Description: <short summary of the patch>
 TODO: Put a short summary on the line above and replace this paragraph
 with a longer explanation of this change. Complete the meta-information
 with other relevant fields (see below for details). To make it easier, the
 information below has been extracted from the changelog. Adjust it or drop
 it.
 .
 zfcpdump-kernel (4.4-0ubuntu0.1) xenial; urgency=low
 .
   * Backport to xenial.  (LP: #1565841)
Author: Andy Whitcroft <apw@ubuntu.com>
Bug-Ubuntu: https://bugs.launchpad.net/bugs/1565841

---
The information above should follow the Patch Tagging Guidelines, please
checkout http://dep.debian.net/deps/dep3/ to learn about the format. Here
are templates for supplementary fields that you might want to add:

Origin: <vendor|upstream|other>, <url of original patch>
Bug: <url in upstream bugtracker>
Bug-Debian: https://bugs.debian.org/<bugnumber>
Bug-Ubuntu: https://launchpad.net/bugs/<bugnumber>
Forwarded: <no|not-needed|url proving that it has been forwarded>
Reviewed-By: <name and email of someone who approved the patch>
Last-Update: 2016-11-11

--- zfcpdump-kernel-4.4.orig/Documentation/ABI/stable/sysfs-bus-vmbus
+++ zfcpdump-kernel-4.4/Documentation/ABI/stable/sysfs-bus-vmbus
@@ -27,3 +27,17 @@ Description:	The mapping of which primar
 		Virtual Processors.
 		Format: <channel's child_relid:the bound cpu's number>
 Users:		tools/hv/lsvmbus
+
+What:		/sys/bus/vmbus/devices/vmbus_*/device
+Date:		Dec. 2015
+KernelVersion:	4.5
+Contact:	K. Y. Srinivasan <kys@microsoft.com>
+Description:	The 16 bit device ID of the device
+Users:		tools/hv/lsvmbus and user level RDMA libraries
+
+What:		/sys/bus/vmbus/devices/vmbus_*/vendor
+Date:		Dec. 2015
+KernelVersion:	4.5
+Contact:	K. Y. Srinivasan <kys@microsoft.com>
+Description:	The 16 bit vendor ID of the device
+Users:		tools/hv/lsvmbus and user level RDMA libraries
--- /dev/null
+++ zfcpdump-kernel-4.4/Documentation/ABI/testing/debugfs-aufs
@@ -0,0 +1,50 @@
+What:		/debug/aufs/si_<id>/
+Date:		March 2009
+Contact:	J. R. Okajima <hooanon05g@gmail.com>
+Description:
+		Under /debug/aufs, a directory named si_<id> is created
+		per aufs mount, where <id> is a unique id generated
+		internally.
+
+What:		/debug/aufs/si_<id>/plink
+Date:		Apr 2013
+Contact:	J. R. Okajima <hooanon05g@gmail.com>
+Description:
+		It has three lines and shows the information about the
+		pseudo-link. The first line is a single number
+		representing a number of buckets. The second line is a
+		number of pseudo-links per buckets (separated by a
+		blank). The last line is a single number representing a
+		total number of psedo-links.
+		When the aufs mount option 'noplink' is specified, it
+		will show "1\n0\n0\n".
+
+What:		/debug/aufs/si_<id>/xib
+Date:		March 2009
+Contact:	J. R. Okajima <hooanon05g@gmail.com>
+Description:
+		It shows the consumed blocks by xib (External Inode Number
+		Bitmap), its block size and file size.
+		When the aufs mount option 'noxino' is specified, it
+		will be empty. About XINO files, see the aufs manual.
+
+What:		/debug/aufs/si_<id>/xino0, xino1 ... xinoN
+Date:		March 2009
+Contact:	J. R. Okajima <hooanon05g@gmail.com>
+Description:
+		It shows the consumed blocks by xino (External Inode Number
+		Translation Table), its link count, block size and file
+		size.
+		When the aufs mount option 'noxino' is specified, it
+		will be empty. About XINO files, see the aufs manual.
+
+What:		/debug/aufs/si_<id>/xigen
+Date:		March 2009
+Contact:	J. R. Okajima <hooanon05g@gmail.com>
+Description:
+		It shows the consumed blocks by xigen (External Inode
+		Generation Table), its block size and file size.
+		If CONFIG_AUFS_EXPORT is disabled, this entry will not
+		be created.
+		When the aufs mount option 'noxino' is specified, it
+		will be empty. About XINO files, see the aufs manual.
--- /dev/null
+++ zfcpdump-kernel-4.4/Documentation/ABI/testing/sysfs-aufs
@@ -0,0 +1,31 @@
+What:		/sys/fs/aufs/si_<id>/
+Date:		March 2009
+Contact:	J. R. Okajima <hooanon05g@gmail.com>
+Description:
+		Under /sys/fs/aufs, a directory named si_<id> is created
+		per aufs mount, where <id> is a unique id generated
+		internally.
+
+What:		/sys/fs/aufs/si_<id>/br0, br1 ... brN
+Date:		March 2009
+Contact:	J. R. Okajima <hooanon05g@gmail.com>
+Description:
+		It shows the abolute path of a member directory (which
+		is called branch) in aufs, and its permission.
+
+What:		/sys/fs/aufs/si_<id>/brid0, brid1 ... bridN
+Date:		July 2013
+Contact:	J. R. Okajima <hooanon05g@gmail.com>
+Description:
+		It shows the id of a member directory (which is called
+		branch) in aufs.
+
+What:		/sys/fs/aufs/si_<id>/xi_path
+Date:		March 2009
+Contact:	J. R. Okajima <hooanon05g@gmail.com>
+Description:
+		It shows the abolute path of XINO (External Inode Number
+		Bitmap, Translation Table and Generation Table) file
+		even if it is the default path.
+		When the aufs mount option 'noxino' is specified, it
+		will be empty. About XINO files, see the aufs manual.
--- zfcpdump-kernel-4.4.orig/Documentation/ABI/testing/sysfs-bus-iio-proximity-as3935
+++ zfcpdump-kernel-4.4/Documentation/ABI/testing/sysfs-bus-iio-proximity-as3935
@@ -1,4 +1,4 @@
-What		/sys/bus/iio/devices/iio:deviceX/in_proximity_raw
+What		/sys/bus/iio/devices/iio:deviceX/in_proximity_input
 Date:		March 2014
 KernelVersion:	3.15
 Contact:	Matt Ranostay <mranostay@gmail.com>
--- zfcpdump-kernel-4.4.orig/Documentation/ABI/testing/sysfs-bus-usb
+++ zfcpdump-kernel-4.4/Documentation/ABI/testing/sysfs-bus-usb
@@ -134,19 +134,21 @@ Description:
 		enabled for the device. Developer can write y/Y/1 or n/N/0 to
 		the file to enable/disable the feature.
 
-What:		/sys/bus/usb/devices/.../power/usb3_hardware_lpm
-Date:		June 2015
+What:		/sys/bus/usb/devices/.../power/usb3_hardware_lpm_u1
+		/sys/bus/usb/devices/.../power/usb3_hardware_lpm_u2
+Date:		November 2015
 Contact:	Kevin Strasser <kevin.strasser@linux.intel.com>
+		Lu Baolu <baolu.lu@linux.intel.com>
 Description:
 		If CONFIG_PM is set and a USB 3.0 lpm-capable device is plugged
 		in to a xHCI host which supports link PM, it will check if U1
 		and U2 exit latencies have been set in the BOS descriptor; if
-		the check is is passed and the host supports USB3 hardware LPM,
+		the check is passed and the host supports USB3 hardware LPM,
 		USB3 hardware LPM will be enabled for the device and the USB
-		device directory will contain a file named
-		power/usb3_hardware_lpm. The file holds a string value (enable
-		or disable) indicating whether or not USB3 hardware LPM is
-		enabled for the device.
+		device directory will contain two files named
+		power/usb3_hardware_lpm_u1 and power/usb3_hardware_lpm_u2. These
+		files hold a string value (enable or disable) indicating whether
+		or not USB3 hardware LPM U1 or U2 is enabled for the device.
 
 What:		/sys/bus/usb/devices/.../removable
 Date:		February 2012
--- zfcpdump-kernel-4.4.orig/Documentation/ABI/testing/sysfs-class-cxl
+++ zfcpdump-kernel-4.4/Documentation/ABI/testing/sysfs-class-cxl
@@ -159,7 +159,7 @@ Description:    read only
                 Decimal value of the Per Process MMIO space length.
 Users:		https://github.com/ibm-capi/libcxl
 
-What:           /sys/class/cxl/<afu>m/pp_mmio_off
+What:           /sys/class/cxl/<afu>m/pp_mmio_off (not in a guest)
 Date:           September 2014
 Contact:        linuxppc-dev@lists.ozlabs.org
 Description:    read only
@@ -183,7 +183,7 @@ Description:    read only
                 Identifies the revision level of the PSL.
 Users:		https://github.com/ibm-capi/libcxl
 
-What:           /sys/class/cxl/<card>/base_image
+What:           /sys/class/cxl/<card>/base_image (not in a guest)
 Date:           September 2014
 Contact:        linuxppc-dev@lists.ozlabs.org
 Description:    read only
@@ -193,7 +193,7 @@ Description:    read only
                 during the initial program load.
 Users:		https://github.com/ibm-capi/libcxl
 
-What:           /sys/class/cxl/<card>/image_loaded
+What:           /sys/class/cxl/<card>/image_loaded (not in a guest)
 Date:           September 2014
 Contact:        linuxppc-dev@lists.ozlabs.org
 Description:    read only
@@ -201,7 +201,7 @@ Description:    read only
                 onto the card.
 Users:		https://github.com/ibm-capi/libcxl
 
-What:           /sys/class/cxl/<card>/load_image_on_perst
+What:           /sys/class/cxl/<card>/load_image_on_perst (not in a guest)
 Date:           December 2014
 Contact:        linuxppc-dev@lists.ozlabs.org
 Description:    read/write
@@ -224,7 +224,7 @@ Description:    write only
                 to reload the FPGA depending on load_image_on_perst.
 Users:		https://github.com/ibm-capi/libcxl
 
-What:		/sys/class/cxl/<card>/perst_reloads_same_image
+What:		/sys/class/cxl/<card>/perst_reloads_same_image (not in a guest)
 Date:		July 2015
 Contact:	linuxppc-dev@lists.ozlabs.org
 Description:	read/write
@@ -233,3 +233,11 @@ Description:	read/write
 		0 = don't trust, the image may be different (default)
 		1 = trust that the image will not change.
 Users:		https://github.com/ibm-capi/libcxl
+
+What:           /sys/class/cxl/<card>/psl_timebase_synced
+Date:           March 2016
+Contact:        linuxppc-dev@lists.ozlabs.org
+Description:    read only
+                Returns 1 if the psl timebase register is synchronized
+                with the core timebase register, 0 otherwise.
+Users:          https://github.com/ibm-capi/libcxl
--- zfcpdump-kernel-4.4.orig/Documentation/ABI/testing/sysfs-devices-system-cpu
+++ zfcpdump-kernel-4.4/Documentation/ABI/testing/sysfs-devices-system-cpu
@@ -271,3 +271,72 @@ Description:	Parameters for the CPU cach
 			- WriteBack: data is written only to the cache line and
 				     the modified cache line is written to main
 				     memory only when it is replaced
+
+What:		/sys/devices/system/cpu/cpuX/cpufreq/throttle_stats
+		/sys/devices/system/cpu/cpuX/cpufreq/throttle_stats/turbo_stat
+		/sys/devices/system/cpu/cpuX/cpufreq/throttle_stats/sub_turbo_stat
+		/sys/devices/system/cpu/cpuX/cpufreq/throttle_stats/unthrottle
+		/sys/devices/system/cpu/cpuX/cpufreq/throttle_stats/powercap
+		/sys/devices/system/cpu/cpuX/cpufreq/throttle_stats/overtemp
+		/sys/devices/system/cpu/cpuX/cpufreq/throttle_stats/supply_fault
+		/sys/devices/system/cpu/cpuX/cpufreq/throttle_stats/overcurrent
+		/sys/devices/system/cpu/cpuX/cpufreq/throttle_stats/occ_reset
+Date:		March 2016
+Contact:	Linux kernel mailing list <linux-kernel@vger.kernel.org>
+		Linux for PowerPC mailing list <linuxppc-dev@ozlabs.org>
+Description:	POWERNV CPUFreq driver's frequency throttle stats directory and
+		attributes
+
+		'cpuX/cpufreq/throttle_stats' directory contains the CPU frequency
+		throttle stat attributes for the chip. The throttle stats of a cpu
+		is common across all the cpus belonging to a chip. Below are the
+		throttle attributes exported in the 'throttle_stats' directory:
+
+		- turbo_stat : This file gives the total number of times the max
+		frequency is throttled to lower frequency in turbo (at and above
+		nominal frequency) range of frequencies.
+
+		- sub_turbo_stat : This file gives the total number of times the
+		max frequency is throttled to lower frequency in sub-turbo(below
+		nominal frequency) range of frequencies.
+
+		- unthrottle : This file gives the total number of times the max
+		frequency is unthrottled after being throttled.
+
+		- powercap : This file gives the total number of times the max
+		frequency is throttled due to 'Power Capping'.
+
+		- overtemp : This file gives the total number of times the max
+		frequency is throttled due to 'CPU Over Temperature'.
+
+		- supply_fault : This file gives the total number of times the
+		max frequency is throttled due to 'Power Supply Failure'.
+
+		- overcurrent : This file gives the total number of times the
+		max frequency is throttled due to 'Overcurrent'.
+
+		- occ_reset : This file gives the total number of times the max
+		frequency is throttled due to 'OCC Reset'.
+
+		The sysfs attributes representing different throttle reasons like
+		powercap, overtemp, supply_fault, overcurrent and occ_reset map to
+		the reasons provided by OCC firmware for throttling the frequency.
+
+What:		/sys/devices/system/cpu/cpufreq/policyX/throttle_stats
+		/sys/devices/system/cpu/cpufreq/policyX/throttle_stats/turbo_stat
+		/sys/devices/system/cpu/cpufreq/policyX/throttle_stats/sub_turbo_stat
+		/sys/devices/system/cpu/cpufreq/policyX/throttle_stats/unthrottle
+		/sys/devices/system/cpu/cpufreq/policyX/throttle_stats/powercap
+		/sys/devices/system/cpu/cpufreq/policyX/throttle_stats/overtemp
+		/sys/devices/system/cpu/cpufreq/policyX/throttle_stats/supply_fault
+		/sys/devices/system/cpu/cpufreq/policyX/throttle_stats/overcurrent
+		/sys/devices/system/cpu/cpufreq/policyX/throttle_stats/occ_reset
+Date:		March 2016
+Contact:	Linux kernel mailing list <linux-kernel@vger.kernel.org>
+		Linux for PowerPC mailing list <linuxppc-dev@ozlabs.org>
+Description:	POWERNV CPUFreq driver's frequency throttle stats directory and
+		attributes
+
+		'policyX/throttle_stats' directory and all the attributes are same as
+		the /sys/devices/system/cpu/cpuX/cpufreq/throttle_stats directory and
+		attributes which give the frequency throttle information of the chip.
--- zfcpdump-kernel-4.4.orig/Documentation/ABI/testing/sysfs-kernel-livepatch
+++ zfcpdump-kernel-4.4/Documentation/ABI/testing/sysfs-kernel-livepatch
@@ -33,7 +33,7 @@ Description:
 		The object directory contains subdirectories for each function
 		that is patched within the object.
 
-What:		/sys/kernel/livepatch/<patch>/<object>/<function>
+What:		/sys/kernel/livepatch/<patch>/<object>/<function,sympos>
 Date:		Nov 2014
 KernelVersion:	3.19.0
 Contact:	live-patching@vger.kernel.org
@@ -41,4 +41,8 @@ Description:
 		The function directory contains attributes regarding the
 		properties and state of the patched function.
 
+		The directory name contains the patched function name and a
+		sympos number corresponding to the nth occurrence of the symbol
+		name in kallsyms for the patched object.
+
 		There are currently no such attributes.
--- zfcpdump-kernel-4.4.orig/Documentation/DocBook/gpu.tmpl
+++ zfcpdump-kernel-4.4/Documentation/DocBook/gpu.tmpl
@@ -2350,6 +2350,12 @@ void intel_crt_init(struct drm_device *d
 !Edrivers/gpu/drm/drm_dp_helper.c
     </sect2>
     <sect2>
+      <title>Display Port Dual Mode Adaptor Helper Functions Reference</title>
+!Pdrivers/gpu/drm/drm_dp_dual_mode_helper.c dp dual mode helpers
+!Iinclude/drm/drm_dp_dual_mode_helper.h
+!Edrivers/gpu/drm/drm_dp_dual_mode_helper.c
+    </sect2>
+    <sect2>
       <title>Display Port MST Helper Functions Reference</title>
 !Pdrivers/gpu/drm/drm_dp_mst_topology.c dp mst helper
 !Iinclude/drm/drm_dp_mst_helper.h
@@ -2543,7 +2549,7 @@ void intel_crt_init(struct drm_device *d
 	<td valign="top" >Description/Restrictions</td>
 	</tr>
 	<tr>
-	<td rowspan="37" valign="top" >DRM</td>
+	<td rowspan="42" valign="top" >DRM</td>
 	<td valign="top" >Generic</td>
 	<td valign="top" >“rotation”</td>
 	<td valign="top" >BITMASK</td>
@@ -2795,7 +2801,7 @@ void intel_crt_init(struct drm_device *d
 	<td valign="top" >property to suggest an Y offset for a connector</td>
 	</tr>
 	<tr>
-	<td rowspan="3" valign="top" >Optional</td>
+	<td rowspan="8" valign="top" >Optional</td>
 	<td valign="top" >“scaling mode”</td>
 	<td valign="top" >ENUM</td>
 	<td valign="top" >{ "None", "Full", "Center", "Full aspect" }</td>
@@ -2819,6 +2825,61 @@ void intel_crt_init(struct drm_device *d
 	<td valign="top" >TBD</td>
 	</tr>
 	<tr>
+	<td valign="top" >“DEGAMMA_LUT”</td>
+	<td valign="top" >BLOB</td>
+	<td valign="top" >0</td>
+	<td valign="top" >CRTC</td>
+	<td valign="top" >DRM property to set the degamma lookup table
+		(LUT) mapping pixel data from the framebuffer before it is
+		given to the transformation matrix. The data is an interpreted
+		as an array of struct drm_color_lut elements. Hardware might
+		choose not to use the full precision of the LUT elements nor
+		use all the elements of the LUT (for example the hardware
+		might choose to interpolate between LUT[0] and LUT[4]). </td>
+	</tr>
+	<tr>
+	<td valign="top" >“DEGAMMA_LUT_SIZE”</td>
+	<td valign="top" >RANGE | IMMUTABLE</td>
+	<td valign="top" >Min=0, Max=UINT_MAX</td>
+	<td valign="top" >CRTC</td>
+	<td valign="top" >DRM property to gives the size of the lookup
+		table to be set on the DEGAMMA_LUT property (the size depends
+		on the underlying hardware).</td>
+	</tr>
+	<tr>
+	<td valign="top" >“CTM”</td>
+	<td valign="top" >BLOB</td>
+	<td valign="top" >0</td>
+	<td valign="top" >CRTC</td>
+	<td valign="top" >DRM property to set the current
+		transformation matrix (CTM) apply to pixel data after the
+		lookup through the degamma LUT and before the lookup through
+		the gamma LUT. The data is an interpreted as a struct
+		drm_color_ctm.</td>
+	</tr>
+	<tr>
+	<td valign="top" >“GAMMA_LUT”</td>
+	<td valign="top" >BLOB</td>
+	<td valign="top" >0</td>
+	<td valign="top" >CRTC</td>
+	<td valign="top" >DRM property to set the gamma lookup table
+		(LUT) mapping pixel data after to the transformation matrix to
+		data sent to the connector. The data is an interpreted as an
+		array of struct drm_color_lut elements. Hardware might choose
+		not to use the full precision of the LUT elements nor use all
+		the elements of the LUT (for example the hardware might choose
+		to interpolate between LUT[0] and LUT[4]).</td>
+	</tr>
+	<tr>
+	<td valign="top" >“GAMMA_LUT_SIZE”</td>
+	<td valign="top" >RANGE | IMMUTABLE</td>
+	<td valign="top" >Min=0, Max=UINT_MAX</td>
+	<td valign="top" >CRTC</td>
+	<td valign="top" >DRM property to gives the size of the lookup
+		table to be set on the GAMMA_LUT property (the size depends on
+		the underlying hardware).</td>
+	</tr>
+	<tr>
 	<td rowspan="20" valign="top" >i915</td>
 	<td rowspan="2" valign="top" >Generic</td>
 	<td valign="top" >"Broadcast RGB"</td>
--- /dev/null
+++ zfcpdump-kernel-4.4/Documentation/cgroups/namespace.txt
@@ -0,0 +1,142 @@
+			CGroup Namespaces
+
+CGroup Namespace provides a mechanism to virtualize the view of the
+/proc/<pid>/cgroup file. The CLONE_NEWCGROUP clone-flag can be used with
+clone() and unshare() syscalls to create a new cgroup namespace.
+The process running inside the cgroup namespace will have its /proc/<pid>/cgroup
+output restricted to cgroupns-root. cgroupns-root is the cgroup of the process
+at the time of creation of the cgroup namespace.
+
+Prior to CGroup Namespace, the /proc/<pid>/cgroup file used to show complete
+path of the cgroup of a process. In a container setup (where a set of cgroups
+and namespaces are intended to isolate processes), the /proc/<pid>/cgroup file
+may leak potential system level information to the isolated processes.
+
+For Example:
+  $ cat /proc/self/cgroup
+  0:cpuset,cpu,cpuacct,memory,devices,freezer,hugetlb:/batchjobs/container_id1
+
+The path '/batchjobs/container_id1' can generally be considered as system-data
+and its desirable to not expose it to the isolated process.
+
+CGroup Namespaces can be used to restrict visibility of this path.
+For Example:
+  # Before creating cgroup namespace
+  $ ls -l /proc/self/ns/cgroup
+  lrwxrwxrwx 1 root root 0 2014-07-15 10:37 /proc/self/ns/cgroup -> cgroup:[4026531835]
+  $ cat /proc/self/cgroup
+  0:cpuset,cpu,cpuacct,memory,devices,freezer,hugetlb:/batchjobs/container_id1
+
+  # unshare(CLONE_NEWCGROUP) and exec /bin/bash
+  $ ~/unshare -c
+  [ns]$ ls -l /proc/self/ns/cgroup
+  lrwxrwxrwx 1 root root 0 2014-07-15 10:35 /proc/self/ns/cgroup -> cgroup:[4026532183]
+  # From within new cgroupns, process sees that its in the root cgroup
+  [ns]$ cat /proc/self/cgroup
+  0:cpuset,cpu,cpuacct,memory,devices,freezer,hugetlb:/
+
+  # From global cgroupns:
+  $ cat /proc/<pid>/cgroup
+  0:cpuset,cpu,cpuacct,memory,devices,freezer,hugetlb:/batchjobs/container_id1
+
+  # Unshare cgroupns along with userns and mountns
+  # Following calls unshare(CLONE_NEWCGROUP|CLONE_NEWUSER|CLONE_NEWNS), then
+  # sets up uid/gid map and execs /bin/bash
+  $ ~/unshare -c -u -m
+  # Originally, we were in /batchjobs/container_id1 cgroup. Mount our own cgroup
+  # hierarchy.
+  [ns]$ mount -t cgroup cgroup /tmp/cgroup
+  [ns]$ ls -l /tmp/cgroup
+  total 0
+  -r--r--r-- 1 root root 0 2014-10-13 09:32 cgroup.controllers
+  -r--r--r-- 1 root root 0 2014-10-13 09:32 cgroup.populated
+  -rw-r--r-- 1 root root 0 2014-10-13 09:25 cgroup.procs
+  -rw-r--r-- 1 root root 0 2014-10-13 09:32 cgroup.subtree_control
+
+The cgroupns-root (/batchjobs/container_id1 in above example) becomes the
+filesystem root for the namespace specific cgroupfs mount.
+
+The virtualization of /proc/self/cgroup file combined with restricting
+the view of cgroup hierarchy by namespace-private cgroupfs mount
+should provide a completely isolated cgroup view inside the container.
+
+In its current form, the cgroup namespaces patcheset provides following
+behavior:
+
+(1) The 'cgroupns-root' for a cgroup namespace is the cgroup in which
+    the process calling unshare is running.
+    For ex. if a process in /batchjobs/container_id1 cgroup calls unshare,
+    cgroup /batchjobs/container_id1 becomes the cgroupns-root.
+    For the init_cgroup_ns, this is the real root ('/') cgroup
+    (identified in code as cgrp_dfl_root.cgrp).
+
+(2) The cgroupns-root cgroup does not change even if the namespace
+    creator process later moves to a different cgroup.
+    $ ~/unshare -c # unshare cgroupns in some cgroup
+    [ns]$ cat /proc/self/cgroup
+    0:cpuset,cpu,cpuacct,memory,devices,freezer,hugetlb:/
+    [ns]$ mkdir sub_cgrp_1
+    [ns]$ echo 0 > sub_cgrp_1/cgroup.procs
+    [ns]$ cat /proc/self/cgroup
+    0:cpuset,cpu,cpuacct,memory,devices,freezer,hugetlb:/sub_cgrp_1
+
+(3) Each process gets its CGROUPNS specific view of /proc/<pid>/cgroup
+(a) Processes running inside the cgroup namespace will be able to see
+    cgroup paths (in /proc/self/cgroup) only inside their root cgroup
+    [ns]$ sleep 100000 &  # From within unshared cgroupns
+    [1] 7353
+    [ns]$ echo 7353 > sub_cgrp_1/cgroup.procs
+    [ns]$ cat /proc/7353/cgroup
+    0:cpuset,cpu,cpuacct,memory,devices,freezer,hugetlb:/sub_cgrp_1
+
+(b) From global cgroupns, the real cgroup path will be visible:
+    $ cat /proc/7353/cgroup
+    0:cpuset,cpu,cpuacct,memory,devices,freezer,hugetlb:/batchjobs/container_id1/sub_cgrp_1
+
+(c) From a sibling cgroupns (cgroupns root-ed at a different cgroup), cgroup
+    path relative to its own cgroupns-root will be shown:
+    # ns2's cgroupns-root is at '/batchjobs/container_id2'
+    [ns2]$ cat /proc/7353/cgroup
+    0:cpuset,cpu,cpuacct,memory,devices,freezer,hugetlb:/../container_id2/sub_cgrp_1
+
+    Note that the relative path always starts with '/' to indicate that its
+    relative to the cgroupns-root of the caller.
+
+(4) Processes inside a cgroupns can move in-and-out of the cgroupns-root
+    (if they have proper access to external cgroups).
+    # From inside cgroupns (with cgroupns-root at /batchjobs/container_id1), and
+    # assuming that the global hierarchy is still accessible inside cgroupns:
+    $ cat /proc/7353/cgroup
+    0:cpuset,cpu,cpuacct,memory,devices,freezer,hugetlb:/sub_cgrp_1
+    $ echo 7353 > batchjobs/container_id2/cgroup.procs
+    $ cat /proc/7353/cgroup
+    0:cpuset,cpu,cpuacct,memory,devices,freezer,hugetlb:/../container_id2
+
+    Note that this kind of setup is not encouraged. A task inside cgroupns
+    should only be exposed to its own cgroupns hierarchy. Otherwise it makes
+    the virtualization of /proc/<pid>/cgroup less useful.
+
+(5) Setns to another cgroup namespace is allowed when:
+    (a) the process has CAP_SYS_ADMIN in its current userns
+    (b) the process has CAP_SYS_ADMIN in the target cgroupns' userns
+    No implicit cgroup changes happen with attaching to another cgroupns. It
+    is expected that the somone moves the attaching process under the target
+    cgroupns-root.
+
+(6) When some thread from a multi-threaded process unshares its
+    cgroup-namespace, the new cgroupns gets applied to the entire process (all
+    the threads). For the unified-hierarchy this is expected as it only allows
+    process-level containerization.  For the legacy hierarchies this may be
+    unexpected.  So all the threads in the process will have the same cgroup.
+
+(7) The cgroup namespace is alive as long as there is atleast 1
+    process inside it. When the last process exits, the cgroup
+    namespace is destroyed. The cgroupns-root and the actual cgroups
+    remain though.
+
+(8) Namespace specific cgroup hierarchy can be mounted by a process running
+    inside cgroupns:
+    $ mount -t cgroup -o __DEVEL__sane_behavior cgroup $MOUNT_POINT
+
+    This will mount the unified cgroup hierarchy with cgroupns-root as the
+    filesystem root. The process needs CAP_SYS_ADMIN in its userns and mntns.
--- zfcpdump-kernel-4.4.orig/Documentation/devicetree/bindings/arm/omap/omap.txt
+++ zfcpdump-kernel-4.4/Documentation/devicetree/bindings/arm/omap/omap.txt
@@ -23,6 +23,7 @@ Optional properties:
   during suspend.
 - ti,no-reset-on-init: When present, the module should not be reset at init
 - ti,no-idle-on-init: When present, the module should not be idled at init
+- ti,no-idle: When present, the module is never allowed to idle.
 
 Example:
 
--- zfcpdump-kernel-4.4.orig/Documentation/devicetree/bindings/arm/pmu.txt
+++ zfcpdump-kernel-4.4/Documentation/devicetree/bindings/arm/pmu.txt
@@ -24,6 +24,7 @@ Required properties:
 	"qcom,scorpion-pmu"
 	"qcom,scorpion-mp-pmu"
 	"qcom,krait-pmu"
+	"cavium,thunder-pmu"
 - interrupts : 1 combined interrupt or 1 per core. If the interrupt is a per-cpu
                interrupt (PPI) then 1 interrupt should be specified.
 
--- zfcpdump-kernel-4.4.orig/Documentation/devicetree/bindings/ata/ahci-platform.txt
+++ zfcpdump-kernel-4.4/Documentation/devicetree/bindings/ata/ahci-platform.txt
@@ -30,6 +30,10 @@ Optional properties:
 - target-supply     : regulator for SATA target power
 - phys              : reference to the SATA PHY node
 - phy-names         : must be "sata-phy"
+- ports-implemented : Mask that indicates which ports that the HBA supports
+		      are available for software to use. Useful if PORTS_IMPL
+		      is not programmed by the BIOS, which is true with
+		      some embedded SOC's.
 
 Required properties when using sub-nodes:
 - #address-cells    : number of cells to encode an address
--- zfcpdump-kernel-4.4.orig/Documentation/devicetree/bindings/clock/imx35-clock.txt
+++ zfcpdump-kernel-4.4/Documentation/devicetree/bindings/clock/imx35-clock.txt
@@ -94,6 +94,7 @@ clocks and IDs.
 	csi_sel			79
 	iim_gate		80
 	gpu2d_gate		81
+	ckli_gate		82
 
 Examples:
 
--- zfcpdump-kernel-4.4.orig/Documentation/devicetree/bindings/iio/adc/rockchip-saradc.txt
+++ zfcpdump-kernel-4.4/Documentation/devicetree/bindings/iio/adc/rockchip-saradc.txt
@@ -12,6 +12,11 @@ Required properties:
 - vref-supply: The regulator supply ADC reference voltage.
 - #io-channel-cells: Should be 1, see ../iio-bindings.txt
 
+Optional properties:
+- resets: Must contain an entry for each entry in reset-names if need support
+	  this option. See ../reset/reset.txt for details.
+- reset-names: Must include the name "saradc-apb".
+
 Example:
 	saradc: saradc@2006c000 {
 		compatible = "rockchip,saradc";
@@ -19,6 +24,8 @@ Example:
 		interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&cru SCLK_SARADC>, <&cru PCLK_SARADC>;
 		clock-names = "saradc", "apb_pclk";
+		resets = <&cru SRST_SARADC>;
+		reset-names = "saradc-apb";
 		#io-channel-cells = <1>;
 		vref-supply = <&vcc18>;
 	};
--- zfcpdump-kernel-4.4.orig/Documentation/devicetree/bindings/net/cavium-mdio.txt
+++ zfcpdump-kernel-4.4/Documentation/devicetree/bindings/net/cavium-mdio.txt
@@ -1,9 +1,12 @@
 * System Management Interface (SMI) / MDIO
 
 Properties:
-- compatible: "cavium,octeon-3860-mdio"
+- compatible: One of:
 
-  Compatibility with all cn3XXX, cn5XXX and cn6XXX SOCs.
+   "cavium,octeon-3860-mdio": Compatibility with all cn3XXX, cn5XXX
+                       and cn6XXX SOCs.
+
+   "cavium,thunder-8890-mdio": Compatibility with all cn8XXX SOCs.
 
 - reg: The base address of the MDIO bus controller register bank.
 
@@ -25,3 +28,57 @@ Example:
 			reg = <0>;
 		};
 	};
+
+
+* System Management Interface (SMI) / MDIO Nexus
+
+  Several mdio buses may be gathered as children of a single PCI
+  device, this PCI device is the nexus of the buses.
+
+Properties:
+
+- compatible: "cavium,thunder-8890-mdio-nexus";
+
+- reg: The PCI device and function numbers of the nexus device.
+
+- #address-cells: Must be <2>.
+
+- #size-cells: Must be <2>.
+
+- ranges: As needed for mapping of the MDIO bus device registers.
+
+- assigned-addresses: As needed for mapping of the MDIO bus device registers.
+
+Example:
+
+        mdio-nexus@1,3 {
+                compatible = "cavium,thunder-8890-mdio-nexus";
+                #address-cells = <2>;
+                #size-cells = <2>;
+                reg = <0x0b00 0 0 0 0>; /* DEVFN = 0x0b (1:3) */
+                assigned-addresses = <0x03000000 0x87e0 0x05000000 0x0 0x800000>;
+                ranges = <0x87e0 0x05000000 0x03000000 0x87e0 0x05000000 0x0 0x800000>;
+
+                mdio0@87e0,05003800 {
+                        compatible = "cavium,thunder-8890-mdio";
+                        #address-cells = <1>;
+                        #size-cells = <0>;
+                        reg = <0x87e0 0x05003800 0x0 0x30>;
+
+                        ethernet-phy@0 {
+                                ...
+                                reg = <0>;
+                        };
+                };
+                mdio0@87e0,05003880 {
+                        compatible = "cavium,thunder-8890-mdio";
+                        #address-cells = <1>;
+                        #size-cells = <0>;
+                        reg = <0x87e0 0x05003880 0x0 0x30>;
+
+                        ethernet-phy@0 {
+                                ...
+                                reg = <0>;
+                        };
+                };
+        };
--- /dev/null
+++ zfcpdump-kernel-4.4/Documentation/devicetree/bindings/numa.txt
@@ -0,0 +1,275 @@
+==============================================================================
+NUMA binding description.
+==============================================================================
+
+==============================================================================
+1 - Introduction
+==============================================================================
+
+Systems employing a Non Uniform Memory Access (NUMA) architecture contain
+collections of hardware resources including processors, memory, and I/O buses,
+that comprise what is commonly known as a NUMA node.
+Processor accesses to memory within the local NUMA node is generally faster
+than processor accesses to memory outside of the local NUMA node.
+DT defines interfaces that allow the platform to convey NUMA node
+topology information to OS.
+
+==============================================================================
+2 - numa-node-id
+==============================================================================
+
+For the purpose of identification, each NUMA node is associated with a unique
+token known as a node id. For the purpose of this binding
+a node id is a 32-bit integer.
+
+A device node is associated with a NUMA node by the presence of a
+numa-node-id property which contains the node id of the device.
+
+Example:
+	/* numa node 0 */
+	numa-node-id = <0>;
+
+	/* numa node 1 */
+	numa-node-id = <1>;
+
+==============================================================================
+3 - distance-map
+==============================================================================
+
+The optional device tree node distance-map describes the relative
+distance (memory latency) between all numa nodes.
+
+- compatible : Should at least contain "numa-distance-map-v1".
+
+- distance-matrix
+  This property defines a matrix to describe the relative distances
+  between all numa nodes.
+  It is represented as a list of node pairs and their relative distance.
+
+  Note:
+	1. Each entry represents distance from first node to second node.
+	The distances are equal in either direction.
+	2. The distance from a node to self (local distance) is represented
+	with value 10 and all internode distance should be represented with
+	a value greater than 10.
+	3. distance-matrix should have entries in lexicographical ascending
+	order of nodes.
+	4. There must be only one device node distance-map which must
+	reside in the root node.
+	5. If the distance-map node is not present, a default
+	distance-matrix is used.
+
+Example:
+	4 nodes connected in mesh/ring topology as below,
+
+		0_______20______1
+		|               |
+		|               |
+		20             20
+		|               |
+		|               |
+		|_______________|
+		3       20      2
+
+	if relative distance for each hop is 20,
+	then internode distance would be,
+	      0 -> 1 = 20
+	      1 -> 2 = 20
+	      2 -> 3 = 20
+	      3 -> 0 = 20
+	      0 -> 2 = 40
+	      1 -> 3 = 40
+
+     and dt presentation for this distance matrix is,
+
+		distance-map {
+			 compatible = "numa-distance-map-v1";
+			 distance-matrix = <0 0  10>,
+					   <0 1  20>,
+					   <0 2  40>,
+					   <0 3  20>,
+					   <1 0  20>,
+					   <1 1  10>,
+					   <1 2  20>,
+					   <1 3  40>,
+					   <2 0  40>,
+					   <2 1  20>,
+					   <2 2  10>,
+					   <2 3  20>,
+					   <3 0  20>,
+					   <3 1  40>,
+					   <3 2  20>,
+					   <3 3  10>;
+		};
+
+==============================================================================
+4 - Example dts
+==============================================================================
+
+Dual socket system consists of 2 boards connected through ccn bus and
+each board having one socket/soc of 8 cpus, memory and pci bus.
+
+	memory@c00000 {
+		device_type = "memory";
+		reg = <0x0 0xc00000 0x0 0x80000000>;
+		/* node 0 */
+		numa-node-id = <0>;
+	};
+
+	memory@10000000000 {
+		device_type = "memory";
+		reg = <0x100 0x0 0x0 0x80000000>;
+		/* node 1 */
+		numa-node-id = <1>;
+	};
+
+	cpus {
+		#address-cells = <2>;
+		#size-cells = <0>;
+
+		cpu@0 {
+			device_type = "cpu";
+			compatible =  "arm,armv8";
+			reg = <0x0 0x0>;
+			enable-method = "psci";
+			/* node 0 */
+			numa-node-id = <0>;
+		};
+		cpu@1 {
+			device_type = "cpu";
+			compatible =  "arm,armv8";
+			reg = <0x0 0x1>;
+			enable-method = "psci";
+			numa-node-id = <0>;
+		};
+		cpu@2 {
+			device_type = "cpu";
+			compatible =  "arm,armv8";
+			reg = <0x0 0x2>;
+			enable-method = "psci";
+			numa-node-id = <0>;
+		};
+		cpu@3 {
+			device_type = "cpu";
+			compatible =  "arm,armv8";
+			reg = <0x0 0x3>;
+			enable-method = "psci";
+			numa-node-id = <0>;
+		};
+		cpu@4 {
+			device_type = "cpu";
+			compatible =  "arm,armv8";
+			reg = <0x0 0x4>;
+			enable-method = "psci";
+			numa-node-id = <0>;
+		};
+		cpu@5 {
+			device_type = "cpu";
+			compatible =  "arm,armv8";
+			reg = <0x0 0x5>;
+			enable-method = "psci";
+			numa-node-id = <0>;
+		};
+		cpu@6 {
+			device_type = "cpu";
+			compatible =  "arm,armv8";
+			reg = <0x0 0x6>;
+			enable-method = "psci";
+			numa-node-id = <0>;
+		};
+		cpu@7 {
+			device_type = "cpu";
+			compatible =  "arm,armv8";
+			reg = <0x0 0x7>;
+			enable-method = "psci";
+			numa-node-id = <0>;
+		};
+		cpu@8 {
+			device_type = "cpu";
+			compatible =  "arm,armv8";
+			reg = <0x0 0x8>;
+			enable-method = "psci";
+			/* node 1 */
+			numa-node-id = <1>;
+		};
+		cpu@9 {
+			device_type = "cpu";
+			compatible =  "arm,armv8";
+			reg = <0x0 0x9>;
+			enable-method = "psci";
+			numa-node-id = <1>;
+		};
+		cpu@a {
+			device_type = "cpu";
+			compatible =  "arm,armv8";
+			reg = <0x0 0xa>;
+			enable-method = "psci";
+			numa-node-id = <1>;
+		};
+		cpu@b {
+			device_type = "cpu";
+			compatible =  "arm,armv8";
+			reg = <0x0 0xb>;
+			enable-method = "psci";
+			numa-node-id = <1>;
+		};
+		cpu@c {
+			device_type = "cpu";
+			compatible =  "arm,armv8";
+			reg = <0x0 0xc>;
+			enable-method = "psci";
+			numa-node-id = <1>;
+		};
+		cpu@d {
+			device_type = "cpu";
+			compatible =  "arm,armv8";
+			reg = <0x0 0xd>;
+			enable-method = "psci";
+			numa-node-id = <1>;
+		};
+		cpu@e {
+			device_type = "cpu";
+			compatible =  "arm,armv8";
+			reg = <0x0 0xe>;
+			enable-method = "psci";
+			numa-node-id = <1>;
+		};
+		cpu@f {
+			device_type = "cpu";
+			compatible =  "arm,armv8";
+			reg = <0x0 0xf>;
+			enable-method = "psci";
+			numa-node-id = <1>;
+		};
+	};
+
+	pcie0: pcie0@848000000000 {
+		compatible = "arm,armv8";
+		device_type = "pci";
+		bus-range = <0 255>;
+		#size-cells = <2>;
+		#address-cells = <3>;
+		reg = <0x8480 0x00000000 0 0x10000000>;  /* Configuration space */
+		ranges = <0x03000000 0x8010 0x00000000 0x8010 0x00000000 0x70 0x00000000>;
+		/* node 0 */
+		numa-node-id = <0>;
+        };
+
+	pcie1: pcie1@948000000000 {
+		compatible = "arm,armv8";
+		device_type = "pci";
+		bus-range = <0 255>;
+		#size-cells = <2>;
+		#address-cells = <3>;
+		reg = <0x9480 0x00000000 0 0x10000000>;  /* Configuration space */
+		ranges = <0x03000000 0x9010 0x00000000 0x9010 0x00000000 0x70 0x00000000>;
+		/* node 1 */
+		numa-node-id = <1>;
+        };
+
+	distance-map {
+		compatible = "numa-distance-map-v1";
+		distance-matrix = <0 0 10>,
+				  <0 1 20>,
+				  <1 1 10>;
+	};
--- /dev/null
+++ zfcpdump-kernel-4.4/Documentation/devicetree/bindings/pci/pci-thunder-ecam.txt
@@ -0,0 +1,30 @@
+* ThunderX PCI host controller for pass-1.x silicon
+
+Firmware-initialized PCI host controller to on-chip devices found on
+some Cavium ThunderX processors.  These devices have ECAM-based config
+access, but the BARs are all at fixed addresses.  We handle the fixed
+addresses by synthesizing Enhanced Allocation (EA) capabilities for
+these devices.
+
+The properties and their meanings are identical to those described in
+host-generic-pci.txt except as listed below.
+
+Properties of the host controller node that differ from
+host-generic-pci.txt:
+
+- compatible     : Must be "cavium,pci-host-thunder-ecam"
+
+Example:
+
+	pcie@84b000000000 {
+		compatible = "cavium,pci-host-thunder-ecam";
+		device_type = "pci";
+		msi-parent = <&its>;
+		msi-map = <0 &its 0x30000 0x10000>;
+		bus-range = <0 31>;
+		#size-cells = <2>;
+		#address-cells = <3>;
+		#stream-id-cells = <1>;
+		reg = <0x84b0 0x00000000 0 0x02000000>;  /* Configuration space */
+		ranges = <0x03000000 0x8180 0x00000000 0x8180 0x00000000 0x80 0x00000000>; /* mem ranges */
+	};
--- /dev/null
+++ zfcpdump-kernel-4.4/Documentation/devicetree/bindings/pci/pci-thunder-pem.txt
@@ -0,0 +1,43 @@
+* ThunderX PEM PCIe host controller
+
+Firmware-initialized PCI host controller found on some Cavium
+ThunderX processors.
+
+The properties and their meanings are identical to those described in
+host-generic-pci.txt except as listed below.
+
+Properties of the host controller node that differ from
+host-generic-pci.txt:
+
+- compatible     : Must be "cavium,pci-host-thunder-pem"
+
+- reg            : Two entries: First the configuration space for down
+                   stream devices base address and size, as accessed
+                   from the parent bus. Second, the register bank of
+                   the PEM device PCIe bridge.
+
+Example:
+
+    pci@87e0,c2000000 {
+	compatible = "cavium,pci-host-thunder-pem";
+	device_type = "pci";
+	msi-parent = <&its>;
+	msi-map = <0 &its 0x10000 0x10000>;
+	bus-range = <0x8f 0xc7>;
+	#size-cells = <2>;
+	#address-cells = <3>;
+
+	reg = <0x8880 0x8f000000 0x0 0x39000000>,  /* Configuration space */
+	      <0x87e0 0xc2000000 0x0 0x00010000>; /* PEM space */
+	ranges = <0x01000000 0x00 0x00020000 0x88b0 0x00020000 0x00 0x00010000>, /* I/O */
+		 <0x03000000 0x00 0x10000000 0x8890 0x10000000 0x0f 0xf0000000>, /* mem64 */
+		 <0x43000000 0x10 0x00000000 0x88a0 0x00000000 0x10 0x00000000>, /* mem64-pref */
+		 <0x03000000 0x87e0 0xc2f00000 0x87e0 0xc2000000 0x00 0x00100000>; /* mem64 PEM BAR4 */
+
+	#interrupt-cells = <1>;
+	interrupt-map-mask = <0 0 0 7>;
+	interrupt-map = <0 0 0 1 &gic0 0 0 0 24 4>, /* INTA */
+			<0 0 0 2 &gic0 0 0 0 25 4>, /* INTB */
+			<0 0 0 3 &gic0 0 0 0 26 4>, /* INTC */
+			<0 0 0 4 &gic0 0 0 0 27 4>; /* INTD */
+    };
--- zfcpdump-kernel-4.4.orig/Documentation/devicetree/bindings/pinctrl/img,pistachio-pinctrl.txt
+++ zfcpdump-kernel-4.4/Documentation/devicetree/bindings/pinctrl/img,pistachio-pinctrl.txt
@@ -134,12 +134,12 @@ mfio80		ddr_debug, mips_trace_data, mips
 mfio81		dreq0, mips_trace_data, eth_debug
 mfio82		dreq1, mips_trace_data, eth_debug
 mfio83		mips_pll_lock, mips_trace_data, usb_debug
-mfio84		sys_pll_lock, mips_trace_data, usb_debug
-mfio85		wifi_pll_lock, mips_trace_data, sdhost_debug
-mfio86		bt_pll_lock, mips_trace_data, sdhost_debug
-mfio87		rpu_v_pll_lock, dreq2, socif_debug
-mfio88		rpu_l_pll_lock, dreq3, socif_debug
-mfio89		audio_pll_lock, dreq4, dreq5
+mfio84		audio_pll_lock, mips_trace_data, usb_debug
+mfio85		rpu_v_pll_lock, mips_trace_data, sdhost_debug
+mfio86		rpu_l_pll_lock, mips_trace_data, sdhost_debug
+mfio87		sys_pll_lock, dreq2, socif_debug
+mfio88		wifi_pll_lock, dreq3, socif_debug
+mfio89		bt_pll_lock, dreq4, dreq5
 tck
 trstn
 tdi
--- /dev/null
+++ zfcpdump-kernel-4.4/Documentation/devicetree/bindings/pwm/pwm-omap-dmtimer.txt
@@ -0,0 +1,18 @@
+* OMAP PWM for dual-mode timers
+
+Required properties:
+- compatible: Shall contain "ti,omap-dmtimer-pwm".
+- ti,timers: phandle to PWM capable OMAP timer. See arm/omap/timer.txt for info
+  about these timers.
+- #pwm-cells: Should be 3. See pwm.txt in this directory for a description of
+  the cells format.
+
+Optional properties:
+- ti,prescaler: Should be a value between 0 and 7, see the timers datasheet
+
+Example:
+	pwm9: dmtimer-pwm@9 {
+		compatible = "ti,omap-dmtimer-pwm";
+		ti,timers = <&timer9>;
+		#pwm-cells = <3>;
+	};
--- zfcpdump-kernel-4.4.orig/Documentation/devicetree/bindings/regulator/qcom,spmi-regulator.txt
+++ zfcpdump-kernel-4.4/Documentation/devicetree/bindings/regulator/qcom,spmi-regulator.txt
@@ -81,9 +81,9 @@ pm8916:
 	l14, l15, l16, l17, l18
 
 pm8941:
-	s1, s2, s3, l1, l2, l3, l4, l5, l6, l7, l8, l9, l10, l11, l12, l13, l14,
-	l15, l16, l17, l18, l19, l20, l21, l22, l23, l24, lvs1, lvs2, lvs3,
-	mvs1, mvs2
+	s1, s2, s3, s4, l1, l2, l3, l4, l5, l6, l7, l8, l9, l10, l11, l12, l13,
+	l14, l15, l16, l17, l18, l19, l20, l21, l22, l23, l24, lvs1, lvs2, lvs3,
+	5vs1, 5vs2
 
 The content of each sub-node is defined by the standard binding for regulators -
 see regulator.txt - with additional custom properties described below:
--- /dev/null
+++ zfcpdump-kernel-4.4/Documentation/filesystems/aufs/README
@@ -0,0 +1,390 @@
+
+Aufs4 -- advanced multi layered unification filesystem version 4.x
+http://aufs.sf.net
+Junjiro R. Okajima
+
+
+0. Introduction
+----------------------------------------
+In the early days, aufs was entirely re-designed and re-implemented
+Unionfs Version 1.x series. Adding many original ideas, approaches,
+improvements and implementations, it becomes totally different from
+Unionfs while keeping the basic features.
+Recently, Unionfs Version 2.x series begin taking some of the same
+approaches to aufs1's.
+Unionfs is being developed by Professor Erez Zadok at Stony Brook
+University and his team.
+
+Aufs4 supports linux-4.0 and later, and for linux-3.x series try aufs3.
+If you want older kernel version support, try aufs2-2.6.git or
+aufs2-standalone.git repository, aufs1 from CVS on SourceForge.
+
+Note: it becomes clear that "Aufs was rejected. Let's give it up."
+      According to Christoph Hellwig, linux rejects all union-type
+      filesystems but UnionMount.
+<http://marc.info/?l=linux-kernel&m=123938533724484&w=2>
+
+PS. Al Viro seems have a plan to merge aufs as well as overlayfs and
+    UnionMount, and he pointed out an issue around a directory mutex
+    lock and aufs addressed it. But it is still unsure whether aufs will
+    be merged (or any other union solution).
+<http://marc.info/?l=linux-kernel&m=136312705029295&w=1>
+
+
+1. Features
+----------------------------------------
+- unite several directories into a single virtual filesystem. The member
+  directory is called as a branch.
+- you can specify the permission flags to the branch, which are 'readonly',
+  'readwrite' and 'whiteout-able.'
+- by upper writable branch, internal copyup and whiteout, files/dirs on
+  readonly branch are modifiable logically.
+- dynamic branch manipulation, add, del.
+- etc...
+
+Also there are many enhancements in aufs, such as:
+- test only the highest one for the directory permission (dirperm1)
+- copyup on open (coo=)
+- 'move' policy for copy-up between two writable branches, after
+  checking free space.
+- xattr, acl
+- readdir(3) in userspace.
+- keep inode number by external inode number table
+- keep the timestamps of file/dir in internal copyup operation
+- seekable directory, supporting NFS readdir.
+- whiteout is hardlinked in order to reduce the consumption of inodes
+  on branch
+- do not copyup, nor create a whiteout when it is unnecessary
+- revert a single systemcall when an error occurs in aufs
+- remount interface instead of ioctl
+- maintain /etc/mtab by an external command, /sbin/mount.aufs.
+- loopback mounted filesystem as a branch
+- kernel thread for removing the dir who has a plenty of whiteouts
+- support copyup sparse file (a file which has a 'hole' in it)
+- default permission flags for branches
+- selectable permission flags for ro branch, whether whiteout can
+  exist or not
+- export via NFS.
+- support <sysfs>/fs/aufs and <debugfs>/aufs.
+- support multiple writable branches, some policies to select one
+  among multiple writable branches.
+- a new semantics for link(2) and rename(2) to support multiple
+  writable branches.
+- no glibc changes are required.
+- pseudo hardlink (hardlink over branches)
+- allow a direct access manually to a file on branch, e.g. bypassing aufs.
+  including NFS or remote filesystem branch.
+- userspace wrapper for pathconf(3)/fpathconf(3) with _PC_LINK_MAX.
+- and more...
+
+Currently these features are dropped temporary from aufs4.
+See design/08plan.txt in detail.
+- nested mount, i.e. aufs as readonly no-whiteout branch of another aufs
+  (robr)
+- statistics of aufs thread (/sys/fs/aufs/stat)
+
+Features or just an idea in the future (see also design/*.txt),
+- reorder the branch index without del/re-add.
+- permanent xino files for NFSD
+- an option for refreshing the opened files after add/del branches
+- light version, without branch manipulation. (unnecessary?)
+- copyup in userspace
+- inotify in userspace
+- readv/writev
+
+
+2. Download
+----------------------------------------
+There are three GIT trees for aufs4, aufs4-linux.git,
+aufs4-standalone.git, and aufs-util.git. Note that there is no "4" in
+"aufs-util.git."
+While the aufs-util is always necessary, you need either of aufs4-linux
+or aufs4-standalone.
+
+The aufs4-linux tree includes the whole linux mainline GIT tree,
+git://git.kernel.org/.../torvalds/linux.git.
+And you cannot select CONFIG_AUFS_FS=m for this version, eg. you cannot
+build aufs4 as an external kernel module.
+Several extra patches are not included in this tree. Only
+aufs4-standalone tree contains them. They are described in the later
+section "Configuration and Compilation."
+
+On the other hand, the aufs4-standalone tree has only aufs source files
+and necessary patches, and you can select CONFIG_AUFS_FS=m.
+But you need to apply all aufs patches manually.
+
+You will find GIT branches whose name is in form of "aufs4.x" where "x"
+represents the linux kernel version, "linux-4.x". For instance,
+"aufs4.0" is for linux-4.0. For latest "linux-4.x-rcN", use
+"aufs4.x-rcN" branch.
+
+o aufs4-linux tree
+$ git clone --reference /your/linux/git/tree \
+	git://github.com/sfjro/aufs4-linux.git aufs4-linux.git
+- if you don't have linux GIT tree, then remove "--reference ..."
+$ cd aufs4-linux.git
+$ git checkout origin/aufs4.0
+
+Or You may want to directly git-pull aufs into your linux GIT tree, and
+leave the patch-work to GIT.
+$ cd /your/linux/git/tree
+$ git remote add aufs4 git://github.com/sfjro/aufs4-linux.git
+$ git fetch aufs4
+$ git checkout -b my4.0 v4.0
+$ (add your local change...)
+$ git pull aufs4 aufs4.0
+- now you have v4.0 + your_changes + aufs4.0 in you my4.0 branch.
+- you may need to solve some conflicts between your_changes and
+  aufs4.0. in this case, git-rerere is recommended so that you can
+  solve the similar conflicts automatically when you upgrade to 4.1 or
+  later in the future.
+
+o aufs4-standalone tree
+$ git clone git://github.com/sfjro/aufs4-standalone.git aufs4-standalone.git
+$ cd aufs4-standalone.git
+$ git checkout origin/aufs4.0
+
+o aufs-util tree
+$ git clone git://git.code.sf.net/p/aufs/aufs-util aufs-util.git
+- note that the public aufs-util.git is on SourceForge instead of
+  GitHUB.
+$ cd aufs-util.git
+$ git checkout origin/aufs4.0
+
+Note: The 4.x-rcN branch is to be used with `rc' kernel versions ONLY.
+The minor version number, 'x' in '4.x', of aufs may not always
+follow the minor version number of the kernel.
+Because changes in the kernel that cause the use of a new
+minor version number do not always require changes to aufs-util.
+
+Since aufs-util has its own minor version number, you may not be
+able to find a GIT branch in aufs-util for your kernel's
+exact minor version number.
+In this case, you should git-checkout the branch for the
+nearest lower number.
+
+For (an unreleased) example:
+If you are using "linux-4.10" and the "aufs4.10" branch
+does not exist in aufs-util repository, then "aufs4.9", "aufs4.8"
+or something numerically smaller is the branch for your kernel.
+
+Also you can view all branches by
+	$ git branch -a
+
+
+3. Configuration and Compilation
+----------------------------------------
+Make sure you have git-checkout'ed the correct branch.
+
+For aufs4-linux tree,
+- enable CONFIG_AUFS_FS.
+- set other aufs configurations if necessary.
+
+For aufs4-standalone tree,
+There are several ways to build.
+
+1.
+- apply ./aufs4-kbuild.patch to your kernel source files.
+- apply ./aufs4-base.patch too.
+- apply ./aufs4-mmap.patch too.
+- apply ./aufs4-standalone.patch too, if you have a plan to set
+  CONFIG_AUFS_FS=m. otherwise you don't need ./aufs4-standalone.patch.
+- copy ./{Documentation,fs,include/uapi/linux/aufs_type.h} files to your
+  kernel source tree. Never copy $PWD/include/uapi/linux/Kbuild.
+- enable CONFIG_AUFS_FS, you can select either
+  =m or =y.
+- and build your kernel as usual.
+- install the built kernel.
+  Note: Since linux-3.9, every filesystem module requires an alias
+  "fs-<fsname>". You should make sure that "fs-aufs" is listed in your
+  modules.aliases file if you set CONFIG_AUFS_FS=m.
+- install the header files too by "make headers_install" to the
+  directory where you specify. By default, it is $PWD/usr.
+  "make help" shows a brief note for headers_install.
+- and reboot your system.
+
+2.
+- module only (CONFIG_AUFS_FS=m).
+- apply ./aufs4-base.patch to your kernel source files.
+- apply ./aufs4-mmap.patch too.
+- apply ./aufs4-standalone.patch too.
+- build your kernel, don't forget "make headers_install", and reboot.
+- edit ./config.mk and set other aufs configurations if necessary.
+  Note: You should read $PWD/fs/aufs/Kconfig carefully which describes
+  every aufs configurations.
+- build the module by simple "make".
+  Note: Since linux-3.9, every filesystem module requires an alias
+  "fs-<fsname>". You should make sure that "fs-aufs" is listed in your
+  modules.aliases file.
+- you can specify ${KDIR} make variable which points to your kernel
+  source tree.
+- install the files
+  + run "make install" to install the aufs module, or copy the built
+    $PWD/aufs.ko to /lib/modules/... and run depmod -a (or reboot simply).
+  + run "make install_headers" (instead of headers_install) to install
+    the modified aufs header file (you can specify DESTDIR which is
+    available in aufs standalone version's Makefile only), or copy
+    $PWD/usr/include/linux/aufs_type.h to /usr/include/linux or wherever
+    you like manually. By default, the target directory is $PWD/usr.
+- no need to apply aufs4-kbuild.patch, nor copying source files to your
+  kernel source tree.
+
+Note: The header file aufs_type.h is necessary to build aufs-util
+      as well as "make headers_install" in the kernel source tree.
+      headers_install is subject to be forgotten, but it is essentially
+      necessary, not only for building aufs-util.
+      You may not meet problems without headers_install in some older
+      version though.
+
+And then,
+- read README in aufs-util, build and install it
+- note that your distribution may contain an obsoleted version of
+  aufs_type.h in /usr/include/linux or something. When you build aufs
+  utilities, make sure that your compiler refers the correct aufs header
+  file which is built by "make headers_install."
+- if you want to use readdir(3) in userspace or pathconf(3) wrapper,
+  then run "make install_ulib" too. And refer to the aufs manual in
+  detail.
+
+There several other patches in aufs4-standalone.git. They are all
+optional. When you meet some problems, they will help you.
+- aufs4-loopback.patch
+  Supports a nested loopback mount in a branch-fs. This patch is
+  unnecessary until aufs produces a message like "you may want to try
+  another patch for loopback file".
+- vfs-ino.patch
+  Modifies a system global kernel internal function get_next_ino() in
+  order to stop assigning 0 for an inode-number. Not directly related to
+  aufs, but recommended generally.
+- tmpfs-idr.patch
+  Keeps the tmpfs inode number as the lowest value. Effective to reduce
+  the size of aufs XINO files for tmpfs branch. Also it prevents the
+  duplication of inode number, which is important for backup tools and
+  other utilities. When you find aufs XINO files for tmpfs branch
+  growing too much, try this patch.
+- lockdep-debug.patch
+  Because aufs is not only an ordinary filesystem (callee of VFS), but
+  also a caller of VFS functions for branch filesystems, subclassing of
+  the internal locks for LOCKDEP is necessary. LOCKDEP is a debugging
+  feature of linux kernel. If you enable CONFIG_LOCKDEP, then you will
+  need to apply this debug patch to expand several constant values.
+  If don't know what LOCKDEP, then you don't have apply this patch.
+
+
+4. Usage
+----------------------------------------
+At first, make sure aufs-util are installed, and please read the aufs
+manual, aufs.5 in aufs-util.git tree.
+$ man -l aufs.5
+
+And then,
+$ mkdir /tmp/rw /tmp/aufs
+# mount -t aufs -o br=/tmp/rw:${HOME} none /tmp/aufs
+
+Here is another example. The result is equivalent.
+# mount -t aufs -o br=/tmp/rw=rw:${HOME}=ro none /tmp/aufs
+  Or
+# mount -t aufs -o br:/tmp/rw none /tmp/aufs
+# mount -o remount,append:${HOME} /tmp/aufs
+
+Then, you can see whole tree of your home dir through /tmp/aufs. If
+you modify a file under /tmp/aufs, the one on your home directory is
+not affected, instead the same named file will be newly created under
+/tmp/rw. And all of your modification to a file will be applied to
+the one under /tmp/rw. This is called the file based Copy on Write
+(COW) method.
+Aufs mount options are described in aufs.5.
+If you run chroot or something and make your aufs as a root directory,
+then you need to customize the shutdown script. See the aufs manual in
+detail.
+
+Additionally, there are some sample usages of aufs which are a
+diskless system with network booting, and LiveCD over NFS.
+See sample dir in CVS tree on SourceForge.
+
+
+5. Contact
+----------------------------------------
+When you have any problems or strange behaviour in aufs, please let me
+know with:
+- /proc/mounts (instead of the output of mount(8))
+- /sys/module/aufs/*
+- /sys/fs/aufs/* (if you have them)
+- /debug/aufs/* (if you have them)
+- linux kernel version
+  if your kernel is not plain, for example modified by distributor,
+  the url where i can download its source is necessary too.
+- aufs version which was printed at loading the module or booting the
+  system, instead of the date you downloaded.
+- configuration (define/undefine CONFIG_AUFS_xxx)
+- kernel configuration or /proc/config.gz (if you have it)
+- behaviour which you think to be incorrect
+- actual operation, reproducible one is better
+- mailto: aufs-users at lists.sourceforge.net
+
+Usually, I don't watch the Public Areas(Bugs, Support Requests, Patches,
+and Feature Requests) on SourceForge. Please join and write to
+aufs-users ML.
+
+
+6. Acknowledgements
+----------------------------------------
+Thanks to everyone who have tried and are using aufs, whoever
+have reported a bug or any feedback.
+
+Especially donators:
+Tomas Matejicek(slax.org) made a donation (much more than once).
+	Since Apr 2010, Tomas M (the author of Slax and Linux Live
+	scripts) is making "doubling" donations.
+	Unfortunately I cannot list all of the donators, but I really
+	appreciate.
+	It ends Aug 2010, but the ordinary donation URL is still available.
+	<http://sourceforge.net/donate/index.php?group_id=167503>
+Dai Itasaka made a donation (2007/8).
+Chuck Smith made a donation (2008/4, 10 and 12).
+Henk Schoneveld made a donation (2008/9).
+Chih-Wei Huang, ASUS, CTC donated Eee PC 4G (2008/10).
+Francois Dupoux made a donation (2008/11).
+Bruno Cesar Ribas and Luis Carlos Erpen de Bona, C3SL serves public
+	aufs2 GIT tree (2009/2).
+William Grant made a donation (2009/3).
+Patrick Lane made a donation (2009/4).
+The Mail Archive (mail-archive.com) made donations (2009/5).
+Nippy Networks (Ed Wildgoose) made a donation (2009/7).
+New Dream Network, LLC (www.dreamhost.com) made a donation (2009/11).
+Pavel Pronskiy made a donation (2011/2).
+Iridium and Inmarsat satellite phone retailer (www.mailasail.com), Nippy
+	Networks (Ed Wildgoose) made a donation for hardware (2011/3).
+Max Lekomcev (DOM-TV project) made a donation (2011/7, 12, 2012/3, 6 and
+11).
+Sam Liddicott made a donation (2011/9).
+Era Scarecrow made a donation (2013/4).
+Bor Ratajc made a donation (2013/4).
+Alessandro Gorreta made a donation (2013/4).
+POIRETTE Marc made a donation (2013/4).
+Alessandro Gorreta made a donation (2013/4).
+lauri kasvandik made a donation (2013/5).
+"pemasu from Finland" made a donation (2013/7).
+The Parted Magic Project made a donation (2013/9 and 11).
+Pavel Barta made a donation (2013/10).
+Nikolay Pertsev made a donation (2014/5).
+James B made a donation (2014/7 and 2015/7).
+Stefano Di Biase made a donation (2014/8).
+Daniel Epellei made a donation (2015/1).
+
+Thank you very much.
+Donations are always, including future donations, very important and
+helpful for me to keep on developing aufs.
+
+
+7.
+----------------------------------------
+If you are an experienced user, no explanation is needed. Aufs is
+just a linux filesystem.
+
+
+Enjoy!
+
+# Local variables: ;
+# mode: text;
+# End: ;
--- /dev/null
+++ zfcpdump-kernel-4.4/Documentation/filesystems/aufs/design/01intro.txt
@@ -0,0 +1,170 @@
+
+# Copyright (C) 2005-2015 Junjiro R. Okajima
+# 
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+# 
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+Introduction
+----------------------------------------
+
+aufs [ei ju: ef es] | [a u f s]
+1. abbrev. for "advanced multi-layered unification filesystem".
+2. abbrev. for "another unionfs".
+3. abbrev. for "auf das" in German which means "on the" in English.
+   Ex. "Butter aufs Brot"(G) means "butter onto bread"(E).
+   But "Filesystem aufs Filesystem" is hard to understand.
+
+AUFS is a filesystem with features:
+- multi layered stackable unification filesystem, the member directory
+  is called as a branch.
+- branch permission and attribute, 'readonly', 'real-readonly',
+  'readwrite', 'whiteout-able', 'link-able whiteout', etc. and their
+  combination.
+- internal "file copy-on-write".
+- logical deletion, whiteout.
+- dynamic branch manipulation, adding, deleting and changing permission.
+- allow bypassing aufs, user's direct branch access.
+- external inode number translation table and bitmap which maintains the
+  persistent aufs inode number.
+- seekable directory, including NFS readdir.
+- file mapping, mmap and sharing pages.
+- pseudo-link, hardlink over branches.
+- loopback mounted filesystem as a branch.
+- several policies to select one among multiple writable branches.
+- revert a single systemcall when an error occurs in aufs.
+- and more...
+
+
+Multi Layered Stackable Unification Filesystem
+----------------------------------------------------------------------
+Most people already knows what it is.
+It is a filesystem which unifies several directories and provides a
+merged single directory. When users access a file, the access will be
+passed/re-directed/converted (sorry, I am not sure which English word is
+correct) to the real file on the member filesystem. The member
+filesystem is called 'lower filesystem' or 'branch' and has a mode
+'readonly' and 'readwrite.' And the deletion for a file on the lower
+readonly branch is handled by creating 'whiteout' on the upper writable
+branch.
+
+On LKML, there have been discussions about UnionMount (Jan Blunck,
+Bharata B Rao and Valerie Aurora) and Unionfs (Erez Zadok). They took
+different approaches to implement the merged-view.
+The former tries putting it into VFS, and the latter implements as a
+separate filesystem.
+(If I misunderstand about these implementations, please let me know and
+I shall correct it. Because it is a long time ago when I read their
+source files last time).
+
+UnionMount's approach will be able to small, but may be hard to share
+branches between several UnionMount since the whiteout in it is
+implemented in the inode on branch filesystem and always
+shared. According to Bharata's post, readdir does not seems to be
+finished yet.
+There are several missing features known in this implementations such as
+- for users, the inode number may change silently. eg. copy-up.
+- link(2) may break by copy-up.
+- read(2) may get an obsoleted filedata (fstat(2) too).
+- fcntl(F_SETLK) may be broken by copy-up.
+- unnecessary copy-up may happen, for example mmap(MAP_PRIVATE) after
+  open(O_RDWR).
+
+In linux-3.18, "overlay" filesystem (formerly known as "overlayfs") was
+merged into mainline. This is another implementation of UnionMount as a
+separated filesystem. All the limitations and known problems which
+UnionMount are equally inherited to "overlay" filesystem.
+
+Unionfs has a longer history. When I started implementing a stackable
+filesystem (Aug 2005), it already existed. It has virtual super_block,
+inode, dentry and file objects and they have an array pointing lower
+same kind objects. After contributing many patches for Unionfs, I
+re-started my project AUFS (Jun 2006).
+
+In AUFS, the structure of filesystem resembles to Unionfs, but I
+implemented my own ideas, approaches and enhancements and it became
+totally different one.
+
+Comparing DM snapshot and fs based implementation
+- the number of bytes to be copied between devices is much smaller.
+- the type of filesystem must be one and only.
+- the fs must be writable, no readonly fs, even for the lower original
+  device. so the compression fs will not be usable. but if we use
+  loopback mount, we may address this issue.
+  for instance,
+	mount /cdrom/squashfs.img /sq
+	losetup /sq/ext2.img
+	losetup /somewhere/cow
+	dmsetup "snapshot /dev/loop0 /dev/loop1 ..."
+- it will be difficult (or needs more operations) to extract the
+  difference between the original device and COW.
+- DM snapshot-merge may help a lot when users try merging. in the
+  fs-layer union, users will use rsync(1).
+
+You may want to read my old paper "Filesystems in LiveCD"
+(http://aufs.sourceforge.net/aufs2/report/sq/sq.pdf).
+
+
+Several characters/aspects/persona of aufs
+----------------------------------------------------------------------
+
+Aufs has several characters, aspects or persona.
+1. a filesystem, callee of VFS helper
+2. sub-VFS, caller of VFS helper for branches
+3. a virtual filesystem which maintains persistent inode number
+4. reader/writer of files on branches such like an application
+
+1. Callee of VFS Helper
+As an ordinary linux filesystem, aufs is a callee of VFS. For instance,
+unlink(2) from an application reaches sys_unlink() kernel function and
+then vfs_unlink() is called. vfs_unlink() is one of VFS helper and it
+calls filesystem specific unlink operation. Actually aufs implements the
+unlink operation but it behaves like a redirector.
+
+2. Caller of VFS Helper for Branches
+aufs_unlink() passes the unlink request to the branch filesystem as if
+it were called from VFS. So the called unlink operation of the branch
+filesystem acts as usual. As a caller of VFS helper, aufs should handle
+every necessary pre/post operation for the branch filesystem.
+- acquire the lock for the parent dir on a branch
+- lookup in a branch
+- revalidate dentry on a branch
+- mnt_want_write() for a branch
+- vfs_unlink() for a branch
+- mnt_drop_write() for a branch
+- release the lock on a branch
+
+3. Persistent Inode Number
+One of the most important issue for a filesystem is to maintain inode
+numbers. This is particularly important to support exporting a
+filesystem via NFS. Aufs is a virtual filesystem which doesn't have a
+backend block device for its own. But some storage is necessary to
+keep and maintain the inode numbers. It may be a large space and may not
+suit to keep in memory. Aufs rents some space from its first writable
+branch filesystem (by default) and creates file(s) on it. These files
+are created by aufs internally and removed soon (currently) keeping
+opened.
+Note: Because these files are removed, they are totally gone after
+      unmounting aufs. It means the inode numbers are not persistent
+      across unmount or reboot. I have a plan to make them really
+      persistent which will be important for aufs on NFS server.
+
+4. Read/Write Files Internally (copy-on-write)
+Because a branch can be readonly, when you write a file on it, aufs will
+"copy-up" it to the upper writable branch internally. And then write the
+originally requested thing to the file. Generally kernel doesn't
+open/read/write file actively. In aufs, even a single write may cause a
+internal "file copy". This behaviour is very similar to cp(1) command.
+
+Some people may think it is better to pass such work to user space
+helper, instead of doing in kernel space. Actually I am still thinking
+about it. But currently I have implemented it in kernel space.
--- /dev/null
+++ zfcpdump-kernel-4.4/Documentation/filesystems/aufs/design/02struct.txt
@@ -0,0 +1,258 @@
+
+# Copyright (C) 2005-2015 Junjiro R. Okajima
+# 
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+# 
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+Basic Aufs Internal Structure
+
+Superblock/Inode/Dentry/File Objects
+----------------------------------------------------------------------
+As like an ordinary filesystem, aufs has its own
+superblock/inode/dentry/file objects. All these objects have a
+dynamically allocated array and store the same kind of pointers to the
+lower filesystem, branch.
+For example, when you build a union with one readwrite branch and one
+readonly, mounted /au, /rw and /ro respectively.
+- /au = /rw + /ro
+- /ro/fileA exists but /rw/fileA
+
+Aufs lookup operation finds /ro/fileA and gets dentry for that. These
+pointers are stored in a aufs dentry. The array in aufs dentry will be,
+- [0] = NULL (because /rw/fileA doesn't exist)
+- [1] = /ro/fileA
+
+This style of an array is essentially same to the aufs
+superblock/inode/dentry/file objects.
+
+Because aufs supports manipulating branches, ie. add/delete/change
+branches dynamically, these objects has its own generation. When
+branches are changed, the generation in aufs superblock is
+incremented. And a generation in other object are compared when it is
+accessed. When a generation in other objects are obsoleted, aufs
+refreshes the internal array.
+
+
+Superblock
+----------------------------------------------------------------------
+Additionally aufs superblock has some data for policies to select one
+among multiple writable branches, XIB files, pseudo-links and kobject.
+See below in detail.
+About the policies which supports copy-down a directory, see
+wbr_policy.txt too.
+
+
+Branch and XINO(External Inode Number Translation Table)
+----------------------------------------------------------------------
+Every branch has its own xino (external inode number translation table)
+file. The xino file is created and unlinked by aufs internally. When two
+members of a union exist on the same filesystem, they share the single
+xino file.
+The struct of a xino file is simple, just a sequence of aufs inode
+numbers which is indexed by the lower inode number.
+In the above sample, assume the inode number of /ro/fileA is i111 and
+aufs assigns the inode number i999 for fileA. Then aufs writes 999 as
+4(8) bytes at 111 * 4(8) bytes offset in the xino file.
+
+When the inode numbers are not contiguous, the xino file will be sparse
+which has a hole in it and doesn't consume as much disk space as it
+might appear. If your branch filesystem consumes disk space for such
+holes, then you should specify 'xino=' option at mounting aufs.
+
+Aufs has a mount option to free the disk blocks for such holes in XINO
+files on tmpfs or ramdisk. But it is not so effective actually. If you
+meet a problem of disk shortage due to XINO files, then you should try
+"tmpfs-ino.patch" (and "vfs-ino.patch" too) in aufs4-standalone.git.
+The patch localizes the assignment inumbers per tmpfs-mount and avoid
+the holes in XINO files.
+
+Also a writable branch has three kinds of "whiteout bases". All these
+are existed when the branch is joined to aufs, and their names are
+whiteout-ed doubly, so that users will never see their names in aufs
+hierarchy.
+1. a regular file which will be hardlinked to all whiteouts.
+2. a directory to store a pseudo-link.
+3. a directory to store an "orphan"-ed file temporary.
+
+1. Whiteout Base
+   When you remove a file on a readonly branch, aufs handles it as a
+   logical deletion and creates a whiteout on the upper writable branch
+   as a hardlink of this file in order not to consume inode on the
+   writable branch.
+2. Pseudo-link Dir
+   See below, Pseudo-link.
+3. Step-Parent Dir
+   When "fileC" exists on the lower readonly branch only and it is
+   opened and removed with its parent dir, and then user writes
+   something into it, then aufs copies-up fileC to this
+   directory. Because there is no other dir to store fileC. After
+   creating a file under this dir, the file is unlinked.
+
+Because aufs supports manipulating branches, ie. add/delete/change
+dynamically, a branch has its own id. When the branch order changes,
+aufs finds the new index by searching the branch id.
+
+
+Pseudo-link
+----------------------------------------------------------------------
+Assume "fileA" exists on the lower readonly branch only and it is
+hardlinked to "fileB" on the branch. When you write something to fileA,
+aufs copies-up it to the upper writable branch. Additionally aufs
+creates a hardlink under the Pseudo-link Directory of the writable
+branch. The inode of a pseudo-link is kept in aufs super_block as a
+simple list. If fileB is read after unlinking fileA, aufs returns
+filedata from the pseudo-link instead of the lower readonly
+branch. Because the pseudo-link is based upon the inode, to keep the
+inode number by xino (see above) is essentially necessary.
+
+All the hardlinks under the Pseudo-link Directory of the writable branch
+should be restored in a proper location later. Aufs provides a utility
+to do this. The userspace helpers executed at remounting and unmounting
+aufs by default.
+During this utility is running, it puts aufs into the pseudo-link
+maintenance mode. In this mode, only the process which began the
+maintenance mode (and its child processes) is allowed to operate in
+aufs. Some other processes which are not related to the pseudo-link will
+be allowed to run too, but the rest have to return an error or wait
+until the maintenance mode ends. If a process already acquires an inode
+mutex (in VFS), it has to return an error.
+
+
+XIB(external inode number bitmap)
+----------------------------------------------------------------------
+Addition to the xino file per a branch, aufs has an external inode number
+bitmap in a superblock object. It is also an internal file such like a
+xino file.
+It is a simple bitmap to mark whether the aufs inode number is in-use or
+not.
+To reduce the file I/O, aufs prepares a single memory page to cache xib.
+
+As well as XINO files, aufs has a feature to truncate/refresh XIB to
+reduce the number of consumed disk blocks for these files.
+
+
+Virtual or Vertical Dir, and Readdir in Userspace
+----------------------------------------------------------------------
+In order to support multiple layers (branches), aufs readdir operation
+constructs a virtual dir block on memory. For readdir, aufs calls
+vfs_readdir() internally for each dir on branches, merges their entries
+with eliminating the whiteout-ed ones, and sets it to file (dir)
+object. So the file object has its entry list until it is closed. The
+entry list will be updated when the file position is zero and becomes
+obsoleted. This decision is made in aufs automatically.
+
+The dynamically allocated memory block for the name of entries has a
+unit of 512 bytes (by default) and stores the names contiguously (no
+padding). Another block for each entry is handled by kmem_cache too.
+During building dir blocks, aufs creates hash list and judging whether
+the entry is whiteouted by its upper branch or already listed.
+The merged result is cached in the corresponding inode object and
+maintained by a customizable life-time option.
+
+Some people may call it can be a security hole or invite DoS attack
+since the opened and once readdir-ed dir (file object) holds its entry
+list and becomes a pressure for system memory. But I'd say it is similar
+to files under /proc or /sys. The virtual files in them also holds a
+memory page (generally) while they are opened. When an idea to reduce
+memory for them is introduced, it will be applied to aufs too.
+For those who really hate this situation, I've developed readdir(3)
+library which operates this merging in userspace. You just need to set
+LD_PRELOAD environment variable, and aufs will not consume no memory in
+kernel space for readdir(3).
+
+
+Workqueue
+----------------------------------------------------------------------
+Aufs sometimes requires privilege access to a branch. For instance,
+in copy-up/down operation. When a user process is going to make changes
+to a file which exists in the lower readonly branch only, and the mode
+of one of ancestor directories may not be writable by a user
+process. Here aufs copy-up the file with its ancestors and they may
+require privilege to set its owner/group/mode/etc.
+This is a typical case of a application character of aufs (see
+Introduction).
+
+Aufs uses workqueue synchronously for this case. It creates its own
+workqueue. The workqueue is a kernel thread and has privilege. Aufs
+passes the request to call mkdir or write (for example), and wait for
+its completion. This approach solves a problem of a signal handler
+simply.
+If aufs didn't adopt the workqueue and changed the privilege of the
+process, then the process may receive the unexpected SIGXFSZ or other
+signals.
+
+Also aufs uses the system global workqueue ("events" kernel thread) too
+for asynchronous tasks, such like handling inotify/fsnotify, re-creating a
+whiteout base and etc. This is unrelated to a privilege.
+Most of aufs operation tries acquiring a rw_semaphore for aufs
+superblock at the beginning, at the same time waits for the completion
+of all queued asynchronous tasks.
+
+
+Whiteout
+----------------------------------------------------------------------
+The whiteout in aufs is very similar to Unionfs's. That is represented
+by its filename. UnionMount takes an approach of a file mode, but I am
+afraid several utilities (find(1) or something) will have to support it.
+
+Basically the whiteout represents "logical deletion" which stops aufs to
+lookup further, but also it represents "dir is opaque" which also stop
+further lookup.
+
+In aufs, rmdir(2) and rename(2) for dir uses whiteout alternatively.
+In order to make several functions in a single systemcall to be
+revertible, aufs adopts an approach to rename a directory to a temporary
+unique whiteouted name.
+For example, in rename(2) dir where the target dir already existed, aufs
+renames the target dir to a temporary unique whiteouted name before the
+actual rename on a branch, and then handles other actions (make it opaque,
+update the attributes, etc). If an error happens in these actions, aufs
+simply renames the whiteouted name back and returns an error. If all are
+succeeded, aufs registers a function to remove the whiteouted unique
+temporary name completely and asynchronously to the system global
+workqueue.
+
+
+Copy-up
+----------------------------------------------------------------------
+It is a well-known feature or concept.
+When user modifies a file on a readonly branch, aufs operate "copy-up"
+internally and makes change to the new file on the upper writable branch.
+When the trigger systemcall does not update the timestamps of the parent
+dir, aufs reverts it after copy-up.
+
+
+Move-down (aufs3.9 and later)
+----------------------------------------------------------------------
+"Copy-up" is one of the essential feature in aufs. It copies a file from
+the lower readonly branch to the upper writable branch when a user
+changes something about the file.
+"Move-down" is an opposite action of copy-up. Basically this action is
+ran manually instead of automatically and internally.
+For desgin and implementation, aufs has to consider these issues.
+- whiteout for the file may exist on the lower branch.
+- ancestor directories may not exist on the lower branch.
+- diropq for the ancestor directories may exist on the upper branch.
+- free space on the lower branch will reduce.
+- another access to the file may happen during moving-down, including
+  UDBA (see "Revalidate Dentry and UDBA").
+- the file should not be hard-linked nor pseudo-linked. they should be
+  handled by auplink utility later.
+
+Sometimes users want to move-down a file from the upper writable branch
+to the lower readonly or writable branch. For instance,
+- the free space of the upper writable branch is going to run out.
+- create a new intermediate branch between the upper and lower branch.
+- etc.
+
+For this purpose, use "aumvdown" command in aufs-util.git.
--- /dev/null
+++ zfcpdump-kernel-4.4/Documentation/filesystems/aufs/design/03atomic_open.txt
@@ -0,0 +1,85 @@
+
+# Copyright (C) 2015 Junjiro R. Okajima
+# 
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+# 
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+Support for a branch who has its ->atomic_open()
+----------------------------------------------------------------------
+The filesystems who implement its ->atomic_open() are not majority. For
+example NFSv4 does, and aufs should call NFSv4 ->atomic_open,
+particularly for open(O_CREAT|O_EXCL, 0400) case. Other than
+->atomic_open(), NFSv4 returns an error for this open(2). While I am not
+sure whether all filesystems who have ->atomic_open() behave like this,
+but NFSv4 surely returns the error.
+
+In order to support ->atomic_open() for aufs, there are a few
+approaches.
+
+A. Introduce aufs_atomic_open()
+   - calls one of VFS:do_last(), lookup_open() or atomic_open() for
+     branch fs.
+B. Introduce aufs_atomic_open() calling create, open and chmod. this is
+   an aufs user Pip Cet's approach
+   - calls aufs_create(), VFS finish_open() and notify_change().
+   - pass fake-mode to finish_open(), and then correct the mode by
+     notify_change().
+C. Extend aufs_open() to call branch fs's ->atomic_open()
+   - no aufs_atomic_open().
+   - aufs_lookup() registers the TID to an aufs internal object.
+   - aufs_create() does nothing when the matching TID is registered, but
+     registers the mode.
+   - aufs_open() calls branch fs's ->atomic_open() when the matching
+     TID is registered.
+D. Extend aufs_open() to re-try branch fs's ->open() with superuser's
+   credential
+   - no aufs_atomic_open().
+   - aufs_create() registers the TID to an internal object. this info
+     represents "this process created this file just now."
+   - when aufs gets EACCES from branch fs's ->open(), then confirm the
+     registered TID and re-try open() with superuser's credential.
+
+Pros and cons for each approach.
+
+A.
+   - straightforward but highly depends upon VFS internal.
+   - the atomic behavaiour is kept.
+   - some of parameters such as nameidata are hard to reproduce for
+     branch fs.
+   - large overhead.
+B.
+   - easy to implement.
+   - the atomic behavaiour is lost.
+C.
+   - the atomic behavaiour is kept.
+   - dirty and tricky.
+   - VFS checks whether the file is created correctly after calling
+     ->create(), which means this approach doesn't work.
+D.
+   - easy to implement.
+   - the atomic behavaiour is lost.
+   - to open a file with superuser's credential and give it to a user
+     process is a bad idea, since the file object keeps the credential
+     in it. It may affect LSM or something. This approach doesn't work
+     either.
+
+The approach A is ideal, but it hard to implement. So here is a
+variation of A, which is to be implemented.
+
+A-1. Introduce aufs_atomic_open()
+     - calls branch fs ->atomic_open() if exists. otherwise calls
+       vfs_create() and finish_open().
+     - the demerit is that the several checks after branch fs
+       ->atomic_open() are lost. in the ordinary case, the checks are
+       done by VFS:do_last(), lookup_open() and atomic_open(). some can
+       be implemented in aufs, but not all I am afraid.
--- /dev/null
+++ zfcpdump-kernel-4.4/Documentation/filesystems/aufs/design/03lookup.txt
@@ -0,0 +1,113 @@
+
+# Copyright (C) 2005-2015 Junjiro R. Okajima
+# 
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+# 
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+Lookup in a Branch
+----------------------------------------------------------------------
+Since aufs has a character of sub-VFS (see Introduction), it operates
+lookup for branches as VFS does. It may be a heavy work. But almost all
+lookup operation in aufs is the simplest case, ie. lookup only an entry
+directly connected to its parent. Digging down the directory hierarchy
+is unnecessary. VFS has a function lookup_one_len() for that use, and
+aufs calls it.
+
+When a branch is a remote filesystem, aufs basically relies upon its
+->d_revalidate(), also aufs forces the hardest revalidate tests for
+them.
+For d_revalidate, aufs implements three levels of revalidate tests. See
+"Revalidate Dentry and UDBA" in detail.
+
+
+Test Only the Highest One for the Directory Permission (dirperm1 option)
+----------------------------------------------------------------------
+Let's try case study.
+- aufs has two branches, upper readwrite and lower readonly.
+  /au = /rw + /ro
+- "dirA" exists under /ro, but /rw. and its mode is 0700.
+- user invoked "chmod a+rx /au/dirA"
+- the internal copy-up is activated and "/rw/dirA" is created and its
+  permission bits are set to world readable.
+- then "/au/dirA" becomes world readable?
+
+In this case, /ro/dirA is still 0700 since it exists in readonly branch,
+or it may be a natively readonly filesystem. If aufs respects the lower
+branch, it should not respond readdir request from other users. But user
+allowed it by chmod. Should really aufs rejects showing the entries
+under /ro/dirA?
+
+To be honest, I don't have a good solution for this case. So aufs
+implements 'dirperm1' and 'nodirperm1' mount options, and leave it to
+users.
+When dirperm1 is specified, aufs checks only the highest one for the
+directory permission, and shows the entries. Otherwise, as usual, checks
+every dir existing on all branches and rejects the request.
+
+As a side effect, dirperm1 option improves the performance of aufs
+because the number of permission check is reduced when the number of
+branch is many.
+
+
+Revalidate Dentry and UDBA (User's Direct Branch Access)
+----------------------------------------------------------------------
+Generally VFS helpers re-validate a dentry as a part of lookup.
+0. digging down the directory hierarchy.
+1. lock the parent dir by its i_mutex.
+2. lookup the final (child) entry.
+3. revalidate it.
+4. call the actual operation (create, unlink, etc.)
+5. unlock the parent dir
+
+If the filesystem implements its ->d_revalidate() (step 3), then it is
+called. Actually aufs implements it and checks the dentry on a branch is
+still valid.
+But it is not enough. Because aufs has to release the lock for the
+parent dir on a branch at the end of ->lookup() (step 2) and
+->d_revalidate() (step 3) while the i_mutex of the aufs dir is still
+held by VFS.
+If the file on a branch is changed directly, eg. bypassing aufs, after
+aufs released the lock, then the subsequent operation may cause
+something unpleasant result.
+
+This situation is a result of VFS architecture, ->lookup() and
+->d_revalidate() is separated. But I never say it is wrong. It is a good
+design from VFS's point of view. It is just not suitable for sub-VFS
+character in aufs.
+
+Aufs supports such case by three level of revalidation which is
+selectable by user.
+1. Simple Revalidate
+   Addition to the native flow in VFS's, confirm the child-parent
+   relationship on the branch just after locking the parent dir on the
+   branch in the "actual operation" (step 4). When this validation
+   fails, aufs returns EBUSY. ->d_revalidate() (step 3) in aufs still
+   checks the validation of the dentry on branches.
+2. Monitor Changes Internally by Inotify/Fsnotify
+   Addition to above, in the "actual operation" (step 4) aufs re-lookup
+   the dentry on the branch, and returns EBUSY if it finds different
+   dentry.
+   Additionally, aufs sets the inotify/fsnotify watch for every dir on branches
+   during it is in cache. When the event is notified, aufs registers a
+   function to kernel 'events' thread by schedule_work(). And the
+   function sets some special status to the cached aufs dentry and inode
+   private data. If they are not cached, then aufs has nothing to
+   do. When the same file is accessed through aufs (step 0-3) later,
+   aufs will detect the status and refresh all necessary data.
+   In this mode, aufs has to ignore the event which is fired by aufs
+   itself.
+3. No Extra Validation
+   This is the simplest test and doesn't add any additional revalidation
+   test, and skip the revalidation in step 4. It is useful and improves
+   aufs performance when system surely hide the aufs branches from user,
+   by over-mounting something (or another method).
--- /dev/null
+++ zfcpdump-kernel-4.4/Documentation/filesystems/aufs/design/04branch.txt
@@ -0,0 +1,74 @@
+
+# Copyright (C) 2005-2015 Junjiro R. Okajima
+# 
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+# 
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+Branch Manipulation
+
+Since aufs supports dynamic branch manipulation, ie. add/remove a branch
+and changing its permission/attribute, there are a lot of works to do.
+
+
+Add a Branch
+----------------------------------------------------------------------
+o Confirm the adding dir exists outside of aufs, including loopback
+  mount, and its various attributes.
+o Initialize the xino file and whiteout bases if necessary.
+  See struct.txt.
+
+o Check the owner/group/mode of the directory
+  When the owner/group/mode of the adding directory differs from the
+  existing branch, aufs issues a warning because it may impose a
+  security risk.
+  For example, when a upper writable branch has a world writable empty
+  top directory, a malicious user can create any files on the writable
+  branch directly, like copy-up and modify manually. If something like
+  /etc/{passwd,shadow} exists on the lower readonly branch but the upper
+  writable branch, and the writable branch is world-writable, then a
+  malicious guy may create /etc/passwd on the writable branch directly
+  and the infected file will be valid in aufs.
+  I am afraid it can be a security issue, but aufs can do nothing except
+  producing a warning.
+
+
+Delete a Branch
+----------------------------------------------------------------------
+o Confirm the deleting branch is not busy
+  To be general, there is one merit to adopt "remount" interface to
+  manipulate branches. It is to discard caches. At deleting a branch,
+  aufs checks the still cached (and connected) dentries and inodes. If
+  there are any, then they are all in-use. An inode without its
+  corresponding dentry can be alive alone (for example, inotify/fsnotify case).
+
+  For the cached one, aufs checks whether the same named entry exists on
+  other branches.
+  If the cached one is a directory, because aufs provides a merged view
+  to users, as long as one dir is left on any branch aufs can show the
+  dir to users. In this case, the branch can be removed from aufs.
+  Otherwise aufs rejects deleting the branch.
+
+  If any file on the deleting branch is opened by aufs, then aufs
+  rejects deleting.
+
+
+Modify the Permission of a Branch
+----------------------------------------------------------------------
+o Re-initialize or remove the xino file and whiteout bases if necessary.
+  See struct.txt.
+
+o rw --> ro: Confirm the modifying branch is not busy
+  Aufs rejects the request if any of these conditions are true.
+  - a file on the branch is mmap-ed.
+  - a regular file on the branch is opened for write and there is no
+    same named entry on the upper branch.
--- /dev/null
+++ zfcpdump-kernel-4.4/Documentation/filesystems/aufs/design/05wbr_policy.txt
@@ -0,0 +1,64 @@
+
+# Copyright (C) 2005-2015 Junjiro R. Okajima
+# 
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+# 
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+Policies to Select One among Multiple Writable Branches
+----------------------------------------------------------------------
+When the number of writable branch is more than one, aufs has to decide
+the target branch for file creation or copy-up. By default, the highest
+writable branch which has the parent (or ancestor) dir of the target
+file is chosen (top-down-parent policy).
+By user's request, aufs implements some other policies to select the
+writable branch, for file creation several policies, round-robin,
+most-free-space, and other policies. For copy-up, top-down-parent,
+bottom-up-parent, bottom-up and others.
+
+As expected, the round-robin policy selects the branch in circular. When
+you have two writable branches and creates 10 new files, 5 files will be
+created for each branch. mkdir(2) systemcall is an exception. When you
+create 10 new directories, all will be created on the same branch.
+And the most-free-space policy selects the one which has most free
+space among the writable branches. The amount of free space will be
+checked by aufs internally, and users can specify its time interval.
+
+The policies for copy-up is more simple,
+top-down-parent is equivalent to the same named on in create policy,
+bottom-up-parent selects the writable branch where the parent dir
+exists and the nearest upper one from the copyup-source,
+bottom-up selects the nearest upper writable branch from the
+copyup-source, regardless the existence of the parent dir.
+
+There are some rules or exceptions to apply these policies.
+- If there is a readonly branch above the policy-selected branch and
+  the parent dir is marked as opaque (a variation of whiteout), or the
+  target (creating) file is whiteout-ed on the upper readonly branch,
+  then the result of the policy is ignored and the target file will be
+  created on the nearest upper writable branch than the readonly branch.
+- If there is a writable branch above the policy-selected branch and
+  the parent dir is marked as opaque or the target file is whiteouted
+  on the branch, then the result of the policy is ignored and the target
+  file will be created on the highest one among the upper writable
+  branches who has diropq or whiteout. In case of whiteout, aufs removes
+  it as usual.
+- link(2) and rename(2) systemcalls are exceptions in every policy.
+  They try selecting the branch where the source exists as possible
+  since copyup a large file will take long time. If it can't be,
+  ie. the branch where the source exists is readonly, then they will
+  follow the copyup policy.
+- There is an exception for rename(2) when the target exists.
+  If the rename target exists, aufs compares the index of the branches
+  where the source and the target exists and selects the higher
+  one. If the selected branch is readonly, then aufs follows the
+  copyup policy.
--- /dev/null
+++ zfcpdump-kernel-4.4/Documentation/filesystems/aufs/design/06fhsm.txt
@@ -0,0 +1,120 @@
+
+# Copyright (C) 2011-2015 Junjiro R. Okajima
+# 
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+# 
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+
+File-based Hierarchical Storage Management (FHSM)
+----------------------------------------------------------------------
+Hierarchical Storage Management (or HSM) is a well-known feature in the
+storage world. Aufs provides this feature as file-based with multiple
+writable branches, based upon the principle of "Colder, the Lower".
+Here the word "colder" means that the less used files, and "lower" means
+that the position in the order of the stacked branches vertically.
+These multiple writable branches are prioritized, ie. the topmost one
+should be the fastest drive and be used heavily.
+
+o Characters in aufs FHSM story
+- aufs itself and a new branch attribute.
+- a new ioctl interface to move-down and to establish a connection with
+  the daemon ("move-down" is a converse of "copy-up").
+- userspace tool and daemon.
+
+The userspace daemon establishes a connection with aufs and waits for
+the notification. The notified information is very similar to struct
+statfs containing the number of consumed blocks and inodes.
+When the consumed blocks/inodes of a branch exceeds the user-specified
+upper watermark, the daemon activates its move-down process until the
+consumed blocks/inodes reaches the user-specified lower watermark.
+
+The actual move-down is done by aufs based upon the request from
+user-space since we need to maintain the inode number and the internal
+pointer arrays in aufs.
+
+Currently aufs FHSM handles the regular files only. Additionally they
+must not be hard-linked nor pseudo-linked.
+
+
+o Cowork of aufs and the user-space daemon
+  During the userspace daemon established the connection, aufs sends a
+  small notification to it whenever aufs writes something into the
+  writable branch. But it may cost high since aufs issues statfs(2)
+  internally. So user can specify a new option to cache the
+  info. Actually the notification is controlled by these factors.
+  + the specified cache time.
+  + classified as "force" by aufs internally.
+  Until the specified time expires, aufs doesn't send the info
+  except the forced cases. When aufs decide forcing, the info is always
+  notified to userspace.
+  For example, the number of free inodes is generally large enough and
+  the shortage of it happens rarely. So aufs doesn't force the
+  notification when creating a new file, directory and others. This is
+  the typical case which aufs doesn't force.
+  When aufs writes the actual filedata and the files consumes any of new
+  blocks, the aufs forces notifying.
+
+
+o Interfaces in aufs
+- New branch attribute.
+  + fhsm
+    Specifies that the branch is managed by FHSM feature. In other word,
+    participant in the FHSM.
+    When nofhsm is set to the branch, it will not be the source/target
+    branch of the move-down operation. This attribute is set
+    independently from coo and moo attributes, and if you want full
+    FHSM, you should specify them as well.
+- New mount option.
+  + fhsm_sec
+    Specifies a second to suppress many less important info to be
+    notified.
+- New ioctl.
+  + AUFS_CTL_FHSM_FD
+    create a new file descriptor which userspace can read the notification
+    (a subset of struct statfs) from aufs.
+- Module parameter 'brs'
+  It has to be set to 1. Otherwise the new mount option 'fhsm' will not
+  be set.
+- mount helpers /sbin/mount.aufs and /sbin/umount.aufs
+  When there are two or more branches with fhsm attributes,
+  /sbin/mount.aufs invokes the user-space daemon and /sbin/umount.aufs
+  terminates it. As a result of remounting and branch-manipulation, the
+  number of branches with fhsm attribute can be one. In this case,
+  /sbin/mount.aufs will terminate the user-space daemon.
+
+
+Finally the operation is done as these steps in kernel-space.
+- make sure that,
+  + no one else is using the file.
+  + the file is not hard-linked.
+  + the file is not pseudo-linked.
+  + the file is a regular file.
+  + the parent dir is not opaqued.
+- find the target writable branch.
+- make sure the file is not whiteout-ed by the upper (than the target)
+  branch.
+- make the parent dir on the target branch.
+- mutex lock the inode on the branch.
+- unlink the whiteout on the target branch (if exists).
+- lookup and create the whiteout-ed temporary name on the target branch.
+- copy the file as the whiteout-ed temporary name on the target branch.
+- rename the whiteout-ed temporary name to the original name.
+- unlink the file on the source branch.
+- maintain the internal pointer array and the external inode number
+  table (XINO).
+- maintain the timestamps and other attributes of the parent dir and the
+  file.
+
+And of course, in every step, an error may happen. So the operation
+should restore the original file state after an error happens.
--- /dev/null
+++ zfcpdump-kernel-4.4/Documentation/filesystems/aufs/design/06mmap.txt
@@ -0,0 +1,72 @@
+
+# Copyright (C) 2005-2015 Junjiro R. Okajima
+# 
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+# 
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+mmap(2) -- File Memory Mapping
+----------------------------------------------------------------------
+In aufs, the file-mapped pages are handled by a branch fs directly, no
+interaction with aufs. It means aufs_mmap() calls the branch fs's
+->mmap().
+This approach is simple and good, but there is one problem.
+Under /proc, several entries show the mmapped files by its path (with
+device and inode number), and the printed path will be the path on the
+branch fs's instead of virtual aufs's.
+This is not a problem in most cases, but some utilities lsof(1) (and its
+user) may expect the path on aufs.
+
+To address this issue, aufs adds a new member called vm_prfile in struct
+vm_area_struct (and struct vm_region). The original vm_file points to
+the file on the branch fs in order to handle everything correctly as
+usual. The new vm_prfile points to a virtual file in aufs, and the
+show-functions in procfs refers to vm_prfile if it is set.
+Also we need to maintain several other places where touching vm_file
+such like
+- fork()/clone() copies vma and the reference count of vm_file is
+  incremented.
+- merging vma maintains the ref count too.
+
+This is not a good approach. It just fakes the printed path. But it
+leaves all behaviour around f_mapping unchanged. This is surely an
+advantage.
+Actually aufs had adopted another complicated approach which calls
+generic_file_mmap() and handles struct vm_operations_struct. In this
+approach, aufs met a hard problem and I could not solve it without
+switching the approach.
+
+There may be one more another approach which is
+- bind-mount the branch-root onto the aufs-root internally
+- grab the new vfsmount (ie. struct mount)
+- lazy-umount the branch-root internally
+- in open(2) the aufs-file, open the branch-file with the hidden
+  vfsmount (instead of the original branch's vfsmount)
+- ideally this "bind-mount and lazy-umount" should be done atomically,
+  but it may be possible from userspace by the mount helper.
+
+Adding the internal hidden vfsmount and using it in opening a file, the
+file path under /proc will be printed correctly. This approach looks
+smarter, but is not possible I am afraid.
+- aufs-root may be bind-mount later. when it happens, another hidden
+  vfsmount will be required.
+- it is hard to get the chance to bind-mount and lazy-umount
+  + in kernel-space, FS can have vfsmount in open(2) via
+    file->f_path, and aufs can know its vfsmount. But several locks are
+    already acquired, and if aufs tries to bind-mount and lazy-umount
+    here, then it may cause a deadlock.
+  + in user-space, bind-mount doesn't invoke the mount helper.
+- since /proc shows dev and ino, aufs has to give vma these info. it
+  means a new member vm_prinode will be necessary. this is essentially
+  equivalent to vm_prfile described above.
+
+I have to give up this "looks-smater" approach.
--- /dev/null
+++ zfcpdump-kernel-4.4/Documentation/filesystems/aufs/design/06xattr.txt
@@ -0,0 +1,96 @@
+
+# Copyright (C) 2014-2015 Junjiro R. Okajima
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+
+Listing XATTR/EA and getting the value
+----------------------------------------------------------------------
+For the inode standard attributes (owner, group, timestamps, etc.), aufs
+shows the values from the topmost existing file. This behaviour is good
+for the non-dir entries since the bahaviour exactly matches the shown
+information. But for the directories, aufs considers all the same named
+entries on the lower branches. Which means, if one of the lower entry
+rejects readdir call, then aufs returns an error even if the topmost
+entry allows it. This behaviour is necessary to respect the branch fs's
+security, but can make users confused since the user-visible standard
+attributes don't match the behaviour.
+To address this issue, aufs has a mount option called dirperm1 which
+checks the permission for the topmost entry only, and ignores the lower
+entry's permission.
+
+A similar issue can happen around XATTR.
+getxattr(2) and listxattr(2) families behave as if dirperm1 option is
+always set. Otherwise these very unpleasant situation would happen.
+- listxattr(2) may return the duplicated entries.
+- users may not be able to remove or reset the XATTR forever,
+
+
+XATTR/EA support in the internal (copy,move)-(up,down)
+----------------------------------------------------------------------
+Generally the extended attributes of inode are categorized as these.
+- "security" for LSM and capability.
+- "system" for posix ACL, 'acl' mount option is required for the branch
+  fs generally.
+- "trusted" for userspace, CAP_SYS_ADMIN is required.
+- "user" for userspace, 'user_xattr' mount option is required for the
+  branch fs generally.
+
+Moreover there are some other categories. Aufs handles these rather
+unpopular categories as the ordinary ones, ie. there is no special
+condition nor exception.
+
+In copy-up, the support for XATTR on the dst branch may differ from the
+src branch. In this case, the copy-up operation will get an error and
+the original user operation which triggered the copy-up will fail. It
+can happen that even all copy-up will fail.
+When both of src and dst branches support XATTR and if an error occurs
+during copying XATTR, then the copy-up should fail obviously. That is a
+good reason and aufs should return an error to userspace. But when only
+the src branch support that XATTR, aufs should not return an error.
+For example, the src branch supports ACL but the dst branch doesn't
+because the dst branch may natively un-support it or temporary
+un-support it due to "noacl" mount option. Of course, the dst branch fs
+may NOT return an error even if the XATTR is not supported. It is
+totally up to the branch fs.
+
+Anyway when the aufs internal copy-up gets an error from the dst branch
+fs, then aufs tries removing the just copied entry and returns the error
+to the userspace. The worst case of this situation will be all copy-up
+will fail.
+
+For the copy-up operation, there two basic approaches.
+- copy the specified XATTR only (by category above), and return the
+  error unconditionally if it happens.
+- copy all XATTR, and ignore the error on the specified category only.
+
+In order to support XATTR and to implement the correct behaviour, aufs
+chooses the latter approach and introduces some new branch attributes,
+"icexsec", "icexsys", "icextr", "icexusr", and "icexoth".
+They correspond to the XATTR namespaces (see above). Additionally, to be
+convenient, "icex" is also provided which means all "icex*" attributes
+are set (here the word "icex" stands for "ignore copy-error on XATTR").
+
+The meaning of these attributes is to ignore the error from setting
+XATTR on that branch.
+Note that aufs tries copying all XATTR unconditionally, and ignores the
+error from the dst branch according to the specified attributes.
+
+Some XATTR may have its default value. The default value may come from
+the parent dir or the environment. If the default value is set at the
+file creating-time, it will be overwritten by copy-up.
+Some contradiction may happen I am afraid.
+Do we need another attribute to stop copying XATTR? I am unsure. For
+now, aufs implements the branch attributes to ignore the error.
--- /dev/null
+++ zfcpdump-kernel-4.4/Documentation/filesystems/aufs/design/07export.txt
@@ -0,0 +1,58 @@
+
+# Copyright (C) 2005-2015 Junjiro R. Okajima
+# 
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+# 
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+Export Aufs via NFS
+----------------------------------------------------------------------
+Here is an approach.
+- like xino/xib, add a new file 'xigen' which stores aufs inode
+  generation.
+- iget_locked(): initialize aufs inode generation for a new inode, and
+  store it in xigen file.
+- destroy_inode(): increment aufs inode generation and store it in xigen
+  file. it is necessary even if it is not unlinked, because any data of
+  inode may be changed by UDBA.
+- encode_fh(): for a root dir, simply return FILEID_ROOT. otherwise
+  build file handle by
+  + branch id (4 bytes)
+  + superblock generation (4 bytes)
+  + inode number (4 or 8 bytes)
+  + parent dir inode number (4 or 8 bytes)
+  + inode generation (4 bytes))
+  + return value of exportfs_encode_fh() for the parent on a branch (4
+    bytes)
+  + file handle for a branch (by exportfs_encode_fh())
+- fh_to_dentry():
+  + find the index of a branch from its id in handle, and check it is
+    still exist in aufs.
+  + 1st level: get the inode number from handle and search it in cache.
+  + 2nd level: if not found in cache, get the parent inode number from
+    the handle and search it in cache. and then open the found parent
+    dir, find the matching inode number by vfs_readdir() and get its
+    name, and call lookup_one_len() for the target dentry.
+  + 3rd level: if the parent dir is not cached, call
+    exportfs_decode_fh() for a branch and get the parent on a branch,
+    build a pathname of it, convert it a pathname in aufs, call
+    path_lookup(). now aufs gets a parent dir dentry, then handle it as
+    the 2nd level.
+  + to open the dir, aufs needs struct vfsmount. aufs keeps vfsmount
+    for every branch, but not itself. to get this, (currently) aufs
+    searches in current->nsproxy->mnt_ns list. it may not be a good
+    idea, but I didn't get other approach.
+  + test the generation of the gotten inode.
+- every inode operation: they may get EBUSY due to UDBA. in this case,
+  convert it into ESTALE for NFSD.
+- readdir(): call lockdep_on/off() because filldir in NFSD calls
+  lookup_one_len(), vfs_getattr(), encode_fh() and others.
--- /dev/null
+++ zfcpdump-kernel-4.4/Documentation/filesystems/aufs/design/08shwh.txt
@@ -0,0 +1,52 @@
+
+# Copyright (C) 2005-2015 Junjiro R. Okajima
+# 
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+# 
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+Show Whiteout Mode (shwh)
+----------------------------------------------------------------------
+Generally aufs hides the name of whiteouts. But in some cases, to show
+them is very useful for users. For instance, creating a new middle layer
+(branch) by merging existing layers.
+
+(borrowing aufs1 HOW-TO from a user, Michael Towers)
+When you have three branches,
+- Bottom: 'system', squashfs (underlying base system), read-only
+- Middle: 'mods', squashfs, read-only
+- Top: 'overlay', ram (tmpfs), read-write
+
+The top layer is loaded at boot time and saved at shutdown, to preserve
+the changes made to the system during the session.
+When larger changes have been made, or smaller changes have accumulated,
+the size of the saved top layer data grows. At this point, it would be
+nice to be able to merge the two overlay branches ('mods' and 'overlay')
+and rewrite the 'mods' squashfs, clearing the top layer and thus
+restoring save and load speed.
+
+This merging is simplified by the use of another aufs mount, of just the
+two overlay branches using the 'shwh' option.
+# mount -t aufs -o ro,shwh,br:/livesys/overlay=ro+wh:/livesys/mods=rr+wh \
+	aufs /livesys/merge_union
+
+A merged view of these two branches is then available at
+/livesys/merge_union, and the new feature is that the whiteouts are
+visible!
+Note that in 'shwh' mode the aufs mount must be 'ro', which will disable
+writing to all branches. Also the default mode for all branches is 'ro'.
+It is now possible to save the combined contents of the two overlay
+branches to a new squashfs, e.g.:
+# mksquashfs /livesys/merge_union /path/to/newmods.squash
+
+This new squashfs archive can be stored on the boot device and the
+initramfs will use it to replace the old one at the next boot.
--- /dev/null
+++ zfcpdump-kernel-4.4/Documentation/filesystems/aufs/design/10dynop.txt
@@ -0,0 +1,47 @@
+
+# Copyright (C) 2010-2015 Junjiro R. Okajima
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+Dynamically customizable FS operations
+----------------------------------------------------------------------
+Generally FS operations (struct inode_operations, struct
+address_space_operations, struct file_operations, etc.) are defined as
+"static const", but it never means that FS have only one set of
+operation. Some FS have multiple sets of them. For instance, ext2 has
+three sets, one for XIP, for NOBH, and for normal.
+Since aufs overrides and redirects these operations, sometimes aufs has
+to change its behaviour according to the branch FS type. More importantly
+VFS acts differently if a function (member in the struct) is set or
+not. It means aufs should have several sets of operations and select one
+among them according to the branch FS definition.
+
+In order to solve this problem and not to affect the behaviour of VFS,
+aufs defines these operations dynamically. For instance, aufs defines
+dummy direct_IO function for struct address_space_operations, but it may
+not be set to the address_space_operations actually. When the branch FS
+doesn't have it, aufs doesn't set it to its address_space_operations
+while the function definition itself is still alive. So the behaviour
+itself will not change, and it will return an error when direct_IO is
+not set.
+
+The lifetime of these dynamically generated operation object is
+maintained by aufs branch object. When the branch is removed from aufs,
+the reference counter of the object is decremented. When it reaches
+zero, the dynamically generated operation object will be freed.
+
+This approach is designed to support AIO (io_submit), Direct I/O and
+XIP (DAX) mainly.
+Currently this approach is applied to address_space_operations for
+regular files only.
--- zfcpdump-kernel-4.4.orig/Documentation/filesystems/efivarfs.txt
+++ zfcpdump-kernel-4.4/Documentation/filesystems/efivarfs.txt
@@ -14,3 +14,10 @@ filesystem.
 efivarfs is typically mounted like this,
 
 	mount -t efivarfs none /sys/firmware/efi/efivars
+
+Due to the presence of numerous firmware bugs where removing non-standard
+UEFI variables causes the system firmware to fail to POST, efivarfs
+files that are not well-known standardized variables are created
+as immutable files.  This doesn't prevent removal - "chattr -i" will work -
+but it does prevent this kind of failure from being accomplished
+accidentally.
--- zfcpdump-kernel-4.4.orig/Documentation/filesystems/proc.txt
+++ zfcpdump-kernel-4.4/Documentation/filesystems/proc.txt
@@ -346,7 +346,7 @@ address           perms offset  dev   in
 a7cb1000-a7cb2000 ---p 00000000 00:00 0
 a7cb2000-a7eb2000 rw-p 00000000 00:00 0
 a7eb2000-a7eb3000 ---p 00000000 00:00 0
-a7eb3000-a7ed5000 rw-p 00000000 00:00 0          [stack:1001]
+a7eb3000-a7ed5000 rw-p 00000000 00:00 0
 a7ed5000-a8008000 r-xp 00000000 03:00 4222       /lib/libc.so.6
 a8008000-a800a000 r--p 00133000 03:00 4222       /lib/libc.so.6
 a800a000-a800b000 rw-p 00135000 03:00 4222       /lib/libc.so.6
@@ -378,7 +378,6 @@ is not associated with a file:
 
  [heap]                   = the heap of the program
  [stack]                  = the stack of the main process
- [stack:1001]             = the stack of the thread with tid 1001
  [vdso]                   = the "virtual dynamic shared object",
                             the kernel system call handler
 
@@ -386,10 +385,8 @@ is not associated with a file:
 
 The /proc/PID/task/TID/maps is a view of the virtual memory from the viewpoint
 of the individual tasks of a process. In this file you will see a mapping marked
-as [stack] if that task sees it as a stack. This is a key difference from the
-content of /proc/PID/maps, where you will see all mappings that are being used
-as stack by all of those tasks. Hence, for the example above, the task-level
-map, i.e. /proc/PID/task/TID/maps for thread 1001 will look like this:
+as [stack] if that task sees it as a stack. Hence, for the example above, the
+task-level map, i.e. /proc/PID/task/TID/maps for thread 1001 will look like this:
 
 08048000-08049000 r-xp 00000000 03:00 8312       /opt/test
 08049000-0804a000 rw-p 00001000 03:00 8312       /opt/test
--- /dev/null
+++ zfcpdump-kernel-4.4/Documentation/hid/hid-alps.txt
@@ -0,0 +1,139 @@
+ALPS HID Touchpad Protocol
+----------------------
+
+Introduction
+------------
+Currently ALPS HID driver supports U1 Touchpad device.
+
+U1 devuce basic information.
+Vender ID	0x044E
+Product ID	0x120B
+Version ID	0x0121
+
+
+HID Descriptor
+------------
+Byte	Field			Value	Notes
+0	wHIDDescLength		001E	Length of HID Descriptor : 30 bytes
+2	bcdVersion		0100	Compliant with Version 1.00
+4	wReportDescLength	00B2	Report Descriptor is 178 Bytes (0x00B2)
+6	wReportDescRegister	0002	Identifier to read Report Descriptor
+8	wInputRegister		0003	Identifier to read Input Report
+10	wMaxInputLength		0053	Input Report is 80 Bytes + 2
+12	wOutputRegister		0000	Identifier to read Output Report
+14	wMaxOutputLength	0000	No Output Reports
+16	wCommandRegister	0005	Identifier for Command Register
+18	wDataRegister		0006	Identifier for Data Register
+20	wVendorID		044E	Vendor ID 0x044E
+22	wProductID		120B	Product ID 0x120B
+24	wVersionID		0121	Version 01.21
+26	RESERVED		0000	RESERVED
+
+
+Report ID
+------------
+ReportID-1	(Input Reports)	(HIDUsage-Mouse) for TP&SP
+ReportID-2	(Input Reports)	(HIDUsage-keyboard) for TP
+ReportID-3	(Input Reports)	(Vendor Usage: Max 10 finger data) for TP
+ReportID-4	(Input Reports)	(Vendor Usage: ON bit data) for GP
+ReportID-5	(Feature Reports)	Feature Reports
+ReportID-6	(Input Reports)	(Vendor Usage: StickPointer data) for SP
+ReportID-7	(Feature Reports)	Flash update (Bootloader)
+
+
+Data pattern
+------------
+Case1	ReportID_1	TP/SP	Relative/Relative
+Case2	ReportID_3	TP	Absolute
+	ReportID_6	SP	Absolute
+
+
+Command Read/Write
+------------------
+To read/write to RAM, need to send a commands to the device.
+The command format is as below.
+
+DataByte(SET_REPORT)
+Byte1	Command Byte
+Byte2	Address - Byte 0 (LSB)
+Byte3	Address - Byte 1
+Byte4	Address - Byte 2
+Byte5	Address - Byte 3 (MSB)
+Byte6	Value Byte
+Byte7	Checksum
+
+Command Byte is read=0xD1/write=0xD2 .
+Address is read/write RAM address.
+Value Byte is writing data when you send the write commands.
+When you read RAM, there is no meaning.
+
+DataByte(GET_REPORT)
+Byte1	Response Byte
+Byte2	Address - Byte 0 (LSB)
+Byte3	Address - Byte 1
+Byte4	Address - Byte 2
+Byte5	Address - Byte 3 (MSB)
+Byte6	Value Byte
+Byte7	Checksum
+
+Read value is stored in Value Byte.
+
+
+Packet Format
+Touchpad data byte
+------------------
+	b7	b6	b5	b4	b3	b2	b1	b0
+1	0	0	SW6	SW5	SW4	SW3	SW2	SW1
+2	0	0	0	Fcv	Fn3	Fn2	Fn1	Fn0
+3	Xa0_7	Xa0_6	Xa0_5	Xa0_4	Xa0_3	Xa0_2	Xa0_1	Xa0_0
+4	Xa0_15	Xa0_14	Xa0_13	Xa0_12	Xa0_11	Xa0_10	Xa0_9	Xa0_8
+5	Ya0_7	Ya0_6	Ya0_5	Ya0_4	Ya0_3	Ya0_2	Ya0_1	Ya0_0
+6	Ya0_15	Ya0_14	Ya0_13	Ya0_12	Ya0_11	Ya0_10	Ya0_9	Ya0_8
+7	LFB0	Zs0_6	Zs0_5	Zs0_4	Zs0_3	Zs0_2	Zs0_1	Zs0_0
+
+8	Xa1_7	Xa1_6	Xa1_5	Xa1_4	Xa1_3	Xa1_2	Xa1_1	Xa1_0
+9	Xa1_15	Xa1_14	Xa1_13	Xa1_12	Xa1_11	Xa1_10	Xa1_9	Xa1_8
+10	Ya1_7	Ya1_6	Ya1_5	Ya1_4	Ya1_3	Ya1_2	Ya1_1	Ya1_0
+11	Ya1_15	Ya1_14	Ya1_13	Ya1_12	Ya1_11	Ya1_10	Ya1_9	Ya1_8
+12	LFB1	Zs1_6	Zs1_5	Zs1_4	Zs1_3	Zs1_2	Zs1_1	Zs1_0
+
+13	Xa2_7	Xa2_6	Xa2_5	Xa2_4	Xa2_3	Xa2_2	Xa2_1	Xa2_0
+14	Xa2_15	Xa2_14	Xa2_13	Xa2_12	Xa2_11	Xa2_10	Xa2_9	Xa2_8
+15	Ya2_7	Ya2_6	Ya2_5	Ya2_4	Ya2_3	Ya2_2	Ya2_1	Ya2_0
+16	Ya2_15	Ya2_14	Ya2_13	Ya2_12	Ya2_11	Ya2_10	Ya2_9	Ya2_8
+17	LFB2	Zs2_6	Zs2_5	Zs2_4	Zs2_3	Zs2_2	Zs2_1	Zs2_0
+
+18	Xa3_7	Xa3_6	Xa3_5	Xa3_4	Xa3_3	Xa3_2	Xa3_1	Xa3_0
+19	Xa3_15	Xa3_14	Xa3_13	Xa3_12	Xa3_11	Xa3_10	Xa3_9	Xa3_8
+20	Ya3_7	Ya3_6	Ya3_5	Ya3_4	Ya3_3	Ya3_2	Ya3_1	Ya3_0
+21	Ya3_15	Ya3_14	Ya3_13	Ya3_12	Ya3_11	Ya3_10	Ya3_9	Ya3_8
+22	LFB3	Zs3_6	Zs3_5	Zs3_4	Zs3_3	Zs3_2	Zs3_1	Zs3_0
+
+23	Xa4_7	Xa4_6	Xa4_5	Xa4_4	Xa4_3	Xa4_2	Xa4_1	Xa4_0
+24	Xa4_15	Xa4_14	Xa4_13	Xa4_12	Xa4_11	Xa4_10	Xa4_9	Xa4_8
+25	Ya4_7	Ya4_6	Ya4_5	Ya4_4	Ya4_3	Ya4_2	Ya4_1	Ya4_0
+26	Ya4_15	Ya4_14	Ya4_13	Ya4_12	Ya4_11	Ya4_10	Ya4_9	Ya4_8
+27	LFB4	Zs4_6	Zs4_5	Zs4_4	Zs4_3	Zs4_2	Zs4_1	Zs4_0
+
+
+SW1-SW6:	SW ON/OFF status
+Xan_15-0(16bit):X Absolute data of the "n"th finger
+Yan_15-0(16bit):Y Absolute data of the "n"th finger
+Zsn_6-0(7bit):	Operation area of the "n"th finger
+
+
+StickPointer data byte
+------------------
+	b7	b6	b5	b4	b3	b2	b1	b0
+Byte1	1	1	1	0	1	SW3	SW2	SW1
+Byte2	X7	X6	X5	X4	X3	X2	X1	X0
+Byte3	X15	X14	X13	X12	X11	X10	X9	X8
+Byte4	Y7	Y6	Y5	Y4	Y3	Y2	Y1	Y0
+Byte5	Y15	Y14	Y13	Y12	Y11	Y10	Y9	Y8
+Byte6	Z7	Z6	Z5	Z4	Z3	Z2	Z1	Z0
+Byte7	T&P	Z14	Z13	Z12	Z11	Z10	Z9	Z8
+
+SW1-SW3:	SW ON/OFF status
+Xn_15-0(16bit):X Absolute data
+Yn_15-0(16bit):Y Absolute data
+Zn_14-0(15bit):Z
--- zfcpdump-kernel-4.4.orig/Documentation/kernel-parameters.txt
+++ zfcpdump-kernel-4.4/Documentation/kernel-parameters.txt
@@ -193,6 +193,12 @@ bytes respectively. Such letter suffixes
 			(e.g. thinkpad_acpi, sony_acpi, etc.) instead
 			of the ACPI video.ko driver.
 
+	acpi_force_32bit_fadt_addr
+			force FADT to use 32 bit addresses rather than the
+			64 bit X_* addresses. Some firmware have broken 64
+			bit addresses for force ACPI ignore these and use
+			the older legacy 32 bit addresss.
+
 	acpica_no_return_repair [HW, ACPI]
 			Disable AML predefined validation mechanism
 			This mechanism can repair the evaluation result to make
@@ -652,7 +658,7 @@ bytes respectively. Such letter suffixes
 
 	clearcpuid=BITNUM [X86]
 			Disable CPUID feature X for the kernel. See
-			arch/x86/include/asm/cpufeature.h for the valid bit
+			arch/x86/include/asm/cpufeatures.h for the valid bit
 			numbers. Note the Linux specific bits are not necessarily
 			stable over kernel options, but the vendor specific
 			ones should be.
@@ -750,6 +756,10 @@ bytes respectively. Such letter suffixes
 			/proc/<pid>/coredump_filter.
 			See also Documentation/filesystems/proc.txt.
 
+	cpufreq_driver= [X86] Allow only the named cpu frequency scaling driver
+			to register. Example: cpufreq_driver=powernow-k8
+			Format: { none | STRING }
+
 	cpuidle.off=1	[CPU_IDLE]
 			disable the cpuidle sub-system
 
@@ -3928,6 +3938,8 @@ bytes respectively. Such letter suffixes
 					sector if the number is odd);
 				i = IGNORE_DEVICE (don't bind to this
 					device);
+				j = NO_REPORT_LUNS (don't use report luns
+					command, uas only);
 				l = NOT_LOCKABLE (don't try to lock and
 					unlock ejectable media);
 				m = MAX_SECTORS_64 (don't transfer more
--- zfcpdump-kernel-4.4.orig/Documentation/memory-barriers.txt
+++ zfcpdump-kernel-4.4/Documentation/memory-barriers.txt
@@ -1655,17 +1655,18 @@ macro is a good place to start looking.
 SMP memory barriers are reduced to compiler barriers on uniprocessor compiled
 systems because it is assumed that a CPU will appear to be self-consistent,
 and will order overlapping accesses correctly with respect to itself.
+However, see the subsection on "Virtual Machine Guests" below.
 
 [!] Note that SMP memory barriers _must_ be used to control the ordering of
 references to shared memory on SMP systems, though the use of locking instead
 is sufficient.
 
 Mandatory barriers should not be used to control SMP effects, since mandatory
-barriers unnecessarily impose overhead on UP systems. They may, however, be
-used to control MMIO effects on accesses through relaxed memory I/O windows.
-These are required even on non-SMP systems as they affect the order in which
-memory operations appear to a device by prohibiting both the compiler and the
-CPU from reordering them.
+barriers impose unnecessary overhead on both SMP and UP systems. They may,
+however, be used to control MMIO effects on accesses through relaxed memory I/O
+windows.  These barriers are required even on non-SMP systems as they affect
+the order in which memory operations appear to a device by prohibiting both the
+compiler and the CPU from reordering them.
 
 
 There are some more advanced barrier functions:
@@ -2948,6 +2949,23 @@ The Alpha defines the Linux kernel's mem
 
 See the subsection on "Cache Coherency" above.
 
+VIRTUAL MACHINE GUESTS
+-------------------
+
+Guests running within virtual machines might be affected by SMP effects even if
+the guest itself is compiled without SMP support.  This is an artifact of
+interfacing with an SMP host while running an UP kernel.  Using mandatory
+barriers for this use-case would be possible but is often suboptimal.
+
+To handle this case optimally, low-level virt_mb() etc macros are available.
+These have the same effect as smp_mb() etc when SMP is enabled, but generate
+identical code for SMP and non-SMP systems. For example, virtual machine guests
+should use virt_mb() rather than smp_mb() when synchronizing against a
+(possibly SMP) host.
+
+These are equivalent to smp_mb() etc counterparts in all other respects,
+in particular, they do not control MMIO effects: to control
+MMIO effects, use mandatory barriers.
 
 ============
 EXAMPLE USES
--- zfcpdump-kernel-4.4.orig/Documentation/mic/mpssd/mpssd.c
+++ zfcpdump-kernel-4.4/Documentation/mic/mpssd/mpssd.c
@@ -1538,9 +1538,9 @@ set_cmdline(struct mic_info *mic)
 
 	len = snprintf(buffer, PATH_MAX,
 		"clocksource=tsc highres=off nohz=off ");
-	len += snprintf(buffer + len, PATH_MAX,
+	len += snprintf(buffer + len, PATH_MAX - len,
 		"cpufreq_on;corec6_off;pc3_off;pc6_off ");
-	len += snprintf(buffer + len, PATH_MAX,
+	len += snprintf(buffer + len, PATH_MAX - len,
 		"ifcfg=static;address,172.31.%d.1;netmask,255.255.255.0",
 		mic->id + 1);
 
--- zfcpdump-kernel-4.4.orig/Documentation/module-signing.txt
+++ zfcpdump-kernel-4.4/Documentation/module-signing.txt
@@ -271,3 +271,9 @@ Since the private key is used to sign mo
 the private key to sign modules and compromise the operating system.  The
 private key must be either destroyed or moved to a secure location and not kept
 in the root node of the kernel source tree.
+
+If you use the same private key to sign modules for multiple kernel
+configurations, you must ensure that the module version information is
+sufficient to prevent loading a module into a different kernel.  Either
+set CONFIG_MODVERSIONS=y or ensure that each configuration has a different
+kernel release string by changing EXTRAVERSION or CONFIG_LOCALVERSION.
--- zfcpdump-kernel-4.4.orig/Documentation/networking/00-INDEX
+++ zfcpdump-kernel-4.4/Documentation/networking/00-INDEX
@@ -72,6 +72,8 @@ dns_resolver.txt
 	- The DNS resolver module allows kernel servies to make DNS queries.
 driver.txt
 	- Softnet driver issues.
+ena.txt
+	- info on Amazon's Elastic Network Adapter (ENA)
 e100.txt
 	- info on Intel's EtherExpress PRO/100 line of 10/100 boards
 e1000.txt
--- zfcpdump-kernel-4.4.orig/Documentation/pinctrl.txt
+++ zfcpdump-kernel-4.4/Documentation/pinctrl.txt
@@ -831,7 +831,7 @@ separate memory range only intended for
 range dealing with pin config and pin multiplexing get placed into a
 different memory range and a separate section of the data sheet.
 
-A flag "strict" in struct pinctrl_desc is available to check and deny
+A flag "strict" in struct pinmux_ops is available to check and deny
 simultaneous access to the same pin from GPIO and pin multiplexing
 consumers on hardware of this type. The pinctrl driver should set this flag
 accordingly.
--- zfcpdump-kernel-4.4.orig/Documentation/power/runtime_pm.txt
+++ zfcpdump-kernel-4.4/Documentation/power/runtime_pm.txt
@@ -371,6 +371,12 @@ drivers/base/power/runtime.c and include
     - increment the device's usage counter, run pm_runtime_resume(dev) and
       return its result
 
+  int pm_runtime_get_if_in_use(struct device *dev);
+    - return -EINVAL if 'power.disable_depth' is nonzero; otherwise, if the
+      runtime PM status is RPM_ACTIVE and the runtime PM usage counter is
+      nonzero, increment the counter and return 1; otherwise return 0 without
+      changing the counter
+
   void pm_runtime_put_noidle(struct device *dev);
     - decrement the device's usage counter
 
--- zfcpdump-kernel-4.4.orig/Documentation/powerpc/cxl.txt
+++ zfcpdump-kernel-4.4/Documentation/powerpc/cxl.txt
@@ -116,6 +116,8 @@ Work Element Descriptor (WED)
 User API
 ========
 
+1. AFU character devices
+
     For AFUs operating in AFU directed mode, two character device
     files will be created. /dev/cxl/afu0.0m will correspond to a
     master context and /dev/cxl/afu0.0s will correspond to a slave
@@ -362,6 +364,59 @@ read
         reserved fields:
             For future extensions and padding
 
+
+2. Card character device (powerVM guest only)
+
+    In a powerVM guest, an extra character device is created for the
+    card. The device is only used to write (flash) a new image on the
+    FPGA accelerator. Once the image is written and verified, the
+    device tree is updated and the card is reset to reload the updated
+    image.
+
+open
+----
+
+    Opens the device and allocates a file descriptor to be used with
+    the rest of the API. The device can only be opened once.
+
+ioctl
+-----
+
+CXL_IOCTL_DOWNLOAD_IMAGE:
+CXL_IOCTL_VALIDATE_IMAGE:
+    Starts and controls flashing a new FPGA image. Partial
+    reconfiguration is not supported (yet), so the image must contain
+    a copy of the PSL and AFU(s). Since an image can be quite large,
+    the caller may have to iterate, splitting the image in smaller
+    chunks.
+
+    Takes a pointer to a struct cxl_adapter_image:
+        struct cxl_adapter_image {
+            __u64 flags;
+            __u64 data;
+            __u64 len_data;
+            __u64 len_image;
+            __u64 reserved1;
+            __u64 reserved2;
+            __u64 reserved3;
+            __u64 reserved4;
+        };
+
+    flags:
+        These flags indicate which optional fields are present in
+        this struct. Currently all fields are mandatory.
+
+    data:
+        Pointer to a buffer with part of the image to write to the
+        card.
+
+    len_data:
+        Size of the buffer pointed to by data.
+
+    len_image:
+        Full size of the image.
+
+
 Sysfs Class
 ===========
 
--- zfcpdump-kernel-4.4.orig/Documentation/ptp/testptp.c
+++ zfcpdump-kernel-4.4/Documentation/ptp/testptp.c
@@ -277,13 +277,15 @@ int main(int argc, char *argv[])
 			       "  %d external time stamp channels\n"
 			       "  %d programmable periodic signals\n"
 			       "  %d pulse per second\n"
-			       "  %d programmable pins\n",
+			       "  %d programmable pins\n"
+			       "  %d cross timestamping\n",
 			       caps.max_adj,
 			       caps.n_alarm,
 			       caps.n_ext_ts,
 			       caps.n_per_out,
 			       caps.pps,
-			       caps.n_pins);
+			       caps.n_pins,
+			       caps.cross_timestamping);
 		}
 	}
 
--- zfcpdump-kernel-4.4.orig/Documentation/scsi/scsi_eh.txt
+++ zfcpdump-kernel-4.4/Documentation/scsi/scsi_eh.txt
@@ -263,19 +263,23 @@ scmd->allowed.
 
  3. scmd recovered
     ACTION: scsi_eh_finish_cmd() is invoked to EH-finish scmd
-	- shost->host_failed--
 	- clear scmd->eh_eflags
 	- scsi_setup_cmd_retry()
 	- move from local eh_work_q to local eh_done_q
     LOCKING: none
+    CONCURRENCY: at most one thread per separate eh_work_q to
+		 keep queue manipulation lockless
 
  4. EH completes
     ACTION: scsi_eh_flush_done_q() retries scmds or notifies upper
-	    layer of failure.
+	    layer of failure. May be called concurrently but must have
+	    a no more than one thread per separate eh_work_q to
+	    manipulate the queue locklessly
 	- scmd is removed from eh_done_q and scmd->eh_entry is cleared
 	- if retry is necessary, scmd is requeued using
           scsi_queue_insert()
 	- otherwise, scsi_finish_command() is invoked for scmd
+	- zero shost->host_failed
     LOCKING: queue or finish function performs appropriate locking
 
 
--- zfcpdump-kernel-4.4.orig/Documentation/security/keys-trusted-encrypted.txt
+++ zfcpdump-kernel-4.4/Documentation/security/keys-trusted-encrypted.txt
@@ -27,17 +27,26 @@ Usage:
     keyctl print keyid
 
     options:
-       keyhandle= ascii hex value of sealing key default 0x40000000 (SRK)
-       keyauth=	  ascii hex auth for sealing key default 0x00...i
-		  (40 ascii zeros)
-       blobauth=  ascii hex auth for sealed data default 0x00...
-		  (40 ascii zeros)
-       blobauth=  ascii hex auth for sealed data default 0x00...
-		  (40 ascii zeros)
-       pcrinfo=	  ascii hex of PCR_INFO or PCR_INFO_LONG (no default)
-       pcrlock=	  pcr number to be extended to "lock" blob
-       migratable= 0|1 indicating permission to reseal to new PCR values,
-                   default 1 (resealing allowed)
+       keyhandle=    ascii hex value of sealing key default 0x40000000 (SRK)
+       keyauth=	     ascii hex auth for sealing key default 0x00...i
+                     (40 ascii zeros)
+       blobauth=     ascii hex auth for sealed data default 0x00...
+                     (40 ascii zeros)
+       blobauth=     ascii hex auth for sealed data default 0x00...
+                     (40 ascii zeros)
+       pcrinfo=	     ascii hex of PCR_INFO or PCR_INFO_LONG (no default)
+       pcrlock=	     pcr number to be extended to "lock" blob
+       migratable=   0|1 indicating permission to reseal to new PCR values,
+                     default 1 (resealing allowed)
+       hash=         hash algorithm name as a string. For TPM 1.x the only
+                     allowed value is sha1. For TPM 2.x the allowed values
+                     are sha1, sha256, sha384, sha512 and sm3-256.
+       policydigest= digest for the authorization policy. must be calculated
+                     with the same hash algorithm as specified by the 'hash='
+                     option.
+       policyhandle= handle to an authorization policy session that defines the
+                     same policy and with the same hash algorithm as was used to
+                     seal the key.
 
 "keyctl print" returns an ascii hex copy of the sealed key, which is in standard
 TPM_STORED_DATA format.  The key length for new keys are always in bytes.
--- zfcpdump-kernel-4.4.orig/Documentation/serial/tty.txt
+++ zfcpdump-kernel-4.4/Documentation/serial/tty.txt
@@ -213,9 +213,6 @@ TTY_IO_ERROR		If set, causes all subsequ
 
 TTY_OTHER_CLOSED	Device is a pty and the other side has closed.
 
-TTY_OTHER_DONE		Device is a pty and the other side has closed and
-			all pending input processing has been completed.
-
 TTY_NO_WRITE_SPLIT	Prevent driver from splitting up writes into
 			smaller chunks.
 
--- zfcpdump-kernel-4.4.orig/Documentation/sysctl/fs.txt
+++ zfcpdump-kernel-4.4/Documentation/sysctl/fs.txt
@@ -32,6 +32,8 @@ Currently, these files are in /proc/sys/
 - nr_open
 - overflowuid
 - overflowgid
+- pipe-user-pages-hard
+- pipe-user-pages-soft
 - protected_hardlinks
 - protected_symlinks
 - suid_dumpable
@@ -159,6 +161,27 @@ The default is 65534.
 
 ==============================================================
 
+pipe-user-pages-hard:
+
+Maximum total number of pages a non-privileged user may allocate for pipes.
+Once this limit is reached, no new pipes may be allocated until usage goes
+below the limit again. When set to 0, no limit is applied, which is the default
+setting.
+
+==============================================================
+
+pipe-user-pages-soft:
+
+Maximum total number of pages a non-privileged user may allocate for pipes
+before the pipe size gets limited to a single page. Once this limit is reached,
+new pipes will be limited to a single page in size for this user in order to
+limit total memory usage, and trying to increase them using fcntl() will be
+denied until usage goes below the limit again. The default value allows to
+allocate up to 1024 pipes at their default size. When set to 0, no limit is
+applied.
+
+==============================================================
+
 protected_hardlinks:
 
 A long-standing class of security issues is the hardlink-based
--- zfcpdump-kernel-4.4.orig/Documentation/usb/power-management.txt
+++ zfcpdump-kernel-4.4/Documentation/usb/power-management.txt
@@ -537,17 +537,18 @@ relevant attribute files are usb2_hardwa
 		can write y/Y/1 or n/N/0 to the file to	enable/disable
 		USB2 hardware LPM manually. This is for	test purpose mainly.
 
-	power/usb3_hardware_lpm
+	power/usb3_hardware_lpm_u1
+	power/usb3_hardware_lpm_u2
 
 		When a USB 3.0 lpm-capable device is plugged in to a
 		xHCI host which supports link PM, it will check if U1
 		and U2 exit latencies have been set in the BOS
 		descriptor; if the check is is passed and the host
 		supports USB3 hardware LPM, USB3 hardware LPM will be
-		enabled for the device and this file will be created.
-		The file holds a string value (enable or disable)
-		indicating whether or not USB3 hardware LPM is
-		enabled for the device.
+		enabled for the device and these files will be created.
+		The files hold a string value (enable or disable)
+		indicating whether or not USB3 hardware LPM U1 or U2
+		is enabled for the device.
 
 	USB Port Power Control
 	----------------------
--- zfcpdump-kernel-4.4.orig/Documentation/virtual/kvm/api.txt
+++ zfcpdump-kernel-4.4/Documentation/virtual/kvm/api.txt
@@ -1451,6 +1451,7 @@ struct kvm_irq_routing_entry {
 		struct kvm_irq_routing_irqchip irqchip;
 		struct kvm_irq_routing_msi msi;
 		struct kvm_irq_routing_s390_adapter adapter;
+		struct kvm_irq_routing_hv_sint hv_sint;
 		__u32 pad[8];
 	} u;
 };
@@ -1459,6 +1460,7 @@ struct kvm_irq_routing_entry {
 #define KVM_IRQ_ROUTING_IRQCHIP 1
 #define KVM_IRQ_ROUTING_MSI 2
 #define KVM_IRQ_ROUTING_S390_ADAPTER 3
+#define KVM_IRQ_ROUTING_HV_SINT 4
 
 No flags are specified so far, the corresponding field must be set to zero.
 
@@ -1482,6 +1484,10 @@ struct kvm_irq_routing_s390_adapter {
 	__u32 adapter_id;
 };
 
+struct kvm_irq_routing_hv_sint {
+	__u32 vcpu;
+	__u32 sint;
+};
 
 4.53 KVM_ASSIGN_SET_MSIX_NR (deprecated)
 
@@ -3331,6 +3337,28 @@ the userspace IOAPIC should process the
 it is still asserted.  Vector is the LAPIC interrupt vector for which the
 EOI was received.
 
+		struct kvm_hyperv_exit {
+#define KVM_EXIT_HYPERV_SYNIC          1
+			__u32 type;
+			union {
+				struct {
+					__u32 msr;
+					__u64 control;
+					__u64 evt_page;
+					__u64 msg_page;
+				} synic;
+			} u;
+		};
+		/* KVM_EXIT_HYPERV */
+                struct kvm_hyperv_exit hyperv;
+Indicates that the VCPU exits into userspace to process some tasks
+related to Hyper-V emulation.
+Valid values for 'type' are:
+	KVM_EXIT_HYPERV_SYNIC -- synchronously notify user-space about
+Hyper-V SynIC state change. Notification is used to remap SynIC
+event/message pages and to enable/disable SynIC messages/events processing
+in userspace.
+
 		/* Fix the size of the union. */
 		char padding[256];
 	};
@@ -3685,3 +3713,16 @@ available, means that that the kernel ha
 H_RANDOM hypercall backed by a hardware random-number generator.
 If present, the kernel H_RANDOM handler can be enabled for guest use
 with the KVM_CAP_PPC_ENABLE_HCALL capability.
+
+8.2 KVM_CAP_HYPERV_SYNIC
+
+Architectures: x86
+This capability, if KVM_CHECK_EXTENSION indicates that it is
+available, means that that the kernel has an implementation of the
+Hyper-V Synthetic interrupt controller(SynIC). Hyper-V SynIC is
+used to support Windows Hyper-V based guest paravirt drivers(VMBus).
+
+In order to use SynIC, it has to be activated by setting this
+capability via KVM_ENABLE_CAP ioctl on the vcpu fd. Note that this
+will disable the use of APIC hardware virtualization even if supported
+by the CPU, as it's incompatible with SynIC auto-EOI behavior.
--- zfcpdump-kernel-4.4.orig/Documentation/virtual/kvm/mmu.txt
+++ zfcpdump-kernel-4.4/Documentation/virtual/kvm/mmu.txt
@@ -358,7 +358,8 @@ In the first case there are two addition
 - if CR4.SMEP is enabled: since we've turned the page into a kernel page,
   the kernel may now execute it.  We handle this by also setting spte.nx.
   If we get a user fetch or read fault, we'll change spte.u=1 and
-  spte.nx=gpte.nx back.
+  spte.nx=gpte.nx back.  For this to work, KVM forces EFER.NX to 1 when
+  shadow paging is in use.
 - if CR4.SMAP is disabled: since the page has been changed to a kernel
   page, it can not be reused when CR4.SMAP is enabled. We set
   CR4.SMAP && !CR0.WP into shadow page's role to avoid this case. Note,
--- zfcpdump-kernel-4.4.orig/Documentation/x86/pat.txt
+++ zfcpdump-kernel-4.4/Documentation/x86/pat.txt
@@ -196,3 +196,35 @@ Another, more verbose way of getting PAT
 "debugpat" boot parameter. With this parameter, various debug messages are
 printed to dmesg log.
 
+PAT Initialization
+------------------
+
+The following table describes how PAT is initialized under various
+configurations. The PAT MSR must be updated by Linux in order to support WC
+and WT attributes. Otherwise, the PAT MSR has the value programmed in it
+by the firmware. Note, Xen enables WC attribute in the PAT MSR for guests.
+
+ MTRR PAT   Call Sequence               PAT State  PAT MSR
+ =========================================================
+ E    E     MTRR -> PAT init            Enabled    OS
+ E    D     MTRR -> PAT init            Disabled    -
+ D    E     MTRR -> PAT disable         Disabled   BIOS
+ D    D     MTRR -> PAT disable         Disabled    -
+ -    np/E  PAT  -> PAT disable         Disabled   BIOS
+ -    np/D  PAT  -> PAT disable         Disabled    -
+ E    !P/E  MTRR -> PAT init            Disabled   BIOS
+ D    !P/E  MTRR -> PAT disable         Disabled   BIOS
+ !M   !P/E  MTRR stub -> PAT disable    Disabled   BIOS
+
+ Legend
+ ------------------------------------------------
+ E         Feature enabled in CPU
+ D	   Feature disabled/unsupported in CPU
+ np	   "nopat" boot option specified
+ !P	   CONFIG_X86_PAT option unset
+ !M	   CONFIG_MTRR option unset
+ Enabled   PAT state set to enabled
+ Disabled  PAT state set to disabled
+ OS        PAT initializes PAT MSR with OS setting
+ BIOS      PAT keeps PAT MSR with BIOS setting
+
--- zfcpdump-kernel-4.4.orig/Documentation/x86/zero-page.txt
+++ zfcpdump-kernel-4.4/Documentation/x86/zero-page.txt
@@ -31,6 +31,8 @@ Offset	Proto	Name		Meaning
 1E9/001	ALL	eddbuf_entries	Number of entries in eddbuf (below)
 1EA/001	ALL	edd_mbr_sig_buf_entries	Number of entries in edd_mbr_sig_buffer
 				(below)
+1EB/001	ALL     kbd_status      Numlock is enabled
+1EC/001	ALL     secure_boot	Secure boot is enabled in the firmware
 1EF/001	ALL	sentinel	Used to detect broken bootloaders
 290/040	ALL	edd_mbr_sig_buffer EDD MBR signatures
 2D0/A00	ALL	e820_map	E820 memory map table
--- zfcpdump-kernel-4.4.orig/MAINTAINERS
+++ zfcpdump-kernel-4.4/MAINTAINERS
@@ -230,13 +230,13 @@ F:	kernel/sys_ni.c
 
 ABIT UGURU 1,2 HARDWARE MONITOR DRIVER
 M:	Hans de Goede <hdegoede@redhat.com>
-L:	lm-sensors@lm-sensors.org
+L:	linux-hwmon@vger.kernel.org
 S:	Maintained
 F:	drivers/hwmon/abituguru.c
 
 ABIT UGURU 3 HARDWARE MONITOR DRIVER
 M:	Alistair John Strachan <alistair@devzero.co.uk>
-L:	lm-sensors@lm-sensors.org
+L:	linux-hwmon@vger.kernel.org
 S:	Maintained
 F:	drivers/hwmon/abituguru3.c
 
@@ -373,14 +373,14 @@ S:	Maintained
 
 ADM1025 HARDWARE MONITOR DRIVER
 M:	Jean Delvare <jdelvare@suse.com>
-L:	lm-sensors@lm-sensors.org
+L:	linux-hwmon@vger.kernel.org
 S:	Maintained
 F:	Documentation/hwmon/adm1025
 F:	drivers/hwmon/adm1025.c
 
 ADM1029 HARDWARE MONITOR DRIVER
 M:	Corentin Labbe <clabbe.montjoie@gmail.com>
-L:	lm-sensors@lm-sensors.org
+L:	linux-hwmon@vger.kernel.org
 S:	Maintained
 F:	drivers/hwmon/adm1029.c
 
@@ -425,7 +425,7 @@ F:	drivers/video/backlight/adp8860_bl.c
 
 ADS1015 HARDWARE MONITOR DRIVER
 M:	Dirk Eibach <eibach@gdsys.de>
-L:	lm-sensors@lm-sensors.org
+L:	linux-hwmon@vger.kernel.org
 S:	Maintained
 F:	Documentation/hwmon/ads1015
 F:	drivers/hwmon/ads1015.c
@@ -438,7 +438,7 @@ F:	drivers/macintosh/therm_adt746x.c
 
 ADT7475 HARDWARE MONITOR DRIVER
 M:	Jean Delvare <jdelvare@suse.com>
-L:	lm-sensors@lm-sensors.org
+L:	linux-hwmon@vger.kernel.org
 S:	Maintained
 F:	Documentation/hwmon/adt7475
 F:	drivers/hwmon/adt7475.c
@@ -606,6 +606,15 @@ F:	drivers/tty/serial/altera_jtaguart.c
 F:	include/linux/altera_uart.h
 F:	include/linux/altera_jtaguart.h
 
+AMAZON ETHERNET DRIVERS
+M:	Netanel Belgazal <netanel@annapurnalabs.com>
+R:	Saeed Bishara <saeed@annapurnalabs.com>
+R:	Zorik Machulsky <zorik@annapurnalabs.com>
+L:	netdev@vger.kernel.org
+S:	Supported
+F:	Documentation/networking/ena.txt
+F:	drivers/net/ethernet/amazon/
+
 AMD CRYPTOGRAPHIC COPROCESSOR (CCP) DRIVER
 M:	Tom Lendacky <thomas.lendacky@amd.com>
 L:	linux-crypto@vger.kernel.org
@@ -615,7 +624,7 @@ F:	include/linux/ccp.h
 
 AMD FAM15H PROCESSOR POWER MONITORING DRIVER
 M:	Andreas Herrmann <herrmann.der.user@googlemail.com>
-L:	lm-sensors@lm-sensors.org
+L:	linux-hwmon@vger.kernel.org
 S:	Maintained
 F:	Documentation/hwmon/fam15h_power
 F:	drivers/hwmon/fam15h_power.c
@@ -779,7 +788,7 @@ F:	drivers/input/mouse/bcm5974.c
 
 APPLE SMC DRIVER
 M:	Henrik Rydberg <rydberg@bitmath.org>
-L:	lm-sensors@lm-sensors.org
+L:	linux-hwmon@vger.kernel.org
 S:	Odd fixes
 F:	drivers/hwmon/applesmc.c
 
@@ -1777,7 +1786,7 @@ F:	include/media/as3645a.h
 
 ASC7621 HARDWARE MONITOR DRIVER
 M:	George Joseph <george.joseph@fairview5.com>
-L:	lm-sensors@lm-sensors.org
+L:	linux-hwmon@vger.kernel.org
 S:	Maintained
 F:	Documentation/hwmon/asc7621
 F:	drivers/hwmon/asc7621.c
@@ -1864,7 +1873,7 @@ F:	drivers/net/wireless/ath/carl9170/
 
 ATK0110 HWMON DRIVER
 M:	Luca Tettamanti <kronos.it@gmail.com>
-L:	lm-sensors@lm-sensors.org
+L:	linux-hwmon@vger.kernel.org
 S:	Maintained
 F:	drivers/hwmon/asus_atk0110.c
 
@@ -2029,6 +2038,19 @@ F:	include/linux/audit.h
 F:	include/uapi/linux/audit.h
 F:	kernel/audit*
 
+AUFS (advanced multi layered unification filesystem) FILESYSTEM
+M:	"J. R. Okajima" <hooanon05g@gmail.com>
+L:	linux-unionfs@vger.kernel.org
+L:	aufs-users@lists.sourceforge.net (members only)
+W:	http://aufs.sourceforge.net
+T:	git://github.com/sfjro/aufs4-linux.git
+S:	Supported
+F:	Documentation/filesystems/aufs/
+F:	Documentation/ABI/testing/debugfs-aufs
+F:	Documentation/ABI/testing/sysfs-aufs
+F:	fs/aufs/
+F:	include/uapi/linux/aufs_type.h
+
 AUXILIARY DISPLAY DRIVERS
 M:	Miguel Ojeda Sandonis <miguel.ojeda.sandonis@gmail.com>
 W:	http://miguelojeda.es/auxdisplay.htm
@@ -2984,7 +3006,7 @@ F:	mm/swap_cgroup.c
 
 CORETEMP HARDWARE MONITORING DRIVER
 M:	Fenghua Yu <fenghua.yu@intel.com>
-L:	lm-sensors@lm-sensors.org
+L:	linux-hwmon@vger.kernel.org
 S:	Maintained
 F:	Documentation/hwmon/coretemp
 F:	drivers/hwmon/coretemp.c
@@ -3549,7 +3571,7 @@ T:	git git://git.infradead.org/users/vko
 
 DME1737 HARDWARE MONITOR DRIVER
 M:	Juerg Haefliger <juergh@gmail.com>
-L:	lm-sensors@lm-sensors.org
+L:	linux-hwmon@vger.kernel.org
 S:	Maintained
 F:	Documentation/hwmon/dme1737
 F:	drivers/hwmon/dme1737.c
@@ -4074,6 +4096,12 @@ W:	bluesmoke.sourceforge.net
 S:	Maintained
 F:	drivers/edac/sb_edac.c
 
+EDAC-SKYLAKE
+M:	Tony Luck <tony.luck@intel.com>
+L:	linux-edac@vger.kernel.org
+S:	Maintained
+F:	drivers/edac/skx_edac.c
+
 EDAC-XGENE
 APPLIED MICRO (APM) X-GENE SOC EDAC
 M:     Loc Ho <lho@apm.com>
@@ -4097,8 +4125,8 @@ F:	Documentation/efi-stub.txt
 F:	arch/ia64/kernel/efi.c
 F:	arch/x86/boot/compressed/eboot.[ch]
 F:	arch/x86/include/asm/efi.h
-F:	arch/x86/platform/efi/*
-F:	drivers/firmware/efi/*
+F:	arch/x86/platform/efi/
+F:	drivers/firmware/efi/
 F:	include/linux/efi*.h
 
 EFI VARIABLE FILESYSTEM
@@ -4262,7 +4290,7 @@ F:	include/video/exynos_mipi*
 
 F71805F HARDWARE MONITORING DRIVER
 M:	Jean Delvare <jdelvare@suse.com>
-L:	lm-sensors@lm-sensors.org
+L:	linux-hwmon@vger.kernel.org
 S:	Maintained
 F:	Documentation/hwmon/f71805f
 F:	drivers/hwmon/f71805f.c
@@ -4341,7 +4369,7 @@ F:	fs/*
 
 FINTEK F75375S HARDWARE MONITOR AND FAN CONTROLLER DRIVER
 M:	Riku Voipio <riku.voipio@iki.fi>
-L:	lm-sensors@lm-sensors.org
+L:	linux-hwmon@vger.kernel.org
 S:	Maintained
 F:	drivers/hwmon/f75375s.c
 F:	include/linux/f75375s.h
@@ -4883,8 +4911,8 @@ F:	drivers/media/usb/hackrf/
 HARDWARE MONITORING
 M:	Jean Delvare <jdelvare@suse.com>
 M:	Guenter Roeck <linux@roeck-us.net>
-L:	lm-sensors@lm-sensors.org
-W:	http://www.lm-sensors.org/
+L:	linux-hwmon@vger.kernel.org
+W:	http://hwmon.wiki.kernel.org/
 T:	quilt http://jdelvare.nerim.net/devel/linux/jdelvare-hwmon/
 T:	git git://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging.git
 S:	Maintained
@@ -5120,6 +5148,7 @@ F:	arch/x86/kernel/cpu/mshyperv.c
 F:	drivers/hid/hid-hyperv.c
 F:	drivers/hv/
 F:	drivers/input/serio/hyperv-keyboard.c
+F:	drivers/pci/host/pci-hyperv.c
 F:	drivers/net/hyperv/
 F:	drivers/scsi/storvsc_drv.c
 F:	drivers/video/fbdev/hyperv_fb.c
@@ -5283,12 +5312,27 @@ L:	netdev@vger.kernel.org
 S:	Supported
 F:	drivers/net/ethernet/ibm/ibmveth.*
 
+IBM Power SRIOV Virtual NIC Device Driver
+M:	Thomas Falcon <tlfalcon@linux.vnet.ibm.com>
+M:	John Allen <jallen@linux.vnet.ibm.com>
+L:	netdev@vger.kernel.org
+S:	Supported
+F:	drivers/net/ethernet/ibm/ibmvnic.*
+
 IBM Power Virtual SCSI Device Drivers
 M:	Tyrel Datwyler <tyreld@linux.vnet.ibm.com>
 L:	linux-scsi@vger.kernel.org
 S:	Supported
 F:	drivers/scsi/ibmvscsi/ibmvscsi*
-F:	drivers/scsi/ibmvscsi/viosrp.h
+F:	include/scsi/viosrp.h
+
+IBM Power Virtual SCSI Device Target Driver
+M:	Bryant G. Ly <bryantly@linux.vnet.ibm.com>
+M:	Michael Cyr <mikecyr@linux.vnet.ibm.com>
+L:	linux-scsi@vger.kernel.org
+L:	target-devel@vger.kernel.org
+S:	Supported
+F:	drivers/scsi/ibmvscsi_tgt/
 
 IBM Power Virtual FC Device Drivers
 M:	Tyrel Datwyler <tyreld@linux.vnet.ibm.com>
@@ -5393,7 +5437,7 @@ F:	drivers/usb/atm/ueagle-atm.c
 
 INA209 HARDWARE MONITOR DRIVER
 M:	Guenter Roeck <linux@roeck-us.net>
-L:	lm-sensors@lm-sensors.org
+L:	linux-hwmon@vger.kernel.org
 S:	Maintained
 F:	Documentation/hwmon/ina209
 F:	Documentation/devicetree/bindings/i2c/ina209.txt
@@ -5401,7 +5445,7 @@ F:	drivers/hwmon/ina209.c
 
 INA2XX HARDWARE MONITOR DRIVER
 M:	Guenter Roeck <linux@roeck-us.net>
-L:	lm-sensors@lm-sensors.org
+L:	linux-hwmon@vger.kernel.org
 S:	Maintained
 F:	Documentation/hwmon/ina2xx
 F:	drivers/hwmon/ina2xx.c
@@ -5502,6 +5546,18 @@ T:	git git://git.code.sf.net/p/intel-sas
 S:	Supported
 F:	drivers/scsi/isci/
 
+INTEL HID EVENT DRIVER
+M:	Alex Hung <alex.hung@canonical.com>
+L:	platform-driver-x86@vger.kernel.org
+S:	Maintained
+F:	drivers/platform/x86/intel-hid.c
+
+INTEL VIRTUAL BUTTON DRIVER
+M:	AceLan Kao <acelan.kao@canonical.com>
+L:	platform-driver-x86@vger.kernel.org
+S:	Maintained
+F:	drivers/platform/x86/intel-vbtn.c
+
 INTEL IDLE DRIVER
 M:	Len Brown <lenb@kernel.org>
 L:	linux-pm@vger.kernel.org
@@ -5684,12 +5740,23 @@ F:	drivers/dma/mic_x100_dma.c
 F:	drivers/dma/mic_x100_dma.h
 F	Documentation/mic/
 
-INTEL PMC IPC DRIVER
+INTEL PMC/P-Unit IPC DRIVER
 M:	Zha Qipeng<qipeng.zha@intel.com>
 L:	platform-driver-x86@vger.kernel.org
 S:	Maintained
 F:	drivers/platform/x86/intel_pmc_ipc.c
+F:	drivers/platform/x86/intel_punit_ipc.c
 F:	arch/x86/include/asm/intel_pmc_ipc.h
+F:	arch/x86/include/asm/intel_punit_ipc.h
+
+INTEL TELEMETRY DRIVER
+M:	Souvik Kumar Chakravarty <souvik.k.chakravarty@intel.com>
+L:	platform-driver-x86@vger.kernel.org
+S:	Maintained
+F:	drivers/platform/x86/intel_telemetry_core.c
+F:	arch/x86/include/asm/intel_telemetry.h
+F:	drivers/platform/x86/intel_telemetry_pltdrv.c
+F:	drivers/platform/x86/intel_telemetry_debugfs.c
 
 IOC3 ETHERNET DRIVER
 M:	Ralf Baechle <ralf@linux-mips.org>
@@ -5884,7 +5951,7 @@ F:	drivers/isdn/hardware/eicon/
 
 IT87 HARDWARE MONITORING DRIVER
 M:	Jean Delvare <jdelvare@suse.com>
-L:	lm-sensors@lm-sensors.org
+L:	linux-hwmon@vger.kernel.org
 S:	Maintained
 F:	Documentation/hwmon/it87
 F:	drivers/hwmon/it87.c
@@ -5920,7 +5987,7 @@ F:	drivers/media/dvb-frontends/ix2505v*
 
 JC42.4 TEMPERATURE SENSOR DRIVER
 M:	Guenter Roeck <linux@roeck-us.net>
-L:	lm-sensors@lm-sensors.org
+L:	linux-hwmon@vger.kernel.org
 S:	Maintained
 F:	drivers/hwmon/jc42.c
 F:	Documentation/hwmon/jc42
@@ -5970,14 +6037,14 @@ F:	drivers/tty/serial/jsm/
 
 K10TEMP HARDWARE MONITORING DRIVER
 M:	Clemens Ladisch <clemens@ladisch.de>
-L:	lm-sensors@lm-sensors.org
+L:	linux-hwmon@vger.kernel.org
 S:	Maintained
 F:	Documentation/hwmon/k10temp
 F:	drivers/hwmon/k10temp.c
 
 K8TEMP HARDWARE MONITORING DRIVER
 M:	Rudolf Marek <r.marek@assembler.cz>
-L:	lm-sensors@lm-sensors.org
+L:	linux-hwmon@vger.kernel.org
 S:	Maintained
 F:	Documentation/hwmon/k8temp
 F:	drivers/hwmon/k8temp.c
@@ -6485,27 +6552,27 @@ F:	net/llc/
 
 LM73 HARDWARE MONITOR DRIVER
 M:	Guillaume Ligneul <guillaume.ligneul@gmail.com>
-L:	lm-sensors@lm-sensors.org
+L:	linux-hwmon@vger.kernel.org
 S:	Maintained
 F:	drivers/hwmon/lm73.c
 
 LM78 HARDWARE MONITOR DRIVER
 M:	Jean Delvare <jdelvare@suse.com>
-L:	lm-sensors@lm-sensors.org
+L:	linux-hwmon@vger.kernel.org
 S:	Maintained
 F:	Documentation/hwmon/lm78
 F:	drivers/hwmon/lm78.c
 
 LM83 HARDWARE MONITOR DRIVER
 M:	Jean Delvare <jdelvare@suse.com>
-L:	lm-sensors@lm-sensors.org
+L:	linux-hwmon@vger.kernel.org
 S:	Maintained
 F:	Documentation/hwmon/lm83
 F:	drivers/hwmon/lm83.c
 
 LM90 HARDWARE MONITOR DRIVER
 M:	Jean Delvare <jdelvare@suse.com>
-L:	lm-sensors@lm-sensors.org
+L:	linux-hwmon@vger.kernel.org
 S:	Maintained
 F:	Documentation/hwmon/lm90
 F:	Documentation/devicetree/bindings/hwmon/lm90.txt
@@ -6513,7 +6580,7 @@ F:	drivers/hwmon/lm90.c
 
 LM95234 HARDWARE MONITOR DRIVER
 M:	Guenter Roeck <linux@roeck-us.net>
-L:	lm-sensors@lm-sensors.org
+L:	linux-hwmon@vger.kernel.org
 S:	Maintained
 F:	Documentation/hwmon/lm95234
 F:	drivers/hwmon/lm95234.c
@@ -6580,7 +6647,7 @@ F:	drivers/scsi/sym53c8xx_2/
 
 LTC4261 HARDWARE MONITOR DRIVER
 M:	Guenter Roeck <linux@roeck-us.net>
-L:	lm-sensors@lm-sensors.org
+L:	linux-hwmon@vger.kernel.org
 S:	Maintained
 F:	Documentation/hwmon/ltc4261
 F:	drivers/hwmon/ltc4261.c
@@ -6749,28 +6816,28 @@ F:	include/uapi/linux/matroxfb.h
 
 MAX16065 HARDWARE MONITOR DRIVER
 M:	Guenter Roeck <linux@roeck-us.net>
-L:	lm-sensors@lm-sensors.org
+L:	linux-hwmon@vger.kernel.org
 S:	Maintained
 F:	Documentation/hwmon/max16065
 F:	drivers/hwmon/max16065.c
 
 MAX20751 HARDWARE MONITOR DRIVER
 M:	Guenter Roeck <linux@roeck-us.net>
-L:	lm-sensors@lm-sensors.org
+L:	linux-hwmon@vger.kernel.org
 S:	Maintained
 F:	Documentation/hwmon/max20751
 F:	drivers/hwmon/max20751.c
 
 MAX6650 HARDWARE MONITOR AND FAN CONTROLLER DRIVER
 M:	"Hans J. Koch" <hjk@hansjkoch.de>
-L:	lm-sensors@lm-sensors.org
+L:	linux-hwmon@vger.kernel.org
 S:	Maintained
 F:	Documentation/hwmon/max6650
 F:	drivers/hwmon/max6650.c
 
 MAX6697 HARDWARE MONITOR DRIVER
 M:	Guenter Roeck <linux@roeck-us.net>
-L:	lm-sensors@lm-sensors.org
+L:	linux-hwmon@vger.kernel.org
 S:	Maintained
 F:	Documentation/hwmon/max6697
 F:	Documentation/devicetree/bindings/i2c/max6697.txt
@@ -7303,7 +7370,7 @@ F:	drivers/scsi/NCR_D700.*
 
 NCT6775 HARDWARE MONITOR DRIVER
 M:	Guenter Roeck <linux@roeck-us.net>
-L:	lm-sensors@lm-sensors.org
+L:	linux-hwmon@vger.kernel.org
 S:	Maintained
 F:	Documentation/hwmon/nct6775
 F:	drivers/hwmon/nct6775.c
@@ -7586,6 +7653,12 @@ W:	https://github.com/jonmason/ntb/wiki
 T:	git git://github.com/jonmason/ntb.git
 F:	drivers/ntb/hw/intel/
 
+NTB AMD DRIVER
+M:	Xiangliang Yu <Xiangliang.Yu@amd.com>
+L:	linux-ntb@googlegroups.com
+S:	Supported
+F:	drivers/ntb/hw/amd/
+
 NTFS FILESYSTEM
 M:	Anton Altaparmakov <anton@tuxera.com>
 L:	linux-ntfs-dev@lists.sourceforge.net
@@ -8064,7 +8137,7 @@ F:	drivers/video/logo/logo_parisc*
 
 PC87360 HARDWARE MONITORING DRIVER
 M:	Jim Cromie <jim.cromie@gmail.com>
-L:	lm-sensors@lm-sensors.org
+L:	linux-hwmon@vger.kernel.org
 S:	Maintained
 F:	Documentation/hwmon/pc87360
 F:	drivers/hwmon/pc87360.c
@@ -8076,7 +8149,7 @@ F:	drivers/char/pc8736x_gpio.c
 
 PC87427 HARDWARE MONITORING DRIVER
 M:	Jean Delvare <jdelvare@suse.com>
-L:	lm-sensors@lm-sensors.org
+L:	linux-hwmon@vger.kernel.org
 S:	Maintained
 F:	Documentation/hwmon/pc87427
 F:	drivers/hwmon/pc87427.c
@@ -8217,6 +8290,7 @@ L:	linux-pci@vger.kernel.org
 L:	linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 S:	Maintained
 F:	Documentation/devicetree/bindings/pci/host-generic-pci.txt
+F:	drivers/pci/host/pci-host-common.c
 F:	drivers/pci/host/pci-host-generic.c
 
 PCIE DRIVER FOR ST SPEAR13XX
@@ -8248,6 +8322,14 @@ S:	Maintained
 F:	Documentation/devicetree/bindings/pci/hisilicon-pcie.txt
 F:	drivers/pci/host/pcie-hisi.c
 
+PCIE DRIVER FOR CAVIUM THUNDERX
+M:	David Daney <david.daney@cavium.com>
+L:	linux-pci@vger.kernel.org
+L:	linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
+S:	Supported
+F:	Documentation/devicetree/bindings/pci/pci-thunder-*
+F:	drivers/pci/host/pci-thunder-*
+
 PCMCIA SUBSYSTEM
 P:	Linux PCMCIA Team
 L:	linux-pcmcia@lists.infradead.org
@@ -8415,8 +8497,8 @@ F:	drivers/rtc/rtc-puv3.c
 
 PMBUS HARDWARE MONITORING DRIVERS
 M:	Guenter Roeck <linux@roeck-us.net>
-L:	lm-sensors@lm-sensors.org
-W:	http://www.lm-sensors.org/
+L:	linux-hwmon@vger.kernel.org
+W:	http://hwmon.wiki.kernel.org/
 W:	http://www.roeck-us.net/linux/drivers/
 T:	git git://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging.git
 S:	Maintained
@@ -8610,7 +8692,7 @@ F:	drivers/media/usb/pwc/*
 
 PWM FAN DRIVER
 M:	Kamil Debski <k.debski@samsung.com>
-L:	lm-sensors@lm-sensors.org
+L:	linux-hwmon@vger.kernel.org
 S:	Supported
 F:	Documentation/devicetree/bindings/hwmon/pwm-fan.txt
 F:	Documentation/hwmon/pwm-fan
@@ -9882,28 +9964,28 @@ F:	Documentation/devicetree/bindings/med
 
 SMM665 HARDWARE MONITOR DRIVER
 M:	Guenter Roeck <linux@roeck-us.net>
-L:	lm-sensors@lm-sensors.org
+L:	linux-hwmon@vger.kernel.org
 S:	Maintained
 F:	Documentation/hwmon/smm665
 F:	drivers/hwmon/smm665.c
 
 SMSC EMC2103 HARDWARE MONITOR DRIVER
 M:	Steve Glendinning <steve.glendinning@shawell.net>
-L:	lm-sensors@lm-sensors.org
+L:	linux-hwmon@vger.kernel.org
 S:	Maintained
 F:	Documentation/hwmon/emc2103
 F:	drivers/hwmon/emc2103.c
 
 SMSC SCH5627 HARDWARE MONITOR DRIVER
 M:	Hans de Goede <hdegoede@redhat.com>
-L:	lm-sensors@lm-sensors.org
+L:	linux-hwmon@vger.kernel.org
 S:	Supported
 F:	Documentation/hwmon/sch5627
 F:	drivers/hwmon/sch5627.c
 
 SMSC47B397 HARDWARE MONITOR DRIVER
 M:	Jean Delvare <jdelvare@suse.com>
-L:	lm-sensors@lm-sensors.org
+L:	linux-hwmon@vger.kernel.org
 S:	Maintained
 F:	Documentation/hwmon/smsc47b397
 F:	drivers/hwmon/smsc47b397.c
@@ -10289,9 +10371,11 @@ S:	Maintained
 F:	drivers/net/ethernet/dlink/sundance.c
 
 SUPERH
+M:	Yoshinori Sato <ysato@users.sourceforge.jp>
+M:	Rich Felker <dalias@libc.org>
 L:	linux-sh@vger.kernel.org
 Q:	http://patchwork.kernel.org/project/linux-sh/list/
-S:	Orphan
+S:	Maintained
 F:	Documentation/sh/
 F:	arch/sh/
 F:	drivers/sh/
@@ -10828,7 +10912,7 @@ F:	include/linux/mmc/sh_mobile_sdhi.h
 
 TMP401 HARDWARE MONITOR DRIVER
 M:	Guenter Roeck <linux@roeck-us.net>
-L:	lm-sensors@lm-sensors.org
+L:	linux-hwmon@vger.kernel.org
 S:	Maintained
 F:	Documentation/hwmon/tmp401
 F:	drivers/hwmon/tmp401.c
@@ -11562,14 +11646,14 @@ F:	Documentation/networking/vrf.txt
 
 VT1211 HARDWARE MONITOR DRIVER
 M:	Juerg Haefliger <juergh@gmail.com>
-L:	lm-sensors@lm-sensors.org
+L:	linux-hwmon@vger.kernel.org
 S:	Maintained
 F:	Documentation/hwmon/vt1211
 F:	drivers/hwmon/vt1211.c
 
 VT8231 HARDWARE MONITOR DRIVER
 M:	Roger Lucas <vt8231@hiddenengine.co.uk>
-L:	lm-sensors@lm-sensors.org
+L:	linux-hwmon@vger.kernel.org
 S:	Maintained
 F:	drivers/hwmon/vt8231.c
 
@@ -11588,21 +11672,21 @@ F:	drivers/w1/
 
 W83791D HARDWARE MONITORING DRIVER
 M:	Marc Hulsman <m.hulsman@tudelft.nl>
-L:	lm-sensors@lm-sensors.org
+L:	linux-hwmon@vger.kernel.org
 S:	Maintained
 F:	Documentation/hwmon/w83791d
 F:	drivers/hwmon/w83791d.c
 
 W83793 HARDWARE MONITORING DRIVER
 M:	Rudolf Marek <r.marek@assembler.cz>
-L:	lm-sensors@lm-sensors.org
+L:	linux-hwmon@vger.kernel.org
 S:	Maintained
 F:	Documentation/hwmon/w83793
 F:	drivers/hwmon/w83793.c
 
 W83795 HARDWARE MONITORING DRIVER
 M:	Jean Delvare <jdelvare@suse.com>
-L:	lm-sensors@lm-sensors.org
+L:	linux-hwmon@vger.kernel.org
 S:	Maintained
 F:	drivers/hwmon/w83795.c
 
--- zfcpdump-kernel-4.4.orig/Makefile
+++ zfcpdump-kernel-4.4/Makefile
@@ -1,6 +1,6 @@
 VERSION = 4
 PATCHLEVEL = 4
-SUBLEVEL = 0
+SUBLEVEL = 24
 EXTRAVERSION =
 NAME = Blurry Fish Butt
 
@@ -128,6 +128,10 @@ _all:
 # Cancel implicit rules on top Makefile
 $(CURDIR)/Makefile Makefile: ;
 
+ifneq ($(words $(subst :, ,$(CURDIR))), 1)
+  $(error main directory cannot contain spaces nor colons)
+endif
+
 ifneq ($(KBUILD_OUTPUT),)
 # Invoke a second make in the output directory, passing relevant variables
 # check that the output directory actually exists
@@ -364,8 +368,14 @@ AFLAGS_MODULE   =
 LDFLAGS_MODULE  =
 CFLAGS_KERNEL	=
 AFLAGS_KERNEL	=
-CFLAGS_GCOV	= -fprofile-arcs -ftest-coverage
+CFLAGS_GCOV	= -fprofile-arcs -ftest-coverage -fno-tree-loop-im
 
+# Prefer linux-backports-modules
+ifneq ($(KBUILD_SRC),)
+ifneq ($(shell if test -e $(KBUILD_OUTPUT)/ubuntu-build; then echo yes; fi),yes)
+UBUNTUINCLUDE := -I/usr/src/linux-headers-lbm-$(KERNELRELEASE)
+endif
+endif
 
 # Use USERINCLUDE when you must reference the UAPI directories only.
 USERINCLUDE    := \
@@ -378,6 +388,7 @@ USERINCLUDE    := \
 # Use LINUXINCLUDE when you must reference the include/ directory.
 # Needed to be compatible with the O= option
 LINUXINCLUDE    := \
+		$(UBUNTUINCLUDE) \
 		-I$(srctree)/arch/$(hdr-arch)/include \
 		-Iarch/$(hdr-arch)/include/generated/uapi \
 		-Iarch/$(hdr-arch)/include/generated \
@@ -385,6 +396,9 @@ LINUXINCLUDE    := \
 		-Iinclude \
 		$(USERINCLUDE)
 
+# UBUNTU: Include our third party driver stuff too
+LINUXINCLUDE   += -Iubuntu/include $(if $(KBUILD_SRC),-I$(srctree)/ubuntu/include)
+
 KBUILD_CPPFLAGS := -D__KERNEL__
 
 KBUILD_CFLAGS   := -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \
@@ -495,6 +509,12 @@ ifeq ($(KBUILD_EXTMOD),)
                 endif
         endif
 endif
+# install and module_install need also be processed one by one
+ifneq ($(filter install,$(MAKECMDGOALS)),)
+        ifneq ($(filter modules_install,$(MAKECMDGOALS)),)
+	        mixed-targets := 1
+        endif
+endif
 
 ifeq ($(mixed-targets),1)
 # ===========================================================================
@@ -546,7 +566,7 @@ scripts: scripts_basic include/config/au
 
 # Objects we will link into vmlinux / subdirs we need to visit
 init-y		:= init/
-drivers-y	:= drivers/ sound/ firmware/
+drivers-y	:= drivers/ sound/ firmware/ ubuntu/
 net-y		:= net/
 libs-y		:= lib/
 core-y		:= usr/
@@ -598,6 +618,12 @@ endif # $(dot-config)
 # Defaults to vmlinux, but the arch makefile usually adds further targets
 all: vmlinux
 
+# force no-pie for distro compilers that enable pie by default
+KBUILD_CFLAGS += $(call cc-option, -fno-pie)
+KBUILD_CFLAGS += $(call cc-option, -no-pie)
+KBUILD_AFLAGS += $(call cc-option, -fno-pie)
+KBUILD_CPPFLAGS += $(call cc-option, -fno-pie)
+
 # The arch Makefile can set ARCH_{CPP,A,C}FLAGS to override the default
 # values of the respective KBUILD_* variables
 ARCH_CPPFLAGS :=
@@ -606,11 +632,16 @@ ARCH_CFLAGS :=
 include arch/$(SRCARCH)/Makefile
 
 KBUILD_CFLAGS	+= $(call cc-option,-fno-delete-null-pointer-checks,)
+KBUILD_CFLAGS	+= $(call cc-disable-warning,maybe-uninitialized,)
 
 ifdef CONFIG_CC_OPTIMIZE_FOR_SIZE
-KBUILD_CFLAGS	+= -Os $(call cc-disable-warning,maybe-uninitialized,)
+KBUILD_CFLAGS	+= -Os
 else
+ifdef CONFIG_PROFILE_ALL_BRANCHES
 KBUILD_CFLAGS	+= -O2
+else
+KBUILD_CFLAGS   += -O2
+endif
 endif
 
 # Tell gcc to never replace conditional load with a non-conditional one
@@ -682,9 +713,10 @@ KBUILD_CFLAGS += $(call cc-option, -mno-
 KBUILD_CFLAGS += $(call cc-option, -fcatch-undefined-behavior)
 else
 
-# This warning generated too much noise in a regular build.
-# Use make W=1 to enable this warning (see scripts/Makefile.build)
+# These warnings generated too much noise in a regular build.
+# Use make W=1 to enable them (see scripts/Makefile.build)
 KBUILD_CFLAGS += $(call cc-disable-warning, unused-but-set-variable)
+KBUILD_CFLAGS += $(call cc-disable-warning, unused-const-variable)
 endif
 
 ifdef CONFIG_FRAME_POINTER
@@ -1060,6 +1092,7 @@ headers_install: __headers
 	  $(error Headers not exportable for the $(SRCARCH) architecture))
 	$(Q)$(MAKE) $(hdr-inst)=include/uapi
 	$(Q)$(MAKE) $(hdr-inst)=arch/$(hdr-arch)/include/uapi/asm $(hdr-dst)
+	$(Q)$(MAKE) $(hdr-inst)=ubuntu/include dst=include oldheaders=
 
 PHONY += headers_check_all
 headers_check_all: headers_install_all
@@ -1069,6 +1102,7 @@ PHONY += headers_check
 headers_check: headers_install
 	$(Q)$(MAKE) $(hdr-inst)=include/uapi HDRCHECK=1
 	$(Q)$(MAKE) $(hdr-inst)=arch/$(hdr-arch)/include/uapi/asm $(hdr-dst) HDRCHECK=1
+	$(Q)$(MAKE) $(hdr-inst)=ubuntu/include dst=include oldheaders= HDRCHECK=1
 
 # ---------------------------------------------------------------------------
 # Kernel selftest
@@ -1259,7 +1293,7 @@ help:
 	@echo  '  firmware_install- Install all firmware to INSTALL_FW_PATH'
 	@echo  '                    (default: $$(INSTALL_MOD_PATH)/lib/firmware)'
 	@echo  '  dir/            - Build all files in dir and below'
-	@echo  '  dir/file.[oisS] - Build specified target only'
+	@echo  '  dir/file.[ois]  - Build specified target only'
 	@echo  '  dir/file.lst    - Build specified mixed source/assembly target only'
 	@echo  '                    (requires a recent binutils and recent build (System.map))'
 	@echo  '  dir/file.ko     - Build module including final link'
@@ -1499,11 +1533,11 @@ image_name:
 # Clear a bunch of variables before executing the submake
 tools/: FORCE
 	$(Q)mkdir -p $(objtree)/tools
-	$(Q)$(MAKE) LDFLAGS= MAKEFLAGS="$(filter --j% -j,$(MAKEFLAGS))" O=$(O) subdir=tools -C $(src)/tools/
+	$(Q)$(MAKE) LDFLAGS= MAKEFLAGS="$(filter --j% -j,$(MAKEFLAGS))" O=$(shell cd $(objtree) && /bin/pwd) subdir=tools -C $(src)/tools/
 
 tools/%: FORCE
 	$(Q)mkdir -p $(objtree)/tools
-	$(Q)$(MAKE) LDFLAGS= MAKEFLAGS="$(filter --j% -j,$(MAKEFLAGS))" O=$(O) subdir=tools -C $(src)/tools/ $*
+	$(Q)$(MAKE) LDFLAGS= MAKEFLAGS="$(filter --j% -j,$(MAKEFLAGS))" O=$(shell cd $(objtree) && /bin/pwd) subdir=tools -C $(src)/tools/ $*
 
 # Single targets
 # ---------------------------------------------------------------------------
--- zfcpdump-kernel-4.4.orig/arch/alpha/include/asm/uaccess.h
+++ zfcpdump-kernel-4.4/arch/alpha/include/asm/uaccess.h
@@ -371,14 +371,6 @@ __copy_tofrom_user_nocheck(void *to, con
 	return __cu_len;
 }
 
-extern inline long
-__copy_tofrom_user(void *to, const void *from, long len, const void __user *validate)
-{
-	if (__access_ok((unsigned long)validate, len, get_fs()))
-		len = __copy_tofrom_user_nocheck(to, from, len);
-	return len;
-}
-
 #define __copy_to_user(to, from, n)					\
 ({									\
 	__chk_user_ptr(to);						\
@@ -393,17 +385,22 @@ __copy_tofrom_user(void *to, const void
 #define __copy_to_user_inatomic __copy_to_user
 #define __copy_from_user_inatomic __copy_from_user
 
-
 extern inline long
 copy_to_user(void __user *to, const void *from, long n)
 {
-	return __copy_tofrom_user((__force void *)to, from, n, to);
+	if (likely(__access_ok((unsigned long)to, n, get_fs())))
+		n = __copy_tofrom_user_nocheck((__force void *)to, from, n);
+	return n;
 }
 
 extern inline long
 copy_from_user(void *to, const void __user *from, long n)
 {
-	return __copy_tofrom_user(to, (__force void *)from, n, from);
+	if (likely(__access_ok((unsigned long)from, n, get_fs())))
+		n = __copy_tofrom_user_nocheck(to, (__force void *)from, n);
+	else
+		memset(to, 0, n);
+	return n;
 }
 
 extern void __do_clear_user(void);
--- zfcpdump-kernel-4.4.orig/arch/alpha/kernel/module.c
+++ zfcpdump-kernel-4.4/arch/alpha/kernel/module.c
@@ -160,7 +160,7 @@ apply_relocate_add(Elf64_Shdr *sechdrs,
 
 	/* The small sections were sorted to the end of the segment.
 	   The following should definitely cover them.  */
-	gp = (u64)me->module_core + me->core_size - 0x8000;
+	gp = (u64)me->core_layout.base + me->core_layout.size - 0x8000;
 	got = sechdrs[me->arch.gotsecindex].sh_addr;
 
 	for (i = 0; i < n; i++) {
--- zfcpdump-kernel-4.4.orig/arch/arc/Kconfig
+++ zfcpdump-kernel-4.4/arch/arc/Kconfig
@@ -387,7 +387,7 @@ config ARC_HAS_LLSC
 
 config ARC_STAR_9000923308
 	bool "Workaround for llock/scond livelock"
-	default y
+	default n
 	depends on ISA_ARCV2 && SMP && ARC_HAS_LLSC
 
 config ARC_HAS_SWAPE
--- zfcpdump-kernel-4.4.orig/arch/arc/Makefile
+++ zfcpdump-kernel-4.4/arch/arc/Makefile
@@ -18,6 +18,20 @@ cflags-y	+= -fno-common -pipe -fno-built
 cflags-$(CONFIG_ISA_ARCOMPACT)	+= -mA7
 cflags-$(CONFIG_ISA_ARCV2)	+= -mcpu=archs
 
+is_700 = $(shell $(CC) -dM -E - < /dev/null | grep -q "ARC700" && echo 1 || echo 0)
+
+ifdef CONFIG_ISA_ARCOMPACT
+ifeq ($(is_700), 0)
+    $(error Toolchain not configured for ARCompact builds)
+endif
+endif
+
+ifdef CONFIG_ISA_ARCV2
+ifeq ($(is_700), 1)
+    $(error Toolchain not configured for ARCv2 builds)
+endif
+endif
+
 ifdef CONFIG_ARC_CURR_IN_REG
 # For a global register defintion, make sure it gets passed to every file
 # We had a customer reported bug where some code built in kernel was NOT using
@@ -48,8 +62,6 @@ endif
 
 endif
 
-cflags-$(CONFIG_ARC_DW2_UNWIND)		+= -fasynchronous-unwind-tables
-
 # By default gcc 4.8 generates dwarf4 which kernel unwinder can't grok
 ifeq ($(atleast_gcc48),y)
 cflags-$(CONFIG_ARC_DW2_UNWIND)		+= -gdwarf-2
--- zfcpdump-kernel-4.4.orig/arch/arc/include/asm/arcregs.h
+++ zfcpdump-kernel-4.4/arch/arc/include/asm/arcregs.h
@@ -374,12 +374,6 @@ static inline int is_isa_arcompact(void)
 	return IS_ENABLED(CONFIG_ISA_ARCOMPACT);
 }
 
-#if defined(CONFIG_ISA_ARCOMPACT) && !defined(_CPU_DEFAULT_A7)
-#error "Toolchain not configured for ARCompact builds"
-#elif defined(CONFIG_ISA_ARCV2) && !defined(_CPU_DEFAULT_HS)
-#error "Toolchain not configured for ARCv2 builds"
-#endif
-
 #endif /* __ASEMBLY__ */
 
 #endif /* _ASM_ARC_ARCREGS_H */
--- zfcpdump-kernel-4.4.orig/arch/arc/include/asm/bitops.h
+++ zfcpdump-kernel-4.4/arch/arc/include/asm/bitops.h
@@ -35,21 +35,6 @@ static inline void op##_bit(unsigned lon
 									\
 	m += nr >> 5;							\
 									\
-	/*								\
-	 * ARC ISA micro-optimization:					\
-	 *								\
-	 * Instructions dealing with bitpos only consider lower 5 bits	\
-	 * e.g (x << 33) is handled like (x << 1) by ASL instruction	\
-	 *  (mem pointer still needs adjustment to point to next word)	\
-	 *								\
-	 * Hence the masking to clamp @nr arg can be elided in general.	\
-	 *								\
-	 * However if @nr is a constant (above assumed in a register),	\
-	 * and greater than 31, gcc can optimize away (x << 33) to 0,	\
-	 * as overflow, given the 32-bit ISA. Thus masking needs to be	\
-	 * done for const @nr, but no code is generated due to gcc	\
-	 * const prop.							\
-	 */								\
 	nr &= 0x1f;							\
 									\
 	__asm__ __volatile__(						\
--- zfcpdump-kernel-4.4.orig/arch/arc/include/asm/entry.h
+++ zfcpdump-kernel-4.4/arch/arc/include/asm/entry.h
@@ -142,7 +142,7 @@
 
 #ifdef CONFIG_ARC_CURR_IN_REG
 	; Retrieve orig r25 and save it with rest of callee_regs
-	ld.as   r12, [r12, PT_user_r25]
+	ld	r12, [r12, PT_user_r25]
 	PUSH	r12
 #else
 	PUSH	r25
@@ -198,7 +198,7 @@
 
 	; SP is back to start of pt_regs
 #ifdef CONFIG_ARC_CURR_IN_REG
-	st.as   r12, [sp, PT_user_r25]
+	st	r12, [sp, PT_user_r25]
 #endif
 .endm
 
--- zfcpdump-kernel-4.4.orig/arch/arc/include/asm/io.h
+++ zfcpdump-kernel-4.4/arch/arc/include/asm/io.h
@@ -13,6 +13,15 @@
 #include <asm/byteorder.h>
 #include <asm/page.h>
 
+#ifdef CONFIG_ISA_ARCV2
+#include <asm/barrier.h>
+#define __iormb()		rmb()
+#define __iowmb()		wmb()
+#else
+#define __iormb()		do { } while (0)
+#define __iowmb()		do { } while (0)
+#endif
+
 extern void __iomem *ioremap(unsigned long physaddr, unsigned long size);
 extern void __iomem *ioremap_prot(phys_addr_t offset, unsigned long size,
 				  unsigned long flags);
@@ -22,6 +31,15 @@ extern void iounmap(const void __iomem *
 #define ioremap_wc(phy, sz)		ioremap(phy, sz)
 #define ioremap_wt(phy, sz)		ioremap(phy, sz)
 
+/*
+ * io{read,write}{16,32}be() macros
+ */
+#define ioread16be(p)		({ u16 __v = be16_to_cpu((__force __be16)__raw_readw(p)); __iormb(); __v; })
+#define ioread32be(p)		({ u32 __v = be32_to_cpu((__force __be32)__raw_readl(p)); __iormb(); __v; })
+
+#define iowrite16be(v,p)	({ __iowmb(); __raw_writew((__force u16)cpu_to_be16(v), p); })
+#define iowrite32be(v,p)	({ __iowmb(); __raw_writel((__force u32)cpu_to_be32(v), p); })
+
 /* Change struct page to physical address */
 #define page_to_phys(page)		(page_to_pfn(page) << PAGE_SHIFT)
 
@@ -99,15 +117,6 @@ static inline void __raw_writel(u32 w, v
 
 }
 
-#ifdef CONFIG_ISA_ARCV2
-#include <asm/barrier.h>
-#define __iormb()		rmb()
-#define __iowmb()		wmb()
-#else
-#define __iormb()		do { } while (0)
-#define __iowmb()		do { } while (0)
-#endif
-
 /*
  * MMIO can also get buffered/optimized in micro-arch, so barriers needed
  * Based on ARM model for the typical use case
@@ -129,15 +138,23 @@ static inline void __raw_writel(u32 w, v
 #define writel(v,c)		({ __iowmb(); writel_relaxed(v,c); })
 
 /*
- * Relaxed API for drivers which can handle any ordering themselves
+ * Relaxed API for drivers which can handle barrier ordering themselves
+ *
+ * Also these are defined to perform little endian accesses.
+ * To provide the typical device register semantics of fixed endian,
+ * swap the byte order for Big Endian
+ *
+ * http://lkml.kernel.org/r/201603100845.30602.arnd@arndb.de
  */
 #define readb_relaxed(c)	__raw_readb(c)
-#define readw_relaxed(c)	__raw_readw(c)
-#define readl_relaxed(c)	__raw_readl(c)
+#define readw_relaxed(c) ({ u16 __r = le16_to_cpu((__force __le16) \
+					__raw_readw(c)); __r; })
+#define readl_relaxed(c) ({ u32 __r = le32_to_cpu((__force __le32) \
+					__raw_readl(c)); __r; })
 
 #define writeb_relaxed(v,c)	__raw_writeb(v,c)
-#define writew_relaxed(v,c)	__raw_writew(v,c)
-#define writel_relaxed(v,c)	__raw_writel(v,c)
+#define writew_relaxed(v,c)	__raw_writew((__force u16) cpu_to_le16(v),c)
+#define writel_relaxed(v,c)	__raw_writel((__force u32) cpu_to_le32(v),c)
 
 #include <asm-generic/io.h>
 
--- zfcpdump-kernel-4.4.orig/arch/arc/include/asm/irqflags-arcv2.h
+++ zfcpdump-kernel-4.4/arch/arc/include/asm/irqflags-arcv2.h
@@ -22,6 +22,7 @@
 #define AUX_IRQ_CTRL		0x00E
 #define AUX_IRQ_ACT		0x043	/* Active Intr across all levels */
 #define AUX_IRQ_LVL_PEND	0x200	/* Pending Intr across all levels */
+#define AUX_IRQ_HINT		0x201	/* For generating Soft Interrupts */
 #define AUX_IRQ_PRIORITY	0x206
 #define ICAUSE			0x40a
 #define AUX_IRQ_SELECT		0x40b
@@ -112,6 +113,16 @@ static inline int arch_irqs_disabled(voi
 	return arch_irqs_disabled_flags(arch_local_save_flags());
 }
 
+static inline void arc_softirq_trigger(int irq)
+{
+	write_aux_reg(AUX_IRQ_HINT, irq);
+}
+
+static inline void arc_softirq_clear(int irq)
+{
+	write_aux_reg(AUX_IRQ_HINT, 0);
+}
+
 #else
 
 .macro IRQ_DISABLE  scratch
--- zfcpdump-kernel-4.4.orig/arch/arc/include/asm/irqflags-compact.h
+++ zfcpdump-kernel-4.4/arch/arc/include/asm/irqflags-compact.h
@@ -188,10 +188,10 @@ static inline int arch_irqs_disabled(voi
 .endm
 
 .macro IRQ_ENABLE  scratch
+	TRACE_ASM_IRQ_ENABLE
 	lr	\scratch, [status32]
 	or	\scratch, \scratch, (STATUS_E1_MASK | STATUS_E2_MASK)
 	flag	\scratch
-	TRACE_ASM_IRQ_ENABLE
 .endm
 
 #endif	/* __ASSEMBLY__ */
--- zfcpdump-kernel-4.4.orig/arch/arc/include/asm/pgtable.h
+++ zfcpdump-kernel-4.4/arch/arc/include/asm/pgtable.h
@@ -110,7 +110,7 @@
 #define ___DEF (_PAGE_PRESENT | _PAGE_CACHEABLE)
 
 /* Set of bits not changed in pte_modify */
-#define _PAGE_CHG_MASK	(PAGE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY)
+#define _PAGE_CHG_MASK	(PAGE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY | _PAGE_SPECIAL)
 
 /* More Abbrevaited helpers */
 #define PAGE_U_NONE     __pgprot(___DEF)
@@ -277,8 +277,7 @@ static inline void pmd_set(pmd_t *pmdp,
 
 #define mk_pte(page, prot)	pfn_pte(page_to_pfn(page), prot)
 #define pte_pfn(pte)		(pte_val(pte) >> PAGE_SHIFT)
-#define pfn_pte(pfn, prot)	(__pte(((pte_t)(pfn) << PAGE_SHIFT) | \
-				 pgprot_val(prot)))
+#define pfn_pte(pfn, prot)	(__pte(((pfn) << PAGE_SHIFT) | pgprot_val(prot)))
 #define __pte_index(addr)	(((addr) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))
 
 /*
--- zfcpdump-kernel-4.4.orig/arch/arc/include/asm/uaccess.h
+++ zfcpdump-kernel-4.4/arch/arc/include/asm/uaccess.h
@@ -83,7 +83,10 @@
 	"2:	;nop\n"				\
 	"	.section .fixup, \"ax\"\n"	\
 	"	.align 4\n"			\
-	"3:	mov %0, %3\n"			\
+	"3:	# return -EFAULT\n"		\
+	"	mov %0, %3\n"			\
+	"	# zero out dst ptr\n"		\
+	"	mov %1,  0\n"			\
 	"	j   2b\n"			\
 	"	.previous\n"			\
 	"	.section __ex_table, \"a\"\n"	\
@@ -101,7 +104,11 @@
 	"2:	;nop\n"				\
 	"	.section .fixup, \"ax\"\n"	\
 	"	.align 4\n"			\
-	"3:	mov %0, %3\n"			\
+	"3:	# return -EFAULT\n"		\
+	"	mov %0, %3\n"			\
+	"	# zero out dst ptr\n"		\
+	"	mov %1,  0\n"			\
+	"	mov %R1, 0\n"			\
 	"	j   2b\n"			\
 	"	.previous\n"			\
 	"	.section __ex_table, \"a\"\n"	\
--- zfcpdump-kernel-4.4.orig/arch/arc/kernel/entry-arcv2.S
+++ zfcpdump-kernel-4.4/arch/arc/kernel/entry-arcv2.S
@@ -45,11 +45,12 @@ VECTOR	reserved		; Reserved slots
 VECTOR	handle_interrupt	; (16) Timer0
 VECTOR	handle_interrupt	; unused (Timer1)
 VECTOR	handle_interrupt	; unused (WDT)
-VECTOR	handle_interrupt	; (19) ICI (inter core interrupt)
-VECTOR	handle_interrupt
-VECTOR	handle_interrupt
-VECTOR	handle_interrupt
-VECTOR	handle_interrupt	; (23) End of fixed IRQs
+VECTOR	handle_interrupt	; (19) Inter core Interrupt (IPI)
+VECTOR	handle_interrupt	; (20) perf Interrupt
+VECTOR	handle_interrupt	; (21) Software Triggered Intr (Self IPI)
+VECTOR	handle_interrupt	; unused
+VECTOR	handle_interrupt	; (23) unused
+# End of fixed IRQs
 
 .rept CONFIG_ARC_NUMBER_OF_INTERRUPTS - 8
 	VECTOR	handle_interrupt
@@ -211,7 +212,11 @@ debug_marker_syscall:
 ; (since IRQ NOT allowed in DS in ARCv2, this can only happen if orig
 ; entry was via Exception in DS which got preempted in kernel).
 ;
-; IRQ RTIE won't reliably restore DE bit and/or BTA, needs handling
+; IRQ RTIE won't reliably restore DE bit and/or BTA, needs workaround
+;
+; Solution is return from Intr w/o any delay slot quirks into a kernel trampoline
+; and from pure kernel mode return to delay slot which handles DS bit/BTA correctly
+
 .Lintr_ret_to_delay_slot:
 debug_marker_ds:
 
@@ -222,18 +227,23 @@ debug_marker_ds:
 	ld	r2, [sp, PT_ret]
 	ld	r3, [sp, PT_status32]
 
+	; STAT32 for Int return created from scratch
+	; (No delay dlot, disable Further intr in trampoline)
+
 	bic  	r0, r3, STATUS_U_MASK|STATUS_DE_MASK|STATUS_IE_MASK|STATUS_L_MASK
 	st	r0, [sp, PT_status32]
 
 	mov	r1, .Lintr_ret_to_delay_slot_2
 	st	r1, [sp, PT_ret]
 
+	; Orig exception PC/STAT32 safekept @orig_r0 and @event stack slots
 	st	r2, [sp, 0]
 	st	r3, [sp, 4]
 
 	b	.Lisr_ret_fast_path
 
 .Lintr_ret_to_delay_slot_2:
+	; Trampoline to restore orig exception PC/STAT32/BTA/AUX_USER_SP
 	sub	sp, sp, SZ_PT_REGS
 	st	r9, [sp, -4]
 
@@ -243,11 +253,19 @@ debug_marker_ds:
 	ld	r9, [sp, 4]
 	sr	r9, [erstatus]
 
+	; restore AUX_USER_SP if returning to U mode
+	bbit0	r9, STATUS_U_BIT, 1f
+	ld	r9, [sp, PT_sp]
+	sr	r9, [AUX_USER_SP]
+
+1:
 	ld	r9, [sp, 8]
 	sr	r9, [erbta]
 
 	ld	r9, [sp, -4]
 	add	sp, sp, SZ_PT_REGS
+
+	; return from pure kernel mode to delay slot
 	rtie
 
 END(ret_from_exception)
--- zfcpdump-kernel-4.4.orig/arch/arc/kernel/mcip.c
+++ zfcpdump-kernel-4.4/arch/arc/kernel/mcip.c
@@ -11,9 +11,12 @@
 #include <linux/smp.h>
 #include <linux/irq.h>
 #include <linux/spinlock.h>
+#include <asm/irqflags-arcv2.h>
 #include <asm/mcip.h>
 #include <asm/setup.h>
 
+#define SOFTIRQ_IRQ	21
+
 static char smp_cpuinfo_buf[128];
 static int idu_detected;
 
@@ -22,6 +25,7 @@ static DEFINE_RAW_SPINLOCK(mcip_lock);
 static void mcip_setup_per_cpu(int cpu)
 {
 	smp_ipi_irq_setup(cpu, IPI_IRQ);
+	smp_ipi_irq_setup(cpu, SOFTIRQ_IRQ);
 }
 
 static void mcip_ipi_send(int cpu)
@@ -29,6 +33,12 @@ static void mcip_ipi_send(int cpu)
 	unsigned long flags;
 	int ipi_was_pending;
 
+	/* ARConnect can only send IPI to others */
+	if (unlikely(cpu == raw_smp_processor_id())) {
+		arc_softirq_trigger(SOFTIRQ_IRQ);
+		return;
+	}
+
 	/*
 	 * NOTE: We must spin here if the other cpu hasn't yet
 	 * serviced a previous message. This can burn lots
@@ -63,6 +73,11 @@ static void mcip_ipi_clear(int irq)
 	unsigned long flags;
 	unsigned int __maybe_unused copy;
 
+	if (unlikely(irq == SOFTIRQ_IRQ)) {
+		arc_softirq_clear(irq);
+		return;
+	}
+
 	raw_spin_lock_irqsave(&mcip_lock, flags);
 
 	/* Who sent the IPI */
--- zfcpdump-kernel-4.4.orig/arch/arc/kernel/setup.c
+++ zfcpdump-kernel-4.4/arch/arc/kernel/setup.c
@@ -332,10 +332,6 @@ static void arc_chk_core_config(void)
 		pr_warn("CONFIG_ARC_FPU_SAVE_RESTORE needed for working apps\n");
 	else if (!cpu->extn.fpu_dp && fpu_enabled)
 		panic("FPU non-existent, disable CONFIG_ARC_FPU_SAVE_RESTORE\n");
-
-	if (is_isa_arcv2() && IS_ENABLED(CONFIG_SMP) && cpu->isa.atomic &&
-	    !IS_ENABLED(CONFIG_ARC_STAR_9000923308))
-		panic("llock/scond livelock workaround missing\n");
 }
 
 /*
--- zfcpdump-kernel-4.4.orig/arch/arc/kernel/stacktrace.c
+++ zfcpdump-kernel-4.4/arch/arc/kernel/stacktrace.c
@@ -142,7 +142,7 @@ arc_unwind_core(struct task_struct *tsk,
 	 * prelogue is setup (callee regs saved and then fp set and not other
 	 * way around
 	 */
-	pr_warn("CONFIG_ARC_DW2_UNWIND needs to be enabled\n");
+	pr_warn_once("CONFIG_ARC_DW2_UNWIND needs to be enabled\n");
 	return 0;
 
 #endif
--- zfcpdump-kernel-4.4.orig/arch/arc/kernel/unwind.c
+++ zfcpdump-kernel-4.4/arch/arc/kernel/unwind.c
@@ -385,8 +385,8 @@ void *unwind_add_table(struct module *mo
 		return NULL;
 
 	init_unwind_table(table, module->name,
-			  module->module_core, module->core_size,
-			  module->module_init, module->init_size,
+			  module->core_layout.base, module->core_layout.size,
+			  module->init_layout.base, module->init_layout.size,
 			  table_start, table_size,
 			  NULL, 0);
 
--- zfcpdump-kernel-4.4.orig/arch/arc/mm/cache.c
+++ zfcpdump-kernel-4.4/arch/arc/mm/cache.c
@@ -914,6 +914,15 @@ void arc_cache_init(void)
 
 	printk(arc_cache_mumbojumbo(0, str, sizeof(str)));
 
+	/*
+	 * Only master CPU needs to execute rest of function:
+	 *  - Assume SMP so all cores will have same cache config so
+	 *    any geomtry checks will be same for all
+	 *  - IOC setup / dma callbacks only need to be setup once
+	 */
+	if (cpu)
+		return;
+
 	if (IS_ENABLED(CONFIG_ARC_HAS_ICACHE)) {
 		struct cpuinfo_arc_cache *ic = &cpuinfo_arc700[cpu].icache;
 
--- zfcpdump-kernel-4.4.orig/arch/arm/Kconfig
+++ zfcpdump-kernel-4.4/arch/arm/Kconfig
@@ -2154,6 +2154,7 @@ source "net/Kconfig"
 source "drivers/Kconfig"
 
 source "drivers/firmware/Kconfig"
+source "ubuntu/Kconfig"
 
 source "fs/Kconfig"
 
--- zfcpdump-kernel-4.4.orig/arch/arm/Kconfig.debug
+++ zfcpdump-kernel-4.4/arch/arm/Kconfig.debug
@@ -162,10 +162,9 @@ choice
 		  mobile SoCs in the Kona family of chips (e.g. bcm28155,
 		  bcm11351, etc...)
 
-	config DEBUG_BCM63XX
+	config DEBUG_BCM63XX_UART
 		bool "Kernel low-level debugging on BCM63XX UART"
 		depends on ARCH_BCM_63XX
-		select DEBUG_UART_BCM63XX
 
 	config DEBUG_BERLIN_UART
 		bool "Marvell Berlin SoC Debug UART"
@@ -1348,7 +1347,7 @@ config DEBUG_LL_INCLUDE
 	default "debug/vf.S" if DEBUG_VF_UART
 	default "debug/vt8500.S" if DEBUG_VT8500_UART0
 	default "debug/zynq.S" if DEBUG_ZYNQ_UART0 || DEBUG_ZYNQ_UART1
-	default "debug/bcm63xx.S" if DEBUG_UART_BCM63XX
+	default "debug/bcm63xx.S" if DEBUG_BCM63XX_UART
 	default "debug/digicolor.S" if DEBUG_DIGICOLOR_UA0
 	default "mach/debug-macro.S"
 
@@ -1364,10 +1363,6 @@ config DEBUG_UART_8250
 		ARCH_IOP33X || ARCH_IXP4XX || \
 		ARCH_LPC32XX || ARCH_MV78XX0 || ARCH_ORION5X || ARCH_RPC
 
-# Compatibility options for BCM63xx
-config DEBUG_UART_BCM63XX
-	def_bool ARCH_BCM_63XX
-
 config DEBUG_UART_PHYS
 	hex "Physical base address of debug UART"
 	default 0x00100a00 if DEBUG_NETX_UART
@@ -1462,7 +1457,7 @@ config DEBUG_UART_PHYS
 	default 0xfffb0000 if DEBUG_OMAP1UART1 || DEBUG_OMAP7XXUART1
 	default 0xfffb0800 if DEBUG_OMAP1UART2 || DEBUG_OMAP7XXUART2
 	default 0xfffb9800 if DEBUG_OMAP1UART3 || DEBUG_OMAP7XXUART3
-	default 0xfffe8600 if DEBUG_UART_BCM63XX
+	default 0xfffe8600 if DEBUG_BCM63XX_UART
 	default 0xfffff700 if ARCH_IOP33X
 	depends on ARCH_EP93XX || \
 	        DEBUG_LL_UART_8250 || DEBUG_LL_UART_PL01X || \
@@ -1474,7 +1469,7 @@ config DEBUG_UART_PHYS
 		DEBUG_RCAR_GEN2_SCIF0 || DEBUG_RCAR_GEN2_SCIF2 || \
 		DEBUG_RMOBILE_SCIFA0 || DEBUG_RMOBILE_SCIFA1 || \
 		DEBUG_RMOBILE_SCIFA4 || DEBUG_S3C24XX_UART || \
-		DEBUG_UART_BCM63XX || DEBUG_ASM9260_UART || \
+		DEBUG_BCM63XX_UART || DEBUG_ASM9260_UART || \
 		DEBUG_SIRFSOC_UART || DEBUG_DIGICOLOR_UA0 || \
 		DEBUG_AT91_UART
 
@@ -1515,7 +1510,7 @@ config DEBUG_UART_VIRT
 	default 0xfb10c000 if DEBUG_REALVIEW_PB1176_PORT
 	default 0xfc40ab00 if DEBUG_BRCMSTB_UART
 	default 0xfc705000 if DEBUG_ZTE_ZX
-	default 0xfcfe8600 if DEBUG_UART_BCM63XX
+	default 0xfcfe8600 if DEBUG_BCM63XX_UART
 	default 0xfd000000 if ARCH_SPEAR3XX || ARCH_SPEAR6XX
 	default 0xfd000000 if ARCH_SPEAR13XX
 	default 0xfd012000 if ARCH_MV78XX0
@@ -1566,7 +1561,7 @@ config DEBUG_UART_VIRT
 		DEBUG_UART_8250 || DEBUG_UART_PL01X || DEBUG_MESON_UARTAO || \
 		DEBUG_NETX_UART || \
 		DEBUG_QCOM_UARTDM || DEBUG_S3C24XX_UART || \
-		DEBUG_UART_BCM63XX || DEBUG_ASM9260_UART || \
+		DEBUG_BCM63XX_UART || DEBUG_ASM9260_UART || \
 		DEBUG_SIRFSOC_UART || DEBUG_DIGICOLOR_UA0
 
 config DEBUG_UART_8250_SHIFT
--- zfcpdump-kernel-4.4.orig/arch/arm/boot/compressed/Makefile
+++ zfcpdump-kernel-4.4/arch/arm/boot/compressed/Makefile
@@ -3,6 +3,7 @@
 #
 # create a compressed vmlinuz image from the original vmlinux
 #
+KBUILD_CFLAGS := $(filter-out -fstack-protector, $(KBUILD_CFLAGS)) -fno-stack-protector
 
 OBJS		=
 
--- zfcpdump-kernel-4.4.orig/arch/arm/boot/compressed/head.S
+++ zfcpdump-kernel-4.4/arch/arm/boot/compressed/head.S
@@ -776,7 +776,7 @@ __armv7_mmu_cache_on:
 		orrne	r0, r0, #1		@ MMU enabled
 		movne	r1, #0xfffffffd		@ domain 0 = client
 		bic     r6, r6, #1 << 31        @ 32-bit translation system
-		bic     r6, r6, #3 << 0         @ use only ttbr0
+		bic     r6, r6, #(7 << 0) | (1 << 4)	@ use only ttbr0
 		mcrne	p15, 0, r3, c2, c0, 0	@ load page table pointer
 		mcrne	p15, 0, r1, c3, c0, 0	@ load domain access control
 		mcrne   p15, 0, r6, c2, c0, 2   @ load ttb control
--- zfcpdump-kernel-4.4.orig/arch/arm/boot/dts/am43x-epos-evm.dts
+++ zfcpdump-kernel-4.4/arch/arm/boot/dts/am43x-epos-evm.dts
@@ -792,3 +792,8 @@
 	tx-num-evt = <32>;
 	rx-num-evt = <32>;
 };
+
+&synctimer_32kclk {
+	assigned-clocks = <&mux_synctimer32k_ck>;
+	assigned-clock-parents = <&clkdiv32k_ick>;
+};
--- zfcpdump-kernel-4.4.orig/arch/arm/boot/dts/armada-375.dtsi
+++ zfcpdump-kernel-4.4/arch/arm/boot/dts/armada-375.dtsi
@@ -529,7 +529,7 @@
 			};
 
 			sata@a0000 {
-				compatible = "marvell,orion-sata";
+				compatible = "marvell,armada-370-sata";
 				reg = <0xa0000 0x5000>;
 				interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>;
 				clocks = <&gateclk 14>, <&gateclk 20>;
--- zfcpdump-kernel-4.4.orig/arch/arm/boot/dts/armada-385-linksys.dtsi
+++ zfcpdump-kernel-4.4/arch/arm/boot/dts/armada-385-linksys.dtsi
@@ -58,8 +58,8 @@
 	soc {
 		ranges = <MBUS_ID(0xf0, 0x01) 0 0xf1000000 0x100000
 			  MBUS_ID(0x01, 0x1d) 0 0xfff00000 0x100000
-			  MBUS_ID(0x09, 0x09) 0 0xf1100000 0x10000
-			  MBUS_ID(0x09, 0x05) 0 0xf1110000 0x10000>;
+			  MBUS_ID(0x09, 0x19) 0 0xf1100000 0x10000
+			  MBUS_ID(0x09, 0x15) 0 0xf1110000 0x10000>;
 
 		internal-regs {
 
@@ -117,7 +117,7 @@
 			};
 
 			/* USB part of the eSATA/USB 2.0 port */
-			usb@50000 {
+			usb@58000 {
 				status = "okay";
 			};
 
@@ -245,7 +245,7 @@
 		button@2 {
 			label = "Factory Reset Button";
 			linux,code = <KEY_RESTART>;
-			gpios = <&gpio1 15 GPIO_ACTIVE_LOW>;
+			gpios = <&gpio0 29 GPIO_ACTIVE_LOW>;
 		};
 	};
 
@@ -260,7 +260,7 @@
 		};
 
 		sata {
-			gpios = <&gpio1 22 GPIO_ACTIVE_HIGH>;
+			gpios = <&gpio1 22 GPIO_ACTIVE_LOW>;
 			default-state = "off";
 		};
 	};
@@ -313,7 +313,7 @@
 
 &pinctrl {
 	keys_pin: keys-pin {
-		marvell,pins = "mpp24", "mpp47";
+		marvell,pins = "mpp24", "mpp29";
 		marvell,function = "gpio";
 	};
 
--- zfcpdump-kernel-4.4.orig/arch/arm/boot/dts/armada-388-gp.dts
+++ zfcpdump-kernel-4.4/arch/arm/boot/dts/armada-388-gp.dts
@@ -303,16 +303,6 @@
 		gpio = <&expander0 4 GPIO_ACTIVE_HIGH>;
 	};
 
-	reg_usb2_1_vbus: v5-vbus1 {
-		compatible = "regulator-fixed";
-		regulator-name = "v5.0-vbus1";
-		regulator-min-microvolt = <5000000>;
-		regulator-max-microvolt = <5000000>;
-		enable-active-high;
-		regulator-always-on;
-		gpio = <&expander0 4 GPIO_ACTIVE_HIGH>;
-	};
-
 	reg_sata0: pwr-sata0 {
 		compatible = "regulator-fixed";
 		regulator-name = "pwr_en_sata0";
--- zfcpdump-kernel-4.4.orig/arch/arm/boot/dts/armada-xp-axpwifiap.dts
+++ zfcpdump-kernel-4.4/arch/arm/boot/dts/armada-xp-axpwifiap.dts
@@ -70,8 +70,8 @@
 	soc {
 		ranges = <MBUS_ID(0xf0, 0x01) 0 0 0xf1000000 0x100000
 			  MBUS_ID(0x01, 0x1d) 0 0 0xfff00000 0x100000
-			  MBUS_ID(0x09, 0x09) 0 0 0xf8100000 0x10000
-			  MBUS_ID(0x09, 0x05) 0 0 0xf8110000 0x10000>;
+			  MBUS_ID(0x09, 0x09) 0 0 0xf1100000 0x10000
+			  MBUS_ID(0x09, 0x05) 0 0 0xf1110000 0x10000>;
 
 		pcie-controller {
 			status = "okay";
--- zfcpdump-kernel-4.4.orig/arch/arm/boot/dts/armada-xp-db.dts
+++ zfcpdump-kernel-4.4/arch/arm/boot/dts/armada-xp-db.dts
@@ -76,8 +76,8 @@
 		ranges = <MBUS_ID(0xf0, 0x01) 0 0 0xf1000000 0x100000
 			  MBUS_ID(0x01, 0x1d) 0 0 0xfff00000 0x100000
 			  MBUS_ID(0x01, 0x2f) 0 0 0xf0000000 0x1000000
-			  MBUS_ID(0x09, 0x09) 0 0 0xf8100000 0x10000
-			  MBUS_ID(0x09, 0x05) 0 0 0xf8110000 0x10000>;
+			  MBUS_ID(0x09, 0x09) 0 0 0xf1100000 0x10000
+			  MBUS_ID(0x09, 0x05) 0 0 0xf1110000 0x10000>;
 
 		devbus-bootcs {
 			status = "okay";
--- zfcpdump-kernel-4.4.orig/arch/arm/boot/dts/armada-xp-gp.dts
+++ zfcpdump-kernel-4.4/arch/arm/boot/dts/armada-xp-gp.dts
@@ -95,8 +95,8 @@
 		ranges = <MBUS_ID(0xf0, 0x01) 0 0 0xf1000000 0x100000
 			  MBUS_ID(0x01, 0x1d) 0 0 0xfff00000 0x100000
 			  MBUS_ID(0x01, 0x2f) 0 0 0xf0000000 0x1000000
-			  MBUS_ID(0x09, 0x09) 0 0 0xf8100000 0x10000
-			  MBUS_ID(0x09, 0x05) 0 0 0xf8110000 0x10000>;
+			  MBUS_ID(0x09, 0x09) 0 0 0xf1100000 0x10000
+			  MBUS_ID(0x09, 0x05) 0 0 0xf1110000 0x10000>;
 
 		devbus-bootcs {
 			status = "okay";
--- zfcpdump-kernel-4.4.orig/arch/arm/boot/dts/armada-xp-lenovo-ix4-300d.dts
+++ zfcpdump-kernel-4.4/arch/arm/boot/dts/armada-xp-lenovo-ix4-300d.dts
@@ -65,8 +65,8 @@
 	soc {
 		ranges = <MBUS_ID(0xf0, 0x01) 0 0 0xd0000000 0x100000
 			MBUS_ID(0x01, 0x1d) 0 0 0xfff00000 0x100000
-			MBUS_ID(0x09, 0x09) 0 0 0xf8100000 0x10000
-			MBUS_ID(0x09, 0x05) 0 0 0xf8110000 0x10000>;
+			MBUS_ID(0x09, 0x09) 0 0 0xf1100000 0x10000
+			MBUS_ID(0x09, 0x05) 0 0 0xf1110000 0x10000>;
 
 		pcie-controller {
 			status = "okay";
--- zfcpdump-kernel-4.4.orig/arch/arm/boot/dts/armada-xp-linksys-mamba.dts
+++ zfcpdump-kernel-4.4/arch/arm/boot/dts/armada-xp-linksys-mamba.dts
@@ -70,8 +70,8 @@
 	soc {
 		ranges = <MBUS_ID(0xf0, 0x01) 0 0 0xf1000000 0x100000
 			  MBUS_ID(0x01, 0x1d) 0 0 0xfff00000 0x100000
-			  MBUS_ID(0x09, 0x09) 0 0 0xf8100000 0x10000
-			  MBUS_ID(0x09, 0x05) 0 0 0xf8110000 0x10000>;
+			  MBUS_ID(0x09, 0x09) 0 0 0xf1100000 0x10000
+			  MBUS_ID(0x09, 0x05) 0 0 0xf1110000 0x10000>;
 
 		pcie-controller {
 			status = "okay";
@@ -304,13 +304,13 @@
 		button@1 {
 			label = "WPS";
 			linux,code = <KEY_WPS_BUTTON>;
-			gpios = <&gpio1 0 GPIO_ACTIVE_HIGH>;
+			gpios = <&gpio1 0 GPIO_ACTIVE_LOW>;
 		};
 
 		button@2 {
 			label = "Factory Reset Button";
 			linux,code = <KEY_RESTART>;
-			gpios = <&gpio1 1 GPIO_ACTIVE_HIGH>;
+			gpios = <&gpio1 1 GPIO_ACTIVE_LOW>;
 		};
 	};
 
--- zfcpdump-kernel-4.4.orig/arch/arm/boot/dts/armada-xp-matrix.dts
+++ zfcpdump-kernel-4.4/arch/arm/boot/dts/armada-xp-matrix.dts
@@ -68,8 +68,8 @@
 	soc {
 		ranges = <MBUS_ID(0xf0, 0x01) 0 0 0xf1000000 0x100000
 			  MBUS_ID(0x01, 0x1d) 0 0 0xfff00000 0x100000
-			  MBUS_ID(0x09, 0x09) 0 0 0xf8100000 0x10000
-			  MBUS_ID(0x09, 0x05) 0 0 0xf8110000 0x10000>;
+			  MBUS_ID(0x09, 0x09) 0 0 0xf1100000 0x10000
+			  MBUS_ID(0x09, 0x05) 0 0 0xf1110000 0x10000>;
 
 		internal-regs {
 			serial@12000 {
--- zfcpdump-kernel-4.4.orig/arch/arm/boot/dts/armada-xp-netgear-rn2120.dts
+++ zfcpdump-kernel-4.4/arch/arm/boot/dts/armada-xp-netgear-rn2120.dts
@@ -64,8 +64,8 @@
 	soc {
 		ranges = <MBUS_ID(0xf0, 0x01) 0 0 0xd0000000 0x100000
 			  MBUS_ID(0x01, 0x1d) 0 0 0xfff00000 0x100000
-			  MBUS_ID(0x09, 0x09) 0 0 0xf8100000 0x10000
-			  MBUS_ID(0x09, 0x05) 0 0 0xf8110000 0x10000>;
+			  MBUS_ID(0x09, 0x09) 0 0 0xf1100000 0x10000
+			  MBUS_ID(0x09, 0x05) 0 0 0xf1110000 0x10000>;
 
 		pcie-controller {
 			status = "okay";
--- zfcpdump-kernel-4.4.orig/arch/arm/boot/dts/armada-xp-openblocks-ax3-4.dts
+++ zfcpdump-kernel-4.4/arch/arm/boot/dts/armada-xp-openblocks-ax3-4.dts
@@ -65,9 +65,9 @@
 	soc {
 		ranges = <MBUS_ID(0xf0, 0x01) 0 0 0xd0000000 0x100000
 			  MBUS_ID(0x01, 0x1d) 0 0 0xfff00000 0x100000
-			  MBUS_ID(0x01, 0x2f) 0 0 0xf0000000 0x8000000
-			  MBUS_ID(0x09, 0x09) 0 0 0xf8100000 0x10000
-			  MBUS_ID(0x09, 0x05) 0 0 0xf8110000 0x10000>;
+			  MBUS_ID(0x01, 0x2f) 0 0 0xe8000000 0x8000000
+			  MBUS_ID(0x09, 0x09) 0 0 0xf1100000 0x10000
+			  MBUS_ID(0x09, 0x05) 0 0 0xf1110000 0x10000>;
 
 		devbus-bootcs {
 			status = "okay";
--- zfcpdump-kernel-4.4.orig/arch/arm/boot/dts/armada-xp-synology-ds414.dts
+++ zfcpdump-kernel-4.4/arch/arm/boot/dts/armada-xp-synology-ds414.dts
@@ -78,8 +78,8 @@
 	soc {
 		ranges = <MBUS_ID(0xf0, 0x01) 0 0 0xf1000000 0x100000
 			  MBUS_ID(0x01, 0x1d) 0 0 0xfff00000 0x100000
-			  MBUS_ID(0x09, 0x09) 0 0 0xf8100000 0x10000
-			  MBUS_ID(0x09, 0x05) 0 0 0xf8110000 0x10000>;
+			  MBUS_ID(0x09, 0x09) 0 0 0xf1100000 0x10000
+			  MBUS_ID(0x09, 0x05) 0 0 0xf1110000 0x10000>;
 
 		pcie-controller {
 			status = "okay";
--- zfcpdump-kernel-4.4.orig/arch/arm/boot/dts/at91-sama5d3_xplained.dts
+++ zfcpdump-kernel-4.4/arch/arm/boot/dts/at91-sama5d3_xplained.dts
@@ -303,6 +303,7 @@
 		regulator-name = "mmc0-card-supply";
 		regulator-min-microvolt = <3300000>;
 		regulator-max-microvolt = <3300000>;
+		regulator-always-on;
 	};
 
 	gpio_keys {
--- zfcpdump-kernel-4.4.orig/arch/arm/boot/dts/at91-sama5d4_xplained.dts
+++ zfcpdump-kernel-4.4/arch/arm/boot/dts/at91-sama5d4_xplained.dts
@@ -86,10 +86,12 @@
 			macb0: ethernet@f8020000 {
 				phy-mode = "rmii";
 				status = "okay";
+				pinctrl-names = "default";
+				pinctrl-0 = <&pinctrl_macb0_rmii &pinctrl_macb0_phy_irq>;
 
 				phy0: ethernet-phy@1 {
 					interrupt-parent = <&pioE>;
-					interrupts = <1 IRQ_TYPE_EDGE_FALLING>;
+					interrupts = <1 IRQ_TYPE_LEVEL_LOW>;
 					reg = <1>;
 				};
 			};
@@ -152,6 +154,10 @@
 						atmel,pins =
 							<AT91_PIOE 8 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP_DEGLITCH>;
 					};
+					pinctrl_macb0_phy_irq: macb0_phy_irq_0 {
+						atmel,pins =
+							<AT91_PIOE 1 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP_DEGLITCH>;
+					};
 				};
 			};
 		};
@@ -262,5 +268,6 @@
 		regulator-min-microvolt = <3300000>;
 		regulator-max-microvolt = <3300000>;
 		vin-supply = <&vcc_3v3_reg>;
+		regulator-always-on;
 	};
 };
--- zfcpdump-kernel-4.4.orig/arch/arm/boot/dts/at91-sama5d4ek.dts
+++ zfcpdump-kernel-4.4/arch/arm/boot/dts/at91-sama5d4ek.dts
@@ -160,8 +160,15 @@
 			};
 
 			macb0: ethernet@f8020000 {
+				pinctrl-0 = <&pinctrl_macb0_rmii &pinctrl_macb0_phy_irq>;
 				phy-mode = "rmii";
 				status = "okay";
+
+				ethernet-phy@1 {
+					reg = <0x1>;
+					interrupt-parent = <&pioE>;
+					interrupts = <1 IRQ_TYPE_LEVEL_LOW>;
+				};
 			};
 
 			mmc1: mmc@fc000000 {
@@ -193,6 +200,10 @@
 
 			pinctrl@fc06a000 {
 				board {
+					pinctrl_macb0_phy_irq: macb0_phy_irq {
+						atmel,pins =
+							<AT91_PIOE 1 AT91_PERIPH_GPIO AT91_PINCTRL_NONE>;
+					};
 					pinctrl_mmc0_cd: mmc0_cd {
 						atmel,pins =
 							<AT91_PIOE 5 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP_DEGLITCH>;
--- zfcpdump-kernel-4.4.orig/arch/arm/boot/dts/at91sam9x5.dtsi
+++ zfcpdump-kernel-4.4/arch/arm/boot/dts/at91sam9x5.dtsi
@@ -106,7 +106,7 @@
 
 			pmc: pmc@fffffc00 {
 				compatible = "atmel,at91sam9x5-pmc", "syscon";
-				reg = <0xfffffc00 0x100>;
+				reg = <0xfffffc00 0x200>;
 				interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
 				interrupt-controller;
 				#address-cells = <1>;
--- zfcpdump-kernel-4.4.orig/arch/arm/boot/dts/dra7.dtsi
+++ zfcpdump-kernel-4.4/arch/arm/boot/dts/dra7.dtsi
@@ -1497,6 +1497,16 @@
 			       0x48485200 0x2E00>;
 			#address-cells = <1>;
 			#size-cells = <1>;
+
+			/*
+			 * Do not allow gating of cpsw clock as workaround
+			 * for errata i877. Keeping internal clock disabled
+			 * causes the device switching characteristics
+			 * to degrade over time and eventually fail to meet
+			 * the data manual delay time/skew specs.
+			 */
+			ti,no-idle;
+
 			/*
 			 * rx_thresh_pend
 			 * rx_pend
--- zfcpdump-kernel-4.4.orig/arch/arm/boot/dts/exynos4210-trats.dts
+++ zfcpdump-kernel-4.4/arch/arm/boot/dts/exynos4210-trats.dts
@@ -298,6 +298,8 @@
 		compatible = "maxim,max8997-pmic";
 
 		reg = <0x66>;
+		interrupt-parent = <&gpx0>;
+		interrupts = <7 0>;
 
 		max8997,pmic-buck1-uses-gpio-dvs;
 		max8997,pmic-buck2-uses-gpio-dvs;
--- zfcpdump-kernel-4.4.orig/arch/arm/boot/dts/imx6qdl.dtsi
+++ zfcpdump-kernel-4.4/arch/arm/boot/dts/imx6qdl.dtsi
@@ -221,7 +221,7 @@
 					clocks = <&clks IMX6QDL_CLK_SPDIF_GCLK>, <&clks IMX6QDL_CLK_OSC>,
 						 <&clks IMX6QDL_CLK_SPDIF>, <&clks IMX6QDL_CLK_ASRC>,
 						 <&clks IMX6QDL_CLK_DUMMY>, <&clks IMX6QDL_CLK_ESAI_EXTAL>,
-						 <&clks IMX6QDL_CLK_IPG>, <&clks IMX6QDL_CLK_MLB>,
+						 <&clks IMX6QDL_CLK_IPG>, <&clks IMX6QDL_CLK_DUMMY>,
 						 <&clks IMX6QDL_CLK_DUMMY>, <&clks IMX6QDL_CLK_SPBA>;
 					clock-names = "core",  "rxtx0",
 						      "rxtx1", "rxtx2",
--- zfcpdump-kernel-4.4.orig/arch/arm/boot/dts/kirkwood-ib62x0.dts
+++ zfcpdump-kernel-4.4/arch/arm/boot/dts/kirkwood-ib62x0.dts
@@ -113,7 +113,7 @@
 
 	partition@e0000 {
 		label = "u-boot environment";
-		reg = <0xe0000 0x100000>;
+		reg = <0xe0000 0x20000>;
 	};
 
 	partition@100000 {
--- zfcpdump-kernel-4.4.orig/arch/arm/boot/dts/logicpd-torpedo-som.dtsi
+++ zfcpdump-kernel-4.4/arch/arm/boot/dts/logicpd-torpedo-som.dtsi
@@ -122,6 +122,7 @@
 		interrupt-parent = <&gpio5>;
 		interrupts = <24 IRQ_TYPE_LEVEL_HIGH>; /* gpio 152 */
 		ref-clock-frequency = <26000000>;
+		tcxo-clock-frequency = <26000000>;
 	};
 };
 
--- zfcpdump-kernel-4.4.orig/arch/arm/boot/dts/omap3-overo-base.dtsi
+++ zfcpdump-kernel-4.4/arch/arm/boot/dts/omap3-overo-base.dtsi
@@ -223,7 +223,9 @@
 };
 
 &gpmc {
-	ranges = <0 0 0x00000000 0x20000000>;
+	ranges = <0 0 0x30000000 0x1000000>,	/* CS0 */
+		 <4 0 0x2b000000 0x1000000>,	/* CS4 */
+		 <5 0 0x2c000000 0x1000000>;	/* CS5 */
 
 	nand@0,0 {
 		linux,mtd-name= "micron,mt29c4g96maz";
--- zfcpdump-kernel-4.4.orig/arch/arm/boot/dts/omap3-overo-chestnut43-common.dtsi
+++ zfcpdump-kernel-4.4/arch/arm/boot/dts/omap3-overo-chestnut43-common.dtsi
@@ -55,8 +55,6 @@
 #include "omap-gpmc-smsc9221.dtsi"
 
 &gpmc {
-	ranges = <5 0 0x2c000000 0x1000000>;	/* CS5 */
-
 	ethernet@gpmc {
 		reg = <5 0 0xff>;
 		interrupt-parent = <&gpio6>;
--- zfcpdump-kernel-4.4.orig/arch/arm/boot/dts/omap3-overo-tobi-common.dtsi
+++ zfcpdump-kernel-4.4/arch/arm/boot/dts/omap3-overo-tobi-common.dtsi
@@ -27,8 +27,6 @@
 #include "omap-gpmc-smsc9221.dtsi"
 
 &gpmc {
-	ranges = <5 0 0x2c000000 0x1000000>;	/* CS5 */
-
 	ethernet@gpmc {
 		reg = <5 0 0xff>;
 		interrupt-parent = <&gpio6>;
--- zfcpdump-kernel-4.4.orig/arch/arm/boot/dts/omap3-overo-tobiduo-common.dtsi
+++ zfcpdump-kernel-4.4/arch/arm/boot/dts/omap3-overo-tobiduo-common.dtsi
@@ -15,9 +15,6 @@
 #include "omap-gpmc-smsc9221.dtsi"
 
 &gpmc {
-	ranges = <4 0 0x2b000000 0x1000000>,	/* CS4 */
-		 <5 0 0x2c000000 0x1000000>;	/* CS5 */
-
 	smsc1: ethernet@gpmc {
 		reg = <5 0 0xff>;
 		interrupt-parent = <&gpio6>;
--- zfcpdump-kernel-4.4.orig/arch/arm/boot/dts/omap5-board-common.dtsi
+++ zfcpdump-kernel-4.4/arch/arm/boot/dts/omap5-board-common.dtsi
@@ -130,6 +130,16 @@
 	};
 };
 
+&gpio8 {
+	/* TI trees use GPIO instead of msecure, see also muxing */
+	p234 {
+		gpio-hog;
+		gpios = <10 GPIO_ACTIVE_HIGH>;
+		output-high;
+		line-name = "gpio8_234/msecure";
+	};
+};
+
 &omap5_pmx_core {
 	pinctrl-names = "default";
 	pinctrl-0 = <
@@ -213,6 +223,13 @@
 		>;
 	};
 
+	/* TI trees use GPIO mode; msecure mode does not work reliably? */
+	palmas_msecure_pins: palmas_msecure_pins {
+		pinctrl-single,pins = <
+			OMAP5_IOPAD(0x180, PIN_OUTPUT | MUX_MODE6) /* gpio8_234 */
+		>;
+	};
+
 	usbhost_pins: pinmux_usbhost_pins {
 		pinctrl-single,pins = <
 			0x84 (PIN_INPUT | MUX_MODE0) /* usbb2_hsic_strobe */
@@ -278,6 +295,12 @@
 			&usbhost_wkup_pins
 	>;
 
+	palmas_sys_nirq_pins: pinmux_palmas_sys_nirq_pins {
+		pinctrl-single,pins = <
+			OMAP5_IOPAD(0x068, PIN_INPUT_PULLUP | MUX_MODE0) /* sys_nirq1 */
+		>;
+	};
+
 	usbhost_wkup_pins: pinmux_usbhost_wkup_pins {
 		pinctrl-single,pins = <
 			0x1A (PIN_OUTPUT | MUX_MODE0) /* fref_clk1_out, USB hub clk */
@@ -345,6 +368,8 @@
 		interrupt-controller;
 		#interrupt-cells = <2>;
 		ti,system-power-controller;
+		pinctrl-names = "default";
+		pinctrl-0 = <&palmas_sys_nirq_pins &palmas_msecure_pins>;
 
 		extcon_usb3: palmas_usb {
 			compatible = "ti,palmas-usb-vid";
@@ -358,6 +383,14 @@
 			#clock-cells = <0>;
 		};
 
+		rtc {
+			compatible = "ti,palmas-rtc";
+			interrupt-parent = <&palmas>;
+			interrupts = <8 IRQ_TYPE_NONE>;
+			ti,backup-battery-chargeable;
+			ti,backup-battery-charge-high-current;
+		};
+
 		palmas_pmic {
 			compatible = "ti,palmas-pmic";
 			interrupt-parent = <&palmas>;
--- zfcpdump-kernel-4.4.orig/arch/arm/boot/dts/pxa3xx.dtsi
+++ zfcpdump-kernel-4.4/arch/arm/boot/dts/pxa3xx.dtsi
@@ -30,7 +30,7 @@
 			reg = <0x43100000 90>;
 			interrupts = <45>;
 			clocks = <&clks CLK_NAND>;
-			dmas = <&pdma 97>;
+			dmas = <&pdma 97 3>;
 			dma-names = "data";
 			#address-cells = <1>;
 			#size-cells = <1>;	
--- zfcpdump-kernel-4.4.orig/arch/arm/boot/dts/sama5d2-pinfunc.h
+++ zfcpdump-kernel-4.4/arch/arm/boot/dts/sama5d2-pinfunc.h
@@ -90,7 +90,7 @@
 #define PIN_PA14__I2SC1_MCK		PINMUX_PIN(PIN_PA14, 4, 2)
 #define PIN_PA14__FLEXCOM3_IO2		PINMUX_PIN(PIN_PA14, 5, 1)
 #define PIN_PA14__D9			PINMUX_PIN(PIN_PA14, 6, 2)
-#define PIN_PA15			14
+#define PIN_PA15			15
 #define PIN_PA15__GPIO			PINMUX_PIN(PIN_PA15, 0, 0)
 #define PIN_PA15__SPI0_MOSI		PINMUX_PIN(PIN_PA15, 1, 1)
 #define PIN_PA15__TF1			PINMUX_PIN(PIN_PA15, 2, 1)
@@ -837,8 +837,8 @@
 #define PIN_PD23__ISC_FIELD		PINMUX_PIN(PIN_PD23, 6, 4)
 #define PIN_PD24			120
 #define PIN_PD24__GPIO			PINMUX_PIN(PIN_PD24, 0, 0)
-#define PIN_PD24__UTXD2			PINMUX_PIN(PIN_PD23, 1, 2)
-#define PIN_PD24__FLEXCOM4_IO3		PINMUX_PIN(PIN_PD23, 3, 3)
+#define PIN_PD24__UTXD2			PINMUX_PIN(PIN_PD24, 1, 2)
+#define PIN_PD24__FLEXCOM4_IO3		PINMUX_PIN(PIN_PD24, 3, 3)
 #define PIN_PD25			121
 #define PIN_PD25__GPIO			PINMUX_PIN(PIN_PD25, 0, 0)
 #define PIN_PD25__SPI1_SPCK		PINMUX_PIN(PIN_PD25, 1, 3)
--- zfcpdump-kernel-4.4.orig/arch/arm/boot/dts/sama5d4.dtsi
+++ zfcpdump-kernel-4.4/arch/arm/boot/dts/sama5d4.dtsi
@@ -1342,7 +1342,7 @@
 			dbgu: serial@fc069000 {
 				compatible = "atmel,at91sam9260-dbgu", "atmel,at91sam9260-usart";
 				reg = <0xfc069000 0x200>;
-				interrupts = <2 IRQ_TYPE_LEVEL_HIGH 7>;
+				interrupts = <45 IRQ_TYPE_LEVEL_HIGH 7>;
 				pinctrl-names = "default";
 				pinctrl-0 = <&pinctrl_dbgu>;
 				clocks = <&dbgu_clk>;
--- zfcpdump-kernel-4.4.orig/arch/arm/boot/dts/ste-nomadik-stn8815.dtsi
+++ zfcpdump-kernel-4.4/arch/arm/boot/dts/ste-nomadik-stn8815.dtsi
@@ -127,22 +127,14 @@
 			};
 			mmcsd_default_mode: mmcsd_default {
 				mmcsd_default_cfg1 {
-					/* MCCLK */
-					pins = "GPIO8_B10";
-					ste,output = <0>;
-				};
-				mmcsd_default_cfg2 {
-					/* MCCMDDIR, MCDAT0DIR, MCDAT31DIR, MCDATDIR2 */
-					pins = "GPIO10_C11", "GPIO15_A12",
-					"GPIO16_C13", "GPIO23_D15";
-					ste,output = <1>;
-				};
-				mmcsd_default_cfg3 {
-					/* MCCMD, MCDAT3-0, MCMSFBCLK */
-					pins = "GPIO9_A10", "GPIO11_B11",
-					"GPIO12_A11", "GPIO13_C12",
-					"GPIO14_B12", "GPIO24_C15";
-					ste,input = <1>;
+					/*
+					 * MCCLK, MCCMDDIR, MCDAT0DIR, MCDAT31DIR, MCDATDIR2
+					 * MCCMD, MCDAT3-0, MCMSFBCLK
+					 */
+					pins = "GPIO8_B10", "GPIO9_A10", "GPIO10_C11", "GPIO11_B11",
+					       "GPIO12_A11", "GPIO13_C12", "GPIO14_B12", "GPIO15_A12",
+					       "GPIO16_C13", "GPIO23_D15", "GPIO24_C15";
+					ste,output = <2>;
 				};
 			};
 		};
@@ -802,10 +794,21 @@
 			clock-names = "mclk", "apb_pclk";
 			interrupt-parent = <&vica>;
 			interrupts = <22>;
-			max-frequency = <48000000>;
+			max-frequency = <400000>;
 			bus-width = <4>;
 			cap-mmc-highspeed;
 			cap-sd-highspeed;
+			full-pwr-cycle;
+			/*
+			 * The STw4811 circuit used with the Nomadik strictly
+			 * requires that all of these signal direction pins be
+			 * routed and used for its 4-bit levelshifter.
+			 */
+			st,sig-dir-dat0;
+			st,sig-dir-dat2;
+			st,sig-dir-dat31;
+			st,sig-dir-cmd;
+			st,sig-pin-fbclk;
 			pinctrl-names = "default";
 			pinctrl-0 = <&mmcsd_default_mux>, <&mmcsd_default_mode>;
 			vmmc-supply = <&vmmc_regulator>;
--- zfcpdump-kernel-4.4.orig/arch/arm/boot/dts/stih407-family.dtsi
+++ zfcpdump-kernel-4.4/arch/arm/boot/dts/stih407-family.dtsi
@@ -497,8 +497,9 @@
 			interrupt-names = "mmcirq";
 			pinctrl-names = "default";
 			pinctrl-0 = <&pinctrl_mmc0>;
-			clock-names = "mmc";
-			clocks = <&clk_s_c0_flexgen CLK_MMC_0>;
+			clock-names = "mmc", "icn";
+			clocks = <&clk_s_c0_flexgen CLK_MMC_0>,
+				 <&clk_s_c0_flexgen CLK_RX_ICN_HVA>;
 			bus-width = <8>;
 			non-removable;
 		};
@@ -512,8 +513,9 @@
 			interrupt-names = "mmcirq";
 			pinctrl-names = "default";
 			pinctrl-0 = <&pinctrl_sd1>;
-			clock-names = "mmc";
-			clocks = <&clk_s_c0_flexgen CLK_MMC_1>;
+			clock-names = "mmc", "icn";
+			clocks = <&clk_s_c0_flexgen CLK_MMC_1>,
+				 <&clk_s_c0_flexgen CLK_RX_ICN_HVA>;
 			resets = <&softreset STIH407_MMC1_SOFTRESET>;
 			bus-width = <4>;
 		};
--- zfcpdump-kernel-4.4.orig/arch/arm/boot/dts/stih410.dtsi
+++ zfcpdump-kernel-4.4/arch/arm/boot/dts/stih410.dtsi
@@ -41,7 +41,8 @@
 			compatible = "st,st-ohci-300x";
 			reg = <0x9a03c00 0x100>;
 			interrupts = <GIC_SPI 180 IRQ_TYPE_NONE>;
-			clocks = <&clk_s_c0_flexgen CLK_TX_ICN_DISP_0>;
+			clocks = <&clk_s_c0_flexgen CLK_TX_ICN_DISP_0>,
+				 <&clk_s_c0_flexgen CLK_RX_ICN_DISP_0>;
 			resets = <&powerdown STIH407_USB2_PORT0_POWERDOWN>,
 				 <&softreset STIH407_USB2_PORT0_SOFTRESET>;
 			reset-names = "power", "softreset";
@@ -57,7 +58,8 @@
 			interrupts = <GIC_SPI 151 IRQ_TYPE_NONE>;
 			pinctrl-names = "default";
 			pinctrl-0 = <&pinctrl_usb0>;
-			clocks = <&clk_s_c0_flexgen CLK_TX_ICN_DISP_0>;
+			clocks = <&clk_s_c0_flexgen CLK_TX_ICN_DISP_0>,
+				 <&clk_s_c0_flexgen CLK_RX_ICN_DISP_0>;
 			resets = <&powerdown STIH407_USB2_PORT0_POWERDOWN>,
 				 <&softreset STIH407_USB2_PORT0_SOFTRESET>;
 			reset-names = "power", "softreset";
@@ -71,7 +73,8 @@
 			compatible = "st,st-ohci-300x";
 			reg = <0x9a83c00 0x100>;
 			interrupts = <GIC_SPI 181 IRQ_TYPE_NONE>;
-			clocks = <&clk_s_c0_flexgen CLK_TX_ICN_DISP_0>;
+			clocks = <&clk_s_c0_flexgen CLK_TX_ICN_DISP_0>,
+				 <&clk_s_c0_flexgen CLK_RX_ICN_DISP_0>;
 			resets = <&powerdown STIH407_USB2_PORT1_POWERDOWN>,
 				 <&softreset STIH407_USB2_PORT1_SOFTRESET>;
 			reset-names = "power", "softreset";
@@ -87,7 +90,8 @@
 			interrupts = <GIC_SPI 153 IRQ_TYPE_NONE>;
 			pinctrl-names = "default";
 			pinctrl-0 = <&pinctrl_usb1>;
-			clocks = <&clk_s_c0_flexgen CLK_TX_ICN_DISP_0>;
+			clocks = <&clk_s_c0_flexgen CLK_TX_ICN_DISP_0>,
+				 <&clk_s_c0_flexgen CLK_RX_ICN_DISP_0>;
 			resets = <&powerdown STIH407_USB2_PORT1_POWERDOWN>,
 				 <&softreset STIH407_USB2_PORT1_SOFTRESET>;
 			reset-names = "power", "softreset";
--- zfcpdump-kernel-4.4.orig/arch/arm/boot/dts/sun4i-a10-a1000.dts
+++ zfcpdump-kernel-4.4/arch/arm/boot/dts/sun4i-a10-a1000.dts
@@ -84,6 +84,7 @@
 		regulator-name = "emac-3v3";
 		regulator-min-microvolt = <3300000>;
 		regulator-max-microvolt = <3300000>;
+		startup-delay-us = <20000>;
 		enable-active-high;
 		gpio = <&pio 7 15 GPIO_ACTIVE_HIGH>;
 	};
--- zfcpdump-kernel-4.4.orig/arch/arm/boot/dts/sun4i-a10-hackberry.dts
+++ zfcpdump-kernel-4.4/arch/arm/boot/dts/sun4i-a10-hackberry.dts
@@ -66,6 +66,7 @@
 		regulator-name = "emac-3v3";
 		regulator-min-microvolt = <3300000>;
 		regulator-max-microvolt = <3300000>;
+		startup-delay-us = <20000>;
 		enable-active-high;
 		gpio = <&pio 7 19 GPIO_ACTIVE_HIGH>;
 	};
--- zfcpdump-kernel-4.4.orig/arch/arm/boot/dts/sun4i-a10-jesurun-q5.dts
+++ zfcpdump-kernel-4.4/arch/arm/boot/dts/sun4i-a10-jesurun-q5.dts
@@ -80,6 +80,7 @@
 		regulator-name = "emac-3v3";
 		regulator-min-microvolt = <3300000>;
 		regulator-max-microvolt = <3300000>;
+		startup-delay-us = <20000>;
 		enable-active-high;
 		gpio = <&pio 7 19 GPIO_ACTIVE_HIGH>;   /* PH19 */
 	};
--- zfcpdump-kernel-4.4.orig/arch/arm/boot/dts/sun5i-a10s-wobo-i5.dts
+++ zfcpdump-kernel-4.4/arch/arm/boot/dts/sun5i-a10s-wobo-i5.dts
@@ -79,6 +79,7 @@
 		regulator-name = "emac-3v3";
 		regulator-min-microvolt = <3300000>;
 		regulator-max-microvolt = <3300000>;
+		startup-delay-us = <20000>;
 		enable-active-high;
 		gpio = <&pio 0 2 GPIO_ACTIVE_HIGH>;
 	};
--- zfcpdump-kernel-4.4.orig/arch/arm/boot/dts/sun5i-a13.dtsi
+++ zfcpdump-kernel-4.4/arch/arm/boot/dts/sun5i-a13.dtsi
@@ -83,7 +83,7 @@
 			trips {
 				cpu_alert0: cpu_alert0 {
 					/* milliCelsius */
-					temperature = <850000>;
+					temperature = <85000>;
 					hysteresis = <2000>;
 					type = "passive";
 				};
--- zfcpdump-kernel-4.4.orig/arch/arm/boot/dts/sun5i-r8-chip.dts
+++ zfcpdump-kernel-4.4/arch/arm/boot/dts/sun5i-r8-chip.dts
@@ -52,7 +52,7 @@
 
 / {
 	model = "NextThing C.H.I.P.";
-	compatible = "nextthing,chip", "allwinner,sun5i-r8";
+	compatible = "nextthing,chip", "allwinner,sun5i-r8", "allwinner,sun5i-a13";
 
 	aliases {
 		i2c0 = &i2c0;
--- zfcpdump-kernel-4.4.orig/arch/arm/common/icst.c
+++ zfcpdump-kernel-4.4/arch/arm/common/icst.c
@@ -16,7 +16,7 @@
  */
 #include <linux/module.h>
 #include <linux/kernel.h>
-
+#include <asm/div64.h>
 #include <asm/hardware/icst.h>
 
 /*
@@ -29,7 +29,11 @@ EXPORT_SYMBOL(icst525_s2div);
 
 unsigned long icst_hz(const struct icst_params *p, struct icst_vco vco)
 {
-	return p->ref * 2 * (vco.v + 8) / ((vco.r + 2) * p->s2div[vco.s]);
+	u64 dividend = p->ref * 2 * (u64)(vco.v + 8);
+	u32 divisor = (vco.r + 2) * p->s2div[vco.s];
+
+	do_div(dividend, divisor);
+	return (unsigned long)dividend;
 }
 
 EXPORT_SYMBOL(icst_hz);
@@ -58,6 +62,7 @@ icst_hz_to_vco(const struct icst_params
 
 		if (f > p->vco_min && f <= p->vco_max)
 			break;
+		i++;
 	} while (i < 8);
 
 	if (i >= 8)
--- zfcpdump-kernel-4.4.orig/arch/arm/common/sa1111.c
+++ zfcpdump-kernel-4.4/arch/arm/common/sa1111.c
@@ -869,9 +869,9 @@ struct sa1111_save_data {
 
 #ifdef CONFIG_PM
 
-static int sa1111_suspend(struct platform_device *dev, pm_message_t state)
+static int sa1111_suspend_noirq(struct device *dev)
 {
-	struct sa1111 *sachip = platform_get_drvdata(dev);
+	struct sa1111 *sachip = dev_get_drvdata(dev);
 	struct sa1111_save_data *save;
 	unsigned long flags;
 	unsigned int val;
@@ -934,9 +934,9 @@ static int sa1111_suspend(struct platfor
  *	restored by their respective drivers, and must be called
  *	via LDM after this function.
  */
-static int sa1111_resume(struct platform_device *dev)
+static int sa1111_resume_noirq(struct device *dev)
 {
-	struct sa1111 *sachip = platform_get_drvdata(dev);
+	struct sa1111 *sachip = dev_get_drvdata(dev);
 	struct sa1111_save_data *save;
 	unsigned long flags, id;
 	void __iomem *base;
@@ -952,7 +952,7 @@ static int sa1111_resume(struct platform
 	id = sa1111_readl(sachip->base + SA1111_SKID);
 	if ((id & SKID_ID_MASK) != SKID_SA1111_ID) {
 		__sa1111_remove(sachip);
-		platform_set_drvdata(dev, NULL);
+		dev_set_drvdata(dev, NULL);
 		kfree(save);
 		return 0;
 	}
@@ -1003,8 +1003,8 @@ static int sa1111_resume(struct platform
 }
 
 #else
-#define sa1111_suspend NULL
-#define sa1111_resume  NULL
+#define sa1111_suspend_noirq NULL
+#define sa1111_resume_noirq  NULL
 #endif
 
 static int sa1111_probe(struct platform_device *pdev)
@@ -1038,6 +1038,11 @@ static int sa1111_remove(struct platform
 	return 0;
 }
 
+static struct dev_pm_ops sa1111_pm_ops = {
+	.suspend_noirq = sa1111_suspend_noirq,
+	.resume_noirq = sa1111_resume_noirq,
+};
+
 /*
  *	Not sure if this should be on the system bus or not yet.
  *	We really want some way to register a system device at
@@ -1050,10 +1055,9 @@ static int sa1111_remove(struct platform
 static struct platform_driver sa1111_device_driver = {
 	.probe		= sa1111_probe,
 	.remove		= sa1111_remove,
-	.suspend	= sa1111_suspend,
-	.resume		= sa1111_resume,
 	.driver		= {
 		.name	= "sa1111",
+		.pm	= &sa1111_pm_ops,
 	},
 };
 
--- zfcpdump-kernel-4.4.orig/arch/arm/crypto/aes-ce-glue.c
+++ zfcpdump-kernel-4.4/arch/arm/crypto/aes-ce-glue.c
@@ -15,6 +15,7 @@
 #include <crypto/ablk_helper.h>
 #include <crypto/algapi.h>
 #include <linux/module.h>
+#include <crypto/xts.h>
 
 MODULE_DESCRIPTION("AES-ECB/CBC/CTR/XTS using ARMv8 Crypto Extensions");
 MODULE_AUTHOR("Ard Biesheuvel <ard.biesheuvel@linaro.org>");
@@ -152,6 +153,10 @@ static int xts_set_key(struct crypto_tfm
 	struct crypto_aes_xts_ctx *ctx = crypto_tfm_ctx(tfm);
 	int ret;
 
+	ret = xts_check_key(tfm, in_key, key_len);
+	if (ret)
+		return ret;
+
 	ret = ce_aes_expandkey(&ctx->key1, in_key, key_len / 2);
 	if (!ret)
 		ret = ce_aes_expandkey(&ctx->key2, &in_key[key_len / 2],
@@ -279,7 +284,7 @@ static int ctr_encrypt(struct blkcipher_
 		err = blkcipher_walk_done(desc, &walk,
 					  walk.nbytes % AES_BLOCK_SIZE);
 	}
-	if (nbytes) {
+	if (walk.nbytes % AES_BLOCK_SIZE) {
 		u8 *tdst = walk.dst.virt.addr + blocks * AES_BLOCK_SIZE;
 		u8 *tsrc = walk.src.virt.addr + blocks * AES_BLOCK_SIZE;
 		u8 __aligned(8) tail[AES_BLOCK_SIZE];
--- zfcpdump-kernel-4.4.orig/arch/arm/crypto/aesbs-glue.c
+++ zfcpdump-kernel-4.4/arch/arm/crypto/aesbs-glue.c
@@ -13,6 +13,7 @@
 #include <crypto/ablk_helper.h>
 #include <crypto/algapi.h>
 #include <linux/module.h>
+#include <crypto/xts.h>
 
 #include "aes_glue.h"
 
@@ -89,6 +90,11 @@ static int aesbs_xts_set_key(struct cryp
 {
 	struct aesbs_xts_ctx *ctx = crypto_tfm_ctx(tfm);
 	int bits = key_len * 4;
+	int err;
+
+	err = xts_check_key(tfm, in_key, key_len);
+	if (err)
+		return err;
 
 	if (private_AES_set_encrypt_key(in_key, bits, &ctx->enc.rk)) {
 		tfm->crt_flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
--- zfcpdump-kernel-4.4.orig/arch/arm/include/asm/dma-mapping.h
+++ zfcpdump-kernel-4.4/arch/arm/include/asm/dma-mapping.h
@@ -119,7 +119,7 @@ static inline dma_addr_t virt_to_dma(str
 /* The ARM override for dma_max_pfn() */
 static inline unsigned long dma_max_pfn(struct device *dev)
 {
-	return PHYS_PFN_OFFSET + dma_to_pfn(dev, *dev->dma_mask);
+	return dma_to_pfn(dev, *dev->dma_mask);
 }
 #define dma_max_pfn(dev) dma_max_pfn(dev)
 
--- zfcpdump-kernel-4.4.orig/arch/arm/include/asm/pgtable-2level.h
+++ zfcpdump-kernel-4.4/arch/arm/include/asm/pgtable-2level.h
@@ -193,6 +193,7 @@ static inline pmd_t *pmd_offset(pud_t *p
 
 #define pmd_large(pmd)		(pmd_val(pmd) & 2)
 #define pmd_bad(pmd)		(pmd_val(pmd) & 2)
+#define pmd_present(pmd)	(pmd_val(pmd))
 
 #define copy_pmd(pmdpd,pmdps)		\
 	do {				\
--- zfcpdump-kernel-4.4.orig/arch/arm/include/asm/pgtable-3level.h
+++ zfcpdump-kernel-4.4/arch/arm/include/asm/pgtable-3level.h
@@ -212,6 +212,7 @@ static inline pmd_t *pmd_offset(pud_t *p
 						: !!(pmd_val(pmd) & (val)))
 #define pmd_isclear(pmd, val)	(!(pmd_val(pmd) & (val)))
 
+#define pmd_present(pmd)	(pmd_isset((pmd), L_PMD_SECT_VALID))
 #define pmd_young(pmd)		(pmd_isset((pmd), PMD_SECT_AF))
 #define pte_special(pte)	(pte_isset((pte), L_PTE_SPECIAL))
 static inline pte_t pte_mkspecial(pte_t pte)
@@ -257,10 +258,10 @@ PMD_BIT_FUNC(mkyoung,   |= PMD_SECT_AF);
 #define pfn_pmd(pfn,prot)	(__pmd(((phys_addr_t)(pfn) << PAGE_SHIFT) | pgprot_val(prot)))
 #define mk_pmd(page,prot)	pfn_pmd(page_to_pfn(page),prot)
 
-/* represent a notpresent pmd by zero, this is used by pmdp_invalidate */
+/* represent a notpresent pmd by faulting entry, this is used by pmdp_invalidate */
 static inline pmd_t pmd_mknotpresent(pmd_t pmd)
 {
-	return __pmd(0);
+	return __pmd(pmd_val(pmd) & ~L_PMD_SECT_VALID);
 }
 
 static inline pmd_t pmd_modify(pmd_t pmd, pgprot_t newprot)
--- zfcpdump-kernel-4.4.orig/arch/arm/include/asm/pgtable.h
+++ zfcpdump-kernel-4.4/arch/arm/include/asm/pgtable.h
@@ -182,7 +182,6 @@ extern pgd_t swapper_pg_dir[PTRS_PER_PGD
 #define pgd_offset_k(addr)	pgd_offset(&init_mm, addr)
 
 #define pmd_none(pmd)		(!pmd_val(pmd))
-#define pmd_present(pmd)	(pmd_val(pmd))
 
 static inline pte_t *pmd_page_vaddr(pmd_t pmd)
 {
--- zfcpdump-kernel-4.4.orig/arch/arm/include/asm/psci.h
+++ zfcpdump-kernel-4.4/arch/arm/include/asm/psci.h
@@ -16,7 +16,7 @@
 
 extern struct smp_operations psci_smp_ops;
 
-#ifdef CONFIG_ARM_PSCI
+#if defined(CONFIG_SMP) && defined(CONFIG_ARM_PSCI)
 bool psci_smp_available(void);
 #else
 static inline bool psci_smp_available(void) { return false; }
--- zfcpdump-kernel-4.4.orig/arch/arm/include/asm/xen/page-coherent.h
+++ zfcpdump-kernel-4.4/arch/arm/include/asm/xen/page-coherent.h
@@ -35,14 +35,21 @@ static inline void xen_dma_map_page(stru
 	     dma_addr_t dev_addr, unsigned long offset, size_t size,
 	     enum dma_data_direction dir, struct dma_attrs *attrs)
 {
-	bool local = XEN_PFN_DOWN(dev_addr) == page_to_xen_pfn(page);
+	unsigned long page_pfn = page_to_xen_pfn(page);
+	unsigned long dev_pfn = XEN_PFN_DOWN(dev_addr);
+	unsigned long compound_pages =
+		(1<<compound_order(page)) * XEN_PFN_PER_PAGE;
+	bool local = (page_pfn <= dev_pfn) &&
+		(dev_pfn - page_pfn < compound_pages);
+
 	/*
-	 * Dom0 is mapped 1:1, while the Linux page can be spanned accross
-	 * multiple Xen page, it's not possible to have a mix of local and
-	 * foreign Xen page. So if the first xen_pfn == mfn the page is local
-	 * otherwise it's a foreign page grant-mapped in dom0. If the page is
-	 * local we can safely call the native dma_ops function, otherwise we
-	 * call the xen specific function.
+	 * Dom0 is mapped 1:1, while the Linux page can span across
+	 * multiple Xen pages, it's not possible for it to contain a
+	 * mix of local and foreign Xen pages. So if the first xen_pfn
+	 * == mfn the page is local otherwise it's a foreign page
+	 * grant-mapped in dom0. If the page is local we can safely
+	 * call the native dma_ops function, otherwise we call the xen
+	 * specific function.
 	 */
 	if (local)
 		__generic_dma_ops(hwdev)->map_page(hwdev, page, offset, size, dir, attrs);
--- zfcpdump-kernel-4.4.orig/arch/arm/kernel/devtree.c
+++ zfcpdump-kernel-4.4/arch/arm/kernel/devtree.c
@@ -87,6 +87,8 @@ void __init arm_dt_init_cpu_maps(void)
 		return;
 
 	for_each_child_of_node(cpus, cpu) {
+		const __be32 *cell;
+		int prop_bytes;
 		u32 hwid;
 
 		if (of_node_cmp(cpu->type, "cpu"))
@@ -98,7 +100,8 @@ void __init arm_dt_init_cpu_maps(void)
 		 * properties is considered invalid to build the
 		 * cpu_logical_map.
 		 */
-		if (of_property_read_u32(cpu, "reg", &hwid)) {
+		cell = of_get_property(cpu, "reg", &prop_bytes);
+		if (!cell || prop_bytes < sizeof(*cell)) {
 			pr_debug(" * %s missing reg property\n",
 				     cpu->full_name);
 			of_node_put(cpu);
@@ -106,10 +109,15 @@ void __init arm_dt_init_cpu_maps(void)
 		}
 
 		/*
-		 * 8 MSBs must be set to 0 in the DT since the reg property
+		 * Bits n:24 must be set to 0 in the DT since the reg property
 		 * defines the MPIDR[23:0].
 		 */
-		if (hwid & ~MPIDR_HWID_BITMASK) {
+		do {
+			hwid = be32_to_cpu(*cell++);
+			prop_bytes -= sizeof(*cell);
+		} while (!hwid && prop_bytes > 0);
+
+		if (prop_bytes || (hwid & ~MPIDR_HWID_BITMASK)) {
 			of_node_put(cpu);
 			return;
 		}
--- zfcpdump-kernel-4.4.orig/arch/arm/kernel/module-plts.c
+++ zfcpdump-kernel-4.4/arch/arm/kernel/module-plts.c
@@ -32,7 +32,7 @@ struct plt_entries {
 
 static bool in_init(const struct module *mod, u32 addr)
 {
-	return addr - (u32)mod->module_init < mod->init_size;
+	return addr - (u32)mod->init_layout.base < mod->init_layout.size;
 }
 
 u32 get_module_plt(struct module *mod, unsigned long loc, Elf32_Addr val)
--- zfcpdump-kernel-4.4.orig/arch/arm/kernel/perf_event_v7.c
+++ zfcpdump-kernel-4.4/arch/arm/kernel/perf_event_v7.c
@@ -35,133 +35,117 @@
  * but the encodings are considered to be `reserved' in the case that
  * they are not available.
  */
-enum armv7_perf_types {
-	ARMV7_PERFCTR_PMNC_SW_INCR			= 0x00,
-	ARMV7_PERFCTR_L1_ICACHE_REFILL			= 0x01,
-	ARMV7_PERFCTR_ITLB_REFILL			= 0x02,
-	ARMV7_PERFCTR_L1_DCACHE_REFILL			= 0x03,
-	ARMV7_PERFCTR_L1_DCACHE_ACCESS			= 0x04,
-	ARMV7_PERFCTR_DTLB_REFILL			= 0x05,
-	ARMV7_PERFCTR_MEM_READ				= 0x06,
-	ARMV7_PERFCTR_MEM_WRITE				= 0x07,
-	ARMV7_PERFCTR_INSTR_EXECUTED			= 0x08,
-	ARMV7_PERFCTR_EXC_TAKEN				= 0x09,
-	ARMV7_PERFCTR_EXC_EXECUTED			= 0x0A,
-	ARMV7_PERFCTR_CID_WRITE				= 0x0B,
-
-	/*
-	 * ARMV7_PERFCTR_PC_WRITE is equivalent to HW_BRANCH_INSTRUCTIONS.
-	 * It counts:
-	 *  - all (taken) branch instructions,
-	 *  - instructions that explicitly write the PC,
-	 *  - exception generating instructions.
-	 */
-	ARMV7_PERFCTR_PC_WRITE				= 0x0C,
-	ARMV7_PERFCTR_PC_IMM_BRANCH			= 0x0D,
-	ARMV7_PERFCTR_PC_PROC_RETURN			= 0x0E,
-	ARMV7_PERFCTR_MEM_UNALIGNED_ACCESS		= 0x0F,
-	ARMV7_PERFCTR_PC_BRANCH_MIS_PRED		= 0x10,
-	ARMV7_PERFCTR_CLOCK_CYCLES			= 0x11,
-	ARMV7_PERFCTR_PC_BRANCH_PRED			= 0x12,
-
-	/* These events are defined by the PMUv2 supplement (ARM DDI 0457A). */
-	ARMV7_PERFCTR_MEM_ACCESS			= 0x13,
-	ARMV7_PERFCTR_L1_ICACHE_ACCESS			= 0x14,
-	ARMV7_PERFCTR_L1_DCACHE_WB			= 0x15,
-	ARMV7_PERFCTR_L2_CACHE_ACCESS			= 0x16,
-	ARMV7_PERFCTR_L2_CACHE_REFILL			= 0x17,
-	ARMV7_PERFCTR_L2_CACHE_WB			= 0x18,
-	ARMV7_PERFCTR_BUS_ACCESS			= 0x19,
-	ARMV7_PERFCTR_MEM_ERROR				= 0x1A,
-	ARMV7_PERFCTR_INSTR_SPEC			= 0x1B,
-	ARMV7_PERFCTR_TTBR_WRITE			= 0x1C,
-	ARMV7_PERFCTR_BUS_CYCLES			= 0x1D,
+#define ARMV7_PERFCTR_PMNC_SW_INCR			0x00
+#define ARMV7_PERFCTR_L1_ICACHE_REFILL			0x01
+#define ARMV7_PERFCTR_ITLB_REFILL			0x02
+#define ARMV7_PERFCTR_L1_DCACHE_REFILL			0x03
+#define ARMV7_PERFCTR_L1_DCACHE_ACCESS			0x04
+#define ARMV7_PERFCTR_DTLB_REFILL			0x05
+#define ARMV7_PERFCTR_MEM_READ				0x06
+#define ARMV7_PERFCTR_MEM_WRITE				0x07
+#define ARMV7_PERFCTR_INSTR_EXECUTED			0x08
+#define ARMV7_PERFCTR_EXC_TAKEN				0x09
+#define ARMV7_PERFCTR_EXC_EXECUTED			0x0A
+#define ARMV7_PERFCTR_CID_WRITE				0x0B
 
-	ARMV7_PERFCTR_CPU_CYCLES			= 0xFF
-};
+/*
+ * ARMV7_PERFCTR_PC_WRITE is equivalent to HW_BRANCH_INSTRUCTIONS.
+ * It counts:
+ *  - all (taken) branch instructions,
+ *  - instructions that explicitly write the PC,
+ *  - exception generating instructions.
+ */
+#define ARMV7_PERFCTR_PC_WRITE				0x0C
+#define ARMV7_PERFCTR_PC_IMM_BRANCH			0x0D
+#define ARMV7_PERFCTR_PC_PROC_RETURN			0x0E
+#define ARMV7_PERFCTR_MEM_UNALIGNED_ACCESS		0x0F
+#define ARMV7_PERFCTR_PC_BRANCH_MIS_PRED		0x10
+#define ARMV7_PERFCTR_CLOCK_CYCLES			0x11
+#define ARMV7_PERFCTR_PC_BRANCH_PRED			0x12
+
+/* These events are defined by the PMUv2 supplement (ARM DDI 0457A). */
+#define ARMV7_PERFCTR_MEM_ACCESS			0x13
+#define ARMV7_PERFCTR_L1_ICACHE_ACCESS			0x14
+#define ARMV7_PERFCTR_L1_DCACHE_WB			0x15
+#define ARMV7_PERFCTR_L2_CACHE_ACCESS			0x16
+#define ARMV7_PERFCTR_L2_CACHE_REFILL			0x17
+#define ARMV7_PERFCTR_L2_CACHE_WB			0x18
+#define ARMV7_PERFCTR_BUS_ACCESS			0x19
+#define ARMV7_PERFCTR_MEM_ERROR				0x1A
+#define ARMV7_PERFCTR_INSTR_SPEC			0x1B
+#define ARMV7_PERFCTR_TTBR_WRITE			0x1C
+#define ARMV7_PERFCTR_BUS_CYCLES			0x1D
+
+#define ARMV7_PERFCTR_CPU_CYCLES			0xFF
 
 /* ARMv7 Cortex-A8 specific event types */
-enum armv7_a8_perf_types {
-	ARMV7_A8_PERFCTR_L2_CACHE_ACCESS		= 0x43,
-	ARMV7_A8_PERFCTR_L2_CACHE_REFILL		= 0x44,
-	ARMV7_A8_PERFCTR_L1_ICACHE_ACCESS		= 0x50,
-	ARMV7_A8_PERFCTR_STALL_ISIDE			= 0x56,
-};
+#define ARMV7_A8_PERFCTR_L2_CACHE_ACCESS		0x43
+#define ARMV7_A8_PERFCTR_L2_CACHE_REFILL		0x44
+#define ARMV7_A8_PERFCTR_L1_ICACHE_ACCESS		0x50
+#define ARMV7_A8_PERFCTR_STALL_ISIDE			0x56
 
 /* ARMv7 Cortex-A9 specific event types */
-enum armv7_a9_perf_types {
-	ARMV7_A9_PERFCTR_INSTR_CORE_RENAME		= 0x68,
-	ARMV7_A9_PERFCTR_STALL_ICACHE			= 0x60,
-	ARMV7_A9_PERFCTR_STALL_DISPATCH			= 0x66,
-};
+#define ARMV7_A9_PERFCTR_INSTR_CORE_RENAME		0x68
+#define ARMV7_A9_PERFCTR_STALL_ICACHE			0x60
+#define ARMV7_A9_PERFCTR_STALL_DISPATCH			0x66
 
 /* ARMv7 Cortex-A5 specific event types */
-enum armv7_a5_perf_types {
-	ARMV7_A5_PERFCTR_PREFETCH_LINEFILL		= 0xc2,
-	ARMV7_A5_PERFCTR_PREFETCH_LINEFILL_DROP		= 0xc3,
-};
+#define ARMV7_A5_PERFCTR_PREFETCH_LINEFILL		0xc2
+#define ARMV7_A5_PERFCTR_PREFETCH_LINEFILL_DROP		0xc3
 
 /* ARMv7 Cortex-A15 specific event types */
-enum armv7_a15_perf_types {
-	ARMV7_A15_PERFCTR_L1_DCACHE_ACCESS_READ		= 0x40,
-	ARMV7_A15_PERFCTR_L1_DCACHE_ACCESS_WRITE	= 0x41,
-	ARMV7_A15_PERFCTR_L1_DCACHE_REFILL_READ		= 0x42,
-	ARMV7_A15_PERFCTR_L1_DCACHE_REFILL_WRITE	= 0x43,
-
-	ARMV7_A15_PERFCTR_DTLB_REFILL_L1_READ		= 0x4C,
-	ARMV7_A15_PERFCTR_DTLB_REFILL_L1_WRITE		= 0x4D,
-
-	ARMV7_A15_PERFCTR_L2_CACHE_ACCESS_READ		= 0x50,
-	ARMV7_A15_PERFCTR_L2_CACHE_ACCESS_WRITE		= 0x51,
-	ARMV7_A15_PERFCTR_L2_CACHE_REFILL_READ		= 0x52,
-	ARMV7_A15_PERFCTR_L2_CACHE_REFILL_WRITE		= 0x53,
+#define ARMV7_A15_PERFCTR_L1_DCACHE_ACCESS_READ		0x40
+#define ARMV7_A15_PERFCTR_L1_DCACHE_ACCESS_WRITE	0x41
+#define ARMV7_A15_PERFCTR_L1_DCACHE_REFILL_READ		0x42
+#define ARMV7_A15_PERFCTR_L1_DCACHE_REFILL_WRITE	0x43
+
+#define ARMV7_A15_PERFCTR_DTLB_REFILL_L1_READ		0x4C
+#define ARMV7_A15_PERFCTR_DTLB_REFILL_L1_WRITE		0x4D
+
+#define ARMV7_A15_PERFCTR_L2_CACHE_ACCESS_READ		0x50
+#define ARMV7_A15_PERFCTR_L2_CACHE_ACCESS_WRITE		0x51
+#define ARMV7_A15_PERFCTR_L2_CACHE_REFILL_READ		0x52
+#define ARMV7_A15_PERFCTR_L2_CACHE_REFILL_WRITE		0x53
 
-	ARMV7_A15_PERFCTR_PC_WRITE_SPEC			= 0x76,
-};
+#define ARMV7_A15_PERFCTR_PC_WRITE_SPEC			0x76
 
 /* ARMv7 Cortex-A12 specific event types */
-enum armv7_a12_perf_types {
-	ARMV7_A12_PERFCTR_L1_DCACHE_ACCESS_READ		= 0x40,
-	ARMV7_A12_PERFCTR_L1_DCACHE_ACCESS_WRITE	= 0x41,
+#define ARMV7_A12_PERFCTR_L1_DCACHE_ACCESS_READ		0x40
+#define ARMV7_A12_PERFCTR_L1_DCACHE_ACCESS_WRITE	0x41
 
-	ARMV7_A12_PERFCTR_L2_CACHE_ACCESS_READ		= 0x50,
-	ARMV7_A12_PERFCTR_L2_CACHE_ACCESS_WRITE		= 0x51,
+#define ARMV7_A12_PERFCTR_L2_CACHE_ACCESS_READ		0x50
+#define ARMV7_A12_PERFCTR_L2_CACHE_ACCESS_WRITE		0x51
 
-	ARMV7_A12_PERFCTR_PC_WRITE_SPEC			= 0x76,
+#define ARMV7_A12_PERFCTR_PC_WRITE_SPEC			0x76
 
-	ARMV7_A12_PERFCTR_PF_TLB_REFILL			= 0xe7,
-};
+#define ARMV7_A12_PERFCTR_PF_TLB_REFILL			0xe7
 
 /* ARMv7 Krait specific event types */
-enum krait_perf_types {
-	KRAIT_PMRESR0_GROUP0				= 0xcc,
-	KRAIT_PMRESR1_GROUP0				= 0xd0,
-	KRAIT_PMRESR2_GROUP0				= 0xd4,
-	KRAIT_VPMRESR0_GROUP0				= 0xd8,
+#define KRAIT_PMRESR0_GROUP0				0xcc
+#define KRAIT_PMRESR1_GROUP0				0xd0
+#define KRAIT_PMRESR2_GROUP0				0xd4
+#define KRAIT_VPMRESR0_GROUP0				0xd8
 
-	KRAIT_PERFCTR_L1_ICACHE_ACCESS			= 0x10011,
-	KRAIT_PERFCTR_L1_ICACHE_MISS			= 0x10010,
+#define KRAIT_PERFCTR_L1_ICACHE_ACCESS			0x10011
+#define KRAIT_PERFCTR_L1_ICACHE_MISS			0x10010
 
-	KRAIT_PERFCTR_L1_ITLB_ACCESS			= 0x12222,
-	KRAIT_PERFCTR_L1_DTLB_ACCESS			= 0x12210,
-};
+#define KRAIT_PERFCTR_L1_ITLB_ACCESS			0x12222
+#define KRAIT_PERFCTR_L1_DTLB_ACCESS			0x12210
 
 /* ARMv7 Scorpion specific event types */
-enum scorpion_perf_types {
-	SCORPION_LPM0_GROUP0				= 0x4c,
-	SCORPION_LPM1_GROUP0				= 0x50,
-	SCORPION_LPM2_GROUP0				= 0x54,
-	SCORPION_L2LPM_GROUP0				= 0x58,
-	SCORPION_VLPM_GROUP0				= 0x5c,
+#define SCORPION_LPM0_GROUP0				0x4c
+#define SCORPION_LPM1_GROUP0				0x50
+#define SCORPION_LPM2_GROUP0				0x54
+#define SCORPION_L2LPM_GROUP0				0x58
+#define SCORPION_VLPM_GROUP0				0x5c
 
-	SCORPION_ICACHE_ACCESS				= 0x10053,
-	SCORPION_ICACHE_MISS				= 0x10052,
+#define SCORPION_ICACHE_ACCESS				0x10053
+#define SCORPION_ICACHE_MISS				0x10052
 
-	SCORPION_DTLB_ACCESS				= 0x12013,
-	SCORPION_DTLB_MISS				= 0x12012,
+#define SCORPION_DTLB_ACCESS				0x12013
+#define SCORPION_DTLB_MISS				0x12012
 
-	SCORPION_ITLB_MISS				= 0x12021,
-};
+#define SCORPION_ITLB_MISS				0x12021
 
 /*
  * Cortex-A8 HW events mapping
@@ -547,6 +531,134 @@ static const unsigned scorpion_perf_cach
 	[C(BPU)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
 };
 
+PMU_FORMAT_ATTR(event, "config:0-7");
+
+static struct attribute *armv7_pmu_format_attrs[] = {
+	&format_attr_event.attr,
+	NULL,
+};
+
+static struct attribute_group armv7_pmu_format_attr_group = {
+	.name = "format",
+	.attrs = armv7_pmu_format_attrs,
+};
+
+#define ARMV7_EVENT_ATTR_RESOLVE(m) #m
+#define ARMV7_EVENT_ATTR(name, config) \
+	PMU_EVENT_ATTR_STRING(name, armv7_event_attr_##name, \
+			      "event=" ARMV7_EVENT_ATTR_RESOLVE(config))
+
+ARMV7_EVENT_ATTR(sw_incr, ARMV7_PERFCTR_PMNC_SW_INCR);
+ARMV7_EVENT_ATTR(l1i_cache_refill, ARMV7_PERFCTR_L1_ICACHE_REFILL);
+ARMV7_EVENT_ATTR(l1i_tlb_refill, ARMV7_PERFCTR_ITLB_REFILL);
+ARMV7_EVENT_ATTR(l1d_cache_refill, ARMV7_PERFCTR_L1_DCACHE_REFILL);
+ARMV7_EVENT_ATTR(l1d_cache, ARMV7_PERFCTR_L1_DCACHE_ACCESS);
+ARMV7_EVENT_ATTR(l1d_tlb_refill, ARMV7_PERFCTR_DTLB_REFILL);
+ARMV7_EVENT_ATTR(ld_retired, ARMV7_PERFCTR_MEM_READ);
+ARMV7_EVENT_ATTR(st_retired, ARMV7_PERFCTR_MEM_WRITE);
+ARMV7_EVENT_ATTR(inst_retired, ARMV7_PERFCTR_INSTR_EXECUTED);
+ARMV7_EVENT_ATTR(exc_taken, ARMV7_PERFCTR_EXC_TAKEN);
+ARMV7_EVENT_ATTR(exc_return, ARMV7_PERFCTR_EXC_EXECUTED);
+ARMV7_EVENT_ATTR(cid_write_retired, ARMV7_PERFCTR_CID_WRITE);
+ARMV7_EVENT_ATTR(pc_write_retired, ARMV7_PERFCTR_PC_WRITE);
+ARMV7_EVENT_ATTR(br_immed_retired, ARMV7_PERFCTR_PC_IMM_BRANCH);
+ARMV7_EVENT_ATTR(br_return_retired, ARMV7_PERFCTR_PC_PROC_RETURN);
+ARMV7_EVENT_ATTR(unaligned_ldst_retired, ARMV7_PERFCTR_MEM_UNALIGNED_ACCESS);
+ARMV7_EVENT_ATTR(br_mis_pred, ARMV7_PERFCTR_PC_BRANCH_MIS_PRED);
+ARMV7_EVENT_ATTR(cpu_cycles, ARMV7_PERFCTR_CLOCK_CYCLES);
+ARMV7_EVENT_ATTR(br_pred, ARMV7_PERFCTR_PC_BRANCH_PRED);
+
+static struct attribute *armv7_pmuv1_event_attrs[] = {
+	&armv7_event_attr_sw_incr.attr.attr,
+	&armv7_event_attr_l1i_cache_refill.attr.attr,
+	&armv7_event_attr_l1i_tlb_refill.attr.attr,
+	&armv7_event_attr_l1d_cache_refill.attr.attr,
+	&armv7_event_attr_l1d_cache.attr.attr,
+	&armv7_event_attr_l1d_tlb_refill.attr.attr,
+	&armv7_event_attr_ld_retired.attr.attr,
+	&armv7_event_attr_st_retired.attr.attr,
+	&armv7_event_attr_inst_retired.attr.attr,
+	&armv7_event_attr_exc_taken.attr.attr,
+	&armv7_event_attr_exc_return.attr.attr,
+	&armv7_event_attr_cid_write_retired.attr.attr,
+	&armv7_event_attr_pc_write_retired.attr.attr,
+	&armv7_event_attr_br_immed_retired.attr.attr,
+	&armv7_event_attr_br_return_retired.attr.attr,
+	&armv7_event_attr_unaligned_ldst_retired.attr.attr,
+	&armv7_event_attr_br_mis_pred.attr.attr,
+	&armv7_event_attr_cpu_cycles.attr.attr,
+	&armv7_event_attr_br_pred.attr.attr,
+	NULL,
+};
+
+static struct attribute_group armv7_pmuv1_events_attr_group = {
+	.name = "events",
+	.attrs = armv7_pmuv1_event_attrs,
+};
+
+static const struct attribute_group *armv7_pmuv1_attr_groups[] = {
+	&armv7_pmuv1_events_attr_group,
+	&armv7_pmu_format_attr_group,
+	NULL,
+};
+
+ARMV7_EVENT_ATTR(mem_access, ARMV7_PERFCTR_MEM_ACCESS);
+ARMV7_EVENT_ATTR(l1i_cache, ARMV7_PERFCTR_L1_ICACHE_ACCESS);
+ARMV7_EVENT_ATTR(l1d_cache_wb, ARMV7_PERFCTR_L1_DCACHE_WB);
+ARMV7_EVENT_ATTR(l2d_cache, ARMV7_PERFCTR_L2_CACHE_ACCESS);
+ARMV7_EVENT_ATTR(l2d_cache_refill, ARMV7_PERFCTR_L2_CACHE_REFILL);
+ARMV7_EVENT_ATTR(l2d_cache_wb, ARMV7_PERFCTR_L2_CACHE_WB);
+ARMV7_EVENT_ATTR(bus_access, ARMV7_PERFCTR_BUS_ACCESS);
+ARMV7_EVENT_ATTR(memory_error, ARMV7_PERFCTR_MEM_ERROR);
+ARMV7_EVENT_ATTR(inst_spec, ARMV7_PERFCTR_INSTR_SPEC);
+ARMV7_EVENT_ATTR(ttbr_write_retired, ARMV7_PERFCTR_TTBR_WRITE);
+ARMV7_EVENT_ATTR(bus_cycles, ARMV7_PERFCTR_BUS_CYCLES);
+
+static struct attribute *armv7_pmuv2_event_attrs[] = {
+	&armv7_event_attr_sw_incr.attr.attr,
+	&armv7_event_attr_l1i_cache_refill.attr.attr,
+	&armv7_event_attr_l1i_tlb_refill.attr.attr,
+	&armv7_event_attr_l1d_cache_refill.attr.attr,
+	&armv7_event_attr_l1d_cache.attr.attr,
+	&armv7_event_attr_l1d_tlb_refill.attr.attr,
+	&armv7_event_attr_ld_retired.attr.attr,
+	&armv7_event_attr_st_retired.attr.attr,
+	&armv7_event_attr_inst_retired.attr.attr,
+	&armv7_event_attr_exc_taken.attr.attr,
+	&armv7_event_attr_exc_return.attr.attr,
+	&armv7_event_attr_cid_write_retired.attr.attr,
+	&armv7_event_attr_pc_write_retired.attr.attr,
+	&armv7_event_attr_br_immed_retired.attr.attr,
+	&armv7_event_attr_br_return_retired.attr.attr,
+	&armv7_event_attr_unaligned_ldst_retired.attr.attr,
+	&armv7_event_attr_br_mis_pred.attr.attr,
+	&armv7_event_attr_cpu_cycles.attr.attr,
+	&armv7_event_attr_br_pred.attr.attr,
+	&armv7_event_attr_mem_access.attr.attr,
+	&armv7_event_attr_l1i_cache.attr.attr,
+	&armv7_event_attr_l1d_cache_wb.attr.attr,
+	&armv7_event_attr_l2d_cache.attr.attr,
+	&armv7_event_attr_l2d_cache_refill.attr.attr,
+	&armv7_event_attr_l2d_cache_wb.attr.attr,
+	&armv7_event_attr_bus_access.attr.attr,
+	&armv7_event_attr_memory_error.attr.attr,
+	&armv7_event_attr_inst_spec.attr.attr,
+	&armv7_event_attr_ttbr_write_retired.attr.attr,
+	&armv7_event_attr_bus_cycles.attr.attr,
+	NULL,
+};
+
+static struct attribute_group armv7_pmuv2_events_attr_group = {
+	.name = "events",
+	.attrs = armv7_pmuv2_event_attrs,
+};
+
+static const struct attribute_group *armv7_pmuv2_attr_groups[] = {
+	&armv7_pmuv2_events_attr_group,
+	&armv7_pmu_format_attr_group,
+	NULL,
+};
+
 /*
  * Perf Events' indices
  */
@@ -1085,6 +1197,7 @@ static int armv7_a8_pmu_init(struct arm_
 	armv7pmu_init(cpu_pmu);
 	cpu_pmu->name		= "armv7_cortex_a8";
 	cpu_pmu->map_event	= armv7_a8_map_event;
+	cpu_pmu->pmu.attr_groups = armv7_pmuv1_attr_groups;
 	return armv7_probe_num_events(cpu_pmu);
 }
 
@@ -1093,6 +1206,7 @@ static int armv7_a9_pmu_init(struct arm_
 	armv7pmu_init(cpu_pmu);
 	cpu_pmu->name		= "armv7_cortex_a9";
 	cpu_pmu->map_event	= armv7_a9_map_event;
+	cpu_pmu->pmu.attr_groups = armv7_pmuv1_attr_groups;
 	return armv7_probe_num_events(cpu_pmu);
 }
 
@@ -1101,6 +1215,7 @@ static int armv7_a5_pmu_init(struct arm_
 	armv7pmu_init(cpu_pmu);
 	cpu_pmu->name		= "armv7_cortex_a5";
 	cpu_pmu->map_event	= armv7_a5_map_event;
+	cpu_pmu->pmu.attr_groups = armv7_pmuv1_attr_groups;
 	return armv7_probe_num_events(cpu_pmu);
 }
 
@@ -1110,6 +1225,7 @@ static int armv7_a15_pmu_init(struct arm
 	cpu_pmu->name		= "armv7_cortex_a15";
 	cpu_pmu->map_event	= armv7_a15_map_event;
 	cpu_pmu->set_event_filter = armv7pmu_set_event_filter;
+	cpu_pmu->pmu.attr_groups = armv7_pmuv2_attr_groups;
 	return armv7_probe_num_events(cpu_pmu);
 }
 
@@ -1119,6 +1235,7 @@ static int armv7_a7_pmu_init(struct arm_
 	cpu_pmu->name		= "armv7_cortex_a7";
 	cpu_pmu->map_event	= armv7_a7_map_event;
 	cpu_pmu->set_event_filter = armv7pmu_set_event_filter;
+	cpu_pmu->pmu.attr_groups = armv7_pmuv2_attr_groups;
 	return armv7_probe_num_events(cpu_pmu);
 }
 
@@ -1128,6 +1245,7 @@ static int armv7_a12_pmu_init(struct arm
 	cpu_pmu->name		= "armv7_cortex_a12";
 	cpu_pmu->map_event	= armv7_a12_map_event;
 	cpu_pmu->set_event_filter = armv7pmu_set_event_filter;
+	cpu_pmu->pmu.attr_groups = armv7_pmuv2_attr_groups;
 	return armv7_probe_num_events(cpu_pmu);
 }
 
@@ -1135,6 +1253,7 @@ static int armv7_a17_pmu_init(struct arm
 {
 	int ret = armv7_a12_pmu_init(cpu_pmu);
 	cpu_pmu->name = "armv7_cortex_a17";
+	cpu_pmu->pmu.attr_groups = armv7_pmuv2_attr_groups;
 	return ret;
 }
 
--- zfcpdump-kernel-4.4.orig/arch/arm/kernel/ptrace.c
+++ zfcpdump-kernel-4.4/arch/arm/kernel/ptrace.c
@@ -733,8 +733,8 @@ static int vfp_set(struct task_struct *t
 	if (ret)
 		return ret;
 
-	vfp_flush_hwstate(thread);
 	thread->vfpstate.hard = new_vfp;
+	vfp_flush_hwstate(thread);
 
 	return 0;
 }
--- zfcpdump-kernel-4.4.orig/arch/arm/kernel/sys_oabi-compat.c
+++ zfcpdump-kernel-4.4/arch/arm/kernel/sys_oabi-compat.c
@@ -279,8 +279,12 @@ asmlinkage long sys_oabi_epoll_wait(int
 	mm_segment_t fs;
 	long ret, err, i;
 
-	if (maxevents <= 0 || maxevents > (INT_MAX/sizeof(struct epoll_event)))
+	if (maxevents <= 0 ||
+			maxevents > (INT_MAX/sizeof(*kbuf)) ||
+			maxevents > (INT_MAX/sizeof(*events)))
 		return -EINVAL;
+	if (!access_ok(VERIFY_WRITE, events, sizeof(*events) * maxevents))
+		return -EFAULT;
 	kbuf = kmalloc(sizeof(*kbuf) * maxevents, GFP_KERNEL);
 	if (!kbuf)
 		return -ENOMEM;
@@ -317,6 +321,8 @@ asmlinkage long sys_oabi_semtimedop(int
 
 	if (nsops < 1 || nsops > SEMOPM)
 		return -EINVAL;
+	if (!access_ok(VERIFY_READ, tsops, sizeof(*tsops) * nsops))
+		return -EFAULT;
 	sops = kmalloc(sizeof(*sops) * nsops, GFP_KERNEL);
 	if (!sops)
 		return -ENOMEM;
--- zfcpdump-kernel-4.4.orig/arch/arm/kvm/arm.c
+++ zfcpdump-kernel-4.4/arch/arm/kvm/arm.c
@@ -155,8 +155,6 @@ void kvm_arch_destroy_vm(struct kvm *kvm
 {
 	int i;
 
-	kvm_free_stage2_pgd(kvm);
-
 	for (i = 0; i < KVM_MAX_VCPUS; ++i) {
 		if (kvm->vcpus[i]) {
 			kvm_arch_vcpu_free(kvm->vcpus[i]);
--- zfcpdump-kernel-4.4.orig/arch/arm/kvm/guest.c
+++ zfcpdump-kernel-4.4/arch/arm/kvm/guest.c
@@ -155,7 +155,7 @@ static int get_timer_reg(struct kvm_vcpu
 	u64 val;
 
 	val = kvm_arm_timer_get_reg(vcpu, reg->id);
-	return copy_to_user(uaddr, &val, KVM_REG_SIZE(reg->id));
+	return copy_to_user(uaddr, &val, KVM_REG_SIZE(reg->id)) ? -EFAULT : 0;
 }
 
 static unsigned long num_core_regs(void)
--- zfcpdump-kernel-4.4.orig/arch/arm/kvm/mmu.c
+++ zfcpdump-kernel-4.4/arch/arm/kvm/mmu.c
@@ -886,11 +886,14 @@ static int stage2_set_pmd_huge(struct kv
 	VM_BUG_ON(pmd_present(*pmd) && pmd_pfn(*pmd) != pmd_pfn(*new_pmd));
 
 	old_pmd = *pmd;
-	kvm_set_pmd(pmd, *new_pmd);
-	if (pmd_present(old_pmd))
+	if (pmd_present(old_pmd)) {
+		pmd_clear(pmd);
 		kvm_tlb_flush_vmid_ipa(kvm, addr);
-	else
+	} else {
 		get_page(virt_to_page(pmd));
+	}
+
+	kvm_set_pmd(pmd, *new_pmd);
 	return 0;
 }
 
@@ -939,12 +942,14 @@ static int stage2_set_pte(struct kvm *kv
 
 	/* Create 2nd stage page table mapping - Level 3 */
 	old_pte = *pte;
-	kvm_set_pte(pte, *new_pte);
-	if (pte_present(old_pte))
+	if (pte_present(old_pte)) {
+		kvm_set_pte(pte, __pte(0));
 		kvm_tlb_flush_vmid_ipa(kvm, addr);
-	else
+	} else {
 		get_page(virt_to_page(pte));
+	}
 
+	kvm_set_pte(pte, *new_pte);
 	return 0;
 }
 
@@ -1847,6 +1852,7 @@ void kvm_arch_memslots_updated(struct kv
 
 void kvm_arch_flush_shadow_all(struct kvm *kvm)
 {
+	kvm_free_stage2_pgd(kvm);
 }
 
 void kvm_arch_flush_shadow_memslot(struct kvm *kvm,
--- zfcpdump-kernel-4.4.orig/arch/arm/mach-cns3xxx/pcie.c
+++ zfcpdump-kernel-4.4/arch/arm/mach-cns3xxx/pcie.c
@@ -220,13 +220,13 @@ static void cns3xxx_write_config(struct
 	u32 mask = (0x1ull << (size * 8)) - 1;
 	int shift = (where % 4) * 8;
 
-	v = readl_relaxed(base + (where & 0xffc));
+	v = readl_relaxed(base);
 
 	v &= ~(mask << shift);
 	v |= (val & mask) << shift;
 
-	writel_relaxed(v, base + (where & 0xffc));
-	readl_relaxed(base + (where & 0xffc));
+	writel_relaxed(v, base);
+	readl_relaxed(base);
 }
 
 static void __init cns3xxx_pcie_hw_init(struct cns3xxx_pcie *cnspci)
--- zfcpdump-kernel-4.4.orig/arch/arm/mach-exynos/Kconfig
+++ zfcpdump-kernel-4.4/arch/arm/mach-exynos/Kconfig
@@ -26,6 +26,7 @@ menuconfig ARCH_EXYNOS
 	select S5P_DEV_MFC
 	select SRAM
 	select THERMAL
+	select THERMAL_OF
 	select MFD_SYSCON
 	help
 	  Support for SAMSUNG EXYNOS SoCs (EXYNOS4/5)
--- zfcpdump-kernel-4.4.orig/arch/arm/mach-exynos/pm_domains.c
+++ zfcpdump-kernel-4.4/arch/arm/mach-exynos/pm_domains.c
@@ -92,7 +92,7 @@ static int exynos_pd_power(struct generi
 			if (IS_ERR(pd->clk[i]))
 				break;
 
-			if (IS_ERR(pd->clk[i]))
+			if (IS_ERR(pd->pclk[i]))
 				continue; /* Skip on first power up */
 			if (clk_set_parent(pd->clk[i], pd->pclk[i]))
 				pr_err("%s: error setting parent to clock%d\n",
--- zfcpdump-kernel-4.4.orig/arch/arm/mach-highbank/Makefile
+++ zfcpdump-kernel-4.4/arch/arm/mach-highbank/Makefile
@@ -1,3 +1,5 @@
+KBUILD_CFLAGS += -I$(srctree)/arch/arm/mach-highbank/include
+
 obj-y					:= highbank.o system.o smc.o
 
 plus_sec := $(call as-instr,.arch_extension sec,+sec)
--- zfcpdump-kernel-4.4.orig/arch/arm/mach-imx/mach-imx6ul.c
+++ zfcpdump-kernel-4.4/arch/arm/mach-imx/mach-imx6ul.c
@@ -46,7 +46,7 @@ static int ksz8081_phy_fixup(struct phy_
 static void __init imx6ul_enet_phy_init(void)
 {
 	if (IS_BUILTIN(CONFIG_PHYLIB))
-		phy_register_fixup_for_uid(PHY_ID_KSZ8081, 0xffffffff,
+		phy_register_fixup_for_uid(PHY_ID_KSZ8081, MICREL_PHY_ID_MASK,
 					   ksz8081_phy_fixup);
 }
 
--- zfcpdump-kernel-4.4.orig/arch/arm/mach-imx/pm-imx6.c
+++ zfcpdump-kernel-4.4/arch/arm/mach-imx/pm-imx6.c
@@ -295,7 +295,7 @@ int imx6_set_lpm(enum mxc_cpu_pwr_mode m
 		val &= ~BM_CLPCR_SBYOS;
 		if (cpu_is_imx6sl())
 			val |= BM_CLPCR_BYPASS_PMIC_READY;
-		if (cpu_is_imx6sl() || cpu_is_imx6sx())
+		if (cpu_is_imx6sl() || cpu_is_imx6sx() || cpu_is_imx6ul())
 			val |= BM_CLPCR_BYP_MMDC_CH0_LPM_HS;
 		else
 			val |= BM_CLPCR_BYP_MMDC_CH1_LPM_HS;
@@ -310,7 +310,7 @@ int imx6_set_lpm(enum mxc_cpu_pwr_mode m
 		val |= 0x3 << BP_CLPCR_STBY_COUNT;
 		val |= BM_CLPCR_VSTBY;
 		val |= BM_CLPCR_SBYOS;
-		if (cpu_is_imx6sl())
+		if (cpu_is_imx6sl() || cpu_is_imx6sx())
 			val |= BM_CLPCR_BYPASS_PMIC_READY;
 		if (cpu_is_imx6sl() || cpu_is_imx6sx() || cpu_is_imx6ul())
 			val |= BM_CLPCR_BYP_MMDC_CH0_LPM_HS;
--- zfcpdump-kernel-4.4.orig/arch/arm/mach-mvebu/coherency.c
+++ zfcpdump-kernel-4.4/arch/arm/mach-mvebu/coherency.c
@@ -162,22 +162,16 @@ exit:
 }
 
 /*
- * This ioremap hook is used on Armada 375/38x to ensure that PCIe
- * memory areas are mapped as MT_UNCACHED instead of MT_DEVICE. This
- * is needed as a workaround for a deadlock issue between the PCIe
- * interface and the cache controller.
+ * This ioremap hook is used on Armada 375/38x to ensure that all MMIO
+ * areas are mapped as MT_UNCACHED instead of MT_DEVICE. This is
+ * needed for the HW I/O coherency mechanism to work properly without
+ * deadlock.
  */
 static void __iomem *
-armada_pcie_wa_ioremap_caller(phys_addr_t phys_addr, size_t size,
-			      unsigned int mtype, void *caller)
+armada_wa_ioremap_caller(phys_addr_t phys_addr, size_t size,
+			 unsigned int mtype, void *caller)
 {
-	struct resource pcie_mem;
-
-	mvebu_mbus_get_pcie_mem_aperture(&pcie_mem);
-
-	if (pcie_mem.start <= phys_addr && (phys_addr + size) <= pcie_mem.end)
-		mtype = MT_UNCACHED;
-
+	mtype = MT_UNCACHED;
 	return __arm_ioremap_caller(phys_addr, size, mtype, caller);
 }
 
@@ -186,7 +180,7 @@ static void __init armada_375_380_cohere
 	struct device_node *cache_dn;
 
 	coherency_cpu_base = of_iomap(np, 0);
-	arch_ioremap_caller = armada_pcie_wa_ioremap_caller;
+	arch_ioremap_caller = armada_wa_ioremap_caller;
 
 	/*
 	 * We should switch the PL310 to I/O coherency mode only if
--- zfcpdump-kernel-4.4.orig/arch/arm/mach-omap2/cpuidle34xx.c
+++ zfcpdump-kernel-4.4/arch/arm/mach-omap2/cpuidle34xx.c
@@ -34,6 +34,7 @@
 #include "pm.h"
 #include "control.h"
 #include "common.h"
+#include "soc.h"
 
 /* Mach specific information to be recorded in the C-state driver_data */
 struct omap3_idle_statedata {
@@ -315,6 +316,69 @@ static struct cpuidle_driver omap3_idle_
 	.safe_state_index = 0,
 };
 
+/*
+ * Numbers based on measurements made in October 2009 for PM optimized kernel
+ * with CPU freq enabled on device Nokia N900. Assumes OPP2 (main idle OPP,
+ * and worst case latencies).
+ */
+static struct cpuidle_driver omap3430_idle_driver = {
+	.name             = "omap3430_idle",
+	.owner            = THIS_MODULE,
+	.states = {
+		{
+			.enter		  = omap3_enter_idle_bm,
+			.exit_latency	  = 110 + 162,
+			.target_residency = 5,
+			.name		  = "C1",
+			.desc		  = "MPU ON + CORE ON",
+		},
+		{
+			.enter		  = omap3_enter_idle_bm,
+			.exit_latency	  = 106 + 180,
+			.target_residency = 309,
+			.name		  = "C2",
+			.desc		  = "MPU ON + CORE ON",
+		},
+		{
+			.enter		  = omap3_enter_idle_bm,
+			.exit_latency	  = 107 + 410,
+			.target_residency = 46057,
+			.name		  = "C3",
+			.desc		  = "MPU RET + CORE ON",
+		},
+		{
+			.enter		  = omap3_enter_idle_bm,
+			.exit_latency	  = 121 + 3374,
+			.target_residency = 46057,
+			.name		  = "C4",
+			.desc		  = "MPU OFF + CORE ON",
+		},
+		{
+			.enter		  = omap3_enter_idle_bm,
+			.exit_latency	  = 855 + 1146,
+			.target_residency = 46057,
+			.name		  = "C5",
+			.desc		  = "MPU RET + CORE RET",
+		},
+		{
+			.enter		  = omap3_enter_idle_bm,
+			.exit_latency	  = 7580 + 4134,
+			.target_residency = 484329,
+			.name		  = "C6",
+			.desc		  = "MPU OFF + CORE RET",
+		},
+		{
+			.enter		  = omap3_enter_idle_bm,
+			.exit_latency	  = 7505 + 15274,
+			.target_residency = 484329,
+			.name		  = "C7",
+			.desc		  = "MPU OFF + CORE OFF",
+		},
+	},
+	.state_count = ARRAY_SIZE(omap3_idle_data),
+	.safe_state_index = 0,
+};
+
 /* Public functions */
 
 /**
@@ -333,5 +397,8 @@ int __init omap3_idle_init(void)
 	if (!mpu_pd || !core_pd || !per_pd || !cam_pd)
 		return -ENODEV;
 
-	return cpuidle_register(&omap3_idle_driver, NULL);
+	if (cpu_is_omap3430())
+		return cpuidle_register(&omap3430_idle_driver, NULL);
+	else
+		return cpuidle_register(&omap3_idle_driver, NULL);
 }
--- zfcpdump-kernel-4.4.orig/arch/arm/mach-omap2/gpmc-onenand.c
+++ zfcpdump-kernel-4.4/arch/arm/mach-omap2/gpmc-onenand.c
@@ -101,10 +101,8 @@ static void omap2_onenand_set_async_mode
 
 static void set_onenand_cfg(void __iomem *onenand_base)
 {
-	u32 reg;
+	u32 reg = ONENAND_SYS_CFG1_RDY | ONENAND_SYS_CFG1_INT;
 
-	reg = readw(onenand_base + ONENAND_REG_SYS_CFG1);
-	reg &= ~((0x7 << ONENAND_SYS_CFG1_BRL_SHIFT) | (0x7 << 9));
 	reg |=	(latency << ONENAND_SYS_CFG1_BRL_SHIFT) |
 		ONENAND_SYS_CFG1_BL_16;
 	if (onenand_flags & ONENAND_FLAG_SYNCREAD)
@@ -123,6 +121,7 @@ static void set_onenand_cfg(void __iomem
 		reg |= ONENAND_SYS_CFG1_VHF;
 	else
 		reg &= ~ONENAND_SYS_CFG1_VHF;
+
 	writew(reg, onenand_base + ONENAND_REG_SYS_CFG1);
 }
 
@@ -289,6 +288,7 @@ static int omap2_onenand_setup_async(voi
 		}
 	}
 
+	onenand_async.sync_write = true;
 	omap2_onenand_calc_async_timings(&t);
 
 	ret = gpmc_cs_program_settings(gpmc_onenand_data->cs, &onenand_async);
--- zfcpdump-kernel-4.4.orig/arch/arm/mach-omap2/io.c
+++ zfcpdump-kernel-4.4/arch/arm/mach-omap2/io.c
@@ -368,6 +368,7 @@ void __init omap5_map_io(void)
 void __init dra7xx_map_io(void)
 {
 	iotable_init(dra7xx_io_desc, ARRAY_SIZE(dra7xx_io_desc));
+	omap_barriers_init();
 }
 #endif
 /*
--- zfcpdump-kernel-4.4.orig/arch/arm/mach-omap2/omap_device.c
+++ zfcpdump-kernel-4.4/arch/arm/mach-omap2/omap_device.c
@@ -190,12 +190,22 @@ static int _omap_device_notifier_call(st
 {
 	struct platform_device *pdev = to_platform_device(dev);
 	struct omap_device *od;
+	int err;
 
 	switch (event) {
-	case BUS_NOTIFY_DEL_DEVICE:
+	case BUS_NOTIFY_REMOVED_DEVICE:
 		if (pdev->archdata.od)
 			omap_device_delete(pdev->archdata.od);
 		break;
+	case BUS_NOTIFY_UNBOUND_DRIVER:
+		od = to_omap_device(pdev);
+		if (od && (od->_state == OMAP_DEVICE_STATE_ENABLED)) {
+			dev_info(dev, "enabled after unload, idling\n");
+			err = omap_device_idle(pdev);
+			if (err)
+				dev_err(dev, "failed to idle\n");
+		}
+		break;
 	case BUS_NOTIFY_ADD_DEVICE:
 		if (pdev->dev.of_node)
 			omap_device_build_from_dt(pdev);
@@ -257,7 +267,7 @@ static int _omap_device_idle_hwmods(stru
  * function returns a value different than the value the caller got
  * the last time it called this function.
  *
- * If any hwmods exist for the omap_device assoiated with @pdev,
+ * If any hwmods exist for the omap_device associated with @pdev,
  * return the context loss counter for that hwmod, otherwise return
  * zero.
  */
--- zfcpdump-kernel-4.4.orig/arch/arm/mach-omap2/omap_hwmod.c
+++ zfcpdump-kernel-4.4/arch/arm/mach-omap2/omap_hwmod.c
@@ -1416,9 +1416,7 @@ static void _enable_sysc(struct omap_hwm
 	    (sf & SYSC_HAS_CLOCKACTIVITY))
 		_set_clockactivity(oh, oh->class->sysc->clockact, &v);
 
-	/* If the cached value is the same as the new value, skip the write */
-	if (oh->_sysc_cache != v)
-		_write_sysconfig(v, oh);
+	_write_sysconfig(v, oh);
 
 	/*
 	 * Set the autoidle bit only after setting the smartidle bit
@@ -1481,7 +1479,9 @@ static void _idle_sysc(struct omap_hwmod
 		_set_master_standbymode(oh, idlemode, &v);
 	}
 
-	_write_sysconfig(v, oh);
+	/* If the cached value is the same as the new value, skip the write */
+	if (oh->_sysc_cache != v)
+		_write_sysconfig(v, oh);
 }
 
 /**
@@ -2200,6 +2200,11 @@ static int _enable(struct omap_hwmod *oh
  */
 static int _idle(struct omap_hwmod *oh)
 {
+	if (oh->flags & HWMOD_NO_IDLE) {
+		oh->_int_flags |= _HWMOD_SKIP_ENABLE;
+		return 0;
+	}
+
 	pr_debug("omap_hwmod: %s: idling\n", oh->name);
 
 	if (oh->_state != _HWMOD_STATE_ENABLED) {
@@ -2504,6 +2509,8 @@ static int __init _init(struct omap_hwmo
 			oh->flags |= HWMOD_INIT_NO_RESET;
 		if (of_find_property(np, "ti,no-idle-on-init", NULL))
 			oh->flags |= HWMOD_INIT_NO_IDLE;
+		if (of_find_property(np, "ti,no-idle", NULL))
+			oh->flags |= HWMOD_NO_IDLE;
 	}
 
 	oh->_state = _HWMOD_STATE_INITIALIZED;
@@ -2630,7 +2637,7 @@ static void __init _setup_postsetup(stru
 	 * XXX HWMOD_INIT_NO_IDLE does not belong in hwmod data -
 	 * it should be set by the core code as a runtime flag during startup
 	 */
-	if ((oh->flags & HWMOD_INIT_NO_IDLE) &&
+	if ((oh->flags & (HWMOD_INIT_NO_IDLE | HWMOD_NO_IDLE)) &&
 	    (postsetup_state == _HWMOD_STATE_IDLE)) {
 		oh->_int_flags |= _HWMOD_SKIP_ENABLE;
 		postsetup_state = _HWMOD_STATE_ENABLED;
--- zfcpdump-kernel-4.4.orig/arch/arm/mach-omap2/omap_hwmod.h
+++ zfcpdump-kernel-4.4/arch/arm/mach-omap2/omap_hwmod.h
@@ -41,6 +41,7 @@ struct omap_device;
 extern struct omap_hwmod_sysc_fields omap_hwmod_sysc_type1;
 extern struct omap_hwmod_sysc_fields omap_hwmod_sysc_type2;
 extern struct omap_hwmod_sysc_fields omap_hwmod_sysc_type3;
+extern struct omap_hwmod_sysc_fields omap_hwmod_sysc_type4;
 
 /*
  * OCP SYSCONFIG bit shifts/masks TYPE1. These are for IPs compliant
@@ -81,6 +82,16 @@ extern struct omap_hwmod_sysc_fields oma
 #define SYSC_TYPE3_MIDLEMODE_SHIFT	2
 #define SYSC_TYPE3_MIDLEMODE_MASK	(0x3 << SYSC_TYPE3_MIDLEMODE_SHIFT)
 
+/*
+ * OCP SYSCONFIG bit shifts/masks TYPE4.
+ */
+#define SYSC_TYPE4_SIDLEMODE_SHIFT	2
+#define SYSC_TYPE4_SIDLEMODE_MASK	(0x3 << SYSC_TYPE4_SIDLEMODE_SHIFT)
+#define SYSC_TYPE4_SOFTRESET_SHIFT	1
+#define SYSC_TYPE4_SOFTRESET_MASK	(1 << SYSC_TYPE4_SOFTRESET_SHIFT)
+#define SYSC_TYPE4_AUTOIDLE_SHIFT	0
+#define SYSC_TYPE4_AUTOIDLE_MASK	(1 << SYSC_TYPE4_AUTOIDLE_SHIFT)
+
 /* OCP SYSSTATUS bit shifts/masks */
 #define SYSS_RESETDONE_SHIFT		0
 #define SYSS_RESETDONE_MASK		(1 << SYSS_RESETDONE_SHIFT)
@@ -525,6 +536,8 @@ struct omap_hwmod_omap4_prcm {
  *     or idled.
  * HWMOD_OPT_CLKS_NEEDED: The optional clocks are needed for the module to
  *     operate and they need to be handled at the same time as the main_clk.
+ * HWMOD_NO_IDLE: Do not idle the hwmod at all. Useful to handle certain
+ *     IPs like CPSW on DRA7, where clocks to this module cannot be disabled.
  */
 #define HWMOD_SWSUP_SIDLE			(1 << 0)
 #define HWMOD_SWSUP_MSTANDBY			(1 << 1)
@@ -541,6 +554,7 @@ struct omap_hwmod_omap4_prcm {
 #define HWMOD_SWSUP_SIDLE_ACT			(1 << 12)
 #define HWMOD_RECONFIG_IO_CHAIN			(1 << 13)
 #define HWMOD_OPT_CLKS_NEEDED			(1 << 14)
+#define HWMOD_NO_IDLE				(1 << 15)
 
 /*
  * omap_hwmod._int_flags definitions
--- zfcpdump-kernel-4.4.orig/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_ipblock_data.c
+++ zfcpdump-kernel-4.4/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_ipblock_data.c
@@ -223,6 +223,7 @@ static struct omap_hwmod_class_sysconfig
 	.sysc_offs	= 0x84,
 	.syss_offs	= 0x88,
 	.sysc_flags	= SYSS_HAS_RESET_STATUS,
+	.sysc_fields    = &omap_hwmod_sysc_type4,
 };
 
 static struct omap_hwmod_class am33xx_aes0_hwmod_class = {
@@ -1474,6 +1475,7 @@ static void omap_hwmod_am43xx_rst(void)
 {
 	RSTCTRL(am33xx_pruss_hwmod, AM43XX_RM_PER_RSTCTRL_OFFSET);
 	RSTCTRL(am33xx_gfx_hwmod, AM43XX_RM_GFX_RSTCTRL_OFFSET);
+	RSTST(am33xx_pruss_hwmod, AM43XX_RM_PER_RSTST_OFFSET);
 	RSTST(am33xx_gfx_hwmod, AM43XX_RM_GFX_RSTST_OFFSET);
 }
 
--- zfcpdump-kernel-4.4.orig/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
+++ zfcpdump-kernel-4.4/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
@@ -723,8 +723,20 @@ static struct omap_hwmod omap3xxx_dss_di
  * display serial interface controller
  */
 
+static struct omap_hwmod_class_sysconfig omap3xxx_dsi_sysc = {
+	.rev_offs	= 0x0000,
+	.sysc_offs	= 0x0010,
+	.syss_offs	= 0x0014,
+	.sysc_flags	= (SYSC_HAS_AUTOIDLE | SYSC_HAS_CLOCKACTIVITY |
+			   SYSC_HAS_ENAWAKEUP | SYSC_HAS_SIDLEMODE |
+			   SYSC_HAS_SOFTRESET | SYSS_HAS_RESET_STATUS),
+	.idlemodes	= (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
+	.sysc_fields	= &omap_hwmod_sysc_type1,
+};
+
 static struct omap_hwmod_class omap3xxx_dsi_hwmod_class = {
 	.name = "dsi",
+	.sysc	= &omap3xxx_dsi_sysc,
 };
 
 static struct omap_hwmod_irq_info omap3xxx_dsi1_irqs[] = {
--- zfcpdump-kernel-4.4.orig/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
+++ zfcpdump-kernel-4.4/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
@@ -4691,6 +4691,59 @@ static struct omap_hwmod_ocp_if omap44xx
 	.user		= OCP_USER_MPU | OCP_USER_SDMA,
 };
 
+/*
+    Crypto modules AES0/1 belong to:
+	PD_L4_PER power domain
+	CD_L4_SEC clock domain
+	On the L3, the AES modules are mapped to
+	L3_CLK2: Peripherals and multimedia sub clock domain
+*/
+
+static struct omap_hwmod_class_sysconfig omap4_aes1_sysc = {
+	.rev_offs	= 0x80,
+	.sysc_offs	= 0x84,
+	.syss_offs	= 0x88,
+	.sysc_flags	= SYSS_HAS_RESET_STATUS,
+	.sysc_fields	= &omap_hwmod_sysc_type4,
+};
+
+static struct omap_hwmod_class omap4_aes1_hwmod_class = {
+	.name		= "aes1",
+	.sysc		= &omap4_aes1_sysc,
+};
+
+static struct omap_hwmod omap4_aes1_hwmod = {
+	.name		= "aes",
+	.class		= &omap4_aes1_hwmod_class,
+	.clkdm_name	= "l4_secure_clkdm",
+	.main_clk	= "aes1_fck",
+	.prcm		= {
+		.omap4	= {
+			.clkctrl_offs = OMAP4_CM_L4SEC_AES1_CLKCTRL_OFFSET,
+			.context_offs = OMAP4_RM_L4SEC_AES1_CONTEXT_OFFSET,
+			.modulemode	= MODULEMODE_SWCTRL,
+		},
+	},
+};
+
+/* l3_main_2 -> aes1 */
+static struct omap_hwmod_addr_space omap4_aes1_addrs[] = {
+	{
+		.pa_start	= 0x4B500000,
+		.pa_end		= 0x4B500000 + SZ_1M - 1,
+		.flags		= ADDR_TYPE_RT
+	},
+	{ }
+};
+
+static struct omap_hwmod_ocp_if omap4_l3_main_2__aes1 = {
+	.master		= &omap44xx_l3_main_2_hwmod,
+	.slave		= &omap4_aes1_hwmod,
+	.clk		= "aes1_fck",
+	.addr		= omap4_aes1_addrs,
+	.user		= OCP_USER_MPU | OCP_USER_SDMA,
+};
+
 static struct omap_hwmod_ocp_if *omap44xx_hwmod_ocp_ifs[] __initdata = {
 	&omap44xx_l3_main_1__dmm,
 	&omap44xx_mpu__dmm,
@@ -4836,6 +4889,7 @@ static struct omap_hwmod_ocp_if *omap44x
 	&omap44xx_l4_abe__wd_timer3_dma,
 	&omap44xx_mpu__emif1,
 	&omap44xx_mpu__emif2,
+	&omap4_l3_main_2__aes1,
 	NULL,
 };
 
--- zfcpdump-kernel-4.4.orig/arch/arm/mach-omap2/omap_hwmod_common_data.c
+++ zfcpdump-kernel-4.4/arch/arm/mach-omap2/omap_hwmod_common_data.c
@@ -59,6 +59,16 @@ struct omap_hwmod_sysc_fields omap_hwmod
 	.sidle_shift	= SYSC_TYPE3_SIDLEMODE_SHIFT,
 };
 
+/**
+ * struct omap_hwmod_sysc_type4 - TYPE4 sysconfig scheme.
+ * Used by some IPs on AM33xx
+ */
+struct omap_hwmod_sysc_fields omap_hwmod_sysc_type4 = {
+	.sidle_shift	= SYSC_TYPE4_SIDLEMODE_SHIFT,
+	.srst_shift	= SYSC_TYPE4_SOFTRESET_SHIFT,
+	.autoidle_shift	= SYSC_TYPE4_AUTOIDLE_SHIFT,
+};
+
 struct omap_dss_dispc_dev_attr omap2_3_dss_dispc_dev_attr = {
 	.manager_count		= 2,
 	.has_framedonetv_irq	= 0
--- zfcpdump-kernel-4.4.orig/arch/arm/mach-omap2/prcm43xx.h
+++ zfcpdump-kernel-4.4/arch/arm/mach-omap2/prcm43xx.h
@@ -39,6 +39,7 @@
 
 /* RM RSTST offsets */
 #define AM43XX_RM_GFX_RSTST_OFFSET			0x0014
+#define AM43XX_RM_PER_RSTST_OFFSET			0x0014
 #define AM43XX_RM_WKUP_RSTST_OFFSET			0x0014
 
 /* CM instances */
--- zfcpdump-kernel-4.4.orig/arch/arm/mach-omap2/sleep34xx.S
+++ zfcpdump-kernel-4.4/arch/arm/mach-omap2/sleep34xx.S
@@ -86,13 +86,18 @@ ENTRY(enable_omap3630_toggle_l2_on_resto
 	stmfd	sp!, {lr}	@ save registers on stack
 	/* Setup so that we will disable and enable l2 */
 	mov	r1, #0x1
-	adrl	r2, l2dis_3630	@ may be too distant for plain adr
-	str	r1, [r2]
+	adrl	r3, l2dis_3630_offset	@ may be too distant for plain adr
+	ldr	r2, [r3]		@ value for offset
+	str	r1, [r2, r3]		@ write to l2dis_3630
 	ldmfd	sp!, {pc}	@ restore regs and return
 ENDPROC(enable_omap3630_toggle_l2_on_restore)
 
-	.text
-/* Function to call rom code to save secure ram context */
+/*
+ * Function to call rom code to save secure ram context. This gets
+ * relocated to SRAM, so it can be all in .data section. Otherwise
+ * we need to initialize api_params separately.
+ */
+	.data
 	.align	3
 ENTRY(save_secure_ram_context)
 	stmfd	sp!, {r4 - r11, lr}	@ save registers on stack
@@ -126,6 +131,8 @@ ENDPROC(save_secure_ram_context)
 ENTRY(save_secure_ram_context_sz)
 	.word	. - save_secure_ram_context
 
+	.text
+
 /*
  * ======================
  * == Idle entry point ==
@@ -289,12 +296,6 @@ wait_sdrc_ready:
 	bic	r5, r5, #0x40
 	str	r5, [r4]
 
-/*
- * PC-relative stores lead to undefined behaviour in Thumb-2: use a r7 as a
- * base instead.
- * Be careful not to clobber r7 when maintaing this code.
- */
-
 is_dll_in_lock_mode:
 	/* Is dll in lock mode? */
 	ldr	r4, sdrc_dlla_ctrl
@@ -302,11 +303,7 @@ is_dll_in_lock_mode:
 	tst	r5, #0x4
 	bne	exit_nonoff_modes	@ Return if locked
 	/* wait till dll locks */
-	adr	r7, kick_counter
 wait_dll_lock_timed:
-	ldr	r4, wait_dll_lock_counter
-	add	r4, r4, #1
-	str	r4, [r7, #wait_dll_lock_counter - kick_counter]
 	ldr	r4, sdrc_dlla_status
 	/* Wait 20uS for lock */
 	mov	r6, #8
@@ -330,9 +327,6 @@ kick_dll:
 	orr	r6, r6, #(1<<3)		@ enable dll
 	str	r6, [r4]
 	dsb
-	ldr	r4, kick_counter
-	add	r4, r4, #1
-	str	r4, [r7]		@ kick_counter
 	b	wait_dll_lock_timed
 
 exit_nonoff_modes:
@@ -360,15 +354,6 @@ sdrc_dlla_status:
 	.word	SDRC_DLLA_STATUS_V
 sdrc_dlla_ctrl:
 	.word	SDRC_DLLA_CTRL_V
-	/*
-	 * When exporting to userspace while the counters are in SRAM,
-	 * these 2 words need to be at the end to facilitate retrival!
-	 */
-kick_counter:
-	.word	0
-wait_dll_lock_counter:
-	.word	0
-
 ENTRY(omap3_do_wfi_sz)
 	.word	. - omap3_do_wfi
 
@@ -437,7 +422,9 @@ ENTRY(omap3_restore)
 	cmp	r2, #0x0	@ Check if target power state was OFF or RET
 	bne	logic_l1_restore
 
-	ldr	r0, l2dis_3630
+	adr	r1, l2dis_3630_offset	@ address for offset
+	ldr	r0, [r1]		@ value for offset
+	ldr	r0, [r1, r0]		@ value at l2dis_3630
 	cmp	r0, #0x1	@ should we disable L2 on 3630?
 	bne	skipl2dis
 	mrc	p15, 0, r0, c1, c0, 1
@@ -449,12 +436,14 @@ skipl2dis:
 	and	r1, #0x700
 	cmp	r1, #0x300
 	beq	l2_inv_gp
+	adr	r0, l2_inv_api_params_offset
+	ldr	r3, [r0]
+	add	r3, r3, r0		@ r3 points to dummy parameters
 	mov	r0, #40			@ set service ID for PPA
 	mov	r12, r0			@ copy secure Service ID in r12
 	mov	r1, #0			@ set task id for ROM code in r1
 	mov	r2, #4			@ set some flags in r2, r6
 	mov	r6, #0xff
-	adr	r3, l2_inv_api_params	@ r3 points to dummy parameters
 	dsb				@ data write barrier
 	dmb				@ data memory barrier
 	smc	#1			@ call SMI monitor (smi #1)
@@ -488,8 +477,8 @@ skipl2dis:
 	b	logic_l1_restore
 
 	.align
-l2_inv_api_params:
-	.word	0x1, 0x00
+l2_inv_api_params_offset:
+	.long	l2_inv_api_params - .
 l2_inv_gp:
 	/* Execute smi to invalidate L2 cache */
 	mov r12, #0x1			@ set up to invalidate L2
@@ -506,7 +495,9 @@ l2_inv_gp:
 	mov	r12, #0x2
 	smc	#0			@ Call SMI monitor (smieq)
 logic_l1_restore:
-	ldr	r1, l2dis_3630
+	adr	r0, l2dis_3630_offset	@ adress for offset
+	ldr	r1, [r0]		@ value for offset
+	ldr	r1, [r0, r1]		@ value at l2dis_3630
 	cmp	r1, #0x1		@ Test if L2 re-enable needed on 3630
 	bne	skipl2reen
 	mrc	p15, 0, r1, c1, c0, 1
@@ -535,9 +526,17 @@ control_stat:
 	.word	CONTROL_STAT
 control_mem_rta:
 	.word	CONTROL_MEM_RTA_CTRL
+l2dis_3630_offset:
+	.long	l2dis_3630 - .
+
+	.data
 l2dis_3630:
 	.word	0
 
+	.data
+l2_inv_api_params:
+	.word	0x1, 0x00
+
 /*
  * Internal functions
  */
--- zfcpdump-kernel-4.4.orig/arch/arm/mach-omap2/sleep44xx.S
+++ zfcpdump-kernel-4.4/arch/arm/mach-omap2/sleep44xx.S
@@ -29,12 +29,6 @@
 	dsb
 .endm
 
-ppa_zero_params:
-	.word		0x0
-
-ppa_por_params:
-	.word		1, 0
-
 #ifdef CONFIG_ARCH_OMAP4
 
 /*
@@ -266,7 +260,9 @@ ENTRY(omap4_cpu_resume)
 	beq	skip_ns_smp_enable
 ppa_actrl_retry:
 	mov     r0, #OMAP4_PPA_CPU_ACTRL_SMP_INDEX
-	adr	r3, ppa_zero_params		@ Pointer to parameters
+	adr	r1, ppa_zero_params_offset
+	ldr	r3, [r1]
+	add	r3, r3, r1			@ Pointer to ppa_zero_params
 	mov	r1, #0x0			@ Process ID
 	mov	r2, #0x4			@ Flag
 	mov	r6, #0xff
@@ -303,7 +299,9 @@ skip_ns_smp_enable:
 	ldr     r0, =OMAP4_PPA_L2_POR_INDEX
 	ldr     r1, =OMAP44XX_SAR_RAM_BASE
 	ldr     r4, [r1, #L2X0_PREFETCH_CTRL_OFFSET]
-	adr     r3, ppa_por_params
+	adr     r1, ppa_por_params_offset
+	ldr	r3, [r1]
+	add	r3, r3, r1			@ Pointer to ppa_por_params
 	str     r4, [r3, #0x04]
 	mov	r1, #0x0			@ Process ID
 	mov	r2, #0x4			@ Flag
@@ -328,6 +326,8 @@ skip_l2en:
 #endif
 
 	b	cpu_resume			@ Jump to generic resume
+ppa_por_params_offset:
+	.long	ppa_por_params - .
 ENDPROC(omap4_cpu_resume)
 #endif	/* CONFIG_ARCH_OMAP4 */
 
@@ -380,4 +380,13 @@ ENTRY(omap_do_wfi)
 	nop
 
 	ldmfd	sp!, {pc}
+ppa_zero_params_offset:
+	.long	ppa_zero_params - .
 ENDPROC(omap_do_wfi)
+
+	.data
+ppa_zero_params:
+	.word		0
+
+ppa_por_params:
+	.word		1, 0
--- zfcpdump-kernel-4.4.orig/arch/arm/mach-prima2/Kconfig
+++ zfcpdump-kernel-4.4/arch/arm/mach-prima2/Kconfig
@@ -1,6 +1,7 @@
 menuconfig ARCH_SIRF
 	bool "CSR SiRF" if ARCH_MULTI_V7
 	select ARCH_HAS_RESET_CONTROLLER
+	select RESET_CONTROLLER
 	select ARCH_REQUIRE_GPIOLIB
 	select GENERIC_IRQ_CHIP
 	select NO_IOPORT_MAP
--- zfcpdump-kernel-4.4.orig/arch/arm/mach-pxa/idp.c
+++ zfcpdump-kernel-4.4/arch/arm/mach-pxa/idp.c
@@ -83,7 +83,8 @@ static struct resource smc91x_resources[
 };
 
 static struct smc91x_platdata smc91x_platdata = {
-	.flags = SMC91X_USE_32BIT | SMC91X_USE_DMA | SMC91X_NOWAIT,
+	.flags = SMC91X_USE_8BIT | SMC91X_USE_16BIT | SMC91X_USE_32BIT |
+		 SMC91X_USE_DMA | SMC91X_NOWAIT,
 };
 
 static struct platform_device smc91x_device = {
--- zfcpdump-kernel-4.4.orig/arch/arm/mach-pxa/xcep.c
+++ zfcpdump-kernel-4.4/arch/arm/mach-pxa/xcep.c
@@ -120,7 +120,8 @@ static struct resource smc91x_resources[
 };
 
 static struct smc91x_platdata xcep_smc91x_info = {
-	.flags	= SMC91X_USE_32BIT | SMC91X_NOWAIT | SMC91X_USE_DMA,
+	.flags	= SMC91X_USE_8BIT | SMC91X_USE_16BIT | SMC91X_USE_32BIT |
+		  SMC91X_NOWAIT | SMC91X_USE_DMA,
 };
 
 static struct platform_device smc91x_device = {
--- zfcpdump-kernel-4.4.orig/arch/arm/mach-realview/core.c
+++ zfcpdump-kernel-4.4/arch/arm/mach-realview/core.c
@@ -95,7 +95,8 @@ static struct smsc911x_platform_config s
 };
 
 static struct smc91x_platdata smc91x_platdata = {
-	.flags = SMC91X_USE_32BIT | SMC91X_NOWAIT,
+	.flags = SMC91X_USE_8BIT | SMC91X_USE_16BIT | SMC91X_USE_32BIT |
+		 SMC91X_NOWAIT,
 };
 
 static struct platform_device realview_eth_device = {
--- zfcpdump-kernel-4.4.orig/arch/arm/mach-s3c64xx/dev-audio.c
+++ zfcpdump-kernel-4.4/arch/arm/mach-s3c64xx/dev-audio.c
@@ -54,12 +54,12 @@ static int s3c64xx_i2s_cfg_gpio(struct p
 
 static struct resource s3c64xx_iis0_resource[] = {
 	[0] = DEFINE_RES_MEM(S3C64XX_PA_IIS0, SZ_256),
-	[1] = DEFINE_RES_DMA(DMACH_I2S0_OUT),
-	[2] = DEFINE_RES_DMA(DMACH_I2S0_IN),
 };
 
-static struct s3c_audio_pdata i2sv3_pdata = {
+static struct s3c_audio_pdata i2s0_pdata = {
 	.cfg_gpio = s3c64xx_i2s_cfg_gpio,
+	.dma_playback = DMACH_I2S0_OUT,
+	.dma_capture = DMACH_I2S0_IN,
 };
 
 struct platform_device s3c64xx_device_iis0 = {
@@ -68,15 +68,19 @@ struct platform_device s3c64xx_device_ii
 	.num_resources	  = ARRAY_SIZE(s3c64xx_iis0_resource),
 	.resource	  = s3c64xx_iis0_resource,
 	.dev = {
-		.platform_data = &i2sv3_pdata,
+		.platform_data = &i2s0_pdata,
 	},
 };
 EXPORT_SYMBOL(s3c64xx_device_iis0);
 
 static struct resource s3c64xx_iis1_resource[] = {
 	[0] = DEFINE_RES_MEM(S3C64XX_PA_IIS1, SZ_256),
-	[1] = DEFINE_RES_DMA(DMACH_I2S1_OUT),
-	[2] = DEFINE_RES_DMA(DMACH_I2S1_IN),
+};
+
+static struct s3c_audio_pdata i2s1_pdata = {
+	.cfg_gpio = s3c64xx_i2s_cfg_gpio,
+	.dma_playback = DMACH_I2S1_OUT,
+	.dma_capture = DMACH_I2S1_IN,
 };
 
 struct platform_device s3c64xx_device_iis1 = {
@@ -85,19 +89,19 @@ struct platform_device s3c64xx_device_ii
 	.num_resources	  = ARRAY_SIZE(s3c64xx_iis1_resource),
 	.resource	  = s3c64xx_iis1_resource,
 	.dev = {
-		.platform_data = &i2sv3_pdata,
+		.platform_data = &i2s1_pdata,
 	},
 };
 EXPORT_SYMBOL(s3c64xx_device_iis1);
 
 static struct resource s3c64xx_iisv4_resource[] = {
 	[0] = DEFINE_RES_MEM(S3C64XX_PA_IISV4, SZ_256),
-	[1] = DEFINE_RES_DMA(DMACH_HSI_I2SV40_TX),
-	[2] = DEFINE_RES_DMA(DMACH_HSI_I2SV40_RX),
 };
 
 static struct s3c_audio_pdata i2sv4_pdata = {
 	.cfg_gpio = s3c64xx_i2s_cfg_gpio,
+	.dma_playback = DMACH_HSI_I2SV40_TX,
+	.dma_capture = DMACH_HSI_I2SV40_RX,
 	.type = {
 		.i2s = {
 			.quirks = QUIRK_PRI_6CHAN,
@@ -142,12 +146,12 @@ static int s3c64xx_pcm_cfg_gpio(struct p
 
 static struct resource s3c64xx_pcm0_resource[] = {
 	[0] = DEFINE_RES_MEM(S3C64XX_PA_PCM0, SZ_256),
-	[1] = DEFINE_RES_DMA(DMACH_PCM0_TX),
-	[2] = DEFINE_RES_DMA(DMACH_PCM0_RX),
 };
 
 static struct s3c_audio_pdata s3c_pcm0_pdata = {
 	.cfg_gpio = s3c64xx_pcm_cfg_gpio,
+	.dma_capture = DMACH_PCM0_RX,
+	.dma_playback = DMACH_PCM0_TX,
 };
 
 struct platform_device s3c64xx_device_pcm0 = {
@@ -163,12 +167,12 @@ EXPORT_SYMBOL(s3c64xx_device_pcm0);
 
 static struct resource s3c64xx_pcm1_resource[] = {
 	[0] = DEFINE_RES_MEM(S3C64XX_PA_PCM1, SZ_256),
-	[1] = DEFINE_RES_DMA(DMACH_PCM1_TX),
-	[2] = DEFINE_RES_DMA(DMACH_PCM1_RX),
 };
 
 static struct s3c_audio_pdata s3c_pcm1_pdata = {
 	.cfg_gpio = s3c64xx_pcm_cfg_gpio,
+	.dma_playback = DMACH_PCM1_TX,
+	.dma_capture = DMACH_PCM1_RX,
 };
 
 struct platform_device s3c64xx_device_pcm1 = {
@@ -196,13 +200,14 @@ static int s3c64xx_ac97_cfg_gpe(struct p
 
 static struct resource s3c64xx_ac97_resource[] = {
 	[0] = DEFINE_RES_MEM(S3C64XX_PA_AC97, SZ_256),
-	[1] = DEFINE_RES_DMA(DMACH_AC97_PCMOUT),
-	[2] = DEFINE_RES_DMA(DMACH_AC97_PCMIN),
-	[3] = DEFINE_RES_DMA(DMACH_AC97_MICIN),
-	[4] = DEFINE_RES_IRQ(IRQ_AC97),
+	[1] = DEFINE_RES_IRQ(IRQ_AC97),
 };
 
-static struct s3c_audio_pdata s3c_ac97_pdata;
+static struct s3c_audio_pdata s3c_ac97_pdata = {
+	.dma_playback = DMACH_AC97_PCMOUT,
+	.dma_capture = DMACH_AC97_PCMIN,
+	.dma_capture_mic = DMACH_AC97_MICIN,
+};
 
 static u64 s3c64xx_ac97_dmamask = DMA_BIT_MASK(32);
 
--- zfcpdump-kernel-4.4.orig/arch/arm/mach-s3c64xx/include/mach/dma.h
+++ zfcpdump-kernel-4.4/arch/arm/mach-s3c64xx/include/mach/dma.h
@@ -14,38 +14,38 @@
 #define S3C64XX_DMA_CHAN(name)		((unsigned long)(name))
 
 /* DMA0/SDMA0 */
-#define DMACH_UART0		S3C64XX_DMA_CHAN("uart0_tx")
-#define DMACH_UART0_SRC2	S3C64XX_DMA_CHAN("uart0_rx")
-#define DMACH_UART1		S3C64XX_DMA_CHAN("uart1_tx")
-#define DMACH_UART1_SRC2	S3C64XX_DMA_CHAN("uart1_rx")
-#define DMACH_UART2		S3C64XX_DMA_CHAN("uart2_tx")
-#define DMACH_UART2_SRC2	S3C64XX_DMA_CHAN("uart2_rx")
-#define DMACH_UART3		S3C64XX_DMA_CHAN("uart3_tx")
-#define DMACH_UART3_SRC2	S3C64XX_DMA_CHAN("uart3_rx")
-#define DMACH_PCM0_TX		S3C64XX_DMA_CHAN("pcm0_tx")
-#define DMACH_PCM0_RX		S3C64XX_DMA_CHAN("pcm0_rx")
-#define DMACH_I2S0_OUT		S3C64XX_DMA_CHAN("i2s0_tx")
-#define DMACH_I2S0_IN		S3C64XX_DMA_CHAN("i2s0_rx")
+#define DMACH_UART0		"uart0_tx"
+#define DMACH_UART0_SRC2	"uart0_rx"
+#define DMACH_UART1		"uart1_tx"
+#define DMACH_UART1_SRC2	"uart1_rx"
+#define DMACH_UART2		"uart2_tx"
+#define DMACH_UART2_SRC2	"uart2_rx"
+#define DMACH_UART3		"uart3_tx"
+#define DMACH_UART3_SRC2	"uart3_rx"
+#define DMACH_PCM0_TX		"pcm0_tx"
+#define DMACH_PCM0_RX		"pcm0_rx"
+#define DMACH_I2S0_OUT		"i2s0_tx"
+#define DMACH_I2S0_IN		"i2s0_rx"
 #define DMACH_SPI0_TX		S3C64XX_DMA_CHAN("spi0_tx")
 #define DMACH_SPI0_RX		S3C64XX_DMA_CHAN("spi0_rx")
-#define DMACH_HSI_I2SV40_TX	S3C64XX_DMA_CHAN("i2s2_tx")
-#define DMACH_HSI_I2SV40_RX	S3C64XX_DMA_CHAN("i2s2_rx")
+#define DMACH_HSI_I2SV40_TX	"i2s2_tx"
+#define DMACH_HSI_I2SV40_RX	"i2s2_rx"
 
 /* DMA1/SDMA1 */
-#define DMACH_PCM1_TX		S3C64XX_DMA_CHAN("pcm1_tx")
-#define DMACH_PCM1_RX		S3C64XX_DMA_CHAN("pcm1_rx")
-#define DMACH_I2S1_OUT		S3C64XX_DMA_CHAN("i2s1_tx")
-#define DMACH_I2S1_IN		S3C64XX_DMA_CHAN("i2s1_rx")
+#define DMACH_PCM1_TX		"pcm1_tx"
+#define DMACH_PCM1_RX		"pcm1_rx"
+#define DMACH_I2S1_OUT		"i2s1_tx"
+#define DMACH_I2S1_IN		"i2s1_rx"
 #define DMACH_SPI1_TX		S3C64XX_DMA_CHAN("spi1_tx")
 #define DMACH_SPI1_RX		S3C64XX_DMA_CHAN("spi1_rx")
-#define DMACH_AC97_PCMOUT	S3C64XX_DMA_CHAN("ac97_out")
-#define DMACH_AC97_PCMIN	S3C64XX_DMA_CHAN("ac97_in")
-#define DMACH_AC97_MICIN	S3C64XX_DMA_CHAN("ac97_mic")
-#define DMACH_PWM		S3C64XX_DMA_CHAN("pwm")
-#define DMACH_IRDA		S3C64XX_DMA_CHAN("irda")
-#define DMACH_EXTERNAL		S3C64XX_DMA_CHAN("external")
-#define DMACH_SECURITY_RX	S3C64XX_DMA_CHAN("sec_rx")
-#define DMACH_SECURITY_TX	S3C64XX_DMA_CHAN("sec_tx")
+#define DMACH_AC97_PCMOUT	"ac97_out"
+#define DMACH_AC97_PCMIN	"ac97_in"
+#define DMACH_AC97_MICIN	"ac97_mic"
+#define DMACH_PWM		"pwm"
+#define DMACH_IRDA		"irda"
+#define DMACH_EXTERNAL		"external"
+#define DMACH_SECURITY_RX	"sec_rx"
+#define DMACH_SECURITY_TX	"sec_tx"
 
 enum dma_ch {
 	DMACH_MAX = 32
--- zfcpdump-kernel-4.4.orig/arch/arm/mach-sa1100/clock.c
+++ zfcpdump-kernel-4.4/arch/arm/mach-sa1100/clock.c
@@ -125,6 +125,8 @@ static unsigned long clk_36864_get_rate(
 }
 
 static struct clkops clk_36864_ops = {
+	.enable		= clk_cpu_enable,
+	.disable	= clk_cpu_disable,
 	.get_rate	= clk_36864_get_rate,
 };
 
@@ -140,9 +142,8 @@ static struct clk_lookup sa11xx_clkregs[
 	CLKDEV_INIT(NULL, "OSTIMER0", &clk_36864),
 };
 
-static int __init sa11xx_clk_init(void)
+int __init sa11xx_clk_init(void)
 {
 	clkdev_add_table(sa11xx_clkregs, ARRAY_SIZE(sa11xx_clkregs));
 	return 0;
 }
-core_initcall(sa11xx_clk_init);
--- zfcpdump-kernel-4.4.orig/arch/arm/mach-sa1100/generic.c
+++ zfcpdump-kernel-4.4/arch/arm/mach-sa1100/generic.c
@@ -34,6 +34,7 @@
 
 #include <mach/hardware.h>
 #include <mach/irqs.h>
+#include <mach/reset.h>
 
 #include "generic.h"
 #include <clocksource/pxa.h>
@@ -95,6 +96,8 @@ static void sa1100_power_off(void)
 
 void sa11x0_restart(enum reboot_mode mode, const char *cmd)
 {
+	clear_reset_status(RESET_STATUS_ALL);
+
 	if (mode == REBOOT_SOFT) {
 		/* Jump into ROM at address 0 */
 		soft_restart(0);
@@ -388,6 +391,7 @@ void __init sa1100_init_irq(void)
 	sa11x0_init_irq_nodt(IRQ_GPIO0_SC, irq_resource.start);
 
 	sa1100_init_gpio();
+	sa11xx_clk_init();
 }
 
 /*
--- zfcpdump-kernel-4.4.orig/arch/arm/mach-sa1100/generic.h
+++ zfcpdump-kernel-4.4/arch/arm/mach-sa1100/generic.h
@@ -44,3 +44,5 @@ int sa11x0_pm_init(void);
 #else
 static inline int sa11x0_pm_init(void) { return 0; }
 #endif
+
+int sa11xx_clk_init(void);
--- zfcpdump-kernel-4.4.orig/arch/arm/mach-sa1100/pleb.c
+++ zfcpdump-kernel-4.4/arch/arm/mach-sa1100/pleb.c
@@ -45,7 +45,7 @@ static struct resource smc91x_resources[
 };
 
 static struct smc91x_platdata smc91x_platdata = {
-	.flags = SMC91X_USE_16BIT | SMC91X_NOWAIT,
+	.flags = SMC91X_USE_16BIT | SMC91X_USE_8BIT | SMC91X_NOWAIT,
 };
 
 static struct platform_device smc91x_device = {
--- zfcpdump-kernel-4.4.orig/arch/arm/mach-shmobile/regulator-quirk-rcar-gen2.c
+++ zfcpdump-kernel-4.4/arch/arm/mach-shmobile/regulator-quirk-rcar-gen2.c
@@ -41,39 +41,26 @@
 
 #define REGULATOR_IRQ_MASK	BIT(2)	/* IRQ2, active low */
 
-static void __iomem *irqc;
-
-static const u8 da9063_mask_regs[] = {
-	DA9063_REG_IRQ_MASK_A,
-	DA9063_REG_IRQ_MASK_B,
-	DA9063_REG_IRQ_MASK_C,
-	DA9063_REG_IRQ_MASK_D,
-};
-
-/* DA9210 System Control and Event Registers */
+/* start of DA9210 System Control and Event Registers */
 #define DA9210_REG_MASK_A		0x54
-#define DA9210_REG_MASK_B		0x55
-
-static const u8 da9210_mask_regs[] = {
-	DA9210_REG_MASK_A,
-	DA9210_REG_MASK_B,
-};
 
-static void da9xxx_mask_irqs(struct i2c_client *client, const u8 regs[],
-			     unsigned int nregs)
-{
-	unsigned int i;
-
-	dev_info(&client->dev, "Masking %s interrupt sources\n", client->name);
+static void __iomem *irqc;
 
-	for (i = 0; i < nregs; i++) {
-		int error = i2c_smbus_write_byte_data(client, regs[i], ~0);
-		if (error) {
-			dev_err(&client->dev, "i2c error %d\n", error);
-			return;
-		}
-	}
-}
+/* first byte sets the memory pointer, following are consecutive reg values */
+static u8 da9063_irq_clr[] = { DA9063_REG_IRQ_MASK_A, 0xff, 0xff, 0xff, 0xff };
+static u8 da9210_irq_clr[] = { DA9210_REG_MASK_A, 0xff, 0xff };
+
+static struct i2c_msg da9xxx_msgs[2] = {
+	{
+		.addr = 0x58,
+		.len = ARRAY_SIZE(da9063_irq_clr),
+		.buf = da9063_irq_clr,
+	}, {
+		.addr = 0x68,
+		.len = ARRAY_SIZE(da9210_irq_clr),
+		.buf = da9210_irq_clr,
+	},
+};
 
 static int regulator_quirk_notify(struct notifier_block *nb,
 				  unsigned long action, void *data)
@@ -93,12 +80,15 @@ static int regulator_quirk_notify(struct
 	client = to_i2c_client(dev);
 	dev_dbg(dev, "Detected %s\n", client->name);
 
-	if ((client->addr == 0x58 && !strcmp(client->name, "da9063")))
-		da9xxx_mask_irqs(client, da9063_mask_regs,
-				 ARRAY_SIZE(da9063_mask_regs));
-	else if (client->addr == 0x68 && !strcmp(client->name, "da9210"))
-		da9xxx_mask_irqs(client, da9210_mask_regs,
-				 ARRAY_SIZE(da9210_mask_regs));
+	if ((client->addr == 0x58 && !strcmp(client->name, "da9063")) ||
+	    (client->addr == 0x68 && !strcmp(client->name, "da9210"))) {
+		int ret;
+
+		dev_info(&client->dev, "clearing da9063/da9210 interrupts\n");
+		ret = i2c_transfer(client->adapter, da9xxx_msgs, ARRAY_SIZE(da9xxx_msgs));
+		if (ret != ARRAY_SIZE(da9xxx_msgs))
+			dev_err(&client->dev, "i2c error %d\n", ret);
+	}
 
 	mon = ioread32(irqc + IRQC_MONITOR);
 	if (mon & REGULATOR_IRQ_MASK)
--- zfcpdump-kernel-4.4.orig/arch/arm/mach-socfpga/headsmp.S
+++ zfcpdump-kernel-4.4/arch/arm/mach-socfpga/headsmp.S
@@ -13,6 +13,7 @@
 #include <asm/assembler.h>
 
 	.arch	armv7-a
+	.arm
 
 ENTRY(secondary_trampoline)
 	/* CPU1 will always fetch from 0x0 when it is brought out of reset.
--- zfcpdump-kernel-4.4.orig/arch/arm/mm/pageattr.c
+++ zfcpdump-kernel-4.4/arch/arm/mm/pageattr.c
@@ -55,6 +55,9 @@ static int change_memory_common(unsigned
 	if (end < MODULES_VADDR || start >= MODULES_END)
 		return -EINVAL;
 
+	if (!numpages)
+		return 0;
+
 	data.set_mask = set_mask;
 	data.clear_mask = clear_mask;
 
--- zfcpdump-kernel-4.4.orig/arch/arm/plat-samsung/devs.c
+++ zfcpdump-kernel-4.4/arch/arm/plat-samsung/devs.c
@@ -65,6 +65,7 @@
 #include <linux/platform_data/usb-ohci-s3c2410.h>
 #include <plat/usb-phy.h>
 #include <plat/regs-spi.h>
+#include <linux/platform_data/asoc-s3c.h>
 #include <linux/platform_data/spi-s3c64xx.h>
 
 static u64 samsung_device_dma_mask = DMA_BIT_MASK(32);
@@ -74,9 +75,12 @@ static u64 samsung_device_dma_mask = DMA
 static struct resource s3c_ac97_resource[] = {
 	[0] = DEFINE_RES_MEM(S3C2440_PA_AC97, S3C2440_SZ_AC97),
 	[1] = DEFINE_RES_IRQ(IRQ_S3C244X_AC97),
-	[2] = DEFINE_RES_DMA_NAMED(DMACH_PCM_OUT, "PCM out"),
-	[3] = DEFINE_RES_DMA_NAMED(DMACH_PCM_IN, "PCM in"),
-	[4] = DEFINE_RES_DMA_NAMED(DMACH_MIC_IN, "Mic in"),
+};
+
+static struct s3c_audio_pdata s3c_ac97_pdata = {
+	.dma_playback = (void *)DMACH_PCM_OUT,
+	.dma_capture = (void *)DMACH_PCM_IN,
+	.dma_capture_mic = (void *)DMACH_MIC_IN,
 };
 
 struct platform_device s3c_device_ac97 = {
@@ -87,6 +91,7 @@ struct platform_device s3c_device_ac97 =
 	.dev		= {
 		.dma_mask		= &samsung_device_dma_mask,
 		.coherent_dma_mask	= DMA_BIT_MASK(32),
+		.platform_data		= &s3c_ac97_pdata,
 	}
 };
 #endif /* CONFIG_CPU_S3C2440 */
--- zfcpdump-kernel-4.4.orig/arch/arm64/Kconfig
+++ zfcpdump-kernel-4.4/arch/arm64/Kconfig
@@ -10,6 +10,7 @@ config ARM64
 	select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST
 	select ARCH_USE_CMPXCHG_LOCKREF
 	select ARCH_SUPPORTS_ATOMIC_RMW
+	select ARCH_SUPPORTS_NUMA_BALANCING
 	select ARCH_WANT_OPTIONAL_GPIOLIB
 	select ARCH_WANT_COMPAT_IPC_PARSE_VERSION
 	select ARCH_WANT_FRAME_POINTERS
@@ -71,6 +72,7 @@ config ARM64
 	select HAVE_GENERIC_DMA_COHERENT
 	select HAVE_HW_BREAKPOINT if PERF_EVENTS
 	select HAVE_MEMBLOCK
+	select HAVE_MEMBLOCK_NODE_MAP if NUMA
 	select HAVE_PATA_PLATFORM
 	select HAVE_PERF_EVENTS
 	select HAVE_PERF_REGS
@@ -92,6 +94,7 @@ config ARM64
 	select SPARSE_IRQ
 	select SYSCTL_EXCEPTION_TRACE
 	select HAVE_CONTEXT_TRACKING
+	select OF_NUMA if NUMA && OF
 	help
 	  ARM 64-bit (AArch64) Linux support.
 
@@ -391,6 +394,15 @@ config CAVIUM_ERRATUM_22375
 
 	  If unsure, say Y.
 
+config CAVIUM_ERRATUM_23144
+	bool "Cavium erratum 23144: ITS SYNC hang on dual socket system"
+	depends on NUMA
+	default y
+	help
+	  ITS SYNC command hang for cross node io and collections/cpu mapping.
+
+	  If unsure, say Y.
+
 config CAVIUM_ERRATUM_23154
 	bool "Cavium erratum 23154: Access to ICC_IAR1_EL1 is not sync'ed"
 	default y
@@ -401,6 +413,17 @@ config CAVIUM_ERRATUM_23154
 
 	  If unsure, say Y.
 
+config CAVIUM_ERRATUM_27456
+	bool "Cavium erratum 27456: Broadcast TLBI instructions may cause icache corruption"
+	default y
+	help
+	  On ThunderX T88 pass 1.x through 2.1 parts, broadcast TLBI
+	  instructions may cause the icache to become corrupted if it
+	  contains data for a non-current ASID.  The fix is to
+	  invalidate the icache when changing the mm context.
+
+	  If unsure, say Y.
+
 endmenu
 
 
@@ -503,6 +526,30 @@ config HOTPLUG_CPU
 	  Say Y here to experiment with turning CPUs off and on.  CPUs
 	  can be controlled through /sys/devices/system/cpu.
 
+# Common NUMA Features
+config NUMA
+	bool "Numa Memory Allocation and Scheduler Support"
+	depends on SMP
+	help
+	  Enable NUMA (Non Uniform Memory Access) support.
+
+	  The kernel will try to allocate memory used by a CPU on the
+	  local memory of the CPU and add some more
+	  NUMA awareness to the kernel.
+
+config NODES_SHIFT
+	int "Maximum NUMA Nodes (as a power of 2)"
+	range 1 10
+	default "2"
+	depends on NEED_MULTIPLE_NODES
+	help
+	  Specify the maximum number of NUMA Nodes available on the target
+	  system.  Increases memory reserved to accommodate various tables.
+
+config USE_PERCPU_NUMA_NODE_ID
+	def_bool y
+	depends on NUMA
+
 source kernel/Kconfig.preempt
 source kernel/Kconfig.hz
 
@@ -570,6 +617,7 @@ config XEN
 config FORCE_MAX_ZONEORDER
 	int
 	default "14" if (ARM64_64K_PAGES && TRANSPARENT_HUGEPAGE)
+	default "13" if (ARCH_THUNDER && ARM64_4K_PAGES)
 	default "12" if (ARM64_16K_PAGES && TRANSPARENT_HUGEPAGE)
 	default "11"
 	help
@@ -708,6 +756,15 @@ endmenu
 
 menu "Boot options"
 
+config ARM64_ACPI_PARKING_PROTOCOL
+	bool "Enable support for the ARM64 ACPI parking protocol"
+	depends on ACPI
+	help
+	  Enable support for the ARM64 ACPI parking protocol. If disabled
+	  the kernel will not allow booting through the ARM64 ACPI parking
+	  protocol even if the corresponding data is present in the ACPI
+	  MADT table.
+
 config CMDLINE
 	string "Default kernel command string"
 	default ""
@@ -807,6 +864,8 @@ source "net/Kconfig"
 
 source "drivers/Kconfig"
 
+source "ubuntu/Kconfig"
+
 source "drivers/firmware/Kconfig"
 
 source "drivers/acpi/Kconfig"
--- zfcpdump-kernel-4.4.orig/arch/arm64/Makefile
+++ zfcpdump-kernel-4.4/arch/arm64/Makefile
@@ -27,6 +27,7 @@ $(warning LSE atomics not supported by b
 endif
 
 KBUILD_CFLAGS	+= -mgeneral-regs-only $(lseinstr)
+KBUILD_CFLAGS	+= $(call cc-option, -mpc-relative-literal-loads)
 KBUILD_AFLAGS	+= $(lseinstr)
 
 ifeq ($(CONFIG_CPU_BIG_ENDIAN), y)
@@ -43,6 +44,7 @@ CHECKFLAGS	+= -D__aarch64__
 
 ifeq ($(CONFIG_ARM64_ERRATUM_843419), y)
 KBUILD_CFLAGS_MODULE	+= -mcmodel=large
+KBUILD_CFLAGS_MODULE	+= $(call cc-option, -mpc-relative-literal-loads)
 endif
 
 # Default value
--- zfcpdump-kernel-4.4.orig/arch/arm64/boot/dts/cavium/thunder-88xx.dtsi
+++ zfcpdump-kernel-4.4/arch/arm64/boot/dts/cavium/thunder-88xx.dtsi
@@ -360,6 +360,11 @@
 		             <1 10 0xff01>;
 	};
 
+	pmu {
+		compatible = "cavium,thunder-pmu", "arm,armv8-pmuv3";
+		interrupts = <1 7 4>;
+	};
+
 	soc {
 		compatible = "simple-bus";
 		#address-cells = <2>;
--- zfcpdump-kernel-4.4.orig/arch/arm64/boot/dts/rockchip/rk3368.dtsi
+++ zfcpdump-kernel-4.4/arch/arm64/boot/dts/rockchip/rk3368.dtsi
@@ -262,6 +262,8 @@
 		#io-channel-cells = <1>;
 		clocks = <&cru SCLK_SARADC>, <&cru PCLK_SARADC>;
 		clock-names = "saradc", "apb_pclk";
+		resets = <&cru SRST_SARADC>;
+		reset-names = "saradc-apb";
 		status = "disabled";
 	};
 
@@ -517,7 +519,7 @@
 		#address-cells = <0>;
 
 		reg = <0x0 0xffb71000 0x0 0x1000>,
-		      <0x0 0xffb72000 0x0 0x1000>,
+		      <0x0 0xffb72000 0x0 0x2000>,
 		      <0x0 0xffb74000 0x0 0x2000>,
 		      <0x0 0xffb76000 0x0 0x2000>;
 		interrupts = <GIC_PPI 9
--- zfcpdump-kernel-4.4.orig/arch/arm64/crypto/aes-glue.c
+++ zfcpdump-kernel-4.4/arch/arm64/crypto/aes-glue.c
@@ -15,6 +15,7 @@
 #include <crypto/algapi.h>
 #include <linux/module.h>
 #include <linux/cpufeature.h>
+#include <crypto/xts.h>
 
 #include "aes-ce-setkey.h"
 
@@ -85,6 +86,10 @@ static int xts_set_key(struct crypto_tfm
 	struct crypto_aes_xts_ctx *ctx = crypto_tfm_ctx(tfm);
 	int ret;
 
+	ret = xts_check_key(tfm, in_key, key_len);
+	if (ret)
+		return ret;
+
 	ret = aes_expandkey(&ctx->key1, in_key, key_len / 2);
 	if (!ret)
 		ret = aes_expandkey(&ctx->key2, &in_key[key_len / 2],
@@ -211,7 +216,7 @@ static int ctr_encrypt(struct blkcipher_
 		err = blkcipher_walk_done(desc, &walk,
 					  walk.nbytes % AES_BLOCK_SIZE);
 	}
-	if (nbytes) {
+	if (walk.nbytes % AES_BLOCK_SIZE) {
 		u8 *tdst = walk.dst.virt.addr + blocks * AES_BLOCK_SIZE;
 		u8 *tsrc = walk.src.virt.addr + blocks * AES_BLOCK_SIZE;
 		u8 __aligned(8) tail[AES_BLOCK_SIZE];
--- zfcpdump-kernel-4.4.orig/arch/arm64/include/asm/acpi.h
+++ zfcpdump-kernel-4.4/arch/arm64/include/asm/acpi.h
@@ -87,9 +87,26 @@ void __init acpi_init_cpus(void);
 static inline void acpi_init_cpus(void) { }
 #endif /* CONFIG_ACPI */
 
+#ifdef CONFIG_ARM64_ACPI_PARKING_PROTOCOL
+bool acpi_parking_protocol_valid(int cpu);
+void __init
+acpi_set_mailbox_entry(int cpu, struct acpi_madt_generic_interrupt *processor);
+#else
+static inline bool acpi_parking_protocol_valid(int cpu) { return false; }
+static inline void
+acpi_set_mailbox_entry(int cpu, struct acpi_madt_generic_interrupt *processor)
+{}
+#endif
+
 static inline const char *acpi_get_enable_method(int cpu)
 {
-	return acpi_psci_present() ? "psci" : NULL;
+	if (acpi_psci_present())
+		return "psci";
+
+	if (acpi_parking_protocol_valid(cpu))
+		return "parking-protocol";
+
+	return NULL;
 }
 
 #ifdef	CONFIG_ACPI_APEI
--- zfcpdump-kernel-4.4.orig/arch/arm64/include/asm/arch_gicv3.h
+++ zfcpdump-kernel-4.4/arch/arm64/include/asm/arch_gicv3.h
@@ -103,6 +103,7 @@ static inline u64 gic_read_iar_common(vo
 	u64 irqstat;
 
 	asm volatile("mrs_s %0, " __stringify(ICC_IAR1_EL1) : "=r" (irqstat));
+	dsb(sy);
 	return irqstat;
 }
 
--- zfcpdump-kernel-4.4.orig/arch/arm64/include/asm/cpufeature.h
+++ zfcpdump-kernel-4.4/arch/arm64/include/asm/cpufeature.h
@@ -30,8 +30,10 @@
 #define ARM64_HAS_LSE_ATOMICS			5
 #define ARM64_WORKAROUND_CAVIUM_23154		6
 #define ARM64_WORKAROUND_834220			7
+#define ARM64_HAS_NO_HW_PREFETCH		8
+#define ARM64_WORKAROUND_CAVIUM_27456		9
 
-#define ARM64_NCAPS				8
+#define ARM64_NCAPS				10
 
 #ifndef __ASSEMBLY__
 
--- zfcpdump-kernel-4.4.orig/arch/arm64/include/asm/cputype.h
+++ zfcpdump-kernel-4.4/arch/arm64/include/asm/cputype.h
@@ -57,11 +57,22 @@
 #define MIDR_IMPLEMENTOR(midr)	\
 	(((midr) & MIDR_IMPLEMENTOR_MASK) >> MIDR_IMPLEMENTOR_SHIFT)
 
-#define MIDR_CPU_PART(imp, partnum) \
+#define MIDR_CPU_MODEL(imp, partnum) \
 	(((imp)			<< MIDR_IMPLEMENTOR_SHIFT) | \
 	(0xf			<< MIDR_ARCHITECTURE_SHIFT) | \
 	((partnum)		<< MIDR_PARTNUM_SHIFT))
 
+#define MIDR_CPU_MODEL_MASK (MIDR_IMPLEMENTOR_MASK | MIDR_PARTNUM_MASK | \
+			     MIDR_ARCHITECTURE_MASK)
+
+#define MIDR_IS_CPU_MODEL_RANGE(midr, model, rv_min, rv_max)		\
+({									\
+	u32 _model = (midr) & MIDR_CPU_MODEL_MASK;			\
+	u32 rv = (midr) & (MIDR_REVISION_MASK | MIDR_VARIANT_MASK);	\
+									\
+	_model == (model) && rv >= (rv_min) && rv <= (rv_max);		\
+ })
+
 #define ARM_CPU_IMP_ARM			0x41
 #define ARM_CPU_IMP_APM			0x50
 #define ARM_CPU_IMP_CAVIUM		0x43
@@ -75,6 +86,10 @@
 
 #define CAVIUM_CPU_PART_THUNDERX	0x0A1
 
+#define MIDR_CORTEX_A53 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A53)
+#define MIDR_CORTEX_A57 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A57)
+#define MIDR_THUNDERX	MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX)
+
 #ifndef __ASSEMBLY__
 
 /*
--- zfcpdump-kernel-4.4.orig/arch/arm64/include/asm/elf.h
+++ zfcpdump-kernel-4.4/arch/arm64/include/asm/elf.h
@@ -136,6 +136,7 @@ typedef struct user_fpsimd_state elf_fpr
 
 #define SET_PERSONALITY(ex)		clear_thread_flag(TIF_32BIT);
 
+/* update AT_VECTOR_SIZE_ARCH if the number of NEW_AUX_ENT entries changes */
 #define ARCH_DLINFO							\
 do {									\
 	NEW_AUX_ENT(AT_SYSINFO_EHDR,					\
@@ -156,14 +157,14 @@ extern int arch_setup_additional_pages(s
 #define STACK_RND_MASK			(0x3ffff >> (PAGE_SHIFT - 12))
 #endif
 
-#ifdef CONFIG_COMPAT
-
 #ifdef __AARCH64EB__
 #define COMPAT_ELF_PLATFORM		("v8b")
 #else
 #define COMPAT_ELF_PLATFORM		("v8l")
 #endif
 
+#ifdef CONFIG_COMPAT
+
 #define COMPAT_ELF_ET_DYN_BASE		(2 * TASK_SIZE_32 / 3)
 
 /* AArch32 registers. */
--- zfcpdump-kernel-4.4.orig/arch/arm64/include/asm/hardirq.h
+++ zfcpdump-kernel-4.4/arch/arm64/include/asm/hardirq.h
@@ -20,7 +20,7 @@
 #include <linux/threads.h>
 #include <asm/irq.h>
 
-#define NR_IPI	5
+#define NR_IPI	6
 
 typedef struct {
 	unsigned int __softirq_pending;
--- zfcpdump-kernel-4.4.orig/arch/arm64/include/asm/kvm_arm.h
+++ zfcpdump-kernel-4.4/arch/arm64/include/asm/kvm_arm.h
@@ -107,8 +107,6 @@
 #define TCR_EL2_MASK	(TCR_EL2_TG0 | TCR_EL2_SH0 | \
 			 TCR_EL2_ORGN0 | TCR_EL2_IRGN0 | TCR_EL2_T0SZ)
 
-#define TCR_EL2_FLAGS	(TCR_EL2_RES1 | TCR_EL2_PS_40B)
-
 /* VTCR_EL2 Registers bits */
 #define VTCR_EL2_RES1		(1 << 31)
 #define VTCR_EL2_PS_MASK	(7 << 16)
--- zfcpdump-kernel-4.4.orig/arch/arm64/include/asm/mmu.h
+++ zfcpdump-kernel-4.4/arch/arm64/include/asm/mmu.h
@@ -28,7 +28,8 @@ typedef struct {
  */
 #define ASID(mm)	((mm)->context.id.counter & 0xffff)
 
-extern void paging_init(void);
+extern void paging_init_map_mem(void);
+extern void paging_init_rest(void);
 extern void __iomem *early_io_map(phys_addr_t phys, unsigned long virt);
 extern void init_mem_pgprot(void);
 extern void create_pgd_mapping(struct mm_struct *mm, phys_addr_t phys,
--- /dev/null
+++ zfcpdump-kernel-4.4/arch/arm64/include/asm/mmzone.h
@@ -0,0 +1,12 @@
+#ifndef __ASM_MMZONE_H
+#define __ASM_MMZONE_H
+
+#ifdef CONFIG_NUMA
+
+#include <asm/numa.h>
+
+extern struct pglist_data *node_data[];
+#define NODE_DATA(nid)		(node_data[(nid)])
+
+#endif /* CONFIG_NUMA */
+#endif /* __ASM_MMZONE_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/arch/arm64/include/asm/numa.h
@@ -0,0 +1,45 @@
+#ifndef __ASM_NUMA_H
+#define __ASM_NUMA_H
+
+#include <asm/topology.h>
+
+#ifdef CONFIG_NUMA
+
+/* currently, arm64 implements flat NUMA topology */
+#define parent_node(node)	(node)
+
+int __node_distance(int from, int to);
+#define node_distance(a, b) __node_distance(a, b)
+
+extern nodemask_t numa_nodes_parsed __initdata;
+
+/* Mappings between node number and cpus on that node. */
+extern cpumask_var_t node_to_cpumask_map[MAX_NUMNODES];
+void numa_clear_node(unsigned int cpu);
+
+#ifdef CONFIG_DEBUG_PER_CPU_MAPS
+const struct cpumask *cpumask_of_node(int node);
+#else
+/* Returns a pointer to the cpumask of CPUs on Node 'node'. */
+static inline const struct cpumask *cpumask_of_node(int node)
+{
+	return node_to_cpumask_map[node];
+}
+#endif
+
+void __init arm64_numa_init(void);
+int __init numa_add_memblk(int nodeid, u64 start, u64 end);
+void __init numa_set_distance(int from, int to, int distance);
+void __init numa_free_distance(void);
+void __init early_map_cpu_to_node(unsigned int cpu, int nid);
+void numa_store_cpu_info(unsigned int cpu);
+
+#else	/* CONFIG_NUMA */
+
+static inline void numa_store_cpu_info(unsigned int cpu) { }
+static inline void arm64_numa_init(void) { }
+static inline void early_map_cpu_to_node(unsigned int cpu, int nid) { }
+
+#endif	/* CONFIG_NUMA */
+
+#endif	/* __ASM_NUMA_H */
--- zfcpdump-kernel-4.4.orig/arch/arm64/include/asm/opcodes.h
+++ zfcpdump-kernel-4.4/arch/arm64/include/asm/opcodes.h
@@ -1 +1,5 @@
+#ifdef CONFIG_CPU_BIG_ENDIAN
+#define CONFIG_CPU_ENDIAN_BE8 CONFIG_CPU_BIG_ENDIAN
+#endif
+
 #include <../../arm/include/asm/opcodes.h>
--- zfcpdump-kernel-4.4.orig/arch/arm64/include/asm/pgtable-hwdef.h
+++ zfcpdump-kernel-4.4/arch/arm64/include/asm/pgtable-hwdef.h
@@ -117,7 +117,6 @@
  * Section
  */
 #define PMD_SECT_VALID		(_AT(pmdval_t, 1) << 0)
-#define PMD_SECT_PROT_NONE	(_AT(pmdval_t, 1) << 58)
 #define PMD_SECT_USER		(_AT(pmdval_t, 1) << 6)		/* AP[1] */
 #define PMD_SECT_RDONLY		(_AT(pmdval_t, 1) << 7)		/* AP[2] */
 #define PMD_SECT_S		(_AT(pmdval_t, 3) << 8)
--- zfcpdump-kernel-4.4.orig/arch/arm64/include/asm/pgtable.h
+++ zfcpdump-kernel-4.4/arch/arm64/include/asm/pgtable.h
@@ -34,7 +34,7 @@
 /*
  * VMALLOC and SPARSEMEM_VMEMMAP ranges.
  *
- * VMEMAP_SIZE: allows the whole VA space to be covered by a struct page array
+ * VMEMAP_SIZE: allows the whole linear region to be covered by a struct page array
  *	(rounded up to PUD_SIZE).
  * VMALLOC_START: beginning of the kernel VA space
  * VMALLOC_END: extends to the available space below vmmemmap, PCI I/O space,
@@ -51,7 +51,9 @@
 
 #define VMALLOC_END		(PAGE_OFFSET - PUD_SIZE - VMEMMAP_SIZE - SZ_64K)
 
-#define vmemmap			((struct page *)(VMALLOC_END + SZ_64K))
+#define VMEMMAP_START		(VMALLOC_END + SZ_64K)
+#define vmemmap			((struct page *)VMEMMAP_START - \
+				 SECTION_ALIGN_DOWN(memstart_addr >> PAGE_SHIFT))
 
 #define FIRST_USER_ADDRESS	0UL
 
@@ -67,11 +69,11 @@ extern void __pgd_error(const char *file
 #define PROT_DEFAULT		(PTE_TYPE_PAGE | PTE_AF | PTE_SHARED)
 #define PROT_SECT_DEFAULT	(PMD_TYPE_SECT | PMD_SECT_AF | PMD_SECT_S)
 
-#define PROT_DEVICE_nGnRnE	(PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_ATTRINDX(MT_DEVICE_nGnRnE))
-#define PROT_DEVICE_nGnRE	(PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_ATTRINDX(MT_DEVICE_nGnRE))
-#define PROT_NORMAL_NC		(PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_ATTRINDX(MT_NORMAL_NC))
-#define PROT_NORMAL_WT		(PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_ATTRINDX(MT_NORMAL_WT))
-#define PROT_NORMAL		(PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_ATTRINDX(MT_NORMAL))
+#define PROT_DEVICE_nGnRnE	(PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_DIRTY | PTE_WRITE | PTE_ATTRINDX(MT_DEVICE_nGnRnE))
+#define PROT_DEVICE_nGnRE	(PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_DIRTY | PTE_WRITE | PTE_ATTRINDX(MT_DEVICE_nGnRE))
+#define PROT_NORMAL_NC		(PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_DIRTY | PTE_WRITE | PTE_ATTRINDX(MT_NORMAL_NC))
+#define PROT_NORMAL_WT		(PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_DIRTY | PTE_WRITE | PTE_ATTRINDX(MT_NORMAL_WT))
+#define PROT_NORMAL		(PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_DIRTY | PTE_WRITE | PTE_ATTRINDX(MT_NORMAL))
 
 #define PROT_SECT_DEVICE_nGnRE	(PROT_SECT_DEFAULT | PMD_SECT_PXN | PMD_SECT_UXN | PMD_ATTRINDX(MT_DEVICE_nGnRE))
 #define PROT_SECT_NORMAL	(PROT_SECT_DEFAULT | PMD_SECT_PXN | PMD_SECT_UXN | PMD_ATTRINDX(MT_NORMAL))
@@ -81,7 +83,7 @@ extern void __pgd_error(const char *file
 
 #define PAGE_KERNEL		__pgprot(_PAGE_DEFAULT | PTE_PXN | PTE_UXN | PTE_DIRTY | PTE_WRITE)
 #define PAGE_KERNEL_RO		__pgprot(_PAGE_DEFAULT | PTE_PXN | PTE_UXN | PTE_DIRTY | PTE_RDONLY)
-#define PAGE_KERNEL_ROX	__pgprot(_PAGE_DEFAULT | PTE_UXN | PTE_DIRTY | PTE_RDONLY)
+#define PAGE_KERNEL_ROX		__pgprot(_PAGE_DEFAULT | PTE_UXN | PTE_DIRTY | PTE_RDONLY)
 #define PAGE_KERNEL_EXEC	__pgprot(_PAGE_DEFAULT | PTE_UXN | PTE_DIRTY | PTE_WRITE)
 #define PAGE_KERNEL_EXEC_CONT	__pgprot(_PAGE_DEFAULT | PTE_UXN | PTE_DIRTY | PTE_WRITE | PTE_CONT)
 
@@ -153,6 +155,7 @@ extern struct page *empty_zero_page;
 #define pte_write(pte)		(!!(pte_val(pte) & PTE_WRITE))
 #define pte_exec(pte)		(!(pte_val(pte) & PTE_UXN))
 #define pte_cont(pte)		(!!(pte_val(pte) & PTE_CONT))
+#define pte_user(pte)		(!!(pte_val(pte) & PTE_USER))
 
 #ifdef CONFIG_ARM64_HW_AFDBM
 #define pte_hw_dirty(pte)	(pte_write(pte) && !(pte_val(pte) & PTE_RDONLY))
@@ -163,8 +166,6 @@ extern struct page *empty_zero_page;
 #define pte_dirty(pte)		(pte_sw_dirty(pte) || pte_hw_dirty(pte))
 
 #define pte_valid(pte)		(!!(pte_val(pte) & PTE_VALID))
-#define pte_valid_user(pte) \
-	((pte_val(pte) & (PTE_VALID | PTE_USER)) == (PTE_VALID | PTE_USER))
 #define pte_valid_not_user(pte) \
 	((pte_val(pte) & (PTE_VALID | PTE_USER)) == PTE_VALID)
 
@@ -262,13 +263,13 @@ extern void __sync_icache_dcache(pte_t p
 static inline void set_pte_at(struct mm_struct *mm, unsigned long addr,
 			      pte_t *ptep, pte_t pte)
 {
-	if (pte_valid_user(pte)) {
-		if (!pte_special(pte) && pte_exec(pte))
-			__sync_icache_dcache(pte, addr);
+	if (pte_present(pte)) {
 		if (pte_sw_dirty(pte) && pte_write(pte))
 			pte_val(pte) &= ~PTE_RDONLY;
 		else
 			pte_val(pte) |= PTE_RDONLY;
+		if (pte_user(pte) && pte_exec(pte) && !pte_special(pte))
+			__sync_icache_dcache(pte, addr);
 	}
 
 	/*
@@ -331,6 +332,21 @@ static inline pgprot_t mk_sect_prot(pgpr
 	return __pgprot(pgprot_val(prot) & ~PTE_TABLE_BIT);
 }
 
+#ifdef CONFIG_NUMA_BALANCING
+/*
+ * See the comment in include/asm-generic/pgtable.h
+ */
+static inline int pte_protnone(pte_t pte)
+{
+	return (pte_val(pte) & (PTE_VALID | PTE_PROT_NONE)) == PTE_PROT_NONE;
+}
+
+static inline int pmd_protnone(pmd_t pmd)
+{
+	return pte_protnone(pmd_pte(pmd));
+}
+#endif
+
 /*
  * THP definitions.
  */
@@ -346,6 +362,7 @@ void pmdp_splitting_flush(struct vm_area
 #endif /* CONFIG_HAVE_RCU_TABLE_FREE */
 #endif /* CONFIG_TRANSPARENT_HUGEPAGE */
 
+#define pmd_present(pmd)	pte_present(pmd_pte(pmd))
 #define pmd_dirty(pmd)		pte_dirty(pmd_pte(pmd))
 #define pmd_young(pmd)		pte_young(pmd_pte(pmd))
 #define pmd_wrprotect(pmd)	pte_pmd(pte_wrprotect(pmd_pte(pmd)))
@@ -354,7 +371,7 @@ void pmdp_splitting_flush(struct vm_area
 #define pmd_mkwrite(pmd)	pte_pmd(pte_mkwrite(pmd_pte(pmd)))
 #define pmd_mkdirty(pmd)	pte_pmd(pte_mkdirty(pmd_pte(pmd)))
 #define pmd_mkyoung(pmd)	pte_pmd(pte_mkyoung(pmd_pte(pmd)))
-#define pmd_mknotpresent(pmd)	(__pmd(pmd_val(pmd) & ~PMD_TYPE_MASK))
+#define pmd_mknotpresent(pmd)	(__pmd(pmd_val(pmd) & ~PMD_SECT_VALID))
 
 #define __HAVE_ARCH_PMD_WRITE
 #define pmd_write(pmd)		pte_write(pmd_pte(pmd))
@@ -393,7 +410,6 @@ extern pgprot_t phys_mem_access_prot(str
 				     unsigned long size, pgprot_t vma_prot);
 
 #define pmd_none(pmd)		(!pmd_val(pmd))
-#define pmd_present(pmd)	(pmd_val(pmd))
 
 #define pmd_bad(pmd)		(!(pmd_val(pmd) & 2))
 
@@ -537,6 +553,21 @@ static inline pmd_t pmd_modify(pmd_t pmd
 }
 
 #ifdef CONFIG_ARM64_HW_AFDBM
+#define __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS
+extern int ptep_set_access_flags(struct vm_area_struct *vma,
+				 unsigned long address, pte_t *ptep,
+				 pte_t entry, int dirty);
+
+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
+#define __HAVE_ARCH_PMDP_SET_ACCESS_FLAGS
+static inline int pmdp_set_access_flags(struct vm_area_struct *vma,
+					unsigned long address, pmd_t *pmdp,
+					pmd_t entry, int dirty)
+{
+	return ptep_set_access_flags(vma, address, (pte_t *)pmdp, pmd_pte(entry), dirty);
+}
+#endif
+
 /*
  * Atomic pte/pmd modifications.
  */
@@ -589,9 +620,9 @@ static inline pte_t ptep_get_and_clear(s
 }
 
 #ifdef CONFIG_TRANSPARENT_HUGEPAGE
-#define __HAVE_ARCH_PMDP_GET_AND_CLEAR
-static inline pmd_t pmdp_get_and_clear(struct mm_struct *mm,
-				       unsigned long address, pmd_t *pmdp)
+#define __HAVE_ARCH_PMDP_HUGE_GET_AND_CLEAR
+static inline pmd_t pmdp_huge_get_and_clear(struct mm_struct *mm,
+					    unsigned long address, pmd_t *pmdp)
 {
 	return pte_pmd(ptep_get_and_clear(mm, address, (pte_t *)pmdp));
 }
@@ -639,6 +670,7 @@ extern pgd_t idmap_pg_dir[PTRS_PER_PGD];
  *	bits 0-1:	present (must be zero)
  *	bits 2-7:	swap type
  *	bits 8-57:	swap offset
+ *	bit  58:	PTE_PROT_NONE (must be zero)
  */
 #define __SWP_TYPE_SHIFT	2
 #define __SWP_TYPE_BITS		6
--- zfcpdump-kernel-4.4.orig/arch/arm64/include/asm/processor.h
+++ zfcpdump-kernel-4.4/arch/arm64/include/asm/processor.h
@@ -29,8 +29,10 @@
 
 #include <linux/string.h>
 
+#include <asm/alternative.h>
 #include <asm/fpsimd.h>
 #include <asm/hw_breakpoint.h>
+#include <asm/lse.h>
 #include <asm/pgtable-hwdef.h>
 #include <asm/ptrace.h>
 #include <asm/types.h>
@@ -177,9 +179,11 @@ static inline void prefetchw(const void
 }
 
 #define ARCH_HAS_SPINLOCK_PREFETCH
-static inline void spin_lock_prefetch(const void *x)
+static inline void spin_lock_prefetch(const void *ptr)
 {
-	prefetchw(x);
+	asm volatile(ARM64_LSE_ATOMIC_INSN(
+		     "prfm pstl1strm, %a0",
+		     "nop") : : "p" (ptr));
 }
 
 #define HAVE_ARCH_PICK_MMAP_LAYOUT
--- zfcpdump-kernel-4.4.orig/arch/arm64/include/asm/ptrace.h
+++ zfcpdump-kernel-4.4/arch/arm64/include/asm/ptrace.h
@@ -58,6 +58,7 @@
 #define COMPAT_PSR_Z_BIT	0x40000000
 #define COMPAT_PSR_N_BIT	0x80000000
 #define COMPAT_PSR_IT_MASK	0x0600fc00	/* If-Then execution state mask */
+#define COMPAT_PSR_GE_MASK	0x000f0000
 
 #ifdef CONFIG_CPU_BIG_ENDIAN
 #define COMPAT_PSR_ENDSTATE	COMPAT_PSR_E_BIT
@@ -116,6 +117,8 @@ struct pt_regs {
 	};
 	u64 orig_x0;
 	u64 syscallno;
+	u64 orig_addr_limit;
+	u64 unused;	// maintain 16 byte alignment
 };
 
 #define arch_has_single_step()	(1)
@@ -151,35 +154,9 @@ static inline unsigned long regs_return_
 	return regs->regs[0];
 }
 
-/*
- * Are the current registers suitable for user mode? (used to maintain
- * security in signal handlers)
- */
-static inline int valid_user_regs(struct user_pt_regs *regs)
-{
-	if (user_mode(regs) && (regs->pstate & PSR_I_BIT) == 0) {
-		regs->pstate &= ~(PSR_F_BIT | PSR_A_BIT);
-
-		/* The T bit is reserved for AArch64 */
-		if (!(regs->pstate & PSR_MODE32_BIT))
-			regs->pstate &= ~COMPAT_PSR_T_BIT;
-
-		return 1;
-	}
-
-	/*
-	 * Force PSR to something logical...
-	 */
-	regs->pstate &= PSR_f | PSR_s | (PSR_x & ~PSR_A_BIT) | \
-			COMPAT_PSR_T_BIT | PSR_MODE32_BIT;
-
-	if (!(regs->pstate & PSR_MODE32_BIT)) {
-		regs->pstate &= ~COMPAT_PSR_T_BIT;
-		regs->pstate |= PSR_MODE_EL0t;
-	}
-
-	return 0;
-}
+/* We must avoid circular header include via sched.h */
+struct task_struct;
+int valid_user_regs(struct user_pt_regs *regs, struct task_struct *task);
 
 #define instruction_pointer(regs)	((unsigned long)(regs)->pc)
 
--- zfcpdump-kernel-4.4.orig/arch/arm64/include/asm/smp.h
+++ zfcpdump-kernel-4.4/arch/arm64/include/asm/smp.h
@@ -64,6 +64,15 @@ extern void secondary_entry(void);
 extern void arch_send_call_function_single_ipi(int cpu);
 extern void arch_send_call_function_ipi_mask(const struct cpumask *mask);
 
+#ifdef CONFIG_ARM64_ACPI_PARKING_PROTOCOL
+extern void arch_send_wakeup_ipi_mask(const struct cpumask *mask);
+#else
+static inline void arch_send_wakeup_ipi_mask(const struct cpumask *mask)
+{
+	BUILD_BUG();
+}
+#endif
+
 extern int __cpu_disable(void);
 
 extern void __cpu_die(unsigned int cpu);
--- zfcpdump-kernel-4.4.orig/arch/arm64/include/asm/spinlock.h
+++ zfcpdump-kernel-4.4/arch/arm64/include/asm/spinlock.h
@@ -312,4 +312,14 @@ static inline int arch_read_trylock(arch
 #define arch_read_relax(lock)	cpu_relax()
 #define arch_write_relax(lock)	cpu_relax()
 
+/*
+ * Accesses appearing in program order before a spin_lock() operation
+ * can be reordered with accesses inside the critical section, by virtue
+ * of arch_spin_lock being constructed using acquire semantics.
+ *
+ * In cases where this is problematic (e.g. try_to_wake_up), an
+ * smp_mb__before_spinlock() can restore the required ordering.
+ */
+#define smp_mb__before_spinlock()	smp_mb()
+
 #endif /* __ASM_SPINLOCK_H */
--- zfcpdump-kernel-4.4.orig/arch/arm64/include/asm/topology.h
+++ zfcpdump-kernel-4.4/arch/arm64/include/asm/topology.h
@@ -22,6 +22,16 @@ void init_cpu_topology(void);
 void store_cpu_topology(unsigned int cpuid);
 const struct cpumask *cpu_coregroup_mask(int cpu);
 
+#ifdef CONFIG_NUMA
+
+struct pci_bus;
+int pcibus_to_node(struct pci_bus *bus);
+#define cpumask_of_pcibus(bus)	(pcibus_to_node(bus) == -1 ?		\
+				 cpu_all_mask :				\
+				 cpumask_of_node(pcibus_to_node(bus)))
+
+#endif /* CONFIG_NUMA */
+
 #include <asm-generic/topology.h>
 
 #endif /* _ASM_ARM_TOPOLOGY_H */
--- zfcpdump-kernel-4.4.orig/arch/arm64/include/uapi/asm/auxvec.h
+++ zfcpdump-kernel-4.4/arch/arm64/include/uapi/asm/auxvec.h
@@ -19,4 +19,6 @@
 /* vDSO location */
 #define AT_SYSINFO_EHDR	33
 
+#define AT_VECTOR_SIZE_ARCH 1 /* entries in ARCH_DLINFO */
+
 #endif
--- zfcpdump-kernel-4.4.orig/arch/arm64/kernel/Makefile
+++ zfcpdump-kernel-4.4/arch/arm64/kernel/Makefile
@@ -41,6 +41,7 @@ arm64-obj-$(CONFIG_EFI)			+= efi.o efi-e
 arm64-obj-$(CONFIG_PCI)			+= pci.o
 arm64-obj-$(CONFIG_ARMV8_DEPRECATED)	+= armv8_deprecated.o
 arm64-obj-$(CONFIG_ACPI)		+= acpi.o
+arm64-obj-$(CONFIG_ARM64_ACPI_PARKING_PROTOCOL)	+= acpi_parking_protocol.o
 
 obj-y					+= $(arm64-obj-y) vdso/
 obj-m					+= $(arm64-obj-m)
--- /dev/null
+++ zfcpdump-kernel-4.4/arch/arm64/kernel/acpi_parking_protocol.c
@@ -0,0 +1,153 @@
+/*
+ * ARM64 ACPI Parking Protocol implementation
+ *
+ * Authors: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
+ *	    Mark Salter <msalter@redhat.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#include <linux/acpi.h>
+#include <linux/types.h>
+
+#include <asm/cpu_ops.h>
+
+struct cpu_mailbox_entry {
+	phys_addr_t mailbox_addr;
+	u8 version;
+	u8 gic_cpu_id;
+};
+
+static struct cpu_mailbox_entry cpu_mailbox_entries[NR_CPUS];
+
+void __init acpi_set_mailbox_entry(int cpu,
+				   struct acpi_madt_generic_interrupt *p)
+{
+	struct cpu_mailbox_entry *cpu_entry = &cpu_mailbox_entries[cpu];
+
+	cpu_entry->mailbox_addr = p->parked_address;
+	cpu_entry->version = p->parking_version;
+	cpu_entry->gic_cpu_id = p->cpu_interface_number;
+}
+
+bool acpi_parking_protocol_valid(int cpu)
+{
+	struct cpu_mailbox_entry *cpu_entry = &cpu_mailbox_entries[cpu];
+
+	return cpu_entry->mailbox_addr && cpu_entry->version;
+}
+
+static int acpi_parking_protocol_cpu_init(unsigned int cpu)
+{
+	pr_debug("%s: ACPI parked addr=%llx\n", __func__,
+		  cpu_mailbox_entries[cpu].mailbox_addr);
+
+	return 0;
+}
+
+static int acpi_parking_protocol_cpu_prepare(unsigned int cpu)
+{
+	return 0;
+}
+
+struct parking_protocol_mailbox {
+	__le32 cpu_id;
+	__le32 reserved;
+	__le64 entry_point;
+};
+
+static int acpi_parking_protocol_cpu_boot(unsigned int cpu)
+{
+	struct cpu_mailbox_entry *cpu_entry = &cpu_mailbox_entries[cpu];
+	struct parking_protocol_mailbox __iomem *mailbox;
+	__le32 cpu_id;
+
+	/*
+	 * Map mailbox memory with attribute device nGnRE (ie ioremap -
+	 * this deviates from the parking protocol specifications since
+	 * the mailboxes are required to be mapped nGnRnE; the attribute
+	 * discrepancy is harmless insofar as the protocol specification
+	 * is concerned).
+	 * If the mailbox is mistakenly allocated in the linear mapping
+	 * by FW ioremap will fail since the mapping will be prevented
+	 * by the kernel (it clashes with the linear mapping attributes
+	 * specifications).
+	 */
+	mailbox = ioremap(cpu_entry->mailbox_addr, sizeof(*mailbox));
+	if (!mailbox)
+		return -EIO;
+
+	cpu_id = readl_relaxed(&mailbox->cpu_id);
+	/*
+	 * Check if firmware has set-up the mailbox entry properly
+	 * before kickstarting the respective cpu.
+	 */
+	if (cpu_id != ~0U) {
+		iounmap(mailbox);
+		return -ENXIO;
+	}
+
+	/*
+	 * We write the entry point and cpu id as LE regardless of the
+	 * native endianness of the kernel. Therefore, any boot-loaders
+	 * that read this address need to convert this address to the
+	 * Boot-Loader's endianness before jumping.
+	 */
+	writeq_relaxed(__pa(secondary_entry), &mailbox->entry_point);
+	writel_relaxed(cpu_entry->gic_cpu_id, &mailbox->cpu_id);
+
+	arch_send_wakeup_ipi_mask(cpumask_of(cpu));
+
+	iounmap(mailbox);
+
+	return 0;
+}
+
+static void acpi_parking_protocol_cpu_postboot(void)
+{
+	int cpu = smp_processor_id();
+	struct cpu_mailbox_entry *cpu_entry = &cpu_mailbox_entries[cpu];
+	struct parking_protocol_mailbox __iomem *mailbox;
+	__le64 entry_point;
+
+	/*
+	 * Map mailbox memory with attribute device nGnRE (ie ioremap -
+	 * this deviates from the parking protocol specifications since
+	 * the mailboxes are required to be mapped nGnRnE; the attribute
+	 * discrepancy is harmless insofar as the protocol specification
+	 * is concerned).
+	 * If the mailbox is mistakenly allocated in the linear mapping
+	 * by FW ioremap will fail since the mapping will be prevented
+	 * by the kernel (it clashes with the linear mapping attributes
+	 * specifications).
+	 */
+	mailbox = ioremap(cpu_entry->mailbox_addr, sizeof(*mailbox));
+	if (!mailbox)
+		return;
+
+	entry_point = readl_relaxed(&mailbox->entry_point);
+	/*
+	 * Check if firmware has cleared the entry_point as expected
+	 * by the protocol specification.
+	 */
+	WARN_ON(entry_point);
+
+	iounmap(mailbox);
+}
+
+const struct cpu_operations acpi_parking_protocol_ops = {
+	.name		= "parking-protocol",
+	.cpu_init	= acpi_parking_protocol_cpu_init,
+	.cpu_prepare	= acpi_parking_protocol_cpu_prepare,
+	.cpu_boot	= acpi_parking_protocol_cpu_boot,
+	.cpu_postboot	= acpi_parking_protocol_cpu_postboot
+};
--- zfcpdump-kernel-4.4.orig/arch/arm64/kernel/asm-offsets.c
+++ zfcpdump-kernel-4.4/arch/arm64/kernel/asm-offsets.c
@@ -58,6 +58,7 @@ int main(void)
   DEFINE(S_PC,			offsetof(struct pt_regs, pc));
   DEFINE(S_ORIG_X0,		offsetof(struct pt_regs, orig_x0));
   DEFINE(S_SYSCALLNO,		offsetof(struct pt_regs, syscallno));
+  DEFINE(S_ORIG_ADDR_LIMIT,	offsetof(struct pt_regs, orig_addr_limit));
   DEFINE(S_FRAME_SIZE,		sizeof(struct pt_regs));
   BLANK();
   DEFINE(MM_CONTEXT_ID,		offsetof(struct mm_struct, context.id.counter));
--- zfcpdump-kernel-4.4.orig/arch/arm64/kernel/cpu_errata.c
+++ zfcpdump-kernel-4.4/arch/arm64/kernel/cpu_errata.c
@@ -21,24 +21,12 @@
 #include <asm/cputype.h>
 #include <asm/cpufeature.h>
 
-#define MIDR_CORTEX_A53 MIDR_CPU_PART(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A53)
-#define MIDR_CORTEX_A57 MIDR_CPU_PART(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A57)
-#define MIDR_THUNDERX	MIDR_CPU_PART(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX)
-
-#define CPU_MODEL_MASK (MIDR_IMPLEMENTOR_MASK | MIDR_PARTNUM_MASK | \
-			MIDR_ARCHITECTURE_MASK)
-
 static bool __maybe_unused
 is_affected_midr_range(const struct arm64_cpu_capabilities *entry)
 {
-	u32 midr = read_cpuid_id();
-
-	if ((midr & CPU_MODEL_MASK) != entry->midr_model)
-		return false;
-
-	midr &= MIDR_REVISION_MASK | MIDR_VARIANT_MASK;
-
-	return (midr >= entry->midr_range_min && midr <= entry->midr_range_max);
+	return MIDR_IS_CPU_MODEL_RANGE(read_cpuid_id(), entry->midr_model,
+				       entry->midr_range_min,
+				       entry->midr_range_max);
 }
 
 #define MIDR_RANGE(model, min, max) \
@@ -100,6 +88,15 @@ const struct arm64_cpu_capabilities arm6
 		MIDR_RANGE(MIDR_THUNDERX, 0x00, 0x01),
 	},
 #endif
+#ifdef CONFIG_CAVIUM_ERRATUM_27456
+	{
+	/* Cavium ThunderX, T88 pass 1.x - 2.1 */
+		.desc = "Cavium erratum 27456",
+		.capability = ARM64_WORKAROUND_CAVIUM_27456,
+		MIDR_RANGE(MIDR_THUNDERX, 0x00,
+			   (1 << MIDR_VARIANT_SHIFT) | 1),
+	},
+#endif
 	{
 	}
 };
--- zfcpdump-kernel-4.4.orig/arch/arm64/kernel/cpu_ops.c
+++ zfcpdump-kernel-4.4/arch/arm64/kernel/cpu_ops.c
@@ -25,19 +25,30 @@
 #include <asm/smp_plat.h>
 
 extern const struct cpu_operations smp_spin_table_ops;
+extern const struct cpu_operations acpi_parking_protocol_ops;
 extern const struct cpu_operations cpu_psci_ops;
 
 const struct cpu_operations *cpu_ops[NR_CPUS];
 
-static const struct cpu_operations *supported_cpu_ops[] __initconst = {
+static const struct cpu_operations *dt_supported_cpu_ops[] __initconst = {
 	&smp_spin_table_ops,
 	&cpu_psci_ops,
 	NULL,
 };
 
+static const struct cpu_operations *acpi_supported_cpu_ops[] __initconst = {
+#ifdef CONFIG_ARM64_ACPI_PARKING_PROTOCOL
+	&acpi_parking_protocol_ops,
+#endif
+	&cpu_psci_ops,
+	NULL,
+};
+
 static const struct cpu_operations * __init cpu_get_ops(const char *name)
 {
-	const struct cpu_operations **ops = supported_cpu_ops;
+	const struct cpu_operations **ops;
+
+	ops = acpi_disabled ? dt_supported_cpu_ops : acpi_supported_cpu_ops;
 
 	while (*ops) {
 		if (!strcmp(name, (*ops)->name))
@@ -75,8 +86,16 @@ static const char *__init cpu_read_enabl
 		}
 	} else {
 		enable_method = acpi_get_enable_method(cpu);
-		if (!enable_method)
-			pr_err("Unsupported ACPI enable-method\n");
+		if (!enable_method) {
+			/*
+			 * In ACPI systems the boot CPU does not require
+			 * checking the enable method since for some
+			 * boot protocol (ie parking protocol) it need not
+			 * be initialized. Don't warn spuriously.
+			 */
+			if (cpu != 0)
+				pr_err("Unsupported ACPI enable-method\n");
+		}
 	}
 
 	return enable_method;
--- zfcpdump-kernel-4.4.orig/arch/arm64/kernel/cpufeature.c
+++ zfcpdump-kernel-4.4/arch/arm64/kernel/cpufeature.c
@@ -621,6 +621,18 @@ static bool has_useable_gicv3_cpuif(cons
 	return has_sre;
 }
 
+static bool has_no_hw_prefetch(const struct arm64_cpu_capabilities *entry)
+{
+	u32 midr = read_cpuid_id();
+	u32 rv_min, rv_max;
+
+	/* Cavium ThunderX pass 1.x and 2.x */
+	rv_min = 0;
+	rv_max = (1 << MIDR_VARIANT_SHIFT) | MIDR_REVISION_MASK;
+
+	return MIDR_IS_CPU_MODEL_RANGE(midr, MIDR_THUNDERX, rv_min, rv_max);
+}
+
 static const struct arm64_cpu_capabilities arm64_features[] = {
 	{
 		.desc = "GIC system register CPU interface",
@@ -651,6 +663,11 @@ static const struct arm64_cpu_capabiliti
 		.min_field_value = 2,
 	},
 #endif /* CONFIG_AS_LSE && CONFIG_ARM64_LSE_ATOMICS */
+	{
+		.desc = "Software prefetching using PRFM",
+		.capability = ARM64_HAS_NO_HW_PREFETCH,
+		.matches = has_no_hw_prefetch,
+	},
 	{},
 };
 
--- zfcpdump-kernel-4.4.orig/arch/arm64/kernel/cpuinfo.c
+++ zfcpdump-kernel-4.4/arch/arm64/kernel/cpuinfo.c
@@ -22,6 +22,8 @@
 
 #include <linux/bitops.h>
 #include <linux/bug.h>
+#include <linux/compat.h>
+#include <linux/elf.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/personality.h>
@@ -85,7 +87,8 @@ static const char *const compat_hwcap_st
 	"idivt",
 	"vfpd32",
 	"lpae",
-	"evtstrm"
+	"evtstrm",
+	NULL
 };
 
 static const char *const compat_hwcap2_str[] = {
@@ -101,6 +104,7 @@ static const char *const compat_hwcap2_s
 static int c_show(struct seq_file *m, void *v)
 {
 	int i, j;
+	bool compat = personality(current->personality) == PER_LINUX32;
 
 	for_each_online_cpu(i) {
 		struct cpuinfo_arm64 *cpuinfo = &per_cpu(cpu_data, i);
@@ -112,6 +116,9 @@ static int c_show(struct seq_file *m, vo
 		 * "processor".  Give glibc what it expects.
 		 */
 		seq_printf(m, "processor\t: %d\n", i);
+		if (compat)
+			seq_printf(m, "model name\t: ARMv8 Processor rev %d (%s)\n",
+				   MIDR_REVISION(midr), COMPAT_ELF_PLATFORM);
 
 		seq_printf(m, "BogoMIPS\t: %lu.%02lu\n",
 			   loops_per_jiffy / (500000UL/HZ),
@@ -124,7 +131,7 @@ static int c_show(struct seq_file *m, vo
 		 * software which does already (at least for 32-bit).
 		 */
 		seq_puts(m, "Features\t:");
-		if (personality(current->personality) == PER_LINUX32) {
+		if (compat) {
 #ifdef CONFIG_COMPAT
 			for (j = 0; compat_hwcap_str[j]; j++)
 				if (compat_elf_hwcap & (1 << j))
--- zfcpdump-kernel-4.4.orig/arch/arm64/kernel/debug-monitors.c
+++ zfcpdump-kernel-4.4/arch/arm64/kernel/debug-monitors.c
@@ -152,7 +152,6 @@ static int debug_monitors_init(void)
 	/* Clear the OS lock. */
 	on_each_cpu(clear_os_lock, NULL, 1);
 	isb();
-	local_dbg_enable();
 
 	/* Register hotplug handler. */
 	__register_cpu_notifier(&os_lock_nb);
@@ -186,20 +185,21 @@ static void clear_regs_spsr_ss(struct pt
 
 /* EL1 Single Step Handler hooks */
 static LIST_HEAD(step_hook);
-static DEFINE_RWLOCK(step_hook_lock);
+static DEFINE_SPINLOCK(step_hook_lock);
 
 void register_step_hook(struct step_hook *hook)
 {
-	write_lock(&step_hook_lock);
-	list_add(&hook->node, &step_hook);
-	write_unlock(&step_hook_lock);
+	spin_lock(&step_hook_lock);
+	list_add_rcu(&hook->node, &step_hook);
+	spin_unlock(&step_hook_lock);
 }
 
 void unregister_step_hook(struct step_hook *hook)
 {
-	write_lock(&step_hook_lock);
-	list_del(&hook->node);
-	write_unlock(&step_hook_lock);
+	spin_lock(&step_hook_lock);
+	list_del_rcu(&hook->node);
+	spin_unlock(&step_hook_lock);
+	synchronize_rcu();
 }
 
 /*
@@ -213,15 +213,15 @@ static int call_step_hook(struct pt_regs
 	struct step_hook *hook;
 	int retval = DBG_HOOK_ERROR;
 
-	read_lock(&step_hook_lock);
+	rcu_read_lock();
 
-	list_for_each_entry(hook, &step_hook, node)	{
+	list_for_each_entry_rcu(hook, &step_hook, node)	{
 		retval = hook->fn(regs, esr);
 		if (retval == DBG_HOOK_HANDLED)
 			break;
 	}
 
-	read_unlock(&step_hook_lock);
+	rcu_read_unlock();
 
 	return retval;
 }
@@ -422,8 +422,10 @@ int kernel_active_single_step(void)
 /* ptrace API */
 void user_enable_single_step(struct task_struct *task)
 {
-	set_ti_thread_flag(task_thread_info(task), TIF_SINGLESTEP);
-	set_regs_spsr_ss(task_pt_regs(task));
+	struct thread_info *ti = task_thread_info(task);
+
+	if (!test_and_set_ti_thread_flag(ti, TIF_SINGLESTEP))
+		set_regs_spsr_ss(task_pt_regs(task));
 }
 
 void user_disable_single_step(struct task_struct *task)
--- zfcpdump-kernel-4.4.orig/arch/arm64/kernel/efi.c
+++ zfcpdump-kernel-4.4/arch/arm64/kernel/efi.c
@@ -168,6 +168,14 @@ static __init void reserve_regions(void)
 	if (efi_enabled(EFI_DBG))
 		pr_info("Processing EFI memory map:\n");
 
+	/*
+	 * Discard memblocks discovered so far: if there are any at this
+	 * point, they originate from memory nodes in the DT, and UEFI
+	 * uses its own memory map instead.
+	 */
+	memblock_dump_all();
+	memblock_remove(0, ULLONG_MAX);
+
 	for_each_efi_memory_desc(&memmap, md) {
 		paddr = md->phys_addr;
 		npages = md->num_pages;
--- zfcpdump-kernel-4.4.orig/arch/arm64/kernel/entry.S
+++ zfcpdump-kernel-4.4/arch/arm64/kernel/entry.S
@@ -27,6 +27,7 @@
 #include <asm/cpufeature.h>
 #include <asm/errno.h>
 #include <asm/esr.h>
+#include <asm/memory.h>
 #include <asm/thread_info.h>
 #include <asm/unistd.h>
 
@@ -93,7 +94,13 @@
 	disable_step_tsk x19, x20		// exceptions when scheduling.
 	.else
 	add	x21, sp, #S_FRAME_SIZE
-	.endif
+	get_thread_info tsk
+	/* Save the task's original addr_limit and set USER_DS (TASK_SIZE_64) */
+	ldr	x20, [tsk, #TI_ADDR_LIMIT]
+	str	x20, [sp, #S_ORIG_ADDR_LIMIT]
+	mov	x20, #TASK_SIZE_64
+	str	x20, [tsk, #TI_ADDR_LIMIT]
+	.endif /* \el == 0 */
 	mrs	x22, elr_el1
 	mrs	x23, spsr_el1
 	stp	lr, x21, [sp, #S_LR]
@@ -117,6 +124,12 @@
 	.endm
 
 	.macro	kernel_exit, el
+	.if	\el != 0
+	/* Restore the task's original addr_limit. */
+	ldr	x20, [sp, #S_ORIG_ADDR_LIMIT]
+	str	x20, [tsk, #TI_ADDR_LIMIT]
+	.endif
+
 	ldp	x21, x22, [sp, #S_PC]		// load ELR, SPSR
 	.if	\el == 0
 	ct_user_enter
--- zfcpdump-kernel-4.4.orig/arch/arm64/kernel/head.S
+++ zfcpdump-kernel-4.4/arch/arm64/kernel/head.S
@@ -512,9 +512,14 @@ CPU_LE(	movk	x0, #0x30d0, lsl #16	)	// C
 #endif
 
 	/* EL2 debug */
+	mrs	x0, id_aa64dfr0_el1		// Check ID_AA64DFR0_EL1 PMUVer
+	sbfx	x0, x0, #8, #4
+	cmp	x0, #1
+	b.lt	4f				// Skip if no PMU present
 	mrs	x0, pmcr_el0			// Disable debug access traps
 	ubfx	x0, x0, #11, #5			// to EL2 and allow access to
 	msr	mdcr_el2, x0			// all PMU counters from EL1
+4:
 
 	/* Stage-2 translation */
 	msr	vttbr_el2, xzr
--- zfcpdump-kernel-4.4.orig/arch/arm64/kernel/pci.c
+++ zfcpdump-kernel-4.4/arch/arm64/kernel/pci.c
@@ -76,6 +76,16 @@ int raw_pci_write(unsigned int domain, u
 	return -ENXIO;
 }
 
+#ifdef CONFIG_NUMA
+
+int pcibus_to_node(struct pci_bus *bus)
+{
+	return dev_to_node(&bus->dev);
+}
+EXPORT_SYMBOL(pcibus_to_node);
+
+#endif
+
 #ifdef CONFIG_ACPI
 /* Root bridge scanning */
 struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root)
--- zfcpdump-kernel-4.4.orig/arch/arm64/kernel/perf_event.c
+++ zfcpdump-kernel-4.4/arch/arm64/kernel/perf_event.c
@@ -29,60 +29,83 @@
  * ARMv8 PMUv3 Performance Events handling code.
  * Common event types.
  */
-enum armv8_pmuv3_perf_types {
-	/* Required events. */
-	ARMV8_PMUV3_PERFCTR_PMNC_SW_INCR			= 0x00,
-	ARMV8_PMUV3_PERFCTR_L1_DCACHE_REFILL			= 0x03,
-	ARMV8_PMUV3_PERFCTR_L1_DCACHE_ACCESS			= 0x04,
-	ARMV8_PMUV3_PERFCTR_PC_BRANCH_MIS_PRED			= 0x10,
-	ARMV8_PMUV3_PERFCTR_CLOCK_CYCLES			= 0x11,
-	ARMV8_PMUV3_PERFCTR_PC_BRANCH_PRED			= 0x12,
-
-	/* At least one of the following is required. */
-	ARMV8_PMUV3_PERFCTR_INSTR_EXECUTED			= 0x08,
-	ARMV8_PMUV3_PERFCTR_OP_SPEC				= 0x1B,
-
-	/* Common architectural events. */
-	ARMV8_PMUV3_PERFCTR_MEM_READ				= 0x06,
-	ARMV8_PMUV3_PERFCTR_MEM_WRITE				= 0x07,
-	ARMV8_PMUV3_PERFCTR_EXC_TAKEN				= 0x09,
-	ARMV8_PMUV3_PERFCTR_EXC_EXECUTED			= 0x0A,
-	ARMV8_PMUV3_PERFCTR_CID_WRITE				= 0x0B,
-	ARMV8_PMUV3_PERFCTR_PC_WRITE				= 0x0C,
-	ARMV8_PMUV3_PERFCTR_PC_IMM_BRANCH			= 0x0D,
-	ARMV8_PMUV3_PERFCTR_PC_PROC_RETURN			= 0x0E,
-	ARMV8_PMUV3_PERFCTR_MEM_UNALIGNED_ACCESS		= 0x0F,
-	ARMV8_PMUV3_PERFCTR_TTBR_WRITE				= 0x1C,
-
-	/* Common microarchitectural events. */
-	ARMV8_PMUV3_PERFCTR_L1_ICACHE_REFILL			= 0x01,
-	ARMV8_PMUV3_PERFCTR_ITLB_REFILL				= 0x02,
-	ARMV8_PMUV3_PERFCTR_DTLB_REFILL				= 0x05,
-	ARMV8_PMUV3_PERFCTR_MEM_ACCESS				= 0x13,
-	ARMV8_PMUV3_PERFCTR_L1_ICACHE_ACCESS			= 0x14,
-	ARMV8_PMUV3_PERFCTR_L1_DCACHE_WB			= 0x15,
-	ARMV8_PMUV3_PERFCTR_L2_CACHE_ACCESS			= 0x16,
-	ARMV8_PMUV3_PERFCTR_L2_CACHE_REFILL			= 0x17,
-	ARMV8_PMUV3_PERFCTR_L2_CACHE_WB				= 0x18,
-	ARMV8_PMUV3_PERFCTR_BUS_ACCESS				= 0x19,
-	ARMV8_PMUV3_PERFCTR_MEM_ERROR				= 0x1A,
-	ARMV8_PMUV3_PERFCTR_BUS_CYCLES				= 0x1D,
-};
+
+/* Required events. */
+#define ARMV8_PMUV3_PERFCTR_PMNC_SW_INCR			0x00
+#define ARMV8_PMUV3_PERFCTR_L1_DCACHE_REFILL			0x03
+#define ARMV8_PMUV3_PERFCTR_L1_DCACHE_ACCESS			0x04
+#define ARMV8_PMUV3_PERFCTR_PC_BRANCH_MIS_PRED			0x10
+#define ARMV8_PMUV3_PERFCTR_CLOCK_CYCLES			0x11
+#define ARMV8_PMUV3_PERFCTR_PC_BRANCH_PRED			0x12
+
+/* At least one of the following is required. */
+#define ARMV8_PMUV3_PERFCTR_INSTR_EXECUTED			0x08
+#define ARMV8_PMUV3_PERFCTR_OP_SPEC				0x1B
+
+/* Common architectural events. */
+#define ARMV8_PMUV3_PERFCTR_MEM_READ				0x06
+#define ARMV8_PMUV3_PERFCTR_MEM_WRITE				0x07
+#define ARMV8_PMUV3_PERFCTR_EXC_TAKEN				0x09
+#define ARMV8_PMUV3_PERFCTR_EXC_EXECUTED			0x0A
+#define ARMV8_PMUV3_PERFCTR_CID_WRITE				0x0B
+#define ARMV8_PMUV3_PERFCTR_PC_WRITE				0x0C
+#define ARMV8_PMUV3_PERFCTR_PC_IMM_BRANCH			0x0D
+#define ARMV8_PMUV3_PERFCTR_PC_PROC_RETURN			0x0E
+#define ARMV8_PMUV3_PERFCTR_MEM_UNALIGNED_ACCESS		0x0F
+#define ARMV8_PMUV3_PERFCTR_TTBR_WRITE				0x1C
+#define ARMV8_PMUV3_PERFCTR_CHAIN				0x1E
+#define ARMV8_PMUV3_PERFCTR_BR_RETIRED				0x21
+
+/* Common microarchitectural events. */
+#define ARMV8_PMUV3_PERFCTR_L1_ICACHE_REFILL			0x01
+#define ARMV8_PMUV3_PERFCTR_ITLB_REFILL				0x02
+#define ARMV8_PMUV3_PERFCTR_DTLB_REFILL				0x05
+#define ARMV8_PMUV3_PERFCTR_MEM_ACCESS				0x13
+#define ARMV8_PMUV3_PERFCTR_L1_ICACHE_ACCESS			0x14
+#define ARMV8_PMUV3_PERFCTR_L1_DCACHE_WB			0x15
+#define ARMV8_PMUV3_PERFCTR_L2_CACHE_ACCESS			0x16
+#define ARMV8_PMUV3_PERFCTR_L2_CACHE_REFILL			0x17
+#define ARMV8_PMUV3_PERFCTR_L2_CACHE_WB				0x18
+#define ARMV8_PMUV3_PERFCTR_BUS_ACCESS				0x19
+#define ARMV8_PMUV3_PERFCTR_MEM_ERROR				0x1A
+#define ARMV8_PMUV3_PERFCTR_BUS_CYCLES				0x1D
+#define ARMV8_PMUV3_PERFCTR_L1D_CACHE_ALLOCATE			0x1F
+#define ARMV8_PMUV3_PERFCTR_L2D_CACHE_ALLOCATE			0x20
+#define ARMV8_PMUV3_PERFCTR_BR_MIS_PRED_RETIRED			0x22
+#define ARMV8_PMUV3_PERFCTR_STALL_FRONTEND			0x23
+#define ARMV8_PMUV3_PERFCTR_STALL_BACKEND			0x24
+#define ARMV8_PMUV3_PERFCTR_L1D_TLB				0x25
+#define ARMV8_PMUV3_PERFCTR_L1I_TLB				0x26
+#define ARMV8_PMUV3_PERFCTR_L2I_CACHE				0x27
+#define ARMV8_PMUV3_PERFCTR_L2I_CACHE_REFILL			0x28
+#define ARMV8_PMUV3_PERFCTR_L3D_CACHE_ALLOCATE			0x29
+#define ARMV8_PMUV3_PERFCTR_L3D_CACHE_REFILL			0x2A
+#define ARMV8_PMUV3_PERFCTR_L3D_CACHE				0x2B
+#define ARMV8_PMUV3_PERFCTR_L3D_CACHE_WB			0x2C
+#define ARMV8_PMUV3_PERFCTR_L2D_TLB_REFILL			0x2D
+#define ARMV8_PMUV3_PERFCTR_L21_TLB_REFILL			0x2E
+#define ARMV8_PMUV3_PERFCTR_L2D_TLB				0x2F
+#define ARMV8_PMUV3_PERFCTR_L21_TLB				0x30
+
+/* ARMv8 implementation defined event types. */
+#define ARMV8_IMPDEF_PERFCTR_L1_DCACHE_ACCESS_LD		0x40
+#define ARMV8_IMPDEF_PERFCTR_L1_DCACHE_ACCESS_ST		0x41
+#define ARMV8_IMPDEF_PERFCTR_L1_DCACHE_REFILL_LD		0x42
+#define ARMV8_IMPDEF_PERFCTR_L1_DCACHE_REFILL_ST		0x43
+#define ARMV8_IMPDEF_PERFCTR_DTLB_REFILL_LD			0x4C
+#define ARMV8_IMPDEF_PERFCTR_DTLB_REFILL_ST			0x4D
+#define ARMV8_IMPDEF_PERFCTR_DTLB_ACCESS_LD			0x4E
+#define ARMV8_IMPDEF_PERFCTR_DTLB_ACCESS_ST			0x4F
 
 /* ARMv8 Cortex-A53 specific event types. */
-enum armv8_a53_pmu_perf_types {
-	ARMV8_A53_PERFCTR_PREFETCH_LINEFILL			= 0xC2,
-};
+#define ARMV8_A53_PERFCTR_PREFETCH_LINEFILL			0xC2
 
-/* ARMv8 Cortex-A57 specific event types. */
-enum armv8_a57_perf_types {
-	ARMV8_A57_PERFCTR_L1_DCACHE_ACCESS_LD			= 0x40,
-	ARMV8_A57_PERFCTR_L1_DCACHE_ACCESS_ST			= 0x41,
-	ARMV8_A57_PERFCTR_L1_DCACHE_REFILL_LD			= 0x42,
-	ARMV8_A57_PERFCTR_L1_DCACHE_REFILL_ST			= 0x43,
-	ARMV8_A57_PERFCTR_DTLB_REFILL_LD			= 0x4c,
-	ARMV8_A57_PERFCTR_DTLB_REFILL_ST			= 0x4d,
-};
+/* ARMv8 Cavium ThunderX specific event types. */
+#define ARMV8_THUNDER_PERFCTR_L1_DCACHE_MISS_ST			0xE9
+#define ARMV8_THUNDER_PERFCTR_L1_DCACHE_PREF_ACCESS		0xEA
+#define ARMV8_THUNDER_PERFCTR_L1_DCACHE_PREF_MISS		0xEB
+#define ARMV8_THUNDER_PERFCTR_L1_ICACHE_PREF_ACCESS		0xEC
+#define ARMV8_THUNDER_PERFCTR_L1_ICACHE_PREF_MISS		0xED
 
 /* PMUv3 HW events mapping. */
 static const unsigned armv8_pmuv3_perf_map[PERF_COUNT_HW_MAX] = {
@@ -116,6 +139,18 @@ static const unsigned armv8_a57_perf_map
 	[PERF_COUNT_HW_BUS_CYCLES]		= ARMV8_PMUV3_PERFCTR_BUS_CYCLES,
 };
 
+static const unsigned armv8_thunder_perf_map[PERF_COUNT_HW_MAX] = {
+	PERF_MAP_ALL_UNSUPPORTED,
+	[PERF_COUNT_HW_CPU_CYCLES]		= ARMV8_PMUV3_PERFCTR_CLOCK_CYCLES,
+	[PERF_COUNT_HW_INSTRUCTIONS]		= ARMV8_PMUV3_PERFCTR_INSTR_EXECUTED,
+	[PERF_COUNT_HW_CACHE_REFERENCES]	= ARMV8_PMUV3_PERFCTR_L1_DCACHE_ACCESS,
+	[PERF_COUNT_HW_CACHE_MISSES]		= ARMV8_PMUV3_PERFCTR_L1_DCACHE_REFILL,
+	[PERF_COUNT_HW_BRANCH_INSTRUCTIONS]	= ARMV8_PMUV3_PERFCTR_PC_WRITE,
+	[PERF_COUNT_HW_BRANCH_MISSES]		= ARMV8_PMUV3_PERFCTR_PC_BRANCH_MIS_PRED,
+	[PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = ARMV8_PMUV3_PERFCTR_STALL_FRONTEND,
+	[PERF_COUNT_HW_STALLED_CYCLES_BACKEND]	= ARMV8_PMUV3_PERFCTR_STALL_BACKEND,
+};
+
 static const unsigned armv8_pmuv3_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
 						[PERF_COUNT_HW_CACHE_OP_MAX]
 						[PERF_COUNT_HW_CACHE_RESULT_MAX] = {
@@ -159,16 +194,16 @@ static const unsigned armv8_a57_perf_cac
 					      [PERF_COUNT_HW_CACHE_RESULT_MAX] = {
 	PERF_CACHE_MAP_ALL_UNSUPPORTED,
 
-	[C(L1D)][C(OP_READ)][C(RESULT_ACCESS)]	= ARMV8_A57_PERFCTR_L1_DCACHE_ACCESS_LD,
-	[C(L1D)][C(OP_READ)][C(RESULT_MISS)]	= ARMV8_A57_PERFCTR_L1_DCACHE_REFILL_LD,
-	[C(L1D)][C(OP_WRITE)][C(RESULT_ACCESS)]	= ARMV8_A57_PERFCTR_L1_DCACHE_ACCESS_ST,
-	[C(L1D)][C(OP_WRITE)][C(RESULT_MISS)]	= ARMV8_A57_PERFCTR_L1_DCACHE_REFILL_ST,
+	[C(L1D)][C(OP_READ)][C(RESULT_ACCESS)]	= ARMV8_IMPDEF_PERFCTR_L1_DCACHE_ACCESS_LD,
+	[C(L1D)][C(OP_READ)][C(RESULT_MISS)]	= ARMV8_IMPDEF_PERFCTR_L1_DCACHE_REFILL_LD,
+	[C(L1D)][C(OP_WRITE)][C(RESULT_ACCESS)]	= ARMV8_IMPDEF_PERFCTR_L1_DCACHE_ACCESS_ST,
+	[C(L1D)][C(OP_WRITE)][C(RESULT_MISS)]	= ARMV8_IMPDEF_PERFCTR_L1_DCACHE_REFILL_ST,
 
 	[C(L1I)][C(OP_READ)][C(RESULT_ACCESS)]	= ARMV8_PMUV3_PERFCTR_L1_ICACHE_ACCESS,
 	[C(L1I)][C(OP_READ)][C(RESULT_MISS)]	= ARMV8_PMUV3_PERFCTR_L1_ICACHE_REFILL,
 
-	[C(DTLB)][C(OP_READ)][C(RESULT_MISS)]	= ARMV8_A57_PERFCTR_DTLB_REFILL_LD,
-	[C(DTLB)][C(OP_WRITE)][C(RESULT_MISS)]	= ARMV8_A57_PERFCTR_DTLB_REFILL_ST,
+	[C(DTLB)][C(OP_READ)][C(RESULT_MISS)]	= ARMV8_IMPDEF_PERFCTR_DTLB_REFILL_LD,
+	[C(DTLB)][C(OP_WRITE)][C(RESULT_MISS)]	= ARMV8_IMPDEF_PERFCTR_DTLB_REFILL_ST,
 
 	[C(ITLB)][C(OP_READ)][C(RESULT_MISS)]	= ARMV8_PMUV3_PERFCTR_ITLB_REFILL,
 
@@ -178,6 +213,166 @@ static const unsigned armv8_a57_perf_cac
 	[C(BPU)][C(OP_WRITE)][C(RESULT_MISS)]	= ARMV8_PMUV3_PERFCTR_PC_BRANCH_MIS_PRED,
 };
 
+static const unsigned armv8_thunder_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
+						   [PERF_COUNT_HW_CACHE_OP_MAX]
+						   [PERF_COUNT_HW_CACHE_RESULT_MAX] = {
+	PERF_CACHE_MAP_ALL_UNSUPPORTED,
+
+	[C(L1D)][C(OP_READ)][C(RESULT_ACCESS)]	= ARMV8_IMPDEF_PERFCTR_L1_DCACHE_ACCESS_LD,
+	[C(L1D)][C(OP_READ)][C(RESULT_MISS)]	= ARMV8_IMPDEF_PERFCTR_L1_DCACHE_REFILL_LD,
+	[C(L1D)][C(OP_WRITE)][C(RESULT_ACCESS)]	= ARMV8_IMPDEF_PERFCTR_L1_DCACHE_ACCESS_ST,
+	[C(L1D)][C(OP_WRITE)][C(RESULT_MISS)]	= ARMV8_THUNDER_PERFCTR_L1_DCACHE_MISS_ST,
+	[C(L1D)][C(OP_PREFETCH)][C(RESULT_ACCESS)] = ARMV8_THUNDER_PERFCTR_L1_DCACHE_PREF_ACCESS,
+	[C(L1D)][C(OP_PREFETCH)][C(RESULT_MISS)] = ARMV8_THUNDER_PERFCTR_L1_DCACHE_PREF_MISS,
+
+	[C(L1I)][C(OP_READ)][C(RESULT_ACCESS)]	= ARMV8_PMUV3_PERFCTR_L1_ICACHE_ACCESS,
+	[C(L1I)][C(OP_READ)][C(RESULT_MISS)]	= ARMV8_PMUV3_PERFCTR_L1_ICACHE_REFILL,
+	[C(L1I)][C(OP_PREFETCH)][C(RESULT_ACCESS)] = ARMV8_THUNDER_PERFCTR_L1_ICACHE_PREF_ACCESS,
+	[C(L1I)][C(OP_PREFETCH)][C(RESULT_MISS)] = ARMV8_THUNDER_PERFCTR_L1_ICACHE_PREF_MISS,
+
+	[C(DTLB)][C(OP_READ)][C(RESULT_ACCESS)]	= ARMV8_IMPDEF_PERFCTR_DTLB_ACCESS_LD,
+	[C(DTLB)][C(OP_READ)][C(RESULT_MISS)]	= ARMV8_IMPDEF_PERFCTR_DTLB_REFILL_LD,
+	[C(DTLB)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV8_IMPDEF_PERFCTR_DTLB_ACCESS_ST,
+	[C(DTLB)][C(OP_WRITE)][C(RESULT_MISS)]	= ARMV8_IMPDEF_PERFCTR_DTLB_REFILL_ST,
+
+	[C(ITLB)][C(OP_READ)][C(RESULT_MISS)]	= ARMV8_PMUV3_PERFCTR_ITLB_REFILL,
+
+	[C(BPU)][C(OP_READ)][C(RESULT_ACCESS)]	= ARMV8_PMUV3_PERFCTR_PC_BRANCH_PRED,
+	[C(BPU)][C(OP_READ)][C(RESULT_MISS)]	= ARMV8_PMUV3_PERFCTR_PC_BRANCH_MIS_PRED,
+	[C(BPU)][C(OP_WRITE)][C(RESULT_ACCESS)]	= ARMV8_PMUV3_PERFCTR_PC_BRANCH_PRED,
+	[C(BPU)][C(OP_WRITE)][C(RESULT_MISS)]	= ARMV8_PMUV3_PERFCTR_PC_BRANCH_MIS_PRED,
+};
+
+#define ARMV8_EVENT_ATTR_RESOLVE(m) #m
+#define ARMV8_EVENT_ATTR(name, config) \
+	PMU_EVENT_ATTR_STRING(name, armv8_event_attr_##name, \
+			      "event=" ARMV8_EVENT_ATTR_RESOLVE(config))
+
+ARMV8_EVENT_ATTR(sw_incr, ARMV8_PMUV3_PERFCTR_PMNC_SW_INCR);
+ARMV8_EVENT_ATTR(l1i_cache_refill, ARMV8_PMUV3_PERFCTR_L1_ICACHE_REFILL);
+ARMV8_EVENT_ATTR(l1i_tlb_refill, ARMV8_PMUV3_PERFCTR_ITLB_REFILL);
+ARMV8_EVENT_ATTR(l1d_cache_refill, ARMV8_PMUV3_PERFCTR_L1_DCACHE_REFILL);
+ARMV8_EVENT_ATTR(l1d_cache, ARMV8_PMUV3_PERFCTR_L1_DCACHE_ACCESS);
+ARMV8_EVENT_ATTR(l1d_tlb_refill, ARMV8_PMUV3_PERFCTR_DTLB_REFILL);
+ARMV8_EVENT_ATTR(ld_retired, ARMV8_PMUV3_PERFCTR_MEM_READ);
+ARMV8_EVENT_ATTR(st_retired, ARMV8_PMUV3_PERFCTR_MEM_WRITE);
+ARMV8_EVENT_ATTR(inst_retired, ARMV8_PMUV3_PERFCTR_INSTR_EXECUTED);
+ARMV8_EVENT_ATTR(exc_taken, ARMV8_PMUV3_PERFCTR_EXC_TAKEN);
+ARMV8_EVENT_ATTR(exc_return, ARMV8_PMUV3_PERFCTR_EXC_EXECUTED);
+ARMV8_EVENT_ATTR(cid_write_retired, ARMV8_PMUV3_PERFCTR_CID_WRITE);
+ARMV8_EVENT_ATTR(pc_write_retired, ARMV8_PMUV3_PERFCTR_PC_WRITE);
+ARMV8_EVENT_ATTR(br_immed_retired, ARMV8_PMUV3_PERFCTR_PC_IMM_BRANCH);
+ARMV8_EVENT_ATTR(br_return_retired, ARMV8_PMUV3_PERFCTR_PC_PROC_RETURN);
+ARMV8_EVENT_ATTR(unaligned_ldst_retired, ARMV8_PMUV3_PERFCTR_MEM_UNALIGNED_ACCESS);
+ARMV8_EVENT_ATTR(br_mis_pred, ARMV8_PMUV3_PERFCTR_PC_BRANCH_MIS_PRED);
+ARMV8_EVENT_ATTR(cpu_cycles, ARMV8_PMUV3_PERFCTR_CLOCK_CYCLES);
+ARMV8_EVENT_ATTR(br_pred, ARMV8_PMUV3_PERFCTR_PC_BRANCH_PRED);
+ARMV8_EVENT_ATTR(mem_access, ARMV8_PMUV3_PERFCTR_MEM_ACCESS);
+ARMV8_EVENT_ATTR(l1i_cache, ARMV8_PMUV3_PERFCTR_L1_ICACHE_ACCESS);
+ARMV8_EVENT_ATTR(l1d_cache_wb, ARMV8_PMUV3_PERFCTR_L1_DCACHE_WB);
+ARMV8_EVENT_ATTR(l2d_cache, ARMV8_PMUV3_PERFCTR_L2_CACHE_ACCESS);
+ARMV8_EVENT_ATTR(l2d_cache_refill, ARMV8_PMUV3_PERFCTR_L2_CACHE_REFILL);
+ARMV8_EVENT_ATTR(l2d_cache_wb, ARMV8_PMUV3_PERFCTR_L2_CACHE_WB);
+ARMV8_EVENT_ATTR(bus_access, ARMV8_PMUV3_PERFCTR_BUS_ACCESS);
+ARMV8_EVENT_ATTR(memory_error, ARMV8_PMUV3_PERFCTR_MEM_ERROR);
+ARMV8_EVENT_ATTR(inst_spec, ARMV8_PMUV3_PERFCTR_OP_SPEC);
+ARMV8_EVENT_ATTR(ttbr_write_retired, ARMV8_PMUV3_PERFCTR_TTBR_WRITE);
+ARMV8_EVENT_ATTR(bus_cycles, ARMV8_PMUV3_PERFCTR_BUS_CYCLES);
+ARMV8_EVENT_ATTR(chain, ARMV8_PMUV3_PERFCTR_CHAIN);
+ARMV8_EVENT_ATTR(l1d_cache_allocate, ARMV8_PMUV3_PERFCTR_L1D_CACHE_ALLOCATE);
+ARMV8_EVENT_ATTR(l2d_cache_allocate, ARMV8_PMUV3_PERFCTR_L2D_CACHE_ALLOCATE);
+ARMV8_EVENT_ATTR(br_retired, ARMV8_PMUV3_PERFCTR_BR_RETIRED);
+ARMV8_EVENT_ATTR(br_mis_pred_retired, ARMV8_PMUV3_PERFCTR_BR_MIS_PRED_RETIRED);
+ARMV8_EVENT_ATTR(stall_frontend, ARMV8_PMUV3_PERFCTR_STALL_FRONTEND);
+ARMV8_EVENT_ATTR(stall_backend, ARMV8_PMUV3_PERFCTR_STALL_BACKEND);
+ARMV8_EVENT_ATTR(l1d_tlb, ARMV8_PMUV3_PERFCTR_L1D_TLB);
+ARMV8_EVENT_ATTR(l1i_tlb, ARMV8_PMUV3_PERFCTR_L1I_TLB);
+ARMV8_EVENT_ATTR(l2i_cache, ARMV8_PMUV3_PERFCTR_L2I_CACHE);
+ARMV8_EVENT_ATTR(l2i_cache_refill, ARMV8_PMUV3_PERFCTR_L2I_CACHE_REFILL);
+ARMV8_EVENT_ATTR(l3d_cache_allocate, ARMV8_PMUV3_PERFCTR_L3D_CACHE_ALLOCATE);
+ARMV8_EVENT_ATTR(l3d_cache_refill, ARMV8_PMUV3_PERFCTR_L3D_CACHE_REFILL);
+ARMV8_EVENT_ATTR(l3d_cache, ARMV8_PMUV3_PERFCTR_L3D_CACHE);
+ARMV8_EVENT_ATTR(l3d_cache_wb, ARMV8_PMUV3_PERFCTR_L3D_CACHE_WB);
+ARMV8_EVENT_ATTR(l2d_tlb_refill, ARMV8_PMUV3_PERFCTR_L2D_TLB_REFILL);
+ARMV8_EVENT_ATTR(l21_tlb_refill, ARMV8_PMUV3_PERFCTR_L21_TLB_REFILL);
+ARMV8_EVENT_ATTR(l2d_tlb, ARMV8_PMUV3_PERFCTR_L2D_TLB);
+ARMV8_EVENT_ATTR(l21_tlb, ARMV8_PMUV3_PERFCTR_L21_TLB);
+
+static struct attribute *armv8_pmuv3_event_attrs[] = {
+	&armv8_event_attr_sw_incr.attr.attr,
+	&armv8_event_attr_l1i_cache_refill.attr.attr,
+	&armv8_event_attr_l1i_tlb_refill.attr.attr,
+	&armv8_event_attr_l1d_cache_refill.attr.attr,
+	&armv8_event_attr_l1d_cache.attr.attr,
+	&armv8_event_attr_l1d_tlb_refill.attr.attr,
+	&armv8_event_attr_ld_retired.attr.attr,
+	&armv8_event_attr_st_retired.attr.attr,
+	&armv8_event_attr_inst_retired.attr.attr,
+	&armv8_event_attr_exc_taken.attr.attr,
+	&armv8_event_attr_exc_return.attr.attr,
+	&armv8_event_attr_cid_write_retired.attr.attr,
+	&armv8_event_attr_pc_write_retired.attr.attr,
+	&armv8_event_attr_br_immed_retired.attr.attr,
+	&armv8_event_attr_br_return_retired.attr.attr,
+	&armv8_event_attr_unaligned_ldst_retired.attr.attr,
+	&armv8_event_attr_br_mis_pred.attr.attr,
+	&armv8_event_attr_cpu_cycles.attr.attr,
+	&armv8_event_attr_br_pred.attr.attr,
+	&armv8_event_attr_mem_access.attr.attr,
+	&armv8_event_attr_l1i_cache.attr.attr,
+	&armv8_event_attr_l1d_cache_wb.attr.attr,
+	&armv8_event_attr_l2d_cache.attr.attr,
+	&armv8_event_attr_l2d_cache_refill.attr.attr,
+	&armv8_event_attr_l2d_cache_wb.attr.attr,
+	&armv8_event_attr_bus_access.attr.attr,
+	&armv8_event_attr_memory_error.attr.attr,
+	&armv8_event_attr_inst_spec.attr.attr,
+	&armv8_event_attr_ttbr_write_retired.attr.attr,
+	&armv8_event_attr_bus_cycles.attr.attr,
+	&armv8_event_attr_chain.attr.attr,
+	&armv8_event_attr_l1d_cache_allocate.attr.attr,
+	&armv8_event_attr_l2d_cache_allocate.attr.attr,
+	&armv8_event_attr_br_retired.attr.attr,
+	&armv8_event_attr_br_mis_pred_retired.attr.attr,
+	&armv8_event_attr_stall_frontend.attr.attr,
+	&armv8_event_attr_stall_backend.attr.attr,
+	&armv8_event_attr_l1d_tlb.attr.attr,
+	&armv8_event_attr_l1i_tlb.attr.attr,
+	&armv8_event_attr_l2i_cache.attr.attr,
+	&armv8_event_attr_l2i_cache_refill.attr.attr,
+	&armv8_event_attr_l3d_cache_allocate.attr.attr,
+	&armv8_event_attr_l3d_cache_refill.attr.attr,
+	&armv8_event_attr_l3d_cache.attr.attr,
+	&armv8_event_attr_l3d_cache_wb.attr.attr,
+	&armv8_event_attr_l2d_tlb_refill.attr.attr,
+	&armv8_event_attr_l21_tlb_refill.attr.attr,
+	&armv8_event_attr_l2d_tlb.attr.attr,
+	&armv8_event_attr_l21_tlb.attr.attr,
+	NULL,
+};
+
+static struct attribute_group armv8_pmuv3_events_attr_group = {
+	.name = "events",
+	.attrs = armv8_pmuv3_event_attrs,
+};
+
+PMU_FORMAT_ATTR(event, "config:0-9");
+
+static struct attribute *armv8_pmuv3_format_attrs[] = {
+	&format_attr_event.attr,
+	NULL,
+};
+
+static struct attribute_group armv8_pmuv3_format_attr_group = {
+	.name = "format",
+	.attrs = armv8_pmuv3_format_attrs,
+};
+
+static const struct attribute_group *armv8_pmuv3_attr_groups[] = {
+	&armv8_pmuv3_events_attr_group,
+	&armv8_pmuv3_format_attr_group,
+	NULL,
+};
 
 /*
  * Perf Events' indices
@@ -209,6 +404,7 @@ static const unsigned armv8_a57_perf_cac
 #define ARMV8_PMCR_D		(1 << 3) /* CCNT counts every 64th cpu cycle */
 #define ARMV8_PMCR_X		(1 << 4) /* Export to ETM */
 #define ARMV8_PMCR_DP		(1 << 5) /* Disable CCNT if non-invasive debug*/
+#define ARMV8_PMCR_LC		(1 << 6) /* Overflow on 64 bit cycle counter */
 #define	ARMV8_PMCR_N_SHIFT	11	 /* Number of counters supported */
 #define	ARMV8_PMCR_N_MASK	0x1f
 #define	ARMV8_PMCR_MASK		0x3f	 /* Mask for writable bits */
@@ -222,8 +418,8 @@ static const unsigned armv8_a57_perf_cac
 /*
  * PMXEVTYPER: Event selection reg
  */
-#define	ARMV8_EVTYPE_MASK	0xc80003ff	/* Mask for writable bits */
-#define	ARMV8_EVTYPE_EVENT	0x3ff		/* Mask for EVENT bits */
+#define	ARMV8_EVTYPE_MASK	0xc800ffff	/* Mask for writable bits */
+#define	ARMV8_EVTYPE_EVENT	0xffff		/* Mask for EVENT bits */
 
 /*
  * Event filters for PMUv3
@@ -298,9 +494,16 @@ static inline void armv8pmu_write_counte
 	if (!armv8pmu_counter_valid(cpu_pmu, idx))
 		pr_err("CPU%u writing wrong counter %d\n",
 			smp_processor_id(), idx);
-	else if (idx == ARMV8_IDX_CYCLE_COUNTER)
-		asm volatile("msr pmccntr_el0, %0" :: "r" (value));
-	else if (armv8pmu_select_counter(idx) == idx)
+	else if (idx == ARMV8_IDX_CYCLE_COUNTER) {
+		/*
+		 * Set the upper 32bits as this is a 64bit counter but we only
+		 * count using the lower 32bits and we want an interrupt when
+		 * it overflows.
+		 */
+		u64 value64 = 0xffffffff00000000ULL | value;
+
+		asm volatile("msr pmccntr_el0, %0" :: "r" (value64));
+	} else if (armv8pmu_select_counter(idx) == idx)
 		asm volatile("msr pmxevcntr_el0, %0" :: "r" (value));
 }
 
@@ -572,11 +775,11 @@ static void armv8pmu_reset(void *info)
 		armv8pmu_disable_intens(idx);
 	}
 
-	/* Initialize & Reset PMNC: C and P bits. */
-	armv8pmu_pmcr_write(ARMV8_PMCR_P | ARMV8_PMCR_C);
-
-	/* Disable access from userspace. */
-	asm volatile("msr pmuserenr_el0, %0" :: "r" (0));
+	/*
+	 * Initialize & Reset PMNC. Request overflow interrupt for
+	 * 64 bit cycle counter but cheat in armv8pmu_write_counter().
+	 */
+	armv8pmu_pmcr_write(ARMV8_PMCR_P | ARMV8_PMCR_C | ARMV8_PMCR_LC);
 }
 
 static int armv8_pmuv3_map_event(struct perf_event *event)
@@ -600,6 +803,13 @@ static int armv8_a57_map_event(struct pe
 				ARMV8_EVTYPE_EVENT);
 }
 
+static int armv8_thunder_map_event(struct perf_event *event)
+{
+	return armpmu_map_event(event, &armv8_thunder_perf_map,
+				&armv8_thunder_perf_cache_map,
+				ARMV8_EVTYPE_EVENT);
+}
+
 static void armv8pmu_read_num_pmnc_events(void *info)
 {
 	int *nb_cnt = info;
@@ -646,6 +856,7 @@ static int armv8_a53_pmu_init(struct arm
 	armv8_pmu_init(cpu_pmu);
 	cpu_pmu->name			= "armv8_cortex_a53";
 	cpu_pmu->map_event		= armv8_a53_map_event;
+	cpu_pmu->pmu.attr_groups	= armv8_pmuv3_attr_groups;
 	return armv8pmu_probe_num_events(cpu_pmu);
 }
 
@@ -654,6 +865,16 @@ static int armv8_a57_pmu_init(struct arm
 	armv8_pmu_init(cpu_pmu);
 	cpu_pmu->name			= "armv8_cortex_a57";
 	cpu_pmu->map_event		= armv8_a57_map_event;
+	cpu_pmu->pmu.attr_groups	= armv8_pmuv3_attr_groups;
+	return armv8pmu_probe_num_events(cpu_pmu);
+}
+
+static int armv8_thunder_pmu_init(struct arm_pmu *cpu_pmu)
+{
+	armv8_pmu_init(cpu_pmu);
+	cpu_pmu->name			= "armv8_cavium_thunder";
+	cpu_pmu->map_event		= armv8_thunder_map_event;
+	cpu_pmu->pmu.attr_groups	= armv8_pmuv3_attr_groups;
 	return armv8pmu_probe_num_events(cpu_pmu);
 }
 
@@ -661,6 +882,7 @@ static const struct of_device_id armv8_p
 	{.compatible = "arm,armv8-pmuv3",	.data = armv8_pmuv3_init},
 	{.compatible = "arm,cortex-a53-pmu",	.data = armv8_a53_pmu_init},
 	{.compatible = "arm,cortex-a57-pmu",	.data = armv8_a57_pmu_init},
+	{.compatible = "cavium,thunder-pmu",	.data = armv8_thunder_pmu_init},
 	{},
 };
 
--- zfcpdump-kernel-4.4.orig/arch/arm64/kernel/ptrace.c
+++ zfcpdump-kernel-4.4/arch/arm64/kernel/ptrace.c
@@ -39,6 +39,7 @@
 #include <linux/elf.h>
 
 #include <asm/compat.h>
+#include <asm/cpufeature.h>
 #include <asm/debug-monitors.h>
 #include <asm/pgtable.h>
 #include <asm/syscall.h>
@@ -58,6 +59,12 @@
  */
 void ptrace_disable(struct task_struct *child)
 {
+	/*
+	 * This would be better off in core code, but PTRACE_DETACH has
+	 * grown its fair share of arch-specific worts and changing it
+	 * is likely to cause regressions on obscure architectures.
+	 */
+	user_disable_single_step(child);
 }
 
 #ifdef CONFIG_HAVE_HW_BREAKPOINT
@@ -494,7 +501,7 @@ static int gpr_set(struct task_struct *t
 	if (ret)
 		return ret;
 
-	if (!valid_user_regs(&newregs))
+	if (!valid_user_regs(&newregs, target))
 		return -EINVAL;
 
 	task_pt_regs(target)->user_regs = newregs;
@@ -764,7 +771,7 @@ static int compat_gpr_set(struct task_st
 
 	}
 
-	if (valid_user_regs(&newregs.user_regs))
+	if (valid_user_regs(&newregs.user_regs, target))
 		*task_pt_regs(target) = newregs;
 	else
 		ret = -EINVAL;
@@ -1266,3 +1273,79 @@ asmlinkage void syscall_trace_exit(struc
 	if (test_thread_flag(TIF_SYSCALL_TRACE))
 		tracehook_report_syscall(regs, PTRACE_SYSCALL_EXIT);
 }
+
+/*
+ * Bits which are always architecturally RES0 per ARM DDI 0487A.h
+ * Userspace cannot use these until they have an architectural meaning.
+ * We also reserve IL for the kernel; SS is handled dynamically.
+ */
+#define SPSR_EL1_AARCH64_RES0_BITS \
+	(GENMASK_ULL(63,32) | GENMASK_ULL(27, 22) | GENMASK_ULL(20, 10) | \
+	 GENMASK_ULL(5, 5))
+#define SPSR_EL1_AARCH32_RES0_BITS \
+	(GENMASK_ULL(63,32) | GENMASK_ULL(24, 22) | GENMASK_ULL(20,20))
+
+static int valid_compat_regs(struct user_pt_regs *regs)
+{
+	regs->pstate &= ~SPSR_EL1_AARCH32_RES0_BITS;
+
+	if (!system_supports_mixed_endian_el0()) {
+		if (IS_ENABLED(CONFIG_CPU_BIG_ENDIAN))
+			regs->pstate |= COMPAT_PSR_E_BIT;
+		else
+			regs->pstate &= ~COMPAT_PSR_E_BIT;
+	}
+
+	if (user_mode(regs) && (regs->pstate & PSR_MODE32_BIT) &&
+	    (regs->pstate & COMPAT_PSR_A_BIT) == 0 &&
+	    (regs->pstate & COMPAT_PSR_I_BIT) == 0 &&
+	    (regs->pstate & COMPAT_PSR_F_BIT) == 0) {
+		return 1;
+	}
+
+	/*
+	 * Force PSR to a valid 32-bit EL0t, preserving the same bits as
+	 * arch/arm.
+	 */
+	regs->pstate &= COMPAT_PSR_N_BIT | COMPAT_PSR_Z_BIT |
+			COMPAT_PSR_C_BIT | COMPAT_PSR_V_BIT |
+			COMPAT_PSR_Q_BIT | COMPAT_PSR_IT_MASK |
+			COMPAT_PSR_GE_MASK | COMPAT_PSR_E_BIT |
+			COMPAT_PSR_T_BIT;
+	regs->pstate |= PSR_MODE32_BIT;
+
+	return 0;
+}
+
+static int valid_native_regs(struct user_pt_regs *regs)
+{
+	regs->pstate &= ~SPSR_EL1_AARCH64_RES0_BITS;
+
+	if (user_mode(regs) && !(regs->pstate & PSR_MODE32_BIT) &&
+	    (regs->pstate & PSR_D_BIT) == 0 &&
+	    (regs->pstate & PSR_A_BIT) == 0 &&
+	    (regs->pstate & PSR_I_BIT) == 0 &&
+	    (regs->pstate & PSR_F_BIT) == 0) {
+		return 1;
+	}
+
+	/* Force PSR to a valid 64-bit EL0t */
+	regs->pstate &= PSR_N_BIT | PSR_Z_BIT | PSR_C_BIT | PSR_V_BIT;
+
+	return 0;
+}
+
+/*
+ * Are the current registers suitable for user mode? (used to maintain
+ * security in signal handlers)
+ */
+int valid_user_regs(struct user_pt_regs *regs, struct task_struct *task)
+{
+	if (!test_tsk_thread_flag(task, TIF_SINGLESTEP))
+		regs->pstate &= ~DBG_SPSR_SS;
+
+	if (is_compat_thread(task_thread_info(task)))
+		return valid_compat_regs(regs);
+	else
+		return valid_native_regs(regs);
+}
--- zfcpdump-kernel-4.4.orig/arch/arm64/kernel/setup.c
+++ zfcpdump-kernel-4.4/arch/arm64/kernel/setup.c
@@ -53,6 +53,7 @@
 #include <asm/cpufeature.h>
 #include <asm/cpu_ops.h>
 #include <asm/kasan.h>
+#include <asm/numa.h>
 #include <asm/sections.h>
 #include <asm/setup.h>
 #include <asm/smp_plat.h>
@@ -319,7 +320,13 @@ void __init setup_arch(char **cmdline_p)
 	/* Parse the ACPI tables for possible boot-time configuration */
 	acpi_boot_table_init();
 
-	paging_init();
+	paging_init_map_mem();
+
+	if (acpi_disabled)
+		unflatten_device_tree();
+
+	paging_init_rest();
+
 	relocate_initrd();
 
 	kasan_init();
@@ -328,12 +335,11 @@ void __init setup_arch(char **cmdline_p)
 
 	early_ioremap_reset();
 
-	if (acpi_disabled) {
-		unflatten_device_tree();
+	if (acpi_disabled)
 		psci_dt_init();
-	} else {
+	else
 		psci_acpi_init();
-	}
+
 	xen_early_init();
 
 	cpu_read_bootcpu_ops();
@@ -372,6 +378,9 @@ static int __init topology_init(void)
 {
 	int i;
 
+	for_each_online_node(i)
+		register_one_node(i);
+
 	for_each_possible_cpu(i) {
 		struct cpu *cpu = &per_cpu(cpu_data.cpu, i);
 		cpu->hotpluggable = 1;
--- zfcpdump-kernel-4.4.orig/arch/arm64/kernel/signal.c
+++ zfcpdump-kernel-4.4/arch/arm64/kernel/signal.c
@@ -115,7 +115,7 @@ static int restore_sigframe(struct pt_re
 	 */
 	regs->syscallno = ~0UL;
 
-	err |= !valid_user_regs(&regs->user_regs);
+	err |= !valid_user_regs(&regs->user_regs, current);
 
 	if (err == 0) {
 		struct fpsimd_context *fpsimd_ctx =
@@ -307,7 +307,7 @@ static void handle_signal(struct ksignal
 	/*
 	 * Check that the resulting registers are actually sane.
 	 */
-	ret |= !valid_user_regs(&regs->user_regs);
+	ret |= !valid_user_regs(&regs->user_regs, current);
 
 	/*
 	 * Fast forward the stepping logic so we step into the signal
--- zfcpdump-kernel-4.4.orig/arch/arm64/kernel/signal32.c
+++ zfcpdump-kernel-4.4/arch/arm64/kernel/signal32.c
@@ -356,7 +356,7 @@ static int compat_restore_sigframe(struc
 	 */
 	regs->syscallno = ~0UL;
 
-	err |= !valid_user_regs(&regs->user_regs);
+	err |= !valid_user_regs(&regs->user_regs, current);
 
 	aux = (struct compat_aux_sigframe __user *) sf->uc.uc_regspace;
 	if (err == 0)
--- zfcpdump-kernel-4.4.orig/arch/arm64/kernel/smp.c
+++ zfcpdump-kernel-4.4/arch/arm64/kernel/smp.c
@@ -45,6 +45,7 @@
 #include <asm/cputype.h>
 #include <asm/cpu_ops.h>
 #include <asm/mmu_context.h>
+#include <asm/numa.h>
 #include <asm/pgtable.h>
 #include <asm/pgalloc.h>
 #include <asm/processor.h>
@@ -70,6 +71,7 @@ enum ipi_msg_type {
 	IPI_CPU_STOP,
 	IPI_TIMER,
 	IPI_IRQ_WORK,
+	IPI_WAKEUP
 };
 
 /*
@@ -125,6 +127,7 @@ int __cpu_up(unsigned int cpu, struct ta
 static void smp_store_cpu_info(unsigned int cpuid)
 {
 	store_cpu_topology(cpuid);
+	numa_store_cpu_info(cpuid);
 }
 
 /*
@@ -188,7 +191,6 @@ asmlinkage void secondary_start_kernel(v
 	set_cpu_online(cpu, true);
 	complete(&cpu_running);
 
-	local_dbg_enable();
 	local_irq_enable();
 	local_async_enable();
 
@@ -334,8 +336,8 @@ void __init smp_cpus_done(unsigned int m
 
 void __init smp_prepare_boot_cpu(void)
 {
-	cpuinfo_store_boot_cpu();
 	set_my_cpu_offset(per_cpu_offset(smp_processor_id()));
+	cpuinfo_store_boot_cpu();
 }
 
 static u64 __init of_get_cpu_mpidr(struct device_node *dn)
@@ -445,6 +447,17 @@ acpi_map_gic_cpu_interface(struct acpi_m
 	/* map the logical cpu id to cpu MPIDR */
 	cpu_logical_map(cpu_count) = hwid;
 
+	/*
+	 * Set-up the ACPI parking protocol cpu entries
+	 * while initializing the cpu_logical_map to
+	 * avoid parsing MADT entries multiple times for
+	 * nothing (ie a valid cpu_logical_map entry should
+	 * contain a valid parking protocol data set to
+	 * initialize the cpu if the parking protocol is
+	 * the only available enable method).
+	 */
+	acpi_set_mailbox_entry(cpu_count, processor);
+
 	cpu_count++;
 }
 
@@ -518,6 +531,8 @@ static void __init of_parse_and_init_cpu
 
 		pr_debug("cpu logical map 0x%llx\n", hwid);
 		cpu_logical_map(cpu_count) = hwid;
+
+		early_map_cpu_to_node(cpu_count, of_node_to_nid(dn));
 next:
 		cpu_count++;
 	}
@@ -627,6 +642,7 @@ static const char *ipi_types[NR_IPI] __t
 	S(IPI_CPU_STOP, "CPU stop interrupts"),
 	S(IPI_TIMER, "Timer broadcast interrupts"),
 	S(IPI_IRQ_WORK, "IRQ work interrupts"),
+	S(IPI_WAKEUP, "CPU wake-up interrupts"),
 };
 
 static void smp_cross_call(const struct cpumask *target, unsigned int ipinr)
@@ -670,6 +686,13 @@ void arch_send_call_function_single_ipi(
 	smp_cross_call(cpumask_of(cpu), IPI_CALL_FUNC);
 }
 
+#ifdef CONFIG_ARM64_ACPI_PARKING_PROTOCOL
+void arch_send_wakeup_ipi_mask(const struct cpumask *mask)
+{
+	smp_cross_call(mask, IPI_WAKEUP);
+}
+#endif
+
 #ifdef CONFIG_IRQ_WORK
 void arch_irq_work_raise(void)
 {
@@ -747,6 +770,14 @@ void handle_IPI(int ipinr, struct pt_reg
 		break;
 #endif
 
+#ifdef CONFIG_ARM64_ACPI_PARKING_PROTOCOL
+	case IPI_WAKEUP:
+		WARN_ONCE(!acpi_parking_protocol_valid(cpu),
+			  "CPU%u: Wake-up IPI outside the ACPI parking protocol\n",
+			  cpu);
+		break;
+#endif
+
 	default:
 		pr_crit("CPU%u: Unknown IPI message 0x%x\n", cpu, ipinr);
 		break;
--- zfcpdump-kernel-4.4.orig/arch/arm64/kvm/guest.c
+++ zfcpdump-kernel-4.4/arch/arm64/kvm/guest.c
@@ -186,7 +186,7 @@ static int get_timer_reg(struct kvm_vcpu
 	u64 val;
 
 	val = kvm_arm_timer_get_reg(vcpu, reg->id);
-	return copy_to_user(uaddr, &val, KVM_REG_SIZE(reg->id));
+	return copy_to_user(uaddr, &val, KVM_REG_SIZE(reg->id)) ? -EFAULT : 0;
 }
 
 /**
--- zfcpdump-kernel-4.4.orig/arch/arm64/kvm/hyp-init.S
+++ zfcpdump-kernel-4.4/arch/arm64/kvm/hyp-init.S
@@ -64,7 +64,7 @@ __do_hyp_init:
 	mrs	x4, tcr_el1
 	ldr	x5, =TCR_EL2_MASK
 	and	x4, x4, x5
-	ldr	x5, =TCR_EL2_FLAGS
+	mov	x5, #TCR_EL2_RES1
 	orr	x4, x4, x5
 
 #ifndef CONFIG_ARM64_VA_BITS_48
@@ -85,15 +85,18 @@ __do_hyp_init:
 	ldr_l	x5, idmap_t0sz
 	bfi	x4, x5, TCR_T0SZ_OFFSET, TCR_TxSZ_WIDTH
 #endif
-	msr	tcr_el2, x4
-
-	ldr	x4, =VTCR_EL2_FLAGS
 	/*
 	 * Read the PARange bits from ID_AA64MMFR0_EL1 and set the PS bits in
-	 * VTCR_EL2.
+	 * TCR_EL2 and VTCR_EL2.
 	 */
 	mrs	x5, ID_AA64MMFR0_EL1
 	bfi	x4, x5, #16, #3
+
+	msr	tcr_el2, x4
+
+	ldr	x4, =VTCR_EL2_FLAGS
+	bfi	x4, x5, #16, #3
+
 	msr	vtcr_el2, x4
 
 	mrs	x4, mair_el1
--- zfcpdump-kernel-4.4.orig/arch/arm64/kvm/inject_fault.c
+++ zfcpdump-kernel-4.4/arch/arm64/kvm/inject_fault.c
@@ -130,7 +130,7 @@ static void inject_abt64(struct kvm_vcpu
 		esr |= (ESR_ELx_EC_IABT_CUR << ESR_ELx_EC_SHIFT);
 
 	if (!is_iabt)
-		esr |= ESR_ELx_EC_DABT_LOW;
+		esr |= ESR_ELx_EC_DABT_LOW << ESR_ELx_EC_SHIFT;
 
 	vcpu_sys_reg(vcpu, ESR_EL1) = esr | ESR_ELx_FSC_EXTABT;
 }
--- zfcpdump-kernel-4.4.orig/arch/arm64/lib/copy_page.S
+++ zfcpdump-kernel-4.4/arch/arm64/lib/copy_page.S
@@ -18,6 +18,8 @@
 #include <linux/const.h>
 #include <asm/assembler.h>
 #include <asm/page.h>
+#include <asm/cpufeature.h>
+#include <asm/alternative.h>
 
 /*
  * Copy a page from src to dest (both are page aligned)
@@ -27,20 +29,65 @@
  *	x1 - src
  */
 ENTRY(copy_page)
-	/* Assume cache line size is 64 bytes. */
-	prfm	pldl1strm, [x1, #64]
-1:	ldp	x2, x3, [x1]
+alternative_if_not ARM64_HAS_NO_HW_PREFETCH
+	nop
+	nop
+alternative_else
+	# Prefetch two cache lines ahead.
+	prfm    pldl1strm, [x1, #128]
+	prfm    pldl1strm, [x1, #256]
+alternative_endif
+
+	ldp	x2, x3, [x1]
 	ldp	x4, x5, [x1, #16]
 	ldp	x6, x7, [x1, #32]
 	ldp	x8, x9, [x1, #48]
-	add	x1, x1, #64
-	prfm	pldl1strm, [x1, #64]
+	ldp	x10, x11, [x1, #64]
+	ldp	x12, x13, [x1, #80]
+	ldp	x14, x15, [x1, #96]
+	ldp	x16, x17, [x1, #112]
+
+	mov	x18, #(PAGE_SIZE - 128)
+	add	x1, x1, #128
+1:
+	subs	x18, x18, #128
+
+alternative_if_not ARM64_HAS_NO_HW_PREFETCH
+	nop
+alternative_else
+	prfm    pldl1strm, [x1, #384]
+alternative_endif
+
 	stnp	x2, x3, [x0]
+	ldp	x2, x3, [x1]
 	stnp	x4, x5, [x0, #16]
+	ldp	x4, x5, [x1, #16]
 	stnp	x6, x7, [x0, #32]
+	ldp	x6, x7, [x1, #32]
 	stnp	x8, x9, [x0, #48]
-	add	x0, x0, #64
-	tst	x1, #(PAGE_SIZE - 1)
-	b.ne	1b
+	ldp	x8, x9, [x1, #48]
+	stnp	x10, x11, [x0, #64]
+	ldp	x10, x11, [x1, #64]
+	stnp	x12, x13, [x0, #80]
+	ldp	x12, x13, [x1, #80]
+	stnp	x14, x15, [x0, #96]
+	ldp	x14, x15, [x1, #96]
+	stnp	x16, x17, [x0, #112]
+	ldp	x16, x17, [x1, #112]
+
+	add	x0, x0, #128
+	add	x1, x1, #128
+
+	b.gt	1b
+
+	stnp	x2, x3, [x0]
+	stnp	x4, x5, [x0, #16]
+	stnp	x6, x7, [x0, #32]
+	stnp	x8, x9, [x0, #48]
+	stnp	x10, x11, [x0, #64]
+	stnp	x12, x13, [x0, #80]
+	stnp	x14, x15, [x0, #96]
+	stnp	x16, x17, [x0, #112]
+
 	ret
 ENDPROC(copy_page)
--- zfcpdump-kernel-4.4.orig/arch/arm64/mm/Makefile
+++ zfcpdump-kernel-4.4/arch/arm64/mm/Makefile
@@ -4,6 +4,7 @@ obj-y				:= dma-mapping.o extable.o faul
 				   context.o proc.o pageattr.o
 obj-$(CONFIG_HUGETLB_PAGE)	+= hugetlbpage.o
 obj-$(CONFIG_ARM64_PTDUMP)	+= dump.o
+obj-$(CONFIG_NUMA)		+= numa.o
 
 obj-$(CONFIG_KASAN)		+= kasan_init.o
 KASAN_SANITIZE_kasan_init.o	:= n
--- zfcpdump-kernel-4.4.orig/arch/arm64/mm/dma-mapping.c
+++ zfcpdump-kernel-4.4/arch/arm64/mm/dma-mapping.c
@@ -933,6 +933,10 @@ static int __init __iommu_dma_init(void)
 		ret = register_iommu_dma_ops_notifier(&platform_bus_type);
 	if (!ret)
 		ret = register_iommu_dma_ops_notifier(&amba_bustype);
+
+	/* handle devices queued before this arch_initcall */
+	if (!ret)
+		__iommu_attach_notifier(NULL, BUS_NOTIFY_ADD_DEVICE, NULL);
 	return ret;
 }
 arch_initcall(__iommu_dma_init);
--- zfcpdump-kernel-4.4.orig/arch/arm64/mm/fault.c
+++ zfcpdump-kernel-4.4/arch/arm64/mm/fault.c
@@ -81,6 +81,56 @@ void show_pte(struct mm_struct *mm, unsi
 	printk("\n");
 }
 
+#ifdef CONFIG_ARM64_HW_AFDBM
+/*
+ * This function sets the access flags (dirty, accessed), as well as write
+ * permission, and only to a more permissive setting.
+ *
+ * It needs to cope with hardware update of the accessed/dirty state by other
+ * agents in the system and can safely skip the __sync_icache_dcache() call as,
+ * like set_pte_at(), the PTE is never changed from no-exec to exec here.
+ *
+ * Returns whether or not the PTE actually changed.
+ */
+int ptep_set_access_flags(struct vm_area_struct *vma,
+			  unsigned long address, pte_t *ptep,
+			  pte_t entry, int dirty)
+{
+	pteval_t old_pteval;
+	unsigned int tmp;
+
+	if (pte_same(*ptep, entry))
+		return 0;
+
+	/* only preserve the access flags and write permission */
+	pte_val(entry) &= PTE_AF | PTE_WRITE | PTE_DIRTY;
+
+	/*
+	 * PTE_RDONLY is cleared by default in the asm below, so set it in
+	 * back if necessary (read-only or clean PTE).
+	 */
+	if (!pte_write(entry) || !pte_sw_dirty(entry))
+		pte_val(entry) |= PTE_RDONLY;
+
+	/*
+	 * Setting the flags must be done atomically to avoid racing with the
+	 * hardware update of the access/dirty state.
+	 */
+	asm volatile("//	ptep_set_access_flags\n"
+	"	prfm	pstl1strm, %2\n"
+	"1:	ldxr	%0, %2\n"
+	"	and	%0, %0, %3		// clear PTE_RDONLY\n"
+	"	orr	%0, %0, %4		// set flags\n"
+	"	stxr	%w1, %0, %2\n"
+	"	cbnz	%w1, 1b\n"
+	: "=&r" (old_pteval), "=&r" (tmp), "+Q" (pte_val(*ptep))
+	: "L" (~PTE_RDONLY), "r" (pte_val(entry)));
+
+	flush_tlb_fix_spurious_fault(vma, address);
+	return 1;
+}
+#endif
+
 /*
  * The kernel tried to access some page that wasn't present.
  */
--- zfcpdump-kernel-4.4.orig/arch/arm64/mm/init.c
+++ zfcpdump-kernel-4.4/arch/arm64/mm/init.c
@@ -37,6 +37,7 @@
 
 #include <asm/fixmap.h>
 #include <asm/memory.h>
+#include <asm/numa.h>
 #include <asm/sections.h>
 #include <asm/setup.h>
 #include <asm/sizes.h>
@@ -77,6 +78,21 @@ static phys_addr_t max_zone_dma_phys(voi
 	return min(offset + (1ULL << 32), memblock_end_of_DRAM());
 }
 
+#ifdef CONFIG_NUMA
+
+static void __init zone_sizes_init(unsigned long min, unsigned long max)
+{
+	unsigned long max_zone_pfns[MAX_NR_ZONES]  = {0};
+
+	if (IS_ENABLED(CONFIG_ZONE_DMA))
+		max_zone_pfns[ZONE_DMA] = PFN_DOWN(max_zone_dma_phys());
+	max_zone_pfns[ZONE_NORMAL] = max;
+
+	free_area_init_nodes(max_zone_pfns);
+}
+
+#else
+
 static void __init zone_sizes_init(unsigned long min, unsigned long max)
 {
 	struct memblock_region *reg;
@@ -117,6 +133,8 @@ static void __init zone_sizes_init(unsig
 	free_area_init_node(0, zone_size, min, zhole_size);
 }
 
+#endif /* CONFIG_NUMA */
+
 #ifdef CONFIG_HAVE_ARCH_PFN_VALID
 int pfn_valid(unsigned long pfn)
 {
@@ -133,10 +151,15 @@ static void arm64_memory_present(void)
 static void arm64_memory_present(void)
 {
 	struct memblock_region *reg;
+	int nid = 0;
 
-	for_each_memblock(memory, reg)
-		memory_present(0, memblock_region_memory_base_pfn(reg),
-			       memblock_region_memory_end_pfn(reg));
+	for_each_memblock(memory, reg) {
+#ifdef CONFIG_NUMA
+		nid = reg->nid;
+#endif
+		memory_present(nid, memblock_region_memory_base_pfn(reg),
+				memblock_region_memory_end_pfn(reg));
+	}
 }
 #endif
 
@@ -181,7 +204,6 @@ void __init arm64_memblock_init(void)
 	dma_contiguous_reserve(arm64_dma_phys_limit);
 
 	memblock_allow_resize();
-	memblock_dump_all();
 }
 
 void __init bootmem_init(void)
@@ -193,6 +215,9 @@ void __init bootmem_init(void)
 
 	early_memtest(min << PAGE_SHIFT, max << PAGE_SHIFT);
 
+	max_pfn = max_low_pfn = max;
+
+	arm64_numa_init();
 	/*
 	 * Sparsemem tries to allocate bootmem in memory_present(), so must be
 	 * done after the fixed reservations.
@@ -203,7 +228,6 @@ void __init bootmem_init(void)
 	zone_sizes_init(min, max);
 
 	high_memory = __va((max << PAGE_SHIFT) - 1) + 1;
-	max_pfn = max_low_pfn = max;
 }
 
 #ifndef CONFIG_SPARSEMEM_VMEMMAP
@@ -319,8 +343,8 @@ void __init mem_init(void)
 #endif
 		  MLG(VMALLOC_START, VMALLOC_END),
 #ifdef CONFIG_SPARSEMEM_VMEMMAP
-		  MLG((unsigned long)vmemmap,
-		      (unsigned long)vmemmap + VMEMMAP_SIZE),
+		  MLG(VMEMMAP_START,
+		      VMEMMAP_START + VMEMMAP_SIZE),
 		  MLM((unsigned long)virt_to_page(PAGE_OFFSET),
 		      (unsigned long)virt_to_page(high_memory)),
 #endif
--- zfcpdump-kernel-4.4.orig/arch/arm64/mm/mmu.c
+++ zfcpdump-kernel-4.4/arch/arm64/mm/mmu.c
@@ -439,23 +439,32 @@ void fixup_init(void)
 }
 
 /*
- * paging_init() sets up the page tables, initialises the zone memory
- * maps and sets up the zero page.
+ * paging_init_map_mem() sets up the page tables so that memblock
+ * memory is usable.
  */
-void __init paging_init(void)
+void __init paging_init_map_mem(void)
 {
-	void *zero_page;
-
 	map_mem();
 	fixup_executable();
+}
 
+/*
+ * paging_init_rest() finishes setting up the page tables, initializes
+ * the zone memory maps and sets up the zero page.
+ */
+void __init paging_init_rest(void)
+{
 	/* allocate the zero page. */
-	zero_page = early_alloc(PAGE_SIZE);
+	void *zero_page = early_alloc(PAGE_SIZE);
 
 	bootmem_init();
+	memblock_dump_all();
 
 	empty_zero_page = virt_to_page(zero_page);
 
+	/* Ensure the zero page is visible to the page table walker */
+	dsb(ishst);
+
 	/*
 	 * TTBR0 is only used for the identity mapping at this stage. Make it
 	 * point to zero page to avoid speculatively fetching new entries.
@@ -649,9 +658,9 @@ void *__init fixmap_remap_fdt(phys_addr_
 	/*
 	 * Check whether the physical FDT address is set and meets the minimum
 	 * alignment requirement. Since we are relying on MIN_FDT_ALIGN to be
-	 * at least 8 bytes so that we can always access the size field of the
-	 * FDT header after mapping the first chunk, double check here if that
-	 * is indeed the case.
+	 * at least 8 bytes so that we can always access the magic and size
+	 * fields of the FDT header after mapping the first chunk, double check
+	 * here if that is indeed the case.
 	 */
 	BUILD_BUG_ON(MIN_FDT_ALIGN < 8);
 	if (!dt_phys || dt_phys % MIN_FDT_ALIGN)
@@ -679,7 +688,7 @@ void *__init fixmap_remap_fdt(phys_addr_
 	create_mapping(round_down(dt_phys, SWAPPER_BLOCK_SIZE), dt_virt_base,
 		       SWAPPER_BLOCK_SIZE, prot);
 
-	if (fdt_check_header(dt_virt) != 0)
+	if (fdt_magic(dt_virt) != FDT_MAGIC)
 		return NULL;
 
 	size = fdt_totalsize(dt_virt);
--- /dev/null
+++ zfcpdump-kernel-4.4/arch/arm64/mm/numa.c
@@ -0,0 +1,396 @@
+/*
+ * NUMA support, based on the x86 implementation.
+ *
+ * Copyright (C) 2015 Cavium Inc.
+ * Author: Ganapatrao Kulkarni <gkulkarni@cavium.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/bootmem.h>
+#include <linux/memblock.h>
+#include <linux/module.h>
+#include <linux/of.h>
+
+struct pglist_data *node_data[MAX_NUMNODES] __read_mostly;
+EXPORT_SYMBOL(node_data);
+nodemask_t numa_nodes_parsed __initdata;
+static int cpu_to_node_map[NR_CPUS] = { [0 ... NR_CPUS-1] = NUMA_NO_NODE };
+
+static int numa_distance_cnt;
+static u8 *numa_distance;
+static int numa_off;
+
+static __init int numa_parse_early_param(char *opt)
+{
+	if (!opt)
+		return -EINVAL;
+	if (!strncmp(opt, "off", 3)) {
+		pr_info("%s\n", "NUMA turned off");
+		numa_off = 1;
+	}
+	return 0;
+}
+early_param("numa", numa_parse_early_param);
+
+cpumask_var_t node_to_cpumask_map[MAX_NUMNODES];
+EXPORT_SYMBOL(node_to_cpumask_map);
+
+#ifdef CONFIG_DEBUG_PER_CPU_MAPS
+
+/*
+ * Returns a pointer to the bitmask of CPUs on Node 'node'.
+ */
+const struct cpumask *cpumask_of_node(int node)
+{
+	if (WARN_ON(node >= nr_node_ids))
+		return cpu_none_mask;
+
+	if (WARN_ON(node_to_cpumask_map[node] == NULL))
+		return cpu_online_mask;
+
+	return node_to_cpumask_map[node];
+}
+EXPORT_SYMBOL(cpumask_of_node);
+
+#endif
+
+static void map_cpu_to_node(unsigned int cpu, int nid)
+{
+	set_cpu_numa_node(cpu, nid);
+	if (nid >= 0)
+		cpumask_set_cpu(cpu, node_to_cpumask_map[nid]);
+}
+
+void numa_clear_node(unsigned int cpu)
+{
+	int nid = cpu_to_node(cpu);
+
+	if (nid >= 0)
+		cpumask_clear_cpu(cpu, node_to_cpumask_map[nid]);
+	set_cpu_numa_node(cpu, NUMA_NO_NODE);
+}
+
+/*
+ * Allocate node_to_cpumask_map based on number of available nodes
+ * Requires node_possible_map to be valid.
+ *
+ * Note: cpumask_of_node() is not valid until after this is done.
+ * (Use CONFIG_DEBUG_PER_CPU_MAPS to check this.)
+ */
+static void __init setup_node_to_cpumask_map(void)
+{
+	unsigned int cpu;
+	int node;
+
+	/* setup nr_node_ids if not done yet */
+	if (nr_node_ids == MAX_NUMNODES)
+		setup_nr_node_ids();
+
+	/* allocate and clear the mapping */
+	for (node = 0; node < nr_node_ids; node++) {
+		alloc_bootmem_cpumask_var(&node_to_cpumask_map[node]);
+		cpumask_clear(node_to_cpumask_map[node]);
+	}
+
+	for_each_possible_cpu(cpu)
+		set_cpu_numa_node(cpu, NUMA_NO_NODE);
+
+	/* cpumask_of_node() will now work */
+	pr_debug("NUMA: Node to cpumask map for %d nodes\n", nr_node_ids);
+}
+
+/*
+ *  Set the cpu to node and mem mapping
+ */
+void numa_store_cpu_info(unsigned int cpu)
+{
+	map_cpu_to_node(cpu, numa_off ? 0 : cpu_to_node_map[cpu]);
+}
+
+void __init early_map_cpu_to_node(unsigned int cpu, int nid)
+{
+	/* fallback to node 0 */
+	if (nid < 0 || nid >= MAX_NUMNODES)
+		nid = 0;
+
+	cpu_to_node_map[cpu] = nid;
+}
+
+/**
+ * numa_add_memblk - Set node id to memblk
+ * @nid: NUMA node ID of the new memblk
+ * @start: Start address of the new memblk
+ * @size:  Size of the new memblk
+ *
+ * RETURNS:
+ * 0 on success, -errno on failure.
+ */
+int __init numa_add_memblk(int nid, u64 start, u64 size)
+{
+	int ret;
+
+	ret = memblock_set_node(start, size, &memblock.memory, nid);
+	if (ret < 0) {
+		pr_err("NUMA: memblock [0x%llx - 0x%llx] failed to add on node %d\n",
+			start, (start + size - 1), nid);
+		return ret;
+	}
+
+	node_set(nid, numa_nodes_parsed);
+	pr_info("NUMA: Adding memblock [0x%llx - 0x%llx] on node %d\n",
+			start, (start + size - 1), nid);
+	return ret;
+}
+
+/**
+ * Initialize NODE_DATA for a node on the local memory
+ */
+static void __init setup_node_data(int nid, u64 start_pfn, u64 end_pfn)
+{
+	const size_t nd_size = roundup(sizeof(pg_data_t), SMP_CACHE_BYTES);
+	u64 nd_pa;
+	void *nd;
+	int tnid;
+
+	pr_info("NUMA: Initmem setup node %d [mem %#010Lx-%#010Lx]\n",
+			nid, start_pfn << PAGE_SHIFT,
+			(end_pfn << PAGE_SHIFT) - 1);
+
+	nd_pa = memblock_alloc_try_nid(nd_size, SMP_CACHE_BYTES, nid);
+	nd = __va(nd_pa);
+
+	/* report and initialize */
+	pr_info("NUMA: NODE_DATA [mem %#010Lx-%#010Lx]\n",
+		nd_pa, nd_pa + nd_size - 1);
+	tnid = early_pfn_to_nid(nd_pa >> PAGE_SHIFT);
+	if (tnid != nid)
+		pr_info("NUMA: NODE_DATA(%d) on node %d\n", nid, tnid);
+
+	node_data[nid] = nd;
+	memset(NODE_DATA(nid), 0, sizeof(pg_data_t));
+	NODE_DATA(nid)->node_id = nid;
+	NODE_DATA(nid)->node_start_pfn = start_pfn;
+	NODE_DATA(nid)->node_spanned_pages = end_pfn - start_pfn;
+}
+
+/**
+ * numa_free_distance
+ *
+ * The current table is freed.
+ */
+void __init numa_free_distance(void)
+{
+	size_t size;
+
+	if (!numa_distance)
+		return;
+
+	size = numa_distance_cnt * numa_distance_cnt *
+		sizeof(numa_distance[0]);
+
+	memblock_free(__pa(numa_distance), size);
+	numa_distance_cnt = 0;
+	numa_distance = NULL;
+}
+
+/**
+ *
+ * Create a new NUMA distance table.
+ *
+ */
+static int __init numa_alloc_distance(void)
+{
+	size_t size;
+	u64 phys;
+	int i, j;
+
+	size = nr_node_ids * nr_node_ids * sizeof(numa_distance[0]);
+	phys = memblock_find_in_range(0, PFN_PHYS(max_pfn),
+				      size, PAGE_SIZE);
+	if (WARN_ON(!phys))
+		return -ENOMEM;
+
+	memblock_reserve(phys, size);
+
+	numa_distance = __va(phys);
+	numa_distance_cnt = nr_node_ids;
+
+	/* fill with the default distances */
+	for (i = 0; i < numa_distance_cnt; i++)
+		for (j = 0; j < numa_distance_cnt; j++)
+			numa_distance[i * numa_distance_cnt + j] = i == j ?
+				LOCAL_DISTANCE : REMOTE_DISTANCE;
+
+	pr_debug("NUMA: Initialized distance table, cnt=%d\n",
+			numa_distance_cnt);
+
+	return 0;
+}
+
+/**
+ * numa_set_distance - Set inter node NUMA distance from node to node.
+ * @from: the 'from' node to set distance
+ * @to: the 'to'  node to set distance
+ * @distance: NUMA distance
+ *
+ * Set the distance from node @from to @to to @distance.
+ * If distance table doesn't exist, a warning is printed.
+ *
+ * If @from or @to is higher than the highest known node or lower than zero
+ * or @distance doesn't make sense, the call is ignored.
+ *
+ */
+void __init numa_set_distance(int from, int to, int distance)
+{
+	if (!numa_distance) {
+		pr_warn_once("NUMA: Warning: distance table not allocated yet\n");
+		return;
+	}
+
+	if (from >= numa_distance_cnt || to >= numa_distance_cnt ||
+			from < 0 || to < 0) {
+		pr_warn_once("NUMA: Warning: node ids are out of bound, from=%d to=%d distance=%d\n",
+			    from, to, distance);
+		return;
+	}
+
+	if ((u8)distance != distance ||
+	    (from == to && distance != LOCAL_DISTANCE)) {
+		pr_warn_once("NUMA: Warning: invalid distance parameter, from=%d to=%d distance=%d\n",
+			     from, to, distance);
+		return;
+	}
+
+	numa_distance[from * numa_distance_cnt + to] = distance;
+}
+
+/**
+ * Return NUMA distance @from to @to
+ */
+int __node_distance(int from, int to)
+{
+	if (from >= numa_distance_cnt || to >= numa_distance_cnt)
+		return from == to ? LOCAL_DISTANCE : REMOTE_DISTANCE;
+	return numa_distance[from * numa_distance_cnt + to];
+}
+EXPORT_SYMBOL(__node_distance);
+
+static int __init numa_register_nodes(void)
+{
+	int nid;
+	struct memblock_region *mblk;
+
+	/* Check that valid nid is set to memblks */
+	for_each_memblock(memory, mblk)
+		if (mblk->nid == NUMA_NO_NODE || mblk->nid >= MAX_NUMNODES) {
+			pr_warn("NUMA: Warning: invalid memblk node %d [mem %#010Lx-%#010Lx]\n",
+				mblk->nid, mblk->base,
+				mblk->base + mblk->size - 1);
+			return -EINVAL;
+		}
+
+	/* Finally register nodes. */
+	for_each_node_mask(nid, numa_nodes_parsed) {
+		unsigned long start_pfn, end_pfn;
+
+		get_pfn_range_for_nid(nid, &start_pfn, &end_pfn);
+		setup_node_data(nid, start_pfn, end_pfn);
+		node_set_online(nid);
+	}
+
+	/* Setup online nodes to actual nodes*/
+	node_possible_map = numa_nodes_parsed;
+
+	return 0;
+}
+
+static int __init numa_init(int (*init_func)(void))
+{
+	int ret;
+
+	nodes_clear(numa_nodes_parsed);
+	nodes_clear(node_possible_map);
+	nodes_clear(node_online_map);
+	numa_free_distance();
+
+	ret = numa_alloc_distance();
+	if (ret < 0)
+		return ret;
+
+	ret = init_func();
+	if (ret < 0)
+		return ret;
+
+	if (nodes_empty(numa_nodes_parsed))
+		return -EINVAL;
+
+	ret = numa_register_nodes();
+	if (ret < 0)
+		return ret;
+
+	setup_node_to_cpumask_map();
+
+	/* init boot processor */
+	cpu_to_node_map[0] = 0;
+	map_cpu_to_node(0, 0);
+
+	return 0;
+}
+
+/**
+ * dummy_numa_init - Fallback dummy NUMA init
+ *
+ * Used if there's no underlying NUMA architecture, NUMA initialization
+ * fails, or NUMA is disabled on the command line.
+ *
+ * Must online at least one node (node 0) and add memory blocks that cover all
+ * allowed memory. It is unlikely that this function fails.
+ */
+static int __init dummy_numa_init(void)
+{
+	int ret;
+	struct memblock_region *mblk;
+
+	pr_info("%s\n", "No NUMA configuration found");
+	pr_info("NUMA: Faking a node at [mem %#018Lx-%#018Lx]\n",
+	       0LLU, PFN_PHYS(max_pfn) - 1);
+
+	for_each_memblock(memory, mblk) {
+		ret = numa_add_memblk(0, mblk->base, mblk->size);
+		if (!ret)
+			continue;
+
+		pr_err("NUMA init failed\n");
+		return ret;
+	}
+
+	numa_off = 1;
+	return 0;
+}
+
+/**
+ * arm64_numa_init - Initialize NUMA
+ *
+ * Try each configured NUMA initialization method until one succeeds.  The
+ * last fallback is dummy single node config encomapssing whole memory.
+ */
+void __init arm64_numa_init(void)
+{
+	if (!numa_off) {
+		if (!numa_init(of_numa_init))
+			return;
+	}
+
+	numa_init(dummy_numa_init);
+}
--- zfcpdump-kernel-4.4.orig/arch/arm64/mm/pageattr.c
+++ zfcpdump-kernel-4.4/arch/arm64/mm/pageattr.c
@@ -57,6 +57,9 @@ static int change_memory_common(unsigned
 	if (end < MODULES_VADDR || end >= MODULES_END)
 		return -EINVAL;
 
+	if (!numpages)
+		return 0;
+
 	data.set_mask = set_mask;
 	data.clear_mask = clear_mask;
 
--- zfcpdump-kernel-4.4.orig/arch/arm64/mm/proc-macros.S
+++ zfcpdump-kernel-4.4/arch/arm64/mm/proc-macros.S
@@ -62,3 +62,15 @@
 	bfi	\valreg, \tmpreg, #TCR_T0SZ_OFFSET, #TCR_TxSZ_WIDTH
 #endif
 	.endm
+
+/*
+ * reset_pmuserenr_el0 - reset PMUSERENR_EL0 if PMUv3 present
+ */
+	.macro	reset_pmuserenr_el0, tmpreg
+	mrs	\tmpreg, id_aa64dfr0_el1	// Check ID_AA64DFR0_EL1 PMUVer
+	sbfx	\tmpreg, \tmpreg, #8, #4
+	cmp	\tmpreg, #1			// Skip if no PMU present
+	b.lt	9000f
+	msr	pmuserenr_el0, xzr		// Disable PMU access from EL0
+9000:
+	.endm
--- zfcpdump-kernel-4.4.orig/arch/arm64/mm/proc.S
+++ zfcpdump-kernel-4.4/arch/arm64/mm/proc.S
@@ -25,6 +25,8 @@
 #include <asm/hwcap.h>
 #include <asm/pgtable-hwdef.h>
 #include <asm/pgtable.h>
+#include <asm/cpufeature.h>
+#include <asm/alternative.h>
 
 #include "proc-macros.S"
 
@@ -117,6 +119,7 @@ ENTRY(cpu_do_resume)
 	 */
 	ubfx	x11, x11, #1, #1
 	msr	oslar_el1, x11
+	reset_pmuserenr_el0 x0			// Disable PMU access from EL0
 	mov	x0, x12
 	dsb	nsh		// Make sure local tlb invalidation completed
 	isb
@@ -136,7 +139,17 @@ ENTRY(cpu_do_switch_mm)
 	bfi	x0, x1, #48, #16		// set the ASID
 	msr	ttbr0_el1, x0			// set TTBR0
 	isb
+alternative_if_not ARM64_WORKAROUND_CAVIUM_27456
 	ret
+	nop
+	nop
+	nop
+alternative_else
+	ic	iallu
+	dsb	nsh
+	isb
+	ret
+alternative_endif
 ENDPROC(cpu_do_switch_mm)
 
 	.section ".text.init", #alloc, #execinstr
@@ -155,6 +168,9 @@ ENTRY(__cpu_setup)
 	msr	cpacr_el1, x0			// Enable FP/ASIMD
 	mov	x0, #1 << 12			// Reset mdscr_el1 and disable
 	msr	mdscr_el1, x0			// access to the DCC from EL0
+	isb					// Unmask debug exceptions now,
+	enable_dbg				// since this is per-cpu
+	reset_pmuserenr_el0 x0			// Disable PMU access from EL0
 	/*
 	 * Memory region attributes for LPAE:
 	 *
--- zfcpdump-kernel-4.4.orig/arch/avr32/include/asm/uaccess.h
+++ zfcpdump-kernel-4.4/arch/avr32/include/asm/uaccess.h
@@ -74,7 +74,7 @@ extern __kernel_size_t __copy_user(void
 
 extern __kernel_size_t copy_to_user(void __user *to, const void *from,
 				    __kernel_size_t n);
-extern __kernel_size_t copy_from_user(void *to, const void __user *from,
+extern __kernel_size_t ___copy_from_user(void *to, const void __user *from,
 				      __kernel_size_t n);
 
 static inline __kernel_size_t __copy_to_user(void __user *to, const void *from,
@@ -88,6 +88,15 @@ static inline __kernel_size_t __copy_fro
 {
 	return __copy_user(to, (const void __force *)from, n);
 }
+static inline __kernel_size_t copy_from_user(void *to,
+					       const void __user *from,
+					       __kernel_size_t n)
+{
+	size_t res = ___copy_from_user(to, from, n);
+	if (unlikely(res))
+		memset(to + (n - res), 0, res);
+	return res;
+}
 
 #define __copy_to_user_inatomic __copy_to_user
 #define __copy_from_user_inatomic __copy_from_user
--- zfcpdump-kernel-4.4.orig/arch/avr32/kernel/avr32_ksyms.c
+++ zfcpdump-kernel-4.4/arch/avr32/kernel/avr32_ksyms.c
@@ -36,7 +36,7 @@ EXPORT_SYMBOL(copy_page);
 /*
  * Userspace access stuff.
  */
-EXPORT_SYMBOL(copy_from_user);
+EXPORT_SYMBOL(___copy_from_user);
 EXPORT_SYMBOL(copy_to_user);
 EXPORT_SYMBOL(__copy_user);
 EXPORT_SYMBOL(strncpy_from_user);
--- zfcpdump-kernel-4.4.orig/arch/avr32/kernel/module.c
+++ zfcpdump-kernel-4.4/arch/avr32/kernel/module.c
@@ -118,9 +118,9 @@ int module_frob_arch_sections(Elf_Ehdr *
 	 * Increase core size to make room for GOT and set start
 	 * offset for GOT.
 	 */
-	module->core_size = ALIGN(module->core_size, 4);
-	module->arch.got_offset = module->core_size;
-	module->core_size += module->arch.got_size;
+	module->core_layout.size = ALIGN(module->core_layout.size, 4);
+	module->arch.got_offset = module->core_layout.size;
+	module->core_layout.size += module->arch.got_size;
 
 	return 0;
 
@@ -177,7 +177,7 @@ int apply_relocate_add(Elf32_Shdr *sechd
 			if (!info->got_initialized) {
 				Elf32_Addr *gotent;
 
-				gotent = (module->module_core
+				gotent = (module->core_layout.base
 					  + module->arch.got_offset
 					  + info->got_offset);
 				*gotent = relocation;
@@ -255,8 +255,8 @@ int apply_relocate_add(Elf32_Shdr *sechd
 			 */
 			pr_debug("GOTPC: PC=0x%x, got_offset=0x%lx, core=0x%p\n",
 				 relocation, module->arch.got_offset,
-				 module->module_core);
-			relocation -= ((unsigned long)module->module_core
+				 module->core_layout.base);
+			relocation -= ((unsigned long)module->core_layout.base
 				       + module->arch.got_offset);
 			*location = relocation;
 			break;
--- zfcpdump-kernel-4.4.orig/arch/avr32/lib/copy_user.S
+++ zfcpdump-kernel-4.4/arch/avr32/lib/copy_user.S
@@ -23,13 +23,13 @@
 	 */
 	.text
 	.align	1
-	.global	copy_from_user
-	.type	copy_from_user, @function
-copy_from_user:
+	.global	___copy_from_user
+	.type	___copy_from_user, @function
+___copy_from_user:
 	branch_if_kernel r8, __copy_user
 	ret_if_privileged r8, r11, r10, r10
 	rjmp	__copy_user
-	.size	copy_from_user, . - copy_from_user
+	.size	___copy_from_user, . - ___copy_from_user
 
 	.global	copy_to_user
 	.type	copy_to_user, @function
--- zfcpdump-kernel-4.4.orig/arch/avr32/mach-at32ap/pio.c
+++ zfcpdump-kernel-4.4/arch/avr32/mach-at32ap/pio.c
@@ -435,7 +435,7 @@ void __init at32_init_pio(struct platfor
 	struct resource *regs;
 	struct pio_device *pio;
 
-	if (pdev->id > MAX_NR_PIO_DEVICES) {
+	if (pdev->id >= MAX_NR_PIO_DEVICES) {
 		dev_err(&pdev->dev, "only %d PIO devices supported\n",
 			MAX_NR_PIO_DEVICES);
 		return;
--- zfcpdump-kernel-4.4.orig/arch/blackfin/include/asm/uaccess.h
+++ zfcpdump-kernel-4.4/arch/blackfin/include/asm/uaccess.h
@@ -177,11 +177,12 @@ static inline int bad_user_access_length
 static inline unsigned long __must_check
 copy_from_user(void *to, const void __user *from, unsigned long n)
 {
-	if (access_ok(VERIFY_READ, from, n))
+	if (likely(access_ok(VERIFY_READ, from, n))) {
 		memcpy(to, (const void __force *)from, n);
-	else
-		return n;
-	return 0;
+		return 0;
+	}
+	memset(to, 0, n);
+	return n;
 }
 
 static inline unsigned long __must_check
--- zfcpdump-kernel-4.4.orig/arch/blackfin/mach-bf561/boards/cm_bf561.c
+++ zfcpdump-kernel-4.4/arch/blackfin/mach-bf561/boards/cm_bf561.c
@@ -146,7 +146,8 @@ static struct platform_device hitachi_fb
 #include <linux/smc91x.h>
 
 static struct smc91x_platdata smc91x_info = {
-	.flags = SMC91X_USE_32BIT | SMC91X_NOWAIT,
+	.flags = SMC91X_USE_8BIT | SMC91X_USE_16BIT | SMC91X_USE_32BIT |
+		 SMC91X_NOWAIT,
 	.leda = RPC_LED_100_10,
 	.ledb = RPC_LED_TX_RX,
 };
--- zfcpdump-kernel-4.4.orig/arch/blackfin/mach-bf561/boards/ezkit.c
+++ zfcpdump-kernel-4.4/arch/blackfin/mach-bf561/boards/ezkit.c
@@ -134,7 +134,8 @@ static struct platform_device net2272_bf
 #include <linux/smc91x.h>
 
 static struct smc91x_platdata smc91x_info = {
-	.flags = SMC91X_USE_32BIT | SMC91X_NOWAIT,
+	.flags = SMC91X_USE_8BIT | SMC91X_USE_16BIT | SMC91X_USE_32BIT |
+		 SMC91X_NOWAIT,
 	.leda = RPC_LED_100_10,
 	.ledb = RPC_LED_TX_RX,
 };
--- zfcpdump-kernel-4.4.orig/arch/cris/include/asm/uaccess.h
+++ zfcpdump-kernel-4.4/arch/cris/include/asm/uaccess.h
@@ -194,30 +194,6 @@ extern unsigned long __copy_user(void __
 extern unsigned long __copy_user_zeroing(void *to, const void __user *from, unsigned long n);
 extern unsigned long __do_clear_user(void __user *to, unsigned long n);
 
-static inline unsigned long
-__generic_copy_to_user(void __user *to, const void *from, unsigned long n)
-{
-	if (access_ok(VERIFY_WRITE, to, n))
-		return __copy_user(to, from, n);
-	return n;
-}
-
-static inline unsigned long
-__generic_copy_from_user(void *to, const void __user *from, unsigned long n)
-{
-	if (access_ok(VERIFY_READ, from, n))
-		return __copy_user_zeroing(to, from, n);
-	return n;
-}
-
-static inline unsigned long
-__generic_clear_user(void __user *to, unsigned long n)
-{
-	if (access_ok(VERIFY_WRITE, to, n))
-		return __do_clear_user(to, n);
-	return n;
-}
-
 static inline long
 __strncpy_from_user(char *dst, const char __user *src, long count)
 {
@@ -282,7 +258,7 @@ __constant_copy_from_user(void *to, cons
 	else if (n == 24)
 		__asm_copy_from_user_24(to, from, ret);
 	else
-		ret = __generic_copy_from_user(to, from, n);
+		ret = __copy_user_zeroing(to, from, n);
 
 	return ret;
 }
@@ -333,7 +309,7 @@ __constant_copy_to_user(void __user *to,
 	else if (n == 24)
 		__asm_copy_to_user_24(to, from, ret);
 	else
-		ret = __generic_copy_to_user(to, from, n);
+		ret = __copy_user(to, from, n);
 
 	return ret;
 }
@@ -366,26 +342,43 @@ __constant_clear_user(void __user *to, u
 	else if (n == 24)
 		__asm_clear_24(to, ret);
 	else
-		ret = __generic_clear_user(to, n);
+		ret = __do_clear_user(to, n);
 
 	return ret;
 }
 
 
-#define clear_user(to, n)				\
-	(__builtin_constant_p(n) ?			\
-	 __constant_clear_user(to, n) :			\
-	 __generic_clear_user(to, n))
-
-#define copy_from_user(to, from, n)			\
-	(__builtin_constant_p(n) ?			\
-	 __constant_copy_from_user(to, from, n) :	\
-	 __generic_copy_from_user(to, from, n))
-
-#define copy_to_user(to, from, n)			\
-	(__builtin_constant_p(n) ?			\
-	 __constant_copy_to_user(to, from, n) :		\
-	 __generic_copy_to_user(to, from, n))
+static inline size_t clear_user(void __user *to, size_t n)
+{
+	if (unlikely(!access_ok(VERIFY_WRITE, to, n)))
+		return n;
+	if (__builtin_constant_p(n))
+		return __constant_clear_user(to, n);
+	else
+		return __do_clear_user(to, n);
+}
+
+static inline size_t copy_from_user(void *to, const void __user *from, size_t n)
+{
+	if (unlikely(!access_ok(VERIFY_READ, from, n))) {
+		memset(to, 0, n);
+		return n;
+	}
+	if (__builtin_constant_p(n))
+		return __constant_copy_from_user(to, from, n);
+	else
+		return __copy_user_zeroing(to, from, n);
+}
+
+static inline size_t copy_to_user(void __user *to, const void *from, size_t n)
+{
+	if (unlikely(!access_ok(VERIFY_WRITE, to, n)))
+		return n;
+	if (__builtin_constant_p(n))
+		return __constant_copy_to_user(to, from, n);
+	else
+		return __copy_user(to, from, n);
+}
 
 /* We let the __ versions of copy_from/to_user inline, because they're often
  * used in fast paths and have only a small space overhead.
--- zfcpdump-kernel-4.4.orig/arch/frv/include/asm/uaccess.h
+++ zfcpdump-kernel-4.4/arch/frv/include/asm/uaccess.h
@@ -263,19 +263,25 @@ do {							\
 extern long __memset_user(void *dst, unsigned long count);
 extern long __memcpy_user(void *dst, const void *src, unsigned long count);
 
-#define clear_user(dst,count)			__memset_user(____force(dst), (count))
+#define __clear_user(dst,count)			__memset_user(____force(dst), (count))
 #define __copy_from_user_inatomic(to, from, n)	__memcpy_user((to), ____force(from), (n))
 #define __copy_to_user_inatomic(to, from, n)	__memcpy_user(____force(to), (from), (n))
 
 #else
 
-#define clear_user(dst,count)			(memset(____force(dst), 0, (count)), 0)
+#define __clear_user(dst,count)			(memset(____force(dst), 0, (count)), 0)
 #define __copy_from_user_inatomic(to, from, n)	(memcpy((to), ____force(from), (n)), 0)
 #define __copy_to_user_inatomic(to, from, n)	(memcpy(____force(to), (from), (n)), 0)
 
 #endif
 
-#define __clear_user clear_user
+static inline unsigned long __must_check
+clear_user(void __user *to, unsigned long n)
+{
+	if (likely(__access_ok(to, n)))
+		n = __clear_user(to, n);
+	return n;
+}
 
 static inline unsigned long __must_check
 __copy_to_user(void __user *to, const void *from, unsigned long n)
--- zfcpdump-kernel-4.4.orig/arch/hexagon/include/asm/uaccess.h
+++ zfcpdump-kernel-4.4/arch/hexagon/include/asm/uaccess.h
@@ -103,7 +103,8 @@ static inline long hexagon_strncpy_from_
 {
 	long res = __strnlen_user(src, n);
 
-	/* return from strnlen can't be zero -- that would be rubbish. */
+	if (unlikely(!res))
+		return -EFAULT;
 
 	if (res > n) {
 		copy_from_user(dst, src, n);
--- zfcpdump-kernel-4.4.orig/arch/ia64/include/asm/barrier.h
+++ zfcpdump-kernel-4.4/arch/ia64/include/asm/barrier.h
@@ -77,7 +77,7 @@ do {									\
 	___p1;								\
 })
 
-#define smp_store_mb(var, value)	do { WRITE_ONCE(var, value); mb(); } while (0)
+#define smp_store_mb(var, value) do { WRITE_ONCE(var, value); smp_mb(); } while (0)
 
 /*
  * The group barrier in front of the rsm & ssm are necessary to ensure
--- zfcpdump-kernel-4.4.orig/arch/ia64/include/asm/io.h
+++ zfcpdump-kernel-4.4/arch/ia64/include/asm/io.h
@@ -436,6 +436,7 @@ static inline void __iomem * ioremap_cac
 	return ioremap(phys_addr, size);
 }
 #define ioremap_cache ioremap_cache
+#define ioremap_uc ioremap_nocache
 
 
 /*
--- zfcpdump-kernel-4.4.orig/arch/ia64/include/asm/uaccess.h
+++ zfcpdump-kernel-4.4/arch/ia64/include/asm/uaccess.h
@@ -263,17 +263,15 @@ __copy_from_user (void *to, const void _
 	__cu_len;									\
 })
 
-#define copy_from_user(to, from, n)							\
-({											\
-	void *__cu_to = (to);								\
-	const void __user *__cu_from = (from);						\
-	long __cu_len = (n);								\
-											\
-	__chk_user_ptr(__cu_from);							\
-	if (__access_ok(__cu_from, __cu_len, get_fs()))					\
-		__cu_len = __copy_user((__force void __user *) __cu_to, __cu_from, __cu_len);	\
-	__cu_len;									\
-})
+static inline unsigned long
+copy_from_user(void *to, const void __user *from, unsigned long n)
+{
+	if (likely(__access_ok(from, n, get_fs())))
+		n = __copy_user((__force void __user *) to, from, n);
+	else
+		memset(to, 0, n);
+	return n;
+}
 
 #define __copy_in_user(to, from, size)	__copy_user((to), (from), (size))
 
--- zfcpdump-kernel-4.4.orig/arch/ia64/kernel/module.c
+++ zfcpdump-kernel-4.4/arch/ia64/kernel/module.c
@@ -486,13 +486,13 @@ module_frob_arch_sections (Elf_Ehdr *ehd
 static inline int
 in_init (const struct module *mod, uint64_t addr)
 {
-	return addr - (uint64_t) mod->module_init < mod->init_size;
+	return addr - (uint64_t) mod->init_layout.base < mod->init_layout.size;
 }
 
 static inline int
 in_core (const struct module *mod, uint64_t addr)
 {
-	return addr - (uint64_t) mod->module_core < mod->core_size;
+	return addr - (uint64_t) mod->core_layout.base < mod->core_layout.size;
 }
 
 static inline int
@@ -675,7 +675,7 @@ do_reloc (struct module *mod, uint8_t r_
 		break;
 
 	      case RV_BDREL:
-		val -= (uint64_t) (in_init(mod, val) ? mod->module_init : mod->module_core);
+		val -= (uint64_t) (in_init(mod, val) ? mod->init_layout.base : mod->core_layout.base);
 		break;
 
 	      case RV_LTV:
@@ -810,15 +810,15 @@ apply_relocate_add (Elf64_Shdr *sechdrs,
 		 *     addresses have been selected...
 		 */
 		uint64_t gp;
-		if (mod->core_size > MAX_LTOFF)
+		if (mod->core_layout.size > MAX_LTOFF)
 			/*
 			 * This takes advantage of fact that SHF_ARCH_SMALL gets allocated
 			 * at the end of the module.
 			 */
-			gp = mod->core_size - MAX_LTOFF / 2;
+			gp = mod->core_layout.size - MAX_LTOFF / 2;
 		else
-			gp = mod->core_size / 2;
-		gp = (uint64_t) mod->module_core + ((gp + 7) & -8);
+			gp = mod->core_layout.size / 2;
+		gp = (uint64_t) mod->core_layout.base + ((gp + 7) & -8);
 		mod->arch.gp = gp;
 		DEBUGP("%s: placing gp at 0x%lx\n", __func__, gp);
 	}
--- zfcpdump-kernel-4.4.orig/arch/m32r/include/asm/uaccess.h
+++ zfcpdump-kernel-4.4/arch/m32r/include/asm/uaccess.h
@@ -219,7 +219,7 @@ extern int fixup_exception(struct pt_reg
 #define __get_user_nocheck(x, ptr, size)				\
 ({									\
 	long __gu_err = 0;						\
-	unsigned long __gu_val;						\
+	unsigned long __gu_val = 0;					\
 	might_fault();							\
 	__get_user_size(__gu_val, (ptr), (size), __gu_err);		\
 	(x) = (__force __typeof__(*(ptr)))__gu_val;			\
--- zfcpdump-kernel-4.4.orig/arch/m32r/kernel/setup.c
+++ zfcpdump-kernel-4.4/arch/m32r/kernel/setup.c
@@ -81,7 +81,10 @@ static struct resource code_resource = {
 };
 
 unsigned long memory_start;
+EXPORT_SYMBOL(memory_start);
+
 unsigned long memory_end;
+EXPORT_SYMBOL(memory_end);
 
 void __init setup_arch(char **);
 int get_cpuinfo(char *);
--- zfcpdump-kernel-4.4.orig/arch/metag/include/asm/atomic_lnkget.h
+++ zfcpdump-kernel-4.4/arch/metag/include/asm/atomic_lnkget.h
@@ -61,7 +61,7 @@ static inline int atomic_##op##_return(i
 		"	CMPT	%0, #HI(0x02000000)\n"			\
 		"	BNZ 1b\n"					\
 		: "=&d" (temp), "=&da" (result)				\
-		: "da" (&v->counter), "bd" (i)				\
+		: "da" (&v->counter), "br" (i)				\
 		: "cc");						\
 									\
 	smp_mb();							\
--- zfcpdump-kernel-4.4.orig/arch/metag/include/asm/cmpxchg_lnkget.h
+++ zfcpdump-kernel-4.4/arch/metag/include/asm/cmpxchg_lnkget.h
@@ -73,7 +73,7 @@ static inline unsigned long __cmpxchg_u3
 		      "	DCACHE	[%2], %0\n"
 #endif
 		      "2:\n"
-		      : "=&d" (temp), "=&da" (retval)
+		      : "=&d" (temp), "=&d" (retval)
 		      : "da" (m), "bd" (old), "da" (new)
 		      : "cc"
 		      );
--- zfcpdump-kernel-4.4.orig/arch/metag/include/asm/uaccess.h
+++ zfcpdump-kernel-4.4/arch/metag/include/asm/uaccess.h
@@ -204,8 +204,9 @@ extern unsigned long __must_check __copy
 static inline unsigned long
 copy_from_user(void *to, const void __user *from, unsigned long n)
 {
-	if (access_ok(VERIFY_READ, from, n))
+	if (likely(access_ok(VERIFY_READ, from, n)))
 		return __copy_user_zeroing(to, from, n);
+	memset(to, 0, n);
 	return n;
 }
 
--- zfcpdump-kernel-4.4.orig/arch/metag/kernel/module.c
+++ zfcpdump-kernel-4.4/arch/metag/kernel/module.c
@@ -176,8 +176,8 @@ static uint32_t do_plt_call(void *locati
 	tramp[1] = 0xac000001 | ((val & 0x0000ffff) << 3);
 
 	/* Init, or core PLT? */
-	if (location >= mod->module_core
-	    && location < mod->module_core + mod->core_size)
+	if (location >= mod->core_layout.base
+	    && location < mod->core_layout.base + mod->core_layout.size)
 		entry = (void *)sechdrs[mod->arch.core_plt_section].sh_addr;
 	else
 		entry = (void *)sechdrs[mod->arch.init_plt_section].sh_addr;
--- zfcpdump-kernel-4.4.orig/arch/microblaze/include/asm/uaccess.h
+++ zfcpdump-kernel-4.4/arch/microblaze/include/asm/uaccess.h
@@ -227,7 +227,7 @@ extern long __user_bad(void);
 
 #define __get_user(x, ptr)						\
 ({									\
-	unsigned long __gu_val;						\
+	unsigned long __gu_val = 0;					\
 	/*unsigned long __gu_ptr = (unsigned long)(ptr);*/		\
 	long __gu_err;							\
 	switch (sizeof(*(ptr))) {					\
@@ -373,10 +373,13 @@ extern long __user_bad(void);
 static inline long copy_from_user(void *to,
 		const void __user *from, unsigned long n)
 {
+	unsigned long res = n;
 	might_fault();
-	if (access_ok(VERIFY_READ, from, n))
-		return __copy_from_user(to, from, n);
-	return n;
+	if (likely(access_ok(VERIFY_READ, from, n)))
+		res = __copy_from_user(to, from, n);
+	if (unlikely(res))
+		memset(to + (n - res), 0, res);
+	return res;
 }
 
 #define __copy_to_user(to, from, n)	\
--- zfcpdump-kernel-4.4.orig/arch/mips/Kconfig
+++ zfcpdump-kernel-4.4/arch/mips/Kconfig
@@ -2155,7 +2155,7 @@ config MIPS_MT_SMP
 	select CPU_MIPSR2_IRQ_VI
 	select CPU_MIPSR2_IRQ_EI
 	select SYNC_R4K
-	select MIPS_GIC_IPI
+	select MIPS_GIC_IPI if MIPS_GIC
 	select MIPS_MT
 	select SMP
 	select SMP_UP
@@ -2253,7 +2253,7 @@ config MIPS_VPE_APSP_API_MT
 config MIPS_CMP
 	bool "MIPS CMP framework support (DEPRECATED)"
 	depends on SYS_SUPPORTS_MIPS_CMP && !CPU_MIPSR6
-	select MIPS_GIC_IPI
+	select MIPS_GIC_IPI if MIPS_GIC
 	select SMP
 	select SYNC_R4K
 	select SYS_SUPPORTS_SMP
@@ -2273,7 +2273,7 @@ config MIPS_CPS
 	select MIPS_CM
 	select MIPS_CPC
 	select MIPS_CPS_PM if HOTPLUG_CPU
-	select MIPS_GIC_IPI
+	select MIPS_GIC_IPI if MIPS_GIC
 	select SMP
 	select SYNC_R4K if (CEVT_R4K || CSRC_R4K)
 	select SYS_SUPPORTS_HOTPLUG_CPU
@@ -2292,6 +2292,7 @@ config MIPS_CPS_PM
 	bool
 
 config MIPS_GIC_IPI
+	depends on MIPS_GIC
 	bool
 
 config MIPS_CM
--- zfcpdump-kernel-4.4.orig/arch/mips/Kconfig.debug
+++ zfcpdump-kernel-4.4/arch/mips/Kconfig.debug
@@ -113,42 +113,6 @@ config SPINLOCK_TEST
 	help
 	  Add several files to the debugfs to test spinlock speed.
 
-if CPU_MIPSR6
-
-choice
-	prompt "Compact branch policy"
-	default MIPS_COMPACT_BRANCHES_OPTIMAL
-
-config MIPS_COMPACT_BRANCHES_NEVER
-	bool "Never (force delay slot branches)"
-	help
-	  Pass the -mcompact-branches=never flag to the compiler in order to
-	  force it to always emit branches with delay slots, and make no use
-	  of the compact branch instructions introduced by MIPSr6. This is
-	  useful if you suspect there may be an issue with compact branches in
-	  either the compiler or the CPU.
-
-config MIPS_COMPACT_BRANCHES_OPTIMAL
-	bool "Optimal (use where beneficial)"
-	help
-	  Pass the -mcompact-branches=optimal flag to the compiler in order for
-	  it to make use of compact branch instructions where it deems them
-	  beneficial, and use branches with delay slots elsewhere. This is the
-	  default compiler behaviour, and should be used unless you have a
-	  reason to choose otherwise.
-
-config MIPS_COMPACT_BRANCHES_ALWAYS
-	bool "Always (force compact branches)"
-	help
-	  Pass the -mcompact-branches=always flag to the compiler in order to
-	  force it to always emit compact branches, making no use of branch
-	  instructions with delay slots. This can result in more compact code
-	  which may be beneficial in some scenarios.
-
-endchoice
-
-endif # CPU_MIPSR6
-
 config SCACHE_DEBUGFS
 	bool "L2 cache debugfs entries"
 	depends on DEBUG_FS
--- zfcpdump-kernel-4.4.orig/arch/mips/Makefile
+++ zfcpdump-kernel-4.4/arch/mips/Makefile
@@ -204,10 +204,6 @@ toolchain-msa				:= $(call cc-option-yn,
 cflags-$(toolchain-msa)			+= -DTOOLCHAIN_SUPPORTS_MSA
 endif
 
-cflags-$(CONFIG_MIPS_COMPACT_BRANCHES_NEVER)	+= -mcompact-branches=never
-cflags-$(CONFIG_MIPS_COMPACT_BRANCHES_OPTIMAL)	+= -mcompact-branches=optimal
-cflags-$(CONFIG_MIPS_COMPACT_BRANCHES_ALWAYS)	+= -mcompact-branches=always
-
 #
 # Firmware support
 #
--- zfcpdump-kernel-4.4.orig/arch/mips/alchemy/devboards/db1000.c
+++ zfcpdump-kernel-4.4/arch/mips/alchemy/devboards/db1000.c
@@ -503,15 +503,15 @@ int __init db1000_dev_setup(void)
 	if (board == BCSR_WHOAMI_DB1500) {
 		c0 = AU1500_GPIO2_INT;
 		c1 = AU1500_GPIO5_INT;
-		d0 = AU1500_GPIO0_INT;
-		d1 = AU1500_GPIO3_INT;
+		d0 = 0;	/* GPIO number, NOT irq! */
+		d1 = 3; /* GPIO number, NOT irq! */
 		s0 = AU1500_GPIO1_INT;
 		s1 = AU1500_GPIO4_INT;
 	} else if (board == BCSR_WHOAMI_DB1100) {
 		c0 = AU1100_GPIO2_INT;
 		c1 = AU1100_GPIO5_INT;
-		d0 = AU1100_GPIO0_INT;
-		d1 = AU1100_GPIO3_INT;
+		d0 = 0; /* GPIO number, NOT irq! */
+		d1 = 3; /* GPIO number, NOT irq! */
 		s0 = AU1100_GPIO1_INT;
 		s1 = AU1100_GPIO4_INT;
 
@@ -545,15 +545,15 @@ int __init db1000_dev_setup(void)
 	} else if (board == BCSR_WHOAMI_DB1000) {
 		c0 = AU1000_GPIO2_INT;
 		c1 = AU1000_GPIO5_INT;
-		d0 = AU1000_GPIO0_INT;
-		d1 = AU1000_GPIO3_INT;
+		d0 = 0; /* GPIO number, NOT irq! */
+		d1 = 3; /* GPIO number, NOT irq! */
 		s0 = AU1000_GPIO1_INT;
 		s1 = AU1000_GPIO4_INT;
 		platform_add_devices(db1000_devs, ARRAY_SIZE(db1000_devs));
 	} else if ((board == BCSR_WHOAMI_PB1500) ||
 		   (board == BCSR_WHOAMI_PB1500R2)) {
 		c0 = AU1500_GPIO203_INT;
-		d0 = AU1500_GPIO201_INT;
+		d0 = 1; /* GPIO number, NOT irq! */
 		s0 = AU1500_GPIO202_INT;
 		twosocks = 0;
 		flashsize = 64;
@@ -566,7 +566,7 @@ int __init db1000_dev_setup(void)
 		 */
 	} else if (board == BCSR_WHOAMI_PB1100) {
 		c0 = AU1100_GPIO11_INT;
-		d0 = AU1100_GPIO9_INT;
+		d0 = 9; /* GPIO number, NOT irq! */
 		s0 = AU1100_GPIO10_INT;
 		twosocks = 0;
 		flashsize = 64;
@@ -583,7 +583,6 @@ int __init db1000_dev_setup(void)
 	} else
 		return 0; /* unknown board, no further dev setup to do */
 
-	irq_set_irq_type(d0, IRQ_TYPE_EDGE_BOTH);
 	irq_set_irq_type(c0, IRQ_TYPE_LEVEL_LOW);
 	irq_set_irq_type(s0, IRQ_TYPE_LEVEL_LOW);
 
@@ -597,7 +596,6 @@ int __init db1000_dev_setup(void)
 		c0, d0, /*s0*/0, 0, 0);
 
 	if (twosocks) {
-		irq_set_irq_type(d1, IRQ_TYPE_EDGE_BOTH);
 		irq_set_irq_type(c1, IRQ_TYPE_LEVEL_LOW);
 		irq_set_irq_type(s1, IRQ_TYPE_LEVEL_LOW);
 
--- zfcpdump-kernel-4.4.orig/arch/mips/alchemy/devboards/db1550.c
+++ zfcpdump-kernel-4.4/arch/mips/alchemy/devboards/db1550.c
@@ -514,7 +514,7 @@ static void __init db1550_devices(void)
 		AU1000_PCMCIA_MEM_PHYS_ADDR  + 0x000400000 - 1,
 		AU1000_PCMCIA_IO_PHYS_ADDR,
 		AU1000_PCMCIA_IO_PHYS_ADDR   + 0x000010000 - 1,
-		AU1550_GPIO3_INT, AU1550_GPIO0_INT,
+		AU1550_GPIO3_INT, 0,
 		/*AU1550_GPIO21_INT*/0, 0, 0);
 
 	db1x_register_pcmcia_socket(
@@ -524,7 +524,7 @@ static void __init db1550_devices(void)
 		AU1000_PCMCIA_MEM_PHYS_ADDR  + 0x004400000 - 1,
 		AU1000_PCMCIA_IO_PHYS_ADDR   + 0x004000000,
 		AU1000_PCMCIA_IO_PHYS_ADDR   + 0x004010000 - 1,
-		AU1550_GPIO5_INT, AU1550_GPIO1_INT,
+		AU1550_GPIO5_INT, 1,
 		/*AU1550_GPIO22_INT*/0, 0, 1);
 
 	platform_device_register(&db1550_nand_dev);
--- zfcpdump-kernel-4.4.orig/arch/mips/ath79/early_printk.c
+++ zfcpdump-kernel-4.4/arch/mips/ath79/early_printk.c
@@ -31,13 +31,15 @@ static inline void prom_putchar_wait(voi
 	} while (1);
 }
 
+#define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE)
+
 static void prom_putchar_ar71xx(unsigned char ch)
 {
 	void __iomem *base = (void __iomem *)(KSEG1ADDR(AR71XX_UART_BASE));
 
-	prom_putchar_wait(base + UART_LSR * 4, UART_LSR_THRE, UART_LSR_THRE);
+	prom_putchar_wait(base + UART_LSR * 4, BOTH_EMPTY, BOTH_EMPTY);
 	__raw_writel(ch, base + UART_TX * 4);
-	prom_putchar_wait(base + UART_LSR * 4, UART_LSR_THRE, UART_LSR_THRE);
+	prom_putchar_wait(base + UART_LSR * 4, BOTH_EMPTY, BOTH_EMPTY);
 }
 
 static void prom_putchar_ar933x(unsigned char ch)
--- zfcpdump-kernel-4.4.orig/arch/mips/include/asm/asmmacro.h
+++ zfcpdump-kernel-4.4/arch/mips/include/asm/asmmacro.h
@@ -135,6 +135,7 @@
 	ldc1	$f28, THREAD_FPR28(\thread)
 	ldc1	$f30, THREAD_FPR30(\thread)
 	ctc1	\tmp, fcr31
+	.set	pop
 	.endm
 
 	.macro	fpu_restore_16odd thread
@@ -298,21 +299,21 @@
 	.set	pop
 	.endm
 
-	.macro	copy_u_w	ws, n
+	.macro	copy_s_w	ws, n
 	.set	push
 	.set	mips32r2
 	.set	fp=64
 	.set	msa
-	copy_u.w $1, $w\ws[\n]
+	copy_s.w $1, $w\ws[\n]
 	.set	pop
 	.endm
 
-	.macro	copy_u_d	ws, n
+	.macro	copy_s_d	ws, n
 	.set	push
 	.set	mips64r2
 	.set	fp=64
 	.set	msa
-	copy_u.d $1, $w\ws[\n]
+	copy_s.d $1, $w\ws[\n]
 	.set	pop
 	.endm
 
@@ -346,8 +347,8 @@
 #define STH_MSA_INSN		0x5800081f
 #define STW_MSA_INSN		0x5800082f
 #define STD_MSA_INSN		0x5800083f
-#define COPY_UW_MSA_INSN	0x58f00056
-#define COPY_UD_MSA_INSN	0x58f80056
+#define COPY_SW_MSA_INSN	0x58b00056
+#define COPY_SD_MSA_INSN	0x58b80056
 #define INSERT_W_MSA_INSN	0x59300816
 #define INSERT_D_MSA_INSN	0x59380816
 #else
@@ -361,8 +362,8 @@
 #define STH_MSA_INSN		0x78000825
 #define STW_MSA_INSN		0x78000826
 #define STD_MSA_INSN		0x78000827
-#define COPY_UW_MSA_INSN	0x78f00059
-#define COPY_UD_MSA_INSN	0x78f80059
+#define COPY_SW_MSA_INSN	0x78b00059
+#define COPY_SD_MSA_INSN	0x78b80059
 #define INSERT_W_MSA_INSN	0x79300819
 #define INSERT_D_MSA_INSN	0x79380819
 #endif
@@ -393,7 +394,7 @@
 	.set	push
 	.set	noat
 	SET_HARDFLOAT
-	addu	$1, \base, \off
+	PTR_ADDU $1, \base, \off
 	.word	LDB_MSA_INSN | (\wd << 6)
 	.set	pop
 	.endm
@@ -402,7 +403,7 @@
 	.set	push
 	.set	noat
 	SET_HARDFLOAT
-	addu	$1, \base, \off
+	PTR_ADDU $1, \base, \off
 	.word	LDH_MSA_INSN | (\wd << 6)
 	.set	pop
 	.endm
@@ -411,7 +412,7 @@
 	.set	push
 	.set	noat
 	SET_HARDFLOAT
-	addu	$1, \base, \off
+	PTR_ADDU $1, \base, \off
 	.word	LDW_MSA_INSN | (\wd << 6)
 	.set	pop
 	.endm
@@ -420,7 +421,7 @@
 	.set	push
 	.set	noat
 	SET_HARDFLOAT
-	addu	$1, \base, \off
+	PTR_ADDU $1, \base, \off
 	.word	LDD_MSA_INSN | (\wd << 6)
 	.set	pop
 	.endm
@@ -429,7 +430,7 @@
 	.set	push
 	.set	noat
 	SET_HARDFLOAT
-	addu	$1, \base, \off
+	PTR_ADDU $1, \base, \off
 	.word	STB_MSA_INSN | (\wd << 6)
 	.set	pop
 	.endm
@@ -438,7 +439,7 @@
 	.set	push
 	.set	noat
 	SET_HARDFLOAT
-	addu	$1, \base, \off
+	PTR_ADDU $1, \base, \off
 	.word	STH_MSA_INSN | (\wd << 6)
 	.set	pop
 	.endm
@@ -447,7 +448,7 @@
 	.set	push
 	.set	noat
 	SET_HARDFLOAT
-	addu	$1, \base, \off
+	PTR_ADDU $1, \base, \off
 	.word	STW_MSA_INSN | (\wd << 6)
 	.set	pop
 	.endm
@@ -456,26 +457,26 @@
 	.set	push
 	.set	noat
 	SET_HARDFLOAT
-	addu	$1, \base, \off
+	PTR_ADDU $1, \base, \off
 	.word	STD_MSA_INSN | (\wd << 6)
 	.set	pop
 	.endm
 
-	.macro	copy_u_w	ws, n
+	.macro	copy_s_w	ws, n
 	.set	push
 	.set	noat
 	SET_HARDFLOAT
 	.insn
-	.word	COPY_UW_MSA_INSN | (\n << 16) | (\ws << 11)
+	.word	COPY_SW_MSA_INSN | (\n << 16) | (\ws << 11)
 	.set	pop
 	.endm
 
-	.macro	copy_u_d	ws, n
+	.macro	copy_s_d	ws, n
 	.set	push
 	.set	noat
 	SET_HARDFLOAT
 	.insn
-	.word	COPY_UD_MSA_INSN | (\n << 16) | (\ws << 11)
+	.word	COPY_SD_MSA_INSN | (\n << 16) | (\ws << 11)
 	.set	pop
 	.endm
 
--- zfcpdump-kernel-4.4.orig/arch/mips/include/asm/cacheflush.h
+++ zfcpdump-kernel-4.4/arch/mips/include/asm/cacheflush.h
@@ -51,7 +51,6 @@ extern void (*flush_cache_range)(struct
 	unsigned long start, unsigned long end);
 extern void (*flush_cache_page)(struct vm_area_struct *vma, unsigned long page, unsigned long pfn);
 extern void __flush_dcache_page(struct page *page);
-extern void __flush_icache_page(struct vm_area_struct *vma, struct page *page);
 
 #define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 1
 static inline void flush_dcache_page(struct page *page)
@@ -77,11 +76,6 @@ static inline void flush_anon_page(struc
 static inline void flush_icache_page(struct vm_area_struct *vma,
 	struct page *page)
 {
-	if (!cpu_has_ic_fills_f_dc && (vma->vm_flags & VM_EXEC) &&
-	    Page_dcache_dirty(page)) {
-		__flush_icache_page(vma, page);
-		ClearPageDcacheDirty(page);
-	}
 }
 
 extern void (*flush_icache_range)(unsigned long start, unsigned long end);
--- zfcpdump-kernel-4.4.orig/arch/mips/include/asm/kvm_host.h
+++ zfcpdump-kernel-4.4/arch/mips/include/asm/kvm_host.h
@@ -372,6 +372,7 @@ struct kvm_mips_tlb {
 #define KVM_MIPS_GUEST_TLB_SIZE	64
 struct kvm_vcpu_arch {
 	void *host_ebase, *guest_ebase;
+	int (*vcpu_run)(struct kvm_run *run, struct kvm_vcpu *vcpu);
 	unsigned long host_stack;
 	unsigned long host_gp;
 
@@ -784,7 +785,7 @@ extern enum emulation_result kvm_mips_co
 
 uint32_t kvm_mips_read_count(struct kvm_vcpu *vcpu);
 void kvm_mips_write_count(struct kvm_vcpu *vcpu, uint32_t count);
-void kvm_mips_write_compare(struct kvm_vcpu *vcpu, uint32_t compare);
+void kvm_mips_write_compare(struct kvm_vcpu *vcpu, uint32_t compare, bool ack);
 void kvm_mips_init_count(struct kvm_vcpu *vcpu);
 int kvm_mips_set_count_ctl(struct kvm_vcpu *vcpu, s64 count_ctl);
 int kvm_mips_set_count_resume(struct kvm_vcpu *vcpu, s64 count_resume);
--- zfcpdump-kernel-4.4.orig/arch/mips/include/asm/mach-paravirt/kernel-entry-init.h
+++ zfcpdump-kernel-4.4/arch/mips/include/asm/mach-paravirt/kernel-entry-init.h
@@ -11,11 +11,13 @@
 #define CP0_EBASE $15, 1
 
 	.macro  kernel_entry_setup
+#ifdef CONFIG_SMP
 	mfc0	t0, CP0_EBASE
 	andi	t0, t0, 0x3ff		# CPUNum
 	beqz	t0, 1f
 	# CPUs other than zero goto smp_bootstrap
 	j	smp_bootstrap
+#endif /* CONFIG_SMP */
 
 1:
 	.endm
--- zfcpdump-kernel-4.4.orig/arch/mips/include/asm/msa.h
+++ zfcpdump-kernel-4.4/arch/mips/include/asm/msa.h
@@ -147,6 +147,19 @@ static inline void restore_msa(struct ta
 		_restore_msa(t);
 }
 
+static inline void init_msa_upper(void)
+{
+	/*
+	 * Check cpu_has_msa only if it's a constant. This will allow the
+	 * compiler to optimise out code for CPUs without MSA without adding
+	 * an extra redundant check for CPUs with MSA.
+	 */
+	if (__builtin_constant_p(cpu_has_msa) && !cpu_has_msa)
+		return;
+
+	_init_msa_upper();
+}
+
 #ifdef TOOLCHAIN_SUPPORTS_MSA
 
 #define __BUILD_MSA_CTL_REG(name, cs)				\
--- zfcpdump-kernel-4.4.orig/arch/mips/include/asm/page.h
+++ zfcpdump-kernel-4.4/arch/mips/include/asm/page.h
@@ -33,7 +33,7 @@
 #define PAGE_SHIFT	16
 #endif
 #define PAGE_SIZE	(_AC(1,UL) << PAGE_SHIFT)
-#define PAGE_MASK	(~(PAGE_SIZE - 1))
+#define PAGE_MASK	(~((1 << PAGE_SHIFT) - 1))
 
 /*
  * This is used for calculating the real page sizes
--- zfcpdump-kernel-4.4.orig/arch/mips/include/asm/pgtable.h
+++ zfcpdump-kernel-4.4/arch/mips/include/asm/pgtable.h
@@ -127,10 +127,14 @@ do {									\
 	}								\
 } while(0)
 
+static inline void set_pte_at(struct mm_struct *mm, unsigned long addr,
+			      pte_t *ptep, pte_t pteval);
+
 #if defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_CPU_MIPS32)
 
 #define pte_none(pte)		(!(((pte).pte_high) & ~_PAGE_GLOBAL))
 #define pte_present(pte)	((pte).pte_low & _PAGE_PRESENT)
+#define pte_no_exec(pte)	((pte).pte_low & _PAGE_NO_EXEC)
 
 static inline void set_pte(pte_t *ptep, pte_t pte)
 {
@@ -148,7 +152,6 @@ static inline void set_pte(pte_t *ptep,
 			buddy->pte_high |= _PAGE_GLOBAL;
 	}
 }
-#define set_pte_at(mm, addr, ptep, pteval) set_pte(ptep, pteval)
 
 static inline void pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
 {
@@ -166,6 +169,7 @@ static inline void pte_clear(struct mm_s
 
 #define pte_none(pte)		(!(pte_val(pte) & ~_PAGE_GLOBAL))
 #define pte_present(pte)	(pte_val(pte) & _PAGE_PRESENT)
+#define pte_no_exec(pte)	(pte_val(pte) & _PAGE_NO_EXEC)
 
 /*
  * Certain architectures need to do special things when pte's
@@ -218,7 +222,6 @@ static inline void set_pte(pte_t *ptep,
 	}
 #endif
 }
-#define set_pte_at(mm, addr, ptep, pteval) set_pte(ptep, pteval)
 
 static inline void pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
 {
@@ -234,6 +237,22 @@ static inline void pte_clear(struct mm_s
 }
 #endif
 
+static inline void set_pte_at(struct mm_struct *mm, unsigned long addr,
+			      pte_t *ptep, pte_t pteval)
+{
+	extern void __update_cache(unsigned long address, pte_t pte);
+
+	if (!pte_present(pteval))
+		goto cache_sync_done;
+
+	if (pte_present(*ptep) && (pte_pfn(*ptep) == pte_pfn(pteval)))
+		goto cache_sync_done;
+
+	__update_cache(addr, pteval);
+cache_sync_done:
+	set_pte(ptep, pteval);
+}
+
 /*
  * (pmds are folded into puds so this doesn't get actually called,
  * but the define is needed for a generic inline function.)
@@ -353,7 +372,7 @@ static inline pte_t pte_mkdirty(pte_t pt
 static inline pte_t pte_mkyoung(pte_t pte)
 {
 	pte_val(pte) |= _PAGE_ACCESSED;
-#ifdef CONFIG_CPU_MIPSR2
+#if defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_CPU_MIPSR6)
 	if (!(pte_val(pte) & _PAGE_NO_READ))
 		pte_val(pte) |= _PAGE_SILENT_READ;
 	else
@@ -430,15 +449,12 @@ static inline pte_t pte_modify(pte_t pte
 
 extern void __update_tlb(struct vm_area_struct *vma, unsigned long address,
 	pte_t pte);
-extern void __update_cache(struct vm_area_struct *vma, unsigned long address,
-	pte_t pte);
 
 static inline void update_mmu_cache(struct vm_area_struct *vma,
 	unsigned long address, pte_t *ptep)
 {
 	pte_t pte = *ptep;
 	__update_tlb(vma, address, pte);
-	__update_cache(vma, address, pte);
 }
 
 static inline void update_mmu_cache_pmd(struct vm_area_struct *vma,
@@ -560,7 +576,7 @@ static inline pmd_t pmd_mkyoung(pmd_t pm
 {
 	pmd_val(pmd) |= _PAGE_ACCESSED;
 
-#ifdef CONFIG_CPU_MIPSR2
+#if defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_CPU_MIPSR6)
 	if (!(pmd_val(pmd) & _PAGE_NO_READ))
 		pmd_val(pmd) |= _PAGE_SILENT_READ;
 	else
--- zfcpdump-kernel-4.4.orig/arch/mips/include/asm/processor.h
+++ zfcpdump-kernel-4.4/arch/mips/include/asm/processor.h
@@ -45,7 +45,7 @@ extern unsigned int vced_count, vcei_cou
  * User space process size: 2GB. This is hardcoded into a few places,
  * so don't change it unless you know what you are doing.
  */
-#define TASK_SIZE	0x7fff8000UL
+#define TASK_SIZE	0x80000000UL
 #endif
 
 #define STACK_TOP_MAX	TASK_SIZE
--- zfcpdump-kernel-4.4.orig/arch/mips/include/asm/switch_to.h
+++ zfcpdump-kernel-4.4/arch/mips/include/asm/switch_to.h
@@ -105,7 +105,7 @@ do {									\
 	__clear_software_ll_bit();					\
 	if (cpu_has_userlocal)						\
 		write_c0_userlocal(task_thread_info(next)->tp_value);	\
-	__restore_watch();						\
+	__restore_watch(next);						\
 	(last) = resume(prev, next, task_thread_info(next));		\
 } while (0)
 
--- zfcpdump-kernel-4.4.orig/arch/mips/include/asm/syscall.h
+++ zfcpdump-kernel-4.4/arch/mips/include/asm/syscall.h
@@ -101,10 +101,8 @@ static inline void syscall_get_arguments
 	/* O32 ABI syscall() - Either 64-bit with O32 or 32-bit */
 	if ((config_enabled(CONFIG_32BIT) ||
 	    test_tsk_thread_flag(task, TIF_32BIT_REGS)) &&
-	    (regs->regs[2] == __NR_syscall)) {
+	    (regs->regs[2] == __NR_syscall))
 		i++;
-		n++;
-	}
 
 	while (n--)
 		ret |= mips_get_syscall_arg(args++, task, regs, i++);
--- zfcpdump-kernel-4.4.orig/arch/mips/include/asm/uaccess.h
+++ zfcpdump-kernel-4.4/arch/mips/include/asm/uaccess.h
@@ -14,6 +14,7 @@
 #include <linux/kernel.h>
 #include <linux/errno.h>
 #include <linux/thread_info.h>
+#include <linux/string.h>
 #include <asm/asm-eva.h>
 
 /*
@@ -1170,6 +1171,8 @@ extern size_t __copy_in_user_eva(void *_
 			__cu_len = __invoke_copy_from_user(__cu_to,	\
 							   __cu_from,	\
 							   __cu_len);   \
+		} else {						\
+			memset(__cu_to, 0, __cu_len);			\
 		}							\
 	}								\
 	__cu_len;							\
--- zfcpdump-kernel-4.4.orig/arch/mips/include/asm/uprobes.h
+++ zfcpdump-kernel-4.4/arch/mips/include/asm/uprobes.h
@@ -36,7 +36,6 @@ struct arch_uprobe {
 	unsigned long	resume_epc;
 	u32	insn[2];
 	u32	ixol[2];
-	union	mips_instruction orig_inst[MAX_UINSN_BYTES / 4];
 };
 
 struct arch_uprobe_task {
--- zfcpdump-kernel-4.4.orig/arch/mips/include/asm/watch.h
+++ zfcpdump-kernel-4.4/arch/mips/include/asm/watch.h
@@ -12,21 +12,21 @@
 
 #include <asm/mipsregs.h>
 
-void mips_install_watch_registers(void);
+void mips_install_watch_registers(struct task_struct *t);
 void mips_read_watch_registers(void);
 void mips_clear_watch_registers(void);
 void mips_probe_watch_registers(struct cpuinfo_mips *c);
 
 #ifdef CONFIG_HARDWARE_WATCHPOINTS
-#define __restore_watch() do {						\
+#define __restore_watch(task) do {					\
 	if (unlikely(test_bit(TIF_LOAD_WATCH,				\
-			      &current_thread_info()->flags))) {	\
-		mips_install_watch_registers();				\
+			      &task_thread_info(task)->flags))) {	\
+		mips_install_watch_registers(task);			\
 	}								\
 } while (0)
 
 #else
-#define __restore_watch() do {} while (0)
+#define __restore_watch(task) do {} while (0)
 #endif
 
 #endif /* _ASM_WATCH_H */
--- zfcpdump-kernel-4.4.orig/arch/mips/include/uapi/asm/siginfo.h
+++ zfcpdump-kernel-4.4/arch/mips/include/uapi/asm/siginfo.h
@@ -28,7 +28,7 @@
 
 #define __ARCH_SIGSYS
 
-#include <uapi/asm-generic/siginfo.h>
+#include <asm-generic/siginfo.h>
 
 /* We can't use generic siginfo_t, because our si_code and si_errno are swapped */
 typedef struct siginfo {
@@ -42,13 +42,13 @@ typedef struct siginfo {
 
 		/* kill() */
 		struct {
-			pid_t _pid;		/* sender's pid */
+			__kernel_pid_t _pid;	/* sender's pid */
 			__ARCH_SI_UID_T _uid;	/* sender's uid */
 		} _kill;
 
 		/* POSIX.1b timers */
 		struct {
-			timer_t _tid;		/* timer id */
+			__kernel_timer_t _tid;	/* timer id */
 			int _overrun;		/* overrun count */
 			char _pad[sizeof( __ARCH_SI_UID_T) - sizeof(int)];
 			sigval_t _sigval;	/* same as below */
@@ -57,26 +57,26 @@ typedef struct siginfo {
 
 		/* POSIX.1b signals */
 		struct {
-			pid_t _pid;		/* sender's pid */
+			__kernel_pid_t _pid;	/* sender's pid */
 			__ARCH_SI_UID_T _uid;	/* sender's uid */
 			sigval_t _sigval;
 		} _rt;
 
 		/* SIGCHLD */
 		struct {
-			pid_t _pid;		/* which child */
+			__kernel_pid_t _pid;	/* which child */
 			__ARCH_SI_UID_T _uid;	/* sender's uid */
 			int _status;		/* exit code */
-			clock_t _utime;
-			clock_t _stime;
+			__kernel_clock_t _utime;
+			__kernel_clock_t _stime;
 		} _sigchld;
 
 		/* IRIX SIGCHLD */
 		struct {
-			pid_t _pid;		/* which child */
-			clock_t _utime;
+			__kernel_pid_t _pid;	/* which child */
+			__kernel_clock_t _utime;
 			int _status;		/* exit code */
-			clock_t _stime;
+			__kernel_clock_t _stime;
 		} _irix_sigchld;
 
 		/* SIGILL, SIGFPE, SIGSEGV, SIGBUS */
@@ -118,6 +118,4 @@ typedef struct siginfo {
 #define SI_TIMER __SI_CODE(__SI_TIMER, -3) /* sent by timer expiration */
 #define SI_MESGQ __SI_CODE(__SI_MESGQ, -4) /* sent by real time mesq state change */
 
-#include <asm-generic/siginfo.h>
-
 #endif /* _UAPI_ASM_SIGINFO_H */
--- zfcpdump-kernel-4.4.orig/arch/mips/kernel/csrc-r4k.c
+++ zfcpdump-kernel-4.4/arch/mips/kernel/csrc-r4k.c
@@ -23,7 +23,7 @@ static struct clocksource clocksource_mi
 	.flags		= CLOCK_SOURCE_IS_CONTINUOUS,
 };
 
-static u64 notrace r4k_read_sched_clock(void)
+static u64 __maybe_unused notrace r4k_read_sched_clock(void)
 {
 	return read_c0_count();
 }
@@ -82,7 +82,9 @@ int __init init_r4k_clocksource(void)
 
 	clocksource_register_hz(&clocksource_mips, mips_hpt_frequency);
 
+#ifndef CONFIG_CPU_FREQ
 	sched_clock_register(r4k_read_sched_clock, 32, mips_hpt_frequency);
+#endif
 
 	return 0;
 }
--- zfcpdump-kernel-4.4.orig/arch/mips/kernel/mips-r2-to-r6-emul.c
+++ zfcpdump-kernel-4.4/arch/mips/kernel/mips-r2-to-r6-emul.c
@@ -28,6 +28,7 @@
 #include <asm/inst.h>
 #include <asm/mips-r2-to-r6-emul.h>
 #include <asm/local.h>
+#include <asm/mipsregs.h>
 #include <asm/ptrace.h>
 #include <asm/uaccess.h>
 
@@ -1163,7 +1164,9 @@ fpu_emul:
 		regs->regs[31] = r31;
 		regs->cp0_epc = epc;
 		if (!used_math()) {     /* First time FPU user.  */
+			preempt_disable();
 			err = init_fpu();
+			preempt_enable();
 			set_used_math();
 		}
 		lose_fpu(1);    /* Save FPU state for the emulator. */
@@ -1251,10 +1254,10 @@ fpu_emul:
 			"	j	10b\n"
 			"	.previous\n"
 			"	.section	__ex_table,\"a\"\n"
-			"	.word	1b,8b\n"
-			"	.word	2b,8b\n"
-			"	.word	3b,8b\n"
-			"	.word	4b,8b\n"
+			STR(PTR) " 1b,8b\n"
+			STR(PTR) " 2b,8b\n"
+			STR(PTR) " 3b,8b\n"
+			STR(PTR) " 4b,8b\n"
 			"	.previous\n"
 			"	.set	pop\n"
 			: "+&r"(rt), "=&r"(rs),
@@ -1326,10 +1329,10 @@ fpu_emul:
 			"	j	10b\n"
 			"       .previous\n"
 			"	.section	__ex_table,\"a\"\n"
-			"	.word	1b,8b\n"
-			"	.word	2b,8b\n"
-			"	.word	3b,8b\n"
-			"	.word	4b,8b\n"
+			STR(PTR) " 1b,8b\n"
+			STR(PTR) " 2b,8b\n"
+			STR(PTR) " 3b,8b\n"
+			STR(PTR) " 4b,8b\n"
 			"	.previous\n"
 			"	.set	pop\n"
 			: "+&r"(rt), "=&r"(rs),
@@ -1397,10 +1400,10 @@ fpu_emul:
 			"	j	9b\n"
 			"	.previous\n"
 			"	.section        __ex_table,\"a\"\n"
-			"	.word	1b,8b\n"
-			"	.word	2b,8b\n"
-			"	.word	3b,8b\n"
-			"	.word	4b,8b\n"
+			STR(PTR) " 1b,8b\n"
+			STR(PTR) " 2b,8b\n"
+			STR(PTR) " 3b,8b\n"
+			STR(PTR) " 4b,8b\n"
 			"	.previous\n"
 			"	.set	pop\n"
 			: "+&r"(rt), "=&r"(rs),
@@ -1467,10 +1470,10 @@ fpu_emul:
 			"	j	9b\n"
 			"	.previous\n"
 			"	.section        __ex_table,\"a\"\n"
-			"	.word	1b,8b\n"
-			"	.word	2b,8b\n"
-			"	.word	3b,8b\n"
-			"	.word	4b,8b\n"
+			STR(PTR) " 1b,8b\n"
+			STR(PTR) " 2b,8b\n"
+			STR(PTR) " 3b,8b\n"
+			STR(PTR) " 4b,8b\n"
 			"	.previous\n"
 			"	.set	pop\n"
 			: "+&r"(rt), "=&r"(rs),
@@ -1582,14 +1585,14 @@ fpu_emul:
 			"	j	9b\n"
 			"	.previous\n"
 			"	.section        __ex_table,\"a\"\n"
-			"	.word	1b,8b\n"
-			"	.word	2b,8b\n"
-			"	.word	3b,8b\n"
-			"	.word	4b,8b\n"
-			"	.word	5b,8b\n"
-			"	.word	6b,8b\n"
-			"	.word	7b,8b\n"
-			"	.word	0b,8b\n"
+			STR(PTR) " 1b,8b\n"
+			STR(PTR) " 2b,8b\n"
+			STR(PTR) " 3b,8b\n"
+			STR(PTR) " 4b,8b\n"
+			STR(PTR) " 5b,8b\n"
+			STR(PTR) " 6b,8b\n"
+			STR(PTR) " 7b,8b\n"
+			STR(PTR) " 0b,8b\n"
 			"	.previous\n"
 			"	.set	pop\n"
 			: "+&r"(rt), "=&r"(rs),
@@ -1701,14 +1704,14 @@ fpu_emul:
 			"	j      9b\n"
 			"	.previous\n"
 			"	.section        __ex_table,\"a\"\n"
-			"	.word  1b,8b\n"
-			"	.word  2b,8b\n"
-			"	.word  3b,8b\n"
-			"	.word  4b,8b\n"
-			"	.word  5b,8b\n"
-			"	.word  6b,8b\n"
-			"	.word  7b,8b\n"
-			"	.word  0b,8b\n"
+			STR(PTR) " 1b,8b\n"
+			STR(PTR) " 2b,8b\n"
+			STR(PTR) " 3b,8b\n"
+			STR(PTR) " 4b,8b\n"
+			STR(PTR) " 5b,8b\n"
+			STR(PTR) " 6b,8b\n"
+			STR(PTR) " 7b,8b\n"
+			STR(PTR) " 0b,8b\n"
 			"	.previous\n"
 			"	.set    pop\n"
 			: "+&r"(rt), "=&r"(rs),
@@ -1820,14 +1823,14 @@ fpu_emul:
 			"	j	9b\n"
 			"	.previous\n"
 			"	.section        __ex_table,\"a\"\n"
-			"	.word	1b,8b\n"
-			"	.word	2b,8b\n"
-			"	.word	3b,8b\n"
-			"	.word	4b,8b\n"
-			"	.word	5b,8b\n"
-			"	.word	6b,8b\n"
-			"	.word	7b,8b\n"
-			"	.word	0b,8b\n"
+			STR(PTR) " 1b,8b\n"
+			STR(PTR) " 2b,8b\n"
+			STR(PTR) " 3b,8b\n"
+			STR(PTR) " 4b,8b\n"
+			STR(PTR) " 5b,8b\n"
+			STR(PTR) " 6b,8b\n"
+			STR(PTR) " 7b,8b\n"
+			STR(PTR) " 0b,8b\n"
 			"	.previous\n"
 			"	.set	pop\n"
 			: "+&r"(rt), "=&r"(rs),
@@ -1938,14 +1941,14 @@ fpu_emul:
 			"       j	9b\n"
 			"       .previous\n"
 			"       .section        __ex_table,\"a\"\n"
-			"       .word	1b,8b\n"
-			"       .word	2b,8b\n"
-			"       .word	3b,8b\n"
-			"       .word	4b,8b\n"
-			"       .word	5b,8b\n"
-			"       .word	6b,8b\n"
-			"       .word	7b,8b\n"
-			"       .word	0b,8b\n"
+			STR(PTR) " 1b,8b\n"
+			STR(PTR) " 2b,8b\n"
+			STR(PTR) " 3b,8b\n"
+			STR(PTR) " 4b,8b\n"
+			STR(PTR) " 5b,8b\n"
+			STR(PTR) " 6b,8b\n"
+			STR(PTR) " 7b,8b\n"
+			STR(PTR) " 0b,8b\n"
 			"       .previous\n"
 			"       .set	pop\n"
 			: "+&r"(rt), "=&r"(rs),
@@ -2000,7 +2003,7 @@ fpu_emul:
 			"j	2b\n"
 			".previous\n"
 			".section        __ex_table,\"a\"\n"
-			".word  1b, 3b\n"
+			STR(PTR) " 1b,3b\n"
 			".previous\n"
 			: "=&r"(res), "+&r"(err)
 			: "r"(vaddr), "i"(SIGSEGV)
@@ -2058,7 +2061,7 @@ fpu_emul:
 			"j	2b\n"
 			".previous\n"
 			".section        __ex_table,\"a\"\n"
-			".word	1b, 3b\n"
+			STR(PTR) " 1b,3b\n"
 			".previous\n"
 			: "+&r"(res), "+&r"(err)
 			: "r"(vaddr), "i"(SIGSEGV));
@@ -2119,7 +2122,7 @@ fpu_emul:
 			"j	2b\n"
 			".previous\n"
 			".section        __ex_table,\"a\"\n"
-			".word  1b, 3b\n"
+			STR(PTR) " 1b,3b\n"
 			".previous\n"
 			: "=&r"(res), "+&r"(err)
 			: "r"(vaddr), "i"(SIGSEGV)
@@ -2182,7 +2185,7 @@ fpu_emul:
 			"j	2b\n"
 			".previous\n"
 			".section        __ex_table,\"a\"\n"
-			".word	1b, 3b\n"
+			STR(PTR) " 1b,3b\n"
 			".previous\n"
 			: "+&r"(res), "+&r"(err)
 			: "r"(vaddr), "i"(SIGSEGV));
--- zfcpdump-kernel-4.4.orig/arch/mips/kernel/pm.c
+++ zfcpdump-kernel-4.4/arch/mips/kernel/pm.c
@@ -56,7 +56,7 @@ static void mips_cpu_restore(void)
 		write_c0_userlocal(current_thread_info()->tp_value);
 
 	/* Restore watch registers */
-	__restore_watch();
+	__restore_watch(current);
 }
 
 /**
--- zfcpdump-kernel-4.4.orig/arch/mips/kernel/process.c
+++ zfcpdump-kernel-4.4/arch/mips/kernel/process.c
@@ -457,7 +457,7 @@ unsigned long notrace unwind_stack_by_ad
 		    *sp + sizeof(*regs) <= stack_page + THREAD_SIZE - 32) {
 			regs = (struct pt_regs *)*sp;
 			pc = regs->cp0_epc;
-			if (__kernel_text_address(pc)) {
+			if (!user_mode(regs) && __kernel_text_address(pc)) {
 				*sp = regs->regs[29];
 				*ra = regs->regs[31];
 				return pc;
@@ -593,16 +593,19 @@ int mips_set_process_fp_mode(struct task
 		return -EOPNOTSUPP;
 
 	/* Avoid inadvertently triggering emulation */
-	if ((value & PR_FP_MODE_FR) && cpu_has_fpu &&
-	    !(current_cpu_data.fpu_id & MIPS_FPIR_F64))
+	if ((value & PR_FP_MODE_FR) && raw_cpu_has_fpu &&
+	    !(raw_current_cpu_data.fpu_id & MIPS_FPIR_F64))
 		return -EOPNOTSUPP;
-	if ((value & PR_FP_MODE_FRE) && cpu_has_fpu && !cpu_has_fre)
+	if ((value & PR_FP_MODE_FRE) && raw_cpu_has_fpu && !cpu_has_fre)
 		return -EOPNOTSUPP;
 
 	/* FR = 0 not supported in MIPS R6 */
-	if (!(value & PR_FP_MODE_FR) && cpu_has_fpu && cpu_has_mips_r6)
+	if (!(value & PR_FP_MODE_FR) && raw_cpu_has_fpu && cpu_has_mips_r6)
 		return -EOPNOTSUPP;
 
+	/* Proceed with the mode switch */
+	preempt_disable();
+
 	/* Save FP & vector context, then disable FPU & MSA */
 	if (task->signal == current->signal)
 		lose_fpu(1);
@@ -661,6 +664,7 @@ int mips_set_process_fp_mode(struct task
 
 	/* Allow threads to use FP again */
 	atomic_set(&task->mm->context.fp_mode_switching, 0);
+	preempt_enable();
 
 	return 0;
 }
--- zfcpdump-kernel-4.4.orig/arch/mips/kernel/ptrace.c
+++ zfcpdump-kernel-4.4/arch/mips/kernel/ptrace.c
@@ -57,8 +57,7 @@ static void init_fp_ctx(struct task_stru
 	/* Begin with data registers set to all 1s... */
 	memset(&target->thread.fpu.fpr, ~0, sizeof(target->thread.fpu.fpr));
 
-	/* ...and FCSR zeroed */
-	target->thread.fpu.fcr31 = 0;
+	/* FCSR has been preset by `mips_set_personality_nan'.  */
 
 	/*
 	 * Record that the target has "used" math, such that the context
@@ -80,6 +79,22 @@ void ptrace_disable(struct task_struct *
 }
 
 /*
+ * Poke at FCSR according to its mask.  Don't set the cause bits as
+ * this is currently not handled correctly in FP context restoration
+ * and will cause an oops if a corresponding enable bit is set.
+ */
+static void ptrace_setfcr31(struct task_struct *child, u32 value)
+{
+	u32 fcr31;
+	u32 mask;
+
+	value &= ~FPU_CSR_ALL_X;
+	fcr31 = child->thread.fpu.fcr31;
+	mask = boot_cpu_data.fpu_msk31;
+	child->thread.fpu.fcr31 = (value & ~mask) | (fcr31 & mask);
+}
+
+/*
  * Read a general register set.	 We always use the 64-bit format, even
  * for 32-bit kernels and for 32-bit processes on a 64-bit kernel.
  * Registers are sign extended to fill the available space.
@@ -159,9 +174,7 @@ int ptrace_setfpregs(struct task_struct
 {
 	union fpureg *fregs;
 	u64 fpr_val;
-	u32 fcr31;
 	u32 value;
-	u32 mask;
 	int i;
 
 	if (!access_ok(VERIFY_READ, data, 33 * 8))
@@ -176,9 +189,7 @@ int ptrace_setfpregs(struct task_struct
 	}
 
 	__get_user(value, data + 64);
-	fcr31 = child->thread.fpu.fcr31;
-	mask = boot_cpu_data.fpu_msk31;
-	child->thread.fpu.fcr31 = (value & ~mask) | (fcr31 & mask);
+	ptrace_setfcr31(child, value);
 
 	/* FIR may not be written.  */
 
@@ -808,7 +819,7 @@ long arch_ptrace(struct task_struct *chi
 			break;
 #endif
 		case FPC_CSR:
-			child->thread.fpu.fcr31 = data & ~FPU_CSR_ALL_X;
+			ptrace_setfcr31(child, data);
 			break;
 		case DSP_BASE ... DSP_BASE + 5: {
 			dspreg_t *dregs;
--- zfcpdump-kernel-4.4.orig/arch/mips/kernel/r4k_fpu.S
+++ zfcpdump-kernel-4.4/arch/mips/kernel/r4k_fpu.S
@@ -244,17 +244,17 @@ LEAF(\name)
 	.set	push
 	.set	noat
 #ifdef CONFIG_64BIT
-	copy_u_d \wr, 1
+	copy_s_d \wr, 1
 	EX sd	$1, \off(\base)
 #elif defined(CONFIG_CPU_LITTLE_ENDIAN)
-	copy_u_w \wr, 2
+	copy_s_w \wr, 2
 	EX sw	$1, \off(\base)
-	copy_u_w \wr, 3
+	copy_s_w \wr, 3
 	EX sw	$1, (\off+4)(\base)
 #else /* CONFIG_CPU_BIG_ENDIAN */
-	copy_u_w \wr, 2
+	copy_s_w \wr, 2
 	EX sw	$1, (\off+4)(\base)
-	copy_u_w \wr, 3
+	copy_s_w \wr, 3
 	EX sw	$1, \off(\base)
 #endif
 	.set	pop
--- zfcpdump-kernel-4.4.orig/arch/mips/kernel/scall64-n32.S
+++ zfcpdump-kernel-4.4/arch/mips/kernel/scall64-n32.S
@@ -344,7 +344,7 @@ EXPORT(sysn32_call_table)
 	PTR	sys_ni_syscall			/* available, was setaltroot */
 	PTR	sys_add_key
 	PTR	sys_request_key
-	PTR	sys_keyctl			/* 6245 */
+	PTR	compat_sys_keyctl		/* 6245 */
 	PTR	sys_set_thread_area
 	PTR	sys_inotify_init
 	PTR	sys_inotify_add_watch
--- zfcpdump-kernel-4.4.orig/arch/mips/kernel/scall64-o32.S
+++ zfcpdump-kernel-4.4/arch/mips/kernel/scall64-o32.S
@@ -500,7 +500,7 @@ EXPORT(sys32_call_table)
 	PTR	sys_ni_syscall			/* available, was setaltroot */
 	PTR	sys_add_key			/* 4280 */
 	PTR	sys_request_key
-	PTR	sys_keyctl
+	PTR	compat_sys_keyctl
 	PTR	sys_set_thread_area
 	PTR	sys_inotify_init
 	PTR	sys_inotify_add_watch		/* 4285 */
--- zfcpdump-kernel-4.4.orig/arch/mips/kernel/setup.c
+++ zfcpdump-kernel-4.4/arch/mips/kernel/setup.c
@@ -706,6 +706,9 @@ static void __init arch_mem_init(char **
 	for_each_memblock(reserved, reg)
 		if (reg->size != 0)
 			reserve_bootmem(reg->base, reg->size, BOOTMEM_DEFAULT);
+
+	reserve_bootmem_region(__pa_symbol(&__nosave_begin),
+			__pa_symbol(&__nosave_end)); /* Reserve for hibernation */
 }
 
 static void __init resource_init(void)
--- zfcpdump-kernel-4.4.orig/arch/mips/kernel/signal.c
+++ zfcpdump-kernel-4.4/arch/mips/kernel/signal.c
@@ -195,6 +195,9 @@ static int restore_msa_extcontext(void _
 	unsigned int csr;
 	int i, err;
 
+	if (!config_enabled(CONFIG_CPU_HAS_MSA))
+		return SIGSYS;
+
 	if (size != sizeof(*msa))
 		return -EINVAL;
 
@@ -398,8 +401,8 @@ int protected_restore_fp_context(void __
 	}
 
 fp_done:
-	if (used & USED_EXTCONTEXT)
-		err |= restore_extcontext(sc_to_extcontext(sc));
+	if (!err && (used & USED_EXTCONTEXT))
+		err = restore_extcontext(sc_to_extcontext(sc));
 
 	return err ?: sig;
 }
@@ -767,15 +770,7 @@ static void handle_signal(struct ksignal
 	sigset_t *oldset = sigmask_to_save();
 	int ret;
 	struct mips_abi *abi = current->thread.abi;
-#ifdef CONFIG_CPU_MICROMIPS
-	void *vdso;
-	unsigned long tmp = (unsigned long)current->mm->context.vdso;
-
-	set_isa16_mode(tmp);
-	vdso = (void *)tmp;
-#else
 	void *vdso = current->mm->context.vdso;
-#endif
 
 	if (regs->regs[0]) {
 		switch(regs->regs[2]) {
--- zfcpdump-kernel-4.4.orig/arch/mips/kernel/smp.c
+++ zfcpdump-kernel-4.4/arch/mips/kernel/smp.c
@@ -121,6 +121,7 @@ static inline void calculate_cpu_foreign
 	cpumask_t temp_foreign_map;
 
 	/* Re-calculate the mask */
+	cpumask_clear(&temp_foreign_map);
 	for_each_online_cpu(i) {
 		core_present = 0;
 		for_each_cpu(k, &temp_foreign_map)
@@ -173,6 +174,9 @@ asmlinkage void start_secondary(void)
 	cpumask_set_cpu(cpu, &cpu_coherent_mask);
 	notify_cpu_starting(cpu);
 
+	cpumask_set_cpu(cpu, &cpu_callin_map);
+	synchronise_count_slave(cpu);
+
 	set_cpu_online(cpu, true);
 
 	set_cpu_sibling_map(cpu);
@@ -180,10 +184,6 @@ asmlinkage void start_secondary(void)
 
 	calculate_cpu_foreign_map();
 
-	cpumask_set_cpu(cpu, &cpu_callin_map);
-
-	synchronise_count_slave(cpu);
-
 	/*
 	 * irq will be enabled in ->smp_finish(), enabling it too early
 	 * is dangerous.
--- zfcpdump-kernel-4.4.orig/arch/mips/kernel/traps.c
+++ zfcpdump-kernel-4.4/arch/mips/kernel/traps.c
@@ -144,7 +144,7 @@ static void show_backtrace(struct task_s
 	if (!task)
 		task = current;
 
-	if (raw_show_trace || !__kernel_text_address(pc)) {
+	if (raw_show_trace || user_mode(regs) || !__kernel_text_address(pc)) {
 		show_raw_backtrace(sp);
 		return;
 	}
@@ -690,15 +690,15 @@ static int simulate_sync(struct pt_regs
 asmlinkage void do_ov(struct pt_regs *regs)
 {
 	enum ctx_state prev_state;
-	siginfo_t info;
+	siginfo_t info = {
+		.si_signo = SIGFPE,
+		.si_code = FPE_INTOVF,
+		.si_addr = (void __user *)regs->cp0_epc,
+	};
 
 	prev_state = exception_enter();
 	die_if_kernel("Integer overflow", regs);
 
-	info.si_code = FPE_INTOVF;
-	info.si_signo = SIGFPE;
-	info.si_errno = 0;
-	info.si_addr = (void __user *) regs->cp0_epc;
 	force_sig_info(SIGFPE, &info, current);
 	exception_exit(prev_state);
 }
@@ -874,7 +874,7 @@ out:
 void do_trap_or_bp(struct pt_regs *regs, unsigned int code,
 	const char *str)
 {
-	siginfo_t info;
+	siginfo_t info = { 0 };
 	char b[40];
 
 #ifdef CONFIG_KGDB_LOW_LEVEL_TRAP
@@ -903,7 +903,6 @@ void do_trap_or_bp(struct pt_regs *regs,
 		else
 			info.si_code = FPE_INTOVF;
 		info.si_signo = SIGFPE;
-		info.si_errno = 0;
 		info.si_addr = (void __user *) regs->cp0_epc;
 		force_sig_info(SIGFPE, &info, current);
 		break;
@@ -1242,7 +1241,7 @@ static int enable_restore_fp_context(int
 		err = init_fpu();
 		if (msa && !err) {
 			enable_msa();
-			_init_msa_upper();
+			init_msa_upper();
 			set_thread_flag(TIF_USEDMSA);
 			set_thread_flag(TIF_MSA_CTX_LIVE);
 		}
@@ -1305,7 +1304,7 @@ static int enable_restore_fp_context(int
 	 */
 	prior_msa = test_and_set_thread_flag(TIF_MSA_CTX_LIVE);
 	if (!prior_msa && was_fpu_owner) {
-		_init_msa_upper();
+		init_msa_upper();
 
 		goto out;
 	}
@@ -1322,7 +1321,7 @@ static int enable_restore_fp_context(int
 		 * of each vector register such that it cannot see data left
 		 * behind by another task.
 		 */
-		_init_msa_upper();
+		init_msa_upper();
 	} else {
 		/* We need to restore the vector context. */
 		restore_msa(current);
--- zfcpdump-kernel-4.4.orig/arch/mips/kernel/unaligned.c
+++ zfcpdump-kernel-4.4/arch/mips/kernel/unaligned.c
@@ -885,7 +885,7 @@ static void emulate_load_store_insn(stru
 {
 	union mips_instruction insn;
 	unsigned long value;
-	unsigned int res;
+	unsigned int res, preempted;
 	unsigned long origpc;
 	unsigned long orig31;
 	void __user *fault_addr = NULL;
@@ -1226,27 +1226,36 @@ static void emulate_load_store_insn(stru
 			if (!access_ok(VERIFY_READ, addr, sizeof(*fpr)))
 				goto sigbus;
 
-			/*
-			 * Disable preemption to avoid a race between copying
-			 * state from userland, migrating to another CPU and
-			 * updating the hardware vector register below.
-			 */
-			preempt_disable();
-
-			res = __copy_from_user_inatomic(fpr, addr,
-							sizeof(*fpr));
-			if (res)
-				goto fault;
-
-			/*
-			 * Update the hardware register if it is in use by the
-			 * task in this quantum, in order to avoid having to
-			 * save & restore the whole vector context.
-			 */
-			if (test_thread_flag(TIF_USEDMSA))
-				write_msa_wr(wd, fpr, df);
-
-			preempt_enable();
+			do {
+				/*
+				 * If we have live MSA context keep track of
+				 * whether we get preempted in order to avoid
+				 * the register context we load being clobbered
+				 * by the live context as it's saved during
+				 * preemption. If we don't have live context
+				 * then it can't be saved to clobber the value
+				 * we load.
+				 */
+				preempted = test_thread_flag(TIF_USEDMSA);
+
+				res = __copy_from_user_inatomic(fpr, addr,
+								sizeof(*fpr));
+				if (res)
+					goto fault;
+
+				/*
+				 * Update the hardware register if it is in use
+				 * by the task in this quantum, in order to
+				 * avoid having to save & restore the whole
+				 * vector context.
+				 */
+				preempt_disable();
+				if (test_thread_flag(TIF_USEDMSA)) {
+					write_msa_wr(wd, fpr, df);
+					preempted = 0;
+				}
+				preempt_enable();
+			} while (preempted);
 			break;
 
 		case msa_st_op:
--- zfcpdump-kernel-4.4.orig/arch/mips/kernel/uprobes.c
+++ zfcpdump-kernel-4.4/arch/mips/kernel/uprobes.c
@@ -157,7 +157,6 @@ bool is_trap_insn(uprobe_opcode_t *insn)
 int arch_uprobe_pre_xol(struct arch_uprobe *aup, struct pt_regs *regs)
 {
 	struct uprobe_task *utask = current->utask;
-	union mips_instruction insn;
 
 	/*
 	 * Now find the EPC where to resume after the breakpoint has been
@@ -168,10 +167,10 @@ int arch_uprobe_pre_xol(struct arch_upro
 		unsigned long epc;
 
 		epc = regs->cp0_epc;
-		__compute_return_epc_for_insn(regs, insn);
+		__compute_return_epc_for_insn(regs,
+			(union mips_instruction) aup->insn[0]);
 		aup->resume_epc = regs->cp0_epc;
 	}
-
 	utask->autask.saved_trap_nr = current->thread.trap_nr;
 	current->thread.trap_nr = UPROBE_TRAP_NR;
 	regs->cp0_epc = current->utask->xol_vaddr;
@@ -257,7 +256,7 @@ unsigned long arch_uretprobe_hijack_retu
 	ra = regs->regs[31];
 
 	/* Replace the return address with the trampoline address */
-	regs->regs[31] = ra;
+	regs->regs[31] = trampoline_vaddr;
 
 	return ra;
 }
@@ -280,24 +279,6 @@ int __weak set_swbp(struct arch_uprobe *
 	return uprobe_write_opcode(mm, vaddr, UPROBE_SWBP_INSN);
 }
 
-/**
- * set_orig_insn - Restore the original instruction.
- * @mm: the probed process address space.
- * @auprobe: arch specific probepoint information.
- * @vaddr: the virtual address to insert the opcode.
- *
- * For mm @mm, restore the original opcode (opcode) at @vaddr.
- * Return 0 (success) or a negative errno.
- *
- * This overrides the weak version in kernel/events/uprobes.c.
- */
-int set_orig_insn(struct arch_uprobe *auprobe, struct mm_struct *mm,
-		 unsigned long vaddr)
-{
-	return uprobe_write_opcode(mm, vaddr,
-			*(uprobe_opcode_t *)&auprobe->orig_inst[0].word);
-}
-
 void __weak arch_uprobe_copy_ixol(struct page *page, unsigned long vaddr,
 				  void *src, unsigned long len)
 {
--- zfcpdump-kernel-4.4.orig/arch/mips/kernel/vdso.c
+++ zfcpdump-kernel-4.4/arch/mips/kernel/vdso.c
@@ -39,16 +39,16 @@ static struct vm_special_mapping vdso_vv
 static void __init init_vdso_image(struct mips_vdso_image *image)
 {
 	unsigned long num_pages, i;
+	unsigned long data_pfn;
 
 	BUG_ON(!PAGE_ALIGNED(image->data));
 	BUG_ON(!PAGE_ALIGNED(image->size));
 
 	num_pages = image->size / PAGE_SIZE;
 
-	for (i = 0; i < num_pages; i++) {
-		image->mapping.pages[i] =
-			virt_to_page(image->data + (i * PAGE_SIZE));
-	}
+	data_pfn = __phys_to_pfn(__pa_symbol(image->data));
+	for (i = 0; i < num_pages; i++)
+		image->mapping.pages[i] = pfn_to_page(data_pfn + i);
 }
 
 static int __init init_vdso(void)
--- zfcpdump-kernel-4.4.orig/arch/mips/kernel/vpe.c
+++ zfcpdump-kernel-4.4/arch/mips/kernel/vpe.c
@@ -205,11 +205,11 @@ static void layout_sections(struct modul
 			    || s->sh_entsize != ~0UL)
 				continue;
 			s->sh_entsize =
-				get_offset((unsigned long *)&mod->core_size, s);
+				get_offset((unsigned long *)&mod->core_layout.size, s);
 		}
 
 		if (m == 0)
-			mod->core_text_size = mod->core_size;
+			mod->core_layout.text_size = mod->core_layout.size;
 
 	}
 }
@@ -641,7 +641,7 @@ static int vpe_elfload(struct vpe *v)
 		layout_sections(&mod, hdr, sechdrs, secstrings);
 	}
 
-	v->load_addr = alloc_progmem(mod.core_size);
+	v->load_addr = alloc_progmem(mod.core_layout.size);
 	if (!v->load_addr)
 		return -ENOMEM;
 
--- zfcpdump-kernel-4.4.orig/arch/mips/kernel/watch.c
+++ zfcpdump-kernel-4.4/arch/mips/kernel/watch.c
@@ -15,10 +15,9 @@
  * Install the watch registers for the current thread.	A maximum of
  * four registers are installed although the machine may have more.
  */
-void mips_install_watch_registers(void)
+void mips_install_watch_registers(struct task_struct *t)
 {
-	struct mips3264_watch_reg_state *watches =
-		&current->thread.watch.mips3264;
+	struct mips3264_watch_reg_state *watches = &t->thread.watch.mips3264;
 	switch (current_cpu_data.watch_reg_use_cnt) {
 	default:
 		BUG();
--- zfcpdump-kernel-4.4.orig/arch/mips/kvm/emulate.c
+++ zfcpdump-kernel-4.4/arch/mips/kvm/emulate.c
@@ -302,12 +302,31 @@ static inline ktime_t kvm_mips_count_tim
  */
 static uint32_t kvm_mips_read_count_running(struct kvm_vcpu *vcpu, ktime_t now)
 {
-	ktime_t expires;
+	struct mips_coproc *cop0 = vcpu->arch.cop0;
+	ktime_t expires, threshold;
+	uint32_t count, compare;
 	int running;
 
-	/* Is the hrtimer pending? */
+	/* Calculate the biased and scaled guest CP0_Count */
+	count = vcpu->arch.count_bias + kvm_mips_ktime_to_count(vcpu, now);
+	compare = kvm_read_c0_guest_compare(cop0);
+
+	/*
+	 * Find whether CP0_Count has reached the closest timer interrupt. If
+	 * not, we shouldn't inject it.
+	 */
+	if ((int32_t)(count - compare) < 0)
+		return count;
+
+	/*
+	 * The CP0_Count we're going to return has already reached the closest
+	 * timer interrupt. Quickly check if it really is a new interrupt by
+	 * looking at whether the interval until the hrtimer expiry time is
+	 * less than 1/4 of the timer period.
+	 */
 	expires = hrtimer_get_expires(&vcpu->arch.comparecount_timer);
-	if (ktime_compare(now, expires) >= 0) {
+	threshold = ktime_add_ns(now, vcpu->arch.count_period / 4);
+	if (ktime_before(expires, threshold)) {
 		/*
 		 * Cancel it while we handle it so there's no chance of
 		 * interference with the timeout handler.
@@ -329,8 +348,7 @@ static uint32_t kvm_mips_read_count_runn
 		}
 	}
 
-	/* Return the biased and scaled guest CP0_Count */
-	return vcpu->arch.count_bias + kvm_mips_ktime_to_count(vcpu, now);
+	return count;
 }
 
 /**
@@ -420,32 +438,6 @@ static void kvm_mips_resume_hrtimer(stru
 }
 
 /**
- * kvm_mips_update_hrtimer() - Update next expiry time of hrtimer.
- * @vcpu:	Virtual CPU.
- *
- * Recalculates and updates the expiry time of the hrtimer. This can be used
- * after timer parameters have been altered which do not depend on the time that
- * the change occurs (in those cases kvm_mips_freeze_hrtimer() and
- * kvm_mips_resume_hrtimer() are used directly).
- *
- * It is guaranteed that no timer interrupts will be lost in the process.
- *
- * Assumes !kvm_mips_count_disabled(@vcpu) (guest CP0_Count timer is running).
- */
-static void kvm_mips_update_hrtimer(struct kvm_vcpu *vcpu)
-{
-	ktime_t now;
-	uint32_t count;
-
-	/*
-	 * freeze_hrtimer takes care of a timer interrupts <= count, and
-	 * resume_hrtimer the hrtimer takes care of a timer interrupts > count.
-	 */
-	now = kvm_mips_freeze_hrtimer(vcpu, &count);
-	kvm_mips_resume_hrtimer(vcpu, now, count);
-}
-
-/**
  * kvm_mips_write_count() - Modify the count and update timer.
  * @vcpu:	Virtual CPU.
  * @count:	Guest CP0_Count value to set.
@@ -540,23 +532,42 @@ int kvm_mips_set_count_hz(struct kvm_vcp
  * kvm_mips_write_compare() - Modify compare and update timer.
  * @vcpu:	Virtual CPU.
  * @compare:	New CP0_Compare value.
+ * @ack:	Whether to acknowledge timer interrupt.
  *
  * Update CP0_Compare to a new value and update the timeout.
+ * If @ack, atomically acknowledge any pending timer interrupt, otherwise ensure
+ * any pending timer interrupt is preserved.
  */
-void kvm_mips_write_compare(struct kvm_vcpu *vcpu, uint32_t compare)
+void kvm_mips_write_compare(struct kvm_vcpu *vcpu, uint32_t compare, bool ack)
 {
 	struct mips_coproc *cop0 = vcpu->arch.cop0;
+	int dc;
+	u32 old_compare = kvm_read_c0_guest_compare(cop0);
+	ktime_t now;
+	uint32_t count;
 
 	/* if unchanged, must just be an ack */
-	if (kvm_read_c0_guest_compare(cop0) == compare)
+	if (old_compare == compare) {
+		if (!ack)
+			return;
+		kvm_mips_callbacks->dequeue_timer_int(vcpu);
+		kvm_write_c0_guest_compare(cop0, compare);
 		return;
+	}
+
+	/* freeze_hrtimer() takes care of timer interrupts <= count */
+	dc = kvm_mips_count_disabled(vcpu);
+	if (!dc)
+		now = kvm_mips_freeze_hrtimer(vcpu, &count);
+
+	if (ack)
+		kvm_mips_callbacks->dequeue_timer_int(vcpu);
 
-	/* Update compare */
 	kvm_write_c0_guest_compare(cop0, compare);
 
-	/* Update timeout if count enabled */
-	if (!kvm_mips_count_disabled(vcpu))
-		kvm_mips_update_hrtimer(vcpu);
+	/* resume_hrtimer() takes care of timer interrupts > count */
+	if (!dc)
+		kvm_mips_resume_hrtimer(vcpu, now, count);
 }
 
 /**
@@ -1095,9 +1106,9 @@ enum emulation_result kvm_mips_emulate_C
 
 				/* If we are writing to COMPARE */
 				/* Clear pending timer interrupt, if any */
-				kvm_mips_callbacks->dequeue_timer_int(vcpu);
 				kvm_mips_write_compare(vcpu,
-						       vcpu->arch.gprs[rt]);
+						       vcpu->arch.gprs[rt],
+						       true);
 			} else if ((rd == MIPS_CP0_STATUS) && (sel == 0)) {
 				unsigned int old_val, val, change;
 
@@ -1618,8 +1629,14 @@ enum emulation_result kvm_mips_emulate_c
 
 	preempt_disable();
 	if (KVM_GUEST_KSEGX(va) == KVM_GUEST_KSEG0) {
-		if (kvm_mips_host_tlb_lookup(vcpu, va) < 0)
-			kvm_mips_handle_kseg0_tlb_fault(va, vcpu);
+		if (kvm_mips_host_tlb_lookup(vcpu, va) < 0 &&
+		    kvm_mips_handle_kseg0_tlb_fault(va, vcpu)) {
+			kvm_err("%s: handling mapped kseg0 tlb fault for %lx, vcpu: %p, ASID: %#lx\n",
+				__func__, va, vcpu, read_c0_entryhi());
+			er = EMULATE_FAIL;
+			preempt_enable();
+			goto done;
+		}
 	} else if ((KVM_GUEST_KSEGX(va) < KVM_GUEST_KSEG0) ||
 		   KVM_GUEST_KSEGX(va) == KVM_GUEST_KSEG23) {
 		int index;
@@ -1654,14 +1671,19 @@ enum emulation_result kvm_mips_emulate_c
 								run, vcpu);
 				preempt_enable();
 				goto dont_update_pc;
-			} else {
-				/*
-				 * We fault an entry from the guest tlb to the
-				 * shadow host TLB
-				 */
-				kvm_mips_handle_mapped_seg_tlb_fault(vcpu, tlb,
-								     NULL,
-								     NULL);
+			}
+			/*
+			 * We fault an entry from the guest tlb to the
+			 * shadow host TLB
+			 */
+			if (kvm_mips_handle_mapped_seg_tlb_fault(vcpu, tlb,
+								 NULL, NULL)) {
+				kvm_err("%s: handling mapped seg tlb fault for %lx, index: %u, vcpu: %p, ASID: %#lx\n",
+					__func__, va, index, vcpu,
+					read_c0_entryhi());
+				er = EMULATE_FAIL;
+				preempt_enable();
+				goto done;
 			}
 		}
 	} else {
@@ -2622,8 +2644,13 @@ enum emulation_result kvm_mips_handle_tl
 			 * OK we have a Guest TLB entry, now inject it into the
 			 * shadow host TLB
 			 */
-			kvm_mips_handle_mapped_seg_tlb_fault(vcpu, tlb, NULL,
-							     NULL);
+			if (kvm_mips_handle_mapped_seg_tlb_fault(vcpu, tlb,
+								 NULL, NULL)) {
+				kvm_err("%s: handling mapped seg tlb fault for %lx, index: %u, vcpu: %p, ASID: %#lx\n",
+					__func__, va, index, vcpu,
+					read_c0_entryhi());
+				er = EMULATE_FAIL;
+			}
 		}
 	}
 
--- zfcpdump-kernel-4.4.orig/arch/mips/kvm/interrupt.h
+++ zfcpdump-kernel-4.4/arch/mips/kvm/interrupt.h
@@ -28,6 +28,7 @@
 #define MIPS_EXC_MAX                12
 /* XXXSL More to follow */
 
+extern char __kvm_mips_vcpu_run_end[];
 extern char mips32_exception[], mips32_exceptionEnd[];
 extern char mips32_GuestException[], mips32_GuestExceptionEnd[];
 
--- zfcpdump-kernel-4.4.orig/arch/mips/kvm/locore.S
+++ zfcpdump-kernel-4.4/arch/mips/kvm/locore.S
@@ -227,6 +227,7 @@ FEXPORT(__kvm_mips_load_k0k1)
 
 	/* Jump to guest */
 	eret
+EXPORT(__kvm_mips_vcpu_run_end)
 
 VECTOR(MIPSX(exception), unknown)
 /* Find out what mode we came from and jump to the proper handler. */
--- zfcpdump-kernel-4.4.orig/arch/mips/kvm/mips.c
+++ zfcpdump-kernel-4.4/arch/mips/kvm/mips.c
@@ -314,6 +314,15 @@ struct kvm_vcpu *kvm_arch_vcpu_create(st
 	memcpy(gebase + offset, mips32_GuestException,
 	       mips32_GuestExceptionEnd - mips32_GuestException);
 
+#ifdef MODULE
+	offset += mips32_GuestExceptionEnd - mips32_GuestException;
+	memcpy(gebase + offset, (char *)__kvm_mips_vcpu_run,
+	       __kvm_mips_vcpu_run_end - (char *)__kvm_mips_vcpu_run);
+	vcpu->arch.vcpu_run = gebase + offset;
+#else
+	vcpu->arch.vcpu_run = __kvm_mips_vcpu_run;
+#endif
+
 	/* Invalidate the icache for these ranges */
 	local_flush_icache_range((unsigned long)gebase,
 				(unsigned long)gebase + ALIGN(size, PAGE_SIZE));
@@ -403,7 +412,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_v
 	/* Disable hardware page table walking while in guest */
 	htw_stop();
 
-	r = __kvm_mips_vcpu_run(run, vcpu);
+	r = vcpu->arch.vcpu_run(run, vcpu);
 
 	/* Re-enable HTW before enabling interrupts */
 	htw_start();
@@ -702,7 +711,7 @@ static int kvm_mips_get_reg(struct kvm_v
 	} else if ((reg->id & KVM_REG_SIZE_MASK) == KVM_REG_SIZE_U128) {
 		void __user *uaddr = (void __user *)(long)reg->addr;
 
-		return copy_to_user(uaddr, vs, 16);
+		return copy_to_user(uaddr, vs, 16) ? -EFAULT : 0;
 	} else {
 		return -EINVAL;
 	}
@@ -732,7 +741,7 @@ static int kvm_mips_set_reg(struct kvm_v
 	} else if ((reg->id & KVM_REG_SIZE_MASK) == KVM_REG_SIZE_U128) {
 		void __user *uaddr = (void __user *)(long)reg->addr;
 
-		return copy_from_user(vs, uaddr, 16);
+		return copy_from_user(vs, uaddr, 16) ? -EFAULT : 0;
 	} else {
 		return -EINVAL;
 	}
--- zfcpdump-kernel-4.4.orig/arch/mips/kvm/tlb.c
+++ zfcpdump-kernel-4.4/arch/mips/kvm/tlb.c
@@ -152,7 +152,7 @@ static int kvm_mips_map_page(struct kvm
 	srcu_idx = srcu_read_lock(&kvm->srcu);
 	pfn = kvm_mips_gfn_to_pfn(kvm, gfn);
 
-	if (kvm_mips_is_error_pfn(pfn)) {
+	if (is_error_noslot_pfn(pfn)) {
 		kvm_err("Couldn't get pfn for gfn %#" PRIx64 "!\n", gfn);
 		err = -EFAULT;
 		goto out;
@@ -276,7 +276,7 @@ int kvm_mips_handle_kseg0_tlb_fault(unsi
 	}
 
 	gfn = (KVM_GUEST_CPHYSADDR(badvaddr) >> PAGE_SHIFT);
-	if (gfn >= kvm->arch.guest_pmap_npages) {
+	if ((gfn | 1) >= kvm->arch.guest_pmap_npages) {
 		kvm_err("%s: Invalid gfn: %#llx, BadVaddr: %#lx\n", __func__,
 			gfn, badvaddr);
 		kvm_mips_dump_host_tlbs();
@@ -361,25 +361,39 @@ int kvm_mips_handle_mapped_seg_tlb_fault
 	unsigned long entryhi = 0, entrylo0 = 0, entrylo1 = 0;
 	struct kvm *kvm = vcpu->kvm;
 	pfn_t pfn0, pfn1;
+	gfn_t gfn0, gfn1;
+	long tlb_lo[2];
 
-	if ((tlb->tlb_hi & VPN2_MASK) == 0) {
-		pfn0 = 0;
-		pfn1 = 0;
-	} else {
-		if (kvm_mips_map_page(kvm, mips3_tlbpfn_to_paddr(tlb->tlb_lo0)
-					   >> PAGE_SHIFT) < 0)
-			return -1;
-
-		if (kvm_mips_map_page(kvm, mips3_tlbpfn_to_paddr(tlb->tlb_lo1)
-					   >> PAGE_SHIFT) < 0)
-			return -1;
-
-		pfn0 = kvm->arch.guest_pmap[mips3_tlbpfn_to_paddr(tlb->tlb_lo0)
-					    >> PAGE_SHIFT];
-		pfn1 = kvm->arch.guest_pmap[mips3_tlbpfn_to_paddr(tlb->tlb_lo1)
-					    >> PAGE_SHIFT];
+	tlb_lo[0] = tlb->tlb_lo0;
+	tlb_lo[1] = tlb->tlb_lo1;
+
+	/*
+	 * The commpage address must not be mapped to anything else if the guest
+	 * TLB contains entries nearby, or commpage accesses will break.
+	 */
+	if (!((tlb->tlb_hi ^ KVM_GUEST_COMMPAGE_ADDR) &
+			VPN2_MASK & (PAGE_MASK << 1)))
+		tlb_lo[(KVM_GUEST_COMMPAGE_ADDR >> PAGE_SHIFT) & 1] = 0;
+
+	gfn0 = mips3_tlbpfn_to_paddr(tlb_lo[0]) >> PAGE_SHIFT;
+	gfn1 = mips3_tlbpfn_to_paddr(tlb_lo[1]) >> PAGE_SHIFT;
+	if (gfn0 >= kvm->arch.guest_pmap_npages ||
+	    gfn1 >= kvm->arch.guest_pmap_npages) {
+		kvm_err("%s: Invalid gfn: [%#llx, %#llx], EHi: %#lx\n",
+			__func__, gfn0, gfn1, tlb->tlb_hi);
+		kvm_mips_dump_guest_tlbs(vcpu);
+		return -1;
 	}
 
+	if (kvm_mips_map_page(kvm, gfn0) < 0)
+		return -1;
+
+	if (kvm_mips_map_page(kvm, gfn1) < 0)
+		return -1;
+
+	pfn0 = kvm->arch.guest_pmap[gfn0];
+	pfn1 = kvm->arch.guest_pmap[gfn1];
+
 	if (hpa0)
 		*hpa0 = pfn0 << PAGE_SHIFT;
 
@@ -391,9 +405,9 @@ int kvm_mips_handle_mapped_seg_tlb_fault
 					       kvm_mips_get_kernel_asid(vcpu) :
 					       kvm_mips_get_user_asid(vcpu));
 	entrylo0 = mips3_paddr_to_tlbpfn(pfn0 << PAGE_SHIFT) | (0x3 << 3) |
-		   (tlb->tlb_lo0 & MIPS3_PG_D) | (tlb->tlb_lo0 & MIPS3_PG_V);
+		   (tlb_lo[0] & MIPS3_PG_D) | (tlb_lo[0] & MIPS3_PG_V);
 	entrylo1 = mips3_paddr_to_tlbpfn(pfn1 << PAGE_SHIFT) | (0x3 << 3) |
-		   (tlb->tlb_lo1 & MIPS3_PG_D) | (tlb->tlb_lo1 & MIPS3_PG_V);
+		   (tlb_lo[1] & MIPS3_PG_D) | (tlb_lo[1] & MIPS3_PG_V);
 
 	kvm_debug("@ %#lx tlb_lo0: 0x%08lx tlb_lo1: 0x%08lx\n", vcpu->arch.pc,
 		  tlb->tlb_lo0, tlb->tlb_lo1);
@@ -794,10 +808,16 @@ uint32_t kvm_get_inst(uint32_t *opc, str
 				local_irq_restore(flags);
 				return KVM_INVALID_INST;
 			}
-			kvm_mips_handle_mapped_seg_tlb_fault(vcpu,
-							     &vcpu->arch.
-							     guest_tlb[index],
-							     NULL, NULL);
+			if (kvm_mips_handle_mapped_seg_tlb_fault(vcpu,
+						&vcpu->arch.guest_tlb[index],
+						NULL, NULL)) {
+				kvm_err("%s: handling mapped seg tlb fault failed for %p, index: %u, vcpu: %p, ASID: %#lx\n",
+					__func__, opc, index, vcpu,
+					read_c0_entryhi());
+				kvm_mips_dump_guest_tlbs(vcpu);
+				local_irq_restore(flags);
+				return KVM_INVALID_INST;
+			}
 			inst = *(opc);
 		}
 		local_irq_restore(flags);
--- zfcpdump-kernel-4.4.orig/arch/mips/kvm/trap_emul.c
+++ zfcpdump-kernel-4.4/arch/mips/kvm/trap_emul.c
@@ -547,7 +547,7 @@ static int kvm_trap_emul_set_one_reg(str
 		kvm_mips_write_count(vcpu, v);
 		break;
 	case KVM_REG_MIPS_CP0_COMPARE:
-		kvm_mips_write_compare(vcpu, v);
+		kvm_mips_write_compare(vcpu, v, false);
 		break;
 	case KVM_REG_MIPS_CP0_CAUSE:
 		/*
--- zfcpdump-kernel-4.4.orig/arch/mips/lib/ashldi3.c
+++ zfcpdump-kernel-4.4/arch/mips/lib/ashldi3.c
@@ -2,7 +2,7 @@
 
 #include "libgcc.h"
 
-long long __ashldi3(long long u, word_type b)
+long long notrace __ashldi3(long long u, word_type b)
 {
 	DWunion uu, w;
 	word_type bm;
--- zfcpdump-kernel-4.4.orig/arch/mips/lib/ashrdi3.c
+++ zfcpdump-kernel-4.4/arch/mips/lib/ashrdi3.c
@@ -2,7 +2,7 @@
 
 #include "libgcc.h"
 
-long long __ashrdi3(long long u, word_type b)
+long long notrace __ashrdi3(long long u, word_type b)
 {
 	DWunion uu, w;
 	word_type bm;
--- zfcpdump-kernel-4.4.orig/arch/mips/lib/bswapdi.c
+++ zfcpdump-kernel-4.4/arch/mips/lib/bswapdi.c
@@ -1,6 +1,6 @@
 #include <linux/module.h>
 
-unsigned long long __bswapdi2(unsigned long long u)
+unsigned long long notrace __bswapdi2(unsigned long long u)
 {
 	return (((u) & 0xff00000000000000ull) >> 56) |
 	       (((u) & 0x00ff000000000000ull) >> 40) |
--- zfcpdump-kernel-4.4.orig/arch/mips/lib/bswapsi.c
+++ zfcpdump-kernel-4.4/arch/mips/lib/bswapsi.c
@@ -1,6 +1,6 @@
 #include <linux/module.h>
 
-unsigned int __bswapsi2(unsigned int u)
+unsigned int notrace __bswapsi2(unsigned int u)
 {
 	return (((u) & 0xff000000) >> 24) |
 	       (((u) & 0x00ff0000) >>  8) |
--- zfcpdump-kernel-4.4.orig/arch/mips/lib/cmpdi2.c
+++ zfcpdump-kernel-4.4/arch/mips/lib/cmpdi2.c
@@ -2,7 +2,7 @@
 
 #include "libgcc.h"
 
-word_type __cmpdi2(long long a, long long b)
+word_type notrace __cmpdi2(long long a, long long b)
 {
 	const DWunion au = {
 		.ll = a
--- zfcpdump-kernel-4.4.orig/arch/mips/lib/lshrdi3.c
+++ zfcpdump-kernel-4.4/arch/mips/lib/lshrdi3.c
@@ -2,7 +2,7 @@
 
 #include "libgcc.h"
 
-long long __lshrdi3(long long u, word_type b)
+long long notrace __lshrdi3(long long u, word_type b)
 {
 	DWunion uu, w;
 	word_type bm;
--- zfcpdump-kernel-4.4.orig/arch/mips/lib/ucmpdi2.c
+++ zfcpdump-kernel-4.4/arch/mips/lib/ucmpdi2.c
@@ -2,7 +2,7 @@
 
 #include "libgcc.h"
 
-word_type __ucmpdi2(unsigned long long a, unsigned long long b)
+word_type notrace __ucmpdi2(unsigned long long a, unsigned long long b)
 {
 	const DWunion au = {.ll = a};
 	const DWunion bu = {.ll = b};
--- zfcpdump-kernel-4.4.orig/arch/mips/loongson64/loongson-3/hpet.c
+++ zfcpdump-kernel-4.4/arch/mips/loongson64/loongson-3/hpet.c
@@ -13,6 +13,9 @@
 #define SMBUS_PCI_REG64		0x64
 #define SMBUS_PCI_REGB4		0xb4
 
+#define HPET_MIN_CYCLES		16
+#define HPET_MIN_PROG_DELTA	(HPET_MIN_CYCLES * 12)
+
 static DEFINE_SPINLOCK(hpet_lock);
 DEFINE_PER_CPU(struct clock_event_device, hpet_clockevent_device);
 
@@ -154,15 +157,16 @@ static int hpet_tick_resume(struct clock
 static int hpet_next_event(unsigned long delta,
 		struct clock_event_device *evt)
 {
-	unsigned int cnt;
-	int res;
+	u32 cnt;
+	s32 res;
 
 	cnt = hpet_read(HPET_COUNTER);
-	cnt += delta;
+	cnt += (u32) delta;
 	hpet_write(HPET_T0_CMP, cnt);
 
-	res = ((int)(hpet_read(HPET_COUNTER) - cnt) > 0) ? -ETIME : 0;
-	return res;
+	res = (s32)(cnt - hpet_read(HPET_COUNTER));
+
+	return res < HPET_MIN_CYCLES ? -ETIME : 0;
 }
 
 static irqreturn_t hpet_irq_handler(int irq, void *data)
@@ -226,7 +230,7 @@ void __init setup_hpet_timer(void)
 
 	cd = &per_cpu(hpet_clockevent_device, cpu);
 	cd->name = "hpet";
-	cd->rating = 320;
+	cd->rating = 100;
 	cd->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT;
 	cd->set_state_shutdown = hpet_set_state_shutdown;
 	cd->set_state_periodic = hpet_set_state_periodic;
@@ -237,7 +241,7 @@ void __init setup_hpet_timer(void)
 	cd->cpumask = cpumask_of(cpu);
 	clockevent_set_clock(cd, HPET_FREQ);
 	cd->max_delta_ns = clockevent_delta2ns(0x7fffffff, cd);
-	cd->min_delta_ns = 5000;
+	cd->min_delta_ns = clockevent_delta2ns(HPET_MIN_PROG_DELTA, cd);
 
 	clockevents_register_device(cd);
 	setup_irq(HPET_T0_IRQ, &hpet_irq);
--- zfcpdump-kernel-4.4.orig/arch/mips/loongson64/loongson-3/numa.c
+++ zfcpdump-kernel-4.4/arch/mips/loongson64/loongson-3/numa.c
@@ -213,10 +213,10 @@ static void __init node_mem_init(unsigne
 		BOOTMEM_DEFAULT);
 
 	if (node == 0 && node_end_pfn(0) >= (0xffffffff >> PAGE_SHIFT)) {
-		/* Reserve 0xff800000~0xffffffff for RS780E integrated GPU */
+		/* Reserve 0xfe000000~0xffffffff for RS780E integrated GPU */
 		reserve_bootmem_node(NODE_DATA(node),
-				(node_addrspace_offset | 0xff800000),
-				8 << 20, BOOTMEM_DEFAULT);
+				(node_addrspace_offset | 0xfe000000),
+				32 << 20, BOOTMEM_DEFAULT);
 	}
 
 	sparse_memory_present_with_active_regions(node);
--- zfcpdump-kernel-4.4.orig/arch/mips/loongson64/loongson-3/smp.c
+++ zfcpdump-kernel-4.4/arch/mips/loongson64/loongson-3/smp.c
@@ -30,13 +30,13 @@
 #include "smp.h"
 
 DEFINE_PER_CPU(int, cpu_state);
-DEFINE_PER_CPU(uint32_t, core0_c0count);
 
 static void *ipi_set0_regs[16];
 static void *ipi_clear0_regs[16];
 static void *ipi_status0_regs[16];
 static void *ipi_en0_regs[16];
 static void *ipi_mailbox_buf[16];
+static uint32_t core0_c0count[NR_CPUS];
 
 /* read a 32bit value from ipi register */
 #define loongson3_ipi_read32(addr) readl(addr)
@@ -275,12 +275,14 @@ void loongson3_ipi_interrupt(struct pt_r
 	if (action & SMP_ASK_C0COUNT) {
 		BUG_ON(cpu != 0);
 		c0count = read_c0_count();
-		for (i = 1; i < num_possible_cpus(); i++)
-			per_cpu(core0_c0count, i) = c0count;
+		c0count = c0count ? c0count : 1;
+		for (i = 1; i < nr_cpu_ids; i++)
+			core0_c0count[i] = c0count;
+		__wbflush(); /* Let others see the result ASAP */
 	}
 }
 
-#define MAX_LOOPS 1111
+#define MAX_LOOPS 800
 /*
  * SMP init and finish on secondary CPUs
  */
@@ -305,16 +307,20 @@ static void loongson3_init_secondary(voi
 		cpu_logical_map(cpu) / loongson_sysconf.cores_per_package;
 
 	i = 0;
-	__this_cpu_write(core0_c0count, 0);
+	core0_c0count[cpu] = 0;
 	loongson3_send_ipi_single(0, SMP_ASK_C0COUNT);
-	while (!__this_cpu_read(core0_c0count)) {
+	while (!core0_c0count[cpu]) {
 		i++;
 		cpu_relax();
 	}
 
 	if (i > MAX_LOOPS)
 		i = MAX_LOOPS;
-	initcount = __this_cpu_read(core0_c0count) + i;
+	if (cpu_data[cpu].package)
+		initcount = core0_c0count[cpu] + i;
+	else /* Local access is faster for loops */
+		initcount = core0_c0count[cpu] + i/2;
+
 	write_c0_count(initcount);
 }
 
--- zfcpdump-kernel-4.4.orig/arch/mips/math-emu/cp1emu.c
+++ zfcpdump-kernel-4.4/arch/mips/math-emu/cp1emu.c
@@ -445,9 +445,11 @@ static int isBranchInstr(struct pt_regs
 	case spec_op:
 		switch (insn.r_format.func) {
 		case jalr_op:
-			regs->regs[insn.r_format.rd] =
-				regs->cp0_epc + dec_insn.pc_inc +
-				dec_insn.next_pc_inc;
+			if (insn.r_format.rd != 0) {
+				regs->regs[insn.r_format.rd] =
+					regs->cp0_epc + dec_insn.pc_inc +
+					dec_insn.next_pc_inc;
+			}
 			/* Fall through */
 		case jr_op:
 			/* For R6, JR already emulated in jalr_op */
--- zfcpdump-kernel-4.4.orig/arch/mips/mm/cache.c
+++ zfcpdump-kernel-4.4/arch/mips/mm/cache.c
@@ -16,6 +16,7 @@
 #include <linux/mm.h>
 
 #include <asm/cacheflush.h>
+#include <asm/highmem.h>
 #include <asm/processor.h>
 #include <asm/cpu.h>
 #include <asm/cpu-features.h>
@@ -83,8 +84,6 @@ void __flush_dcache_page(struct page *pa
 	struct address_space *mapping = page_mapping(page);
 	unsigned long addr;
 
-	if (PageHighMem(page))
-		return;
 	if (mapping && !mapping_mapped(mapping)) {
 		SetPageDcacheDirty(page);
 		return;
@@ -95,8 +94,15 @@ void __flush_dcache_page(struct page *pa
 	 * case is for exec env/arg pages and those are %99 certainly going to
 	 * get faulted into the tlb (and thus flushed) anyways.
 	 */
-	addr = (unsigned long) page_address(page);
+	if (PageHighMem(page))
+		addr = (unsigned long)kmap_atomic(page);
+	else
+		addr = (unsigned long)page_address(page);
+
 	flush_data_cache_page(addr);
+
+	if (PageHighMem(page))
+		__kunmap_atomic((void *)addr);
 }
 
 EXPORT_SYMBOL(__flush_dcache_page);
@@ -119,33 +125,28 @@ void __flush_anon_page(struct page *page
 
 EXPORT_SYMBOL(__flush_anon_page);
 
-void __flush_icache_page(struct vm_area_struct *vma, struct page *page)
-{
-	unsigned long addr;
-
-	if (PageHighMem(page))
-		return;
-
-	addr = (unsigned long) page_address(page);
-	flush_data_cache_page(addr);
-}
-EXPORT_SYMBOL_GPL(__flush_icache_page);
-
-void __update_cache(struct vm_area_struct *vma, unsigned long address,
-	pte_t pte)
+void __update_cache(unsigned long address, pte_t pte)
 {
 	struct page *page;
 	unsigned long pfn, addr;
-	int exec = (vma->vm_flags & VM_EXEC) && !cpu_has_ic_fills_f_dc;
+	int exec = !pte_no_exec(pte) && !cpu_has_ic_fills_f_dc;
 
 	pfn = pte_pfn(pte);
 	if (unlikely(!pfn_valid(pfn)))
 		return;
 	page = pfn_to_page(pfn);
-	if (page_mapping(page) && Page_dcache_dirty(page)) {
-		addr = (unsigned long) page_address(page);
+	if (Page_dcache_dirty(page)) {
+		if (PageHighMem(page))
+			addr = (unsigned long)kmap_atomic(page);
+		else
+			addr = (unsigned long)page_address(page);
+
 		if (exec || pages_do_alias(addr, address & PAGE_MASK))
 			flush_data_cache_page(addr);
+
+		if (PageHighMem(page))
+			__kunmap_atomic((void *)addr);
+
 		ClearPageDcacheDirty(page);
 	}
 }
--- zfcpdump-kernel-4.4.orig/arch/mips/mm/sc-mips.c
+++ zfcpdump-kernel-4.4/arch/mips/mm/sc-mips.c
@@ -164,11 +164,13 @@ static int __init mips_sc_probe_cm3(void
 
 	sets = cfg & CM_GCR_L2_CONFIG_SET_SIZE_MSK;
 	sets >>= CM_GCR_L2_CONFIG_SET_SIZE_SHF;
-	c->scache.sets = 64 << sets;
+	if (sets)
+		c->scache.sets = 64 << sets;
 
 	line_sz = cfg & CM_GCR_L2_CONFIG_LINE_SIZE_MSK;
 	line_sz >>= CM_GCR_L2_CONFIG_LINE_SIZE_SHF;
-	c->scache.linesz = 2 << line_sz;
+	if (line_sz)
+		c->scache.linesz = 2 << line_sz;
 
 	assoc = cfg & CM_GCR_L2_CONFIG_ASSOC_MSK;
 	assoc >>= CM_GCR_L2_CONFIG_ASSOC_SHF;
@@ -176,9 +178,12 @@ static int __init mips_sc_probe_cm3(void
 	c->scache.waysize = c->scache.sets * c->scache.linesz;
 	c->scache.waybit = __ffs(c->scache.waysize);
 
-	c->scache.flags &= ~MIPS_CACHE_NOT_PRESENT;
+	if (c->scache.linesz) {
+		c->scache.flags &= ~MIPS_CACHE_NOT_PRESENT;
+		return 1;
+	}
 
-	return 1;
+	return 0;
 }
 
 void __weak platform_early_l2_init(void)
--- zfcpdump-kernel-4.4.orig/arch/mips/mm/tlbex.c
+++ zfcpdump-kernel-4.4/arch/mips/mm/tlbex.c
@@ -242,7 +242,7 @@ static void output_pgtable_bits_defines(
 	pr_define("_PAGE_HUGE_SHIFT %d\n", _PAGE_HUGE_SHIFT);
 	pr_define("_PAGE_SPLITTING_SHIFT %d\n", _PAGE_SPLITTING_SHIFT);
 #endif
-#ifdef CONFIG_CPU_MIPSR2
+#if defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_CPU_MIPSR6)
 	if (cpu_has_rixi) {
 #ifdef _PAGE_NO_EXEC_SHIFT
 		pr_define("_PAGE_NO_EXEC_SHIFT %d\n", _PAGE_NO_EXEC_SHIFT);
--- zfcpdump-kernel-4.4.orig/arch/mips/mm/uasm-mips.c
+++ zfcpdump-kernel-4.4/arch/mips/mm/uasm-mips.c
@@ -65,7 +65,7 @@ static struct insn insn_table[] = {
 #ifndef CONFIG_CPU_MIPSR6
 	{ insn_cache,  M(cache_op, 0, 0, 0, 0, 0),  RS | RT | SIMM },
 #else
-	{ insn_cache,  M6(cache_op, 0, 0, 0, cache6_op),  RS | RT | SIMM9 },
+	{ insn_cache,  M6(spec3_op, 0, 0, 0, cache6_op),  RS | RT | SIMM9 },
 #endif
 	{ insn_daddiu, M(daddiu_op, 0, 0, 0, 0, 0), RS | RT | SIMM },
 	{ insn_daddu, M(spec_op, 0, 0, 0, 0, daddu_op), RS | RT | RD },
--- zfcpdump-kernel-4.4.orig/arch/mips/mti-malta/malta-setup.c
+++ zfcpdump-kernel-4.4/arch/mips/mti-malta/malta-setup.c
@@ -39,6 +39,9 @@
 #include <linux/console.h>
 #endif
 
+#define ROCIT_CONFIG_GEN0		0x1f403000
+#define  ROCIT_CONFIG_GEN0_PCI_IOCU	BIT(7)
+
 extern void malta_be_init(void);
 extern int malta_be_handler(struct pt_regs *regs, int is_fixup);
 
@@ -107,6 +110,8 @@ static void __init fd_activate(void)
 static int __init plat_enable_iocoherency(void)
 {
 	int supported = 0;
+	u32 cfg;
+
 	if (mips_revision_sconid == MIPS_REVISION_SCON_BONITO) {
 		if (BONITO_PCICACHECTRL & BONITO_PCICACHECTRL_CPUCOH_PRES) {
 			BONITO_PCICACHECTRL |= BONITO_PCICACHECTRL_CPUCOH_EN;
@@ -129,7 +134,8 @@ static int __init plat_enable_iocoherenc
 	} else if (mips_cm_numiocu() != 0) {
 		/* Nothing special needs to be done to enable coherency */
 		pr_info("CMP IOCU detected\n");
-		if ((*(unsigned int *)0xbf403000 & 0x81) != 0x81) {
+		cfg = __raw_readl((u32 *)CKSEG1ADDR(ROCIT_CONFIG_GEN0));
+		if (!(cfg & ROCIT_CONFIG_GEN0_PCI_IOCU)) {
 			pr_crit("IOCU OPERATION DISABLED BY SWITCH - DEFAULTING TO SW IO COHERENCY\n");
 			return 0;
 		}
--- zfcpdump-kernel-4.4.orig/arch/mips/vdso/Makefile
+++ zfcpdump-kernel-4.4/arch/mips/vdso/Makefile
@@ -5,10 +5,12 @@ obj-vdso-y := elf.o gettimeofday.o sigre
 ccflags-vdso := \
 	$(filter -I%,$(KBUILD_CFLAGS)) \
 	$(filter -E%,$(KBUILD_CFLAGS)) \
+	$(filter -mmicromips,$(KBUILD_CFLAGS)) \
 	$(filter -march=%,$(KBUILD_CFLAGS))
 cflags-vdso := $(ccflags-vdso) \
 	$(filter -W%,$(filter-out -Wa$(comma)%,$(KBUILD_CFLAGS))) \
-	-O2 -g -fPIC -fno-common -fno-builtin -G 0 -DDISABLE_BRANCH_PROFILING \
+	-O2 -g -fPIC -fno-strict-aliasing -fno-common -fno-builtin -G 0 \
+	-DDISABLE_BRANCH_PROFILING \
 	$(call cc-option, -fno-stack-protector)
 aflags-vdso := $(ccflags-vdso) \
 	$(filter -I%,$(KBUILD_CFLAGS)) \
--- zfcpdump-kernel-4.4.orig/arch/mn10300/include/asm/uaccess.h
+++ zfcpdump-kernel-4.4/arch/mn10300/include/asm/uaccess.h
@@ -181,6 +181,7 @@ struct __large_struct { unsigned long bu
 		"2:\n"						\
 		"	.section	.fixup,\"ax\"\n"	\
 		"3:\n\t"					\
+		"	mov		0,%1\n"			\
 		"	mov		%3,%0\n"		\
 		"	jmp		2b\n"			\
 		"	.previous\n"				\
--- zfcpdump-kernel-4.4.orig/arch/mn10300/lib/usercopy.c
+++ zfcpdump-kernel-4.4/arch/mn10300/lib/usercopy.c
@@ -9,7 +9,7 @@
  * as published by the Free Software Foundation; either version
  * 2 of the Licence, or (at your option) any later version.
  */
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
 
 unsigned long
 __generic_copy_to_user(void *to, const void *from, unsigned long n)
@@ -24,6 +24,8 @@ __generic_copy_from_user(void *to, const
 {
 	if (access_ok(VERIFY_READ, from, n))
 		__copy_user_zeroing(to, from, n);
+	else
+		memset(to, 0, n);
 	return n;
 }
 
--- zfcpdump-kernel-4.4.orig/arch/nios2/include/asm/uaccess.h
+++ zfcpdump-kernel-4.4/arch/nios2/include/asm/uaccess.h
@@ -102,9 +102,12 @@ extern long __copy_to_user(void __user *
 static inline long copy_from_user(void *to, const void __user *from,
 				unsigned long n)
 {
-	if (!access_ok(VERIFY_READ, from, n))
-		return n;
-	return __copy_from_user(to, from, n);
+	unsigned long res = n;
+	if (access_ok(VERIFY_READ, from, n))
+		res = __copy_from_user(to, from, n);
+	if (unlikely(res))
+		memset(to + (n - res), 0, res);
+	return res;
 }
 
 static inline long copy_to_user(void __user *to, const void *from,
@@ -139,7 +142,7 @@ extern long strnlen_user(const char __us
 
 #define __get_user_unknown(val, size, ptr, err) do {			\
 	err = 0;							\
-	if (copy_from_user(&(val), ptr, size)) {			\
+	if (__copy_from_user(&(val), ptr, size)) {			\
 		err = -EFAULT;						\
 	}								\
 	} while (0)
@@ -166,7 +169,7 @@ do {									\
 	({								\
 	long __gu_err = -EFAULT;					\
 	const __typeof__(*(ptr)) __user *__gu_ptr = (ptr);		\
-	unsigned long __gu_val;						\
+	unsigned long __gu_val = 0;					\
 	__get_user_common(__gu_val, sizeof(*(ptr)), __gu_ptr, __gu_err);\
 	(x) = (__force __typeof__(x))__gu_val;				\
 	__gu_err;							\
--- zfcpdump-kernel-4.4.orig/arch/openrisc/include/asm/uaccess.h
+++ zfcpdump-kernel-4.4/arch/openrisc/include/asm/uaccess.h
@@ -273,28 +273,20 @@ __copy_tofrom_user(void *to, const void
 static inline unsigned long
 copy_from_user(void *to, const void *from, unsigned long n)
 {
-	unsigned long over;
+	unsigned long res = n;
 
-	if (access_ok(VERIFY_READ, from, n))
-		return __copy_tofrom_user(to, from, n);
-	if ((unsigned long)from < TASK_SIZE) {
-		over = (unsigned long)from + n - TASK_SIZE;
-		return __copy_tofrom_user(to, from, n - over) + over;
-	}
-	return n;
+	if (likely(access_ok(VERIFY_READ, from, n)))
+		res = __copy_tofrom_user(to, from, n);
+	if (unlikely(res))
+		memset(to + (n - res), 0, res);
+	return res;
 }
 
 static inline unsigned long
 copy_to_user(void *to, const void *from, unsigned long n)
 {
-	unsigned long over;
-
-	if (access_ok(VERIFY_WRITE, to, n))
-		return __copy_tofrom_user(to, from, n);
-	if ((unsigned long)to < TASK_SIZE) {
-		over = (unsigned long)to + n - TASK_SIZE;
-		return __copy_tofrom_user(to, from, n - over) + over;
-	}
+	if (likely(access_ok(VERIFY_WRITE, to, n)))
+		n = __copy_tofrom_user(to, from, n);
 	return n;
 }
 
@@ -303,13 +295,8 @@ extern unsigned long __clear_user(void *
 static inline __must_check unsigned long
 clear_user(void *addr, unsigned long size)
 {
-
-	if (access_ok(VERIFY_WRITE, addr, size))
-		return __clear_user(addr, size);
-	if ((unsigned long)addr < TASK_SIZE) {
-		unsigned long over = (unsigned long)addr + size - TASK_SIZE;
-		return __clear_user(addr, size - over) + over;
-	}
+	if (likely(access_ok(VERIFY_WRITE, addr, size)))
+		size = __clear_user(addr, size);
 	return size;
 }
 
--- zfcpdump-kernel-4.4.orig/arch/parisc/include/asm/hugetlb.h
+++ zfcpdump-kernel-4.4/arch/parisc/include/asm/hugetlb.h
@@ -54,24 +54,12 @@ static inline pte_t huge_pte_wrprotect(p
 	return pte_wrprotect(pte);
 }
 
-static inline void huge_ptep_set_wrprotect(struct mm_struct *mm,
-					   unsigned long addr, pte_t *ptep)
-{
-	pte_t old_pte = *ptep;
-	set_huge_pte_at(mm, addr, ptep, pte_wrprotect(old_pte));
-}
+void huge_ptep_set_wrprotect(struct mm_struct *mm,
+					   unsigned long addr, pte_t *ptep);
 
-static inline int huge_ptep_set_access_flags(struct vm_area_struct *vma,
+int huge_ptep_set_access_flags(struct vm_area_struct *vma,
 					     unsigned long addr, pte_t *ptep,
-					     pte_t pte, int dirty)
-{
-	int changed = !pte_same(*ptep, pte);
-	if (changed) {
-		set_huge_pte_at(vma->vm_mm, addr, ptep, pte);
-		flush_tlb_page(vma, addr);
-	}
-	return changed;
-}
+					     pte_t pte, int dirty);
 
 static inline pte_t huge_ptep_get(pte_t *ptep)
 {
--- zfcpdump-kernel-4.4.orig/arch/parisc/include/asm/uaccess.h
+++ zfcpdump-kernel-4.4/arch/parisc/include/asm/uaccess.h
@@ -10,6 +10,7 @@
 #include <asm-generic/uaccess-unaligned.h>
 
 #include <linux/bug.h>
+#include <linux/string.h>
 
 #define VERIFY_READ 0
 #define VERIFY_WRITE 1
@@ -76,6 +77,7 @@ struct exception_table_entry {
  */
 struct exception_data {
 	unsigned long fault_ip;
+	unsigned long fault_gp;
 	unsigned long fault_space;
 	unsigned long fault_addr;
 };
@@ -244,13 +246,14 @@ static inline unsigned long __must_check
                                           unsigned long n)
 {
         int sz = __compiletime_object_size(to);
-        int ret = -EFAULT;
+        unsigned long ret = n;
 
         if (likely(sz == -1 || !__builtin_constant_p(n) || sz >= n))
                 ret = __copy_from_user(to, from, n);
         else
                 copy_from_user_overflow();
-
+	if (unlikely(ret))
+		memset(to + (n - ret), 0, ret);
         return ret;
 }
 
--- zfcpdump-kernel-4.4.orig/arch/parisc/include/uapi/asm/errno.h
+++ zfcpdump-kernel-4.4/arch/parisc/include/uapi/asm/errno.h
@@ -97,10 +97,10 @@
 #define	ENOTCONN	235	/* Transport endpoint is not connected */
 #define	ESHUTDOWN	236	/* Cannot send after transport endpoint shutdown */
 #define	ETOOMANYREFS	237	/* Too many references: cannot splice */
-#define EREFUSED	ECONNREFUSED	/* for HP's NFS apparently */
 #define	ETIMEDOUT	238	/* Connection timed out */
 #define	ECONNREFUSED	239	/* Connection refused */
-#define EREMOTERELEASE	240	/* Remote peer released connection */
+#define	EREFUSED	ECONNREFUSED	/* for HP's NFS apparently */
+#define	EREMOTERELEASE	240	/* Remote peer released connection */
 #define	EHOSTDOWN	241	/* Host is down */
 #define	EHOSTUNREACH	242	/* No route to host */
 
--- zfcpdump-kernel-4.4.orig/arch/parisc/include/uapi/asm/siginfo.h
+++ zfcpdump-kernel-4.4/arch/parisc/include/uapi/asm/siginfo.h
@@ -1,6 +1,10 @@
 #ifndef _PARISC_SIGINFO_H
 #define _PARISC_SIGINFO_H
 
+#if defined(__LP64__)
+#define __ARCH_SI_PREAMBLE_SIZE   (4 * sizeof(int))
+#endif
+
 #include <asm-generic/siginfo.h>
 
 #undef NSIGTRAP
--- zfcpdump-kernel-4.4.orig/arch/parisc/kernel/asm-offsets.c
+++ zfcpdump-kernel-4.4/arch/parisc/kernel/asm-offsets.c
@@ -299,6 +299,7 @@ int main(void)
 #endif
 	BLANK();
 	DEFINE(EXCDATA_IP, offsetof(struct exception_data, fault_ip));
+	DEFINE(EXCDATA_GP, offsetof(struct exception_data, fault_gp));
 	DEFINE(EXCDATA_SPACE, offsetof(struct exception_data, fault_space));
 	DEFINE(EXCDATA_ADDR, offsetof(struct exception_data, fault_addr));
 	BLANK();
--- zfcpdump-kernel-4.4.orig/arch/parisc/kernel/module.c
+++ zfcpdump-kernel-4.4/arch/parisc/kernel/module.c
@@ -42,9 +42,9 @@
  *      We are not doing SEGREL32 handling correctly. According to the ABI, we
  *      should do a value offset, like this:
  *			if (in_init(me, (void *)val))
- *				val -= (uint32_t)me->module_init;
+ *				val -= (uint32_t)me->init_layout.base;
  *			else
- *				val -= (uint32_t)me->module_core;
+ *				val -= (uint32_t)me->core_layout.base;
  *	However, SEGREL32 is used only for PARISC unwind entries, and we want
  *	those entries to have an absolute address, and not just an offset.
  *
@@ -100,14 +100,14 @@
  * or init pieces the location is */
 static inline int in_init(struct module *me, void *loc)
 {
-	return (loc >= me->module_init &&
-		loc <= (me->module_init + me->init_size));
+	return (loc >= me->init_layout.base &&
+		loc <= (me->init_layout.base + me->init_layout.size));
 }
 
 static inline int in_core(struct module *me, void *loc)
 {
-	return (loc >= me->module_core &&
-		loc <= (me->module_core + me->core_size));
+	return (loc >= me->core_layout.base &&
+		loc <= (me->core_layout.base + me->core_layout.size));
 }
 
 static inline int in_local(struct module *me, void *loc)
@@ -367,13 +367,13 @@ int module_frob_arch_sections(CONST Elf_
 	}
 
 	/* align things a bit */
-	me->core_size = ALIGN(me->core_size, 16);
-	me->arch.got_offset = me->core_size;
-	me->core_size += gots * sizeof(struct got_entry);
-
-	me->core_size = ALIGN(me->core_size, 16);
-	me->arch.fdesc_offset = me->core_size;
-	me->core_size += fdescs * sizeof(Elf_Fdesc);
+	me->core_layout.size = ALIGN(me->core_layout.size, 16);
+	me->arch.got_offset = me->core_layout.size;
+	me->core_layout.size += gots * sizeof(struct got_entry);
+
+	me->core_layout.size = ALIGN(me->core_layout.size, 16);
+	me->arch.fdesc_offset = me->core_layout.size;
+	me->core_layout.size += fdescs * sizeof(Elf_Fdesc);
 
 	me->arch.got_max = gots;
 	me->arch.fdesc_max = fdescs;
@@ -391,7 +391,7 @@ static Elf64_Word get_got(struct module
 
 	BUG_ON(value == 0);
 
-	got = me->module_core + me->arch.got_offset;
+	got = me->core_layout.base + me->arch.got_offset;
 	for (i = 0; got[i].addr; i++)
 		if (got[i].addr == value)
 			goto out;
@@ -409,7 +409,7 @@ static Elf64_Word get_got(struct module
 #ifdef CONFIG_64BIT
 static Elf_Addr get_fdesc(struct module *me, unsigned long value)
 {
-	Elf_Fdesc *fdesc = me->module_core + me->arch.fdesc_offset;
+	Elf_Fdesc *fdesc = me->core_layout.base + me->arch.fdesc_offset;
 
 	if (!value) {
 		printk(KERN_ERR "%s: zero OPD requested!\n", me->name);
@@ -427,7 +427,7 @@ static Elf_Addr get_fdesc(struct module
 
 	/* Create new one */
 	fdesc->addr = value;
-	fdesc->gp = (Elf_Addr)me->module_core + me->arch.got_offset;
+	fdesc->gp = (Elf_Addr)me->core_layout.base + me->arch.got_offset;
 	return (Elf_Addr)fdesc;
 }
 #endif /* CONFIG_64BIT */
@@ -839,7 +839,7 @@ register_unwind_table(struct module *me,
 
 	table = (unsigned char *)sechdrs[me->arch.unwind_section].sh_addr;
 	end = table + sechdrs[me->arch.unwind_section].sh_size;
-	gp = (Elf_Addr)me->module_core + me->arch.got_offset;
+	gp = (Elf_Addr)me->core_layout.base + me->arch.got_offset;
 
 	DEBUGP("register_unwind_table(), sect = %d at 0x%p - 0x%p (gp=0x%lx)\n",
 	       me->arch.unwind_section, table, end, gp);
--- zfcpdump-kernel-4.4.orig/arch/parisc/kernel/parisc_ksyms.c
+++ zfcpdump-kernel-4.4/arch/parisc/kernel/parisc_ksyms.c
@@ -47,11 +47,11 @@ EXPORT_SYMBOL(__cmpxchg_u64);
 EXPORT_SYMBOL(lclear_user);
 EXPORT_SYMBOL(lstrnlen_user);
 
-/* Global fixups */
-extern void fixup_get_user_skip_1(void);
-extern void fixup_get_user_skip_2(void);
-extern void fixup_put_user_skip_1(void);
-extern void fixup_put_user_skip_2(void);
+/* Global fixups - defined as int to avoid creation of function pointers */
+extern int fixup_get_user_skip_1;
+extern int fixup_get_user_skip_2;
+extern int fixup_put_user_skip_1;
+extern int fixup_put_user_skip_2;
 EXPORT_SYMBOL(fixup_get_user_skip_1);
 EXPORT_SYMBOL(fixup_get_user_skip_2);
 EXPORT_SYMBOL(fixup_put_user_skip_1);
--- zfcpdump-kernel-4.4.orig/arch/parisc/kernel/ptrace.c
+++ zfcpdump-kernel-4.4/arch/parisc/kernel/ptrace.c
@@ -269,14 +269,19 @@ long compat_arch_ptrace(struct task_stru
 
 long do_syscall_trace_enter(struct pt_regs *regs)
 {
-	long ret = 0;
-
 	/* Do the secure computing check first. */
 	secure_computing_strict(regs->gr[20]);
 
 	if (test_thread_flag(TIF_SYSCALL_TRACE) &&
-	    tracehook_report_syscall_entry(regs))
-		ret = -1L;
+	    tracehook_report_syscall_entry(regs)) {
+		/*
+		 * Tracing decided this syscall should not happen or the
+		 * debugger stored an invalid system call number. Skip
+		 * the system call and the system call restart handling.
+		 */
+		regs->gr[20] = -1UL;
+		goto out;
+	}
 
 #ifdef CONFIG_64BIT
 	if (!is_compat_task())
@@ -290,7 +295,8 @@ long do_syscall_trace_enter(struct pt_re
 			regs->gr[24] & 0xffffffff,
 			regs->gr[23] & 0xffffffff);
 
-	return ret ? : regs->gr[20];
+out:
+	return regs->gr[20];
 }
 
 void do_syscall_trace_exit(struct pt_regs *regs)
--- zfcpdump-kernel-4.4.orig/arch/parisc/kernel/syscall.S
+++ zfcpdump-kernel-4.4/arch/parisc/kernel/syscall.S
@@ -343,7 +343,7 @@ tracesys_next:
 #endif
 
 	comiclr,>>=	__NR_Linux_syscalls, %r20, %r0
-	b,n	.Lsyscall_nosys
+	b,n	.Ltracesys_nosys
 
 	LDREGX  %r20(%r19), %r19
 
@@ -359,6 +359,9 @@ tracesys_next:
 	be      0(%sr7,%r19)
 	ldo	R%tracesys_exit(%r2),%r2
 
+.Ltracesys_nosys:
+	ldo	-ENOSYS(%r0),%r28		/* set errno */
+
 	/* Do *not* call this function on the gateway page, because it
 	makes a direct call to syscall_trace. */
 	
--- zfcpdump-kernel-4.4.orig/arch/parisc/kernel/traps.c
+++ zfcpdump-kernel-4.4/arch/parisc/kernel/traps.c
@@ -798,6 +798,9 @@ void notrace handle_interruption(int cod
 
 	    if (fault_space == 0 && !faulthandler_disabled())
 	    {
+		/* Clean up and return if in exception table. */
+		if (fixup_exception(regs))
+			return;
 		pdc_chassis_send_status(PDC_CHASSIS_DIRECT_PANIC);
 		parisc_terminate("Kernel Fault", regs, code, fault_address);
 	    }
--- zfcpdump-kernel-4.4.orig/arch/parisc/kernel/unaligned.c
+++ zfcpdump-kernel-4.4/arch/parisc/kernel/unaligned.c
@@ -666,7 +666,7 @@ void handle_unaligned(struct pt_regs *re
 		break;
 	}
 
-	if (modify && R1(regs->iir))
+	if (ret == 0 && modify && R1(regs->iir))
 		regs->gr[R1(regs->iir)] = newbase;
 
 
@@ -677,6 +677,14 @@ void handle_unaligned(struct pt_regs *re
 
 	if (ret)
 	{
+		/*
+		 * The unaligned handler failed.
+		 * If we were called by __get_user() or __put_user() jump
+		 * to it's exception fixup handler instead of crashing.
+		 */
+		if (!user_mode(regs) && fixup_exception(regs))
+			return;
+
 		printk(KERN_CRIT "Unaligned handler failed, ret = %d\n", ret);
 		die_if_kernel("Unaligned data reference", regs, 28);
 
--- zfcpdump-kernel-4.4.orig/arch/parisc/lib/fixup.S
+++ zfcpdump-kernel-4.4/arch/parisc/lib/fixup.S
@@ -26,6 +26,7 @@
 
 #ifdef CONFIG_SMP
 	.macro  get_fault_ip t1 t2
+	loadgp
 	addil LT%__per_cpu_offset,%r27
 	LDREG RT%__per_cpu_offset(%r1),\t1
 	/* t2 = smp_processor_id() */
@@ -40,14 +41,19 @@
 	LDREG RT%exception_data(%r1),\t1
 	/* t1 = this_cpu_ptr(&exception_data) */
 	add,l \t1,\t2,\t1
+	/* %r27 = t1->fault_gp - restore gp */
+	LDREG EXCDATA_GP(\t1), %r27
 	/* t1 = t1->fault_ip */
 	LDREG EXCDATA_IP(\t1), \t1
 	.endm
 #else
 	.macro  get_fault_ip t1 t2
+	loadgp
 	/* t1 = this_cpu_ptr(&exception_data) */
 	addil LT%exception_data,%r27
 	LDREG RT%exception_data(%r1),\t2
+	/* %r27 = t2->fault_gp - restore gp */
+	LDREG EXCDATA_GP(\t2), %r27
 	/* t1 = t2->fault_ip */
 	LDREG EXCDATA_IP(\t2), \t1
 	.endm
--- zfcpdump-kernel-4.4.orig/arch/parisc/mm/fault.c
+++ zfcpdump-kernel-4.4/arch/parisc/mm/fault.c
@@ -151,6 +151,7 @@ int fixup_exception(struct pt_regs *regs
 		struct exception_data *d;
 		d = this_cpu_ptr(&exception_data);
 		d->fault_ip = regs->iaoq[0];
+		d->fault_gp = regs->gr[27];
 		d->fault_space = regs->isr;
 		d->fault_addr = regs->ior;
 
--- zfcpdump-kernel-4.4.orig/arch/parisc/mm/hugetlbpage.c
+++ zfcpdump-kernel-4.4/arch/parisc/mm/hugetlbpage.c
@@ -105,15 +105,13 @@ static inline void purge_tlb_entries_hug
 	addr |= _HUGE_PAGE_SIZE_ENCODING_DEFAULT;
 
 	for (i = 0; i < (1 << (HPAGE_SHIFT-REAL_HPAGE_SHIFT)); i++) {
-		mtsp(mm->context, 1);
-		pdtlb(addr);
-		if (unlikely(split_tlb))
-			pitlb(addr);
+		purge_tlb_entries(mm, addr);
 		addr += (1UL << REAL_HPAGE_SHIFT);
 	}
 }
 
-void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
+/* __set_huge_pte_at() must be called holding the pa_tlb_lock. */
+static void __set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
 		     pte_t *ptep, pte_t entry)
 {
 	unsigned long addr_start;
@@ -123,14 +121,9 @@ void set_huge_pte_at(struct mm_struct *m
 	addr_start = addr;
 
 	for (i = 0; i < (1 << HUGETLB_PAGE_ORDER); i++) {
-		/* Directly write pte entry.  We could call set_pte_at(mm, addr, ptep, entry)
-		 * instead, but then we get double locking on pa_tlb_lock. */
-		*ptep = entry;
+		set_pte(ptep, entry);
 		ptep++;
 
-		/* Drop the PAGE_SIZE/non-huge tlb entry */
-		purge_tlb_entries(mm, addr);
-
 		addr += PAGE_SIZE;
 		pte_val(entry) += PAGE_SIZE;
 	}
@@ -138,18 +131,61 @@ void set_huge_pte_at(struct mm_struct *m
 	purge_tlb_entries_huge(mm, addr_start);
 }
 
+void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
+		     pte_t *ptep, pte_t entry)
+{
+	unsigned long flags;
+
+	purge_tlb_start(flags);
+	__set_huge_pte_at(mm, addr, ptep, entry);
+	purge_tlb_end(flags);
+}
+
 
 pte_t huge_ptep_get_and_clear(struct mm_struct *mm, unsigned long addr,
 			      pte_t *ptep)
 {
+	unsigned long flags;
 	pte_t entry;
 
+	purge_tlb_start(flags);
 	entry = *ptep;
-	set_huge_pte_at(mm, addr, ptep, __pte(0));
+	__set_huge_pte_at(mm, addr, ptep, __pte(0));
+	purge_tlb_end(flags);
 
 	return entry;
 }
 
+
+void huge_ptep_set_wrprotect(struct mm_struct *mm,
+				unsigned long addr, pte_t *ptep)
+{
+	unsigned long flags;
+	pte_t old_pte;
+
+	purge_tlb_start(flags);
+	old_pte = *ptep;
+	__set_huge_pte_at(mm, addr, ptep, pte_wrprotect(old_pte));
+	purge_tlb_end(flags);
+}
+
+int huge_ptep_set_access_flags(struct vm_area_struct *vma,
+				unsigned long addr, pte_t *ptep,
+				pte_t pte, int dirty)
+{
+	unsigned long flags;
+	int changed;
+
+	purge_tlb_start(flags);
+	changed = !pte_same(*ptep, pte);
+	if (changed) {
+		__set_huge_pte_at(vma->vm_mm, addr, ptep, pte);
+	}
+	purge_tlb_end(flags);
+	return changed;
+}
+
+
 int pmd_huge(pmd_t pmd)
 {
 	return 0;
--- zfcpdump-kernel-4.4.orig/arch/powerpc/Kconfig
+++ zfcpdump-kernel-4.4/arch/powerpc/Kconfig
@@ -1072,6 +1072,8 @@ source "net/Kconfig"
 
 source "drivers/Kconfig"
 
+source "ubuntu/Kconfig"
+
 source "fs/Kconfig"
 
 source "arch/powerpc/sysdev/qe_lib/Kconfig"
--- zfcpdump-kernel-4.4.orig/arch/powerpc/Makefile
+++ zfcpdump-kernel-4.4/arch/powerpc/Makefile
@@ -241,7 +241,7 @@ drivers-$(CONFIG_OPROFILE)	+= arch/power
 all: zImage
 
 # With make 3.82 we cannot mix normal and wildcard targets
-BOOT_TARGETS1 := zImage zImage.initrd uImage
+BOOT_TARGETS1 := zImage zImage.initrd uImage vmlinux.strip
 BOOT_TARGETS2 := zImage% dtbImage% treeImage.% cuImage.% simpleImage.% uImage.%
 
 PHONY += $(BOOT_TARGETS1) $(BOOT_TARGETS2)
--- zfcpdump-kernel-4.4.orig/arch/powerpc/crypto/aes-spe-glue.c
+++ zfcpdump-kernel-4.4/arch/powerpc/crypto/aes-spe-glue.c
@@ -22,6 +22,7 @@
 #include <asm/byteorder.h>
 #include <asm/switch_to.h>
 #include <crypto/algapi.h>
+#include <crypto/xts.h>
 
 /*
  * MAX_BYTES defines the number of bytes that are allowed to be processed
@@ -85,6 +86,7 @@ static void spe_begin(void)
 
 static void spe_end(void)
 {
+	disable_kernel_spe();
 	/* reenable preemption */
 	preempt_enable();
 }
@@ -125,6 +127,11 @@ static int ppc_xts_setkey(struct crypto_
 		   unsigned int key_len)
 {
 	struct ppc_xts_ctx *ctx = crypto_tfm_ctx(tfm);
+	int err;
+
+	err = xts_check_key(tfm, in_key, key_len);
+	if (err)
+		return err;
 
 	key_len >>= 1;
 
--- zfcpdump-kernel-4.4.orig/arch/powerpc/crypto/sha1-powerpc-asm.S
+++ zfcpdump-kernel-4.4/arch/powerpc/crypto/sha1-powerpc-asm.S
@@ -7,6 +7,15 @@
 #include <asm/ppc_asm.h>
 #include <asm/asm-offsets.h>
 
+#ifdef __BIG_ENDIAN__
+#define LWZ(rt, d, ra)	\
+	lwz	rt,d(ra)
+#else
+#define LWZ(rt, d, ra)	\
+	li	rt,d;	\
+	lwbrx	rt,rt,ra
+#endif
+
 /*
  * We roll the registers for T, A, B, C, D, E around on each
  * iteration; T on iteration t is A on iteration t+1, and so on.
@@ -23,7 +32,7 @@
 #define W(t)	(((t)%16)+16)
 
 #define LOADW(t)				\
-	lwz	W(t),(t)*4(r4)
+	LWZ(W(t),(t)*4,r4)
 
 #define STEPD0_LOAD(t)				\
 	andc	r0,RD(t),RB(t);		\
@@ -33,7 +42,7 @@
 	add	r0,RE(t),r15;			\
 	add	RT(t),RT(t),r6;		\
 	add	r14,r0,W(t);			\
-	lwz	W((t)+4),((t)+4)*4(r4);	\
+	LWZ(W((t)+4),((t)+4)*4,r4);	\
 	rotlwi	RB(t),RB(t),30;			\
 	add	RT(t),RT(t),r14
 
--- zfcpdump-kernel-4.4.orig/arch/powerpc/crypto/sha1-spe-glue.c
+++ zfcpdump-kernel-4.4/arch/powerpc/crypto/sha1-spe-glue.c
@@ -46,6 +46,7 @@ static void spe_begin(void)
 
 static void spe_end(void)
 {
+	disable_kernel_spe();
 	/* reenable preemption */
 	preempt_enable();
 }
--- zfcpdump-kernel-4.4.orig/arch/powerpc/crypto/sha256-spe-glue.c
+++ zfcpdump-kernel-4.4/arch/powerpc/crypto/sha256-spe-glue.c
@@ -47,6 +47,7 @@ static void spe_begin(void)
 
 static void spe_end(void)
 {
+	disable_kernel_spe();
 	/* reenable preemption */
 	preempt_enable();
 }
--- zfcpdump-kernel-4.4.orig/arch/powerpc/include/asm/atomic.h
+++ zfcpdump-kernel-4.4/arch/powerpc/include/asm/atomic.h
@@ -12,6 +12,24 @@
 
 #define ATOMIC_INIT(i)		{ (i) }
 
+/*
+ * Since *_return_relaxed and {cmp}xchg_relaxed are implemented with
+ * a "bne-" instruction at the end, so an isync is enough as a acquire barrier
+ * on the platform without lwsync.
+ */
+#define __atomic_op_acquire(op, args...)				\
+({									\
+	typeof(op##_relaxed(args)) __ret  = op##_relaxed(args);		\
+	__asm__ __volatile__(PPC_ACQUIRE_BARRIER "" : : : "memory");	\
+	__ret;								\
+})
+
+#define __atomic_op_release(op, args...)				\
+({									\
+	__asm__ __volatile__(PPC_RELEASE_BARRIER "" : : : "memory");	\
+	op##_relaxed(args);						\
+})
+
 static __inline__ int atomic_read(const atomic_t *v)
 {
 	int t;
@@ -42,27 +60,27 @@ static __inline__ void atomic_##op(int a
 	: "cc");							\
 }									\
 
-#define ATOMIC_OP_RETURN(op, asm_op)					\
-static __inline__ int atomic_##op##_return(int a, atomic_t *v)		\
+#define ATOMIC_OP_RETURN_RELAXED(op, asm_op)				\
+static inline int atomic_##op##_return_relaxed(int a, atomic_t *v)	\
 {									\
 	int t;								\
 									\
 	__asm__ __volatile__(						\
-	PPC_ATOMIC_ENTRY_BARRIER					\
-"1:	lwarx	%0,0,%2		# atomic_" #op "_return\n"		\
-	#asm_op " %0,%1,%0\n"						\
-	PPC405_ERR77(0,%2)						\
-"	stwcx.	%0,0,%2 \n"						\
+"1:	lwarx	%0,0,%3		# atomic_" #op "_return_relaxed\n"	\
+	#asm_op " %0,%2,%0\n"						\
+	PPC405_ERR77(0, %3)						\
+"	stwcx.	%0,0,%3\n"						\
 "	bne-	1b\n"							\
-	PPC_ATOMIC_EXIT_BARRIER						\
-	: "=&r" (t)							\
+	: "=&r" (t), "+m" (v->counter)					\
 	: "r" (a), "r" (&v->counter)					\
-	: "cc", "memory");						\
+	: "cc");							\
 									\
 	return t;							\
 }
 
-#define ATOMIC_OPS(op, asm_op) ATOMIC_OP(op, asm_op) ATOMIC_OP_RETURN(op, asm_op)
+#define ATOMIC_OPS(op, asm_op)						\
+	ATOMIC_OP(op, asm_op)						\
+	ATOMIC_OP_RETURN_RELAXED(op, asm_op)
 
 ATOMIC_OPS(add, add)
 ATOMIC_OPS(sub, subf)
@@ -71,8 +89,11 @@ ATOMIC_OP(and, and)
 ATOMIC_OP(or, or)
 ATOMIC_OP(xor, xor)
 
+#define atomic_add_return_relaxed atomic_add_return_relaxed
+#define atomic_sub_return_relaxed atomic_sub_return_relaxed
+
 #undef ATOMIC_OPS
-#undef ATOMIC_OP_RETURN
+#undef ATOMIC_OP_RETURN_RELAXED
 #undef ATOMIC_OP
 
 #define atomic_add_negative(a, v)	(atomic_add_return((a), (v)) < 0)
@@ -92,21 +113,19 @@ static __inline__ void atomic_inc(atomic
 	: "cc", "xer");
 }
 
-static __inline__ int atomic_inc_return(atomic_t *v)
+static __inline__ int atomic_inc_return_relaxed(atomic_t *v)
 {
 	int t;
 
 	__asm__ __volatile__(
-	PPC_ATOMIC_ENTRY_BARRIER
-"1:	lwarx	%0,0,%1		# atomic_inc_return\n\
-	addic	%0,%0,1\n"
-	PPC405_ERR77(0,%1)
-"	stwcx.	%0,0,%1 \n\
-	bne-	1b"
-	PPC_ATOMIC_EXIT_BARRIER
-	: "=&r" (t)
+"1:	lwarx	%0,0,%2		# atomic_inc_return_relaxed\n"
+"	addic	%0,%0,1\n"
+	PPC405_ERR77(0, %2)
+"	stwcx.	%0,0,%2\n"
+"	bne-	1b"
+	: "=&r" (t), "+m" (v->counter)
 	: "r" (&v->counter)
-	: "cc", "xer", "memory");
+	: "cc", "xer");
 
 	return t;
 }
@@ -136,27 +155,34 @@ static __inline__ void atomic_dec(atomic
 	: "cc", "xer");
 }
 
-static __inline__ int atomic_dec_return(atomic_t *v)
+static __inline__ int atomic_dec_return_relaxed(atomic_t *v)
 {
 	int t;
 
 	__asm__ __volatile__(
-	PPC_ATOMIC_ENTRY_BARRIER
-"1:	lwarx	%0,0,%1		# atomic_dec_return\n\
-	addic	%0,%0,-1\n"
-	PPC405_ERR77(0,%1)
-"	stwcx.	%0,0,%1\n\
-	bne-	1b"
-	PPC_ATOMIC_EXIT_BARRIER
-	: "=&r" (t)
+"1:	lwarx	%0,0,%2		# atomic_dec_return_relaxed\n"
+"	addic	%0,%0,-1\n"
+	PPC405_ERR77(0, %2)
+"	stwcx.	%0,0,%2\n"
+"	bne-	1b"
+	: "=&r" (t), "+m" (v->counter)
 	: "r" (&v->counter)
-	: "cc", "xer", "memory");
+	: "cc", "xer");
 
 	return t;
 }
 
+#define atomic_inc_return_relaxed atomic_inc_return_relaxed
+#define atomic_dec_return_relaxed atomic_dec_return_relaxed
+
 #define atomic_cmpxchg(v, o, n) (cmpxchg(&((v)->counter), (o), (n)))
+#define atomic_cmpxchg_relaxed(v, o, n) \
+	cmpxchg_relaxed(&((v)->counter), (o), (n))
+#define atomic_cmpxchg_acquire(v, o, n) \
+	cmpxchg_acquire(&((v)->counter), (o), (n))
+
 #define atomic_xchg(v, new) (xchg(&((v)->counter), new))
+#define atomic_xchg_relaxed(v, new) xchg_relaxed(&((v)->counter), (new))
 
 /**
  * __atomic_add_unless - add unless the number is a given value
@@ -285,26 +311,27 @@ static __inline__ void atomic64_##op(lon
 	: "cc");							\
 }
 
-#define ATOMIC64_OP_RETURN(op, asm_op)					\
-static __inline__ long atomic64_##op##_return(long a, atomic64_t *v)	\
+#define ATOMIC64_OP_RETURN_RELAXED(op, asm_op)				\
+static inline long							\
+atomic64_##op##_return_relaxed(long a, atomic64_t *v)			\
 {									\
 	long t;								\
 									\
 	__asm__ __volatile__(						\
-	PPC_ATOMIC_ENTRY_BARRIER					\
-"1:	ldarx	%0,0,%2		# atomic64_" #op "_return\n"		\
-	#asm_op " %0,%1,%0\n"						\
-"	stdcx.	%0,0,%2 \n"						\
+"1:	ldarx	%0,0,%3		# atomic64_" #op "_return_relaxed\n"	\
+	#asm_op " %0,%2,%0\n"						\
+"	stdcx.	%0,0,%3\n"						\
 "	bne-	1b\n"							\
-	PPC_ATOMIC_EXIT_BARRIER						\
-	: "=&r" (t)							\
+	: "=&r" (t), "+m" (v->counter)					\
 	: "r" (a), "r" (&v->counter)					\
-	: "cc", "memory");						\
+	: "cc");							\
 									\
 	return t;							\
 }
 
-#define ATOMIC64_OPS(op, asm_op) ATOMIC64_OP(op, asm_op) ATOMIC64_OP_RETURN(op, asm_op)
+#define ATOMIC64_OPS(op, asm_op)					\
+	ATOMIC64_OP(op, asm_op)						\
+	ATOMIC64_OP_RETURN_RELAXED(op, asm_op)
 
 ATOMIC64_OPS(add, add)
 ATOMIC64_OPS(sub, subf)
@@ -312,8 +339,11 @@ ATOMIC64_OP(and, and)
 ATOMIC64_OP(or, or)
 ATOMIC64_OP(xor, xor)
 
-#undef ATOMIC64_OPS
-#undef ATOMIC64_OP_RETURN
+#define atomic64_add_return_relaxed atomic64_add_return_relaxed
+#define atomic64_sub_return_relaxed atomic64_sub_return_relaxed
+
+#undef ATOPIC64_OPS
+#undef ATOMIC64_OP_RETURN_RELAXED
 #undef ATOMIC64_OP
 
 #define atomic64_add_negative(a, v)	(atomic64_add_return((a), (v)) < 0)
@@ -332,20 +362,18 @@ static __inline__ void atomic64_inc(atom
 	: "cc", "xer");
 }
 
-static __inline__ long atomic64_inc_return(atomic64_t *v)
+static __inline__ long atomic64_inc_return_relaxed(atomic64_t *v)
 {
 	long t;
 
 	__asm__ __volatile__(
-	PPC_ATOMIC_ENTRY_BARRIER
-"1:	ldarx	%0,0,%1		# atomic64_inc_return\n\
-	addic	%0,%0,1\n\
-	stdcx.	%0,0,%1 \n\
-	bne-	1b"
-	PPC_ATOMIC_EXIT_BARRIER
-	: "=&r" (t)
+"1:	ldarx	%0,0,%2		# atomic64_inc_return_relaxed\n"
+"	addic	%0,%0,1\n"
+"	stdcx.	%0,0,%2\n"
+"	bne-	1b"
+	: "=&r" (t), "+m" (v->counter)
 	: "r" (&v->counter)
-	: "cc", "xer", "memory");
+	: "cc", "xer");
 
 	return t;
 }
@@ -374,24 +402,25 @@ static __inline__ void atomic64_dec(atom
 	: "cc", "xer");
 }
 
-static __inline__ long atomic64_dec_return(atomic64_t *v)
+static __inline__ long atomic64_dec_return_relaxed(atomic64_t *v)
 {
 	long t;
 
 	__asm__ __volatile__(
-	PPC_ATOMIC_ENTRY_BARRIER
-"1:	ldarx	%0,0,%1		# atomic64_dec_return\n\
-	addic	%0,%0,-1\n\
-	stdcx.	%0,0,%1\n\
-	bne-	1b"
-	PPC_ATOMIC_EXIT_BARRIER
-	: "=&r" (t)
+"1:	ldarx	%0,0,%2		# atomic64_dec_return_relaxed\n"
+"	addic	%0,%0,-1\n"
+"	stdcx.	%0,0,%2\n"
+"	bne-	1b"
+	: "=&r" (t), "+m" (v->counter)
 	: "r" (&v->counter)
-	: "cc", "xer", "memory");
+	: "cc", "xer");
 
 	return t;
 }
 
+#define atomic64_inc_return_relaxed atomic64_inc_return_relaxed
+#define atomic64_dec_return_relaxed atomic64_dec_return_relaxed
+
 #define atomic64_sub_and_test(a, v)	(atomic64_sub_return((a), (v)) == 0)
 #define atomic64_dec_and_test(v)	(atomic64_dec_return((v)) == 0)
 
@@ -420,7 +449,13 @@ static __inline__ long atomic64_dec_if_p
 }
 
 #define atomic64_cmpxchg(v, o, n) (cmpxchg(&((v)->counter), (o), (n)))
+#define atomic64_cmpxchg_relaxed(v, o, n) \
+	cmpxchg_relaxed(&((v)->counter), (o), (n))
+#define atomic64_cmpxchg_acquire(v, o, n) \
+	cmpxchg_acquire(&((v)->counter), (o), (n))
+
 #define atomic64_xchg(v, new) (xchg(&((v)->counter), new))
+#define atomic64_xchg_relaxed(v, new) xchg_relaxed(&((v)->counter), (new))
 
 /**
  * atomic64_add_unless - add unless the number is a given value
--- zfcpdump-kernel-4.4.orig/arch/powerpc/include/asm/barrier.h
+++ zfcpdump-kernel-4.4/arch/powerpc/include/asm/barrier.h
@@ -34,7 +34,7 @@
 #define rmb()  __asm__ __volatile__ ("sync" : : : "memory")
 #define wmb()  __asm__ __volatile__ ("sync" : : : "memory")
 
-#define smp_store_mb(var, value)	do { WRITE_ONCE(var, value); mb(); } while (0)
+#define smp_store_mb(var, value) do { WRITE_ONCE(var, value); smp_mb(); } while (0)
 
 #ifdef __SUBARCH_HAS_LWSYNC
 #    define SMPWMB      LWSYNC
--- zfcpdump-kernel-4.4.orig/arch/powerpc/include/asm/cmpxchg.h
+++ zfcpdump-kernel-4.4/arch/powerpc/include/asm/cmpxchg.h
@@ -9,21 +9,20 @@
 /*
  * Atomic exchange
  *
- * Changes the memory location '*ptr' to be val and returns
+ * Changes the memory location '*p' to be val and returns
  * the previous value stored there.
  */
+
 static __always_inline unsigned long
-__xchg_u32(volatile void *p, unsigned long val)
+__xchg_u32_local(volatile void *p, unsigned long val)
 {
 	unsigned long prev;
 
 	__asm__ __volatile__(
-	PPC_RELEASE_BARRIER
 "1:	lwarx	%0,0,%2 \n"
 	PPC405_ERR77(0,%2)
 "	stwcx.	%3,0,%2 \n\
 	bne-	1b"
-	PPC_ACQUIRE_BARRIER
 	: "=&r" (prev), "+m" (*(volatile unsigned int *)p)
 	: "r" (p), "r" (val)
 	: "cc", "memory");
@@ -31,42 +30,34 @@ __xchg_u32(volatile void *p, unsigned lo
 	return prev;
 }
 
-/*
- * Atomic exchange
- *
- * Changes the memory location '*ptr' to be val and returns
- * the previous value stored there.
- */
 static __always_inline unsigned long
-__xchg_u32_local(volatile void *p, unsigned long val)
+__xchg_u32_relaxed(u32 *p, unsigned long val)
 {
 	unsigned long prev;
 
 	__asm__ __volatile__(
-"1:	lwarx	%0,0,%2 \n"
-	PPC405_ERR77(0,%2)
-"	stwcx.	%3,0,%2 \n\
-	bne-	1b"
-	: "=&r" (prev), "+m" (*(volatile unsigned int *)p)
+"1:	lwarx	%0,0,%2\n"
+	PPC405_ERR77(0, %2)
+"	stwcx.	%3,0,%2\n"
+"	bne-	1b"
+	: "=&r" (prev), "+m" (*p)
 	: "r" (p), "r" (val)
-	: "cc", "memory");
+	: "cc");
 
 	return prev;
 }
 
 #ifdef CONFIG_PPC64
 static __always_inline unsigned long
-__xchg_u64(volatile void *p, unsigned long val)
+__xchg_u64_local(volatile void *p, unsigned long val)
 {
 	unsigned long prev;
 
 	__asm__ __volatile__(
-	PPC_RELEASE_BARRIER
 "1:	ldarx	%0,0,%2 \n"
 	PPC405_ERR77(0,%2)
 "	stdcx.	%3,0,%2 \n\
 	bne-	1b"
-	PPC_ACQUIRE_BARRIER
 	: "=&r" (prev), "+m" (*(volatile unsigned long *)p)
 	: "r" (p), "r" (val)
 	: "cc", "memory");
@@ -75,18 +66,18 @@ __xchg_u64(volatile void *p, unsigned lo
 }
 
 static __always_inline unsigned long
-__xchg_u64_local(volatile void *p, unsigned long val)
+__xchg_u64_relaxed(u64 *p, unsigned long val)
 {
 	unsigned long prev;
 
 	__asm__ __volatile__(
-"1:	ldarx	%0,0,%2 \n"
-	PPC405_ERR77(0,%2)
-"	stdcx.	%3,0,%2 \n\
-	bne-	1b"
-	: "=&r" (prev), "+m" (*(volatile unsigned long *)p)
+"1:	ldarx	%0,0,%2\n"
+	PPC405_ERR77(0, %2)
+"	stdcx.	%3,0,%2\n"
+"	bne-	1b"
+	: "=&r" (prev), "+m" (*p)
 	: "r" (p), "r" (val)
-	: "cc", "memory");
+	: "cc");
 
 	return prev;
 }
@@ -99,14 +90,14 @@ __xchg_u64_local(volatile void *p, unsig
 extern void __xchg_called_with_bad_pointer(void);
 
 static __always_inline unsigned long
-__xchg(volatile void *ptr, unsigned long x, unsigned int size)
+__xchg_local(volatile void *ptr, unsigned long x, unsigned int size)
 {
 	switch (size) {
 	case 4:
-		return __xchg_u32(ptr, x);
+		return __xchg_u32_local(ptr, x);
 #ifdef CONFIG_PPC64
 	case 8:
-		return __xchg_u64(ptr, x);
+		return __xchg_u64_local(ptr, x);
 #endif
 	}
 	__xchg_called_with_bad_pointer();
@@ -114,25 +105,19 @@ __xchg(volatile void *ptr, unsigned long
 }
 
 static __always_inline unsigned long
-__xchg_local(volatile void *ptr, unsigned long x, unsigned int size)
+__xchg_relaxed(void *ptr, unsigned long x, unsigned int size)
 {
 	switch (size) {
 	case 4:
-		return __xchg_u32_local(ptr, x);
+		return __xchg_u32_relaxed(ptr, x);
 #ifdef CONFIG_PPC64
 	case 8:
-		return __xchg_u64_local(ptr, x);
+		return __xchg_u64_relaxed(ptr, x);
 #endif
 	}
 	__xchg_called_with_bad_pointer();
 	return x;
 }
-#define xchg(ptr,x)							     \
-  ({									     \
-     __typeof__(*(ptr)) _x_ = (x);					     \
-     (__typeof__(*(ptr))) __xchg((ptr), (unsigned long)_x_, sizeof(*(ptr))); \
-  })
-
 #define xchg_local(ptr,x)						     \
   ({									     \
      __typeof__(*(ptr)) _x_ = (x);					     \
@@ -140,6 +125,12 @@ __xchg_local(volatile void *ptr, unsigne
      		(unsigned long)_x_, sizeof(*(ptr))); 			     \
   })
 
+#define xchg_relaxed(ptr, x)						\
+({									\
+	__typeof__(*(ptr)) _x_ = (x);					\
+	(__typeof__(*(ptr))) __xchg_relaxed((ptr),			\
+			(unsigned long)_x_, sizeof(*(ptr)));		\
+})
 /*
  * Compare and exchange - if *p == old, set it to new,
  * and return the old value of *p.
@@ -151,14 +142,14 @@ __cmpxchg_u32(volatile unsigned int *p,
 	unsigned int prev;
 
 	__asm__ __volatile__ (
-	PPC_RELEASE_BARRIER
+	PPC_ATOMIC_ENTRY_BARRIER
 "1:	lwarx	%0,0,%2		# __cmpxchg_u32\n\
 	cmpw	0,%0,%3\n\
 	bne-	2f\n"
 	PPC405_ERR77(0,%2)
 "	stwcx.	%4,0,%2\n\
 	bne-	1b"
-	PPC_ACQUIRE_BARRIER
+	PPC_ATOMIC_EXIT_BARRIER
 	"\n\
 2:"
 	: "=&r" (prev), "+m" (*p)
@@ -190,6 +181,56 @@ __cmpxchg_u32_local(volatile unsigned in
 	return prev;
 }
 
+static __always_inline unsigned long
+__cmpxchg_u32_relaxed(u32 *p, unsigned long old, unsigned long new)
+{
+	unsigned long prev;
+
+	__asm__ __volatile__ (
+"1:	lwarx	%0,0,%2		# __cmpxchg_u32_relaxed\n"
+"	cmpw	0,%0,%3\n"
+"	bne-	2f\n"
+	PPC405_ERR77(0, %2)
+"	stwcx.	%4,0,%2\n"
+"	bne-	1b\n"
+"2:"
+	: "=&r" (prev), "+m" (*p)
+	: "r" (p), "r" (old), "r" (new)
+	: "cc");
+
+	return prev;
+}
+
+/*
+ * cmpxchg family don't have order guarantee if cmp part fails, therefore we
+ * can avoid superfluous barriers if we use assembly code to implement
+ * cmpxchg() and cmpxchg_acquire(), however we don't do the similar for
+ * cmpxchg_release() because that will result in putting a barrier in the
+ * middle of a ll/sc loop, which is probably a bad idea. For example, this
+ * might cause the conditional store more likely to fail.
+ */
+static __always_inline unsigned long
+__cmpxchg_u32_acquire(u32 *p, unsigned long old, unsigned long new)
+{
+	unsigned long prev;
+
+	__asm__ __volatile__ (
+"1:	lwarx	%0,0,%2		# __cmpxchg_u32_acquire\n"
+"	cmpw	0,%0,%3\n"
+"	bne-	2f\n"
+	PPC405_ERR77(0, %2)
+"	stwcx.	%4,0,%2\n"
+"	bne-	1b\n"
+	PPC_ACQUIRE_BARRIER
+	"\n"
+"2:"
+	: "=&r" (prev), "+m" (*p)
+	: "r" (p), "r" (old), "r" (new)
+	: "cc", "memory");
+
+	return prev;
+}
+
 #ifdef CONFIG_PPC64
 static __always_inline unsigned long
 __cmpxchg_u64(volatile unsigned long *p, unsigned long old, unsigned long new)
@@ -197,13 +238,13 @@ __cmpxchg_u64(volatile unsigned long *p,
 	unsigned long prev;
 
 	__asm__ __volatile__ (
-	PPC_RELEASE_BARRIER
+	PPC_ATOMIC_ENTRY_BARRIER
 "1:	ldarx	%0,0,%2		# __cmpxchg_u64\n\
 	cmpd	0,%0,%3\n\
 	bne-	2f\n\
 	stdcx.	%4,0,%2\n\
 	bne-	1b"
-	PPC_ACQUIRE_BARRIER
+	PPC_ATOMIC_EXIT_BARRIER
 	"\n\
 2:"
 	: "=&r" (prev), "+m" (*p)
@@ -233,6 +274,46 @@ __cmpxchg_u64_local(volatile unsigned lo
 
 	return prev;
 }
+
+static __always_inline unsigned long
+__cmpxchg_u64_relaxed(u64 *p, unsigned long old, unsigned long new)
+{
+	unsigned long prev;
+
+	__asm__ __volatile__ (
+"1:	ldarx	%0,0,%2		# __cmpxchg_u64_relaxed\n"
+"	cmpd	0,%0,%3\n"
+"	bne-	2f\n"
+"	stdcx.	%4,0,%2\n"
+"	bne-	1b\n"
+"2:"
+	: "=&r" (prev), "+m" (*p)
+	: "r" (p), "r" (old), "r" (new)
+	: "cc");
+
+	return prev;
+}
+
+static __always_inline unsigned long
+__cmpxchg_u64_acquire(u64 *p, unsigned long old, unsigned long new)
+{
+	unsigned long prev;
+
+	__asm__ __volatile__ (
+"1:	ldarx	%0,0,%2		# __cmpxchg_u64_acquire\n"
+"	cmpd	0,%0,%3\n"
+"	bne-	2f\n"
+"	stdcx.	%4,0,%2\n"
+"	bne-	1b\n"
+	PPC_ACQUIRE_BARRIER
+	"\n"
+"2:"
+	: "=&r" (prev), "+m" (*p)
+	: "r" (p), "r" (old), "r" (new)
+	: "cc", "memory");
+
+	return prev;
+}
 #endif
 
 /* This function doesn't exist, so you'll get a linker error
@@ -271,6 +352,37 @@ __cmpxchg_local(volatile void *ptr, unsi
 	return old;
 }
 
+static __always_inline unsigned long
+__cmpxchg_relaxed(void *ptr, unsigned long old, unsigned long new,
+		  unsigned int size)
+{
+	switch (size) {
+	case 4:
+		return __cmpxchg_u32_relaxed(ptr, old, new);
+#ifdef CONFIG_PPC64
+	case 8:
+		return __cmpxchg_u64_relaxed(ptr, old, new);
+#endif
+	}
+	__cmpxchg_called_with_bad_pointer();
+	return old;
+}
+
+static __always_inline unsigned long
+__cmpxchg_acquire(void *ptr, unsigned long old, unsigned long new,
+		  unsigned int size)
+{
+	switch (size) {
+	case 4:
+		return __cmpxchg_u32_acquire(ptr, old, new);
+#ifdef CONFIG_PPC64
+	case 8:
+		return __cmpxchg_u64_acquire(ptr, old, new);
+#endif
+	}
+	__cmpxchg_called_with_bad_pointer();
+	return old;
+}
 #define cmpxchg(ptr, o, n)						 \
   ({									 \
      __typeof__(*(ptr)) _o_ = (o);					 \
@@ -288,6 +400,23 @@ __cmpxchg_local(volatile void *ptr, unsi
 				    (unsigned long)_n_, sizeof(*(ptr))); \
   })
 
+#define cmpxchg_relaxed(ptr, o, n)					\
+({									\
+	__typeof__(*(ptr)) _o_ = (o);					\
+	__typeof__(*(ptr)) _n_ = (n);					\
+	(__typeof__(*(ptr))) __cmpxchg_relaxed((ptr),			\
+			(unsigned long)_o_, (unsigned long)_n_,		\
+			sizeof(*(ptr)));				\
+})
+
+#define cmpxchg_acquire(ptr, o, n)					\
+({									\
+	__typeof__(*(ptr)) _o_ = (o);					\
+	__typeof__(*(ptr)) _n_ = (n);					\
+	(__typeof__(*(ptr))) __cmpxchg_acquire((ptr),			\
+			(unsigned long)_o_, (unsigned long)_n_,		\
+			sizeof(*(ptr)));				\
+})
 #ifdef CONFIG_PPC64
 #define cmpxchg64(ptr, o, n)						\
   ({									\
@@ -299,7 +428,16 @@ __cmpxchg_local(volatile void *ptr, unsi
 	BUILD_BUG_ON(sizeof(*(ptr)) != 8);				\
 	cmpxchg_local((ptr), (o), (n));					\
   })
-#define cmpxchg64_relaxed	cmpxchg64_local
+#define cmpxchg64_relaxed(ptr, o, n)					\
+({									\
+	BUILD_BUG_ON(sizeof(*(ptr)) != 8);				\
+	cmpxchg_relaxed((ptr), (o), (n));				\
+})
+#define cmpxchg64_acquire(ptr, o, n)					\
+({									\
+	BUILD_BUG_ON(sizeof(*(ptr)) != 8);				\
+	cmpxchg_acquire((ptr), (o), (n));				\
+})
 #else
 #include <asm-generic/cmpxchg-local.h>
 #define cmpxchg64_local(ptr, o, n) __cmpxchg64_local_generic((ptr), (o), (n))
--- zfcpdump-kernel-4.4.orig/arch/powerpc/include/asm/eeh.h
+++ zfcpdump-kernel-4.4/arch/powerpc/include/asm/eeh.h
@@ -81,6 +81,7 @@ struct pci_dn;
 #define EEH_PE_KEEP		(1 << 8)	/* Keep PE on hotplug	*/
 #define EEH_PE_CFG_RESTRICTED	(1 << 9)	/* Block config on error */
 #define EEH_PE_REMOVED		(1 << 10)	/* Removed permanently	*/
+#define EEH_PE_PRI_BUS		(1 << 11)	/* Cached primary bus   */
 
 struct eeh_pe {
 	int type;			/* PE type: PHB/Bus/Device	*/
--- /dev/null
+++ zfcpdump-kernel-4.4/arch/powerpc/include/asm/hmi.h
@@ -0,0 +1,45 @@
+/*
+ * Hypervisor Maintenance Interrupt header file.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.
+ *
+ * Copyright 2015 IBM Corporation
+ * Author: Mahesh Salgaonkar <mahesh@linux.vnet.ibm.com>
+ */
+
+#ifndef __ASM_PPC64_HMI_H__
+#define __ASM_PPC64_HMI_H__
+
+#ifdef CONFIG_PPC_BOOK3S_64
+
+#define	CORE_TB_RESYNC_REQ_BIT		63
+#define MAX_SUBCORE_PER_CORE		4
+
+/*
+ * sibling_subcore_state structure is used to co-ordinate all threads
+ * during HMI to avoid TB corruption. This structure is allocated once
+ * per each core and shared by all threads on that core.
+ */
+struct sibling_subcore_state {
+	unsigned long	flags;
+	u8		in_guest[MAX_SUBCORE_PER_CORE];
+};
+
+extern void wait_for_subcore_guest_exit(void);
+extern void wait_for_tb_resync(void);
+#else
+static inline void wait_for_subcore_guest_exit(void) { }
+static inline void wait_for_tb_resync(void) { }
+#endif
+#endif /* __ASM_PPC64_HMI_H__ */
--- zfcpdump-kernel-4.4.orig/arch/powerpc/include/asm/hvcall.h
+++ zfcpdump-kernel-4.4/arch/powerpc/include/asm/hvcall.h
@@ -94,6 +94,7 @@
 #define H_SG_LIST	-72
 #define H_OP_MODE	-73
 #define H_COP_HW	-74
+#define H_STATE		-75
 #define H_UNSUPPORTED_FLAG_START	-256
 #define H_UNSUPPORTED_FLAG_END		-511
 #define H_MULTI_THREADS_ACTIVE	-9005
@@ -258,11 +259,16 @@
 #define H_DEL_CONN		0x288
 #define H_JOIN			0x298
 #define H_VASI_STATE            0x2A4
+#define H_VIOCTL		0x2A8
 #define H_ENABLE_CRQ		0x2B0
 #define H_GET_EM_PARMS		0x2B8
 #define H_SET_MPP		0x2D0
 #define H_GET_MPP		0x2D4
+#define H_REG_SUB_CRQ		0x2DC
 #define H_HOME_NODE_ASSOCIATIVITY 0x2EC
+#define H_FREE_SUB_CRQ		0x2E0
+#define H_SEND_SUB_CRQ		0x2E4
+#define H_SEND_SUB_CRQ_INDIRECT	0x2E8
 #define H_BEST_ENERGY		0x2F4
 #define H_XIRR_X		0x2FC
 #define H_RANDOM		0x300
@@ -271,6 +277,21 @@
 #define H_SET_MODE		0x31C
 #define MAX_HCALL_OPCODE	H_SET_MODE
 
+/* H_VIOCTL functions */
+#define H_GET_VIOA_DUMP_SIZE	0x01
+#define H_GET_VIOA_DUMP		0x02
+#define H_GET_ILLAN_NUM_VLAN_IDS 0x03
+#define H_GET_ILLAN_VLAN_ID_LIST 0x04
+#define H_GET_ILLAN_SWITCH_ID	0x05
+#define H_DISABLE_MIGRATION	0x06
+#define H_ENABLE_MIGRATION	0x07
+#define H_GET_PARTNER_INFO	0x08
+#define H_GET_PARTNER_WWPN_LIST	0x09
+#define H_DISABLE_ALL_VIO_INTS	0x0A
+#define H_DISABLE_VIO_INTERRUPT	0x0B
+#define H_ENABLE_VIO_INTERRUPT	0x0C
+
+
 /* Platform specific hcalls, used by KVM */
 #define H_RTAS			0xf000
 
--- zfcpdump-kernel-4.4.orig/arch/powerpc/include/asm/icswx.h
+++ zfcpdump-kernel-4.4/arch/powerpc/include/asm/icswx.h
@@ -164,6 +164,7 @@ struct coprocessor_request_block {
 #define ICSWX_INITIATED		(0x8)
 #define ICSWX_BUSY		(0x4)
 #define ICSWX_REJECTED		(0x2)
+#define ICSWX_XERS0		(0x1)	/* undefined or set from XERSO. */
 
 static inline int icswx(__be32 ccw, struct coprocessor_request_block *crb)
 {
--- zfcpdump-kernel-4.4.orig/arch/powerpc/include/asm/io.h
+++ zfcpdump-kernel-4.4/arch/powerpc/include/asm/io.h
@@ -385,6 +385,17 @@ static inline void __raw_writeq(unsigned
 {
 	*(volatile unsigned long __force *)PCI_FIX_ADDR(addr) = v;
 }
+
+/*
+ * Real mode version of the above. stdcix is only supposed to be used
+ * in hypervisor real mode as per the architecture spec.
+ */
+static inline void __raw_rm_writeq(u64 val, volatile void __iomem *paddr)
+{
+	__asm__ __volatile__("stdcix %0,0,%1"
+		: : "r" (val), "r" (paddr) : "memory");
+}
+
 #endif /* __powerpc64__ */
 
 /*
--- zfcpdump-kernel-4.4.orig/arch/powerpc/include/asm/kvm_booke.h
+++ zfcpdump-kernel-4.4/arch/powerpc/include/asm/kvm_booke.h
@@ -100,6 +100,11 @@ static inline ulong kvmppc_get_pc(struct
 	return vcpu->arch.pc;
 }
 
+static inline bool kvmppc_is_bigendian(struct kvm_vcpu *vcpu)
+{
+	return 1;
+}
+
 static inline ulong kvmppc_get_fault_dar(struct kvm_vcpu *vcpu)
 {
 	return vcpu->arch.fault_dear;
--- zfcpdump-kernel-4.4.orig/arch/powerpc/include/asm/opal-api.h
+++ zfcpdump-kernel-4.4/arch/powerpc/include/asm/opal-api.h
@@ -157,7 +157,8 @@
 #define OPAL_LEDS_GET_INDICATOR			114
 #define OPAL_LEDS_SET_INDICATOR			115
 #define OPAL_CEC_REBOOT2			116
-#define OPAL_LAST				116
+#define OPAL_CONSOLE_FLUSH			117
+#define OPAL_LAST				117
 
 /* Device tree flags */
 
--- zfcpdump-kernel-4.4.orig/arch/powerpc/include/asm/opal.h
+++ zfcpdump-kernel-4.4/arch/powerpc/include/asm/opal.h
@@ -35,6 +35,7 @@ int64_t opal_console_read(int64_t term_n
 			  uint8_t *buffer);
 int64_t opal_console_write_buffer_space(int64_t term_number,
 					__be64 *length);
+int64_t opal_console_flush(int64_t term_number);
 int64_t opal_rtc_read(__be32 *year_month_day,
 		      __be64 *hour_minute_second_millisecond);
 int64_t opal_rtc_write(uint32_t year_month_day,
@@ -262,6 +263,8 @@ extern int opal_resync_timebase(void);
 
 extern void opal_lpc_init(void);
 
+extern void opal_kmsg_init(void);
+
 extern int opal_event_request(unsigned int opal_event_nr);
 
 struct opal_sg_list *opal_vmalloc_to_sg_list(void *vmalloc_addr,
--- zfcpdump-kernel-4.4.orig/arch/powerpc/include/asm/paca.h
+++ zfcpdump-kernel-4.4/arch/powerpc/include/asm/paca.h
@@ -24,6 +24,7 @@
 #ifdef CONFIG_KVM_BOOK3S_64_HANDLER
 #include <asm/kvm_book3s_asm.h>
 #endif
+#include <asm/hmi.h>
 
 register struct paca_struct *local_paca asm("r13");
 
@@ -41,6 +42,9 @@ extern unsigned int debug_smp_processor_
 #define get_lppaca()	(get_paca()->lppaca_ptr)
 #define get_slb_shadow()	(get_paca()->slb_shadow_ptr)
 
+/* Maximum number of threads per core. */
+#define	MAX_SMT		8
+
 struct task_struct;
 
 /*
@@ -171,6 +175,11 @@ struct paca_struct {
 	 */
 	u16 in_mce;
 	u8 hmi_event_available;		 /* HMI event is available */
+	/*
+	 * Bitmap for sibling subcore status. See kvm/book3s_hv_ras.c for
+	 * more details
+	 */
+	struct sibling_subcore_state *sibling_subcore_state;
 #endif
 
 	/* Stuff for accurate time accounting */
--- zfcpdump-kernel-4.4.orig/arch/powerpc/include/asm/pci-bridge.h
+++ zfcpdump-kernel-4.4/arch/powerpc/include/asm/pci-bridge.h
@@ -205,6 +205,7 @@ struct pci_dn {
 
 	int	pci_ext_config_space;	/* for pci devices */
 
+	struct	pci_dev *pcidev;	/* back-pointer to the pci device */
 #ifdef CONFIG_EEH
 	struct eeh_dev *edev;		/* eeh device */
 #endif
@@ -295,6 +296,7 @@ extern void pci_process_bridge_OF_ranges
 /* Allocate & free a PCI host bridge structure */
 extern struct pci_controller *pcibios_alloc_controller(struct device_node *dev);
 extern void pcibios_free_controller(struct pci_controller *phb);
+extern void pcibios_free_controller_deferred(struct pci_host_bridge *bridge);
 
 #ifdef CONFIG_PCI
 extern int pcibios_vaddr_is_ioport(void __iomem *address);
--- zfcpdump-kernel-4.4.orig/arch/powerpc/include/asm/pci.h
+++ zfcpdump-kernel-4.4/arch/powerpc/include/asm/pci.h
@@ -149,4 +149,8 @@ extern void pcibios_setup_phb_io_space(s
 extern void pcibios_scan_phb(struct pci_controller *hose);
 
 #endif	/* __KERNEL__ */
+
+extern struct pci_dev *pnv_pci_get_gpu_dev(struct pci_dev *npdev);
+extern struct pci_dev *pnv_pci_get_npu_dev(struct pci_dev *gpdev, int index);
+
 #endif /* __ASM_POWERPC_PCI_H */
--- zfcpdump-kernel-4.4.orig/arch/powerpc/include/asm/perf_event_server.h
+++ zfcpdump-kernel-4.4/arch/powerpc/include/asm/perf_event_server.h
@@ -136,16 +136,24 @@ extern ssize_t power_events_sysfs_show(s
  * event 'cpu-cycles' can have two entries in sysfs: 'cpu-cycles' and
  * 'PM_CYC' where the latter is the name by which the event is known in
  * POWER CPU specification.
+ *
+ * Similarly, some hardware and cache events use the same event code. Eg.
+ * on POWER8, both "cache-references" and "L1-dcache-loads" events refer
+ * to the same event, PM_LD_REF_L1.  The suffix, allows us to have two
+ * sysfs objects for the same event and thus two entries/aliases in sysfs.
  */
 #define	EVENT_VAR(_id, _suffix)		event_attr_##_id##_suffix
 #define	EVENT_PTR(_id, _suffix)		&EVENT_VAR(_id, _suffix).attr.attr
 
 #define	EVENT_ATTR(_name, _id, _suffix)					\
-	PMU_EVENT_ATTR(_name, EVENT_VAR(_id, _suffix), PME_##_id,	\
+	PMU_EVENT_ATTR(_name, EVENT_VAR(_id, _suffix), _id,		\
 			power_events_sysfs_show)
 
 #define	GENERIC_EVENT_ATTR(_name, _id)	EVENT_ATTR(_name, _id, _g)
 #define	GENERIC_EVENT_PTR(_id)		EVENT_PTR(_id, _g)
 
+#define	CACHE_EVENT_ATTR(_name, _id)	EVENT_ATTR(_name, _id, _c)
+#define	CACHE_EVENT_PTR(_id)		EVENT_PTR(_id, _c)
+
 #define	POWER_EVENT_ATTR(_name, _id)	EVENT_ATTR(_name, _id, _p)
 #define	POWER_EVENT_PTR(_id)		EVENT_PTR(_id, _p)
--- zfcpdump-kernel-4.4.orig/arch/powerpc/include/asm/reg.h
+++ zfcpdump-kernel-4.4/arch/powerpc/include/asm/reg.h
@@ -707,7 +707,7 @@
 #define   MMCR0_FCWAIT	0x00000002UL /* freeze counter in WAIT state */
 #define   MMCR0_FCHV	0x00000001UL /* freeze conditions in hypervisor mode */
 #define SPRN_MMCR1	798
-#define SPRN_MMCR2	769
+#define SPRN_MMCR2	785
 #define SPRN_MMCRA	0x312
 #define   MMCRA_SDSYNC	0x80000000UL /* SDAR synced with SIAR */
 #define   MMCRA_SDAR_DCACHE_MISS 0x40000000UL
@@ -744,13 +744,13 @@
 #define SPRN_PMC6	792
 #define SPRN_PMC7	793
 #define SPRN_PMC8	794
-#define SPRN_SIAR	780
-#define SPRN_SDAR	781
 #define SPRN_SIER	784
 #define   SIER_SIPR		0x2000000	/* Sampled MSR_PR */
 #define   SIER_SIHV		0x1000000	/* Sampled MSR_HV */
 #define   SIER_SIAR_VALID	0x0400000	/* SIAR contents valid */
 #define   SIER_SDAR_VALID	0x0200000	/* SDAR contents valid */
+#define SPRN_SIAR	796
+#define SPRN_SDAR	797
 #define SPRN_TACR	888
 #define SPRN_TCSCR	889
 #define SPRN_CSIGR	890
@@ -1174,6 +1174,7 @@
 #define PVR_970GX	0x0045
 #define PVR_POWER7p	0x004A
 #define PVR_POWER8E	0x004B
+#define PVR_POWER8NVL	0x004C
 #define PVR_POWER8	0x004D
 #define PVR_BE		0x0070
 #define PVR_PA6T	0x0090
--- zfcpdump-kernel-4.4.orig/arch/powerpc/include/asm/smp.h
+++ zfcpdump-kernel-4.4/arch/powerpc/include/asm/smp.h
@@ -30,6 +30,7 @@
 #include <asm/percpu.h>
 
 extern int boot_cpuid;
+extern int boot_hw_cpuid;
 extern int spinning_secondaries;
 
 extern void cpu_die(void);
--- zfcpdump-kernel-4.4.orig/arch/powerpc/include/asm/switch_to.h
+++ zfcpdump-kernel-4.4/arch/powerpc/include/asm/switch_to.h
@@ -46,6 +46,11 @@ static inline void discard_lazy_cpu_stat
 }
 #endif
 
+static inline void disable_kernel_fp(void) { }
+static inline void disable_kernel_altivec(void) { }
+static inline void disable_kernel_spe(void) { }
+static inline void disable_kernel_vsx(void) { }
+
 #ifdef CONFIG_PPC_FPU
 extern void flush_fp_to_thread(struct task_struct *);
 extern void giveup_fpu(struct task_struct *);
--- zfcpdump-kernel-4.4.orig/arch/powerpc/include/asm/synch.h
+++ zfcpdump-kernel-4.4/arch/powerpc/include/asm/synch.h
@@ -44,7 +44,7 @@ static inline void isync(void)
 	MAKE_LWSYNC_SECTION_ENTRY(97, __lwsync_fixup);
 #define PPC_ACQUIRE_BARRIER	 "\n" stringify_in_c(__PPC_ACQUIRE_BARRIER)
 #define PPC_RELEASE_BARRIER	 stringify_in_c(LWSYNC) "\n"
-#define PPC_ATOMIC_ENTRY_BARRIER "\n" stringify_in_c(LWSYNC) "\n"
+#define PPC_ATOMIC_ENTRY_BARRIER "\n" stringify_in_c(sync) "\n"
 #define PPC_ATOMIC_EXIT_BARRIER	 "\n" stringify_in_c(sync) "\n"
 #else
 #define PPC_ACQUIRE_BARRIER
--- zfcpdump-kernel-4.4.orig/arch/powerpc/include/asm/uaccess.h
+++ zfcpdump-kernel-4.4/arch/powerpc/include/asm/uaccess.h
@@ -323,30 +323,17 @@ extern unsigned long __copy_tofrom_user(
 static inline unsigned long copy_from_user(void *to,
 		const void __user *from, unsigned long n)
 {
-	unsigned long over;
-
-	if (access_ok(VERIFY_READ, from, n))
+	if (likely(access_ok(VERIFY_READ, from, n)))
 		return __copy_tofrom_user((__force void __user *)to, from, n);
-	if ((unsigned long)from < TASK_SIZE) {
-		over = (unsigned long)from + n - TASK_SIZE;
-		return __copy_tofrom_user((__force void __user *)to, from,
-				n - over) + over;
-	}
+	memset(to, 0, n);
 	return n;
 }
 
 static inline unsigned long copy_to_user(void __user *to,
 		const void *from, unsigned long n)
 {
-	unsigned long over;
-
 	if (access_ok(VERIFY_WRITE, to, n))
 		return __copy_tofrom_user(to, (__force void __user *)from, n);
-	if ((unsigned long)to < TASK_SIZE) {
-		over = (unsigned long)to + n - TASK_SIZE;
-		return __copy_tofrom_user(to, (__force void __user *)from,
-				n - over) + over;
-	}
 	return n;
 }
 
@@ -437,10 +424,6 @@ static inline unsigned long clear_user(v
 	might_fault();
 	if (likely(access_ok(VERIFY_WRITE, addr, size)))
 		return __clear_user(addr, size);
-	if ((unsigned long)addr < TASK_SIZE) {
-		unsigned long over = (unsigned long)addr + size - TASK_SIZE;
-		return __clear_user(addr, size - over) + over;
-	}
 	return size;
 }
 
--- zfcpdump-kernel-4.4.orig/arch/powerpc/include/asm/word-at-a-time.h
+++ zfcpdump-kernel-4.4/arch/powerpc/include/asm/word-at-a-time.h
@@ -82,7 +82,7 @@ static inline unsigned long create_zero_
 	    "andc	%1,%1,%2\n\t"
 	    "popcntd	%0,%1"
 		: "=r" (leading_zero_bits), "=&r" (trailing_zero_bit_mask)
-		: "r" (bits));
+		: "b" (bits));
 
 	return leading_zero_bits;
 }
--- zfcpdump-kernel-4.4.orig/arch/powerpc/include/uapi/asm/cputable.h
+++ zfcpdump-kernel-4.4/arch/powerpc/include/uapi/asm/cputable.h
@@ -31,6 +31,7 @@
 #define PPC_FEATURE_PSERIES_PERFMON_COMPAT \
 					0x00000040
 
+/* Reserved - do not use		0x00000004 */
 #define PPC_FEATURE_TRUE_LE		0x00000002
 #define PPC_FEATURE_PPC_LE		0x00000001
 
--- zfcpdump-kernel-4.4.orig/arch/powerpc/include/uapi/asm/elf.h
+++ zfcpdump-kernel-4.4/arch/powerpc/include/uapi/asm/elf.h
@@ -295,6 +295,8 @@ do {									\
 #define R_PPC64_TLSLD		108
 #define R_PPC64_TOCSAVE		109
 
+#define R_PPC64_ENTRY		118
+
 #define R_PPC64_REL16		249
 #define R_PPC64_REL16_LO	250
 #define R_PPC64_REL16_HI	251
--- zfcpdump-kernel-4.4.orig/arch/powerpc/kernel/Makefile
+++ zfcpdump-kernel-4.4/arch/powerpc/kernel/Makefile
@@ -41,7 +41,7 @@ obj-$(CONFIG_VDSO32)		+= vdso32/
 obj-$(CONFIG_HAVE_HW_BREAKPOINT)	+= hw_breakpoint.o
 obj-$(CONFIG_PPC_BOOK3S_64)	+= cpu_setup_ppc970.o cpu_setup_pa6t.o
 obj-$(CONFIG_PPC_BOOK3S_64)	+= cpu_setup_power.o
-obj-$(CONFIG_PPC_BOOK3S_64)	+= mce.o mce_power.o
+obj-$(CONFIG_PPC_BOOK3S_64)	+= mce.o mce_power.o hmi.o
 obj64-$(CONFIG_RELOCATABLE)	+= reloc_64.o
 obj-$(CONFIG_PPC_BOOK3E_64)	+= exceptions-64e.o idle_book3e.o
 obj-$(CONFIG_PPC64)		+= vdso64/
--- zfcpdump-kernel-4.4.orig/arch/powerpc/kernel/align.c
+++ zfcpdump-kernel-4.4/arch/powerpc/kernel/align.c
@@ -960,6 +960,7 @@ int fix_alignment(struct pt_regs *regs)
 			preempt_disable();
 			enable_kernel_fp();
 			cvt_df(&data.dd, (float *)&data.x32.low32);
+			disable_kernel_fp();
 			preempt_enable();
 #else
 			return 0;
@@ -1000,6 +1001,7 @@ int fix_alignment(struct pt_regs *regs)
 		preempt_disable();
 		enable_kernel_fp();
 		cvt_fd((float *)&data.x32.low32, &data.dd);
+		disable_kernel_fp();
 		preempt_enable();
 #else
 		return 0;
--- zfcpdump-kernel-4.4.orig/arch/powerpc/kernel/eeh.c
+++ zfcpdump-kernel-4.4/arch/powerpc/kernel/eeh.c
@@ -677,7 +677,7 @@ int eeh_pci_enable(struct eeh_pe *pe, in
 	/* Check if the request is finished successfully */
 	if (active_flag) {
 		rc = eeh_ops->wait_state(pe, PCI_BUS_RESET_WAIT_MSEC);
-		if (rc <= 0)
+		if (rc < 0)
 			return rc;
 
 		if (rc & active_flag)
@@ -1072,7 +1072,7 @@ void eeh_add_device_early(struct pci_dn
 	struct pci_controller *phb;
 	struct eeh_dev *edev = pdn_to_eeh_dev(pdn);
 
-	if (!edev || !eeh_enabled())
+	if (!edev)
 		return;
 
 	if (!eeh_has_flag(EEH_PROBE_MODE_DEVTREE))
--- zfcpdump-kernel-4.4.orig/arch/powerpc/kernel/eeh_driver.c
+++ zfcpdump-kernel-4.4/arch/powerpc/kernel/eeh_driver.c
@@ -166,6 +166,16 @@ static void *eeh_dev_save_state(void *da
 	if (!edev)
 		return NULL;
 
+	/*
+	 * We cannot access the config space on some adapters.
+	 * Otherwise, it will cause fenced PHB. We don't save
+	 * the content in their config space and will restore
+	 * from the initial config space saved when the EEH
+	 * device is created.
+	 */
+	if (edev->pe && (edev->pe->state & EEH_PE_CFG_RESTRICTED))
+		return NULL;
+
 	pdev = eeh_dev_to_pci_dev(edev);
 	if (!pdev)
 		return NULL;
@@ -305,6 +315,19 @@ static void *eeh_dev_restore_state(void
 	if (!edev)
 		return NULL;
 
+	/*
+	 * The content in the config space isn't saved because
+	 * the blocked config space on some adapters. We have
+	 * to restore the initial saved config space when the
+	 * EEH device is created.
+	 */
+	if (edev->pe && (edev->pe->state & EEH_PE_CFG_RESTRICTED)) {
+		if (list_is_last(&edev->list, &edev->pe->edevs))
+			eeh_pe_restore_bars(edev->pe);
+
+		return NULL;
+	}
+
 	pdev = eeh_dev_to_pci_dev(edev);
 	if (!pdev)
 		return NULL;
@@ -418,8 +441,7 @@ static void *eeh_rmv_device(void *data,
 		eeh_pcid_put(dev);
 		if (driver->err_handler &&
 		    driver->err_handler->error_detected &&
-		    driver->err_handler->slot_reset &&
-		    driver->err_handler->resume)
+		    driver->err_handler->slot_reset)
 			return NULL;
 	}
 
@@ -505,9 +527,6 @@ int eeh_pe_reset_and_recover(struct eeh_
 	/* Save states */
 	eeh_pe_dev_traverse(pe, eeh_dev_save_state, NULL);
 
-	/* Report error */
-	eeh_pe_dev_traverse(pe, eeh_report_error, &result);
-
 	/* Issue reset */
 	ret = eeh_reset_pe(pe);
 	if (ret) {
@@ -617,6 +636,7 @@ static int eeh_reset_device(struct eeh_p
 		ssleep(5);
 
 		eeh_pe_traverse(pe, eeh_pe_detach_dev, NULL);
+		eeh_pe_state_clear(pe, EEH_PE_PRI_BUS);
 		pcibios_add_pci_devices(frozen_bus);
 	}
 	eeh_pe_state_clear(pe, EEH_PE_KEEP);
@@ -803,6 +823,7 @@ perm_error:
 	 * the their PCI config any more.
 	 */
 	if (frozen_bus) {
+		eeh_pe_state_clear(pe, EEH_PE_PRI_BUS);
 		eeh_pe_dev_mode_mark(pe, EEH_DEV_REMOVED);
 
 		pci_lock_rescan_remove();
@@ -886,6 +907,7 @@ static void eeh_handle_special_event(voi
 					continue;
 
 				/* Notify all devices to be down */
+				eeh_pe_state_clear(pe, EEH_PE_PRI_BUS);
 				bus = eeh_pe_bus_get(phb_pe);
 				eeh_pe_dev_traverse(pe,
 					eeh_report_failure, NULL);
--- zfcpdump-kernel-4.4.orig/arch/powerpc/kernel/eeh_pe.c
+++ zfcpdump-kernel-4.4/arch/powerpc/kernel/eeh_pe.c
@@ -883,32 +883,29 @@ void eeh_pe_restore_bars(struct eeh_pe *
 const char *eeh_pe_loc_get(struct eeh_pe *pe)
 {
 	struct pci_bus *bus = eeh_pe_bus_get(pe);
-	struct device_node *dn = pci_bus_to_OF_node(bus);
+	struct device_node *dn;
 	const char *loc = NULL;
 
-	if (!dn)
-		goto out;
+	while (bus) {
+		dn = pci_bus_to_OF_node(bus);
+		if (!dn) {
+			bus = bus->parent;
+			continue;
+		}
 
-	/* PHB PE or root PE ? */
-	if (pci_is_root_bus(bus)) {
-		loc = of_get_property(dn, "ibm,loc-code", NULL);
-		if (!loc)
+		if (pci_is_root_bus(bus))
 			loc = of_get_property(dn, "ibm,io-base-loc-code", NULL);
+		else
+			loc = of_get_property(dn, "ibm,slot-location-code",
+					      NULL);
+
 		if (loc)
-			goto out;
+			return loc;
 
-		/* Check the root port */
-		dn = dn->child;
-		if (!dn)
-			goto out;
+		bus = bus->parent;
 	}
 
-	loc = of_get_property(dn, "ibm,loc-code", NULL);
-	if (!loc)
-		loc = of_get_property(dn, "ibm,slot-location-code", NULL);
-
-out:
-	return loc ? loc : "N/A";
+	return "N/A";
 }
 
 /**
@@ -931,7 +928,7 @@ struct pci_bus *eeh_pe_bus_get(struct ee
 		bus = pe->phb->bus;
 	} else if (pe->type & EEH_PE_BUS ||
 		   pe->type & EEH_PE_DEVICE) {
-		if (pe->bus) {
+		if (pe->state & EEH_PE_PRI_BUS) {
 			bus = pe->bus;
 			goto out;
 		}
--- zfcpdump-kernel-4.4.orig/arch/powerpc/kernel/entry_64.S
+++ zfcpdump-kernel-4.4/arch/powerpc/kernel/entry_64.S
@@ -334,13 +334,13 @@ syscall_exit_work:
 tabort_syscall:
 	/* Firstly we need to enable TM in the kernel */
 	mfmsr	r10
-	li	r13, 1
-	rldimi	r10, r13, MSR_TM_LG, 63-MSR_TM_LG
+	li	r9, 1
+	rldimi	r10, r9, MSR_TM_LG, 63-MSR_TM_LG
 	mtmsrd	r10, 0
 
 	/* tabort, this dooms the transaction, nothing else */
-	li	r13, (TM_CAUSE_SYSCALL|TM_CAUSE_PERSISTENT)
-	TABORT(R13)
+	li	r9, (TM_CAUSE_SYSCALL|TM_CAUSE_PERSISTENT)
+	TABORT(R9)
 
 	/*
 	 * Return directly to userspace. We have corrupted user register state,
@@ -348,8 +348,8 @@ tabort_syscall:
 	 * resume after the tbegin of the aborted transaction with the
 	 * checkpointed register state.
 	 */
-	li	r13, MSR_RI
-	andc	r10, r10, r13
+	li	r9, MSR_RI
+	andc	r10, r10, r9
 	mtmsrd	r10, 1
 	mtspr	SPRN_SRR0, r11
 	mtspr	SPRN_SRR1, r12
--- zfcpdump-kernel-4.4.orig/arch/powerpc/kernel/exceptions-64s.S
+++ zfcpdump-kernel-4.4/arch/powerpc/kernel/exceptions-64s.S
@@ -698,6 +698,8 @@ _GLOBAL(__replay_interrupt)
 BEGIN_FTR_SECTION
 	cmpwi	r3,0xe80
 	beq	h_doorbell_common
+	cmpwi	r3,0xe60
+	beq	hmi_exception_common
 FTR_SECTION_ELSE
 	cmpwi	r3,0xa00
 	beq	doorbell_super_common
@@ -962,11 +964,6 @@ hv_facility_unavailable_relon_trampoline
 #endif
 	STD_RELON_EXCEPTION_PSERIES(0x5700, 0x1700, altivec_assist)
 
-	/* Other future vectors */
-	.align	7
-	.globl	__end_interrupts
-__end_interrupts:
-
 	.align	7
 system_call_entry:
 	b	system_call_common
@@ -1253,6 +1250,17 @@ __end_handlers:
 	STD_RELON_EXCEPTION_PSERIES_OOL(0xf60, facility_unavailable)
 	STD_RELON_EXCEPTION_HV_OOL(0xf80, hv_facility_unavailable)
 
+	/*
+	 * The __end_interrupts marker must be past the out-of-line (OOL)
+	 * handlers, so that they are copied to real address 0x100 when running
+	 * a relocatable kernel. This ensures they can be reached from the short
+	 * trampoline handlers (like 0x4f00, 0x4f20, etc.) which branch
+	 * directly, without using LOAD_HANDLER().
+	 */
+	.align	7
+	.globl	__end_interrupts
+__end_interrupts:
+
 #if defined(CONFIG_PPC_PSERIES) || defined(CONFIG_PPC_POWERNV)
 /*
  * Data area reserved for FWNMI option.
@@ -1270,7 +1278,7 @@ fwnmi_data_area:
 
 	.globl hmi_exception_early
 hmi_exception_early:
-	EXCEPTION_PROLOG_1(PACA_EXGEN, NOTEST, 0xe60)
+	EXCEPTION_PROLOG_1(PACA_EXGEN, KVMTEST, 0xe62)
 	mr	r10,r1			/* Save r1			*/
 	ld	r1,PACAEMERGSP(r13)	/* Use emergency stack		*/
 	subi	r1,r1,INT_FRAME_SIZE	/* alloc stack frame		*/
--- /dev/null
+++ zfcpdump-kernel-4.4/arch/powerpc/kernel/hmi.c
@@ -0,0 +1,56 @@
+/*
+ * Hypervisor Maintenance Interrupt (HMI) handling.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.
+ *
+ * Copyright 2015 IBM Corporation
+ * Author: Mahesh Salgaonkar <mahesh@linux.vnet.ibm.com>
+ */
+
+#undef DEBUG
+
+#include <linux/types.h>
+#include <linux/compiler.h>
+#include <asm/paca.h>
+#include <asm/hmi.h>
+
+void wait_for_subcore_guest_exit(void)
+{
+	int i;
+
+	/*
+	 * NULL bitmap pointer indicates that KVM module hasn't
+	 * been loaded yet and hence no guests are running.
+	 * If no KVM is in use, no need to co-ordinate among threads
+	 * as all of them will always be in host and no one is going
+	 * to modify TB other than the opal hmi handler.
+	 * Hence, just return from here.
+	 */
+	if (!local_paca->sibling_subcore_state)
+		return;
+
+	for (i = 0; i < MAX_SUBCORE_PER_CORE; i++)
+		while (local_paca->sibling_subcore_state->in_guest[i])
+			cpu_relax();
+}
+
+void wait_for_tb_resync(void)
+{
+	if (!local_paca->sibling_subcore_state)
+		return;
+
+	while (test_bit(CORE_TB_RESYNC_REQ_BIT,
+				&local_paca->sibling_subcore_state->flags))
+		cpu_relax();
+}
--- zfcpdump-kernel-4.4.orig/arch/powerpc/kernel/idle_power7.S
+++ zfcpdump-kernel-4.4/arch/powerpc/kernel/idle_power7.S
@@ -277,8 +277,9 @@ ALT_FTR_SECTION_END_NESTED_IFSET(CPU_FTR
 	ld	r2,PACATOC(r13);					\
 	ld	r1,PACAR1(r13);						\
 	std	r3,ORIG_GPR3(r1);	/* Save original r3 */		\
-	li	r0,OPAL_HANDLE_HMI;	/* Pass opal token argument*/	\
-	bl	opal_call_realmode;					\
+	li	r3,0;			/* NULL argument */		\
+	bl	hmi_exception_realmode;					\
+	nop;								\
 	ld	r3,ORIG_GPR3(r1);	/* Restore original r3 */	\
 20:	nop;
 
--- zfcpdump-kernel-4.4.orig/arch/powerpc/kernel/module_32.c
+++ zfcpdump-kernel-4.4/arch/powerpc/kernel/module_32.c
@@ -188,8 +188,8 @@ static uint32_t do_plt_call(void *locati
 
 	pr_debug("Doing plt for call to 0x%x at 0x%x\n", val, (unsigned int)location);
 	/* Init, or core PLT? */
-	if (location >= mod->module_core
-	    && location < mod->module_core + mod->core_size)
+	if (location >= mod->core_layout.base
+	    && location < mod->core_layout.base + mod->core_layout.size)
 		entry = (void *)sechdrs[mod->arch.core_plt_section].sh_addr;
 	else
 		entry = (void *)sechdrs[mod->arch.init_plt_section].sh_addr;
@@ -296,7 +296,7 @@ int apply_relocate_add(Elf32_Shdr *sechd
 	}
 #ifdef CONFIG_DYNAMIC_FTRACE
 	module->arch.tramp =
-		do_plt_call(module->module_core,
+		do_plt_call(module->core_layout.base,
 			    (unsigned long)ftrace_caller,
 			    sechdrs, module);
 #endif
--- zfcpdump-kernel-4.4.orig/arch/powerpc/kernel/module_64.c
+++ zfcpdump-kernel-4.4/arch/powerpc/kernel/module_64.c
@@ -335,7 +335,7 @@ static void dedotify(Elf64_Sym *syms, un
 		if (syms[i].st_shndx == SHN_UNDEF) {
 			char *name = strtab + syms[i].st_name;
 			if (name[0] == '.')
-				memmove(name, name+1, strlen(name));
+				syms[i].st_name++;
 		}
 	}
 }
@@ -635,6 +635,33 @@ int apply_relocate_add(Elf64_Shdr *sechd
 			 */
 			break;
 
+		case R_PPC64_ENTRY:
+			/*
+			 * Optimize ELFv2 large code model entry point if
+			 * the TOC is within 2GB range of current location.
+			 */
+			value = my_r2(sechdrs, me) - (unsigned long)location;
+			if (value + 0x80008000 > 0xffffffff)
+				break;
+			/*
+			 * Check for the large code model prolog sequence:
+		         *	ld r2, ...(r12)
+			 *	add r2, r2, r12
+			 */
+			if ((((uint32_t *)location)[0] & ~0xfffc)
+			    != 0xe84c0000)
+				break;
+			if (((uint32_t *)location)[1] != 0x7c426214)
+				break;
+			/*
+			 * If found, replace it with:
+			 *	addis r2, r12, (.TOC.-func)@ha
+			 *	addi r2, r12, (.TOC.-func)@l
+			 */
+			((uint32_t *)location)[0] = 0x3c4c0000 + PPC_HA(value);
+			((uint32_t *)location)[1] = 0x38420000 + PPC_LO(value);
+			break;
+
 		case R_PPC64_REL16_HA:
 			/* Subtract location pointer */
 			value -= (unsigned long)location;
--- zfcpdump-kernel-4.4.orig/arch/powerpc/kernel/paca.c
+++ zfcpdump-kernel-4.4/arch/powerpc/kernel/paca.c
@@ -206,6 +206,7 @@ void __init allocate_pacas(void)
 {
 	u64 limit;
 	int cpu;
+	int nr_cpus;
 
 	limit = ppc64_rma_size;
 
@@ -218,20 +219,32 @@ void __init allocate_pacas(void)
 	limit = min(0x10000000ULL, limit);
 #endif
 
-	paca_size = PAGE_ALIGN(sizeof(struct paca_struct) * nr_cpu_ids);
+	/*
+	 * Always align up the nr_cpu_ids to SMT threads and allocate
+	 * the paca. This will help us to prepare for a situation where
+	 * boot cpu id > nr_cpus_id. We will use the last nthreads
+	 * slots (nthreads == threads per core) to accommodate a core
+	 * that contains boot cpu thread.
+	 *
+	 * Do not change nr_cpu_ids value here. Let us do that in
+	 * early_init_dt_scan_cpus() where we know exact value
+	 * of threads per core.
+	 */
+	nr_cpus = _ALIGN_UP(nr_cpu_ids, MAX_SMT);
+	paca_size = PAGE_ALIGN(sizeof(struct paca_struct) * nr_cpus);
 
 	paca = __va(memblock_alloc_base(paca_size, PAGE_SIZE, limit));
 	memset(paca, 0, paca_size);
 
 	printk(KERN_DEBUG "Allocated %u bytes for %d pacas at %p\n",
-		paca_size, nr_cpu_ids, paca);
+		paca_size, nr_cpus, paca);
 
-	allocate_lppacas(nr_cpu_ids, limit);
+	allocate_lppacas(nr_cpus, limit);
 
-	allocate_slb_shadows(nr_cpu_ids, limit);
+	allocate_slb_shadows(nr_cpus, limit);
 
 	/* Can't use for_each_*_cpu, as they aren't functional yet */
-	for (cpu = 0; cpu < nr_cpu_ids; cpu++)
+	for (cpu = 0; cpu < nr_cpus; cpu++)
 		initialise_paca(&paca[cpu], cpu);
 }
 
--- zfcpdump-kernel-4.4.orig/arch/powerpc/kernel/pci-common.c
+++ zfcpdump-kernel-4.4/arch/powerpc/kernel/pci-common.c
@@ -41,11 +41,18 @@
 #include <asm/ppc-pci.h>
 #include <asm/eeh.h>
 
+/* hose_spinlock protects accesses to the the phb_bitmap. */
 static DEFINE_SPINLOCK(hose_spinlock);
 LIST_HEAD(hose_list);
 
-/* XXX kill that some day ... */
-static int global_phb_number;		/* Global phb counter */
+/* For dynamic PHB numbering on get_phb_number(): max number of PHBs. */
+#define MAX_PHBS 0x10000
+
+/*
+ * For dynamic PHB numbering: used/free PHBs tracking bitmap.
+ * Accesses to this bitmap should be protected by hose_spinlock.
+ */
+static DECLARE_BITMAP(phb_bitmap, MAX_PHBS);
 
 /* ISA Memory physical address */
 resource_size_t isa_mem_base;
@@ -64,6 +71,42 @@ struct dma_map_ops *get_pci_dma_ops(void
 }
 EXPORT_SYMBOL(get_pci_dma_ops);
 
+/*
+ * This function should run under locking protection, specifically
+ * hose_spinlock.
+ */
+static int get_phb_number(struct device_node *dn)
+{
+	int ret, phb_id = -1;
+	u64 prop;
+
+	/*
+	 * Try fixed PHB numbering first, by checking archs and reading
+	 * the respective device-tree properties. Firstly, try powernv by
+	 * reading "ibm,opal-phbid", only present in OPAL environment.
+	 */
+	ret = of_property_read_u64(dn, "ibm,opal-phbid", &prop);
+	if (ret)
+		ret = of_property_read_u32_index(dn, "reg", 1, (u32 *)&prop);
+
+	if (!ret)
+		phb_id = (int)(prop & (MAX_PHBS - 1));
+
+	/* We need to be sure to not use the same PHB number twice. */
+	if ((phb_id >= 0) && !test_and_set_bit(phb_id, phb_bitmap))
+		return phb_id;
+
+	/*
+	 * If not pseries nor powernv, or if fixed PHB numbering tried to add
+	 * the same PHB number twice, then fallback to dynamic PHB numbering.
+	 */
+	phb_id = find_first_zero_bit(phb_bitmap, MAX_PHBS);
+	BUG_ON(phb_id >= MAX_PHBS);
+	set_bit(phb_id, phb_bitmap);
+
+	return phb_id;
+}
+
 struct pci_controller *pcibios_alloc_controller(struct device_node *dev)
 {
 	struct pci_controller *phb;
@@ -72,7 +115,7 @@ struct pci_controller *pcibios_alloc_con
 	if (phb == NULL)
 		return NULL;
 	spin_lock(&hose_spinlock);
-	phb->global_number = global_phb_number++;
+	phb->global_number = get_phb_number(dev);
 	list_add_tail(&phb->list_node, &hose_list);
 	spin_unlock(&hose_spinlock);
 	phb->dn = dev;
@@ -94,6 +137,11 @@ EXPORT_SYMBOL_GPL(pcibios_alloc_controll
 void pcibios_free_controller(struct pci_controller *phb)
 {
 	spin_lock(&hose_spinlock);
+
+	/* Clear bit of phb_bitmap to allow reuse of this PHB number. */
+	if (phb->global_number < MAX_PHBS)
+		clear_bit(phb->global_number, phb_bitmap);
+
 	list_del(&phb->list_node);
 	spin_unlock(&hose_spinlock);
 
@@ -103,6 +151,42 @@ void pcibios_free_controller(struct pci_
 EXPORT_SYMBOL_GPL(pcibios_free_controller);
 
 /*
+ * This function is used to call pcibios_free_controller()
+ * in a deferred manner: a callback from the PCI subsystem.
+ *
+ * _*DO NOT*_ call pcibios_free_controller() explicitly if
+ * this is used (or it may access an invalid *phb pointer).
+ *
+ * The callback occurs when all references to the root bus
+ * are dropped (e.g., child buses/devices and their users).
+ *
+ * It's called as .release_fn() of 'struct pci_host_bridge'
+ * which is associated with the 'struct pci_controller.bus'
+ * (root bus) - it expects .release_data to hold a pointer
+ * to 'struct pci_controller'.
+ *
+ * In order to use it, register .release_fn()/release_data
+ * like this:
+ *
+ * pci_set_host_bridge_release(bridge,
+ *                             pcibios_free_controller_deferred
+ *                             (void *) phb);
+ *
+ * e.g. in the pcibios_root_bridge_prepare() callback from
+ * pci_create_root_bus().
+ */
+void pcibios_free_controller_deferred(struct pci_host_bridge *bridge)
+{
+	struct pci_controller *phb = (struct pci_controller *)
+					 bridge->release_data;
+
+	pr_debug("domain %d, dynamic %d\n", phb->global_number, phb->is_dynamic);
+
+	pcibios_free_controller(phb);
+}
+EXPORT_SYMBOL_GPL(pcibios_free_controller_deferred);
+
+/*
  * The function is used to return the minimal alignment
  * for memory or I/O windows of the associated P2P bridge.
  * By default, 4KiB alignment for I/O windows and 1MiB for
@@ -226,6 +310,7 @@ struct pci_controller* pci_find_hose_for
 	}
 	return NULL;
 }
+EXPORT_SYMBOL(pci_find_hose_for_OF_device);
 
 /*
  * Reads the interrupt pin to determine if interrupt is use by card.
@@ -1469,9 +1554,15 @@ void pcibios_disable_device(struct pci_d
 		phb->controller_ops.disable_device(dev);
 }
 
+/* Before assuming too much here, take care to realize that we need sign
+ * extension from 32-bit pointers to 64-bit resource addresses to work.
+ */
 resource_size_t pcibios_io_space_offset(struct pci_controller *hose)
 {
-	return (unsigned long) hose->io_base_virt - _IO_BASE;
+	long vbase = (long)hose->io_base_virt;
+	long io_base = _IO_BASE;
+
+	return (resource_size_t)(vbase - io_base);
 }
 
 static void pcibios_setup_phb_resources(struct pci_controller *hose,
@@ -1585,6 +1676,7 @@ int early_find_capability(struct pci_con
 {
 	return pci_bus_find_capability(fake_pci_bus(hose, bus), devfn, cap);
 }
+EXPORT_SYMBOL_GPL(early_find_capability);
 
 struct device_node *pcibios_get_phb_of_node(struct pci_bus *bus)
 {
--- zfcpdump-kernel-4.4.orig/arch/powerpc/kernel/process.c
+++ zfcpdump-kernel-4.4/arch/powerpc/kernel/process.c
@@ -1239,6 +1239,16 @@ void start_thread(struct pt_regs *regs,
 		current->thread.regs = regs - 1;
 	}
 
+#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
+	/*
+	 * Clear any transactional state, we're exec()ing. The cause is
+	 * not important as there will never be a recheckpoint so it's not
+	 * user visible.
+	 */
+	if (MSR_TM_SUSPENDED(mfmsr()))
+		tm_reclaim_current(0);
+#endif
+
 	memset(regs->gpr, 0, sizeof(regs->gpr));
 	regs->ctr = 0;
 	regs->link = 0;
--- zfcpdump-kernel-4.4.orig/arch/powerpc/kernel/prom.c
+++ zfcpdump-kernel-4.4/arch/powerpc/kernel/prom.c
@@ -148,23 +148,25 @@ static struct ibm_pa_feature {
 	unsigned long	cpu_features;	/* CPU_FTR_xxx bit */
 	unsigned long	mmu_features;	/* MMU_FTR_xxx bit */
 	unsigned int	cpu_user_ftrs;	/* PPC_FEATURE_xxx bit */
+	unsigned int	cpu_user_ftrs2;	/* PPC_FEATURE2_xxx bit */
 	unsigned char	pabyte;		/* byte number in ibm,pa-features */
 	unsigned char	pabit;		/* bit number (big-endian) */
 	unsigned char	invert;		/* if 1, pa bit set => clear feature */
 } ibm_pa_features[] __initdata = {
-	{0, 0, PPC_FEATURE_HAS_MMU,	0, 0, 0},
-	{0, 0, PPC_FEATURE_HAS_FPU,	0, 1, 0},
-	{CPU_FTR_CTRL, 0, 0,		0, 3, 0},
-	{CPU_FTR_NOEXECUTE, 0, 0,	0, 6, 0},
-	{CPU_FTR_NODSISRALIGN, 0, 0,	1, 1, 1},
-	{0, MMU_FTR_CI_LARGE_PAGE, 0,	1, 2, 0},
-	{CPU_FTR_REAL_LE, PPC_FEATURE_TRUE_LE, 5, 0, 0},
+	{0, 0, PPC_FEATURE_HAS_MMU, 0,		0, 0, 0},
+	{0, 0, PPC_FEATURE_HAS_FPU, 0,		0, 1, 0},
+	{CPU_FTR_CTRL, 0, 0, 0,			0, 3, 0},
+	{CPU_FTR_NOEXECUTE, 0, 0, 0,		0, 6, 0},
+	{CPU_FTR_NODSISRALIGN, 0, 0, 0,		1, 1, 1},
+	{0, MMU_FTR_CI_LARGE_PAGE, 0, 0,		1, 2, 0},
+	{CPU_FTR_REAL_LE, 0, PPC_FEATURE_TRUE_LE, 0, 5, 0, 0},
 	/*
-	 * If the kernel doesn't support TM (ie. CONFIG_PPC_TRANSACTIONAL_MEM=n),
-	 * we don't want to turn on CPU_FTR_TM here, so we use CPU_FTR_TM_COMP
-	 * which is 0 if the kernel doesn't support TM.
+	 * If the kernel doesn't support TM (ie CONFIG_PPC_TRANSACTIONAL_MEM=n),
+	 * we don't want to turn on TM here, so we use the *_COMP versions
+	 * which are 0 if the kernel doesn't support TM.
 	 */
-	{CPU_FTR_TM_COMP, 0, 0,		22, 0, 0},
+	{CPU_FTR_TM_COMP, 0, 0,
+	 PPC_FEATURE2_HTM_COMP|PPC_FEATURE2_HTM_NOSC_COMP, 22, 0, 0},
 };
 
 static void __init scan_features(unsigned long node, const unsigned char *ftrs,
@@ -195,10 +197,12 @@ static void __init scan_features(unsigne
 		if (bit ^ fp->invert) {
 			cur_cpu_spec->cpu_features |= fp->cpu_features;
 			cur_cpu_spec->cpu_user_features |= fp->cpu_user_ftrs;
+			cur_cpu_spec->cpu_user_features2 |= fp->cpu_user_ftrs2;
 			cur_cpu_spec->mmu_features |= fp->mmu_features;
 		} else {
 			cur_cpu_spec->cpu_features &= ~fp->cpu_features;
 			cur_cpu_spec->cpu_user_features &= ~fp->cpu_user_ftrs;
+			cur_cpu_spec->cpu_user_features2 &= ~fp->cpu_user_ftrs2;
 			cur_cpu_spec->mmu_features &= ~fp->mmu_features;
 		}
 	}
@@ -291,6 +295,29 @@ static void __init check_cpu_feature_pro
 	}
 }
 
+/*
+ * Adjust the logical id of a boot cpu to fall under nr_cpu_ids. Map it to
+ * last core slot in the allocated paca array.
+ *
+ * e.g. on SMT=8 system, kernel booted with nr_cpus=1 and boot cpu = 33,
+ * align nr_cpu_ids to MAX_SMT value 8. Allocate paca array to hold up-to
+ * MAX_SMT=8 cpus. Since boot cpu 33 is greater than nr_cpus (8), adjust
+ * its logical id so that new id becomes less than nr_cpu_ids. Make sure
+ * that boot cpu's new logical id is aligned to its thread id and falls
+ * under last nthreads slots available in paca array. In this case the
+ * boot cpu 33 is adjusted to new boot cpu id 1.
+ *
+ */
+static inline void adjust_boot_cpuid(int nthreads, int phys_id)
+{
+	boot_hw_cpuid = phys_id;
+	if (boot_cpuid >= nr_cpu_ids) {
+		boot_cpuid = (boot_cpuid % nthreads) + (nr_cpu_ids - nthreads);
+		pr_info("Adjusted logical boot cpu id: logical %d physical %d\n",
+			boot_cpuid, phys_id);
+	}
+}
+
 static int __init early_init_dt_scan_cpus(unsigned long node,
 					  const char *uname, int depth,
 					  void *data)
@@ -314,6 +341,18 @@ static int __init early_init_dt_scan_cpu
 
 	nthreads = len / sizeof(int);
 
+#ifdef CONFIG_SMP
+	/*
+	 * Now that we know threads per core lets align nr_cpu_ids to
+	 * correct SMT value.
+	 */
+	if (nr_cpu_ids % nthreads) {
+		nr_cpu_ids = _ALIGN_UP(nr_cpu_ids, nthreads);
+		pr_info("Aligned nr_cpus to SMT=%d, nr_cpu_ids = %d\n",
+				 nthreads, nr_cpu_ids);
+	}
+#endif
+
 	/*
 	 * Now see if any of these threads match our boot cpu.
 	 * NOTE: This must match the parsing done in smp_setup_cpu_maps.
@@ -352,7 +391,9 @@ static int __init early_init_dt_scan_cpu
 	DBG("boot cpu: logical %d physical %d\n", found,
 	    be32_to_cpu(intserv[found_thread]));
 	boot_cpuid = found;
-	set_hard_smp_processor_id(found, be32_to_cpu(intserv[found_thread]));
+	adjust_boot_cpuid(nthreads, be32_to_cpu(intserv[found_thread]));
+	set_hard_smp_processor_id(boot_cpuid,
+					be32_to_cpu(intserv[found_thread]));
 
 	/*
 	 * PAPR defines "logical" PVR values for cpus that
--- zfcpdump-kernel-4.4.orig/arch/powerpc/kernel/prom_init.c
+++ zfcpdump-kernel-4.4/arch/powerpc/kernel/prom_init.c
@@ -655,6 +655,7 @@ unsigned char ibm_architecture_vec[] = {
 	W(0xffff0000), W(0x003e0000),	/* POWER6 */
 	W(0xffff0000), W(0x003f0000),	/* POWER7 */
 	W(0xffff0000), W(0x004b0000),	/* POWER8E */
+	W(0xffff0000), W(0x004c0000),   /* POWER8NVL */
 	W(0xffff0000), W(0x004d0000),	/* POWER8 */
 	W(0xffffffff), W(0x0f000004),	/* all 2.07-compliant */
 	W(0xffffffff), W(0x0f000003),	/* all 2.06-compliant */
@@ -677,7 +678,7 @@ unsigned char ibm_architecture_vec[] = {
 	W(0xffffffff),			/* virt_base */
 	W(0xffffffff),			/* virt_size */
 	W(0xffffffff),			/* load_base */
-	W(256),				/* 256MB min RMA */
+	W(512),				/* 512MB min RMA */
 	W(0xffffffff),			/* full client load */
 	0,				/* min RMA percentage of total RAM */
 	48,				/* max log_2(hash table size) */
@@ -693,7 +694,7 @@ unsigned char ibm_architecture_vec[] = {
 	OV4_MIN_ENT_CAP,		/* minimum VP entitled capacity */
 
 	/* option vector 5: PAPR/OF options */
-	VECTOR_LENGTH(18),		/* length */
+	VECTOR_LENGTH(21),		/* length */
 	0,				/* don't ignore, don't halt */
 	OV5_FEAT(OV5_LPAR) | OV5_FEAT(OV5_SPLPAR) | OV5_FEAT(OV5_LARGE_PAGES) |
 	OV5_FEAT(OV5_DRCONF_MEMORY) | OV5_FEAT(OV5_DONATE_DEDICATE_CPU) |
@@ -717,15 +718,18 @@ unsigned char ibm_architecture_vec[] = {
 	 * must match by the macro below. Update the definition if
 	 * the structure layout changes.
 	 */
-#define IBM_ARCH_VEC_NRCORES_OFFSET	125
+#define IBM_ARCH_VEC_NRCORES_OFFSET	133
 	W(NR_CPUS),			/* number of cores supported */
 	0,
 	0,
 	0,
 	0,
 	OV5_FEAT(OV5_PFO_HW_RNG) | OV5_FEAT(OV5_PFO_HW_ENCR) |
-	OV5_FEAT(OV5_PFO_HW_842),
-	OV5_FEAT(OV5_SUB_PROCESSORS),
+	OV5_FEAT(OV5_PFO_HW_842),				/* Byte 17 */
+	0,							/* Byte 18 */
+	0,							/* Byte 19 */
+	0,							/* Byte 20 */
+	OV5_FEAT(OV5_SUB_PROCESSORS),				/* Byte 21 */
 
 	/* option vector 6: IBM PAPR hints */
 	VECTOR_LENGTH(3),		/* length */
--- zfcpdump-kernel-4.4.orig/arch/powerpc/kernel/setup-common.c
+++ zfcpdump-kernel-4.4/arch/powerpc/kernel/setup-common.c
@@ -77,6 +77,7 @@ struct machdep_calls *machine_id;
 EXPORT_SYMBOL(machine_id);
 
 int boot_cpuid = -1;
+int boot_hw_cpuid = -1;
 EXPORT_SYMBOL_GPL(boot_cpuid);
 
 unsigned long klimit = (unsigned long) _end;
@@ -444,6 +445,7 @@ void __init smp_setup_cpu_maps(void)
 	struct device_node *dn = NULL;
 	int cpu = 0;
 	int nthreads = 1;
+	bool boot_cpu_added = false;
 
 	DBG("smp_setup_cpu_maps()\n");
 
@@ -470,6 +472,24 @@ void __init smp_setup_cpu_maps(void)
 		}
 
 		nthreads = len / sizeof(int);
+		/*
+		 * If boot cpu hasn't been added to paca and there are only
+		 * last nthreads slots available in paca array then wait
+		 * for boot cpu to show up.
+		 */
+		if (!boot_cpu_added && (cpu + nthreads) >= nr_cpu_ids) {
+			int found = 0;
+
+			DBG("Holding last nthreads paca slots for boot cpu\n");
+			for (j = 0; j < nthreads && cpu < nr_cpu_ids; j++) {
+				if (boot_hw_cpuid == be32_to_cpu(intserv[j])) {
+					found = 1;
+					break;
+				}
+			}
+			if (!found)
+				continue;
+		}
 
 		for (j = 0; j < nthreads && cpu < nr_cpu_ids; j++) {
 			bool avail;
@@ -485,6 +505,11 @@ void __init smp_setup_cpu_maps(void)
 			set_cpu_present(cpu, avail);
 			set_hard_smp_processor_id(cpu, be32_to_cpu(intserv[j]));
 			set_cpu_possible(cpu, true);
+			if (boot_hw_cpuid == be32_to_cpu(intserv[j])) {
+				DBG("Boot cpu %d (hard id %d) added to paca\n",
+				    cpu, be32_to_cpu(intserv[j]));
+				boot_cpu_added = true;
+			}
 			cpu++;
 		}
 	}
--- zfcpdump-kernel-4.4.orig/arch/powerpc/kernel/tm.S
+++ zfcpdump-kernel-4.4/arch/powerpc/kernel/tm.S
@@ -110,17 +110,11 @@ _GLOBAL(tm_reclaim)
 	std	r3, STK_PARAM(R3)(r1)
 	SAVE_NVGPRS(r1)
 
-	/* We need to setup MSR for VSX register save instructions.  Here we
-	 * also clear the MSR RI since when we do the treclaim, we won't have a
-	 * valid kernel pointer for a while.  We clear RI here as it avoids
-	 * adding another mtmsr closer to the treclaim.  This makes the region
-	 * maked as non-recoverable wider than it needs to be but it saves on
-	 * inserting another mtmsrd later.
-	 */
+	/* We need to setup MSR for VSX register save instructions. */
 	mfmsr	r14
 	mr	r15, r14
 	ori	r15, r15, MSR_FP
-	li	r16, MSR_RI
+	li	r16, 0
 	ori	r16, r16, MSR_EE /* IRQs hard off */
 	andc	r15, r15, r16
 	oris	r15, r15, MSR_VEC@h
@@ -176,7 +170,17 @@ dont_backup_fp:
 1:	tdeqi   r6, 0
 	EMIT_BUG_ENTRY 1b,__FILE__,__LINE__,0
 
-	/* The moment we treclaim, ALL of our GPRs will switch
+	/* Clear MSR RI since we are about to change r1, EE is already off. */
+	li	r4, 0
+	mtmsrd	r4, 1
+
+	/*
+	 * BE CAREFUL HERE:
+	 * At this point we can't take an SLB miss since we have MSR_RI
+	 * off. Load only to/from the stack/paca which are in SLB bolted regions
+	 * until we turn MSR RI back on.
+	 *
+	 * The moment we treclaim, ALL of our GPRs will switch
 	 * to user register state.  (FPRs, CCR etc. also!)
 	 * Use an sprg and a tm_scratch in the PACA to shuffle.
 	 */
@@ -197,6 +201,11 @@ dont_backup_fp:
 
 	/* Store the PPR in r11 and reset to decent value */
 	std	r11, GPR11(r1)			/* Temporary stash */
+
+	/* Reset MSR RI so we can take SLB faults again */
+	li	r11, MSR_RI
+	mtmsrd	r11, 1
+
 	mfspr	r11, SPRN_PPR
 	HMT_MEDIUM
 
@@ -329,8 +338,6 @@ _GLOBAL(__tm_recheckpoint)
 	 */
 	subi	r7, r7, STACK_FRAME_OVERHEAD
 
-	SET_SCRATCH0(r1)
-
 	mfmsr	r6
 	/* R4 = original MSR to indicate whether thread used FP/Vector etc. */
 
@@ -397,11 +404,6 @@ restore_gprs:
 	ld	r5, THREAD_TM_DSCR(r3)
 	ld	r6, THREAD_TM_PPR(r3)
 
-	/* Clear the MSR RI since we are about to change R1.  EE is already off
-	 */
-	li	r4, 0
-	mtmsrd	r4, 1
-
 	REST_GPR(0, r7)				/* GPR0 */
 	REST_2GPRS(2, r7)			/* GPR2-3 */
 	REST_GPR(4, r7)				/* GPR4 */
@@ -439,10 +441,34 @@ restore_gprs:
 	ld	r6, _CCR(r7)
 	mtcr    r6
 
-	REST_GPR(1, r7)				/* GPR1 */
-	REST_GPR(5, r7)				/* GPR5-7 */
 	REST_GPR(6, r7)
-	ld	r7, GPR7(r7)
+
+	/*
+	 * Store r1 and r5 on the stack so that we can access them
+	 * after we clear MSR RI.
+	 */
+
+	REST_GPR(5, r7)
+	std	r5, -8(r1)
+	ld	r5, GPR1(r7)
+	std	r5, -16(r1)
+
+	REST_GPR(7, r7)
+
+	/* Clear MSR RI since we are about to change r1. EE is already off */
+	li	r5, 0
+	mtmsrd	r5, 1
+
+	/*
+	 * BE CAREFUL HERE:
+	 * At this point we can't take an SLB miss since we have MSR_RI
+	 * off. Load only to/from the stack/paca which are in SLB bolted regions
+	 * until we turn MSR RI back on.
+	 */
+
+	SET_SCRATCH0(r1)
+	ld	r5, -8(r1)
+	ld	r1, -16(r1)
 
 	/* Commit register state as checkpointed state: */
 	TRECHKPT
--- zfcpdump-kernel-4.4.orig/arch/powerpc/kernel/traps.c
+++ zfcpdump-kernel-4.4/arch/powerpc/kernel/traps.c
@@ -60,6 +60,7 @@
 #include <asm/switch_to.h>
 #include <asm/tm.h>
 #include <asm/debug.h>
+#include <asm/hmi.h>
 #include <sysdev/fsl_pci.h>
 
 #if defined(CONFIG_DEBUGGER) || defined(CONFIG_KEXEC)
@@ -308,9 +309,13 @@ long hmi_exception_realmode(struct pt_re
 {
 	__this_cpu_inc(irq_stat.hmi_exceptions);
 
+	wait_for_subcore_guest_exit();
+
 	if (ppc_md.hmi_exception_early)
 		ppc_md.hmi_exception_early(regs);
 
+	wait_for_tb_resync();
+
 	return 0;
 }
 
--- zfcpdump-kernel-4.4.orig/arch/powerpc/kvm/book3s_hv.c
+++ zfcpdump-kernel-4.4/arch/powerpc/kvm/book3s_hv.c
@@ -51,6 +51,7 @@
 #include <asm/switch_to.h>
 #include <asm/smp.h>
 #include <asm/dbell.h>
+#include <asm/hmi.h>
 #include <linux/gfp.h>
 #include <linux/vmalloc.h>
 #include <linux/highmem.h>
@@ -3195,6 +3196,38 @@ static struct kvmppc_ops kvm_ops_hv = {
 	.hcall_implemented = kvmppc_hcall_impl_hv,
 };
 
+static int kvm_init_subcore_bitmap(void)
+{
+	int i, j;
+	int nr_cores = cpu_nr_cores();
+	struct sibling_subcore_state *sibling_subcore_state;
+
+	for (i = 0; i < nr_cores; i++) {
+		int first_cpu = i * threads_per_core;
+		int node = cpu_to_node(first_cpu);
+
+		/* Ignore if it is already allocated. */
+		if (paca[first_cpu].sibling_subcore_state)
+			continue;
+
+		sibling_subcore_state =
+			kmalloc_node(sizeof(struct sibling_subcore_state),
+							GFP_KERNEL, node);
+		if (!sibling_subcore_state)
+			return -ENOMEM;
+
+		memset(sibling_subcore_state, 0,
+				sizeof(struct sibling_subcore_state));
+
+		for (j = 0; j < threads_per_core; j++) {
+			int cpu = first_cpu + j;
+
+			paca[cpu].sibling_subcore_state = sibling_subcore_state;
+		}
+	}
+	return 0;
+}
+
 static int kvmppc_book3s_init_hv(void)
 {
 	int r;
@@ -3205,6 +3238,10 @@ static int kvmppc_book3s_init_hv(void)
 	if (r < 0)
 		return -ENODEV;
 
+	r = kvm_init_subcore_bitmap();
+	if (r)
+		return r;
+
 	kvm_ops_hv.owner = THIS_MODULE;
 	kvmppc_hv_ops = &kvm_ops_hv;
 
--- zfcpdump-kernel-4.4.orig/arch/powerpc/kvm/book3s_hv_ras.c
+++ zfcpdump-kernel-4.4/arch/powerpc/kvm/book3s_hv_ras.c
@@ -13,6 +13,9 @@
 #include <linux/kernel.h>
 #include <asm/opal.h>
 #include <asm/mce.h>
+#include <asm/machdep.h>
+#include <asm/cputhreads.h>
+#include <asm/hmi.h>
 
 /* SRR1 bits for machine check on POWER7 */
 #define SRR1_MC_LDSTERR		(1ul << (63-42))
@@ -140,3 +143,176 @@ long kvmppc_realmode_machine_check(struc
 {
 	return kvmppc_realmode_mc_power7(vcpu);
 }
+
+/* Check if dynamic split is in force and return subcore size accordingly. */
+static inline int kvmppc_cur_subcore_size(void)
+{
+	if (local_paca->kvm_hstate.kvm_split_mode)
+		return local_paca->kvm_hstate.kvm_split_mode->subcore_size;
+
+	return threads_per_subcore;
+}
+
+void kvmppc_subcore_enter_guest(void)
+{
+	int thread_id, subcore_id;
+
+	thread_id = cpu_thread_in_core(local_paca->paca_index);
+	subcore_id = thread_id / kvmppc_cur_subcore_size();
+
+	local_paca->sibling_subcore_state->in_guest[subcore_id] = 1;
+}
+
+void kvmppc_subcore_exit_guest(void)
+{
+	int thread_id, subcore_id;
+
+	thread_id = cpu_thread_in_core(local_paca->paca_index);
+	subcore_id = thread_id / kvmppc_cur_subcore_size();
+
+	local_paca->sibling_subcore_state->in_guest[subcore_id] = 0;
+}
+
+static bool kvmppc_tb_resync_required(void)
+{
+	if (test_and_set_bit(CORE_TB_RESYNC_REQ_BIT,
+				&local_paca->sibling_subcore_state->flags))
+		return false;
+
+	return true;
+}
+
+static void kvmppc_tb_resync_done(void)
+{
+	clear_bit(CORE_TB_RESYNC_REQ_BIT,
+			&local_paca->sibling_subcore_state->flags);
+}
+
+/*
+ * kvmppc_realmode_hmi_handler() is called only by primary thread during
+ * guest exit path.
+ *
+ * There are multiple reasons why HMI could occur, one of them is
+ * Timebase (TB) error. If this HMI is due to TB error, then TB would
+ * have been in stopped state. The opal hmi handler Will fix it and
+ * restore the TB value with host timebase value. For HMI caused due
+ * to non-TB errors, opal hmi handler will not touch/restore TB register
+ * and hence there won't be any change in TB value.
+ *
+ * Since we are not sure about the cause of this HMI, we can't be sure
+ * about the content of TB register whether it holds guest or host timebase
+ * value. Hence the idea is to resync the TB on every HMI, so that we
+ * know about the exact state of the TB value. Resync TB call will
+ * restore TB to host timebase.
+ *
+ * Things to consider:
+ * - On TB error, HMI interrupt is reported on all the threads of the core
+ *   that has encountered TB error irrespective of split-core mode.
+ * - The very first thread on the core that get chance to fix TB error
+ *   would rsync the TB with local chipTOD value.
+ * - The resync TB is a core level action i.e. it will sync all the TBs
+ *   in that core independent of split-core mode. This means if we trigger
+ *   TB sync from a thread from one subcore, it would affect TB values of
+ *   sibling subcores of the same core.
+ *
+ * All threads need to co-ordinate before making opal hmi handler.
+ * All threads will use sibling_subcore_state->in_guest[] (shared by all
+ * threads in the core) in paca which holds information about whether
+ * sibling subcores are in Guest mode or host mode. The in_guest[] array
+ * is of size MAX_SUBCORE_PER_CORE=4, indexed using subcore id to set/unset
+ * subcore status. Only primary threads from each subcore is responsible
+ * to set/unset its designated array element while entering/exiting the
+ * guset.
+ *
+ * After invoking opal hmi handler call, one of the thread (of entire core)
+ * will need to resync the TB. Bit 63 from subcore state bitmap flags
+ * (sibling_subcore_state->flags) will be used to co-ordinate between
+ * primary threads to decide who takes up the responsibility.
+ *
+ * This is what we do:
+ * - Primary thread from each subcore tries to set resync required bit[63]
+ *   of paca->sibling_subcore_state->flags.
+ * - The first primary thread that is able to set the flag takes the
+ *   responsibility of TB resync. (Let us call it as thread leader)
+ * - All other threads which are in host will call
+ *   wait_for_subcore_guest_exit() and wait for in_guest[0-3] from
+ *   paca->sibling_subcore_state to get cleared.
+ * - All the primary thread will clear its subcore status from subcore
+ *   state in_guest[] array respectively.
+ * - Once all primary threads clear in_guest[0-3], all of them will invoke
+ *   opal hmi handler.
+ * - Now all threads will wait for TB resync to complete by invoking
+ *   wait_for_tb_resync() except the thread leader.
+ * - Thread leader will do a TB resync by invoking opal_resync_timebase()
+ *   call and the it will clear the resync required bit.
+ * - All other threads will now come out of resync wait loop and proceed
+ *   with individual execution.
+ * - On return of this function, primary thread will signal all
+ *   secondary threads to proceed.
+ * - All secondary threads will eventually call opal hmi handler on
+ *   their exit path.
+ */
+
+long kvmppc_realmode_hmi_handler(struct kvm_vcpu *vcpu)
+{
+	int ptid = local_paca->kvm_hstate.ptid;
+	bool resync_req;
+
+	/* This is only called on primary thread. */
+	BUG_ON(ptid != 0);
+	__this_cpu_inc(irq_stat.hmi_exceptions);
+
+	/*
+	 * By now primary thread has already completed guest->host
+	 * partition switch but haven't signaled secondaries yet.
+	 * All the secondary threads on this subcore is waiting
+	 * for primary thread to signal them to go ahead.
+	 *
+	 * For threads from subcore which isn't in guest, they all will
+	 * wait until all other subcores on this core exit the guest.
+	 *
+	 * Now set the resync required bit. If you are the first to
+	 * set this bit then kvmppc_tb_resync_required() function will
+	 * return true. For rest all other subcores
+	 * kvmppc_tb_resync_required() will return false.
+	 *
+	 * If resync_req == true, then this thread is responsible to
+	 * initiate TB resync after hmi handler has completed.
+	 * All other threads on this core will wait until this thread
+	 * clears the resync required bit flag.
+	 */
+	resync_req = kvmppc_tb_resync_required();
+
+	/* Reset the subcore status to indicate it has exited guest */
+	kvmppc_subcore_exit_guest();
+
+	/*
+	 * Wait for other subcores on this core to exit the guest.
+	 * All the primary threads and threads from subcore that are
+	 * not in guest will wait here until all subcores are out
+	 * of guest context.
+	 */
+	wait_for_subcore_guest_exit();
+
+	/*
+	 * At this point we are sure that primary threads from each
+	 * subcore on this core have completed guest->host partition
+	 * switch. Now it is safe to call HMI handler.
+	 */
+	if (ppc_md.hmi_exception_early)
+		ppc_md.hmi_exception_early(NULL);
+
+	/*
+	 * Check if this thread is responsible to resync TB.
+	 * All other threads will wait until this thread completes the
+	 * TB resync.
+	 */
+	if (resync_req) {
+		opal_resync_timebase();
+		/* Reset TB resync req bit */
+		kvmppc_tb_resync_done();
+	} else {
+		wait_for_tb_resync();
+	}
+	return 0;
+}
--- zfcpdump-kernel-4.4.orig/arch/powerpc/kvm/book3s_hv_rmhandlers.S
+++ zfcpdump-kernel-4.4/arch/powerpc/kvm/book3s_hv_rmhandlers.S
@@ -29,6 +29,7 @@
 #include <asm/kvm_book3s_asm.h>
 #include <asm/mmu-hash64.h>
 #include <asm/tm.h>
+#include <asm/opal.h>
 
 #define VCPU_GPRS_TM(reg) (((reg) * ULONG_SIZE) + VCPU_GPR_TM)
 
@@ -373,6 +374,18 @@ kvm_secondary_got_guest:
 	lwsync
 	std	r0, HSTATE_KVM_VCORE(r13)
 
+	/*
+	 * All secondaries exiting guest will fall through this path.
+	 * Before proceeding, just check for HMI interrupt and
+	 * invoke opal hmi handler. By now we are sure that the
+	 * primary thread on this core/subcore has already made partition
+	 * switch/TB resync and we are good to call opal hmi handler.
+	 */
+	cmpwi	r12, BOOK3S_INTERRUPT_HMI
+	bne	kvm_no_guest
+
+	li	r3,0			/* NULL argument */
+	bl	hmi_exception_realmode
 /*
  * At this point we have finished executing in the guest.
  * We need to wait for hwthread_req to become zero, since
@@ -427,6 +440,12 @@ kvm_no_guest:
  * whole-core mode, so we need to nap.
  */
 kvm_unsplit_nap:
+	/* Before we head down to nap, check if HMI is pending and handle it */
+	cmpwi	r12, BOOK3S_INTERRUPT_HMI
+	bne	55f
+	li	r3, 0			/* NULL argument */
+	bl	hmi_exception_realmode
+55:
 	/*
 	 * Ensure that secondary doesn't nap when it has
 	 * its vcore pointer set.
@@ -601,6 +620,11 @@ BEGIN_FTR_SECTION
 	mtspr	SPRN_DPDES, r8
 END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)
 
+	/* Mark the subcore state as inside guest */
+	bl	kvmppc_subcore_enter_guest
+	nop
+	ld	r5, HSTATE_KVM_VCORE(r13)
+	ld	r4, HSTATE_KVM_VCPU(r13)
 	li	r0,1
 	stb	r0,VCORE_IN_GUEST(r5)	/* signal secondaries to continue */
 
@@ -655,112 +679,8 @@ END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_207S)
 
 #ifdef CONFIG_PPC_TRANSACTIONAL_MEM
 BEGIN_FTR_SECTION
-	b	skip_tm
-END_FTR_SECTION_IFCLR(CPU_FTR_TM)
-
-	/* Turn on TM/FP/VSX/VMX so we can restore them. */
-	mfmsr	r5
-	li	r6, MSR_TM >> 32
-	sldi	r6, r6, 32
-	or	r5, r5, r6
-	ori	r5, r5, MSR_FP
-	oris	r5, r5, (MSR_VEC | MSR_VSX)@h
-	mtmsrd	r5
-
-	/*
-	 * The user may change these outside of a transaction, so they must
-	 * always be context switched.
-	 */
-	ld	r5, VCPU_TFHAR(r4)
-	ld	r6, VCPU_TFIAR(r4)
-	ld	r7, VCPU_TEXASR(r4)
-	mtspr	SPRN_TFHAR, r5
-	mtspr	SPRN_TFIAR, r6
-	mtspr	SPRN_TEXASR, r7
-
-	ld	r5, VCPU_MSR(r4)
-	rldicl. r5, r5, 64 - MSR_TS_S_LG, 62
-	beq	skip_tm	/* TM not active in guest */
-
-	/* Make sure the failure summary is set, otherwise we'll program check
-	 * when we trechkpt.  It's possible that this might have been not set
-	 * on a kvmppc_set_one_reg() call but we shouldn't let this crash the
-	 * host.
-	 */
-	oris	r7, r7, (TEXASR_FS)@h
-	mtspr	SPRN_TEXASR, r7
-
-	/*
-	 * We need to load up the checkpointed state for the guest.
-	 * We need to do this early as it will blow away any GPRs, VSRs and
-	 * some SPRs.
-	 */
-
-	mr	r31, r4
-	addi	r3, r31, VCPU_FPRS_TM
-	bl	load_fp_state
-	addi	r3, r31, VCPU_VRS_TM
-	bl	load_vr_state
-	mr	r4, r31
-	lwz	r7, VCPU_VRSAVE_TM(r4)
-	mtspr	SPRN_VRSAVE, r7
-
-	ld	r5, VCPU_LR_TM(r4)
-	lwz	r6, VCPU_CR_TM(r4)
-	ld	r7, VCPU_CTR_TM(r4)
-	ld	r8, VCPU_AMR_TM(r4)
-	ld	r9, VCPU_TAR_TM(r4)
-	mtlr	r5
-	mtcr	r6
-	mtctr	r7
-	mtspr	SPRN_AMR, r8
-	mtspr	SPRN_TAR, r9
-
-	/*
-	 * Load up PPR and DSCR values but don't put them in the actual SPRs
-	 * till the last moment to avoid running with userspace PPR and DSCR for
-	 * too long.
-	 */
-	ld	r29, VCPU_DSCR_TM(r4)
-	ld	r30, VCPU_PPR_TM(r4)
-
-	std	r2, PACATMSCRATCH(r13) /* Save TOC */
-
-	/* Clear the MSR RI since r1, r13 are all going to be foobar. */
-	li	r5, 0
-	mtmsrd	r5, 1
-
-	/* Load GPRs r0-r28 */
-	reg = 0
-	.rept	29
-	ld	reg, VCPU_GPRS_TM(reg)(r31)
-	reg = reg + 1
-	.endr
-
-	mtspr	SPRN_DSCR, r29
-	mtspr	SPRN_PPR, r30
-
-	/* Load final GPRs */
-	ld	29, VCPU_GPRS_TM(29)(r31)
-	ld	30, VCPU_GPRS_TM(30)(r31)
-	ld	31, VCPU_GPRS_TM(31)(r31)
-
-	/* TM checkpointed state is now setup.  All GPRs are now volatile. */
-	TRECHKPT
-
-	/* Now let's get back the state we need. */
-	HMT_MEDIUM
-	GET_PACA(r13)
-	ld	r29, HSTATE_DSCR(r13)
-	mtspr	SPRN_DSCR, r29
-	ld	r4, HSTATE_KVM_VCPU(r13)
-	ld	r1, HSTATE_HOST_R1(r13)
-	ld	r2, PACATMSCRATCH(r13)
-
-	/* Set the MSR RI since we have our registers back. */
-	li	r5, MSR_RI
-	mtmsrd	r5, 1
-skip_tm:
+	bl	kvmppc_restore_tm
+END_FTR_SECTION_IFSET(CPU_FTR_TM)
 #endif
 
 	/* Load guest PMU registers */
@@ -841,12 +761,6 @@ BEGIN_FTR_SECTION
 	/* Skip next section on POWER7 */
 	b	8f
 END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_207S)
-	/* Turn on TM so we can access TFHAR/TFIAR/TEXASR */
-	mfmsr	r8
-	li	r0, 1
-	rldimi	r8, r0, MSR_TM_LG, 63-MSR_TM_LG
-	mtmsrd	r8
-
 	/* Load up POWER8-specific registers */
 	ld	r5, VCPU_IAMR(r4)
 	lwz	r6, VCPU_PSPB(r4)
@@ -1370,6 +1284,20 @@ END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_207S)
 	std	r6, VCPU_ACOP(r9)
 	stw	r7, VCPU_GUEST_PID(r9)
 	std	r8, VCPU_WORT(r9)
+	/*
+	 * Restore various registers to 0, where non-zero values
+	 * set by the guest could disrupt the host.
+	 */
+	li	r0, 0
+	mtspr	SPRN_IAMR, r0
+	mtspr	SPRN_CIABR, r0
+	mtspr	SPRN_DAWRX, r0
+	mtspr	SPRN_TCSCR, r0
+	mtspr	SPRN_WORT, r0
+	/* Set MMCRS to 1<<31 to freeze and disable the SPMC counters */
+	li	r0, 1
+	sldi	r0, r0, 31
+	mtspr	SPRN_MMCRS, r0
 8:
 
 	/* Save and reset AMR and UAMOR before turning on the MMU */
@@ -1422,106 +1350,8 @@ END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_207S)
 
 #ifdef CONFIG_PPC_TRANSACTIONAL_MEM
 BEGIN_FTR_SECTION
-	b	2f
-END_FTR_SECTION_IFCLR(CPU_FTR_TM)
-	/* Turn on TM. */
-	mfmsr	r8
-	li	r0, 1
-	rldimi	r8, r0, MSR_TM_LG, 63-MSR_TM_LG
-	mtmsrd	r8
-
-	ld	r5, VCPU_MSR(r9)
-	rldicl. r5, r5, 64 - MSR_TS_S_LG, 62
-	beq	1f	/* TM not active in guest. */
-
-	li	r3, TM_CAUSE_KVM_RESCHED
-
-	/* Clear the MSR RI since r1, r13 are all going to be foobar. */
-	li	r5, 0
-	mtmsrd	r5, 1
-
-	/* All GPRs are volatile at this point. */
-	TRECLAIM(R3)
-
-	/* Temporarily store r13 and r9 so we have some regs to play with */
-	SET_SCRATCH0(r13)
-	GET_PACA(r13)
-	std	r9, PACATMSCRATCH(r13)
-	ld	r9, HSTATE_KVM_VCPU(r13)
-
-	/* Get a few more GPRs free. */
-	std	r29, VCPU_GPRS_TM(29)(r9)
-	std	r30, VCPU_GPRS_TM(30)(r9)
-	std	r31, VCPU_GPRS_TM(31)(r9)
-
-	/* Save away PPR and DSCR soon so don't run with user values. */
-	mfspr	r31, SPRN_PPR
-	HMT_MEDIUM
-	mfspr	r30, SPRN_DSCR
-	ld	r29, HSTATE_DSCR(r13)
-	mtspr	SPRN_DSCR, r29
-
-	/* Save all but r9, r13 & r29-r31 */
-	reg = 0
-	.rept	29
-	.if (reg != 9) && (reg != 13)
-	std	reg, VCPU_GPRS_TM(reg)(r9)
-	.endif
-	reg = reg + 1
-	.endr
-	/* ... now save r13 */
-	GET_SCRATCH0(r4)
-	std	r4, VCPU_GPRS_TM(13)(r9)
-	/* ... and save r9 */
-	ld	r4, PACATMSCRATCH(r13)
-	std	r4, VCPU_GPRS_TM(9)(r9)
-
-	/* Reload stack pointer and TOC. */
-	ld	r1, HSTATE_HOST_R1(r13)
-	ld	r2, PACATOC(r13)
-
-	/* Set MSR RI now we have r1 and r13 back. */
-	li	r5, MSR_RI
-	mtmsrd	r5, 1
-
-	/* Save away checkpinted SPRs. */
-	std	r31, VCPU_PPR_TM(r9)
-	std	r30, VCPU_DSCR_TM(r9)
-	mflr	r5
-	mfcr	r6
-	mfctr	r7
-	mfspr	r8, SPRN_AMR
-	mfspr	r10, SPRN_TAR
-	std	r5, VCPU_LR_TM(r9)
-	stw	r6, VCPU_CR_TM(r9)
-	std	r7, VCPU_CTR_TM(r9)
-	std	r8, VCPU_AMR_TM(r9)
-	std	r10, VCPU_TAR_TM(r9)
-
-	/* Restore r12 as trap number. */
-	lwz	r12, VCPU_TRAP(r9)
-
-	/* Save FP/VSX. */
-	addi	r3, r9, VCPU_FPRS_TM
-	bl	store_fp_state
-	addi	r3, r9, VCPU_VRS_TM
-	bl	store_vr_state
-	mfspr	r6, SPRN_VRSAVE
-	stw	r6, VCPU_VRSAVE_TM(r9)
-1:
-	/*
-	 * We need to save these SPRs after the treclaim so that the software
-	 * error code is recorded correctly in the TEXASR.  Also the user may
-	 * change these outside of a transaction, so they must always be
-	 * context switched.
-	 */
-	mfspr	r5, SPRN_TFHAR
-	mfspr	r6, SPRN_TFIAR
-	mfspr	r7, SPRN_TEXASR
-	std	r5, VCPU_TFHAR(r9)
-	std	r6, VCPU_TFIAR(r9)
-	std	r7, VCPU_TEXASR(r9)
-2:
+	bl	kvmppc_save_tm
+END_FTR_SECTION_IFSET(CPU_FTR_TM)
 #endif
 
 	/* Increment yield count if they have a VPA */
@@ -1669,6 +1499,24 @@ BEGIN_FTR_SECTION
 	mtspr	SPRN_DPDES, r8
 END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)
 
+	/* If HMI, call kvmppc_realmode_hmi_handler() */
+	cmpwi	r12, BOOK3S_INTERRUPT_HMI
+	bne	27f
+	mr	r3, r9		/* get vcpu pointer */
+	bl	kvmppc_realmode_hmi_handler
+	nop
+	li	r12, BOOK3S_INTERRUPT_HMI
+	/*
+	 * At this point kvmppc_realmode_hmi_handler would have resync-ed
+	 * the TB. Hence it is not required to subtract guest timebase
+	 * offset from timebase. So, skip it.
+	 *
+	 * Also, do not call kvmppc_subcore_exit_guest() because it has
+	 * been invoked as part of kvmppc_realmode_hmi_handler().
+	 */
+	b	30f
+
+27:
 	/* Subtract timebase offset from timebase */
 	ld	r8,VCORE_TB_OFFSET(r5)
 	cmpdi	r8,0
@@ -1684,8 +1532,13 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)
 	addis	r8,r8,0x100		/* if so, increment upper 40 bits */
 	mtspr	SPRN_TBU40,r8
 
+17:	bl	kvmppc_subcore_exit_guest
+	nop
+30:	ld	r5,HSTATE_KVM_VCORE(r13)
+	ld	r4,VCORE_KVM(r5)	/* pointer to struct kvm */
+
 	/* Reset PCR */
-17:	ld	r0, VCORE_PCR(r5)
+	ld	r0, VCORE_PCR(r5)
 	cmpdi	r0, 0
 	beq	18f
 	li	r0, 0
@@ -2153,7 +2006,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)
 
 	/* Emulate H_SET_DABR/X on P8 for the sake of compat mode guests */
 2:	rlwimi	r5, r4, 5, DAWRX_DR | DAWRX_DW
-	rlwimi	r5, r4, 1, DAWRX_WT
+	rlwimi	r5, r4, 2, DAWRX_WT
 	clrrdi	r4, r4, 3
 	std	r4, VCPU_DAWR(r3)
 	std	r5, VCPU_DAWRX(r3)
@@ -2231,6 +2084,13 @@ _GLOBAL(kvmppc_h_cede)		/* r3 = vcpu poi
 	/* save FP state */
 	bl	kvmppc_save_fp
 
+#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
+BEGIN_FTR_SECTION
+	ld	r9, HSTATE_KVM_VCPU(r13)
+	bl	kvmppc_save_tm
+END_FTR_SECTION_IFSET(CPU_FTR_TM)
+#endif
+
 	/*
 	 * Set DEC to the smaller of DEC and HDEC, so that we wake
 	 * no later than the end of our timeslice (HDEC interrupts
@@ -2307,6 +2167,12 @@ kvm_end_cede:
 	bl	kvmhv_accumulate_time
 #endif
 
+#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
+BEGIN_FTR_SECTION
+	bl	kvmppc_restore_tm
+END_FTR_SECTION_IFSET(CPU_FTR_TM)
+#endif
+
 	/* load up FP state */
 	bl	kvmppc_load_fp
 
@@ -2445,6 +2311,8 @@ BEGIN_FTR_SECTION
 	cmpwi	r6, 3			/* hypervisor doorbell? */
 	beq	3f
 END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)
+	cmpwi	r6, 0xa			/* Hypervisor maintenance ? */
+	beq	4f
 	li	r3, 1			/* anything else, return 1 */
 0:	blr
 
@@ -2466,6 +2334,11 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)
 	li	r3, -1
 	blr
 
+	/* Woken up due to Hypervisor maintenance interrupt */
+4:	li	r12, BOOK3S_INTERRUPT_HMI
+	li	r3, 1
+	blr
+
 /*
  * Determine what sort of external interrupt is pending (if any).
  * Returns:
@@ -2615,6 +2488,239 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
 	mr	r4,r31
 	blr
 
+#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
+/*
+ * Save transactional state and TM-related registers.
+ * Called with r9 pointing to the vcpu struct.
+ * This can modify all checkpointed registers, but
+ * restores r1, r2 and r9 (vcpu pointer) before exit.
+ */
+kvmppc_save_tm:
+	mflr	r0
+	std	r0, PPC_LR_STKOFF(r1)
+
+	/* Turn on TM. */
+	mfmsr	r8
+	li	r0, 1
+	rldimi	r8, r0, MSR_TM_LG, 63-MSR_TM_LG
+	mtmsrd	r8
+
+	ld	r5, VCPU_MSR(r9)
+	rldicl. r5, r5, 64 - MSR_TS_S_LG, 62
+	beq	1f	/* TM not active in guest. */
+
+	std	r1, HSTATE_HOST_R1(r13)
+	li	r3, TM_CAUSE_KVM_RESCHED
+
+	/* Clear the MSR RI since r1, r13 are all going to be foobar. */
+	li	r5, 0
+	mtmsrd	r5, 1
+
+	/* All GPRs are volatile at this point. */
+	TRECLAIM(R3)
+
+	/* Temporarily store r13 and r9 so we have some regs to play with */
+	SET_SCRATCH0(r13)
+	GET_PACA(r13)
+	std	r9, PACATMSCRATCH(r13)
+	ld	r9, HSTATE_KVM_VCPU(r13)
+
+	/* Get a few more GPRs free. */
+	std	r29, VCPU_GPRS_TM(29)(r9)
+	std	r30, VCPU_GPRS_TM(30)(r9)
+	std	r31, VCPU_GPRS_TM(31)(r9)
+
+	/* Save away PPR and DSCR soon so don't run with user values. */
+	mfspr	r31, SPRN_PPR
+	HMT_MEDIUM
+	mfspr	r30, SPRN_DSCR
+	ld	r29, HSTATE_DSCR(r13)
+	mtspr	SPRN_DSCR, r29
+
+	/* Save all but r9, r13 & r29-r31 */
+	reg = 0
+	.rept	29
+	.if (reg != 9) && (reg != 13)
+	std	reg, VCPU_GPRS_TM(reg)(r9)
+	.endif
+	reg = reg + 1
+	.endr
+	/* ... now save r13 */
+	GET_SCRATCH0(r4)
+	std	r4, VCPU_GPRS_TM(13)(r9)
+	/* ... and save r9 */
+	ld	r4, PACATMSCRATCH(r13)
+	std	r4, VCPU_GPRS_TM(9)(r9)
+
+	/* Reload stack pointer and TOC. */
+	ld	r1, HSTATE_HOST_R1(r13)
+	ld	r2, PACATOC(r13)
+
+	/* Set MSR RI now we have r1 and r13 back. */
+	li	r5, MSR_RI
+	mtmsrd	r5, 1
+
+	/* Save away checkpinted SPRs. */
+	std	r31, VCPU_PPR_TM(r9)
+	std	r30, VCPU_DSCR_TM(r9)
+	mflr	r5
+	mfcr	r6
+	mfctr	r7
+	mfspr	r8, SPRN_AMR
+	mfspr	r10, SPRN_TAR
+	std	r5, VCPU_LR_TM(r9)
+	stw	r6, VCPU_CR_TM(r9)
+	std	r7, VCPU_CTR_TM(r9)
+	std	r8, VCPU_AMR_TM(r9)
+	std	r10, VCPU_TAR_TM(r9)
+
+	/* Restore r12 as trap number. */
+	lwz	r12, VCPU_TRAP(r9)
+
+	/* Save FP/VSX. */
+	addi	r3, r9, VCPU_FPRS_TM
+	bl	store_fp_state
+	addi	r3, r9, VCPU_VRS_TM
+	bl	store_vr_state
+	mfspr	r6, SPRN_VRSAVE
+	stw	r6, VCPU_VRSAVE_TM(r9)
+1:
+	/*
+	 * We need to save these SPRs after the treclaim so that the software
+	 * error code is recorded correctly in the TEXASR.  Also the user may
+	 * change these outside of a transaction, so they must always be
+	 * context switched.
+	 */
+	mfspr	r5, SPRN_TFHAR
+	mfspr	r6, SPRN_TFIAR
+	mfspr	r7, SPRN_TEXASR
+	std	r5, VCPU_TFHAR(r9)
+	std	r6, VCPU_TFIAR(r9)
+	std	r7, VCPU_TEXASR(r9)
+
+	ld	r0, PPC_LR_STKOFF(r1)
+	mtlr	r0
+	blr
+
+/*
+ * Restore transactional state and TM-related registers.
+ * Called with r4 pointing to the vcpu struct.
+ * This potentially modifies all checkpointed registers.
+ * It restores r1, r2, r4 from the PACA.
+ */
+kvmppc_restore_tm:
+	mflr	r0
+	std	r0, PPC_LR_STKOFF(r1)
+
+	/* Turn on TM/FP/VSX/VMX so we can restore them. */
+	mfmsr	r5
+	li	r6, MSR_TM >> 32
+	sldi	r6, r6, 32
+	or	r5, r5, r6
+	ori	r5, r5, MSR_FP
+	oris	r5, r5, (MSR_VEC | MSR_VSX)@h
+	mtmsrd	r5
+
+	/*
+	 * The user may change these outside of a transaction, so they must
+	 * always be context switched.
+	 */
+	ld	r5, VCPU_TFHAR(r4)
+	ld	r6, VCPU_TFIAR(r4)
+	ld	r7, VCPU_TEXASR(r4)
+	mtspr	SPRN_TFHAR, r5
+	mtspr	SPRN_TFIAR, r6
+	mtspr	SPRN_TEXASR, r7
+
+	ld	r5, VCPU_MSR(r4)
+	rldicl. r5, r5, 64 - MSR_TS_S_LG, 62
+	beqlr		/* TM not active in guest */
+	std	r1, HSTATE_HOST_R1(r13)
+
+	/* Make sure the failure summary is set, otherwise we'll program check
+	 * when we trechkpt.  It's possible that this might have been not set
+	 * on a kvmppc_set_one_reg() call but we shouldn't let this crash the
+	 * host.
+	 */
+	oris	r7, r7, (TEXASR_FS)@h
+	mtspr	SPRN_TEXASR, r7
+
+	/*
+	 * We need to load up the checkpointed state for the guest.
+	 * We need to do this early as it will blow away any GPRs, VSRs and
+	 * some SPRs.
+	 */
+
+	mr	r31, r4
+	addi	r3, r31, VCPU_FPRS_TM
+	bl	load_fp_state
+	addi	r3, r31, VCPU_VRS_TM
+	bl	load_vr_state
+	mr	r4, r31
+	lwz	r7, VCPU_VRSAVE_TM(r4)
+	mtspr	SPRN_VRSAVE, r7
+
+	ld	r5, VCPU_LR_TM(r4)
+	lwz	r6, VCPU_CR_TM(r4)
+	ld	r7, VCPU_CTR_TM(r4)
+	ld	r8, VCPU_AMR_TM(r4)
+	ld	r9, VCPU_TAR_TM(r4)
+	mtlr	r5
+	mtcr	r6
+	mtctr	r7
+	mtspr	SPRN_AMR, r8
+	mtspr	SPRN_TAR, r9
+
+	/*
+	 * Load up PPR and DSCR values but don't put them in the actual SPRs
+	 * till the last moment to avoid running with userspace PPR and DSCR for
+	 * too long.
+	 */
+	ld	r29, VCPU_DSCR_TM(r4)
+	ld	r30, VCPU_PPR_TM(r4)
+
+	std	r2, PACATMSCRATCH(r13) /* Save TOC */
+
+	/* Clear the MSR RI since r1, r13 are all going to be foobar. */
+	li	r5, 0
+	mtmsrd	r5, 1
+
+	/* Load GPRs r0-r28 */
+	reg = 0
+	.rept	29
+	ld	reg, VCPU_GPRS_TM(reg)(r31)
+	reg = reg + 1
+	.endr
+
+	mtspr	SPRN_DSCR, r29
+	mtspr	SPRN_PPR, r30
+
+	/* Load final GPRs */
+	ld	29, VCPU_GPRS_TM(29)(r31)
+	ld	30, VCPU_GPRS_TM(30)(r31)
+	ld	31, VCPU_GPRS_TM(31)(r31)
+
+	/* TM checkpointed state is now setup.  All GPRs are now volatile. */
+	TRECHKPT
+
+	/* Now let's get back the state we need. */
+	HMT_MEDIUM
+	GET_PACA(r13)
+	ld	r29, HSTATE_DSCR(r13)
+	mtspr	SPRN_DSCR, r29
+	ld	r4, HSTATE_KVM_VCPU(r13)
+	ld	r1, HSTATE_HOST_R1(r13)
+	ld	r2, PACATMSCRATCH(r13)
+
+	/* Set the MSR RI since we have our registers back. */
+	li	r5, MSR_RI
+	mtmsrd	r5, 1
+
+	ld	r0, PPC_LR_STKOFF(r1)
+	mtlr	r0
+	blr
+#endif
+
 /*
  * We come here if we get any exception or interrupt while we are
  * executing host real mode code while in guest MMU context.
--- zfcpdump-kernel-4.4.orig/arch/powerpc/kvm/book3s_paired_singles.c
+++ zfcpdump-kernel-4.4/arch/powerpc/kvm/book3s_paired_singles.c
@@ -1265,6 +1265,7 @@ int kvmppc_emulate_paired_single(struct
 	if (rcomp)
 		kvmppc_set_cr(vcpu, cr);
 
+	disable_kernel_fp();
 	preempt_enable();
 
 	return emulated;
--- zfcpdump-kernel-4.4.orig/arch/powerpc/kvm/book3s_pr.c
+++ zfcpdump-kernel-4.4/arch/powerpc/kvm/book3s_pr.c
@@ -751,6 +751,7 @@ static int kvmppc_handle_ext(struct kvm_
 		preempt_disable();
 		enable_kernel_fp();
 		load_fp_state(&vcpu->arch.fp);
+		disable_kernel_fp();
 		t->fp_save_area = &vcpu->arch.fp;
 		preempt_enable();
 	}
@@ -760,6 +761,7 @@ static int kvmppc_handle_ext(struct kvm_
 		preempt_disable();
 		enable_kernel_altivec();
 		load_vr_state(&vcpu->arch.vr);
+		disable_kernel_altivec();
 		t->vr_save_area = &vcpu->arch.vr;
 		preempt_enable();
 #endif
@@ -788,6 +790,7 @@ static void kvmppc_handle_lost_ext(struc
 		preempt_disable();
 		enable_kernel_fp();
 		load_fp_state(&vcpu->arch.fp);
+		disable_kernel_fp();
 		preempt_enable();
 	}
 #ifdef CONFIG_ALTIVEC
@@ -795,6 +798,7 @@ static void kvmppc_handle_lost_ext(struc
 		preempt_disable();
 		enable_kernel_altivec();
 		load_vr_state(&vcpu->arch.vr);
+		disable_kernel_altivec();
 		preempt_enable();
 	}
 #endif
--- zfcpdump-kernel-4.4.orig/arch/powerpc/kvm/book3s_xics.c
+++ zfcpdump-kernel-4.4/arch/powerpc/kvm/book3s_xics.c
@@ -92,7 +92,7 @@ static int ics_deliver_irq(struct kvmppc
 	 * we are the only setter, thus concurrent access is undefined
 	 * to begin with.
 	 */
-	if (level == 1 || level == KVM_INTERRUPT_SET_LEVEL)
+	if ((level == 1 && state->lsi) || level == KVM_INTERRUPT_SET_LEVEL)
 		state->asserted = 1;
 	else if (level == 0 || level == KVM_INTERRUPT_UNSET) {
 		state->asserted = 0;
@@ -1174,9 +1174,11 @@ static int xics_get_source(struct kvmppc
 			prio = irqp->saved_priority;
 		}
 		val |= prio << KVM_XICS_PRIORITY_SHIFT;
-		if (irqp->asserted)
-			val |= KVM_XICS_LEVEL_SENSITIVE | KVM_XICS_PENDING;
-		else if (irqp->masked_pending || irqp->resend)
+		if (irqp->lsi) {
+			val |= KVM_XICS_LEVEL_SENSITIVE;
+			if (irqp->asserted)
+				val |= KVM_XICS_PENDING;
+		} else if (irqp->masked_pending || irqp->resend)
 			val |= KVM_XICS_PENDING;
 		ret = 0;
 	}
@@ -1228,9 +1230,13 @@ static int xics_set_source(struct kvmppc
 	irqp->priority = prio;
 	irqp->resend = 0;
 	irqp->masked_pending = 0;
+	irqp->lsi = 0;
 	irqp->asserted = 0;
-	if ((val & KVM_XICS_PENDING) && (val & KVM_XICS_LEVEL_SENSITIVE))
-		irqp->asserted = 1;
+	if (val & KVM_XICS_LEVEL_SENSITIVE) {
+		irqp->lsi = 1;
+		if (val & KVM_XICS_PENDING)
+			irqp->asserted = 1;
+	}
 	irqp->exists = 1;
 	arch_spin_unlock(&ics->lock);
 	local_irq_restore(flags);
@@ -1249,11 +1255,10 @@ int kvm_set_irq(struct kvm *kvm, int irq
 	return ics_deliver_irq(xics, irq, level);
 }
 
-int kvm_set_msi(struct kvm_kernel_irq_routing_entry *irq_entry, struct kvm *kvm,
-		int irq_source_id, int level, bool line_status)
+int kvm_arch_set_irq_inatomic(struct kvm_kernel_irq_routing_entry *irq_entry,
+			      struct kvm *kvm, int irq_source_id,
+			      int level, bool line_status)
 {
-	if (!level)
-		return -1;
 	return kvm_set_irq(kvm, irq_source_id, irq_entry->gsi,
 			   level, line_status);
 }
--- zfcpdump-kernel-4.4.orig/arch/powerpc/kvm/book3s_xics.h
+++ zfcpdump-kernel-4.4/arch/powerpc/kvm/book3s_xics.h
@@ -39,6 +39,7 @@ struct ics_irq_state {
 	u8  saved_priority;
 	u8  resend;
 	u8  masked_pending;
+	u8  lsi;		/* level-sensitive interrupt */
 	u8  asserted; /* Only for LSI */
 	u8  exists;
 };
--- zfcpdump-kernel-4.4.orig/arch/powerpc/kvm/booke.c
+++ zfcpdump-kernel-4.4/arch/powerpc/kvm/booke.c
@@ -98,6 +98,7 @@ void kvmppc_vcpu_disable_spe(struct kvm_
 	preempt_disable();
 	enable_kernel_spe();
 	kvmppc_save_guest_spe(vcpu);
+	disable_kernel_spe();
 	vcpu->arch.shadow_msr &= ~MSR_SPE;
 	preempt_enable();
 }
@@ -107,6 +108,7 @@ static void kvmppc_vcpu_enable_spe(struc
 	preempt_disable();
 	enable_kernel_spe();
 	kvmppc_load_guest_spe(vcpu);
+	disable_kernel_spe();
 	vcpu->arch.shadow_msr |= MSR_SPE;
 	preempt_enable();
 }
@@ -141,6 +143,7 @@ static inline void kvmppc_load_guest_fp(
 	if (!(current->thread.regs->msr & MSR_FP)) {
 		enable_kernel_fp();
 		load_fp_state(&vcpu->arch.fp);
+		disable_kernel_fp();
 		current->thread.fp_save_area = &vcpu->arch.fp;
 		current->thread.regs->msr |= MSR_FP;
 	}
@@ -182,6 +185,7 @@ static inline void kvmppc_load_guest_alt
 		if (!(current->thread.regs->msr & MSR_VEC)) {
 			enable_kernel_altivec();
 			load_vr_state(&vcpu->arch.vr);
+			disable_kernel_altivec();
 			current->thread.vr_save_area = &vcpu->arch.vr;
 			current->thread.regs->msr |= MSR_VEC;
 		}
--- zfcpdump-kernel-4.4.orig/arch/powerpc/kvm/powerpc.c
+++ zfcpdump-kernel-4.4/arch/powerpc/kvm/powerpc.c
@@ -919,21 +919,17 @@ int kvm_vcpu_ioctl_get_one_reg(struct kv
 				r = -ENXIO;
 				break;
 			}
-			vcpu->arch.vr.vr[reg->id - KVM_REG_PPC_VR0] = val.vval;
+			val.vval = vcpu->arch.vr.vr[reg->id - KVM_REG_PPC_VR0];
 			break;
 		case KVM_REG_PPC_VSCR:
 			if (!cpu_has_feature(CPU_FTR_ALTIVEC)) {
 				r = -ENXIO;
 				break;
 			}
-			vcpu->arch.vr.vscr.u[3] = set_reg_val(reg->id, val);
+			val = get_reg_val(reg->id, vcpu->arch.vr.vscr.u[3]);
 			break;
 		case KVM_REG_PPC_VRSAVE:
-			if (!cpu_has_feature(CPU_FTR_ALTIVEC)) {
-				r = -ENXIO;
-				break;
-			}
-			vcpu->arch.vrsave = set_reg_val(reg->id, val);
+			val = get_reg_val(reg->id, vcpu->arch.vrsave);
 			break;
 #endif /* CONFIG_ALTIVEC */
 		default:
@@ -974,17 +970,21 @@ int kvm_vcpu_ioctl_set_one_reg(struct kv
 				r = -ENXIO;
 				break;
 			}
-			val.vval = vcpu->arch.vr.vr[reg->id - KVM_REG_PPC_VR0];
+			vcpu->arch.vr.vr[reg->id - KVM_REG_PPC_VR0] = val.vval;
 			break;
 		case KVM_REG_PPC_VSCR:
 			if (!cpu_has_feature(CPU_FTR_ALTIVEC)) {
 				r = -ENXIO;
 				break;
 			}
-			val = get_reg_val(reg->id, vcpu->arch.vr.vscr.u[3]);
+			vcpu->arch.vr.vscr.u[3] = set_reg_val(reg->id, val);
 			break;
 		case KVM_REG_PPC_VRSAVE:
-			val = get_reg_val(reg->id, vcpu->arch.vrsave);
+			if (!cpu_has_feature(CPU_FTR_ALTIVEC)) {
+				r = -ENXIO;
+				break;
+			}
+			vcpu->arch.vrsave = set_reg_val(reg->id, val);
 			break;
 #endif /* CONFIG_ALTIVEC */
 		default:
--- zfcpdump-kernel-4.4.orig/arch/powerpc/lib/copyuser_64.S
+++ zfcpdump-kernel-4.4/arch/powerpc/lib/copyuser_64.S
@@ -359,6 +359,7 @@ END_FTR_SECTION_IFCLR(CPU_FTR_UNALIGNED_
 	addi	r3,r3,8
 171:
 177:
+179:
 	addi	r3,r3,8
 370:
 372:
@@ -373,7 +374,6 @@ END_FTR_SECTION_IFCLR(CPU_FTR_UNALIGNED_
 173:
 174:
 175:
-179:
 181:
 184:
 186:
--- zfcpdump-kernel-4.4.orig/arch/powerpc/lib/vmx-helper.c
+++ zfcpdump-kernel-4.4/arch/powerpc/lib/vmx-helper.c
@@ -46,6 +46,7 @@ int enter_vmx_usercopy(void)
  */
 int exit_vmx_usercopy(void)
 {
+	disable_kernel_altivec();
 	pagefault_enable();
 	preempt_enable();
 	return 0;
@@ -70,6 +71,7 @@ int enter_vmx_copy(void)
  */
 void *exit_vmx_copy(void *dest)
 {
+	disable_kernel_altivec();
 	preempt_enable();
 	return dest;
 }
--- zfcpdump-kernel-4.4.orig/arch/powerpc/lib/xor_vmx.c
+++ zfcpdump-kernel-4.4/arch/powerpc/lib/xor_vmx.c
@@ -74,6 +74,7 @@ void xor_altivec_2(unsigned long bytes,
 		v2 += 4;
 	} while (--lines > 0);
 
+	disable_kernel_altivec();
 	preempt_enable();
 }
 EXPORT_SYMBOL(xor_altivec_2);
@@ -102,6 +103,7 @@ void xor_altivec_3(unsigned long bytes,
 		v3 += 4;
 	} while (--lines > 0);
 
+	disable_kernel_altivec();
 	preempt_enable();
 }
 EXPORT_SYMBOL(xor_altivec_3);
@@ -135,6 +137,7 @@ void xor_altivec_4(unsigned long bytes,
 		v4 += 4;
 	} while (--lines > 0);
 
+	disable_kernel_altivec();
 	preempt_enable();
 }
 EXPORT_SYMBOL(xor_altivec_4);
@@ -172,6 +175,7 @@ void xor_altivec_5(unsigned long bytes,
 		v5 += 4;
 	} while (--lines > 0);
 
+	disable_kernel_altivec();
 	preempt_enable();
 }
 EXPORT_SYMBOL(xor_altivec_5);
--- zfcpdump-kernel-4.4.orig/arch/powerpc/mm/hugetlbpage.c
+++ zfcpdump-kernel-4.4/arch/powerpc/mm/hugetlbpage.c
@@ -486,13 +486,13 @@ static void hugepd_free(struct mmu_gathe
 {
 	struct hugepd_freelist **batchp;
 
-	batchp = this_cpu_ptr(&hugepd_freelist_cur);
+	batchp = &get_cpu_var(hugepd_freelist_cur);
 
 	if (atomic_read(&tlb->mm->mm_users) < 2 ||
 	    cpumask_equal(mm_cpumask(tlb->mm),
 			  cpumask_of(smp_processor_id()))) {
 		kmem_cache_free(hugepte_cache, hugepte);
-        put_cpu_var(hugepd_freelist_cur);
+		put_cpu_var(hugepd_freelist_cur);
 		return;
 	}
 
--- zfcpdump-kernel-4.4.orig/arch/powerpc/mm/slb_low.S
+++ zfcpdump-kernel-4.4/arch/powerpc/mm/slb_low.S
@@ -113,7 +113,12 @@ BEGIN_FTR_SECTION
 END_MMU_FTR_SECTION_IFCLR(MMU_FTR_1T_SEGMENT)
 	b	slb_finish_load_1T
 
-0:
+0:	/*
+	 * For userspace addresses, make sure this is region 0.
+	 */
+	cmpdi	r9, 0
+	bne	8f
+
 	/* when using slices, we extract the psize off the slice bitmaps
 	 * and then we need to get the sllp encoding off the mmu_psize_defs
 	 * array.
--- zfcpdump-kernel-4.4.orig/arch/powerpc/perf/power7-pmu.c
+++ zfcpdump-kernel-4.4/arch/powerpc/perf/power7-pmu.c
@@ -54,7 +54,7 @@
  * Power7 event codes.
  */
 #define EVENT(_name, _code) \
-	PME_##_name = _code,
+	_name = _code,
 
 enum {
 #include "power7-events-list.h"
@@ -318,14 +318,14 @@ static void power7_disable_pmc(unsigned
 }
 
 static int power7_generic_events[] = {
-	[PERF_COUNT_HW_CPU_CYCLES] =			PME_PM_CYC,
-	[PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] =	PME_PM_GCT_NOSLOT_CYC,
-	[PERF_COUNT_HW_STALLED_CYCLES_BACKEND] =	PME_PM_CMPLU_STALL,
-	[PERF_COUNT_HW_INSTRUCTIONS] =			PME_PM_INST_CMPL,
-	[PERF_COUNT_HW_CACHE_REFERENCES] =		PME_PM_LD_REF_L1,
-	[PERF_COUNT_HW_CACHE_MISSES] =			PME_PM_LD_MISS_L1,
-	[PERF_COUNT_HW_BRANCH_INSTRUCTIONS] =		PME_PM_BRU_FIN,
-	[PERF_COUNT_HW_BRANCH_MISSES] =			PME_PM_BR_MPRED,
+	[PERF_COUNT_HW_CPU_CYCLES] =			PM_CYC,
+	[PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] =	PM_GCT_NOSLOT_CYC,
+	[PERF_COUNT_HW_STALLED_CYCLES_BACKEND] =	PM_CMPLU_STALL,
+	[PERF_COUNT_HW_INSTRUCTIONS] =			PM_INST_CMPL,
+	[PERF_COUNT_HW_CACHE_REFERENCES] =		PM_LD_REF_L1,
+	[PERF_COUNT_HW_CACHE_MISSES] =			PM_LD_MISS_L1,
+	[PERF_COUNT_HW_BRANCH_INSTRUCTIONS] =		PM_BRU_FIN,
+	[PERF_COUNT_HW_BRANCH_MISSES] =			PM_BR_MPRED,
 };
 
 #define C(x)	PERF_COUNT_HW_CACHE_##x
--- /dev/null
+++ zfcpdump-kernel-4.4/arch/powerpc/perf/power8-events-list.h
@@ -0,0 +1,51 @@
+/*
+ * Performance counter support for POWER8 processors.
+ *
+ * Copyright 2014 Sukadev Bhattiprolu, IBM Corporation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+/*
+ * Power8 event codes.
+ */
+EVENT(PM_CYC,					0x0001e)
+EVENT(PM_GCT_NOSLOT_CYC,			0x100f8)
+EVENT(PM_CMPLU_STALL,				0x4000a)
+EVENT(PM_INST_CMPL,				0x00002)
+EVENT(PM_BRU_FIN,				0x10068)
+EVENT(PM_BR_MPRED_CMPL,				0x400f6)
+
+/* All L1 D cache load references counted at finish, gated by reject */
+EVENT(PM_LD_REF_L1,				0x100ee)
+/* Load Missed L1 */
+EVENT(PM_LD_MISS_L1,				0x3e054)
+/* Store Missed L1 */
+EVENT(PM_ST_MISS_L1,				0x300f0)
+/* L1 cache data prefetches */
+EVENT(PM_L1_PREF,				0x0d8b8)
+/* Instruction fetches from L1 */
+EVENT(PM_INST_FROM_L1,				0x04080)
+/* Demand iCache Miss */
+EVENT(PM_L1_ICACHE_MISS,			0x200fd)
+/* Instruction Demand sectors wriittent into IL1 */
+EVENT(PM_L1_DEMAND_WRITE,			0x0408c)
+/* Instruction prefetch written into IL1 */
+EVENT(PM_IC_PREF_WRITE,				0x0408e)
+/* The data cache was reloaded from local core's L3 due to a demand load */
+EVENT(PM_DATA_FROM_L3,				0x4c042)
+/* Demand LD - L3 Miss (not L2 hit and not L3 hit) */
+EVENT(PM_DATA_FROM_L3MISS,			0x300fe)
+/* All successful D-side store dispatches for this thread */
+EVENT(PM_L2_ST,					0x17080)
+/* All successful D-side store dispatches for this thread that were L2 Miss */
+EVENT(PM_L2_ST_MISS,				0x17082)
+/* Total HW L3 prefetches(Load+store) */
+EVENT(PM_L3_PREF_ALL,				0x4e052)
+/* Data PTEG reload */
+EVENT(PM_DTLB_MISS,				0x300fc)
+/* ITLB Reloaded */
+EVENT(PM_ITLB_MISS,				0x400fc)
--- zfcpdump-kernel-4.4.orig/arch/powerpc/perf/power8-pmu.c
+++ zfcpdump-kernel-4.4/arch/powerpc/perf/power8-pmu.c
@@ -17,48 +17,16 @@
 #include <asm/firmware.h>
 #include <asm/cputable.h>
 
-
 /*
  * Some power8 event codes.
  */
-#define PM_CYC				0x0001e
-#define PM_GCT_NOSLOT_CYC		0x100f8
-#define PM_CMPLU_STALL			0x4000a
-#define PM_INST_CMPL			0x00002
-#define PM_BRU_FIN			0x10068
-#define PM_BR_MPRED_CMPL		0x400f6
-
-/* All L1 D cache load references counted at finish, gated by reject */
-#define PM_LD_REF_L1			0x100ee
-/* Load Missed L1 */
-#define PM_LD_MISS_L1			0x3e054
-/* Store Missed L1 */
-#define PM_ST_MISS_L1			0x300f0
-/* L1 cache data prefetches */
-#define PM_L1_PREF			0x0d8b8
-/* Instruction fetches from L1 */
-#define PM_INST_FROM_L1			0x04080
-/* Demand iCache Miss */
-#define PM_L1_ICACHE_MISS		0x200fd
-/* Instruction Demand sectors wriittent into IL1 */
-#define PM_L1_DEMAND_WRITE		0x0408c
-/* Instruction prefetch written into IL1 */
-#define PM_IC_PREF_WRITE		0x0408e
-/* The data cache was reloaded from local core's L3 due to a demand load */
-#define PM_DATA_FROM_L3			0x4c042
-/* Demand LD - L3 Miss (not L2 hit and not L3 hit) */
-#define PM_DATA_FROM_L3MISS		0x300fe
-/* All successful D-side store dispatches for this thread */
-#define PM_L2_ST			0x17080
-/* All successful D-side store dispatches for this thread that were L2 Miss */
-#define PM_L2_ST_MISS			0x17082
-/* Total HW L3 prefetches(Load+store) */
-#define PM_L3_PREF_ALL			0x4e052
-/* Data PTEG reload */
-#define PM_DTLB_MISS			0x300fc
-/* ITLB Reloaded */
-#define PM_ITLB_MISS			0x400fc
+#define EVENT(_name, _code)	_name = _code,
+
+enum {
+#include "power8-events-list.h"
+};
 
+#undef EVENT
 
 /*
  * Raw event encoding for POWER8:
@@ -604,6 +572,71 @@ static void power8_disable_pmc(unsigned
 		mmcr[1] &= ~(0xffUL << MMCR1_PMCSEL_SHIFT(pmc + 1));
 }
 
+GENERIC_EVENT_ATTR(cpu-cycles,			PM_CYC);
+GENERIC_EVENT_ATTR(stalled-cycles-frontend,	PM_GCT_NOSLOT_CYC);
+GENERIC_EVENT_ATTR(stalled-cycles-backend,	PM_CMPLU_STALL);
+GENERIC_EVENT_ATTR(instructions,		PM_INST_CMPL);
+GENERIC_EVENT_ATTR(branch-instructions,		PM_BRU_FIN);
+GENERIC_EVENT_ATTR(branch-misses,		PM_BR_MPRED_CMPL);
+GENERIC_EVENT_ATTR(cache-references,		PM_LD_REF_L1);
+GENERIC_EVENT_ATTR(cache-misses,		PM_LD_MISS_L1);
+
+CACHE_EVENT_ATTR(L1-dcache-load-misses,		PM_LD_MISS_L1);
+CACHE_EVENT_ATTR(L1-dcache-loads,		PM_LD_REF_L1);
+
+CACHE_EVENT_ATTR(L1-dcache-prefetches,		PM_L1_PREF);
+CACHE_EVENT_ATTR(L1-dcache-store-misses,	PM_ST_MISS_L1);
+CACHE_EVENT_ATTR(L1-icache-load-misses,		PM_L1_ICACHE_MISS);
+CACHE_EVENT_ATTR(L1-icache-loads,		PM_INST_FROM_L1);
+CACHE_EVENT_ATTR(L1-icache-prefetches,		PM_IC_PREF_WRITE);
+
+CACHE_EVENT_ATTR(LLC-load-misses,		PM_DATA_FROM_L3MISS);
+CACHE_EVENT_ATTR(LLC-loads,			PM_DATA_FROM_L3);
+CACHE_EVENT_ATTR(LLC-prefetches,		PM_L3_PREF_ALL);
+CACHE_EVENT_ATTR(LLC-store-misses,		PM_L2_ST_MISS);
+CACHE_EVENT_ATTR(LLC-stores,			PM_L2_ST);
+
+CACHE_EVENT_ATTR(branch-load-misses,		PM_BR_MPRED_CMPL);
+CACHE_EVENT_ATTR(branch-loads,			PM_BRU_FIN);
+CACHE_EVENT_ATTR(dTLB-load-misses,		PM_DTLB_MISS);
+CACHE_EVENT_ATTR(iTLB-load-misses,		PM_ITLB_MISS);
+
+static struct attribute *power8_events_attr[] = {
+	GENERIC_EVENT_PTR(PM_CYC),
+	GENERIC_EVENT_PTR(PM_GCT_NOSLOT_CYC),
+	GENERIC_EVENT_PTR(PM_CMPLU_STALL),
+	GENERIC_EVENT_PTR(PM_INST_CMPL),
+	GENERIC_EVENT_PTR(PM_BRU_FIN),
+	GENERIC_EVENT_PTR(PM_BR_MPRED_CMPL),
+	GENERIC_EVENT_PTR(PM_LD_REF_L1),
+	GENERIC_EVENT_PTR(PM_LD_MISS_L1),
+
+	CACHE_EVENT_PTR(PM_LD_MISS_L1),
+	CACHE_EVENT_PTR(PM_LD_REF_L1),
+	CACHE_EVENT_PTR(PM_L1_PREF),
+	CACHE_EVENT_PTR(PM_ST_MISS_L1),
+	CACHE_EVENT_PTR(PM_L1_ICACHE_MISS),
+	CACHE_EVENT_PTR(PM_INST_FROM_L1),
+	CACHE_EVENT_PTR(PM_IC_PREF_WRITE),
+	CACHE_EVENT_PTR(PM_DATA_FROM_L3MISS),
+	CACHE_EVENT_PTR(PM_DATA_FROM_L3),
+	CACHE_EVENT_PTR(PM_L3_PREF_ALL),
+	CACHE_EVENT_PTR(PM_L2_ST_MISS),
+	CACHE_EVENT_PTR(PM_L2_ST),
+
+	CACHE_EVENT_PTR(PM_BR_MPRED_CMPL),
+	CACHE_EVENT_PTR(PM_BRU_FIN),
+
+	CACHE_EVENT_PTR(PM_DTLB_MISS),
+	CACHE_EVENT_PTR(PM_ITLB_MISS),
+	NULL
+};
+
+static struct attribute_group power8_pmu_events_group = {
+	.name = "events",
+	.attrs = power8_events_attr,
+};
+
 PMU_FORMAT_ATTR(event,		"config:0-49");
 PMU_FORMAT_ATTR(pmcxsel,	"config:0-7");
 PMU_FORMAT_ATTR(mark,		"config:8");
@@ -640,6 +673,7 @@ struct attribute_group power8_pmu_format
 
 static const struct attribute_group *power8_pmu_attr_groups[] = {
 	&power8_pmu_format_group,
+	&power8_pmu_events_group,
 	NULL,
 };
 
--- zfcpdump-kernel-4.4.orig/arch/powerpc/platforms/powernv/Makefile
+++ zfcpdump-kernel-4.4/arch/powerpc/platforms/powernv/Makefile
@@ -2,9 +2,10 @@ obj-y			+= setup.o opal-wrappers.o opal.
 obj-y			+= opal-rtc.o opal-nvram.o opal-lpc.o opal-flash.o
 obj-y			+= rng.o opal-elog.o opal-dump.o opal-sysparam.o opal-sensor.o
 obj-y			+= opal-msglog.o opal-hmi.o opal-power.o opal-irqchip.o
+obj-y			+= opal-kmsg.o
 
 obj-$(CONFIG_SMP)	+= smp.o subcore.o subcore-asm.o
-obj-$(CONFIG_PCI)	+= pci.o pci-p5ioc2.o pci-ioda.o
+obj-$(CONFIG_PCI)	+= pci.o pci-p5ioc2.o pci-ioda.o npu-dma.o
 obj-$(CONFIG_EEH)	+= eeh-powernv.o
 obj-$(CONFIG_PPC_SCOM)	+= opal-xscom.o
 obj-$(CONFIG_MEMORY_FAILURE)	+= opal-memory-errors.o
--- zfcpdump-kernel-4.4.orig/arch/powerpc/platforms/powernv/eeh-powernv.c
+++ zfcpdump-kernel-4.4/arch/powerpc/platforms/powernv/eeh-powernv.c
@@ -444,9 +444,12 @@ static void *pnv_eeh_probe(struct pci_dn
 	 * PCI devices of the PE are expected to be removed prior
 	 * to PE reset.
 	 */
-	if (!edev->pe->bus)
+	if (!(edev->pe->state & EEH_PE_PRI_BUS)) {
 		edev->pe->bus = pci_find_bus(hose->global_number,
 					     pdn->busno);
+		if (edev->pe->bus)
+			edev->pe->state |= EEH_PE_PRI_BUS;
+	}
 
 	/*
 	 * Enable EEH explicitly so that we will do EEH check
--- /dev/null
+++ zfcpdump-kernel-4.4/arch/powerpc/platforms/powernv/npu-dma.c
@@ -0,0 +1,348 @@
+/*
+ * This file implements the DMA operations for NVLink devices. The NPU
+ * devices all point to the same iommu table as the parent PCI device.
+ *
+ * Copyright Alistair Popple, IBM Corporation 2015.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ */
+
+#include <linux/export.h>
+#include <linux/pci.h>
+#include <linux/memblock.h>
+
+#include <asm/iommu.h>
+#include <asm/pnv-pci.h>
+#include <asm/msi_bitmap.h>
+#include <asm/opal.h>
+
+#include "powernv.h"
+#include "pci.h"
+
+/*
+ * Other types of TCE cache invalidation are not functional in the
+ * hardware.
+ */
+#define TCE_KILL_INVAL_ALL PPC_BIT(0)
+
+static struct pci_dev *get_pci_dev(struct device_node *dn)
+{
+	return PCI_DN(dn)->pcidev;
+}
+
+/* Given a NPU device get the associated PCI device. */
+struct pci_dev *pnv_pci_get_gpu_dev(struct pci_dev *npdev)
+{
+	struct device_node *dn;
+	struct pci_dev *gpdev;
+
+	/* Get assoicated PCI device */
+	dn = of_parse_phandle(npdev->dev.of_node, "ibm,gpu", 0);
+	if (!dn)
+		return NULL;
+
+	gpdev = get_pci_dev(dn);
+	of_node_put(dn);
+
+	return gpdev;
+}
+EXPORT_SYMBOL(pnv_pci_get_gpu_dev);
+
+/* Given the real PCI device get a linked NPU device. */
+struct pci_dev *pnv_pci_get_npu_dev(struct pci_dev *gpdev, int index)
+{
+	struct device_node *dn;
+	struct pci_dev *npdev;
+
+	/* Get assoicated PCI device */
+	dn = of_parse_phandle(gpdev->dev.of_node, "ibm,npu", index);
+	if (!dn)
+		return NULL;
+
+	npdev = get_pci_dev(dn);
+	of_node_put(dn);
+
+	return npdev;
+}
+EXPORT_SYMBOL(pnv_pci_get_npu_dev);
+
+#define NPU_DMA_OP_UNSUPPORTED()					\
+	dev_err_once(dev, "%s operation unsupported for NVLink devices\n", \
+		__func__)
+
+static void *dma_npu_alloc(struct device *dev, size_t size,
+			   dma_addr_t *dma_handle, gfp_t flag,
+			   struct dma_attrs *attrs)
+{
+	NPU_DMA_OP_UNSUPPORTED();
+	return NULL;
+}
+
+static void dma_npu_free(struct device *dev, size_t size,
+			 void *vaddr, dma_addr_t dma_handle,
+			 struct dma_attrs *attrs)
+{
+	NPU_DMA_OP_UNSUPPORTED();
+}
+
+static dma_addr_t dma_npu_map_page(struct device *dev, struct page *page,
+				   unsigned long offset, size_t size,
+				   enum dma_data_direction direction,
+				   struct dma_attrs *attrs)
+{
+	NPU_DMA_OP_UNSUPPORTED();
+	return 0;
+}
+
+static int dma_npu_map_sg(struct device *dev, struct scatterlist *sglist,
+			  int nelems, enum dma_data_direction direction,
+			  struct dma_attrs *attrs)
+{
+	NPU_DMA_OP_UNSUPPORTED();
+	return 0;
+}
+
+static int dma_npu_dma_supported(struct device *dev, u64 mask)
+{
+	NPU_DMA_OP_UNSUPPORTED();
+	return 0;
+}
+
+static u64 dma_npu_get_required_mask(struct device *dev)
+{
+	NPU_DMA_OP_UNSUPPORTED();
+	return 0;
+}
+
+struct dma_map_ops dma_npu_ops = {
+	.map_page		= dma_npu_map_page,
+	.map_sg			= dma_npu_map_sg,
+	.alloc			= dma_npu_alloc,
+	.free			= dma_npu_free,
+	.dma_supported		= dma_npu_dma_supported,
+	.get_required_mask	= dma_npu_get_required_mask,
+};
+
+/*
+ * Returns the PE assoicated with the PCI device of the given
+ * NPU. Returns the linked pci device if pci_dev != NULL.
+ */
+static struct pnv_ioda_pe *get_gpu_pci_dev_and_pe(struct pnv_ioda_pe *npe,
+						  struct pci_dev **gpdev)
+{
+	struct pnv_phb *phb;
+	struct pci_controller *hose;
+	struct pci_dev *pdev;
+	struct pnv_ioda_pe *pe;
+	struct pci_dn *pdn;
+
+	if (npe->flags & PNV_IODA_PE_PEER) {
+		pe = npe->peers[0];
+		pdev = pe->pdev;
+	} else {
+		pdev = pnv_pci_get_gpu_dev(npe->pdev);
+		if (!pdev)
+			return NULL;
+
+		pdn = pci_get_pdn(pdev);
+		if (WARN_ON(!pdn || pdn->pe_number == IODA_INVALID_PE))
+			return NULL;
+
+		hose = pci_bus_to_host(pdev->bus);
+		phb = hose->private_data;
+		pe = &phb->ioda.pe_array[pdn->pe_number];
+	}
+
+	if (gpdev)
+		*gpdev = pdev;
+
+	return pe;
+}
+
+void pnv_npu_tce_invalidate_entire(struct pnv_ioda_pe *npe)
+{
+	struct pnv_phb *phb = npe->phb;
+
+	if (WARN_ON(phb->type != PNV_PHB_NPU ||
+		    !phb->ioda.tce_inval_reg ||
+		    !(npe->flags & PNV_IODA_PE_DEV)))
+		return;
+
+	mb(); /* Ensure previous TCE table stores are visible */
+	__raw_writeq(cpu_to_be64(TCE_KILL_INVAL_ALL),
+		phb->ioda.tce_inval_reg);
+}
+
+void pnv_npu_tce_invalidate(struct pnv_ioda_pe *npe,
+				struct iommu_table *tbl,
+				unsigned long index,
+				unsigned long npages,
+				bool rm)
+{
+	struct pnv_phb *phb = npe->phb;
+
+	/* We can only invalidate the whole cache on NPU */
+	unsigned long val = TCE_KILL_INVAL_ALL;
+
+	if (WARN_ON(phb->type != PNV_PHB_NPU ||
+		    !phb->ioda.tce_inval_reg ||
+		    !(npe->flags & PNV_IODA_PE_DEV)))
+		return;
+
+	mb(); /* Ensure previous TCE table stores are visible */
+	if (rm)
+		__raw_rm_writeq(cpu_to_be64(val),
+		  (__be64 __iomem *) phb->ioda.tce_inval_reg_phys);
+	else
+		__raw_writeq(cpu_to_be64(val),
+			phb->ioda.tce_inval_reg);
+}
+
+void pnv_npu_init_dma_pe(struct pnv_ioda_pe *npe)
+{
+	struct pnv_ioda_pe *gpe;
+	struct pci_dev *gpdev;
+	int i, avail = -1;
+
+	if (!npe->pdev || !(npe->flags & PNV_IODA_PE_DEV))
+		return;
+
+	gpe = get_gpu_pci_dev_and_pe(npe, &gpdev);
+	if (!gpe)
+		return;
+
+	for (i = 0; i < PNV_IODA_MAX_PEER_PES; i++) {
+		/* Nothing to do if the PE is already connected. */
+		if (gpe->peers[i] == npe)
+			return;
+
+		if (!gpe->peers[i])
+			avail = i;
+	}
+
+	if (WARN_ON(avail < 0))
+		return;
+
+	gpe->peers[avail] = npe;
+	gpe->flags |= PNV_IODA_PE_PEER;
+
+	/*
+	 * We assume that the NPU devices only have a single peer PE
+	 * (the GPU PCIe device PE).
+	 */
+	npe->peers[0] = gpe;
+	npe->flags |= PNV_IODA_PE_PEER;
+}
+
+/*
+ * For the NPU we want to point the TCE table at the same table as the
+ * real PCI device.
+ */
+static void pnv_npu_disable_bypass(struct pnv_ioda_pe *npe)
+{
+	struct pnv_phb *phb = npe->phb;
+	struct pci_dev *gpdev;
+	struct pnv_ioda_pe *gpe;
+	void *addr;
+	unsigned int size;
+	int64_t rc;
+
+	/*
+	 * Find the assoicated PCI devices and get the dma window
+	 * information from there.
+	 */
+	if (!npe->pdev || !(npe->flags & PNV_IODA_PE_DEV))
+		return;
+
+	gpe = get_gpu_pci_dev_and_pe(npe, &gpdev);
+	if (!gpe)
+		return;
+
+	addr = (void *)gpe->table_group.tables[0]->it_base;
+	size = gpe->table_group.tables[0]->it_size << 3;
+	rc = opal_pci_map_pe_dma_window(phb->opal_id, npe->pe_number,
+					npe->pe_number, 1, __pa(addr),
+					size, 0x1000);
+	if (rc != OPAL_SUCCESS)
+		pr_warn("%s: Error %lld setting DMA window on PHB#%d-PE#%d\n",
+			__func__, rc, phb->hose->global_number, npe->pe_number);
+
+	/*
+	 * We don't initialise npu_pe->tce32_table as we always use
+	 * dma_npu_ops which are nops.
+	 */
+	set_dma_ops(&npe->pdev->dev, &dma_npu_ops);
+}
+
+/*
+ * Enable/disable bypass mode on the NPU. The NPU only supports one
+ * window per link, so bypass needs to be explicity enabled or
+ * disabled. Unlike for a PHB3 bypass and non-bypass modes can't be
+ * active at the same time.
+ */
+int pnv_npu_dma_set_bypass(struct pnv_ioda_pe *npe, bool enable)
+{
+	struct pnv_phb *phb = npe->phb;
+	int64_t rc = 0;
+
+	if (phb->type != PNV_PHB_NPU || !npe->pdev)
+		return -EINVAL;
+
+	if (enable) {
+		/* Enable the bypass window */
+		phys_addr_t top = memblock_end_of_DRAM();
+
+		npe->tce_bypass_base = 0;
+		top = roundup_pow_of_two(top);
+		dev_info(&npe->pdev->dev, "Enabling bypass for PE %d\n",
+			 npe->pe_number);
+		rc = opal_pci_map_pe_dma_window_real(phb->opal_id,
+					npe->pe_number, npe->pe_number,
+					npe->tce_bypass_base, top);
+	} else {
+		/*
+		 * Disable the bypass window by replacing it with the
+		 * TCE32 window.
+		 */
+		pnv_npu_disable_bypass(npe);
+	}
+
+	return rc;
+}
+
+int pnv_npu_dma_set_mask(struct pci_dev *npdev, u64 dma_mask)
+{
+	struct pci_controller *hose = pci_bus_to_host(npdev->bus);
+	struct pnv_phb *phb = hose->private_data;
+	struct pci_dn *pdn = pci_get_pdn(npdev);
+	struct pnv_ioda_pe *npe, *gpe;
+	struct pci_dev *gpdev;
+	uint64_t top;
+	bool bypass = false;
+
+	if (WARN_ON(!pdn || pdn->pe_number == IODA_INVALID_PE))
+		return -ENXIO;
+
+	/* We only do bypass if it's enabled on the linked device */
+	npe = &phb->ioda.pe_array[pdn->pe_number];
+	gpe = get_gpu_pci_dev_and_pe(npe, &gpdev);
+	if (!gpe)
+		return -ENODEV;
+
+	if (gpe->tce_bypass_enabled) {
+		top = gpe->tce_bypass_base + memblock_end_of_DRAM() - 1;
+		bypass = (dma_mask >= top);
+	}
+
+	if (bypass)
+		dev_info(&npdev->dev, "Using 64-bit DMA iommu bypass\n");
+	else
+		dev_info(&npdev->dev, "Using 32-bit DMA via iommu\n");
+
+	pnv_npu_dma_set_bypass(npe, bypass);
+	*npdev->dev.dma_mask = dma_mask;
+
+	return 0;
+}
--- zfcpdump-kernel-4.4.orig/arch/powerpc/platforms/powernv/opal-dump.c
+++ zfcpdump-kernel-4.4/arch/powerpc/platforms/powernv/opal-dump.c
@@ -370,6 +370,7 @@ static irqreturn_t process_dump(int irq,
 	uint32_t dump_id, dump_size, dump_type;
 	struct dump_obj *dump;
 	char name[22];
+	struct kobject *kobj;
 
 	rc = dump_read_info(&dump_id, &dump_size, &dump_type);
 	if (rc != OPAL_SUCCESS)
@@ -381,8 +382,12 @@ static irqreturn_t process_dump(int irq,
 	 * that gracefully and not create two conflicting
 	 * entries.
 	 */
-	if (kset_find_obj(dump_kset, name))
+	kobj = kset_find_obj(dump_kset, name);
+	if (kobj) {
+		/* Drop reference added by kset_find_obj() */
+		kobject_put(kobj);
 		return 0;
+	}
 
 	dump = create_dump_obj(dump_id, dump_size, dump_type);
 	if (!dump)
--- zfcpdump-kernel-4.4.orig/arch/powerpc/platforms/powernv/opal-elog.c
+++ zfcpdump-kernel-4.4/arch/powerpc/platforms/powernv/opal-elog.c
@@ -247,6 +247,7 @@ static irqreturn_t elog_event(int irq, v
 	uint64_t elog_type;
 	int rc;
 	char name[2+16+1];
+	struct kobject *kobj;
 
 	rc = opal_get_elog_size(&id, &size, &type);
 	if (rc != OPAL_SUCCESS) {
@@ -269,8 +270,12 @@ static irqreturn_t elog_event(int irq, v
 	 * that gracefully and not create two conflicting
 	 * entries.
 	 */
-	if (kset_find_obj(elog_kset, name))
+	kobj = kset_find_obj(elog_kset, name);
+	if (kobj) {
+		/* Drop reference added by kset_find_obj() */
+		kobject_put(kobj);
 		return IRQ_HANDLED;
+	}
 
 	create_elog_obj(log_id, elog_size, elog_type);
 
--- /dev/null
+++ zfcpdump-kernel-4.4/arch/powerpc/platforms/powernv/opal-kmsg.c
@@ -0,0 +1,75 @@
+/*
+ * kmsg dumper that ensures the OPAL console fully flushes panic messages
+ *
+ * Author: Russell Currey <ruscur@russell.cc>
+ *
+ * Copyright 2015 IBM Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/kmsg_dump.h>
+
+#include <asm/opal.h>
+#include <asm/opal-api.h>
+
+/*
+ * Console output is controlled by OPAL firmware.  The kernel regularly calls
+ * OPAL_POLL_EVENTS, which flushes some console output.  In a panic state,
+ * however, the kernel no longer calls OPAL_POLL_EVENTS and the panic message
+ * may not be completely printed.  This function does not actually dump the
+ * message, it just ensures that OPAL completely flushes the console buffer.
+ */
+static void force_opal_console_flush(struct kmsg_dumper *dumper,
+				     enum kmsg_dump_reason reason)
+{
+	int i;
+	int64_t ret;
+
+	/*
+	 * Outside of a panic context the pollers will continue to run,
+	 * so we don't need to do any special flushing.
+	 */
+	if (reason != KMSG_DUMP_PANIC)
+		return;
+
+	if (opal_check_token(OPAL_CONSOLE_FLUSH)) {
+		ret = opal_console_flush(0);
+
+		if (ret == OPAL_UNSUPPORTED || ret == OPAL_PARAMETER)
+			return;
+
+		/* Incrementally flush until there's nothing left */
+		while (opal_console_flush(0) != OPAL_SUCCESS);
+	} else {
+		/*
+		 * If OPAL_CONSOLE_FLUSH is not implemented in the firmware,
+		 * the console can still be flushed by calling the polling
+		 * function enough times to flush the buffer.  We don't know
+		 * how much output still needs to be flushed, but we can be
+		 * generous since the kernel is in panic and doesn't need
+		 * to do much else.
+		 */
+		printk(KERN_NOTICE "opal: OPAL_CONSOLE_FLUSH missing.\n");
+		for (i = 0; i < 1024; i++) {
+			opal_poll_events(NULL);
+		}
+	}
+}
+
+static struct kmsg_dumper opal_kmsg_dumper = {
+	.dump = force_opal_console_flush
+};
+
+void __init opal_kmsg_init(void)
+{
+	int rc;
+
+	/* Add our dumper to the list */
+	rc = kmsg_dump_register(&opal_kmsg_dumper);
+	if (rc != 0)
+		pr_err("opal: kmsg_dump_register failed; returned %d\n", rc);
+}
--- zfcpdump-kernel-4.4.orig/arch/powerpc/platforms/powernv/opal-wrappers.S
+++ zfcpdump-kernel-4.4/arch/powerpc/platforms/powernv/opal-wrappers.S
@@ -64,7 +64,6 @@ END_FTR_SECTION(0, 1);						\
 	OPAL_BRANCH(opal_tracepoint_entry) \
 	mfcr	r12;			\
 	stw	r12,8(r1);		\
-	std	r1,PACAR1(r13);		\
 	li	r11,0;			\
 	mfmsr	r12;			\
 	ori	r11,r11,MSR_EE;		\
@@ -127,7 +126,6 @@ opal_tracepoint_entry:
 	mfcr	r12
 	std	r11,16(r1)
 	stw	r12,8(r1)
-	std	r1,PACAR1(r13)
 	li	r11,0
 	mfmsr	r12
 	ori	r11,r11,MSR_EE
@@ -301,3 +299,4 @@ OPAL_CALL(opal_flash_erase,			OPAL_FLASH
 OPAL_CALL(opal_prd_msg,				OPAL_PRD_MSG);
 OPAL_CALL(opal_leds_get_ind,			OPAL_LEDS_GET_INDICATOR);
 OPAL_CALL(opal_leds_set_ind,			OPAL_LEDS_SET_INDICATOR);
+OPAL_CALL(opal_console_flush,			OPAL_CONSOLE_FLUSH);
--- zfcpdump-kernel-4.4.orig/arch/powerpc/platforms/powernv/opal.c
+++ zfcpdump-kernel-4.4/arch/powerpc/platforms/powernv/opal.c
@@ -758,6 +758,9 @@ static int __init opal_init(void)
 	opal_pdev_init(opal_node, "ibm,opal-flash");
 	opal_pdev_init(opal_node, "ibm,opal-prd");
 
+	/* Initialise OPAL kmsg dumper for flushing console on panic */
+	opal_kmsg_init();
+
 	return 0;
 }
 machine_subsys_initcall(powernv, opal_init);
--- zfcpdump-kernel-4.4.orig/arch/powerpc/platforms/powernv/pci-ioda.c
+++ zfcpdump-kernel-4.4/arch/powerpc/platforms/powernv/pci-ioda.c
@@ -116,16 +116,6 @@ static int __init iommu_setup(char *str)
 }
 early_param("iommu", iommu_setup);
 
-/*
- * stdcix is only supposed to be used in hypervisor real mode as per
- * the architecture spec
- */
-static inline void __raw_rm_writeq(u64 val, volatile void __iomem *paddr)
-{
-	__asm__ __volatile__("stdcix %0,0,%1"
-		: : "r" (val), "r" (paddr) : "memory");
-}
-
 static inline bool pnv_pci_is_mem_pref_64(unsigned long flags)
 {
 	return ((flags & (IORESOURCE_MEM_64 | IORESOURCE_PREFETCH)) ==
@@ -780,8 +770,12 @@ static int pnv_ioda_configure_pe(struct
 		return -ENXIO;
 	}
 
-	/* Configure PELTV */
-	pnv_ioda_set_peltv(phb, pe, true);
+	/*
+	 * Configure PELTV. NPUs don't have a PELTV table so skip
+	 * configuration on them.
+	 */
+	if (phb->type != PNV_PHB_NPU)
+		pnv_ioda_set_peltv(phb, pe, true);
 
 	/* Setup reverse map */
 	for (rid = pe->rid; rid < rid_end; rid++)
@@ -924,7 +918,6 @@ static int pnv_pci_vf_resource_shift(str
 }
 #endif /* CONFIG_PCI_IOV */
 
-#if 0
 static struct pnv_ioda_pe *pnv_ioda_setup_dev_PE(struct pci_dev *dev)
 {
 	struct pci_controller *hose = pci_bus_to_host(dev->bus);
@@ -941,11 +934,7 @@ static struct pnv_ioda_pe *pnv_ioda_setu
 	if (pdn->pe_number != IODA_INVALID_PE)
 		return NULL;
 
-	/* PE#0 has been pre-set */
-	if (dev->bus->number == 0)
-		pe_num = 0;
-	else
-		pe_num = pnv_ioda_alloc_pe(phb);
+	pe_num = pnv_ioda_alloc_pe(phb);
 	if (pe_num == IODA_INVALID_PE) {
 		pr_warning("%s: Not enough PE# available, disabling device\n",
 			   pci_name(dev));
@@ -963,6 +952,7 @@ static struct pnv_ioda_pe *pnv_ioda_setu
 	pci_dev_get(dev);
 	pdn->pcidev = dev;
 	pdn->pe_number = pe_num;
+	pe->flags = PNV_IODA_PE_DEV;
 	pe->pdev = dev;
 	pe->pbus = NULL;
 	pe->tce32_seg = -1;
@@ -993,7 +983,6 @@ static struct pnv_ioda_pe *pnv_ioda_setu
 
 	return pe;
 }
-#endif /* Useful for SRIOV case */
 
 static void pnv_ioda_setup_same_PE(struct pci_bus *bus, struct pnv_ioda_pe *pe)
 {
@@ -1007,6 +996,7 @@ static void pnv_ioda_setup_same_PE(struc
 				pci_name(dev));
 			continue;
 		}
+		pdn->pcidev = dev;
 		pdn->pe_number = pe->pe_number;
 		pe->dma_weight += pnv_ioda_dma_weight(dev);
 		if ((pe->flags & PNV_IODA_PE_BUS_ALL) && dev->subordinate)
@@ -1083,6 +1073,77 @@ static void pnv_ioda_setup_bus_PE(struct
 	pnv_ioda_link_pe_by_weight(phb, pe);
 }
 
+static struct pnv_ioda_pe *pnv_ioda_setup_npu_PE(struct pci_dev *npu_pdev)
+{
+	int pe_num, found_pe = false, rc;
+	long rid;
+	struct pnv_ioda_pe *pe;
+	struct pci_dev *gpu_pdev;
+	struct pci_dn *npu_pdn;
+	struct pci_controller *hose = pci_bus_to_host(npu_pdev->bus);
+	struct pnv_phb *phb = hose->private_data;
+
+	/*
+	 * Due to a hardware errata PE#0 on the NPU is reserved for
+	 * error handling. This means we only have three PEs remaining
+	 * which need to be assigned to four links, implying some
+	 * links must share PEs.
+	 *
+	 * To achieve this we assign PEs such that NPUs linking the
+	 * same GPU get assigned the same PE.
+	 */
+	gpu_pdev = pnv_pci_get_gpu_dev(npu_pdev);
+	for (pe_num = 0; pe_num < phb->ioda.total_pe; pe_num++) {
+		pe = &phb->ioda.pe_array[pe_num];
+		if (!pe->pdev)
+			continue;
+
+		if (pnv_pci_get_gpu_dev(pe->pdev) == gpu_pdev) {
+			/*
+			 * This device has the same peer GPU so should
+			 * be assigned the same PE as the existing
+			 * peer NPU.
+			 */
+			dev_info(&npu_pdev->dev,
+				"Associating to existing PE %d\n", pe_num);
+			pci_dev_get(npu_pdev);
+			npu_pdn = pci_get_pdn(npu_pdev);
+			rid = npu_pdev->bus->number << 8 | npu_pdn->devfn;
+			npu_pdn->pcidev = npu_pdev;
+			npu_pdn->pe_number = pe_num;
+			pe->dma_weight += pnv_ioda_dma_weight(npu_pdev);
+			phb->ioda.pe_rmap[rid] = pe->pe_number;
+
+			/* Map the PE to this link */
+			rc = opal_pci_set_pe(phb->opal_id, pe_num, rid,
+					OpalPciBusAll,
+					OPAL_COMPARE_RID_DEVICE_NUMBER,
+					OPAL_COMPARE_RID_FUNCTION_NUMBER,
+					OPAL_MAP_PE);
+			WARN_ON(rc != OPAL_SUCCESS);
+			found_pe = true;
+			break;
+		}
+	}
+
+	if (!found_pe)
+		/*
+		 * Could not find an existing PE so allocate a new
+		 * one.
+		 */
+		return pnv_ioda_setup_dev_PE(npu_pdev);
+	else
+		return pe;
+}
+
+static void pnv_ioda_setup_npu_PEs(struct pci_bus *bus)
+{
+	struct pci_dev *pdev;
+
+	list_for_each_entry(pdev, &bus->devices, bus_list)
+		pnv_ioda_setup_npu_PE(pdev);
+}
+
 static void pnv_ioda_setup_PEs(struct pci_bus *bus)
 {
 	struct pci_dev *dev;
@@ -1119,7 +1180,17 @@ static void pnv_pci_ioda_setup_PEs(void)
 		if (phb->reserve_m64_pe)
 			phb->reserve_m64_pe(hose->bus, NULL, true);
 
-		pnv_ioda_setup_PEs(hose->bus);
+		/*
+		 * On NPU PHB, we expect separate PEs for individual PCI
+		 * functions. PCI bus dependent PEs are required for the
+		 * remaining types of PHBs.
+		 */
+		if (phb->type == PNV_PHB_NPU) {
+			/* PE#0 is needed for error reporting */
+			pnv_ioda_reserve_pe(phb, 0);
+			pnv_ioda_setup_npu_PEs(hose->bus);
+		} else
+			pnv_ioda_setup_PEs(hose->bus);
 	}
 }
 
@@ -1578,6 +1649,8 @@ static int pnv_pci_ioda_dma_set_mask(str
 	struct pnv_ioda_pe *pe;
 	uint64_t top;
 	bool bypass = false;
+	struct pci_dev *linked_npu_dev;
+	int i;
 
 	if (WARN_ON(!pdn || pdn->pe_number == IODA_INVALID_PE))
 		return -ENODEV;;
@@ -1596,6 +1669,18 @@ static int pnv_pci_ioda_dma_set_mask(str
 		set_dma_ops(&pdev->dev, &dma_iommu_ops);
 	}
 	*pdev->dev.dma_mask = dma_mask;
+
+	/* Update peer npu devices */
+	if (pe->flags & PNV_IODA_PE_PEER)
+		for (i = 0; i < PNV_IODA_MAX_PEER_PES; i++) {
+			if (!pe->peers[i])
+				continue;
+
+			linked_npu_dev = pe->peers[i]->pdev;
+			if (dma_get_mask(&linked_npu_dev->dev) != dma_mask)
+				dma_set_mask(&linked_npu_dev->dev, dma_mask);
+		}
+
 	return 0;
 }
 
@@ -1740,12 +1825,23 @@ static inline void pnv_pci_ioda2_tce_inv
 	/* 01xb - invalidate TCEs that match the specified PE# */
 	unsigned long val = (0x4ull << 60) | (pe->pe_number & 0xFF);
 	struct pnv_phb *phb = pe->phb;
+	struct pnv_ioda_pe *npe;
+	int i;
 
 	if (!phb->ioda.tce_inval_reg)
 		return;
 
 	mb(); /* Ensure above stores are visible */
 	__raw_writeq(cpu_to_be64(val), phb->ioda.tce_inval_reg);
+
+	if (pe->flags & PNV_IODA_PE_PEER)
+		for (i = 0; i < PNV_IODA_MAX_PEER_PES; i++) {
+			npe = pe->peers[i];
+			if (!npe || npe->phb->type != PNV_PHB_NPU)
+				continue;
+
+			pnv_npu_tce_invalidate_entire(npe);
+		}
 }
 
 static void pnv_pci_ioda2_do_tce_invalidate(unsigned pe_number, bool rm,
@@ -1780,15 +1876,28 @@ static void pnv_pci_ioda2_tce_invalidate
 	struct iommu_table_group_link *tgl;
 
 	list_for_each_entry_rcu(tgl, &tbl->it_group_list, next) {
+		struct pnv_ioda_pe *npe;
 		struct pnv_ioda_pe *pe = container_of(tgl->table_group,
 				struct pnv_ioda_pe, table_group);
 		__be64 __iomem *invalidate = rm ?
 			(__be64 __iomem *)pe->phb->ioda.tce_inval_reg_phys :
 			pe->phb->ioda.tce_inval_reg;
+		int i;
 
 		pnv_pci_ioda2_do_tce_invalidate(pe->pe_number, rm,
 			invalidate, tbl->it_page_shift,
 			index, npages);
+
+		if (pe->flags & PNV_IODA_PE_PEER)
+			/* Invalidate PEs using the same TCE table */
+			for (i = 0; i < PNV_IODA_MAX_PEER_PES; i++) {
+				npe = pe->peers[i];
+				if (!npe || npe->phb->type != PNV_PHB_NPU)
+					continue;
+
+				pnv_npu_tce_invalidate(npe, tbl, index,
+							npages, rm);
+			}
 	}
 }
 
@@ -2436,10 +2545,17 @@ static void pnv_ioda_setup_dma(struct pn
 			pe_info(pe, "DMA weight %d, assigned %d DMA32 segments\n",
 				pe->dma_weight, segs);
 			pnv_pci_ioda_setup_dma_pe(phb, pe, base, segs);
-		} else {
+		} else if (phb->type == PNV_PHB_IODA2) {
 			pe_info(pe, "Assign DMA32 space\n");
 			segs = 0;
 			pnv_pci_ioda2_setup_dma_pe(phb, pe);
+		} else if (phb->type == PNV_PHB_NPU) {
+			/*
+			 * We initialise the DMA space for an NPU PHB
+			 * after setup of the PHB is complete as we
+			 * point the NPU TVT to the the same location
+			 * as the PHB3 TVT.
+			 */
 		}
 
 		remaining -= segs;
@@ -2881,6 +2997,11 @@ static void pnv_pci_ioda_setup_seg(void)
 
 	list_for_each_entry_safe(hose, tmp, &hose_list, list_node) {
 		phb = hose->private_data;
+
+		/* NPU PHB does not support IO or MMIO segmentation */
+		if (phb->type == PNV_PHB_NPU)
+			continue;
+
 		list_for_each_entry(pe, &phb->ioda.pe_list, list) {
 			pnv_ioda_setup_pe_seg(hose, pe);
 		}
@@ -2920,6 +3041,27 @@ static void pnv_pci_ioda_create_dbgfs(vo
 #endif /* CONFIG_DEBUG_FS */
 }
 
+static void pnv_npu_ioda_fixup(void)
+{
+	bool enable_bypass;
+	struct pci_controller *hose, *tmp;
+	struct pnv_phb *phb;
+	struct pnv_ioda_pe *pe;
+
+	list_for_each_entry_safe(hose, tmp, &hose_list, list_node) {
+		phb = hose->private_data;
+		if (phb->type != PNV_PHB_NPU)
+			continue;
+
+		list_for_each_entry(pe, &phb->ioda.pe_dma_list, dma_link) {
+			enable_bypass = dma_get_mask(&pe->pdev->dev) ==
+				DMA_BIT_MASK(64);
+			pnv_npu_init_dma_pe(pe);
+			pnv_npu_dma_set_bypass(pe, enable_bypass);
+		}
+	}
+}
+
 static void pnv_pci_ioda_fixup(void)
 {
 	pnv_pci_ioda_setup_PEs();
@@ -2932,6 +3074,9 @@ static void pnv_pci_ioda_fixup(void)
 	eeh_init();
 	eeh_addr_cache_build();
 #endif
+
+	/* Link NPU IODA tables to their PCI devices. */
+	pnv_npu_ioda_fixup();
 }
 
 /*
@@ -3034,6 +3179,7 @@ static void pnv_pci_ioda_shutdown(struct
 
 static const struct pci_controller_ops pnv_pci_ioda_controller_ops = {
        .dma_dev_setup = pnv_pci_dma_dev_setup,
+       .dma_bus_setup = pnv_pci_dma_bus_setup,
 #ifdef CONFIG_PCI_MSI
        .setup_msi_irqs = pnv_setup_msi_irqs,
        .teardown_msi_irqs = pnv_teardown_msi_irqs,
@@ -3046,6 +3192,19 @@ static const struct pci_controller_ops p
        .shutdown = pnv_pci_ioda_shutdown,
 };
 
+static const struct pci_controller_ops pnv_npu_ioda_controller_ops = {
+	.dma_dev_setup = pnv_pci_dma_dev_setup,
+#ifdef CONFIG_PCI_MSI
+	.setup_msi_irqs = pnv_setup_msi_irqs,
+	.teardown_msi_irqs = pnv_teardown_msi_irqs,
+#endif
+	.enable_device_hook = pnv_pci_enable_device_hook,
+	.window_alignment = pnv_pci_window_alignment,
+	.reset_secondary_bus = pnv_pci_reset_secondary_bus,
+	.dma_set_mask = pnv_npu_dma_set_mask,
+	.shutdown = pnv_pci_ioda_shutdown,
+};
+
 static void __init pnv_pci_init_ioda_phb(struct device_node *np,
 					 u64 hub_id, int ioda_type)
 {
@@ -3101,6 +3260,8 @@ static void __init pnv_pci_init_ioda_phb
 		phb->model = PNV_PHB_MODEL_P7IOC;
 	else if (of_device_is_compatible(np, "ibm,power8-pciex"))
 		phb->model = PNV_PHB_MODEL_PHB3;
+	else if (of_device_is_compatible(np, "ibm,power8-npu-pciex"))
+		phb->model = PNV_PHB_MODEL_NPU;
 	else
 		phb->model = PNV_PHB_MODEL_UNKNOWN;
 
@@ -3201,7 +3362,11 @@ static void __init pnv_pci_init_ioda_phb
 	 * the child P2P bridges) can form individual PE.
 	 */
 	ppc_md.pcibios_fixup = pnv_pci_ioda_fixup;
-	hose->controller_ops = pnv_pci_ioda_controller_ops;
+
+	if (phb->type == PNV_PHB_NPU)
+		hose->controller_ops = pnv_npu_ioda_controller_ops;
+	else
+		hose->controller_ops = pnv_pci_ioda_controller_ops;
 
 #ifdef CONFIG_PCI_IOV
 	ppc_md.pcibios_fixup_sriov = pnv_pci_ioda_fixup_iov_resources;
@@ -3236,6 +3401,11 @@ void __init pnv_pci_init_ioda2_phb(struc
 	pnv_pci_init_ioda_phb(np, 0, PNV_PHB_IODA2);
 }
 
+void __init pnv_pci_init_npu_phb(struct device_node *np)
+{
+	pnv_pci_init_ioda_phb(np, 0, PNV_PHB_NPU);
+}
+
 void __init pnv_pci_init_ioda_hub(struct device_node *np)
 {
 	struct device_node *phbn;
--- zfcpdump-kernel-4.4.orig/arch/powerpc/platforms/powernv/pci.c
+++ zfcpdump-kernel-4.4/arch/powerpc/platforms/powernv/pci.c
@@ -601,6 +601,9 @@ int pnv_tce_build(struct iommu_table *tb
 	u64 rpn = __pa(uaddr) >> tbl->it_page_shift;
 	long i;
 
+	if (proto_tce & TCE_PCI_WRITE)
+		proto_tce |= TCE_PCI_READ;
+
 	for (i = 0; i < npages; i++) {
 		unsigned long newtce = proto_tce |
 			((rpn + i) << tbl->it_page_shift);
@@ -622,6 +625,9 @@ int pnv_tce_xchg(struct iommu_table *tbl
 
 	BUG_ON(*hpa & ~IOMMU_PAGE_MASK(tbl));
 
+	if (newtce & TCE_PCI_WRITE)
+		newtce |= TCE_PCI_READ;
+
 	oldtce = xchg(pnv_tce(tbl, idx), cpu_to_be64(newtce));
 	*hpa = be64_to_cpu(oldtce) & ~(TCE_PCI_READ | TCE_PCI_WRITE);
 	*direction = iommu_tce_direction(oldtce);
@@ -762,6 +768,26 @@ void pnv_pci_dma_dev_setup(struct pci_de
 		phb->dma_dev_setup(phb, pdev);
 }
 
+void pnv_pci_dma_bus_setup(struct pci_bus *bus)
+{
+	struct pci_controller *hose = bus->sysdata;
+	struct pnv_phb *phb = hose->private_data;
+	struct pnv_ioda_pe *pe;
+
+	list_for_each_entry(pe, &phb->ioda.pe_list, list) {
+		if (!(pe->flags & (PNV_IODA_PE_BUS | PNV_IODA_PE_BUS_ALL)))
+			continue;
+
+		if (!pe->pbus)
+			continue;
+
+		if (bus->number == ((pe->rid >> 8) & 0xFF)) {
+			pe->pbus = bus;
+			break;
+		}
+	}
+}
+
 void pnv_pci_shutdown(void)
 {
 	struct pci_controller *hose;
@@ -807,6 +833,10 @@ void __init pnv_pci_init(void)
 	for_each_compatible_node(np, NULL, "ibm,ioda2-phb")
 		pnv_pci_init_ioda2_phb(np);
 
+	/* Look for NPU PHBs */
+	for_each_compatible_node(np, NULL, "ibm,ioda2-npu-phb")
+		pnv_pci_init_npu_phb(np);
+
 	/* Setup the linkage between OF nodes and PHBs */
 	pci_devs_phb_init();
 
--- zfcpdump-kernel-4.4.orig/arch/powerpc/platforms/powernv/pci.h
+++ zfcpdump-kernel-4.4/arch/powerpc/platforms/powernv/pci.h
@@ -7,6 +7,7 @@ enum pnv_phb_type {
 	PNV_PHB_P5IOC2	= 0,
 	PNV_PHB_IODA1	= 1,
 	PNV_PHB_IODA2	= 2,
+	PNV_PHB_NPU	= 3,
 };
 
 /* Precise PHB model for error management */
@@ -15,6 +16,7 @@ enum pnv_phb_model {
 	PNV_PHB_MODEL_P5IOC2,
 	PNV_PHB_MODEL_P7IOC,
 	PNV_PHB_MODEL_PHB3,
+	PNV_PHB_MODEL_NPU,
 };
 
 #define PNV_PCI_DIAG_BUF_SIZE	8192
@@ -24,6 +26,7 @@ enum pnv_phb_model {
 #define PNV_IODA_PE_MASTER	(1 << 3)	/* Master PE in compound case	*/
 #define PNV_IODA_PE_SLAVE	(1 << 4)	/* Slave PE in compound case	*/
 #define PNV_IODA_PE_VF		(1 << 5)	/* PE for one VF 		*/
+#define PNV_IODA_PE_PEER	(1 << 6)	/* PE has peers			*/
 
 /* Data associated with a PE, including IOMMU tracking etc.. */
 struct pnv_phb;
@@ -31,6 +34,9 @@ struct pnv_ioda_pe {
 	unsigned long		flags;
 	struct pnv_phb		*phb;
 
+#define PNV_IODA_MAX_PEER_PES	8
+	struct pnv_ioda_pe	*peers[PNV_IODA_MAX_PEER_PES];
+
 	/* A PE can be associated with a single device or an
 	 * entire bus (& children). In the former case, pdev
 	 * is populated, in the later case, pbus is.
@@ -229,13 +235,27 @@ extern void pnv_pci_setup_iommu_table(st
 extern void pnv_pci_init_p5ioc2_hub(struct device_node *np);
 extern void pnv_pci_init_ioda_hub(struct device_node *np);
 extern void pnv_pci_init_ioda2_phb(struct device_node *np);
+extern void pnv_pci_init_npu_phb(struct device_node *np);
 extern void pnv_pci_ioda_tce_invalidate(struct iommu_table *tbl,
 					__be64 *startp, __be64 *endp, bool rm);
 extern void pnv_pci_reset_secondary_bus(struct pci_dev *dev);
 extern int pnv_eeh_phb_reset(struct pci_controller *hose, int option);
 
 extern void pnv_pci_dma_dev_setup(struct pci_dev *pdev);
+extern void pnv_pci_dma_bus_setup(struct pci_bus *bus);
 extern int pnv_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type);
 extern void pnv_teardown_msi_irqs(struct pci_dev *pdev);
 
+/* Nvlink functions */
+extern void pnv_npu_tce_invalidate_entire(struct pnv_ioda_pe *npe);
+extern void pnv_npu_tce_invalidate(struct pnv_ioda_pe *npe,
+				       struct iommu_table *tbl,
+				       unsigned long index,
+				       unsigned long npages,
+				       bool rm);
+extern void pnv_npu_init_dma_pe(struct pnv_ioda_pe *npe);
+extern void pnv_npu_setup_dma_pe(struct pnv_ioda_pe *npe);
+extern int pnv_npu_dma_set_bypass(struct pnv_ioda_pe *npe, bool enabled);
+extern int pnv_npu_dma_set_mask(struct pci_dev *npdev, u64 dma_mask);
+
 #endif /* __POWERNV_PCI_H */
--- zfcpdump-kernel-4.4.orig/arch/powerpc/platforms/pseries/eeh_pseries.c
+++ zfcpdump-kernel-4.4/arch/powerpc/platforms/pseries/eeh_pseries.c
@@ -615,29 +615,50 @@ static int pseries_eeh_configure_bridge(
 {
 	int config_addr;
 	int ret;
+	/* Waiting 0.2s maximum before skipping configuration */
+	int max_wait = 200;
 
 	/* Figure out the PE address */
 	config_addr = pe->config_addr;
 	if (pe->addr)
 		config_addr = pe->addr;
 
-	/* Use new configure-pe function, if supported */
-	if (ibm_configure_pe != RTAS_UNKNOWN_SERVICE) {
-		ret = rtas_call(ibm_configure_pe, 3, 1, NULL,
-				config_addr, BUID_HI(pe->phb->buid),
-				BUID_LO(pe->phb->buid));
-	} else if (ibm_configure_bridge != RTAS_UNKNOWN_SERVICE) {
-		ret = rtas_call(ibm_configure_bridge, 3, 1, NULL,
-				config_addr, BUID_HI(pe->phb->buid),
-				BUID_LO(pe->phb->buid));
-	} else {
-		return -EFAULT;
-	}
+	while (max_wait > 0) {
+		/* Use new configure-pe function, if supported */
+		if (ibm_configure_pe != RTAS_UNKNOWN_SERVICE) {
+			ret = rtas_call(ibm_configure_pe, 3, 1, NULL,
+					config_addr, BUID_HI(pe->phb->buid),
+					BUID_LO(pe->phb->buid));
+		} else if (ibm_configure_bridge != RTAS_UNKNOWN_SERVICE) {
+			ret = rtas_call(ibm_configure_bridge, 3, 1, NULL,
+					config_addr, BUID_HI(pe->phb->buid),
+					BUID_LO(pe->phb->buid));
+		} else {
+			return -EFAULT;
+		}
+
+		if (!ret)
+			return ret;
+
+		/*
+		 * If RTAS returns a delay value that's above 100ms, cut it
+		 * down to 100ms in case firmware made a mistake.  For more
+		 * on how these delay values work see rtas_busy_delay_time
+		 */
+		if (ret > RTAS_EXTENDED_DELAY_MIN+2 &&
+		    ret <= RTAS_EXTENDED_DELAY_MAX)
+			ret = RTAS_EXTENDED_DELAY_MIN+2;
 
-	if (ret)
-		pr_warn("%s: Unable to configure bridge PHB#%d-PE#%x (%d)\n",
-			__func__, pe->phb->global_number, pe->addr, ret);
+		max_wait -= rtas_busy_delay_time(ret);
+
+		if (max_wait < 0)
+			break;
+
+		rtas_busy_delay(ret);
+	}
 
+	pr_warn("%s: Unable to configure bridge PHB#%d-PE#%x (%d)\n",
+		__func__, pe->phb->global_number, pe->addr, ret);
 	return ret;
 }
 
--- zfcpdump-kernel-4.4.orig/arch/powerpc/platforms/pseries/iommu.c
+++ zfcpdump-kernel-4.4/arch/powerpc/platforms/pseries/iommu.c
@@ -912,7 +912,8 @@ machine_arch_initcall(pseries, find_exis
 static int query_ddw(struct pci_dev *dev, const u32 *ddw_avail,
 			struct ddw_query_response *query)
 {
-	struct eeh_dev *edev;
+	struct device_node *dn;
+	struct pci_dn *pdn;
 	u32 cfg_addr;
 	u64 buid;
 	int ret;
@@ -923,11 +924,10 @@ static int query_ddw(struct pci_dev *dev
 	 * Retrieve them from the pci device, not the node with the
 	 * dma-window property
 	 */
-	edev = pci_dev_to_eeh_dev(dev);
-	cfg_addr = edev->config_addr;
-	if (edev->pe_config_addr)
-		cfg_addr = edev->pe_config_addr;
-	buid = edev->phb->buid;
+	dn = pci_device_to_OF_node(dev);
+	pdn = PCI_DN(dn);
+	buid = pdn->phb->buid;
+	cfg_addr = ((pdn->busno << 16) | (pdn->devfn << 8));
 
 	ret = rtas_call(ddw_avail[0], 3, 5, (u32 *)query,
 		  cfg_addr, BUID_HI(buid), BUID_LO(buid));
@@ -941,7 +941,8 @@ static int create_ddw(struct pci_dev *de
 			struct ddw_create_response *create, int page_shift,
 			int window_shift)
 {
-	struct eeh_dev *edev;
+	struct device_node *dn;
+	struct pci_dn *pdn;
 	u32 cfg_addr;
 	u64 buid;
 	int ret;
@@ -952,11 +953,10 @@ static int create_ddw(struct pci_dev *de
 	 * Retrieve them from the pci device, not the node with the
 	 * dma-window property
 	 */
-	edev = pci_dev_to_eeh_dev(dev);
-	cfg_addr = edev->config_addr;
-	if (edev->pe_config_addr)
-		cfg_addr = edev->pe_config_addr;
-	buid = edev->phb->buid;
+	dn = pci_device_to_OF_node(dev);
+	pdn = PCI_DN(dn);
+	buid = pdn->phb->buid;
+	cfg_addr = ((pdn->busno << 16) | (pdn->devfn << 8));
 
 	do {
 		/* extra outputs are LIOBN and dma-addr (hi, lo) */
--- zfcpdump-kernel-4.4.orig/arch/powerpc/platforms/pseries/lpar.c
+++ zfcpdump-kernel-4.4/arch/powerpc/platforms/pseries/lpar.c
@@ -406,7 +406,7 @@ static void __pSeries_lpar_hugepage_inva
 					     unsigned long *vpn, int count,
 					     int psize, int ssize)
 {
-	unsigned long param[8];
+	unsigned long param[PLPAR_HCALL9_BUFSIZE];
 	int i = 0, pix = 0, rc;
 	unsigned long flags = 0;
 	int lock_tlbie = !mmu_has_feature(MMU_FTR_LOCKLESS_TLBIE);
@@ -523,7 +523,7 @@ static void pSeries_lpar_flush_hash_rang
 	unsigned long flags = 0;
 	struct ppc64_tlb_batch *batch = this_cpu_ptr(&ppc64_tlb_batch);
 	int lock_tlbie = !mmu_has_feature(MMU_FTR_LOCKLESS_TLBIE);
-	unsigned long param[9];
+	unsigned long param[PLPAR_HCALL9_BUFSIZE];
 	unsigned long hash, index, shift, hidx, slot;
 	real_pte_t pte;
 	int psize, ssize;
--- zfcpdump-kernel-4.4.orig/arch/powerpc/platforms/pseries/pci.c
+++ zfcpdump-kernel-4.4/arch/powerpc/platforms/pseries/pci.c
@@ -119,6 +119,10 @@ int pseries_root_bridge_prepare(struct p
 
 	bus = bridge->bus;
 
+	/* Rely on the pcibios_free_controller_deferred() callback. */
+	pci_set_host_bridge_release(bridge, pcibios_free_controller_deferred,
+					(void *) pci_bus_to_host(bus));
+
 	dn = pcibios_get_phb_of_node(bus);
 	if (!dn)
 		return 0;
--- zfcpdump-kernel-4.4.orig/arch/powerpc/platforms/pseries/pci_dlpar.c
+++ zfcpdump-kernel-4.4/arch/powerpc/platforms/pseries/pci_dlpar.c
@@ -138,8 +138,11 @@ int remove_phb_dynamic(struct pci_contro
 		release_resource(res);
 	}
 
-	/* Free pci_controller data structure */
-	pcibios_free_controller(phb);
+	/*
+	 * The pci_controller data structure is freed by
+	 * the pcibios_free_controller_deferred() callback;
+	 * see pseries_root_bridge_prepare().
+	 */
 
 	return 0;
 }
--- zfcpdump-kernel-4.4.orig/arch/powerpc/platforms/pseries/ras.c
+++ zfcpdump-kernel-4.4/arch/powerpc/platforms/pseries/ras.c
@@ -40,6 +40,9 @@ static int ras_check_exception_token;
 #define EPOW_SENSOR_TOKEN	9
 #define EPOW_SENSOR_INDEX	0
 
+/* EPOW events counter variable */
+static int num_epow_events;
+
 static irqreturn_t ras_epow_interrupt(int irq, void *dev_id);
 static irqreturn_t ras_error_interrupt(int irq, void *dev_id);
 
@@ -82,32 +85,30 @@ static void handle_system_shutdown(char
 {
 	switch (event_modifier) {
 	case EPOW_SHUTDOWN_NORMAL:
-		pr_emerg("Firmware initiated power off");
+		pr_emerg("Power off requested\n");
 		orderly_poweroff(true);
 		break;
 
 	case EPOW_SHUTDOWN_ON_UPS:
-		pr_emerg("Loss of power reported by firmware, system is "
-			"running on UPS/battery");
-		pr_emerg("Check RTAS error log for details");
+		pr_emerg("Loss of system power detected. System is running on"
+			 " UPS/battery. Check RTAS error log for details\n");
 		orderly_poweroff(true);
 		break;
 
 	case EPOW_SHUTDOWN_LOSS_OF_CRITICAL_FUNCTIONS:
-		pr_emerg("Loss of system critical functions reported by "
-			"firmware");
-		pr_emerg("Check RTAS error log for details");
+		pr_emerg("Loss of system critical functions detected. Check"
+			 " RTAS error log for details\n");
 		orderly_poweroff(true);
 		break;
 
 	case EPOW_SHUTDOWN_AMBIENT_TEMPERATURE_TOO_HIGH:
-		pr_emerg("Ambient temperature too high reported by firmware");
-		pr_emerg("Check RTAS error log for details");
+		pr_emerg("High ambient temperature detected. Check RTAS"
+			 " error log for details\n");
 		orderly_poweroff(true);
 		break;
 
 	default:
-		pr_err("Unknown power/cooling shutdown event (modifier %d)",
+		pr_err("Unknown power/cooling shutdown event (modifier = %d)\n",
 			event_modifier);
 	}
 }
@@ -145,17 +146,20 @@ static void rtas_parse_epow_errlog(struc
 
 	switch (action_code) {
 	case EPOW_RESET:
-		pr_err("Non critical power or cooling issue cleared");
+		if (num_epow_events) {
+			pr_info("Non critical power/cooling issue cleared\n");
+			num_epow_events--;
+		}
 		break;
 
 	case EPOW_WARN_COOLING:
-		pr_err("Non critical cooling issue reported by firmware");
-		pr_err("Check RTAS error log for details");
+		pr_info("Non-critical cooling issue detected. Check RTAS error"
+			" log for details\n");
 		break;
 
 	case EPOW_WARN_POWER:
-		pr_err("Non critical power issue reported by firmware");
-		pr_err("Check RTAS error log for details");
+		pr_info("Non-critical power issue detected. Check RTAS error"
+			" log for details\n");
 		break;
 
 	case EPOW_SYSTEM_SHUTDOWN:
@@ -163,23 +167,27 @@ static void rtas_parse_epow_errlog(struc
 		break;
 
 	case EPOW_SYSTEM_HALT:
-		pr_emerg("Firmware initiated power off");
+		pr_emerg("Critical power/cooling issue detected. Check RTAS"
+			 " error log for details. Powering off.\n");
 		orderly_poweroff(true);
 		break;
 
 	case EPOW_MAIN_ENCLOSURE:
 	case EPOW_POWER_OFF:
-		pr_emerg("Critical power/cooling issue reported by firmware");
-		pr_emerg("Check RTAS error log for details");
-		pr_emerg("Immediate power off");
+		pr_emerg("System about to lose power. Check RTAS error log "
+			 " for details. Powering off immediately.\n");
 		emergency_sync();
 		kernel_power_off();
 		break;
 
 	default:
-		pr_err("Unknown power/cooling event (action code %d)",
+		pr_err("Unknown power/cooling event (action code  = %d)\n",
 			action_code);
 	}
+
+	/* Increment epow events counter variable */
+	if (action_code != EPOW_RESET)
+		num_epow_events++;
 }
 
 /* Handle environmental and power warning (EPOW) interrupts. */
@@ -249,13 +257,12 @@ static irqreturn_t ras_error_interrupt(i
 	log_error(ras_log_buf, ERR_TYPE_RTAS_LOG, fatal);
 
 	if (fatal) {
-		pr_emerg("Fatal hardware error reported by firmware");
-		pr_emerg("Check RTAS error log for details");
-		pr_emerg("Immediate power off");
+		pr_emerg("Fatal hardware error detected. Check RTAS error"
+			 " log for details. Powering off immediately\n");
 		emergency_sync();
 		kernel_power_off();
 	} else {
-		pr_err("Recoverable hardware error reported by firmware");
+		pr_err("Recoverable hardware error detected\n");
 	}
 
 	spin_unlock(&ras_log_buf_lock);
--- zfcpdump-kernel-4.4.orig/arch/s390/crypto/aes_s390.c
+++ zfcpdump-kernel-4.4/arch/s390/crypto/aes_s390.c
@@ -27,6 +27,7 @@
 #include <linux/cpufeature.h>
 #include <linux/init.h>
 #include <linux/spinlock.h>
+#include <crypto/xts.h>
 #include "crypt_s390.h"
 
 #define AES_KEYLEN_128		1
@@ -587,6 +588,11 @@ static int xts_aes_set_key(struct crypto
 {
 	struct s390_xts_ctx *xts_ctx = crypto_tfm_ctx(tfm);
 	u32 *flags = &tfm->crt_flags;
+	int err;
+
+	err = xts_check_key(tfm, in_key, key_len);
+	if (err)
+		return err;
 
 	switch (key_len) {
 	case 32:
--- zfcpdump-kernel-4.4.orig/arch/s390/crypto/prng.c
+++ zfcpdump-kernel-4.4/arch/s390/crypto/prng.c
@@ -669,11 +669,13 @@ static const struct file_operations prng
 static struct miscdevice prng_sha512_dev = {
 	.name	= "prandom",
 	.minor	= MISC_DYNAMIC_MINOR,
+	.mode	= 0644,
 	.fops	= &prng_sha512_fops,
 };
 static struct miscdevice prng_tdes_dev = {
 	.name	= "prandom",
 	.minor	= MISC_DYNAMIC_MINOR,
+	.mode	= 0644,
 	.fops	= &prng_tdes_fops,
 };
 
--- zfcpdump-kernel-4.4.orig/arch/s390/include/asm/barrier.h
+++ zfcpdump-kernel-4.4/arch/s390/include/asm/barrier.h
@@ -36,7 +36,7 @@
 #define smp_mb__before_atomic()		smp_mb()
 #define smp_mb__after_atomic()		smp_mb()
 
-#define smp_store_mb(var, value)		do { WRITE_ONCE(var, value); mb(); } while (0)
+#define smp_store_mb(var, value)	do { WRITE_ONCE(var, value); smp_mb(); } while (0)
 
 #define smp_store_release(p, v)						\
 do {									\
--- zfcpdump-kernel-4.4.orig/arch/s390/include/asm/clp.h
+++ zfcpdump-kernel-4.4/arch/s390/include/asm/clp.h
@@ -4,14 +4,23 @@
 /* CLP common request & response block size */
 #define CLP_BLK_SIZE			PAGE_SIZE
 
+#define CLP_LPS_BASE	0
+#define CLP_LPS_PCI	2
+
 struct clp_req_hdr {
 	u16 len;
 	u16 cmd;
+	u32 fmt		: 4;
+	u32 reserved1	: 28;
+	u64 reserved2;
 } __packed;
 
 struct clp_rsp_hdr {
 	u16 len;
 	u16 rsp;
+	u32 fmt		: 4;
+	u32 reserved1	: 28;
+	u64 reserved2;
 } __packed;
 
 /* CLP Response Codes */
@@ -25,4 +34,22 @@ struct clp_rsp_hdr {
 #define CLP_RC_NODATA			0x0080	/* No data available */
 #define CLP_RC_FC_UNKNOWN		0x0100	/* Function code not recognized */
 
+/* Store logical-processor characteristics request */
+struct clp_req_slpc {
+	struct clp_req_hdr hdr;
+} __packed;
+
+struct clp_rsp_slpc {
+	struct clp_rsp_hdr hdr;
+	u32 reserved2[4];
+	u32 lpif[8];
+	u32 reserved3[8];
+	u32 lpic[8];
+} __packed;
+
+struct clp_req_rsp_slpc {
+	struct clp_req_slpc request;
+	struct clp_rsp_slpc response;
+} __packed;
+
 #endif
--- zfcpdump-kernel-4.4.orig/arch/s390/include/asm/facility.h
+++ zfcpdump-kernel-4.4/arch/s390/include/asm/facility.h
@@ -44,10 +44,8 @@ static inline void stfle(u64 *stfle_fac_
 
 	preempt_disable();
 	asm volatile(
-		"	.insn s,0xb2b10000,0(0)\n" /* stfl */
-		"0:\n"
-		EX_TABLE(0b, 0b)
-		: "+m" (S390_lowcore.stfl_fac_list));
+		"	stfl	0(0)\n"
+		: "=m" (S390_lowcore.stfl_fac_list));
 	nr = 4; /* bytes stored by stfl */
 	memcpy(stfle_fac_list, &S390_lowcore.stfl_fac_list, 4);
 	if (S390_lowcore.stfl_fac_list & 0x01000000) {
--- zfcpdump-kernel-4.4.orig/arch/s390/include/asm/fpu/api.h
+++ zfcpdump-kernel-4.4/arch/s390/include/asm/fpu/api.h
@@ -22,7 +22,7 @@ static inline int test_fp_ctl(u32 fpc)
 		"	la	%0,0\n"
 		"1:\n"
 		EX_TABLE(0b,1b)
-		: "=d" (rc), "=d" (orig_fpc)
+		: "=d" (rc), "=&d" (orig_fpc)
 		: "d" (fpc), "0" (-EINVAL));
 	return rc;
 }
--- zfcpdump-kernel-4.4.orig/arch/s390/include/asm/fpu/internal.h
+++ zfcpdump-kernel-4.4/arch/s390/include/asm/fpu/internal.h
@@ -48,6 +48,7 @@ static inline void convert_fp_to_vx(__ve
 static inline void fpregs_store(_s390_fp_regs *fpregs, struct fpu *fpu)
 {
 	fpregs->pad = 0;
+	fpregs->fpc = fpu->fpc;
 	if (MACHINE_HAS_VX)
 		convert_vx_to_fp((freg_t *)&fpregs->fprs, fpu->vxrs);
 	else
@@ -57,6 +58,7 @@ static inline void fpregs_store(_s390_fp
 
 static inline void fpregs_load(_s390_fp_regs *fpregs, struct fpu *fpu)
 {
+	fpu->fpc = fpregs->fpc;
 	if (MACHINE_HAS_VX)
 		convert_fp_to_vx(fpu->vxrs, (freg_t *)&fpregs->fprs);
 	else
--- zfcpdump-kernel-4.4.orig/arch/s390/include/asm/kvm_host.h
+++ zfcpdump-kernel-4.4/arch/s390/include/asm/kvm_host.h
@@ -506,7 +506,6 @@ struct kvm_vcpu_arch {
 	struct kvm_s390_sie_block *sie_block;
 	unsigned int      host_acrs[NUM_ACRS];
 	struct fpu	  host_fpregs;
-	struct fpu	  guest_fpregs;
 	struct kvm_s390_local_interrupt local_int;
 	struct hrtimer    ckc_timer;
 	struct kvm_s390_pgm_info pgm;
--- zfcpdump-kernel-4.4.orig/arch/s390/include/asm/mmu.h
+++ zfcpdump-kernel-4.4/arch/s390/include/asm/mmu.h
@@ -11,7 +11,7 @@ typedef struct {
 	spinlock_t list_lock;
 	struct list_head pgtable_list;
 	struct list_head gmap_list;
-	unsigned long asce_bits;
+	unsigned long asce;
 	unsigned long asce_limit;
 	unsigned long vdso_base;
 	/* The mmu context allocates 4K page tables. */
--- zfcpdump-kernel-4.4.orig/arch/s390/include/asm/mmu_context.h
+++ zfcpdump-kernel-4.4/arch/s390/include/asm/mmu_context.h
@@ -15,17 +15,41 @@
 static inline int init_new_context(struct task_struct *tsk,
 				   struct mm_struct *mm)
 {
+	spin_lock_init(&mm->context.list_lock);
+	INIT_LIST_HEAD(&mm->context.pgtable_list);
+	INIT_LIST_HEAD(&mm->context.gmap_list);
 	cpumask_clear(&mm->context.cpu_attach_mask);
 	atomic_set(&mm->context.attach_count, 0);
 	mm->context.flush_mm = 0;
-	mm->context.asce_bits = _ASCE_TABLE_LENGTH | _ASCE_USER_BITS;
-	mm->context.asce_bits |= _ASCE_TYPE_REGION3;
 #ifdef CONFIG_PGSTE
 	mm->context.alloc_pgste = page_table_allocate_pgste;
 	mm->context.has_pgste = 0;
 	mm->context.use_skey = 0;
 #endif
-	mm->context.asce_limit = STACK_TOP_MAX;
+	switch (mm->context.asce_limit) {
+	case 1UL << 42:
+		/*
+		 * forked 3-level task, fall through to set new asce with new
+		 * mm->pgd
+		 */
+	case 0:
+		/* context created by exec, set asce limit to 4TB */
+		mm->context.asce_limit = STACK_TOP_MAX;
+		mm->context.asce = __pa(mm->pgd) | _ASCE_TABLE_LENGTH |
+				   _ASCE_USER_BITS | _ASCE_TYPE_REGION3;
+		break;
+	case 1UL << 53:
+		/* forked 4-level task, set new asce with new mm->pgd */
+		mm->context.asce = __pa(mm->pgd) | _ASCE_TABLE_LENGTH |
+				   _ASCE_USER_BITS | _ASCE_TYPE_REGION2;
+		break;
+	case 1UL << 31:
+		/* forked 2-level compat task, set new asce with new mm->pgd */
+		mm->context.asce = __pa(mm->pgd) | _ASCE_TABLE_LENGTH |
+				   _ASCE_USER_BITS | _ASCE_TYPE_SEGMENT;
+		/* pgd_alloc() did not increase mm->nr_pmds */
+		mm_inc_nr_pmds(mm);
+	}
 	crst_table_init((unsigned long *) mm->pgd, pgd_entry_type(mm));
 	return 0;
 }
@@ -34,7 +58,7 @@ static inline int init_new_context(struc
 
 static inline void set_user_asce(struct mm_struct *mm)
 {
-	S390_lowcore.user_asce = mm->context.asce_bits | __pa(mm->pgd);
+	S390_lowcore.user_asce = mm->context.asce;
 	if (current->thread.mm_segment.ar4)
 		__ctl_load(S390_lowcore.user_asce, 7, 7);
 	set_cpu_flag(CIF_ASCE);
@@ -63,7 +87,7 @@ static inline void switch_mm(struct mm_s
 {
 	int cpu = smp_processor_id();
 
-	S390_lowcore.user_asce = next->context.asce_bits | __pa(next->pgd);
+	S390_lowcore.user_asce = next->context.asce;
 	if (prev == next)
 		return;
 	if (MACHINE_HAS_TLB_LC)
@@ -111,8 +135,6 @@ static inline void activate_mm(struct mm
 static inline void arch_dup_mmap(struct mm_struct *oldmm,
 				 struct mm_struct *mm)
 {
-	if (oldmm->context.asce_limit < mm->context.asce_limit)
-		crst_table_downgrade(mm, oldmm->context.asce_limit);
 }
 
 static inline void arch_exit_mmap(struct mm_struct *mm)
--- zfcpdump-kernel-4.4.orig/arch/s390/include/asm/pci.h
+++ zfcpdump-kernel-4.4/arch/s390/include/asm/pci.h
@@ -45,7 +45,8 @@ struct zpci_fmb {
 	u64 rpcit_ops;
 	u64 dma_rbytes;
 	u64 dma_wbytes;
-} __packed __aligned(16);
+	u64 pad[2];
+} __packed __aligned(128);
 
 enum zpci_state {
 	ZPCI_FN_STATE_RESERVED,
@@ -66,7 +67,6 @@ struct s390_domain;
 
 /* Private data per function */
 struct zpci_dev {
-	struct pci_dev	*pdev;
 	struct pci_bus	*bus;
 	struct list_head entry;		/* list of all zpci_devices, needed for hotplug, etc. */
 
@@ -192,7 +192,7 @@ int zpci_fmb_disable_device(struct zpci_
 /* Debug */
 int zpci_debug_init(void);
 void zpci_debug_exit(void);
-void zpci_debug_init_device(struct zpci_dev *);
+void zpci_debug_init_device(struct zpci_dev *, const char *);
 void zpci_debug_exit_device(struct zpci_dev *);
 void zpci_debug_info(struct zpci_dev *, struct seq_file *);
 
--- zfcpdump-kernel-4.4.orig/arch/s390/include/asm/pci_clp.h
+++ zfcpdump-kernel-4.4/arch/s390/include/asm/pci_clp.h
@@ -49,9 +49,6 @@ struct clp_fh_list_entry {
 /* List PCI functions request */
 struct clp_req_list_pci {
 	struct clp_req_hdr hdr;
-	u32 fmt			:  4;	/* cmd request block format */
-	u32			: 28;
-	u64 reserved1;
 	u64 resume_token;
 	u64 reserved2;
 } __packed;
@@ -59,9 +56,6 @@ struct clp_req_list_pci {
 /* List PCI functions response */
 struct clp_rsp_list_pci {
 	struct clp_rsp_hdr hdr;
-	u32 fmt			:  4;	/* cmd request block format */
-	u32			: 28;
-	u64 reserved1;
 	u64 resume_token;
 	u32 reserved2;
 	u16 max_fn;
@@ -73,9 +67,6 @@ struct clp_rsp_list_pci {
 /* Query PCI function request */
 struct clp_req_query_pci {
 	struct clp_req_hdr hdr;
-	u32 fmt			:  4;	/* cmd request block format */
-	u32			: 28;
-	u64 reserved1;
 	u32 fh;				/* function handle */
 	u32 reserved2;
 	u64 reserved3;
@@ -84,9 +75,6 @@ struct clp_req_query_pci {
 /* Query PCI function response */
 struct clp_rsp_query_pci {
 	struct clp_rsp_hdr hdr;
-	u32 fmt			:  4;	/* cmd request block format */
-	u32			: 28;
-	u64			: 64;
 	u16 vfn;			/* virtual fn number */
 	u16			:  7;
 	u16 util_str_avail	:  1;	/* utility string available? */
@@ -108,21 +96,15 @@ struct clp_rsp_query_pci {
 /* Query PCI function group request */
 struct clp_req_query_pci_grp {
 	struct clp_req_hdr hdr;
-	u32 fmt			:  4;	/* cmd request block format */
-	u32			: 28;
-	u64 reserved1;
-	u32			: 24;
+	u32 reserved2		: 24;
 	u32 pfgid		:  8;	/* function group id */
-	u32 reserved2;
-	u64 reserved3;
+	u32 reserved3;
+	u64 reserved4;
 } __packed;
 
 /* Query PCI function group response */
 struct clp_rsp_query_pci_grp {
 	struct clp_rsp_hdr hdr;
-	u32 fmt			:  4;	/* cmd request block format */
-	u32			: 28;
-	u64 reserved1;
 	u16			:  4;
 	u16 noi			: 12;	/* number of interrupts */
 	u8 version;
@@ -141,9 +123,6 @@ struct clp_rsp_query_pci_grp {
 /* Set PCI function request */
 struct clp_req_set_pci {
 	struct clp_req_hdr hdr;
-	u32 fmt			:  4;	/* cmd request block format */
-	u32			: 28;
-	u64 reserved1;
 	u32 fh;				/* function handle */
 	u16 reserved2;
 	u8 oc;				/* operation controls */
@@ -154,9 +133,6 @@ struct clp_req_set_pci {
 /* Set PCI function response */
 struct clp_rsp_set_pci {
 	struct clp_rsp_hdr hdr;
-	u32 fmt			:  4;	/* cmd request block format */
-	u32			: 28;
-	u64 reserved1;
 	u32 fh;				/* function handle */
 	u32 reserved3;
 	u64 reserved4;
--- zfcpdump-kernel-4.4.orig/arch/s390/include/asm/pci_dma.h
+++ zfcpdump-kernel-4.4/arch/s390/include/asm/pci_dma.h
@@ -23,6 +23,8 @@ enum zpci_ioat_dtype {
 #define ZPCI_IOTA_FS_2G			2
 #define ZPCI_KEY			(PAGE_DEFAULT_KEY << 5)
 
+#define ZPCI_TABLE_SIZE_RT	(1UL << 42)
+
 #define ZPCI_IOTA_STO_FLAG	(ZPCI_IOTA_IOT_ENABLED | ZPCI_KEY | ZPCI_IOTA_DT_ST)
 #define ZPCI_IOTA_RTTO_FLAG	(ZPCI_IOTA_IOT_ENABLED | ZPCI_KEY | ZPCI_IOTA_DT_RT)
 #define ZPCI_IOTA_RSTO_FLAG	(ZPCI_IOTA_IOT_ENABLED | ZPCI_KEY | ZPCI_IOTA_DT_RS)
--- zfcpdump-kernel-4.4.orig/arch/s390/include/asm/pci_io.h
+++ zfcpdump-kernel-4.4/arch/s390/include/asm/pci_io.h
@@ -8,10 +8,13 @@
 #include <asm/pci_insn.h>
 
 /* I/O Map */
-#define ZPCI_IOMAP_MAX_ENTRIES		0x7fff
-#define ZPCI_IOMAP_ADDR_BASE		0x8000000000000000ULL
-#define ZPCI_IOMAP_ADDR_IDX_MASK	0x7fff000000000000ULL
-#define ZPCI_IOMAP_ADDR_OFF_MASK	0x0000ffffffffffffULL
+#define ZPCI_IOMAP_SHIFT		48
+#define ZPCI_IOMAP_ADDR_BASE		0x8000000000000000UL
+#define ZPCI_IOMAP_ADDR_OFF_MASK	((1UL << ZPCI_IOMAP_SHIFT) - 1)
+#define ZPCI_IOMAP_MAX_ENTRIES							\
+	((ULONG_MAX - ZPCI_IOMAP_ADDR_BASE + 1) / (1UL << ZPCI_IOMAP_SHIFT))
+#define ZPCI_IOMAP_ADDR_IDX_MASK						\
+	(~ZPCI_IOMAP_ADDR_OFF_MASK - ZPCI_IOMAP_ADDR_BASE)
 
 struct zpci_iomap_entry {
 	u32 fh;
@@ -21,8 +24,9 @@ struct zpci_iomap_entry {
 
 extern struct zpci_iomap_entry *zpci_iomap_start;
 
+#define ZPCI_ADDR(idx) (ZPCI_IOMAP_ADDR_BASE | ((u64) idx << ZPCI_IOMAP_SHIFT))
 #define ZPCI_IDX(addr)								\
-	(((__force u64) addr & ZPCI_IOMAP_ADDR_IDX_MASK) >> 48)
+	(((__force u64) addr & ZPCI_IOMAP_ADDR_IDX_MASK) >> ZPCI_IOMAP_SHIFT)
 #define ZPCI_OFFSET(addr)							\
 	((__force u64) addr & ZPCI_IOMAP_ADDR_OFF_MASK)
 
--- zfcpdump-kernel-4.4.orig/arch/s390/include/asm/pgalloc.h
+++ zfcpdump-kernel-4.4/arch/s390/include/asm/pgalloc.h
@@ -56,8 +56,8 @@ static inline unsigned long pgd_entry_ty
 	return _REGION2_ENTRY_EMPTY;
 }
 
-int crst_table_upgrade(struct mm_struct *, unsigned long limit);
-void crst_table_downgrade(struct mm_struct *, unsigned long limit);
+int crst_table_upgrade(struct mm_struct *);
+void crst_table_downgrade(struct mm_struct *);
 
 static inline pud_t *pud_alloc_one(struct mm_struct *mm, unsigned long address)
 {
@@ -100,12 +100,26 @@ static inline void pud_populate(struct m
 
 static inline pgd_t *pgd_alloc(struct mm_struct *mm)
 {
-	spin_lock_init(&mm->context.list_lock);
-	INIT_LIST_HEAD(&mm->context.pgtable_list);
-	INIT_LIST_HEAD(&mm->context.gmap_list);
-	return (pgd_t *) crst_table_alloc(mm);
+	unsigned long *table = crst_table_alloc(mm);
+
+	if (!table)
+		return NULL;
+	if (mm->context.asce_limit == (1UL << 31)) {
+		/* Forking a compat process with 2 page table levels */
+		if (!pgtable_pmd_page_ctor(virt_to_page(table))) {
+			crst_table_free(mm, table);
+			return NULL;
+		}
+	}
+	return (pgd_t *) table;
+}
+
+static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd)
+{
+	if (mm->context.asce_limit == (1UL << 31))
+		pgtable_pmd_page_dtor(virt_to_page(pgd));
+	crst_table_free(mm, (unsigned long *) pgd);
 }
-#define pgd_free(mm, pgd) crst_table_free(mm, (unsigned long *) pgd)
 
 static inline void pmd_populate(struct mm_struct *mm,
 				pmd_t *pmd, pgtable_t pte)
--- zfcpdump-kernel-4.4.orig/arch/s390/include/asm/processor.h
+++ zfcpdump-kernel-4.4/arch/s390/include/asm/processor.h
@@ -163,7 +163,7 @@ extern __vector128 init_task_fpu_regs[__
 	regs->psw.mask	= PSW_USER_BITS | PSW_MASK_BA;			\
 	regs->psw.addr	= new_psw | PSW_ADDR_AMODE;			\
 	regs->gprs[15]	= new_stackp;					\
-	crst_table_downgrade(current->mm, 1UL << 31);			\
+	crst_table_downgrade(current->mm);				\
 	execve_tail();							\
 } while (0)
 
--- zfcpdump-kernel-4.4.orig/arch/s390/include/asm/tlbflush.h
+++ zfcpdump-kernel-4.4/arch/s390/include/asm/tlbflush.h
@@ -110,8 +110,7 @@ static inline void __tlb_flush_asce(stru
 static inline void __tlb_flush_kernel(void)
 {
 	if (MACHINE_HAS_IDTE)
-		__tlb_flush_idte((unsigned long) init_mm.pgd |
-				 init_mm.context.asce_bits);
+		__tlb_flush_idte(init_mm.context.asce);
 	else
 		__tlb_flush_global();
 }
@@ -133,8 +132,7 @@ static inline void __tlb_flush_asce(stru
 static inline void __tlb_flush_kernel(void)
 {
 	if (MACHINE_HAS_TLB_LC)
-		__tlb_flush_idte_local((unsigned long) init_mm.pgd |
-				       init_mm.context.asce_bits);
+		__tlb_flush_idte_local(init_mm.context.asce);
 	else
 		__tlb_flush_local();
 }
@@ -148,8 +146,7 @@ static inline void __tlb_flush_mm(struct
 	 * only ran on the local cpu.
 	 */
 	if (MACHINE_HAS_IDTE && list_empty(&mm->context.gmap_list))
-		__tlb_flush_asce(mm, (unsigned long) mm->pgd |
-				 mm->context.asce_bits);
+		__tlb_flush_asce(mm, mm->context.asce);
 	else
 		__tlb_flush_full(mm);
 }
--- zfcpdump-kernel-4.4.orig/arch/s390/include/asm/uaccess.h
+++ zfcpdump-kernel-4.4/arch/s390/include/asm/uaccess.h
@@ -215,28 +215,28 @@ int __put_user_bad(void) __attribute__((
 	__chk_user_ptr(ptr);					\
 	switch (sizeof(*(ptr))) {				\
 	case 1: {						\
-		unsigned char __x;				\
+		unsigned char __x = 0;				\
 		__gu_err = __get_user_fn(&__x, ptr,		\
 					 sizeof(*(ptr)));	\
 		(x) = *(__force __typeof__(*(ptr)) *) &__x;	\
 		break;						\
 	};							\
 	case 2: {						\
-		unsigned short __x;				\
+		unsigned short __x = 0;				\
 		__gu_err = __get_user_fn(&__x, ptr,		\
 					 sizeof(*(ptr)));	\
 		(x) = *(__force __typeof__(*(ptr)) *) &__x;	\
 		break;						\
 	};							\
 	case 4: {						\
-		unsigned int __x;				\
+		unsigned int __x = 0;				\
 		__gu_err = __get_user_fn(&__x, ptr,		\
 					 sizeof(*(ptr)));	\
 		(x) = *(__force __typeof__(*(ptr)) *) &__x;	\
 		break;						\
 	};							\
 	case 8: {						\
-		unsigned long long __x;				\
+		unsigned long long __x = 0;			\
 		__gu_err = __get_user_fn(&__x, ptr,		\
 					 sizeof(*(ptr)));	\
 		(x) = *(__force __typeof__(*(ptr)) *) &__x;	\
--- /dev/null
+++ zfcpdump-kernel-4.4/arch/s390/include/uapi/asm/clp.h
@@ -0,0 +1,28 @@
+/*
+ * ioctl interface for /dev/clp
+ *
+ * Copyright IBM Corp. 2016
+ * Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com>
+ */
+
+#ifndef _ASM_CLP_H
+#define _ASM_CLP_H
+
+#include <linux/types.h>
+#include <linux/ioctl.h>
+
+struct clp_req {
+	unsigned int c : 1;
+	unsigned int r : 1;
+	unsigned int lps : 6;
+	unsigned int cmd : 8;
+	unsigned int : 16;
+	unsigned int reserved;
+	__u64 data_p;
+};
+
+#define CLP_IOCTL_MAGIC 'c'
+
+#define CLP_SYNC _IOWR(CLP_IOCTL_MAGIC, 0xC1, struct clp_req)
+
+#endif
--- zfcpdump-kernel-4.4.orig/arch/s390/kernel/asm-offsets.c
+++ zfcpdump-kernel-4.4/arch/s390/kernel/asm-offsets.c
@@ -120,6 +120,7 @@ int main(void)
 	OFFSET(__LC_IO_INT_PARM, _lowcore, io_int_parm);
 	OFFSET(__LC_IO_INT_WORD, _lowcore, io_int_word);
 	OFFSET(__LC_STFL_FAC_LIST, _lowcore, stfl_fac_list);
+	OFFSET(__LC_STFLE_FAC_LIST, _lowcore, stfle_fac_list);
 	OFFSET(__LC_MCCK_CODE, _lowcore, mcck_interruption_code);
 	OFFSET(__LC_MCCK_FAIL_STOR_ADDR, _lowcore, failing_storage_address);
 	OFFSET(__LC_LAST_BREAK, _lowcore, breaking_event_addr);
@@ -181,6 +182,7 @@ int main(void)
 	OFFSET(__LC_PSW_SAVE_AREA, _lowcore, psw_save_area);
 	OFFSET(__LC_PREFIX_SAVE_AREA, _lowcore, prefixreg_save_area);
 	OFFSET(__LC_FP_CREG_SAVE_AREA, _lowcore, fpt_creg_save_area);
+	OFFSET(__LC_TOD_PROGREG_SAVE_AREA, _lowcore, tod_progreg_save_area);
 	OFFSET(__LC_CPU_TIMER_SAVE_AREA, _lowcore, cpu_timer_save_area);
 	OFFSET(__LC_CLOCK_COMP_SAVE_AREA, _lowcore, clock_comp_save_area);
 	OFFSET(__LC_AREGS_SAVE_AREA, _lowcore, access_regs_save_area);
--- zfcpdump-kernel-4.4.orig/arch/s390/kernel/compat_signal.c
+++ zfcpdump-kernel-4.4/arch/s390/kernel/compat_signal.c
@@ -271,7 +271,7 @@ static int restore_sigregs_ext32(struct
 
 	/* Restore high gprs from signal stack */
 	if (__copy_from_user(&gprs_high, &sregs_ext->gprs_high,
-			     sizeof(&sregs_ext->gprs_high)))
+			     sizeof(sregs_ext->gprs_high)))
 		return -EFAULT;
 	for (i = 0; i < NUM_GPRS; i++)
 		*(__u32 *)&regs->gprs[i] = gprs_high[i];
--- zfcpdump-kernel-4.4.orig/arch/s390/kernel/entry.S
+++ zfcpdump-kernel-4.4/arch/s390/kernel/entry.S
@@ -1197,114 +1197,12 @@ cleanup_critical:
 	.quad	.Lpsw_idle_lpsw
 
 .Lcleanup_save_fpu_regs:
-	TSTMSK	__LC_CPU_FLAGS,_CIF_FPU
-	bor	%r14
-	clg	%r9,BASED(.Lcleanup_save_fpu_regs_done)
-	jhe	5f
-	clg	%r9,BASED(.Lcleanup_save_fpu_regs_fp)
-	jhe	4f
-	clg	%r9,BASED(.Lcleanup_save_fpu_regs_vx_high)
-	jhe	3f
-	clg	%r9,BASED(.Lcleanup_save_fpu_regs_vx_low)
-	jhe	2f
-	clg	%r9,BASED(.Lcleanup_save_fpu_fpc_end)
-	jhe	1f
-	lg	%r2,__LC_CURRENT
-	aghi	%r2,__TASK_thread
-0:	# Store floating-point controls
-	stfpc	__THREAD_FPU_fpc(%r2)
-1:	# Load register save area and check if VX is active
-	lg	%r3,__THREAD_FPU_regs(%r2)
-	TSTMSK	__LC_MACHINE_FLAGS,MACHINE_FLAG_VX
-	jz	4f			  # no VX -> store FP regs
-2:	# Store vector registers (V0-V15)
-	VSTM	%v0,%v15,0,%r3		  # vstm 0,15,0(3)
-3:	# Store vector registers (V16-V31)
-	VSTM	%v16,%v31,256,%r3	  # vstm 16,31,256(3)
-	j	5f			  # -> done, set CIF_FPU flag
-4:	# Store floating-point registers
-	std	0,0(%r3)
-	std	1,8(%r3)
-	std	2,16(%r3)
-	std	3,24(%r3)
-	std	4,32(%r3)
-	std	5,40(%r3)
-	std	6,48(%r3)
-	std	7,56(%r3)
-	std	8,64(%r3)
-	std	9,72(%r3)
-	std	10,80(%r3)
-	std	11,88(%r3)
-	std	12,96(%r3)
-	std	13,104(%r3)
-	std	14,112(%r3)
-	std	15,120(%r3)
-5:	# Set CIF_FPU flag
-	oi	__LC_CPU_FLAGS+7,_CIF_FPU
-	lg	%r9,48(%r11)		# return from save_fpu_regs
+	larl	%r9,save_fpu_regs
 	br	%r14
-.Lcleanup_save_fpu_fpc_end:
-	.quad	.Lsave_fpu_regs_fpc_end
-.Lcleanup_save_fpu_regs_vx_low:
-	.quad	.Lsave_fpu_regs_vx_low
-.Lcleanup_save_fpu_regs_vx_high:
-	.quad	.Lsave_fpu_regs_vx_high
-.Lcleanup_save_fpu_regs_fp:
-	.quad	.Lsave_fpu_regs_fp
-.Lcleanup_save_fpu_regs_done:
-	.quad	.Lsave_fpu_regs_done
 
 .Lcleanup_load_fpu_regs:
-	TSTMSK	__LC_CPU_FLAGS,_CIF_FPU
-	bnor	%r14
-	clg	%r9,BASED(.Lcleanup_load_fpu_regs_done)
-	jhe	1f
-	clg	%r9,BASED(.Lcleanup_load_fpu_regs_fp)
-	jhe	2f
-	clg	%r9,BASED(.Lcleanup_load_fpu_regs_vx_high)
-	jhe	3f
-	clg	%r9,BASED(.Lcleanup_load_fpu_regs_vx)
-	jhe	4f
-	lg	%r4,__LC_CURRENT
-	aghi	%r4,__TASK_thread
-	lfpc	__THREAD_FPU_fpc(%r4)
-	TSTMSK	__LC_MACHINE_FLAGS,MACHINE_FLAG_VX
-	lg	%r4,__THREAD_FPU_regs(%r4)	# %r4 <- reg save area
-	jz	2f				# -> no VX, load FP regs
-4:	# Load V0 ..V15 registers
-	VLM	%v0,%v15,0,%r4
-3:	# Load V16..V31 registers
-	VLM	%v16,%v31,256,%r4
-	j	1f
-2:	# Load floating-point registers
-	ld	0,0(%r4)
-	ld	1,8(%r4)
-	ld	2,16(%r4)
-	ld	3,24(%r4)
-	ld	4,32(%r4)
-	ld	5,40(%r4)
-	ld	6,48(%r4)
-	ld	7,56(%r4)
-	ld	8,64(%r4)
-	ld	9,72(%r4)
-	ld	10,80(%r4)
-	ld	11,88(%r4)
-	ld	12,96(%r4)
-	ld	13,104(%r4)
-	ld	14,112(%r4)
-	ld	15,120(%r4)
-1:	# Clear CIF_FPU bit
-	ni	__LC_CPU_FLAGS+7,255-_CIF_FPU
-	lg	%r9,48(%r11)		# return from load_fpu_regs
+	larl	%r9,load_fpu_regs
 	br	%r14
-.Lcleanup_load_fpu_regs_vx:
-	.quad	.Lload_fpu_regs_vx
-.Lcleanup_load_fpu_regs_vx_high:
-	.quad	.Lload_fpu_regs_vx_high
-.Lcleanup_load_fpu_regs_fp:
-	.quad	.Lload_fpu_regs_fp
-.Lcleanup_load_fpu_regs_done:
-	.quad	.Lload_fpu_regs_done
 
 /*
  * Integer constants
--- zfcpdump-kernel-4.4.orig/arch/s390/kernel/head.S
+++ zfcpdump-kernel-4.4/arch/s390/kernel/head.S
@@ -300,19 +300,19 @@ ENTRY(startup_kdump)
 	xc	0x200(256),0x200	# partially clear lowcore
 	xc	0x300(256),0x300
 	xc	0xe00(256),0xe00
+	xc	0xf00(256),0xf00
 	lctlg	%c0,%c15,0x200(%r0)	# initialize control registers
 	stck	__LC_LAST_UPDATE_CLOCK
 	spt	6f-.LPG0(%r13)
 	mvc	__LC_LAST_UPDATE_TIMER(8),6f-.LPG0(%r13)
-	xc	__LC_STFL_FAC_LIST(8),__LC_STFL_FAC_LIST
-	# check capabilities against MARCH_{G5,Z900,Z990,Z9_109,Z10}
-	.insn	s,0xb2b10000,0		# store facilities @ __LC_STFL_FAC_LIST
-	tm	__LC_STFL_FAC_LIST,0x01	# stfle available ?
+	stfl	0(%r0)			# store facilities @ __LC_STFL_FAC_LIST
+	mvc	__LC_STFLE_FAC_LIST(4),__LC_STFL_FAC_LIST
+	tm	__LC_STFLE_FAC_LIST,0x01	# stfle available ?
 	jz	0f
 	la	%r0,1
-	.insn	s,0xb2b00000,__LC_STFL_FAC_LIST	# store facility list extended
+	.insn	s,0xb2b00000,__LC_STFLE_FAC_LIST # store facility list extended
 	# verify if all required facilities are supported by the machine
-0:	la	%r1,__LC_STFL_FAC_LIST
+0:	la	%r1,__LC_STFLE_FAC_LIST
 	la	%r2,3f+8-.LPG0(%r13)
 	l	%r3,0(%r2)
 1:	l	%r0,0(%r1)
--- zfcpdump-kernel-4.4.orig/arch/s390/kernel/head64.S
+++ zfcpdump-kernel-4.4/arch/s390/kernel/head64.S
@@ -16,7 +16,7 @@
 
 __HEAD
 ENTRY(startup_continue)
-	tm	__LC_STFL_FAC_LIST+6,0x80	# LPP available ?
+	tm	__LC_STFLE_FAC_LIST+5,0x80	# LPP available ?
 	jz	0f
 	xc	__LC_LPP+1(7,0),__LC_LPP+1	# clear lpp and current_pid
 	mvi	__LC_LPP,0x80			#   and set LPP_MAGIC
--- zfcpdump-kernel-4.4.orig/arch/s390/kernel/ipl.c
+++ zfcpdump-kernel-4.4/arch/s390/kernel/ipl.c
@@ -2070,13 +2070,6 @@ void s390_reset_system(void (*fn_pre)(vo
 	S390_lowcore.program_new_psw.addr =
 		PSW_ADDR_AMODE | (unsigned long) s390_base_pgm_handler;
 
-	/*
-	 * Clear subchannel ID and number to signal new kernel that no CCW or
-	 * SCSI IPL has been done (for kexec and kdump)
-	 */
-	S390_lowcore.subchannel_id = 0;
-	S390_lowcore.subchannel_nr = 0;
-
 	/* Store status at absolute zero */
 	store_status();
 
--- zfcpdump-kernel-4.4.orig/arch/s390/kernel/module.c
+++ zfcpdump-kernel-4.4/arch/s390/kernel/module.c
@@ -159,11 +159,11 @@ int module_frob_arch_sections(Elf_Ehdr *
 
 	/* Increase core size by size of got & plt and set start
 	   offsets for got and plt. */
-	me->core_size = ALIGN(me->core_size, 4);
-	me->arch.got_offset = me->core_size;
-	me->core_size += me->arch.got_size;
-	me->arch.plt_offset = me->core_size;
-	me->core_size += me->arch.plt_size;
+	me->core_layout.size = ALIGN(me->core_layout.size, 4);
+	me->arch.got_offset = me->core_layout.size;
+	me->core_layout.size += me->arch.got_size;
+	me->arch.plt_offset = me->core_layout.size;
+	me->core_layout.size += me->arch.plt_size;
 	return 0;
 }
 
@@ -279,7 +279,7 @@ static int apply_rela(Elf_Rela *rela, El
 		if (info->got_initialized == 0) {
 			Elf_Addr *gotent;
 
-			gotent = me->module_core + me->arch.got_offset +
+			gotent = me->core_layout.base + me->arch.got_offset +
 				info->got_offset;
 			*gotent = val;
 			info->got_initialized = 1;
@@ -302,7 +302,7 @@ static int apply_rela(Elf_Rela *rela, El
 			rc = apply_rela_bits(loc, val, 0, 64, 0);
 		else if (r_type == R_390_GOTENT ||
 			 r_type == R_390_GOTPLTENT) {
-			val += (Elf_Addr) me->module_core - loc;
+			val += (Elf_Addr) me->core_layout.base - loc;
 			rc = apply_rela_bits(loc, val, 1, 32, 1);
 		}
 		break;
@@ -315,7 +315,7 @@ static int apply_rela(Elf_Rela *rela, El
 	case R_390_PLTOFF64:	/* 16 bit offset from GOT to PLT. */
 		if (info->plt_initialized == 0) {
 			unsigned int *ip;
-			ip = me->module_core + me->arch.plt_offset +
+			ip = me->core_layout.base + me->arch.plt_offset +
 				info->plt_offset;
 			ip[0] = 0x0d10e310; /* basr 1,0; lg 1,10(1); br 1 */
 			ip[1] = 0x100a0004;
@@ -334,7 +334,7 @@ static int apply_rela(Elf_Rela *rela, El
 			       val - loc + 0xffffUL < 0x1ffffeUL) ||
 			      (r_type == R_390_PLT32DBL &&
 			       val - loc + 0xffffffffULL < 0x1fffffffeULL)))
-				val = (Elf_Addr) me->module_core +
+				val = (Elf_Addr) me->core_layout.base +
 					me->arch.plt_offset +
 					info->plt_offset;
 			val += rela->r_addend - loc;
@@ -356,7 +356,7 @@ static int apply_rela(Elf_Rela *rela, El
 	case R_390_GOTOFF32:	/* 32 bit offset to GOT.  */
 	case R_390_GOTOFF64:	/* 64 bit offset to GOT. */
 		val = val + rela->r_addend -
-			((Elf_Addr) me->module_core + me->arch.got_offset);
+			((Elf_Addr) me->core_layout.base + me->arch.got_offset);
 		if (r_type == R_390_GOTOFF16)
 			rc = apply_rela_bits(loc, val, 0, 16, 0);
 		else if (r_type == R_390_GOTOFF32)
@@ -366,7 +366,7 @@ static int apply_rela(Elf_Rela *rela, El
 		break;
 	case R_390_GOTPC:	/* 32 bit PC relative offset to GOT. */
 	case R_390_GOTPCDBL:	/* 32 bit PC rel. off. to GOT shifted by 1. */
-		val = (Elf_Addr) me->module_core + me->arch.got_offset +
+		val = (Elf_Addr) me->core_layout.base + me->arch.got_offset +
 			rela->r_addend - loc;
 		if (r_type == R_390_GOTPC)
 			rc = apply_rela_bits(loc, val, 1, 32, 0);
--- zfcpdump-kernel-4.4.orig/arch/s390/kernel/setup.c
+++ zfcpdump-kernel-4.4/arch/s390/kernel/setup.c
@@ -329,6 +329,7 @@ static void __init setup_lowcore(void)
 		+ PAGE_SIZE - STACK_FRAME_OVERHEAD - sizeof(struct pt_regs);
 	lc->current_task = (unsigned long) init_thread_union.thread_info.task;
 	lc->thread_info = (unsigned long) &init_thread_union;
+	lc->lpp = LPP_MAGIC;
 	lc->machine_flags = S390_lowcore.machine_flags;
 	lc->stfl_fac_list = S390_lowcore.stfl_fac_list;
 	memcpy(lc->stfle_fac_list, S390_lowcore.stfle_fac_list,
--- zfcpdump-kernel-4.4.orig/arch/s390/kvm/kvm-s390.c
+++ zfcpdump-kernel-4.4/arch/s390/kvm/kvm-s390.c
@@ -1268,44 +1268,18 @@ int kvm_arch_vcpu_init(struct kvm_vcpu *
 	return 0;
 }
 
-/*
- * Backs up the current FP/VX register save area on a particular
- * destination.  Used to switch between different register save
- * areas.
- */
-static inline void save_fpu_to(struct fpu *dst)
-{
-	dst->fpc = current->thread.fpu.fpc;
-	dst->regs = current->thread.fpu.regs;
-}
-
-/*
- * Switches the FP/VX register save area from which to lazy
- * restore register contents.
- */
-static inline void load_fpu_from(struct fpu *from)
-{
-	current->thread.fpu.fpc = from->fpc;
-	current->thread.fpu.regs = from->regs;
-}
-
 void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
 {
 	/* Save host register state */
 	save_fpu_regs();
-	save_fpu_to(&vcpu->arch.host_fpregs);
-
-	if (test_kvm_facility(vcpu->kvm, 129)) {
-		current->thread.fpu.fpc = vcpu->run->s.regs.fpc;
-		/*
-		 * Use the register save area in the SIE-control block
-		 * for register restore and save in kvm_arch_vcpu_put()
-		 */
-		current->thread.fpu.vxrs =
-			(__vector128 *)&vcpu->run->s.regs.vrs;
-	} else
-		load_fpu_from(&vcpu->arch.guest_fpregs);
+	vcpu->arch.host_fpregs.fpc = current->thread.fpu.fpc;
+	vcpu->arch.host_fpregs.regs = current->thread.fpu.regs;
 
+	/* Depending on MACHINE_HAS_VX, data stored to vrs either
+	 * has vector register or floating point register format.
+	 */
+	current->thread.fpu.regs = vcpu->run->s.regs.vrs;
+	current->thread.fpu.fpc = vcpu->run->s.regs.fpc;
 	if (test_fp_ctl(current->thread.fpu.fpc))
 		/* User space provided an invalid FPC, let's clear it */
 		current->thread.fpu.fpc = 0;
@@ -1321,19 +1295,13 @@ void kvm_arch_vcpu_put(struct kvm_vcpu *
 	atomic_andnot(CPUSTAT_RUNNING, &vcpu->arch.sie_block->cpuflags);
 	gmap_disable(vcpu->arch.gmap);
 
+	/* Save guest register state */
 	save_fpu_regs();
+	vcpu->run->s.regs.fpc = current->thread.fpu.fpc;
 
-	if (test_kvm_facility(vcpu->kvm, 129))
-		/*
-		 * kvm_arch_vcpu_load() set up the register save area to
-		 * the &vcpu->run->s.regs.vrs and, thus, the vector registers
-		 * are already saved.  Only the floating-point control must be
-		 * copied.
-		 */
-		vcpu->run->s.regs.fpc = current->thread.fpu.fpc;
-	else
-		save_fpu_to(&vcpu->arch.guest_fpregs);
-	load_fpu_from(&vcpu->arch.host_fpregs);
+	/* Restore host register state */
+	current->thread.fpu.fpc = vcpu->arch.host_fpregs.fpc;
+	current->thread.fpu.regs = vcpu->arch.host_fpregs.regs;
 
 	save_access_regs(vcpu->run->s.regs.acrs);
 	restore_access_regs(vcpu->arch.host_acrs);
@@ -1351,8 +1319,9 @@ static void kvm_s390_vcpu_initial_reset(
 	memset(vcpu->arch.sie_block->gcr, 0, 16 * sizeof(__u64));
 	vcpu->arch.sie_block->gcr[0]  = 0xE0UL;
 	vcpu->arch.sie_block->gcr[14] = 0xC2000000UL;
-	vcpu->arch.guest_fpregs.fpc = 0;
-	asm volatile("lfpc %0" : : "Q" (vcpu->arch.guest_fpregs.fpc));
+	/* make sure the new fpc will be lazily loaded */
+	save_fpu_regs();
+	current->thread.fpu.fpc = 0;
 	vcpu->arch.sie_block->gbea = 1;
 	vcpu->arch.sie_block->pp = 0;
 	vcpu->arch.pfault_token = KVM_S390_PFAULT_TOKEN_INVALID;
@@ -1501,19 +1470,6 @@ struct kvm_vcpu *kvm_arch_vcpu_create(st
 	vcpu->arch.local_int.wq = &vcpu->wq;
 	vcpu->arch.local_int.cpuflags = &vcpu->arch.sie_block->cpuflags;
 
-	/*
-	 * Allocate a save area for floating-point registers.  If the vector
-	 * extension is available, register contents are saved in the SIE
-	 * control block.  The allocated save area is still required in
-	 * particular places, for example, in kvm_s390_vcpu_store_status().
-	 */
-	vcpu->arch.guest_fpregs.fprs = kzalloc(sizeof(freg_t) * __NUM_FPRS,
-					       GFP_KERNEL);
-	if (!vcpu->arch.guest_fpregs.fprs) {
-		rc = -ENOMEM;
-		goto out_free_sie_block;
-	}
-
 	rc = kvm_vcpu_init(vcpu, kvm, id);
 	if (rc)
 		goto out_free_sie_block;
@@ -1734,19 +1690,27 @@ int kvm_arch_vcpu_ioctl_get_sregs(struct
 
 int kvm_arch_vcpu_ioctl_set_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
 {
+	/* make sure the new values will be lazily loaded */
+	save_fpu_regs();
 	if (test_fp_ctl(fpu->fpc))
 		return -EINVAL;
-	memcpy(vcpu->arch.guest_fpregs.fprs, &fpu->fprs, sizeof(fpu->fprs));
-	vcpu->arch.guest_fpregs.fpc = fpu->fpc;
-	save_fpu_regs();
-	load_fpu_from(&vcpu->arch.guest_fpregs);
+	current->thread.fpu.fpc = fpu->fpc;
+	if (MACHINE_HAS_VX)
+		convert_fp_to_vx(current->thread.fpu.vxrs, (freg_t *)fpu->fprs);
+	else
+		memcpy(current->thread.fpu.fprs, &fpu->fprs, sizeof(fpu->fprs));
 	return 0;
 }
 
 int kvm_arch_vcpu_ioctl_get_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
 {
-	memcpy(&fpu->fprs, vcpu->arch.guest_fpregs.fprs, sizeof(fpu->fprs));
-	fpu->fpc = vcpu->arch.guest_fpregs.fpc;
+	/* make sure we have the latest values */
+	save_fpu_regs();
+	if (MACHINE_HAS_VX)
+		convert_vx_to_fp((freg_t *)fpu->fprs, current->thread.fpu.vxrs);
+	else
+		memcpy(fpu->fprs, current->thread.fpu.fprs, sizeof(fpu->fprs));
+	fpu->fpc = current->thread.fpu.fpc;
 	return 0;
 }
 
@@ -2266,41 +2230,50 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_v
 int kvm_s390_store_status_unloaded(struct kvm_vcpu *vcpu, unsigned long gpa)
 {
 	unsigned char archmode = 1;
+	freg_t fprs[NUM_FPRS];
 	unsigned int px;
 	u64 clkcomp;
 	int rc;
 
+	px = kvm_s390_get_prefix(vcpu);
 	if (gpa == KVM_S390_STORE_STATUS_NOADDR) {
 		if (write_guest_abs(vcpu, 163, &archmode, 1))
 			return -EFAULT;
-		gpa = SAVE_AREA_BASE;
+		gpa = 0;
 	} else if (gpa == KVM_S390_STORE_STATUS_PREFIXED) {
 		if (write_guest_real(vcpu, 163, &archmode, 1))
 			return -EFAULT;
-		gpa = kvm_s390_real_to_abs(vcpu, SAVE_AREA_BASE);
+		gpa = px;
+	} else
+		gpa -= __LC_FPREGS_SAVE_AREA;
+
+	/* manually convert vector registers if necessary */
+	if (MACHINE_HAS_VX) {
+		convert_vx_to_fp(fprs, (__vector128 *) vcpu->run->s.regs.vrs);
+		rc = write_guest_abs(vcpu, gpa + __LC_FPREGS_SAVE_AREA,
+				     fprs, 128);
+	} else {
+		rc = write_guest_abs(vcpu, gpa + __LC_FPREGS_SAVE_AREA,
+				     vcpu->run->s.regs.vrs, 128);
 	}
-	rc = write_guest_abs(vcpu, gpa + offsetof(struct save_area, fp_regs),
-			     vcpu->arch.guest_fpregs.fprs, 128);
-	rc |= write_guest_abs(vcpu, gpa + offsetof(struct save_area, gp_regs),
+	rc |= write_guest_abs(vcpu, gpa + __LC_GPREGS_SAVE_AREA,
 			      vcpu->run->s.regs.gprs, 128);
-	rc |= write_guest_abs(vcpu, gpa + offsetof(struct save_area, psw),
+	rc |= write_guest_abs(vcpu, gpa + __LC_PSW_SAVE_AREA,
 			      &vcpu->arch.sie_block->gpsw, 16);
-	px = kvm_s390_get_prefix(vcpu);
-	rc |= write_guest_abs(vcpu, gpa + offsetof(struct save_area, pref_reg),
+	rc |= write_guest_abs(vcpu, gpa + __LC_PREFIX_SAVE_AREA,
 			      &px, 4);
-	rc |= write_guest_abs(vcpu,
-			      gpa + offsetof(struct save_area, fp_ctrl_reg),
-			      &vcpu->arch.guest_fpregs.fpc, 4);
-	rc |= write_guest_abs(vcpu, gpa + offsetof(struct save_area, tod_reg),
+	rc |= write_guest_abs(vcpu, gpa + __LC_FP_CREG_SAVE_AREA,
+			      &vcpu->run->s.regs.fpc, 4);
+	rc |= write_guest_abs(vcpu, gpa + __LC_TOD_PROGREG_SAVE_AREA,
 			      &vcpu->arch.sie_block->todpr, 4);
-	rc |= write_guest_abs(vcpu, gpa + offsetof(struct save_area, timer),
+	rc |= write_guest_abs(vcpu, gpa + __LC_CPU_TIMER_SAVE_AREA,
 			      &vcpu->arch.sie_block->cputm, 8);
 	clkcomp = vcpu->arch.sie_block->ckc >> 8;
-	rc |= write_guest_abs(vcpu, gpa + offsetof(struct save_area, clk_cmp),
+	rc |= write_guest_abs(vcpu, gpa + __LC_CLOCK_COMP_SAVE_AREA,
 			      &clkcomp, 8);
-	rc |= write_guest_abs(vcpu, gpa + offsetof(struct save_area, acc_regs),
+	rc |= write_guest_abs(vcpu, gpa + __LC_AREGS_SAVE_AREA,
 			      &vcpu->run->s.regs.acrs, 64);
-	rc |= write_guest_abs(vcpu, gpa + offsetof(struct save_area, ctrl_regs),
+	rc |= write_guest_abs(vcpu, gpa + __LC_CREGS_SAVE_AREA,
 			      &vcpu->arch.sie_block->gcr, 128);
 	return rc ? -EFAULT : 0;
 }
@@ -2313,19 +2286,7 @@ int kvm_s390_vcpu_store_status(struct kv
 	 * it into the save area
 	 */
 	save_fpu_regs();
-	if (test_kvm_facility(vcpu->kvm, 129)) {
-		/*
-		 * If the vector extension is available, the vector registers
-		 * which overlaps with floating-point registers are saved in
-		 * the SIE-control block.  Hence, extract the floating-point
-		 * registers and the FPC value and store them in the
-		 * guest_fpregs structure.
-		 */
-		vcpu->arch.guest_fpregs.fpc = current->thread.fpu.fpc;
-		convert_vx_to_fp(vcpu->arch.guest_fpregs.fprs,
-				 current->thread.fpu.vxrs);
-	} else
-		save_fpu_to(&vcpu->arch.guest_fpregs);
+	vcpu->run->s.regs.fpc = current->thread.fpu.fpc;
 	save_access_regs(vcpu->run->s.regs.acrs);
 
 	return kvm_s390_store_status_unloaded(vcpu, addr);
--- zfcpdump-kernel-4.4.orig/arch/s390/mm/extable.c
+++ zfcpdump-kernel-4.4/arch/s390/mm/extable.c
@@ -52,12 +52,16 @@ void sort_extable(struct exception_table
 	int i;
 
 	/* Normalize entries to being relative to the start of the section */
-	for (p = start, i = 0; p < finish; p++, i += 8)
+	for (p = start, i = 0; p < finish; p++, i += 8) {
 		p->insn += i;
+		p->fixup += i + 4;
+	}
 	sort(start, finish - start, sizeof(*start), cmp_ex, NULL);
 	/* Denormalize all entries */
-	for (p = start, i = 0; p < finish; p++, i += 8)
+	for (p = start, i = 0; p < finish; p++, i += 8) {
 		p->insn -= i;
+		p->fixup -= i + 4;
+	}
 }
 
 #ifdef CONFIG_MODULES
--- zfcpdump-kernel-4.4.orig/arch/s390/mm/init.c
+++ zfcpdump-kernel-4.4/arch/s390/mm/init.c
@@ -89,7 +89,8 @@ void __init paging_init(void)
 		asce_bits = _ASCE_TYPE_REGION3 | _ASCE_TABLE_LENGTH;
 		pgd_type = _REGION3_ENTRY_EMPTY;
 	}
-	S390_lowcore.kernel_asce = (__pa(init_mm.pgd) & PAGE_MASK) | asce_bits;
+	init_mm.context.asce = (__pa(init_mm.pgd) & PAGE_MASK) | asce_bits;
+	S390_lowcore.kernel_asce = init_mm.context.asce;
 	clear_table((unsigned long *) init_mm.pgd, pgd_type,
 		    sizeof(unsigned long)*2048);
 	vmem_map_init();
--- zfcpdump-kernel-4.4.orig/arch/s390/mm/mmap.c
+++ zfcpdump-kernel-4.4/arch/s390/mm/mmap.c
@@ -174,7 +174,7 @@ int s390_mmap_check(unsigned long addr,
 	if (!(flags & MAP_FIXED))
 		addr = 0;
 	if ((addr + len) >= TASK_SIZE)
-		return crst_table_upgrade(current->mm, 1UL << 53);
+		return crst_table_upgrade(current->mm);
 	return 0;
 }
 
@@ -191,7 +191,7 @@ s390_get_unmapped_area(struct file *filp
 		return area;
 	if (area == -ENOMEM && !is_compat_task() && TASK_SIZE < (1UL << 53)) {
 		/* Upgrade the page table to 4 levels and retry. */
-		rc = crst_table_upgrade(mm, 1UL << 53);
+		rc = crst_table_upgrade(mm);
 		if (rc)
 			return (unsigned long) rc;
 		area = arch_get_unmapped_area(filp, addr, len, pgoff, flags);
@@ -213,7 +213,7 @@ s390_get_unmapped_area_topdown(struct fi
 		return area;
 	if (area == -ENOMEM && !is_compat_task() && TASK_SIZE < (1UL << 53)) {
 		/* Upgrade the page table to 4 levels and retry. */
-		rc = crst_table_upgrade(mm, 1UL << 53);
+		rc = crst_table_upgrade(mm);
 		if (rc)
 			return (unsigned long) rc;
 		area = arch_get_unmapped_area_topdown(filp, addr, len,
--- zfcpdump-kernel-4.4.orig/arch/s390/mm/pgtable.c
+++ zfcpdump-kernel-4.4/arch/s390/mm/pgtable.c
@@ -49,81 +49,52 @@ static void __crst_table_upgrade(void *a
 	__tlb_flush_local();
 }
 
-int crst_table_upgrade(struct mm_struct *mm, unsigned long limit)
+int crst_table_upgrade(struct mm_struct *mm)
 {
 	unsigned long *table, *pgd;
-	unsigned long entry;
-	int flush;
 
-	BUG_ON(limit > (1UL << 53));
-	flush = 0;
-repeat:
+	/* upgrade should only happen from 3 to 4 levels */
+	BUG_ON(mm->context.asce_limit != (1UL << 42));
+
 	table = crst_table_alloc(mm);
 	if (!table)
 		return -ENOMEM;
+
 	spin_lock_bh(&mm->page_table_lock);
-	if (mm->context.asce_limit < limit) {
-		pgd = (unsigned long *) mm->pgd;
-		if (mm->context.asce_limit <= (1UL << 31)) {
-			entry = _REGION3_ENTRY_EMPTY;
-			mm->context.asce_limit = 1UL << 42;
-			mm->context.asce_bits = _ASCE_TABLE_LENGTH |
-						_ASCE_USER_BITS |
-						_ASCE_TYPE_REGION3;
-		} else {
-			entry = _REGION2_ENTRY_EMPTY;
-			mm->context.asce_limit = 1UL << 53;
-			mm->context.asce_bits = _ASCE_TABLE_LENGTH |
-						_ASCE_USER_BITS |
-						_ASCE_TYPE_REGION2;
-		}
-		crst_table_init(table, entry);
-		pgd_populate(mm, (pgd_t *) table, (pud_t *) pgd);
-		mm->pgd = (pgd_t *) table;
-		mm->task_size = mm->context.asce_limit;
-		table = NULL;
-		flush = 1;
-	}
+	pgd = (unsigned long *) mm->pgd;
+	crst_table_init(table, _REGION2_ENTRY_EMPTY);
+	pgd_populate(mm, (pgd_t *) table, (pud_t *) pgd);
+	mm->pgd = (pgd_t *) table;
+	mm->context.asce_limit = 1UL << 53;
+	mm->context.asce = __pa(mm->pgd) | _ASCE_TABLE_LENGTH |
+			   _ASCE_USER_BITS | _ASCE_TYPE_REGION2;
+	mm->task_size = mm->context.asce_limit;
 	spin_unlock_bh(&mm->page_table_lock);
-	if (table)
-		crst_table_free(mm, table);
-	if (mm->context.asce_limit < limit)
-		goto repeat;
-	if (flush)
-		on_each_cpu(__crst_table_upgrade, mm, 0);
+
+	on_each_cpu(__crst_table_upgrade, mm, 0);
 	return 0;
 }
 
-void crst_table_downgrade(struct mm_struct *mm, unsigned long limit)
+void crst_table_downgrade(struct mm_struct *mm)
 {
 	pgd_t *pgd;
 
+	/* downgrade should only happen from 3 to 2 levels (compat only) */
+	BUG_ON(mm->context.asce_limit != (1UL << 42));
+
 	if (current->active_mm == mm) {
 		clear_user_asce();
 		__tlb_flush_mm(mm);
 	}
-	while (mm->context.asce_limit > limit) {
-		pgd = mm->pgd;
-		switch (pgd_val(*pgd) & _REGION_ENTRY_TYPE_MASK) {
-		case _REGION_ENTRY_TYPE_R2:
-			mm->context.asce_limit = 1UL << 42;
-			mm->context.asce_bits = _ASCE_TABLE_LENGTH |
-						_ASCE_USER_BITS |
-						_ASCE_TYPE_REGION3;
-			break;
-		case _REGION_ENTRY_TYPE_R3:
-			mm->context.asce_limit = 1UL << 31;
-			mm->context.asce_bits = _ASCE_TABLE_LENGTH |
-						_ASCE_USER_BITS |
-						_ASCE_TYPE_SEGMENT;
-			break;
-		default:
-			BUG();
-		}
-		mm->pgd = (pgd_t *) (pgd_val(*pgd) & _REGION_ENTRY_ORIGIN);
-		mm->task_size = mm->context.asce_limit;
-		crst_table_free(mm, (unsigned long *) pgd);
-	}
+
+	pgd = mm->pgd;
+	mm->pgd = (pgd_t *) (pgd_val(*pgd) & _REGION_ENTRY_ORIGIN);
+	mm->context.asce_limit = 1UL << 31;
+	mm->context.asce = __pa(mm->pgd) | _ASCE_TABLE_LENGTH |
+			   _ASCE_USER_BITS | _ASCE_TYPE_SEGMENT;
+	mm->task_size = mm->context.asce_limit;
+	crst_table_free(mm, (unsigned long *) pgd);
+
 	if (current->active_mm == mm)
 		set_user_asce(mm);
 }
--- zfcpdump-kernel-4.4.orig/arch/s390/net/bpf_jit.h
+++ zfcpdump-kernel-4.4/arch/s390/net/bpf_jit.h
@@ -37,7 +37,7 @@ extern u8 sk_load_word[], sk_load_half[]
  *	      |		      |     |
  *	      +---------------+     |
  *	      | 8 byte skbp   |     |
- * R15+170 -> +---------------+     |
+ * R15+176 -> +---------------+     |
  *	      | 8 byte hlen   |     |
  * R15+168 -> +---------------+     |
  *	      | 4 byte align  |     |
@@ -58,7 +58,7 @@ extern u8 sk_load_word[], sk_load_half[]
 #define STK_OFF		(STK_SPACE - STK_160_UNUSED)
 #define STK_OFF_TMP	160	/* Offset of tmp buffer on stack */
 #define STK_OFF_HLEN	168	/* Offset of SKB header length on stack */
-#define STK_OFF_SKBP	170	/* Offset of SKB pointer on stack */
+#define STK_OFF_SKBP	176	/* Offset of SKB pointer on stack */
 
 #define STK_OFF_R6	(160 - 11 * 8)	/* Offset of r6 on stack */
 #define STK_OFF_TCCNT	(160 - 12 * 8)	/* Offset of tail_call_cnt on stack */
--- zfcpdump-kernel-4.4.orig/arch/s390/net/bpf_jit_comp.c
+++ zfcpdump-kernel-4.4/arch/s390/net/bpf_jit_comp.c
@@ -45,7 +45,7 @@ struct bpf_jit {
 	int labels[1];		/* Labels for local jumps */
 };
 
-#define BPF_SIZE_MAX	0x7ffff	/* Max size for program (20 bit signed displ) */
+#define BPF_SIZE_MAX	0xffff	/* Max size for program (16 bit branches) */
 
 #define SEEN_SKB	1	/* skb access */
 #define SEEN_MEM	2	/* use mem[] for temporary storage */
@@ -446,7 +446,7 @@ static void bpf_jit_prologue(struct bpf_
 		emit_load_skb_data_hlen(jit);
 	if (jit->seen & SEEN_SKB_CHANGE)
 		/* stg %b1,ST_OFF_SKBP(%r0,%r15) */
-		EMIT6_DISP_LH(0xe3000000, 0x0024, REG_W1, REG_0, REG_15,
+		EMIT6_DISP_LH(0xe3000000, 0x0024, BPF_REG_1, REG_0, REG_15,
 			      STK_OFF_SKBP);
 	/* Clear A (%b0) and X (%b7) registers for converted BPF programs */
 	if (is_classic) {
--- zfcpdump-kernel-4.4.orig/arch/s390/pci/pci.c
+++ zfcpdump-kernel-4.4/arch/s390/pci/pci.c
@@ -68,9 +68,12 @@ static struct airq_struct zpci_airq = {
 	.isc = PCI_ISC,
 };
 
-/* I/O Map */
+#define ZPCI_IOMAP_ENTRIES						\
+	min(((unsigned long) CONFIG_PCI_NR_FUNCTIONS * PCI_BAR_COUNT),	\
+	    ZPCI_IOMAP_MAX_ENTRIES)
+
 static DEFINE_SPINLOCK(zpci_iomap_lock);
-static DECLARE_BITMAP(zpci_iomap, ZPCI_IOMAP_MAX_ENTRIES);
+static unsigned long *zpci_iomap_bitmap;
 struct zpci_iomap_entry *zpci_iomap_start;
 EXPORT_SYMBOL_GPL(zpci_iomap_start);
 
@@ -265,27 +268,20 @@ void __iomem *pci_iomap_range(struct pci
 			      unsigned long max)
 {
 	struct zpci_dev *zdev =	to_zpci(pdev);
-	u64 addr;
 	int idx;
 
-	if ((bar & 7) != bar)
+	if (!pci_resource_len(pdev, bar))
 		return NULL;
 
 	idx = zdev->bars[bar].map_idx;
 	spin_lock(&zpci_iomap_lock);
-	if (zpci_iomap_start[idx].count++) {
-		BUG_ON(zpci_iomap_start[idx].fh != zdev->fh ||
-		       zpci_iomap_start[idx].bar != bar);
-	} else {
-		zpci_iomap_start[idx].fh = zdev->fh;
-		zpci_iomap_start[idx].bar = bar;
-	}
 	/* Detect overrun */
-	BUG_ON(!zpci_iomap_start[idx].count);
+	WARN_ON(!++zpci_iomap_start[idx].count);
+	zpci_iomap_start[idx].fh = zdev->fh;
+	zpci_iomap_start[idx].bar = bar;
 	spin_unlock(&zpci_iomap_lock);
 
-	addr = ZPCI_IOMAP_ADDR_BASE | ((u64) idx << 48);
-	return (void __iomem *) addr + offset;
+	return (void __iomem *) ZPCI_ADDR(idx) + offset;
 }
 EXPORT_SYMBOL(pci_iomap_range);
 
@@ -297,12 +293,11 @@ EXPORT_SYMBOL(pci_iomap);
 
 void pci_iounmap(struct pci_dev *pdev, void __iomem *addr)
 {
-	unsigned int idx;
+	unsigned int idx = ZPCI_IDX(addr);
 
-	idx = (((__force u64) addr) & ~ZPCI_IOMAP_ADDR_BASE) >> 48;
 	spin_lock(&zpci_iomap_lock);
 	/* Detect underrun */
-	BUG_ON(!zpci_iomap_start[idx].count);
+	WARN_ON(!zpci_iomap_start[idx].count);
 	if (!--zpci_iomap_start[idx].count) {
 		zpci_iomap_start[idx].fh = 0;
 		zpci_iomap_start[idx].bar = 0;
@@ -544,15 +539,15 @@ static void zpci_irq_exit(void)
 
 static int zpci_alloc_iomap(struct zpci_dev *zdev)
 {
-	int entry;
+	unsigned long entry;
 
 	spin_lock(&zpci_iomap_lock);
-	entry = find_first_zero_bit(zpci_iomap, ZPCI_IOMAP_MAX_ENTRIES);
-	if (entry == ZPCI_IOMAP_MAX_ENTRIES) {
+	entry = find_first_zero_bit(zpci_iomap_bitmap, ZPCI_IOMAP_ENTRIES);
+	if (entry == ZPCI_IOMAP_ENTRIES) {
 		spin_unlock(&zpci_iomap_lock);
 		return -ENOSPC;
 	}
-	set_bit(entry, zpci_iomap);
+	set_bit(entry, zpci_iomap_bitmap);
 	spin_unlock(&zpci_iomap_lock);
 	return entry;
 }
@@ -561,7 +556,7 @@ static void zpci_free_iomap(struct zpci_
 {
 	spin_lock(&zpci_iomap_lock);
 	memset(&zpci_iomap_start[entry], 0, sizeof(struct zpci_iomap_entry));
-	clear_bit(entry, zpci_iomap);
+	clear_bit(entry, zpci_iomap_bitmap);
 	spin_unlock(&zpci_iomap_lock);
 }
 
@@ -611,8 +606,7 @@ static int zpci_setup_bus_resources(stru
 		if (zdev->bars[i].val & 4)
 			flags |= IORESOURCE_MEM_64;
 
-		addr = ZPCI_IOMAP_ADDR_BASE + ((u64) entry << 48);
-
+		addr = ZPCI_ADDR(entry);
 		size = 1UL << zdev->bars[i].size;
 
 		res = __alloc_res(zdev, addr, size, flags);
@@ -643,11 +637,9 @@ static void zpci_cleanup_bus_resources(s
 
 int pcibios_add_device(struct pci_dev *pdev)
 {
-	struct zpci_dev *zdev = to_zpci(pdev);
 	struct resource *res;
 	int i;
 
-	zdev->pdev = pdev;
 	pdev->dev.groups = zpci_attr_groups;
 	zpci_map_resources(pdev);
 
@@ -670,8 +662,7 @@ int pcibios_enable_device(struct pci_dev
 {
 	struct zpci_dev *zdev = to_zpci(pdev);
 
-	zdev->pdev = pdev;
-	zpci_debug_init_device(zdev);
+	zpci_debug_init_device(zdev, dev_name(&pdev->dev));
 	zpci_fmb_enable_device(zdev);
 
 	return pci_enable_resources(pdev, mask);
@@ -683,7 +674,6 @@ void pcibios_disable_device(struct pci_d
 
 	zpci_fmb_disable_device(zdev);
 	zpci_debug_exit_device(zdev);
-	zdev->pdev = NULL;
 }
 
 #ifdef CONFIG_HIBERNATE_CALLBACKS
@@ -701,8 +691,7 @@ static int zpci_restore(struct device *d
 		goto out;
 
 	zpci_map_resources(pdev);
-	zpci_register_ioat(zdev, 0, zdev->start_dma + PAGE_OFFSET,
-			   zdev->start_dma + zdev->iommu_size - 1,
+	zpci_register_ioat(zdev, 0, zdev->start_dma, zdev->end_dma,
 			   (u64) zdev->dma_table);
 
 out:
@@ -871,26 +860,36 @@ static inline int barsize(u8 size)
 
 static int zpci_mem_init(void)
 {
+	BUILD_BUG_ON(!is_power_of_2(__alignof__(struct zpci_fmb)) ||
+		     __alignof__(struct zpci_fmb) < sizeof(struct zpci_fmb));
+
 	zdev_fmb_cache = kmem_cache_create("PCI_FMB_cache", sizeof(struct zpci_fmb),
-				16, 0, NULL);
+					   __alignof__(struct zpci_fmb), 0, NULL);
 	if (!zdev_fmb_cache)
-		goto error_zdev;
+		goto error_fmb;
 
-	/* TODO: use realloc */
-	zpci_iomap_start = kzalloc(ZPCI_IOMAP_MAX_ENTRIES * sizeof(*zpci_iomap_start),
-				   GFP_KERNEL);
+	zpci_iomap_start = kcalloc(ZPCI_IOMAP_ENTRIES,
+				   sizeof(*zpci_iomap_start), GFP_KERNEL);
 	if (!zpci_iomap_start)
 		goto error_iomap;
-	return 0;
 
+	zpci_iomap_bitmap = kcalloc(BITS_TO_LONGS(ZPCI_IOMAP_ENTRIES),
+				    sizeof(*zpci_iomap_bitmap), GFP_KERNEL);
+	if (!zpci_iomap_bitmap)
+		goto error_iomap_bitmap;
+
+	return 0;
+error_iomap_bitmap:
+	kfree(zpci_iomap_start);
 error_iomap:
 	kmem_cache_destroy(zdev_fmb_cache);
-error_zdev:
+error_fmb:
 	return -ENOMEM;
 }
 
 static void zpci_mem_exit(void)
 {
+	kfree(zpci_iomap_bitmap);
 	kfree(zpci_iomap_start);
 	kmem_cache_destroy(zdev_fmb_cache);
 }
--- zfcpdump-kernel-4.4.orig/arch/s390/pci/pci_clp.c
+++ zfcpdump-kernel-4.4/arch/s390/pci/pci_clp.c
@@ -8,13 +8,19 @@
 #define KMSG_COMPONENT "zpci"
 #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
 
+#include <linux/compat.h>
 #include <linux/kernel.h>
+#include <linux/miscdevice.h>
 #include <linux/slab.h>
 #include <linux/err.h>
 #include <linux/delay.h>
 #include <linux/pci.h>
+#include <linux/uaccess.h>
 #include <asm/pci_debug.h>
 #include <asm/pci_clp.h>
+#include <asm/compat.h>
+#include <asm/clp.h>
+#include <uapi/asm/clp.h>
 
 static inline void zpci_err_clp(unsigned int rsp, int rc)
 {
@@ -27,21 +33,43 @@ static inline void zpci_err_clp(unsigned
 }
 
 /*
- * Call Logical Processor
- * Retry logic is handled by the caller.
+ * Call Logical Processor with c=1, lps=0 and command 1
+ * to get the bit mask of installed logical processors
  */
-static inline u8 clp_instr(void *data)
+static inline int clp_get_ilp(unsigned long *ilp)
+{
+	unsigned long mask;
+	int cc = 3;
+
+	asm volatile (
+		"	.insn	rrf,0xb9a00000,%[mask],%[cmd],8,0\n"
+		"0:	ipm	%[cc]\n"
+		"	srl	%[cc],28\n"
+		"1:\n"
+		EX_TABLE(0b, 1b)
+		: [cc] "+d" (cc), [mask] "=d" (mask) : [cmd] "a" (1)
+		: "cc");
+	*ilp = mask;
+	return cc;
+}
+
+/*
+ * Call Logical Processor with c=0, the give constant lps and an lpcb request.
+ */
+static inline int clp_req(void *data, unsigned int lps)
 {
 	struct { u8 _[CLP_BLK_SIZE]; } *req = data;
 	u64 ignored;
-	u8 cc;
+	int cc = 3;
 
 	asm volatile (
-		"	.insn	rrf,0xb9a00000,%[ign],%[req],0x0,0x2\n"
-		"	ipm	%[cc]\n"
+		"	.insn	rrf,0xb9a00000,%[ign],%[req],0,%[lps]\n"
+		"0:	ipm	%[cc]\n"
 		"	srl	%[cc],28\n"
-		: [cc] "=d" (cc), [ign] "=d" (ignored), "+m" (*req)
-		: [req] "a" (req)
+		"1:\n"
+		EX_TABLE(0b, 1b)
+		: [cc] "+d" (cc), [ign] "=d" (ignored), "+m" (*req)
+		: [req] "a" (req), [lps] "i" (lps)
 		: "cc");
 	return cc;
 }
@@ -90,7 +118,7 @@ static int clp_query_pci_fngrp(struct zp
 	rrb->response.hdr.len = sizeof(rrb->response);
 	rrb->request.pfgid = pfgid;
 
-	rc = clp_instr(rrb);
+	rc = clp_req(rrb, CLP_LPS_PCI);
 	if (!rc && rrb->response.hdr.rsp == CLP_RC_OK)
 		clp_store_query_pci_fngrp(zdev, &rrb->response);
 	else {
@@ -143,7 +171,7 @@ static int clp_query_pci_fn(struct zpci_
 	rrb->response.hdr.len = sizeof(rrb->response);
 	rrb->request.fh = fh;
 
-	rc = clp_instr(rrb);
+	rc = clp_req(rrb, CLP_LPS_PCI);
 	if (!rc && rrb->response.hdr.rsp == CLP_RC_OK) {
 		rc = clp_store_query_pci_fn(zdev, &rrb->response);
 		if (rc)
@@ -214,7 +242,7 @@ static int clp_set_pci_fn(u32 *fh, u8 nr
 		rrb->request.oc = command;
 		rrb->request.ndas = nr_dma_as;
 
-		rc = clp_instr(rrb);
+		rc = clp_req(rrb, CLP_LPS_PCI);
 		if (rrb->response.hdr.rsp == CLP_RC_SETPCIFN_BUSY) {
 			retries--;
 			if (retries < 0)
@@ -280,7 +308,7 @@ static int clp_list_pci(struct clp_req_r
 		rrb->request.resume_token = resume_token;
 
 		/* Get PCI function handle list */
-		rc = clp_instr(rrb);
+		rc = clp_req(rrb, CLP_LPS_PCI);
 		if (rc || rrb->response.hdr.rsp != CLP_RC_OK) {
 			zpci_err("List PCI FN:\n");
 			zpci_err_clp(rrb->response.hdr.rsp, rc);
@@ -391,3 +419,198 @@ int clp_rescan_pci_devices_simple(void)
 	clp_free_block(rrb);
 	return rc;
 }
+
+static int clp_base_slpc(struct clp_req *req, struct clp_req_rsp_slpc *lpcb)
+{
+	unsigned long limit = PAGE_SIZE - sizeof(lpcb->request);
+
+	if (lpcb->request.hdr.len != sizeof(lpcb->request) ||
+	    lpcb->response.hdr.len > limit)
+		return -EINVAL;
+	return clp_req(lpcb, CLP_LPS_BASE) ? -EOPNOTSUPP : 0;
+}
+
+static int clp_base_command(struct clp_req *req, struct clp_req_hdr *lpcb)
+{
+	switch (lpcb->cmd) {
+	case 0x0001: /* store logical-processor characteristics */
+		return clp_base_slpc(req, (void *) lpcb);
+	default:
+		return -EINVAL;
+	}
+}
+
+static int clp_pci_slpc(struct clp_req *req, struct clp_req_rsp_slpc *lpcb)
+{
+	unsigned long limit = PAGE_SIZE - sizeof(lpcb->request);
+
+	if (lpcb->request.hdr.len != sizeof(lpcb->request) ||
+	    lpcb->response.hdr.len > limit)
+		return -EINVAL;
+	return clp_req(lpcb, CLP_LPS_PCI) ? -EOPNOTSUPP : 0;
+}
+
+static int clp_pci_list(struct clp_req *req, struct clp_req_rsp_list_pci *lpcb)
+{
+	unsigned long limit = PAGE_SIZE - sizeof(lpcb->request);
+
+	if (lpcb->request.hdr.len != sizeof(lpcb->request) ||
+	    lpcb->response.hdr.len > limit)
+		return -EINVAL;
+	if (lpcb->request.reserved2 != 0)
+		return -EINVAL;
+	return clp_req(lpcb, CLP_LPS_PCI) ? -EOPNOTSUPP : 0;
+}
+
+static int clp_pci_query(struct clp_req *req,
+			 struct clp_req_rsp_query_pci *lpcb)
+{
+	unsigned long limit = PAGE_SIZE - sizeof(lpcb->request);
+
+	if (lpcb->request.hdr.len != sizeof(lpcb->request) ||
+	    lpcb->response.hdr.len > limit)
+		return -EINVAL;
+	if (lpcb->request.reserved2 != 0 || lpcb->request.reserved3 != 0)
+		return -EINVAL;
+	return clp_req(lpcb, CLP_LPS_PCI) ? -EOPNOTSUPP : 0;
+}
+
+static int clp_pci_query_grp(struct clp_req *req,
+			     struct clp_req_rsp_query_pci_grp *lpcb)
+{
+	unsigned long limit = PAGE_SIZE - sizeof(lpcb->request);
+
+	if (lpcb->request.hdr.len != sizeof(lpcb->request) ||
+	    lpcb->response.hdr.len > limit)
+		return -EINVAL;
+	if (lpcb->request.reserved2 != 0 || lpcb->request.reserved3 != 0 ||
+	    lpcb->request.reserved4 != 0)
+		return -EINVAL;
+	return clp_req(lpcb, CLP_LPS_PCI) ? -EOPNOTSUPP : 0;
+}
+
+static int clp_pci_command(struct clp_req *req, struct clp_req_hdr *lpcb)
+{
+	switch (lpcb->cmd) {
+	case 0x0001: /* store logical-processor characteristics */
+		return clp_pci_slpc(req, (void *) lpcb);
+	case 0x0002: /* list PCI functions */
+		return clp_pci_list(req, (void *) lpcb);
+	case 0x0003: /* query PCI function */
+		return clp_pci_query(req, (void *) lpcb);
+	case 0x0004: /* query PCI function group */
+		return clp_pci_query_grp(req, (void *) lpcb);
+	default:
+		return -EINVAL;
+	}
+}
+
+static int clp_normal_command(struct clp_req *req)
+{
+	struct clp_req_hdr *lpcb;
+	void __user *uptr;
+	int rc;
+
+	rc = -EINVAL;
+	if (req->lps != 0 && req->lps != 2)
+		goto out;
+
+	rc = -ENOMEM;
+	lpcb = clp_alloc_block(GFP_KERNEL);
+	if (!lpcb)
+		goto out;
+
+	rc = -EFAULT;
+	uptr = (void __force __user *)(unsigned long) req->data_p;
+	if (copy_from_user(lpcb, uptr, PAGE_SIZE) != 0)
+		goto out_free;
+
+	rc = -EINVAL;
+	if (lpcb->fmt != 0 || lpcb->reserved1 != 0 || lpcb->reserved2 != 0)
+		goto out_free;
+
+	switch (req->lps) {
+	case 0:
+		rc = clp_base_command(req, lpcb);
+		break;
+	case 2:
+		rc = clp_pci_command(req, lpcb);
+		break;
+	}
+	if (rc)
+		goto out_free;
+
+	rc = -EFAULT;
+	if (copy_to_user(uptr, lpcb, PAGE_SIZE) != 0)
+		goto out_free;
+
+	rc = 0;
+
+out_free:
+	clp_free_block(lpcb);
+out:
+	return rc;
+}
+
+static int clp_immediate_command(struct clp_req *req)
+{
+	void __user *uptr;
+	unsigned long ilp;
+	int exists;
+
+	if (req->cmd > 1 || clp_get_ilp(&ilp) != 0)
+		return -EINVAL;
+
+	uptr = (void __force __user *)(unsigned long) req->data_p;
+	if (req->cmd == 0) {
+		/* Command code 0: test for a specific processor */
+		exists = test_bit_inv(req->lps, &ilp);
+		return put_user(exists, (int __user *) uptr);
+	}
+	/* Command code 1: return bit mask of installed processors */
+	return put_user(ilp, (unsigned long __user *) uptr);
+}
+
+static long clp_misc_ioctl(struct file *filp, unsigned int cmd,
+			   unsigned long arg)
+{
+	struct clp_req req;
+	void __user *argp;
+
+	if (cmd != CLP_SYNC)
+		return -EINVAL;
+
+	argp = is_compat_task() ? compat_ptr(arg) : (void __user *) arg;
+	if (copy_from_user(&req, argp, sizeof(req)))
+		return -EFAULT;
+	if (req.r != 0)
+		return -EINVAL;
+	return req.c ? clp_immediate_command(&req) : clp_normal_command(&req);
+}
+
+static int clp_misc_release(struct inode *inode, struct file *filp)
+{
+	return 0;
+}
+
+static const struct file_operations clp_misc_fops = {
+	.owner = THIS_MODULE,
+	.open = nonseekable_open,
+	.release = clp_misc_release,
+	.unlocked_ioctl = clp_misc_ioctl,
+	.compat_ioctl = clp_misc_ioctl,
+	.llseek = no_llseek,
+};
+
+static struct miscdevice clp_misc_device = {
+	.minor = MISC_DYNAMIC_MINOR,
+	.name = "clp",
+	.fops = &clp_misc_fops,
+};
+
+static int __init clp_misc_init(void)
+{
+	return misc_register(&clp_misc_device);
+}
+
+device_initcall(clp_misc_init);
--- zfcpdump-kernel-4.4.orig/arch/s390/pci/pci_debug.c
+++ zfcpdump-kernel-4.4/arch/s390/pci/pci_debug.c
@@ -128,10 +128,9 @@ static const struct file_operations debu
 	.release = single_release,
 };
 
-void zpci_debug_init_device(struct zpci_dev *zdev)
+void zpci_debug_init_device(struct zpci_dev *zdev, const char *name)
 {
-	zdev->debugfs_dev = debugfs_create_dir(dev_name(&zdev->pdev->dev),
-					       debugfs_root);
+	zdev->debugfs_dev = debugfs_create_dir(name, debugfs_root);
 	if (IS_ERR(zdev->debugfs_dev))
 		zdev->debugfs_dev = NULL;
 
--- zfcpdump-kernel-4.4.orig/arch/s390/pci/pci_dma.c
+++ zfcpdump-kernel-4.4/arch/s390/pci/pci_dma.c
@@ -217,27 +217,29 @@ void dma_cleanup_tables(unsigned long *t
 	dma_free_cpu_table(table);
 }
 
-static unsigned long __dma_alloc_iommu(struct zpci_dev *zdev,
+static unsigned long __dma_alloc_iommu(struct device *dev,
 				       unsigned long start, int size)
 {
+	struct zpci_dev *zdev = to_zpci(to_pci_dev(dev));
 	unsigned long boundary_size;
 
-	boundary_size = ALIGN(dma_get_seg_boundary(&zdev->pdev->dev) + 1,
+	boundary_size = ALIGN(dma_get_seg_boundary(dev) + 1,
 			      PAGE_SIZE) >> PAGE_SHIFT;
 	return iommu_area_alloc(zdev->iommu_bitmap, zdev->iommu_pages,
 				start, size, 0, boundary_size, 0);
 }
 
-static unsigned long dma_alloc_iommu(struct zpci_dev *zdev, int size)
+static unsigned long dma_alloc_iommu(struct device *dev, int size)
 {
+	struct zpci_dev *zdev = to_zpci(to_pci_dev(dev));
 	unsigned long offset, flags;
 	int wrap = 0;
 
 	spin_lock_irqsave(&zdev->iommu_bitmap_lock, flags);
-	offset = __dma_alloc_iommu(zdev, zdev->next_bit, size);
+	offset = __dma_alloc_iommu(dev, zdev->next_bit, size);
 	if (offset == -1) {
 		/* wrap-around */
-		offset = __dma_alloc_iommu(zdev, 0, size);
+		offset = __dma_alloc_iommu(dev, 0, size);
 		wrap = 1;
 	}
 
@@ -251,8 +253,9 @@ static unsigned long dma_alloc_iommu(str
 	return offset;
 }
 
-static void dma_free_iommu(struct zpci_dev *zdev, unsigned long offset, int size)
+static void dma_free_iommu(struct device *dev, unsigned long offset, int size)
 {
+	struct zpci_dev *zdev = to_zpci(to_pci_dev(dev));
 	unsigned long flags;
 
 	spin_lock_irqsave(&zdev->iommu_bitmap_lock, flags);
@@ -293,7 +296,7 @@ static dma_addr_t s390_dma_map_pages(str
 
 	/* This rounds up number of pages based on size and offset */
 	nr_pages = iommu_num_pages(pa, size, PAGE_SIZE);
-	iommu_page_index = dma_alloc_iommu(zdev, nr_pages);
+	iommu_page_index = dma_alloc_iommu(dev, nr_pages);
 	if (iommu_page_index == -1) {
 		ret = -ENOSPC;
 		goto out_err;
@@ -319,7 +322,7 @@ static dma_addr_t s390_dma_map_pages(str
 	return dma_addr + (offset & ~PAGE_MASK);
 
 out_free:
-	dma_free_iommu(zdev, iommu_page_index, nr_pages);
+	dma_free_iommu(dev, iommu_page_index, nr_pages);
 out_err:
 	zpci_err("map error:\n");
 	zpci_err_dma(ret, pa);
@@ -346,7 +349,7 @@ static void s390_dma_unmap_pages(struct
 
 	atomic64_add(npages, &zdev->unmapped_pages);
 	iommu_page_index = (dma_addr - zdev->start_dma) >> PAGE_SHIFT;
-	dma_free_iommu(zdev, iommu_page_index, npages);
+	dma_free_iommu(dev, iommu_page_index, npages);
 }
 
 static void *s390_dma_alloc(struct device *dev, size_t size,
@@ -366,8 +369,7 @@ static void *s390_dma_alloc(struct devic
 	pa = page_to_phys(page);
 	memset((void *) pa, 0, size);
 
-	map = s390_dma_map_pages(dev, page, pa % PAGE_SIZE,
-				 size, DMA_BIDIRECTIONAL, NULL);
+	map = s390_dma_map_pages(dev, page, 0, size, DMA_BIDIRECTIONAL, NULL);
 	if (dma_mapping_error(dev, map)) {
 		free_pages(pa, get_order(size));
 		return NULL;
@@ -455,29 +457,42 @@ int zpci_dma_init_device(struct zpci_dev
 	zdev->dma_table = dma_alloc_cpu_table();
 	if (!zdev->dma_table) {
 		rc = -ENOMEM;
-		goto out_clean;
+		goto out;
 	}
 
-	zdev->iommu_size = (unsigned long) high_memory - PAGE_OFFSET;
+	/*
+	 * Restrict the iommu bitmap size to the minimum of the following:
+	 * - main memory size
+	 * - 3-level pagetable address limit minus start_dma offset
+	 * - DMA address range allowed by the hardware (clp query pci fn)
+	 *
+	 * Also set zdev->end_dma to the actual end address of the usable
+	 * range, instead of the theoretical maximum as reported by hardware.
+	 */
+	zdev->iommu_size = min3((u64) high_memory,
+				ZPCI_TABLE_SIZE_RT - zdev->start_dma,
+				zdev->end_dma - zdev->start_dma + 1);
+	zdev->end_dma = zdev->start_dma + zdev->iommu_size - 1;
 	zdev->iommu_pages = zdev->iommu_size >> PAGE_SHIFT;
 	zdev->iommu_bitmap = vzalloc(zdev->iommu_pages / 8);
 	if (!zdev->iommu_bitmap) {
 		rc = -ENOMEM;
-		goto out_reg;
+		goto free_dma_table;
 	}
 
-	rc = zpci_register_ioat(zdev,
-				0,
-				zdev->start_dma + PAGE_OFFSET,
-				zdev->start_dma + zdev->iommu_size - 1,
+	rc = zpci_register_ioat(zdev, 0, zdev->start_dma, zdev->end_dma,
 				(u64) zdev->dma_table);
 	if (rc)
-		goto out_reg;
-	return 0;
+		goto free_bitmap;
 
-out_reg:
+	return 0;
+free_bitmap:
+	vfree(zdev->iommu_bitmap);
+	zdev->iommu_bitmap = NULL;
+free_dma_table:
 	dma_free_cpu_table(zdev->dma_table);
-out_clean:
+	zdev->dma_table = NULL;
+out:
 	return rc;
 }
 
--- zfcpdump-kernel-4.4.orig/arch/s390/pci/pci_event.c
+++ zfcpdump-kernel-4.4/arch/s390/pci/pci_event.c
@@ -46,13 +46,22 @@ struct zpci_ccdf_avail {
 static void __zpci_event_error(struct zpci_ccdf_err *ccdf)
 {
 	struct zpci_dev *zdev = get_zdev_by_fid(ccdf->fid);
-	struct pci_dev *pdev = zdev ? zdev->pdev : NULL;
+	struct pci_dev *pdev = NULL;
 
 	zpci_err("error CCDF:\n");
 	zpci_err_hex(ccdf, sizeof(*ccdf));
 
+	if (zdev)
+		pdev = pci_get_slot(zdev->bus, ZPCI_DEVFN);
+
 	pr_err("%s: Event 0x%x reports an error for PCI function 0x%x\n",
 	       pdev ? pci_name(pdev) : "n/a", ccdf->pec, ccdf->fid);
+
+	if (!pdev)
+		return;
+
+	pdev->error_state = pci_channel_io_perm_failure;
+	pci_dev_put(pdev);
 }
 
 void zpci_event_error(void *data)
@@ -64,9 +73,12 @@ void zpci_event_error(void *data)
 static void __zpci_event_availability(struct zpci_ccdf_avail *ccdf)
 {
 	struct zpci_dev *zdev = get_zdev_by_fid(ccdf->fid);
-	struct pci_dev *pdev = zdev ? zdev->pdev : NULL;
+	struct pci_dev *pdev = NULL;
 	int ret;
 
+	if (zdev)
+		pdev = pci_get_slot(zdev->bus, ZPCI_DEVFN);
+
 	pr_info("%s: Event 0x%x reconfigured PCI function 0x%x\n",
 		pdev ? pci_name(pdev) : "n/a", ccdf->pec, ccdf->fid);
 	zpci_err("avail CCDF:\n");
@@ -133,6 +145,8 @@ static void __zpci_event_availability(st
 	default:
 		break;
 	}
+	if (pdev)
+		pci_dev_put(pdev);
 }
 
 void zpci_event_availability(void *data)
--- zfcpdump-kernel-4.4.orig/arch/score/include/asm/uaccess.h
+++ zfcpdump-kernel-4.4/arch/score/include/asm/uaccess.h
@@ -163,7 +163,7 @@ do {									\
 		__get_user_asm(val, "lw", ptr);				\
 		 break;							\
 	case 8: 							\
-		if ((copy_from_user((void *)&val, ptr, 8)) == 0)	\
+		if (__copy_from_user((void *)&val, ptr, 8) == 0)	\
 			__gu_err = 0;					\
 		else							\
 			__gu_err = -EFAULT;				\
@@ -188,6 +188,8 @@ do {									\
 									\
 	if (likely(access_ok(VERIFY_READ, __gu_ptr, size)))		\
 		__get_user_common((x), size, __gu_ptr);			\
+	else								\
+		(x) = 0;						\
 									\
 	__gu_err;							\
 })
@@ -201,6 +203,7 @@ do {									\
 		"2:\n"							\
 		".section .fixup,\"ax\"\n"				\
 		"3:li	%0, %4\n"					\
+		"li	%1, 0\n"					\
 		"j	2b\n"						\
 		".previous\n"						\
 		".section __ex_table,\"a\"\n"				\
@@ -298,35 +301,34 @@ extern int __copy_tofrom_user(void *to,
 static inline unsigned long
 copy_from_user(void *to, const void *from, unsigned long len)
 {
-	unsigned long over;
+	unsigned long res = len;
 
-	if (access_ok(VERIFY_READ, from, len))
-		return __copy_tofrom_user(to, from, len);
+	if (likely(access_ok(VERIFY_READ, from, len)))
+		res = __copy_tofrom_user(to, from, len);
 
-	if ((unsigned long)from < TASK_SIZE) {
-		over = (unsigned long)from + len - TASK_SIZE;
-		return __copy_tofrom_user(to, from, len - over) + over;
-	}
-	return len;
+	if (unlikely(res))
+		memset(to + (len - res), 0, res);
+
+	return res;
 }
 
 static inline unsigned long
 copy_to_user(void *to, const void *from, unsigned long len)
 {
-	unsigned long over;
-
-	if (access_ok(VERIFY_WRITE, to, len))
-		return __copy_tofrom_user(to, from, len);
+	if (likely(access_ok(VERIFY_WRITE, to, len)))
+		len = __copy_tofrom_user(to, from, len);
 
-	if ((unsigned long)to < TASK_SIZE) {
-		over = (unsigned long)to + len - TASK_SIZE;
-		return __copy_tofrom_user(to, from, len - over) + over;
-	}
 	return len;
 }
 
-#define __copy_from_user(to, from, len)	\
-		__copy_tofrom_user((to), (from), (len))
+static inline unsigned long
+__copy_from_user(void *to, const void *from, unsigned long len)
+{
+	unsigned long left = __copy_tofrom_user(to, from, len);
+	if (unlikely(left))
+		memset(to + (len - left), 0, left);
+	return left;
+}
 
 #define __copy_to_user(to, from, len)		\
 		__copy_tofrom_user((to), (from), (len))
@@ -340,17 +342,17 @@ __copy_to_user_inatomic(void *to, const
 static inline unsigned long
 __copy_from_user_inatomic(void *to, const void *from, unsigned long len)
 {
-	return __copy_from_user(to, from, len);
+	return __copy_tofrom_user(to, from, len);
 }
 
-#define __copy_in_user(to, from, len)	__copy_from_user(to, from, len)
+#define __copy_in_user(to, from, len)	__copy_tofrom_user(to, from, len)
 
 static inline unsigned long
 copy_in_user(void *to, const void *from, unsigned long len)
 {
 	if (access_ok(VERIFY_READ, from, len) &&
 		      access_ok(VERFITY_WRITE, to, len))
-		return copy_from_user(to, from, len);
+		return __copy_tofrom_user(to, from, len);
 }
 
 /*
--- zfcpdump-kernel-4.4.orig/arch/sh/include/asm/uaccess.h
+++ zfcpdump-kernel-4.4/arch/sh/include/asm/uaccess.h
@@ -151,7 +151,10 @@ copy_from_user(void *to, const void __us
 	__kernel_size_t __copy_size = (__kernel_size_t) n;
 
 	if (__copy_size && __access_ok(__copy_from, __copy_size))
-		return __copy_user(to, from, __copy_size);
+		__copy_size = __copy_user(to, from, __copy_size);
+
+	if (unlikely(__copy_size))
+		memset(to + (n - __copy_size), 0, __copy_size);
 
 	return __copy_size;
 }
--- zfcpdump-kernel-4.4.orig/arch/sh/include/asm/uaccess_64.h
+++ zfcpdump-kernel-4.4/arch/sh/include/asm/uaccess_64.h
@@ -24,6 +24,7 @@
 #define __get_user_size(x,ptr,size,retval)			\
 do {								\
 	retval = 0;						\
+	x = 0;							\
 	switch (size) {						\
 	case 1:							\
 		retval = __get_user_asm_b((void *)&x,		\
--- zfcpdump-kernel-4.4.orig/arch/sh/mm/kmap.c
+++ zfcpdump-kernel-4.4/arch/sh/mm/kmap.c
@@ -36,6 +36,7 @@ void *kmap_coherent(struct page *page, u
 
 	BUG_ON(!test_bit(PG_dcache_clean, &page->flags));
 
+	preempt_disable();
 	pagefault_disable();
 
 	idx = FIX_CMAP_END -
@@ -64,4 +65,5 @@ void kunmap_coherent(void *kvaddr)
 	}
 
 	pagefault_enable();
+	preempt_enable();
 }
--- zfcpdump-kernel-4.4.orig/arch/sparc/include/asm/head_64.h
+++ zfcpdump-kernel-4.4/arch/sparc/include/asm/head_64.h
@@ -15,6 +15,10 @@
 
 #define	PTREGS_OFF	(STACK_BIAS + STACKFRAME_SZ)
 
+#define	RTRAP_PSTATE		(PSTATE_TSO|PSTATE_PEF|PSTATE_PRIV|PSTATE_IE)
+#define	RTRAP_PSTATE_IRQOFF	(PSTATE_TSO|PSTATE_PEF|PSTATE_PRIV)
+#define RTRAP_PSTATE_AG_IRQOFF	(PSTATE_TSO|PSTATE_PEF|PSTATE_PRIV|PSTATE_AG)
+
 #define __CHEETAH_ID	0x003e0014
 #define __JALAPENO_ID	0x003e0016
 #define __SERRANO_ID	0x003e0022
--- zfcpdump-kernel-4.4.orig/arch/sparc/include/asm/pgtable_64.h
+++ zfcpdump-kernel-4.4/arch/sparc/include/asm/pgtable_64.h
@@ -375,7 +375,7 @@ static inline pgprot_t pgprot_noncached(
 #define pgprot_noncached pgprot_noncached
 
 #if defined(CONFIG_HUGETLB_PAGE) || defined(CONFIG_TRANSPARENT_HUGEPAGE)
-static inline pte_t pte_mkhuge(pte_t pte)
+static inline unsigned long __pte_huge_mask(void)
 {
 	unsigned long mask;
 
@@ -390,8 +390,19 @@ static inline pte_t pte_mkhuge(pte_t pte
 	: "=r" (mask)
 	: "i" (_PAGE_SZHUGE_4U), "i" (_PAGE_SZHUGE_4V));
 
-	return __pte(pte_val(pte) | mask);
+	return mask;
+}
+
+static inline pte_t pte_mkhuge(pte_t pte)
+{
+	return __pte(pte_val(pte) | __pte_huge_mask());
+}
+
+static inline bool is_hugetlb_pte(pte_t pte)
+{
+	return !!(pte_val(pte) & __pte_huge_mask());
 }
+
 #ifdef CONFIG_TRANSPARENT_HUGEPAGE
 static inline pmd_t pmd_mkhuge(pmd_t pmd)
 {
@@ -403,6 +414,11 @@ static inline pmd_t pmd_mkhuge(pmd_t pmd
 	return __pmd(pte_val(pte));
 }
 #endif
+#else
+static inline bool is_hugetlb_pte(pte_t pte)
+{
+	return false;
+}
 #endif
 
 static inline pte_t pte_mkdirty(pte_t pte)
@@ -865,6 +881,19 @@ static inline unsigned long pud_pfn(pud_
 void tlb_batch_add(struct mm_struct *mm, unsigned long vaddr,
 		   pte_t *ptep, pte_t orig, int fullmm);
 
+static void maybe_tlb_batch_add(struct mm_struct *mm, unsigned long vaddr,
+				pte_t *ptep, pte_t orig, int fullmm)
+{
+	/* It is more efficient to let flush_tlb_kernel_range()
+	 * handle init_mm tlb flushes.
+	 *
+	 * SUN4V NOTE: _PAGE_VALID is the same value in both the SUN4U
+	 *             and SUN4V pte layout, so this inline test is fine.
+	 */
+	if (likely(mm != &init_mm) && pte_accessible(mm, orig))
+		tlb_batch_add(mm, vaddr, ptep, orig, fullmm);
+}
+
 #define __HAVE_ARCH_PMDP_HUGE_GET_AND_CLEAR
 static inline pmd_t pmdp_huge_get_and_clear(struct mm_struct *mm,
 					    unsigned long addr,
@@ -881,15 +910,7 @@ static inline void __set_pte_at(struct m
 	pte_t orig = *ptep;
 
 	*ptep = pte;
-
-	/* It is more efficient to let flush_tlb_kernel_range()
-	 * handle init_mm tlb flushes.
-	 *
-	 * SUN4V NOTE: _PAGE_VALID is the same value in both the SUN4U
-	 *             and SUN4V pte layout, so this inline test is fine.
-	 */
-	if (likely(mm != &init_mm) && pte_accessible(mm, orig))
-		tlb_batch_add(mm, addr, ptep, orig, fullmm);
+	maybe_tlb_batch_add(mm, addr, ptep, orig, fullmm);
 }
 
 #define set_pte_at(mm,addr,ptep,pte)	\
--- zfcpdump-kernel-4.4.orig/arch/sparc/include/asm/tlbflush_64.h
+++ zfcpdump-kernel-4.4/arch/sparc/include/asm/tlbflush_64.h
@@ -8,6 +8,7 @@
 #define TLB_BATCH_NR	192
 
 struct tlb_batch {
+	bool huge;
 	struct mm_struct *mm;
 	unsigned long tlb_nr;
 	unsigned long active;
@@ -16,7 +17,7 @@ struct tlb_batch {
 
 void flush_tsb_kernel_range(unsigned long start, unsigned long end);
 void flush_tsb_user(struct tlb_batch *tb);
-void flush_tsb_user_page(struct mm_struct *mm, unsigned long vaddr);
+void flush_tsb_user_page(struct mm_struct *mm, unsigned long vaddr, bool huge);
 
 /* TLB flush operations. */
 
--- zfcpdump-kernel-4.4.orig/arch/sparc/include/asm/ttable.h
+++ zfcpdump-kernel-4.4/arch/sparc/include/asm/ttable.h
@@ -589,8 +589,8 @@ user_rtt_fill_64bit:					\
 	 restored;					\
 	nop; nop; nop; nop; nop; nop;			\
 	nop; nop; nop; nop; nop;			\
-	ba,a,pt	%xcc, user_rtt_fill_fixup;		\
-	ba,a,pt	%xcc, user_rtt_fill_fixup;		\
+	ba,a,pt	%xcc, user_rtt_fill_fixup_dax;		\
+	ba,a,pt	%xcc, user_rtt_fill_fixup_mna;		\
 	ba,a,pt	%xcc, user_rtt_fill_fixup;
 
 
@@ -652,8 +652,8 @@ user_rtt_fill_32bit:					\
 	 restored;					\
 	nop; nop; nop; nop; nop;			\
 	nop; nop; nop;					\
-	ba,a,pt	%xcc, user_rtt_fill_fixup;		\
-	ba,a,pt	%xcc, user_rtt_fill_fixup;		\
+	ba,a,pt	%xcc, user_rtt_fill_fixup_dax;		\
+	ba,a,pt	%xcc, user_rtt_fill_fixup_mna;		\
 	ba,a,pt	%xcc, user_rtt_fill_fixup;
 
 
--- zfcpdump-kernel-4.4.orig/arch/sparc/include/asm/uaccess_32.h
+++ zfcpdump-kernel-4.4/arch/sparc/include/asm/uaccess_32.h
@@ -328,8 +328,10 @@ static inline unsigned long copy_from_us
 {
 	if (n && __access_ok((unsigned long) from, n))
 		return __copy_user((__force void __user *) to, from, n);
-	else
+	else {
+		memset(to, 0, n);
 		return n;
+	}
 }
 
 static inline unsigned long __copy_from_user(void *to, const void __user *from, unsigned long n)
--- zfcpdump-kernel-4.4.orig/arch/sparc/kernel/Makefile
+++ zfcpdump-kernel-4.4/arch/sparc/kernel/Makefile
@@ -21,6 +21,7 @@ CFLAGS_REMOVE_perf_event.o := -pg
 CFLAGS_REMOVE_pcr.o := -pg
 endif
 
+obj-$(CONFIG_SPARC64)   += urtt_fill.o
 obj-$(CONFIG_SPARC32)   += entry.o wof.o wuf.o
 obj-$(CONFIG_SPARC32)   += etrap_32.o
 obj-$(CONFIG_SPARC32)   += rtrap_32.o
--- zfcpdump-kernel-4.4.orig/arch/sparc/kernel/cherrs.S
+++ zfcpdump-kernel-4.4/arch/sparc/kernel/cherrs.S
@@ -214,8 +214,7 @@ do_dcpe_tl1_nonfatal:	/* Ok we may use i
 	subcc		%g1, %g2, %g1		! Next cacheline
 	bge,pt		%icc, 1b
 	 nop
-	ba,pt		%xcc, dcpe_icpe_tl1_common
-	 nop
+	ba,a,pt		%xcc, dcpe_icpe_tl1_common
 
 do_dcpe_tl1_fatal:
 	sethi		%hi(1f), %g7
@@ -224,8 +223,7 @@ do_dcpe_tl1_fatal:
 	mov		0x2, %o0
 	call		cheetah_plus_parity_error
 	 add		%sp, PTREGS_OFF, %o1
-	ba,pt		%xcc, rtrap
-	 nop
+	ba,a,pt		%xcc, rtrap
 	.size		do_dcpe_tl1,.-do_dcpe_tl1
 
 	.globl		do_icpe_tl1
@@ -259,8 +257,7 @@ do_icpe_tl1_nonfatal:	/* Ok we may use i
 	subcc		%g1, %g2, %g1
 	bge,pt		%icc, 1b
 	 nop
-	ba,pt		%xcc, dcpe_icpe_tl1_common
-	 nop
+	ba,a,pt		%xcc, dcpe_icpe_tl1_common
 
 do_icpe_tl1_fatal:
 	sethi		%hi(1f), %g7
@@ -269,8 +266,7 @@ do_icpe_tl1_fatal:
 	mov		0x3, %o0
 	call		cheetah_plus_parity_error
 	 add		%sp, PTREGS_OFF, %o1
-	ba,pt		%xcc, rtrap
-	 nop
+	ba,a,pt		%xcc, rtrap
 	.size		do_icpe_tl1,.-do_icpe_tl1
 	
 	.type		dcpe_icpe_tl1_common,#function
@@ -456,7 +452,7 @@ __cheetah_log_error:
 	 cmp		%g2, 0x63
 	be		c_cee
 	 nop
-	ba,pt		%xcc, c_deferred
+	ba,a,pt		%xcc, c_deferred
 	.size		__cheetah_log_error,.-__cheetah_log_error
 
 	/* Cheetah FECC trap handling, we get here from tl{0,1}_fecc
--- zfcpdump-kernel-4.4.orig/arch/sparc/kernel/entry.S
+++ zfcpdump-kernel-4.4/arch/sparc/kernel/entry.S
@@ -948,7 +948,24 @@ linux_syscall_trace:
 	cmp	%o0, 0
 	bne	3f
 	 mov	-ENOSYS, %o0
+
+	/* Syscall tracing can modify the registers.  */
+	ld	[%sp + STACKFRAME_SZ + PT_G1], %g1
+	sethi	%hi(sys_call_table), %l7
+	ld	[%sp + STACKFRAME_SZ + PT_I0], %i0
+	or	%l7, %lo(sys_call_table), %l7
+	ld	[%sp + STACKFRAME_SZ + PT_I1], %i1
+	ld	[%sp + STACKFRAME_SZ + PT_I2], %i2
+	ld	[%sp + STACKFRAME_SZ + PT_I3], %i3
+	ld	[%sp + STACKFRAME_SZ + PT_I4], %i4
+	ld	[%sp + STACKFRAME_SZ + PT_I5], %i5
+	cmp	%g1, NR_syscalls
+	bgeu	3f
+	 mov	-ENOSYS, %o0
+
+	sll	%g1, 2, %l4
 	mov	%i0, %o0
+	ld	[%l7 + %l4], %l7
 	mov	%i1, %o1
 	mov	%i2, %o2
 	mov	%i3, %o3
--- zfcpdump-kernel-4.4.orig/arch/sparc/kernel/fpu_traps.S
+++ zfcpdump-kernel-4.4/arch/sparc/kernel/fpu_traps.S
@@ -100,8 +100,8 @@ do_fpdis:
 	fmuld		%f0, %f2, %f26
 	faddd		%f0, %f2, %f28
 	fmuld		%f0, %f2, %f30
-	b,pt		%xcc, fpdis_exit
-	 nop
+	ba,a,pt		%xcc, fpdis_exit
+
 2:	andcc		%g5, FPRS_DU, %g0
 	bne,pt		%icc, 3f
 	 fzero		%f32
@@ -144,8 +144,8 @@ do_fpdis:
 	fmuld		%f32, %f34, %f58
 	faddd		%f32, %f34, %f60
 	fmuld		%f32, %f34, %f62
-	ba,pt		%xcc, fpdis_exit
-	 nop
+	ba,a,pt		%xcc, fpdis_exit
+
 3:	mov		SECONDARY_CONTEXT, %g3
 	add		%g6, TI_FPREGS, %g1
 
@@ -197,8 +197,7 @@ fpdis_exit2:
 fp_other_bounce:
 	call		do_fpother
 	 add		%sp, PTREGS_OFF, %o0
-	ba,pt		%xcc, rtrap
-	 nop
+	ba,a,pt		%xcc, rtrap
 	.size		fp_other_bounce,.-fp_other_bounce
 
 	.align		32
--- zfcpdump-kernel-4.4.orig/arch/sparc/kernel/head_64.S
+++ zfcpdump-kernel-4.4/arch/sparc/kernel/head_64.S
@@ -461,9 +461,8 @@ sun4v_chip_type:
 	subcc	%g3, 1, %g3
 	bne,pt	%xcc, 41b
 	add	%g1, 1, %g1
-	mov	SUN4V_CHIP_SPARC64X, %g4
 	ba,pt	%xcc, 5f
-	nop
+	 mov	SUN4V_CHIP_SPARC64X, %g4
 
 49:
 	mov	SUN4V_CHIP_UNKNOWN, %g4
@@ -548,8 +547,7 @@ sun4u_init:
 	stxa		%g0, [%g7] ASI_DMMU
 	membar	#Sync
 
-	ba,pt		%xcc, sun4u_continue
-	 nop
+	ba,a,pt		%xcc, sun4u_continue
 
 sun4v_init:
 	/* Set ctx 0 */
@@ -560,14 +558,12 @@ sun4v_init:
 	mov		SECONDARY_CONTEXT, %g7
 	stxa		%g0, [%g7] ASI_MMU
 	membar		#Sync
-	ba,pt		%xcc, niagara_tlb_fixup
-	 nop
+	ba,a,pt		%xcc, niagara_tlb_fixup
 
 sun4u_continue:
 	BRANCH_IF_ANY_CHEETAH(g1, g7, cheetah_tlb_fixup)
 
-	ba,pt	%xcc, spitfire_tlb_fixup
-	 nop
+	ba,a,pt	%xcc, spitfire_tlb_fixup
 
 niagara_tlb_fixup:
 	mov	3, %g2		/* Set TLB type to hypervisor. */
@@ -639,8 +635,7 @@ niagara_patch:
 	call	hypervisor_patch_cachetlbops
 	 nop
 
-	ba,pt	%xcc, tlb_fixup_done
-	 nop
+	ba,a,pt	%xcc, tlb_fixup_done
 
 cheetah_tlb_fixup:
 	mov	2, %g2		/* Set TLB type to cheetah+. */
@@ -659,8 +654,7 @@ cheetah_tlb_fixup:
 	call	cheetah_patch_cachetlbops
 	 nop
 
-	ba,pt	%xcc, tlb_fixup_done
-	 nop
+	ba,a,pt	%xcc, tlb_fixup_done
 
 spitfire_tlb_fixup:
 	/* Set TLB type to spitfire. */
@@ -782,8 +776,7 @@ setup_trap_table:
 	call	%o1
 	 add	%sp, (2047 + 128), %o0
 
-	ba,pt	%xcc, 2f
-	 nop
+	ba,a,pt	%xcc, 2f
 
 1:	sethi	%hi(sparc64_ttable_tl0), %o0
 	set	prom_set_trap_table_name, %g2
@@ -822,8 +815,7 @@ setup_trap_table:
 
 	BRANCH_IF_ANY_CHEETAH(o2, o3, 1f)
 
-	ba,pt	%xcc, 2f
-	 nop
+	ba,a,pt	%xcc, 2f
 
 	/* Disable STICK_INT interrupts. */
 1:
--- zfcpdump-kernel-4.4.orig/arch/sparc/kernel/idprom.c
+++ zfcpdump-kernel-4.4/arch/sparc/kernel/idprom.c
@@ -9,6 +9,7 @@
 #include <linux/types.h>
 #include <linux/init.h>
 #include <linux/export.h>
+#include <linux/etherdevice.h>
 
 #include <asm/oplib.h>
 #include <asm/idprom.h>
@@ -60,6 +61,12 @@ static void __init display_system_type(u
 {
 }
 #endif
+
+unsigned char *arch_get_platform_mac_address(void)
+{
+	return idprom->id_ethaddr;
+}
+
 /* Calculate the IDPROM checksum (xor of the data bytes). */
 static unsigned char __init calc_idprom_cksum(struct idprom *idprom)
 {
--- zfcpdump-kernel-4.4.orig/arch/sparc/kernel/misctrap.S
+++ zfcpdump-kernel-4.4/arch/sparc/kernel/misctrap.S
@@ -18,8 +18,7 @@ __do_privact:
 109:	or		%g7, %lo(109b), %g7
 	call		do_privact
 	 add		%sp, PTREGS_OFF, %o0
-	ba,pt		%xcc, rtrap
-	 nop
+	ba,a,pt		%xcc, rtrap
 	.size		__do_privact,.-__do_privact
 
 	.type		do_mna,#function
@@ -46,8 +45,7 @@ do_mna:
 	mov		%l5, %o2
 	call		mem_address_unaligned
 	 add		%sp, PTREGS_OFF, %o0
-	ba,pt		%xcc, rtrap
-	 nop
+	ba,a,pt		%xcc, rtrap
 	.size		do_mna,.-do_mna
 
 	.type		do_lddfmna,#function
@@ -65,8 +63,7 @@ do_lddfmna:
 	mov		%l5, %o2
 	call		handle_lddfmna
 	 add		%sp, PTREGS_OFF, %o0
-	ba,pt		%xcc, rtrap
-	 nop
+	ba,a,pt		%xcc, rtrap
 	.size		do_lddfmna,.-do_lddfmna
 
 	.type		do_stdfmna,#function
@@ -84,8 +81,7 @@ do_stdfmna:
 	mov		%l5, %o2
 	call		handle_stdfmna
 	 add		%sp, PTREGS_OFF, %o0
-	ba,pt		%xcc, rtrap
-	 nop
+	ba,a,pt		%xcc, rtrap
 	.size		do_stdfmna,.-do_stdfmna
 
 	.type		breakpoint_trap,#function
--- zfcpdump-kernel-4.4.orig/arch/sparc/kernel/pci.c
+++ zfcpdump-kernel-4.4/arch/sparc/kernel/pci.c
@@ -994,6 +994,23 @@ void pcibios_set_master(struct pci_dev *
 	/* No special bus mastering setup handling */
 }
 
+#ifdef CONFIG_PCI_IOV
+int pcibios_add_device(struct pci_dev *dev)
+{
+	struct pci_dev *pdev;
+
+	/* Add sriov arch specific initialization here.
+	 * Copy dev_archdata from PF to VF
+	 */
+	if (dev->is_virtfn) {
+		pdev = dev->physfn;
+		memcpy(&dev->dev.archdata, &pdev->dev.archdata,
+		       sizeof(struct dev_archdata));
+	}
+	return 0;
+}
+#endif /* CONFIG_PCI_IOV */
+
 static int __init pcibios_init(void)
 {
 	pci_dfl_cache_line_size = 64 >> 2;
--- zfcpdump-kernel-4.4.orig/arch/sparc/kernel/rtrap_64.S
+++ zfcpdump-kernel-4.4/arch/sparc/kernel/rtrap_64.S
@@ -14,10 +14,6 @@
 #include <asm/visasm.h>
 #include <asm/processor.h>
 
-#define		RTRAP_PSTATE		(PSTATE_TSO|PSTATE_PEF|PSTATE_PRIV|PSTATE_IE)
-#define		RTRAP_PSTATE_IRQOFF	(PSTATE_TSO|PSTATE_PEF|PSTATE_PRIV)
-#define		RTRAP_PSTATE_AG_IRQOFF	(PSTATE_TSO|PSTATE_PEF|PSTATE_PRIV|PSTATE_AG)
-
 #ifdef CONFIG_CONTEXT_TRACKING
 # define SCHEDULE_USER schedule_user
 #else
@@ -242,52 +238,17 @@ rt_continue:	ldx			[%sp + PTREGS_OFF + P
 		 wrpr			%g1, %cwp
 		ba,a,pt			%xcc, user_rtt_fill_64bit
 
-user_rtt_fill_fixup:
-		rdpr	%cwp, %g1
-		add	%g1, 1, %g1
-		wrpr	%g1, 0x0, %cwp
-
-		rdpr	%wstate, %g2
-		sll	%g2, 3, %g2
-		wrpr	%g2, 0x0, %wstate
-
-		/* We know %canrestore and %otherwin are both zero.  */
-
-		sethi	%hi(sparc64_kern_pri_context), %g2
-		ldx	[%g2 + %lo(sparc64_kern_pri_context)], %g2
-		mov	PRIMARY_CONTEXT, %g1
-
-661:		stxa	%g2, [%g1] ASI_DMMU
-		.section .sun4v_1insn_patch, "ax"
-		.word	661b
-		stxa	%g2, [%g1] ASI_MMU
-		.previous
-
-		sethi	%hi(KERNBASE), %g1
-		flush	%g1
+user_rtt_fill_fixup_dax:
+		ba,pt	%xcc, user_rtt_fill_fixup_common
+		 mov	1, %g3
+
+user_rtt_fill_fixup_mna:
+		ba,pt	%xcc, user_rtt_fill_fixup_common
+		 mov	2, %g3
 
-		or	%g4, FAULT_CODE_WINFIXUP, %g4
-		stb	%g4, [%g6 + TI_FAULT_CODE]
-		stx	%g5, [%g6 + TI_FAULT_ADDR]
-
-		mov	%g6, %l1
-		wrpr	%g0, 0x0, %tl
-
-661:		nop
-		.section		.sun4v_1insn_patch, "ax"
-		.word			661b
-		SET_GL(0)
-		.previous
-
-		wrpr	%g0, RTRAP_PSTATE, %pstate
-
-		mov	%l1, %g6
-		ldx	[%g6 + TI_TASK], %g4
-		LOAD_PER_CPU_BASE(%g5, %g6, %g1, %g2, %g3)
-		call	do_sparc64_fault
-		 add	%sp, PTREGS_OFF, %o0
-		ba,pt	%xcc, rtrap
-		 nop
+user_rtt_fill_fixup:
+		ba,pt	%xcc, user_rtt_fill_fixup_common
+		 clr	%g3
 
 user_rtt_pre_restore:
 		add			%g1, 1, %g1
--- zfcpdump-kernel-4.4.orig/arch/sparc/kernel/signal32.c
+++ zfcpdump-kernel-4.4/arch/sparc/kernel/signal32.c
@@ -138,12 +138,24 @@ int copy_siginfo_from_user32(siginfo_t *
 	return 0;
 }
 
+/* Checks if the fp is valid.  We always build signal frames which are
+ * 16-byte aligned, therefore we can always enforce that the restore
+ * frame has that property as well.
+ */
+static bool invalid_frame_pointer(void __user *fp, int fplen)
+{
+	if ((((unsigned long) fp) & 15) ||
+	    ((unsigned long)fp) > 0x100000000ULL - fplen)
+		return true;
+	return false;
+}
+
 void do_sigreturn32(struct pt_regs *regs)
 {
 	struct signal_frame32 __user *sf;
 	compat_uptr_t fpu_save;
 	compat_uptr_t rwin_save;
-	unsigned int psr;
+	unsigned int psr, ufp;
 	unsigned pc, npc;
 	sigset_t set;
 	compat_sigset_t seta;
@@ -158,11 +170,16 @@ void do_sigreturn32(struct pt_regs *regs
 	sf = (struct signal_frame32 __user *) regs->u_regs[UREG_FP];
 
 	/* 1. Make sure we are not getting garbage from the user */
-	if (!access_ok(VERIFY_READ, sf, sizeof(*sf)) ||
-	    (((unsigned long) sf) & 3))
+	if (invalid_frame_pointer(sf, sizeof(*sf)))
+		goto segv;
+
+	if (get_user(ufp, &sf->info.si_regs.u_regs[UREG_FP]))
+		goto segv;
+
+	if (ufp & 0x7)
 		goto segv;
 
-	if (get_user(pc, &sf->info.si_regs.pc) ||
+	if (__get_user(pc, &sf->info.si_regs.pc) ||
 	    __get_user(npc, &sf->info.si_regs.npc))
 		goto segv;
 
@@ -227,7 +244,7 @@ segv:
 asmlinkage void do_rt_sigreturn32(struct pt_regs *regs)
 {
 	struct rt_signal_frame32 __user *sf;
-	unsigned int psr, pc, npc;
+	unsigned int psr, pc, npc, ufp;
 	compat_uptr_t fpu_save;
 	compat_uptr_t rwin_save;
 	sigset_t set;
@@ -242,11 +259,16 @@ asmlinkage void do_rt_sigreturn32(struct
 	sf = (struct rt_signal_frame32 __user *) regs->u_regs[UREG_FP];
 
 	/* 1. Make sure we are not getting garbage from the user */
-	if (!access_ok(VERIFY_READ, sf, sizeof(*sf)) ||
-	    (((unsigned long) sf) & 3))
+	if (invalid_frame_pointer(sf, sizeof(*sf)))
 		goto segv;
 
-	if (get_user(pc, &sf->regs.pc) || 
+	if (get_user(ufp, &sf->regs.u_regs[UREG_FP]))
+		goto segv;
+
+	if (ufp & 0x7)
+		goto segv;
+
+	if (__get_user(pc, &sf->regs.pc) ||
 	    __get_user(npc, &sf->regs.npc))
 		goto segv;
 
@@ -307,14 +329,6 @@ segv:
 	force_sig(SIGSEGV, current);
 }
 
-/* Checks if the fp is valid */
-static int invalid_frame_pointer(void __user *fp, int fplen)
-{
-	if ((((unsigned long) fp) & 7) || ((unsigned long)fp) > 0x100000000ULL - fplen)
-		return 1;
-	return 0;
-}
-
 static void __user *get_sigframe(struct ksignal *ksig, struct pt_regs *regs, unsigned long framesize)
 {
 	unsigned long sp;
--- zfcpdump-kernel-4.4.orig/arch/sparc/kernel/signal_32.c
+++ zfcpdump-kernel-4.4/arch/sparc/kernel/signal_32.c
@@ -60,10 +60,22 @@ struct rt_signal_frame {
 #define SF_ALIGNEDSZ  (((sizeof(struct signal_frame) + 7) & (~7)))
 #define RT_ALIGNEDSZ  (((sizeof(struct rt_signal_frame) + 7) & (~7)))
 
+/* Checks if the fp is valid.  We always build signal frames which are
+ * 16-byte aligned, therefore we can always enforce that the restore
+ * frame has that property as well.
+ */
+static inline bool invalid_frame_pointer(void __user *fp, int fplen)
+{
+	if ((((unsigned long) fp) & 15) || !__access_ok((unsigned long)fp, fplen))
+		return true;
+
+	return false;
+}
+
 asmlinkage void do_sigreturn(struct pt_regs *regs)
 {
+	unsigned long up_psr, pc, npc, ufp;
 	struct signal_frame __user *sf;
-	unsigned long up_psr, pc, npc;
 	sigset_t set;
 	__siginfo_fpu_t __user *fpu_save;
 	__siginfo_rwin_t __user *rwin_save;
@@ -77,10 +89,13 @@ asmlinkage void do_sigreturn(struct pt_r
 	sf = (struct signal_frame __user *) regs->u_regs[UREG_FP];
 
 	/* 1. Make sure we are not getting garbage from the user */
-	if (!access_ok(VERIFY_READ, sf, sizeof(*sf)))
+	if (!invalid_frame_pointer(sf, sizeof(*sf)))
 		goto segv_and_exit;
 
-	if (((unsigned long) sf) & 3)
+	if (get_user(ufp, &sf->info.si_regs.u_regs[UREG_FP]))
+		goto segv_and_exit;
+
+	if (ufp & 0x7)
 		goto segv_and_exit;
 
 	err = __get_user(pc,  &sf->info.si_regs.pc);
@@ -127,7 +142,7 @@ segv_and_exit:
 asmlinkage void do_rt_sigreturn(struct pt_regs *regs)
 {
 	struct rt_signal_frame __user *sf;
-	unsigned int psr, pc, npc;
+	unsigned int psr, pc, npc, ufp;
 	__siginfo_fpu_t __user *fpu_save;
 	__siginfo_rwin_t __user *rwin_save;
 	sigset_t set;
@@ -135,8 +150,13 @@ asmlinkage void do_rt_sigreturn(struct p
 
 	synchronize_user_stack();
 	sf = (struct rt_signal_frame __user *) regs->u_regs[UREG_FP];
-	if (!access_ok(VERIFY_READ, sf, sizeof(*sf)) ||
-	    (((unsigned long) sf) & 0x03))
+	if (!invalid_frame_pointer(sf, sizeof(*sf)))
+		goto segv;
+
+	if (get_user(ufp, &sf->regs.u_regs[UREG_FP]))
+		goto segv;
+
+	if (ufp & 0x7)
 		goto segv;
 
 	err = __get_user(pc, &sf->regs.pc);
@@ -178,15 +198,6 @@ segv:
 	force_sig(SIGSEGV, current);
 }
 
-/* Checks if the fp is valid */
-static inline int invalid_frame_pointer(void __user *fp, int fplen)
-{
-	if ((((unsigned long) fp) & 7) || !__access_ok((unsigned long)fp, fplen))
-		return 1;
-
-	return 0;
-}
-
 static inline void __user *get_sigframe(struct ksignal *ksig, struct pt_regs *regs, unsigned long framesize)
 {
 	unsigned long sp = regs->u_regs[UREG_FP];
--- zfcpdump-kernel-4.4.orig/arch/sparc/kernel/signal_64.c
+++ zfcpdump-kernel-4.4/arch/sparc/kernel/signal_64.c
@@ -52,7 +52,7 @@ asmlinkage void sparc64_set_context(stru
 	unsigned char fenab;
 	int err;
 
-	flush_user_windows();
+	synchronize_user_stack();
 	if (get_thread_wsaved()					||
 	    (((unsigned long)ucp) & (sizeof(unsigned long)-1))	||
 	    (!__access_ok(ucp, sizeof(*ucp))))
@@ -234,6 +234,17 @@ do_sigsegv:
 	goto out;
 }
 
+/* Checks if the fp is valid.  We always build rt signal frames which
+ * are 16-byte aligned, therefore we can always enforce that the
+ * restore frame has that property as well.
+ */
+static bool invalid_frame_pointer(void __user *fp)
+{
+	if (((unsigned long) fp) & 15)
+		return true;
+	return false;
+}
+
 struct rt_signal_frame {
 	struct sparc_stackf	ss;
 	siginfo_t		info;
@@ -246,8 +257,8 @@ struct rt_signal_frame {
 
 void do_rt_sigreturn(struct pt_regs *regs)
 {
+	unsigned long tpc, tnpc, tstate, ufp;
 	struct rt_signal_frame __user *sf;
-	unsigned long tpc, tnpc, tstate;
 	__siginfo_fpu_t __user *fpu_save;
 	__siginfo_rwin_t __user *rwin_save;
 	sigset_t set;
@@ -261,10 +272,16 @@ void do_rt_sigreturn(struct pt_regs *reg
 		(regs->u_regs [UREG_FP] + STACK_BIAS);
 
 	/* 1. Make sure we are not getting garbage from the user */
-	if (((unsigned long) sf) & 3)
+	if (invalid_frame_pointer(sf))
+		goto segv;
+
+	if (get_user(ufp, &sf->regs.u_regs[UREG_FP]))
 		goto segv;
 
-	err = get_user(tpc, &sf->regs.tpc);
+	if ((ufp + STACK_BIAS) & 0x7)
+		goto segv;
+
+	err = __get_user(tpc, &sf->regs.tpc);
 	err |= __get_user(tnpc, &sf->regs.tnpc);
 	if (test_thread_flag(TIF_32BIT)) {
 		tpc &= 0xffffffff;
@@ -308,14 +325,6 @@ segv:
 	force_sig(SIGSEGV, current);
 }
 
-/* Checks if the fp is valid */
-static int invalid_frame_pointer(void __user *fp)
-{
-	if (((unsigned long) fp) & 15)
-		return 1;
-	return 0;
-}
-
 static inline void __user *get_sigframe(struct ksignal *ksig, struct pt_regs *regs, unsigned long framesize)
 {
 	unsigned long sp = regs->u_regs[UREG_FP] + STACK_BIAS;
--- zfcpdump-kernel-4.4.orig/arch/sparc/kernel/sigutil_32.c
+++ zfcpdump-kernel-4.4/arch/sparc/kernel/sigutil_32.c
@@ -48,6 +48,10 @@ int save_fpu_state(struct pt_regs *regs,
 int restore_fpu_state(struct pt_regs *regs, __siginfo_fpu_t __user *fpu)
 {
 	int err;
+
+	if (((unsigned long) fpu) & 3)
+		return -EFAULT;
+
 #ifdef CONFIG_SMP
 	if (test_tsk_thread_flag(current, TIF_USEDFPU))
 		regs->psr &= ~PSR_EF;
@@ -97,7 +101,10 @@ int restore_rwin_state(__siginfo_rwin_t
 	struct thread_info *t = current_thread_info();
 	int i, wsaved, err;
 
-	__get_user(wsaved, &rp->wsaved);
+	if (((unsigned long) rp) & 3)
+		return -EFAULT;
+
+	get_user(wsaved, &rp->wsaved);
 	if (wsaved > NSWINS)
 		return -EFAULT;
 
--- zfcpdump-kernel-4.4.orig/arch/sparc/kernel/sigutil_64.c
+++ zfcpdump-kernel-4.4/arch/sparc/kernel/sigutil_64.c
@@ -37,7 +37,10 @@ int restore_fpu_state(struct pt_regs *re
 	unsigned long fprs;
 	int err;
 
-	err = __get_user(fprs, &fpu->si_fprs);
+	if (((unsigned long) fpu) & 7)
+		return -EFAULT;
+
+	err = get_user(fprs, &fpu->si_fprs);
 	fprs_write(0);
 	regs->tstate &= ~TSTATE_PEF;
 	if (fprs & FPRS_DL)
@@ -72,7 +75,10 @@ int restore_rwin_state(__siginfo_rwin_t
 	struct thread_info *t = current_thread_info();
 	int i, wsaved, err;
 
-	__get_user(wsaved, &rp->wsaved);
+	if (((unsigned long) rp) & 7)
+		return -EFAULT;
+
+	get_user(wsaved, &rp->wsaved);
 	if (wsaved > NSWINS)
 		return -EFAULT;
 
--- zfcpdump-kernel-4.4.orig/arch/sparc/kernel/spiterrs.S
+++ zfcpdump-kernel-4.4/arch/sparc/kernel/spiterrs.S
@@ -85,8 +85,7 @@ __spitfire_cee_trap_continue:
 	ba,pt		%xcc, etraptl1
 	 rd		%pc, %g7
 
-	ba,pt		%xcc, 2f
-	 nop
+	ba,a,pt		%xcc, 2f
 
 1:	ba,pt		%xcc, etrap_irq
 	 rd		%pc, %g7
@@ -100,8 +99,7 @@ __spitfire_cee_trap_continue:
 	mov		%l5, %o2
 	call		spitfire_access_error
 	 add		%sp, PTREGS_OFF, %o0
-	ba,pt		%xcc, rtrap
-	 nop
+	ba,a,pt		%xcc, rtrap
 	.size		__spitfire_access_error,.-__spitfire_access_error
 
 	/* This is the trap handler entry point for ECC correctable
@@ -179,8 +177,7 @@ __spitfire_data_access_exception_tl1:
 	mov		%l5, %o2
 	call		spitfire_data_access_exception_tl1
 	 add		%sp, PTREGS_OFF, %o0
-	ba,pt		%xcc, rtrap
-	 nop
+	ba,a,pt		%xcc, rtrap
 	.size		__spitfire_data_access_exception_tl1,.-__spitfire_data_access_exception_tl1
 
 	.type		__spitfire_data_access_exception,#function
@@ -200,8 +197,7 @@ __spitfire_data_access_exception:
 	mov		%l5, %o2
 	call		spitfire_data_access_exception
 	 add		%sp, PTREGS_OFF, %o0
-	ba,pt		%xcc, rtrap
-	 nop
+	ba,a,pt		%xcc, rtrap
 	.size		__spitfire_data_access_exception,.-__spitfire_data_access_exception
 
 	.type		__spitfire_insn_access_exception_tl1,#function
@@ -220,8 +216,7 @@ __spitfire_insn_access_exception_tl1:
 	mov		%l5, %o2
 	call		spitfire_insn_access_exception_tl1
 	 add		%sp, PTREGS_OFF, %o0
-	ba,pt		%xcc, rtrap
-	 nop
+	ba,a,pt		%xcc, rtrap
 	.size		__spitfire_insn_access_exception_tl1,.-__spitfire_insn_access_exception_tl1
 
 	.type		__spitfire_insn_access_exception,#function
@@ -240,6 +235,5 @@ __spitfire_insn_access_exception:
 	mov		%l5, %o2
 	call		spitfire_insn_access_exception
 	 add		%sp, PTREGS_OFF, %o0
-	ba,pt		%xcc, rtrap
-	 nop
+	ba,a,pt		%xcc, rtrap
 	.size		__spitfire_insn_access_exception,.-__spitfire_insn_access_exception
--- zfcpdump-kernel-4.4.orig/arch/sparc/kernel/sys_sparc_64.c
+++ zfcpdump-kernel-4.4/arch/sparc/kernel/sys_sparc_64.c
@@ -413,7 +413,7 @@ out:
 
 SYSCALL_DEFINE1(sparc64_personality, unsigned long, personality)
 {
-	int ret;
+	long ret;
 
 	if (personality(current->personality) == PER_LINUX32 &&
 	    personality(personality) == PER_LINUX)
--- zfcpdump-kernel-4.4.orig/arch/sparc/kernel/syscalls.S
+++ zfcpdump-kernel-4.4/arch/sparc/kernel/syscalls.S
@@ -158,7 +158,25 @@ linux_syscall_trace32:
 	 add	%sp, PTREGS_OFF, %o0
 	brnz,pn	%o0, 3f
 	 mov	-ENOSYS, %o0
+
+	/* Syscall tracing can modify the registers.  */
+	ldx	[%sp + PTREGS_OFF + PT_V9_G1], %g1
+	sethi	%hi(sys_call_table32), %l7
+	ldx	[%sp + PTREGS_OFF + PT_V9_I0], %i0
+	or	%l7, %lo(sys_call_table32), %l7
+	ldx	[%sp + PTREGS_OFF + PT_V9_I1], %i1
+	ldx	[%sp + PTREGS_OFF + PT_V9_I2], %i2
+	ldx	[%sp + PTREGS_OFF + PT_V9_I3], %i3
+	ldx	[%sp + PTREGS_OFF + PT_V9_I4], %i4
+	ldx	[%sp + PTREGS_OFF + PT_V9_I5], %i5
+
+	cmp	%g1, NR_syscalls
+	bgeu,pn	%xcc, 3f
+	 mov	-ENOSYS, %o0
+
+	sll	%g1, 2, %l4
 	srl	%i0, 0, %o0
+	lduw	[%l7 + %l4], %l7
 	srl	%i4, 0, %o4
 	srl	%i1, 0, %o1
 	srl	%i2, 0, %o2
@@ -170,7 +188,25 @@ linux_syscall_trace:
 	 add	%sp, PTREGS_OFF, %o0
 	brnz,pn	%o0, 3f
 	 mov	-ENOSYS, %o0
+
+	/* Syscall tracing can modify the registers.  */
+	ldx	[%sp + PTREGS_OFF + PT_V9_G1], %g1
+	sethi	%hi(sys_call_table64), %l7
+	ldx	[%sp + PTREGS_OFF + PT_V9_I0], %i0
+	or	%l7, %lo(sys_call_table64), %l7
+	ldx	[%sp + PTREGS_OFF + PT_V9_I1], %i1
+	ldx	[%sp + PTREGS_OFF + PT_V9_I2], %i2
+	ldx	[%sp + PTREGS_OFF + PT_V9_I3], %i3
+	ldx	[%sp + PTREGS_OFF + PT_V9_I4], %i4
+	ldx	[%sp + PTREGS_OFF + PT_V9_I5], %i5
+
+	cmp	%g1, NR_syscalls
+	bgeu,pn	%xcc, 3f
+	 mov	-ENOSYS, %o0
+
+	sll	%g1, 2, %l4
 	mov	%i0, %o0
+	lduw	[%l7 + %l4], %l7
 	mov	%i1, %o1
 	mov	%i2, %o2
 	mov	%i3, %o3
--- /dev/null
+++ zfcpdump-kernel-4.4/arch/sparc/kernel/urtt_fill.S
@@ -0,0 +1,98 @@
+#include <asm/thread_info.h>
+#include <asm/trap_block.h>
+#include <asm/spitfire.h>
+#include <asm/ptrace.h>
+#include <asm/head.h>
+
+		.text
+		.align	8
+		.globl	user_rtt_fill_fixup_common
+user_rtt_fill_fixup_common:
+		rdpr	%cwp, %g1
+		add	%g1, 1, %g1
+		wrpr	%g1, 0x0, %cwp
+
+		rdpr	%wstate, %g2
+		sll	%g2, 3, %g2
+		wrpr	%g2, 0x0, %wstate
+
+		/* We know %canrestore and %otherwin are both zero.  */
+
+		sethi	%hi(sparc64_kern_pri_context), %g2
+		ldx	[%g2 + %lo(sparc64_kern_pri_context)], %g2
+		mov	PRIMARY_CONTEXT, %g1
+
+661:		stxa	%g2, [%g1] ASI_DMMU
+		.section .sun4v_1insn_patch, "ax"
+		.word	661b
+		stxa	%g2, [%g1] ASI_MMU
+		.previous
+
+		sethi	%hi(KERNBASE), %g1
+		flush	%g1
+
+		mov	%g4, %l4
+		mov	%g5, %l5
+		brnz,pn	%g3, 1f
+		 mov	%g3, %l3
+
+		or	%g4, FAULT_CODE_WINFIXUP, %g4
+		stb	%g4, [%g6 + TI_FAULT_CODE]
+		stx	%g5, [%g6 + TI_FAULT_ADDR]
+1:
+		mov	%g6, %l1
+		wrpr	%g0, 0x0, %tl
+
+661:		nop
+		.section		.sun4v_1insn_patch, "ax"
+		.word			661b
+		SET_GL(0)
+		.previous
+
+		wrpr	%g0, RTRAP_PSTATE, %pstate
+
+		mov	%l1, %g6
+		ldx	[%g6 + TI_TASK], %g4
+		LOAD_PER_CPU_BASE(%g5, %g6, %g1, %g2, %g3)
+
+		brnz,pn	%l3, 1f
+		 nop
+
+		call	do_sparc64_fault
+		 add	%sp, PTREGS_OFF, %o0
+		ba,pt	%xcc, rtrap
+		 nop
+
+1:		cmp	%g3, 2
+		bne,pn	%xcc, 2f
+		 nop
+
+		sethi	%hi(tlb_type), %g1
+		lduw	[%g1 + %lo(tlb_type)], %g1
+		cmp	%g1, 3
+		bne,pt	%icc, 1f
+		 add	%sp, PTREGS_OFF, %o0
+		mov	%l4, %o2
+		call	sun4v_do_mna
+		 mov	%l5, %o1
+		ba,a,pt	%xcc, rtrap
+1:		mov	%l4, %o1
+		mov	%l5, %o2
+		call	mem_address_unaligned
+		 nop
+		ba,a,pt	%xcc, rtrap
+
+2:		sethi	%hi(tlb_type), %g1
+		mov	%l4, %o1
+		lduw	[%g1 + %lo(tlb_type)], %g1
+		mov	%l5, %o2
+		cmp	%g1, 3
+		bne,pt	%icc, 1f
+		 add	%sp, PTREGS_OFF, %o0
+		call	sun4v_data_access_exception
+		 nop
+		ba,a,pt	%xcc, rtrap
+
+1:		call	spitfire_data_access_exception
+		 nop
+		ba,a,pt	%xcc, rtrap
--- zfcpdump-kernel-4.4.orig/arch/sparc/kernel/utrap.S
+++ zfcpdump-kernel-4.4/arch/sparc/kernel/utrap.S
@@ -11,8 +11,7 @@ utrap_trap:		/* %g3=handler,%g4=level */
 	mov		%l4, %o1
         call		bad_trap
 	 add		%sp, PTREGS_OFF, %o0
-	ba,pt		%xcc, rtrap
-	 nop
+	ba,a,pt		%xcc, rtrap
 
 invoke_utrap:
 	sllx		%g3, 3, %g3
--- zfcpdump-kernel-4.4.orig/arch/sparc/kernel/vmlinux.lds.S
+++ zfcpdump-kernel-4.4/arch/sparc/kernel/vmlinux.lds.S
@@ -33,6 +33,10 @@ ENTRY(_start)
 jiffies = jiffies_64;
 #endif
 
+#ifdef CONFIG_SPARC64
+ASSERT((swapper_tsb == 0x0000000000408000), "Error: sparc64 early assembler too large")
+#endif
+
 SECTIONS
 {
 #ifdef CONFIG_SPARC64
--- zfcpdump-kernel-4.4.orig/arch/sparc/kernel/winfixup.S
+++ zfcpdump-kernel-4.4/arch/sparc/kernel/winfixup.S
@@ -32,8 +32,7 @@ fill_fixup:
 	 rd	%pc, %g7
 	call	do_sparc64_fault
 	 add	%sp, PTREGS_OFF, %o0
-	ba,pt	%xcc, rtrap
-	 nop
+	ba,a,pt	%xcc, rtrap
 
 	/* Be very careful about usage of the trap globals here.
 	 * You cannot touch %g5 as that has the fault information.
--- zfcpdump-kernel-4.4.orig/arch/sparc/mm/hugetlbpage.c
+++ zfcpdump-kernel-4.4/arch/sparc/mm/hugetlbpage.c
@@ -176,17 +176,31 @@ void set_huge_pte_at(struct mm_struct *m
 		     pte_t *ptep, pte_t entry)
 {
 	int i;
+	pte_t orig[2];
+	unsigned long nptes;
 
 	if (!pte_present(*ptep) && pte_present(entry))
 		mm->context.huge_pte_count++;
 
 	addr &= HPAGE_MASK;
-	for (i = 0; i < (1 << HUGETLB_PAGE_ORDER); i++) {
-		set_pte_at(mm, addr, ptep, entry);
+
+	nptes = 1 << HUGETLB_PAGE_ORDER;
+	orig[0] = *ptep;
+	orig[1] = *(ptep + nptes / 2);
+	for (i = 0; i < nptes; i++) {
+		*ptep = entry;
 		ptep++;
 		addr += PAGE_SIZE;
 		pte_val(entry) += PAGE_SIZE;
 	}
+
+	/* Issue TLB flush at REAL_HPAGE_SIZE boundaries */
+	addr -= REAL_HPAGE_SIZE;
+	ptep -= nptes / 2;
+	maybe_tlb_batch_add(mm, addr, ptep, orig[1], 0);
+	addr -= REAL_HPAGE_SIZE;
+	ptep -= nptes / 2;
+	maybe_tlb_batch_add(mm, addr, ptep, orig[0], 0);
 }
 
 pte_t huge_ptep_get_and_clear(struct mm_struct *mm, unsigned long addr,
@@ -194,19 +208,28 @@ pte_t huge_ptep_get_and_clear(struct mm_
 {
 	pte_t entry;
 	int i;
+	unsigned long nptes;
 
 	entry = *ptep;
 	if (pte_present(entry))
 		mm->context.huge_pte_count--;
 
 	addr &= HPAGE_MASK;
-
-	for (i = 0; i < (1 << HUGETLB_PAGE_ORDER); i++) {
-		pte_clear(mm, addr, ptep);
+	nptes = 1 << HUGETLB_PAGE_ORDER;
+	for (i = 0; i < nptes; i++) {
+		*ptep = __pte(0UL);
 		addr += PAGE_SIZE;
 		ptep++;
 	}
 
+	/* Issue TLB flush at REAL_HPAGE_SIZE boundaries */
+	addr -= REAL_HPAGE_SIZE;
+	ptep -= nptes / 2;
+	maybe_tlb_batch_add(mm, addr, ptep, entry, 0);
+	addr -= REAL_HPAGE_SIZE;
+	ptep -= nptes / 2;
+	maybe_tlb_batch_add(mm, addr, ptep, entry, 0);
+
 	return entry;
 }
 
--- zfcpdump-kernel-4.4.orig/arch/sparc/mm/init_64.c
+++ zfcpdump-kernel-4.4/arch/sparc/mm/init_64.c
@@ -324,18 +324,6 @@ static void __update_mmu_tsb_insert(stru
 	tsb_insert(tsb, tag, tte);
 }
 
-#if defined(CONFIG_HUGETLB_PAGE) || defined(CONFIG_TRANSPARENT_HUGEPAGE)
-static inline bool is_hugetlb_pte(pte_t pte)
-{
-	if ((tlb_type == hypervisor &&
-	     (pte_val(pte) & _PAGE_SZALL_4V) == _PAGE_SZHUGE_4V) ||
-	    (tlb_type != hypervisor &&
-	     (pte_val(pte) & _PAGE_SZALL_4U) == _PAGE_SZHUGE_4U))
-		return true;
-	return false;
-}
-#endif
-
 void update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t *ptep)
 {
 	struct mm_struct *mm;
@@ -1267,13 +1255,6 @@ static int __init numa_parse_mdesc(void)
 	int i, j, err, count;
 	u64 node;
 
-	/* Some sane defaults for numa latency values */
-	for (i = 0; i < MAX_NUMNODES; i++) {
-		for (j = 0; j < MAX_NUMNODES; j++)
-			numa_latency[i][j] = (i == j) ?
-				LOCAL_DISTANCE : REMOTE_DISTANCE;
-	}
-
 	node = mdesc_node_by_name(md, MDESC_NODE_NULL, "latency-groups");
 	if (node == MDESC_NODE_NULL) {
 		mdesc_release(md);
@@ -1369,10 +1350,18 @@ static int __init numa_parse_sun4u(void)
 
 static int __init bootmem_init_numa(void)
 {
+	int i, j;
 	int err = -1;
 
 	numadbg("bootmem_init_numa()\n");
 
+	/* Some sane defaults for numa latency values */
+	for (i = 0; i < MAX_NUMNODES; i++) {
+		for (j = 0; j < MAX_NUMNODES; j++)
+			numa_latency[i][j] = (i == j) ?
+				LOCAL_DISTANCE : REMOTE_DISTANCE;
+	}
+
 	if (numa_enabled) {
 		if (tlb_type == hypervisor)
 			err = numa_parse_mdesc();
@@ -2832,9 +2821,10 @@ void hugetlb_setup(struct pt_regs *regs)
 	 * the Data-TLB for huge pages.
 	 */
 	if (tlb_type == cheetah_plus) {
+		bool need_context_reload = false;
 		unsigned long ctx;
 
-		spin_lock(&ctx_alloc_lock);
+		spin_lock_irq(&ctx_alloc_lock);
 		ctx = mm->context.sparc64_ctx_val;
 		ctx &= ~CTX_PGSZ_MASK;
 		ctx |= CTX_PGSZ_BASE << CTX_PGSZ0_SHIFT;
@@ -2853,9 +2843,12 @@ void hugetlb_setup(struct pt_regs *regs)
 			 * also executing in this address space.
 			 */
 			mm->context.sparc64_ctx_val = ctx;
-			on_each_cpu(context_reload, mm, 0);
+			need_context_reload = true;
 		}
-		spin_unlock(&ctx_alloc_lock);
+		spin_unlock_irq(&ctx_alloc_lock);
+
+		if (need_context_reload)
+			on_each_cpu(context_reload, mm, 0);
 	}
 }
 #endif
--- zfcpdump-kernel-4.4.orig/arch/sparc/mm/tlb.c
+++ zfcpdump-kernel-4.4/arch/sparc/mm/tlb.c
@@ -67,7 +67,7 @@ void arch_leave_lazy_mmu_mode(void)
 }
 
 static void tlb_batch_add_one(struct mm_struct *mm, unsigned long vaddr,
-			      bool exec)
+			      bool exec, bool huge)
 {
 	struct tlb_batch *tb = &get_cpu_var(tlb_batch);
 	unsigned long nr;
@@ -84,13 +84,21 @@ static void tlb_batch_add_one(struct mm_
 	}
 
 	if (!tb->active) {
-		flush_tsb_user_page(mm, vaddr);
+		flush_tsb_user_page(mm, vaddr, huge);
 		global_flush_tlb_page(mm, vaddr);
 		goto out;
 	}
 
-	if (nr == 0)
+	if (nr == 0) {
 		tb->mm = mm;
+		tb->huge = huge;
+	}
+
+	if (tb->huge != huge) {
+		flush_tlb_pending();
+		tb->huge = huge;
+		nr = 0;
+	}
 
 	tb->vaddrs[nr] = vaddr;
 	tb->tlb_nr = ++nr;
@@ -104,6 +112,8 @@ out:
 void tlb_batch_add(struct mm_struct *mm, unsigned long vaddr,
 		   pte_t *ptep, pte_t orig, int fullmm)
 {
+	bool huge = is_hugetlb_pte(orig);
+
 	if (tlb_type != hypervisor &&
 	    pte_dirty(orig)) {
 		unsigned long paddr, pfn = pte_pfn(orig);
@@ -129,7 +139,7 @@ void tlb_batch_add(struct mm_struct *mm,
 
 no_cache_flush:
 	if (!fullmm)
-		tlb_batch_add_one(mm, vaddr, pte_exec(orig));
+		tlb_batch_add_one(mm, vaddr, pte_exec(orig), huge);
 }
 
 #ifdef CONFIG_TRANSPARENT_HUGEPAGE
@@ -145,7 +155,7 @@ static void tlb_batch_pmd_scan(struct mm
 		if (pte_val(*pte) & _PAGE_VALID) {
 			bool exec = pte_exec(*pte);
 
-			tlb_batch_add_one(mm, vaddr, exec);
+			tlb_batch_add_one(mm, vaddr, exec, false);
 		}
 		pte++;
 		vaddr += PAGE_SIZE;
@@ -185,8 +195,9 @@ void set_pmd_at(struct mm_struct *mm, un
 			pte_t orig_pte = __pte(pmd_val(orig));
 			bool exec = pte_exec(orig_pte);
 
-			tlb_batch_add_one(mm, addr, exec);
-			tlb_batch_add_one(mm, addr + REAL_HPAGE_SIZE, exec);
+			tlb_batch_add_one(mm, addr, exec, true);
+			tlb_batch_add_one(mm, addr + REAL_HPAGE_SIZE, exec,
+					true);
 		} else {
 			tlb_batch_pmd_scan(mm, addr, orig);
 		}
--- zfcpdump-kernel-4.4.orig/arch/sparc/mm/tsb.c
+++ zfcpdump-kernel-4.4/arch/sparc/mm/tsb.c
@@ -76,14 +76,15 @@ void flush_tsb_user(struct tlb_batch *tb
 
 	spin_lock_irqsave(&mm->context.lock, flags);
 
-	base = (unsigned long) mm->context.tsb_block[MM_TSB_BASE].tsb;
-	nentries = mm->context.tsb_block[MM_TSB_BASE].tsb_nentries;
-	if (tlb_type == cheetah_plus || tlb_type == hypervisor)
-		base = __pa(base);
-	__flush_tsb_one(tb, PAGE_SHIFT, base, nentries);
-
+	if (!tb->huge) {
+		base = (unsigned long) mm->context.tsb_block[MM_TSB_BASE].tsb;
+		nentries = mm->context.tsb_block[MM_TSB_BASE].tsb_nentries;
+		if (tlb_type == cheetah_plus || tlb_type == hypervisor)
+			base = __pa(base);
+		__flush_tsb_one(tb, PAGE_SHIFT, base, nentries);
+	}
 #if defined(CONFIG_HUGETLB_PAGE) || defined(CONFIG_TRANSPARENT_HUGEPAGE)
-	if (mm->context.tsb_block[MM_TSB_HUGE].tsb) {
+	if (tb->huge && mm->context.tsb_block[MM_TSB_HUGE].tsb) {
 		base = (unsigned long) mm->context.tsb_block[MM_TSB_HUGE].tsb;
 		nentries = mm->context.tsb_block[MM_TSB_HUGE].tsb_nentries;
 		if (tlb_type == cheetah_plus || tlb_type == hypervisor)
@@ -94,20 +95,21 @@ void flush_tsb_user(struct tlb_batch *tb
 	spin_unlock_irqrestore(&mm->context.lock, flags);
 }
 
-void flush_tsb_user_page(struct mm_struct *mm, unsigned long vaddr)
+void flush_tsb_user_page(struct mm_struct *mm, unsigned long vaddr, bool huge)
 {
 	unsigned long nentries, base, flags;
 
 	spin_lock_irqsave(&mm->context.lock, flags);
 
-	base = (unsigned long) mm->context.tsb_block[MM_TSB_BASE].tsb;
-	nentries = mm->context.tsb_block[MM_TSB_BASE].tsb_nentries;
-	if (tlb_type == cheetah_plus || tlb_type == hypervisor)
-		base = __pa(base);
-	__flush_tsb_one_entry(base, vaddr, PAGE_SHIFT, nentries);
-
+	if (!huge) {
+		base = (unsigned long) mm->context.tsb_block[MM_TSB_BASE].tsb;
+		nentries = mm->context.tsb_block[MM_TSB_BASE].tsb_nentries;
+		if (tlb_type == cheetah_plus || tlb_type == hypervisor)
+			base = __pa(base);
+		__flush_tsb_one_entry(base, vaddr, PAGE_SHIFT, nentries);
+	}
 #if defined(CONFIG_HUGETLB_PAGE) || defined(CONFIG_TRANSPARENT_HUGEPAGE)
-	if (mm->context.tsb_block[MM_TSB_HUGE].tsb) {
+	if (huge && mm->context.tsb_block[MM_TSB_HUGE].tsb) {
 		base = (unsigned long) mm->context.tsb_block[MM_TSB_HUGE].tsb;
 		nentries = mm->context.tsb_block[MM_TSB_HUGE].tsb_nentries;
 		if (tlb_type == cheetah_plus || tlb_type == hypervisor)
--- zfcpdump-kernel-4.4.orig/arch/tile/include/asm/elf.h
+++ zfcpdump-kernel-4.4/arch/tile/include/asm/elf.h
@@ -129,6 +129,7 @@ extern int dump_task_regs(struct task_st
 struct linux_binprm;
 extern int arch_setup_additional_pages(struct linux_binprm *bprm,
 				       int executable_stack);
+/* update AT_VECTOR_SIZE_ARCH if the number of NEW_AUX_ENT entries changes */
 #define ARCH_DLINFO \
 do { \
 	NEW_AUX_ENT(AT_SYSINFO_EHDR, VDSO_BASE); \
--- zfcpdump-kernel-4.4.orig/arch/tile/include/uapi/asm/auxvec.h
+++ zfcpdump-kernel-4.4/arch/tile/include/uapi/asm/auxvec.h
@@ -18,4 +18,6 @@
 /* The vDSO location. */
 #define AT_SYSINFO_EHDR         33
 
+#define AT_VECTOR_SIZE_ARCH 1 /* entries in ARCH_DLINFO */
+
 #endif /* _ASM_TILE_AUXVEC_H */
--- zfcpdump-kernel-4.4.orig/arch/um/drivers/mconsole_kern.c
+++ zfcpdump-kernel-4.4/arch/um/drivers/mconsole_kern.c
@@ -133,7 +133,7 @@ void mconsole_proc(struct mc_request *re
 	ptr += strlen("proc");
 	ptr = skip_spaces(ptr);
 
-	file = file_open_root(mnt->mnt_root, mnt, ptr, O_RDONLY);
+	file = file_open_root(mnt->mnt_root, mnt, ptr, O_RDONLY, 0);
 	if (IS_ERR(file)) {
 		mconsole_reply(req, "Failed to open file", 1, 0);
 		printk(KERN_ERR "open /proc/%s: %ld\n", ptr, PTR_ERR(file));
--- zfcpdump-kernel-4.4.orig/arch/um/include/asm/common.lds.S
+++ zfcpdump-kernel-4.4/arch/um/include/asm/common.lds.S
@@ -81,7 +81,7 @@
   .altinstr_replacement : { *(.altinstr_replacement) }
   /* .exit.text is discard at runtime, not link time, to deal with references
      from .altinstructions and .eh_frame */
-  .exit.text : { *(.exit.text) }
+  .exit.text : { EXIT_TEXT }
   .exit.data : { *(.exit.data) }
 
   .preinit_array : {
--- zfcpdump-kernel-4.4.orig/arch/um/os-Linux/start_up.c
+++ zfcpdump-kernel-4.4/arch/um/os-Linux/start_up.c
@@ -94,6 +94,8 @@ static int start_ptraced_child(void)
 {
 	int pid, n, status;
 
+	fflush(stdout);
+
 	pid = fork();
 	if (pid == 0)
 		ptrace_child();
--- zfcpdump-kernel-4.4.orig/arch/x86/Kbuild
+++ zfcpdump-kernel-4.4/arch/x86/Kbuild
@@ -1,6 +1,7 @@
-
 obj-y += entry/
 
+obj-$(CONFIG_PERF_EVENTS) += events/
+
 obj-$(CONFIG_KVM) += kvm/
 
 # Xen paravirtualization support
--- zfcpdump-kernel-4.4.orig/arch/x86/Kconfig
+++ zfcpdump-kernel-4.4/arch/x86/Kconfig
@@ -523,9 +523,10 @@ config X86_INTEL_QUARK
 
 config X86_INTEL_LPSS
 	bool "Intel Low Power Subsystem Support"
-	depends on ACPI
+	depends on X86 && ACPI
 	select COMMON_CLK
 	select PINCTRL
+	select IOSF_MBI
 	---help---
 	  Select to build support for Intel Low Power Subsystem such as
 	  found on Intel Lynxpoint PCH. Selecting this option enables
@@ -1126,22 +1127,23 @@ config MICROCODE
 	bool "CPU microcode loading support"
 	default y
 	depends on CPU_SUP_AMD || CPU_SUP_INTEL
-	depends on BLK_DEV_INITRD
 	select FW_LOADER
 	---help---
-
 	  If you say Y here, you will be able to update the microcode on
-	  certain Intel and AMD processors. The Intel support is for the
-	  IA32 family, e.g. Pentium Pro, Pentium II, Pentium III, Pentium 4,
-	  Xeon etc. The AMD support is for families 0x10 and later. You will
-	  obviously need the actual microcode binary data itself which is not
-	  shipped with the Linux kernel.
-
-	  This option selects the general module only, you need to select
-	  at least one vendor specific module as well.
-
-	  To compile this driver as a module, choose M here: the module
-	  will be called microcode.
+	  Intel and AMD processors. The Intel support is for the IA32 family,
+	  e.g. Pentium Pro, Pentium II, Pentium III, Pentium 4, Xeon etc. The
+	  AMD support is for families 0x10 and later. You will obviously need
+	  the actual microcode binary data itself which is not shipped with
+	  the Linux kernel.
+
+	  The preferred method to load microcode from a detached initrd is described
+	  in Documentation/x86/early-microcode.txt. For that you need to enable
+	  CONFIG_BLK_DEV_INITRD in order for the loader to be able to scan the
+	  initrd for microcode blobs.
+
+	  In addition, you can build-in the microcode into the kernel. For that you
+	  need to enable FIRMWARE_IN_KERNEL and add the vendor-supplied microcode
+	  to the CONFIG_EXTRA_FIRMWARE config option.
 
 config MICROCODE_INTEL
 	bool "Intel microcode loading support"
@@ -1720,6 +1722,17 @@ config EFI_MIXED
 
 	   If unsure, say N.
 
+config EFI_SECURE_BOOT_SIG_ENFORCE
+	def_bool n
+	depends on EFI
+	prompt "Force module signing when UEFI Secure Boot is enabled"
+	---help---
+	  UEFI Secure Boot provides a mechanism for ensuring that the
+	  firmware will only load signed bootloaders and kernels. Certain
+	  use cases may also require that all kernel modules also be signed.
+	  Say Y here to automatically enable module signature enforcement
+	  when a system boots with UEFI Secure Boot enabled.
+
 config SECCOMP
 	def_bool y
 	prompt "Enable seccomp to safely compute untrusted bytecode"
@@ -2669,6 +2682,8 @@ source "net/Kconfig"
 
 source "drivers/Kconfig"
 
+source "ubuntu/Kconfig"
+
 source "drivers/firmware/Kconfig"
 
 source "fs/Kconfig"
--- zfcpdump-kernel-4.4.orig/arch/x86/boot/Makefile
+++ zfcpdump-kernel-4.4/arch/x86/boot/Makefile
@@ -162,6 +162,9 @@ isoimage: $(obj)/bzImage
 	for i in lib lib64 share end ; do \
 		if [ -f /usr/$$i/syslinux/isolinux.bin ] ; then \
 			cp /usr/$$i/syslinux/isolinux.bin $(obj)/isoimage ; \
+			if [ -f /usr/$$i/syslinux/ldlinux.c32 ]; then \
+				cp /usr/$$i/syslinux/ldlinux.c32 $(obj)/isoimage ; \
+			fi ; \
 			break ; \
 		fi ; \
 		if [ $$i = end ] ; then exit 1 ; fi ; \
--- zfcpdump-kernel-4.4.orig/arch/x86/boot/compressed/eboot.c
+++ zfcpdump-kernel-4.4/arch/x86/boot/compressed/eboot.c
@@ -12,6 +12,7 @@
 #include <asm/efi.h>
 #include <asm/setup.h>
 #include <asm/desc.h>
+#include <asm/bootparam_utils.h>
 
 #include "../string.h"
 #include "eboot.h"
@@ -847,6 +848,56 @@ out:
 	return status;
 }
 
+static int get_secure_boot(void)
+{
+	u8 sb, setup, moksbstate;
+	unsigned long datasize = sizeof(sb);
+	u32 attr;
+	efi_guid_t var_guid = EFI_GLOBAL_VARIABLE_GUID;
+	efi_status_t status;
+
+	status = efi_early->call((unsigned long)sys_table->runtime->get_variable,
+				L"SecureBoot", &var_guid, NULL, &datasize, &sb);
+
+	if (status != EFI_SUCCESS)
+		return 0;
+
+	if (sb == 0)
+		return 0;
+
+
+	status = efi_early->call((unsigned long)sys_table->runtime->get_variable,
+				L"SetupMode", &var_guid, NULL, &datasize,
+				&setup);
+
+	if (status != EFI_SUCCESS)
+		return 0;
+
+	if (setup == 1)
+		return 0;
+
+	/* See if a user has put shim into insecure_mode.  If so, and the variable
+	 * doesn't have the runtime attribute set, we might as well honor that.
+	 */
+	var_guid = EFI_SHIM_LOCK_GUID;
+	status = efi_early->call((unsigned long)sys_table->runtime->get_variable,
+				L"MokSBState", &var_guid, &attr, &datasize,
+				&moksbstate);
+
+	/* If it fails, we don't care why.  Default to secure */
+	if (status != EFI_SUCCESS)
+		return EFI_SECURE_BOOT;
+
+	if (!(attr & EFI_VARIABLE_RUNTIME_ACCESS)) {
+		if (moksbstate == 1) {
+			return EFI_MOKSBSTATE_DISABLED;
+		}
+	}
+
+	return EFI_SECURE_BOOT;
+}
+
+
 /*
  * See if we have Graphics Output Protocol
  */
@@ -1432,6 +1483,10 @@ struct boot_params *efi_main(struct efi_
 	else
 		setup_boot_services32(efi_early);
 
+	sanitize_boot_params(boot_params);
+
+	boot_params->secure_boot = get_secure_boot();
+
 	setup_graphics(boot_params);
 
 	setup_efi_pci(boot_params);
--- zfcpdump-kernel-4.4.orig/arch/x86/boot/cpuflags.h
+++ zfcpdump-kernel-4.4/arch/x86/boot/cpuflags.h
@@ -1,7 +1,7 @@
 #ifndef BOOT_CPUFLAGS_H
 #define BOOT_CPUFLAGS_H
 
-#include <asm/cpufeature.h>
+#include <asm/cpufeatures.h>
 #include <asm/processor-flags.h>
 
 struct cpu_features {
--- zfcpdump-kernel-4.4.orig/arch/x86/boot/mkcpustr.c
+++ zfcpdump-kernel-4.4/arch/x86/boot/mkcpustr.c
@@ -17,7 +17,7 @@
 
 #include "../include/asm/required-features.h"
 #include "../include/asm/disabled-features.h"
-#include "../include/asm/cpufeature.h"
+#include "../include/asm/cpufeatures.h"
 #include "../kernel/cpu/capflags.c"
 
 int main(void)
--- zfcpdump-kernel-4.4.orig/arch/x86/configs/tiny.config
+++ zfcpdump-kernel-4.4/arch/x86/configs/tiny.config
@@ -1 +1,3 @@
 CONFIG_NOHIGHMEM=y
+# CONFIG_HIGHMEM4G is not set
+# CONFIG_HIGHMEM64G is not set
--- zfcpdump-kernel-4.4.orig/arch/x86/crypto/aesni-intel_glue.c
+++ zfcpdump-kernel-4.4/arch/x86/crypto/aesni-intel_glue.c
@@ -639,16 +639,11 @@ static int xts_aesni_setkey(struct crypt
 			    unsigned int keylen)
 {
 	struct aesni_xts_ctx *ctx = crypto_tfm_ctx(tfm);
-	u32 *flags = &tfm->crt_flags;
 	int err;
 
-	/* key consists of keys of equal size concatenated, therefore
-	 * the length must be even
-	 */
-	if (keylen % 2) {
-		*flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
-		return -EINVAL;
-	}
+	err = xts_check_key(tfm, key, keylen);
+	if (err)
+		return err;
 
 	/* first half of xts-key is for crypt */
 	err = aes_set_key_common(tfm, ctx->raw_crypt_ctx, key, keylen / 2);
--- zfcpdump-kernel-4.4.orig/arch/x86/crypto/camellia_glue.c
+++ zfcpdump-kernel-4.4/arch/x86/crypto/camellia_glue.c
@@ -1503,13 +1503,9 @@ int xts_camellia_setkey(struct crypto_tf
 	u32 *flags = &tfm->crt_flags;
 	int err;
 
-	/* key consists of keys of equal size concatenated, therefore
-	 * the length must be even
-	 */
-	if (keylen % 2) {
-		*flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
-		return -EINVAL;
-	}
+	err = xts_check_key(tfm, key, keylen);
+	if (err)
+		return err;
 
 	/* first half of xts-key is for crypt */
 	err = __camellia_setkey(&ctx->crypt_ctx, key, keylen / 2, flags);
--- zfcpdump-kernel-4.4.orig/arch/x86/crypto/cast6_avx_glue.c
+++ zfcpdump-kernel-4.4/arch/x86/crypto/cast6_avx_glue.c
@@ -329,13 +329,9 @@ static int xts_cast6_setkey(struct crypt
 	u32 *flags = &tfm->crt_flags;
 	int err;
 
-	/* key consists of keys of equal size concatenated, therefore
-	 * the length must be even
-	 */
-	if (keylen % 2) {
-		*flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
-		return -EINVAL;
-	}
+	err = xts_check_key(tfm, key, keylen);
+	if (err)
+		return err;
 
 	/* first half of xts-key is for crypt */
 	err = __cast6_setkey(&ctx->crypt_ctx, key, keylen / 2, flags);
--- zfcpdump-kernel-4.4.orig/arch/x86/crypto/chacha20-ssse3-x86_64.S
+++ zfcpdump-kernel-4.4/arch/x86/crypto/chacha20-ssse3-x86_64.S
@@ -157,7 +157,9 @@ ENTRY(chacha20_4block_xor_ssse3)
 	# done with the slightly better performing SSSE3 byte shuffling,
 	# 7/12-bit word rotation uses traditional shift+OR.
 
-	sub		$0x40,%rsp
+	mov		%rsp,%r11
+	sub		$0x80,%rsp
+	and		$~63,%rsp
 
 	# x0..15[0-3] = s0..3[0..3]
 	movq		0x00(%rdi),%xmm1
@@ -620,6 +622,6 @@ ENTRY(chacha20_4block_xor_ssse3)
 	pxor		%xmm1,%xmm15
 	movdqu		%xmm15,0xf0(%rsi)
 
-	add		$0x40,%rsp
+	mov		%r11,%rsp
 	ret
 ENDPROC(chacha20_4block_xor_ssse3)
--- zfcpdump-kernel-4.4.orig/arch/x86/crypto/crc32-pclmul_glue.c
+++ zfcpdump-kernel-4.4/arch/x86/crypto/crc32-pclmul_glue.c
@@ -33,7 +33,7 @@
 #include <linux/crc32.h>
 #include <crypto/internal/hash.h>
 
-#include <asm/cpufeature.h>
+#include <asm/cpufeatures.h>
 #include <asm/cpu_device_id.h>
 #include <asm/fpu/api.h>
 
--- zfcpdump-kernel-4.4.orig/arch/x86/crypto/crc32c-intel_glue.c
+++ zfcpdump-kernel-4.4/arch/x86/crypto/crc32c-intel_glue.c
@@ -30,7 +30,7 @@
 #include <linux/kernel.h>
 #include <crypto/internal/hash.h>
 
-#include <asm/cpufeature.h>
+#include <asm/cpufeatures.h>
 #include <asm/cpu_device_id.h>
 #include <asm/fpu/internal.h>
 
--- zfcpdump-kernel-4.4.orig/arch/x86/crypto/crct10dif-pclmul_glue.c
+++ zfcpdump-kernel-4.4/arch/x86/crypto/crct10dif-pclmul_glue.c
@@ -30,7 +30,7 @@
 #include <linux/string.h>
 #include <linux/kernel.h>
 #include <asm/fpu/api.h>
-#include <asm/cpufeature.h>
+#include <asm/cpufeatures.h>
 #include <asm/cpu_device_id.h>
 
 asmlinkage __u16 crc_t10dif_pcl(__u16 crc, const unsigned char *buf,
--- zfcpdump-kernel-4.4.orig/arch/x86/crypto/serpent_avx_glue.c
+++ zfcpdump-kernel-4.4/arch/x86/crypto/serpent_avx_glue.c
@@ -332,16 +332,11 @@ int xts_serpent_setkey(struct crypto_tfm
 		       unsigned int keylen)
 {
 	struct serpent_xts_ctx *ctx = crypto_tfm_ctx(tfm);
-	u32 *flags = &tfm->crt_flags;
 	int err;
 
-	/* key consists of keys of equal size concatenated, therefore
-	 * the length must be even
-	 */
-	if (keylen % 2) {
-		*flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
-		return -EINVAL;
-	}
+	err = xts_check_key(tfm, key, keylen);
+	if (err)
+		return err;
 
 	/* first half of xts-key is for crypt */
 	err = __serpent_setkey(&ctx->crypt_ctx, key, keylen / 2);
--- zfcpdump-kernel-4.4.orig/arch/x86/crypto/serpent_sse2_glue.c
+++ zfcpdump-kernel-4.4/arch/x86/crypto/serpent_sse2_glue.c
@@ -309,16 +309,11 @@ static int xts_serpent_setkey(struct cry
 			      unsigned int keylen)
 {
 	struct serpent_xts_ctx *ctx = crypto_tfm_ctx(tfm);
-	u32 *flags = &tfm->crt_flags;
 	int err;
 
-	/* key consists of keys of equal size concatenated, therefore
-	 * the length must be even
-	 */
-	if (keylen % 2) {
-		*flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
-		return -EINVAL;
-	}
+	err = xts_check_key(tfm, key, keylen);
+	if (err)
+		return err;
 
 	/* first half of xts-key is for crypt */
 	err = __serpent_setkey(&ctx->crypt_ctx, key, keylen / 2);
--- zfcpdump-kernel-4.4.orig/arch/x86/crypto/sha-mb/sha1_mb.c
+++ zfcpdump-kernel-4.4/arch/x86/crypto/sha-mb/sha1_mb.c
@@ -453,10 +453,10 @@ static int sha_complete_job(struct mcryp
 
 			req = cast_mcryptd_ctx_to_req(req_ctx);
 			if (irqs_disabled())
-				rctx->complete(&req->base, ret);
+				req_ctx->complete(&req->base, ret);
 			else {
 				local_bh_disable();
-				rctx->complete(&req->base, ret);
+				req_ctx->complete(&req->base, ret);
 				local_bh_enable();
 			}
 		}
--- zfcpdump-kernel-4.4.orig/arch/x86/crypto/twofish_glue_3way.c
+++ zfcpdump-kernel-4.4/arch/x86/crypto/twofish_glue_3way.c
@@ -277,13 +277,9 @@ int xts_twofish_setkey(struct crypto_tfm
 	u32 *flags = &tfm->crt_flags;
 	int err;
 
-	/* key consists of keys of equal size concatenated, therefore
-	 * the length must be even
-	 */
-	if (keylen % 2) {
-		*flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
-		return -EINVAL;
-	}
+	err = xts_check_key(tfm, key, keylen);
+	if (err)
+		return err;
 
 	/* first half of xts-key is for crypt */
 	err = __twofish_setkey(&ctx->crypt_ctx, key, keylen / 2, flags);
--- zfcpdump-kernel-4.4.orig/arch/x86/entry/common.c
+++ zfcpdump-kernel-4.4/arch/x86/entry/common.c
@@ -26,6 +26,7 @@
 #include <asm/traps.h>
 #include <asm/vdso.h>
 #include <asm/uaccess.h>
+#include <asm/cpufeature.h>
 
 #define CREATE_TRACE_POINTS
 #include <trace/events/syscalls.h>
@@ -268,6 +269,7 @@ static void exit_to_usermode_loop(struct
 /* Called with IRQs disabled. */
 __visible inline void prepare_exit_to_usermode(struct pt_regs *regs)
 {
+	struct thread_info *ti = pt_regs_to_thread_info(regs);
 	u32 cached_flags;
 
 	if (IS_ENABLED(CONFIG_PROVE_LOCKING) && WARN_ON(!irqs_disabled()))
@@ -275,12 +277,22 @@ __visible inline void prepare_exit_to_us
 
 	lockdep_sys_exit();
 
-	cached_flags =
-		READ_ONCE(pt_regs_to_thread_info(regs)->flags);
+	cached_flags = READ_ONCE(ti->flags);
 
 	if (unlikely(cached_flags & EXIT_TO_USERMODE_LOOP_FLAGS))
 		exit_to_usermode_loop(regs, cached_flags);
 
+#ifdef CONFIG_COMPAT
+	/*
+	 * Compat syscalls set TS_COMPAT.  Make sure we clear it before
+	 * returning to user mode.  We need to clear it *after* signal
+	 * handling, because syscall restart has a fixup for compat
+	 * syscalls.  The fixup is exercised by the ptrace_syscall_32
+	 * selftest.
+	 */
+	ti->status &= ~TS_COMPAT;
+#endif
+
 	user_enter();
 }
 
@@ -332,14 +344,6 @@ __visible inline void syscall_return_slo
 	if (unlikely(cached_flags & SYSCALL_EXIT_WORK_FLAGS))
 		syscall_slow_exit_work(regs, cached_flags);
 
-#ifdef CONFIG_COMPAT
-	/*
-	 * Compat syscalls set TS_COMPAT.  Make sure we clear it before
-	 * returning to user mode.
-	 */
-	ti->status &= ~TS_COMPAT;
-#endif
-
 	local_irq_disable();
 	prepare_exit_to_usermode(regs);
 }
--- zfcpdump-kernel-4.4.orig/arch/x86/entry/entry_32.S
+++ zfcpdump-kernel-4.4/arch/x86/entry/entry_32.S
@@ -40,7 +40,7 @@
 #include <asm/processor-flags.h>
 #include <asm/ftrace.h>
 #include <asm/irq_vectors.h>
-#include <asm/cpufeature.h>
+#include <asm/cpufeatures.h>
 #include <asm/alternative-asm.h>
 #include <asm/asm.h>
 #include <asm/smap.h>
--- zfcpdump-kernel-4.4.orig/arch/x86/entry/entry_64_compat.S
+++ zfcpdump-kernel-4.4/arch/x86/entry/entry_64_compat.S
@@ -267,6 +267,7 @@ ENTRY(entry_INT80_compat)
 	 * Interrupts are off on entry.
 	 */
 	PARAVIRT_ADJUST_EXCEPTION_FRAME
+	ASM_CLAC			/* Do this early to minimize exposure */
 	SWAPGS
 
 	/*
--- zfcpdump-kernel-4.4.orig/arch/x86/entry/syscalls/syscall_32.tbl
+++ zfcpdump-kernel-4.4/arch/x86/entry/syscalls/syscall_32.tbl
@@ -294,7 +294,7 @@
 # 285 sys_setaltroot
 286	i386	add_key			sys_add_key
 287	i386	request_key		sys_request_key
-288	i386	keyctl			sys_keyctl
+288	i386	keyctl			sys_keyctl			compat_sys_keyctl
 289	i386	ioprio_set		sys_ioprio_set
 290	i386	ioprio_get		sys_ioprio_get
 291	i386	inotify_init		sys_inotify_init
--- zfcpdump-kernel-4.4.orig/arch/x86/entry/vdso/vdso32-setup.c
+++ zfcpdump-kernel-4.4/arch/x86/entry/vdso/vdso32-setup.c
@@ -11,7 +11,6 @@
 #include <linux/kernel.h>
 #include <linux/mm_types.h>
 
-#include <asm/cpufeature.h>
 #include <asm/processor.h>
 #include <asm/vdso.h>
 
--- zfcpdump-kernel-4.4.orig/arch/x86/entry/vdso/vdso32/system_call.S
+++ zfcpdump-kernel-4.4/arch/x86/entry/vdso/vdso32/system_call.S
@@ -3,7 +3,7 @@
 */
 
 #include <asm/dwarf2.h>
-#include <asm/cpufeature.h>
+#include <asm/cpufeatures.h>
 #include <asm/alternative-asm.h>
 
 /*
--- zfcpdump-kernel-4.4.orig/arch/x86/entry/vdso/vma.c
+++ zfcpdump-kernel-4.4/arch/x86/entry/vdso/vma.c
@@ -19,6 +19,7 @@
 #include <asm/page.h>
 #include <asm/hpet.h>
 #include <asm/desc.h>
+#include <asm/cpufeature.h>
 
 #if defined(CONFIG_X86_64)
 unsigned int __read_mostly vdso64_enabled = 1;
--- /dev/null
+++ zfcpdump-kernel-4.4/arch/x86/events/Makefile
@@ -0,0 +1,13 @@
+obj-y			+= core.o
+
+obj-$(CONFIG_CPU_SUP_AMD)               += amd/core.o amd/uncore.o
+obj-$(CONFIG_X86_LOCAL_APIC)            += amd/ibs.o msr.o
+ifdef CONFIG_AMD_IOMMU
+obj-$(CONFIG_CPU_SUP_AMD)               += amd/iommu.o
+endif
+obj-$(CONFIG_CPU_SUP_INTEL)		+= intel/core.o intel/bts.o intel/cqm.o
+obj-$(CONFIG_CPU_SUP_INTEL)		+= intel/cstate.o intel/ds.o intel/knc.o 
+obj-$(CONFIG_CPU_SUP_INTEL)		+= intel/lbr.o intel/p4.o intel/p6.o intel/pt.o
+obj-$(CONFIG_CPU_SUP_INTEL)		+= intel/rapl.o msr.o
+obj-$(CONFIG_PERF_EVENTS_INTEL_UNCORE)	+= intel/uncore.o intel/uncore_nhmex.o
+obj-$(CONFIG_PERF_EVENTS_INTEL_UNCORE)	+= intel/uncore_snb.o intel/uncore_snbep.o
--- /dev/null
+++ zfcpdump-kernel-4.4/arch/x86/events/amd/core.c
@@ -0,0 +1,731 @@
+#include <linux/perf_event.h>
+#include <linux/export.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <asm/apicdef.h>
+
+#include "../perf_event.h"
+
+static __initconst const u64 amd_hw_cache_event_ids
+				[PERF_COUNT_HW_CACHE_MAX]
+				[PERF_COUNT_HW_CACHE_OP_MAX]
+				[PERF_COUNT_HW_CACHE_RESULT_MAX] =
+{
+ [ C(L1D) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = 0x0040, /* Data Cache Accesses        */
+		[ C(RESULT_MISS)   ] = 0x0141, /* Data Cache Misses          */
+	},
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = 0x0142, /* Data Cache Refills :system */
+		[ C(RESULT_MISS)   ] = 0,
+	},
+	[ C(OP_PREFETCH) ] = {
+		[ C(RESULT_ACCESS) ] = 0x0267, /* Data Prefetcher :attempts  */
+		[ C(RESULT_MISS)   ] = 0x0167, /* Data Prefetcher :cancelled */
+	},
+ },
+ [ C(L1I ) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = 0x0080, /* Instruction cache fetches  */
+		[ C(RESULT_MISS)   ] = 0x0081, /* Instruction cache misses   */
+	},
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = -1,
+		[ C(RESULT_MISS)   ] = -1,
+	},
+	[ C(OP_PREFETCH) ] = {
+		[ C(RESULT_ACCESS) ] = 0x014B, /* Prefetch Instructions :Load */
+		[ C(RESULT_MISS)   ] = 0,
+	},
+ },
+ [ C(LL  ) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = 0x037D, /* Requests to L2 Cache :IC+DC */
+		[ C(RESULT_MISS)   ] = 0x037E, /* L2 Cache Misses : IC+DC     */
+	},
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = 0x017F, /* L2 Fill/Writeback           */
+		[ C(RESULT_MISS)   ] = 0,
+	},
+	[ C(OP_PREFETCH) ] = {
+		[ C(RESULT_ACCESS) ] = 0,
+		[ C(RESULT_MISS)   ] = 0,
+	},
+ },
+ [ C(DTLB) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = 0x0040, /* Data Cache Accesses        */
+		[ C(RESULT_MISS)   ] = 0x0746, /* L1_DTLB_AND_L2_DLTB_MISS.ALL */
+	},
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = 0,
+		[ C(RESULT_MISS)   ] = 0,
+	},
+	[ C(OP_PREFETCH) ] = {
+		[ C(RESULT_ACCESS) ] = 0,
+		[ C(RESULT_MISS)   ] = 0,
+	},
+ },
+ [ C(ITLB) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = 0x0080, /* Instruction fecthes        */
+		[ C(RESULT_MISS)   ] = 0x0385, /* L1_ITLB_AND_L2_ITLB_MISS.ALL */
+	},
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = -1,
+		[ C(RESULT_MISS)   ] = -1,
+	},
+	[ C(OP_PREFETCH) ] = {
+		[ C(RESULT_ACCESS) ] = -1,
+		[ C(RESULT_MISS)   ] = -1,
+	},
+ },
+ [ C(BPU ) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = 0x00c2, /* Retired Branch Instr.      */
+		[ C(RESULT_MISS)   ] = 0x00c3, /* Retired Mispredicted BI    */
+	},
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = -1,
+		[ C(RESULT_MISS)   ] = -1,
+	},
+	[ C(OP_PREFETCH) ] = {
+		[ C(RESULT_ACCESS) ] = -1,
+		[ C(RESULT_MISS)   ] = -1,
+	},
+ },
+ [ C(NODE) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = 0xb8e9, /* CPU Request to Memory, l+r */
+		[ C(RESULT_MISS)   ] = 0x98e9, /* CPU Request to Memory, r   */
+	},
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = -1,
+		[ C(RESULT_MISS)   ] = -1,
+	},
+	[ C(OP_PREFETCH) ] = {
+		[ C(RESULT_ACCESS) ] = -1,
+		[ C(RESULT_MISS)   ] = -1,
+	},
+ },
+};
+
+/*
+ * AMD Performance Monitor K7 and later.
+ */
+static const u64 amd_perfmon_event_map[] =
+{
+  [PERF_COUNT_HW_CPU_CYCLES]			= 0x0076,
+  [PERF_COUNT_HW_INSTRUCTIONS]			= 0x00c0,
+  [PERF_COUNT_HW_CACHE_REFERENCES]		= 0x0080,
+  [PERF_COUNT_HW_CACHE_MISSES]			= 0x0081,
+  [PERF_COUNT_HW_BRANCH_INSTRUCTIONS]		= 0x00c2,
+  [PERF_COUNT_HW_BRANCH_MISSES]			= 0x00c3,
+  [PERF_COUNT_HW_STALLED_CYCLES_FRONTEND]	= 0x00d0, /* "Decoder empty" event */
+  [PERF_COUNT_HW_STALLED_CYCLES_BACKEND]	= 0x00d1, /* "Dispatch stalls" event */
+};
+
+static u64 amd_pmu_event_map(int hw_event)
+{
+	return amd_perfmon_event_map[hw_event];
+}
+
+/*
+ * Previously calculated offsets
+ */
+static unsigned int event_offsets[X86_PMC_IDX_MAX] __read_mostly;
+static unsigned int count_offsets[X86_PMC_IDX_MAX] __read_mostly;
+
+/*
+ * Legacy CPUs:
+ *   4 counters starting at 0xc0010000 each offset by 1
+ *
+ * CPUs with core performance counter extensions:
+ *   6 counters starting at 0xc0010200 each offset by 2
+ */
+static inline int amd_pmu_addr_offset(int index, bool eventsel)
+{
+	int offset;
+
+	if (!index)
+		return index;
+
+	if (eventsel)
+		offset = event_offsets[index];
+	else
+		offset = count_offsets[index];
+
+	if (offset)
+		return offset;
+
+	if (!cpu_has_perfctr_core)
+		offset = index;
+	else
+		offset = index << 1;
+
+	if (eventsel)
+		event_offsets[index] = offset;
+	else
+		count_offsets[index] = offset;
+
+	return offset;
+}
+
+static int amd_core_hw_config(struct perf_event *event)
+{
+	if (event->attr.exclude_host && event->attr.exclude_guest)
+		/*
+		 * When HO == GO == 1 the hardware treats that as GO == HO == 0
+		 * and will count in both modes. We don't want to count in that
+		 * case so we emulate no-counting by setting US = OS = 0.
+		 */
+		event->hw.config &= ~(ARCH_PERFMON_EVENTSEL_USR |
+				      ARCH_PERFMON_EVENTSEL_OS);
+	else if (event->attr.exclude_host)
+		event->hw.config |= AMD64_EVENTSEL_GUESTONLY;
+	else if (event->attr.exclude_guest)
+		event->hw.config |= AMD64_EVENTSEL_HOSTONLY;
+
+	return 0;
+}
+
+/*
+ * AMD64 events are detected based on their event codes.
+ */
+static inline unsigned int amd_get_event_code(struct hw_perf_event *hwc)
+{
+	return ((hwc->config >> 24) & 0x0f00) | (hwc->config & 0x00ff);
+}
+
+static inline int amd_is_nb_event(struct hw_perf_event *hwc)
+{
+	return (hwc->config & 0xe0) == 0xe0;
+}
+
+static inline int amd_has_nb(struct cpu_hw_events *cpuc)
+{
+	struct amd_nb *nb = cpuc->amd_nb;
+
+	return nb && nb->nb_id != -1;
+}
+
+static int amd_pmu_hw_config(struct perf_event *event)
+{
+	int ret;
+
+	/* pass precise event sampling to ibs: */
+	if (event->attr.precise_ip && get_ibs_caps())
+		return -ENOENT;
+
+	if (has_branch_stack(event))
+		return -EOPNOTSUPP;
+
+	ret = x86_pmu_hw_config(event);
+	if (ret)
+		return ret;
+
+	if (event->attr.type == PERF_TYPE_RAW)
+		event->hw.config |= event->attr.config & AMD64_RAW_EVENT_MASK;
+
+	return amd_core_hw_config(event);
+}
+
+static void __amd_put_nb_event_constraints(struct cpu_hw_events *cpuc,
+					   struct perf_event *event)
+{
+	struct amd_nb *nb = cpuc->amd_nb;
+	int i;
+
+	/*
+	 * need to scan whole list because event may not have
+	 * been assigned during scheduling
+	 *
+	 * no race condition possible because event can only
+	 * be removed on one CPU at a time AND PMU is disabled
+	 * when we come here
+	 */
+	for (i = 0; i < x86_pmu.num_counters; i++) {
+		if (cmpxchg(nb->owners + i, event, NULL) == event)
+			break;
+	}
+}
+
+ /*
+  * AMD64 NorthBridge events need special treatment because
+  * counter access needs to be synchronized across all cores
+  * of a package. Refer to BKDG section 3.12
+  *
+  * NB events are events measuring L3 cache, Hypertransport
+  * traffic. They are identified by an event code >= 0xe00.
+  * They measure events on the NorthBride which is shared
+  * by all cores on a package. NB events are counted on a
+  * shared set of counters. When a NB event is programmed
+  * in a counter, the data actually comes from a shared
+  * counter. Thus, access to those counters needs to be
+  * synchronized.
+  *
+  * We implement the synchronization such that no two cores
+  * can be measuring NB events using the same counters. Thus,
+  * we maintain a per-NB allocation table. The available slot
+  * is propagated using the event_constraint structure.
+  *
+  * We provide only one choice for each NB event based on
+  * the fact that only NB events have restrictions. Consequently,
+  * if a counter is available, there is a guarantee the NB event
+  * will be assigned to it. If no slot is available, an empty
+  * constraint is returned and scheduling will eventually fail
+  * for this event.
+  *
+  * Note that all cores attached the same NB compete for the same
+  * counters to host NB events, this is why we use atomic ops. Some
+  * multi-chip CPUs may have more than one NB.
+  *
+  * Given that resources are allocated (cmpxchg), they must be
+  * eventually freed for others to use. This is accomplished by
+  * calling __amd_put_nb_event_constraints()
+  *
+  * Non NB events are not impacted by this restriction.
+  */
+static struct event_constraint *
+__amd_get_nb_event_constraints(struct cpu_hw_events *cpuc, struct perf_event *event,
+			       struct event_constraint *c)
+{
+	struct hw_perf_event *hwc = &event->hw;
+	struct amd_nb *nb = cpuc->amd_nb;
+	struct perf_event *old;
+	int idx, new = -1;
+
+	if (!c)
+		c = &unconstrained;
+
+	if (cpuc->is_fake)
+		return c;
+
+	/*
+	 * detect if already present, if so reuse
+	 *
+	 * cannot merge with actual allocation
+	 * because of possible holes
+	 *
+	 * event can already be present yet not assigned (in hwc->idx)
+	 * because of successive calls to x86_schedule_events() from
+	 * hw_perf_group_sched_in() without hw_perf_enable()
+	 */
+	for_each_set_bit(idx, c->idxmsk, x86_pmu.num_counters) {
+		if (new == -1 || hwc->idx == idx)
+			/* assign free slot, prefer hwc->idx */
+			old = cmpxchg(nb->owners + idx, NULL, event);
+		else if (nb->owners[idx] == event)
+			/* event already present */
+			old = event;
+		else
+			continue;
+
+		if (old && old != event)
+			continue;
+
+		/* reassign to this slot */
+		if (new != -1)
+			cmpxchg(nb->owners + new, event, NULL);
+		new = idx;
+
+		/* already present, reuse */
+		if (old == event)
+			break;
+	}
+
+	if (new == -1)
+		return &emptyconstraint;
+
+	return &nb->event_constraints[new];
+}
+
+static struct amd_nb *amd_alloc_nb(int cpu)
+{
+	struct amd_nb *nb;
+	int i;
+
+	nb = kzalloc_node(sizeof(struct amd_nb), GFP_KERNEL, cpu_to_node(cpu));
+	if (!nb)
+		return NULL;
+
+	nb->nb_id = -1;
+
+	/*
+	 * initialize all possible NB constraints
+	 */
+	for (i = 0; i < x86_pmu.num_counters; i++) {
+		__set_bit(i, nb->event_constraints[i].idxmsk);
+		nb->event_constraints[i].weight = 1;
+	}
+	return nb;
+}
+
+static int amd_pmu_cpu_prepare(int cpu)
+{
+	struct cpu_hw_events *cpuc = &per_cpu(cpu_hw_events, cpu);
+
+	WARN_ON_ONCE(cpuc->amd_nb);
+
+	if (boot_cpu_data.x86_max_cores < 2)
+		return NOTIFY_OK;
+
+	cpuc->amd_nb = amd_alloc_nb(cpu);
+	if (!cpuc->amd_nb)
+		return NOTIFY_BAD;
+
+	return NOTIFY_OK;
+}
+
+static void amd_pmu_cpu_starting(int cpu)
+{
+	struct cpu_hw_events *cpuc = &per_cpu(cpu_hw_events, cpu);
+	void **onln = &cpuc->kfree_on_online[X86_PERF_KFREE_SHARED];
+	struct amd_nb *nb;
+	int i, nb_id;
+
+	cpuc->perf_ctr_virt_mask = AMD64_EVENTSEL_HOSTONLY;
+
+	if (boot_cpu_data.x86_max_cores < 2)
+		return;
+
+	nb_id = amd_get_nb_id(cpu);
+	WARN_ON_ONCE(nb_id == BAD_APICID);
+
+	for_each_online_cpu(i) {
+		nb = per_cpu(cpu_hw_events, i).amd_nb;
+		if (WARN_ON_ONCE(!nb))
+			continue;
+
+		if (nb->nb_id == nb_id) {
+			*onln = cpuc->amd_nb;
+			cpuc->amd_nb = nb;
+			break;
+		}
+	}
+
+	cpuc->amd_nb->nb_id = nb_id;
+	cpuc->amd_nb->refcnt++;
+}
+
+static void amd_pmu_cpu_dead(int cpu)
+{
+	struct cpu_hw_events *cpuhw;
+
+	if (boot_cpu_data.x86_max_cores < 2)
+		return;
+
+	cpuhw = &per_cpu(cpu_hw_events, cpu);
+
+	if (cpuhw->amd_nb) {
+		struct amd_nb *nb = cpuhw->amd_nb;
+
+		if (nb->nb_id == -1 || --nb->refcnt == 0)
+			kfree(nb);
+
+		cpuhw->amd_nb = NULL;
+	}
+}
+
+static struct event_constraint *
+amd_get_event_constraints(struct cpu_hw_events *cpuc, int idx,
+			  struct perf_event *event)
+{
+	/*
+	 * if not NB event or no NB, then no constraints
+	 */
+	if (!(amd_has_nb(cpuc) && amd_is_nb_event(&event->hw)))
+		return &unconstrained;
+
+	return __amd_get_nb_event_constraints(cpuc, event, NULL);
+}
+
+static void amd_put_event_constraints(struct cpu_hw_events *cpuc,
+				      struct perf_event *event)
+{
+	if (amd_has_nb(cpuc) && amd_is_nb_event(&event->hw))
+		__amd_put_nb_event_constraints(cpuc, event);
+}
+
+PMU_FORMAT_ATTR(event,	"config:0-7,32-35");
+PMU_FORMAT_ATTR(umask,	"config:8-15"	);
+PMU_FORMAT_ATTR(edge,	"config:18"	);
+PMU_FORMAT_ATTR(inv,	"config:23"	);
+PMU_FORMAT_ATTR(cmask,	"config:24-31"	);
+
+static struct attribute *amd_format_attr[] = {
+	&format_attr_event.attr,
+	&format_attr_umask.attr,
+	&format_attr_edge.attr,
+	&format_attr_inv.attr,
+	&format_attr_cmask.attr,
+	NULL,
+};
+
+/* AMD Family 15h */
+
+#define AMD_EVENT_TYPE_MASK	0x000000F0ULL
+
+#define AMD_EVENT_FP		0x00000000ULL ... 0x00000010ULL
+#define AMD_EVENT_LS		0x00000020ULL ... 0x00000030ULL
+#define AMD_EVENT_DC		0x00000040ULL ... 0x00000050ULL
+#define AMD_EVENT_CU		0x00000060ULL ... 0x00000070ULL
+#define AMD_EVENT_IC_DE		0x00000080ULL ... 0x00000090ULL
+#define AMD_EVENT_EX_LS		0x000000C0ULL
+#define AMD_EVENT_DE		0x000000D0ULL
+#define AMD_EVENT_NB		0x000000E0ULL ... 0x000000F0ULL
+
+/*
+ * AMD family 15h event code/PMC mappings:
+ *
+ * type = event_code & 0x0F0:
+ *
+ * 0x000	FP	PERF_CTL[5:3]
+ * 0x010	FP	PERF_CTL[5:3]
+ * 0x020	LS	PERF_CTL[5:0]
+ * 0x030	LS	PERF_CTL[5:0]
+ * 0x040	DC	PERF_CTL[5:0]
+ * 0x050	DC	PERF_CTL[5:0]
+ * 0x060	CU	PERF_CTL[2:0]
+ * 0x070	CU	PERF_CTL[2:0]
+ * 0x080	IC/DE	PERF_CTL[2:0]
+ * 0x090	IC/DE	PERF_CTL[2:0]
+ * 0x0A0	---
+ * 0x0B0	---
+ * 0x0C0	EX/LS	PERF_CTL[5:0]
+ * 0x0D0	DE	PERF_CTL[2:0]
+ * 0x0E0	NB	NB_PERF_CTL[3:0]
+ * 0x0F0	NB	NB_PERF_CTL[3:0]
+ *
+ * Exceptions:
+ *
+ * 0x000	FP	PERF_CTL[3], PERF_CTL[5:3] (*)
+ * 0x003	FP	PERF_CTL[3]
+ * 0x004	FP	PERF_CTL[3], PERF_CTL[5:3] (*)
+ * 0x00B	FP	PERF_CTL[3]
+ * 0x00D	FP	PERF_CTL[3]
+ * 0x023	DE	PERF_CTL[2:0]
+ * 0x02D	LS	PERF_CTL[3]
+ * 0x02E	LS	PERF_CTL[3,0]
+ * 0x031	LS	PERF_CTL[2:0] (**)
+ * 0x043	CU	PERF_CTL[2:0]
+ * 0x045	CU	PERF_CTL[2:0]
+ * 0x046	CU	PERF_CTL[2:0]
+ * 0x054	CU	PERF_CTL[2:0]
+ * 0x055	CU	PERF_CTL[2:0]
+ * 0x08F	IC	PERF_CTL[0]
+ * 0x187	DE	PERF_CTL[0]
+ * 0x188	DE	PERF_CTL[0]
+ * 0x0DB	EX	PERF_CTL[5:0]
+ * 0x0DC	LS	PERF_CTL[5:0]
+ * 0x0DD	LS	PERF_CTL[5:0]
+ * 0x0DE	LS	PERF_CTL[5:0]
+ * 0x0DF	LS	PERF_CTL[5:0]
+ * 0x1C0	EX	PERF_CTL[5:3]
+ * 0x1D6	EX	PERF_CTL[5:0]
+ * 0x1D8	EX	PERF_CTL[5:0]
+ *
+ * (*)  depending on the umask all FPU counters may be used
+ * (**) only one unitmask enabled at a time
+ */
+
+static struct event_constraint amd_f15_PMC0  = EVENT_CONSTRAINT(0, 0x01, 0);
+static struct event_constraint amd_f15_PMC20 = EVENT_CONSTRAINT(0, 0x07, 0);
+static struct event_constraint amd_f15_PMC3  = EVENT_CONSTRAINT(0, 0x08, 0);
+static struct event_constraint amd_f15_PMC30 = EVENT_CONSTRAINT_OVERLAP(0, 0x09, 0);
+static struct event_constraint amd_f15_PMC50 = EVENT_CONSTRAINT(0, 0x3F, 0);
+static struct event_constraint amd_f15_PMC53 = EVENT_CONSTRAINT(0, 0x38, 0);
+
+static struct event_constraint *
+amd_get_event_constraints_f15h(struct cpu_hw_events *cpuc, int idx,
+			       struct perf_event *event)
+{
+	struct hw_perf_event *hwc = &event->hw;
+	unsigned int event_code = amd_get_event_code(hwc);
+
+	switch (event_code & AMD_EVENT_TYPE_MASK) {
+	case AMD_EVENT_FP:
+		switch (event_code) {
+		case 0x000:
+			if (!(hwc->config & 0x0000F000ULL))
+				break;
+			if (!(hwc->config & 0x00000F00ULL))
+				break;
+			return &amd_f15_PMC3;
+		case 0x004:
+			if (hweight_long(hwc->config & ARCH_PERFMON_EVENTSEL_UMASK) <= 1)
+				break;
+			return &amd_f15_PMC3;
+		case 0x003:
+		case 0x00B:
+		case 0x00D:
+			return &amd_f15_PMC3;
+		}
+		return &amd_f15_PMC53;
+	case AMD_EVENT_LS:
+	case AMD_EVENT_DC:
+	case AMD_EVENT_EX_LS:
+		switch (event_code) {
+		case 0x023:
+		case 0x043:
+		case 0x045:
+		case 0x046:
+		case 0x054:
+		case 0x055:
+			return &amd_f15_PMC20;
+		case 0x02D:
+			return &amd_f15_PMC3;
+		case 0x02E:
+			return &amd_f15_PMC30;
+		case 0x031:
+			if (hweight_long(hwc->config & ARCH_PERFMON_EVENTSEL_UMASK) <= 1)
+				return &amd_f15_PMC20;
+			return &emptyconstraint;
+		case 0x1C0:
+			return &amd_f15_PMC53;
+		default:
+			return &amd_f15_PMC50;
+		}
+	case AMD_EVENT_CU:
+	case AMD_EVENT_IC_DE:
+	case AMD_EVENT_DE:
+		switch (event_code) {
+		case 0x08F:
+		case 0x187:
+		case 0x188:
+			return &amd_f15_PMC0;
+		case 0x0DB ... 0x0DF:
+		case 0x1D6:
+		case 0x1D8:
+			return &amd_f15_PMC50;
+		default:
+			return &amd_f15_PMC20;
+		}
+	case AMD_EVENT_NB:
+		/* moved to perf_event_amd_uncore.c */
+		return &emptyconstraint;
+	default:
+		return &emptyconstraint;
+	}
+}
+
+static ssize_t amd_event_sysfs_show(char *page, u64 config)
+{
+	u64 event = (config & ARCH_PERFMON_EVENTSEL_EVENT) |
+		    (config & AMD64_EVENTSEL_EVENT) >> 24;
+
+	return x86_event_sysfs_show(page, config, event);
+}
+
+static __initconst const struct x86_pmu amd_pmu = {
+	.name			= "AMD",
+	.handle_irq		= x86_pmu_handle_irq,
+	.disable_all		= x86_pmu_disable_all,
+	.enable_all		= x86_pmu_enable_all,
+	.enable			= x86_pmu_enable_event,
+	.disable		= x86_pmu_disable_event,
+	.hw_config		= amd_pmu_hw_config,
+	.schedule_events	= x86_schedule_events,
+	.eventsel		= MSR_K7_EVNTSEL0,
+	.perfctr		= MSR_K7_PERFCTR0,
+	.addr_offset            = amd_pmu_addr_offset,
+	.event_map		= amd_pmu_event_map,
+	.max_events		= ARRAY_SIZE(amd_perfmon_event_map),
+	.num_counters		= AMD64_NUM_COUNTERS,
+	.cntval_bits		= 48,
+	.cntval_mask		= (1ULL << 48) - 1,
+	.apic			= 1,
+	/* use highest bit to detect overflow */
+	.max_period		= (1ULL << 47) - 1,
+	.get_event_constraints	= amd_get_event_constraints,
+	.put_event_constraints	= amd_put_event_constraints,
+
+	.format_attrs		= amd_format_attr,
+	.events_sysfs_show	= amd_event_sysfs_show,
+
+	.cpu_prepare		= amd_pmu_cpu_prepare,
+	.cpu_starting		= amd_pmu_cpu_starting,
+	.cpu_dead		= amd_pmu_cpu_dead,
+};
+
+static int __init amd_core_pmu_init(void)
+{
+	if (!cpu_has_perfctr_core)
+		return 0;
+
+	switch (boot_cpu_data.x86) {
+	case 0x15:
+		pr_cont("Fam15h ");
+		x86_pmu.get_event_constraints = amd_get_event_constraints_f15h;
+		break;
+
+	default:
+		pr_err("core perfctr but no constraints; unknown hardware!\n");
+		return -ENODEV;
+	}
+
+	/*
+	 * If core performance counter extensions exists, we must use
+	 * MSR_F15H_PERF_CTL/MSR_F15H_PERF_CTR msrs. See also
+	 * amd_pmu_addr_offset().
+	 */
+	x86_pmu.eventsel	= MSR_F15H_PERF_CTL;
+	x86_pmu.perfctr		= MSR_F15H_PERF_CTR;
+	x86_pmu.num_counters	= AMD64_NUM_COUNTERS_CORE;
+
+	pr_cont("core perfctr, ");
+	return 0;
+}
+
+__init int amd_pmu_init(void)
+{
+	int ret;
+
+	/* Performance-monitoring supported from K7 and later: */
+	if (boot_cpu_data.x86 < 6)
+		return -ENODEV;
+
+	x86_pmu = amd_pmu;
+
+	ret = amd_core_pmu_init();
+	if (ret)
+		return ret;
+
+	/* Events are common for all AMDs */
+	memcpy(hw_cache_event_ids, amd_hw_cache_event_ids,
+	       sizeof(hw_cache_event_ids));
+
+	return 0;
+}
+
+void amd_pmu_enable_virt(void)
+{
+	struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
+
+	cpuc->perf_ctr_virt_mask = 0;
+
+	/* Reload all events */
+	x86_pmu_disable_all();
+	x86_pmu_enable_all(0);
+}
+EXPORT_SYMBOL_GPL(amd_pmu_enable_virt);
+
+void amd_pmu_disable_virt(void)
+{
+	struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
+
+	/*
+	 * We only mask out the Host-only bit so that host-only counting works
+	 * when SVM is disabled. If someone sets up a guest-only counter when
+	 * SVM is disabled the Guest-only bits still gets set and the counter
+	 * will not count anything.
+	 */
+	cpuc->perf_ctr_virt_mask = AMD64_EVENTSEL_HOSTONLY;
+
+	/* Reload all events */
+	x86_pmu_disable_all();
+	x86_pmu_enable_all(0);
+}
+EXPORT_SYMBOL_GPL(amd_pmu_disable_virt);
--- /dev/null
+++ zfcpdump-kernel-4.4/arch/x86/events/amd/ibs.c
@@ -0,0 +1,959 @@
+/*
+ * Performance events - AMD IBS
+ *
+ *  Copyright (C) 2011 Advanced Micro Devices, Inc., Robert Richter
+ *
+ *  For licencing details see kernel-base/COPYING
+ */
+
+#include <linux/perf_event.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/ptrace.h>
+#include <linux/syscore_ops.h>
+
+#include <asm/apic.h>
+
+#include "../perf_event.h"
+
+static u32 ibs_caps;
+
+#if defined(CONFIG_PERF_EVENTS) && defined(CONFIG_CPU_SUP_AMD)
+
+#include <linux/kprobes.h>
+#include <linux/hardirq.h>
+
+#include <asm/nmi.h>
+
+#define IBS_FETCH_CONFIG_MASK	(IBS_FETCH_RAND_EN | IBS_FETCH_MAX_CNT)
+#define IBS_OP_CONFIG_MASK	IBS_OP_MAX_CNT
+
+enum ibs_states {
+	IBS_ENABLED	= 0,
+	IBS_STARTED	= 1,
+	IBS_STOPPING	= 2,
+
+	IBS_MAX_STATES,
+};
+
+struct cpu_perf_ibs {
+	struct perf_event	*event;
+	unsigned long		state[BITS_TO_LONGS(IBS_MAX_STATES)];
+};
+
+struct perf_ibs {
+	struct pmu			pmu;
+	unsigned int			msr;
+	u64				config_mask;
+	u64				cnt_mask;
+	u64				enable_mask;
+	u64				valid_mask;
+	u64				max_period;
+	unsigned long			offset_mask[1];
+	int				offset_max;
+	struct cpu_perf_ibs __percpu	*pcpu;
+
+	struct attribute		**format_attrs;
+	struct attribute_group		format_group;
+	const struct attribute_group	*attr_groups[2];
+
+	u64				(*get_count)(u64 config);
+};
+
+struct perf_ibs_data {
+	u32		size;
+	union {
+		u32	data[0];	/* data buffer starts here */
+		u32	caps;
+	};
+	u64		regs[MSR_AMD64_IBS_REG_COUNT_MAX];
+};
+
+static int
+perf_event_set_period(struct hw_perf_event *hwc, u64 min, u64 max, u64 *hw_period)
+{
+	s64 left = local64_read(&hwc->period_left);
+	s64 period = hwc->sample_period;
+	int overflow = 0;
+
+	/*
+	 * If we are way outside a reasonable range then just skip forward:
+	 */
+	if (unlikely(left <= -period)) {
+		left = period;
+		local64_set(&hwc->period_left, left);
+		hwc->last_period = period;
+		overflow = 1;
+	}
+
+	if (unlikely(left < (s64)min)) {
+		left += period;
+		local64_set(&hwc->period_left, left);
+		hwc->last_period = period;
+		overflow = 1;
+	}
+
+	/*
+	 * If the hw period that triggers the sw overflow is too short
+	 * we might hit the irq handler. This biases the results.
+	 * Thus we shorten the next-to-last period and set the last
+	 * period to the max period.
+	 */
+	if (left > max) {
+		left -= max;
+		if (left > max)
+			left = max;
+		else if (left < min)
+			left = min;
+	}
+
+	*hw_period = (u64)left;
+
+	return overflow;
+}
+
+static  int
+perf_event_try_update(struct perf_event *event, u64 new_raw_count, int width)
+{
+	struct hw_perf_event *hwc = &event->hw;
+	int shift = 64 - width;
+	u64 prev_raw_count;
+	u64 delta;
+
+	/*
+	 * Careful: an NMI might modify the previous event value.
+	 *
+	 * Our tactic to handle this is to first atomically read and
+	 * exchange a new raw count - then add that new-prev delta
+	 * count to the generic event atomically:
+	 */
+	prev_raw_count = local64_read(&hwc->prev_count);
+	if (local64_cmpxchg(&hwc->prev_count, prev_raw_count,
+					new_raw_count) != prev_raw_count)
+		return 0;
+
+	/*
+	 * Now we have the new raw value and have updated the prev
+	 * timestamp already. We can now calculate the elapsed delta
+	 * (event-)time and add that to the generic event.
+	 *
+	 * Careful, not all hw sign-extends above the physical width
+	 * of the count.
+	 */
+	delta = (new_raw_count << shift) - (prev_raw_count << shift);
+	delta >>= shift;
+
+	local64_add(delta, &event->count);
+	local64_sub(delta, &hwc->period_left);
+
+	return 1;
+}
+
+static struct perf_ibs perf_ibs_fetch;
+static struct perf_ibs perf_ibs_op;
+
+static struct perf_ibs *get_ibs_pmu(int type)
+{
+	if (perf_ibs_fetch.pmu.type == type)
+		return &perf_ibs_fetch;
+	if (perf_ibs_op.pmu.type == type)
+		return &perf_ibs_op;
+	return NULL;
+}
+
+/*
+ * Use IBS for precise event sampling:
+ *
+ *  perf record -a -e cpu-cycles:p ...    # use ibs op counting cycle count
+ *  perf record -a -e r076:p ...          # same as -e cpu-cycles:p
+ *  perf record -a -e r0C1:p ...          # use ibs op counting micro-ops
+ *
+ * IbsOpCntCtl (bit 19) of IBS Execution Control Register (IbsOpCtl,
+ * MSRC001_1033) is used to select either cycle or micro-ops counting
+ * mode.
+ *
+ * The rip of IBS samples has skid 0. Thus, IBS supports precise
+ * levels 1 and 2 and the PERF_EFLAGS_EXACT is set. In rare cases the
+ * rip is invalid when IBS was not able to record the rip correctly.
+ * We clear PERF_EFLAGS_EXACT and take the rip from pt_regs then.
+ *
+ */
+static int perf_ibs_precise_event(struct perf_event *event, u64 *config)
+{
+	switch (event->attr.precise_ip) {
+	case 0:
+		return -ENOENT;
+	case 1:
+	case 2:
+		break;
+	default:
+		return -EOPNOTSUPP;
+	}
+
+	switch (event->attr.type) {
+	case PERF_TYPE_HARDWARE:
+		switch (event->attr.config) {
+		case PERF_COUNT_HW_CPU_CYCLES:
+			*config = 0;
+			return 0;
+		}
+		break;
+	case PERF_TYPE_RAW:
+		switch (event->attr.config) {
+		case 0x0076:
+			*config = 0;
+			return 0;
+		case 0x00C1:
+			*config = IBS_OP_CNT_CTL;
+			return 0;
+		}
+		break;
+	default:
+		return -ENOENT;
+	}
+
+	return -EOPNOTSUPP;
+}
+
+static const struct perf_event_attr ibs_notsupp = {
+	.exclude_user	= 1,
+	.exclude_kernel	= 1,
+	.exclude_hv	= 1,
+	.exclude_idle	= 1,
+	.exclude_host	= 1,
+	.exclude_guest	= 1,
+};
+
+static int perf_ibs_init(struct perf_event *event)
+{
+	struct hw_perf_event *hwc = &event->hw;
+	struct perf_ibs *perf_ibs;
+	u64 max_cnt, config;
+	int ret;
+
+	perf_ibs = get_ibs_pmu(event->attr.type);
+	if (perf_ibs) {
+		config = event->attr.config;
+	} else {
+		perf_ibs = &perf_ibs_op;
+		ret = perf_ibs_precise_event(event, &config);
+		if (ret)
+			return ret;
+	}
+
+	if (event->pmu != &perf_ibs->pmu)
+		return -ENOENT;
+
+	if (perf_flags(&event->attr) & perf_flags(&ibs_notsupp))
+		return -EINVAL;
+
+	if (config & ~perf_ibs->config_mask)
+		return -EINVAL;
+
+	if (hwc->sample_period) {
+		if (config & perf_ibs->cnt_mask)
+			/* raw max_cnt may not be set */
+			return -EINVAL;
+		if (!event->attr.sample_freq && hwc->sample_period & 0x0f)
+			/*
+			 * lower 4 bits can not be set in ibs max cnt,
+			 * but allowing it in case we adjust the
+			 * sample period to set a frequency.
+			 */
+			return -EINVAL;
+		hwc->sample_period &= ~0x0FULL;
+		if (!hwc->sample_period)
+			hwc->sample_period = 0x10;
+	} else {
+		max_cnt = config & perf_ibs->cnt_mask;
+		config &= ~perf_ibs->cnt_mask;
+		event->attr.sample_period = max_cnt << 4;
+		hwc->sample_period = event->attr.sample_period;
+	}
+
+	if (!hwc->sample_period)
+		return -EINVAL;
+
+	/*
+	 * If we modify hwc->sample_period, we also need to update
+	 * hwc->last_period and hwc->period_left.
+	 */
+	hwc->last_period = hwc->sample_period;
+	local64_set(&hwc->period_left, hwc->sample_period);
+
+	hwc->config_base = perf_ibs->msr;
+	hwc->config = config;
+
+	return 0;
+}
+
+static int perf_ibs_set_period(struct perf_ibs *perf_ibs,
+			       struct hw_perf_event *hwc, u64 *period)
+{
+	int overflow;
+
+	/* ignore lower 4 bits in min count: */
+	overflow = perf_event_set_period(hwc, 1<<4, perf_ibs->max_period, period);
+	local64_set(&hwc->prev_count, 0);
+
+	return overflow;
+}
+
+static u64 get_ibs_fetch_count(u64 config)
+{
+	return (config & IBS_FETCH_CNT) >> 12;
+}
+
+static u64 get_ibs_op_count(u64 config)
+{
+	u64 count = 0;
+
+	if (config & IBS_OP_VAL)
+		count += (config & IBS_OP_MAX_CNT) << 4; /* cnt rolled over */
+
+	if (ibs_caps & IBS_CAPS_RDWROPCNT)
+		count += (config & IBS_OP_CUR_CNT) >> 32;
+
+	return count;
+}
+
+static void
+perf_ibs_event_update(struct perf_ibs *perf_ibs, struct perf_event *event,
+		      u64 *config)
+{
+	u64 count = perf_ibs->get_count(*config);
+
+	/*
+	 * Set width to 64 since we do not overflow on max width but
+	 * instead on max count. In perf_ibs_set_period() we clear
+	 * prev count manually on overflow.
+	 */
+	while (!perf_event_try_update(event, count, 64)) {
+		rdmsrl(event->hw.config_base, *config);
+		count = perf_ibs->get_count(*config);
+	}
+}
+
+static inline void perf_ibs_enable_event(struct perf_ibs *perf_ibs,
+					 struct hw_perf_event *hwc, u64 config)
+{
+	wrmsrl(hwc->config_base, hwc->config | config | perf_ibs->enable_mask);
+}
+
+/*
+ * Erratum #420 Instruction-Based Sampling Engine May Generate
+ * Interrupt that Cannot Be Cleared:
+ *
+ * Must clear counter mask first, then clear the enable bit. See
+ * Revision Guide for AMD Family 10h Processors, Publication #41322.
+ */
+static inline void perf_ibs_disable_event(struct perf_ibs *perf_ibs,
+					  struct hw_perf_event *hwc, u64 config)
+{
+	config &= ~perf_ibs->cnt_mask;
+	wrmsrl(hwc->config_base, config);
+	config &= ~perf_ibs->enable_mask;
+	wrmsrl(hwc->config_base, config);
+}
+
+/*
+ * We cannot restore the ibs pmu state, so we always needs to update
+ * the event while stopping it and then reset the state when starting
+ * again. Thus, ignoring PERF_EF_RELOAD and PERF_EF_UPDATE flags in
+ * perf_ibs_start()/perf_ibs_stop() and instead always do it.
+ */
+static void perf_ibs_start(struct perf_event *event, int flags)
+{
+	struct hw_perf_event *hwc = &event->hw;
+	struct perf_ibs *perf_ibs = container_of(event->pmu, struct perf_ibs, pmu);
+	struct cpu_perf_ibs *pcpu = this_cpu_ptr(perf_ibs->pcpu);
+	u64 period;
+
+	if (WARN_ON_ONCE(!(hwc->state & PERF_HES_STOPPED)))
+		return;
+
+	WARN_ON_ONCE(!(hwc->state & PERF_HES_UPTODATE));
+	hwc->state = 0;
+
+	perf_ibs_set_period(perf_ibs, hwc, &period);
+	set_bit(IBS_STARTED, pcpu->state);
+	perf_ibs_enable_event(perf_ibs, hwc, period >> 4);
+
+	perf_event_update_userpage(event);
+}
+
+static void perf_ibs_stop(struct perf_event *event, int flags)
+{
+	struct hw_perf_event *hwc = &event->hw;
+	struct perf_ibs *perf_ibs = container_of(event->pmu, struct perf_ibs, pmu);
+	struct cpu_perf_ibs *pcpu = this_cpu_ptr(perf_ibs->pcpu);
+	u64 config;
+	int stopping;
+
+	stopping = test_and_clear_bit(IBS_STARTED, pcpu->state);
+
+	if (!stopping && (hwc->state & PERF_HES_UPTODATE))
+		return;
+
+	rdmsrl(hwc->config_base, config);
+
+	if (stopping) {
+		set_bit(IBS_STOPPING, pcpu->state);
+		perf_ibs_disable_event(perf_ibs, hwc, config);
+		WARN_ON_ONCE(hwc->state & PERF_HES_STOPPED);
+		hwc->state |= PERF_HES_STOPPED;
+	}
+
+	if (hwc->state & PERF_HES_UPTODATE)
+		return;
+
+	/*
+	 * Clear valid bit to not count rollovers on update, rollovers
+	 * are only updated in the irq handler.
+	 */
+	config &= ~perf_ibs->valid_mask;
+
+	perf_ibs_event_update(perf_ibs, event, &config);
+	hwc->state |= PERF_HES_UPTODATE;
+}
+
+static int perf_ibs_add(struct perf_event *event, int flags)
+{
+	struct perf_ibs *perf_ibs = container_of(event->pmu, struct perf_ibs, pmu);
+	struct cpu_perf_ibs *pcpu = this_cpu_ptr(perf_ibs->pcpu);
+
+	if (test_and_set_bit(IBS_ENABLED, pcpu->state))
+		return -ENOSPC;
+
+	event->hw.state = PERF_HES_UPTODATE | PERF_HES_STOPPED;
+
+	pcpu->event = event;
+
+	if (flags & PERF_EF_START)
+		perf_ibs_start(event, PERF_EF_RELOAD);
+
+	return 0;
+}
+
+static void perf_ibs_del(struct perf_event *event, int flags)
+{
+	struct perf_ibs *perf_ibs = container_of(event->pmu, struct perf_ibs, pmu);
+	struct cpu_perf_ibs *pcpu = this_cpu_ptr(perf_ibs->pcpu);
+
+	if (!test_and_clear_bit(IBS_ENABLED, pcpu->state))
+		return;
+
+	perf_ibs_stop(event, PERF_EF_UPDATE);
+
+	pcpu->event = NULL;
+
+	perf_event_update_userpage(event);
+}
+
+static void perf_ibs_read(struct perf_event *event) { }
+
+PMU_FORMAT_ATTR(rand_en,	"config:57");
+PMU_FORMAT_ATTR(cnt_ctl,	"config:19");
+
+static struct attribute *ibs_fetch_format_attrs[] = {
+	&format_attr_rand_en.attr,
+	NULL,
+};
+
+static struct attribute *ibs_op_format_attrs[] = {
+	NULL,	/* &format_attr_cnt_ctl.attr if IBS_CAPS_OPCNT */
+	NULL,
+};
+
+static struct perf_ibs perf_ibs_fetch = {
+	.pmu = {
+		.task_ctx_nr	= perf_invalid_context,
+
+		.event_init	= perf_ibs_init,
+		.add		= perf_ibs_add,
+		.del		= perf_ibs_del,
+		.start		= perf_ibs_start,
+		.stop		= perf_ibs_stop,
+		.read		= perf_ibs_read,
+	},
+	.msr			= MSR_AMD64_IBSFETCHCTL,
+	.config_mask		= IBS_FETCH_CONFIG_MASK,
+	.cnt_mask		= IBS_FETCH_MAX_CNT,
+	.enable_mask		= IBS_FETCH_ENABLE,
+	.valid_mask		= IBS_FETCH_VAL,
+	.max_period		= IBS_FETCH_MAX_CNT << 4,
+	.offset_mask		= { MSR_AMD64_IBSFETCH_REG_MASK },
+	.offset_max		= MSR_AMD64_IBSFETCH_REG_COUNT,
+	.format_attrs		= ibs_fetch_format_attrs,
+
+	.get_count		= get_ibs_fetch_count,
+};
+
+static struct perf_ibs perf_ibs_op = {
+	.pmu = {
+		.task_ctx_nr	= perf_invalid_context,
+
+		.event_init	= perf_ibs_init,
+		.add		= perf_ibs_add,
+		.del		= perf_ibs_del,
+		.start		= perf_ibs_start,
+		.stop		= perf_ibs_stop,
+		.read		= perf_ibs_read,
+	},
+	.msr			= MSR_AMD64_IBSOPCTL,
+	.config_mask		= IBS_OP_CONFIG_MASK,
+	.cnt_mask		= IBS_OP_MAX_CNT,
+	.enable_mask		= IBS_OP_ENABLE,
+	.valid_mask		= IBS_OP_VAL,
+	.max_period		= IBS_OP_MAX_CNT << 4,
+	.offset_mask		= { MSR_AMD64_IBSOP_REG_MASK },
+	.offset_max		= MSR_AMD64_IBSOP_REG_COUNT,
+	.format_attrs		= ibs_op_format_attrs,
+
+	.get_count		= get_ibs_op_count,
+};
+
+static int perf_ibs_handle_irq(struct perf_ibs *perf_ibs, struct pt_regs *iregs)
+{
+	struct cpu_perf_ibs *pcpu = this_cpu_ptr(perf_ibs->pcpu);
+	struct perf_event *event = pcpu->event;
+	struct hw_perf_event *hwc = &event->hw;
+	struct perf_sample_data data;
+	struct perf_raw_record raw;
+	struct pt_regs regs;
+	struct perf_ibs_data ibs_data;
+	int offset, size, check_rip, offset_max, throttle = 0;
+	unsigned int msr;
+	u64 *buf, *config, period;
+
+	if (!test_bit(IBS_STARTED, pcpu->state)) {
+		/*
+		 * Catch spurious interrupts after stopping IBS: After
+		 * disabling IBS there could be still incoming NMIs
+		 * with samples that even have the valid bit cleared.
+		 * Mark all this NMIs as handled.
+		 */
+		return test_and_clear_bit(IBS_STOPPING, pcpu->state) ? 1 : 0;
+	}
+
+	msr = hwc->config_base;
+	buf = ibs_data.regs;
+	rdmsrl(msr, *buf);
+	if (!(*buf++ & perf_ibs->valid_mask))
+		return 0;
+
+	config = &ibs_data.regs[0];
+	perf_ibs_event_update(perf_ibs, event, config);
+	perf_sample_data_init(&data, 0, hwc->last_period);
+	if (!perf_ibs_set_period(perf_ibs, hwc, &period))
+		goto out;	/* no sw counter overflow */
+
+	ibs_data.caps = ibs_caps;
+	size = 1;
+	offset = 1;
+	check_rip = (perf_ibs == &perf_ibs_op && (ibs_caps & IBS_CAPS_RIPINVALIDCHK));
+	if (event->attr.sample_type & PERF_SAMPLE_RAW)
+		offset_max = perf_ibs->offset_max;
+	else if (check_rip)
+		offset_max = 2;
+	else
+		offset_max = 1;
+	do {
+		rdmsrl(msr + offset, *buf++);
+		size++;
+		offset = find_next_bit(perf_ibs->offset_mask,
+				       perf_ibs->offset_max,
+				       offset + 1);
+	} while (offset < offset_max);
+	if (event->attr.sample_type & PERF_SAMPLE_RAW) {
+		/*
+		 * Read IbsBrTarget and IbsOpData4 separately
+		 * depending on their availability.
+		 * Can't add to offset_max as they are staggered
+		 */
+		if (ibs_caps & IBS_CAPS_BRNTRGT) {
+			rdmsrl(MSR_AMD64_IBSBRTARGET, *buf++);
+			size++;
+		}
+		if (ibs_caps & IBS_CAPS_OPDATA4) {
+			rdmsrl(MSR_AMD64_IBSOPDATA4, *buf++);
+			size++;
+		}
+	}
+	ibs_data.size = sizeof(u64) * size;
+
+	regs = *iregs;
+	if (check_rip && (ibs_data.regs[2] & IBS_RIP_INVALID)) {
+		regs.flags &= ~PERF_EFLAGS_EXACT;
+	} else {
+		set_linear_ip(&regs, ibs_data.regs[1]);
+		regs.flags |= PERF_EFLAGS_EXACT;
+	}
+
+	if (event->attr.sample_type & PERF_SAMPLE_RAW) {
+		raw.size = sizeof(u32) + ibs_data.size;
+		raw.data = ibs_data.data;
+		data.raw = &raw;
+	}
+
+	throttle = perf_event_overflow(event, &data, &regs);
+out:
+	if (throttle)
+		perf_ibs_disable_event(perf_ibs, hwc, *config);
+	else
+		perf_ibs_enable_event(perf_ibs, hwc, period >> 4);
+
+	perf_event_update_userpage(event);
+
+	return 1;
+}
+
+static int
+perf_ibs_nmi_handler(unsigned int cmd, struct pt_regs *regs)
+{
+	int handled = 0;
+
+	handled += perf_ibs_handle_irq(&perf_ibs_fetch, regs);
+	handled += perf_ibs_handle_irq(&perf_ibs_op, regs);
+
+	if (handled)
+		inc_irq_stat(apic_perf_irqs);
+
+	return handled;
+}
+NOKPROBE_SYMBOL(perf_ibs_nmi_handler);
+
+static __init int perf_ibs_pmu_init(struct perf_ibs *perf_ibs, char *name)
+{
+	struct cpu_perf_ibs __percpu *pcpu;
+	int ret;
+
+	pcpu = alloc_percpu(struct cpu_perf_ibs);
+	if (!pcpu)
+		return -ENOMEM;
+
+	perf_ibs->pcpu = pcpu;
+
+	/* register attributes */
+	if (perf_ibs->format_attrs[0]) {
+		memset(&perf_ibs->format_group, 0, sizeof(perf_ibs->format_group));
+		perf_ibs->format_group.name	= "format";
+		perf_ibs->format_group.attrs	= perf_ibs->format_attrs;
+
+		memset(&perf_ibs->attr_groups, 0, sizeof(perf_ibs->attr_groups));
+		perf_ibs->attr_groups[0]	= &perf_ibs->format_group;
+		perf_ibs->pmu.attr_groups	= perf_ibs->attr_groups;
+	}
+
+	ret = perf_pmu_register(&perf_ibs->pmu, name, -1);
+	if (ret) {
+		perf_ibs->pcpu = NULL;
+		free_percpu(pcpu);
+	}
+
+	return ret;
+}
+
+static __init int perf_event_ibs_init(void)
+{
+	struct attribute **attr = ibs_op_format_attrs;
+
+	if (!ibs_caps)
+		return -ENODEV;	/* ibs not supported by the cpu */
+
+	perf_ibs_pmu_init(&perf_ibs_fetch, "ibs_fetch");
+
+	if (ibs_caps & IBS_CAPS_OPCNT) {
+		perf_ibs_op.config_mask |= IBS_OP_CNT_CTL;
+		*attr++ = &format_attr_cnt_ctl.attr;
+	}
+	perf_ibs_pmu_init(&perf_ibs_op, "ibs_op");
+
+	register_nmi_handler(NMI_LOCAL, perf_ibs_nmi_handler, 0, "perf_ibs");
+	printk(KERN_INFO "perf: AMD IBS detected (0x%08x)\n", ibs_caps);
+
+	return 0;
+}
+
+#else /* defined(CONFIG_PERF_EVENTS) && defined(CONFIG_CPU_SUP_AMD) */
+
+static __init int perf_event_ibs_init(void) { return 0; }
+
+#endif
+
+/* IBS - apic initialization, for perf and oprofile */
+
+static __init u32 __get_ibs_caps(void)
+{
+	u32 caps;
+	unsigned int max_level;
+
+	if (!boot_cpu_has(X86_FEATURE_IBS))
+		return 0;
+
+	/* check IBS cpuid feature flags */
+	max_level = cpuid_eax(0x80000000);
+	if (max_level < IBS_CPUID_FEATURES)
+		return IBS_CAPS_DEFAULT;
+
+	caps = cpuid_eax(IBS_CPUID_FEATURES);
+	if (!(caps & IBS_CAPS_AVAIL))
+		/* cpuid flags not valid */
+		return IBS_CAPS_DEFAULT;
+
+	return caps;
+}
+
+u32 get_ibs_caps(void)
+{
+	return ibs_caps;
+}
+
+EXPORT_SYMBOL(get_ibs_caps);
+
+static inline int get_eilvt(int offset)
+{
+	return !setup_APIC_eilvt(offset, 0, APIC_EILVT_MSG_NMI, 1);
+}
+
+static inline int put_eilvt(int offset)
+{
+	return !setup_APIC_eilvt(offset, 0, 0, 1);
+}
+
+/*
+ * Check and reserve APIC extended interrupt LVT offset for IBS if available.
+ */
+static inline int ibs_eilvt_valid(void)
+{
+	int offset;
+	u64 val;
+	int valid = 0;
+
+	preempt_disable();
+
+	rdmsrl(MSR_AMD64_IBSCTL, val);
+	offset = val & IBSCTL_LVT_OFFSET_MASK;
+
+	if (!(val & IBSCTL_LVT_OFFSET_VALID)) {
+		pr_err(FW_BUG "cpu %d, invalid IBS interrupt offset %d (MSR%08X=0x%016llx)\n",
+		       smp_processor_id(), offset, MSR_AMD64_IBSCTL, val);
+		goto out;
+	}
+
+	if (!get_eilvt(offset)) {
+		pr_err(FW_BUG "cpu %d, IBS interrupt offset %d not available (MSR%08X=0x%016llx)\n",
+		       smp_processor_id(), offset, MSR_AMD64_IBSCTL, val);
+		goto out;
+	}
+
+	valid = 1;
+out:
+	preempt_enable();
+
+	return valid;
+}
+
+static int setup_ibs_ctl(int ibs_eilvt_off)
+{
+	struct pci_dev *cpu_cfg;
+	int nodes;
+	u32 value = 0;
+
+	nodes = 0;
+	cpu_cfg = NULL;
+	do {
+		cpu_cfg = pci_get_device(PCI_VENDOR_ID_AMD,
+					 PCI_DEVICE_ID_AMD_10H_NB_MISC,
+					 cpu_cfg);
+		if (!cpu_cfg)
+			break;
+		++nodes;
+		pci_write_config_dword(cpu_cfg, IBSCTL, ibs_eilvt_off
+				       | IBSCTL_LVT_OFFSET_VALID);
+		pci_read_config_dword(cpu_cfg, IBSCTL, &value);
+		if (value != (ibs_eilvt_off | IBSCTL_LVT_OFFSET_VALID)) {
+			pci_dev_put(cpu_cfg);
+			printk(KERN_DEBUG "Failed to setup IBS LVT offset, "
+			       "IBSCTL = 0x%08x\n", value);
+			return -EINVAL;
+		}
+	} while (1);
+
+	if (!nodes) {
+		printk(KERN_DEBUG "No CPU node configured for IBS\n");
+		return -ENODEV;
+	}
+
+	return 0;
+}
+
+/*
+ * This runs only on the current cpu. We try to find an LVT offset and
+ * setup the local APIC. For this we must disable preemption. On
+ * success we initialize all nodes with this offset. This updates then
+ * the offset in the IBS_CTL per-node msr. The per-core APIC setup of
+ * the IBS interrupt vector is handled by perf_ibs_cpu_notifier that
+ * is using the new offset.
+ */
+static void force_ibs_eilvt_setup(void)
+{
+	int offset;
+	int ret;
+
+	preempt_disable();
+	/* find the next free available EILVT entry, skip offset 0 */
+	for (offset = 1; offset < APIC_EILVT_NR_MAX; offset++) {
+		if (get_eilvt(offset))
+			break;
+	}
+	preempt_enable();
+
+	if (offset == APIC_EILVT_NR_MAX) {
+		printk(KERN_DEBUG "No EILVT entry available\n");
+		return;
+	}
+
+	ret = setup_ibs_ctl(offset);
+	if (ret)
+		goto out;
+
+	if (!ibs_eilvt_valid())
+		goto out;
+
+	pr_info("IBS: LVT offset %d assigned\n", offset);
+
+	return;
+out:
+	preempt_disable();
+	put_eilvt(offset);
+	preempt_enable();
+	return;
+}
+
+static void ibs_eilvt_setup(void)
+{
+	/*
+	 * Force LVT offset assignment for family 10h: The offsets are
+	 * not assigned by the BIOS for this family, so the OS is
+	 * responsible for doing it. If the OS assignment fails, fall
+	 * back to BIOS settings and try to setup this.
+	 */
+	if (boot_cpu_data.x86 == 0x10)
+		force_ibs_eilvt_setup();
+}
+
+static inline int get_ibs_lvt_offset(void)
+{
+	u64 val;
+
+	rdmsrl(MSR_AMD64_IBSCTL, val);
+	if (!(val & IBSCTL_LVT_OFFSET_VALID))
+		return -EINVAL;
+
+	return val & IBSCTL_LVT_OFFSET_MASK;
+}
+
+static void setup_APIC_ibs(void *dummy)
+{
+	int offset;
+
+	offset = get_ibs_lvt_offset();
+	if (offset < 0)
+		goto failed;
+
+	if (!setup_APIC_eilvt(offset, 0, APIC_EILVT_MSG_NMI, 0))
+		return;
+failed:
+	pr_warn("perf: IBS APIC setup failed on cpu #%d\n",
+		smp_processor_id());
+}
+
+static void clear_APIC_ibs(void *dummy)
+{
+	int offset;
+
+	offset = get_ibs_lvt_offset();
+	if (offset >= 0)
+		setup_APIC_eilvt(offset, 0, APIC_EILVT_MSG_FIX, 1);
+}
+
+#ifdef CONFIG_PM
+
+static int perf_ibs_suspend(void)
+{
+	clear_APIC_ibs(NULL);
+	return 0;
+}
+
+static void perf_ibs_resume(void)
+{
+	ibs_eilvt_setup();
+	setup_APIC_ibs(NULL);
+}
+
+static struct syscore_ops perf_ibs_syscore_ops = {
+	.resume		= perf_ibs_resume,
+	.suspend	= perf_ibs_suspend,
+};
+
+static void perf_ibs_pm_init(void)
+{
+	register_syscore_ops(&perf_ibs_syscore_ops);
+}
+
+#else
+
+static inline void perf_ibs_pm_init(void) { }
+
+#endif
+
+static int
+perf_ibs_cpu_notifier(struct notifier_block *self, unsigned long action, void *hcpu)
+{
+	switch (action & ~CPU_TASKS_FROZEN) {
+	case CPU_STARTING:
+		setup_APIC_ibs(NULL);
+		break;
+	case CPU_DYING:
+		clear_APIC_ibs(NULL);
+		break;
+	default:
+		break;
+	}
+
+	return NOTIFY_OK;
+}
+
+static __init int amd_ibs_init(void)
+{
+	u32 caps;
+	int ret = -EINVAL;
+
+	caps = __get_ibs_caps();
+	if (!caps)
+		return -ENODEV;	/* ibs not supported by the cpu */
+
+	ibs_eilvt_setup();
+
+	if (!ibs_eilvt_valid())
+		goto out;
+
+	perf_ibs_pm_init();
+	cpu_notifier_register_begin();
+	ibs_caps = caps;
+	/* make ibs_caps visible to other cpus: */
+	smp_mb();
+	smp_call_function(setup_APIC_ibs, NULL, 1);
+	__perf_cpu_notifier(perf_ibs_cpu_notifier);
+	cpu_notifier_register_done();
+
+	ret = perf_event_ibs_init();
+out:
+	if (ret)
+		pr_err("Failed to setup IBS, %d\n", ret);
+	return ret;
+}
+
+/* Since we need the pci subsystem to init ibs we can't do this earlier: */
+device_initcall(amd_ibs_init);
--- /dev/null
+++ zfcpdump-kernel-4.4/arch/x86/events/amd/iommu.c
@@ -0,0 +1,499 @@
+/*
+ * Copyright (C) 2013 Advanced Micro Devices, Inc.
+ *
+ * Author: Steven Kinney <Steven.Kinney@amd.com>
+ * Author: Suravee Suthikulpanit <Suraveee.Suthikulpanit@amd.com>
+ *
+ * Perf: amd_iommu - AMD IOMMU Performance Counter PMU implementation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/perf_event.h>
+#include <linux/module.h>
+#include <linux/cpumask.h>
+#include <linux/slab.h>
+
+#include "../perf_event.h"
+#include "iommu.h"
+
+#define COUNTER_SHIFT		16
+
+#define _GET_BANK(ev)       ((u8)(ev->hw.extra_reg.reg >> 8))
+#define _GET_CNTR(ev)       ((u8)(ev->hw.extra_reg.reg))
+
+/* iommu pmu config masks */
+#define _GET_CSOURCE(ev)    ((ev->hw.config & 0xFFULL))
+#define _GET_DEVID(ev)      ((ev->hw.config >> 8)  & 0xFFFFULL)
+#define _GET_PASID(ev)      ((ev->hw.config >> 24) & 0xFFFFULL)
+#define _GET_DOMID(ev)      ((ev->hw.config >> 40) & 0xFFFFULL)
+#define _GET_DEVID_MASK(ev) ((ev->hw.extra_reg.config)  & 0xFFFFULL)
+#define _GET_PASID_MASK(ev) ((ev->hw.extra_reg.config >> 16) & 0xFFFFULL)
+#define _GET_DOMID_MASK(ev) ((ev->hw.extra_reg.config >> 32) & 0xFFFFULL)
+
+static struct perf_amd_iommu __perf_iommu;
+
+struct perf_amd_iommu {
+	struct pmu pmu;
+	u8 max_banks;
+	u8 max_counters;
+	u64 cntr_assign_mask;
+	raw_spinlock_t lock;
+	const struct attribute_group *attr_groups[4];
+};
+
+#define format_group	attr_groups[0]
+#define cpumask_group	attr_groups[1]
+#define events_group	attr_groups[2]
+#define null_group	attr_groups[3]
+
+/*---------------------------------------------
+ * sysfs format attributes
+ *---------------------------------------------*/
+PMU_FORMAT_ATTR(csource,    "config:0-7");
+PMU_FORMAT_ATTR(devid,      "config:8-23");
+PMU_FORMAT_ATTR(pasid,      "config:24-39");
+PMU_FORMAT_ATTR(domid,      "config:40-55");
+PMU_FORMAT_ATTR(devid_mask, "config1:0-15");
+PMU_FORMAT_ATTR(pasid_mask, "config1:16-31");
+PMU_FORMAT_ATTR(domid_mask, "config1:32-47");
+
+static struct attribute *iommu_format_attrs[] = {
+	&format_attr_csource.attr,
+	&format_attr_devid.attr,
+	&format_attr_pasid.attr,
+	&format_attr_domid.attr,
+	&format_attr_devid_mask.attr,
+	&format_attr_pasid_mask.attr,
+	&format_attr_domid_mask.attr,
+	NULL,
+};
+
+static struct attribute_group amd_iommu_format_group = {
+	.name = "format",
+	.attrs = iommu_format_attrs,
+};
+
+/*---------------------------------------------
+ * sysfs events attributes
+ *---------------------------------------------*/
+struct amd_iommu_event_desc {
+	struct kobj_attribute attr;
+	const char *event;
+};
+
+static ssize_t _iommu_event_show(struct kobject *kobj,
+				struct kobj_attribute *attr, char *buf)
+{
+	struct amd_iommu_event_desc *event =
+		container_of(attr, struct amd_iommu_event_desc, attr);
+	return sprintf(buf, "%s\n", event->event);
+}
+
+#define AMD_IOMMU_EVENT_DESC(_name, _event)			\
+{								\
+	.attr  = __ATTR(_name, 0444, _iommu_event_show, NULL),	\
+	.event = _event,					\
+}
+
+static struct amd_iommu_event_desc amd_iommu_v2_event_descs[] = {
+	AMD_IOMMU_EVENT_DESC(mem_pass_untrans,        "csource=0x01"),
+	AMD_IOMMU_EVENT_DESC(mem_pass_pretrans,       "csource=0x02"),
+	AMD_IOMMU_EVENT_DESC(mem_pass_excl,           "csource=0x03"),
+	AMD_IOMMU_EVENT_DESC(mem_target_abort,        "csource=0x04"),
+	AMD_IOMMU_EVENT_DESC(mem_trans_total,         "csource=0x05"),
+	AMD_IOMMU_EVENT_DESC(mem_iommu_tlb_pte_hit,   "csource=0x06"),
+	AMD_IOMMU_EVENT_DESC(mem_iommu_tlb_pte_mis,   "csource=0x07"),
+	AMD_IOMMU_EVENT_DESC(mem_iommu_tlb_pde_hit,   "csource=0x08"),
+	AMD_IOMMU_EVENT_DESC(mem_iommu_tlb_pde_mis,   "csource=0x09"),
+	AMD_IOMMU_EVENT_DESC(mem_dte_hit,             "csource=0x0a"),
+	AMD_IOMMU_EVENT_DESC(mem_dte_mis,             "csource=0x0b"),
+	AMD_IOMMU_EVENT_DESC(page_tbl_read_tot,       "csource=0x0c"),
+	AMD_IOMMU_EVENT_DESC(page_tbl_read_nst,       "csource=0x0d"),
+	AMD_IOMMU_EVENT_DESC(page_tbl_read_gst,       "csource=0x0e"),
+	AMD_IOMMU_EVENT_DESC(int_dte_hit,             "csource=0x0f"),
+	AMD_IOMMU_EVENT_DESC(int_dte_mis,             "csource=0x10"),
+	AMD_IOMMU_EVENT_DESC(cmd_processed,           "csource=0x11"),
+	AMD_IOMMU_EVENT_DESC(cmd_processed_inv,       "csource=0x12"),
+	AMD_IOMMU_EVENT_DESC(tlb_inv,                 "csource=0x13"),
+	{ /* end: all zeroes */ },
+};
+
+/*---------------------------------------------
+ * sysfs cpumask attributes
+ *---------------------------------------------*/
+static cpumask_t iommu_cpumask;
+
+static ssize_t _iommu_cpumask_show(struct device *dev,
+				   struct device_attribute *attr,
+				   char *buf)
+{
+	return cpumap_print_to_pagebuf(true, buf, &iommu_cpumask);
+}
+static DEVICE_ATTR(cpumask, S_IRUGO, _iommu_cpumask_show, NULL);
+
+static struct attribute *iommu_cpumask_attrs[] = {
+	&dev_attr_cpumask.attr,
+	NULL,
+};
+
+static struct attribute_group amd_iommu_cpumask_group = {
+	.attrs = iommu_cpumask_attrs,
+};
+
+/*---------------------------------------------*/
+
+static int get_next_avail_iommu_bnk_cntr(struct perf_amd_iommu *perf_iommu)
+{
+	unsigned long flags;
+	int shift, bank, cntr, retval;
+	int max_banks = perf_iommu->max_banks;
+	int max_cntrs = perf_iommu->max_counters;
+
+	raw_spin_lock_irqsave(&perf_iommu->lock, flags);
+
+	for (bank = 0, shift = 0; bank < max_banks; bank++) {
+		for (cntr = 0; cntr < max_cntrs; cntr++) {
+			shift = bank + (bank*3) + cntr;
+			if (perf_iommu->cntr_assign_mask & (1ULL<<shift)) {
+				continue;
+			} else {
+				perf_iommu->cntr_assign_mask |= (1ULL<<shift);
+				retval = ((u16)((u16)bank<<8) | (u8)(cntr));
+				goto out;
+			}
+		}
+	}
+	retval = -ENOSPC;
+out:
+	raw_spin_unlock_irqrestore(&perf_iommu->lock, flags);
+	return retval;
+}
+
+static int clear_avail_iommu_bnk_cntr(struct perf_amd_iommu *perf_iommu,
+					u8 bank, u8 cntr)
+{
+	unsigned long flags;
+	int max_banks, max_cntrs;
+	int shift = 0;
+
+	max_banks = perf_iommu->max_banks;
+	max_cntrs = perf_iommu->max_counters;
+
+	if ((bank > max_banks) || (cntr > max_cntrs))
+		return -EINVAL;
+
+	shift = bank + cntr + (bank*3);
+
+	raw_spin_lock_irqsave(&perf_iommu->lock, flags);
+	perf_iommu->cntr_assign_mask &= ~(1ULL<<shift);
+	raw_spin_unlock_irqrestore(&perf_iommu->lock, flags);
+
+	return 0;
+}
+
+static int perf_iommu_event_init(struct perf_event *event)
+{
+	struct hw_perf_event *hwc = &event->hw;
+	struct perf_amd_iommu *perf_iommu;
+	u64 config, config1;
+
+	/* test the event attr type check for PMU enumeration */
+	if (event->attr.type != event->pmu->type)
+		return -ENOENT;
+
+	/*
+	 * IOMMU counters are shared across all cores.
+	 * Therefore, it does not support per-process mode.
+	 * Also, it does not support event sampling mode.
+	 */
+	if (is_sampling_event(event) || event->attach_state & PERF_ATTACH_TASK)
+		return -EINVAL;
+
+	/* IOMMU counters do not have usr/os/guest/host bits */
+	if (event->attr.exclude_user || event->attr.exclude_kernel ||
+	    event->attr.exclude_host || event->attr.exclude_guest)
+		return -EINVAL;
+
+	if (event->cpu < 0)
+		return -EINVAL;
+
+	perf_iommu = &__perf_iommu;
+
+	if (event->pmu != &perf_iommu->pmu)
+		return -ENOENT;
+
+	if (perf_iommu) {
+		config = event->attr.config;
+		config1 = event->attr.config1;
+	} else {
+		return -EINVAL;
+	}
+
+	/* integrate with iommu base devid (0000), assume one iommu */
+	perf_iommu->max_banks =
+		amd_iommu_pc_get_max_banks(IOMMU_BASE_DEVID);
+	perf_iommu->max_counters =
+		amd_iommu_pc_get_max_counters(IOMMU_BASE_DEVID);
+	if ((perf_iommu->max_banks == 0) || (perf_iommu->max_counters == 0))
+		return -EINVAL;
+
+	/* update the hw_perf_event struct with the iommu config data */
+	hwc->config = config;
+	hwc->extra_reg.config = config1;
+
+	return 0;
+}
+
+static void perf_iommu_enable_event(struct perf_event *ev)
+{
+	u8 csource = _GET_CSOURCE(ev);
+	u16 devid = _GET_DEVID(ev);
+	u64 reg = 0ULL;
+
+	reg = csource;
+	amd_iommu_pc_get_set_reg_val(devid,
+			_GET_BANK(ev), _GET_CNTR(ev) ,
+			 IOMMU_PC_COUNTER_SRC_REG, &reg, true);
+
+	reg = 0ULL | devid | (_GET_DEVID_MASK(ev) << 32);
+	if (reg)
+		reg |= (1UL << 31);
+	amd_iommu_pc_get_set_reg_val(devid,
+			_GET_BANK(ev), _GET_CNTR(ev) ,
+			 IOMMU_PC_DEVID_MATCH_REG, &reg, true);
+
+	reg = 0ULL | _GET_PASID(ev) | (_GET_PASID_MASK(ev) << 32);
+	if (reg)
+		reg |= (1UL << 31);
+	amd_iommu_pc_get_set_reg_val(devid,
+			_GET_BANK(ev), _GET_CNTR(ev) ,
+			 IOMMU_PC_PASID_MATCH_REG, &reg, true);
+
+	reg = 0ULL | _GET_DOMID(ev) | (_GET_DOMID_MASK(ev) << 32);
+	if (reg)
+		reg |= (1UL << 31);
+	amd_iommu_pc_get_set_reg_val(devid,
+			_GET_BANK(ev), _GET_CNTR(ev) ,
+			 IOMMU_PC_DOMID_MATCH_REG, &reg, true);
+}
+
+static void perf_iommu_disable_event(struct perf_event *event)
+{
+	u64 reg = 0ULL;
+
+	amd_iommu_pc_get_set_reg_val(_GET_DEVID(event),
+			_GET_BANK(event), _GET_CNTR(event),
+			IOMMU_PC_COUNTER_SRC_REG, &reg, true);
+}
+
+static void perf_iommu_start(struct perf_event *event, int flags)
+{
+	struct hw_perf_event *hwc = &event->hw;
+
+	pr_debug("perf: amd_iommu:perf_iommu_start\n");
+	if (WARN_ON_ONCE(!(hwc->state & PERF_HES_STOPPED)))
+		return;
+
+	WARN_ON_ONCE(!(hwc->state & PERF_HES_UPTODATE));
+	hwc->state = 0;
+
+	if (flags & PERF_EF_RELOAD) {
+		u64 prev_raw_count =  local64_read(&hwc->prev_count);
+		amd_iommu_pc_get_set_reg_val(_GET_DEVID(event),
+				_GET_BANK(event), _GET_CNTR(event),
+				IOMMU_PC_COUNTER_REG, &prev_raw_count, true);
+	}
+
+	perf_iommu_enable_event(event);
+	perf_event_update_userpage(event);
+
+}
+
+static void perf_iommu_read(struct perf_event *event)
+{
+	u64 count = 0ULL;
+	u64 prev_raw_count = 0ULL;
+	u64 delta = 0ULL;
+	struct hw_perf_event *hwc = &event->hw;
+	pr_debug("perf: amd_iommu:perf_iommu_read\n");
+
+	amd_iommu_pc_get_set_reg_val(_GET_DEVID(event),
+				_GET_BANK(event), _GET_CNTR(event),
+				IOMMU_PC_COUNTER_REG, &count, false);
+
+	/* IOMMU pc counter register is only 48 bits */
+	count &= 0xFFFFFFFFFFFFULL;
+
+	prev_raw_count =  local64_read(&hwc->prev_count);
+	if (local64_cmpxchg(&hwc->prev_count, prev_raw_count,
+					count) != prev_raw_count)
+		return;
+
+	/* Handling 48-bit counter overflowing */
+	delta = (count << COUNTER_SHIFT) - (prev_raw_count << COUNTER_SHIFT);
+	delta >>= COUNTER_SHIFT;
+	local64_add(delta, &event->count);
+
+}
+
+static void perf_iommu_stop(struct perf_event *event, int flags)
+{
+	struct hw_perf_event *hwc = &event->hw;
+	u64 config;
+
+	pr_debug("perf: amd_iommu:perf_iommu_stop\n");
+
+	if (hwc->state & PERF_HES_UPTODATE)
+		return;
+
+	perf_iommu_disable_event(event);
+	WARN_ON_ONCE(hwc->state & PERF_HES_STOPPED);
+	hwc->state |= PERF_HES_STOPPED;
+
+	if (hwc->state & PERF_HES_UPTODATE)
+		return;
+
+	config = hwc->config;
+	perf_iommu_read(event);
+	hwc->state |= PERF_HES_UPTODATE;
+}
+
+static int perf_iommu_add(struct perf_event *event, int flags)
+{
+	int retval;
+	struct perf_amd_iommu *perf_iommu =
+			container_of(event->pmu, struct perf_amd_iommu, pmu);
+
+	pr_debug("perf: amd_iommu:perf_iommu_add\n");
+	event->hw.state = PERF_HES_UPTODATE | PERF_HES_STOPPED;
+
+	/* request an iommu bank/counter */
+	retval = get_next_avail_iommu_bnk_cntr(perf_iommu);
+	if (retval != -ENOSPC)
+		event->hw.extra_reg.reg = (u16)retval;
+	else
+		return retval;
+
+	if (flags & PERF_EF_START)
+		perf_iommu_start(event, PERF_EF_RELOAD);
+
+	return 0;
+}
+
+static void perf_iommu_del(struct perf_event *event, int flags)
+{
+	struct perf_amd_iommu *perf_iommu =
+			container_of(event->pmu, struct perf_amd_iommu, pmu);
+
+	pr_debug("perf: amd_iommu:perf_iommu_del\n");
+	perf_iommu_stop(event, PERF_EF_UPDATE);
+
+	/* clear the assigned iommu bank/counter */
+	clear_avail_iommu_bnk_cntr(perf_iommu,
+				     _GET_BANK(event),
+				     _GET_CNTR(event));
+
+	perf_event_update_userpage(event);
+}
+
+static __init int _init_events_attrs(struct perf_amd_iommu *perf_iommu)
+{
+	struct attribute **attrs;
+	struct attribute_group *attr_group;
+	int i = 0, j;
+
+	while (amd_iommu_v2_event_descs[i].attr.attr.name)
+		i++;
+
+	attr_group = kzalloc(sizeof(struct attribute *)
+		* (i + 1) + sizeof(*attr_group), GFP_KERNEL);
+	if (!attr_group)
+		return -ENOMEM;
+
+	attrs = (struct attribute **)(attr_group + 1);
+	for (j = 0; j < i; j++)
+		attrs[j] = &amd_iommu_v2_event_descs[j].attr.attr;
+
+	attr_group->name = "events";
+	attr_group->attrs = attrs;
+	perf_iommu->events_group = attr_group;
+
+	return 0;
+}
+
+static __init void amd_iommu_pc_exit(void)
+{
+	if (__perf_iommu.events_group != NULL) {
+		kfree(__perf_iommu.events_group);
+		__perf_iommu.events_group = NULL;
+	}
+}
+
+static __init int _init_perf_amd_iommu(
+	struct perf_amd_iommu *perf_iommu, char *name)
+{
+	int ret;
+
+	raw_spin_lock_init(&perf_iommu->lock);
+
+	/* Init format attributes */
+	perf_iommu->format_group = &amd_iommu_format_group;
+
+	/* Init cpumask attributes to only core 0 */
+	cpumask_set_cpu(0, &iommu_cpumask);
+	perf_iommu->cpumask_group = &amd_iommu_cpumask_group;
+
+	/* Init events attributes */
+	if (_init_events_attrs(perf_iommu) != 0)
+		pr_err("perf: amd_iommu: Only support raw events.\n");
+
+	/* Init null attributes */
+	perf_iommu->null_group = NULL;
+	perf_iommu->pmu.attr_groups = perf_iommu->attr_groups;
+
+	ret = perf_pmu_register(&perf_iommu->pmu, name, -1);
+	if (ret) {
+		pr_err("perf: amd_iommu: Failed to initialized.\n");
+		amd_iommu_pc_exit();
+	} else {
+		pr_info("perf: amd_iommu: Detected. (%d banks, %d counters/bank)\n",
+			amd_iommu_pc_get_max_banks(IOMMU_BASE_DEVID),
+			amd_iommu_pc_get_max_counters(IOMMU_BASE_DEVID));
+	}
+
+	return ret;
+}
+
+static struct perf_amd_iommu __perf_iommu = {
+	.pmu = {
+		.event_init	= perf_iommu_event_init,
+		.add		= perf_iommu_add,
+		.del		= perf_iommu_del,
+		.start		= perf_iommu_start,
+		.stop		= perf_iommu_stop,
+		.read		= perf_iommu_read,
+	},
+	.max_banks		= 0x00,
+	.max_counters		= 0x00,
+	.cntr_assign_mask	= 0ULL,
+	.format_group		= NULL,
+	.cpumask_group		= NULL,
+	.events_group		= NULL,
+	.null_group		= NULL,
+};
+
+static __init int amd_iommu_pc_init(void)
+{
+	/* Make sure the IOMMU PC resource is available */
+	if (!amd_iommu_pc_supported())
+		return -ENODEV;
+
+	_init_perf_amd_iommu(&__perf_iommu, "amd_iommu");
+
+	return 0;
+}
+
+device_initcall(amd_iommu_pc_init);
--- /dev/null
+++ zfcpdump-kernel-4.4/arch/x86/events/amd/iommu.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2013 Advanced Micro Devices, Inc.
+ *
+ * Author: Steven Kinney <Steven.Kinney@amd.com>
+ * Author: Suravee Suthikulpanit <Suraveee.Suthikulpanit@amd.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef _PERF_EVENT_AMD_IOMMU_H_
+#define _PERF_EVENT_AMD_IOMMU_H_
+
+/* iommu pc mmio region register indexes */
+#define IOMMU_PC_COUNTER_REG			0x00
+#define IOMMU_PC_COUNTER_SRC_REG		0x08
+#define IOMMU_PC_PASID_MATCH_REG		0x10
+#define IOMMU_PC_DOMID_MATCH_REG		0x18
+#define IOMMU_PC_DEVID_MATCH_REG		0x20
+#define IOMMU_PC_COUNTER_REPORT_REG		0x28
+
+/* maximun specified bank/counters */
+#define PC_MAX_SPEC_BNKS			64
+#define PC_MAX_SPEC_CNTRS			16
+
+/* iommu pc reg masks*/
+#define IOMMU_BASE_DEVID			0x0000
+
+/* amd_iommu_init.c external support functions */
+extern bool amd_iommu_pc_supported(void);
+
+extern u8 amd_iommu_pc_get_max_banks(u16 devid);
+
+extern u8 amd_iommu_pc_get_max_counters(u16 devid);
+
+extern int amd_iommu_pc_get_set_reg_val(u16 devid, u8 bank, u8 cntr,
+			u8 fxn, u64 *value, bool is_write);
+
+#endif /*_PERF_EVENT_AMD_IOMMU_H_*/
--- /dev/null
+++ zfcpdump-kernel-4.4/arch/x86/events/amd/uncore.c
@@ -0,0 +1,600 @@
+/*
+ * Copyright (C) 2013 Advanced Micro Devices, Inc.
+ *
+ * Author: Jacob Shin <jacob.shin@amd.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/perf_event.h>
+#include <linux/percpu.h>
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/cpu.h>
+#include <linux/cpumask.h>
+
+#include <asm/cpufeature.h>
+#include <asm/perf_event.h>
+#include <asm/msr.h>
+
+#define NUM_COUNTERS_NB		4
+#define NUM_COUNTERS_L2		4
+#define MAX_COUNTERS		NUM_COUNTERS_NB
+
+#define RDPMC_BASE_NB		6
+#define RDPMC_BASE_L2		10
+
+#define COUNTER_SHIFT		16
+
+struct amd_uncore {
+	int id;
+	int refcnt;
+	int cpu;
+	int num_counters;
+	int rdpmc_base;
+	u32 msr_base;
+	cpumask_t *active_mask;
+	struct pmu *pmu;
+	struct perf_event *events[MAX_COUNTERS];
+	struct amd_uncore *free_when_cpu_online;
+};
+
+static struct amd_uncore * __percpu *amd_uncore_nb;
+static struct amd_uncore * __percpu *amd_uncore_l2;
+
+static struct pmu amd_nb_pmu;
+static struct pmu amd_l2_pmu;
+
+static cpumask_t amd_nb_active_mask;
+static cpumask_t amd_l2_active_mask;
+
+static bool is_nb_event(struct perf_event *event)
+{
+	return event->pmu->type == amd_nb_pmu.type;
+}
+
+static bool is_l2_event(struct perf_event *event)
+{
+	return event->pmu->type == amd_l2_pmu.type;
+}
+
+static struct amd_uncore *event_to_amd_uncore(struct perf_event *event)
+{
+	if (is_nb_event(event) && amd_uncore_nb)
+		return *per_cpu_ptr(amd_uncore_nb, event->cpu);
+	else if (is_l2_event(event) && amd_uncore_l2)
+		return *per_cpu_ptr(amd_uncore_l2, event->cpu);
+
+	return NULL;
+}
+
+static void amd_uncore_read(struct perf_event *event)
+{
+	struct hw_perf_event *hwc = &event->hw;
+	u64 prev, new;
+	s64 delta;
+
+	/*
+	 * since we do not enable counter overflow interrupts,
+	 * we do not have to worry about prev_count changing on us
+	 */
+
+	prev = local64_read(&hwc->prev_count);
+	rdpmcl(hwc->event_base_rdpmc, new);
+	local64_set(&hwc->prev_count, new);
+	delta = (new << COUNTER_SHIFT) - (prev << COUNTER_SHIFT);
+	delta >>= COUNTER_SHIFT;
+	local64_add(delta, &event->count);
+}
+
+static void amd_uncore_start(struct perf_event *event, int flags)
+{
+	struct hw_perf_event *hwc = &event->hw;
+
+	if (flags & PERF_EF_RELOAD)
+		wrmsrl(hwc->event_base, (u64)local64_read(&hwc->prev_count));
+
+	hwc->state = 0;
+	wrmsrl(hwc->config_base, (hwc->config | ARCH_PERFMON_EVENTSEL_ENABLE));
+	perf_event_update_userpage(event);
+}
+
+static void amd_uncore_stop(struct perf_event *event, int flags)
+{
+	struct hw_perf_event *hwc = &event->hw;
+
+	wrmsrl(hwc->config_base, hwc->config);
+	hwc->state |= PERF_HES_STOPPED;
+
+	if ((flags & PERF_EF_UPDATE) && !(hwc->state & PERF_HES_UPTODATE)) {
+		amd_uncore_read(event);
+		hwc->state |= PERF_HES_UPTODATE;
+	}
+}
+
+static int amd_uncore_add(struct perf_event *event, int flags)
+{
+	int i;
+	struct amd_uncore *uncore = event_to_amd_uncore(event);
+	struct hw_perf_event *hwc = &event->hw;
+
+	/* are we already assigned? */
+	if (hwc->idx != -1 && uncore->events[hwc->idx] == event)
+		goto out;
+
+	for (i = 0; i < uncore->num_counters; i++) {
+		if (uncore->events[i] == event) {
+			hwc->idx = i;
+			goto out;
+		}
+	}
+
+	/* if not, take the first available counter */
+	hwc->idx = -1;
+	for (i = 0; i < uncore->num_counters; i++) {
+		if (cmpxchg(&uncore->events[i], NULL, event) == NULL) {
+			hwc->idx = i;
+			break;
+		}
+	}
+
+out:
+	if (hwc->idx == -1)
+		return -EBUSY;
+
+	hwc->config_base = uncore->msr_base + (2 * hwc->idx);
+	hwc->event_base = uncore->msr_base + 1 + (2 * hwc->idx);
+	hwc->event_base_rdpmc = uncore->rdpmc_base + hwc->idx;
+	hwc->state = PERF_HES_UPTODATE | PERF_HES_STOPPED;
+
+	if (flags & PERF_EF_START)
+		amd_uncore_start(event, PERF_EF_RELOAD);
+
+	return 0;
+}
+
+static void amd_uncore_del(struct perf_event *event, int flags)
+{
+	int i;
+	struct amd_uncore *uncore = event_to_amd_uncore(event);
+	struct hw_perf_event *hwc = &event->hw;
+
+	amd_uncore_stop(event, PERF_EF_UPDATE);
+
+	for (i = 0; i < uncore->num_counters; i++) {
+		if (cmpxchg(&uncore->events[i], event, NULL) == event)
+			break;
+	}
+
+	hwc->idx = -1;
+}
+
+static int amd_uncore_event_init(struct perf_event *event)
+{
+	struct amd_uncore *uncore;
+	struct hw_perf_event *hwc = &event->hw;
+
+	if (event->attr.type != event->pmu->type)
+		return -ENOENT;
+
+	/*
+	 * NB and L2 counters (MSRs) are shared across all cores that share the
+	 * same NB / L2 cache. Interrupts can be directed to a single target
+	 * core, however, event counts generated by processes running on other
+	 * cores cannot be masked out. So we do not support sampling and
+	 * per-thread events.
+	 */
+	if (is_sampling_event(event) || event->attach_state & PERF_ATTACH_TASK)
+		return -EINVAL;
+
+	/* NB and L2 counters do not have usr/os/guest/host bits */
+	if (event->attr.exclude_user || event->attr.exclude_kernel ||
+	    event->attr.exclude_host || event->attr.exclude_guest)
+		return -EINVAL;
+
+	/* and we do not enable counter overflow interrupts */
+	hwc->config = event->attr.config & AMD64_RAW_EVENT_MASK_NB;
+	hwc->idx = -1;
+
+	if (event->cpu < 0)
+		return -EINVAL;
+
+	uncore = event_to_amd_uncore(event);
+	if (!uncore)
+		return -ENODEV;
+
+	/*
+	 * since request can come in to any of the shared cores, we will remap
+	 * to a single common cpu.
+	 */
+	event->cpu = uncore->cpu;
+
+	return 0;
+}
+
+static ssize_t amd_uncore_attr_show_cpumask(struct device *dev,
+					    struct device_attribute *attr,
+					    char *buf)
+{
+	cpumask_t *active_mask;
+	struct pmu *pmu = dev_get_drvdata(dev);
+
+	if (pmu->type == amd_nb_pmu.type)
+		active_mask = &amd_nb_active_mask;
+	else if (pmu->type == amd_l2_pmu.type)
+		active_mask = &amd_l2_active_mask;
+	else
+		return 0;
+
+	return cpumap_print_to_pagebuf(true, buf, active_mask);
+}
+static DEVICE_ATTR(cpumask, S_IRUGO, amd_uncore_attr_show_cpumask, NULL);
+
+static struct attribute *amd_uncore_attrs[] = {
+	&dev_attr_cpumask.attr,
+	NULL,
+};
+
+static struct attribute_group amd_uncore_attr_group = {
+	.attrs = amd_uncore_attrs,
+};
+
+PMU_FORMAT_ATTR(event, "config:0-7,32-35");
+PMU_FORMAT_ATTR(umask, "config:8-15");
+
+static struct attribute *amd_uncore_format_attr[] = {
+	&format_attr_event.attr,
+	&format_attr_umask.attr,
+	NULL,
+};
+
+static struct attribute_group amd_uncore_format_group = {
+	.name = "format",
+	.attrs = amd_uncore_format_attr,
+};
+
+static const struct attribute_group *amd_uncore_attr_groups[] = {
+	&amd_uncore_attr_group,
+	&amd_uncore_format_group,
+	NULL,
+};
+
+static struct pmu amd_nb_pmu = {
+	.attr_groups	= amd_uncore_attr_groups,
+	.name		= "amd_nb",
+	.event_init	= amd_uncore_event_init,
+	.add		= amd_uncore_add,
+	.del		= amd_uncore_del,
+	.start		= amd_uncore_start,
+	.stop		= amd_uncore_stop,
+	.read		= amd_uncore_read,
+};
+
+static struct pmu amd_l2_pmu = {
+	.attr_groups	= amd_uncore_attr_groups,
+	.name		= "amd_l2",
+	.event_init	= amd_uncore_event_init,
+	.add		= amd_uncore_add,
+	.del		= amd_uncore_del,
+	.start		= amd_uncore_start,
+	.stop		= amd_uncore_stop,
+	.read		= amd_uncore_read,
+};
+
+static struct amd_uncore *amd_uncore_alloc(unsigned int cpu)
+{
+	return kzalloc_node(sizeof(struct amd_uncore), GFP_KERNEL,
+			cpu_to_node(cpu));
+}
+
+static int amd_uncore_cpu_up_prepare(unsigned int cpu)
+{
+	struct amd_uncore *uncore_nb = NULL, *uncore_l2;
+
+	if (amd_uncore_nb) {
+		uncore_nb = amd_uncore_alloc(cpu);
+		if (!uncore_nb)
+			goto fail;
+		uncore_nb->cpu = cpu;
+		uncore_nb->num_counters = NUM_COUNTERS_NB;
+		uncore_nb->rdpmc_base = RDPMC_BASE_NB;
+		uncore_nb->msr_base = MSR_F15H_NB_PERF_CTL;
+		uncore_nb->active_mask = &amd_nb_active_mask;
+		uncore_nb->pmu = &amd_nb_pmu;
+		*per_cpu_ptr(amd_uncore_nb, cpu) = uncore_nb;
+	}
+
+	if (amd_uncore_l2) {
+		uncore_l2 = amd_uncore_alloc(cpu);
+		if (!uncore_l2)
+			goto fail;
+		uncore_l2->cpu = cpu;
+		uncore_l2->num_counters = NUM_COUNTERS_L2;
+		uncore_l2->rdpmc_base = RDPMC_BASE_L2;
+		uncore_l2->msr_base = MSR_F16H_L2I_PERF_CTL;
+		uncore_l2->active_mask = &amd_l2_active_mask;
+		uncore_l2->pmu = &amd_l2_pmu;
+		*per_cpu_ptr(amd_uncore_l2, cpu) = uncore_l2;
+	}
+
+	return 0;
+
+fail:
+	kfree(uncore_nb);
+	return -ENOMEM;
+}
+
+static struct amd_uncore *
+amd_uncore_find_online_sibling(struct amd_uncore *this,
+			       struct amd_uncore * __percpu *uncores)
+{
+	unsigned int cpu;
+	struct amd_uncore *that;
+
+	for_each_online_cpu(cpu) {
+		that = *per_cpu_ptr(uncores, cpu);
+
+		if (!that)
+			continue;
+
+		if (this == that)
+			continue;
+
+		if (this->id == that->id) {
+			that->free_when_cpu_online = this;
+			this = that;
+			break;
+		}
+	}
+
+	this->refcnt++;
+	return this;
+}
+
+static void amd_uncore_cpu_starting(unsigned int cpu)
+{
+	unsigned int eax, ebx, ecx, edx;
+	struct amd_uncore *uncore;
+
+	if (amd_uncore_nb) {
+		uncore = *per_cpu_ptr(amd_uncore_nb, cpu);
+		cpuid(0x8000001e, &eax, &ebx, &ecx, &edx);
+		uncore->id = ecx & 0xff;
+
+		uncore = amd_uncore_find_online_sibling(uncore, amd_uncore_nb);
+		*per_cpu_ptr(amd_uncore_nb, cpu) = uncore;
+	}
+
+	if (amd_uncore_l2) {
+		unsigned int apicid = cpu_data(cpu).apicid;
+		unsigned int nshared;
+
+		uncore = *per_cpu_ptr(amd_uncore_l2, cpu);
+		cpuid_count(0x8000001d, 2, &eax, &ebx, &ecx, &edx);
+		nshared = ((eax >> 14) & 0xfff) + 1;
+		uncore->id = apicid - (apicid % nshared);
+
+		uncore = amd_uncore_find_online_sibling(uncore, amd_uncore_l2);
+		*per_cpu_ptr(amd_uncore_l2, cpu) = uncore;
+	}
+}
+
+static void uncore_online(unsigned int cpu,
+			  struct amd_uncore * __percpu *uncores)
+{
+	struct amd_uncore *uncore = *per_cpu_ptr(uncores, cpu);
+
+	kfree(uncore->free_when_cpu_online);
+	uncore->free_when_cpu_online = NULL;
+
+	if (cpu == uncore->cpu)
+		cpumask_set_cpu(cpu, uncore->active_mask);
+}
+
+static void amd_uncore_cpu_online(unsigned int cpu)
+{
+	if (amd_uncore_nb)
+		uncore_online(cpu, amd_uncore_nb);
+
+	if (amd_uncore_l2)
+		uncore_online(cpu, amd_uncore_l2);
+}
+
+static void uncore_down_prepare(unsigned int cpu,
+				struct amd_uncore * __percpu *uncores)
+{
+	unsigned int i;
+	struct amd_uncore *this = *per_cpu_ptr(uncores, cpu);
+
+	if (this->cpu != cpu)
+		return;
+
+	/* this cpu is going down, migrate to a shared sibling if possible */
+	for_each_online_cpu(i) {
+		struct amd_uncore *that = *per_cpu_ptr(uncores, i);
+
+		if (cpu == i)
+			continue;
+
+		if (this == that) {
+			perf_pmu_migrate_context(this->pmu, cpu, i);
+			cpumask_clear_cpu(cpu, that->active_mask);
+			cpumask_set_cpu(i, that->active_mask);
+			that->cpu = i;
+			break;
+		}
+	}
+}
+
+static void amd_uncore_cpu_down_prepare(unsigned int cpu)
+{
+	if (amd_uncore_nb)
+		uncore_down_prepare(cpu, amd_uncore_nb);
+
+	if (amd_uncore_l2)
+		uncore_down_prepare(cpu, amd_uncore_l2);
+}
+
+static void uncore_dead(unsigned int cpu, struct amd_uncore * __percpu *uncores)
+{
+	struct amd_uncore *uncore = *per_cpu_ptr(uncores, cpu);
+
+	if (cpu == uncore->cpu)
+		cpumask_clear_cpu(cpu, uncore->active_mask);
+
+	if (!--uncore->refcnt)
+		kfree(uncore);
+	*per_cpu_ptr(uncores, cpu) = NULL;
+}
+
+static void amd_uncore_cpu_dead(unsigned int cpu)
+{
+	if (amd_uncore_nb)
+		uncore_dead(cpu, amd_uncore_nb);
+
+	if (amd_uncore_l2)
+		uncore_dead(cpu, amd_uncore_l2);
+}
+
+static int
+amd_uncore_cpu_notifier(struct notifier_block *self, unsigned long action,
+			void *hcpu)
+{
+	unsigned int cpu = (long)hcpu;
+
+	switch (action & ~CPU_TASKS_FROZEN) {
+	case CPU_UP_PREPARE:
+		if (amd_uncore_cpu_up_prepare(cpu))
+			return notifier_from_errno(-ENOMEM);
+		break;
+
+	case CPU_STARTING:
+		amd_uncore_cpu_starting(cpu);
+		break;
+
+	case CPU_ONLINE:
+		amd_uncore_cpu_online(cpu);
+		break;
+
+	case CPU_DOWN_PREPARE:
+		amd_uncore_cpu_down_prepare(cpu);
+		break;
+
+	case CPU_UP_CANCELED:
+	case CPU_DEAD:
+		amd_uncore_cpu_dead(cpu);
+		break;
+
+	default:
+		break;
+	}
+
+	return NOTIFY_OK;
+}
+
+static struct notifier_block amd_uncore_cpu_notifier_block = {
+	.notifier_call	= amd_uncore_cpu_notifier,
+	.priority	= CPU_PRI_PERF + 1,
+};
+
+static void __init init_cpu_already_online(void *dummy)
+{
+	unsigned int cpu = smp_processor_id();
+
+	amd_uncore_cpu_starting(cpu);
+	amd_uncore_cpu_online(cpu);
+}
+
+static void cleanup_cpu_online(void *dummy)
+{
+	unsigned int cpu = smp_processor_id();
+
+	amd_uncore_cpu_dead(cpu);
+}
+
+static int __init amd_uncore_init(void)
+{
+	unsigned int cpu, cpu2;
+	int ret = -ENODEV;
+
+	if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD)
+		goto fail_nodev;
+
+	if (!cpu_has_topoext)
+		goto fail_nodev;
+
+	if (cpu_has_perfctr_nb) {
+		amd_uncore_nb = alloc_percpu(struct amd_uncore *);
+		if (!amd_uncore_nb) {
+			ret = -ENOMEM;
+			goto fail_nb;
+		}
+		ret = perf_pmu_register(&amd_nb_pmu, amd_nb_pmu.name, -1);
+		if (ret)
+			goto fail_nb;
+
+		printk(KERN_INFO "perf: AMD NB counters detected\n");
+		ret = 0;
+	}
+
+	if (cpu_has_perfctr_l2) {
+		amd_uncore_l2 = alloc_percpu(struct amd_uncore *);
+		if (!amd_uncore_l2) {
+			ret = -ENOMEM;
+			goto fail_l2;
+		}
+		ret = perf_pmu_register(&amd_l2_pmu, amd_l2_pmu.name, -1);
+		if (ret)
+			goto fail_l2;
+
+		printk(KERN_INFO "perf: AMD L2I counters detected\n");
+		ret = 0;
+	}
+
+	if (ret)
+		goto fail_nodev;
+
+	cpu_notifier_register_begin();
+
+	/* init cpus already online before registering for hotplug notifier */
+	for_each_online_cpu(cpu) {
+		ret = amd_uncore_cpu_up_prepare(cpu);
+		if (ret)
+			goto fail_online;
+		smp_call_function_single(cpu, init_cpu_already_online, NULL, 1);
+	}
+
+	__register_cpu_notifier(&amd_uncore_cpu_notifier_block);
+	cpu_notifier_register_done();
+
+	return 0;
+
+
+fail_online:
+	for_each_online_cpu(cpu2) {
+		if (cpu2 == cpu)
+			break;
+		smp_call_function_single(cpu, cleanup_cpu_online, NULL, 1);
+	}
+	cpu_notifier_register_done();
+
+	/* amd_uncore_nb/l2 should have been freed by cleanup_cpu_online */
+	amd_uncore_nb = amd_uncore_l2 = NULL;
+	if (cpu_has_perfctr_l2)
+		perf_pmu_unregister(&amd_l2_pmu);
+fail_l2:
+	if (cpu_has_perfctr_nb)
+		perf_pmu_unregister(&amd_nb_pmu);
+	if (amd_uncore_l2)
+		free_percpu(amd_uncore_l2);
+fail_nb:
+	if (amd_uncore_nb)
+		free_percpu(amd_uncore_nb);
+
+fail_nodev:
+	return ret;
+}
+device_initcall(amd_uncore_init);
--- /dev/null
+++ zfcpdump-kernel-4.4/arch/x86/events/core.c
@@ -0,0 +1,2413 @@
+/*
+ * Performance events x86 architecture code
+ *
+ *  Copyright (C) 2008 Thomas Gleixner <tglx@linutronix.de>
+ *  Copyright (C) 2008-2009 Red Hat, Inc., Ingo Molnar
+ *  Copyright (C) 2009 Jaswinder Singh Rajput
+ *  Copyright (C) 2009 Advanced Micro Devices, Inc., Robert Richter
+ *  Copyright (C) 2008-2009 Red Hat, Inc., Peter Zijlstra
+ *  Copyright (C) 2009 Intel Corporation, <markus.t.metzger@intel.com>
+ *  Copyright (C) 2009 Google, Inc., Stephane Eranian
+ *
+ *  For licencing details see kernel-base/COPYING
+ */
+
+#include <linux/perf_event.h>
+#include <linux/capability.h>
+#include <linux/notifier.h>
+#include <linux/hardirq.h>
+#include <linux/kprobes.h>
+#include <linux/module.h>
+#include <linux/kdebug.h>
+#include <linux/sched.h>
+#include <linux/uaccess.h>
+#include <linux/slab.h>
+#include <linux/cpu.h>
+#include <linux/bitops.h>
+#include <linux/device.h>
+
+#include <asm/apic.h>
+#include <asm/stacktrace.h>
+#include <asm/nmi.h>
+#include <asm/smp.h>
+#include <asm/alternative.h>
+#include <asm/mmu_context.h>
+#include <asm/tlbflush.h>
+#include <asm/timer.h>
+#include <asm/desc.h>
+#include <asm/ldt.h>
+
+#include "perf_event.h"
+
+struct x86_pmu x86_pmu __read_mostly;
+
+DEFINE_PER_CPU(struct cpu_hw_events, cpu_hw_events) = {
+	.enabled = 1,
+};
+
+struct static_key rdpmc_always_available = STATIC_KEY_INIT_FALSE;
+
+u64 __read_mostly hw_cache_event_ids
+				[PERF_COUNT_HW_CACHE_MAX]
+				[PERF_COUNT_HW_CACHE_OP_MAX]
+				[PERF_COUNT_HW_CACHE_RESULT_MAX];
+u64 __read_mostly hw_cache_extra_regs
+				[PERF_COUNT_HW_CACHE_MAX]
+				[PERF_COUNT_HW_CACHE_OP_MAX]
+				[PERF_COUNT_HW_CACHE_RESULT_MAX];
+
+/*
+ * Propagate event elapsed time into the generic event.
+ * Can only be executed on the CPU where the event is active.
+ * Returns the delta events processed.
+ */
+u64 x86_perf_event_update(struct perf_event *event)
+{
+	struct hw_perf_event *hwc = &event->hw;
+	int shift = 64 - x86_pmu.cntval_bits;
+	u64 prev_raw_count, new_raw_count;
+	int idx = hwc->idx;
+	s64 delta;
+
+	if (idx == INTEL_PMC_IDX_FIXED_BTS)
+		return 0;
+
+	/*
+	 * Careful: an NMI might modify the previous event value.
+	 *
+	 * Our tactic to handle this is to first atomically read and
+	 * exchange a new raw count - then add that new-prev delta
+	 * count to the generic event atomically:
+	 */
+again:
+	prev_raw_count = local64_read(&hwc->prev_count);
+	rdpmcl(hwc->event_base_rdpmc, new_raw_count);
+
+	if (local64_cmpxchg(&hwc->prev_count, prev_raw_count,
+					new_raw_count) != prev_raw_count)
+		goto again;
+
+	/*
+	 * Now we have the new raw value and have updated the prev
+	 * timestamp already. We can now calculate the elapsed delta
+	 * (event-)time and add that to the generic event.
+	 *
+	 * Careful, not all hw sign-extends above the physical width
+	 * of the count.
+	 */
+	delta = (new_raw_count << shift) - (prev_raw_count << shift);
+	delta >>= shift;
+
+	local64_add(delta, &event->count);
+	local64_sub(delta, &hwc->period_left);
+
+	return new_raw_count;
+}
+
+/*
+ * Find and validate any extra registers to set up.
+ */
+static int x86_pmu_extra_regs(u64 config, struct perf_event *event)
+{
+	struct hw_perf_event_extra *reg;
+	struct extra_reg *er;
+
+	reg = &event->hw.extra_reg;
+
+	if (!x86_pmu.extra_regs)
+		return 0;
+
+	for (er = x86_pmu.extra_regs; er->msr; er++) {
+		if (er->event != (config & er->config_mask))
+			continue;
+		if (event->attr.config1 & ~er->valid_mask)
+			return -EINVAL;
+		/* Check if the extra msrs can be safely accessed*/
+		if (!er->extra_msr_access)
+			return -ENXIO;
+
+		reg->idx = er->idx;
+		reg->config = event->attr.config1;
+		reg->reg = er->msr;
+		break;
+	}
+	return 0;
+}
+
+static atomic_t active_events;
+static atomic_t pmc_refcount;
+static DEFINE_MUTEX(pmc_reserve_mutex);
+
+#ifdef CONFIG_X86_LOCAL_APIC
+
+static bool reserve_pmc_hardware(void)
+{
+	int i;
+
+	for (i = 0; i < x86_pmu.num_counters; i++) {
+		if (!reserve_perfctr_nmi(x86_pmu_event_addr(i)))
+			goto perfctr_fail;
+	}
+
+	for (i = 0; i < x86_pmu.num_counters; i++) {
+		if (!reserve_evntsel_nmi(x86_pmu_config_addr(i)))
+			goto eventsel_fail;
+	}
+
+	return true;
+
+eventsel_fail:
+	for (i--; i >= 0; i--)
+		release_evntsel_nmi(x86_pmu_config_addr(i));
+
+	i = x86_pmu.num_counters;
+
+perfctr_fail:
+	for (i--; i >= 0; i--)
+		release_perfctr_nmi(x86_pmu_event_addr(i));
+
+	return false;
+}
+
+static void release_pmc_hardware(void)
+{
+	int i;
+
+	for (i = 0; i < x86_pmu.num_counters; i++) {
+		release_perfctr_nmi(x86_pmu_event_addr(i));
+		release_evntsel_nmi(x86_pmu_config_addr(i));
+	}
+}
+
+#else
+
+static bool reserve_pmc_hardware(void) { return true; }
+static void release_pmc_hardware(void) {}
+
+#endif
+
+static bool check_hw_exists(void)
+{
+	u64 val, val_fail, val_new= ~0;
+	int i, reg, reg_fail, ret = 0;
+	int bios_fail = 0;
+	int reg_safe = -1;
+
+	/*
+	 * Check to see if the BIOS enabled any of the counters, if so
+	 * complain and bail.
+	 */
+	for (i = 0; i < x86_pmu.num_counters; i++) {
+		reg = x86_pmu_config_addr(i);
+		ret = rdmsrl_safe(reg, &val);
+		if (ret)
+			goto msr_fail;
+		if (val & ARCH_PERFMON_EVENTSEL_ENABLE) {
+			bios_fail = 1;
+			val_fail = val;
+			reg_fail = reg;
+		} else {
+			reg_safe = i;
+		}
+	}
+
+	if (x86_pmu.num_counters_fixed) {
+		reg = MSR_ARCH_PERFMON_FIXED_CTR_CTRL;
+		ret = rdmsrl_safe(reg, &val);
+		if (ret)
+			goto msr_fail;
+		for (i = 0; i < x86_pmu.num_counters_fixed; i++) {
+			if (val & (0x03 << i*4)) {
+				bios_fail = 1;
+				val_fail = val;
+				reg_fail = reg;
+			}
+		}
+	}
+
+	/*
+	 * If all the counters are enabled, the below test will always
+	 * fail.  The tools will also become useless in this scenario.
+	 * Just fail and disable the hardware counters.
+	 */
+
+	if (reg_safe == -1) {
+		reg = reg_safe;
+		goto msr_fail;
+	}
+
+	/*
+	 * Read the current value, change it and read it back to see if it
+	 * matches, this is needed to detect certain hardware emulators
+	 * (qemu/kvm) that don't trap on the MSR access and always return 0s.
+	 */
+	reg = x86_pmu_event_addr(reg_safe);
+	if (rdmsrl_safe(reg, &val))
+		goto msr_fail;
+	val ^= 0xffffUL;
+	ret = wrmsrl_safe(reg, val);
+	ret |= rdmsrl_safe(reg, &val_new);
+	if (ret || val != val_new)
+		goto msr_fail;
+
+	/*
+	 * We still allow the PMU driver to operate:
+	 */
+	if (bios_fail) {
+		printk(KERN_CONT "Broken BIOS detected, complain to your hardware vendor.\n");
+		printk(KERN_ERR FW_BUG "the BIOS has corrupted hw-PMU resources (MSR %x is %Lx)\n", reg_fail, val_fail);
+	}
+
+	return true;
+
+msr_fail:
+	printk(KERN_CONT "Broken PMU hardware detected, using software events only.\n");
+	printk("%sFailed to access perfctr msr (MSR %x is %Lx)\n",
+		boot_cpu_has(X86_FEATURE_HYPERVISOR) ? KERN_INFO : KERN_ERR,
+		reg, val_new);
+
+	return false;
+}
+
+static void hw_perf_event_destroy(struct perf_event *event)
+{
+	x86_release_hardware();
+	atomic_dec(&active_events);
+}
+
+void hw_perf_lbr_event_destroy(struct perf_event *event)
+{
+	hw_perf_event_destroy(event);
+
+	/* undo the lbr/bts event accounting */
+	x86_del_exclusive(x86_lbr_exclusive_lbr);
+}
+
+static inline int x86_pmu_initialized(void)
+{
+	return x86_pmu.handle_irq != NULL;
+}
+
+static inline int
+set_ext_hw_attr(struct hw_perf_event *hwc, struct perf_event *event)
+{
+	struct perf_event_attr *attr = &event->attr;
+	unsigned int cache_type, cache_op, cache_result;
+	u64 config, val;
+
+	config = attr->config;
+
+	cache_type = (config >>  0) & 0xff;
+	if (cache_type >= PERF_COUNT_HW_CACHE_MAX)
+		return -EINVAL;
+
+	cache_op = (config >>  8) & 0xff;
+	if (cache_op >= PERF_COUNT_HW_CACHE_OP_MAX)
+		return -EINVAL;
+
+	cache_result = (config >> 16) & 0xff;
+	if (cache_result >= PERF_COUNT_HW_CACHE_RESULT_MAX)
+		return -EINVAL;
+
+	val = hw_cache_event_ids[cache_type][cache_op][cache_result];
+
+	if (val == 0)
+		return -ENOENT;
+
+	if (val == -1)
+		return -EINVAL;
+
+	hwc->config |= val;
+	attr->config1 = hw_cache_extra_regs[cache_type][cache_op][cache_result];
+	return x86_pmu_extra_regs(val, event);
+}
+
+int x86_reserve_hardware(void)
+{
+	int err = 0;
+
+	if (!atomic_inc_not_zero(&pmc_refcount)) {
+		mutex_lock(&pmc_reserve_mutex);
+		if (atomic_read(&pmc_refcount) == 0) {
+			if (!reserve_pmc_hardware())
+				err = -EBUSY;
+			else
+				reserve_ds_buffers();
+		}
+		if (!err)
+			atomic_inc(&pmc_refcount);
+		mutex_unlock(&pmc_reserve_mutex);
+	}
+
+	return err;
+}
+
+void x86_release_hardware(void)
+{
+	if (atomic_dec_and_mutex_lock(&pmc_refcount, &pmc_reserve_mutex)) {
+		release_pmc_hardware();
+		release_ds_buffers();
+		mutex_unlock(&pmc_reserve_mutex);
+	}
+}
+
+/*
+ * Check if we can create event of a certain type (that no conflicting events
+ * are present).
+ */
+int x86_add_exclusive(unsigned int what)
+{
+	int i;
+
+	if (!atomic_inc_not_zero(&x86_pmu.lbr_exclusive[what])) {
+		mutex_lock(&pmc_reserve_mutex);
+		for (i = 0; i < ARRAY_SIZE(x86_pmu.lbr_exclusive); i++) {
+			if (i != what && atomic_read(&x86_pmu.lbr_exclusive[i]))
+				goto fail_unlock;
+		}
+		atomic_inc(&x86_pmu.lbr_exclusive[what]);
+		mutex_unlock(&pmc_reserve_mutex);
+	}
+
+	atomic_inc(&active_events);
+	return 0;
+
+fail_unlock:
+	mutex_unlock(&pmc_reserve_mutex);
+	return -EBUSY;
+}
+
+void x86_del_exclusive(unsigned int what)
+{
+	atomic_dec(&x86_pmu.lbr_exclusive[what]);
+	atomic_dec(&active_events);
+}
+
+int x86_setup_perfctr(struct perf_event *event)
+{
+	struct perf_event_attr *attr = &event->attr;
+	struct hw_perf_event *hwc = &event->hw;
+	u64 config;
+
+	if (!is_sampling_event(event)) {
+		hwc->sample_period = x86_pmu.max_period;
+		hwc->last_period = hwc->sample_period;
+		local64_set(&hwc->period_left, hwc->sample_period);
+	}
+
+	if (attr->type == PERF_TYPE_RAW)
+		return x86_pmu_extra_regs(event->attr.config, event);
+
+	if (attr->type == PERF_TYPE_HW_CACHE)
+		return set_ext_hw_attr(hwc, event);
+
+	if (attr->config >= x86_pmu.max_events)
+		return -EINVAL;
+
+	/*
+	 * The generic map:
+	 */
+	config = x86_pmu.event_map(attr->config);
+
+	if (config == 0)
+		return -ENOENT;
+
+	if (config == -1LL)
+		return -EINVAL;
+
+	/*
+	 * Branch tracing:
+	 */
+	if (attr->config == PERF_COUNT_HW_BRANCH_INSTRUCTIONS &&
+	    !attr->freq && hwc->sample_period == 1) {
+		/* BTS is not supported by this architecture. */
+		if (!x86_pmu.bts_active)
+			return -EOPNOTSUPP;
+
+		/* BTS is currently only allowed for user-mode. */
+		if (!attr->exclude_kernel)
+			return -EOPNOTSUPP;
+
+		/* disallow bts if conflicting events are present */
+		if (x86_add_exclusive(x86_lbr_exclusive_lbr))
+			return -EBUSY;
+
+		event->destroy = hw_perf_lbr_event_destroy;
+	}
+
+	hwc->config |= config;
+
+	return 0;
+}
+
+/*
+ * check that branch_sample_type is compatible with
+ * settings needed for precise_ip > 1 which implies
+ * using the LBR to capture ALL taken branches at the
+ * priv levels of the measurement
+ */
+static inline int precise_br_compat(struct perf_event *event)
+{
+	u64 m = event->attr.branch_sample_type;
+	u64 b = 0;
+
+	/* must capture all branches */
+	if (!(m & PERF_SAMPLE_BRANCH_ANY))
+		return 0;
+
+	m &= PERF_SAMPLE_BRANCH_KERNEL | PERF_SAMPLE_BRANCH_USER;
+
+	if (!event->attr.exclude_user)
+		b |= PERF_SAMPLE_BRANCH_USER;
+
+	if (!event->attr.exclude_kernel)
+		b |= PERF_SAMPLE_BRANCH_KERNEL;
+
+	/*
+	 * ignore PERF_SAMPLE_BRANCH_HV, not supported on x86
+	 */
+
+	return m == b;
+}
+
+int x86_pmu_hw_config(struct perf_event *event)
+{
+	if (event->attr.precise_ip) {
+		int precise = 0;
+
+		/* Support for constant skid */
+		if (x86_pmu.pebs_active && !x86_pmu.pebs_broken) {
+			precise++;
+
+			/* Support for IP fixup */
+			if (x86_pmu.lbr_nr || x86_pmu.intel_cap.pebs_format >= 2)
+				precise++;
+		}
+
+		if (event->attr.precise_ip > precise)
+			return -EOPNOTSUPP;
+	}
+	/*
+	 * check that PEBS LBR correction does not conflict with
+	 * whatever the user is asking with attr->branch_sample_type
+	 */
+	if (event->attr.precise_ip > 1 && x86_pmu.intel_cap.pebs_format < 2) {
+		u64 *br_type = &event->attr.branch_sample_type;
+
+		if (has_branch_stack(event)) {
+			if (!precise_br_compat(event))
+				return -EOPNOTSUPP;
+
+			/* branch_sample_type is compatible */
+
+		} else {
+			/*
+			 * user did not specify  branch_sample_type
+			 *
+			 * For PEBS fixups, we capture all
+			 * the branches at the priv level of the
+			 * event.
+			 */
+			*br_type = PERF_SAMPLE_BRANCH_ANY;
+
+			if (!event->attr.exclude_user)
+				*br_type |= PERF_SAMPLE_BRANCH_USER;
+
+			if (!event->attr.exclude_kernel)
+				*br_type |= PERF_SAMPLE_BRANCH_KERNEL;
+		}
+	}
+
+	if (event->attr.branch_sample_type & PERF_SAMPLE_BRANCH_CALL_STACK)
+		event->attach_state |= PERF_ATTACH_TASK_DATA;
+
+	/*
+	 * Generate PMC IRQs:
+	 * (keep 'enabled' bit clear for now)
+	 */
+	event->hw.config = ARCH_PERFMON_EVENTSEL_INT;
+
+	/*
+	 * Count user and OS events unless requested not to
+	 */
+	if (!event->attr.exclude_user)
+		event->hw.config |= ARCH_PERFMON_EVENTSEL_USR;
+	if (!event->attr.exclude_kernel)
+		event->hw.config |= ARCH_PERFMON_EVENTSEL_OS;
+
+	if (event->attr.type == PERF_TYPE_RAW)
+		event->hw.config |= event->attr.config & X86_RAW_EVENT_MASK;
+
+	if (event->attr.sample_period && x86_pmu.limit_period) {
+		if (x86_pmu.limit_period(event, event->attr.sample_period) >
+				event->attr.sample_period)
+			return -EINVAL;
+	}
+
+	return x86_setup_perfctr(event);
+}
+
+/*
+ * Setup the hardware configuration for a given attr_type
+ */
+static int __x86_pmu_event_init(struct perf_event *event)
+{
+	int err;
+
+	if (!x86_pmu_initialized())
+		return -ENODEV;
+
+	err = x86_reserve_hardware();
+	if (err)
+		return err;
+
+	atomic_inc(&active_events);
+	event->destroy = hw_perf_event_destroy;
+
+	event->hw.idx = -1;
+	event->hw.last_cpu = -1;
+	event->hw.last_tag = ~0ULL;
+
+	/* mark unused */
+	event->hw.extra_reg.idx = EXTRA_REG_NONE;
+	event->hw.branch_reg.idx = EXTRA_REG_NONE;
+
+	return x86_pmu.hw_config(event);
+}
+
+void x86_pmu_disable_all(void)
+{
+	struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
+	int idx;
+
+	for (idx = 0; idx < x86_pmu.num_counters; idx++) {
+		u64 val;
+
+		if (!test_bit(idx, cpuc->active_mask))
+			continue;
+		rdmsrl(x86_pmu_config_addr(idx), val);
+		if (!(val & ARCH_PERFMON_EVENTSEL_ENABLE))
+			continue;
+		val &= ~ARCH_PERFMON_EVENTSEL_ENABLE;
+		wrmsrl(x86_pmu_config_addr(idx), val);
+	}
+}
+
+/*
+ * There may be PMI landing after enabled=0. The PMI hitting could be before or
+ * after disable_all.
+ *
+ * If PMI hits before disable_all, the PMU will be disabled in the NMI handler.
+ * It will not be re-enabled in the NMI handler again, because enabled=0. After
+ * handling the NMI, disable_all will be called, which will not change the
+ * state either. If PMI hits after disable_all, the PMU is already disabled
+ * before entering NMI handler. The NMI handler will not change the state
+ * either.
+ *
+ * So either situation is harmless.
+ */
+static void x86_pmu_disable(struct pmu *pmu)
+{
+	struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
+
+	if (!x86_pmu_initialized())
+		return;
+
+	if (!cpuc->enabled)
+		return;
+
+	cpuc->n_added = 0;
+	cpuc->enabled = 0;
+	barrier();
+
+	x86_pmu.disable_all();
+}
+
+void x86_pmu_enable_all(int added)
+{
+	struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
+	int idx;
+
+	for (idx = 0; idx < x86_pmu.num_counters; idx++) {
+		struct hw_perf_event *hwc = &cpuc->events[idx]->hw;
+
+		if (!test_bit(idx, cpuc->active_mask))
+			continue;
+
+		__x86_pmu_enable_event(hwc, ARCH_PERFMON_EVENTSEL_ENABLE);
+	}
+}
+
+static struct pmu pmu;
+
+static inline int is_x86_event(struct perf_event *event)
+{
+	return event->pmu == &pmu;
+}
+
+/*
+ * Event scheduler state:
+ *
+ * Assign events iterating over all events and counters, beginning
+ * with events with least weights first. Keep the current iterator
+ * state in struct sched_state.
+ */
+struct sched_state {
+	int	weight;
+	int	event;		/* event index */
+	int	counter;	/* counter index */
+	int	unassigned;	/* number of events to be assigned left */
+	int	nr_gp;		/* number of GP counters used */
+	unsigned long used[BITS_TO_LONGS(X86_PMC_IDX_MAX)];
+};
+
+/* Total max is X86_PMC_IDX_MAX, but we are O(n!) limited */
+#define	SCHED_STATES_MAX	2
+
+struct perf_sched {
+	int			max_weight;
+	int			max_events;
+	int			max_gp;
+	int			saved_states;
+	struct event_constraint	**constraints;
+	struct sched_state	state;
+	struct sched_state	saved[SCHED_STATES_MAX];
+};
+
+/*
+ * Initialize interator that runs through all events and counters.
+ */
+static void perf_sched_init(struct perf_sched *sched, struct event_constraint **constraints,
+			    int num, int wmin, int wmax, int gpmax)
+{
+	int idx;
+
+	memset(sched, 0, sizeof(*sched));
+	sched->max_events	= num;
+	sched->max_weight	= wmax;
+	sched->max_gp		= gpmax;
+	sched->constraints	= constraints;
+
+	for (idx = 0; idx < num; idx++) {
+		if (constraints[idx]->weight == wmin)
+			break;
+	}
+
+	sched->state.event	= idx;		/* start with min weight */
+	sched->state.weight	= wmin;
+	sched->state.unassigned	= num;
+}
+
+static void perf_sched_save_state(struct perf_sched *sched)
+{
+	if (WARN_ON_ONCE(sched->saved_states >= SCHED_STATES_MAX))
+		return;
+
+	sched->saved[sched->saved_states] = sched->state;
+	sched->saved_states++;
+}
+
+static bool perf_sched_restore_state(struct perf_sched *sched)
+{
+	if (!sched->saved_states)
+		return false;
+
+	sched->saved_states--;
+	sched->state = sched->saved[sched->saved_states];
+
+	/* continue with next counter: */
+	clear_bit(sched->state.counter++, sched->state.used);
+
+	return true;
+}
+
+/*
+ * Select a counter for the current event to schedule. Return true on
+ * success.
+ */
+static bool __perf_sched_find_counter(struct perf_sched *sched)
+{
+	struct event_constraint *c;
+	int idx;
+
+	if (!sched->state.unassigned)
+		return false;
+
+	if (sched->state.event >= sched->max_events)
+		return false;
+
+	c = sched->constraints[sched->state.event];
+	/* Prefer fixed purpose counters */
+	if (c->idxmsk64 & (~0ULL << INTEL_PMC_IDX_FIXED)) {
+		idx = INTEL_PMC_IDX_FIXED;
+		for_each_set_bit_from(idx, c->idxmsk, X86_PMC_IDX_MAX) {
+			if (!__test_and_set_bit(idx, sched->state.used))
+				goto done;
+		}
+	}
+
+	/* Grab the first unused counter starting with idx */
+	idx = sched->state.counter;
+	for_each_set_bit_from(idx, c->idxmsk, INTEL_PMC_IDX_FIXED) {
+		if (!__test_and_set_bit(idx, sched->state.used)) {
+			if (sched->state.nr_gp++ >= sched->max_gp)
+				return false;
+
+			goto done;
+		}
+	}
+
+	return false;
+
+done:
+	sched->state.counter = idx;
+
+	if (c->overlap)
+		perf_sched_save_state(sched);
+
+	return true;
+}
+
+static bool perf_sched_find_counter(struct perf_sched *sched)
+{
+	while (!__perf_sched_find_counter(sched)) {
+		if (!perf_sched_restore_state(sched))
+			return false;
+	}
+
+	return true;
+}
+
+/*
+ * Go through all unassigned events and find the next one to schedule.
+ * Take events with the least weight first. Return true on success.
+ */
+static bool perf_sched_next_event(struct perf_sched *sched)
+{
+	struct event_constraint *c;
+
+	if (!sched->state.unassigned || !--sched->state.unassigned)
+		return false;
+
+	do {
+		/* next event */
+		sched->state.event++;
+		if (sched->state.event >= sched->max_events) {
+			/* next weight */
+			sched->state.event = 0;
+			sched->state.weight++;
+			if (sched->state.weight > sched->max_weight)
+				return false;
+		}
+		c = sched->constraints[sched->state.event];
+	} while (c->weight != sched->state.weight);
+
+	sched->state.counter = 0;	/* start with first counter */
+
+	return true;
+}
+
+/*
+ * Assign a counter for each event.
+ */
+int perf_assign_events(struct event_constraint **constraints, int n,
+			int wmin, int wmax, int gpmax, int *assign)
+{
+	struct perf_sched sched;
+
+	perf_sched_init(&sched, constraints, n, wmin, wmax, gpmax);
+
+	do {
+		if (!perf_sched_find_counter(&sched))
+			break;	/* failed */
+		if (assign)
+			assign[sched.state.event] = sched.state.counter;
+	} while (perf_sched_next_event(&sched));
+
+	return sched.state.unassigned;
+}
+EXPORT_SYMBOL_GPL(perf_assign_events);
+
+int x86_schedule_events(struct cpu_hw_events *cpuc, int n, int *assign)
+{
+	struct event_constraint *c;
+	unsigned long used_mask[BITS_TO_LONGS(X86_PMC_IDX_MAX)];
+	struct perf_event *e;
+	int i, wmin, wmax, unsched = 0;
+	struct hw_perf_event *hwc;
+
+	bitmap_zero(used_mask, X86_PMC_IDX_MAX);
+
+	if (x86_pmu.start_scheduling)
+		x86_pmu.start_scheduling(cpuc);
+
+	for (i = 0, wmin = X86_PMC_IDX_MAX, wmax = 0; i < n; i++) {
+		cpuc->event_constraint[i] = NULL;
+		c = x86_pmu.get_event_constraints(cpuc, i, cpuc->event_list[i]);
+		cpuc->event_constraint[i] = c;
+
+		wmin = min(wmin, c->weight);
+		wmax = max(wmax, c->weight);
+	}
+
+	/*
+	 * fastpath, try to reuse previous register
+	 */
+	for (i = 0; i < n; i++) {
+		hwc = &cpuc->event_list[i]->hw;
+		c = cpuc->event_constraint[i];
+
+		/* never assigned */
+		if (hwc->idx == -1)
+			break;
+
+		/* constraint still honored */
+		if (!test_bit(hwc->idx, c->idxmsk))
+			break;
+
+		/* not already used */
+		if (test_bit(hwc->idx, used_mask))
+			break;
+
+		__set_bit(hwc->idx, used_mask);
+		if (assign)
+			assign[i] = hwc->idx;
+	}
+
+	/* slow path */
+	if (i != n) {
+		int gpmax = x86_pmu.num_counters;
+
+		/*
+		 * Do not allow scheduling of more than half the available
+		 * generic counters.
+		 *
+		 * This helps avoid counter starvation of sibling thread by
+		 * ensuring at most half the counters cannot be in exclusive
+		 * mode. There is no designated counters for the limits. Any
+		 * N/2 counters can be used. This helps with events with
+		 * specific counter constraints.
+		 */
+		if (is_ht_workaround_enabled() && !cpuc->is_fake &&
+		    READ_ONCE(cpuc->excl_cntrs->exclusive_present))
+			gpmax /= 2;
+
+		unsched = perf_assign_events(cpuc->event_constraint, n, wmin,
+					     wmax, gpmax, assign);
+	}
+
+	/*
+	 * In case of success (unsched = 0), mark events as committed,
+	 * so we do not put_constraint() in case new events are added
+	 * and fail to be scheduled
+	 *
+	 * We invoke the lower level commit callback to lock the resource
+	 *
+	 * We do not need to do all of this in case we are called to
+	 * validate an event group (assign == NULL)
+	 */
+	if (!unsched && assign) {
+		for (i = 0; i < n; i++) {
+			e = cpuc->event_list[i];
+			e->hw.flags |= PERF_X86_EVENT_COMMITTED;
+			if (x86_pmu.commit_scheduling)
+				x86_pmu.commit_scheduling(cpuc, i, assign[i]);
+		}
+	} else {
+		for (i = 0; i < n; i++) {
+			e = cpuc->event_list[i];
+			/*
+			 * do not put_constraint() on comitted events,
+			 * because they are good to go
+			 */
+			if ((e->hw.flags & PERF_X86_EVENT_COMMITTED))
+				continue;
+
+			/*
+			 * release events that failed scheduling
+			 */
+			if (x86_pmu.put_event_constraints)
+				x86_pmu.put_event_constraints(cpuc, e);
+		}
+	}
+
+	if (x86_pmu.stop_scheduling)
+		x86_pmu.stop_scheduling(cpuc);
+
+	return unsched ? -EINVAL : 0;
+}
+
+/*
+ * dogrp: true if must collect siblings events (group)
+ * returns total number of events and error code
+ */
+static int collect_events(struct cpu_hw_events *cpuc, struct perf_event *leader, bool dogrp)
+{
+	struct perf_event *event;
+	int n, max_count;
+
+	max_count = x86_pmu.num_counters + x86_pmu.num_counters_fixed;
+
+	/* current number of events already accepted */
+	n = cpuc->n_events;
+
+	if (is_x86_event(leader)) {
+		if (n >= max_count)
+			return -EINVAL;
+		cpuc->event_list[n] = leader;
+		n++;
+	}
+	if (!dogrp)
+		return n;
+
+	list_for_each_entry(event, &leader->sibling_list, group_entry) {
+		if (!is_x86_event(event) ||
+		    event->state <= PERF_EVENT_STATE_OFF)
+			continue;
+
+		if (n >= max_count)
+			return -EINVAL;
+
+		cpuc->event_list[n] = event;
+		n++;
+	}
+	return n;
+}
+
+static inline void x86_assign_hw_event(struct perf_event *event,
+				struct cpu_hw_events *cpuc, int i)
+{
+	struct hw_perf_event *hwc = &event->hw;
+
+	hwc->idx = cpuc->assign[i];
+	hwc->last_cpu = smp_processor_id();
+	hwc->last_tag = ++cpuc->tags[i];
+
+	if (hwc->idx == INTEL_PMC_IDX_FIXED_BTS) {
+		hwc->config_base = 0;
+		hwc->event_base	= 0;
+	} else if (hwc->idx >= INTEL_PMC_IDX_FIXED) {
+		hwc->config_base = MSR_ARCH_PERFMON_FIXED_CTR_CTRL;
+		hwc->event_base = MSR_ARCH_PERFMON_FIXED_CTR0 + (hwc->idx - INTEL_PMC_IDX_FIXED);
+		hwc->event_base_rdpmc = (hwc->idx - INTEL_PMC_IDX_FIXED) | 1<<30;
+	} else {
+		hwc->config_base = x86_pmu_config_addr(hwc->idx);
+		hwc->event_base  = x86_pmu_event_addr(hwc->idx);
+		hwc->event_base_rdpmc = x86_pmu_rdpmc_index(hwc->idx);
+	}
+}
+
+static inline int match_prev_assignment(struct hw_perf_event *hwc,
+					struct cpu_hw_events *cpuc,
+					int i)
+{
+	return hwc->idx == cpuc->assign[i] &&
+		hwc->last_cpu == smp_processor_id() &&
+		hwc->last_tag == cpuc->tags[i];
+}
+
+static void x86_pmu_start(struct perf_event *event, int flags);
+
+static void x86_pmu_enable(struct pmu *pmu)
+{
+	struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
+	struct perf_event *event;
+	struct hw_perf_event *hwc;
+	int i, added = cpuc->n_added;
+
+	if (!x86_pmu_initialized())
+		return;
+
+	if (cpuc->enabled)
+		return;
+
+	if (cpuc->n_added) {
+		int n_running = cpuc->n_events - cpuc->n_added;
+		/*
+		 * apply assignment obtained either from
+		 * hw_perf_group_sched_in() or x86_pmu_enable()
+		 *
+		 * step1: save events moving to new counters
+		 */
+		for (i = 0; i < n_running; i++) {
+			event = cpuc->event_list[i];
+			hwc = &event->hw;
+
+			/*
+			 * we can avoid reprogramming counter if:
+			 * - assigned same counter as last time
+			 * - running on same CPU as last time
+			 * - no other event has used the counter since
+			 */
+			if (hwc->idx == -1 ||
+			    match_prev_assignment(hwc, cpuc, i))
+				continue;
+
+			/*
+			 * Ensure we don't accidentally enable a stopped
+			 * counter simply because we rescheduled.
+			 */
+			if (hwc->state & PERF_HES_STOPPED)
+				hwc->state |= PERF_HES_ARCH;
+
+			x86_pmu_stop(event, PERF_EF_UPDATE);
+		}
+
+		/*
+		 * step2: reprogram moved events into new counters
+		 */
+		for (i = 0; i < cpuc->n_events; i++) {
+			event = cpuc->event_list[i];
+			hwc = &event->hw;
+
+			if (!match_prev_assignment(hwc, cpuc, i))
+				x86_assign_hw_event(event, cpuc, i);
+			else if (i < n_running)
+				continue;
+
+			if (hwc->state & PERF_HES_ARCH)
+				continue;
+
+			x86_pmu_start(event, PERF_EF_RELOAD);
+		}
+		cpuc->n_added = 0;
+		perf_events_lapic_init();
+	}
+
+	cpuc->enabled = 1;
+	barrier();
+
+	x86_pmu.enable_all(added);
+}
+
+static DEFINE_PER_CPU(u64 [X86_PMC_IDX_MAX], pmc_prev_left);
+
+/*
+ * Set the next IRQ period, based on the hwc->period_left value.
+ * To be called with the event disabled in hw:
+ */
+int x86_perf_event_set_period(struct perf_event *event)
+{
+	struct hw_perf_event *hwc = &event->hw;
+	s64 left = local64_read(&hwc->period_left);
+	s64 period = hwc->sample_period;
+	int ret = 0, idx = hwc->idx;
+
+	if (idx == INTEL_PMC_IDX_FIXED_BTS)
+		return 0;
+
+	/*
+	 * If we are way outside a reasonable range then just skip forward:
+	 */
+	if (unlikely(left <= -period)) {
+		left = period;
+		local64_set(&hwc->period_left, left);
+		hwc->last_period = period;
+		ret = 1;
+	}
+
+	if (unlikely(left <= 0)) {
+		left += period;
+		local64_set(&hwc->period_left, left);
+		hwc->last_period = period;
+		ret = 1;
+	}
+	/*
+	 * Quirk: certain CPUs dont like it if just 1 hw_event is left:
+	 */
+	if (unlikely(left < 2))
+		left = 2;
+
+	if (left > x86_pmu.max_period)
+		left = x86_pmu.max_period;
+
+	if (x86_pmu.limit_period)
+		left = x86_pmu.limit_period(event, left);
+
+	per_cpu(pmc_prev_left[idx], smp_processor_id()) = left;
+
+	if (!(hwc->flags & PERF_X86_EVENT_AUTO_RELOAD) ||
+	    local64_read(&hwc->prev_count) != (u64)-left) {
+		/*
+		 * The hw event starts counting from this event offset,
+		 * mark it to be able to extra future deltas:
+		 */
+		local64_set(&hwc->prev_count, (u64)-left);
+
+		wrmsrl(hwc->event_base, (u64)(-left) & x86_pmu.cntval_mask);
+	}
+
+	/*
+	 * Due to erratum on certan cpu we need
+	 * a second write to be sure the register
+	 * is updated properly
+	 */
+	if (x86_pmu.perfctr_second_write) {
+		wrmsrl(hwc->event_base,
+			(u64)(-left) & x86_pmu.cntval_mask);
+	}
+
+	perf_event_update_userpage(event);
+
+	return ret;
+}
+
+void x86_pmu_enable_event(struct perf_event *event)
+{
+	if (__this_cpu_read(cpu_hw_events.enabled))
+		__x86_pmu_enable_event(&event->hw,
+				       ARCH_PERFMON_EVENTSEL_ENABLE);
+}
+
+/*
+ * Add a single event to the PMU.
+ *
+ * The event is added to the group of enabled events
+ * but only if it can be scehduled with existing events.
+ */
+static int x86_pmu_add(struct perf_event *event, int flags)
+{
+	struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
+	struct hw_perf_event *hwc;
+	int assign[X86_PMC_IDX_MAX];
+	int n, n0, ret;
+
+	hwc = &event->hw;
+
+	n0 = cpuc->n_events;
+	ret = n = collect_events(cpuc, event, false);
+	if (ret < 0)
+		goto out;
+
+	hwc->state = PERF_HES_UPTODATE | PERF_HES_STOPPED;
+	if (!(flags & PERF_EF_START))
+		hwc->state |= PERF_HES_ARCH;
+
+	/*
+	 * If group events scheduling transaction was started,
+	 * skip the schedulability test here, it will be performed
+	 * at commit time (->commit_txn) as a whole.
+	 */
+	if (cpuc->txn_flags & PERF_PMU_TXN_ADD)
+		goto done_collect;
+
+	ret = x86_pmu.schedule_events(cpuc, n, assign);
+	if (ret)
+		goto out;
+	/*
+	 * copy new assignment, now we know it is possible
+	 * will be used by hw_perf_enable()
+	 */
+	memcpy(cpuc->assign, assign, n*sizeof(int));
+
+done_collect:
+	/*
+	 * Commit the collect_events() state. See x86_pmu_del() and
+	 * x86_pmu_*_txn().
+	 */
+	cpuc->n_events = n;
+	cpuc->n_added += n - n0;
+	cpuc->n_txn += n - n0;
+
+	ret = 0;
+out:
+	return ret;
+}
+
+static void x86_pmu_start(struct perf_event *event, int flags)
+{
+	struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
+	int idx = event->hw.idx;
+
+	if (WARN_ON_ONCE(!(event->hw.state & PERF_HES_STOPPED)))
+		return;
+
+	if (WARN_ON_ONCE(idx == -1))
+		return;
+
+	if (flags & PERF_EF_RELOAD) {
+		WARN_ON_ONCE(!(event->hw.state & PERF_HES_UPTODATE));
+		x86_perf_event_set_period(event);
+	}
+
+	event->hw.state = 0;
+
+	cpuc->events[idx] = event;
+	__set_bit(idx, cpuc->active_mask);
+	__set_bit(idx, cpuc->running);
+	x86_pmu.enable(event);
+	perf_event_update_userpage(event);
+}
+
+void perf_event_print_debug(void)
+{
+	u64 ctrl, status, overflow, pmc_ctrl, pmc_count, prev_left, fixed;
+	u64 pebs, debugctl;
+	struct cpu_hw_events *cpuc;
+	unsigned long flags;
+	int cpu, idx;
+
+	if (!x86_pmu.num_counters)
+		return;
+
+	local_irq_save(flags);
+
+	cpu = smp_processor_id();
+	cpuc = &per_cpu(cpu_hw_events, cpu);
+
+	if (x86_pmu.version >= 2) {
+		rdmsrl(MSR_CORE_PERF_GLOBAL_CTRL, ctrl);
+		rdmsrl(MSR_CORE_PERF_GLOBAL_STATUS, status);
+		rdmsrl(MSR_CORE_PERF_GLOBAL_OVF_CTRL, overflow);
+		rdmsrl(MSR_ARCH_PERFMON_FIXED_CTR_CTRL, fixed);
+
+		pr_info("\n");
+		pr_info("CPU#%d: ctrl:       %016llx\n", cpu, ctrl);
+		pr_info("CPU#%d: status:     %016llx\n", cpu, status);
+		pr_info("CPU#%d: overflow:   %016llx\n", cpu, overflow);
+		pr_info("CPU#%d: fixed:      %016llx\n", cpu, fixed);
+		if (x86_pmu.pebs_constraints) {
+			rdmsrl(MSR_IA32_PEBS_ENABLE, pebs);
+			pr_info("CPU#%d: pebs:       %016llx\n", cpu, pebs);
+		}
+		if (x86_pmu.lbr_nr) {
+			rdmsrl(MSR_IA32_DEBUGCTLMSR, debugctl);
+			pr_info("CPU#%d: debugctl:   %016llx\n", cpu, debugctl);
+		}
+	}
+	pr_info("CPU#%d: active:     %016llx\n", cpu, *(u64 *)cpuc->active_mask);
+
+	for (idx = 0; idx < x86_pmu.num_counters; idx++) {
+		rdmsrl(x86_pmu_config_addr(idx), pmc_ctrl);
+		rdmsrl(x86_pmu_event_addr(idx), pmc_count);
+
+		prev_left = per_cpu(pmc_prev_left[idx], cpu);
+
+		pr_info("CPU#%d:   gen-PMC%d ctrl:  %016llx\n",
+			cpu, idx, pmc_ctrl);
+		pr_info("CPU#%d:   gen-PMC%d count: %016llx\n",
+			cpu, idx, pmc_count);
+		pr_info("CPU#%d:   gen-PMC%d left:  %016llx\n",
+			cpu, idx, prev_left);
+	}
+	for (idx = 0; idx < x86_pmu.num_counters_fixed; idx++) {
+		rdmsrl(MSR_ARCH_PERFMON_FIXED_CTR0 + idx, pmc_count);
+
+		pr_info("CPU#%d: fixed-PMC%d count: %016llx\n",
+			cpu, idx, pmc_count);
+	}
+	local_irq_restore(flags);
+}
+
+void x86_pmu_stop(struct perf_event *event, int flags)
+{
+	struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
+	struct hw_perf_event *hwc = &event->hw;
+
+	if (__test_and_clear_bit(hwc->idx, cpuc->active_mask)) {
+		x86_pmu.disable(event);
+		cpuc->events[hwc->idx] = NULL;
+		WARN_ON_ONCE(hwc->state & PERF_HES_STOPPED);
+		hwc->state |= PERF_HES_STOPPED;
+	}
+
+	if ((flags & PERF_EF_UPDATE) && !(hwc->state & PERF_HES_UPTODATE)) {
+		/*
+		 * Drain the remaining delta count out of a event
+		 * that we are disabling:
+		 */
+		x86_perf_event_update(event);
+		hwc->state |= PERF_HES_UPTODATE;
+	}
+}
+
+static void x86_pmu_del(struct perf_event *event, int flags)
+{
+	struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
+	int i;
+
+	/*
+	 * event is descheduled
+	 */
+	event->hw.flags &= ~PERF_X86_EVENT_COMMITTED;
+
+	/*
+	 * If we're called during a txn, we don't need to do anything.
+	 * The events never got scheduled and ->cancel_txn will truncate
+	 * the event_list.
+	 *
+	 * XXX assumes any ->del() called during a TXN will only be on
+	 * an event added during that same TXN.
+	 */
+	if (cpuc->txn_flags & PERF_PMU_TXN_ADD)
+		return;
+
+	/*
+	 * Not a TXN, therefore cleanup properly.
+	 */
+	x86_pmu_stop(event, PERF_EF_UPDATE);
+
+	for (i = 0; i < cpuc->n_events; i++) {
+		if (event == cpuc->event_list[i])
+			break;
+	}
+
+	if (WARN_ON_ONCE(i == cpuc->n_events)) /* called ->del() without ->add() ? */
+		return;
+
+	/* If we have a newly added event; make sure to decrease n_added. */
+	if (i >= cpuc->n_events - cpuc->n_added)
+		--cpuc->n_added;
+
+	if (x86_pmu.put_event_constraints)
+		x86_pmu.put_event_constraints(cpuc, event);
+
+	/* Delete the array entry. */
+	while (++i < cpuc->n_events) {
+		cpuc->event_list[i-1] = cpuc->event_list[i];
+		cpuc->event_constraint[i-1] = cpuc->event_constraint[i];
+	}
+	--cpuc->n_events;
+
+	perf_event_update_userpage(event);
+}
+
+int x86_pmu_handle_irq(struct pt_regs *regs)
+{
+	struct perf_sample_data data;
+	struct cpu_hw_events *cpuc;
+	struct perf_event *event;
+	int idx, handled = 0;
+	u64 val;
+
+	cpuc = this_cpu_ptr(&cpu_hw_events);
+
+	/*
+	 * Some chipsets need to unmask the LVTPC in a particular spot
+	 * inside the nmi handler.  As a result, the unmasking was pushed
+	 * into all the nmi handlers.
+	 *
+	 * This generic handler doesn't seem to have any issues where the
+	 * unmasking occurs so it was left at the top.
+	 */
+	apic_write(APIC_LVTPC, APIC_DM_NMI);
+
+	for (idx = 0; idx < x86_pmu.num_counters; idx++) {
+		if (!test_bit(idx, cpuc->active_mask)) {
+			/*
+			 * Though we deactivated the counter some cpus
+			 * might still deliver spurious interrupts still
+			 * in flight. Catch them:
+			 */
+			if (__test_and_clear_bit(idx, cpuc->running))
+				handled++;
+			continue;
+		}
+
+		event = cpuc->events[idx];
+
+		val = x86_perf_event_update(event);
+		if (val & (1ULL << (x86_pmu.cntval_bits - 1)))
+			continue;
+
+		/*
+		 * event overflow
+		 */
+		handled++;
+		perf_sample_data_init(&data, 0, event->hw.last_period);
+
+		if (!x86_perf_event_set_period(event))
+			continue;
+
+		if (perf_event_overflow(event, &data, regs))
+			x86_pmu_stop(event, 0);
+	}
+
+	if (handled)
+		inc_irq_stat(apic_perf_irqs);
+
+	return handled;
+}
+
+void perf_events_lapic_init(void)
+{
+	if (!x86_pmu.apic || !x86_pmu_initialized())
+		return;
+
+	/*
+	 * Always use NMI for PMU
+	 */
+	apic_write(APIC_LVTPC, APIC_DM_NMI);
+}
+
+static int
+perf_event_nmi_handler(unsigned int cmd, struct pt_regs *regs)
+{
+	u64 start_clock;
+	u64 finish_clock;
+	int ret;
+
+	/*
+	 * All PMUs/events that share this PMI handler should make sure to
+	 * increment active_events for their events.
+	 */
+	if (!atomic_read(&active_events))
+		return NMI_DONE;
+
+	start_clock = sched_clock();
+	ret = x86_pmu.handle_irq(regs);
+	finish_clock = sched_clock();
+
+	perf_sample_event_took(finish_clock - start_clock);
+
+	return ret;
+}
+NOKPROBE_SYMBOL(perf_event_nmi_handler);
+
+struct event_constraint emptyconstraint;
+struct event_constraint unconstrained;
+
+static int
+x86_pmu_notifier(struct notifier_block *self, unsigned long action, void *hcpu)
+{
+	unsigned int cpu = (long)hcpu;
+	struct cpu_hw_events *cpuc = &per_cpu(cpu_hw_events, cpu);
+	int i, ret = NOTIFY_OK;
+
+	switch (action & ~CPU_TASKS_FROZEN) {
+	case CPU_UP_PREPARE:
+		for (i = 0 ; i < X86_PERF_KFREE_MAX; i++)
+			cpuc->kfree_on_online[i] = NULL;
+		if (x86_pmu.cpu_prepare)
+			ret = x86_pmu.cpu_prepare(cpu);
+		break;
+
+	case CPU_STARTING:
+		if (x86_pmu.cpu_starting)
+			x86_pmu.cpu_starting(cpu);
+		break;
+
+	case CPU_ONLINE:
+		for (i = 0 ; i < X86_PERF_KFREE_MAX; i++) {
+			kfree(cpuc->kfree_on_online[i]);
+			cpuc->kfree_on_online[i] = NULL;
+		}
+		break;
+
+	case CPU_DYING:
+		if (x86_pmu.cpu_dying)
+			x86_pmu.cpu_dying(cpu);
+		break;
+
+	case CPU_UP_CANCELED:
+	case CPU_DEAD:
+		if (x86_pmu.cpu_dead)
+			x86_pmu.cpu_dead(cpu);
+		break;
+
+	default:
+		break;
+	}
+
+	return ret;
+}
+
+static void __init pmu_check_apic(void)
+{
+	if (cpu_has_apic)
+		return;
+
+	x86_pmu.apic = 0;
+	pr_info("no APIC, boot with the \"lapic\" boot parameter to force-enable it.\n");
+	pr_info("no hardware sampling interrupt available.\n");
+
+	/*
+	 * If we have a PMU initialized but no APIC
+	 * interrupts, we cannot sample hardware
+	 * events (user-space has to fall back and
+	 * sample via a hrtimer based software event):
+	 */
+	pmu.capabilities |= PERF_PMU_CAP_NO_INTERRUPT;
+
+}
+
+static struct attribute_group x86_pmu_format_group = {
+	.name = "format",
+	.attrs = NULL,
+};
+
+/*
+ * Remove all undefined events (x86_pmu.event_map(id) == 0)
+ * out of events_attr attributes.
+ */
+static void __init filter_events(struct attribute **attrs)
+{
+	struct device_attribute *d;
+	struct perf_pmu_events_attr *pmu_attr;
+	int i, j;
+
+	for (i = 0; attrs[i]; i++) {
+		d = (struct device_attribute *)attrs[i];
+		pmu_attr = container_of(d, struct perf_pmu_events_attr, attr);
+		/* str trumps id */
+		if (pmu_attr->event_str)
+			continue;
+		if (x86_pmu.event_map(i))
+			continue;
+
+		for (j = i; attrs[j]; j++)
+			attrs[j] = attrs[j + 1];
+
+		/* Check the shifted attr. */
+		i--;
+	}
+}
+
+/* Merge two pointer arrays */
+__init struct attribute **merge_attr(struct attribute **a, struct attribute **b)
+{
+	struct attribute **new;
+	int j, i;
+
+	for (j = 0; a[j]; j++)
+		;
+	for (i = 0; b[i]; i++)
+		j++;
+	j++;
+
+	new = kmalloc(sizeof(struct attribute *) * j, GFP_KERNEL);
+	if (!new)
+		return NULL;
+
+	j = 0;
+	for (i = 0; a[i]; i++)
+		new[j++] = a[i];
+	for (i = 0; b[i]; i++)
+		new[j++] = b[i];
+	new[j] = NULL;
+
+	return new;
+}
+
+ssize_t events_sysfs_show(struct device *dev, struct device_attribute *attr,
+			  char *page)
+{
+	struct perf_pmu_events_attr *pmu_attr = \
+		container_of(attr, struct perf_pmu_events_attr, attr);
+	u64 config = x86_pmu.event_map(pmu_attr->id);
+
+	/* string trumps id */
+	if (pmu_attr->event_str)
+		return sprintf(page, "%s", pmu_attr->event_str);
+
+	return x86_pmu.events_sysfs_show(page, config);
+}
+
+EVENT_ATTR(cpu-cycles,			CPU_CYCLES		);
+EVENT_ATTR(instructions,		INSTRUCTIONS		);
+EVENT_ATTR(cache-references,		CACHE_REFERENCES	);
+EVENT_ATTR(cache-misses, 		CACHE_MISSES		);
+EVENT_ATTR(branch-instructions,		BRANCH_INSTRUCTIONS	);
+EVENT_ATTR(branch-misses,		BRANCH_MISSES		);
+EVENT_ATTR(bus-cycles,			BUS_CYCLES		);
+EVENT_ATTR(stalled-cycles-frontend,	STALLED_CYCLES_FRONTEND	);
+EVENT_ATTR(stalled-cycles-backend,	STALLED_CYCLES_BACKEND	);
+EVENT_ATTR(ref-cycles,			REF_CPU_CYCLES		);
+
+static struct attribute *empty_attrs;
+
+static struct attribute *events_attr[] = {
+	EVENT_PTR(CPU_CYCLES),
+	EVENT_PTR(INSTRUCTIONS),
+	EVENT_PTR(CACHE_REFERENCES),
+	EVENT_PTR(CACHE_MISSES),
+	EVENT_PTR(BRANCH_INSTRUCTIONS),
+	EVENT_PTR(BRANCH_MISSES),
+	EVENT_PTR(BUS_CYCLES),
+	EVENT_PTR(STALLED_CYCLES_FRONTEND),
+	EVENT_PTR(STALLED_CYCLES_BACKEND),
+	EVENT_PTR(REF_CPU_CYCLES),
+	NULL,
+};
+
+static struct attribute_group x86_pmu_events_group = {
+	.name = "events",
+	.attrs = events_attr,
+};
+
+ssize_t x86_event_sysfs_show(char *page, u64 config, u64 event)
+{
+	u64 umask  = (config & ARCH_PERFMON_EVENTSEL_UMASK) >> 8;
+	u64 cmask  = (config & ARCH_PERFMON_EVENTSEL_CMASK) >> 24;
+	bool edge  = (config & ARCH_PERFMON_EVENTSEL_EDGE);
+	bool pc    = (config & ARCH_PERFMON_EVENTSEL_PIN_CONTROL);
+	bool any   = (config & ARCH_PERFMON_EVENTSEL_ANY);
+	bool inv   = (config & ARCH_PERFMON_EVENTSEL_INV);
+	ssize_t ret;
+
+	/*
+	* We have whole page size to spend and just little data
+	* to write, so we can safely use sprintf.
+	*/
+	ret = sprintf(page, "event=0x%02llx", event);
+
+	if (umask)
+		ret += sprintf(page + ret, ",umask=0x%02llx", umask);
+
+	if (edge)
+		ret += sprintf(page + ret, ",edge");
+
+	if (pc)
+		ret += sprintf(page + ret, ",pc");
+
+	if (any)
+		ret += sprintf(page + ret, ",any");
+
+	if (inv)
+		ret += sprintf(page + ret, ",inv");
+
+	if (cmask)
+		ret += sprintf(page + ret, ",cmask=0x%02llx", cmask);
+
+	ret += sprintf(page + ret, "\n");
+
+	return ret;
+}
+
+static int __init init_hw_perf_events(void)
+{
+	struct x86_pmu_quirk *quirk;
+	int err;
+
+	pr_info("Performance Events: ");
+
+	switch (boot_cpu_data.x86_vendor) {
+	case X86_VENDOR_INTEL:
+		err = intel_pmu_init();
+		break;
+	case X86_VENDOR_AMD:
+		err = amd_pmu_init();
+		break;
+	default:
+		err = -ENOTSUPP;
+	}
+	if (err != 0) {
+		pr_cont("no PMU driver, software events only.\n");
+		return 0;
+	}
+
+	pmu_check_apic();
+
+	/* sanity check that the hardware exists or is emulated */
+	if (!check_hw_exists())
+		return 0;
+
+	pr_cont("%s PMU driver.\n", x86_pmu.name);
+
+	x86_pmu.attr_rdpmc = 1; /* enable userspace RDPMC usage by default */
+
+	for (quirk = x86_pmu.quirks; quirk; quirk = quirk->next)
+		quirk->func();
+
+	if (!x86_pmu.intel_ctrl)
+		x86_pmu.intel_ctrl = (1 << x86_pmu.num_counters) - 1;
+
+	perf_events_lapic_init();
+	register_nmi_handler(NMI_LOCAL, perf_event_nmi_handler, 0, "PMI");
+
+	unconstrained = (struct event_constraint)
+		__EVENT_CONSTRAINT(0, (1ULL << x86_pmu.num_counters) - 1,
+				   0, x86_pmu.num_counters, 0, 0);
+
+	x86_pmu_format_group.attrs = x86_pmu.format_attrs;
+
+	if (x86_pmu.event_attrs)
+		x86_pmu_events_group.attrs = x86_pmu.event_attrs;
+
+	if (!x86_pmu.events_sysfs_show)
+		x86_pmu_events_group.attrs = &empty_attrs;
+	else
+		filter_events(x86_pmu_events_group.attrs);
+
+	if (x86_pmu.cpu_events) {
+		struct attribute **tmp;
+
+		tmp = merge_attr(x86_pmu_events_group.attrs, x86_pmu.cpu_events);
+		if (!WARN_ON(!tmp))
+			x86_pmu_events_group.attrs = tmp;
+	}
+
+	pr_info("... version:                %d\n",     x86_pmu.version);
+	pr_info("... bit width:              %d\n",     x86_pmu.cntval_bits);
+	pr_info("... generic registers:      %d\n",     x86_pmu.num_counters);
+	pr_info("... value mask:             %016Lx\n", x86_pmu.cntval_mask);
+	pr_info("... max period:             %016Lx\n", x86_pmu.max_period);
+	pr_info("... fixed-purpose events:   %d\n",     x86_pmu.num_counters_fixed);
+	pr_info("... event mask:             %016Lx\n", x86_pmu.intel_ctrl);
+
+	perf_pmu_register(&pmu, "cpu", PERF_TYPE_RAW);
+	perf_cpu_notifier(x86_pmu_notifier);
+
+	return 0;
+}
+early_initcall(init_hw_perf_events);
+
+static inline void x86_pmu_read(struct perf_event *event)
+{
+	x86_perf_event_update(event);
+}
+
+/*
+ * Start group events scheduling transaction
+ * Set the flag to make pmu::enable() not perform the
+ * schedulability test, it will be performed at commit time
+ *
+ * We only support PERF_PMU_TXN_ADD transactions. Save the
+ * transaction flags but otherwise ignore non-PERF_PMU_TXN_ADD
+ * transactions.
+ */
+static void x86_pmu_start_txn(struct pmu *pmu, unsigned int txn_flags)
+{
+	struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
+
+	WARN_ON_ONCE(cpuc->txn_flags);		/* txn already in flight */
+
+	cpuc->txn_flags = txn_flags;
+	if (txn_flags & ~PERF_PMU_TXN_ADD)
+		return;
+
+	perf_pmu_disable(pmu);
+	__this_cpu_write(cpu_hw_events.n_txn, 0);
+}
+
+/*
+ * Stop group events scheduling transaction
+ * Clear the flag and pmu::enable() will perform the
+ * schedulability test.
+ */
+static void x86_pmu_cancel_txn(struct pmu *pmu)
+{
+	unsigned int txn_flags;
+	struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
+
+	WARN_ON_ONCE(!cpuc->txn_flags);	/* no txn in flight */
+
+	txn_flags = cpuc->txn_flags;
+	cpuc->txn_flags = 0;
+	if (txn_flags & ~PERF_PMU_TXN_ADD)
+		return;
+
+	/*
+	 * Truncate collected array by the number of events added in this
+	 * transaction. See x86_pmu_add() and x86_pmu_*_txn().
+	 */
+	__this_cpu_sub(cpu_hw_events.n_added, __this_cpu_read(cpu_hw_events.n_txn));
+	__this_cpu_sub(cpu_hw_events.n_events, __this_cpu_read(cpu_hw_events.n_txn));
+	perf_pmu_enable(pmu);
+}
+
+/*
+ * Commit group events scheduling transaction
+ * Perform the group schedulability test as a whole
+ * Return 0 if success
+ *
+ * Does not cancel the transaction on failure; expects the caller to do this.
+ */
+static int x86_pmu_commit_txn(struct pmu *pmu)
+{
+	struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
+	int assign[X86_PMC_IDX_MAX];
+	int n, ret;
+
+	WARN_ON_ONCE(!cpuc->txn_flags);	/* no txn in flight */
+
+	if (cpuc->txn_flags & ~PERF_PMU_TXN_ADD) {
+		cpuc->txn_flags = 0;
+		return 0;
+	}
+
+	n = cpuc->n_events;
+
+	if (!x86_pmu_initialized())
+		return -EAGAIN;
+
+	ret = x86_pmu.schedule_events(cpuc, n, assign);
+	if (ret)
+		return ret;
+
+	/*
+	 * copy new assignment, now we know it is possible
+	 * will be used by hw_perf_enable()
+	 */
+	memcpy(cpuc->assign, assign, n*sizeof(int));
+
+	cpuc->txn_flags = 0;
+	perf_pmu_enable(pmu);
+	return 0;
+}
+/*
+ * a fake_cpuc is used to validate event groups. Due to
+ * the extra reg logic, we need to also allocate a fake
+ * per_core and per_cpu structure. Otherwise, group events
+ * using extra reg may conflict without the kernel being
+ * able to catch this when the last event gets added to
+ * the group.
+ */
+static void free_fake_cpuc(struct cpu_hw_events *cpuc)
+{
+	kfree(cpuc->shared_regs);
+	kfree(cpuc);
+}
+
+static struct cpu_hw_events *allocate_fake_cpuc(void)
+{
+	struct cpu_hw_events *cpuc;
+	int cpu = raw_smp_processor_id();
+
+	cpuc = kzalloc(sizeof(*cpuc), GFP_KERNEL);
+	if (!cpuc)
+		return ERR_PTR(-ENOMEM);
+
+	/* only needed, if we have extra_regs */
+	if (x86_pmu.extra_regs) {
+		cpuc->shared_regs = allocate_shared_regs(cpu);
+		if (!cpuc->shared_regs)
+			goto error;
+	}
+	cpuc->is_fake = 1;
+	return cpuc;
+error:
+	free_fake_cpuc(cpuc);
+	return ERR_PTR(-ENOMEM);
+}
+
+/*
+ * validate that we can schedule this event
+ */
+static int validate_event(struct perf_event *event)
+{
+	struct cpu_hw_events *fake_cpuc;
+	struct event_constraint *c;
+	int ret = 0;
+
+	fake_cpuc = allocate_fake_cpuc();
+	if (IS_ERR(fake_cpuc))
+		return PTR_ERR(fake_cpuc);
+
+	c = x86_pmu.get_event_constraints(fake_cpuc, -1, event);
+
+	if (!c || !c->weight)
+		ret = -EINVAL;
+
+	if (x86_pmu.put_event_constraints)
+		x86_pmu.put_event_constraints(fake_cpuc, event);
+
+	free_fake_cpuc(fake_cpuc);
+
+	return ret;
+}
+
+/*
+ * validate a single event group
+ *
+ * validation include:
+ *	- check events are compatible which each other
+ *	- events do not compete for the same counter
+ *	- number of events <= number of counters
+ *
+ * validation ensures the group can be loaded onto the
+ * PMU if it was the only group available.
+ */
+static int validate_group(struct perf_event *event)
+{
+	struct perf_event *leader = event->group_leader;
+	struct cpu_hw_events *fake_cpuc;
+	int ret = -EINVAL, n;
+
+	fake_cpuc = allocate_fake_cpuc();
+	if (IS_ERR(fake_cpuc))
+		return PTR_ERR(fake_cpuc);
+	/*
+	 * the event is not yet connected with its
+	 * siblings therefore we must first collect
+	 * existing siblings, then add the new event
+	 * before we can simulate the scheduling
+	 */
+	n = collect_events(fake_cpuc, leader, true);
+	if (n < 0)
+		goto out;
+
+	fake_cpuc->n_events = n;
+	n = collect_events(fake_cpuc, event, false);
+	if (n < 0)
+		goto out;
+
+	fake_cpuc->n_events = n;
+
+	ret = x86_pmu.schedule_events(fake_cpuc, n, NULL);
+
+out:
+	free_fake_cpuc(fake_cpuc);
+	return ret;
+}
+
+static int x86_pmu_event_init(struct perf_event *event)
+{
+	struct pmu *tmp;
+	int err;
+
+	switch (event->attr.type) {
+	case PERF_TYPE_RAW:
+	case PERF_TYPE_HARDWARE:
+	case PERF_TYPE_HW_CACHE:
+		break;
+
+	default:
+		return -ENOENT;
+	}
+
+	err = __x86_pmu_event_init(event);
+	if (!err) {
+		/*
+		 * we temporarily connect event to its pmu
+		 * such that validate_group() can classify
+		 * it as an x86 event using is_x86_event()
+		 */
+		tmp = event->pmu;
+		event->pmu = &pmu;
+
+		if (event->group_leader != event)
+			err = validate_group(event);
+		else
+			err = validate_event(event);
+
+		event->pmu = tmp;
+	}
+	if (err) {
+		if (event->destroy)
+			event->destroy(event);
+	}
+
+	if (ACCESS_ONCE(x86_pmu.attr_rdpmc))
+		event->hw.flags |= PERF_X86_EVENT_RDPMC_ALLOWED;
+
+	return err;
+}
+
+static void refresh_pce(void *ignored)
+{
+	if (current->mm)
+		load_mm_cr4(current->mm);
+}
+
+static void x86_pmu_event_mapped(struct perf_event *event)
+{
+	if (!(event->hw.flags & PERF_X86_EVENT_RDPMC_ALLOWED))
+		return;
+
+	if (atomic_inc_return(&current->mm->context.perf_rdpmc_allowed) == 1)
+		on_each_cpu_mask(mm_cpumask(current->mm), refresh_pce, NULL, 1);
+}
+
+static void x86_pmu_event_unmapped(struct perf_event *event)
+{
+	if (!current->mm)
+		return;
+
+	if (!(event->hw.flags & PERF_X86_EVENT_RDPMC_ALLOWED))
+		return;
+
+	if (atomic_dec_and_test(&current->mm->context.perf_rdpmc_allowed))
+		on_each_cpu_mask(mm_cpumask(current->mm), refresh_pce, NULL, 1);
+}
+
+static int x86_pmu_event_idx(struct perf_event *event)
+{
+	int idx = event->hw.idx;
+
+	if (!(event->hw.flags & PERF_X86_EVENT_RDPMC_ALLOWED))
+		return 0;
+
+	if (x86_pmu.num_counters_fixed && idx >= INTEL_PMC_IDX_FIXED) {
+		idx -= INTEL_PMC_IDX_FIXED;
+		idx |= 1 << 30;
+	}
+
+	return idx + 1;
+}
+
+static ssize_t get_attr_rdpmc(struct device *cdev,
+			      struct device_attribute *attr,
+			      char *buf)
+{
+	return snprintf(buf, 40, "%d\n", x86_pmu.attr_rdpmc);
+}
+
+static ssize_t set_attr_rdpmc(struct device *cdev,
+			      struct device_attribute *attr,
+			      const char *buf, size_t count)
+{
+	unsigned long val;
+	ssize_t ret;
+
+	ret = kstrtoul(buf, 0, &val);
+	if (ret)
+		return ret;
+
+	if (val > 2)
+		return -EINVAL;
+
+	if (x86_pmu.attr_rdpmc_broken)
+		return -ENOTSUPP;
+
+	if ((val == 2) != (x86_pmu.attr_rdpmc == 2)) {
+		/*
+		 * Changing into or out of always available, aka
+		 * perf-event-bypassing mode.  This path is extremely slow,
+		 * but only root can trigger it, so it's okay.
+		 */
+		if (val == 2)
+			static_key_slow_inc(&rdpmc_always_available);
+		else
+			static_key_slow_dec(&rdpmc_always_available);
+		on_each_cpu(refresh_pce, NULL, 1);
+	}
+
+	x86_pmu.attr_rdpmc = val;
+
+	return count;
+}
+
+static DEVICE_ATTR(rdpmc, S_IRUSR | S_IWUSR, get_attr_rdpmc, set_attr_rdpmc);
+
+static struct attribute *x86_pmu_attrs[] = {
+	&dev_attr_rdpmc.attr,
+	NULL,
+};
+
+static struct attribute_group x86_pmu_attr_group = {
+	.attrs = x86_pmu_attrs,
+};
+
+static const struct attribute_group *x86_pmu_attr_groups[] = {
+	&x86_pmu_attr_group,
+	&x86_pmu_format_group,
+	&x86_pmu_events_group,
+	NULL,
+};
+
+static void x86_pmu_sched_task(struct perf_event_context *ctx, bool sched_in)
+{
+	if (x86_pmu.sched_task)
+		x86_pmu.sched_task(ctx, sched_in);
+}
+
+void perf_check_microcode(void)
+{
+	if (x86_pmu.check_microcode)
+		x86_pmu.check_microcode();
+}
+EXPORT_SYMBOL_GPL(perf_check_microcode);
+
+static struct pmu pmu = {
+	.pmu_enable		= x86_pmu_enable,
+	.pmu_disable		= x86_pmu_disable,
+
+	.attr_groups		= x86_pmu_attr_groups,
+
+	.event_init		= x86_pmu_event_init,
+
+	.event_mapped		= x86_pmu_event_mapped,
+	.event_unmapped		= x86_pmu_event_unmapped,
+
+	.add			= x86_pmu_add,
+	.del			= x86_pmu_del,
+	.start			= x86_pmu_start,
+	.stop			= x86_pmu_stop,
+	.read			= x86_pmu_read,
+
+	.start_txn		= x86_pmu_start_txn,
+	.cancel_txn		= x86_pmu_cancel_txn,
+	.commit_txn		= x86_pmu_commit_txn,
+
+	.event_idx		= x86_pmu_event_idx,
+	.sched_task		= x86_pmu_sched_task,
+	.task_ctx_size          = sizeof(struct x86_perf_task_context),
+};
+
+void arch_perf_update_userpage(struct perf_event *event,
+			       struct perf_event_mmap_page *userpg, u64 now)
+{
+	struct cyc2ns_data *data;
+
+	userpg->cap_user_time = 0;
+	userpg->cap_user_time_zero = 0;
+	userpg->cap_user_rdpmc =
+		!!(event->hw.flags & PERF_X86_EVENT_RDPMC_ALLOWED);
+	userpg->pmc_width = x86_pmu.cntval_bits;
+
+	if (!sched_clock_stable())
+		return;
+
+	data = cyc2ns_read_begin();
+
+	/*
+	 * Internal timekeeping for enabled/running/stopped times
+	 * is always in the local_clock domain.
+	 */
+	userpg->cap_user_time = 1;
+	userpg->time_mult = data->cyc2ns_mul;
+	userpg->time_shift = data->cyc2ns_shift;
+	userpg->time_offset = data->cyc2ns_offset - now;
+
+	/*
+	 * cap_user_time_zero doesn't make sense when we're using a different
+	 * time base for the records.
+	 */
+	if (event->clock == &local_clock) {
+		userpg->cap_user_time_zero = 1;
+		userpg->time_zero = data->cyc2ns_offset;
+	}
+
+	cyc2ns_read_end(data);
+}
+
+/*
+ * callchain support
+ */
+
+static int backtrace_stack(void *data, char *name)
+{
+	return 0;
+}
+
+static void backtrace_address(void *data, unsigned long addr, int reliable)
+{
+	struct perf_callchain_entry *entry = data;
+
+	perf_callchain_store(entry, addr);
+}
+
+static const struct stacktrace_ops backtrace_ops = {
+	.stack			= backtrace_stack,
+	.address		= backtrace_address,
+	.walk_stack		= print_context_stack_bp,
+};
+
+void
+perf_callchain_kernel(struct perf_callchain_entry *entry, struct pt_regs *regs)
+{
+	if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) {
+		/* TODO: We don't support guest os callchain now */
+		return;
+	}
+
+	perf_callchain_store(entry, regs->ip);
+
+	dump_trace(NULL, regs, NULL, 0, &backtrace_ops, entry);
+}
+
+static inline int
+valid_user_frame(const void __user *fp, unsigned long size)
+{
+	return (__range_not_ok(fp, size, TASK_SIZE) == 0);
+}
+
+static unsigned long get_segment_base(unsigned int segment)
+{
+	struct desc_struct *desc;
+	int idx = segment >> 3;
+
+	if ((segment & SEGMENT_TI_MASK) == SEGMENT_LDT) {
+#ifdef CONFIG_MODIFY_LDT_SYSCALL
+		struct ldt_struct *ldt;
+
+		if (idx > LDT_ENTRIES)
+			return 0;
+
+		/* IRQs are off, so this synchronizes with smp_store_release */
+		ldt = lockless_dereference(current->active_mm->context.ldt);
+		if (!ldt || idx > ldt->size)
+			return 0;
+
+		desc = &ldt->entries[idx];
+#else
+		return 0;
+#endif
+	} else {
+		if (idx > GDT_ENTRIES)
+			return 0;
+
+		desc = raw_cpu_ptr(gdt_page.gdt) + idx;
+	}
+
+	return get_desc_base(desc);
+}
+
+#ifdef CONFIG_IA32_EMULATION
+
+#include <asm/compat.h>
+
+static inline int
+perf_callchain_user32(struct pt_regs *regs, struct perf_callchain_entry *entry)
+{
+	/* 32-bit process in 64-bit kernel. */
+	unsigned long ss_base, cs_base;
+	struct stack_frame_ia32 frame;
+	const void __user *fp;
+
+	if (!test_thread_flag(TIF_IA32))
+		return 0;
+
+	cs_base = get_segment_base(regs->cs);
+	ss_base = get_segment_base(regs->ss);
+
+	fp = compat_ptr(ss_base + regs->bp);
+	while (entry->nr < PERF_MAX_STACK_DEPTH) {
+		unsigned long bytes;
+		frame.next_frame     = 0;
+		frame.return_address = 0;
+
+		bytes = copy_from_user_nmi(&frame, fp, sizeof(frame));
+		if (bytes != 0)
+			break;
+
+		if (!valid_user_frame(fp, sizeof(frame)))
+			break;
+
+		perf_callchain_store(entry, cs_base + frame.return_address);
+		fp = compat_ptr(ss_base + frame.next_frame);
+	}
+	return 1;
+}
+#else
+static inline int
+perf_callchain_user32(struct pt_regs *regs, struct perf_callchain_entry *entry)
+{
+    return 0;
+}
+#endif
+
+void
+perf_callchain_user(struct perf_callchain_entry *entry, struct pt_regs *regs)
+{
+	struct stack_frame frame;
+	const void __user *fp;
+
+	if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) {
+		/* TODO: We don't support guest os callchain now */
+		return;
+	}
+
+	/*
+	 * We don't know what to do with VM86 stacks.. ignore them for now.
+	 */
+	if (regs->flags & (X86_VM_MASK | PERF_EFLAGS_VM))
+		return;
+
+	fp = (void __user *)regs->bp;
+
+	perf_callchain_store(entry, regs->ip);
+
+	if (!current->mm)
+		return;
+
+	if (perf_callchain_user32(regs, entry))
+		return;
+
+	while (entry->nr < PERF_MAX_STACK_DEPTH) {
+		unsigned long bytes;
+		frame.next_frame	     = NULL;
+		frame.return_address = 0;
+
+		bytes = copy_from_user_nmi(&frame, fp, sizeof(frame));
+		if (bytes != 0)
+			break;
+
+		if (!valid_user_frame(fp, sizeof(frame)))
+			break;
+
+		perf_callchain_store(entry, frame.return_address);
+		fp = frame.next_frame;
+	}
+}
+
+/*
+ * Deal with code segment offsets for the various execution modes:
+ *
+ *   VM86 - the good olde 16 bit days, where the linear address is
+ *          20 bits and we use regs->ip + 0x10 * regs->cs.
+ *
+ *   IA32 - Where we need to look at GDT/LDT segment descriptor tables
+ *          to figure out what the 32bit base address is.
+ *
+ *    X32 - has TIF_X32 set, but is running in x86_64
+ *
+ * X86_64 - CS,DS,SS,ES are all zero based.
+ */
+static unsigned long code_segment_base(struct pt_regs *regs)
+{
+	/*
+	 * For IA32 we look at the GDT/LDT segment base to convert the
+	 * effective IP to a linear address.
+	 */
+
+#ifdef CONFIG_X86_32
+	/*
+	 * If we are in VM86 mode, add the segment offset to convert to a
+	 * linear address.
+	 */
+	if (regs->flags & X86_VM_MASK)
+		return 0x10 * regs->cs;
+
+	if (user_mode(regs) && regs->cs != __USER_CS)
+		return get_segment_base(regs->cs);
+#else
+	if (user_mode(regs) && !user_64bit_mode(regs) &&
+	    regs->cs != __USER32_CS)
+		return get_segment_base(regs->cs);
+#endif
+	return 0;
+}
+
+unsigned long perf_instruction_pointer(struct pt_regs *regs)
+{
+	if (perf_guest_cbs && perf_guest_cbs->is_in_guest())
+		return perf_guest_cbs->get_guest_ip();
+
+	return regs->ip + code_segment_base(regs);
+}
+
+unsigned long perf_misc_flags(struct pt_regs *regs)
+{
+	int misc = 0;
+
+	if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) {
+		if (perf_guest_cbs->is_user_mode())
+			misc |= PERF_RECORD_MISC_GUEST_USER;
+		else
+			misc |= PERF_RECORD_MISC_GUEST_KERNEL;
+	} else {
+		if (user_mode(regs))
+			misc |= PERF_RECORD_MISC_USER;
+		else
+			misc |= PERF_RECORD_MISC_KERNEL;
+	}
+
+	if (regs->flags & PERF_EFLAGS_EXACT)
+		misc |= PERF_RECORD_MISC_EXACT_IP;
+
+	return misc;
+}
+
+void perf_get_x86_pmu_capability(struct x86_pmu_capability *cap)
+{
+	cap->version		= x86_pmu.version;
+	cap->num_counters_gp	= x86_pmu.num_counters;
+	cap->num_counters_fixed	= x86_pmu.num_counters_fixed;
+	cap->bit_width_gp	= x86_pmu.cntval_bits;
+	cap->bit_width_fixed	= x86_pmu.cntval_bits;
+	cap->events_mask	= (unsigned int)x86_pmu.events_maskl;
+	cap->events_mask_len	= x86_pmu.events_mask_len;
+}
+EXPORT_SYMBOL_GPL(perf_get_x86_pmu_capability);
--- /dev/null
+++ zfcpdump-kernel-4.4/arch/x86/events/intel/bts.c
@@ -0,0 +1,544 @@
+/*
+ * BTS PMU driver for perf
+ * Copyright (c) 2013-2014, Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ */
+
+#undef DEBUG
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/bitops.h>
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/debugfs.h>
+#include <linux/device.h>
+#include <linux/coredump.h>
+
+#include <asm-generic/sizes.h>
+#include <asm/perf_event.h>
+
+#include "../perf_event.h"
+
+struct bts_ctx {
+	struct perf_output_handle	handle;
+	struct debug_store		ds_back;
+	int				started;
+};
+
+static DEFINE_PER_CPU(struct bts_ctx, bts_ctx);
+
+#define BTS_RECORD_SIZE		24
+#define BTS_SAFETY_MARGIN	4080
+
+struct bts_phys {
+	struct page	*page;
+	unsigned long	size;
+	unsigned long	offset;
+	unsigned long	displacement;
+};
+
+struct bts_buffer {
+	size_t		real_size;	/* multiple of BTS_RECORD_SIZE */
+	unsigned int	nr_pages;
+	unsigned int	nr_bufs;
+	unsigned int	cur_buf;
+	bool		snapshot;
+	local_t		data_size;
+	local_t		lost;
+	local_t		head;
+	unsigned long	end;
+	void		**data_pages;
+	struct bts_phys	buf[0];
+};
+
+struct pmu bts_pmu;
+
+static size_t buf_size(struct page *page)
+{
+	return 1 << (PAGE_SHIFT + page_private(page));
+}
+
+static void *
+bts_buffer_setup_aux(int cpu, void **pages, int nr_pages, bool overwrite)
+{
+	struct bts_buffer *buf;
+	struct page *page;
+	int node = (cpu == -1) ? cpu : cpu_to_node(cpu);
+	unsigned long offset;
+	size_t size = nr_pages << PAGE_SHIFT;
+	int pg, nbuf, pad;
+
+	/* count all the high order buffers */
+	for (pg = 0, nbuf = 0; pg < nr_pages;) {
+		page = virt_to_page(pages[pg]);
+		if (WARN_ON_ONCE(!PagePrivate(page) && nr_pages > 1))
+			return NULL;
+		pg += 1 << page_private(page);
+		nbuf++;
+	}
+
+	/*
+	 * to avoid interrupts in overwrite mode, only allow one physical
+	 */
+	if (overwrite && nbuf > 1)
+		return NULL;
+
+	buf = kzalloc_node(offsetof(struct bts_buffer, buf[nbuf]), GFP_KERNEL, node);
+	if (!buf)
+		return NULL;
+
+	buf->nr_pages = nr_pages;
+	buf->nr_bufs = nbuf;
+	buf->snapshot = overwrite;
+	buf->data_pages = pages;
+	buf->real_size = size - size % BTS_RECORD_SIZE;
+
+	for (pg = 0, nbuf = 0, offset = 0, pad = 0; nbuf < buf->nr_bufs; nbuf++) {
+		unsigned int __nr_pages;
+
+		page = virt_to_page(pages[pg]);
+		__nr_pages = PagePrivate(page) ? 1 << page_private(page) : 1;
+		buf->buf[nbuf].page = page;
+		buf->buf[nbuf].offset = offset;
+		buf->buf[nbuf].displacement = (pad ? BTS_RECORD_SIZE - pad : 0);
+		buf->buf[nbuf].size = buf_size(page) - buf->buf[nbuf].displacement;
+		pad = buf->buf[nbuf].size % BTS_RECORD_SIZE;
+		buf->buf[nbuf].size -= pad;
+
+		pg += __nr_pages;
+		offset += __nr_pages << PAGE_SHIFT;
+	}
+
+	return buf;
+}
+
+static void bts_buffer_free_aux(void *data)
+{
+	kfree(data);
+}
+
+static unsigned long bts_buffer_offset(struct bts_buffer *buf, unsigned int idx)
+{
+	return buf->buf[idx].offset + buf->buf[idx].displacement;
+}
+
+static void
+bts_config_buffer(struct bts_buffer *buf)
+{
+	int cpu = raw_smp_processor_id();
+	struct debug_store *ds = per_cpu(cpu_hw_events, cpu).ds;
+	struct bts_phys *phys = &buf->buf[buf->cur_buf];
+	unsigned long index, thresh = 0, end = phys->size;
+	struct page *page = phys->page;
+
+	index = local_read(&buf->head);
+
+	if (!buf->snapshot) {
+		if (buf->end < phys->offset + buf_size(page))
+			end = buf->end - phys->offset - phys->displacement;
+
+		index -= phys->offset + phys->displacement;
+
+		if (end - index > BTS_SAFETY_MARGIN)
+			thresh = end - BTS_SAFETY_MARGIN;
+		else if (end - index > BTS_RECORD_SIZE)
+			thresh = end - BTS_RECORD_SIZE;
+		else
+			thresh = end;
+	}
+
+	ds->bts_buffer_base = (u64)(long)page_address(page) + phys->displacement;
+	ds->bts_index = ds->bts_buffer_base + index;
+	ds->bts_absolute_maximum = ds->bts_buffer_base + end;
+	ds->bts_interrupt_threshold = !buf->snapshot
+		? ds->bts_buffer_base + thresh
+		: ds->bts_absolute_maximum + BTS_RECORD_SIZE;
+}
+
+static void bts_buffer_pad_out(struct bts_phys *phys, unsigned long head)
+{
+	unsigned long index = head - phys->offset;
+
+	memset(page_address(phys->page) + index, 0, phys->size - index);
+}
+
+static bool bts_buffer_is_full(struct bts_buffer *buf, struct bts_ctx *bts)
+{
+	if (buf->snapshot)
+		return false;
+
+	if (local_read(&buf->data_size) >= bts->handle.size ||
+	    bts->handle.size - local_read(&buf->data_size) < BTS_RECORD_SIZE)
+		return true;
+
+	return false;
+}
+
+static void bts_update(struct bts_ctx *bts)
+{
+	int cpu = raw_smp_processor_id();
+	struct debug_store *ds = per_cpu(cpu_hw_events, cpu).ds;
+	struct bts_buffer *buf = perf_get_aux(&bts->handle);
+	unsigned long index = ds->bts_index - ds->bts_buffer_base, old, head;
+
+	if (!buf)
+		return;
+
+	head = index + bts_buffer_offset(buf, buf->cur_buf);
+	old = local_xchg(&buf->head, head);
+
+	if (!buf->snapshot) {
+		if (old == head)
+			return;
+
+		if (ds->bts_index >= ds->bts_absolute_maximum)
+			local_inc(&buf->lost);
+
+		/*
+		 * old and head are always in the same physical buffer, so we
+		 * can subtract them to get the data size.
+		 */
+		local_add(head - old, &buf->data_size);
+	} else {
+		local_set(&buf->data_size, head);
+	}
+}
+
+static void __bts_event_start(struct perf_event *event)
+{
+	struct bts_ctx *bts = this_cpu_ptr(&bts_ctx);
+	struct bts_buffer *buf = perf_get_aux(&bts->handle);
+	u64 config = 0;
+
+	if (!buf || bts_buffer_is_full(buf, bts))
+		return;
+
+	event->hw.itrace_started = 1;
+	event->hw.state = 0;
+
+	if (!buf->snapshot)
+		config |= ARCH_PERFMON_EVENTSEL_INT;
+	if (!event->attr.exclude_kernel)
+		config |= ARCH_PERFMON_EVENTSEL_OS;
+	if (!event->attr.exclude_user)
+		config |= ARCH_PERFMON_EVENTSEL_USR;
+
+	bts_config_buffer(buf);
+
+	/*
+	 * local barrier to make sure that ds configuration made it
+	 * before we enable BTS
+	 */
+	wmb();
+
+	intel_pmu_enable_bts(config);
+}
+
+static void bts_event_start(struct perf_event *event, int flags)
+{
+	struct bts_ctx *bts = this_cpu_ptr(&bts_ctx);
+
+	__bts_event_start(event);
+
+	/* PMI handler: this counter is running and likely generating PMIs */
+	ACCESS_ONCE(bts->started) = 1;
+}
+
+static void __bts_event_stop(struct perf_event *event)
+{
+	/*
+	 * No extra synchronization is mandated by the documentation to have
+	 * BTS data stores globally visible.
+	 */
+	intel_pmu_disable_bts();
+
+	if (event->hw.state & PERF_HES_STOPPED)
+		return;
+
+	ACCESS_ONCE(event->hw.state) |= PERF_HES_STOPPED;
+}
+
+static void bts_event_stop(struct perf_event *event, int flags)
+{
+	struct bts_ctx *bts = this_cpu_ptr(&bts_ctx);
+
+	/* PMI handler: don't restart this counter */
+	ACCESS_ONCE(bts->started) = 0;
+
+	__bts_event_stop(event);
+
+	if (flags & PERF_EF_UPDATE)
+		bts_update(bts);
+}
+
+void intel_bts_enable_local(void)
+{
+	struct bts_ctx *bts = this_cpu_ptr(&bts_ctx);
+
+	if (bts->handle.event && bts->started)
+		__bts_event_start(bts->handle.event);
+}
+
+void intel_bts_disable_local(void)
+{
+	struct bts_ctx *bts = this_cpu_ptr(&bts_ctx);
+
+	if (bts->handle.event)
+		__bts_event_stop(bts->handle.event);
+}
+
+static int
+bts_buffer_reset(struct bts_buffer *buf, struct perf_output_handle *handle)
+{
+	unsigned long head, space, next_space, pad, gap, skip, wakeup;
+	unsigned int next_buf;
+	struct bts_phys *phys, *next_phys;
+	int ret;
+
+	if (buf->snapshot)
+		return 0;
+
+	head = handle->head & ((buf->nr_pages << PAGE_SHIFT) - 1);
+	if (WARN_ON_ONCE(head != local_read(&buf->head)))
+		return -EINVAL;
+
+	phys = &buf->buf[buf->cur_buf];
+	space = phys->offset + phys->displacement + phys->size - head;
+	pad = space;
+	if (space > handle->size) {
+		space = handle->size;
+		space -= space % BTS_RECORD_SIZE;
+	}
+	if (space <= BTS_SAFETY_MARGIN) {
+		/* See if next phys buffer has more space */
+		next_buf = buf->cur_buf + 1;
+		if (next_buf >= buf->nr_bufs)
+			next_buf = 0;
+		next_phys = &buf->buf[next_buf];
+		gap = buf_size(phys->page) - phys->displacement - phys->size +
+		      next_phys->displacement;
+		skip = pad + gap;
+		if (handle->size >= skip) {
+			next_space = next_phys->size;
+			if (next_space + skip > handle->size) {
+				next_space = handle->size - skip;
+				next_space -= next_space % BTS_RECORD_SIZE;
+			}
+			if (next_space > space || !space) {
+				if (pad)
+					bts_buffer_pad_out(phys, head);
+				ret = perf_aux_output_skip(handle, skip);
+				if (ret)
+					return ret;
+				/* Advance to next phys buffer */
+				phys = next_phys;
+				space = next_space;
+				head = phys->offset + phys->displacement;
+				/*
+				 * After this, cur_buf and head won't match ds
+				 * anymore, so we must not be racing with
+				 * bts_update().
+				 */
+				buf->cur_buf = next_buf;
+				local_set(&buf->head, head);
+			}
+		}
+	}
+
+	/* Don't go far beyond wakeup watermark */
+	wakeup = BTS_SAFETY_MARGIN + BTS_RECORD_SIZE + handle->wakeup -
+		 handle->head;
+	if (space > wakeup) {
+		space = wakeup;
+		space -= space % BTS_RECORD_SIZE;
+	}
+
+	buf->end = head + space;
+
+	/*
+	 * If we have no space, the lost notification would have been sent when
+	 * we hit absolute_maximum - see bts_update()
+	 */
+	if (!space)
+		return -ENOSPC;
+
+	return 0;
+}
+
+int intel_bts_interrupt(void)
+{
+	struct bts_ctx *bts = this_cpu_ptr(&bts_ctx);
+	struct perf_event *event = bts->handle.event;
+	struct bts_buffer *buf;
+	s64 old_head;
+	int err;
+
+	if (!event || !bts->started)
+		return 0;
+
+	buf = perf_get_aux(&bts->handle);
+	/*
+	 * Skip snapshot counters: they don't use the interrupt, but
+	 * there's no other way of telling, because the pointer will
+	 * keep moving
+	 */
+	if (!buf || buf->snapshot)
+		return 0;
+
+	old_head = local_read(&buf->head);
+	bts_update(bts);
+
+	/* no new data */
+	if (old_head == local_read(&buf->head))
+		return 0;
+
+	perf_aux_output_end(&bts->handle, local_xchg(&buf->data_size, 0),
+			    !!local_xchg(&buf->lost, 0));
+
+	buf = perf_aux_output_begin(&bts->handle, event);
+	if (!buf)
+		return 1;
+
+	err = bts_buffer_reset(buf, &bts->handle);
+	if (err)
+		perf_aux_output_end(&bts->handle, 0, false);
+
+	return 1;
+}
+
+static void bts_event_del(struct perf_event *event, int mode)
+{
+	struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
+	struct bts_ctx *bts = this_cpu_ptr(&bts_ctx);
+	struct bts_buffer *buf = perf_get_aux(&bts->handle);
+
+	bts_event_stop(event, PERF_EF_UPDATE);
+
+	if (buf) {
+		if (buf->snapshot)
+			bts->handle.head =
+				local_xchg(&buf->data_size,
+					   buf->nr_pages << PAGE_SHIFT);
+		perf_aux_output_end(&bts->handle, local_xchg(&buf->data_size, 0),
+				    !!local_xchg(&buf->lost, 0));
+	}
+
+	cpuc->ds->bts_index = bts->ds_back.bts_buffer_base;
+	cpuc->ds->bts_buffer_base = bts->ds_back.bts_buffer_base;
+	cpuc->ds->bts_absolute_maximum = bts->ds_back.bts_absolute_maximum;
+	cpuc->ds->bts_interrupt_threshold = bts->ds_back.bts_interrupt_threshold;
+}
+
+static int bts_event_add(struct perf_event *event, int mode)
+{
+	struct bts_buffer *buf;
+	struct bts_ctx *bts = this_cpu_ptr(&bts_ctx);
+	struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
+	struct hw_perf_event *hwc = &event->hw;
+	int ret = -EBUSY;
+
+	event->hw.state = PERF_HES_STOPPED;
+
+	if (test_bit(INTEL_PMC_IDX_FIXED_BTS, cpuc->active_mask))
+		return -EBUSY;
+
+	if (bts->handle.event)
+		return -EBUSY;
+
+	buf = perf_aux_output_begin(&bts->handle, event);
+	if (!buf)
+		return -EINVAL;
+
+	ret = bts_buffer_reset(buf, &bts->handle);
+	if (ret) {
+		perf_aux_output_end(&bts->handle, 0, false);
+		return ret;
+	}
+
+	bts->ds_back.bts_buffer_base = cpuc->ds->bts_buffer_base;
+	bts->ds_back.bts_absolute_maximum = cpuc->ds->bts_absolute_maximum;
+	bts->ds_back.bts_interrupt_threshold = cpuc->ds->bts_interrupt_threshold;
+
+	if (mode & PERF_EF_START) {
+		bts_event_start(event, 0);
+		if (hwc->state & PERF_HES_STOPPED) {
+			bts_event_del(event, 0);
+			return -EBUSY;
+		}
+	}
+
+	return 0;
+}
+
+static void bts_event_destroy(struct perf_event *event)
+{
+	x86_release_hardware();
+	x86_del_exclusive(x86_lbr_exclusive_bts);
+}
+
+static int bts_event_init(struct perf_event *event)
+{
+	int ret;
+
+	if (event->attr.type != bts_pmu.type)
+		return -ENOENT;
+
+	if (x86_add_exclusive(x86_lbr_exclusive_bts))
+		return -EBUSY;
+
+	/*
+	 * BTS leaks kernel addresses even when CPL0 tracing is
+	 * disabled, so disallow intel_bts driver for unprivileged
+	 * users on paranoid systems since it provides trace data
+	 * to the user in a zero-copy fashion.
+	 *
+	 * Note that the default paranoia setting permits unprivileged
+	 * users to profile the kernel.
+	 */
+	if (event->attr.exclude_kernel && perf_paranoid_kernel() &&
+	    !capable(CAP_SYS_ADMIN))
+		return -EACCES;
+
+	ret = x86_reserve_hardware();
+	if (ret) {
+		x86_del_exclusive(x86_lbr_exclusive_bts);
+		return ret;
+	}
+
+	event->destroy = bts_event_destroy;
+
+	return 0;
+}
+
+static void bts_event_read(struct perf_event *event)
+{
+}
+
+static __init int bts_init(void)
+{
+	if (!boot_cpu_has(X86_FEATURE_DTES64) || !x86_pmu.bts)
+		return -ENODEV;
+
+	bts_pmu.capabilities	= PERF_PMU_CAP_AUX_NO_SG | PERF_PMU_CAP_ITRACE;
+	bts_pmu.task_ctx_nr	= perf_sw_context;
+	bts_pmu.event_init	= bts_event_init;
+	bts_pmu.add		= bts_event_add;
+	bts_pmu.del		= bts_event_del;
+	bts_pmu.start		= bts_event_start;
+	bts_pmu.stop		= bts_event_stop;
+	bts_pmu.read		= bts_event_read;
+	bts_pmu.setup_aux	= bts_buffer_setup_aux;
+	bts_pmu.free_aux	= bts_buffer_free_aux;
+
+	return perf_pmu_register(&bts_pmu, "intel_bts", -1);
+}
+arch_initcall(bts_init);
--- /dev/null
+++ zfcpdump-kernel-4.4/arch/x86/events/intel/core.c
@@ -0,0 +1,3754 @@
+/*
+ * Per core/cpu state
+ *
+ * Used to coordinate shared registers between HT threads or
+ * among events on a single PMU.
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/stddef.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/export.h>
+#include <linux/nmi.h>
+
+#include <asm/cpufeature.h>
+#include <asm/hardirq.h>
+#include <asm/apic.h>
+
+#include "../perf_event.h"
+
+/*
+ * Intel PerfMon, used on Core and later.
+ */
+static u64 intel_perfmon_event_map[PERF_COUNT_HW_MAX] __read_mostly =
+{
+	[PERF_COUNT_HW_CPU_CYCLES]		= 0x003c,
+	[PERF_COUNT_HW_INSTRUCTIONS]		= 0x00c0,
+	[PERF_COUNT_HW_CACHE_REFERENCES]	= 0x4f2e,
+	[PERF_COUNT_HW_CACHE_MISSES]		= 0x412e,
+	[PERF_COUNT_HW_BRANCH_INSTRUCTIONS]	= 0x00c4,
+	[PERF_COUNT_HW_BRANCH_MISSES]		= 0x00c5,
+	[PERF_COUNT_HW_BUS_CYCLES]		= 0x013c,
+	[PERF_COUNT_HW_REF_CPU_CYCLES]		= 0x0300, /* pseudo-encoding */
+};
+
+static struct event_constraint intel_core_event_constraints[] __read_mostly =
+{
+	INTEL_EVENT_CONSTRAINT(0x11, 0x2), /* FP_ASSIST */
+	INTEL_EVENT_CONSTRAINT(0x12, 0x2), /* MUL */
+	INTEL_EVENT_CONSTRAINT(0x13, 0x2), /* DIV */
+	INTEL_EVENT_CONSTRAINT(0x14, 0x1), /* CYCLES_DIV_BUSY */
+	INTEL_EVENT_CONSTRAINT(0x19, 0x2), /* DELAYED_BYPASS */
+	INTEL_EVENT_CONSTRAINT(0xc1, 0x1), /* FP_COMP_INSTR_RET */
+	EVENT_CONSTRAINT_END
+};
+
+static struct event_constraint intel_core2_event_constraints[] __read_mostly =
+{
+	FIXED_EVENT_CONSTRAINT(0x00c0, 0), /* INST_RETIRED.ANY */
+	FIXED_EVENT_CONSTRAINT(0x003c, 1), /* CPU_CLK_UNHALTED.CORE */
+	FIXED_EVENT_CONSTRAINT(0x0300, 2), /* CPU_CLK_UNHALTED.REF */
+	INTEL_EVENT_CONSTRAINT(0x10, 0x1), /* FP_COMP_OPS_EXE */
+	INTEL_EVENT_CONSTRAINT(0x11, 0x2), /* FP_ASSIST */
+	INTEL_EVENT_CONSTRAINT(0x12, 0x2), /* MUL */
+	INTEL_EVENT_CONSTRAINT(0x13, 0x2), /* DIV */
+	INTEL_EVENT_CONSTRAINT(0x14, 0x1), /* CYCLES_DIV_BUSY */
+	INTEL_EVENT_CONSTRAINT(0x18, 0x1), /* IDLE_DURING_DIV */
+	INTEL_EVENT_CONSTRAINT(0x19, 0x2), /* DELAYED_BYPASS */
+	INTEL_EVENT_CONSTRAINT(0xa1, 0x1), /* RS_UOPS_DISPATCH_CYCLES */
+	INTEL_EVENT_CONSTRAINT(0xc9, 0x1), /* ITLB_MISS_RETIRED (T30-9) */
+	INTEL_EVENT_CONSTRAINT(0xcb, 0x1), /* MEM_LOAD_RETIRED */
+	EVENT_CONSTRAINT_END
+};
+
+static struct event_constraint intel_nehalem_event_constraints[] __read_mostly =
+{
+	FIXED_EVENT_CONSTRAINT(0x00c0, 0), /* INST_RETIRED.ANY */
+	FIXED_EVENT_CONSTRAINT(0x003c, 1), /* CPU_CLK_UNHALTED.CORE */
+	FIXED_EVENT_CONSTRAINT(0x0300, 2), /* CPU_CLK_UNHALTED.REF */
+	INTEL_EVENT_CONSTRAINT(0x40, 0x3), /* L1D_CACHE_LD */
+	INTEL_EVENT_CONSTRAINT(0x41, 0x3), /* L1D_CACHE_ST */
+	INTEL_EVENT_CONSTRAINT(0x42, 0x3), /* L1D_CACHE_LOCK */
+	INTEL_EVENT_CONSTRAINT(0x43, 0x3), /* L1D_ALL_REF */
+	INTEL_EVENT_CONSTRAINT(0x48, 0x3), /* L1D_PEND_MISS */
+	INTEL_EVENT_CONSTRAINT(0x4e, 0x3), /* L1D_PREFETCH */
+	INTEL_EVENT_CONSTRAINT(0x51, 0x3), /* L1D */
+	INTEL_EVENT_CONSTRAINT(0x63, 0x3), /* CACHE_LOCK_CYCLES */
+	EVENT_CONSTRAINT_END
+};
+
+static struct extra_reg intel_nehalem_extra_regs[] __read_mostly =
+{
+	/* must define OFFCORE_RSP_X first, see intel_fixup_er() */
+	INTEL_UEVENT_EXTRA_REG(0x01b7, MSR_OFFCORE_RSP_0, 0xffff, RSP_0),
+	INTEL_UEVENT_PEBS_LDLAT_EXTRA_REG(0x100b),
+	EVENT_EXTRA_END
+};
+
+static struct event_constraint intel_westmere_event_constraints[] __read_mostly =
+{
+	FIXED_EVENT_CONSTRAINT(0x00c0, 0), /* INST_RETIRED.ANY */
+	FIXED_EVENT_CONSTRAINT(0x003c, 1), /* CPU_CLK_UNHALTED.CORE */
+	FIXED_EVENT_CONSTRAINT(0x0300, 2), /* CPU_CLK_UNHALTED.REF */
+	INTEL_EVENT_CONSTRAINT(0x51, 0x3), /* L1D */
+	INTEL_EVENT_CONSTRAINT(0x60, 0x1), /* OFFCORE_REQUESTS_OUTSTANDING */
+	INTEL_EVENT_CONSTRAINT(0x63, 0x3), /* CACHE_LOCK_CYCLES */
+	INTEL_EVENT_CONSTRAINT(0xb3, 0x1), /* SNOOPQ_REQUEST_OUTSTANDING */
+	EVENT_CONSTRAINT_END
+};
+
+static struct event_constraint intel_snb_event_constraints[] __read_mostly =
+{
+	FIXED_EVENT_CONSTRAINT(0x00c0, 0), /* INST_RETIRED.ANY */
+	FIXED_EVENT_CONSTRAINT(0x003c, 1), /* CPU_CLK_UNHALTED.CORE */
+	FIXED_EVENT_CONSTRAINT(0x0300, 2), /* CPU_CLK_UNHALTED.REF */
+	INTEL_UEVENT_CONSTRAINT(0x04a3, 0xf), /* CYCLE_ACTIVITY.CYCLES_NO_DISPATCH */
+	INTEL_UEVENT_CONSTRAINT(0x05a3, 0xf), /* CYCLE_ACTIVITY.STALLS_L2_PENDING */
+	INTEL_UEVENT_CONSTRAINT(0x02a3, 0x4), /* CYCLE_ACTIVITY.CYCLES_L1D_PENDING */
+	INTEL_UEVENT_CONSTRAINT(0x06a3, 0x4), /* CYCLE_ACTIVITY.STALLS_L1D_PENDING */
+	INTEL_EVENT_CONSTRAINT(0x48, 0x4), /* L1D_PEND_MISS.PENDING */
+	INTEL_UEVENT_CONSTRAINT(0x01c0, 0x2), /* INST_RETIRED.PREC_DIST */
+	INTEL_EVENT_CONSTRAINT(0xcd, 0x8), /* MEM_TRANS_RETIRED.LOAD_LATENCY */
+	INTEL_UEVENT_CONSTRAINT(0x04a3, 0xf), /* CYCLE_ACTIVITY.CYCLES_NO_DISPATCH */
+	INTEL_UEVENT_CONSTRAINT(0x02a3, 0x4), /* CYCLE_ACTIVITY.CYCLES_L1D_PENDING */
+
+	INTEL_EXCLEVT_CONSTRAINT(0xd0, 0xf), /* MEM_UOPS_RETIRED.* */
+	INTEL_EXCLEVT_CONSTRAINT(0xd1, 0xf), /* MEM_LOAD_UOPS_RETIRED.* */
+	INTEL_EXCLEVT_CONSTRAINT(0xd2, 0xf), /* MEM_LOAD_UOPS_LLC_HIT_RETIRED.* */
+	INTEL_EXCLEVT_CONSTRAINT(0xd3, 0xf), /* MEM_LOAD_UOPS_LLC_MISS_RETIRED.* */
+
+	EVENT_CONSTRAINT_END
+};
+
+static struct event_constraint intel_ivb_event_constraints[] __read_mostly =
+{
+	FIXED_EVENT_CONSTRAINT(0x00c0, 0), /* INST_RETIRED.ANY */
+	FIXED_EVENT_CONSTRAINT(0x003c, 1), /* CPU_CLK_UNHALTED.CORE */
+	FIXED_EVENT_CONSTRAINT(0x0300, 2), /* CPU_CLK_UNHALTED.REF */
+	INTEL_UEVENT_CONSTRAINT(0x0148, 0x4), /* L1D_PEND_MISS.PENDING */
+	INTEL_UEVENT_CONSTRAINT(0x0279, 0xf), /* IDQ.EMTPY */
+	INTEL_UEVENT_CONSTRAINT(0x019c, 0xf), /* IDQ_UOPS_NOT_DELIVERED.CORE */
+	INTEL_UEVENT_CONSTRAINT(0x02a3, 0xf), /* CYCLE_ACTIVITY.CYCLES_LDM_PENDING */
+	INTEL_UEVENT_CONSTRAINT(0x04a3, 0xf), /* CYCLE_ACTIVITY.CYCLES_NO_EXECUTE */
+	INTEL_UEVENT_CONSTRAINT(0x05a3, 0xf), /* CYCLE_ACTIVITY.STALLS_L2_PENDING */
+	INTEL_UEVENT_CONSTRAINT(0x06a3, 0xf), /* CYCLE_ACTIVITY.STALLS_LDM_PENDING */
+	INTEL_UEVENT_CONSTRAINT(0x08a3, 0x4), /* CYCLE_ACTIVITY.CYCLES_L1D_PENDING */
+	INTEL_UEVENT_CONSTRAINT(0x0ca3, 0x4), /* CYCLE_ACTIVITY.STALLS_L1D_PENDING */
+	INTEL_UEVENT_CONSTRAINT(0x01c0, 0x2), /* INST_RETIRED.PREC_DIST */
+
+	INTEL_EXCLEVT_CONSTRAINT(0xd0, 0xf), /* MEM_UOPS_RETIRED.* */
+	INTEL_EXCLEVT_CONSTRAINT(0xd1, 0xf), /* MEM_LOAD_UOPS_RETIRED.* */
+	INTEL_EXCLEVT_CONSTRAINT(0xd2, 0xf), /* MEM_LOAD_UOPS_LLC_HIT_RETIRED.* */
+	INTEL_EXCLEVT_CONSTRAINT(0xd3, 0xf), /* MEM_LOAD_UOPS_LLC_MISS_RETIRED.* */
+
+	EVENT_CONSTRAINT_END
+};
+
+static struct extra_reg intel_westmere_extra_regs[] __read_mostly =
+{
+	/* must define OFFCORE_RSP_X first, see intel_fixup_er() */
+	INTEL_UEVENT_EXTRA_REG(0x01b7, MSR_OFFCORE_RSP_0, 0xffff, RSP_0),
+	INTEL_UEVENT_EXTRA_REG(0x01bb, MSR_OFFCORE_RSP_1, 0xffff, RSP_1),
+	INTEL_UEVENT_PEBS_LDLAT_EXTRA_REG(0x100b),
+	EVENT_EXTRA_END
+};
+
+static struct event_constraint intel_v1_event_constraints[] __read_mostly =
+{
+	EVENT_CONSTRAINT_END
+};
+
+static struct event_constraint intel_gen_event_constraints[] __read_mostly =
+{
+	FIXED_EVENT_CONSTRAINT(0x00c0, 0), /* INST_RETIRED.ANY */
+	FIXED_EVENT_CONSTRAINT(0x003c, 1), /* CPU_CLK_UNHALTED.CORE */
+	FIXED_EVENT_CONSTRAINT(0x0300, 2), /* CPU_CLK_UNHALTED.REF */
+	EVENT_CONSTRAINT_END
+};
+
+static struct event_constraint intel_slm_event_constraints[] __read_mostly =
+{
+	FIXED_EVENT_CONSTRAINT(0x00c0, 0), /* INST_RETIRED.ANY */
+	FIXED_EVENT_CONSTRAINT(0x003c, 1), /* CPU_CLK_UNHALTED.CORE */
+	FIXED_EVENT_CONSTRAINT(0x0300, 2), /* pseudo CPU_CLK_UNHALTED.REF */
+	EVENT_CONSTRAINT_END
+};
+
+struct event_constraint intel_skl_event_constraints[] = {
+	FIXED_EVENT_CONSTRAINT(0x00c0, 0),	/* INST_RETIRED.ANY */
+	FIXED_EVENT_CONSTRAINT(0x003c, 1),	/* CPU_CLK_UNHALTED.CORE */
+	FIXED_EVENT_CONSTRAINT(0x0300, 2),	/* CPU_CLK_UNHALTED.REF */
+	INTEL_UEVENT_CONSTRAINT(0x1c0, 0x2),	/* INST_RETIRED.PREC_DIST */
+	EVENT_CONSTRAINT_END
+};
+
+static struct extra_reg intel_knl_extra_regs[] __read_mostly = {
+	INTEL_UEVENT_EXTRA_REG(0x01b7,
+			       MSR_OFFCORE_RSP_0, 0x7f9ffbffffull, RSP_0),
+	INTEL_UEVENT_EXTRA_REG(0x02b7,
+			       MSR_OFFCORE_RSP_1, 0x3f9ffbffffull, RSP_1),
+	EVENT_EXTRA_END
+};
+
+static struct extra_reg intel_snb_extra_regs[] __read_mostly = {
+	/* must define OFFCORE_RSP_X first, see intel_fixup_er() */
+	INTEL_UEVENT_EXTRA_REG(0x01b7, MSR_OFFCORE_RSP_0, 0x3f807f8fffull, RSP_0),
+	INTEL_UEVENT_EXTRA_REG(0x01bb, MSR_OFFCORE_RSP_1, 0x3f807f8fffull, RSP_1),
+	INTEL_UEVENT_PEBS_LDLAT_EXTRA_REG(0x01cd),
+	EVENT_EXTRA_END
+};
+
+static struct extra_reg intel_snbep_extra_regs[] __read_mostly = {
+	/* must define OFFCORE_RSP_X first, see intel_fixup_er() */
+	INTEL_UEVENT_EXTRA_REG(0x01b7, MSR_OFFCORE_RSP_0, 0x3fffff8fffull, RSP_0),
+	INTEL_UEVENT_EXTRA_REG(0x01bb, MSR_OFFCORE_RSP_1, 0x3fffff8fffull, RSP_1),
+	INTEL_UEVENT_PEBS_LDLAT_EXTRA_REG(0x01cd),
+	EVENT_EXTRA_END
+};
+
+static struct extra_reg intel_skl_extra_regs[] __read_mostly = {
+	INTEL_UEVENT_EXTRA_REG(0x01b7, MSR_OFFCORE_RSP_0, 0x3fffff8fffull, RSP_0),
+	INTEL_UEVENT_EXTRA_REG(0x01bb, MSR_OFFCORE_RSP_1, 0x3fffff8fffull, RSP_1),
+	INTEL_UEVENT_PEBS_LDLAT_EXTRA_REG(0x01cd),
+	/*
+	 * Note the low 8 bits eventsel code is not a continuous field, containing
+	 * some #GPing bits. These are masked out.
+	 */
+	INTEL_UEVENT_EXTRA_REG(0x01c6, MSR_PEBS_FRONTEND, 0x7fff17, FE),
+	EVENT_EXTRA_END
+};
+
+EVENT_ATTR_STR(mem-loads,	mem_ld_nhm,	"event=0x0b,umask=0x10,ldlat=3");
+EVENT_ATTR_STR(mem-loads,	mem_ld_snb,	"event=0xcd,umask=0x1,ldlat=3");
+EVENT_ATTR_STR(mem-stores,	mem_st_snb,	"event=0xcd,umask=0x2");
+
+struct attribute *nhm_events_attrs[] = {
+	EVENT_PTR(mem_ld_nhm),
+	NULL,
+};
+
+struct attribute *snb_events_attrs[] = {
+	EVENT_PTR(mem_ld_snb),
+	EVENT_PTR(mem_st_snb),
+	NULL,
+};
+
+static struct event_constraint intel_hsw_event_constraints[] = {
+	FIXED_EVENT_CONSTRAINT(0x00c0, 0), /* INST_RETIRED.ANY */
+	FIXED_EVENT_CONSTRAINT(0x003c, 1), /* CPU_CLK_UNHALTED.CORE */
+	FIXED_EVENT_CONSTRAINT(0x0300, 2), /* CPU_CLK_UNHALTED.REF */
+	INTEL_UEVENT_CONSTRAINT(0x148, 0x4),	/* L1D_PEND_MISS.PENDING */
+	INTEL_UEVENT_CONSTRAINT(0x01c0, 0x2), /* INST_RETIRED.PREC_DIST */
+	INTEL_EVENT_CONSTRAINT(0xcd, 0x8), /* MEM_TRANS_RETIRED.LOAD_LATENCY */
+	/* CYCLE_ACTIVITY.CYCLES_L1D_PENDING */
+	INTEL_UEVENT_CONSTRAINT(0x08a3, 0x4),
+	/* CYCLE_ACTIVITY.STALLS_L1D_PENDING */
+	INTEL_UEVENT_CONSTRAINT(0x0ca3, 0x4),
+	/* CYCLE_ACTIVITY.CYCLES_NO_EXECUTE */
+	INTEL_UEVENT_CONSTRAINT(0x04a3, 0xf),
+
+	INTEL_EXCLEVT_CONSTRAINT(0xd0, 0xf), /* MEM_UOPS_RETIRED.* */
+	INTEL_EXCLEVT_CONSTRAINT(0xd1, 0xf), /* MEM_LOAD_UOPS_RETIRED.* */
+	INTEL_EXCLEVT_CONSTRAINT(0xd2, 0xf), /* MEM_LOAD_UOPS_LLC_HIT_RETIRED.* */
+	INTEL_EXCLEVT_CONSTRAINT(0xd3, 0xf), /* MEM_LOAD_UOPS_LLC_MISS_RETIRED.* */
+
+	EVENT_CONSTRAINT_END
+};
+
+struct event_constraint intel_bdw_event_constraints[] = {
+	FIXED_EVENT_CONSTRAINT(0x00c0, 0),	/* INST_RETIRED.ANY */
+	FIXED_EVENT_CONSTRAINT(0x003c, 1),	/* CPU_CLK_UNHALTED.CORE */
+	FIXED_EVENT_CONSTRAINT(0x0300, 2),	/* CPU_CLK_UNHALTED.REF */
+	INTEL_UEVENT_CONSTRAINT(0x148, 0x4),	/* L1D_PEND_MISS.PENDING */
+	INTEL_UEVENT_CONSTRAINT(0x8a3, 0x4),	/* CYCLE_ACTIVITY.CYCLES_L1D_MISS */
+	EVENT_CONSTRAINT_END
+};
+
+static u64 intel_pmu_event_map(int hw_event)
+{
+	return intel_perfmon_event_map[hw_event];
+}
+
+/*
+ * Notes on the events:
+ * - data reads do not include code reads (comparable to earlier tables)
+ * - data counts include speculative execution (except L1 write, dtlb, bpu)
+ * - remote node access includes remote memory, remote cache, remote mmio.
+ * - prefetches are not included in the counts.
+ * - icache miss does not include decoded icache
+ */
+
+#define SKL_DEMAND_DATA_RD		BIT_ULL(0)
+#define SKL_DEMAND_RFO			BIT_ULL(1)
+#define SKL_ANY_RESPONSE		BIT_ULL(16)
+#define SKL_SUPPLIER_NONE		BIT_ULL(17)
+#define SKL_L3_MISS_LOCAL_DRAM		BIT_ULL(26)
+#define SKL_L3_MISS_REMOTE_HOP0_DRAM	BIT_ULL(27)
+#define SKL_L3_MISS_REMOTE_HOP1_DRAM	BIT_ULL(28)
+#define SKL_L3_MISS_REMOTE_HOP2P_DRAM	BIT_ULL(29)
+#define SKL_L3_MISS			(SKL_L3_MISS_LOCAL_DRAM| \
+					 SKL_L3_MISS_REMOTE_HOP0_DRAM| \
+					 SKL_L3_MISS_REMOTE_HOP1_DRAM| \
+					 SKL_L3_MISS_REMOTE_HOP2P_DRAM)
+#define SKL_SPL_HIT			BIT_ULL(30)
+#define SKL_SNOOP_NONE			BIT_ULL(31)
+#define SKL_SNOOP_NOT_NEEDED		BIT_ULL(32)
+#define SKL_SNOOP_MISS			BIT_ULL(33)
+#define SKL_SNOOP_HIT_NO_FWD		BIT_ULL(34)
+#define SKL_SNOOP_HIT_WITH_FWD		BIT_ULL(35)
+#define SKL_SNOOP_HITM			BIT_ULL(36)
+#define SKL_SNOOP_NON_DRAM		BIT_ULL(37)
+#define SKL_ANY_SNOOP			(SKL_SPL_HIT|SKL_SNOOP_NONE| \
+					 SKL_SNOOP_NOT_NEEDED|SKL_SNOOP_MISS| \
+					 SKL_SNOOP_HIT_NO_FWD|SKL_SNOOP_HIT_WITH_FWD| \
+					 SKL_SNOOP_HITM|SKL_SNOOP_NON_DRAM)
+#define SKL_DEMAND_READ			SKL_DEMAND_DATA_RD
+#define SKL_SNOOP_DRAM			(SKL_SNOOP_NONE| \
+					 SKL_SNOOP_NOT_NEEDED|SKL_SNOOP_MISS| \
+					 SKL_SNOOP_HIT_NO_FWD|SKL_SNOOP_HIT_WITH_FWD| \
+					 SKL_SNOOP_HITM|SKL_SPL_HIT)
+#define SKL_DEMAND_WRITE		SKL_DEMAND_RFO
+#define SKL_LLC_ACCESS			SKL_ANY_RESPONSE
+#define SKL_L3_MISS_REMOTE		(SKL_L3_MISS_REMOTE_HOP0_DRAM| \
+					 SKL_L3_MISS_REMOTE_HOP1_DRAM| \
+					 SKL_L3_MISS_REMOTE_HOP2P_DRAM)
+
+static __initconst const u64 skl_hw_cache_event_ids
+				[PERF_COUNT_HW_CACHE_MAX]
+				[PERF_COUNT_HW_CACHE_OP_MAX]
+				[PERF_COUNT_HW_CACHE_RESULT_MAX] =
+{
+ [ C(L1D ) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = 0x81d0,	/* MEM_INST_RETIRED.ALL_LOADS */
+		[ C(RESULT_MISS)   ] = 0x151,	/* L1D.REPLACEMENT */
+	},
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = 0x82d0,	/* MEM_INST_RETIRED.ALL_STORES */
+		[ C(RESULT_MISS)   ] = 0x0,
+	},
+	[ C(OP_PREFETCH) ] = {
+		[ C(RESULT_ACCESS) ] = 0x0,
+		[ C(RESULT_MISS)   ] = 0x0,
+	},
+ },
+ [ C(L1I ) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = 0x0,
+		[ C(RESULT_MISS)   ] = 0x283,	/* ICACHE_64B.MISS */
+	},
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = -1,
+		[ C(RESULT_MISS)   ] = -1,
+	},
+	[ C(OP_PREFETCH) ] = {
+		[ C(RESULT_ACCESS) ] = 0x0,
+		[ C(RESULT_MISS)   ] = 0x0,
+	},
+ },
+ [ C(LL  ) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = 0x1b7,	/* OFFCORE_RESPONSE */
+		[ C(RESULT_MISS)   ] = 0x1b7,	/* OFFCORE_RESPONSE */
+	},
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = 0x1b7,	/* OFFCORE_RESPONSE */
+		[ C(RESULT_MISS)   ] = 0x1b7,	/* OFFCORE_RESPONSE */
+	},
+	[ C(OP_PREFETCH) ] = {
+		[ C(RESULT_ACCESS) ] = 0x0,
+		[ C(RESULT_MISS)   ] = 0x0,
+	},
+ },
+ [ C(DTLB) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = 0x81d0,	/* MEM_INST_RETIRED.ALL_LOADS */
+		[ C(RESULT_MISS)   ] = 0x608,	/* DTLB_LOAD_MISSES.WALK_COMPLETED */
+	},
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = 0x82d0,	/* MEM_INST_RETIRED.ALL_STORES */
+		[ C(RESULT_MISS)   ] = 0x649,	/* DTLB_STORE_MISSES.WALK_COMPLETED */
+	},
+	[ C(OP_PREFETCH) ] = {
+		[ C(RESULT_ACCESS) ] = 0x0,
+		[ C(RESULT_MISS)   ] = 0x0,
+	},
+ },
+ [ C(ITLB) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = 0x2085,	/* ITLB_MISSES.STLB_HIT */
+		[ C(RESULT_MISS)   ] = 0xe85,	/* ITLB_MISSES.WALK_COMPLETED */
+	},
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = -1,
+		[ C(RESULT_MISS)   ] = -1,
+	},
+	[ C(OP_PREFETCH) ] = {
+		[ C(RESULT_ACCESS) ] = -1,
+		[ C(RESULT_MISS)   ] = -1,
+	},
+ },
+ [ C(BPU ) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = 0xc4,	/* BR_INST_RETIRED.ALL_BRANCHES */
+		[ C(RESULT_MISS)   ] = 0xc5,	/* BR_MISP_RETIRED.ALL_BRANCHES */
+	},
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = -1,
+		[ C(RESULT_MISS)   ] = -1,
+	},
+	[ C(OP_PREFETCH) ] = {
+		[ C(RESULT_ACCESS) ] = -1,
+		[ C(RESULT_MISS)   ] = -1,
+	},
+ },
+ [ C(NODE) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = 0x1b7,	/* OFFCORE_RESPONSE */
+		[ C(RESULT_MISS)   ] = 0x1b7,	/* OFFCORE_RESPONSE */
+	},
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = 0x1b7,	/* OFFCORE_RESPONSE */
+		[ C(RESULT_MISS)   ] = 0x1b7,	/* OFFCORE_RESPONSE */
+	},
+	[ C(OP_PREFETCH) ] = {
+		[ C(RESULT_ACCESS) ] = 0x0,
+		[ C(RESULT_MISS)   ] = 0x0,
+	},
+ },
+};
+
+static __initconst const u64 skl_hw_cache_extra_regs
+				[PERF_COUNT_HW_CACHE_MAX]
+				[PERF_COUNT_HW_CACHE_OP_MAX]
+				[PERF_COUNT_HW_CACHE_RESULT_MAX] =
+{
+ [ C(LL  ) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = SKL_DEMAND_READ|
+				       SKL_LLC_ACCESS|SKL_ANY_SNOOP,
+		[ C(RESULT_MISS)   ] = SKL_DEMAND_READ|
+				       SKL_L3_MISS|SKL_ANY_SNOOP|
+				       SKL_SUPPLIER_NONE,
+	},
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = SKL_DEMAND_WRITE|
+				       SKL_LLC_ACCESS|SKL_ANY_SNOOP,
+		[ C(RESULT_MISS)   ] = SKL_DEMAND_WRITE|
+				       SKL_L3_MISS|SKL_ANY_SNOOP|
+				       SKL_SUPPLIER_NONE,
+	},
+	[ C(OP_PREFETCH) ] = {
+		[ C(RESULT_ACCESS) ] = 0x0,
+		[ C(RESULT_MISS)   ] = 0x0,
+	},
+ },
+ [ C(NODE) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = SKL_DEMAND_READ|
+				       SKL_L3_MISS_LOCAL_DRAM|SKL_SNOOP_DRAM,
+		[ C(RESULT_MISS)   ] = SKL_DEMAND_READ|
+				       SKL_L3_MISS_REMOTE|SKL_SNOOP_DRAM,
+	},
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = SKL_DEMAND_WRITE|
+				       SKL_L3_MISS_LOCAL_DRAM|SKL_SNOOP_DRAM,
+		[ C(RESULT_MISS)   ] = SKL_DEMAND_WRITE|
+				       SKL_L3_MISS_REMOTE|SKL_SNOOP_DRAM,
+	},
+	[ C(OP_PREFETCH) ] = {
+		[ C(RESULT_ACCESS) ] = 0x0,
+		[ C(RESULT_MISS)   ] = 0x0,
+	},
+ },
+};
+
+#define SNB_DMND_DATA_RD	(1ULL << 0)
+#define SNB_DMND_RFO		(1ULL << 1)
+#define SNB_DMND_IFETCH		(1ULL << 2)
+#define SNB_DMND_WB		(1ULL << 3)
+#define SNB_PF_DATA_RD		(1ULL << 4)
+#define SNB_PF_RFO		(1ULL << 5)
+#define SNB_PF_IFETCH		(1ULL << 6)
+#define SNB_LLC_DATA_RD		(1ULL << 7)
+#define SNB_LLC_RFO		(1ULL << 8)
+#define SNB_LLC_IFETCH		(1ULL << 9)
+#define SNB_BUS_LOCKS		(1ULL << 10)
+#define SNB_STRM_ST		(1ULL << 11)
+#define SNB_OTHER		(1ULL << 15)
+#define SNB_RESP_ANY		(1ULL << 16)
+#define SNB_NO_SUPP		(1ULL << 17)
+#define SNB_LLC_HITM		(1ULL << 18)
+#define SNB_LLC_HITE		(1ULL << 19)
+#define SNB_LLC_HITS		(1ULL << 20)
+#define SNB_LLC_HITF		(1ULL << 21)
+#define SNB_LOCAL		(1ULL << 22)
+#define SNB_REMOTE		(0xffULL << 23)
+#define SNB_SNP_NONE		(1ULL << 31)
+#define SNB_SNP_NOT_NEEDED	(1ULL << 32)
+#define SNB_SNP_MISS		(1ULL << 33)
+#define SNB_NO_FWD		(1ULL << 34)
+#define SNB_SNP_FWD		(1ULL << 35)
+#define SNB_HITM		(1ULL << 36)
+#define SNB_NON_DRAM		(1ULL << 37)
+
+#define SNB_DMND_READ		(SNB_DMND_DATA_RD|SNB_LLC_DATA_RD)
+#define SNB_DMND_WRITE		(SNB_DMND_RFO|SNB_LLC_RFO)
+#define SNB_DMND_PREFETCH	(SNB_PF_DATA_RD|SNB_PF_RFO)
+
+#define SNB_SNP_ANY		(SNB_SNP_NONE|SNB_SNP_NOT_NEEDED| \
+				 SNB_SNP_MISS|SNB_NO_FWD|SNB_SNP_FWD| \
+				 SNB_HITM)
+
+#define SNB_DRAM_ANY		(SNB_LOCAL|SNB_REMOTE|SNB_SNP_ANY)
+#define SNB_DRAM_REMOTE		(SNB_REMOTE|SNB_SNP_ANY)
+
+#define SNB_L3_ACCESS		SNB_RESP_ANY
+#define SNB_L3_MISS		(SNB_DRAM_ANY|SNB_NON_DRAM)
+
+static __initconst const u64 snb_hw_cache_extra_regs
+				[PERF_COUNT_HW_CACHE_MAX]
+				[PERF_COUNT_HW_CACHE_OP_MAX]
+				[PERF_COUNT_HW_CACHE_RESULT_MAX] =
+{
+ [ C(LL  ) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = SNB_DMND_READ|SNB_L3_ACCESS,
+		[ C(RESULT_MISS)   ] = SNB_DMND_READ|SNB_L3_MISS,
+	},
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = SNB_DMND_WRITE|SNB_L3_ACCESS,
+		[ C(RESULT_MISS)   ] = SNB_DMND_WRITE|SNB_L3_MISS,
+	},
+	[ C(OP_PREFETCH) ] = {
+		[ C(RESULT_ACCESS) ] = SNB_DMND_PREFETCH|SNB_L3_ACCESS,
+		[ C(RESULT_MISS)   ] = SNB_DMND_PREFETCH|SNB_L3_MISS,
+	},
+ },
+ [ C(NODE) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = SNB_DMND_READ|SNB_DRAM_ANY,
+		[ C(RESULT_MISS)   ] = SNB_DMND_READ|SNB_DRAM_REMOTE,
+	},
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = SNB_DMND_WRITE|SNB_DRAM_ANY,
+		[ C(RESULT_MISS)   ] = SNB_DMND_WRITE|SNB_DRAM_REMOTE,
+	},
+	[ C(OP_PREFETCH) ] = {
+		[ C(RESULT_ACCESS) ] = SNB_DMND_PREFETCH|SNB_DRAM_ANY,
+		[ C(RESULT_MISS)   ] = SNB_DMND_PREFETCH|SNB_DRAM_REMOTE,
+	},
+ },
+};
+
+static __initconst const u64 snb_hw_cache_event_ids
+				[PERF_COUNT_HW_CACHE_MAX]
+				[PERF_COUNT_HW_CACHE_OP_MAX]
+				[PERF_COUNT_HW_CACHE_RESULT_MAX] =
+{
+ [ C(L1D) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = 0xf1d0, /* MEM_UOP_RETIRED.LOADS        */
+		[ C(RESULT_MISS)   ] = 0x0151, /* L1D.REPLACEMENT              */
+	},
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = 0xf2d0, /* MEM_UOP_RETIRED.STORES       */
+		[ C(RESULT_MISS)   ] = 0x0851, /* L1D.ALL_M_REPLACEMENT        */
+	},
+	[ C(OP_PREFETCH) ] = {
+		[ C(RESULT_ACCESS) ] = 0x0,
+		[ C(RESULT_MISS)   ] = 0x024e, /* HW_PRE_REQ.DL1_MISS          */
+	},
+ },
+ [ C(L1I ) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = 0x0,
+		[ C(RESULT_MISS)   ] = 0x0280, /* ICACHE.MISSES */
+	},
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = -1,
+		[ C(RESULT_MISS)   ] = -1,
+	},
+	[ C(OP_PREFETCH) ] = {
+		[ C(RESULT_ACCESS) ] = 0x0,
+		[ C(RESULT_MISS)   ] = 0x0,
+	},
+ },
+ [ C(LL  ) ] = {
+	[ C(OP_READ) ] = {
+		/* OFFCORE_RESPONSE.ANY_DATA.LOCAL_CACHE */
+		[ C(RESULT_ACCESS) ] = 0x01b7,
+		/* OFFCORE_RESPONSE.ANY_DATA.ANY_LLC_MISS */
+		[ C(RESULT_MISS)   ] = 0x01b7,
+	},
+	[ C(OP_WRITE) ] = {
+		/* OFFCORE_RESPONSE.ANY_RFO.LOCAL_CACHE */
+		[ C(RESULT_ACCESS) ] = 0x01b7,
+		/* OFFCORE_RESPONSE.ANY_RFO.ANY_LLC_MISS */
+		[ C(RESULT_MISS)   ] = 0x01b7,
+	},
+	[ C(OP_PREFETCH) ] = {
+		/* OFFCORE_RESPONSE.PREFETCH.LOCAL_CACHE */
+		[ C(RESULT_ACCESS) ] = 0x01b7,
+		/* OFFCORE_RESPONSE.PREFETCH.ANY_LLC_MISS */
+		[ C(RESULT_MISS)   ] = 0x01b7,
+	},
+ },
+ [ C(DTLB) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = 0x81d0, /* MEM_UOP_RETIRED.ALL_LOADS */
+		[ C(RESULT_MISS)   ] = 0x0108, /* DTLB_LOAD_MISSES.CAUSES_A_WALK */
+	},
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = 0x82d0, /* MEM_UOP_RETIRED.ALL_STORES */
+		[ C(RESULT_MISS)   ] = 0x0149, /* DTLB_STORE_MISSES.MISS_CAUSES_A_WALK */
+	},
+	[ C(OP_PREFETCH) ] = {
+		[ C(RESULT_ACCESS) ] = 0x0,
+		[ C(RESULT_MISS)   ] = 0x0,
+	},
+ },
+ [ C(ITLB) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = 0x1085, /* ITLB_MISSES.STLB_HIT         */
+		[ C(RESULT_MISS)   ] = 0x0185, /* ITLB_MISSES.CAUSES_A_WALK    */
+	},
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = -1,
+		[ C(RESULT_MISS)   ] = -1,
+	},
+	[ C(OP_PREFETCH) ] = {
+		[ C(RESULT_ACCESS) ] = -1,
+		[ C(RESULT_MISS)   ] = -1,
+	},
+ },
+ [ C(BPU ) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = 0x00c4, /* BR_INST_RETIRED.ALL_BRANCHES */
+		[ C(RESULT_MISS)   ] = 0x00c5, /* BR_MISP_RETIRED.ALL_BRANCHES */
+	},
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = -1,
+		[ C(RESULT_MISS)   ] = -1,
+	},
+	[ C(OP_PREFETCH) ] = {
+		[ C(RESULT_ACCESS) ] = -1,
+		[ C(RESULT_MISS)   ] = -1,
+	},
+ },
+ [ C(NODE) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = 0x01b7,
+		[ C(RESULT_MISS)   ] = 0x01b7,
+	},
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = 0x01b7,
+		[ C(RESULT_MISS)   ] = 0x01b7,
+	},
+	[ C(OP_PREFETCH) ] = {
+		[ C(RESULT_ACCESS) ] = 0x01b7,
+		[ C(RESULT_MISS)   ] = 0x01b7,
+	},
+ },
+
+};
+
+/*
+ * Notes on the events:
+ * - data reads do not include code reads (comparable to earlier tables)
+ * - data counts include speculative execution (except L1 write, dtlb, bpu)
+ * - remote node access includes remote memory, remote cache, remote mmio.
+ * - prefetches are not included in the counts because they are not
+ *   reliably counted.
+ */
+
+#define HSW_DEMAND_DATA_RD		BIT_ULL(0)
+#define HSW_DEMAND_RFO			BIT_ULL(1)
+#define HSW_ANY_RESPONSE		BIT_ULL(16)
+#define HSW_SUPPLIER_NONE		BIT_ULL(17)
+#define HSW_L3_MISS_LOCAL_DRAM		BIT_ULL(22)
+#define HSW_L3_MISS_REMOTE_HOP0		BIT_ULL(27)
+#define HSW_L3_MISS_REMOTE_HOP1		BIT_ULL(28)
+#define HSW_L3_MISS_REMOTE_HOP2P	BIT_ULL(29)
+#define HSW_L3_MISS			(HSW_L3_MISS_LOCAL_DRAM| \
+					 HSW_L3_MISS_REMOTE_HOP0|HSW_L3_MISS_REMOTE_HOP1| \
+					 HSW_L3_MISS_REMOTE_HOP2P)
+#define HSW_SNOOP_NONE			BIT_ULL(31)
+#define HSW_SNOOP_NOT_NEEDED		BIT_ULL(32)
+#define HSW_SNOOP_MISS			BIT_ULL(33)
+#define HSW_SNOOP_HIT_NO_FWD		BIT_ULL(34)
+#define HSW_SNOOP_HIT_WITH_FWD		BIT_ULL(35)
+#define HSW_SNOOP_HITM			BIT_ULL(36)
+#define HSW_SNOOP_NON_DRAM		BIT_ULL(37)
+#define HSW_ANY_SNOOP			(HSW_SNOOP_NONE| \
+					 HSW_SNOOP_NOT_NEEDED|HSW_SNOOP_MISS| \
+					 HSW_SNOOP_HIT_NO_FWD|HSW_SNOOP_HIT_WITH_FWD| \
+					 HSW_SNOOP_HITM|HSW_SNOOP_NON_DRAM)
+#define HSW_SNOOP_DRAM			(HSW_ANY_SNOOP & ~HSW_SNOOP_NON_DRAM)
+#define HSW_DEMAND_READ			HSW_DEMAND_DATA_RD
+#define HSW_DEMAND_WRITE		HSW_DEMAND_RFO
+#define HSW_L3_MISS_REMOTE		(HSW_L3_MISS_REMOTE_HOP0|\
+					 HSW_L3_MISS_REMOTE_HOP1|HSW_L3_MISS_REMOTE_HOP2P)
+#define HSW_LLC_ACCESS			HSW_ANY_RESPONSE
+
+#define BDW_L3_MISS_LOCAL		BIT(26)
+#define BDW_L3_MISS			(BDW_L3_MISS_LOCAL| \
+					 HSW_L3_MISS_REMOTE_HOP0|HSW_L3_MISS_REMOTE_HOP1| \
+					 HSW_L3_MISS_REMOTE_HOP2P)
+
+
+static __initconst const u64 hsw_hw_cache_event_ids
+				[PERF_COUNT_HW_CACHE_MAX]
+				[PERF_COUNT_HW_CACHE_OP_MAX]
+				[PERF_COUNT_HW_CACHE_RESULT_MAX] =
+{
+ [ C(L1D ) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = 0x81d0,	/* MEM_UOPS_RETIRED.ALL_LOADS */
+		[ C(RESULT_MISS)   ] = 0x151,	/* L1D.REPLACEMENT */
+	},
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = 0x82d0,	/* MEM_UOPS_RETIRED.ALL_STORES */
+		[ C(RESULT_MISS)   ] = 0x0,
+	},
+	[ C(OP_PREFETCH) ] = {
+		[ C(RESULT_ACCESS) ] = 0x0,
+		[ C(RESULT_MISS)   ] = 0x0,
+	},
+ },
+ [ C(L1I ) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = 0x0,
+		[ C(RESULT_MISS)   ] = 0x280,	/* ICACHE.MISSES */
+	},
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = -1,
+		[ C(RESULT_MISS)   ] = -1,
+	},
+	[ C(OP_PREFETCH) ] = {
+		[ C(RESULT_ACCESS) ] = 0x0,
+		[ C(RESULT_MISS)   ] = 0x0,
+	},
+ },
+ [ C(LL  ) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = 0x1b7,	/* OFFCORE_RESPONSE */
+		[ C(RESULT_MISS)   ] = 0x1b7,	/* OFFCORE_RESPONSE */
+	},
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = 0x1b7,	/* OFFCORE_RESPONSE */
+		[ C(RESULT_MISS)   ] = 0x1b7,	/* OFFCORE_RESPONSE */
+	},
+	[ C(OP_PREFETCH) ] = {
+		[ C(RESULT_ACCESS) ] = 0x0,
+		[ C(RESULT_MISS)   ] = 0x0,
+	},
+ },
+ [ C(DTLB) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = 0x81d0,	/* MEM_UOPS_RETIRED.ALL_LOADS */
+		[ C(RESULT_MISS)   ] = 0x108,	/* DTLB_LOAD_MISSES.MISS_CAUSES_A_WALK */
+	},
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = 0x82d0,	/* MEM_UOPS_RETIRED.ALL_STORES */
+		[ C(RESULT_MISS)   ] = 0x149,	/* DTLB_STORE_MISSES.MISS_CAUSES_A_WALK */
+	},
+	[ C(OP_PREFETCH) ] = {
+		[ C(RESULT_ACCESS) ] = 0x0,
+		[ C(RESULT_MISS)   ] = 0x0,
+	},
+ },
+ [ C(ITLB) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = 0x6085,	/* ITLB_MISSES.STLB_HIT */
+		[ C(RESULT_MISS)   ] = 0x185,	/* ITLB_MISSES.MISS_CAUSES_A_WALK */
+	},
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = -1,
+		[ C(RESULT_MISS)   ] = -1,
+	},
+	[ C(OP_PREFETCH) ] = {
+		[ C(RESULT_ACCESS) ] = -1,
+		[ C(RESULT_MISS)   ] = -1,
+	},
+ },
+ [ C(BPU ) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = 0xc4,	/* BR_INST_RETIRED.ALL_BRANCHES */
+		[ C(RESULT_MISS)   ] = 0xc5,	/* BR_MISP_RETIRED.ALL_BRANCHES */
+	},
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = -1,
+		[ C(RESULT_MISS)   ] = -1,
+	},
+	[ C(OP_PREFETCH) ] = {
+		[ C(RESULT_ACCESS) ] = -1,
+		[ C(RESULT_MISS)   ] = -1,
+	},
+ },
+ [ C(NODE) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = 0x1b7,	/* OFFCORE_RESPONSE */
+		[ C(RESULT_MISS)   ] = 0x1b7,	/* OFFCORE_RESPONSE */
+	},
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = 0x1b7,	/* OFFCORE_RESPONSE */
+		[ C(RESULT_MISS)   ] = 0x1b7,	/* OFFCORE_RESPONSE */
+	},
+	[ C(OP_PREFETCH) ] = {
+		[ C(RESULT_ACCESS) ] = 0x0,
+		[ C(RESULT_MISS)   ] = 0x0,
+	},
+ },
+};
+
+static __initconst const u64 hsw_hw_cache_extra_regs
+				[PERF_COUNT_HW_CACHE_MAX]
+				[PERF_COUNT_HW_CACHE_OP_MAX]
+				[PERF_COUNT_HW_CACHE_RESULT_MAX] =
+{
+ [ C(LL  ) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = HSW_DEMAND_READ|
+				       HSW_LLC_ACCESS,
+		[ C(RESULT_MISS)   ] = HSW_DEMAND_READ|
+				       HSW_L3_MISS|HSW_ANY_SNOOP,
+	},
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = HSW_DEMAND_WRITE|
+				       HSW_LLC_ACCESS,
+		[ C(RESULT_MISS)   ] = HSW_DEMAND_WRITE|
+				       HSW_L3_MISS|HSW_ANY_SNOOP,
+	},
+	[ C(OP_PREFETCH) ] = {
+		[ C(RESULT_ACCESS) ] = 0x0,
+		[ C(RESULT_MISS)   ] = 0x0,
+	},
+ },
+ [ C(NODE) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = HSW_DEMAND_READ|
+				       HSW_L3_MISS_LOCAL_DRAM|
+				       HSW_SNOOP_DRAM,
+		[ C(RESULT_MISS)   ] = HSW_DEMAND_READ|
+				       HSW_L3_MISS_REMOTE|
+				       HSW_SNOOP_DRAM,
+	},
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = HSW_DEMAND_WRITE|
+				       HSW_L3_MISS_LOCAL_DRAM|
+				       HSW_SNOOP_DRAM,
+		[ C(RESULT_MISS)   ] = HSW_DEMAND_WRITE|
+				       HSW_L3_MISS_REMOTE|
+				       HSW_SNOOP_DRAM,
+	},
+	[ C(OP_PREFETCH) ] = {
+		[ C(RESULT_ACCESS) ] = 0x0,
+		[ C(RESULT_MISS)   ] = 0x0,
+	},
+ },
+};
+
+static __initconst const u64 westmere_hw_cache_event_ids
+				[PERF_COUNT_HW_CACHE_MAX]
+				[PERF_COUNT_HW_CACHE_OP_MAX]
+				[PERF_COUNT_HW_CACHE_RESULT_MAX] =
+{
+ [ C(L1D) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = 0x010b, /* MEM_INST_RETIRED.LOADS       */
+		[ C(RESULT_MISS)   ] = 0x0151, /* L1D.REPL                     */
+	},
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = 0x020b, /* MEM_INST_RETURED.STORES      */
+		[ C(RESULT_MISS)   ] = 0x0251, /* L1D.M_REPL                   */
+	},
+	[ C(OP_PREFETCH) ] = {
+		[ C(RESULT_ACCESS) ] = 0x014e, /* L1D_PREFETCH.REQUESTS        */
+		[ C(RESULT_MISS)   ] = 0x024e, /* L1D_PREFETCH.MISS            */
+	},
+ },
+ [ C(L1I ) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = 0x0380, /* L1I.READS                    */
+		[ C(RESULT_MISS)   ] = 0x0280, /* L1I.MISSES                   */
+	},
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = -1,
+		[ C(RESULT_MISS)   ] = -1,
+	},
+	[ C(OP_PREFETCH) ] = {
+		[ C(RESULT_ACCESS) ] = 0x0,
+		[ C(RESULT_MISS)   ] = 0x0,
+	},
+ },
+ [ C(LL  ) ] = {
+	[ C(OP_READ) ] = {
+		/* OFFCORE_RESPONSE.ANY_DATA.LOCAL_CACHE */
+		[ C(RESULT_ACCESS) ] = 0x01b7,
+		/* OFFCORE_RESPONSE.ANY_DATA.ANY_LLC_MISS */
+		[ C(RESULT_MISS)   ] = 0x01b7,
+	},
+	/*
+	 * Use RFO, not WRITEBACK, because a write miss would typically occur
+	 * on RFO.
+	 */
+	[ C(OP_WRITE) ] = {
+		/* OFFCORE_RESPONSE.ANY_RFO.LOCAL_CACHE */
+		[ C(RESULT_ACCESS) ] = 0x01b7,
+		/* OFFCORE_RESPONSE.ANY_RFO.ANY_LLC_MISS */
+		[ C(RESULT_MISS)   ] = 0x01b7,
+	},
+	[ C(OP_PREFETCH) ] = {
+		/* OFFCORE_RESPONSE.PREFETCH.LOCAL_CACHE */
+		[ C(RESULT_ACCESS) ] = 0x01b7,
+		/* OFFCORE_RESPONSE.PREFETCH.ANY_LLC_MISS */
+		[ C(RESULT_MISS)   ] = 0x01b7,
+	},
+ },
+ [ C(DTLB) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = 0x010b, /* MEM_INST_RETIRED.LOADS       */
+		[ C(RESULT_MISS)   ] = 0x0108, /* DTLB_LOAD_MISSES.ANY         */
+	},
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = 0x020b, /* MEM_INST_RETURED.STORES      */
+		[ C(RESULT_MISS)   ] = 0x010c, /* MEM_STORE_RETIRED.DTLB_MISS  */
+	},
+	[ C(OP_PREFETCH) ] = {
+		[ C(RESULT_ACCESS) ] = 0x0,
+		[ C(RESULT_MISS)   ] = 0x0,
+	},
+ },
+ [ C(ITLB) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = 0x01c0, /* INST_RETIRED.ANY_P           */
+		[ C(RESULT_MISS)   ] = 0x0185, /* ITLB_MISSES.ANY              */
+	},
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = -1,
+		[ C(RESULT_MISS)   ] = -1,
+	},
+	[ C(OP_PREFETCH) ] = {
+		[ C(RESULT_ACCESS) ] = -1,
+		[ C(RESULT_MISS)   ] = -1,
+	},
+ },
+ [ C(BPU ) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = 0x00c4, /* BR_INST_RETIRED.ALL_BRANCHES */
+		[ C(RESULT_MISS)   ] = 0x03e8, /* BPU_CLEARS.ANY               */
+	},
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = -1,
+		[ C(RESULT_MISS)   ] = -1,
+	},
+	[ C(OP_PREFETCH) ] = {
+		[ C(RESULT_ACCESS) ] = -1,
+		[ C(RESULT_MISS)   ] = -1,
+	},
+ },
+ [ C(NODE) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = 0x01b7,
+		[ C(RESULT_MISS)   ] = 0x01b7,
+	},
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = 0x01b7,
+		[ C(RESULT_MISS)   ] = 0x01b7,
+	},
+	[ C(OP_PREFETCH) ] = {
+		[ C(RESULT_ACCESS) ] = 0x01b7,
+		[ C(RESULT_MISS)   ] = 0x01b7,
+	},
+ },
+};
+
+/*
+ * Nehalem/Westmere MSR_OFFCORE_RESPONSE bits;
+ * See IA32 SDM Vol 3B 30.6.1.3
+ */
+
+#define NHM_DMND_DATA_RD	(1 << 0)
+#define NHM_DMND_RFO		(1 << 1)
+#define NHM_DMND_IFETCH		(1 << 2)
+#define NHM_DMND_WB		(1 << 3)
+#define NHM_PF_DATA_RD		(1 << 4)
+#define NHM_PF_DATA_RFO		(1 << 5)
+#define NHM_PF_IFETCH		(1 << 6)
+#define NHM_OFFCORE_OTHER	(1 << 7)
+#define NHM_UNCORE_HIT		(1 << 8)
+#define NHM_OTHER_CORE_HIT_SNP	(1 << 9)
+#define NHM_OTHER_CORE_HITM	(1 << 10)
+        			/* reserved */
+#define NHM_REMOTE_CACHE_FWD	(1 << 12)
+#define NHM_REMOTE_DRAM		(1 << 13)
+#define NHM_LOCAL_DRAM		(1 << 14)
+#define NHM_NON_DRAM		(1 << 15)
+
+#define NHM_LOCAL		(NHM_LOCAL_DRAM|NHM_REMOTE_CACHE_FWD)
+#define NHM_REMOTE		(NHM_REMOTE_DRAM)
+
+#define NHM_DMND_READ		(NHM_DMND_DATA_RD)
+#define NHM_DMND_WRITE		(NHM_DMND_RFO|NHM_DMND_WB)
+#define NHM_DMND_PREFETCH	(NHM_PF_DATA_RD|NHM_PF_DATA_RFO)
+
+#define NHM_L3_HIT	(NHM_UNCORE_HIT|NHM_OTHER_CORE_HIT_SNP|NHM_OTHER_CORE_HITM)
+#define NHM_L3_MISS	(NHM_NON_DRAM|NHM_LOCAL_DRAM|NHM_REMOTE_DRAM|NHM_REMOTE_CACHE_FWD)
+#define NHM_L3_ACCESS	(NHM_L3_HIT|NHM_L3_MISS)
+
+static __initconst const u64 nehalem_hw_cache_extra_regs
+				[PERF_COUNT_HW_CACHE_MAX]
+				[PERF_COUNT_HW_CACHE_OP_MAX]
+				[PERF_COUNT_HW_CACHE_RESULT_MAX] =
+{
+ [ C(LL  ) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = NHM_DMND_READ|NHM_L3_ACCESS,
+		[ C(RESULT_MISS)   ] = NHM_DMND_READ|NHM_L3_MISS,
+	},
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = NHM_DMND_WRITE|NHM_L3_ACCESS,
+		[ C(RESULT_MISS)   ] = NHM_DMND_WRITE|NHM_L3_MISS,
+	},
+	[ C(OP_PREFETCH) ] = {
+		[ C(RESULT_ACCESS) ] = NHM_DMND_PREFETCH|NHM_L3_ACCESS,
+		[ C(RESULT_MISS)   ] = NHM_DMND_PREFETCH|NHM_L3_MISS,
+	},
+ },
+ [ C(NODE) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = NHM_DMND_READ|NHM_LOCAL|NHM_REMOTE,
+		[ C(RESULT_MISS)   ] = NHM_DMND_READ|NHM_REMOTE,
+	},
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = NHM_DMND_WRITE|NHM_LOCAL|NHM_REMOTE,
+		[ C(RESULT_MISS)   ] = NHM_DMND_WRITE|NHM_REMOTE,
+	},
+	[ C(OP_PREFETCH) ] = {
+		[ C(RESULT_ACCESS) ] = NHM_DMND_PREFETCH|NHM_LOCAL|NHM_REMOTE,
+		[ C(RESULT_MISS)   ] = NHM_DMND_PREFETCH|NHM_REMOTE,
+	},
+ },
+};
+
+static __initconst const u64 nehalem_hw_cache_event_ids
+				[PERF_COUNT_HW_CACHE_MAX]
+				[PERF_COUNT_HW_CACHE_OP_MAX]
+				[PERF_COUNT_HW_CACHE_RESULT_MAX] =
+{
+ [ C(L1D) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = 0x010b, /* MEM_INST_RETIRED.LOADS       */
+		[ C(RESULT_MISS)   ] = 0x0151, /* L1D.REPL                     */
+	},
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = 0x020b, /* MEM_INST_RETURED.STORES      */
+		[ C(RESULT_MISS)   ] = 0x0251, /* L1D.M_REPL                   */
+	},
+	[ C(OP_PREFETCH) ] = {
+		[ C(RESULT_ACCESS) ] = 0x014e, /* L1D_PREFETCH.REQUESTS        */
+		[ C(RESULT_MISS)   ] = 0x024e, /* L1D_PREFETCH.MISS            */
+	},
+ },
+ [ C(L1I ) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = 0x0380, /* L1I.READS                    */
+		[ C(RESULT_MISS)   ] = 0x0280, /* L1I.MISSES                   */
+	},
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = -1,
+		[ C(RESULT_MISS)   ] = -1,
+	},
+	[ C(OP_PREFETCH) ] = {
+		[ C(RESULT_ACCESS) ] = 0x0,
+		[ C(RESULT_MISS)   ] = 0x0,
+	},
+ },
+ [ C(LL  ) ] = {
+	[ C(OP_READ) ] = {
+		/* OFFCORE_RESPONSE.ANY_DATA.LOCAL_CACHE */
+		[ C(RESULT_ACCESS) ] = 0x01b7,
+		/* OFFCORE_RESPONSE.ANY_DATA.ANY_LLC_MISS */
+		[ C(RESULT_MISS)   ] = 0x01b7,
+	},
+	/*
+	 * Use RFO, not WRITEBACK, because a write miss would typically occur
+	 * on RFO.
+	 */
+	[ C(OP_WRITE) ] = {
+		/* OFFCORE_RESPONSE.ANY_RFO.LOCAL_CACHE */
+		[ C(RESULT_ACCESS) ] = 0x01b7,
+		/* OFFCORE_RESPONSE.ANY_RFO.ANY_LLC_MISS */
+		[ C(RESULT_MISS)   ] = 0x01b7,
+	},
+	[ C(OP_PREFETCH) ] = {
+		/* OFFCORE_RESPONSE.PREFETCH.LOCAL_CACHE */
+		[ C(RESULT_ACCESS) ] = 0x01b7,
+		/* OFFCORE_RESPONSE.PREFETCH.ANY_LLC_MISS */
+		[ C(RESULT_MISS)   ] = 0x01b7,
+	},
+ },
+ [ C(DTLB) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = 0x0f40, /* L1D_CACHE_LD.MESI   (alias)  */
+		[ C(RESULT_MISS)   ] = 0x0108, /* DTLB_LOAD_MISSES.ANY         */
+	},
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = 0x0f41, /* L1D_CACHE_ST.MESI   (alias)  */
+		[ C(RESULT_MISS)   ] = 0x010c, /* MEM_STORE_RETIRED.DTLB_MISS  */
+	},
+	[ C(OP_PREFETCH) ] = {
+		[ C(RESULT_ACCESS) ] = 0x0,
+		[ C(RESULT_MISS)   ] = 0x0,
+	},
+ },
+ [ C(ITLB) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = 0x01c0, /* INST_RETIRED.ANY_P           */
+		[ C(RESULT_MISS)   ] = 0x20c8, /* ITLB_MISS_RETIRED            */
+	},
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = -1,
+		[ C(RESULT_MISS)   ] = -1,
+	},
+	[ C(OP_PREFETCH) ] = {
+		[ C(RESULT_ACCESS) ] = -1,
+		[ C(RESULT_MISS)   ] = -1,
+	},
+ },
+ [ C(BPU ) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = 0x00c4, /* BR_INST_RETIRED.ALL_BRANCHES */
+		[ C(RESULT_MISS)   ] = 0x03e8, /* BPU_CLEARS.ANY               */
+	},
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = -1,
+		[ C(RESULT_MISS)   ] = -1,
+	},
+	[ C(OP_PREFETCH) ] = {
+		[ C(RESULT_ACCESS) ] = -1,
+		[ C(RESULT_MISS)   ] = -1,
+	},
+ },
+ [ C(NODE) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = 0x01b7,
+		[ C(RESULT_MISS)   ] = 0x01b7,
+	},
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = 0x01b7,
+		[ C(RESULT_MISS)   ] = 0x01b7,
+	},
+	[ C(OP_PREFETCH) ] = {
+		[ C(RESULT_ACCESS) ] = 0x01b7,
+		[ C(RESULT_MISS)   ] = 0x01b7,
+	},
+ },
+};
+
+static __initconst const u64 core2_hw_cache_event_ids
+				[PERF_COUNT_HW_CACHE_MAX]
+				[PERF_COUNT_HW_CACHE_OP_MAX]
+				[PERF_COUNT_HW_CACHE_RESULT_MAX] =
+{
+ [ C(L1D) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = 0x0f40, /* L1D_CACHE_LD.MESI          */
+		[ C(RESULT_MISS)   ] = 0x0140, /* L1D_CACHE_LD.I_STATE       */
+	},
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = 0x0f41, /* L1D_CACHE_ST.MESI          */
+		[ C(RESULT_MISS)   ] = 0x0141, /* L1D_CACHE_ST.I_STATE       */
+	},
+	[ C(OP_PREFETCH) ] = {
+		[ C(RESULT_ACCESS) ] = 0x104e, /* L1D_PREFETCH.REQUESTS      */
+		[ C(RESULT_MISS)   ] = 0,
+	},
+ },
+ [ C(L1I ) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = 0x0080, /* L1I.READS                  */
+		[ C(RESULT_MISS)   ] = 0x0081, /* L1I.MISSES                 */
+	},
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = -1,
+		[ C(RESULT_MISS)   ] = -1,
+	},
+	[ C(OP_PREFETCH) ] = {
+		[ C(RESULT_ACCESS) ] = 0,
+		[ C(RESULT_MISS)   ] = 0,
+	},
+ },
+ [ C(LL  ) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = 0x4f29, /* L2_LD.MESI                 */
+		[ C(RESULT_MISS)   ] = 0x4129, /* L2_LD.ISTATE               */
+	},
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = 0x4f2A, /* L2_ST.MESI                 */
+		[ C(RESULT_MISS)   ] = 0x412A, /* L2_ST.ISTATE               */
+	},
+	[ C(OP_PREFETCH) ] = {
+		[ C(RESULT_ACCESS) ] = 0,
+		[ C(RESULT_MISS)   ] = 0,
+	},
+ },
+ [ C(DTLB) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = 0x0f40, /* L1D_CACHE_LD.MESI  (alias) */
+		[ C(RESULT_MISS)   ] = 0x0208, /* DTLB_MISSES.MISS_LD        */
+	},
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = 0x0f41, /* L1D_CACHE_ST.MESI  (alias) */
+		[ C(RESULT_MISS)   ] = 0x0808, /* DTLB_MISSES.MISS_ST        */
+	},
+	[ C(OP_PREFETCH) ] = {
+		[ C(RESULT_ACCESS) ] = 0,
+		[ C(RESULT_MISS)   ] = 0,
+	},
+ },
+ [ C(ITLB) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = 0x00c0, /* INST_RETIRED.ANY_P         */
+		[ C(RESULT_MISS)   ] = 0x1282, /* ITLBMISSES                 */
+	},
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = -1,
+		[ C(RESULT_MISS)   ] = -1,
+	},
+	[ C(OP_PREFETCH) ] = {
+		[ C(RESULT_ACCESS) ] = -1,
+		[ C(RESULT_MISS)   ] = -1,
+	},
+ },
+ [ C(BPU ) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = 0x00c4, /* BR_INST_RETIRED.ANY        */
+		[ C(RESULT_MISS)   ] = 0x00c5, /* BP_INST_RETIRED.MISPRED    */
+	},
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = -1,
+		[ C(RESULT_MISS)   ] = -1,
+	},
+	[ C(OP_PREFETCH) ] = {
+		[ C(RESULT_ACCESS) ] = -1,
+		[ C(RESULT_MISS)   ] = -1,
+	},
+ },
+};
+
+static __initconst const u64 atom_hw_cache_event_ids
+				[PERF_COUNT_HW_CACHE_MAX]
+				[PERF_COUNT_HW_CACHE_OP_MAX]
+				[PERF_COUNT_HW_CACHE_RESULT_MAX] =
+{
+ [ C(L1D) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = 0x2140, /* L1D_CACHE.LD               */
+		[ C(RESULT_MISS)   ] = 0,
+	},
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = 0x2240, /* L1D_CACHE.ST               */
+		[ C(RESULT_MISS)   ] = 0,
+	},
+	[ C(OP_PREFETCH) ] = {
+		[ C(RESULT_ACCESS) ] = 0x0,
+		[ C(RESULT_MISS)   ] = 0,
+	},
+ },
+ [ C(L1I ) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = 0x0380, /* L1I.READS                  */
+		[ C(RESULT_MISS)   ] = 0x0280, /* L1I.MISSES                 */
+	},
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = -1,
+		[ C(RESULT_MISS)   ] = -1,
+	},
+	[ C(OP_PREFETCH) ] = {
+		[ C(RESULT_ACCESS) ] = 0,
+		[ C(RESULT_MISS)   ] = 0,
+	},
+ },
+ [ C(LL  ) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = 0x4f29, /* L2_LD.MESI                 */
+		[ C(RESULT_MISS)   ] = 0x4129, /* L2_LD.ISTATE               */
+	},
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = 0x4f2A, /* L2_ST.MESI                 */
+		[ C(RESULT_MISS)   ] = 0x412A, /* L2_ST.ISTATE               */
+	},
+	[ C(OP_PREFETCH) ] = {
+		[ C(RESULT_ACCESS) ] = 0,
+		[ C(RESULT_MISS)   ] = 0,
+	},
+ },
+ [ C(DTLB) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = 0x2140, /* L1D_CACHE_LD.MESI  (alias) */
+		[ C(RESULT_MISS)   ] = 0x0508, /* DTLB_MISSES.MISS_LD        */
+	},
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = 0x2240, /* L1D_CACHE_ST.MESI  (alias) */
+		[ C(RESULT_MISS)   ] = 0x0608, /* DTLB_MISSES.MISS_ST        */
+	},
+	[ C(OP_PREFETCH) ] = {
+		[ C(RESULT_ACCESS) ] = 0,
+		[ C(RESULT_MISS)   ] = 0,
+	},
+ },
+ [ C(ITLB) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = 0x00c0, /* INST_RETIRED.ANY_P         */
+		[ C(RESULT_MISS)   ] = 0x0282, /* ITLB.MISSES                */
+	},
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = -1,
+		[ C(RESULT_MISS)   ] = -1,
+	},
+	[ C(OP_PREFETCH) ] = {
+		[ C(RESULT_ACCESS) ] = -1,
+		[ C(RESULT_MISS)   ] = -1,
+	},
+ },
+ [ C(BPU ) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = 0x00c4, /* BR_INST_RETIRED.ANY        */
+		[ C(RESULT_MISS)   ] = 0x00c5, /* BP_INST_RETIRED.MISPRED    */
+	},
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = -1,
+		[ C(RESULT_MISS)   ] = -1,
+	},
+	[ C(OP_PREFETCH) ] = {
+		[ C(RESULT_ACCESS) ] = -1,
+		[ C(RESULT_MISS)   ] = -1,
+	},
+ },
+};
+
+static struct extra_reg intel_slm_extra_regs[] __read_mostly =
+{
+	/* must define OFFCORE_RSP_X first, see intel_fixup_er() */
+	INTEL_UEVENT_EXTRA_REG(0x01b7, MSR_OFFCORE_RSP_0, 0x768005ffffull, RSP_0),
+	INTEL_UEVENT_EXTRA_REG(0x02b7, MSR_OFFCORE_RSP_1, 0x368005ffffull, RSP_1),
+	EVENT_EXTRA_END
+};
+
+#define SLM_DMND_READ		SNB_DMND_DATA_RD
+#define SLM_DMND_WRITE		SNB_DMND_RFO
+#define SLM_DMND_PREFETCH	(SNB_PF_DATA_RD|SNB_PF_RFO)
+
+#define SLM_SNP_ANY		(SNB_SNP_NONE|SNB_SNP_MISS|SNB_NO_FWD|SNB_HITM)
+#define SLM_LLC_ACCESS		SNB_RESP_ANY
+#define SLM_LLC_MISS		(SLM_SNP_ANY|SNB_NON_DRAM)
+
+static __initconst const u64 slm_hw_cache_extra_regs
+				[PERF_COUNT_HW_CACHE_MAX]
+				[PERF_COUNT_HW_CACHE_OP_MAX]
+				[PERF_COUNT_HW_CACHE_RESULT_MAX] =
+{
+ [ C(LL  ) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = SLM_DMND_READ|SLM_LLC_ACCESS,
+		[ C(RESULT_MISS)   ] = 0,
+	},
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = SLM_DMND_WRITE|SLM_LLC_ACCESS,
+		[ C(RESULT_MISS)   ] = SLM_DMND_WRITE|SLM_LLC_MISS,
+	},
+	[ C(OP_PREFETCH) ] = {
+		[ C(RESULT_ACCESS) ] = SLM_DMND_PREFETCH|SLM_LLC_ACCESS,
+		[ C(RESULT_MISS)   ] = SLM_DMND_PREFETCH|SLM_LLC_MISS,
+	},
+ },
+};
+
+static __initconst const u64 slm_hw_cache_event_ids
+				[PERF_COUNT_HW_CACHE_MAX]
+				[PERF_COUNT_HW_CACHE_OP_MAX]
+				[PERF_COUNT_HW_CACHE_RESULT_MAX] =
+{
+ [ C(L1D) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = 0,
+		[ C(RESULT_MISS)   ] = 0x0104, /* LD_DCU_MISS */
+	},
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = 0,
+		[ C(RESULT_MISS)   ] = 0,
+	},
+	[ C(OP_PREFETCH) ] = {
+		[ C(RESULT_ACCESS) ] = 0,
+		[ C(RESULT_MISS)   ] = 0,
+	},
+ },
+ [ C(L1I ) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = 0x0380, /* ICACHE.ACCESSES */
+		[ C(RESULT_MISS)   ] = 0x0280, /* ICACGE.MISSES */
+	},
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = -1,
+		[ C(RESULT_MISS)   ] = -1,
+	},
+	[ C(OP_PREFETCH) ] = {
+		[ C(RESULT_ACCESS) ] = 0,
+		[ C(RESULT_MISS)   ] = 0,
+	},
+ },
+ [ C(LL  ) ] = {
+	[ C(OP_READ) ] = {
+		/* OFFCORE_RESPONSE.ANY_DATA.LOCAL_CACHE */
+		[ C(RESULT_ACCESS) ] = 0x01b7,
+		[ C(RESULT_MISS)   ] = 0,
+	},
+	[ C(OP_WRITE) ] = {
+		/* OFFCORE_RESPONSE.ANY_RFO.LOCAL_CACHE */
+		[ C(RESULT_ACCESS) ] = 0x01b7,
+		/* OFFCORE_RESPONSE.ANY_RFO.ANY_LLC_MISS */
+		[ C(RESULT_MISS)   ] = 0x01b7,
+	},
+	[ C(OP_PREFETCH) ] = {
+		/* OFFCORE_RESPONSE.PREFETCH.LOCAL_CACHE */
+		[ C(RESULT_ACCESS) ] = 0x01b7,
+		/* OFFCORE_RESPONSE.PREFETCH.ANY_LLC_MISS */
+		[ C(RESULT_MISS)   ] = 0x01b7,
+	},
+ },
+ [ C(DTLB) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = 0,
+		[ C(RESULT_MISS)   ] = 0x0804, /* LD_DTLB_MISS */
+	},
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = 0,
+		[ C(RESULT_MISS)   ] = 0,
+	},
+	[ C(OP_PREFETCH) ] = {
+		[ C(RESULT_ACCESS) ] = 0,
+		[ C(RESULT_MISS)   ] = 0,
+	},
+ },
+ [ C(ITLB) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = 0x00c0, /* INST_RETIRED.ANY_P */
+		[ C(RESULT_MISS)   ] = 0x40205, /* PAGE_WALKS.I_SIDE_WALKS */
+	},
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = -1,
+		[ C(RESULT_MISS)   ] = -1,
+	},
+	[ C(OP_PREFETCH) ] = {
+		[ C(RESULT_ACCESS) ] = -1,
+		[ C(RESULT_MISS)   ] = -1,
+	},
+ },
+ [ C(BPU ) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = 0x00c4, /* BR_INST_RETIRED.ANY */
+		[ C(RESULT_MISS)   ] = 0x00c5, /* BP_INST_RETIRED.MISPRED */
+	},
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = -1,
+		[ C(RESULT_MISS)   ] = -1,
+	},
+	[ C(OP_PREFETCH) ] = {
+		[ C(RESULT_ACCESS) ] = -1,
+		[ C(RESULT_MISS)   ] = -1,
+	},
+ },
+};
+
+#define KNL_OT_L2_HITE		BIT_ULL(19) /* Other Tile L2 Hit */
+#define KNL_OT_L2_HITF		BIT_ULL(20) /* Other Tile L2 Hit */
+#define KNL_MCDRAM_LOCAL	BIT_ULL(21)
+#define KNL_MCDRAM_FAR		BIT_ULL(22)
+#define KNL_DDR_LOCAL		BIT_ULL(23)
+#define KNL_DDR_FAR		BIT_ULL(24)
+#define KNL_DRAM_ANY		(KNL_MCDRAM_LOCAL | KNL_MCDRAM_FAR | \
+				    KNL_DDR_LOCAL | KNL_DDR_FAR)
+#define KNL_L2_READ		SLM_DMND_READ
+#define KNL_L2_WRITE		SLM_DMND_WRITE
+#define KNL_L2_PREFETCH		SLM_DMND_PREFETCH
+#define KNL_L2_ACCESS		SLM_LLC_ACCESS
+#define KNL_L2_MISS		(KNL_OT_L2_HITE | KNL_OT_L2_HITF | \
+				   KNL_DRAM_ANY | SNB_SNP_ANY | \
+						  SNB_NON_DRAM)
+
+static __initconst const u64 knl_hw_cache_extra_regs
+				[PERF_COUNT_HW_CACHE_MAX]
+				[PERF_COUNT_HW_CACHE_OP_MAX]
+				[PERF_COUNT_HW_CACHE_RESULT_MAX] = {
+	[C(LL)] = {
+		[C(OP_READ)] = {
+			[C(RESULT_ACCESS)] = KNL_L2_READ | KNL_L2_ACCESS,
+			[C(RESULT_MISS)]   = 0,
+		},
+		[C(OP_WRITE)] = {
+			[C(RESULT_ACCESS)] = KNL_L2_WRITE | KNL_L2_ACCESS,
+			[C(RESULT_MISS)]   = KNL_L2_WRITE | KNL_L2_MISS,
+		},
+		[C(OP_PREFETCH)] = {
+			[C(RESULT_ACCESS)] = KNL_L2_PREFETCH | KNL_L2_ACCESS,
+			[C(RESULT_MISS)]   = KNL_L2_PREFETCH | KNL_L2_MISS,
+		},
+	},
+};
+
+/*
+ * Used from PMIs where the LBRs are already disabled.
+ *
+ * This function could be called consecutively. It is required to remain in
+ * disabled state if called consecutively.
+ *
+ * During consecutive calls, the same disable value will be written to related
+ * registers, so the PMU state remains unchanged. hw.state in
+ * intel_bts_disable_local will remain PERF_HES_STOPPED too in consecutive
+ * calls.
+ */
+static void __intel_pmu_disable_all(void)
+{
+	struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
+
+	wrmsrl(MSR_CORE_PERF_GLOBAL_CTRL, 0);
+
+	if (test_bit(INTEL_PMC_IDX_FIXED_BTS, cpuc->active_mask))
+		intel_pmu_disable_bts();
+	else
+		intel_bts_disable_local();
+
+	intel_pmu_pebs_disable_all();
+}
+
+static void intel_pmu_disable_all(void)
+{
+	__intel_pmu_disable_all();
+	intel_pmu_lbr_disable_all();
+}
+
+static void __intel_pmu_enable_all(int added, bool pmi)
+{
+	struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
+
+	intel_pmu_pebs_enable_all();
+	intel_pmu_lbr_enable_all(pmi);
+	wrmsrl(MSR_CORE_PERF_GLOBAL_CTRL,
+			x86_pmu.intel_ctrl & ~cpuc->intel_ctrl_guest_mask);
+
+	if (test_bit(INTEL_PMC_IDX_FIXED_BTS, cpuc->active_mask)) {
+		struct perf_event *event =
+			cpuc->events[INTEL_PMC_IDX_FIXED_BTS];
+
+		if (WARN_ON_ONCE(!event))
+			return;
+
+		intel_pmu_enable_bts(event->hw.config);
+	} else
+		intel_bts_enable_local();
+}
+
+static void intel_pmu_enable_all(int added)
+{
+	__intel_pmu_enable_all(added, false);
+}
+
+/*
+ * Workaround for:
+ *   Intel Errata AAK100 (model 26)
+ *   Intel Errata AAP53  (model 30)
+ *   Intel Errata BD53   (model 44)
+ *
+ * The official story:
+ *   These chips need to be 'reset' when adding counters by programming the
+ *   magic three (non-counting) events 0x4300B5, 0x4300D2, and 0x4300B1 either
+ *   in sequence on the same PMC or on different PMCs.
+ *
+ * In practise it appears some of these events do in fact count, and
+ * we need to programm all 4 events.
+ */
+static void intel_pmu_nhm_workaround(void)
+{
+	struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
+	static const unsigned long nhm_magic[4] = {
+		0x4300B5,
+		0x4300D2,
+		0x4300B1,
+		0x4300B1
+	};
+	struct perf_event *event;
+	int i;
+
+	/*
+	 * The Errata requires below steps:
+	 * 1) Clear MSR_IA32_PEBS_ENABLE and MSR_CORE_PERF_GLOBAL_CTRL;
+	 * 2) Configure 4 PERFEVTSELx with the magic events and clear
+	 *    the corresponding PMCx;
+	 * 3) set bit0~bit3 of MSR_CORE_PERF_GLOBAL_CTRL;
+	 * 4) Clear MSR_CORE_PERF_GLOBAL_CTRL;
+	 * 5) Clear 4 pairs of ERFEVTSELx and PMCx;
+	 */
+
+	/*
+	 * The real steps we choose are a little different from above.
+	 * A) To reduce MSR operations, we don't run step 1) as they
+	 *    are already cleared before this function is called;
+	 * B) Call x86_perf_event_update to save PMCx before configuring
+	 *    PERFEVTSELx with magic number;
+	 * C) With step 5), we do clear only when the PERFEVTSELx is
+	 *    not used currently.
+	 * D) Call x86_perf_event_set_period to restore PMCx;
+	 */
+
+	/* We always operate 4 pairs of PERF Counters */
+	for (i = 0; i < 4; i++) {
+		event = cpuc->events[i];
+		if (event)
+			x86_perf_event_update(event);
+	}
+
+	for (i = 0; i < 4; i++) {
+		wrmsrl(MSR_ARCH_PERFMON_EVENTSEL0 + i, nhm_magic[i]);
+		wrmsrl(MSR_ARCH_PERFMON_PERFCTR0 + i, 0x0);
+	}
+
+	wrmsrl(MSR_CORE_PERF_GLOBAL_CTRL, 0xf);
+	wrmsrl(MSR_CORE_PERF_GLOBAL_CTRL, 0x0);
+
+	for (i = 0; i < 4; i++) {
+		event = cpuc->events[i];
+
+		if (event) {
+			x86_perf_event_set_period(event);
+			__x86_pmu_enable_event(&event->hw,
+					ARCH_PERFMON_EVENTSEL_ENABLE);
+		} else
+			wrmsrl(MSR_ARCH_PERFMON_EVENTSEL0 + i, 0x0);
+	}
+}
+
+static void intel_pmu_nhm_enable_all(int added)
+{
+	if (added)
+		intel_pmu_nhm_workaround();
+	intel_pmu_enable_all(added);
+}
+
+static inline u64 intel_pmu_get_status(void)
+{
+	u64 status;
+
+	rdmsrl(MSR_CORE_PERF_GLOBAL_STATUS, status);
+
+	return status;
+}
+
+static inline void intel_pmu_ack_status(u64 ack)
+{
+	wrmsrl(MSR_CORE_PERF_GLOBAL_OVF_CTRL, ack);
+}
+
+static void intel_pmu_disable_fixed(struct hw_perf_event *hwc)
+{
+	int idx = hwc->idx - INTEL_PMC_IDX_FIXED;
+	u64 ctrl_val, mask;
+
+	mask = 0xfULL << (idx * 4);
+
+	rdmsrl(hwc->config_base, ctrl_val);
+	ctrl_val &= ~mask;
+	wrmsrl(hwc->config_base, ctrl_val);
+}
+
+static inline bool event_is_checkpointed(struct perf_event *event)
+{
+	return (event->hw.config & HSW_IN_TX_CHECKPOINTED) != 0;
+}
+
+static void intel_pmu_disable_event(struct perf_event *event)
+{
+	struct hw_perf_event *hwc = &event->hw;
+	struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
+
+	if (unlikely(hwc->idx == INTEL_PMC_IDX_FIXED_BTS)) {
+		intel_pmu_disable_bts();
+		intel_pmu_drain_bts_buffer();
+		return;
+	}
+
+	cpuc->intel_ctrl_guest_mask &= ~(1ull << hwc->idx);
+	cpuc->intel_ctrl_host_mask &= ~(1ull << hwc->idx);
+	cpuc->intel_cp_status &= ~(1ull << hwc->idx);
+
+	/*
+	 * must disable before any actual event
+	 * because any event may be combined with LBR
+	 */
+	if (needs_branch_stack(event))
+		intel_pmu_lbr_disable(event);
+
+	if (unlikely(hwc->config_base == MSR_ARCH_PERFMON_FIXED_CTR_CTRL)) {
+		intel_pmu_disable_fixed(hwc);
+		return;
+	}
+
+	x86_pmu_disable_event(event);
+
+	if (unlikely(event->attr.precise_ip))
+		intel_pmu_pebs_disable(event);
+}
+
+static void intel_pmu_enable_fixed(struct hw_perf_event *hwc)
+{
+	int idx = hwc->idx - INTEL_PMC_IDX_FIXED;
+	u64 ctrl_val, bits, mask;
+
+	/*
+	 * Enable IRQ generation (0x8),
+	 * and enable ring-3 counting (0x2) and ring-0 counting (0x1)
+	 * if requested:
+	 */
+	bits = 0x8ULL;
+	if (hwc->config & ARCH_PERFMON_EVENTSEL_USR)
+		bits |= 0x2;
+	if (hwc->config & ARCH_PERFMON_EVENTSEL_OS)
+		bits |= 0x1;
+
+	/*
+	 * ANY bit is supported in v3 and up
+	 */
+	if (x86_pmu.version > 2 && hwc->config & ARCH_PERFMON_EVENTSEL_ANY)
+		bits |= 0x4;
+
+	bits <<= (idx * 4);
+	mask = 0xfULL << (idx * 4);
+
+	rdmsrl(hwc->config_base, ctrl_val);
+	ctrl_val &= ~mask;
+	ctrl_val |= bits;
+	wrmsrl(hwc->config_base, ctrl_val);
+}
+
+static void intel_pmu_enable_event(struct perf_event *event)
+{
+	struct hw_perf_event *hwc = &event->hw;
+	struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
+
+	if (unlikely(hwc->idx == INTEL_PMC_IDX_FIXED_BTS)) {
+		if (!__this_cpu_read(cpu_hw_events.enabled))
+			return;
+
+		intel_pmu_enable_bts(hwc->config);
+		return;
+	}
+	/*
+	 * must enabled before any actual event
+	 * because any event may be combined with LBR
+	 */
+	if (needs_branch_stack(event))
+		intel_pmu_lbr_enable(event);
+
+	if (event->attr.exclude_host)
+		cpuc->intel_ctrl_guest_mask |= (1ull << hwc->idx);
+	if (event->attr.exclude_guest)
+		cpuc->intel_ctrl_host_mask |= (1ull << hwc->idx);
+
+	if (unlikely(event_is_checkpointed(event)))
+		cpuc->intel_cp_status |= (1ull << hwc->idx);
+
+	if (unlikely(hwc->config_base == MSR_ARCH_PERFMON_FIXED_CTR_CTRL)) {
+		intel_pmu_enable_fixed(hwc);
+		return;
+	}
+
+	if (unlikely(event->attr.precise_ip))
+		intel_pmu_pebs_enable(event);
+
+	__x86_pmu_enable_event(hwc, ARCH_PERFMON_EVENTSEL_ENABLE);
+}
+
+/*
+ * Save and restart an expired event. Called by NMI contexts,
+ * so it has to be careful about preempting normal event ops:
+ */
+int intel_pmu_save_and_restart(struct perf_event *event)
+{
+	x86_perf_event_update(event);
+	/*
+	 * For a checkpointed counter always reset back to 0.  This
+	 * avoids a situation where the counter overflows, aborts the
+	 * transaction and is then set back to shortly before the
+	 * overflow, and overflows and aborts again.
+	 */
+	if (unlikely(event_is_checkpointed(event))) {
+		/* No race with NMIs because the counter should not be armed */
+		wrmsrl(event->hw.event_base, 0);
+		local64_set(&event->hw.prev_count, 0);
+	}
+	return x86_perf_event_set_period(event);
+}
+
+static void intel_pmu_reset(void)
+{
+	struct debug_store *ds = __this_cpu_read(cpu_hw_events.ds);
+	unsigned long flags;
+	int idx;
+
+	if (!x86_pmu.num_counters)
+		return;
+
+	local_irq_save(flags);
+
+	pr_info("clearing PMU state on CPU#%d\n", smp_processor_id());
+
+	for (idx = 0; idx < x86_pmu.num_counters; idx++) {
+		wrmsrl_safe(x86_pmu_config_addr(idx), 0ull);
+		wrmsrl_safe(x86_pmu_event_addr(idx),  0ull);
+	}
+	for (idx = 0; idx < x86_pmu.num_counters_fixed; idx++)
+		wrmsrl_safe(MSR_ARCH_PERFMON_FIXED_CTR0 + idx, 0ull);
+
+	if (ds)
+		ds->bts_index = ds->bts_buffer_base;
+
+	/* Ack all overflows and disable fixed counters */
+	if (x86_pmu.version >= 2) {
+		intel_pmu_ack_status(intel_pmu_get_status());
+		wrmsrl(MSR_CORE_PERF_GLOBAL_CTRL, 0);
+	}
+
+	/* Reset LBRs and LBR freezing */
+	if (x86_pmu.lbr_nr) {
+		update_debugctlmsr(get_debugctlmsr() &
+			~(DEBUGCTLMSR_FREEZE_LBRS_ON_PMI|DEBUGCTLMSR_LBR));
+	}
+
+	local_irq_restore(flags);
+}
+
+/*
+ * This handler is triggered by the local APIC, so the APIC IRQ handling
+ * rules apply:
+ */
+static int intel_pmu_handle_irq(struct pt_regs *regs)
+{
+	struct perf_sample_data data;
+	struct cpu_hw_events *cpuc;
+	int bit, loops;
+	u64 status;
+	int handled;
+
+	cpuc = this_cpu_ptr(&cpu_hw_events);
+
+	/*
+	 * No known reason to not always do late ACK,
+	 * but just in case do it opt-in.
+	 */
+	if (!x86_pmu.late_ack)
+		apic_write(APIC_LVTPC, APIC_DM_NMI);
+	__intel_pmu_disable_all();
+	handled = intel_pmu_drain_bts_buffer();
+	handled += intel_bts_interrupt();
+	status = intel_pmu_get_status();
+	if (!status)
+		goto done;
+
+	loops = 0;
+again:
+	intel_pmu_lbr_read();
+	intel_pmu_ack_status(status);
+	if (++loops > 100) {
+		static bool warned = false;
+		if (!warned) {
+			WARN(1, "perfevents: irq loop stuck!\n");
+			perf_event_print_debug();
+			warned = true;
+		}
+		intel_pmu_reset();
+		goto done;
+	}
+
+	inc_irq_stat(apic_perf_irqs);
+
+
+	/*
+	 * Ignore a range of extra bits in status that do not indicate
+	 * overflow by themselves.
+	 */
+	status &= ~(GLOBAL_STATUS_COND_CHG |
+		    GLOBAL_STATUS_ASIF |
+		    GLOBAL_STATUS_LBRS_FROZEN);
+	if (!status)
+		goto done;
+
+	/*
+	 * PEBS overflow sets bit 62 in the global status register
+	 */
+	if (__test_and_clear_bit(62, (unsigned long *)&status)) {
+		handled++;
+		x86_pmu.drain_pebs(regs);
+		/*
+		 * There are cases where, even though, the PEBS ovfl bit is set
+		 * in GLOBAL_OVF_STATUS, the PEBS events may also have their
+		 * overflow bits set for their counters. We must clear them
+		 * here because they have been processed as exact samples in
+		 * the drain_pebs() routine. They must not be processed again
+		 * in the for_each_bit_set() loop for regular samples below.
+		 */
+		status &= ~cpuc->pebs_enabled;
+		status &= x86_pmu.intel_ctrl | GLOBAL_STATUS_TRACE_TOPAPMI;
+	}
+
+	/*
+	 * Intel PT
+	 */
+	if (__test_and_clear_bit(55, (unsigned long *)&status)) {
+		handled++;
+		intel_pt_interrupt();
+	}
+
+	/*
+	 * Checkpointed counters can lead to 'spurious' PMIs because the
+	 * rollback caused by the PMI will have cleared the overflow status
+	 * bit. Therefore always force probe these counters.
+	 */
+	status |= cpuc->intel_cp_status;
+
+	for_each_set_bit(bit, (unsigned long *)&status, X86_PMC_IDX_MAX) {
+		struct perf_event *event = cpuc->events[bit];
+
+		handled++;
+
+		if (!test_bit(bit, cpuc->active_mask))
+			continue;
+
+		if (!intel_pmu_save_and_restart(event))
+			continue;
+
+		perf_sample_data_init(&data, 0, event->hw.last_period);
+
+		if (has_branch_stack(event))
+			data.br_stack = &cpuc->lbr_stack;
+
+		if (perf_event_overflow(event, &data, regs))
+			x86_pmu_stop(event, 0);
+	}
+
+	/*
+	 * Repeat if there is more work to be done:
+	 */
+	status = intel_pmu_get_status();
+	if (status)
+		goto again;
+
+done:
+	/* Only restore PMU state when it's active. See x86_pmu_disable(). */
+	if (cpuc->enabled)
+		__intel_pmu_enable_all(0, true);
+
+	/*
+	 * Only unmask the NMI after the overflow counters
+	 * have been reset. This avoids spurious NMIs on
+	 * Haswell CPUs.
+	 */
+	if (x86_pmu.late_ack)
+		apic_write(APIC_LVTPC, APIC_DM_NMI);
+	return handled;
+}
+
+static struct event_constraint *
+intel_bts_constraints(struct perf_event *event)
+{
+	struct hw_perf_event *hwc = &event->hw;
+	unsigned int hw_event, bts_event;
+
+	if (event->attr.freq)
+		return NULL;
+
+	hw_event = hwc->config & INTEL_ARCH_EVENT_MASK;
+	bts_event = x86_pmu.event_map(PERF_COUNT_HW_BRANCH_INSTRUCTIONS);
+
+	if (unlikely(hw_event == bts_event && hwc->sample_period == 1))
+		return &bts_constraint;
+
+	return NULL;
+}
+
+static int intel_alt_er(int idx, u64 config)
+{
+	int alt_idx;
+	if (!(x86_pmu.flags & PMU_FL_HAS_RSP_1))
+		return idx;
+
+	if (idx == EXTRA_REG_RSP_0)
+		alt_idx = EXTRA_REG_RSP_1;
+
+	if (idx == EXTRA_REG_RSP_1)
+		alt_idx = EXTRA_REG_RSP_0;
+
+	if (config & ~x86_pmu.extra_regs[alt_idx].valid_mask)
+		return idx;
+
+	return alt_idx;
+}
+
+static void intel_fixup_er(struct perf_event *event, int idx)
+{
+	event->hw.extra_reg.idx = idx;
+
+	if (idx == EXTRA_REG_RSP_0) {
+		event->hw.config &= ~INTEL_ARCH_EVENT_MASK;
+		event->hw.config |= x86_pmu.extra_regs[EXTRA_REG_RSP_0].event;
+		event->hw.extra_reg.reg = MSR_OFFCORE_RSP_0;
+	} else if (idx == EXTRA_REG_RSP_1) {
+		event->hw.config &= ~INTEL_ARCH_EVENT_MASK;
+		event->hw.config |= x86_pmu.extra_regs[EXTRA_REG_RSP_1].event;
+		event->hw.extra_reg.reg = MSR_OFFCORE_RSP_1;
+	}
+}
+
+/*
+ * manage allocation of shared extra msr for certain events
+ *
+ * sharing can be:
+ * per-cpu: to be shared between the various events on a single PMU
+ * per-core: per-cpu + shared by HT threads
+ */
+static struct event_constraint *
+__intel_shared_reg_get_constraints(struct cpu_hw_events *cpuc,
+				   struct perf_event *event,
+				   struct hw_perf_event_extra *reg)
+{
+	struct event_constraint *c = &emptyconstraint;
+	struct er_account *era;
+	unsigned long flags;
+	int idx = reg->idx;
+
+	/*
+	 * reg->alloc can be set due to existing state, so for fake cpuc we
+	 * need to ignore this, otherwise we might fail to allocate proper fake
+	 * state for this extra reg constraint. Also see the comment below.
+	 */
+	if (reg->alloc && !cpuc->is_fake)
+		return NULL; /* call x86_get_event_constraint() */
+
+again:
+	era = &cpuc->shared_regs->regs[idx];
+	/*
+	 * we use spin_lock_irqsave() to avoid lockdep issues when
+	 * passing a fake cpuc
+	 */
+	raw_spin_lock_irqsave(&era->lock, flags);
+
+	if (!atomic_read(&era->ref) || era->config == reg->config) {
+
+		/*
+		 * If its a fake cpuc -- as per validate_{group,event}() we
+		 * shouldn't touch event state and we can avoid doing so
+		 * since both will only call get_event_constraints() once
+		 * on each event, this avoids the need for reg->alloc.
+		 *
+		 * Not doing the ER fixup will only result in era->reg being
+		 * wrong, but since we won't actually try and program hardware
+		 * this isn't a problem either.
+		 */
+		if (!cpuc->is_fake) {
+			if (idx != reg->idx)
+				intel_fixup_er(event, idx);
+
+			/*
+			 * x86_schedule_events() can call get_event_constraints()
+			 * multiple times on events in the case of incremental
+			 * scheduling(). reg->alloc ensures we only do the ER
+			 * allocation once.
+			 */
+			reg->alloc = 1;
+		}
+
+		/* lock in msr value */
+		era->config = reg->config;
+		era->reg = reg->reg;
+
+		/* one more user */
+		atomic_inc(&era->ref);
+
+		/*
+		 * need to call x86_get_event_constraint()
+		 * to check if associated event has constraints
+		 */
+		c = NULL;
+	} else {
+		idx = intel_alt_er(idx, reg->config);
+		if (idx != reg->idx) {
+			raw_spin_unlock_irqrestore(&era->lock, flags);
+			goto again;
+		}
+	}
+	raw_spin_unlock_irqrestore(&era->lock, flags);
+
+	return c;
+}
+
+static void
+__intel_shared_reg_put_constraints(struct cpu_hw_events *cpuc,
+				   struct hw_perf_event_extra *reg)
+{
+	struct er_account *era;
+
+	/*
+	 * Only put constraint if extra reg was actually allocated. Also takes
+	 * care of event which do not use an extra shared reg.
+	 *
+	 * Also, if this is a fake cpuc we shouldn't touch any event state
+	 * (reg->alloc) and we don't care about leaving inconsistent cpuc state
+	 * either since it'll be thrown out.
+	 */
+	if (!reg->alloc || cpuc->is_fake)
+		return;
+
+	era = &cpuc->shared_regs->regs[reg->idx];
+
+	/* one fewer user */
+	atomic_dec(&era->ref);
+
+	/* allocate again next time */
+	reg->alloc = 0;
+}
+
+static struct event_constraint *
+intel_shared_regs_constraints(struct cpu_hw_events *cpuc,
+			      struct perf_event *event)
+{
+	struct event_constraint *c = NULL, *d;
+	struct hw_perf_event_extra *xreg, *breg;
+
+	xreg = &event->hw.extra_reg;
+	if (xreg->idx != EXTRA_REG_NONE) {
+		c = __intel_shared_reg_get_constraints(cpuc, event, xreg);
+		if (c == &emptyconstraint)
+			return c;
+	}
+	breg = &event->hw.branch_reg;
+	if (breg->idx != EXTRA_REG_NONE) {
+		d = __intel_shared_reg_get_constraints(cpuc, event, breg);
+		if (d == &emptyconstraint) {
+			__intel_shared_reg_put_constraints(cpuc, xreg);
+			c = d;
+		}
+	}
+	return c;
+}
+
+struct event_constraint *
+x86_get_event_constraints(struct cpu_hw_events *cpuc, int idx,
+			  struct perf_event *event)
+{
+	struct event_constraint *c;
+
+	if (x86_pmu.event_constraints) {
+		for_each_event_constraint(c, x86_pmu.event_constraints) {
+			if ((event->hw.config & c->cmask) == c->code) {
+				event->hw.flags |= c->flags;
+				return c;
+			}
+		}
+	}
+
+	return &unconstrained;
+}
+
+static struct event_constraint *
+__intel_get_event_constraints(struct cpu_hw_events *cpuc, int idx,
+			    struct perf_event *event)
+{
+	struct event_constraint *c;
+
+	c = intel_bts_constraints(event);
+	if (c)
+		return c;
+
+	c = intel_shared_regs_constraints(cpuc, event);
+	if (c)
+		return c;
+
+	c = intel_pebs_constraints(event);
+	if (c)
+		return c;
+
+	return x86_get_event_constraints(cpuc, idx, event);
+}
+
+static void
+intel_start_scheduling(struct cpu_hw_events *cpuc)
+{
+	struct intel_excl_cntrs *excl_cntrs = cpuc->excl_cntrs;
+	struct intel_excl_states *xl;
+	int tid = cpuc->excl_thread_id;
+
+	/*
+	 * nothing needed if in group validation mode
+	 */
+	if (cpuc->is_fake || !is_ht_workaround_enabled())
+		return;
+
+	/*
+	 * no exclusion needed
+	 */
+	if (WARN_ON_ONCE(!excl_cntrs))
+		return;
+
+	xl = &excl_cntrs->states[tid];
+
+	xl->sched_started = true;
+	/*
+	 * lock shared state until we are done scheduling
+	 * in stop_event_scheduling()
+	 * makes scheduling appear as a transaction
+	 */
+	raw_spin_lock(&excl_cntrs->lock);
+}
+
+static void intel_commit_scheduling(struct cpu_hw_events *cpuc, int idx, int cntr)
+{
+	struct intel_excl_cntrs *excl_cntrs = cpuc->excl_cntrs;
+	struct event_constraint *c = cpuc->event_constraint[idx];
+	struct intel_excl_states *xl;
+	int tid = cpuc->excl_thread_id;
+
+	if (cpuc->is_fake || !is_ht_workaround_enabled())
+		return;
+
+	if (WARN_ON_ONCE(!excl_cntrs))
+		return;
+
+	if (!(c->flags & PERF_X86_EVENT_DYNAMIC))
+		return;
+
+	xl = &excl_cntrs->states[tid];
+
+	lockdep_assert_held(&excl_cntrs->lock);
+
+	if (c->flags & PERF_X86_EVENT_EXCL)
+		xl->state[cntr] = INTEL_EXCL_EXCLUSIVE;
+	else
+		xl->state[cntr] = INTEL_EXCL_SHARED;
+}
+
+static void
+intel_stop_scheduling(struct cpu_hw_events *cpuc)
+{
+	struct intel_excl_cntrs *excl_cntrs = cpuc->excl_cntrs;
+	struct intel_excl_states *xl;
+	int tid = cpuc->excl_thread_id;
+
+	/*
+	 * nothing needed if in group validation mode
+	 */
+	if (cpuc->is_fake || !is_ht_workaround_enabled())
+		return;
+	/*
+	 * no exclusion needed
+	 */
+	if (WARN_ON_ONCE(!excl_cntrs))
+		return;
+
+	xl = &excl_cntrs->states[tid];
+
+	xl->sched_started = false;
+	/*
+	 * release shared state lock (acquired in intel_start_scheduling())
+	 */
+	raw_spin_unlock(&excl_cntrs->lock);
+}
+
+static struct event_constraint *
+intel_get_excl_constraints(struct cpu_hw_events *cpuc, struct perf_event *event,
+			   int idx, struct event_constraint *c)
+{
+	struct intel_excl_cntrs *excl_cntrs = cpuc->excl_cntrs;
+	struct intel_excl_states *xlo;
+	int tid = cpuc->excl_thread_id;
+	int is_excl, i;
+
+	/*
+	 * validating a group does not require
+	 * enforcing cross-thread  exclusion
+	 */
+	if (cpuc->is_fake || !is_ht_workaround_enabled())
+		return c;
+
+	/*
+	 * no exclusion needed
+	 */
+	if (WARN_ON_ONCE(!excl_cntrs))
+		return c;
+
+	/*
+	 * because we modify the constraint, we need
+	 * to make a copy. Static constraints come
+	 * from static const tables.
+	 *
+	 * only needed when constraint has not yet
+	 * been cloned (marked dynamic)
+	 */
+	if (!(c->flags & PERF_X86_EVENT_DYNAMIC)) {
+		struct event_constraint *cx;
+
+		/*
+		 * grab pre-allocated constraint entry
+		 */
+		cx = &cpuc->constraint_list[idx];
+
+		/*
+		 * initialize dynamic constraint
+		 * with static constraint
+		 */
+		*cx = *c;
+
+		/*
+		 * mark constraint as dynamic, so we
+		 * can free it later on
+		 */
+		cx->flags |= PERF_X86_EVENT_DYNAMIC;
+		c = cx;
+	}
+
+	/*
+	 * From here on, the constraint is dynamic.
+	 * Either it was just allocated above, or it
+	 * was allocated during a earlier invocation
+	 * of this function
+	 */
+
+	/*
+	 * state of sibling HT
+	 */
+	xlo = &excl_cntrs->states[tid ^ 1];
+
+	/*
+	 * event requires exclusive counter access
+	 * across HT threads
+	 */
+	is_excl = c->flags & PERF_X86_EVENT_EXCL;
+	if (is_excl && !(event->hw.flags & PERF_X86_EVENT_EXCL_ACCT)) {
+		event->hw.flags |= PERF_X86_EVENT_EXCL_ACCT;
+		if (!cpuc->n_excl++)
+			WRITE_ONCE(excl_cntrs->has_exclusive[tid], 1);
+	}
+
+	/*
+	 * Modify static constraint with current dynamic
+	 * state of thread
+	 *
+	 * EXCLUSIVE: sibling counter measuring exclusive event
+	 * SHARED   : sibling counter measuring non-exclusive event
+	 * UNUSED   : sibling counter unused
+	 */
+	for_each_set_bit(i, c->idxmsk, X86_PMC_IDX_MAX) {
+		/*
+		 * exclusive event in sibling counter
+		 * our corresponding counter cannot be used
+		 * regardless of our event
+		 */
+		if (xlo->state[i] == INTEL_EXCL_EXCLUSIVE)
+			__clear_bit(i, c->idxmsk);
+		/*
+		 * if measuring an exclusive event, sibling
+		 * measuring non-exclusive, then counter cannot
+		 * be used
+		 */
+		if (is_excl && xlo->state[i] == INTEL_EXCL_SHARED)
+			__clear_bit(i, c->idxmsk);
+	}
+
+	/*
+	 * recompute actual bit weight for scheduling algorithm
+	 */
+	c->weight = hweight64(c->idxmsk64);
+
+	/*
+	 * if we return an empty mask, then switch
+	 * back to static empty constraint to avoid
+	 * the cost of freeing later on
+	 */
+	if (c->weight == 0)
+		c = &emptyconstraint;
+
+	return c;
+}
+
+static struct event_constraint *
+intel_get_event_constraints(struct cpu_hw_events *cpuc, int idx,
+			    struct perf_event *event)
+{
+	struct event_constraint *c1 = NULL;
+	struct event_constraint *c2;
+
+	if (idx >= 0) /* fake does < 0 */
+		c1 = cpuc->event_constraint[idx];
+
+	/*
+	 * first time only
+	 * - static constraint: no change across incremental scheduling calls
+	 * - dynamic constraint: handled by intel_get_excl_constraints()
+	 */
+	c2 = __intel_get_event_constraints(cpuc, idx, event);
+	if (c1 && (c1->flags & PERF_X86_EVENT_DYNAMIC)) {
+		bitmap_copy(c1->idxmsk, c2->idxmsk, X86_PMC_IDX_MAX);
+		c1->weight = c2->weight;
+		c2 = c1;
+	}
+
+	if (cpuc->excl_cntrs)
+		return intel_get_excl_constraints(cpuc, event, idx, c2);
+
+	return c2;
+}
+
+static void intel_put_excl_constraints(struct cpu_hw_events *cpuc,
+		struct perf_event *event)
+{
+	struct hw_perf_event *hwc = &event->hw;
+	struct intel_excl_cntrs *excl_cntrs = cpuc->excl_cntrs;
+	int tid = cpuc->excl_thread_id;
+	struct intel_excl_states *xl;
+
+	/*
+	 * nothing needed if in group validation mode
+	 */
+	if (cpuc->is_fake)
+		return;
+
+	if (WARN_ON_ONCE(!excl_cntrs))
+		return;
+
+	if (hwc->flags & PERF_X86_EVENT_EXCL_ACCT) {
+		hwc->flags &= ~PERF_X86_EVENT_EXCL_ACCT;
+		if (!--cpuc->n_excl)
+			WRITE_ONCE(excl_cntrs->has_exclusive[tid], 0);
+	}
+
+	/*
+	 * If event was actually assigned, then mark the counter state as
+	 * unused now.
+	 */
+	if (hwc->idx >= 0) {
+		xl = &excl_cntrs->states[tid];
+
+		/*
+		 * put_constraint may be called from x86_schedule_events()
+		 * which already has the lock held so here make locking
+		 * conditional.
+		 */
+		if (!xl->sched_started)
+			raw_spin_lock(&excl_cntrs->lock);
+
+		xl->state[hwc->idx] = INTEL_EXCL_UNUSED;
+
+		if (!xl->sched_started)
+			raw_spin_unlock(&excl_cntrs->lock);
+	}
+}
+
+static void
+intel_put_shared_regs_event_constraints(struct cpu_hw_events *cpuc,
+					struct perf_event *event)
+{
+	struct hw_perf_event_extra *reg;
+
+	reg = &event->hw.extra_reg;
+	if (reg->idx != EXTRA_REG_NONE)
+		__intel_shared_reg_put_constraints(cpuc, reg);
+
+	reg = &event->hw.branch_reg;
+	if (reg->idx != EXTRA_REG_NONE)
+		__intel_shared_reg_put_constraints(cpuc, reg);
+}
+
+static void intel_put_event_constraints(struct cpu_hw_events *cpuc,
+					struct perf_event *event)
+{
+	intel_put_shared_regs_event_constraints(cpuc, event);
+
+	/*
+	 * is PMU has exclusive counter restrictions, then
+	 * all events are subject to and must call the
+	 * put_excl_constraints() routine
+	 */
+	if (cpuc->excl_cntrs)
+		intel_put_excl_constraints(cpuc, event);
+}
+
+static void intel_pebs_aliases_core2(struct perf_event *event)
+{
+	if ((event->hw.config & X86_RAW_EVENT_MASK) == 0x003c) {
+		/*
+		 * Use an alternative encoding for CPU_CLK_UNHALTED.THREAD_P
+		 * (0x003c) so that we can use it with PEBS.
+		 *
+		 * The regular CPU_CLK_UNHALTED.THREAD_P event (0x003c) isn't
+		 * PEBS capable. However we can use INST_RETIRED.ANY_P
+		 * (0x00c0), which is a PEBS capable event, to get the same
+		 * count.
+		 *
+		 * INST_RETIRED.ANY_P counts the number of cycles that retires
+		 * CNTMASK instructions. By setting CNTMASK to a value (16)
+		 * larger than the maximum number of instructions that can be
+		 * retired per cycle (4) and then inverting the condition, we
+		 * count all cycles that retire 16 or less instructions, which
+		 * is every cycle.
+		 *
+		 * Thereby we gain a PEBS capable cycle counter.
+		 */
+		u64 alt_config = X86_CONFIG(.event=0xc0, .inv=1, .cmask=16);
+
+		alt_config |= (event->hw.config & ~X86_RAW_EVENT_MASK);
+		event->hw.config = alt_config;
+	}
+}
+
+static void intel_pebs_aliases_snb(struct perf_event *event)
+{
+	if ((event->hw.config & X86_RAW_EVENT_MASK) == 0x003c) {
+		/*
+		 * Use an alternative encoding for CPU_CLK_UNHALTED.THREAD_P
+		 * (0x003c) so that we can use it with PEBS.
+		 *
+		 * The regular CPU_CLK_UNHALTED.THREAD_P event (0x003c) isn't
+		 * PEBS capable. However we can use UOPS_RETIRED.ALL
+		 * (0x01c2), which is a PEBS capable event, to get the same
+		 * count.
+		 *
+		 * UOPS_RETIRED.ALL counts the number of cycles that retires
+		 * CNTMASK micro-ops. By setting CNTMASK to a value (16)
+		 * larger than the maximum number of micro-ops that can be
+		 * retired per cycle (4) and then inverting the condition, we
+		 * count all cycles that retire 16 or less micro-ops, which
+		 * is every cycle.
+		 *
+		 * Thereby we gain a PEBS capable cycle counter.
+		 */
+		u64 alt_config = X86_CONFIG(.event=0xc2, .umask=0x01, .inv=1, .cmask=16);
+
+		alt_config |= (event->hw.config & ~X86_RAW_EVENT_MASK);
+		event->hw.config = alt_config;
+	}
+}
+
+static unsigned long intel_pmu_free_running_flags(struct perf_event *event)
+{
+	unsigned long flags = x86_pmu.free_running_flags;
+
+	if (event->attr.use_clockid)
+		flags &= ~PERF_SAMPLE_TIME;
+	return flags;
+}
+
+static int intel_pmu_hw_config(struct perf_event *event)
+{
+	int ret = x86_pmu_hw_config(event);
+
+	if (ret)
+		return ret;
+
+	if (event->attr.precise_ip) {
+		if (!event->attr.freq) {
+			event->hw.flags |= PERF_X86_EVENT_AUTO_RELOAD;
+			if (!(event->attr.sample_type &
+			      ~intel_pmu_free_running_flags(event)))
+				event->hw.flags |= PERF_X86_EVENT_FREERUNNING;
+		}
+		if (x86_pmu.pebs_aliases)
+			x86_pmu.pebs_aliases(event);
+	}
+
+	if (needs_branch_stack(event)) {
+		ret = intel_pmu_setup_lbr_filter(event);
+		if (ret)
+			return ret;
+
+		/*
+		 * BTS is set up earlier in this path, so don't account twice
+		 */
+		if (!intel_pmu_has_bts(event)) {
+			/* disallow lbr if conflicting events are present */
+			if (x86_add_exclusive(x86_lbr_exclusive_lbr))
+				return -EBUSY;
+
+			event->destroy = hw_perf_lbr_event_destroy;
+		}
+	}
+
+	if (event->attr.type != PERF_TYPE_RAW)
+		return 0;
+
+	if (!(event->attr.config & ARCH_PERFMON_EVENTSEL_ANY))
+		return 0;
+
+	if (x86_pmu.version < 3)
+		return -EINVAL;
+
+	if (perf_paranoid_cpu() && !capable(CAP_SYS_ADMIN))
+		return -EACCES;
+
+	event->hw.config |= ARCH_PERFMON_EVENTSEL_ANY;
+
+	return 0;
+}
+
+struct perf_guest_switch_msr *perf_guest_get_msrs(int *nr)
+{
+	if (x86_pmu.guest_get_msrs)
+		return x86_pmu.guest_get_msrs(nr);
+	*nr = 0;
+	return NULL;
+}
+EXPORT_SYMBOL_GPL(perf_guest_get_msrs);
+
+static struct perf_guest_switch_msr *intel_guest_get_msrs(int *nr)
+{
+	struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
+	struct perf_guest_switch_msr *arr = cpuc->guest_switch_msrs;
+
+	arr[0].msr = MSR_CORE_PERF_GLOBAL_CTRL;
+	arr[0].host = x86_pmu.intel_ctrl & ~cpuc->intel_ctrl_guest_mask;
+	arr[0].guest = x86_pmu.intel_ctrl & ~cpuc->intel_ctrl_host_mask;
+	/*
+	 * If PMU counter has PEBS enabled it is not enough to disable counter
+	 * on a guest entry since PEBS memory write can overshoot guest entry
+	 * and corrupt guest memory. Disabling PEBS solves the problem.
+	 */
+	arr[1].msr = MSR_IA32_PEBS_ENABLE;
+	arr[1].host = cpuc->pebs_enabled;
+	arr[1].guest = 0;
+
+	*nr = 2;
+	return arr;
+}
+
+static struct perf_guest_switch_msr *core_guest_get_msrs(int *nr)
+{
+	struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
+	struct perf_guest_switch_msr *arr = cpuc->guest_switch_msrs;
+	int idx;
+
+	for (idx = 0; idx < x86_pmu.num_counters; idx++)  {
+		struct perf_event *event = cpuc->events[idx];
+
+		arr[idx].msr = x86_pmu_config_addr(idx);
+		arr[idx].host = arr[idx].guest = 0;
+
+		if (!test_bit(idx, cpuc->active_mask))
+			continue;
+
+		arr[idx].host = arr[idx].guest =
+			event->hw.config | ARCH_PERFMON_EVENTSEL_ENABLE;
+
+		if (event->attr.exclude_host)
+			arr[idx].host &= ~ARCH_PERFMON_EVENTSEL_ENABLE;
+		else if (event->attr.exclude_guest)
+			arr[idx].guest &= ~ARCH_PERFMON_EVENTSEL_ENABLE;
+	}
+
+	*nr = x86_pmu.num_counters;
+	return arr;
+}
+
+static void core_pmu_enable_event(struct perf_event *event)
+{
+	if (!event->attr.exclude_host)
+		x86_pmu_enable_event(event);
+}
+
+static void core_pmu_enable_all(int added)
+{
+	struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
+	int idx;
+
+	for (idx = 0; idx < x86_pmu.num_counters; idx++) {
+		struct hw_perf_event *hwc = &cpuc->events[idx]->hw;
+
+		if (!test_bit(idx, cpuc->active_mask) ||
+				cpuc->events[idx]->attr.exclude_host)
+			continue;
+
+		__x86_pmu_enable_event(hwc, ARCH_PERFMON_EVENTSEL_ENABLE);
+	}
+}
+
+static int hsw_hw_config(struct perf_event *event)
+{
+	int ret = intel_pmu_hw_config(event);
+
+	if (ret)
+		return ret;
+	if (!boot_cpu_has(X86_FEATURE_RTM) && !boot_cpu_has(X86_FEATURE_HLE))
+		return 0;
+	event->hw.config |= event->attr.config & (HSW_IN_TX|HSW_IN_TX_CHECKPOINTED);
+
+	/*
+	 * IN_TX/IN_TX-CP filters are not supported by the Haswell PMU with
+	 * PEBS or in ANY thread mode. Since the results are non-sensical forbid
+	 * this combination.
+	 */
+	if ((event->hw.config & (HSW_IN_TX|HSW_IN_TX_CHECKPOINTED)) &&
+	     ((event->hw.config & ARCH_PERFMON_EVENTSEL_ANY) ||
+	      event->attr.precise_ip > 0))
+		return -EOPNOTSUPP;
+
+	if (event_is_checkpointed(event)) {
+		/*
+		 * Sampling of checkpointed events can cause situations where
+		 * the CPU constantly aborts because of a overflow, which is
+		 * then checkpointed back and ignored. Forbid checkpointing
+		 * for sampling.
+		 *
+		 * But still allow a long sampling period, so that perf stat
+		 * from KVM works.
+		 */
+		if (event->attr.sample_period > 0 &&
+		    event->attr.sample_period < 0x7fffffff)
+			return -EOPNOTSUPP;
+	}
+	return 0;
+}
+
+static struct event_constraint counter2_constraint =
+			EVENT_CONSTRAINT(0, 0x4, 0);
+
+static struct event_constraint *
+hsw_get_event_constraints(struct cpu_hw_events *cpuc, int idx,
+			  struct perf_event *event)
+{
+	struct event_constraint *c;
+
+	c = intel_get_event_constraints(cpuc, idx, event);
+
+	/* Handle special quirk on in_tx_checkpointed only in counter 2 */
+	if (event->hw.config & HSW_IN_TX_CHECKPOINTED) {
+		if (c->idxmsk64 & (1U << 2))
+			return &counter2_constraint;
+		return &emptyconstraint;
+	}
+
+	return c;
+}
+
+/*
+ * Broadwell:
+ *
+ * The INST_RETIRED.ALL period always needs to have lowest 6 bits cleared
+ * (BDM55) and it must not use a period smaller than 100 (BDM11). We combine
+ * the two to enforce a minimum period of 128 (the smallest value that has bits
+ * 0-5 cleared and >= 100).
+ *
+ * Because of how the code in x86_perf_event_set_period() works, the truncation
+ * of the lower 6 bits is 'harmless' as we'll occasionally add a longer period
+ * to make up for the 'lost' events due to carrying the 'error' in period_left.
+ *
+ * Therefore the effective (average) period matches the requested period,
+ * despite coarser hardware granularity.
+ */
+static unsigned bdw_limit_period(struct perf_event *event, unsigned left)
+{
+	if ((event->hw.config & INTEL_ARCH_EVENT_MASK) ==
+			X86_CONFIG(.event=0xc0, .umask=0x01)) {
+		if (left < 128)
+			left = 128;
+		left &= ~0x3fu;
+	}
+	return left;
+}
+
+PMU_FORMAT_ATTR(event,	"config:0-7"	);
+PMU_FORMAT_ATTR(umask,	"config:8-15"	);
+PMU_FORMAT_ATTR(edge,	"config:18"	);
+PMU_FORMAT_ATTR(pc,	"config:19"	);
+PMU_FORMAT_ATTR(any,	"config:21"	); /* v3 + */
+PMU_FORMAT_ATTR(inv,	"config:23"	);
+PMU_FORMAT_ATTR(cmask,	"config:24-31"	);
+PMU_FORMAT_ATTR(in_tx,  "config:32");
+PMU_FORMAT_ATTR(in_tx_cp, "config:33");
+
+static struct attribute *intel_arch_formats_attr[] = {
+	&format_attr_event.attr,
+	&format_attr_umask.attr,
+	&format_attr_edge.attr,
+	&format_attr_pc.attr,
+	&format_attr_inv.attr,
+	&format_attr_cmask.attr,
+	NULL,
+};
+
+ssize_t intel_event_sysfs_show(char *page, u64 config)
+{
+	u64 event = (config & ARCH_PERFMON_EVENTSEL_EVENT);
+
+	return x86_event_sysfs_show(page, config, event);
+}
+
+struct intel_shared_regs *allocate_shared_regs(int cpu)
+{
+	struct intel_shared_regs *regs;
+	int i;
+
+	regs = kzalloc_node(sizeof(struct intel_shared_regs),
+			    GFP_KERNEL, cpu_to_node(cpu));
+	if (regs) {
+		/*
+		 * initialize the locks to keep lockdep happy
+		 */
+		for (i = 0; i < EXTRA_REG_MAX; i++)
+			raw_spin_lock_init(&regs->regs[i].lock);
+
+		regs->core_id = -1;
+	}
+	return regs;
+}
+
+static struct intel_excl_cntrs *allocate_excl_cntrs(int cpu)
+{
+	struct intel_excl_cntrs *c;
+
+	c = kzalloc_node(sizeof(struct intel_excl_cntrs),
+			 GFP_KERNEL, cpu_to_node(cpu));
+	if (c) {
+		raw_spin_lock_init(&c->lock);
+		c->core_id = -1;
+	}
+	return c;
+}
+
+static int intel_pmu_cpu_prepare(int cpu)
+{
+	struct cpu_hw_events *cpuc = &per_cpu(cpu_hw_events, cpu);
+
+	if (x86_pmu.extra_regs || x86_pmu.lbr_sel_map) {
+		cpuc->shared_regs = allocate_shared_regs(cpu);
+		if (!cpuc->shared_regs)
+			goto err;
+	}
+
+	if (x86_pmu.flags & PMU_FL_EXCL_CNTRS) {
+		size_t sz = X86_PMC_IDX_MAX * sizeof(struct event_constraint);
+
+		cpuc->constraint_list = kzalloc(sz, GFP_KERNEL);
+		if (!cpuc->constraint_list)
+			goto err_shared_regs;
+
+		cpuc->excl_cntrs = allocate_excl_cntrs(cpu);
+		if (!cpuc->excl_cntrs)
+			goto err_constraint_list;
+
+		cpuc->excl_thread_id = 0;
+	}
+
+	return NOTIFY_OK;
+
+err_constraint_list:
+	kfree(cpuc->constraint_list);
+	cpuc->constraint_list = NULL;
+
+err_shared_regs:
+	kfree(cpuc->shared_regs);
+	cpuc->shared_regs = NULL;
+
+err:
+	return NOTIFY_BAD;
+}
+
+static void intel_pmu_cpu_starting(int cpu)
+{
+	struct cpu_hw_events *cpuc = &per_cpu(cpu_hw_events, cpu);
+	int core_id = topology_core_id(cpu);
+	int i;
+
+	init_debug_store_on_cpu(cpu);
+	/*
+	 * Deal with CPUs that don't clear their LBRs on power-up.
+	 */
+	intel_pmu_lbr_reset();
+
+	cpuc->lbr_sel = NULL;
+
+	if (!cpuc->shared_regs)
+		return;
+
+	if (!(x86_pmu.flags & PMU_FL_NO_HT_SHARING)) {
+		void **onln = &cpuc->kfree_on_online[X86_PERF_KFREE_SHARED];
+
+		for_each_cpu(i, topology_sibling_cpumask(cpu)) {
+			struct intel_shared_regs *pc;
+
+			pc = per_cpu(cpu_hw_events, i).shared_regs;
+			if (pc && pc->core_id == core_id) {
+				*onln = cpuc->shared_regs;
+				cpuc->shared_regs = pc;
+				break;
+			}
+		}
+		cpuc->shared_regs->core_id = core_id;
+		cpuc->shared_regs->refcnt++;
+	}
+
+	if (x86_pmu.lbr_sel_map)
+		cpuc->lbr_sel = &cpuc->shared_regs->regs[EXTRA_REG_LBR];
+
+	if (x86_pmu.flags & PMU_FL_EXCL_CNTRS) {
+		for_each_cpu(i, topology_sibling_cpumask(cpu)) {
+			struct intel_excl_cntrs *c;
+
+			c = per_cpu(cpu_hw_events, i).excl_cntrs;
+			if (c && c->core_id == core_id) {
+				cpuc->kfree_on_online[1] = cpuc->excl_cntrs;
+				cpuc->excl_cntrs = c;
+				cpuc->excl_thread_id = 1;
+				break;
+			}
+		}
+		cpuc->excl_cntrs->core_id = core_id;
+		cpuc->excl_cntrs->refcnt++;
+	}
+}
+
+static void free_excl_cntrs(int cpu)
+{
+	struct cpu_hw_events *cpuc = &per_cpu(cpu_hw_events, cpu);
+	struct intel_excl_cntrs *c;
+
+	c = cpuc->excl_cntrs;
+	if (c) {
+		if (c->core_id == -1 || --c->refcnt == 0)
+			kfree(c);
+		cpuc->excl_cntrs = NULL;
+		kfree(cpuc->constraint_list);
+		cpuc->constraint_list = NULL;
+	}
+}
+
+static void intel_pmu_cpu_dying(int cpu)
+{
+	struct cpu_hw_events *cpuc = &per_cpu(cpu_hw_events, cpu);
+	struct intel_shared_regs *pc;
+
+	pc = cpuc->shared_regs;
+	if (pc) {
+		if (pc->core_id == -1 || --pc->refcnt == 0)
+			kfree(pc);
+		cpuc->shared_regs = NULL;
+	}
+
+	free_excl_cntrs(cpu);
+
+	fini_debug_store_on_cpu(cpu);
+}
+
+static void intel_pmu_sched_task(struct perf_event_context *ctx,
+				 bool sched_in)
+{
+	if (x86_pmu.pebs_active)
+		intel_pmu_pebs_sched_task(ctx, sched_in);
+	if (x86_pmu.lbr_nr)
+		intel_pmu_lbr_sched_task(ctx, sched_in);
+}
+
+PMU_FORMAT_ATTR(offcore_rsp, "config1:0-63");
+
+PMU_FORMAT_ATTR(ldlat, "config1:0-15");
+
+PMU_FORMAT_ATTR(frontend, "config1:0-23");
+
+static struct attribute *intel_arch3_formats_attr[] = {
+	&format_attr_event.attr,
+	&format_attr_umask.attr,
+	&format_attr_edge.attr,
+	&format_attr_pc.attr,
+	&format_attr_any.attr,
+	&format_attr_inv.attr,
+	&format_attr_cmask.attr,
+	&format_attr_in_tx.attr,
+	&format_attr_in_tx_cp.attr,
+
+	&format_attr_offcore_rsp.attr, /* XXX do NHM/WSM + SNB breakout */
+	&format_attr_ldlat.attr, /* PEBS load latency */
+	NULL,
+};
+
+static struct attribute *skl_format_attr[] = {
+	&format_attr_frontend.attr,
+	NULL,
+};
+
+static __initconst const struct x86_pmu core_pmu = {
+	.name			= "core",
+	.handle_irq		= x86_pmu_handle_irq,
+	.disable_all		= x86_pmu_disable_all,
+	.enable_all		= core_pmu_enable_all,
+	.enable			= core_pmu_enable_event,
+	.disable		= x86_pmu_disable_event,
+	.hw_config		= x86_pmu_hw_config,
+	.schedule_events	= x86_schedule_events,
+	.eventsel		= MSR_ARCH_PERFMON_EVENTSEL0,
+	.perfctr		= MSR_ARCH_PERFMON_PERFCTR0,
+	.event_map		= intel_pmu_event_map,
+	.max_events		= ARRAY_SIZE(intel_perfmon_event_map),
+	.apic			= 1,
+	.free_running_flags	= PEBS_FREERUNNING_FLAGS,
+
+	/*
+	 * Intel PMCs cannot be accessed sanely above 32-bit width,
+	 * so we install an artificial 1<<31 period regardless of
+	 * the generic event period:
+	 */
+	.max_period		= (1ULL<<31) - 1,
+	.get_event_constraints	= intel_get_event_constraints,
+	.put_event_constraints	= intel_put_event_constraints,
+	.event_constraints	= intel_core_event_constraints,
+	.guest_get_msrs		= core_guest_get_msrs,
+	.format_attrs		= intel_arch_formats_attr,
+	.events_sysfs_show	= intel_event_sysfs_show,
+
+	/*
+	 * Virtual (or funny metal) CPU can define x86_pmu.extra_regs
+	 * together with PMU version 1 and thus be using core_pmu with
+	 * shared_regs. We need following callbacks here to allocate
+	 * it properly.
+	 */
+	.cpu_prepare		= intel_pmu_cpu_prepare,
+	.cpu_starting		= intel_pmu_cpu_starting,
+	.cpu_dying		= intel_pmu_cpu_dying,
+};
+
+static __initconst const struct x86_pmu intel_pmu = {
+	.name			= "Intel",
+	.handle_irq		= intel_pmu_handle_irq,
+	.disable_all		= intel_pmu_disable_all,
+	.enable_all		= intel_pmu_enable_all,
+	.enable			= intel_pmu_enable_event,
+	.disable		= intel_pmu_disable_event,
+	.hw_config		= intel_pmu_hw_config,
+	.schedule_events	= x86_schedule_events,
+	.eventsel		= MSR_ARCH_PERFMON_EVENTSEL0,
+	.perfctr		= MSR_ARCH_PERFMON_PERFCTR0,
+	.event_map		= intel_pmu_event_map,
+	.max_events		= ARRAY_SIZE(intel_perfmon_event_map),
+	.apic			= 1,
+	.free_running_flags	= PEBS_FREERUNNING_FLAGS,
+	/*
+	 * Intel PMCs cannot be accessed sanely above 32 bit width,
+	 * so we install an artificial 1<<31 period regardless of
+	 * the generic event period:
+	 */
+	.max_period		= (1ULL << 31) - 1,
+	.get_event_constraints	= intel_get_event_constraints,
+	.put_event_constraints	= intel_put_event_constraints,
+	.pebs_aliases		= intel_pebs_aliases_core2,
+
+	.format_attrs		= intel_arch3_formats_attr,
+	.events_sysfs_show	= intel_event_sysfs_show,
+
+	.cpu_prepare		= intel_pmu_cpu_prepare,
+	.cpu_starting		= intel_pmu_cpu_starting,
+	.cpu_dying		= intel_pmu_cpu_dying,
+	.guest_get_msrs		= intel_guest_get_msrs,
+	.sched_task		= intel_pmu_sched_task,
+};
+
+static __init void intel_clovertown_quirk(void)
+{
+	/*
+	 * PEBS is unreliable due to:
+	 *
+	 *   AJ67  - PEBS may experience CPL leaks
+	 *   AJ68  - PEBS PMI may be delayed by one event
+	 *   AJ69  - GLOBAL_STATUS[62] will only be set when DEBUGCTL[12]
+	 *   AJ106 - FREEZE_LBRS_ON_PMI doesn't work in combination with PEBS
+	 *
+	 * AJ67 could be worked around by restricting the OS/USR flags.
+	 * AJ69 could be worked around by setting PMU_FREEZE_ON_PMI.
+	 *
+	 * AJ106 could possibly be worked around by not allowing LBR
+	 *       usage from PEBS, including the fixup.
+	 * AJ68  could possibly be worked around by always programming
+	 *	 a pebs_event_reset[0] value and coping with the lost events.
+	 *
+	 * But taken together it might just make sense to not enable PEBS on
+	 * these chips.
+	 */
+	pr_warn("PEBS disabled due to CPU errata\n");
+	x86_pmu.pebs = 0;
+	x86_pmu.pebs_constraints = NULL;
+}
+
+static int intel_snb_pebs_broken(int cpu)
+{
+	u32 rev = UINT_MAX; /* default to broken for unknown models */
+
+	switch (cpu_data(cpu).x86_model) {
+	case 42: /* SNB */
+		rev = 0x28;
+		break;
+
+	case 45: /* SNB-EP */
+		switch (cpu_data(cpu).x86_mask) {
+		case 6: rev = 0x618; break;
+		case 7: rev = 0x70c; break;
+		}
+	}
+
+	return (cpu_data(cpu).microcode < rev);
+}
+
+static void intel_snb_check_microcode(void)
+{
+	int pebs_broken = 0;
+	int cpu;
+
+	get_online_cpus();
+	for_each_online_cpu(cpu) {
+		if ((pebs_broken = intel_snb_pebs_broken(cpu)))
+			break;
+	}
+	put_online_cpus();
+
+	if (pebs_broken == x86_pmu.pebs_broken)
+		return;
+
+	/*
+	 * Serialized by the microcode lock..
+	 */
+	if (x86_pmu.pebs_broken) {
+		pr_info("PEBS enabled due to microcode update\n");
+		x86_pmu.pebs_broken = 0;
+	} else {
+		pr_info("PEBS disabled due to CPU errata, please upgrade microcode\n");
+		x86_pmu.pebs_broken = 1;
+	}
+}
+
+/*
+ * Under certain circumstances, access certain MSR may cause #GP.
+ * The function tests if the input MSR can be safely accessed.
+ */
+static bool check_msr(unsigned long msr, u64 mask)
+{
+	u64 val_old, val_new, val_tmp;
+
+	/*
+	 * Read the current value, change it and read it back to see if it
+	 * matches, this is needed to detect certain hardware emulators
+	 * (qemu/kvm) that don't trap on the MSR access and always return 0s.
+	 */
+	if (rdmsrl_safe(msr, &val_old))
+		return false;
+
+	/*
+	 * Only change the bits which can be updated by wrmsrl.
+	 */
+	val_tmp = val_old ^ mask;
+	if (wrmsrl_safe(msr, val_tmp) ||
+	    rdmsrl_safe(msr, &val_new))
+		return false;
+
+	if (val_new != val_tmp)
+		return false;
+
+	/* Here it's sure that the MSR can be safely accessed.
+	 * Restore the old value and return.
+	 */
+	wrmsrl(msr, val_old);
+
+	return true;
+}
+
+static __init void intel_sandybridge_quirk(void)
+{
+	x86_pmu.check_microcode = intel_snb_check_microcode;
+	intel_snb_check_microcode();
+}
+
+static const struct { int id; char *name; } intel_arch_events_map[] __initconst = {
+	{ PERF_COUNT_HW_CPU_CYCLES, "cpu cycles" },
+	{ PERF_COUNT_HW_INSTRUCTIONS, "instructions" },
+	{ PERF_COUNT_HW_BUS_CYCLES, "bus cycles" },
+	{ PERF_COUNT_HW_CACHE_REFERENCES, "cache references" },
+	{ PERF_COUNT_HW_CACHE_MISSES, "cache misses" },
+	{ PERF_COUNT_HW_BRANCH_INSTRUCTIONS, "branch instructions" },
+	{ PERF_COUNT_HW_BRANCH_MISSES, "branch misses" },
+};
+
+static __init void intel_arch_events_quirk(void)
+{
+	int bit;
+
+	/* disable event that reported as not presend by cpuid */
+	for_each_set_bit(bit, x86_pmu.events_mask, ARRAY_SIZE(intel_arch_events_map)) {
+		intel_perfmon_event_map[intel_arch_events_map[bit].id] = 0;
+		pr_warn("CPUID marked event: \'%s\' unavailable\n",
+			intel_arch_events_map[bit].name);
+	}
+}
+
+static __init void intel_nehalem_quirk(void)
+{
+	union cpuid10_ebx ebx;
+
+	ebx.full = x86_pmu.events_maskl;
+	if (ebx.split.no_branch_misses_retired) {
+		/*
+		 * Erratum AAJ80 detected, we work it around by using
+		 * the BR_MISP_EXEC.ANY event. This will over-count
+		 * branch-misses, but it's still much better than the
+		 * architectural event which is often completely bogus:
+		 */
+		intel_perfmon_event_map[PERF_COUNT_HW_BRANCH_MISSES] = 0x7f89;
+		ebx.split.no_branch_misses_retired = 0;
+		x86_pmu.events_maskl = ebx.full;
+		pr_info("CPU erratum AAJ80 worked around\n");
+	}
+}
+
+/*
+ * enable software workaround for errata:
+ * SNB: BJ122
+ * IVB: BV98
+ * HSW: HSD29
+ *
+ * Only needed when HT is enabled. However detecting
+ * if HT is enabled is difficult (model specific). So instead,
+ * we enable the workaround in the early boot, and verify if
+ * it is needed in a later initcall phase once we have valid
+ * topology information to check if HT is actually enabled
+ */
+static __init void intel_ht_bug(void)
+{
+	x86_pmu.flags |= PMU_FL_EXCL_CNTRS | PMU_FL_EXCL_ENABLED;
+
+	x86_pmu.start_scheduling = intel_start_scheduling;
+	x86_pmu.commit_scheduling = intel_commit_scheduling;
+	x86_pmu.stop_scheduling = intel_stop_scheduling;
+}
+
+EVENT_ATTR_STR(mem-loads,	mem_ld_hsw,	"event=0xcd,umask=0x1,ldlat=3");
+EVENT_ATTR_STR(mem-stores,	mem_st_hsw,	"event=0xd0,umask=0x82")
+
+/* Haswell special events */
+EVENT_ATTR_STR(tx-start,	tx_start,	"event=0xc9,umask=0x1");
+EVENT_ATTR_STR(tx-commit,	tx_commit,	"event=0xc9,umask=0x2");
+EVENT_ATTR_STR(tx-abort,	tx_abort,	"event=0xc9,umask=0x4");
+EVENT_ATTR_STR(tx-capacity,	tx_capacity,	"event=0x54,umask=0x2");
+EVENT_ATTR_STR(tx-conflict,	tx_conflict,	"event=0x54,umask=0x1");
+EVENT_ATTR_STR(el-start,	el_start,	"event=0xc8,umask=0x1");
+EVENT_ATTR_STR(el-commit,	el_commit,	"event=0xc8,umask=0x2");
+EVENT_ATTR_STR(el-abort,	el_abort,	"event=0xc8,umask=0x4");
+EVENT_ATTR_STR(el-capacity,	el_capacity,	"event=0x54,umask=0x2");
+EVENT_ATTR_STR(el-conflict,	el_conflict,	"event=0x54,umask=0x1");
+EVENT_ATTR_STR(cycles-t,	cycles_t,	"event=0x3c,in_tx=1");
+EVENT_ATTR_STR(cycles-ct,	cycles_ct,	"event=0x3c,in_tx=1,in_tx_cp=1");
+
+static struct attribute *hsw_events_attrs[] = {
+	EVENT_PTR(tx_start),
+	EVENT_PTR(tx_commit),
+	EVENT_PTR(tx_abort),
+	EVENT_PTR(tx_capacity),
+	EVENT_PTR(tx_conflict),
+	EVENT_PTR(el_start),
+	EVENT_PTR(el_commit),
+	EVENT_PTR(el_abort),
+	EVENT_PTR(el_capacity),
+	EVENT_PTR(el_conflict),
+	EVENT_PTR(cycles_t),
+	EVENT_PTR(cycles_ct),
+	EVENT_PTR(mem_ld_hsw),
+	EVENT_PTR(mem_st_hsw),
+	NULL
+};
+
+__init int intel_pmu_init(void)
+{
+	union cpuid10_edx edx;
+	union cpuid10_eax eax;
+	union cpuid10_ebx ebx;
+	struct event_constraint *c;
+	unsigned int unused;
+	struct extra_reg *er;
+	int version, i;
+
+	if (!cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON)) {
+		switch (boot_cpu_data.x86) {
+		case 0x6:
+			return p6_pmu_init();
+		case 0xb:
+			return knc_pmu_init();
+		case 0xf:
+			return p4_pmu_init();
+		}
+		return -ENODEV;
+	}
+
+	/*
+	 * Check whether the Architectural PerfMon supports
+	 * Branch Misses Retired hw_event or not.
+	 */
+	cpuid(10, &eax.full, &ebx.full, &unused, &edx.full);
+	if (eax.split.mask_length < ARCH_PERFMON_EVENTS_COUNT)
+		return -ENODEV;
+
+	version = eax.split.version_id;
+	if (version < 2)
+		x86_pmu = core_pmu;
+	else
+		x86_pmu = intel_pmu;
+
+	x86_pmu.version			= version;
+	x86_pmu.num_counters		= eax.split.num_counters;
+	x86_pmu.cntval_bits		= eax.split.bit_width;
+	x86_pmu.cntval_mask		= (1ULL << eax.split.bit_width) - 1;
+
+	x86_pmu.events_maskl		= ebx.full;
+	x86_pmu.events_mask_len		= eax.split.mask_length;
+
+	x86_pmu.max_pebs_events		= min_t(unsigned, MAX_PEBS_EVENTS, x86_pmu.num_counters);
+
+	/*
+	 * Quirk: v2 perfmon does not report fixed-purpose events, so
+	 * assume at least 3 events:
+	 */
+	if (version > 1)
+		x86_pmu.num_counters_fixed = max((int)edx.split.num_counters_fixed, 3);
+
+	if (boot_cpu_has(X86_FEATURE_PDCM)) {
+		u64 capabilities;
+
+		rdmsrl(MSR_IA32_PERF_CAPABILITIES, capabilities);
+		x86_pmu.intel_cap.capabilities = capabilities;
+	}
+
+	intel_ds_init();
+
+	x86_add_quirk(intel_arch_events_quirk); /* Install first, so it runs last */
+
+	/*
+	 * Install the hw-cache-events table:
+	 */
+	switch (boot_cpu_data.x86_model) {
+	case 14: /* 65nm Core "Yonah" */
+		pr_cont("Core events, ");
+		break;
+
+	case 15: /* 65nm Core2 "Merom"          */
+		x86_add_quirk(intel_clovertown_quirk);
+	case 22: /* 65nm Core2 "Merom-L"        */
+	case 23: /* 45nm Core2 "Penryn"         */
+	case 29: /* 45nm Core2 "Dunnington (MP) */
+		memcpy(hw_cache_event_ids, core2_hw_cache_event_ids,
+		       sizeof(hw_cache_event_ids));
+
+		intel_pmu_lbr_init_core();
+
+		x86_pmu.event_constraints = intel_core2_event_constraints;
+		x86_pmu.pebs_constraints = intel_core2_pebs_event_constraints;
+		pr_cont("Core2 events, ");
+		break;
+
+	case 30: /* 45nm Nehalem    */
+	case 26: /* 45nm Nehalem-EP */
+	case 46: /* 45nm Nehalem-EX */
+		memcpy(hw_cache_event_ids, nehalem_hw_cache_event_ids,
+		       sizeof(hw_cache_event_ids));
+		memcpy(hw_cache_extra_regs, nehalem_hw_cache_extra_regs,
+		       sizeof(hw_cache_extra_regs));
+
+		intel_pmu_lbr_init_nhm();
+
+		x86_pmu.event_constraints = intel_nehalem_event_constraints;
+		x86_pmu.pebs_constraints = intel_nehalem_pebs_event_constraints;
+		x86_pmu.enable_all = intel_pmu_nhm_enable_all;
+		x86_pmu.extra_regs = intel_nehalem_extra_regs;
+
+		x86_pmu.cpu_events = nhm_events_attrs;
+
+		/* UOPS_ISSUED.STALLED_CYCLES */
+		intel_perfmon_event_map[PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] =
+			X86_CONFIG(.event=0x0e, .umask=0x01, .inv=1, .cmask=1);
+		/* UOPS_EXECUTED.CORE_ACTIVE_CYCLES,c=1,i=1 */
+		intel_perfmon_event_map[PERF_COUNT_HW_STALLED_CYCLES_BACKEND] =
+			X86_CONFIG(.event=0xb1, .umask=0x3f, .inv=1, .cmask=1);
+
+		intel_pmu_pebs_data_source_nhm();
+		x86_add_quirk(intel_nehalem_quirk);
+
+		pr_cont("Nehalem events, ");
+		break;
+
+	case 28: /* 45nm Atom "Pineview"   */
+	case 38: /* 45nm Atom "Lincroft"   */
+	case 39: /* 32nm Atom "Penwell"    */
+	case 53: /* 32nm Atom "Cloverview" */
+	case 54: /* 32nm Atom "Cedarview"  */
+		memcpy(hw_cache_event_ids, atom_hw_cache_event_ids,
+		       sizeof(hw_cache_event_ids));
+
+		intel_pmu_lbr_init_atom();
+
+		x86_pmu.event_constraints = intel_gen_event_constraints;
+		x86_pmu.pebs_constraints = intel_atom_pebs_event_constraints;
+		pr_cont("Atom events, ");
+		break;
+
+	case 55: /* 22nm Atom "Silvermont"                */
+	case 76: /* 14nm Atom "Airmont"                   */
+	case 77: /* 22nm Atom "Silvermont Avoton/Rangely" */
+		memcpy(hw_cache_event_ids, slm_hw_cache_event_ids,
+			sizeof(hw_cache_event_ids));
+		memcpy(hw_cache_extra_regs, slm_hw_cache_extra_regs,
+		       sizeof(hw_cache_extra_regs));
+
+		intel_pmu_lbr_init_atom();
+
+		x86_pmu.event_constraints = intel_slm_event_constraints;
+		x86_pmu.pebs_constraints = intel_slm_pebs_event_constraints;
+		x86_pmu.extra_regs = intel_slm_extra_regs;
+		x86_pmu.flags |= PMU_FL_HAS_RSP_1;
+		pr_cont("Silvermont events, ");
+		break;
+
+	case 37: /* 32nm Westmere    */
+	case 44: /* 32nm Westmere-EP */
+	case 47: /* 32nm Westmere-EX */
+		memcpy(hw_cache_event_ids, westmere_hw_cache_event_ids,
+		       sizeof(hw_cache_event_ids));
+		memcpy(hw_cache_extra_regs, nehalem_hw_cache_extra_regs,
+		       sizeof(hw_cache_extra_regs));
+
+		intel_pmu_lbr_init_nhm();
+
+		x86_pmu.event_constraints = intel_westmere_event_constraints;
+		x86_pmu.enable_all = intel_pmu_nhm_enable_all;
+		x86_pmu.pebs_constraints = intel_westmere_pebs_event_constraints;
+		x86_pmu.extra_regs = intel_westmere_extra_regs;
+		x86_pmu.flags |= PMU_FL_HAS_RSP_1;
+
+		x86_pmu.cpu_events = nhm_events_attrs;
+
+		/* UOPS_ISSUED.STALLED_CYCLES */
+		intel_perfmon_event_map[PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] =
+			X86_CONFIG(.event=0x0e, .umask=0x01, .inv=1, .cmask=1);
+		/* UOPS_EXECUTED.CORE_ACTIVE_CYCLES,c=1,i=1 */
+		intel_perfmon_event_map[PERF_COUNT_HW_STALLED_CYCLES_BACKEND] =
+			X86_CONFIG(.event=0xb1, .umask=0x3f, .inv=1, .cmask=1);
+
+		intel_pmu_pebs_data_source_nhm();
+		pr_cont("Westmere events, ");
+		break;
+
+	case 42: /* 32nm SandyBridge         */
+	case 45: /* 32nm SandyBridge-E/EN/EP */
+		x86_add_quirk(intel_sandybridge_quirk);
+		x86_add_quirk(intel_ht_bug);
+		memcpy(hw_cache_event_ids, snb_hw_cache_event_ids,
+		       sizeof(hw_cache_event_ids));
+		memcpy(hw_cache_extra_regs, snb_hw_cache_extra_regs,
+		       sizeof(hw_cache_extra_regs));
+
+		intel_pmu_lbr_init_snb();
+
+		x86_pmu.event_constraints = intel_snb_event_constraints;
+		x86_pmu.pebs_constraints = intel_snb_pebs_event_constraints;
+		x86_pmu.pebs_aliases = intel_pebs_aliases_snb;
+		if (boot_cpu_data.x86_model == 45)
+			x86_pmu.extra_regs = intel_snbep_extra_regs;
+		else
+			x86_pmu.extra_regs = intel_snb_extra_regs;
+
+
+		/* all extra regs are per-cpu when HT is on */
+		x86_pmu.flags |= PMU_FL_HAS_RSP_1;
+		x86_pmu.flags |= PMU_FL_NO_HT_SHARING;
+
+		x86_pmu.cpu_events = snb_events_attrs;
+
+		/* UOPS_ISSUED.ANY,c=1,i=1 to count stall cycles */
+		intel_perfmon_event_map[PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] =
+			X86_CONFIG(.event=0x0e, .umask=0x01, .inv=1, .cmask=1);
+		/* UOPS_DISPATCHED.THREAD,c=1,i=1 to count stall cycles*/
+		intel_perfmon_event_map[PERF_COUNT_HW_STALLED_CYCLES_BACKEND] =
+			X86_CONFIG(.event=0xb1, .umask=0x01, .inv=1, .cmask=1);
+
+		pr_cont("SandyBridge events, ");
+		break;
+
+	case 58: /* 22nm IvyBridge       */
+	case 62: /* 22nm IvyBridge-EP/EX */
+		x86_add_quirk(intel_ht_bug);
+		memcpy(hw_cache_event_ids, snb_hw_cache_event_ids,
+		       sizeof(hw_cache_event_ids));
+		/* dTLB-load-misses on IVB is different than SNB */
+		hw_cache_event_ids[C(DTLB)][C(OP_READ)][C(RESULT_MISS)] = 0x8108; /* DTLB_LOAD_MISSES.DEMAND_LD_MISS_CAUSES_A_WALK */
+
+		memcpy(hw_cache_extra_regs, snb_hw_cache_extra_regs,
+		       sizeof(hw_cache_extra_regs));
+
+		intel_pmu_lbr_init_snb();
+
+		x86_pmu.event_constraints = intel_ivb_event_constraints;
+		x86_pmu.pebs_constraints = intel_ivb_pebs_event_constraints;
+		x86_pmu.pebs_aliases = intel_pebs_aliases_snb;
+		if (boot_cpu_data.x86_model == 62)
+			x86_pmu.extra_regs = intel_snbep_extra_regs;
+		else
+			x86_pmu.extra_regs = intel_snb_extra_regs;
+		/* all extra regs are per-cpu when HT is on */
+		x86_pmu.flags |= PMU_FL_HAS_RSP_1;
+		x86_pmu.flags |= PMU_FL_NO_HT_SHARING;
+
+		x86_pmu.cpu_events = snb_events_attrs;
+
+		/* UOPS_ISSUED.ANY,c=1,i=1 to count stall cycles */
+		intel_perfmon_event_map[PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] =
+			X86_CONFIG(.event=0x0e, .umask=0x01, .inv=1, .cmask=1);
+
+		pr_cont("IvyBridge events, ");
+		break;
+
+
+	case 60: /* 22nm Haswell Core */
+	case 63: /* 22nm Haswell Server */
+	case 69: /* 22nm Haswell ULT */
+	case 70: /* 22nm Haswell + GT3e (Intel Iris Pro graphics) */
+		x86_add_quirk(intel_ht_bug);
+		x86_pmu.late_ack = true;
+		memcpy(hw_cache_event_ids, hsw_hw_cache_event_ids, sizeof(hw_cache_event_ids));
+		memcpy(hw_cache_extra_regs, hsw_hw_cache_extra_regs, sizeof(hw_cache_extra_regs));
+
+		intel_pmu_lbr_init_hsw();
+
+		x86_pmu.event_constraints = intel_hsw_event_constraints;
+		x86_pmu.pebs_constraints = intel_hsw_pebs_event_constraints;
+		x86_pmu.extra_regs = intel_snbep_extra_regs;
+		x86_pmu.pebs_aliases = intel_pebs_aliases_snb;
+		/* all extra regs are per-cpu when HT is on */
+		x86_pmu.flags |= PMU_FL_HAS_RSP_1;
+		x86_pmu.flags |= PMU_FL_NO_HT_SHARING;
+
+		x86_pmu.hw_config = hsw_hw_config;
+		x86_pmu.get_event_constraints = hsw_get_event_constraints;
+		x86_pmu.cpu_events = hsw_events_attrs;
+		x86_pmu.lbr_double_abort = true;
+		pr_cont("Haswell events, ");
+		break;
+
+	case 61: /* 14nm Broadwell Core-M */
+	case 86: /* 14nm Broadwell Xeon D */
+	case 71: /* 14nm Broadwell + GT3e (Intel Iris Pro graphics) */
+	case 79: /* 14nm Broadwell Server */
+		x86_pmu.late_ack = true;
+		memcpy(hw_cache_event_ids, hsw_hw_cache_event_ids, sizeof(hw_cache_event_ids));
+		memcpy(hw_cache_extra_regs, hsw_hw_cache_extra_regs, sizeof(hw_cache_extra_regs));
+
+		/* L3_MISS_LOCAL_DRAM is BIT(26) in Broadwell */
+		hw_cache_extra_regs[C(LL)][C(OP_READ)][C(RESULT_MISS)] = HSW_DEMAND_READ |
+									 BDW_L3_MISS|HSW_SNOOP_DRAM;
+		hw_cache_extra_regs[C(LL)][C(OP_WRITE)][C(RESULT_MISS)] = HSW_DEMAND_WRITE|BDW_L3_MISS|
+									  HSW_SNOOP_DRAM;
+		hw_cache_extra_regs[C(NODE)][C(OP_READ)][C(RESULT_ACCESS)] = HSW_DEMAND_READ|
+									     BDW_L3_MISS_LOCAL|HSW_SNOOP_DRAM;
+		hw_cache_extra_regs[C(NODE)][C(OP_WRITE)][C(RESULT_ACCESS)] = HSW_DEMAND_WRITE|
+									      BDW_L3_MISS_LOCAL|HSW_SNOOP_DRAM;
+
+		intel_pmu_lbr_init_hsw();
+
+		x86_pmu.event_constraints = intel_bdw_event_constraints;
+		x86_pmu.pebs_constraints = intel_hsw_pebs_event_constraints;
+		x86_pmu.extra_regs = intel_snbep_extra_regs;
+		x86_pmu.pebs_aliases = intel_pebs_aliases_snb;
+		/* all extra regs are per-cpu when HT is on */
+		x86_pmu.flags |= PMU_FL_HAS_RSP_1;
+		x86_pmu.flags |= PMU_FL_NO_HT_SHARING;
+
+		x86_pmu.hw_config = hsw_hw_config;
+		x86_pmu.get_event_constraints = hsw_get_event_constraints;
+		x86_pmu.cpu_events = hsw_events_attrs;
+		x86_pmu.limit_period = bdw_limit_period;
+		pr_cont("Broadwell events, ");
+		break;
+
+	case 87: /* Knights Landing Xeon Phi */
+		memcpy(hw_cache_event_ids,
+		       slm_hw_cache_event_ids, sizeof(hw_cache_event_ids));
+		memcpy(hw_cache_extra_regs,
+		       knl_hw_cache_extra_regs, sizeof(hw_cache_extra_regs));
+		intel_pmu_lbr_init_knl();
+
+		x86_pmu.event_constraints = intel_slm_event_constraints;
+		x86_pmu.pebs_constraints = intel_slm_pebs_event_constraints;
+		x86_pmu.extra_regs = intel_knl_extra_regs;
+
+		/* all extra regs are per-cpu when HT is on */
+		x86_pmu.flags |= PMU_FL_HAS_RSP_1;
+		x86_pmu.flags |= PMU_FL_NO_HT_SHARING;
+
+		pr_cont("Knights Landing events, ");
+		break;
+
+	case 78: /* 14nm Skylake Mobile */
+	case 94: /* 14nm Skylake Desktop */
+		x86_pmu.late_ack = true;
+		memcpy(hw_cache_event_ids, skl_hw_cache_event_ids, sizeof(hw_cache_event_ids));
+		memcpy(hw_cache_extra_regs, skl_hw_cache_extra_regs, sizeof(hw_cache_extra_regs));
+		intel_pmu_lbr_init_skl();
+
+		x86_pmu.event_constraints = intel_skl_event_constraints;
+		x86_pmu.pebs_constraints = intel_skl_pebs_event_constraints;
+		x86_pmu.extra_regs = intel_skl_extra_regs;
+		x86_pmu.pebs_aliases = intel_pebs_aliases_snb;
+		/* all extra regs are per-cpu when HT is on */
+		x86_pmu.flags |= PMU_FL_HAS_RSP_1;
+		x86_pmu.flags |= PMU_FL_NO_HT_SHARING;
+
+		x86_pmu.hw_config = hsw_hw_config;
+		x86_pmu.get_event_constraints = hsw_get_event_constraints;
+		x86_pmu.format_attrs = merge_attr(intel_arch3_formats_attr,
+						  skl_format_attr);
+		WARN_ON(!x86_pmu.format_attrs);
+		x86_pmu.cpu_events = hsw_events_attrs;
+		pr_cont("Skylake events, ");
+		break;
+
+	default:
+		switch (x86_pmu.version) {
+		case 1:
+			x86_pmu.event_constraints = intel_v1_event_constraints;
+			pr_cont("generic architected perfmon v1, ");
+			break;
+		default:
+			/*
+			 * default constraints for v2 and up
+			 */
+			x86_pmu.event_constraints = intel_gen_event_constraints;
+			pr_cont("generic architected perfmon, ");
+			break;
+		}
+	}
+
+	if (x86_pmu.num_counters > INTEL_PMC_MAX_GENERIC) {
+		WARN(1, KERN_ERR "hw perf events %d > max(%d), clipping!",
+		     x86_pmu.num_counters, INTEL_PMC_MAX_GENERIC);
+		x86_pmu.num_counters = INTEL_PMC_MAX_GENERIC;
+	}
+	x86_pmu.intel_ctrl = (1 << x86_pmu.num_counters) - 1;
+
+	if (x86_pmu.num_counters_fixed > INTEL_PMC_MAX_FIXED) {
+		WARN(1, KERN_ERR "hw perf events fixed %d > max(%d), clipping!",
+		     x86_pmu.num_counters_fixed, INTEL_PMC_MAX_FIXED);
+		x86_pmu.num_counters_fixed = INTEL_PMC_MAX_FIXED;
+	}
+
+	x86_pmu.intel_ctrl |=
+		((1LL << x86_pmu.num_counters_fixed)-1) << INTEL_PMC_IDX_FIXED;
+
+	if (x86_pmu.event_constraints) {
+		/*
+		 * event on fixed counter2 (REF_CYCLES) only works on this
+		 * counter, so do not extend mask to generic counters
+		 */
+		for_each_event_constraint(c, x86_pmu.event_constraints) {
+			if (c->cmask == FIXED_EVENT_FLAGS
+			    && c->idxmsk64 != INTEL_PMC_MSK_FIXED_REF_CYCLES) {
+				c->idxmsk64 |= (1ULL << x86_pmu.num_counters) - 1;
+			}
+			c->idxmsk64 &=
+				~(~0ULL << (INTEL_PMC_IDX_FIXED + x86_pmu.num_counters_fixed));
+			c->weight = hweight64(c->idxmsk64);
+		}
+	}
+
+	/*
+	 * Access LBR MSR may cause #GP under certain circumstances.
+	 * E.g. KVM doesn't support LBR MSR
+	 * Check all LBT MSR here.
+	 * Disable LBR access if any LBR MSRs can not be accessed.
+	 */
+	if (x86_pmu.lbr_nr && !check_msr(x86_pmu.lbr_tos, 0x3UL))
+		x86_pmu.lbr_nr = 0;
+	for (i = 0; i < x86_pmu.lbr_nr; i++) {
+		if (!(check_msr(x86_pmu.lbr_from + i, 0xffffUL) &&
+		      check_msr(x86_pmu.lbr_to + i, 0xffffUL)))
+			x86_pmu.lbr_nr = 0;
+	}
+
+	/*
+	 * Access extra MSR may cause #GP under certain circumstances.
+	 * E.g. KVM doesn't support offcore event
+	 * Check all extra_regs here.
+	 */
+	if (x86_pmu.extra_regs) {
+		for (er = x86_pmu.extra_regs; er->msr; er++) {
+			er->extra_msr_access = check_msr(er->msr, 0x11UL);
+			/* Disable LBR select mapping */
+			if ((er->idx == EXTRA_REG_LBR) && !er->extra_msr_access)
+				x86_pmu.lbr_sel_map = NULL;
+		}
+	}
+
+	/* Support full width counters using alternative MSR range */
+	if (x86_pmu.intel_cap.full_width_write) {
+		x86_pmu.max_period = x86_pmu.cntval_mask;
+		x86_pmu.perfctr = MSR_IA32_PMC0;
+		pr_cont("full-width counters, ");
+	}
+
+	return 0;
+}
+
+/*
+ * HT bug: phase 2 init
+ * Called once we have valid topology information to check
+ * whether or not HT is enabled
+ * If HT is off, then we disable the workaround
+ */
+static __init int fixup_ht_bug(void)
+{
+	int cpu = smp_processor_id();
+	int w, c;
+	/*
+	 * problem not present on this CPU model, nothing to do
+	 */
+	if (!(x86_pmu.flags & PMU_FL_EXCL_ENABLED))
+		return 0;
+
+	w = cpumask_weight(topology_sibling_cpumask(cpu));
+	if (w > 1) {
+		pr_info("PMU erratum BJ122, BV98, HSD29 worked around, HT is on\n");
+		return 0;
+	}
+
+	if (lockup_detector_suspend() != 0) {
+		pr_debug("failed to disable PMU erratum BJ122, BV98, HSD29 workaround\n");
+		return 0;
+	}
+
+	x86_pmu.flags &= ~(PMU_FL_EXCL_CNTRS | PMU_FL_EXCL_ENABLED);
+
+	x86_pmu.start_scheduling = NULL;
+	x86_pmu.commit_scheduling = NULL;
+	x86_pmu.stop_scheduling = NULL;
+
+	lockup_detector_resume();
+
+	get_online_cpus();
+
+	for_each_online_cpu(c) {
+		free_excl_cntrs(c);
+	}
+
+	put_online_cpus();
+	pr_info("PMU erratum BJ122, BV98, HSD29 workaround disabled, HT off\n");
+	return 0;
+}
+subsys_initcall(fixup_ht_bug)
--- /dev/null
+++ zfcpdump-kernel-4.4/arch/x86/events/intel/cqm.c
@@ -0,0 +1,1801 @@
+/*
+ * Intel Cache Quality-of-Service Monitoring (CQM) support.
+ *
+ * Based very, very heavily on work by Peter Zijlstra.
+ */
+
+#include <linux/perf_event.h>
+#include <linux/slab.h>
+#include <asm/cpu_device_id.h>
+#include "../perf_event.h"
+
+#define MSR_IA32_PQR_ASSOC	0x0c8f
+#define MSR_IA32_QM_CTR		0x0c8e
+#define MSR_IA32_QM_EVTSEL	0x0c8d
+
+#define MBM_CNTR_WIDTH		24
+/*
+ * Guaranteed time in ms as per SDM where MBM counters will not overflow.
+ */
+#define MBM_CTR_OVERFLOW_TIME	1000
+
+static u32 cqm_max_rmid = -1;
+static unsigned int cqm_l3_scale; /* supposedly cacheline size */
+static bool cqm_enabled, mbm_enabled;
+unsigned int mbm_socket_max;
+
+/**
+ * struct intel_pqr_state - State cache for the PQR MSR
+ * @rmid:		The cached Resource Monitoring ID
+ * @closid:		The cached Class Of Service ID
+ * @rmid_usecnt:	The usage counter for rmid
+ *
+ * The upper 32 bits of MSR_IA32_PQR_ASSOC contain closid and the
+ * lower 10 bits rmid. The update to MSR_IA32_PQR_ASSOC always
+ * contains both parts, so we need to cache them.
+ *
+ * The cache also helps to avoid pointless updates if the value does
+ * not change.
+ */
+struct intel_pqr_state {
+	u32			rmid;
+	u32			closid;
+	int			rmid_usecnt;
+};
+
+/*
+ * The cached intel_pqr_state is strictly per CPU and can never be
+ * updated from a remote CPU. Both functions which modify the state
+ * (intel_cqm_event_start and intel_cqm_event_stop) are called with
+ * interrupts disabled, which is sufficient for the protection.
+ */
+static DEFINE_PER_CPU(struct intel_pqr_state, pqr_state);
+static struct hrtimer *mbm_timers;
+/**
+ * struct sample - mbm event's (local or total) data
+ * @total_bytes    #bytes since we began monitoring
+ * @prev_msr       previous value of MSR
+ */
+struct sample {
+	u64	total_bytes;
+	u64	prev_msr;
+};
+
+/*
+ * samples profiled for total memory bandwidth type events
+ */
+static struct sample *mbm_total;
+/*
+ * samples profiled for local memory bandwidth type events
+ */
+static struct sample *mbm_local;
+
+#define pkg_id	topology_physical_package_id(smp_processor_id())
+/*
+ * rmid_2_index returns the index for the rmid in mbm_local/mbm_total array.
+ * mbm_total[] and mbm_local[] are linearly indexed by socket# * max number of
+ * rmids per socket, an example is given below
+ * RMID1 of Socket0:  vrmid =  1
+ * RMID1 of Socket1:  vrmid =  1 * (cqm_max_rmid + 1) + 1
+ * RMID1 of Socket2:  vrmid =  2 * (cqm_max_rmid + 1) + 1
+ */
+#define rmid_2_index(rmid)  ((pkg_id * (cqm_max_rmid + 1)) + rmid)
+/*
+ * Protects cache_cgroups and cqm_rmid_free_lru and cqm_rmid_limbo_lru.
+ * Also protects event->hw.cqm_rmid
+ *
+ * Hold either for stability, both for modification of ->hw.cqm_rmid.
+ */
+static DEFINE_MUTEX(cache_mutex);
+static DEFINE_RAW_SPINLOCK(cache_lock);
+
+/*
+ * Groups of events that have the same target(s), one RMID per group.
+ */
+static LIST_HEAD(cache_groups);
+
+/*
+ * Mask of CPUs for reading CQM values. We only need one per-socket.
+ */
+static cpumask_t cqm_cpumask;
+
+#define RMID_VAL_ERROR		(1ULL << 63)
+#define RMID_VAL_UNAVAIL	(1ULL << 62)
+
+/*
+ * Event IDs are used to program IA32_QM_EVTSEL before reading event
+ * counter from IA32_QM_CTR
+ */
+#define QOS_L3_OCCUP_EVENT_ID	0x01
+#define QOS_MBM_TOTAL_EVENT_ID	0x02
+#define QOS_MBM_LOCAL_EVENT_ID	0x03
+
+/*
+ * This is central to the rotation algorithm in __intel_cqm_rmid_rotate().
+ *
+ * This rmid is always free and is guaranteed to have an associated
+ * near-zero occupancy value, i.e. no cachelines are tagged with this
+ * RMID, once __intel_cqm_rmid_rotate() returns.
+ */
+static u32 intel_cqm_rotation_rmid;
+
+#define INVALID_RMID		(-1)
+
+/*
+ * Is @rmid valid for programming the hardware?
+ *
+ * rmid 0 is reserved by the hardware for all non-monitored tasks, which
+ * means that we should never come across an rmid with that value.
+ * Likewise, an rmid value of -1 is used to indicate "no rmid currently
+ * assigned" and is used as part of the rotation code.
+ */
+static inline bool __rmid_valid(u32 rmid)
+{
+	if (!rmid || rmid == INVALID_RMID)
+		return false;
+
+	return true;
+}
+
+static u64 __rmid_read(u32 rmid)
+{
+	u64 val;
+
+	/*
+	 * Ignore the SDM, this thing is _NOTHING_ like a regular perfcnt,
+	 * it just says that to increase confusion.
+	 */
+	wrmsr(MSR_IA32_QM_EVTSEL, QOS_L3_OCCUP_EVENT_ID, rmid);
+	rdmsrl(MSR_IA32_QM_CTR, val);
+
+	/*
+	 * Aside from the ERROR and UNAVAIL bits, assume this thing returns
+	 * the number of cachelines tagged with @rmid.
+	 */
+	return val;
+}
+
+enum rmid_recycle_state {
+	RMID_YOUNG = 0,
+	RMID_AVAILABLE,
+	RMID_DIRTY,
+};
+
+struct cqm_rmid_entry {
+	u32 rmid;
+	enum rmid_recycle_state state;
+	struct list_head list;
+	unsigned long queue_time;
+};
+
+/*
+ * cqm_rmid_free_lru - A least recently used list of RMIDs.
+ *
+ * Oldest entry at the head, newest (most recently used) entry at the
+ * tail. This list is never traversed, it's only used to keep track of
+ * the lru order. That is, we only pick entries of the head or insert
+ * them on the tail.
+ *
+ * All entries on the list are 'free', and their RMIDs are not currently
+ * in use. To mark an RMID as in use, remove its entry from the lru
+ * list.
+ *
+ *
+ * cqm_rmid_limbo_lru - list of currently unused but (potentially) dirty RMIDs.
+ *
+ * This list is contains RMIDs that no one is currently using but that
+ * may have a non-zero occupancy value associated with them. The
+ * rotation worker moves RMIDs from the limbo list to the free list once
+ * the occupancy value drops below __intel_cqm_threshold.
+ *
+ * Both lists are protected by cache_mutex.
+ */
+static LIST_HEAD(cqm_rmid_free_lru);
+static LIST_HEAD(cqm_rmid_limbo_lru);
+
+/*
+ * We use a simple array of pointers so that we can lookup a struct
+ * cqm_rmid_entry in O(1). This alleviates the callers of __get_rmid()
+ * and __put_rmid() from having to worry about dealing with struct
+ * cqm_rmid_entry - they just deal with rmids, i.e. integers.
+ *
+ * Once this array is initialized it is read-only. No locks are required
+ * to access it.
+ *
+ * All entries for all RMIDs can be looked up in the this array at all
+ * times.
+ */
+static struct cqm_rmid_entry **cqm_rmid_ptrs;
+
+static inline struct cqm_rmid_entry *__rmid_entry(u32 rmid)
+{
+	struct cqm_rmid_entry *entry;
+
+	entry = cqm_rmid_ptrs[rmid];
+	WARN_ON(entry->rmid != rmid);
+
+	return entry;
+}
+
+/*
+ * Returns < 0 on fail.
+ *
+ * We expect to be called with cache_mutex held.
+ */
+static u32 __get_rmid(void)
+{
+	struct cqm_rmid_entry *entry;
+
+	lockdep_assert_held(&cache_mutex);
+
+	if (list_empty(&cqm_rmid_free_lru))
+		return INVALID_RMID;
+
+	entry = list_first_entry(&cqm_rmid_free_lru, struct cqm_rmid_entry, list);
+	list_del(&entry->list);
+
+	return entry->rmid;
+}
+
+static void __put_rmid(u32 rmid)
+{
+	struct cqm_rmid_entry *entry;
+
+	lockdep_assert_held(&cache_mutex);
+
+	WARN_ON(!__rmid_valid(rmid));
+	entry = __rmid_entry(rmid);
+
+	entry->queue_time = jiffies;
+	entry->state = RMID_YOUNG;
+
+	list_add_tail(&entry->list, &cqm_rmid_limbo_lru);
+}
+
+static void cqm_cleanup(void)
+{
+	int i;
+
+	if (!cqm_rmid_ptrs)
+		return;
+
+	for (i = 0; i < cqm_max_rmid; i++)
+		kfree(cqm_rmid_ptrs[i]);
+
+	kfree(cqm_rmid_ptrs);
+	cqm_rmid_ptrs = NULL;
+	cqm_enabled = false;
+}
+
+static int intel_cqm_setup_rmid_cache(void)
+{
+	struct cqm_rmid_entry *entry;
+	unsigned int nr_rmids;
+	int r = 0;
+
+	nr_rmids = cqm_max_rmid + 1;
+	cqm_rmid_ptrs = kzalloc(sizeof(struct cqm_rmid_entry *) *
+				nr_rmids, GFP_KERNEL);
+	if (!cqm_rmid_ptrs)
+		return -ENOMEM;
+
+	for (; r <= cqm_max_rmid; r++) {
+		struct cqm_rmid_entry *entry;
+
+		entry = kmalloc(sizeof(*entry), GFP_KERNEL);
+		if (!entry)
+			goto fail;
+
+		INIT_LIST_HEAD(&entry->list);
+		entry->rmid = r;
+		cqm_rmid_ptrs[r] = entry;
+
+		list_add_tail(&entry->list, &cqm_rmid_free_lru);
+	}
+
+	/*
+	 * RMID 0 is special and is always allocated. It's used for all
+	 * tasks that are not monitored.
+	 */
+	entry = __rmid_entry(0);
+	list_del(&entry->list);
+
+	mutex_lock(&cache_mutex);
+	intel_cqm_rotation_rmid = __get_rmid();
+	mutex_unlock(&cache_mutex);
+
+	return 0;
+
+fail:
+	cqm_cleanup();
+	return -ENOMEM;
+}
+
+/*
+ * Determine if @a and @b measure the same set of tasks.
+ *
+ * If @a and @b measure the same set of tasks then we want to share a
+ * single RMID.
+ */
+static bool __match_event(struct perf_event *a, struct perf_event *b)
+{
+	/* Per-cpu and task events don't mix */
+	if ((a->attach_state & PERF_ATTACH_TASK) !=
+	    (b->attach_state & PERF_ATTACH_TASK))
+		return false;
+
+#ifdef CONFIG_CGROUP_PERF
+	if (a->cgrp != b->cgrp)
+		return false;
+#endif
+
+	/* If not task event, we're machine wide */
+	if (!(b->attach_state & PERF_ATTACH_TASK))
+		return true;
+
+	/*
+	 * Events that target same task are placed into the same cache group.
+	 * Mark it as a multi event group, so that we update ->count
+	 * for every event rather than just the group leader later.
+	 */
+	if (a->hw.target == b->hw.target) {
+		b->hw.is_group_event = true;
+		return true;
+	}
+
+	/*
+	 * Are we an inherited event?
+	 */
+	if (b->parent == a)
+		return true;
+
+	return false;
+}
+
+#ifdef CONFIG_CGROUP_PERF
+static inline struct perf_cgroup *event_to_cgroup(struct perf_event *event)
+{
+	if (event->attach_state & PERF_ATTACH_TASK)
+		return perf_cgroup_from_task(event->hw.target, event->ctx);
+
+	return event->cgrp;
+}
+#endif
+
+/*
+ * Determine if @a's tasks intersect with @b's tasks
+ *
+ * There are combinations of events that we explicitly prohibit,
+ *
+ *		   PROHIBITS
+ *     system-wide    -> 	cgroup and task
+ *     cgroup 	      ->	system-wide
+ *     		      ->	task in cgroup
+ *     task 	      -> 	system-wide
+ *     		      ->	task in cgroup
+ *
+ * Call this function before allocating an RMID.
+ */
+static bool __conflict_event(struct perf_event *a, struct perf_event *b)
+{
+#ifdef CONFIG_CGROUP_PERF
+	/*
+	 * We can have any number of cgroups but only one system-wide
+	 * event at a time.
+	 */
+	if (a->cgrp && b->cgrp) {
+		struct perf_cgroup *ac = a->cgrp;
+		struct perf_cgroup *bc = b->cgrp;
+
+		/*
+		 * This condition should have been caught in
+		 * __match_event() and we should be sharing an RMID.
+		 */
+		WARN_ON_ONCE(ac == bc);
+
+		if (cgroup_is_descendant(ac->css.cgroup, bc->css.cgroup) ||
+		    cgroup_is_descendant(bc->css.cgroup, ac->css.cgroup))
+			return true;
+
+		return false;
+	}
+
+	if (a->cgrp || b->cgrp) {
+		struct perf_cgroup *ac, *bc;
+
+		/*
+		 * cgroup and system-wide events are mutually exclusive
+		 */
+		if ((a->cgrp && !(b->attach_state & PERF_ATTACH_TASK)) ||
+		    (b->cgrp && !(a->attach_state & PERF_ATTACH_TASK)))
+			return true;
+
+		/*
+		 * Ensure neither event is part of the other's cgroup
+		 */
+		ac = event_to_cgroup(a);
+		bc = event_to_cgroup(b);
+		if (ac == bc)
+			return true;
+
+		/*
+		 * Must have cgroup and non-intersecting task events.
+		 */
+		if (!ac || !bc)
+			return false;
+
+		/*
+		 * We have cgroup and task events, and the task belongs
+		 * to a cgroup. Check for for overlap.
+		 */
+		if (cgroup_is_descendant(ac->css.cgroup, bc->css.cgroup) ||
+		    cgroup_is_descendant(bc->css.cgroup, ac->css.cgroup))
+			return true;
+
+		return false;
+	}
+#endif
+	/*
+	 * If one of them is not a task, same story as above with cgroups.
+	 */
+	if (!(a->attach_state & PERF_ATTACH_TASK) ||
+	    !(b->attach_state & PERF_ATTACH_TASK))
+		return true;
+
+	/*
+	 * Must be non-overlapping.
+	 */
+	return false;
+}
+
+struct rmid_read {
+	u32 rmid;
+	u32 evt_type;
+	atomic64_t value;
+};
+
+static void __intel_cqm_event_count(void *info);
+static void init_mbm_sample(u32 rmid, u32 evt_type);
+static void __intel_mbm_event_count(void *info);
+
+static bool is_mbm_event(int e)
+{
+	return (e >= QOS_MBM_TOTAL_EVENT_ID && e <= QOS_MBM_LOCAL_EVENT_ID);
+}
+
+/*
+ * Exchange the RMID of a group of events.
+ */
+static u32 intel_cqm_xchg_rmid(struct perf_event *group, u32 rmid)
+{
+	struct perf_event *event;
+	struct list_head *head = &group->hw.cqm_group_entry;
+	u32 old_rmid = group->hw.cqm_rmid;
+
+	lockdep_assert_held(&cache_mutex);
+
+	/*
+	 * If our RMID is being deallocated, perform a read now.
+	 */
+	if (__rmid_valid(old_rmid) && !__rmid_valid(rmid)) {
+		struct rmid_read rr = {
+			.value = ATOMIC64_INIT(0),
+			.rmid = old_rmid,
+		};
+
+		if (is_mbm_event(group->attr.config)) {
+			rr.evt_type = group->attr.config;
+			on_each_cpu_mask(&cqm_cpumask, __intel_mbm_event_count,
+					 &rr, 1);
+		} else {
+			on_each_cpu_mask(&cqm_cpumask, __intel_cqm_event_count,
+					 &rr, 1);
+		}
+		local64_set(&group->count, atomic64_read(&rr.value));
+	}
+
+	raw_spin_lock_irq(&cache_lock);
+
+	group->hw.cqm_rmid = rmid;
+	list_for_each_entry(event, head, hw.cqm_group_entry)
+		event->hw.cqm_rmid = rmid;
+
+	raw_spin_unlock_irq(&cache_lock);
+
+	/*
+	 * If the allocation is for mbm, init the mbm stats.
+	 * Need to check if each event in the group is mbm event
+	 * because there could be multiple type of events in the same group.
+	 */
+	if (__rmid_valid(rmid)) {
+		event = group;
+		if (is_mbm_event(event->attr.config))
+			init_mbm_sample(rmid, event->attr.config);
+
+		list_for_each_entry(event, head, hw.cqm_group_entry) {
+			if (is_mbm_event(event->attr.config))
+				init_mbm_sample(rmid, event->attr.config);
+		}
+	}
+
+	return old_rmid;
+}
+
+/*
+ * If we fail to assign a new RMID for intel_cqm_rotation_rmid because
+ * cachelines are still tagged with RMIDs in limbo, we progressively
+ * increment the threshold until we find an RMID in limbo with <=
+ * __intel_cqm_threshold lines tagged. This is designed to mitigate the
+ * problem where cachelines tagged with an RMID are not steadily being
+ * evicted.
+ *
+ * On successful rotations we decrease the threshold back towards zero.
+ *
+ * __intel_cqm_max_threshold provides an upper bound on the threshold,
+ * and is measured in bytes because it's exposed to userland.
+ */
+static unsigned int __intel_cqm_threshold;
+static unsigned int __intel_cqm_max_threshold;
+
+/*
+ * Test whether an RMID has a zero occupancy value on this cpu.
+ */
+static void intel_cqm_stable(void *arg)
+{
+	struct cqm_rmid_entry *entry;
+
+	list_for_each_entry(entry, &cqm_rmid_limbo_lru, list) {
+		if (entry->state != RMID_AVAILABLE)
+			break;
+
+		if (__rmid_read(entry->rmid) > __intel_cqm_threshold)
+			entry->state = RMID_DIRTY;
+	}
+}
+
+/*
+ * If we have group events waiting for an RMID that don't conflict with
+ * events already running, assign @rmid.
+ */
+static bool intel_cqm_sched_in_event(u32 rmid)
+{
+	struct perf_event *leader, *event;
+
+	lockdep_assert_held(&cache_mutex);
+
+	leader = list_first_entry(&cache_groups, struct perf_event,
+				  hw.cqm_groups_entry);
+	event = leader;
+
+	list_for_each_entry_continue(event, &cache_groups,
+				     hw.cqm_groups_entry) {
+		if (__rmid_valid(event->hw.cqm_rmid))
+			continue;
+
+		if (__conflict_event(event, leader))
+			continue;
+
+		intel_cqm_xchg_rmid(event, rmid);
+		return true;
+	}
+
+	return false;
+}
+
+/*
+ * Initially use this constant for both the limbo queue time and the
+ * rotation timer interval, pmu::hrtimer_interval_ms.
+ *
+ * They don't need to be the same, but the two are related since if you
+ * rotate faster than you recycle RMIDs, you may run out of available
+ * RMIDs.
+ */
+#define RMID_DEFAULT_QUEUE_TIME 250	/* ms */
+
+static unsigned int __rmid_queue_time_ms = RMID_DEFAULT_QUEUE_TIME;
+
+/*
+ * intel_cqm_rmid_stabilize - move RMIDs from limbo to free list
+ * @nr_available: number of freeable RMIDs on the limbo list
+ *
+ * Quiescent state; wait for all 'freed' RMIDs to become unused, i.e. no
+ * cachelines are tagged with those RMIDs. After this we can reuse them
+ * and know that the current set of active RMIDs is stable.
+ *
+ * Return %true or %false depending on whether stabilization needs to be
+ * reattempted.
+ *
+ * If we return %true then @nr_available is updated to indicate the
+ * number of RMIDs on the limbo list that have been queued for the
+ * minimum queue time (RMID_AVAILABLE), but whose data occupancy values
+ * are above __intel_cqm_threshold.
+ */
+static bool intel_cqm_rmid_stabilize(unsigned int *available)
+{
+	struct cqm_rmid_entry *entry, *tmp;
+
+	lockdep_assert_held(&cache_mutex);
+
+	*available = 0;
+	list_for_each_entry(entry, &cqm_rmid_limbo_lru, list) {
+		unsigned long min_queue_time;
+		unsigned long now = jiffies;
+
+		/*
+		 * We hold RMIDs placed into limbo for a minimum queue
+		 * time. Before the minimum queue time has elapsed we do
+		 * not recycle RMIDs.
+		 *
+		 * The reasoning is that until a sufficient time has
+		 * passed since we stopped using an RMID, any RMID
+		 * placed onto the limbo list will likely still have
+		 * data tagged in the cache, which means we'll probably
+		 * fail to recycle it anyway.
+		 *
+		 * We can save ourselves an expensive IPI by skipping
+		 * any RMIDs that have not been queued for the minimum
+		 * time.
+		 */
+		min_queue_time = entry->queue_time +
+			msecs_to_jiffies(__rmid_queue_time_ms);
+
+		if (time_after(min_queue_time, now))
+			break;
+
+		entry->state = RMID_AVAILABLE;
+		(*available)++;
+	}
+
+	/*
+	 * Fast return if none of the RMIDs on the limbo list have been
+	 * sitting on the queue for the minimum queue time.
+	 */
+	if (!*available)
+		return false;
+
+	/*
+	 * Test whether an RMID is free for each package.
+	 */
+	on_each_cpu_mask(&cqm_cpumask, intel_cqm_stable, NULL, true);
+
+	list_for_each_entry_safe(entry, tmp, &cqm_rmid_limbo_lru, list) {
+		/*
+		 * Exhausted all RMIDs that have waited min queue time.
+		 */
+		if (entry->state == RMID_YOUNG)
+			break;
+
+		if (entry->state == RMID_DIRTY)
+			continue;
+
+		list_del(&entry->list);	/* remove from limbo */
+
+		/*
+		 * The rotation RMID gets priority if it's
+		 * currently invalid. In which case, skip adding
+		 * the RMID to the the free lru.
+		 */
+		if (!__rmid_valid(intel_cqm_rotation_rmid)) {
+			intel_cqm_rotation_rmid = entry->rmid;
+			continue;
+		}
+
+		/*
+		 * If we have groups waiting for RMIDs, hand
+		 * them one now provided they don't conflict.
+		 */
+		if (intel_cqm_sched_in_event(entry->rmid))
+			continue;
+
+		/*
+		 * Otherwise place it onto the free list.
+		 */
+		list_add_tail(&entry->list, &cqm_rmid_free_lru);
+	}
+
+
+	return __rmid_valid(intel_cqm_rotation_rmid);
+}
+
+/*
+ * Pick a victim group and move it to the tail of the group list.
+ * @next: The first group without an RMID
+ */
+static void __intel_cqm_pick_and_rotate(struct perf_event *next)
+{
+	struct perf_event *rotor;
+	u32 rmid;
+
+	lockdep_assert_held(&cache_mutex);
+
+	rotor = list_first_entry(&cache_groups, struct perf_event,
+				 hw.cqm_groups_entry);
+
+	/*
+	 * The group at the front of the list should always have a valid
+	 * RMID. If it doesn't then no groups have RMIDs assigned and we
+	 * don't need to rotate the list.
+	 */
+	if (next == rotor)
+		return;
+
+	rmid = intel_cqm_xchg_rmid(rotor, INVALID_RMID);
+	__put_rmid(rmid);
+
+	list_rotate_left(&cache_groups);
+}
+
+/*
+ * Deallocate the RMIDs from any events that conflict with @event, and
+ * place them on the back of the group list.
+ */
+static void intel_cqm_sched_out_conflicting_events(struct perf_event *event)
+{
+	struct perf_event *group, *g;
+	u32 rmid;
+
+	lockdep_assert_held(&cache_mutex);
+
+	list_for_each_entry_safe(group, g, &cache_groups, hw.cqm_groups_entry) {
+		if (group == event)
+			continue;
+
+		rmid = group->hw.cqm_rmid;
+
+		/*
+		 * Skip events that don't have a valid RMID.
+		 */
+		if (!__rmid_valid(rmid))
+			continue;
+
+		/*
+		 * No conflict? No problem! Leave the event alone.
+		 */
+		if (!__conflict_event(group, event))
+			continue;
+
+		intel_cqm_xchg_rmid(group, INVALID_RMID);
+		__put_rmid(rmid);
+	}
+}
+
+/*
+ * Attempt to rotate the groups and assign new RMIDs.
+ *
+ * We rotate for two reasons,
+ *   1. To handle the scheduling of conflicting events
+ *   2. To recycle RMIDs
+ *
+ * Rotating RMIDs is complicated because the hardware doesn't give us
+ * any clues.
+ *
+ * There's problems with the hardware interface; when you change the
+ * task:RMID map cachelines retain their 'old' tags, giving a skewed
+ * picture. In order to work around this, we must always keep one free
+ * RMID - intel_cqm_rotation_rmid.
+ *
+ * Rotation works by taking away an RMID from a group (the old RMID),
+ * and assigning the free RMID to another group (the new RMID). We must
+ * then wait for the old RMID to not be used (no cachelines tagged).
+ * This ensure that all cachelines are tagged with 'active' RMIDs. At
+ * this point we can start reading values for the new RMID and treat the
+ * old RMID as the free RMID for the next rotation.
+ *
+ * Return %true or %false depending on whether we did any rotating.
+ */
+static bool __intel_cqm_rmid_rotate(void)
+{
+	struct perf_event *group, *start = NULL;
+	unsigned int threshold_limit;
+	unsigned int nr_needed = 0;
+	unsigned int nr_available;
+	bool rotated = false;
+
+	mutex_lock(&cache_mutex);
+
+again:
+	/*
+	 * Fast path through this function if there are no groups and no
+	 * RMIDs that need cleaning.
+	 */
+	if (list_empty(&cache_groups) && list_empty(&cqm_rmid_limbo_lru))
+		goto out;
+
+	list_for_each_entry(group, &cache_groups, hw.cqm_groups_entry) {
+		if (!__rmid_valid(group->hw.cqm_rmid)) {
+			if (!start)
+				start = group;
+			nr_needed++;
+		}
+	}
+
+	/*
+	 * We have some event groups, but they all have RMIDs assigned
+	 * and no RMIDs need cleaning.
+	 */
+	if (!nr_needed && list_empty(&cqm_rmid_limbo_lru))
+		goto out;
+
+	if (!nr_needed)
+		goto stabilize;
+
+	/*
+	 * We have more event groups without RMIDs than available RMIDs,
+	 * or we have event groups that conflict with the ones currently
+	 * scheduled.
+	 *
+	 * We force deallocate the rmid of the group at the head of
+	 * cache_groups. The first event group without an RMID then gets
+	 * assigned intel_cqm_rotation_rmid. This ensures we always make
+	 * forward progress.
+	 *
+	 * Rotate the cache_groups list so the previous head is now the
+	 * tail.
+	 */
+	__intel_cqm_pick_and_rotate(start);
+
+	/*
+	 * If the rotation is going to succeed, reduce the threshold so
+	 * that we don't needlessly reuse dirty RMIDs.
+	 */
+	if (__rmid_valid(intel_cqm_rotation_rmid)) {
+		intel_cqm_xchg_rmid(start, intel_cqm_rotation_rmid);
+		intel_cqm_rotation_rmid = __get_rmid();
+
+		intel_cqm_sched_out_conflicting_events(start);
+
+		if (__intel_cqm_threshold)
+			__intel_cqm_threshold--;
+	}
+
+	rotated = true;
+
+stabilize:
+	/*
+	 * We now need to stablize the RMID we freed above (if any) to
+	 * ensure that the next time we rotate we have an RMID with zero
+	 * occupancy value.
+	 *
+	 * Alternatively, if we didn't need to perform any rotation,
+	 * we'll have a bunch of RMIDs in limbo that need stabilizing.
+	 */
+	threshold_limit = __intel_cqm_max_threshold / cqm_l3_scale;
+
+	while (intel_cqm_rmid_stabilize(&nr_available) &&
+	       __intel_cqm_threshold < threshold_limit) {
+		unsigned int steal_limit;
+
+		/*
+		 * Don't spin if nobody is actively waiting for an RMID,
+		 * the rotation worker will be kicked as soon as an
+		 * event needs an RMID anyway.
+		 */
+		if (!nr_needed)
+			break;
+
+		/* Allow max 25% of RMIDs to be in limbo. */
+		steal_limit = (cqm_max_rmid + 1) / 4;
+
+		/*
+		 * We failed to stabilize any RMIDs so our rotation
+		 * logic is now stuck. In order to make forward progress
+		 * we have a few options:
+		 *
+		 *   1. rotate ("steal") another RMID
+		 *   2. increase the threshold
+		 *   3. do nothing
+		 *
+		 * We do both of 1. and 2. until we hit the steal limit.
+		 *
+		 * The steal limit prevents all RMIDs ending up on the
+		 * limbo list. This can happen if every RMID has a
+		 * non-zero occupancy above threshold_limit, and the
+		 * occupancy values aren't dropping fast enough.
+		 *
+		 * Note that there is prioritisation at work here - we'd
+		 * rather increase the number of RMIDs on the limbo list
+		 * than increase the threshold, because increasing the
+		 * threshold skews the event data (because we reuse
+		 * dirty RMIDs) - threshold bumps are a last resort.
+		 */
+		if (nr_available < steal_limit)
+			goto again;
+
+		__intel_cqm_threshold++;
+	}
+
+out:
+	mutex_unlock(&cache_mutex);
+	return rotated;
+}
+
+static void intel_cqm_rmid_rotate(struct work_struct *work);
+
+static DECLARE_DELAYED_WORK(intel_cqm_rmid_work, intel_cqm_rmid_rotate);
+
+static struct pmu intel_cqm_pmu;
+
+static void intel_cqm_rmid_rotate(struct work_struct *work)
+{
+	unsigned long delay;
+
+	__intel_cqm_rmid_rotate();
+
+	delay = msecs_to_jiffies(intel_cqm_pmu.hrtimer_interval_ms);
+	schedule_delayed_work(&intel_cqm_rmid_work, delay);
+}
+
+static u64 update_sample(unsigned int rmid, u32 evt_type, int first)
+{
+	struct sample *mbm_current;
+	u32 vrmid = rmid_2_index(rmid);
+	u64 val, bytes, shift;
+	u32 eventid;
+
+	if (evt_type == QOS_MBM_LOCAL_EVENT_ID) {
+		mbm_current = &mbm_local[vrmid];
+		eventid     = QOS_MBM_LOCAL_EVENT_ID;
+	} else {
+		mbm_current = &mbm_total[vrmid];
+		eventid     = QOS_MBM_TOTAL_EVENT_ID;
+	}
+
+	wrmsr(MSR_IA32_QM_EVTSEL, eventid, rmid);
+	rdmsrl(MSR_IA32_QM_CTR, val);
+	if (val & (RMID_VAL_ERROR | RMID_VAL_UNAVAIL))
+		return mbm_current->total_bytes;
+
+	if (first) {
+		mbm_current->prev_msr = val;
+		mbm_current->total_bytes = 0;
+		return mbm_current->total_bytes;
+	}
+
+	/*
+	 * The h/w guarantees that counters will not overflow
+	 * so long as we poll them at least once per second.
+	 */
+	shift = 64 - MBM_CNTR_WIDTH;
+	bytes = (val << shift) - (mbm_current->prev_msr << shift);
+	bytes >>= shift;
+
+	bytes *= cqm_l3_scale;
+
+	mbm_current->total_bytes += bytes;
+	mbm_current->prev_msr = val;
+
+	return mbm_current->total_bytes;
+}
+
+static u64 rmid_read_mbm(unsigned int rmid, u32 evt_type)
+{
+	return update_sample(rmid, evt_type, 0);
+}
+
+static void __intel_mbm_event_init(void *info)
+{
+	struct rmid_read *rr = info;
+
+	update_sample(rr->rmid, rr->evt_type, 1);
+}
+
+static void init_mbm_sample(u32 rmid, u32 evt_type)
+{
+	struct rmid_read rr = {
+		.rmid = rmid,
+		.evt_type = evt_type,
+		.value = ATOMIC64_INIT(0),
+	};
+
+	/* on each socket, init sample */
+	on_each_cpu_mask(&cqm_cpumask, __intel_mbm_event_init, &rr, 1);
+}
+
+/*
+ * Find a group and setup RMID.
+ *
+ * If we're part of a group, we use the group's RMID.
+ */
+static void intel_cqm_setup_event(struct perf_event *event,
+				  struct perf_event **group)
+{
+	struct perf_event *iter;
+	bool conflict = false;
+	u32 rmid;
+
+	event->hw.is_group_event = false;
+	list_for_each_entry(iter, &cache_groups, hw.cqm_groups_entry) {
+		rmid = iter->hw.cqm_rmid;
+
+		if (__match_event(iter, event)) {
+			/* All tasks in a group share an RMID */
+			event->hw.cqm_rmid = rmid;
+			*group = iter;
+			if (is_mbm_event(event->attr.config) && __rmid_valid(rmid))
+				init_mbm_sample(rmid, event->attr.config);
+			return;
+		}
+
+		/*
+		 * We only care about conflicts for events that are
+		 * actually scheduled in (and hence have a valid RMID).
+		 */
+		if (__conflict_event(iter, event) && __rmid_valid(rmid))
+			conflict = true;
+	}
+
+	if (conflict)
+		rmid = INVALID_RMID;
+	else
+		rmid = __get_rmid();
+
+	if (is_mbm_event(event->attr.config) && __rmid_valid(rmid))
+		init_mbm_sample(rmid, event->attr.config);
+
+	event->hw.cqm_rmid = rmid;
+}
+
+static void intel_cqm_event_read(struct perf_event *event)
+{
+	unsigned long flags;
+	u32 rmid;
+	u64 val;
+
+	/*
+	 * Task events are handled by intel_cqm_event_count().
+	 */
+	if (event->cpu == -1)
+		return;
+
+	raw_spin_lock_irqsave(&cache_lock, flags);
+	rmid = event->hw.cqm_rmid;
+
+	if (!__rmid_valid(rmid))
+		goto out;
+
+	if (is_mbm_event(event->attr.config))
+		val = rmid_read_mbm(rmid, event->attr.config);
+	else
+		val = __rmid_read(rmid);
+
+	/*
+	 * Ignore this reading on error states and do not update the value.
+	 */
+	if (val & (RMID_VAL_ERROR | RMID_VAL_UNAVAIL))
+		goto out;
+
+	local64_set(&event->count, val);
+out:
+	raw_spin_unlock_irqrestore(&cache_lock, flags);
+}
+
+static void __intel_cqm_event_count(void *info)
+{
+	struct rmid_read *rr = info;
+	u64 val;
+
+	val = __rmid_read(rr->rmid);
+
+	if (val & (RMID_VAL_ERROR | RMID_VAL_UNAVAIL))
+		return;
+
+	atomic64_add(val, &rr->value);
+}
+
+static inline bool cqm_group_leader(struct perf_event *event)
+{
+	return !list_empty(&event->hw.cqm_groups_entry);
+}
+
+static void __intel_mbm_event_count(void *info)
+{
+	struct rmid_read *rr = info;
+	u64 val;
+
+	val = rmid_read_mbm(rr->rmid, rr->evt_type);
+	if (val & (RMID_VAL_ERROR | RMID_VAL_UNAVAIL))
+		return;
+	atomic64_add(val, &rr->value);
+}
+
+static enum hrtimer_restart mbm_hrtimer_handle(struct hrtimer *hrtimer)
+{
+	struct perf_event *iter, *iter1;
+	int ret = HRTIMER_RESTART;
+	struct list_head *head;
+	unsigned long flags;
+	u32 grp_rmid;
+
+	/*
+	 * Need to cache_lock as the timer Event Select MSR reads
+	 * can race with the mbm/cqm count() and mbm_init() reads.
+	 */
+	raw_spin_lock_irqsave(&cache_lock, flags);
+
+	if (list_empty(&cache_groups)) {
+		ret = HRTIMER_NORESTART;
+		goto out;
+	}
+
+	list_for_each_entry(iter, &cache_groups, hw.cqm_groups_entry) {
+		grp_rmid = iter->hw.cqm_rmid;
+		if (!__rmid_valid(grp_rmid))
+			continue;
+		if (is_mbm_event(iter->attr.config))
+			update_sample(grp_rmid, iter->attr.config, 0);
+
+		head = &iter->hw.cqm_group_entry;
+		if (list_empty(head))
+			continue;
+		list_for_each_entry(iter1, head, hw.cqm_group_entry) {
+			if (!iter1->hw.is_group_event)
+				break;
+			if (is_mbm_event(iter1->attr.config))
+				update_sample(iter1->hw.cqm_rmid,
+					      iter1->attr.config, 0);
+		}
+	}
+
+	hrtimer_forward_now(hrtimer, ms_to_ktime(MBM_CTR_OVERFLOW_TIME));
+out:
+	raw_spin_unlock_irqrestore(&cache_lock, flags);
+
+	return ret;
+}
+
+static void __mbm_start_timer(void *info)
+{
+	hrtimer_start(&mbm_timers[pkg_id], ms_to_ktime(MBM_CTR_OVERFLOW_TIME),
+			     HRTIMER_MODE_REL_PINNED);
+}
+
+static void __mbm_stop_timer(void *info)
+{
+	hrtimer_cancel(&mbm_timers[pkg_id]);
+}
+
+static void mbm_start_timers(void)
+{
+	on_each_cpu_mask(&cqm_cpumask, __mbm_start_timer, NULL, 1);
+}
+
+static void mbm_stop_timers(void)
+{
+	on_each_cpu_mask(&cqm_cpumask, __mbm_stop_timer, NULL, 1);
+}
+
+static void mbm_hrtimer_init(void)
+{
+	struct hrtimer *hr;
+	int i;
+
+	for (i = 0; i < mbm_socket_max; i++) {
+		hr = &mbm_timers[i];
+		hrtimer_init(hr, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
+		hr->function = mbm_hrtimer_handle;
+	}
+}
+
+static u64 intel_cqm_event_count(struct perf_event *event)
+{
+	unsigned long flags;
+	struct rmid_read rr = {
+		.value = ATOMIC64_INIT(0),
+	};
+
+	/*
+	 * We only need to worry about task events. System-wide events
+	 * are handled like usual, i.e. entirely with
+	 * intel_cqm_event_read().
+	 */
+	if (event->cpu != -1)
+		return __perf_event_count(event);
+
+	/*
+	 * Only the group leader gets to report values except in case of
+	 * multiple events in the same group, we still need to read the
+	 * other events.This stops us
+	 * reporting duplicate values to userspace, and gives us a clear
+	 * rule for which task gets to report the values.
+	 *
+	 * Note that it is impossible to attribute these values to
+	 * specific packages - we forfeit that ability when we create
+	 * task events.
+	 */
+	if (!cqm_group_leader(event) && !event->hw.is_group_event)
+		return 0;
+
+	/*
+	 * Getting up-to-date values requires an SMP IPI which is not
+	 * possible if we're being called in interrupt context. Return
+	 * the cached values instead.
+	 */
+	if (unlikely(in_interrupt()))
+		goto out;
+
+	/*
+	 * Notice that we don't perform the reading of an RMID
+	 * atomically, because we can't hold a spin lock across the
+	 * IPIs.
+	 *
+	 * Speculatively perform the read, since @event might be
+	 * assigned a different (possibly invalid) RMID while we're
+	 * busying performing the IPI calls. It's therefore necessary to
+	 * check @event's RMID afterwards, and if it has changed,
+	 * discard the result of the read.
+	 */
+	rr.rmid = ACCESS_ONCE(event->hw.cqm_rmid);
+
+	if (!__rmid_valid(rr.rmid))
+		goto out;
+
+	if (is_mbm_event(event->attr.config)) {
+		rr.evt_type = event->attr.config;
+		on_each_cpu_mask(&cqm_cpumask, __intel_mbm_event_count, &rr, 1);
+	} else {
+		on_each_cpu_mask(&cqm_cpumask, __intel_cqm_event_count, &rr, 1);
+	}
+
+	raw_spin_lock_irqsave(&cache_lock, flags);
+	if (event->hw.cqm_rmid == rr.rmid)
+		local64_set(&event->count, atomic64_read(&rr.value));
+	raw_spin_unlock_irqrestore(&cache_lock, flags);
+out:
+	return __perf_event_count(event);
+}
+
+static void intel_cqm_event_start(struct perf_event *event, int mode)
+{
+	struct intel_pqr_state *state = this_cpu_ptr(&pqr_state);
+	u32 rmid = event->hw.cqm_rmid;
+
+	if (!(event->hw.cqm_state & PERF_HES_STOPPED))
+		return;
+
+	event->hw.cqm_state &= ~PERF_HES_STOPPED;
+
+	if (state->rmid_usecnt++) {
+		if (!WARN_ON_ONCE(state->rmid != rmid))
+			return;
+	} else {
+		WARN_ON_ONCE(state->rmid);
+	}
+
+	state->rmid = rmid;
+	wrmsr(MSR_IA32_PQR_ASSOC, rmid, state->closid);
+}
+
+static void intel_cqm_event_stop(struct perf_event *event, int mode)
+{
+	struct intel_pqr_state *state = this_cpu_ptr(&pqr_state);
+
+	if (event->hw.cqm_state & PERF_HES_STOPPED)
+		return;
+
+	event->hw.cqm_state |= PERF_HES_STOPPED;
+
+	intel_cqm_event_read(event);
+
+	if (!--state->rmid_usecnt) {
+		state->rmid = 0;
+		wrmsr(MSR_IA32_PQR_ASSOC, 0, state->closid);
+	} else {
+		WARN_ON_ONCE(!state->rmid);
+	}
+}
+
+static int intel_cqm_event_add(struct perf_event *event, int mode)
+{
+	unsigned long flags;
+	u32 rmid;
+
+	raw_spin_lock_irqsave(&cache_lock, flags);
+
+	event->hw.cqm_state = PERF_HES_STOPPED;
+	rmid = event->hw.cqm_rmid;
+
+	if (__rmid_valid(rmid) && (mode & PERF_EF_START))
+		intel_cqm_event_start(event, mode);
+
+	raw_spin_unlock_irqrestore(&cache_lock, flags);
+
+	return 0;
+}
+
+static void intel_cqm_event_destroy(struct perf_event *event)
+{
+	struct perf_event *group_other = NULL;
+	unsigned long flags;
+
+	mutex_lock(&cache_mutex);
+	/*
+	* Hold the cache_lock as mbm timer handlers could be
+	* scanning the list of events.
+	*/
+	raw_spin_lock_irqsave(&cache_lock, flags);
+
+	/*
+	 * If there's another event in this group...
+	 */
+	if (!list_empty(&event->hw.cqm_group_entry)) {
+		group_other = list_first_entry(&event->hw.cqm_group_entry,
+					       struct perf_event,
+					       hw.cqm_group_entry);
+		list_del(&event->hw.cqm_group_entry);
+	}
+
+	/*
+	 * And we're the group leader..
+	 */
+	if (cqm_group_leader(event)) {
+		/*
+		 * If there was a group_other, make that leader, otherwise
+		 * destroy the group and return the RMID.
+		 */
+		if (group_other) {
+			list_replace(&event->hw.cqm_groups_entry,
+				     &group_other->hw.cqm_groups_entry);
+		} else {
+			u32 rmid = event->hw.cqm_rmid;
+
+			if (__rmid_valid(rmid))
+				__put_rmid(rmid);
+			list_del(&event->hw.cqm_groups_entry);
+		}
+	}
+
+	raw_spin_unlock_irqrestore(&cache_lock, flags);
+
+	/*
+	 * Stop the mbm overflow timers when the last event is destroyed.
+	*/
+	if (mbm_enabled && list_empty(&cache_groups))
+		mbm_stop_timers();
+
+	mutex_unlock(&cache_mutex);
+}
+
+static int intel_cqm_event_init(struct perf_event *event)
+{
+	struct perf_event *group = NULL;
+	bool rotate = false;
+	unsigned long flags;
+
+	if (event->attr.type != intel_cqm_pmu.type)
+		return -ENOENT;
+
+	if ((event->attr.config < QOS_L3_OCCUP_EVENT_ID) ||
+	     (event->attr.config > QOS_MBM_LOCAL_EVENT_ID))
+		return -EINVAL;
+
+	/* unsupported modes and filters */
+	if (event->attr.exclude_user   ||
+	    event->attr.exclude_kernel ||
+	    event->attr.exclude_hv     ||
+	    event->attr.exclude_idle   ||
+	    event->attr.exclude_host   ||
+	    event->attr.exclude_guest  ||
+	    event->attr.sample_period) /* no sampling */
+		return -EINVAL;
+
+	INIT_LIST_HEAD(&event->hw.cqm_group_entry);
+	INIT_LIST_HEAD(&event->hw.cqm_groups_entry);
+
+	event->destroy = intel_cqm_event_destroy;
+
+	mutex_lock(&cache_mutex);
+
+	/*
+	 * Start the mbm overflow timers when the first event is created.
+	*/
+	if (mbm_enabled && list_empty(&cache_groups))
+		mbm_start_timers();
+
+	/* Will also set rmid */
+	intel_cqm_setup_event(event, &group);
+
+	/*
+	* Hold the cache_lock as mbm timer handlers be
+	* scanning the list of events.
+	*/
+	raw_spin_lock_irqsave(&cache_lock, flags);
+
+	if (group) {
+		list_add_tail(&event->hw.cqm_group_entry,
+			      &group->hw.cqm_group_entry);
+	} else {
+		list_add_tail(&event->hw.cqm_groups_entry,
+			      &cache_groups);
+
+		/*
+		 * All RMIDs are either in use or have recently been
+		 * used. Kick the rotation worker to clean/free some.
+		 *
+		 * We only do this for the group leader, rather than for
+		 * every event in a group to save on needless work.
+		 */
+		if (!__rmid_valid(event->hw.cqm_rmid))
+			rotate = true;
+	}
+
+	raw_spin_unlock_irqrestore(&cache_lock, flags);
+	mutex_unlock(&cache_mutex);
+
+	if (rotate)
+		schedule_delayed_work(&intel_cqm_rmid_work, 0);
+
+	return 0;
+}
+
+EVENT_ATTR_STR(llc_occupancy, intel_cqm_llc, "event=0x01");
+EVENT_ATTR_STR(llc_occupancy.per-pkg, intel_cqm_llc_pkg, "1");
+EVENT_ATTR_STR(llc_occupancy.unit, intel_cqm_llc_unit, "Bytes");
+EVENT_ATTR_STR(llc_occupancy.scale, intel_cqm_llc_scale, NULL);
+EVENT_ATTR_STR(llc_occupancy.snapshot, intel_cqm_llc_snapshot, "1");
+
+EVENT_ATTR_STR(total_bytes, intel_cqm_total_bytes, "event=0x02");
+EVENT_ATTR_STR(total_bytes.per-pkg, intel_cqm_total_bytes_pkg, "1");
+EVENT_ATTR_STR(total_bytes.unit, intel_cqm_total_bytes_unit, "MB");
+EVENT_ATTR_STR(total_bytes.scale, intel_cqm_total_bytes_scale, "1e-6");
+
+EVENT_ATTR_STR(local_bytes, intel_cqm_local_bytes, "event=0x03");
+EVENT_ATTR_STR(local_bytes.per-pkg, intel_cqm_local_bytes_pkg, "1");
+EVENT_ATTR_STR(local_bytes.unit, intel_cqm_local_bytes_unit, "MB");
+EVENT_ATTR_STR(local_bytes.scale, intel_cqm_local_bytes_scale, "1e-6");
+
+static struct attribute *intel_cqm_events_attr[] = {
+	EVENT_PTR(intel_cqm_llc),
+	EVENT_PTR(intel_cqm_llc_pkg),
+	EVENT_PTR(intel_cqm_llc_unit),
+	EVENT_PTR(intel_cqm_llc_scale),
+	EVENT_PTR(intel_cqm_llc_snapshot),
+	NULL,
+};
+
+static struct attribute *intel_mbm_events_attr[] = {
+	EVENT_PTR(intel_cqm_total_bytes),
+	EVENT_PTR(intel_cqm_local_bytes),
+	EVENT_PTR(intel_cqm_total_bytes_pkg),
+	EVENT_PTR(intel_cqm_local_bytes_pkg),
+	EVENT_PTR(intel_cqm_total_bytes_unit),
+	EVENT_PTR(intel_cqm_local_bytes_unit),
+	EVENT_PTR(intel_cqm_total_bytes_scale),
+	EVENT_PTR(intel_cqm_local_bytes_scale),
+	NULL,
+};
+
+static struct attribute *intel_cmt_mbm_events_attr[] = {
+	EVENT_PTR(intel_cqm_llc),
+	EVENT_PTR(intel_cqm_total_bytes),
+	EVENT_PTR(intel_cqm_local_bytes),
+	EVENT_PTR(intel_cqm_llc_pkg),
+	EVENT_PTR(intel_cqm_total_bytes_pkg),
+	EVENT_PTR(intel_cqm_local_bytes_pkg),
+	EVENT_PTR(intel_cqm_llc_unit),
+	EVENT_PTR(intel_cqm_total_bytes_unit),
+	EVENT_PTR(intel_cqm_local_bytes_unit),
+	EVENT_PTR(intel_cqm_llc_scale),
+	EVENT_PTR(intel_cqm_total_bytes_scale),
+	EVENT_PTR(intel_cqm_local_bytes_scale),
+	EVENT_PTR(intel_cqm_llc_snapshot),
+	NULL,
+};
+
+static struct attribute_group intel_cqm_events_group = {
+	.name = "events",
+	.attrs = NULL,
+};
+
+PMU_FORMAT_ATTR(event, "config:0-7");
+static struct attribute *intel_cqm_formats_attr[] = {
+	&format_attr_event.attr,
+	NULL,
+};
+
+static struct attribute_group intel_cqm_format_group = {
+	.name = "format",
+	.attrs = intel_cqm_formats_attr,
+};
+
+static ssize_t
+max_recycle_threshold_show(struct device *dev, struct device_attribute *attr,
+			   char *page)
+{
+	ssize_t rv;
+
+	mutex_lock(&cache_mutex);
+	rv = snprintf(page, PAGE_SIZE-1, "%u\n", __intel_cqm_max_threshold);
+	mutex_unlock(&cache_mutex);
+
+	return rv;
+}
+
+static ssize_t
+max_recycle_threshold_store(struct device *dev,
+			    struct device_attribute *attr,
+			    const char *buf, size_t count)
+{
+	unsigned int bytes, cachelines;
+	int ret;
+
+	ret = kstrtouint(buf, 0, &bytes);
+	if (ret)
+		return ret;
+
+	mutex_lock(&cache_mutex);
+
+	__intel_cqm_max_threshold = bytes;
+	cachelines = bytes / cqm_l3_scale;
+
+	/*
+	 * The new maximum takes effect immediately.
+	 */
+	if (__intel_cqm_threshold > cachelines)
+		__intel_cqm_threshold = cachelines;
+
+	mutex_unlock(&cache_mutex);
+
+	return count;
+}
+
+static DEVICE_ATTR_RW(max_recycle_threshold);
+
+static struct attribute *intel_cqm_attrs[] = {
+	&dev_attr_max_recycle_threshold.attr,
+	NULL,
+};
+
+static const struct attribute_group intel_cqm_group = {
+	.attrs = intel_cqm_attrs,
+};
+
+static const struct attribute_group *intel_cqm_attr_groups[] = {
+	&intel_cqm_events_group,
+	&intel_cqm_format_group,
+	&intel_cqm_group,
+	NULL,
+};
+
+static struct pmu intel_cqm_pmu = {
+	.hrtimer_interval_ms = RMID_DEFAULT_QUEUE_TIME,
+	.attr_groups	     = intel_cqm_attr_groups,
+	.task_ctx_nr	     = perf_sw_context,
+	.event_init	     = intel_cqm_event_init,
+	.add		     = intel_cqm_event_add,
+	.del		     = intel_cqm_event_stop,
+	.start		     = intel_cqm_event_start,
+	.stop		     = intel_cqm_event_stop,
+	.read		     = intel_cqm_event_read,
+	.count		     = intel_cqm_event_count,
+};
+
+static inline void cqm_pick_event_reader(int cpu)
+{
+	int phys_id = topology_physical_package_id(cpu);
+	int i;
+
+	for_each_cpu(i, &cqm_cpumask) {
+		if (phys_id == topology_physical_package_id(i))
+			return;	/* already got reader for this socket */
+	}
+
+	cpumask_set_cpu(cpu, &cqm_cpumask);
+}
+
+static void intel_cqm_cpu_starting(unsigned int cpu)
+{
+	struct intel_pqr_state *state = &per_cpu(pqr_state, cpu);
+	struct cpuinfo_x86 *c = &cpu_data(cpu);
+
+	state->rmid = 0;
+	state->closid = 0;
+	state->rmid_usecnt = 0;
+
+	WARN_ON(c->x86_cache_max_rmid != cqm_max_rmid);
+	WARN_ON(c->x86_cache_occ_scale != cqm_l3_scale);
+}
+
+static void intel_cqm_cpu_exit(unsigned int cpu)
+{
+	int phys_id = topology_physical_package_id(cpu);
+	int i;
+
+	/*
+	 * Is @cpu a designated cqm reader?
+	 */
+	if (!cpumask_test_and_clear_cpu(cpu, &cqm_cpumask))
+		return;
+
+	for_each_online_cpu(i) {
+		if (i == cpu)
+			continue;
+
+		if (phys_id == topology_physical_package_id(i)) {
+			cpumask_set_cpu(i, &cqm_cpumask);
+			break;
+		}
+	}
+}
+
+static int intel_cqm_cpu_notifier(struct notifier_block *nb,
+				  unsigned long action, void *hcpu)
+{
+	unsigned int cpu  = (unsigned long)hcpu;
+
+	switch (action & ~CPU_TASKS_FROZEN) {
+	case CPU_DOWN_PREPARE:
+		intel_cqm_cpu_exit(cpu);
+		break;
+	case CPU_STARTING:
+		intel_cqm_cpu_starting(cpu);
+		cqm_pick_event_reader(cpu);
+		break;
+	}
+
+	return NOTIFY_OK;
+}
+
+static const struct x86_cpu_id intel_cqm_match[] = {
+	{ .vendor = X86_VENDOR_INTEL, .feature = X86_FEATURE_CQM_OCCUP_LLC },
+	{}
+};
+
+static void mbm_cleanup(void)
+{
+	if (!mbm_enabled)
+		return;
+
+	kfree(mbm_local);
+	kfree(mbm_total);
+	mbm_enabled = false;
+}
+
+static const struct x86_cpu_id intel_mbm_local_match[] = {
+	{ .vendor = X86_VENDOR_INTEL, .feature = X86_FEATURE_CQM_MBM_LOCAL },
+	{}
+};
+
+static const struct x86_cpu_id intel_mbm_total_match[] = {
+	{ .vendor = X86_VENDOR_INTEL, .feature = X86_FEATURE_CQM_MBM_TOTAL },
+	{}
+};
+
+static int intel_mbm_init(void)
+{
+	int ret = 0, array_size, maxid = cqm_max_rmid + 1;
+
+	mbm_socket_max = topology_max_packages();
+	array_size = sizeof(struct sample) * maxid * mbm_socket_max;
+	mbm_local = kmalloc(array_size, GFP_KERNEL);
+	if (!mbm_local)
+		return -ENOMEM;
+
+	mbm_total = kmalloc(array_size, GFP_KERNEL);
+	if (!mbm_total) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	array_size = sizeof(struct hrtimer) * mbm_socket_max;
+	mbm_timers = kmalloc(array_size, GFP_KERNEL);
+	if (!mbm_timers) {
+		ret = -ENOMEM;
+		goto out;
+	}
+	mbm_hrtimer_init();
+
+out:
+	if (ret)
+		mbm_cleanup();
+
+	return ret;
+}
+
+static int __init intel_cqm_init(void)
+{
+	char *str = NULL, scale[20];
+	int i, cpu, ret;
+
+	if (x86_match_cpu(intel_cqm_match))
+		cqm_enabled = true;
+
+	if (x86_match_cpu(intel_mbm_local_match) &&
+	     x86_match_cpu(intel_mbm_total_match))
+		mbm_enabled = true;
+
+	if (!cqm_enabled && !mbm_enabled)
+		return -ENODEV;
+
+	cqm_l3_scale = boot_cpu_data.x86_cache_occ_scale;
+
+	/*
+	 * It's possible that not all resources support the same number
+	 * of RMIDs. Instead of making scheduling much more complicated
+	 * (where we have to match a task's RMID to a cpu that supports
+	 * that many RMIDs) just find the minimum RMIDs supported across
+	 * all cpus.
+	 *
+	 * Also, check that the scales match on all cpus.
+	 */
+	cpu_notifier_register_begin();
+
+	for_each_online_cpu(cpu) {
+		struct cpuinfo_x86 *c = &cpu_data(cpu);
+
+		if (c->x86_cache_max_rmid < cqm_max_rmid)
+			cqm_max_rmid = c->x86_cache_max_rmid;
+
+		if (c->x86_cache_occ_scale != cqm_l3_scale) {
+			pr_err("Multiple LLC scale values, disabling\n");
+			ret = -EINVAL;
+			goto out;
+		}
+	}
+
+	/*
+	 * A reasonable upper limit on the max threshold is the number
+	 * of lines tagged per RMID if all RMIDs have the same number of
+	 * lines tagged in the LLC.
+	 *
+	 * For a 35MB LLC and 56 RMIDs, this is ~1.8% of the LLC.
+	 */
+	__intel_cqm_max_threshold =
+		boot_cpu_data.x86_cache_size * 1024 / (cqm_max_rmid + 1);
+
+	snprintf(scale, sizeof(scale), "%u", cqm_l3_scale);
+	str = kstrdup(scale, GFP_KERNEL);
+	if (!str) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	event_attr_intel_cqm_llc_scale.event_str = str;
+
+	ret = intel_cqm_setup_rmid_cache();
+	if (ret)
+		goto out;
+
+	for_each_online_cpu(i) {
+		intel_cqm_cpu_starting(i);
+		cqm_pick_event_reader(i);
+	}
+
+	if (mbm_enabled)
+		ret = intel_mbm_init();
+	if (ret && !cqm_enabled)
+		goto out;
+
+	if (cqm_enabled && mbm_enabled)
+		intel_cqm_events_group.attrs = intel_cmt_mbm_events_attr;
+	else if (!cqm_enabled && mbm_enabled)
+		intel_cqm_events_group.attrs = intel_mbm_events_attr;
+	else if (cqm_enabled && !mbm_enabled)
+		intel_cqm_events_group.attrs = intel_cqm_events_attr;
+
+	ret = perf_pmu_register(&intel_cqm_pmu, "intel_cqm", -1);
+	if (ret) {
+		pr_err("Intel CQM perf registration failed: %d\n", ret);
+		goto out;
+	}
+
+	if (cqm_enabled)
+		pr_info("Intel CQM monitoring enabled\n");
+	if (mbm_enabled)
+		pr_info("Intel MBM enabled\n");
+
+	/*
+	 * Register the hot cpu notifier once we are sure cqm
+	 * is enabled to avoid notifier leak.
+	 */
+	__perf_cpu_notifier(intel_cqm_cpu_notifier);
+out:
+	cpu_notifier_register_done();
+	if (ret) {
+		kfree(str);
+		cqm_cleanup();
+		mbm_cleanup();
+	}
+
+	return ret;
+}
+device_initcall(intel_cqm_init);
--- /dev/null
+++ zfcpdump-kernel-4.4/arch/x86/events/intel/cstate.c
@@ -0,0 +1,694 @@
+/*
+ * perf_event_intel_cstate.c: support cstate residency counters
+ *
+ * Copyright (C) 2015, Intel Corp.
+ * Author: Kan Liang (kan.liang@intel.com)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ */
+
+/*
+ * This file export cstate related free running (read-only) counters
+ * for perf. These counters may be use simultaneously by other tools,
+ * such as turbostat. However, it still make sense to implement them
+ * in perf. Because we can conveniently collect them together with
+ * other events, and allow to use them from tools without special MSR
+ * access code.
+ *
+ * The events only support system-wide mode counting. There is no
+ * sampling support because it is not supported by the hardware.
+ *
+ * According to counters' scope and category, two PMUs are registered
+ * with the perf_event core subsystem.
+ *  - 'cstate_core': The counter is available for each physical core.
+ *    The counters include CORE_C*_RESIDENCY.
+ *  - 'cstate_pkg': The counter is available for each physical package.
+ *    The counters include PKG_C*_RESIDENCY.
+ *
+ * All of these counters are specified in the Intel® 64 and IA-32
+ * Architectures Software Developer.s Manual Vol3b.
+ *
+ * Model specific counters:
+ *	MSR_CORE_C1_RES: CORE C1 Residency Counter
+ *			 perf code: 0x00
+ *			 Available model: SLM,AMT
+ *			 Scope: Core (each processor core has a MSR)
+ *	MSR_CORE_C3_RESIDENCY: CORE C3 Residency Counter
+ *			       perf code: 0x01
+ *			       Available model: NHM,WSM,SNB,IVB,HSW,BDW,SKL
+ *			       Scope: Core
+ *	MSR_CORE_C6_RESIDENCY: CORE C6 Residency Counter
+ *			       perf code: 0x02
+ *			       Available model: SLM,AMT,NHM,WSM,SNB,IVB,HSW,BDW,SKL
+ *			       Scope: Core
+ *	MSR_CORE_C7_RESIDENCY: CORE C7 Residency Counter
+ *			       perf code: 0x03
+ *			       Available model: SNB,IVB,HSW,BDW,SKL
+ *			       Scope: Core
+ *	MSR_PKG_C2_RESIDENCY:  Package C2 Residency Counter.
+ *			       perf code: 0x00
+ *			       Available model: SNB,IVB,HSW,BDW,SKL
+ *			       Scope: Package (physical package)
+ *	MSR_PKG_C3_RESIDENCY:  Package C3 Residency Counter.
+ *			       perf code: 0x01
+ *			       Available model: NHM,WSM,SNB,IVB,HSW,BDW,SKL
+ *			       Scope: Package (physical package)
+ *	MSR_PKG_C6_RESIDENCY:  Package C6 Residency Counter.
+ *			       perf code: 0x02
+ *			       Available model: SLM,AMT,NHM,WSM,SNB,IVB,HSW,BDW,SKL
+ *			       Scope: Package (physical package)
+ *	MSR_PKG_C7_RESIDENCY:  Package C7 Residency Counter.
+ *			       perf code: 0x03
+ *			       Available model: NHM,WSM,SNB,IVB,HSW,BDW,SKL
+ *			       Scope: Package (physical package)
+ *	MSR_PKG_C8_RESIDENCY:  Package C8 Residency Counter.
+ *			       perf code: 0x04
+ *			       Available model: HSW ULT only
+ *			       Scope: Package (physical package)
+ *	MSR_PKG_C9_RESIDENCY:  Package C9 Residency Counter.
+ *			       perf code: 0x05
+ *			       Available model: HSW ULT only
+ *			       Scope: Package (physical package)
+ *	MSR_PKG_C10_RESIDENCY: Package C10 Residency Counter.
+ *			       perf code: 0x06
+ *			       Available model: HSW ULT only
+ *			       Scope: Package (physical package)
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/perf_event.h>
+#include <asm/cpu_device_id.h>
+#include "../perf_event.h"
+
+#define DEFINE_CSTATE_FORMAT_ATTR(_var, _name, _format)		\
+static ssize_t __cstate_##_var##_show(struct kobject *kobj,	\
+				struct kobj_attribute *attr,	\
+				char *page)			\
+{								\
+	BUILD_BUG_ON(sizeof(_format) >= PAGE_SIZE);		\
+	return sprintf(page, _format "\n");			\
+}								\
+static struct kobj_attribute format_attr_##_var =		\
+	__ATTR(_name, 0444, __cstate_##_var##_show, NULL)
+
+static ssize_t cstate_get_attr_cpumask(struct device *dev,
+				       struct device_attribute *attr,
+				       char *buf);
+
+struct perf_cstate_msr {
+	u64	msr;
+	struct	perf_pmu_events_attr *attr;
+	bool	(*test)(int idx);
+};
+
+
+/* cstate_core PMU */
+
+static struct pmu cstate_core_pmu;
+static bool has_cstate_core;
+
+enum perf_cstate_core_id {
+	/*
+	 * cstate_core events
+	 */
+	PERF_CSTATE_CORE_C1_RES = 0,
+	PERF_CSTATE_CORE_C3_RES,
+	PERF_CSTATE_CORE_C6_RES,
+	PERF_CSTATE_CORE_C7_RES,
+
+	PERF_CSTATE_CORE_EVENT_MAX,
+};
+
+bool test_core(int idx)
+{
+	if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL ||
+	    boot_cpu_data.x86 != 6)
+		return false;
+
+	switch (boot_cpu_data.x86_model) {
+	case 30: /* 45nm Nehalem    */
+	case 26: /* 45nm Nehalem-EP */
+	case 46: /* 45nm Nehalem-EX */
+
+	case 37: /* 32nm Westmere    */
+	case 44: /* 32nm Westmere-EP */
+	case 47: /* 32nm Westmere-EX */
+		if (idx == PERF_CSTATE_CORE_C3_RES ||
+		    idx == PERF_CSTATE_CORE_C6_RES)
+			return true;
+		break;
+	case 42: /* 32nm SandyBridge         */
+	case 45: /* 32nm SandyBridge-E/EN/EP */
+
+	case 58: /* 22nm IvyBridge       */
+	case 62: /* 22nm IvyBridge-EP/EX */
+
+	case 60: /* 22nm Haswell Core */
+	case 63: /* 22nm Haswell Server */
+	case 69: /* 22nm Haswell ULT */
+	case 70: /* 22nm Haswell + GT3e (Intel Iris Pro graphics) */
+
+	case 61: /* 14nm Broadwell Core-M */
+	case 86: /* 14nm Broadwell Xeon D */
+	case 71: /* 14nm Broadwell + GT3e (Intel Iris Pro graphics) */
+	case 79: /* 14nm Broadwell Server */
+
+	case 78: /* 14nm Skylake Mobile */
+	case 94: /* 14nm Skylake Desktop */
+		if (idx == PERF_CSTATE_CORE_C3_RES ||
+		    idx == PERF_CSTATE_CORE_C6_RES ||
+		    idx == PERF_CSTATE_CORE_C7_RES)
+			return true;
+		break;
+	case 55: /* 22nm Atom "Silvermont"                */
+	case 77: /* 22nm Atom "Silvermont Avoton/Rangely" */
+	case 76: /* 14nm Atom "Airmont"                   */
+		if (idx == PERF_CSTATE_CORE_C1_RES ||
+		    idx == PERF_CSTATE_CORE_C6_RES)
+			return true;
+		break;
+	}
+
+	return false;
+}
+
+PMU_EVENT_ATTR_STRING(c1-residency, evattr_cstate_core_c1, "event=0x00");
+PMU_EVENT_ATTR_STRING(c3-residency, evattr_cstate_core_c3, "event=0x01");
+PMU_EVENT_ATTR_STRING(c6-residency, evattr_cstate_core_c6, "event=0x02");
+PMU_EVENT_ATTR_STRING(c7-residency, evattr_cstate_core_c7, "event=0x03");
+
+static struct perf_cstate_msr core_msr[] = {
+	[PERF_CSTATE_CORE_C1_RES] = { MSR_CORE_C1_RES,		&evattr_cstate_core_c1,	test_core, },
+	[PERF_CSTATE_CORE_C3_RES] = { MSR_CORE_C3_RESIDENCY,	&evattr_cstate_core_c3, test_core, },
+	[PERF_CSTATE_CORE_C6_RES] = { MSR_CORE_C6_RESIDENCY,	&evattr_cstate_core_c6, test_core, },
+	[PERF_CSTATE_CORE_C7_RES] = { MSR_CORE_C7_RESIDENCY,	&evattr_cstate_core_c7,	test_core, },
+};
+
+static struct attribute *core_events_attrs[PERF_CSTATE_CORE_EVENT_MAX + 1] = {
+	NULL,
+};
+
+static struct attribute_group core_events_attr_group = {
+	.name = "events",
+	.attrs = core_events_attrs,
+};
+
+DEFINE_CSTATE_FORMAT_ATTR(core_event, event, "config:0-63");
+static struct attribute *core_format_attrs[] = {
+	&format_attr_core_event.attr,
+	NULL,
+};
+
+static struct attribute_group core_format_attr_group = {
+	.name = "format",
+	.attrs = core_format_attrs,
+};
+
+static cpumask_t cstate_core_cpu_mask;
+static DEVICE_ATTR(cpumask, S_IRUGO, cstate_get_attr_cpumask, NULL);
+
+static struct attribute *cstate_cpumask_attrs[] = {
+	&dev_attr_cpumask.attr,
+	NULL,
+};
+
+static struct attribute_group cpumask_attr_group = {
+	.attrs = cstate_cpumask_attrs,
+};
+
+static const struct attribute_group *core_attr_groups[] = {
+	&core_events_attr_group,
+	&core_format_attr_group,
+	&cpumask_attr_group,
+	NULL,
+};
+
+/* cstate_core PMU end */
+
+
+/* cstate_pkg PMU */
+
+static struct pmu cstate_pkg_pmu;
+static bool has_cstate_pkg;
+
+enum perf_cstate_pkg_id {
+	/*
+	 * cstate_pkg events
+	 */
+	PERF_CSTATE_PKG_C2_RES = 0,
+	PERF_CSTATE_PKG_C3_RES,
+	PERF_CSTATE_PKG_C6_RES,
+	PERF_CSTATE_PKG_C7_RES,
+	PERF_CSTATE_PKG_C8_RES,
+	PERF_CSTATE_PKG_C9_RES,
+	PERF_CSTATE_PKG_C10_RES,
+
+	PERF_CSTATE_PKG_EVENT_MAX,
+};
+
+bool test_pkg(int idx)
+{
+	if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL ||
+	    boot_cpu_data.x86 != 6)
+		return false;
+
+	switch (boot_cpu_data.x86_model) {
+	case 30: /* 45nm Nehalem    */
+	case 26: /* 45nm Nehalem-EP */
+	case 46: /* 45nm Nehalem-EX */
+
+	case 37: /* 32nm Westmere    */
+	case 44: /* 32nm Westmere-EP */
+	case 47: /* 32nm Westmere-EX */
+		if (idx == PERF_CSTATE_CORE_C3_RES ||
+		    idx == PERF_CSTATE_CORE_C6_RES ||
+		    idx == PERF_CSTATE_CORE_C7_RES)
+			return true;
+		break;
+	case 42: /* 32nm SandyBridge         */
+	case 45: /* 32nm SandyBridge-E/EN/EP */
+
+	case 58: /* 22nm IvyBridge       */
+	case 62: /* 22nm IvyBridge-EP/EX */
+
+	case 60: /* 22nm Haswell Core */
+	case 63: /* 22nm Haswell Server */
+	case 70: /* 22nm Haswell + GT3e (Intel Iris Pro graphics) */
+
+	case 61: /* 14nm Broadwell Core-M */
+	case 86: /* 14nm Broadwell Xeon D */
+	case 71: /* 14nm Broadwell + GT3e (Intel Iris Pro graphics) */
+	case 79: /* 14nm Broadwell Server */
+
+	case 78: /* 14nm Skylake Mobile */
+	case 94: /* 14nm Skylake Desktop */
+		if (idx == PERF_CSTATE_PKG_C2_RES ||
+		    idx == PERF_CSTATE_PKG_C3_RES ||
+		    idx == PERF_CSTATE_PKG_C6_RES ||
+		    idx == PERF_CSTATE_PKG_C7_RES)
+			return true;
+		break;
+	case 55: /* 22nm Atom "Silvermont"                */
+	case 77: /* 22nm Atom "Silvermont Avoton/Rangely" */
+	case 76: /* 14nm Atom "Airmont"                   */
+		if (idx == PERF_CSTATE_CORE_C6_RES)
+			return true;
+		break;
+	case 69: /* 22nm Haswell ULT */
+		if (idx == PERF_CSTATE_PKG_C2_RES ||
+		    idx == PERF_CSTATE_PKG_C3_RES ||
+		    idx == PERF_CSTATE_PKG_C6_RES ||
+		    idx == PERF_CSTATE_PKG_C7_RES ||
+		    idx == PERF_CSTATE_PKG_C8_RES ||
+		    idx == PERF_CSTATE_PKG_C9_RES ||
+		    idx == PERF_CSTATE_PKG_C10_RES)
+			return true;
+		break;
+	}
+
+	return false;
+}
+
+PMU_EVENT_ATTR_STRING(c2-residency, evattr_cstate_pkg_c2, "event=0x00");
+PMU_EVENT_ATTR_STRING(c3-residency, evattr_cstate_pkg_c3, "event=0x01");
+PMU_EVENT_ATTR_STRING(c6-residency, evattr_cstate_pkg_c6, "event=0x02");
+PMU_EVENT_ATTR_STRING(c7-residency, evattr_cstate_pkg_c7, "event=0x03");
+PMU_EVENT_ATTR_STRING(c8-residency, evattr_cstate_pkg_c8, "event=0x04");
+PMU_EVENT_ATTR_STRING(c9-residency, evattr_cstate_pkg_c9, "event=0x05");
+PMU_EVENT_ATTR_STRING(c10-residency, evattr_cstate_pkg_c10, "event=0x06");
+
+static struct perf_cstate_msr pkg_msr[] = {
+	[PERF_CSTATE_PKG_C2_RES] = { MSR_PKG_C2_RESIDENCY,	&evattr_cstate_pkg_c2,	test_pkg, },
+	[PERF_CSTATE_PKG_C3_RES] = { MSR_PKG_C3_RESIDENCY,	&evattr_cstate_pkg_c3,	test_pkg, },
+	[PERF_CSTATE_PKG_C6_RES] = { MSR_PKG_C6_RESIDENCY,	&evattr_cstate_pkg_c6,	test_pkg, },
+	[PERF_CSTATE_PKG_C7_RES] = { MSR_PKG_C7_RESIDENCY,	&evattr_cstate_pkg_c7,	test_pkg, },
+	[PERF_CSTATE_PKG_C8_RES] = { MSR_PKG_C8_RESIDENCY,	&evattr_cstate_pkg_c8,	test_pkg, },
+	[PERF_CSTATE_PKG_C9_RES] = { MSR_PKG_C9_RESIDENCY,	&evattr_cstate_pkg_c9,	test_pkg, },
+	[PERF_CSTATE_PKG_C10_RES] = { MSR_PKG_C10_RESIDENCY,	&evattr_cstate_pkg_c10,	test_pkg, },
+};
+
+static struct attribute *pkg_events_attrs[PERF_CSTATE_PKG_EVENT_MAX + 1] = {
+	NULL,
+};
+
+static struct attribute_group pkg_events_attr_group = {
+	.name = "events",
+	.attrs = pkg_events_attrs,
+};
+
+DEFINE_CSTATE_FORMAT_ATTR(pkg_event, event, "config:0-63");
+static struct attribute *pkg_format_attrs[] = {
+	&format_attr_pkg_event.attr,
+	NULL,
+};
+static struct attribute_group pkg_format_attr_group = {
+	.name = "format",
+	.attrs = pkg_format_attrs,
+};
+
+static cpumask_t cstate_pkg_cpu_mask;
+
+static const struct attribute_group *pkg_attr_groups[] = {
+	&pkg_events_attr_group,
+	&pkg_format_attr_group,
+	&cpumask_attr_group,
+	NULL,
+};
+
+/* cstate_pkg PMU end*/
+
+static ssize_t cstate_get_attr_cpumask(struct device *dev,
+				       struct device_attribute *attr,
+				       char *buf)
+{
+	struct pmu *pmu = dev_get_drvdata(dev);
+
+	if (pmu == &cstate_core_pmu)
+		return cpumap_print_to_pagebuf(true, buf, &cstate_core_cpu_mask);
+	else if (pmu == &cstate_pkg_pmu)
+		return cpumap_print_to_pagebuf(true, buf, &cstate_pkg_cpu_mask);
+	else
+		return 0;
+}
+
+static int cstate_pmu_event_init(struct perf_event *event)
+{
+	u64 cfg = event->attr.config;
+	int ret = 0;
+
+	if (event->attr.type != event->pmu->type)
+		return -ENOENT;
+
+	/* unsupported modes and filters */
+	if (event->attr.exclude_user   ||
+	    event->attr.exclude_kernel ||
+	    event->attr.exclude_hv     ||
+	    event->attr.exclude_idle   ||
+	    event->attr.exclude_host   ||
+	    event->attr.exclude_guest  ||
+	    event->attr.sample_period) /* no sampling */
+		return -EINVAL;
+
+	if (event->pmu == &cstate_core_pmu) {
+		if (cfg >= PERF_CSTATE_CORE_EVENT_MAX)
+			return -EINVAL;
+		if (!core_msr[cfg].attr)
+			return -EINVAL;
+		event->hw.event_base = core_msr[cfg].msr;
+	} else if (event->pmu == &cstate_pkg_pmu) {
+		if (cfg >= PERF_CSTATE_PKG_EVENT_MAX)
+			return -EINVAL;
+		if (!pkg_msr[cfg].attr)
+			return -EINVAL;
+		event->hw.event_base = pkg_msr[cfg].msr;
+	} else
+		return -ENOENT;
+
+	/* must be done before validate_group */
+	event->hw.config = cfg;
+	event->hw.idx = -1;
+
+	return ret;
+}
+
+static inline u64 cstate_pmu_read_counter(struct perf_event *event)
+{
+	u64 val;
+
+	rdmsrl(event->hw.event_base, val);
+	return val;
+}
+
+static void cstate_pmu_event_update(struct perf_event *event)
+{
+	struct hw_perf_event *hwc = &event->hw;
+	u64 prev_raw_count, new_raw_count;
+
+again:
+	prev_raw_count = local64_read(&hwc->prev_count);
+	new_raw_count = cstate_pmu_read_counter(event);
+
+	if (local64_cmpxchg(&hwc->prev_count, prev_raw_count,
+			    new_raw_count) != prev_raw_count)
+		goto again;
+
+	local64_add(new_raw_count - prev_raw_count, &event->count);
+}
+
+static void cstate_pmu_event_start(struct perf_event *event, int mode)
+{
+	local64_set(&event->hw.prev_count, cstate_pmu_read_counter(event));
+}
+
+static void cstate_pmu_event_stop(struct perf_event *event, int mode)
+{
+	cstate_pmu_event_update(event);
+}
+
+static void cstate_pmu_event_del(struct perf_event *event, int mode)
+{
+	cstate_pmu_event_stop(event, PERF_EF_UPDATE);
+}
+
+static int cstate_pmu_event_add(struct perf_event *event, int mode)
+{
+	if (mode & PERF_EF_START)
+		cstate_pmu_event_start(event, mode);
+
+	return 0;
+}
+
+static void cstate_cpu_exit(int cpu)
+{
+	int i, id, target;
+
+	/* cpu exit for cstate core */
+	if (has_cstate_core) {
+		id = topology_core_id(cpu);
+		target = -1;
+
+		for_each_online_cpu(i) {
+			if (i == cpu)
+				continue;
+			if (id == topology_core_id(i)) {
+				target = i;
+				break;
+			}
+		}
+		if (cpumask_test_and_clear_cpu(cpu, &cstate_core_cpu_mask) && target >= 0)
+			cpumask_set_cpu(target, &cstate_core_cpu_mask);
+		WARN_ON(cpumask_empty(&cstate_core_cpu_mask));
+		if (target >= 0)
+			perf_pmu_migrate_context(&cstate_core_pmu, cpu, target);
+	}
+
+	/* cpu exit for cstate pkg */
+	if (has_cstate_pkg) {
+		id = topology_physical_package_id(cpu);
+		target = -1;
+
+		for_each_online_cpu(i) {
+			if (i == cpu)
+				continue;
+			if (id == topology_physical_package_id(i)) {
+				target = i;
+				break;
+			}
+		}
+		if (cpumask_test_and_clear_cpu(cpu, &cstate_pkg_cpu_mask) && target >= 0)
+			cpumask_set_cpu(target, &cstate_pkg_cpu_mask);
+		WARN_ON(cpumask_empty(&cstate_pkg_cpu_mask));
+		if (target >= 0)
+			perf_pmu_migrate_context(&cstate_pkg_pmu, cpu, target);
+	}
+}
+
+static void cstate_cpu_init(int cpu)
+{
+	int i, id;
+
+	/* cpu init for cstate core */
+	if (has_cstate_core) {
+		id = topology_core_id(cpu);
+		for_each_cpu(i, &cstate_core_cpu_mask) {
+			if (id == topology_core_id(i))
+				break;
+		}
+		if (i >= nr_cpu_ids)
+			cpumask_set_cpu(cpu, &cstate_core_cpu_mask);
+	}
+
+	/* cpu init for cstate pkg */
+	if (has_cstate_pkg) {
+		id = topology_physical_package_id(cpu);
+		for_each_cpu(i, &cstate_pkg_cpu_mask) {
+			if (id == topology_physical_package_id(i))
+				break;
+		}
+		if (i >= nr_cpu_ids)
+			cpumask_set_cpu(cpu, &cstate_pkg_cpu_mask);
+	}
+}
+
+static int cstate_cpu_notifier(struct notifier_block *self,
+				  unsigned long action, void *hcpu)
+{
+	unsigned int cpu = (long)hcpu;
+
+	switch (action & ~CPU_TASKS_FROZEN) {
+	case CPU_UP_PREPARE:
+		break;
+	case CPU_STARTING:
+		cstate_cpu_init(cpu);
+		break;
+	case CPU_UP_CANCELED:
+	case CPU_DYING:
+		break;
+	case CPU_ONLINE:
+	case CPU_DEAD:
+		break;
+	case CPU_DOWN_PREPARE:
+		cstate_cpu_exit(cpu);
+		break;
+	default:
+		break;
+	}
+
+	return NOTIFY_OK;
+}
+
+/*
+ * Probe the cstate events and insert the available one into sysfs attrs
+ * Return false if there is no available events.
+ */
+static bool cstate_probe_msr(struct perf_cstate_msr *msr,
+			     struct attribute	**events_attrs,
+			     int max_event_nr)
+{
+	int i, j = 0;
+	u64 val;
+
+	/* Probe the cstate events. */
+	for (i = 0; i < max_event_nr; i++) {
+		if (!msr[i].test(i) || rdmsrl_safe(msr[i].msr, &val))
+			msr[i].attr = NULL;
+	}
+
+	/* List remaining events in the sysfs attrs. */
+	for (i = 0; i < max_event_nr; i++) {
+		if (msr[i].attr)
+			events_attrs[j++] = &msr[i].attr->attr.attr;
+	}
+	events_attrs[j] = NULL;
+
+	return (j > 0) ? true : false;
+}
+
+static int __init cstate_init(void)
+{
+	/* SLM has different MSR for PKG C6 */
+	switch (boot_cpu_data.x86_model) {
+	case 55:
+	case 76:
+	case 77:
+		pkg_msr[PERF_CSTATE_PKG_C6_RES].msr = MSR_PKG_C7_RESIDENCY;
+	}
+
+	if (cstate_probe_msr(core_msr, core_events_attrs, PERF_CSTATE_CORE_EVENT_MAX))
+		has_cstate_core = true;
+
+	if (cstate_probe_msr(pkg_msr, pkg_events_attrs, PERF_CSTATE_PKG_EVENT_MAX))
+		has_cstate_pkg = true;
+
+	return (has_cstate_core || has_cstate_pkg) ? 0 : -ENODEV;
+}
+
+static void __init cstate_cpumask_init(void)
+{
+	int cpu;
+
+	cpu_notifier_register_begin();
+
+	for_each_online_cpu(cpu)
+		cstate_cpu_init(cpu);
+
+	__perf_cpu_notifier(cstate_cpu_notifier);
+
+	cpu_notifier_register_done();
+}
+
+static struct pmu cstate_core_pmu = {
+	.attr_groups	= core_attr_groups,
+	.name		= "cstate_core",
+	.task_ctx_nr	= perf_invalid_context,
+	.event_init	= cstate_pmu_event_init,
+	.add		= cstate_pmu_event_add, /* must have */
+	.del		= cstate_pmu_event_del, /* must have */
+	.start		= cstate_pmu_event_start,
+	.stop		= cstate_pmu_event_stop,
+	.read		= cstate_pmu_event_update,
+	.capabilities	= PERF_PMU_CAP_NO_INTERRUPT,
+};
+
+static struct pmu cstate_pkg_pmu = {
+	.attr_groups	= pkg_attr_groups,
+	.name		= "cstate_pkg",
+	.task_ctx_nr	= perf_invalid_context,
+	.event_init	= cstate_pmu_event_init,
+	.add		= cstate_pmu_event_add, /* must have */
+	.del		= cstate_pmu_event_del, /* must have */
+	.start		= cstate_pmu_event_start,
+	.stop		= cstate_pmu_event_stop,
+	.read		= cstate_pmu_event_update,
+	.capabilities	= PERF_PMU_CAP_NO_INTERRUPT,
+};
+
+static void __init cstate_pmus_register(void)
+{
+	int err;
+
+	if (has_cstate_core) {
+		err = perf_pmu_register(&cstate_core_pmu, cstate_core_pmu.name, -1);
+		if (WARN_ON(err))
+			pr_info("Failed to register PMU %s error %d\n",
+				cstate_core_pmu.name, err);
+	}
+
+	if (has_cstate_pkg) {
+		err = perf_pmu_register(&cstate_pkg_pmu, cstate_pkg_pmu.name, -1);
+		if (WARN_ON(err))
+			pr_info("Failed to register PMU %s error %d\n",
+				cstate_pkg_pmu.name, err);
+	}
+}
+
+static int __init cstate_pmu_init(void)
+{
+	int err;
+
+	if (cpu_has_hypervisor)
+		return -ENODEV;
+
+	err = cstate_init();
+	if (err)
+		return err;
+
+	cstate_cpumask_init();
+
+	cstate_pmus_register();
+
+	return 0;
+}
+
+device_initcall(cstate_pmu_init);
--- /dev/null
+++ zfcpdump-kernel-4.4/arch/x86/events/intel/ds.c
@@ -0,0 +1,1370 @@
+#include <linux/bitops.h>
+#include <linux/types.h>
+#include <linux/slab.h>
+
+#include <asm/perf_event.h>
+#include <asm/insn.h>
+
+#include "../perf_event.h"
+
+/* The size of a BTS record in bytes: */
+#define BTS_RECORD_SIZE		24
+
+#define BTS_BUFFER_SIZE		(PAGE_SIZE << 4)
+#define PEBS_BUFFER_SIZE	(PAGE_SIZE << 4)
+#define PEBS_FIXUP_SIZE		PAGE_SIZE
+
+/*
+ * pebs_record_32 for p4 and core not supported
+
+struct pebs_record_32 {
+	u32 flags, ip;
+	u32 ax, bc, cx, dx;
+	u32 si, di, bp, sp;
+};
+
+ */
+
+union intel_x86_pebs_dse {
+	u64 val;
+	struct {
+		unsigned int ld_dse:4;
+		unsigned int ld_stlb_miss:1;
+		unsigned int ld_locked:1;
+		unsigned int ld_reserved:26;
+	};
+	struct {
+		unsigned int st_l1d_hit:1;
+		unsigned int st_reserved1:3;
+		unsigned int st_stlb_miss:1;
+		unsigned int st_locked:1;
+		unsigned int st_reserved2:26;
+	};
+};
+
+
+/*
+ * Map PEBS Load Latency Data Source encodings to generic
+ * memory data source information
+ */
+#define P(a, b) PERF_MEM_S(a, b)
+#define OP_LH (P(OP, LOAD) | P(LVL, HIT))
+#define SNOOP_NONE_MISS (P(SNOOP, NONE) | P(SNOOP, MISS))
+
+/* Version for Sandy Bridge and later */
+static u64 pebs_data_source[] = {
+	P(OP, LOAD) | P(LVL, MISS) | P(LVL, L3) | P(SNOOP, NA),/* 0x00:ukn L3 */
+	OP_LH | P(LVL, L1)  | P(SNOOP, NONE),	/* 0x01: L1 local */
+	OP_LH | P(LVL, LFB) | P(SNOOP, NONE),	/* 0x02: LFB hit */
+	OP_LH | P(LVL, L2)  | P(SNOOP, NONE),	/* 0x03: L2 hit */
+	OP_LH | P(LVL, L3)  | P(SNOOP, NONE),	/* 0x04: L3 hit */
+	OP_LH | P(LVL, L3)  | P(SNOOP, MISS),	/* 0x05: L3 hit, snoop miss */
+	OP_LH | P(LVL, L3)  | P(SNOOP, HIT),	/* 0x06: L3 hit, snoop hit */
+	OP_LH | P(LVL, L3)  | P(SNOOP, HITM),	/* 0x07: L3 hit, snoop hitm */
+	OP_LH | P(LVL, REM_CCE1) | P(SNOOP, HIT),  /* 0x08: L3 miss snoop hit */
+	OP_LH | P(LVL, REM_CCE1) | P(SNOOP, HITM), /* 0x09: L3 miss snoop hitm*/
+	OP_LH | P(LVL, LOC_RAM)  | P(SNOOP, HIT),  /* 0x0a: L3 miss, shared */
+	OP_LH | P(LVL, REM_RAM1) | P(SNOOP, HIT),  /* 0x0b: L3 miss, shared */
+	OP_LH | P(LVL, LOC_RAM)  | SNOOP_NONE_MISS,/* 0x0c: L3 miss, excl */
+	OP_LH | P(LVL, REM_RAM1) | SNOOP_NONE_MISS,/* 0x0d: L3 miss, excl */
+	OP_LH | P(LVL, IO)  | P(SNOOP, NONE), /* 0x0e: I/O */
+	OP_LH | P(LVL, UNC) | P(SNOOP, NONE), /* 0x0f: uncached */
+};
+
+/* Patch up minor differences in the bits */
+void __init intel_pmu_pebs_data_source_nhm(void)
+{
+	pebs_data_source[0x05] = OP_LH | P(LVL, L3)  | P(SNOOP, HIT);
+	pebs_data_source[0x06] = OP_LH | P(LVL, L3)  | P(SNOOP, HITM);
+	pebs_data_source[0x07] = OP_LH | P(LVL, L3)  | P(SNOOP, HITM);
+}
+
+static u64 precise_store_data(u64 status)
+{
+	union intel_x86_pebs_dse dse;
+	u64 val = P(OP, STORE) | P(SNOOP, NA) | P(LVL, L1) | P(TLB, L2);
+
+	dse.val = status;
+
+	/*
+	 * bit 4: TLB access
+	 * 1 = stored missed 2nd level TLB
+	 *
+	 * so it either hit the walker or the OS
+	 * otherwise hit 2nd level TLB
+	 */
+	if (dse.st_stlb_miss)
+		val |= P(TLB, MISS);
+	else
+		val |= P(TLB, HIT);
+
+	/*
+	 * bit 0: hit L1 data cache
+	 * if not set, then all we know is that
+	 * it missed L1D
+	 */
+	if (dse.st_l1d_hit)
+		val |= P(LVL, HIT);
+	else
+		val |= P(LVL, MISS);
+
+	/*
+	 * bit 5: Locked prefix
+	 */
+	if (dse.st_locked)
+		val |= P(LOCK, LOCKED);
+
+	return val;
+}
+
+static u64 precise_datala_hsw(struct perf_event *event, u64 status)
+{
+	union perf_mem_data_src dse;
+
+	dse.val = PERF_MEM_NA;
+
+	if (event->hw.flags & PERF_X86_EVENT_PEBS_ST_HSW)
+		dse.mem_op = PERF_MEM_OP_STORE;
+	else if (event->hw.flags & PERF_X86_EVENT_PEBS_LD_HSW)
+		dse.mem_op = PERF_MEM_OP_LOAD;
+
+	/*
+	 * L1 info only valid for following events:
+	 *
+	 * MEM_UOPS_RETIRED.STLB_MISS_STORES
+	 * MEM_UOPS_RETIRED.LOCK_STORES
+	 * MEM_UOPS_RETIRED.SPLIT_STORES
+	 * MEM_UOPS_RETIRED.ALL_STORES
+	 */
+	if (event->hw.flags & PERF_X86_EVENT_PEBS_ST_HSW) {
+		if (status & 1)
+			dse.mem_lvl = PERF_MEM_LVL_L1 | PERF_MEM_LVL_HIT;
+		else
+			dse.mem_lvl = PERF_MEM_LVL_L1 | PERF_MEM_LVL_MISS;
+	}
+	return dse.val;
+}
+
+static u64 load_latency_data(u64 status)
+{
+	union intel_x86_pebs_dse dse;
+	u64 val;
+	int model = boot_cpu_data.x86_model;
+	int fam = boot_cpu_data.x86;
+
+	dse.val = status;
+
+	/*
+	 * use the mapping table for bit 0-3
+	 */
+	val = pebs_data_source[dse.ld_dse];
+
+	/*
+	 * Nehalem models do not support TLB, Lock infos
+	 */
+	if (fam == 0x6 && (model == 26 || model == 30
+	    || model == 31 || model == 46)) {
+		val |= P(TLB, NA) | P(LOCK, NA);
+		return val;
+	}
+	/*
+	 * bit 4: TLB access
+	 * 0 = did not miss 2nd level TLB
+	 * 1 = missed 2nd level TLB
+	 */
+	if (dse.ld_stlb_miss)
+		val |= P(TLB, MISS) | P(TLB, L2);
+	else
+		val |= P(TLB, HIT) | P(TLB, L1) | P(TLB, L2);
+
+	/*
+	 * bit 5: locked prefix
+	 */
+	if (dse.ld_locked)
+		val |= P(LOCK, LOCKED);
+
+	return val;
+}
+
+struct pebs_record_core {
+	u64 flags, ip;
+	u64 ax, bx, cx, dx;
+	u64 si, di, bp, sp;
+	u64 r8,  r9,  r10, r11;
+	u64 r12, r13, r14, r15;
+};
+
+struct pebs_record_nhm {
+	u64 flags, ip;
+	u64 ax, bx, cx, dx;
+	u64 si, di, bp, sp;
+	u64 r8,  r9,  r10, r11;
+	u64 r12, r13, r14, r15;
+	u64 status, dla, dse, lat;
+};
+
+/*
+ * Same as pebs_record_nhm, with two additional fields.
+ */
+struct pebs_record_hsw {
+	u64 flags, ip;
+	u64 ax, bx, cx, dx;
+	u64 si, di, bp, sp;
+	u64 r8,  r9,  r10, r11;
+	u64 r12, r13, r14, r15;
+	u64 status, dla, dse, lat;
+	u64 real_ip, tsx_tuning;
+};
+
+union hsw_tsx_tuning {
+	struct {
+		u32 cycles_last_block     : 32,
+		    hle_abort		  : 1,
+		    rtm_abort		  : 1,
+		    instruction_abort     : 1,
+		    non_instruction_abort : 1,
+		    retry		  : 1,
+		    data_conflict	  : 1,
+		    capacity_writes	  : 1,
+		    capacity_reads	  : 1;
+	};
+	u64	    value;
+};
+
+#define PEBS_HSW_TSX_FLAGS	0xff00000000ULL
+
+/* Same as HSW, plus TSC */
+
+struct pebs_record_skl {
+	u64 flags, ip;
+	u64 ax, bx, cx, dx;
+	u64 si, di, bp, sp;
+	u64 r8,  r9,  r10, r11;
+	u64 r12, r13, r14, r15;
+	u64 status, dla, dse, lat;
+	u64 real_ip, tsx_tuning;
+	u64 tsc;
+};
+
+void init_debug_store_on_cpu(int cpu)
+{
+	struct debug_store *ds = per_cpu(cpu_hw_events, cpu).ds;
+
+	if (!ds)
+		return;
+
+	wrmsr_on_cpu(cpu, MSR_IA32_DS_AREA,
+		     (u32)((u64)(unsigned long)ds),
+		     (u32)((u64)(unsigned long)ds >> 32));
+}
+
+void fini_debug_store_on_cpu(int cpu)
+{
+	if (!per_cpu(cpu_hw_events, cpu).ds)
+		return;
+
+	wrmsr_on_cpu(cpu, MSR_IA32_DS_AREA, 0, 0);
+}
+
+static DEFINE_PER_CPU(void *, insn_buffer);
+
+static int alloc_pebs_buffer(int cpu)
+{
+	struct debug_store *ds = per_cpu(cpu_hw_events, cpu).ds;
+	int node = cpu_to_node(cpu);
+	int max;
+	void *buffer, *ibuffer;
+
+	if (!x86_pmu.pebs)
+		return 0;
+
+	buffer = kzalloc_node(x86_pmu.pebs_buffer_size, GFP_KERNEL, node);
+	if (unlikely(!buffer))
+		return -ENOMEM;
+
+	/*
+	 * HSW+ already provides us the eventing ip; no need to allocate this
+	 * buffer then.
+	 */
+	if (x86_pmu.intel_cap.pebs_format < 2) {
+		ibuffer = kzalloc_node(PEBS_FIXUP_SIZE, GFP_KERNEL, node);
+		if (!ibuffer) {
+			kfree(buffer);
+			return -ENOMEM;
+		}
+		per_cpu(insn_buffer, cpu) = ibuffer;
+	}
+
+	max = x86_pmu.pebs_buffer_size / x86_pmu.pebs_record_size;
+
+	ds->pebs_buffer_base = (u64)(unsigned long)buffer;
+	ds->pebs_index = ds->pebs_buffer_base;
+	ds->pebs_absolute_maximum = ds->pebs_buffer_base +
+		max * x86_pmu.pebs_record_size;
+
+	return 0;
+}
+
+static void release_pebs_buffer(int cpu)
+{
+	struct debug_store *ds = per_cpu(cpu_hw_events, cpu).ds;
+
+	if (!ds || !x86_pmu.pebs)
+		return;
+
+	kfree(per_cpu(insn_buffer, cpu));
+	per_cpu(insn_buffer, cpu) = NULL;
+
+	kfree((void *)(unsigned long)ds->pebs_buffer_base);
+	ds->pebs_buffer_base = 0;
+}
+
+static int alloc_bts_buffer(int cpu)
+{
+	struct debug_store *ds = per_cpu(cpu_hw_events, cpu).ds;
+	int node = cpu_to_node(cpu);
+	int max, thresh;
+	void *buffer;
+
+	if (!x86_pmu.bts)
+		return 0;
+
+	buffer = kzalloc_node(BTS_BUFFER_SIZE, GFP_KERNEL | __GFP_NOWARN, node);
+	if (unlikely(!buffer)) {
+		WARN_ONCE(1, "%s: BTS buffer allocation failure\n", __func__);
+		return -ENOMEM;
+	}
+
+	max = BTS_BUFFER_SIZE / BTS_RECORD_SIZE;
+	thresh = max / 16;
+
+	ds->bts_buffer_base = (u64)(unsigned long)buffer;
+	ds->bts_index = ds->bts_buffer_base;
+	ds->bts_absolute_maximum = ds->bts_buffer_base +
+		max * BTS_RECORD_SIZE;
+	ds->bts_interrupt_threshold = ds->bts_absolute_maximum -
+		thresh * BTS_RECORD_SIZE;
+
+	return 0;
+}
+
+static void release_bts_buffer(int cpu)
+{
+	struct debug_store *ds = per_cpu(cpu_hw_events, cpu).ds;
+
+	if (!ds || !x86_pmu.bts)
+		return;
+
+	kfree((void *)(unsigned long)ds->bts_buffer_base);
+	ds->bts_buffer_base = 0;
+}
+
+static int alloc_ds_buffer(int cpu)
+{
+	int node = cpu_to_node(cpu);
+	struct debug_store *ds;
+
+	ds = kzalloc_node(sizeof(*ds), GFP_KERNEL, node);
+	if (unlikely(!ds))
+		return -ENOMEM;
+
+	per_cpu(cpu_hw_events, cpu).ds = ds;
+
+	return 0;
+}
+
+static void release_ds_buffer(int cpu)
+{
+	struct debug_store *ds = per_cpu(cpu_hw_events, cpu).ds;
+
+	if (!ds)
+		return;
+
+	per_cpu(cpu_hw_events, cpu).ds = NULL;
+	kfree(ds);
+}
+
+void release_ds_buffers(void)
+{
+	int cpu;
+
+	if (!x86_pmu.bts && !x86_pmu.pebs)
+		return;
+
+	get_online_cpus();
+	for_each_online_cpu(cpu)
+		fini_debug_store_on_cpu(cpu);
+
+	for_each_possible_cpu(cpu) {
+		release_pebs_buffer(cpu);
+		release_bts_buffer(cpu);
+		release_ds_buffer(cpu);
+	}
+	put_online_cpus();
+}
+
+void reserve_ds_buffers(void)
+{
+	int bts_err = 0, pebs_err = 0;
+	int cpu;
+
+	x86_pmu.bts_active = 0;
+	x86_pmu.pebs_active = 0;
+
+	if (!x86_pmu.bts && !x86_pmu.pebs)
+		return;
+
+	if (!x86_pmu.bts)
+		bts_err = 1;
+
+	if (!x86_pmu.pebs)
+		pebs_err = 1;
+
+	get_online_cpus();
+
+	for_each_possible_cpu(cpu) {
+		if (alloc_ds_buffer(cpu)) {
+			bts_err = 1;
+			pebs_err = 1;
+		}
+
+		if (!bts_err && alloc_bts_buffer(cpu))
+			bts_err = 1;
+
+		if (!pebs_err && alloc_pebs_buffer(cpu))
+			pebs_err = 1;
+
+		if (bts_err && pebs_err)
+			break;
+	}
+
+	if (bts_err) {
+		for_each_possible_cpu(cpu)
+			release_bts_buffer(cpu);
+	}
+
+	if (pebs_err) {
+		for_each_possible_cpu(cpu)
+			release_pebs_buffer(cpu);
+	}
+
+	if (bts_err && pebs_err) {
+		for_each_possible_cpu(cpu)
+			release_ds_buffer(cpu);
+	} else {
+		if (x86_pmu.bts && !bts_err)
+			x86_pmu.bts_active = 1;
+
+		if (x86_pmu.pebs && !pebs_err)
+			x86_pmu.pebs_active = 1;
+
+		for_each_online_cpu(cpu)
+			init_debug_store_on_cpu(cpu);
+	}
+
+	put_online_cpus();
+}
+
+/*
+ * BTS
+ */
+
+struct event_constraint bts_constraint =
+	EVENT_CONSTRAINT(0, 1ULL << INTEL_PMC_IDX_FIXED_BTS, 0);
+
+void intel_pmu_enable_bts(u64 config)
+{
+	unsigned long debugctlmsr;
+
+	debugctlmsr = get_debugctlmsr();
+
+	debugctlmsr |= DEBUGCTLMSR_TR;
+	debugctlmsr |= DEBUGCTLMSR_BTS;
+	if (config & ARCH_PERFMON_EVENTSEL_INT)
+		debugctlmsr |= DEBUGCTLMSR_BTINT;
+
+	if (!(config & ARCH_PERFMON_EVENTSEL_OS))
+		debugctlmsr |= DEBUGCTLMSR_BTS_OFF_OS;
+
+	if (!(config & ARCH_PERFMON_EVENTSEL_USR))
+		debugctlmsr |= DEBUGCTLMSR_BTS_OFF_USR;
+
+	update_debugctlmsr(debugctlmsr);
+}
+
+void intel_pmu_disable_bts(void)
+{
+	struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
+	unsigned long debugctlmsr;
+
+	if (!cpuc->ds)
+		return;
+
+	debugctlmsr = get_debugctlmsr();
+
+	debugctlmsr &=
+		~(DEBUGCTLMSR_TR | DEBUGCTLMSR_BTS | DEBUGCTLMSR_BTINT |
+		  DEBUGCTLMSR_BTS_OFF_OS | DEBUGCTLMSR_BTS_OFF_USR);
+
+	update_debugctlmsr(debugctlmsr);
+}
+
+int intel_pmu_drain_bts_buffer(void)
+{
+	struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
+	struct debug_store *ds = cpuc->ds;
+	struct bts_record {
+		u64	from;
+		u64	to;
+		u64	flags;
+	};
+	struct perf_event *event = cpuc->events[INTEL_PMC_IDX_FIXED_BTS];
+	struct bts_record *at, *base, *top;
+	struct perf_output_handle handle;
+	struct perf_event_header header;
+	struct perf_sample_data data;
+	unsigned long skip = 0;
+	struct pt_regs regs;
+
+	if (!event)
+		return 0;
+
+	if (!x86_pmu.bts_active)
+		return 0;
+
+	base = (struct bts_record *)(unsigned long)ds->bts_buffer_base;
+	top  = (struct bts_record *)(unsigned long)ds->bts_index;
+
+	if (top <= base)
+		return 0;
+
+	memset(&regs, 0, sizeof(regs));
+
+	ds->bts_index = ds->bts_buffer_base;
+
+	perf_sample_data_init(&data, 0, event->hw.last_period);
+
+	/*
+	 * BTS leaks kernel addresses in branches across the cpl boundary,
+	 * such as traps or system calls, so unless the user is asking for
+	 * kernel tracing (and right now it's not possible), we'd need to
+	 * filter them out. But first we need to count how many of those we
+	 * have in the current batch. This is an extra O(n) pass, however,
+	 * it's much faster than the other one especially considering that
+	 * n <= 2560 (BTS_BUFFER_SIZE / BTS_RECORD_SIZE * 15/16; see the
+	 * alloc_bts_buffer()).
+	 */
+	for (at = base; at < top; at++) {
+		/*
+		 * Note that right now *this* BTS code only works if
+		 * attr::exclude_kernel is set, but let's keep this extra
+		 * check here in case that changes.
+		 */
+		if (event->attr.exclude_kernel &&
+		    (kernel_ip(at->from) || kernel_ip(at->to)))
+			skip++;
+	}
+
+	/*
+	 * Prepare a generic sample, i.e. fill in the invariant fields.
+	 * We will overwrite the from and to address before we output
+	 * the sample.
+	 */
+	perf_prepare_sample(&header, &data, event, &regs);
+
+	if (perf_output_begin(&handle, event, header.size *
+			      (top - base - skip)))
+		return 1;
+
+	for (at = base; at < top; at++) {
+		/* Filter out any records that contain kernel addresses. */
+		if (event->attr.exclude_kernel &&
+		    (kernel_ip(at->from) || kernel_ip(at->to)))
+			continue;
+
+		data.ip		= at->from;
+		data.addr	= at->to;
+
+		perf_output_sample(&handle, &header, &data, event);
+	}
+
+	perf_output_end(&handle);
+
+	/* There's new data available. */
+	event->hw.interrupts++;
+	event->pending_kill = POLL_IN;
+	return 1;
+}
+
+static inline void intel_pmu_drain_pebs_buffer(void)
+{
+	struct pt_regs regs;
+
+	x86_pmu.drain_pebs(&regs);
+}
+
+void intel_pmu_pebs_sched_task(struct perf_event_context *ctx, bool sched_in)
+{
+	if (!sched_in)
+		intel_pmu_drain_pebs_buffer();
+}
+
+/*
+ * PEBS
+ */
+struct event_constraint intel_core2_pebs_event_constraints[] = {
+	INTEL_FLAGS_UEVENT_CONSTRAINT(0x00c0, 0x1), /* INST_RETIRED.ANY */
+	INTEL_FLAGS_UEVENT_CONSTRAINT(0xfec1, 0x1), /* X87_OPS_RETIRED.ANY */
+	INTEL_FLAGS_UEVENT_CONSTRAINT(0x00c5, 0x1), /* BR_INST_RETIRED.MISPRED */
+	INTEL_FLAGS_UEVENT_CONSTRAINT(0x1fc7, 0x1), /* SIMD_INST_RETURED.ANY */
+	INTEL_FLAGS_EVENT_CONSTRAINT(0xcb, 0x1),    /* MEM_LOAD_RETIRED.* */
+	/* INST_RETIRED.ANY_P, inv=1, cmask=16 (cycles:p). */
+	INTEL_FLAGS_EVENT_CONSTRAINT(0x108000c0, 0x01),
+	EVENT_CONSTRAINT_END
+};
+
+struct event_constraint intel_atom_pebs_event_constraints[] = {
+	INTEL_FLAGS_UEVENT_CONSTRAINT(0x00c0, 0x1), /* INST_RETIRED.ANY */
+	INTEL_FLAGS_UEVENT_CONSTRAINT(0x00c5, 0x1), /* MISPREDICTED_BRANCH_RETIRED */
+	INTEL_FLAGS_EVENT_CONSTRAINT(0xcb, 0x1),    /* MEM_LOAD_RETIRED.* */
+	/* INST_RETIRED.ANY_P, inv=1, cmask=16 (cycles:p). */
+	INTEL_FLAGS_EVENT_CONSTRAINT(0x108000c0, 0x01),
+	EVENT_CONSTRAINT_END
+};
+
+struct event_constraint intel_slm_pebs_event_constraints[] = {
+	/* INST_RETIRED.ANY_P, inv=1, cmask=16 (cycles:p). */
+	INTEL_FLAGS_EVENT_CONSTRAINT(0x108000c0, 0x1),
+	/* Allow all events as PEBS with no flags */
+	INTEL_ALL_EVENT_CONSTRAINT(0, 0x1),
+	EVENT_CONSTRAINT_END
+};
+
+struct event_constraint intel_nehalem_pebs_event_constraints[] = {
+	INTEL_PLD_CONSTRAINT(0x100b, 0xf),      /* MEM_INST_RETIRED.* */
+	INTEL_FLAGS_EVENT_CONSTRAINT(0x0f, 0xf),    /* MEM_UNCORE_RETIRED.* */
+	INTEL_FLAGS_UEVENT_CONSTRAINT(0x010c, 0xf), /* MEM_STORE_RETIRED.DTLB_MISS */
+	INTEL_FLAGS_EVENT_CONSTRAINT(0xc0, 0xf),    /* INST_RETIRED.ANY */
+	INTEL_EVENT_CONSTRAINT(0xc2, 0xf),    /* UOPS_RETIRED.* */
+	INTEL_FLAGS_EVENT_CONSTRAINT(0xc4, 0xf),    /* BR_INST_RETIRED.* */
+	INTEL_FLAGS_UEVENT_CONSTRAINT(0x02c5, 0xf), /* BR_MISP_RETIRED.NEAR_CALL */
+	INTEL_FLAGS_EVENT_CONSTRAINT(0xc7, 0xf),    /* SSEX_UOPS_RETIRED.* */
+	INTEL_FLAGS_UEVENT_CONSTRAINT(0x20c8, 0xf), /* ITLB_MISS_RETIRED */
+	INTEL_FLAGS_EVENT_CONSTRAINT(0xcb, 0xf),    /* MEM_LOAD_RETIRED.* */
+	INTEL_FLAGS_EVENT_CONSTRAINT(0xf7, 0xf),    /* FP_ASSIST.* */
+	/* INST_RETIRED.ANY_P, inv=1, cmask=16 (cycles:p). */
+	INTEL_FLAGS_EVENT_CONSTRAINT(0x108000c0, 0x0f),
+	EVENT_CONSTRAINT_END
+};
+
+struct event_constraint intel_westmere_pebs_event_constraints[] = {
+	INTEL_PLD_CONSTRAINT(0x100b, 0xf),      /* MEM_INST_RETIRED.* */
+	INTEL_FLAGS_EVENT_CONSTRAINT(0x0f, 0xf),    /* MEM_UNCORE_RETIRED.* */
+	INTEL_FLAGS_UEVENT_CONSTRAINT(0x010c, 0xf), /* MEM_STORE_RETIRED.DTLB_MISS */
+	INTEL_FLAGS_EVENT_CONSTRAINT(0xc0, 0xf),    /* INSTR_RETIRED.* */
+	INTEL_EVENT_CONSTRAINT(0xc2, 0xf),    /* UOPS_RETIRED.* */
+	INTEL_FLAGS_EVENT_CONSTRAINT(0xc4, 0xf),    /* BR_INST_RETIRED.* */
+	INTEL_FLAGS_EVENT_CONSTRAINT(0xc5, 0xf),    /* BR_MISP_RETIRED.* */
+	INTEL_FLAGS_EVENT_CONSTRAINT(0xc7, 0xf),    /* SSEX_UOPS_RETIRED.* */
+	INTEL_FLAGS_UEVENT_CONSTRAINT(0x20c8, 0xf), /* ITLB_MISS_RETIRED */
+	INTEL_FLAGS_EVENT_CONSTRAINT(0xcb, 0xf),    /* MEM_LOAD_RETIRED.* */
+	INTEL_FLAGS_EVENT_CONSTRAINT(0xf7, 0xf),    /* FP_ASSIST.* */
+	/* INST_RETIRED.ANY_P, inv=1, cmask=16 (cycles:p). */
+	INTEL_FLAGS_EVENT_CONSTRAINT(0x108000c0, 0x0f),
+	EVENT_CONSTRAINT_END
+};
+
+struct event_constraint intel_snb_pebs_event_constraints[] = {
+	INTEL_FLAGS_UEVENT_CONSTRAINT(0x01c0, 0x2), /* INST_RETIRED.PRECDIST */
+	INTEL_PLD_CONSTRAINT(0x01cd, 0x8),    /* MEM_TRANS_RETIRED.LAT_ABOVE_THR */
+	INTEL_PST_CONSTRAINT(0x02cd, 0x8),    /* MEM_TRANS_RETIRED.PRECISE_STORES */
+	/* UOPS_RETIRED.ALL, inv=1, cmask=16 (cycles:p). */
+	INTEL_FLAGS_EVENT_CONSTRAINT(0x108001c2, 0xf),
+        INTEL_EXCLEVT_CONSTRAINT(0xd0, 0xf),    /* MEM_UOP_RETIRED.* */
+        INTEL_EXCLEVT_CONSTRAINT(0xd1, 0xf),    /* MEM_LOAD_UOPS_RETIRED.* */
+        INTEL_EXCLEVT_CONSTRAINT(0xd2, 0xf),    /* MEM_LOAD_UOPS_LLC_HIT_RETIRED.* */
+        INTEL_EXCLEVT_CONSTRAINT(0xd3, 0xf),    /* MEM_LOAD_UOPS_LLC_MISS_RETIRED.* */
+	/* Allow all events as PEBS with no flags */
+	INTEL_ALL_EVENT_CONSTRAINT(0, 0xf),
+	EVENT_CONSTRAINT_END
+};
+
+struct event_constraint intel_ivb_pebs_event_constraints[] = {
+        INTEL_FLAGS_UEVENT_CONSTRAINT(0x01c0, 0x2), /* INST_RETIRED.PRECDIST */
+        INTEL_PLD_CONSTRAINT(0x01cd, 0x8),    /* MEM_TRANS_RETIRED.LAT_ABOVE_THR */
+	INTEL_PST_CONSTRAINT(0x02cd, 0x8),    /* MEM_TRANS_RETIRED.PRECISE_STORES */
+	/* UOPS_RETIRED.ALL, inv=1, cmask=16 (cycles:p). */
+	INTEL_FLAGS_EVENT_CONSTRAINT(0x108001c2, 0xf),
+	INTEL_EXCLEVT_CONSTRAINT(0xd0, 0xf),    /* MEM_UOP_RETIRED.* */
+	INTEL_EXCLEVT_CONSTRAINT(0xd1, 0xf),    /* MEM_LOAD_UOPS_RETIRED.* */
+	INTEL_EXCLEVT_CONSTRAINT(0xd2, 0xf),    /* MEM_LOAD_UOPS_LLC_HIT_RETIRED.* */
+	INTEL_EXCLEVT_CONSTRAINT(0xd3, 0xf),    /* MEM_LOAD_UOPS_LLC_MISS_RETIRED.* */
+	/* Allow all events as PEBS with no flags */
+	INTEL_ALL_EVENT_CONSTRAINT(0, 0xf),
+        EVENT_CONSTRAINT_END
+};
+
+struct event_constraint intel_hsw_pebs_event_constraints[] = {
+	INTEL_FLAGS_UEVENT_CONSTRAINT(0x01c0, 0x2), /* INST_RETIRED.PRECDIST */
+	INTEL_PLD_CONSTRAINT(0x01cd, 0xf),    /* MEM_TRANS_RETIRED.* */
+	/* UOPS_RETIRED.ALL, inv=1, cmask=16 (cycles:p). */
+	INTEL_FLAGS_EVENT_CONSTRAINT(0x108001c2, 0xf),
+	INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_NA(0x01c2, 0xf), /* UOPS_RETIRED.ALL */
+	INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_XLD(0x11d0, 0xf), /* MEM_UOPS_RETIRED.STLB_MISS_LOADS */
+	INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_XLD(0x21d0, 0xf), /* MEM_UOPS_RETIRED.LOCK_LOADS */
+	INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_XLD(0x41d0, 0xf), /* MEM_UOPS_RETIRED.SPLIT_LOADS */
+	INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_XLD(0x81d0, 0xf), /* MEM_UOPS_RETIRED.ALL_LOADS */
+	INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_XST(0x12d0, 0xf), /* MEM_UOPS_RETIRED.STLB_MISS_STORES */
+	INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_XST(0x42d0, 0xf), /* MEM_UOPS_RETIRED.SPLIT_STORES */
+	INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_XST(0x82d0, 0xf), /* MEM_UOPS_RETIRED.ALL_STORES */
+	INTEL_FLAGS_EVENT_CONSTRAINT_DATALA_XLD(0xd1, 0xf),    /* MEM_LOAD_UOPS_RETIRED.* */
+	INTEL_FLAGS_EVENT_CONSTRAINT_DATALA_XLD(0xd2, 0xf),    /* MEM_LOAD_UOPS_L3_HIT_RETIRED.* */
+	INTEL_FLAGS_EVENT_CONSTRAINT_DATALA_XLD(0xd3, 0xf),    /* MEM_LOAD_UOPS_L3_MISS_RETIRED.* */
+	/* Allow all events as PEBS with no flags */
+	INTEL_ALL_EVENT_CONSTRAINT(0, 0xf),
+	EVENT_CONSTRAINT_END
+};
+
+struct event_constraint intel_skl_pebs_event_constraints[] = {
+	INTEL_FLAGS_UEVENT_CONSTRAINT(0x1c0, 0x2),	/* INST_RETIRED.PREC_DIST */
+	INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_NA(0x01c2, 0xf), /* UOPS_RETIRED.ALL */
+	/* UOPS_RETIRED.ALL, inv=1, cmask=16 (cycles:p). */
+	INTEL_FLAGS_EVENT_CONSTRAINT(0x108001c2, 0xf),
+	INTEL_PLD_CONSTRAINT(0x1cd, 0xf),		      /* MEM_TRANS_RETIRED.* */
+	INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_LD(0x11d0, 0xf), /* MEM_INST_RETIRED.STLB_MISS_LOADS */
+	INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_ST(0x12d0, 0xf), /* MEM_INST_RETIRED.STLB_MISS_STORES */
+	INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_LD(0x21d0, 0xf), /* MEM_INST_RETIRED.LOCK_LOADS */
+	INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_ST(0x22d0, 0xf), /* MEM_INST_RETIRED.LOCK_STORES */
+	INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_LD(0x41d0, 0xf), /* MEM_INST_RETIRED.SPLIT_LOADS */
+	INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_ST(0x42d0, 0xf), /* MEM_INST_RETIRED.SPLIT_STORES */
+	INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_LD(0x81d0, 0xf), /* MEM_INST_RETIRED.ALL_LOADS */
+	INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_ST(0x82d0, 0xf), /* MEM_INST_RETIRED.ALL_STORES */
+	INTEL_FLAGS_EVENT_CONSTRAINT_DATALA_LD(0xd1, 0xf),    /* MEM_LOAD_RETIRED.* */
+	INTEL_FLAGS_EVENT_CONSTRAINT_DATALA_LD(0xd2, 0xf),    /* MEM_LOAD_L3_HIT_RETIRED.* */
+	INTEL_FLAGS_EVENT_CONSTRAINT_DATALA_LD(0xd3, 0xf),    /* MEM_LOAD_L3_MISS_RETIRED.* */
+	/* Allow all events as PEBS with no flags */
+	INTEL_ALL_EVENT_CONSTRAINT(0, 0xf),
+	EVENT_CONSTRAINT_END
+};
+
+struct event_constraint *intel_pebs_constraints(struct perf_event *event)
+{
+	struct event_constraint *c;
+
+	if (!event->attr.precise_ip)
+		return NULL;
+
+	if (x86_pmu.pebs_constraints) {
+		for_each_event_constraint(c, x86_pmu.pebs_constraints) {
+			if ((event->hw.config & c->cmask) == c->code) {
+				event->hw.flags |= c->flags;
+				return c;
+			}
+		}
+	}
+
+	return &emptyconstraint;
+}
+
+static inline bool pebs_is_enabled(struct cpu_hw_events *cpuc)
+{
+	return (cpuc->pebs_enabled & ((1ULL << MAX_PEBS_EVENTS) - 1));
+}
+
+void intel_pmu_pebs_enable(struct perf_event *event)
+{
+	struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
+	struct hw_perf_event *hwc = &event->hw;
+	struct debug_store *ds = cpuc->ds;
+	bool first_pebs;
+	u64 threshold;
+
+	hwc->config &= ~ARCH_PERFMON_EVENTSEL_INT;
+
+	first_pebs = !pebs_is_enabled(cpuc);
+	cpuc->pebs_enabled |= 1ULL << hwc->idx;
+
+	if (event->hw.flags & PERF_X86_EVENT_PEBS_LDLAT)
+		cpuc->pebs_enabled |= 1ULL << (hwc->idx + 32);
+	else if (event->hw.flags & PERF_X86_EVENT_PEBS_ST)
+		cpuc->pebs_enabled |= 1ULL << 63;
+
+	/*
+	 * When the event is constrained enough we can use a larger
+	 * threshold and run the event with less frequent PMI.
+	 */
+	if (hwc->flags & PERF_X86_EVENT_FREERUNNING) {
+		threshold = ds->pebs_absolute_maximum -
+			x86_pmu.max_pebs_events * x86_pmu.pebs_record_size;
+
+		if (first_pebs)
+			perf_sched_cb_inc(event->ctx->pmu);
+	} else {
+		threshold = ds->pebs_buffer_base + x86_pmu.pebs_record_size;
+
+		/*
+		 * If not all events can use larger buffer,
+		 * roll back to threshold = 1
+		 */
+		if (!first_pebs &&
+		    (ds->pebs_interrupt_threshold > threshold))
+			perf_sched_cb_dec(event->ctx->pmu);
+	}
+
+	/* Use auto-reload if possible to save a MSR write in the PMI */
+	if (hwc->flags & PERF_X86_EVENT_AUTO_RELOAD) {
+		ds->pebs_event_reset[hwc->idx] =
+			(u64)(-hwc->sample_period) & x86_pmu.cntval_mask;
+	}
+
+	if (first_pebs || ds->pebs_interrupt_threshold > threshold)
+		ds->pebs_interrupt_threshold = threshold;
+}
+
+void intel_pmu_pebs_disable(struct perf_event *event)
+{
+	struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
+	struct hw_perf_event *hwc = &event->hw;
+	struct debug_store *ds = cpuc->ds;
+	bool large_pebs = ds->pebs_interrupt_threshold >
+		ds->pebs_buffer_base + x86_pmu.pebs_record_size;
+
+	if (large_pebs)
+		intel_pmu_drain_pebs_buffer();
+
+	cpuc->pebs_enabled &= ~(1ULL << hwc->idx);
+
+	if (event->hw.flags & PERF_X86_EVENT_PEBS_LDLAT)
+		cpuc->pebs_enabled &= ~(1ULL << (hwc->idx + 32));
+	else if (event->hw.flags & PERF_X86_EVENT_PEBS_ST)
+		cpuc->pebs_enabled &= ~(1ULL << 63);
+
+	if (large_pebs && !pebs_is_enabled(cpuc))
+		perf_sched_cb_dec(event->ctx->pmu);
+
+	if (cpuc->enabled)
+		wrmsrl(MSR_IA32_PEBS_ENABLE, cpuc->pebs_enabled);
+
+	hwc->config |= ARCH_PERFMON_EVENTSEL_INT;
+}
+
+void intel_pmu_pebs_enable_all(void)
+{
+	struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
+
+	if (cpuc->pebs_enabled)
+		wrmsrl(MSR_IA32_PEBS_ENABLE, cpuc->pebs_enabled);
+}
+
+void intel_pmu_pebs_disable_all(void)
+{
+	struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
+
+	if (cpuc->pebs_enabled)
+		wrmsrl(MSR_IA32_PEBS_ENABLE, 0);
+}
+
+static int intel_pmu_pebs_fixup_ip(struct pt_regs *regs)
+{
+	struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
+	unsigned long from = cpuc->lbr_entries[0].from;
+	unsigned long old_to, to = cpuc->lbr_entries[0].to;
+	unsigned long ip = regs->ip;
+	int is_64bit = 0;
+	void *kaddr;
+	int size;
+
+	/*
+	 * We don't need to fixup if the PEBS assist is fault like
+	 */
+	if (!x86_pmu.intel_cap.pebs_trap)
+		return 1;
+
+	/*
+	 * No LBR entry, no basic block, no rewinding
+	 */
+	if (!cpuc->lbr_stack.nr || !from || !to)
+		return 0;
+
+	/*
+	 * Basic blocks should never cross user/kernel boundaries
+	 */
+	if (kernel_ip(ip) != kernel_ip(to))
+		return 0;
+
+	/*
+	 * unsigned math, either ip is before the start (impossible) or
+	 * the basic block is larger than 1 page (sanity)
+	 */
+	if ((ip - to) > PEBS_FIXUP_SIZE)
+		return 0;
+
+	/*
+	 * We sampled a branch insn, rewind using the LBR stack
+	 */
+	if (ip == to) {
+		set_linear_ip(regs, from);
+		return 1;
+	}
+
+	size = ip - to;
+	if (!kernel_ip(ip)) {
+		int bytes;
+		u8 *buf = this_cpu_read(insn_buffer);
+
+		/* 'size' must fit our buffer, see above */
+		bytes = copy_from_user_nmi(buf, (void __user *)to, size);
+		if (bytes != 0)
+			return 0;
+
+		kaddr = buf;
+	} else {
+		kaddr = (void *)to;
+	}
+
+	do {
+		struct insn insn;
+
+		old_to = to;
+
+#ifdef CONFIG_X86_64
+		is_64bit = kernel_ip(to) || !test_thread_flag(TIF_IA32);
+#endif
+		insn_init(&insn, kaddr, size, is_64bit);
+		insn_get_length(&insn);
+		/*
+		 * Make sure there was not a problem decoding the
+		 * instruction and getting the length.  This is
+		 * doubly important because we have an infinite
+		 * loop if insn.length=0.
+		 */
+		if (!insn.length)
+			break;
+
+		to += insn.length;
+		kaddr += insn.length;
+		size -= insn.length;
+	} while (to < ip);
+
+	if (to == ip) {
+		set_linear_ip(regs, old_to);
+		return 1;
+	}
+
+	/*
+	 * Even though we decoded the basic block, the instruction stream
+	 * never matched the given IP, either the TO or the IP got corrupted.
+	 */
+	return 0;
+}
+
+static inline u64 intel_hsw_weight(struct pebs_record_skl *pebs)
+{
+	if (pebs->tsx_tuning) {
+		union hsw_tsx_tuning tsx = { .value = pebs->tsx_tuning };
+		return tsx.cycles_last_block;
+	}
+	return 0;
+}
+
+static inline u64 intel_hsw_transaction(struct pebs_record_skl *pebs)
+{
+	u64 txn = (pebs->tsx_tuning & PEBS_HSW_TSX_FLAGS) >> 32;
+
+	/* For RTM XABORTs also log the abort code from AX */
+	if ((txn & PERF_TXN_TRANSACTION) && (pebs->ax & 1))
+		txn |= ((pebs->ax >> 24) & 0xff) << PERF_TXN_ABORT_SHIFT;
+	return txn;
+}
+
+static void setup_pebs_sample_data(struct perf_event *event,
+				   struct pt_regs *iregs, void *__pebs,
+				   struct perf_sample_data *data,
+				   struct pt_regs *regs)
+{
+#define PERF_X86_EVENT_PEBS_HSW_PREC \
+		(PERF_X86_EVENT_PEBS_ST_HSW | \
+		 PERF_X86_EVENT_PEBS_LD_HSW | \
+		 PERF_X86_EVENT_PEBS_NA_HSW)
+	/*
+	 * We cast to the biggest pebs_record but are careful not to
+	 * unconditionally access the 'extra' entries.
+	 */
+	struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
+	struct pebs_record_skl *pebs = __pebs;
+	u64 sample_type;
+	int fll, fst, dsrc;
+	int fl = event->hw.flags;
+
+	if (pebs == NULL)
+		return;
+
+	sample_type = event->attr.sample_type;
+	dsrc = sample_type & PERF_SAMPLE_DATA_SRC;
+
+	fll = fl & PERF_X86_EVENT_PEBS_LDLAT;
+	fst = fl & (PERF_X86_EVENT_PEBS_ST | PERF_X86_EVENT_PEBS_HSW_PREC);
+
+	perf_sample_data_init(data, 0, event->hw.last_period);
+
+	data->period = event->hw.last_period;
+
+	/*
+	 * Use latency for weight (only avail with PEBS-LL)
+	 */
+	if (fll && (sample_type & PERF_SAMPLE_WEIGHT))
+		data->weight = pebs->lat;
+
+	/*
+	 * data.data_src encodes the data source
+	 */
+	if (dsrc) {
+		u64 val = PERF_MEM_NA;
+		if (fll)
+			val = load_latency_data(pebs->dse);
+		else if (fst && (fl & PERF_X86_EVENT_PEBS_HSW_PREC))
+			val = precise_datala_hsw(event, pebs->dse);
+		else if (fst)
+			val = precise_store_data(pebs->dse);
+		data->data_src.val = val;
+	}
+
+	/*
+	 * We use the interrupt regs as a base because the PEBS record
+	 * does not contain a full regs set, specifically it seems to
+	 * lack segment descriptors, which get used by things like
+	 * user_mode().
+	 *
+	 * In the simple case fix up only the IP and BP,SP regs, for
+	 * PERF_SAMPLE_IP and PERF_SAMPLE_CALLCHAIN to function properly.
+	 * A possible PERF_SAMPLE_REGS will have to transfer all regs.
+	 */
+	*regs = *iregs;
+	regs->flags = pebs->flags;
+	set_linear_ip(regs, pebs->ip);
+	regs->bp = pebs->bp;
+	regs->sp = pebs->sp;
+
+	if (sample_type & PERF_SAMPLE_REGS_INTR) {
+		regs->ax = pebs->ax;
+		regs->bx = pebs->bx;
+		regs->cx = pebs->cx;
+		regs->dx = pebs->dx;
+		regs->si = pebs->si;
+		regs->di = pebs->di;
+		regs->bp = pebs->bp;
+		regs->sp = pebs->sp;
+
+		regs->flags = pebs->flags;
+#ifndef CONFIG_X86_32
+		regs->r8 = pebs->r8;
+		regs->r9 = pebs->r9;
+		regs->r10 = pebs->r10;
+		regs->r11 = pebs->r11;
+		regs->r12 = pebs->r12;
+		regs->r13 = pebs->r13;
+		regs->r14 = pebs->r14;
+		regs->r15 = pebs->r15;
+#endif
+	}
+
+	if (event->attr.precise_ip > 1 && x86_pmu.intel_cap.pebs_format >= 2) {
+		regs->ip = pebs->real_ip;
+		regs->flags |= PERF_EFLAGS_EXACT;
+	} else if (event->attr.precise_ip > 1 && intel_pmu_pebs_fixup_ip(regs))
+		regs->flags |= PERF_EFLAGS_EXACT;
+	else
+		regs->flags &= ~PERF_EFLAGS_EXACT;
+
+	if ((sample_type & PERF_SAMPLE_ADDR) &&
+	    x86_pmu.intel_cap.pebs_format >= 1)
+		data->addr = pebs->dla;
+
+	if (x86_pmu.intel_cap.pebs_format >= 2) {
+		/* Only set the TSX weight when no memory weight. */
+		if ((sample_type & PERF_SAMPLE_WEIGHT) && !fll)
+			data->weight = intel_hsw_weight(pebs);
+
+		if (sample_type & PERF_SAMPLE_TRANSACTION)
+			data->txn = intel_hsw_transaction(pebs);
+	}
+
+	/*
+	 * v3 supplies an accurate time stamp, so we use that
+	 * for the time stamp.
+	 *
+	 * We can only do this for the default trace clock.
+	 */
+	if (x86_pmu.intel_cap.pebs_format >= 3 &&
+		event->attr.use_clockid == 0)
+		data->time = native_sched_clock_from_tsc(pebs->tsc);
+
+	if (has_branch_stack(event))
+		data->br_stack = &cpuc->lbr_stack;
+}
+
+static inline void *
+get_next_pebs_record_by_bit(void *base, void *top, int bit)
+{
+	struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
+	void *at;
+	u64 pebs_status;
+
+	/*
+	 * fmt0 does not have a status bitfield (does not use
+	 * perf_record_nhm format)
+	 */
+	if (x86_pmu.intel_cap.pebs_format < 1)
+		return base;
+
+	if (base == NULL)
+		return NULL;
+
+	for (at = base; at < top; at += x86_pmu.pebs_record_size) {
+		struct pebs_record_nhm *p = at;
+
+		if (test_bit(bit, (unsigned long *)&p->status)) {
+			/* PEBS v3 has accurate status bits */
+			if (x86_pmu.intel_cap.pebs_format >= 3)
+				return at;
+
+			if (p->status == (1 << bit))
+				return at;
+
+			/* clear non-PEBS bit and re-check */
+			pebs_status = p->status & cpuc->pebs_enabled;
+			pebs_status &= (1ULL << MAX_PEBS_EVENTS) - 1;
+			if (pebs_status == (1 << bit))
+				return at;
+		}
+	}
+	return NULL;
+}
+
+static void __intel_pmu_pebs_event(struct perf_event *event,
+				   struct pt_regs *iregs,
+				   void *base, void *top,
+				   int bit, int count)
+{
+	struct perf_sample_data data;
+	struct pt_regs regs;
+	void *at = get_next_pebs_record_by_bit(base, top, bit);
+
+	if (!intel_pmu_save_and_restart(event) &&
+	    !(event->hw.flags & PERF_X86_EVENT_AUTO_RELOAD))
+		return;
+
+	while (count > 1) {
+		setup_pebs_sample_data(event, iregs, at, &data, &regs);
+		perf_event_output(event, &data, &regs);
+		at += x86_pmu.pebs_record_size;
+		at = get_next_pebs_record_by_bit(at, top, bit);
+		count--;
+	}
+
+	setup_pebs_sample_data(event, iregs, at, &data, &regs);
+
+	/*
+	 * All but the last records are processed.
+	 * The last one is left to be able to call the overflow handler.
+	 */
+	if (perf_event_overflow(event, &data, &regs)) {
+		x86_pmu_stop(event, 0);
+		return;
+	}
+
+}
+
+static void intel_pmu_drain_pebs_core(struct pt_regs *iregs)
+{
+	struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
+	struct debug_store *ds = cpuc->ds;
+	struct perf_event *event = cpuc->events[0]; /* PMC0 only */
+	struct pebs_record_core *at, *top;
+	int n;
+
+	if (!x86_pmu.pebs_active)
+		return;
+
+	at  = (struct pebs_record_core *)(unsigned long)ds->pebs_buffer_base;
+	top = (struct pebs_record_core *)(unsigned long)ds->pebs_index;
+
+	/*
+	 * Whatever else happens, drain the thing
+	 */
+	ds->pebs_index = ds->pebs_buffer_base;
+
+	if (!test_bit(0, cpuc->active_mask))
+		return;
+
+	WARN_ON_ONCE(!event);
+
+	if (!event->attr.precise_ip)
+		return;
+
+	n = top - at;
+	if (n <= 0)
+		return;
+
+	__intel_pmu_pebs_event(event, iregs, at, top, 0, n);
+}
+
+static void intel_pmu_drain_pebs_nhm(struct pt_regs *iregs)
+{
+	struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
+	struct debug_store *ds = cpuc->ds;
+	struct perf_event *event;
+	void *base, *at, *top;
+	short counts[MAX_PEBS_EVENTS] = {};
+	short error[MAX_PEBS_EVENTS] = {};
+	int bit, i;
+
+	if (!x86_pmu.pebs_active)
+		return;
+
+	base = (struct pebs_record_nhm *)(unsigned long)ds->pebs_buffer_base;
+	top = (struct pebs_record_nhm *)(unsigned long)ds->pebs_index;
+
+	ds->pebs_index = ds->pebs_buffer_base;
+
+	if (unlikely(base >= top))
+		return;
+
+	for (at = base; at < top; at += x86_pmu.pebs_record_size) {
+		struct pebs_record_nhm *p = at;
+		u64 pebs_status;
+
+		/* PEBS v3 has accurate status bits */
+		if (x86_pmu.intel_cap.pebs_format >= 3) {
+			for_each_set_bit(bit, (unsigned long *)&p->status,
+					 MAX_PEBS_EVENTS)
+				counts[bit]++;
+
+			continue;
+		}
+
+		pebs_status = p->status & cpuc->pebs_enabled;
+		pebs_status &= (1ULL << x86_pmu.max_pebs_events) - 1;
+
+		bit = find_first_bit((unsigned long *)&pebs_status,
+					x86_pmu.max_pebs_events);
+		if (WARN(bit >= x86_pmu.max_pebs_events,
+			 "PEBS record without PEBS event! status=%Lx pebs_enabled=%Lx active_mask=%Lx",
+			 (unsigned long long)p->status, (unsigned long long)cpuc->pebs_enabled,
+			 *(unsigned long long *)cpuc->active_mask))
+			continue;
+
+		/*
+		 * The PEBS hardware does not deal well with the situation
+		 * when events happen near to each other and multiple bits
+		 * are set. But it should happen rarely.
+		 *
+		 * If these events include one PEBS and multiple non-PEBS
+		 * events, it doesn't impact PEBS record. The record will
+		 * be handled normally. (slow path)
+		 *
+		 * If these events include two or more PEBS events, the
+		 * records for the events can be collapsed into a single
+		 * one, and it's not possible to reconstruct all events
+		 * that caused the PEBS record. It's called collision.
+		 * If collision happened, the record will be dropped.
+		 */
+		if (p->status != (1ULL << bit)) {
+			for_each_set_bit(i, (unsigned long *)&pebs_status,
+					 x86_pmu.max_pebs_events)
+				error[i]++;
+			continue;
+		}
+
+		counts[bit]++;
+	}
+
+	for (bit = 0; bit < x86_pmu.max_pebs_events; bit++) {
+		if ((counts[bit] == 0) && (error[bit] == 0))
+			continue;
+
+		event = cpuc->events[bit];
+		WARN_ON_ONCE(!event);
+		WARN_ON_ONCE(!event->attr.precise_ip);
+
+		/* log dropped samples number */
+		if (error[bit])
+			perf_log_lost_samples(event, error[bit]);
+
+		if (counts[bit]) {
+			__intel_pmu_pebs_event(event, iregs, base,
+					       top, bit, counts[bit]);
+		}
+	}
+}
+
+/*
+ * BTS, PEBS probe and setup
+ */
+
+void __init intel_ds_init(void)
+{
+	/*
+	 * No support for 32bit formats
+	 */
+	if (!boot_cpu_has(X86_FEATURE_DTES64))
+		return;
+
+	x86_pmu.bts  = boot_cpu_has(X86_FEATURE_BTS);
+	x86_pmu.pebs = boot_cpu_has(X86_FEATURE_PEBS);
+	x86_pmu.pebs_buffer_size = PEBS_BUFFER_SIZE;
+	if (x86_pmu.pebs) {
+		char pebs_type = x86_pmu.intel_cap.pebs_trap ?  '+' : '-';
+		int format = x86_pmu.intel_cap.pebs_format;
+
+		switch (format) {
+		case 0:
+			printk(KERN_CONT "PEBS fmt0%c, ", pebs_type);
+			x86_pmu.pebs_record_size = sizeof(struct pebs_record_core);
+			/*
+			 * Using >PAGE_SIZE buffers makes the WRMSR to
+			 * PERF_GLOBAL_CTRL in intel_pmu_enable_all()
+			 * mysteriously hang on Core2.
+			 *
+			 * As a workaround, we don't do this.
+			 */
+			x86_pmu.pebs_buffer_size = PAGE_SIZE;
+			x86_pmu.drain_pebs = intel_pmu_drain_pebs_core;
+			break;
+
+		case 1:
+			printk(KERN_CONT "PEBS fmt1%c, ", pebs_type);
+			x86_pmu.pebs_record_size = sizeof(struct pebs_record_nhm);
+			x86_pmu.drain_pebs = intel_pmu_drain_pebs_nhm;
+			break;
+
+		case 2:
+			pr_cont("PEBS fmt2%c, ", pebs_type);
+			x86_pmu.pebs_record_size = sizeof(struct pebs_record_hsw);
+			x86_pmu.drain_pebs = intel_pmu_drain_pebs_nhm;
+			break;
+
+		case 3:
+			pr_cont("PEBS fmt3%c, ", pebs_type);
+			x86_pmu.pebs_record_size =
+						sizeof(struct pebs_record_skl);
+			x86_pmu.drain_pebs = intel_pmu_drain_pebs_nhm;
+			x86_pmu.free_running_flags |= PERF_SAMPLE_TIME;
+			break;
+
+		default:
+			printk(KERN_CONT "no PEBS fmt%d%c, ", format, pebs_type);
+			x86_pmu.pebs = 0;
+		}
+	}
+}
+
+void perf_restore_debug_store(void)
+{
+	struct debug_store *ds = __this_cpu_read(cpu_hw_events.ds);
+
+	if (!x86_pmu.bts && !x86_pmu.pebs)
+		return;
+
+	wrmsrl(MSR_IA32_DS_AREA, (unsigned long)ds);
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/arch/x86/events/intel/knc.c
@@ -0,0 +1,321 @@
+/* Driver for Intel Xeon Phi "Knights Corner" PMU */
+
+#include <linux/perf_event.h>
+#include <linux/types.h>
+
+#include <asm/hardirq.h>
+
+#include "../perf_event.h"
+
+static const u64 knc_perfmon_event_map[] =
+{
+  [PERF_COUNT_HW_CPU_CYCLES]		= 0x002a,
+  [PERF_COUNT_HW_INSTRUCTIONS]		= 0x0016,
+  [PERF_COUNT_HW_CACHE_REFERENCES]	= 0x0028,
+  [PERF_COUNT_HW_CACHE_MISSES]		= 0x0029,
+  [PERF_COUNT_HW_BRANCH_INSTRUCTIONS]	= 0x0012,
+  [PERF_COUNT_HW_BRANCH_MISSES]		= 0x002b,
+};
+
+static const u64 __initconst knc_hw_cache_event_ids
+				[PERF_COUNT_HW_CACHE_MAX]
+				[PERF_COUNT_HW_CACHE_OP_MAX]
+				[PERF_COUNT_HW_CACHE_RESULT_MAX] =
+{
+ [ C(L1D) ] = {
+	[ C(OP_READ) ] = {
+		/* On Xeon Phi event "0" is a valid DATA_READ          */
+		/*   (L1 Data Cache Reads) Instruction.                */
+		/* We code this as ARCH_PERFMON_EVENTSEL_INT as this   */
+		/* bit will always be set in x86_pmu_hw_config().      */
+		[ C(RESULT_ACCESS) ] = ARCH_PERFMON_EVENTSEL_INT,
+						/* DATA_READ           */
+		[ C(RESULT_MISS)   ] = 0x0003,	/* DATA_READ_MISS      */
+	},
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = 0x0001,	/* DATA_WRITE          */
+		[ C(RESULT_MISS)   ] = 0x0004,	/* DATA_WRITE_MISS     */
+	},
+	[ C(OP_PREFETCH) ] = {
+		[ C(RESULT_ACCESS) ] = 0x0011,	/* L1_DATA_PF1         */
+		[ C(RESULT_MISS)   ] = 0x001c,	/* L1_DATA_PF1_MISS    */
+	},
+ },
+ [ C(L1I ) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = 0x000c,	/* CODE_READ          */
+		[ C(RESULT_MISS)   ] = 0x000e,	/* CODE_CACHE_MISS    */
+	},
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = -1,
+		[ C(RESULT_MISS)   ] = -1,
+	},
+	[ C(OP_PREFETCH) ] = {
+		[ C(RESULT_ACCESS) ] = 0x0,
+		[ C(RESULT_MISS)   ] = 0x0,
+	},
+ },
+ [ C(LL  ) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = 0,
+		[ C(RESULT_MISS)   ] = 0x10cb,	/* L2_READ_MISS */
+	},
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = 0x10cc,	/* L2_WRITE_HIT */
+		[ C(RESULT_MISS)   ] = 0,
+	},
+	[ C(OP_PREFETCH) ] = {
+		[ C(RESULT_ACCESS) ] = 0x10fc,	/* L2_DATA_PF2      */
+		[ C(RESULT_MISS)   ] = 0x10fe,	/* L2_DATA_PF2_MISS */
+	},
+ },
+ [ C(DTLB) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = ARCH_PERFMON_EVENTSEL_INT,
+						/* DATA_READ */
+						/* see note on L1 OP_READ */
+		[ C(RESULT_MISS)   ] = 0x0002,	/* DATA_PAGE_WALK */
+	},
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = 0x0001,	/* DATA_WRITE */
+		[ C(RESULT_MISS)   ] = 0x0002,	/* DATA_PAGE_WALK */
+	},
+	[ C(OP_PREFETCH) ] = {
+		[ C(RESULT_ACCESS) ] = 0x0,
+		[ C(RESULT_MISS)   ] = 0x0,
+	},
+ },
+ [ C(ITLB) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = 0x000c,	/* CODE_READ */
+		[ C(RESULT_MISS)   ] = 0x000d,	/* CODE_PAGE_WALK */
+	},
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = -1,
+		[ C(RESULT_MISS)   ] = -1,
+	},
+	[ C(OP_PREFETCH) ] = {
+		[ C(RESULT_ACCESS) ] = -1,
+		[ C(RESULT_MISS)   ] = -1,
+	},
+ },
+ [ C(BPU ) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = 0x0012,	/* BRANCHES */
+		[ C(RESULT_MISS)   ] = 0x002b,	/* BRANCHES_MISPREDICTED */
+	},
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = -1,
+		[ C(RESULT_MISS)   ] = -1,
+	},
+	[ C(OP_PREFETCH) ] = {
+		[ C(RESULT_ACCESS) ] = -1,
+		[ C(RESULT_MISS)   ] = -1,
+	},
+ },
+};
+
+
+static u64 knc_pmu_event_map(int hw_event)
+{
+	return knc_perfmon_event_map[hw_event];
+}
+
+static struct event_constraint knc_event_constraints[] =
+{
+	INTEL_EVENT_CONSTRAINT(0xc3, 0x1),	/* HWP_L2HIT */
+	INTEL_EVENT_CONSTRAINT(0xc4, 0x1),	/* HWP_L2MISS */
+	INTEL_EVENT_CONSTRAINT(0xc8, 0x1),	/* L2_READ_HIT_E */
+	INTEL_EVENT_CONSTRAINT(0xc9, 0x1),	/* L2_READ_HIT_M */
+	INTEL_EVENT_CONSTRAINT(0xca, 0x1),	/* L2_READ_HIT_S */
+	INTEL_EVENT_CONSTRAINT(0xcb, 0x1),	/* L2_READ_MISS */
+	INTEL_EVENT_CONSTRAINT(0xcc, 0x1),	/* L2_WRITE_HIT */
+	INTEL_EVENT_CONSTRAINT(0xce, 0x1),	/* L2_STRONGLY_ORDERED_STREAMING_VSTORES_MISS */
+	INTEL_EVENT_CONSTRAINT(0xcf, 0x1),	/* L2_WEAKLY_ORDERED_STREAMING_VSTORE_MISS */
+	INTEL_EVENT_CONSTRAINT(0xd7, 0x1),	/* L2_VICTIM_REQ_WITH_DATA */
+	INTEL_EVENT_CONSTRAINT(0xe3, 0x1),	/* SNP_HITM_BUNIT */
+	INTEL_EVENT_CONSTRAINT(0xe6, 0x1),	/* SNP_HIT_L2 */
+	INTEL_EVENT_CONSTRAINT(0xe7, 0x1),	/* SNP_HITM_L2 */
+	INTEL_EVENT_CONSTRAINT(0xf1, 0x1),	/* L2_DATA_READ_MISS_CACHE_FILL */
+	INTEL_EVENT_CONSTRAINT(0xf2, 0x1),	/* L2_DATA_WRITE_MISS_CACHE_FILL */
+	INTEL_EVENT_CONSTRAINT(0xf6, 0x1),	/* L2_DATA_READ_MISS_MEM_FILL */
+	INTEL_EVENT_CONSTRAINT(0xf7, 0x1),	/* L2_DATA_WRITE_MISS_MEM_FILL */
+	INTEL_EVENT_CONSTRAINT(0xfc, 0x1),	/* L2_DATA_PF2 */
+	INTEL_EVENT_CONSTRAINT(0xfd, 0x1),	/* L2_DATA_PF2_DROP */
+	INTEL_EVENT_CONSTRAINT(0xfe, 0x1),	/* L2_DATA_PF2_MISS */
+	INTEL_EVENT_CONSTRAINT(0xff, 0x1),	/* L2_DATA_HIT_INFLIGHT_PF2 */
+	EVENT_CONSTRAINT_END
+};
+
+#define MSR_KNC_IA32_PERF_GLOBAL_STATUS		0x0000002d
+#define MSR_KNC_IA32_PERF_GLOBAL_OVF_CONTROL	0x0000002e
+#define MSR_KNC_IA32_PERF_GLOBAL_CTRL		0x0000002f
+
+#define KNC_ENABLE_COUNTER0			0x00000001
+#define KNC_ENABLE_COUNTER1			0x00000002
+
+static void knc_pmu_disable_all(void)
+{
+	u64 val;
+
+	rdmsrl(MSR_KNC_IA32_PERF_GLOBAL_CTRL, val);
+	val &= ~(KNC_ENABLE_COUNTER0|KNC_ENABLE_COUNTER1);
+	wrmsrl(MSR_KNC_IA32_PERF_GLOBAL_CTRL, val);
+}
+
+static void knc_pmu_enable_all(int added)
+{
+	u64 val;
+
+	rdmsrl(MSR_KNC_IA32_PERF_GLOBAL_CTRL, val);
+	val |= (KNC_ENABLE_COUNTER0|KNC_ENABLE_COUNTER1);
+	wrmsrl(MSR_KNC_IA32_PERF_GLOBAL_CTRL, val);
+}
+
+static inline void
+knc_pmu_disable_event(struct perf_event *event)
+{
+	struct hw_perf_event *hwc = &event->hw;
+	u64 val;
+
+	val = hwc->config;
+	val &= ~ARCH_PERFMON_EVENTSEL_ENABLE;
+
+	(void)wrmsrl_safe(hwc->config_base + hwc->idx, val);
+}
+
+static void knc_pmu_enable_event(struct perf_event *event)
+{
+	struct hw_perf_event *hwc = &event->hw;
+	u64 val;
+
+	val = hwc->config;
+	val |= ARCH_PERFMON_EVENTSEL_ENABLE;
+
+	(void)wrmsrl_safe(hwc->config_base + hwc->idx, val);
+}
+
+static inline u64 knc_pmu_get_status(void)
+{
+	u64 status;
+
+	rdmsrl(MSR_KNC_IA32_PERF_GLOBAL_STATUS, status);
+
+	return status;
+}
+
+static inline void knc_pmu_ack_status(u64 ack)
+{
+	wrmsrl(MSR_KNC_IA32_PERF_GLOBAL_OVF_CONTROL, ack);
+}
+
+static int knc_pmu_handle_irq(struct pt_regs *regs)
+{
+	struct perf_sample_data data;
+	struct cpu_hw_events *cpuc;
+	int handled = 0;
+	int bit, loops;
+	u64 status;
+
+	cpuc = this_cpu_ptr(&cpu_hw_events);
+
+	knc_pmu_disable_all();
+
+	status = knc_pmu_get_status();
+	if (!status) {
+		knc_pmu_enable_all(0);
+		return handled;
+	}
+
+	loops = 0;
+again:
+	knc_pmu_ack_status(status);
+	if (++loops > 100) {
+		WARN_ONCE(1, "perf: irq loop stuck!\n");
+		perf_event_print_debug();
+		goto done;
+	}
+
+	inc_irq_stat(apic_perf_irqs);
+
+	for_each_set_bit(bit, (unsigned long *)&status, X86_PMC_IDX_MAX) {
+		struct perf_event *event = cpuc->events[bit];
+
+		handled++;
+
+		if (!test_bit(bit, cpuc->active_mask))
+			continue;
+
+		if (!intel_pmu_save_and_restart(event))
+			continue;
+
+		perf_sample_data_init(&data, 0, event->hw.last_period);
+
+		if (perf_event_overflow(event, &data, regs))
+			x86_pmu_stop(event, 0);
+	}
+
+	/*
+	 * Repeat if there is more work to be done:
+	 */
+	status = knc_pmu_get_status();
+	if (status)
+		goto again;
+
+done:
+	/* Only restore PMU state when it's active. See x86_pmu_disable(). */
+	if (cpuc->enabled)
+		knc_pmu_enable_all(0);
+
+	return handled;
+}
+
+
+PMU_FORMAT_ATTR(event,	"config:0-7"	);
+PMU_FORMAT_ATTR(umask,	"config:8-15"	);
+PMU_FORMAT_ATTR(edge,	"config:18"	);
+PMU_FORMAT_ATTR(inv,	"config:23"	);
+PMU_FORMAT_ATTR(cmask,	"config:24-31"	);
+
+static struct attribute *intel_knc_formats_attr[] = {
+	&format_attr_event.attr,
+	&format_attr_umask.attr,
+	&format_attr_edge.attr,
+	&format_attr_inv.attr,
+	&format_attr_cmask.attr,
+	NULL,
+};
+
+static const struct x86_pmu knc_pmu __initconst = {
+	.name			= "knc",
+	.handle_irq		= knc_pmu_handle_irq,
+	.disable_all		= knc_pmu_disable_all,
+	.enable_all		= knc_pmu_enable_all,
+	.enable			= knc_pmu_enable_event,
+	.disable		= knc_pmu_disable_event,
+	.hw_config		= x86_pmu_hw_config,
+	.schedule_events	= x86_schedule_events,
+	.eventsel		= MSR_KNC_EVNTSEL0,
+	.perfctr		= MSR_KNC_PERFCTR0,
+	.event_map		= knc_pmu_event_map,
+	.max_events             = ARRAY_SIZE(knc_perfmon_event_map),
+	.apic			= 1,
+	.max_period		= (1ULL << 39) - 1,
+	.version		= 0,
+	.num_counters		= 2,
+	.cntval_bits		= 40,
+	.cntval_mask		= (1ULL << 40) - 1,
+	.get_event_constraints	= x86_get_event_constraints,
+	.event_constraints	= knc_event_constraints,
+	.format_attrs		= intel_knc_formats_attr,
+};
+
+__init int knc_pmu_init(void)
+{
+	x86_pmu = knc_pmu;
+
+	memcpy(hw_cache_event_ids, knc_hw_cache_event_ids, 
+		sizeof(hw_cache_event_ids));
+
+	return 0;
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/arch/x86/events/intel/lbr.c
@@ -0,0 +1,1044 @@
+#include <linux/perf_event.h>
+#include <linux/types.h>
+
+#include <asm/perf_event.h>
+#include <asm/msr.h>
+#include <asm/insn.h>
+
+#include "../perf_event.h"
+
+enum {
+	LBR_FORMAT_32		= 0x00,
+	LBR_FORMAT_LIP		= 0x01,
+	LBR_FORMAT_EIP		= 0x02,
+	LBR_FORMAT_EIP_FLAGS	= 0x03,
+	LBR_FORMAT_EIP_FLAGS2	= 0x04,
+	LBR_FORMAT_INFO		= 0x05,
+	LBR_FORMAT_MAX_KNOWN    = LBR_FORMAT_INFO,
+};
+
+static enum {
+	LBR_EIP_FLAGS		= 1,
+	LBR_TSX			= 2,
+} lbr_desc[LBR_FORMAT_MAX_KNOWN + 1] = {
+	[LBR_FORMAT_EIP_FLAGS]  = LBR_EIP_FLAGS,
+	[LBR_FORMAT_EIP_FLAGS2] = LBR_EIP_FLAGS | LBR_TSX,
+};
+
+/*
+ * Intel LBR_SELECT bits
+ * Intel Vol3a, April 2011, Section 16.7 Table 16-10
+ *
+ * Hardware branch filter (not available on all CPUs)
+ */
+#define LBR_KERNEL_BIT		0 /* do not capture at ring0 */
+#define LBR_USER_BIT		1 /* do not capture at ring > 0 */
+#define LBR_JCC_BIT		2 /* do not capture conditional branches */
+#define LBR_REL_CALL_BIT	3 /* do not capture relative calls */
+#define LBR_IND_CALL_BIT	4 /* do not capture indirect calls */
+#define LBR_RETURN_BIT		5 /* do not capture near returns */
+#define LBR_IND_JMP_BIT		6 /* do not capture indirect jumps */
+#define LBR_REL_JMP_BIT		7 /* do not capture relative jumps */
+#define LBR_FAR_BIT		8 /* do not capture far branches */
+#define LBR_CALL_STACK_BIT	9 /* enable call stack */
+
+#define LBR_KERNEL	(1 << LBR_KERNEL_BIT)
+#define LBR_USER	(1 << LBR_USER_BIT)
+#define LBR_JCC		(1 << LBR_JCC_BIT)
+#define LBR_REL_CALL	(1 << LBR_REL_CALL_BIT)
+#define LBR_IND_CALL	(1 << LBR_IND_CALL_BIT)
+#define LBR_RETURN	(1 << LBR_RETURN_BIT)
+#define LBR_REL_JMP	(1 << LBR_REL_JMP_BIT)
+#define LBR_IND_JMP	(1 << LBR_IND_JMP_BIT)
+#define LBR_FAR		(1 << LBR_FAR_BIT)
+#define LBR_CALL_STACK	(1 << LBR_CALL_STACK_BIT)
+
+#define LBR_PLM (LBR_KERNEL | LBR_USER)
+
+#define LBR_SEL_MASK	0x1ff	/* valid bits in LBR_SELECT */
+#define LBR_NOT_SUPP	-1	/* LBR filter not supported */
+#define LBR_IGN		0	/* ignored */
+
+#define LBR_ANY		 \
+	(LBR_JCC	|\
+	 LBR_REL_CALL	|\
+	 LBR_IND_CALL	|\
+	 LBR_RETURN	|\
+	 LBR_REL_JMP	|\
+	 LBR_IND_JMP	|\
+	 LBR_FAR)
+
+#define LBR_FROM_FLAG_MISPRED  (1ULL << 63)
+#define LBR_FROM_FLAG_IN_TX    (1ULL << 62)
+#define LBR_FROM_FLAG_ABORT    (1ULL << 61)
+
+/*
+ * x86control flow change classification
+ * x86control flow changes include branches, interrupts, traps, faults
+ */
+enum {
+	X86_BR_NONE		= 0,      /* unknown */
+
+	X86_BR_USER		= 1 << 0, /* branch target is user */
+	X86_BR_KERNEL		= 1 << 1, /* branch target is kernel */
+
+	X86_BR_CALL		= 1 << 2, /* call */
+	X86_BR_RET		= 1 << 3, /* return */
+	X86_BR_SYSCALL		= 1 << 4, /* syscall */
+	X86_BR_SYSRET		= 1 << 5, /* syscall return */
+	X86_BR_INT		= 1 << 6, /* sw interrupt */
+	X86_BR_IRET		= 1 << 7, /* return from interrupt */
+	X86_BR_JCC		= 1 << 8, /* conditional */
+	X86_BR_JMP		= 1 << 9, /* jump */
+	X86_BR_IRQ		= 1 << 10,/* hw interrupt or trap or fault */
+	X86_BR_IND_CALL		= 1 << 11,/* indirect calls */
+	X86_BR_ABORT		= 1 << 12,/* transaction abort */
+	X86_BR_IN_TX		= 1 << 13,/* in transaction */
+	X86_BR_NO_TX		= 1 << 14,/* not in transaction */
+	X86_BR_ZERO_CALL	= 1 << 15,/* zero length call */
+	X86_BR_CALL_STACK	= 1 << 16,/* call stack */
+	X86_BR_IND_JMP		= 1 << 17,/* indirect jump */
+};
+
+#define X86_BR_PLM (X86_BR_USER | X86_BR_KERNEL)
+#define X86_BR_ANYTX (X86_BR_NO_TX | X86_BR_IN_TX)
+
+#define X86_BR_ANY       \
+	(X86_BR_CALL    |\
+	 X86_BR_RET     |\
+	 X86_BR_SYSCALL |\
+	 X86_BR_SYSRET  |\
+	 X86_BR_INT     |\
+	 X86_BR_IRET    |\
+	 X86_BR_JCC     |\
+	 X86_BR_JMP	 |\
+	 X86_BR_IRQ	 |\
+	 X86_BR_ABORT	 |\
+	 X86_BR_IND_CALL |\
+	 X86_BR_IND_JMP  |\
+	 X86_BR_ZERO_CALL)
+
+#define X86_BR_ALL (X86_BR_PLM | X86_BR_ANY)
+
+#define X86_BR_ANY_CALL		 \
+	(X86_BR_CALL		|\
+	 X86_BR_IND_CALL	|\
+	 X86_BR_ZERO_CALL	|\
+	 X86_BR_SYSCALL		|\
+	 X86_BR_IRQ		|\
+	 X86_BR_INT)
+
+static void intel_pmu_lbr_filter(struct cpu_hw_events *cpuc);
+
+/*
+ * We only support LBR implementations that have FREEZE_LBRS_ON_PMI
+ * otherwise it becomes near impossible to get a reliable stack.
+ */
+
+static void __intel_pmu_lbr_enable(bool pmi)
+{
+	struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
+	u64 debugctl, lbr_select = 0, orig_debugctl;
+
+	/*
+	 * No need to unfreeze manually, as v4 can do that as part
+	 * of the GLOBAL_STATUS ack.
+	 */
+	if (pmi && x86_pmu.version >= 4)
+		return;
+
+	/*
+	 * No need to reprogram LBR_SELECT in a PMI, as it
+	 * did not change.
+	 */
+	if (cpuc->lbr_sel)
+		lbr_select = cpuc->lbr_sel->config;
+	if (!pmi)
+		wrmsrl(MSR_LBR_SELECT, lbr_select);
+
+	rdmsrl(MSR_IA32_DEBUGCTLMSR, debugctl);
+	orig_debugctl = debugctl;
+	debugctl |= DEBUGCTLMSR_LBR;
+	/*
+	 * LBR callstack does not work well with FREEZE_LBRS_ON_PMI.
+	 * If FREEZE_LBRS_ON_PMI is set, PMI near call/return instructions
+	 * may cause superfluous increase/decrease of LBR_TOS.
+	 */
+	if (!(lbr_select & LBR_CALL_STACK))
+		debugctl |= DEBUGCTLMSR_FREEZE_LBRS_ON_PMI;
+	if (orig_debugctl != debugctl)
+		wrmsrl(MSR_IA32_DEBUGCTLMSR, debugctl);
+}
+
+static void __intel_pmu_lbr_disable(void)
+{
+	u64 debugctl;
+
+	rdmsrl(MSR_IA32_DEBUGCTLMSR, debugctl);
+	debugctl &= ~(DEBUGCTLMSR_LBR | DEBUGCTLMSR_FREEZE_LBRS_ON_PMI);
+	wrmsrl(MSR_IA32_DEBUGCTLMSR, debugctl);
+}
+
+static void intel_pmu_lbr_reset_32(void)
+{
+	int i;
+
+	for (i = 0; i < x86_pmu.lbr_nr; i++)
+		wrmsrl(x86_pmu.lbr_from + i, 0);
+}
+
+static void intel_pmu_lbr_reset_64(void)
+{
+	int i;
+
+	for (i = 0; i < x86_pmu.lbr_nr; i++) {
+		wrmsrl(x86_pmu.lbr_from + i, 0);
+		wrmsrl(x86_pmu.lbr_to   + i, 0);
+		if (x86_pmu.intel_cap.lbr_format == LBR_FORMAT_INFO)
+			wrmsrl(MSR_LBR_INFO_0 + i, 0);
+	}
+}
+
+void intel_pmu_lbr_reset(void)
+{
+	if (!x86_pmu.lbr_nr)
+		return;
+
+	if (x86_pmu.intel_cap.lbr_format == LBR_FORMAT_32)
+		intel_pmu_lbr_reset_32();
+	else
+		intel_pmu_lbr_reset_64();
+}
+
+/*
+ * TOS = most recently recorded branch
+ */
+static inline u64 intel_pmu_lbr_tos(void)
+{
+	u64 tos;
+
+	rdmsrl(x86_pmu.lbr_tos, tos);
+	return tos;
+}
+
+enum {
+	LBR_NONE,
+	LBR_VALID,
+};
+
+static void __intel_pmu_lbr_restore(struct x86_perf_task_context *task_ctx)
+{
+	int i;
+	unsigned lbr_idx, mask;
+	u64 tos;
+
+	if (task_ctx->lbr_callstack_users == 0 ||
+	    task_ctx->lbr_stack_state == LBR_NONE) {
+		intel_pmu_lbr_reset();
+		return;
+	}
+
+	mask = x86_pmu.lbr_nr - 1;
+	tos = task_ctx->tos;
+	for (i = 0; i < tos; i++) {
+		lbr_idx = (tos - i) & mask;
+		wrmsrl(x86_pmu.lbr_from + lbr_idx, task_ctx->lbr_from[i]);
+		wrmsrl(x86_pmu.lbr_to + lbr_idx, task_ctx->lbr_to[i]);
+		if (x86_pmu.intel_cap.lbr_format == LBR_FORMAT_INFO)
+			wrmsrl(MSR_LBR_INFO_0 + lbr_idx, task_ctx->lbr_info[i]);
+	}
+	wrmsrl(x86_pmu.lbr_tos, tos);
+	task_ctx->lbr_stack_state = LBR_NONE;
+}
+
+static void __intel_pmu_lbr_save(struct x86_perf_task_context *task_ctx)
+{
+	int i;
+	unsigned lbr_idx, mask;
+	u64 tos;
+
+	if (task_ctx->lbr_callstack_users == 0) {
+		task_ctx->lbr_stack_state = LBR_NONE;
+		return;
+	}
+
+	mask = x86_pmu.lbr_nr - 1;
+	tos = intel_pmu_lbr_tos();
+	for (i = 0; i < tos; i++) {
+		lbr_idx = (tos - i) & mask;
+		rdmsrl(x86_pmu.lbr_from + lbr_idx, task_ctx->lbr_from[i]);
+		rdmsrl(x86_pmu.lbr_to + lbr_idx, task_ctx->lbr_to[i]);
+		if (x86_pmu.intel_cap.lbr_format == LBR_FORMAT_INFO)
+			rdmsrl(MSR_LBR_INFO_0 + lbr_idx, task_ctx->lbr_info[i]);
+	}
+	task_ctx->tos = tos;
+	task_ctx->lbr_stack_state = LBR_VALID;
+}
+
+void intel_pmu_lbr_sched_task(struct perf_event_context *ctx, bool sched_in)
+{
+	struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
+	struct x86_perf_task_context *task_ctx;
+
+	/*
+	 * If LBR callstack feature is enabled and the stack was saved when
+	 * the task was scheduled out, restore the stack. Otherwise flush
+	 * the LBR stack.
+	 */
+	task_ctx = ctx ? ctx->task_ctx_data : NULL;
+	if (task_ctx) {
+		if (sched_in) {
+			__intel_pmu_lbr_restore(task_ctx);
+			cpuc->lbr_context = ctx;
+		} else {
+			__intel_pmu_lbr_save(task_ctx);
+		}
+		return;
+	}
+
+	/*
+	 * When sampling the branck stack in system-wide, it may be
+	 * necessary to flush the stack on context switch. This happens
+	 * when the branch stack does not tag its entries with the pid
+	 * of the current task. Otherwise it becomes impossible to
+	 * associate a branch entry with a task. This ambiguity is more
+	 * likely to appear when the branch stack supports priv level
+	 * filtering and the user sets it to monitor only at the user
+	 * level (which could be a useful measurement in system-wide
+	 * mode). In that case, the risk is high of having a branch
+	 * stack with branch from multiple tasks.
+ 	 */
+	if (sched_in) {
+		intel_pmu_lbr_reset();
+		cpuc->lbr_context = ctx;
+	}
+}
+
+static inline bool branch_user_callstack(unsigned br_sel)
+{
+	return (br_sel & X86_BR_USER) && (br_sel & X86_BR_CALL_STACK);
+}
+
+void intel_pmu_lbr_enable(struct perf_event *event)
+{
+	struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
+	struct x86_perf_task_context *task_ctx;
+
+	if (!x86_pmu.lbr_nr)
+		return;
+
+	/*
+	 * Reset the LBR stack if we changed task context to
+	 * avoid data leaks.
+	 */
+	if (event->ctx->task && cpuc->lbr_context != event->ctx) {
+		intel_pmu_lbr_reset();
+		cpuc->lbr_context = event->ctx;
+	}
+	cpuc->br_sel = event->hw.branch_reg.reg;
+
+	if (branch_user_callstack(cpuc->br_sel) && event->ctx &&
+					event->ctx->task_ctx_data) {
+		task_ctx = event->ctx->task_ctx_data;
+		task_ctx->lbr_callstack_users++;
+	}
+
+	cpuc->lbr_users++;
+	perf_sched_cb_inc(event->ctx->pmu);
+}
+
+void intel_pmu_lbr_disable(struct perf_event *event)
+{
+	struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
+	struct x86_perf_task_context *task_ctx;
+
+	if (!x86_pmu.lbr_nr)
+		return;
+
+	if (branch_user_callstack(cpuc->br_sel) && event->ctx &&
+					event->ctx->task_ctx_data) {
+		task_ctx = event->ctx->task_ctx_data;
+		task_ctx->lbr_callstack_users--;
+	}
+
+	cpuc->lbr_users--;
+	WARN_ON_ONCE(cpuc->lbr_users < 0);
+	perf_sched_cb_dec(event->ctx->pmu);
+
+	if (cpuc->enabled && !cpuc->lbr_users) {
+		__intel_pmu_lbr_disable();
+		/* avoid stale pointer */
+		cpuc->lbr_context = NULL;
+	}
+}
+
+void intel_pmu_lbr_enable_all(bool pmi)
+{
+	struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
+
+	if (cpuc->lbr_users)
+		__intel_pmu_lbr_enable(pmi);
+}
+
+void intel_pmu_lbr_disable_all(void)
+{
+	struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
+
+	if (cpuc->lbr_users)
+		__intel_pmu_lbr_disable();
+}
+
+static void intel_pmu_lbr_read_32(struct cpu_hw_events *cpuc)
+{
+	unsigned long mask = x86_pmu.lbr_nr - 1;
+	u64 tos = intel_pmu_lbr_tos();
+	int i;
+
+	for (i = 0; i < x86_pmu.lbr_nr; i++) {
+		unsigned long lbr_idx = (tos - i) & mask;
+		union {
+			struct {
+				u32 from;
+				u32 to;
+			};
+			u64     lbr;
+		} msr_lastbranch;
+
+		rdmsrl(x86_pmu.lbr_from + lbr_idx, msr_lastbranch.lbr);
+
+		cpuc->lbr_entries[i].from	= msr_lastbranch.from;
+		cpuc->lbr_entries[i].to		= msr_lastbranch.to;
+		cpuc->lbr_entries[i].mispred	= 0;
+		cpuc->lbr_entries[i].predicted	= 0;
+		cpuc->lbr_entries[i].reserved	= 0;
+	}
+	cpuc->lbr_stack.nr = i;
+}
+
+/*
+ * Due to lack of segmentation in Linux the effective address (offset)
+ * is the same as the linear address, allowing us to merge the LIP and EIP
+ * LBR formats.
+ */
+static void intel_pmu_lbr_read_64(struct cpu_hw_events *cpuc)
+{
+	unsigned long mask = x86_pmu.lbr_nr - 1;
+	int lbr_format = x86_pmu.intel_cap.lbr_format;
+	u64 tos = intel_pmu_lbr_tos();
+	int i;
+	int out = 0;
+	int num = x86_pmu.lbr_nr;
+
+	if (cpuc->lbr_sel->config & LBR_CALL_STACK)
+		num = tos;
+
+	for (i = 0; i < num; i++) {
+		unsigned long lbr_idx = (tos - i) & mask;
+		u64 from, to, mis = 0, pred = 0, in_tx = 0, abort = 0;
+		int skip = 0;
+		u16 cycles = 0;
+		int lbr_flags = lbr_desc[lbr_format];
+
+		rdmsrl(x86_pmu.lbr_from + lbr_idx, from);
+		rdmsrl(x86_pmu.lbr_to   + lbr_idx, to);
+
+		if (lbr_format == LBR_FORMAT_INFO) {
+			u64 info;
+
+			rdmsrl(MSR_LBR_INFO_0 + lbr_idx, info);
+			mis = !!(info & LBR_INFO_MISPRED);
+			pred = !mis;
+			in_tx = !!(info & LBR_INFO_IN_TX);
+			abort = !!(info & LBR_INFO_ABORT);
+			cycles = (info & LBR_INFO_CYCLES);
+		}
+		if (lbr_flags & LBR_EIP_FLAGS) {
+			mis = !!(from & LBR_FROM_FLAG_MISPRED);
+			pred = !mis;
+			skip = 1;
+		}
+		if (lbr_flags & LBR_TSX) {
+			in_tx = !!(from & LBR_FROM_FLAG_IN_TX);
+			abort = !!(from & LBR_FROM_FLAG_ABORT);
+			skip = 3;
+		}
+		from = (u64)((((s64)from) << skip) >> skip);
+
+		/*
+		 * Some CPUs report duplicated abort records,
+		 * with the second entry not having an abort bit set.
+		 * Skip them here. This loop runs backwards,
+		 * so we need to undo the previous record.
+		 * If the abort just happened outside the window
+		 * the extra entry cannot be removed.
+		 */
+		if (abort && x86_pmu.lbr_double_abort && out > 0)
+			out--;
+
+		cpuc->lbr_entries[out].from	 = from;
+		cpuc->lbr_entries[out].to	 = to;
+		cpuc->lbr_entries[out].mispred	 = mis;
+		cpuc->lbr_entries[out].predicted = pred;
+		cpuc->lbr_entries[out].in_tx	 = in_tx;
+		cpuc->lbr_entries[out].abort	 = abort;
+		cpuc->lbr_entries[out].cycles	 = cycles;
+		cpuc->lbr_entries[out].reserved	 = 0;
+		out++;
+	}
+	cpuc->lbr_stack.nr = out;
+}
+
+void intel_pmu_lbr_read(void)
+{
+	struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
+
+	if (!cpuc->lbr_users)
+		return;
+
+	if (x86_pmu.intel_cap.lbr_format == LBR_FORMAT_32)
+		intel_pmu_lbr_read_32(cpuc);
+	else
+		intel_pmu_lbr_read_64(cpuc);
+
+	intel_pmu_lbr_filter(cpuc);
+}
+
+/*
+ * SW filter is used:
+ * - in case there is no HW filter
+ * - in case the HW filter has errata or limitations
+ */
+static int intel_pmu_setup_sw_lbr_filter(struct perf_event *event)
+{
+	u64 br_type = event->attr.branch_sample_type;
+	int mask = 0;
+
+	if (br_type & PERF_SAMPLE_BRANCH_USER)
+		mask |= X86_BR_USER;
+
+	if (br_type & PERF_SAMPLE_BRANCH_KERNEL)
+		mask |= X86_BR_KERNEL;
+
+	/* we ignore BRANCH_HV here */
+
+	if (br_type & PERF_SAMPLE_BRANCH_ANY)
+		mask |= X86_BR_ANY;
+
+	if (br_type & PERF_SAMPLE_BRANCH_ANY_CALL)
+		mask |= X86_BR_ANY_CALL;
+
+	if (br_type & PERF_SAMPLE_BRANCH_ANY_RETURN)
+		mask |= X86_BR_RET | X86_BR_IRET | X86_BR_SYSRET;
+
+	if (br_type & PERF_SAMPLE_BRANCH_IND_CALL)
+		mask |= X86_BR_IND_CALL;
+
+	if (br_type & PERF_SAMPLE_BRANCH_ABORT_TX)
+		mask |= X86_BR_ABORT;
+
+	if (br_type & PERF_SAMPLE_BRANCH_IN_TX)
+		mask |= X86_BR_IN_TX;
+
+	if (br_type & PERF_SAMPLE_BRANCH_NO_TX)
+		mask |= X86_BR_NO_TX;
+
+	if (br_type & PERF_SAMPLE_BRANCH_COND)
+		mask |= X86_BR_JCC;
+
+	if (br_type & PERF_SAMPLE_BRANCH_CALL_STACK) {
+		if (!x86_pmu_has_lbr_callstack())
+			return -EOPNOTSUPP;
+		if (mask & ~(X86_BR_USER | X86_BR_KERNEL))
+			return -EINVAL;
+		mask |= X86_BR_CALL | X86_BR_IND_CALL | X86_BR_RET |
+			X86_BR_CALL_STACK;
+	}
+
+	if (br_type & PERF_SAMPLE_BRANCH_IND_JUMP)
+		mask |= X86_BR_IND_JMP;
+
+	if (br_type & PERF_SAMPLE_BRANCH_CALL)
+		mask |= X86_BR_CALL | X86_BR_ZERO_CALL;
+	/*
+	 * stash actual user request into reg, it may
+	 * be used by fixup code for some CPU
+	 */
+	event->hw.branch_reg.reg = mask;
+	return 0;
+}
+
+/*
+ * setup the HW LBR filter
+ * Used only when available, may not be enough to disambiguate
+ * all branches, may need the help of the SW filter
+ */
+static int intel_pmu_setup_hw_lbr_filter(struct perf_event *event)
+{
+	struct hw_perf_event_extra *reg;
+	u64 br_type = event->attr.branch_sample_type;
+	u64 mask = 0, v;
+	int i;
+
+	for (i = 0; i < PERF_SAMPLE_BRANCH_MAX_SHIFT; i++) {
+		if (!(br_type & (1ULL << i)))
+			continue;
+
+		v = x86_pmu.lbr_sel_map[i];
+		if (v == LBR_NOT_SUPP)
+			return -EOPNOTSUPP;
+
+		if (v != LBR_IGN)
+			mask |= v;
+	}
+	reg = &event->hw.branch_reg;
+	reg->idx = EXTRA_REG_LBR;
+
+	/*
+	 * The first 9 bits (LBR_SEL_MASK) in LBR_SELECT operate
+	 * in suppress mode. So LBR_SELECT should be set to
+	 * (~mask & LBR_SEL_MASK) | (mask & ~LBR_SEL_MASK)
+	 */
+	reg->config = mask ^ x86_pmu.lbr_sel_mask;
+
+	return 0;
+}
+
+int intel_pmu_setup_lbr_filter(struct perf_event *event)
+{
+	int ret = 0;
+
+	/*
+	 * no LBR on this PMU
+	 */
+	if (!x86_pmu.lbr_nr)
+		return -EOPNOTSUPP;
+
+	/*
+	 * setup SW LBR filter
+	 */
+	ret = intel_pmu_setup_sw_lbr_filter(event);
+	if (ret)
+		return ret;
+
+	/*
+	 * setup HW LBR filter, if any
+	 */
+	if (x86_pmu.lbr_sel_map)
+		ret = intel_pmu_setup_hw_lbr_filter(event);
+
+	return ret;
+}
+
+/*
+ * return the type of control flow change at address "from"
+ * intruction is not necessarily a branch (in case of interrupt).
+ *
+ * The branch type returned also includes the priv level of the
+ * target of the control flow change (X86_BR_USER, X86_BR_KERNEL).
+ *
+ * If a branch type is unknown OR the instruction cannot be
+ * decoded (e.g., text page not present), then X86_BR_NONE is
+ * returned.
+ */
+static int branch_type(unsigned long from, unsigned long to, int abort)
+{
+	struct insn insn;
+	void *addr;
+	int bytes_read, bytes_left;
+	int ret = X86_BR_NONE;
+	int ext, to_plm, from_plm;
+	u8 buf[MAX_INSN_SIZE];
+	int is64 = 0;
+
+	to_plm = kernel_ip(to) ? X86_BR_KERNEL : X86_BR_USER;
+	from_plm = kernel_ip(from) ? X86_BR_KERNEL : X86_BR_USER;
+
+	/*
+	 * maybe zero if lbr did not fill up after a reset by the time
+	 * we get a PMU interrupt
+	 */
+	if (from == 0 || to == 0)
+		return X86_BR_NONE;
+
+	if (abort)
+		return X86_BR_ABORT | to_plm;
+
+	if (from_plm == X86_BR_USER) {
+		/*
+		 * can happen if measuring at the user level only
+		 * and we interrupt in a kernel thread, e.g., idle.
+		 */
+		if (!current->mm)
+			return X86_BR_NONE;
+
+		/* may fail if text not present */
+		bytes_left = copy_from_user_nmi(buf, (void __user *)from,
+						MAX_INSN_SIZE);
+		bytes_read = MAX_INSN_SIZE - bytes_left;
+		if (!bytes_read)
+			return X86_BR_NONE;
+
+		addr = buf;
+	} else {
+		/*
+		 * The LBR logs any address in the IP, even if the IP just
+		 * faulted. This means userspace can control the from address.
+		 * Ensure we don't blindy read any address by validating it is
+		 * a known text address.
+		 */
+		if (kernel_text_address(from)) {
+			addr = (void *)from;
+			/*
+			 * Assume we can get the maximum possible size
+			 * when grabbing kernel data.  This is not
+			 * _strictly_ true since we could possibly be
+			 * executing up next to a memory hole, but
+			 * it is very unlikely to be a problem.
+			 */
+			bytes_read = MAX_INSN_SIZE;
+		} else {
+			return X86_BR_NONE;
+		}
+	}
+
+	/*
+	 * decoder needs to know the ABI especially
+	 * on 64-bit systems running 32-bit apps
+	 */
+#ifdef CONFIG_X86_64
+	is64 = kernel_ip((unsigned long)addr) || !test_thread_flag(TIF_IA32);
+#endif
+	insn_init(&insn, addr, bytes_read, is64);
+	insn_get_opcode(&insn);
+	if (!insn.opcode.got)
+		return X86_BR_ABORT;
+
+	switch (insn.opcode.bytes[0]) {
+	case 0xf:
+		switch (insn.opcode.bytes[1]) {
+		case 0x05: /* syscall */
+		case 0x34: /* sysenter */
+			ret = X86_BR_SYSCALL;
+			break;
+		case 0x07: /* sysret */
+		case 0x35: /* sysexit */
+			ret = X86_BR_SYSRET;
+			break;
+		case 0x80 ... 0x8f: /* conditional */
+			ret = X86_BR_JCC;
+			break;
+		default:
+			ret = X86_BR_NONE;
+		}
+		break;
+	case 0x70 ... 0x7f: /* conditional */
+		ret = X86_BR_JCC;
+		break;
+	case 0xc2: /* near ret */
+	case 0xc3: /* near ret */
+	case 0xca: /* far ret */
+	case 0xcb: /* far ret */
+		ret = X86_BR_RET;
+		break;
+	case 0xcf: /* iret */
+		ret = X86_BR_IRET;
+		break;
+	case 0xcc ... 0xce: /* int */
+		ret = X86_BR_INT;
+		break;
+	case 0xe8: /* call near rel */
+		insn_get_immediate(&insn);
+		if (insn.immediate1.value == 0) {
+			/* zero length call */
+			ret = X86_BR_ZERO_CALL;
+			break;
+		}
+	case 0x9a: /* call far absolute */
+		ret = X86_BR_CALL;
+		break;
+	case 0xe0 ... 0xe3: /* loop jmp */
+		ret = X86_BR_JCC;
+		break;
+	case 0xe9 ... 0xeb: /* jmp */
+		ret = X86_BR_JMP;
+		break;
+	case 0xff: /* call near absolute, call far absolute ind */
+		insn_get_modrm(&insn);
+		ext = (insn.modrm.bytes[0] >> 3) & 0x7;
+		switch (ext) {
+		case 2: /* near ind call */
+		case 3: /* far ind call */
+			ret = X86_BR_IND_CALL;
+			break;
+		case 4:
+		case 5:
+			ret = X86_BR_IND_JMP;
+			break;
+		}
+		break;
+	default:
+		ret = X86_BR_NONE;
+	}
+	/*
+	 * interrupts, traps, faults (and thus ring transition) may
+	 * occur on any instructions. Thus, to classify them correctly,
+	 * we need to first look at the from and to priv levels. If they
+	 * are different and to is in the kernel, then it indicates
+	 * a ring transition. If the from instruction is not a ring
+	 * transition instr (syscall, systenter, int), then it means
+	 * it was a irq, trap or fault.
+	 *
+	 * we have no way of detecting kernel to kernel faults.
+	 */
+	if (from_plm == X86_BR_USER && to_plm == X86_BR_KERNEL
+	    && ret != X86_BR_SYSCALL && ret != X86_BR_INT)
+		ret = X86_BR_IRQ;
+
+	/*
+	 * branch priv level determined by target as
+	 * is done by HW when LBR_SELECT is implemented
+	 */
+	if (ret != X86_BR_NONE)
+		ret |= to_plm;
+
+	return ret;
+}
+
+/*
+ * implement actual branch filter based on user demand.
+ * Hardware may not exactly satisfy that request, thus
+ * we need to inspect opcodes. Mismatched branches are
+ * discarded. Therefore, the number of branches returned
+ * in PERF_SAMPLE_BRANCH_STACK sample may vary.
+ */
+static void
+intel_pmu_lbr_filter(struct cpu_hw_events *cpuc)
+{
+	u64 from, to;
+	int br_sel = cpuc->br_sel;
+	int i, j, type;
+	bool compress = false;
+
+	/* if sampling all branches, then nothing to filter */
+	if ((br_sel & X86_BR_ALL) == X86_BR_ALL)
+		return;
+
+	for (i = 0; i < cpuc->lbr_stack.nr; i++) {
+
+		from = cpuc->lbr_entries[i].from;
+		to = cpuc->lbr_entries[i].to;
+
+		type = branch_type(from, to, cpuc->lbr_entries[i].abort);
+		if (type != X86_BR_NONE && (br_sel & X86_BR_ANYTX)) {
+			if (cpuc->lbr_entries[i].in_tx)
+				type |= X86_BR_IN_TX;
+			else
+				type |= X86_BR_NO_TX;
+		}
+
+		/* if type does not correspond, then discard */
+		if (type == X86_BR_NONE || (br_sel & type) != type) {
+			cpuc->lbr_entries[i].from = 0;
+			compress = true;
+		}
+	}
+
+	if (!compress)
+		return;
+
+	/* remove all entries with from=0 */
+	for (i = 0; i < cpuc->lbr_stack.nr; ) {
+		if (!cpuc->lbr_entries[i].from) {
+			j = i;
+			while (++j < cpuc->lbr_stack.nr)
+				cpuc->lbr_entries[j-1] = cpuc->lbr_entries[j];
+			cpuc->lbr_stack.nr--;
+			if (!cpuc->lbr_entries[i].from)
+				continue;
+		}
+		i++;
+	}
+}
+
+/*
+ * Map interface branch filters onto LBR filters
+ */
+static const int nhm_lbr_sel_map[PERF_SAMPLE_BRANCH_MAX_SHIFT] = {
+	[PERF_SAMPLE_BRANCH_ANY_SHIFT]		= LBR_ANY,
+	[PERF_SAMPLE_BRANCH_USER_SHIFT]		= LBR_USER,
+	[PERF_SAMPLE_BRANCH_KERNEL_SHIFT]	= LBR_KERNEL,
+	[PERF_SAMPLE_BRANCH_HV_SHIFT]		= LBR_IGN,
+	[PERF_SAMPLE_BRANCH_ANY_RETURN_SHIFT]	= LBR_RETURN | LBR_REL_JMP
+						| LBR_IND_JMP | LBR_FAR,
+	/*
+	 * NHM/WSM erratum: must include REL_JMP+IND_JMP to get CALL branches
+	 */
+	[PERF_SAMPLE_BRANCH_ANY_CALL_SHIFT] =
+	 LBR_REL_CALL | LBR_IND_CALL | LBR_REL_JMP | LBR_IND_JMP | LBR_FAR,
+	/*
+	 * NHM/WSM erratum: must include IND_JMP to capture IND_CALL
+	 */
+	[PERF_SAMPLE_BRANCH_IND_CALL_SHIFT] = LBR_IND_CALL | LBR_IND_JMP,
+	[PERF_SAMPLE_BRANCH_COND_SHIFT]     = LBR_JCC,
+	[PERF_SAMPLE_BRANCH_IND_JUMP_SHIFT] = LBR_IND_JMP,
+};
+
+static const int snb_lbr_sel_map[PERF_SAMPLE_BRANCH_MAX_SHIFT] = {
+	[PERF_SAMPLE_BRANCH_ANY_SHIFT]		= LBR_ANY,
+	[PERF_SAMPLE_BRANCH_USER_SHIFT]		= LBR_USER,
+	[PERF_SAMPLE_BRANCH_KERNEL_SHIFT]	= LBR_KERNEL,
+	[PERF_SAMPLE_BRANCH_HV_SHIFT]		= LBR_IGN,
+	[PERF_SAMPLE_BRANCH_ANY_RETURN_SHIFT]	= LBR_RETURN | LBR_FAR,
+	[PERF_SAMPLE_BRANCH_ANY_CALL_SHIFT]	= LBR_REL_CALL | LBR_IND_CALL
+						| LBR_FAR,
+	[PERF_SAMPLE_BRANCH_IND_CALL_SHIFT]	= LBR_IND_CALL,
+	[PERF_SAMPLE_BRANCH_COND_SHIFT]		= LBR_JCC,
+	[PERF_SAMPLE_BRANCH_IND_JUMP_SHIFT]	= LBR_IND_JMP,
+	[PERF_SAMPLE_BRANCH_CALL_SHIFT]		= LBR_REL_CALL,
+};
+
+static const int hsw_lbr_sel_map[PERF_SAMPLE_BRANCH_MAX_SHIFT] = {
+	[PERF_SAMPLE_BRANCH_ANY_SHIFT]		= LBR_ANY,
+	[PERF_SAMPLE_BRANCH_USER_SHIFT]		= LBR_USER,
+	[PERF_SAMPLE_BRANCH_KERNEL_SHIFT]	= LBR_KERNEL,
+	[PERF_SAMPLE_BRANCH_HV_SHIFT]		= LBR_IGN,
+	[PERF_SAMPLE_BRANCH_ANY_RETURN_SHIFT]	= LBR_RETURN | LBR_FAR,
+	[PERF_SAMPLE_BRANCH_ANY_CALL_SHIFT]	= LBR_REL_CALL | LBR_IND_CALL
+						| LBR_FAR,
+	[PERF_SAMPLE_BRANCH_IND_CALL_SHIFT]	= LBR_IND_CALL,
+	[PERF_SAMPLE_BRANCH_COND_SHIFT]		= LBR_JCC,
+	[PERF_SAMPLE_BRANCH_CALL_STACK_SHIFT]	= LBR_REL_CALL | LBR_IND_CALL
+						| LBR_RETURN | LBR_CALL_STACK,
+	[PERF_SAMPLE_BRANCH_IND_JUMP_SHIFT]	= LBR_IND_JMP,
+	[PERF_SAMPLE_BRANCH_CALL_SHIFT]		= LBR_REL_CALL,
+};
+
+/* core */
+void __init intel_pmu_lbr_init_core(void)
+{
+	x86_pmu.lbr_nr     = 4;
+	x86_pmu.lbr_tos    = MSR_LBR_TOS;
+	x86_pmu.lbr_from   = MSR_LBR_CORE_FROM;
+	x86_pmu.lbr_to     = MSR_LBR_CORE_TO;
+
+	/*
+	 * SW branch filter usage:
+	 * - compensate for lack of HW filter
+	 */
+	pr_cont("4-deep LBR, ");
+}
+
+/* nehalem/westmere */
+void __init intel_pmu_lbr_init_nhm(void)
+{
+	x86_pmu.lbr_nr     = 16;
+	x86_pmu.lbr_tos    = MSR_LBR_TOS;
+	x86_pmu.lbr_from   = MSR_LBR_NHM_FROM;
+	x86_pmu.lbr_to     = MSR_LBR_NHM_TO;
+
+	x86_pmu.lbr_sel_mask = LBR_SEL_MASK;
+	x86_pmu.lbr_sel_map  = nhm_lbr_sel_map;
+
+	/*
+	 * SW branch filter usage:
+	 * - workaround LBR_SEL errata (see above)
+	 * - support syscall, sysret capture.
+	 *   That requires LBR_FAR but that means far
+	 *   jmp need to be filtered out
+	 */
+	pr_cont("16-deep LBR, ");
+}
+
+/* sandy bridge */
+void __init intel_pmu_lbr_init_snb(void)
+{
+	x86_pmu.lbr_nr	 = 16;
+	x86_pmu.lbr_tos	 = MSR_LBR_TOS;
+	x86_pmu.lbr_from = MSR_LBR_NHM_FROM;
+	x86_pmu.lbr_to   = MSR_LBR_NHM_TO;
+
+	x86_pmu.lbr_sel_mask = LBR_SEL_MASK;
+	x86_pmu.lbr_sel_map  = snb_lbr_sel_map;
+
+	/*
+	 * SW branch filter usage:
+	 * - support syscall, sysret capture.
+	 *   That requires LBR_FAR but that means far
+	 *   jmp need to be filtered out
+	 */
+	pr_cont("16-deep LBR, ");
+}
+
+/* haswell */
+void intel_pmu_lbr_init_hsw(void)
+{
+	x86_pmu.lbr_nr	 = 16;
+	x86_pmu.lbr_tos	 = MSR_LBR_TOS;
+	x86_pmu.lbr_from = MSR_LBR_NHM_FROM;
+	x86_pmu.lbr_to   = MSR_LBR_NHM_TO;
+
+	x86_pmu.lbr_sel_mask = LBR_SEL_MASK;
+	x86_pmu.lbr_sel_map  = hsw_lbr_sel_map;
+
+	pr_cont("16-deep LBR, ");
+}
+
+/* skylake */
+__init void intel_pmu_lbr_init_skl(void)
+{
+	x86_pmu.lbr_nr	 = 32;
+	x86_pmu.lbr_tos	 = MSR_LBR_TOS;
+	x86_pmu.lbr_from = MSR_LBR_NHM_FROM;
+	x86_pmu.lbr_to   = MSR_LBR_NHM_TO;
+
+	x86_pmu.lbr_sel_mask = LBR_SEL_MASK;
+	x86_pmu.lbr_sel_map  = hsw_lbr_sel_map;
+
+	/*
+	 * SW branch filter usage:
+	 * - support syscall, sysret capture.
+	 *   That requires LBR_FAR but that means far
+	 *   jmp need to be filtered out
+	 */
+	pr_cont("32-deep LBR, ");
+}
+
+/* atom */
+void __init intel_pmu_lbr_init_atom(void)
+{
+	/*
+	 * only models starting at stepping 10 seems
+	 * to have an operational LBR which can freeze
+	 * on PMU interrupt
+	 */
+	if (boot_cpu_data.x86_model == 28
+	    && boot_cpu_data.x86_mask < 10) {
+		pr_cont("LBR disabled due to erratum");
+		return;
+	}
+
+	x86_pmu.lbr_nr	   = 8;
+	x86_pmu.lbr_tos    = MSR_LBR_TOS;
+	x86_pmu.lbr_from   = MSR_LBR_CORE_FROM;
+	x86_pmu.lbr_to     = MSR_LBR_CORE_TO;
+
+	/*
+	 * SW branch filter usage:
+	 * - compensate for lack of HW filter
+	 */
+	pr_cont("8-deep LBR, ");
+}
+
+/* Knights Landing */
+void intel_pmu_lbr_init_knl(void)
+{
+	x86_pmu.lbr_nr	   = 8;
+	x86_pmu.lbr_tos    = MSR_LBR_TOS;
+	x86_pmu.lbr_from   = MSR_LBR_NHM_FROM;
+	x86_pmu.lbr_to     = MSR_LBR_NHM_TO;
+
+	x86_pmu.lbr_sel_mask = LBR_SEL_MASK;
+	x86_pmu.lbr_sel_map  = snb_lbr_sel_map;
+
+	pr_cont("8-deep LBR, ");
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/arch/x86/events/intel/p4.c
@@ -0,0 +1,1376 @@
+/*
+ * Netburst Performance Events (P4, old Xeon)
+ *
+ *  Copyright (C) 2010 Parallels, Inc., Cyrill Gorcunov <gorcunov@openvz.org>
+ *  Copyright (C) 2010 Intel Corporation, Lin Ming <ming.m.lin@intel.com>
+ *
+ *  For licencing details see kernel-base/COPYING
+ */
+
+#include <linux/perf_event.h>
+
+#include <asm/perf_event_p4.h>
+#include <asm/hardirq.h>
+#include <asm/apic.h>
+
+#include "../perf_event.h"
+
+#define P4_CNTR_LIMIT 3
+/*
+ * array indices: 0,1 - HT threads, used with HT enabled cpu
+ */
+struct p4_event_bind {
+	unsigned int opcode;			/* Event code and ESCR selector */
+	unsigned int escr_msr[2];		/* ESCR MSR for this event */
+	unsigned int escr_emask;		/* valid ESCR EventMask bits */
+	unsigned int shared;			/* event is shared across threads */
+	char cntr[2][P4_CNTR_LIMIT];		/* counter index (offset), -1 on abscence */
+};
+
+struct p4_pebs_bind {
+	unsigned int metric_pebs;
+	unsigned int metric_vert;
+};
+
+/* it sets P4_PEBS_ENABLE_UOP_TAG as well */
+#define P4_GEN_PEBS_BIND(name, pebs, vert)			\
+	[P4_PEBS_METRIC__##name] = {				\
+		.metric_pebs = pebs | P4_PEBS_ENABLE_UOP_TAG,	\
+		.metric_vert = vert,				\
+	}
+
+/*
+ * note we have P4_PEBS_ENABLE_UOP_TAG always set here
+ *
+ * it's needed for mapping P4_PEBS_CONFIG_METRIC_MASK bits of
+ * event configuration to find out which values are to be
+ * written into MSR_IA32_PEBS_ENABLE and MSR_P4_PEBS_MATRIX_VERT
+ * resgisters
+ */
+static struct p4_pebs_bind p4_pebs_bind_map[] = {
+	P4_GEN_PEBS_BIND(1stl_cache_load_miss_retired,	0x0000001, 0x0000001),
+	P4_GEN_PEBS_BIND(2ndl_cache_load_miss_retired,	0x0000002, 0x0000001),
+	P4_GEN_PEBS_BIND(dtlb_load_miss_retired,	0x0000004, 0x0000001),
+	P4_GEN_PEBS_BIND(dtlb_store_miss_retired,	0x0000004, 0x0000002),
+	P4_GEN_PEBS_BIND(dtlb_all_miss_retired,		0x0000004, 0x0000003),
+	P4_GEN_PEBS_BIND(tagged_mispred_branch,		0x0018000, 0x0000010),
+	P4_GEN_PEBS_BIND(mob_load_replay_retired,	0x0000200, 0x0000001),
+	P4_GEN_PEBS_BIND(split_load_retired,		0x0000400, 0x0000001),
+	P4_GEN_PEBS_BIND(split_store_retired,		0x0000400, 0x0000002),
+};
+
+/*
+ * Note that we don't use CCCR1 here, there is an
+ * exception for P4_BSQ_ALLOCATION but we just have
+ * no workaround
+ *
+ * consider this binding as resources which particular
+ * event may borrow, it doesn't contain EventMask,
+ * Tags and friends -- they are left to a caller
+ */
+static struct p4_event_bind p4_event_bind_map[] = {
+	[P4_EVENT_TC_DELIVER_MODE] = {
+		.opcode		= P4_OPCODE(P4_EVENT_TC_DELIVER_MODE),
+		.escr_msr	= { MSR_P4_TC_ESCR0, MSR_P4_TC_ESCR1 },
+		.escr_emask	=
+			P4_ESCR_EMASK_BIT(P4_EVENT_TC_DELIVER_MODE, DD)			|
+			P4_ESCR_EMASK_BIT(P4_EVENT_TC_DELIVER_MODE, DB)			|
+			P4_ESCR_EMASK_BIT(P4_EVENT_TC_DELIVER_MODE, DI)			|
+			P4_ESCR_EMASK_BIT(P4_EVENT_TC_DELIVER_MODE, BD)			|
+			P4_ESCR_EMASK_BIT(P4_EVENT_TC_DELIVER_MODE, BB)			|
+			P4_ESCR_EMASK_BIT(P4_EVENT_TC_DELIVER_MODE, BI)			|
+			P4_ESCR_EMASK_BIT(P4_EVENT_TC_DELIVER_MODE, ID),
+		.shared		= 1,
+		.cntr		= { {4, 5, -1}, {6, 7, -1} },
+	},
+	[P4_EVENT_BPU_FETCH_REQUEST] = {
+		.opcode		= P4_OPCODE(P4_EVENT_BPU_FETCH_REQUEST),
+		.escr_msr	= { MSR_P4_BPU_ESCR0, MSR_P4_BPU_ESCR1 },
+		.escr_emask	=
+			P4_ESCR_EMASK_BIT(P4_EVENT_BPU_FETCH_REQUEST, TCMISS),
+		.cntr		= { {0, -1, -1}, {2, -1, -1} },
+	},
+	[P4_EVENT_ITLB_REFERENCE] = {
+		.opcode		= P4_OPCODE(P4_EVENT_ITLB_REFERENCE),
+		.escr_msr	= { MSR_P4_ITLB_ESCR0, MSR_P4_ITLB_ESCR1 },
+		.escr_emask	=
+			P4_ESCR_EMASK_BIT(P4_EVENT_ITLB_REFERENCE, HIT)			|
+			P4_ESCR_EMASK_BIT(P4_EVENT_ITLB_REFERENCE, MISS)		|
+			P4_ESCR_EMASK_BIT(P4_EVENT_ITLB_REFERENCE, HIT_UK),
+		.cntr		= { {0, -1, -1}, {2, -1, -1} },
+	},
+	[P4_EVENT_MEMORY_CANCEL] = {
+		.opcode		= P4_OPCODE(P4_EVENT_MEMORY_CANCEL),
+		.escr_msr	= { MSR_P4_DAC_ESCR0, MSR_P4_DAC_ESCR1 },
+		.escr_emask	=
+			P4_ESCR_EMASK_BIT(P4_EVENT_MEMORY_CANCEL, ST_RB_FULL)		|
+			P4_ESCR_EMASK_BIT(P4_EVENT_MEMORY_CANCEL, 64K_CONF),
+		.cntr		= { {8, 9, -1}, {10, 11, -1} },
+	},
+	[P4_EVENT_MEMORY_COMPLETE] = {
+		.opcode		= P4_OPCODE(P4_EVENT_MEMORY_COMPLETE),
+		.escr_msr	= { MSR_P4_SAAT_ESCR0 , MSR_P4_SAAT_ESCR1 },
+		.escr_emask	=
+			P4_ESCR_EMASK_BIT(P4_EVENT_MEMORY_COMPLETE, LSC)		|
+			P4_ESCR_EMASK_BIT(P4_EVENT_MEMORY_COMPLETE, SSC),
+		.cntr		= { {8, 9, -1}, {10, 11, -1} },
+	},
+	[P4_EVENT_LOAD_PORT_REPLAY] = {
+		.opcode		= P4_OPCODE(P4_EVENT_LOAD_PORT_REPLAY),
+		.escr_msr	= { MSR_P4_SAAT_ESCR0, MSR_P4_SAAT_ESCR1 },
+		.escr_emask	=
+			P4_ESCR_EMASK_BIT(P4_EVENT_LOAD_PORT_REPLAY, SPLIT_LD),
+		.cntr		= { {8, 9, -1}, {10, 11, -1} },
+	},
+	[P4_EVENT_STORE_PORT_REPLAY] = {
+		.opcode		= P4_OPCODE(P4_EVENT_STORE_PORT_REPLAY),
+		.escr_msr	= { MSR_P4_SAAT_ESCR0 ,  MSR_P4_SAAT_ESCR1 },
+		.escr_emask	=
+			P4_ESCR_EMASK_BIT(P4_EVENT_STORE_PORT_REPLAY, SPLIT_ST),
+		.cntr		= { {8, 9, -1}, {10, 11, -1} },
+	},
+	[P4_EVENT_MOB_LOAD_REPLAY] = {
+		.opcode		= P4_OPCODE(P4_EVENT_MOB_LOAD_REPLAY),
+		.escr_msr	= { MSR_P4_MOB_ESCR0, MSR_P4_MOB_ESCR1 },
+		.escr_emask	=
+			P4_ESCR_EMASK_BIT(P4_EVENT_MOB_LOAD_REPLAY, NO_STA)		|
+			P4_ESCR_EMASK_BIT(P4_EVENT_MOB_LOAD_REPLAY, NO_STD)		|
+			P4_ESCR_EMASK_BIT(P4_EVENT_MOB_LOAD_REPLAY, PARTIAL_DATA)	|
+			P4_ESCR_EMASK_BIT(P4_EVENT_MOB_LOAD_REPLAY, UNALGN_ADDR),
+		.cntr		= { {0, -1, -1}, {2, -1, -1} },
+	},
+	[P4_EVENT_PAGE_WALK_TYPE] = {
+		.opcode		= P4_OPCODE(P4_EVENT_PAGE_WALK_TYPE),
+		.escr_msr	= { MSR_P4_PMH_ESCR0, MSR_P4_PMH_ESCR1 },
+		.escr_emask	=
+			P4_ESCR_EMASK_BIT(P4_EVENT_PAGE_WALK_TYPE, DTMISS)		|
+			P4_ESCR_EMASK_BIT(P4_EVENT_PAGE_WALK_TYPE, ITMISS),
+		.shared		= 1,
+		.cntr		= { {0, -1, -1}, {2, -1, -1} },
+	},
+	[P4_EVENT_BSQ_CACHE_REFERENCE] = {
+		.opcode		= P4_OPCODE(P4_EVENT_BSQ_CACHE_REFERENCE),
+		.escr_msr	= { MSR_P4_BSU_ESCR0, MSR_P4_BSU_ESCR1 },
+		.escr_emask	=
+			P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_CACHE_REFERENCE, RD_2ndL_HITS)	|
+			P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_CACHE_REFERENCE, RD_2ndL_HITE)	|
+			P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_CACHE_REFERENCE, RD_2ndL_HITM)	|
+			P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_CACHE_REFERENCE, RD_3rdL_HITS)	|
+			P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_CACHE_REFERENCE, RD_3rdL_HITE)	|
+			P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_CACHE_REFERENCE, RD_3rdL_HITM)	|
+			P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_CACHE_REFERENCE, RD_2ndL_MISS)	|
+			P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_CACHE_REFERENCE, RD_3rdL_MISS)	|
+			P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_CACHE_REFERENCE, WR_2ndL_MISS),
+		.cntr		= { {0, -1, -1}, {2, -1, -1} },
+	},
+	[P4_EVENT_IOQ_ALLOCATION] = {
+		.opcode		= P4_OPCODE(P4_EVENT_IOQ_ALLOCATION),
+		.escr_msr	= { MSR_P4_FSB_ESCR0, MSR_P4_FSB_ESCR1 },
+		.escr_emask	=
+			P4_ESCR_EMASK_BIT(P4_EVENT_IOQ_ALLOCATION, DEFAULT)		|
+			P4_ESCR_EMASK_BIT(P4_EVENT_IOQ_ALLOCATION, ALL_READ)		|
+			P4_ESCR_EMASK_BIT(P4_EVENT_IOQ_ALLOCATION, ALL_WRITE)		|
+			P4_ESCR_EMASK_BIT(P4_EVENT_IOQ_ALLOCATION, MEM_UC)		|
+			P4_ESCR_EMASK_BIT(P4_EVENT_IOQ_ALLOCATION, MEM_WC)		|
+			P4_ESCR_EMASK_BIT(P4_EVENT_IOQ_ALLOCATION, MEM_WT)		|
+			P4_ESCR_EMASK_BIT(P4_EVENT_IOQ_ALLOCATION, MEM_WP)		|
+			P4_ESCR_EMASK_BIT(P4_EVENT_IOQ_ALLOCATION, MEM_WB)		|
+			P4_ESCR_EMASK_BIT(P4_EVENT_IOQ_ALLOCATION, OWN)			|
+			P4_ESCR_EMASK_BIT(P4_EVENT_IOQ_ALLOCATION, OTHER)		|
+			P4_ESCR_EMASK_BIT(P4_EVENT_IOQ_ALLOCATION, PREFETCH),
+		.cntr		= { {0, -1, -1}, {2, -1, -1} },
+	},
+	[P4_EVENT_IOQ_ACTIVE_ENTRIES] = {	/* shared ESCR */
+		.opcode		= P4_OPCODE(P4_EVENT_IOQ_ACTIVE_ENTRIES),
+		.escr_msr	= { MSR_P4_FSB_ESCR1,  MSR_P4_FSB_ESCR1 },
+		.escr_emask	=
+			P4_ESCR_EMASK_BIT(P4_EVENT_IOQ_ACTIVE_ENTRIES, DEFAULT)		|
+			P4_ESCR_EMASK_BIT(P4_EVENT_IOQ_ACTIVE_ENTRIES, ALL_READ)	|
+			P4_ESCR_EMASK_BIT(P4_EVENT_IOQ_ACTIVE_ENTRIES, ALL_WRITE)	|
+			P4_ESCR_EMASK_BIT(P4_EVENT_IOQ_ACTIVE_ENTRIES, MEM_UC)		|
+			P4_ESCR_EMASK_BIT(P4_EVENT_IOQ_ACTIVE_ENTRIES, MEM_WC)		|
+			P4_ESCR_EMASK_BIT(P4_EVENT_IOQ_ACTIVE_ENTRIES, MEM_WT)		|
+			P4_ESCR_EMASK_BIT(P4_EVENT_IOQ_ACTIVE_ENTRIES, MEM_WP)		|
+			P4_ESCR_EMASK_BIT(P4_EVENT_IOQ_ACTIVE_ENTRIES, MEM_WB)		|
+			P4_ESCR_EMASK_BIT(P4_EVENT_IOQ_ACTIVE_ENTRIES, OWN)		|
+			P4_ESCR_EMASK_BIT(P4_EVENT_IOQ_ACTIVE_ENTRIES, OTHER)		|
+			P4_ESCR_EMASK_BIT(P4_EVENT_IOQ_ACTIVE_ENTRIES, PREFETCH),
+		.cntr		= { {2, -1, -1}, {3, -1, -1} },
+	},
+	[P4_EVENT_FSB_DATA_ACTIVITY] = {
+		.opcode		= P4_OPCODE(P4_EVENT_FSB_DATA_ACTIVITY),
+		.escr_msr	= { MSR_P4_FSB_ESCR0, MSR_P4_FSB_ESCR1 },
+		.escr_emask	=
+			P4_ESCR_EMASK_BIT(P4_EVENT_FSB_DATA_ACTIVITY, DRDY_DRV)		|
+			P4_ESCR_EMASK_BIT(P4_EVENT_FSB_DATA_ACTIVITY, DRDY_OWN)		|
+			P4_ESCR_EMASK_BIT(P4_EVENT_FSB_DATA_ACTIVITY, DRDY_OTHER)	|
+			P4_ESCR_EMASK_BIT(P4_EVENT_FSB_DATA_ACTIVITY, DBSY_DRV)		|
+			P4_ESCR_EMASK_BIT(P4_EVENT_FSB_DATA_ACTIVITY, DBSY_OWN)		|
+			P4_ESCR_EMASK_BIT(P4_EVENT_FSB_DATA_ACTIVITY, DBSY_OTHER),
+		.shared		= 1,
+		.cntr		= { {0, -1, -1}, {2, -1, -1} },
+	},
+	[P4_EVENT_BSQ_ALLOCATION] = {		/* shared ESCR, broken CCCR1 */
+		.opcode		= P4_OPCODE(P4_EVENT_BSQ_ALLOCATION),
+		.escr_msr	= { MSR_P4_BSU_ESCR0, MSR_P4_BSU_ESCR0 },
+		.escr_emask	=
+			P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ALLOCATION, REQ_TYPE0)		|
+			P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ALLOCATION, REQ_TYPE1)		|
+			P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ALLOCATION, REQ_LEN0)		|
+			P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ALLOCATION, REQ_LEN1)		|
+			P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ALLOCATION, REQ_IO_TYPE)		|
+			P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ALLOCATION, REQ_LOCK_TYPE)	|
+			P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ALLOCATION, REQ_CACHE_TYPE)	|
+			P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ALLOCATION, REQ_SPLIT_TYPE)	|
+			P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ALLOCATION, REQ_DEM_TYPE)	|
+			P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ALLOCATION, REQ_ORD_TYPE)	|
+			P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ALLOCATION, MEM_TYPE0)		|
+			P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ALLOCATION, MEM_TYPE1)		|
+			P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ALLOCATION, MEM_TYPE2),
+		.cntr		= { {0, -1, -1}, {1, -1, -1} },
+	},
+	[P4_EVENT_BSQ_ACTIVE_ENTRIES] = {	/* shared ESCR */
+		.opcode		= P4_OPCODE(P4_EVENT_BSQ_ACTIVE_ENTRIES),
+		.escr_msr	= { MSR_P4_BSU_ESCR1 , MSR_P4_BSU_ESCR1 },
+		.escr_emask	=
+			P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ACTIVE_ENTRIES, REQ_TYPE0)	|
+			P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ACTIVE_ENTRIES, REQ_TYPE1)	|
+			P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ACTIVE_ENTRIES, REQ_LEN0)	|
+			P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ACTIVE_ENTRIES, REQ_LEN1)	|
+			P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ACTIVE_ENTRIES, REQ_IO_TYPE)	|
+			P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ACTIVE_ENTRIES, REQ_LOCK_TYPE)	|
+			P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ACTIVE_ENTRIES, REQ_CACHE_TYPE)	|
+			P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ACTIVE_ENTRIES, REQ_SPLIT_TYPE)	|
+			P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ACTIVE_ENTRIES, REQ_DEM_TYPE)	|
+			P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ACTIVE_ENTRIES, REQ_ORD_TYPE)	|
+			P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ACTIVE_ENTRIES, MEM_TYPE0)	|
+			P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ACTIVE_ENTRIES, MEM_TYPE1)	|
+			P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ACTIVE_ENTRIES, MEM_TYPE2),
+		.cntr		= { {2, -1, -1}, {3, -1, -1} },
+	},
+	[P4_EVENT_SSE_INPUT_ASSIST] = {
+		.opcode		= P4_OPCODE(P4_EVENT_SSE_INPUT_ASSIST),
+		.escr_msr	= { MSR_P4_FIRM_ESCR0, MSR_P4_FIRM_ESCR1 },
+		.escr_emask	=
+			P4_ESCR_EMASK_BIT(P4_EVENT_SSE_INPUT_ASSIST, ALL),
+		.shared		= 1,
+		.cntr		= { {8, 9, -1}, {10, 11, -1} },
+	},
+	[P4_EVENT_PACKED_SP_UOP] = {
+		.opcode		= P4_OPCODE(P4_EVENT_PACKED_SP_UOP),
+		.escr_msr	= { MSR_P4_FIRM_ESCR0, MSR_P4_FIRM_ESCR1 },
+		.escr_emask	=
+			P4_ESCR_EMASK_BIT(P4_EVENT_PACKED_SP_UOP, ALL),
+		.shared		= 1,
+		.cntr		= { {8, 9, -1}, {10, 11, -1} },
+	},
+	[P4_EVENT_PACKED_DP_UOP] = {
+		.opcode		= P4_OPCODE(P4_EVENT_PACKED_DP_UOP),
+		.escr_msr	= { MSR_P4_FIRM_ESCR0, MSR_P4_FIRM_ESCR1 },
+		.escr_emask	=
+			P4_ESCR_EMASK_BIT(P4_EVENT_PACKED_DP_UOP, ALL),
+		.shared		= 1,
+		.cntr		= { {8, 9, -1}, {10, 11, -1} },
+	},
+	[P4_EVENT_SCALAR_SP_UOP] = {
+		.opcode		= P4_OPCODE(P4_EVENT_SCALAR_SP_UOP),
+		.escr_msr	= { MSR_P4_FIRM_ESCR0, MSR_P4_FIRM_ESCR1 },
+		.escr_emask	=
+			P4_ESCR_EMASK_BIT(P4_EVENT_SCALAR_SP_UOP, ALL),
+		.shared		= 1,
+		.cntr		= { {8, 9, -1}, {10, 11, -1} },
+	},
+	[P4_EVENT_SCALAR_DP_UOP] = {
+		.opcode		= P4_OPCODE(P4_EVENT_SCALAR_DP_UOP),
+		.escr_msr	= { MSR_P4_FIRM_ESCR0, MSR_P4_FIRM_ESCR1 },
+		.escr_emask	=
+			P4_ESCR_EMASK_BIT(P4_EVENT_SCALAR_DP_UOP, ALL),
+		.shared		= 1,
+		.cntr		= { {8, 9, -1}, {10, 11, -1} },
+	},
+	[P4_EVENT_64BIT_MMX_UOP] = {
+		.opcode		= P4_OPCODE(P4_EVENT_64BIT_MMX_UOP),
+		.escr_msr	= { MSR_P4_FIRM_ESCR0, MSR_P4_FIRM_ESCR1 },
+		.escr_emask	=
+			P4_ESCR_EMASK_BIT(P4_EVENT_64BIT_MMX_UOP, ALL),
+		.shared		= 1,
+		.cntr		= { {8, 9, -1}, {10, 11, -1} },
+	},
+	[P4_EVENT_128BIT_MMX_UOP] = {
+		.opcode		= P4_OPCODE(P4_EVENT_128BIT_MMX_UOP),
+		.escr_msr	= { MSR_P4_FIRM_ESCR0, MSR_P4_FIRM_ESCR1 },
+		.escr_emask	=
+			P4_ESCR_EMASK_BIT(P4_EVENT_128BIT_MMX_UOP, ALL),
+		.shared		= 1,
+		.cntr		= { {8, 9, -1}, {10, 11, -1} },
+	},
+	[P4_EVENT_X87_FP_UOP] = {
+		.opcode		= P4_OPCODE(P4_EVENT_X87_FP_UOP),
+		.escr_msr	= { MSR_P4_FIRM_ESCR0, MSR_P4_FIRM_ESCR1 },
+		.escr_emask	=
+			P4_ESCR_EMASK_BIT(P4_EVENT_X87_FP_UOP, ALL),
+		.shared		= 1,
+		.cntr		= { {8, 9, -1}, {10, 11, -1} },
+	},
+	[P4_EVENT_TC_MISC] = {
+		.opcode		= P4_OPCODE(P4_EVENT_TC_MISC),
+		.escr_msr	= { MSR_P4_TC_ESCR0, MSR_P4_TC_ESCR1 },
+		.escr_emask	=
+			P4_ESCR_EMASK_BIT(P4_EVENT_TC_MISC, FLUSH),
+		.cntr		= { {4, 5, -1}, {6, 7, -1} },
+	},
+	[P4_EVENT_GLOBAL_POWER_EVENTS] = {
+		.opcode		= P4_OPCODE(P4_EVENT_GLOBAL_POWER_EVENTS),
+		.escr_msr	= { MSR_P4_FSB_ESCR0, MSR_P4_FSB_ESCR1 },
+		.escr_emask	=
+			P4_ESCR_EMASK_BIT(P4_EVENT_GLOBAL_POWER_EVENTS, RUNNING),
+		.cntr		= { {0, -1, -1}, {2, -1, -1} },
+	},
+	[P4_EVENT_TC_MS_XFER] = {
+		.opcode		= P4_OPCODE(P4_EVENT_TC_MS_XFER),
+		.escr_msr	= { MSR_P4_MS_ESCR0, MSR_P4_MS_ESCR1 },
+		.escr_emask	=
+			P4_ESCR_EMASK_BIT(P4_EVENT_TC_MS_XFER, CISC),
+		.cntr		= { {4, 5, -1}, {6, 7, -1} },
+	},
+	[P4_EVENT_UOP_QUEUE_WRITES] = {
+		.opcode		= P4_OPCODE(P4_EVENT_UOP_QUEUE_WRITES),
+		.escr_msr	= { MSR_P4_MS_ESCR0, MSR_P4_MS_ESCR1 },
+		.escr_emask	=
+			P4_ESCR_EMASK_BIT(P4_EVENT_UOP_QUEUE_WRITES, FROM_TC_BUILD)	|
+			P4_ESCR_EMASK_BIT(P4_EVENT_UOP_QUEUE_WRITES, FROM_TC_DELIVER)	|
+			P4_ESCR_EMASK_BIT(P4_EVENT_UOP_QUEUE_WRITES, FROM_ROM),
+		.cntr		= { {4, 5, -1}, {6, 7, -1} },
+	},
+	[P4_EVENT_RETIRED_MISPRED_BRANCH_TYPE] = {
+		.opcode		= P4_OPCODE(P4_EVENT_RETIRED_MISPRED_BRANCH_TYPE),
+		.escr_msr	= { MSR_P4_TBPU_ESCR0 , MSR_P4_TBPU_ESCR0 },
+		.escr_emask	=
+			P4_ESCR_EMASK_BIT(P4_EVENT_RETIRED_MISPRED_BRANCH_TYPE, CONDITIONAL)	|
+			P4_ESCR_EMASK_BIT(P4_EVENT_RETIRED_MISPRED_BRANCH_TYPE, CALL)		|
+			P4_ESCR_EMASK_BIT(P4_EVENT_RETIRED_MISPRED_BRANCH_TYPE, RETURN)		|
+			P4_ESCR_EMASK_BIT(P4_EVENT_RETIRED_MISPRED_BRANCH_TYPE, INDIRECT),
+		.cntr		= { {4, 5, -1}, {6, 7, -1} },
+	},
+	[P4_EVENT_RETIRED_BRANCH_TYPE] = {
+		.opcode		= P4_OPCODE(P4_EVENT_RETIRED_BRANCH_TYPE),
+		.escr_msr	= { MSR_P4_TBPU_ESCR0 , MSR_P4_TBPU_ESCR1 },
+		.escr_emask	=
+			P4_ESCR_EMASK_BIT(P4_EVENT_RETIRED_BRANCH_TYPE, CONDITIONAL)	|
+			P4_ESCR_EMASK_BIT(P4_EVENT_RETIRED_BRANCH_TYPE, CALL)		|
+			P4_ESCR_EMASK_BIT(P4_EVENT_RETIRED_BRANCH_TYPE, RETURN)		|
+			P4_ESCR_EMASK_BIT(P4_EVENT_RETIRED_BRANCH_TYPE, INDIRECT),
+		.cntr		= { {4, 5, -1}, {6, 7, -1} },
+	},
+	[P4_EVENT_RESOURCE_STALL] = {
+		.opcode		= P4_OPCODE(P4_EVENT_RESOURCE_STALL),
+		.escr_msr	= { MSR_P4_ALF_ESCR0, MSR_P4_ALF_ESCR1 },
+		.escr_emask	=
+			P4_ESCR_EMASK_BIT(P4_EVENT_RESOURCE_STALL, SBFULL),
+		.cntr		= { {12, 13, 16}, {14, 15, 17} },
+	},
+	[P4_EVENT_WC_BUFFER] = {
+		.opcode		= P4_OPCODE(P4_EVENT_WC_BUFFER),
+		.escr_msr	= { MSR_P4_DAC_ESCR0, MSR_P4_DAC_ESCR1 },
+		.escr_emask	=
+			P4_ESCR_EMASK_BIT(P4_EVENT_WC_BUFFER, WCB_EVICTS)		|
+			P4_ESCR_EMASK_BIT(P4_EVENT_WC_BUFFER, WCB_FULL_EVICTS),
+		.shared		= 1,
+		.cntr		= { {8, 9, -1}, {10, 11, -1} },
+	},
+	[P4_EVENT_B2B_CYCLES] = {
+		.opcode		= P4_OPCODE(P4_EVENT_B2B_CYCLES),
+		.escr_msr	= { MSR_P4_FSB_ESCR0, MSR_P4_FSB_ESCR1 },
+		.escr_emask	= 0,
+		.cntr		= { {0, -1, -1}, {2, -1, -1} },
+	},
+	[P4_EVENT_BNR] = {
+		.opcode		= P4_OPCODE(P4_EVENT_BNR),
+		.escr_msr	= { MSR_P4_FSB_ESCR0, MSR_P4_FSB_ESCR1 },
+		.escr_emask	= 0,
+		.cntr		= { {0, -1, -1}, {2, -1, -1} },
+	},
+	[P4_EVENT_SNOOP] = {
+		.opcode		= P4_OPCODE(P4_EVENT_SNOOP),
+		.escr_msr	= { MSR_P4_FSB_ESCR0, MSR_P4_FSB_ESCR1 },
+		.escr_emask	= 0,
+		.cntr		= { {0, -1, -1}, {2, -1, -1} },
+	},
+	[P4_EVENT_RESPONSE] = {
+		.opcode		= P4_OPCODE(P4_EVENT_RESPONSE),
+		.escr_msr	= { MSR_P4_FSB_ESCR0, MSR_P4_FSB_ESCR1 },
+		.escr_emask	= 0,
+		.cntr		= { {0, -1, -1}, {2, -1, -1} },
+	},
+	[P4_EVENT_FRONT_END_EVENT] = {
+		.opcode		= P4_OPCODE(P4_EVENT_FRONT_END_EVENT),
+		.escr_msr	= { MSR_P4_CRU_ESCR2, MSR_P4_CRU_ESCR3 },
+		.escr_emask	=
+			P4_ESCR_EMASK_BIT(P4_EVENT_FRONT_END_EVENT, NBOGUS)		|
+			P4_ESCR_EMASK_BIT(P4_EVENT_FRONT_END_EVENT, BOGUS),
+		.cntr		= { {12, 13, 16}, {14, 15, 17} },
+	},
+	[P4_EVENT_EXECUTION_EVENT] = {
+		.opcode		= P4_OPCODE(P4_EVENT_EXECUTION_EVENT),
+		.escr_msr	= { MSR_P4_CRU_ESCR2, MSR_P4_CRU_ESCR3 },
+		.escr_emask	=
+			P4_ESCR_EMASK_BIT(P4_EVENT_EXECUTION_EVENT, NBOGUS0)		|
+			P4_ESCR_EMASK_BIT(P4_EVENT_EXECUTION_EVENT, NBOGUS1)		|
+			P4_ESCR_EMASK_BIT(P4_EVENT_EXECUTION_EVENT, NBOGUS2)		|
+			P4_ESCR_EMASK_BIT(P4_EVENT_EXECUTION_EVENT, NBOGUS3)		|
+			P4_ESCR_EMASK_BIT(P4_EVENT_EXECUTION_EVENT, BOGUS0)		|
+			P4_ESCR_EMASK_BIT(P4_EVENT_EXECUTION_EVENT, BOGUS1)		|
+			P4_ESCR_EMASK_BIT(P4_EVENT_EXECUTION_EVENT, BOGUS2)		|
+			P4_ESCR_EMASK_BIT(P4_EVENT_EXECUTION_EVENT, BOGUS3),
+		.cntr		= { {12, 13, 16}, {14, 15, 17} },
+	},
+	[P4_EVENT_REPLAY_EVENT] = {
+		.opcode		= P4_OPCODE(P4_EVENT_REPLAY_EVENT),
+		.escr_msr	= { MSR_P4_CRU_ESCR2, MSR_P4_CRU_ESCR3 },
+		.escr_emask	=
+			P4_ESCR_EMASK_BIT(P4_EVENT_REPLAY_EVENT, NBOGUS)		|
+			P4_ESCR_EMASK_BIT(P4_EVENT_REPLAY_EVENT, BOGUS),
+		.cntr		= { {12, 13, 16}, {14, 15, 17} },
+	},
+	[P4_EVENT_INSTR_RETIRED] = {
+		.opcode		= P4_OPCODE(P4_EVENT_INSTR_RETIRED),
+		.escr_msr	= { MSR_P4_CRU_ESCR0, MSR_P4_CRU_ESCR1 },
+		.escr_emask	=
+			P4_ESCR_EMASK_BIT(P4_EVENT_INSTR_RETIRED, NBOGUSNTAG)		|
+			P4_ESCR_EMASK_BIT(P4_EVENT_INSTR_RETIRED, NBOGUSTAG)		|
+			P4_ESCR_EMASK_BIT(P4_EVENT_INSTR_RETIRED, BOGUSNTAG)		|
+			P4_ESCR_EMASK_BIT(P4_EVENT_INSTR_RETIRED, BOGUSTAG),
+		.cntr		= { {12, 13, 16}, {14, 15, 17} },
+	},
+	[P4_EVENT_UOPS_RETIRED] = {
+		.opcode		= P4_OPCODE(P4_EVENT_UOPS_RETIRED),
+		.escr_msr	= { MSR_P4_CRU_ESCR0, MSR_P4_CRU_ESCR1 },
+		.escr_emask	=
+			P4_ESCR_EMASK_BIT(P4_EVENT_UOPS_RETIRED, NBOGUS)		|
+			P4_ESCR_EMASK_BIT(P4_EVENT_UOPS_RETIRED, BOGUS),
+		.cntr		= { {12, 13, 16}, {14, 15, 17} },
+	},
+	[P4_EVENT_UOP_TYPE] = {
+		.opcode		= P4_OPCODE(P4_EVENT_UOP_TYPE),
+		.escr_msr	= { MSR_P4_RAT_ESCR0, MSR_P4_RAT_ESCR1 },
+		.escr_emask	=
+			P4_ESCR_EMASK_BIT(P4_EVENT_UOP_TYPE, TAGLOADS)			|
+			P4_ESCR_EMASK_BIT(P4_EVENT_UOP_TYPE, TAGSTORES),
+		.cntr		= { {12, 13, 16}, {14, 15, 17} },
+	},
+	[P4_EVENT_BRANCH_RETIRED] = {
+		.opcode		= P4_OPCODE(P4_EVENT_BRANCH_RETIRED),
+		.escr_msr	= { MSR_P4_CRU_ESCR2, MSR_P4_CRU_ESCR3 },
+		.escr_emask	=
+			P4_ESCR_EMASK_BIT(P4_EVENT_BRANCH_RETIRED, MMNP)		|
+			P4_ESCR_EMASK_BIT(P4_EVENT_BRANCH_RETIRED, MMNM)		|
+			P4_ESCR_EMASK_BIT(P4_EVENT_BRANCH_RETIRED, MMTP)		|
+			P4_ESCR_EMASK_BIT(P4_EVENT_BRANCH_RETIRED, MMTM),
+		.cntr		= { {12, 13, 16}, {14, 15, 17} },
+	},
+	[P4_EVENT_MISPRED_BRANCH_RETIRED] = {
+		.opcode		= P4_OPCODE(P4_EVENT_MISPRED_BRANCH_RETIRED),
+		.escr_msr	= { MSR_P4_CRU_ESCR0, MSR_P4_CRU_ESCR1 },
+		.escr_emask	=
+			P4_ESCR_EMASK_BIT(P4_EVENT_MISPRED_BRANCH_RETIRED, NBOGUS),
+		.cntr		= { {12, 13, 16}, {14, 15, 17} },
+	},
+	[P4_EVENT_X87_ASSIST] = {
+		.opcode		= P4_OPCODE(P4_EVENT_X87_ASSIST),
+		.escr_msr	= { MSR_P4_CRU_ESCR2, MSR_P4_CRU_ESCR3 },
+		.escr_emask	=
+			P4_ESCR_EMASK_BIT(P4_EVENT_X87_ASSIST, FPSU)			|
+			P4_ESCR_EMASK_BIT(P4_EVENT_X87_ASSIST, FPSO)			|
+			P4_ESCR_EMASK_BIT(P4_EVENT_X87_ASSIST, POAO)			|
+			P4_ESCR_EMASK_BIT(P4_EVENT_X87_ASSIST, POAU)			|
+			P4_ESCR_EMASK_BIT(P4_EVENT_X87_ASSIST, PREA),
+		.cntr		= { {12, 13, 16}, {14, 15, 17} },
+	},
+	[P4_EVENT_MACHINE_CLEAR] = {
+		.opcode		= P4_OPCODE(P4_EVENT_MACHINE_CLEAR),
+		.escr_msr	= { MSR_P4_CRU_ESCR2, MSR_P4_CRU_ESCR3 },
+		.escr_emask	=
+			P4_ESCR_EMASK_BIT(P4_EVENT_MACHINE_CLEAR, CLEAR)		|
+			P4_ESCR_EMASK_BIT(P4_EVENT_MACHINE_CLEAR, MOCLEAR)		|
+			P4_ESCR_EMASK_BIT(P4_EVENT_MACHINE_CLEAR, SMCLEAR),
+		.cntr		= { {12, 13, 16}, {14, 15, 17} },
+	},
+	[P4_EVENT_INSTR_COMPLETED] = {
+		.opcode		= P4_OPCODE(P4_EVENT_INSTR_COMPLETED),
+		.escr_msr	= { MSR_P4_CRU_ESCR0, MSR_P4_CRU_ESCR1 },
+		.escr_emask	=
+			P4_ESCR_EMASK_BIT(P4_EVENT_INSTR_COMPLETED, NBOGUS)		|
+			P4_ESCR_EMASK_BIT(P4_EVENT_INSTR_COMPLETED, BOGUS),
+		.cntr		= { {12, 13, 16}, {14, 15, 17} },
+	},
+};
+
+#define P4_GEN_CACHE_EVENT(event, bit, metric)				  \
+	p4_config_pack_escr(P4_ESCR_EVENT(event)			| \
+			    P4_ESCR_EMASK_BIT(event, bit))		| \
+	p4_config_pack_cccr(metric					| \
+			    P4_CCCR_ESEL(P4_OPCODE_ESEL(P4_OPCODE(event))))
+
+static __initconst const u64 p4_hw_cache_event_ids
+				[PERF_COUNT_HW_CACHE_MAX]
+				[PERF_COUNT_HW_CACHE_OP_MAX]
+				[PERF_COUNT_HW_CACHE_RESULT_MAX] =
+{
+ [ C(L1D ) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = 0x0,
+		[ C(RESULT_MISS)   ] = P4_GEN_CACHE_EVENT(P4_EVENT_REPLAY_EVENT, NBOGUS,
+						P4_PEBS_METRIC__1stl_cache_load_miss_retired),
+	},
+ },
+ [ C(LL  ) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = 0x0,
+		[ C(RESULT_MISS)   ] = P4_GEN_CACHE_EVENT(P4_EVENT_REPLAY_EVENT, NBOGUS,
+						P4_PEBS_METRIC__2ndl_cache_load_miss_retired),
+	},
+},
+ [ C(DTLB) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = 0x0,
+		[ C(RESULT_MISS)   ] = P4_GEN_CACHE_EVENT(P4_EVENT_REPLAY_EVENT, NBOGUS,
+						P4_PEBS_METRIC__dtlb_load_miss_retired),
+	},
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = 0x0,
+		[ C(RESULT_MISS)   ] = P4_GEN_CACHE_EVENT(P4_EVENT_REPLAY_EVENT, NBOGUS,
+						P4_PEBS_METRIC__dtlb_store_miss_retired),
+	},
+ },
+ [ C(ITLB) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = P4_GEN_CACHE_EVENT(P4_EVENT_ITLB_REFERENCE, HIT,
+						P4_PEBS_METRIC__none),
+		[ C(RESULT_MISS)   ] = P4_GEN_CACHE_EVENT(P4_EVENT_ITLB_REFERENCE, MISS,
+						P4_PEBS_METRIC__none),
+	},
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = -1,
+		[ C(RESULT_MISS)   ] = -1,
+	},
+	[ C(OP_PREFETCH) ] = {
+		[ C(RESULT_ACCESS) ] = -1,
+		[ C(RESULT_MISS)   ] = -1,
+	},
+ },
+ [ C(NODE) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = -1,
+		[ C(RESULT_MISS)   ] = -1,
+	},
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = -1,
+		[ C(RESULT_MISS)   ] = -1,
+	},
+	[ C(OP_PREFETCH) ] = {
+		[ C(RESULT_ACCESS) ] = -1,
+		[ C(RESULT_MISS)   ] = -1,
+	},
+ },
+};
+
+/*
+ * Because of Netburst being quite restricted in how many
+ * identical events may run simultaneously, we introduce event aliases,
+ * ie the different events which have the same functionality but
+ * utilize non-intersected resources (ESCR/CCCR/counter registers).
+ *
+ * This allow us to relax restrictions a bit and run two or more
+ * identical events together.
+ *
+ * Never set any custom internal bits such as P4_CONFIG_HT,
+ * P4_CONFIG_ALIASABLE or bits for P4_PEBS_METRIC, they are
+ * either up to date automatically or not applicable at all.
+ */
+struct p4_event_alias {
+	u64 original;
+	u64 alternative;
+} p4_event_aliases[] = {
+	{
+		/*
+		 * Non-halted cycles can be substituted with non-sleeping cycles (see
+		 * Intel SDM Vol3b for details). We need this alias to be able
+		 * to run nmi-watchdog and 'perf top' (or any other user space tool
+		 * which is interested in running PERF_COUNT_HW_CPU_CYCLES)
+		 * simultaneously.
+		 */
+	.original	=
+		p4_config_pack_escr(P4_ESCR_EVENT(P4_EVENT_GLOBAL_POWER_EVENTS)		|
+				    P4_ESCR_EMASK_BIT(P4_EVENT_GLOBAL_POWER_EVENTS, RUNNING)),
+	.alternative	=
+		p4_config_pack_escr(P4_ESCR_EVENT(P4_EVENT_EXECUTION_EVENT)		|
+				    P4_ESCR_EMASK_BIT(P4_EVENT_EXECUTION_EVENT, NBOGUS0)|
+				    P4_ESCR_EMASK_BIT(P4_EVENT_EXECUTION_EVENT, NBOGUS1)|
+				    P4_ESCR_EMASK_BIT(P4_EVENT_EXECUTION_EVENT, NBOGUS2)|
+				    P4_ESCR_EMASK_BIT(P4_EVENT_EXECUTION_EVENT, NBOGUS3)|
+				    P4_ESCR_EMASK_BIT(P4_EVENT_EXECUTION_EVENT, BOGUS0)	|
+				    P4_ESCR_EMASK_BIT(P4_EVENT_EXECUTION_EVENT, BOGUS1)	|
+				    P4_ESCR_EMASK_BIT(P4_EVENT_EXECUTION_EVENT, BOGUS2)	|
+				    P4_ESCR_EMASK_BIT(P4_EVENT_EXECUTION_EVENT, BOGUS3))|
+		p4_config_pack_cccr(P4_CCCR_THRESHOLD(15) | P4_CCCR_COMPLEMENT		|
+				    P4_CCCR_COMPARE),
+	},
+};
+
+static u64 p4_get_alias_event(u64 config)
+{
+	u64 config_match;
+	int i;
+
+	/*
+	 * Only event with special mark is allowed,
+	 * we're to be sure it didn't come as malformed
+	 * RAW event.
+	 */
+	if (!(config & P4_CONFIG_ALIASABLE))
+		return 0;
+
+	config_match = config & P4_CONFIG_EVENT_ALIAS_MASK;
+
+	for (i = 0; i < ARRAY_SIZE(p4_event_aliases); i++) {
+		if (config_match == p4_event_aliases[i].original) {
+			config_match = p4_event_aliases[i].alternative;
+			break;
+		} else if (config_match == p4_event_aliases[i].alternative) {
+			config_match = p4_event_aliases[i].original;
+			break;
+		}
+	}
+
+	if (i >= ARRAY_SIZE(p4_event_aliases))
+		return 0;
+
+	return config_match | (config & P4_CONFIG_EVENT_ALIAS_IMMUTABLE_BITS);
+}
+
+static u64 p4_general_events[PERF_COUNT_HW_MAX] = {
+  /* non-halted CPU clocks */
+  [PERF_COUNT_HW_CPU_CYCLES] =
+	p4_config_pack_escr(P4_ESCR_EVENT(P4_EVENT_GLOBAL_POWER_EVENTS)		|
+		P4_ESCR_EMASK_BIT(P4_EVENT_GLOBAL_POWER_EVENTS, RUNNING))	|
+		P4_CONFIG_ALIASABLE,
+
+  /*
+   * retired instructions
+   * in a sake of simplicity we don't use the FSB tagging
+   */
+  [PERF_COUNT_HW_INSTRUCTIONS] =
+	p4_config_pack_escr(P4_ESCR_EVENT(P4_EVENT_INSTR_RETIRED)		|
+		P4_ESCR_EMASK_BIT(P4_EVENT_INSTR_RETIRED, NBOGUSNTAG)		|
+		P4_ESCR_EMASK_BIT(P4_EVENT_INSTR_RETIRED, BOGUSNTAG)),
+
+  /* cache hits */
+  [PERF_COUNT_HW_CACHE_REFERENCES] =
+	p4_config_pack_escr(P4_ESCR_EVENT(P4_EVENT_BSQ_CACHE_REFERENCE)		|
+		P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_CACHE_REFERENCE, RD_2ndL_HITS)	|
+		P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_CACHE_REFERENCE, RD_2ndL_HITE)	|
+		P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_CACHE_REFERENCE, RD_2ndL_HITM)	|
+		P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_CACHE_REFERENCE, RD_3rdL_HITS)	|
+		P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_CACHE_REFERENCE, RD_3rdL_HITE)	|
+		P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_CACHE_REFERENCE, RD_3rdL_HITM)),
+
+  /* cache misses */
+  [PERF_COUNT_HW_CACHE_MISSES] =
+	p4_config_pack_escr(P4_ESCR_EVENT(P4_EVENT_BSQ_CACHE_REFERENCE)		|
+		P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_CACHE_REFERENCE, RD_2ndL_MISS)	|
+		P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_CACHE_REFERENCE, RD_3rdL_MISS)	|
+		P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_CACHE_REFERENCE, WR_2ndL_MISS)),
+
+  /* branch instructions retired */
+  [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] =
+	p4_config_pack_escr(P4_ESCR_EVENT(P4_EVENT_RETIRED_BRANCH_TYPE)		|
+		P4_ESCR_EMASK_BIT(P4_EVENT_RETIRED_BRANCH_TYPE, CONDITIONAL)	|
+		P4_ESCR_EMASK_BIT(P4_EVENT_RETIRED_BRANCH_TYPE, CALL)		|
+		P4_ESCR_EMASK_BIT(P4_EVENT_RETIRED_BRANCH_TYPE, RETURN)		|
+		P4_ESCR_EMASK_BIT(P4_EVENT_RETIRED_BRANCH_TYPE, INDIRECT)),
+
+  /* mispredicted branches retired */
+  [PERF_COUNT_HW_BRANCH_MISSES]	=
+	p4_config_pack_escr(P4_ESCR_EVENT(P4_EVENT_MISPRED_BRANCH_RETIRED)	|
+		P4_ESCR_EMASK_BIT(P4_EVENT_MISPRED_BRANCH_RETIRED, NBOGUS)),
+
+  /* bus ready clocks (cpu is driving #DRDY_DRV\#DRDY_OWN):  */
+  [PERF_COUNT_HW_BUS_CYCLES] =
+	p4_config_pack_escr(P4_ESCR_EVENT(P4_EVENT_FSB_DATA_ACTIVITY)		|
+		P4_ESCR_EMASK_BIT(P4_EVENT_FSB_DATA_ACTIVITY, DRDY_DRV)		|
+		P4_ESCR_EMASK_BIT(P4_EVENT_FSB_DATA_ACTIVITY, DRDY_OWN))	|
+	p4_config_pack_cccr(P4_CCCR_EDGE | P4_CCCR_COMPARE),
+};
+
+static struct p4_event_bind *p4_config_get_bind(u64 config)
+{
+	unsigned int evnt = p4_config_unpack_event(config);
+	struct p4_event_bind *bind = NULL;
+
+	if (evnt < ARRAY_SIZE(p4_event_bind_map))
+		bind = &p4_event_bind_map[evnt];
+
+	return bind;
+}
+
+static u64 p4_pmu_event_map(int hw_event)
+{
+	struct p4_event_bind *bind;
+	unsigned int esel;
+	u64 config;
+
+	config = p4_general_events[hw_event];
+	bind = p4_config_get_bind(config);
+	esel = P4_OPCODE_ESEL(bind->opcode);
+	config |= p4_config_pack_cccr(P4_CCCR_ESEL(esel));
+
+	return config;
+}
+
+/* check cpu model specifics */
+static bool p4_event_match_cpu_model(unsigned int event_idx)
+{
+	/* INSTR_COMPLETED event only exist for model 3, 4, 6 (Prescott) */
+	if (event_idx == P4_EVENT_INSTR_COMPLETED) {
+		if (boot_cpu_data.x86_model != 3 &&
+			boot_cpu_data.x86_model != 4 &&
+			boot_cpu_data.x86_model != 6)
+			return false;
+	}
+
+	/*
+	 * For info
+	 * - IQ_ESCR0, IQ_ESCR1 only for models 1 and 2
+	 */
+
+	return true;
+}
+
+static int p4_validate_raw_event(struct perf_event *event)
+{
+	unsigned int v, emask;
+
+	/* User data may have out-of-bound event index */
+	v = p4_config_unpack_event(event->attr.config);
+	if (v >= ARRAY_SIZE(p4_event_bind_map))
+		return -EINVAL;
+
+	/* It may be unsupported: */
+	if (!p4_event_match_cpu_model(v))
+		return -EINVAL;
+
+	/*
+	 * NOTE: P4_CCCR_THREAD_ANY has not the same meaning as
+	 * in Architectural Performance Monitoring, it means not
+	 * on _which_ logical cpu to count but rather _when_, ie it
+	 * depends on logical cpu state -- count event if one cpu active,
+	 * none, both or any, so we just allow user to pass any value
+	 * desired.
+	 *
+	 * In turn we always set Tx_OS/Tx_USR bits bound to logical
+	 * cpu without their propagation to another cpu
+	 */
+
+	/*
+	 * if an event is shared across the logical threads
+	 * the user needs special permissions to be able to use it
+	 */
+	if (p4_ht_active() && p4_event_bind_map[v].shared) {
+		if (perf_paranoid_cpu() && !capable(CAP_SYS_ADMIN))
+			return -EACCES;
+	}
+
+	/* ESCR EventMask bits may be invalid */
+	emask = p4_config_unpack_escr(event->attr.config) & P4_ESCR_EVENTMASK_MASK;
+	if (emask & ~p4_event_bind_map[v].escr_emask)
+		return -EINVAL;
+
+	/*
+	 * it may have some invalid PEBS bits
+	 */
+	if (p4_config_pebs_has(event->attr.config, P4_PEBS_CONFIG_ENABLE))
+		return -EINVAL;
+
+	v = p4_config_unpack_metric(event->attr.config);
+	if (v >= ARRAY_SIZE(p4_pebs_bind_map))
+		return -EINVAL;
+
+	return 0;
+}
+
+static int p4_hw_config(struct perf_event *event)
+{
+	int cpu = get_cpu();
+	int rc = 0;
+	u32 escr, cccr;
+
+	/*
+	 * the reason we use cpu that early is that: if we get scheduled
+	 * first time on the same cpu -- we will not need swap thread
+	 * specific flags in config (and will save some cpu cycles)
+	 */
+
+	cccr = p4_default_cccr_conf(cpu);
+	escr = p4_default_escr_conf(cpu, event->attr.exclude_kernel,
+					 event->attr.exclude_user);
+	event->hw.config = p4_config_pack_escr(escr) |
+			   p4_config_pack_cccr(cccr);
+
+	if (p4_ht_active() && p4_ht_thread(cpu))
+		event->hw.config = p4_set_ht_bit(event->hw.config);
+
+	if (event->attr.type == PERF_TYPE_RAW) {
+		struct p4_event_bind *bind;
+		unsigned int esel;
+		/*
+		 * Clear bits we reserve to be managed by kernel itself
+		 * and never allowed from a user space
+		 */
+		 event->attr.config &= P4_CONFIG_MASK;
+
+		rc = p4_validate_raw_event(event);
+		if (rc)
+			goto out;
+
+		/*
+		 * Note that for RAW events we allow user to use P4_CCCR_RESERVED
+		 * bits since we keep additional info here (for cache events and etc)
+		 */
+		event->hw.config |= event->attr.config;
+		bind = p4_config_get_bind(event->attr.config);
+		if (!bind) {
+			rc = -EINVAL;
+			goto out;
+		}
+		esel = P4_OPCODE_ESEL(bind->opcode);
+		event->hw.config |= p4_config_pack_cccr(P4_CCCR_ESEL(esel));
+	}
+
+	rc = x86_setup_perfctr(event);
+out:
+	put_cpu();
+	return rc;
+}
+
+static inline int p4_pmu_clear_cccr_ovf(struct hw_perf_event *hwc)
+{
+	u64 v;
+
+	/* an official way for overflow indication */
+	rdmsrl(hwc->config_base, v);
+	if (v & P4_CCCR_OVF) {
+		wrmsrl(hwc->config_base, v & ~P4_CCCR_OVF);
+		return 1;
+	}
+
+	/*
+	 * In some circumstances the overflow might issue an NMI but did
+	 * not set P4_CCCR_OVF bit. Because a counter holds a negative value
+	 * we simply check for high bit being set, if it's cleared it means
+	 * the counter has reached zero value and continued counting before
+	 * real NMI signal was received:
+	 */
+	rdmsrl(hwc->event_base, v);
+	if (!(v & ARCH_P4_UNFLAGGED_BIT))
+		return 1;
+
+	return 0;
+}
+
+static void p4_pmu_disable_pebs(void)
+{
+	/*
+	 * FIXME
+	 *
+	 * It's still allowed that two threads setup same cache
+	 * events so we can't simply clear metrics until we knew
+	 * no one is depending on us, so we need kind of counter
+	 * for "ReplayEvent" users.
+	 *
+	 * What is more complex -- RAW events, if user (for some
+	 * reason) will pass some cache event metric with improper
+	 * event opcode -- it's fine from hardware point of view
+	 * but completely nonsense from "meaning" of such action.
+	 *
+	 * So at moment let leave metrics turned on forever -- it's
+	 * ok for now but need to be revisited!
+	 *
+	 * (void)wrmsrl_safe(MSR_IA32_PEBS_ENABLE, 0);
+	 * (void)wrmsrl_safe(MSR_P4_PEBS_MATRIX_VERT, 0);
+	 */
+}
+
+static inline void p4_pmu_disable_event(struct perf_event *event)
+{
+	struct hw_perf_event *hwc = &event->hw;
+
+	/*
+	 * If event gets disabled while counter is in overflowed
+	 * state we need to clear P4_CCCR_OVF, otherwise interrupt get
+	 * asserted again and again
+	 */
+	(void)wrmsrl_safe(hwc->config_base,
+		p4_config_unpack_cccr(hwc->config) & ~P4_CCCR_ENABLE & ~P4_CCCR_OVF & ~P4_CCCR_RESERVED);
+}
+
+static void p4_pmu_disable_all(void)
+{
+	struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
+	int idx;
+
+	for (idx = 0; idx < x86_pmu.num_counters; idx++) {
+		struct perf_event *event = cpuc->events[idx];
+		if (!test_bit(idx, cpuc->active_mask))
+			continue;
+		p4_pmu_disable_event(event);
+	}
+
+	p4_pmu_disable_pebs();
+}
+
+/* configuration must be valid */
+static void p4_pmu_enable_pebs(u64 config)
+{
+	struct p4_pebs_bind *bind;
+	unsigned int idx;
+
+	BUILD_BUG_ON(P4_PEBS_METRIC__max > P4_PEBS_CONFIG_METRIC_MASK);
+
+	idx = p4_config_unpack_metric(config);
+	if (idx == P4_PEBS_METRIC__none)
+		return;
+
+	bind = &p4_pebs_bind_map[idx];
+
+	(void)wrmsrl_safe(MSR_IA32_PEBS_ENABLE,	(u64)bind->metric_pebs);
+	(void)wrmsrl_safe(MSR_P4_PEBS_MATRIX_VERT,	(u64)bind->metric_vert);
+}
+
+static void p4_pmu_enable_event(struct perf_event *event)
+{
+	struct hw_perf_event *hwc = &event->hw;
+	int thread = p4_ht_config_thread(hwc->config);
+	u64 escr_conf = p4_config_unpack_escr(p4_clear_ht_bit(hwc->config));
+	unsigned int idx = p4_config_unpack_event(hwc->config);
+	struct p4_event_bind *bind;
+	u64 escr_addr, cccr;
+
+	bind = &p4_event_bind_map[idx];
+	escr_addr = bind->escr_msr[thread];
+
+	/*
+	 * - we dont support cascaded counters yet
+	 * - and counter 1 is broken (erratum)
+	 */
+	WARN_ON_ONCE(p4_is_event_cascaded(hwc->config));
+	WARN_ON_ONCE(hwc->idx == 1);
+
+	/* we need a real Event value */
+	escr_conf &= ~P4_ESCR_EVENT_MASK;
+	escr_conf |= P4_ESCR_EVENT(P4_OPCODE_EVNT(bind->opcode));
+
+	cccr = p4_config_unpack_cccr(hwc->config);
+
+	/*
+	 * it could be Cache event so we need to write metrics
+	 * into additional MSRs
+	 */
+	p4_pmu_enable_pebs(hwc->config);
+
+	(void)wrmsrl_safe(escr_addr, escr_conf);
+	(void)wrmsrl_safe(hwc->config_base,
+				(cccr & ~P4_CCCR_RESERVED) | P4_CCCR_ENABLE);
+}
+
+static void p4_pmu_enable_all(int added)
+{
+	struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
+	int idx;
+
+	for (idx = 0; idx < x86_pmu.num_counters; idx++) {
+		struct perf_event *event = cpuc->events[idx];
+		if (!test_bit(idx, cpuc->active_mask))
+			continue;
+		p4_pmu_enable_event(event);
+	}
+}
+
+static int p4_pmu_handle_irq(struct pt_regs *regs)
+{
+	struct perf_sample_data data;
+	struct cpu_hw_events *cpuc;
+	struct perf_event *event;
+	struct hw_perf_event *hwc;
+	int idx, handled = 0;
+	u64 val;
+
+	cpuc = this_cpu_ptr(&cpu_hw_events);
+
+	for (idx = 0; idx < x86_pmu.num_counters; idx++) {
+		int overflow;
+
+		if (!test_bit(idx, cpuc->active_mask)) {
+			/* catch in-flight IRQs */
+			if (__test_and_clear_bit(idx, cpuc->running))
+				handled++;
+			continue;
+		}
+
+		event = cpuc->events[idx];
+		hwc = &event->hw;
+
+		WARN_ON_ONCE(hwc->idx != idx);
+
+		/* it might be unflagged overflow */
+		overflow = p4_pmu_clear_cccr_ovf(hwc);
+
+		val = x86_perf_event_update(event);
+		if (!overflow && (val & (1ULL << (x86_pmu.cntval_bits - 1))))
+			continue;
+
+		handled += overflow;
+
+		/* event overflow for sure */
+		perf_sample_data_init(&data, 0, hwc->last_period);
+
+		if (!x86_perf_event_set_period(event))
+			continue;
+
+
+		if (perf_event_overflow(event, &data, regs))
+			x86_pmu_stop(event, 0);
+	}
+
+	if (handled)
+		inc_irq_stat(apic_perf_irqs);
+
+	/*
+	 * When dealing with the unmasking of the LVTPC on P4 perf hw, it has
+	 * been observed that the OVF bit flag has to be cleared first _before_
+	 * the LVTPC can be unmasked.
+	 *
+	 * The reason is the NMI line will continue to be asserted while the OVF
+	 * bit is set.  This causes a second NMI to generate if the LVTPC is
+	 * unmasked before the OVF bit is cleared, leading to unknown NMI
+	 * messages.
+	 */
+	apic_write(APIC_LVTPC, APIC_DM_NMI);
+
+	return handled;
+}
+
+/*
+ * swap thread specific fields according to a thread
+ * we are going to run on
+ */
+static void p4_pmu_swap_config_ts(struct hw_perf_event *hwc, int cpu)
+{
+	u32 escr, cccr;
+
+	/*
+	 * we either lucky and continue on same cpu or no HT support
+	 */
+	if (!p4_should_swap_ts(hwc->config, cpu))
+		return;
+
+	/*
+	 * the event is migrated from an another logical
+	 * cpu, so we need to swap thread specific flags
+	 */
+
+	escr = p4_config_unpack_escr(hwc->config);
+	cccr = p4_config_unpack_cccr(hwc->config);
+
+	if (p4_ht_thread(cpu)) {
+		cccr &= ~P4_CCCR_OVF_PMI_T0;
+		cccr |= P4_CCCR_OVF_PMI_T1;
+		if (escr & P4_ESCR_T0_OS) {
+			escr &= ~P4_ESCR_T0_OS;
+			escr |= P4_ESCR_T1_OS;
+		}
+		if (escr & P4_ESCR_T0_USR) {
+			escr &= ~P4_ESCR_T0_USR;
+			escr |= P4_ESCR_T1_USR;
+		}
+		hwc->config  = p4_config_pack_escr(escr);
+		hwc->config |= p4_config_pack_cccr(cccr);
+		hwc->config |= P4_CONFIG_HT;
+	} else {
+		cccr &= ~P4_CCCR_OVF_PMI_T1;
+		cccr |= P4_CCCR_OVF_PMI_T0;
+		if (escr & P4_ESCR_T1_OS) {
+			escr &= ~P4_ESCR_T1_OS;
+			escr |= P4_ESCR_T0_OS;
+		}
+		if (escr & P4_ESCR_T1_USR) {
+			escr &= ~P4_ESCR_T1_USR;
+			escr |= P4_ESCR_T0_USR;
+		}
+		hwc->config  = p4_config_pack_escr(escr);
+		hwc->config |= p4_config_pack_cccr(cccr);
+		hwc->config &= ~P4_CONFIG_HT;
+	}
+}
+
+/*
+ * ESCR address hashing is tricky, ESCRs are not sequential
+ * in memory but all starts from MSR_P4_BSU_ESCR0 (0x03a0) and
+ * the metric between any ESCRs is laid in range [0xa0,0xe1]
+ *
+ * so we make ~70% filled hashtable
+ */
+
+#define P4_ESCR_MSR_BASE		0x000003a0
+#define P4_ESCR_MSR_MAX			0x000003e1
+#define P4_ESCR_MSR_TABLE_SIZE		(P4_ESCR_MSR_MAX - P4_ESCR_MSR_BASE + 1)
+#define P4_ESCR_MSR_IDX(msr)		(msr - P4_ESCR_MSR_BASE)
+#define P4_ESCR_MSR_TABLE_ENTRY(msr)	[P4_ESCR_MSR_IDX(msr)] = msr
+
+static const unsigned int p4_escr_table[P4_ESCR_MSR_TABLE_SIZE] = {
+	P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_ALF_ESCR0),
+	P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_ALF_ESCR1),
+	P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_BPU_ESCR0),
+	P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_BPU_ESCR1),
+	P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_BSU_ESCR0),
+	P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_BSU_ESCR1),
+	P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_CRU_ESCR0),
+	P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_CRU_ESCR1),
+	P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_CRU_ESCR2),
+	P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_CRU_ESCR3),
+	P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_CRU_ESCR4),
+	P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_CRU_ESCR5),
+	P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_DAC_ESCR0),
+	P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_DAC_ESCR1),
+	P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_FIRM_ESCR0),
+	P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_FIRM_ESCR1),
+	P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_FLAME_ESCR0),
+	P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_FLAME_ESCR1),
+	P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_FSB_ESCR0),
+	P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_FSB_ESCR1),
+	P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_IQ_ESCR0),
+	P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_IQ_ESCR1),
+	P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_IS_ESCR0),
+	P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_IS_ESCR1),
+	P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_ITLB_ESCR0),
+	P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_ITLB_ESCR1),
+	P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_IX_ESCR0),
+	P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_IX_ESCR1),
+	P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_MOB_ESCR0),
+	P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_MOB_ESCR1),
+	P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_MS_ESCR0),
+	P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_MS_ESCR1),
+	P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_PMH_ESCR0),
+	P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_PMH_ESCR1),
+	P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_RAT_ESCR0),
+	P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_RAT_ESCR1),
+	P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_SAAT_ESCR0),
+	P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_SAAT_ESCR1),
+	P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_SSU_ESCR0),
+	P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_SSU_ESCR1),
+	P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_TBPU_ESCR0),
+	P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_TBPU_ESCR1),
+	P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_TC_ESCR0),
+	P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_TC_ESCR1),
+	P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_U2L_ESCR0),
+	P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_U2L_ESCR1),
+};
+
+static int p4_get_escr_idx(unsigned int addr)
+{
+	unsigned int idx = P4_ESCR_MSR_IDX(addr);
+
+	if (unlikely(idx >= P4_ESCR_MSR_TABLE_SIZE	||
+			!p4_escr_table[idx]		||
+			p4_escr_table[idx] != addr)) {
+		WARN_ONCE(1, "P4 PMU: Wrong address passed: %x\n", addr);
+		return -1;
+	}
+
+	return idx;
+}
+
+static int p4_next_cntr(int thread, unsigned long *used_mask,
+			struct p4_event_bind *bind)
+{
+	int i, j;
+
+	for (i = 0; i < P4_CNTR_LIMIT; i++) {
+		j = bind->cntr[thread][i];
+		if (j != -1 && !test_bit(j, used_mask))
+			return j;
+	}
+
+	return -1;
+}
+
+static int p4_pmu_schedule_events(struct cpu_hw_events *cpuc, int n, int *assign)
+{
+	unsigned long used_mask[BITS_TO_LONGS(X86_PMC_IDX_MAX)];
+	unsigned long escr_mask[BITS_TO_LONGS(P4_ESCR_MSR_TABLE_SIZE)];
+	int cpu = smp_processor_id();
+	struct hw_perf_event *hwc;
+	struct p4_event_bind *bind;
+	unsigned int i, thread, num;
+	int cntr_idx, escr_idx;
+	u64 config_alias;
+	int pass;
+
+	bitmap_zero(used_mask, X86_PMC_IDX_MAX);
+	bitmap_zero(escr_mask, P4_ESCR_MSR_TABLE_SIZE);
+
+	for (i = 0, num = n; i < n; i++, num--) {
+
+		hwc = &cpuc->event_list[i]->hw;
+		thread = p4_ht_thread(cpu);
+		pass = 0;
+
+again:
+		/*
+		 * It's possible to hit a circular lock
+		 * between original and alternative events
+		 * if both are scheduled already.
+		 */
+		if (pass > 2)
+			goto done;
+
+		bind = p4_config_get_bind(hwc->config);
+		escr_idx = p4_get_escr_idx(bind->escr_msr[thread]);
+		if (unlikely(escr_idx == -1))
+			goto done;
+
+		if (hwc->idx != -1 && !p4_should_swap_ts(hwc->config, cpu)) {
+			cntr_idx = hwc->idx;
+			if (assign)
+				assign[i] = hwc->idx;
+			goto reserve;
+		}
+
+		cntr_idx = p4_next_cntr(thread, used_mask, bind);
+		if (cntr_idx == -1 || test_bit(escr_idx, escr_mask)) {
+			/*
+			 * Check whether an event alias is still available.
+			 */
+			config_alias = p4_get_alias_event(hwc->config);
+			if (!config_alias)
+				goto done;
+			hwc->config = config_alias;
+			pass++;
+			goto again;
+		}
+		/*
+		 * Perf does test runs to see if a whole group can be assigned
+		 * together succesfully.  There can be multiple rounds of this.
+		 * Unfortunately, p4_pmu_swap_config_ts touches the hwc->config
+		 * bits, such that the next round of group assignments will
+		 * cause the above p4_should_swap_ts to pass instead of fail.
+		 * This leads to counters exclusive to thread0 being used by
+		 * thread1.
+		 *
+		 * Solve this with a cheap hack, reset the idx back to -1 to
+		 * force a new lookup (p4_next_cntr) to get the right counter
+		 * for the right thread.
+		 *
+		 * This probably doesn't comply with the general spirit of how
+		 * perf wants to work, but P4 is special. :-(
+		 */
+		if (p4_should_swap_ts(hwc->config, cpu))
+			hwc->idx = -1;
+		p4_pmu_swap_config_ts(hwc, cpu);
+		if (assign)
+			assign[i] = cntr_idx;
+reserve:
+		set_bit(cntr_idx, used_mask);
+		set_bit(escr_idx, escr_mask);
+	}
+
+done:
+	return num ? -EINVAL : 0;
+}
+
+PMU_FORMAT_ATTR(cccr, "config:0-31" );
+PMU_FORMAT_ATTR(escr, "config:32-62");
+PMU_FORMAT_ATTR(ht,   "config:63"   );
+
+static struct attribute *intel_p4_formats_attr[] = {
+	&format_attr_cccr.attr,
+	&format_attr_escr.attr,
+	&format_attr_ht.attr,
+	NULL,
+};
+
+static __initconst const struct x86_pmu p4_pmu = {
+	.name			= "Netburst P4/Xeon",
+	.handle_irq		= p4_pmu_handle_irq,
+	.disable_all		= p4_pmu_disable_all,
+	.enable_all		= p4_pmu_enable_all,
+	.enable			= p4_pmu_enable_event,
+	.disable		= p4_pmu_disable_event,
+	.eventsel		= MSR_P4_BPU_CCCR0,
+	.perfctr		= MSR_P4_BPU_PERFCTR0,
+	.event_map		= p4_pmu_event_map,
+	.max_events		= ARRAY_SIZE(p4_general_events),
+	.get_event_constraints	= x86_get_event_constraints,
+	/*
+	 * IF HT disabled we may need to use all
+	 * ARCH_P4_MAX_CCCR counters simulaneously
+	 * though leave it restricted at moment assuming
+	 * HT is on
+	 */
+	.num_counters		= ARCH_P4_MAX_CCCR,
+	.apic			= 1,
+	.cntval_bits		= ARCH_P4_CNTRVAL_BITS,
+	.cntval_mask		= ARCH_P4_CNTRVAL_MASK,
+	.max_period		= (1ULL << (ARCH_P4_CNTRVAL_BITS - 1)) - 1,
+	.hw_config		= p4_hw_config,
+	.schedule_events	= p4_pmu_schedule_events,
+	/*
+	 * This handles erratum N15 in intel doc 249199-029,
+	 * the counter may not be updated correctly on write
+	 * so we need a second write operation to do the trick
+	 * (the official workaround didn't work)
+	 *
+	 * the former idea is taken from OProfile code
+	 */
+	.perfctr_second_write	= 1,
+
+	.format_attrs		= intel_p4_formats_attr,
+};
+
+__init int p4_pmu_init(void)
+{
+	unsigned int low, high;
+	int i, reg;
+
+	/* If we get stripped -- indexing fails */
+	BUILD_BUG_ON(ARCH_P4_MAX_CCCR > INTEL_PMC_MAX_GENERIC);
+
+	rdmsr(MSR_IA32_MISC_ENABLE, low, high);
+	if (!(low & (1 << 7))) {
+		pr_cont("unsupported Netburst CPU model %d ",
+			boot_cpu_data.x86_model);
+		return -ENODEV;
+	}
+
+	memcpy(hw_cache_event_ids, p4_hw_cache_event_ids,
+		sizeof(hw_cache_event_ids));
+
+	pr_cont("Netburst events, ");
+
+	x86_pmu = p4_pmu;
+
+	/*
+	 * Even though the counters are configured to interrupt a particular
+	 * logical processor when an overflow happens, testing has shown that
+	 * on kdump kernels (which uses a single cpu), thread1's counter
+	 * continues to run and will report an NMI on thread0.  Due to the
+	 * overflow bug, this leads to a stream of unknown NMIs.
+	 *
+	 * Solve this by zero'ing out the registers to mimic a reset.
+	 */
+	for (i = 0; i < x86_pmu.num_counters; i++) {
+		reg = x86_pmu_config_addr(i);
+		wrmsrl_safe(reg, 0ULL);
+	}
+
+	return 0;
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/arch/x86/events/intel/p6.c
@@ -0,0 +1,279 @@
+#include <linux/perf_event.h>
+#include <linux/types.h>
+
+#include "../perf_event.h"
+
+/*
+ * Not sure about some of these
+ */
+static const u64 p6_perfmon_event_map[] =
+{
+  [PERF_COUNT_HW_CPU_CYCLES]		= 0x0079,	/* CPU_CLK_UNHALTED */
+  [PERF_COUNT_HW_INSTRUCTIONS]		= 0x00c0,	/* INST_RETIRED     */
+  [PERF_COUNT_HW_CACHE_REFERENCES]	= 0x0f2e,	/* L2_RQSTS:M:E:S:I */
+  [PERF_COUNT_HW_CACHE_MISSES]		= 0x012e,	/* L2_RQSTS:I       */
+  [PERF_COUNT_HW_BRANCH_INSTRUCTIONS]	= 0x00c4,	/* BR_INST_RETIRED  */
+  [PERF_COUNT_HW_BRANCH_MISSES]		= 0x00c5,	/* BR_MISS_PRED_RETIRED */
+  [PERF_COUNT_HW_BUS_CYCLES]		= 0x0062,	/* BUS_DRDY_CLOCKS  */
+  [PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = 0x00a2,	/* RESOURCE_STALLS  */
+
+};
+
+static const u64 __initconst p6_hw_cache_event_ids
+				[PERF_COUNT_HW_CACHE_MAX]
+				[PERF_COUNT_HW_CACHE_OP_MAX]
+				[PERF_COUNT_HW_CACHE_RESULT_MAX] =
+{
+ [ C(L1D) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = 0x0043,	/* DATA_MEM_REFS       */
+                [ C(RESULT_MISS)   ] = 0x0045,	/* DCU_LINES_IN        */
+	},
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = 0,
+		[ C(RESULT_MISS)   ] = 0x0f29,	/* L2_LD:M:E:S:I       */
+	},
+        [ C(OP_PREFETCH) ] = {
+		[ C(RESULT_ACCESS) ] = 0,
+		[ C(RESULT_MISS)   ] = 0,
+        },
+ },
+ [ C(L1I ) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = 0x0080,	/* IFU_IFETCH         */
+		[ C(RESULT_MISS)   ] = 0x0f28,	/* L2_IFETCH:M:E:S:I  */
+	},
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = -1,
+		[ C(RESULT_MISS)   ] = -1,
+	},
+	[ C(OP_PREFETCH) ] = {
+		[ C(RESULT_ACCESS) ] = 0,
+		[ C(RESULT_MISS)   ] = 0,
+	},
+ },
+ [ C(LL  ) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = 0,
+		[ C(RESULT_MISS)   ] = 0,
+	},
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = 0,
+		[ C(RESULT_MISS)   ] = 0x0025,	/* L2_M_LINES_INM     */
+	},
+	[ C(OP_PREFETCH) ] = {
+		[ C(RESULT_ACCESS) ] = 0,
+		[ C(RESULT_MISS)   ] = 0,
+	},
+ },
+ [ C(DTLB) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = 0x0043,	/* DATA_MEM_REFS      */
+		[ C(RESULT_MISS)   ] = 0,
+	},
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = 0,
+		[ C(RESULT_MISS)   ] = 0,
+	},
+	[ C(OP_PREFETCH) ] = {
+		[ C(RESULT_ACCESS) ] = 0,
+		[ C(RESULT_MISS)   ] = 0,
+	},
+ },
+ [ C(ITLB) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = 0x0080,	/* IFU_IFETCH         */
+		[ C(RESULT_MISS)   ] = 0x0085,	/* ITLB_MISS          */
+	},
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = -1,
+		[ C(RESULT_MISS)   ] = -1,
+	},
+	[ C(OP_PREFETCH) ] = {
+		[ C(RESULT_ACCESS) ] = -1,
+		[ C(RESULT_MISS)   ] = -1,
+	},
+ },
+ [ C(BPU ) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = 0x00c4,	/* BR_INST_RETIRED      */
+		[ C(RESULT_MISS)   ] = 0x00c5,	/* BR_MISS_PRED_RETIRED */
+        },
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = -1,
+		[ C(RESULT_MISS)   ] = -1,
+	},
+	[ C(OP_PREFETCH) ] = {
+		[ C(RESULT_ACCESS) ] = -1,
+		[ C(RESULT_MISS)   ] = -1,
+	},
+ },
+};
+
+static u64 p6_pmu_event_map(int hw_event)
+{
+	return p6_perfmon_event_map[hw_event];
+}
+
+/*
+ * Event setting that is specified not to count anything.
+ * We use this to effectively disable a counter.
+ *
+ * L2_RQSTS with 0 MESI unit mask.
+ */
+#define P6_NOP_EVENT			0x0000002EULL
+
+static struct event_constraint p6_event_constraints[] =
+{
+	INTEL_EVENT_CONSTRAINT(0xc1, 0x1),	/* FLOPS */
+	INTEL_EVENT_CONSTRAINT(0x10, 0x1),	/* FP_COMP_OPS_EXE */
+	INTEL_EVENT_CONSTRAINT(0x11, 0x2),	/* FP_ASSIST */
+	INTEL_EVENT_CONSTRAINT(0x12, 0x2),	/* MUL */
+	INTEL_EVENT_CONSTRAINT(0x13, 0x2),	/* DIV */
+	INTEL_EVENT_CONSTRAINT(0x14, 0x1),	/* CYCLES_DIV_BUSY */
+	EVENT_CONSTRAINT_END
+};
+
+static void p6_pmu_disable_all(void)
+{
+	u64 val;
+
+	/* p6 only has one enable register */
+	rdmsrl(MSR_P6_EVNTSEL0, val);
+	val &= ~ARCH_PERFMON_EVENTSEL_ENABLE;
+	wrmsrl(MSR_P6_EVNTSEL0, val);
+}
+
+static void p6_pmu_enable_all(int added)
+{
+	unsigned long val;
+
+	/* p6 only has one enable register */
+	rdmsrl(MSR_P6_EVNTSEL0, val);
+	val |= ARCH_PERFMON_EVENTSEL_ENABLE;
+	wrmsrl(MSR_P6_EVNTSEL0, val);
+}
+
+static inline void
+p6_pmu_disable_event(struct perf_event *event)
+{
+	struct hw_perf_event *hwc = &event->hw;
+	u64 val = P6_NOP_EVENT;
+
+	(void)wrmsrl_safe(hwc->config_base, val);
+}
+
+static void p6_pmu_enable_event(struct perf_event *event)
+{
+	struct hw_perf_event *hwc = &event->hw;
+	u64 val;
+
+	val = hwc->config;
+
+	/*
+	 * p6 only has a global event enable, set on PerfEvtSel0
+	 * We "disable" events by programming P6_NOP_EVENT
+	 * and we rely on p6_pmu_enable_all() being called
+	 * to actually enable the events.
+	 */
+
+	(void)wrmsrl_safe(hwc->config_base, val);
+}
+
+PMU_FORMAT_ATTR(event,	"config:0-7"	);
+PMU_FORMAT_ATTR(umask,	"config:8-15"	);
+PMU_FORMAT_ATTR(edge,	"config:18"	);
+PMU_FORMAT_ATTR(pc,	"config:19"	);
+PMU_FORMAT_ATTR(inv,	"config:23"	);
+PMU_FORMAT_ATTR(cmask,	"config:24-31"	);
+
+static struct attribute *intel_p6_formats_attr[] = {
+	&format_attr_event.attr,
+	&format_attr_umask.attr,
+	&format_attr_edge.attr,
+	&format_attr_pc.attr,
+	&format_attr_inv.attr,
+	&format_attr_cmask.attr,
+	NULL,
+};
+
+static __initconst const struct x86_pmu p6_pmu = {
+	.name			= "p6",
+	.handle_irq		= x86_pmu_handle_irq,
+	.disable_all		= p6_pmu_disable_all,
+	.enable_all		= p6_pmu_enable_all,
+	.enable			= p6_pmu_enable_event,
+	.disable		= p6_pmu_disable_event,
+	.hw_config		= x86_pmu_hw_config,
+	.schedule_events	= x86_schedule_events,
+	.eventsel		= MSR_P6_EVNTSEL0,
+	.perfctr		= MSR_P6_PERFCTR0,
+	.event_map		= p6_pmu_event_map,
+	.max_events		= ARRAY_SIZE(p6_perfmon_event_map),
+	.apic			= 1,
+	.max_period		= (1ULL << 31) - 1,
+	.version		= 0,
+	.num_counters		= 2,
+	/*
+	 * Events have 40 bits implemented. However they are designed such
+	 * that bits [32-39] are sign extensions of bit 31. As such the
+	 * effective width of a event for P6-like PMU is 32 bits only.
+	 *
+	 * See IA-32 Intel Architecture Software developer manual Vol 3B
+	 */
+	.cntval_bits		= 32,
+	.cntval_mask		= (1ULL << 32) - 1,
+	.get_event_constraints	= x86_get_event_constraints,
+	.event_constraints	= p6_event_constraints,
+
+	.format_attrs		= intel_p6_formats_attr,
+	.events_sysfs_show	= intel_event_sysfs_show,
+
+};
+
+static __init void p6_pmu_rdpmc_quirk(void)
+{
+	if (boot_cpu_data.x86_mask < 9) {
+		/*
+		 * PPro erratum 26; fixed in stepping 9 and above.
+		 */
+		pr_warn("Userspace RDPMC support disabled due to a CPU erratum\n");
+		x86_pmu.attr_rdpmc_broken = 1;
+		x86_pmu.attr_rdpmc = 0;
+	}
+}
+
+__init int p6_pmu_init(void)
+{
+	x86_pmu = p6_pmu;
+
+	switch (boot_cpu_data.x86_model) {
+	case  1: /* Pentium Pro */
+		x86_add_quirk(p6_pmu_rdpmc_quirk);
+		break;
+
+	case  3: /* Pentium II - Klamath */
+	case  5: /* Pentium II - Deschutes */
+	case  6: /* Pentium II - Mendocino */
+		break;
+
+	case  7: /* Pentium III - Katmai */
+	case  8: /* Pentium III - Coppermine */
+	case 10: /* Pentium III Xeon */
+	case 11: /* Pentium III - Tualatin */
+		break;
+
+	case  9: /* Pentium M - Banias */
+	case 13: /* Pentium M - Dothan */
+		break;
+
+	default:
+		pr_cont("unsupported p6 CPU model %d ", boot_cpu_data.x86_model);
+		return -ENODEV;
+	}
+
+	memcpy(hw_cache_event_ids, p6_hw_cache_event_ids,
+		sizeof(hw_cache_event_ids));
+
+	return 0;
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/arch/x86/events/intel/pt.c
@@ -0,0 +1,1181 @@
+/*
+ * Intel(R) Processor Trace PMU driver for perf
+ * Copyright (c) 2013-2014, Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * Intel PT is specified in the Intel Architecture Instruction Set Extensions
+ * Programming Reference:
+ * http://software.intel.com/en-us/intel-isa-extensions
+ */
+
+#undef DEBUG
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/device.h>
+
+#include <asm/perf_event.h>
+#include <asm/insn.h>
+#include <asm/io.h>
+
+#include "../perf_event.h"
+#include "pt.h"
+
+static DEFINE_PER_CPU(struct pt, pt_ctx);
+
+static struct pt_pmu pt_pmu;
+
+enum cpuid_regs {
+	CR_EAX = 0,
+	CR_ECX,
+	CR_EDX,
+	CR_EBX
+};
+
+/*
+ * Capabilities of Intel PT hardware, such as number of address bits or
+ * supported output schemes, are cached and exported to userspace as "caps"
+ * attribute group of pt pmu device
+ * (/sys/bus/event_source/devices/intel_pt/caps/) so that userspace can store
+ * relevant bits together with intel_pt traces.
+ *
+ * These are necessary for both trace decoding (payloads_lip, contains address
+ * width encoded in IP-related packets), and event configuration (bitmasks with
+ * permitted values for certain bit fields).
+ */
+#define PT_CAP(_n, _l, _r, _m)						\
+	[PT_CAP_ ## _n] = { .name = __stringify(_n), .leaf = _l,	\
+			    .reg = _r, .mask = _m }
+
+static struct pt_cap_desc {
+	const char	*name;
+	u32		leaf;
+	u8		reg;
+	u32		mask;
+} pt_caps[] = {
+	PT_CAP(max_subleaf,		0, CR_EAX, 0xffffffff),
+	PT_CAP(cr3_filtering,		0, CR_EBX, BIT(0)),
+	PT_CAP(psb_cyc,			0, CR_EBX, BIT(1)),
+	PT_CAP(mtc,			0, CR_EBX, BIT(3)),
+	PT_CAP(topa_output,		0, CR_ECX, BIT(0)),
+	PT_CAP(topa_multiple_entries,	0, CR_ECX, BIT(1)),
+	PT_CAP(single_range_output,	0, CR_ECX, BIT(2)),
+	PT_CAP(payloads_lip,		0, CR_ECX, BIT(31)),
+	PT_CAP(mtc_periods,		1, CR_EAX, 0xffff0000),
+	PT_CAP(cycle_thresholds,	1, CR_EBX, 0xffff),
+	PT_CAP(psb_periods,		1, CR_EBX, 0xffff0000),
+};
+
+static u32 pt_cap_get(enum pt_capabilities cap)
+{
+	struct pt_cap_desc *cd = &pt_caps[cap];
+	u32 c = pt_pmu.caps[cd->leaf * PT_CPUID_REGS_NUM + cd->reg];
+	unsigned int shift = __ffs(cd->mask);
+
+	return (c & cd->mask) >> shift;
+}
+
+static ssize_t pt_cap_show(struct device *cdev,
+			   struct device_attribute *attr,
+			   char *buf)
+{
+	struct dev_ext_attribute *ea =
+		container_of(attr, struct dev_ext_attribute, attr);
+	enum pt_capabilities cap = (long)ea->var;
+
+	return snprintf(buf, PAGE_SIZE, "%x\n", pt_cap_get(cap));
+}
+
+static struct attribute_group pt_cap_group = {
+	.name	= "caps",
+};
+
+PMU_FORMAT_ATTR(cyc,		"config:1"	);
+PMU_FORMAT_ATTR(mtc,		"config:9"	);
+PMU_FORMAT_ATTR(tsc,		"config:10"	);
+PMU_FORMAT_ATTR(noretcomp,	"config:11"	);
+PMU_FORMAT_ATTR(mtc_period,	"config:14-17"	);
+PMU_FORMAT_ATTR(cyc_thresh,	"config:19-22"	);
+PMU_FORMAT_ATTR(psb_period,	"config:24-27"	);
+
+static struct attribute *pt_formats_attr[] = {
+	&format_attr_cyc.attr,
+	&format_attr_mtc.attr,
+	&format_attr_tsc.attr,
+	&format_attr_noretcomp.attr,
+	&format_attr_mtc_period.attr,
+	&format_attr_cyc_thresh.attr,
+	&format_attr_psb_period.attr,
+	NULL,
+};
+
+static struct attribute_group pt_format_group = {
+	.name	= "format",
+	.attrs	= pt_formats_attr,
+};
+
+static const struct attribute_group *pt_attr_groups[] = {
+	&pt_cap_group,
+	&pt_format_group,
+	NULL,
+};
+
+static int __init pt_pmu_hw_init(void)
+{
+	struct dev_ext_attribute *de_attrs;
+	struct attribute **attrs;
+	size_t size;
+	int ret;
+	long i;
+
+	attrs = NULL;
+
+	for (i = 0; i < PT_CPUID_LEAVES; i++) {
+		cpuid_count(20, i,
+			    &pt_pmu.caps[CR_EAX + i*PT_CPUID_REGS_NUM],
+			    &pt_pmu.caps[CR_EBX + i*PT_CPUID_REGS_NUM],
+			    &pt_pmu.caps[CR_ECX + i*PT_CPUID_REGS_NUM],
+			    &pt_pmu.caps[CR_EDX + i*PT_CPUID_REGS_NUM]);
+	}
+
+	ret = -ENOMEM;
+	size = sizeof(struct attribute *) * (ARRAY_SIZE(pt_caps)+1);
+	attrs = kzalloc(size, GFP_KERNEL);
+	if (!attrs)
+		goto fail;
+
+	size = sizeof(struct dev_ext_attribute) * (ARRAY_SIZE(pt_caps)+1);
+	de_attrs = kzalloc(size, GFP_KERNEL);
+	if (!de_attrs)
+		goto fail;
+
+	for (i = 0; i < ARRAY_SIZE(pt_caps); i++) {
+		struct dev_ext_attribute *de_attr = de_attrs + i;
+
+		de_attr->attr.attr.name = pt_caps[i].name;
+
+		sysfs_attr_init(&de_attr->attr.attr);
+
+		de_attr->attr.attr.mode		= S_IRUGO;
+		de_attr->attr.show		= pt_cap_show;
+		de_attr->var			= (void *)i;
+
+		attrs[i] = &de_attr->attr.attr;
+	}
+
+	pt_cap_group.attrs = attrs;
+
+	return 0;
+
+fail:
+	kfree(attrs);
+
+	return ret;
+}
+
+#define RTIT_CTL_CYC_PSB (RTIT_CTL_CYCLEACC	| \
+			  RTIT_CTL_CYC_THRESH	| \
+			  RTIT_CTL_PSB_FREQ)
+
+#define RTIT_CTL_MTC	(RTIT_CTL_MTC_EN	| \
+			 RTIT_CTL_MTC_RANGE)
+
+#define PT_CONFIG_MASK (RTIT_CTL_TSC_EN		| \
+			RTIT_CTL_DISRETC	| \
+			RTIT_CTL_CYC_PSB	| \
+			RTIT_CTL_MTC)
+
+static bool pt_event_valid(struct perf_event *event)
+{
+	u64 config = event->attr.config;
+	u64 allowed, requested;
+
+	if ((config & PT_CONFIG_MASK) != config)
+		return false;
+
+	if (config & RTIT_CTL_CYC_PSB) {
+		if (!pt_cap_get(PT_CAP_psb_cyc))
+			return false;
+
+		allowed = pt_cap_get(PT_CAP_psb_periods);
+		requested = (config & RTIT_CTL_PSB_FREQ) >>
+			RTIT_CTL_PSB_FREQ_OFFSET;
+		if (requested && (!(allowed & BIT(requested))))
+			return false;
+
+		allowed = pt_cap_get(PT_CAP_cycle_thresholds);
+		requested = (config & RTIT_CTL_CYC_THRESH) >>
+			RTIT_CTL_CYC_THRESH_OFFSET;
+		if (requested && (!(allowed & BIT(requested))))
+			return false;
+	}
+
+	if (config & RTIT_CTL_MTC) {
+		/*
+		 * In the unlikely case that CPUID lists valid mtc periods,
+		 * but not the mtc capability, drop out here.
+		 *
+		 * Spec says that setting mtc period bits while mtc bit in
+		 * CPUID is 0 will #GP, so better safe than sorry.
+		 */
+		if (!pt_cap_get(PT_CAP_mtc))
+			return false;
+
+		allowed = pt_cap_get(PT_CAP_mtc_periods);
+		if (!allowed)
+			return false;
+
+		requested = (config & RTIT_CTL_MTC_RANGE) >>
+			RTIT_CTL_MTC_RANGE_OFFSET;
+
+		if (!(allowed & BIT(requested)))
+			return false;
+	}
+
+	return true;
+}
+
+/*
+ * PT configuration helpers
+ * These all are cpu affine and operate on a local PT
+ */
+
+static void pt_config(struct perf_event *event)
+{
+	u64 reg;
+
+	if (!event->hw.itrace_started) {
+		event->hw.itrace_started = 1;
+		wrmsrl(MSR_IA32_RTIT_STATUS, 0);
+	}
+
+	reg = RTIT_CTL_TOPA | RTIT_CTL_BRANCH_EN | RTIT_CTL_TRACEEN;
+
+	if (!event->attr.exclude_kernel)
+		reg |= RTIT_CTL_OS;
+	if (!event->attr.exclude_user)
+		reg |= RTIT_CTL_USR;
+
+	reg |= (event->attr.config & PT_CONFIG_MASK);
+
+	wrmsrl(MSR_IA32_RTIT_CTL, reg);
+}
+
+static void pt_config_start(bool start)
+{
+	u64 ctl;
+
+	rdmsrl(MSR_IA32_RTIT_CTL, ctl);
+	if (start)
+		ctl |= RTIT_CTL_TRACEEN;
+	else
+		ctl &= ~RTIT_CTL_TRACEEN;
+	wrmsrl(MSR_IA32_RTIT_CTL, ctl);
+
+	/*
+	 * A wrmsr that disables trace generation serializes other PT
+	 * registers and causes all data packets to be written to memory,
+	 * but a fence is required for the data to become globally visible.
+	 *
+	 * The below WMB, separating data store and aux_head store matches
+	 * the consumer's RMB that separates aux_head load and data load.
+	 */
+	if (!start)
+		wmb();
+}
+
+static void pt_config_buffer(void *buf, unsigned int topa_idx,
+			     unsigned int output_off)
+{
+	u64 reg;
+
+	wrmsrl(MSR_IA32_RTIT_OUTPUT_BASE, virt_to_phys(buf));
+
+	reg = 0x7f | ((u64)topa_idx << 7) | ((u64)output_off << 32);
+
+	wrmsrl(MSR_IA32_RTIT_OUTPUT_MASK, reg);
+}
+
+/*
+ * Keep ToPA table-related metadata on the same page as the actual table,
+ * taking up a few words from the top
+ */
+
+#define TENTS_PER_PAGE (((PAGE_SIZE - 40) / sizeof(struct topa_entry)) - 1)
+
+/**
+ * struct topa - page-sized ToPA table with metadata at the top
+ * @table:	actual ToPA table entries, as understood by PT hardware
+ * @list:	linkage to struct pt_buffer's list of tables
+ * @phys:	physical address of this page
+ * @offset:	offset of the first entry in this table in the buffer
+ * @size:	total size of all entries in this table
+ * @last:	index of the last initialized entry in this table
+ */
+struct topa {
+	struct topa_entry	table[TENTS_PER_PAGE];
+	struct list_head	list;
+	u64			phys;
+	u64			offset;
+	size_t			size;
+	int			last;
+};
+
+/* make -1 stand for the last table entry */
+#define TOPA_ENTRY(t, i) ((i) == -1 ? &(t)->table[(t)->last] : &(t)->table[(i)])
+
+/**
+ * topa_alloc() - allocate page-sized ToPA table
+ * @cpu:	CPU on which to allocate.
+ * @gfp:	Allocation flags.
+ *
+ * Return:	On success, return the pointer to ToPA table page.
+ */
+static struct topa *topa_alloc(int cpu, gfp_t gfp)
+{
+	int node = cpu_to_node(cpu);
+	struct topa *topa;
+	struct page *p;
+
+	p = alloc_pages_node(node, gfp | __GFP_ZERO, 0);
+	if (!p)
+		return NULL;
+
+	topa = page_address(p);
+	topa->last = 0;
+	topa->phys = page_to_phys(p);
+
+	/*
+	 * In case of singe-entry ToPA, always put the self-referencing END
+	 * link as the 2nd entry in the table
+	 */
+	if (!pt_cap_get(PT_CAP_topa_multiple_entries)) {
+		TOPA_ENTRY(topa, 1)->base = topa->phys >> TOPA_SHIFT;
+		TOPA_ENTRY(topa, 1)->end = 1;
+	}
+
+	return topa;
+}
+
+/**
+ * topa_free() - free a page-sized ToPA table
+ * @topa:	Table to deallocate.
+ */
+static void topa_free(struct topa *topa)
+{
+	free_page((unsigned long)topa);
+}
+
+/**
+ * topa_insert_table() - insert a ToPA table into a buffer
+ * @buf:	 PT buffer that's being extended.
+ * @topa:	 New topa table to be inserted.
+ *
+ * If it's the first table in this buffer, set up buffer's pointers
+ * accordingly; otherwise, add a END=1 link entry to @topa to the current
+ * "last" table and adjust the last table pointer to @topa.
+ */
+static void topa_insert_table(struct pt_buffer *buf, struct topa *topa)
+{
+	struct topa *last = buf->last;
+
+	list_add_tail(&topa->list, &buf->tables);
+
+	if (!buf->first) {
+		buf->first = buf->last = buf->cur = topa;
+		return;
+	}
+
+	topa->offset = last->offset + last->size;
+	buf->last = topa;
+
+	if (!pt_cap_get(PT_CAP_topa_multiple_entries))
+		return;
+
+	BUG_ON(last->last != TENTS_PER_PAGE - 1);
+
+	TOPA_ENTRY(last, -1)->base = topa->phys >> TOPA_SHIFT;
+	TOPA_ENTRY(last, -1)->end = 1;
+}
+
+/**
+ * topa_table_full() - check if a ToPA table is filled up
+ * @topa:	ToPA table.
+ */
+static bool topa_table_full(struct topa *topa)
+{
+	/* single-entry ToPA is a special case */
+	if (!pt_cap_get(PT_CAP_topa_multiple_entries))
+		return !!topa->last;
+
+	return topa->last == TENTS_PER_PAGE - 1;
+}
+
+/**
+ * topa_insert_pages() - create a list of ToPA tables
+ * @buf:	PT buffer being initialized.
+ * @gfp:	Allocation flags.
+ *
+ * This initializes a list of ToPA tables with entries from
+ * the data_pages provided by rb_alloc_aux().
+ *
+ * Return:	0 on success or error code.
+ */
+static int topa_insert_pages(struct pt_buffer *buf, gfp_t gfp)
+{
+	struct topa *topa = buf->last;
+	int order = 0;
+	struct page *p;
+
+	p = virt_to_page(buf->data_pages[buf->nr_pages]);
+	if (PagePrivate(p))
+		order = page_private(p);
+
+	if (topa_table_full(topa)) {
+		topa = topa_alloc(buf->cpu, gfp);
+		if (!topa)
+			return -ENOMEM;
+
+		topa_insert_table(buf, topa);
+	}
+
+	TOPA_ENTRY(topa, -1)->base = page_to_phys(p) >> TOPA_SHIFT;
+	TOPA_ENTRY(topa, -1)->size = order;
+	if (!buf->snapshot && !pt_cap_get(PT_CAP_topa_multiple_entries)) {
+		TOPA_ENTRY(topa, -1)->intr = 1;
+		TOPA_ENTRY(topa, -1)->stop = 1;
+	}
+
+	topa->last++;
+	topa->size += sizes(order);
+
+	buf->nr_pages += 1ul << order;
+
+	return 0;
+}
+
+/**
+ * pt_topa_dump() - print ToPA tables and their entries
+ * @buf:	PT buffer.
+ */
+static void pt_topa_dump(struct pt_buffer *buf)
+{
+	struct topa *topa;
+
+	list_for_each_entry(topa, &buf->tables, list) {
+		int i;
+
+		pr_debug("# table @%p (%016Lx), off %llx size %zx\n", topa->table,
+			 topa->phys, topa->offset, topa->size);
+		for (i = 0; i < TENTS_PER_PAGE; i++) {
+			pr_debug("# entry @%p (%lx sz %u %c%c%c) raw=%16llx\n",
+				 &topa->table[i],
+				 (unsigned long)topa->table[i].base << TOPA_SHIFT,
+				 sizes(topa->table[i].size),
+				 topa->table[i].end ?  'E' : ' ',
+				 topa->table[i].intr ? 'I' : ' ',
+				 topa->table[i].stop ? 'S' : ' ',
+				 *(u64 *)&topa->table[i]);
+			if ((pt_cap_get(PT_CAP_topa_multiple_entries) &&
+			     topa->table[i].stop) ||
+			    topa->table[i].end)
+				break;
+		}
+	}
+}
+
+/**
+ * pt_buffer_advance() - advance to the next output region
+ * @buf:	PT buffer.
+ *
+ * Advance the current pointers in the buffer to the next ToPA entry.
+ */
+static void pt_buffer_advance(struct pt_buffer *buf)
+{
+	buf->output_off = 0;
+	buf->cur_idx++;
+
+	if (buf->cur_idx == buf->cur->last) {
+		if (buf->cur == buf->last)
+			buf->cur = buf->first;
+		else
+			buf->cur = list_entry(buf->cur->list.next, struct topa,
+					      list);
+		buf->cur_idx = 0;
+	}
+}
+
+/**
+ * pt_update_head() - calculate current offsets and sizes
+ * @pt:		Per-cpu pt context.
+ *
+ * Update buffer's current write pointer position and data size.
+ */
+static void pt_update_head(struct pt *pt)
+{
+	struct pt_buffer *buf = perf_get_aux(&pt->handle);
+	u64 topa_idx, base, old;
+
+	/* offset of the first region in this table from the beginning of buf */
+	base = buf->cur->offset + buf->output_off;
+
+	/* offset of the current output region within this table */
+	for (topa_idx = 0; topa_idx < buf->cur_idx; topa_idx++)
+		base += sizes(buf->cur->table[topa_idx].size);
+
+	if (buf->snapshot) {
+		local_set(&buf->data_size, base);
+	} else {
+		old = (local64_xchg(&buf->head, base) &
+		       ((buf->nr_pages << PAGE_SHIFT) - 1));
+		if (base < old)
+			base += buf->nr_pages << PAGE_SHIFT;
+
+		local_add(base - old, &buf->data_size);
+	}
+}
+
+/**
+ * pt_buffer_region() - obtain current output region's address
+ * @buf:	PT buffer.
+ */
+static void *pt_buffer_region(struct pt_buffer *buf)
+{
+	return phys_to_virt(buf->cur->table[buf->cur_idx].base << TOPA_SHIFT);
+}
+
+/**
+ * pt_buffer_region_size() - obtain current output region's size
+ * @buf:	PT buffer.
+ */
+static size_t pt_buffer_region_size(struct pt_buffer *buf)
+{
+	return sizes(buf->cur->table[buf->cur_idx].size);
+}
+
+/**
+ * pt_handle_status() - take care of possible status conditions
+ * @pt:		Per-cpu pt context.
+ */
+static void pt_handle_status(struct pt *pt)
+{
+	struct pt_buffer *buf = perf_get_aux(&pt->handle);
+	int advance = 0;
+	u64 status;
+
+	rdmsrl(MSR_IA32_RTIT_STATUS, status);
+
+	if (status & RTIT_STATUS_ERROR) {
+		pr_err_ratelimited("ToPA ERROR encountered, trying to recover\n");
+		pt_topa_dump(buf);
+		status &= ~RTIT_STATUS_ERROR;
+	}
+
+	if (status & RTIT_STATUS_STOPPED) {
+		status &= ~RTIT_STATUS_STOPPED;
+
+		/*
+		 * On systems that only do single-entry ToPA, hitting STOP
+		 * means we are already losing data; need to let the decoder
+		 * know.
+		 */
+		if (!pt_cap_get(PT_CAP_topa_multiple_entries) ||
+		    buf->output_off == sizes(TOPA_ENTRY(buf->cur, buf->cur_idx)->size)) {
+			local_inc(&buf->lost);
+			advance++;
+		}
+	}
+
+	/*
+	 * Also on single-entry ToPA implementations, interrupt will come
+	 * before the output reaches its output region's boundary.
+	 */
+	if (!pt_cap_get(PT_CAP_topa_multiple_entries) && !buf->snapshot &&
+	    pt_buffer_region_size(buf) - buf->output_off <= TOPA_PMI_MARGIN) {
+		void *head = pt_buffer_region(buf);
+
+		/* everything within this margin needs to be zeroed out */
+		memset(head + buf->output_off, 0,
+		       pt_buffer_region_size(buf) -
+		       buf->output_off);
+		advance++;
+	}
+
+	if (advance)
+		pt_buffer_advance(buf);
+
+	wrmsrl(MSR_IA32_RTIT_STATUS, status);
+}
+
+/**
+ * pt_read_offset() - translate registers into buffer pointers
+ * @buf:	PT buffer.
+ *
+ * Set buffer's output pointers from MSR values.
+ */
+static void pt_read_offset(struct pt_buffer *buf)
+{
+	u64 offset, base_topa;
+
+	rdmsrl(MSR_IA32_RTIT_OUTPUT_BASE, base_topa);
+	buf->cur = phys_to_virt(base_topa);
+
+	rdmsrl(MSR_IA32_RTIT_OUTPUT_MASK, offset);
+	/* offset within current output region */
+	buf->output_off = offset >> 32;
+	/* index of current output region within this table */
+	buf->cur_idx = (offset & 0xffffff80) >> 7;
+}
+
+/**
+ * pt_topa_next_entry() - obtain index of the first page in the next ToPA entry
+ * @buf:	PT buffer.
+ * @pg:		Page offset in the buffer.
+ *
+ * When advancing to the next output region (ToPA entry), given a page offset
+ * into the buffer, we need to find the offset of the first page in the next
+ * region.
+ */
+static unsigned int pt_topa_next_entry(struct pt_buffer *buf, unsigned int pg)
+{
+	struct topa_entry *te = buf->topa_index[pg];
+
+	/* one region */
+	if (buf->first == buf->last && buf->first->last == 1)
+		return pg;
+
+	do {
+		pg++;
+		pg &= buf->nr_pages - 1;
+	} while (buf->topa_index[pg] == te);
+
+	return pg;
+}
+
+/**
+ * pt_buffer_reset_markers() - place interrupt and stop bits in the buffer
+ * @buf:	PT buffer.
+ * @handle:	Current output handle.
+ *
+ * Place INT and STOP marks to prevent overwriting old data that the consumer
+ * hasn't yet collected and waking up the consumer after a certain fraction of
+ * the buffer has filled up. Only needed and sensible for non-snapshot counters.
+ *
+ * This obviously relies on buf::head to figure out buffer markers, so it has
+ * to be called after pt_buffer_reset_offsets() and before the hardware tracing
+ * is enabled.
+ */
+static int pt_buffer_reset_markers(struct pt_buffer *buf,
+				   struct perf_output_handle *handle)
+
+{
+	unsigned long head = local64_read(&buf->head);
+	unsigned long idx, npages, wakeup;
+
+	/* can't stop in the middle of an output region */
+	if (buf->output_off + handle->size + 1 <
+	    sizes(TOPA_ENTRY(buf->cur, buf->cur_idx)->size))
+		return -EINVAL;
+
+
+	/* single entry ToPA is handled by marking all regions STOP=1 INT=1 */
+	if (!pt_cap_get(PT_CAP_topa_multiple_entries))
+		return 0;
+
+	/* clear STOP and INT from current entry */
+	buf->topa_index[buf->stop_pos]->stop = 0;
+	buf->topa_index[buf->stop_pos]->intr = 0;
+	buf->topa_index[buf->intr_pos]->intr = 0;
+
+	/* how many pages till the STOP marker */
+	npages = handle->size >> PAGE_SHIFT;
+
+	/* if it's on a page boundary, fill up one more page */
+	if (!offset_in_page(head + handle->size + 1))
+		npages++;
+
+	idx = (head >> PAGE_SHIFT) + npages;
+	idx &= buf->nr_pages - 1;
+	buf->stop_pos = idx;
+
+	wakeup = handle->wakeup >> PAGE_SHIFT;
+
+	/* in the worst case, wake up the consumer one page before hard stop */
+	idx = (head >> PAGE_SHIFT) + npages - 1;
+	if (idx > wakeup)
+		idx = wakeup;
+
+	idx &= buf->nr_pages - 1;
+	buf->intr_pos = idx;
+
+	buf->topa_index[buf->stop_pos]->stop = 1;
+	buf->topa_index[buf->stop_pos]->intr = 1;
+	buf->topa_index[buf->intr_pos]->intr = 1;
+
+	return 0;
+}
+
+/**
+ * pt_buffer_setup_topa_index() - build topa_index[] table of regions
+ * @buf:	PT buffer.
+ *
+ * topa_index[] references output regions indexed by offset into the
+ * buffer for purposes of quick reverse lookup.
+ */
+static void pt_buffer_setup_topa_index(struct pt_buffer *buf)
+{
+	struct topa *cur = buf->first, *prev = buf->last;
+	struct topa_entry *te_cur = TOPA_ENTRY(cur, 0),
+		*te_prev = TOPA_ENTRY(prev, prev->last - 1);
+	int pg = 0, idx = 0;
+
+	while (pg < buf->nr_pages) {
+		int tidx;
+
+		/* pages within one topa entry */
+		for (tidx = 0; tidx < 1 << te_cur->size; tidx++, pg++)
+			buf->topa_index[pg] = te_prev;
+
+		te_prev = te_cur;
+
+		if (idx == cur->last - 1) {
+			/* advance to next topa table */
+			idx = 0;
+			cur = list_entry(cur->list.next, struct topa, list);
+		} else {
+			idx++;
+		}
+		te_cur = TOPA_ENTRY(cur, idx);
+	}
+
+}
+
+/**
+ * pt_buffer_reset_offsets() - adjust buffer's write pointers from aux_head
+ * @buf:	PT buffer.
+ * @head:	Write pointer (aux_head) from AUX buffer.
+ *
+ * Find the ToPA table and entry corresponding to given @head and set buffer's
+ * "current" pointers accordingly. This is done after we have obtained the
+ * current aux_head position from a successful call to perf_aux_output_begin()
+ * to make sure the hardware is writing to the right place.
+ *
+ * This function modifies buf::{cur,cur_idx,output_off} that will be programmed
+ * into PT msrs when the tracing is enabled and buf::head and buf::data_size,
+ * which are used to determine INT and STOP markers' locations by a subsequent
+ * call to pt_buffer_reset_markers().
+ */
+static void pt_buffer_reset_offsets(struct pt_buffer *buf, unsigned long head)
+{
+	int pg;
+
+	if (buf->snapshot)
+		head &= (buf->nr_pages << PAGE_SHIFT) - 1;
+
+	pg = (head >> PAGE_SHIFT) & (buf->nr_pages - 1);
+	pg = pt_topa_next_entry(buf, pg);
+
+	buf->cur = (struct topa *)((unsigned long)buf->topa_index[pg] & PAGE_MASK);
+	buf->cur_idx = ((unsigned long)buf->topa_index[pg] -
+			(unsigned long)buf->cur) / sizeof(struct topa_entry);
+	buf->output_off = head & (sizes(buf->cur->table[buf->cur_idx].size) - 1);
+
+	local64_set(&buf->head, head);
+	local_set(&buf->data_size, 0);
+}
+
+/**
+ * pt_buffer_fini_topa() - deallocate ToPA structure of a buffer
+ * @buf:	PT buffer.
+ */
+static void pt_buffer_fini_topa(struct pt_buffer *buf)
+{
+	struct topa *topa, *iter;
+
+	list_for_each_entry_safe(topa, iter, &buf->tables, list) {
+		/*
+		 * right now, this is in free_aux() path only, so
+		 * no need to unlink this table from the list
+		 */
+		topa_free(topa);
+	}
+}
+
+/**
+ * pt_buffer_init_topa() - initialize ToPA table for pt buffer
+ * @buf:	PT buffer.
+ * @size:	Total size of all regions within this ToPA.
+ * @gfp:	Allocation flags.
+ */
+static int pt_buffer_init_topa(struct pt_buffer *buf, unsigned long nr_pages,
+			       gfp_t gfp)
+{
+	struct topa *topa;
+	int err;
+
+	topa = topa_alloc(buf->cpu, gfp);
+	if (!topa)
+		return -ENOMEM;
+
+	topa_insert_table(buf, topa);
+
+	while (buf->nr_pages < nr_pages) {
+		err = topa_insert_pages(buf, gfp);
+		if (err) {
+			pt_buffer_fini_topa(buf);
+			return -ENOMEM;
+		}
+	}
+
+	pt_buffer_setup_topa_index(buf);
+
+	/* link last table to the first one, unless we're double buffering */
+	if (pt_cap_get(PT_CAP_topa_multiple_entries)) {
+		TOPA_ENTRY(buf->last, -1)->base = buf->first->phys >> TOPA_SHIFT;
+		TOPA_ENTRY(buf->last, -1)->end = 1;
+	}
+
+	pt_topa_dump(buf);
+	return 0;
+}
+
+/**
+ * pt_buffer_setup_aux() - set up topa tables for a PT buffer
+ * @cpu:	Cpu on which to allocate, -1 means current.
+ * @pages:	Array of pointers to buffer pages passed from perf core.
+ * @nr_pages:	Number of pages in the buffer.
+ * @snapshot:	If this is a snapshot/overwrite counter.
+ *
+ * This is a pmu::setup_aux callback that sets up ToPA tables and all the
+ * bookkeeping for an AUX buffer.
+ *
+ * Return:	Our private PT buffer structure.
+ */
+static void *
+pt_buffer_setup_aux(int cpu, void **pages, int nr_pages, bool snapshot)
+{
+	struct pt_buffer *buf;
+	int node, ret;
+
+	if (!nr_pages)
+		return NULL;
+
+	if (cpu == -1)
+		cpu = raw_smp_processor_id();
+	node = cpu_to_node(cpu);
+
+	buf = kzalloc_node(offsetof(struct pt_buffer, topa_index[nr_pages]),
+			   GFP_KERNEL, node);
+	if (!buf)
+		return NULL;
+
+	buf->cpu = cpu;
+	buf->snapshot = snapshot;
+	buf->data_pages = pages;
+
+	INIT_LIST_HEAD(&buf->tables);
+
+	ret = pt_buffer_init_topa(buf, nr_pages, GFP_KERNEL);
+	if (ret) {
+		kfree(buf);
+		return NULL;
+	}
+
+	return buf;
+}
+
+/**
+ * pt_buffer_free_aux() - perf AUX deallocation path callback
+ * @data:	PT buffer.
+ */
+static void pt_buffer_free_aux(void *data)
+{
+	struct pt_buffer *buf = data;
+
+	pt_buffer_fini_topa(buf);
+	kfree(buf);
+}
+
+/**
+ * pt_buffer_is_full() - check if the buffer is full
+ * @buf:	PT buffer.
+ * @pt:		Per-cpu pt handle.
+ *
+ * If the user hasn't read data from the output region that aux_head
+ * points to, the buffer is considered full: the user needs to read at
+ * least this region and update aux_tail to point past it.
+ */
+static bool pt_buffer_is_full(struct pt_buffer *buf, struct pt *pt)
+{
+	if (buf->snapshot)
+		return false;
+
+	if (local_read(&buf->data_size) >= pt->handle.size)
+		return true;
+
+	return false;
+}
+
+/**
+ * intel_pt_interrupt() - PT PMI handler
+ */
+void intel_pt_interrupt(void)
+{
+	struct pt *pt = this_cpu_ptr(&pt_ctx);
+	struct pt_buffer *buf;
+	struct perf_event *event = pt->handle.event;
+
+	/*
+	 * There may be a dangling PT bit in the interrupt status register
+	 * after PT has been disabled by pt_event_stop(). Make sure we don't
+	 * do anything (particularly, re-enable) for this event here.
+	 */
+	if (!ACCESS_ONCE(pt->handle_nmi))
+		return;
+
+	pt_config_start(false);
+
+	if (!event)
+		return;
+
+	buf = perf_get_aux(&pt->handle);
+	if (!buf)
+		return;
+
+	pt_read_offset(buf);
+
+	pt_handle_status(pt);
+
+	pt_update_head(pt);
+
+	perf_aux_output_end(&pt->handle, local_xchg(&buf->data_size, 0),
+			    local_xchg(&buf->lost, 0));
+
+	if (!event->hw.state) {
+		int ret;
+
+		buf = perf_aux_output_begin(&pt->handle, event);
+		if (!buf) {
+			event->hw.state = PERF_HES_STOPPED;
+			return;
+		}
+
+		pt_buffer_reset_offsets(buf, pt->handle.head);
+		/* snapshot counters don't use PMI, so it's safe */
+		ret = pt_buffer_reset_markers(buf, &pt->handle);
+		if (ret) {
+			perf_aux_output_end(&pt->handle, 0, true);
+			return;
+		}
+
+		pt_config_buffer(buf->cur->table, buf->cur_idx,
+				 buf->output_off);
+		pt_config(event);
+	}
+}
+
+/*
+ * PMU callbacks
+ */
+
+static void pt_event_start(struct perf_event *event, int mode)
+{
+	struct pt *pt = this_cpu_ptr(&pt_ctx);
+	struct pt_buffer *buf = perf_get_aux(&pt->handle);
+
+	if (!buf || pt_buffer_is_full(buf, pt)) {
+		event->hw.state = PERF_HES_STOPPED;
+		return;
+	}
+
+	ACCESS_ONCE(pt->handle_nmi) = 1;
+	event->hw.state = 0;
+
+	pt_config_buffer(buf->cur->table, buf->cur_idx,
+			 buf->output_off);
+	pt_config(event);
+}
+
+static void pt_event_stop(struct perf_event *event, int mode)
+{
+	struct pt *pt = this_cpu_ptr(&pt_ctx);
+
+	/*
+	 * Protect against the PMI racing with disabling wrmsr,
+	 * see comment in intel_pt_interrupt().
+	 */
+	ACCESS_ONCE(pt->handle_nmi) = 0;
+	pt_config_start(false);
+
+	if (event->hw.state == PERF_HES_STOPPED)
+		return;
+
+	event->hw.state = PERF_HES_STOPPED;
+
+	if (mode & PERF_EF_UPDATE) {
+		struct pt_buffer *buf = perf_get_aux(&pt->handle);
+
+		if (!buf)
+			return;
+
+		if (WARN_ON_ONCE(pt->handle.event != event))
+			return;
+
+		pt_read_offset(buf);
+
+		pt_handle_status(pt);
+
+		pt_update_head(pt);
+	}
+}
+
+static void pt_event_del(struct perf_event *event, int mode)
+{
+	struct pt *pt = this_cpu_ptr(&pt_ctx);
+	struct pt_buffer *buf;
+
+	pt_event_stop(event, PERF_EF_UPDATE);
+
+	buf = perf_get_aux(&pt->handle);
+
+	if (buf) {
+		if (buf->snapshot)
+			pt->handle.head =
+				local_xchg(&buf->data_size,
+					   buf->nr_pages << PAGE_SHIFT);
+		perf_aux_output_end(&pt->handle, local_xchg(&buf->data_size, 0),
+				    local_xchg(&buf->lost, 0));
+	}
+}
+
+static int pt_event_add(struct perf_event *event, int mode)
+{
+	struct pt_buffer *buf;
+	struct pt *pt = this_cpu_ptr(&pt_ctx);
+	struct hw_perf_event *hwc = &event->hw;
+	int ret = -EBUSY;
+
+	if (pt->handle.event)
+		goto fail;
+
+	buf = perf_aux_output_begin(&pt->handle, event);
+	ret = -EINVAL;
+	if (!buf)
+		goto fail_stop;
+
+	pt_buffer_reset_offsets(buf, pt->handle.head);
+	if (!buf->snapshot) {
+		ret = pt_buffer_reset_markers(buf, &pt->handle);
+		if (ret)
+			goto fail_end_stop;
+	}
+
+	if (mode & PERF_EF_START) {
+		pt_event_start(event, 0);
+		ret = -EBUSY;
+		if (hwc->state == PERF_HES_STOPPED)
+			goto fail_end_stop;
+	} else {
+		hwc->state = PERF_HES_STOPPED;
+	}
+
+	return 0;
+
+fail_end_stop:
+	perf_aux_output_end(&pt->handle, 0, true);
+fail_stop:
+	hwc->state = PERF_HES_STOPPED;
+fail:
+	return ret;
+}
+
+static void pt_event_read(struct perf_event *event)
+{
+}
+
+static void pt_event_destroy(struct perf_event *event)
+{
+	x86_del_exclusive(x86_lbr_exclusive_pt);
+}
+
+static int pt_event_init(struct perf_event *event)
+{
+	if (event->attr.type != pt_pmu.pmu.type)
+		return -ENOENT;
+
+	if (!pt_event_valid(event))
+		return -EINVAL;
+
+	if (x86_add_exclusive(x86_lbr_exclusive_pt))
+		return -EBUSY;
+
+	event->destroy = pt_event_destroy;
+
+	return 0;
+}
+
+static __init int pt_init(void)
+{
+	int ret, cpu, prior_warn = 0;
+
+	BUILD_BUG_ON(sizeof(struct topa) > PAGE_SIZE);
+
+	if (!test_cpu_cap(&boot_cpu_data, X86_FEATURE_INTEL_PT))
+		return -ENODEV;
+
+	get_online_cpus();
+	for_each_online_cpu(cpu) {
+		u64 ctl;
+
+		ret = rdmsrl_safe_on_cpu(cpu, MSR_IA32_RTIT_CTL, &ctl);
+		if (!ret && (ctl & RTIT_CTL_TRACEEN))
+			prior_warn++;
+	}
+	put_online_cpus();
+
+	if (prior_warn) {
+		x86_add_exclusive(x86_lbr_exclusive_pt);
+		pr_warn("PT is enabled at boot time, doing nothing\n");
+
+		return -EBUSY;
+	}
+
+	ret = pt_pmu_hw_init();
+	if (ret)
+		return ret;
+
+	if (!pt_cap_get(PT_CAP_topa_output)) {
+		pr_warn("ToPA output is not supported on this CPU\n");
+		return -ENODEV;
+	}
+
+	if (!pt_cap_get(PT_CAP_topa_multiple_entries))
+		pt_pmu.pmu.capabilities =
+			PERF_PMU_CAP_AUX_NO_SG | PERF_PMU_CAP_AUX_SW_DOUBLEBUF;
+
+	pt_pmu.pmu.capabilities	|= PERF_PMU_CAP_EXCLUSIVE | PERF_PMU_CAP_ITRACE;
+	pt_pmu.pmu.attr_groups	= pt_attr_groups;
+	pt_pmu.pmu.task_ctx_nr	= perf_sw_context;
+	pt_pmu.pmu.event_init	= pt_event_init;
+	pt_pmu.pmu.add		= pt_event_add;
+	pt_pmu.pmu.del		= pt_event_del;
+	pt_pmu.pmu.start	= pt_event_start;
+	pt_pmu.pmu.stop		= pt_event_stop;
+	pt_pmu.pmu.read		= pt_event_read;
+	pt_pmu.pmu.setup_aux	= pt_buffer_setup_aux;
+	pt_pmu.pmu.free_aux	= pt_buffer_free_aux;
+	ret = perf_pmu_register(&pt_pmu.pmu, "intel_pt", -1);
+
+	return ret;
+}
+arch_initcall(pt_init);
--- /dev/null
+++ zfcpdump-kernel-4.4/arch/x86/events/intel/pt.h
@@ -0,0 +1,116 @@
+/*
+ * Intel(R) Processor Trace PMU driver for perf
+ * Copyright (c) 2013-2014, Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * Intel PT is specified in the Intel Architecture Instruction Set Extensions
+ * Programming Reference:
+ * http://software.intel.com/en-us/intel-isa-extensions
+ */
+
+#ifndef __INTEL_PT_H__
+#define __INTEL_PT_H__
+
+/*
+ * Single-entry ToPA: when this close to region boundary, switch
+ * buffers to avoid losing data.
+ */
+#define TOPA_PMI_MARGIN 512
+
+#define TOPA_SHIFT 12
+
+static inline unsigned int sizes(unsigned int tsz)
+{
+	return 1 << (tsz + TOPA_SHIFT);
+};
+
+struct topa_entry {
+	u64	end	: 1;
+	u64	rsvd0	: 1;
+	u64	intr	: 1;
+	u64	rsvd1	: 1;
+	u64	stop	: 1;
+	u64	rsvd2	: 1;
+	u64	size	: 4;
+	u64	rsvd3	: 2;
+	u64	base	: 36;
+	u64	rsvd4	: 16;
+};
+
+#define PT_CPUID_LEAVES		2
+#define PT_CPUID_REGS_NUM	4 /* number of regsters (eax, ebx, ecx, edx) */
+
+enum pt_capabilities {
+	PT_CAP_max_subleaf = 0,
+	PT_CAP_cr3_filtering,
+	PT_CAP_psb_cyc,
+	PT_CAP_mtc,
+	PT_CAP_topa_output,
+	PT_CAP_topa_multiple_entries,
+	PT_CAP_single_range_output,
+	PT_CAP_payloads_lip,
+	PT_CAP_mtc_periods,
+	PT_CAP_cycle_thresholds,
+	PT_CAP_psb_periods,
+};
+
+struct pt_pmu {
+	struct pmu		pmu;
+	u32			caps[PT_CPUID_REGS_NUM * PT_CPUID_LEAVES];
+};
+
+/**
+ * struct pt_buffer - buffer configuration; one buffer per task_struct or
+ *		cpu, depending on perf event configuration
+ * @cpu:	cpu for per-cpu allocation
+ * @tables:	list of ToPA tables in this buffer
+ * @first:	shorthand for first topa table
+ * @last:	shorthand for last topa table
+ * @cur:	current topa table
+ * @nr_pages:	buffer size in pages
+ * @cur_idx:	current output region's index within @cur table
+ * @output_off:	offset within the current output region
+ * @data_size:	running total of the amount of data in this buffer
+ * @lost:	if data was lost/truncated
+ * @head:	logical write offset inside the buffer
+ * @snapshot:	if this is for a snapshot/overwrite counter
+ * @stop_pos:	STOP topa entry in the buffer
+ * @intr_pos:	INT topa entry in the buffer
+ * @data_pages:	array of pages from perf
+ * @topa_index:	table of topa entries indexed by page offset
+ */
+struct pt_buffer {
+	int			cpu;
+	struct list_head	tables;
+	struct topa		*first, *last, *cur;
+	unsigned int		cur_idx;
+	size_t			output_off;
+	unsigned long		nr_pages;
+	local_t			data_size;
+	local_t			lost;
+	local64_t		head;
+	bool			snapshot;
+	unsigned long		stop_pos, intr_pos;
+	void			**data_pages;
+	struct topa_entry	*topa_index[0];
+};
+
+/**
+ * struct pt - per-cpu pt context
+ * @handle:	perf output handle
+ * @handle_nmi:	do handle PT PMI on this cpu, there's an active event
+ */
+struct pt {
+	struct perf_output_handle handle;
+	int			handle_nmi;
+};
+
+#endif /* __INTEL_PT_H__ */
--- /dev/null
+++ zfcpdump-kernel-4.4/arch/x86/events/intel/rapl.c
@@ -0,0 +1,796 @@
+/*
+ * perf_event_intel_rapl.c: support Intel RAPL energy consumption counters
+ * Copyright (C) 2013 Google, Inc., Stephane Eranian
+ *
+ * Intel RAPL interface is specified in the IA-32 Manual Vol3b
+ * section 14.7.1 (September 2013)
+ *
+ * RAPL provides more controls than just reporting energy consumption
+ * however here we only expose the 3 energy consumption free running
+ * counters (pp0, pkg, dram).
+ *
+ * Each of those counters increments in a power unit defined by the
+ * RAPL_POWER_UNIT MSR. On SandyBridge, this unit is 1/(2^16) Joules
+ * but it can vary.
+ *
+ * Counter to rapl events mappings:
+ *
+ *  pp0 counter: consumption of all physical cores (power plane 0)
+ * 	  event: rapl_energy_cores
+ *    perf code: 0x1
+ *
+ *  pkg counter: consumption of the whole processor package
+ *	  event: rapl_energy_pkg
+ *    perf code: 0x2
+ *
+ * dram counter: consumption of the dram domain (servers only)
+ *	  event: rapl_energy_dram
+ *    perf code: 0x3
+ *
+ * dram counter: consumption of the builtin-gpu domain (client only)
+ *	  event: rapl_energy_gpu
+ *    perf code: 0x4
+ *
+ * We manage those counters as free running (read-only). They may be
+ * use simultaneously by other tools, such as turbostat.
+ *
+ * The events only support system-wide mode counting. There is no
+ * sampling support because it does not make sense and is not
+ * supported by the RAPL hardware.
+ *
+ * Because we want to avoid floating-point operations in the kernel,
+ * the events are all reported in fixed point arithmetic (32.32).
+ * Tools must adjust the counts to convert them to Watts using
+ * the duration of the measurement. Tools may use a function such as
+ * ldexp(raw_count, -32);
+ */
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/perf_event.h>
+#include <asm/cpu_device_id.h>
+#include "../perf_event.h"
+
+/*
+ * RAPL energy status counters
+ */
+#define RAPL_IDX_PP0_NRG_STAT	0	/* all cores */
+#define INTEL_RAPL_PP0		0x1	/* pseudo-encoding */
+#define RAPL_IDX_PKG_NRG_STAT	1	/* entire package */
+#define INTEL_RAPL_PKG		0x2	/* pseudo-encoding */
+#define RAPL_IDX_RAM_NRG_STAT	2	/* DRAM */
+#define INTEL_RAPL_RAM		0x3	/* pseudo-encoding */
+#define RAPL_IDX_PP1_NRG_STAT	3	/* gpu */
+#define INTEL_RAPL_PP1		0x4	/* pseudo-encoding */
+
+#define NR_RAPL_DOMAINS         0x4
+static const char *rapl_domain_names[NR_RAPL_DOMAINS] __initconst = {
+	"pp0-core",
+	"package",
+	"dram",
+	"pp1-gpu",
+};
+
+/* Clients have PP0, PKG */
+#define RAPL_IDX_CLN	(1<<RAPL_IDX_PP0_NRG_STAT|\
+			 1<<RAPL_IDX_PKG_NRG_STAT|\
+			 1<<RAPL_IDX_PP1_NRG_STAT)
+
+/* Servers have PP0, PKG, RAM */
+#define RAPL_IDX_SRV	(1<<RAPL_IDX_PP0_NRG_STAT|\
+			 1<<RAPL_IDX_PKG_NRG_STAT|\
+			 1<<RAPL_IDX_RAM_NRG_STAT)
+
+/* Servers have PP0, PKG, RAM, PP1 */
+#define RAPL_IDX_HSW	(1<<RAPL_IDX_PP0_NRG_STAT|\
+			 1<<RAPL_IDX_PKG_NRG_STAT|\
+			 1<<RAPL_IDX_RAM_NRG_STAT|\
+			 1<<RAPL_IDX_PP1_NRG_STAT)
+
+/* Knights Landing has PKG, RAM */
+#define RAPL_IDX_KNL	(1<<RAPL_IDX_PKG_NRG_STAT|\
+			 1<<RAPL_IDX_RAM_NRG_STAT)
+
+/*
+ * event code: LSB 8 bits, passed in attr->config
+ * any other bit is reserved
+ */
+#define RAPL_EVENT_MASK	0xFFULL
+
+#define DEFINE_RAPL_FORMAT_ATTR(_var, _name, _format)		\
+static ssize_t __rapl_##_var##_show(struct kobject *kobj,	\
+				struct kobj_attribute *attr,	\
+				char *page)			\
+{								\
+	BUILD_BUG_ON(sizeof(_format) >= PAGE_SIZE);		\
+	return sprintf(page, _format "\n");			\
+}								\
+static struct kobj_attribute format_attr_##_var =		\
+	__ATTR(_name, 0444, __rapl_##_var##_show, NULL)
+
+#define RAPL_CNTR_WIDTH 32 /* 32-bit rapl counters */
+
+#define RAPL_EVENT_ATTR_STR(_name, v, str)				\
+static struct perf_pmu_events_attr event_attr_##v = {			\
+	.attr		= __ATTR(_name, 0444, rapl_sysfs_show, NULL),	\
+	.id		= 0,						\
+	.event_str	= str,						\
+};
+
+struct rapl_pmu {
+	spinlock_t	 lock;
+	int		 n_active; /* number of active events */
+	struct list_head active_list;
+	struct pmu	 *pmu; /* pointer to rapl_pmu_class */
+	ktime_t		 timer_interval; /* in ktime_t unit */
+	struct hrtimer   hrtimer;
+};
+
+static int rapl_hw_unit[NR_RAPL_DOMAINS] __read_mostly;  /* 1/2^hw_unit Joule */
+static struct pmu rapl_pmu_class;
+static cpumask_t rapl_cpu_mask;
+static int rapl_cntr_mask;
+
+static DEFINE_PER_CPU(struct rapl_pmu *, rapl_pmu);
+static DEFINE_PER_CPU(struct rapl_pmu *, rapl_pmu_to_free);
+
+static struct x86_pmu_quirk *rapl_quirks;
+static inline u64 rapl_read_counter(struct perf_event *event)
+{
+	u64 raw;
+	rdmsrl(event->hw.event_base, raw);
+	return raw;
+}
+
+#define rapl_add_quirk(func_)						\
+do {									\
+	static struct x86_pmu_quirk __quirk __initdata = {		\
+		.func = func_,						\
+	};								\
+	__quirk.next = rapl_quirks;					\
+	rapl_quirks = &__quirk;						\
+} while (0)
+
+static inline u64 rapl_scale(u64 v, int cfg)
+{
+	if (cfg > NR_RAPL_DOMAINS) {
+		pr_warn("invalid domain %d, failed to scale data\n", cfg);
+		return v;
+	}
+	/*
+	 * scale delta to smallest unit (1/2^32)
+	 * users must then scale back: count * 1/(1e9*2^32) to get Joules
+	 * or use ldexp(count, -32).
+	 * Watts = Joules/Time delta
+	 */
+	return v << (32 - rapl_hw_unit[cfg - 1]);
+}
+
+static u64 rapl_event_update(struct perf_event *event)
+{
+	struct hw_perf_event *hwc = &event->hw;
+	u64 prev_raw_count, new_raw_count;
+	s64 delta, sdelta;
+	int shift = RAPL_CNTR_WIDTH;
+
+again:
+	prev_raw_count = local64_read(&hwc->prev_count);
+	rdmsrl(event->hw.event_base, new_raw_count);
+
+	if (local64_cmpxchg(&hwc->prev_count, prev_raw_count,
+			    new_raw_count) != prev_raw_count) {
+		cpu_relax();
+		goto again;
+	}
+
+	/*
+	 * Now we have the new raw value and have updated the prev
+	 * timestamp already. We can now calculate the elapsed delta
+	 * (event-)time and add that to the generic event.
+	 *
+	 * Careful, not all hw sign-extends above the physical width
+	 * of the count.
+	 */
+	delta = (new_raw_count << shift) - (prev_raw_count << shift);
+	delta >>= shift;
+
+	sdelta = rapl_scale(delta, event->hw.config);
+
+	local64_add(sdelta, &event->count);
+
+	return new_raw_count;
+}
+
+static void rapl_start_hrtimer(struct rapl_pmu *pmu)
+{
+       hrtimer_start(&pmu->hrtimer, pmu->timer_interval,
+		     HRTIMER_MODE_REL_PINNED);
+}
+
+static void rapl_stop_hrtimer(struct rapl_pmu *pmu)
+{
+	hrtimer_cancel(&pmu->hrtimer);
+}
+
+static enum hrtimer_restart rapl_hrtimer_handle(struct hrtimer *hrtimer)
+{
+	struct rapl_pmu *pmu = __this_cpu_read(rapl_pmu);
+	struct perf_event *event;
+	unsigned long flags;
+
+	if (!pmu->n_active)
+		return HRTIMER_NORESTART;
+
+	spin_lock_irqsave(&pmu->lock, flags);
+
+	list_for_each_entry(event, &pmu->active_list, active_entry) {
+		rapl_event_update(event);
+	}
+
+	spin_unlock_irqrestore(&pmu->lock, flags);
+
+	hrtimer_forward_now(hrtimer, pmu->timer_interval);
+
+	return HRTIMER_RESTART;
+}
+
+static void rapl_hrtimer_init(struct rapl_pmu *pmu)
+{
+	struct hrtimer *hr = &pmu->hrtimer;
+
+	hrtimer_init(hr, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
+	hr->function = rapl_hrtimer_handle;
+}
+
+static void __rapl_pmu_event_start(struct rapl_pmu *pmu,
+				   struct perf_event *event)
+{
+	if (WARN_ON_ONCE(!(event->hw.state & PERF_HES_STOPPED)))
+		return;
+
+	event->hw.state = 0;
+
+	list_add_tail(&event->active_entry, &pmu->active_list);
+
+	local64_set(&event->hw.prev_count, rapl_read_counter(event));
+
+	pmu->n_active++;
+	if (pmu->n_active == 1)
+		rapl_start_hrtimer(pmu);
+}
+
+static void rapl_pmu_event_start(struct perf_event *event, int mode)
+{
+	struct rapl_pmu *pmu = __this_cpu_read(rapl_pmu);
+	unsigned long flags;
+
+	spin_lock_irqsave(&pmu->lock, flags);
+	__rapl_pmu_event_start(pmu, event);
+	spin_unlock_irqrestore(&pmu->lock, flags);
+}
+
+static void rapl_pmu_event_stop(struct perf_event *event, int mode)
+{
+	struct rapl_pmu *pmu = __this_cpu_read(rapl_pmu);
+	struct hw_perf_event *hwc = &event->hw;
+	unsigned long flags;
+
+	spin_lock_irqsave(&pmu->lock, flags);
+
+	/* mark event as deactivated and stopped */
+	if (!(hwc->state & PERF_HES_STOPPED)) {
+		WARN_ON_ONCE(pmu->n_active <= 0);
+		pmu->n_active--;
+		if (pmu->n_active == 0)
+			rapl_stop_hrtimer(pmu);
+
+		list_del(&event->active_entry);
+
+		WARN_ON_ONCE(hwc->state & PERF_HES_STOPPED);
+		hwc->state |= PERF_HES_STOPPED;
+	}
+
+	/* check if update of sw counter is necessary */
+	if ((mode & PERF_EF_UPDATE) && !(hwc->state & PERF_HES_UPTODATE)) {
+		/*
+		 * Drain the remaining delta count out of a event
+		 * that we are disabling:
+		 */
+		rapl_event_update(event);
+		hwc->state |= PERF_HES_UPTODATE;
+	}
+
+	spin_unlock_irqrestore(&pmu->lock, flags);
+}
+
+static int rapl_pmu_event_add(struct perf_event *event, int mode)
+{
+	struct rapl_pmu *pmu = __this_cpu_read(rapl_pmu);
+	struct hw_perf_event *hwc = &event->hw;
+	unsigned long flags;
+
+	spin_lock_irqsave(&pmu->lock, flags);
+
+	hwc->state = PERF_HES_UPTODATE | PERF_HES_STOPPED;
+
+	if (mode & PERF_EF_START)
+		__rapl_pmu_event_start(pmu, event);
+
+	spin_unlock_irqrestore(&pmu->lock, flags);
+
+	return 0;
+}
+
+static void rapl_pmu_event_del(struct perf_event *event, int flags)
+{
+	rapl_pmu_event_stop(event, PERF_EF_UPDATE);
+}
+
+static int rapl_pmu_event_init(struct perf_event *event)
+{
+	u64 cfg = event->attr.config & RAPL_EVENT_MASK;
+	int bit, msr, ret = 0;
+
+	/* only look at RAPL events */
+	if (event->attr.type != rapl_pmu_class.type)
+		return -ENOENT;
+
+	/* check only supported bits are set */
+	if (event->attr.config & ~RAPL_EVENT_MASK)
+		return -EINVAL;
+
+	/*
+	 * check event is known (determines counter)
+	 */
+	switch (cfg) {
+	case INTEL_RAPL_PP0:
+		bit = RAPL_IDX_PP0_NRG_STAT;
+		msr = MSR_PP0_ENERGY_STATUS;
+		break;
+	case INTEL_RAPL_PKG:
+		bit = RAPL_IDX_PKG_NRG_STAT;
+		msr = MSR_PKG_ENERGY_STATUS;
+		break;
+	case INTEL_RAPL_RAM:
+		bit = RAPL_IDX_RAM_NRG_STAT;
+		msr = MSR_DRAM_ENERGY_STATUS;
+		break;
+	case INTEL_RAPL_PP1:
+		bit = RAPL_IDX_PP1_NRG_STAT;
+		msr = MSR_PP1_ENERGY_STATUS;
+		break;
+	default:
+		return -EINVAL;
+	}
+	/* check event supported */
+	if (!(rapl_cntr_mask & (1 << bit)))
+		return -EINVAL;
+
+	/* unsupported modes and filters */
+	if (event->attr.exclude_user   ||
+	    event->attr.exclude_kernel ||
+	    event->attr.exclude_hv     ||
+	    event->attr.exclude_idle   ||
+	    event->attr.exclude_host   ||
+	    event->attr.exclude_guest  ||
+	    event->attr.sample_period) /* no sampling */
+		return -EINVAL;
+
+	/* must be done before validate_group */
+	event->hw.event_base = msr;
+	event->hw.config = cfg;
+	event->hw.idx = bit;
+
+	return ret;
+}
+
+static void rapl_pmu_event_read(struct perf_event *event)
+{
+	rapl_event_update(event);
+}
+
+static ssize_t rapl_get_attr_cpumask(struct device *dev,
+				struct device_attribute *attr, char *buf)
+{
+	return cpumap_print_to_pagebuf(true, buf, &rapl_cpu_mask);
+}
+
+static DEVICE_ATTR(cpumask, S_IRUGO, rapl_get_attr_cpumask, NULL);
+
+static struct attribute *rapl_pmu_attrs[] = {
+	&dev_attr_cpumask.attr,
+	NULL,
+};
+
+static struct attribute_group rapl_pmu_attr_group = {
+	.attrs = rapl_pmu_attrs,
+};
+
+static ssize_t rapl_sysfs_show(struct device *dev,
+			       struct device_attribute *attr,
+			       char *page)
+{
+	struct perf_pmu_events_attr *pmu_attr = \
+		container_of(attr, struct perf_pmu_events_attr, attr);
+
+	if (pmu_attr->event_str)
+		return sprintf(page, "%s", pmu_attr->event_str);
+
+	return 0;
+}
+
+RAPL_EVENT_ATTR_STR(energy-cores, rapl_cores, "event=0x01");
+RAPL_EVENT_ATTR_STR(energy-pkg  ,   rapl_pkg, "event=0x02");
+RAPL_EVENT_ATTR_STR(energy-ram  ,   rapl_ram, "event=0x03");
+RAPL_EVENT_ATTR_STR(energy-gpu  ,   rapl_gpu, "event=0x04");
+
+RAPL_EVENT_ATTR_STR(energy-cores.unit, rapl_cores_unit, "Joules");
+RAPL_EVENT_ATTR_STR(energy-pkg.unit  ,   rapl_pkg_unit, "Joules");
+RAPL_EVENT_ATTR_STR(energy-ram.unit  ,   rapl_ram_unit, "Joules");
+RAPL_EVENT_ATTR_STR(energy-gpu.unit  ,   rapl_gpu_unit, "Joules");
+
+/*
+ * we compute in 0.23 nJ increments regardless of MSR
+ */
+RAPL_EVENT_ATTR_STR(energy-cores.scale, rapl_cores_scale, "2.3283064365386962890625e-10");
+RAPL_EVENT_ATTR_STR(energy-pkg.scale,     rapl_pkg_scale, "2.3283064365386962890625e-10");
+RAPL_EVENT_ATTR_STR(energy-ram.scale,     rapl_ram_scale, "2.3283064365386962890625e-10");
+RAPL_EVENT_ATTR_STR(energy-gpu.scale,     rapl_gpu_scale, "2.3283064365386962890625e-10");
+
+static struct attribute *rapl_events_srv_attr[] = {
+	EVENT_PTR(rapl_cores),
+	EVENT_PTR(rapl_pkg),
+	EVENT_PTR(rapl_ram),
+
+	EVENT_PTR(rapl_cores_unit),
+	EVENT_PTR(rapl_pkg_unit),
+	EVENT_PTR(rapl_ram_unit),
+
+	EVENT_PTR(rapl_cores_scale),
+	EVENT_PTR(rapl_pkg_scale),
+	EVENT_PTR(rapl_ram_scale),
+	NULL,
+};
+
+static struct attribute *rapl_events_cln_attr[] = {
+	EVENT_PTR(rapl_cores),
+	EVENT_PTR(rapl_pkg),
+	EVENT_PTR(rapl_gpu),
+
+	EVENT_PTR(rapl_cores_unit),
+	EVENT_PTR(rapl_pkg_unit),
+	EVENT_PTR(rapl_gpu_unit),
+
+	EVENT_PTR(rapl_cores_scale),
+	EVENT_PTR(rapl_pkg_scale),
+	EVENT_PTR(rapl_gpu_scale),
+	NULL,
+};
+
+static struct attribute *rapl_events_hsw_attr[] = {
+	EVENT_PTR(rapl_cores),
+	EVENT_PTR(rapl_pkg),
+	EVENT_PTR(rapl_gpu),
+	EVENT_PTR(rapl_ram),
+
+	EVENT_PTR(rapl_cores_unit),
+	EVENT_PTR(rapl_pkg_unit),
+	EVENT_PTR(rapl_gpu_unit),
+	EVENT_PTR(rapl_ram_unit),
+
+	EVENT_PTR(rapl_cores_scale),
+	EVENT_PTR(rapl_pkg_scale),
+	EVENT_PTR(rapl_gpu_scale),
+	EVENT_PTR(rapl_ram_scale),
+	NULL,
+};
+
+static struct attribute *rapl_events_knl_attr[] = {
+	EVENT_PTR(rapl_pkg),
+	EVENT_PTR(rapl_ram),
+
+	EVENT_PTR(rapl_pkg_unit),
+	EVENT_PTR(rapl_ram_unit),
+
+	EVENT_PTR(rapl_pkg_scale),
+	EVENT_PTR(rapl_ram_scale),
+	NULL,
+};
+
+static struct attribute_group rapl_pmu_events_group = {
+	.name = "events",
+	.attrs = NULL, /* patched at runtime */
+};
+
+DEFINE_RAPL_FORMAT_ATTR(event, event, "config:0-7");
+static struct attribute *rapl_formats_attr[] = {
+	&format_attr_event.attr,
+	NULL,
+};
+
+static struct attribute_group rapl_pmu_format_group = {
+	.name = "format",
+	.attrs = rapl_formats_attr,
+};
+
+const struct attribute_group *rapl_attr_groups[] = {
+	&rapl_pmu_attr_group,
+	&rapl_pmu_format_group,
+	&rapl_pmu_events_group,
+	NULL,
+};
+
+static struct pmu rapl_pmu_class = {
+	.attr_groups	= rapl_attr_groups,
+	.task_ctx_nr	= perf_invalid_context, /* system-wide only */
+	.event_init	= rapl_pmu_event_init,
+	.add		= rapl_pmu_event_add, /* must have */
+	.del		= rapl_pmu_event_del, /* must have */
+	.start		= rapl_pmu_event_start,
+	.stop		= rapl_pmu_event_stop,
+	.read		= rapl_pmu_event_read,
+};
+
+static void rapl_cpu_exit(int cpu)
+{
+	struct rapl_pmu *pmu = per_cpu(rapl_pmu, cpu);
+	int i, phys_id = topology_physical_package_id(cpu);
+	int target = -1;
+
+	/* find a new cpu on same package */
+	for_each_online_cpu(i) {
+		if (i == cpu)
+			continue;
+		if (phys_id == topology_physical_package_id(i)) {
+			target = i;
+			break;
+		}
+	}
+	/*
+	 * clear cpu from cpumask
+	 * if was set in cpumask and still some cpu on package,
+	 * then move to new cpu
+	 */
+	if (cpumask_test_and_clear_cpu(cpu, &rapl_cpu_mask) && target >= 0)
+		cpumask_set_cpu(target, &rapl_cpu_mask);
+
+	WARN_ON(cpumask_empty(&rapl_cpu_mask));
+	/*
+	 * migrate events and context to new cpu
+	 */
+	if (target >= 0)
+		perf_pmu_migrate_context(pmu->pmu, cpu, target);
+
+	/* cancel overflow polling timer for CPU */
+	rapl_stop_hrtimer(pmu);
+}
+
+static void rapl_cpu_init(int cpu)
+{
+	int i, phys_id = topology_physical_package_id(cpu);
+
+	/* check if phys_is is already covered */
+	for_each_cpu(i, &rapl_cpu_mask) {
+		if (phys_id == topology_physical_package_id(i))
+			return;
+	}
+	/* was not found, so add it */
+	cpumask_set_cpu(cpu, &rapl_cpu_mask);
+}
+
+static __init void rapl_hsw_server_quirk(void)
+{
+	/*
+	 * DRAM domain on HSW server has fixed energy unit which can be
+	 * different than the unit from power unit MSR.
+	 * "Intel Xeon Processor E5-1600 and E5-2600 v3 Product Families, V2
+	 * of 2. Datasheet, September 2014, Reference Number: 330784-001 "
+	 */
+	rapl_hw_unit[RAPL_IDX_RAM_NRG_STAT] = 16;
+}
+
+static int rapl_cpu_prepare(int cpu)
+{
+	struct rapl_pmu *pmu = per_cpu(rapl_pmu, cpu);
+	int phys_id = topology_physical_package_id(cpu);
+	u64 ms;
+
+	if (pmu)
+		return 0;
+
+	if (phys_id < 0)
+		return -1;
+
+	pmu = kzalloc_node(sizeof(*pmu), GFP_KERNEL, cpu_to_node(cpu));
+	if (!pmu)
+		return -1;
+	spin_lock_init(&pmu->lock);
+
+	INIT_LIST_HEAD(&pmu->active_list);
+
+	pmu->pmu = &rapl_pmu_class;
+
+	/*
+	 * use reference of 200W for scaling the timeout
+	 * to avoid missing counter overflows.
+	 * 200W = 200 Joules/sec
+	 * divide interval by 2 to avoid lockstep (2 * 100)
+	 * if hw unit is 32, then we use 2 ms 1/200/2
+	 */
+	if (rapl_hw_unit[0] < 32)
+		ms = (1000 / (2 * 100)) * (1ULL << (32 - rapl_hw_unit[0] - 1));
+	else
+		ms = 2;
+
+	pmu->timer_interval = ms_to_ktime(ms);
+
+	rapl_hrtimer_init(pmu);
+
+	/* set RAPL pmu for this cpu for now */
+	per_cpu(rapl_pmu, cpu) = pmu;
+	per_cpu(rapl_pmu_to_free, cpu) = NULL;
+
+	return 0;
+}
+
+static void rapl_cpu_kfree(int cpu)
+{
+	struct rapl_pmu *pmu = per_cpu(rapl_pmu_to_free, cpu);
+
+	kfree(pmu);
+
+	per_cpu(rapl_pmu_to_free, cpu) = NULL;
+}
+
+static int rapl_cpu_dying(int cpu)
+{
+	struct rapl_pmu *pmu = per_cpu(rapl_pmu, cpu);
+
+	if (!pmu)
+		return 0;
+
+	per_cpu(rapl_pmu, cpu) = NULL;
+
+	per_cpu(rapl_pmu_to_free, cpu) = pmu;
+
+	return 0;
+}
+
+static int rapl_cpu_notifier(struct notifier_block *self,
+			     unsigned long action, void *hcpu)
+{
+	unsigned int cpu = (long)hcpu;
+
+	switch (action & ~CPU_TASKS_FROZEN) {
+	case CPU_UP_PREPARE:
+		rapl_cpu_prepare(cpu);
+		break;
+	case CPU_STARTING:
+		rapl_cpu_init(cpu);
+		break;
+	case CPU_UP_CANCELED:
+	case CPU_DYING:
+		rapl_cpu_dying(cpu);
+		break;
+	case CPU_ONLINE:
+	case CPU_DEAD:
+		rapl_cpu_kfree(cpu);
+		break;
+	case CPU_DOWN_PREPARE:
+		rapl_cpu_exit(cpu);
+		break;
+	default:
+		break;
+	}
+
+	return NOTIFY_OK;
+}
+
+static int rapl_check_hw_unit(void)
+{
+	u64 msr_rapl_power_unit_bits;
+	int i;
+
+	/* protect rdmsrl() to handle virtualization */
+	if (rdmsrl_safe(MSR_RAPL_POWER_UNIT, &msr_rapl_power_unit_bits))
+		return -1;
+	for (i = 0; i < NR_RAPL_DOMAINS; i++)
+		rapl_hw_unit[i] = (msr_rapl_power_unit_bits >> 8) & 0x1FULL;
+
+	return 0;
+}
+
+static const struct x86_cpu_id rapl_cpu_match[] = {
+	[0] = { .vendor = X86_VENDOR_INTEL, .family = 6 },
+	[1] = {},
+};
+
+static int __init rapl_pmu_init(void)
+{
+	struct rapl_pmu *pmu;
+	int cpu, ret;
+	struct x86_pmu_quirk *quirk;
+	int i;
+
+	/*
+	 * check for Intel processor family 6
+	 */
+	if (!x86_match_cpu(rapl_cpu_match))
+		return 0;
+
+	/* check supported CPU */
+	switch (boot_cpu_data.x86_model) {
+	case 42: /* Sandy Bridge */
+	case 58: /* Ivy Bridge */
+		rapl_cntr_mask = RAPL_IDX_CLN;
+		rapl_pmu_events_group.attrs = rapl_events_cln_attr;
+		break;
+	case 63: /* Haswell-Server */
+		rapl_add_quirk(rapl_hsw_server_quirk);
+		rapl_cntr_mask = RAPL_IDX_SRV;
+		rapl_pmu_events_group.attrs = rapl_events_srv_attr;
+		break;
+	case 60: /* Haswell */
+	case 69: /* Haswell-Celeron */
+	case 61: /* Broadwell */
+		rapl_cntr_mask = RAPL_IDX_HSW;
+		rapl_pmu_events_group.attrs = rapl_events_hsw_attr;
+		break;
+	case 45: /* Sandy Bridge-EP */
+	case 62: /* IvyTown */
+		rapl_cntr_mask = RAPL_IDX_SRV;
+		rapl_pmu_events_group.attrs = rapl_events_srv_attr;
+		break;
+	case 87: /* Knights Landing */
+		rapl_add_quirk(rapl_hsw_server_quirk);
+		rapl_cntr_mask = RAPL_IDX_KNL;
+		rapl_pmu_events_group.attrs = rapl_events_knl_attr;
+
+	default:
+		/* unsupported */
+		return 0;
+	}
+	ret = rapl_check_hw_unit();
+	if (ret)
+		return ret;
+
+	/* run cpu model quirks */
+	for (quirk = rapl_quirks; quirk; quirk = quirk->next)
+		quirk->func();
+	cpu_notifier_register_begin();
+
+	for_each_online_cpu(cpu) {
+		ret = rapl_cpu_prepare(cpu);
+		if (ret)
+			goto out;
+		rapl_cpu_init(cpu);
+	}
+
+	__perf_cpu_notifier(rapl_cpu_notifier);
+
+	ret = perf_pmu_register(&rapl_pmu_class, "power", -1);
+	if (WARN_ON(ret)) {
+		pr_info("RAPL PMU detected, registration failed (%d), RAPL PMU disabled\n", ret);
+		cpu_notifier_register_done();
+		return -1;
+	}
+
+	pmu = __this_cpu_read(rapl_pmu);
+
+	pr_info("RAPL PMU detected,"
+		" API unit is 2^-32 Joules,"
+		" %d fixed counters"
+		" %llu ms ovfl timer\n",
+		hweight32(rapl_cntr_mask),
+		ktime_to_ms(pmu->timer_interval));
+	for (i = 0; i < NR_RAPL_DOMAINS; i++) {
+		if (rapl_cntr_mask & (1 << i)) {
+			pr_info("hw unit of domain %s 2^-%d Joules\n",
+				rapl_domain_names[i], rapl_hw_unit[i]);
+		}
+	}
+out:
+	cpu_notifier_register_done();
+
+	return 0;
+}
+device_initcall(rapl_pmu_init);
--- /dev/null
+++ zfcpdump-kernel-4.4/arch/x86/events/intel/uncore.c
@@ -0,0 +1,1398 @@
+#include "uncore.h"
+
+static struct intel_uncore_type *empty_uncore[] = { NULL, };
+struct intel_uncore_type **uncore_msr_uncores = empty_uncore;
+struct intel_uncore_type **uncore_pci_uncores = empty_uncore;
+
+static bool pcidrv_registered;
+struct pci_driver *uncore_pci_driver;
+/* pci bus to socket mapping */
+DEFINE_RAW_SPINLOCK(pci2phy_map_lock);
+struct list_head pci2phy_map_head = LIST_HEAD_INIT(pci2phy_map_head);
+struct pci_dev *uncore_extra_pci_dev[UNCORE_SOCKET_MAX][UNCORE_EXTRA_PCI_DEV_MAX];
+
+static DEFINE_RAW_SPINLOCK(uncore_box_lock);
+/* mask of cpus that collect uncore events */
+static cpumask_t uncore_cpu_mask;
+
+/* constraint for the fixed counter */
+static struct event_constraint uncore_constraint_fixed =
+	EVENT_CONSTRAINT(~0ULL, 1 << UNCORE_PMC_IDX_FIXED, ~0ULL);
+struct event_constraint uncore_constraint_empty =
+	EVENT_CONSTRAINT(0, 0, 0);
+
+int uncore_pcibus_to_physid(struct pci_bus *bus)
+{
+	struct pci2phy_map *map;
+	int phys_id = -1;
+
+	raw_spin_lock(&pci2phy_map_lock);
+	list_for_each_entry(map, &pci2phy_map_head, list) {
+		if (map->segment == pci_domain_nr(bus)) {
+			phys_id = map->pbus_to_physid[bus->number];
+			break;
+		}
+	}
+	raw_spin_unlock(&pci2phy_map_lock);
+
+	return phys_id;
+}
+
+struct pci2phy_map *__find_pci2phy_map(int segment)
+{
+	struct pci2phy_map *map, *alloc = NULL;
+	int i;
+
+	lockdep_assert_held(&pci2phy_map_lock);
+
+lookup:
+	list_for_each_entry(map, &pci2phy_map_head, list) {
+		if (map->segment == segment)
+			goto end;
+	}
+
+	if (!alloc) {
+		raw_spin_unlock(&pci2phy_map_lock);
+		alloc = kmalloc(sizeof(struct pci2phy_map), GFP_KERNEL);
+		raw_spin_lock(&pci2phy_map_lock);
+
+		if (!alloc)
+			return NULL;
+
+		goto lookup;
+	}
+
+	map = alloc;
+	alloc = NULL;
+	map->segment = segment;
+	for (i = 0; i < 256; i++)
+		map->pbus_to_physid[i] = -1;
+	list_add_tail(&map->list, &pci2phy_map_head);
+
+end:
+	kfree(alloc);
+	return map;
+}
+
+ssize_t uncore_event_show(struct kobject *kobj,
+			  struct kobj_attribute *attr, char *buf)
+{
+	struct uncore_event_desc *event =
+		container_of(attr, struct uncore_event_desc, attr);
+	return sprintf(buf, "%s", event->config);
+}
+
+struct intel_uncore_pmu *uncore_event_to_pmu(struct perf_event *event)
+{
+	return container_of(event->pmu, struct intel_uncore_pmu, pmu);
+}
+
+struct intel_uncore_box *uncore_pmu_to_box(struct intel_uncore_pmu *pmu, int cpu)
+{
+	struct intel_uncore_box *box;
+
+	box = *per_cpu_ptr(pmu->box, cpu);
+	if (box)
+		return box;
+
+	raw_spin_lock(&uncore_box_lock);
+	/* Recheck in lock to handle races. */
+	if (*per_cpu_ptr(pmu->box, cpu))
+		goto out;
+	list_for_each_entry(box, &pmu->box_list, list) {
+		if (box->phys_id == topology_physical_package_id(cpu)) {
+			atomic_inc(&box->refcnt);
+			*per_cpu_ptr(pmu->box, cpu) = box;
+			break;
+		}
+	}
+out:
+	raw_spin_unlock(&uncore_box_lock);
+
+	return *per_cpu_ptr(pmu->box, cpu);
+}
+
+struct intel_uncore_box *uncore_event_to_box(struct perf_event *event)
+{
+	/*
+	 * perf core schedules event on the basis of cpu, uncore events are
+	 * collected by one of the cpus inside a physical package.
+	 */
+	return uncore_pmu_to_box(uncore_event_to_pmu(event), smp_processor_id());
+}
+
+u64 uncore_msr_read_counter(struct intel_uncore_box *box, struct perf_event *event)
+{
+	u64 count;
+
+	rdmsrl(event->hw.event_base, count);
+
+	return count;
+}
+
+/*
+ * generic get constraint function for shared match/mask registers.
+ */
+struct event_constraint *
+uncore_get_constraint(struct intel_uncore_box *box, struct perf_event *event)
+{
+	struct intel_uncore_extra_reg *er;
+	struct hw_perf_event_extra *reg1 = &event->hw.extra_reg;
+	struct hw_perf_event_extra *reg2 = &event->hw.branch_reg;
+	unsigned long flags;
+	bool ok = false;
+
+	/*
+	 * reg->alloc can be set due to existing state, so for fake box we
+	 * need to ignore this, otherwise we might fail to allocate proper
+	 * fake state for this extra reg constraint.
+	 */
+	if (reg1->idx == EXTRA_REG_NONE ||
+	    (!uncore_box_is_fake(box) && reg1->alloc))
+		return NULL;
+
+	er = &box->shared_regs[reg1->idx];
+	raw_spin_lock_irqsave(&er->lock, flags);
+	if (!atomic_read(&er->ref) ||
+	    (er->config1 == reg1->config && er->config2 == reg2->config)) {
+		atomic_inc(&er->ref);
+		er->config1 = reg1->config;
+		er->config2 = reg2->config;
+		ok = true;
+	}
+	raw_spin_unlock_irqrestore(&er->lock, flags);
+
+	if (ok) {
+		if (!uncore_box_is_fake(box))
+			reg1->alloc = 1;
+		return NULL;
+	}
+
+	return &uncore_constraint_empty;
+}
+
+void uncore_put_constraint(struct intel_uncore_box *box, struct perf_event *event)
+{
+	struct intel_uncore_extra_reg *er;
+	struct hw_perf_event_extra *reg1 = &event->hw.extra_reg;
+
+	/*
+	 * Only put constraint if extra reg was actually allocated. Also
+	 * takes care of event which do not use an extra shared reg.
+	 *
+	 * Also, if this is a fake box we shouldn't touch any event state
+	 * (reg->alloc) and we don't care about leaving inconsistent box
+	 * state either since it will be thrown out.
+	 */
+	if (uncore_box_is_fake(box) || !reg1->alloc)
+		return;
+
+	er = &box->shared_regs[reg1->idx];
+	atomic_dec(&er->ref);
+	reg1->alloc = 0;
+}
+
+u64 uncore_shared_reg_config(struct intel_uncore_box *box, int idx)
+{
+	struct intel_uncore_extra_reg *er;
+	unsigned long flags;
+	u64 config;
+
+	er = &box->shared_regs[idx];
+
+	raw_spin_lock_irqsave(&er->lock, flags);
+	config = er->config;
+	raw_spin_unlock_irqrestore(&er->lock, flags);
+
+	return config;
+}
+
+static void uncore_assign_hw_event(struct intel_uncore_box *box, struct perf_event *event, int idx)
+{
+	struct hw_perf_event *hwc = &event->hw;
+
+	hwc->idx = idx;
+	hwc->last_tag = ++box->tags[idx];
+
+	if (hwc->idx == UNCORE_PMC_IDX_FIXED) {
+		hwc->event_base = uncore_fixed_ctr(box);
+		hwc->config_base = uncore_fixed_ctl(box);
+		return;
+	}
+
+	hwc->config_base = uncore_event_ctl(box, hwc->idx);
+	hwc->event_base  = uncore_perf_ctr(box, hwc->idx);
+}
+
+void uncore_perf_event_update(struct intel_uncore_box *box, struct perf_event *event)
+{
+	u64 prev_count, new_count, delta;
+	int shift;
+
+	if (event->hw.idx >= UNCORE_PMC_IDX_FIXED)
+		shift = 64 - uncore_fixed_ctr_bits(box);
+	else
+		shift = 64 - uncore_perf_ctr_bits(box);
+
+	/* the hrtimer might modify the previous event value */
+again:
+	prev_count = local64_read(&event->hw.prev_count);
+	new_count = uncore_read_counter(box, event);
+	if (local64_xchg(&event->hw.prev_count, new_count) != prev_count)
+		goto again;
+
+	delta = (new_count << shift) - (prev_count << shift);
+	delta >>= shift;
+
+	local64_add(delta, &event->count);
+}
+
+/*
+ * The overflow interrupt is unavailable for SandyBridge-EP, is broken
+ * for SandyBridge. So we use hrtimer to periodically poll the counter
+ * to avoid overflow.
+ */
+static enum hrtimer_restart uncore_pmu_hrtimer(struct hrtimer *hrtimer)
+{
+	struct intel_uncore_box *box;
+	struct perf_event *event;
+	unsigned long flags;
+	int bit;
+
+	box = container_of(hrtimer, struct intel_uncore_box, hrtimer);
+	if (!box->n_active || box->cpu != smp_processor_id())
+		return HRTIMER_NORESTART;
+	/*
+	 * disable local interrupt to prevent uncore_pmu_event_start/stop
+	 * to interrupt the update process
+	 */
+	local_irq_save(flags);
+
+	/*
+	 * handle boxes with an active event list as opposed to active
+	 * counters
+	 */
+	list_for_each_entry(event, &box->active_list, active_entry) {
+		uncore_perf_event_update(box, event);
+	}
+
+	for_each_set_bit(bit, box->active_mask, UNCORE_PMC_IDX_MAX)
+		uncore_perf_event_update(box, box->events[bit]);
+
+	local_irq_restore(flags);
+
+	hrtimer_forward_now(hrtimer, ns_to_ktime(box->hrtimer_duration));
+	return HRTIMER_RESTART;
+}
+
+void uncore_pmu_start_hrtimer(struct intel_uncore_box *box)
+{
+	hrtimer_start(&box->hrtimer, ns_to_ktime(box->hrtimer_duration),
+		      HRTIMER_MODE_REL_PINNED);
+}
+
+void uncore_pmu_cancel_hrtimer(struct intel_uncore_box *box)
+{
+	hrtimer_cancel(&box->hrtimer);
+}
+
+static void uncore_pmu_init_hrtimer(struct intel_uncore_box *box)
+{
+	hrtimer_init(&box->hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
+	box->hrtimer.function = uncore_pmu_hrtimer;
+}
+
+static struct intel_uncore_box *uncore_alloc_box(struct intel_uncore_type *type, int node)
+{
+	struct intel_uncore_box *box;
+	int i, size;
+
+	size = sizeof(*box) + type->num_shared_regs * sizeof(struct intel_uncore_extra_reg);
+
+	box = kzalloc_node(size, GFP_KERNEL, node);
+	if (!box)
+		return NULL;
+
+	for (i = 0; i < type->num_shared_regs; i++)
+		raw_spin_lock_init(&box->shared_regs[i].lock);
+
+	uncore_pmu_init_hrtimer(box);
+	atomic_set(&box->refcnt, 1);
+	box->cpu = -1;
+	box->phys_id = -1;
+
+	/* set default hrtimer timeout */
+	box->hrtimer_duration = UNCORE_PMU_HRTIMER_INTERVAL;
+
+	INIT_LIST_HEAD(&box->active_list);
+
+	return box;
+}
+
+/*
+ * Using uncore_pmu_event_init pmu event_init callback
+ * as a detection point for uncore events.
+ */
+static int uncore_pmu_event_init(struct perf_event *event);
+
+static bool is_uncore_event(struct perf_event *event)
+{
+	return event->pmu->event_init == uncore_pmu_event_init;
+}
+
+static int
+uncore_collect_events(struct intel_uncore_box *box, struct perf_event *leader, bool dogrp)
+{
+	struct perf_event *event;
+	int n, max_count;
+
+	max_count = box->pmu->type->num_counters;
+	if (box->pmu->type->fixed_ctl)
+		max_count++;
+
+	if (box->n_events >= max_count)
+		return -EINVAL;
+
+	n = box->n_events;
+
+	if (is_uncore_event(leader)) {
+		box->event_list[n] = leader;
+		n++;
+	}
+
+	if (!dogrp)
+		return n;
+
+	list_for_each_entry(event, &leader->sibling_list, group_entry) {
+		if (!is_uncore_event(event) ||
+		    event->state <= PERF_EVENT_STATE_OFF)
+			continue;
+
+		if (n >= max_count)
+			return -EINVAL;
+
+		box->event_list[n] = event;
+		n++;
+	}
+	return n;
+}
+
+static struct event_constraint *
+uncore_get_event_constraint(struct intel_uncore_box *box, struct perf_event *event)
+{
+	struct intel_uncore_type *type = box->pmu->type;
+	struct event_constraint *c;
+
+	if (type->ops->get_constraint) {
+		c = type->ops->get_constraint(box, event);
+		if (c)
+			return c;
+	}
+
+	if (event->attr.config == UNCORE_FIXED_EVENT)
+		return &uncore_constraint_fixed;
+
+	if (type->constraints) {
+		for_each_event_constraint(c, type->constraints) {
+			if ((event->hw.config & c->cmask) == c->code)
+				return c;
+		}
+	}
+
+	return &type->unconstrainted;
+}
+
+static void uncore_put_event_constraint(struct intel_uncore_box *box, struct perf_event *event)
+{
+	if (box->pmu->type->ops->put_constraint)
+		box->pmu->type->ops->put_constraint(box, event);
+}
+
+static int uncore_assign_events(struct intel_uncore_box *box, int assign[], int n)
+{
+	unsigned long used_mask[BITS_TO_LONGS(UNCORE_PMC_IDX_MAX)];
+	struct event_constraint *c;
+	int i, wmin, wmax, ret = 0;
+	struct hw_perf_event *hwc;
+
+	bitmap_zero(used_mask, UNCORE_PMC_IDX_MAX);
+
+	for (i = 0, wmin = UNCORE_PMC_IDX_MAX, wmax = 0; i < n; i++) {
+		c = uncore_get_event_constraint(box, box->event_list[i]);
+		box->event_constraint[i] = c;
+		wmin = min(wmin, c->weight);
+		wmax = max(wmax, c->weight);
+	}
+
+	/* fastpath, try to reuse previous register */
+	for (i = 0; i < n; i++) {
+		hwc = &box->event_list[i]->hw;
+		c = box->event_constraint[i];
+
+		/* never assigned */
+		if (hwc->idx == -1)
+			break;
+
+		/* constraint still honored */
+		if (!test_bit(hwc->idx, c->idxmsk))
+			break;
+
+		/* not already used */
+		if (test_bit(hwc->idx, used_mask))
+			break;
+
+		__set_bit(hwc->idx, used_mask);
+		if (assign)
+			assign[i] = hwc->idx;
+	}
+	/* slow path */
+	if (i != n)
+		ret = perf_assign_events(box->event_constraint, n,
+					 wmin, wmax, n, assign);
+
+	if (!assign || ret) {
+		for (i = 0; i < n; i++)
+			uncore_put_event_constraint(box, box->event_list[i]);
+	}
+	return ret ? -EINVAL : 0;
+}
+
+static void uncore_pmu_event_start(struct perf_event *event, int flags)
+{
+	struct intel_uncore_box *box = uncore_event_to_box(event);
+	int idx = event->hw.idx;
+
+	if (WARN_ON_ONCE(!(event->hw.state & PERF_HES_STOPPED)))
+		return;
+
+	if (WARN_ON_ONCE(idx == -1 || idx >= UNCORE_PMC_IDX_MAX))
+		return;
+
+	event->hw.state = 0;
+	box->events[idx] = event;
+	box->n_active++;
+	__set_bit(idx, box->active_mask);
+
+	local64_set(&event->hw.prev_count, uncore_read_counter(box, event));
+	uncore_enable_event(box, event);
+
+	if (box->n_active == 1) {
+		uncore_enable_box(box);
+		uncore_pmu_start_hrtimer(box);
+	}
+}
+
+static void uncore_pmu_event_stop(struct perf_event *event, int flags)
+{
+	struct intel_uncore_box *box = uncore_event_to_box(event);
+	struct hw_perf_event *hwc = &event->hw;
+
+	if (__test_and_clear_bit(hwc->idx, box->active_mask)) {
+		uncore_disable_event(box, event);
+		box->n_active--;
+		box->events[hwc->idx] = NULL;
+		WARN_ON_ONCE(hwc->state & PERF_HES_STOPPED);
+		hwc->state |= PERF_HES_STOPPED;
+
+		if (box->n_active == 0) {
+			uncore_disable_box(box);
+			uncore_pmu_cancel_hrtimer(box);
+		}
+	}
+
+	if ((flags & PERF_EF_UPDATE) && !(hwc->state & PERF_HES_UPTODATE)) {
+		/*
+		 * Drain the remaining delta count out of a event
+		 * that we are disabling:
+		 */
+		uncore_perf_event_update(box, event);
+		hwc->state |= PERF_HES_UPTODATE;
+	}
+}
+
+static int uncore_pmu_event_add(struct perf_event *event, int flags)
+{
+	struct intel_uncore_box *box = uncore_event_to_box(event);
+	struct hw_perf_event *hwc = &event->hw;
+	int assign[UNCORE_PMC_IDX_MAX];
+	int i, n, ret;
+
+	if (!box)
+		return -ENODEV;
+
+	ret = n = uncore_collect_events(box, event, false);
+	if (ret < 0)
+		return ret;
+
+	hwc->state = PERF_HES_UPTODATE | PERF_HES_STOPPED;
+	if (!(flags & PERF_EF_START))
+		hwc->state |= PERF_HES_ARCH;
+
+	ret = uncore_assign_events(box, assign, n);
+	if (ret)
+		return ret;
+
+	/* save events moving to new counters */
+	for (i = 0; i < box->n_events; i++) {
+		event = box->event_list[i];
+		hwc = &event->hw;
+
+		if (hwc->idx == assign[i] &&
+			hwc->last_tag == box->tags[assign[i]])
+			continue;
+		/*
+		 * Ensure we don't accidentally enable a stopped
+		 * counter simply because we rescheduled.
+		 */
+		if (hwc->state & PERF_HES_STOPPED)
+			hwc->state |= PERF_HES_ARCH;
+
+		uncore_pmu_event_stop(event, PERF_EF_UPDATE);
+	}
+
+	/* reprogram moved events into new counters */
+	for (i = 0; i < n; i++) {
+		event = box->event_list[i];
+		hwc = &event->hw;
+
+		if (hwc->idx != assign[i] ||
+			hwc->last_tag != box->tags[assign[i]])
+			uncore_assign_hw_event(box, event, assign[i]);
+		else if (i < box->n_events)
+			continue;
+
+		if (hwc->state & PERF_HES_ARCH)
+			continue;
+
+		uncore_pmu_event_start(event, 0);
+	}
+	box->n_events = n;
+
+	return 0;
+}
+
+static void uncore_pmu_event_del(struct perf_event *event, int flags)
+{
+	struct intel_uncore_box *box = uncore_event_to_box(event);
+	int i;
+
+	uncore_pmu_event_stop(event, PERF_EF_UPDATE);
+
+	for (i = 0; i < box->n_events; i++) {
+		if (event == box->event_list[i]) {
+			uncore_put_event_constraint(box, event);
+
+			while (++i < box->n_events)
+				box->event_list[i - 1] = box->event_list[i];
+
+			--box->n_events;
+			break;
+		}
+	}
+
+	event->hw.idx = -1;
+	event->hw.last_tag = ~0ULL;
+}
+
+void uncore_pmu_event_read(struct perf_event *event)
+{
+	struct intel_uncore_box *box = uncore_event_to_box(event);
+	uncore_perf_event_update(box, event);
+}
+
+/*
+ * validation ensures the group can be loaded onto the
+ * PMU if it was the only group available.
+ */
+static int uncore_validate_group(struct intel_uncore_pmu *pmu,
+				struct perf_event *event)
+{
+	struct perf_event *leader = event->group_leader;
+	struct intel_uncore_box *fake_box;
+	int ret = -EINVAL, n;
+
+	fake_box = uncore_alloc_box(pmu->type, NUMA_NO_NODE);
+	if (!fake_box)
+		return -ENOMEM;
+
+	fake_box->pmu = pmu;
+	/*
+	 * the event is not yet connected with its
+	 * siblings therefore we must first collect
+	 * existing siblings, then add the new event
+	 * before we can simulate the scheduling
+	 */
+	n = uncore_collect_events(fake_box, leader, true);
+	if (n < 0)
+		goto out;
+
+	fake_box->n_events = n;
+	n = uncore_collect_events(fake_box, event, false);
+	if (n < 0)
+		goto out;
+
+	fake_box->n_events = n;
+
+	ret = uncore_assign_events(fake_box, NULL, n);
+out:
+	kfree(fake_box);
+	return ret;
+}
+
+static int uncore_pmu_event_init(struct perf_event *event)
+{
+	struct intel_uncore_pmu *pmu;
+	struct intel_uncore_box *box;
+	struct hw_perf_event *hwc = &event->hw;
+	int ret;
+
+	if (event->attr.type != event->pmu->type)
+		return -ENOENT;
+
+	pmu = uncore_event_to_pmu(event);
+	/* no device found for this pmu */
+	if (pmu->func_id < 0)
+		return -ENOENT;
+
+	/*
+	 * Uncore PMU does measure at all privilege level all the time.
+	 * So it doesn't make sense to specify any exclude bits.
+	 */
+	if (event->attr.exclude_user || event->attr.exclude_kernel ||
+			event->attr.exclude_hv || event->attr.exclude_idle)
+		return -EINVAL;
+
+	/* Sampling not supported yet */
+	if (hwc->sample_period)
+		return -EINVAL;
+
+	/*
+	 * Place all uncore events for a particular physical package
+	 * onto a single cpu
+	 */
+	if (event->cpu < 0)
+		return -EINVAL;
+	box = uncore_pmu_to_box(pmu, event->cpu);
+	if (!box || box->cpu < 0)
+		return -EINVAL;
+	event->cpu = box->cpu;
+
+	event->hw.idx = -1;
+	event->hw.last_tag = ~0ULL;
+	event->hw.extra_reg.idx = EXTRA_REG_NONE;
+	event->hw.branch_reg.idx = EXTRA_REG_NONE;
+
+	if (event->attr.config == UNCORE_FIXED_EVENT) {
+		/* no fixed counter */
+		if (!pmu->type->fixed_ctl)
+			return -EINVAL;
+		/*
+		 * if there is only one fixed counter, only the first pmu
+		 * can access the fixed counter
+		 */
+		if (pmu->type->single_fixed && pmu->pmu_idx > 0)
+			return -EINVAL;
+
+		/* fixed counters have event field hardcoded to zero */
+		hwc->config = 0ULL;
+	} else {
+		hwc->config = event->attr.config & pmu->type->event_mask;
+		if (pmu->type->ops->hw_config) {
+			ret = pmu->type->ops->hw_config(box, event);
+			if (ret)
+				return ret;
+		}
+	}
+
+	if (event->group_leader != event)
+		ret = uncore_validate_group(pmu, event);
+	else
+		ret = 0;
+
+	return ret;
+}
+
+static ssize_t uncore_get_attr_cpumask(struct device *dev,
+				struct device_attribute *attr, char *buf)
+{
+	return cpumap_print_to_pagebuf(true, buf, &uncore_cpu_mask);
+}
+
+static DEVICE_ATTR(cpumask, S_IRUGO, uncore_get_attr_cpumask, NULL);
+
+static struct attribute *uncore_pmu_attrs[] = {
+	&dev_attr_cpumask.attr,
+	NULL,
+};
+
+static struct attribute_group uncore_pmu_attr_group = {
+	.attrs = uncore_pmu_attrs,
+};
+
+static int uncore_pmu_register(struct intel_uncore_pmu *pmu)
+{
+	int ret;
+
+	if (!pmu->type->pmu) {
+		pmu->pmu = (struct pmu) {
+			.attr_groups	= pmu->type->attr_groups,
+			.task_ctx_nr	= perf_invalid_context,
+			.event_init	= uncore_pmu_event_init,
+			.add		= uncore_pmu_event_add,
+			.del		= uncore_pmu_event_del,
+			.start		= uncore_pmu_event_start,
+			.stop		= uncore_pmu_event_stop,
+			.read		= uncore_pmu_event_read,
+		};
+	} else {
+		pmu->pmu = *pmu->type->pmu;
+		pmu->pmu.attr_groups = pmu->type->attr_groups;
+	}
+
+	if (pmu->type->num_boxes == 1) {
+		if (strlen(pmu->type->name) > 0)
+			sprintf(pmu->name, "uncore_%s", pmu->type->name);
+		else
+			sprintf(pmu->name, "uncore");
+	} else {
+		sprintf(pmu->name, "uncore_%s_%d", pmu->type->name,
+			pmu->pmu_idx);
+	}
+
+	ret = perf_pmu_register(&pmu->pmu, pmu->name, -1);
+	return ret;
+}
+
+static void __init uncore_type_exit(struct intel_uncore_type *type)
+{
+	int i;
+
+	for (i = 0; i < type->num_boxes; i++)
+		free_percpu(type->pmus[i].box);
+	kfree(type->pmus);
+	type->pmus = NULL;
+	kfree(type->events_group);
+	type->events_group = NULL;
+}
+
+static void __init uncore_types_exit(struct intel_uncore_type **types)
+{
+	int i;
+	for (i = 0; types[i]; i++)
+		uncore_type_exit(types[i]);
+}
+
+static int __init uncore_type_init(struct intel_uncore_type *type)
+{
+	struct intel_uncore_pmu *pmus;
+	struct attribute_group *attr_group;
+	struct attribute **attrs;
+	int i, j;
+
+	pmus = kzalloc(sizeof(*pmus) * type->num_boxes, GFP_KERNEL);
+	if (!pmus)
+		return -ENOMEM;
+
+	type->pmus = pmus;
+
+	type->unconstrainted = (struct event_constraint)
+		__EVENT_CONSTRAINT(0, (1ULL << type->num_counters) - 1,
+				0, type->num_counters, 0, 0);
+
+	for (i = 0; i < type->num_boxes; i++) {
+		pmus[i].func_id = -1;
+		pmus[i].pmu_idx = i;
+		pmus[i].type = type;
+		INIT_LIST_HEAD(&pmus[i].box_list);
+		pmus[i].box = alloc_percpu(struct intel_uncore_box *);
+		if (!pmus[i].box)
+			goto fail;
+	}
+
+	if (type->event_descs) {
+		i = 0;
+		while (type->event_descs[i].attr.attr.name)
+			i++;
+
+		attr_group = kzalloc(sizeof(struct attribute *) * (i + 1) +
+					sizeof(*attr_group), GFP_KERNEL);
+		if (!attr_group)
+			goto fail;
+
+		attrs = (struct attribute **)(attr_group + 1);
+		attr_group->name = "events";
+		attr_group->attrs = attrs;
+
+		for (j = 0; j < i; j++)
+			attrs[j] = &type->event_descs[j].attr.attr;
+
+		type->events_group = attr_group;
+	}
+
+	type->pmu_group = &uncore_pmu_attr_group;
+	return 0;
+fail:
+	uncore_type_exit(type);
+	return -ENOMEM;
+}
+
+static int __init uncore_types_init(struct intel_uncore_type **types)
+{
+	int i, ret;
+
+	for (i = 0; types[i]; i++) {
+		ret = uncore_type_init(types[i]);
+		if (ret)
+			goto fail;
+	}
+	return 0;
+fail:
+	while (--i >= 0)
+		uncore_type_exit(types[i]);
+	return ret;
+}
+
+/*
+ * add a pci uncore device
+ */
+static int uncore_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
+{
+	struct intel_uncore_pmu *pmu;
+	struct intel_uncore_box *box;
+	struct intel_uncore_type *type;
+	int phys_id;
+	bool first_box = false;
+
+	phys_id = uncore_pcibus_to_physid(pdev->bus);
+	if (phys_id < 0)
+		return -ENODEV;
+
+	if (UNCORE_PCI_DEV_TYPE(id->driver_data) == UNCORE_EXTRA_PCI_DEV) {
+		int idx = UNCORE_PCI_DEV_IDX(id->driver_data);
+		uncore_extra_pci_dev[phys_id][idx] = pdev;
+		pci_set_drvdata(pdev, NULL);
+		return 0;
+	}
+
+	type = uncore_pci_uncores[UNCORE_PCI_DEV_TYPE(id->driver_data)];
+	box = uncore_alloc_box(type, NUMA_NO_NODE);
+	if (!box)
+		return -ENOMEM;
+
+	/*
+	 * for performance monitoring unit with multiple boxes,
+	 * each box has a different function id.
+	 */
+	pmu = &type->pmus[UNCORE_PCI_DEV_IDX(id->driver_data)];
+	/* Knights Landing uses a common PCI device ID for multiple instances of
+	 * an uncore PMU device type. There is only one entry per device type in
+	 * the knl_uncore_pci_ids table inspite of multiple devices present for
+	 * some device types. Hence PCI device idx would be 0 for all devices.
+	 * So increment pmu pointer to point to an unused array element.
+	 */
+	if (boot_cpu_data.x86_model == 87)
+		while (pmu->func_id >= 0)
+			pmu++;
+	if (pmu->func_id < 0)
+		pmu->func_id = pdev->devfn;
+	else
+		WARN_ON_ONCE(pmu->func_id != pdev->devfn);
+
+	box->phys_id = phys_id;
+	box->pci_dev = pdev;
+	box->pmu = pmu;
+	uncore_box_init(box);
+	pci_set_drvdata(pdev, box);
+
+	raw_spin_lock(&uncore_box_lock);
+	if (list_empty(&pmu->box_list))
+		first_box = true;
+	list_add_tail(&box->list, &pmu->box_list);
+	raw_spin_unlock(&uncore_box_lock);
+
+	if (first_box)
+		uncore_pmu_register(pmu);
+	return 0;
+}
+
+static void uncore_pci_remove(struct pci_dev *pdev)
+{
+	struct intel_uncore_box *box = pci_get_drvdata(pdev);
+	struct intel_uncore_pmu *pmu;
+	int i, cpu, phys_id;
+	bool last_box = false;
+
+	phys_id = uncore_pcibus_to_physid(pdev->bus);
+	box = pci_get_drvdata(pdev);
+	if (!box) {
+		for (i = 0; i < UNCORE_EXTRA_PCI_DEV_MAX; i++) {
+			if (uncore_extra_pci_dev[phys_id][i] == pdev) {
+				uncore_extra_pci_dev[phys_id][i] = NULL;
+				break;
+			}
+		}
+		WARN_ON_ONCE(i >= UNCORE_EXTRA_PCI_DEV_MAX);
+		return;
+	}
+
+	pmu = box->pmu;
+	if (WARN_ON_ONCE(phys_id != box->phys_id))
+		return;
+
+	pci_set_drvdata(pdev, NULL);
+
+	raw_spin_lock(&uncore_box_lock);
+	list_del(&box->list);
+	if (list_empty(&pmu->box_list))
+		last_box = true;
+	raw_spin_unlock(&uncore_box_lock);
+
+	for_each_possible_cpu(cpu) {
+		if (*per_cpu_ptr(pmu->box, cpu) == box) {
+			*per_cpu_ptr(pmu->box, cpu) = NULL;
+			atomic_dec(&box->refcnt);
+		}
+	}
+
+	WARN_ON_ONCE(atomic_read(&box->refcnt) != 1);
+	kfree(box);
+
+	if (last_box)
+		perf_pmu_unregister(&pmu->pmu);
+}
+
+static int __init uncore_pci_init(void)
+{
+	int ret;
+
+	switch (boot_cpu_data.x86_model) {
+	case 45: /* Sandy Bridge-EP */
+		ret = snbep_uncore_pci_init();
+		break;
+	case 62: /* Ivy Bridge-EP */
+		ret = ivbep_uncore_pci_init();
+		break;
+	case 63: /* Haswell-EP */
+		ret = hswep_uncore_pci_init();
+		break;
+	case 79: /* BDX-EP */
+	case 86: /* BDX-DE */
+		ret = bdx_uncore_pci_init();
+		break;
+	case 42: /* Sandy Bridge */
+		ret = snb_uncore_pci_init();
+		break;
+	case 58: /* Ivy Bridge */
+		ret = ivb_uncore_pci_init();
+		break;
+	case 60: /* Haswell */
+	case 69: /* Haswell Celeron */
+		ret = hsw_uncore_pci_init();
+		break;
+	case 61: /* Broadwell */
+		ret = bdw_uncore_pci_init();
+		break;
+	case 87: /* Knights Landing */
+		ret = knl_uncore_pci_init();
+		break;
+	default:
+		return 0;
+	}
+
+	if (ret)
+		return ret;
+
+	ret = uncore_types_init(uncore_pci_uncores);
+	if (ret)
+		return ret;
+
+	uncore_pci_driver->probe = uncore_pci_probe;
+	uncore_pci_driver->remove = uncore_pci_remove;
+
+	ret = pci_register_driver(uncore_pci_driver);
+	if (ret == 0)
+		pcidrv_registered = true;
+	else
+		uncore_types_exit(uncore_pci_uncores);
+
+	return ret;
+}
+
+static void __init uncore_pci_exit(void)
+{
+	if (pcidrv_registered) {
+		pcidrv_registered = false;
+		pci_unregister_driver(uncore_pci_driver);
+		uncore_types_exit(uncore_pci_uncores);
+	}
+}
+
+/* CPU hot plug/unplug are serialized by cpu_add_remove_lock mutex */
+static LIST_HEAD(boxes_to_free);
+
+static void uncore_kfree_boxes(void)
+{
+	struct intel_uncore_box *box;
+
+	while (!list_empty(&boxes_to_free)) {
+		box = list_entry(boxes_to_free.next,
+				 struct intel_uncore_box, list);
+		list_del(&box->list);
+		kfree(box);
+	}
+}
+
+static void uncore_cpu_dying(int cpu)
+{
+	struct intel_uncore_type *type;
+	struct intel_uncore_pmu *pmu;
+	struct intel_uncore_box *box;
+	int i, j;
+
+	for (i = 0; uncore_msr_uncores[i]; i++) {
+		type = uncore_msr_uncores[i];
+		for (j = 0; j < type->num_boxes; j++) {
+			pmu = &type->pmus[j];
+			box = *per_cpu_ptr(pmu->box, cpu);
+			*per_cpu_ptr(pmu->box, cpu) = NULL;
+			if (box && atomic_dec_and_test(&box->refcnt))
+				list_add(&box->list, &boxes_to_free);
+		}
+	}
+}
+
+static int uncore_cpu_starting(int cpu)
+{
+	struct intel_uncore_type *type;
+	struct intel_uncore_pmu *pmu;
+	struct intel_uncore_box *box, *exist;
+	int i, j, k, phys_id;
+
+	phys_id = topology_physical_package_id(cpu);
+
+	for (i = 0; uncore_msr_uncores[i]; i++) {
+		type = uncore_msr_uncores[i];
+		for (j = 0; j < type->num_boxes; j++) {
+			pmu = &type->pmus[j];
+			box = *per_cpu_ptr(pmu->box, cpu);
+			/* called by uncore_cpu_init? */
+			if (box && box->phys_id >= 0) {
+				uncore_box_init(box);
+				continue;
+			}
+
+			for_each_online_cpu(k) {
+				exist = *per_cpu_ptr(pmu->box, k);
+				if (exist && exist->phys_id == phys_id) {
+					atomic_inc(&exist->refcnt);
+					*per_cpu_ptr(pmu->box, cpu) = exist;
+					if (box) {
+						list_add(&box->list,
+							 &boxes_to_free);
+						box = NULL;
+					}
+					break;
+				}
+			}
+
+			if (box) {
+				box->phys_id = phys_id;
+				uncore_box_init(box);
+			}
+		}
+	}
+	return 0;
+}
+
+static int uncore_cpu_prepare(int cpu, int phys_id)
+{
+	struct intel_uncore_type *type;
+	struct intel_uncore_pmu *pmu;
+	struct intel_uncore_box *box;
+	int i, j;
+
+	for (i = 0; uncore_msr_uncores[i]; i++) {
+		type = uncore_msr_uncores[i];
+		for (j = 0; j < type->num_boxes; j++) {
+			pmu = &type->pmus[j];
+			if (pmu->func_id < 0)
+				pmu->func_id = j;
+
+			box = uncore_alloc_box(type, cpu_to_node(cpu));
+			if (!box)
+				return -ENOMEM;
+
+			box->pmu = pmu;
+			box->phys_id = phys_id;
+			*per_cpu_ptr(pmu->box, cpu) = box;
+		}
+	}
+	return 0;
+}
+
+static void
+uncore_change_context(struct intel_uncore_type **uncores, int old_cpu, int new_cpu)
+{
+	struct intel_uncore_type *type;
+	struct intel_uncore_pmu *pmu;
+	struct intel_uncore_box *box;
+	int i, j;
+
+	for (i = 0; uncores[i]; i++) {
+		type = uncores[i];
+		for (j = 0; j < type->num_boxes; j++) {
+			pmu = &type->pmus[j];
+			if (old_cpu < 0)
+				box = uncore_pmu_to_box(pmu, new_cpu);
+			else
+				box = uncore_pmu_to_box(pmu, old_cpu);
+			if (!box)
+				continue;
+
+			if (old_cpu < 0) {
+				WARN_ON_ONCE(box->cpu != -1);
+				box->cpu = new_cpu;
+				continue;
+			}
+
+			WARN_ON_ONCE(box->cpu != old_cpu);
+			if (new_cpu >= 0) {
+				uncore_pmu_cancel_hrtimer(box);
+				perf_pmu_migrate_context(&pmu->pmu,
+						old_cpu, new_cpu);
+				box->cpu = new_cpu;
+			} else {
+				box->cpu = -1;
+			}
+		}
+	}
+}
+
+static void uncore_event_exit_cpu(int cpu)
+{
+	int i, phys_id, target;
+
+	/* if exiting cpu is used for collecting uncore events */
+	if (!cpumask_test_and_clear_cpu(cpu, &uncore_cpu_mask))
+		return;
+
+	/* find a new cpu to collect uncore events */
+	phys_id = topology_physical_package_id(cpu);
+	target = -1;
+	for_each_online_cpu(i) {
+		if (i == cpu)
+			continue;
+		if (phys_id == topology_physical_package_id(i)) {
+			target = i;
+			break;
+		}
+	}
+
+	/* migrate uncore events to the new cpu */
+	if (target >= 0)
+		cpumask_set_cpu(target, &uncore_cpu_mask);
+
+	uncore_change_context(uncore_msr_uncores, cpu, target);
+	uncore_change_context(uncore_pci_uncores, cpu, target);
+}
+
+static void uncore_event_init_cpu(int cpu)
+{
+	int i, phys_id;
+
+	phys_id = topology_physical_package_id(cpu);
+	for_each_cpu(i, &uncore_cpu_mask) {
+		if (phys_id == topology_physical_package_id(i))
+			return;
+	}
+
+	cpumask_set_cpu(cpu, &uncore_cpu_mask);
+
+	uncore_change_context(uncore_msr_uncores, -1, cpu);
+	uncore_change_context(uncore_pci_uncores, -1, cpu);
+}
+
+static int uncore_cpu_notifier(struct notifier_block *self,
+			       unsigned long action, void *hcpu)
+{
+	unsigned int cpu = (long)hcpu;
+
+	/* allocate/free data structure for uncore box */
+	switch (action & ~CPU_TASKS_FROZEN) {
+	case CPU_UP_PREPARE:
+		uncore_cpu_prepare(cpu, -1);
+		break;
+	case CPU_STARTING:
+		uncore_cpu_starting(cpu);
+		break;
+	case CPU_UP_CANCELED:
+	case CPU_DYING:
+		uncore_cpu_dying(cpu);
+		break;
+	case CPU_ONLINE:
+	case CPU_DEAD:
+		uncore_kfree_boxes();
+		break;
+	default:
+		break;
+	}
+
+	/* select the cpu that collects uncore events */
+	switch (action & ~CPU_TASKS_FROZEN) {
+	case CPU_DOWN_FAILED:
+	case CPU_STARTING:
+		uncore_event_init_cpu(cpu);
+		break;
+	case CPU_DOWN_PREPARE:
+		uncore_event_exit_cpu(cpu);
+		break;
+	default:
+		break;
+	}
+
+	return NOTIFY_OK;
+}
+
+static struct notifier_block uncore_cpu_nb = {
+	.notifier_call	= uncore_cpu_notifier,
+	/*
+	 * to migrate uncore events, our notifier should be executed
+	 * before perf core's notifier.
+	 */
+	.priority	= CPU_PRI_PERF + 1,
+};
+
+static void __init uncore_cpu_setup(void *dummy)
+{
+	uncore_cpu_starting(smp_processor_id());
+}
+
+static int __init uncore_cpu_init(void)
+{
+	int ret;
+
+	switch (boot_cpu_data.x86_model) {
+	case 26: /* Nehalem */
+	case 30:
+	case 37: /* Westmere */
+	case 44:
+		nhm_uncore_cpu_init();
+		break;
+	case 42: /* Sandy Bridge */
+	case 58: /* Ivy Bridge */
+	case 60: /* Haswell */
+	case 69: /* Haswell */
+	case 70: /* Haswell */
+	case 61: /* Broadwell */
+	case 71: /* Broadwell */
+		snb_uncore_cpu_init();
+		break;
+	case 45: /* Sandy Bridge-EP */
+		snbep_uncore_cpu_init();
+		break;
+	case 46: /* Nehalem-EX */
+	case 47: /* Westmere-EX aka. Xeon E7 */
+		nhmex_uncore_cpu_init();
+		break;
+	case 62: /* Ivy Bridge-EP */
+		ivbep_uncore_cpu_init();
+		break;
+	case 63: /* Haswell-EP */
+		hswep_uncore_cpu_init();
+		break;
+	case 79: /* BDX-EP */
+	case 86: /* BDX-DE */
+		bdx_uncore_cpu_init();
+		break;
+	case 87: /* Knights Landing */
+		knl_uncore_cpu_init();
+		break;
+	default:
+		return 0;
+	}
+
+	ret = uncore_types_init(uncore_msr_uncores);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static int __init uncore_pmus_register(void)
+{
+	struct intel_uncore_pmu *pmu;
+	struct intel_uncore_type *type;
+	int i, j;
+
+	for (i = 0; uncore_msr_uncores[i]; i++) {
+		type = uncore_msr_uncores[i];
+		for (j = 0; j < type->num_boxes; j++) {
+			pmu = &type->pmus[j];
+			uncore_pmu_register(pmu);
+		}
+	}
+
+	return 0;
+}
+
+static void __init uncore_cpumask_init(void)
+{
+	int cpu;
+
+	/*
+	 * ony invoke once from msr or pci init code
+	 */
+	if (!cpumask_empty(&uncore_cpu_mask))
+		return;
+
+	cpu_notifier_register_begin();
+
+	for_each_online_cpu(cpu) {
+		int i, phys_id = topology_physical_package_id(cpu);
+
+		for_each_cpu(i, &uncore_cpu_mask) {
+			if (phys_id == topology_physical_package_id(i)) {
+				phys_id = -1;
+				break;
+			}
+		}
+		if (phys_id < 0)
+			continue;
+
+		uncore_cpu_prepare(cpu, phys_id);
+		uncore_event_init_cpu(cpu);
+	}
+	on_each_cpu(uncore_cpu_setup, NULL, 1);
+
+	__register_cpu_notifier(&uncore_cpu_nb);
+
+	cpu_notifier_register_done();
+}
+
+
+static int __init intel_uncore_init(void)
+{
+	int ret;
+
+	if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL)
+		return -ENODEV;
+
+	if (cpu_has_hypervisor)
+		return -ENODEV;
+
+	ret = uncore_pci_init();
+	if (ret)
+		goto fail;
+	ret = uncore_cpu_init();
+	if (ret) {
+		uncore_pci_exit();
+		goto fail;
+	}
+	uncore_cpumask_init();
+
+	uncore_pmus_register();
+	return 0;
+fail:
+	return ret;
+}
+device_initcall(intel_uncore_init);
--- /dev/null
+++ zfcpdump-kernel-4.4/arch/x86/events/intel/uncore.h
@@ -0,0 +1,356 @@
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/pci.h>
+#include <linux/perf_event.h>
+#include "../perf_event.h"
+
+#define UNCORE_PMU_NAME_LEN		32
+#define UNCORE_PMU_HRTIMER_INTERVAL	(60LL * NSEC_PER_SEC)
+#define UNCORE_SNB_IMC_HRTIMER_INTERVAL (5ULL * NSEC_PER_SEC)
+
+#define UNCORE_FIXED_EVENT		0xff
+#define UNCORE_PMC_IDX_MAX_GENERIC	8
+#define UNCORE_PMC_IDX_FIXED		UNCORE_PMC_IDX_MAX_GENERIC
+#define UNCORE_PMC_IDX_MAX		(UNCORE_PMC_IDX_FIXED + 1)
+
+#define UNCORE_PCI_DEV_DATA(type, idx)	((type << 8) | idx)
+#define UNCORE_PCI_DEV_TYPE(data)	((data >> 8) & 0xff)
+#define UNCORE_PCI_DEV_IDX(data)	(data & 0xff)
+#define UNCORE_EXTRA_PCI_DEV		0xff
+#define UNCORE_EXTRA_PCI_DEV_MAX	3
+
+/* support up to 8 sockets */
+#define UNCORE_SOCKET_MAX		8
+
+#define UNCORE_EVENT_CONSTRAINT(c, n) EVENT_CONSTRAINT(c, n, 0xff)
+
+struct intel_uncore_ops;
+struct intel_uncore_pmu;
+struct intel_uncore_box;
+struct uncore_event_desc;
+
+struct intel_uncore_type {
+	const char *name;
+	int num_counters;
+	int num_boxes;
+	int perf_ctr_bits;
+	int fixed_ctr_bits;
+	unsigned perf_ctr;
+	unsigned event_ctl;
+	unsigned event_mask;
+	unsigned fixed_ctr;
+	unsigned fixed_ctl;
+	unsigned box_ctl;
+	unsigned msr_offset;
+	unsigned num_shared_regs:8;
+	unsigned single_fixed:1;
+	unsigned pair_ctr_ctl:1;
+	unsigned *msr_offsets;
+	struct event_constraint unconstrainted;
+	struct event_constraint *constraints;
+	struct intel_uncore_pmu *pmus;
+	struct intel_uncore_ops *ops;
+	struct uncore_event_desc *event_descs;
+	const struct attribute_group *attr_groups[4];
+	struct pmu *pmu; /* for custom pmu ops */
+};
+
+#define pmu_group attr_groups[0]
+#define format_group attr_groups[1]
+#define events_group attr_groups[2]
+
+struct intel_uncore_ops {
+	void (*init_box)(struct intel_uncore_box *);
+	void (*disable_box)(struct intel_uncore_box *);
+	void (*enable_box)(struct intel_uncore_box *);
+	void (*disable_event)(struct intel_uncore_box *, struct perf_event *);
+	void (*enable_event)(struct intel_uncore_box *, struct perf_event *);
+	u64 (*read_counter)(struct intel_uncore_box *, struct perf_event *);
+	int (*hw_config)(struct intel_uncore_box *, struct perf_event *);
+	struct event_constraint *(*get_constraint)(struct intel_uncore_box *,
+						   struct perf_event *);
+	void (*put_constraint)(struct intel_uncore_box *, struct perf_event *);
+};
+
+struct intel_uncore_pmu {
+	struct pmu pmu;
+	char name[UNCORE_PMU_NAME_LEN];
+	int pmu_idx;
+	int func_id;
+	struct intel_uncore_type *type;
+	struct intel_uncore_box ** __percpu box;
+	struct list_head box_list;
+};
+
+struct intel_uncore_extra_reg {
+	raw_spinlock_t lock;
+	u64 config, config1, config2;
+	atomic_t ref;
+};
+
+struct intel_uncore_box {
+	int phys_id;
+	int n_active;	/* number of active events */
+	int n_events;
+	int cpu;	/* cpu to collect events */
+	unsigned long flags;
+	atomic_t refcnt;
+	struct perf_event *events[UNCORE_PMC_IDX_MAX];
+	struct perf_event *event_list[UNCORE_PMC_IDX_MAX];
+	struct event_constraint *event_constraint[UNCORE_PMC_IDX_MAX];
+	unsigned long active_mask[BITS_TO_LONGS(UNCORE_PMC_IDX_MAX)];
+	u64 tags[UNCORE_PMC_IDX_MAX];
+	struct pci_dev *pci_dev;
+	struct intel_uncore_pmu *pmu;
+	u64 hrtimer_duration; /* hrtimer timeout for this box */
+	struct hrtimer hrtimer;
+	struct list_head list;
+	struct list_head active_list;
+	void *io_addr;
+	struct intel_uncore_extra_reg shared_regs[0];
+};
+
+#define UNCORE_BOX_FLAG_INITIATED	0
+
+struct uncore_event_desc {
+	struct kobj_attribute attr;
+	const char *config;
+};
+
+struct pci2phy_map {
+	struct list_head list;
+	int segment;
+	int pbus_to_physid[256];
+};
+
+int uncore_pcibus_to_physid(struct pci_bus *bus);
+struct pci2phy_map *__find_pci2phy_map(int segment);
+
+ssize_t uncore_event_show(struct kobject *kobj,
+			  struct kobj_attribute *attr, char *buf);
+
+#define INTEL_UNCORE_EVENT_DESC(_name, _config)			\
+{								\
+	.attr	= __ATTR(_name, 0444, uncore_event_show, NULL),	\
+	.config	= _config,					\
+}
+
+#define DEFINE_UNCORE_FORMAT_ATTR(_var, _name, _format)			\
+static ssize_t __uncore_##_var##_show(struct kobject *kobj,		\
+				struct kobj_attribute *attr,		\
+				char *page)				\
+{									\
+	BUILD_BUG_ON(sizeof(_format) >= PAGE_SIZE);			\
+	return sprintf(page, _format "\n");				\
+}									\
+static struct kobj_attribute format_attr_##_var =			\
+	__ATTR(_name, 0444, __uncore_##_var##_show, NULL)
+
+static inline unsigned uncore_pci_box_ctl(struct intel_uncore_box *box)
+{
+	return box->pmu->type->box_ctl;
+}
+
+static inline unsigned uncore_pci_fixed_ctl(struct intel_uncore_box *box)
+{
+	return box->pmu->type->fixed_ctl;
+}
+
+static inline unsigned uncore_pci_fixed_ctr(struct intel_uncore_box *box)
+{
+	return box->pmu->type->fixed_ctr;
+}
+
+static inline
+unsigned uncore_pci_event_ctl(struct intel_uncore_box *box, int idx)
+{
+	return idx * 4 + box->pmu->type->event_ctl;
+}
+
+static inline
+unsigned uncore_pci_perf_ctr(struct intel_uncore_box *box, int idx)
+{
+	return idx * 8 + box->pmu->type->perf_ctr;
+}
+
+static inline unsigned uncore_msr_box_offset(struct intel_uncore_box *box)
+{
+	struct intel_uncore_pmu *pmu = box->pmu;
+	return pmu->type->msr_offsets ?
+		pmu->type->msr_offsets[pmu->pmu_idx] :
+		pmu->type->msr_offset * pmu->pmu_idx;
+}
+
+static inline unsigned uncore_msr_box_ctl(struct intel_uncore_box *box)
+{
+	if (!box->pmu->type->box_ctl)
+		return 0;
+	return box->pmu->type->box_ctl + uncore_msr_box_offset(box);
+}
+
+static inline unsigned uncore_msr_fixed_ctl(struct intel_uncore_box *box)
+{
+	if (!box->pmu->type->fixed_ctl)
+		return 0;
+	return box->pmu->type->fixed_ctl + uncore_msr_box_offset(box);
+}
+
+static inline unsigned uncore_msr_fixed_ctr(struct intel_uncore_box *box)
+{
+	return box->pmu->type->fixed_ctr + uncore_msr_box_offset(box);
+}
+
+static inline
+unsigned uncore_msr_event_ctl(struct intel_uncore_box *box, int idx)
+{
+	return box->pmu->type->event_ctl +
+		(box->pmu->type->pair_ctr_ctl ? 2 * idx : idx) +
+		uncore_msr_box_offset(box);
+}
+
+static inline
+unsigned uncore_msr_perf_ctr(struct intel_uncore_box *box, int idx)
+{
+	return box->pmu->type->perf_ctr +
+		(box->pmu->type->pair_ctr_ctl ? 2 * idx : idx) +
+		uncore_msr_box_offset(box);
+}
+
+static inline
+unsigned uncore_fixed_ctl(struct intel_uncore_box *box)
+{
+	if (box->pci_dev)
+		return uncore_pci_fixed_ctl(box);
+	else
+		return uncore_msr_fixed_ctl(box);
+}
+
+static inline
+unsigned uncore_fixed_ctr(struct intel_uncore_box *box)
+{
+	if (box->pci_dev)
+		return uncore_pci_fixed_ctr(box);
+	else
+		return uncore_msr_fixed_ctr(box);
+}
+
+static inline
+unsigned uncore_event_ctl(struct intel_uncore_box *box, int idx)
+{
+	if (box->pci_dev)
+		return uncore_pci_event_ctl(box, idx);
+	else
+		return uncore_msr_event_ctl(box, idx);
+}
+
+static inline
+unsigned uncore_perf_ctr(struct intel_uncore_box *box, int idx)
+{
+	if (box->pci_dev)
+		return uncore_pci_perf_ctr(box, idx);
+	else
+		return uncore_msr_perf_ctr(box, idx);
+}
+
+static inline int uncore_perf_ctr_bits(struct intel_uncore_box *box)
+{
+	return box->pmu->type->perf_ctr_bits;
+}
+
+static inline int uncore_fixed_ctr_bits(struct intel_uncore_box *box)
+{
+	return box->pmu->type->fixed_ctr_bits;
+}
+
+static inline int uncore_num_counters(struct intel_uncore_box *box)
+{
+	return box->pmu->type->num_counters;
+}
+
+static inline void uncore_disable_box(struct intel_uncore_box *box)
+{
+	if (box->pmu->type->ops->disable_box)
+		box->pmu->type->ops->disable_box(box);
+}
+
+static inline void uncore_enable_box(struct intel_uncore_box *box)
+{
+	if (box->pmu->type->ops->enable_box)
+		box->pmu->type->ops->enable_box(box);
+}
+
+static inline void uncore_disable_event(struct intel_uncore_box *box,
+				struct perf_event *event)
+{
+	box->pmu->type->ops->disable_event(box, event);
+}
+
+static inline void uncore_enable_event(struct intel_uncore_box *box,
+				struct perf_event *event)
+{
+	box->pmu->type->ops->enable_event(box, event);
+}
+
+static inline u64 uncore_read_counter(struct intel_uncore_box *box,
+				struct perf_event *event)
+{
+	return box->pmu->type->ops->read_counter(box, event);
+}
+
+static inline void uncore_box_init(struct intel_uncore_box *box)
+{
+	if (!test_and_set_bit(UNCORE_BOX_FLAG_INITIATED, &box->flags)) {
+		if (box->pmu->type->ops->init_box)
+			box->pmu->type->ops->init_box(box);
+	}
+}
+
+static inline bool uncore_box_is_fake(struct intel_uncore_box *box)
+{
+	return (box->phys_id < 0);
+}
+
+struct intel_uncore_pmu *uncore_event_to_pmu(struct perf_event *event);
+struct intel_uncore_box *uncore_pmu_to_box(struct intel_uncore_pmu *pmu, int cpu);
+struct intel_uncore_box *uncore_event_to_box(struct perf_event *event);
+u64 uncore_msr_read_counter(struct intel_uncore_box *box, struct perf_event *event);
+void uncore_pmu_start_hrtimer(struct intel_uncore_box *box);
+void uncore_pmu_cancel_hrtimer(struct intel_uncore_box *box);
+void uncore_pmu_event_read(struct perf_event *event);
+void uncore_perf_event_update(struct intel_uncore_box *box, struct perf_event *event);
+struct event_constraint *
+uncore_get_constraint(struct intel_uncore_box *box, struct perf_event *event);
+void uncore_put_constraint(struct intel_uncore_box *box, struct perf_event *event);
+u64 uncore_shared_reg_config(struct intel_uncore_box *box, int idx);
+
+extern struct intel_uncore_type **uncore_msr_uncores;
+extern struct intel_uncore_type **uncore_pci_uncores;
+extern struct pci_driver *uncore_pci_driver;
+extern raw_spinlock_t pci2phy_map_lock;
+extern struct list_head pci2phy_map_head;
+extern struct pci_dev *uncore_extra_pci_dev[UNCORE_SOCKET_MAX][UNCORE_EXTRA_PCI_DEV_MAX];
+extern struct event_constraint uncore_constraint_empty;
+
+/* perf_event_intel_uncore_snb.c */
+int snb_uncore_pci_init(void);
+int ivb_uncore_pci_init(void);
+int hsw_uncore_pci_init(void);
+int bdw_uncore_pci_init(void);
+void snb_uncore_cpu_init(void);
+void nhm_uncore_cpu_init(void);
+int snb_pci2phy_map_init(int devid);
+
+/* perf_event_intel_uncore_snbep.c */
+int snbep_uncore_pci_init(void);
+void snbep_uncore_cpu_init(void);
+int ivbep_uncore_pci_init(void);
+void ivbep_uncore_cpu_init(void);
+int hswep_uncore_pci_init(void);
+void hswep_uncore_cpu_init(void);
+int bdx_uncore_pci_init(void);
+void bdx_uncore_cpu_init(void);
+int knl_uncore_pci_init(void);
+void knl_uncore_cpu_init(void);
+
+/* perf_event_intel_uncore_nhmex.c */
+void nhmex_uncore_cpu_init(void);
--- /dev/null
+++ zfcpdump-kernel-4.4/arch/x86/events/intel/uncore_nhmex.c
@@ -0,0 +1,1221 @@
+/* Nehalem-EX/Westmere-EX uncore support */
+#include "uncore.h"
+
+/* NHM-EX event control */
+#define NHMEX_PMON_CTL_EV_SEL_MASK	0x000000ff
+#define NHMEX_PMON_CTL_UMASK_MASK	0x0000ff00
+#define NHMEX_PMON_CTL_EN_BIT0		(1 << 0)
+#define NHMEX_PMON_CTL_EDGE_DET		(1 << 18)
+#define NHMEX_PMON_CTL_PMI_EN		(1 << 20)
+#define NHMEX_PMON_CTL_EN_BIT22		(1 << 22)
+#define NHMEX_PMON_CTL_INVERT		(1 << 23)
+#define NHMEX_PMON_CTL_TRESH_MASK	0xff000000
+#define NHMEX_PMON_RAW_EVENT_MASK	(NHMEX_PMON_CTL_EV_SEL_MASK | \
+					 NHMEX_PMON_CTL_UMASK_MASK | \
+					 NHMEX_PMON_CTL_EDGE_DET | \
+					 NHMEX_PMON_CTL_INVERT | \
+					 NHMEX_PMON_CTL_TRESH_MASK)
+
+/* NHM-EX Ubox */
+#define NHMEX_U_MSR_PMON_GLOBAL_CTL		0xc00
+#define NHMEX_U_MSR_PMON_CTR			0xc11
+#define NHMEX_U_MSR_PMON_EV_SEL			0xc10
+
+#define NHMEX_U_PMON_GLOBAL_EN			(1 << 0)
+#define NHMEX_U_PMON_GLOBAL_PMI_CORE_SEL	0x0000001e
+#define NHMEX_U_PMON_GLOBAL_EN_ALL		(1 << 28)
+#define NHMEX_U_PMON_GLOBAL_RST_ALL		(1 << 29)
+#define NHMEX_U_PMON_GLOBAL_FRZ_ALL		(1 << 31)
+
+#define NHMEX_U_PMON_RAW_EVENT_MASK		\
+		(NHMEX_PMON_CTL_EV_SEL_MASK |	\
+		 NHMEX_PMON_CTL_EDGE_DET)
+
+/* NHM-EX Cbox */
+#define NHMEX_C0_MSR_PMON_GLOBAL_CTL		0xd00
+#define NHMEX_C0_MSR_PMON_CTR0			0xd11
+#define NHMEX_C0_MSR_PMON_EV_SEL0		0xd10
+#define NHMEX_C_MSR_OFFSET			0x20
+
+/* NHM-EX Bbox */
+#define NHMEX_B0_MSR_PMON_GLOBAL_CTL		0xc20
+#define NHMEX_B0_MSR_PMON_CTR0			0xc31
+#define NHMEX_B0_MSR_PMON_CTL0			0xc30
+#define NHMEX_B_MSR_OFFSET			0x40
+#define NHMEX_B0_MSR_MATCH			0xe45
+#define NHMEX_B0_MSR_MASK			0xe46
+#define NHMEX_B1_MSR_MATCH			0xe4d
+#define NHMEX_B1_MSR_MASK			0xe4e
+
+#define NHMEX_B_PMON_CTL_EN			(1 << 0)
+#define NHMEX_B_PMON_CTL_EV_SEL_SHIFT		1
+#define NHMEX_B_PMON_CTL_EV_SEL_MASK		\
+		(0x1f << NHMEX_B_PMON_CTL_EV_SEL_SHIFT)
+#define NHMEX_B_PMON_CTR_SHIFT		6
+#define NHMEX_B_PMON_CTR_MASK		\
+		(0x3 << NHMEX_B_PMON_CTR_SHIFT)
+#define NHMEX_B_PMON_RAW_EVENT_MASK		\
+		(NHMEX_B_PMON_CTL_EV_SEL_MASK | \
+		 NHMEX_B_PMON_CTR_MASK)
+
+/* NHM-EX Sbox */
+#define NHMEX_S0_MSR_PMON_GLOBAL_CTL		0xc40
+#define NHMEX_S0_MSR_PMON_CTR0			0xc51
+#define NHMEX_S0_MSR_PMON_CTL0			0xc50
+#define NHMEX_S_MSR_OFFSET			0x80
+#define NHMEX_S0_MSR_MM_CFG			0xe48
+#define NHMEX_S0_MSR_MATCH			0xe49
+#define NHMEX_S0_MSR_MASK			0xe4a
+#define NHMEX_S1_MSR_MM_CFG			0xe58
+#define NHMEX_S1_MSR_MATCH			0xe59
+#define NHMEX_S1_MSR_MASK			0xe5a
+
+#define NHMEX_S_PMON_MM_CFG_EN			(0x1ULL << 63)
+#define NHMEX_S_EVENT_TO_R_PROG_EV		0
+
+/* NHM-EX Mbox */
+#define NHMEX_M0_MSR_GLOBAL_CTL			0xca0
+#define NHMEX_M0_MSR_PMU_DSP			0xca5
+#define NHMEX_M0_MSR_PMU_ISS			0xca6
+#define NHMEX_M0_MSR_PMU_MAP			0xca7
+#define NHMEX_M0_MSR_PMU_MSC_THR		0xca8
+#define NHMEX_M0_MSR_PMU_PGT			0xca9
+#define NHMEX_M0_MSR_PMU_PLD			0xcaa
+#define NHMEX_M0_MSR_PMU_ZDP_CTL_FVC		0xcab
+#define NHMEX_M0_MSR_PMU_CTL0			0xcb0
+#define NHMEX_M0_MSR_PMU_CNT0			0xcb1
+#define NHMEX_M_MSR_OFFSET			0x40
+#define NHMEX_M0_MSR_PMU_MM_CFG			0xe54
+#define NHMEX_M1_MSR_PMU_MM_CFG			0xe5c
+
+#define NHMEX_M_PMON_MM_CFG_EN			(1ULL << 63)
+#define NHMEX_M_PMON_ADDR_MATCH_MASK		0x3ffffffffULL
+#define NHMEX_M_PMON_ADDR_MASK_MASK		0x7ffffffULL
+#define NHMEX_M_PMON_ADDR_MASK_SHIFT		34
+
+#define NHMEX_M_PMON_CTL_EN			(1 << 0)
+#define NHMEX_M_PMON_CTL_PMI_EN			(1 << 1)
+#define NHMEX_M_PMON_CTL_COUNT_MODE_SHIFT	2
+#define NHMEX_M_PMON_CTL_COUNT_MODE_MASK	\
+	(0x3 << NHMEX_M_PMON_CTL_COUNT_MODE_SHIFT)
+#define NHMEX_M_PMON_CTL_STORAGE_MODE_SHIFT	4
+#define NHMEX_M_PMON_CTL_STORAGE_MODE_MASK	\
+	(0x3 << NHMEX_M_PMON_CTL_STORAGE_MODE_SHIFT)
+#define NHMEX_M_PMON_CTL_WRAP_MODE		(1 << 6)
+#define NHMEX_M_PMON_CTL_FLAG_MODE		(1 << 7)
+#define NHMEX_M_PMON_CTL_INC_SEL_SHIFT		9
+#define NHMEX_M_PMON_CTL_INC_SEL_MASK		\
+	(0x1f << NHMEX_M_PMON_CTL_INC_SEL_SHIFT)
+#define NHMEX_M_PMON_CTL_SET_FLAG_SEL_SHIFT	19
+#define NHMEX_M_PMON_CTL_SET_FLAG_SEL_MASK	\
+	(0x7 << NHMEX_M_PMON_CTL_SET_FLAG_SEL_SHIFT)
+#define NHMEX_M_PMON_RAW_EVENT_MASK			\
+		(NHMEX_M_PMON_CTL_COUNT_MODE_MASK |	\
+		 NHMEX_M_PMON_CTL_STORAGE_MODE_MASK |	\
+		 NHMEX_M_PMON_CTL_WRAP_MODE |		\
+		 NHMEX_M_PMON_CTL_FLAG_MODE |		\
+		 NHMEX_M_PMON_CTL_INC_SEL_MASK |	\
+		 NHMEX_M_PMON_CTL_SET_FLAG_SEL_MASK)
+
+#define NHMEX_M_PMON_ZDP_CTL_FVC_MASK		(((1 << 11) - 1) | (1 << 23))
+#define NHMEX_M_PMON_ZDP_CTL_FVC_EVENT_MASK(n)	(0x7ULL << (11 + 3 * (n)))
+
+#define WSMEX_M_PMON_ZDP_CTL_FVC_MASK		(((1 << 12) - 1) | (1 << 24))
+#define WSMEX_M_PMON_ZDP_CTL_FVC_EVENT_MASK(n)	(0x7ULL << (12 + 3 * (n)))
+
+/*
+ * use the 9~13 bits to select event If the 7th bit is not set,
+ * otherwise use the 19~21 bits to select event.
+ */
+#define MBOX_INC_SEL(x) ((x) << NHMEX_M_PMON_CTL_INC_SEL_SHIFT)
+#define MBOX_SET_FLAG_SEL(x) (((x) << NHMEX_M_PMON_CTL_SET_FLAG_SEL_SHIFT) | \
+				NHMEX_M_PMON_CTL_FLAG_MODE)
+#define MBOX_INC_SEL_MASK (NHMEX_M_PMON_CTL_INC_SEL_MASK | \
+			   NHMEX_M_PMON_CTL_FLAG_MODE)
+#define MBOX_SET_FLAG_SEL_MASK (NHMEX_M_PMON_CTL_SET_FLAG_SEL_MASK | \
+				NHMEX_M_PMON_CTL_FLAG_MODE)
+#define MBOX_INC_SEL_EXTAR_REG(c, r) \
+		EVENT_EXTRA_REG(MBOX_INC_SEL(c), NHMEX_M0_MSR_PMU_##r, \
+				MBOX_INC_SEL_MASK, (u64)-1, NHMEX_M_##r)
+#define MBOX_SET_FLAG_SEL_EXTRA_REG(c, r) \
+		EVENT_EXTRA_REG(MBOX_SET_FLAG_SEL(c), NHMEX_M0_MSR_PMU_##r, \
+				MBOX_SET_FLAG_SEL_MASK, \
+				(u64)-1, NHMEX_M_##r)
+
+/* NHM-EX Rbox */
+#define NHMEX_R_MSR_GLOBAL_CTL			0xe00
+#define NHMEX_R_MSR_PMON_CTL0			0xe10
+#define NHMEX_R_MSR_PMON_CNT0			0xe11
+#define NHMEX_R_MSR_OFFSET			0x20
+
+#define NHMEX_R_MSR_PORTN_QLX_CFG(n)		\
+		((n) < 4 ? (0xe0c + (n)) : (0xe2c + (n) - 4))
+#define NHMEX_R_MSR_PORTN_IPERF_CFG0(n)		(0xe04 + (n))
+#define NHMEX_R_MSR_PORTN_IPERF_CFG1(n)		(0xe24 + (n))
+#define NHMEX_R_MSR_PORTN_XBR_OFFSET(n)		\
+		(((n) < 4 ? 0 : 0x10) + (n) * 4)
+#define NHMEX_R_MSR_PORTN_XBR_SET1_MM_CFG(n)	\
+		(0xe60 + NHMEX_R_MSR_PORTN_XBR_OFFSET(n))
+#define NHMEX_R_MSR_PORTN_XBR_SET1_MATCH(n)	\
+		(NHMEX_R_MSR_PORTN_XBR_SET1_MM_CFG(n) + 1)
+#define NHMEX_R_MSR_PORTN_XBR_SET1_MASK(n)	\
+		(NHMEX_R_MSR_PORTN_XBR_SET1_MM_CFG(n) + 2)
+#define NHMEX_R_MSR_PORTN_XBR_SET2_MM_CFG(n)	\
+		(0xe70 + NHMEX_R_MSR_PORTN_XBR_OFFSET(n))
+#define NHMEX_R_MSR_PORTN_XBR_SET2_MATCH(n)	\
+		(NHMEX_R_MSR_PORTN_XBR_SET2_MM_CFG(n) + 1)
+#define NHMEX_R_MSR_PORTN_XBR_SET2_MASK(n)	\
+		(NHMEX_R_MSR_PORTN_XBR_SET2_MM_CFG(n) + 2)
+
+#define NHMEX_R_PMON_CTL_EN			(1 << 0)
+#define NHMEX_R_PMON_CTL_EV_SEL_SHIFT		1
+#define NHMEX_R_PMON_CTL_EV_SEL_MASK		\
+		(0x1f << NHMEX_R_PMON_CTL_EV_SEL_SHIFT)
+#define NHMEX_R_PMON_CTL_PMI_EN			(1 << 6)
+#define NHMEX_R_PMON_RAW_EVENT_MASK		NHMEX_R_PMON_CTL_EV_SEL_MASK
+
+/* NHM-EX Wbox */
+#define NHMEX_W_MSR_GLOBAL_CTL			0xc80
+#define NHMEX_W_MSR_PMON_CNT0			0xc90
+#define NHMEX_W_MSR_PMON_EVT_SEL0		0xc91
+#define NHMEX_W_MSR_PMON_FIXED_CTR		0x394
+#define NHMEX_W_MSR_PMON_FIXED_CTL		0x395
+
+#define NHMEX_W_PMON_GLOBAL_FIXED_EN		(1ULL << 31)
+
+#define __BITS_VALUE(x, i, n)  ((typeof(x))(((x) >> ((i) * (n))) & \
+				((1ULL << (n)) - 1)))
+
+DEFINE_UNCORE_FORMAT_ATTR(event, event, "config:0-7");
+DEFINE_UNCORE_FORMAT_ATTR(event5, event, "config:1-5");
+DEFINE_UNCORE_FORMAT_ATTR(umask, umask, "config:8-15");
+DEFINE_UNCORE_FORMAT_ATTR(edge, edge, "config:18");
+DEFINE_UNCORE_FORMAT_ATTR(inv, inv, "config:23");
+DEFINE_UNCORE_FORMAT_ATTR(thresh8, thresh, "config:24-31");
+DEFINE_UNCORE_FORMAT_ATTR(counter, counter, "config:6-7");
+DEFINE_UNCORE_FORMAT_ATTR(match, match, "config1:0-63");
+DEFINE_UNCORE_FORMAT_ATTR(mask, mask, "config2:0-63");
+
+static void nhmex_uncore_msr_init_box(struct intel_uncore_box *box)
+{
+	wrmsrl(NHMEX_U_MSR_PMON_GLOBAL_CTL, NHMEX_U_PMON_GLOBAL_EN_ALL);
+}
+
+static void nhmex_uncore_msr_disable_box(struct intel_uncore_box *box)
+{
+	unsigned msr = uncore_msr_box_ctl(box);
+	u64 config;
+
+	if (msr) {
+		rdmsrl(msr, config);
+		config &= ~((1ULL << uncore_num_counters(box)) - 1);
+		/* WBox has a fixed counter */
+		if (uncore_msr_fixed_ctl(box))
+			config &= ~NHMEX_W_PMON_GLOBAL_FIXED_EN;
+		wrmsrl(msr, config);
+	}
+}
+
+static void nhmex_uncore_msr_enable_box(struct intel_uncore_box *box)
+{
+	unsigned msr = uncore_msr_box_ctl(box);
+	u64 config;
+
+	if (msr) {
+		rdmsrl(msr, config);
+		config |= (1ULL << uncore_num_counters(box)) - 1;
+		/* WBox has a fixed counter */
+		if (uncore_msr_fixed_ctl(box))
+			config |= NHMEX_W_PMON_GLOBAL_FIXED_EN;
+		wrmsrl(msr, config);
+	}
+}
+
+static void nhmex_uncore_msr_disable_event(struct intel_uncore_box *box, struct perf_event *event)
+{
+	wrmsrl(event->hw.config_base, 0);
+}
+
+static void nhmex_uncore_msr_enable_event(struct intel_uncore_box *box, struct perf_event *event)
+{
+	struct hw_perf_event *hwc = &event->hw;
+
+	if (hwc->idx >= UNCORE_PMC_IDX_FIXED)
+		wrmsrl(hwc->config_base, NHMEX_PMON_CTL_EN_BIT0);
+	else if (box->pmu->type->event_mask & NHMEX_PMON_CTL_EN_BIT0)
+		wrmsrl(hwc->config_base, hwc->config | NHMEX_PMON_CTL_EN_BIT22);
+	else
+		wrmsrl(hwc->config_base, hwc->config | NHMEX_PMON_CTL_EN_BIT0);
+}
+
+#define NHMEX_UNCORE_OPS_COMMON_INIT()				\
+	.init_box	= nhmex_uncore_msr_init_box,		\
+	.disable_box	= nhmex_uncore_msr_disable_box,		\
+	.enable_box	= nhmex_uncore_msr_enable_box,		\
+	.disable_event	= nhmex_uncore_msr_disable_event,	\
+	.read_counter	= uncore_msr_read_counter
+
+static struct intel_uncore_ops nhmex_uncore_ops = {
+	NHMEX_UNCORE_OPS_COMMON_INIT(),
+	.enable_event	= nhmex_uncore_msr_enable_event,
+};
+
+static struct attribute *nhmex_uncore_ubox_formats_attr[] = {
+	&format_attr_event.attr,
+	&format_attr_edge.attr,
+	NULL,
+};
+
+static struct attribute_group nhmex_uncore_ubox_format_group = {
+	.name		= "format",
+	.attrs		= nhmex_uncore_ubox_formats_attr,
+};
+
+static struct intel_uncore_type nhmex_uncore_ubox = {
+	.name		= "ubox",
+	.num_counters	= 1,
+	.num_boxes	= 1,
+	.perf_ctr_bits	= 48,
+	.event_ctl	= NHMEX_U_MSR_PMON_EV_SEL,
+	.perf_ctr	= NHMEX_U_MSR_PMON_CTR,
+	.event_mask	= NHMEX_U_PMON_RAW_EVENT_MASK,
+	.box_ctl	= NHMEX_U_MSR_PMON_GLOBAL_CTL,
+	.ops		= &nhmex_uncore_ops,
+	.format_group	= &nhmex_uncore_ubox_format_group
+};
+
+static struct attribute *nhmex_uncore_cbox_formats_attr[] = {
+	&format_attr_event.attr,
+	&format_attr_umask.attr,
+	&format_attr_edge.attr,
+	&format_attr_inv.attr,
+	&format_attr_thresh8.attr,
+	NULL,
+};
+
+static struct attribute_group nhmex_uncore_cbox_format_group = {
+	.name = "format",
+	.attrs = nhmex_uncore_cbox_formats_attr,
+};
+
+/* msr offset for each instance of cbox */
+static unsigned nhmex_cbox_msr_offsets[] = {
+	0x0, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, 0x240, 0x2c0,
+};
+
+static struct intel_uncore_type nhmex_uncore_cbox = {
+	.name			= "cbox",
+	.num_counters		= 6,
+	.num_boxes		= 10,
+	.perf_ctr_bits		= 48,
+	.event_ctl		= NHMEX_C0_MSR_PMON_EV_SEL0,
+	.perf_ctr		= NHMEX_C0_MSR_PMON_CTR0,
+	.event_mask		= NHMEX_PMON_RAW_EVENT_MASK,
+	.box_ctl		= NHMEX_C0_MSR_PMON_GLOBAL_CTL,
+	.msr_offsets		= nhmex_cbox_msr_offsets,
+	.pair_ctr_ctl		= 1,
+	.ops			= &nhmex_uncore_ops,
+	.format_group		= &nhmex_uncore_cbox_format_group
+};
+
+static struct uncore_event_desc nhmex_uncore_wbox_events[] = {
+	INTEL_UNCORE_EVENT_DESC(clockticks, "event=0xff,umask=0"),
+	{ /* end: all zeroes */ },
+};
+
+static struct intel_uncore_type nhmex_uncore_wbox = {
+	.name			= "wbox",
+	.num_counters		= 4,
+	.num_boxes		= 1,
+	.perf_ctr_bits		= 48,
+	.event_ctl		= NHMEX_W_MSR_PMON_CNT0,
+	.perf_ctr		= NHMEX_W_MSR_PMON_EVT_SEL0,
+	.fixed_ctr		= NHMEX_W_MSR_PMON_FIXED_CTR,
+	.fixed_ctl		= NHMEX_W_MSR_PMON_FIXED_CTL,
+	.event_mask		= NHMEX_PMON_RAW_EVENT_MASK,
+	.box_ctl		= NHMEX_W_MSR_GLOBAL_CTL,
+	.pair_ctr_ctl		= 1,
+	.event_descs		= nhmex_uncore_wbox_events,
+	.ops			= &nhmex_uncore_ops,
+	.format_group		= &nhmex_uncore_cbox_format_group
+};
+
+static int nhmex_bbox_hw_config(struct intel_uncore_box *box, struct perf_event *event)
+{
+	struct hw_perf_event *hwc = &event->hw;
+	struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
+	struct hw_perf_event_extra *reg2 = &hwc->branch_reg;
+	int ctr, ev_sel;
+
+	ctr = (hwc->config & NHMEX_B_PMON_CTR_MASK) >>
+		NHMEX_B_PMON_CTR_SHIFT;
+	ev_sel = (hwc->config & NHMEX_B_PMON_CTL_EV_SEL_MASK) >>
+		  NHMEX_B_PMON_CTL_EV_SEL_SHIFT;
+
+	/* events that do not use the match/mask registers */
+	if ((ctr == 0 && ev_sel > 0x3) || (ctr == 1 && ev_sel > 0x6) ||
+	    (ctr == 2 && ev_sel != 0x4) || ctr == 3)
+		return 0;
+
+	if (box->pmu->pmu_idx == 0)
+		reg1->reg = NHMEX_B0_MSR_MATCH;
+	else
+		reg1->reg = NHMEX_B1_MSR_MATCH;
+	reg1->idx = 0;
+	reg1->config = event->attr.config1;
+	reg2->config = event->attr.config2;
+	return 0;
+}
+
+static void nhmex_bbox_msr_enable_event(struct intel_uncore_box *box, struct perf_event *event)
+{
+	struct hw_perf_event *hwc = &event->hw;
+	struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
+	struct hw_perf_event_extra *reg2 = &hwc->branch_reg;
+
+	if (reg1->idx != EXTRA_REG_NONE) {
+		wrmsrl(reg1->reg, reg1->config);
+		wrmsrl(reg1->reg + 1, reg2->config);
+	}
+	wrmsrl(hwc->config_base, NHMEX_PMON_CTL_EN_BIT0 |
+		(hwc->config & NHMEX_B_PMON_CTL_EV_SEL_MASK));
+}
+
+/*
+ * The Bbox has 4 counters, but each counter monitors different events.
+ * Use bits 6-7 in the event config to select counter.
+ */
+static struct event_constraint nhmex_uncore_bbox_constraints[] = {
+	EVENT_CONSTRAINT(0 , 1, 0xc0),
+	EVENT_CONSTRAINT(0x40, 2, 0xc0),
+	EVENT_CONSTRAINT(0x80, 4, 0xc0),
+	EVENT_CONSTRAINT(0xc0, 8, 0xc0),
+	EVENT_CONSTRAINT_END,
+};
+
+static struct attribute *nhmex_uncore_bbox_formats_attr[] = {
+	&format_attr_event5.attr,
+	&format_attr_counter.attr,
+	&format_attr_match.attr,
+	&format_attr_mask.attr,
+	NULL,
+};
+
+static struct attribute_group nhmex_uncore_bbox_format_group = {
+	.name = "format",
+	.attrs = nhmex_uncore_bbox_formats_attr,
+};
+
+static struct intel_uncore_ops nhmex_uncore_bbox_ops = {
+	NHMEX_UNCORE_OPS_COMMON_INIT(),
+	.enable_event		= nhmex_bbox_msr_enable_event,
+	.hw_config		= nhmex_bbox_hw_config,
+	.get_constraint		= uncore_get_constraint,
+	.put_constraint		= uncore_put_constraint,
+};
+
+static struct intel_uncore_type nhmex_uncore_bbox = {
+	.name			= "bbox",
+	.num_counters		= 4,
+	.num_boxes		= 2,
+	.perf_ctr_bits		= 48,
+	.event_ctl		= NHMEX_B0_MSR_PMON_CTL0,
+	.perf_ctr		= NHMEX_B0_MSR_PMON_CTR0,
+	.event_mask		= NHMEX_B_PMON_RAW_EVENT_MASK,
+	.box_ctl		= NHMEX_B0_MSR_PMON_GLOBAL_CTL,
+	.msr_offset		= NHMEX_B_MSR_OFFSET,
+	.pair_ctr_ctl		= 1,
+	.num_shared_regs	= 1,
+	.constraints		= nhmex_uncore_bbox_constraints,
+	.ops			= &nhmex_uncore_bbox_ops,
+	.format_group		= &nhmex_uncore_bbox_format_group
+};
+
+static int nhmex_sbox_hw_config(struct intel_uncore_box *box, struct perf_event *event)
+{
+	struct hw_perf_event *hwc = &event->hw;
+	struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
+	struct hw_perf_event_extra *reg2 = &hwc->branch_reg;
+
+	/* only TO_R_PROG_EV event uses the match/mask register */
+	if ((hwc->config & NHMEX_PMON_CTL_EV_SEL_MASK) !=
+	    NHMEX_S_EVENT_TO_R_PROG_EV)
+		return 0;
+
+	if (box->pmu->pmu_idx == 0)
+		reg1->reg = NHMEX_S0_MSR_MM_CFG;
+	else
+		reg1->reg = NHMEX_S1_MSR_MM_CFG;
+	reg1->idx = 0;
+	reg1->config = event->attr.config1;
+	reg2->config = event->attr.config2;
+	return 0;
+}
+
+static void nhmex_sbox_msr_enable_event(struct intel_uncore_box *box, struct perf_event *event)
+{
+	struct hw_perf_event *hwc = &event->hw;
+	struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
+	struct hw_perf_event_extra *reg2 = &hwc->branch_reg;
+
+	if (reg1->idx != EXTRA_REG_NONE) {
+		wrmsrl(reg1->reg, 0);
+		wrmsrl(reg1->reg + 1, reg1->config);
+		wrmsrl(reg1->reg + 2, reg2->config);
+		wrmsrl(reg1->reg, NHMEX_S_PMON_MM_CFG_EN);
+	}
+	wrmsrl(hwc->config_base, hwc->config | NHMEX_PMON_CTL_EN_BIT22);
+}
+
+static struct attribute *nhmex_uncore_sbox_formats_attr[] = {
+	&format_attr_event.attr,
+	&format_attr_umask.attr,
+	&format_attr_edge.attr,
+	&format_attr_inv.attr,
+	&format_attr_thresh8.attr,
+	&format_attr_match.attr,
+	&format_attr_mask.attr,
+	NULL,
+};
+
+static struct attribute_group nhmex_uncore_sbox_format_group = {
+	.name			= "format",
+	.attrs			= nhmex_uncore_sbox_formats_attr,
+};
+
+static struct intel_uncore_ops nhmex_uncore_sbox_ops = {
+	NHMEX_UNCORE_OPS_COMMON_INIT(),
+	.enable_event		= nhmex_sbox_msr_enable_event,
+	.hw_config		= nhmex_sbox_hw_config,
+	.get_constraint		= uncore_get_constraint,
+	.put_constraint		= uncore_put_constraint,
+};
+
+static struct intel_uncore_type nhmex_uncore_sbox = {
+	.name			= "sbox",
+	.num_counters		= 4,
+	.num_boxes		= 2,
+	.perf_ctr_bits		= 48,
+	.event_ctl		= NHMEX_S0_MSR_PMON_CTL0,
+	.perf_ctr		= NHMEX_S0_MSR_PMON_CTR0,
+	.event_mask		= NHMEX_PMON_RAW_EVENT_MASK,
+	.box_ctl		= NHMEX_S0_MSR_PMON_GLOBAL_CTL,
+	.msr_offset		= NHMEX_S_MSR_OFFSET,
+	.pair_ctr_ctl		= 1,
+	.num_shared_regs	= 1,
+	.ops			= &nhmex_uncore_sbox_ops,
+	.format_group		= &nhmex_uncore_sbox_format_group
+};
+
+enum {
+	EXTRA_REG_NHMEX_M_FILTER,
+	EXTRA_REG_NHMEX_M_DSP,
+	EXTRA_REG_NHMEX_M_ISS,
+	EXTRA_REG_NHMEX_M_MAP,
+	EXTRA_REG_NHMEX_M_MSC_THR,
+	EXTRA_REG_NHMEX_M_PGT,
+	EXTRA_REG_NHMEX_M_PLD,
+	EXTRA_REG_NHMEX_M_ZDP_CTL_FVC,
+};
+
+static struct extra_reg nhmex_uncore_mbox_extra_regs[] = {
+	MBOX_INC_SEL_EXTAR_REG(0x0, DSP),
+	MBOX_INC_SEL_EXTAR_REG(0x4, MSC_THR),
+	MBOX_INC_SEL_EXTAR_REG(0x5, MSC_THR),
+	MBOX_INC_SEL_EXTAR_REG(0x9, ISS),
+	/* event 0xa uses two extra registers */
+	MBOX_INC_SEL_EXTAR_REG(0xa, ISS),
+	MBOX_INC_SEL_EXTAR_REG(0xa, PLD),
+	MBOX_INC_SEL_EXTAR_REG(0xb, PLD),
+	/* events 0xd ~ 0x10 use the same extra register */
+	MBOX_INC_SEL_EXTAR_REG(0xd, ZDP_CTL_FVC),
+	MBOX_INC_SEL_EXTAR_REG(0xe, ZDP_CTL_FVC),
+	MBOX_INC_SEL_EXTAR_REG(0xf, ZDP_CTL_FVC),
+	MBOX_INC_SEL_EXTAR_REG(0x10, ZDP_CTL_FVC),
+	MBOX_INC_SEL_EXTAR_REG(0x16, PGT),
+	MBOX_SET_FLAG_SEL_EXTRA_REG(0x0, DSP),
+	MBOX_SET_FLAG_SEL_EXTRA_REG(0x1, ISS),
+	MBOX_SET_FLAG_SEL_EXTRA_REG(0x5, PGT),
+	MBOX_SET_FLAG_SEL_EXTRA_REG(0x6, MAP),
+	EVENT_EXTRA_END
+};
+
+/* Nehalem-EX or Westmere-EX ? */
+static bool uncore_nhmex;
+
+static bool nhmex_mbox_get_shared_reg(struct intel_uncore_box *box, int idx, u64 config)
+{
+	struct intel_uncore_extra_reg *er;
+	unsigned long flags;
+	bool ret = false;
+	u64 mask;
+
+	if (idx < EXTRA_REG_NHMEX_M_ZDP_CTL_FVC) {
+		er = &box->shared_regs[idx];
+		raw_spin_lock_irqsave(&er->lock, flags);
+		if (!atomic_read(&er->ref) || er->config == config) {
+			atomic_inc(&er->ref);
+			er->config = config;
+			ret = true;
+		}
+		raw_spin_unlock_irqrestore(&er->lock, flags);
+
+		return ret;
+	}
+	/*
+	 * The ZDP_CTL_FVC MSR has 4 fields which are used to control
+	 * events 0xd ~ 0x10. Besides these 4 fields, there are additional
+	 * fields which are shared.
+	 */
+	idx -= EXTRA_REG_NHMEX_M_ZDP_CTL_FVC;
+	if (WARN_ON_ONCE(idx >= 4))
+		return false;
+
+	/* mask of the shared fields */
+	if (uncore_nhmex)
+		mask = NHMEX_M_PMON_ZDP_CTL_FVC_MASK;
+	else
+		mask = WSMEX_M_PMON_ZDP_CTL_FVC_MASK;
+	er = &box->shared_regs[EXTRA_REG_NHMEX_M_ZDP_CTL_FVC];
+
+	raw_spin_lock_irqsave(&er->lock, flags);
+	/* add mask of the non-shared field if it's in use */
+	if (__BITS_VALUE(atomic_read(&er->ref), idx, 8)) {
+		if (uncore_nhmex)
+			mask |= NHMEX_M_PMON_ZDP_CTL_FVC_EVENT_MASK(idx);
+		else
+			mask |= WSMEX_M_PMON_ZDP_CTL_FVC_EVENT_MASK(idx);
+	}
+
+	if (!atomic_read(&er->ref) || !((er->config ^ config) & mask)) {
+		atomic_add(1 << (idx * 8), &er->ref);
+		if (uncore_nhmex)
+			mask = NHMEX_M_PMON_ZDP_CTL_FVC_MASK |
+				NHMEX_M_PMON_ZDP_CTL_FVC_EVENT_MASK(idx);
+		else
+			mask = WSMEX_M_PMON_ZDP_CTL_FVC_MASK |
+				WSMEX_M_PMON_ZDP_CTL_FVC_EVENT_MASK(idx);
+		er->config &= ~mask;
+		er->config |= (config & mask);
+		ret = true;
+	}
+	raw_spin_unlock_irqrestore(&er->lock, flags);
+
+	return ret;
+}
+
+static void nhmex_mbox_put_shared_reg(struct intel_uncore_box *box, int idx)
+{
+	struct intel_uncore_extra_reg *er;
+
+	if (idx < EXTRA_REG_NHMEX_M_ZDP_CTL_FVC) {
+		er = &box->shared_regs[idx];
+		atomic_dec(&er->ref);
+		return;
+	}
+
+	idx -= EXTRA_REG_NHMEX_M_ZDP_CTL_FVC;
+	er = &box->shared_regs[EXTRA_REG_NHMEX_M_ZDP_CTL_FVC];
+	atomic_sub(1 << (idx * 8), &er->ref);
+}
+
+static u64 nhmex_mbox_alter_er(struct perf_event *event, int new_idx, bool modify)
+{
+	struct hw_perf_event *hwc = &event->hw;
+	struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
+	u64 idx, orig_idx = __BITS_VALUE(reg1->idx, 0, 8);
+	u64 config = reg1->config;
+
+	/* get the non-shared control bits and shift them */
+	idx = orig_idx - EXTRA_REG_NHMEX_M_ZDP_CTL_FVC;
+	if (uncore_nhmex)
+		config &= NHMEX_M_PMON_ZDP_CTL_FVC_EVENT_MASK(idx);
+	else
+		config &= WSMEX_M_PMON_ZDP_CTL_FVC_EVENT_MASK(idx);
+	if (new_idx > orig_idx) {
+		idx = new_idx - orig_idx;
+		config <<= 3 * idx;
+	} else {
+		idx = orig_idx - new_idx;
+		config >>= 3 * idx;
+	}
+
+	/* add the shared control bits back */
+	if (uncore_nhmex)
+		config |= NHMEX_M_PMON_ZDP_CTL_FVC_MASK & reg1->config;
+	else
+		config |= WSMEX_M_PMON_ZDP_CTL_FVC_MASK & reg1->config;
+	config |= NHMEX_M_PMON_ZDP_CTL_FVC_MASK & reg1->config;
+	if (modify) {
+		/* adjust the main event selector */
+		if (new_idx > orig_idx)
+			hwc->config += idx << NHMEX_M_PMON_CTL_INC_SEL_SHIFT;
+		else
+			hwc->config -= idx << NHMEX_M_PMON_CTL_INC_SEL_SHIFT;
+		reg1->config = config;
+		reg1->idx = ~0xff | new_idx;
+	}
+	return config;
+}
+
+static struct event_constraint *
+nhmex_mbox_get_constraint(struct intel_uncore_box *box, struct perf_event *event)
+{
+	struct hw_perf_event_extra *reg1 = &event->hw.extra_reg;
+	struct hw_perf_event_extra *reg2 = &event->hw.branch_reg;
+	int i, idx[2], alloc = 0;
+	u64 config1 = reg1->config;
+
+	idx[0] = __BITS_VALUE(reg1->idx, 0, 8);
+	idx[1] = __BITS_VALUE(reg1->idx, 1, 8);
+again:
+	for (i = 0; i < 2; i++) {
+		if (!uncore_box_is_fake(box) && (reg1->alloc & (0x1 << i)))
+			idx[i] = 0xff;
+
+		if (idx[i] == 0xff)
+			continue;
+
+		if (!nhmex_mbox_get_shared_reg(box, idx[i],
+				__BITS_VALUE(config1, i, 32)))
+			goto fail;
+		alloc |= (0x1 << i);
+	}
+
+	/* for the match/mask registers */
+	if (reg2->idx != EXTRA_REG_NONE &&
+	    (uncore_box_is_fake(box) || !reg2->alloc) &&
+	    !nhmex_mbox_get_shared_reg(box, reg2->idx, reg2->config))
+		goto fail;
+
+	/*
+	 * If it's a fake box -- as per validate_{group,event}() we
+	 * shouldn't touch event state and we can avoid doing so
+	 * since both will only call get_event_constraints() once
+	 * on each event, this avoids the need for reg->alloc.
+	 */
+	if (!uncore_box_is_fake(box)) {
+		if (idx[0] != 0xff && idx[0] != __BITS_VALUE(reg1->idx, 0, 8))
+			nhmex_mbox_alter_er(event, idx[0], true);
+		reg1->alloc |= alloc;
+		if (reg2->idx != EXTRA_REG_NONE)
+			reg2->alloc = 1;
+	}
+	return NULL;
+fail:
+	if (idx[0] != 0xff && !(alloc & 0x1) &&
+	    idx[0] >= EXTRA_REG_NHMEX_M_ZDP_CTL_FVC) {
+		/*
+		 * events 0xd ~ 0x10 are functional identical, but are
+		 * controlled by different fields in the ZDP_CTL_FVC
+		 * register. If we failed to take one field, try the
+		 * rest 3 choices.
+		 */
+		BUG_ON(__BITS_VALUE(reg1->idx, 1, 8) != 0xff);
+		idx[0] -= EXTRA_REG_NHMEX_M_ZDP_CTL_FVC;
+		idx[0] = (idx[0] + 1) % 4;
+		idx[0] += EXTRA_REG_NHMEX_M_ZDP_CTL_FVC;
+		if (idx[0] != __BITS_VALUE(reg1->idx, 0, 8)) {
+			config1 = nhmex_mbox_alter_er(event, idx[0], false);
+			goto again;
+		}
+	}
+
+	if (alloc & 0x1)
+		nhmex_mbox_put_shared_reg(box, idx[0]);
+	if (alloc & 0x2)
+		nhmex_mbox_put_shared_reg(box, idx[1]);
+	return &uncore_constraint_empty;
+}
+
+static void nhmex_mbox_put_constraint(struct intel_uncore_box *box, struct perf_event *event)
+{
+	struct hw_perf_event_extra *reg1 = &event->hw.extra_reg;
+	struct hw_perf_event_extra *reg2 = &event->hw.branch_reg;
+
+	if (uncore_box_is_fake(box))
+		return;
+
+	if (reg1->alloc & 0x1)
+		nhmex_mbox_put_shared_reg(box, __BITS_VALUE(reg1->idx, 0, 8));
+	if (reg1->alloc & 0x2)
+		nhmex_mbox_put_shared_reg(box, __BITS_VALUE(reg1->idx, 1, 8));
+	reg1->alloc = 0;
+
+	if (reg2->alloc) {
+		nhmex_mbox_put_shared_reg(box, reg2->idx);
+		reg2->alloc = 0;
+	}
+}
+
+static int nhmex_mbox_extra_reg_idx(struct extra_reg *er)
+{
+	if (er->idx < EXTRA_REG_NHMEX_M_ZDP_CTL_FVC)
+		return er->idx;
+	return er->idx + (er->event >> NHMEX_M_PMON_CTL_INC_SEL_SHIFT) - 0xd;
+}
+
+static int nhmex_mbox_hw_config(struct intel_uncore_box *box, struct perf_event *event)
+{
+	struct intel_uncore_type *type = box->pmu->type;
+	struct hw_perf_event_extra *reg1 = &event->hw.extra_reg;
+	struct hw_perf_event_extra *reg2 = &event->hw.branch_reg;
+	struct extra_reg *er;
+	unsigned msr;
+	int reg_idx = 0;
+	/*
+	 * The mbox events may require 2 extra MSRs at the most. But only
+	 * the lower 32 bits in these MSRs are significant, so we can use
+	 * config1 to pass two MSRs' config.
+	 */
+	for (er = nhmex_uncore_mbox_extra_regs; er->msr; er++) {
+		if (er->event != (event->hw.config & er->config_mask))
+			continue;
+		if (event->attr.config1 & ~er->valid_mask)
+			return -EINVAL;
+
+		msr = er->msr + type->msr_offset * box->pmu->pmu_idx;
+		if (WARN_ON_ONCE(msr >= 0xffff || er->idx >= 0xff))
+			return -EINVAL;
+
+		/* always use the 32~63 bits to pass the PLD config */
+		if (er->idx == EXTRA_REG_NHMEX_M_PLD)
+			reg_idx = 1;
+		else if (WARN_ON_ONCE(reg_idx > 0))
+			return -EINVAL;
+
+		reg1->idx &= ~(0xff << (reg_idx * 8));
+		reg1->reg &= ~(0xffff << (reg_idx * 16));
+		reg1->idx |= nhmex_mbox_extra_reg_idx(er) << (reg_idx * 8);
+		reg1->reg |= msr << (reg_idx * 16);
+		reg1->config = event->attr.config1;
+		reg_idx++;
+	}
+	/*
+	 * The mbox only provides ability to perform address matching
+	 * for the PLD events.
+	 */
+	if (reg_idx == 2) {
+		reg2->idx = EXTRA_REG_NHMEX_M_FILTER;
+		if (event->attr.config2 & NHMEX_M_PMON_MM_CFG_EN)
+			reg2->config = event->attr.config2;
+		else
+			reg2->config = ~0ULL;
+		if (box->pmu->pmu_idx == 0)
+			reg2->reg = NHMEX_M0_MSR_PMU_MM_CFG;
+		else
+			reg2->reg = NHMEX_M1_MSR_PMU_MM_CFG;
+	}
+	return 0;
+}
+
+static u64 nhmex_mbox_shared_reg_config(struct intel_uncore_box *box, int idx)
+{
+	struct intel_uncore_extra_reg *er;
+	unsigned long flags;
+	u64 config;
+
+	if (idx < EXTRA_REG_NHMEX_M_ZDP_CTL_FVC)
+		return box->shared_regs[idx].config;
+
+	er = &box->shared_regs[EXTRA_REG_NHMEX_M_ZDP_CTL_FVC];
+	raw_spin_lock_irqsave(&er->lock, flags);
+	config = er->config;
+	raw_spin_unlock_irqrestore(&er->lock, flags);
+	return config;
+}
+
+static void nhmex_mbox_msr_enable_event(struct intel_uncore_box *box, struct perf_event *event)
+{
+	struct hw_perf_event *hwc = &event->hw;
+	struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
+	struct hw_perf_event_extra *reg2 = &hwc->branch_reg;
+	int idx;
+
+	idx = __BITS_VALUE(reg1->idx, 0, 8);
+	if (idx != 0xff)
+		wrmsrl(__BITS_VALUE(reg1->reg, 0, 16),
+			nhmex_mbox_shared_reg_config(box, idx));
+	idx = __BITS_VALUE(reg1->idx, 1, 8);
+	if (idx != 0xff)
+		wrmsrl(__BITS_VALUE(reg1->reg, 1, 16),
+			nhmex_mbox_shared_reg_config(box, idx));
+
+	if (reg2->idx != EXTRA_REG_NONE) {
+		wrmsrl(reg2->reg, 0);
+		if (reg2->config != ~0ULL) {
+			wrmsrl(reg2->reg + 1,
+				reg2->config & NHMEX_M_PMON_ADDR_MATCH_MASK);
+			wrmsrl(reg2->reg + 2, NHMEX_M_PMON_ADDR_MASK_MASK &
+				(reg2->config >> NHMEX_M_PMON_ADDR_MASK_SHIFT));
+			wrmsrl(reg2->reg, NHMEX_M_PMON_MM_CFG_EN);
+		}
+	}
+
+	wrmsrl(hwc->config_base, hwc->config | NHMEX_PMON_CTL_EN_BIT0);
+}
+
+DEFINE_UNCORE_FORMAT_ATTR(count_mode,		count_mode,	"config:2-3");
+DEFINE_UNCORE_FORMAT_ATTR(storage_mode,		storage_mode,	"config:4-5");
+DEFINE_UNCORE_FORMAT_ATTR(wrap_mode,		wrap_mode,	"config:6");
+DEFINE_UNCORE_FORMAT_ATTR(flag_mode,		flag_mode,	"config:7");
+DEFINE_UNCORE_FORMAT_ATTR(inc_sel,		inc_sel,	"config:9-13");
+DEFINE_UNCORE_FORMAT_ATTR(set_flag_sel,		set_flag_sel,	"config:19-21");
+DEFINE_UNCORE_FORMAT_ATTR(filter_cfg_en,	filter_cfg_en,	"config2:63");
+DEFINE_UNCORE_FORMAT_ATTR(filter_match,		filter_match,	"config2:0-33");
+DEFINE_UNCORE_FORMAT_ATTR(filter_mask,		filter_mask,	"config2:34-61");
+DEFINE_UNCORE_FORMAT_ATTR(dsp,			dsp,		"config1:0-31");
+DEFINE_UNCORE_FORMAT_ATTR(thr,			thr,		"config1:0-31");
+DEFINE_UNCORE_FORMAT_ATTR(fvc,			fvc,		"config1:0-31");
+DEFINE_UNCORE_FORMAT_ATTR(pgt,			pgt,		"config1:0-31");
+DEFINE_UNCORE_FORMAT_ATTR(map,			map,		"config1:0-31");
+DEFINE_UNCORE_FORMAT_ATTR(iss,			iss,		"config1:0-31");
+DEFINE_UNCORE_FORMAT_ATTR(pld,			pld,		"config1:32-63");
+
+static struct attribute *nhmex_uncore_mbox_formats_attr[] = {
+	&format_attr_count_mode.attr,
+	&format_attr_storage_mode.attr,
+	&format_attr_wrap_mode.attr,
+	&format_attr_flag_mode.attr,
+	&format_attr_inc_sel.attr,
+	&format_attr_set_flag_sel.attr,
+	&format_attr_filter_cfg_en.attr,
+	&format_attr_filter_match.attr,
+	&format_attr_filter_mask.attr,
+	&format_attr_dsp.attr,
+	&format_attr_thr.attr,
+	&format_attr_fvc.attr,
+	&format_attr_pgt.attr,
+	&format_attr_map.attr,
+	&format_attr_iss.attr,
+	&format_attr_pld.attr,
+	NULL,
+};
+
+static struct attribute_group nhmex_uncore_mbox_format_group = {
+	.name		= "format",
+	.attrs		= nhmex_uncore_mbox_formats_attr,
+};
+
+static struct uncore_event_desc nhmex_uncore_mbox_events[] = {
+	INTEL_UNCORE_EVENT_DESC(bbox_cmds_read, "inc_sel=0xd,fvc=0x2800"),
+	INTEL_UNCORE_EVENT_DESC(bbox_cmds_write, "inc_sel=0xd,fvc=0x2820"),
+	{ /* end: all zeroes */ },
+};
+
+static struct uncore_event_desc wsmex_uncore_mbox_events[] = {
+	INTEL_UNCORE_EVENT_DESC(bbox_cmds_read, "inc_sel=0xd,fvc=0x5000"),
+	INTEL_UNCORE_EVENT_DESC(bbox_cmds_write, "inc_sel=0xd,fvc=0x5040"),
+	{ /* end: all zeroes */ },
+};
+
+static struct intel_uncore_ops nhmex_uncore_mbox_ops = {
+	NHMEX_UNCORE_OPS_COMMON_INIT(),
+	.enable_event	= nhmex_mbox_msr_enable_event,
+	.hw_config	= nhmex_mbox_hw_config,
+	.get_constraint	= nhmex_mbox_get_constraint,
+	.put_constraint	= nhmex_mbox_put_constraint,
+};
+
+static struct intel_uncore_type nhmex_uncore_mbox = {
+	.name			= "mbox",
+	.num_counters		= 6,
+	.num_boxes		= 2,
+	.perf_ctr_bits		= 48,
+	.event_ctl		= NHMEX_M0_MSR_PMU_CTL0,
+	.perf_ctr		= NHMEX_M0_MSR_PMU_CNT0,
+	.event_mask		= NHMEX_M_PMON_RAW_EVENT_MASK,
+	.box_ctl		= NHMEX_M0_MSR_GLOBAL_CTL,
+	.msr_offset		= NHMEX_M_MSR_OFFSET,
+	.pair_ctr_ctl		= 1,
+	.num_shared_regs	= 8,
+	.event_descs		= nhmex_uncore_mbox_events,
+	.ops			= &nhmex_uncore_mbox_ops,
+	.format_group		= &nhmex_uncore_mbox_format_group,
+};
+
+static void nhmex_rbox_alter_er(struct intel_uncore_box *box, struct perf_event *event)
+{
+	struct hw_perf_event *hwc = &event->hw;
+	struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
+
+	/* adjust the main event selector and extra register index */
+	if (reg1->idx % 2) {
+		reg1->idx--;
+		hwc->config -= 1 << NHMEX_R_PMON_CTL_EV_SEL_SHIFT;
+	} else {
+		reg1->idx++;
+		hwc->config += 1 << NHMEX_R_PMON_CTL_EV_SEL_SHIFT;
+	}
+
+	/* adjust extra register config */
+	switch (reg1->idx % 6) {
+	case 2:
+		/* shift the 8~15 bits to the 0~7 bits */
+		reg1->config >>= 8;
+		break;
+	case 3:
+		/* shift the 0~7 bits to the 8~15 bits */
+		reg1->config <<= 8;
+		break;
+	}
+}
+
+/*
+ * Each rbox has 4 event set which monitor PQI port 0~3 or 4~7.
+ * An event set consists of 6 events, the 3rd and 4th events in
+ * an event set use the same extra register. So an event set uses
+ * 5 extra registers.
+ */
+static struct event_constraint *
+nhmex_rbox_get_constraint(struct intel_uncore_box *box, struct perf_event *event)
+{
+	struct hw_perf_event *hwc = &event->hw;
+	struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
+	struct hw_perf_event_extra *reg2 = &hwc->branch_reg;
+	struct intel_uncore_extra_reg *er;
+	unsigned long flags;
+	int idx, er_idx;
+	u64 config1;
+	bool ok = false;
+
+	if (!uncore_box_is_fake(box) && reg1->alloc)
+		return NULL;
+
+	idx = reg1->idx % 6;
+	config1 = reg1->config;
+again:
+	er_idx = idx;
+	/* the 3rd and 4th events use the same extra register */
+	if (er_idx > 2)
+		er_idx--;
+	er_idx += (reg1->idx / 6) * 5;
+
+	er = &box->shared_regs[er_idx];
+	raw_spin_lock_irqsave(&er->lock, flags);
+	if (idx < 2) {
+		if (!atomic_read(&er->ref) || er->config == reg1->config) {
+			atomic_inc(&er->ref);
+			er->config = reg1->config;
+			ok = true;
+		}
+	} else if (idx == 2 || idx == 3) {
+		/*
+		 * these two events use different fields in a extra register,
+		 * the 0~7 bits and the 8~15 bits respectively.
+		 */
+		u64 mask = 0xff << ((idx - 2) * 8);
+		if (!__BITS_VALUE(atomic_read(&er->ref), idx - 2, 8) ||
+				!((er->config ^ config1) & mask)) {
+			atomic_add(1 << ((idx - 2) * 8), &er->ref);
+			er->config &= ~mask;
+			er->config |= config1 & mask;
+			ok = true;
+		}
+	} else {
+		if (!atomic_read(&er->ref) ||
+				(er->config == (hwc->config >> 32) &&
+				 er->config1 == reg1->config &&
+				 er->config2 == reg2->config)) {
+			atomic_inc(&er->ref);
+			er->config = (hwc->config >> 32);
+			er->config1 = reg1->config;
+			er->config2 = reg2->config;
+			ok = true;
+		}
+	}
+	raw_spin_unlock_irqrestore(&er->lock, flags);
+
+	if (!ok) {
+		/*
+		 * The Rbox events are always in pairs. The paired
+		 * events are functional identical, but use different
+		 * extra registers. If we failed to take an extra
+		 * register, try the alternative.
+		 */
+		idx ^= 1;
+		if (idx != reg1->idx % 6) {
+			if (idx == 2)
+				config1 >>= 8;
+			else if (idx == 3)
+				config1 <<= 8;
+			goto again;
+		}
+	} else {
+		if (!uncore_box_is_fake(box)) {
+			if (idx != reg1->idx % 6)
+				nhmex_rbox_alter_er(box, event);
+			reg1->alloc = 1;
+		}
+		return NULL;
+	}
+	return &uncore_constraint_empty;
+}
+
+static void nhmex_rbox_put_constraint(struct intel_uncore_box *box, struct perf_event *event)
+{
+	struct intel_uncore_extra_reg *er;
+	struct hw_perf_event_extra *reg1 = &event->hw.extra_reg;
+	int idx, er_idx;
+
+	if (uncore_box_is_fake(box) || !reg1->alloc)
+		return;
+
+	idx = reg1->idx % 6;
+	er_idx = idx;
+	if (er_idx > 2)
+		er_idx--;
+	er_idx += (reg1->idx / 6) * 5;
+
+	er = &box->shared_regs[er_idx];
+	if (idx == 2 || idx == 3)
+		atomic_sub(1 << ((idx - 2) * 8), &er->ref);
+	else
+		atomic_dec(&er->ref);
+
+	reg1->alloc = 0;
+}
+
+static int nhmex_rbox_hw_config(struct intel_uncore_box *box, struct perf_event *event)
+{
+	struct hw_perf_event *hwc = &event->hw;
+	struct hw_perf_event_extra *reg1 = &event->hw.extra_reg;
+	struct hw_perf_event_extra *reg2 = &event->hw.branch_reg;
+	int idx;
+
+	idx = (event->hw.config & NHMEX_R_PMON_CTL_EV_SEL_MASK) >>
+		NHMEX_R_PMON_CTL_EV_SEL_SHIFT;
+	if (idx >= 0x18)
+		return -EINVAL;
+
+	reg1->idx = idx;
+	reg1->config = event->attr.config1;
+
+	switch (idx % 6) {
+	case 4:
+	case 5:
+		hwc->config |= event->attr.config & (~0ULL << 32);
+		reg2->config = event->attr.config2;
+		break;
+	}
+	return 0;
+}
+
+static void nhmex_rbox_msr_enable_event(struct intel_uncore_box *box, struct perf_event *event)
+{
+	struct hw_perf_event *hwc = &event->hw;
+	struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
+	struct hw_perf_event_extra *reg2 = &hwc->branch_reg;
+	int idx, port;
+
+	idx = reg1->idx;
+	port = idx / 6 + box->pmu->pmu_idx * 4;
+
+	switch (idx % 6) {
+	case 0:
+		wrmsrl(NHMEX_R_MSR_PORTN_IPERF_CFG0(port), reg1->config);
+		break;
+	case 1:
+		wrmsrl(NHMEX_R_MSR_PORTN_IPERF_CFG1(port), reg1->config);
+		break;
+	case 2:
+	case 3:
+		wrmsrl(NHMEX_R_MSR_PORTN_QLX_CFG(port),
+			uncore_shared_reg_config(box, 2 + (idx / 6) * 5));
+		break;
+	case 4:
+		wrmsrl(NHMEX_R_MSR_PORTN_XBR_SET1_MM_CFG(port),
+			hwc->config >> 32);
+		wrmsrl(NHMEX_R_MSR_PORTN_XBR_SET1_MATCH(port), reg1->config);
+		wrmsrl(NHMEX_R_MSR_PORTN_XBR_SET1_MASK(port), reg2->config);
+		break;
+	case 5:
+		wrmsrl(NHMEX_R_MSR_PORTN_XBR_SET2_MM_CFG(port),
+			hwc->config >> 32);
+		wrmsrl(NHMEX_R_MSR_PORTN_XBR_SET2_MATCH(port), reg1->config);
+		wrmsrl(NHMEX_R_MSR_PORTN_XBR_SET2_MASK(port), reg2->config);
+		break;
+	}
+
+	wrmsrl(hwc->config_base, NHMEX_PMON_CTL_EN_BIT0 |
+		(hwc->config & NHMEX_R_PMON_CTL_EV_SEL_MASK));
+}
+
+DEFINE_UNCORE_FORMAT_ATTR(xbr_mm_cfg, xbr_mm_cfg, "config:32-63");
+DEFINE_UNCORE_FORMAT_ATTR(xbr_match, xbr_match, "config1:0-63");
+DEFINE_UNCORE_FORMAT_ATTR(xbr_mask, xbr_mask, "config2:0-63");
+DEFINE_UNCORE_FORMAT_ATTR(qlx_cfg, qlx_cfg, "config1:0-15");
+DEFINE_UNCORE_FORMAT_ATTR(iperf_cfg, iperf_cfg, "config1:0-31");
+
+static struct attribute *nhmex_uncore_rbox_formats_attr[] = {
+	&format_attr_event5.attr,
+	&format_attr_xbr_mm_cfg.attr,
+	&format_attr_xbr_match.attr,
+	&format_attr_xbr_mask.attr,
+	&format_attr_qlx_cfg.attr,
+	&format_attr_iperf_cfg.attr,
+	NULL,
+};
+
+static struct attribute_group nhmex_uncore_rbox_format_group = {
+	.name = "format",
+	.attrs = nhmex_uncore_rbox_formats_attr,
+};
+
+static struct uncore_event_desc nhmex_uncore_rbox_events[] = {
+	INTEL_UNCORE_EVENT_DESC(qpi0_flit_send,		"event=0x0,iperf_cfg=0x80000000"),
+	INTEL_UNCORE_EVENT_DESC(qpi1_filt_send,		"event=0x6,iperf_cfg=0x80000000"),
+	INTEL_UNCORE_EVENT_DESC(qpi0_idle_filt,		"event=0x0,iperf_cfg=0x40000000"),
+	INTEL_UNCORE_EVENT_DESC(qpi1_idle_filt,		"event=0x6,iperf_cfg=0x40000000"),
+	INTEL_UNCORE_EVENT_DESC(qpi0_date_response,	"event=0x0,iperf_cfg=0xc4"),
+	INTEL_UNCORE_EVENT_DESC(qpi1_date_response,	"event=0x6,iperf_cfg=0xc4"),
+	{ /* end: all zeroes */ },
+};
+
+static struct intel_uncore_ops nhmex_uncore_rbox_ops = {
+	NHMEX_UNCORE_OPS_COMMON_INIT(),
+	.enable_event		= nhmex_rbox_msr_enable_event,
+	.hw_config		= nhmex_rbox_hw_config,
+	.get_constraint		= nhmex_rbox_get_constraint,
+	.put_constraint		= nhmex_rbox_put_constraint,
+};
+
+static struct intel_uncore_type nhmex_uncore_rbox = {
+	.name			= "rbox",
+	.num_counters		= 8,
+	.num_boxes		= 2,
+	.perf_ctr_bits		= 48,
+	.event_ctl		= NHMEX_R_MSR_PMON_CTL0,
+	.perf_ctr		= NHMEX_R_MSR_PMON_CNT0,
+	.event_mask		= NHMEX_R_PMON_RAW_EVENT_MASK,
+	.box_ctl		= NHMEX_R_MSR_GLOBAL_CTL,
+	.msr_offset		= NHMEX_R_MSR_OFFSET,
+	.pair_ctr_ctl		= 1,
+	.num_shared_regs	= 20,
+	.event_descs		= nhmex_uncore_rbox_events,
+	.ops			= &nhmex_uncore_rbox_ops,
+	.format_group		= &nhmex_uncore_rbox_format_group
+};
+
+static struct intel_uncore_type *nhmex_msr_uncores[] = {
+	&nhmex_uncore_ubox,
+	&nhmex_uncore_cbox,
+	&nhmex_uncore_bbox,
+	&nhmex_uncore_sbox,
+	&nhmex_uncore_mbox,
+	&nhmex_uncore_rbox,
+	&nhmex_uncore_wbox,
+	NULL,
+};
+
+void nhmex_uncore_cpu_init(void)
+{
+	if (boot_cpu_data.x86_model == 46)
+		uncore_nhmex = true;
+	else
+		nhmex_uncore_mbox.event_descs = wsmex_uncore_mbox_events;
+	if (nhmex_uncore_cbox.num_boxes > boot_cpu_data.x86_max_cores)
+		nhmex_uncore_cbox.num_boxes = boot_cpu_data.x86_max_cores;
+	uncore_msr_uncores = nhmex_msr_uncores;
+}
+/* end of Nehalem-EX uncore support */
--- /dev/null
+++ zfcpdump-kernel-4.4/arch/x86/events/intel/uncore_snb.c
@@ -0,0 +1,697 @@
+/* Nehalem/SandBridge/Haswell uncore support */
+#include "uncore.h"
+
+/* Uncore IMC PCI IDs */
+#define PCI_DEVICE_ID_INTEL_SNB_IMC	0x0100
+#define PCI_DEVICE_ID_INTEL_IVB_IMC	0x0154
+#define PCI_DEVICE_ID_INTEL_IVB_E3_IMC	0x0150
+#define PCI_DEVICE_ID_INTEL_HSW_IMC	0x0c00
+#define PCI_DEVICE_ID_INTEL_HSW_U_IMC	0x0a04
+#define PCI_DEVICE_ID_INTEL_BDW_IMC	0x1604
+
+/* SNB event control */
+#define SNB_UNC_CTL_EV_SEL_MASK			0x000000ff
+#define SNB_UNC_CTL_UMASK_MASK			0x0000ff00
+#define SNB_UNC_CTL_EDGE_DET			(1 << 18)
+#define SNB_UNC_CTL_EN				(1 << 22)
+#define SNB_UNC_CTL_INVERT			(1 << 23)
+#define SNB_UNC_CTL_CMASK_MASK			0x1f000000
+#define NHM_UNC_CTL_CMASK_MASK			0xff000000
+#define NHM_UNC_FIXED_CTR_CTL_EN		(1 << 0)
+
+#define SNB_UNC_RAW_EVENT_MASK			(SNB_UNC_CTL_EV_SEL_MASK | \
+						 SNB_UNC_CTL_UMASK_MASK | \
+						 SNB_UNC_CTL_EDGE_DET | \
+						 SNB_UNC_CTL_INVERT | \
+						 SNB_UNC_CTL_CMASK_MASK)
+
+#define NHM_UNC_RAW_EVENT_MASK			(SNB_UNC_CTL_EV_SEL_MASK | \
+						 SNB_UNC_CTL_UMASK_MASK | \
+						 SNB_UNC_CTL_EDGE_DET | \
+						 SNB_UNC_CTL_INVERT | \
+						 NHM_UNC_CTL_CMASK_MASK)
+
+/* SNB global control register */
+#define SNB_UNC_PERF_GLOBAL_CTL                 0x391
+#define SNB_UNC_FIXED_CTR_CTRL                  0x394
+#define SNB_UNC_FIXED_CTR                       0x395
+
+/* SNB uncore global control */
+#define SNB_UNC_GLOBAL_CTL_CORE_ALL             ((1 << 4) - 1)
+#define SNB_UNC_GLOBAL_CTL_EN                   (1 << 29)
+
+/* SNB Cbo register */
+#define SNB_UNC_CBO_0_PERFEVTSEL0               0x700
+#define SNB_UNC_CBO_0_PER_CTR0                  0x706
+#define SNB_UNC_CBO_MSR_OFFSET                  0x10
+
+/* SNB ARB register */
+#define SNB_UNC_ARB_PER_CTR0			0x3b0
+#define SNB_UNC_ARB_PERFEVTSEL0			0x3b2
+#define SNB_UNC_ARB_MSR_OFFSET			0x10
+
+/* NHM global control register */
+#define NHM_UNC_PERF_GLOBAL_CTL                 0x391
+#define NHM_UNC_FIXED_CTR                       0x394
+#define NHM_UNC_FIXED_CTR_CTRL                  0x395
+
+/* NHM uncore global control */
+#define NHM_UNC_GLOBAL_CTL_EN_PC_ALL            ((1ULL << 8) - 1)
+#define NHM_UNC_GLOBAL_CTL_EN_FC                (1ULL << 32)
+
+/* NHM uncore register */
+#define NHM_UNC_PERFEVTSEL0                     0x3c0
+#define NHM_UNC_UNCORE_PMC0                     0x3b0
+
+DEFINE_UNCORE_FORMAT_ATTR(event, event, "config:0-7");
+DEFINE_UNCORE_FORMAT_ATTR(umask, umask, "config:8-15");
+DEFINE_UNCORE_FORMAT_ATTR(edge, edge, "config:18");
+DEFINE_UNCORE_FORMAT_ATTR(inv, inv, "config:23");
+DEFINE_UNCORE_FORMAT_ATTR(cmask5, cmask, "config:24-28");
+DEFINE_UNCORE_FORMAT_ATTR(cmask8, cmask, "config:24-31");
+
+/* Sandy Bridge uncore support */
+static void snb_uncore_msr_enable_event(struct intel_uncore_box *box, struct perf_event *event)
+{
+	struct hw_perf_event *hwc = &event->hw;
+
+	if (hwc->idx < UNCORE_PMC_IDX_FIXED)
+		wrmsrl(hwc->config_base, hwc->config | SNB_UNC_CTL_EN);
+	else
+		wrmsrl(hwc->config_base, SNB_UNC_CTL_EN);
+}
+
+static void snb_uncore_msr_disable_event(struct intel_uncore_box *box, struct perf_event *event)
+{
+	wrmsrl(event->hw.config_base, 0);
+}
+
+static void snb_uncore_msr_init_box(struct intel_uncore_box *box)
+{
+	if (box->pmu->pmu_idx == 0) {
+		wrmsrl(SNB_UNC_PERF_GLOBAL_CTL,
+			SNB_UNC_GLOBAL_CTL_EN | SNB_UNC_GLOBAL_CTL_CORE_ALL);
+	}
+}
+
+static struct uncore_event_desc snb_uncore_events[] = {
+	INTEL_UNCORE_EVENT_DESC(clockticks, "event=0xff,umask=0x00"),
+	{ /* end: all zeroes */ },
+};
+
+static struct attribute *snb_uncore_formats_attr[] = {
+	&format_attr_event.attr,
+	&format_attr_umask.attr,
+	&format_attr_edge.attr,
+	&format_attr_inv.attr,
+	&format_attr_cmask5.attr,
+	NULL,
+};
+
+static struct attribute_group snb_uncore_format_group = {
+	.name		= "format",
+	.attrs		= snb_uncore_formats_attr,
+};
+
+static struct intel_uncore_ops snb_uncore_msr_ops = {
+	.init_box	= snb_uncore_msr_init_box,
+	.disable_event	= snb_uncore_msr_disable_event,
+	.enable_event	= snb_uncore_msr_enable_event,
+	.read_counter	= uncore_msr_read_counter,
+};
+
+static struct event_constraint snb_uncore_arb_constraints[] = {
+	UNCORE_EVENT_CONSTRAINT(0x80, 0x1),
+	UNCORE_EVENT_CONSTRAINT(0x83, 0x1),
+	EVENT_CONSTRAINT_END
+};
+
+static struct intel_uncore_type snb_uncore_cbox = {
+	.name		= "cbox",
+	.num_counters   = 2,
+	.num_boxes	= 4,
+	.perf_ctr_bits	= 44,
+	.fixed_ctr_bits	= 48,
+	.perf_ctr	= SNB_UNC_CBO_0_PER_CTR0,
+	.event_ctl	= SNB_UNC_CBO_0_PERFEVTSEL0,
+	.fixed_ctr	= SNB_UNC_FIXED_CTR,
+	.fixed_ctl	= SNB_UNC_FIXED_CTR_CTRL,
+	.single_fixed	= 1,
+	.event_mask	= SNB_UNC_RAW_EVENT_MASK,
+	.msr_offset	= SNB_UNC_CBO_MSR_OFFSET,
+	.ops		= &snb_uncore_msr_ops,
+	.format_group	= &snb_uncore_format_group,
+	.event_descs	= snb_uncore_events,
+};
+
+static struct intel_uncore_type snb_uncore_arb = {
+	.name		= "arb",
+	.num_counters   = 2,
+	.num_boxes	= 1,
+	.perf_ctr_bits	= 44,
+	.perf_ctr	= SNB_UNC_ARB_PER_CTR0,
+	.event_ctl	= SNB_UNC_ARB_PERFEVTSEL0,
+	.event_mask	= SNB_UNC_RAW_EVENT_MASK,
+	.msr_offset	= SNB_UNC_ARB_MSR_OFFSET,
+	.constraints	= snb_uncore_arb_constraints,
+	.ops		= &snb_uncore_msr_ops,
+	.format_group	= &snb_uncore_format_group,
+};
+
+static struct intel_uncore_type *snb_msr_uncores[] = {
+	&snb_uncore_cbox,
+	&snb_uncore_arb,
+	NULL,
+};
+
+void snb_uncore_cpu_init(void)
+{
+	uncore_msr_uncores = snb_msr_uncores;
+	if (snb_uncore_cbox.num_boxes > boot_cpu_data.x86_max_cores)
+		snb_uncore_cbox.num_boxes = boot_cpu_data.x86_max_cores;
+}
+
+enum {
+	SNB_PCI_UNCORE_IMC,
+};
+
+static struct uncore_event_desc snb_uncore_imc_events[] = {
+	INTEL_UNCORE_EVENT_DESC(data_reads,  "event=0x01"),
+	INTEL_UNCORE_EVENT_DESC(data_reads.scale, "6.103515625e-5"),
+	INTEL_UNCORE_EVENT_DESC(data_reads.unit, "MiB"),
+
+	INTEL_UNCORE_EVENT_DESC(data_writes, "event=0x02"),
+	INTEL_UNCORE_EVENT_DESC(data_writes.scale, "6.103515625e-5"),
+	INTEL_UNCORE_EVENT_DESC(data_writes.unit, "MiB"),
+
+	{ /* end: all zeroes */ },
+};
+
+#define SNB_UNCORE_PCI_IMC_EVENT_MASK		0xff
+#define SNB_UNCORE_PCI_IMC_BAR_OFFSET		0x48
+
+/* page size multiple covering all config regs */
+#define SNB_UNCORE_PCI_IMC_MAP_SIZE		0x6000
+
+#define SNB_UNCORE_PCI_IMC_DATA_READS		0x1
+#define SNB_UNCORE_PCI_IMC_DATA_READS_BASE	0x5050
+#define SNB_UNCORE_PCI_IMC_DATA_WRITES		0x2
+#define SNB_UNCORE_PCI_IMC_DATA_WRITES_BASE	0x5054
+#define SNB_UNCORE_PCI_IMC_CTR_BASE		SNB_UNCORE_PCI_IMC_DATA_READS_BASE
+
+static struct attribute *snb_uncore_imc_formats_attr[] = {
+	&format_attr_event.attr,
+	NULL,
+};
+
+static struct attribute_group snb_uncore_imc_format_group = {
+	.name = "format",
+	.attrs = snb_uncore_imc_formats_attr,
+};
+
+static void snb_uncore_imc_init_box(struct intel_uncore_box *box)
+{
+	struct pci_dev *pdev = box->pci_dev;
+	int where = SNB_UNCORE_PCI_IMC_BAR_OFFSET;
+	resource_size_t addr;
+	u32 pci_dword;
+
+	pci_read_config_dword(pdev, where, &pci_dword);
+	addr = pci_dword;
+
+#ifdef CONFIG_PHYS_ADDR_T_64BIT
+	pci_read_config_dword(pdev, where + 4, &pci_dword);
+	addr |= ((resource_size_t)pci_dword << 32);
+#endif
+
+	addr &= ~(PAGE_SIZE - 1);
+
+	box->io_addr = ioremap(addr, SNB_UNCORE_PCI_IMC_MAP_SIZE);
+	box->hrtimer_duration = UNCORE_SNB_IMC_HRTIMER_INTERVAL;
+}
+
+static void snb_uncore_imc_enable_box(struct intel_uncore_box *box)
+{}
+
+static void snb_uncore_imc_disable_box(struct intel_uncore_box *box)
+{}
+
+static void snb_uncore_imc_enable_event(struct intel_uncore_box *box, struct perf_event *event)
+{}
+
+static void snb_uncore_imc_disable_event(struct intel_uncore_box *box, struct perf_event *event)
+{}
+
+static u64 snb_uncore_imc_read_counter(struct intel_uncore_box *box, struct perf_event *event)
+{
+	struct hw_perf_event *hwc = &event->hw;
+
+	return (u64)*(unsigned int *)(box->io_addr + hwc->event_base);
+}
+
+/*
+ * custom event_init() function because we define our own fixed, free
+ * running counters, so we do not want to conflict with generic uncore
+ * logic. Also simplifies processing
+ */
+static int snb_uncore_imc_event_init(struct perf_event *event)
+{
+	struct intel_uncore_pmu *pmu;
+	struct intel_uncore_box *box;
+	struct hw_perf_event *hwc = &event->hw;
+	u64 cfg = event->attr.config & SNB_UNCORE_PCI_IMC_EVENT_MASK;
+	int idx, base;
+
+	if (event->attr.type != event->pmu->type)
+		return -ENOENT;
+
+	pmu = uncore_event_to_pmu(event);
+	/* no device found for this pmu */
+	if (pmu->func_id < 0)
+		return -ENOENT;
+
+	/* Sampling not supported yet */
+	if (hwc->sample_period)
+		return -EINVAL;
+
+	/* unsupported modes and filters */
+	if (event->attr.exclude_user   ||
+	    event->attr.exclude_kernel ||
+	    event->attr.exclude_hv     ||
+	    event->attr.exclude_idle   ||
+	    event->attr.exclude_host   ||
+	    event->attr.exclude_guest  ||
+	    event->attr.sample_period) /* no sampling */
+		return -EINVAL;
+
+	/*
+	 * Place all uncore events for a particular physical package
+	 * onto a single cpu
+	 */
+	if (event->cpu < 0)
+		return -EINVAL;
+
+	/* check only supported bits are set */
+	if (event->attr.config & ~SNB_UNCORE_PCI_IMC_EVENT_MASK)
+		return -EINVAL;
+
+	box = uncore_pmu_to_box(pmu, event->cpu);
+	if (!box || box->cpu < 0)
+		return -EINVAL;
+
+	event->cpu = box->cpu;
+
+	event->hw.idx = -1;
+	event->hw.last_tag = ~0ULL;
+	event->hw.extra_reg.idx = EXTRA_REG_NONE;
+	event->hw.branch_reg.idx = EXTRA_REG_NONE;
+	/*
+	 * check event is known (whitelist, determines counter)
+	 */
+	switch (cfg) {
+	case SNB_UNCORE_PCI_IMC_DATA_READS:
+		base = SNB_UNCORE_PCI_IMC_DATA_READS_BASE;
+		idx = UNCORE_PMC_IDX_FIXED;
+		break;
+	case SNB_UNCORE_PCI_IMC_DATA_WRITES:
+		base = SNB_UNCORE_PCI_IMC_DATA_WRITES_BASE;
+		idx = UNCORE_PMC_IDX_FIXED + 1;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	/* must be done before validate_group */
+	event->hw.event_base = base;
+	event->hw.config = cfg;
+	event->hw.idx = idx;
+
+	/* no group validation needed, we have free running counters */
+
+	return 0;
+}
+
+static int snb_uncore_imc_hw_config(struct intel_uncore_box *box, struct perf_event *event)
+{
+	return 0;
+}
+
+static void snb_uncore_imc_event_start(struct perf_event *event, int flags)
+{
+	struct intel_uncore_box *box = uncore_event_to_box(event);
+	u64 count;
+
+	if (WARN_ON_ONCE(!(event->hw.state & PERF_HES_STOPPED)))
+		return;
+
+	event->hw.state = 0;
+	box->n_active++;
+
+	list_add_tail(&event->active_entry, &box->active_list);
+
+	count = snb_uncore_imc_read_counter(box, event);
+	local64_set(&event->hw.prev_count, count);
+
+	if (box->n_active == 1)
+		uncore_pmu_start_hrtimer(box);
+}
+
+static void snb_uncore_imc_event_stop(struct perf_event *event, int flags)
+{
+	struct intel_uncore_box *box = uncore_event_to_box(event);
+	struct hw_perf_event *hwc = &event->hw;
+
+	if (!(hwc->state & PERF_HES_STOPPED)) {
+		box->n_active--;
+
+		WARN_ON_ONCE(hwc->state & PERF_HES_STOPPED);
+		hwc->state |= PERF_HES_STOPPED;
+
+		list_del(&event->active_entry);
+
+		if (box->n_active == 0)
+			uncore_pmu_cancel_hrtimer(box);
+	}
+
+	if ((flags & PERF_EF_UPDATE) && !(hwc->state & PERF_HES_UPTODATE)) {
+		/*
+		 * Drain the remaining delta count out of a event
+		 * that we are disabling:
+		 */
+		uncore_perf_event_update(box, event);
+		hwc->state |= PERF_HES_UPTODATE;
+	}
+}
+
+static int snb_uncore_imc_event_add(struct perf_event *event, int flags)
+{
+	struct intel_uncore_box *box = uncore_event_to_box(event);
+	struct hw_perf_event *hwc = &event->hw;
+
+	if (!box)
+		return -ENODEV;
+
+	hwc->state = PERF_HES_UPTODATE | PERF_HES_STOPPED;
+	if (!(flags & PERF_EF_START))
+		hwc->state |= PERF_HES_ARCH;
+
+	snb_uncore_imc_event_start(event, 0);
+
+	box->n_events++;
+
+	return 0;
+}
+
+static void snb_uncore_imc_event_del(struct perf_event *event, int flags)
+{
+	struct intel_uncore_box *box = uncore_event_to_box(event);
+	int i;
+
+	snb_uncore_imc_event_stop(event, PERF_EF_UPDATE);
+
+	for (i = 0; i < box->n_events; i++) {
+		if (event == box->event_list[i]) {
+			--box->n_events;
+			break;
+		}
+	}
+}
+
+int snb_pci2phy_map_init(int devid)
+{
+	struct pci_dev *dev = NULL;
+	struct pci2phy_map *map;
+	int bus, segment;
+
+	dev = pci_get_device(PCI_VENDOR_ID_INTEL, devid, dev);
+	if (!dev)
+		return -ENOTTY;
+
+	bus = dev->bus->number;
+	segment = pci_domain_nr(dev->bus);
+
+	raw_spin_lock(&pci2phy_map_lock);
+	map = __find_pci2phy_map(segment);
+	if (!map) {
+		raw_spin_unlock(&pci2phy_map_lock);
+		pci_dev_put(dev);
+		return -ENOMEM;
+	}
+	map->pbus_to_physid[bus] = 0;
+	raw_spin_unlock(&pci2phy_map_lock);
+
+	pci_dev_put(dev);
+
+	return 0;
+}
+
+static struct pmu snb_uncore_imc_pmu = {
+	.task_ctx_nr	= perf_invalid_context,
+	.event_init	= snb_uncore_imc_event_init,
+	.add		= snb_uncore_imc_event_add,
+	.del		= snb_uncore_imc_event_del,
+	.start		= snb_uncore_imc_event_start,
+	.stop		= snb_uncore_imc_event_stop,
+	.read		= uncore_pmu_event_read,
+};
+
+static struct intel_uncore_ops snb_uncore_imc_ops = {
+	.init_box	= snb_uncore_imc_init_box,
+	.enable_box	= snb_uncore_imc_enable_box,
+	.disable_box	= snb_uncore_imc_disable_box,
+	.disable_event	= snb_uncore_imc_disable_event,
+	.enable_event	= snb_uncore_imc_enable_event,
+	.hw_config	= snb_uncore_imc_hw_config,
+	.read_counter	= snb_uncore_imc_read_counter,
+};
+
+static struct intel_uncore_type snb_uncore_imc = {
+	.name		= "imc",
+	.num_counters   = 2,
+	.num_boxes	= 1,
+	.fixed_ctr_bits	= 32,
+	.fixed_ctr	= SNB_UNCORE_PCI_IMC_CTR_BASE,
+	.event_descs	= snb_uncore_imc_events,
+	.format_group	= &snb_uncore_imc_format_group,
+	.perf_ctr	= SNB_UNCORE_PCI_IMC_DATA_READS_BASE,
+	.event_mask	= SNB_UNCORE_PCI_IMC_EVENT_MASK,
+	.ops		= &snb_uncore_imc_ops,
+	.pmu		= &snb_uncore_imc_pmu,
+};
+
+static struct intel_uncore_type *snb_pci_uncores[] = {
+	[SNB_PCI_UNCORE_IMC]	= &snb_uncore_imc,
+	NULL,
+};
+
+static const struct pci_device_id snb_uncore_pci_ids[] = {
+	{ /* IMC */
+		PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_SNB_IMC),
+		.driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0),
+	},
+	{ /* end: all zeroes */ },
+};
+
+static const struct pci_device_id ivb_uncore_pci_ids[] = {
+	{ /* IMC */
+		PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IVB_IMC),
+		.driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0),
+	},
+	{ /* IMC */
+		PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IVB_E3_IMC),
+		.driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0),
+	},
+	{ /* end: all zeroes */ },
+};
+
+static const struct pci_device_id hsw_uncore_pci_ids[] = {
+	{ /* IMC */
+		PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_HSW_IMC),
+		.driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0),
+	},
+	{ /* IMC */
+		PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_HSW_U_IMC),
+		.driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0),
+	},
+	{ /* end: all zeroes */ },
+};
+
+static const struct pci_device_id bdw_uncore_pci_ids[] = {
+	{ /* IMC */
+		PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BDW_IMC),
+		.driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0),
+	},
+	{ /* end: all zeroes */ },
+};
+
+static struct pci_driver snb_uncore_pci_driver = {
+	.name		= "snb_uncore",
+	.id_table	= snb_uncore_pci_ids,
+};
+
+static struct pci_driver ivb_uncore_pci_driver = {
+	.name		= "ivb_uncore",
+	.id_table	= ivb_uncore_pci_ids,
+};
+
+static struct pci_driver hsw_uncore_pci_driver = {
+	.name		= "hsw_uncore",
+	.id_table	= hsw_uncore_pci_ids,
+};
+
+static struct pci_driver bdw_uncore_pci_driver = {
+	.name		= "bdw_uncore",
+	.id_table	= bdw_uncore_pci_ids,
+};
+
+struct imc_uncore_pci_dev {
+	__u32 pci_id;
+	struct pci_driver *driver;
+};
+#define IMC_DEV(a, d) \
+	{ .pci_id = PCI_DEVICE_ID_INTEL_##a, .driver = (d) }
+
+static const struct imc_uncore_pci_dev desktop_imc_pci_ids[] = {
+	IMC_DEV(SNB_IMC, &snb_uncore_pci_driver),
+	IMC_DEV(IVB_IMC, &ivb_uncore_pci_driver),    /* 3rd Gen Core processor */
+	IMC_DEV(IVB_E3_IMC, &ivb_uncore_pci_driver), /* Xeon E3-1200 v2/3rd Gen Core processor */
+	IMC_DEV(HSW_IMC, &hsw_uncore_pci_driver),    /* 4th Gen Core Processor */
+	IMC_DEV(HSW_U_IMC, &hsw_uncore_pci_driver),  /* 4th Gen Core ULT Mobile Processor */
+	IMC_DEV(BDW_IMC, &bdw_uncore_pci_driver),    /* 5th Gen Core U */
+	{  /* end marker */ }
+};
+
+
+#define for_each_imc_pci_id(x, t) \
+	for (x = (t); (x)->pci_id; x++)
+
+static struct pci_driver *imc_uncore_find_dev(void)
+{
+	const struct imc_uncore_pci_dev *p;
+	int ret;
+
+	for_each_imc_pci_id(p, desktop_imc_pci_ids) {
+		ret = snb_pci2phy_map_init(p->pci_id);
+		if (ret == 0)
+			return p->driver;
+	}
+	return NULL;
+}
+
+static int imc_uncore_pci_init(void)
+{
+	struct pci_driver *imc_drv = imc_uncore_find_dev();
+
+	if (!imc_drv)
+		return -ENODEV;
+
+	uncore_pci_uncores = snb_pci_uncores;
+	uncore_pci_driver = imc_drv;
+
+	return 0;
+}
+
+int snb_uncore_pci_init(void)
+{
+	return imc_uncore_pci_init();
+}
+
+int ivb_uncore_pci_init(void)
+{
+	return imc_uncore_pci_init();
+}
+int hsw_uncore_pci_init(void)
+{
+	return imc_uncore_pci_init();
+}
+
+int bdw_uncore_pci_init(void)
+{
+	return imc_uncore_pci_init();
+}
+
+/* end of Sandy Bridge uncore support */
+
+/* Nehalem uncore support */
+static void nhm_uncore_msr_disable_box(struct intel_uncore_box *box)
+{
+	wrmsrl(NHM_UNC_PERF_GLOBAL_CTL, 0);
+}
+
+static void nhm_uncore_msr_enable_box(struct intel_uncore_box *box)
+{
+	wrmsrl(NHM_UNC_PERF_GLOBAL_CTL, NHM_UNC_GLOBAL_CTL_EN_PC_ALL | NHM_UNC_GLOBAL_CTL_EN_FC);
+}
+
+static void nhm_uncore_msr_enable_event(struct intel_uncore_box *box, struct perf_event *event)
+{
+	struct hw_perf_event *hwc = &event->hw;
+
+	if (hwc->idx < UNCORE_PMC_IDX_FIXED)
+		wrmsrl(hwc->config_base, hwc->config | SNB_UNC_CTL_EN);
+	else
+		wrmsrl(hwc->config_base, NHM_UNC_FIXED_CTR_CTL_EN);
+}
+
+static struct attribute *nhm_uncore_formats_attr[] = {
+	&format_attr_event.attr,
+	&format_attr_umask.attr,
+	&format_attr_edge.attr,
+	&format_attr_inv.attr,
+	&format_attr_cmask8.attr,
+	NULL,
+};
+
+static struct attribute_group nhm_uncore_format_group = {
+	.name = "format",
+	.attrs = nhm_uncore_formats_attr,
+};
+
+static struct uncore_event_desc nhm_uncore_events[] = {
+	INTEL_UNCORE_EVENT_DESC(clockticks,                "event=0xff,umask=0x00"),
+	INTEL_UNCORE_EVENT_DESC(qmc_writes_full_any,       "event=0x2f,umask=0x0f"),
+	INTEL_UNCORE_EVENT_DESC(qmc_normal_reads_any,      "event=0x2c,umask=0x0f"),
+	INTEL_UNCORE_EVENT_DESC(qhl_request_ioh_reads,     "event=0x20,umask=0x01"),
+	INTEL_UNCORE_EVENT_DESC(qhl_request_ioh_writes,    "event=0x20,umask=0x02"),
+	INTEL_UNCORE_EVENT_DESC(qhl_request_remote_reads,  "event=0x20,umask=0x04"),
+	INTEL_UNCORE_EVENT_DESC(qhl_request_remote_writes, "event=0x20,umask=0x08"),
+	INTEL_UNCORE_EVENT_DESC(qhl_request_local_reads,   "event=0x20,umask=0x10"),
+	INTEL_UNCORE_EVENT_DESC(qhl_request_local_writes,  "event=0x20,umask=0x20"),
+	{ /* end: all zeroes */ },
+};
+
+static struct intel_uncore_ops nhm_uncore_msr_ops = {
+	.disable_box	= nhm_uncore_msr_disable_box,
+	.enable_box	= nhm_uncore_msr_enable_box,
+	.disable_event	= snb_uncore_msr_disable_event,
+	.enable_event	= nhm_uncore_msr_enable_event,
+	.read_counter	= uncore_msr_read_counter,
+};
+
+static struct intel_uncore_type nhm_uncore = {
+	.name		= "",
+	.num_counters   = 8,
+	.num_boxes	= 1,
+	.perf_ctr_bits	= 48,
+	.fixed_ctr_bits	= 48,
+	.event_ctl	= NHM_UNC_PERFEVTSEL0,
+	.perf_ctr	= NHM_UNC_UNCORE_PMC0,
+	.fixed_ctr	= NHM_UNC_FIXED_CTR,
+	.fixed_ctl	= NHM_UNC_FIXED_CTR_CTRL,
+	.event_mask	= NHM_UNC_RAW_EVENT_MASK,
+	.event_descs	= nhm_uncore_events,
+	.ops		= &nhm_uncore_msr_ops,
+	.format_group	= &nhm_uncore_format_group,
+};
+
+static struct intel_uncore_type *nhm_msr_uncores[] = {
+	&nhm_uncore,
+	NULL,
+};
+
+void nhm_uncore_cpu_init(void)
+{
+	uncore_msr_uncores = nhm_msr_uncores;
+}
+
+/* end of Nehalem uncore support */
--- /dev/null
+++ zfcpdump-kernel-4.4/arch/x86/events/intel/uncore_snbep.c
@@ -0,0 +1,3125 @@
+/* SandyBridge-EP/IvyTown uncore support */
+#include "uncore.h"
+
+/* SNB-EP Box level control */
+#define SNBEP_PMON_BOX_CTL_RST_CTRL	(1 << 0)
+#define SNBEP_PMON_BOX_CTL_RST_CTRS	(1 << 1)
+#define SNBEP_PMON_BOX_CTL_FRZ		(1 << 8)
+#define SNBEP_PMON_BOX_CTL_FRZ_EN	(1 << 16)
+#define SNBEP_PMON_BOX_CTL_INT		(SNBEP_PMON_BOX_CTL_RST_CTRL | \
+					 SNBEP_PMON_BOX_CTL_RST_CTRS | \
+					 SNBEP_PMON_BOX_CTL_FRZ_EN)
+/* SNB-EP event control */
+#define SNBEP_PMON_CTL_EV_SEL_MASK	0x000000ff
+#define SNBEP_PMON_CTL_UMASK_MASK	0x0000ff00
+#define SNBEP_PMON_CTL_RST		(1 << 17)
+#define SNBEP_PMON_CTL_EDGE_DET		(1 << 18)
+#define SNBEP_PMON_CTL_EV_SEL_EXT	(1 << 21)
+#define SNBEP_PMON_CTL_EN		(1 << 22)
+#define SNBEP_PMON_CTL_INVERT		(1 << 23)
+#define SNBEP_PMON_CTL_TRESH_MASK	0xff000000
+#define SNBEP_PMON_RAW_EVENT_MASK	(SNBEP_PMON_CTL_EV_SEL_MASK | \
+					 SNBEP_PMON_CTL_UMASK_MASK | \
+					 SNBEP_PMON_CTL_EDGE_DET | \
+					 SNBEP_PMON_CTL_INVERT | \
+					 SNBEP_PMON_CTL_TRESH_MASK)
+
+/* SNB-EP Ubox event control */
+#define SNBEP_U_MSR_PMON_CTL_TRESH_MASK		0x1f000000
+#define SNBEP_U_MSR_PMON_RAW_EVENT_MASK		\
+				(SNBEP_PMON_CTL_EV_SEL_MASK | \
+				 SNBEP_PMON_CTL_UMASK_MASK | \
+				 SNBEP_PMON_CTL_EDGE_DET | \
+				 SNBEP_PMON_CTL_INVERT | \
+				 SNBEP_U_MSR_PMON_CTL_TRESH_MASK)
+
+#define SNBEP_CBO_PMON_CTL_TID_EN		(1 << 19)
+#define SNBEP_CBO_MSR_PMON_RAW_EVENT_MASK	(SNBEP_PMON_RAW_EVENT_MASK | \
+						 SNBEP_CBO_PMON_CTL_TID_EN)
+
+/* SNB-EP PCU event control */
+#define SNBEP_PCU_MSR_PMON_CTL_OCC_SEL_MASK	0x0000c000
+#define SNBEP_PCU_MSR_PMON_CTL_TRESH_MASK	0x1f000000
+#define SNBEP_PCU_MSR_PMON_CTL_OCC_INVERT	(1 << 30)
+#define SNBEP_PCU_MSR_PMON_CTL_OCC_EDGE_DET	(1 << 31)
+#define SNBEP_PCU_MSR_PMON_RAW_EVENT_MASK	\
+				(SNBEP_PMON_CTL_EV_SEL_MASK | \
+				 SNBEP_PCU_MSR_PMON_CTL_OCC_SEL_MASK | \
+				 SNBEP_PMON_CTL_EDGE_DET | \
+				 SNBEP_PMON_CTL_EV_SEL_EXT | \
+				 SNBEP_PMON_CTL_INVERT | \
+				 SNBEP_PCU_MSR_PMON_CTL_TRESH_MASK | \
+				 SNBEP_PCU_MSR_PMON_CTL_OCC_INVERT | \
+				 SNBEP_PCU_MSR_PMON_CTL_OCC_EDGE_DET)
+
+#define SNBEP_QPI_PCI_PMON_RAW_EVENT_MASK	\
+				(SNBEP_PMON_RAW_EVENT_MASK | \
+				 SNBEP_PMON_CTL_EV_SEL_EXT)
+
+/* SNB-EP pci control register */
+#define SNBEP_PCI_PMON_BOX_CTL			0xf4
+#define SNBEP_PCI_PMON_CTL0			0xd8
+/* SNB-EP pci counter register */
+#define SNBEP_PCI_PMON_CTR0			0xa0
+
+/* SNB-EP home agent register */
+#define SNBEP_HA_PCI_PMON_BOX_ADDRMATCH0	0x40
+#define SNBEP_HA_PCI_PMON_BOX_ADDRMATCH1	0x44
+#define SNBEP_HA_PCI_PMON_BOX_OPCODEMATCH	0x48
+/* SNB-EP memory controller register */
+#define SNBEP_MC_CHy_PCI_PMON_FIXED_CTL		0xf0
+#define SNBEP_MC_CHy_PCI_PMON_FIXED_CTR		0xd0
+/* SNB-EP QPI register */
+#define SNBEP_Q_Py_PCI_PMON_PKT_MATCH0		0x228
+#define SNBEP_Q_Py_PCI_PMON_PKT_MATCH1		0x22c
+#define SNBEP_Q_Py_PCI_PMON_PKT_MASK0		0x238
+#define SNBEP_Q_Py_PCI_PMON_PKT_MASK1		0x23c
+
+/* SNB-EP Ubox register */
+#define SNBEP_U_MSR_PMON_CTR0			0xc16
+#define SNBEP_U_MSR_PMON_CTL0			0xc10
+
+#define SNBEP_U_MSR_PMON_UCLK_FIXED_CTL		0xc08
+#define SNBEP_U_MSR_PMON_UCLK_FIXED_CTR		0xc09
+
+/* SNB-EP Cbo register */
+#define SNBEP_C0_MSR_PMON_CTR0			0xd16
+#define SNBEP_C0_MSR_PMON_CTL0			0xd10
+#define SNBEP_C0_MSR_PMON_BOX_CTL		0xd04
+#define SNBEP_C0_MSR_PMON_BOX_FILTER		0xd14
+#define SNBEP_CBO_MSR_OFFSET			0x20
+
+#define SNBEP_CB0_MSR_PMON_BOX_FILTER_TID	0x1f
+#define SNBEP_CB0_MSR_PMON_BOX_FILTER_NID	0x3fc00
+#define SNBEP_CB0_MSR_PMON_BOX_FILTER_STATE	0x7c0000
+#define SNBEP_CB0_MSR_PMON_BOX_FILTER_OPC	0xff800000
+
+#define SNBEP_CBO_EVENT_EXTRA_REG(e, m, i) {	\
+	.event = (e),				\
+	.msr = SNBEP_C0_MSR_PMON_BOX_FILTER,	\
+	.config_mask = (m),			\
+	.idx = (i)				\
+}
+
+/* SNB-EP PCU register */
+#define SNBEP_PCU_MSR_PMON_CTR0			0xc36
+#define SNBEP_PCU_MSR_PMON_CTL0			0xc30
+#define SNBEP_PCU_MSR_PMON_BOX_CTL		0xc24
+#define SNBEP_PCU_MSR_PMON_BOX_FILTER		0xc34
+#define SNBEP_PCU_MSR_PMON_BOX_FILTER_MASK	0xffffffff
+#define SNBEP_PCU_MSR_CORE_C3_CTR		0x3fc
+#define SNBEP_PCU_MSR_CORE_C6_CTR		0x3fd
+
+/* IVBEP event control */
+#define IVBEP_PMON_BOX_CTL_INT		(SNBEP_PMON_BOX_CTL_RST_CTRL | \
+					 SNBEP_PMON_BOX_CTL_RST_CTRS)
+#define IVBEP_PMON_RAW_EVENT_MASK		(SNBEP_PMON_CTL_EV_SEL_MASK | \
+					 SNBEP_PMON_CTL_UMASK_MASK | \
+					 SNBEP_PMON_CTL_EDGE_DET | \
+					 SNBEP_PMON_CTL_TRESH_MASK)
+/* IVBEP Ubox */
+#define IVBEP_U_MSR_PMON_GLOBAL_CTL		0xc00
+#define IVBEP_U_PMON_GLOBAL_FRZ_ALL		(1 << 31)
+#define IVBEP_U_PMON_GLOBAL_UNFRZ_ALL		(1 << 29)
+
+#define IVBEP_U_MSR_PMON_RAW_EVENT_MASK	\
+				(SNBEP_PMON_CTL_EV_SEL_MASK | \
+				 SNBEP_PMON_CTL_UMASK_MASK | \
+				 SNBEP_PMON_CTL_EDGE_DET | \
+				 SNBEP_U_MSR_PMON_CTL_TRESH_MASK)
+/* IVBEP Cbo */
+#define IVBEP_CBO_MSR_PMON_RAW_EVENT_MASK		(IVBEP_PMON_RAW_EVENT_MASK | \
+						 SNBEP_CBO_PMON_CTL_TID_EN)
+
+#define IVBEP_CB0_MSR_PMON_BOX_FILTER_TID		(0x1fULL << 0)
+#define IVBEP_CB0_MSR_PMON_BOX_FILTER_LINK	(0xfULL << 5)
+#define IVBEP_CB0_MSR_PMON_BOX_FILTER_STATE	(0x3fULL << 17)
+#define IVBEP_CB0_MSR_PMON_BOX_FILTER_NID		(0xffffULL << 32)
+#define IVBEP_CB0_MSR_PMON_BOX_FILTER_OPC		(0x1ffULL << 52)
+#define IVBEP_CB0_MSR_PMON_BOX_FILTER_C6		(0x1ULL << 61)
+#define IVBEP_CB0_MSR_PMON_BOX_FILTER_NC		(0x1ULL << 62)
+#define IVBEP_CB0_MSR_PMON_BOX_FILTER_ISOC	(0x1ULL << 63)
+
+/* IVBEP home agent */
+#define IVBEP_HA_PCI_PMON_CTL_Q_OCC_RST		(1 << 16)
+#define IVBEP_HA_PCI_PMON_RAW_EVENT_MASK		\
+				(IVBEP_PMON_RAW_EVENT_MASK | \
+				 IVBEP_HA_PCI_PMON_CTL_Q_OCC_RST)
+/* IVBEP PCU */
+#define IVBEP_PCU_MSR_PMON_RAW_EVENT_MASK	\
+				(SNBEP_PMON_CTL_EV_SEL_MASK | \
+				 SNBEP_PMON_CTL_EV_SEL_EXT | \
+				 SNBEP_PCU_MSR_PMON_CTL_OCC_SEL_MASK | \
+				 SNBEP_PMON_CTL_EDGE_DET | \
+				 SNBEP_PCU_MSR_PMON_CTL_TRESH_MASK | \
+				 SNBEP_PCU_MSR_PMON_CTL_OCC_INVERT | \
+				 SNBEP_PCU_MSR_PMON_CTL_OCC_EDGE_DET)
+/* IVBEP QPI */
+#define IVBEP_QPI_PCI_PMON_RAW_EVENT_MASK	\
+				(IVBEP_PMON_RAW_EVENT_MASK | \
+				 SNBEP_PMON_CTL_EV_SEL_EXT)
+
+#define __BITS_VALUE(x, i, n)  ((typeof(x))(((x) >> ((i) * (n))) & \
+				((1ULL << (n)) - 1)))
+
+/* Haswell-EP Ubox */
+#define HSWEP_U_MSR_PMON_CTR0			0x709
+#define HSWEP_U_MSR_PMON_CTL0			0x705
+#define HSWEP_U_MSR_PMON_FILTER			0x707
+
+#define HSWEP_U_MSR_PMON_UCLK_FIXED_CTL		0x703
+#define HSWEP_U_MSR_PMON_UCLK_FIXED_CTR		0x704
+
+#define HSWEP_U_MSR_PMON_BOX_FILTER_TID		(0x1 << 0)
+#define HSWEP_U_MSR_PMON_BOX_FILTER_CID		(0x1fULL << 1)
+#define HSWEP_U_MSR_PMON_BOX_FILTER_MASK \
+					(HSWEP_U_MSR_PMON_BOX_FILTER_TID | \
+					 HSWEP_U_MSR_PMON_BOX_FILTER_CID)
+
+/* Haswell-EP CBo */
+#define HSWEP_C0_MSR_PMON_CTR0			0xe08
+#define HSWEP_C0_MSR_PMON_CTL0			0xe01
+#define HSWEP_C0_MSR_PMON_BOX_CTL			0xe00
+#define HSWEP_C0_MSR_PMON_BOX_FILTER0		0xe05
+#define HSWEP_CBO_MSR_OFFSET			0x10
+
+
+#define HSWEP_CB0_MSR_PMON_BOX_FILTER_TID		(0x3fULL << 0)
+#define HSWEP_CB0_MSR_PMON_BOX_FILTER_LINK	(0xfULL << 6)
+#define HSWEP_CB0_MSR_PMON_BOX_FILTER_STATE	(0x7fULL << 17)
+#define HSWEP_CB0_MSR_PMON_BOX_FILTER_NID		(0xffffULL << 32)
+#define HSWEP_CB0_MSR_PMON_BOX_FILTER_OPC		(0x1ffULL << 52)
+#define HSWEP_CB0_MSR_PMON_BOX_FILTER_C6		(0x1ULL << 61)
+#define HSWEP_CB0_MSR_PMON_BOX_FILTER_NC		(0x1ULL << 62)
+#define HSWEP_CB0_MSR_PMON_BOX_FILTER_ISOC	(0x1ULL << 63)
+
+
+/* Haswell-EP Sbox */
+#define HSWEP_S0_MSR_PMON_CTR0			0x726
+#define HSWEP_S0_MSR_PMON_CTL0			0x721
+#define HSWEP_S0_MSR_PMON_BOX_CTL			0x720
+#define HSWEP_SBOX_MSR_OFFSET			0xa
+#define HSWEP_S_MSR_PMON_RAW_EVENT_MASK		(SNBEP_PMON_RAW_EVENT_MASK | \
+						 SNBEP_CBO_PMON_CTL_TID_EN)
+
+/* Haswell-EP PCU */
+#define HSWEP_PCU_MSR_PMON_CTR0			0x717
+#define HSWEP_PCU_MSR_PMON_CTL0			0x711
+#define HSWEP_PCU_MSR_PMON_BOX_CTL		0x710
+#define HSWEP_PCU_MSR_PMON_BOX_FILTER		0x715
+
+/* KNL Ubox */
+#define KNL_U_MSR_PMON_RAW_EVENT_MASK \
+					(SNBEP_U_MSR_PMON_RAW_EVENT_MASK | \
+						SNBEP_CBO_PMON_CTL_TID_EN)
+/* KNL CHA */
+#define KNL_CHA_MSR_OFFSET			0xc
+#define KNL_CHA_MSR_PMON_CTL_QOR		(1 << 16)
+#define KNL_CHA_MSR_PMON_RAW_EVENT_MASK \
+					(SNBEP_CBO_MSR_PMON_RAW_EVENT_MASK | \
+					 KNL_CHA_MSR_PMON_CTL_QOR)
+#define KNL_CHA_MSR_PMON_BOX_FILTER_TID		0x1ff
+#define KNL_CHA_MSR_PMON_BOX_FILTER_STATE	(7 << 18)
+#define KNL_CHA_MSR_PMON_BOX_FILTER_OP		(0xfffffe2aULL << 32)
+
+/* KNL EDC/MC UCLK */
+#define KNL_UCLK_MSR_PMON_CTR0_LOW		0x400
+#define KNL_UCLK_MSR_PMON_CTL0			0x420
+#define KNL_UCLK_MSR_PMON_BOX_CTL		0x430
+#define KNL_UCLK_MSR_PMON_UCLK_FIXED_LOW	0x44c
+#define KNL_UCLK_MSR_PMON_UCLK_FIXED_CTL	0x454
+#define KNL_PMON_FIXED_CTL_EN			0x1
+
+/* KNL EDC */
+#define KNL_EDC0_ECLK_MSR_PMON_CTR0_LOW		0xa00
+#define KNL_EDC0_ECLK_MSR_PMON_CTL0		0xa20
+#define KNL_EDC0_ECLK_MSR_PMON_BOX_CTL		0xa30
+#define KNL_EDC0_ECLK_MSR_PMON_ECLK_FIXED_LOW	0xa3c
+#define KNL_EDC0_ECLK_MSR_PMON_ECLK_FIXED_CTL	0xa44
+
+/* KNL MC */
+#define KNL_MC0_CH0_MSR_PMON_CTR0_LOW		0xb00
+#define KNL_MC0_CH0_MSR_PMON_CTL0		0xb20
+#define KNL_MC0_CH0_MSR_PMON_BOX_CTL		0xb30
+#define KNL_MC0_CH0_MSR_PMON_FIXED_LOW		0xb3c
+#define KNL_MC0_CH0_MSR_PMON_FIXED_CTL		0xb44
+
+/* KNL IRP */
+#define KNL_IRP_PCI_PMON_BOX_CTL		0xf0
+#define KNL_IRP_PCI_PMON_RAW_EVENT_MASK		(SNBEP_PMON_RAW_EVENT_MASK | \
+						 KNL_CHA_MSR_PMON_CTL_QOR)
+/* KNL PCU */
+#define KNL_PCU_PMON_CTL_EV_SEL_MASK		0x0000007f
+#define KNL_PCU_PMON_CTL_USE_OCC_CTR		(1 << 7)
+#define KNL_PCU_MSR_PMON_CTL_TRESH_MASK		0x3f000000
+#define KNL_PCU_MSR_PMON_RAW_EVENT_MASK	\
+				(KNL_PCU_PMON_CTL_EV_SEL_MASK | \
+				 KNL_PCU_PMON_CTL_USE_OCC_CTR | \
+				 SNBEP_PCU_MSR_PMON_CTL_OCC_SEL_MASK | \
+				 SNBEP_PMON_CTL_EDGE_DET | \
+				 SNBEP_CBO_PMON_CTL_TID_EN | \
+				 SNBEP_PMON_CTL_EV_SEL_EXT | \
+				 SNBEP_PMON_CTL_INVERT | \
+				 KNL_PCU_MSR_PMON_CTL_TRESH_MASK | \
+				 SNBEP_PCU_MSR_PMON_CTL_OCC_INVERT | \
+				 SNBEP_PCU_MSR_PMON_CTL_OCC_EDGE_DET)
+
+DEFINE_UNCORE_FORMAT_ATTR(event, event, "config:0-7");
+DEFINE_UNCORE_FORMAT_ATTR(event2, event, "config:0-6");
+DEFINE_UNCORE_FORMAT_ATTR(event_ext, event, "config:0-7,21");
+DEFINE_UNCORE_FORMAT_ATTR(use_occ_ctr, use_occ_ctr, "config:7");
+DEFINE_UNCORE_FORMAT_ATTR(umask, umask, "config:8-15");
+DEFINE_UNCORE_FORMAT_ATTR(qor, qor, "config:16");
+DEFINE_UNCORE_FORMAT_ATTR(edge, edge, "config:18");
+DEFINE_UNCORE_FORMAT_ATTR(tid_en, tid_en, "config:19");
+DEFINE_UNCORE_FORMAT_ATTR(inv, inv, "config:23");
+DEFINE_UNCORE_FORMAT_ATTR(thresh8, thresh, "config:24-31");
+DEFINE_UNCORE_FORMAT_ATTR(thresh6, thresh, "config:24-29");
+DEFINE_UNCORE_FORMAT_ATTR(thresh5, thresh, "config:24-28");
+DEFINE_UNCORE_FORMAT_ATTR(occ_sel, occ_sel, "config:14-15");
+DEFINE_UNCORE_FORMAT_ATTR(occ_invert, occ_invert, "config:30");
+DEFINE_UNCORE_FORMAT_ATTR(occ_edge, occ_edge, "config:14-51");
+DEFINE_UNCORE_FORMAT_ATTR(occ_edge_det, occ_edge_det, "config:31");
+DEFINE_UNCORE_FORMAT_ATTR(filter_tid, filter_tid, "config1:0-4");
+DEFINE_UNCORE_FORMAT_ATTR(filter_tid2, filter_tid, "config1:0");
+DEFINE_UNCORE_FORMAT_ATTR(filter_tid3, filter_tid, "config1:0-5");
+DEFINE_UNCORE_FORMAT_ATTR(filter_tid4, filter_tid, "config1:0-8");
+DEFINE_UNCORE_FORMAT_ATTR(filter_cid, filter_cid, "config1:5");
+DEFINE_UNCORE_FORMAT_ATTR(filter_link, filter_link, "config1:5-8");
+DEFINE_UNCORE_FORMAT_ATTR(filter_link2, filter_link, "config1:6-8");
+DEFINE_UNCORE_FORMAT_ATTR(filter_link3, filter_link, "config1:12");
+DEFINE_UNCORE_FORMAT_ATTR(filter_nid, filter_nid, "config1:10-17");
+DEFINE_UNCORE_FORMAT_ATTR(filter_nid2, filter_nid, "config1:32-47");
+DEFINE_UNCORE_FORMAT_ATTR(filter_state, filter_state, "config1:18-22");
+DEFINE_UNCORE_FORMAT_ATTR(filter_state2, filter_state, "config1:17-22");
+DEFINE_UNCORE_FORMAT_ATTR(filter_state3, filter_state, "config1:17-23");
+DEFINE_UNCORE_FORMAT_ATTR(filter_state4, filter_state, "config1:18-20");
+DEFINE_UNCORE_FORMAT_ATTR(filter_local, filter_local, "config1:33");
+DEFINE_UNCORE_FORMAT_ATTR(filter_all_op, filter_all_op, "config1:35");
+DEFINE_UNCORE_FORMAT_ATTR(filter_nnm, filter_nnm, "config1:37");
+DEFINE_UNCORE_FORMAT_ATTR(filter_opc, filter_opc, "config1:23-31");
+DEFINE_UNCORE_FORMAT_ATTR(filter_opc2, filter_opc, "config1:52-60");
+DEFINE_UNCORE_FORMAT_ATTR(filter_opc3, filter_opc, "config1:41-60");
+DEFINE_UNCORE_FORMAT_ATTR(filter_nc, filter_nc, "config1:62");
+DEFINE_UNCORE_FORMAT_ATTR(filter_c6, filter_c6, "config1:61");
+DEFINE_UNCORE_FORMAT_ATTR(filter_isoc, filter_isoc, "config1:63");
+DEFINE_UNCORE_FORMAT_ATTR(filter_band0, filter_band0, "config1:0-7");
+DEFINE_UNCORE_FORMAT_ATTR(filter_band1, filter_band1, "config1:8-15");
+DEFINE_UNCORE_FORMAT_ATTR(filter_band2, filter_band2, "config1:16-23");
+DEFINE_UNCORE_FORMAT_ATTR(filter_band3, filter_band3, "config1:24-31");
+DEFINE_UNCORE_FORMAT_ATTR(match_rds, match_rds, "config1:48-51");
+DEFINE_UNCORE_FORMAT_ATTR(match_rnid30, match_rnid30, "config1:32-35");
+DEFINE_UNCORE_FORMAT_ATTR(match_rnid4, match_rnid4, "config1:31");
+DEFINE_UNCORE_FORMAT_ATTR(match_dnid, match_dnid, "config1:13-17");
+DEFINE_UNCORE_FORMAT_ATTR(match_mc, match_mc, "config1:9-12");
+DEFINE_UNCORE_FORMAT_ATTR(match_opc, match_opc, "config1:5-8");
+DEFINE_UNCORE_FORMAT_ATTR(match_vnw, match_vnw, "config1:3-4");
+DEFINE_UNCORE_FORMAT_ATTR(match0, match0, "config1:0-31");
+DEFINE_UNCORE_FORMAT_ATTR(match1, match1, "config1:32-63");
+DEFINE_UNCORE_FORMAT_ATTR(mask_rds, mask_rds, "config2:48-51");
+DEFINE_UNCORE_FORMAT_ATTR(mask_rnid30, mask_rnid30, "config2:32-35");
+DEFINE_UNCORE_FORMAT_ATTR(mask_rnid4, mask_rnid4, "config2:31");
+DEFINE_UNCORE_FORMAT_ATTR(mask_dnid, mask_dnid, "config2:13-17");
+DEFINE_UNCORE_FORMAT_ATTR(mask_mc, mask_mc, "config2:9-12");
+DEFINE_UNCORE_FORMAT_ATTR(mask_opc, mask_opc, "config2:5-8");
+DEFINE_UNCORE_FORMAT_ATTR(mask_vnw, mask_vnw, "config2:3-4");
+DEFINE_UNCORE_FORMAT_ATTR(mask0, mask0, "config2:0-31");
+DEFINE_UNCORE_FORMAT_ATTR(mask1, mask1, "config2:32-63");
+
+static void snbep_uncore_pci_disable_box(struct intel_uncore_box *box)
+{
+	struct pci_dev *pdev = box->pci_dev;
+	int box_ctl = uncore_pci_box_ctl(box);
+	u32 config = 0;
+
+	if (!pci_read_config_dword(pdev, box_ctl, &config)) {
+		config |= SNBEP_PMON_BOX_CTL_FRZ;
+		pci_write_config_dword(pdev, box_ctl, config);
+	}
+}
+
+static void snbep_uncore_pci_enable_box(struct intel_uncore_box *box)
+{
+	struct pci_dev *pdev = box->pci_dev;
+	int box_ctl = uncore_pci_box_ctl(box);
+	u32 config = 0;
+
+	if (!pci_read_config_dword(pdev, box_ctl, &config)) {
+		config &= ~SNBEP_PMON_BOX_CTL_FRZ;
+		pci_write_config_dword(pdev, box_ctl, config);
+	}
+}
+
+static void snbep_uncore_pci_enable_event(struct intel_uncore_box *box, struct perf_event *event)
+{
+	struct pci_dev *pdev = box->pci_dev;
+	struct hw_perf_event *hwc = &event->hw;
+
+	pci_write_config_dword(pdev, hwc->config_base, hwc->config | SNBEP_PMON_CTL_EN);
+}
+
+static void snbep_uncore_pci_disable_event(struct intel_uncore_box *box, struct perf_event *event)
+{
+	struct pci_dev *pdev = box->pci_dev;
+	struct hw_perf_event *hwc = &event->hw;
+
+	pci_write_config_dword(pdev, hwc->config_base, hwc->config);
+}
+
+static u64 snbep_uncore_pci_read_counter(struct intel_uncore_box *box, struct perf_event *event)
+{
+	struct pci_dev *pdev = box->pci_dev;
+	struct hw_perf_event *hwc = &event->hw;
+	u64 count = 0;
+
+	pci_read_config_dword(pdev, hwc->event_base, (u32 *)&count);
+	pci_read_config_dword(pdev, hwc->event_base + 4, (u32 *)&count + 1);
+
+	return count;
+}
+
+static void snbep_uncore_pci_init_box(struct intel_uncore_box *box)
+{
+	struct pci_dev *pdev = box->pci_dev;
+	int box_ctl = uncore_pci_box_ctl(box);
+
+	pci_write_config_dword(pdev, box_ctl, SNBEP_PMON_BOX_CTL_INT);
+}
+
+static void snbep_uncore_msr_disable_box(struct intel_uncore_box *box)
+{
+	u64 config;
+	unsigned msr;
+
+	msr = uncore_msr_box_ctl(box);
+	if (msr) {
+		rdmsrl(msr, config);
+		config |= SNBEP_PMON_BOX_CTL_FRZ;
+		wrmsrl(msr, config);
+	}
+}
+
+static void snbep_uncore_msr_enable_box(struct intel_uncore_box *box)
+{
+	u64 config;
+	unsigned msr;
+
+	msr = uncore_msr_box_ctl(box);
+	if (msr) {
+		rdmsrl(msr, config);
+		config &= ~SNBEP_PMON_BOX_CTL_FRZ;
+		wrmsrl(msr, config);
+	}
+}
+
+static void snbep_uncore_msr_enable_event(struct intel_uncore_box *box, struct perf_event *event)
+{
+	struct hw_perf_event *hwc = &event->hw;
+	struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
+
+	if (reg1->idx != EXTRA_REG_NONE)
+		wrmsrl(reg1->reg, uncore_shared_reg_config(box, 0));
+
+	wrmsrl(hwc->config_base, hwc->config | SNBEP_PMON_CTL_EN);
+}
+
+static void snbep_uncore_msr_disable_event(struct intel_uncore_box *box,
+					struct perf_event *event)
+{
+	struct hw_perf_event *hwc = &event->hw;
+
+	wrmsrl(hwc->config_base, hwc->config);
+}
+
+static void snbep_uncore_msr_init_box(struct intel_uncore_box *box)
+{
+	unsigned msr = uncore_msr_box_ctl(box);
+
+	if (msr)
+		wrmsrl(msr, SNBEP_PMON_BOX_CTL_INT);
+}
+
+static struct attribute *snbep_uncore_formats_attr[] = {
+	&format_attr_event.attr,
+	&format_attr_umask.attr,
+	&format_attr_edge.attr,
+	&format_attr_inv.attr,
+	&format_attr_thresh8.attr,
+	NULL,
+};
+
+static struct attribute *snbep_uncore_ubox_formats_attr[] = {
+	&format_attr_event.attr,
+	&format_attr_umask.attr,
+	&format_attr_edge.attr,
+	&format_attr_inv.attr,
+	&format_attr_thresh5.attr,
+	NULL,
+};
+
+static struct attribute *snbep_uncore_cbox_formats_attr[] = {
+	&format_attr_event.attr,
+	&format_attr_umask.attr,
+	&format_attr_edge.attr,
+	&format_attr_tid_en.attr,
+	&format_attr_inv.attr,
+	&format_attr_thresh8.attr,
+	&format_attr_filter_tid.attr,
+	&format_attr_filter_nid.attr,
+	&format_attr_filter_state.attr,
+	&format_attr_filter_opc.attr,
+	NULL,
+};
+
+static struct attribute *snbep_uncore_pcu_formats_attr[] = {
+	&format_attr_event_ext.attr,
+	&format_attr_occ_sel.attr,
+	&format_attr_edge.attr,
+	&format_attr_inv.attr,
+	&format_attr_thresh5.attr,
+	&format_attr_occ_invert.attr,
+	&format_attr_occ_edge.attr,
+	&format_attr_filter_band0.attr,
+	&format_attr_filter_band1.attr,
+	&format_attr_filter_band2.attr,
+	&format_attr_filter_band3.attr,
+	NULL,
+};
+
+static struct attribute *snbep_uncore_qpi_formats_attr[] = {
+	&format_attr_event_ext.attr,
+	&format_attr_umask.attr,
+	&format_attr_edge.attr,
+	&format_attr_inv.attr,
+	&format_attr_thresh8.attr,
+	&format_attr_match_rds.attr,
+	&format_attr_match_rnid30.attr,
+	&format_attr_match_rnid4.attr,
+	&format_attr_match_dnid.attr,
+	&format_attr_match_mc.attr,
+	&format_attr_match_opc.attr,
+	&format_attr_match_vnw.attr,
+	&format_attr_match0.attr,
+	&format_attr_match1.attr,
+	&format_attr_mask_rds.attr,
+	&format_attr_mask_rnid30.attr,
+	&format_attr_mask_rnid4.attr,
+	&format_attr_mask_dnid.attr,
+	&format_attr_mask_mc.attr,
+	&format_attr_mask_opc.attr,
+	&format_attr_mask_vnw.attr,
+	&format_attr_mask0.attr,
+	&format_attr_mask1.attr,
+	NULL,
+};
+
+static struct uncore_event_desc snbep_uncore_imc_events[] = {
+	INTEL_UNCORE_EVENT_DESC(clockticks,      "event=0xff,umask=0x00"),
+	INTEL_UNCORE_EVENT_DESC(cas_count_read,  "event=0x04,umask=0x03"),
+	INTEL_UNCORE_EVENT_DESC(cas_count_read.scale, "6.103515625e-5"),
+	INTEL_UNCORE_EVENT_DESC(cas_count_read.unit, "MiB"),
+	INTEL_UNCORE_EVENT_DESC(cas_count_write, "event=0x04,umask=0x0c"),
+	INTEL_UNCORE_EVENT_DESC(cas_count_write.scale, "6.103515625e-5"),
+	INTEL_UNCORE_EVENT_DESC(cas_count_write.unit, "MiB"),
+	{ /* end: all zeroes */ },
+};
+
+static struct uncore_event_desc snbep_uncore_qpi_events[] = {
+	INTEL_UNCORE_EVENT_DESC(clockticks,       "event=0x14"),
+	INTEL_UNCORE_EVENT_DESC(txl_flits_active, "event=0x00,umask=0x06"),
+	INTEL_UNCORE_EVENT_DESC(drs_data,         "event=0x102,umask=0x08"),
+	INTEL_UNCORE_EVENT_DESC(ncb_data,         "event=0x103,umask=0x04"),
+	{ /* end: all zeroes */ },
+};
+
+static struct attribute_group snbep_uncore_format_group = {
+	.name = "format",
+	.attrs = snbep_uncore_formats_attr,
+};
+
+static struct attribute_group snbep_uncore_ubox_format_group = {
+	.name = "format",
+	.attrs = snbep_uncore_ubox_formats_attr,
+};
+
+static struct attribute_group snbep_uncore_cbox_format_group = {
+	.name = "format",
+	.attrs = snbep_uncore_cbox_formats_attr,
+};
+
+static struct attribute_group snbep_uncore_pcu_format_group = {
+	.name = "format",
+	.attrs = snbep_uncore_pcu_formats_attr,
+};
+
+static struct attribute_group snbep_uncore_qpi_format_group = {
+	.name = "format",
+	.attrs = snbep_uncore_qpi_formats_attr,
+};
+
+#define __SNBEP_UNCORE_MSR_OPS_COMMON_INIT()			\
+	.disable_box	= snbep_uncore_msr_disable_box,		\
+	.enable_box	= snbep_uncore_msr_enable_box,		\
+	.disable_event	= snbep_uncore_msr_disable_event,	\
+	.enable_event	= snbep_uncore_msr_enable_event,	\
+	.read_counter	= uncore_msr_read_counter
+
+#define SNBEP_UNCORE_MSR_OPS_COMMON_INIT()			\
+	__SNBEP_UNCORE_MSR_OPS_COMMON_INIT(),			\
+	.init_box	= snbep_uncore_msr_init_box		\
+
+static struct intel_uncore_ops snbep_uncore_msr_ops = {
+	SNBEP_UNCORE_MSR_OPS_COMMON_INIT(),
+};
+
+#define SNBEP_UNCORE_PCI_OPS_COMMON_INIT()			\
+	.init_box	= snbep_uncore_pci_init_box,		\
+	.disable_box	= snbep_uncore_pci_disable_box,		\
+	.enable_box	= snbep_uncore_pci_enable_box,		\
+	.disable_event	= snbep_uncore_pci_disable_event,	\
+	.read_counter	= snbep_uncore_pci_read_counter
+
+static struct intel_uncore_ops snbep_uncore_pci_ops = {
+	SNBEP_UNCORE_PCI_OPS_COMMON_INIT(),
+	.enable_event	= snbep_uncore_pci_enable_event,	\
+};
+
+static struct event_constraint snbep_uncore_cbox_constraints[] = {
+	UNCORE_EVENT_CONSTRAINT(0x01, 0x1),
+	UNCORE_EVENT_CONSTRAINT(0x02, 0x3),
+	UNCORE_EVENT_CONSTRAINT(0x04, 0x3),
+	UNCORE_EVENT_CONSTRAINT(0x05, 0x3),
+	UNCORE_EVENT_CONSTRAINT(0x07, 0x3),
+	UNCORE_EVENT_CONSTRAINT(0x09, 0x3),
+	UNCORE_EVENT_CONSTRAINT(0x11, 0x1),
+	UNCORE_EVENT_CONSTRAINT(0x12, 0x3),
+	UNCORE_EVENT_CONSTRAINT(0x13, 0x3),
+	UNCORE_EVENT_CONSTRAINT(0x1b, 0xc),
+	UNCORE_EVENT_CONSTRAINT(0x1c, 0xc),
+	UNCORE_EVENT_CONSTRAINT(0x1d, 0xc),
+	UNCORE_EVENT_CONSTRAINT(0x1e, 0xc),
+	EVENT_CONSTRAINT_OVERLAP(0x1f, 0xe, 0xff),
+	UNCORE_EVENT_CONSTRAINT(0x21, 0x3),
+	UNCORE_EVENT_CONSTRAINT(0x23, 0x3),
+	UNCORE_EVENT_CONSTRAINT(0x31, 0x3),
+	UNCORE_EVENT_CONSTRAINT(0x32, 0x3),
+	UNCORE_EVENT_CONSTRAINT(0x33, 0x3),
+	UNCORE_EVENT_CONSTRAINT(0x34, 0x3),
+	UNCORE_EVENT_CONSTRAINT(0x35, 0x3),
+	UNCORE_EVENT_CONSTRAINT(0x36, 0x1),
+	UNCORE_EVENT_CONSTRAINT(0x37, 0x3),
+	UNCORE_EVENT_CONSTRAINT(0x38, 0x3),
+	UNCORE_EVENT_CONSTRAINT(0x39, 0x3),
+	UNCORE_EVENT_CONSTRAINT(0x3b, 0x1),
+	EVENT_CONSTRAINT_END
+};
+
+static struct event_constraint snbep_uncore_r2pcie_constraints[] = {
+	UNCORE_EVENT_CONSTRAINT(0x10, 0x3),
+	UNCORE_EVENT_CONSTRAINT(0x11, 0x3),
+	UNCORE_EVENT_CONSTRAINT(0x12, 0x1),
+	UNCORE_EVENT_CONSTRAINT(0x23, 0x3),
+	UNCORE_EVENT_CONSTRAINT(0x24, 0x3),
+	UNCORE_EVENT_CONSTRAINT(0x25, 0x3),
+	UNCORE_EVENT_CONSTRAINT(0x26, 0x3),
+	UNCORE_EVENT_CONSTRAINT(0x32, 0x3),
+	UNCORE_EVENT_CONSTRAINT(0x33, 0x3),
+	UNCORE_EVENT_CONSTRAINT(0x34, 0x3),
+	EVENT_CONSTRAINT_END
+};
+
+static struct event_constraint snbep_uncore_r3qpi_constraints[] = {
+	UNCORE_EVENT_CONSTRAINT(0x10, 0x3),
+	UNCORE_EVENT_CONSTRAINT(0x11, 0x3),
+	UNCORE_EVENT_CONSTRAINT(0x12, 0x3),
+	UNCORE_EVENT_CONSTRAINT(0x13, 0x1),
+	UNCORE_EVENT_CONSTRAINT(0x20, 0x3),
+	UNCORE_EVENT_CONSTRAINT(0x21, 0x3),
+	UNCORE_EVENT_CONSTRAINT(0x22, 0x3),
+	UNCORE_EVENT_CONSTRAINT(0x23, 0x3),
+	UNCORE_EVENT_CONSTRAINT(0x24, 0x3),
+	UNCORE_EVENT_CONSTRAINT(0x25, 0x3),
+	UNCORE_EVENT_CONSTRAINT(0x26, 0x3),
+	UNCORE_EVENT_CONSTRAINT(0x28, 0x3),
+	UNCORE_EVENT_CONSTRAINT(0x29, 0x3),
+	UNCORE_EVENT_CONSTRAINT(0x2a, 0x3),
+	UNCORE_EVENT_CONSTRAINT(0x2b, 0x3),
+	UNCORE_EVENT_CONSTRAINT(0x2c, 0x3),
+	UNCORE_EVENT_CONSTRAINT(0x2d, 0x3),
+	UNCORE_EVENT_CONSTRAINT(0x2e, 0x3),
+	UNCORE_EVENT_CONSTRAINT(0x2f, 0x3),
+	UNCORE_EVENT_CONSTRAINT(0x30, 0x3),
+	UNCORE_EVENT_CONSTRAINT(0x31, 0x3),
+	UNCORE_EVENT_CONSTRAINT(0x32, 0x3),
+	UNCORE_EVENT_CONSTRAINT(0x33, 0x3),
+	UNCORE_EVENT_CONSTRAINT(0x34, 0x3),
+	UNCORE_EVENT_CONSTRAINT(0x36, 0x3),
+	UNCORE_EVENT_CONSTRAINT(0x37, 0x3),
+	UNCORE_EVENT_CONSTRAINT(0x38, 0x3),
+	UNCORE_EVENT_CONSTRAINT(0x39, 0x3),
+	EVENT_CONSTRAINT_END
+};
+
+static struct intel_uncore_type snbep_uncore_ubox = {
+	.name		= "ubox",
+	.num_counters   = 2,
+	.num_boxes	= 1,
+	.perf_ctr_bits	= 44,
+	.fixed_ctr_bits	= 48,
+	.perf_ctr	= SNBEP_U_MSR_PMON_CTR0,
+	.event_ctl	= SNBEP_U_MSR_PMON_CTL0,
+	.event_mask	= SNBEP_U_MSR_PMON_RAW_EVENT_MASK,
+	.fixed_ctr	= SNBEP_U_MSR_PMON_UCLK_FIXED_CTR,
+	.fixed_ctl	= SNBEP_U_MSR_PMON_UCLK_FIXED_CTL,
+	.ops		= &snbep_uncore_msr_ops,
+	.format_group	= &snbep_uncore_ubox_format_group,
+};
+
+static struct extra_reg snbep_uncore_cbox_extra_regs[] = {
+	SNBEP_CBO_EVENT_EXTRA_REG(SNBEP_CBO_PMON_CTL_TID_EN,
+				  SNBEP_CBO_PMON_CTL_TID_EN, 0x1),
+	SNBEP_CBO_EVENT_EXTRA_REG(0x0334, 0xffff, 0x4),
+	SNBEP_CBO_EVENT_EXTRA_REG(0x4334, 0xffff, 0x6),
+	SNBEP_CBO_EVENT_EXTRA_REG(0x0534, 0xffff, 0x4),
+	SNBEP_CBO_EVENT_EXTRA_REG(0x4534, 0xffff, 0x6),
+	SNBEP_CBO_EVENT_EXTRA_REG(0x0934, 0xffff, 0x4),
+	SNBEP_CBO_EVENT_EXTRA_REG(0x4934, 0xffff, 0x6),
+	SNBEP_CBO_EVENT_EXTRA_REG(0x4134, 0xffff, 0x6),
+	SNBEP_CBO_EVENT_EXTRA_REG(0x0135, 0xffff, 0x8),
+	SNBEP_CBO_EVENT_EXTRA_REG(0x0335, 0xffff, 0x8),
+	SNBEP_CBO_EVENT_EXTRA_REG(0x4135, 0xffff, 0xa),
+	SNBEP_CBO_EVENT_EXTRA_REG(0x4335, 0xffff, 0xa),
+	SNBEP_CBO_EVENT_EXTRA_REG(0x4435, 0xffff, 0x2),
+	SNBEP_CBO_EVENT_EXTRA_REG(0x4835, 0xffff, 0x2),
+	SNBEP_CBO_EVENT_EXTRA_REG(0x4a35, 0xffff, 0x2),
+	SNBEP_CBO_EVENT_EXTRA_REG(0x5035, 0xffff, 0x2),
+	SNBEP_CBO_EVENT_EXTRA_REG(0x0136, 0xffff, 0x8),
+	SNBEP_CBO_EVENT_EXTRA_REG(0x0336, 0xffff, 0x8),
+	SNBEP_CBO_EVENT_EXTRA_REG(0x4136, 0xffff, 0xa),
+	SNBEP_CBO_EVENT_EXTRA_REG(0x4336, 0xffff, 0xa),
+	SNBEP_CBO_EVENT_EXTRA_REG(0x4436, 0xffff, 0x2),
+	SNBEP_CBO_EVENT_EXTRA_REG(0x4836, 0xffff, 0x2),
+	SNBEP_CBO_EVENT_EXTRA_REG(0x4a36, 0xffff, 0x2),
+	SNBEP_CBO_EVENT_EXTRA_REG(0x4037, 0x40ff, 0x2),
+	EVENT_EXTRA_END
+};
+
+static void snbep_cbox_put_constraint(struct intel_uncore_box *box, struct perf_event *event)
+{
+	struct hw_perf_event_extra *reg1 = &event->hw.extra_reg;
+	struct intel_uncore_extra_reg *er = &box->shared_regs[0];
+	int i;
+
+	if (uncore_box_is_fake(box))
+		return;
+
+	for (i = 0; i < 5; i++) {
+		if (reg1->alloc & (0x1 << i))
+			atomic_sub(1 << (i * 6), &er->ref);
+	}
+	reg1->alloc = 0;
+}
+
+static struct event_constraint *
+__snbep_cbox_get_constraint(struct intel_uncore_box *box, struct perf_event *event,
+			    u64 (*cbox_filter_mask)(int fields))
+{
+	struct hw_perf_event_extra *reg1 = &event->hw.extra_reg;
+	struct intel_uncore_extra_reg *er = &box->shared_regs[0];
+	int i, alloc = 0;
+	unsigned long flags;
+	u64 mask;
+
+	if (reg1->idx == EXTRA_REG_NONE)
+		return NULL;
+
+	raw_spin_lock_irqsave(&er->lock, flags);
+	for (i = 0; i < 5; i++) {
+		if (!(reg1->idx & (0x1 << i)))
+			continue;
+		if (!uncore_box_is_fake(box) && (reg1->alloc & (0x1 << i)))
+			continue;
+
+		mask = cbox_filter_mask(0x1 << i);
+		if (!__BITS_VALUE(atomic_read(&er->ref), i, 6) ||
+		    !((reg1->config ^ er->config) & mask)) {
+			atomic_add(1 << (i * 6), &er->ref);
+			er->config &= ~mask;
+			er->config |= reg1->config & mask;
+			alloc |= (0x1 << i);
+		} else {
+			break;
+		}
+	}
+	raw_spin_unlock_irqrestore(&er->lock, flags);
+	if (i < 5)
+		goto fail;
+
+	if (!uncore_box_is_fake(box))
+		reg1->alloc |= alloc;
+
+	return NULL;
+fail:
+	for (; i >= 0; i--) {
+		if (alloc & (0x1 << i))
+			atomic_sub(1 << (i * 6), &er->ref);
+	}
+	return &uncore_constraint_empty;
+}
+
+static u64 snbep_cbox_filter_mask(int fields)
+{
+	u64 mask = 0;
+
+	if (fields & 0x1)
+		mask |= SNBEP_CB0_MSR_PMON_BOX_FILTER_TID;
+	if (fields & 0x2)
+		mask |= SNBEP_CB0_MSR_PMON_BOX_FILTER_NID;
+	if (fields & 0x4)
+		mask |= SNBEP_CB0_MSR_PMON_BOX_FILTER_STATE;
+	if (fields & 0x8)
+		mask |= SNBEP_CB0_MSR_PMON_BOX_FILTER_OPC;
+
+	return mask;
+}
+
+static struct event_constraint *
+snbep_cbox_get_constraint(struct intel_uncore_box *box, struct perf_event *event)
+{
+	return __snbep_cbox_get_constraint(box, event, snbep_cbox_filter_mask);
+}
+
+static int snbep_cbox_hw_config(struct intel_uncore_box *box, struct perf_event *event)
+{
+	struct hw_perf_event_extra *reg1 = &event->hw.extra_reg;
+	struct extra_reg *er;
+	int idx = 0;
+
+	for (er = snbep_uncore_cbox_extra_regs; er->msr; er++) {
+		if (er->event != (event->hw.config & er->config_mask))
+			continue;
+		idx |= er->idx;
+	}
+
+	if (idx) {
+		reg1->reg = SNBEP_C0_MSR_PMON_BOX_FILTER +
+			SNBEP_CBO_MSR_OFFSET * box->pmu->pmu_idx;
+		reg1->config = event->attr.config1 & snbep_cbox_filter_mask(idx);
+		reg1->idx = idx;
+	}
+	return 0;
+}
+
+static struct intel_uncore_ops snbep_uncore_cbox_ops = {
+	SNBEP_UNCORE_MSR_OPS_COMMON_INIT(),
+	.hw_config		= snbep_cbox_hw_config,
+	.get_constraint		= snbep_cbox_get_constraint,
+	.put_constraint		= snbep_cbox_put_constraint,
+};
+
+static struct intel_uncore_type snbep_uncore_cbox = {
+	.name			= "cbox",
+	.num_counters		= 4,
+	.num_boxes		= 8,
+	.perf_ctr_bits		= 44,
+	.event_ctl		= SNBEP_C0_MSR_PMON_CTL0,
+	.perf_ctr		= SNBEP_C0_MSR_PMON_CTR0,
+	.event_mask		= SNBEP_CBO_MSR_PMON_RAW_EVENT_MASK,
+	.box_ctl		= SNBEP_C0_MSR_PMON_BOX_CTL,
+	.msr_offset		= SNBEP_CBO_MSR_OFFSET,
+	.num_shared_regs	= 1,
+	.constraints		= snbep_uncore_cbox_constraints,
+	.ops			= &snbep_uncore_cbox_ops,
+	.format_group		= &snbep_uncore_cbox_format_group,
+};
+
+static u64 snbep_pcu_alter_er(struct perf_event *event, int new_idx, bool modify)
+{
+	struct hw_perf_event *hwc = &event->hw;
+	struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
+	u64 config = reg1->config;
+
+	if (new_idx > reg1->idx)
+		config <<= 8 * (new_idx - reg1->idx);
+	else
+		config >>= 8 * (reg1->idx - new_idx);
+
+	if (modify) {
+		hwc->config += new_idx - reg1->idx;
+		reg1->config = config;
+		reg1->idx = new_idx;
+	}
+	return config;
+}
+
+static struct event_constraint *
+snbep_pcu_get_constraint(struct intel_uncore_box *box, struct perf_event *event)
+{
+	struct hw_perf_event_extra *reg1 = &event->hw.extra_reg;
+	struct intel_uncore_extra_reg *er = &box->shared_regs[0];
+	unsigned long flags;
+	int idx = reg1->idx;
+	u64 mask, config1 = reg1->config;
+	bool ok = false;
+
+	if (reg1->idx == EXTRA_REG_NONE ||
+	    (!uncore_box_is_fake(box) && reg1->alloc))
+		return NULL;
+again:
+	mask = 0xffULL << (idx * 8);
+	raw_spin_lock_irqsave(&er->lock, flags);
+	if (!__BITS_VALUE(atomic_read(&er->ref), idx, 8) ||
+	    !((config1 ^ er->config) & mask)) {
+		atomic_add(1 << (idx * 8), &er->ref);
+		er->config &= ~mask;
+		er->config |= config1 & mask;
+		ok = true;
+	}
+	raw_spin_unlock_irqrestore(&er->lock, flags);
+
+	if (!ok) {
+		idx = (idx + 1) % 4;
+		if (idx != reg1->idx) {
+			config1 = snbep_pcu_alter_er(event, idx, false);
+			goto again;
+		}
+		return &uncore_constraint_empty;
+	}
+
+	if (!uncore_box_is_fake(box)) {
+		if (idx != reg1->idx)
+			snbep_pcu_alter_er(event, idx, true);
+		reg1->alloc = 1;
+	}
+	return NULL;
+}
+
+static void snbep_pcu_put_constraint(struct intel_uncore_box *box, struct perf_event *event)
+{
+	struct hw_perf_event_extra *reg1 = &event->hw.extra_reg;
+	struct intel_uncore_extra_reg *er = &box->shared_regs[0];
+
+	if (uncore_box_is_fake(box) || !reg1->alloc)
+		return;
+
+	atomic_sub(1 << (reg1->idx * 8), &er->ref);
+	reg1->alloc = 0;
+}
+
+static int snbep_pcu_hw_config(struct intel_uncore_box *box, struct perf_event *event)
+{
+	struct hw_perf_event *hwc = &event->hw;
+	struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
+	int ev_sel = hwc->config & SNBEP_PMON_CTL_EV_SEL_MASK;
+
+	if (ev_sel >= 0xb && ev_sel <= 0xe) {
+		reg1->reg = SNBEP_PCU_MSR_PMON_BOX_FILTER;
+		reg1->idx = ev_sel - 0xb;
+		reg1->config = event->attr.config1 & (0xff << (reg1->idx * 8));
+	}
+	return 0;
+}
+
+static struct intel_uncore_ops snbep_uncore_pcu_ops = {
+	SNBEP_UNCORE_MSR_OPS_COMMON_INIT(),
+	.hw_config		= snbep_pcu_hw_config,
+	.get_constraint		= snbep_pcu_get_constraint,
+	.put_constraint		= snbep_pcu_put_constraint,
+};
+
+static struct intel_uncore_type snbep_uncore_pcu = {
+	.name			= "pcu",
+	.num_counters		= 4,
+	.num_boxes		= 1,
+	.perf_ctr_bits		= 48,
+	.perf_ctr		= SNBEP_PCU_MSR_PMON_CTR0,
+	.event_ctl		= SNBEP_PCU_MSR_PMON_CTL0,
+	.event_mask		= SNBEP_PCU_MSR_PMON_RAW_EVENT_MASK,
+	.box_ctl		= SNBEP_PCU_MSR_PMON_BOX_CTL,
+	.num_shared_regs	= 1,
+	.ops			= &snbep_uncore_pcu_ops,
+	.format_group		= &snbep_uncore_pcu_format_group,
+};
+
+static struct intel_uncore_type *snbep_msr_uncores[] = {
+	&snbep_uncore_ubox,
+	&snbep_uncore_cbox,
+	&snbep_uncore_pcu,
+	NULL,
+};
+
+void snbep_uncore_cpu_init(void)
+{
+	if (snbep_uncore_cbox.num_boxes > boot_cpu_data.x86_max_cores)
+		snbep_uncore_cbox.num_boxes = boot_cpu_data.x86_max_cores;
+	uncore_msr_uncores = snbep_msr_uncores;
+}
+
+enum {
+	SNBEP_PCI_QPI_PORT0_FILTER,
+	SNBEP_PCI_QPI_PORT1_FILTER,
+	HSWEP_PCI_PCU_3,
+};
+
+static int snbep_qpi_hw_config(struct intel_uncore_box *box, struct perf_event *event)
+{
+	struct hw_perf_event *hwc = &event->hw;
+	struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
+	struct hw_perf_event_extra *reg2 = &hwc->branch_reg;
+
+	if ((hwc->config & SNBEP_PMON_CTL_EV_SEL_MASK) == 0x38) {
+		reg1->idx = 0;
+		reg1->reg = SNBEP_Q_Py_PCI_PMON_PKT_MATCH0;
+		reg1->config = event->attr.config1;
+		reg2->reg = SNBEP_Q_Py_PCI_PMON_PKT_MASK0;
+		reg2->config = event->attr.config2;
+	}
+	return 0;
+}
+
+static void snbep_qpi_enable_event(struct intel_uncore_box *box, struct perf_event *event)
+{
+	struct pci_dev *pdev = box->pci_dev;
+	struct hw_perf_event *hwc = &event->hw;
+	struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
+	struct hw_perf_event_extra *reg2 = &hwc->branch_reg;
+
+	if (reg1->idx != EXTRA_REG_NONE) {
+		int idx = box->pmu->pmu_idx + SNBEP_PCI_QPI_PORT0_FILTER;
+		struct pci_dev *filter_pdev = uncore_extra_pci_dev[box->phys_id][idx];
+		if (filter_pdev) {
+			pci_write_config_dword(filter_pdev, reg1->reg,
+						(u32)reg1->config);
+			pci_write_config_dword(filter_pdev, reg1->reg + 4,
+						(u32)(reg1->config >> 32));
+			pci_write_config_dword(filter_pdev, reg2->reg,
+						(u32)reg2->config);
+			pci_write_config_dword(filter_pdev, reg2->reg + 4,
+						(u32)(reg2->config >> 32));
+		}
+	}
+
+	pci_write_config_dword(pdev, hwc->config_base, hwc->config | SNBEP_PMON_CTL_EN);
+}
+
+static struct intel_uncore_ops snbep_uncore_qpi_ops = {
+	SNBEP_UNCORE_PCI_OPS_COMMON_INIT(),
+	.enable_event		= snbep_qpi_enable_event,
+	.hw_config		= snbep_qpi_hw_config,
+	.get_constraint		= uncore_get_constraint,
+	.put_constraint		= uncore_put_constraint,
+};
+
+#define SNBEP_UNCORE_PCI_COMMON_INIT()				\
+	.perf_ctr	= SNBEP_PCI_PMON_CTR0,			\
+	.event_ctl	= SNBEP_PCI_PMON_CTL0,			\
+	.event_mask	= SNBEP_PMON_RAW_EVENT_MASK,		\
+	.box_ctl	= SNBEP_PCI_PMON_BOX_CTL,		\
+	.ops		= &snbep_uncore_pci_ops,		\
+	.format_group	= &snbep_uncore_format_group
+
+static struct intel_uncore_type snbep_uncore_ha = {
+	.name		= "ha",
+	.num_counters   = 4,
+	.num_boxes	= 1,
+	.perf_ctr_bits	= 48,
+	SNBEP_UNCORE_PCI_COMMON_INIT(),
+};
+
+static struct intel_uncore_type snbep_uncore_imc = {
+	.name		= "imc",
+	.num_counters   = 4,
+	.num_boxes	= 4,
+	.perf_ctr_bits	= 48,
+	.fixed_ctr_bits	= 48,
+	.fixed_ctr	= SNBEP_MC_CHy_PCI_PMON_FIXED_CTR,
+	.fixed_ctl	= SNBEP_MC_CHy_PCI_PMON_FIXED_CTL,
+	.event_descs	= snbep_uncore_imc_events,
+	SNBEP_UNCORE_PCI_COMMON_INIT(),
+};
+
+static struct intel_uncore_type snbep_uncore_qpi = {
+	.name			= "qpi",
+	.num_counters		= 4,
+	.num_boxes		= 2,
+	.perf_ctr_bits		= 48,
+	.perf_ctr		= SNBEP_PCI_PMON_CTR0,
+	.event_ctl		= SNBEP_PCI_PMON_CTL0,
+	.event_mask		= SNBEP_QPI_PCI_PMON_RAW_EVENT_MASK,
+	.box_ctl		= SNBEP_PCI_PMON_BOX_CTL,
+	.num_shared_regs	= 1,
+	.ops			= &snbep_uncore_qpi_ops,
+	.event_descs		= snbep_uncore_qpi_events,
+	.format_group		= &snbep_uncore_qpi_format_group,
+};
+
+
+static struct intel_uncore_type snbep_uncore_r2pcie = {
+	.name		= "r2pcie",
+	.num_counters   = 4,
+	.num_boxes	= 1,
+	.perf_ctr_bits	= 44,
+	.constraints	= snbep_uncore_r2pcie_constraints,
+	SNBEP_UNCORE_PCI_COMMON_INIT(),
+};
+
+static struct intel_uncore_type snbep_uncore_r3qpi = {
+	.name		= "r3qpi",
+	.num_counters   = 3,
+	.num_boxes	= 2,
+	.perf_ctr_bits	= 44,
+	.constraints	= snbep_uncore_r3qpi_constraints,
+	SNBEP_UNCORE_PCI_COMMON_INIT(),
+};
+
+enum {
+	SNBEP_PCI_UNCORE_HA,
+	SNBEP_PCI_UNCORE_IMC,
+	SNBEP_PCI_UNCORE_QPI,
+	SNBEP_PCI_UNCORE_R2PCIE,
+	SNBEP_PCI_UNCORE_R3QPI,
+};
+
+static struct intel_uncore_type *snbep_pci_uncores[] = {
+	[SNBEP_PCI_UNCORE_HA]		= &snbep_uncore_ha,
+	[SNBEP_PCI_UNCORE_IMC]		= &snbep_uncore_imc,
+	[SNBEP_PCI_UNCORE_QPI]		= &snbep_uncore_qpi,
+	[SNBEP_PCI_UNCORE_R2PCIE]	= &snbep_uncore_r2pcie,
+	[SNBEP_PCI_UNCORE_R3QPI]	= &snbep_uncore_r3qpi,
+	NULL,
+};
+
+static const struct pci_device_id snbep_uncore_pci_ids[] = {
+	{ /* Home Agent */
+		PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_HA),
+		.driver_data = UNCORE_PCI_DEV_DATA(SNBEP_PCI_UNCORE_HA, 0),
+	},
+	{ /* MC Channel 0 */
+		PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_IMC0),
+		.driver_data = UNCORE_PCI_DEV_DATA(SNBEP_PCI_UNCORE_IMC, 0),
+	},
+	{ /* MC Channel 1 */
+		PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_IMC1),
+		.driver_data = UNCORE_PCI_DEV_DATA(SNBEP_PCI_UNCORE_IMC, 1),
+	},
+	{ /* MC Channel 2 */
+		PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_IMC2),
+		.driver_data = UNCORE_PCI_DEV_DATA(SNBEP_PCI_UNCORE_IMC, 2),
+	},
+	{ /* MC Channel 3 */
+		PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_IMC3),
+		.driver_data = UNCORE_PCI_DEV_DATA(SNBEP_PCI_UNCORE_IMC, 3),
+	},
+	{ /* QPI Port 0 */
+		PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_QPI0),
+		.driver_data = UNCORE_PCI_DEV_DATA(SNBEP_PCI_UNCORE_QPI, 0),
+	},
+	{ /* QPI Port 1 */
+		PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_QPI1),
+		.driver_data = UNCORE_PCI_DEV_DATA(SNBEP_PCI_UNCORE_QPI, 1),
+	},
+	{ /* R2PCIe */
+		PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_R2PCIE),
+		.driver_data = UNCORE_PCI_DEV_DATA(SNBEP_PCI_UNCORE_R2PCIE, 0),
+	},
+	{ /* R3QPI Link 0 */
+		PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_R3QPI0),
+		.driver_data = UNCORE_PCI_DEV_DATA(SNBEP_PCI_UNCORE_R3QPI, 0),
+	},
+	{ /* R3QPI Link 1 */
+		PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_R3QPI1),
+		.driver_data = UNCORE_PCI_DEV_DATA(SNBEP_PCI_UNCORE_R3QPI, 1),
+	},
+	{ /* QPI Port 0 filter  */
+		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x3c86),
+		.driver_data = UNCORE_PCI_DEV_DATA(UNCORE_EXTRA_PCI_DEV,
+						   SNBEP_PCI_QPI_PORT0_FILTER),
+	},
+	{ /* QPI Port 0 filter  */
+		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x3c96),
+		.driver_data = UNCORE_PCI_DEV_DATA(UNCORE_EXTRA_PCI_DEV,
+						   SNBEP_PCI_QPI_PORT1_FILTER),
+	},
+	{ /* end: all zeroes */ }
+};
+
+static struct pci_driver snbep_uncore_pci_driver = {
+	.name		= "snbep_uncore",
+	.id_table	= snbep_uncore_pci_ids,
+};
+
+/*
+ * build pci bus to socket mapping
+ */
+static int snbep_pci2phy_map_init(int devid)
+{
+	struct pci_dev *ubox_dev = NULL;
+	int i, bus, nodeid, segment;
+	struct pci2phy_map *map;
+	int err = 0;
+	u32 config = 0;
+
+	while (1) {
+		/* find the UBOX device */
+		ubox_dev = pci_get_device(PCI_VENDOR_ID_INTEL, devid, ubox_dev);
+		if (!ubox_dev)
+			break;
+		bus = ubox_dev->bus->number;
+		/* get the Node ID of the local register */
+		err = pci_read_config_dword(ubox_dev, 0x40, &config);
+		if (err)
+			break;
+		nodeid = config;
+		/* get the Node ID mapping */
+		err = pci_read_config_dword(ubox_dev, 0x54, &config);
+		if (err)
+			break;
+
+		segment = pci_domain_nr(ubox_dev->bus);
+		raw_spin_lock(&pci2phy_map_lock);
+		map = __find_pci2phy_map(segment);
+		if (!map) {
+			raw_spin_unlock(&pci2phy_map_lock);
+			err = -ENOMEM;
+			break;
+		}
+
+		/*
+		 * every three bits in the Node ID mapping register maps
+		 * to a particular node.
+		 */
+		for (i = 0; i < 8; i++) {
+			if (nodeid == ((config >> (3 * i)) & 0x7)) {
+				map->pbus_to_physid[bus] = i;
+				break;
+			}
+		}
+		raw_spin_unlock(&pci2phy_map_lock);
+	}
+
+	if (!err) {
+		/*
+		 * For PCI bus with no UBOX device, find the next bus
+		 * that has UBOX device and use its mapping.
+		 */
+		raw_spin_lock(&pci2phy_map_lock);
+		list_for_each_entry(map, &pci2phy_map_head, list) {
+			i = -1;
+			for (bus = 255; bus >= 0; bus--) {
+				if (map->pbus_to_physid[bus] >= 0)
+					i = map->pbus_to_physid[bus];
+				else
+					map->pbus_to_physid[bus] = i;
+			}
+		}
+		raw_spin_unlock(&pci2phy_map_lock);
+	}
+
+	pci_dev_put(ubox_dev);
+
+	return err ? pcibios_err_to_errno(err) : 0;
+}
+
+int snbep_uncore_pci_init(void)
+{
+	int ret = snbep_pci2phy_map_init(0x3ce0);
+	if (ret)
+		return ret;
+	uncore_pci_uncores = snbep_pci_uncores;
+	uncore_pci_driver = &snbep_uncore_pci_driver;
+	return 0;
+}
+/* end of Sandy Bridge-EP uncore support */
+
+/* IvyTown uncore support */
+static void ivbep_uncore_msr_init_box(struct intel_uncore_box *box)
+{
+	unsigned msr = uncore_msr_box_ctl(box);
+	if (msr)
+		wrmsrl(msr, IVBEP_PMON_BOX_CTL_INT);
+}
+
+static void ivbep_uncore_pci_init_box(struct intel_uncore_box *box)
+{
+	struct pci_dev *pdev = box->pci_dev;
+
+	pci_write_config_dword(pdev, SNBEP_PCI_PMON_BOX_CTL, IVBEP_PMON_BOX_CTL_INT);
+}
+
+#define IVBEP_UNCORE_MSR_OPS_COMMON_INIT()			\
+	.init_box	= ivbep_uncore_msr_init_box,		\
+	.disable_box	= snbep_uncore_msr_disable_box,		\
+	.enable_box	= snbep_uncore_msr_enable_box,		\
+	.disable_event	= snbep_uncore_msr_disable_event,	\
+	.enable_event	= snbep_uncore_msr_enable_event,	\
+	.read_counter	= uncore_msr_read_counter
+
+static struct intel_uncore_ops ivbep_uncore_msr_ops = {
+	IVBEP_UNCORE_MSR_OPS_COMMON_INIT(),
+};
+
+static struct intel_uncore_ops ivbep_uncore_pci_ops = {
+	.init_box	= ivbep_uncore_pci_init_box,
+	.disable_box	= snbep_uncore_pci_disable_box,
+	.enable_box	= snbep_uncore_pci_enable_box,
+	.disable_event	= snbep_uncore_pci_disable_event,
+	.enable_event	= snbep_uncore_pci_enable_event,
+	.read_counter	= snbep_uncore_pci_read_counter,
+};
+
+#define IVBEP_UNCORE_PCI_COMMON_INIT()				\
+	.perf_ctr	= SNBEP_PCI_PMON_CTR0,			\
+	.event_ctl	= SNBEP_PCI_PMON_CTL0,			\
+	.event_mask	= IVBEP_PMON_RAW_EVENT_MASK,		\
+	.box_ctl	= SNBEP_PCI_PMON_BOX_CTL,		\
+	.ops		= &ivbep_uncore_pci_ops,			\
+	.format_group	= &ivbep_uncore_format_group
+
+static struct attribute *ivbep_uncore_formats_attr[] = {
+	&format_attr_event.attr,
+	&format_attr_umask.attr,
+	&format_attr_edge.attr,
+	&format_attr_inv.attr,
+	&format_attr_thresh8.attr,
+	NULL,
+};
+
+static struct attribute *ivbep_uncore_ubox_formats_attr[] = {
+	&format_attr_event.attr,
+	&format_attr_umask.attr,
+	&format_attr_edge.attr,
+	&format_attr_inv.attr,
+	&format_attr_thresh5.attr,
+	NULL,
+};
+
+static struct attribute *ivbep_uncore_cbox_formats_attr[] = {
+	&format_attr_event.attr,
+	&format_attr_umask.attr,
+	&format_attr_edge.attr,
+	&format_attr_tid_en.attr,
+	&format_attr_thresh8.attr,
+	&format_attr_filter_tid.attr,
+	&format_attr_filter_link.attr,
+	&format_attr_filter_state2.attr,
+	&format_attr_filter_nid2.attr,
+	&format_attr_filter_opc2.attr,
+	&format_attr_filter_nc.attr,
+	&format_attr_filter_c6.attr,
+	&format_attr_filter_isoc.attr,
+	NULL,
+};
+
+static struct attribute *ivbep_uncore_pcu_formats_attr[] = {
+	&format_attr_event_ext.attr,
+	&format_attr_occ_sel.attr,
+	&format_attr_edge.attr,
+	&format_attr_thresh5.attr,
+	&format_attr_occ_invert.attr,
+	&format_attr_occ_edge.attr,
+	&format_attr_filter_band0.attr,
+	&format_attr_filter_band1.attr,
+	&format_attr_filter_band2.attr,
+	&format_attr_filter_band3.attr,
+	NULL,
+};
+
+static struct attribute *ivbep_uncore_qpi_formats_attr[] = {
+	&format_attr_event_ext.attr,
+	&format_attr_umask.attr,
+	&format_attr_edge.attr,
+	&format_attr_thresh8.attr,
+	&format_attr_match_rds.attr,
+	&format_attr_match_rnid30.attr,
+	&format_attr_match_rnid4.attr,
+	&format_attr_match_dnid.attr,
+	&format_attr_match_mc.attr,
+	&format_attr_match_opc.attr,
+	&format_attr_match_vnw.attr,
+	&format_attr_match0.attr,
+	&format_attr_match1.attr,
+	&format_attr_mask_rds.attr,
+	&format_attr_mask_rnid30.attr,
+	&format_attr_mask_rnid4.attr,
+	&format_attr_mask_dnid.attr,
+	&format_attr_mask_mc.attr,
+	&format_attr_mask_opc.attr,
+	&format_attr_mask_vnw.attr,
+	&format_attr_mask0.attr,
+	&format_attr_mask1.attr,
+	NULL,
+};
+
+static struct attribute_group ivbep_uncore_format_group = {
+	.name = "format",
+	.attrs = ivbep_uncore_formats_attr,
+};
+
+static struct attribute_group ivbep_uncore_ubox_format_group = {
+	.name = "format",
+	.attrs = ivbep_uncore_ubox_formats_attr,
+};
+
+static struct attribute_group ivbep_uncore_cbox_format_group = {
+	.name = "format",
+	.attrs = ivbep_uncore_cbox_formats_attr,
+};
+
+static struct attribute_group ivbep_uncore_pcu_format_group = {
+	.name = "format",
+	.attrs = ivbep_uncore_pcu_formats_attr,
+};
+
+static struct attribute_group ivbep_uncore_qpi_format_group = {
+	.name = "format",
+	.attrs = ivbep_uncore_qpi_formats_attr,
+};
+
+static struct intel_uncore_type ivbep_uncore_ubox = {
+	.name		= "ubox",
+	.num_counters   = 2,
+	.num_boxes	= 1,
+	.perf_ctr_bits	= 44,
+	.fixed_ctr_bits	= 48,
+	.perf_ctr	= SNBEP_U_MSR_PMON_CTR0,
+	.event_ctl	= SNBEP_U_MSR_PMON_CTL0,
+	.event_mask	= IVBEP_U_MSR_PMON_RAW_EVENT_MASK,
+	.fixed_ctr	= SNBEP_U_MSR_PMON_UCLK_FIXED_CTR,
+	.fixed_ctl	= SNBEP_U_MSR_PMON_UCLK_FIXED_CTL,
+	.ops		= &ivbep_uncore_msr_ops,
+	.format_group	= &ivbep_uncore_ubox_format_group,
+};
+
+static struct extra_reg ivbep_uncore_cbox_extra_regs[] = {
+	SNBEP_CBO_EVENT_EXTRA_REG(SNBEP_CBO_PMON_CTL_TID_EN,
+				  SNBEP_CBO_PMON_CTL_TID_EN, 0x1),
+	SNBEP_CBO_EVENT_EXTRA_REG(0x1031, 0x10ff, 0x2),
+	SNBEP_CBO_EVENT_EXTRA_REG(0x1134, 0xffff, 0x4),
+	SNBEP_CBO_EVENT_EXTRA_REG(0x4134, 0xffff, 0xc),
+	SNBEP_CBO_EVENT_EXTRA_REG(0x5134, 0xffff, 0xc),
+	SNBEP_CBO_EVENT_EXTRA_REG(0x0334, 0xffff, 0x4),
+	SNBEP_CBO_EVENT_EXTRA_REG(0x4334, 0xffff, 0xc),
+	SNBEP_CBO_EVENT_EXTRA_REG(0x0534, 0xffff, 0x4),
+	SNBEP_CBO_EVENT_EXTRA_REG(0x4534, 0xffff, 0xc),
+	SNBEP_CBO_EVENT_EXTRA_REG(0x0934, 0xffff, 0x4),
+	SNBEP_CBO_EVENT_EXTRA_REG(0x4934, 0xffff, 0xc),
+	SNBEP_CBO_EVENT_EXTRA_REG(0x0135, 0xffff, 0x10),
+	SNBEP_CBO_EVENT_EXTRA_REG(0x0335, 0xffff, 0x10),
+	SNBEP_CBO_EVENT_EXTRA_REG(0x2135, 0xffff, 0x10),
+	SNBEP_CBO_EVENT_EXTRA_REG(0x2335, 0xffff, 0x10),
+	SNBEP_CBO_EVENT_EXTRA_REG(0x4135, 0xffff, 0x18),
+	SNBEP_CBO_EVENT_EXTRA_REG(0x4335, 0xffff, 0x18),
+	SNBEP_CBO_EVENT_EXTRA_REG(0x4435, 0xffff, 0x8),
+	SNBEP_CBO_EVENT_EXTRA_REG(0x4835, 0xffff, 0x8),
+	SNBEP_CBO_EVENT_EXTRA_REG(0x4a35, 0xffff, 0x8),
+	SNBEP_CBO_EVENT_EXTRA_REG(0x5035, 0xffff, 0x8),
+	SNBEP_CBO_EVENT_EXTRA_REG(0x8135, 0xffff, 0x10),
+	SNBEP_CBO_EVENT_EXTRA_REG(0x8335, 0xffff, 0x10),
+	SNBEP_CBO_EVENT_EXTRA_REG(0x0136, 0xffff, 0x10),
+	SNBEP_CBO_EVENT_EXTRA_REG(0x0336, 0xffff, 0x10),
+	SNBEP_CBO_EVENT_EXTRA_REG(0x2136, 0xffff, 0x10),
+	SNBEP_CBO_EVENT_EXTRA_REG(0x2336, 0xffff, 0x10),
+	SNBEP_CBO_EVENT_EXTRA_REG(0x4136, 0xffff, 0x18),
+	SNBEP_CBO_EVENT_EXTRA_REG(0x4336, 0xffff, 0x18),
+	SNBEP_CBO_EVENT_EXTRA_REG(0x4436, 0xffff, 0x8),
+	SNBEP_CBO_EVENT_EXTRA_REG(0x4836, 0xffff, 0x8),
+	SNBEP_CBO_EVENT_EXTRA_REG(0x4a36, 0xffff, 0x8),
+	SNBEP_CBO_EVENT_EXTRA_REG(0x5036, 0xffff, 0x8),
+	SNBEP_CBO_EVENT_EXTRA_REG(0x8136, 0xffff, 0x10),
+	SNBEP_CBO_EVENT_EXTRA_REG(0x8336, 0xffff, 0x10),
+	SNBEP_CBO_EVENT_EXTRA_REG(0x4037, 0x40ff, 0x8),
+	EVENT_EXTRA_END
+};
+
+static u64 ivbep_cbox_filter_mask(int fields)
+{
+	u64 mask = 0;
+
+	if (fields & 0x1)
+		mask |= IVBEP_CB0_MSR_PMON_BOX_FILTER_TID;
+	if (fields & 0x2)
+		mask |= IVBEP_CB0_MSR_PMON_BOX_FILTER_LINK;
+	if (fields & 0x4)
+		mask |= IVBEP_CB0_MSR_PMON_BOX_FILTER_STATE;
+	if (fields & 0x8)
+		mask |= IVBEP_CB0_MSR_PMON_BOX_FILTER_NID;
+	if (fields & 0x10) {
+		mask |= IVBEP_CB0_MSR_PMON_BOX_FILTER_OPC;
+		mask |= IVBEP_CB0_MSR_PMON_BOX_FILTER_NC;
+		mask |= IVBEP_CB0_MSR_PMON_BOX_FILTER_C6;
+		mask |= IVBEP_CB0_MSR_PMON_BOX_FILTER_ISOC;
+	}
+
+	return mask;
+}
+
+static struct event_constraint *
+ivbep_cbox_get_constraint(struct intel_uncore_box *box, struct perf_event *event)
+{
+	return __snbep_cbox_get_constraint(box, event, ivbep_cbox_filter_mask);
+}
+
+static int ivbep_cbox_hw_config(struct intel_uncore_box *box, struct perf_event *event)
+{
+	struct hw_perf_event_extra *reg1 = &event->hw.extra_reg;
+	struct extra_reg *er;
+	int idx = 0;
+
+	for (er = ivbep_uncore_cbox_extra_regs; er->msr; er++) {
+		if (er->event != (event->hw.config & er->config_mask))
+			continue;
+		idx |= er->idx;
+	}
+
+	if (idx) {
+		reg1->reg = SNBEP_C0_MSR_PMON_BOX_FILTER +
+			SNBEP_CBO_MSR_OFFSET * box->pmu->pmu_idx;
+		reg1->config = event->attr.config1 & ivbep_cbox_filter_mask(idx);
+		reg1->idx = idx;
+	}
+	return 0;
+}
+
+static void ivbep_cbox_enable_event(struct intel_uncore_box *box, struct perf_event *event)
+{
+	struct hw_perf_event *hwc = &event->hw;
+	struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
+
+	if (reg1->idx != EXTRA_REG_NONE) {
+		u64 filter = uncore_shared_reg_config(box, 0);
+		wrmsrl(reg1->reg, filter & 0xffffffff);
+		wrmsrl(reg1->reg + 6, filter >> 32);
+	}
+
+	wrmsrl(hwc->config_base, hwc->config | SNBEP_PMON_CTL_EN);
+}
+
+static struct intel_uncore_ops ivbep_uncore_cbox_ops = {
+	.init_box		= ivbep_uncore_msr_init_box,
+	.disable_box		= snbep_uncore_msr_disable_box,
+	.enable_box		= snbep_uncore_msr_enable_box,
+	.disable_event		= snbep_uncore_msr_disable_event,
+	.enable_event		= ivbep_cbox_enable_event,
+	.read_counter		= uncore_msr_read_counter,
+	.hw_config		= ivbep_cbox_hw_config,
+	.get_constraint		= ivbep_cbox_get_constraint,
+	.put_constraint		= snbep_cbox_put_constraint,
+};
+
+static struct intel_uncore_type ivbep_uncore_cbox = {
+	.name			= "cbox",
+	.num_counters		= 4,
+	.num_boxes		= 15,
+	.perf_ctr_bits		= 44,
+	.event_ctl		= SNBEP_C0_MSR_PMON_CTL0,
+	.perf_ctr		= SNBEP_C0_MSR_PMON_CTR0,
+	.event_mask		= IVBEP_CBO_MSR_PMON_RAW_EVENT_MASK,
+	.box_ctl		= SNBEP_C0_MSR_PMON_BOX_CTL,
+	.msr_offset		= SNBEP_CBO_MSR_OFFSET,
+	.num_shared_regs	= 1,
+	.constraints		= snbep_uncore_cbox_constraints,
+	.ops			= &ivbep_uncore_cbox_ops,
+	.format_group		= &ivbep_uncore_cbox_format_group,
+};
+
+static struct intel_uncore_ops ivbep_uncore_pcu_ops = {
+	IVBEP_UNCORE_MSR_OPS_COMMON_INIT(),
+	.hw_config		= snbep_pcu_hw_config,
+	.get_constraint		= snbep_pcu_get_constraint,
+	.put_constraint		= snbep_pcu_put_constraint,
+};
+
+static struct intel_uncore_type ivbep_uncore_pcu = {
+	.name			= "pcu",
+	.num_counters		= 4,
+	.num_boxes		= 1,
+	.perf_ctr_bits		= 48,
+	.perf_ctr		= SNBEP_PCU_MSR_PMON_CTR0,
+	.event_ctl		= SNBEP_PCU_MSR_PMON_CTL0,
+	.event_mask		= IVBEP_PCU_MSR_PMON_RAW_EVENT_MASK,
+	.box_ctl		= SNBEP_PCU_MSR_PMON_BOX_CTL,
+	.num_shared_regs	= 1,
+	.ops			= &ivbep_uncore_pcu_ops,
+	.format_group		= &ivbep_uncore_pcu_format_group,
+};
+
+static struct intel_uncore_type *ivbep_msr_uncores[] = {
+	&ivbep_uncore_ubox,
+	&ivbep_uncore_cbox,
+	&ivbep_uncore_pcu,
+	NULL,
+};
+
+void ivbep_uncore_cpu_init(void)
+{
+	if (ivbep_uncore_cbox.num_boxes > boot_cpu_data.x86_max_cores)
+		ivbep_uncore_cbox.num_boxes = boot_cpu_data.x86_max_cores;
+	uncore_msr_uncores = ivbep_msr_uncores;
+}
+
+static struct intel_uncore_type ivbep_uncore_ha = {
+	.name		= "ha",
+	.num_counters   = 4,
+	.num_boxes	= 2,
+	.perf_ctr_bits	= 48,
+	IVBEP_UNCORE_PCI_COMMON_INIT(),
+};
+
+static struct intel_uncore_type ivbep_uncore_imc = {
+	.name		= "imc",
+	.num_counters   = 4,
+	.num_boxes	= 8,
+	.perf_ctr_bits	= 48,
+	.fixed_ctr_bits	= 48,
+	.fixed_ctr	= SNBEP_MC_CHy_PCI_PMON_FIXED_CTR,
+	.fixed_ctl	= SNBEP_MC_CHy_PCI_PMON_FIXED_CTL,
+	.event_descs	= snbep_uncore_imc_events,
+	IVBEP_UNCORE_PCI_COMMON_INIT(),
+};
+
+/* registers in IRP boxes are not properly aligned */
+static unsigned ivbep_uncore_irp_ctls[] = {0xd8, 0xdc, 0xe0, 0xe4};
+static unsigned ivbep_uncore_irp_ctrs[] = {0xa0, 0xb0, 0xb8, 0xc0};
+
+static void ivbep_uncore_irp_enable_event(struct intel_uncore_box *box, struct perf_event *event)
+{
+	struct pci_dev *pdev = box->pci_dev;
+	struct hw_perf_event *hwc = &event->hw;
+
+	pci_write_config_dword(pdev, ivbep_uncore_irp_ctls[hwc->idx],
+			       hwc->config | SNBEP_PMON_CTL_EN);
+}
+
+static void ivbep_uncore_irp_disable_event(struct intel_uncore_box *box, struct perf_event *event)
+{
+	struct pci_dev *pdev = box->pci_dev;
+	struct hw_perf_event *hwc = &event->hw;
+
+	pci_write_config_dword(pdev, ivbep_uncore_irp_ctls[hwc->idx], hwc->config);
+}
+
+static u64 ivbep_uncore_irp_read_counter(struct intel_uncore_box *box, struct perf_event *event)
+{
+	struct pci_dev *pdev = box->pci_dev;
+	struct hw_perf_event *hwc = &event->hw;
+	u64 count = 0;
+
+	pci_read_config_dword(pdev, ivbep_uncore_irp_ctrs[hwc->idx], (u32 *)&count);
+	pci_read_config_dword(pdev, ivbep_uncore_irp_ctrs[hwc->idx] + 4, (u32 *)&count + 1);
+
+	return count;
+}
+
+static struct intel_uncore_ops ivbep_uncore_irp_ops = {
+	.init_box	= ivbep_uncore_pci_init_box,
+	.disable_box	= snbep_uncore_pci_disable_box,
+	.enable_box	= snbep_uncore_pci_enable_box,
+	.disable_event	= ivbep_uncore_irp_disable_event,
+	.enable_event	= ivbep_uncore_irp_enable_event,
+	.read_counter	= ivbep_uncore_irp_read_counter,
+};
+
+static struct intel_uncore_type ivbep_uncore_irp = {
+	.name			= "irp",
+	.num_counters		= 4,
+	.num_boxes		= 1,
+	.perf_ctr_bits		= 48,
+	.event_mask		= IVBEP_PMON_RAW_EVENT_MASK,
+	.box_ctl		= SNBEP_PCI_PMON_BOX_CTL,
+	.ops			= &ivbep_uncore_irp_ops,
+	.format_group		= &ivbep_uncore_format_group,
+};
+
+static struct intel_uncore_ops ivbep_uncore_qpi_ops = {
+	.init_box	= ivbep_uncore_pci_init_box,
+	.disable_box	= snbep_uncore_pci_disable_box,
+	.enable_box	= snbep_uncore_pci_enable_box,
+	.disable_event	= snbep_uncore_pci_disable_event,
+	.enable_event	= snbep_qpi_enable_event,
+	.read_counter	= snbep_uncore_pci_read_counter,
+	.hw_config	= snbep_qpi_hw_config,
+	.get_constraint	= uncore_get_constraint,
+	.put_constraint	= uncore_put_constraint,
+};
+
+static struct intel_uncore_type ivbep_uncore_qpi = {
+	.name			= "qpi",
+	.num_counters		= 4,
+	.num_boxes		= 3,
+	.perf_ctr_bits		= 48,
+	.perf_ctr		= SNBEP_PCI_PMON_CTR0,
+	.event_ctl		= SNBEP_PCI_PMON_CTL0,
+	.event_mask		= IVBEP_QPI_PCI_PMON_RAW_EVENT_MASK,
+	.box_ctl		= SNBEP_PCI_PMON_BOX_CTL,
+	.num_shared_regs	= 1,
+	.ops			= &ivbep_uncore_qpi_ops,
+	.format_group		= &ivbep_uncore_qpi_format_group,
+};
+
+static struct intel_uncore_type ivbep_uncore_r2pcie = {
+	.name		= "r2pcie",
+	.num_counters   = 4,
+	.num_boxes	= 1,
+	.perf_ctr_bits	= 44,
+	.constraints	= snbep_uncore_r2pcie_constraints,
+	IVBEP_UNCORE_PCI_COMMON_INIT(),
+};
+
+static struct intel_uncore_type ivbep_uncore_r3qpi = {
+	.name		= "r3qpi",
+	.num_counters   = 3,
+	.num_boxes	= 2,
+	.perf_ctr_bits	= 44,
+	.constraints	= snbep_uncore_r3qpi_constraints,
+	IVBEP_UNCORE_PCI_COMMON_INIT(),
+};
+
+enum {
+	IVBEP_PCI_UNCORE_HA,
+	IVBEP_PCI_UNCORE_IMC,
+	IVBEP_PCI_UNCORE_IRP,
+	IVBEP_PCI_UNCORE_QPI,
+	IVBEP_PCI_UNCORE_R2PCIE,
+	IVBEP_PCI_UNCORE_R3QPI,
+};
+
+static struct intel_uncore_type *ivbep_pci_uncores[] = {
+	[IVBEP_PCI_UNCORE_HA]	= &ivbep_uncore_ha,
+	[IVBEP_PCI_UNCORE_IMC]	= &ivbep_uncore_imc,
+	[IVBEP_PCI_UNCORE_IRP]	= &ivbep_uncore_irp,
+	[IVBEP_PCI_UNCORE_QPI]	= &ivbep_uncore_qpi,
+	[IVBEP_PCI_UNCORE_R2PCIE]	= &ivbep_uncore_r2pcie,
+	[IVBEP_PCI_UNCORE_R3QPI]	= &ivbep_uncore_r3qpi,
+	NULL,
+};
+
+static const struct pci_device_id ivbep_uncore_pci_ids[] = {
+	{ /* Home Agent 0 */
+		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe30),
+		.driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_HA, 0),
+	},
+	{ /* Home Agent 1 */
+		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe38),
+		.driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_HA, 1),
+	},
+	{ /* MC0 Channel 0 */
+		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xeb4),
+		.driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_IMC, 0),
+	},
+	{ /* MC0 Channel 1 */
+		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xeb5),
+		.driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_IMC, 1),
+	},
+	{ /* MC0 Channel 3 */
+		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xeb0),
+		.driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_IMC, 2),
+	},
+	{ /* MC0 Channel 4 */
+		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xeb1),
+		.driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_IMC, 3),
+	},
+	{ /* MC1 Channel 0 */
+		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xef4),
+		.driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_IMC, 4),
+	},
+	{ /* MC1 Channel 1 */
+		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xef5),
+		.driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_IMC, 5),
+	},
+	{ /* MC1 Channel 3 */
+		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xef0),
+		.driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_IMC, 6),
+	},
+	{ /* MC1 Channel 4 */
+		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xef1),
+		.driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_IMC, 7),
+	},
+	{ /* IRP */
+		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe39),
+		.driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_IRP, 0),
+	},
+	{ /* QPI0 Port 0 */
+		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe32),
+		.driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_QPI, 0),
+	},
+	{ /* QPI0 Port 1 */
+		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe33),
+		.driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_QPI, 1),
+	},
+	{ /* QPI1 Port 2 */
+		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe3a),
+		.driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_QPI, 2),
+	},
+	{ /* R2PCIe */
+		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe34),
+		.driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_R2PCIE, 0),
+	},
+	{ /* R3QPI0 Link 0 */
+		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe36),
+		.driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_R3QPI, 0),
+	},
+	{ /* R3QPI0 Link 1 */
+		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe37),
+		.driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_R3QPI, 1),
+	},
+	{ /* R3QPI1 Link 2 */
+		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe3e),
+		.driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_R3QPI, 2),
+	},
+	{ /* QPI Port 0 filter  */
+		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe86),
+		.driver_data = UNCORE_PCI_DEV_DATA(UNCORE_EXTRA_PCI_DEV,
+						   SNBEP_PCI_QPI_PORT0_FILTER),
+	},
+	{ /* QPI Port 0 filter  */
+		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe96),
+		.driver_data = UNCORE_PCI_DEV_DATA(UNCORE_EXTRA_PCI_DEV,
+						   SNBEP_PCI_QPI_PORT1_FILTER),
+	},
+	{ /* end: all zeroes */ }
+};
+
+static struct pci_driver ivbep_uncore_pci_driver = {
+	.name		= "ivbep_uncore",
+	.id_table	= ivbep_uncore_pci_ids,
+};
+
+int ivbep_uncore_pci_init(void)
+{
+	int ret = snbep_pci2phy_map_init(0x0e1e);
+	if (ret)
+		return ret;
+	uncore_pci_uncores = ivbep_pci_uncores;
+	uncore_pci_driver = &ivbep_uncore_pci_driver;
+	return 0;
+}
+/* end of IvyTown uncore support */
+
+/* KNL uncore support */
+static struct attribute *knl_uncore_ubox_formats_attr[] = {
+	&format_attr_event.attr,
+	&format_attr_umask.attr,
+	&format_attr_edge.attr,
+	&format_attr_tid_en.attr,
+	&format_attr_inv.attr,
+	&format_attr_thresh5.attr,
+	NULL,
+};
+
+static struct attribute_group knl_uncore_ubox_format_group = {
+	.name = "format",
+	.attrs = knl_uncore_ubox_formats_attr,
+};
+
+static struct intel_uncore_type knl_uncore_ubox = {
+	.name			= "ubox",
+	.num_counters		= 2,
+	.num_boxes		= 1,
+	.perf_ctr_bits		= 48,
+	.fixed_ctr_bits		= 48,
+	.perf_ctr		= HSWEP_U_MSR_PMON_CTR0,
+	.event_ctl		= HSWEP_U_MSR_PMON_CTL0,
+	.event_mask		= KNL_U_MSR_PMON_RAW_EVENT_MASK,
+	.fixed_ctr		= HSWEP_U_MSR_PMON_UCLK_FIXED_CTR,
+	.fixed_ctl		= HSWEP_U_MSR_PMON_UCLK_FIXED_CTL,
+	.ops			= &snbep_uncore_msr_ops,
+	.format_group		= &knl_uncore_ubox_format_group,
+};
+
+static struct attribute *knl_uncore_cha_formats_attr[] = {
+	&format_attr_event.attr,
+	&format_attr_umask.attr,
+	&format_attr_qor.attr,
+	&format_attr_edge.attr,
+	&format_attr_tid_en.attr,
+	&format_attr_inv.attr,
+	&format_attr_thresh8.attr,
+	&format_attr_filter_tid4.attr,
+	&format_attr_filter_link3.attr,
+	&format_attr_filter_state4.attr,
+	&format_attr_filter_local.attr,
+	&format_attr_filter_all_op.attr,
+	&format_attr_filter_nnm.attr,
+	&format_attr_filter_opc3.attr,
+	&format_attr_filter_nc.attr,
+	&format_attr_filter_isoc.attr,
+	NULL,
+};
+
+static struct attribute_group knl_uncore_cha_format_group = {
+	.name = "format",
+	.attrs = knl_uncore_cha_formats_attr,
+};
+
+static struct event_constraint knl_uncore_cha_constraints[] = {
+	UNCORE_EVENT_CONSTRAINT(0x11, 0x1),
+	UNCORE_EVENT_CONSTRAINT(0x1f, 0x1),
+	UNCORE_EVENT_CONSTRAINT(0x36, 0x1),
+	EVENT_CONSTRAINT_END
+};
+
+static struct extra_reg knl_uncore_cha_extra_regs[] = {
+	SNBEP_CBO_EVENT_EXTRA_REG(SNBEP_CBO_PMON_CTL_TID_EN,
+				  SNBEP_CBO_PMON_CTL_TID_EN, 0x1),
+	SNBEP_CBO_EVENT_EXTRA_REG(0x3d, 0xff, 0x2),
+	SNBEP_CBO_EVENT_EXTRA_REG(0x35, 0xff, 0x4),
+	SNBEP_CBO_EVENT_EXTRA_REG(0x36, 0xff, 0x4),
+	EVENT_EXTRA_END
+};
+
+static u64 knl_cha_filter_mask(int fields)
+{
+	u64 mask = 0;
+
+	if (fields & 0x1)
+		mask |= KNL_CHA_MSR_PMON_BOX_FILTER_TID;
+	if (fields & 0x2)
+		mask |= KNL_CHA_MSR_PMON_BOX_FILTER_STATE;
+	if (fields & 0x4)
+		mask |= KNL_CHA_MSR_PMON_BOX_FILTER_OP;
+	return mask;
+}
+
+static struct event_constraint *
+knl_cha_get_constraint(struct intel_uncore_box *box, struct perf_event *event)
+{
+	return __snbep_cbox_get_constraint(box, event, knl_cha_filter_mask);
+}
+
+static int knl_cha_hw_config(struct intel_uncore_box *box,
+			     struct perf_event *event)
+{
+	struct hw_perf_event_extra *reg1 = &event->hw.extra_reg;
+	struct extra_reg *er;
+	int idx = 0;
+
+	for (er = knl_uncore_cha_extra_regs; er->msr; er++) {
+		if (er->event != (event->hw.config & er->config_mask))
+			continue;
+		idx |= er->idx;
+	}
+
+	if (idx) {
+		reg1->reg = HSWEP_C0_MSR_PMON_BOX_FILTER0 +
+			    KNL_CHA_MSR_OFFSET * box->pmu->pmu_idx;
+		reg1->config = event->attr.config1 & knl_cha_filter_mask(idx);
+		reg1->idx = idx;
+	}
+	return 0;
+}
+
+static void hswep_cbox_enable_event(struct intel_uncore_box *box,
+				    struct perf_event *event);
+
+static struct intel_uncore_ops knl_uncore_cha_ops = {
+	.init_box		= snbep_uncore_msr_init_box,
+	.disable_box		= snbep_uncore_msr_disable_box,
+	.enable_box		= snbep_uncore_msr_enable_box,
+	.disable_event		= snbep_uncore_msr_disable_event,
+	.enable_event		= hswep_cbox_enable_event,
+	.read_counter		= uncore_msr_read_counter,
+	.hw_config		= knl_cha_hw_config,
+	.get_constraint		= knl_cha_get_constraint,
+	.put_constraint		= snbep_cbox_put_constraint,
+};
+
+static struct intel_uncore_type knl_uncore_cha = {
+	.name			= "cha",
+	.num_counters		= 4,
+	.num_boxes		= 38,
+	.perf_ctr_bits		= 48,
+	.event_ctl		= HSWEP_C0_MSR_PMON_CTL0,
+	.perf_ctr		= HSWEP_C0_MSR_PMON_CTR0,
+	.event_mask		= KNL_CHA_MSR_PMON_RAW_EVENT_MASK,
+	.box_ctl		= HSWEP_C0_MSR_PMON_BOX_CTL,
+	.msr_offset		= KNL_CHA_MSR_OFFSET,
+	.num_shared_regs	= 1,
+	.constraints		= knl_uncore_cha_constraints,
+	.ops			= &knl_uncore_cha_ops,
+	.format_group		= &knl_uncore_cha_format_group,
+};
+
+static struct attribute *knl_uncore_pcu_formats_attr[] = {
+	&format_attr_event2.attr,
+	&format_attr_use_occ_ctr.attr,
+	&format_attr_occ_sel.attr,
+	&format_attr_edge.attr,
+	&format_attr_tid_en.attr,
+	&format_attr_inv.attr,
+	&format_attr_thresh6.attr,
+	&format_attr_occ_invert.attr,
+	&format_attr_occ_edge_det.attr,
+	NULL,
+};
+
+static struct attribute_group knl_uncore_pcu_format_group = {
+	.name = "format",
+	.attrs = knl_uncore_pcu_formats_attr,
+};
+
+static struct intel_uncore_type knl_uncore_pcu = {
+	.name			= "pcu",
+	.num_counters		= 4,
+	.num_boxes		= 1,
+	.perf_ctr_bits		= 48,
+	.perf_ctr		= HSWEP_PCU_MSR_PMON_CTR0,
+	.event_ctl		= HSWEP_PCU_MSR_PMON_CTL0,
+	.event_mask		= KNL_PCU_MSR_PMON_RAW_EVENT_MASK,
+	.box_ctl		= HSWEP_PCU_MSR_PMON_BOX_CTL,
+	.ops			= &snbep_uncore_msr_ops,
+	.format_group		= &knl_uncore_pcu_format_group,
+};
+
+static struct intel_uncore_type *knl_msr_uncores[] = {
+	&knl_uncore_ubox,
+	&knl_uncore_cha,
+	&knl_uncore_pcu,
+	NULL,
+};
+
+void knl_uncore_cpu_init(void)
+{
+	uncore_msr_uncores = knl_msr_uncores;
+}
+
+static void knl_uncore_imc_enable_box(struct intel_uncore_box *box)
+{
+	struct pci_dev *pdev = box->pci_dev;
+	int box_ctl = uncore_pci_box_ctl(box);
+
+	pci_write_config_dword(pdev, box_ctl, 0);
+}
+
+static void knl_uncore_imc_enable_event(struct intel_uncore_box *box,
+					struct perf_event *event)
+{
+	struct pci_dev *pdev = box->pci_dev;
+	struct hw_perf_event *hwc = &event->hw;
+
+	if ((event->attr.config & SNBEP_PMON_CTL_EV_SEL_MASK)
+							== UNCORE_FIXED_EVENT)
+		pci_write_config_dword(pdev, hwc->config_base,
+				       hwc->config | KNL_PMON_FIXED_CTL_EN);
+	else
+		pci_write_config_dword(pdev, hwc->config_base,
+				       hwc->config | SNBEP_PMON_CTL_EN);
+}
+
+static struct intel_uncore_ops knl_uncore_imc_ops = {
+	.init_box	= snbep_uncore_pci_init_box,
+	.disable_box	= snbep_uncore_pci_disable_box,
+	.enable_box	= knl_uncore_imc_enable_box,
+	.read_counter	= snbep_uncore_pci_read_counter,
+	.enable_event	= knl_uncore_imc_enable_event,
+	.disable_event	= snbep_uncore_pci_disable_event,
+};
+
+static struct intel_uncore_type knl_uncore_imc_uclk = {
+	.name			= "imc_uclk",
+	.num_counters		= 4,
+	.num_boxes		= 2,
+	.perf_ctr_bits		= 48,
+	.fixed_ctr_bits		= 48,
+	.perf_ctr		= KNL_UCLK_MSR_PMON_CTR0_LOW,
+	.event_ctl		= KNL_UCLK_MSR_PMON_CTL0,
+	.event_mask		= SNBEP_PMON_RAW_EVENT_MASK,
+	.fixed_ctr		= KNL_UCLK_MSR_PMON_UCLK_FIXED_LOW,
+	.fixed_ctl		= KNL_UCLK_MSR_PMON_UCLK_FIXED_CTL,
+	.box_ctl		= KNL_UCLK_MSR_PMON_BOX_CTL,
+	.ops			= &knl_uncore_imc_ops,
+	.format_group		= &snbep_uncore_format_group,
+};
+
+static struct intel_uncore_type knl_uncore_imc_dclk = {
+	.name			= "imc",
+	.num_counters		= 4,
+	.num_boxes		= 6,
+	.perf_ctr_bits		= 48,
+	.fixed_ctr_bits		= 48,
+	.perf_ctr		= KNL_MC0_CH0_MSR_PMON_CTR0_LOW,
+	.event_ctl		= KNL_MC0_CH0_MSR_PMON_CTL0,
+	.event_mask		= SNBEP_PMON_RAW_EVENT_MASK,
+	.fixed_ctr		= KNL_MC0_CH0_MSR_PMON_FIXED_LOW,
+	.fixed_ctl		= KNL_MC0_CH0_MSR_PMON_FIXED_CTL,
+	.box_ctl		= KNL_MC0_CH0_MSR_PMON_BOX_CTL,
+	.ops			= &knl_uncore_imc_ops,
+	.format_group		= &snbep_uncore_format_group,
+};
+
+static struct intel_uncore_type knl_uncore_edc_uclk = {
+	.name			= "edc_uclk",
+	.num_counters		= 4,
+	.num_boxes		= 8,
+	.perf_ctr_bits		= 48,
+	.fixed_ctr_bits		= 48,
+	.perf_ctr		= KNL_UCLK_MSR_PMON_CTR0_LOW,
+	.event_ctl		= KNL_UCLK_MSR_PMON_CTL0,
+	.event_mask		= SNBEP_PMON_RAW_EVENT_MASK,
+	.fixed_ctr		= KNL_UCLK_MSR_PMON_UCLK_FIXED_LOW,
+	.fixed_ctl		= KNL_UCLK_MSR_PMON_UCLK_FIXED_CTL,
+	.box_ctl		= KNL_UCLK_MSR_PMON_BOX_CTL,
+	.ops			= &knl_uncore_imc_ops,
+	.format_group		= &snbep_uncore_format_group,
+};
+
+static struct intel_uncore_type knl_uncore_edc_eclk = {
+	.name			= "edc_eclk",
+	.num_counters		= 4,
+	.num_boxes		= 8,
+	.perf_ctr_bits		= 48,
+	.fixed_ctr_bits		= 48,
+	.perf_ctr		= KNL_EDC0_ECLK_MSR_PMON_CTR0_LOW,
+	.event_ctl		= KNL_EDC0_ECLK_MSR_PMON_CTL0,
+	.event_mask		= SNBEP_PMON_RAW_EVENT_MASK,
+	.fixed_ctr		= KNL_EDC0_ECLK_MSR_PMON_ECLK_FIXED_LOW,
+	.fixed_ctl		= KNL_EDC0_ECLK_MSR_PMON_ECLK_FIXED_CTL,
+	.box_ctl		= KNL_EDC0_ECLK_MSR_PMON_BOX_CTL,
+	.ops			= &knl_uncore_imc_ops,
+	.format_group		= &snbep_uncore_format_group,
+};
+
+static struct event_constraint knl_uncore_m2pcie_constraints[] = {
+	UNCORE_EVENT_CONSTRAINT(0x23, 0x3),
+	EVENT_CONSTRAINT_END
+};
+
+static struct intel_uncore_type knl_uncore_m2pcie = {
+	.name		= "m2pcie",
+	.num_counters   = 4,
+	.num_boxes	= 1,
+	.perf_ctr_bits	= 48,
+	.constraints	= knl_uncore_m2pcie_constraints,
+	SNBEP_UNCORE_PCI_COMMON_INIT(),
+};
+
+static struct attribute *knl_uncore_irp_formats_attr[] = {
+	&format_attr_event.attr,
+	&format_attr_umask.attr,
+	&format_attr_qor.attr,
+	&format_attr_edge.attr,
+	&format_attr_inv.attr,
+	&format_attr_thresh8.attr,
+	NULL,
+};
+
+static struct attribute_group knl_uncore_irp_format_group = {
+	.name = "format",
+	.attrs = knl_uncore_irp_formats_attr,
+};
+
+static struct intel_uncore_type knl_uncore_irp = {
+	.name			= "irp",
+	.num_counters		= 2,
+	.num_boxes		= 1,
+	.perf_ctr_bits		= 48,
+	.perf_ctr		= SNBEP_PCI_PMON_CTR0,
+	.event_ctl		= SNBEP_PCI_PMON_CTL0,
+	.event_mask		= KNL_IRP_PCI_PMON_RAW_EVENT_MASK,
+	.box_ctl		= KNL_IRP_PCI_PMON_BOX_CTL,
+	.ops			= &snbep_uncore_pci_ops,
+	.format_group		= &knl_uncore_irp_format_group,
+};
+
+enum {
+	KNL_PCI_UNCORE_MC_UCLK,
+	KNL_PCI_UNCORE_MC_DCLK,
+	KNL_PCI_UNCORE_EDC_UCLK,
+	KNL_PCI_UNCORE_EDC_ECLK,
+	KNL_PCI_UNCORE_M2PCIE,
+	KNL_PCI_UNCORE_IRP,
+};
+
+static struct intel_uncore_type *knl_pci_uncores[] = {
+	[KNL_PCI_UNCORE_MC_UCLK]	= &knl_uncore_imc_uclk,
+	[KNL_PCI_UNCORE_MC_DCLK]	= &knl_uncore_imc_dclk,
+	[KNL_PCI_UNCORE_EDC_UCLK]	= &knl_uncore_edc_uclk,
+	[KNL_PCI_UNCORE_EDC_ECLK]	= &knl_uncore_edc_eclk,
+	[KNL_PCI_UNCORE_M2PCIE]		= &knl_uncore_m2pcie,
+	[KNL_PCI_UNCORE_IRP]		= &knl_uncore_irp,
+	NULL,
+};
+
+/*
+ * KNL uses a common PCI device ID for multiple instances of an Uncore PMU
+ * device type. prior to KNL, each instance of a PMU device type had a unique
+ * device ID.
+ *
+ *	PCI Device ID	Uncore PMU Devices
+ *	----------------------------------
+ *	0x7841		MC0 UClk, MC1 UClk
+ *	0x7843		MC0 DClk CH 0, MC0 DClk CH 1, MC0 DClk CH 2,
+ *			MC1 DClk CH 0, MC1 DClk CH 1, MC1 DClk CH 2
+ *	0x7833		EDC0 UClk, EDC1 UClk, EDC2 UClk, EDC3 UClk,
+ *			EDC4 UClk, EDC5 UClk, EDC6 UClk, EDC7 UClk
+ *	0x7835		EDC0 EClk, EDC1 EClk, EDC2 EClk, EDC3 EClk,
+ *			EDC4 EClk, EDC5 EClk, EDC6 EClk, EDC7 EClk
+ *	0x7817		M2PCIe
+ *	0x7814		IRP
+*/
+
+static const struct pci_device_id knl_uncore_pci_ids[] = {
+	{ /* MC UClk */
+		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x7841),
+		.driver_data = UNCORE_PCI_DEV_DATA(KNL_PCI_UNCORE_MC_UCLK, 0),
+	},
+	{ /* MC DClk Channel */
+		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x7843),
+		.driver_data = UNCORE_PCI_DEV_DATA(KNL_PCI_UNCORE_MC_DCLK, 0),
+	},
+	{ /* EDC UClk */
+		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x7833),
+		.driver_data = UNCORE_PCI_DEV_DATA(KNL_PCI_UNCORE_EDC_UCLK, 0),
+	},
+	{ /* EDC EClk */
+		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x7835),
+		.driver_data = UNCORE_PCI_DEV_DATA(KNL_PCI_UNCORE_EDC_ECLK, 0),
+	},
+	{ /* M2PCIe */
+		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x7817),
+		.driver_data = UNCORE_PCI_DEV_DATA(KNL_PCI_UNCORE_M2PCIE, 0),
+	},
+	{ /* IRP */
+		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x7814),
+		.driver_data = UNCORE_PCI_DEV_DATA(KNL_PCI_UNCORE_IRP, 0),
+	},
+	{ /* end: all zeroes */ }
+};
+
+static struct pci_driver knl_uncore_pci_driver = {
+	.name		= "knl_uncore",
+	.id_table	= knl_uncore_pci_ids,
+};
+
+int knl_uncore_pci_init(void)
+{
+	int ret;
+
+	/* All KNL PCI based PMON units are on the same PCI bus except IRP */
+	ret = snb_pci2phy_map_init(0x7814); /* IRP */
+	if (ret)
+		return ret;
+	ret = snb_pci2phy_map_init(0x7817); /* M2PCIe */
+	if (ret)
+		return ret;
+	uncore_pci_uncores = knl_pci_uncores;
+	uncore_pci_driver = &knl_uncore_pci_driver;
+	return 0;
+}
+
+/* end of KNL uncore support */
+
+/* Haswell-EP uncore support */
+static struct attribute *hswep_uncore_ubox_formats_attr[] = {
+	&format_attr_event.attr,
+	&format_attr_umask.attr,
+	&format_attr_edge.attr,
+	&format_attr_inv.attr,
+	&format_attr_thresh5.attr,
+	&format_attr_filter_tid2.attr,
+	&format_attr_filter_cid.attr,
+	NULL,
+};
+
+static struct attribute_group hswep_uncore_ubox_format_group = {
+	.name = "format",
+	.attrs = hswep_uncore_ubox_formats_attr,
+};
+
+static int hswep_ubox_hw_config(struct intel_uncore_box *box, struct perf_event *event)
+{
+	struct hw_perf_event_extra *reg1 = &event->hw.extra_reg;
+	reg1->reg = HSWEP_U_MSR_PMON_FILTER;
+	reg1->config = event->attr.config1 & HSWEP_U_MSR_PMON_BOX_FILTER_MASK;
+	reg1->idx = 0;
+	return 0;
+}
+
+static struct intel_uncore_ops hswep_uncore_ubox_ops = {
+	SNBEP_UNCORE_MSR_OPS_COMMON_INIT(),
+	.hw_config		= hswep_ubox_hw_config,
+	.get_constraint		= uncore_get_constraint,
+	.put_constraint		= uncore_put_constraint,
+};
+
+static struct intel_uncore_type hswep_uncore_ubox = {
+	.name			= "ubox",
+	.num_counters		= 2,
+	.num_boxes		= 1,
+	.perf_ctr_bits		= 44,
+	.fixed_ctr_bits		= 48,
+	.perf_ctr		= HSWEP_U_MSR_PMON_CTR0,
+	.event_ctl		= HSWEP_U_MSR_PMON_CTL0,
+	.event_mask		= SNBEP_U_MSR_PMON_RAW_EVENT_MASK,
+	.fixed_ctr		= HSWEP_U_MSR_PMON_UCLK_FIXED_CTR,
+	.fixed_ctl		= HSWEP_U_MSR_PMON_UCLK_FIXED_CTL,
+	.num_shared_regs	= 1,
+	.ops			= &hswep_uncore_ubox_ops,
+	.format_group		= &hswep_uncore_ubox_format_group,
+};
+
+static struct attribute *hswep_uncore_cbox_formats_attr[] = {
+	&format_attr_event.attr,
+	&format_attr_umask.attr,
+	&format_attr_edge.attr,
+	&format_attr_tid_en.attr,
+	&format_attr_thresh8.attr,
+	&format_attr_filter_tid3.attr,
+	&format_attr_filter_link2.attr,
+	&format_attr_filter_state3.attr,
+	&format_attr_filter_nid2.attr,
+	&format_attr_filter_opc2.attr,
+	&format_attr_filter_nc.attr,
+	&format_attr_filter_c6.attr,
+	&format_attr_filter_isoc.attr,
+	NULL,
+};
+
+static struct attribute_group hswep_uncore_cbox_format_group = {
+	.name = "format",
+	.attrs = hswep_uncore_cbox_formats_attr,
+};
+
+static struct event_constraint hswep_uncore_cbox_constraints[] = {
+	UNCORE_EVENT_CONSTRAINT(0x01, 0x1),
+	UNCORE_EVENT_CONSTRAINT(0x09, 0x1),
+	UNCORE_EVENT_CONSTRAINT(0x11, 0x1),
+	UNCORE_EVENT_CONSTRAINT(0x36, 0x1),
+	UNCORE_EVENT_CONSTRAINT(0x38, 0x3),
+	UNCORE_EVENT_CONSTRAINT(0x3b, 0x1),
+	UNCORE_EVENT_CONSTRAINT(0x3e, 0x1),
+	EVENT_CONSTRAINT_END
+};
+
+static struct extra_reg hswep_uncore_cbox_extra_regs[] = {
+	SNBEP_CBO_EVENT_EXTRA_REG(SNBEP_CBO_PMON_CTL_TID_EN,
+				  SNBEP_CBO_PMON_CTL_TID_EN, 0x1),
+	SNBEP_CBO_EVENT_EXTRA_REG(0x0334, 0xffff, 0x4),
+	SNBEP_CBO_EVENT_EXTRA_REG(0x0534, 0xffff, 0x4),
+	SNBEP_CBO_EVENT_EXTRA_REG(0x0934, 0xffff, 0x4),
+	SNBEP_CBO_EVENT_EXTRA_REG(0x1134, 0xffff, 0x4),
+	SNBEP_CBO_EVENT_EXTRA_REG(0x2134, 0xffff, 0x4),
+	SNBEP_CBO_EVENT_EXTRA_REG(0x4134, 0xffff, 0x4),
+	SNBEP_CBO_EVENT_EXTRA_REG(0x4037, 0x40ff, 0x8),
+	SNBEP_CBO_EVENT_EXTRA_REG(0x4028, 0x40ff, 0x8),
+	SNBEP_CBO_EVENT_EXTRA_REG(0x4032, 0x40ff, 0x8),
+	SNBEP_CBO_EVENT_EXTRA_REG(0x4029, 0x40ff, 0x8),
+	SNBEP_CBO_EVENT_EXTRA_REG(0x4033, 0x40ff, 0x8),
+	SNBEP_CBO_EVENT_EXTRA_REG(0x402A, 0x40ff, 0x8),
+	SNBEP_CBO_EVENT_EXTRA_REG(0x0135, 0xffff, 0x12),
+	SNBEP_CBO_EVENT_EXTRA_REG(0x0335, 0xffff, 0x10),
+	SNBEP_CBO_EVENT_EXTRA_REG(0x4135, 0xffff, 0x18),
+	SNBEP_CBO_EVENT_EXTRA_REG(0x4435, 0xffff, 0x8),
+	SNBEP_CBO_EVENT_EXTRA_REG(0x4835, 0xffff, 0x8),
+	SNBEP_CBO_EVENT_EXTRA_REG(0x5035, 0xffff, 0x8),
+	SNBEP_CBO_EVENT_EXTRA_REG(0x4335, 0xffff, 0x18),
+	SNBEP_CBO_EVENT_EXTRA_REG(0x4a35, 0xffff, 0x8),
+	SNBEP_CBO_EVENT_EXTRA_REG(0x2335, 0xffff, 0x10),
+	SNBEP_CBO_EVENT_EXTRA_REG(0x8335, 0xffff, 0x10),
+	SNBEP_CBO_EVENT_EXTRA_REG(0x2135, 0xffff, 0x10),
+	SNBEP_CBO_EVENT_EXTRA_REG(0x8135, 0xffff, 0x10),
+	SNBEP_CBO_EVENT_EXTRA_REG(0x0136, 0xffff, 0x10),
+	SNBEP_CBO_EVENT_EXTRA_REG(0x0336, 0xffff, 0x10),
+	SNBEP_CBO_EVENT_EXTRA_REG(0x4136, 0xffff, 0x18),
+	SNBEP_CBO_EVENT_EXTRA_REG(0x4436, 0xffff, 0x8),
+	SNBEP_CBO_EVENT_EXTRA_REG(0x4836, 0xffff, 0x8),
+	SNBEP_CBO_EVENT_EXTRA_REG(0x4336, 0xffff, 0x18),
+	SNBEP_CBO_EVENT_EXTRA_REG(0x4a36, 0xffff, 0x8),
+	SNBEP_CBO_EVENT_EXTRA_REG(0x2336, 0xffff, 0x10),
+	SNBEP_CBO_EVENT_EXTRA_REG(0x8336, 0xffff, 0x10),
+	SNBEP_CBO_EVENT_EXTRA_REG(0x2136, 0xffff, 0x10),
+	SNBEP_CBO_EVENT_EXTRA_REG(0x8136, 0xffff, 0x10),
+	SNBEP_CBO_EVENT_EXTRA_REG(0x5036, 0xffff, 0x8),
+	EVENT_EXTRA_END
+};
+
+static u64 hswep_cbox_filter_mask(int fields)
+{
+	u64 mask = 0;
+	if (fields & 0x1)
+		mask |= HSWEP_CB0_MSR_PMON_BOX_FILTER_TID;
+	if (fields & 0x2)
+		mask |= HSWEP_CB0_MSR_PMON_BOX_FILTER_LINK;
+	if (fields & 0x4)
+		mask |= HSWEP_CB0_MSR_PMON_BOX_FILTER_STATE;
+	if (fields & 0x8)
+		mask |= HSWEP_CB0_MSR_PMON_BOX_FILTER_NID;
+	if (fields & 0x10) {
+		mask |= HSWEP_CB0_MSR_PMON_BOX_FILTER_OPC;
+		mask |= HSWEP_CB0_MSR_PMON_BOX_FILTER_NC;
+		mask |= HSWEP_CB0_MSR_PMON_BOX_FILTER_C6;
+		mask |= HSWEP_CB0_MSR_PMON_BOX_FILTER_ISOC;
+	}
+	return mask;
+}
+
+static struct event_constraint *
+hswep_cbox_get_constraint(struct intel_uncore_box *box, struct perf_event *event)
+{
+	return __snbep_cbox_get_constraint(box, event, hswep_cbox_filter_mask);
+}
+
+static int hswep_cbox_hw_config(struct intel_uncore_box *box, struct perf_event *event)
+{
+	struct hw_perf_event_extra *reg1 = &event->hw.extra_reg;
+	struct extra_reg *er;
+	int idx = 0;
+
+	for (er = hswep_uncore_cbox_extra_regs; er->msr; er++) {
+		if (er->event != (event->hw.config & er->config_mask))
+			continue;
+		idx |= er->idx;
+	}
+
+	if (idx) {
+		reg1->reg = HSWEP_C0_MSR_PMON_BOX_FILTER0 +
+			    HSWEP_CBO_MSR_OFFSET * box->pmu->pmu_idx;
+		reg1->config = event->attr.config1 & hswep_cbox_filter_mask(idx);
+		reg1->idx = idx;
+	}
+	return 0;
+}
+
+static void hswep_cbox_enable_event(struct intel_uncore_box *box,
+				  struct perf_event *event)
+{
+	struct hw_perf_event *hwc = &event->hw;
+	struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
+
+	if (reg1->idx != EXTRA_REG_NONE) {
+		u64 filter = uncore_shared_reg_config(box, 0);
+		wrmsrl(reg1->reg, filter & 0xffffffff);
+		wrmsrl(reg1->reg + 1, filter >> 32);
+	}
+
+	wrmsrl(hwc->config_base, hwc->config | SNBEP_PMON_CTL_EN);
+}
+
+static struct intel_uncore_ops hswep_uncore_cbox_ops = {
+	.init_box		= snbep_uncore_msr_init_box,
+	.disable_box		= snbep_uncore_msr_disable_box,
+	.enable_box		= snbep_uncore_msr_enable_box,
+	.disable_event		= snbep_uncore_msr_disable_event,
+	.enable_event		= hswep_cbox_enable_event,
+	.read_counter		= uncore_msr_read_counter,
+	.hw_config		= hswep_cbox_hw_config,
+	.get_constraint		= hswep_cbox_get_constraint,
+	.put_constraint		= snbep_cbox_put_constraint,
+};
+
+static struct intel_uncore_type hswep_uncore_cbox = {
+	.name			= "cbox",
+	.num_counters		= 4,
+	.num_boxes		= 18,
+	.perf_ctr_bits		= 48,
+	.event_ctl		= HSWEP_C0_MSR_PMON_CTL0,
+	.perf_ctr		= HSWEP_C0_MSR_PMON_CTR0,
+	.event_mask		= SNBEP_CBO_MSR_PMON_RAW_EVENT_MASK,
+	.box_ctl		= HSWEP_C0_MSR_PMON_BOX_CTL,
+	.msr_offset		= HSWEP_CBO_MSR_OFFSET,
+	.num_shared_regs	= 1,
+	.constraints		= hswep_uncore_cbox_constraints,
+	.ops			= &hswep_uncore_cbox_ops,
+	.format_group		= &hswep_uncore_cbox_format_group,
+};
+
+/*
+ * Write SBOX Initialization register bit by bit to avoid spurious #GPs
+ */
+static void hswep_uncore_sbox_msr_init_box(struct intel_uncore_box *box)
+{
+	unsigned msr = uncore_msr_box_ctl(box);
+
+	if (msr) {
+		u64 init = SNBEP_PMON_BOX_CTL_INT;
+		u64 flags = 0;
+		int i;
+
+		for_each_set_bit(i, (unsigned long *)&init, 64) {
+			flags |= (1ULL << i);
+			wrmsrl(msr, flags);
+		}
+	}
+}
+
+static struct intel_uncore_ops hswep_uncore_sbox_msr_ops = {
+	__SNBEP_UNCORE_MSR_OPS_COMMON_INIT(),
+	.init_box		= hswep_uncore_sbox_msr_init_box
+};
+
+static struct attribute *hswep_uncore_sbox_formats_attr[] = {
+	&format_attr_event.attr,
+	&format_attr_umask.attr,
+	&format_attr_edge.attr,
+	&format_attr_tid_en.attr,
+	&format_attr_inv.attr,
+	&format_attr_thresh8.attr,
+	NULL,
+};
+
+static struct attribute_group hswep_uncore_sbox_format_group = {
+	.name = "format",
+	.attrs = hswep_uncore_sbox_formats_attr,
+};
+
+static struct intel_uncore_type hswep_uncore_sbox = {
+	.name			= "sbox",
+	.num_counters		= 4,
+	.num_boxes		= 4,
+	.perf_ctr_bits		= 44,
+	.event_ctl		= HSWEP_S0_MSR_PMON_CTL0,
+	.perf_ctr		= HSWEP_S0_MSR_PMON_CTR0,
+	.event_mask		= HSWEP_S_MSR_PMON_RAW_EVENT_MASK,
+	.box_ctl		= HSWEP_S0_MSR_PMON_BOX_CTL,
+	.msr_offset		= HSWEP_SBOX_MSR_OFFSET,
+	.ops			= &hswep_uncore_sbox_msr_ops,
+	.format_group		= &hswep_uncore_sbox_format_group,
+};
+
+static int hswep_pcu_hw_config(struct intel_uncore_box *box, struct perf_event *event)
+{
+	struct hw_perf_event *hwc = &event->hw;
+	struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
+	int ev_sel = hwc->config & SNBEP_PMON_CTL_EV_SEL_MASK;
+
+	if (ev_sel >= 0xb && ev_sel <= 0xe) {
+		reg1->reg = HSWEP_PCU_MSR_PMON_BOX_FILTER;
+		reg1->idx = ev_sel - 0xb;
+		reg1->config = event->attr.config1 & (0xff << reg1->idx);
+	}
+	return 0;
+}
+
+static struct intel_uncore_ops hswep_uncore_pcu_ops = {
+	SNBEP_UNCORE_MSR_OPS_COMMON_INIT(),
+	.hw_config		= hswep_pcu_hw_config,
+	.get_constraint		= snbep_pcu_get_constraint,
+	.put_constraint		= snbep_pcu_put_constraint,
+};
+
+static struct intel_uncore_type hswep_uncore_pcu = {
+	.name			= "pcu",
+	.num_counters		= 4,
+	.num_boxes		= 1,
+	.perf_ctr_bits		= 48,
+	.perf_ctr		= HSWEP_PCU_MSR_PMON_CTR0,
+	.event_ctl		= HSWEP_PCU_MSR_PMON_CTL0,
+	.event_mask		= SNBEP_PCU_MSR_PMON_RAW_EVENT_MASK,
+	.box_ctl		= HSWEP_PCU_MSR_PMON_BOX_CTL,
+	.num_shared_regs	= 1,
+	.ops			= &hswep_uncore_pcu_ops,
+	.format_group		= &snbep_uncore_pcu_format_group,
+};
+
+static struct intel_uncore_type *hswep_msr_uncores[] = {
+	&hswep_uncore_ubox,
+	&hswep_uncore_cbox,
+	&hswep_uncore_sbox,
+	&hswep_uncore_pcu,
+	NULL,
+};
+
+void hswep_uncore_cpu_init(void)
+{
+	if (hswep_uncore_cbox.num_boxes > boot_cpu_data.x86_max_cores)
+		hswep_uncore_cbox.num_boxes = boot_cpu_data.x86_max_cores;
+
+	/* Detect 6-8 core systems with only two SBOXes */
+	if (uncore_extra_pci_dev[0][HSWEP_PCI_PCU_3]) {
+		u32 capid4;
+
+		pci_read_config_dword(uncore_extra_pci_dev[0][HSWEP_PCI_PCU_3],
+				      0x94, &capid4);
+		if (((capid4 >> 6) & 0x3) == 0)
+			hswep_uncore_sbox.num_boxes = 2;
+	}
+
+	uncore_msr_uncores = hswep_msr_uncores;
+}
+
+static struct intel_uncore_type hswep_uncore_ha = {
+	.name		= "ha",
+	.num_counters   = 5,
+	.num_boxes	= 2,
+	.perf_ctr_bits	= 48,
+	SNBEP_UNCORE_PCI_COMMON_INIT(),
+};
+
+static struct uncore_event_desc hswep_uncore_imc_events[] = {
+	INTEL_UNCORE_EVENT_DESC(clockticks,      "event=0x00,umask=0x00"),
+	INTEL_UNCORE_EVENT_DESC(cas_count_read,  "event=0x04,umask=0x03"),
+	INTEL_UNCORE_EVENT_DESC(cas_count_read.scale, "6.103515625e-5"),
+	INTEL_UNCORE_EVENT_DESC(cas_count_read.unit, "MiB"),
+	INTEL_UNCORE_EVENT_DESC(cas_count_write, "event=0x04,umask=0x0c"),
+	INTEL_UNCORE_EVENT_DESC(cas_count_write.scale, "6.103515625e-5"),
+	INTEL_UNCORE_EVENT_DESC(cas_count_write.unit, "MiB"),
+	{ /* end: all zeroes */ },
+};
+
+static struct intel_uncore_type hswep_uncore_imc = {
+	.name		= "imc",
+	.num_counters   = 5,
+	.num_boxes	= 8,
+	.perf_ctr_bits	= 48,
+	.fixed_ctr_bits	= 48,
+	.fixed_ctr	= SNBEP_MC_CHy_PCI_PMON_FIXED_CTR,
+	.fixed_ctl	= SNBEP_MC_CHy_PCI_PMON_FIXED_CTL,
+	.event_descs	= hswep_uncore_imc_events,
+	SNBEP_UNCORE_PCI_COMMON_INIT(),
+};
+
+static unsigned hswep_uncore_irp_ctrs[] = {0xa0, 0xa8, 0xb0, 0xb8};
+
+static u64 hswep_uncore_irp_read_counter(struct intel_uncore_box *box, struct perf_event *event)
+{
+	struct pci_dev *pdev = box->pci_dev;
+	struct hw_perf_event *hwc = &event->hw;
+	u64 count = 0;
+
+	pci_read_config_dword(pdev, hswep_uncore_irp_ctrs[hwc->idx], (u32 *)&count);
+	pci_read_config_dword(pdev, hswep_uncore_irp_ctrs[hwc->idx] + 4, (u32 *)&count + 1);
+
+	return count;
+}
+
+static struct intel_uncore_ops hswep_uncore_irp_ops = {
+	.init_box	= snbep_uncore_pci_init_box,
+	.disable_box	= snbep_uncore_pci_disable_box,
+	.enable_box	= snbep_uncore_pci_enable_box,
+	.disable_event	= ivbep_uncore_irp_disable_event,
+	.enable_event	= ivbep_uncore_irp_enable_event,
+	.read_counter	= hswep_uncore_irp_read_counter,
+};
+
+static struct intel_uncore_type hswep_uncore_irp = {
+	.name			= "irp",
+	.num_counters		= 4,
+	.num_boxes		= 1,
+	.perf_ctr_bits		= 48,
+	.event_mask		= SNBEP_PMON_RAW_EVENT_MASK,
+	.box_ctl		= SNBEP_PCI_PMON_BOX_CTL,
+	.ops			= &hswep_uncore_irp_ops,
+	.format_group		= &snbep_uncore_format_group,
+};
+
+static struct intel_uncore_type hswep_uncore_qpi = {
+	.name			= "qpi",
+	.num_counters		= 5,
+	.num_boxes		= 3,
+	.perf_ctr_bits		= 48,
+	.perf_ctr		= SNBEP_PCI_PMON_CTR0,
+	.event_ctl		= SNBEP_PCI_PMON_CTL0,
+	.event_mask		= SNBEP_QPI_PCI_PMON_RAW_EVENT_MASK,
+	.box_ctl		= SNBEP_PCI_PMON_BOX_CTL,
+	.num_shared_regs	= 1,
+	.ops			= &snbep_uncore_qpi_ops,
+	.format_group		= &snbep_uncore_qpi_format_group,
+};
+
+static struct event_constraint hswep_uncore_r2pcie_constraints[] = {
+	UNCORE_EVENT_CONSTRAINT(0x10, 0x3),
+	UNCORE_EVENT_CONSTRAINT(0x11, 0x3),
+	UNCORE_EVENT_CONSTRAINT(0x13, 0x1),
+	UNCORE_EVENT_CONSTRAINT(0x23, 0x1),
+	UNCORE_EVENT_CONSTRAINT(0x24, 0x1),
+	UNCORE_EVENT_CONSTRAINT(0x25, 0x1),
+	UNCORE_EVENT_CONSTRAINT(0x26, 0x3),
+	UNCORE_EVENT_CONSTRAINT(0x27, 0x1),
+	UNCORE_EVENT_CONSTRAINT(0x28, 0x3),
+	UNCORE_EVENT_CONSTRAINT(0x29, 0x3),
+	UNCORE_EVENT_CONSTRAINT(0x2a, 0x1),
+	UNCORE_EVENT_CONSTRAINT(0x2b, 0x3),
+	UNCORE_EVENT_CONSTRAINT(0x2c, 0x3),
+	UNCORE_EVENT_CONSTRAINT(0x2d, 0x3),
+	UNCORE_EVENT_CONSTRAINT(0x32, 0x3),
+	UNCORE_EVENT_CONSTRAINT(0x33, 0x3),
+	UNCORE_EVENT_CONSTRAINT(0x34, 0x3),
+	UNCORE_EVENT_CONSTRAINT(0x35, 0x3),
+	EVENT_CONSTRAINT_END
+};
+
+static struct intel_uncore_type hswep_uncore_r2pcie = {
+	.name		= "r2pcie",
+	.num_counters   = 4,
+	.num_boxes	= 1,
+	.perf_ctr_bits	= 48,
+	.constraints	= hswep_uncore_r2pcie_constraints,
+	SNBEP_UNCORE_PCI_COMMON_INIT(),
+};
+
+static struct event_constraint hswep_uncore_r3qpi_constraints[] = {
+	UNCORE_EVENT_CONSTRAINT(0x01, 0x3),
+	UNCORE_EVENT_CONSTRAINT(0x07, 0x7),
+	UNCORE_EVENT_CONSTRAINT(0x08, 0x7),
+	UNCORE_EVENT_CONSTRAINT(0x09, 0x7),
+	UNCORE_EVENT_CONSTRAINT(0x0a, 0x7),
+	UNCORE_EVENT_CONSTRAINT(0x0e, 0x7),
+	UNCORE_EVENT_CONSTRAINT(0x10, 0x3),
+	UNCORE_EVENT_CONSTRAINT(0x11, 0x3),
+	UNCORE_EVENT_CONSTRAINT(0x12, 0x3),
+	UNCORE_EVENT_CONSTRAINT(0x13, 0x1),
+	UNCORE_EVENT_CONSTRAINT(0x14, 0x3),
+	UNCORE_EVENT_CONSTRAINT(0x15, 0x3),
+	UNCORE_EVENT_CONSTRAINT(0x1f, 0x3),
+	UNCORE_EVENT_CONSTRAINT(0x20, 0x3),
+	UNCORE_EVENT_CONSTRAINT(0x21, 0x3),
+	UNCORE_EVENT_CONSTRAINT(0x22, 0x3),
+	UNCORE_EVENT_CONSTRAINT(0x23, 0x3),
+	UNCORE_EVENT_CONSTRAINT(0x25, 0x3),
+	UNCORE_EVENT_CONSTRAINT(0x26, 0x3),
+	UNCORE_EVENT_CONSTRAINT(0x28, 0x3),
+	UNCORE_EVENT_CONSTRAINT(0x29, 0x3),
+	UNCORE_EVENT_CONSTRAINT(0x2c, 0x3),
+	UNCORE_EVENT_CONSTRAINT(0x2d, 0x3),
+	UNCORE_EVENT_CONSTRAINT(0x2e, 0x3),
+	UNCORE_EVENT_CONSTRAINT(0x2f, 0x3),
+	UNCORE_EVENT_CONSTRAINT(0x31, 0x3),
+	UNCORE_EVENT_CONSTRAINT(0x32, 0x3),
+	UNCORE_EVENT_CONSTRAINT(0x33, 0x3),
+	UNCORE_EVENT_CONSTRAINT(0x34, 0x3),
+	UNCORE_EVENT_CONSTRAINT(0x36, 0x3),
+	UNCORE_EVENT_CONSTRAINT(0x37, 0x3),
+	UNCORE_EVENT_CONSTRAINT(0x38, 0x3),
+	UNCORE_EVENT_CONSTRAINT(0x39, 0x3),
+	EVENT_CONSTRAINT_END
+};
+
+static struct intel_uncore_type hswep_uncore_r3qpi = {
+	.name		= "r3qpi",
+	.num_counters   = 4,
+	.num_boxes	= 3,
+	.perf_ctr_bits	= 44,
+	.constraints	= hswep_uncore_r3qpi_constraints,
+	SNBEP_UNCORE_PCI_COMMON_INIT(),
+};
+
+enum {
+	HSWEP_PCI_UNCORE_HA,
+	HSWEP_PCI_UNCORE_IMC,
+	HSWEP_PCI_UNCORE_IRP,
+	HSWEP_PCI_UNCORE_QPI,
+	HSWEP_PCI_UNCORE_R2PCIE,
+	HSWEP_PCI_UNCORE_R3QPI,
+};
+
+static struct intel_uncore_type *hswep_pci_uncores[] = {
+	[HSWEP_PCI_UNCORE_HA]	= &hswep_uncore_ha,
+	[HSWEP_PCI_UNCORE_IMC]	= &hswep_uncore_imc,
+	[HSWEP_PCI_UNCORE_IRP]	= &hswep_uncore_irp,
+	[HSWEP_PCI_UNCORE_QPI]	= &hswep_uncore_qpi,
+	[HSWEP_PCI_UNCORE_R2PCIE]	= &hswep_uncore_r2pcie,
+	[HSWEP_PCI_UNCORE_R3QPI]	= &hswep_uncore_r3qpi,
+	NULL,
+};
+
+static const struct pci_device_id hswep_uncore_pci_ids[] = {
+	{ /* Home Agent 0 */
+		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2f30),
+		.driver_data = UNCORE_PCI_DEV_DATA(HSWEP_PCI_UNCORE_HA, 0),
+	},
+	{ /* Home Agent 1 */
+		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2f38),
+		.driver_data = UNCORE_PCI_DEV_DATA(HSWEP_PCI_UNCORE_HA, 1),
+	},
+	{ /* MC0 Channel 0 */
+		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2fb0),
+		.driver_data = UNCORE_PCI_DEV_DATA(HSWEP_PCI_UNCORE_IMC, 0),
+	},
+	{ /* MC0 Channel 1 */
+		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2fb1),
+		.driver_data = UNCORE_PCI_DEV_DATA(HSWEP_PCI_UNCORE_IMC, 1),
+	},
+	{ /* MC0 Channel 2 */
+		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2fb4),
+		.driver_data = UNCORE_PCI_DEV_DATA(HSWEP_PCI_UNCORE_IMC, 2),
+	},
+	{ /* MC0 Channel 3 */
+		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2fb5),
+		.driver_data = UNCORE_PCI_DEV_DATA(HSWEP_PCI_UNCORE_IMC, 3),
+	},
+	{ /* MC1 Channel 0 */
+		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2fd0),
+		.driver_data = UNCORE_PCI_DEV_DATA(HSWEP_PCI_UNCORE_IMC, 4),
+	},
+	{ /* MC1 Channel 1 */
+		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2fd1),
+		.driver_data = UNCORE_PCI_DEV_DATA(HSWEP_PCI_UNCORE_IMC, 5),
+	},
+	{ /* MC1 Channel 2 */
+		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2fd4),
+		.driver_data = UNCORE_PCI_DEV_DATA(HSWEP_PCI_UNCORE_IMC, 6),
+	},
+	{ /* MC1 Channel 3 */
+		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2fd5),
+		.driver_data = UNCORE_PCI_DEV_DATA(HSWEP_PCI_UNCORE_IMC, 7),
+	},
+	{ /* IRP */
+		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2f39),
+		.driver_data = UNCORE_PCI_DEV_DATA(HSWEP_PCI_UNCORE_IRP, 0),
+	},
+	{ /* QPI0 Port 0 */
+		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2f32),
+		.driver_data = UNCORE_PCI_DEV_DATA(HSWEP_PCI_UNCORE_QPI, 0),
+	},
+	{ /* QPI0 Port 1 */
+		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2f33),
+		.driver_data = UNCORE_PCI_DEV_DATA(HSWEP_PCI_UNCORE_QPI, 1),
+	},
+	{ /* QPI1 Port 2 */
+		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2f3a),
+		.driver_data = UNCORE_PCI_DEV_DATA(HSWEP_PCI_UNCORE_QPI, 2),
+	},
+	{ /* R2PCIe */
+		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2f34),
+		.driver_data = UNCORE_PCI_DEV_DATA(HSWEP_PCI_UNCORE_R2PCIE, 0),
+	},
+	{ /* R3QPI0 Link 0 */
+		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2f36),
+		.driver_data = UNCORE_PCI_DEV_DATA(HSWEP_PCI_UNCORE_R3QPI, 0),
+	},
+	{ /* R3QPI0 Link 1 */
+		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2f37),
+		.driver_data = UNCORE_PCI_DEV_DATA(HSWEP_PCI_UNCORE_R3QPI, 1),
+	},
+	{ /* R3QPI1 Link 2 */
+		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2f3e),
+		.driver_data = UNCORE_PCI_DEV_DATA(HSWEP_PCI_UNCORE_R3QPI, 2),
+	},
+	{ /* QPI Port 0 filter  */
+		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2f86),
+		.driver_data = UNCORE_PCI_DEV_DATA(UNCORE_EXTRA_PCI_DEV,
+						   SNBEP_PCI_QPI_PORT0_FILTER),
+	},
+	{ /* QPI Port 1 filter  */
+		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2f96),
+		.driver_data = UNCORE_PCI_DEV_DATA(UNCORE_EXTRA_PCI_DEV,
+						   SNBEP_PCI_QPI_PORT1_FILTER),
+	},
+	{ /* PCU.3 (for Capability registers) */
+		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2fc0),
+		.driver_data = UNCORE_PCI_DEV_DATA(UNCORE_EXTRA_PCI_DEV,
+						   HSWEP_PCI_PCU_3),
+	},
+	{ /* end: all zeroes */ }
+};
+
+static struct pci_driver hswep_uncore_pci_driver = {
+	.name		= "hswep_uncore",
+	.id_table	= hswep_uncore_pci_ids,
+};
+
+int hswep_uncore_pci_init(void)
+{
+	int ret = snbep_pci2phy_map_init(0x2f1e);
+	if (ret)
+		return ret;
+	uncore_pci_uncores = hswep_pci_uncores;
+	uncore_pci_driver = &hswep_uncore_pci_driver;
+	return 0;
+}
+/* end of Haswell-EP uncore support */
+
+/* BDX uncore support */
+
+static struct intel_uncore_type bdx_uncore_ubox = {
+	.name			= "ubox",
+	.num_counters		= 2,
+	.num_boxes		= 1,
+	.perf_ctr_bits		= 48,
+	.fixed_ctr_bits		= 48,
+	.perf_ctr		= HSWEP_U_MSR_PMON_CTR0,
+	.event_ctl		= HSWEP_U_MSR_PMON_CTL0,
+	.event_mask		= SNBEP_U_MSR_PMON_RAW_EVENT_MASK,
+	.fixed_ctr		= HSWEP_U_MSR_PMON_UCLK_FIXED_CTR,
+	.fixed_ctl		= HSWEP_U_MSR_PMON_UCLK_FIXED_CTL,
+	.num_shared_regs	= 1,
+	.ops			= &ivbep_uncore_msr_ops,
+	.format_group		= &ivbep_uncore_ubox_format_group,
+};
+
+static struct event_constraint bdx_uncore_cbox_constraints[] = {
+	UNCORE_EVENT_CONSTRAINT(0x09, 0x3),
+	UNCORE_EVENT_CONSTRAINT(0x11, 0x1),
+	UNCORE_EVENT_CONSTRAINT(0x36, 0x1),
+	UNCORE_EVENT_CONSTRAINT(0x3e, 0x1),
+	EVENT_CONSTRAINT_END
+};
+
+static struct intel_uncore_type bdx_uncore_cbox = {
+	.name			= "cbox",
+	.num_counters		= 4,
+	.num_boxes		= 24,
+	.perf_ctr_bits		= 48,
+	.event_ctl		= HSWEP_C0_MSR_PMON_CTL0,
+	.perf_ctr		= HSWEP_C0_MSR_PMON_CTR0,
+	.event_mask		= SNBEP_CBO_MSR_PMON_RAW_EVENT_MASK,
+	.box_ctl		= HSWEP_C0_MSR_PMON_BOX_CTL,
+	.msr_offset		= HSWEP_CBO_MSR_OFFSET,
+	.num_shared_regs	= 1,
+	.constraints		= bdx_uncore_cbox_constraints,
+	.ops			= &hswep_uncore_cbox_ops,
+	.format_group		= &hswep_uncore_cbox_format_group,
+};
+
+static struct intel_uncore_type bdx_uncore_sbox = {
+	.name			= "sbox",
+	.num_counters		= 4,
+	.num_boxes		= 4,
+	.perf_ctr_bits		= 48,
+	.event_ctl		= HSWEP_S0_MSR_PMON_CTL0,
+	.perf_ctr		= HSWEP_S0_MSR_PMON_CTR0,
+	.event_mask		= HSWEP_S_MSR_PMON_RAW_EVENT_MASK,
+	.box_ctl		= HSWEP_S0_MSR_PMON_BOX_CTL,
+	.msr_offset		= HSWEP_SBOX_MSR_OFFSET,
+	.ops			= &hswep_uncore_sbox_msr_ops,
+	.format_group		= &hswep_uncore_sbox_format_group,
+};
+
+static struct intel_uncore_type *bdx_msr_uncores[] = {
+	&bdx_uncore_ubox,
+	&bdx_uncore_cbox,
+	&bdx_uncore_sbox,
+	&hswep_uncore_pcu,
+	NULL,
+};
+
+void bdx_uncore_cpu_init(void)
+{
+	if (bdx_uncore_cbox.num_boxes > boot_cpu_data.x86_max_cores)
+		bdx_uncore_cbox.num_boxes = boot_cpu_data.x86_max_cores;
+	uncore_msr_uncores = bdx_msr_uncores;
+}
+
+static struct intel_uncore_type bdx_uncore_ha = {
+	.name		= "ha",
+	.num_counters   = 4,
+	.num_boxes	= 2,
+	.perf_ctr_bits	= 48,
+	SNBEP_UNCORE_PCI_COMMON_INIT(),
+};
+
+static struct intel_uncore_type bdx_uncore_imc = {
+	.name		= "imc",
+	.num_counters   = 5,
+	.num_boxes	= 8,
+	.perf_ctr_bits	= 48,
+	.fixed_ctr_bits	= 48,
+	.fixed_ctr	= SNBEP_MC_CHy_PCI_PMON_FIXED_CTR,
+	.fixed_ctl	= SNBEP_MC_CHy_PCI_PMON_FIXED_CTL,
+	.event_descs	= hswep_uncore_imc_events,
+	SNBEP_UNCORE_PCI_COMMON_INIT(),
+};
+
+static struct intel_uncore_type bdx_uncore_irp = {
+	.name			= "irp",
+	.num_counters		= 4,
+	.num_boxes		= 1,
+	.perf_ctr_bits		= 48,
+	.event_mask		= SNBEP_PMON_RAW_EVENT_MASK,
+	.box_ctl		= SNBEP_PCI_PMON_BOX_CTL,
+	.ops			= &hswep_uncore_irp_ops,
+	.format_group		= &snbep_uncore_format_group,
+};
+
+static struct intel_uncore_type bdx_uncore_qpi = {
+	.name			= "qpi",
+	.num_counters		= 4,
+	.num_boxes		= 3,
+	.perf_ctr_bits		= 48,
+	.perf_ctr		= SNBEP_PCI_PMON_CTR0,
+	.event_ctl		= SNBEP_PCI_PMON_CTL0,
+	.event_mask		= SNBEP_QPI_PCI_PMON_RAW_EVENT_MASK,
+	.box_ctl		= SNBEP_PCI_PMON_BOX_CTL,
+	.num_shared_regs	= 1,
+	.ops			= &snbep_uncore_qpi_ops,
+	.format_group		= &snbep_uncore_qpi_format_group,
+};
+
+static struct event_constraint bdx_uncore_r2pcie_constraints[] = {
+	UNCORE_EVENT_CONSTRAINT(0x10, 0x3),
+	UNCORE_EVENT_CONSTRAINT(0x11, 0x3),
+	UNCORE_EVENT_CONSTRAINT(0x13, 0x1),
+	UNCORE_EVENT_CONSTRAINT(0x23, 0x1),
+	UNCORE_EVENT_CONSTRAINT(0x25, 0x1),
+	UNCORE_EVENT_CONSTRAINT(0x26, 0x3),
+	UNCORE_EVENT_CONSTRAINT(0x28, 0x3),
+	UNCORE_EVENT_CONSTRAINT(0x2c, 0x3),
+	UNCORE_EVENT_CONSTRAINT(0x2d, 0x3),
+	EVENT_CONSTRAINT_END
+};
+
+static struct intel_uncore_type bdx_uncore_r2pcie = {
+	.name		= "r2pcie",
+	.num_counters   = 4,
+	.num_boxes	= 1,
+	.perf_ctr_bits	= 48,
+	.constraints	= bdx_uncore_r2pcie_constraints,
+	SNBEP_UNCORE_PCI_COMMON_INIT(),
+};
+
+static struct event_constraint bdx_uncore_r3qpi_constraints[] = {
+	UNCORE_EVENT_CONSTRAINT(0x01, 0x7),
+	UNCORE_EVENT_CONSTRAINT(0x07, 0x7),
+	UNCORE_EVENT_CONSTRAINT(0x08, 0x7),
+	UNCORE_EVENT_CONSTRAINT(0x09, 0x7),
+	UNCORE_EVENT_CONSTRAINT(0x0a, 0x7),
+	UNCORE_EVENT_CONSTRAINT(0x0e, 0x7),
+	UNCORE_EVENT_CONSTRAINT(0x10, 0x3),
+	UNCORE_EVENT_CONSTRAINT(0x11, 0x3),
+	UNCORE_EVENT_CONSTRAINT(0x13, 0x1),
+	UNCORE_EVENT_CONSTRAINT(0x14, 0x3),
+	UNCORE_EVENT_CONSTRAINT(0x15, 0x3),
+	UNCORE_EVENT_CONSTRAINT(0x1f, 0x3),
+	UNCORE_EVENT_CONSTRAINT(0x20, 0x3),
+	UNCORE_EVENT_CONSTRAINT(0x21, 0x3),
+	UNCORE_EVENT_CONSTRAINT(0x22, 0x3),
+	UNCORE_EVENT_CONSTRAINT(0x23, 0x3),
+	UNCORE_EVENT_CONSTRAINT(0x25, 0x3),
+	UNCORE_EVENT_CONSTRAINT(0x26, 0x3),
+	UNCORE_EVENT_CONSTRAINT(0x28, 0x3),
+	UNCORE_EVENT_CONSTRAINT(0x29, 0x3),
+	UNCORE_EVENT_CONSTRAINT(0x2c, 0x3),
+	UNCORE_EVENT_CONSTRAINT(0x2d, 0x3),
+	UNCORE_EVENT_CONSTRAINT(0x2e, 0x3),
+	UNCORE_EVENT_CONSTRAINT(0x2f, 0x3),
+	UNCORE_EVENT_CONSTRAINT(0x33, 0x3),
+	UNCORE_EVENT_CONSTRAINT(0x34, 0x3),
+	UNCORE_EVENT_CONSTRAINT(0x36, 0x3),
+	UNCORE_EVENT_CONSTRAINT(0x37, 0x3),
+	UNCORE_EVENT_CONSTRAINT(0x38, 0x3),
+	UNCORE_EVENT_CONSTRAINT(0x39, 0x3),
+	EVENT_CONSTRAINT_END
+};
+
+static struct intel_uncore_type bdx_uncore_r3qpi = {
+	.name		= "r3qpi",
+	.num_counters   = 3,
+	.num_boxes	= 3,
+	.perf_ctr_bits	= 48,
+	.constraints	= bdx_uncore_r3qpi_constraints,
+	SNBEP_UNCORE_PCI_COMMON_INIT(),
+};
+
+enum {
+	BDX_PCI_UNCORE_HA,
+	BDX_PCI_UNCORE_IMC,
+	BDX_PCI_UNCORE_IRP,
+	BDX_PCI_UNCORE_QPI,
+	BDX_PCI_UNCORE_R2PCIE,
+	BDX_PCI_UNCORE_R3QPI,
+};
+
+static struct intel_uncore_type *bdx_pci_uncores[] = {
+	[BDX_PCI_UNCORE_HA]	= &bdx_uncore_ha,
+	[BDX_PCI_UNCORE_IMC]	= &bdx_uncore_imc,
+	[BDX_PCI_UNCORE_IRP]	= &bdx_uncore_irp,
+	[BDX_PCI_UNCORE_QPI]	= &bdx_uncore_qpi,
+	[BDX_PCI_UNCORE_R2PCIE]	= &bdx_uncore_r2pcie,
+	[BDX_PCI_UNCORE_R3QPI]	= &bdx_uncore_r3qpi,
+	NULL,
+};
+
+static const struct pci_device_id bdx_uncore_pci_ids[] = {
+	{ /* Home Agent 0 */
+		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x6f30),
+		.driver_data = UNCORE_PCI_DEV_DATA(BDX_PCI_UNCORE_HA, 0),
+	},
+	{ /* Home Agent 1 */
+		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x6f38),
+		.driver_data = UNCORE_PCI_DEV_DATA(BDX_PCI_UNCORE_HA, 1),
+	},
+	{ /* MC0 Channel 0 */
+		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x6fb0),
+		.driver_data = UNCORE_PCI_DEV_DATA(BDX_PCI_UNCORE_IMC, 0),
+	},
+	{ /* MC0 Channel 1 */
+		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x6fb1),
+		.driver_data = UNCORE_PCI_DEV_DATA(BDX_PCI_UNCORE_IMC, 1),
+	},
+	{ /* MC0 Channel 2 */
+		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x6fb4),
+		.driver_data = UNCORE_PCI_DEV_DATA(BDX_PCI_UNCORE_IMC, 2),
+	},
+	{ /* MC0 Channel 3 */
+		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x6fb5),
+		.driver_data = UNCORE_PCI_DEV_DATA(BDX_PCI_UNCORE_IMC, 3),
+	},
+	{ /* MC1 Channel 0 */
+		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x6fd0),
+		.driver_data = UNCORE_PCI_DEV_DATA(BDX_PCI_UNCORE_IMC, 4),
+	},
+	{ /* MC1 Channel 1 */
+		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x6fd1),
+		.driver_data = UNCORE_PCI_DEV_DATA(BDX_PCI_UNCORE_IMC, 5),
+	},
+	{ /* MC1 Channel 2 */
+		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x6fd4),
+		.driver_data = UNCORE_PCI_DEV_DATA(BDX_PCI_UNCORE_IMC, 6),
+	},
+	{ /* MC1 Channel 3 */
+		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x6fd5),
+		.driver_data = UNCORE_PCI_DEV_DATA(BDX_PCI_UNCORE_IMC, 7),
+	},
+	{ /* IRP */
+		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x6f39),
+		.driver_data = UNCORE_PCI_DEV_DATA(BDX_PCI_UNCORE_IRP, 0),
+	},
+	{ /* QPI0 Port 0 */
+		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x6f32),
+		.driver_data = UNCORE_PCI_DEV_DATA(BDX_PCI_UNCORE_QPI, 0),
+	},
+	{ /* QPI0 Port 1 */
+		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x6f33),
+		.driver_data = UNCORE_PCI_DEV_DATA(BDX_PCI_UNCORE_QPI, 1),
+	},
+	{ /* QPI1 Port 2 */
+		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x6f3a),
+		.driver_data = UNCORE_PCI_DEV_DATA(BDX_PCI_UNCORE_QPI, 2),
+	},
+	{ /* R2PCIe */
+		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x6f34),
+		.driver_data = UNCORE_PCI_DEV_DATA(BDX_PCI_UNCORE_R2PCIE, 0),
+	},
+	{ /* R3QPI0 Link 0 */
+		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x6f36),
+		.driver_data = UNCORE_PCI_DEV_DATA(BDX_PCI_UNCORE_R3QPI, 0),
+	},
+	{ /* R3QPI0 Link 1 */
+		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x6f37),
+		.driver_data = UNCORE_PCI_DEV_DATA(BDX_PCI_UNCORE_R3QPI, 1),
+	},
+	{ /* R3QPI1 Link 2 */
+		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x6f3e),
+		.driver_data = UNCORE_PCI_DEV_DATA(BDX_PCI_UNCORE_R3QPI, 2),
+	},
+	{ /* QPI Port 0 filter  */
+		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x6f86),
+		.driver_data = UNCORE_PCI_DEV_DATA(UNCORE_EXTRA_PCI_DEV, 0),
+	},
+	{ /* QPI Port 1 filter  */
+		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x6f96),
+		.driver_data = UNCORE_PCI_DEV_DATA(UNCORE_EXTRA_PCI_DEV, 1),
+	},
+	{ /* QPI Port 2 filter  */
+		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x6f46),
+		.driver_data = UNCORE_PCI_DEV_DATA(UNCORE_EXTRA_PCI_DEV, 2),
+	},
+	{ /* end: all zeroes */ }
+};
+
+static struct pci_driver bdx_uncore_pci_driver = {
+	.name		= "bdx_uncore",
+	.id_table	= bdx_uncore_pci_ids,
+};
+
+int bdx_uncore_pci_init(void)
+{
+	int ret = snbep_pci2phy_map_init(0x6f1e);
+
+	if (ret)
+		return ret;
+	uncore_pci_uncores = bdx_pci_uncores;
+	uncore_pci_driver = &bdx_uncore_pci_driver;
+	return 0;
+}
+
+/* end of BDX uncore support */
--- /dev/null
+++ zfcpdump-kernel-4.4/arch/x86/events/msr.c
@@ -0,0 +1,241 @@
+#include <linux/perf_event.h>
+
+enum perf_msr_id {
+	PERF_MSR_TSC			= 0,
+	PERF_MSR_APERF			= 1,
+	PERF_MSR_MPERF			= 2,
+	PERF_MSR_PPERF			= 3,
+	PERF_MSR_SMI			= 4,
+
+	PERF_MSR_EVENT_MAX,
+};
+
+static bool test_aperfmperf(int idx)
+{
+	return boot_cpu_has(X86_FEATURE_APERFMPERF);
+}
+
+static bool test_intel(int idx)
+{
+	if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL ||
+	    boot_cpu_data.x86 != 6)
+		return false;
+
+	switch (boot_cpu_data.x86_model) {
+	case 30: /* 45nm Nehalem    */
+	case 26: /* 45nm Nehalem-EP */
+	case 46: /* 45nm Nehalem-EX */
+
+	case 37: /* 32nm Westmere    */
+	case 44: /* 32nm Westmere-EP */
+	case 47: /* 32nm Westmere-EX */
+
+	case 42: /* 32nm SandyBridge         */
+	case 45: /* 32nm SandyBridge-E/EN/EP */
+
+	case 58: /* 22nm IvyBridge       */
+	case 62: /* 22nm IvyBridge-EP/EX */
+
+	case 60: /* 22nm Haswell Core */
+	case 63: /* 22nm Haswell Server */
+	case 69: /* 22nm Haswell ULT */
+	case 70: /* 22nm Haswell + GT3e (Intel Iris Pro graphics) */
+
+	case 61: /* 14nm Broadwell Core-M */
+	case 86: /* 14nm Broadwell Xeon D */
+	case 71: /* 14nm Broadwell + GT3e (Intel Iris Pro graphics) */
+	case 79: /* 14nm Broadwell Server */
+
+	case 55: /* 22nm Atom "Silvermont"                */
+	case 77: /* 22nm Atom "Silvermont Avoton/Rangely" */
+	case 76: /* 14nm Atom "Airmont"                   */
+		if (idx == PERF_MSR_SMI)
+			return true;
+		break;
+
+	case 78: /* 14nm Skylake Mobile */
+	case 94: /* 14nm Skylake Desktop */
+		if (idx == PERF_MSR_SMI || idx == PERF_MSR_PPERF)
+			return true;
+		break;
+	}
+
+	return false;
+}
+
+struct perf_msr {
+	u64	msr;
+	struct	perf_pmu_events_attr *attr;
+	bool	(*test)(int idx);
+};
+
+PMU_EVENT_ATTR_STRING(tsc,   evattr_tsc,   "event=0x00");
+PMU_EVENT_ATTR_STRING(aperf, evattr_aperf, "event=0x01");
+PMU_EVENT_ATTR_STRING(mperf, evattr_mperf, "event=0x02");
+PMU_EVENT_ATTR_STRING(pperf, evattr_pperf, "event=0x03");
+PMU_EVENT_ATTR_STRING(smi,   evattr_smi,   "event=0x04");
+
+static struct perf_msr msr[] = {
+	[PERF_MSR_TSC]   = { 0,			&evattr_tsc,	NULL,		 },
+	[PERF_MSR_APERF] = { MSR_IA32_APERF,	&evattr_aperf,	test_aperfmperf, },
+	[PERF_MSR_MPERF] = { MSR_IA32_MPERF,	&evattr_mperf,	test_aperfmperf, },
+	[PERF_MSR_PPERF] = { MSR_PPERF,		&evattr_pperf,	test_intel,	 },
+	[PERF_MSR_SMI]   = { MSR_SMI_COUNT,	&evattr_smi,	test_intel,	 },
+};
+
+static struct attribute *events_attrs[PERF_MSR_EVENT_MAX + 1] = {
+	NULL,
+};
+
+static struct attribute_group events_attr_group = {
+	.name = "events",
+	.attrs = events_attrs,
+};
+
+PMU_FORMAT_ATTR(event, "config:0-63");
+static struct attribute *format_attrs[] = {
+	&format_attr_event.attr,
+	NULL,
+};
+static struct attribute_group format_attr_group = {
+	.name = "format",
+	.attrs = format_attrs,
+};
+
+static const struct attribute_group *attr_groups[] = {
+	&events_attr_group,
+	&format_attr_group,
+	NULL,
+};
+
+static int msr_event_init(struct perf_event *event)
+{
+	u64 cfg = event->attr.config;
+
+	if (event->attr.type != event->pmu->type)
+		return -ENOENT;
+
+	if (cfg >= PERF_MSR_EVENT_MAX)
+		return -EINVAL;
+
+	/* unsupported modes and filters */
+	if (event->attr.exclude_user   ||
+	    event->attr.exclude_kernel ||
+	    event->attr.exclude_hv     ||
+	    event->attr.exclude_idle   ||
+	    event->attr.exclude_host   ||
+	    event->attr.exclude_guest  ||
+	    event->attr.sample_period) /* no sampling */
+		return -EINVAL;
+
+	if (!msr[cfg].attr)
+		return -EINVAL;
+
+	event->hw.idx = -1;
+	event->hw.event_base = msr[cfg].msr;
+	event->hw.config = cfg;
+
+	return 0;
+}
+
+static inline u64 msr_read_counter(struct perf_event *event)
+{
+	u64 now;
+
+	if (event->hw.event_base)
+		rdmsrl(event->hw.event_base, now);
+	else
+		rdtscll(now);
+
+	return now;
+}
+static void msr_event_update(struct perf_event *event)
+{
+	u64 prev, now;
+	s64 delta;
+
+	/* Careful, an NMI might modify the previous event value. */
+again:
+	prev = local64_read(&event->hw.prev_count);
+	now = msr_read_counter(event);
+
+	if (local64_cmpxchg(&event->hw.prev_count, prev, now) != prev)
+		goto again;
+
+	delta = now - prev;
+	if (unlikely(event->hw.event_base == MSR_SMI_COUNT))
+		delta = sign_extend64(delta, 31);
+
+	local64_add(now - prev, &event->count);
+}
+
+static void msr_event_start(struct perf_event *event, int flags)
+{
+	u64 now;
+
+	now = msr_read_counter(event);
+	local64_set(&event->hw.prev_count, now);
+}
+
+static void msr_event_stop(struct perf_event *event, int flags)
+{
+	msr_event_update(event);
+}
+
+static void msr_event_del(struct perf_event *event, int flags)
+{
+	msr_event_stop(event, PERF_EF_UPDATE);
+}
+
+static int msr_event_add(struct perf_event *event, int flags)
+{
+	if (flags & PERF_EF_START)
+		msr_event_start(event, flags);
+
+	return 0;
+}
+
+static struct pmu pmu_msr = {
+	.task_ctx_nr	= perf_sw_context,
+	.attr_groups	= attr_groups,
+	.event_init	= msr_event_init,
+	.add		= msr_event_add,
+	.del		= msr_event_del,
+	.start		= msr_event_start,
+	.stop		= msr_event_stop,
+	.read		= msr_event_update,
+	.capabilities	= PERF_PMU_CAP_NO_INTERRUPT,
+};
+
+static int __init msr_init(void)
+{
+	int i, j = 0;
+
+	if (!boot_cpu_has(X86_FEATURE_TSC)) {
+		pr_cont("no MSR PMU driver.\n");
+		return 0;
+	}
+
+	/* Probe the MSRs. */
+	for (i = PERF_MSR_TSC + 1; i < PERF_MSR_EVENT_MAX; i++) {
+		u64 val;
+
+		/*
+		 * Virt sucks arse; you cannot tell if a R/O MSR is present :/
+		 */
+		if (!msr[i].test(i) || rdmsrl_safe(msr[i].msr, &val))
+			msr[i].attr = NULL;
+	}
+
+	/* List remaining MSRs in the sysfs attrs. */
+	for (i = 0; i < PERF_MSR_EVENT_MAX; i++) {
+		if (msr[i].attr)
+			events_attrs[j++] = &msr[i].attr->attr.attr;
+	}
+	events_attrs[j] = NULL;
+
+	perf_pmu_register(&pmu_msr, "msr", -1);
+
+	return 0;
+}
+device_initcall(msr_init);
--- /dev/null
+++ zfcpdump-kernel-4.4/arch/x86/events/perf_event.h
@@ -0,0 +1,963 @@
+/*
+ * Performance events x86 architecture header
+ *
+ *  Copyright (C) 2008 Thomas Gleixner <tglx@linutronix.de>
+ *  Copyright (C) 2008-2009 Red Hat, Inc., Ingo Molnar
+ *  Copyright (C) 2009 Jaswinder Singh Rajput
+ *  Copyright (C) 2009 Advanced Micro Devices, Inc., Robert Richter
+ *  Copyright (C) 2008-2009 Red Hat, Inc., Peter Zijlstra
+ *  Copyright (C) 2009 Intel Corporation, <markus.t.metzger@intel.com>
+ *  Copyright (C) 2009 Google, Inc., Stephane Eranian
+ *
+ *  For licencing details see kernel-base/COPYING
+ */
+
+#include <linux/perf_event.h>
+
+#if 0
+#undef wrmsrl
+#define wrmsrl(msr, val) 						\
+do {									\
+	unsigned int _msr = (msr);					\
+	u64 _val = (val);						\
+	trace_printk("wrmsrl(%x, %Lx)\n", (unsigned int)(_msr),		\
+			(unsigned long long)(_val));			\
+	native_write_msr((_msr), (u32)(_val), (u32)(_val >> 32));	\
+} while (0)
+#endif
+
+/*
+ *          |   NHM/WSM    |      SNB     |
+ * register -------------------------------
+ *          |  HT  | no HT |  HT  | no HT |
+ *-----------------------------------------
+ * offcore  | core | core  | cpu  | core  |
+ * lbr_sel  | core | core  | cpu  | core  |
+ * ld_lat   | cpu  | core  | cpu  | core  |
+ *-----------------------------------------
+ *
+ * Given that there is a small number of shared regs,
+ * we can pre-allocate their slot in the per-cpu
+ * per-core reg tables.
+ */
+enum extra_reg_type {
+	EXTRA_REG_NONE  = -1,	/* not used */
+
+	EXTRA_REG_RSP_0 = 0,	/* offcore_response_0 */
+	EXTRA_REG_RSP_1 = 1,	/* offcore_response_1 */
+	EXTRA_REG_LBR   = 2,	/* lbr_select */
+	EXTRA_REG_LDLAT = 3,	/* ld_lat_threshold */
+	EXTRA_REG_FE    = 4,    /* fe_* */
+
+	EXTRA_REG_MAX		/* number of entries needed */
+};
+
+struct event_constraint {
+	union {
+		unsigned long	idxmsk[BITS_TO_LONGS(X86_PMC_IDX_MAX)];
+		u64		idxmsk64;
+	};
+	u64	code;
+	u64	cmask;
+	int	weight;
+	int	overlap;
+	int	flags;
+};
+/*
+ * struct hw_perf_event.flags flags
+ */
+#define PERF_X86_EVENT_PEBS_LDLAT	0x0001 /* ld+ldlat data address sampling */
+#define PERF_X86_EVENT_PEBS_ST		0x0002 /* st data address sampling */
+#define PERF_X86_EVENT_PEBS_ST_HSW	0x0004 /* haswell style datala, store */
+#define PERF_X86_EVENT_COMMITTED	0x0008 /* event passed commit_txn */
+#define PERF_X86_EVENT_PEBS_LD_HSW	0x0010 /* haswell style datala, load */
+#define PERF_X86_EVENT_PEBS_NA_HSW	0x0020 /* haswell style datala, unknown */
+#define PERF_X86_EVENT_EXCL		0x0040 /* HT exclusivity on counter */
+#define PERF_X86_EVENT_DYNAMIC		0x0080 /* dynamic alloc'd constraint */
+#define PERF_X86_EVENT_RDPMC_ALLOWED	0x0100 /* grant rdpmc permission */
+#define PERF_X86_EVENT_EXCL_ACCT	0x0200 /* accounted EXCL event */
+#define PERF_X86_EVENT_AUTO_RELOAD	0x0400 /* use PEBS auto-reload */
+#define PERF_X86_EVENT_FREERUNNING	0x0800 /* use freerunning PEBS */
+
+
+struct amd_nb {
+	int nb_id;  /* NorthBridge id */
+	int refcnt; /* reference count */
+	struct perf_event *owners[X86_PMC_IDX_MAX];
+	struct event_constraint event_constraints[X86_PMC_IDX_MAX];
+};
+
+/* The maximal number of PEBS events: */
+#define MAX_PEBS_EVENTS		8
+
+/*
+ * Flags PEBS can handle without an PMI.
+ *
+ * TID can only be handled by flushing at context switch.
+ *
+ */
+#define PEBS_FREERUNNING_FLAGS \
+	(PERF_SAMPLE_IP | PERF_SAMPLE_TID | PERF_SAMPLE_ADDR | \
+	PERF_SAMPLE_ID | PERF_SAMPLE_CPU | PERF_SAMPLE_STREAM_ID | \
+	PERF_SAMPLE_DATA_SRC | PERF_SAMPLE_IDENTIFIER | \
+	PERF_SAMPLE_TRANSACTION)
+
+/*
+ * A debug store configuration.
+ *
+ * We only support architectures that use 64bit fields.
+ */
+struct debug_store {
+	u64	bts_buffer_base;
+	u64	bts_index;
+	u64	bts_absolute_maximum;
+	u64	bts_interrupt_threshold;
+	u64	pebs_buffer_base;
+	u64	pebs_index;
+	u64	pebs_absolute_maximum;
+	u64	pebs_interrupt_threshold;
+	u64	pebs_event_reset[MAX_PEBS_EVENTS];
+};
+
+/*
+ * Per register state.
+ */
+struct er_account {
+	raw_spinlock_t		lock;	/* per-core: protect structure */
+	u64                 config;	/* extra MSR config */
+	u64                 reg;	/* extra MSR number */
+	atomic_t            ref;	/* reference count */
+};
+
+/*
+ * Per core/cpu state
+ *
+ * Used to coordinate shared registers between HT threads or
+ * among events on a single PMU.
+ */
+struct intel_shared_regs {
+	struct er_account       regs[EXTRA_REG_MAX];
+	int                     refcnt;		/* per-core: #HT threads */
+	unsigned                core_id;	/* per-core: core id */
+};
+
+enum intel_excl_state_type {
+	INTEL_EXCL_UNUSED    = 0, /* counter is unused */
+	INTEL_EXCL_SHARED    = 1, /* counter can be used by both threads */
+	INTEL_EXCL_EXCLUSIVE = 2, /* counter can be used by one thread only */
+};
+
+struct intel_excl_states {
+	enum intel_excl_state_type state[X86_PMC_IDX_MAX];
+	bool sched_started; /* true if scheduling has started */
+};
+
+struct intel_excl_cntrs {
+	raw_spinlock_t	lock;
+
+	struct intel_excl_states states[2];
+
+	union {
+		u16	has_exclusive[2];
+		u32	exclusive_present;
+	};
+
+	int		refcnt;		/* per-core: #HT threads */
+	unsigned	core_id;	/* per-core: core id */
+};
+
+#define MAX_LBR_ENTRIES		32
+
+enum {
+	X86_PERF_KFREE_SHARED = 0,
+	X86_PERF_KFREE_EXCL   = 1,
+	X86_PERF_KFREE_MAX
+};
+
+struct cpu_hw_events {
+	/*
+	 * Generic x86 PMC bits
+	 */
+	struct perf_event	*events[X86_PMC_IDX_MAX]; /* in counter order */
+	unsigned long		active_mask[BITS_TO_LONGS(X86_PMC_IDX_MAX)];
+	unsigned long		running[BITS_TO_LONGS(X86_PMC_IDX_MAX)];
+	int			enabled;
+
+	int			n_events; /* the # of events in the below arrays */
+	int			n_added;  /* the # last events in the below arrays;
+					     they've never been enabled yet */
+	int			n_txn;    /* the # last events in the below arrays;
+					     added in the current transaction */
+	int			assign[X86_PMC_IDX_MAX]; /* event to counter assignment */
+	u64			tags[X86_PMC_IDX_MAX];
+
+	struct perf_event	*event_list[X86_PMC_IDX_MAX]; /* in enabled order */
+	struct event_constraint	*event_constraint[X86_PMC_IDX_MAX];
+
+	int			n_excl; /* the number of exclusive events */
+
+	unsigned int		txn_flags;
+	int			is_fake;
+
+	/*
+	 * Intel DebugStore bits
+	 */
+	struct debug_store	*ds;
+	u64			pebs_enabled;
+
+	/*
+	 * Intel LBR bits
+	 */
+	int				lbr_users;
+	void				*lbr_context;
+	struct perf_branch_stack	lbr_stack;
+	struct perf_branch_entry	lbr_entries[MAX_LBR_ENTRIES];
+	struct er_account		*lbr_sel;
+	u64				br_sel;
+
+	/*
+	 * Intel host/guest exclude bits
+	 */
+	u64				intel_ctrl_guest_mask;
+	u64				intel_ctrl_host_mask;
+	struct perf_guest_switch_msr	guest_switch_msrs[X86_PMC_IDX_MAX];
+
+	/*
+	 * Intel checkpoint mask
+	 */
+	u64				intel_cp_status;
+
+	/*
+	 * manage shared (per-core, per-cpu) registers
+	 * used on Intel NHM/WSM/SNB
+	 */
+	struct intel_shared_regs	*shared_regs;
+	/*
+	 * manage exclusive counter access between hyperthread
+	 */
+	struct event_constraint *constraint_list; /* in enable order */
+	struct intel_excl_cntrs		*excl_cntrs;
+	int excl_thread_id; /* 0 or 1 */
+
+	/*
+	 * AMD specific bits
+	 */
+	struct amd_nb			*amd_nb;
+	/* Inverted mask of bits to clear in the perf_ctr ctrl registers */
+	u64				perf_ctr_virt_mask;
+
+	void				*kfree_on_online[X86_PERF_KFREE_MAX];
+};
+
+#define __EVENT_CONSTRAINT(c, n, m, w, o, f) {\
+	{ .idxmsk64 = (n) },		\
+	.code = (c),			\
+	.cmask = (m),			\
+	.weight = (w),			\
+	.overlap = (o),			\
+	.flags = f,			\
+}
+
+#define EVENT_CONSTRAINT(c, n, m)	\
+	__EVENT_CONSTRAINT(c, n, m, HWEIGHT(n), 0, 0)
+
+#define INTEL_EXCLEVT_CONSTRAINT(c, n)	\
+	__EVENT_CONSTRAINT(c, n, ARCH_PERFMON_EVENTSEL_EVENT, HWEIGHT(n),\
+			   0, PERF_X86_EVENT_EXCL)
+
+/*
+ * The overlap flag marks event constraints with overlapping counter
+ * masks. This is the case if the counter mask of such an event is not
+ * a subset of any other counter mask of a constraint with an equal or
+ * higher weight, e.g.:
+ *
+ *  c_overlaps = EVENT_CONSTRAINT_OVERLAP(0, 0x09, 0);
+ *  c_another1 = EVENT_CONSTRAINT(0, 0x07, 0);
+ *  c_another2 = EVENT_CONSTRAINT(0, 0x38, 0);
+ *
+ * The event scheduler may not select the correct counter in the first
+ * cycle because it needs to know which subsequent events will be
+ * scheduled. It may fail to schedule the events then. So we set the
+ * overlap flag for such constraints to give the scheduler a hint which
+ * events to select for counter rescheduling.
+ *
+ * Care must be taken as the rescheduling algorithm is O(n!) which
+ * will increase scheduling cycles for an over-commited system
+ * dramatically.  The number of such EVENT_CONSTRAINT_OVERLAP() macros
+ * and its counter masks must be kept at a minimum.
+ */
+#define EVENT_CONSTRAINT_OVERLAP(c, n, m)	\
+	__EVENT_CONSTRAINT(c, n, m, HWEIGHT(n), 1, 0)
+
+/*
+ * Constraint on the Event code.
+ */
+#define INTEL_EVENT_CONSTRAINT(c, n)	\
+	EVENT_CONSTRAINT(c, n, ARCH_PERFMON_EVENTSEL_EVENT)
+
+/*
+ * Constraint on the Event code + UMask + fixed-mask
+ *
+ * filter mask to validate fixed counter events.
+ * the following filters disqualify for fixed counters:
+ *  - inv
+ *  - edge
+ *  - cnt-mask
+ *  - in_tx
+ *  - in_tx_checkpointed
+ *  The other filters are supported by fixed counters.
+ *  The any-thread option is supported starting with v3.
+ */
+#define FIXED_EVENT_FLAGS (X86_RAW_EVENT_MASK|HSW_IN_TX|HSW_IN_TX_CHECKPOINTED)
+#define FIXED_EVENT_CONSTRAINT(c, n)	\
+	EVENT_CONSTRAINT(c, (1ULL << (32+n)), FIXED_EVENT_FLAGS)
+
+/*
+ * Constraint on the Event code + UMask
+ */
+#define INTEL_UEVENT_CONSTRAINT(c, n)	\
+	EVENT_CONSTRAINT(c, n, INTEL_ARCH_EVENT_MASK)
+
+/* Like UEVENT_CONSTRAINT, but match flags too */
+#define INTEL_FLAGS_UEVENT_CONSTRAINT(c, n)	\
+	EVENT_CONSTRAINT(c, n, INTEL_ARCH_EVENT_MASK|X86_ALL_EVENT_FLAGS)
+
+#define INTEL_EXCLUEVT_CONSTRAINT(c, n)	\
+	__EVENT_CONSTRAINT(c, n, INTEL_ARCH_EVENT_MASK, \
+			   HWEIGHT(n), 0, PERF_X86_EVENT_EXCL)
+
+#define INTEL_PLD_CONSTRAINT(c, n)	\
+	__EVENT_CONSTRAINT(c, n, INTEL_ARCH_EVENT_MASK|X86_ALL_EVENT_FLAGS, \
+			   HWEIGHT(n), 0, PERF_X86_EVENT_PEBS_LDLAT)
+
+#define INTEL_PST_CONSTRAINT(c, n)	\
+	__EVENT_CONSTRAINT(c, n, INTEL_ARCH_EVENT_MASK|X86_ALL_EVENT_FLAGS, \
+			  HWEIGHT(n), 0, PERF_X86_EVENT_PEBS_ST)
+
+/* Event constraint, but match on all event flags too. */
+#define INTEL_FLAGS_EVENT_CONSTRAINT(c, n) \
+	EVENT_CONSTRAINT(c, n, INTEL_ARCH_EVENT_MASK|X86_ALL_EVENT_FLAGS)
+
+/* Check only flags, but allow all event/umask */
+#define INTEL_ALL_EVENT_CONSTRAINT(code, n)	\
+	EVENT_CONSTRAINT(code, n, X86_ALL_EVENT_FLAGS)
+
+/* Check flags and event code, and set the HSW store flag */
+#define INTEL_FLAGS_EVENT_CONSTRAINT_DATALA_ST(code, n) \
+	__EVENT_CONSTRAINT(code, n, 			\
+			  ARCH_PERFMON_EVENTSEL_EVENT|X86_ALL_EVENT_FLAGS, \
+			  HWEIGHT(n), 0, PERF_X86_EVENT_PEBS_ST_HSW)
+
+/* Check flags and event code, and set the HSW load flag */
+#define INTEL_FLAGS_EVENT_CONSTRAINT_DATALA_LD(code, n) \
+	__EVENT_CONSTRAINT(code, n,			\
+			  ARCH_PERFMON_EVENTSEL_EVENT|X86_ALL_EVENT_FLAGS, \
+			  HWEIGHT(n), 0, PERF_X86_EVENT_PEBS_LD_HSW)
+
+#define INTEL_FLAGS_EVENT_CONSTRAINT_DATALA_XLD(code, n) \
+	__EVENT_CONSTRAINT(code, n,			\
+			  ARCH_PERFMON_EVENTSEL_EVENT|X86_ALL_EVENT_FLAGS, \
+			  HWEIGHT(n), 0, \
+			  PERF_X86_EVENT_PEBS_LD_HSW|PERF_X86_EVENT_EXCL)
+
+/* Check flags and event code/umask, and set the HSW store flag */
+#define INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_ST(code, n) \
+	__EVENT_CONSTRAINT(code, n, 			\
+			  INTEL_ARCH_EVENT_MASK|X86_ALL_EVENT_FLAGS, \
+			  HWEIGHT(n), 0, PERF_X86_EVENT_PEBS_ST_HSW)
+
+#define INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_XST(code, n) \
+	__EVENT_CONSTRAINT(code, n,			\
+			  INTEL_ARCH_EVENT_MASK|X86_ALL_EVENT_FLAGS, \
+			  HWEIGHT(n), 0, \
+			  PERF_X86_EVENT_PEBS_ST_HSW|PERF_X86_EVENT_EXCL)
+
+/* Check flags and event code/umask, and set the HSW load flag */
+#define INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_LD(code, n) \
+	__EVENT_CONSTRAINT(code, n, 			\
+			  INTEL_ARCH_EVENT_MASK|X86_ALL_EVENT_FLAGS, \
+			  HWEIGHT(n), 0, PERF_X86_EVENT_PEBS_LD_HSW)
+
+#define INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_XLD(code, n) \
+	__EVENT_CONSTRAINT(code, n,			\
+			  INTEL_ARCH_EVENT_MASK|X86_ALL_EVENT_FLAGS, \
+			  HWEIGHT(n), 0, \
+			  PERF_X86_EVENT_PEBS_LD_HSW|PERF_X86_EVENT_EXCL)
+
+/* Check flags and event code/umask, and set the HSW N/A flag */
+#define INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_NA(code, n) \
+	__EVENT_CONSTRAINT(code, n, 			\
+			  INTEL_ARCH_EVENT_MASK|X86_ALL_EVENT_FLAGS, \
+			  HWEIGHT(n), 0, PERF_X86_EVENT_PEBS_NA_HSW)
+
+
+/*
+ * We define the end marker as having a weight of -1
+ * to enable blacklisting of events using a counter bitmask
+ * of zero and thus a weight of zero.
+ * The end marker has a weight that cannot possibly be
+ * obtained from counting the bits in the bitmask.
+ */
+#define EVENT_CONSTRAINT_END { .weight = -1 }
+
+/*
+ * Check for end marker with weight == -1
+ */
+#define for_each_event_constraint(e, c)	\
+	for ((e) = (c); (e)->weight != -1; (e)++)
+
+/*
+ * Extra registers for specific events.
+ *
+ * Some events need large masks and require external MSRs.
+ * Those extra MSRs end up being shared for all events on
+ * a PMU and sometimes between PMU of sibling HT threads.
+ * In either case, the kernel needs to handle conflicting
+ * accesses to those extra, shared, regs. The data structure
+ * to manage those registers is stored in cpu_hw_event.
+ */
+struct extra_reg {
+	unsigned int		event;
+	unsigned int		msr;
+	u64			config_mask;
+	u64			valid_mask;
+	int			idx;  /* per_xxx->regs[] reg index */
+	bool			extra_msr_access;
+};
+
+#define EVENT_EXTRA_REG(e, ms, m, vm, i) {	\
+	.event = (e),			\
+	.msr = (ms),			\
+	.config_mask = (m),		\
+	.valid_mask = (vm),		\
+	.idx = EXTRA_REG_##i,		\
+	.extra_msr_access = true,	\
+	}
+
+#define INTEL_EVENT_EXTRA_REG(event, msr, vm, idx)	\
+	EVENT_EXTRA_REG(event, msr, ARCH_PERFMON_EVENTSEL_EVENT, vm, idx)
+
+#define INTEL_UEVENT_EXTRA_REG(event, msr, vm, idx) \
+	EVENT_EXTRA_REG(event, msr, ARCH_PERFMON_EVENTSEL_EVENT | \
+			ARCH_PERFMON_EVENTSEL_UMASK, vm, idx)
+
+#define INTEL_UEVENT_PEBS_LDLAT_EXTRA_REG(c) \
+	INTEL_UEVENT_EXTRA_REG(c, \
+			       MSR_PEBS_LD_LAT_THRESHOLD, \
+			       0xffff, \
+			       LDLAT)
+
+#define EVENT_EXTRA_END EVENT_EXTRA_REG(0, 0, 0, 0, RSP_0)
+
+union perf_capabilities {
+	struct {
+		u64	lbr_format:6;
+		u64	pebs_trap:1;
+		u64	pebs_arch_reg:1;
+		u64	pebs_format:4;
+		u64	smm_freeze:1;
+		/*
+		 * PMU supports separate counter range for writing
+		 * values > 32bit.
+		 */
+		u64	full_width_write:1;
+	};
+	u64	capabilities;
+};
+
+struct x86_pmu_quirk {
+	struct x86_pmu_quirk *next;
+	void (*func)(void);
+};
+
+union x86_pmu_config {
+	struct {
+		u64 event:8,
+		    umask:8,
+		    usr:1,
+		    os:1,
+		    edge:1,
+		    pc:1,
+		    interrupt:1,
+		    __reserved1:1,
+		    en:1,
+		    inv:1,
+		    cmask:8,
+		    event2:4,
+		    __reserved2:4,
+		    go:1,
+		    ho:1;
+	} bits;
+	u64 value;
+};
+
+#define X86_CONFIG(args...) ((union x86_pmu_config){.bits = {args}}).value
+
+enum {
+	x86_lbr_exclusive_lbr,
+	x86_lbr_exclusive_bts,
+	x86_lbr_exclusive_pt,
+	x86_lbr_exclusive_max,
+};
+
+/*
+ * struct x86_pmu - generic x86 pmu
+ */
+struct x86_pmu {
+	/*
+	 * Generic x86 PMC bits
+	 */
+	const char	*name;
+	int		version;
+	int		(*handle_irq)(struct pt_regs *);
+	void		(*disable_all)(void);
+	void		(*enable_all)(int added);
+	void		(*enable)(struct perf_event *);
+	void		(*disable)(struct perf_event *);
+	int		(*hw_config)(struct perf_event *event);
+	int		(*schedule_events)(struct cpu_hw_events *cpuc, int n, int *assign);
+	unsigned	eventsel;
+	unsigned	perfctr;
+	int		(*addr_offset)(int index, bool eventsel);
+	int		(*rdpmc_index)(int index);
+	u64		(*event_map)(int);
+	int		max_events;
+	int		num_counters;
+	int		num_counters_fixed;
+	int		cntval_bits;
+	u64		cntval_mask;
+	union {
+			unsigned long events_maskl;
+			unsigned long events_mask[BITS_TO_LONGS(ARCH_PERFMON_EVENTS_COUNT)];
+	};
+	int		events_mask_len;
+	int		apic;
+	u64		max_period;
+	struct event_constraint *
+			(*get_event_constraints)(struct cpu_hw_events *cpuc,
+						 int idx,
+						 struct perf_event *event);
+
+	void		(*put_event_constraints)(struct cpu_hw_events *cpuc,
+						 struct perf_event *event);
+
+	void		(*start_scheduling)(struct cpu_hw_events *cpuc);
+
+	void		(*commit_scheduling)(struct cpu_hw_events *cpuc, int idx, int cntr);
+
+	void		(*stop_scheduling)(struct cpu_hw_events *cpuc);
+
+	struct event_constraint *event_constraints;
+	struct x86_pmu_quirk *quirks;
+	int		perfctr_second_write;
+	bool		late_ack;
+	unsigned	(*limit_period)(struct perf_event *event, unsigned l);
+
+	/*
+	 * sysfs attrs
+	 */
+	int		attr_rdpmc_broken;
+	int		attr_rdpmc;
+	struct attribute **format_attrs;
+	struct attribute **event_attrs;
+
+	ssize_t		(*events_sysfs_show)(char *page, u64 config);
+	struct attribute **cpu_events;
+
+	/*
+	 * CPU Hotplug hooks
+	 */
+	int		(*cpu_prepare)(int cpu);
+	void		(*cpu_starting)(int cpu);
+	void		(*cpu_dying)(int cpu);
+	void		(*cpu_dead)(int cpu);
+
+	void		(*check_microcode)(void);
+	void		(*sched_task)(struct perf_event_context *ctx,
+				      bool sched_in);
+
+	/*
+	 * Intel Arch Perfmon v2+
+	 */
+	u64			intel_ctrl;
+	union perf_capabilities intel_cap;
+
+	/*
+	 * Intel DebugStore bits
+	 */
+	unsigned int	bts		:1,
+			bts_active	:1,
+			pebs		:1,
+			pebs_active	:1,
+			pebs_broken	:1;
+	int		pebs_record_size;
+	int		pebs_buffer_size;
+	void		(*drain_pebs)(struct pt_regs *regs);
+	struct event_constraint *pebs_constraints;
+	void		(*pebs_aliases)(struct perf_event *event);
+	int 		max_pebs_events;
+	unsigned long	free_running_flags;
+
+	/*
+	 * Intel LBR
+	 */
+	unsigned long	lbr_tos, lbr_from, lbr_to; /* MSR base regs       */
+	int		lbr_nr;			   /* hardware stack size */
+	u64		lbr_sel_mask;		   /* LBR_SELECT valid bits */
+	const int	*lbr_sel_map;		   /* lbr_select mappings */
+	bool		lbr_double_abort;	   /* duplicated lbr aborts */
+
+	/*
+	 * Intel PT/LBR/BTS are exclusive
+	 */
+	atomic_t	lbr_exclusive[x86_lbr_exclusive_max];
+
+	/*
+	 * Extra registers for events
+	 */
+	struct extra_reg *extra_regs;
+	unsigned int flags;
+
+	/*
+	 * Intel host/guest support (KVM)
+	 */
+	struct perf_guest_switch_msr *(*guest_get_msrs)(int *nr);
+};
+
+struct x86_perf_task_context {
+	u64 lbr_from[MAX_LBR_ENTRIES];
+	u64 lbr_to[MAX_LBR_ENTRIES];
+	u64 lbr_info[MAX_LBR_ENTRIES];
+	int tos;
+	int lbr_callstack_users;
+	int lbr_stack_state;
+};
+
+#define x86_add_quirk(func_)						\
+do {									\
+	static struct x86_pmu_quirk __quirk __initdata = {		\
+		.func = func_,						\
+	};								\
+	__quirk.next = x86_pmu.quirks;					\
+	x86_pmu.quirks = &__quirk;					\
+} while (0)
+
+/*
+ * x86_pmu flags
+ */
+#define PMU_FL_NO_HT_SHARING	0x1 /* no hyper-threading resource sharing */
+#define PMU_FL_HAS_RSP_1	0x2 /* has 2 equivalent offcore_rsp regs   */
+#define PMU_FL_EXCL_CNTRS	0x4 /* has exclusive counter requirements  */
+#define PMU_FL_EXCL_ENABLED	0x8 /* exclusive counter active */
+
+#define EVENT_VAR(_id)  event_attr_##_id
+#define EVENT_PTR(_id) &event_attr_##_id.attr.attr
+
+#define EVENT_ATTR(_name, _id)						\
+static struct perf_pmu_events_attr EVENT_VAR(_id) = {			\
+	.attr		= __ATTR(_name, 0444, events_sysfs_show, NULL),	\
+	.id		= PERF_COUNT_HW_##_id,				\
+	.event_str	= NULL,						\
+};
+
+#define EVENT_ATTR_STR(_name, v, str)					\
+static struct perf_pmu_events_attr event_attr_##v = {			\
+	.attr		= __ATTR(_name, 0444, events_sysfs_show, NULL),	\
+	.id		= 0,						\
+	.event_str	= str,						\
+};
+
+extern struct x86_pmu x86_pmu __read_mostly;
+
+static inline bool x86_pmu_has_lbr_callstack(void)
+{
+	return  x86_pmu.lbr_sel_map &&
+		x86_pmu.lbr_sel_map[PERF_SAMPLE_BRANCH_CALL_STACK_SHIFT] > 0;
+}
+
+DECLARE_PER_CPU(struct cpu_hw_events, cpu_hw_events);
+
+int x86_perf_event_set_period(struct perf_event *event);
+
+/*
+ * Generalized hw caching related hw_event table, filled
+ * in on a per model basis. A value of 0 means
+ * 'not supported', -1 means 'hw_event makes no sense on
+ * this CPU', any other value means the raw hw_event
+ * ID.
+ */
+
+#define C(x) PERF_COUNT_HW_CACHE_##x
+
+extern u64 __read_mostly hw_cache_event_ids
+				[PERF_COUNT_HW_CACHE_MAX]
+				[PERF_COUNT_HW_CACHE_OP_MAX]
+				[PERF_COUNT_HW_CACHE_RESULT_MAX];
+extern u64 __read_mostly hw_cache_extra_regs
+				[PERF_COUNT_HW_CACHE_MAX]
+				[PERF_COUNT_HW_CACHE_OP_MAX]
+				[PERF_COUNT_HW_CACHE_RESULT_MAX];
+
+u64 x86_perf_event_update(struct perf_event *event);
+
+static inline unsigned int x86_pmu_config_addr(int index)
+{
+	return x86_pmu.eventsel + (x86_pmu.addr_offset ?
+				   x86_pmu.addr_offset(index, true) : index);
+}
+
+static inline unsigned int x86_pmu_event_addr(int index)
+{
+	return x86_pmu.perfctr + (x86_pmu.addr_offset ?
+				  x86_pmu.addr_offset(index, false) : index);
+}
+
+static inline int x86_pmu_rdpmc_index(int index)
+{
+	return x86_pmu.rdpmc_index ? x86_pmu.rdpmc_index(index) : index;
+}
+
+int x86_add_exclusive(unsigned int what);
+
+void x86_del_exclusive(unsigned int what);
+
+int x86_reserve_hardware(void);
+
+void x86_release_hardware(void);
+
+void hw_perf_lbr_event_destroy(struct perf_event *event);
+
+int x86_setup_perfctr(struct perf_event *event);
+
+int x86_pmu_hw_config(struct perf_event *event);
+
+void x86_pmu_disable_all(void);
+
+static inline void __x86_pmu_enable_event(struct hw_perf_event *hwc,
+					  u64 enable_mask)
+{
+	u64 disable_mask = __this_cpu_read(cpu_hw_events.perf_ctr_virt_mask);
+
+	if (hwc->extra_reg.reg)
+		wrmsrl(hwc->extra_reg.reg, hwc->extra_reg.config);
+	wrmsrl(hwc->config_base, (hwc->config | enable_mask) & ~disable_mask);
+}
+
+void x86_pmu_enable_all(int added);
+
+int perf_assign_events(struct event_constraint **constraints, int n,
+			int wmin, int wmax, int gpmax, int *assign);
+int x86_schedule_events(struct cpu_hw_events *cpuc, int n, int *assign);
+
+void x86_pmu_stop(struct perf_event *event, int flags);
+
+static inline void x86_pmu_disable_event(struct perf_event *event)
+{
+	struct hw_perf_event *hwc = &event->hw;
+
+	wrmsrl(hwc->config_base, hwc->config);
+}
+
+void x86_pmu_enable_event(struct perf_event *event);
+
+int x86_pmu_handle_irq(struct pt_regs *regs);
+
+extern struct event_constraint emptyconstraint;
+
+extern struct event_constraint unconstrained;
+
+static inline bool kernel_ip(unsigned long ip)
+{
+#ifdef CONFIG_X86_32
+	return ip > PAGE_OFFSET;
+#else
+	return (long)ip < 0;
+#endif
+}
+
+/*
+ * Not all PMUs provide the right context information to place the reported IP
+ * into full context. Specifically segment registers are typically not
+ * supplied.
+ *
+ * Assuming the address is a linear address (it is for IBS), we fake the CS and
+ * vm86 mode using the known zero-based code segment and 'fix up' the registers
+ * to reflect this.
+ *
+ * Intel PEBS/LBR appear to typically provide the effective address, nothing
+ * much we can do about that but pray and treat it like a linear address.
+ */
+static inline void set_linear_ip(struct pt_regs *regs, unsigned long ip)
+{
+	regs->cs = kernel_ip(ip) ? __KERNEL_CS : __USER_CS;
+	if (regs->flags & X86_VM_MASK)
+		regs->flags ^= (PERF_EFLAGS_VM | X86_VM_MASK);
+	regs->ip = ip;
+}
+
+ssize_t x86_event_sysfs_show(char *page, u64 config, u64 event);
+ssize_t intel_event_sysfs_show(char *page, u64 config);
+
+struct attribute **merge_attr(struct attribute **a, struct attribute **b);
+
+#ifdef CONFIG_CPU_SUP_AMD
+
+int amd_pmu_init(void);
+
+#else /* CONFIG_CPU_SUP_AMD */
+
+static inline int amd_pmu_init(void)
+{
+	return 0;
+}
+
+#endif /* CONFIG_CPU_SUP_AMD */
+
+#ifdef CONFIG_CPU_SUP_INTEL
+
+static inline bool intel_pmu_has_bts(struct perf_event *event)
+{
+	if (event->attr.config == PERF_COUNT_HW_BRANCH_INSTRUCTIONS &&
+	    !event->attr.freq && event->hw.sample_period == 1)
+		return true;
+
+	return false;
+}
+
+int intel_pmu_save_and_restart(struct perf_event *event);
+
+struct event_constraint *
+x86_get_event_constraints(struct cpu_hw_events *cpuc, int idx,
+			  struct perf_event *event);
+
+struct intel_shared_regs *allocate_shared_regs(int cpu);
+
+int intel_pmu_init(void);
+
+void init_debug_store_on_cpu(int cpu);
+
+void fini_debug_store_on_cpu(int cpu);
+
+void release_ds_buffers(void);
+
+void reserve_ds_buffers(void);
+
+extern struct event_constraint bts_constraint;
+
+void intel_pmu_enable_bts(u64 config);
+
+void intel_pmu_disable_bts(void);
+
+int intel_pmu_drain_bts_buffer(void);
+
+extern struct event_constraint intel_core2_pebs_event_constraints[];
+
+extern struct event_constraint intel_atom_pebs_event_constraints[];
+
+extern struct event_constraint intel_slm_pebs_event_constraints[];
+
+extern struct event_constraint intel_nehalem_pebs_event_constraints[];
+
+extern struct event_constraint intel_westmere_pebs_event_constraints[];
+
+extern struct event_constraint intel_snb_pebs_event_constraints[];
+
+extern struct event_constraint intel_ivb_pebs_event_constraints[];
+
+extern struct event_constraint intel_hsw_pebs_event_constraints[];
+
+extern struct event_constraint intel_skl_pebs_event_constraints[];
+
+struct event_constraint *intel_pebs_constraints(struct perf_event *event);
+
+void intel_pmu_pebs_enable(struct perf_event *event);
+
+void intel_pmu_pebs_disable(struct perf_event *event);
+
+void intel_pmu_pebs_enable_all(void);
+
+void intel_pmu_pebs_disable_all(void);
+
+void intel_pmu_pebs_sched_task(struct perf_event_context *ctx, bool sched_in);
+
+void intel_ds_init(void);
+
+void intel_pmu_lbr_sched_task(struct perf_event_context *ctx, bool sched_in);
+
+void intel_pmu_lbr_reset(void);
+
+void intel_pmu_lbr_enable(struct perf_event *event);
+
+void intel_pmu_lbr_disable(struct perf_event *event);
+
+void intel_pmu_lbr_enable_all(bool pmi);
+
+void intel_pmu_lbr_disable_all(void);
+
+void intel_pmu_lbr_read(void);
+
+void intel_pmu_lbr_init_core(void);
+
+void intel_pmu_lbr_init_nhm(void);
+
+void intel_pmu_lbr_init_atom(void);
+
+void intel_pmu_lbr_init_snb(void);
+
+void intel_pmu_lbr_init_hsw(void);
+
+void intel_pmu_lbr_init_skl(void);
+
+void intel_pmu_lbr_init_knl(void);
+
+void intel_pmu_pebs_data_source_nhm(void);
+
+int intel_pmu_setup_lbr_filter(struct perf_event *event);
+
+void intel_pt_interrupt(void);
+
+int intel_bts_interrupt(void);
+
+void intel_bts_enable_local(void);
+
+void intel_bts_disable_local(void);
+
+int p4_pmu_init(void);
+
+int p6_pmu_init(void);
+
+int knc_pmu_init(void);
+
+ssize_t events_sysfs_show(struct device *dev, struct device_attribute *attr,
+			  char *page);
+
+static inline int is_ht_workaround_enabled(void)
+{
+	return !!(x86_pmu.flags & PMU_FL_EXCL_ENABLED);
+}
+
+#else /* CONFIG_CPU_SUP_INTEL */
+
+static inline void reserve_ds_buffers(void)
+{
+}
+
+static inline void release_ds_buffers(void)
+{
+}
+
+static inline int intel_pmu_init(void)
+{
+	return 0;
+}
+
+static inline struct intel_shared_regs *allocate_shared_regs(int cpu)
+{
+	return NULL;
+}
+
+static inline int is_ht_workaround_enabled(void)
+{
+	return 0;
+}
+#endif /* CONFIG_CPU_SUP_INTEL */
--- zfcpdump-kernel-4.4.orig/arch/x86/include/asm/alternative.h
+++ zfcpdump-kernel-4.4/arch/x86/include/asm/alternative.h
@@ -152,12 +152,6 @@ static inline int alternatives_text_rese
 	".popsection"
 
 /*
- * This must be included *after* the definition of ALTERNATIVE due to
- * <asm/arch_hweight.h>
- */
-#include <asm/cpufeature.h>
-
-/*
  * Alternative instructions for different CPU types or capabilities.
  *
  * This allows to use optimized instructions even on generic binary
--- zfcpdump-kernel-4.4.orig/arch/x86/include/asm/apic.h
+++ zfcpdump-kernel-4.4/arch/x86/include/asm/apic.h
@@ -6,7 +6,6 @@
 
 #include <asm/alternative.h>
 #include <asm/cpufeature.h>
-#include <asm/processor.h>
 #include <asm/apicdef.h>
 #include <linux/atomic.h>
 #include <asm/fixmap.h>
@@ -638,8 +637,8 @@ static inline void entering_irq(void)
 
 static inline void entering_ack_irq(void)
 {
-	ack_APIC_irq();
 	entering_irq();
+	ack_APIC_irq();
 }
 
 static inline void ipi_entering_ack_irq(void)
--- zfcpdump-kernel-4.4.orig/arch/x86/include/asm/arch_hweight.h
+++ zfcpdump-kernel-4.4/arch/x86/include/asm/arch_hweight.h
@@ -1,6 +1,8 @@
 #ifndef _ASM_X86_HWEIGHT_H
 #define _ASM_X86_HWEIGHT_H
 
+#include <asm/cpufeatures.h>
+
 #ifdef CONFIG_64BIT
 /* popcnt %edi, %eax -- redundant REX prefix for alignment */
 #define POPCNT32 ".byte 0xf3,0x40,0x0f,0xb8,0xc7"
--- zfcpdump-kernel-4.4.orig/arch/x86/include/asm/barrier.h
+++ zfcpdump-kernel-4.4/arch/x86/include/asm/barrier.h
@@ -31,20 +31,10 @@
 #endif
 #define dma_wmb()	barrier()
 
-#ifdef CONFIG_SMP
-#define smp_mb()	mb()
-#define smp_rmb()	dma_rmb()
-#define smp_wmb()	barrier()
-#define smp_store_mb(var, value) do { (void)xchg(&var, value); } while (0)
-#else /* !SMP */
-#define smp_mb()	barrier()
-#define smp_rmb()	barrier()
-#define smp_wmb()	barrier()
-#define smp_store_mb(var, value) do { WRITE_ONCE(var, value); barrier(); } while (0)
-#endif /* SMP */
-
-#define read_barrier_depends()		do { } while (0)
-#define smp_read_barrier_depends()	do { } while (0)
+#define __smp_mb()	mb()
+#define __smp_rmb()	dma_rmb()
+#define __smp_wmb()	barrier()
+#define __smp_store_mb(var, value) do { (void)xchg(&var, value); } while (0)
 
 #if defined(CONFIG_X86_PPRO_FENCE)
 
@@ -53,31 +43,31 @@
  * model and we should fall back to full barriers.
  */
 
-#define smp_store_release(p, v)						\
+#define __smp_store_release(p, v)					\
 do {									\
 	compiletime_assert_atomic_type(*p);				\
-	smp_mb();							\
+	__smp_mb();							\
 	WRITE_ONCE(*p, v);						\
 } while (0)
 
-#define smp_load_acquire(p)						\
+#define __smp_load_acquire(p)						\
 ({									\
 	typeof(*p) ___p1 = READ_ONCE(*p);				\
 	compiletime_assert_atomic_type(*p);				\
-	smp_mb();							\
+	__smp_mb();							\
 	___p1;								\
 })
 
 #else /* regular x86 TSO memory ordering */
 
-#define smp_store_release(p, v)						\
+#define __smp_store_release(p, v)					\
 do {									\
 	compiletime_assert_atomic_type(*p);				\
 	barrier();							\
 	WRITE_ONCE(*p, v);						\
 } while (0)
 
-#define smp_load_acquire(p)						\
+#define __smp_load_acquire(p)						\
 ({									\
 	typeof(*p) ___p1 = READ_ONCE(*p);				\
 	compiletime_assert_atomic_type(*p);				\
@@ -88,7 +78,9 @@ do {									\
 #endif
 
 /* Atomic operations are already serializing on x86 */
-#define smp_mb__before_atomic()	barrier()
-#define smp_mb__after_atomic()	barrier()
+#define __smp_mb__before_atomic()	barrier()
+#define __smp_mb__after_atomic()	barrier()
+
+#include <asm-generic/barrier.h>
 
 #endif /* _ASM_X86_BARRIER_H */
--- zfcpdump-kernel-4.4.orig/arch/x86/include/asm/boot.h
+++ zfcpdump-kernel-4.4/arch/x86/include/asm/boot.h
@@ -27,7 +27,7 @@
 #define BOOT_HEAP_SIZE             0x400000
 #else /* !CONFIG_KERNEL_BZIP2 */
 
-#define BOOT_HEAP_SIZE	0x8000
+#define BOOT_HEAP_SIZE	0x10000
 
 #endif /* !CONFIG_KERNEL_BZIP2 */
 
--- zfcpdump-kernel-4.4.orig/arch/x86/include/asm/cmpxchg.h
+++ zfcpdump-kernel-4.4/arch/x86/include/asm/cmpxchg.h
@@ -2,6 +2,7 @@
 #define ASM_X86_CMPXCHG_H
 
 #include <linux/compiler.h>
+#include <asm/cpufeatures.h>
 #include <asm/alternative.h> /* Provides LOCK_PREFIX */
 
 /*
--- zfcpdump-kernel-4.4.orig/arch/x86/include/asm/cpufeature.h
+++ zfcpdump-kernel-4.4/arch/x86/include/asm/cpufeature.h
@@ -1,278 +1,7 @@
-/*
- * Defines x86 CPU feature bits
- */
 #ifndef _ASM_X86_CPUFEATURE_H
 #define _ASM_X86_CPUFEATURE_H
 
-#ifndef _ASM_X86_REQUIRED_FEATURES_H
-#include <asm/required-features.h>
-#endif
-
-#ifndef _ASM_X86_DISABLED_FEATURES_H
-#include <asm/disabled-features.h>
-#endif
-
-#define NCAPINTS	14	/* N 32-bit words worth of info */
-#define NBUGINTS	1	/* N 32-bit bug flags */
-
-/*
- * Note: If the comment begins with a quoted string, that string is used
- * in /proc/cpuinfo instead of the macro name.  If the string is "",
- * this feature bit is not displayed in /proc/cpuinfo at all.
- */
-
-/* Intel-defined CPU features, CPUID level 0x00000001 (edx), word 0 */
-#define X86_FEATURE_FPU		( 0*32+ 0) /* Onboard FPU */
-#define X86_FEATURE_VME		( 0*32+ 1) /* Virtual Mode Extensions */
-#define X86_FEATURE_DE		( 0*32+ 2) /* Debugging Extensions */
-#define X86_FEATURE_PSE		( 0*32+ 3) /* Page Size Extensions */
-#define X86_FEATURE_TSC		( 0*32+ 4) /* Time Stamp Counter */
-#define X86_FEATURE_MSR		( 0*32+ 5) /* Model-Specific Registers */
-#define X86_FEATURE_PAE		( 0*32+ 6) /* Physical Address Extensions */
-#define X86_FEATURE_MCE		( 0*32+ 7) /* Machine Check Exception */
-#define X86_FEATURE_CX8		( 0*32+ 8) /* CMPXCHG8 instruction */
-#define X86_FEATURE_APIC	( 0*32+ 9) /* Onboard APIC */
-#define X86_FEATURE_SEP		( 0*32+11) /* SYSENTER/SYSEXIT */
-#define X86_FEATURE_MTRR	( 0*32+12) /* Memory Type Range Registers */
-#define X86_FEATURE_PGE		( 0*32+13) /* Page Global Enable */
-#define X86_FEATURE_MCA		( 0*32+14) /* Machine Check Architecture */
-#define X86_FEATURE_CMOV	( 0*32+15) /* CMOV instructions */
-					  /* (plus FCMOVcc, FCOMI with FPU) */
-#define X86_FEATURE_PAT		( 0*32+16) /* Page Attribute Table */
-#define X86_FEATURE_PSE36	( 0*32+17) /* 36-bit PSEs */
-#define X86_FEATURE_PN		( 0*32+18) /* Processor serial number */
-#define X86_FEATURE_CLFLUSH	( 0*32+19) /* CLFLUSH instruction */
-#define X86_FEATURE_DS		( 0*32+21) /* "dts" Debug Store */
-#define X86_FEATURE_ACPI	( 0*32+22) /* ACPI via MSR */
-#define X86_FEATURE_MMX		( 0*32+23) /* Multimedia Extensions */
-#define X86_FEATURE_FXSR	( 0*32+24) /* FXSAVE/FXRSTOR, CR4.OSFXSR */
-#define X86_FEATURE_XMM		( 0*32+25) /* "sse" */
-#define X86_FEATURE_XMM2	( 0*32+26) /* "sse2" */
-#define X86_FEATURE_SELFSNOOP	( 0*32+27) /* "ss" CPU self snoop */
-#define X86_FEATURE_HT		( 0*32+28) /* Hyper-Threading */
-#define X86_FEATURE_ACC		( 0*32+29) /* "tm" Automatic clock control */
-#define X86_FEATURE_IA64	( 0*32+30) /* IA-64 processor */
-#define X86_FEATURE_PBE		( 0*32+31) /* Pending Break Enable */
-
-/* AMD-defined CPU features, CPUID level 0x80000001, word 1 */
-/* Don't duplicate feature flags which are redundant with Intel! */
-#define X86_FEATURE_SYSCALL	( 1*32+11) /* SYSCALL/SYSRET */
-#define X86_FEATURE_MP		( 1*32+19) /* MP Capable. */
-#define X86_FEATURE_NX		( 1*32+20) /* Execute Disable */
-#define X86_FEATURE_MMXEXT	( 1*32+22) /* AMD MMX extensions */
-#define X86_FEATURE_FXSR_OPT	( 1*32+25) /* FXSAVE/FXRSTOR optimizations */
-#define X86_FEATURE_GBPAGES	( 1*32+26) /* "pdpe1gb" GB pages */
-#define X86_FEATURE_RDTSCP	( 1*32+27) /* RDTSCP */
-#define X86_FEATURE_LM		( 1*32+29) /* Long Mode (x86-64) */
-#define X86_FEATURE_3DNOWEXT	( 1*32+30) /* AMD 3DNow! extensions */
-#define X86_FEATURE_3DNOW	( 1*32+31) /* 3DNow! */
-
-/* Transmeta-defined CPU features, CPUID level 0x80860001, word 2 */
-#define X86_FEATURE_RECOVERY	( 2*32+ 0) /* CPU in recovery mode */
-#define X86_FEATURE_LONGRUN	( 2*32+ 1) /* Longrun power control */
-#define X86_FEATURE_LRTI	( 2*32+ 3) /* LongRun table interface */
-
-/* Other features, Linux-defined mapping, word 3 */
-/* This range is used for feature bits which conflict or are synthesized */
-#define X86_FEATURE_CXMMX	( 3*32+ 0) /* Cyrix MMX extensions */
-#define X86_FEATURE_K6_MTRR	( 3*32+ 1) /* AMD K6 nonstandard MTRRs */
-#define X86_FEATURE_CYRIX_ARR	( 3*32+ 2) /* Cyrix ARRs (= MTRRs) */
-#define X86_FEATURE_CENTAUR_MCR	( 3*32+ 3) /* Centaur MCRs (= MTRRs) */
-/* cpu types for specific tunings: */
-#define X86_FEATURE_K8		( 3*32+ 4) /* "" Opteron, Athlon64 */
-#define X86_FEATURE_K7		( 3*32+ 5) /* "" Athlon */
-#define X86_FEATURE_P3		( 3*32+ 6) /* "" P3 */
-#define X86_FEATURE_P4		( 3*32+ 7) /* "" P4 */
-#define X86_FEATURE_CONSTANT_TSC ( 3*32+ 8) /* TSC ticks at a constant rate */
-#define X86_FEATURE_UP		( 3*32+ 9) /* smp kernel running on up */
-/* free, was #define X86_FEATURE_FXSAVE_LEAK ( 3*32+10) * "" FXSAVE leaks FOP/FIP/FOP */
-#define X86_FEATURE_ARCH_PERFMON ( 3*32+11) /* Intel Architectural PerfMon */
-#define X86_FEATURE_PEBS	( 3*32+12) /* Precise-Event Based Sampling */
-#define X86_FEATURE_BTS		( 3*32+13) /* Branch Trace Store */
-#define X86_FEATURE_SYSCALL32	( 3*32+14) /* "" syscall in ia32 userspace */
-#define X86_FEATURE_SYSENTER32	( 3*32+15) /* "" sysenter in ia32 userspace */
-#define X86_FEATURE_REP_GOOD	( 3*32+16) /* rep microcode works well */
-#define X86_FEATURE_MFENCE_RDTSC ( 3*32+17) /* "" Mfence synchronizes RDTSC */
-#define X86_FEATURE_LFENCE_RDTSC ( 3*32+18) /* "" Lfence synchronizes RDTSC */
-/* free, was #define X86_FEATURE_11AP	( 3*32+19) * "" Bad local APIC aka 11AP */
-#define X86_FEATURE_NOPL	( 3*32+20) /* The NOPL (0F 1F) instructions */
-#define X86_FEATURE_ALWAYS	( 3*32+21) /* "" Always-present feature */
-#define X86_FEATURE_XTOPOLOGY	( 3*32+22) /* cpu topology enum extensions */
-#define X86_FEATURE_TSC_RELIABLE ( 3*32+23) /* TSC is known to be reliable */
-#define X86_FEATURE_NONSTOP_TSC	( 3*32+24) /* TSC does not stop in C states */
-/* free, was #define X86_FEATURE_CLFLUSH_MONITOR ( 3*32+25) * "" clflush reqd with monitor */
-#define X86_FEATURE_EXTD_APICID	( 3*32+26) /* has extended APICID (8 bits) */
-#define X86_FEATURE_AMD_DCM     ( 3*32+27) /* multi-node processor */
-#define X86_FEATURE_APERFMPERF	( 3*32+28) /* APERFMPERF */
-#define X86_FEATURE_EAGER_FPU	( 3*32+29) /* "eagerfpu" Non lazy FPU restore */
-#define X86_FEATURE_NONSTOP_TSC_S3 ( 3*32+30) /* TSC doesn't stop in S3 state */
-
-/* Intel-defined CPU features, CPUID level 0x00000001 (ecx), word 4 */
-#define X86_FEATURE_XMM3	( 4*32+ 0) /* "pni" SSE-3 */
-#define X86_FEATURE_PCLMULQDQ	( 4*32+ 1) /* PCLMULQDQ instruction */
-#define X86_FEATURE_DTES64	( 4*32+ 2) /* 64-bit Debug Store */
-#define X86_FEATURE_MWAIT	( 4*32+ 3) /* "monitor" Monitor/Mwait support */
-#define X86_FEATURE_DSCPL	( 4*32+ 4) /* "ds_cpl" CPL Qual. Debug Store */
-#define X86_FEATURE_VMX		( 4*32+ 5) /* Hardware virtualization */
-#define X86_FEATURE_SMX		( 4*32+ 6) /* Safer mode */
-#define X86_FEATURE_EST		( 4*32+ 7) /* Enhanced SpeedStep */
-#define X86_FEATURE_TM2		( 4*32+ 8) /* Thermal Monitor 2 */
-#define X86_FEATURE_SSSE3	( 4*32+ 9) /* Supplemental SSE-3 */
-#define X86_FEATURE_CID		( 4*32+10) /* Context ID */
-#define X86_FEATURE_SDBG	( 4*32+11) /* Silicon Debug */
-#define X86_FEATURE_FMA		( 4*32+12) /* Fused multiply-add */
-#define X86_FEATURE_CX16	( 4*32+13) /* CMPXCHG16B */
-#define X86_FEATURE_XTPR	( 4*32+14) /* Send Task Priority Messages */
-#define X86_FEATURE_PDCM	( 4*32+15) /* Performance Capabilities */
-#define X86_FEATURE_PCID	( 4*32+17) /* Process Context Identifiers */
-#define X86_FEATURE_DCA		( 4*32+18) /* Direct Cache Access */
-#define X86_FEATURE_XMM4_1	( 4*32+19) /* "sse4_1" SSE-4.1 */
-#define X86_FEATURE_XMM4_2	( 4*32+20) /* "sse4_2" SSE-4.2 */
-#define X86_FEATURE_X2APIC	( 4*32+21) /* x2APIC */
-#define X86_FEATURE_MOVBE	( 4*32+22) /* MOVBE instruction */
-#define X86_FEATURE_POPCNT      ( 4*32+23) /* POPCNT instruction */
-#define X86_FEATURE_TSC_DEADLINE_TIMER	( 4*32+24) /* Tsc deadline timer */
-#define X86_FEATURE_AES		( 4*32+25) /* AES instructions */
-#define X86_FEATURE_XSAVE	( 4*32+26) /* XSAVE/XRSTOR/XSETBV/XGETBV */
-#define X86_FEATURE_OSXSAVE	( 4*32+27) /* "" XSAVE enabled in the OS */
-#define X86_FEATURE_AVX		( 4*32+28) /* Advanced Vector Extensions */
-#define X86_FEATURE_F16C	( 4*32+29) /* 16-bit fp conversions */
-#define X86_FEATURE_RDRAND	( 4*32+30) /* The RDRAND instruction */
-#define X86_FEATURE_HYPERVISOR	( 4*32+31) /* Running on a hypervisor */
-
-/* VIA/Cyrix/Centaur-defined CPU features, CPUID level 0xC0000001, word 5 */
-#define X86_FEATURE_XSTORE	( 5*32+ 2) /* "rng" RNG present (xstore) */
-#define X86_FEATURE_XSTORE_EN	( 5*32+ 3) /* "rng_en" RNG enabled */
-#define X86_FEATURE_XCRYPT	( 5*32+ 6) /* "ace" on-CPU crypto (xcrypt) */
-#define X86_FEATURE_XCRYPT_EN	( 5*32+ 7) /* "ace_en" on-CPU crypto enabled */
-#define X86_FEATURE_ACE2	( 5*32+ 8) /* Advanced Cryptography Engine v2 */
-#define X86_FEATURE_ACE2_EN	( 5*32+ 9) /* ACE v2 enabled */
-#define X86_FEATURE_PHE		( 5*32+10) /* PadLock Hash Engine */
-#define X86_FEATURE_PHE_EN	( 5*32+11) /* PHE enabled */
-#define X86_FEATURE_PMM		( 5*32+12) /* PadLock Montgomery Multiplier */
-#define X86_FEATURE_PMM_EN	( 5*32+13) /* PMM enabled */
-
-/* More extended AMD flags: CPUID level 0x80000001, ecx, word 6 */
-#define X86_FEATURE_LAHF_LM	( 6*32+ 0) /* LAHF/SAHF in long mode */
-#define X86_FEATURE_CMP_LEGACY	( 6*32+ 1) /* If yes HyperThreading not valid */
-#define X86_FEATURE_SVM		( 6*32+ 2) /* Secure virtual machine */
-#define X86_FEATURE_EXTAPIC	( 6*32+ 3) /* Extended APIC space */
-#define X86_FEATURE_CR8_LEGACY	( 6*32+ 4) /* CR8 in 32-bit mode */
-#define X86_FEATURE_ABM		( 6*32+ 5) /* Advanced bit manipulation */
-#define X86_FEATURE_SSE4A	( 6*32+ 6) /* SSE-4A */
-#define X86_FEATURE_MISALIGNSSE ( 6*32+ 7) /* Misaligned SSE mode */
-#define X86_FEATURE_3DNOWPREFETCH ( 6*32+ 8) /* 3DNow prefetch instructions */
-#define X86_FEATURE_OSVW	( 6*32+ 9) /* OS Visible Workaround */
-#define X86_FEATURE_IBS		( 6*32+10) /* Instruction Based Sampling */
-#define X86_FEATURE_XOP		( 6*32+11) /* extended AVX instructions */
-#define X86_FEATURE_SKINIT	( 6*32+12) /* SKINIT/STGI instructions */
-#define X86_FEATURE_WDT		( 6*32+13) /* Watchdog timer */
-#define X86_FEATURE_LWP		( 6*32+15) /* Light Weight Profiling */
-#define X86_FEATURE_FMA4	( 6*32+16) /* 4 operands MAC instructions */
-#define X86_FEATURE_TCE		( 6*32+17) /* translation cache extension */
-#define X86_FEATURE_NODEID_MSR	( 6*32+19) /* NodeId MSR */
-#define X86_FEATURE_TBM		( 6*32+21) /* trailing bit manipulations */
-#define X86_FEATURE_TOPOEXT	( 6*32+22) /* topology extensions CPUID leafs */
-#define X86_FEATURE_PERFCTR_CORE ( 6*32+23) /* core performance counter extensions */
-#define X86_FEATURE_PERFCTR_NB  ( 6*32+24) /* NB performance counter extensions */
-#define X86_FEATURE_BPEXT	(6*32+26) /* data breakpoint extension */
-#define X86_FEATURE_PERFCTR_L2	( 6*32+28) /* L2 performance counter extensions */
-#define X86_FEATURE_MWAITX	( 6*32+29) /* MWAIT extension (MONITORX/MWAITX) */
-
-/*
- * Auxiliary flags: Linux defined - For features scattered in various
- * CPUID levels like 0x6, 0xA etc, word 7
- */
-#define X86_FEATURE_IDA		( 7*32+ 0) /* Intel Dynamic Acceleration */
-#define X86_FEATURE_ARAT	( 7*32+ 1) /* Always Running APIC Timer */
-#define X86_FEATURE_CPB		( 7*32+ 2) /* AMD Core Performance Boost */
-#define X86_FEATURE_EPB		( 7*32+ 3) /* IA32_ENERGY_PERF_BIAS support */
-#define X86_FEATURE_PLN		( 7*32+ 5) /* Intel Power Limit Notification */
-#define X86_FEATURE_PTS		( 7*32+ 6) /* Intel Package Thermal Status */
-#define X86_FEATURE_DTHERM	( 7*32+ 7) /* Digital Thermal Sensor */
-#define X86_FEATURE_HW_PSTATE	( 7*32+ 8) /* AMD HW-PState */
-#define X86_FEATURE_PROC_FEEDBACK ( 7*32+ 9) /* AMD ProcFeedbackInterface */
-#define X86_FEATURE_HWP		( 7*32+ 10) /* "hwp" Intel HWP */
-#define X86_FEATURE_HWP_NOTIFY	( 7*32+ 11) /* Intel HWP_NOTIFY */
-#define X86_FEATURE_HWP_ACT_WINDOW ( 7*32+ 12) /* Intel HWP_ACT_WINDOW */
-#define X86_FEATURE_HWP_EPP	( 7*32+13) /* Intel HWP_EPP */
-#define X86_FEATURE_HWP_PKG_REQ ( 7*32+14) /* Intel HWP_PKG_REQ */
-#define X86_FEATURE_INTEL_PT	( 7*32+15) /* Intel Processor Trace */
-
-/* Virtualization flags: Linux defined, word 8 */
-#define X86_FEATURE_TPR_SHADOW  ( 8*32+ 0) /* Intel TPR Shadow */
-#define X86_FEATURE_VNMI        ( 8*32+ 1) /* Intel Virtual NMI */
-#define X86_FEATURE_FLEXPRIORITY ( 8*32+ 2) /* Intel FlexPriority */
-#define X86_FEATURE_EPT         ( 8*32+ 3) /* Intel Extended Page Table */
-#define X86_FEATURE_VPID        ( 8*32+ 4) /* Intel Virtual Processor ID */
-#define X86_FEATURE_NPT		( 8*32+ 5) /* AMD Nested Page Table support */
-#define X86_FEATURE_LBRV	( 8*32+ 6) /* AMD LBR Virtualization support */
-#define X86_FEATURE_SVML	( 8*32+ 7) /* "svm_lock" AMD SVM locking MSR */
-#define X86_FEATURE_NRIPS	( 8*32+ 8) /* "nrip_save" AMD SVM next_rip save */
-#define X86_FEATURE_TSCRATEMSR  ( 8*32+ 9) /* "tsc_scale" AMD TSC scaling support */
-#define X86_FEATURE_VMCBCLEAN   ( 8*32+10) /* "vmcb_clean" AMD VMCB clean bits support */
-#define X86_FEATURE_FLUSHBYASID ( 8*32+11) /* AMD flush-by-ASID support */
-#define X86_FEATURE_DECODEASSISTS ( 8*32+12) /* AMD Decode Assists support */
-#define X86_FEATURE_PAUSEFILTER ( 8*32+13) /* AMD filtered pause intercept */
-#define X86_FEATURE_PFTHRESHOLD ( 8*32+14) /* AMD pause filter threshold */
-#define X86_FEATURE_VMMCALL     ( 8*32+15) /* Prefer vmmcall to vmcall */
-#define X86_FEATURE_XENPV       ( 8*32+16) /* "" Xen paravirtual guest */
-
-
-/* Intel-defined CPU features, CPUID level 0x00000007:0 (ebx), word 9 */
-#define X86_FEATURE_FSGSBASE	( 9*32+ 0) /* {RD/WR}{FS/GS}BASE instructions*/
-#define X86_FEATURE_TSC_ADJUST	( 9*32+ 1) /* TSC adjustment MSR 0x3b */
-#define X86_FEATURE_BMI1	( 9*32+ 3) /* 1st group bit manipulation extensions */
-#define X86_FEATURE_HLE		( 9*32+ 4) /* Hardware Lock Elision */
-#define X86_FEATURE_AVX2	( 9*32+ 5) /* AVX2 instructions */
-#define X86_FEATURE_SMEP	( 9*32+ 7) /* Supervisor Mode Execution Protection */
-#define X86_FEATURE_BMI2	( 9*32+ 8) /* 2nd group bit manipulation extensions */
-#define X86_FEATURE_ERMS	( 9*32+ 9) /* Enhanced REP MOVSB/STOSB */
-#define X86_FEATURE_INVPCID	( 9*32+10) /* Invalidate Processor Context ID */
-#define X86_FEATURE_RTM		( 9*32+11) /* Restricted Transactional Memory */
-#define X86_FEATURE_CQM		( 9*32+12) /* Cache QoS Monitoring */
-#define X86_FEATURE_MPX		( 9*32+14) /* Memory Protection Extension */
-#define X86_FEATURE_AVX512F	( 9*32+16) /* AVX-512 Foundation */
-#define X86_FEATURE_RDSEED	( 9*32+18) /* The RDSEED instruction */
-#define X86_FEATURE_ADX		( 9*32+19) /* The ADCX and ADOX instructions */
-#define X86_FEATURE_SMAP	( 9*32+20) /* Supervisor Mode Access Prevention */
-#define X86_FEATURE_PCOMMIT	( 9*32+22) /* PCOMMIT instruction */
-#define X86_FEATURE_CLFLUSHOPT	( 9*32+23) /* CLFLUSHOPT instruction */
-#define X86_FEATURE_CLWB	( 9*32+24) /* CLWB instruction */
-#define X86_FEATURE_AVX512PF	( 9*32+26) /* AVX-512 Prefetch */
-#define X86_FEATURE_AVX512ER	( 9*32+27) /* AVX-512 Exponential and Reciprocal */
-#define X86_FEATURE_AVX512CD	( 9*32+28) /* AVX-512 Conflict Detection */
-#define X86_FEATURE_SHA_NI	( 9*32+29) /* SHA1/SHA256 Instruction Extensions */
-
-/* Extended state features, CPUID level 0x0000000d:1 (eax), word 10 */
-#define X86_FEATURE_XSAVEOPT	(10*32+ 0) /* XSAVEOPT */
-#define X86_FEATURE_XSAVEC	(10*32+ 1) /* XSAVEC */
-#define X86_FEATURE_XGETBV1	(10*32+ 2) /* XGETBV with ECX = 1 */
-#define X86_FEATURE_XSAVES	(10*32+ 3) /* XSAVES/XRSTORS */
-
-/* Intel-defined CPU QoS Sub-leaf, CPUID level 0x0000000F:0 (edx), word 11 */
-#define X86_FEATURE_CQM_LLC	(11*32+ 1) /* LLC QoS if 1 */
-
-/* Intel-defined CPU QoS Sub-leaf, CPUID level 0x0000000F:1 (edx), word 12 */
-#define X86_FEATURE_CQM_OCCUP_LLC (12*32+ 0) /* LLC occupancy monitoring if 1 */
-
-/* AMD-defined CPU features, CPUID level 0x80000008 (ebx), word 13 */
-#define X86_FEATURE_CLZERO	(13*32+0) /* CLZERO instruction */
-
-/*
- * BUG word(s)
- */
-#define X86_BUG(x)		(NCAPINTS*32 + (x))
-
-#define X86_BUG_F00F		X86_BUG(0) /* Intel F00F */
-#define X86_BUG_FDIV		X86_BUG(1) /* FPU FDIV */
-#define X86_BUG_COMA		X86_BUG(2) /* Cyrix 6x86 coma */
-#define X86_BUG_AMD_TLB_MMATCH	X86_BUG(3) /* "tlb_mmatch" AMD Erratum 383 */
-#define X86_BUG_AMD_APIC_C1E	X86_BUG(4) /* "apic_c1e" AMD Erratum 400 */
-#define X86_BUG_11AP		X86_BUG(5) /* Bad local APIC aka 11AP */
-#define X86_BUG_FXSAVE_LEAK	X86_BUG(6) /* FXSAVE leaks FOP/FIP/FOP */
-#define X86_BUG_CLFLUSH_MONITOR	X86_BUG(7) /* AAI65, CLFLUSH required before MONITOR */
-#define X86_BUG_SYSRET_SS_ATTRS	X86_BUG(8) /* SYSRET doesn't fix up SS attrs */
+#include <asm/processor.h>
 
 #if defined(__KERNEL__) && !defined(__ASSEMBLY__)
 
--- /dev/null
+++ zfcpdump-kernel-4.4/arch/x86/include/asm/cpufeatures.h
@@ -0,0 +1,291 @@
+#ifndef _ASM_X86_CPUFEATURES_H
+#define _ASM_X86_CPUFEATURES_H
+
+#ifndef _ASM_X86_REQUIRED_FEATURES_H
+#include <asm/required-features.h>
+#endif
+
+#ifndef _ASM_X86_DISABLED_FEATURES_H
+#include <asm/disabled-features.h>
+#endif
+
+/*
+ * Defines x86 CPU feature bits
+ */
+#define NCAPINTS	16	/* N 32-bit words worth of info */
+#define NBUGINTS	1	/* N 32-bit bug flags */
+
+/*
+ * Note: If the comment begins with a quoted string, that string is used
+ * in /proc/cpuinfo instead of the macro name.  If the string is "",
+ * this feature bit is not displayed in /proc/cpuinfo at all.
+ */
+
+/* Intel-defined CPU features, CPUID level 0x00000001 (edx), word 0 */
+#define X86_FEATURE_FPU		( 0*32+ 0) /* Onboard FPU */
+#define X86_FEATURE_VME		( 0*32+ 1) /* Virtual Mode Extensions */
+#define X86_FEATURE_DE		( 0*32+ 2) /* Debugging Extensions */
+#define X86_FEATURE_PSE		( 0*32+ 3) /* Page Size Extensions */
+#define X86_FEATURE_TSC		( 0*32+ 4) /* Time Stamp Counter */
+#define X86_FEATURE_MSR		( 0*32+ 5) /* Model-Specific Registers */
+#define X86_FEATURE_PAE		( 0*32+ 6) /* Physical Address Extensions */
+#define X86_FEATURE_MCE		( 0*32+ 7) /* Machine Check Exception */
+#define X86_FEATURE_CX8		( 0*32+ 8) /* CMPXCHG8 instruction */
+#define X86_FEATURE_APIC	( 0*32+ 9) /* Onboard APIC */
+#define X86_FEATURE_SEP		( 0*32+11) /* SYSENTER/SYSEXIT */
+#define X86_FEATURE_MTRR	( 0*32+12) /* Memory Type Range Registers */
+#define X86_FEATURE_PGE		( 0*32+13) /* Page Global Enable */
+#define X86_FEATURE_MCA		( 0*32+14) /* Machine Check Architecture */
+#define X86_FEATURE_CMOV	( 0*32+15) /* CMOV instructions */
+					  /* (plus FCMOVcc, FCOMI with FPU) */
+#define X86_FEATURE_PAT		( 0*32+16) /* Page Attribute Table */
+#define X86_FEATURE_PSE36	( 0*32+17) /* 36-bit PSEs */
+#define X86_FEATURE_PN		( 0*32+18) /* Processor serial number */
+#define X86_FEATURE_CLFLUSH	( 0*32+19) /* CLFLUSH instruction */
+#define X86_FEATURE_DS		( 0*32+21) /* "dts" Debug Store */
+#define X86_FEATURE_ACPI	( 0*32+22) /* ACPI via MSR */
+#define X86_FEATURE_MMX		( 0*32+23) /* Multimedia Extensions */
+#define X86_FEATURE_FXSR	( 0*32+24) /* FXSAVE/FXRSTOR, CR4.OSFXSR */
+#define X86_FEATURE_XMM		( 0*32+25) /* "sse" */
+#define X86_FEATURE_XMM2	( 0*32+26) /* "sse2" */
+#define X86_FEATURE_SELFSNOOP	( 0*32+27) /* "ss" CPU self snoop */
+#define X86_FEATURE_HT		( 0*32+28) /* Hyper-Threading */
+#define X86_FEATURE_ACC		( 0*32+29) /* "tm" Automatic clock control */
+#define X86_FEATURE_IA64	( 0*32+30) /* IA-64 processor */
+#define X86_FEATURE_PBE		( 0*32+31) /* Pending Break Enable */
+
+/* AMD-defined CPU features, CPUID level 0x80000001, word 1 */
+/* Don't duplicate feature flags which are redundant with Intel! */
+#define X86_FEATURE_SYSCALL	( 1*32+11) /* SYSCALL/SYSRET */
+#define X86_FEATURE_MP		( 1*32+19) /* MP Capable. */
+#define X86_FEATURE_NX		( 1*32+20) /* Execute Disable */
+#define X86_FEATURE_MMXEXT	( 1*32+22) /* AMD MMX extensions */
+#define X86_FEATURE_FXSR_OPT	( 1*32+25) /* FXSAVE/FXRSTOR optimizations */
+#define X86_FEATURE_GBPAGES	( 1*32+26) /* "pdpe1gb" GB pages */
+#define X86_FEATURE_RDTSCP	( 1*32+27) /* RDTSCP */
+#define X86_FEATURE_LM		( 1*32+29) /* Long Mode (x86-64) */
+#define X86_FEATURE_3DNOWEXT	( 1*32+30) /* AMD 3DNow! extensions */
+#define X86_FEATURE_3DNOW	( 1*32+31) /* 3DNow! */
+
+/* Transmeta-defined CPU features, CPUID level 0x80860001, word 2 */
+#define X86_FEATURE_RECOVERY	( 2*32+ 0) /* CPU in recovery mode */
+#define X86_FEATURE_LONGRUN	( 2*32+ 1) /* Longrun power control */
+#define X86_FEATURE_LRTI	( 2*32+ 3) /* LongRun table interface */
+
+/* Other features, Linux-defined mapping, word 3 */
+/* This range is used for feature bits which conflict or are synthesized */
+#define X86_FEATURE_CXMMX	( 3*32+ 0) /* Cyrix MMX extensions */
+#define X86_FEATURE_K6_MTRR	( 3*32+ 1) /* AMD K6 nonstandard MTRRs */
+#define X86_FEATURE_CYRIX_ARR	( 3*32+ 2) /* Cyrix ARRs (= MTRRs) */
+#define X86_FEATURE_CENTAUR_MCR	( 3*32+ 3) /* Centaur MCRs (= MTRRs) */
+/* cpu types for specific tunings: */
+#define X86_FEATURE_K8		( 3*32+ 4) /* "" Opteron, Athlon64 */
+#define X86_FEATURE_K7		( 3*32+ 5) /* "" Athlon */
+#define X86_FEATURE_P3		( 3*32+ 6) /* "" P3 */
+#define X86_FEATURE_P4		( 3*32+ 7) /* "" P4 */
+#define X86_FEATURE_CONSTANT_TSC ( 3*32+ 8) /* TSC ticks at a constant rate */
+#define X86_FEATURE_UP		( 3*32+ 9) /* smp kernel running on up */
+#define X86_FEATURE_ART		( 3*32+10) /* Platform has always running timer (ART) */
+#define X86_FEATURE_ARCH_PERFMON ( 3*32+11) /* Intel Architectural PerfMon */
+#define X86_FEATURE_PEBS	( 3*32+12) /* Precise-Event Based Sampling */
+#define X86_FEATURE_BTS		( 3*32+13) /* Branch Trace Store */
+#define X86_FEATURE_SYSCALL32	( 3*32+14) /* "" syscall in ia32 userspace */
+#define X86_FEATURE_SYSENTER32	( 3*32+15) /* "" sysenter in ia32 userspace */
+#define X86_FEATURE_REP_GOOD	( 3*32+16) /* rep microcode works well */
+#define X86_FEATURE_MFENCE_RDTSC ( 3*32+17) /* "" Mfence synchronizes RDTSC */
+#define X86_FEATURE_LFENCE_RDTSC ( 3*32+18) /* "" Lfence synchronizes RDTSC */
+/* free, was #define X86_FEATURE_11AP	( 3*32+19) * "" Bad local APIC aka 11AP */
+#define X86_FEATURE_NOPL	( 3*32+20) /* The NOPL (0F 1F) instructions */
+#define X86_FEATURE_ALWAYS	( 3*32+21) /* "" Always-present feature */
+#define X86_FEATURE_XTOPOLOGY	( 3*32+22) /* cpu topology enum extensions */
+#define X86_FEATURE_TSC_RELIABLE ( 3*32+23) /* TSC is known to be reliable */
+#define X86_FEATURE_NONSTOP_TSC	( 3*32+24) /* TSC does not stop in C states */
+/* free, was #define X86_FEATURE_CLFLUSH_MONITOR ( 3*32+25) * "" clflush reqd with monitor */
+#define X86_FEATURE_EXTD_APICID	( 3*32+26) /* has extended APICID (8 bits) */
+#define X86_FEATURE_AMD_DCM     ( 3*32+27) /* multi-node processor */
+#define X86_FEATURE_APERFMPERF	( 3*32+28) /* APERFMPERF */
+#define X86_FEATURE_EAGER_FPU	( 3*32+29) /* "eagerfpu" Non lazy FPU restore */
+#define X86_FEATURE_NONSTOP_TSC_S3 ( 3*32+30) /* TSC doesn't stop in S3 state */
+
+/* Intel-defined CPU features, CPUID level 0x00000001 (ecx), word 4 */
+#define X86_FEATURE_XMM3	( 4*32+ 0) /* "pni" SSE-3 */
+#define X86_FEATURE_PCLMULQDQ	( 4*32+ 1) /* PCLMULQDQ instruction */
+#define X86_FEATURE_DTES64	( 4*32+ 2) /* 64-bit Debug Store */
+#define X86_FEATURE_MWAIT	( 4*32+ 3) /* "monitor" Monitor/Mwait support */
+#define X86_FEATURE_DSCPL	( 4*32+ 4) /* "ds_cpl" CPL Qual. Debug Store */
+#define X86_FEATURE_VMX		( 4*32+ 5) /* Hardware virtualization */
+#define X86_FEATURE_SMX		( 4*32+ 6) /* Safer mode */
+#define X86_FEATURE_EST		( 4*32+ 7) /* Enhanced SpeedStep */
+#define X86_FEATURE_TM2		( 4*32+ 8) /* Thermal Monitor 2 */
+#define X86_FEATURE_SSSE3	( 4*32+ 9) /* Supplemental SSE-3 */
+#define X86_FEATURE_CID		( 4*32+10) /* Context ID */
+#define X86_FEATURE_SDBG	( 4*32+11) /* Silicon Debug */
+#define X86_FEATURE_FMA		( 4*32+12) /* Fused multiply-add */
+#define X86_FEATURE_CX16	( 4*32+13) /* CMPXCHG16B */
+#define X86_FEATURE_XTPR	( 4*32+14) /* Send Task Priority Messages */
+#define X86_FEATURE_PDCM	( 4*32+15) /* Performance Capabilities */
+#define X86_FEATURE_PCID	( 4*32+17) /* Process Context Identifiers */
+#define X86_FEATURE_DCA		( 4*32+18) /* Direct Cache Access */
+#define X86_FEATURE_XMM4_1	( 4*32+19) /* "sse4_1" SSE-4.1 */
+#define X86_FEATURE_XMM4_2	( 4*32+20) /* "sse4_2" SSE-4.2 */
+#define X86_FEATURE_X2APIC	( 4*32+21) /* x2APIC */
+#define X86_FEATURE_MOVBE	( 4*32+22) /* MOVBE instruction */
+#define X86_FEATURE_POPCNT      ( 4*32+23) /* POPCNT instruction */
+#define X86_FEATURE_TSC_DEADLINE_TIMER	( 4*32+24) /* Tsc deadline timer */
+#define X86_FEATURE_AES		( 4*32+25) /* AES instructions */
+#define X86_FEATURE_XSAVE	( 4*32+26) /* XSAVE/XRSTOR/XSETBV/XGETBV */
+#define X86_FEATURE_OSXSAVE	( 4*32+27) /* "" XSAVE enabled in the OS */
+#define X86_FEATURE_AVX		( 4*32+28) /* Advanced Vector Extensions */
+#define X86_FEATURE_F16C	( 4*32+29) /* 16-bit fp conversions */
+#define X86_FEATURE_RDRAND	( 4*32+30) /* The RDRAND instruction */
+#define X86_FEATURE_HYPERVISOR	( 4*32+31) /* Running on a hypervisor */
+
+/* VIA/Cyrix/Centaur-defined CPU features, CPUID level 0xC0000001, word 5 */
+#define X86_FEATURE_XSTORE	( 5*32+ 2) /* "rng" RNG present (xstore) */
+#define X86_FEATURE_XSTORE_EN	( 5*32+ 3) /* "rng_en" RNG enabled */
+#define X86_FEATURE_XCRYPT	( 5*32+ 6) /* "ace" on-CPU crypto (xcrypt) */
+#define X86_FEATURE_XCRYPT_EN	( 5*32+ 7) /* "ace_en" on-CPU crypto enabled */
+#define X86_FEATURE_ACE2	( 5*32+ 8) /* Advanced Cryptography Engine v2 */
+#define X86_FEATURE_ACE2_EN	( 5*32+ 9) /* ACE v2 enabled */
+#define X86_FEATURE_PHE		( 5*32+10) /* PadLock Hash Engine */
+#define X86_FEATURE_PHE_EN	( 5*32+11) /* PHE enabled */
+#define X86_FEATURE_PMM		( 5*32+12) /* PadLock Montgomery Multiplier */
+#define X86_FEATURE_PMM_EN	( 5*32+13) /* PMM enabled */
+
+/* More extended AMD flags: CPUID level 0x80000001, ecx, word 6 */
+#define X86_FEATURE_LAHF_LM	( 6*32+ 0) /* LAHF/SAHF in long mode */
+#define X86_FEATURE_CMP_LEGACY	( 6*32+ 1) /* If yes HyperThreading not valid */
+#define X86_FEATURE_SVM		( 6*32+ 2) /* Secure virtual machine */
+#define X86_FEATURE_EXTAPIC	( 6*32+ 3) /* Extended APIC space */
+#define X86_FEATURE_CR8_LEGACY	( 6*32+ 4) /* CR8 in 32-bit mode */
+#define X86_FEATURE_ABM		( 6*32+ 5) /* Advanced bit manipulation */
+#define X86_FEATURE_SSE4A	( 6*32+ 6) /* SSE-4A */
+#define X86_FEATURE_MISALIGNSSE ( 6*32+ 7) /* Misaligned SSE mode */
+#define X86_FEATURE_3DNOWPREFETCH ( 6*32+ 8) /* 3DNow prefetch instructions */
+#define X86_FEATURE_OSVW	( 6*32+ 9) /* OS Visible Workaround */
+#define X86_FEATURE_IBS		( 6*32+10) /* Instruction Based Sampling */
+#define X86_FEATURE_XOP		( 6*32+11) /* extended AVX instructions */
+#define X86_FEATURE_SKINIT	( 6*32+12) /* SKINIT/STGI instructions */
+#define X86_FEATURE_WDT		( 6*32+13) /* Watchdog timer */
+#define X86_FEATURE_LWP		( 6*32+15) /* Light Weight Profiling */
+#define X86_FEATURE_FMA4	( 6*32+16) /* 4 operands MAC instructions */
+#define X86_FEATURE_TCE		( 6*32+17) /* translation cache extension */
+#define X86_FEATURE_NODEID_MSR	( 6*32+19) /* NodeId MSR */
+#define X86_FEATURE_TBM		( 6*32+21) /* trailing bit manipulations */
+#define X86_FEATURE_TOPOEXT	( 6*32+22) /* topology extensions CPUID leafs */
+#define X86_FEATURE_PERFCTR_CORE ( 6*32+23) /* core performance counter extensions */
+#define X86_FEATURE_PERFCTR_NB  ( 6*32+24) /* NB performance counter extensions */
+#define X86_FEATURE_BPEXT	(6*32+26) /* data breakpoint extension */
+#define X86_FEATURE_PERFCTR_L2	( 6*32+28) /* L2 performance counter extensions */
+#define X86_FEATURE_MWAITX	( 6*32+29) /* MWAIT extension (MONITORX/MWAITX) */
+
+/*
+ * Auxiliary flags: Linux defined - For features scattered in various
+ * CPUID levels like 0x6, 0xA etc, word 7.
+ *
+ * Reuse free bits when adding new feature flags!
+ */
+
+#define X86_FEATURE_CPB		( 7*32+ 2) /* AMD Core Performance Boost */
+#define X86_FEATURE_EPB		( 7*32+ 3) /* IA32_ENERGY_PERF_BIAS support */
+
+#define X86_FEATURE_HW_PSTATE	( 7*32+ 8) /* AMD HW-PState */
+#define X86_FEATURE_PROC_FEEDBACK ( 7*32+ 9) /* AMD ProcFeedbackInterface */
+
+#define X86_FEATURE_INTEL_PT	( 7*32+15) /* Intel Processor Trace */
+
+/* Virtualization flags: Linux defined, word 8 */
+#define X86_FEATURE_TPR_SHADOW  ( 8*32+ 0) /* Intel TPR Shadow */
+#define X86_FEATURE_VNMI        ( 8*32+ 1) /* Intel Virtual NMI */
+#define X86_FEATURE_FLEXPRIORITY ( 8*32+ 2) /* Intel FlexPriority */
+#define X86_FEATURE_EPT         ( 8*32+ 3) /* Intel Extended Page Table */
+#define X86_FEATURE_VPID        ( 8*32+ 4) /* Intel Virtual Processor ID */
+
+#define X86_FEATURE_VMMCALL     ( 8*32+15) /* Prefer vmmcall to vmcall */
+#define X86_FEATURE_XENPV       ( 8*32+16) /* "" Xen paravirtual guest */
+
+
+/* Intel-defined CPU features, CPUID level 0x00000007:0 (ebx), word 9 */
+#define X86_FEATURE_FSGSBASE	( 9*32+ 0) /* {RD/WR}{FS/GS}BASE instructions*/
+#define X86_FEATURE_TSC_ADJUST	( 9*32+ 1) /* TSC adjustment MSR 0x3b */
+#define X86_FEATURE_BMI1	( 9*32+ 3) /* 1st group bit manipulation extensions */
+#define X86_FEATURE_HLE		( 9*32+ 4) /* Hardware Lock Elision */
+#define X86_FEATURE_AVX2	( 9*32+ 5) /* AVX2 instructions */
+#define X86_FEATURE_SMEP	( 9*32+ 7) /* Supervisor Mode Execution Protection */
+#define X86_FEATURE_BMI2	( 9*32+ 8) /* 2nd group bit manipulation extensions */
+#define X86_FEATURE_ERMS	( 9*32+ 9) /* Enhanced REP MOVSB/STOSB */
+#define X86_FEATURE_INVPCID	( 9*32+10) /* Invalidate Processor Context ID */
+#define X86_FEATURE_RTM		( 9*32+11) /* Restricted Transactional Memory */
+#define X86_FEATURE_CQM		( 9*32+12) /* Cache QoS Monitoring */
+#define X86_FEATURE_MPX		( 9*32+14) /* Memory Protection Extension */
+#define X86_FEATURE_AVX512F	( 9*32+16) /* AVX-512 Foundation */
+#define X86_FEATURE_RDSEED	( 9*32+18) /* The RDSEED instruction */
+#define X86_FEATURE_ADX		( 9*32+19) /* The ADCX and ADOX instructions */
+#define X86_FEATURE_SMAP	( 9*32+20) /* Supervisor Mode Access Prevention */
+#define X86_FEATURE_PCOMMIT	( 9*32+22) /* PCOMMIT instruction */
+#define X86_FEATURE_CLFLUSHOPT	( 9*32+23) /* CLFLUSHOPT instruction */
+#define X86_FEATURE_CLWB	( 9*32+24) /* CLWB instruction */
+#define X86_FEATURE_AVX512PF	( 9*32+26) /* AVX-512 Prefetch */
+#define X86_FEATURE_AVX512ER	( 9*32+27) /* AVX-512 Exponential and Reciprocal */
+#define X86_FEATURE_AVX512CD	( 9*32+28) /* AVX-512 Conflict Detection */
+#define X86_FEATURE_SHA_NI	( 9*32+29) /* SHA1/SHA256 Instruction Extensions */
+
+/* Extended state features, CPUID level 0x0000000d:1 (eax), word 10 */
+#define X86_FEATURE_XSAVEOPT	(10*32+ 0) /* XSAVEOPT */
+#define X86_FEATURE_XSAVEC	(10*32+ 1) /* XSAVEC */
+#define X86_FEATURE_XGETBV1	(10*32+ 2) /* XGETBV with ECX = 1 */
+#define X86_FEATURE_XSAVES	(10*32+ 3) /* XSAVES/XRSTORS */
+
+/* Intel-defined CPU QoS Sub-leaf, CPUID level 0x0000000F:0 (edx), word 11 */
+#define X86_FEATURE_CQM_LLC	(11*32+ 1) /* LLC QoS if 1 */
+
+/* Intel-defined CPU QoS Sub-leaf, CPUID level 0x0000000F:1 (edx), word 12 */
+#define X86_FEATURE_CQM_OCCUP_LLC (12*32+ 0) /* LLC occupancy monitoring if 1 */
+#define X86_FEATURE_CQM_MBM_TOTAL (12*32+ 1) /* LLC Total MBM monitoring */
+#define X86_FEATURE_CQM_MBM_LOCAL (12*32+ 2) /* LLC Local MBM monitoring */
+
+/* AMD-defined CPU features, CPUID level 0x80000008 (ebx), word 13 */
+#define X86_FEATURE_CLZERO	(13*32+0) /* CLZERO instruction */
+
+/* Thermal and Power Management Leaf, CPUID level 0x00000006 (eax), word 14 */
+#define X86_FEATURE_DTHERM	(14*32+ 0) /* Digital Thermal Sensor */
+#define X86_FEATURE_IDA		(14*32+ 1) /* Intel Dynamic Acceleration */
+#define X86_FEATURE_ARAT	(14*32+ 2) /* Always Running APIC Timer */
+#define X86_FEATURE_PLN		(14*32+ 4) /* Intel Power Limit Notification */
+#define X86_FEATURE_PTS		(14*32+ 6) /* Intel Package Thermal Status */
+#define X86_FEATURE_HWP		(14*32+ 7) /* Intel Hardware P-states */
+#define X86_FEATURE_HWP_NOTIFY	(14*32+ 8) /* HWP Notification */
+#define X86_FEATURE_HWP_ACT_WINDOW (14*32+ 9) /* HWP Activity Window */
+#define X86_FEATURE_HWP_EPP	(14*32+10) /* HWP Energy Perf. Preference */
+#define X86_FEATURE_HWP_PKG_REQ (14*32+11) /* HWP Package Level Request */
+
+/* AMD SVM Feature Identification, CPUID level 0x8000000a (edx), word 15 */
+#define X86_FEATURE_NPT		(15*32+ 0) /* Nested Page Table support */
+#define X86_FEATURE_LBRV	(15*32+ 1) /* LBR Virtualization support */
+#define X86_FEATURE_SVML	(15*32+ 2) /* "svm_lock" SVM locking MSR */
+#define X86_FEATURE_NRIPS	(15*32+ 3) /* "nrip_save" SVM next_rip save */
+#define X86_FEATURE_TSCRATEMSR  (15*32+ 4) /* "tsc_scale" TSC scaling support */
+#define X86_FEATURE_VMCBCLEAN   (15*32+ 5) /* "vmcb_clean" VMCB clean bits support */
+#define X86_FEATURE_FLUSHBYASID (15*32+ 6) /* flush-by-ASID support */
+#define X86_FEATURE_DECODEASSISTS (15*32+ 7) /* Decode Assists support */
+#define X86_FEATURE_PAUSEFILTER (15*32+10) /* filtered pause intercept */
+#define X86_FEATURE_PFTHRESHOLD (15*32+12) /* pause filter threshold */
+#define X86_FEATURE_AVIC	(15*32+13) /* Virtual Interrupt Controller */
+
+/*
+ * BUG word(s)
+ */
+#define X86_BUG(x)		(NCAPINTS*32 + (x))
+
+#define X86_BUG_F00F		X86_BUG(0) /* Intel F00F */
+#define X86_BUG_FDIV		X86_BUG(1) /* FPU FDIV */
+#define X86_BUG_COMA		X86_BUG(2) /* Cyrix 6x86 coma */
+#define X86_BUG_AMD_TLB_MMATCH	X86_BUG(3) /* "tlb_mmatch" AMD Erratum 383 */
+#define X86_BUG_AMD_APIC_C1E	X86_BUG(4) /* "apic_c1e" AMD Erratum 400 */
+#define X86_BUG_11AP		X86_BUG(5) /* Bad local APIC aka 11AP */
+#define X86_BUG_FXSAVE_LEAK	X86_BUG(6) /* FXSAVE leaks FOP/FIP/FOP */
+#define X86_BUG_CLFLUSH_MONITOR	X86_BUG(7) /* AAI65, CLFLUSH required before MONITOR */
+#define X86_BUG_SYSRET_SS_ATTRS	X86_BUG(8) /* SYSRET doesn't fix up SS attrs */
+
+#define X86_BUG_MONITOR		X86_BUG(12) /* IPI required to wake up remote CPU */
+#endif /* _ASM_X86_CPUFEATURES_H */
--- zfcpdump-kernel-4.4.orig/arch/x86/include/asm/fpu/internal.h
+++ zfcpdump-kernel-4.4/arch/x86/include/asm/fpu/internal.h
@@ -17,6 +17,7 @@
 #include <asm/user.h>
 #include <asm/fpu/api.h>
 #include <asm/fpu/xstate.h>
+#include <asm/cpufeature.h>
 
 /*
  * High level FPU state handling functions:
--- zfcpdump-kernel-4.4.orig/arch/x86/include/asm/hugetlb.h
+++ zfcpdump-kernel-4.4/arch/x86/include/asm/hugetlb.h
@@ -4,6 +4,7 @@
 #include <asm/page.h>
 #include <asm-generic/hugetlb.h>
 
+#define hugepages_supported() cpu_has_pse
 
 static inline int is_hugepage_only_range(struct mm_struct *mm,
 					 unsigned long addr,
--- zfcpdump-kernel-4.4.orig/arch/x86/include/asm/hw_irq.h
+++ zfcpdump-kernel-4.4/arch/x86/include/asm/hw_irq.h
@@ -136,6 +136,7 @@ struct irq_alloc_info {
 struct irq_cfg {
 	unsigned int		dest_apicid;
 	u8			vector;
+	u8			old_vector;
 };
 
 extern struct irq_cfg *irq_cfg(unsigned int irq);
--- zfcpdump-kernel-4.4.orig/arch/x86/include/asm/inat.h
+++ zfcpdump-kernel-4.4/arch/x86/include/asm/inat.h
@@ -48,6 +48,7 @@
 /* AVX VEX prefixes */
 #define INAT_PFX_VEX2	13	/* 2-bytes VEX prefix */
 #define INAT_PFX_VEX3	14	/* 3-bytes VEX prefix */
+#define INAT_PFX_EVEX	15	/* EVEX prefix */
 
 #define INAT_LSTPFX_MAX	3
 #define INAT_LGCPFX_MAX	11
@@ -89,6 +90,7 @@
 #define INAT_VARIANT	(1 << (INAT_FLAG_OFFS + 4))
 #define INAT_VEXOK	(1 << (INAT_FLAG_OFFS + 5))
 #define INAT_VEXONLY	(1 << (INAT_FLAG_OFFS + 6))
+#define INAT_EVEXONLY	(1 << (INAT_FLAG_OFFS + 7))
 /* Attribute making macros for attribute tables */
 #define INAT_MAKE_PREFIX(pfx)	(pfx << INAT_PFX_OFFS)
 #define INAT_MAKE_ESCAPE(esc)	(esc << INAT_ESC_OFFS)
@@ -141,7 +143,13 @@ static inline int inat_last_prefix_id(in
 static inline int inat_is_vex_prefix(insn_attr_t attr)
 {
 	attr &= INAT_PFX_MASK;
-	return attr == INAT_PFX_VEX2 || attr == INAT_PFX_VEX3;
+	return attr == INAT_PFX_VEX2 || attr == INAT_PFX_VEX3 ||
+	       attr == INAT_PFX_EVEX;
+}
+
+static inline int inat_is_evex_prefix(insn_attr_t attr)
+{
+	return (attr & INAT_PFX_MASK) == INAT_PFX_EVEX;
 }
 
 static inline int inat_is_vex3_prefix(insn_attr_t attr)
@@ -216,6 +224,11 @@ static inline int inat_accept_vex(insn_a
 
 static inline int inat_must_vex(insn_attr_t attr)
 {
-	return attr & INAT_VEXONLY;
+	return attr & (INAT_VEXONLY | INAT_EVEXONLY);
+}
+
+static inline int inat_must_evex(insn_attr_t attr)
+{
+	return attr & INAT_EVEXONLY;
 }
 #endif
--- zfcpdump-kernel-4.4.orig/arch/x86/include/asm/insn.h
+++ zfcpdump-kernel-4.4/arch/x86/include/asm/insn.h
@@ -91,6 +91,7 @@ struct insn {
 #define X86_VEX_B(vex)	((vex) & 0x20)	/* VEX3 Byte1 */
 #define X86_VEX_L(vex)	((vex) & 0x04)	/* VEX3 Byte2, VEX2 Byte1 */
 /* VEX bit fields */
+#define X86_EVEX_M(vex)	((vex) & 0x03)		/* EVEX Byte1 */
 #define X86_VEX3_M(vex)	((vex) & 0x1f)		/* VEX3 Byte1 */
 #define X86_VEX2_M	1			/* VEX2.M always 1 */
 #define X86_VEX_V(vex)	(((vex) & 0x78) >> 3)	/* VEX3 Byte2, VEX2 Byte1 */
@@ -133,6 +134,13 @@ static inline int insn_is_avx(struct ins
 	return (insn->vex_prefix.value != 0);
 }
 
+static inline int insn_is_evex(struct insn *insn)
+{
+	if (!insn->prefixes.got)
+		insn_get_prefixes(insn);
+	return (insn->vex_prefix.nbytes == 4);
+}
+
 /* Ensure this instruction is decoded completely */
 static inline int insn_complete(struct insn *insn)
 {
@@ -144,8 +152,10 @@ static inline insn_byte_t insn_vex_m_bit
 {
 	if (insn->vex_prefix.nbytes == 2)	/* 2 bytes VEX */
 		return X86_VEX2_M;
-	else
+	else if (insn->vex_prefix.nbytes == 3)	/* 3 bytes VEX */
 		return X86_VEX3_M(insn->vex_prefix.bytes[1]);
+	else					/* EVEX */
+		return X86_EVEX_M(insn->vex_prefix.bytes[1]);
 }
 
 static inline insn_byte_t insn_vex_p_bits(struct insn *insn)
--- /dev/null
+++ zfcpdump-kernel-4.4/arch/x86/include/asm/intel-family.h
@@ -0,0 +1,68 @@
+#ifndef _ASM_X86_INTEL_FAMILY_H
+#define _ASM_X86_INTEL_FAMILY_H
+
+/*
+ * "Big Core" Processors (Branded as Core, Xeon, etc...)
+ *
+ * The "_X" parts are generally the EP and EX Xeons, or the
+ * "Extreme" ones, like Broadwell-E.
+ *
+ * Things ending in "2" are usually because we have no better
+ * name for them.  There's no processor called "WESTMERE2".
+ */
+
+#define INTEL_FAM6_CORE_YONAH		0x0E
+#define INTEL_FAM6_CORE2_MEROM		0x0F
+#define INTEL_FAM6_CORE2_MEROM_L	0x16
+#define INTEL_FAM6_CORE2_PENRYN		0x17
+#define INTEL_FAM6_CORE2_DUNNINGTON	0x1D
+
+#define INTEL_FAM6_NEHALEM		0x1E
+#define INTEL_FAM6_NEHALEM_EP		0x1A
+#define INTEL_FAM6_NEHALEM_EX		0x2E
+#define INTEL_FAM6_WESTMERE		0x25
+#define INTEL_FAM6_WESTMERE2		0x1F
+#define INTEL_FAM6_WESTMERE_EP		0x2C
+#define INTEL_FAM6_WESTMERE_EX		0x2F
+
+#define INTEL_FAM6_SANDYBRIDGE		0x2A
+#define INTEL_FAM6_SANDYBRIDGE_X	0x2D
+#define INTEL_FAM6_IVYBRIDGE		0x3A
+#define INTEL_FAM6_IVYBRIDGE_X		0x3E
+
+#define INTEL_FAM6_HASWELL_CORE		0x3C
+#define INTEL_FAM6_HASWELL_X		0x3F
+#define INTEL_FAM6_HASWELL_ULT		0x45
+#define INTEL_FAM6_HASWELL_GT3E		0x46
+
+#define INTEL_FAM6_BROADWELL_CORE	0x3D
+#define INTEL_FAM6_BROADWELL_XEON_D	0x56
+#define INTEL_FAM6_BROADWELL_GT3E	0x47
+#define INTEL_FAM6_BROADWELL_X		0x4F
+
+#define INTEL_FAM6_SKYLAKE_MOBILE	0x4E
+#define INTEL_FAM6_SKYLAKE_DESKTOP	0x5E
+#define INTEL_FAM6_SKYLAKE_X		0x55
+#define INTEL_FAM6_KABYLAKE_MOBILE	0x8E
+#define INTEL_FAM6_KABYLAKE_DESKTOP	0x9E
+
+/* "Small Core" Processors (Atom) */
+
+#define INTEL_FAM6_ATOM_PINEVIEW	0x1C
+#define INTEL_FAM6_ATOM_LINCROFT	0x26
+#define INTEL_FAM6_ATOM_PENWELL		0x27
+#define INTEL_FAM6_ATOM_CLOVERVIEW	0x35
+#define INTEL_FAM6_ATOM_CEDARVIEW	0x36
+#define INTEL_FAM6_ATOM_SILVERMONT1	0x37 /* BayTrail/BYT / Valleyview */
+#define INTEL_FAM6_ATOM_SILVERMONT2	0x4D /* Avaton/Rangely */
+#define INTEL_FAM6_ATOM_AIRMONT		0x4C /* CherryTrail / Braswell */
+#define INTEL_FAM6_ATOM_MERRIFIELD1	0x4A /* Tangier */
+#define INTEL_FAM6_ATOM_MERRIFIELD2	0x5A /* Annidale */
+#define INTEL_FAM6_ATOM_GOLDMONT	0x5C
+#define INTEL_FAM6_ATOM_DENVERTON	0x5F /* Goldmont Microserver */
+
+/* Xeon Phi */
+
+#define INTEL_FAM6_XEON_PHI_KNL		0x57 /* Knights Landing */
+
+#endif /* _ASM_X86_INTEL_FAMILY_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/arch/x86/include/asm/intel_punit_ipc.h
@@ -0,0 +1,101 @@
+#ifndef _ASM_X86_INTEL_PUNIT_IPC_H_
+#define  _ASM_X86_INTEL_PUNIT_IPC_H_
+
+/*
+ * Three types of 8bit P-Unit IPC commands are supported,
+ * bit[7:6]: [00]: BIOS; [01]: GTD; [10]: ISPD.
+ */
+typedef enum {
+	BIOS_IPC = 0,
+	GTDRIVER_IPC,
+	ISPDRIVER_IPC,
+	RESERVED_IPC,
+} IPC_TYPE;
+
+#define IPC_TYPE_OFFSET			6
+#define IPC_PUNIT_BIOS_CMD_BASE		(BIOS_IPC << IPC_TYPE_OFFSET)
+#define IPC_PUNIT_GTD_CMD_BASE		(GTDDRIVER_IPC << IPC_TYPE_OFFSET)
+#define IPC_PUNIT_ISPD_CMD_BASE		(ISPDRIVER_IPC << IPC_TYPE_OFFSET)
+#define IPC_PUNIT_CMD_TYPE_MASK		(RESERVED_IPC << IPC_TYPE_OFFSET)
+
+/* BIOS => Pcode commands */
+#define IPC_PUNIT_BIOS_ZERO			(IPC_PUNIT_BIOS_CMD_BASE | 0x00)
+#define IPC_PUNIT_BIOS_VR_INTERFACE		(IPC_PUNIT_BIOS_CMD_BASE | 0x01)
+#define IPC_PUNIT_BIOS_READ_PCS			(IPC_PUNIT_BIOS_CMD_BASE | 0x02)
+#define IPC_PUNIT_BIOS_WRITE_PCS		(IPC_PUNIT_BIOS_CMD_BASE | 0x03)
+#define IPC_PUNIT_BIOS_READ_PCU_CONFIG		(IPC_PUNIT_BIOS_CMD_BASE | 0x04)
+#define IPC_PUNIT_BIOS_WRITE_PCU_CONFIG		(IPC_PUNIT_BIOS_CMD_BASE | 0x05)
+#define IPC_PUNIT_BIOS_READ_PL1_SETTING		(IPC_PUNIT_BIOS_CMD_BASE | 0x06)
+#define IPC_PUNIT_BIOS_WRITE_PL1_SETTING	(IPC_PUNIT_BIOS_CMD_BASE | 0x07)
+#define IPC_PUNIT_BIOS_TRIGGER_VDD_RAM		(IPC_PUNIT_BIOS_CMD_BASE | 0x08)
+#define IPC_PUNIT_BIOS_READ_TELE_INFO		(IPC_PUNIT_BIOS_CMD_BASE | 0x09)
+#define IPC_PUNIT_BIOS_READ_TELE_TRACE_CTRL	(IPC_PUNIT_BIOS_CMD_BASE | 0x0a)
+#define IPC_PUNIT_BIOS_WRITE_TELE_TRACE_CTRL	(IPC_PUNIT_BIOS_CMD_BASE | 0x0b)
+#define IPC_PUNIT_BIOS_READ_TELE_EVENT_CTRL	(IPC_PUNIT_BIOS_CMD_BASE | 0x0c)
+#define IPC_PUNIT_BIOS_WRITE_TELE_EVENT_CTRL	(IPC_PUNIT_BIOS_CMD_BASE | 0x0d)
+#define IPC_PUNIT_BIOS_READ_TELE_TRACE		(IPC_PUNIT_BIOS_CMD_BASE | 0x0e)
+#define IPC_PUNIT_BIOS_WRITE_TELE_TRACE		(IPC_PUNIT_BIOS_CMD_BASE | 0x0f)
+#define IPC_PUNIT_BIOS_READ_TELE_EVENT		(IPC_PUNIT_BIOS_CMD_BASE | 0x10)
+#define IPC_PUNIT_BIOS_WRITE_TELE_EVENT		(IPC_PUNIT_BIOS_CMD_BASE | 0x11)
+#define IPC_PUNIT_BIOS_READ_MODULE_TEMP		(IPC_PUNIT_BIOS_CMD_BASE | 0x12)
+#define IPC_PUNIT_BIOS_RESERVED			(IPC_PUNIT_BIOS_CMD_BASE | 0x13)
+#define IPC_PUNIT_BIOS_READ_VOLTAGE_OVER	(IPC_PUNIT_BIOS_CMD_BASE | 0x14)
+#define IPC_PUNIT_BIOS_WRITE_VOLTAGE_OVER	(IPC_PUNIT_BIOS_CMD_BASE | 0x15)
+#define IPC_PUNIT_BIOS_READ_RATIO_OVER		(IPC_PUNIT_BIOS_CMD_BASE | 0x16)
+#define IPC_PUNIT_BIOS_WRITE_RATIO_OVER		(IPC_PUNIT_BIOS_CMD_BASE | 0x17)
+#define IPC_PUNIT_BIOS_READ_VF_GL_CTRL		(IPC_PUNIT_BIOS_CMD_BASE | 0x18)
+#define IPC_PUNIT_BIOS_WRITE_VF_GL_CTRL		(IPC_PUNIT_BIOS_CMD_BASE | 0x19)
+#define IPC_PUNIT_BIOS_READ_FM_SOC_TEMP_THRESH	(IPC_PUNIT_BIOS_CMD_BASE | 0x1a)
+#define IPC_PUNIT_BIOS_WRITE_FM_SOC_TEMP_THRESH	(IPC_PUNIT_BIOS_CMD_BASE | 0x1b)
+
+/* GT Driver => Pcode commands */
+#define IPC_PUNIT_GTD_ZERO			(IPC_PUNIT_GTD_CMD_BASE | 0x00)
+#define IPC_PUNIT_GTD_CONFIG			(IPC_PUNIT_GTD_CMD_BASE | 0x01)
+#define IPC_PUNIT_GTD_READ_ICCP_LIC_CDYN_SCAL	(IPC_PUNIT_GTD_CMD_BASE | 0x02)
+#define IPC_PUNIT_GTD_WRITE_ICCP_LIC_CDYN_SCAL	(IPC_PUNIT_GTD_CMD_BASE | 0x03)
+#define IPC_PUNIT_GTD_GET_WM_VAL		(IPC_PUNIT_GTD_CMD_BASE | 0x06)
+#define IPC_PUNIT_GTD_WRITE_CONFIG_WISHREQ	(IPC_PUNIT_GTD_CMD_BASE | 0x07)
+#define IPC_PUNIT_GTD_READ_REQ_DUTY_CYCLE	(IPC_PUNIT_GTD_CMD_BASE | 0x16)
+#define IPC_PUNIT_GTD_DIS_VOL_FREQ_CHG_REQUEST	(IPC_PUNIT_GTD_CMD_BASE | 0x17)
+#define IPC_PUNIT_GTD_DYNA_DUTY_CYCLE_CTRL	(IPC_PUNIT_GTD_CMD_BASE | 0x1a)
+#define IPC_PUNIT_GTD_DYNA_DUTY_CYCLE_TUNING	(IPC_PUNIT_GTD_CMD_BASE | 0x1c)
+
+/* ISP Driver => Pcode commands */
+#define IPC_PUNIT_ISPD_ZERO			(IPC_PUNIT_ISPD_CMD_BASE | 0x00)
+#define IPC_PUNIT_ISPD_CONFIG			(IPC_PUNIT_ISPD_CMD_BASE | 0x01)
+#define IPC_PUNIT_ISPD_GET_ISP_LTR_VAL		(IPC_PUNIT_ISPD_CMD_BASE | 0x02)
+#define IPC_PUNIT_ISPD_ACCESS_IU_FREQ_BOUNDS	(IPC_PUNIT_ISPD_CMD_BASE | 0x03)
+#define IPC_PUNIT_ISPD_READ_CDYN_LEVEL		(IPC_PUNIT_ISPD_CMD_BASE | 0x04)
+#define IPC_PUNIT_ISPD_WRITE_CDYN_LEVEL		(IPC_PUNIT_ISPD_CMD_BASE | 0x05)
+
+/* Error codes */
+#define IPC_PUNIT_ERR_SUCCESS			0
+#define IPC_PUNIT_ERR_INVALID_CMD		1
+#define IPC_PUNIT_ERR_INVALID_PARAMETER		2
+#define IPC_PUNIT_ERR_CMD_TIMEOUT		3
+#define IPC_PUNIT_ERR_CMD_LOCKED		4
+#define IPC_PUNIT_ERR_INVALID_VR_ID		5
+#define IPC_PUNIT_ERR_VR_ERR			6
+
+#if IS_ENABLED(CONFIG_INTEL_PUNIT_IPC)
+
+int intel_punit_ipc_simple_command(int cmd, int para1, int para2);
+int intel_punit_ipc_command(u32 cmd, u32 para1, u32 para2, u32 *in, u32 *out);
+
+#else
+
+static inline int intel_punit_ipc_simple_command(int cmd,
+						  int para1, int para2)
+{
+	return -ENODEV;
+}
+
+static inline int intel_punit_ipc_command(u32 cmd, u32 para1, u32 para2,
+					  u32 *in, u32 *out)
+{
+	return -ENODEV;
+}
+
+#endif /* CONFIG_INTEL_PUNIT_IPC */
+
+#endif
--- /dev/null
+++ zfcpdump-kernel-4.4/arch/x86/include/asm/intel_telemetry.h
@@ -0,0 +1,147 @@
+/*
+ * Intel SOC Telemetry Driver Header File
+ * Copyright (C) 2015, Intel Corporation.
+ * All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ */
+#ifndef INTEL_TELEMETRY_H
+#define INTEL_TELEMETRY_H
+
+#define TELEM_MAX_EVENTS_SRAM		28
+#define TELEM_MAX_OS_ALLOCATED_EVENTS	20
+
+enum telemetry_unit {
+	TELEM_PSS = 0,
+	TELEM_IOSS,
+	TELEM_UNIT_NONE
+};
+
+struct telemetry_evtlog {
+	u32 telem_evtid;
+	u64 telem_evtlog;
+};
+
+struct telemetry_evtconfig {
+	/* Array of Event-IDs to Enable */
+	u32 *evtmap;
+
+	/* Number of Events (<29) in evtmap */
+	u8 num_evts;
+
+	/* Sampling period */
+	u8 period;
+};
+
+struct telemetry_evtmap {
+	const char *name;
+	u32 evt_id;
+};
+
+struct telemetry_unit_config {
+	struct telemetry_evtmap *telem_evts;
+	void __iomem *regmap;
+	u32 ssram_base_addr;
+	u8 ssram_evts_used;
+	u8 curr_period;
+	u8 max_period;
+	u8 min_period;
+	u32 ssram_size;
+
+};
+
+struct telemetry_plt_config {
+	struct telemetry_unit_config pss_config;
+	struct telemetry_unit_config ioss_config;
+	struct mutex telem_trace_lock;
+	struct mutex telem_lock;
+	bool telem_in_use;
+};
+
+struct telemetry_core_ops {
+	int (*get_sampling_period)(u8 *pss_min_period, u8 *pss_max_period,
+				   u8 *ioss_min_period, u8 *ioss_max_period);
+
+	int (*get_eventconfig)(struct telemetry_evtconfig *pss_evtconfig,
+			       struct telemetry_evtconfig *ioss_evtconfig,
+			       int pss_len, int ioss_len);
+
+	int (*update_events)(struct telemetry_evtconfig pss_evtconfig,
+			     struct telemetry_evtconfig ioss_evtconfig);
+
+	int (*set_sampling_period)(u8 pss_period, u8 ioss_period);
+
+	int (*get_trace_verbosity)(enum telemetry_unit telem_unit,
+				   u32 *verbosity);
+
+	int (*set_trace_verbosity)(enum telemetry_unit telem_unit,
+				   u32 verbosity);
+
+	int (*raw_read_eventlog)(enum telemetry_unit telem_unit,
+				 struct telemetry_evtlog *evtlog,
+				 int len, int log_all_evts);
+
+	int (*read_eventlog)(enum telemetry_unit telem_unit,
+			     struct telemetry_evtlog *evtlog,
+			     int len, int log_all_evts);
+
+	int (*add_events)(u8 num_pss_evts, u8 num_ioss_evts,
+			  u32 *pss_evtmap, u32 *ioss_evtmap);
+
+	int (*reset_events)(void);
+};
+
+int telemetry_set_pltdata(struct telemetry_core_ops *ops,
+			  struct telemetry_plt_config *pltconfig);
+
+int telemetry_clear_pltdata(void);
+
+int telemetry_pltconfig_valid(void);
+
+int telemetry_get_evtname(enum telemetry_unit telem_unit,
+			  const char **name, int len);
+
+int telemetry_update_events(struct telemetry_evtconfig pss_evtconfig,
+			    struct telemetry_evtconfig ioss_evtconfig);
+
+int telemetry_add_events(u8 num_pss_evts, u8 num_ioss_evts,
+			 u32 *pss_evtmap, u32 *ioss_evtmap);
+
+int telemetry_reset_events(void);
+
+int telemetry_get_eventconfig(struct telemetry_evtconfig *pss_config,
+			      struct telemetry_evtconfig *ioss_config,
+			      int pss_len, int ioss_len);
+
+int telemetry_read_events(enum telemetry_unit telem_unit,
+			  struct telemetry_evtlog *evtlog, int len);
+
+int telemetry_raw_read_events(enum telemetry_unit telem_unit,
+			      struct telemetry_evtlog *evtlog, int len);
+
+int telemetry_read_eventlog(enum telemetry_unit telem_unit,
+			    struct telemetry_evtlog *evtlog, int len);
+
+int telemetry_raw_read_eventlog(enum telemetry_unit telem_unit,
+				struct telemetry_evtlog *evtlog, int len);
+
+int telemetry_get_sampling_period(u8 *pss_min_period, u8 *pss_max_period,
+				  u8 *ioss_min_period, u8 *ioss_max_period);
+
+int telemetry_set_sampling_period(u8 pss_period, u8 ioss_period);
+
+int telemetry_set_trace_verbosity(enum telemetry_unit telem_unit,
+				  u32 verbosity);
+
+int telemetry_get_trace_verbosity(enum telemetry_unit telem_unit,
+				  u32 *verbosity);
+
+#endif /* INTEL_TELEMETRY_H */
--- zfcpdump-kernel-4.4.orig/arch/x86/include/asm/iosf_mbi.h
+++ zfcpdump-kernel-4.4/arch/x86/include/asm/iosf_mbi.h
@@ -16,6 +16,18 @@
 #define MBI_MASK_LO		0x000000FF
 #define MBI_ENABLE		0xF0
 
+/* IOSF SB read/write opcodes */
+#define MBI_MMIO_READ		0x00
+#define MBI_MMIO_WRITE		0x01
+#define MBI_CFG_READ		0x04
+#define MBI_CFG_WRITE		0x05
+#define MBI_CR_READ		0x06
+#define MBI_CR_WRITE		0x07
+#define MBI_REG_READ		0x10
+#define MBI_REG_WRITE		0x11
+#define MBI_ESRAM_READ		0x12
+#define MBI_ESRAM_WRITE		0x13
+
 /* Baytrail available units */
 #define BT_MBI_UNIT_AUNIT	0x00
 #define BT_MBI_UNIT_SMC		0x01
--- zfcpdump-kernel-4.4.orig/arch/x86/include/asm/irq.h
+++ zfcpdump-kernel-4.4/arch/x86/include/asm/irq.h
@@ -23,11 +23,13 @@ extern void irq_ctx_init(int cpu);
 
 #define __ARCH_HAS_DO_SOFTIRQ
 
+struct irq_desc;
+
 #ifdef CONFIG_HOTPLUG_CPU
 #include <linux/cpumask.h>
 extern int check_irq_vectors_for_cpu_disable(void);
 extern void fixup_irqs(void);
-extern void irq_force_complete_move(int);
+extern void irq_force_complete_move(struct irq_desc *desc);
 #endif
 
 #ifdef CONFIG_HAVE_KVM
@@ -37,7 +39,6 @@ extern void kvm_set_posted_intr_wakeup_h
 extern void (*x86_platform_ipi_callback)(void);
 extern void native_init_IRQ(void);
 
-struct irq_desc;
 extern bool handle_irq(struct irq_desc *desc, struct pt_regs *regs);
 
 extern __visible unsigned int do_IRQ(struct pt_regs *regs);
--- zfcpdump-kernel-4.4.orig/arch/x86/include/asm/irq_work.h
+++ zfcpdump-kernel-4.4/arch/x86/include/asm/irq_work.h
@@ -1,7 +1,7 @@
 #ifndef _ASM_IRQ_WORK_H
 #define _ASM_IRQ_WORK_H
 
-#include <asm/processor.h>
+#include <asm/cpufeature.h>
 
 static inline bool arch_irq_work_has_interrupt(void)
 {
--- zfcpdump-kernel-4.4.orig/arch/x86/include/asm/kvm_host.h
+++ zfcpdump-kernel-4.4/arch/x86/include/asm/kvm_host.h
@@ -25,6 +25,7 @@
 #include <linux/pvclock_gtod.h>
 #include <linux/clocksource.h>
 #include <linux/irqbypass.h>
+#include <linux/hyperv.h>
 
 #include <asm/pvclock-abi.h>
 #include <asm/desc.h>
@@ -41,7 +42,7 @@
 
 #define KVM_PIO_PAGE_OFFSET 1
 #define KVM_COALESCED_MMIO_PAGE_OFFSET 2
-#define KVM_HALT_POLL_NS_DEFAULT 500000
+#define KVM_HALT_POLL_NS_DEFAULT 400000
 
 #define KVM_IRQCHIP_NUM_PINS  KVM_IOAPIC_NUM_PINS
 
@@ -374,10 +375,38 @@ struct kvm_mtrr {
 	struct list_head head;
 };
 
+/* Hyper-V SynIC timer */
+struct kvm_vcpu_hv_stimer {
+	struct hrtimer timer;
+	int index;
+	u64 config;
+	u64 count;
+	u64 exp_time;
+	struct hv_message msg;
+	bool msg_pending;
+};
+
+/* Hyper-V synthetic interrupt controller (SynIC)*/
+struct kvm_vcpu_hv_synic {
+	u64 version;
+	u64 control;
+	u64 msg_page;
+	u64 evt_page;
+	atomic64_t sint[HV_SYNIC_SINT_COUNT];
+	atomic_t sint_to_gsi[HV_SYNIC_SINT_COUNT];
+	DECLARE_BITMAP(auto_eoi_bitmap, 256);
+	DECLARE_BITMAP(vec_bitmap, 256);
+	bool active;
+};
+
 /* Hyper-V per vcpu emulation context */
 struct kvm_vcpu_hv {
 	u64 hv_vapic;
 	s64 runtime_offset;
+	struct kvm_vcpu_hv_synic synic;
+	struct kvm_hyperv_exit exit;
+	struct kvm_vcpu_hv_stimer stimer[HV_SYNIC_STIMER_COUNT];
+	DECLARE_BITMAP(stimer_pending_bitmap, HV_SYNIC_STIMER_COUNT);
 };
 
 struct kvm_vcpu_arch {
@@ -400,7 +429,8 @@ struct kvm_vcpu_arch {
 	u64 efer;
 	u64 apic_base;
 	struct kvm_lapic *apic;    /* kernel irqchip context */
-	u64 eoi_exit_bitmap[4];
+	bool apicv_active;
+	DECLARE_BITMAP(ioapic_handled_vectors, 256);
 	unsigned long apic_attention;
 	int32_t apic_arb_prio;
 	int mp_state;
@@ -831,10 +861,11 @@ struct kvm_x86_ops {
 	void (*enable_nmi_window)(struct kvm_vcpu *vcpu);
 	void (*enable_irq_window)(struct kvm_vcpu *vcpu);
 	void (*update_cr8_intercept)(struct kvm_vcpu *vcpu, int tpr, int irr);
-	int (*cpu_uses_apicv)(struct kvm_vcpu *vcpu);
+	bool (*get_enable_apicv)(void);
+	void (*refresh_apicv_exec_ctrl)(struct kvm_vcpu *vcpu);
 	void (*hwapic_irr_update)(struct kvm_vcpu *vcpu, int max_irr);
 	void (*hwapic_isr_update)(struct kvm *kvm, int isr);
-	void (*load_eoi_exitmap)(struct kvm_vcpu *vcpu);
+	void (*load_eoi_exitmap)(struct kvm_vcpu *vcpu, u64 *eoi_exit_bitmap);
 	void (*set_virtual_x2apic_mode)(struct kvm_vcpu *vcpu, bool set);
 	void (*set_apic_access_page_addr)(struct kvm_vcpu *vcpu, hpa_t hpa);
 	void (*deliver_posted_interrupt)(struct kvm_vcpu *vcpu, int vector);
@@ -1086,6 +1117,8 @@ gpa_t kvm_mmu_gva_to_gpa_write(struct kv
 gpa_t kvm_mmu_gva_to_gpa_system(struct kvm_vcpu *vcpu, gva_t gva,
 				struct x86_exception *exception);
 
+void kvm_vcpu_deactivate_apicv(struct kvm_vcpu *vcpu);
+
 int kvm_emulate_hypercall(struct kvm_vcpu *vcpu);
 
 int kvm_mmu_page_fault(struct kvm_vcpu *vcpu, gva_t gva, u32 error_code,
--- zfcpdump-kernel-4.4.orig/arch/x86/include/asm/microcode.h
+++ zfcpdump-kernel-4.4/arch/x86/include/asm/microcode.h
@@ -2,6 +2,7 @@
 #define _ASM_X86_MICROCODE_H
 
 #include <linux/earlycpio.h>
+#include <linux/initrd.h>
 
 #define native_rdmsr(msr, val1, val2)			\
 do {							\
@@ -168,4 +169,29 @@ static inline void reload_early_microcod
 static inline bool
 get_builtin_firmware(struct cpio_data *cd, const char *name)	{ return false; }
 #endif
+
+static inline unsigned long get_initrd_start(void)
+{
+#ifdef CONFIG_BLK_DEV_INITRD
+	return initrd_start;
+#else
+	return 0;
+#endif
+}
+
+static inline unsigned long get_initrd_start_addr(void)
+{
+#ifdef CONFIG_BLK_DEV_INITRD
+#ifdef CONFIG_X86_32
+	unsigned long *initrd_start_p = (unsigned long *)__pa_nodebug(&initrd_start);
+
+	return (unsigned long)__pa_nodebug(*initrd_start_p);
+#else
+	return get_initrd_start();
+#endif
+#else /* CONFIG_BLK_DEV_INITRD */
+	return 0;
+#endif
+}
+
 #endif /* _ASM_X86_MICROCODE_H */
--- zfcpdump-kernel-4.4.orig/arch/x86/include/asm/mmu_context.h
+++ zfcpdump-kernel-4.4/arch/x86/include/asm/mmu_context.h
@@ -116,8 +116,36 @@ static inline void switch_mm(struct mm_s
 #endif
 		cpumask_set_cpu(cpu, mm_cpumask(next));
 
-		/* Re-load page tables */
+		/*
+		 * Re-load page tables.
+		 *
+		 * This logic has an ordering constraint:
+		 *
+		 *  CPU 0: Write to a PTE for 'next'
+		 *  CPU 0: load bit 1 in mm_cpumask.  if nonzero, send IPI.
+		 *  CPU 1: set bit 1 in next's mm_cpumask
+		 *  CPU 1: load from the PTE that CPU 0 writes (implicit)
+		 *
+		 * We need to prevent an outcome in which CPU 1 observes
+		 * the new PTE value and CPU 0 observes bit 1 clear in
+		 * mm_cpumask.  (If that occurs, then the IPI will never
+		 * be sent, and CPU 0's TLB will contain a stale entry.)
+		 *
+		 * The bad outcome can occur if either CPU's load is
+		 * reordered before that CPU's store, so both CPUs must
+		 * execute full barriers to prevent this from happening.
+		 *
+		 * Thus, switch_mm needs a full barrier between the
+		 * store to mm_cpumask and any operation that could load
+		 * from next->pgd.  TLB fills are special and can happen
+		 * due to instruction fetches or for no reason at all,
+		 * and neither LOCK nor MFENCE orders them.
+		 * Fortunately, load_cr3() is serializing and gives the
+		 * ordering guarantee we need.
+		 *
+		 */
 		load_cr3(next->pgd);
+
 		trace_tlb_flush(TLB_FLUSH_ON_TASK_SWITCH, TLB_FLUSH_ALL);
 
 		/* Stop flush ipis for the previous mm */
@@ -156,10 +184,14 @@ static inline void switch_mm(struct mm_s
 			 * schedule, protecting us from simultaneous changes.
 			 */
 			cpumask_set_cpu(cpu, mm_cpumask(next));
+
 			/*
 			 * We were in lazy tlb mode and leave_mm disabled
 			 * tlb flush IPI delivery. We must reload CR3
 			 * to make sure to use no freed page tables.
+			 *
+			 * As above, load_cr3() is serializing and orders TLB
+			 * fills with respect to the mm_cpumask write.
 			 */
 			load_cr3(next->pgd);
 			trace_tlb_flush(TLB_FLUSH_ON_TASK_SWITCH, TLB_FLUSH_ALL);
--- zfcpdump-kernel-4.4.orig/arch/x86/include/asm/msi.h
+++ zfcpdump-kernel-4.4/arch/x86/include/asm/msi.h
@@ -1,7 +1,13 @@
 #ifndef _ASM_X86_MSI_H
 #define _ASM_X86_MSI_H
 #include <asm/hw_irq.h>
+#include <asm/irqdomain.h>
 
 typedef struct irq_alloc_info msi_alloc_info_t;
 
+int pci_msi_prepare(struct irq_domain *domain, struct device *dev, int nvec,
+		    msi_alloc_info_t *arg);
+
+void pci_msi_set_desc(msi_alloc_info_t *arg, struct msi_desc *desc);
+
 #endif /* _ASM_X86_MSI_H */
--- zfcpdump-kernel-4.4.orig/arch/x86/include/asm/msr-index.h
+++ zfcpdump-kernel-4.4/arch/x86/include/asm/msr-index.h
@@ -162,6 +162,14 @@
 #define MSR_PKG_C9_RESIDENCY		0x00000631
 #define MSR_PKG_C10_RESIDENCY		0x00000632
 
+/* Interrupt Response Limit */
+#define MSR_PKGC3_IRTL			0x0000060a
+#define MSR_PKGC6_IRTL			0x0000060b
+#define MSR_PKGC7_IRTL			0x0000060c
+#define MSR_PKGC8_IRTL			0x00000633
+#define MSR_PKGC9_IRTL			0x00000634
+#define MSR_PKGC10_IRTL			0x00000635
+
 /* Run Time Average Power Limiting (RAPL) Interface */
 
 #define MSR_RAPL_POWER_UNIT		0x00000606
--- zfcpdump-kernel-4.4.orig/arch/x86/include/asm/mtrr.h
+++ zfcpdump-kernel-4.4/arch/x86/include/asm/mtrr.h
@@ -24,6 +24,7 @@
 #define _ASM_X86_MTRR_H
 
 #include <uapi/asm/mtrr.h>
+#include <asm/pat.h>
 
 
 /*
@@ -83,9 +84,12 @@ static inline int mtrr_trim_uncached_mem
 static inline void mtrr_centaur_report_mcr(int mcr, u32 lo, u32 hi)
 {
 }
+static inline void mtrr_bp_init(void)
+{
+	pat_disable("MTRRs disabled, skipping PAT initialization too.");
+}
 
 #define mtrr_ap_init() do {} while (0)
-#define mtrr_bp_init() do {} while (0)
 #define set_mtrr_aps_delayed_init() do {} while (0)
 #define mtrr_aps_init() do {} while (0)
 #define mtrr_bp_restore() do {} while (0)
--- zfcpdump-kernel-4.4.orig/arch/x86/include/asm/mwait.h
+++ zfcpdump-kernel-4.4/arch/x86/include/asm/mwait.h
@@ -3,6 +3,8 @@
 
 #include <linux/sched.h>
 
+#include <asm/cpufeature.h>
+
 #define MWAIT_SUBSTATE_MASK		0xf
 #define MWAIT_CSTATE_MASK		0xf
 #define MWAIT_SUBSTATE_SIZE		4
@@ -95,7 +97,7 @@ static inline void __sti_mwait(unsigned
  */
 static inline void mwait_idle_with_hints(unsigned long eax, unsigned long ecx)
 {
-	if (!current_set_polling_and_test()) {
+	if (static_cpu_has_bug(X86_BUG_MONITOR) || !current_set_polling_and_test()) {
 		if (static_cpu_has_bug(X86_BUG_CLFLUSH_MONITOR)) {
 			mb();
 			clflush((void *)&current_thread_info()->flags);
--- zfcpdump-kernel-4.4.orig/arch/x86/include/asm/pat.h
+++ zfcpdump-kernel-4.4/arch/x86/include/asm/pat.h
@@ -5,8 +5,8 @@
 #include <asm/pgtable_types.h>
 
 bool pat_enabled(void);
+void pat_disable(const char *reason);
 extern void pat_init(void);
-void pat_init_cache_modes(u64);
 
 extern int reserve_memtype(u64 start, u64 end,
 		enum page_cache_mode req_pcm, enum page_cache_mode *ret_pcm);
--- zfcpdump-kernel-4.4.orig/arch/x86/include/asm/pci.h
+++ zfcpdump-kernel-4.4/arch/x86/include/asm/pci.h
@@ -20,6 +20,9 @@ struct pci_sysdata {
 #ifdef CONFIG_X86_64
 	void		*iommu;		/* IOMMU private data */
 #endif
+#ifdef CONFIG_PCI_MSI_IRQ_DOMAIN
+	void		*fwnode;	/* IRQ domain for MSI assignment */
+#endif
 };
 
 extern int pci_routeirq;
@@ -32,6 +35,7 @@ extern int noioapicreroute;
 static inline int pci_domain_nr(struct pci_bus *bus)
 {
 	struct pci_sysdata *sd = bus->sysdata;
+
 	return sd->domain;
 }
 
@@ -41,6 +45,17 @@ static inline int pci_proc_domain(struct
 }
 #endif
 
+#ifdef CONFIG_PCI_MSI_IRQ_DOMAIN
+static inline void *_pci_root_bus_fwnode(struct pci_bus *bus)
+{
+	struct pci_sysdata *sd = bus->sysdata;
+
+	return sd->fwnode;
+}
+
+#define pci_root_bus_fwnode	_pci_root_bus_fwnode
+#endif
+
 /* Can be used to override the logic in pci_scan_bus for skipping
    already-configured bus numbers - to be used for buggy BIOSes
    or architectures with incomplete PCI setup by the loader */
--- zfcpdump-kernel-4.4.orig/arch/x86/include/asm/pci_x86.h
+++ zfcpdump-kernel-4.4/arch/x86/include/asm/pci_x86.h
@@ -93,6 +93,8 @@ extern raw_spinlock_t pci_config_lock;
 extern int (*pcibios_enable_irq)(struct pci_dev *dev);
 extern void (*pcibios_disable_irq)(struct pci_dev *dev);
 
+extern bool mp_should_keep_irq(struct device *dev);
+
 struct pci_raw_ops {
 	int (*read)(unsigned int domain, unsigned int bus, unsigned int devfn,
 						int reg, int len, u32 *val);
--- zfcpdump-kernel-4.4.orig/arch/x86/include/asm/perf_event.h
+++ zfcpdump-kernel-4.4/arch/x86/include/asm/perf_event.h
@@ -165,6 +165,7 @@ struct x86_pmu_capability {
 #define GLOBAL_STATUS_ASIF				BIT_ULL(60)
 #define GLOBAL_STATUS_COUNTERS_FROZEN			BIT_ULL(59)
 #define GLOBAL_STATUS_LBRS_FROZEN			BIT_ULL(58)
+#define GLOBAL_STATUS_TRACE_TOPAPMI			BIT_ULL(55)
 
 /*
  * IBS cpuid feature detection
--- zfcpdump-kernel-4.4.orig/arch/x86/include/asm/pgtable_types.h
+++ zfcpdump-kernel-4.4/arch/x86/include/asm/pgtable_types.h
@@ -363,20 +363,18 @@ static inline enum page_cache_mode pgpro
 }
 static inline pgprot_t pgprot_4k_2_large(pgprot_t pgprot)
 {
+	pgprotval_t val = pgprot_val(pgprot);
 	pgprot_t new;
-	unsigned long val;
 
-	val = pgprot_val(pgprot);
 	pgprot_val(new) = (val & ~(_PAGE_PAT | _PAGE_PAT_LARGE)) |
 		((val & _PAGE_PAT) << (_PAGE_BIT_PAT_LARGE - _PAGE_BIT_PAT));
 	return new;
 }
 static inline pgprot_t pgprot_large_2_4k(pgprot_t pgprot)
 {
+	pgprotval_t val = pgprot_val(pgprot);
 	pgprot_t new;
-	unsigned long val;
 
-	val = pgprot_val(pgprot);
 	pgprot_val(new) = (val & ~(_PAGE_PAT | _PAGE_PAT_LARGE)) |
 			  ((val & _PAGE_PAT_LARGE) >>
 			   (_PAGE_BIT_PAT_LARGE - _PAGE_BIT_PAT));
--- zfcpdump-kernel-4.4.orig/arch/x86/include/asm/processor.h
+++ zfcpdump-kernel-4.4/arch/x86/include/asm/processor.h
@@ -13,7 +13,7 @@ struct vm86;
 #include <asm/types.h>
 #include <uapi/asm/sigcontext.h>
 #include <asm/current.h>
-#include <asm/cpufeature.h>
+#include <asm/cpufeatures.h>
 #include <asm/page.h>
 #include <asm/pgtable_types.h>
 #include <asm/percpu.h>
@@ -24,7 +24,6 @@ struct vm86;
 #include <asm/fpu/types.h>
 
 #include <linux/personality.h>
-#include <linux/cpumask.h>
 #include <linux/cache.h>
 #include <linux/threads.h>
 #include <linux/math64.h>
@@ -129,6 +128,8 @@ struct cpuinfo_x86 {
 	u16			booted_cores;
 	/* Physical processor id: */
 	u16			phys_proc_id;
+	/* Logical processor id: */
+	u16			logical_proc_id;
 	/* Core id: */
 	u16			cpu_core_id;
 	/* Compute unit id */
--- zfcpdump-kernel-4.4.orig/arch/x86/include/asm/pvclock.h
+++ zfcpdump-kernel-4.4/arch/x86/include/asm/pvclock.h
@@ -76,6 +76,8 @@ unsigned __pvclock_read_cycles(const str
 	u8 ret_flags;
 
 	version = src->version;
+	/* Make the latest version visible */
+	smp_rmb();
 
 	offset = pvclock_get_nsec_offset(src);
 	ret = src->system_time + offset;
--- zfcpdump-kernel-4.4.orig/arch/x86/include/asm/smap.h
+++ zfcpdump-kernel-4.4/arch/x86/include/asm/smap.h
@@ -15,7 +15,7 @@
 
 #include <linux/stringify.h>
 #include <asm/nops.h>
-#include <asm/cpufeature.h>
+#include <asm/cpufeatures.h>
 
 /* "Raw" instruction opcodes */
 #define __ASM_CLAC	.byte 0x0f,0x01,0xca
--- zfcpdump-kernel-4.4.orig/arch/x86/include/asm/smp.h
+++ zfcpdump-kernel-4.4/arch/x86/include/asm/smp.h
@@ -16,7 +16,6 @@
 #endif
 #include <asm/thread_info.h>
 #include <asm/cpumask.h>
-#include <asm/cpufeature.h>
 
 extern int smp_num_siblings;
 extern unsigned int num_processors;
@@ -168,6 +167,7 @@ static inline int wbinvd_on_all_cpus(voi
 	wbinvd();
 	return 0;
 }
+#define smp_num_siblings	1
 #endif /* CONFIG_SMP */
 
 extern unsigned disabled_cpus;
--- zfcpdump-kernel-4.4.orig/arch/x86/include/asm/thread_info.h
+++ zfcpdump-kernel-4.4/arch/x86/include/asm/thread_info.h
@@ -49,7 +49,7 @@
  */
 #ifndef __ASSEMBLY__
 struct task_struct;
-#include <asm/processor.h>
+#include <asm/cpufeature.h>
 #include <linux/atomic.h>
 
 struct thread_info {
--- zfcpdump-kernel-4.4.orig/arch/x86/include/asm/tlbflush.h
+++ zfcpdump-kernel-4.4/arch/x86/include/asm/tlbflush.h
@@ -5,6 +5,7 @@
 #include <linux/sched.h>
 
 #include <asm/processor.h>
+#include <asm/cpufeature.h>
 #include <asm/special_insns.h>
 
 #ifdef CONFIG_PARAVIRT
@@ -32,7 +33,7 @@ DECLARE_PER_CPU_SHARED_ALIGNED(struct tl
 /* Initialize cr4 shadow for this CPU. */
 static inline void cr4_init_shadow(void)
 {
-	this_cpu_write(cpu_tlbstate.cr4, __read_cr4());
+	this_cpu_write(cpu_tlbstate.cr4, __read_cr4_safe());
 }
 
 /* Set in this cpu's CR4. */
@@ -86,7 +87,14 @@ static inline void cr4_set_bits_and_upda
 
 static inline void __native_flush_tlb(void)
 {
+	/*
+	 * If current->mm == NULL then we borrow a mm which may change during a
+	 * task switch and therefore we must not be preempted while we write CR3
+	 * back:
+	 */
+	preempt_disable();
 	native_write_cr3(native_read_cr3());
+	preempt_enable();
 }
 
 static inline void __native_flush_tlb_global_irq_disabled(void)
--- zfcpdump-kernel-4.4.orig/arch/x86/include/asm/topology.h
+++ zfcpdump-kernel-4.4/arch/x86/include/asm/topology.h
@@ -46,6 +46,7 @@
 #include <linux/cpumask.h>
 
 #include <asm/mpspec.h>
+#include <asm/percpu.h>
 
 /* Mappings between logical cpu number and node number */
 DECLARE_EARLY_PER_CPU(int, x86_cpu_to_node_map);
@@ -119,12 +120,23 @@ static inline void setup_node_to_cpumask
 
 extern const struct cpumask *cpu_coregroup_mask(int cpu);
 
+#define topology_logical_package_id(cpu)	(cpu_data(cpu).logical_proc_id)
 #define topology_physical_package_id(cpu)	(cpu_data(cpu).phys_proc_id)
 #define topology_core_id(cpu)			(cpu_data(cpu).cpu_core_id)
 
 #ifdef ENABLE_TOPO_DEFINES
 #define topology_core_cpumask(cpu)		(per_cpu(cpu_core_map, cpu))
 #define topology_sibling_cpumask(cpu)		(per_cpu(cpu_sibling_map, cpu))
+
+extern unsigned int __max_logical_packages;
+#define topology_max_packages()			(__max_logical_packages)
+int topology_update_package_map(unsigned int apicid, unsigned int cpu);
+extern int topology_phys_to_logical_pkg(unsigned int pkg);
+#else
+#define topology_max_packages()			(1)
+static inline int
+topology_update_package_map(unsigned int apicid, unsigned int cpu) { return 0; }
+static inline int topology_phys_to_logical_pkg(unsigned int pkg) { return 0; }
 #endif
 
 static inline void arch_fix_phys_package_id(int num, u32 slot)
--- zfcpdump-kernel-4.4.orig/arch/x86/include/asm/tsc.h
+++ zfcpdump-kernel-4.4/arch/x86/include/asm/tsc.h
@@ -29,6 +29,8 @@ static inline cycles_t get_cycles(void)
 	return rdtsc();
 }
 
+extern struct system_counterval_t convert_art_to_tsc(cycle_t art);
+
 extern void tsc_init(void);
 extern void mark_tsc_unstable(char *reason);
 extern int unsynchronized_tsc(void);
--- zfcpdump-kernel-4.4.orig/arch/x86/include/asm/uaccess.h
+++ zfcpdump-kernel-4.4/arch/x86/include/asm/uaccess.h
@@ -394,7 +394,11 @@ do {									\
 #define __get_user_asm_ex(x, addr, itype, rtype, ltype)			\
 	asm volatile("1:	mov"itype" %1,%"rtype"0\n"		\
 		     "2:\n"						\
-		     _ASM_EXTABLE_EX(1b, 2b)				\
+		     ".section .fixup,\"ax\"\n"				\
+                     "3:xor"itype" %"rtype"0,%"rtype"0\n"		\
+		     "  jmp 2b\n"					\
+		     ".previous\n"					\
+		     _ASM_EXTABLE_EX(1b, 3b)				\
 		     : ltype(x) : "m" (__m(addr)))
 
 #define __put_user_nocheck(x, ptr, size)			\
--- zfcpdump-kernel-4.4.orig/arch/x86/include/asm/uaccess_64.h
+++ zfcpdump-kernel-4.4/arch/x86/include/asm/uaccess_64.h
@@ -8,7 +8,7 @@
 #include <linux/errno.h>
 #include <linux/lockdep.h>
 #include <asm/alternative.h>
-#include <asm/cpufeature.h>
+#include <asm/cpufeatures.h>
 #include <asm/page.h>
 
 /*
--- zfcpdump-kernel-4.4.orig/arch/x86/include/asm/xen/hypervisor.h
+++ zfcpdump-kernel-4.4/arch/x86/include/asm/xen/hypervisor.h
@@ -62,4 +62,6 @@ void xen_arch_register_cpu(int num);
 void xen_arch_unregister_cpu(int num);
 #endif
 
+extern void xen_set_iopl_mask(unsigned mask);
+
 #endif /* _ASM_X86_XEN_HYPERVISOR_H */
--- zfcpdump-kernel-4.4.orig/arch/x86/include/uapi/asm/bootparam.h
+++ zfcpdump-kernel-4.4/arch/x86/include/uapi/asm/bootparam.h
@@ -134,7 +134,8 @@ struct boot_params {
 	__u8  eddbuf_entries;				/* 0x1e9 */
 	__u8  edd_mbr_sig_buf_entries;			/* 0x1ea */
 	__u8  kbd_status;				/* 0x1eb */
-	__u8  _pad5[3];					/* 0x1ec */
+	__u8  secure_boot;				/* 0x1ec */
+	__u8  _pad5[2];					/* 0x1ed */
 	/*
 	 * The sentinel is set to a nonzero value (0xff) in header.S.
 	 *
--- zfcpdump-kernel-4.4.orig/arch/x86/include/uapi/asm/hyperv.h
+++ zfcpdump-kernel-4.4/arch/x86/include/uapi/asm/hyperv.h
@@ -226,7 +226,9 @@
 		(~((1ull << HV_X64_MSR_HYPERCALL_PAGE_ADDRESS_SHIFT) - 1))
 
 /* Declare the various hypercall operations. */
-#define HV_X64_HV_NOTIFY_LONG_SPIN_WAIT		0x0008
+#define HVCALL_NOTIFY_LONG_SPIN_WAIT		0x0008
+#define HVCALL_POST_MESSAGE			0x005c
+#define HVCALL_SIGNAL_EVENT			0x005d
 
 #define HV_X64_MSR_APIC_ASSIST_PAGE_ENABLE		0x00000001
 #define HV_X64_MSR_APIC_ASSIST_PAGE_ADDRESS_SHIFT	12
@@ -269,4 +271,96 @@ typedef struct _HV_REFERENCE_TSC_PAGE {
 #define HV_SYNIC_SINT_AUTO_EOI		(1ULL << 17)
 #define HV_SYNIC_SINT_VECTOR_MASK	(0xFF)
 
+#define HV_SYNIC_STIMER_COUNT		(4)
+
+/* Define synthetic interrupt controller message constants. */
+#define HV_MESSAGE_SIZE			(256)
+#define HV_MESSAGE_PAYLOAD_BYTE_COUNT	(240)
+#define HV_MESSAGE_PAYLOAD_QWORD_COUNT	(30)
+
+/* Define hypervisor message types. */
+enum hv_message_type {
+	HVMSG_NONE			= 0x00000000,
+
+	/* Memory access messages. */
+	HVMSG_UNMAPPED_GPA		= 0x80000000,
+	HVMSG_GPA_INTERCEPT		= 0x80000001,
+
+	/* Timer notification messages. */
+	HVMSG_TIMER_EXPIRED			= 0x80000010,
+
+	/* Error messages. */
+	HVMSG_INVALID_VP_REGISTER_VALUE	= 0x80000020,
+	HVMSG_UNRECOVERABLE_EXCEPTION	= 0x80000021,
+	HVMSG_UNSUPPORTED_FEATURE		= 0x80000022,
+
+	/* Trace buffer complete messages. */
+	HVMSG_EVENTLOG_BUFFERCOMPLETE	= 0x80000040,
+
+	/* Platform-specific processor intercept messages. */
+	HVMSG_X64_IOPORT_INTERCEPT		= 0x80010000,
+	HVMSG_X64_MSR_INTERCEPT		= 0x80010001,
+	HVMSG_X64_CPUID_INTERCEPT		= 0x80010002,
+	HVMSG_X64_EXCEPTION_INTERCEPT	= 0x80010003,
+	HVMSG_X64_APIC_EOI			= 0x80010004,
+	HVMSG_X64_LEGACY_FP_ERROR		= 0x80010005
+};
+
+/* Define synthetic interrupt controller message flags. */
+union hv_message_flags {
+	__u8 asu8;
+	struct {
+		__u8 msg_pending:1;
+		__u8 reserved:7;
+	};
+};
+
+/* Define port identifier type. */
+union hv_port_id {
+	__u32 asu32;
+	struct {
+		__u32 id:24;
+		__u32 reserved:8;
+	} u;
+};
+
+/* Define synthetic interrupt controller message header. */
+struct hv_message_header {
+	__u32 message_type;
+	__u8 payload_size;
+	union hv_message_flags message_flags;
+	__u8 reserved[2];
+	union {
+		__u64 sender;
+		union hv_port_id port;
+	};
+};
+
+/* Define synthetic interrupt controller message format. */
+struct hv_message {
+	struct hv_message_header header;
+	union {
+		__u64 payload[HV_MESSAGE_PAYLOAD_QWORD_COUNT];
+	} u;
+};
+
+/* Define the synthetic interrupt message page layout. */
+struct hv_message_page {
+	struct hv_message sint_message[HV_SYNIC_SINT_COUNT];
+};
+
+/* Define timer message payload structure. */
+struct hv_timer_message_payload {
+	__u32 timer_index;
+	__u32 reserved;
+	__u64 expiration_time;	/* When the timer expired */
+	__u64 delivery_time;	/* When the message was delivered */
+};
+
+#define HV_STIMER_ENABLE		(1ULL << 0)
+#define HV_STIMER_PERIODIC		(1ULL << 1)
+#define HV_STIMER_LAZY			(1ULL << 2)
+#define HV_STIMER_AUTOENABLE		(1ULL << 3)
+#define HV_STIMER_SINT(config)		(__u8)(((config) >> 16) & 0x0F)
+
 #endif
--- zfcpdump-kernel-4.4.orig/arch/x86/kernel/acpi/boot.c
+++ zfcpdump-kernel-4.4/arch/x86/kernel/acpi/boot.c
@@ -28,7 +28,7 @@
 #include <linux/acpi_pmtmr.h>
 #include <linux/efi.h>
 #include <linux/cpumask.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/dmi.h>
 #include <linux/irq.h>
 #include <linux/slab.h>
--- zfcpdump-kernel-4.4.orig/arch/x86/kernel/acpi/cstate.c
+++ zfcpdump-kernel-4.4/arch/x86/kernel/acpi/cstate.c
@@ -5,7 +5,7 @@
  */
 
 #include <linux/kernel.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/init.h>
 #include <linux/acpi.h>
 #include <linux/cpu.h>
--- zfcpdump-kernel-4.4.orig/arch/x86/kernel/acpi/sleep.c
+++ zfcpdump-kernel-4.4/arch/x86/kernel/acpi/sleep.c
@@ -16,6 +16,7 @@
 #include <asm/cacheflush.h>
 #include <asm/realmode.h>
 
+#include <linux/ftrace.h>
 #include "../../realmode/rm/wakeup.h"
 #include "sleep.h"
 
@@ -107,7 +108,13 @@ int x86_acpi_suspend_lowlevel(void)
        saved_magic = 0x123456789abcdef0L;
 #endif /* CONFIG_64BIT */
 
+	/*
+	 * Pause/unpause graph tracing around do_suspend_lowlevel as it has
+	 * inconsistent call/return info after it jumps to the wakeup vector.
+	 */
+	pause_graph_tracing();
 	do_suspend_lowlevel();
+	unpause_graph_tracing();
 	return 0;
 }
 
--- zfcpdump-kernel-4.4.orig/arch/x86/kernel/amd_gart_64.c
+++ zfcpdump-kernel-4.4/arch/x86/kernel/amd_gart_64.c
@@ -20,7 +20,6 @@
 #include <linux/string.h>
 #include <linux/spinlock.h>
 #include <linux/pci.h>
-#include <linux/module.h>
 #include <linux/topology.h>
 #include <linux/interrupt.h>
 #include <linux/bitmap.h>
--- zfcpdump-kernel-4.4.orig/arch/x86/kernel/amd_nb.c
+++ zfcpdump-kernel-4.4/arch/x86/kernel/amd_nb.c
@@ -9,7 +9,7 @@
 #include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/errno.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/spinlock.h>
 #include <asm/amd_nb.h>
 
@@ -71,8 +71,8 @@ int amd_cache_northbridges(void)
 	while ((misc = next_northbridge(misc, amd_nb_misc_ids)) != NULL)
 		i++;
 
-	if (i == 0)
-		return 0;
+	if (!i)
+		return -ENODEV;
 
 	nb = kzalloc(i * sizeof(struct amd_northbridge), GFP_KERNEL);
 	if (!nb)
--- zfcpdump-kernel-4.4.orig/arch/x86/kernel/apic/apic.c
+++ zfcpdump-kernel-4.4/arch/x86/kernel/apic/apic.c
@@ -23,7 +23,7 @@
 #include <linux/bootmem.h>
 #include <linux/ftrace.h>
 #include <linux/ioport.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/syscore_ops.h>
 #include <linux/delay.h>
 #include <linux/timex.h>
@@ -1587,6 +1587,9 @@ void __init enable_IR_x2apic(void)
 	unsigned long flags;
 	int ret, ir_stat;
 
+	if (skip_ioapic_setup)
+		return;
+
 	ir_stat = irq_remapping_prepare();
 	if (ir_stat < 0 && !x2apic_supported())
 		return;
@@ -2068,6 +2071,20 @@ int generic_processor_info(int apicid, i
 		cpu = cpumask_next_zero(-1, cpu_present_mask);
 
 	/*
+	 * This can happen on physical hotplug. The sanity check at boot time
+	 * is done from native_smp_prepare_cpus() after num_possible_cpus() is
+	 * established.
+	 */
+	if (topology_update_package_map(apicid, cpu) < 0) {
+		int thiscpu = max + disabled_cpus;
+
+		pr_warning("ACPI: Package limit reached. Processor %d/0x%x ignored.\n",
+			   thiscpu, apicid);
+		disabled_cpus++;
+		return -ENOSPC;
+	}
+
+	/*
 	 * Validate version
 	 */
 	if (version == 0x0) {
--- zfcpdump-kernel-4.4.orig/arch/x86/kernel/apic/apic_flat_64.c
+++ zfcpdump-kernel-4.4/arch/x86/kernel/apic/apic_flat_64.c
@@ -15,7 +15,7 @@
 #include <linux/kernel.h>
 #include <linux/ctype.h>
 #include <linux/hardirq.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <asm/smp.h>
 #include <asm/apic.h>
 #include <asm/ipi.h>
--- zfcpdump-kernel-4.4.orig/arch/x86/kernel/apic/apic_noop.c
+++ zfcpdump-kernel-4.4/arch/x86/kernel/apic/apic_noop.c
@@ -11,7 +11,6 @@
 
 #include <linux/threads.h>
 #include <linux/cpumask.h>
-#include <linux/module.h>
 #include <linux/string.h>
 #include <linux/kernel.h>
 #include <linux/ctype.h>
--- zfcpdump-kernel-4.4.orig/arch/x86/kernel/apic/hw_nmi.c
+++ zfcpdump-kernel-4.4/arch/x86/kernel/apic/hw_nmi.c
@@ -16,7 +16,7 @@
 #include <linux/notifier.h>
 #include <linux/kprobes.h>
 #include <linux/nmi.h>
-#include <linux/module.h>
+#include <linux/init.h>
 #include <linux/delay.h>
 #include <linux/seq_buf.h>
 
--- zfcpdump-kernel-4.4.orig/arch/x86/kernel/apic/io_apic.c
+++ zfcpdump-kernel-4.4/arch/x86/kernel/apic/io_apic.c
@@ -39,7 +39,7 @@
 #include <linux/mc146818rtc.h>
 #include <linux/compiler.h>
 #include <linux/acpi.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/syscore_ops.h>
 #include <linux/freezer.h>
 #include <linux/kthread.h>
@@ -2521,6 +2521,7 @@ void __init setup_ioapic_dest(void)
 {
 	int pin, ioapic, irq, irq_entry;
 	const struct cpumask *mask;
+	struct irq_desc *desc;
 	struct irq_data *idata;
 	struct irq_chip *chip;
 
@@ -2536,7 +2537,9 @@ void __init setup_ioapic_dest(void)
 		if (irq < 0 || !mp_init_irq_at_boot(ioapic, irq))
 			continue;
 
-		idata = irq_get_irq_data(irq);
+		desc = irq_to_desc(irq);
+		raw_spin_lock_irq(&desc->lock);
+		idata = irq_desc_get_irq_data(desc);
 
 		/*
 		 * Honour affinities which have been set in early boot
@@ -2550,6 +2553,7 @@ void __init setup_ioapic_dest(void)
 		/* Might be lapic_chip for irq 0 */
 		if (chip->irq_set_affinity)
 			chip->irq_set_affinity(idata, mask, false);
+		raw_spin_unlock_irq(&desc->lock);
 	}
 }
 #endif
--- zfcpdump-kernel-4.4.orig/arch/x86/kernel/apic/ipi.c
+++ zfcpdump-kernel-4.4/arch/x86/kernel/apic/ipi.c
@@ -8,7 +8,6 @@
 #include <linux/mc146818rtc.h>
 #include <linux/cache.h>
 #include <linux/cpu.h>
-#include <linux/module.h>
 
 #include <asm/smp.h>
 #include <asm/mtrr.h>
--- zfcpdump-kernel-4.4.orig/arch/x86/kernel/apic/msi.c
+++ zfcpdump-kernel-4.4/arch/x86/kernel/apic/msi.c
@@ -96,8 +96,8 @@ static irq_hw_number_t pci_msi_get_hwirq
 	return arg->msi_hwirq;
 }
 
-static int pci_msi_prepare(struct irq_domain *domain, struct device *dev,
-			   int nvec, msi_alloc_info_t *arg)
+int pci_msi_prepare(struct irq_domain *domain, struct device *dev, int nvec,
+		    msi_alloc_info_t *arg)
 {
 	struct pci_dev *pdev = to_pci_dev(dev);
 	struct msi_desc *desc = first_pci_msi_entry(pdev);
@@ -113,11 +113,13 @@ static int pci_msi_prepare(struct irq_do
 
 	return 0;
 }
+EXPORT_SYMBOL_GPL(pci_msi_prepare);
 
-static void pci_msi_set_desc(msi_alloc_info_t *arg, struct msi_desc *desc)
+void pci_msi_set_desc(msi_alloc_info_t *arg, struct msi_desc *desc)
 {
 	arg->msi_hwirq = pci_msi_domain_calc_hwirq(arg->msi_dev, desc);
 }
+EXPORT_SYMBOL_GPL(pci_msi_set_desc);
 
 static struct msi_domain_ops pci_msi_domain_ops = {
 	.get_hwirq	= pci_msi_get_hwirq,
--- zfcpdump-kernel-4.4.orig/arch/x86/kernel/apic/probe_32.c
+++ zfcpdump-kernel-4.4/arch/x86/kernel/apic/probe_32.c
@@ -8,7 +8,7 @@
  */
 #include <linux/threads.h>
 #include <linux/cpumask.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/string.h>
 #include <linux/kernel.h>
 #include <linux/ctype.h>
--- zfcpdump-kernel-4.4.orig/arch/x86/kernel/apic/probe_64.c
+++ zfcpdump-kernel-4.4/arch/x86/kernel/apic/probe_64.c
@@ -11,7 +11,7 @@
 #include <linux/threads.h>
 #include <linux/cpumask.h>
 #include <linux/string.h>
-#include <linux/module.h>
+#include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/ctype.h>
 #include <linux/init.h>
--- zfcpdump-kernel-4.4.orig/arch/x86/kernel/apic/vector.c
+++ zfcpdump-kernel-4.4/arch/x86/kernel/apic/vector.c
@@ -29,8 +29,9 @@ struct apic_chip_data {
 };
 
 struct irq_domain *x86_vector_domain;
+EXPORT_SYMBOL_GPL(x86_vector_domain);
 static DEFINE_RAW_SPINLOCK(vector_lock);
-static cpumask_var_t vector_cpumask;
+static cpumask_var_t vector_cpumask, vector_searchmask, searched_cpumask;
 static struct irq_chip lapic_controller;
 #ifdef	CONFIG_X86_IO_APIC
 static struct apic_chip_data *legacy_irq_data[NR_IRQS_LEGACY];
@@ -66,6 +67,7 @@ struct irq_cfg *irqd_cfg(struct irq_data
 
 	return data ? &data->cfg : NULL;
 }
+EXPORT_SYMBOL_GPL(irqd_cfg);
 
 struct irq_cfg *irq_cfg(unsigned int irq)
 {
@@ -116,35 +118,47 @@ static int __assign_irq_vector(int irq,
 	 */
 	static int current_vector = FIRST_EXTERNAL_VECTOR + VECTOR_OFFSET_START;
 	static int current_offset = VECTOR_OFFSET_START % 16;
-	int cpu, err;
+	int cpu, vector;
 
-	if (d->move_in_progress)
+	/*
+	 * If there is still a move in progress or the previous move has not
+	 * been cleaned up completely, tell the caller to come back later.
+	 */
+	if (d->move_in_progress ||
+	    cpumask_intersects(d->old_domain, cpu_online_mask))
 		return -EBUSY;
 
 	/* Only try and allocate irqs on cpus that are present */
-	err = -ENOSPC;
 	cpumask_clear(d->old_domain);
+	cpumask_clear(searched_cpumask);
 	cpu = cpumask_first_and(mask, cpu_online_mask);
 	while (cpu < nr_cpu_ids) {
-		int new_cpu, vector, offset;
+		int new_cpu, offset;
 
+		/* Get the possible target cpus for @mask/@cpu from the apic */
 		apic->vector_allocation_domain(cpu, vector_cpumask, mask);
 
+		/*
+		 * Clear the offline cpus from @vector_cpumask for searching
+		 * and verify whether the result overlaps with @mask. If true,
+		 * then the call to apic->cpu_mask_to_apicid_and() will
+		 * succeed as well. If not, no point in trying to find a
+		 * vector in this mask.
+		 */
+		cpumask_and(vector_searchmask, vector_cpumask, cpu_online_mask);
+		if (!cpumask_intersects(vector_searchmask, mask))
+			goto next_cpu;
+
 		if (cpumask_subset(vector_cpumask, d->domain)) {
-			err = 0;
 			if (cpumask_equal(vector_cpumask, d->domain))
-				break;
+				goto success;
 			/*
-			 * New cpumask using the vector is a proper subset of
-			 * the current in use mask. So cleanup the vector
-			 * allocation for the members that are not used anymore.
+			 * Mark the cpus which are not longer in the mask for
+			 * cleanup.
 			 */
-			cpumask_andnot(d->old_domain, d->domain,
-				       vector_cpumask);
-			d->move_in_progress =
-			   cpumask_intersects(d->old_domain, cpu_online_mask);
-			cpumask_and(d->domain, d->domain, vector_cpumask);
-			break;
+			cpumask_andnot(d->old_domain, d->domain, vector_cpumask);
+			vector = d->cfg.vector;
+			goto update;
 		}
 
 		vector = current_vector;
@@ -156,45 +170,61 @@ next:
 			vector = FIRST_EXTERNAL_VECTOR + offset;
 		}
 
-		if (unlikely(current_vector == vector)) {
-			cpumask_or(d->old_domain, d->old_domain,
-				   vector_cpumask);
-			cpumask_andnot(vector_cpumask, mask, d->old_domain);
-			cpu = cpumask_first_and(vector_cpumask,
-						cpu_online_mask);
-			continue;
-		}
+		/* If the search wrapped around, try the next cpu */
+		if (unlikely(current_vector == vector))
+			goto next_cpu;
 
 		if (test_bit(vector, used_vectors))
 			goto next;
 
-		for_each_cpu_and(new_cpu, vector_cpumask, cpu_online_mask) {
+		for_each_cpu(new_cpu, vector_searchmask) {
 			if (!IS_ERR_OR_NULL(per_cpu(vector_irq, new_cpu)[vector]))
 				goto next;
 		}
 		/* Found one! */
 		current_vector = vector;
 		current_offset = offset;
-		if (d->cfg.vector) {
+		/* Schedule the old vector for cleanup on all cpus */
+		if (d->cfg.vector)
 			cpumask_copy(d->old_domain, d->domain);
-			d->move_in_progress =
-			   cpumask_intersects(d->old_domain, cpu_online_mask);
-		}
-		for_each_cpu_and(new_cpu, vector_cpumask, cpu_online_mask)
+		for_each_cpu(new_cpu, vector_searchmask)
 			per_cpu(vector_irq, new_cpu)[vector] = irq_to_desc(irq);
-		d->cfg.vector = vector;
-		cpumask_copy(d->domain, vector_cpumask);
-		err = 0;
-		break;
-	}
+		goto update;
 
-	if (!err) {
-		/* cache destination APIC IDs into cfg->dest_apicid */
-		err = apic->cpu_mask_to_apicid_and(mask, d->domain,
-						   &d->cfg.dest_apicid);
+next_cpu:
+		/*
+		 * We exclude the current @vector_cpumask from the requested
+		 * @mask and try again with the next online cpu in the
+		 * result. We cannot modify @mask, so we use @vector_cpumask
+		 * as a temporary buffer here as it will be reassigned when
+		 * calling apic->vector_allocation_domain() above.
+		 */
+		cpumask_or(searched_cpumask, searched_cpumask, vector_cpumask);
+		cpumask_andnot(vector_cpumask, mask, searched_cpumask);
+		cpu = cpumask_first_and(vector_cpumask, cpu_online_mask);
+		continue;
 	}
+	return -ENOSPC;
 
-	return err;
+update:
+	/*
+	 * Exclude offline cpus from the cleanup mask and set the
+	 * move_in_progress flag when the result is not empty.
+	 */
+	cpumask_and(d->old_domain, d->old_domain, cpu_online_mask);
+	d->move_in_progress = !cpumask_empty(d->old_domain);
+	d->cfg.old_vector = d->move_in_progress ? d->cfg.vector : 0;
+	d->cfg.vector = vector;
+	cpumask_copy(d->domain, vector_cpumask);
+success:
+	/*
+	 * Cache destination APIC IDs into cfg->dest_apicid. This cannot fail
+	 * as we already established, that mask & d->domain & cpu_online_mask
+	 * is not empty.
+	 */
+	BUG_ON(apic->cpu_mask_to_apicid_and(mask, d->domain,
+					    &d->cfg.dest_apicid));
+	return 0;
 }
 
 static int assign_irq_vector(int irq, struct apic_chip_data *data,
@@ -224,11 +254,10 @@ static int assign_irq_vector_policy(int
 static void clear_irq_vector(int irq, struct apic_chip_data *data)
 {
 	struct irq_desc *desc;
-	unsigned long flags;
 	int cpu, vector;
 
-	raw_spin_lock_irqsave(&vector_lock, flags);
-	BUG_ON(!data->cfg.vector);
+	if (!data->cfg.vector)
+		return;
 
 	vector = data->cfg.vector;
 	for_each_cpu_and(cpu, data->domain, cpu_online_mask)
@@ -237,10 +266,13 @@ static void clear_irq_vector(int irq, st
 	data->cfg.vector = 0;
 	cpumask_clear(data->domain);
 
-	if (likely(!data->move_in_progress)) {
-		raw_spin_unlock_irqrestore(&vector_lock, flags);
+	/*
+	 * If move is in progress or the old_domain mask is not empty,
+	 * i.e. the cleanup IPI has not been processed yet, we need to remove
+	 * the old references to desc from all cpus vector tables.
+	 */
+	if (!data->move_in_progress && cpumask_empty(data->old_domain))
 		return;
-	}
 
 	desc = irq_to_desc(irq);
 	for_each_cpu_and(cpu, data->old_domain, cpu_online_mask) {
@@ -253,7 +285,6 @@ static void clear_irq_vector(int irq, st
 		}
 	}
 	data->move_in_progress = 0;
-	raw_spin_unlock_irqrestore(&vector_lock, flags);
 }
 
 void init_irq_alloc_info(struct irq_alloc_info *info,
@@ -274,19 +305,24 @@ void copy_irq_alloc_info(struct irq_allo
 static void x86_vector_free_irqs(struct irq_domain *domain,
 				 unsigned int virq, unsigned int nr_irqs)
 {
+	struct apic_chip_data *apic_data;
 	struct irq_data *irq_data;
+	unsigned long flags;
 	int i;
 
 	for (i = 0; i < nr_irqs; i++) {
 		irq_data = irq_domain_get_irq_data(x86_vector_domain, virq + i);
 		if (irq_data && irq_data->chip_data) {
+			raw_spin_lock_irqsave(&vector_lock, flags);
 			clear_irq_vector(virq + i, irq_data->chip_data);
-			free_apic_chip_data(irq_data->chip_data);
+			apic_data = irq_data->chip_data;
+			irq_domain_reset_irq_data(irq_data);
+			raw_spin_unlock_irqrestore(&vector_lock, flags);
+			free_apic_chip_data(apic_data);
 #ifdef	CONFIG_X86_IO_APIC
 			if (virq + i < nr_legacy_irqs())
 				legacy_irq_data[virq + i] = NULL;
 #endif
-			irq_domain_reset_irq_data(irq_data);
 		}
 	}
 }
@@ -404,6 +440,8 @@ int __init arch_early_irq_init(void)
 	arch_init_htirq_domain(x86_vector_domain);
 
 	BUG_ON(!alloc_cpumask_var(&vector_cpumask, GFP_KERNEL));
+	BUG_ON(!alloc_cpumask_var(&vector_searchmask, GFP_KERNEL));
+	BUG_ON(!alloc_cpumask_var(&searched_cpumask, GFP_KERNEL));
 
 	return arch_early_ioapic_init();
 }
@@ -492,14 +530,7 @@ static int apic_set_affinity(struct irq_
 		return -EINVAL;
 
 	err = assign_irq_vector(irq, data, dest);
-	if (err) {
-		if (assign_irq_vector(irq, data,
-				      irq_data_get_affinity_mask(irq_data)))
-			pr_err("Failed to recover vector for irq %d\n", irq);
-		return err;
-	}
-
-	return IRQ_SET_MASK_OK;
+	return err ? err : IRQ_SET_MASK_OK;
 }
 
 static struct irq_chip lapic_controller = {
@@ -511,20 +542,12 @@ static struct irq_chip lapic_controller
 #ifdef CONFIG_SMP
 static void __send_cleanup_vector(struct apic_chip_data *data)
 {
-	cpumask_var_t cleanup_mask;
-
-	if (unlikely(!alloc_cpumask_var(&cleanup_mask, GFP_ATOMIC))) {
-		unsigned int i;
-
-		for_each_cpu_and(i, data->old_domain, cpu_online_mask)
-			apic->send_IPI_mask(cpumask_of(i),
-					    IRQ_MOVE_CLEANUP_VECTOR);
-	} else {
-		cpumask_and(cleanup_mask, data->old_domain, cpu_online_mask);
-		apic->send_IPI_mask(cleanup_mask, IRQ_MOVE_CLEANUP_VECTOR);
-		free_cpumask_var(cleanup_mask);
-	}
+	raw_spin_lock(&vector_lock);
+	cpumask_and(data->old_domain, data->old_domain, cpu_online_mask);
 	data->move_in_progress = 0;
+	if (!cpumask_empty(data->old_domain))
+		apic->send_IPI_mask(data->old_domain, IRQ_MOVE_CLEANUP_VECTOR);
+	raw_spin_unlock(&vector_lock);
 }
 
 void send_cleanup_vector(struct irq_cfg *cfg)
@@ -568,12 +591,25 @@ asmlinkage __visible void smp_irq_move_c
 			goto unlock;
 
 		/*
-		 * Check if the irq migration is in progress. If so, we
-		 * haven't received the cleanup request yet for this irq.
+		 * Nothing to cleanup if irq migration is in progress
+		 * or this cpu is not set in the cleanup mask.
 		 */
-		if (data->move_in_progress)
+		if (data->move_in_progress ||
+		    !cpumask_test_cpu(me, data->old_domain))
 			goto unlock;
 
+		/*
+		 * We have two cases to handle here:
+		 * 1) vector is unchanged but the target mask got reduced
+		 * 2) vector and the target mask has changed
+		 *
+		 * #1 is obvious, but in #2 we have two vectors with the same
+		 * irq descriptor: the old and the new vector. So we need to
+		 * make sure that we only cleanup the old vector. The new
+		 * vector has the current @vector number in the config and
+		 * this cpu is part of the target mask. We better leave that
+		 * one alone.
+		 */
 		if (vector == data->cfg.vector &&
 		    cpumask_test_cpu(me, data->domain))
 			goto unlock;
@@ -591,6 +627,7 @@ asmlinkage __visible void smp_irq_move_c
 			goto unlock;
 		}
 		__this_cpu_write(vector_irq[vector], VECTOR_UNUSED);
+		cpumask_clear_cpu(me, data->old_domain);
 unlock:
 		raw_spin_unlock(&desc->lock);
 	}
@@ -619,12 +656,99 @@ void irq_complete_move(struct irq_cfg *c
 	__irq_complete_move(cfg, ~get_irq_regs()->orig_ax);
 }
 
-void irq_force_complete_move(int irq)
+/*
+ * Called from fixup_irqs() with @desc->lock held and interrupts disabled.
+ */
+void irq_force_complete_move(struct irq_desc *desc)
 {
-	struct irq_cfg *cfg = irq_cfg(irq);
+	struct irq_data *irqdata = irq_desc_get_irq_data(desc);
+	struct apic_chip_data *data = apic_chip_data(irqdata);
+	struct irq_cfg *cfg = data ? &data->cfg : NULL;
+	unsigned int cpu;
+
+	if (!cfg)
+		return;
+
+	/*
+	 * This is tricky. If the cleanup of @data->old_domain has not been
+	 * done yet, then the following setaffinity call will fail with
+	 * -EBUSY. This can leave the interrupt in a stale state.
+	 *
+	 * All CPUs are stuck in stop machine with interrupts disabled so
+	 * calling __irq_complete_move() would be completely pointless.
+	 */
+	raw_spin_lock(&vector_lock);
+	/*
+	 * Clean out all offline cpus (including the outgoing one) from the
+	 * old_domain mask.
+	 */
+	cpumask_and(data->old_domain, data->old_domain, cpu_online_mask);
 
-	if (cfg)
-		__irq_complete_move(cfg, cfg->vector);
+	/*
+	 * If move_in_progress is cleared and the old_domain mask is empty,
+	 * then there is nothing to cleanup. fixup_irqs() will take care of
+	 * the stale vectors on the outgoing cpu.
+	 */
+	if (!data->move_in_progress && cpumask_empty(data->old_domain)) {
+		raw_spin_unlock(&vector_lock);
+		return;
+	}
+
+	/*
+	 * 1) The interrupt is in move_in_progress state. That means that we
+	 *    have not seen an interrupt since the io_apic was reprogrammed to
+	 *    the new vector.
+	 *
+	 * 2) The interrupt has fired on the new vector, but the cleanup IPIs
+	 *    have not been processed yet.
+	 */
+	if (data->move_in_progress) {
+		/*
+		 * In theory there is a race:
+		 *
+		 * set_ioapic(new_vector) <-- Interrupt is raised before update
+		 *			      is effective, i.e. it's raised on
+		 *			      the old vector.
+		 *
+		 * So if the target cpu cannot handle that interrupt before
+		 * the old vector is cleaned up, we get a spurious interrupt
+		 * and in the worst case the ioapic irq line becomes stale.
+		 *
+		 * But in case of cpu hotplug this should be a non issue
+		 * because if the affinity update happens right before all
+		 * cpus rendevouz in stop machine, there is no way that the
+		 * interrupt can be blocked on the target cpu because all cpus
+		 * loops first with interrupts enabled in stop machine, so the
+		 * old vector is not yet cleaned up when the interrupt fires.
+		 *
+		 * So the only way to run into this issue is if the delivery
+		 * of the interrupt on the apic/system bus would be delayed
+		 * beyond the point where the target cpu disables interrupts
+		 * in stop machine. I doubt that it can happen, but at least
+		 * there is a theroretical chance. Virtualization might be
+		 * able to expose this, but AFAICT the IOAPIC emulation is not
+		 * as stupid as the real hardware.
+		 *
+		 * Anyway, there is nothing we can do about that at this point
+		 * w/o refactoring the whole fixup_irq() business completely.
+		 * We print at least the irq number and the old vector number,
+		 * so we have the necessary information when a problem in that
+		 * area arises.
+		 */
+		pr_warn("IRQ fixup: irq %d move in progress, old vector %d\n",
+			irqdata->irq, cfg->old_vector);
+	}
+	/*
+	 * If old_domain is not empty, then other cpus still have the irq
+	 * descriptor set in their vector array. Clean it up.
+	 */
+	for_each_cpu(cpu, data->old_domain)
+		per_cpu(vector_irq, cpu)[cfg->old_vector] = VECTOR_UNUSED;
+
+	/* Cleanup the left overs of the (half finished) move */
+	cpumask_clear(data->old_domain);
+	data->move_in_progress = 0;
+	raw_spin_unlock(&vector_lock);
 }
 #endif
 
--- zfcpdump-kernel-4.4.orig/arch/x86/kernel/apic/x2apic_uv_x.c
+++ zfcpdump-kernel-4.4/arch/x86/kernel/apic/x2apic_uv_x.c
@@ -12,7 +12,7 @@
 #include <linux/proc_fs.h>
 #include <linux/threads.h>
 #include <linux/kernel.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/string.h>
 #include <linux/ctype.h>
 #include <linux/sched.h>
--- zfcpdump-kernel-4.4.orig/arch/x86/kernel/cpu/Makefile
+++ zfcpdump-kernel-4.4/arch/x86/kernel/cpu/Makefile
@@ -30,33 +30,11 @@ obj-$(CONFIG_CPU_SUP_CENTAUR)		+= centau
 obj-$(CONFIG_CPU_SUP_TRANSMETA_32)	+= transmeta.o
 obj-$(CONFIG_CPU_SUP_UMC_32)		+= umc.o
 
-obj-$(CONFIG_PERF_EVENTS)		+= perf_event.o
-
-ifdef CONFIG_PERF_EVENTS
-obj-$(CONFIG_CPU_SUP_AMD)		+= perf_event_amd.o perf_event_amd_uncore.o
-ifdef CONFIG_AMD_IOMMU
-obj-$(CONFIG_CPU_SUP_AMD)		+= perf_event_amd_iommu.o
-endif
-obj-$(CONFIG_CPU_SUP_INTEL)		+= perf_event_p6.o perf_event_knc.o perf_event_p4.o
-obj-$(CONFIG_CPU_SUP_INTEL)		+= perf_event_intel_lbr.o perf_event_intel_ds.o perf_event_intel.o
-obj-$(CONFIG_CPU_SUP_INTEL)		+= perf_event_intel_rapl.o perf_event_intel_cqm.o
-obj-$(CONFIG_CPU_SUP_INTEL)		+= perf_event_intel_pt.o perf_event_intel_bts.o
-obj-$(CONFIG_CPU_SUP_INTEL)		+= perf_event_intel_cstate.o
-
-obj-$(CONFIG_PERF_EVENTS_INTEL_UNCORE)	+= perf_event_intel_uncore.o \
-					   perf_event_intel_uncore_snb.o \
-					   perf_event_intel_uncore_snbep.o \
-					   perf_event_intel_uncore_nhmex.o
-obj-$(CONFIG_CPU_SUP_INTEL)		+= perf_event_msr.o
-obj-$(CONFIG_CPU_SUP_AMD)		+= perf_event_msr.o
-endif
-
-
 obj-$(CONFIG_X86_MCE)			+= mcheck/
 obj-$(CONFIG_MTRR)			+= mtrr/
 obj-$(CONFIG_MICROCODE)			+= microcode/
 
-obj-$(CONFIG_X86_LOCAL_APIC)		+= perfctr-watchdog.o perf_event_amd_ibs.o
+obj-$(CONFIG_X86_LOCAL_APIC)		+= perfctr-watchdog.o
 
 obj-$(CONFIG_HYPERVISOR_GUEST)		+= vmware.o hypervisor.o mshyperv.o
 
@@ -64,7 +42,7 @@ ifdef CONFIG_X86_FEATURE_NAMES
 quiet_cmd_mkcapflags = MKCAP   $@
       cmd_mkcapflags = $(CONFIG_SHELL) $(srctree)/$(src)/mkcapflags.sh $< $@
 
-cpufeature = $(src)/../../include/asm/cpufeature.h
+cpufeature = $(src)/../../include/asm/cpufeatures.h
 
 targets += capflags.c
 $(obj)/capflags.c: $(cpufeature) $(src)/mkcapflags.sh FORCE
--- zfcpdump-kernel-4.4.orig/arch/x86/kernel/cpu/amd.c
+++ zfcpdump-kernel-4.4/arch/x86/kernel/cpu/amd.c
@@ -312,9 +312,9 @@ static void amd_get_topology(struct cpui
 		node_id = ecx & 7;
 
 		/* get compute unit information */
-		smp_num_siblings = ((ebx >> 8) & 3) + 1;
+		cores_per_cu = smp_num_siblings = ((ebx >> 8) & 3) + 1;
+		c->x86_max_cores /= smp_num_siblings;
 		c->compute_unit_id = ebx & 0xff;
-		cores_per_cu += ((ebx >> 8) & 3);
 	} else if (cpu_has(c, X86_FEATURE_NODEID_MSR)) {
 		u64 value;
 
@@ -330,8 +330,8 @@ static void amd_get_topology(struct cpui
 		u32 cus_per_node;
 
 		set_cpu_cap(c, X86_FEATURE_AMD_DCM);
-		cores_per_node = c->x86_max_cores / nodes_per_socket;
-		cus_per_node = cores_per_node / cores_per_cu;
+		cus_per_node = c->x86_max_cores / nodes_per_socket;
+		cores_per_node = cus_per_node * cores_per_cu;
 
 		/* store NodeID, use llc_shared_map to store sibling info */
 		per_cpu(cpu_llc_id, cpu) = node_id;
@@ -656,6 +656,17 @@ static void init_amd_gh(struct cpuinfo_x
 		set_cpu_bug(c, X86_BUG_AMD_TLB_MMATCH);
 }
 
+#define MSR_AMD64_DE_CFG	0xC0011029
+
+static void init_amd_ln(struct cpuinfo_x86 *c)
+{
+	/*
+	 * Apply erratum 665 fix unconditionally so machines without a BIOS
+	 * fix work.
+	 */
+	msr_set_bit(MSR_AMD64_DE_CFG, 31);
+}
+
 static void init_amd_bd(struct cpuinfo_x86 *c)
 {
 	u64 value;
@@ -713,6 +724,7 @@ static void init_amd(struct cpuinfo_x86
 	case 6:	   init_amd_k7(c); break;
 	case 0xf:  init_amd_k8(c); break;
 	case 0x10: init_amd_gh(c); break;
+	case 0x12: init_amd_ln(c); break;
 	case 0x15: init_amd_bd(c); break;
 	}
 
--- zfcpdump-kernel-4.4.orig/arch/x86/kernel/cpu/centaur.c
+++ zfcpdump-kernel-4.4/arch/x86/kernel/cpu/centaur.c
@@ -1,7 +1,7 @@
 #include <linux/bitops.h>
 #include <linux/kernel.h>
 
-#include <asm/processor.h>
+#include <asm/cpufeature.h>
 #include <asm/e820.h>
 #include <asm/mtrr.h>
 #include <asm/msr.h>
--- zfcpdump-kernel-4.4.orig/arch/x86/kernel/cpu/common.c
+++ zfcpdump-kernel-4.4/arch/x86/kernel/cpu/common.c
@@ -2,7 +2,7 @@
 #include <linux/linkage.h>
 #include <linux/bitops.h>
 #include <linux/kernel.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/percpu.h>
 #include <linux/string.h>
 #include <linux/ctype.h>
@@ -643,7 +643,10 @@ void get_cpu_cap(struct cpuinfo_x86 *c)
 			/* QoS sub-leaf, EAX=0Fh, ECX=1 */
 			cpuid_count(0x0000000F, 1, &eax, &ebx, &ecx, &edx);
 			c->x86_capability[12] = edx;
-			if (cpu_has(c, X86_FEATURE_CQM_OCCUP_LLC)) {
+
+			if ((cpu_has(c, X86_FEATURE_CQM_OCCUP_LLC)) ||
+			      ((cpu_has(c, X86_FEATURE_CQM_MBM_TOTAL)) ||
+			       (cpu_has(c, X86_FEATURE_CQM_MBM_LOCAL)))) {
 				c->x86_cache_max_rmid = ecx;
 				c->x86_cache_occ_scale = ebx;
 			}
@@ -737,21 +740,20 @@ static void __init early_identify_cpu(st
 		identify_cpu_without_cpuid(c);
 
 	/* cyrix could have cpuid enabled via c_identify()*/
-	if (!have_cpuid_p())
-		return;
-
-	cpu_detect(c);
-	get_cpu_vendor(c);
-	get_cpu_cap(c);
+	if (have_cpuid_p()) {
+		cpu_detect(c);
+		get_cpu_vendor(c);
+		get_cpu_cap(c);
 
-	if (this_cpu->c_early_init)
-		this_cpu->c_early_init(c);
+		if (this_cpu->c_early_init)
+			this_cpu->c_early_init(c);
 
-	c->cpu_index = 0;
-	filter_cpuid_features(c, false);
+		c->cpu_index = 0;
+		filter_cpuid_features(c, false);
 
-	if (this_cpu->c_bsp_init)
-		this_cpu->c_bsp_init(c);
+		if (this_cpu->c_bsp_init)
+			this_cpu->c_bsp_init(c);
+	}
 
 	setup_force_cpu_cap(X86_FEATURE_ALWAYS);
 	fpu__init_system(c);
@@ -980,6 +982,8 @@ static void identify_cpu(struct cpuinfo_
 #ifdef CONFIG_NUMA
 	numa_add_cpu(smp_processor_id());
 #endif
+	/* The boot/hotplug time assigment got cleared, restore it */
+	c->logical_proc_id = topology_phys_to_logical_pkg(c->phys_proc_id);
 }
 
 /*
--- zfcpdump-kernel-4.4.orig/arch/x86/kernel/cpu/cyrix.c
+++ zfcpdump-kernel-4.4/arch/x86/kernel/cpu/cyrix.c
@@ -8,6 +8,7 @@
 #include <linux/timer.h>
 #include <asm/pci-direct.h>
 #include <asm/tsc.h>
+#include <asm/cpufeature.h>
 
 #include "cpu.h"
 
--- zfcpdump-kernel-4.4.orig/arch/x86/kernel/cpu/hypervisor.c
+++ zfcpdump-kernel-4.4/arch/x86/kernel/cpu/hypervisor.c
@@ -21,7 +21,8 @@
  *
  */
 
-#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/export.h>
 #include <asm/processor.h>
 #include <asm/hypervisor.h>
 
--- zfcpdump-kernel-4.4.orig/arch/x86/kernel/cpu/intel.c
+++ zfcpdump-kernel-4.4/arch/x86/kernel/cpu/intel.c
@@ -5,14 +5,15 @@
 #include <linux/smp.h>
 #include <linux/sched.h>
 #include <linux/thread_info.h>
-#include <linux/module.h>
+#include <linux/init.h>
 #include <linux/uaccess.h>
 
-#include <asm/processor.h>
+#include <asm/cpufeature.h>
 #include <asm/pgtable.h>
 #include <asm/msr.h>
 #include <asm/bugs.h>
 #include <asm/cpu.h>
+#include <asm/intel-family.h>
 
 #ifdef CONFIG_X86_64
 #include <linux/topology.h>
@@ -160,6 +161,19 @@ static void early_init_intel(struct cpui
 		pr_info("Disabling PGE capability bit\n");
 		setup_clear_cpu_cap(X86_FEATURE_PGE);
 	}
+
+	if (c->cpuid_level >= 0x00000001) {
+		u32 eax, ebx, ecx, edx;
+
+		cpuid(0x00000001, &eax, &ebx, &ecx, &edx);
+		/*
+		 * If HTT (EDX[28]) is set EBX[16:23] contain the number of
+		 * apicids which are reserved per package. Store the resulting
+		 * shift value for the package management code.
+		 */
+		if (edx & (1U << 28))
+			c->x86_coreid_bits = get_count_order((ebx >> 16) & 0xff);
+	}
 }
 
 #ifdef CONFIG_X86_32
@@ -458,6 +472,10 @@ static void init_intel(struct cpuinfo_x8
 	    (c->x86_model == 29 || c->x86_model == 46 || c->x86_model == 47))
 		set_cpu_bug(c, X86_BUG_CLFLUSH_MONITOR);
 
+	if (c->x86 == 6 && boot_cpu_has(X86_FEATURE_MWAIT) &&
+		((c->x86_model == INTEL_FAM6_ATOM_GOLDMONT)))
+		set_cpu_bug(c, X86_BUG_MONITOR);
+
 #ifdef CONFIG_X86_64
 	if (c->x86 == 15)
 		c->x86_cache_alignment = c->x86_clflush_size * 2;
--- zfcpdump-kernel-4.4.orig/arch/x86/kernel/cpu/intel_cacheinfo.c
+++ zfcpdump-kernel-4.4/arch/x86/kernel/cpu/intel_cacheinfo.c
@@ -14,7 +14,7 @@
 #include <linux/sysfs.h>
 #include <linux/pci.h>
 
-#include <asm/processor.h>
+#include <asm/cpufeature.h>
 #include <asm/amd_nb.h>
 #include <asm/smp.h>
 
--- zfcpdump-kernel-4.4.orig/arch/x86/kernel/cpu/intel_pt.h
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * Intel(R) Processor Trace PMU driver for perf
- * Copyright (c) 2013-2014, Intel Corporation.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * Intel PT is specified in the Intel Architecture Instruction Set Extensions
- * Programming Reference:
- * http://software.intel.com/en-us/intel-isa-extensions
- */
-
-#ifndef __INTEL_PT_H__
-#define __INTEL_PT_H__
-
-/*
- * Single-entry ToPA: when this close to region boundary, switch
- * buffers to avoid losing data.
- */
-#define TOPA_PMI_MARGIN 512
-
-#define TOPA_SHIFT 12
-
-static inline unsigned int sizes(unsigned int tsz)
-{
-	return 1 << (tsz + TOPA_SHIFT);
-};
-
-struct topa_entry {
-	u64	end	: 1;
-	u64	rsvd0	: 1;
-	u64	intr	: 1;
-	u64	rsvd1	: 1;
-	u64	stop	: 1;
-	u64	rsvd2	: 1;
-	u64	size	: 4;
-	u64	rsvd3	: 2;
-	u64	base	: 36;
-	u64	rsvd4	: 16;
-};
-
-#define PT_CPUID_LEAVES		2
-#define PT_CPUID_REGS_NUM	4 /* number of regsters (eax, ebx, ecx, edx) */
-
-enum pt_capabilities {
-	PT_CAP_max_subleaf = 0,
-	PT_CAP_cr3_filtering,
-	PT_CAP_psb_cyc,
-	PT_CAP_mtc,
-	PT_CAP_topa_output,
-	PT_CAP_topa_multiple_entries,
-	PT_CAP_single_range_output,
-	PT_CAP_payloads_lip,
-	PT_CAP_mtc_periods,
-	PT_CAP_cycle_thresholds,
-	PT_CAP_psb_periods,
-};
-
-struct pt_pmu {
-	struct pmu		pmu;
-	u32			caps[PT_CPUID_REGS_NUM * PT_CPUID_LEAVES];
-};
-
-/**
- * struct pt_buffer - buffer configuration; one buffer per task_struct or
- *		cpu, depending on perf event configuration
- * @cpu:	cpu for per-cpu allocation
- * @tables:	list of ToPA tables in this buffer
- * @first:	shorthand for first topa table
- * @last:	shorthand for last topa table
- * @cur:	current topa table
- * @nr_pages:	buffer size in pages
- * @cur_idx:	current output region's index within @cur table
- * @output_off:	offset within the current output region
- * @data_size:	running total of the amount of data in this buffer
- * @lost:	if data was lost/truncated
- * @head:	logical write offset inside the buffer
- * @snapshot:	if this is for a snapshot/overwrite counter
- * @stop_pos:	STOP topa entry in the buffer
- * @intr_pos:	INT topa entry in the buffer
- * @data_pages:	array of pages from perf
- * @topa_index:	table of topa entries indexed by page offset
- */
-struct pt_buffer {
-	int			cpu;
-	struct list_head	tables;
-	struct topa		*first, *last, *cur;
-	unsigned int		cur_idx;
-	size_t			output_off;
-	unsigned long		nr_pages;
-	local_t			data_size;
-	local_t			lost;
-	local64_t		head;
-	bool			snapshot;
-	unsigned long		stop_pos, intr_pos;
-	void			**data_pages;
-	struct topa_entry	*topa_index[0];
-};
-
-/**
- * struct pt - per-cpu pt context
- * @handle:	perf output handle
- * @handle_nmi:	do handle PT PMI on this cpu, there's an active event
- */
-struct pt {
-	struct perf_output_handle handle;
-	int			handle_nmi;
-};
-
-#endif /* __INTEL_PT_H__ */
--- zfcpdump-kernel-4.4.orig/arch/x86/kernel/cpu/match.c
+++ zfcpdump-kernel-4.4/arch/x86/kernel/cpu/match.c
@@ -1,7 +1,7 @@
 #include <asm/cpu_device_id.h>
-#include <asm/processor.h>
+#include <asm/cpufeature.h>
 #include <linux/cpu.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/slab.h>
 
 /**
--- zfcpdump-kernel-4.4.orig/arch/x86/kernel/cpu/mcheck/mce-genpool.c
+++ zfcpdump-kernel-4.4/arch/x86/kernel/cpu/mcheck/mce-genpool.c
@@ -29,7 +29,7 @@ static char gen_pool_buf[MCE_POOLSZ];
 void mce_gen_pool_process(void)
 {
 	struct llist_node *head;
-	struct mce_evt_llist *node;
+	struct mce_evt_llist *node, *tmp;
 	struct mce *mce;
 
 	head = llist_del_all(&mce_event_llist);
@@ -37,7 +37,7 @@ void mce_gen_pool_process(void)
 		return;
 
 	head = llist_reverse_order(head);
-	llist_for_each_entry(node, head, llnode) {
+	llist_for_each_entry_safe(node, tmp, head, llnode) {
 		mce = &node->mce;
 		atomic_notifier_call_chain(&x86_mce_decoder_chain, 0, mce);
 		gen_pool_free(mce_evt_pool, (unsigned long)node, sizeof(*node));
--- zfcpdump-kernel-4.4.orig/arch/x86/kernel/cpu/mcheck/therm_throt.c
+++ zfcpdump-kernel-4.4/arch/x86/kernel/cpu/mcheck/therm_throt.c
@@ -385,6 +385,9 @@ static void intel_thermal_interrupt(void
 {
 	__u64 msr_val;
 
+	if (static_cpu_has(X86_FEATURE_HWP))
+		wrmsrl_safe(MSR_HWP_STATUS, 0);
+
 	rdmsrl(MSR_IA32_THERM_STATUS, msr_val);
 
 	/* Check for violation of core thermal thresholds*/
--- zfcpdump-kernel-4.4.orig/arch/x86/kernel/cpu/microcode/intel.c
+++ zfcpdump-kernel-4.4/arch/x86/kernel/cpu/microcode/intel.c
@@ -555,10 +555,14 @@ scan_microcode(struct mc_saved_data *mc_
 	cd.data = NULL;
 	cd.size = 0;
 
-	cd = find_cpio_data(p, (void *)start, size, &offset);
-	if (!cd.data) {
+	/* try built-in microcode if no initrd */
+	if (!size) {
 		if (!load_builtin_intel_microcode(&cd))
 			return UCODE_ERROR;
+	} else {
+		cd = find_cpio_data(p, (void *)start, size, &offset);
+		if (!cd.data)
+			return UCODE_ERROR;
 	}
 
 	return get_matching_model_microcode(0, start, cd.data, cd.size,
@@ -694,7 +698,7 @@ int __init save_microcode_in_initrd_inte
 	if (count == 0)
 		return ret;
 
-	copy_initrd_ptrs(mc_saved, mc_saved_in_initrd, initrd_start, count);
+	copy_initrd_ptrs(mc_saved, mc_saved_in_initrd, get_initrd_start(), count);
 	ret = save_microcode(&mc_saved_data, mc_saved, count);
 	if (ret)
 		pr_err("Cannot save microcode patches from initrd.\n");
@@ -732,16 +736,20 @@ void __init load_ucode_intel_bsp(void)
 	struct boot_params *p;
 
 	p	= (struct boot_params *)__pa_nodebug(&boot_params);
-	start	= p->hdr.ramdisk_image;
 	size	= p->hdr.ramdisk_size;
 
-	_load_ucode_intel_bsp(
-			(struct mc_saved_data *)__pa_nodebug(&mc_saved_data),
-			(unsigned long *)__pa_nodebug(&mc_saved_in_initrd),
-			start, size);
+	/*
+	 * Set start only if we have an initrd image. We cannot use initrd_start
+	 * because it is not set that early yet.
+	 */
+	start	= (size ? p->hdr.ramdisk_image : 0);
+
+	_load_ucode_intel_bsp((struct mc_saved_data *)__pa_nodebug(&mc_saved_data),
+			      (unsigned long *)__pa_nodebug(&mc_saved_in_initrd),
+			      start, size);
 #else
-	start	= boot_params.hdr.ramdisk_image + PAGE_OFFSET;
 	size	= boot_params.hdr.ramdisk_size;
+	start	= (size ? boot_params.hdr.ramdisk_image + PAGE_OFFSET : 0);
 
 	_load_ucode_intel_bsp(&mc_saved_data, mc_saved_in_initrd, start, size);
 #endif
@@ -752,20 +760,14 @@ void load_ucode_intel_ap(void)
 	struct mc_saved_data *mc_saved_data_p;
 	struct ucode_cpu_info uci;
 	unsigned long *mc_saved_in_initrd_p;
-	unsigned long initrd_start_addr;
 	enum ucode_state ret;
 #ifdef CONFIG_X86_32
-	unsigned long *initrd_start_p;
 
-	mc_saved_in_initrd_p =
-		(unsigned long *)__pa_nodebug(mc_saved_in_initrd);
+	mc_saved_in_initrd_p = (unsigned long *)__pa_nodebug(mc_saved_in_initrd);
 	mc_saved_data_p = (struct mc_saved_data *)__pa_nodebug(&mc_saved_data);
-	initrd_start_p = (unsigned long *)__pa_nodebug(&initrd_start);
-	initrd_start_addr = (unsigned long)__pa_nodebug(*initrd_start_p);
 #else
-	mc_saved_data_p = &mc_saved_data;
 	mc_saved_in_initrd_p = mc_saved_in_initrd;
-	initrd_start_addr = initrd_start;
+	mc_saved_data_p = &mc_saved_data;
 #endif
 
 	/*
@@ -777,7 +779,7 @@ void load_ucode_intel_ap(void)
 
 	collect_cpu_info_early(&uci);
 	ret = load_microcode(mc_saved_data_p, mc_saved_in_initrd_p,
-			     initrd_start_addr, &uci);
+			     get_initrd_start_addr(), &uci);
 
 	if (ret != UCODE_OK)
 		return;
--- zfcpdump-kernel-4.4.orig/arch/x86/kernel/cpu/mkcapflags.sh
+++ zfcpdump-kernel-4.4/arch/x86/kernel/cpu/mkcapflags.sh
@@ -1,6 +1,6 @@
 #!/bin/sh
 #
-# Generate the x86_cap/bug_flags[] arrays from include/asm/cpufeature.h
+# Generate the x86_cap/bug_flags[] arrays from include/asm/cpufeatures.h
 #
 
 IN=$1
@@ -49,8 +49,8 @@ dump_array()
 trap 'rm "$OUT"' EXIT
 
 (
-	echo "#ifndef _ASM_X86_CPUFEATURE_H"
-	echo "#include <asm/cpufeature.h>"
+	echo "#ifndef _ASM_X86_CPUFEATURES_H"
+	echo "#include <asm/cpufeatures.h>"
 	echo "#endif"
 	echo ""
 
--- zfcpdump-kernel-4.4.orig/arch/x86/kernel/cpu/mshyperv.c
+++ zfcpdump-kernel-4.4/arch/x86/kernel/cpu/mshyperv.c
@@ -13,7 +13,8 @@
 #include <linux/types.h>
 #include <linux/time.h>
 #include <linux/clocksource.h>
-#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/export.h>
 #include <linux/hardirq.h>
 #include <linux/efi.h>
 #include <linux/interrupt.h>
@@ -152,6 +153,11 @@ static struct clocksource hyperv_cs = {
 	.flags		= CLOCK_SOURCE_IS_CONTINUOUS,
 };
 
+static unsigned char hv_get_nmi_reason(void)
+{
+	return 0;
+}
+
 static void __init ms_hyperv_init_platform(void)
 {
 	/*
@@ -191,6 +197,13 @@ static void __init ms_hyperv_init_platfo
 	machine_ops.crash_shutdown = hv_machine_crash_shutdown;
 #endif
 	mark_tsc_unstable("running on Hyper-V");
+
+	/*
+	 * Generation 2 instances don't support reading the NMI status from
+	 * 0x61 port.
+	 */
+	if (efi_enabled(EFI_BOOT))
+		x86_platform.get_nmi_reason = hv_get_nmi_reason;
 }
 
 const __refconst struct hypervisor_x86 x86_hyper_ms_hyperv = {
--- zfcpdump-kernel-4.4.orig/arch/x86/kernel/cpu/mtrr/cleanup.c
+++ zfcpdump-kernel-4.4/arch/x86/kernel/cpu/mtrr/cleanup.c
@@ -17,7 +17,6 @@
  * License along with this library; if not, write to the Free
  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-#include <linux/module.h>
 #include <linux/init.h>
 #include <linux/pci.h>
 #include <linux/smp.h>
--- zfcpdump-kernel-4.4.orig/arch/x86/kernel/cpu/mtrr/generic.c
+++ zfcpdump-kernel-4.4/arch/x86/kernel/cpu/mtrr/generic.c
@@ -4,7 +4,7 @@
  */
 #define DEBUG
 
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/init.h>
 #include <linux/io.h>
 #include <linux/mm.h>
@@ -444,11 +444,24 @@ static void __init print_mtrr_state(void
 		pr_debug("TOM2: %016llx aka %lldM\n", mtrr_tom2, mtrr_tom2>>20);
 }
 
+/* PAT setup for BP. We need to go through sync steps here */
+void __init mtrr_bp_pat_init(void)
+{
+	unsigned long flags;
+
+	local_irq_save(flags);
+	prepare_set();
+
+	pat_init();
+
+	post_set();
+	local_irq_restore(flags);
+}
+
 /* Grab all of the MTRR state for this CPU into *state */
 bool __init get_mtrr_state(void)
 {
 	struct mtrr_var_range *vrs;
-	unsigned long flags;
 	unsigned lo, dummy;
 	unsigned int i;
 
@@ -481,15 +494,6 @@ bool __init get_mtrr_state(void)
 
 	mtrr_state_set = 1;
 
-	/* PAT setup for BP. We need to go through sync steps here */
-	local_irq_save(flags);
-	prepare_set();
-
-	pat_init();
-
-	post_set();
-	local_irq_restore(flags);
-
 	return !!(mtrr_state.enabled & MTRR_STATE_MTRR_ENABLED);
 }
 
--- zfcpdump-kernel-4.4.orig/arch/x86/kernel/cpu/mtrr/main.c
+++ zfcpdump-kernel-4.4/arch/x86/kernel/cpu/mtrr/main.c
@@ -47,7 +47,7 @@
 #include <linux/smp.h>
 #include <linux/syscore_ops.h>
 
-#include <asm/processor.h>
+#include <asm/cpufeature.h>
 #include <asm/e820.h>
 #include <asm/mtrr.h>
 #include <asm/msr.h>
@@ -752,6 +752,9 @@ void __init mtrr_bp_init(void)
 			/* BIOS may override */
 			__mtrr_enabled = get_mtrr_state();
 
+			if (mtrr_enabled())
+				mtrr_bp_pat_init();
+
 			if (mtrr_cleanup(phys_addr)) {
 				changed_by_mtrr_cleanup = 1;
 				mtrr_if->set_all();
@@ -759,8 +762,16 @@ void __init mtrr_bp_init(void)
 		}
 	}
 
-	if (!mtrr_enabled())
+	if (!mtrr_enabled()) {
 		pr_info("MTRR: Disabled\n");
+
+		/*
+		 * PAT initialization relies on MTRR's rendezvous handler.
+		 * Skip PAT init until the handler can initialize both
+		 * features independently.
+		 */
+		pat_disable("MTRRs disabled, skipping PAT initialization too.");
+	}
 }
 
 void mtrr_ap_init(void)
--- zfcpdump-kernel-4.4.orig/arch/x86/kernel/cpu/mtrr/mtrr.h
+++ zfcpdump-kernel-4.4/arch/x86/kernel/cpu/mtrr/mtrr.h
@@ -52,6 +52,7 @@ void set_mtrr_prepare_save(struct set_mt
 void fill_mtrr_var_range(unsigned int index,
 		u32 base_lo, u32 base_hi, u32 mask_lo, u32 mask_hi);
 bool get_mtrr_state(void);
+void mtrr_bp_pat_init(void);
 
 extern void set_mtrr_ops(const struct mtrr_ops *ops);
 
--- zfcpdump-kernel-4.4.orig/arch/x86/kernel/cpu/perf_event.c
+++ /dev/null
@@ -1,2400 +0,0 @@
-/*
- * Performance events x86 architecture code
- *
- *  Copyright (C) 2008 Thomas Gleixner <tglx@linutronix.de>
- *  Copyright (C) 2008-2009 Red Hat, Inc., Ingo Molnar
- *  Copyright (C) 2009 Jaswinder Singh Rajput
- *  Copyright (C) 2009 Advanced Micro Devices, Inc., Robert Richter
- *  Copyright (C) 2008-2009 Red Hat, Inc., Peter Zijlstra
- *  Copyright (C) 2009 Intel Corporation, <markus.t.metzger@intel.com>
- *  Copyright (C) 2009 Google, Inc., Stephane Eranian
- *
- *  For licencing details see kernel-base/COPYING
- */
-
-#include <linux/perf_event.h>
-#include <linux/capability.h>
-#include <linux/notifier.h>
-#include <linux/hardirq.h>
-#include <linux/kprobes.h>
-#include <linux/module.h>
-#include <linux/kdebug.h>
-#include <linux/sched.h>
-#include <linux/uaccess.h>
-#include <linux/slab.h>
-#include <linux/cpu.h>
-#include <linux/bitops.h>
-#include <linux/device.h>
-
-#include <asm/apic.h>
-#include <asm/stacktrace.h>
-#include <asm/nmi.h>
-#include <asm/smp.h>
-#include <asm/alternative.h>
-#include <asm/mmu_context.h>
-#include <asm/tlbflush.h>
-#include <asm/timer.h>
-#include <asm/desc.h>
-#include <asm/ldt.h>
-
-#include "perf_event.h"
-
-struct x86_pmu x86_pmu __read_mostly;
-
-DEFINE_PER_CPU(struct cpu_hw_events, cpu_hw_events) = {
-	.enabled = 1,
-};
-
-struct static_key rdpmc_always_available = STATIC_KEY_INIT_FALSE;
-
-u64 __read_mostly hw_cache_event_ids
-				[PERF_COUNT_HW_CACHE_MAX]
-				[PERF_COUNT_HW_CACHE_OP_MAX]
-				[PERF_COUNT_HW_CACHE_RESULT_MAX];
-u64 __read_mostly hw_cache_extra_regs
-				[PERF_COUNT_HW_CACHE_MAX]
-				[PERF_COUNT_HW_CACHE_OP_MAX]
-				[PERF_COUNT_HW_CACHE_RESULT_MAX];
-
-/*
- * Propagate event elapsed time into the generic event.
- * Can only be executed on the CPU where the event is active.
- * Returns the delta events processed.
- */
-u64 x86_perf_event_update(struct perf_event *event)
-{
-	struct hw_perf_event *hwc = &event->hw;
-	int shift = 64 - x86_pmu.cntval_bits;
-	u64 prev_raw_count, new_raw_count;
-	int idx = hwc->idx;
-	s64 delta;
-
-	if (idx == INTEL_PMC_IDX_FIXED_BTS)
-		return 0;
-
-	/*
-	 * Careful: an NMI might modify the previous event value.
-	 *
-	 * Our tactic to handle this is to first atomically read and
-	 * exchange a new raw count - then add that new-prev delta
-	 * count to the generic event atomically:
-	 */
-again:
-	prev_raw_count = local64_read(&hwc->prev_count);
-	rdpmcl(hwc->event_base_rdpmc, new_raw_count);
-
-	if (local64_cmpxchg(&hwc->prev_count, prev_raw_count,
-					new_raw_count) != prev_raw_count)
-		goto again;
-
-	/*
-	 * Now we have the new raw value and have updated the prev
-	 * timestamp already. We can now calculate the elapsed delta
-	 * (event-)time and add that to the generic event.
-	 *
-	 * Careful, not all hw sign-extends above the physical width
-	 * of the count.
-	 */
-	delta = (new_raw_count << shift) - (prev_raw_count << shift);
-	delta >>= shift;
-
-	local64_add(delta, &event->count);
-	local64_sub(delta, &hwc->period_left);
-
-	return new_raw_count;
-}
-
-/*
- * Find and validate any extra registers to set up.
- */
-static int x86_pmu_extra_regs(u64 config, struct perf_event *event)
-{
-	struct hw_perf_event_extra *reg;
-	struct extra_reg *er;
-
-	reg = &event->hw.extra_reg;
-
-	if (!x86_pmu.extra_regs)
-		return 0;
-
-	for (er = x86_pmu.extra_regs; er->msr; er++) {
-		if (er->event != (config & er->config_mask))
-			continue;
-		if (event->attr.config1 & ~er->valid_mask)
-			return -EINVAL;
-		/* Check if the extra msrs can be safely accessed*/
-		if (!er->extra_msr_access)
-			return -ENXIO;
-
-		reg->idx = er->idx;
-		reg->config = event->attr.config1;
-		reg->reg = er->msr;
-		break;
-	}
-	return 0;
-}
-
-static atomic_t active_events;
-static atomic_t pmc_refcount;
-static DEFINE_MUTEX(pmc_reserve_mutex);
-
-#ifdef CONFIG_X86_LOCAL_APIC
-
-static bool reserve_pmc_hardware(void)
-{
-	int i;
-
-	for (i = 0; i < x86_pmu.num_counters; i++) {
-		if (!reserve_perfctr_nmi(x86_pmu_event_addr(i)))
-			goto perfctr_fail;
-	}
-
-	for (i = 0; i < x86_pmu.num_counters; i++) {
-		if (!reserve_evntsel_nmi(x86_pmu_config_addr(i)))
-			goto eventsel_fail;
-	}
-
-	return true;
-
-eventsel_fail:
-	for (i--; i >= 0; i--)
-		release_evntsel_nmi(x86_pmu_config_addr(i));
-
-	i = x86_pmu.num_counters;
-
-perfctr_fail:
-	for (i--; i >= 0; i--)
-		release_perfctr_nmi(x86_pmu_event_addr(i));
-
-	return false;
-}
-
-static void release_pmc_hardware(void)
-{
-	int i;
-
-	for (i = 0; i < x86_pmu.num_counters; i++) {
-		release_perfctr_nmi(x86_pmu_event_addr(i));
-		release_evntsel_nmi(x86_pmu_config_addr(i));
-	}
-}
-
-#else
-
-static bool reserve_pmc_hardware(void) { return true; }
-static void release_pmc_hardware(void) {}
-
-#endif
-
-static bool check_hw_exists(void)
-{
-	u64 val, val_fail, val_new= ~0;
-	int i, reg, reg_fail, ret = 0;
-	int bios_fail = 0;
-	int reg_safe = -1;
-
-	/*
-	 * Check to see if the BIOS enabled any of the counters, if so
-	 * complain and bail.
-	 */
-	for (i = 0; i < x86_pmu.num_counters; i++) {
-		reg = x86_pmu_config_addr(i);
-		ret = rdmsrl_safe(reg, &val);
-		if (ret)
-			goto msr_fail;
-		if (val & ARCH_PERFMON_EVENTSEL_ENABLE) {
-			bios_fail = 1;
-			val_fail = val;
-			reg_fail = reg;
-		} else {
-			reg_safe = i;
-		}
-	}
-
-	if (x86_pmu.num_counters_fixed) {
-		reg = MSR_ARCH_PERFMON_FIXED_CTR_CTRL;
-		ret = rdmsrl_safe(reg, &val);
-		if (ret)
-			goto msr_fail;
-		for (i = 0; i < x86_pmu.num_counters_fixed; i++) {
-			if (val & (0x03 << i*4)) {
-				bios_fail = 1;
-				val_fail = val;
-				reg_fail = reg;
-			}
-		}
-	}
-
-	/*
-	 * If all the counters are enabled, the below test will always
-	 * fail.  The tools will also become useless in this scenario.
-	 * Just fail and disable the hardware counters.
-	 */
-
-	if (reg_safe == -1) {
-		reg = reg_safe;
-		goto msr_fail;
-	}
-
-	/*
-	 * Read the current value, change it and read it back to see if it
-	 * matches, this is needed to detect certain hardware emulators
-	 * (qemu/kvm) that don't trap on the MSR access and always return 0s.
-	 */
-	reg = x86_pmu_event_addr(reg_safe);
-	if (rdmsrl_safe(reg, &val))
-		goto msr_fail;
-	val ^= 0xffffUL;
-	ret = wrmsrl_safe(reg, val);
-	ret |= rdmsrl_safe(reg, &val_new);
-	if (ret || val != val_new)
-		goto msr_fail;
-
-	/*
-	 * We still allow the PMU driver to operate:
-	 */
-	if (bios_fail) {
-		printk(KERN_CONT "Broken BIOS detected, complain to your hardware vendor.\n");
-		printk(KERN_ERR FW_BUG "the BIOS has corrupted hw-PMU resources (MSR %x is %Lx)\n", reg_fail, val_fail);
-	}
-
-	return true;
-
-msr_fail:
-	printk(KERN_CONT "Broken PMU hardware detected, using software events only.\n");
-	printk("%sFailed to access perfctr msr (MSR %x is %Lx)\n",
-		boot_cpu_has(X86_FEATURE_HYPERVISOR) ? KERN_INFO : KERN_ERR,
-		reg, val_new);
-
-	return false;
-}
-
-static void hw_perf_event_destroy(struct perf_event *event)
-{
-	x86_release_hardware();
-	atomic_dec(&active_events);
-}
-
-void hw_perf_lbr_event_destroy(struct perf_event *event)
-{
-	hw_perf_event_destroy(event);
-
-	/* undo the lbr/bts event accounting */
-	x86_del_exclusive(x86_lbr_exclusive_lbr);
-}
-
-static inline int x86_pmu_initialized(void)
-{
-	return x86_pmu.handle_irq != NULL;
-}
-
-static inline int
-set_ext_hw_attr(struct hw_perf_event *hwc, struct perf_event *event)
-{
-	struct perf_event_attr *attr = &event->attr;
-	unsigned int cache_type, cache_op, cache_result;
-	u64 config, val;
-
-	config = attr->config;
-
-	cache_type = (config >>  0) & 0xff;
-	if (cache_type >= PERF_COUNT_HW_CACHE_MAX)
-		return -EINVAL;
-
-	cache_op = (config >>  8) & 0xff;
-	if (cache_op >= PERF_COUNT_HW_CACHE_OP_MAX)
-		return -EINVAL;
-
-	cache_result = (config >> 16) & 0xff;
-	if (cache_result >= PERF_COUNT_HW_CACHE_RESULT_MAX)
-		return -EINVAL;
-
-	val = hw_cache_event_ids[cache_type][cache_op][cache_result];
-
-	if (val == 0)
-		return -ENOENT;
-
-	if (val == -1)
-		return -EINVAL;
-
-	hwc->config |= val;
-	attr->config1 = hw_cache_extra_regs[cache_type][cache_op][cache_result];
-	return x86_pmu_extra_regs(val, event);
-}
-
-int x86_reserve_hardware(void)
-{
-	int err = 0;
-
-	if (!atomic_inc_not_zero(&pmc_refcount)) {
-		mutex_lock(&pmc_reserve_mutex);
-		if (atomic_read(&pmc_refcount) == 0) {
-			if (!reserve_pmc_hardware())
-				err = -EBUSY;
-			else
-				reserve_ds_buffers();
-		}
-		if (!err)
-			atomic_inc(&pmc_refcount);
-		mutex_unlock(&pmc_reserve_mutex);
-	}
-
-	return err;
-}
-
-void x86_release_hardware(void)
-{
-	if (atomic_dec_and_mutex_lock(&pmc_refcount, &pmc_reserve_mutex)) {
-		release_pmc_hardware();
-		release_ds_buffers();
-		mutex_unlock(&pmc_reserve_mutex);
-	}
-}
-
-/*
- * Check if we can create event of a certain type (that no conflicting events
- * are present).
- */
-int x86_add_exclusive(unsigned int what)
-{
-	int i;
-
-	if (!atomic_inc_not_zero(&x86_pmu.lbr_exclusive[what])) {
-		mutex_lock(&pmc_reserve_mutex);
-		for (i = 0; i < ARRAY_SIZE(x86_pmu.lbr_exclusive); i++) {
-			if (i != what && atomic_read(&x86_pmu.lbr_exclusive[i]))
-				goto fail_unlock;
-		}
-		atomic_inc(&x86_pmu.lbr_exclusive[what]);
-		mutex_unlock(&pmc_reserve_mutex);
-	}
-
-	atomic_inc(&active_events);
-	return 0;
-
-fail_unlock:
-	mutex_unlock(&pmc_reserve_mutex);
-	return -EBUSY;
-}
-
-void x86_del_exclusive(unsigned int what)
-{
-	atomic_dec(&x86_pmu.lbr_exclusive[what]);
-	atomic_dec(&active_events);
-}
-
-int x86_setup_perfctr(struct perf_event *event)
-{
-	struct perf_event_attr *attr = &event->attr;
-	struct hw_perf_event *hwc = &event->hw;
-	u64 config;
-
-	if (!is_sampling_event(event)) {
-		hwc->sample_period = x86_pmu.max_period;
-		hwc->last_period = hwc->sample_period;
-		local64_set(&hwc->period_left, hwc->sample_period);
-	}
-
-	if (attr->type == PERF_TYPE_RAW)
-		return x86_pmu_extra_regs(event->attr.config, event);
-
-	if (attr->type == PERF_TYPE_HW_CACHE)
-		return set_ext_hw_attr(hwc, event);
-
-	if (attr->config >= x86_pmu.max_events)
-		return -EINVAL;
-
-	/*
-	 * The generic map:
-	 */
-	config = x86_pmu.event_map(attr->config);
-
-	if (config == 0)
-		return -ENOENT;
-
-	if (config == -1LL)
-		return -EINVAL;
-
-	/*
-	 * Branch tracing:
-	 */
-	if (attr->config == PERF_COUNT_HW_BRANCH_INSTRUCTIONS &&
-	    !attr->freq && hwc->sample_period == 1) {
-		/* BTS is not supported by this architecture. */
-		if (!x86_pmu.bts_active)
-			return -EOPNOTSUPP;
-
-		/* BTS is currently only allowed for user-mode. */
-		if (!attr->exclude_kernel)
-			return -EOPNOTSUPP;
-
-		/* disallow bts if conflicting events are present */
-		if (x86_add_exclusive(x86_lbr_exclusive_lbr))
-			return -EBUSY;
-
-		event->destroy = hw_perf_lbr_event_destroy;
-	}
-
-	hwc->config |= config;
-
-	return 0;
-}
-
-/*
- * check that branch_sample_type is compatible with
- * settings needed for precise_ip > 1 which implies
- * using the LBR to capture ALL taken branches at the
- * priv levels of the measurement
- */
-static inline int precise_br_compat(struct perf_event *event)
-{
-	u64 m = event->attr.branch_sample_type;
-	u64 b = 0;
-
-	/* must capture all branches */
-	if (!(m & PERF_SAMPLE_BRANCH_ANY))
-		return 0;
-
-	m &= PERF_SAMPLE_BRANCH_KERNEL | PERF_SAMPLE_BRANCH_USER;
-
-	if (!event->attr.exclude_user)
-		b |= PERF_SAMPLE_BRANCH_USER;
-
-	if (!event->attr.exclude_kernel)
-		b |= PERF_SAMPLE_BRANCH_KERNEL;
-
-	/*
-	 * ignore PERF_SAMPLE_BRANCH_HV, not supported on x86
-	 */
-
-	return m == b;
-}
-
-int x86_pmu_hw_config(struct perf_event *event)
-{
-	if (event->attr.precise_ip) {
-		int precise = 0;
-
-		/* Support for constant skid */
-		if (x86_pmu.pebs_active && !x86_pmu.pebs_broken) {
-			precise++;
-
-			/* Support for IP fixup */
-			if (x86_pmu.lbr_nr || x86_pmu.intel_cap.pebs_format >= 2)
-				precise++;
-		}
-
-		if (event->attr.precise_ip > precise)
-			return -EOPNOTSUPP;
-	}
-	/*
-	 * check that PEBS LBR correction does not conflict with
-	 * whatever the user is asking with attr->branch_sample_type
-	 */
-	if (event->attr.precise_ip > 1 && x86_pmu.intel_cap.pebs_format < 2) {
-		u64 *br_type = &event->attr.branch_sample_type;
-
-		if (has_branch_stack(event)) {
-			if (!precise_br_compat(event))
-				return -EOPNOTSUPP;
-
-			/* branch_sample_type is compatible */
-
-		} else {
-			/*
-			 * user did not specify  branch_sample_type
-			 *
-			 * For PEBS fixups, we capture all
-			 * the branches at the priv level of the
-			 * event.
-			 */
-			*br_type = PERF_SAMPLE_BRANCH_ANY;
-
-			if (!event->attr.exclude_user)
-				*br_type |= PERF_SAMPLE_BRANCH_USER;
-
-			if (!event->attr.exclude_kernel)
-				*br_type |= PERF_SAMPLE_BRANCH_KERNEL;
-		}
-	}
-
-	if (event->attr.branch_sample_type & PERF_SAMPLE_BRANCH_CALL_STACK)
-		event->attach_state |= PERF_ATTACH_TASK_DATA;
-
-	/*
-	 * Generate PMC IRQs:
-	 * (keep 'enabled' bit clear for now)
-	 */
-	event->hw.config = ARCH_PERFMON_EVENTSEL_INT;
-
-	/*
-	 * Count user and OS events unless requested not to
-	 */
-	if (!event->attr.exclude_user)
-		event->hw.config |= ARCH_PERFMON_EVENTSEL_USR;
-	if (!event->attr.exclude_kernel)
-		event->hw.config |= ARCH_PERFMON_EVENTSEL_OS;
-
-	if (event->attr.type == PERF_TYPE_RAW)
-		event->hw.config |= event->attr.config & X86_RAW_EVENT_MASK;
-
-	if (event->attr.sample_period && x86_pmu.limit_period) {
-		if (x86_pmu.limit_period(event, event->attr.sample_period) >
-				event->attr.sample_period)
-			return -EINVAL;
-	}
-
-	return x86_setup_perfctr(event);
-}
-
-/*
- * Setup the hardware configuration for a given attr_type
- */
-static int __x86_pmu_event_init(struct perf_event *event)
-{
-	int err;
-
-	if (!x86_pmu_initialized())
-		return -ENODEV;
-
-	err = x86_reserve_hardware();
-	if (err)
-		return err;
-
-	atomic_inc(&active_events);
-	event->destroy = hw_perf_event_destroy;
-
-	event->hw.idx = -1;
-	event->hw.last_cpu = -1;
-	event->hw.last_tag = ~0ULL;
-
-	/* mark unused */
-	event->hw.extra_reg.idx = EXTRA_REG_NONE;
-	event->hw.branch_reg.idx = EXTRA_REG_NONE;
-
-	return x86_pmu.hw_config(event);
-}
-
-void x86_pmu_disable_all(void)
-{
-	struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
-	int idx;
-
-	for (idx = 0; idx < x86_pmu.num_counters; idx++) {
-		u64 val;
-
-		if (!test_bit(idx, cpuc->active_mask))
-			continue;
-		rdmsrl(x86_pmu_config_addr(idx), val);
-		if (!(val & ARCH_PERFMON_EVENTSEL_ENABLE))
-			continue;
-		val &= ~ARCH_PERFMON_EVENTSEL_ENABLE;
-		wrmsrl(x86_pmu_config_addr(idx), val);
-	}
-}
-
-static void x86_pmu_disable(struct pmu *pmu)
-{
-	struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
-
-	if (!x86_pmu_initialized())
-		return;
-
-	if (!cpuc->enabled)
-		return;
-
-	cpuc->n_added = 0;
-	cpuc->enabled = 0;
-	barrier();
-
-	x86_pmu.disable_all();
-}
-
-void x86_pmu_enable_all(int added)
-{
-	struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
-	int idx;
-
-	for (idx = 0; idx < x86_pmu.num_counters; idx++) {
-		struct hw_perf_event *hwc = &cpuc->events[idx]->hw;
-
-		if (!test_bit(idx, cpuc->active_mask))
-			continue;
-
-		__x86_pmu_enable_event(hwc, ARCH_PERFMON_EVENTSEL_ENABLE);
-	}
-}
-
-static struct pmu pmu;
-
-static inline int is_x86_event(struct perf_event *event)
-{
-	return event->pmu == &pmu;
-}
-
-/*
- * Event scheduler state:
- *
- * Assign events iterating over all events and counters, beginning
- * with events with least weights first. Keep the current iterator
- * state in struct sched_state.
- */
-struct sched_state {
-	int	weight;
-	int	event;		/* event index */
-	int	counter;	/* counter index */
-	int	unassigned;	/* number of events to be assigned left */
-	int	nr_gp;		/* number of GP counters used */
-	unsigned long used[BITS_TO_LONGS(X86_PMC_IDX_MAX)];
-};
-
-/* Total max is X86_PMC_IDX_MAX, but we are O(n!) limited */
-#define	SCHED_STATES_MAX	2
-
-struct perf_sched {
-	int			max_weight;
-	int			max_events;
-	int			max_gp;
-	int			saved_states;
-	struct event_constraint	**constraints;
-	struct sched_state	state;
-	struct sched_state	saved[SCHED_STATES_MAX];
-};
-
-/*
- * Initialize interator that runs through all events and counters.
- */
-static void perf_sched_init(struct perf_sched *sched, struct event_constraint **constraints,
-			    int num, int wmin, int wmax, int gpmax)
-{
-	int idx;
-
-	memset(sched, 0, sizeof(*sched));
-	sched->max_events	= num;
-	sched->max_weight	= wmax;
-	sched->max_gp		= gpmax;
-	sched->constraints	= constraints;
-
-	for (idx = 0; idx < num; idx++) {
-		if (constraints[idx]->weight == wmin)
-			break;
-	}
-
-	sched->state.event	= idx;		/* start with min weight */
-	sched->state.weight	= wmin;
-	sched->state.unassigned	= num;
-}
-
-static void perf_sched_save_state(struct perf_sched *sched)
-{
-	if (WARN_ON_ONCE(sched->saved_states >= SCHED_STATES_MAX))
-		return;
-
-	sched->saved[sched->saved_states] = sched->state;
-	sched->saved_states++;
-}
-
-static bool perf_sched_restore_state(struct perf_sched *sched)
-{
-	if (!sched->saved_states)
-		return false;
-
-	sched->saved_states--;
-	sched->state = sched->saved[sched->saved_states];
-
-	/* continue with next counter: */
-	clear_bit(sched->state.counter++, sched->state.used);
-
-	return true;
-}
-
-/*
- * Select a counter for the current event to schedule. Return true on
- * success.
- */
-static bool __perf_sched_find_counter(struct perf_sched *sched)
-{
-	struct event_constraint *c;
-	int idx;
-
-	if (!sched->state.unassigned)
-		return false;
-
-	if (sched->state.event >= sched->max_events)
-		return false;
-
-	c = sched->constraints[sched->state.event];
-	/* Prefer fixed purpose counters */
-	if (c->idxmsk64 & (~0ULL << INTEL_PMC_IDX_FIXED)) {
-		idx = INTEL_PMC_IDX_FIXED;
-		for_each_set_bit_from(idx, c->idxmsk, X86_PMC_IDX_MAX) {
-			if (!__test_and_set_bit(idx, sched->state.used))
-				goto done;
-		}
-	}
-
-	/* Grab the first unused counter starting with idx */
-	idx = sched->state.counter;
-	for_each_set_bit_from(idx, c->idxmsk, INTEL_PMC_IDX_FIXED) {
-		if (!__test_and_set_bit(idx, sched->state.used)) {
-			if (sched->state.nr_gp++ >= sched->max_gp)
-				return false;
-
-			goto done;
-		}
-	}
-
-	return false;
-
-done:
-	sched->state.counter = idx;
-
-	if (c->overlap)
-		perf_sched_save_state(sched);
-
-	return true;
-}
-
-static bool perf_sched_find_counter(struct perf_sched *sched)
-{
-	while (!__perf_sched_find_counter(sched)) {
-		if (!perf_sched_restore_state(sched))
-			return false;
-	}
-
-	return true;
-}
-
-/*
- * Go through all unassigned events and find the next one to schedule.
- * Take events with the least weight first. Return true on success.
- */
-static bool perf_sched_next_event(struct perf_sched *sched)
-{
-	struct event_constraint *c;
-
-	if (!sched->state.unassigned || !--sched->state.unassigned)
-		return false;
-
-	do {
-		/* next event */
-		sched->state.event++;
-		if (sched->state.event >= sched->max_events) {
-			/* next weight */
-			sched->state.event = 0;
-			sched->state.weight++;
-			if (sched->state.weight > sched->max_weight)
-				return false;
-		}
-		c = sched->constraints[sched->state.event];
-	} while (c->weight != sched->state.weight);
-
-	sched->state.counter = 0;	/* start with first counter */
-
-	return true;
-}
-
-/*
- * Assign a counter for each event.
- */
-int perf_assign_events(struct event_constraint **constraints, int n,
-			int wmin, int wmax, int gpmax, int *assign)
-{
-	struct perf_sched sched;
-
-	perf_sched_init(&sched, constraints, n, wmin, wmax, gpmax);
-
-	do {
-		if (!perf_sched_find_counter(&sched))
-			break;	/* failed */
-		if (assign)
-			assign[sched.state.event] = sched.state.counter;
-	} while (perf_sched_next_event(&sched));
-
-	return sched.state.unassigned;
-}
-EXPORT_SYMBOL_GPL(perf_assign_events);
-
-int x86_schedule_events(struct cpu_hw_events *cpuc, int n, int *assign)
-{
-	struct event_constraint *c;
-	unsigned long used_mask[BITS_TO_LONGS(X86_PMC_IDX_MAX)];
-	struct perf_event *e;
-	int i, wmin, wmax, unsched = 0;
-	struct hw_perf_event *hwc;
-
-	bitmap_zero(used_mask, X86_PMC_IDX_MAX);
-
-	if (x86_pmu.start_scheduling)
-		x86_pmu.start_scheduling(cpuc);
-
-	for (i = 0, wmin = X86_PMC_IDX_MAX, wmax = 0; i < n; i++) {
-		cpuc->event_constraint[i] = NULL;
-		c = x86_pmu.get_event_constraints(cpuc, i, cpuc->event_list[i]);
-		cpuc->event_constraint[i] = c;
-
-		wmin = min(wmin, c->weight);
-		wmax = max(wmax, c->weight);
-	}
-
-	/*
-	 * fastpath, try to reuse previous register
-	 */
-	for (i = 0; i < n; i++) {
-		hwc = &cpuc->event_list[i]->hw;
-		c = cpuc->event_constraint[i];
-
-		/* never assigned */
-		if (hwc->idx == -1)
-			break;
-
-		/* constraint still honored */
-		if (!test_bit(hwc->idx, c->idxmsk))
-			break;
-
-		/* not already used */
-		if (test_bit(hwc->idx, used_mask))
-			break;
-
-		__set_bit(hwc->idx, used_mask);
-		if (assign)
-			assign[i] = hwc->idx;
-	}
-
-	/* slow path */
-	if (i != n) {
-		int gpmax = x86_pmu.num_counters;
-
-		/*
-		 * Do not allow scheduling of more than half the available
-		 * generic counters.
-		 *
-		 * This helps avoid counter starvation of sibling thread by
-		 * ensuring at most half the counters cannot be in exclusive
-		 * mode. There is no designated counters for the limits. Any
-		 * N/2 counters can be used. This helps with events with
-		 * specific counter constraints.
-		 */
-		if (is_ht_workaround_enabled() && !cpuc->is_fake &&
-		    READ_ONCE(cpuc->excl_cntrs->exclusive_present))
-			gpmax /= 2;
-
-		unsched = perf_assign_events(cpuc->event_constraint, n, wmin,
-					     wmax, gpmax, assign);
-	}
-
-	/*
-	 * In case of success (unsched = 0), mark events as committed,
-	 * so we do not put_constraint() in case new events are added
-	 * and fail to be scheduled
-	 *
-	 * We invoke the lower level commit callback to lock the resource
-	 *
-	 * We do not need to do all of this in case we are called to
-	 * validate an event group (assign == NULL)
-	 */
-	if (!unsched && assign) {
-		for (i = 0; i < n; i++) {
-			e = cpuc->event_list[i];
-			e->hw.flags |= PERF_X86_EVENT_COMMITTED;
-			if (x86_pmu.commit_scheduling)
-				x86_pmu.commit_scheduling(cpuc, i, assign[i]);
-		}
-	} else {
-		for (i = 0; i < n; i++) {
-			e = cpuc->event_list[i];
-			/*
-			 * do not put_constraint() on comitted events,
-			 * because they are good to go
-			 */
-			if ((e->hw.flags & PERF_X86_EVENT_COMMITTED))
-				continue;
-
-			/*
-			 * release events that failed scheduling
-			 */
-			if (x86_pmu.put_event_constraints)
-				x86_pmu.put_event_constraints(cpuc, e);
-		}
-	}
-
-	if (x86_pmu.stop_scheduling)
-		x86_pmu.stop_scheduling(cpuc);
-
-	return unsched ? -EINVAL : 0;
-}
-
-/*
- * dogrp: true if must collect siblings events (group)
- * returns total number of events and error code
- */
-static int collect_events(struct cpu_hw_events *cpuc, struct perf_event *leader, bool dogrp)
-{
-	struct perf_event *event;
-	int n, max_count;
-
-	max_count = x86_pmu.num_counters + x86_pmu.num_counters_fixed;
-
-	/* current number of events already accepted */
-	n = cpuc->n_events;
-
-	if (is_x86_event(leader)) {
-		if (n >= max_count)
-			return -EINVAL;
-		cpuc->event_list[n] = leader;
-		n++;
-	}
-	if (!dogrp)
-		return n;
-
-	list_for_each_entry(event, &leader->sibling_list, group_entry) {
-		if (!is_x86_event(event) ||
-		    event->state <= PERF_EVENT_STATE_OFF)
-			continue;
-
-		if (n >= max_count)
-			return -EINVAL;
-
-		cpuc->event_list[n] = event;
-		n++;
-	}
-	return n;
-}
-
-static inline void x86_assign_hw_event(struct perf_event *event,
-				struct cpu_hw_events *cpuc, int i)
-{
-	struct hw_perf_event *hwc = &event->hw;
-
-	hwc->idx = cpuc->assign[i];
-	hwc->last_cpu = smp_processor_id();
-	hwc->last_tag = ++cpuc->tags[i];
-
-	if (hwc->idx == INTEL_PMC_IDX_FIXED_BTS) {
-		hwc->config_base = 0;
-		hwc->event_base	= 0;
-	} else if (hwc->idx >= INTEL_PMC_IDX_FIXED) {
-		hwc->config_base = MSR_ARCH_PERFMON_FIXED_CTR_CTRL;
-		hwc->event_base = MSR_ARCH_PERFMON_FIXED_CTR0 + (hwc->idx - INTEL_PMC_IDX_FIXED);
-		hwc->event_base_rdpmc = (hwc->idx - INTEL_PMC_IDX_FIXED) | 1<<30;
-	} else {
-		hwc->config_base = x86_pmu_config_addr(hwc->idx);
-		hwc->event_base  = x86_pmu_event_addr(hwc->idx);
-		hwc->event_base_rdpmc = x86_pmu_rdpmc_index(hwc->idx);
-	}
-}
-
-static inline int match_prev_assignment(struct hw_perf_event *hwc,
-					struct cpu_hw_events *cpuc,
-					int i)
-{
-	return hwc->idx == cpuc->assign[i] &&
-		hwc->last_cpu == smp_processor_id() &&
-		hwc->last_tag == cpuc->tags[i];
-}
-
-static void x86_pmu_start(struct perf_event *event, int flags);
-
-static void x86_pmu_enable(struct pmu *pmu)
-{
-	struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
-	struct perf_event *event;
-	struct hw_perf_event *hwc;
-	int i, added = cpuc->n_added;
-
-	if (!x86_pmu_initialized())
-		return;
-
-	if (cpuc->enabled)
-		return;
-
-	if (cpuc->n_added) {
-		int n_running = cpuc->n_events - cpuc->n_added;
-		/*
-		 * apply assignment obtained either from
-		 * hw_perf_group_sched_in() or x86_pmu_enable()
-		 *
-		 * step1: save events moving to new counters
-		 */
-		for (i = 0; i < n_running; i++) {
-			event = cpuc->event_list[i];
-			hwc = &event->hw;
-
-			/*
-			 * we can avoid reprogramming counter if:
-			 * - assigned same counter as last time
-			 * - running on same CPU as last time
-			 * - no other event has used the counter since
-			 */
-			if (hwc->idx == -1 ||
-			    match_prev_assignment(hwc, cpuc, i))
-				continue;
-
-			/*
-			 * Ensure we don't accidentally enable a stopped
-			 * counter simply because we rescheduled.
-			 */
-			if (hwc->state & PERF_HES_STOPPED)
-				hwc->state |= PERF_HES_ARCH;
-
-			x86_pmu_stop(event, PERF_EF_UPDATE);
-		}
-
-		/*
-		 * step2: reprogram moved events into new counters
-		 */
-		for (i = 0; i < cpuc->n_events; i++) {
-			event = cpuc->event_list[i];
-			hwc = &event->hw;
-
-			if (!match_prev_assignment(hwc, cpuc, i))
-				x86_assign_hw_event(event, cpuc, i);
-			else if (i < n_running)
-				continue;
-
-			if (hwc->state & PERF_HES_ARCH)
-				continue;
-
-			x86_pmu_start(event, PERF_EF_RELOAD);
-		}
-		cpuc->n_added = 0;
-		perf_events_lapic_init();
-	}
-
-	cpuc->enabled = 1;
-	barrier();
-
-	x86_pmu.enable_all(added);
-}
-
-static DEFINE_PER_CPU(u64 [X86_PMC_IDX_MAX], pmc_prev_left);
-
-/*
- * Set the next IRQ period, based on the hwc->period_left value.
- * To be called with the event disabled in hw:
- */
-int x86_perf_event_set_period(struct perf_event *event)
-{
-	struct hw_perf_event *hwc = &event->hw;
-	s64 left = local64_read(&hwc->period_left);
-	s64 period = hwc->sample_period;
-	int ret = 0, idx = hwc->idx;
-
-	if (idx == INTEL_PMC_IDX_FIXED_BTS)
-		return 0;
-
-	/*
-	 * If we are way outside a reasonable range then just skip forward:
-	 */
-	if (unlikely(left <= -period)) {
-		left = period;
-		local64_set(&hwc->period_left, left);
-		hwc->last_period = period;
-		ret = 1;
-	}
-
-	if (unlikely(left <= 0)) {
-		left += period;
-		local64_set(&hwc->period_left, left);
-		hwc->last_period = period;
-		ret = 1;
-	}
-	/*
-	 * Quirk: certain CPUs dont like it if just 1 hw_event is left:
-	 */
-	if (unlikely(left < 2))
-		left = 2;
-
-	if (left > x86_pmu.max_period)
-		left = x86_pmu.max_period;
-
-	if (x86_pmu.limit_period)
-		left = x86_pmu.limit_period(event, left);
-
-	per_cpu(pmc_prev_left[idx], smp_processor_id()) = left;
-
-	if (!(hwc->flags & PERF_X86_EVENT_AUTO_RELOAD) ||
-	    local64_read(&hwc->prev_count) != (u64)-left) {
-		/*
-		 * The hw event starts counting from this event offset,
-		 * mark it to be able to extra future deltas:
-		 */
-		local64_set(&hwc->prev_count, (u64)-left);
-
-		wrmsrl(hwc->event_base, (u64)(-left) & x86_pmu.cntval_mask);
-	}
-
-	/*
-	 * Due to erratum on certan cpu we need
-	 * a second write to be sure the register
-	 * is updated properly
-	 */
-	if (x86_pmu.perfctr_second_write) {
-		wrmsrl(hwc->event_base,
-			(u64)(-left) & x86_pmu.cntval_mask);
-	}
-
-	perf_event_update_userpage(event);
-
-	return ret;
-}
-
-void x86_pmu_enable_event(struct perf_event *event)
-{
-	if (__this_cpu_read(cpu_hw_events.enabled))
-		__x86_pmu_enable_event(&event->hw,
-				       ARCH_PERFMON_EVENTSEL_ENABLE);
-}
-
-/*
- * Add a single event to the PMU.
- *
- * The event is added to the group of enabled events
- * but only if it can be scehduled with existing events.
- */
-static int x86_pmu_add(struct perf_event *event, int flags)
-{
-	struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
-	struct hw_perf_event *hwc;
-	int assign[X86_PMC_IDX_MAX];
-	int n, n0, ret;
-
-	hwc = &event->hw;
-
-	n0 = cpuc->n_events;
-	ret = n = collect_events(cpuc, event, false);
-	if (ret < 0)
-		goto out;
-
-	hwc->state = PERF_HES_UPTODATE | PERF_HES_STOPPED;
-	if (!(flags & PERF_EF_START))
-		hwc->state |= PERF_HES_ARCH;
-
-	/*
-	 * If group events scheduling transaction was started,
-	 * skip the schedulability test here, it will be performed
-	 * at commit time (->commit_txn) as a whole.
-	 */
-	if (cpuc->txn_flags & PERF_PMU_TXN_ADD)
-		goto done_collect;
-
-	ret = x86_pmu.schedule_events(cpuc, n, assign);
-	if (ret)
-		goto out;
-	/*
-	 * copy new assignment, now we know it is possible
-	 * will be used by hw_perf_enable()
-	 */
-	memcpy(cpuc->assign, assign, n*sizeof(int));
-
-done_collect:
-	/*
-	 * Commit the collect_events() state. See x86_pmu_del() and
-	 * x86_pmu_*_txn().
-	 */
-	cpuc->n_events = n;
-	cpuc->n_added += n - n0;
-	cpuc->n_txn += n - n0;
-
-	ret = 0;
-out:
-	return ret;
-}
-
-static void x86_pmu_start(struct perf_event *event, int flags)
-{
-	struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
-	int idx = event->hw.idx;
-
-	if (WARN_ON_ONCE(!(event->hw.state & PERF_HES_STOPPED)))
-		return;
-
-	if (WARN_ON_ONCE(idx == -1))
-		return;
-
-	if (flags & PERF_EF_RELOAD) {
-		WARN_ON_ONCE(!(event->hw.state & PERF_HES_UPTODATE));
-		x86_perf_event_set_period(event);
-	}
-
-	event->hw.state = 0;
-
-	cpuc->events[idx] = event;
-	__set_bit(idx, cpuc->active_mask);
-	__set_bit(idx, cpuc->running);
-	x86_pmu.enable(event);
-	perf_event_update_userpage(event);
-}
-
-void perf_event_print_debug(void)
-{
-	u64 ctrl, status, overflow, pmc_ctrl, pmc_count, prev_left, fixed;
-	u64 pebs, debugctl;
-	struct cpu_hw_events *cpuc;
-	unsigned long flags;
-	int cpu, idx;
-
-	if (!x86_pmu.num_counters)
-		return;
-
-	local_irq_save(flags);
-
-	cpu = smp_processor_id();
-	cpuc = &per_cpu(cpu_hw_events, cpu);
-
-	if (x86_pmu.version >= 2) {
-		rdmsrl(MSR_CORE_PERF_GLOBAL_CTRL, ctrl);
-		rdmsrl(MSR_CORE_PERF_GLOBAL_STATUS, status);
-		rdmsrl(MSR_CORE_PERF_GLOBAL_OVF_CTRL, overflow);
-		rdmsrl(MSR_ARCH_PERFMON_FIXED_CTR_CTRL, fixed);
-
-		pr_info("\n");
-		pr_info("CPU#%d: ctrl:       %016llx\n", cpu, ctrl);
-		pr_info("CPU#%d: status:     %016llx\n", cpu, status);
-		pr_info("CPU#%d: overflow:   %016llx\n", cpu, overflow);
-		pr_info("CPU#%d: fixed:      %016llx\n", cpu, fixed);
-		if (x86_pmu.pebs_constraints) {
-			rdmsrl(MSR_IA32_PEBS_ENABLE, pebs);
-			pr_info("CPU#%d: pebs:       %016llx\n", cpu, pebs);
-		}
-		if (x86_pmu.lbr_nr) {
-			rdmsrl(MSR_IA32_DEBUGCTLMSR, debugctl);
-			pr_info("CPU#%d: debugctl:   %016llx\n", cpu, debugctl);
-		}
-	}
-	pr_info("CPU#%d: active:     %016llx\n", cpu, *(u64 *)cpuc->active_mask);
-
-	for (idx = 0; idx < x86_pmu.num_counters; idx++) {
-		rdmsrl(x86_pmu_config_addr(idx), pmc_ctrl);
-		rdmsrl(x86_pmu_event_addr(idx), pmc_count);
-
-		prev_left = per_cpu(pmc_prev_left[idx], cpu);
-
-		pr_info("CPU#%d:   gen-PMC%d ctrl:  %016llx\n",
-			cpu, idx, pmc_ctrl);
-		pr_info("CPU#%d:   gen-PMC%d count: %016llx\n",
-			cpu, idx, pmc_count);
-		pr_info("CPU#%d:   gen-PMC%d left:  %016llx\n",
-			cpu, idx, prev_left);
-	}
-	for (idx = 0; idx < x86_pmu.num_counters_fixed; idx++) {
-		rdmsrl(MSR_ARCH_PERFMON_FIXED_CTR0 + idx, pmc_count);
-
-		pr_info("CPU#%d: fixed-PMC%d count: %016llx\n",
-			cpu, idx, pmc_count);
-	}
-	local_irq_restore(flags);
-}
-
-void x86_pmu_stop(struct perf_event *event, int flags)
-{
-	struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
-	struct hw_perf_event *hwc = &event->hw;
-
-	if (__test_and_clear_bit(hwc->idx, cpuc->active_mask)) {
-		x86_pmu.disable(event);
-		cpuc->events[hwc->idx] = NULL;
-		WARN_ON_ONCE(hwc->state & PERF_HES_STOPPED);
-		hwc->state |= PERF_HES_STOPPED;
-	}
-
-	if ((flags & PERF_EF_UPDATE) && !(hwc->state & PERF_HES_UPTODATE)) {
-		/*
-		 * Drain the remaining delta count out of a event
-		 * that we are disabling:
-		 */
-		x86_perf_event_update(event);
-		hwc->state |= PERF_HES_UPTODATE;
-	}
-}
-
-static void x86_pmu_del(struct perf_event *event, int flags)
-{
-	struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
-	int i;
-
-	/*
-	 * event is descheduled
-	 */
-	event->hw.flags &= ~PERF_X86_EVENT_COMMITTED;
-
-	/*
-	 * If we're called during a txn, we don't need to do anything.
-	 * The events never got scheduled and ->cancel_txn will truncate
-	 * the event_list.
-	 *
-	 * XXX assumes any ->del() called during a TXN will only be on
-	 * an event added during that same TXN.
-	 */
-	if (cpuc->txn_flags & PERF_PMU_TXN_ADD)
-		return;
-
-	/*
-	 * Not a TXN, therefore cleanup properly.
-	 */
-	x86_pmu_stop(event, PERF_EF_UPDATE);
-
-	for (i = 0; i < cpuc->n_events; i++) {
-		if (event == cpuc->event_list[i])
-			break;
-	}
-
-	if (WARN_ON_ONCE(i == cpuc->n_events)) /* called ->del() without ->add() ? */
-		return;
-
-	/* If we have a newly added event; make sure to decrease n_added. */
-	if (i >= cpuc->n_events - cpuc->n_added)
-		--cpuc->n_added;
-
-	if (x86_pmu.put_event_constraints)
-		x86_pmu.put_event_constraints(cpuc, event);
-
-	/* Delete the array entry. */
-	while (++i < cpuc->n_events) {
-		cpuc->event_list[i-1] = cpuc->event_list[i];
-		cpuc->event_constraint[i-1] = cpuc->event_constraint[i];
-	}
-	--cpuc->n_events;
-
-	perf_event_update_userpage(event);
-}
-
-int x86_pmu_handle_irq(struct pt_regs *regs)
-{
-	struct perf_sample_data data;
-	struct cpu_hw_events *cpuc;
-	struct perf_event *event;
-	int idx, handled = 0;
-	u64 val;
-
-	cpuc = this_cpu_ptr(&cpu_hw_events);
-
-	/*
-	 * Some chipsets need to unmask the LVTPC in a particular spot
-	 * inside the nmi handler.  As a result, the unmasking was pushed
-	 * into all the nmi handlers.
-	 *
-	 * This generic handler doesn't seem to have any issues where the
-	 * unmasking occurs so it was left at the top.
-	 */
-	apic_write(APIC_LVTPC, APIC_DM_NMI);
-
-	for (idx = 0; idx < x86_pmu.num_counters; idx++) {
-		if (!test_bit(idx, cpuc->active_mask)) {
-			/*
-			 * Though we deactivated the counter some cpus
-			 * might still deliver spurious interrupts still
-			 * in flight. Catch them:
-			 */
-			if (__test_and_clear_bit(idx, cpuc->running))
-				handled++;
-			continue;
-		}
-
-		event = cpuc->events[idx];
-
-		val = x86_perf_event_update(event);
-		if (val & (1ULL << (x86_pmu.cntval_bits - 1)))
-			continue;
-
-		/*
-		 * event overflow
-		 */
-		handled++;
-		perf_sample_data_init(&data, 0, event->hw.last_period);
-
-		if (!x86_perf_event_set_period(event))
-			continue;
-
-		if (perf_event_overflow(event, &data, regs))
-			x86_pmu_stop(event, 0);
-	}
-
-	if (handled)
-		inc_irq_stat(apic_perf_irqs);
-
-	return handled;
-}
-
-void perf_events_lapic_init(void)
-{
-	if (!x86_pmu.apic || !x86_pmu_initialized())
-		return;
-
-	/*
-	 * Always use NMI for PMU
-	 */
-	apic_write(APIC_LVTPC, APIC_DM_NMI);
-}
-
-static int
-perf_event_nmi_handler(unsigned int cmd, struct pt_regs *regs)
-{
-	u64 start_clock;
-	u64 finish_clock;
-	int ret;
-
-	/*
-	 * All PMUs/events that share this PMI handler should make sure to
-	 * increment active_events for their events.
-	 */
-	if (!atomic_read(&active_events))
-		return NMI_DONE;
-
-	start_clock = sched_clock();
-	ret = x86_pmu.handle_irq(regs);
-	finish_clock = sched_clock();
-
-	perf_sample_event_took(finish_clock - start_clock);
-
-	return ret;
-}
-NOKPROBE_SYMBOL(perf_event_nmi_handler);
-
-struct event_constraint emptyconstraint;
-struct event_constraint unconstrained;
-
-static int
-x86_pmu_notifier(struct notifier_block *self, unsigned long action, void *hcpu)
-{
-	unsigned int cpu = (long)hcpu;
-	struct cpu_hw_events *cpuc = &per_cpu(cpu_hw_events, cpu);
-	int i, ret = NOTIFY_OK;
-
-	switch (action & ~CPU_TASKS_FROZEN) {
-	case CPU_UP_PREPARE:
-		for (i = 0 ; i < X86_PERF_KFREE_MAX; i++)
-			cpuc->kfree_on_online[i] = NULL;
-		if (x86_pmu.cpu_prepare)
-			ret = x86_pmu.cpu_prepare(cpu);
-		break;
-
-	case CPU_STARTING:
-		if (x86_pmu.cpu_starting)
-			x86_pmu.cpu_starting(cpu);
-		break;
-
-	case CPU_ONLINE:
-		for (i = 0 ; i < X86_PERF_KFREE_MAX; i++) {
-			kfree(cpuc->kfree_on_online[i]);
-			cpuc->kfree_on_online[i] = NULL;
-		}
-		break;
-
-	case CPU_DYING:
-		if (x86_pmu.cpu_dying)
-			x86_pmu.cpu_dying(cpu);
-		break;
-
-	case CPU_UP_CANCELED:
-	case CPU_DEAD:
-		if (x86_pmu.cpu_dead)
-			x86_pmu.cpu_dead(cpu);
-		break;
-
-	default:
-		break;
-	}
-
-	return ret;
-}
-
-static void __init pmu_check_apic(void)
-{
-	if (cpu_has_apic)
-		return;
-
-	x86_pmu.apic = 0;
-	pr_info("no APIC, boot with the \"lapic\" boot parameter to force-enable it.\n");
-	pr_info("no hardware sampling interrupt available.\n");
-
-	/*
-	 * If we have a PMU initialized but no APIC
-	 * interrupts, we cannot sample hardware
-	 * events (user-space has to fall back and
-	 * sample via a hrtimer based software event):
-	 */
-	pmu.capabilities |= PERF_PMU_CAP_NO_INTERRUPT;
-
-}
-
-static struct attribute_group x86_pmu_format_group = {
-	.name = "format",
-	.attrs = NULL,
-};
-
-/*
- * Remove all undefined events (x86_pmu.event_map(id) == 0)
- * out of events_attr attributes.
- */
-static void __init filter_events(struct attribute **attrs)
-{
-	struct device_attribute *d;
-	struct perf_pmu_events_attr *pmu_attr;
-	int i, j;
-
-	for (i = 0; attrs[i]; i++) {
-		d = (struct device_attribute *)attrs[i];
-		pmu_attr = container_of(d, struct perf_pmu_events_attr, attr);
-		/* str trumps id */
-		if (pmu_attr->event_str)
-			continue;
-		if (x86_pmu.event_map(i))
-			continue;
-
-		for (j = i; attrs[j]; j++)
-			attrs[j] = attrs[j + 1];
-
-		/* Check the shifted attr. */
-		i--;
-	}
-}
-
-/* Merge two pointer arrays */
-__init struct attribute **merge_attr(struct attribute **a, struct attribute **b)
-{
-	struct attribute **new;
-	int j, i;
-
-	for (j = 0; a[j]; j++)
-		;
-	for (i = 0; b[i]; i++)
-		j++;
-	j++;
-
-	new = kmalloc(sizeof(struct attribute *) * j, GFP_KERNEL);
-	if (!new)
-		return NULL;
-
-	j = 0;
-	for (i = 0; a[i]; i++)
-		new[j++] = a[i];
-	for (i = 0; b[i]; i++)
-		new[j++] = b[i];
-	new[j] = NULL;
-
-	return new;
-}
-
-ssize_t events_sysfs_show(struct device *dev, struct device_attribute *attr,
-			  char *page)
-{
-	struct perf_pmu_events_attr *pmu_attr = \
-		container_of(attr, struct perf_pmu_events_attr, attr);
-	u64 config = x86_pmu.event_map(pmu_attr->id);
-
-	/* string trumps id */
-	if (pmu_attr->event_str)
-		return sprintf(page, "%s", pmu_attr->event_str);
-
-	return x86_pmu.events_sysfs_show(page, config);
-}
-
-EVENT_ATTR(cpu-cycles,			CPU_CYCLES		);
-EVENT_ATTR(instructions,		INSTRUCTIONS		);
-EVENT_ATTR(cache-references,		CACHE_REFERENCES	);
-EVENT_ATTR(cache-misses, 		CACHE_MISSES		);
-EVENT_ATTR(branch-instructions,		BRANCH_INSTRUCTIONS	);
-EVENT_ATTR(branch-misses,		BRANCH_MISSES		);
-EVENT_ATTR(bus-cycles,			BUS_CYCLES		);
-EVENT_ATTR(stalled-cycles-frontend,	STALLED_CYCLES_FRONTEND	);
-EVENT_ATTR(stalled-cycles-backend,	STALLED_CYCLES_BACKEND	);
-EVENT_ATTR(ref-cycles,			REF_CPU_CYCLES		);
-
-static struct attribute *empty_attrs;
-
-static struct attribute *events_attr[] = {
-	EVENT_PTR(CPU_CYCLES),
-	EVENT_PTR(INSTRUCTIONS),
-	EVENT_PTR(CACHE_REFERENCES),
-	EVENT_PTR(CACHE_MISSES),
-	EVENT_PTR(BRANCH_INSTRUCTIONS),
-	EVENT_PTR(BRANCH_MISSES),
-	EVENT_PTR(BUS_CYCLES),
-	EVENT_PTR(STALLED_CYCLES_FRONTEND),
-	EVENT_PTR(STALLED_CYCLES_BACKEND),
-	EVENT_PTR(REF_CPU_CYCLES),
-	NULL,
-};
-
-static struct attribute_group x86_pmu_events_group = {
-	.name = "events",
-	.attrs = events_attr,
-};
-
-ssize_t x86_event_sysfs_show(char *page, u64 config, u64 event)
-{
-	u64 umask  = (config & ARCH_PERFMON_EVENTSEL_UMASK) >> 8;
-	u64 cmask  = (config & ARCH_PERFMON_EVENTSEL_CMASK) >> 24;
-	bool edge  = (config & ARCH_PERFMON_EVENTSEL_EDGE);
-	bool pc    = (config & ARCH_PERFMON_EVENTSEL_PIN_CONTROL);
-	bool any   = (config & ARCH_PERFMON_EVENTSEL_ANY);
-	bool inv   = (config & ARCH_PERFMON_EVENTSEL_INV);
-	ssize_t ret;
-
-	/*
-	* We have whole page size to spend and just little data
-	* to write, so we can safely use sprintf.
-	*/
-	ret = sprintf(page, "event=0x%02llx", event);
-
-	if (umask)
-		ret += sprintf(page + ret, ",umask=0x%02llx", umask);
-
-	if (edge)
-		ret += sprintf(page + ret, ",edge");
-
-	if (pc)
-		ret += sprintf(page + ret, ",pc");
-
-	if (any)
-		ret += sprintf(page + ret, ",any");
-
-	if (inv)
-		ret += sprintf(page + ret, ",inv");
-
-	if (cmask)
-		ret += sprintf(page + ret, ",cmask=0x%02llx", cmask);
-
-	ret += sprintf(page + ret, "\n");
-
-	return ret;
-}
-
-static int __init init_hw_perf_events(void)
-{
-	struct x86_pmu_quirk *quirk;
-	int err;
-
-	pr_info("Performance Events: ");
-
-	switch (boot_cpu_data.x86_vendor) {
-	case X86_VENDOR_INTEL:
-		err = intel_pmu_init();
-		break;
-	case X86_VENDOR_AMD:
-		err = amd_pmu_init();
-		break;
-	default:
-		err = -ENOTSUPP;
-	}
-	if (err != 0) {
-		pr_cont("no PMU driver, software events only.\n");
-		return 0;
-	}
-
-	pmu_check_apic();
-
-	/* sanity check that the hardware exists or is emulated */
-	if (!check_hw_exists())
-		return 0;
-
-	pr_cont("%s PMU driver.\n", x86_pmu.name);
-
-	x86_pmu.attr_rdpmc = 1; /* enable userspace RDPMC usage by default */
-
-	for (quirk = x86_pmu.quirks; quirk; quirk = quirk->next)
-		quirk->func();
-
-	if (!x86_pmu.intel_ctrl)
-		x86_pmu.intel_ctrl = (1 << x86_pmu.num_counters) - 1;
-
-	perf_events_lapic_init();
-	register_nmi_handler(NMI_LOCAL, perf_event_nmi_handler, 0, "PMI");
-
-	unconstrained = (struct event_constraint)
-		__EVENT_CONSTRAINT(0, (1ULL << x86_pmu.num_counters) - 1,
-				   0, x86_pmu.num_counters, 0, 0);
-
-	x86_pmu_format_group.attrs = x86_pmu.format_attrs;
-
-	if (x86_pmu.event_attrs)
-		x86_pmu_events_group.attrs = x86_pmu.event_attrs;
-
-	if (!x86_pmu.events_sysfs_show)
-		x86_pmu_events_group.attrs = &empty_attrs;
-	else
-		filter_events(x86_pmu_events_group.attrs);
-
-	if (x86_pmu.cpu_events) {
-		struct attribute **tmp;
-
-		tmp = merge_attr(x86_pmu_events_group.attrs, x86_pmu.cpu_events);
-		if (!WARN_ON(!tmp))
-			x86_pmu_events_group.attrs = tmp;
-	}
-
-	pr_info("... version:                %d\n",     x86_pmu.version);
-	pr_info("... bit width:              %d\n",     x86_pmu.cntval_bits);
-	pr_info("... generic registers:      %d\n",     x86_pmu.num_counters);
-	pr_info("... value mask:             %016Lx\n", x86_pmu.cntval_mask);
-	pr_info("... max period:             %016Lx\n", x86_pmu.max_period);
-	pr_info("... fixed-purpose events:   %d\n",     x86_pmu.num_counters_fixed);
-	pr_info("... event mask:             %016Lx\n", x86_pmu.intel_ctrl);
-
-	perf_pmu_register(&pmu, "cpu", PERF_TYPE_RAW);
-	perf_cpu_notifier(x86_pmu_notifier);
-
-	return 0;
-}
-early_initcall(init_hw_perf_events);
-
-static inline void x86_pmu_read(struct perf_event *event)
-{
-	x86_perf_event_update(event);
-}
-
-/*
- * Start group events scheduling transaction
- * Set the flag to make pmu::enable() not perform the
- * schedulability test, it will be performed at commit time
- *
- * We only support PERF_PMU_TXN_ADD transactions. Save the
- * transaction flags but otherwise ignore non-PERF_PMU_TXN_ADD
- * transactions.
- */
-static void x86_pmu_start_txn(struct pmu *pmu, unsigned int txn_flags)
-{
-	struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
-
-	WARN_ON_ONCE(cpuc->txn_flags);		/* txn already in flight */
-
-	cpuc->txn_flags = txn_flags;
-	if (txn_flags & ~PERF_PMU_TXN_ADD)
-		return;
-
-	perf_pmu_disable(pmu);
-	__this_cpu_write(cpu_hw_events.n_txn, 0);
-}
-
-/*
- * Stop group events scheduling transaction
- * Clear the flag and pmu::enable() will perform the
- * schedulability test.
- */
-static void x86_pmu_cancel_txn(struct pmu *pmu)
-{
-	unsigned int txn_flags;
-	struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
-
-	WARN_ON_ONCE(!cpuc->txn_flags);	/* no txn in flight */
-
-	txn_flags = cpuc->txn_flags;
-	cpuc->txn_flags = 0;
-	if (txn_flags & ~PERF_PMU_TXN_ADD)
-		return;
-
-	/*
-	 * Truncate collected array by the number of events added in this
-	 * transaction. See x86_pmu_add() and x86_pmu_*_txn().
-	 */
-	__this_cpu_sub(cpu_hw_events.n_added, __this_cpu_read(cpu_hw_events.n_txn));
-	__this_cpu_sub(cpu_hw_events.n_events, __this_cpu_read(cpu_hw_events.n_txn));
-	perf_pmu_enable(pmu);
-}
-
-/*
- * Commit group events scheduling transaction
- * Perform the group schedulability test as a whole
- * Return 0 if success
- *
- * Does not cancel the transaction on failure; expects the caller to do this.
- */
-static int x86_pmu_commit_txn(struct pmu *pmu)
-{
-	struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
-	int assign[X86_PMC_IDX_MAX];
-	int n, ret;
-
-	WARN_ON_ONCE(!cpuc->txn_flags);	/* no txn in flight */
-
-	if (cpuc->txn_flags & ~PERF_PMU_TXN_ADD) {
-		cpuc->txn_flags = 0;
-		return 0;
-	}
-
-	n = cpuc->n_events;
-
-	if (!x86_pmu_initialized())
-		return -EAGAIN;
-
-	ret = x86_pmu.schedule_events(cpuc, n, assign);
-	if (ret)
-		return ret;
-
-	/*
-	 * copy new assignment, now we know it is possible
-	 * will be used by hw_perf_enable()
-	 */
-	memcpy(cpuc->assign, assign, n*sizeof(int));
-
-	cpuc->txn_flags = 0;
-	perf_pmu_enable(pmu);
-	return 0;
-}
-/*
- * a fake_cpuc is used to validate event groups. Due to
- * the extra reg logic, we need to also allocate a fake
- * per_core and per_cpu structure. Otherwise, group events
- * using extra reg may conflict without the kernel being
- * able to catch this when the last event gets added to
- * the group.
- */
-static void free_fake_cpuc(struct cpu_hw_events *cpuc)
-{
-	kfree(cpuc->shared_regs);
-	kfree(cpuc);
-}
-
-static struct cpu_hw_events *allocate_fake_cpuc(void)
-{
-	struct cpu_hw_events *cpuc;
-	int cpu = raw_smp_processor_id();
-
-	cpuc = kzalloc(sizeof(*cpuc), GFP_KERNEL);
-	if (!cpuc)
-		return ERR_PTR(-ENOMEM);
-
-	/* only needed, if we have extra_regs */
-	if (x86_pmu.extra_regs) {
-		cpuc->shared_regs = allocate_shared_regs(cpu);
-		if (!cpuc->shared_regs)
-			goto error;
-	}
-	cpuc->is_fake = 1;
-	return cpuc;
-error:
-	free_fake_cpuc(cpuc);
-	return ERR_PTR(-ENOMEM);
-}
-
-/*
- * validate that we can schedule this event
- */
-static int validate_event(struct perf_event *event)
-{
-	struct cpu_hw_events *fake_cpuc;
-	struct event_constraint *c;
-	int ret = 0;
-
-	fake_cpuc = allocate_fake_cpuc();
-	if (IS_ERR(fake_cpuc))
-		return PTR_ERR(fake_cpuc);
-
-	c = x86_pmu.get_event_constraints(fake_cpuc, -1, event);
-
-	if (!c || !c->weight)
-		ret = -EINVAL;
-
-	if (x86_pmu.put_event_constraints)
-		x86_pmu.put_event_constraints(fake_cpuc, event);
-
-	free_fake_cpuc(fake_cpuc);
-
-	return ret;
-}
-
-/*
- * validate a single event group
- *
- * validation include:
- *	- check events are compatible which each other
- *	- events do not compete for the same counter
- *	- number of events <= number of counters
- *
- * validation ensures the group can be loaded onto the
- * PMU if it was the only group available.
- */
-static int validate_group(struct perf_event *event)
-{
-	struct perf_event *leader = event->group_leader;
-	struct cpu_hw_events *fake_cpuc;
-	int ret = -EINVAL, n;
-
-	fake_cpuc = allocate_fake_cpuc();
-	if (IS_ERR(fake_cpuc))
-		return PTR_ERR(fake_cpuc);
-	/*
-	 * the event is not yet connected with its
-	 * siblings therefore we must first collect
-	 * existing siblings, then add the new event
-	 * before we can simulate the scheduling
-	 */
-	n = collect_events(fake_cpuc, leader, true);
-	if (n < 0)
-		goto out;
-
-	fake_cpuc->n_events = n;
-	n = collect_events(fake_cpuc, event, false);
-	if (n < 0)
-		goto out;
-
-	fake_cpuc->n_events = n;
-
-	ret = x86_pmu.schedule_events(fake_cpuc, n, NULL);
-
-out:
-	free_fake_cpuc(fake_cpuc);
-	return ret;
-}
-
-static int x86_pmu_event_init(struct perf_event *event)
-{
-	struct pmu *tmp;
-	int err;
-
-	switch (event->attr.type) {
-	case PERF_TYPE_RAW:
-	case PERF_TYPE_HARDWARE:
-	case PERF_TYPE_HW_CACHE:
-		break;
-
-	default:
-		return -ENOENT;
-	}
-
-	err = __x86_pmu_event_init(event);
-	if (!err) {
-		/*
-		 * we temporarily connect event to its pmu
-		 * such that validate_group() can classify
-		 * it as an x86 event using is_x86_event()
-		 */
-		tmp = event->pmu;
-		event->pmu = &pmu;
-
-		if (event->group_leader != event)
-			err = validate_group(event);
-		else
-			err = validate_event(event);
-
-		event->pmu = tmp;
-	}
-	if (err) {
-		if (event->destroy)
-			event->destroy(event);
-	}
-
-	if (ACCESS_ONCE(x86_pmu.attr_rdpmc))
-		event->hw.flags |= PERF_X86_EVENT_RDPMC_ALLOWED;
-
-	return err;
-}
-
-static void refresh_pce(void *ignored)
-{
-	if (current->mm)
-		load_mm_cr4(current->mm);
-}
-
-static void x86_pmu_event_mapped(struct perf_event *event)
-{
-	if (!(event->hw.flags & PERF_X86_EVENT_RDPMC_ALLOWED))
-		return;
-
-	if (atomic_inc_return(&current->mm->context.perf_rdpmc_allowed) == 1)
-		on_each_cpu_mask(mm_cpumask(current->mm), refresh_pce, NULL, 1);
-}
-
-static void x86_pmu_event_unmapped(struct perf_event *event)
-{
-	if (!current->mm)
-		return;
-
-	if (!(event->hw.flags & PERF_X86_EVENT_RDPMC_ALLOWED))
-		return;
-
-	if (atomic_dec_and_test(&current->mm->context.perf_rdpmc_allowed))
-		on_each_cpu_mask(mm_cpumask(current->mm), refresh_pce, NULL, 1);
-}
-
-static int x86_pmu_event_idx(struct perf_event *event)
-{
-	int idx = event->hw.idx;
-
-	if (!(event->hw.flags & PERF_X86_EVENT_RDPMC_ALLOWED))
-		return 0;
-
-	if (x86_pmu.num_counters_fixed && idx >= INTEL_PMC_IDX_FIXED) {
-		idx -= INTEL_PMC_IDX_FIXED;
-		idx |= 1 << 30;
-	}
-
-	return idx + 1;
-}
-
-static ssize_t get_attr_rdpmc(struct device *cdev,
-			      struct device_attribute *attr,
-			      char *buf)
-{
-	return snprintf(buf, 40, "%d\n", x86_pmu.attr_rdpmc);
-}
-
-static ssize_t set_attr_rdpmc(struct device *cdev,
-			      struct device_attribute *attr,
-			      const char *buf, size_t count)
-{
-	unsigned long val;
-	ssize_t ret;
-
-	ret = kstrtoul(buf, 0, &val);
-	if (ret)
-		return ret;
-
-	if (val > 2)
-		return -EINVAL;
-
-	if (x86_pmu.attr_rdpmc_broken)
-		return -ENOTSUPP;
-
-	if ((val == 2) != (x86_pmu.attr_rdpmc == 2)) {
-		/*
-		 * Changing into or out of always available, aka
-		 * perf-event-bypassing mode.  This path is extremely slow,
-		 * but only root can trigger it, so it's okay.
-		 */
-		if (val == 2)
-			static_key_slow_inc(&rdpmc_always_available);
-		else
-			static_key_slow_dec(&rdpmc_always_available);
-		on_each_cpu(refresh_pce, NULL, 1);
-	}
-
-	x86_pmu.attr_rdpmc = val;
-
-	return count;
-}
-
-static DEVICE_ATTR(rdpmc, S_IRUSR | S_IWUSR, get_attr_rdpmc, set_attr_rdpmc);
-
-static struct attribute *x86_pmu_attrs[] = {
-	&dev_attr_rdpmc.attr,
-	NULL,
-};
-
-static struct attribute_group x86_pmu_attr_group = {
-	.attrs = x86_pmu_attrs,
-};
-
-static const struct attribute_group *x86_pmu_attr_groups[] = {
-	&x86_pmu_attr_group,
-	&x86_pmu_format_group,
-	&x86_pmu_events_group,
-	NULL,
-};
-
-static void x86_pmu_sched_task(struct perf_event_context *ctx, bool sched_in)
-{
-	if (x86_pmu.sched_task)
-		x86_pmu.sched_task(ctx, sched_in);
-}
-
-void perf_check_microcode(void)
-{
-	if (x86_pmu.check_microcode)
-		x86_pmu.check_microcode();
-}
-EXPORT_SYMBOL_GPL(perf_check_microcode);
-
-static struct pmu pmu = {
-	.pmu_enable		= x86_pmu_enable,
-	.pmu_disable		= x86_pmu_disable,
-
-	.attr_groups		= x86_pmu_attr_groups,
-
-	.event_init		= x86_pmu_event_init,
-
-	.event_mapped		= x86_pmu_event_mapped,
-	.event_unmapped		= x86_pmu_event_unmapped,
-
-	.add			= x86_pmu_add,
-	.del			= x86_pmu_del,
-	.start			= x86_pmu_start,
-	.stop			= x86_pmu_stop,
-	.read			= x86_pmu_read,
-
-	.start_txn		= x86_pmu_start_txn,
-	.cancel_txn		= x86_pmu_cancel_txn,
-	.commit_txn		= x86_pmu_commit_txn,
-
-	.event_idx		= x86_pmu_event_idx,
-	.sched_task		= x86_pmu_sched_task,
-	.task_ctx_size          = sizeof(struct x86_perf_task_context),
-};
-
-void arch_perf_update_userpage(struct perf_event *event,
-			       struct perf_event_mmap_page *userpg, u64 now)
-{
-	struct cyc2ns_data *data;
-
-	userpg->cap_user_time = 0;
-	userpg->cap_user_time_zero = 0;
-	userpg->cap_user_rdpmc =
-		!!(event->hw.flags & PERF_X86_EVENT_RDPMC_ALLOWED);
-	userpg->pmc_width = x86_pmu.cntval_bits;
-
-	if (!sched_clock_stable())
-		return;
-
-	data = cyc2ns_read_begin();
-
-	/*
-	 * Internal timekeeping for enabled/running/stopped times
-	 * is always in the local_clock domain.
-	 */
-	userpg->cap_user_time = 1;
-	userpg->time_mult = data->cyc2ns_mul;
-	userpg->time_shift = data->cyc2ns_shift;
-	userpg->time_offset = data->cyc2ns_offset - now;
-
-	/*
-	 * cap_user_time_zero doesn't make sense when we're using a different
-	 * time base for the records.
-	 */
-	if (event->clock == &local_clock) {
-		userpg->cap_user_time_zero = 1;
-		userpg->time_zero = data->cyc2ns_offset;
-	}
-
-	cyc2ns_read_end(data);
-}
-
-/*
- * callchain support
- */
-
-static int backtrace_stack(void *data, char *name)
-{
-	return 0;
-}
-
-static void backtrace_address(void *data, unsigned long addr, int reliable)
-{
-	struct perf_callchain_entry *entry = data;
-
-	perf_callchain_store(entry, addr);
-}
-
-static const struct stacktrace_ops backtrace_ops = {
-	.stack			= backtrace_stack,
-	.address		= backtrace_address,
-	.walk_stack		= print_context_stack_bp,
-};
-
-void
-perf_callchain_kernel(struct perf_callchain_entry *entry, struct pt_regs *regs)
-{
-	if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) {
-		/* TODO: We don't support guest os callchain now */
-		return;
-	}
-
-	perf_callchain_store(entry, regs->ip);
-
-	dump_trace(NULL, regs, NULL, 0, &backtrace_ops, entry);
-}
-
-static inline int
-valid_user_frame(const void __user *fp, unsigned long size)
-{
-	return (__range_not_ok(fp, size, TASK_SIZE) == 0);
-}
-
-static unsigned long get_segment_base(unsigned int segment)
-{
-	struct desc_struct *desc;
-	int idx = segment >> 3;
-
-	if ((segment & SEGMENT_TI_MASK) == SEGMENT_LDT) {
-#ifdef CONFIG_MODIFY_LDT_SYSCALL
-		struct ldt_struct *ldt;
-
-		if (idx > LDT_ENTRIES)
-			return 0;
-
-		/* IRQs are off, so this synchronizes with smp_store_release */
-		ldt = lockless_dereference(current->active_mm->context.ldt);
-		if (!ldt || idx > ldt->size)
-			return 0;
-
-		desc = &ldt->entries[idx];
-#else
-		return 0;
-#endif
-	} else {
-		if (idx > GDT_ENTRIES)
-			return 0;
-
-		desc = raw_cpu_ptr(gdt_page.gdt) + idx;
-	}
-
-	return get_desc_base(desc);
-}
-
-#ifdef CONFIG_IA32_EMULATION
-
-#include <asm/compat.h>
-
-static inline int
-perf_callchain_user32(struct pt_regs *regs, struct perf_callchain_entry *entry)
-{
-	/* 32-bit process in 64-bit kernel. */
-	unsigned long ss_base, cs_base;
-	struct stack_frame_ia32 frame;
-	const void __user *fp;
-
-	if (!test_thread_flag(TIF_IA32))
-		return 0;
-
-	cs_base = get_segment_base(regs->cs);
-	ss_base = get_segment_base(regs->ss);
-
-	fp = compat_ptr(ss_base + regs->bp);
-	while (entry->nr < PERF_MAX_STACK_DEPTH) {
-		unsigned long bytes;
-		frame.next_frame     = 0;
-		frame.return_address = 0;
-
-		bytes = copy_from_user_nmi(&frame, fp, sizeof(frame));
-		if (bytes != 0)
-			break;
-
-		if (!valid_user_frame(fp, sizeof(frame)))
-			break;
-
-		perf_callchain_store(entry, cs_base + frame.return_address);
-		fp = compat_ptr(ss_base + frame.next_frame);
-	}
-	return 1;
-}
-#else
-static inline int
-perf_callchain_user32(struct pt_regs *regs, struct perf_callchain_entry *entry)
-{
-    return 0;
-}
-#endif
-
-void
-perf_callchain_user(struct perf_callchain_entry *entry, struct pt_regs *regs)
-{
-	struct stack_frame frame;
-	const void __user *fp;
-
-	if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) {
-		/* TODO: We don't support guest os callchain now */
-		return;
-	}
-
-	/*
-	 * We don't know what to do with VM86 stacks.. ignore them for now.
-	 */
-	if (regs->flags & (X86_VM_MASK | PERF_EFLAGS_VM))
-		return;
-
-	fp = (void __user *)regs->bp;
-
-	perf_callchain_store(entry, regs->ip);
-
-	if (!current->mm)
-		return;
-
-	if (perf_callchain_user32(regs, entry))
-		return;
-
-	while (entry->nr < PERF_MAX_STACK_DEPTH) {
-		unsigned long bytes;
-		frame.next_frame	     = NULL;
-		frame.return_address = 0;
-
-		bytes = copy_from_user_nmi(&frame, fp, sizeof(frame));
-		if (bytes != 0)
-			break;
-
-		if (!valid_user_frame(fp, sizeof(frame)))
-			break;
-
-		perf_callchain_store(entry, frame.return_address);
-		fp = frame.next_frame;
-	}
-}
-
-/*
- * Deal with code segment offsets for the various execution modes:
- *
- *   VM86 - the good olde 16 bit days, where the linear address is
- *          20 bits and we use regs->ip + 0x10 * regs->cs.
- *
- *   IA32 - Where we need to look at GDT/LDT segment descriptor tables
- *          to figure out what the 32bit base address is.
- *
- *    X32 - has TIF_X32 set, but is running in x86_64
- *
- * X86_64 - CS,DS,SS,ES are all zero based.
- */
-static unsigned long code_segment_base(struct pt_regs *regs)
-{
-	/*
-	 * For IA32 we look at the GDT/LDT segment base to convert the
-	 * effective IP to a linear address.
-	 */
-
-#ifdef CONFIG_X86_32
-	/*
-	 * If we are in VM86 mode, add the segment offset to convert to a
-	 * linear address.
-	 */
-	if (regs->flags & X86_VM_MASK)
-		return 0x10 * regs->cs;
-
-	if (user_mode(regs) && regs->cs != __USER_CS)
-		return get_segment_base(regs->cs);
-#else
-	if (user_mode(regs) && !user_64bit_mode(regs) &&
-	    regs->cs != __USER32_CS)
-		return get_segment_base(regs->cs);
-#endif
-	return 0;
-}
-
-unsigned long perf_instruction_pointer(struct pt_regs *regs)
-{
-	if (perf_guest_cbs && perf_guest_cbs->is_in_guest())
-		return perf_guest_cbs->get_guest_ip();
-
-	return regs->ip + code_segment_base(regs);
-}
-
-unsigned long perf_misc_flags(struct pt_regs *regs)
-{
-	int misc = 0;
-
-	if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) {
-		if (perf_guest_cbs->is_user_mode())
-			misc |= PERF_RECORD_MISC_GUEST_USER;
-		else
-			misc |= PERF_RECORD_MISC_GUEST_KERNEL;
-	} else {
-		if (user_mode(regs))
-			misc |= PERF_RECORD_MISC_USER;
-		else
-			misc |= PERF_RECORD_MISC_KERNEL;
-	}
-
-	if (regs->flags & PERF_EFLAGS_EXACT)
-		misc |= PERF_RECORD_MISC_EXACT_IP;
-
-	return misc;
-}
-
-void perf_get_x86_pmu_capability(struct x86_pmu_capability *cap)
-{
-	cap->version		= x86_pmu.version;
-	cap->num_counters_gp	= x86_pmu.num_counters;
-	cap->num_counters_fixed	= x86_pmu.num_counters_fixed;
-	cap->bit_width_gp	= x86_pmu.cntval_bits;
-	cap->bit_width_fixed	= x86_pmu.cntval_bits;
-	cap->events_mask	= (unsigned int)x86_pmu.events_maskl;
-	cap->events_mask_len	= x86_pmu.events_mask_len;
-}
-EXPORT_SYMBOL_GPL(perf_get_x86_pmu_capability);
--- zfcpdump-kernel-4.4.orig/arch/x86/kernel/cpu/perf_event.h
+++ /dev/null
@@ -1,958 +0,0 @@
-/*
- * Performance events x86 architecture header
- *
- *  Copyright (C) 2008 Thomas Gleixner <tglx@linutronix.de>
- *  Copyright (C) 2008-2009 Red Hat, Inc., Ingo Molnar
- *  Copyright (C) 2009 Jaswinder Singh Rajput
- *  Copyright (C) 2009 Advanced Micro Devices, Inc., Robert Richter
- *  Copyright (C) 2008-2009 Red Hat, Inc., Peter Zijlstra
- *  Copyright (C) 2009 Intel Corporation, <markus.t.metzger@intel.com>
- *  Copyright (C) 2009 Google, Inc., Stephane Eranian
- *
- *  For licencing details see kernel-base/COPYING
- */
-
-#include <linux/perf_event.h>
-
-#if 0
-#undef wrmsrl
-#define wrmsrl(msr, val) 						\
-do {									\
-	unsigned int _msr = (msr);					\
-	u64 _val = (val);						\
-	trace_printk("wrmsrl(%x, %Lx)\n", (unsigned int)(_msr),		\
-			(unsigned long long)(_val));			\
-	native_write_msr((_msr), (u32)(_val), (u32)(_val >> 32));	\
-} while (0)
-#endif
-
-/*
- *          |   NHM/WSM    |      SNB     |
- * register -------------------------------
- *          |  HT  | no HT |  HT  | no HT |
- *-----------------------------------------
- * offcore  | core | core  | cpu  | core  |
- * lbr_sel  | core | core  | cpu  | core  |
- * ld_lat   | cpu  | core  | cpu  | core  |
- *-----------------------------------------
- *
- * Given that there is a small number of shared regs,
- * we can pre-allocate their slot in the per-cpu
- * per-core reg tables.
- */
-enum extra_reg_type {
-	EXTRA_REG_NONE  = -1,	/* not used */
-
-	EXTRA_REG_RSP_0 = 0,	/* offcore_response_0 */
-	EXTRA_REG_RSP_1 = 1,	/* offcore_response_1 */
-	EXTRA_REG_LBR   = 2,	/* lbr_select */
-	EXTRA_REG_LDLAT = 3,	/* ld_lat_threshold */
-	EXTRA_REG_FE    = 4,    /* fe_* */
-
-	EXTRA_REG_MAX		/* number of entries needed */
-};
-
-struct event_constraint {
-	union {
-		unsigned long	idxmsk[BITS_TO_LONGS(X86_PMC_IDX_MAX)];
-		u64		idxmsk64;
-	};
-	u64	code;
-	u64	cmask;
-	int	weight;
-	int	overlap;
-	int	flags;
-};
-/*
- * struct hw_perf_event.flags flags
- */
-#define PERF_X86_EVENT_PEBS_LDLAT	0x0001 /* ld+ldlat data address sampling */
-#define PERF_X86_EVENT_PEBS_ST		0x0002 /* st data address sampling */
-#define PERF_X86_EVENT_PEBS_ST_HSW	0x0004 /* haswell style datala, store */
-#define PERF_X86_EVENT_COMMITTED	0x0008 /* event passed commit_txn */
-#define PERF_X86_EVENT_PEBS_LD_HSW	0x0010 /* haswell style datala, load */
-#define PERF_X86_EVENT_PEBS_NA_HSW	0x0020 /* haswell style datala, unknown */
-#define PERF_X86_EVENT_EXCL		0x0040 /* HT exclusivity on counter */
-#define PERF_X86_EVENT_DYNAMIC		0x0080 /* dynamic alloc'd constraint */
-#define PERF_X86_EVENT_RDPMC_ALLOWED	0x0100 /* grant rdpmc permission */
-#define PERF_X86_EVENT_EXCL_ACCT	0x0200 /* accounted EXCL event */
-#define PERF_X86_EVENT_AUTO_RELOAD	0x0400 /* use PEBS auto-reload */
-#define PERF_X86_EVENT_FREERUNNING	0x0800 /* use freerunning PEBS */
-
-
-struct amd_nb {
-	int nb_id;  /* NorthBridge id */
-	int refcnt; /* reference count */
-	struct perf_event *owners[X86_PMC_IDX_MAX];
-	struct event_constraint event_constraints[X86_PMC_IDX_MAX];
-};
-
-/* The maximal number of PEBS events: */
-#define MAX_PEBS_EVENTS		8
-
-/*
- * Flags PEBS can handle without an PMI.
- *
- * TID can only be handled by flushing at context switch.
- *
- */
-#define PEBS_FREERUNNING_FLAGS \
-	(PERF_SAMPLE_IP | PERF_SAMPLE_TID | PERF_SAMPLE_ADDR | \
-	PERF_SAMPLE_ID | PERF_SAMPLE_CPU | PERF_SAMPLE_STREAM_ID | \
-	PERF_SAMPLE_DATA_SRC | PERF_SAMPLE_IDENTIFIER | \
-	PERF_SAMPLE_TRANSACTION)
-
-/*
- * A debug store configuration.
- *
- * We only support architectures that use 64bit fields.
- */
-struct debug_store {
-	u64	bts_buffer_base;
-	u64	bts_index;
-	u64	bts_absolute_maximum;
-	u64	bts_interrupt_threshold;
-	u64	pebs_buffer_base;
-	u64	pebs_index;
-	u64	pebs_absolute_maximum;
-	u64	pebs_interrupt_threshold;
-	u64	pebs_event_reset[MAX_PEBS_EVENTS];
-};
-
-/*
- * Per register state.
- */
-struct er_account {
-	raw_spinlock_t		lock;	/* per-core: protect structure */
-	u64                 config;	/* extra MSR config */
-	u64                 reg;	/* extra MSR number */
-	atomic_t            ref;	/* reference count */
-};
-
-/*
- * Per core/cpu state
- *
- * Used to coordinate shared registers between HT threads or
- * among events on a single PMU.
- */
-struct intel_shared_regs {
-	struct er_account       regs[EXTRA_REG_MAX];
-	int                     refcnt;		/* per-core: #HT threads */
-	unsigned                core_id;	/* per-core: core id */
-};
-
-enum intel_excl_state_type {
-	INTEL_EXCL_UNUSED    = 0, /* counter is unused */
-	INTEL_EXCL_SHARED    = 1, /* counter can be used by both threads */
-	INTEL_EXCL_EXCLUSIVE = 2, /* counter can be used by one thread only */
-};
-
-struct intel_excl_states {
-	enum intel_excl_state_type state[X86_PMC_IDX_MAX];
-	bool sched_started; /* true if scheduling has started */
-};
-
-struct intel_excl_cntrs {
-	raw_spinlock_t	lock;
-
-	struct intel_excl_states states[2];
-
-	union {
-		u16	has_exclusive[2];
-		u32	exclusive_present;
-	};
-
-	int		refcnt;		/* per-core: #HT threads */
-	unsigned	core_id;	/* per-core: core id */
-};
-
-#define MAX_LBR_ENTRIES		32
-
-enum {
-	X86_PERF_KFREE_SHARED = 0,
-	X86_PERF_KFREE_EXCL   = 1,
-	X86_PERF_KFREE_MAX
-};
-
-struct cpu_hw_events {
-	/*
-	 * Generic x86 PMC bits
-	 */
-	struct perf_event	*events[X86_PMC_IDX_MAX]; /* in counter order */
-	unsigned long		active_mask[BITS_TO_LONGS(X86_PMC_IDX_MAX)];
-	unsigned long		running[BITS_TO_LONGS(X86_PMC_IDX_MAX)];
-	int			enabled;
-
-	int			n_events; /* the # of events in the below arrays */
-	int			n_added;  /* the # last events in the below arrays;
-					     they've never been enabled yet */
-	int			n_txn;    /* the # last events in the below arrays;
-					     added in the current transaction */
-	int			assign[X86_PMC_IDX_MAX]; /* event to counter assignment */
-	u64			tags[X86_PMC_IDX_MAX];
-
-	struct perf_event	*event_list[X86_PMC_IDX_MAX]; /* in enabled order */
-	struct event_constraint	*event_constraint[X86_PMC_IDX_MAX];
-
-	int			n_excl; /* the number of exclusive events */
-
-	unsigned int		txn_flags;
-	int			is_fake;
-
-	/*
-	 * Intel DebugStore bits
-	 */
-	struct debug_store	*ds;
-	u64			pebs_enabled;
-
-	/*
-	 * Intel LBR bits
-	 */
-	int				lbr_users;
-	void				*lbr_context;
-	struct perf_branch_stack	lbr_stack;
-	struct perf_branch_entry	lbr_entries[MAX_LBR_ENTRIES];
-	struct er_account		*lbr_sel;
-	u64				br_sel;
-
-	/*
-	 * Intel host/guest exclude bits
-	 */
-	u64				intel_ctrl_guest_mask;
-	u64				intel_ctrl_host_mask;
-	struct perf_guest_switch_msr	guest_switch_msrs[X86_PMC_IDX_MAX];
-
-	/*
-	 * Intel checkpoint mask
-	 */
-	u64				intel_cp_status;
-
-	/*
-	 * manage shared (per-core, per-cpu) registers
-	 * used on Intel NHM/WSM/SNB
-	 */
-	struct intel_shared_regs	*shared_regs;
-	/*
-	 * manage exclusive counter access between hyperthread
-	 */
-	struct event_constraint *constraint_list; /* in enable order */
-	struct intel_excl_cntrs		*excl_cntrs;
-	int excl_thread_id; /* 0 or 1 */
-
-	/*
-	 * AMD specific bits
-	 */
-	struct amd_nb			*amd_nb;
-	/* Inverted mask of bits to clear in the perf_ctr ctrl registers */
-	u64				perf_ctr_virt_mask;
-
-	void				*kfree_on_online[X86_PERF_KFREE_MAX];
-};
-
-#define __EVENT_CONSTRAINT(c, n, m, w, o, f) {\
-	{ .idxmsk64 = (n) },		\
-	.code = (c),			\
-	.cmask = (m),			\
-	.weight = (w),			\
-	.overlap = (o),			\
-	.flags = f,			\
-}
-
-#define EVENT_CONSTRAINT(c, n, m)	\
-	__EVENT_CONSTRAINT(c, n, m, HWEIGHT(n), 0, 0)
-
-#define INTEL_EXCLEVT_CONSTRAINT(c, n)	\
-	__EVENT_CONSTRAINT(c, n, ARCH_PERFMON_EVENTSEL_EVENT, HWEIGHT(n),\
-			   0, PERF_X86_EVENT_EXCL)
-
-/*
- * The overlap flag marks event constraints with overlapping counter
- * masks. This is the case if the counter mask of such an event is not
- * a subset of any other counter mask of a constraint with an equal or
- * higher weight, e.g.:
- *
- *  c_overlaps = EVENT_CONSTRAINT_OVERLAP(0, 0x09, 0);
- *  c_another1 = EVENT_CONSTRAINT(0, 0x07, 0);
- *  c_another2 = EVENT_CONSTRAINT(0, 0x38, 0);
- *
- * The event scheduler may not select the correct counter in the first
- * cycle because it needs to know which subsequent events will be
- * scheduled. It may fail to schedule the events then. So we set the
- * overlap flag for such constraints to give the scheduler a hint which
- * events to select for counter rescheduling.
- *
- * Care must be taken as the rescheduling algorithm is O(n!) which
- * will increase scheduling cycles for an over-commited system
- * dramatically.  The number of such EVENT_CONSTRAINT_OVERLAP() macros
- * and its counter masks must be kept at a minimum.
- */
-#define EVENT_CONSTRAINT_OVERLAP(c, n, m)	\
-	__EVENT_CONSTRAINT(c, n, m, HWEIGHT(n), 1, 0)
-
-/*
- * Constraint on the Event code.
- */
-#define INTEL_EVENT_CONSTRAINT(c, n)	\
-	EVENT_CONSTRAINT(c, n, ARCH_PERFMON_EVENTSEL_EVENT)
-
-/*
- * Constraint on the Event code + UMask + fixed-mask
- *
- * filter mask to validate fixed counter events.
- * the following filters disqualify for fixed counters:
- *  - inv
- *  - edge
- *  - cnt-mask
- *  - in_tx
- *  - in_tx_checkpointed
- *  The other filters are supported by fixed counters.
- *  The any-thread option is supported starting with v3.
- */
-#define FIXED_EVENT_FLAGS (X86_RAW_EVENT_MASK|HSW_IN_TX|HSW_IN_TX_CHECKPOINTED)
-#define FIXED_EVENT_CONSTRAINT(c, n)	\
-	EVENT_CONSTRAINT(c, (1ULL << (32+n)), FIXED_EVENT_FLAGS)
-
-/*
- * Constraint on the Event code + UMask
- */
-#define INTEL_UEVENT_CONSTRAINT(c, n)	\
-	EVENT_CONSTRAINT(c, n, INTEL_ARCH_EVENT_MASK)
-
-/* Like UEVENT_CONSTRAINT, but match flags too */
-#define INTEL_FLAGS_UEVENT_CONSTRAINT(c, n)	\
-	EVENT_CONSTRAINT(c, n, INTEL_ARCH_EVENT_MASK|X86_ALL_EVENT_FLAGS)
-
-#define INTEL_EXCLUEVT_CONSTRAINT(c, n)	\
-	__EVENT_CONSTRAINT(c, n, INTEL_ARCH_EVENT_MASK, \
-			   HWEIGHT(n), 0, PERF_X86_EVENT_EXCL)
-
-#define INTEL_PLD_CONSTRAINT(c, n)	\
-	__EVENT_CONSTRAINT(c, n, INTEL_ARCH_EVENT_MASK|X86_ALL_EVENT_FLAGS, \
-			   HWEIGHT(n), 0, PERF_X86_EVENT_PEBS_LDLAT)
-
-#define INTEL_PST_CONSTRAINT(c, n)	\
-	__EVENT_CONSTRAINT(c, n, INTEL_ARCH_EVENT_MASK|X86_ALL_EVENT_FLAGS, \
-			  HWEIGHT(n), 0, PERF_X86_EVENT_PEBS_ST)
-
-/* Event constraint, but match on all event flags too. */
-#define INTEL_FLAGS_EVENT_CONSTRAINT(c, n) \
-	EVENT_CONSTRAINT(c, n, INTEL_ARCH_EVENT_MASK|X86_ALL_EVENT_FLAGS)
-
-/* Check only flags, but allow all event/umask */
-#define INTEL_ALL_EVENT_CONSTRAINT(code, n)	\
-	EVENT_CONSTRAINT(code, n, X86_ALL_EVENT_FLAGS)
-
-/* Check flags and event code, and set the HSW store flag */
-#define INTEL_FLAGS_EVENT_CONSTRAINT_DATALA_ST(code, n) \
-	__EVENT_CONSTRAINT(code, n, 			\
-			  ARCH_PERFMON_EVENTSEL_EVENT|X86_ALL_EVENT_FLAGS, \
-			  HWEIGHT(n), 0, PERF_X86_EVENT_PEBS_ST_HSW)
-
-/* Check flags and event code, and set the HSW load flag */
-#define INTEL_FLAGS_EVENT_CONSTRAINT_DATALA_LD(code, n) \
-	__EVENT_CONSTRAINT(code, n,			\
-			  ARCH_PERFMON_EVENTSEL_EVENT|X86_ALL_EVENT_FLAGS, \
-			  HWEIGHT(n), 0, PERF_X86_EVENT_PEBS_LD_HSW)
-
-#define INTEL_FLAGS_EVENT_CONSTRAINT_DATALA_XLD(code, n) \
-	__EVENT_CONSTRAINT(code, n,			\
-			  ARCH_PERFMON_EVENTSEL_EVENT|X86_ALL_EVENT_FLAGS, \
-			  HWEIGHT(n), 0, \
-			  PERF_X86_EVENT_PEBS_LD_HSW|PERF_X86_EVENT_EXCL)
-
-/* Check flags and event code/umask, and set the HSW store flag */
-#define INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_ST(code, n) \
-	__EVENT_CONSTRAINT(code, n, 			\
-			  INTEL_ARCH_EVENT_MASK|X86_ALL_EVENT_FLAGS, \
-			  HWEIGHT(n), 0, PERF_X86_EVENT_PEBS_ST_HSW)
-
-#define INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_XST(code, n) \
-	__EVENT_CONSTRAINT(code, n,			\
-			  INTEL_ARCH_EVENT_MASK|X86_ALL_EVENT_FLAGS, \
-			  HWEIGHT(n), 0, \
-			  PERF_X86_EVENT_PEBS_ST_HSW|PERF_X86_EVENT_EXCL)
-
-/* Check flags and event code/umask, and set the HSW load flag */
-#define INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_LD(code, n) \
-	__EVENT_CONSTRAINT(code, n, 			\
-			  INTEL_ARCH_EVENT_MASK|X86_ALL_EVENT_FLAGS, \
-			  HWEIGHT(n), 0, PERF_X86_EVENT_PEBS_LD_HSW)
-
-#define INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_XLD(code, n) \
-	__EVENT_CONSTRAINT(code, n,			\
-			  INTEL_ARCH_EVENT_MASK|X86_ALL_EVENT_FLAGS, \
-			  HWEIGHT(n), 0, \
-			  PERF_X86_EVENT_PEBS_LD_HSW|PERF_X86_EVENT_EXCL)
-
-/* Check flags and event code/umask, and set the HSW N/A flag */
-#define INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_NA(code, n) \
-	__EVENT_CONSTRAINT(code, n, 			\
-			  INTEL_ARCH_EVENT_MASK|X86_ALL_EVENT_FLAGS, \
-			  HWEIGHT(n), 0, PERF_X86_EVENT_PEBS_NA_HSW)
-
-
-/*
- * We define the end marker as having a weight of -1
- * to enable blacklisting of events using a counter bitmask
- * of zero and thus a weight of zero.
- * The end marker has a weight that cannot possibly be
- * obtained from counting the bits in the bitmask.
- */
-#define EVENT_CONSTRAINT_END { .weight = -1 }
-
-/*
- * Check for end marker with weight == -1
- */
-#define for_each_event_constraint(e, c)	\
-	for ((e) = (c); (e)->weight != -1; (e)++)
-
-/*
- * Extra registers for specific events.
- *
- * Some events need large masks and require external MSRs.
- * Those extra MSRs end up being shared for all events on
- * a PMU and sometimes between PMU of sibling HT threads.
- * In either case, the kernel needs to handle conflicting
- * accesses to those extra, shared, regs. The data structure
- * to manage those registers is stored in cpu_hw_event.
- */
-struct extra_reg {
-	unsigned int		event;
-	unsigned int		msr;
-	u64			config_mask;
-	u64			valid_mask;
-	int			idx;  /* per_xxx->regs[] reg index */
-	bool			extra_msr_access;
-};
-
-#define EVENT_EXTRA_REG(e, ms, m, vm, i) {	\
-	.event = (e),			\
-	.msr = (ms),			\
-	.config_mask = (m),		\
-	.valid_mask = (vm),		\
-	.idx = EXTRA_REG_##i,		\
-	.extra_msr_access = true,	\
-	}
-
-#define INTEL_EVENT_EXTRA_REG(event, msr, vm, idx)	\
-	EVENT_EXTRA_REG(event, msr, ARCH_PERFMON_EVENTSEL_EVENT, vm, idx)
-
-#define INTEL_UEVENT_EXTRA_REG(event, msr, vm, idx) \
-	EVENT_EXTRA_REG(event, msr, ARCH_PERFMON_EVENTSEL_EVENT | \
-			ARCH_PERFMON_EVENTSEL_UMASK, vm, idx)
-
-#define INTEL_UEVENT_PEBS_LDLAT_EXTRA_REG(c) \
-	INTEL_UEVENT_EXTRA_REG(c, \
-			       MSR_PEBS_LD_LAT_THRESHOLD, \
-			       0xffff, \
-			       LDLAT)
-
-#define EVENT_EXTRA_END EVENT_EXTRA_REG(0, 0, 0, 0, RSP_0)
-
-union perf_capabilities {
-	struct {
-		u64	lbr_format:6;
-		u64	pebs_trap:1;
-		u64	pebs_arch_reg:1;
-		u64	pebs_format:4;
-		u64	smm_freeze:1;
-		/*
-		 * PMU supports separate counter range for writing
-		 * values > 32bit.
-		 */
-		u64	full_width_write:1;
-	};
-	u64	capabilities;
-};
-
-struct x86_pmu_quirk {
-	struct x86_pmu_quirk *next;
-	void (*func)(void);
-};
-
-union x86_pmu_config {
-	struct {
-		u64 event:8,
-		    umask:8,
-		    usr:1,
-		    os:1,
-		    edge:1,
-		    pc:1,
-		    interrupt:1,
-		    __reserved1:1,
-		    en:1,
-		    inv:1,
-		    cmask:8,
-		    event2:4,
-		    __reserved2:4,
-		    go:1,
-		    ho:1;
-	} bits;
-	u64 value;
-};
-
-#define X86_CONFIG(args...) ((union x86_pmu_config){.bits = {args}}).value
-
-enum {
-	x86_lbr_exclusive_lbr,
-	x86_lbr_exclusive_bts,
-	x86_lbr_exclusive_pt,
-	x86_lbr_exclusive_max,
-};
-
-/*
- * struct x86_pmu - generic x86 pmu
- */
-struct x86_pmu {
-	/*
-	 * Generic x86 PMC bits
-	 */
-	const char	*name;
-	int		version;
-	int		(*handle_irq)(struct pt_regs *);
-	void		(*disable_all)(void);
-	void		(*enable_all)(int added);
-	void		(*enable)(struct perf_event *);
-	void		(*disable)(struct perf_event *);
-	int		(*hw_config)(struct perf_event *event);
-	int		(*schedule_events)(struct cpu_hw_events *cpuc, int n, int *assign);
-	unsigned	eventsel;
-	unsigned	perfctr;
-	int		(*addr_offset)(int index, bool eventsel);
-	int		(*rdpmc_index)(int index);
-	u64		(*event_map)(int);
-	int		max_events;
-	int		num_counters;
-	int		num_counters_fixed;
-	int		cntval_bits;
-	u64		cntval_mask;
-	union {
-			unsigned long events_maskl;
-			unsigned long events_mask[BITS_TO_LONGS(ARCH_PERFMON_EVENTS_COUNT)];
-	};
-	int		events_mask_len;
-	int		apic;
-	u64		max_period;
-	struct event_constraint *
-			(*get_event_constraints)(struct cpu_hw_events *cpuc,
-						 int idx,
-						 struct perf_event *event);
-
-	void		(*put_event_constraints)(struct cpu_hw_events *cpuc,
-						 struct perf_event *event);
-
-	void		(*start_scheduling)(struct cpu_hw_events *cpuc);
-
-	void		(*commit_scheduling)(struct cpu_hw_events *cpuc, int idx, int cntr);
-
-	void		(*stop_scheduling)(struct cpu_hw_events *cpuc);
-
-	struct event_constraint *event_constraints;
-	struct x86_pmu_quirk *quirks;
-	int		perfctr_second_write;
-	bool		late_ack;
-	unsigned	(*limit_period)(struct perf_event *event, unsigned l);
-
-	/*
-	 * sysfs attrs
-	 */
-	int		attr_rdpmc_broken;
-	int		attr_rdpmc;
-	struct attribute **format_attrs;
-	struct attribute **event_attrs;
-
-	ssize_t		(*events_sysfs_show)(char *page, u64 config);
-	struct attribute **cpu_events;
-
-	/*
-	 * CPU Hotplug hooks
-	 */
-	int		(*cpu_prepare)(int cpu);
-	void		(*cpu_starting)(int cpu);
-	void		(*cpu_dying)(int cpu);
-	void		(*cpu_dead)(int cpu);
-
-	void		(*check_microcode)(void);
-	void		(*sched_task)(struct perf_event_context *ctx,
-				      bool sched_in);
-
-	/*
-	 * Intel Arch Perfmon v2+
-	 */
-	u64			intel_ctrl;
-	union perf_capabilities intel_cap;
-
-	/*
-	 * Intel DebugStore bits
-	 */
-	unsigned int	bts		:1,
-			bts_active	:1,
-			pebs		:1,
-			pebs_active	:1,
-			pebs_broken	:1;
-	int		pebs_record_size;
-	void		(*drain_pebs)(struct pt_regs *regs);
-	struct event_constraint *pebs_constraints;
-	void		(*pebs_aliases)(struct perf_event *event);
-	int 		max_pebs_events;
-	unsigned long	free_running_flags;
-
-	/*
-	 * Intel LBR
-	 */
-	unsigned long	lbr_tos, lbr_from, lbr_to; /* MSR base regs       */
-	int		lbr_nr;			   /* hardware stack size */
-	u64		lbr_sel_mask;		   /* LBR_SELECT valid bits */
-	const int	*lbr_sel_map;		   /* lbr_select mappings */
-	bool		lbr_double_abort;	   /* duplicated lbr aborts */
-
-	/*
-	 * Intel PT/LBR/BTS are exclusive
-	 */
-	atomic_t	lbr_exclusive[x86_lbr_exclusive_max];
-
-	/*
-	 * Extra registers for events
-	 */
-	struct extra_reg *extra_regs;
-	unsigned int flags;
-
-	/*
-	 * Intel host/guest support (KVM)
-	 */
-	struct perf_guest_switch_msr *(*guest_get_msrs)(int *nr);
-};
-
-struct x86_perf_task_context {
-	u64 lbr_from[MAX_LBR_ENTRIES];
-	u64 lbr_to[MAX_LBR_ENTRIES];
-	u64 lbr_info[MAX_LBR_ENTRIES];
-	int tos;
-	int lbr_callstack_users;
-	int lbr_stack_state;
-};
-
-#define x86_add_quirk(func_)						\
-do {									\
-	static struct x86_pmu_quirk __quirk __initdata = {		\
-		.func = func_,						\
-	};								\
-	__quirk.next = x86_pmu.quirks;					\
-	x86_pmu.quirks = &__quirk;					\
-} while (0)
-
-/*
- * x86_pmu flags
- */
-#define PMU_FL_NO_HT_SHARING	0x1 /* no hyper-threading resource sharing */
-#define PMU_FL_HAS_RSP_1	0x2 /* has 2 equivalent offcore_rsp regs   */
-#define PMU_FL_EXCL_CNTRS	0x4 /* has exclusive counter requirements  */
-#define PMU_FL_EXCL_ENABLED	0x8 /* exclusive counter active */
-
-#define EVENT_VAR(_id)  event_attr_##_id
-#define EVENT_PTR(_id) &event_attr_##_id.attr.attr
-
-#define EVENT_ATTR(_name, _id)						\
-static struct perf_pmu_events_attr EVENT_VAR(_id) = {			\
-	.attr		= __ATTR(_name, 0444, events_sysfs_show, NULL),	\
-	.id		= PERF_COUNT_HW_##_id,				\
-	.event_str	= NULL,						\
-};
-
-#define EVENT_ATTR_STR(_name, v, str)					\
-static struct perf_pmu_events_attr event_attr_##v = {			\
-	.attr		= __ATTR(_name, 0444, events_sysfs_show, NULL),	\
-	.id		= 0,						\
-	.event_str	= str,						\
-};
-
-extern struct x86_pmu x86_pmu __read_mostly;
-
-static inline bool x86_pmu_has_lbr_callstack(void)
-{
-	return  x86_pmu.lbr_sel_map &&
-		x86_pmu.lbr_sel_map[PERF_SAMPLE_BRANCH_CALL_STACK_SHIFT] > 0;
-}
-
-DECLARE_PER_CPU(struct cpu_hw_events, cpu_hw_events);
-
-int x86_perf_event_set_period(struct perf_event *event);
-
-/*
- * Generalized hw caching related hw_event table, filled
- * in on a per model basis. A value of 0 means
- * 'not supported', -1 means 'hw_event makes no sense on
- * this CPU', any other value means the raw hw_event
- * ID.
- */
-
-#define C(x) PERF_COUNT_HW_CACHE_##x
-
-extern u64 __read_mostly hw_cache_event_ids
-				[PERF_COUNT_HW_CACHE_MAX]
-				[PERF_COUNT_HW_CACHE_OP_MAX]
-				[PERF_COUNT_HW_CACHE_RESULT_MAX];
-extern u64 __read_mostly hw_cache_extra_regs
-				[PERF_COUNT_HW_CACHE_MAX]
-				[PERF_COUNT_HW_CACHE_OP_MAX]
-				[PERF_COUNT_HW_CACHE_RESULT_MAX];
-
-u64 x86_perf_event_update(struct perf_event *event);
-
-static inline unsigned int x86_pmu_config_addr(int index)
-{
-	return x86_pmu.eventsel + (x86_pmu.addr_offset ?
-				   x86_pmu.addr_offset(index, true) : index);
-}
-
-static inline unsigned int x86_pmu_event_addr(int index)
-{
-	return x86_pmu.perfctr + (x86_pmu.addr_offset ?
-				  x86_pmu.addr_offset(index, false) : index);
-}
-
-static inline int x86_pmu_rdpmc_index(int index)
-{
-	return x86_pmu.rdpmc_index ? x86_pmu.rdpmc_index(index) : index;
-}
-
-int x86_add_exclusive(unsigned int what);
-
-void x86_del_exclusive(unsigned int what);
-
-int x86_reserve_hardware(void);
-
-void x86_release_hardware(void);
-
-void hw_perf_lbr_event_destroy(struct perf_event *event);
-
-int x86_setup_perfctr(struct perf_event *event);
-
-int x86_pmu_hw_config(struct perf_event *event);
-
-void x86_pmu_disable_all(void);
-
-static inline void __x86_pmu_enable_event(struct hw_perf_event *hwc,
-					  u64 enable_mask)
-{
-	u64 disable_mask = __this_cpu_read(cpu_hw_events.perf_ctr_virt_mask);
-
-	if (hwc->extra_reg.reg)
-		wrmsrl(hwc->extra_reg.reg, hwc->extra_reg.config);
-	wrmsrl(hwc->config_base, (hwc->config | enable_mask) & ~disable_mask);
-}
-
-void x86_pmu_enable_all(int added);
-
-int perf_assign_events(struct event_constraint **constraints, int n,
-			int wmin, int wmax, int gpmax, int *assign);
-int x86_schedule_events(struct cpu_hw_events *cpuc, int n, int *assign);
-
-void x86_pmu_stop(struct perf_event *event, int flags);
-
-static inline void x86_pmu_disable_event(struct perf_event *event)
-{
-	struct hw_perf_event *hwc = &event->hw;
-
-	wrmsrl(hwc->config_base, hwc->config);
-}
-
-void x86_pmu_enable_event(struct perf_event *event);
-
-int x86_pmu_handle_irq(struct pt_regs *regs);
-
-extern struct event_constraint emptyconstraint;
-
-extern struct event_constraint unconstrained;
-
-static inline bool kernel_ip(unsigned long ip)
-{
-#ifdef CONFIG_X86_32
-	return ip > PAGE_OFFSET;
-#else
-	return (long)ip < 0;
-#endif
-}
-
-/*
- * Not all PMUs provide the right context information to place the reported IP
- * into full context. Specifically segment registers are typically not
- * supplied.
- *
- * Assuming the address is a linear address (it is for IBS), we fake the CS and
- * vm86 mode using the known zero-based code segment and 'fix up' the registers
- * to reflect this.
- *
- * Intel PEBS/LBR appear to typically provide the effective address, nothing
- * much we can do about that but pray and treat it like a linear address.
- */
-static inline void set_linear_ip(struct pt_regs *regs, unsigned long ip)
-{
-	regs->cs = kernel_ip(ip) ? __KERNEL_CS : __USER_CS;
-	if (regs->flags & X86_VM_MASK)
-		regs->flags ^= (PERF_EFLAGS_VM | X86_VM_MASK);
-	regs->ip = ip;
-}
-
-ssize_t x86_event_sysfs_show(char *page, u64 config, u64 event);
-ssize_t intel_event_sysfs_show(char *page, u64 config);
-
-struct attribute **merge_attr(struct attribute **a, struct attribute **b);
-
-#ifdef CONFIG_CPU_SUP_AMD
-
-int amd_pmu_init(void);
-
-#else /* CONFIG_CPU_SUP_AMD */
-
-static inline int amd_pmu_init(void)
-{
-	return 0;
-}
-
-#endif /* CONFIG_CPU_SUP_AMD */
-
-#ifdef CONFIG_CPU_SUP_INTEL
-
-static inline bool intel_pmu_has_bts(struct perf_event *event)
-{
-	if (event->attr.config == PERF_COUNT_HW_BRANCH_INSTRUCTIONS &&
-	    !event->attr.freq && event->hw.sample_period == 1)
-		return true;
-
-	return false;
-}
-
-int intel_pmu_save_and_restart(struct perf_event *event);
-
-struct event_constraint *
-x86_get_event_constraints(struct cpu_hw_events *cpuc, int idx,
-			  struct perf_event *event);
-
-struct intel_shared_regs *allocate_shared_regs(int cpu);
-
-int intel_pmu_init(void);
-
-void init_debug_store_on_cpu(int cpu);
-
-void fini_debug_store_on_cpu(int cpu);
-
-void release_ds_buffers(void);
-
-void reserve_ds_buffers(void);
-
-extern struct event_constraint bts_constraint;
-
-void intel_pmu_enable_bts(u64 config);
-
-void intel_pmu_disable_bts(void);
-
-int intel_pmu_drain_bts_buffer(void);
-
-extern struct event_constraint intel_core2_pebs_event_constraints[];
-
-extern struct event_constraint intel_atom_pebs_event_constraints[];
-
-extern struct event_constraint intel_slm_pebs_event_constraints[];
-
-extern struct event_constraint intel_nehalem_pebs_event_constraints[];
-
-extern struct event_constraint intel_westmere_pebs_event_constraints[];
-
-extern struct event_constraint intel_snb_pebs_event_constraints[];
-
-extern struct event_constraint intel_ivb_pebs_event_constraints[];
-
-extern struct event_constraint intel_hsw_pebs_event_constraints[];
-
-extern struct event_constraint intel_skl_pebs_event_constraints[];
-
-struct event_constraint *intel_pebs_constraints(struct perf_event *event);
-
-void intel_pmu_pebs_enable(struct perf_event *event);
-
-void intel_pmu_pebs_disable(struct perf_event *event);
-
-void intel_pmu_pebs_enable_all(void);
-
-void intel_pmu_pebs_disable_all(void);
-
-void intel_pmu_pebs_sched_task(struct perf_event_context *ctx, bool sched_in);
-
-void intel_ds_init(void);
-
-void intel_pmu_lbr_sched_task(struct perf_event_context *ctx, bool sched_in);
-
-void intel_pmu_lbr_reset(void);
-
-void intel_pmu_lbr_enable(struct perf_event *event);
-
-void intel_pmu_lbr_disable(struct perf_event *event);
-
-void intel_pmu_lbr_enable_all(bool pmi);
-
-void intel_pmu_lbr_disable_all(void);
-
-void intel_pmu_lbr_read(void);
-
-void intel_pmu_lbr_init_core(void);
-
-void intel_pmu_lbr_init_nhm(void);
-
-void intel_pmu_lbr_init_atom(void);
-
-void intel_pmu_lbr_init_snb(void);
-
-void intel_pmu_lbr_init_hsw(void);
-
-void intel_pmu_lbr_init_skl(void);
-
-int intel_pmu_setup_lbr_filter(struct perf_event *event);
-
-void intel_pt_interrupt(void);
-
-int intel_bts_interrupt(void);
-
-void intel_bts_enable_local(void);
-
-void intel_bts_disable_local(void);
-
-int p4_pmu_init(void);
-
-int p6_pmu_init(void);
-
-int knc_pmu_init(void);
-
-ssize_t events_sysfs_show(struct device *dev, struct device_attribute *attr,
-			  char *page);
-
-static inline int is_ht_workaround_enabled(void)
-{
-	return !!(x86_pmu.flags & PMU_FL_EXCL_ENABLED);
-}
-
-#else /* CONFIG_CPU_SUP_INTEL */
-
-static inline void reserve_ds_buffers(void)
-{
-}
-
-static inline void release_ds_buffers(void)
-{
-}
-
-static inline int intel_pmu_init(void)
-{
-	return 0;
-}
-
-static inline struct intel_shared_regs *allocate_shared_regs(int cpu)
-{
-	return NULL;
-}
-
-static inline int is_ht_workaround_enabled(void)
-{
-	return 0;
-}
-#endif /* CONFIG_CPU_SUP_INTEL */
--- zfcpdump-kernel-4.4.orig/arch/x86/kernel/cpu/perf_event_amd.c
+++ /dev/null
@@ -1,731 +0,0 @@
-#include <linux/perf_event.h>
-#include <linux/export.h>
-#include <linux/types.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <asm/apicdef.h>
-
-#include "perf_event.h"
-
-static __initconst const u64 amd_hw_cache_event_ids
-				[PERF_COUNT_HW_CACHE_MAX]
-				[PERF_COUNT_HW_CACHE_OP_MAX]
-				[PERF_COUNT_HW_CACHE_RESULT_MAX] =
-{
- [ C(L1D) ] = {
-	[ C(OP_READ) ] = {
-		[ C(RESULT_ACCESS) ] = 0x0040, /* Data Cache Accesses        */
-		[ C(RESULT_MISS)   ] = 0x0141, /* Data Cache Misses          */
-	},
-	[ C(OP_WRITE) ] = {
-		[ C(RESULT_ACCESS) ] = 0x0142, /* Data Cache Refills :system */
-		[ C(RESULT_MISS)   ] = 0,
-	},
-	[ C(OP_PREFETCH) ] = {
-		[ C(RESULT_ACCESS) ] = 0x0267, /* Data Prefetcher :attempts  */
-		[ C(RESULT_MISS)   ] = 0x0167, /* Data Prefetcher :cancelled */
-	},
- },
- [ C(L1I ) ] = {
-	[ C(OP_READ) ] = {
-		[ C(RESULT_ACCESS) ] = 0x0080, /* Instruction cache fetches  */
-		[ C(RESULT_MISS)   ] = 0x0081, /* Instruction cache misses   */
-	},
-	[ C(OP_WRITE) ] = {
-		[ C(RESULT_ACCESS) ] = -1,
-		[ C(RESULT_MISS)   ] = -1,
-	},
-	[ C(OP_PREFETCH) ] = {
-		[ C(RESULT_ACCESS) ] = 0x014B, /* Prefetch Instructions :Load */
-		[ C(RESULT_MISS)   ] = 0,
-	},
- },
- [ C(LL  ) ] = {
-	[ C(OP_READ) ] = {
-		[ C(RESULT_ACCESS) ] = 0x037D, /* Requests to L2 Cache :IC+DC */
-		[ C(RESULT_MISS)   ] = 0x037E, /* L2 Cache Misses : IC+DC     */
-	},
-	[ C(OP_WRITE) ] = {
-		[ C(RESULT_ACCESS) ] = 0x017F, /* L2 Fill/Writeback           */
-		[ C(RESULT_MISS)   ] = 0,
-	},
-	[ C(OP_PREFETCH) ] = {
-		[ C(RESULT_ACCESS) ] = 0,
-		[ C(RESULT_MISS)   ] = 0,
-	},
- },
- [ C(DTLB) ] = {
-	[ C(OP_READ) ] = {
-		[ C(RESULT_ACCESS) ] = 0x0040, /* Data Cache Accesses        */
-		[ C(RESULT_MISS)   ] = 0x0746, /* L1_DTLB_AND_L2_DLTB_MISS.ALL */
-	},
-	[ C(OP_WRITE) ] = {
-		[ C(RESULT_ACCESS) ] = 0,
-		[ C(RESULT_MISS)   ] = 0,
-	},
-	[ C(OP_PREFETCH) ] = {
-		[ C(RESULT_ACCESS) ] = 0,
-		[ C(RESULT_MISS)   ] = 0,
-	},
- },
- [ C(ITLB) ] = {
-	[ C(OP_READ) ] = {
-		[ C(RESULT_ACCESS) ] = 0x0080, /* Instruction fecthes        */
-		[ C(RESULT_MISS)   ] = 0x0385, /* L1_ITLB_AND_L2_ITLB_MISS.ALL */
-	},
-	[ C(OP_WRITE) ] = {
-		[ C(RESULT_ACCESS) ] = -1,
-		[ C(RESULT_MISS)   ] = -1,
-	},
-	[ C(OP_PREFETCH) ] = {
-		[ C(RESULT_ACCESS) ] = -1,
-		[ C(RESULT_MISS)   ] = -1,
-	},
- },
- [ C(BPU ) ] = {
-	[ C(OP_READ) ] = {
-		[ C(RESULT_ACCESS) ] = 0x00c2, /* Retired Branch Instr.      */
-		[ C(RESULT_MISS)   ] = 0x00c3, /* Retired Mispredicted BI    */
-	},
-	[ C(OP_WRITE) ] = {
-		[ C(RESULT_ACCESS) ] = -1,
-		[ C(RESULT_MISS)   ] = -1,
-	},
-	[ C(OP_PREFETCH) ] = {
-		[ C(RESULT_ACCESS) ] = -1,
-		[ C(RESULT_MISS)   ] = -1,
-	},
- },
- [ C(NODE) ] = {
-	[ C(OP_READ) ] = {
-		[ C(RESULT_ACCESS) ] = 0xb8e9, /* CPU Request to Memory, l+r */
-		[ C(RESULT_MISS)   ] = 0x98e9, /* CPU Request to Memory, r   */
-	},
-	[ C(OP_WRITE) ] = {
-		[ C(RESULT_ACCESS) ] = -1,
-		[ C(RESULT_MISS)   ] = -1,
-	},
-	[ C(OP_PREFETCH) ] = {
-		[ C(RESULT_ACCESS) ] = -1,
-		[ C(RESULT_MISS)   ] = -1,
-	},
- },
-};
-
-/*
- * AMD Performance Monitor K7 and later.
- */
-static const u64 amd_perfmon_event_map[] =
-{
-  [PERF_COUNT_HW_CPU_CYCLES]			= 0x0076,
-  [PERF_COUNT_HW_INSTRUCTIONS]			= 0x00c0,
-  [PERF_COUNT_HW_CACHE_REFERENCES]		= 0x0080,
-  [PERF_COUNT_HW_CACHE_MISSES]			= 0x0081,
-  [PERF_COUNT_HW_BRANCH_INSTRUCTIONS]		= 0x00c2,
-  [PERF_COUNT_HW_BRANCH_MISSES]			= 0x00c3,
-  [PERF_COUNT_HW_STALLED_CYCLES_FRONTEND]	= 0x00d0, /* "Decoder empty" event */
-  [PERF_COUNT_HW_STALLED_CYCLES_BACKEND]	= 0x00d1, /* "Dispatch stalls" event */
-};
-
-static u64 amd_pmu_event_map(int hw_event)
-{
-	return amd_perfmon_event_map[hw_event];
-}
-
-/*
- * Previously calculated offsets
- */
-static unsigned int event_offsets[X86_PMC_IDX_MAX] __read_mostly;
-static unsigned int count_offsets[X86_PMC_IDX_MAX] __read_mostly;
-
-/*
- * Legacy CPUs:
- *   4 counters starting at 0xc0010000 each offset by 1
- *
- * CPUs with core performance counter extensions:
- *   6 counters starting at 0xc0010200 each offset by 2
- */
-static inline int amd_pmu_addr_offset(int index, bool eventsel)
-{
-	int offset;
-
-	if (!index)
-		return index;
-
-	if (eventsel)
-		offset = event_offsets[index];
-	else
-		offset = count_offsets[index];
-
-	if (offset)
-		return offset;
-
-	if (!cpu_has_perfctr_core)
-		offset = index;
-	else
-		offset = index << 1;
-
-	if (eventsel)
-		event_offsets[index] = offset;
-	else
-		count_offsets[index] = offset;
-
-	return offset;
-}
-
-static int amd_core_hw_config(struct perf_event *event)
-{
-	if (event->attr.exclude_host && event->attr.exclude_guest)
-		/*
-		 * When HO == GO == 1 the hardware treats that as GO == HO == 0
-		 * and will count in both modes. We don't want to count in that
-		 * case so we emulate no-counting by setting US = OS = 0.
-		 */
-		event->hw.config &= ~(ARCH_PERFMON_EVENTSEL_USR |
-				      ARCH_PERFMON_EVENTSEL_OS);
-	else if (event->attr.exclude_host)
-		event->hw.config |= AMD64_EVENTSEL_GUESTONLY;
-	else if (event->attr.exclude_guest)
-		event->hw.config |= AMD64_EVENTSEL_HOSTONLY;
-
-	return 0;
-}
-
-/*
- * AMD64 events are detected based on their event codes.
- */
-static inline unsigned int amd_get_event_code(struct hw_perf_event *hwc)
-{
-	return ((hwc->config >> 24) & 0x0f00) | (hwc->config & 0x00ff);
-}
-
-static inline int amd_is_nb_event(struct hw_perf_event *hwc)
-{
-	return (hwc->config & 0xe0) == 0xe0;
-}
-
-static inline int amd_has_nb(struct cpu_hw_events *cpuc)
-{
-	struct amd_nb *nb = cpuc->amd_nb;
-
-	return nb && nb->nb_id != -1;
-}
-
-static int amd_pmu_hw_config(struct perf_event *event)
-{
-	int ret;
-
-	/* pass precise event sampling to ibs: */
-	if (event->attr.precise_ip && get_ibs_caps())
-		return -ENOENT;
-
-	if (has_branch_stack(event))
-		return -EOPNOTSUPP;
-
-	ret = x86_pmu_hw_config(event);
-	if (ret)
-		return ret;
-
-	if (event->attr.type == PERF_TYPE_RAW)
-		event->hw.config |= event->attr.config & AMD64_RAW_EVENT_MASK;
-
-	return amd_core_hw_config(event);
-}
-
-static void __amd_put_nb_event_constraints(struct cpu_hw_events *cpuc,
-					   struct perf_event *event)
-{
-	struct amd_nb *nb = cpuc->amd_nb;
-	int i;
-
-	/*
-	 * need to scan whole list because event may not have
-	 * been assigned during scheduling
-	 *
-	 * no race condition possible because event can only
-	 * be removed on one CPU at a time AND PMU is disabled
-	 * when we come here
-	 */
-	for (i = 0; i < x86_pmu.num_counters; i++) {
-		if (cmpxchg(nb->owners + i, event, NULL) == event)
-			break;
-	}
-}
-
- /*
-  * AMD64 NorthBridge events need special treatment because
-  * counter access needs to be synchronized across all cores
-  * of a package. Refer to BKDG section 3.12
-  *
-  * NB events are events measuring L3 cache, Hypertransport
-  * traffic. They are identified by an event code >= 0xe00.
-  * They measure events on the NorthBride which is shared
-  * by all cores on a package. NB events are counted on a
-  * shared set of counters. When a NB event is programmed
-  * in a counter, the data actually comes from a shared
-  * counter. Thus, access to those counters needs to be
-  * synchronized.
-  *
-  * We implement the synchronization such that no two cores
-  * can be measuring NB events using the same counters. Thus,
-  * we maintain a per-NB allocation table. The available slot
-  * is propagated using the event_constraint structure.
-  *
-  * We provide only one choice for each NB event based on
-  * the fact that only NB events have restrictions. Consequently,
-  * if a counter is available, there is a guarantee the NB event
-  * will be assigned to it. If no slot is available, an empty
-  * constraint is returned and scheduling will eventually fail
-  * for this event.
-  *
-  * Note that all cores attached the same NB compete for the same
-  * counters to host NB events, this is why we use atomic ops. Some
-  * multi-chip CPUs may have more than one NB.
-  *
-  * Given that resources are allocated (cmpxchg), they must be
-  * eventually freed for others to use. This is accomplished by
-  * calling __amd_put_nb_event_constraints()
-  *
-  * Non NB events are not impacted by this restriction.
-  */
-static struct event_constraint *
-__amd_get_nb_event_constraints(struct cpu_hw_events *cpuc, struct perf_event *event,
-			       struct event_constraint *c)
-{
-	struct hw_perf_event *hwc = &event->hw;
-	struct amd_nb *nb = cpuc->amd_nb;
-	struct perf_event *old;
-	int idx, new = -1;
-
-	if (!c)
-		c = &unconstrained;
-
-	if (cpuc->is_fake)
-		return c;
-
-	/*
-	 * detect if already present, if so reuse
-	 *
-	 * cannot merge with actual allocation
-	 * because of possible holes
-	 *
-	 * event can already be present yet not assigned (in hwc->idx)
-	 * because of successive calls to x86_schedule_events() from
-	 * hw_perf_group_sched_in() without hw_perf_enable()
-	 */
-	for_each_set_bit(idx, c->idxmsk, x86_pmu.num_counters) {
-		if (new == -1 || hwc->idx == idx)
-			/* assign free slot, prefer hwc->idx */
-			old = cmpxchg(nb->owners + idx, NULL, event);
-		else if (nb->owners[idx] == event)
-			/* event already present */
-			old = event;
-		else
-			continue;
-
-		if (old && old != event)
-			continue;
-
-		/* reassign to this slot */
-		if (new != -1)
-			cmpxchg(nb->owners + new, event, NULL);
-		new = idx;
-
-		/* already present, reuse */
-		if (old == event)
-			break;
-	}
-
-	if (new == -1)
-		return &emptyconstraint;
-
-	return &nb->event_constraints[new];
-}
-
-static struct amd_nb *amd_alloc_nb(int cpu)
-{
-	struct amd_nb *nb;
-	int i;
-
-	nb = kzalloc_node(sizeof(struct amd_nb), GFP_KERNEL, cpu_to_node(cpu));
-	if (!nb)
-		return NULL;
-
-	nb->nb_id = -1;
-
-	/*
-	 * initialize all possible NB constraints
-	 */
-	for (i = 0; i < x86_pmu.num_counters; i++) {
-		__set_bit(i, nb->event_constraints[i].idxmsk);
-		nb->event_constraints[i].weight = 1;
-	}
-	return nb;
-}
-
-static int amd_pmu_cpu_prepare(int cpu)
-{
-	struct cpu_hw_events *cpuc = &per_cpu(cpu_hw_events, cpu);
-
-	WARN_ON_ONCE(cpuc->amd_nb);
-
-	if (boot_cpu_data.x86_max_cores < 2)
-		return NOTIFY_OK;
-
-	cpuc->amd_nb = amd_alloc_nb(cpu);
-	if (!cpuc->amd_nb)
-		return NOTIFY_BAD;
-
-	return NOTIFY_OK;
-}
-
-static void amd_pmu_cpu_starting(int cpu)
-{
-	struct cpu_hw_events *cpuc = &per_cpu(cpu_hw_events, cpu);
-	void **onln = &cpuc->kfree_on_online[X86_PERF_KFREE_SHARED];
-	struct amd_nb *nb;
-	int i, nb_id;
-
-	cpuc->perf_ctr_virt_mask = AMD64_EVENTSEL_HOSTONLY;
-
-	if (boot_cpu_data.x86_max_cores < 2)
-		return;
-
-	nb_id = amd_get_nb_id(cpu);
-	WARN_ON_ONCE(nb_id == BAD_APICID);
-
-	for_each_online_cpu(i) {
-		nb = per_cpu(cpu_hw_events, i).amd_nb;
-		if (WARN_ON_ONCE(!nb))
-			continue;
-
-		if (nb->nb_id == nb_id) {
-			*onln = cpuc->amd_nb;
-			cpuc->amd_nb = nb;
-			break;
-		}
-	}
-
-	cpuc->amd_nb->nb_id = nb_id;
-	cpuc->amd_nb->refcnt++;
-}
-
-static void amd_pmu_cpu_dead(int cpu)
-{
-	struct cpu_hw_events *cpuhw;
-
-	if (boot_cpu_data.x86_max_cores < 2)
-		return;
-
-	cpuhw = &per_cpu(cpu_hw_events, cpu);
-
-	if (cpuhw->amd_nb) {
-		struct amd_nb *nb = cpuhw->amd_nb;
-
-		if (nb->nb_id == -1 || --nb->refcnt == 0)
-			kfree(nb);
-
-		cpuhw->amd_nb = NULL;
-	}
-}
-
-static struct event_constraint *
-amd_get_event_constraints(struct cpu_hw_events *cpuc, int idx,
-			  struct perf_event *event)
-{
-	/*
-	 * if not NB event or no NB, then no constraints
-	 */
-	if (!(amd_has_nb(cpuc) && amd_is_nb_event(&event->hw)))
-		return &unconstrained;
-
-	return __amd_get_nb_event_constraints(cpuc, event, NULL);
-}
-
-static void amd_put_event_constraints(struct cpu_hw_events *cpuc,
-				      struct perf_event *event)
-{
-	if (amd_has_nb(cpuc) && amd_is_nb_event(&event->hw))
-		__amd_put_nb_event_constraints(cpuc, event);
-}
-
-PMU_FORMAT_ATTR(event,	"config:0-7,32-35");
-PMU_FORMAT_ATTR(umask,	"config:8-15"	);
-PMU_FORMAT_ATTR(edge,	"config:18"	);
-PMU_FORMAT_ATTR(inv,	"config:23"	);
-PMU_FORMAT_ATTR(cmask,	"config:24-31"	);
-
-static struct attribute *amd_format_attr[] = {
-	&format_attr_event.attr,
-	&format_attr_umask.attr,
-	&format_attr_edge.attr,
-	&format_attr_inv.attr,
-	&format_attr_cmask.attr,
-	NULL,
-};
-
-/* AMD Family 15h */
-
-#define AMD_EVENT_TYPE_MASK	0x000000F0ULL
-
-#define AMD_EVENT_FP		0x00000000ULL ... 0x00000010ULL
-#define AMD_EVENT_LS		0x00000020ULL ... 0x00000030ULL
-#define AMD_EVENT_DC		0x00000040ULL ... 0x00000050ULL
-#define AMD_EVENT_CU		0x00000060ULL ... 0x00000070ULL
-#define AMD_EVENT_IC_DE		0x00000080ULL ... 0x00000090ULL
-#define AMD_EVENT_EX_LS		0x000000C0ULL
-#define AMD_EVENT_DE		0x000000D0ULL
-#define AMD_EVENT_NB		0x000000E0ULL ... 0x000000F0ULL
-
-/*
- * AMD family 15h event code/PMC mappings:
- *
- * type = event_code & 0x0F0:
- *
- * 0x000	FP	PERF_CTL[5:3]
- * 0x010	FP	PERF_CTL[5:3]
- * 0x020	LS	PERF_CTL[5:0]
- * 0x030	LS	PERF_CTL[5:0]
- * 0x040	DC	PERF_CTL[5:0]
- * 0x050	DC	PERF_CTL[5:0]
- * 0x060	CU	PERF_CTL[2:0]
- * 0x070	CU	PERF_CTL[2:0]
- * 0x080	IC/DE	PERF_CTL[2:0]
- * 0x090	IC/DE	PERF_CTL[2:0]
- * 0x0A0	---
- * 0x0B0	---
- * 0x0C0	EX/LS	PERF_CTL[5:0]
- * 0x0D0	DE	PERF_CTL[2:0]
- * 0x0E0	NB	NB_PERF_CTL[3:0]
- * 0x0F0	NB	NB_PERF_CTL[3:0]
- *
- * Exceptions:
- *
- * 0x000	FP	PERF_CTL[3], PERF_CTL[5:3] (*)
- * 0x003	FP	PERF_CTL[3]
- * 0x004	FP	PERF_CTL[3], PERF_CTL[5:3] (*)
- * 0x00B	FP	PERF_CTL[3]
- * 0x00D	FP	PERF_CTL[3]
- * 0x023	DE	PERF_CTL[2:0]
- * 0x02D	LS	PERF_CTL[3]
- * 0x02E	LS	PERF_CTL[3,0]
- * 0x031	LS	PERF_CTL[2:0] (**)
- * 0x043	CU	PERF_CTL[2:0]
- * 0x045	CU	PERF_CTL[2:0]
- * 0x046	CU	PERF_CTL[2:0]
- * 0x054	CU	PERF_CTL[2:0]
- * 0x055	CU	PERF_CTL[2:0]
- * 0x08F	IC	PERF_CTL[0]
- * 0x187	DE	PERF_CTL[0]
- * 0x188	DE	PERF_CTL[0]
- * 0x0DB	EX	PERF_CTL[5:0]
- * 0x0DC	LS	PERF_CTL[5:0]
- * 0x0DD	LS	PERF_CTL[5:0]
- * 0x0DE	LS	PERF_CTL[5:0]
- * 0x0DF	LS	PERF_CTL[5:0]
- * 0x1C0	EX	PERF_CTL[5:3]
- * 0x1D6	EX	PERF_CTL[5:0]
- * 0x1D8	EX	PERF_CTL[5:0]
- *
- * (*)  depending on the umask all FPU counters may be used
- * (**) only one unitmask enabled at a time
- */
-
-static struct event_constraint amd_f15_PMC0  = EVENT_CONSTRAINT(0, 0x01, 0);
-static struct event_constraint amd_f15_PMC20 = EVENT_CONSTRAINT(0, 0x07, 0);
-static struct event_constraint amd_f15_PMC3  = EVENT_CONSTRAINT(0, 0x08, 0);
-static struct event_constraint amd_f15_PMC30 = EVENT_CONSTRAINT_OVERLAP(0, 0x09, 0);
-static struct event_constraint amd_f15_PMC50 = EVENT_CONSTRAINT(0, 0x3F, 0);
-static struct event_constraint amd_f15_PMC53 = EVENT_CONSTRAINT(0, 0x38, 0);
-
-static struct event_constraint *
-amd_get_event_constraints_f15h(struct cpu_hw_events *cpuc, int idx,
-			       struct perf_event *event)
-{
-	struct hw_perf_event *hwc = &event->hw;
-	unsigned int event_code = amd_get_event_code(hwc);
-
-	switch (event_code & AMD_EVENT_TYPE_MASK) {
-	case AMD_EVENT_FP:
-		switch (event_code) {
-		case 0x000:
-			if (!(hwc->config & 0x0000F000ULL))
-				break;
-			if (!(hwc->config & 0x00000F00ULL))
-				break;
-			return &amd_f15_PMC3;
-		case 0x004:
-			if (hweight_long(hwc->config & ARCH_PERFMON_EVENTSEL_UMASK) <= 1)
-				break;
-			return &amd_f15_PMC3;
-		case 0x003:
-		case 0x00B:
-		case 0x00D:
-			return &amd_f15_PMC3;
-		}
-		return &amd_f15_PMC53;
-	case AMD_EVENT_LS:
-	case AMD_EVENT_DC:
-	case AMD_EVENT_EX_LS:
-		switch (event_code) {
-		case 0x023:
-		case 0x043:
-		case 0x045:
-		case 0x046:
-		case 0x054:
-		case 0x055:
-			return &amd_f15_PMC20;
-		case 0x02D:
-			return &amd_f15_PMC3;
-		case 0x02E:
-			return &amd_f15_PMC30;
-		case 0x031:
-			if (hweight_long(hwc->config & ARCH_PERFMON_EVENTSEL_UMASK) <= 1)
-				return &amd_f15_PMC20;
-			return &emptyconstraint;
-		case 0x1C0:
-			return &amd_f15_PMC53;
-		default:
-			return &amd_f15_PMC50;
-		}
-	case AMD_EVENT_CU:
-	case AMD_EVENT_IC_DE:
-	case AMD_EVENT_DE:
-		switch (event_code) {
-		case 0x08F:
-		case 0x187:
-		case 0x188:
-			return &amd_f15_PMC0;
-		case 0x0DB ... 0x0DF:
-		case 0x1D6:
-		case 0x1D8:
-			return &amd_f15_PMC50;
-		default:
-			return &amd_f15_PMC20;
-		}
-	case AMD_EVENT_NB:
-		/* moved to perf_event_amd_uncore.c */
-		return &emptyconstraint;
-	default:
-		return &emptyconstraint;
-	}
-}
-
-static ssize_t amd_event_sysfs_show(char *page, u64 config)
-{
-	u64 event = (config & ARCH_PERFMON_EVENTSEL_EVENT) |
-		    (config & AMD64_EVENTSEL_EVENT) >> 24;
-
-	return x86_event_sysfs_show(page, config, event);
-}
-
-static __initconst const struct x86_pmu amd_pmu = {
-	.name			= "AMD",
-	.handle_irq		= x86_pmu_handle_irq,
-	.disable_all		= x86_pmu_disable_all,
-	.enable_all		= x86_pmu_enable_all,
-	.enable			= x86_pmu_enable_event,
-	.disable		= x86_pmu_disable_event,
-	.hw_config		= amd_pmu_hw_config,
-	.schedule_events	= x86_schedule_events,
-	.eventsel		= MSR_K7_EVNTSEL0,
-	.perfctr		= MSR_K7_PERFCTR0,
-	.addr_offset            = amd_pmu_addr_offset,
-	.event_map		= amd_pmu_event_map,
-	.max_events		= ARRAY_SIZE(amd_perfmon_event_map),
-	.num_counters		= AMD64_NUM_COUNTERS,
-	.cntval_bits		= 48,
-	.cntval_mask		= (1ULL << 48) - 1,
-	.apic			= 1,
-	/* use highest bit to detect overflow */
-	.max_period		= (1ULL << 47) - 1,
-	.get_event_constraints	= amd_get_event_constraints,
-	.put_event_constraints	= amd_put_event_constraints,
-
-	.format_attrs		= amd_format_attr,
-	.events_sysfs_show	= amd_event_sysfs_show,
-
-	.cpu_prepare		= amd_pmu_cpu_prepare,
-	.cpu_starting		= amd_pmu_cpu_starting,
-	.cpu_dead		= amd_pmu_cpu_dead,
-};
-
-static int __init amd_core_pmu_init(void)
-{
-	if (!cpu_has_perfctr_core)
-		return 0;
-
-	switch (boot_cpu_data.x86) {
-	case 0x15:
-		pr_cont("Fam15h ");
-		x86_pmu.get_event_constraints = amd_get_event_constraints_f15h;
-		break;
-
-	default:
-		pr_err("core perfctr but no constraints; unknown hardware!\n");
-		return -ENODEV;
-	}
-
-	/*
-	 * If core performance counter extensions exists, we must use
-	 * MSR_F15H_PERF_CTL/MSR_F15H_PERF_CTR msrs. See also
-	 * amd_pmu_addr_offset().
-	 */
-	x86_pmu.eventsel	= MSR_F15H_PERF_CTL;
-	x86_pmu.perfctr		= MSR_F15H_PERF_CTR;
-	x86_pmu.num_counters	= AMD64_NUM_COUNTERS_CORE;
-
-	pr_cont("core perfctr, ");
-	return 0;
-}
-
-__init int amd_pmu_init(void)
-{
-	int ret;
-
-	/* Performance-monitoring supported from K7 and later: */
-	if (boot_cpu_data.x86 < 6)
-		return -ENODEV;
-
-	x86_pmu = amd_pmu;
-
-	ret = amd_core_pmu_init();
-	if (ret)
-		return ret;
-
-	/* Events are common for all AMDs */
-	memcpy(hw_cache_event_ids, amd_hw_cache_event_ids,
-	       sizeof(hw_cache_event_ids));
-
-	return 0;
-}
-
-void amd_pmu_enable_virt(void)
-{
-	struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
-
-	cpuc->perf_ctr_virt_mask = 0;
-
-	/* Reload all events */
-	x86_pmu_disable_all();
-	x86_pmu_enable_all(0);
-}
-EXPORT_SYMBOL_GPL(amd_pmu_enable_virt);
-
-void amd_pmu_disable_virt(void)
-{
-	struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
-
-	/*
-	 * We only mask out the Host-only bit so that host-only counting works
-	 * when SVM is disabled. If someone sets up a guest-only counter when
-	 * SVM is disabled the Guest-only bits still gets set and the counter
-	 * will not count anything.
-	 */
-	cpuc->perf_ctr_virt_mask = AMD64_EVENTSEL_HOSTONLY;
-
-	/* Reload all events */
-	x86_pmu_disable_all();
-	x86_pmu_enable_all(0);
-}
-EXPORT_SYMBOL_GPL(amd_pmu_disable_virt);
--- zfcpdump-kernel-4.4.orig/arch/x86/kernel/cpu/perf_event_amd_ibs.c
+++ /dev/null
@@ -1,959 +0,0 @@
-/*
- * Performance events - AMD IBS
- *
- *  Copyright (C) 2011 Advanced Micro Devices, Inc., Robert Richter
- *
- *  For licencing details see kernel-base/COPYING
- */
-
-#include <linux/perf_event.h>
-#include <linux/module.h>
-#include <linux/pci.h>
-#include <linux/ptrace.h>
-#include <linux/syscore_ops.h>
-
-#include <asm/apic.h>
-
-#include "perf_event.h"
-
-static u32 ibs_caps;
-
-#if defined(CONFIG_PERF_EVENTS) && defined(CONFIG_CPU_SUP_AMD)
-
-#include <linux/kprobes.h>
-#include <linux/hardirq.h>
-
-#include <asm/nmi.h>
-
-#define IBS_FETCH_CONFIG_MASK	(IBS_FETCH_RAND_EN | IBS_FETCH_MAX_CNT)
-#define IBS_OP_CONFIG_MASK	IBS_OP_MAX_CNT
-
-enum ibs_states {
-	IBS_ENABLED	= 0,
-	IBS_STARTED	= 1,
-	IBS_STOPPING	= 2,
-
-	IBS_MAX_STATES,
-};
-
-struct cpu_perf_ibs {
-	struct perf_event	*event;
-	unsigned long		state[BITS_TO_LONGS(IBS_MAX_STATES)];
-};
-
-struct perf_ibs {
-	struct pmu			pmu;
-	unsigned int			msr;
-	u64				config_mask;
-	u64				cnt_mask;
-	u64				enable_mask;
-	u64				valid_mask;
-	u64				max_period;
-	unsigned long			offset_mask[1];
-	int				offset_max;
-	struct cpu_perf_ibs __percpu	*pcpu;
-
-	struct attribute		**format_attrs;
-	struct attribute_group		format_group;
-	const struct attribute_group	*attr_groups[2];
-
-	u64				(*get_count)(u64 config);
-};
-
-struct perf_ibs_data {
-	u32		size;
-	union {
-		u32	data[0];	/* data buffer starts here */
-		u32	caps;
-	};
-	u64		regs[MSR_AMD64_IBS_REG_COUNT_MAX];
-};
-
-static int
-perf_event_set_period(struct hw_perf_event *hwc, u64 min, u64 max, u64 *hw_period)
-{
-	s64 left = local64_read(&hwc->period_left);
-	s64 period = hwc->sample_period;
-	int overflow = 0;
-
-	/*
-	 * If we are way outside a reasonable range then just skip forward:
-	 */
-	if (unlikely(left <= -period)) {
-		left = period;
-		local64_set(&hwc->period_left, left);
-		hwc->last_period = period;
-		overflow = 1;
-	}
-
-	if (unlikely(left < (s64)min)) {
-		left += period;
-		local64_set(&hwc->period_left, left);
-		hwc->last_period = period;
-		overflow = 1;
-	}
-
-	/*
-	 * If the hw period that triggers the sw overflow is too short
-	 * we might hit the irq handler. This biases the results.
-	 * Thus we shorten the next-to-last period and set the last
-	 * period to the max period.
-	 */
-	if (left > max) {
-		left -= max;
-		if (left > max)
-			left = max;
-		else if (left < min)
-			left = min;
-	}
-
-	*hw_period = (u64)left;
-
-	return overflow;
-}
-
-static  int
-perf_event_try_update(struct perf_event *event, u64 new_raw_count, int width)
-{
-	struct hw_perf_event *hwc = &event->hw;
-	int shift = 64 - width;
-	u64 prev_raw_count;
-	u64 delta;
-
-	/*
-	 * Careful: an NMI might modify the previous event value.
-	 *
-	 * Our tactic to handle this is to first atomically read and
-	 * exchange a new raw count - then add that new-prev delta
-	 * count to the generic event atomically:
-	 */
-	prev_raw_count = local64_read(&hwc->prev_count);
-	if (local64_cmpxchg(&hwc->prev_count, prev_raw_count,
-					new_raw_count) != prev_raw_count)
-		return 0;
-
-	/*
-	 * Now we have the new raw value and have updated the prev
-	 * timestamp already. We can now calculate the elapsed delta
-	 * (event-)time and add that to the generic event.
-	 *
-	 * Careful, not all hw sign-extends above the physical width
-	 * of the count.
-	 */
-	delta = (new_raw_count << shift) - (prev_raw_count << shift);
-	delta >>= shift;
-
-	local64_add(delta, &event->count);
-	local64_sub(delta, &hwc->period_left);
-
-	return 1;
-}
-
-static struct perf_ibs perf_ibs_fetch;
-static struct perf_ibs perf_ibs_op;
-
-static struct perf_ibs *get_ibs_pmu(int type)
-{
-	if (perf_ibs_fetch.pmu.type == type)
-		return &perf_ibs_fetch;
-	if (perf_ibs_op.pmu.type == type)
-		return &perf_ibs_op;
-	return NULL;
-}
-
-/*
- * Use IBS for precise event sampling:
- *
- *  perf record -a -e cpu-cycles:p ...    # use ibs op counting cycle count
- *  perf record -a -e r076:p ...          # same as -e cpu-cycles:p
- *  perf record -a -e r0C1:p ...          # use ibs op counting micro-ops
- *
- * IbsOpCntCtl (bit 19) of IBS Execution Control Register (IbsOpCtl,
- * MSRC001_1033) is used to select either cycle or micro-ops counting
- * mode.
- *
- * The rip of IBS samples has skid 0. Thus, IBS supports precise
- * levels 1 and 2 and the PERF_EFLAGS_EXACT is set. In rare cases the
- * rip is invalid when IBS was not able to record the rip correctly.
- * We clear PERF_EFLAGS_EXACT and take the rip from pt_regs then.
- *
- */
-static int perf_ibs_precise_event(struct perf_event *event, u64 *config)
-{
-	switch (event->attr.precise_ip) {
-	case 0:
-		return -ENOENT;
-	case 1:
-	case 2:
-		break;
-	default:
-		return -EOPNOTSUPP;
-	}
-
-	switch (event->attr.type) {
-	case PERF_TYPE_HARDWARE:
-		switch (event->attr.config) {
-		case PERF_COUNT_HW_CPU_CYCLES:
-			*config = 0;
-			return 0;
-		}
-		break;
-	case PERF_TYPE_RAW:
-		switch (event->attr.config) {
-		case 0x0076:
-			*config = 0;
-			return 0;
-		case 0x00C1:
-			*config = IBS_OP_CNT_CTL;
-			return 0;
-		}
-		break;
-	default:
-		return -ENOENT;
-	}
-
-	return -EOPNOTSUPP;
-}
-
-static const struct perf_event_attr ibs_notsupp = {
-	.exclude_user	= 1,
-	.exclude_kernel	= 1,
-	.exclude_hv	= 1,
-	.exclude_idle	= 1,
-	.exclude_host	= 1,
-	.exclude_guest	= 1,
-};
-
-static int perf_ibs_init(struct perf_event *event)
-{
-	struct hw_perf_event *hwc = &event->hw;
-	struct perf_ibs *perf_ibs;
-	u64 max_cnt, config;
-	int ret;
-
-	perf_ibs = get_ibs_pmu(event->attr.type);
-	if (perf_ibs) {
-		config = event->attr.config;
-	} else {
-		perf_ibs = &perf_ibs_op;
-		ret = perf_ibs_precise_event(event, &config);
-		if (ret)
-			return ret;
-	}
-
-	if (event->pmu != &perf_ibs->pmu)
-		return -ENOENT;
-
-	if (perf_flags(&event->attr) & perf_flags(&ibs_notsupp))
-		return -EINVAL;
-
-	if (config & ~perf_ibs->config_mask)
-		return -EINVAL;
-
-	if (hwc->sample_period) {
-		if (config & perf_ibs->cnt_mask)
-			/* raw max_cnt may not be set */
-			return -EINVAL;
-		if (!event->attr.sample_freq && hwc->sample_period & 0x0f)
-			/*
-			 * lower 4 bits can not be set in ibs max cnt,
-			 * but allowing it in case we adjust the
-			 * sample period to set a frequency.
-			 */
-			return -EINVAL;
-		hwc->sample_period &= ~0x0FULL;
-		if (!hwc->sample_period)
-			hwc->sample_period = 0x10;
-	} else {
-		max_cnt = config & perf_ibs->cnt_mask;
-		config &= ~perf_ibs->cnt_mask;
-		event->attr.sample_period = max_cnt << 4;
-		hwc->sample_period = event->attr.sample_period;
-	}
-
-	if (!hwc->sample_period)
-		return -EINVAL;
-
-	/*
-	 * If we modify hwc->sample_period, we also need to update
-	 * hwc->last_period and hwc->period_left.
-	 */
-	hwc->last_period = hwc->sample_period;
-	local64_set(&hwc->period_left, hwc->sample_period);
-
-	hwc->config_base = perf_ibs->msr;
-	hwc->config = config;
-
-	return 0;
-}
-
-static int perf_ibs_set_period(struct perf_ibs *perf_ibs,
-			       struct hw_perf_event *hwc, u64 *period)
-{
-	int overflow;
-
-	/* ignore lower 4 bits in min count: */
-	overflow = perf_event_set_period(hwc, 1<<4, perf_ibs->max_period, period);
-	local64_set(&hwc->prev_count, 0);
-
-	return overflow;
-}
-
-static u64 get_ibs_fetch_count(u64 config)
-{
-	return (config & IBS_FETCH_CNT) >> 12;
-}
-
-static u64 get_ibs_op_count(u64 config)
-{
-	u64 count = 0;
-
-	if (config & IBS_OP_VAL)
-		count += (config & IBS_OP_MAX_CNT) << 4; /* cnt rolled over */
-
-	if (ibs_caps & IBS_CAPS_RDWROPCNT)
-		count += (config & IBS_OP_CUR_CNT) >> 32;
-
-	return count;
-}
-
-static void
-perf_ibs_event_update(struct perf_ibs *perf_ibs, struct perf_event *event,
-		      u64 *config)
-{
-	u64 count = perf_ibs->get_count(*config);
-
-	/*
-	 * Set width to 64 since we do not overflow on max width but
-	 * instead on max count. In perf_ibs_set_period() we clear
-	 * prev count manually on overflow.
-	 */
-	while (!perf_event_try_update(event, count, 64)) {
-		rdmsrl(event->hw.config_base, *config);
-		count = perf_ibs->get_count(*config);
-	}
-}
-
-static inline void perf_ibs_enable_event(struct perf_ibs *perf_ibs,
-					 struct hw_perf_event *hwc, u64 config)
-{
-	wrmsrl(hwc->config_base, hwc->config | config | perf_ibs->enable_mask);
-}
-
-/*
- * Erratum #420 Instruction-Based Sampling Engine May Generate
- * Interrupt that Cannot Be Cleared:
- *
- * Must clear counter mask first, then clear the enable bit. See
- * Revision Guide for AMD Family 10h Processors, Publication #41322.
- */
-static inline void perf_ibs_disable_event(struct perf_ibs *perf_ibs,
-					  struct hw_perf_event *hwc, u64 config)
-{
-	config &= ~perf_ibs->cnt_mask;
-	wrmsrl(hwc->config_base, config);
-	config &= ~perf_ibs->enable_mask;
-	wrmsrl(hwc->config_base, config);
-}
-
-/*
- * We cannot restore the ibs pmu state, so we always needs to update
- * the event while stopping it and then reset the state when starting
- * again. Thus, ignoring PERF_EF_RELOAD and PERF_EF_UPDATE flags in
- * perf_ibs_start()/perf_ibs_stop() and instead always do it.
- */
-static void perf_ibs_start(struct perf_event *event, int flags)
-{
-	struct hw_perf_event *hwc = &event->hw;
-	struct perf_ibs *perf_ibs = container_of(event->pmu, struct perf_ibs, pmu);
-	struct cpu_perf_ibs *pcpu = this_cpu_ptr(perf_ibs->pcpu);
-	u64 period;
-
-	if (WARN_ON_ONCE(!(hwc->state & PERF_HES_STOPPED)))
-		return;
-
-	WARN_ON_ONCE(!(hwc->state & PERF_HES_UPTODATE));
-	hwc->state = 0;
-
-	perf_ibs_set_period(perf_ibs, hwc, &period);
-	set_bit(IBS_STARTED, pcpu->state);
-	perf_ibs_enable_event(perf_ibs, hwc, period >> 4);
-
-	perf_event_update_userpage(event);
-}
-
-static void perf_ibs_stop(struct perf_event *event, int flags)
-{
-	struct hw_perf_event *hwc = &event->hw;
-	struct perf_ibs *perf_ibs = container_of(event->pmu, struct perf_ibs, pmu);
-	struct cpu_perf_ibs *pcpu = this_cpu_ptr(perf_ibs->pcpu);
-	u64 config;
-	int stopping;
-
-	stopping = test_and_clear_bit(IBS_STARTED, pcpu->state);
-
-	if (!stopping && (hwc->state & PERF_HES_UPTODATE))
-		return;
-
-	rdmsrl(hwc->config_base, config);
-
-	if (stopping) {
-		set_bit(IBS_STOPPING, pcpu->state);
-		perf_ibs_disable_event(perf_ibs, hwc, config);
-		WARN_ON_ONCE(hwc->state & PERF_HES_STOPPED);
-		hwc->state |= PERF_HES_STOPPED;
-	}
-
-	if (hwc->state & PERF_HES_UPTODATE)
-		return;
-
-	/*
-	 * Clear valid bit to not count rollovers on update, rollovers
-	 * are only updated in the irq handler.
-	 */
-	config &= ~perf_ibs->valid_mask;
-
-	perf_ibs_event_update(perf_ibs, event, &config);
-	hwc->state |= PERF_HES_UPTODATE;
-}
-
-static int perf_ibs_add(struct perf_event *event, int flags)
-{
-	struct perf_ibs *perf_ibs = container_of(event->pmu, struct perf_ibs, pmu);
-	struct cpu_perf_ibs *pcpu = this_cpu_ptr(perf_ibs->pcpu);
-
-	if (test_and_set_bit(IBS_ENABLED, pcpu->state))
-		return -ENOSPC;
-
-	event->hw.state = PERF_HES_UPTODATE | PERF_HES_STOPPED;
-
-	pcpu->event = event;
-
-	if (flags & PERF_EF_START)
-		perf_ibs_start(event, PERF_EF_RELOAD);
-
-	return 0;
-}
-
-static void perf_ibs_del(struct perf_event *event, int flags)
-{
-	struct perf_ibs *perf_ibs = container_of(event->pmu, struct perf_ibs, pmu);
-	struct cpu_perf_ibs *pcpu = this_cpu_ptr(perf_ibs->pcpu);
-
-	if (!test_and_clear_bit(IBS_ENABLED, pcpu->state))
-		return;
-
-	perf_ibs_stop(event, PERF_EF_UPDATE);
-
-	pcpu->event = NULL;
-
-	perf_event_update_userpage(event);
-}
-
-static void perf_ibs_read(struct perf_event *event) { }
-
-PMU_FORMAT_ATTR(rand_en,	"config:57");
-PMU_FORMAT_ATTR(cnt_ctl,	"config:19");
-
-static struct attribute *ibs_fetch_format_attrs[] = {
-	&format_attr_rand_en.attr,
-	NULL,
-};
-
-static struct attribute *ibs_op_format_attrs[] = {
-	NULL,	/* &format_attr_cnt_ctl.attr if IBS_CAPS_OPCNT */
-	NULL,
-};
-
-static struct perf_ibs perf_ibs_fetch = {
-	.pmu = {
-		.task_ctx_nr	= perf_invalid_context,
-
-		.event_init	= perf_ibs_init,
-		.add		= perf_ibs_add,
-		.del		= perf_ibs_del,
-		.start		= perf_ibs_start,
-		.stop		= perf_ibs_stop,
-		.read		= perf_ibs_read,
-	},
-	.msr			= MSR_AMD64_IBSFETCHCTL,
-	.config_mask		= IBS_FETCH_CONFIG_MASK,
-	.cnt_mask		= IBS_FETCH_MAX_CNT,
-	.enable_mask		= IBS_FETCH_ENABLE,
-	.valid_mask		= IBS_FETCH_VAL,
-	.max_period		= IBS_FETCH_MAX_CNT << 4,
-	.offset_mask		= { MSR_AMD64_IBSFETCH_REG_MASK },
-	.offset_max		= MSR_AMD64_IBSFETCH_REG_COUNT,
-	.format_attrs		= ibs_fetch_format_attrs,
-
-	.get_count		= get_ibs_fetch_count,
-};
-
-static struct perf_ibs perf_ibs_op = {
-	.pmu = {
-		.task_ctx_nr	= perf_invalid_context,
-
-		.event_init	= perf_ibs_init,
-		.add		= perf_ibs_add,
-		.del		= perf_ibs_del,
-		.start		= perf_ibs_start,
-		.stop		= perf_ibs_stop,
-		.read		= perf_ibs_read,
-	},
-	.msr			= MSR_AMD64_IBSOPCTL,
-	.config_mask		= IBS_OP_CONFIG_MASK,
-	.cnt_mask		= IBS_OP_MAX_CNT,
-	.enable_mask		= IBS_OP_ENABLE,
-	.valid_mask		= IBS_OP_VAL,
-	.max_period		= IBS_OP_MAX_CNT << 4,
-	.offset_mask		= { MSR_AMD64_IBSOP_REG_MASK },
-	.offset_max		= MSR_AMD64_IBSOP_REG_COUNT,
-	.format_attrs		= ibs_op_format_attrs,
-
-	.get_count		= get_ibs_op_count,
-};
-
-static int perf_ibs_handle_irq(struct perf_ibs *perf_ibs, struct pt_regs *iregs)
-{
-	struct cpu_perf_ibs *pcpu = this_cpu_ptr(perf_ibs->pcpu);
-	struct perf_event *event = pcpu->event;
-	struct hw_perf_event *hwc = &event->hw;
-	struct perf_sample_data data;
-	struct perf_raw_record raw;
-	struct pt_regs regs;
-	struct perf_ibs_data ibs_data;
-	int offset, size, check_rip, offset_max, throttle = 0;
-	unsigned int msr;
-	u64 *buf, *config, period;
-
-	if (!test_bit(IBS_STARTED, pcpu->state)) {
-		/*
-		 * Catch spurious interrupts after stopping IBS: After
-		 * disabling IBS there could be still incoming NMIs
-		 * with samples that even have the valid bit cleared.
-		 * Mark all this NMIs as handled.
-		 */
-		return test_and_clear_bit(IBS_STOPPING, pcpu->state) ? 1 : 0;
-	}
-
-	msr = hwc->config_base;
-	buf = ibs_data.regs;
-	rdmsrl(msr, *buf);
-	if (!(*buf++ & perf_ibs->valid_mask))
-		return 0;
-
-	config = &ibs_data.regs[0];
-	perf_ibs_event_update(perf_ibs, event, config);
-	perf_sample_data_init(&data, 0, hwc->last_period);
-	if (!perf_ibs_set_period(perf_ibs, hwc, &period))
-		goto out;	/* no sw counter overflow */
-
-	ibs_data.caps = ibs_caps;
-	size = 1;
-	offset = 1;
-	check_rip = (perf_ibs == &perf_ibs_op && (ibs_caps & IBS_CAPS_RIPINVALIDCHK));
-	if (event->attr.sample_type & PERF_SAMPLE_RAW)
-		offset_max = perf_ibs->offset_max;
-	else if (check_rip)
-		offset_max = 2;
-	else
-		offset_max = 1;
-	do {
-		rdmsrl(msr + offset, *buf++);
-		size++;
-		offset = find_next_bit(perf_ibs->offset_mask,
-				       perf_ibs->offset_max,
-				       offset + 1);
-	} while (offset < offset_max);
-	if (event->attr.sample_type & PERF_SAMPLE_RAW) {
-		/*
-		 * Read IbsBrTarget and IbsOpData4 separately
-		 * depending on their availability.
-		 * Can't add to offset_max as they are staggered
-		 */
-		if (ibs_caps & IBS_CAPS_BRNTRGT) {
-			rdmsrl(MSR_AMD64_IBSBRTARGET, *buf++);
-			size++;
-		}
-		if (ibs_caps & IBS_CAPS_OPDATA4) {
-			rdmsrl(MSR_AMD64_IBSOPDATA4, *buf++);
-			size++;
-		}
-	}
-	ibs_data.size = sizeof(u64) * size;
-
-	regs = *iregs;
-	if (check_rip && (ibs_data.regs[2] & IBS_RIP_INVALID)) {
-		regs.flags &= ~PERF_EFLAGS_EXACT;
-	} else {
-		set_linear_ip(&regs, ibs_data.regs[1]);
-		regs.flags |= PERF_EFLAGS_EXACT;
-	}
-
-	if (event->attr.sample_type & PERF_SAMPLE_RAW) {
-		raw.size = sizeof(u32) + ibs_data.size;
-		raw.data = ibs_data.data;
-		data.raw = &raw;
-	}
-
-	throttle = perf_event_overflow(event, &data, &regs);
-out:
-	if (throttle)
-		perf_ibs_disable_event(perf_ibs, hwc, *config);
-	else
-		perf_ibs_enable_event(perf_ibs, hwc, period >> 4);
-
-	perf_event_update_userpage(event);
-
-	return 1;
-}
-
-static int
-perf_ibs_nmi_handler(unsigned int cmd, struct pt_regs *regs)
-{
-	int handled = 0;
-
-	handled += perf_ibs_handle_irq(&perf_ibs_fetch, regs);
-	handled += perf_ibs_handle_irq(&perf_ibs_op, regs);
-
-	if (handled)
-		inc_irq_stat(apic_perf_irqs);
-
-	return handled;
-}
-NOKPROBE_SYMBOL(perf_ibs_nmi_handler);
-
-static __init int perf_ibs_pmu_init(struct perf_ibs *perf_ibs, char *name)
-{
-	struct cpu_perf_ibs __percpu *pcpu;
-	int ret;
-
-	pcpu = alloc_percpu(struct cpu_perf_ibs);
-	if (!pcpu)
-		return -ENOMEM;
-
-	perf_ibs->pcpu = pcpu;
-
-	/* register attributes */
-	if (perf_ibs->format_attrs[0]) {
-		memset(&perf_ibs->format_group, 0, sizeof(perf_ibs->format_group));
-		perf_ibs->format_group.name	= "format";
-		perf_ibs->format_group.attrs	= perf_ibs->format_attrs;
-
-		memset(&perf_ibs->attr_groups, 0, sizeof(perf_ibs->attr_groups));
-		perf_ibs->attr_groups[0]	= &perf_ibs->format_group;
-		perf_ibs->pmu.attr_groups	= perf_ibs->attr_groups;
-	}
-
-	ret = perf_pmu_register(&perf_ibs->pmu, name, -1);
-	if (ret) {
-		perf_ibs->pcpu = NULL;
-		free_percpu(pcpu);
-	}
-
-	return ret;
-}
-
-static __init int perf_event_ibs_init(void)
-{
-	struct attribute **attr = ibs_op_format_attrs;
-
-	if (!ibs_caps)
-		return -ENODEV;	/* ibs not supported by the cpu */
-
-	perf_ibs_pmu_init(&perf_ibs_fetch, "ibs_fetch");
-
-	if (ibs_caps & IBS_CAPS_OPCNT) {
-		perf_ibs_op.config_mask |= IBS_OP_CNT_CTL;
-		*attr++ = &format_attr_cnt_ctl.attr;
-	}
-	perf_ibs_pmu_init(&perf_ibs_op, "ibs_op");
-
-	register_nmi_handler(NMI_LOCAL, perf_ibs_nmi_handler, 0, "perf_ibs");
-	printk(KERN_INFO "perf: AMD IBS detected (0x%08x)\n", ibs_caps);
-
-	return 0;
-}
-
-#else /* defined(CONFIG_PERF_EVENTS) && defined(CONFIG_CPU_SUP_AMD) */
-
-static __init int perf_event_ibs_init(void) { return 0; }
-
-#endif
-
-/* IBS - apic initialization, for perf and oprofile */
-
-static __init u32 __get_ibs_caps(void)
-{
-	u32 caps;
-	unsigned int max_level;
-
-	if (!boot_cpu_has(X86_FEATURE_IBS))
-		return 0;
-
-	/* check IBS cpuid feature flags */
-	max_level = cpuid_eax(0x80000000);
-	if (max_level < IBS_CPUID_FEATURES)
-		return IBS_CAPS_DEFAULT;
-
-	caps = cpuid_eax(IBS_CPUID_FEATURES);
-	if (!(caps & IBS_CAPS_AVAIL))
-		/* cpuid flags not valid */
-		return IBS_CAPS_DEFAULT;
-
-	return caps;
-}
-
-u32 get_ibs_caps(void)
-{
-	return ibs_caps;
-}
-
-EXPORT_SYMBOL(get_ibs_caps);
-
-static inline int get_eilvt(int offset)
-{
-	return !setup_APIC_eilvt(offset, 0, APIC_EILVT_MSG_NMI, 1);
-}
-
-static inline int put_eilvt(int offset)
-{
-	return !setup_APIC_eilvt(offset, 0, 0, 1);
-}
-
-/*
- * Check and reserve APIC extended interrupt LVT offset for IBS if available.
- */
-static inline int ibs_eilvt_valid(void)
-{
-	int offset;
-	u64 val;
-	int valid = 0;
-
-	preempt_disable();
-
-	rdmsrl(MSR_AMD64_IBSCTL, val);
-	offset = val & IBSCTL_LVT_OFFSET_MASK;
-
-	if (!(val & IBSCTL_LVT_OFFSET_VALID)) {
-		pr_err(FW_BUG "cpu %d, invalid IBS interrupt offset %d (MSR%08X=0x%016llx)\n",
-		       smp_processor_id(), offset, MSR_AMD64_IBSCTL, val);
-		goto out;
-	}
-
-	if (!get_eilvt(offset)) {
-		pr_err(FW_BUG "cpu %d, IBS interrupt offset %d not available (MSR%08X=0x%016llx)\n",
-		       smp_processor_id(), offset, MSR_AMD64_IBSCTL, val);
-		goto out;
-	}
-
-	valid = 1;
-out:
-	preempt_enable();
-
-	return valid;
-}
-
-static int setup_ibs_ctl(int ibs_eilvt_off)
-{
-	struct pci_dev *cpu_cfg;
-	int nodes;
-	u32 value = 0;
-
-	nodes = 0;
-	cpu_cfg = NULL;
-	do {
-		cpu_cfg = pci_get_device(PCI_VENDOR_ID_AMD,
-					 PCI_DEVICE_ID_AMD_10H_NB_MISC,
-					 cpu_cfg);
-		if (!cpu_cfg)
-			break;
-		++nodes;
-		pci_write_config_dword(cpu_cfg, IBSCTL, ibs_eilvt_off
-				       | IBSCTL_LVT_OFFSET_VALID);
-		pci_read_config_dword(cpu_cfg, IBSCTL, &value);
-		if (value != (ibs_eilvt_off | IBSCTL_LVT_OFFSET_VALID)) {
-			pci_dev_put(cpu_cfg);
-			printk(KERN_DEBUG "Failed to setup IBS LVT offset, "
-			       "IBSCTL = 0x%08x\n", value);
-			return -EINVAL;
-		}
-	} while (1);
-
-	if (!nodes) {
-		printk(KERN_DEBUG "No CPU node configured for IBS\n");
-		return -ENODEV;
-	}
-
-	return 0;
-}
-
-/*
- * This runs only on the current cpu. We try to find an LVT offset and
- * setup the local APIC. For this we must disable preemption. On
- * success we initialize all nodes with this offset. This updates then
- * the offset in the IBS_CTL per-node msr. The per-core APIC setup of
- * the IBS interrupt vector is handled by perf_ibs_cpu_notifier that
- * is using the new offset.
- */
-static void force_ibs_eilvt_setup(void)
-{
-	int offset;
-	int ret;
-
-	preempt_disable();
-	/* find the next free available EILVT entry, skip offset 0 */
-	for (offset = 1; offset < APIC_EILVT_NR_MAX; offset++) {
-		if (get_eilvt(offset))
-			break;
-	}
-	preempt_enable();
-
-	if (offset == APIC_EILVT_NR_MAX) {
-		printk(KERN_DEBUG "No EILVT entry available\n");
-		return;
-	}
-
-	ret = setup_ibs_ctl(offset);
-	if (ret)
-		goto out;
-
-	if (!ibs_eilvt_valid())
-		goto out;
-
-	pr_info("IBS: LVT offset %d assigned\n", offset);
-
-	return;
-out:
-	preempt_disable();
-	put_eilvt(offset);
-	preempt_enable();
-	return;
-}
-
-static void ibs_eilvt_setup(void)
-{
-	/*
-	 * Force LVT offset assignment for family 10h: The offsets are
-	 * not assigned by the BIOS for this family, so the OS is
-	 * responsible for doing it. If the OS assignment fails, fall
-	 * back to BIOS settings and try to setup this.
-	 */
-	if (boot_cpu_data.x86 == 0x10)
-		force_ibs_eilvt_setup();
-}
-
-static inline int get_ibs_lvt_offset(void)
-{
-	u64 val;
-
-	rdmsrl(MSR_AMD64_IBSCTL, val);
-	if (!(val & IBSCTL_LVT_OFFSET_VALID))
-		return -EINVAL;
-
-	return val & IBSCTL_LVT_OFFSET_MASK;
-}
-
-static void setup_APIC_ibs(void *dummy)
-{
-	int offset;
-
-	offset = get_ibs_lvt_offset();
-	if (offset < 0)
-		goto failed;
-
-	if (!setup_APIC_eilvt(offset, 0, APIC_EILVT_MSG_NMI, 0))
-		return;
-failed:
-	pr_warn("perf: IBS APIC setup failed on cpu #%d\n",
-		smp_processor_id());
-}
-
-static void clear_APIC_ibs(void *dummy)
-{
-	int offset;
-
-	offset = get_ibs_lvt_offset();
-	if (offset >= 0)
-		setup_APIC_eilvt(offset, 0, APIC_EILVT_MSG_FIX, 1);
-}
-
-#ifdef CONFIG_PM
-
-static int perf_ibs_suspend(void)
-{
-	clear_APIC_ibs(NULL);
-	return 0;
-}
-
-static void perf_ibs_resume(void)
-{
-	ibs_eilvt_setup();
-	setup_APIC_ibs(NULL);
-}
-
-static struct syscore_ops perf_ibs_syscore_ops = {
-	.resume		= perf_ibs_resume,
-	.suspend	= perf_ibs_suspend,
-};
-
-static void perf_ibs_pm_init(void)
-{
-	register_syscore_ops(&perf_ibs_syscore_ops);
-}
-
-#else
-
-static inline void perf_ibs_pm_init(void) { }
-
-#endif
-
-static int
-perf_ibs_cpu_notifier(struct notifier_block *self, unsigned long action, void *hcpu)
-{
-	switch (action & ~CPU_TASKS_FROZEN) {
-	case CPU_STARTING:
-		setup_APIC_ibs(NULL);
-		break;
-	case CPU_DYING:
-		clear_APIC_ibs(NULL);
-		break;
-	default:
-		break;
-	}
-
-	return NOTIFY_OK;
-}
-
-static __init int amd_ibs_init(void)
-{
-	u32 caps;
-	int ret = -EINVAL;
-
-	caps = __get_ibs_caps();
-	if (!caps)
-		return -ENODEV;	/* ibs not supported by the cpu */
-
-	ibs_eilvt_setup();
-
-	if (!ibs_eilvt_valid())
-		goto out;
-
-	perf_ibs_pm_init();
-	cpu_notifier_register_begin();
-	ibs_caps = caps;
-	/* make ibs_caps visible to other cpus: */
-	smp_mb();
-	smp_call_function(setup_APIC_ibs, NULL, 1);
-	__perf_cpu_notifier(perf_ibs_cpu_notifier);
-	cpu_notifier_register_done();
-
-	ret = perf_event_ibs_init();
-out:
-	if (ret)
-		pr_err("Failed to setup IBS, %d\n", ret);
-	return ret;
-}
-
-/* Since we need the pci subsystem to init ibs we can't do this earlier: */
-device_initcall(amd_ibs_init);
--- zfcpdump-kernel-4.4.orig/arch/x86/kernel/cpu/perf_event_amd_iommu.c
+++ /dev/null
@@ -1,499 +0,0 @@
-/*
- * Copyright (C) 2013 Advanced Micro Devices, Inc.
- *
- * Author: Steven Kinney <Steven.Kinney@amd.com>
- * Author: Suravee Suthikulpanit <Suraveee.Suthikulpanit@amd.com>
- *
- * Perf: amd_iommu - AMD IOMMU Performance Counter PMU implementation
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/perf_event.h>
-#include <linux/module.h>
-#include <linux/cpumask.h>
-#include <linux/slab.h>
-
-#include "perf_event.h"
-#include "perf_event_amd_iommu.h"
-
-#define COUNTER_SHIFT		16
-
-#define _GET_BANK(ev)       ((u8)(ev->hw.extra_reg.reg >> 8))
-#define _GET_CNTR(ev)       ((u8)(ev->hw.extra_reg.reg))
-
-/* iommu pmu config masks */
-#define _GET_CSOURCE(ev)    ((ev->hw.config & 0xFFULL))
-#define _GET_DEVID(ev)      ((ev->hw.config >> 8)  & 0xFFFFULL)
-#define _GET_PASID(ev)      ((ev->hw.config >> 24) & 0xFFFFULL)
-#define _GET_DOMID(ev)      ((ev->hw.config >> 40) & 0xFFFFULL)
-#define _GET_DEVID_MASK(ev) ((ev->hw.extra_reg.config)  & 0xFFFFULL)
-#define _GET_PASID_MASK(ev) ((ev->hw.extra_reg.config >> 16) & 0xFFFFULL)
-#define _GET_DOMID_MASK(ev) ((ev->hw.extra_reg.config >> 32) & 0xFFFFULL)
-
-static struct perf_amd_iommu __perf_iommu;
-
-struct perf_amd_iommu {
-	struct pmu pmu;
-	u8 max_banks;
-	u8 max_counters;
-	u64 cntr_assign_mask;
-	raw_spinlock_t lock;
-	const struct attribute_group *attr_groups[4];
-};
-
-#define format_group	attr_groups[0]
-#define cpumask_group	attr_groups[1]
-#define events_group	attr_groups[2]
-#define null_group	attr_groups[3]
-
-/*---------------------------------------------
- * sysfs format attributes
- *---------------------------------------------*/
-PMU_FORMAT_ATTR(csource,    "config:0-7");
-PMU_FORMAT_ATTR(devid,      "config:8-23");
-PMU_FORMAT_ATTR(pasid,      "config:24-39");
-PMU_FORMAT_ATTR(domid,      "config:40-55");
-PMU_FORMAT_ATTR(devid_mask, "config1:0-15");
-PMU_FORMAT_ATTR(pasid_mask, "config1:16-31");
-PMU_FORMAT_ATTR(domid_mask, "config1:32-47");
-
-static struct attribute *iommu_format_attrs[] = {
-	&format_attr_csource.attr,
-	&format_attr_devid.attr,
-	&format_attr_pasid.attr,
-	&format_attr_domid.attr,
-	&format_attr_devid_mask.attr,
-	&format_attr_pasid_mask.attr,
-	&format_attr_domid_mask.attr,
-	NULL,
-};
-
-static struct attribute_group amd_iommu_format_group = {
-	.name = "format",
-	.attrs = iommu_format_attrs,
-};
-
-/*---------------------------------------------
- * sysfs events attributes
- *---------------------------------------------*/
-struct amd_iommu_event_desc {
-	struct kobj_attribute attr;
-	const char *event;
-};
-
-static ssize_t _iommu_event_show(struct kobject *kobj,
-				struct kobj_attribute *attr, char *buf)
-{
-	struct amd_iommu_event_desc *event =
-		container_of(attr, struct amd_iommu_event_desc, attr);
-	return sprintf(buf, "%s\n", event->event);
-}
-
-#define AMD_IOMMU_EVENT_DESC(_name, _event)			\
-{								\
-	.attr  = __ATTR(_name, 0444, _iommu_event_show, NULL),	\
-	.event = _event,					\
-}
-
-static struct amd_iommu_event_desc amd_iommu_v2_event_descs[] = {
-	AMD_IOMMU_EVENT_DESC(mem_pass_untrans,        "csource=0x01"),
-	AMD_IOMMU_EVENT_DESC(mem_pass_pretrans,       "csource=0x02"),
-	AMD_IOMMU_EVENT_DESC(mem_pass_excl,           "csource=0x03"),
-	AMD_IOMMU_EVENT_DESC(mem_target_abort,        "csource=0x04"),
-	AMD_IOMMU_EVENT_DESC(mem_trans_total,         "csource=0x05"),
-	AMD_IOMMU_EVENT_DESC(mem_iommu_tlb_pte_hit,   "csource=0x06"),
-	AMD_IOMMU_EVENT_DESC(mem_iommu_tlb_pte_mis,   "csource=0x07"),
-	AMD_IOMMU_EVENT_DESC(mem_iommu_tlb_pde_hit,   "csource=0x08"),
-	AMD_IOMMU_EVENT_DESC(mem_iommu_tlb_pde_mis,   "csource=0x09"),
-	AMD_IOMMU_EVENT_DESC(mem_dte_hit,             "csource=0x0a"),
-	AMD_IOMMU_EVENT_DESC(mem_dte_mis,             "csource=0x0b"),
-	AMD_IOMMU_EVENT_DESC(page_tbl_read_tot,       "csource=0x0c"),
-	AMD_IOMMU_EVENT_DESC(page_tbl_read_nst,       "csource=0x0d"),
-	AMD_IOMMU_EVENT_DESC(page_tbl_read_gst,       "csource=0x0e"),
-	AMD_IOMMU_EVENT_DESC(int_dte_hit,             "csource=0x0f"),
-	AMD_IOMMU_EVENT_DESC(int_dte_mis,             "csource=0x10"),
-	AMD_IOMMU_EVENT_DESC(cmd_processed,           "csource=0x11"),
-	AMD_IOMMU_EVENT_DESC(cmd_processed_inv,       "csource=0x12"),
-	AMD_IOMMU_EVENT_DESC(tlb_inv,                 "csource=0x13"),
-	{ /* end: all zeroes */ },
-};
-
-/*---------------------------------------------
- * sysfs cpumask attributes
- *---------------------------------------------*/
-static cpumask_t iommu_cpumask;
-
-static ssize_t _iommu_cpumask_show(struct device *dev,
-				   struct device_attribute *attr,
-				   char *buf)
-{
-	return cpumap_print_to_pagebuf(true, buf, &iommu_cpumask);
-}
-static DEVICE_ATTR(cpumask, S_IRUGO, _iommu_cpumask_show, NULL);
-
-static struct attribute *iommu_cpumask_attrs[] = {
-	&dev_attr_cpumask.attr,
-	NULL,
-};
-
-static struct attribute_group amd_iommu_cpumask_group = {
-	.attrs = iommu_cpumask_attrs,
-};
-
-/*---------------------------------------------*/
-
-static int get_next_avail_iommu_bnk_cntr(struct perf_amd_iommu *perf_iommu)
-{
-	unsigned long flags;
-	int shift, bank, cntr, retval;
-	int max_banks = perf_iommu->max_banks;
-	int max_cntrs = perf_iommu->max_counters;
-
-	raw_spin_lock_irqsave(&perf_iommu->lock, flags);
-
-	for (bank = 0, shift = 0; bank < max_banks; bank++) {
-		for (cntr = 0; cntr < max_cntrs; cntr++) {
-			shift = bank + (bank*3) + cntr;
-			if (perf_iommu->cntr_assign_mask & (1ULL<<shift)) {
-				continue;
-			} else {
-				perf_iommu->cntr_assign_mask |= (1ULL<<shift);
-				retval = ((u16)((u16)bank<<8) | (u8)(cntr));
-				goto out;
-			}
-		}
-	}
-	retval = -ENOSPC;
-out:
-	raw_spin_unlock_irqrestore(&perf_iommu->lock, flags);
-	return retval;
-}
-
-static int clear_avail_iommu_bnk_cntr(struct perf_amd_iommu *perf_iommu,
-					u8 bank, u8 cntr)
-{
-	unsigned long flags;
-	int max_banks, max_cntrs;
-	int shift = 0;
-
-	max_banks = perf_iommu->max_banks;
-	max_cntrs = perf_iommu->max_counters;
-
-	if ((bank > max_banks) || (cntr > max_cntrs))
-		return -EINVAL;
-
-	shift = bank + cntr + (bank*3);
-
-	raw_spin_lock_irqsave(&perf_iommu->lock, flags);
-	perf_iommu->cntr_assign_mask &= ~(1ULL<<shift);
-	raw_spin_unlock_irqrestore(&perf_iommu->lock, flags);
-
-	return 0;
-}
-
-static int perf_iommu_event_init(struct perf_event *event)
-{
-	struct hw_perf_event *hwc = &event->hw;
-	struct perf_amd_iommu *perf_iommu;
-	u64 config, config1;
-
-	/* test the event attr type check for PMU enumeration */
-	if (event->attr.type != event->pmu->type)
-		return -ENOENT;
-
-	/*
-	 * IOMMU counters are shared across all cores.
-	 * Therefore, it does not support per-process mode.
-	 * Also, it does not support event sampling mode.
-	 */
-	if (is_sampling_event(event) || event->attach_state & PERF_ATTACH_TASK)
-		return -EINVAL;
-
-	/* IOMMU counters do not have usr/os/guest/host bits */
-	if (event->attr.exclude_user || event->attr.exclude_kernel ||
-	    event->attr.exclude_host || event->attr.exclude_guest)
-		return -EINVAL;
-
-	if (event->cpu < 0)
-		return -EINVAL;
-
-	perf_iommu = &__perf_iommu;
-
-	if (event->pmu != &perf_iommu->pmu)
-		return -ENOENT;
-
-	if (perf_iommu) {
-		config = event->attr.config;
-		config1 = event->attr.config1;
-	} else {
-		return -EINVAL;
-	}
-
-	/* integrate with iommu base devid (0000), assume one iommu */
-	perf_iommu->max_banks =
-		amd_iommu_pc_get_max_banks(IOMMU_BASE_DEVID);
-	perf_iommu->max_counters =
-		amd_iommu_pc_get_max_counters(IOMMU_BASE_DEVID);
-	if ((perf_iommu->max_banks == 0) || (perf_iommu->max_counters == 0))
-		return -EINVAL;
-
-	/* update the hw_perf_event struct with the iommu config data */
-	hwc->config = config;
-	hwc->extra_reg.config = config1;
-
-	return 0;
-}
-
-static void perf_iommu_enable_event(struct perf_event *ev)
-{
-	u8 csource = _GET_CSOURCE(ev);
-	u16 devid = _GET_DEVID(ev);
-	u64 reg = 0ULL;
-
-	reg = csource;
-	amd_iommu_pc_get_set_reg_val(devid,
-			_GET_BANK(ev), _GET_CNTR(ev) ,
-			 IOMMU_PC_COUNTER_SRC_REG, &reg, true);
-
-	reg = 0ULL | devid | (_GET_DEVID_MASK(ev) << 32);
-	if (reg)
-		reg |= (1UL << 31);
-	amd_iommu_pc_get_set_reg_val(devid,
-			_GET_BANK(ev), _GET_CNTR(ev) ,
-			 IOMMU_PC_DEVID_MATCH_REG, &reg, true);
-
-	reg = 0ULL | _GET_PASID(ev) | (_GET_PASID_MASK(ev) << 32);
-	if (reg)
-		reg |= (1UL << 31);
-	amd_iommu_pc_get_set_reg_val(devid,
-			_GET_BANK(ev), _GET_CNTR(ev) ,
-			 IOMMU_PC_PASID_MATCH_REG, &reg, true);
-
-	reg = 0ULL | _GET_DOMID(ev) | (_GET_DOMID_MASK(ev) << 32);
-	if (reg)
-		reg |= (1UL << 31);
-	amd_iommu_pc_get_set_reg_val(devid,
-			_GET_BANK(ev), _GET_CNTR(ev) ,
-			 IOMMU_PC_DOMID_MATCH_REG, &reg, true);
-}
-
-static void perf_iommu_disable_event(struct perf_event *event)
-{
-	u64 reg = 0ULL;
-
-	amd_iommu_pc_get_set_reg_val(_GET_DEVID(event),
-			_GET_BANK(event), _GET_CNTR(event),
-			IOMMU_PC_COUNTER_SRC_REG, &reg, true);
-}
-
-static void perf_iommu_start(struct perf_event *event, int flags)
-{
-	struct hw_perf_event *hwc = &event->hw;
-
-	pr_debug("perf: amd_iommu:perf_iommu_start\n");
-	if (WARN_ON_ONCE(!(hwc->state & PERF_HES_STOPPED)))
-		return;
-
-	WARN_ON_ONCE(!(hwc->state & PERF_HES_UPTODATE));
-	hwc->state = 0;
-
-	if (flags & PERF_EF_RELOAD) {
-		u64 prev_raw_count =  local64_read(&hwc->prev_count);
-		amd_iommu_pc_get_set_reg_val(_GET_DEVID(event),
-				_GET_BANK(event), _GET_CNTR(event),
-				IOMMU_PC_COUNTER_REG, &prev_raw_count, true);
-	}
-
-	perf_iommu_enable_event(event);
-	perf_event_update_userpage(event);
-
-}
-
-static void perf_iommu_read(struct perf_event *event)
-{
-	u64 count = 0ULL;
-	u64 prev_raw_count = 0ULL;
-	u64 delta = 0ULL;
-	struct hw_perf_event *hwc = &event->hw;
-	pr_debug("perf: amd_iommu:perf_iommu_read\n");
-
-	amd_iommu_pc_get_set_reg_val(_GET_DEVID(event),
-				_GET_BANK(event), _GET_CNTR(event),
-				IOMMU_PC_COUNTER_REG, &count, false);
-
-	/* IOMMU pc counter register is only 48 bits */
-	count &= 0xFFFFFFFFFFFFULL;
-
-	prev_raw_count =  local64_read(&hwc->prev_count);
-	if (local64_cmpxchg(&hwc->prev_count, prev_raw_count,
-					count) != prev_raw_count)
-		return;
-
-	/* Handling 48-bit counter overflowing */
-	delta = (count << COUNTER_SHIFT) - (prev_raw_count << COUNTER_SHIFT);
-	delta >>= COUNTER_SHIFT;
-	local64_add(delta, &event->count);
-
-}
-
-static void perf_iommu_stop(struct perf_event *event, int flags)
-{
-	struct hw_perf_event *hwc = &event->hw;
-	u64 config;
-
-	pr_debug("perf: amd_iommu:perf_iommu_stop\n");
-
-	if (hwc->state & PERF_HES_UPTODATE)
-		return;
-
-	perf_iommu_disable_event(event);
-	WARN_ON_ONCE(hwc->state & PERF_HES_STOPPED);
-	hwc->state |= PERF_HES_STOPPED;
-
-	if (hwc->state & PERF_HES_UPTODATE)
-		return;
-
-	config = hwc->config;
-	perf_iommu_read(event);
-	hwc->state |= PERF_HES_UPTODATE;
-}
-
-static int perf_iommu_add(struct perf_event *event, int flags)
-{
-	int retval;
-	struct perf_amd_iommu *perf_iommu =
-			container_of(event->pmu, struct perf_amd_iommu, pmu);
-
-	pr_debug("perf: amd_iommu:perf_iommu_add\n");
-	event->hw.state = PERF_HES_UPTODATE | PERF_HES_STOPPED;
-
-	/* request an iommu bank/counter */
-	retval = get_next_avail_iommu_bnk_cntr(perf_iommu);
-	if (retval != -ENOSPC)
-		event->hw.extra_reg.reg = (u16)retval;
-	else
-		return retval;
-
-	if (flags & PERF_EF_START)
-		perf_iommu_start(event, PERF_EF_RELOAD);
-
-	return 0;
-}
-
-static void perf_iommu_del(struct perf_event *event, int flags)
-{
-	struct perf_amd_iommu *perf_iommu =
-			container_of(event->pmu, struct perf_amd_iommu, pmu);
-
-	pr_debug("perf: amd_iommu:perf_iommu_del\n");
-	perf_iommu_stop(event, PERF_EF_UPDATE);
-
-	/* clear the assigned iommu bank/counter */
-	clear_avail_iommu_bnk_cntr(perf_iommu,
-				     _GET_BANK(event),
-				     _GET_CNTR(event));
-
-	perf_event_update_userpage(event);
-}
-
-static __init int _init_events_attrs(struct perf_amd_iommu *perf_iommu)
-{
-	struct attribute **attrs;
-	struct attribute_group *attr_group;
-	int i = 0, j;
-
-	while (amd_iommu_v2_event_descs[i].attr.attr.name)
-		i++;
-
-	attr_group = kzalloc(sizeof(struct attribute *)
-		* (i + 1) + sizeof(*attr_group), GFP_KERNEL);
-	if (!attr_group)
-		return -ENOMEM;
-
-	attrs = (struct attribute **)(attr_group + 1);
-	for (j = 0; j < i; j++)
-		attrs[j] = &amd_iommu_v2_event_descs[j].attr.attr;
-
-	attr_group->name = "events";
-	attr_group->attrs = attrs;
-	perf_iommu->events_group = attr_group;
-
-	return 0;
-}
-
-static __init void amd_iommu_pc_exit(void)
-{
-	if (__perf_iommu.events_group != NULL) {
-		kfree(__perf_iommu.events_group);
-		__perf_iommu.events_group = NULL;
-	}
-}
-
-static __init int _init_perf_amd_iommu(
-	struct perf_amd_iommu *perf_iommu, char *name)
-{
-	int ret;
-
-	raw_spin_lock_init(&perf_iommu->lock);
-
-	/* Init format attributes */
-	perf_iommu->format_group = &amd_iommu_format_group;
-
-	/* Init cpumask attributes to only core 0 */
-	cpumask_set_cpu(0, &iommu_cpumask);
-	perf_iommu->cpumask_group = &amd_iommu_cpumask_group;
-
-	/* Init events attributes */
-	if (_init_events_attrs(perf_iommu) != 0)
-		pr_err("perf: amd_iommu: Only support raw events.\n");
-
-	/* Init null attributes */
-	perf_iommu->null_group = NULL;
-	perf_iommu->pmu.attr_groups = perf_iommu->attr_groups;
-
-	ret = perf_pmu_register(&perf_iommu->pmu, name, -1);
-	if (ret) {
-		pr_err("perf: amd_iommu: Failed to initialized.\n");
-		amd_iommu_pc_exit();
-	} else {
-		pr_info("perf: amd_iommu: Detected. (%d banks, %d counters/bank)\n",
-			amd_iommu_pc_get_max_banks(IOMMU_BASE_DEVID),
-			amd_iommu_pc_get_max_counters(IOMMU_BASE_DEVID));
-	}
-
-	return ret;
-}
-
-static struct perf_amd_iommu __perf_iommu = {
-	.pmu = {
-		.event_init	= perf_iommu_event_init,
-		.add		= perf_iommu_add,
-		.del		= perf_iommu_del,
-		.start		= perf_iommu_start,
-		.stop		= perf_iommu_stop,
-		.read		= perf_iommu_read,
-	},
-	.max_banks		= 0x00,
-	.max_counters		= 0x00,
-	.cntr_assign_mask	= 0ULL,
-	.format_group		= NULL,
-	.cpumask_group		= NULL,
-	.events_group		= NULL,
-	.null_group		= NULL,
-};
-
-static __init int amd_iommu_pc_init(void)
-{
-	/* Make sure the IOMMU PC resource is available */
-	if (!amd_iommu_pc_supported())
-		return -ENODEV;
-
-	_init_perf_amd_iommu(&__perf_iommu, "amd_iommu");
-
-	return 0;
-}
-
-device_initcall(amd_iommu_pc_init);
--- zfcpdump-kernel-4.4.orig/arch/x86/kernel/cpu/perf_event_amd_iommu.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2013 Advanced Micro Devices, Inc.
- *
- * Author: Steven Kinney <Steven.Kinney@amd.com>
- * Author: Suravee Suthikulpanit <Suraveee.Suthikulpanit@amd.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef _PERF_EVENT_AMD_IOMMU_H_
-#define _PERF_EVENT_AMD_IOMMU_H_
-
-/* iommu pc mmio region register indexes */
-#define IOMMU_PC_COUNTER_REG			0x00
-#define IOMMU_PC_COUNTER_SRC_REG		0x08
-#define IOMMU_PC_PASID_MATCH_REG		0x10
-#define IOMMU_PC_DOMID_MATCH_REG		0x18
-#define IOMMU_PC_DEVID_MATCH_REG		0x20
-#define IOMMU_PC_COUNTER_REPORT_REG		0x28
-
-/* maximun specified bank/counters */
-#define PC_MAX_SPEC_BNKS			64
-#define PC_MAX_SPEC_CNTRS			16
-
-/* iommu pc reg masks*/
-#define IOMMU_BASE_DEVID			0x0000
-
-/* amd_iommu_init.c external support functions */
-extern bool amd_iommu_pc_supported(void);
-
-extern u8 amd_iommu_pc_get_max_banks(u16 devid);
-
-extern u8 amd_iommu_pc_get_max_counters(u16 devid);
-
-extern int amd_iommu_pc_get_set_reg_val(u16 devid, u8 bank, u8 cntr,
-			u8 fxn, u64 *value, bool is_write);
-
-#endif /*_PERF_EVENT_AMD_IOMMU_H_*/
--- zfcpdump-kernel-4.4.orig/arch/x86/kernel/cpu/perf_event_amd_uncore.c
+++ /dev/null
@@ -1,600 +0,0 @@
-/*
- * Copyright (C) 2013 Advanced Micro Devices, Inc.
- *
- * Author: Jacob Shin <jacob.shin@amd.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/perf_event.h>
-#include <linux/percpu.h>
-#include <linux/types.h>
-#include <linux/slab.h>
-#include <linux/init.h>
-#include <linux/cpu.h>
-#include <linux/cpumask.h>
-
-#include <asm/cpufeature.h>
-#include <asm/perf_event.h>
-#include <asm/msr.h>
-
-#define NUM_COUNTERS_NB		4
-#define NUM_COUNTERS_L2		4
-#define MAX_COUNTERS		NUM_COUNTERS_NB
-
-#define RDPMC_BASE_NB		6
-#define RDPMC_BASE_L2		10
-
-#define COUNTER_SHIFT		16
-
-struct amd_uncore {
-	int id;
-	int refcnt;
-	int cpu;
-	int num_counters;
-	int rdpmc_base;
-	u32 msr_base;
-	cpumask_t *active_mask;
-	struct pmu *pmu;
-	struct perf_event *events[MAX_COUNTERS];
-	struct amd_uncore *free_when_cpu_online;
-};
-
-static struct amd_uncore * __percpu *amd_uncore_nb;
-static struct amd_uncore * __percpu *amd_uncore_l2;
-
-static struct pmu amd_nb_pmu;
-static struct pmu amd_l2_pmu;
-
-static cpumask_t amd_nb_active_mask;
-static cpumask_t amd_l2_active_mask;
-
-static bool is_nb_event(struct perf_event *event)
-{
-	return event->pmu->type == amd_nb_pmu.type;
-}
-
-static bool is_l2_event(struct perf_event *event)
-{
-	return event->pmu->type == amd_l2_pmu.type;
-}
-
-static struct amd_uncore *event_to_amd_uncore(struct perf_event *event)
-{
-	if (is_nb_event(event) && amd_uncore_nb)
-		return *per_cpu_ptr(amd_uncore_nb, event->cpu);
-	else if (is_l2_event(event) && amd_uncore_l2)
-		return *per_cpu_ptr(amd_uncore_l2, event->cpu);
-
-	return NULL;
-}
-
-static void amd_uncore_read(struct perf_event *event)
-{
-	struct hw_perf_event *hwc = &event->hw;
-	u64 prev, new;
-	s64 delta;
-
-	/*
-	 * since we do not enable counter overflow interrupts,
-	 * we do not have to worry about prev_count changing on us
-	 */
-
-	prev = local64_read(&hwc->prev_count);
-	rdpmcl(hwc->event_base_rdpmc, new);
-	local64_set(&hwc->prev_count, new);
-	delta = (new << COUNTER_SHIFT) - (prev << COUNTER_SHIFT);
-	delta >>= COUNTER_SHIFT;
-	local64_add(delta, &event->count);
-}
-
-static void amd_uncore_start(struct perf_event *event, int flags)
-{
-	struct hw_perf_event *hwc = &event->hw;
-
-	if (flags & PERF_EF_RELOAD)
-		wrmsrl(hwc->event_base, (u64)local64_read(&hwc->prev_count));
-
-	hwc->state = 0;
-	wrmsrl(hwc->config_base, (hwc->config | ARCH_PERFMON_EVENTSEL_ENABLE));
-	perf_event_update_userpage(event);
-}
-
-static void amd_uncore_stop(struct perf_event *event, int flags)
-{
-	struct hw_perf_event *hwc = &event->hw;
-
-	wrmsrl(hwc->config_base, hwc->config);
-	hwc->state |= PERF_HES_STOPPED;
-
-	if ((flags & PERF_EF_UPDATE) && !(hwc->state & PERF_HES_UPTODATE)) {
-		amd_uncore_read(event);
-		hwc->state |= PERF_HES_UPTODATE;
-	}
-}
-
-static int amd_uncore_add(struct perf_event *event, int flags)
-{
-	int i;
-	struct amd_uncore *uncore = event_to_amd_uncore(event);
-	struct hw_perf_event *hwc = &event->hw;
-
-	/* are we already assigned? */
-	if (hwc->idx != -1 && uncore->events[hwc->idx] == event)
-		goto out;
-
-	for (i = 0; i < uncore->num_counters; i++) {
-		if (uncore->events[i] == event) {
-			hwc->idx = i;
-			goto out;
-		}
-	}
-
-	/* if not, take the first available counter */
-	hwc->idx = -1;
-	for (i = 0; i < uncore->num_counters; i++) {
-		if (cmpxchg(&uncore->events[i], NULL, event) == NULL) {
-			hwc->idx = i;
-			break;
-		}
-	}
-
-out:
-	if (hwc->idx == -1)
-		return -EBUSY;
-
-	hwc->config_base = uncore->msr_base + (2 * hwc->idx);
-	hwc->event_base = uncore->msr_base + 1 + (2 * hwc->idx);
-	hwc->event_base_rdpmc = uncore->rdpmc_base + hwc->idx;
-	hwc->state = PERF_HES_UPTODATE | PERF_HES_STOPPED;
-
-	if (flags & PERF_EF_START)
-		amd_uncore_start(event, PERF_EF_RELOAD);
-
-	return 0;
-}
-
-static void amd_uncore_del(struct perf_event *event, int flags)
-{
-	int i;
-	struct amd_uncore *uncore = event_to_amd_uncore(event);
-	struct hw_perf_event *hwc = &event->hw;
-
-	amd_uncore_stop(event, PERF_EF_UPDATE);
-
-	for (i = 0; i < uncore->num_counters; i++) {
-		if (cmpxchg(&uncore->events[i], event, NULL) == event)
-			break;
-	}
-
-	hwc->idx = -1;
-}
-
-static int amd_uncore_event_init(struct perf_event *event)
-{
-	struct amd_uncore *uncore;
-	struct hw_perf_event *hwc = &event->hw;
-
-	if (event->attr.type != event->pmu->type)
-		return -ENOENT;
-
-	/*
-	 * NB and L2 counters (MSRs) are shared across all cores that share the
-	 * same NB / L2 cache. Interrupts can be directed to a single target
-	 * core, however, event counts generated by processes running on other
-	 * cores cannot be masked out. So we do not support sampling and
-	 * per-thread events.
-	 */
-	if (is_sampling_event(event) || event->attach_state & PERF_ATTACH_TASK)
-		return -EINVAL;
-
-	/* NB and L2 counters do not have usr/os/guest/host bits */
-	if (event->attr.exclude_user || event->attr.exclude_kernel ||
-	    event->attr.exclude_host || event->attr.exclude_guest)
-		return -EINVAL;
-
-	/* and we do not enable counter overflow interrupts */
-	hwc->config = event->attr.config & AMD64_RAW_EVENT_MASK_NB;
-	hwc->idx = -1;
-
-	if (event->cpu < 0)
-		return -EINVAL;
-
-	uncore = event_to_amd_uncore(event);
-	if (!uncore)
-		return -ENODEV;
-
-	/*
-	 * since request can come in to any of the shared cores, we will remap
-	 * to a single common cpu.
-	 */
-	event->cpu = uncore->cpu;
-
-	return 0;
-}
-
-static ssize_t amd_uncore_attr_show_cpumask(struct device *dev,
-					    struct device_attribute *attr,
-					    char *buf)
-{
-	cpumask_t *active_mask;
-	struct pmu *pmu = dev_get_drvdata(dev);
-
-	if (pmu->type == amd_nb_pmu.type)
-		active_mask = &amd_nb_active_mask;
-	else if (pmu->type == amd_l2_pmu.type)
-		active_mask = &amd_l2_active_mask;
-	else
-		return 0;
-
-	return cpumap_print_to_pagebuf(true, buf, active_mask);
-}
-static DEVICE_ATTR(cpumask, S_IRUGO, amd_uncore_attr_show_cpumask, NULL);
-
-static struct attribute *amd_uncore_attrs[] = {
-	&dev_attr_cpumask.attr,
-	NULL,
-};
-
-static struct attribute_group amd_uncore_attr_group = {
-	.attrs = amd_uncore_attrs,
-};
-
-PMU_FORMAT_ATTR(event, "config:0-7,32-35");
-PMU_FORMAT_ATTR(umask, "config:8-15");
-
-static struct attribute *amd_uncore_format_attr[] = {
-	&format_attr_event.attr,
-	&format_attr_umask.attr,
-	NULL,
-};
-
-static struct attribute_group amd_uncore_format_group = {
-	.name = "format",
-	.attrs = amd_uncore_format_attr,
-};
-
-static const struct attribute_group *amd_uncore_attr_groups[] = {
-	&amd_uncore_attr_group,
-	&amd_uncore_format_group,
-	NULL,
-};
-
-static struct pmu amd_nb_pmu = {
-	.attr_groups	= amd_uncore_attr_groups,
-	.name		= "amd_nb",
-	.event_init	= amd_uncore_event_init,
-	.add		= amd_uncore_add,
-	.del		= amd_uncore_del,
-	.start		= amd_uncore_start,
-	.stop		= amd_uncore_stop,
-	.read		= amd_uncore_read,
-};
-
-static struct pmu amd_l2_pmu = {
-	.attr_groups	= amd_uncore_attr_groups,
-	.name		= "amd_l2",
-	.event_init	= amd_uncore_event_init,
-	.add		= amd_uncore_add,
-	.del		= amd_uncore_del,
-	.start		= amd_uncore_start,
-	.stop		= amd_uncore_stop,
-	.read		= amd_uncore_read,
-};
-
-static struct amd_uncore *amd_uncore_alloc(unsigned int cpu)
-{
-	return kzalloc_node(sizeof(struct amd_uncore), GFP_KERNEL,
-			cpu_to_node(cpu));
-}
-
-static int amd_uncore_cpu_up_prepare(unsigned int cpu)
-{
-	struct amd_uncore *uncore_nb = NULL, *uncore_l2;
-
-	if (amd_uncore_nb) {
-		uncore_nb = amd_uncore_alloc(cpu);
-		if (!uncore_nb)
-			goto fail;
-		uncore_nb->cpu = cpu;
-		uncore_nb->num_counters = NUM_COUNTERS_NB;
-		uncore_nb->rdpmc_base = RDPMC_BASE_NB;
-		uncore_nb->msr_base = MSR_F15H_NB_PERF_CTL;
-		uncore_nb->active_mask = &amd_nb_active_mask;
-		uncore_nb->pmu = &amd_nb_pmu;
-		*per_cpu_ptr(amd_uncore_nb, cpu) = uncore_nb;
-	}
-
-	if (amd_uncore_l2) {
-		uncore_l2 = amd_uncore_alloc(cpu);
-		if (!uncore_l2)
-			goto fail;
-		uncore_l2->cpu = cpu;
-		uncore_l2->num_counters = NUM_COUNTERS_L2;
-		uncore_l2->rdpmc_base = RDPMC_BASE_L2;
-		uncore_l2->msr_base = MSR_F16H_L2I_PERF_CTL;
-		uncore_l2->active_mask = &amd_l2_active_mask;
-		uncore_l2->pmu = &amd_l2_pmu;
-		*per_cpu_ptr(amd_uncore_l2, cpu) = uncore_l2;
-	}
-
-	return 0;
-
-fail:
-	kfree(uncore_nb);
-	return -ENOMEM;
-}
-
-static struct amd_uncore *
-amd_uncore_find_online_sibling(struct amd_uncore *this,
-			       struct amd_uncore * __percpu *uncores)
-{
-	unsigned int cpu;
-	struct amd_uncore *that;
-
-	for_each_online_cpu(cpu) {
-		that = *per_cpu_ptr(uncores, cpu);
-
-		if (!that)
-			continue;
-
-		if (this == that)
-			continue;
-
-		if (this->id == that->id) {
-			that->free_when_cpu_online = this;
-			this = that;
-			break;
-		}
-	}
-
-	this->refcnt++;
-	return this;
-}
-
-static void amd_uncore_cpu_starting(unsigned int cpu)
-{
-	unsigned int eax, ebx, ecx, edx;
-	struct amd_uncore *uncore;
-
-	if (amd_uncore_nb) {
-		uncore = *per_cpu_ptr(amd_uncore_nb, cpu);
-		cpuid(0x8000001e, &eax, &ebx, &ecx, &edx);
-		uncore->id = ecx & 0xff;
-
-		uncore = amd_uncore_find_online_sibling(uncore, amd_uncore_nb);
-		*per_cpu_ptr(amd_uncore_nb, cpu) = uncore;
-	}
-
-	if (amd_uncore_l2) {
-		unsigned int apicid = cpu_data(cpu).apicid;
-		unsigned int nshared;
-
-		uncore = *per_cpu_ptr(amd_uncore_l2, cpu);
-		cpuid_count(0x8000001d, 2, &eax, &ebx, &ecx, &edx);
-		nshared = ((eax >> 14) & 0xfff) + 1;
-		uncore->id = apicid - (apicid % nshared);
-
-		uncore = amd_uncore_find_online_sibling(uncore, amd_uncore_l2);
-		*per_cpu_ptr(amd_uncore_l2, cpu) = uncore;
-	}
-}
-
-static void uncore_online(unsigned int cpu,
-			  struct amd_uncore * __percpu *uncores)
-{
-	struct amd_uncore *uncore = *per_cpu_ptr(uncores, cpu);
-
-	kfree(uncore->free_when_cpu_online);
-	uncore->free_when_cpu_online = NULL;
-
-	if (cpu == uncore->cpu)
-		cpumask_set_cpu(cpu, uncore->active_mask);
-}
-
-static void amd_uncore_cpu_online(unsigned int cpu)
-{
-	if (amd_uncore_nb)
-		uncore_online(cpu, amd_uncore_nb);
-
-	if (amd_uncore_l2)
-		uncore_online(cpu, amd_uncore_l2);
-}
-
-static void uncore_down_prepare(unsigned int cpu,
-				struct amd_uncore * __percpu *uncores)
-{
-	unsigned int i;
-	struct amd_uncore *this = *per_cpu_ptr(uncores, cpu);
-
-	if (this->cpu != cpu)
-		return;
-
-	/* this cpu is going down, migrate to a shared sibling if possible */
-	for_each_online_cpu(i) {
-		struct amd_uncore *that = *per_cpu_ptr(uncores, i);
-
-		if (cpu == i)
-			continue;
-
-		if (this == that) {
-			perf_pmu_migrate_context(this->pmu, cpu, i);
-			cpumask_clear_cpu(cpu, that->active_mask);
-			cpumask_set_cpu(i, that->active_mask);
-			that->cpu = i;
-			break;
-		}
-	}
-}
-
-static void amd_uncore_cpu_down_prepare(unsigned int cpu)
-{
-	if (amd_uncore_nb)
-		uncore_down_prepare(cpu, amd_uncore_nb);
-
-	if (amd_uncore_l2)
-		uncore_down_prepare(cpu, amd_uncore_l2);
-}
-
-static void uncore_dead(unsigned int cpu, struct amd_uncore * __percpu *uncores)
-{
-	struct amd_uncore *uncore = *per_cpu_ptr(uncores, cpu);
-
-	if (cpu == uncore->cpu)
-		cpumask_clear_cpu(cpu, uncore->active_mask);
-
-	if (!--uncore->refcnt)
-		kfree(uncore);
-	*per_cpu_ptr(uncores, cpu) = NULL;
-}
-
-static void amd_uncore_cpu_dead(unsigned int cpu)
-{
-	if (amd_uncore_nb)
-		uncore_dead(cpu, amd_uncore_nb);
-
-	if (amd_uncore_l2)
-		uncore_dead(cpu, amd_uncore_l2);
-}
-
-static int
-amd_uncore_cpu_notifier(struct notifier_block *self, unsigned long action,
-			void *hcpu)
-{
-	unsigned int cpu = (long)hcpu;
-
-	switch (action & ~CPU_TASKS_FROZEN) {
-	case CPU_UP_PREPARE:
-		if (amd_uncore_cpu_up_prepare(cpu))
-			return notifier_from_errno(-ENOMEM);
-		break;
-
-	case CPU_STARTING:
-		amd_uncore_cpu_starting(cpu);
-		break;
-
-	case CPU_ONLINE:
-		amd_uncore_cpu_online(cpu);
-		break;
-
-	case CPU_DOWN_PREPARE:
-		amd_uncore_cpu_down_prepare(cpu);
-		break;
-
-	case CPU_UP_CANCELED:
-	case CPU_DEAD:
-		amd_uncore_cpu_dead(cpu);
-		break;
-
-	default:
-		break;
-	}
-
-	return NOTIFY_OK;
-}
-
-static struct notifier_block amd_uncore_cpu_notifier_block = {
-	.notifier_call	= amd_uncore_cpu_notifier,
-	.priority	= CPU_PRI_PERF + 1,
-};
-
-static void __init init_cpu_already_online(void *dummy)
-{
-	unsigned int cpu = smp_processor_id();
-
-	amd_uncore_cpu_starting(cpu);
-	amd_uncore_cpu_online(cpu);
-}
-
-static void cleanup_cpu_online(void *dummy)
-{
-	unsigned int cpu = smp_processor_id();
-
-	amd_uncore_cpu_dead(cpu);
-}
-
-static int __init amd_uncore_init(void)
-{
-	unsigned int cpu, cpu2;
-	int ret = -ENODEV;
-
-	if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD)
-		goto fail_nodev;
-
-	if (!cpu_has_topoext)
-		goto fail_nodev;
-
-	if (cpu_has_perfctr_nb) {
-		amd_uncore_nb = alloc_percpu(struct amd_uncore *);
-		if (!amd_uncore_nb) {
-			ret = -ENOMEM;
-			goto fail_nb;
-		}
-		ret = perf_pmu_register(&amd_nb_pmu, amd_nb_pmu.name, -1);
-		if (ret)
-			goto fail_nb;
-
-		printk(KERN_INFO "perf: AMD NB counters detected\n");
-		ret = 0;
-	}
-
-	if (cpu_has_perfctr_l2) {
-		amd_uncore_l2 = alloc_percpu(struct amd_uncore *);
-		if (!amd_uncore_l2) {
-			ret = -ENOMEM;
-			goto fail_l2;
-		}
-		ret = perf_pmu_register(&amd_l2_pmu, amd_l2_pmu.name, -1);
-		if (ret)
-			goto fail_l2;
-
-		printk(KERN_INFO "perf: AMD L2I counters detected\n");
-		ret = 0;
-	}
-
-	if (ret)
-		goto fail_nodev;
-
-	cpu_notifier_register_begin();
-
-	/* init cpus already online before registering for hotplug notifier */
-	for_each_online_cpu(cpu) {
-		ret = amd_uncore_cpu_up_prepare(cpu);
-		if (ret)
-			goto fail_online;
-		smp_call_function_single(cpu, init_cpu_already_online, NULL, 1);
-	}
-
-	__register_cpu_notifier(&amd_uncore_cpu_notifier_block);
-	cpu_notifier_register_done();
-
-	return 0;
-
-
-fail_online:
-	for_each_online_cpu(cpu2) {
-		if (cpu2 == cpu)
-			break;
-		smp_call_function_single(cpu, cleanup_cpu_online, NULL, 1);
-	}
-	cpu_notifier_register_done();
-
-	/* amd_uncore_nb/l2 should have been freed by cleanup_cpu_online */
-	amd_uncore_nb = amd_uncore_l2 = NULL;
-	if (cpu_has_perfctr_l2)
-		perf_pmu_unregister(&amd_l2_pmu);
-fail_l2:
-	if (cpu_has_perfctr_nb)
-		perf_pmu_unregister(&amd_nb_pmu);
-	if (amd_uncore_l2)
-		free_percpu(amd_uncore_l2);
-fail_nb:
-	if (amd_uncore_nb)
-		free_percpu(amd_uncore_nb);
-
-fail_nodev:
-	return ret;
-}
-device_initcall(amd_uncore_init);
--- zfcpdump-kernel-4.4.orig/arch/x86/kernel/cpu/perf_event_intel.c
+++ /dev/null
@@ -1,3669 +0,0 @@
-/*
- * Per core/cpu state
- *
- * Used to coordinate shared registers between HT threads or
- * among events on a single PMU.
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/stddef.h>
-#include <linux/types.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/export.h>
-#include <linux/nmi.h>
-
-#include <asm/cpufeature.h>
-#include <asm/hardirq.h>
-#include <asm/apic.h>
-
-#include "perf_event.h"
-
-/*
- * Intel PerfMon, used on Core and later.
- */
-static u64 intel_perfmon_event_map[PERF_COUNT_HW_MAX] __read_mostly =
-{
-	[PERF_COUNT_HW_CPU_CYCLES]		= 0x003c,
-	[PERF_COUNT_HW_INSTRUCTIONS]		= 0x00c0,
-	[PERF_COUNT_HW_CACHE_REFERENCES]	= 0x4f2e,
-	[PERF_COUNT_HW_CACHE_MISSES]		= 0x412e,
-	[PERF_COUNT_HW_BRANCH_INSTRUCTIONS]	= 0x00c4,
-	[PERF_COUNT_HW_BRANCH_MISSES]		= 0x00c5,
-	[PERF_COUNT_HW_BUS_CYCLES]		= 0x013c,
-	[PERF_COUNT_HW_REF_CPU_CYCLES]		= 0x0300, /* pseudo-encoding */
-};
-
-static struct event_constraint intel_core_event_constraints[] __read_mostly =
-{
-	INTEL_EVENT_CONSTRAINT(0x11, 0x2), /* FP_ASSIST */
-	INTEL_EVENT_CONSTRAINT(0x12, 0x2), /* MUL */
-	INTEL_EVENT_CONSTRAINT(0x13, 0x2), /* DIV */
-	INTEL_EVENT_CONSTRAINT(0x14, 0x1), /* CYCLES_DIV_BUSY */
-	INTEL_EVENT_CONSTRAINT(0x19, 0x2), /* DELAYED_BYPASS */
-	INTEL_EVENT_CONSTRAINT(0xc1, 0x1), /* FP_COMP_INSTR_RET */
-	EVENT_CONSTRAINT_END
-};
-
-static struct event_constraint intel_core2_event_constraints[] __read_mostly =
-{
-	FIXED_EVENT_CONSTRAINT(0x00c0, 0), /* INST_RETIRED.ANY */
-	FIXED_EVENT_CONSTRAINT(0x003c, 1), /* CPU_CLK_UNHALTED.CORE */
-	FIXED_EVENT_CONSTRAINT(0x0300, 2), /* CPU_CLK_UNHALTED.REF */
-	INTEL_EVENT_CONSTRAINT(0x10, 0x1), /* FP_COMP_OPS_EXE */
-	INTEL_EVENT_CONSTRAINT(0x11, 0x2), /* FP_ASSIST */
-	INTEL_EVENT_CONSTRAINT(0x12, 0x2), /* MUL */
-	INTEL_EVENT_CONSTRAINT(0x13, 0x2), /* DIV */
-	INTEL_EVENT_CONSTRAINT(0x14, 0x1), /* CYCLES_DIV_BUSY */
-	INTEL_EVENT_CONSTRAINT(0x18, 0x1), /* IDLE_DURING_DIV */
-	INTEL_EVENT_CONSTRAINT(0x19, 0x2), /* DELAYED_BYPASS */
-	INTEL_EVENT_CONSTRAINT(0xa1, 0x1), /* RS_UOPS_DISPATCH_CYCLES */
-	INTEL_EVENT_CONSTRAINT(0xc9, 0x1), /* ITLB_MISS_RETIRED (T30-9) */
-	INTEL_EVENT_CONSTRAINT(0xcb, 0x1), /* MEM_LOAD_RETIRED */
-	EVENT_CONSTRAINT_END
-};
-
-static struct event_constraint intel_nehalem_event_constraints[] __read_mostly =
-{
-	FIXED_EVENT_CONSTRAINT(0x00c0, 0), /* INST_RETIRED.ANY */
-	FIXED_EVENT_CONSTRAINT(0x003c, 1), /* CPU_CLK_UNHALTED.CORE */
-	FIXED_EVENT_CONSTRAINT(0x0300, 2), /* CPU_CLK_UNHALTED.REF */
-	INTEL_EVENT_CONSTRAINT(0x40, 0x3), /* L1D_CACHE_LD */
-	INTEL_EVENT_CONSTRAINT(0x41, 0x3), /* L1D_CACHE_ST */
-	INTEL_EVENT_CONSTRAINT(0x42, 0x3), /* L1D_CACHE_LOCK */
-	INTEL_EVENT_CONSTRAINT(0x43, 0x3), /* L1D_ALL_REF */
-	INTEL_EVENT_CONSTRAINT(0x48, 0x3), /* L1D_PEND_MISS */
-	INTEL_EVENT_CONSTRAINT(0x4e, 0x3), /* L1D_PREFETCH */
-	INTEL_EVENT_CONSTRAINT(0x51, 0x3), /* L1D */
-	INTEL_EVENT_CONSTRAINT(0x63, 0x3), /* CACHE_LOCK_CYCLES */
-	EVENT_CONSTRAINT_END
-};
-
-static struct extra_reg intel_nehalem_extra_regs[] __read_mostly =
-{
-	/* must define OFFCORE_RSP_X first, see intel_fixup_er() */
-	INTEL_UEVENT_EXTRA_REG(0x01b7, MSR_OFFCORE_RSP_0, 0xffff, RSP_0),
-	INTEL_UEVENT_PEBS_LDLAT_EXTRA_REG(0x100b),
-	EVENT_EXTRA_END
-};
-
-static struct event_constraint intel_westmere_event_constraints[] __read_mostly =
-{
-	FIXED_EVENT_CONSTRAINT(0x00c0, 0), /* INST_RETIRED.ANY */
-	FIXED_EVENT_CONSTRAINT(0x003c, 1), /* CPU_CLK_UNHALTED.CORE */
-	FIXED_EVENT_CONSTRAINT(0x0300, 2), /* CPU_CLK_UNHALTED.REF */
-	INTEL_EVENT_CONSTRAINT(0x51, 0x3), /* L1D */
-	INTEL_EVENT_CONSTRAINT(0x60, 0x1), /* OFFCORE_REQUESTS_OUTSTANDING */
-	INTEL_EVENT_CONSTRAINT(0x63, 0x3), /* CACHE_LOCK_CYCLES */
-	INTEL_EVENT_CONSTRAINT(0xb3, 0x1), /* SNOOPQ_REQUEST_OUTSTANDING */
-	EVENT_CONSTRAINT_END
-};
-
-static struct event_constraint intel_snb_event_constraints[] __read_mostly =
-{
-	FIXED_EVENT_CONSTRAINT(0x00c0, 0), /* INST_RETIRED.ANY */
-	FIXED_EVENT_CONSTRAINT(0x003c, 1), /* CPU_CLK_UNHALTED.CORE */
-	FIXED_EVENT_CONSTRAINT(0x0300, 2), /* CPU_CLK_UNHALTED.REF */
-	INTEL_UEVENT_CONSTRAINT(0x04a3, 0xf), /* CYCLE_ACTIVITY.CYCLES_NO_DISPATCH */
-	INTEL_UEVENT_CONSTRAINT(0x05a3, 0xf), /* CYCLE_ACTIVITY.STALLS_L2_PENDING */
-	INTEL_UEVENT_CONSTRAINT(0x02a3, 0x4), /* CYCLE_ACTIVITY.CYCLES_L1D_PENDING */
-	INTEL_UEVENT_CONSTRAINT(0x06a3, 0x4), /* CYCLE_ACTIVITY.STALLS_L1D_PENDING */
-	INTEL_EVENT_CONSTRAINT(0x48, 0x4), /* L1D_PEND_MISS.PENDING */
-	INTEL_UEVENT_CONSTRAINT(0x01c0, 0x2), /* INST_RETIRED.PREC_DIST */
-	INTEL_EVENT_CONSTRAINT(0xcd, 0x8), /* MEM_TRANS_RETIRED.LOAD_LATENCY */
-	INTEL_UEVENT_CONSTRAINT(0x04a3, 0xf), /* CYCLE_ACTIVITY.CYCLES_NO_DISPATCH */
-	INTEL_UEVENT_CONSTRAINT(0x02a3, 0x4), /* CYCLE_ACTIVITY.CYCLES_L1D_PENDING */
-
-	INTEL_EXCLEVT_CONSTRAINT(0xd0, 0xf), /* MEM_UOPS_RETIRED.* */
-	INTEL_EXCLEVT_CONSTRAINT(0xd1, 0xf), /* MEM_LOAD_UOPS_RETIRED.* */
-	INTEL_EXCLEVT_CONSTRAINT(0xd2, 0xf), /* MEM_LOAD_UOPS_LLC_HIT_RETIRED.* */
-	INTEL_EXCLEVT_CONSTRAINT(0xd3, 0xf), /* MEM_LOAD_UOPS_LLC_MISS_RETIRED.* */
-
-	EVENT_CONSTRAINT_END
-};
-
-static struct event_constraint intel_ivb_event_constraints[] __read_mostly =
-{
-	FIXED_EVENT_CONSTRAINT(0x00c0, 0), /* INST_RETIRED.ANY */
-	FIXED_EVENT_CONSTRAINT(0x003c, 1), /* CPU_CLK_UNHALTED.CORE */
-	FIXED_EVENT_CONSTRAINT(0x0300, 2), /* CPU_CLK_UNHALTED.REF */
-	INTEL_UEVENT_CONSTRAINT(0x0148, 0x4), /* L1D_PEND_MISS.PENDING */
-	INTEL_UEVENT_CONSTRAINT(0x0279, 0xf), /* IDQ.EMTPY */
-	INTEL_UEVENT_CONSTRAINT(0x019c, 0xf), /* IDQ_UOPS_NOT_DELIVERED.CORE */
-	INTEL_UEVENT_CONSTRAINT(0x02a3, 0xf), /* CYCLE_ACTIVITY.CYCLES_LDM_PENDING */
-	INTEL_UEVENT_CONSTRAINT(0x04a3, 0xf), /* CYCLE_ACTIVITY.CYCLES_NO_EXECUTE */
-	INTEL_UEVENT_CONSTRAINT(0x05a3, 0xf), /* CYCLE_ACTIVITY.STALLS_L2_PENDING */
-	INTEL_UEVENT_CONSTRAINT(0x06a3, 0xf), /* CYCLE_ACTIVITY.STALLS_LDM_PENDING */
-	INTEL_UEVENT_CONSTRAINT(0x08a3, 0x4), /* CYCLE_ACTIVITY.CYCLES_L1D_PENDING */
-	INTEL_UEVENT_CONSTRAINT(0x0ca3, 0x4), /* CYCLE_ACTIVITY.STALLS_L1D_PENDING */
-	INTEL_UEVENT_CONSTRAINT(0x01c0, 0x2), /* INST_RETIRED.PREC_DIST */
-
-	INTEL_EXCLEVT_CONSTRAINT(0xd0, 0xf), /* MEM_UOPS_RETIRED.* */
-	INTEL_EXCLEVT_CONSTRAINT(0xd1, 0xf), /* MEM_LOAD_UOPS_RETIRED.* */
-	INTEL_EXCLEVT_CONSTRAINT(0xd2, 0xf), /* MEM_LOAD_UOPS_LLC_HIT_RETIRED.* */
-	INTEL_EXCLEVT_CONSTRAINT(0xd3, 0xf), /* MEM_LOAD_UOPS_LLC_MISS_RETIRED.* */
-
-	EVENT_CONSTRAINT_END
-};
-
-static struct extra_reg intel_westmere_extra_regs[] __read_mostly =
-{
-	/* must define OFFCORE_RSP_X first, see intel_fixup_er() */
-	INTEL_UEVENT_EXTRA_REG(0x01b7, MSR_OFFCORE_RSP_0, 0xffff, RSP_0),
-	INTEL_UEVENT_EXTRA_REG(0x01bb, MSR_OFFCORE_RSP_1, 0xffff, RSP_1),
-	INTEL_UEVENT_PEBS_LDLAT_EXTRA_REG(0x100b),
-	EVENT_EXTRA_END
-};
-
-static struct event_constraint intel_v1_event_constraints[] __read_mostly =
-{
-	EVENT_CONSTRAINT_END
-};
-
-static struct event_constraint intel_gen_event_constraints[] __read_mostly =
-{
-	FIXED_EVENT_CONSTRAINT(0x00c0, 0), /* INST_RETIRED.ANY */
-	FIXED_EVENT_CONSTRAINT(0x003c, 1), /* CPU_CLK_UNHALTED.CORE */
-	FIXED_EVENT_CONSTRAINT(0x0300, 2), /* CPU_CLK_UNHALTED.REF */
-	EVENT_CONSTRAINT_END
-};
-
-static struct event_constraint intel_slm_event_constraints[] __read_mostly =
-{
-	FIXED_EVENT_CONSTRAINT(0x00c0, 0), /* INST_RETIRED.ANY */
-	FIXED_EVENT_CONSTRAINT(0x003c, 1), /* CPU_CLK_UNHALTED.CORE */
-	FIXED_EVENT_CONSTRAINT(0x0300, 2), /* pseudo CPU_CLK_UNHALTED.REF */
-	EVENT_CONSTRAINT_END
-};
-
-struct event_constraint intel_skl_event_constraints[] = {
-	FIXED_EVENT_CONSTRAINT(0x00c0, 0),	/* INST_RETIRED.ANY */
-	FIXED_EVENT_CONSTRAINT(0x003c, 1),	/* CPU_CLK_UNHALTED.CORE */
-	FIXED_EVENT_CONSTRAINT(0x0300, 2),	/* CPU_CLK_UNHALTED.REF */
-	INTEL_UEVENT_CONSTRAINT(0x1c0, 0x2),	/* INST_RETIRED.PREC_DIST */
-	EVENT_CONSTRAINT_END
-};
-
-static struct extra_reg intel_snb_extra_regs[] __read_mostly = {
-	/* must define OFFCORE_RSP_X first, see intel_fixup_er() */
-	INTEL_UEVENT_EXTRA_REG(0x01b7, MSR_OFFCORE_RSP_0, 0x3f807f8fffull, RSP_0),
-	INTEL_UEVENT_EXTRA_REG(0x01bb, MSR_OFFCORE_RSP_1, 0x3f807f8fffull, RSP_1),
-	INTEL_UEVENT_PEBS_LDLAT_EXTRA_REG(0x01cd),
-	EVENT_EXTRA_END
-};
-
-static struct extra_reg intel_snbep_extra_regs[] __read_mostly = {
-	/* must define OFFCORE_RSP_X first, see intel_fixup_er() */
-	INTEL_UEVENT_EXTRA_REG(0x01b7, MSR_OFFCORE_RSP_0, 0x3fffff8fffull, RSP_0),
-	INTEL_UEVENT_EXTRA_REG(0x01bb, MSR_OFFCORE_RSP_1, 0x3fffff8fffull, RSP_1),
-	INTEL_UEVENT_PEBS_LDLAT_EXTRA_REG(0x01cd),
-	EVENT_EXTRA_END
-};
-
-static struct extra_reg intel_skl_extra_regs[] __read_mostly = {
-	INTEL_UEVENT_EXTRA_REG(0x01b7, MSR_OFFCORE_RSP_0, 0x3fffff8fffull, RSP_0),
-	INTEL_UEVENT_EXTRA_REG(0x01bb, MSR_OFFCORE_RSP_1, 0x3fffff8fffull, RSP_1),
-	INTEL_UEVENT_PEBS_LDLAT_EXTRA_REG(0x01cd),
-	/*
-	 * Note the low 8 bits eventsel code is not a continuous field, containing
-	 * some #GPing bits. These are masked out.
-	 */
-	INTEL_UEVENT_EXTRA_REG(0x01c6, MSR_PEBS_FRONTEND, 0x7fff17, FE),
-	EVENT_EXTRA_END
-};
-
-EVENT_ATTR_STR(mem-loads,	mem_ld_nhm,	"event=0x0b,umask=0x10,ldlat=3");
-EVENT_ATTR_STR(mem-loads,	mem_ld_snb,	"event=0xcd,umask=0x1,ldlat=3");
-EVENT_ATTR_STR(mem-stores,	mem_st_snb,	"event=0xcd,umask=0x2");
-
-struct attribute *nhm_events_attrs[] = {
-	EVENT_PTR(mem_ld_nhm),
-	NULL,
-};
-
-struct attribute *snb_events_attrs[] = {
-	EVENT_PTR(mem_ld_snb),
-	EVENT_PTR(mem_st_snb),
-	NULL,
-};
-
-static struct event_constraint intel_hsw_event_constraints[] = {
-	FIXED_EVENT_CONSTRAINT(0x00c0, 0), /* INST_RETIRED.ANY */
-	FIXED_EVENT_CONSTRAINT(0x003c, 1), /* CPU_CLK_UNHALTED.CORE */
-	FIXED_EVENT_CONSTRAINT(0x0300, 2), /* CPU_CLK_UNHALTED.REF */
-	INTEL_UEVENT_CONSTRAINT(0x148, 0x4),	/* L1D_PEND_MISS.PENDING */
-	INTEL_UEVENT_CONSTRAINT(0x01c0, 0x2), /* INST_RETIRED.PREC_DIST */
-	INTEL_EVENT_CONSTRAINT(0xcd, 0x8), /* MEM_TRANS_RETIRED.LOAD_LATENCY */
-	/* CYCLE_ACTIVITY.CYCLES_L1D_PENDING */
-	INTEL_UEVENT_CONSTRAINT(0x08a3, 0x4),
-	/* CYCLE_ACTIVITY.STALLS_L1D_PENDING */
-	INTEL_UEVENT_CONSTRAINT(0x0ca3, 0x4),
-	/* CYCLE_ACTIVITY.CYCLES_NO_EXECUTE */
-	INTEL_UEVENT_CONSTRAINT(0x04a3, 0xf),
-
-	INTEL_EXCLEVT_CONSTRAINT(0xd0, 0xf), /* MEM_UOPS_RETIRED.* */
-	INTEL_EXCLEVT_CONSTRAINT(0xd1, 0xf), /* MEM_LOAD_UOPS_RETIRED.* */
-	INTEL_EXCLEVT_CONSTRAINT(0xd2, 0xf), /* MEM_LOAD_UOPS_LLC_HIT_RETIRED.* */
-	INTEL_EXCLEVT_CONSTRAINT(0xd3, 0xf), /* MEM_LOAD_UOPS_LLC_MISS_RETIRED.* */
-
-	EVENT_CONSTRAINT_END
-};
-
-struct event_constraint intel_bdw_event_constraints[] = {
-	FIXED_EVENT_CONSTRAINT(0x00c0, 0),	/* INST_RETIRED.ANY */
-	FIXED_EVENT_CONSTRAINT(0x003c, 1),	/* CPU_CLK_UNHALTED.CORE */
-	FIXED_EVENT_CONSTRAINT(0x0300, 2),	/* CPU_CLK_UNHALTED.REF */
-	INTEL_UEVENT_CONSTRAINT(0x148, 0x4),	/* L1D_PEND_MISS.PENDING */
-	INTEL_UEVENT_CONSTRAINT(0x8a3, 0x4),	/* CYCLE_ACTIVITY.CYCLES_L1D_MISS */
-	EVENT_CONSTRAINT_END
-};
-
-static u64 intel_pmu_event_map(int hw_event)
-{
-	return intel_perfmon_event_map[hw_event];
-}
-
-/*
- * Notes on the events:
- * - data reads do not include code reads (comparable to earlier tables)
- * - data counts include speculative execution (except L1 write, dtlb, bpu)
- * - remote node access includes remote memory, remote cache, remote mmio.
- * - prefetches are not included in the counts.
- * - icache miss does not include decoded icache
- */
-
-#define SKL_DEMAND_DATA_RD		BIT_ULL(0)
-#define SKL_DEMAND_RFO			BIT_ULL(1)
-#define SKL_ANY_RESPONSE		BIT_ULL(16)
-#define SKL_SUPPLIER_NONE		BIT_ULL(17)
-#define SKL_L3_MISS_LOCAL_DRAM		BIT_ULL(26)
-#define SKL_L3_MISS_REMOTE_HOP0_DRAM	BIT_ULL(27)
-#define SKL_L3_MISS_REMOTE_HOP1_DRAM	BIT_ULL(28)
-#define SKL_L3_MISS_REMOTE_HOP2P_DRAM	BIT_ULL(29)
-#define SKL_L3_MISS			(SKL_L3_MISS_LOCAL_DRAM| \
-					 SKL_L3_MISS_REMOTE_HOP0_DRAM| \
-					 SKL_L3_MISS_REMOTE_HOP1_DRAM| \
-					 SKL_L3_MISS_REMOTE_HOP2P_DRAM)
-#define SKL_SPL_HIT			BIT_ULL(30)
-#define SKL_SNOOP_NONE			BIT_ULL(31)
-#define SKL_SNOOP_NOT_NEEDED		BIT_ULL(32)
-#define SKL_SNOOP_MISS			BIT_ULL(33)
-#define SKL_SNOOP_HIT_NO_FWD		BIT_ULL(34)
-#define SKL_SNOOP_HIT_WITH_FWD		BIT_ULL(35)
-#define SKL_SNOOP_HITM			BIT_ULL(36)
-#define SKL_SNOOP_NON_DRAM		BIT_ULL(37)
-#define SKL_ANY_SNOOP			(SKL_SPL_HIT|SKL_SNOOP_NONE| \
-					 SKL_SNOOP_NOT_NEEDED|SKL_SNOOP_MISS| \
-					 SKL_SNOOP_HIT_NO_FWD|SKL_SNOOP_HIT_WITH_FWD| \
-					 SKL_SNOOP_HITM|SKL_SNOOP_NON_DRAM)
-#define SKL_DEMAND_READ			SKL_DEMAND_DATA_RD
-#define SKL_SNOOP_DRAM			(SKL_SNOOP_NONE| \
-					 SKL_SNOOP_NOT_NEEDED|SKL_SNOOP_MISS| \
-					 SKL_SNOOP_HIT_NO_FWD|SKL_SNOOP_HIT_WITH_FWD| \
-					 SKL_SNOOP_HITM|SKL_SPL_HIT)
-#define SKL_DEMAND_WRITE		SKL_DEMAND_RFO
-#define SKL_LLC_ACCESS			SKL_ANY_RESPONSE
-#define SKL_L3_MISS_REMOTE		(SKL_L3_MISS_REMOTE_HOP0_DRAM| \
-					 SKL_L3_MISS_REMOTE_HOP1_DRAM| \
-					 SKL_L3_MISS_REMOTE_HOP2P_DRAM)
-
-static __initconst const u64 skl_hw_cache_event_ids
-				[PERF_COUNT_HW_CACHE_MAX]
-				[PERF_COUNT_HW_CACHE_OP_MAX]
-				[PERF_COUNT_HW_CACHE_RESULT_MAX] =
-{
- [ C(L1D ) ] = {
-	[ C(OP_READ) ] = {
-		[ C(RESULT_ACCESS) ] = 0x81d0,	/* MEM_INST_RETIRED.ALL_LOADS */
-		[ C(RESULT_MISS)   ] = 0x151,	/* L1D.REPLACEMENT */
-	},
-	[ C(OP_WRITE) ] = {
-		[ C(RESULT_ACCESS) ] = 0x82d0,	/* MEM_INST_RETIRED.ALL_STORES */
-		[ C(RESULT_MISS)   ] = 0x0,
-	},
-	[ C(OP_PREFETCH) ] = {
-		[ C(RESULT_ACCESS) ] = 0x0,
-		[ C(RESULT_MISS)   ] = 0x0,
-	},
- },
- [ C(L1I ) ] = {
-	[ C(OP_READ) ] = {
-		[ C(RESULT_ACCESS) ] = 0x0,
-		[ C(RESULT_MISS)   ] = 0x283,	/* ICACHE_64B.MISS */
-	},
-	[ C(OP_WRITE) ] = {
-		[ C(RESULT_ACCESS) ] = -1,
-		[ C(RESULT_MISS)   ] = -1,
-	},
-	[ C(OP_PREFETCH) ] = {
-		[ C(RESULT_ACCESS) ] = 0x0,
-		[ C(RESULT_MISS)   ] = 0x0,
-	},
- },
- [ C(LL  ) ] = {
-	[ C(OP_READ) ] = {
-		[ C(RESULT_ACCESS) ] = 0x1b7,	/* OFFCORE_RESPONSE */
-		[ C(RESULT_MISS)   ] = 0x1b7,	/* OFFCORE_RESPONSE */
-	},
-	[ C(OP_WRITE) ] = {
-		[ C(RESULT_ACCESS) ] = 0x1b7,	/* OFFCORE_RESPONSE */
-		[ C(RESULT_MISS)   ] = 0x1b7,	/* OFFCORE_RESPONSE */
-	},
-	[ C(OP_PREFETCH) ] = {
-		[ C(RESULT_ACCESS) ] = 0x0,
-		[ C(RESULT_MISS)   ] = 0x0,
-	},
- },
- [ C(DTLB) ] = {
-	[ C(OP_READ) ] = {
-		[ C(RESULT_ACCESS) ] = 0x81d0,	/* MEM_INST_RETIRED.ALL_LOADS */
-		[ C(RESULT_MISS)   ] = 0x608,	/* DTLB_LOAD_MISSES.WALK_COMPLETED */
-	},
-	[ C(OP_WRITE) ] = {
-		[ C(RESULT_ACCESS) ] = 0x82d0,	/* MEM_INST_RETIRED.ALL_STORES */
-		[ C(RESULT_MISS)   ] = 0x649,	/* DTLB_STORE_MISSES.WALK_COMPLETED */
-	},
-	[ C(OP_PREFETCH) ] = {
-		[ C(RESULT_ACCESS) ] = 0x0,
-		[ C(RESULT_MISS)   ] = 0x0,
-	},
- },
- [ C(ITLB) ] = {
-	[ C(OP_READ) ] = {
-		[ C(RESULT_ACCESS) ] = 0x2085,	/* ITLB_MISSES.STLB_HIT */
-		[ C(RESULT_MISS)   ] = 0xe85,	/* ITLB_MISSES.WALK_COMPLETED */
-	},
-	[ C(OP_WRITE) ] = {
-		[ C(RESULT_ACCESS) ] = -1,
-		[ C(RESULT_MISS)   ] = -1,
-	},
-	[ C(OP_PREFETCH) ] = {
-		[ C(RESULT_ACCESS) ] = -1,
-		[ C(RESULT_MISS)   ] = -1,
-	},
- },
- [ C(BPU ) ] = {
-	[ C(OP_READ) ] = {
-		[ C(RESULT_ACCESS) ] = 0xc4,	/* BR_INST_RETIRED.ALL_BRANCHES */
-		[ C(RESULT_MISS)   ] = 0xc5,	/* BR_MISP_RETIRED.ALL_BRANCHES */
-	},
-	[ C(OP_WRITE) ] = {
-		[ C(RESULT_ACCESS) ] = -1,
-		[ C(RESULT_MISS)   ] = -1,
-	},
-	[ C(OP_PREFETCH) ] = {
-		[ C(RESULT_ACCESS) ] = -1,
-		[ C(RESULT_MISS)   ] = -1,
-	},
- },
- [ C(NODE) ] = {
-	[ C(OP_READ) ] = {
-		[ C(RESULT_ACCESS) ] = 0x1b7,	/* OFFCORE_RESPONSE */
-		[ C(RESULT_MISS)   ] = 0x1b7,	/* OFFCORE_RESPONSE */
-	},
-	[ C(OP_WRITE) ] = {
-		[ C(RESULT_ACCESS) ] = 0x1b7,	/* OFFCORE_RESPONSE */
-		[ C(RESULT_MISS)   ] = 0x1b7,	/* OFFCORE_RESPONSE */
-	},
-	[ C(OP_PREFETCH) ] = {
-		[ C(RESULT_ACCESS) ] = 0x0,
-		[ C(RESULT_MISS)   ] = 0x0,
-	},
- },
-};
-
-static __initconst const u64 skl_hw_cache_extra_regs
-				[PERF_COUNT_HW_CACHE_MAX]
-				[PERF_COUNT_HW_CACHE_OP_MAX]
-				[PERF_COUNT_HW_CACHE_RESULT_MAX] =
-{
- [ C(LL  ) ] = {
-	[ C(OP_READ) ] = {
-		[ C(RESULT_ACCESS) ] = SKL_DEMAND_READ|
-				       SKL_LLC_ACCESS|SKL_ANY_SNOOP,
-		[ C(RESULT_MISS)   ] = SKL_DEMAND_READ|
-				       SKL_L3_MISS|SKL_ANY_SNOOP|
-				       SKL_SUPPLIER_NONE,
-	},
-	[ C(OP_WRITE) ] = {
-		[ C(RESULT_ACCESS) ] = SKL_DEMAND_WRITE|
-				       SKL_LLC_ACCESS|SKL_ANY_SNOOP,
-		[ C(RESULT_MISS)   ] = SKL_DEMAND_WRITE|
-				       SKL_L3_MISS|SKL_ANY_SNOOP|
-				       SKL_SUPPLIER_NONE,
-	},
-	[ C(OP_PREFETCH) ] = {
-		[ C(RESULT_ACCESS) ] = 0x0,
-		[ C(RESULT_MISS)   ] = 0x0,
-	},
- },
- [ C(NODE) ] = {
-	[ C(OP_READ) ] = {
-		[ C(RESULT_ACCESS) ] = SKL_DEMAND_READ|
-				       SKL_L3_MISS_LOCAL_DRAM|SKL_SNOOP_DRAM,
-		[ C(RESULT_MISS)   ] = SKL_DEMAND_READ|
-				       SKL_L3_MISS_REMOTE|SKL_SNOOP_DRAM,
-	},
-	[ C(OP_WRITE) ] = {
-		[ C(RESULT_ACCESS) ] = SKL_DEMAND_WRITE|
-				       SKL_L3_MISS_LOCAL_DRAM|SKL_SNOOP_DRAM,
-		[ C(RESULT_MISS)   ] = SKL_DEMAND_WRITE|
-				       SKL_L3_MISS_REMOTE|SKL_SNOOP_DRAM,
-	},
-	[ C(OP_PREFETCH) ] = {
-		[ C(RESULT_ACCESS) ] = 0x0,
-		[ C(RESULT_MISS)   ] = 0x0,
-	},
- },
-};
-
-#define SNB_DMND_DATA_RD	(1ULL << 0)
-#define SNB_DMND_RFO		(1ULL << 1)
-#define SNB_DMND_IFETCH		(1ULL << 2)
-#define SNB_DMND_WB		(1ULL << 3)
-#define SNB_PF_DATA_RD		(1ULL << 4)
-#define SNB_PF_RFO		(1ULL << 5)
-#define SNB_PF_IFETCH		(1ULL << 6)
-#define SNB_LLC_DATA_RD		(1ULL << 7)
-#define SNB_LLC_RFO		(1ULL << 8)
-#define SNB_LLC_IFETCH		(1ULL << 9)
-#define SNB_BUS_LOCKS		(1ULL << 10)
-#define SNB_STRM_ST		(1ULL << 11)
-#define SNB_OTHER		(1ULL << 15)
-#define SNB_RESP_ANY		(1ULL << 16)
-#define SNB_NO_SUPP		(1ULL << 17)
-#define SNB_LLC_HITM		(1ULL << 18)
-#define SNB_LLC_HITE		(1ULL << 19)
-#define SNB_LLC_HITS		(1ULL << 20)
-#define SNB_LLC_HITF		(1ULL << 21)
-#define SNB_LOCAL		(1ULL << 22)
-#define SNB_REMOTE		(0xffULL << 23)
-#define SNB_SNP_NONE		(1ULL << 31)
-#define SNB_SNP_NOT_NEEDED	(1ULL << 32)
-#define SNB_SNP_MISS		(1ULL << 33)
-#define SNB_NO_FWD		(1ULL << 34)
-#define SNB_SNP_FWD		(1ULL << 35)
-#define SNB_HITM		(1ULL << 36)
-#define SNB_NON_DRAM		(1ULL << 37)
-
-#define SNB_DMND_READ		(SNB_DMND_DATA_RD|SNB_LLC_DATA_RD)
-#define SNB_DMND_WRITE		(SNB_DMND_RFO|SNB_LLC_RFO)
-#define SNB_DMND_PREFETCH	(SNB_PF_DATA_RD|SNB_PF_RFO)
-
-#define SNB_SNP_ANY		(SNB_SNP_NONE|SNB_SNP_NOT_NEEDED| \
-				 SNB_SNP_MISS|SNB_NO_FWD|SNB_SNP_FWD| \
-				 SNB_HITM)
-
-#define SNB_DRAM_ANY		(SNB_LOCAL|SNB_REMOTE|SNB_SNP_ANY)
-#define SNB_DRAM_REMOTE		(SNB_REMOTE|SNB_SNP_ANY)
-
-#define SNB_L3_ACCESS		SNB_RESP_ANY
-#define SNB_L3_MISS		(SNB_DRAM_ANY|SNB_NON_DRAM)
-
-static __initconst const u64 snb_hw_cache_extra_regs
-				[PERF_COUNT_HW_CACHE_MAX]
-				[PERF_COUNT_HW_CACHE_OP_MAX]
-				[PERF_COUNT_HW_CACHE_RESULT_MAX] =
-{
- [ C(LL  ) ] = {
-	[ C(OP_READ) ] = {
-		[ C(RESULT_ACCESS) ] = SNB_DMND_READ|SNB_L3_ACCESS,
-		[ C(RESULT_MISS)   ] = SNB_DMND_READ|SNB_L3_MISS,
-	},
-	[ C(OP_WRITE) ] = {
-		[ C(RESULT_ACCESS) ] = SNB_DMND_WRITE|SNB_L3_ACCESS,
-		[ C(RESULT_MISS)   ] = SNB_DMND_WRITE|SNB_L3_MISS,
-	},
-	[ C(OP_PREFETCH) ] = {
-		[ C(RESULT_ACCESS) ] = SNB_DMND_PREFETCH|SNB_L3_ACCESS,
-		[ C(RESULT_MISS)   ] = SNB_DMND_PREFETCH|SNB_L3_MISS,
-	},
- },
- [ C(NODE) ] = {
-	[ C(OP_READ) ] = {
-		[ C(RESULT_ACCESS) ] = SNB_DMND_READ|SNB_DRAM_ANY,
-		[ C(RESULT_MISS)   ] = SNB_DMND_READ|SNB_DRAM_REMOTE,
-	},
-	[ C(OP_WRITE) ] = {
-		[ C(RESULT_ACCESS) ] = SNB_DMND_WRITE|SNB_DRAM_ANY,
-		[ C(RESULT_MISS)   ] = SNB_DMND_WRITE|SNB_DRAM_REMOTE,
-	},
-	[ C(OP_PREFETCH) ] = {
-		[ C(RESULT_ACCESS) ] = SNB_DMND_PREFETCH|SNB_DRAM_ANY,
-		[ C(RESULT_MISS)   ] = SNB_DMND_PREFETCH|SNB_DRAM_REMOTE,
-	},
- },
-};
-
-static __initconst const u64 snb_hw_cache_event_ids
-				[PERF_COUNT_HW_CACHE_MAX]
-				[PERF_COUNT_HW_CACHE_OP_MAX]
-				[PERF_COUNT_HW_CACHE_RESULT_MAX] =
-{
- [ C(L1D) ] = {
-	[ C(OP_READ) ] = {
-		[ C(RESULT_ACCESS) ] = 0xf1d0, /* MEM_UOP_RETIRED.LOADS        */
-		[ C(RESULT_MISS)   ] = 0x0151, /* L1D.REPLACEMENT              */
-	},
-	[ C(OP_WRITE) ] = {
-		[ C(RESULT_ACCESS) ] = 0xf2d0, /* MEM_UOP_RETIRED.STORES       */
-		[ C(RESULT_MISS)   ] = 0x0851, /* L1D.ALL_M_REPLACEMENT        */
-	},
-	[ C(OP_PREFETCH) ] = {
-		[ C(RESULT_ACCESS) ] = 0x0,
-		[ C(RESULT_MISS)   ] = 0x024e, /* HW_PRE_REQ.DL1_MISS          */
-	},
- },
- [ C(L1I ) ] = {
-	[ C(OP_READ) ] = {
-		[ C(RESULT_ACCESS) ] = 0x0,
-		[ C(RESULT_MISS)   ] = 0x0280, /* ICACHE.MISSES */
-	},
-	[ C(OP_WRITE) ] = {
-		[ C(RESULT_ACCESS) ] = -1,
-		[ C(RESULT_MISS)   ] = -1,
-	},
-	[ C(OP_PREFETCH) ] = {
-		[ C(RESULT_ACCESS) ] = 0x0,
-		[ C(RESULT_MISS)   ] = 0x0,
-	},
- },
- [ C(LL  ) ] = {
-	[ C(OP_READ) ] = {
-		/* OFFCORE_RESPONSE.ANY_DATA.LOCAL_CACHE */
-		[ C(RESULT_ACCESS) ] = 0x01b7,
-		/* OFFCORE_RESPONSE.ANY_DATA.ANY_LLC_MISS */
-		[ C(RESULT_MISS)   ] = 0x01b7,
-	},
-	[ C(OP_WRITE) ] = {
-		/* OFFCORE_RESPONSE.ANY_RFO.LOCAL_CACHE */
-		[ C(RESULT_ACCESS) ] = 0x01b7,
-		/* OFFCORE_RESPONSE.ANY_RFO.ANY_LLC_MISS */
-		[ C(RESULT_MISS)   ] = 0x01b7,
-	},
-	[ C(OP_PREFETCH) ] = {
-		/* OFFCORE_RESPONSE.PREFETCH.LOCAL_CACHE */
-		[ C(RESULT_ACCESS) ] = 0x01b7,
-		/* OFFCORE_RESPONSE.PREFETCH.ANY_LLC_MISS */
-		[ C(RESULT_MISS)   ] = 0x01b7,
-	},
- },
- [ C(DTLB) ] = {
-	[ C(OP_READ) ] = {
-		[ C(RESULT_ACCESS) ] = 0x81d0, /* MEM_UOP_RETIRED.ALL_LOADS */
-		[ C(RESULT_MISS)   ] = 0x0108, /* DTLB_LOAD_MISSES.CAUSES_A_WALK */
-	},
-	[ C(OP_WRITE) ] = {
-		[ C(RESULT_ACCESS) ] = 0x82d0, /* MEM_UOP_RETIRED.ALL_STORES */
-		[ C(RESULT_MISS)   ] = 0x0149, /* DTLB_STORE_MISSES.MISS_CAUSES_A_WALK */
-	},
-	[ C(OP_PREFETCH) ] = {
-		[ C(RESULT_ACCESS) ] = 0x0,
-		[ C(RESULT_MISS)   ] = 0x0,
-	},
- },
- [ C(ITLB) ] = {
-	[ C(OP_READ) ] = {
-		[ C(RESULT_ACCESS) ] = 0x1085, /* ITLB_MISSES.STLB_HIT         */
-		[ C(RESULT_MISS)   ] = 0x0185, /* ITLB_MISSES.CAUSES_A_WALK    */
-	},
-	[ C(OP_WRITE) ] = {
-		[ C(RESULT_ACCESS) ] = -1,
-		[ C(RESULT_MISS)   ] = -1,
-	},
-	[ C(OP_PREFETCH) ] = {
-		[ C(RESULT_ACCESS) ] = -1,
-		[ C(RESULT_MISS)   ] = -1,
-	},
- },
- [ C(BPU ) ] = {
-	[ C(OP_READ) ] = {
-		[ C(RESULT_ACCESS) ] = 0x00c4, /* BR_INST_RETIRED.ALL_BRANCHES */
-		[ C(RESULT_MISS)   ] = 0x00c5, /* BR_MISP_RETIRED.ALL_BRANCHES */
-	},
-	[ C(OP_WRITE) ] = {
-		[ C(RESULT_ACCESS) ] = -1,
-		[ C(RESULT_MISS)   ] = -1,
-	},
-	[ C(OP_PREFETCH) ] = {
-		[ C(RESULT_ACCESS) ] = -1,
-		[ C(RESULT_MISS)   ] = -1,
-	},
- },
- [ C(NODE) ] = {
-	[ C(OP_READ) ] = {
-		[ C(RESULT_ACCESS) ] = 0x01b7,
-		[ C(RESULT_MISS)   ] = 0x01b7,
-	},
-	[ C(OP_WRITE) ] = {
-		[ C(RESULT_ACCESS) ] = 0x01b7,
-		[ C(RESULT_MISS)   ] = 0x01b7,
-	},
-	[ C(OP_PREFETCH) ] = {
-		[ C(RESULT_ACCESS) ] = 0x01b7,
-		[ C(RESULT_MISS)   ] = 0x01b7,
-	},
- },
-
-};
-
-/*
- * Notes on the events:
- * - data reads do not include code reads (comparable to earlier tables)
- * - data counts include speculative execution (except L1 write, dtlb, bpu)
- * - remote node access includes remote memory, remote cache, remote mmio.
- * - prefetches are not included in the counts because they are not
- *   reliably counted.
- */
-
-#define HSW_DEMAND_DATA_RD		BIT_ULL(0)
-#define HSW_DEMAND_RFO			BIT_ULL(1)
-#define HSW_ANY_RESPONSE		BIT_ULL(16)
-#define HSW_SUPPLIER_NONE		BIT_ULL(17)
-#define HSW_L3_MISS_LOCAL_DRAM		BIT_ULL(22)
-#define HSW_L3_MISS_REMOTE_HOP0		BIT_ULL(27)
-#define HSW_L3_MISS_REMOTE_HOP1		BIT_ULL(28)
-#define HSW_L3_MISS_REMOTE_HOP2P	BIT_ULL(29)
-#define HSW_L3_MISS			(HSW_L3_MISS_LOCAL_DRAM| \
-					 HSW_L3_MISS_REMOTE_HOP0|HSW_L3_MISS_REMOTE_HOP1| \
-					 HSW_L3_MISS_REMOTE_HOP2P)
-#define HSW_SNOOP_NONE			BIT_ULL(31)
-#define HSW_SNOOP_NOT_NEEDED		BIT_ULL(32)
-#define HSW_SNOOP_MISS			BIT_ULL(33)
-#define HSW_SNOOP_HIT_NO_FWD		BIT_ULL(34)
-#define HSW_SNOOP_HIT_WITH_FWD		BIT_ULL(35)
-#define HSW_SNOOP_HITM			BIT_ULL(36)
-#define HSW_SNOOP_NON_DRAM		BIT_ULL(37)
-#define HSW_ANY_SNOOP			(HSW_SNOOP_NONE| \
-					 HSW_SNOOP_NOT_NEEDED|HSW_SNOOP_MISS| \
-					 HSW_SNOOP_HIT_NO_FWD|HSW_SNOOP_HIT_WITH_FWD| \
-					 HSW_SNOOP_HITM|HSW_SNOOP_NON_DRAM)
-#define HSW_SNOOP_DRAM			(HSW_ANY_SNOOP & ~HSW_SNOOP_NON_DRAM)
-#define HSW_DEMAND_READ			HSW_DEMAND_DATA_RD
-#define HSW_DEMAND_WRITE		HSW_DEMAND_RFO
-#define HSW_L3_MISS_REMOTE		(HSW_L3_MISS_REMOTE_HOP0|\
-					 HSW_L3_MISS_REMOTE_HOP1|HSW_L3_MISS_REMOTE_HOP2P)
-#define HSW_LLC_ACCESS			HSW_ANY_RESPONSE
-
-#define BDW_L3_MISS_LOCAL		BIT(26)
-#define BDW_L3_MISS			(BDW_L3_MISS_LOCAL| \
-					 HSW_L3_MISS_REMOTE_HOP0|HSW_L3_MISS_REMOTE_HOP1| \
-					 HSW_L3_MISS_REMOTE_HOP2P)
-
-
-static __initconst const u64 hsw_hw_cache_event_ids
-				[PERF_COUNT_HW_CACHE_MAX]
-				[PERF_COUNT_HW_CACHE_OP_MAX]
-				[PERF_COUNT_HW_CACHE_RESULT_MAX] =
-{
- [ C(L1D ) ] = {
-	[ C(OP_READ) ] = {
-		[ C(RESULT_ACCESS) ] = 0x81d0,	/* MEM_UOPS_RETIRED.ALL_LOADS */
-		[ C(RESULT_MISS)   ] = 0x151,	/* L1D.REPLACEMENT */
-	},
-	[ C(OP_WRITE) ] = {
-		[ C(RESULT_ACCESS) ] = 0x82d0,	/* MEM_UOPS_RETIRED.ALL_STORES */
-		[ C(RESULT_MISS)   ] = 0x0,
-	},
-	[ C(OP_PREFETCH) ] = {
-		[ C(RESULT_ACCESS) ] = 0x0,
-		[ C(RESULT_MISS)   ] = 0x0,
-	},
- },
- [ C(L1I ) ] = {
-	[ C(OP_READ) ] = {
-		[ C(RESULT_ACCESS) ] = 0x0,
-		[ C(RESULT_MISS)   ] = 0x280,	/* ICACHE.MISSES */
-	},
-	[ C(OP_WRITE) ] = {
-		[ C(RESULT_ACCESS) ] = -1,
-		[ C(RESULT_MISS)   ] = -1,
-	},
-	[ C(OP_PREFETCH) ] = {
-		[ C(RESULT_ACCESS) ] = 0x0,
-		[ C(RESULT_MISS)   ] = 0x0,
-	},
- },
- [ C(LL  ) ] = {
-	[ C(OP_READ) ] = {
-		[ C(RESULT_ACCESS) ] = 0x1b7,	/* OFFCORE_RESPONSE */
-		[ C(RESULT_MISS)   ] = 0x1b7,	/* OFFCORE_RESPONSE */
-	},
-	[ C(OP_WRITE) ] = {
-		[ C(RESULT_ACCESS) ] = 0x1b7,	/* OFFCORE_RESPONSE */
-		[ C(RESULT_MISS)   ] = 0x1b7,	/* OFFCORE_RESPONSE */
-	},
-	[ C(OP_PREFETCH) ] = {
-		[ C(RESULT_ACCESS) ] = 0x0,
-		[ C(RESULT_MISS)   ] = 0x0,
-	},
- },
- [ C(DTLB) ] = {
-	[ C(OP_READ) ] = {
-		[ C(RESULT_ACCESS) ] = 0x81d0,	/* MEM_UOPS_RETIRED.ALL_LOADS */
-		[ C(RESULT_MISS)   ] = 0x108,	/* DTLB_LOAD_MISSES.MISS_CAUSES_A_WALK */
-	},
-	[ C(OP_WRITE) ] = {
-		[ C(RESULT_ACCESS) ] = 0x82d0,	/* MEM_UOPS_RETIRED.ALL_STORES */
-		[ C(RESULT_MISS)   ] = 0x149,	/* DTLB_STORE_MISSES.MISS_CAUSES_A_WALK */
-	},
-	[ C(OP_PREFETCH) ] = {
-		[ C(RESULT_ACCESS) ] = 0x0,
-		[ C(RESULT_MISS)   ] = 0x0,
-	},
- },
- [ C(ITLB) ] = {
-	[ C(OP_READ) ] = {
-		[ C(RESULT_ACCESS) ] = 0x6085,	/* ITLB_MISSES.STLB_HIT */
-		[ C(RESULT_MISS)   ] = 0x185,	/* ITLB_MISSES.MISS_CAUSES_A_WALK */
-	},
-	[ C(OP_WRITE) ] = {
-		[ C(RESULT_ACCESS) ] = -1,
-		[ C(RESULT_MISS)   ] = -1,
-	},
-	[ C(OP_PREFETCH) ] = {
-		[ C(RESULT_ACCESS) ] = -1,
-		[ C(RESULT_MISS)   ] = -1,
-	},
- },
- [ C(BPU ) ] = {
-	[ C(OP_READ) ] = {
-		[ C(RESULT_ACCESS) ] = 0xc4,	/* BR_INST_RETIRED.ALL_BRANCHES */
-		[ C(RESULT_MISS)   ] = 0xc5,	/* BR_MISP_RETIRED.ALL_BRANCHES */
-	},
-	[ C(OP_WRITE) ] = {
-		[ C(RESULT_ACCESS) ] = -1,
-		[ C(RESULT_MISS)   ] = -1,
-	},
-	[ C(OP_PREFETCH) ] = {
-		[ C(RESULT_ACCESS) ] = -1,
-		[ C(RESULT_MISS)   ] = -1,
-	},
- },
- [ C(NODE) ] = {
-	[ C(OP_READ) ] = {
-		[ C(RESULT_ACCESS) ] = 0x1b7,	/* OFFCORE_RESPONSE */
-		[ C(RESULT_MISS)   ] = 0x1b7,	/* OFFCORE_RESPONSE */
-	},
-	[ C(OP_WRITE) ] = {
-		[ C(RESULT_ACCESS) ] = 0x1b7,	/* OFFCORE_RESPONSE */
-		[ C(RESULT_MISS)   ] = 0x1b7,	/* OFFCORE_RESPONSE */
-	},
-	[ C(OP_PREFETCH) ] = {
-		[ C(RESULT_ACCESS) ] = 0x0,
-		[ C(RESULT_MISS)   ] = 0x0,
-	},
- },
-};
-
-static __initconst const u64 hsw_hw_cache_extra_regs
-				[PERF_COUNT_HW_CACHE_MAX]
-				[PERF_COUNT_HW_CACHE_OP_MAX]
-				[PERF_COUNT_HW_CACHE_RESULT_MAX] =
-{
- [ C(LL  ) ] = {
-	[ C(OP_READ) ] = {
-		[ C(RESULT_ACCESS) ] = HSW_DEMAND_READ|
-				       HSW_LLC_ACCESS,
-		[ C(RESULT_MISS)   ] = HSW_DEMAND_READ|
-				       HSW_L3_MISS|HSW_ANY_SNOOP,
-	},
-	[ C(OP_WRITE) ] = {
-		[ C(RESULT_ACCESS) ] = HSW_DEMAND_WRITE|
-				       HSW_LLC_ACCESS,
-		[ C(RESULT_MISS)   ] = HSW_DEMAND_WRITE|
-				       HSW_L3_MISS|HSW_ANY_SNOOP,
-	},
-	[ C(OP_PREFETCH) ] = {
-		[ C(RESULT_ACCESS) ] = 0x0,
-		[ C(RESULT_MISS)   ] = 0x0,
-	},
- },
- [ C(NODE) ] = {
-	[ C(OP_READ) ] = {
-		[ C(RESULT_ACCESS) ] = HSW_DEMAND_READ|
-				       HSW_L3_MISS_LOCAL_DRAM|
-				       HSW_SNOOP_DRAM,
-		[ C(RESULT_MISS)   ] = HSW_DEMAND_READ|
-				       HSW_L3_MISS_REMOTE|
-				       HSW_SNOOP_DRAM,
-	},
-	[ C(OP_WRITE) ] = {
-		[ C(RESULT_ACCESS) ] = HSW_DEMAND_WRITE|
-				       HSW_L3_MISS_LOCAL_DRAM|
-				       HSW_SNOOP_DRAM,
-		[ C(RESULT_MISS)   ] = HSW_DEMAND_WRITE|
-				       HSW_L3_MISS_REMOTE|
-				       HSW_SNOOP_DRAM,
-	},
-	[ C(OP_PREFETCH) ] = {
-		[ C(RESULT_ACCESS) ] = 0x0,
-		[ C(RESULT_MISS)   ] = 0x0,
-	},
- },
-};
-
-static __initconst const u64 westmere_hw_cache_event_ids
-				[PERF_COUNT_HW_CACHE_MAX]
-				[PERF_COUNT_HW_CACHE_OP_MAX]
-				[PERF_COUNT_HW_CACHE_RESULT_MAX] =
-{
- [ C(L1D) ] = {
-	[ C(OP_READ) ] = {
-		[ C(RESULT_ACCESS) ] = 0x010b, /* MEM_INST_RETIRED.LOADS       */
-		[ C(RESULT_MISS)   ] = 0x0151, /* L1D.REPL                     */
-	},
-	[ C(OP_WRITE) ] = {
-		[ C(RESULT_ACCESS) ] = 0x020b, /* MEM_INST_RETURED.STORES      */
-		[ C(RESULT_MISS)   ] = 0x0251, /* L1D.M_REPL                   */
-	},
-	[ C(OP_PREFETCH) ] = {
-		[ C(RESULT_ACCESS) ] = 0x014e, /* L1D_PREFETCH.REQUESTS        */
-		[ C(RESULT_MISS)   ] = 0x024e, /* L1D_PREFETCH.MISS            */
-	},
- },
- [ C(L1I ) ] = {
-	[ C(OP_READ) ] = {
-		[ C(RESULT_ACCESS) ] = 0x0380, /* L1I.READS                    */
-		[ C(RESULT_MISS)   ] = 0x0280, /* L1I.MISSES                   */
-	},
-	[ C(OP_WRITE) ] = {
-		[ C(RESULT_ACCESS) ] = -1,
-		[ C(RESULT_MISS)   ] = -1,
-	},
-	[ C(OP_PREFETCH) ] = {
-		[ C(RESULT_ACCESS) ] = 0x0,
-		[ C(RESULT_MISS)   ] = 0x0,
-	},
- },
- [ C(LL  ) ] = {
-	[ C(OP_READ) ] = {
-		/* OFFCORE_RESPONSE.ANY_DATA.LOCAL_CACHE */
-		[ C(RESULT_ACCESS) ] = 0x01b7,
-		/* OFFCORE_RESPONSE.ANY_DATA.ANY_LLC_MISS */
-		[ C(RESULT_MISS)   ] = 0x01b7,
-	},
-	/*
-	 * Use RFO, not WRITEBACK, because a write miss would typically occur
-	 * on RFO.
-	 */
-	[ C(OP_WRITE) ] = {
-		/* OFFCORE_RESPONSE.ANY_RFO.LOCAL_CACHE */
-		[ C(RESULT_ACCESS) ] = 0x01b7,
-		/* OFFCORE_RESPONSE.ANY_RFO.ANY_LLC_MISS */
-		[ C(RESULT_MISS)   ] = 0x01b7,
-	},
-	[ C(OP_PREFETCH) ] = {
-		/* OFFCORE_RESPONSE.PREFETCH.LOCAL_CACHE */
-		[ C(RESULT_ACCESS) ] = 0x01b7,
-		/* OFFCORE_RESPONSE.PREFETCH.ANY_LLC_MISS */
-		[ C(RESULT_MISS)   ] = 0x01b7,
-	},
- },
- [ C(DTLB) ] = {
-	[ C(OP_READ) ] = {
-		[ C(RESULT_ACCESS) ] = 0x010b, /* MEM_INST_RETIRED.LOADS       */
-		[ C(RESULT_MISS)   ] = 0x0108, /* DTLB_LOAD_MISSES.ANY         */
-	},
-	[ C(OP_WRITE) ] = {
-		[ C(RESULT_ACCESS) ] = 0x020b, /* MEM_INST_RETURED.STORES      */
-		[ C(RESULT_MISS)   ] = 0x010c, /* MEM_STORE_RETIRED.DTLB_MISS  */
-	},
-	[ C(OP_PREFETCH) ] = {
-		[ C(RESULT_ACCESS) ] = 0x0,
-		[ C(RESULT_MISS)   ] = 0x0,
-	},
- },
- [ C(ITLB) ] = {
-	[ C(OP_READ) ] = {
-		[ C(RESULT_ACCESS) ] = 0x01c0, /* INST_RETIRED.ANY_P           */
-		[ C(RESULT_MISS)   ] = 0x0185, /* ITLB_MISSES.ANY              */
-	},
-	[ C(OP_WRITE) ] = {
-		[ C(RESULT_ACCESS) ] = -1,
-		[ C(RESULT_MISS)   ] = -1,
-	},
-	[ C(OP_PREFETCH) ] = {
-		[ C(RESULT_ACCESS) ] = -1,
-		[ C(RESULT_MISS)   ] = -1,
-	},
- },
- [ C(BPU ) ] = {
-	[ C(OP_READ) ] = {
-		[ C(RESULT_ACCESS) ] = 0x00c4, /* BR_INST_RETIRED.ALL_BRANCHES */
-		[ C(RESULT_MISS)   ] = 0x03e8, /* BPU_CLEARS.ANY               */
-	},
-	[ C(OP_WRITE) ] = {
-		[ C(RESULT_ACCESS) ] = -1,
-		[ C(RESULT_MISS)   ] = -1,
-	},
-	[ C(OP_PREFETCH) ] = {
-		[ C(RESULT_ACCESS) ] = -1,
-		[ C(RESULT_MISS)   ] = -1,
-	},
- },
- [ C(NODE) ] = {
-	[ C(OP_READ) ] = {
-		[ C(RESULT_ACCESS) ] = 0x01b7,
-		[ C(RESULT_MISS)   ] = 0x01b7,
-	},
-	[ C(OP_WRITE) ] = {
-		[ C(RESULT_ACCESS) ] = 0x01b7,
-		[ C(RESULT_MISS)   ] = 0x01b7,
-	},
-	[ C(OP_PREFETCH) ] = {
-		[ C(RESULT_ACCESS) ] = 0x01b7,
-		[ C(RESULT_MISS)   ] = 0x01b7,
-	},
- },
-};
-
-/*
- * Nehalem/Westmere MSR_OFFCORE_RESPONSE bits;
- * See IA32 SDM Vol 3B 30.6.1.3
- */
-
-#define NHM_DMND_DATA_RD	(1 << 0)
-#define NHM_DMND_RFO		(1 << 1)
-#define NHM_DMND_IFETCH		(1 << 2)
-#define NHM_DMND_WB		(1 << 3)
-#define NHM_PF_DATA_RD		(1 << 4)
-#define NHM_PF_DATA_RFO		(1 << 5)
-#define NHM_PF_IFETCH		(1 << 6)
-#define NHM_OFFCORE_OTHER	(1 << 7)
-#define NHM_UNCORE_HIT		(1 << 8)
-#define NHM_OTHER_CORE_HIT_SNP	(1 << 9)
-#define NHM_OTHER_CORE_HITM	(1 << 10)
-        			/* reserved */
-#define NHM_REMOTE_CACHE_FWD	(1 << 12)
-#define NHM_REMOTE_DRAM		(1 << 13)
-#define NHM_LOCAL_DRAM		(1 << 14)
-#define NHM_NON_DRAM		(1 << 15)
-
-#define NHM_LOCAL		(NHM_LOCAL_DRAM|NHM_REMOTE_CACHE_FWD)
-#define NHM_REMOTE		(NHM_REMOTE_DRAM)
-
-#define NHM_DMND_READ		(NHM_DMND_DATA_RD)
-#define NHM_DMND_WRITE		(NHM_DMND_RFO|NHM_DMND_WB)
-#define NHM_DMND_PREFETCH	(NHM_PF_DATA_RD|NHM_PF_DATA_RFO)
-
-#define NHM_L3_HIT	(NHM_UNCORE_HIT|NHM_OTHER_CORE_HIT_SNP|NHM_OTHER_CORE_HITM)
-#define NHM_L3_MISS	(NHM_NON_DRAM|NHM_LOCAL_DRAM|NHM_REMOTE_DRAM|NHM_REMOTE_CACHE_FWD)
-#define NHM_L3_ACCESS	(NHM_L3_HIT|NHM_L3_MISS)
-
-static __initconst const u64 nehalem_hw_cache_extra_regs
-				[PERF_COUNT_HW_CACHE_MAX]
-				[PERF_COUNT_HW_CACHE_OP_MAX]
-				[PERF_COUNT_HW_CACHE_RESULT_MAX] =
-{
- [ C(LL  ) ] = {
-	[ C(OP_READ) ] = {
-		[ C(RESULT_ACCESS) ] = NHM_DMND_READ|NHM_L3_ACCESS,
-		[ C(RESULT_MISS)   ] = NHM_DMND_READ|NHM_L3_MISS,
-	},
-	[ C(OP_WRITE) ] = {
-		[ C(RESULT_ACCESS) ] = NHM_DMND_WRITE|NHM_L3_ACCESS,
-		[ C(RESULT_MISS)   ] = NHM_DMND_WRITE|NHM_L3_MISS,
-	},
-	[ C(OP_PREFETCH) ] = {
-		[ C(RESULT_ACCESS) ] = NHM_DMND_PREFETCH|NHM_L3_ACCESS,
-		[ C(RESULT_MISS)   ] = NHM_DMND_PREFETCH|NHM_L3_MISS,
-	},
- },
- [ C(NODE) ] = {
-	[ C(OP_READ) ] = {
-		[ C(RESULT_ACCESS) ] = NHM_DMND_READ|NHM_LOCAL|NHM_REMOTE,
-		[ C(RESULT_MISS)   ] = NHM_DMND_READ|NHM_REMOTE,
-	},
-	[ C(OP_WRITE) ] = {
-		[ C(RESULT_ACCESS) ] = NHM_DMND_WRITE|NHM_LOCAL|NHM_REMOTE,
-		[ C(RESULT_MISS)   ] = NHM_DMND_WRITE|NHM_REMOTE,
-	},
-	[ C(OP_PREFETCH) ] = {
-		[ C(RESULT_ACCESS) ] = NHM_DMND_PREFETCH|NHM_LOCAL|NHM_REMOTE,
-		[ C(RESULT_MISS)   ] = NHM_DMND_PREFETCH|NHM_REMOTE,
-	},
- },
-};
-
-static __initconst const u64 nehalem_hw_cache_event_ids
-				[PERF_COUNT_HW_CACHE_MAX]
-				[PERF_COUNT_HW_CACHE_OP_MAX]
-				[PERF_COUNT_HW_CACHE_RESULT_MAX] =
-{
- [ C(L1D) ] = {
-	[ C(OP_READ) ] = {
-		[ C(RESULT_ACCESS) ] = 0x010b, /* MEM_INST_RETIRED.LOADS       */
-		[ C(RESULT_MISS)   ] = 0x0151, /* L1D.REPL                     */
-	},
-	[ C(OP_WRITE) ] = {
-		[ C(RESULT_ACCESS) ] = 0x020b, /* MEM_INST_RETURED.STORES      */
-		[ C(RESULT_MISS)   ] = 0x0251, /* L1D.M_REPL                   */
-	},
-	[ C(OP_PREFETCH) ] = {
-		[ C(RESULT_ACCESS) ] = 0x014e, /* L1D_PREFETCH.REQUESTS        */
-		[ C(RESULT_MISS)   ] = 0x024e, /* L1D_PREFETCH.MISS            */
-	},
- },
- [ C(L1I ) ] = {
-	[ C(OP_READ) ] = {
-		[ C(RESULT_ACCESS) ] = 0x0380, /* L1I.READS                    */
-		[ C(RESULT_MISS)   ] = 0x0280, /* L1I.MISSES                   */
-	},
-	[ C(OP_WRITE) ] = {
-		[ C(RESULT_ACCESS) ] = -1,
-		[ C(RESULT_MISS)   ] = -1,
-	},
-	[ C(OP_PREFETCH) ] = {
-		[ C(RESULT_ACCESS) ] = 0x0,
-		[ C(RESULT_MISS)   ] = 0x0,
-	},
- },
- [ C(LL  ) ] = {
-	[ C(OP_READ) ] = {
-		/* OFFCORE_RESPONSE.ANY_DATA.LOCAL_CACHE */
-		[ C(RESULT_ACCESS) ] = 0x01b7,
-		/* OFFCORE_RESPONSE.ANY_DATA.ANY_LLC_MISS */
-		[ C(RESULT_MISS)   ] = 0x01b7,
-	},
-	/*
-	 * Use RFO, not WRITEBACK, because a write miss would typically occur
-	 * on RFO.
-	 */
-	[ C(OP_WRITE) ] = {
-		/* OFFCORE_RESPONSE.ANY_RFO.LOCAL_CACHE */
-		[ C(RESULT_ACCESS) ] = 0x01b7,
-		/* OFFCORE_RESPONSE.ANY_RFO.ANY_LLC_MISS */
-		[ C(RESULT_MISS)   ] = 0x01b7,
-	},
-	[ C(OP_PREFETCH) ] = {
-		/* OFFCORE_RESPONSE.PREFETCH.LOCAL_CACHE */
-		[ C(RESULT_ACCESS) ] = 0x01b7,
-		/* OFFCORE_RESPONSE.PREFETCH.ANY_LLC_MISS */
-		[ C(RESULT_MISS)   ] = 0x01b7,
-	},
- },
- [ C(DTLB) ] = {
-	[ C(OP_READ) ] = {
-		[ C(RESULT_ACCESS) ] = 0x0f40, /* L1D_CACHE_LD.MESI   (alias)  */
-		[ C(RESULT_MISS)   ] = 0x0108, /* DTLB_LOAD_MISSES.ANY         */
-	},
-	[ C(OP_WRITE) ] = {
-		[ C(RESULT_ACCESS) ] = 0x0f41, /* L1D_CACHE_ST.MESI   (alias)  */
-		[ C(RESULT_MISS)   ] = 0x010c, /* MEM_STORE_RETIRED.DTLB_MISS  */
-	},
-	[ C(OP_PREFETCH) ] = {
-		[ C(RESULT_ACCESS) ] = 0x0,
-		[ C(RESULT_MISS)   ] = 0x0,
-	},
- },
- [ C(ITLB) ] = {
-	[ C(OP_READ) ] = {
-		[ C(RESULT_ACCESS) ] = 0x01c0, /* INST_RETIRED.ANY_P           */
-		[ C(RESULT_MISS)   ] = 0x20c8, /* ITLB_MISS_RETIRED            */
-	},
-	[ C(OP_WRITE) ] = {
-		[ C(RESULT_ACCESS) ] = -1,
-		[ C(RESULT_MISS)   ] = -1,
-	},
-	[ C(OP_PREFETCH) ] = {
-		[ C(RESULT_ACCESS) ] = -1,
-		[ C(RESULT_MISS)   ] = -1,
-	},
- },
- [ C(BPU ) ] = {
-	[ C(OP_READ) ] = {
-		[ C(RESULT_ACCESS) ] = 0x00c4, /* BR_INST_RETIRED.ALL_BRANCHES */
-		[ C(RESULT_MISS)   ] = 0x03e8, /* BPU_CLEARS.ANY               */
-	},
-	[ C(OP_WRITE) ] = {
-		[ C(RESULT_ACCESS) ] = -1,
-		[ C(RESULT_MISS)   ] = -1,
-	},
-	[ C(OP_PREFETCH) ] = {
-		[ C(RESULT_ACCESS) ] = -1,
-		[ C(RESULT_MISS)   ] = -1,
-	},
- },
- [ C(NODE) ] = {
-	[ C(OP_READ) ] = {
-		[ C(RESULT_ACCESS) ] = 0x01b7,
-		[ C(RESULT_MISS)   ] = 0x01b7,
-	},
-	[ C(OP_WRITE) ] = {
-		[ C(RESULT_ACCESS) ] = 0x01b7,
-		[ C(RESULT_MISS)   ] = 0x01b7,
-	},
-	[ C(OP_PREFETCH) ] = {
-		[ C(RESULT_ACCESS) ] = 0x01b7,
-		[ C(RESULT_MISS)   ] = 0x01b7,
-	},
- },
-};
-
-static __initconst const u64 core2_hw_cache_event_ids
-				[PERF_COUNT_HW_CACHE_MAX]
-				[PERF_COUNT_HW_CACHE_OP_MAX]
-				[PERF_COUNT_HW_CACHE_RESULT_MAX] =
-{
- [ C(L1D) ] = {
-	[ C(OP_READ) ] = {
-		[ C(RESULT_ACCESS) ] = 0x0f40, /* L1D_CACHE_LD.MESI          */
-		[ C(RESULT_MISS)   ] = 0x0140, /* L1D_CACHE_LD.I_STATE       */
-	},
-	[ C(OP_WRITE) ] = {
-		[ C(RESULT_ACCESS) ] = 0x0f41, /* L1D_CACHE_ST.MESI          */
-		[ C(RESULT_MISS)   ] = 0x0141, /* L1D_CACHE_ST.I_STATE       */
-	},
-	[ C(OP_PREFETCH) ] = {
-		[ C(RESULT_ACCESS) ] = 0x104e, /* L1D_PREFETCH.REQUESTS      */
-		[ C(RESULT_MISS)   ] = 0,
-	},
- },
- [ C(L1I ) ] = {
-	[ C(OP_READ) ] = {
-		[ C(RESULT_ACCESS) ] = 0x0080, /* L1I.READS                  */
-		[ C(RESULT_MISS)   ] = 0x0081, /* L1I.MISSES                 */
-	},
-	[ C(OP_WRITE) ] = {
-		[ C(RESULT_ACCESS) ] = -1,
-		[ C(RESULT_MISS)   ] = -1,
-	},
-	[ C(OP_PREFETCH) ] = {
-		[ C(RESULT_ACCESS) ] = 0,
-		[ C(RESULT_MISS)   ] = 0,
-	},
- },
- [ C(LL  ) ] = {
-	[ C(OP_READ) ] = {
-		[ C(RESULT_ACCESS) ] = 0x4f29, /* L2_LD.MESI                 */
-		[ C(RESULT_MISS)   ] = 0x4129, /* L2_LD.ISTATE               */
-	},
-	[ C(OP_WRITE) ] = {
-		[ C(RESULT_ACCESS) ] = 0x4f2A, /* L2_ST.MESI                 */
-		[ C(RESULT_MISS)   ] = 0x412A, /* L2_ST.ISTATE               */
-	},
-	[ C(OP_PREFETCH) ] = {
-		[ C(RESULT_ACCESS) ] = 0,
-		[ C(RESULT_MISS)   ] = 0,
-	},
- },
- [ C(DTLB) ] = {
-	[ C(OP_READ) ] = {
-		[ C(RESULT_ACCESS) ] = 0x0f40, /* L1D_CACHE_LD.MESI  (alias) */
-		[ C(RESULT_MISS)   ] = 0x0208, /* DTLB_MISSES.MISS_LD        */
-	},
-	[ C(OP_WRITE) ] = {
-		[ C(RESULT_ACCESS) ] = 0x0f41, /* L1D_CACHE_ST.MESI  (alias) */
-		[ C(RESULT_MISS)   ] = 0x0808, /* DTLB_MISSES.MISS_ST        */
-	},
-	[ C(OP_PREFETCH) ] = {
-		[ C(RESULT_ACCESS) ] = 0,
-		[ C(RESULT_MISS)   ] = 0,
-	},
- },
- [ C(ITLB) ] = {
-	[ C(OP_READ) ] = {
-		[ C(RESULT_ACCESS) ] = 0x00c0, /* INST_RETIRED.ANY_P         */
-		[ C(RESULT_MISS)   ] = 0x1282, /* ITLBMISSES                 */
-	},
-	[ C(OP_WRITE) ] = {
-		[ C(RESULT_ACCESS) ] = -1,
-		[ C(RESULT_MISS)   ] = -1,
-	},
-	[ C(OP_PREFETCH) ] = {
-		[ C(RESULT_ACCESS) ] = -1,
-		[ C(RESULT_MISS)   ] = -1,
-	},
- },
- [ C(BPU ) ] = {
-	[ C(OP_READ) ] = {
-		[ C(RESULT_ACCESS) ] = 0x00c4, /* BR_INST_RETIRED.ANY        */
-		[ C(RESULT_MISS)   ] = 0x00c5, /* BP_INST_RETIRED.MISPRED    */
-	},
-	[ C(OP_WRITE) ] = {
-		[ C(RESULT_ACCESS) ] = -1,
-		[ C(RESULT_MISS)   ] = -1,
-	},
-	[ C(OP_PREFETCH) ] = {
-		[ C(RESULT_ACCESS) ] = -1,
-		[ C(RESULT_MISS)   ] = -1,
-	},
- },
-};
-
-static __initconst const u64 atom_hw_cache_event_ids
-				[PERF_COUNT_HW_CACHE_MAX]
-				[PERF_COUNT_HW_CACHE_OP_MAX]
-				[PERF_COUNT_HW_CACHE_RESULT_MAX] =
-{
- [ C(L1D) ] = {
-	[ C(OP_READ) ] = {
-		[ C(RESULT_ACCESS) ] = 0x2140, /* L1D_CACHE.LD               */
-		[ C(RESULT_MISS)   ] = 0,
-	},
-	[ C(OP_WRITE) ] = {
-		[ C(RESULT_ACCESS) ] = 0x2240, /* L1D_CACHE.ST               */
-		[ C(RESULT_MISS)   ] = 0,
-	},
-	[ C(OP_PREFETCH) ] = {
-		[ C(RESULT_ACCESS) ] = 0x0,
-		[ C(RESULT_MISS)   ] = 0,
-	},
- },
- [ C(L1I ) ] = {
-	[ C(OP_READ) ] = {
-		[ C(RESULT_ACCESS) ] = 0x0380, /* L1I.READS                  */
-		[ C(RESULT_MISS)   ] = 0x0280, /* L1I.MISSES                 */
-	},
-	[ C(OP_WRITE) ] = {
-		[ C(RESULT_ACCESS) ] = -1,
-		[ C(RESULT_MISS)   ] = -1,
-	},
-	[ C(OP_PREFETCH) ] = {
-		[ C(RESULT_ACCESS) ] = 0,
-		[ C(RESULT_MISS)   ] = 0,
-	},
- },
- [ C(LL  ) ] = {
-	[ C(OP_READ) ] = {
-		[ C(RESULT_ACCESS) ] = 0x4f29, /* L2_LD.MESI                 */
-		[ C(RESULT_MISS)   ] = 0x4129, /* L2_LD.ISTATE               */
-	},
-	[ C(OP_WRITE) ] = {
-		[ C(RESULT_ACCESS) ] = 0x4f2A, /* L2_ST.MESI                 */
-		[ C(RESULT_MISS)   ] = 0x412A, /* L2_ST.ISTATE               */
-	},
-	[ C(OP_PREFETCH) ] = {
-		[ C(RESULT_ACCESS) ] = 0,
-		[ C(RESULT_MISS)   ] = 0,
-	},
- },
- [ C(DTLB) ] = {
-	[ C(OP_READ) ] = {
-		[ C(RESULT_ACCESS) ] = 0x2140, /* L1D_CACHE_LD.MESI  (alias) */
-		[ C(RESULT_MISS)   ] = 0x0508, /* DTLB_MISSES.MISS_LD        */
-	},
-	[ C(OP_WRITE) ] = {
-		[ C(RESULT_ACCESS) ] = 0x2240, /* L1D_CACHE_ST.MESI  (alias) */
-		[ C(RESULT_MISS)   ] = 0x0608, /* DTLB_MISSES.MISS_ST        */
-	},
-	[ C(OP_PREFETCH) ] = {
-		[ C(RESULT_ACCESS) ] = 0,
-		[ C(RESULT_MISS)   ] = 0,
-	},
- },
- [ C(ITLB) ] = {
-	[ C(OP_READ) ] = {
-		[ C(RESULT_ACCESS) ] = 0x00c0, /* INST_RETIRED.ANY_P         */
-		[ C(RESULT_MISS)   ] = 0x0282, /* ITLB.MISSES                */
-	},
-	[ C(OP_WRITE) ] = {
-		[ C(RESULT_ACCESS) ] = -1,
-		[ C(RESULT_MISS)   ] = -1,
-	},
-	[ C(OP_PREFETCH) ] = {
-		[ C(RESULT_ACCESS) ] = -1,
-		[ C(RESULT_MISS)   ] = -1,
-	},
- },
- [ C(BPU ) ] = {
-	[ C(OP_READ) ] = {
-		[ C(RESULT_ACCESS) ] = 0x00c4, /* BR_INST_RETIRED.ANY        */
-		[ C(RESULT_MISS)   ] = 0x00c5, /* BP_INST_RETIRED.MISPRED    */
-	},
-	[ C(OP_WRITE) ] = {
-		[ C(RESULT_ACCESS) ] = -1,
-		[ C(RESULT_MISS)   ] = -1,
-	},
-	[ C(OP_PREFETCH) ] = {
-		[ C(RESULT_ACCESS) ] = -1,
-		[ C(RESULT_MISS)   ] = -1,
-	},
- },
-};
-
-static struct extra_reg intel_slm_extra_regs[] __read_mostly =
-{
-	/* must define OFFCORE_RSP_X first, see intel_fixup_er() */
-	INTEL_UEVENT_EXTRA_REG(0x01b7, MSR_OFFCORE_RSP_0, 0x768005ffffull, RSP_0),
-	INTEL_UEVENT_EXTRA_REG(0x02b7, MSR_OFFCORE_RSP_1, 0x368005ffffull, RSP_1),
-	EVENT_EXTRA_END
-};
-
-#define SLM_DMND_READ		SNB_DMND_DATA_RD
-#define SLM_DMND_WRITE		SNB_DMND_RFO
-#define SLM_DMND_PREFETCH	(SNB_PF_DATA_RD|SNB_PF_RFO)
-
-#define SLM_SNP_ANY		(SNB_SNP_NONE|SNB_SNP_MISS|SNB_NO_FWD|SNB_HITM)
-#define SLM_LLC_ACCESS		SNB_RESP_ANY
-#define SLM_LLC_MISS		(SLM_SNP_ANY|SNB_NON_DRAM)
-
-static __initconst const u64 slm_hw_cache_extra_regs
-				[PERF_COUNT_HW_CACHE_MAX]
-				[PERF_COUNT_HW_CACHE_OP_MAX]
-				[PERF_COUNT_HW_CACHE_RESULT_MAX] =
-{
- [ C(LL  ) ] = {
-	[ C(OP_READ) ] = {
-		[ C(RESULT_ACCESS) ] = SLM_DMND_READ|SLM_LLC_ACCESS,
-		[ C(RESULT_MISS)   ] = 0,
-	},
-	[ C(OP_WRITE) ] = {
-		[ C(RESULT_ACCESS) ] = SLM_DMND_WRITE|SLM_LLC_ACCESS,
-		[ C(RESULT_MISS)   ] = SLM_DMND_WRITE|SLM_LLC_MISS,
-	},
-	[ C(OP_PREFETCH) ] = {
-		[ C(RESULT_ACCESS) ] = SLM_DMND_PREFETCH|SLM_LLC_ACCESS,
-		[ C(RESULT_MISS)   ] = SLM_DMND_PREFETCH|SLM_LLC_MISS,
-	},
- },
-};
-
-static __initconst const u64 slm_hw_cache_event_ids
-				[PERF_COUNT_HW_CACHE_MAX]
-				[PERF_COUNT_HW_CACHE_OP_MAX]
-				[PERF_COUNT_HW_CACHE_RESULT_MAX] =
-{
- [ C(L1D) ] = {
-	[ C(OP_READ) ] = {
-		[ C(RESULT_ACCESS) ] = 0,
-		[ C(RESULT_MISS)   ] = 0x0104, /* LD_DCU_MISS */
-	},
-	[ C(OP_WRITE) ] = {
-		[ C(RESULT_ACCESS) ] = 0,
-		[ C(RESULT_MISS)   ] = 0,
-	},
-	[ C(OP_PREFETCH) ] = {
-		[ C(RESULT_ACCESS) ] = 0,
-		[ C(RESULT_MISS)   ] = 0,
-	},
- },
- [ C(L1I ) ] = {
-	[ C(OP_READ) ] = {
-		[ C(RESULT_ACCESS) ] = 0x0380, /* ICACHE.ACCESSES */
-		[ C(RESULT_MISS)   ] = 0x0280, /* ICACGE.MISSES */
-	},
-	[ C(OP_WRITE) ] = {
-		[ C(RESULT_ACCESS) ] = -1,
-		[ C(RESULT_MISS)   ] = -1,
-	},
-	[ C(OP_PREFETCH) ] = {
-		[ C(RESULT_ACCESS) ] = 0,
-		[ C(RESULT_MISS)   ] = 0,
-	},
- },
- [ C(LL  ) ] = {
-	[ C(OP_READ) ] = {
-		/* OFFCORE_RESPONSE.ANY_DATA.LOCAL_CACHE */
-		[ C(RESULT_ACCESS) ] = 0x01b7,
-		[ C(RESULT_MISS)   ] = 0,
-	},
-	[ C(OP_WRITE) ] = {
-		/* OFFCORE_RESPONSE.ANY_RFO.LOCAL_CACHE */
-		[ C(RESULT_ACCESS) ] = 0x01b7,
-		/* OFFCORE_RESPONSE.ANY_RFO.ANY_LLC_MISS */
-		[ C(RESULT_MISS)   ] = 0x01b7,
-	},
-	[ C(OP_PREFETCH) ] = {
-		/* OFFCORE_RESPONSE.PREFETCH.LOCAL_CACHE */
-		[ C(RESULT_ACCESS) ] = 0x01b7,
-		/* OFFCORE_RESPONSE.PREFETCH.ANY_LLC_MISS */
-		[ C(RESULT_MISS)   ] = 0x01b7,
-	},
- },
- [ C(DTLB) ] = {
-	[ C(OP_READ) ] = {
-		[ C(RESULT_ACCESS) ] = 0,
-		[ C(RESULT_MISS)   ] = 0x0804, /* LD_DTLB_MISS */
-	},
-	[ C(OP_WRITE) ] = {
-		[ C(RESULT_ACCESS) ] = 0,
-		[ C(RESULT_MISS)   ] = 0,
-	},
-	[ C(OP_PREFETCH) ] = {
-		[ C(RESULT_ACCESS) ] = 0,
-		[ C(RESULT_MISS)   ] = 0,
-	},
- },
- [ C(ITLB) ] = {
-	[ C(OP_READ) ] = {
-		[ C(RESULT_ACCESS) ] = 0x00c0, /* INST_RETIRED.ANY_P */
-		[ C(RESULT_MISS)   ] = 0x40205, /* PAGE_WALKS.I_SIDE_WALKS */
-	},
-	[ C(OP_WRITE) ] = {
-		[ C(RESULT_ACCESS) ] = -1,
-		[ C(RESULT_MISS)   ] = -1,
-	},
-	[ C(OP_PREFETCH) ] = {
-		[ C(RESULT_ACCESS) ] = -1,
-		[ C(RESULT_MISS)   ] = -1,
-	},
- },
- [ C(BPU ) ] = {
-	[ C(OP_READ) ] = {
-		[ C(RESULT_ACCESS) ] = 0x00c4, /* BR_INST_RETIRED.ANY */
-		[ C(RESULT_MISS)   ] = 0x00c5, /* BP_INST_RETIRED.MISPRED */
-	},
-	[ C(OP_WRITE) ] = {
-		[ C(RESULT_ACCESS) ] = -1,
-		[ C(RESULT_MISS)   ] = -1,
-	},
-	[ C(OP_PREFETCH) ] = {
-		[ C(RESULT_ACCESS) ] = -1,
-		[ C(RESULT_MISS)   ] = -1,
-	},
- },
-};
-
-/*
- * Use from PMIs where the LBRs are already disabled.
- */
-static void __intel_pmu_disable_all(void)
-{
-	struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
-
-	wrmsrl(MSR_CORE_PERF_GLOBAL_CTRL, 0);
-
-	if (test_bit(INTEL_PMC_IDX_FIXED_BTS, cpuc->active_mask))
-		intel_pmu_disable_bts();
-	else
-		intel_bts_disable_local();
-
-	intel_pmu_pebs_disable_all();
-}
-
-static void intel_pmu_disable_all(void)
-{
-	__intel_pmu_disable_all();
-	intel_pmu_lbr_disable_all();
-}
-
-static void __intel_pmu_enable_all(int added, bool pmi)
-{
-	struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
-
-	intel_pmu_pebs_enable_all();
-	intel_pmu_lbr_enable_all(pmi);
-	wrmsrl(MSR_CORE_PERF_GLOBAL_CTRL,
-			x86_pmu.intel_ctrl & ~cpuc->intel_ctrl_guest_mask);
-
-	if (test_bit(INTEL_PMC_IDX_FIXED_BTS, cpuc->active_mask)) {
-		struct perf_event *event =
-			cpuc->events[INTEL_PMC_IDX_FIXED_BTS];
-
-		if (WARN_ON_ONCE(!event))
-			return;
-
-		intel_pmu_enable_bts(event->hw.config);
-	} else
-		intel_bts_enable_local();
-}
-
-static void intel_pmu_enable_all(int added)
-{
-	__intel_pmu_enable_all(added, false);
-}
-
-/*
- * Workaround for:
- *   Intel Errata AAK100 (model 26)
- *   Intel Errata AAP53  (model 30)
- *   Intel Errata BD53   (model 44)
- *
- * The official story:
- *   These chips need to be 'reset' when adding counters by programming the
- *   magic three (non-counting) events 0x4300B5, 0x4300D2, and 0x4300B1 either
- *   in sequence on the same PMC or on different PMCs.
- *
- * In practise it appears some of these events do in fact count, and
- * we need to programm all 4 events.
- */
-static void intel_pmu_nhm_workaround(void)
-{
-	struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
-	static const unsigned long nhm_magic[4] = {
-		0x4300B5,
-		0x4300D2,
-		0x4300B1,
-		0x4300B1
-	};
-	struct perf_event *event;
-	int i;
-
-	/*
-	 * The Errata requires below steps:
-	 * 1) Clear MSR_IA32_PEBS_ENABLE and MSR_CORE_PERF_GLOBAL_CTRL;
-	 * 2) Configure 4 PERFEVTSELx with the magic events and clear
-	 *    the corresponding PMCx;
-	 * 3) set bit0~bit3 of MSR_CORE_PERF_GLOBAL_CTRL;
-	 * 4) Clear MSR_CORE_PERF_GLOBAL_CTRL;
-	 * 5) Clear 4 pairs of ERFEVTSELx and PMCx;
-	 */
-
-	/*
-	 * The real steps we choose are a little different from above.
-	 * A) To reduce MSR operations, we don't run step 1) as they
-	 *    are already cleared before this function is called;
-	 * B) Call x86_perf_event_update to save PMCx before configuring
-	 *    PERFEVTSELx with magic number;
-	 * C) With step 5), we do clear only when the PERFEVTSELx is
-	 *    not used currently.
-	 * D) Call x86_perf_event_set_period to restore PMCx;
-	 */
-
-	/* We always operate 4 pairs of PERF Counters */
-	for (i = 0; i < 4; i++) {
-		event = cpuc->events[i];
-		if (event)
-			x86_perf_event_update(event);
-	}
-
-	for (i = 0; i < 4; i++) {
-		wrmsrl(MSR_ARCH_PERFMON_EVENTSEL0 + i, nhm_magic[i]);
-		wrmsrl(MSR_ARCH_PERFMON_PERFCTR0 + i, 0x0);
-	}
-
-	wrmsrl(MSR_CORE_PERF_GLOBAL_CTRL, 0xf);
-	wrmsrl(MSR_CORE_PERF_GLOBAL_CTRL, 0x0);
-
-	for (i = 0; i < 4; i++) {
-		event = cpuc->events[i];
-
-		if (event) {
-			x86_perf_event_set_period(event);
-			__x86_pmu_enable_event(&event->hw,
-					ARCH_PERFMON_EVENTSEL_ENABLE);
-		} else
-			wrmsrl(MSR_ARCH_PERFMON_EVENTSEL0 + i, 0x0);
-	}
-}
-
-static void intel_pmu_nhm_enable_all(int added)
-{
-	if (added)
-		intel_pmu_nhm_workaround();
-	intel_pmu_enable_all(added);
-}
-
-static inline u64 intel_pmu_get_status(void)
-{
-	u64 status;
-
-	rdmsrl(MSR_CORE_PERF_GLOBAL_STATUS, status);
-
-	return status;
-}
-
-static inline void intel_pmu_ack_status(u64 ack)
-{
-	wrmsrl(MSR_CORE_PERF_GLOBAL_OVF_CTRL, ack);
-}
-
-static void intel_pmu_disable_fixed(struct hw_perf_event *hwc)
-{
-	int idx = hwc->idx - INTEL_PMC_IDX_FIXED;
-	u64 ctrl_val, mask;
-
-	mask = 0xfULL << (idx * 4);
-
-	rdmsrl(hwc->config_base, ctrl_val);
-	ctrl_val &= ~mask;
-	wrmsrl(hwc->config_base, ctrl_val);
-}
-
-static inline bool event_is_checkpointed(struct perf_event *event)
-{
-	return (event->hw.config & HSW_IN_TX_CHECKPOINTED) != 0;
-}
-
-static void intel_pmu_disable_event(struct perf_event *event)
-{
-	struct hw_perf_event *hwc = &event->hw;
-	struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
-
-	if (unlikely(hwc->idx == INTEL_PMC_IDX_FIXED_BTS)) {
-		intel_pmu_disable_bts();
-		intel_pmu_drain_bts_buffer();
-		return;
-	}
-
-	cpuc->intel_ctrl_guest_mask &= ~(1ull << hwc->idx);
-	cpuc->intel_ctrl_host_mask &= ~(1ull << hwc->idx);
-	cpuc->intel_cp_status &= ~(1ull << hwc->idx);
-
-	/*
-	 * must disable before any actual event
-	 * because any event may be combined with LBR
-	 */
-	if (needs_branch_stack(event))
-		intel_pmu_lbr_disable(event);
-
-	if (unlikely(hwc->config_base == MSR_ARCH_PERFMON_FIXED_CTR_CTRL)) {
-		intel_pmu_disable_fixed(hwc);
-		return;
-	}
-
-	x86_pmu_disable_event(event);
-
-	if (unlikely(event->attr.precise_ip))
-		intel_pmu_pebs_disable(event);
-}
-
-static void intel_pmu_enable_fixed(struct hw_perf_event *hwc)
-{
-	int idx = hwc->idx - INTEL_PMC_IDX_FIXED;
-	u64 ctrl_val, bits, mask;
-
-	/*
-	 * Enable IRQ generation (0x8),
-	 * and enable ring-3 counting (0x2) and ring-0 counting (0x1)
-	 * if requested:
-	 */
-	bits = 0x8ULL;
-	if (hwc->config & ARCH_PERFMON_EVENTSEL_USR)
-		bits |= 0x2;
-	if (hwc->config & ARCH_PERFMON_EVENTSEL_OS)
-		bits |= 0x1;
-
-	/*
-	 * ANY bit is supported in v3 and up
-	 */
-	if (x86_pmu.version > 2 && hwc->config & ARCH_PERFMON_EVENTSEL_ANY)
-		bits |= 0x4;
-
-	bits <<= (idx * 4);
-	mask = 0xfULL << (idx * 4);
-
-	rdmsrl(hwc->config_base, ctrl_val);
-	ctrl_val &= ~mask;
-	ctrl_val |= bits;
-	wrmsrl(hwc->config_base, ctrl_val);
-}
-
-static void intel_pmu_enable_event(struct perf_event *event)
-{
-	struct hw_perf_event *hwc = &event->hw;
-	struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
-
-	if (unlikely(hwc->idx == INTEL_PMC_IDX_FIXED_BTS)) {
-		if (!__this_cpu_read(cpu_hw_events.enabled))
-			return;
-
-		intel_pmu_enable_bts(hwc->config);
-		return;
-	}
-	/*
-	 * must enabled before any actual event
-	 * because any event may be combined with LBR
-	 */
-	if (needs_branch_stack(event))
-		intel_pmu_lbr_enable(event);
-
-	if (event->attr.exclude_host)
-		cpuc->intel_ctrl_guest_mask |= (1ull << hwc->idx);
-	if (event->attr.exclude_guest)
-		cpuc->intel_ctrl_host_mask |= (1ull << hwc->idx);
-
-	if (unlikely(event_is_checkpointed(event)))
-		cpuc->intel_cp_status |= (1ull << hwc->idx);
-
-	if (unlikely(hwc->config_base == MSR_ARCH_PERFMON_FIXED_CTR_CTRL)) {
-		intel_pmu_enable_fixed(hwc);
-		return;
-	}
-
-	if (unlikely(event->attr.precise_ip))
-		intel_pmu_pebs_enable(event);
-
-	__x86_pmu_enable_event(hwc, ARCH_PERFMON_EVENTSEL_ENABLE);
-}
-
-/*
- * Save and restart an expired event. Called by NMI contexts,
- * so it has to be careful about preempting normal event ops:
- */
-int intel_pmu_save_and_restart(struct perf_event *event)
-{
-	x86_perf_event_update(event);
-	/*
-	 * For a checkpointed counter always reset back to 0.  This
-	 * avoids a situation where the counter overflows, aborts the
-	 * transaction and is then set back to shortly before the
-	 * overflow, and overflows and aborts again.
-	 */
-	if (unlikely(event_is_checkpointed(event))) {
-		/* No race with NMIs because the counter should not be armed */
-		wrmsrl(event->hw.event_base, 0);
-		local64_set(&event->hw.prev_count, 0);
-	}
-	return x86_perf_event_set_period(event);
-}
-
-static void intel_pmu_reset(void)
-{
-	struct debug_store *ds = __this_cpu_read(cpu_hw_events.ds);
-	unsigned long flags;
-	int idx;
-
-	if (!x86_pmu.num_counters)
-		return;
-
-	local_irq_save(flags);
-
-	pr_info("clearing PMU state on CPU#%d\n", smp_processor_id());
-
-	for (idx = 0; idx < x86_pmu.num_counters; idx++) {
-		wrmsrl_safe(x86_pmu_config_addr(idx), 0ull);
-		wrmsrl_safe(x86_pmu_event_addr(idx),  0ull);
-	}
-	for (idx = 0; idx < x86_pmu.num_counters_fixed; idx++)
-		wrmsrl_safe(MSR_ARCH_PERFMON_FIXED_CTR0 + idx, 0ull);
-
-	if (ds)
-		ds->bts_index = ds->bts_buffer_base;
-
-	/* Ack all overflows and disable fixed counters */
-	if (x86_pmu.version >= 2) {
-		intel_pmu_ack_status(intel_pmu_get_status());
-		wrmsrl(MSR_CORE_PERF_GLOBAL_CTRL, 0);
-	}
-
-	/* Reset LBRs and LBR freezing */
-	if (x86_pmu.lbr_nr) {
-		update_debugctlmsr(get_debugctlmsr() &
-			~(DEBUGCTLMSR_FREEZE_LBRS_ON_PMI|DEBUGCTLMSR_LBR));
-	}
-
-	local_irq_restore(flags);
-}
-
-/*
- * This handler is triggered by the local APIC, so the APIC IRQ handling
- * rules apply:
- */
-static int intel_pmu_handle_irq(struct pt_regs *regs)
-{
-	struct perf_sample_data data;
-	struct cpu_hw_events *cpuc;
-	int bit, loops;
-	u64 status;
-	int handled;
-
-	cpuc = this_cpu_ptr(&cpu_hw_events);
-
-	/*
-	 * No known reason to not always do late ACK,
-	 * but just in case do it opt-in.
-	 */
-	if (!x86_pmu.late_ack)
-		apic_write(APIC_LVTPC, APIC_DM_NMI);
-	__intel_pmu_disable_all();
-	handled = intel_pmu_drain_bts_buffer();
-	handled += intel_bts_interrupt();
-	status = intel_pmu_get_status();
-	if (!status)
-		goto done;
-
-	loops = 0;
-again:
-	intel_pmu_lbr_read();
-	intel_pmu_ack_status(status);
-	if (++loops > 100) {
-		static bool warned = false;
-		if (!warned) {
-			WARN(1, "perfevents: irq loop stuck!\n");
-			perf_event_print_debug();
-			warned = true;
-		}
-		intel_pmu_reset();
-		goto done;
-	}
-
-	inc_irq_stat(apic_perf_irqs);
-
-
-	/*
-	 * Ignore a range of extra bits in status that do not indicate
-	 * overflow by themselves.
-	 */
-	status &= ~(GLOBAL_STATUS_COND_CHG |
-		    GLOBAL_STATUS_ASIF |
-		    GLOBAL_STATUS_LBRS_FROZEN);
-	if (!status)
-		goto done;
-
-	/*
-	 * PEBS overflow sets bit 62 in the global status register
-	 */
-	if (__test_and_clear_bit(62, (unsigned long *)&status)) {
-		handled++;
-		x86_pmu.drain_pebs(regs);
-	}
-
-	/*
-	 * Intel PT
-	 */
-	if (__test_and_clear_bit(55, (unsigned long *)&status)) {
-		handled++;
-		intel_pt_interrupt();
-	}
-
-	/*
-	 * Checkpointed counters can lead to 'spurious' PMIs because the
-	 * rollback caused by the PMI will have cleared the overflow status
-	 * bit. Therefore always force probe these counters.
-	 */
-	status |= cpuc->intel_cp_status;
-
-	for_each_set_bit(bit, (unsigned long *)&status, X86_PMC_IDX_MAX) {
-		struct perf_event *event = cpuc->events[bit];
-
-		handled++;
-
-		if (!test_bit(bit, cpuc->active_mask))
-			continue;
-
-		if (!intel_pmu_save_and_restart(event))
-			continue;
-
-		perf_sample_data_init(&data, 0, event->hw.last_period);
-
-		if (has_branch_stack(event))
-			data.br_stack = &cpuc->lbr_stack;
-
-		if (perf_event_overflow(event, &data, regs))
-			x86_pmu_stop(event, 0);
-	}
-
-	/*
-	 * Repeat if there is more work to be done:
-	 */
-	status = intel_pmu_get_status();
-	if (status)
-		goto again;
-
-done:
-	__intel_pmu_enable_all(0, true);
-	/*
-	 * Only unmask the NMI after the overflow counters
-	 * have been reset. This avoids spurious NMIs on
-	 * Haswell CPUs.
-	 */
-	if (x86_pmu.late_ack)
-		apic_write(APIC_LVTPC, APIC_DM_NMI);
-	return handled;
-}
-
-static struct event_constraint *
-intel_bts_constraints(struct perf_event *event)
-{
-	struct hw_perf_event *hwc = &event->hw;
-	unsigned int hw_event, bts_event;
-
-	if (event->attr.freq)
-		return NULL;
-
-	hw_event = hwc->config & INTEL_ARCH_EVENT_MASK;
-	bts_event = x86_pmu.event_map(PERF_COUNT_HW_BRANCH_INSTRUCTIONS);
-
-	if (unlikely(hw_event == bts_event && hwc->sample_period == 1))
-		return &bts_constraint;
-
-	return NULL;
-}
-
-static int intel_alt_er(int idx, u64 config)
-{
-	int alt_idx;
-	if (!(x86_pmu.flags & PMU_FL_HAS_RSP_1))
-		return idx;
-
-	if (idx == EXTRA_REG_RSP_0)
-		alt_idx = EXTRA_REG_RSP_1;
-
-	if (idx == EXTRA_REG_RSP_1)
-		alt_idx = EXTRA_REG_RSP_0;
-
-	if (config & ~x86_pmu.extra_regs[alt_idx].valid_mask)
-		return idx;
-
-	return alt_idx;
-}
-
-static void intel_fixup_er(struct perf_event *event, int idx)
-{
-	event->hw.extra_reg.idx = idx;
-
-	if (idx == EXTRA_REG_RSP_0) {
-		event->hw.config &= ~INTEL_ARCH_EVENT_MASK;
-		event->hw.config |= x86_pmu.extra_regs[EXTRA_REG_RSP_0].event;
-		event->hw.extra_reg.reg = MSR_OFFCORE_RSP_0;
-	} else if (idx == EXTRA_REG_RSP_1) {
-		event->hw.config &= ~INTEL_ARCH_EVENT_MASK;
-		event->hw.config |= x86_pmu.extra_regs[EXTRA_REG_RSP_1].event;
-		event->hw.extra_reg.reg = MSR_OFFCORE_RSP_1;
-	}
-}
-
-/*
- * manage allocation of shared extra msr for certain events
- *
- * sharing can be:
- * per-cpu: to be shared between the various events on a single PMU
- * per-core: per-cpu + shared by HT threads
- */
-static struct event_constraint *
-__intel_shared_reg_get_constraints(struct cpu_hw_events *cpuc,
-				   struct perf_event *event,
-				   struct hw_perf_event_extra *reg)
-{
-	struct event_constraint *c = &emptyconstraint;
-	struct er_account *era;
-	unsigned long flags;
-	int idx = reg->idx;
-
-	/*
-	 * reg->alloc can be set due to existing state, so for fake cpuc we
-	 * need to ignore this, otherwise we might fail to allocate proper fake
-	 * state for this extra reg constraint. Also see the comment below.
-	 */
-	if (reg->alloc && !cpuc->is_fake)
-		return NULL; /* call x86_get_event_constraint() */
-
-again:
-	era = &cpuc->shared_regs->regs[idx];
-	/*
-	 * we use spin_lock_irqsave() to avoid lockdep issues when
-	 * passing a fake cpuc
-	 */
-	raw_spin_lock_irqsave(&era->lock, flags);
-
-	if (!atomic_read(&era->ref) || era->config == reg->config) {
-
-		/*
-		 * If its a fake cpuc -- as per validate_{group,event}() we
-		 * shouldn't touch event state and we can avoid doing so
-		 * since both will only call get_event_constraints() once
-		 * on each event, this avoids the need for reg->alloc.
-		 *
-		 * Not doing the ER fixup will only result in era->reg being
-		 * wrong, but since we won't actually try and program hardware
-		 * this isn't a problem either.
-		 */
-		if (!cpuc->is_fake) {
-			if (idx != reg->idx)
-				intel_fixup_er(event, idx);
-
-			/*
-			 * x86_schedule_events() can call get_event_constraints()
-			 * multiple times on events in the case of incremental
-			 * scheduling(). reg->alloc ensures we only do the ER
-			 * allocation once.
-			 */
-			reg->alloc = 1;
-		}
-
-		/* lock in msr value */
-		era->config = reg->config;
-		era->reg = reg->reg;
-
-		/* one more user */
-		atomic_inc(&era->ref);
-
-		/*
-		 * need to call x86_get_event_constraint()
-		 * to check if associated event has constraints
-		 */
-		c = NULL;
-	} else {
-		idx = intel_alt_er(idx, reg->config);
-		if (idx != reg->idx) {
-			raw_spin_unlock_irqrestore(&era->lock, flags);
-			goto again;
-		}
-	}
-	raw_spin_unlock_irqrestore(&era->lock, flags);
-
-	return c;
-}
-
-static void
-__intel_shared_reg_put_constraints(struct cpu_hw_events *cpuc,
-				   struct hw_perf_event_extra *reg)
-{
-	struct er_account *era;
-
-	/*
-	 * Only put constraint if extra reg was actually allocated. Also takes
-	 * care of event which do not use an extra shared reg.
-	 *
-	 * Also, if this is a fake cpuc we shouldn't touch any event state
-	 * (reg->alloc) and we don't care about leaving inconsistent cpuc state
-	 * either since it'll be thrown out.
-	 */
-	if (!reg->alloc || cpuc->is_fake)
-		return;
-
-	era = &cpuc->shared_regs->regs[reg->idx];
-
-	/* one fewer user */
-	atomic_dec(&era->ref);
-
-	/* allocate again next time */
-	reg->alloc = 0;
-}
-
-static struct event_constraint *
-intel_shared_regs_constraints(struct cpu_hw_events *cpuc,
-			      struct perf_event *event)
-{
-	struct event_constraint *c = NULL, *d;
-	struct hw_perf_event_extra *xreg, *breg;
-
-	xreg = &event->hw.extra_reg;
-	if (xreg->idx != EXTRA_REG_NONE) {
-		c = __intel_shared_reg_get_constraints(cpuc, event, xreg);
-		if (c == &emptyconstraint)
-			return c;
-	}
-	breg = &event->hw.branch_reg;
-	if (breg->idx != EXTRA_REG_NONE) {
-		d = __intel_shared_reg_get_constraints(cpuc, event, breg);
-		if (d == &emptyconstraint) {
-			__intel_shared_reg_put_constraints(cpuc, xreg);
-			c = d;
-		}
-	}
-	return c;
-}
-
-struct event_constraint *
-x86_get_event_constraints(struct cpu_hw_events *cpuc, int idx,
-			  struct perf_event *event)
-{
-	struct event_constraint *c;
-
-	if (x86_pmu.event_constraints) {
-		for_each_event_constraint(c, x86_pmu.event_constraints) {
-			if ((event->hw.config & c->cmask) == c->code) {
-				event->hw.flags |= c->flags;
-				return c;
-			}
-		}
-	}
-
-	return &unconstrained;
-}
-
-static struct event_constraint *
-__intel_get_event_constraints(struct cpu_hw_events *cpuc, int idx,
-			    struct perf_event *event)
-{
-	struct event_constraint *c;
-
-	c = intel_bts_constraints(event);
-	if (c)
-		return c;
-
-	c = intel_shared_regs_constraints(cpuc, event);
-	if (c)
-		return c;
-
-	c = intel_pebs_constraints(event);
-	if (c)
-		return c;
-
-	return x86_get_event_constraints(cpuc, idx, event);
-}
-
-static void
-intel_start_scheduling(struct cpu_hw_events *cpuc)
-{
-	struct intel_excl_cntrs *excl_cntrs = cpuc->excl_cntrs;
-	struct intel_excl_states *xl;
-	int tid = cpuc->excl_thread_id;
-
-	/*
-	 * nothing needed if in group validation mode
-	 */
-	if (cpuc->is_fake || !is_ht_workaround_enabled())
-		return;
-
-	/*
-	 * no exclusion needed
-	 */
-	if (WARN_ON_ONCE(!excl_cntrs))
-		return;
-
-	xl = &excl_cntrs->states[tid];
-
-	xl->sched_started = true;
-	/*
-	 * lock shared state until we are done scheduling
-	 * in stop_event_scheduling()
-	 * makes scheduling appear as a transaction
-	 */
-	raw_spin_lock(&excl_cntrs->lock);
-}
-
-static void intel_commit_scheduling(struct cpu_hw_events *cpuc, int idx, int cntr)
-{
-	struct intel_excl_cntrs *excl_cntrs = cpuc->excl_cntrs;
-	struct event_constraint *c = cpuc->event_constraint[idx];
-	struct intel_excl_states *xl;
-	int tid = cpuc->excl_thread_id;
-
-	if (cpuc->is_fake || !is_ht_workaround_enabled())
-		return;
-
-	if (WARN_ON_ONCE(!excl_cntrs))
-		return;
-
-	if (!(c->flags & PERF_X86_EVENT_DYNAMIC))
-		return;
-
-	xl = &excl_cntrs->states[tid];
-
-	lockdep_assert_held(&excl_cntrs->lock);
-
-	if (c->flags & PERF_X86_EVENT_EXCL)
-		xl->state[cntr] = INTEL_EXCL_EXCLUSIVE;
-	else
-		xl->state[cntr] = INTEL_EXCL_SHARED;
-}
-
-static void
-intel_stop_scheduling(struct cpu_hw_events *cpuc)
-{
-	struct intel_excl_cntrs *excl_cntrs = cpuc->excl_cntrs;
-	struct intel_excl_states *xl;
-	int tid = cpuc->excl_thread_id;
-
-	/*
-	 * nothing needed if in group validation mode
-	 */
-	if (cpuc->is_fake || !is_ht_workaround_enabled())
-		return;
-	/*
-	 * no exclusion needed
-	 */
-	if (WARN_ON_ONCE(!excl_cntrs))
-		return;
-
-	xl = &excl_cntrs->states[tid];
-
-	xl->sched_started = false;
-	/*
-	 * release shared state lock (acquired in intel_start_scheduling())
-	 */
-	raw_spin_unlock(&excl_cntrs->lock);
-}
-
-static struct event_constraint *
-intel_get_excl_constraints(struct cpu_hw_events *cpuc, struct perf_event *event,
-			   int idx, struct event_constraint *c)
-{
-	struct intel_excl_cntrs *excl_cntrs = cpuc->excl_cntrs;
-	struct intel_excl_states *xlo;
-	int tid = cpuc->excl_thread_id;
-	int is_excl, i;
-
-	/*
-	 * validating a group does not require
-	 * enforcing cross-thread  exclusion
-	 */
-	if (cpuc->is_fake || !is_ht_workaround_enabled())
-		return c;
-
-	/*
-	 * no exclusion needed
-	 */
-	if (WARN_ON_ONCE(!excl_cntrs))
-		return c;
-
-	/*
-	 * because we modify the constraint, we need
-	 * to make a copy. Static constraints come
-	 * from static const tables.
-	 *
-	 * only needed when constraint has not yet
-	 * been cloned (marked dynamic)
-	 */
-	if (!(c->flags & PERF_X86_EVENT_DYNAMIC)) {
-		struct event_constraint *cx;
-
-		/*
-		 * grab pre-allocated constraint entry
-		 */
-		cx = &cpuc->constraint_list[idx];
-
-		/*
-		 * initialize dynamic constraint
-		 * with static constraint
-		 */
-		*cx = *c;
-
-		/*
-		 * mark constraint as dynamic, so we
-		 * can free it later on
-		 */
-		cx->flags |= PERF_X86_EVENT_DYNAMIC;
-		c = cx;
-	}
-
-	/*
-	 * From here on, the constraint is dynamic.
-	 * Either it was just allocated above, or it
-	 * was allocated during a earlier invocation
-	 * of this function
-	 */
-
-	/*
-	 * state of sibling HT
-	 */
-	xlo = &excl_cntrs->states[tid ^ 1];
-
-	/*
-	 * event requires exclusive counter access
-	 * across HT threads
-	 */
-	is_excl = c->flags & PERF_X86_EVENT_EXCL;
-	if (is_excl && !(event->hw.flags & PERF_X86_EVENT_EXCL_ACCT)) {
-		event->hw.flags |= PERF_X86_EVENT_EXCL_ACCT;
-		if (!cpuc->n_excl++)
-			WRITE_ONCE(excl_cntrs->has_exclusive[tid], 1);
-	}
-
-	/*
-	 * Modify static constraint with current dynamic
-	 * state of thread
-	 *
-	 * EXCLUSIVE: sibling counter measuring exclusive event
-	 * SHARED   : sibling counter measuring non-exclusive event
-	 * UNUSED   : sibling counter unused
-	 */
-	for_each_set_bit(i, c->idxmsk, X86_PMC_IDX_MAX) {
-		/*
-		 * exclusive event in sibling counter
-		 * our corresponding counter cannot be used
-		 * regardless of our event
-		 */
-		if (xlo->state[i] == INTEL_EXCL_EXCLUSIVE)
-			__clear_bit(i, c->idxmsk);
-		/*
-		 * if measuring an exclusive event, sibling
-		 * measuring non-exclusive, then counter cannot
-		 * be used
-		 */
-		if (is_excl && xlo->state[i] == INTEL_EXCL_SHARED)
-			__clear_bit(i, c->idxmsk);
-	}
-
-	/*
-	 * recompute actual bit weight for scheduling algorithm
-	 */
-	c->weight = hweight64(c->idxmsk64);
-
-	/*
-	 * if we return an empty mask, then switch
-	 * back to static empty constraint to avoid
-	 * the cost of freeing later on
-	 */
-	if (c->weight == 0)
-		c = &emptyconstraint;
-
-	return c;
-}
-
-static struct event_constraint *
-intel_get_event_constraints(struct cpu_hw_events *cpuc, int idx,
-			    struct perf_event *event)
-{
-	struct event_constraint *c1 = NULL;
-	struct event_constraint *c2;
-
-	if (idx >= 0) /* fake does < 0 */
-		c1 = cpuc->event_constraint[idx];
-
-	/*
-	 * first time only
-	 * - static constraint: no change across incremental scheduling calls
-	 * - dynamic constraint: handled by intel_get_excl_constraints()
-	 */
-	c2 = __intel_get_event_constraints(cpuc, idx, event);
-	if (c1 && (c1->flags & PERF_X86_EVENT_DYNAMIC)) {
-		bitmap_copy(c1->idxmsk, c2->idxmsk, X86_PMC_IDX_MAX);
-		c1->weight = c2->weight;
-		c2 = c1;
-	}
-
-	if (cpuc->excl_cntrs)
-		return intel_get_excl_constraints(cpuc, event, idx, c2);
-
-	return c2;
-}
-
-static void intel_put_excl_constraints(struct cpu_hw_events *cpuc,
-		struct perf_event *event)
-{
-	struct hw_perf_event *hwc = &event->hw;
-	struct intel_excl_cntrs *excl_cntrs = cpuc->excl_cntrs;
-	int tid = cpuc->excl_thread_id;
-	struct intel_excl_states *xl;
-
-	/*
-	 * nothing needed if in group validation mode
-	 */
-	if (cpuc->is_fake)
-		return;
-
-	if (WARN_ON_ONCE(!excl_cntrs))
-		return;
-
-	if (hwc->flags & PERF_X86_EVENT_EXCL_ACCT) {
-		hwc->flags &= ~PERF_X86_EVENT_EXCL_ACCT;
-		if (!--cpuc->n_excl)
-			WRITE_ONCE(excl_cntrs->has_exclusive[tid], 0);
-	}
-
-	/*
-	 * If event was actually assigned, then mark the counter state as
-	 * unused now.
-	 */
-	if (hwc->idx >= 0) {
-		xl = &excl_cntrs->states[tid];
-
-		/*
-		 * put_constraint may be called from x86_schedule_events()
-		 * which already has the lock held so here make locking
-		 * conditional.
-		 */
-		if (!xl->sched_started)
-			raw_spin_lock(&excl_cntrs->lock);
-
-		xl->state[hwc->idx] = INTEL_EXCL_UNUSED;
-
-		if (!xl->sched_started)
-			raw_spin_unlock(&excl_cntrs->lock);
-	}
-}
-
-static void
-intel_put_shared_regs_event_constraints(struct cpu_hw_events *cpuc,
-					struct perf_event *event)
-{
-	struct hw_perf_event_extra *reg;
-
-	reg = &event->hw.extra_reg;
-	if (reg->idx != EXTRA_REG_NONE)
-		__intel_shared_reg_put_constraints(cpuc, reg);
-
-	reg = &event->hw.branch_reg;
-	if (reg->idx != EXTRA_REG_NONE)
-		__intel_shared_reg_put_constraints(cpuc, reg);
-}
-
-static void intel_put_event_constraints(struct cpu_hw_events *cpuc,
-					struct perf_event *event)
-{
-	intel_put_shared_regs_event_constraints(cpuc, event);
-
-	/*
-	 * is PMU has exclusive counter restrictions, then
-	 * all events are subject to and must call the
-	 * put_excl_constraints() routine
-	 */
-	if (cpuc->excl_cntrs)
-		intel_put_excl_constraints(cpuc, event);
-}
-
-static void intel_pebs_aliases_core2(struct perf_event *event)
-{
-	if ((event->hw.config & X86_RAW_EVENT_MASK) == 0x003c) {
-		/*
-		 * Use an alternative encoding for CPU_CLK_UNHALTED.THREAD_P
-		 * (0x003c) so that we can use it with PEBS.
-		 *
-		 * The regular CPU_CLK_UNHALTED.THREAD_P event (0x003c) isn't
-		 * PEBS capable. However we can use INST_RETIRED.ANY_P
-		 * (0x00c0), which is a PEBS capable event, to get the same
-		 * count.
-		 *
-		 * INST_RETIRED.ANY_P counts the number of cycles that retires
-		 * CNTMASK instructions. By setting CNTMASK to a value (16)
-		 * larger than the maximum number of instructions that can be
-		 * retired per cycle (4) and then inverting the condition, we
-		 * count all cycles that retire 16 or less instructions, which
-		 * is every cycle.
-		 *
-		 * Thereby we gain a PEBS capable cycle counter.
-		 */
-		u64 alt_config = X86_CONFIG(.event=0xc0, .inv=1, .cmask=16);
-
-		alt_config |= (event->hw.config & ~X86_RAW_EVENT_MASK);
-		event->hw.config = alt_config;
-	}
-}
-
-static void intel_pebs_aliases_snb(struct perf_event *event)
-{
-	if ((event->hw.config & X86_RAW_EVENT_MASK) == 0x003c) {
-		/*
-		 * Use an alternative encoding for CPU_CLK_UNHALTED.THREAD_P
-		 * (0x003c) so that we can use it with PEBS.
-		 *
-		 * The regular CPU_CLK_UNHALTED.THREAD_P event (0x003c) isn't
-		 * PEBS capable. However we can use UOPS_RETIRED.ALL
-		 * (0x01c2), which is a PEBS capable event, to get the same
-		 * count.
-		 *
-		 * UOPS_RETIRED.ALL counts the number of cycles that retires
-		 * CNTMASK micro-ops. By setting CNTMASK to a value (16)
-		 * larger than the maximum number of micro-ops that can be
-		 * retired per cycle (4) and then inverting the condition, we
-		 * count all cycles that retire 16 or less micro-ops, which
-		 * is every cycle.
-		 *
-		 * Thereby we gain a PEBS capable cycle counter.
-		 */
-		u64 alt_config = X86_CONFIG(.event=0xc2, .umask=0x01, .inv=1, .cmask=16);
-
-		alt_config |= (event->hw.config & ~X86_RAW_EVENT_MASK);
-		event->hw.config = alt_config;
-	}
-}
-
-static unsigned long intel_pmu_free_running_flags(struct perf_event *event)
-{
-	unsigned long flags = x86_pmu.free_running_flags;
-
-	if (event->attr.use_clockid)
-		flags &= ~PERF_SAMPLE_TIME;
-	return flags;
-}
-
-static int intel_pmu_hw_config(struct perf_event *event)
-{
-	int ret = x86_pmu_hw_config(event);
-
-	if (ret)
-		return ret;
-
-	if (event->attr.precise_ip) {
-		if (!event->attr.freq) {
-			event->hw.flags |= PERF_X86_EVENT_AUTO_RELOAD;
-			if (!(event->attr.sample_type &
-			      ~intel_pmu_free_running_flags(event)))
-				event->hw.flags |= PERF_X86_EVENT_FREERUNNING;
-		}
-		if (x86_pmu.pebs_aliases)
-			x86_pmu.pebs_aliases(event);
-	}
-
-	if (needs_branch_stack(event)) {
-		ret = intel_pmu_setup_lbr_filter(event);
-		if (ret)
-			return ret;
-
-		/*
-		 * BTS is set up earlier in this path, so don't account twice
-		 */
-		if (!intel_pmu_has_bts(event)) {
-			/* disallow lbr if conflicting events are present */
-			if (x86_add_exclusive(x86_lbr_exclusive_lbr))
-				return -EBUSY;
-
-			event->destroy = hw_perf_lbr_event_destroy;
-		}
-	}
-
-	if (event->attr.type != PERF_TYPE_RAW)
-		return 0;
-
-	if (!(event->attr.config & ARCH_PERFMON_EVENTSEL_ANY))
-		return 0;
-
-	if (x86_pmu.version < 3)
-		return -EINVAL;
-
-	if (perf_paranoid_cpu() && !capable(CAP_SYS_ADMIN))
-		return -EACCES;
-
-	event->hw.config |= ARCH_PERFMON_EVENTSEL_ANY;
-
-	return 0;
-}
-
-struct perf_guest_switch_msr *perf_guest_get_msrs(int *nr)
-{
-	if (x86_pmu.guest_get_msrs)
-		return x86_pmu.guest_get_msrs(nr);
-	*nr = 0;
-	return NULL;
-}
-EXPORT_SYMBOL_GPL(perf_guest_get_msrs);
-
-static struct perf_guest_switch_msr *intel_guest_get_msrs(int *nr)
-{
-	struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
-	struct perf_guest_switch_msr *arr = cpuc->guest_switch_msrs;
-
-	arr[0].msr = MSR_CORE_PERF_GLOBAL_CTRL;
-	arr[0].host = x86_pmu.intel_ctrl & ~cpuc->intel_ctrl_guest_mask;
-	arr[0].guest = x86_pmu.intel_ctrl & ~cpuc->intel_ctrl_host_mask;
-	/*
-	 * If PMU counter has PEBS enabled it is not enough to disable counter
-	 * on a guest entry since PEBS memory write can overshoot guest entry
-	 * and corrupt guest memory. Disabling PEBS solves the problem.
-	 */
-	arr[1].msr = MSR_IA32_PEBS_ENABLE;
-	arr[1].host = cpuc->pebs_enabled;
-	arr[1].guest = 0;
-
-	*nr = 2;
-	return arr;
-}
-
-static struct perf_guest_switch_msr *core_guest_get_msrs(int *nr)
-{
-	struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
-	struct perf_guest_switch_msr *arr = cpuc->guest_switch_msrs;
-	int idx;
-
-	for (idx = 0; idx < x86_pmu.num_counters; idx++)  {
-		struct perf_event *event = cpuc->events[idx];
-
-		arr[idx].msr = x86_pmu_config_addr(idx);
-		arr[idx].host = arr[idx].guest = 0;
-
-		if (!test_bit(idx, cpuc->active_mask))
-			continue;
-
-		arr[idx].host = arr[idx].guest =
-			event->hw.config | ARCH_PERFMON_EVENTSEL_ENABLE;
-
-		if (event->attr.exclude_host)
-			arr[idx].host &= ~ARCH_PERFMON_EVENTSEL_ENABLE;
-		else if (event->attr.exclude_guest)
-			arr[idx].guest &= ~ARCH_PERFMON_EVENTSEL_ENABLE;
-	}
-
-	*nr = x86_pmu.num_counters;
-	return arr;
-}
-
-static void core_pmu_enable_event(struct perf_event *event)
-{
-	if (!event->attr.exclude_host)
-		x86_pmu_enable_event(event);
-}
-
-static void core_pmu_enable_all(int added)
-{
-	struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
-	int idx;
-
-	for (idx = 0; idx < x86_pmu.num_counters; idx++) {
-		struct hw_perf_event *hwc = &cpuc->events[idx]->hw;
-
-		if (!test_bit(idx, cpuc->active_mask) ||
-				cpuc->events[idx]->attr.exclude_host)
-			continue;
-
-		__x86_pmu_enable_event(hwc, ARCH_PERFMON_EVENTSEL_ENABLE);
-	}
-}
-
-static int hsw_hw_config(struct perf_event *event)
-{
-	int ret = intel_pmu_hw_config(event);
-
-	if (ret)
-		return ret;
-	if (!boot_cpu_has(X86_FEATURE_RTM) && !boot_cpu_has(X86_FEATURE_HLE))
-		return 0;
-	event->hw.config |= event->attr.config & (HSW_IN_TX|HSW_IN_TX_CHECKPOINTED);
-
-	/*
-	 * IN_TX/IN_TX-CP filters are not supported by the Haswell PMU with
-	 * PEBS or in ANY thread mode. Since the results are non-sensical forbid
-	 * this combination.
-	 */
-	if ((event->hw.config & (HSW_IN_TX|HSW_IN_TX_CHECKPOINTED)) &&
-	     ((event->hw.config & ARCH_PERFMON_EVENTSEL_ANY) ||
-	      event->attr.precise_ip > 0))
-		return -EOPNOTSUPP;
-
-	if (event_is_checkpointed(event)) {
-		/*
-		 * Sampling of checkpointed events can cause situations where
-		 * the CPU constantly aborts because of a overflow, which is
-		 * then checkpointed back and ignored. Forbid checkpointing
-		 * for sampling.
-		 *
-		 * But still allow a long sampling period, so that perf stat
-		 * from KVM works.
-		 */
-		if (event->attr.sample_period > 0 &&
-		    event->attr.sample_period < 0x7fffffff)
-			return -EOPNOTSUPP;
-	}
-	return 0;
-}
-
-static struct event_constraint counter2_constraint =
-			EVENT_CONSTRAINT(0, 0x4, 0);
-
-static struct event_constraint *
-hsw_get_event_constraints(struct cpu_hw_events *cpuc, int idx,
-			  struct perf_event *event)
-{
-	struct event_constraint *c;
-
-	c = intel_get_event_constraints(cpuc, idx, event);
-
-	/* Handle special quirk on in_tx_checkpointed only in counter 2 */
-	if (event->hw.config & HSW_IN_TX_CHECKPOINTED) {
-		if (c->idxmsk64 & (1U << 2))
-			return &counter2_constraint;
-		return &emptyconstraint;
-	}
-
-	return c;
-}
-
-/*
- * Broadwell:
- *
- * The INST_RETIRED.ALL period always needs to have lowest 6 bits cleared
- * (BDM55) and it must not use a period smaller than 100 (BDM11). We combine
- * the two to enforce a minimum period of 128 (the smallest value that has bits
- * 0-5 cleared and >= 100).
- *
- * Because of how the code in x86_perf_event_set_period() works, the truncation
- * of the lower 6 bits is 'harmless' as we'll occasionally add a longer period
- * to make up for the 'lost' events due to carrying the 'error' in period_left.
- *
- * Therefore the effective (average) period matches the requested period,
- * despite coarser hardware granularity.
- */
-static unsigned bdw_limit_period(struct perf_event *event, unsigned left)
-{
-	if ((event->hw.config & INTEL_ARCH_EVENT_MASK) ==
-			X86_CONFIG(.event=0xc0, .umask=0x01)) {
-		if (left < 128)
-			left = 128;
-		left &= ~0x3fu;
-	}
-	return left;
-}
-
-PMU_FORMAT_ATTR(event,	"config:0-7"	);
-PMU_FORMAT_ATTR(umask,	"config:8-15"	);
-PMU_FORMAT_ATTR(edge,	"config:18"	);
-PMU_FORMAT_ATTR(pc,	"config:19"	);
-PMU_FORMAT_ATTR(any,	"config:21"	); /* v3 + */
-PMU_FORMAT_ATTR(inv,	"config:23"	);
-PMU_FORMAT_ATTR(cmask,	"config:24-31"	);
-PMU_FORMAT_ATTR(in_tx,  "config:32");
-PMU_FORMAT_ATTR(in_tx_cp, "config:33");
-
-static struct attribute *intel_arch_formats_attr[] = {
-	&format_attr_event.attr,
-	&format_attr_umask.attr,
-	&format_attr_edge.attr,
-	&format_attr_pc.attr,
-	&format_attr_inv.attr,
-	&format_attr_cmask.attr,
-	NULL,
-};
-
-ssize_t intel_event_sysfs_show(char *page, u64 config)
-{
-	u64 event = (config & ARCH_PERFMON_EVENTSEL_EVENT);
-
-	return x86_event_sysfs_show(page, config, event);
-}
-
-struct intel_shared_regs *allocate_shared_regs(int cpu)
-{
-	struct intel_shared_regs *regs;
-	int i;
-
-	regs = kzalloc_node(sizeof(struct intel_shared_regs),
-			    GFP_KERNEL, cpu_to_node(cpu));
-	if (regs) {
-		/*
-		 * initialize the locks to keep lockdep happy
-		 */
-		for (i = 0; i < EXTRA_REG_MAX; i++)
-			raw_spin_lock_init(&regs->regs[i].lock);
-
-		regs->core_id = -1;
-	}
-	return regs;
-}
-
-static struct intel_excl_cntrs *allocate_excl_cntrs(int cpu)
-{
-	struct intel_excl_cntrs *c;
-
-	c = kzalloc_node(sizeof(struct intel_excl_cntrs),
-			 GFP_KERNEL, cpu_to_node(cpu));
-	if (c) {
-		raw_spin_lock_init(&c->lock);
-		c->core_id = -1;
-	}
-	return c;
-}
-
-static int intel_pmu_cpu_prepare(int cpu)
-{
-	struct cpu_hw_events *cpuc = &per_cpu(cpu_hw_events, cpu);
-
-	if (x86_pmu.extra_regs || x86_pmu.lbr_sel_map) {
-		cpuc->shared_regs = allocate_shared_regs(cpu);
-		if (!cpuc->shared_regs)
-			goto err;
-	}
-
-	if (x86_pmu.flags & PMU_FL_EXCL_CNTRS) {
-		size_t sz = X86_PMC_IDX_MAX * sizeof(struct event_constraint);
-
-		cpuc->constraint_list = kzalloc(sz, GFP_KERNEL);
-		if (!cpuc->constraint_list)
-			goto err_shared_regs;
-
-		cpuc->excl_cntrs = allocate_excl_cntrs(cpu);
-		if (!cpuc->excl_cntrs)
-			goto err_constraint_list;
-
-		cpuc->excl_thread_id = 0;
-	}
-
-	return NOTIFY_OK;
-
-err_constraint_list:
-	kfree(cpuc->constraint_list);
-	cpuc->constraint_list = NULL;
-
-err_shared_regs:
-	kfree(cpuc->shared_regs);
-	cpuc->shared_regs = NULL;
-
-err:
-	return NOTIFY_BAD;
-}
-
-static void intel_pmu_cpu_starting(int cpu)
-{
-	struct cpu_hw_events *cpuc = &per_cpu(cpu_hw_events, cpu);
-	int core_id = topology_core_id(cpu);
-	int i;
-
-	init_debug_store_on_cpu(cpu);
-	/*
-	 * Deal with CPUs that don't clear their LBRs on power-up.
-	 */
-	intel_pmu_lbr_reset();
-
-	cpuc->lbr_sel = NULL;
-
-	if (!cpuc->shared_regs)
-		return;
-
-	if (!(x86_pmu.flags & PMU_FL_NO_HT_SHARING)) {
-		void **onln = &cpuc->kfree_on_online[X86_PERF_KFREE_SHARED];
-
-		for_each_cpu(i, topology_sibling_cpumask(cpu)) {
-			struct intel_shared_regs *pc;
-
-			pc = per_cpu(cpu_hw_events, i).shared_regs;
-			if (pc && pc->core_id == core_id) {
-				*onln = cpuc->shared_regs;
-				cpuc->shared_regs = pc;
-				break;
-			}
-		}
-		cpuc->shared_regs->core_id = core_id;
-		cpuc->shared_regs->refcnt++;
-	}
-
-	if (x86_pmu.lbr_sel_map)
-		cpuc->lbr_sel = &cpuc->shared_regs->regs[EXTRA_REG_LBR];
-
-	if (x86_pmu.flags & PMU_FL_EXCL_CNTRS) {
-		for_each_cpu(i, topology_sibling_cpumask(cpu)) {
-			struct intel_excl_cntrs *c;
-
-			c = per_cpu(cpu_hw_events, i).excl_cntrs;
-			if (c && c->core_id == core_id) {
-				cpuc->kfree_on_online[1] = cpuc->excl_cntrs;
-				cpuc->excl_cntrs = c;
-				cpuc->excl_thread_id = 1;
-				break;
-			}
-		}
-		cpuc->excl_cntrs->core_id = core_id;
-		cpuc->excl_cntrs->refcnt++;
-	}
-}
-
-static void free_excl_cntrs(int cpu)
-{
-	struct cpu_hw_events *cpuc = &per_cpu(cpu_hw_events, cpu);
-	struct intel_excl_cntrs *c;
-
-	c = cpuc->excl_cntrs;
-	if (c) {
-		if (c->core_id == -1 || --c->refcnt == 0)
-			kfree(c);
-		cpuc->excl_cntrs = NULL;
-		kfree(cpuc->constraint_list);
-		cpuc->constraint_list = NULL;
-	}
-}
-
-static void intel_pmu_cpu_dying(int cpu)
-{
-	struct cpu_hw_events *cpuc = &per_cpu(cpu_hw_events, cpu);
-	struct intel_shared_regs *pc;
-
-	pc = cpuc->shared_regs;
-	if (pc) {
-		if (pc->core_id == -1 || --pc->refcnt == 0)
-			kfree(pc);
-		cpuc->shared_regs = NULL;
-	}
-
-	free_excl_cntrs(cpu);
-
-	fini_debug_store_on_cpu(cpu);
-}
-
-static void intel_pmu_sched_task(struct perf_event_context *ctx,
-				 bool sched_in)
-{
-	if (x86_pmu.pebs_active)
-		intel_pmu_pebs_sched_task(ctx, sched_in);
-	if (x86_pmu.lbr_nr)
-		intel_pmu_lbr_sched_task(ctx, sched_in);
-}
-
-PMU_FORMAT_ATTR(offcore_rsp, "config1:0-63");
-
-PMU_FORMAT_ATTR(ldlat, "config1:0-15");
-
-PMU_FORMAT_ATTR(frontend, "config1:0-23");
-
-static struct attribute *intel_arch3_formats_attr[] = {
-	&format_attr_event.attr,
-	&format_attr_umask.attr,
-	&format_attr_edge.attr,
-	&format_attr_pc.attr,
-	&format_attr_any.attr,
-	&format_attr_inv.attr,
-	&format_attr_cmask.attr,
-	&format_attr_in_tx.attr,
-	&format_attr_in_tx_cp.attr,
-
-	&format_attr_offcore_rsp.attr, /* XXX do NHM/WSM + SNB breakout */
-	&format_attr_ldlat.attr, /* PEBS load latency */
-	NULL,
-};
-
-static struct attribute *skl_format_attr[] = {
-	&format_attr_frontend.attr,
-	NULL,
-};
-
-static __initconst const struct x86_pmu core_pmu = {
-	.name			= "core",
-	.handle_irq		= x86_pmu_handle_irq,
-	.disable_all		= x86_pmu_disable_all,
-	.enable_all		= core_pmu_enable_all,
-	.enable			= core_pmu_enable_event,
-	.disable		= x86_pmu_disable_event,
-	.hw_config		= x86_pmu_hw_config,
-	.schedule_events	= x86_schedule_events,
-	.eventsel		= MSR_ARCH_PERFMON_EVENTSEL0,
-	.perfctr		= MSR_ARCH_PERFMON_PERFCTR0,
-	.event_map		= intel_pmu_event_map,
-	.max_events		= ARRAY_SIZE(intel_perfmon_event_map),
-	.apic			= 1,
-	.free_running_flags	= PEBS_FREERUNNING_FLAGS,
-
-	/*
-	 * Intel PMCs cannot be accessed sanely above 32-bit width,
-	 * so we install an artificial 1<<31 period regardless of
-	 * the generic event period:
-	 */
-	.max_period		= (1ULL<<31) - 1,
-	.get_event_constraints	= intel_get_event_constraints,
-	.put_event_constraints	= intel_put_event_constraints,
-	.event_constraints	= intel_core_event_constraints,
-	.guest_get_msrs		= core_guest_get_msrs,
-	.format_attrs		= intel_arch_formats_attr,
-	.events_sysfs_show	= intel_event_sysfs_show,
-
-	/*
-	 * Virtual (or funny metal) CPU can define x86_pmu.extra_regs
-	 * together with PMU version 1 and thus be using core_pmu with
-	 * shared_regs. We need following callbacks here to allocate
-	 * it properly.
-	 */
-	.cpu_prepare		= intel_pmu_cpu_prepare,
-	.cpu_starting		= intel_pmu_cpu_starting,
-	.cpu_dying		= intel_pmu_cpu_dying,
-};
-
-static __initconst const struct x86_pmu intel_pmu = {
-	.name			= "Intel",
-	.handle_irq		= intel_pmu_handle_irq,
-	.disable_all		= intel_pmu_disable_all,
-	.enable_all		= intel_pmu_enable_all,
-	.enable			= intel_pmu_enable_event,
-	.disable		= intel_pmu_disable_event,
-	.hw_config		= intel_pmu_hw_config,
-	.schedule_events	= x86_schedule_events,
-	.eventsel		= MSR_ARCH_PERFMON_EVENTSEL0,
-	.perfctr		= MSR_ARCH_PERFMON_PERFCTR0,
-	.event_map		= intel_pmu_event_map,
-	.max_events		= ARRAY_SIZE(intel_perfmon_event_map),
-	.apic			= 1,
-	.free_running_flags	= PEBS_FREERUNNING_FLAGS,
-	/*
-	 * Intel PMCs cannot be accessed sanely above 32 bit width,
-	 * so we install an artificial 1<<31 period regardless of
-	 * the generic event period:
-	 */
-	.max_period		= (1ULL << 31) - 1,
-	.get_event_constraints	= intel_get_event_constraints,
-	.put_event_constraints	= intel_put_event_constraints,
-	.pebs_aliases		= intel_pebs_aliases_core2,
-
-	.format_attrs		= intel_arch3_formats_attr,
-	.events_sysfs_show	= intel_event_sysfs_show,
-
-	.cpu_prepare		= intel_pmu_cpu_prepare,
-	.cpu_starting		= intel_pmu_cpu_starting,
-	.cpu_dying		= intel_pmu_cpu_dying,
-	.guest_get_msrs		= intel_guest_get_msrs,
-	.sched_task		= intel_pmu_sched_task,
-};
-
-static __init void intel_clovertown_quirk(void)
-{
-	/*
-	 * PEBS is unreliable due to:
-	 *
-	 *   AJ67  - PEBS may experience CPL leaks
-	 *   AJ68  - PEBS PMI may be delayed by one event
-	 *   AJ69  - GLOBAL_STATUS[62] will only be set when DEBUGCTL[12]
-	 *   AJ106 - FREEZE_LBRS_ON_PMI doesn't work in combination with PEBS
-	 *
-	 * AJ67 could be worked around by restricting the OS/USR flags.
-	 * AJ69 could be worked around by setting PMU_FREEZE_ON_PMI.
-	 *
-	 * AJ106 could possibly be worked around by not allowing LBR
-	 *       usage from PEBS, including the fixup.
-	 * AJ68  could possibly be worked around by always programming
-	 *	 a pebs_event_reset[0] value and coping with the lost events.
-	 *
-	 * But taken together it might just make sense to not enable PEBS on
-	 * these chips.
-	 */
-	pr_warn("PEBS disabled due to CPU errata\n");
-	x86_pmu.pebs = 0;
-	x86_pmu.pebs_constraints = NULL;
-}
-
-static int intel_snb_pebs_broken(int cpu)
-{
-	u32 rev = UINT_MAX; /* default to broken for unknown models */
-
-	switch (cpu_data(cpu).x86_model) {
-	case 42: /* SNB */
-		rev = 0x28;
-		break;
-
-	case 45: /* SNB-EP */
-		switch (cpu_data(cpu).x86_mask) {
-		case 6: rev = 0x618; break;
-		case 7: rev = 0x70c; break;
-		}
-	}
-
-	return (cpu_data(cpu).microcode < rev);
-}
-
-static void intel_snb_check_microcode(void)
-{
-	int pebs_broken = 0;
-	int cpu;
-
-	get_online_cpus();
-	for_each_online_cpu(cpu) {
-		if ((pebs_broken = intel_snb_pebs_broken(cpu)))
-			break;
-	}
-	put_online_cpus();
-
-	if (pebs_broken == x86_pmu.pebs_broken)
-		return;
-
-	/*
-	 * Serialized by the microcode lock..
-	 */
-	if (x86_pmu.pebs_broken) {
-		pr_info("PEBS enabled due to microcode update\n");
-		x86_pmu.pebs_broken = 0;
-	} else {
-		pr_info("PEBS disabled due to CPU errata, please upgrade microcode\n");
-		x86_pmu.pebs_broken = 1;
-	}
-}
-
-/*
- * Under certain circumstances, access certain MSR may cause #GP.
- * The function tests if the input MSR can be safely accessed.
- */
-static bool check_msr(unsigned long msr, u64 mask)
-{
-	u64 val_old, val_new, val_tmp;
-
-	/*
-	 * Read the current value, change it and read it back to see if it
-	 * matches, this is needed to detect certain hardware emulators
-	 * (qemu/kvm) that don't trap on the MSR access and always return 0s.
-	 */
-	if (rdmsrl_safe(msr, &val_old))
-		return false;
-
-	/*
-	 * Only change the bits which can be updated by wrmsrl.
-	 */
-	val_tmp = val_old ^ mask;
-	if (wrmsrl_safe(msr, val_tmp) ||
-	    rdmsrl_safe(msr, &val_new))
-		return false;
-
-	if (val_new != val_tmp)
-		return false;
-
-	/* Here it's sure that the MSR can be safely accessed.
-	 * Restore the old value and return.
-	 */
-	wrmsrl(msr, val_old);
-
-	return true;
-}
-
-static __init void intel_sandybridge_quirk(void)
-{
-	x86_pmu.check_microcode = intel_snb_check_microcode;
-	intel_snb_check_microcode();
-}
-
-static const struct { int id; char *name; } intel_arch_events_map[] __initconst = {
-	{ PERF_COUNT_HW_CPU_CYCLES, "cpu cycles" },
-	{ PERF_COUNT_HW_INSTRUCTIONS, "instructions" },
-	{ PERF_COUNT_HW_BUS_CYCLES, "bus cycles" },
-	{ PERF_COUNT_HW_CACHE_REFERENCES, "cache references" },
-	{ PERF_COUNT_HW_CACHE_MISSES, "cache misses" },
-	{ PERF_COUNT_HW_BRANCH_INSTRUCTIONS, "branch instructions" },
-	{ PERF_COUNT_HW_BRANCH_MISSES, "branch misses" },
-};
-
-static __init void intel_arch_events_quirk(void)
-{
-	int bit;
-
-	/* disable event that reported as not presend by cpuid */
-	for_each_set_bit(bit, x86_pmu.events_mask, ARRAY_SIZE(intel_arch_events_map)) {
-		intel_perfmon_event_map[intel_arch_events_map[bit].id] = 0;
-		pr_warn("CPUID marked event: \'%s\' unavailable\n",
-			intel_arch_events_map[bit].name);
-	}
-}
-
-static __init void intel_nehalem_quirk(void)
-{
-	union cpuid10_ebx ebx;
-
-	ebx.full = x86_pmu.events_maskl;
-	if (ebx.split.no_branch_misses_retired) {
-		/*
-		 * Erratum AAJ80 detected, we work it around by using
-		 * the BR_MISP_EXEC.ANY event. This will over-count
-		 * branch-misses, but it's still much better than the
-		 * architectural event which is often completely bogus:
-		 */
-		intel_perfmon_event_map[PERF_COUNT_HW_BRANCH_MISSES] = 0x7f89;
-		ebx.split.no_branch_misses_retired = 0;
-		x86_pmu.events_maskl = ebx.full;
-		pr_info("CPU erratum AAJ80 worked around\n");
-	}
-}
-
-/*
- * enable software workaround for errata:
- * SNB: BJ122
- * IVB: BV98
- * HSW: HSD29
- *
- * Only needed when HT is enabled. However detecting
- * if HT is enabled is difficult (model specific). So instead,
- * we enable the workaround in the early boot, and verify if
- * it is needed in a later initcall phase once we have valid
- * topology information to check if HT is actually enabled
- */
-static __init void intel_ht_bug(void)
-{
-	x86_pmu.flags |= PMU_FL_EXCL_CNTRS | PMU_FL_EXCL_ENABLED;
-
-	x86_pmu.start_scheduling = intel_start_scheduling;
-	x86_pmu.commit_scheduling = intel_commit_scheduling;
-	x86_pmu.stop_scheduling = intel_stop_scheduling;
-}
-
-EVENT_ATTR_STR(mem-loads,	mem_ld_hsw,	"event=0xcd,umask=0x1,ldlat=3");
-EVENT_ATTR_STR(mem-stores,	mem_st_hsw,	"event=0xd0,umask=0x82")
-
-/* Haswell special events */
-EVENT_ATTR_STR(tx-start,	tx_start,	"event=0xc9,umask=0x1");
-EVENT_ATTR_STR(tx-commit,	tx_commit,	"event=0xc9,umask=0x2");
-EVENT_ATTR_STR(tx-abort,	tx_abort,	"event=0xc9,umask=0x4");
-EVENT_ATTR_STR(tx-capacity,	tx_capacity,	"event=0x54,umask=0x2");
-EVENT_ATTR_STR(tx-conflict,	tx_conflict,	"event=0x54,umask=0x1");
-EVENT_ATTR_STR(el-start,	el_start,	"event=0xc8,umask=0x1");
-EVENT_ATTR_STR(el-commit,	el_commit,	"event=0xc8,umask=0x2");
-EVENT_ATTR_STR(el-abort,	el_abort,	"event=0xc8,umask=0x4");
-EVENT_ATTR_STR(el-capacity,	el_capacity,	"event=0x54,umask=0x2");
-EVENT_ATTR_STR(el-conflict,	el_conflict,	"event=0x54,umask=0x1");
-EVENT_ATTR_STR(cycles-t,	cycles_t,	"event=0x3c,in_tx=1");
-EVENT_ATTR_STR(cycles-ct,	cycles_ct,	"event=0x3c,in_tx=1,in_tx_cp=1");
-
-static struct attribute *hsw_events_attrs[] = {
-	EVENT_PTR(tx_start),
-	EVENT_PTR(tx_commit),
-	EVENT_PTR(tx_abort),
-	EVENT_PTR(tx_capacity),
-	EVENT_PTR(tx_conflict),
-	EVENT_PTR(el_start),
-	EVENT_PTR(el_commit),
-	EVENT_PTR(el_abort),
-	EVENT_PTR(el_capacity),
-	EVENT_PTR(el_conflict),
-	EVENT_PTR(cycles_t),
-	EVENT_PTR(cycles_ct),
-	EVENT_PTR(mem_ld_hsw),
-	EVENT_PTR(mem_st_hsw),
-	NULL
-};
-
-__init int intel_pmu_init(void)
-{
-	union cpuid10_edx edx;
-	union cpuid10_eax eax;
-	union cpuid10_ebx ebx;
-	struct event_constraint *c;
-	unsigned int unused;
-	struct extra_reg *er;
-	int version, i;
-
-	if (!cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON)) {
-		switch (boot_cpu_data.x86) {
-		case 0x6:
-			return p6_pmu_init();
-		case 0xb:
-			return knc_pmu_init();
-		case 0xf:
-			return p4_pmu_init();
-		}
-		return -ENODEV;
-	}
-
-	/*
-	 * Check whether the Architectural PerfMon supports
-	 * Branch Misses Retired hw_event or not.
-	 */
-	cpuid(10, &eax.full, &ebx.full, &unused, &edx.full);
-	if (eax.split.mask_length < ARCH_PERFMON_EVENTS_COUNT)
-		return -ENODEV;
-
-	version = eax.split.version_id;
-	if (version < 2)
-		x86_pmu = core_pmu;
-	else
-		x86_pmu = intel_pmu;
-
-	x86_pmu.version			= version;
-	x86_pmu.num_counters		= eax.split.num_counters;
-	x86_pmu.cntval_bits		= eax.split.bit_width;
-	x86_pmu.cntval_mask		= (1ULL << eax.split.bit_width) - 1;
-
-	x86_pmu.events_maskl		= ebx.full;
-	x86_pmu.events_mask_len		= eax.split.mask_length;
-
-	x86_pmu.max_pebs_events		= min_t(unsigned, MAX_PEBS_EVENTS, x86_pmu.num_counters);
-
-	/*
-	 * Quirk: v2 perfmon does not report fixed-purpose events, so
-	 * assume at least 3 events:
-	 */
-	if (version > 1)
-		x86_pmu.num_counters_fixed = max((int)edx.split.num_counters_fixed, 3);
-
-	if (boot_cpu_has(X86_FEATURE_PDCM)) {
-		u64 capabilities;
-
-		rdmsrl(MSR_IA32_PERF_CAPABILITIES, capabilities);
-		x86_pmu.intel_cap.capabilities = capabilities;
-	}
-
-	intel_ds_init();
-
-	x86_add_quirk(intel_arch_events_quirk); /* Install first, so it runs last */
-
-	/*
-	 * Install the hw-cache-events table:
-	 */
-	switch (boot_cpu_data.x86_model) {
-	case 14: /* 65nm Core "Yonah" */
-		pr_cont("Core events, ");
-		break;
-
-	case 15: /* 65nm Core2 "Merom"          */
-		x86_add_quirk(intel_clovertown_quirk);
-	case 22: /* 65nm Core2 "Merom-L"        */
-	case 23: /* 45nm Core2 "Penryn"         */
-	case 29: /* 45nm Core2 "Dunnington (MP) */
-		memcpy(hw_cache_event_ids, core2_hw_cache_event_ids,
-		       sizeof(hw_cache_event_ids));
-
-		intel_pmu_lbr_init_core();
-
-		x86_pmu.event_constraints = intel_core2_event_constraints;
-		x86_pmu.pebs_constraints = intel_core2_pebs_event_constraints;
-		pr_cont("Core2 events, ");
-		break;
-
-	case 30: /* 45nm Nehalem    */
-	case 26: /* 45nm Nehalem-EP */
-	case 46: /* 45nm Nehalem-EX */
-		memcpy(hw_cache_event_ids, nehalem_hw_cache_event_ids,
-		       sizeof(hw_cache_event_ids));
-		memcpy(hw_cache_extra_regs, nehalem_hw_cache_extra_regs,
-		       sizeof(hw_cache_extra_regs));
-
-		intel_pmu_lbr_init_nhm();
-
-		x86_pmu.event_constraints = intel_nehalem_event_constraints;
-		x86_pmu.pebs_constraints = intel_nehalem_pebs_event_constraints;
-		x86_pmu.enable_all = intel_pmu_nhm_enable_all;
-		x86_pmu.extra_regs = intel_nehalem_extra_regs;
-
-		x86_pmu.cpu_events = nhm_events_attrs;
-
-		/* UOPS_ISSUED.STALLED_CYCLES */
-		intel_perfmon_event_map[PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] =
-			X86_CONFIG(.event=0x0e, .umask=0x01, .inv=1, .cmask=1);
-		/* UOPS_EXECUTED.CORE_ACTIVE_CYCLES,c=1,i=1 */
-		intel_perfmon_event_map[PERF_COUNT_HW_STALLED_CYCLES_BACKEND] =
-			X86_CONFIG(.event=0xb1, .umask=0x3f, .inv=1, .cmask=1);
-
-		x86_add_quirk(intel_nehalem_quirk);
-
-		pr_cont("Nehalem events, ");
-		break;
-
-	case 28: /* 45nm Atom "Pineview"   */
-	case 38: /* 45nm Atom "Lincroft"   */
-	case 39: /* 32nm Atom "Penwell"    */
-	case 53: /* 32nm Atom "Cloverview" */
-	case 54: /* 32nm Atom "Cedarview"  */
-		memcpy(hw_cache_event_ids, atom_hw_cache_event_ids,
-		       sizeof(hw_cache_event_ids));
-
-		intel_pmu_lbr_init_atom();
-
-		x86_pmu.event_constraints = intel_gen_event_constraints;
-		x86_pmu.pebs_constraints = intel_atom_pebs_event_constraints;
-		pr_cont("Atom events, ");
-		break;
-
-	case 55: /* 22nm Atom "Silvermont"                */
-	case 76: /* 14nm Atom "Airmont"                   */
-	case 77: /* 22nm Atom "Silvermont Avoton/Rangely" */
-		memcpy(hw_cache_event_ids, slm_hw_cache_event_ids,
-			sizeof(hw_cache_event_ids));
-		memcpy(hw_cache_extra_regs, slm_hw_cache_extra_regs,
-		       sizeof(hw_cache_extra_regs));
-
-		intel_pmu_lbr_init_atom();
-
-		x86_pmu.event_constraints = intel_slm_event_constraints;
-		x86_pmu.pebs_constraints = intel_slm_pebs_event_constraints;
-		x86_pmu.extra_regs = intel_slm_extra_regs;
-		x86_pmu.flags |= PMU_FL_HAS_RSP_1;
-		pr_cont("Silvermont events, ");
-		break;
-
-	case 37: /* 32nm Westmere    */
-	case 44: /* 32nm Westmere-EP */
-	case 47: /* 32nm Westmere-EX */
-		memcpy(hw_cache_event_ids, westmere_hw_cache_event_ids,
-		       sizeof(hw_cache_event_ids));
-		memcpy(hw_cache_extra_regs, nehalem_hw_cache_extra_regs,
-		       sizeof(hw_cache_extra_regs));
-
-		intel_pmu_lbr_init_nhm();
-
-		x86_pmu.event_constraints = intel_westmere_event_constraints;
-		x86_pmu.enable_all = intel_pmu_nhm_enable_all;
-		x86_pmu.pebs_constraints = intel_westmere_pebs_event_constraints;
-		x86_pmu.extra_regs = intel_westmere_extra_regs;
-		x86_pmu.flags |= PMU_FL_HAS_RSP_1;
-
-		x86_pmu.cpu_events = nhm_events_attrs;
-
-		/* UOPS_ISSUED.STALLED_CYCLES */
-		intel_perfmon_event_map[PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] =
-			X86_CONFIG(.event=0x0e, .umask=0x01, .inv=1, .cmask=1);
-		/* UOPS_EXECUTED.CORE_ACTIVE_CYCLES,c=1,i=1 */
-		intel_perfmon_event_map[PERF_COUNT_HW_STALLED_CYCLES_BACKEND] =
-			X86_CONFIG(.event=0xb1, .umask=0x3f, .inv=1, .cmask=1);
-
-		pr_cont("Westmere events, ");
-		break;
-
-	case 42: /* 32nm SandyBridge         */
-	case 45: /* 32nm SandyBridge-E/EN/EP */
-		x86_add_quirk(intel_sandybridge_quirk);
-		x86_add_quirk(intel_ht_bug);
-		memcpy(hw_cache_event_ids, snb_hw_cache_event_ids,
-		       sizeof(hw_cache_event_ids));
-		memcpy(hw_cache_extra_regs, snb_hw_cache_extra_regs,
-		       sizeof(hw_cache_extra_regs));
-
-		intel_pmu_lbr_init_snb();
-
-		x86_pmu.event_constraints = intel_snb_event_constraints;
-		x86_pmu.pebs_constraints = intel_snb_pebs_event_constraints;
-		x86_pmu.pebs_aliases = intel_pebs_aliases_snb;
-		if (boot_cpu_data.x86_model == 45)
-			x86_pmu.extra_regs = intel_snbep_extra_regs;
-		else
-			x86_pmu.extra_regs = intel_snb_extra_regs;
-
-
-		/* all extra regs are per-cpu when HT is on */
-		x86_pmu.flags |= PMU_FL_HAS_RSP_1;
-		x86_pmu.flags |= PMU_FL_NO_HT_SHARING;
-
-		x86_pmu.cpu_events = snb_events_attrs;
-
-		/* UOPS_ISSUED.ANY,c=1,i=1 to count stall cycles */
-		intel_perfmon_event_map[PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] =
-			X86_CONFIG(.event=0x0e, .umask=0x01, .inv=1, .cmask=1);
-		/* UOPS_DISPATCHED.THREAD,c=1,i=1 to count stall cycles*/
-		intel_perfmon_event_map[PERF_COUNT_HW_STALLED_CYCLES_BACKEND] =
-			X86_CONFIG(.event=0xb1, .umask=0x01, .inv=1, .cmask=1);
-
-		pr_cont("SandyBridge events, ");
-		break;
-
-	case 58: /* 22nm IvyBridge       */
-	case 62: /* 22nm IvyBridge-EP/EX */
-		x86_add_quirk(intel_ht_bug);
-		memcpy(hw_cache_event_ids, snb_hw_cache_event_ids,
-		       sizeof(hw_cache_event_ids));
-		/* dTLB-load-misses on IVB is different than SNB */
-		hw_cache_event_ids[C(DTLB)][C(OP_READ)][C(RESULT_MISS)] = 0x8108; /* DTLB_LOAD_MISSES.DEMAND_LD_MISS_CAUSES_A_WALK */
-
-		memcpy(hw_cache_extra_regs, snb_hw_cache_extra_regs,
-		       sizeof(hw_cache_extra_regs));
-
-		intel_pmu_lbr_init_snb();
-
-		x86_pmu.event_constraints = intel_ivb_event_constraints;
-		x86_pmu.pebs_constraints = intel_ivb_pebs_event_constraints;
-		x86_pmu.pebs_aliases = intel_pebs_aliases_snb;
-		if (boot_cpu_data.x86_model == 62)
-			x86_pmu.extra_regs = intel_snbep_extra_regs;
-		else
-			x86_pmu.extra_regs = intel_snb_extra_regs;
-		/* all extra regs are per-cpu when HT is on */
-		x86_pmu.flags |= PMU_FL_HAS_RSP_1;
-		x86_pmu.flags |= PMU_FL_NO_HT_SHARING;
-
-		x86_pmu.cpu_events = snb_events_attrs;
-
-		/* UOPS_ISSUED.ANY,c=1,i=1 to count stall cycles */
-		intel_perfmon_event_map[PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] =
-			X86_CONFIG(.event=0x0e, .umask=0x01, .inv=1, .cmask=1);
-
-		pr_cont("IvyBridge events, ");
-		break;
-
-
-	case 60: /* 22nm Haswell Core */
-	case 63: /* 22nm Haswell Server */
-	case 69: /* 22nm Haswell ULT */
-	case 70: /* 22nm Haswell + GT3e (Intel Iris Pro graphics) */
-		x86_add_quirk(intel_ht_bug);
-		x86_pmu.late_ack = true;
-		memcpy(hw_cache_event_ids, hsw_hw_cache_event_ids, sizeof(hw_cache_event_ids));
-		memcpy(hw_cache_extra_regs, hsw_hw_cache_extra_regs, sizeof(hw_cache_extra_regs));
-
-		intel_pmu_lbr_init_hsw();
-
-		x86_pmu.event_constraints = intel_hsw_event_constraints;
-		x86_pmu.pebs_constraints = intel_hsw_pebs_event_constraints;
-		x86_pmu.extra_regs = intel_snbep_extra_regs;
-		x86_pmu.pebs_aliases = intel_pebs_aliases_snb;
-		/* all extra regs are per-cpu when HT is on */
-		x86_pmu.flags |= PMU_FL_HAS_RSP_1;
-		x86_pmu.flags |= PMU_FL_NO_HT_SHARING;
-
-		x86_pmu.hw_config = hsw_hw_config;
-		x86_pmu.get_event_constraints = hsw_get_event_constraints;
-		x86_pmu.cpu_events = hsw_events_attrs;
-		x86_pmu.lbr_double_abort = true;
-		pr_cont("Haswell events, ");
-		break;
-
-	case 61: /* 14nm Broadwell Core-M */
-	case 86: /* 14nm Broadwell Xeon D */
-	case 71: /* 14nm Broadwell + GT3e (Intel Iris Pro graphics) */
-	case 79: /* 14nm Broadwell Server */
-		x86_pmu.late_ack = true;
-		memcpy(hw_cache_event_ids, hsw_hw_cache_event_ids, sizeof(hw_cache_event_ids));
-		memcpy(hw_cache_extra_regs, hsw_hw_cache_extra_regs, sizeof(hw_cache_extra_regs));
-
-		/* L3_MISS_LOCAL_DRAM is BIT(26) in Broadwell */
-		hw_cache_extra_regs[C(LL)][C(OP_READ)][C(RESULT_MISS)] = HSW_DEMAND_READ |
-									 BDW_L3_MISS|HSW_SNOOP_DRAM;
-		hw_cache_extra_regs[C(LL)][C(OP_WRITE)][C(RESULT_MISS)] = HSW_DEMAND_WRITE|BDW_L3_MISS|
-									  HSW_SNOOP_DRAM;
-		hw_cache_extra_regs[C(NODE)][C(OP_READ)][C(RESULT_ACCESS)] = HSW_DEMAND_READ|
-									     BDW_L3_MISS_LOCAL|HSW_SNOOP_DRAM;
-		hw_cache_extra_regs[C(NODE)][C(OP_WRITE)][C(RESULT_ACCESS)] = HSW_DEMAND_WRITE|
-									      BDW_L3_MISS_LOCAL|HSW_SNOOP_DRAM;
-
-		intel_pmu_lbr_init_hsw();
-
-		x86_pmu.event_constraints = intel_bdw_event_constraints;
-		x86_pmu.pebs_constraints = intel_hsw_pebs_event_constraints;
-		x86_pmu.extra_regs = intel_snbep_extra_regs;
-		x86_pmu.pebs_aliases = intel_pebs_aliases_snb;
-		/* all extra regs are per-cpu when HT is on */
-		x86_pmu.flags |= PMU_FL_HAS_RSP_1;
-		x86_pmu.flags |= PMU_FL_NO_HT_SHARING;
-
-		x86_pmu.hw_config = hsw_hw_config;
-		x86_pmu.get_event_constraints = hsw_get_event_constraints;
-		x86_pmu.cpu_events = hsw_events_attrs;
-		x86_pmu.limit_period = bdw_limit_period;
-		pr_cont("Broadwell events, ");
-		break;
-
-	case 78: /* 14nm Skylake Mobile */
-	case 94: /* 14nm Skylake Desktop */
-		x86_pmu.late_ack = true;
-		memcpy(hw_cache_event_ids, skl_hw_cache_event_ids, sizeof(hw_cache_event_ids));
-		memcpy(hw_cache_extra_regs, skl_hw_cache_extra_regs, sizeof(hw_cache_extra_regs));
-		intel_pmu_lbr_init_skl();
-
-		x86_pmu.event_constraints = intel_skl_event_constraints;
-		x86_pmu.pebs_constraints = intel_skl_pebs_event_constraints;
-		x86_pmu.extra_regs = intel_skl_extra_regs;
-		x86_pmu.pebs_aliases = intel_pebs_aliases_snb;
-		/* all extra regs are per-cpu when HT is on */
-		x86_pmu.flags |= PMU_FL_HAS_RSP_1;
-		x86_pmu.flags |= PMU_FL_NO_HT_SHARING;
-
-		x86_pmu.hw_config = hsw_hw_config;
-		x86_pmu.get_event_constraints = hsw_get_event_constraints;
-		x86_pmu.format_attrs = merge_attr(intel_arch3_formats_attr,
-						  skl_format_attr);
-		WARN_ON(!x86_pmu.format_attrs);
-		x86_pmu.cpu_events = hsw_events_attrs;
-		pr_cont("Skylake events, ");
-		break;
-
-	default:
-		switch (x86_pmu.version) {
-		case 1:
-			x86_pmu.event_constraints = intel_v1_event_constraints;
-			pr_cont("generic architected perfmon v1, ");
-			break;
-		default:
-			/*
-			 * default constraints for v2 and up
-			 */
-			x86_pmu.event_constraints = intel_gen_event_constraints;
-			pr_cont("generic architected perfmon, ");
-			break;
-		}
-	}
-
-	if (x86_pmu.num_counters > INTEL_PMC_MAX_GENERIC) {
-		WARN(1, KERN_ERR "hw perf events %d > max(%d), clipping!",
-		     x86_pmu.num_counters, INTEL_PMC_MAX_GENERIC);
-		x86_pmu.num_counters = INTEL_PMC_MAX_GENERIC;
-	}
-	x86_pmu.intel_ctrl = (1 << x86_pmu.num_counters) - 1;
-
-	if (x86_pmu.num_counters_fixed > INTEL_PMC_MAX_FIXED) {
-		WARN(1, KERN_ERR "hw perf events fixed %d > max(%d), clipping!",
-		     x86_pmu.num_counters_fixed, INTEL_PMC_MAX_FIXED);
-		x86_pmu.num_counters_fixed = INTEL_PMC_MAX_FIXED;
-	}
-
-	x86_pmu.intel_ctrl |=
-		((1LL << x86_pmu.num_counters_fixed)-1) << INTEL_PMC_IDX_FIXED;
-
-	if (x86_pmu.event_constraints) {
-		/*
-		 * event on fixed counter2 (REF_CYCLES) only works on this
-		 * counter, so do not extend mask to generic counters
-		 */
-		for_each_event_constraint(c, x86_pmu.event_constraints) {
-			if (c->cmask == FIXED_EVENT_FLAGS
-			    && c->idxmsk64 != INTEL_PMC_MSK_FIXED_REF_CYCLES) {
-				c->idxmsk64 |= (1ULL << x86_pmu.num_counters) - 1;
-			}
-			c->idxmsk64 &=
-				~(~0UL << (INTEL_PMC_IDX_FIXED + x86_pmu.num_counters_fixed));
-			c->weight = hweight64(c->idxmsk64);
-		}
-	}
-
-	/*
-	 * Access LBR MSR may cause #GP under certain circumstances.
-	 * E.g. KVM doesn't support LBR MSR
-	 * Check all LBT MSR here.
-	 * Disable LBR access if any LBR MSRs can not be accessed.
-	 */
-	if (x86_pmu.lbr_nr && !check_msr(x86_pmu.lbr_tos, 0x3UL))
-		x86_pmu.lbr_nr = 0;
-	for (i = 0; i < x86_pmu.lbr_nr; i++) {
-		if (!(check_msr(x86_pmu.lbr_from + i, 0xffffUL) &&
-		      check_msr(x86_pmu.lbr_to + i, 0xffffUL)))
-			x86_pmu.lbr_nr = 0;
-	}
-
-	/*
-	 * Access extra MSR may cause #GP under certain circumstances.
-	 * E.g. KVM doesn't support offcore event
-	 * Check all extra_regs here.
-	 */
-	if (x86_pmu.extra_regs) {
-		for (er = x86_pmu.extra_regs; er->msr; er++) {
-			er->extra_msr_access = check_msr(er->msr, 0x11UL);
-			/* Disable LBR select mapping */
-			if ((er->idx == EXTRA_REG_LBR) && !er->extra_msr_access)
-				x86_pmu.lbr_sel_map = NULL;
-		}
-	}
-
-	/* Support full width counters using alternative MSR range */
-	if (x86_pmu.intel_cap.full_width_write) {
-		x86_pmu.max_period = x86_pmu.cntval_mask;
-		x86_pmu.perfctr = MSR_IA32_PMC0;
-		pr_cont("full-width counters, ");
-	}
-
-	return 0;
-}
-
-/*
- * HT bug: phase 2 init
- * Called once we have valid topology information to check
- * whether or not HT is enabled
- * If HT is off, then we disable the workaround
- */
-static __init int fixup_ht_bug(void)
-{
-	int cpu = smp_processor_id();
-	int w, c;
-	/*
-	 * problem not present on this CPU model, nothing to do
-	 */
-	if (!(x86_pmu.flags & PMU_FL_EXCL_ENABLED))
-		return 0;
-
-	w = cpumask_weight(topology_sibling_cpumask(cpu));
-	if (w > 1) {
-		pr_info("PMU erratum BJ122, BV98, HSD29 worked around, HT is on\n");
-		return 0;
-	}
-
-	if (lockup_detector_suspend() != 0) {
-		pr_debug("failed to disable PMU erratum BJ122, BV98, HSD29 workaround\n");
-		return 0;
-	}
-
-	x86_pmu.flags &= ~(PMU_FL_EXCL_CNTRS | PMU_FL_EXCL_ENABLED);
-
-	x86_pmu.start_scheduling = NULL;
-	x86_pmu.commit_scheduling = NULL;
-	x86_pmu.stop_scheduling = NULL;
-
-	lockup_detector_resume();
-
-	get_online_cpus();
-
-	for_each_online_cpu(c) {
-		free_excl_cntrs(c);
-	}
-
-	put_online_cpus();
-	pr_info("PMU erratum BJ122, BV98, HSD29 workaround disabled, HT off\n");
-	return 0;
-}
-subsys_initcall(fixup_ht_bug)
--- zfcpdump-kernel-4.4.orig/arch/x86/kernel/cpu/perf_event_intel_bts.c
+++ /dev/null
@@ -1,544 +0,0 @@
-/*
- * BTS PMU driver for perf
- * Copyright (c) 2013-2014, Intel Corporation.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- */
-
-#undef DEBUG
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/bitops.h>
-#include <linux/types.h>
-#include <linux/slab.h>
-#include <linux/debugfs.h>
-#include <linux/device.h>
-#include <linux/coredump.h>
-
-#include <asm-generic/sizes.h>
-#include <asm/perf_event.h>
-
-#include "perf_event.h"
-
-struct bts_ctx {
-	struct perf_output_handle	handle;
-	struct debug_store		ds_back;
-	int				started;
-};
-
-static DEFINE_PER_CPU(struct bts_ctx, bts_ctx);
-
-#define BTS_RECORD_SIZE		24
-#define BTS_SAFETY_MARGIN	4080
-
-struct bts_phys {
-	struct page	*page;
-	unsigned long	size;
-	unsigned long	offset;
-	unsigned long	displacement;
-};
-
-struct bts_buffer {
-	size_t		real_size;	/* multiple of BTS_RECORD_SIZE */
-	unsigned int	nr_pages;
-	unsigned int	nr_bufs;
-	unsigned int	cur_buf;
-	bool		snapshot;
-	local_t		data_size;
-	local_t		lost;
-	local_t		head;
-	unsigned long	end;
-	void		**data_pages;
-	struct bts_phys	buf[0];
-};
-
-struct pmu bts_pmu;
-
-static size_t buf_size(struct page *page)
-{
-	return 1 << (PAGE_SHIFT + page_private(page));
-}
-
-static void *
-bts_buffer_setup_aux(int cpu, void **pages, int nr_pages, bool overwrite)
-{
-	struct bts_buffer *buf;
-	struct page *page;
-	int node = (cpu == -1) ? cpu : cpu_to_node(cpu);
-	unsigned long offset;
-	size_t size = nr_pages << PAGE_SHIFT;
-	int pg, nbuf, pad;
-
-	/* count all the high order buffers */
-	for (pg = 0, nbuf = 0; pg < nr_pages;) {
-		page = virt_to_page(pages[pg]);
-		if (WARN_ON_ONCE(!PagePrivate(page) && nr_pages > 1))
-			return NULL;
-		pg += 1 << page_private(page);
-		nbuf++;
-	}
-
-	/*
-	 * to avoid interrupts in overwrite mode, only allow one physical
-	 */
-	if (overwrite && nbuf > 1)
-		return NULL;
-
-	buf = kzalloc_node(offsetof(struct bts_buffer, buf[nbuf]), GFP_KERNEL, node);
-	if (!buf)
-		return NULL;
-
-	buf->nr_pages = nr_pages;
-	buf->nr_bufs = nbuf;
-	buf->snapshot = overwrite;
-	buf->data_pages = pages;
-	buf->real_size = size - size % BTS_RECORD_SIZE;
-
-	for (pg = 0, nbuf = 0, offset = 0, pad = 0; nbuf < buf->nr_bufs; nbuf++) {
-		unsigned int __nr_pages;
-
-		page = virt_to_page(pages[pg]);
-		__nr_pages = PagePrivate(page) ? 1 << page_private(page) : 1;
-		buf->buf[nbuf].page = page;
-		buf->buf[nbuf].offset = offset;
-		buf->buf[nbuf].displacement = (pad ? BTS_RECORD_SIZE - pad : 0);
-		buf->buf[nbuf].size = buf_size(page) - buf->buf[nbuf].displacement;
-		pad = buf->buf[nbuf].size % BTS_RECORD_SIZE;
-		buf->buf[nbuf].size -= pad;
-
-		pg += __nr_pages;
-		offset += __nr_pages << PAGE_SHIFT;
-	}
-
-	return buf;
-}
-
-static void bts_buffer_free_aux(void *data)
-{
-	kfree(data);
-}
-
-static unsigned long bts_buffer_offset(struct bts_buffer *buf, unsigned int idx)
-{
-	return buf->buf[idx].offset + buf->buf[idx].displacement;
-}
-
-static void
-bts_config_buffer(struct bts_buffer *buf)
-{
-	int cpu = raw_smp_processor_id();
-	struct debug_store *ds = per_cpu(cpu_hw_events, cpu).ds;
-	struct bts_phys *phys = &buf->buf[buf->cur_buf];
-	unsigned long index, thresh = 0, end = phys->size;
-	struct page *page = phys->page;
-
-	index = local_read(&buf->head);
-
-	if (!buf->snapshot) {
-		if (buf->end < phys->offset + buf_size(page))
-			end = buf->end - phys->offset - phys->displacement;
-
-		index -= phys->offset + phys->displacement;
-
-		if (end - index > BTS_SAFETY_MARGIN)
-			thresh = end - BTS_SAFETY_MARGIN;
-		else if (end - index > BTS_RECORD_SIZE)
-			thresh = end - BTS_RECORD_SIZE;
-		else
-			thresh = end;
-	}
-
-	ds->bts_buffer_base = (u64)(long)page_address(page) + phys->displacement;
-	ds->bts_index = ds->bts_buffer_base + index;
-	ds->bts_absolute_maximum = ds->bts_buffer_base + end;
-	ds->bts_interrupt_threshold = !buf->snapshot
-		? ds->bts_buffer_base + thresh
-		: ds->bts_absolute_maximum + BTS_RECORD_SIZE;
-}
-
-static void bts_buffer_pad_out(struct bts_phys *phys, unsigned long head)
-{
-	unsigned long index = head - phys->offset;
-
-	memset(page_address(phys->page) + index, 0, phys->size - index);
-}
-
-static bool bts_buffer_is_full(struct bts_buffer *buf, struct bts_ctx *bts)
-{
-	if (buf->snapshot)
-		return false;
-
-	if (local_read(&buf->data_size) >= bts->handle.size ||
-	    bts->handle.size - local_read(&buf->data_size) < BTS_RECORD_SIZE)
-		return true;
-
-	return false;
-}
-
-static void bts_update(struct bts_ctx *bts)
-{
-	int cpu = raw_smp_processor_id();
-	struct debug_store *ds = per_cpu(cpu_hw_events, cpu).ds;
-	struct bts_buffer *buf = perf_get_aux(&bts->handle);
-	unsigned long index = ds->bts_index - ds->bts_buffer_base, old, head;
-
-	if (!buf)
-		return;
-
-	head = index + bts_buffer_offset(buf, buf->cur_buf);
-	old = local_xchg(&buf->head, head);
-
-	if (!buf->snapshot) {
-		if (old == head)
-			return;
-
-		if (ds->bts_index >= ds->bts_absolute_maximum)
-			local_inc(&buf->lost);
-
-		/*
-		 * old and head are always in the same physical buffer, so we
-		 * can subtract them to get the data size.
-		 */
-		local_add(head - old, &buf->data_size);
-	} else {
-		local_set(&buf->data_size, head);
-	}
-}
-
-static void __bts_event_start(struct perf_event *event)
-{
-	struct bts_ctx *bts = this_cpu_ptr(&bts_ctx);
-	struct bts_buffer *buf = perf_get_aux(&bts->handle);
-	u64 config = 0;
-
-	if (!buf || bts_buffer_is_full(buf, bts))
-		return;
-
-	event->hw.itrace_started = 1;
-	event->hw.state = 0;
-
-	if (!buf->snapshot)
-		config |= ARCH_PERFMON_EVENTSEL_INT;
-	if (!event->attr.exclude_kernel)
-		config |= ARCH_PERFMON_EVENTSEL_OS;
-	if (!event->attr.exclude_user)
-		config |= ARCH_PERFMON_EVENTSEL_USR;
-
-	bts_config_buffer(buf);
-
-	/*
-	 * local barrier to make sure that ds configuration made it
-	 * before we enable BTS
-	 */
-	wmb();
-
-	intel_pmu_enable_bts(config);
-}
-
-static void bts_event_start(struct perf_event *event, int flags)
-{
-	struct bts_ctx *bts = this_cpu_ptr(&bts_ctx);
-
-	__bts_event_start(event);
-
-	/* PMI handler: this counter is running and likely generating PMIs */
-	ACCESS_ONCE(bts->started) = 1;
-}
-
-static void __bts_event_stop(struct perf_event *event)
-{
-	/*
-	 * No extra synchronization is mandated by the documentation to have
-	 * BTS data stores globally visible.
-	 */
-	intel_pmu_disable_bts();
-
-	if (event->hw.state & PERF_HES_STOPPED)
-		return;
-
-	ACCESS_ONCE(event->hw.state) |= PERF_HES_STOPPED;
-}
-
-static void bts_event_stop(struct perf_event *event, int flags)
-{
-	struct bts_ctx *bts = this_cpu_ptr(&bts_ctx);
-
-	/* PMI handler: don't restart this counter */
-	ACCESS_ONCE(bts->started) = 0;
-
-	__bts_event_stop(event);
-
-	if (flags & PERF_EF_UPDATE)
-		bts_update(bts);
-}
-
-void intel_bts_enable_local(void)
-{
-	struct bts_ctx *bts = this_cpu_ptr(&bts_ctx);
-
-	if (bts->handle.event && bts->started)
-		__bts_event_start(bts->handle.event);
-}
-
-void intel_bts_disable_local(void)
-{
-	struct bts_ctx *bts = this_cpu_ptr(&bts_ctx);
-
-	if (bts->handle.event)
-		__bts_event_stop(bts->handle.event);
-}
-
-static int
-bts_buffer_reset(struct bts_buffer *buf, struct perf_output_handle *handle)
-{
-	unsigned long head, space, next_space, pad, gap, skip, wakeup;
-	unsigned int next_buf;
-	struct bts_phys *phys, *next_phys;
-	int ret;
-
-	if (buf->snapshot)
-		return 0;
-
-	head = handle->head & ((buf->nr_pages << PAGE_SHIFT) - 1);
-	if (WARN_ON_ONCE(head != local_read(&buf->head)))
-		return -EINVAL;
-
-	phys = &buf->buf[buf->cur_buf];
-	space = phys->offset + phys->displacement + phys->size - head;
-	pad = space;
-	if (space > handle->size) {
-		space = handle->size;
-		space -= space % BTS_RECORD_SIZE;
-	}
-	if (space <= BTS_SAFETY_MARGIN) {
-		/* See if next phys buffer has more space */
-		next_buf = buf->cur_buf + 1;
-		if (next_buf >= buf->nr_bufs)
-			next_buf = 0;
-		next_phys = &buf->buf[next_buf];
-		gap = buf_size(phys->page) - phys->displacement - phys->size +
-		      next_phys->displacement;
-		skip = pad + gap;
-		if (handle->size >= skip) {
-			next_space = next_phys->size;
-			if (next_space + skip > handle->size) {
-				next_space = handle->size - skip;
-				next_space -= next_space % BTS_RECORD_SIZE;
-			}
-			if (next_space > space || !space) {
-				if (pad)
-					bts_buffer_pad_out(phys, head);
-				ret = perf_aux_output_skip(handle, skip);
-				if (ret)
-					return ret;
-				/* Advance to next phys buffer */
-				phys = next_phys;
-				space = next_space;
-				head = phys->offset + phys->displacement;
-				/*
-				 * After this, cur_buf and head won't match ds
-				 * anymore, so we must not be racing with
-				 * bts_update().
-				 */
-				buf->cur_buf = next_buf;
-				local_set(&buf->head, head);
-			}
-		}
-	}
-
-	/* Don't go far beyond wakeup watermark */
-	wakeup = BTS_SAFETY_MARGIN + BTS_RECORD_SIZE + handle->wakeup -
-		 handle->head;
-	if (space > wakeup) {
-		space = wakeup;
-		space -= space % BTS_RECORD_SIZE;
-	}
-
-	buf->end = head + space;
-
-	/*
-	 * If we have no space, the lost notification would have been sent when
-	 * we hit absolute_maximum - see bts_update()
-	 */
-	if (!space)
-		return -ENOSPC;
-
-	return 0;
-}
-
-int intel_bts_interrupt(void)
-{
-	struct bts_ctx *bts = this_cpu_ptr(&bts_ctx);
-	struct perf_event *event = bts->handle.event;
-	struct bts_buffer *buf;
-	s64 old_head;
-	int err;
-
-	if (!event || !bts->started)
-		return 0;
-
-	buf = perf_get_aux(&bts->handle);
-	/*
-	 * Skip snapshot counters: they don't use the interrupt, but
-	 * there's no other way of telling, because the pointer will
-	 * keep moving
-	 */
-	if (!buf || buf->snapshot)
-		return 0;
-
-	old_head = local_read(&buf->head);
-	bts_update(bts);
-
-	/* no new data */
-	if (old_head == local_read(&buf->head))
-		return 0;
-
-	perf_aux_output_end(&bts->handle, local_xchg(&buf->data_size, 0),
-			    !!local_xchg(&buf->lost, 0));
-
-	buf = perf_aux_output_begin(&bts->handle, event);
-	if (!buf)
-		return 1;
-
-	err = bts_buffer_reset(buf, &bts->handle);
-	if (err)
-		perf_aux_output_end(&bts->handle, 0, false);
-
-	return 1;
-}
-
-static void bts_event_del(struct perf_event *event, int mode)
-{
-	struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
-	struct bts_ctx *bts = this_cpu_ptr(&bts_ctx);
-	struct bts_buffer *buf = perf_get_aux(&bts->handle);
-
-	bts_event_stop(event, PERF_EF_UPDATE);
-
-	if (buf) {
-		if (buf->snapshot)
-			bts->handle.head =
-				local_xchg(&buf->data_size,
-					   buf->nr_pages << PAGE_SHIFT);
-		perf_aux_output_end(&bts->handle, local_xchg(&buf->data_size, 0),
-				    !!local_xchg(&buf->lost, 0));
-	}
-
-	cpuc->ds->bts_index = bts->ds_back.bts_buffer_base;
-	cpuc->ds->bts_buffer_base = bts->ds_back.bts_buffer_base;
-	cpuc->ds->bts_absolute_maximum = bts->ds_back.bts_absolute_maximum;
-	cpuc->ds->bts_interrupt_threshold = bts->ds_back.bts_interrupt_threshold;
-}
-
-static int bts_event_add(struct perf_event *event, int mode)
-{
-	struct bts_buffer *buf;
-	struct bts_ctx *bts = this_cpu_ptr(&bts_ctx);
-	struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
-	struct hw_perf_event *hwc = &event->hw;
-	int ret = -EBUSY;
-
-	event->hw.state = PERF_HES_STOPPED;
-
-	if (test_bit(INTEL_PMC_IDX_FIXED_BTS, cpuc->active_mask))
-		return -EBUSY;
-
-	if (bts->handle.event)
-		return -EBUSY;
-
-	buf = perf_aux_output_begin(&bts->handle, event);
-	if (!buf)
-		return -EINVAL;
-
-	ret = bts_buffer_reset(buf, &bts->handle);
-	if (ret) {
-		perf_aux_output_end(&bts->handle, 0, false);
-		return ret;
-	}
-
-	bts->ds_back.bts_buffer_base = cpuc->ds->bts_buffer_base;
-	bts->ds_back.bts_absolute_maximum = cpuc->ds->bts_absolute_maximum;
-	bts->ds_back.bts_interrupt_threshold = cpuc->ds->bts_interrupt_threshold;
-
-	if (mode & PERF_EF_START) {
-		bts_event_start(event, 0);
-		if (hwc->state & PERF_HES_STOPPED) {
-			bts_event_del(event, 0);
-			return -EBUSY;
-		}
-	}
-
-	return 0;
-}
-
-static void bts_event_destroy(struct perf_event *event)
-{
-	x86_release_hardware();
-	x86_del_exclusive(x86_lbr_exclusive_bts);
-}
-
-static int bts_event_init(struct perf_event *event)
-{
-	int ret;
-
-	if (event->attr.type != bts_pmu.type)
-		return -ENOENT;
-
-	if (x86_add_exclusive(x86_lbr_exclusive_bts))
-		return -EBUSY;
-
-	/*
-	 * BTS leaks kernel addresses even when CPL0 tracing is
-	 * disabled, so disallow intel_bts driver for unprivileged
-	 * users on paranoid systems since it provides trace data
-	 * to the user in a zero-copy fashion.
-	 *
-	 * Note that the default paranoia setting permits unprivileged
-	 * users to profile the kernel.
-	 */
-	if (event->attr.exclude_kernel && perf_paranoid_kernel() &&
-	    !capable(CAP_SYS_ADMIN))
-		return -EACCES;
-
-	ret = x86_reserve_hardware();
-	if (ret) {
-		x86_del_exclusive(x86_lbr_exclusive_bts);
-		return ret;
-	}
-
-	event->destroy = bts_event_destroy;
-
-	return 0;
-}
-
-static void bts_event_read(struct perf_event *event)
-{
-}
-
-static __init int bts_init(void)
-{
-	if (!boot_cpu_has(X86_FEATURE_DTES64) || !x86_pmu.bts)
-		return -ENODEV;
-
-	bts_pmu.capabilities	= PERF_PMU_CAP_AUX_NO_SG | PERF_PMU_CAP_ITRACE;
-	bts_pmu.task_ctx_nr	= perf_sw_context;
-	bts_pmu.event_init	= bts_event_init;
-	bts_pmu.add		= bts_event_add;
-	bts_pmu.del		= bts_event_del;
-	bts_pmu.start		= bts_event_start;
-	bts_pmu.stop		= bts_event_stop;
-	bts_pmu.read		= bts_event_read;
-	bts_pmu.setup_aux	= bts_buffer_setup_aux;
-	bts_pmu.free_aux	= bts_buffer_free_aux;
-
-	return perf_pmu_register(&bts_pmu, "intel_bts", -1);
-}
-arch_initcall(bts_init);
--- zfcpdump-kernel-4.4.orig/arch/x86/kernel/cpu/perf_event_intel_cqm.c
+++ /dev/null
@@ -1,1391 +0,0 @@
-/*
- * Intel Cache Quality-of-Service Monitoring (CQM) support.
- *
- * Based very, very heavily on work by Peter Zijlstra.
- */
-
-#include <linux/perf_event.h>
-#include <linux/slab.h>
-#include <asm/cpu_device_id.h>
-#include "perf_event.h"
-
-#define MSR_IA32_PQR_ASSOC	0x0c8f
-#define MSR_IA32_QM_CTR		0x0c8e
-#define MSR_IA32_QM_EVTSEL	0x0c8d
-
-static u32 cqm_max_rmid = -1;
-static unsigned int cqm_l3_scale; /* supposedly cacheline size */
-
-/**
- * struct intel_pqr_state - State cache for the PQR MSR
- * @rmid:		The cached Resource Monitoring ID
- * @closid:		The cached Class Of Service ID
- * @rmid_usecnt:	The usage counter for rmid
- *
- * The upper 32 bits of MSR_IA32_PQR_ASSOC contain closid and the
- * lower 10 bits rmid. The update to MSR_IA32_PQR_ASSOC always
- * contains both parts, so we need to cache them.
- *
- * The cache also helps to avoid pointless updates if the value does
- * not change.
- */
-struct intel_pqr_state {
-	u32			rmid;
-	u32			closid;
-	int			rmid_usecnt;
-};
-
-/*
- * The cached intel_pqr_state is strictly per CPU and can never be
- * updated from a remote CPU. Both functions which modify the state
- * (intel_cqm_event_start and intel_cqm_event_stop) are called with
- * interrupts disabled, which is sufficient for the protection.
- */
-static DEFINE_PER_CPU(struct intel_pqr_state, pqr_state);
-
-/*
- * Protects cache_cgroups and cqm_rmid_free_lru and cqm_rmid_limbo_lru.
- * Also protects event->hw.cqm_rmid
- *
- * Hold either for stability, both for modification of ->hw.cqm_rmid.
- */
-static DEFINE_MUTEX(cache_mutex);
-static DEFINE_RAW_SPINLOCK(cache_lock);
-
-/*
- * Groups of events that have the same target(s), one RMID per group.
- */
-static LIST_HEAD(cache_groups);
-
-/*
- * Mask of CPUs for reading CQM values. We only need one per-socket.
- */
-static cpumask_t cqm_cpumask;
-
-#define RMID_VAL_ERROR		(1ULL << 63)
-#define RMID_VAL_UNAVAIL	(1ULL << 62)
-
-#define QOS_L3_OCCUP_EVENT_ID	(1 << 0)
-
-#define QOS_EVENT_MASK	QOS_L3_OCCUP_EVENT_ID
-
-/*
- * This is central to the rotation algorithm in __intel_cqm_rmid_rotate().
- *
- * This rmid is always free and is guaranteed to have an associated
- * near-zero occupancy value, i.e. no cachelines are tagged with this
- * RMID, once __intel_cqm_rmid_rotate() returns.
- */
-static u32 intel_cqm_rotation_rmid;
-
-#define INVALID_RMID		(-1)
-
-/*
- * Is @rmid valid for programming the hardware?
- *
- * rmid 0 is reserved by the hardware for all non-monitored tasks, which
- * means that we should never come across an rmid with that value.
- * Likewise, an rmid value of -1 is used to indicate "no rmid currently
- * assigned" and is used as part of the rotation code.
- */
-static inline bool __rmid_valid(u32 rmid)
-{
-	if (!rmid || rmid == INVALID_RMID)
-		return false;
-
-	return true;
-}
-
-static u64 __rmid_read(u32 rmid)
-{
-	u64 val;
-
-	/*
-	 * Ignore the SDM, this thing is _NOTHING_ like a regular perfcnt,
-	 * it just says that to increase confusion.
-	 */
-	wrmsr(MSR_IA32_QM_EVTSEL, QOS_L3_OCCUP_EVENT_ID, rmid);
-	rdmsrl(MSR_IA32_QM_CTR, val);
-
-	/*
-	 * Aside from the ERROR and UNAVAIL bits, assume this thing returns
-	 * the number of cachelines tagged with @rmid.
-	 */
-	return val;
-}
-
-enum rmid_recycle_state {
-	RMID_YOUNG = 0,
-	RMID_AVAILABLE,
-	RMID_DIRTY,
-};
-
-struct cqm_rmid_entry {
-	u32 rmid;
-	enum rmid_recycle_state state;
-	struct list_head list;
-	unsigned long queue_time;
-};
-
-/*
- * cqm_rmid_free_lru - A least recently used list of RMIDs.
- *
- * Oldest entry at the head, newest (most recently used) entry at the
- * tail. This list is never traversed, it's only used to keep track of
- * the lru order. That is, we only pick entries of the head or insert
- * them on the tail.
- *
- * All entries on the list are 'free', and their RMIDs are not currently
- * in use. To mark an RMID as in use, remove its entry from the lru
- * list.
- *
- *
- * cqm_rmid_limbo_lru - list of currently unused but (potentially) dirty RMIDs.
- *
- * This list is contains RMIDs that no one is currently using but that
- * may have a non-zero occupancy value associated with them. The
- * rotation worker moves RMIDs from the limbo list to the free list once
- * the occupancy value drops below __intel_cqm_threshold.
- *
- * Both lists are protected by cache_mutex.
- */
-static LIST_HEAD(cqm_rmid_free_lru);
-static LIST_HEAD(cqm_rmid_limbo_lru);
-
-/*
- * We use a simple array of pointers so that we can lookup a struct
- * cqm_rmid_entry in O(1). This alleviates the callers of __get_rmid()
- * and __put_rmid() from having to worry about dealing with struct
- * cqm_rmid_entry - they just deal with rmids, i.e. integers.
- *
- * Once this array is initialized it is read-only. No locks are required
- * to access it.
- *
- * All entries for all RMIDs can be looked up in the this array at all
- * times.
- */
-static struct cqm_rmid_entry **cqm_rmid_ptrs;
-
-static inline struct cqm_rmid_entry *__rmid_entry(u32 rmid)
-{
-	struct cqm_rmid_entry *entry;
-
-	entry = cqm_rmid_ptrs[rmid];
-	WARN_ON(entry->rmid != rmid);
-
-	return entry;
-}
-
-/*
- * Returns < 0 on fail.
- *
- * We expect to be called with cache_mutex held.
- */
-static u32 __get_rmid(void)
-{
-	struct cqm_rmid_entry *entry;
-
-	lockdep_assert_held(&cache_mutex);
-
-	if (list_empty(&cqm_rmid_free_lru))
-		return INVALID_RMID;
-
-	entry = list_first_entry(&cqm_rmid_free_lru, struct cqm_rmid_entry, list);
-	list_del(&entry->list);
-
-	return entry->rmid;
-}
-
-static void __put_rmid(u32 rmid)
-{
-	struct cqm_rmid_entry *entry;
-
-	lockdep_assert_held(&cache_mutex);
-
-	WARN_ON(!__rmid_valid(rmid));
-	entry = __rmid_entry(rmid);
-
-	entry->queue_time = jiffies;
-	entry->state = RMID_YOUNG;
-
-	list_add_tail(&entry->list, &cqm_rmid_limbo_lru);
-}
-
-static int intel_cqm_setup_rmid_cache(void)
-{
-	struct cqm_rmid_entry *entry;
-	unsigned int nr_rmids;
-	int r = 0;
-
-	nr_rmids = cqm_max_rmid + 1;
-	cqm_rmid_ptrs = kmalloc(sizeof(struct cqm_rmid_entry *) *
-				nr_rmids, GFP_KERNEL);
-	if (!cqm_rmid_ptrs)
-		return -ENOMEM;
-
-	for (; r <= cqm_max_rmid; r++) {
-		struct cqm_rmid_entry *entry;
-
-		entry = kmalloc(sizeof(*entry), GFP_KERNEL);
-		if (!entry)
-			goto fail;
-
-		INIT_LIST_HEAD(&entry->list);
-		entry->rmid = r;
-		cqm_rmid_ptrs[r] = entry;
-
-		list_add_tail(&entry->list, &cqm_rmid_free_lru);
-	}
-
-	/*
-	 * RMID 0 is special and is always allocated. It's used for all
-	 * tasks that are not monitored.
-	 */
-	entry = __rmid_entry(0);
-	list_del(&entry->list);
-
-	mutex_lock(&cache_mutex);
-	intel_cqm_rotation_rmid = __get_rmid();
-	mutex_unlock(&cache_mutex);
-
-	return 0;
-fail:
-	while (r--)
-		kfree(cqm_rmid_ptrs[r]);
-
-	kfree(cqm_rmid_ptrs);
-	return -ENOMEM;
-}
-
-/*
- * Determine if @a and @b measure the same set of tasks.
- *
- * If @a and @b measure the same set of tasks then we want to share a
- * single RMID.
- */
-static bool __match_event(struct perf_event *a, struct perf_event *b)
-{
-	/* Per-cpu and task events don't mix */
-	if ((a->attach_state & PERF_ATTACH_TASK) !=
-	    (b->attach_state & PERF_ATTACH_TASK))
-		return false;
-
-#ifdef CONFIG_CGROUP_PERF
-	if (a->cgrp != b->cgrp)
-		return false;
-#endif
-
-	/* If not task event, we're machine wide */
-	if (!(b->attach_state & PERF_ATTACH_TASK))
-		return true;
-
-	/*
-	 * Events that target same task are placed into the same cache group.
-	 */
-	if (a->hw.target == b->hw.target)
-		return true;
-
-	/*
-	 * Are we an inherited event?
-	 */
-	if (b->parent == a)
-		return true;
-
-	return false;
-}
-
-#ifdef CONFIG_CGROUP_PERF
-static inline struct perf_cgroup *event_to_cgroup(struct perf_event *event)
-{
-	if (event->attach_state & PERF_ATTACH_TASK)
-		return perf_cgroup_from_task(event->hw.target, event->ctx);
-
-	return event->cgrp;
-}
-#endif
-
-/*
- * Determine if @a's tasks intersect with @b's tasks
- *
- * There are combinations of events that we explicitly prohibit,
- *
- *		   PROHIBITS
- *     system-wide    -> 	cgroup and task
- *     cgroup 	      ->	system-wide
- *     		      ->	task in cgroup
- *     task 	      -> 	system-wide
- *     		      ->	task in cgroup
- *
- * Call this function before allocating an RMID.
- */
-static bool __conflict_event(struct perf_event *a, struct perf_event *b)
-{
-#ifdef CONFIG_CGROUP_PERF
-	/*
-	 * We can have any number of cgroups but only one system-wide
-	 * event at a time.
-	 */
-	if (a->cgrp && b->cgrp) {
-		struct perf_cgroup *ac = a->cgrp;
-		struct perf_cgroup *bc = b->cgrp;
-
-		/*
-		 * This condition should have been caught in
-		 * __match_event() and we should be sharing an RMID.
-		 */
-		WARN_ON_ONCE(ac == bc);
-
-		if (cgroup_is_descendant(ac->css.cgroup, bc->css.cgroup) ||
-		    cgroup_is_descendant(bc->css.cgroup, ac->css.cgroup))
-			return true;
-
-		return false;
-	}
-
-	if (a->cgrp || b->cgrp) {
-		struct perf_cgroup *ac, *bc;
-
-		/*
-		 * cgroup and system-wide events are mutually exclusive
-		 */
-		if ((a->cgrp && !(b->attach_state & PERF_ATTACH_TASK)) ||
-		    (b->cgrp && !(a->attach_state & PERF_ATTACH_TASK)))
-			return true;
-
-		/*
-		 * Ensure neither event is part of the other's cgroup
-		 */
-		ac = event_to_cgroup(a);
-		bc = event_to_cgroup(b);
-		if (ac == bc)
-			return true;
-
-		/*
-		 * Must have cgroup and non-intersecting task events.
-		 */
-		if (!ac || !bc)
-			return false;
-
-		/*
-		 * We have cgroup and task events, and the task belongs
-		 * to a cgroup. Check for for overlap.
-		 */
-		if (cgroup_is_descendant(ac->css.cgroup, bc->css.cgroup) ||
-		    cgroup_is_descendant(bc->css.cgroup, ac->css.cgroup))
-			return true;
-
-		return false;
-	}
-#endif
-	/*
-	 * If one of them is not a task, same story as above with cgroups.
-	 */
-	if (!(a->attach_state & PERF_ATTACH_TASK) ||
-	    !(b->attach_state & PERF_ATTACH_TASK))
-		return true;
-
-	/*
-	 * Must be non-overlapping.
-	 */
-	return false;
-}
-
-struct rmid_read {
-	u32 rmid;
-	atomic64_t value;
-};
-
-static void __intel_cqm_event_count(void *info);
-
-/*
- * Exchange the RMID of a group of events.
- */
-static u32 intel_cqm_xchg_rmid(struct perf_event *group, u32 rmid)
-{
-	struct perf_event *event;
-	struct list_head *head = &group->hw.cqm_group_entry;
-	u32 old_rmid = group->hw.cqm_rmid;
-
-	lockdep_assert_held(&cache_mutex);
-
-	/*
-	 * If our RMID is being deallocated, perform a read now.
-	 */
-	if (__rmid_valid(old_rmid) && !__rmid_valid(rmid)) {
-		struct rmid_read rr = {
-			.value = ATOMIC64_INIT(0),
-			.rmid = old_rmid,
-		};
-
-		on_each_cpu_mask(&cqm_cpumask, __intel_cqm_event_count,
-				 &rr, 1);
-		local64_set(&group->count, atomic64_read(&rr.value));
-	}
-
-	raw_spin_lock_irq(&cache_lock);
-
-	group->hw.cqm_rmid = rmid;
-	list_for_each_entry(event, head, hw.cqm_group_entry)
-		event->hw.cqm_rmid = rmid;
-
-	raw_spin_unlock_irq(&cache_lock);
-
-	return old_rmid;
-}
-
-/*
- * If we fail to assign a new RMID for intel_cqm_rotation_rmid because
- * cachelines are still tagged with RMIDs in limbo, we progressively
- * increment the threshold until we find an RMID in limbo with <=
- * __intel_cqm_threshold lines tagged. This is designed to mitigate the
- * problem where cachelines tagged with an RMID are not steadily being
- * evicted.
- *
- * On successful rotations we decrease the threshold back towards zero.
- *
- * __intel_cqm_max_threshold provides an upper bound on the threshold,
- * and is measured in bytes because it's exposed to userland.
- */
-static unsigned int __intel_cqm_threshold;
-static unsigned int __intel_cqm_max_threshold;
-
-/*
- * Test whether an RMID has a zero occupancy value on this cpu.
- */
-static void intel_cqm_stable(void *arg)
-{
-	struct cqm_rmid_entry *entry;
-
-	list_for_each_entry(entry, &cqm_rmid_limbo_lru, list) {
-		if (entry->state != RMID_AVAILABLE)
-			break;
-
-		if (__rmid_read(entry->rmid) > __intel_cqm_threshold)
-			entry->state = RMID_DIRTY;
-	}
-}
-
-/*
- * If we have group events waiting for an RMID that don't conflict with
- * events already running, assign @rmid.
- */
-static bool intel_cqm_sched_in_event(u32 rmid)
-{
-	struct perf_event *leader, *event;
-
-	lockdep_assert_held(&cache_mutex);
-
-	leader = list_first_entry(&cache_groups, struct perf_event,
-				  hw.cqm_groups_entry);
-	event = leader;
-
-	list_for_each_entry_continue(event, &cache_groups,
-				     hw.cqm_groups_entry) {
-		if (__rmid_valid(event->hw.cqm_rmid))
-			continue;
-
-		if (__conflict_event(event, leader))
-			continue;
-
-		intel_cqm_xchg_rmid(event, rmid);
-		return true;
-	}
-
-	return false;
-}
-
-/*
- * Initially use this constant for both the limbo queue time and the
- * rotation timer interval, pmu::hrtimer_interval_ms.
- *
- * They don't need to be the same, but the two are related since if you
- * rotate faster than you recycle RMIDs, you may run out of available
- * RMIDs.
- */
-#define RMID_DEFAULT_QUEUE_TIME 250	/* ms */
-
-static unsigned int __rmid_queue_time_ms = RMID_DEFAULT_QUEUE_TIME;
-
-/*
- * intel_cqm_rmid_stabilize - move RMIDs from limbo to free list
- * @nr_available: number of freeable RMIDs on the limbo list
- *
- * Quiescent state; wait for all 'freed' RMIDs to become unused, i.e. no
- * cachelines are tagged with those RMIDs. After this we can reuse them
- * and know that the current set of active RMIDs is stable.
- *
- * Return %true or %false depending on whether stabilization needs to be
- * reattempted.
- *
- * If we return %true then @nr_available is updated to indicate the
- * number of RMIDs on the limbo list that have been queued for the
- * minimum queue time (RMID_AVAILABLE), but whose data occupancy values
- * are above __intel_cqm_threshold.
- */
-static bool intel_cqm_rmid_stabilize(unsigned int *available)
-{
-	struct cqm_rmid_entry *entry, *tmp;
-
-	lockdep_assert_held(&cache_mutex);
-
-	*available = 0;
-	list_for_each_entry(entry, &cqm_rmid_limbo_lru, list) {
-		unsigned long min_queue_time;
-		unsigned long now = jiffies;
-
-		/*
-		 * We hold RMIDs placed into limbo for a minimum queue
-		 * time. Before the minimum queue time has elapsed we do
-		 * not recycle RMIDs.
-		 *
-		 * The reasoning is that until a sufficient time has
-		 * passed since we stopped using an RMID, any RMID
-		 * placed onto the limbo list will likely still have
-		 * data tagged in the cache, which means we'll probably
-		 * fail to recycle it anyway.
-		 *
-		 * We can save ourselves an expensive IPI by skipping
-		 * any RMIDs that have not been queued for the minimum
-		 * time.
-		 */
-		min_queue_time = entry->queue_time +
-			msecs_to_jiffies(__rmid_queue_time_ms);
-
-		if (time_after(min_queue_time, now))
-			break;
-
-		entry->state = RMID_AVAILABLE;
-		(*available)++;
-	}
-
-	/*
-	 * Fast return if none of the RMIDs on the limbo list have been
-	 * sitting on the queue for the minimum queue time.
-	 */
-	if (!*available)
-		return false;
-
-	/*
-	 * Test whether an RMID is free for each package.
-	 */
-	on_each_cpu_mask(&cqm_cpumask, intel_cqm_stable, NULL, true);
-
-	list_for_each_entry_safe(entry, tmp, &cqm_rmid_limbo_lru, list) {
-		/*
-		 * Exhausted all RMIDs that have waited min queue time.
-		 */
-		if (entry->state == RMID_YOUNG)
-			break;
-
-		if (entry->state == RMID_DIRTY)
-			continue;
-
-		list_del(&entry->list);	/* remove from limbo */
-
-		/*
-		 * The rotation RMID gets priority if it's
-		 * currently invalid. In which case, skip adding
-		 * the RMID to the the free lru.
-		 */
-		if (!__rmid_valid(intel_cqm_rotation_rmid)) {
-			intel_cqm_rotation_rmid = entry->rmid;
-			continue;
-		}
-
-		/*
-		 * If we have groups waiting for RMIDs, hand
-		 * them one now provided they don't conflict.
-		 */
-		if (intel_cqm_sched_in_event(entry->rmid))
-			continue;
-
-		/*
-		 * Otherwise place it onto the free list.
-		 */
-		list_add_tail(&entry->list, &cqm_rmid_free_lru);
-	}
-
-
-	return __rmid_valid(intel_cqm_rotation_rmid);
-}
-
-/*
- * Pick a victim group and move it to the tail of the group list.
- * @next: The first group without an RMID
- */
-static void __intel_cqm_pick_and_rotate(struct perf_event *next)
-{
-	struct perf_event *rotor;
-	u32 rmid;
-
-	lockdep_assert_held(&cache_mutex);
-
-	rotor = list_first_entry(&cache_groups, struct perf_event,
-				 hw.cqm_groups_entry);
-
-	/*
-	 * The group at the front of the list should always have a valid
-	 * RMID. If it doesn't then no groups have RMIDs assigned and we
-	 * don't need to rotate the list.
-	 */
-	if (next == rotor)
-		return;
-
-	rmid = intel_cqm_xchg_rmid(rotor, INVALID_RMID);
-	__put_rmid(rmid);
-
-	list_rotate_left(&cache_groups);
-}
-
-/*
- * Deallocate the RMIDs from any events that conflict with @event, and
- * place them on the back of the group list.
- */
-static void intel_cqm_sched_out_conflicting_events(struct perf_event *event)
-{
-	struct perf_event *group, *g;
-	u32 rmid;
-
-	lockdep_assert_held(&cache_mutex);
-
-	list_for_each_entry_safe(group, g, &cache_groups, hw.cqm_groups_entry) {
-		if (group == event)
-			continue;
-
-		rmid = group->hw.cqm_rmid;
-
-		/*
-		 * Skip events that don't have a valid RMID.
-		 */
-		if (!__rmid_valid(rmid))
-			continue;
-
-		/*
-		 * No conflict? No problem! Leave the event alone.
-		 */
-		if (!__conflict_event(group, event))
-			continue;
-
-		intel_cqm_xchg_rmid(group, INVALID_RMID);
-		__put_rmid(rmid);
-	}
-}
-
-/*
- * Attempt to rotate the groups and assign new RMIDs.
- *
- * We rotate for two reasons,
- *   1. To handle the scheduling of conflicting events
- *   2. To recycle RMIDs
- *
- * Rotating RMIDs is complicated because the hardware doesn't give us
- * any clues.
- *
- * There's problems with the hardware interface; when you change the
- * task:RMID map cachelines retain their 'old' tags, giving a skewed
- * picture. In order to work around this, we must always keep one free
- * RMID - intel_cqm_rotation_rmid.
- *
- * Rotation works by taking away an RMID from a group (the old RMID),
- * and assigning the free RMID to another group (the new RMID). We must
- * then wait for the old RMID to not be used (no cachelines tagged).
- * This ensure that all cachelines are tagged with 'active' RMIDs. At
- * this point we can start reading values for the new RMID and treat the
- * old RMID as the free RMID for the next rotation.
- *
- * Return %true or %false depending on whether we did any rotating.
- */
-static bool __intel_cqm_rmid_rotate(void)
-{
-	struct perf_event *group, *start = NULL;
-	unsigned int threshold_limit;
-	unsigned int nr_needed = 0;
-	unsigned int nr_available;
-	bool rotated = false;
-
-	mutex_lock(&cache_mutex);
-
-again:
-	/*
-	 * Fast path through this function if there are no groups and no
-	 * RMIDs that need cleaning.
-	 */
-	if (list_empty(&cache_groups) && list_empty(&cqm_rmid_limbo_lru))
-		goto out;
-
-	list_for_each_entry(group, &cache_groups, hw.cqm_groups_entry) {
-		if (!__rmid_valid(group->hw.cqm_rmid)) {
-			if (!start)
-				start = group;
-			nr_needed++;
-		}
-	}
-
-	/*
-	 * We have some event groups, but they all have RMIDs assigned
-	 * and no RMIDs need cleaning.
-	 */
-	if (!nr_needed && list_empty(&cqm_rmid_limbo_lru))
-		goto out;
-
-	if (!nr_needed)
-		goto stabilize;
-
-	/*
-	 * We have more event groups without RMIDs than available RMIDs,
-	 * or we have event groups that conflict with the ones currently
-	 * scheduled.
-	 *
-	 * We force deallocate the rmid of the group at the head of
-	 * cache_groups. The first event group without an RMID then gets
-	 * assigned intel_cqm_rotation_rmid. This ensures we always make
-	 * forward progress.
-	 *
-	 * Rotate the cache_groups list so the previous head is now the
-	 * tail.
-	 */
-	__intel_cqm_pick_and_rotate(start);
-
-	/*
-	 * If the rotation is going to succeed, reduce the threshold so
-	 * that we don't needlessly reuse dirty RMIDs.
-	 */
-	if (__rmid_valid(intel_cqm_rotation_rmid)) {
-		intel_cqm_xchg_rmid(start, intel_cqm_rotation_rmid);
-		intel_cqm_rotation_rmid = __get_rmid();
-
-		intel_cqm_sched_out_conflicting_events(start);
-
-		if (__intel_cqm_threshold)
-			__intel_cqm_threshold--;
-	}
-
-	rotated = true;
-
-stabilize:
-	/*
-	 * We now need to stablize the RMID we freed above (if any) to
-	 * ensure that the next time we rotate we have an RMID with zero
-	 * occupancy value.
-	 *
-	 * Alternatively, if we didn't need to perform any rotation,
-	 * we'll have a bunch of RMIDs in limbo that need stabilizing.
-	 */
-	threshold_limit = __intel_cqm_max_threshold / cqm_l3_scale;
-
-	while (intel_cqm_rmid_stabilize(&nr_available) &&
-	       __intel_cqm_threshold < threshold_limit) {
-		unsigned int steal_limit;
-
-		/*
-		 * Don't spin if nobody is actively waiting for an RMID,
-		 * the rotation worker will be kicked as soon as an
-		 * event needs an RMID anyway.
-		 */
-		if (!nr_needed)
-			break;
-
-		/* Allow max 25% of RMIDs to be in limbo. */
-		steal_limit = (cqm_max_rmid + 1) / 4;
-
-		/*
-		 * We failed to stabilize any RMIDs so our rotation
-		 * logic is now stuck. In order to make forward progress
-		 * we have a few options:
-		 *
-		 *   1. rotate ("steal") another RMID
-		 *   2. increase the threshold
-		 *   3. do nothing
-		 *
-		 * We do both of 1. and 2. until we hit the steal limit.
-		 *
-		 * The steal limit prevents all RMIDs ending up on the
-		 * limbo list. This can happen if every RMID has a
-		 * non-zero occupancy above threshold_limit, and the
-		 * occupancy values aren't dropping fast enough.
-		 *
-		 * Note that there is prioritisation at work here - we'd
-		 * rather increase the number of RMIDs on the limbo list
-		 * than increase the threshold, because increasing the
-		 * threshold skews the event data (because we reuse
-		 * dirty RMIDs) - threshold bumps are a last resort.
-		 */
-		if (nr_available < steal_limit)
-			goto again;
-
-		__intel_cqm_threshold++;
-	}
-
-out:
-	mutex_unlock(&cache_mutex);
-	return rotated;
-}
-
-static void intel_cqm_rmid_rotate(struct work_struct *work);
-
-static DECLARE_DELAYED_WORK(intel_cqm_rmid_work, intel_cqm_rmid_rotate);
-
-static struct pmu intel_cqm_pmu;
-
-static void intel_cqm_rmid_rotate(struct work_struct *work)
-{
-	unsigned long delay;
-
-	__intel_cqm_rmid_rotate();
-
-	delay = msecs_to_jiffies(intel_cqm_pmu.hrtimer_interval_ms);
-	schedule_delayed_work(&intel_cqm_rmid_work, delay);
-}
-
-/*
- * Find a group and setup RMID.
- *
- * If we're part of a group, we use the group's RMID.
- */
-static void intel_cqm_setup_event(struct perf_event *event,
-				  struct perf_event **group)
-{
-	struct perf_event *iter;
-	bool conflict = false;
-	u32 rmid;
-
-	list_for_each_entry(iter, &cache_groups, hw.cqm_groups_entry) {
-		rmid = iter->hw.cqm_rmid;
-
-		if (__match_event(iter, event)) {
-			/* All tasks in a group share an RMID */
-			event->hw.cqm_rmid = rmid;
-			*group = iter;
-			return;
-		}
-
-		/*
-		 * We only care about conflicts for events that are
-		 * actually scheduled in (and hence have a valid RMID).
-		 */
-		if (__conflict_event(iter, event) && __rmid_valid(rmid))
-			conflict = true;
-	}
-
-	if (conflict)
-		rmid = INVALID_RMID;
-	else
-		rmid = __get_rmid();
-
-	event->hw.cqm_rmid = rmid;
-}
-
-static void intel_cqm_event_read(struct perf_event *event)
-{
-	unsigned long flags;
-	u32 rmid;
-	u64 val;
-
-	/*
-	 * Task events are handled by intel_cqm_event_count().
-	 */
-	if (event->cpu == -1)
-		return;
-
-	raw_spin_lock_irqsave(&cache_lock, flags);
-	rmid = event->hw.cqm_rmid;
-
-	if (!__rmid_valid(rmid))
-		goto out;
-
-	val = __rmid_read(rmid);
-
-	/*
-	 * Ignore this reading on error states and do not update the value.
-	 */
-	if (val & (RMID_VAL_ERROR | RMID_VAL_UNAVAIL))
-		goto out;
-
-	local64_set(&event->count, val);
-out:
-	raw_spin_unlock_irqrestore(&cache_lock, flags);
-}
-
-static void __intel_cqm_event_count(void *info)
-{
-	struct rmid_read *rr = info;
-	u64 val;
-
-	val = __rmid_read(rr->rmid);
-
-	if (val & (RMID_VAL_ERROR | RMID_VAL_UNAVAIL))
-		return;
-
-	atomic64_add(val, &rr->value);
-}
-
-static inline bool cqm_group_leader(struct perf_event *event)
-{
-	return !list_empty(&event->hw.cqm_groups_entry);
-}
-
-static u64 intel_cqm_event_count(struct perf_event *event)
-{
-	unsigned long flags;
-	struct rmid_read rr = {
-		.value = ATOMIC64_INIT(0),
-	};
-
-	/*
-	 * We only need to worry about task events. System-wide events
-	 * are handled like usual, i.e. entirely with
-	 * intel_cqm_event_read().
-	 */
-	if (event->cpu != -1)
-		return __perf_event_count(event);
-
-	/*
-	 * Only the group leader gets to report values. This stops us
-	 * reporting duplicate values to userspace, and gives us a clear
-	 * rule for which task gets to report the values.
-	 *
-	 * Note that it is impossible to attribute these values to
-	 * specific packages - we forfeit that ability when we create
-	 * task events.
-	 */
-	if (!cqm_group_leader(event))
-		return 0;
-
-	/*
-	 * Getting up-to-date values requires an SMP IPI which is not
-	 * possible if we're being called in interrupt context. Return
-	 * the cached values instead.
-	 */
-	if (unlikely(in_interrupt()))
-		goto out;
-
-	/*
-	 * Notice that we don't perform the reading of an RMID
-	 * atomically, because we can't hold a spin lock across the
-	 * IPIs.
-	 *
-	 * Speculatively perform the read, since @event might be
-	 * assigned a different (possibly invalid) RMID while we're
-	 * busying performing the IPI calls. It's therefore necessary to
-	 * check @event's RMID afterwards, and if it has changed,
-	 * discard the result of the read.
-	 */
-	rr.rmid = ACCESS_ONCE(event->hw.cqm_rmid);
-
-	if (!__rmid_valid(rr.rmid))
-		goto out;
-
-	on_each_cpu_mask(&cqm_cpumask, __intel_cqm_event_count, &rr, 1);
-
-	raw_spin_lock_irqsave(&cache_lock, flags);
-	if (event->hw.cqm_rmid == rr.rmid)
-		local64_set(&event->count, atomic64_read(&rr.value));
-	raw_spin_unlock_irqrestore(&cache_lock, flags);
-out:
-	return __perf_event_count(event);
-}
-
-static void intel_cqm_event_start(struct perf_event *event, int mode)
-{
-	struct intel_pqr_state *state = this_cpu_ptr(&pqr_state);
-	u32 rmid = event->hw.cqm_rmid;
-
-	if (!(event->hw.cqm_state & PERF_HES_STOPPED))
-		return;
-
-	event->hw.cqm_state &= ~PERF_HES_STOPPED;
-
-	if (state->rmid_usecnt++) {
-		if (!WARN_ON_ONCE(state->rmid != rmid))
-			return;
-	} else {
-		WARN_ON_ONCE(state->rmid);
-	}
-
-	state->rmid = rmid;
-	wrmsr(MSR_IA32_PQR_ASSOC, rmid, state->closid);
-}
-
-static void intel_cqm_event_stop(struct perf_event *event, int mode)
-{
-	struct intel_pqr_state *state = this_cpu_ptr(&pqr_state);
-
-	if (event->hw.cqm_state & PERF_HES_STOPPED)
-		return;
-
-	event->hw.cqm_state |= PERF_HES_STOPPED;
-
-	intel_cqm_event_read(event);
-
-	if (!--state->rmid_usecnt) {
-		state->rmid = 0;
-		wrmsr(MSR_IA32_PQR_ASSOC, 0, state->closid);
-	} else {
-		WARN_ON_ONCE(!state->rmid);
-	}
-}
-
-static int intel_cqm_event_add(struct perf_event *event, int mode)
-{
-	unsigned long flags;
-	u32 rmid;
-
-	raw_spin_lock_irqsave(&cache_lock, flags);
-
-	event->hw.cqm_state = PERF_HES_STOPPED;
-	rmid = event->hw.cqm_rmid;
-
-	if (__rmid_valid(rmid) && (mode & PERF_EF_START))
-		intel_cqm_event_start(event, mode);
-
-	raw_spin_unlock_irqrestore(&cache_lock, flags);
-
-	return 0;
-}
-
-static void intel_cqm_event_destroy(struct perf_event *event)
-{
-	struct perf_event *group_other = NULL;
-
-	mutex_lock(&cache_mutex);
-
-	/*
-	 * If there's another event in this group...
-	 */
-	if (!list_empty(&event->hw.cqm_group_entry)) {
-		group_other = list_first_entry(&event->hw.cqm_group_entry,
-					       struct perf_event,
-					       hw.cqm_group_entry);
-		list_del(&event->hw.cqm_group_entry);
-	}
-
-	/*
-	 * And we're the group leader..
-	 */
-	if (cqm_group_leader(event)) {
-		/*
-		 * If there was a group_other, make that leader, otherwise
-		 * destroy the group and return the RMID.
-		 */
-		if (group_other) {
-			list_replace(&event->hw.cqm_groups_entry,
-				     &group_other->hw.cqm_groups_entry);
-		} else {
-			u32 rmid = event->hw.cqm_rmid;
-
-			if (__rmid_valid(rmid))
-				__put_rmid(rmid);
-			list_del(&event->hw.cqm_groups_entry);
-		}
-	}
-
-	mutex_unlock(&cache_mutex);
-}
-
-static int intel_cqm_event_init(struct perf_event *event)
-{
-	struct perf_event *group = NULL;
-	bool rotate = false;
-
-	if (event->attr.type != intel_cqm_pmu.type)
-		return -ENOENT;
-
-	if (event->attr.config & ~QOS_EVENT_MASK)
-		return -EINVAL;
-
-	/* unsupported modes and filters */
-	if (event->attr.exclude_user   ||
-	    event->attr.exclude_kernel ||
-	    event->attr.exclude_hv     ||
-	    event->attr.exclude_idle   ||
-	    event->attr.exclude_host   ||
-	    event->attr.exclude_guest  ||
-	    event->attr.sample_period) /* no sampling */
-		return -EINVAL;
-
-	INIT_LIST_HEAD(&event->hw.cqm_group_entry);
-	INIT_LIST_HEAD(&event->hw.cqm_groups_entry);
-
-	event->destroy = intel_cqm_event_destroy;
-
-	mutex_lock(&cache_mutex);
-
-	/* Will also set rmid */
-	intel_cqm_setup_event(event, &group);
-
-	if (group) {
-		list_add_tail(&event->hw.cqm_group_entry,
-			      &group->hw.cqm_group_entry);
-	} else {
-		list_add_tail(&event->hw.cqm_groups_entry,
-			      &cache_groups);
-
-		/*
-		 * All RMIDs are either in use or have recently been
-		 * used. Kick the rotation worker to clean/free some.
-		 *
-		 * We only do this for the group leader, rather than for
-		 * every event in a group to save on needless work.
-		 */
-		if (!__rmid_valid(event->hw.cqm_rmid))
-			rotate = true;
-	}
-
-	mutex_unlock(&cache_mutex);
-
-	if (rotate)
-		schedule_delayed_work(&intel_cqm_rmid_work, 0);
-
-	return 0;
-}
-
-EVENT_ATTR_STR(llc_occupancy, intel_cqm_llc, "event=0x01");
-EVENT_ATTR_STR(llc_occupancy.per-pkg, intel_cqm_llc_pkg, "1");
-EVENT_ATTR_STR(llc_occupancy.unit, intel_cqm_llc_unit, "Bytes");
-EVENT_ATTR_STR(llc_occupancy.scale, intel_cqm_llc_scale, NULL);
-EVENT_ATTR_STR(llc_occupancy.snapshot, intel_cqm_llc_snapshot, "1");
-
-static struct attribute *intel_cqm_events_attr[] = {
-	EVENT_PTR(intel_cqm_llc),
-	EVENT_PTR(intel_cqm_llc_pkg),
-	EVENT_PTR(intel_cqm_llc_unit),
-	EVENT_PTR(intel_cqm_llc_scale),
-	EVENT_PTR(intel_cqm_llc_snapshot),
-	NULL,
-};
-
-static struct attribute_group intel_cqm_events_group = {
-	.name = "events",
-	.attrs = intel_cqm_events_attr,
-};
-
-PMU_FORMAT_ATTR(event, "config:0-7");
-static struct attribute *intel_cqm_formats_attr[] = {
-	&format_attr_event.attr,
-	NULL,
-};
-
-static struct attribute_group intel_cqm_format_group = {
-	.name = "format",
-	.attrs = intel_cqm_formats_attr,
-};
-
-static ssize_t
-max_recycle_threshold_show(struct device *dev, struct device_attribute *attr,
-			   char *page)
-{
-	ssize_t rv;
-
-	mutex_lock(&cache_mutex);
-	rv = snprintf(page, PAGE_SIZE-1, "%u\n", __intel_cqm_max_threshold);
-	mutex_unlock(&cache_mutex);
-
-	return rv;
-}
-
-static ssize_t
-max_recycle_threshold_store(struct device *dev,
-			    struct device_attribute *attr,
-			    const char *buf, size_t count)
-{
-	unsigned int bytes, cachelines;
-	int ret;
-
-	ret = kstrtouint(buf, 0, &bytes);
-	if (ret)
-		return ret;
-
-	mutex_lock(&cache_mutex);
-
-	__intel_cqm_max_threshold = bytes;
-	cachelines = bytes / cqm_l3_scale;
-
-	/*
-	 * The new maximum takes effect immediately.
-	 */
-	if (__intel_cqm_threshold > cachelines)
-		__intel_cqm_threshold = cachelines;
-
-	mutex_unlock(&cache_mutex);
-
-	return count;
-}
-
-static DEVICE_ATTR_RW(max_recycle_threshold);
-
-static struct attribute *intel_cqm_attrs[] = {
-	&dev_attr_max_recycle_threshold.attr,
-	NULL,
-};
-
-static const struct attribute_group intel_cqm_group = {
-	.attrs = intel_cqm_attrs,
-};
-
-static const struct attribute_group *intel_cqm_attr_groups[] = {
-	&intel_cqm_events_group,
-	&intel_cqm_format_group,
-	&intel_cqm_group,
-	NULL,
-};
-
-static struct pmu intel_cqm_pmu = {
-	.hrtimer_interval_ms = RMID_DEFAULT_QUEUE_TIME,
-	.attr_groups	     = intel_cqm_attr_groups,
-	.task_ctx_nr	     = perf_sw_context,
-	.event_init	     = intel_cqm_event_init,
-	.add		     = intel_cqm_event_add,
-	.del		     = intel_cqm_event_stop,
-	.start		     = intel_cqm_event_start,
-	.stop		     = intel_cqm_event_stop,
-	.read		     = intel_cqm_event_read,
-	.count		     = intel_cqm_event_count,
-};
-
-static inline void cqm_pick_event_reader(int cpu)
-{
-	int phys_id = topology_physical_package_id(cpu);
-	int i;
-
-	for_each_cpu(i, &cqm_cpumask) {
-		if (phys_id == topology_physical_package_id(i))
-			return;	/* already got reader for this socket */
-	}
-
-	cpumask_set_cpu(cpu, &cqm_cpumask);
-}
-
-static void intel_cqm_cpu_starting(unsigned int cpu)
-{
-	struct intel_pqr_state *state = &per_cpu(pqr_state, cpu);
-	struct cpuinfo_x86 *c = &cpu_data(cpu);
-
-	state->rmid = 0;
-	state->closid = 0;
-	state->rmid_usecnt = 0;
-
-	WARN_ON(c->x86_cache_max_rmid != cqm_max_rmid);
-	WARN_ON(c->x86_cache_occ_scale != cqm_l3_scale);
-}
-
-static void intel_cqm_cpu_exit(unsigned int cpu)
-{
-	int phys_id = topology_physical_package_id(cpu);
-	int i;
-
-	/*
-	 * Is @cpu a designated cqm reader?
-	 */
-	if (!cpumask_test_and_clear_cpu(cpu, &cqm_cpumask))
-		return;
-
-	for_each_online_cpu(i) {
-		if (i == cpu)
-			continue;
-
-		if (phys_id == topology_physical_package_id(i)) {
-			cpumask_set_cpu(i, &cqm_cpumask);
-			break;
-		}
-	}
-}
-
-static int intel_cqm_cpu_notifier(struct notifier_block *nb,
-				  unsigned long action, void *hcpu)
-{
-	unsigned int cpu  = (unsigned long)hcpu;
-
-	switch (action & ~CPU_TASKS_FROZEN) {
-	case CPU_DOWN_PREPARE:
-		intel_cqm_cpu_exit(cpu);
-		break;
-	case CPU_STARTING:
-		intel_cqm_cpu_starting(cpu);
-		cqm_pick_event_reader(cpu);
-		break;
-	}
-
-	return NOTIFY_OK;
-}
-
-static const struct x86_cpu_id intel_cqm_match[] = {
-	{ .vendor = X86_VENDOR_INTEL, .feature = X86_FEATURE_CQM_OCCUP_LLC },
-	{}
-};
-
-static int __init intel_cqm_init(void)
-{
-	char *str, scale[20];
-	int i, cpu, ret;
-
-	if (!x86_match_cpu(intel_cqm_match))
-		return -ENODEV;
-
-	cqm_l3_scale = boot_cpu_data.x86_cache_occ_scale;
-
-	/*
-	 * It's possible that not all resources support the same number
-	 * of RMIDs. Instead of making scheduling much more complicated
-	 * (where we have to match a task's RMID to a cpu that supports
-	 * that many RMIDs) just find the minimum RMIDs supported across
-	 * all cpus.
-	 *
-	 * Also, check that the scales match on all cpus.
-	 */
-	cpu_notifier_register_begin();
-
-	for_each_online_cpu(cpu) {
-		struct cpuinfo_x86 *c = &cpu_data(cpu);
-
-		if (c->x86_cache_max_rmid < cqm_max_rmid)
-			cqm_max_rmid = c->x86_cache_max_rmid;
-
-		if (c->x86_cache_occ_scale != cqm_l3_scale) {
-			pr_err("Multiple LLC scale values, disabling\n");
-			ret = -EINVAL;
-			goto out;
-		}
-	}
-
-	/*
-	 * A reasonable upper limit on the max threshold is the number
-	 * of lines tagged per RMID if all RMIDs have the same number of
-	 * lines tagged in the LLC.
-	 *
-	 * For a 35MB LLC and 56 RMIDs, this is ~1.8% of the LLC.
-	 */
-	__intel_cqm_max_threshold =
-		boot_cpu_data.x86_cache_size * 1024 / (cqm_max_rmid + 1);
-
-	snprintf(scale, sizeof(scale), "%u", cqm_l3_scale);
-	str = kstrdup(scale, GFP_KERNEL);
-	if (!str) {
-		ret = -ENOMEM;
-		goto out;
-	}
-
-	event_attr_intel_cqm_llc_scale.event_str = str;
-
-	ret = intel_cqm_setup_rmid_cache();
-	if (ret)
-		goto out;
-
-	for_each_online_cpu(i) {
-		intel_cqm_cpu_starting(i);
-		cqm_pick_event_reader(i);
-	}
-
-	__perf_cpu_notifier(intel_cqm_cpu_notifier);
-
-	ret = perf_pmu_register(&intel_cqm_pmu, "intel_cqm", -1);
-	if (ret)
-		pr_err("Intel CQM perf registration failed: %d\n", ret);
-	else
-		pr_info("Intel CQM monitoring enabled\n");
-
-out:
-	cpu_notifier_register_done();
-
-	return ret;
-}
-device_initcall(intel_cqm_init);
--- zfcpdump-kernel-4.4.orig/arch/x86/kernel/cpu/perf_event_intel_cstate.c
+++ /dev/null
@@ -1,694 +0,0 @@
-/*
- * perf_event_intel_cstate.c: support cstate residency counters
- *
- * Copyright (C) 2015, Intel Corp.
- * Author: Kan Liang (kan.liang@intel.com)
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- */
-
-/*
- * This file export cstate related free running (read-only) counters
- * for perf. These counters may be use simultaneously by other tools,
- * such as turbostat. However, it still make sense to implement them
- * in perf. Because we can conveniently collect them together with
- * other events, and allow to use them from tools without special MSR
- * access code.
- *
- * The events only support system-wide mode counting. There is no
- * sampling support because it is not supported by the hardware.
- *
- * According to counters' scope and category, two PMUs are registered
- * with the perf_event core subsystem.
- *  - 'cstate_core': The counter is available for each physical core.
- *    The counters include CORE_C*_RESIDENCY.
- *  - 'cstate_pkg': The counter is available for each physical package.
- *    The counters include PKG_C*_RESIDENCY.
- *
- * All of these counters are specified in the Intel® 64 and IA-32
- * Architectures Software Developer.s Manual Vol3b.
- *
- * Model specific counters:
- *	MSR_CORE_C1_RES: CORE C1 Residency Counter
- *			 perf code: 0x00
- *			 Available model: SLM,AMT
- *			 Scope: Core (each processor core has a MSR)
- *	MSR_CORE_C3_RESIDENCY: CORE C3 Residency Counter
- *			       perf code: 0x01
- *			       Available model: NHM,WSM,SNB,IVB,HSW,BDW,SKL
- *			       Scope: Core
- *	MSR_CORE_C6_RESIDENCY: CORE C6 Residency Counter
- *			       perf code: 0x02
- *			       Available model: SLM,AMT,NHM,WSM,SNB,IVB,HSW,BDW,SKL
- *			       Scope: Core
- *	MSR_CORE_C7_RESIDENCY: CORE C7 Residency Counter
- *			       perf code: 0x03
- *			       Available model: SNB,IVB,HSW,BDW,SKL
- *			       Scope: Core
- *	MSR_PKG_C2_RESIDENCY:  Package C2 Residency Counter.
- *			       perf code: 0x00
- *			       Available model: SNB,IVB,HSW,BDW,SKL
- *			       Scope: Package (physical package)
- *	MSR_PKG_C3_RESIDENCY:  Package C3 Residency Counter.
- *			       perf code: 0x01
- *			       Available model: NHM,WSM,SNB,IVB,HSW,BDW,SKL
- *			       Scope: Package (physical package)
- *	MSR_PKG_C6_RESIDENCY:  Package C6 Residency Counter.
- *			       perf code: 0x02
- *			       Available model: SLM,AMT,NHM,WSM,SNB,IVB,HSW,BDW,SKL
- *			       Scope: Package (physical package)
- *	MSR_PKG_C7_RESIDENCY:  Package C7 Residency Counter.
- *			       perf code: 0x03
- *			       Available model: NHM,WSM,SNB,IVB,HSW,BDW,SKL
- *			       Scope: Package (physical package)
- *	MSR_PKG_C8_RESIDENCY:  Package C8 Residency Counter.
- *			       perf code: 0x04
- *			       Available model: HSW ULT only
- *			       Scope: Package (physical package)
- *	MSR_PKG_C9_RESIDENCY:  Package C9 Residency Counter.
- *			       perf code: 0x05
- *			       Available model: HSW ULT only
- *			       Scope: Package (physical package)
- *	MSR_PKG_C10_RESIDENCY: Package C10 Residency Counter.
- *			       perf code: 0x06
- *			       Available model: HSW ULT only
- *			       Scope: Package (physical package)
- *
- */
-
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/perf_event.h>
-#include <asm/cpu_device_id.h>
-#include "perf_event.h"
-
-#define DEFINE_CSTATE_FORMAT_ATTR(_var, _name, _format)		\
-static ssize_t __cstate_##_var##_show(struct kobject *kobj,	\
-				struct kobj_attribute *attr,	\
-				char *page)			\
-{								\
-	BUILD_BUG_ON(sizeof(_format) >= PAGE_SIZE);		\
-	return sprintf(page, _format "\n");			\
-}								\
-static struct kobj_attribute format_attr_##_var =		\
-	__ATTR(_name, 0444, __cstate_##_var##_show, NULL)
-
-static ssize_t cstate_get_attr_cpumask(struct device *dev,
-				       struct device_attribute *attr,
-				       char *buf);
-
-struct perf_cstate_msr {
-	u64	msr;
-	struct	perf_pmu_events_attr *attr;
-	bool	(*test)(int idx);
-};
-
-
-/* cstate_core PMU */
-
-static struct pmu cstate_core_pmu;
-static bool has_cstate_core;
-
-enum perf_cstate_core_id {
-	/*
-	 * cstate_core events
-	 */
-	PERF_CSTATE_CORE_C1_RES = 0,
-	PERF_CSTATE_CORE_C3_RES,
-	PERF_CSTATE_CORE_C6_RES,
-	PERF_CSTATE_CORE_C7_RES,
-
-	PERF_CSTATE_CORE_EVENT_MAX,
-};
-
-bool test_core(int idx)
-{
-	if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL ||
-	    boot_cpu_data.x86 != 6)
-		return false;
-
-	switch (boot_cpu_data.x86_model) {
-	case 30: /* 45nm Nehalem    */
-	case 26: /* 45nm Nehalem-EP */
-	case 46: /* 45nm Nehalem-EX */
-
-	case 37: /* 32nm Westmere    */
-	case 44: /* 32nm Westmere-EP */
-	case 47: /* 32nm Westmere-EX */
-		if (idx == PERF_CSTATE_CORE_C3_RES ||
-		    idx == PERF_CSTATE_CORE_C6_RES)
-			return true;
-		break;
-	case 42: /* 32nm SandyBridge         */
-	case 45: /* 32nm SandyBridge-E/EN/EP */
-
-	case 58: /* 22nm IvyBridge       */
-	case 62: /* 22nm IvyBridge-EP/EX */
-
-	case 60: /* 22nm Haswell Core */
-	case 63: /* 22nm Haswell Server */
-	case 69: /* 22nm Haswell ULT */
-	case 70: /* 22nm Haswell + GT3e (Intel Iris Pro graphics) */
-
-	case 61: /* 14nm Broadwell Core-M */
-	case 86: /* 14nm Broadwell Xeon D */
-	case 71: /* 14nm Broadwell + GT3e (Intel Iris Pro graphics) */
-	case 79: /* 14nm Broadwell Server */
-
-	case 78: /* 14nm Skylake Mobile */
-	case 94: /* 14nm Skylake Desktop */
-		if (idx == PERF_CSTATE_CORE_C3_RES ||
-		    idx == PERF_CSTATE_CORE_C6_RES ||
-		    idx == PERF_CSTATE_CORE_C7_RES)
-			return true;
-		break;
-	case 55: /* 22nm Atom "Silvermont"                */
-	case 77: /* 22nm Atom "Silvermont Avoton/Rangely" */
-	case 76: /* 14nm Atom "Airmont"                   */
-		if (idx == PERF_CSTATE_CORE_C1_RES ||
-		    idx == PERF_CSTATE_CORE_C6_RES)
-			return true;
-		break;
-	}
-
-	return false;
-}
-
-PMU_EVENT_ATTR_STRING(c1-residency, evattr_cstate_core_c1, "event=0x00");
-PMU_EVENT_ATTR_STRING(c3-residency, evattr_cstate_core_c3, "event=0x01");
-PMU_EVENT_ATTR_STRING(c6-residency, evattr_cstate_core_c6, "event=0x02");
-PMU_EVENT_ATTR_STRING(c7-residency, evattr_cstate_core_c7, "event=0x03");
-
-static struct perf_cstate_msr core_msr[] = {
-	[PERF_CSTATE_CORE_C1_RES] = { MSR_CORE_C1_RES,		&evattr_cstate_core_c1,	test_core, },
-	[PERF_CSTATE_CORE_C3_RES] = { MSR_CORE_C3_RESIDENCY,	&evattr_cstate_core_c3, test_core, },
-	[PERF_CSTATE_CORE_C6_RES] = { MSR_CORE_C6_RESIDENCY,	&evattr_cstate_core_c6, test_core, },
-	[PERF_CSTATE_CORE_C7_RES] = { MSR_CORE_C7_RESIDENCY,	&evattr_cstate_core_c7,	test_core, },
-};
-
-static struct attribute *core_events_attrs[PERF_CSTATE_CORE_EVENT_MAX + 1] = {
-	NULL,
-};
-
-static struct attribute_group core_events_attr_group = {
-	.name = "events",
-	.attrs = core_events_attrs,
-};
-
-DEFINE_CSTATE_FORMAT_ATTR(core_event, event, "config:0-63");
-static struct attribute *core_format_attrs[] = {
-	&format_attr_core_event.attr,
-	NULL,
-};
-
-static struct attribute_group core_format_attr_group = {
-	.name = "format",
-	.attrs = core_format_attrs,
-};
-
-static cpumask_t cstate_core_cpu_mask;
-static DEVICE_ATTR(cpumask, S_IRUGO, cstate_get_attr_cpumask, NULL);
-
-static struct attribute *cstate_cpumask_attrs[] = {
-	&dev_attr_cpumask.attr,
-	NULL,
-};
-
-static struct attribute_group cpumask_attr_group = {
-	.attrs = cstate_cpumask_attrs,
-};
-
-static const struct attribute_group *core_attr_groups[] = {
-	&core_events_attr_group,
-	&core_format_attr_group,
-	&cpumask_attr_group,
-	NULL,
-};
-
-/* cstate_core PMU end */
-
-
-/* cstate_pkg PMU */
-
-static struct pmu cstate_pkg_pmu;
-static bool has_cstate_pkg;
-
-enum perf_cstate_pkg_id {
-	/*
-	 * cstate_pkg events
-	 */
-	PERF_CSTATE_PKG_C2_RES = 0,
-	PERF_CSTATE_PKG_C3_RES,
-	PERF_CSTATE_PKG_C6_RES,
-	PERF_CSTATE_PKG_C7_RES,
-	PERF_CSTATE_PKG_C8_RES,
-	PERF_CSTATE_PKG_C9_RES,
-	PERF_CSTATE_PKG_C10_RES,
-
-	PERF_CSTATE_PKG_EVENT_MAX,
-};
-
-bool test_pkg(int idx)
-{
-	if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL ||
-	    boot_cpu_data.x86 != 6)
-		return false;
-
-	switch (boot_cpu_data.x86_model) {
-	case 30: /* 45nm Nehalem    */
-	case 26: /* 45nm Nehalem-EP */
-	case 46: /* 45nm Nehalem-EX */
-
-	case 37: /* 32nm Westmere    */
-	case 44: /* 32nm Westmere-EP */
-	case 47: /* 32nm Westmere-EX */
-		if (idx == PERF_CSTATE_CORE_C3_RES ||
-		    idx == PERF_CSTATE_CORE_C6_RES ||
-		    idx == PERF_CSTATE_CORE_C7_RES)
-			return true;
-		break;
-	case 42: /* 32nm SandyBridge         */
-	case 45: /* 32nm SandyBridge-E/EN/EP */
-
-	case 58: /* 22nm IvyBridge       */
-	case 62: /* 22nm IvyBridge-EP/EX */
-
-	case 60: /* 22nm Haswell Core */
-	case 63: /* 22nm Haswell Server */
-	case 70: /* 22nm Haswell + GT3e (Intel Iris Pro graphics) */
-
-	case 61: /* 14nm Broadwell Core-M */
-	case 86: /* 14nm Broadwell Xeon D */
-	case 71: /* 14nm Broadwell + GT3e (Intel Iris Pro graphics) */
-	case 79: /* 14nm Broadwell Server */
-
-	case 78: /* 14nm Skylake Mobile */
-	case 94: /* 14nm Skylake Desktop */
-		if (idx == PERF_CSTATE_PKG_C2_RES ||
-		    idx == PERF_CSTATE_PKG_C3_RES ||
-		    idx == PERF_CSTATE_PKG_C6_RES ||
-		    idx == PERF_CSTATE_PKG_C7_RES)
-			return true;
-		break;
-	case 55: /* 22nm Atom "Silvermont"                */
-	case 77: /* 22nm Atom "Silvermont Avoton/Rangely" */
-	case 76: /* 14nm Atom "Airmont"                   */
-		if (idx == PERF_CSTATE_CORE_C6_RES)
-			return true;
-		break;
-	case 69: /* 22nm Haswell ULT */
-		if (idx == PERF_CSTATE_PKG_C2_RES ||
-		    idx == PERF_CSTATE_PKG_C3_RES ||
-		    idx == PERF_CSTATE_PKG_C6_RES ||
-		    idx == PERF_CSTATE_PKG_C7_RES ||
-		    idx == PERF_CSTATE_PKG_C8_RES ||
-		    idx == PERF_CSTATE_PKG_C9_RES ||
-		    idx == PERF_CSTATE_PKG_C10_RES)
-			return true;
-		break;
-	}
-
-	return false;
-}
-
-PMU_EVENT_ATTR_STRING(c2-residency, evattr_cstate_pkg_c2, "event=0x00");
-PMU_EVENT_ATTR_STRING(c3-residency, evattr_cstate_pkg_c3, "event=0x01");
-PMU_EVENT_ATTR_STRING(c6-residency, evattr_cstate_pkg_c6, "event=0x02");
-PMU_EVENT_ATTR_STRING(c7-residency, evattr_cstate_pkg_c7, "event=0x03");
-PMU_EVENT_ATTR_STRING(c8-residency, evattr_cstate_pkg_c8, "event=0x04");
-PMU_EVENT_ATTR_STRING(c9-residency, evattr_cstate_pkg_c9, "event=0x05");
-PMU_EVENT_ATTR_STRING(c10-residency, evattr_cstate_pkg_c10, "event=0x06");
-
-static struct perf_cstate_msr pkg_msr[] = {
-	[PERF_CSTATE_PKG_C2_RES] = { MSR_PKG_C2_RESIDENCY,	&evattr_cstate_pkg_c2,	test_pkg, },
-	[PERF_CSTATE_PKG_C3_RES] = { MSR_PKG_C3_RESIDENCY,	&evattr_cstate_pkg_c3,	test_pkg, },
-	[PERF_CSTATE_PKG_C6_RES] = { MSR_PKG_C6_RESIDENCY,	&evattr_cstate_pkg_c6,	test_pkg, },
-	[PERF_CSTATE_PKG_C7_RES] = { MSR_PKG_C7_RESIDENCY,	&evattr_cstate_pkg_c7,	test_pkg, },
-	[PERF_CSTATE_PKG_C8_RES] = { MSR_PKG_C8_RESIDENCY,	&evattr_cstate_pkg_c8,	test_pkg, },
-	[PERF_CSTATE_PKG_C9_RES] = { MSR_PKG_C9_RESIDENCY,	&evattr_cstate_pkg_c9,	test_pkg, },
-	[PERF_CSTATE_PKG_C10_RES] = { MSR_PKG_C10_RESIDENCY,	&evattr_cstate_pkg_c10,	test_pkg, },
-};
-
-static struct attribute *pkg_events_attrs[PERF_CSTATE_PKG_EVENT_MAX + 1] = {
-	NULL,
-};
-
-static struct attribute_group pkg_events_attr_group = {
-	.name = "events",
-	.attrs = pkg_events_attrs,
-};
-
-DEFINE_CSTATE_FORMAT_ATTR(pkg_event, event, "config:0-63");
-static struct attribute *pkg_format_attrs[] = {
-	&format_attr_pkg_event.attr,
-	NULL,
-};
-static struct attribute_group pkg_format_attr_group = {
-	.name = "format",
-	.attrs = pkg_format_attrs,
-};
-
-static cpumask_t cstate_pkg_cpu_mask;
-
-static const struct attribute_group *pkg_attr_groups[] = {
-	&pkg_events_attr_group,
-	&pkg_format_attr_group,
-	&cpumask_attr_group,
-	NULL,
-};
-
-/* cstate_pkg PMU end*/
-
-static ssize_t cstate_get_attr_cpumask(struct device *dev,
-				       struct device_attribute *attr,
-				       char *buf)
-{
-	struct pmu *pmu = dev_get_drvdata(dev);
-
-	if (pmu == &cstate_core_pmu)
-		return cpumap_print_to_pagebuf(true, buf, &cstate_core_cpu_mask);
-	else if (pmu == &cstate_pkg_pmu)
-		return cpumap_print_to_pagebuf(true, buf, &cstate_pkg_cpu_mask);
-	else
-		return 0;
-}
-
-static int cstate_pmu_event_init(struct perf_event *event)
-{
-	u64 cfg = event->attr.config;
-	int ret = 0;
-
-	if (event->attr.type != event->pmu->type)
-		return -ENOENT;
-
-	/* unsupported modes and filters */
-	if (event->attr.exclude_user   ||
-	    event->attr.exclude_kernel ||
-	    event->attr.exclude_hv     ||
-	    event->attr.exclude_idle   ||
-	    event->attr.exclude_host   ||
-	    event->attr.exclude_guest  ||
-	    event->attr.sample_period) /* no sampling */
-		return -EINVAL;
-
-	if (event->pmu == &cstate_core_pmu) {
-		if (cfg >= PERF_CSTATE_CORE_EVENT_MAX)
-			return -EINVAL;
-		if (!core_msr[cfg].attr)
-			return -EINVAL;
-		event->hw.event_base = core_msr[cfg].msr;
-	} else if (event->pmu == &cstate_pkg_pmu) {
-		if (cfg >= PERF_CSTATE_PKG_EVENT_MAX)
-			return -EINVAL;
-		if (!pkg_msr[cfg].attr)
-			return -EINVAL;
-		event->hw.event_base = pkg_msr[cfg].msr;
-	} else
-		return -ENOENT;
-
-	/* must be done before validate_group */
-	event->hw.config = cfg;
-	event->hw.idx = -1;
-
-	return ret;
-}
-
-static inline u64 cstate_pmu_read_counter(struct perf_event *event)
-{
-	u64 val;
-
-	rdmsrl(event->hw.event_base, val);
-	return val;
-}
-
-static void cstate_pmu_event_update(struct perf_event *event)
-{
-	struct hw_perf_event *hwc = &event->hw;
-	u64 prev_raw_count, new_raw_count;
-
-again:
-	prev_raw_count = local64_read(&hwc->prev_count);
-	new_raw_count = cstate_pmu_read_counter(event);
-
-	if (local64_cmpxchg(&hwc->prev_count, prev_raw_count,
-			    new_raw_count) != prev_raw_count)
-		goto again;
-
-	local64_add(new_raw_count - prev_raw_count, &event->count);
-}
-
-static void cstate_pmu_event_start(struct perf_event *event, int mode)
-{
-	local64_set(&event->hw.prev_count, cstate_pmu_read_counter(event));
-}
-
-static void cstate_pmu_event_stop(struct perf_event *event, int mode)
-{
-	cstate_pmu_event_update(event);
-}
-
-static void cstate_pmu_event_del(struct perf_event *event, int mode)
-{
-	cstate_pmu_event_stop(event, PERF_EF_UPDATE);
-}
-
-static int cstate_pmu_event_add(struct perf_event *event, int mode)
-{
-	if (mode & PERF_EF_START)
-		cstate_pmu_event_start(event, mode);
-
-	return 0;
-}
-
-static void cstate_cpu_exit(int cpu)
-{
-	int i, id, target;
-
-	/* cpu exit for cstate core */
-	if (has_cstate_core) {
-		id = topology_core_id(cpu);
-		target = -1;
-
-		for_each_online_cpu(i) {
-			if (i == cpu)
-				continue;
-			if (id == topology_core_id(i)) {
-				target = i;
-				break;
-			}
-		}
-		if (cpumask_test_and_clear_cpu(cpu, &cstate_core_cpu_mask) && target >= 0)
-			cpumask_set_cpu(target, &cstate_core_cpu_mask);
-		WARN_ON(cpumask_empty(&cstate_core_cpu_mask));
-		if (target >= 0)
-			perf_pmu_migrate_context(&cstate_core_pmu, cpu, target);
-	}
-
-	/* cpu exit for cstate pkg */
-	if (has_cstate_pkg) {
-		id = topology_physical_package_id(cpu);
-		target = -1;
-
-		for_each_online_cpu(i) {
-			if (i == cpu)
-				continue;
-			if (id == topology_physical_package_id(i)) {
-				target = i;
-				break;
-			}
-		}
-		if (cpumask_test_and_clear_cpu(cpu, &cstate_pkg_cpu_mask) && target >= 0)
-			cpumask_set_cpu(target, &cstate_pkg_cpu_mask);
-		WARN_ON(cpumask_empty(&cstate_pkg_cpu_mask));
-		if (target >= 0)
-			perf_pmu_migrate_context(&cstate_pkg_pmu, cpu, target);
-	}
-}
-
-static void cstate_cpu_init(int cpu)
-{
-	int i, id;
-
-	/* cpu init for cstate core */
-	if (has_cstate_core) {
-		id = topology_core_id(cpu);
-		for_each_cpu(i, &cstate_core_cpu_mask) {
-			if (id == topology_core_id(i))
-				break;
-		}
-		if (i >= nr_cpu_ids)
-			cpumask_set_cpu(cpu, &cstate_core_cpu_mask);
-	}
-
-	/* cpu init for cstate pkg */
-	if (has_cstate_pkg) {
-		id = topology_physical_package_id(cpu);
-		for_each_cpu(i, &cstate_pkg_cpu_mask) {
-			if (id == topology_physical_package_id(i))
-				break;
-		}
-		if (i >= nr_cpu_ids)
-			cpumask_set_cpu(cpu, &cstate_pkg_cpu_mask);
-	}
-}
-
-static int cstate_cpu_notifier(struct notifier_block *self,
-				  unsigned long action, void *hcpu)
-{
-	unsigned int cpu = (long)hcpu;
-
-	switch (action & ~CPU_TASKS_FROZEN) {
-	case CPU_UP_PREPARE:
-		break;
-	case CPU_STARTING:
-		cstate_cpu_init(cpu);
-		break;
-	case CPU_UP_CANCELED:
-	case CPU_DYING:
-		break;
-	case CPU_ONLINE:
-	case CPU_DEAD:
-		break;
-	case CPU_DOWN_PREPARE:
-		cstate_cpu_exit(cpu);
-		break;
-	default:
-		break;
-	}
-
-	return NOTIFY_OK;
-}
-
-/*
- * Probe the cstate events and insert the available one into sysfs attrs
- * Return false if there is no available events.
- */
-static bool cstate_probe_msr(struct perf_cstate_msr *msr,
-			     struct attribute	**events_attrs,
-			     int max_event_nr)
-{
-	int i, j = 0;
-	u64 val;
-
-	/* Probe the cstate events. */
-	for (i = 0; i < max_event_nr; i++) {
-		if (!msr[i].test(i) || rdmsrl_safe(msr[i].msr, &val))
-			msr[i].attr = NULL;
-	}
-
-	/* List remaining events in the sysfs attrs. */
-	for (i = 0; i < max_event_nr; i++) {
-		if (msr[i].attr)
-			events_attrs[j++] = &msr[i].attr->attr.attr;
-	}
-	events_attrs[j] = NULL;
-
-	return (j > 0) ? true : false;
-}
-
-static int __init cstate_init(void)
-{
-	/* SLM has different MSR for PKG C6 */
-	switch (boot_cpu_data.x86_model) {
-	case 55:
-	case 76:
-	case 77:
-		pkg_msr[PERF_CSTATE_PKG_C6_RES].msr = MSR_PKG_C7_RESIDENCY;
-	}
-
-	if (cstate_probe_msr(core_msr, core_events_attrs, PERF_CSTATE_CORE_EVENT_MAX))
-		has_cstate_core = true;
-
-	if (cstate_probe_msr(pkg_msr, pkg_events_attrs, PERF_CSTATE_PKG_EVENT_MAX))
-		has_cstate_pkg = true;
-
-	return (has_cstate_core || has_cstate_pkg) ? 0 : -ENODEV;
-}
-
-static void __init cstate_cpumask_init(void)
-{
-	int cpu;
-
-	cpu_notifier_register_begin();
-
-	for_each_online_cpu(cpu)
-		cstate_cpu_init(cpu);
-
-	__perf_cpu_notifier(cstate_cpu_notifier);
-
-	cpu_notifier_register_done();
-}
-
-static struct pmu cstate_core_pmu = {
-	.attr_groups	= core_attr_groups,
-	.name		= "cstate_core",
-	.task_ctx_nr	= perf_invalid_context,
-	.event_init	= cstate_pmu_event_init,
-	.add		= cstate_pmu_event_add, /* must have */
-	.del		= cstate_pmu_event_del, /* must have */
-	.start		= cstate_pmu_event_start,
-	.stop		= cstate_pmu_event_stop,
-	.read		= cstate_pmu_event_update,
-	.capabilities	= PERF_PMU_CAP_NO_INTERRUPT,
-};
-
-static struct pmu cstate_pkg_pmu = {
-	.attr_groups	= pkg_attr_groups,
-	.name		= "cstate_pkg",
-	.task_ctx_nr	= perf_invalid_context,
-	.event_init	= cstate_pmu_event_init,
-	.add		= cstate_pmu_event_add, /* must have */
-	.del		= cstate_pmu_event_del, /* must have */
-	.start		= cstate_pmu_event_start,
-	.stop		= cstate_pmu_event_stop,
-	.read		= cstate_pmu_event_update,
-	.capabilities	= PERF_PMU_CAP_NO_INTERRUPT,
-};
-
-static void __init cstate_pmus_register(void)
-{
-	int err;
-
-	if (has_cstate_core) {
-		err = perf_pmu_register(&cstate_core_pmu, cstate_core_pmu.name, -1);
-		if (WARN_ON(err))
-			pr_info("Failed to register PMU %s error %d\n",
-				cstate_core_pmu.name, err);
-	}
-
-	if (has_cstate_pkg) {
-		err = perf_pmu_register(&cstate_pkg_pmu, cstate_pkg_pmu.name, -1);
-		if (WARN_ON(err))
-			pr_info("Failed to register PMU %s error %d\n",
-				cstate_pkg_pmu.name, err);
-	}
-}
-
-static int __init cstate_pmu_init(void)
-{
-	int err;
-
-	if (cpu_has_hypervisor)
-		return -ENODEV;
-
-	err = cstate_init();
-	if (err)
-		return err;
-
-	cstate_cpumask_init();
-
-	cstate_pmus_register();
-
-	return 0;
-}
-
-device_initcall(cstate_pmu_init);
--- zfcpdump-kernel-4.4.orig/arch/x86/kernel/cpu/perf_event_intel_ds.c
+++ /dev/null
@@ -1,1345 +0,0 @@
-#include <linux/bitops.h>
-#include <linux/types.h>
-#include <linux/slab.h>
-
-#include <asm/perf_event.h>
-#include <asm/insn.h>
-
-#include "perf_event.h"
-
-/* The size of a BTS record in bytes: */
-#define BTS_RECORD_SIZE		24
-
-#define BTS_BUFFER_SIZE		(PAGE_SIZE << 4)
-#define PEBS_BUFFER_SIZE	(PAGE_SIZE << 4)
-#define PEBS_FIXUP_SIZE		PAGE_SIZE
-
-/*
- * pebs_record_32 for p4 and core not supported
-
-struct pebs_record_32 {
-	u32 flags, ip;
-	u32 ax, bc, cx, dx;
-	u32 si, di, bp, sp;
-};
-
- */
-
-union intel_x86_pebs_dse {
-	u64 val;
-	struct {
-		unsigned int ld_dse:4;
-		unsigned int ld_stlb_miss:1;
-		unsigned int ld_locked:1;
-		unsigned int ld_reserved:26;
-	};
-	struct {
-		unsigned int st_l1d_hit:1;
-		unsigned int st_reserved1:3;
-		unsigned int st_stlb_miss:1;
-		unsigned int st_locked:1;
-		unsigned int st_reserved2:26;
-	};
-};
-
-
-/*
- * Map PEBS Load Latency Data Source encodings to generic
- * memory data source information
- */
-#define P(a, b) PERF_MEM_S(a, b)
-#define OP_LH (P(OP, LOAD) | P(LVL, HIT))
-#define SNOOP_NONE_MISS (P(SNOOP, NONE) | P(SNOOP, MISS))
-
-static const u64 pebs_data_source[] = {
-	P(OP, LOAD) | P(LVL, MISS) | P(LVL, L3) | P(SNOOP, NA),/* 0x00:ukn L3 */
-	OP_LH | P(LVL, L1)  | P(SNOOP, NONE),	/* 0x01: L1 local */
-	OP_LH | P(LVL, LFB) | P(SNOOP, NONE),	/* 0x02: LFB hit */
-	OP_LH | P(LVL, L2)  | P(SNOOP, NONE),	/* 0x03: L2 hit */
-	OP_LH | P(LVL, L3)  | P(SNOOP, NONE),	/* 0x04: L3 hit */
-	OP_LH | P(LVL, L3)  | P(SNOOP, MISS),	/* 0x05: L3 hit, snoop miss */
-	OP_LH | P(LVL, L3)  | P(SNOOP, HIT),	/* 0x06: L3 hit, snoop hit */
-	OP_LH | P(LVL, L3)  | P(SNOOP, HITM),	/* 0x07: L3 hit, snoop hitm */
-	OP_LH | P(LVL, REM_CCE1) | P(SNOOP, HIT),  /* 0x08: L3 miss snoop hit */
-	OP_LH | P(LVL, REM_CCE1) | P(SNOOP, HITM), /* 0x09: L3 miss snoop hitm*/
-	OP_LH | P(LVL, LOC_RAM)  | P(SNOOP, HIT),  /* 0x0a: L3 miss, shared */
-	OP_LH | P(LVL, REM_RAM1) | P(SNOOP, HIT),  /* 0x0b: L3 miss, shared */
-	OP_LH | P(LVL, LOC_RAM)  | SNOOP_NONE_MISS,/* 0x0c: L3 miss, excl */
-	OP_LH | P(LVL, REM_RAM1) | SNOOP_NONE_MISS,/* 0x0d: L3 miss, excl */
-	OP_LH | P(LVL, IO)  | P(SNOOP, NONE), /* 0x0e: I/O */
-	OP_LH | P(LVL, UNC) | P(SNOOP, NONE), /* 0x0f: uncached */
-};
-
-static u64 precise_store_data(u64 status)
-{
-	union intel_x86_pebs_dse dse;
-	u64 val = P(OP, STORE) | P(SNOOP, NA) | P(LVL, L1) | P(TLB, L2);
-
-	dse.val = status;
-
-	/*
-	 * bit 4: TLB access
-	 * 1 = stored missed 2nd level TLB
-	 *
-	 * so it either hit the walker or the OS
-	 * otherwise hit 2nd level TLB
-	 */
-	if (dse.st_stlb_miss)
-		val |= P(TLB, MISS);
-	else
-		val |= P(TLB, HIT);
-
-	/*
-	 * bit 0: hit L1 data cache
-	 * if not set, then all we know is that
-	 * it missed L1D
-	 */
-	if (dse.st_l1d_hit)
-		val |= P(LVL, HIT);
-	else
-		val |= P(LVL, MISS);
-
-	/*
-	 * bit 5: Locked prefix
-	 */
-	if (dse.st_locked)
-		val |= P(LOCK, LOCKED);
-
-	return val;
-}
-
-static u64 precise_datala_hsw(struct perf_event *event, u64 status)
-{
-	union perf_mem_data_src dse;
-
-	dse.val = PERF_MEM_NA;
-
-	if (event->hw.flags & PERF_X86_EVENT_PEBS_ST_HSW)
-		dse.mem_op = PERF_MEM_OP_STORE;
-	else if (event->hw.flags & PERF_X86_EVENT_PEBS_LD_HSW)
-		dse.mem_op = PERF_MEM_OP_LOAD;
-
-	/*
-	 * L1 info only valid for following events:
-	 *
-	 * MEM_UOPS_RETIRED.STLB_MISS_STORES
-	 * MEM_UOPS_RETIRED.LOCK_STORES
-	 * MEM_UOPS_RETIRED.SPLIT_STORES
-	 * MEM_UOPS_RETIRED.ALL_STORES
-	 */
-	if (event->hw.flags & PERF_X86_EVENT_PEBS_ST_HSW) {
-		if (status & 1)
-			dse.mem_lvl = PERF_MEM_LVL_L1 | PERF_MEM_LVL_HIT;
-		else
-			dse.mem_lvl = PERF_MEM_LVL_L1 | PERF_MEM_LVL_MISS;
-	}
-	return dse.val;
-}
-
-static u64 load_latency_data(u64 status)
-{
-	union intel_x86_pebs_dse dse;
-	u64 val;
-	int model = boot_cpu_data.x86_model;
-	int fam = boot_cpu_data.x86;
-
-	dse.val = status;
-
-	/*
-	 * use the mapping table for bit 0-3
-	 */
-	val = pebs_data_source[dse.ld_dse];
-
-	/*
-	 * Nehalem models do not support TLB, Lock infos
-	 */
-	if (fam == 0x6 && (model == 26 || model == 30
-	    || model == 31 || model == 46)) {
-		val |= P(TLB, NA) | P(LOCK, NA);
-		return val;
-	}
-	/*
-	 * bit 4: TLB access
-	 * 0 = did not miss 2nd level TLB
-	 * 1 = missed 2nd level TLB
-	 */
-	if (dse.ld_stlb_miss)
-		val |= P(TLB, MISS) | P(TLB, L2);
-	else
-		val |= P(TLB, HIT) | P(TLB, L1) | P(TLB, L2);
-
-	/*
-	 * bit 5: locked prefix
-	 */
-	if (dse.ld_locked)
-		val |= P(LOCK, LOCKED);
-
-	return val;
-}
-
-struct pebs_record_core {
-	u64 flags, ip;
-	u64 ax, bx, cx, dx;
-	u64 si, di, bp, sp;
-	u64 r8,  r9,  r10, r11;
-	u64 r12, r13, r14, r15;
-};
-
-struct pebs_record_nhm {
-	u64 flags, ip;
-	u64 ax, bx, cx, dx;
-	u64 si, di, bp, sp;
-	u64 r8,  r9,  r10, r11;
-	u64 r12, r13, r14, r15;
-	u64 status, dla, dse, lat;
-};
-
-/*
- * Same as pebs_record_nhm, with two additional fields.
- */
-struct pebs_record_hsw {
-	u64 flags, ip;
-	u64 ax, bx, cx, dx;
-	u64 si, di, bp, sp;
-	u64 r8,  r9,  r10, r11;
-	u64 r12, r13, r14, r15;
-	u64 status, dla, dse, lat;
-	u64 real_ip, tsx_tuning;
-};
-
-union hsw_tsx_tuning {
-	struct {
-		u32 cycles_last_block     : 32,
-		    hle_abort		  : 1,
-		    rtm_abort		  : 1,
-		    instruction_abort     : 1,
-		    non_instruction_abort : 1,
-		    retry		  : 1,
-		    data_conflict	  : 1,
-		    capacity_writes	  : 1,
-		    capacity_reads	  : 1;
-	};
-	u64	    value;
-};
-
-#define PEBS_HSW_TSX_FLAGS	0xff00000000ULL
-
-/* Same as HSW, plus TSC */
-
-struct pebs_record_skl {
-	u64 flags, ip;
-	u64 ax, bx, cx, dx;
-	u64 si, di, bp, sp;
-	u64 r8,  r9,  r10, r11;
-	u64 r12, r13, r14, r15;
-	u64 status, dla, dse, lat;
-	u64 real_ip, tsx_tuning;
-	u64 tsc;
-};
-
-void init_debug_store_on_cpu(int cpu)
-{
-	struct debug_store *ds = per_cpu(cpu_hw_events, cpu).ds;
-
-	if (!ds)
-		return;
-
-	wrmsr_on_cpu(cpu, MSR_IA32_DS_AREA,
-		     (u32)((u64)(unsigned long)ds),
-		     (u32)((u64)(unsigned long)ds >> 32));
-}
-
-void fini_debug_store_on_cpu(int cpu)
-{
-	if (!per_cpu(cpu_hw_events, cpu).ds)
-		return;
-
-	wrmsr_on_cpu(cpu, MSR_IA32_DS_AREA, 0, 0);
-}
-
-static DEFINE_PER_CPU(void *, insn_buffer);
-
-static int alloc_pebs_buffer(int cpu)
-{
-	struct debug_store *ds = per_cpu(cpu_hw_events, cpu).ds;
-	int node = cpu_to_node(cpu);
-	int max;
-	void *buffer, *ibuffer;
-
-	if (!x86_pmu.pebs)
-		return 0;
-
-	buffer = kzalloc_node(PEBS_BUFFER_SIZE, GFP_KERNEL, node);
-	if (unlikely(!buffer))
-		return -ENOMEM;
-
-	/*
-	 * HSW+ already provides us the eventing ip; no need to allocate this
-	 * buffer then.
-	 */
-	if (x86_pmu.intel_cap.pebs_format < 2) {
-		ibuffer = kzalloc_node(PEBS_FIXUP_SIZE, GFP_KERNEL, node);
-		if (!ibuffer) {
-			kfree(buffer);
-			return -ENOMEM;
-		}
-		per_cpu(insn_buffer, cpu) = ibuffer;
-	}
-
-	max = PEBS_BUFFER_SIZE / x86_pmu.pebs_record_size;
-
-	ds->pebs_buffer_base = (u64)(unsigned long)buffer;
-	ds->pebs_index = ds->pebs_buffer_base;
-	ds->pebs_absolute_maximum = ds->pebs_buffer_base +
-		max * x86_pmu.pebs_record_size;
-
-	return 0;
-}
-
-static void release_pebs_buffer(int cpu)
-{
-	struct debug_store *ds = per_cpu(cpu_hw_events, cpu).ds;
-
-	if (!ds || !x86_pmu.pebs)
-		return;
-
-	kfree(per_cpu(insn_buffer, cpu));
-	per_cpu(insn_buffer, cpu) = NULL;
-
-	kfree((void *)(unsigned long)ds->pebs_buffer_base);
-	ds->pebs_buffer_base = 0;
-}
-
-static int alloc_bts_buffer(int cpu)
-{
-	struct debug_store *ds = per_cpu(cpu_hw_events, cpu).ds;
-	int node = cpu_to_node(cpu);
-	int max, thresh;
-	void *buffer;
-
-	if (!x86_pmu.bts)
-		return 0;
-
-	buffer = kzalloc_node(BTS_BUFFER_SIZE, GFP_KERNEL | __GFP_NOWARN, node);
-	if (unlikely(!buffer)) {
-		WARN_ONCE(1, "%s: BTS buffer allocation failure\n", __func__);
-		return -ENOMEM;
-	}
-
-	max = BTS_BUFFER_SIZE / BTS_RECORD_SIZE;
-	thresh = max / 16;
-
-	ds->bts_buffer_base = (u64)(unsigned long)buffer;
-	ds->bts_index = ds->bts_buffer_base;
-	ds->bts_absolute_maximum = ds->bts_buffer_base +
-		max * BTS_RECORD_SIZE;
-	ds->bts_interrupt_threshold = ds->bts_absolute_maximum -
-		thresh * BTS_RECORD_SIZE;
-
-	return 0;
-}
-
-static void release_bts_buffer(int cpu)
-{
-	struct debug_store *ds = per_cpu(cpu_hw_events, cpu).ds;
-
-	if (!ds || !x86_pmu.bts)
-		return;
-
-	kfree((void *)(unsigned long)ds->bts_buffer_base);
-	ds->bts_buffer_base = 0;
-}
-
-static int alloc_ds_buffer(int cpu)
-{
-	int node = cpu_to_node(cpu);
-	struct debug_store *ds;
-
-	ds = kzalloc_node(sizeof(*ds), GFP_KERNEL, node);
-	if (unlikely(!ds))
-		return -ENOMEM;
-
-	per_cpu(cpu_hw_events, cpu).ds = ds;
-
-	return 0;
-}
-
-static void release_ds_buffer(int cpu)
-{
-	struct debug_store *ds = per_cpu(cpu_hw_events, cpu).ds;
-
-	if (!ds)
-		return;
-
-	per_cpu(cpu_hw_events, cpu).ds = NULL;
-	kfree(ds);
-}
-
-void release_ds_buffers(void)
-{
-	int cpu;
-
-	if (!x86_pmu.bts && !x86_pmu.pebs)
-		return;
-
-	get_online_cpus();
-	for_each_online_cpu(cpu)
-		fini_debug_store_on_cpu(cpu);
-
-	for_each_possible_cpu(cpu) {
-		release_pebs_buffer(cpu);
-		release_bts_buffer(cpu);
-		release_ds_buffer(cpu);
-	}
-	put_online_cpus();
-}
-
-void reserve_ds_buffers(void)
-{
-	int bts_err = 0, pebs_err = 0;
-	int cpu;
-
-	x86_pmu.bts_active = 0;
-	x86_pmu.pebs_active = 0;
-
-	if (!x86_pmu.bts && !x86_pmu.pebs)
-		return;
-
-	if (!x86_pmu.bts)
-		bts_err = 1;
-
-	if (!x86_pmu.pebs)
-		pebs_err = 1;
-
-	get_online_cpus();
-
-	for_each_possible_cpu(cpu) {
-		if (alloc_ds_buffer(cpu)) {
-			bts_err = 1;
-			pebs_err = 1;
-		}
-
-		if (!bts_err && alloc_bts_buffer(cpu))
-			bts_err = 1;
-
-		if (!pebs_err && alloc_pebs_buffer(cpu))
-			pebs_err = 1;
-
-		if (bts_err && pebs_err)
-			break;
-	}
-
-	if (bts_err) {
-		for_each_possible_cpu(cpu)
-			release_bts_buffer(cpu);
-	}
-
-	if (pebs_err) {
-		for_each_possible_cpu(cpu)
-			release_pebs_buffer(cpu);
-	}
-
-	if (bts_err && pebs_err) {
-		for_each_possible_cpu(cpu)
-			release_ds_buffer(cpu);
-	} else {
-		if (x86_pmu.bts && !bts_err)
-			x86_pmu.bts_active = 1;
-
-		if (x86_pmu.pebs && !pebs_err)
-			x86_pmu.pebs_active = 1;
-
-		for_each_online_cpu(cpu)
-			init_debug_store_on_cpu(cpu);
-	}
-
-	put_online_cpus();
-}
-
-/*
- * BTS
- */
-
-struct event_constraint bts_constraint =
-	EVENT_CONSTRAINT(0, 1ULL << INTEL_PMC_IDX_FIXED_BTS, 0);
-
-void intel_pmu_enable_bts(u64 config)
-{
-	unsigned long debugctlmsr;
-
-	debugctlmsr = get_debugctlmsr();
-
-	debugctlmsr |= DEBUGCTLMSR_TR;
-	debugctlmsr |= DEBUGCTLMSR_BTS;
-	if (config & ARCH_PERFMON_EVENTSEL_INT)
-		debugctlmsr |= DEBUGCTLMSR_BTINT;
-
-	if (!(config & ARCH_PERFMON_EVENTSEL_OS))
-		debugctlmsr |= DEBUGCTLMSR_BTS_OFF_OS;
-
-	if (!(config & ARCH_PERFMON_EVENTSEL_USR))
-		debugctlmsr |= DEBUGCTLMSR_BTS_OFF_USR;
-
-	update_debugctlmsr(debugctlmsr);
-}
-
-void intel_pmu_disable_bts(void)
-{
-	struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
-	unsigned long debugctlmsr;
-
-	if (!cpuc->ds)
-		return;
-
-	debugctlmsr = get_debugctlmsr();
-
-	debugctlmsr &=
-		~(DEBUGCTLMSR_TR | DEBUGCTLMSR_BTS | DEBUGCTLMSR_BTINT |
-		  DEBUGCTLMSR_BTS_OFF_OS | DEBUGCTLMSR_BTS_OFF_USR);
-
-	update_debugctlmsr(debugctlmsr);
-}
-
-int intel_pmu_drain_bts_buffer(void)
-{
-	struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
-	struct debug_store *ds = cpuc->ds;
-	struct bts_record {
-		u64	from;
-		u64	to;
-		u64	flags;
-	};
-	struct perf_event *event = cpuc->events[INTEL_PMC_IDX_FIXED_BTS];
-	struct bts_record *at, *base, *top;
-	struct perf_output_handle handle;
-	struct perf_event_header header;
-	struct perf_sample_data data;
-	unsigned long skip = 0;
-	struct pt_regs regs;
-
-	if (!event)
-		return 0;
-
-	if (!x86_pmu.bts_active)
-		return 0;
-
-	base = (struct bts_record *)(unsigned long)ds->bts_buffer_base;
-	top  = (struct bts_record *)(unsigned long)ds->bts_index;
-
-	if (top <= base)
-		return 0;
-
-	memset(&regs, 0, sizeof(regs));
-
-	ds->bts_index = ds->bts_buffer_base;
-
-	perf_sample_data_init(&data, 0, event->hw.last_period);
-
-	/*
-	 * BTS leaks kernel addresses in branches across the cpl boundary,
-	 * such as traps or system calls, so unless the user is asking for
-	 * kernel tracing (and right now it's not possible), we'd need to
-	 * filter them out. But first we need to count how many of those we
-	 * have in the current batch. This is an extra O(n) pass, however,
-	 * it's much faster than the other one especially considering that
-	 * n <= 2560 (BTS_BUFFER_SIZE / BTS_RECORD_SIZE * 15/16; see the
-	 * alloc_bts_buffer()).
-	 */
-	for (at = base; at < top; at++) {
-		/*
-		 * Note that right now *this* BTS code only works if
-		 * attr::exclude_kernel is set, but let's keep this extra
-		 * check here in case that changes.
-		 */
-		if (event->attr.exclude_kernel &&
-		    (kernel_ip(at->from) || kernel_ip(at->to)))
-			skip++;
-	}
-
-	/*
-	 * Prepare a generic sample, i.e. fill in the invariant fields.
-	 * We will overwrite the from and to address before we output
-	 * the sample.
-	 */
-	perf_prepare_sample(&header, &data, event, &regs);
-
-	if (perf_output_begin(&handle, event, header.size *
-			      (top - base - skip)))
-		return 1;
-
-	for (at = base; at < top; at++) {
-		/* Filter out any records that contain kernel addresses. */
-		if (event->attr.exclude_kernel &&
-		    (kernel_ip(at->from) || kernel_ip(at->to)))
-			continue;
-
-		data.ip		= at->from;
-		data.addr	= at->to;
-
-		perf_output_sample(&handle, &header, &data, event);
-	}
-
-	perf_output_end(&handle);
-
-	/* There's new data available. */
-	event->hw.interrupts++;
-	event->pending_kill = POLL_IN;
-	return 1;
-}
-
-static inline void intel_pmu_drain_pebs_buffer(void)
-{
-	struct pt_regs regs;
-
-	x86_pmu.drain_pebs(&regs);
-}
-
-void intel_pmu_pebs_sched_task(struct perf_event_context *ctx, bool sched_in)
-{
-	if (!sched_in)
-		intel_pmu_drain_pebs_buffer();
-}
-
-/*
- * PEBS
- */
-struct event_constraint intel_core2_pebs_event_constraints[] = {
-	INTEL_FLAGS_UEVENT_CONSTRAINT(0x00c0, 0x1), /* INST_RETIRED.ANY */
-	INTEL_FLAGS_UEVENT_CONSTRAINT(0xfec1, 0x1), /* X87_OPS_RETIRED.ANY */
-	INTEL_FLAGS_UEVENT_CONSTRAINT(0x00c5, 0x1), /* BR_INST_RETIRED.MISPRED */
-	INTEL_FLAGS_UEVENT_CONSTRAINT(0x1fc7, 0x1), /* SIMD_INST_RETURED.ANY */
-	INTEL_FLAGS_EVENT_CONSTRAINT(0xcb, 0x1),    /* MEM_LOAD_RETIRED.* */
-	/* INST_RETIRED.ANY_P, inv=1, cmask=16 (cycles:p). */
-	INTEL_FLAGS_EVENT_CONSTRAINT(0x108000c0, 0x01),
-	EVENT_CONSTRAINT_END
-};
-
-struct event_constraint intel_atom_pebs_event_constraints[] = {
-	INTEL_FLAGS_UEVENT_CONSTRAINT(0x00c0, 0x1), /* INST_RETIRED.ANY */
-	INTEL_FLAGS_UEVENT_CONSTRAINT(0x00c5, 0x1), /* MISPREDICTED_BRANCH_RETIRED */
-	INTEL_FLAGS_EVENT_CONSTRAINT(0xcb, 0x1),    /* MEM_LOAD_RETIRED.* */
-	/* INST_RETIRED.ANY_P, inv=1, cmask=16 (cycles:p). */
-	INTEL_FLAGS_EVENT_CONSTRAINT(0x108000c0, 0x01),
-	EVENT_CONSTRAINT_END
-};
-
-struct event_constraint intel_slm_pebs_event_constraints[] = {
-	/* INST_RETIRED.ANY_P, inv=1, cmask=16 (cycles:p). */
-	INTEL_FLAGS_EVENT_CONSTRAINT(0x108000c0, 0x1),
-	/* Allow all events as PEBS with no flags */
-	INTEL_ALL_EVENT_CONSTRAINT(0, 0x1),
-	EVENT_CONSTRAINT_END
-};
-
-struct event_constraint intel_nehalem_pebs_event_constraints[] = {
-	INTEL_PLD_CONSTRAINT(0x100b, 0xf),      /* MEM_INST_RETIRED.* */
-	INTEL_FLAGS_EVENT_CONSTRAINT(0x0f, 0xf),    /* MEM_UNCORE_RETIRED.* */
-	INTEL_FLAGS_UEVENT_CONSTRAINT(0x010c, 0xf), /* MEM_STORE_RETIRED.DTLB_MISS */
-	INTEL_FLAGS_EVENT_CONSTRAINT(0xc0, 0xf),    /* INST_RETIRED.ANY */
-	INTEL_EVENT_CONSTRAINT(0xc2, 0xf),    /* UOPS_RETIRED.* */
-	INTEL_FLAGS_EVENT_CONSTRAINT(0xc4, 0xf),    /* BR_INST_RETIRED.* */
-	INTEL_FLAGS_UEVENT_CONSTRAINT(0x02c5, 0xf), /* BR_MISP_RETIRED.NEAR_CALL */
-	INTEL_FLAGS_EVENT_CONSTRAINT(0xc7, 0xf),    /* SSEX_UOPS_RETIRED.* */
-	INTEL_FLAGS_UEVENT_CONSTRAINT(0x20c8, 0xf), /* ITLB_MISS_RETIRED */
-	INTEL_FLAGS_EVENT_CONSTRAINT(0xcb, 0xf),    /* MEM_LOAD_RETIRED.* */
-	INTEL_FLAGS_EVENT_CONSTRAINT(0xf7, 0xf),    /* FP_ASSIST.* */
-	/* INST_RETIRED.ANY_P, inv=1, cmask=16 (cycles:p). */
-	INTEL_FLAGS_EVENT_CONSTRAINT(0x108000c0, 0x0f),
-	EVENT_CONSTRAINT_END
-};
-
-struct event_constraint intel_westmere_pebs_event_constraints[] = {
-	INTEL_PLD_CONSTRAINT(0x100b, 0xf),      /* MEM_INST_RETIRED.* */
-	INTEL_FLAGS_EVENT_CONSTRAINT(0x0f, 0xf),    /* MEM_UNCORE_RETIRED.* */
-	INTEL_FLAGS_UEVENT_CONSTRAINT(0x010c, 0xf), /* MEM_STORE_RETIRED.DTLB_MISS */
-	INTEL_FLAGS_EVENT_CONSTRAINT(0xc0, 0xf),    /* INSTR_RETIRED.* */
-	INTEL_EVENT_CONSTRAINT(0xc2, 0xf),    /* UOPS_RETIRED.* */
-	INTEL_FLAGS_EVENT_CONSTRAINT(0xc4, 0xf),    /* BR_INST_RETIRED.* */
-	INTEL_FLAGS_EVENT_CONSTRAINT(0xc5, 0xf),    /* BR_MISP_RETIRED.* */
-	INTEL_FLAGS_EVENT_CONSTRAINT(0xc7, 0xf),    /* SSEX_UOPS_RETIRED.* */
-	INTEL_FLAGS_UEVENT_CONSTRAINT(0x20c8, 0xf), /* ITLB_MISS_RETIRED */
-	INTEL_FLAGS_EVENT_CONSTRAINT(0xcb, 0xf),    /* MEM_LOAD_RETIRED.* */
-	INTEL_FLAGS_EVENT_CONSTRAINT(0xf7, 0xf),    /* FP_ASSIST.* */
-	/* INST_RETIRED.ANY_P, inv=1, cmask=16 (cycles:p). */
-	INTEL_FLAGS_EVENT_CONSTRAINT(0x108000c0, 0x0f),
-	EVENT_CONSTRAINT_END
-};
-
-struct event_constraint intel_snb_pebs_event_constraints[] = {
-	INTEL_FLAGS_UEVENT_CONSTRAINT(0x01c0, 0x2), /* INST_RETIRED.PRECDIST */
-	INTEL_PLD_CONSTRAINT(0x01cd, 0x8),    /* MEM_TRANS_RETIRED.LAT_ABOVE_THR */
-	INTEL_PST_CONSTRAINT(0x02cd, 0x8),    /* MEM_TRANS_RETIRED.PRECISE_STORES */
-	/* UOPS_RETIRED.ALL, inv=1, cmask=16 (cycles:p). */
-	INTEL_FLAGS_EVENT_CONSTRAINT(0x108001c2, 0xf),
-        INTEL_EXCLEVT_CONSTRAINT(0xd0, 0xf),    /* MEM_UOP_RETIRED.* */
-        INTEL_EXCLEVT_CONSTRAINT(0xd1, 0xf),    /* MEM_LOAD_UOPS_RETIRED.* */
-        INTEL_EXCLEVT_CONSTRAINT(0xd2, 0xf),    /* MEM_LOAD_UOPS_LLC_HIT_RETIRED.* */
-        INTEL_EXCLEVT_CONSTRAINT(0xd3, 0xf),    /* MEM_LOAD_UOPS_LLC_MISS_RETIRED.* */
-	/* Allow all events as PEBS with no flags */
-	INTEL_ALL_EVENT_CONSTRAINT(0, 0xf),
-	EVENT_CONSTRAINT_END
-};
-
-struct event_constraint intel_ivb_pebs_event_constraints[] = {
-        INTEL_FLAGS_UEVENT_CONSTRAINT(0x01c0, 0x2), /* INST_RETIRED.PRECDIST */
-        INTEL_PLD_CONSTRAINT(0x01cd, 0x8),    /* MEM_TRANS_RETIRED.LAT_ABOVE_THR */
-	INTEL_PST_CONSTRAINT(0x02cd, 0x8),    /* MEM_TRANS_RETIRED.PRECISE_STORES */
-	/* UOPS_RETIRED.ALL, inv=1, cmask=16 (cycles:p). */
-	INTEL_FLAGS_EVENT_CONSTRAINT(0x108001c2, 0xf),
-	INTEL_EXCLEVT_CONSTRAINT(0xd0, 0xf),    /* MEM_UOP_RETIRED.* */
-	INTEL_EXCLEVT_CONSTRAINT(0xd1, 0xf),    /* MEM_LOAD_UOPS_RETIRED.* */
-	INTEL_EXCLEVT_CONSTRAINT(0xd2, 0xf),    /* MEM_LOAD_UOPS_LLC_HIT_RETIRED.* */
-	INTEL_EXCLEVT_CONSTRAINT(0xd3, 0xf),    /* MEM_LOAD_UOPS_LLC_MISS_RETIRED.* */
-	/* Allow all events as PEBS with no flags */
-	INTEL_ALL_EVENT_CONSTRAINT(0, 0xf),
-        EVENT_CONSTRAINT_END
-};
-
-struct event_constraint intel_hsw_pebs_event_constraints[] = {
-	INTEL_FLAGS_UEVENT_CONSTRAINT(0x01c0, 0x2), /* INST_RETIRED.PRECDIST */
-	INTEL_PLD_CONSTRAINT(0x01cd, 0xf),    /* MEM_TRANS_RETIRED.* */
-	/* UOPS_RETIRED.ALL, inv=1, cmask=16 (cycles:p). */
-	INTEL_FLAGS_EVENT_CONSTRAINT(0x108001c2, 0xf),
-	INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_NA(0x01c2, 0xf), /* UOPS_RETIRED.ALL */
-	INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_XLD(0x11d0, 0xf), /* MEM_UOPS_RETIRED.STLB_MISS_LOADS */
-	INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_XLD(0x21d0, 0xf), /* MEM_UOPS_RETIRED.LOCK_LOADS */
-	INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_XLD(0x41d0, 0xf), /* MEM_UOPS_RETIRED.SPLIT_LOADS */
-	INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_XLD(0x81d0, 0xf), /* MEM_UOPS_RETIRED.ALL_LOADS */
-	INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_XST(0x12d0, 0xf), /* MEM_UOPS_RETIRED.STLB_MISS_STORES */
-	INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_XST(0x42d0, 0xf), /* MEM_UOPS_RETIRED.SPLIT_STORES */
-	INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_XST(0x82d0, 0xf), /* MEM_UOPS_RETIRED.ALL_STORES */
-	INTEL_FLAGS_EVENT_CONSTRAINT_DATALA_XLD(0xd1, 0xf),    /* MEM_LOAD_UOPS_RETIRED.* */
-	INTEL_FLAGS_EVENT_CONSTRAINT_DATALA_XLD(0xd2, 0xf),    /* MEM_LOAD_UOPS_L3_HIT_RETIRED.* */
-	INTEL_FLAGS_EVENT_CONSTRAINT_DATALA_XLD(0xd3, 0xf),    /* MEM_LOAD_UOPS_L3_MISS_RETIRED.* */
-	/* Allow all events as PEBS with no flags */
-	INTEL_ALL_EVENT_CONSTRAINT(0, 0xf),
-	EVENT_CONSTRAINT_END
-};
-
-struct event_constraint intel_skl_pebs_event_constraints[] = {
-	INTEL_FLAGS_UEVENT_CONSTRAINT(0x1c0, 0x2),	/* INST_RETIRED.PREC_DIST */
-	INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_NA(0x01c2, 0xf), /* UOPS_RETIRED.ALL */
-	/* UOPS_RETIRED.ALL, inv=1, cmask=16 (cycles:p). */
-	INTEL_FLAGS_EVENT_CONSTRAINT(0x108001c2, 0xf),
-	INTEL_PLD_CONSTRAINT(0x1cd, 0xf),		      /* MEM_TRANS_RETIRED.* */
-	INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_LD(0x11d0, 0xf), /* MEM_INST_RETIRED.STLB_MISS_LOADS */
-	INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_ST(0x12d0, 0xf), /* MEM_INST_RETIRED.STLB_MISS_STORES */
-	INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_LD(0x21d0, 0xf), /* MEM_INST_RETIRED.LOCK_LOADS */
-	INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_ST(0x22d0, 0xf), /* MEM_INST_RETIRED.LOCK_STORES */
-	INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_LD(0x41d0, 0xf), /* MEM_INST_RETIRED.SPLIT_LOADS */
-	INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_ST(0x42d0, 0xf), /* MEM_INST_RETIRED.SPLIT_STORES */
-	INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_LD(0x81d0, 0xf), /* MEM_INST_RETIRED.ALL_LOADS */
-	INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_ST(0x82d0, 0xf), /* MEM_INST_RETIRED.ALL_STORES */
-	INTEL_FLAGS_EVENT_CONSTRAINT_DATALA_LD(0xd1, 0xf),    /* MEM_LOAD_RETIRED.* */
-	INTEL_FLAGS_EVENT_CONSTRAINT_DATALA_LD(0xd2, 0xf),    /* MEM_LOAD_L3_HIT_RETIRED.* */
-	INTEL_FLAGS_EVENT_CONSTRAINT_DATALA_LD(0xd3, 0xf),    /* MEM_LOAD_L3_MISS_RETIRED.* */
-	/* Allow all events as PEBS with no flags */
-	INTEL_ALL_EVENT_CONSTRAINT(0, 0xf),
-	EVENT_CONSTRAINT_END
-};
-
-struct event_constraint *intel_pebs_constraints(struct perf_event *event)
-{
-	struct event_constraint *c;
-
-	if (!event->attr.precise_ip)
-		return NULL;
-
-	if (x86_pmu.pebs_constraints) {
-		for_each_event_constraint(c, x86_pmu.pebs_constraints) {
-			if ((event->hw.config & c->cmask) == c->code) {
-				event->hw.flags |= c->flags;
-				return c;
-			}
-		}
-	}
-
-	return &emptyconstraint;
-}
-
-static inline bool pebs_is_enabled(struct cpu_hw_events *cpuc)
-{
-	return (cpuc->pebs_enabled & ((1ULL << MAX_PEBS_EVENTS) - 1));
-}
-
-void intel_pmu_pebs_enable(struct perf_event *event)
-{
-	struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
-	struct hw_perf_event *hwc = &event->hw;
-	struct debug_store *ds = cpuc->ds;
-	bool first_pebs;
-	u64 threshold;
-
-	hwc->config &= ~ARCH_PERFMON_EVENTSEL_INT;
-
-	first_pebs = !pebs_is_enabled(cpuc);
-	cpuc->pebs_enabled |= 1ULL << hwc->idx;
-
-	if (event->hw.flags & PERF_X86_EVENT_PEBS_LDLAT)
-		cpuc->pebs_enabled |= 1ULL << (hwc->idx + 32);
-	else if (event->hw.flags & PERF_X86_EVENT_PEBS_ST)
-		cpuc->pebs_enabled |= 1ULL << 63;
-
-	/*
-	 * When the event is constrained enough we can use a larger
-	 * threshold and run the event with less frequent PMI.
-	 */
-	if (hwc->flags & PERF_X86_EVENT_FREERUNNING) {
-		threshold = ds->pebs_absolute_maximum -
-			x86_pmu.max_pebs_events * x86_pmu.pebs_record_size;
-
-		if (first_pebs)
-			perf_sched_cb_inc(event->ctx->pmu);
-	} else {
-		threshold = ds->pebs_buffer_base + x86_pmu.pebs_record_size;
-
-		/*
-		 * If not all events can use larger buffer,
-		 * roll back to threshold = 1
-		 */
-		if (!first_pebs &&
-		    (ds->pebs_interrupt_threshold > threshold))
-			perf_sched_cb_dec(event->ctx->pmu);
-	}
-
-	/* Use auto-reload if possible to save a MSR write in the PMI */
-	if (hwc->flags & PERF_X86_EVENT_AUTO_RELOAD) {
-		ds->pebs_event_reset[hwc->idx] =
-			(u64)(-hwc->sample_period) & x86_pmu.cntval_mask;
-	}
-
-	if (first_pebs || ds->pebs_interrupt_threshold > threshold)
-		ds->pebs_interrupt_threshold = threshold;
-}
-
-void intel_pmu_pebs_disable(struct perf_event *event)
-{
-	struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
-	struct hw_perf_event *hwc = &event->hw;
-	struct debug_store *ds = cpuc->ds;
-	bool large_pebs = ds->pebs_interrupt_threshold >
-		ds->pebs_buffer_base + x86_pmu.pebs_record_size;
-
-	if (large_pebs)
-		intel_pmu_drain_pebs_buffer();
-
-	cpuc->pebs_enabled &= ~(1ULL << hwc->idx);
-
-	if (event->hw.flags & PERF_X86_EVENT_PEBS_LDLAT)
-		cpuc->pebs_enabled &= ~(1ULL << (hwc->idx + 32));
-	else if (event->hw.flags & PERF_X86_EVENT_PEBS_ST)
-		cpuc->pebs_enabled &= ~(1ULL << 63);
-
-	if (large_pebs && !pebs_is_enabled(cpuc))
-		perf_sched_cb_dec(event->ctx->pmu);
-
-	if (cpuc->enabled)
-		wrmsrl(MSR_IA32_PEBS_ENABLE, cpuc->pebs_enabled);
-
-	hwc->config |= ARCH_PERFMON_EVENTSEL_INT;
-}
-
-void intel_pmu_pebs_enable_all(void)
-{
-	struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
-
-	if (cpuc->pebs_enabled)
-		wrmsrl(MSR_IA32_PEBS_ENABLE, cpuc->pebs_enabled);
-}
-
-void intel_pmu_pebs_disable_all(void)
-{
-	struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
-
-	if (cpuc->pebs_enabled)
-		wrmsrl(MSR_IA32_PEBS_ENABLE, 0);
-}
-
-static int intel_pmu_pebs_fixup_ip(struct pt_regs *regs)
-{
-	struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
-	unsigned long from = cpuc->lbr_entries[0].from;
-	unsigned long old_to, to = cpuc->lbr_entries[0].to;
-	unsigned long ip = regs->ip;
-	int is_64bit = 0;
-	void *kaddr;
-	int size;
-
-	/*
-	 * We don't need to fixup if the PEBS assist is fault like
-	 */
-	if (!x86_pmu.intel_cap.pebs_trap)
-		return 1;
-
-	/*
-	 * No LBR entry, no basic block, no rewinding
-	 */
-	if (!cpuc->lbr_stack.nr || !from || !to)
-		return 0;
-
-	/*
-	 * Basic blocks should never cross user/kernel boundaries
-	 */
-	if (kernel_ip(ip) != kernel_ip(to))
-		return 0;
-
-	/*
-	 * unsigned math, either ip is before the start (impossible) or
-	 * the basic block is larger than 1 page (sanity)
-	 */
-	if ((ip - to) > PEBS_FIXUP_SIZE)
-		return 0;
-
-	/*
-	 * We sampled a branch insn, rewind using the LBR stack
-	 */
-	if (ip == to) {
-		set_linear_ip(regs, from);
-		return 1;
-	}
-
-	size = ip - to;
-	if (!kernel_ip(ip)) {
-		int bytes;
-		u8 *buf = this_cpu_read(insn_buffer);
-
-		/* 'size' must fit our buffer, see above */
-		bytes = copy_from_user_nmi(buf, (void __user *)to, size);
-		if (bytes != 0)
-			return 0;
-
-		kaddr = buf;
-	} else {
-		kaddr = (void *)to;
-	}
-
-	do {
-		struct insn insn;
-
-		old_to = to;
-
-#ifdef CONFIG_X86_64
-		is_64bit = kernel_ip(to) || !test_thread_flag(TIF_IA32);
-#endif
-		insn_init(&insn, kaddr, size, is_64bit);
-		insn_get_length(&insn);
-		/*
-		 * Make sure there was not a problem decoding the
-		 * instruction and getting the length.  This is
-		 * doubly important because we have an infinite
-		 * loop if insn.length=0.
-		 */
-		if (!insn.length)
-			break;
-
-		to += insn.length;
-		kaddr += insn.length;
-		size -= insn.length;
-	} while (to < ip);
-
-	if (to == ip) {
-		set_linear_ip(regs, old_to);
-		return 1;
-	}
-
-	/*
-	 * Even though we decoded the basic block, the instruction stream
-	 * never matched the given IP, either the TO or the IP got corrupted.
-	 */
-	return 0;
-}
-
-static inline u64 intel_hsw_weight(struct pebs_record_skl *pebs)
-{
-	if (pebs->tsx_tuning) {
-		union hsw_tsx_tuning tsx = { .value = pebs->tsx_tuning };
-		return tsx.cycles_last_block;
-	}
-	return 0;
-}
-
-static inline u64 intel_hsw_transaction(struct pebs_record_skl *pebs)
-{
-	u64 txn = (pebs->tsx_tuning & PEBS_HSW_TSX_FLAGS) >> 32;
-
-	/* For RTM XABORTs also log the abort code from AX */
-	if ((txn & PERF_TXN_TRANSACTION) && (pebs->ax & 1))
-		txn |= ((pebs->ax >> 24) & 0xff) << PERF_TXN_ABORT_SHIFT;
-	return txn;
-}
-
-static void setup_pebs_sample_data(struct perf_event *event,
-				   struct pt_regs *iregs, void *__pebs,
-				   struct perf_sample_data *data,
-				   struct pt_regs *regs)
-{
-#define PERF_X86_EVENT_PEBS_HSW_PREC \
-		(PERF_X86_EVENT_PEBS_ST_HSW | \
-		 PERF_X86_EVENT_PEBS_LD_HSW | \
-		 PERF_X86_EVENT_PEBS_NA_HSW)
-	/*
-	 * We cast to the biggest pebs_record but are careful not to
-	 * unconditionally access the 'extra' entries.
-	 */
-	struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
-	struct pebs_record_skl *pebs = __pebs;
-	u64 sample_type;
-	int fll, fst, dsrc;
-	int fl = event->hw.flags;
-
-	if (pebs == NULL)
-		return;
-
-	sample_type = event->attr.sample_type;
-	dsrc = sample_type & PERF_SAMPLE_DATA_SRC;
-
-	fll = fl & PERF_X86_EVENT_PEBS_LDLAT;
-	fst = fl & (PERF_X86_EVENT_PEBS_ST | PERF_X86_EVENT_PEBS_HSW_PREC);
-
-	perf_sample_data_init(data, 0, event->hw.last_period);
-
-	data->period = event->hw.last_period;
-
-	/*
-	 * Use latency for weight (only avail with PEBS-LL)
-	 */
-	if (fll && (sample_type & PERF_SAMPLE_WEIGHT))
-		data->weight = pebs->lat;
-
-	/*
-	 * data.data_src encodes the data source
-	 */
-	if (dsrc) {
-		u64 val = PERF_MEM_NA;
-		if (fll)
-			val = load_latency_data(pebs->dse);
-		else if (fst && (fl & PERF_X86_EVENT_PEBS_HSW_PREC))
-			val = precise_datala_hsw(event, pebs->dse);
-		else if (fst)
-			val = precise_store_data(pebs->dse);
-		data->data_src.val = val;
-	}
-
-	/*
-	 * We use the interrupt regs as a base because the PEBS record
-	 * does not contain a full regs set, specifically it seems to
-	 * lack segment descriptors, which get used by things like
-	 * user_mode().
-	 *
-	 * In the simple case fix up only the IP and BP,SP regs, for
-	 * PERF_SAMPLE_IP and PERF_SAMPLE_CALLCHAIN to function properly.
-	 * A possible PERF_SAMPLE_REGS will have to transfer all regs.
-	 */
-	*regs = *iregs;
-	regs->flags = pebs->flags;
-	set_linear_ip(regs, pebs->ip);
-	regs->bp = pebs->bp;
-	regs->sp = pebs->sp;
-
-	if (sample_type & PERF_SAMPLE_REGS_INTR) {
-		regs->ax = pebs->ax;
-		regs->bx = pebs->bx;
-		regs->cx = pebs->cx;
-		regs->dx = pebs->dx;
-		regs->si = pebs->si;
-		regs->di = pebs->di;
-		regs->bp = pebs->bp;
-		regs->sp = pebs->sp;
-
-		regs->flags = pebs->flags;
-#ifndef CONFIG_X86_32
-		regs->r8 = pebs->r8;
-		regs->r9 = pebs->r9;
-		regs->r10 = pebs->r10;
-		regs->r11 = pebs->r11;
-		regs->r12 = pebs->r12;
-		regs->r13 = pebs->r13;
-		regs->r14 = pebs->r14;
-		regs->r15 = pebs->r15;
-#endif
-	}
-
-	if (event->attr.precise_ip > 1 && x86_pmu.intel_cap.pebs_format >= 2) {
-		regs->ip = pebs->real_ip;
-		regs->flags |= PERF_EFLAGS_EXACT;
-	} else if (event->attr.precise_ip > 1 && intel_pmu_pebs_fixup_ip(regs))
-		regs->flags |= PERF_EFLAGS_EXACT;
-	else
-		regs->flags &= ~PERF_EFLAGS_EXACT;
-
-	if ((sample_type & PERF_SAMPLE_ADDR) &&
-	    x86_pmu.intel_cap.pebs_format >= 1)
-		data->addr = pebs->dla;
-
-	if (x86_pmu.intel_cap.pebs_format >= 2) {
-		/* Only set the TSX weight when no memory weight. */
-		if ((sample_type & PERF_SAMPLE_WEIGHT) && !fll)
-			data->weight = intel_hsw_weight(pebs);
-
-		if (sample_type & PERF_SAMPLE_TRANSACTION)
-			data->txn = intel_hsw_transaction(pebs);
-	}
-
-	/*
-	 * v3 supplies an accurate time stamp, so we use that
-	 * for the time stamp.
-	 *
-	 * We can only do this for the default trace clock.
-	 */
-	if (x86_pmu.intel_cap.pebs_format >= 3 &&
-		event->attr.use_clockid == 0)
-		data->time = native_sched_clock_from_tsc(pebs->tsc);
-
-	if (has_branch_stack(event))
-		data->br_stack = &cpuc->lbr_stack;
-}
-
-static inline void *
-get_next_pebs_record_by_bit(void *base, void *top, int bit)
-{
-	struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
-	void *at;
-	u64 pebs_status;
-
-	if (base == NULL)
-		return NULL;
-
-	for (at = base; at < top; at += x86_pmu.pebs_record_size) {
-		struct pebs_record_nhm *p = at;
-
-		if (test_bit(bit, (unsigned long *)&p->status)) {
-			/* PEBS v3 has accurate status bits */
-			if (x86_pmu.intel_cap.pebs_format >= 3)
-				return at;
-
-			if (p->status == (1 << bit))
-				return at;
-
-			/* clear non-PEBS bit and re-check */
-			pebs_status = p->status & cpuc->pebs_enabled;
-			pebs_status &= (1ULL << MAX_PEBS_EVENTS) - 1;
-			if (pebs_status == (1 << bit))
-				return at;
-		}
-	}
-	return NULL;
-}
-
-static void __intel_pmu_pebs_event(struct perf_event *event,
-				   struct pt_regs *iregs,
-				   void *base, void *top,
-				   int bit, int count)
-{
-	struct perf_sample_data data;
-	struct pt_regs regs;
-	void *at = get_next_pebs_record_by_bit(base, top, bit);
-
-	if (!intel_pmu_save_and_restart(event) &&
-	    !(event->hw.flags & PERF_X86_EVENT_AUTO_RELOAD))
-		return;
-
-	while (count > 1) {
-		setup_pebs_sample_data(event, iregs, at, &data, &regs);
-		perf_event_output(event, &data, &regs);
-		at += x86_pmu.pebs_record_size;
-		at = get_next_pebs_record_by_bit(at, top, bit);
-		count--;
-	}
-
-	setup_pebs_sample_data(event, iregs, at, &data, &regs);
-
-	/*
-	 * All but the last records are processed.
-	 * The last one is left to be able to call the overflow handler.
-	 */
-	if (perf_event_overflow(event, &data, &regs)) {
-		x86_pmu_stop(event, 0);
-		return;
-	}
-
-}
-
-static void intel_pmu_drain_pebs_core(struct pt_regs *iregs)
-{
-	struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
-	struct debug_store *ds = cpuc->ds;
-	struct perf_event *event = cpuc->events[0]; /* PMC0 only */
-	struct pebs_record_core *at, *top;
-	int n;
-
-	if (!x86_pmu.pebs_active)
-		return;
-
-	at  = (struct pebs_record_core *)(unsigned long)ds->pebs_buffer_base;
-	top = (struct pebs_record_core *)(unsigned long)ds->pebs_index;
-
-	/*
-	 * Whatever else happens, drain the thing
-	 */
-	ds->pebs_index = ds->pebs_buffer_base;
-
-	if (!test_bit(0, cpuc->active_mask))
-		return;
-
-	WARN_ON_ONCE(!event);
-
-	if (!event->attr.precise_ip)
-		return;
-
-	n = (top - at) / x86_pmu.pebs_record_size;
-	if (n <= 0)
-		return;
-
-	__intel_pmu_pebs_event(event, iregs, at, top, 0, n);
-}
-
-static void intel_pmu_drain_pebs_nhm(struct pt_regs *iregs)
-{
-	struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
-	struct debug_store *ds = cpuc->ds;
-	struct perf_event *event;
-	void *base, *at, *top;
-	short counts[MAX_PEBS_EVENTS] = {};
-	short error[MAX_PEBS_EVENTS] = {};
-	int bit, i;
-
-	if (!x86_pmu.pebs_active)
-		return;
-
-	base = (struct pebs_record_nhm *)(unsigned long)ds->pebs_buffer_base;
-	top = (struct pebs_record_nhm *)(unsigned long)ds->pebs_index;
-
-	ds->pebs_index = ds->pebs_buffer_base;
-
-	if (unlikely(base >= top))
-		return;
-
-	for (at = base; at < top; at += x86_pmu.pebs_record_size) {
-		struct pebs_record_nhm *p = at;
-		u64 pebs_status;
-
-		/* PEBS v3 has accurate status bits */
-		if (x86_pmu.intel_cap.pebs_format >= 3) {
-			for_each_set_bit(bit, (unsigned long *)&p->status,
-					 MAX_PEBS_EVENTS)
-				counts[bit]++;
-
-			continue;
-		}
-
-		pebs_status = p->status & cpuc->pebs_enabled;
-		pebs_status &= (1ULL << x86_pmu.max_pebs_events) - 1;
-
-		bit = find_first_bit((unsigned long *)&pebs_status,
-					x86_pmu.max_pebs_events);
-		if (WARN(bit >= x86_pmu.max_pebs_events,
-			 "PEBS record without PEBS event! status=%Lx pebs_enabled=%Lx active_mask=%Lx",
-			 (unsigned long long)p->status, (unsigned long long)cpuc->pebs_enabled,
-			 *(unsigned long long *)cpuc->active_mask))
-			continue;
-
-		/*
-		 * The PEBS hardware does not deal well with the situation
-		 * when events happen near to each other and multiple bits
-		 * are set. But it should happen rarely.
-		 *
-		 * If these events include one PEBS and multiple non-PEBS
-		 * events, it doesn't impact PEBS record. The record will
-		 * be handled normally. (slow path)
-		 *
-		 * If these events include two or more PEBS events, the
-		 * records for the events can be collapsed into a single
-		 * one, and it's not possible to reconstruct all events
-		 * that caused the PEBS record. It's called collision.
-		 * If collision happened, the record will be dropped.
-		 */
-		if (p->status != (1ULL << bit)) {
-			for_each_set_bit(i, (unsigned long *)&pebs_status,
-					 x86_pmu.max_pebs_events)
-				error[i]++;
-			continue;
-		}
-
-		counts[bit]++;
-	}
-
-	for (bit = 0; bit < x86_pmu.max_pebs_events; bit++) {
-		if ((counts[bit] == 0) && (error[bit] == 0))
-			continue;
-
-		event = cpuc->events[bit];
-		WARN_ON_ONCE(!event);
-		WARN_ON_ONCE(!event->attr.precise_ip);
-
-		/* log dropped samples number */
-		if (error[bit])
-			perf_log_lost_samples(event, error[bit]);
-
-		if (counts[bit]) {
-			__intel_pmu_pebs_event(event, iregs, base,
-					       top, bit, counts[bit]);
-		}
-	}
-}
-
-/*
- * BTS, PEBS probe and setup
- */
-
-void __init intel_ds_init(void)
-{
-	/*
-	 * No support for 32bit formats
-	 */
-	if (!boot_cpu_has(X86_FEATURE_DTES64))
-		return;
-
-	x86_pmu.bts  = boot_cpu_has(X86_FEATURE_BTS);
-	x86_pmu.pebs = boot_cpu_has(X86_FEATURE_PEBS);
-	if (x86_pmu.pebs) {
-		char pebs_type = x86_pmu.intel_cap.pebs_trap ?  '+' : '-';
-		int format = x86_pmu.intel_cap.pebs_format;
-
-		switch (format) {
-		case 0:
-			printk(KERN_CONT "PEBS fmt0%c, ", pebs_type);
-			x86_pmu.pebs_record_size = sizeof(struct pebs_record_core);
-			x86_pmu.drain_pebs = intel_pmu_drain_pebs_core;
-			break;
-
-		case 1:
-			printk(KERN_CONT "PEBS fmt1%c, ", pebs_type);
-			x86_pmu.pebs_record_size = sizeof(struct pebs_record_nhm);
-			x86_pmu.drain_pebs = intel_pmu_drain_pebs_nhm;
-			break;
-
-		case 2:
-			pr_cont("PEBS fmt2%c, ", pebs_type);
-			x86_pmu.pebs_record_size = sizeof(struct pebs_record_hsw);
-			x86_pmu.drain_pebs = intel_pmu_drain_pebs_nhm;
-			break;
-
-		case 3:
-			pr_cont("PEBS fmt3%c, ", pebs_type);
-			x86_pmu.pebs_record_size =
-						sizeof(struct pebs_record_skl);
-			x86_pmu.drain_pebs = intel_pmu_drain_pebs_nhm;
-			x86_pmu.free_running_flags |= PERF_SAMPLE_TIME;
-			break;
-
-		default:
-			printk(KERN_CONT "no PEBS fmt%d%c, ", format, pebs_type);
-			x86_pmu.pebs = 0;
-		}
-	}
-}
-
-void perf_restore_debug_store(void)
-{
-	struct debug_store *ds = __this_cpu_read(cpu_hw_events.ds);
-
-	if (!x86_pmu.bts && !x86_pmu.pebs)
-		return;
-
-	wrmsrl(MSR_IA32_DS_AREA, (unsigned long)ds);
-}
--- zfcpdump-kernel-4.4.orig/arch/x86/kernel/cpu/perf_event_intel_lbr.c
+++ /dev/null
@@ -1,1030 +0,0 @@
-#include <linux/perf_event.h>
-#include <linux/types.h>
-
-#include <asm/perf_event.h>
-#include <asm/msr.h>
-#include <asm/insn.h>
-
-#include "perf_event.h"
-
-enum {
-	LBR_FORMAT_32		= 0x00,
-	LBR_FORMAT_LIP		= 0x01,
-	LBR_FORMAT_EIP		= 0x02,
-	LBR_FORMAT_EIP_FLAGS	= 0x03,
-	LBR_FORMAT_EIP_FLAGS2	= 0x04,
-	LBR_FORMAT_INFO		= 0x05,
-	LBR_FORMAT_MAX_KNOWN    = LBR_FORMAT_INFO,
-};
-
-static enum {
-	LBR_EIP_FLAGS		= 1,
-	LBR_TSX			= 2,
-} lbr_desc[LBR_FORMAT_MAX_KNOWN + 1] = {
-	[LBR_FORMAT_EIP_FLAGS]  = LBR_EIP_FLAGS,
-	[LBR_FORMAT_EIP_FLAGS2] = LBR_EIP_FLAGS | LBR_TSX,
-};
-
-/*
- * Intel LBR_SELECT bits
- * Intel Vol3a, April 2011, Section 16.7 Table 16-10
- *
- * Hardware branch filter (not available on all CPUs)
- */
-#define LBR_KERNEL_BIT		0 /* do not capture at ring0 */
-#define LBR_USER_BIT		1 /* do not capture at ring > 0 */
-#define LBR_JCC_BIT		2 /* do not capture conditional branches */
-#define LBR_REL_CALL_BIT	3 /* do not capture relative calls */
-#define LBR_IND_CALL_BIT	4 /* do not capture indirect calls */
-#define LBR_RETURN_BIT		5 /* do not capture near returns */
-#define LBR_IND_JMP_BIT		6 /* do not capture indirect jumps */
-#define LBR_REL_JMP_BIT		7 /* do not capture relative jumps */
-#define LBR_FAR_BIT		8 /* do not capture far branches */
-#define LBR_CALL_STACK_BIT	9 /* enable call stack */
-
-#define LBR_KERNEL	(1 << LBR_KERNEL_BIT)
-#define LBR_USER	(1 << LBR_USER_BIT)
-#define LBR_JCC		(1 << LBR_JCC_BIT)
-#define LBR_REL_CALL	(1 << LBR_REL_CALL_BIT)
-#define LBR_IND_CALL	(1 << LBR_IND_CALL_BIT)
-#define LBR_RETURN	(1 << LBR_RETURN_BIT)
-#define LBR_REL_JMP	(1 << LBR_REL_JMP_BIT)
-#define LBR_IND_JMP	(1 << LBR_IND_JMP_BIT)
-#define LBR_FAR		(1 << LBR_FAR_BIT)
-#define LBR_CALL_STACK	(1 << LBR_CALL_STACK_BIT)
-
-#define LBR_PLM (LBR_KERNEL | LBR_USER)
-
-#define LBR_SEL_MASK	0x1ff	/* valid bits in LBR_SELECT */
-#define LBR_NOT_SUPP	-1	/* LBR filter not supported */
-#define LBR_IGN		0	/* ignored */
-
-#define LBR_ANY		 \
-	(LBR_JCC	|\
-	 LBR_REL_CALL	|\
-	 LBR_IND_CALL	|\
-	 LBR_RETURN	|\
-	 LBR_REL_JMP	|\
-	 LBR_IND_JMP	|\
-	 LBR_FAR)
-
-#define LBR_FROM_FLAG_MISPRED  (1ULL << 63)
-#define LBR_FROM_FLAG_IN_TX    (1ULL << 62)
-#define LBR_FROM_FLAG_ABORT    (1ULL << 61)
-
-/*
- * x86control flow change classification
- * x86control flow changes include branches, interrupts, traps, faults
- */
-enum {
-	X86_BR_NONE		= 0,      /* unknown */
-
-	X86_BR_USER		= 1 << 0, /* branch target is user */
-	X86_BR_KERNEL		= 1 << 1, /* branch target is kernel */
-
-	X86_BR_CALL		= 1 << 2, /* call */
-	X86_BR_RET		= 1 << 3, /* return */
-	X86_BR_SYSCALL		= 1 << 4, /* syscall */
-	X86_BR_SYSRET		= 1 << 5, /* syscall return */
-	X86_BR_INT		= 1 << 6, /* sw interrupt */
-	X86_BR_IRET		= 1 << 7, /* return from interrupt */
-	X86_BR_JCC		= 1 << 8, /* conditional */
-	X86_BR_JMP		= 1 << 9, /* jump */
-	X86_BR_IRQ		= 1 << 10,/* hw interrupt or trap or fault */
-	X86_BR_IND_CALL		= 1 << 11,/* indirect calls */
-	X86_BR_ABORT		= 1 << 12,/* transaction abort */
-	X86_BR_IN_TX		= 1 << 13,/* in transaction */
-	X86_BR_NO_TX		= 1 << 14,/* not in transaction */
-	X86_BR_ZERO_CALL	= 1 << 15,/* zero length call */
-	X86_BR_CALL_STACK	= 1 << 16,/* call stack */
-	X86_BR_IND_JMP		= 1 << 17,/* indirect jump */
-};
-
-#define X86_BR_PLM (X86_BR_USER | X86_BR_KERNEL)
-#define X86_BR_ANYTX (X86_BR_NO_TX | X86_BR_IN_TX)
-
-#define X86_BR_ANY       \
-	(X86_BR_CALL    |\
-	 X86_BR_RET     |\
-	 X86_BR_SYSCALL |\
-	 X86_BR_SYSRET  |\
-	 X86_BR_INT     |\
-	 X86_BR_IRET    |\
-	 X86_BR_JCC     |\
-	 X86_BR_JMP	 |\
-	 X86_BR_IRQ	 |\
-	 X86_BR_ABORT	 |\
-	 X86_BR_IND_CALL |\
-	 X86_BR_IND_JMP  |\
-	 X86_BR_ZERO_CALL)
-
-#define X86_BR_ALL (X86_BR_PLM | X86_BR_ANY)
-
-#define X86_BR_ANY_CALL		 \
-	(X86_BR_CALL		|\
-	 X86_BR_IND_CALL	|\
-	 X86_BR_ZERO_CALL	|\
-	 X86_BR_SYSCALL		|\
-	 X86_BR_IRQ		|\
-	 X86_BR_INT)
-
-static void intel_pmu_lbr_filter(struct cpu_hw_events *cpuc);
-
-/*
- * We only support LBR implementations that have FREEZE_LBRS_ON_PMI
- * otherwise it becomes near impossible to get a reliable stack.
- */
-
-static void __intel_pmu_lbr_enable(bool pmi)
-{
-	struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
-	u64 debugctl, lbr_select = 0, orig_debugctl;
-
-	/*
-	 * No need to unfreeze manually, as v4 can do that as part
-	 * of the GLOBAL_STATUS ack.
-	 */
-	if (pmi && x86_pmu.version >= 4)
-		return;
-
-	/*
-	 * No need to reprogram LBR_SELECT in a PMI, as it
-	 * did not change.
-	 */
-	if (cpuc->lbr_sel)
-		lbr_select = cpuc->lbr_sel->config;
-	if (!pmi)
-		wrmsrl(MSR_LBR_SELECT, lbr_select);
-
-	rdmsrl(MSR_IA32_DEBUGCTLMSR, debugctl);
-	orig_debugctl = debugctl;
-	debugctl |= DEBUGCTLMSR_LBR;
-	/*
-	 * LBR callstack does not work well with FREEZE_LBRS_ON_PMI.
-	 * If FREEZE_LBRS_ON_PMI is set, PMI near call/return instructions
-	 * may cause superfluous increase/decrease of LBR_TOS.
-	 */
-	if (!(lbr_select & LBR_CALL_STACK))
-		debugctl |= DEBUGCTLMSR_FREEZE_LBRS_ON_PMI;
-	if (orig_debugctl != debugctl)
-		wrmsrl(MSR_IA32_DEBUGCTLMSR, debugctl);
-}
-
-static void __intel_pmu_lbr_disable(void)
-{
-	u64 debugctl;
-
-	rdmsrl(MSR_IA32_DEBUGCTLMSR, debugctl);
-	debugctl &= ~(DEBUGCTLMSR_LBR | DEBUGCTLMSR_FREEZE_LBRS_ON_PMI);
-	wrmsrl(MSR_IA32_DEBUGCTLMSR, debugctl);
-}
-
-static void intel_pmu_lbr_reset_32(void)
-{
-	int i;
-
-	for (i = 0; i < x86_pmu.lbr_nr; i++)
-		wrmsrl(x86_pmu.lbr_from + i, 0);
-}
-
-static void intel_pmu_lbr_reset_64(void)
-{
-	int i;
-
-	for (i = 0; i < x86_pmu.lbr_nr; i++) {
-		wrmsrl(x86_pmu.lbr_from + i, 0);
-		wrmsrl(x86_pmu.lbr_to   + i, 0);
-		if (x86_pmu.intel_cap.lbr_format == LBR_FORMAT_INFO)
-			wrmsrl(MSR_LBR_INFO_0 + i, 0);
-	}
-}
-
-void intel_pmu_lbr_reset(void)
-{
-	if (!x86_pmu.lbr_nr)
-		return;
-
-	if (x86_pmu.intel_cap.lbr_format == LBR_FORMAT_32)
-		intel_pmu_lbr_reset_32();
-	else
-		intel_pmu_lbr_reset_64();
-}
-
-/*
- * TOS = most recently recorded branch
- */
-static inline u64 intel_pmu_lbr_tos(void)
-{
-	u64 tos;
-
-	rdmsrl(x86_pmu.lbr_tos, tos);
-	return tos;
-}
-
-enum {
-	LBR_NONE,
-	LBR_VALID,
-};
-
-static void __intel_pmu_lbr_restore(struct x86_perf_task_context *task_ctx)
-{
-	int i;
-	unsigned lbr_idx, mask;
-	u64 tos;
-
-	if (task_ctx->lbr_callstack_users == 0 ||
-	    task_ctx->lbr_stack_state == LBR_NONE) {
-		intel_pmu_lbr_reset();
-		return;
-	}
-
-	mask = x86_pmu.lbr_nr - 1;
-	tos = task_ctx->tos;
-	for (i = 0; i < tos; i++) {
-		lbr_idx = (tos - i) & mask;
-		wrmsrl(x86_pmu.lbr_from + lbr_idx, task_ctx->lbr_from[i]);
-		wrmsrl(x86_pmu.lbr_to + lbr_idx, task_ctx->lbr_to[i]);
-		if (x86_pmu.intel_cap.lbr_format == LBR_FORMAT_INFO)
-			wrmsrl(MSR_LBR_INFO_0 + lbr_idx, task_ctx->lbr_info[i]);
-	}
-	wrmsrl(x86_pmu.lbr_tos, tos);
-	task_ctx->lbr_stack_state = LBR_NONE;
-}
-
-static void __intel_pmu_lbr_save(struct x86_perf_task_context *task_ctx)
-{
-	int i;
-	unsigned lbr_idx, mask;
-	u64 tos;
-
-	if (task_ctx->lbr_callstack_users == 0) {
-		task_ctx->lbr_stack_state = LBR_NONE;
-		return;
-	}
-
-	mask = x86_pmu.lbr_nr - 1;
-	tos = intel_pmu_lbr_tos();
-	for (i = 0; i < tos; i++) {
-		lbr_idx = (tos - i) & mask;
-		rdmsrl(x86_pmu.lbr_from + lbr_idx, task_ctx->lbr_from[i]);
-		rdmsrl(x86_pmu.lbr_to + lbr_idx, task_ctx->lbr_to[i]);
-		if (x86_pmu.intel_cap.lbr_format == LBR_FORMAT_INFO)
-			rdmsrl(MSR_LBR_INFO_0 + lbr_idx, task_ctx->lbr_info[i]);
-	}
-	task_ctx->tos = tos;
-	task_ctx->lbr_stack_state = LBR_VALID;
-}
-
-void intel_pmu_lbr_sched_task(struct perf_event_context *ctx, bool sched_in)
-{
-	struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
-	struct x86_perf_task_context *task_ctx;
-
-	/*
-	 * If LBR callstack feature is enabled and the stack was saved when
-	 * the task was scheduled out, restore the stack. Otherwise flush
-	 * the LBR stack.
-	 */
-	task_ctx = ctx ? ctx->task_ctx_data : NULL;
-	if (task_ctx) {
-		if (sched_in) {
-			__intel_pmu_lbr_restore(task_ctx);
-			cpuc->lbr_context = ctx;
-		} else {
-			__intel_pmu_lbr_save(task_ctx);
-		}
-		return;
-	}
-
-	/*
-	 * When sampling the branck stack in system-wide, it may be
-	 * necessary to flush the stack on context switch. This happens
-	 * when the branch stack does not tag its entries with the pid
-	 * of the current task. Otherwise it becomes impossible to
-	 * associate a branch entry with a task. This ambiguity is more
-	 * likely to appear when the branch stack supports priv level
-	 * filtering and the user sets it to monitor only at the user
-	 * level (which could be a useful measurement in system-wide
-	 * mode). In that case, the risk is high of having a branch
-	 * stack with branch from multiple tasks.
- 	 */
-	if (sched_in) {
-		intel_pmu_lbr_reset();
-		cpuc->lbr_context = ctx;
-	}
-}
-
-static inline bool branch_user_callstack(unsigned br_sel)
-{
-	return (br_sel & X86_BR_USER) && (br_sel & X86_BR_CALL_STACK);
-}
-
-void intel_pmu_lbr_enable(struct perf_event *event)
-{
-	struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
-	struct x86_perf_task_context *task_ctx;
-
-	if (!x86_pmu.lbr_nr)
-		return;
-
-	/*
-	 * Reset the LBR stack if we changed task context to
-	 * avoid data leaks.
-	 */
-	if (event->ctx->task && cpuc->lbr_context != event->ctx) {
-		intel_pmu_lbr_reset();
-		cpuc->lbr_context = event->ctx;
-	}
-	cpuc->br_sel = event->hw.branch_reg.reg;
-
-	if (branch_user_callstack(cpuc->br_sel) && event->ctx &&
-					event->ctx->task_ctx_data) {
-		task_ctx = event->ctx->task_ctx_data;
-		task_ctx->lbr_callstack_users++;
-	}
-
-	cpuc->lbr_users++;
-	perf_sched_cb_inc(event->ctx->pmu);
-}
-
-void intel_pmu_lbr_disable(struct perf_event *event)
-{
-	struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
-	struct x86_perf_task_context *task_ctx;
-
-	if (!x86_pmu.lbr_nr)
-		return;
-
-	if (branch_user_callstack(cpuc->br_sel) && event->ctx &&
-					event->ctx->task_ctx_data) {
-		task_ctx = event->ctx->task_ctx_data;
-		task_ctx->lbr_callstack_users--;
-	}
-
-	cpuc->lbr_users--;
-	WARN_ON_ONCE(cpuc->lbr_users < 0);
-	perf_sched_cb_dec(event->ctx->pmu);
-
-	if (cpuc->enabled && !cpuc->lbr_users) {
-		__intel_pmu_lbr_disable();
-		/* avoid stale pointer */
-		cpuc->lbr_context = NULL;
-	}
-}
-
-void intel_pmu_lbr_enable_all(bool pmi)
-{
-	struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
-
-	if (cpuc->lbr_users)
-		__intel_pmu_lbr_enable(pmi);
-}
-
-void intel_pmu_lbr_disable_all(void)
-{
-	struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
-
-	if (cpuc->lbr_users)
-		__intel_pmu_lbr_disable();
-}
-
-static void intel_pmu_lbr_read_32(struct cpu_hw_events *cpuc)
-{
-	unsigned long mask = x86_pmu.lbr_nr - 1;
-	u64 tos = intel_pmu_lbr_tos();
-	int i;
-
-	for (i = 0; i < x86_pmu.lbr_nr; i++) {
-		unsigned long lbr_idx = (tos - i) & mask;
-		union {
-			struct {
-				u32 from;
-				u32 to;
-			};
-			u64     lbr;
-		} msr_lastbranch;
-
-		rdmsrl(x86_pmu.lbr_from + lbr_idx, msr_lastbranch.lbr);
-
-		cpuc->lbr_entries[i].from	= msr_lastbranch.from;
-		cpuc->lbr_entries[i].to		= msr_lastbranch.to;
-		cpuc->lbr_entries[i].mispred	= 0;
-		cpuc->lbr_entries[i].predicted	= 0;
-		cpuc->lbr_entries[i].reserved	= 0;
-	}
-	cpuc->lbr_stack.nr = i;
-}
-
-/*
- * Due to lack of segmentation in Linux the effective address (offset)
- * is the same as the linear address, allowing us to merge the LIP and EIP
- * LBR formats.
- */
-static void intel_pmu_lbr_read_64(struct cpu_hw_events *cpuc)
-{
-	unsigned long mask = x86_pmu.lbr_nr - 1;
-	int lbr_format = x86_pmu.intel_cap.lbr_format;
-	u64 tos = intel_pmu_lbr_tos();
-	int i;
-	int out = 0;
-	int num = x86_pmu.lbr_nr;
-
-	if (cpuc->lbr_sel->config & LBR_CALL_STACK)
-		num = tos;
-
-	for (i = 0; i < num; i++) {
-		unsigned long lbr_idx = (tos - i) & mask;
-		u64 from, to, mis = 0, pred = 0, in_tx = 0, abort = 0;
-		int skip = 0;
-		u16 cycles = 0;
-		int lbr_flags = lbr_desc[lbr_format];
-
-		rdmsrl(x86_pmu.lbr_from + lbr_idx, from);
-		rdmsrl(x86_pmu.lbr_to   + lbr_idx, to);
-
-		if (lbr_format == LBR_FORMAT_INFO) {
-			u64 info;
-
-			rdmsrl(MSR_LBR_INFO_0 + lbr_idx, info);
-			mis = !!(info & LBR_INFO_MISPRED);
-			pred = !mis;
-			in_tx = !!(info & LBR_INFO_IN_TX);
-			abort = !!(info & LBR_INFO_ABORT);
-			cycles = (info & LBR_INFO_CYCLES);
-		}
-		if (lbr_flags & LBR_EIP_FLAGS) {
-			mis = !!(from & LBR_FROM_FLAG_MISPRED);
-			pred = !mis;
-			skip = 1;
-		}
-		if (lbr_flags & LBR_TSX) {
-			in_tx = !!(from & LBR_FROM_FLAG_IN_TX);
-			abort = !!(from & LBR_FROM_FLAG_ABORT);
-			skip = 3;
-		}
-		from = (u64)((((s64)from) << skip) >> skip);
-
-		/*
-		 * Some CPUs report duplicated abort records,
-		 * with the second entry not having an abort bit set.
-		 * Skip them here. This loop runs backwards,
-		 * so we need to undo the previous record.
-		 * If the abort just happened outside the window
-		 * the extra entry cannot be removed.
-		 */
-		if (abort && x86_pmu.lbr_double_abort && out > 0)
-			out--;
-
-		cpuc->lbr_entries[out].from	 = from;
-		cpuc->lbr_entries[out].to	 = to;
-		cpuc->lbr_entries[out].mispred	 = mis;
-		cpuc->lbr_entries[out].predicted = pred;
-		cpuc->lbr_entries[out].in_tx	 = in_tx;
-		cpuc->lbr_entries[out].abort	 = abort;
-		cpuc->lbr_entries[out].cycles	 = cycles;
-		cpuc->lbr_entries[out].reserved	 = 0;
-		out++;
-	}
-	cpuc->lbr_stack.nr = out;
-}
-
-void intel_pmu_lbr_read(void)
-{
-	struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
-
-	if (!cpuc->lbr_users)
-		return;
-
-	if (x86_pmu.intel_cap.lbr_format == LBR_FORMAT_32)
-		intel_pmu_lbr_read_32(cpuc);
-	else
-		intel_pmu_lbr_read_64(cpuc);
-
-	intel_pmu_lbr_filter(cpuc);
-}
-
-/*
- * SW filter is used:
- * - in case there is no HW filter
- * - in case the HW filter has errata or limitations
- */
-static int intel_pmu_setup_sw_lbr_filter(struct perf_event *event)
-{
-	u64 br_type = event->attr.branch_sample_type;
-	int mask = 0;
-
-	if (br_type & PERF_SAMPLE_BRANCH_USER)
-		mask |= X86_BR_USER;
-
-	if (br_type & PERF_SAMPLE_BRANCH_KERNEL)
-		mask |= X86_BR_KERNEL;
-
-	/* we ignore BRANCH_HV here */
-
-	if (br_type & PERF_SAMPLE_BRANCH_ANY)
-		mask |= X86_BR_ANY;
-
-	if (br_type & PERF_SAMPLE_BRANCH_ANY_CALL)
-		mask |= X86_BR_ANY_CALL;
-
-	if (br_type & PERF_SAMPLE_BRANCH_ANY_RETURN)
-		mask |= X86_BR_RET | X86_BR_IRET | X86_BR_SYSRET;
-
-	if (br_type & PERF_SAMPLE_BRANCH_IND_CALL)
-		mask |= X86_BR_IND_CALL;
-
-	if (br_type & PERF_SAMPLE_BRANCH_ABORT_TX)
-		mask |= X86_BR_ABORT;
-
-	if (br_type & PERF_SAMPLE_BRANCH_IN_TX)
-		mask |= X86_BR_IN_TX;
-
-	if (br_type & PERF_SAMPLE_BRANCH_NO_TX)
-		mask |= X86_BR_NO_TX;
-
-	if (br_type & PERF_SAMPLE_BRANCH_COND)
-		mask |= X86_BR_JCC;
-
-	if (br_type & PERF_SAMPLE_BRANCH_CALL_STACK) {
-		if (!x86_pmu_has_lbr_callstack())
-			return -EOPNOTSUPP;
-		if (mask & ~(X86_BR_USER | X86_BR_KERNEL))
-			return -EINVAL;
-		mask |= X86_BR_CALL | X86_BR_IND_CALL | X86_BR_RET |
-			X86_BR_CALL_STACK;
-	}
-
-	if (br_type & PERF_SAMPLE_BRANCH_IND_JUMP)
-		mask |= X86_BR_IND_JMP;
-
-	if (br_type & PERF_SAMPLE_BRANCH_CALL)
-		mask |= X86_BR_CALL | X86_BR_ZERO_CALL;
-	/*
-	 * stash actual user request into reg, it may
-	 * be used by fixup code for some CPU
-	 */
-	event->hw.branch_reg.reg = mask;
-	return 0;
-}
-
-/*
- * setup the HW LBR filter
- * Used only when available, may not be enough to disambiguate
- * all branches, may need the help of the SW filter
- */
-static int intel_pmu_setup_hw_lbr_filter(struct perf_event *event)
-{
-	struct hw_perf_event_extra *reg;
-	u64 br_type = event->attr.branch_sample_type;
-	u64 mask = 0, v;
-	int i;
-
-	for (i = 0; i < PERF_SAMPLE_BRANCH_MAX_SHIFT; i++) {
-		if (!(br_type & (1ULL << i)))
-			continue;
-
-		v = x86_pmu.lbr_sel_map[i];
-		if (v == LBR_NOT_SUPP)
-			return -EOPNOTSUPP;
-
-		if (v != LBR_IGN)
-			mask |= v;
-	}
-	reg = &event->hw.branch_reg;
-	reg->idx = EXTRA_REG_LBR;
-
-	/*
-	 * The first 9 bits (LBR_SEL_MASK) in LBR_SELECT operate
-	 * in suppress mode. So LBR_SELECT should be set to
-	 * (~mask & LBR_SEL_MASK) | (mask & ~LBR_SEL_MASK)
-	 */
-	reg->config = mask ^ x86_pmu.lbr_sel_mask;
-
-	return 0;
-}
-
-int intel_pmu_setup_lbr_filter(struct perf_event *event)
-{
-	int ret = 0;
-
-	/*
-	 * no LBR on this PMU
-	 */
-	if (!x86_pmu.lbr_nr)
-		return -EOPNOTSUPP;
-
-	/*
-	 * setup SW LBR filter
-	 */
-	ret = intel_pmu_setup_sw_lbr_filter(event);
-	if (ret)
-		return ret;
-
-	/*
-	 * setup HW LBR filter, if any
-	 */
-	if (x86_pmu.lbr_sel_map)
-		ret = intel_pmu_setup_hw_lbr_filter(event);
-
-	return ret;
-}
-
-/*
- * return the type of control flow change at address "from"
- * intruction is not necessarily a branch (in case of interrupt).
- *
- * The branch type returned also includes the priv level of the
- * target of the control flow change (X86_BR_USER, X86_BR_KERNEL).
- *
- * If a branch type is unknown OR the instruction cannot be
- * decoded (e.g., text page not present), then X86_BR_NONE is
- * returned.
- */
-static int branch_type(unsigned long from, unsigned long to, int abort)
-{
-	struct insn insn;
-	void *addr;
-	int bytes_read, bytes_left;
-	int ret = X86_BR_NONE;
-	int ext, to_plm, from_plm;
-	u8 buf[MAX_INSN_SIZE];
-	int is64 = 0;
-
-	to_plm = kernel_ip(to) ? X86_BR_KERNEL : X86_BR_USER;
-	from_plm = kernel_ip(from) ? X86_BR_KERNEL : X86_BR_USER;
-
-	/*
-	 * maybe zero if lbr did not fill up after a reset by the time
-	 * we get a PMU interrupt
-	 */
-	if (from == 0 || to == 0)
-		return X86_BR_NONE;
-
-	if (abort)
-		return X86_BR_ABORT | to_plm;
-
-	if (from_plm == X86_BR_USER) {
-		/*
-		 * can happen if measuring at the user level only
-		 * and we interrupt in a kernel thread, e.g., idle.
-		 */
-		if (!current->mm)
-			return X86_BR_NONE;
-
-		/* may fail if text not present */
-		bytes_left = copy_from_user_nmi(buf, (void __user *)from,
-						MAX_INSN_SIZE);
-		bytes_read = MAX_INSN_SIZE - bytes_left;
-		if (!bytes_read)
-			return X86_BR_NONE;
-
-		addr = buf;
-	} else {
-		/*
-		 * The LBR logs any address in the IP, even if the IP just
-		 * faulted. This means userspace can control the from address.
-		 * Ensure we don't blindy read any address by validating it is
-		 * a known text address.
-		 */
-		if (kernel_text_address(from)) {
-			addr = (void *)from;
-			/*
-			 * Assume we can get the maximum possible size
-			 * when grabbing kernel data.  This is not
-			 * _strictly_ true since we could possibly be
-			 * executing up next to a memory hole, but
-			 * it is very unlikely to be a problem.
-			 */
-			bytes_read = MAX_INSN_SIZE;
-		} else {
-			return X86_BR_NONE;
-		}
-	}
-
-	/*
-	 * decoder needs to know the ABI especially
-	 * on 64-bit systems running 32-bit apps
-	 */
-#ifdef CONFIG_X86_64
-	is64 = kernel_ip((unsigned long)addr) || !test_thread_flag(TIF_IA32);
-#endif
-	insn_init(&insn, addr, bytes_read, is64);
-	insn_get_opcode(&insn);
-	if (!insn.opcode.got)
-		return X86_BR_ABORT;
-
-	switch (insn.opcode.bytes[0]) {
-	case 0xf:
-		switch (insn.opcode.bytes[1]) {
-		case 0x05: /* syscall */
-		case 0x34: /* sysenter */
-			ret = X86_BR_SYSCALL;
-			break;
-		case 0x07: /* sysret */
-		case 0x35: /* sysexit */
-			ret = X86_BR_SYSRET;
-			break;
-		case 0x80 ... 0x8f: /* conditional */
-			ret = X86_BR_JCC;
-			break;
-		default:
-			ret = X86_BR_NONE;
-		}
-		break;
-	case 0x70 ... 0x7f: /* conditional */
-		ret = X86_BR_JCC;
-		break;
-	case 0xc2: /* near ret */
-	case 0xc3: /* near ret */
-	case 0xca: /* far ret */
-	case 0xcb: /* far ret */
-		ret = X86_BR_RET;
-		break;
-	case 0xcf: /* iret */
-		ret = X86_BR_IRET;
-		break;
-	case 0xcc ... 0xce: /* int */
-		ret = X86_BR_INT;
-		break;
-	case 0xe8: /* call near rel */
-		insn_get_immediate(&insn);
-		if (insn.immediate1.value == 0) {
-			/* zero length call */
-			ret = X86_BR_ZERO_CALL;
-			break;
-		}
-	case 0x9a: /* call far absolute */
-		ret = X86_BR_CALL;
-		break;
-	case 0xe0 ... 0xe3: /* loop jmp */
-		ret = X86_BR_JCC;
-		break;
-	case 0xe9 ... 0xeb: /* jmp */
-		ret = X86_BR_JMP;
-		break;
-	case 0xff: /* call near absolute, call far absolute ind */
-		insn_get_modrm(&insn);
-		ext = (insn.modrm.bytes[0] >> 3) & 0x7;
-		switch (ext) {
-		case 2: /* near ind call */
-		case 3: /* far ind call */
-			ret = X86_BR_IND_CALL;
-			break;
-		case 4:
-		case 5:
-			ret = X86_BR_IND_JMP;
-			break;
-		}
-		break;
-	default:
-		ret = X86_BR_NONE;
-	}
-	/*
-	 * interrupts, traps, faults (and thus ring transition) may
-	 * occur on any instructions. Thus, to classify them correctly,
-	 * we need to first look at the from and to priv levels. If they
-	 * are different and to is in the kernel, then it indicates
-	 * a ring transition. If the from instruction is not a ring
-	 * transition instr (syscall, systenter, int), then it means
-	 * it was a irq, trap or fault.
-	 *
-	 * we have no way of detecting kernel to kernel faults.
-	 */
-	if (from_plm == X86_BR_USER && to_plm == X86_BR_KERNEL
-	    && ret != X86_BR_SYSCALL && ret != X86_BR_INT)
-		ret = X86_BR_IRQ;
-
-	/*
-	 * branch priv level determined by target as
-	 * is done by HW when LBR_SELECT is implemented
-	 */
-	if (ret != X86_BR_NONE)
-		ret |= to_plm;
-
-	return ret;
-}
-
-/*
- * implement actual branch filter based on user demand.
- * Hardware may not exactly satisfy that request, thus
- * we need to inspect opcodes. Mismatched branches are
- * discarded. Therefore, the number of branches returned
- * in PERF_SAMPLE_BRANCH_STACK sample may vary.
- */
-static void
-intel_pmu_lbr_filter(struct cpu_hw_events *cpuc)
-{
-	u64 from, to;
-	int br_sel = cpuc->br_sel;
-	int i, j, type;
-	bool compress = false;
-
-	/* if sampling all branches, then nothing to filter */
-	if ((br_sel & X86_BR_ALL) == X86_BR_ALL)
-		return;
-
-	for (i = 0; i < cpuc->lbr_stack.nr; i++) {
-
-		from = cpuc->lbr_entries[i].from;
-		to = cpuc->lbr_entries[i].to;
-
-		type = branch_type(from, to, cpuc->lbr_entries[i].abort);
-		if (type != X86_BR_NONE && (br_sel & X86_BR_ANYTX)) {
-			if (cpuc->lbr_entries[i].in_tx)
-				type |= X86_BR_IN_TX;
-			else
-				type |= X86_BR_NO_TX;
-		}
-
-		/* if type does not correspond, then discard */
-		if (type == X86_BR_NONE || (br_sel & type) != type) {
-			cpuc->lbr_entries[i].from = 0;
-			compress = true;
-		}
-	}
-
-	if (!compress)
-		return;
-
-	/* remove all entries with from=0 */
-	for (i = 0; i < cpuc->lbr_stack.nr; ) {
-		if (!cpuc->lbr_entries[i].from) {
-			j = i;
-			while (++j < cpuc->lbr_stack.nr)
-				cpuc->lbr_entries[j-1] = cpuc->lbr_entries[j];
-			cpuc->lbr_stack.nr--;
-			if (!cpuc->lbr_entries[i].from)
-				continue;
-		}
-		i++;
-	}
-}
-
-/*
- * Map interface branch filters onto LBR filters
- */
-static const int nhm_lbr_sel_map[PERF_SAMPLE_BRANCH_MAX_SHIFT] = {
-	[PERF_SAMPLE_BRANCH_ANY_SHIFT]		= LBR_ANY,
-	[PERF_SAMPLE_BRANCH_USER_SHIFT]		= LBR_USER,
-	[PERF_SAMPLE_BRANCH_KERNEL_SHIFT]	= LBR_KERNEL,
-	[PERF_SAMPLE_BRANCH_HV_SHIFT]		= LBR_IGN,
-	[PERF_SAMPLE_BRANCH_ANY_RETURN_SHIFT]	= LBR_RETURN | LBR_REL_JMP
-						| LBR_IND_JMP | LBR_FAR,
-	/*
-	 * NHM/WSM erratum: must include REL_JMP+IND_JMP to get CALL branches
-	 */
-	[PERF_SAMPLE_BRANCH_ANY_CALL_SHIFT] =
-	 LBR_REL_CALL | LBR_IND_CALL | LBR_REL_JMP | LBR_IND_JMP | LBR_FAR,
-	/*
-	 * NHM/WSM erratum: must include IND_JMP to capture IND_CALL
-	 */
-	[PERF_SAMPLE_BRANCH_IND_CALL_SHIFT] = LBR_IND_CALL | LBR_IND_JMP,
-	[PERF_SAMPLE_BRANCH_COND_SHIFT]     = LBR_JCC,
-	[PERF_SAMPLE_BRANCH_IND_JUMP_SHIFT] = LBR_IND_JMP,
-};
-
-static const int snb_lbr_sel_map[PERF_SAMPLE_BRANCH_MAX_SHIFT] = {
-	[PERF_SAMPLE_BRANCH_ANY_SHIFT]		= LBR_ANY,
-	[PERF_SAMPLE_BRANCH_USER_SHIFT]		= LBR_USER,
-	[PERF_SAMPLE_BRANCH_KERNEL_SHIFT]	= LBR_KERNEL,
-	[PERF_SAMPLE_BRANCH_HV_SHIFT]		= LBR_IGN,
-	[PERF_SAMPLE_BRANCH_ANY_RETURN_SHIFT]	= LBR_RETURN | LBR_FAR,
-	[PERF_SAMPLE_BRANCH_ANY_CALL_SHIFT]	= LBR_REL_CALL | LBR_IND_CALL
-						| LBR_FAR,
-	[PERF_SAMPLE_BRANCH_IND_CALL_SHIFT]	= LBR_IND_CALL,
-	[PERF_SAMPLE_BRANCH_COND_SHIFT]		= LBR_JCC,
-	[PERF_SAMPLE_BRANCH_IND_JUMP_SHIFT]	= LBR_IND_JMP,
-	[PERF_SAMPLE_BRANCH_CALL_SHIFT]		= LBR_REL_CALL,
-};
-
-static const int hsw_lbr_sel_map[PERF_SAMPLE_BRANCH_MAX_SHIFT] = {
-	[PERF_SAMPLE_BRANCH_ANY_SHIFT]		= LBR_ANY,
-	[PERF_SAMPLE_BRANCH_USER_SHIFT]		= LBR_USER,
-	[PERF_SAMPLE_BRANCH_KERNEL_SHIFT]	= LBR_KERNEL,
-	[PERF_SAMPLE_BRANCH_HV_SHIFT]		= LBR_IGN,
-	[PERF_SAMPLE_BRANCH_ANY_RETURN_SHIFT]	= LBR_RETURN | LBR_FAR,
-	[PERF_SAMPLE_BRANCH_ANY_CALL_SHIFT]	= LBR_REL_CALL | LBR_IND_CALL
-						| LBR_FAR,
-	[PERF_SAMPLE_BRANCH_IND_CALL_SHIFT]	= LBR_IND_CALL,
-	[PERF_SAMPLE_BRANCH_COND_SHIFT]		= LBR_JCC,
-	[PERF_SAMPLE_BRANCH_CALL_STACK_SHIFT]	= LBR_REL_CALL | LBR_IND_CALL
-						| LBR_RETURN | LBR_CALL_STACK,
-	[PERF_SAMPLE_BRANCH_IND_JUMP_SHIFT]	= LBR_IND_JMP,
-	[PERF_SAMPLE_BRANCH_CALL_SHIFT]		= LBR_REL_CALL,
-};
-
-/* core */
-void __init intel_pmu_lbr_init_core(void)
-{
-	x86_pmu.lbr_nr     = 4;
-	x86_pmu.lbr_tos    = MSR_LBR_TOS;
-	x86_pmu.lbr_from   = MSR_LBR_CORE_FROM;
-	x86_pmu.lbr_to     = MSR_LBR_CORE_TO;
-
-	/*
-	 * SW branch filter usage:
-	 * - compensate for lack of HW filter
-	 */
-	pr_cont("4-deep LBR, ");
-}
-
-/* nehalem/westmere */
-void __init intel_pmu_lbr_init_nhm(void)
-{
-	x86_pmu.lbr_nr     = 16;
-	x86_pmu.lbr_tos    = MSR_LBR_TOS;
-	x86_pmu.lbr_from   = MSR_LBR_NHM_FROM;
-	x86_pmu.lbr_to     = MSR_LBR_NHM_TO;
-
-	x86_pmu.lbr_sel_mask = LBR_SEL_MASK;
-	x86_pmu.lbr_sel_map  = nhm_lbr_sel_map;
-
-	/*
-	 * SW branch filter usage:
-	 * - workaround LBR_SEL errata (see above)
-	 * - support syscall, sysret capture.
-	 *   That requires LBR_FAR but that means far
-	 *   jmp need to be filtered out
-	 */
-	pr_cont("16-deep LBR, ");
-}
-
-/* sandy bridge */
-void __init intel_pmu_lbr_init_snb(void)
-{
-	x86_pmu.lbr_nr	 = 16;
-	x86_pmu.lbr_tos	 = MSR_LBR_TOS;
-	x86_pmu.lbr_from = MSR_LBR_NHM_FROM;
-	x86_pmu.lbr_to   = MSR_LBR_NHM_TO;
-
-	x86_pmu.lbr_sel_mask = LBR_SEL_MASK;
-	x86_pmu.lbr_sel_map  = snb_lbr_sel_map;
-
-	/*
-	 * SW branch filter usage:
-	 * - support syscall, sysret capture.
-	 *   That requires LBR_FAR but that means far
-	 *   jmp need to be filtered out
-	 */
-	pr_cont("16-deep LBR, ");
-}
-
-/* haswell */
-void intel_pmu_lbr_init_hsw(void)
-{
-	x86_pmu.lbr_nr	 = 16;
-	x86_pmu.lbr_tos	 = MSR_LBR_TOS;
-	x86_pmu.lbr_from = MSR_LBR_NHM_FROM;
-	x86_pmu.lbr_to   = MSR_LBR_NHM_TO;
-
-	x86_pmu.lbr_sel_mask = LBR_SEL_MASK;
-	x86_pmu.lbr_sel_map  = hsw_lbr_sel_map;
-
-	pr_cont("16-deep LBR, ");
-}
-
-/* skylake */
-__init void intel_pmu_lbr_init_skl(void)
-{
-	x86_pmu.lbr_nr	 = 32;
-	x86_pmu.lbr_tos	 = MSR_LBR_TOS;
-	x86_pmu.lbr_from = MSR_LBR_NHM_FROM;
-	x86_pmu.lbr_to   = MSR_LBR_NHM_TO;
-
-	x86_pmu.lbr_sel_mask = LBR_SEL_MASK;
-	x86_pmu.lbr_sel_map  = hsw_lbr_sel_map;
-
-	/*
-	 * SW branch filter usage:
-	 * - support syscall, sysret capture.
-	 *   That requires LBR_FAR but that means far
-	 *   jmp need to be filtered out
-	 */
-	pr_cont("32-deep LBR, ");
-}
-
-/* atom */
-void __init intel_pmu_lbr_init_atom(void)
-{
-	/*
-	 * only models starting at stepping 10 seems
-	 * to have an operational LBR which can freeze
-	 * on PMU interrupt
-	 */
-	if (boot_cpu_data.x86_model == 28
-	    && boot_cpu_data.x86_mask < 10) {
-		pr_cont("LBR disabled due to erratum");
-		return;
-	}
-
-	x86_pmu.lbr_nr	   = 8;
-	x86_pmu.lbr_tos    = MSR_LBR_TOS;
-	x86_pmu.lbr_from   = MSR_LBR_CORE_FROM;
-	x86_pmu.lbr_to     = MSR_LBR_CORE_TO;
-
-	/*
-	 * SW branch filter usage:
-	 * - compensate for lack of HW filter
-	 */
-	pr_cont("8-deep LBR, ");
-}
--- zfcpdump-kernel-4.4.orig/arch/x86/kernel/cpu/perf_event_intel_pt.c
+++ /dev/null
@@ -1,1179 +0,0 @@
-/*
- * Intel(R) Processor Trace PMU driver for perf
- * Copyright (c) 2013-2014, Intel Corporation.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * Intel PT is specified in the Intel Architecture Instruction Set Extensions
- * Programming Reference:
- * http://software.intel.com/en-us/intel-isa-extensions
- */
-
-#undef DEBUG
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/types.h>
-#include <linux/slab.h>
-#include <linux/device.h>
-
-#include <asm/perf_event.h>
-#include <asm/insn.h>
-#include <asm/io.h>
-
-#include "perf_event.h"
-#include "intel_pt.h"
-
-static DEFINE_PER_CPU(struct pt, pt_ctx);
-
-static struct pt_pmu pt_pmu;
-
-enum cpuid_regs {
-	CR_EAX = 0,
-	CR_ECX,
-	CR_EDX,
-	CR_EBX
-};
-
-/*
- * Capabilities of Intel PT hardware, such as number of address bits or
- * supported output schemes, are cached and exported to userspace as "caps"
- * attribute group of pt pmu device
- * (/sys/bus/event_source/devices/intel_pt/caps/) so that userspace can store
- * relevant bits together with intel_pt traces.
- *
- * These are necessary for both trace decoding (payloads_lip, contains address
- * width encoded in IP-related packets), and event configuration (bitmasks with
- * permitted values for certain bit fields).
- */
-#define PT_CAP(_n, _l, _r, _m)						\
-	[PT_CAP_ ## _n] = { .name = __stringify(_n), .leaf = _l,	\
-			    .reg = _r, .mask = _m }
-
-static struct pt_cap_desc {
-	const char	*name;
-	u32		leaf;
-	u8		reg;
-	u32		mask;
-} pt_caps[] = {
-	PT_CAP(max_subleaf,		0, CR_EAX, 0xffffffff),
-	PT_CAP(cr3_filtering,		0, CR_EBX, BIT(0)),
-	PT_CAP(psb_cyc,			0, CR_EBX, BIT(1)),
-	PT_CAP(mtc,			0, CR_EBX, BIT(3)),
-	PT_CAP(topa_output,		0, CR_ECX, BIT(0)),
-	PT_CAP(topa_multiple_entries,	0, CR_ECX, BIT(1)),
-	PT_CAP(single_range_output,	0, CR_ECX, BIT(2)),
-	PT_CAP(payloads_lip,		0, CR_ECX, BIT(31)),
-	PT_CAP(mtc_periods,		1, CR_EAX, 0xffff0000),
-	PT_CAP(cycle_thresholds,	1, CR_EBX, 0xffff),
-	PT_CAP(psb_periods,		1, CR_EBX, 0xffff0000),
-};
-
-static u32 pt_cap_get(enum pt_capabilities cap)
-{
-	struct pt_cap_desc *cd = &pt_caps[cap];
-	u32 c = pt_pmu.caps[cd->leaf * PT_CPUID_REGS_NUM + cd->reg];
-	unsigned int shift = __ffs(cd->mask);
-
-	return (c & cd->mask) >> shift;
-}
-
-static ssize_t pt_cap_show(struct device *cdev,
-			   struct device_attribute *attr,
-			   char *buf)
-{
-	struct dev_ext_attribute *ea =
-		container_of(attr, struct dev_ext_attribute, attr);
-	enum pt_capabilities cap = (long)ea->var;
-
-	return snprintf(buf, PAGE_SIZE, "%x\n", pt_cap_get(cap));
-}
-
-static struct attribute_group pt_cap_group = {
-	.name	= "caps",
-};
-
-PMU_FORMAT_ATTR(cyc,		"config:1"	);
-PMU_FORMAT_ATTR(mtc,		"config:9"	);
-PMU_FORMAT_ATTR(tsc,		"config:10"	);
-PMU_FORMAT_ATTR(noretcomp,	"config:11"	);
-PMU_FORMAT_ATTR(mtc_period,	"config:14-17"	);
-PMU_FORMAT_ATTR(cyc_thresh,	"config:19-22"	);
-PMU_FORMAT_ATTR(psb_period,	"config:24-27"	);
-
-static struct attribute *pt_formats_attr[] = {
-	&format_attr_cyc.attr,
-	&format_attr_mtc.attr,
-	&format_attr_tsc.attr,
-	&format_attr_noretcomp.attr,
-	&format_attr_mtc_period.attr,
-	&format_attr_cyc_thresh.attr,
-	&format_attr_psb_period.attr,
-	NULL,
-};
-
-static struct attribute_group pt_format_group = {
-	.name	= "format",
-	.attrs	= pt_formats_attr,
-};
-
-static const struct attribute_group *pt_attr_groups[] = {
-	&pt_cap_group,
-	&pt_format_group,
-	NULL,
-};
-
-static int __init pt_pmu_hw_init(void)
-{
-	struct dev_ext_attribute *de_attrs;
-	struct attribute **attrs;
-	size_t size;
-	int ret;
-	long i;
-
-	attrs = NULL;
-
-	for (i = 0; i < PT_CPUID_LEAVES; i++) {
-		cpuid_count(20, i,
-			    &pt_pmu.caps[CR_EAX + i*PT_CPUID_REGS_NUM],
-			    &pt_pmu.caps[CR_EBX + i*PT_CPUID_REGS_NUM],
-			    &pt_pmu.caps[CR_ECX + i*PT_CPUID_REGS_NUM],
-			    &pt_pmu.caps[CR_EDX + i*PT_CPUID_REGS_NUM]);
-	}
-
-	ret = -ENOMEM;
-	size = sizeof(struct attribute *) * (ARRAY_SIZE(pt_caps)+1);
-	attrs = kzalloc(size, GFP_KERNEL);
-	if (!attrs)
-		goto fail;
-
-	size = sizeof(struct dev_ext_attribute) * (ARRAY_SIZE(pt_caps)+1);
-	de_attrs = kzalloc(size, GFP_KERNEL);
-	if (!de_attrs)
-		goto fail;
-
-	for (i = 0; i < ARRAY_SIZE(pt_caps); i++) {
-		struct dev_ext_attribute *de_attr = de_attrs + i;
-
-		de_attr->attr.attr.name = pt_caps[i].name;
-
-		sysfs_attr_init(&de_attr->attr.attr);
-
-		de_attr->attr.attr.mode		= S_IRUGO;
-		de_attr->attr.show		= pt_cap_show;
-		de_attr->var			= (void *)i;
-
-		attrs[i] = &de_attr->attr.attr;
-	}
-
-	pt_cap_group.attrs = attrs;
-
-	return 0;
-
-fail:
-	kfree(attrs);
-
-	return ret;
-}
-
-#define RTIT_CTL_CYC_PSB (RTIT_CTL_CYCLEACC	| \
-			  RTIT_CTL_CYC_THRESH	| \
-			  RTIT_CTL_PSB_FREQ)
-
-#define RTIT_CTL_MTC	(RTIT_CTL_MTC_EN	| \
-			 RTIT_CTL_MTC_RANGE)
-
-#define PT_CONFIG_MASK (RTIT_CTL_TSC_EN		| \
-			RTIT_CTL_DISRETC	| \
-			RTIT_CTL_CYC_PSB	| \
-			RTIT_CTL_MTC)
-
-static bool pt_event_valid(struct perf_event *event)
-{
-	u64 config = event->attr.config;
-	u64 allowed, requested;
-
-	if ((config & PT_CONFIG_MASK) != config)
-		return false;
-
-	if (config & RTIT_CTL_CYC_PSB) {
-		if (!pt_cap_get(PT_CAP_psb_cyc))
-			return false;
-
-		allowed = pt_cap_get(PT_CAP_psb_periods);
-		requested = (config & RTIT_CTL_PSB_FREQ) >>
-			RTIT_CTL_PSB_FREQ_OFFSET;
-		if (requested && (!(allowed & BIT(requested))))
-			return false;
-
-		allowed = pt_cap_get(PT_CAP_cycle_thresholds);
-		requested = (config & RTIT_CTL_CYC_THRESH) >>
-			RTIT_CTL_CYC_THRESH_OFFSET;
-		if (requested && (!(allowed & BIT(requested))))
-			return false;
-	}
-
-	if (config & RTIT_CTL_MTC) {
-		/*
-		 * In the unlikely case that CPUID lists valid mtc periods,
-		 * but not the mtc capability, drop out here.
-		 *
-		 * Spec says that setting mtc period bits while mtc bit in
-		 * CPUID is 0 will #GP, so better safe than sorry.
-		 */
-		if (!pt_cap_get(PT_CAP_mtc))
-			return false;
-
-		allowed = pt_cap_get(PT_CAP_mtc_periods);
-		if (!allowed)
-			return false;
-
-		requested = (config & RTIT_CTL_MTC_RANGE) >>
-			RTIT_CTL_MTC_RANGE_OFFSET;
-
-		if (!(allowed & BIT(requested)))
-			return false;
-	}
-
-	return true;
-}
-
-/*
- * PT configuration helpers
- * These all are cpu affine and operate on a local PT
- */
-
-static void pt_config(struct perf_event *event)
-{
-	u64 reg;
-
-	if (!event->hw.itrace_started) {
-		event->hw.itrace_started = 1;
-		wrmsrl(MSR_IA32_RTIT_STATUS, 0);
-	}
-
-	reg = RTIT_CTL_TOPA | RTIT_CTL_BRANCH_EN | RTIT_CTL_TRACEEN;
-
-	if (!event->attr.exclude_kernel)
-		reg |= RTIT_CTL_OS;
-	if (!event->attr.exclude_user)
-		reg |= RTIT_CTL_USR;
-
-	reg |= (event->attr.config & PT_CONFIG_MASK);
-
-	wrmsrl(MSR_IA32_RTIT_CTL, reg);
-}
-
-static void pt_config_start(bool start)
-{
-	u64 ctl;
-
-	rdmsrl(MSR_IA32_RTIT_CTL, ctl);
-	if (start)
-		ctl |= RTIT_CTL_TRACEEN;
-	else
-		ctl &= ~RTIT_CTL_TRACEEN;
-	wrmsrl(MSR_IA32_RTIT_CTL, ctl);
-
-	/*
-	 * A wrmsr that disables trace generation serializes other PT
-	 * registers and causes all data packets to be written to memory,
-	 * but a fence is required for the data to become globally visible.
-	 *
-	 * The below WMB, separating data store and aux_head store matches
-	 * the consumer's RMB that separates aux_head load and data load.
-	 */
-	if (!start)
-		wmb();
-}
-
-static void pt_config_buffer(void *buf, unsigned int topa_idx,
-			     unsigned int output_off)
-{
-	u64 reg;
-
-	wrmsrl(MSR_IA32_RTIT_OUTPUT_BASE, virt_to_phys(buf));
-
-	reg = 0x7f | ((u64)topa_idx << 7) | ((u64)output_off << 32);
-
-	wrmsrl(MSR_IA32_RTIT_OUTPUT_MASK, reg);
-}
-
-/*
- * Keep ToPA table-related metadata on the same page as the actual table,
- * taking up a few words from the top
- */
-
-#define TENTS_PER_PAGE (((PAGE_SIZE - 40) / sizeof(struct topa_entry)) - 1)
-
-/**
- * struct topa - page-sized ToPA table with metadata at the top
- * @table:	actual ToPA table entries, as understood by PT hardware
- * @list:	linkage to struct pt_buffer's list of tables
- * @phys:	physical address of this page
- * @offset:	offset of the first entry in this table in the buffer
- * @size:	total size of all entries in this table
- * @last:	index of the last initialized entry in this table
- */
-struct topa {
-	struct topa_entry	table[TENTS_PER_PAGE];
-	struct list_head	list;
-	u64			phys;
-	u64			offset;
-	size_t			size;
-	int			last;
-};
-
-/* make -1 stand for the last table entry */
-#define TOPA_ENTRY(t, i) ((i) == -1 ? &(t)->table[(t)->last] : &(t)->table[(i)])
-
-/**
- * topa_alloc() - allocate page-sized ToPA table
- * @cpu:	CPU on which to allocate.
- * @gfp:	Allocation flags.
- *
- * Return:	On success, return the pointer to ToPA table page.
- */
-static struct topa *topa_alloc(int cpu, gfp_t gfp)
-{
-	int node = cpu_to_node(cpu);
-	struct topa *topa;
-	struct page *p;
-
-	p = alloc_pages_node(node, gfp | __GFP_ZERO, 0);
-	if (!p)
-		return NULL;
-
-	topa = page_address(p);
-	topa->last = 0;
-	topa->phys = page_to_phys(p);
-
-	/*
-	 * In case of singe-entry ToPA, always put the self-referencing END
-	 * link as the 2nd entry in the table
-	 */
-	if (!pt_cap_get(PT_CAP_topa_multiple_entries)) {
-		TOPA_ENTRY(topa, 1)->base = topa->phys >> TOPA_SHIFT;
-		TOPA_ENTRY(topa, 1)->end = 1;
-	}
-
-	return topa;
-}
-
-/**
- * topa_free() - free a page-sized ToPA table
- * @topa:	Table to deallocate.
- */
-static void topa_free(struct topa *topa)
-{
-	free_page((unsigned long)topa);
-}
-
-/**
- * topa_insert_table() - insert a ToPA table into a buffer
- * @buf:	 PT buffer that's being extended.
- * @topa:	 New topa table to be inserted.
- *
- * If it's the first table in this buffer, set up buffer's pointers
- * accordingly; otherwise, add a END=1 link entry to @topa to the current
- * "last" table and adjust the last table pointer to @topa.
- */
-static void topa_insert_table(struct pt_buffer *buf, struct topa *topa)
-{
-	struct topa *last = buf->last;
-
-	list_add_tail(&topa->list, &buf->tables);
-
-	if (!buf->first) {
-		buf->first = buf->last = buf->cur = topa;
-		return;
-	}
-
-	topa->offset = last->offset + last->size;
-	buf->last = topa;
-
-	if (!pt_cap_get(PT_CAP_topa_multiple_entries))
-		return;
-
-	BUG_ON(last->last != TENTS_PER_PAGE - 1);
-
-	TOPA_ENTRY(last, -1)->base = topa->phys >> TOPA_SHIFT;
-	TOPA_ENTRY(last, -1)->end = 1;
-}
-
-/**
- * topa_table_full() - check if a ToPA table is filled up
- * @topa:	ToPA table.
- */
-static bool topa_table_full(struct topa *topa)
-{
-	/* single-entry ToPA is a special case */
-	if (!pt_cap_get(PT_CAP_topa_multiple_entries))
-		return !!topa->last;
-
-	return topa->last == TENTS_PER_PAGE - 1;
-}
-
-/**
- * topa_insert_pages() - create a list of ToPA tables
- * @buf:	PT buffer being initialized.
- * @gfp:	Allocation flags.
- *
- * This initializes a list of ToPA tables with entries from
- * the data_pages provided by rb_alloc_aux().
- *
- * Return:	0 on success or error code.
- */
-static int topa_insert_pages(struct pt_buffer *buf, gfp_t gfp)
-{
-	struct topa *topa = buf->last;
-	int order = 0;
-	struct page *p;
-
-	p = virt_to_page(buf->data_pages[buf->nr_pages]);
-	if (PagePrivate(p))
-		order = page_private(p);
-
-	if (topa_table_full(topa)) {
-		topa = topa_alloc(buf->cpu, gfp);
-		if (!topa)
-			return -ENOMEM;
-
-		topa_insert_table(buf, topa);
-	}
-
-	TOPA_ENTRY(topa, -1)->base = page_to_phys(p) >> TOPA_SHIFT;
-	TOPA_ENTRY(topa, -1)->size = order;
-	if (!buf->snapshot && !pt_cap_get(PT_CAP_topa_multiple_entries)) {
-		TOPA_ENTRY(topa, -1)->intr = 1;
-		TOPA_ENTRY(topa, -1)->stop = 1;
-	}
-
-	topa->last++;
-	topa->size += sizes(order);
-
-	buf->nr_pages += 1ul << order;
-
-	return 0;
-}
-
-/**
- * pt_topa_dump() - print ToPA tables and their entries
- * @buf:	PT buffer.
- */
-static void pt_topa_dump(struct pt_buffer *buf)
-{
-	struct topa *topa;
-
-	list_for_each_entry(topa, &buf->tables, list) {
-		int i;
-
-		pr_debug("# table @%p (%016Lx), off %llx size %zx\n", topa->table,
-			 topa->phys, topa->offset, topa->size);
-		for (i = 0; i < TENTS_PER_PAGE; i++) {
-			pr_debug("# entry @%p (%lx sz %u %c%c%c) raw=%16llx\n",
-				 &topa->table[i],
-				 (unsigned long)topa->table[i].base << TOPA_SHIFT,
-				 sizes(topa->table[i].size),
-				 topa->table[i].end ?  'E' : ' ',
-				 topa->table[i].intr ? 'I' : ' ',
-				 topa->table[i].stop ? 'S' : ' ',
-				 *(u64 *)&topa->table[i]);
-			if ((pt_cap_get(PT_CAP_topa_multiple_entries) &&
-			     topa->table[i].stop) ||
-			    topa->table[i].end)
-				break;
-		}
-	}
-}
-
-/**
- * pt_buffer_advance() - advance to the next output region
- * @buf:	PT buffer.
- *
- * Advance the current pointers in the buffer to the next ToPA entry.
- */
-static void pt_buffer_advance(struct pt_buffer *buf)
-{
-	buf->output_off = 0;
-	buf->cur_idx++;
-
-	if (buf->cur_idx == buf->cur->last) {
-		if (buf->cur == buf->last)
-			buf->cur = buf->first;
-		else
-			buf->cur = list_entry(buf->cur->list.next, struct topa,
-					      list);
-		buf->cur_idx = 0;
-	}
-}
-
-/**
- * pt_update_head() - calculate current offsets and sizes
- * @pt:		Per-cpu pt context.
- *
- * Update buffer's current write pointer position and data size.
- */
-static void pt_update_head(struct pt *pt)
-{
-	struct pt_buffer *buf = perf_get_aux(&pt->handle);
-	u64 topa_idx, base, old;
-
-	/* offset of the first region in this table from the beginning of buf */
-	base = buf->cur->offset + buf->output_off;
-
-	/* offset of the current output region within this table */
-	for (topa_idx = 0; topa_idx < buf->cur_idx; topa_idx++)
-		base += sizes(buf->cur->table[topa_idx].size);
-
-	if (buf->snapshot) {
-		local_set(&buf->data_size, base);
-	} else {
-		old = (local64_xchg(&buf->head, base) &
-		       ((buf->nr_pages << PAGE_SHIFT) - 1));
-		if (base < old)
-			base += buf->nr_pages << PAGE_SHIFT;
-
-		local_add(base - old, &buf->data_size);
-	}
-}
-
-/**
- * pt_buffer_region() - obtain current output region's address
- * @buf:	PT buffer.
- */
-static void *pt_buffer_region(struct pt_buffer *buf)
-{
-	return phys_to_virt(buf->cur->table[buf->cur_idx].base << TOPA_SHIFT);
-}
-
-/**
- * pt_buffer_region_size() - obtain current output region's size
- * @buf:	PT buffer.
- */
-static size_t pt_buffer_region_size(struct pt_buffer *buf)
-{
-	return sizes(buf->cur->table[buf->cur_idx].size);
-}
-
-/**
- * pt_handle_status() - take care of possible status conditions
- * @pt:		Per-cpu pt context.
- */
-static void pt_handle_status(struct pt *pt)
-{
-	struct pt_buffer *buf = perf_get_aux(&pt->handle);
-	int advance = 0;
-	u64 status;
-
-	rdmsrl(MSR_IA32_RTIT_STATUS, status);
-
-	if (status & RTIT_STATUS_ERROR) {
-		pr_err_ratelimited("ToPA ERROR encountered, trying to recover\n");
-		pt_topa_dump(buf);
-		status &= ~RTIT_STATUS_ERROR;
-	}
-
-	if (status & RTIT_STATUS_STOPPED) {
-		status &= ~RTIT_STATUS_STOPPED;
-
-		/*
-		 * On systems that only do single-entry ToPA, hitting STOP
-		 * means we are already losing data; need to let the decoder
-		 * know.
-		 */
-		if (!pt_cap_get(PT_CAP_topa_multiple_entries) ||
-		    buf->output_off == sizes(TOPA_ENTRY(buf->cur, buf->cur_idx)->size)) {
-			local_inc(&buf->lost);
-			advance++;
-		}
-	}
-
-	/*
-	 * Also on single-entry ToPA implementations, interrupt will come
-	 * before the output reaches its output region's boundary.
-	 */
-	if (!pt_cap_get(PT_CAP_topa_multiple_entries) && !buf->snapshot &&
-	    pt_buffer_region_size(buf) - buf->output_off <= TOPA_PMI_MARGIN) {
-		void *head = pt_buffer_region(buf);
-
-		/* everything within this margin needs to be zeroed out */
-		memset(head + buf->output_off, 0,
-		       pt_buffer_region_size(buf) -
-		       buf->output_off);
-		advance++;
-	}
-
-	if (advance)
-		pt_buffer_advance(buf);
-
-	wrmsrl(MSR_IA32_RTIT_STATUS, status);
-}
-
-/**
- * pt_read_offset() - translate registers into buffer pointers
- * @buf:	PT buffer.
- *
- * Set buffer's output pointers from MSR values.
- */
-static void pt_read_offset(struct pt_buffer *buf)
-{
-	u64 offset, base_topa;
-
-	rdmsrl(MSR_IA32_RTIT_OUTPUT_BASE, base_topa);
-	buf->cur = phys_to_virt(base_topa);
-
-	rdmsrl(MSR_IA32_RTIT_OUTPUT_MASK, offset);
-	/* offset within current output region */
-	buf->output_off = offset >> 32;
-	/* index of current output region within this table */
-	buf->cur_idx = (offset & 0xffffff80) >> 7;
-}
-
-/**
- * pt_topa_next_entry() - obtain index of the first page in the next ToPA entry
- * @buf:	PT buffer.
- * @pg:		Page offset in the buffer.
- *
- * When advancing to the next output region (ToPA entry), given a page offset
- * into the buffer, we need to find the offset of the first page in the next
- * region.
- */
-static unsigned int pt_topa_next_entry(struct pt_buffer *buf, unsigned int pg)
-{
-	struct topa_entry *te = buf->topa_index[pg];
-
-	/* one region */
-	if (buf->first == buf->last && buf->first->last == 1)
-		return pg;
-
-	do {
-		pg++;
-		pg &= buf->nr_pages - 1;
-	} while (buf->topa_index[pg] == te);
-
-	return pg;
-}
-
-/**
- * pt_buffer_reset_markers() - place interrupt and stop bits in the buffer
- * @buf:	PT buffer.
- * @handle:	Current output handle.
- *
- * Place INT and STOP marks to prevent overwriting old data that the consumer
- * hasn't yet collected and waking up the consumer after a certain fraction of
- * the buffer has filled up. Only needed and sensible for non-snapshot counters.
- *
- * This obviously relies on buf::head to figure out buffer markers, so it has
- * to be called after pt_buffer_reset_offsets() and before the hardware tracing
- * is enabled.
- */
-static int pt_buffer_reset_markers(struct pt_buffer *buf,
-				   struct perf_output_handle *handle)
-
-{
-	unsigned long head = local64_read(&buf->head);
-	unsigned long idx, npages, wakeup;
-
-	/* can't stop in the middle of an output region */
-	if (buf->output_off + handle->size + 1 <
-	    sizes(TOPA_ENTRY(buf->cur, buf->cur_idx)->size))
-		return -EINVAL;
-
-
-	/* single entry ToPA is handled by marking all regions STOP=1 INT=1 */
-	if (!pt_cap_get(PT_CAP_topa_multiple_entries))
-		return 0;
-
-	/* clear STOP and INT from current entry */
-	buf->topa_index[buf->stop_pos]->stop = 0;
-	buf->topa_index[buf->intr_pos]->intr = 0;
-
-	/* how many pages till the STOP marker */
-	npages = handle->size >> PAGE_SHIFT;
-
-	/* if it's on a page boundary, fill up one more page */
-	if (!offset_in_page(head + handle->size + 1))
-		npages++;
-
-	idx = (head >> PAGE_SHIFT) + npages;
-	idx &= buf->nr_pages - 1;
-	buf->stop_pos = idx;
-
-	wakeup = handle->wakeup >> PAGE_SHIFT;
-
-	/* in the worst case, wake up the consumer one page before hard stop */
-	idx = (head >> PAGE_SHIFT) + npages - 1;
-	if (idx > wakeup)
-		idx = wakeup;
-
-	idx &= buf->nr_pages - 1;
-	buf->intr_pos = idx;
-
-	buf->topa_index[buf->stop_pos]->stop = 1;
-	buf->topa_index[buf->intr_pos]->intr = 1;
-
-	return 0;
-}
-
-/**
- * pt_buffer_setup_topa_index() - build topa_index[] table of regions
- * @buf:	PT buffer.
- *
- * topa_index[] references output regions indexed by offset into the
- * buffer for purposes of quick reverse lookup.
- */
-static void pt_buffer_setup_topa_index(struct pt_buffer *buf)
-{
-	struct topa *cur = buf->first, *prev = buf->last;
-	struct topa_entry *te_cur = TOPA_ENTRY(cur, 0),
-		*te_prev = TOPA_ENTRY(prev, prev->last - 1);
-	int pg = 0, idx = 0;
-
-	while (pg < buf->nr_pages) {
-		int tidx;
-
-		/* pages within one topa entry */
-		for (tidx = 0; tidx < 1 << te_cur->size; tidx++, pg++)
-			buf->topa_index[pg] = te_prev;
-
-		te_prev = te_cur;
-
-		if (idx == cur->last - 1) {
-			/* advance to next topa table */
-			idx = 0;
-			cur = list_entry(cur->list.next, struct topa, list);
-		} else {
-			idx++;
-		}
-		te_cur = TOPA_ENTRY(cur, idx);
-	}
-
-}
-
-/**
- * pt_buffer_reset_offsets() - adjust buffer's write pointers from aux_head
- * @buf:	PT buffer.
- * @head:	Write pointer (aux_head) from AUX buffer.
- *
- * Find the ToPA table and entry corresponding to given @head and set buffer's
- * "current" pointers accordingly. This is done after we have obtained the
- * current aux_head position from a successful call to perf_aux_output_begin()
- * to make sure the hardware is writing to the right place.
- *
- * This function modifies buf::{cur,cur_idx,output_off} that will be programmed
- * into PT msrs when the tracing is enabled and buf::head and buf::data_size,
- * which are used to determine INT and STOP markers' locations by a subsequent
- * call to pt_buffer_reset_markers().
- */
-static void pt_buffer_reset_offsets(struct pt_buffer *buf, unsigned long head)
-{
-	int pg;
-
-	if (buf->snapshot)
-		head &= (buf->nr_pages << PAGE_SHIFT) - 1;
-
-	pg = (head >> PAGE_SHIFT) & (buf->nr_pages - 1);
-	pg = pt_topa_next_entry(buf, pg);
-
-	buf->cur = (struct topa *)((unsigned long)buf->topa_index[pg] & PAGE_MASK);
-	buf->cur_idx = ((unsigned long)buf->topa_index[pg] -
-			(unsigned long)buf->cur) / sizeof(struct topa_entry);
-	buf->output_off = head & (sizes(buf->cur->table[buf->cur_idx].size) - 1);
-
-	local64_set(&buf->head, head);
-	local_set(&buf->data_size, 0);
-}
-
-/**
- * pt_buffer_fini_topa() - deallocate ToPA structure of a buffer
- * @buf:	PT buffer.
- */
-static void pt_buffer_fini_topa(struct pt_buffer *buf)
-{
-	struct topa *topa, *iter;
-
-	list_for_each_entry_safe(topa, iter, &buf->tables, list) {
-		/*
-		 * right now, this is in free_aux() path only, so
-		 * no need to unlink this table from the list
-		 */
-		topa_free(topa);
-	}
-}
-
-/**
- * pt_buffer_init_topa() - initialize ToPA table for pt buffer
- * @buf:	PT buffer.
- * @size:	Total size of all regions within this ToPA.
- * @gfp:	Allocation flags.
- */
-static int pt_buffer_init_topa(struct pt_buffer *buf, unsigned long nr_pages,
-			       gfp_t gfp)
-{
-	struct topa *topa;
-	int err;
-
-	topa = topa_alloc(buf->cpu, gfp);
-	if (!topa)
-		return -ENOMEM;
-
-	topa_insert_table(buf, topa);
-
-	while (buf->nr_pages < nr_pages) {
-		err = topa_insert_pages(buf, gfp);
-		if (err) {
-			pt_buffer_fini_topa(buf);
-			return -ENOMEM;
-		}
-	}
-
-	pt_buffer_setup_topa_index(buf);
-
-	/* link last table to the first one, unless we're double buffering */
-	if (pt_cap_get(PT_CAP_topa_multiple_entries)) {
-		TOPA_ENTRY(buf->last, -1)->base = buf->first->phys >> TOPA_SHIFT;
-		TOPA_ENTRY(buf->last, -1)->end = 1;
-	}
-
-	pt_topa_dump(buf);
-	return 0;
-}
-
-/**
- * pt_buffer_setup_aux() - set up topa tables for a PT buffer
- * @cpu:	Cpu on which to allocate, -1 means current.
- * @pages:	Array of pointers to buffer pages passed from perf core.
- * @nr_pages:	Number of pages in the buffer.
- * @snapshot:	If this is a snapshot/overwrite counter.
- *
- * This is a pmu::setup_aux callback that sets up ToPA tables and all the
- * bookkeeping for an AUX buffer.
- *
- * Return:	Our private PT buffer structure.
- */
-static void *
-pt_buffer_setup_aux(int cpu, void **pages, int nr_pages, bool snapshot)
-{
-	struct pt_buffer *buf;
-	int node, ret;
-
-	if (!nr_pages)
-		return NULL;
-
-	if (cpu == -1)
-		cpu = raw_smp_processor_id();
-	node = cpu_to_node(cpu);
-
-	buf = kzalloc_node(offsetof(struct pt_buffer, topa_index[nr_pages]),
-			   GFP_KERNEL, node);
-	if (!buf)
-		return NULL;
-
-	buf->cpu = cpu;
-	buf->snapshot = snapshot;
-	buf->data_pages = pages;
-
-	INIT_LIST_HEAD(&buf->tables);
-
-	ret = pt_buffer_init_topa(buf, nr_pages, GFP_KERNEL);
-	if (ret) {
-		kfree(buf);
-		return NULL;
-	}
-
-	return buf;
-}
-
-/**
- * pt_buffer_free_aux() - perf AUX deallocation path callback
- * @data:	PT buffer.
- */
-static void pt_buffer_free_aux(void *data)
-{
-	struct pt_buffer *buf = data;
-
-	pt_buffer_fini_topa(buf);
-	kfree(buf);
-}
-
-/**
- * pt_buffer_is_full() - check if the buffer is full
- * @buf:	PT buffer.
- * @pt:		Per-cpu pt handle.
- *
- * If the user hasn't read data from the output region that aux_head
- * points to, the buffer is considered full: the user needs to read at
- * least this region and update aux_tail to point past it.
- */
-static bool pt_buffer_is_full(struct pt_buffer *buf, struct pt *pt)
-{
-	if (buf->snapshot)
-		return false;
-
-	if (local_read(&buf->data_size) >= pt->handle.size)
-		return true;
-
-	return false;
-}
-
-/**
- * intel_pt_interrupt() - PT PMI handler
- */
-void intel_pt_interrupt(void)
-{
-	struct pt *pt = this_cpu_ptr(&pt_ctx);
-	struct pt_buffer *buf;
-	struct perf_event *event = pt->handle.event;
-
-	/*
-	 * There may be a dangling PT bit in the interrupt status register
-	 * after PT has been disabled by pt_event_stop(). Make sure we don't
-	 * do anything (particularly, re-enable) for this event here.
-	 */
-	if (!ACCESS_ONCE(pt->handle_nmi))
-		return;
-
-	pt_config_start(false);
-
-	if (!event)
-		return;
-
-	buf = perf_get_aux(&pt->handle);
-	if (!buf)
-		return;
-
-	pt_read_offset(buf);
-
-	pt_handle_status(pt);
-
-	pt_update_head(pt);
-
-	perf_aux_output_end(&pt->handle, local_xchg(&buf->data_size, 0),
-			    local_xchg(&buf->lost, 0));
-
-	if (!event->hw.state) {
-		int ret;
-
-		buf = perf_aux_output_begin(&pt->handle, event);
-		if (!buf) {
-			event->hw.state = PERF_HES_STOPPED;
-			return;
-		}
-
-		pt_buffer_reset_offsets(buf, pt->handle.head);
-		/* snapshot counters don't use PMI, so it's safe */
-		ret = pt_buffer_reset_markers(buf, &pt->handle);
-		if (ret) {
-			perf_aux_output_end(&pt->handle, 0, true);
-			return;
-		}
-
-		pt_config_buffer(buf->cur->table, buf->cur_idx,
-				 buf->output_off);
-		pt_config(event);
-	}
-}
-
-/*
- * PMU callbacks
- */
-
-static void pt_event_start(struct perf_event *event, int mode)
-{
-	struct pt *pt = this_cpu_ptr(&pt_ctx);
-	struct pt_buffer *buf = perf_get_aux(&pt->handle);
-
-	if (!buf || pt_buffer_is_full(buf, pt)) {
-		event->hw.state = PERF_HES_STOPPED;
-		return;
-	}
-
-	ACCESS_ONCE(pt->handle_nmi) = 1;
-	event->hw.state = 0;
-
-	pt_config_buffer(buf->cur->table, buf->cur_idx,
-			 buf->output_off);
-	pt_config(event);
-}
-
-static void pt_event_stop(struct perf_event *event, int mode)
-{
-	struct pt *pt = this_cpu_ptr(&pt_ctx);
-
-	/*
-	 * Protect against the PMI racing with disabling wrmsr,
-	 * see comment in intel_pt_interrupt().
-	 */
-	ACCESS_ONCE(pt->handle_nmi) = 0;
-	pt_config_start(false);
-
-	if (event->hw.state == PERF_HES_STOPPED)
-		return;
-
-	event->hw.state = PERF_HES_STOPPED;
-
-	if (mode & PERF_EF_UPDATE) {
-		struct pt_buffer *buf = perf_get_aux(&pt->handle);
-
-		if (!buf)
-			return;
-
-		if (WARN_ON_ONCE(pt->handle.event != event))
-			return;
-
-		pt_read_offset(buf);
-
-		pt_handle_status(pt);
-
-		pt_update_head(pt);
-	}
-}
-
-static void pt_event_del(struct perf_event *event, int mode)
-{
-	struct pt *pt = this_cpu_ptr(&pt_ctx);
-	struct pt_buffer *buf;
-
-	pt_event_stop(event, PERF_EF_UPDATE);
-
-	buf = perf_get_aux(&pt->handle);
-
-	if (buf) {
-		if (buf->snapshot)
-			pt->handle.head =
-				local_xchg(&buf->data_size,
-					   buf->nr_pages << PAGE_SHIFT);
-		perf_aux_output_end(&pt->handle, local_xchg(&buf->data_size, 0),
-				    local_xchg(&buf->lost, 0));
-	}
-}
-
-static int pt_event_add(struct perf_event *event, int mode)
-{
-	struct pt_buffer *buf;
-	struct pt *pt = this_cpu_ptr(&pt_ctx);
-	struct hw_perf_event *hwc = &event->hw;
-	int ret = -EBUSY;
-
-	if (pt->handle.event)
-		goto fail;
-
-	buf = perf_aux_output_begin(&pt->handle, event);
-	ret = -EINVAL;
-	if (!buf)
-		goto fail_stop;
-
-	pt_buffer_reset_offsets(buf, pt->handle.head);
-	if (!buf->snapshot) {
-		ret = pt_buffer_reset_markers(buf, &pt->handle);
-		if (ret)
-			goto fail_end_stop;
-	}
-
-	if (mode & PERF_EF_START) {
-		pt_event_start(event, 0);
-		ret = -EBUSY;
-		if (hwc->state == PERF_HES_STOPPED)
-			goto fail_end_stop;
-	} else {
-		hwc->state = PERF_HES_STOPPED;
-	}
-
-	return 0;
-
-fail_end_stop:
-	perf_aux_output_end(&pt->handle, 0, true);
-fail_stop:
-	hwc->state = PERF_HES_STOPPED;
-fail:
-	return ret;
-}
-
-static void pt_event_read(struct perf_event *event)
-{
-}
-
-static void pt_event_destroy(struct perf_event *event)
-{
-	x86_del_exclusive(x86_lbr_exclusive_pt);
-}
-
-static int pt_event_init(struct perf_event *event)
-{
-	if (event->attr.type != pt_pmu.pmu.type)
-		return -ENOENT;
-
-	if (!pt_event_valid(event))
-		return -EINVAL;
-
-	if (x86_add_exclusive(x86_lbr_exclusive_pt))
-		return -EBUSY;
-
-	event->destroy = pt_event_destroy;
-
-	return 0;
-}
-
-static __init int pt_init(void)
-{
-	int ret, cpu, prior_warn = 0;
-
-	BUILD_BUG_ON(sizeof(struct topa) > PAGE_SIZE);
-
-	if (!test_cpu_cap(&boot_cpu_data, X86_FEATURE_INTEL_PT))
-		return -ENODEV;
-
-	get_online_cpus();
-	for_each_online_cpu(cpu) {
-		u64 ctl;
-
-		ret = rdmsrl_safe_on_cpu(cpu, MSR_IA32_RTIT_CTL, &ctl);
-		if (!ret && (ctl & RTIT_CTL_TRACEEN))
-			prior_warn++;
-	}
-	put_online_cpus();
-
-	if (prior_warn) {
-		x86_add_exclusive(x86_lbr_exclusive_pt);
-		pr_warn("PT is enabled at boot time, doing nothing\n");
-
-		return -EBUSY;
-	}
-
-	ret = pt_pmu_hw_init();
-	if (ret)
-		return ret;
-
-	if (!pt_cap_get(PT_CAP_topa_output)) {
-		pr_warn("ToPA output is not supported on this CPU\n");
-		return -ENODEV;
-	}
-
-	if (!pt_cap_get(PT_CAP_topa_multiple_entries))
-		pt_pmu.pmu.capabilities =
-			PERF_PMU_CAP_AUX_NO_SG | PERF_PMU_CAP_AUX_SW_DOUBLEBUF;
-
-	pt_pmu.pmu.capabilities	|= PERF_PMU_CAP_EXCLUSIVE | PERF_PMU_CAP_ITRACE;
-	pt_pmu.pmu.attr_groups	= pt_attr_groups;
-	pt_pmu.pmu.task_ctx_nr	= perf_sw_context;
-	pt_pmu.pmu.event_init	= pt_event_init;
-	pt_pmu.pmu.add		= pt_event_add;
-	pt_pmu.pmu.del		= pt_event_del;
-	pt_pmu.pmu.start	= pt_event_start;
-	pt_pmu.pmu.stop		= pt_event_stop;
-	pt_pmu.pmu.read		= pt_event_read;
-	pt_pmu.pmu.setup_aux	= pt_buffer_setup_aux;
-	pt_pmu.pmu.free_aux	= pt_buffer_free_aux;
-	ret = perf_pmu_register(&pt_pmu.pmu, "intel_pt", -1);
-
-	return ret;
-}
-arch_initcall(pt_init);
--- zfcpdump-kernel-4.4.orig/arch/x86/kernel/cpu/perf_event_intel_rapl.c
+++ /dev/null
@@ -1,796 +0,0 @@
-/*
- * perf_event_intel_rapl.c: support Intel RAPL energy consumption counters
- * Copyright (C) 2013 Google, Inc., Stephane Eranian
- *
- * Intel RAPL interface is specified in the IA-32 Manual Vol3b
- * section 14.7.1 (September 2013)
- *
- * RAPL provides more controls than just reporting energy consumption
- * however here we only expose the 3 energy consumption free running
- * counters (pp0, pkg, dram).
- *
- * Each of those counters increments in a power unit defined by the
- * RAPL_POWER_UNIT MSR. On SandyBridge, this unit is 1/(2^16) Joules
- * but it can vary.
- *
- * Counter to rapl events mappings:
- *
- *  pp0 counter: consumption of all physical cores (power plane 0)
- * 	  event: rapl_energy_cores
- *    perf code: 0x1
- *
- *  pkg counter: consumption of the whole processor package
- *	  event: rapl_energy_pkg
- *    perf code: 0x2
- *
- * dram counter: consumption of the dram domain (servers only)
- *	  event: rapl_energy_dram
- *    perf code: 0x3
- *
- * dram counter: consumption of the builtin-gpu domain (client only)
- *	  event: rapl_energy_gpu
- *    perf code: 0x4
- *
- * We manage those counters as free running (read-only). They may be
- * use simultaneously by other tools, such as turbostat.
- *
- * The events only support system-wide mode counting. There is no
- * sampling support because it does not make sense and is not
- * supported by the RAPL hardware.
- *
- * Because we want to avoid floating-point operations in the kernel,
- * the events are all reported in fixed point arithmetic (32.32).
- * Tools must adjust the counts to convert them to Watts using
- * the duration of the measurement. Tools may use a function such as
- * ldexp(raw_count, -32);
- */
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/perf_event.h>
-#include <asm/cpu_device_id.h>
-#include "perf_event.h"
-
-/*
- * RAPL energy status counters
- */
-#define RAPL_IDX_PP0_NRG_STAT	0	/* all cores */
-#define INTEL_RAPL_PP0		0x1	/* pseudo-encoding */
-#define RAPL_IDX_PKG_NRG_STAT	1	/* entire package */
-#define INTEL_RAPL_PKG		0x2	/* pseudo-encoding */
-#define RAPL_IDX_RAM_NRG_STAT	2	/* DRAM */
-#define INTEL_RAPL_RAM		0x3	/* pseudo-encoding */
-#define RAPL_IDX_PP1_NRG_STAT	3	/* gpu */
-#define INTEL_RAPL_PP1		0x4	/* pseudo-encoding */
-
-#define NR_RAPL_DOMAINS         0x4
-static const char *rapl_domain_names[NR_RAPL_DOMAINS] __initconst = {
-	"pp0-core",
-	"package",
-	"dram",
-	"pp1-gpu",
-};
-
-/* Clients have PP0, PKG */
-#define RAPL_IDX_CLN	(1<<RAPL_IDX_PP0_NRG_STAT|\
-			 1<<RAPL_IDX_PKG_NRG_STAT|\
-			 1<<RAPL_IDX_PP1_NRG_STAT)
-
-/* Servers have PP0, PKG, RAM */
-#define RAPL_IDX_SRV	(1<<RAPL_IDX_PP0_NRG_STAT|\
-			 1<<RAPL_IDX_PKG_NRG_STAT|\
-			 1<<RAPL_IDX_RAM_NRG_STAT)
-
-/* Servers have PP0, PKG, RAM, PP1 */
-#define RAPL_IDX_HSW	(1<<RAPL_IDX_PP0_NRG_STAT|\
-			 1<<RAPL_IDX_PKG_NRG_STAT|\
-			 1<<RAPL_IDX_RAM_NRG_STAT|\
-			 1<<RAPL_IDX_PP1_NRG_STAT)
-
-/* Knights Landing has PKG, RAM */
-#define RAPL_IDX_KNL	(1<<RAPL_IDX_PKG_NRG_STAT|\
-			 1<<RAPL_IDX_RAM_NRG_STAT)
-
-/*
- * event code: LSB 8 bits, passed in attr->config
- * any other bit is reserved
- */
-#define RAPL_EVENT_MASK	0xFFULL
-
-#define DEFINE_RAPL_FORMAT_ATTR(_var, _name, _format)		\
-static ssize_t __rapl_##_var##_show(struct kobject *kobj,	\
-				struct kobj_attribute *attr,	\
-				char *page)			\
-{								\
-	BUILD_BUG_ON(sizeof(_format) >= PAGE_SIZE);		\
-	return sprintf(page, _format "\n");			\
-}								\
-static struct kobj_attribute format_attr_##_var =		\
-	__ATTR(_name, 0444, __rapl_##_var##_show, NULL)
-
-#define RAPL_CNTR_WIDTH 32 /* 32-bit rapl counters */
-
-#define RAPL_EVENT_ATTR_STR(_name, v, str)				\
-static struct perf_pmu_events_attr event_attr_##v = {			\
-	.attr		= __ATTR(_name, 0444, rapl_sysfs_show, NULL),	\
-	.id		= 0,						\
-	.event_str	= str,						\
-};
-
-struct rapl_pmu {
-	spinlock_t	 lock;
-	int		 n_active; /* number of active events */
-	struct list_head active_list;
-	struct pmu	 *pmu; /* pointer to rapl_pmu_class */
-	ktime_t		 timer_interval; /* in ktime_t unit */
-	struct hrtimer   hrtimer;
-};
-
-static int rapl_hw_unit[NR_RAPL_DOMAINS] __read_mostly;  /* 1/2^hw_unit Joule */
-static struct pmu rapl_pmu_class;
-static cpumask_t rapl_cpu_mask;
-static int rapl_cntr_mask;
-
-static DEFINE_PER_CPU(struct rapl_pmu *, rapl_pmu);
-static DEFINE_PER_CPU(struct rapl_pmu *, rapl_pmu_to_free);
-
-static struct x86_pmu_quirk *rapl_quirks;
-static inline u64 rapl_read_counter(struct perf_event *event)
-{
-	u64 raw;
-	rdmsrl(event->hw.event_base, raw);
-	return raw;
-}
-
-#define rapl_add_quirk(func_)						\
-do {									\
-	static struct x86_pmu_quirk __quirk __initdata = {		\
-		.func = func_,						\
-	};								\
-	__quirk.next = rapl_quirks;					\
-	rapl_quirks = &__quirk;						\
-} while (0)
-
-static inline u64 rapl_scale(u64 v, int cfg)
-{
-	if (cfg > NR_RAPL_DOMAINS) {
-		pr_warn("invalid domain %d, failed to scale data\n", cfg);
-		return v;
-	}
-	/*
-	 * scale delta to smallest unit (1/2^32)
-	 * users must then scale back: count * 1/(1e9*2^32) to get Joules
-	 * or use ldexp(count, -32).
-	 * Watts = Joules/Time delta
-	 */
-	return v << (32 - rapl_hw_unit[cfg - 1]);
-}
-
-static u64 rapl_event_update(struct perf_event *event)
-{
-	struct hw_perf_event *hwc = &event->hw;
-	u64 prev_raw_count, new_raw_count;
-	s64 delta, sdelta;
-	int shift = RAPL_CNTR_WIDTH;
-
-again:
-	prev_raw_count = local64_read(&hwc->prev_count);
-	rdmsrl(event->hw.event_base, new_raw_count);
-
-	if (local64_cmpxchg(&hwc->prev_count, prev_raw_count,
-			    new_raw_count) != prev_raw_count) {
-		cpu_relax();
-		goto again;
-	}
-
-	/*
-	 * Now we have the new raw value and have updated the prev
-	 * timestamp already. We can now calculate the elapsed delta
-	 * (event-)time and add that to the generic event.
-	 *
-	 * Careful, not all hw sign-extends above the physical width
-	 * of the count.
-	 */
-	delta = (new_raw_count << shift) - (prev_raw_count << shift);
-	delta >>= shift;
-
-	sdelta = rapl_scale(delta, event->hw.config);
-
-	local64_add(sdelta, &event->count);
-
-	return new_raw_count;
-}
-
-static void rapl_start_hrtimer(struct rapl_pmu *pmu)
-{
-       hrtimer_start(&pmu->hrtimer, pmu->timer_interval,
-		     HRTIMER_MODE_REL_PINNED);
-}
-
-static void rapl_stop_hrtimer(struct rapl_pmu *pmu)
-{
-	hrtimer_cancel(&pmu->hrtimer);
-}
-
-static enum hrtimer_restart rapl_hrtimer_handle(struct hrtimer *hrtimer)
-{
-	struct rapl_pmu *pmu = __this_cpu_read(rapl_pmu);
-	struct perf_event *event;
-	unsigned long flags;
-
-	if (!pmu->n_active)
-		return HRTIMER_NORESTART;
-
-	spin_lock_irqsave(&pmu->lock, flags);
-
-	list_for_each_entry(event, &pmu->active_list, active_entry) {
-		rapl_event_update(event);
-	}
-
-	spin_unlock_irqrestore(&pmu->lock, flags);
-
-	hrtimer_forward_now(hrtimer, pmu->timer_interval);
-
-	return HRTIMER_RESTART;
-}
-
-static void rapl_hrtimer_init(struct rapl_pmu *pmu)
-{
-	struct hrtimer *hr = &pmu->hrtimer;
-
-	hrtimer_init(hr, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
-	hr->function = rapl_hrtimer_handle;
-}
-
-static void __rapl_pmu_event_start(struct rapl_pmu *pmu,
-				   struct perf_event *event)
-{
-	if (WARN_ON_ONCE(!(event->hw.state & PERF_HES_STOPPED)))
-		return;
-
-	event->hw.state = 0;
-
-	list_add_tail(&event->active_entry, &pmu->active_list);
-
-	local64_set(&event->hw.prev_count, rapl_read_counter(event));
-
-	pmu->n_active++;
-	if (pmu->n_active == 1)
-		rapl_start_hrtimer(pmu);
-}
-
-static void rapl_pmu_event_start(struct perf_event *event, int mode)
-{
-	struct rapl_pmu *pmu = __this_cpu_read(rapl_pmu);
-	unsigned long flags;
-
-	spin_lock_irqsave(&pmu->lock, flags);
-	__rapl_pmu_event_start(pmu, event);
-	spin_unlock_irqrestore(&pmu->lock, flags);
-}
-
-static void rapl_pmu_event_stop(struct perf_event *event, int mode)
-{
-	struct rapl_pmu *pmu = __this_cpu_read(rapl_pmu);
-	struct hw_perf_event *hwc = &event->hw;
-	unsigned long flags;
-
-	spin_lock_irqsave(&pmu->lock, flags);
-
-	/* mark event as deactivated and stopped */
-	if (!(hwc->state & PERF_HES_STOPPED)) {
-		WARN_ON_ONCE(pmu->n_active <= 0);
-		pmu->n_active--;
-		if (pmu->n_active == 0)
-			rapl_stop_hrtimer(pmu);
-
-		list_del(&event->active_entry);
-
-		WARN_ON_ONCE(hwc->state & PERF_HES_STOPPED);
-		hwc->state |= PERF_HES_STOPPED;
-	}
-
-	/* check if update of sw counter is necessary */
-	if ((mode & PERF_EF_UPDATE) && !(hwc->state & PERF_HES_UPTODATE)) {
-		/*
-		 * Drain the remaining delta count out of a event
-		 * that we are disabling:
-		 */
-		rapl_event_update(event);
-		hwc->state |= PERF_HES_UPTODATE;
-	}
-
-	spin_unlock_irqrestore(&pmu->lock, flags);
-}
-
-static int rapl_pmu_event_add(struct perf_event *event, int mode)
-{
-	struct rapl_pmu *pmu = __this_cpu_read(rapl_pmu);
-	struct hw_perf_event *hwc = &event->hw;
-	unsigned long flags;
-
-	spin_lock_irqsave(&pmu->lock, flags);
-
-	hwc->state = PERF_HES_UPTODATE | PERF_HES_STOPPED;
-
-	if (mode & PERF_EF_START)
-		__rapl_pmu_event_start(pmu, event);
-
-	spin_unlock_irqrestore(&pmu->lock, flags);
-
-	return 0;
-}
-
-static void rapl_pmu_event_del(struct perf_event *event, int flags)
-{
-	rapl_pmu_event_stop(event, PERF_EF_UPDATE);
-}
-
-static int rapl_pmu_event_init(struct perf_event *event)
-{
-	u64 cfg = event->attr.config & RAPL_EVENT_MASK;
-	int bit, msr, ret = 0;
-
-	/* only look at RAPL events */
-	if (event->attr.type != rapl_pmu_class.type)
-		return -ENOENT;
-
-	/* check only supported bits are set */
-	if (event->attr.config & ~RAPL_EVENT_MASK)
-		return -EINVAL;
-
-	/*
-	 * check event is known (determines counter)
-	 */
-	switch (cfg) {
-	case INTEL_RAPL_PP0:
-		bit = RAPL_IDX_PP0_NRG_STAT;
-		msr = MSR_PP0_ENERGY_STATUS;
-		break;
-	case INTEL_RAPL_PKG:
-		bit = RAPL_IDX_PKG_NRG_STAT;
-		msr = MSR_PKG_ENERGY_STATUS;
-		break;
-	case INTEL_RAPL_RAM:
-		bit = RAPL_IDX_RAM_NRG_STAT;
-		msr = MSR_DRAM_ENERGY_STATUS;
-		break;
-	case INTEL_RAPL_PP1:
-		bit = RAPL_IDX_PP1_NRG_STAT;
-		msr = MSR_PP1_ENERGY_STATUS;
-		break;
-	default:
-		return -EINVAL;
-	}
-	/* check event supported */
-	if (!(rapl_cntr_mask & (1 << bit)))
-		return -EINVAL;
-
-	/* unsupported modes and filters */
-	if (event->attr.exclude_user   ||
-	    event->attr.exclude_kernel ||
-	    event->attr.exclude_hv     ||
-	    event->attr.exclude_idle   ||
-	    event->attr.exclude_host   ||
-	    event->attr.exclude_guest  ||
-	    event->attr.sample_period) /* no sampling */
-		return -EINVAL;
-
-	/* must be done before validate_group */
-	event->hw.event_base = msr;
-	event->hw.config = cfg;
-	event->hw.idx = bit;
-
-	return ret;
-}
-
-static void rapl_pmu_event_read(struct perf_event *event)
-{
-	rapl_event_update(event);
-}
-
-static ssize_t rapl_get_attr_cpumask(struct device *dev,
-				struct device_attribute *attr, char *buf)
-{
-	return cpumap_print_to_pagebuf(true, buf, &rapl_cpu_mask);
-}
-
-static DEVICE_ATTR(cpumask, S_IRUGO, rapl_get_attr_cpumask, NULL);
-
-static struct attribute *rapl_pmu_attrs[] = {
-	&dev_attr_cpumask.attr,
-	NULL,
-};
-
-static struct attribute_group rapl_pmu_attr_group = {
-	.attrs = rapl_pmu_attrs,
-};
-
-static ssize_t rapl_sysfs_show(struct device *dev,
-			       struct device_attribute *attr,
-			       char *page)
-{
-	struct perf_pmu_events_attr *pmu_attr = \
-		container_of(attr, struct perf_pmu_events_attr, attr);
-
-	if (pmu_attr->event_str)
-		return sprintf(page, "%s", pmu_attr->event_str);
-
-	return 0;
-}
-
-RAPL_EVENT_ATTR_STR(energy-cores, rapl_cores, "event=0x01");
-RAPL_EVENT_ATTR_STR(energy-pkg  ,   rapl_pkg, "event=0x02");
-RAPL_EVENT_ATTR_STR(energy-ram  ,   rapl_ram, "event=0x03");
-RAPL_EVENT_ATTR_STR(energy-gpu  ,   rapl_gpu, "event=0x04");
-
-RAPL_EVENT_ATTR_STR(energy-cores.unit, rapl_cores_unit, "Joules");
-RAPL_EVENT_ATTR_STR(energy-pkg.unit  ,   rapl_pkg_unit, "Joules");
-RAPL_EVENT_ATTR_STR(energy-ram.unit  ,   rapl_ram_unit, "Joules");
-RAPL_EVENT_ATTR_STR(energy-gpu.unit  ,   rapl_gpu_unit, "Joules");
-
-/*
- * we compute in 0.23 nJ increments regardless of MSR
- */
-RAPL_EVENT_ATTR_STR(energy-cores.scale, rapl_cores_scale, "2.3283064365386962890625e-10");
-RAPL_EVENT_ATTR_STR(energy-pkg.scale,     rapl_pkg_scale, "2.3283064365386962890625e-10");
-RAPL_EVENT_ATTR_STR(energy-ram.scale,     rapl_ram_scale, "2.3283064365386962890625e-10");
-RAPL_EVENT_ATTR_STR(energy-gpu.scale,     rapl_gpu_scale, "2.3283064365386962890625e-10");
-
-static struct attribute *rapl_events_srv_attr[] = {
-	EVENT_PTR(rapl_cores),
-	EVENT_PTR(rapl_pkg),
-	EVENT_PTR(rapl_ram),
-
-	EVENT_PTR(rapl_cores_unit),
-	EVENT_PTR(rapl_pkg_unit),
-	EVENT_PTR(rapl_ram_unit),
-
-	EVENT_PTR(rapl_cores_scale),
-	EVENT_PTR(rapl_pkg_scale),
-	EVENT_PTR(rapl_ram_scale),
-	NULL,
-};
-
-static struct attribute *rapl_events_cln_attr[] = {
-	EVENT_PTR(rapl_cores),
-	EVENT_PTR(rapl_pkg),
-	EVENT_PTR(rapl_gpu),
-
-	EVENT_PTR(rapl_cores_unit),
-	EVENT_PTR(rapl_pkg_unit),
-	EVENT_PTR(rapl_gpu_unit),
-
-	EVENT_PTR(rapl_cores_scale),
-	EVENT_PTR(rapl_pkg_scale),
-	EVENT_PTR(rapl_gpu_scale),
-	NULL,
-};
-
-static struct attribute *rapl_events_hsw_attr[] = {
-	EVENT_PTR(rapl_cores),
-	EVENT_PTR(rapl_pkg),
-	EVENT_PTR(rapl_gpu),
-	EVENT_PTR(rapl_ram),
-
-	EVENT_PTR(rapl_cores_unit),
-	EVENT_PTR(rapl_pkg_unit),
-	EVENT_PTR(rapl_gpu_unit),
-	EVENT_PTR(rapl_ram_unit),
-
-	EVENT_PTR(rapl_cores_scale),
-	EVENT_PTR(rapl_pkg_scale),
-	EVENT_PTR(rapl_gpu_scale),
-	EVENT_PTR(rapl_ram_scale),
-	NULL,
-};
-
-static struct attribute *rapl_events_knl_attr[] = {
-	EVENT_PTR(rapl_pkg),
-	EVENT_PTR(rapl_ram),
-
-	EVENT_PTR(rapl_pkg_unit),
-	EVENT_PTR(rapl_ram_unit),
-
-	EVENT_PTR(rapl_pkg_scale),
-	EVENT_PTR(rapl_ram_scale),
-	NULL,
-};
-
-static struct attribute_group rapl_pmu_events_group = {
-	.name = "events",
-	.attrs = NULL, /* patched at runtime */
-};
-
-DEFINE_RAPL_FORMAT_ATTR(event, event, "config:0-7");
-static struct attribute *rapl_formats_attr[] = {
-	&format_attr_event.attr,
-	NULL,
-};
-
-static struct attribute_group rapl_pmu_format_group = {
-	.name = "format",
-	.attrs = rapl_formats_attr,
-};
-
-const struct attribute_group *rapl_attr_groups[] = {
-	&rapl_pmu_attr_group,
-	&rapl_pmu_format_group,
-	&rapl_pmu_events_group,
-	NULL,
-};
-
-static struct pmu rapl_pmu_class = {
-	.attr_groups	= rapl_attr_groups,
-	.task_ctx_nr	= perf_invalid_context, /* system-wide only */
-	.event_init	= rapl_pmu_event_init,
-	.add		= rapl_pmu_event_add, /* must have */
-	.del		= rapl_pmu_event_del, /* must have */
-	.start		= rapl_pmu_event_start,
-	.stop		= rapl_pmu_event_stop,
-	.read		= rapl_pmu_event_read,
-};
-
-static void rapl_cpu_exit(int cpu)
-{
-	struct rapl_pmu *pmu = per_cpu(rapl_pmu, cpu);
-	int i, phys_id = topology_physical_package_id(cpu);
-	int target = -1;
-
-	/* find a new cpu on same package */
-	for_each_online_cpu(i) {
-		if (i == cpu)
-			continue;
-		if (phys_id == topology_physical_package_id(i)) {
-			target = i;
-			break;
-		}
-	}
-	/*
-	 * clear cpu from cpumask
-	 * if was set in cpumask and still some cpu on package,
-	 * then move to new cpu
-	 */
-	if (cpumask_test_and_clear_cpu(cpu, &rapl_cpu_mask) && target >= 0)
-		cpumask_set_cpu(target, &rapl_cpu_mask);
-
-	WARN_ON(cpumask_empty(&rapl_cpu_mask));
-	/*
-	 * migrate events and context to new cpu
-	 */
-	if (target >= 0)
-		perf_pmu_migrate_context(pmu->pmu, cpu, target);
-
-	/* cancel overflow polling timer for CPU */
-	rapl_stop_hrtimer(pmu);
-}
-
-static void rapl_cpu_init(int cpu)
-{
-	int i, phys_id = topology_physical_package_id(cpu);
-
-	/* check if phys_is is already covered */
-	for_each_cpu(i, &rapl_cpu_mask) {
-		if (phys_id == topology_physical_package_id(i))
-			return;
-	}
-	/* was not found, so add it */
-	cpumask_set_cpu(cpu, &rapl_cpu_mask);
-}
-
-static __init void rapl_hsw_server_quirk(void)
-{
-	/*
-	 * DRAM domain on HSW server has fixed energy unit which can be
-	 * different than the unit from power unit MSR.
-	 * "Intel Xeon Processor E5-1600 and E5-2600 v3 Product Families, V2
-	 * of 2. Datasheet, September 2014, Reference Number: 330784-001 "
-	 */
-	rapl_hw_unit[RAPL_IDX_RAM_NRG_STAT] = 16;
-}
-
-static int rapl_cpu_prepare(int cpu)
-{
-	struct rapl_pmu *pmu = per_cpu(rapl_pmu, cpu);
-	int phys_id = topology_physical_package_id(cpu);
-	u64 ms;
-
-	if (pmu)
-		return 0;
-
-	if (phys_id < 0)
-		return -1;
-
-	pmu = kzalloc_node(sizeof(*pmu), GFP_KERNEL, cpu_to_node(cpu));
-	if (!pmu)
-		return -1;
-	spin_lock_init(&pmu->lock);
-
-	INIT_LIST_HEAD(&pmu->active_list);
-
-	pmu->pmu = &rapl_pmu_class;
-
-	/*
-	 * use reference of 200W for scaling the timeout
-	 * to avoid missing counter overflows.
-	 * 200W = 200 Joules/sec
-	 * divide interval by 2 to avoid lockstep (2 * 100)
-	 * if hw unit is 32, then we use 2 ms 1/200/2
-	 */
-	if (rapl_hw_unit[0] < 32)
-		ms = (1000 / (2 * 100)) * (1ULL << (32 - rapl_hw_unit[0] - 1));
-	else
-		ms = 2;
-
-	pmu->timer_interval = ms_to_ktime(ms);
-
-	rapl_hrtimer_init(pmu);
-
-	/* set RAPL pmu for this cpu for now */
-	per_cpu(rapl_pmu, cpu) = pmu;
-	per_cpu(rapl_pmu_to_free, cpu) = NULL;
-
-	return 0;
-}
-
-static void rapl_cpu_kfree(int cpu)
-{
-	struct rapl_pmu *pmu = per_cpu(rapl_pmu_to_free, cpu);
-
-	kfree(pmu);
-
-	per_cpu(rapl_pmu_to_free, cpu) = NULL;
-}
-
-static int rapl_cpu_dying(int cpu)
-{
-	struct rapl_pmu *pmu = per_cpu(rapl_pmu, cpu);
-
-	if (!pmu)
-		return 0;
-
-	per_cpu(rapl_pmu, cpu) = NULL;
-
-	per_cpu(rapl_pmu_to_free, cpu) = pmu;
-
-	return 0;
-}
-
-static int rapl_cpu_notifier(struct notifier_block *self,
-			     unsigned long action, void *hcpu)
-{
-	unsigned int cpu = (long)hcpu;
-
-	switch (action & ~CPU_TASKS_FROZEN) {
-	case CPU_UP_PREPARE:
-		rapl_cpu_prepare(cpu);
-		break;
-	case CPU_STARTING:
-		rapl_cpu_init(cpu);
-		break;
-	case CPU_UP_CANCELED:
-	case CPU_DYING:
-		rapl_cpu_dying(cpu);
-		break;
-	case CPU_ONLINE:
-	case CPU_DEAD:
-		rapl_cpu_kfree(cpu);
-		break;
-	case CPU_DOWN_PREPARE:
-		rapl_cpu_exit(cpu);
-		break;
-	default:
-		break;
-	}
-
-	return NOTIFY_OK;
-}
-
-static int rapl_check_hw_unit(void)
-{
-	u64 msr_rapl_power_unit_bits;
-	int i;
-
-	/* protect rdmsrl() to handle virtualization */
-	if (rdmsrl_safe(MSR_RAPL_POWER_UNIT, &msr_rapl_power_unit_bits))
-		return -1;
-	for (i = 0; i < NR_RAPL_DOMAINS; i++)
-		rapl_hw_unit[i] = (msr_rapl_power_unit_bits >> 8) & 0x1FULL;
-
-	return 0;
-}
-
-static const struct x86_cpu_id rapl_cpu_match[] = {
-	[0] = { .vendor = X86_VENDOR_INTEL, .family = 6 },
-	[1] = {},
-};
-
-static int __init rapl_pmu_init(void)
-{
-	struct rapl_pmu *pmu;
-	int cpu, ret;
-	struct x86_pmu_quirk *quirk;
-	int i;
-
-	/*
-	 * check for Intel processor family 6
-	 */
-	if (!x86_match_cpu(rapl_cpu_match))
-		return 0;
-
-	/* check supported CPU */
-	switch (boot_cpu_data.x86_model) {
-	case 42: /* Sandy Bridge */
-	case 58: /* Ivy Bridge */
-		rapl_cntr_mask = RAPL_IDX_CLN;
-		rapl_pmu_events_group.attrs = rapl_events_cln_attr;
-		break;
-	case 63: /* Haswell-Server */
-		rapl_add_quirk(rapl_hsw_server_quirk);
-		rapl_cntr_mask = RAPL_IDX_SRV;
-		rapl_pmu_events_group.attrs = rapl_events_srv_attr;
-		break;
-	case 60: /* Haswell */
-	case 69: /* Haswell-Celeron */
-	case 61: /* Broadwell */
-		rapl_cntr_mask = RAPL_IDX_HSW;
-		rapl_pmu_events_group.attrs = rapl_events_hsw_attr;
-		break;
-	case 45: /* Sandy Bridge-EP */
-	case 62: /* IvyTown */
-		rapl_cntr_mask = RAPL_IDX_SRV;
-		rapl_pmu_events_group.attrs = rapl_events_srv_attr;
-		break;
-	case 87: /* Knights Landing */
-		rapl_add_quirk(rapl_hsw_server_quirk);
-		rapl_cntr_mask = RAPL_IDX_KNL;
-		rapl_pmu_events_group.attrs = rapl_events_knl_attr;
-
-	default:
-		/* unsupported */
-		return 0;
-	}
-	ret = rapl_check_hw_unit();
-	if (ret)
-		return ret;
-
-	/* run cpu model quirks */
-	for (quirk = rapl_quirks; quirk; quirk = quirk->next)
-		quirk->func();
-	cpu_notifier_register_begin();
-
-	for_each_online_cpu(cpu) {
-		ret = rapl_cpu_prepare(cpu);
-		if (ret)
-			goto out;
-		rapl_cpu_init(cpu);
-	}
-
-	__perf_cpu_notifier(rapl_cpu_notifier);
-
-	ret = perf_pmu_register(&rapl_pmu_class, "power", -1);
-	if (WARN_ON(ret)) {
-		pr_info("RAPL PMU detected, registration failed (%d), RAPL PMU disabled\n", ret);
-		cpu_notifier_register_done();
-		return -1;
-	}
-
-	pmu = __this_cpu_read(rapl_pmu);
-
-	pr_info("RAPL PMU detected,"
-		" API unit is 2^-32 Joules,"
-		" %d fixed counters"
-		" %llu ms ovfl timer\n",
-		hweight32(rapl_cntr_mask),
-		ktime_to_ms(pmu->timer_interval));
-	for (i = 0; i < NR_RAPL_DOMAINS; i++) {
-		if (rapl_cntr_mask & (1 << i)) {
-			pr_info("hw unit of domain %s 2^-%d Joules\n",
-				rapl_domain_names[i], rapl_hw_unit[i]);
-		}
-	}
-out:
-	cpu_notifier_register_done();
-
-	return 0;
-}
-device_initcall(rapl_pmu_init);
--- zfcpdump-kernel-4.4.orig/arch/x86/kernel/cpu/perf_event_intel_uncore.c
+++ /dev/null
@@ -1,1381 +0,0 @@
-#include "perf_event_intel_uncore.h"
-
-static struct intel_uncore_type *empty_uncore[] = { NULL, };
-struct intel_uncore_type **uncore_msr_uncores = empty_uncore;
-struct intel_uncore_type **uncore_pci_uncores = empty_uncore;
-
-static bool pcidrv_registered;
-struct pci_driver *uncore_pci_driver;
-/* pci bus to socket mapping */
-DEFINE_RAW_SPINLOCK(pci2phy_map_lock);
-struct list_head pci2phy_map_head = LIST_HEAD_INIT(pci2phy_map_head);
-struct pci_dev *uncore_extra_pci_dev[UNCORE_SOCKET_MAX][UNCORE_EXTRA_PCI_DEV_MAX];
-
-static DEFINE_RAW_SPINLOCK(uncore_box_lock);
-/* mask of cpus that collect uncore events */
-static cpumask_t uncore_cpu_mask;
-
-/* constraint for the fixed counter */
-static struct event_constraint uncore_constraint_fixed =
-	EVENT_CONSTRAINT(~0ULL, 1 << UNCORE_PMC_IDX_FIXED, ~0ULL);
-struct event_constraint uncore_constraint_empty =
-	EVENT_CONSTRAINT(0, 0, 0);
-
-int uncore_pcibus_to_physid(struct pci_bus *bus)
-{
-	struct pci2phy_map *map;
-	int phys_id = -1;
-
-	raw_spin_lock(&pci2phy_map_lock);
-	list_for_each_entry(map, &pci2phy_map_head, list) {
-		if (map->segment == pci_domain_nr(bus)) {
-			phys_id = map->pbus_to_physid[bus->number];
-			break;
-		}
-	}
-	raw_spin_unlock(&pci2phy_map_lock);
-
-	return phys_id;
-}
-
-struct pci2phy_map *__find_pci2phy_map(int segment)
-{
-	struct pci2phy_map *map, *alloc = NULL;
-	int i;
-
-	lockdep_assert_held(&pci2phy_map_lock);
-
-lookup:
-	list_for_each_entry(map, &pci2phy_map_head, list) {
-		if (map->segment == segment)
-			goto end;
-	}
-
-	if (!alloc) {
-		raw_spin_unlock(&pci2phy_map_lock);
-		alloc = kmalloc(sizeof(struct pci2phy_map), GFP_KERNEL);
-		raw_spin_lock(&pci2phy_map_lock);
-
-		if (!alloc)
-			return NULL;
-
-		goto lookup;
-	}
-
-	map = alloc;
-	alloc = NULL;
-	map->segment = segment;
-	for (i = 0; i < 256; i++)
-		map->pbus_to_physid[i] = -1;
-	list_add_tail(&map->list, &pci2phy_map_head);
-
-end:
-	kfree(alloc);
-	return map;
-}
-
-ssize_t uncore_event_show(struct kobject *kobj,
-			  struct kobj_attribute *attr, char *buf)
-{
-	struct uncore_event_desc *event =
-		container_of(attr, struct uncore_event_desc, attr);
-	return sprintf(buf, "%s", event->config);
-}
-
-struct intel_uncore_pmu *uncore_event_to_pmu(struct perf_event *event)
-{
-	return container_of(event->pmu, struct intel_uncore_pmu, pmu);
-}
-
-struct intel_uncore_box *uncore_pmu_to_box(struct intel_uncore_pmu *pmu, int cpu)
-{
-	struct intel_uncore_box *box;
-
-	box = *per_cpu_ptr(pmu->box, cpu);
-	if (box)
-		return box;
-
-	raw_spin_lock(&uncore_box_lock);
-	/* Recheck in lock to handle races. */
-	if (*per_cpu_ptr(pmu->box, cpu))
-		goto out;
-	list_for_each_entry(box, &pmu->box_list, list) {
-		if (box->phys_id == topology_physical_package_id(cpu)) {
-			atomic_inc(&box->refcnt);
-			*per_cpu_ptr(pmu->box, cpu) = box;
-			break;
-		}
-	}
-out:
-	raw_spin_unlock(&uncore_box_lock);
-
-	return *per_cpu_ptr(pmu->box, cpu);
-}
-
-struct intel_uncore_box *uncore_event_to_box(struct perf_event *event)
-{
-	/*
-	 * perf core schedules event on the basis of cpu, uncore events are
-	 * collected by one of the cpus inside a physical package.
-	 */
-	return uncore_pmu_to_box(uncore_event_to_pmu(event), smp_processor_id());
-}
-
-u64 uncore_msr_read_counter(struct intel_uncore_box *box, struct perf_event *event)
-{
-	u64 count;
-
-	rdmsrl(event->hw.event_base, count);
-
-	return count;
-}
-
-/*
- * generic get constraint function for shared match/mask registers.
- */
-struct event_constraint *
-uncore_get_constraint(struct intel_uncore_box *box, struct perf_event *event)
-{
-	struct intel_uncore_extra_reg *er;
-	struct hw_perf_event_extra *reg1 = &event->hw.extra_reg;
-	struct hw_perf_event_extra *reg2 = &event->hw.branch_reg;
-	unsigned long flags;
-	bool ok = false;
-
-	/*
-	 * reg->alloc can be set due to existing state, so for fake box we
-	 * need to ignore this, otherwise we might fail to allocate proper
-	 * fake state for this extra reg constraint.
-	 */
-	if (reg1->idx == EXTRA_REG_NONE ||
-	    (!uncore_box_is_fake(box) && reg1->alloc))
-		return NULL;
-
-	er = &box->shared_regs[reg1->idx];
-	raw_spin_lock_irqsave(&er->lock, flags);
-	if (!atomic_read(&er->ref) ||
-	    (er->config1 == reg1->config && er->config2 == reg2->config)) {
-		atomic_inc(&er->ref);
-		er->config1 = reg1->config;
-		er->config2 = reg2->config;
-		ok = true;
-	}
-	raw_spin_unlock_irqrestore(&er->lock, flags);
-
-	if (ok) {
-		if (!uncore_box_is_fake(box))
-			reg1->alloc = 1;
-		return NULL;
-	}
-
-	return &uncore_constraint_empty;
-}
-
-void uncore_put_constraint(struct intel_uncore_box *box, struct perf_event *event)
-{
-	struct intel_uncore_extra_reg *er;
-	struct hw_perf_event_extra *reg1 = &event->hw.extra_reg;
-
-	/*
-	 * Only put constraint if extra reg was actually allocated. Also
-	 * takes care of event which do not use an extra shared reg.
-	 *
-	 * Also, if this is a fake box we shouldn't touch any event state
-	 * (reg->alloc) and we don't care about leaving inconsistent box
-	 * state either since it will be thrown out.
-	 */
-	if (uncore_box_is_fake(box) || !reg1->alloc)
-		return;
-
-	er = &box->shared_regs[reg1->idx];
-	atomic_dec(&er->ref);
-	reg1->alloc = 0;
-}
-
-u64 uncore_shared_reg_config(struct intel_uncore_box *box, int idx)
-{
-	struct intel_uncore_extra_reg *er;
-	unsigned long flags;
-	u64 config;
-
-	er = &box->shared_regs[idx];
-
-	raw_spin_lock_irqsave(&er->lock, flags);
-	config = er->config;
-	raw_spin_unlock_irqrestore(&er->lock, flags);
-
-	return config;
-}
-
-static void uncore_assign_hw_event(struct intel_uncore_box *box, struct perf_event *event, int idx)
-{
-	struct hw_perf_event *hwc = &event->hw;
-
-	hwc->idx = idx;
-	hwc->last_tag = ++box->tags[idx];
-
-	if (hwc->idx == UNCORE_PMC_IDX_FIXED) {
-		hwc->event_base = uncore_fixed_ctr(box);
-		hwc->config_base = uncore_fixed_ctl(box);
-		return;
-	}
-
-	hwc->config_base = uncore_event_ctl(box, hwc->idx);
-	hwc->event_base  = uncore_perf_ctr(box, hwc->idx);
-}
-
-void uncore_perf_event_update(struct intel_uncore_box *box, struct perf_event *event)
-{
-	u64 prev_count, new_count, delta;
-	int shift;
-
-	if (event->hw.idx >= UNCORE_PMC_IDX_FIXED)
-		shift = 64 - uncore_fixed_ctr_bits(box);
-	else
-		shift = 64 - uncore_perf_ctr_bits(box);
-
-	/* the hrtimer might modify the previous event value */
-again:
-	prev_count = local64_read(&event->hw.prev_count);
-	new_count = uncore_read_counter(box, event);
-	if (local64_xchg(&event->hw.prev_count, new_count) != prev_count)
-		goto again;
-
-	delta = (new_count << shift) - (prev_count << shift);
-	delta >>= shift;
-
-	local64_add(delta, &event->count);
-}
-
-/*
- * The overflow interrupt is unavailable for SandyBridge-EP, is broken
- * for SandyBridge. So we use hrtimer to periodically poll the counter
- * to avoid overflow.
- */
-static enum hrtimer_restart uncore_pmu_hrtimer(struct hrtimer *hrtimer)
-{
-	struct intel_uncore_box *box;
-	struct perf_event *event;
-	unsigned long flags;
-	int bit;
-
-	box = container_of(hrtimer, struct intel_uncore_box, hrtimer);
-	if (!box->n_active || box->cpu != smp_processor_id())
-		return HRTIMER_NORESTART;
-	/*
-	 * disable local interrupt to prevent uncore_pmu_event_start/stop
-	 * to interrupt the update process
-	 */
-	local_irq_save(flags);
-
-	/*
-	 * handle boxes with an active event list as opposed to active
-	 * counters
-	 */
-	list_for_each_entry(event, &box->active_list, active_entry) {
-		uncore_perf_event_update(box, event);
-	}
-
-	for_each_set_bit(bit, box->active_mask, UNCORE_PMC_IDX_MAX)
-		uncore_perf_event_update(box, box->events[bit]);
-
-	local_irq_restore(flags);
-
-	hrtimer_forward_now(hrtimer, ns_to_ktime(box->hrtimer_duration));
-	return HRTIMER_RESTART;
-}
-
-void uncore_pmu_start_hrtimer(struct intel_uncore_box *box)
-{
-	hrtimer_start(&box->hrtimer, ns_to_ktime(box->hrtimer_duration),
-		      HRTIMER_MODE_REL_PINNED);
-}
-
-void uncore_pmu_cancel_hrtimer(struct intel_uncore_box *box)
-{
-	hrtimer_cancel(&box->hrtimer);
-}
-
-static void uncore_pmu_init_hrtimer(struct intel_uncore_box *box)
-{
-	hrtimer_init(&box->hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
-	box->hrtimer.function = uncore_pmu_hrtimer;
-}
-
-static struct intel_uncore_box *uncore_alloc_box(struct intel_uncore_type *type, int node)
-{
-	struct intel_uncore_box *box;
-	int i, size;
-
-	size = sizeof(*box) + type->num_shared_regs * sizeof(struct intel_uncore_extra_reg);
-
-	box = kzalloc_node(size, GFP_KERNEL, node);
-	if (!box)
-		return NULL;
-
-	for (i = 0; i < type->num_shared_regs; i++)
-		raw_spin_lock_init(&box->shared_regs[i].lock);
-
-	uncore_pmu_init_hrtimer(box);
-	atomic_set(&box->refcnt, 1);
-	box->cpu = -1;
-	box->phys_id = -1;
-
-	/* set default hrtimer timeout */
-	box->hrtimer_duration = UNCORE_PMU_HRTIMER_INTERVAL;
-
-	INIT_LIST_HEAD(&box->active_list);
-
-	return box;
-}
-
-/*
- * Using uncore_pmu_event_init pmu event_init callback
- * as a detection point for uncore events.
- */
-static int uncore_pmu_event_init(struct perf_event *event);
-
-static bool is_uncore_event(struct perf_event *event)
-{
-	return event->pmu->event_init == uncore_pmu_event_init;
-}
-
-static int
-uncore_collect_events(struct intel_uncore_box *box, struct perf_event *leader, bool dogrp)
-{
-	struct perf_event *event;
-	int n, max_count;
-
-	max_count = box->pmu->type->num_counters;
-	if (box->pmu->type->fixed_ctl)
-		max_count++;
-
-	if (box->n_events >= max_count)
-		return -EINVAL;
-
-	n = box->n_events;
-
-	if (is_uncore_event(leader)) {
-		box->event_list[n] = leader;
-		n++;
-	}
-
-	if (!dogrp)
-		return n;
-
-	list_for_each_entry(event, &leader->sibling_list, group_entry) {
-		if (!is_uncore_event(event) ||
-		    event->state <= PERF_EVENT_STATE_OFF)
-			continue;
-
-		if (n >= max_count)
-			return -EINVAL;
-
-		box->event_list[n] = event;
-		n++;
-	}
-	return n;
-}
-
-static struct event_constraint *
-uncore_get_event_constraint(struct intel_uncore_box *box, struct perf_event *event)
-{
-	struct intel_uncore_type *type = box->pmu->type;
-	struct event_constraint *c;
-
-	if (type->ops->get_constraint) {
-		c = type->ops->get_constraint(box, event);
-		if (c)
-			return c;
-	}
-
-	if (event->attr.config == UNCORE_FIXED_EVENT)
-		return &uncore_constraint_fixed;
-
-	if (type->constraints) {
-		for_each_event_constraint(c, type->constraints) {
-			if ((event->hw.config & c->cmask) == c->code)
-				return c;
-		}
-	}
-
-	return &type->unconstrainted;
-}
-
-static void uncore_put_event_constraint(struct intel_uncore_box *box, struct perf_event *event)
-{
-	if (box->pmu->type->ops->put_constraint)
-		box->pmu->type->ops->put_constraint(box, event);
-}
-
-static int uncore_assign_events(struct intel_uncore_box *box, int assign[], int n)
-{
-	unsigned long used_mask[BITS_TO_LONGS(UNCORE_PMC_IDX_MAX)];
-	struct event_constraint *c;
-	int i, wmin, wmax, ret = 0;
-	struct hw_perf_event *hwc;
-
-	bitmap_zero(used_mask, UNCORE_PMC_IDX_MAX);
-
-	for (i = 0, wmin = UNCORE_PMC_IDX_MAX, wmax = 0; i < n; i++) {
-		c = uncore_get_event_constraint(box, box->event_list[i]);
-		box->event_constraint[i] = c;
-		wmin = min(wmin, c->weight);
-		wmax = max(wmax, c->weight);
-	}
-
-	/* fastpath, try to reuse previous register */
-	for (i = 0; i < n; i++) {
-		hwc = &box->event_list[i]->hw;
-		c = box->event_constraint[i];
-
-		/* never assigned */
-		if (hwc->idx == -1)
-			break;
-
-		/* constraint still honored */
-		if (!test_bit(hwc->idx, c->idxmsk))
-			break;
-
-		/* not already used */
-		if (test_bit(hwc->idx, used_mask))
-			break;
-
-		__set_bit(hwc->idx, used_mask);
-		if (assign)
-			assign[i] = hwc->idx;
-	}
-	/* slow path */
-	if (i != n)
-		ret = perf_assign_events(box->event_constraint, n,
-					 wmin, wmax, n, assign);
-
-	if (!assign || ret) {
-		for (i = 0; i < n; i++)
-			uncore_put_event_constraint(box, box->event_list[i]);
-	}
-	return ret ? -EINVAL : 0;
-}
-
-static void uncore_pmu_event_start(struct perf_event *event, int flags)
-{
-	struct intel_uncore_box *box = uncore_event_to_box(event);
-	int idx = event->hw.idx;
-
-	if (WARN_ON_ONCE(!(event->hw.state & PERF_HES_STOPPED)))
-		return;
-
-	if (WARN_ON_ONCE(idx == -1 || idx >= UNCORE_PMC_IDX_MAX))
-		return;
-
-	event->hw.state = 0;
-	box->events[idx] = event;
-	box->n_active++;
-	__set_bit(idx, box->active_mask);
-
-	local64_set(&event->hw.prev_count, uncore_read_counter(box, event));
-	uncore_enable_event(box, event);
-
-	if (box->n_active == 1) {
-		uncore_enable_box(box);
-		uncore_pmu_start_hrtimer(box);
-	}
-}
-
-static void uncore_pmu_event_stop(struct perf_event *event, int flags)
-{
-	struct intel_uncore_box *box = uncore_event_to_box(event);
-	struct hw_perf_event *hwc = &event->hw;
-
-	if (__test_and_clear_bit(hwc->idx, box->active_mask)) {
-		uncore_disable_event(box, event);
-		box->n_active--;
-		box->events[hwc->idx] = NULL;
-		WARN_ON_ONCE(hwc->state & PERF_HES_STOPPED);
-		hwc->state |= PERF_HES_STOPPED;
-
-		if (box->n_active == 0) {
-			uncore_disable_box(box);
-			uncore_pmu_cancel_hrtimer(box);
-		}
-	}
-
-	if ((flags & PERF_EF_UPDATE) && !(hwc->state & PERF_HES_UPTODATE)) {
-		/*
-		 * Drain the remaining delta count out of a event
-		 * that we are disabling:
-		 */
-		uncore_perf_event_update(box, event);
-		hwc->state |= PERF_HES_UPTODATE;
-	}
-}
-
-static int uncore_pmu_event_add(struct perf_event *event, int flags)
-{
-	struct intel_uncore_box *box = uncore_event_to_box(event);
-	struct hw_perf_event *hwc = &event->hw;
-	int assign[UNCORE_PMC_IDX_MAX];
-	int i, n, ret;
-
-	if (!box)
-		return -ENODEV;
-
-	ret = n = uncore_collect_events(box, event, false);
-	if (ret < 0)
-		return ret;
-
-	hwc->state = PERF_HES_UPTODATE | PERF_HES_STOPPED;
-	if (!(flags & PERF_EF_START))
-		hwc->state |= PERF_HES_ARCH;
-
-	ret = uncore_assign_events(box, assign, n);
-	if (ret)
-		return ret;
-
-	/* save events moving to new counters */
-	for (i = 0; i < box->n_events; i++) {
-		event = box->event_list[i];
-		hwc = &event->hw;
-
-		if (hwc->idx == assign[i] &&
-			hwc->last_tag == box->tags[assign[i]])
-			continue;
-		/*
-		 * Ensure we don't accidentally enable a stopped
-		 * counter simply because we rescheduled.
-		 */
-		if (hwc->state & PERF_HES_STOPPED)
-			hwc->state |= PERF_HES_ARCH;
-
-		uncore_pmu_event_stop(event, PERF_EF_UPDATE);
-	}
-
-	/* reprogram moved events into new counters */
-	for (i = 0; i < n; i++) {
-		event = box->event_list[i];
-		hwc = &event->hw;
-
-		if (hwc->idx != assign[i] ||
-			hwc->last_tag != box->tags[assign[i]])
-			uncore_assign_hw_event(box, event, assign[i]);
-		else if (i < box->n_events)
-			continue;
-
-		if (hwc->state & PERF_HES_ARCH)
-			continue;
-
-		uncore_pmu_event_start(event, 0);
-	}
-	box->n_events = n;
-
-	return 0;
-}
-
-static void uncore_pmu_event_del(struct perf_event *event, int flags)
-{
-	struct intel_uncore_box *box = uncore_event_to_box(event);
-	int i;
-
-	uncore_pmu_event_stop(event, PERF_EF_UPDATE);
-
-	for (i = 0; i < box->n_events; i++) {
-		if (event == box->event_list[i]) {
-			uncore_put_event_constraint(box, event);
-
-			while (++i < box->n_events)
-				box->event_list[i - 1] = box->event_list[i];
-
-			--box->n_events;
-			break;
-		}
-	}
-
-	event->hw.idx = -1;
-	event->hw.last_tag = ~0ULL;
-}
-
-void uncore_pmu_event_read(struct perf_event *event)
-{
-	struct intel_uncore_box *box = uncore_event_to_box(event);
-	uncore_perf_event_update(box, event);
-}
-
-/*
- * validation ensures the group can be loaded onto the
- * PMU if it was the only group available.
- */
-static int uncore_validate_group(struct intel_uncore_pmu *pmu,
-				struct perf_event *event)
-{
-	struct perf_event *leader = event->group_leader;
-	struct intel_uncore_box *fake_box;
-	int ret = -EINVAL, n;
-
-	fake_box = uncore_alloc_box(pmu->type, NUMA_NO_NODE);
-	if (!fake_box)
-		return -ENOMEM;
-
-	fake_box->pmu = pmu;
-	/*
-	 * the event is not yet connected with its
-	 * siblings therefore we must first collect
-	 * existing siblings, then add the new event
-	 * before we can simulate the scheduling
-	 */
-	n = uncore_collect_events(fake_box, leader, true);
-	if (n < 0)
-		goto out;
-
-	fake_box->n_events = n;
-	n = uncore_collect_events(fake_box, event, false);
-	if (n < 0)
-		goto out;
-
-	fake_box->n_events = n;
-
-	ret = uncore_assign_events(fake_box, NULL, n);
-out:
-	kfree(fake_box);
-	return ret;
-}
-
-static int uncore_pmu_event_init(struct perf_event *event)
-{
-	struct intel_uncore_pmu *pmu;
-	struct intel_uncore_box *box;
-	struct hw_perf_event *hwc = &event->hw;
-	int ret;
-
-	if (event->attr.type != event->pmu->type)
-		return -ENOENT;
-
-	pmu = uncore_event_to_pmu(event);
-	/* no device found for this pmu */
-	if (pmu->func_id < 0)
-		return -ENOENT;
-
-	/*
-	 * Uncore PMU does measure at all privilege level all the time.
-	 * So it doesn't make sense to specify any exclude bits.
-	 */
-	if (event->attr.exclude_user || event->attr.exclude_kernel ||
-			event->attr.exclude_hv || event->attr.exclude_idle)
-		return -EINVAL;
-
-	/* Sampling not supported yet */
-	if (hwc->sample_period)
-		return -EINVAL;
-
-	/*
-	 * Place all uncore events for a particular physical package
-	 * onto a single cpu
-	 */
-	if (event->cpu < 0)
-		return -EINVAL;
-	box = uncore_pmu_to_box(pmu, event->cpu);
-	if (!box || box->cpu < 0)
-		return -EINVAL;
-	event->cpu = box->cpu;
-
-	event->hw.idx = -1;
-	event->hw.last_tag = ~0ULL;
-	event->hw.extra_reg.idx = EXTRA_REG_NONE;
-	event->hw.branch_reg.idx = EXTRA_REG_NONE;
-
-	if (event->attr.config == UNCORE_FIXED_EVENT) {
-		/* no fixed counter */
-		if (!pmu->type->fixed_ctl)
-			return -EINVAL;
-		/*
-		 * if there is only one fixed counter, only the first pmu
-		 * can access the fixed counter
-		 */
-		if (pmu->type->single_fixed && pmu->pmu_idx > 0)
-			return -EINVAL;
-
-		/* fixed counters have event field hardcoded to zero */
-		hwc->config = 0ULL;
-	} else {
-		hwc->config = event->attr.config & pmu->type->event_mask;
-		if (pmu->type->ops->hw_config) {
-			ret = pmu->type->ops->hw_config(box, event);
-			if (ret)
-				return ret;
-		}
-	}
-
-	if (event->group_leader != event)
-		ret = uncore_validate_group(pmu, event);
-	else
-		ret = 0;
-
-	return ret;
-}
-
-static ssize_t uncore_get_attr_cpumask(struct device *dev,
-				struct device_attribute *attr, char *buf)
-{
-	return cpumap_print_to_pagebuf(true, buf, &uncore_cpu_mask);
-}
-
-static DEVICE_ATTR(cpumask, S_IRUGO, uncore_get_attr_cpumask, NULL);
-
-static struct attribute *uncore_pmu_attrs[] = {
-	&dev_attr_cpumask.attr,
-	NULL,
-};
-
-static struct attribute_group uncore_pmu_attr_group = {
-	.attrs = uncore_pmu_attrs,
-};
-
-static int uncore_pmu_register(struct intel_uncore_pmu *pmu)
-{
-	int ret;
-
-	if (!pmu->type->pmu) {
-		pmu->pmu = (struct pmu) {
-			.attr_groups	= pmu->type->attr_groups,
-			.task_ctx_nr	= perf_invalid_context,
-			.event_init	= uncore_pmu_event_init,
-			.add		= uncore_pmu_event_add,
-			.del		= uncore_pmu_event_del,
-			.start		= uncore_pmu_event_start,
-			.stop		= uncore_pmu_event_stop,
-			.read		= uncore_pmu_event_read,
-		};
-	} else {
-		pmu->pmu = *pmu->type->pmu;
-		pmu->pmu.attr_groups = pmu->type->attr_groups;
-	}
-
-	if (pmu->type->num_boxes == 1) {
-		if (strlen(pmu->type->name) > 0)
-			sprintf(pmu->name, "uncore_%s", pmu->type->name);
-		else
-			sprintf(pmu->name, "uncore");
-	} else {
-		sprintf(pmu->name, "uncore_%s_%d", pmu->type->name,
-			pmu->pmu_idx);
-	}
-
-	ret = perf_pmu_register(&pmu->pmu, pmu->name, -1);
-	return ret;
-}
-
-static void __init uncore_type_exit(struct intel_uncore_type *type)
-{
-	int i;
-
-	for (i = 0; i < type->num_boxes; i++)
-		free_percpu(type->pmus[i].box);
-	kfree(type->pmus);
-	type->pmus = NULL;
-	kfree(type->events_group);
-	type->events_group = NULL;
-}
-
-static void __init uncore_types_exit(struct intel_uncore_type **types)
-{
-	int i;
-	for (i = 0; types[i]; i++)
-		uncore_type_exit(types[i]);
-}
-
-static int __init uncore_type_init(struct intel_uncore_type *type)
-{
-	struct intel_uncore_pmu *pmus;
-	struct attribute_group *attr_group;
-	struct attribute **attrs;
-	int i, j;
-
-	pmus = kzalloc(sizeof(*pmus) * type->num_boxes, GFP_KERNEL);
-	if (!pmus)
-		return -ENOMEM;
-
-	type->pmus = pmus;
-
-	type->unconstrainted = (struct event_constraint)
-		__EVENT_CONSTRAINT(0, (1ULL << type->num_counters) - 1,
-				0, type->num_counters, 0, 0);
-
-	for (i = 0; i < type->num_boxes; i++) {
-		pmus[i].func_id = -1;
-		pmus[i].pmu_idx = i;
-		pmus[i].type = type;
-		INIT_LIST_HEAD(&pmus[i].box_list);
-		pmus[i].box = alloc_percpu(struct intel_uncore_box *);
-		if (!pmus[i].box)
-			goto fail;
-	}
-
-	if (type->event_descs) {
-		i = 0;
-		while (type->event_descs[i].attr.attr.name)
-			i++;
-
-		attr_group = kzalloc(sizeof(struct attribute *) * (i + 1) +
-					sizeof(*attr_group), GFP_KERNEL);
-		if (!attr_group)
-			goto fail;
-
-		attrs = (struct attribute **)(attr_group + 1);
-		attr_group->name = "events";
-		attr_group->attrs = attrs;
-
-		for (j = 0; j < i; j++)
-			attrs[j] = &type->event_descs[j].attr.attr;
-
-		type->events_group = attr_group;
-	}
-
-	type->pmu_group = &uncore_pmu_attr_group;
-	return 0;
-fail:
-	uncore_type_exit(type);
-	return -ENOMEM;
-}
-
-static int __init uncore_types_init(struct intel_uncore_type **types)
-{
-	int i, ret;
-
-	for (i = 0; types[i]; i++) {
-		ret = uncore_type_init(types[i]);
-		if (ret)
-			goto fail;
-	}
-	return 0;
-fail:
-	while (--i >= 0)
-		uncore_type_exit(types[i]);
-	return ret;
-}
-
-/*
- * add a pci uncore device
- */
-static int uncore_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
-{
-	struct intel_uncore_pmu *pmu;
-	struct intel_uncore_box *box;
-	struct intel_uncore_type *type;
-	int phys_id;
-	bool first_box = false;
-
-	phys_id = uncore_pcibus_to_physid(pdev->bus);
-	if (phys_id < 0)
-		return -ENODEV;
-
-	if (UNCORE_PCI_DEV_TYPE(id->driver_data) == UNCORE_EXTRA_PCI_DEV) {
-		int idx = UNCORE_PCI_DEV_IDX(id->driver_data);
-		uncore_extra_pci_dev[phys_id][idx] = pdev;
-		pci_set_drvdata(pdev, NULL);
-		return 0;
-	}
-
-	type = uncore_pci_uncores[UNCORE_PCI_DEV_TYPE(id->driver_data)];
-	box = uncore_alloc_box(type, NUMA_NO_NODE);
-	if (!box)
-		return -ENOMEM;
-
-	/*
-	 * for performance monitoring unit with multiple boxes,
-	 * each box has a different function id.
-	 */
-	pmu = &type->pmus[UNCORE_PCI_DEV_IDX(id->driver_data)];
-	if (pmu->func_id < 0)
-		pmu->func_id = pdev->devfn;
-	else
-		WARN_ON_ONCE(pmu->func_id != pdev->devfn);
-
-	box->phys_id = phys_id;
-	box->pci_dev = pdev;
-	box->pmu = pmu;
-	uncore_box_init(box);
-	pci_set_drvdata(pdev, box);
-
-	raw_spin_lock(&uncore_box_lock);
-	if (list_empty(&pmu->box_list))
-		first_box = true;
-	list_add_tail(&box->list, &pmu->box_list);
-	raw_spin_unlock(&uncore_box_lock);
-
-	if (first_box)
-		uncore_pmu_register(pmu);
-	return 0;
-}
-
-static void uncore_pci_remove(struct pci_dev *pdev)
-{
-	struct intel_uncore_box *box = pci_get_drvdata(pdev);
-	struct intel_uncore_pmu *pmu;
-	int i, cpu, phys_id;
-	bool last_box = false;
-
-	phys_id = uncore_pcibus_to_physid(pdev->bus);
-	box = pci_get_drvdata(pdev);
-	if (!box) {
-		for (i = 0; i < UNCORE_EXTRA_PCI_DEV_MAX; i++) {
-			if (uncore_extra_pci_dev[phys_id][i] == pdev) {
-				uncore_extra_pci_dev[phys_id][i] = NULL;
-				break;
-			}
-		}
-		WARN_ON_ONCE(i >= UNCORE_EXTRA_PCI_DEV_MAX);
-		return;
-	}
-
-	pmu = box->pmu;
-	if (WARN_ON_ONCE(phys_id != box->phys_id))
-		return;
-
-	pci_set_drvdata(pdev, NULL);
-
-	raw_spin_lock(&uncore_box_lock);
-	list_del(&box->list);
-	if (list_empty(&pmu->box_list))
-		last_box = true;
-	raw_spin_unlock(&uncore_box_lock);
-
-	for_each_possible_cpu(cpu) {
-		if (*per_cpu_ptr(pmu->box, cpu) == box) {
-			*per_cpu_ptr(pmu->box, cpu) = NULL;
-			atomic_dec(&box->refcnt);
-		}
-	}
-
-	WARN_ON_ONCE(atomic_read(&box->refcnt) != 1);
-	kfree(box);
-
-	if (last_box)
-		perf_pmu_unregister(&pmu->pmu);
-}
-
-static int __init uncore_pci_init(void)
-{
-	int ret;
-
-	switch (boot_cpu_data.x86_model) {
-	case 45: /* Sandy Bridge-EP */
-		ret = snbep_uncore_pci_init();
-		break;
-	case 62: /* Ivy Bridge-EP */
-		ret = ivbep_uncore_pci_init();
-		break;
-	case 63: /* Haswell-EP */
-		ret = hswep_uncore_pci_init();
-		break;
-	case 86: /* BDX-DE */
-		ret = bdx_uncore_pci_init();
-		break;
-	case 42: /* Sandy Bridge */
-		ret = snb_uncore_pci_init();
-		break;
-	case 58: /* Ivy Bridge */
-		ret = ivb_uncore_pci_init();
-		break;
-	case 60: /* Haswell */
-	case 69: /* Haswell Celeron */
-		ret = hsw_uncore_pci_init();
-		break;
-	case 61: /* Broadwell */
-		ret = bdw_uncore_pci_init();
-		break;
-	default:
-		return 0;
-	}
-
-	if (ret)
-		return ret;
-
-	ret = uncore_types_init(uncore_pci_uncores);
-	if (ret)
-		return ret;
-
-	uncore_pci_driver->probe = uncore_pci_probe;
-	uncore_pci_driver->remove = uncore_pci_remove;
-
-	ret = pci_register_driver(uncore_pci_driver);
-	if (ret == 0)
-		pcidrv_registered = true;
-	else
-		uncore_types_exit(uncore_pci_uncores);
-
-	return ret;
-}
-
-static void __init uncore_pci_exit(void)
-{
-	if (pcidrv_registered) {
-		pcidrv_registered = false;
-		pci_unregister_driver(uncore_pci_driver);
-		uncore_types_exit(uncore_pci_uncores);
-	}
-}
-
-/* CPU hot plug/unplug are serialized by cpu_add_remove_lock mutex */
-static LIST_HEAD(boxes_to_free);
-
-static void uncore_kfree_boxes(void)
-{
-	struct intel_uncore_box *box;
-
-	while (!list_empty(&boxes_to_free)) {
-		box = list_entry(boxes_to_free.next,
-				 struct intel_uncore_box, list);
-		list_del(&box->list);
-		kfree(box);
-	}
-}
-
-static void uncore_cpu_dying(int cpu)
-{
-	struct intel_uncore_type *type;
-	struct intel_uncore_pmu *pmu;
-	struct intel_uncore_box *box;
-	int i, j;
-
-	for (i = 0; uncore_msr_uncores[i]; i++) {
-		type = uncore_msr_uncores[i];
-		for (j = 0; j < type->num_boxes; j++) {
-			pmu = &type->pmus[j];
-			box = *per_cpu_ptr(pmu->box, cpu);
-			*per_cpu_ptr(pmu->box, cpu) = NULL;
-			if (box && atomic_dec_and_test(&box->refcnt))
-				list_add(&box->list, &boxes_to_free);
-		}
-	}
-}
-
-static int uncore_cpu_starting(int cpu)
-{
-	struct intel_uncore_type *type;
-	struct intel_uncore_pmu *pmu;
-	struct intel_uncore_box *box, *exist;
-	int i, j, k, phys_id;
-
-	phys_id = topology_physical_package_id(cpu);
-
-	for (i = 0; uncore_msr_uncores[i]; i++) {
-		type = uncore_msr_uncores[i];
-		for (j = 0; j < type->num_boxes; j++) {
-			pmu = &type->pmus[j];
-			box = *per_cpu_ptr(pmu->box, cpu);
-			/* called by uncore_cpu_init? */
-			if (box && box->phys_id >= 0) {
-				uncore_box_init(box);
-				continue;
-			}
-
-			for_each_online_cpu(k) {
-				exist = *per_cpu_ptr(pmu->box, k);
-				if (exist && exist->phys_id == phys_id) {
-					atomic_inc(&exist->refcnt);
-					*per_cpu_ptr(pmu->box, cpu) = exist;
-					if (box) {
-						list_add(&box->list,
-							 &boxes_to_free);
-						box = NULL;
-					}
-					break;
-				}
-			}
-
-			if (box) {
-				box->phys_id = phys_id;
-				uncore_box_init(box);
-			}
-		}
-	}
-	return 0;
-}
-
-static int uncore_cpu_prepare(int cpu, int phys_id)
-{
-	struct intel_uncore_type *type;
-	struct intel_uncore_pmu *pmu;
-	struct intel_uncore_box *box;
-	int i, j;
-
-	for (i = 0; uncore_msr_uncores[i]; i++) {
-		type = uncore_msr_uncores[i];
-		for (j = 0; j < type->num_boxes; j++) {
-			pmu = &type->pmus[j];
-			if (pmu->func_id < 0)
-				pmu->func_id = j;
-
-			box = uncore_alloc_box(type, cpu_to_node(cpu));
-			if (!box)
-				return -ENOMEM;
-
-			box->pmu = pmu;
-			box->phys_id = phys_id;
-			*per_cpu_ptr(pmu->box, cpu) = box;
-		}
-	}
-	return 0;
-}
-
-static void
-uncore_change_context(struct intel_uncore_type **uncores, int old_cpu, int new_cpu)
-{
-	struct intel_uncore_type *type;
-	struct intel_uncore_pmu *pmu;
-	struct intel_uncore_box *box;
-	int i, j;
-
-	for (i = 0; uncores[i]; i++) {
-		type = uncores[i];
-		for (j = 0; j < type->num_boxes; j++) {
-			pmu = &type->pmus[j];
-			if (old_cpu < 0)
-				box = uncore_pmu_to_box(pmu, new_cpu);
-			else
-				box = uncore_pmu_to_box(pmu, old_cpu);
-			if (!box)
-				continue;
-
-			if (old_cpu < 0) {
-				WARN_ON_ONCE(box->cpu != -1);
-				box->cpu = new_cpu;
-				continue;
-			}
-
-			WARN_ON_ONCE(box->cpu != old_cpu);
-			if (new_cpu >= 0) {
-				uncore_pmu_cancel_hrtimer(box);
-				perf_pmu_migrate_context(&pmu->pmu,
-						old_cpu, new_cpu);
-				box->cpu = new_cpu;
-			} else {
-				box->cpu = -1;
-			}
-		}
-	}
-}
-
-static void uncore_event_exit_cpu(int cpu)
-{
-	int i, phys_id, target;
-
-	/* if exiting cpu is used for collecting uncore events */
-	if (!cpumask_test_and_clear_cpu(cpu, &uncore_cpu_mask))
-		return;
-
-	/* find a new cpu to collect uncore events */
-	phys_id = topology_physical_package_id(cpu);
-	target = -1;
-	for_each_online_cpu(i) {
-		if (i == cpu)
-			continue;
-		if (phys_id == topology_physical_package_id(i)) {
-			target = i;
-			break;
-		}
-	}
-
-	/* migrate uncore events to the new cpu */
-	if (target >= 0)
-		cpumask_set_cpu(target, &uncore_cpu_mask);
-
-	uncore_change_context(uncore_msr_uncores, cpu, target);
-	uncore_change_context(uncore_pci_uncores, cpu, target);
-}
-
-static void uncore_event_init_cpu(int cpu)
-{
-	int i, phys_id;
-
-	phys_id = topology_physical_package_id(cpu);
-	for_each_cpu(i, &uncore_cpu_mask) {
-		if (phys_id == topology_physical_package_id(i))
-			return;
-	}
-
-	cpumask_set_cpu(cpu, &uncore_cpu_mask);
-
-	uncore_change_context(uncore_msr_uncores, -1, cpu);
-	uncore_change_context(uncore_pci_uncores, -1, cpu);
-}
-
-static int uncore_cpu_notifier(struct notifier_block *self,
-			       unsigned long action, void *hcpu)
-{
-	unsigned int cpu = (long)hcpu;
-
-	/* allocate/free data structure for uncore box */
-	switch (action & ~CPU_TASKS_FROZEN) {
-	case CPU_UP_PREPARE:
-		uncore_cpu_prepare(cpu, -1);
-		break;
-	case CPU_STARTING:
-		uncore_cpu_starting(cpu);
-		break;
-	case CPU_UP_CANCELED:
-	case CPU_DYING:
-		uncore_cpu_dying(cpu);
-		break;
-	case CPU_ONLINE:
-	case CPU_DEAD:
-		uncore_kfree_boxes();
-		break;
-	default:
-		break;
-	}
-
-	/* select the cpu that collects uncore events */
-	switch (action & ~CPU_TASKS_FROZEN) {
-	case CPU_DOWN_FAILED:
-	case CPU_STARTING:
-		uncore_event_init_cpu(cpu);
-		break;
-	case CPU_DOWN_PREPARE:
-		uncore_event_exit_cpu(cpu);
-		break;
-	default:
-		break;
-	}
-
-	return NOTIFY_OK;
-}
-
-static struct notifier_block uncore_cpu_nb = {
-	.notifier_call	= uncore_cpu_notifier,
-	/*
-	 * to migrate uncore events, our notifier should be executed
-	 * before perf core's notifier.
-	 */
-	.priority	= CPU_PRI_PERF + 1,
-};
-
-static void __init uncore_cpu_setup(void *dummy)
-{
-	uncore_cpu_starting(smp_processor_id());
-}
-
-static int __init uncore_cpu_init(void)
-{
-	int ret;
-
-	switch (boot_cpu_data.x86_model) {
-	case 26: /* Nehalem */
-	case 30:
-	case 37: /* Westmere */
-	case 44:
-		nhm_uncore_cpu_init();
-		break;
-	case 42: /* Sandy Bridge */
-	case 58: /* Ivy Bridge */
-	case 60: /* Haswell */
-	case 69: /* Haswell */
-	case 70: /* Haswell */
-	case 61: /* Broadwell */
-	case 71: /* Broadwell */
-		snb_uncore_cpu_init();
-		break;
-	case 45: /* Sandy Bridge-EP */
-		snbep_uncore_cpu_init();
-		break;
-	case 46: /* Nehalem-EX */
-	case 47: /* Westmere-EX aka. Xeon E7 */
-		nhmex_uncore_cpu_init();
-		break;
-	case 62: /* Ivy Bridge-EP */
-		ivbep_uncore_cpu_init();
-		break;
-	case 63: /* Haswell-EP */
-		hswep_uncore_cpu_init();
-		break;
-	case 86: /* BDX-DE */
-		bdx_uncore_cpu_init();
-		break;
-	default:
-		return 0;
-	}
-
-	ret = uncore_types_init(uncore_msr_uncores);
-	if (ret)
-		return ret;
-
-	return 0;
-}
-
-static int __init uncore_pmus_register(void)
-{
-	struct intel_uncore_pmu *pmu;
-	struct intel_uncore_type *type;
-	int i, j;
-
-	for (i = 0; uncore_msr_uncores[i]; i++) {
-		type = uncore_msr_uncores[i];
-		for (j = 0; j < type->num_boxes; j++) {
-			pmu = &type->pmus[j];
-			uncore_pmu_register(pmu);
-		}
-	}
-
-	return 0;
-}
-
-static void __init uncore_cpumask_init(void)
-{
-	int cpu;
-
-	/*
-	 * ony invoke once from msr or pci init code
-	 */
-	if (!cpumask_empty(&uncore_cpu_mask))
-		return;
-
-	cpu_notifier_register_begin();
-
-	for_each_online_cpu(cpu) {
-		int i, phys_id = topology_physical_package_id(cpu);
-
-		for_each_cpu(i, &uncore_cpu_mask) {
-			if (phys_id == topology_physical_package_id(i)) {
-				phys_id = -1;
-				break;
-			}
-		}
-		if (phys_id < 0)
-			continue;
-
-		uncore_cpu_prepare(cpu, phys_id);
-		uncore_event_init_cpu(cpu);
-	}
-	on_each_cpu(uncore_cpu_setup, NULL, 1);
-
-	__register_cpu_notifier(&uncore_cpu_nb);
-
-	cpu_notifier_register_done();
-}
-
-
-static int __init intel_uncore_init(void)
-{
-	int ret;
-
-	if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL)
-		return -ENODEV;
-
-	if (cpu_has_hypervisor)
-		return -ENODEV;
-
-	ret = uncore_pci_init();
-	if (ret)
-		goto fail;
-	ret = uncore_cpu_init();
-	if (ret) {
-		uncore_pci_exit();
-		goto fail;
-	}
-	uncore_cpumask_init();
-
-	uncore_pmus_register();
-	return 0;
-fail:
-	return ret;
-}
-device_initcall(intel_uncore_init);
--- zfcpdump-kernel-4.4.orig/arch/x86/kernel/cpu/perf_event_intel_uncore.h
+++ /dev/null
@@ -1,353 +0,0 @@
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/pci.h>
-#include <linux/perf_event.h>
-#include "perf_event.h"
-
-#define UNCORE_PMU_NAME_LEN		32
-#define UNCORE_PMU_HRTIMER_INTERVAL	(60LL * NSEC_PER_SEC)
-#define UNCORE_SNB_IMC_HRTIMER_INTERVAL (5ULL * NSEC_PER_SEC)
-
-#define UNCORE_FIXED_EVENT		0xff
-#define UNCORE_PMC_IDX_MAX_GENERIC	8
-#define UNCORE_PMC_IDX_FIXED		UNCORE_PMC_IDX_MAX_GENERIC
-#define UNCORE_PMC_IDX_MAX		(UNCORE_PMC_IDX_FIXED + 1)
-
-#define UNCORE_PCI_DEV_DATA(type, idx)	((type << 8) | idx)
-#define UNCORE_PCI_DEV_TYPE(data)	((data >> 8) & 0xff)
-#define UNCORE_PCI_DEV_IDX(data)	(data & 0xff)
-#define UNCORE_EXTRA_PCI_DEV		0xff
-#define UNCORE_EXTRA_PCI_DEV_MAX	3
-
-/* support up to 8 sockets */
-#define UNCORE_SOCKET_MAX		8
-
-#define UNCORE_EVENT_CONSTRAINT(c, n) EVENT_CONSTRAINT(c, n, 0xff)
-
-struct intel_uncore_ops;
-struct intel_uncore_pmu;
-struct intel_uncore_box;
-struct uncore_event_desc;
-
-struct intel_uncore_type {
-	const char *name;
-	int num_counters;
-	int num_boxes;
-	int perf_ctr_bits;
-	int fixed_ctr_bits;
-	unsigned perf_ctr;
-	unsigned event_ctl;
-	unsigned event_mask;
-	unsigned fixed_ctr;
-	unsigned fixed_ctl;
-	unsigned box_ctl;
-	unsigned msr_offset;
-	unsigned num_shared_regs:8;
-	unsigned single_fixed:1;
-	unsigned pair_ctr_ctl:1;
-	unsigned *msr_offsets;
-	struct event_constraint unconstrainted;
-	struct event_constraint *constraints;
-	struct intel_uncore_pmu *pmus;
-	struct intel_uncore_ops *ops;
-	struct uncore_event_desc *event_descs;
-	const struct attribute_group *attr_groups[4];
-	struct pmu *pmu; /* for custom pmu ops */
-};
-
-#define pmu_group attr_groups[0]
-#define format_group attr_groups[1]
-#define events_group attr_groups[2]
-
-struct intel_uncore_ops {
-	void (*init_box)(struct intel_uncore_box *);
-	void (*disable_box)(struct intel_uncore_box *);
-	void (*enable_box)(struct intel_uncore_box *);
-	void (*disable_event)(struct intel_uncore_box *, struct perf_event *);
-	void (*enable_event)(struct intel_uncore_box *, struct perf_event *);
-	u64 (*read_counter)(struct intel_uncore_box *, struct perf_event *);
-	int (*hw_config)(struct intel_uncore_box *, struct perf_event *);
-	struct event_constraint *(*get_constraint)(struct intel_uncore_box *,
-						   struct perf_event *);
-	void (*put_constraint)(struct intel_uncore_box *, struct perf_event *);
-};
-
-struct intel_uncore_pmu {
-	struct pmu pmu;
-	char name[UNCORE_PMU_NAME_LEN];
-	int pmu_idx;
-	int func_id;
-	struct intel_uncore_type *type;
-	struct intel_uncore_box ** __percpu box;
-	struct list_head box_list;
-};
-
-struct intel_uncore_extra_reg {
-	raw_spinlock_t lock;
-	u64 config, config1, config2;
-	atomic_t ref;
-};
-
-struct intel_uncore_box {
-	int phys_id;
-	int n_active;	/* number of active events */
-	int n_events;
-	int cpu;	/* cpu to collect events */
-	unsigned long flags;
-	atomic_t refcnt;
-	struct perf_event *events[UNCORE_PMC_IDX_MAX];
-	struct perf_event *event_list[UNCORE_PMC_IDX_MAX];
-	struct event_constraint *event_constraint[UNCORE_PMC_IDX_MAX];
-	unsigned long active_mask[BITS_TO_LONGS(UNCORE_PMC_IDX_MAX)];
-	u64 tags[UNCORE_PMC_IDX_MAX];
-	struct pci_dev *pci_dev;
-	struct intel_uncore_pmu *pmu;
-	u64 hrtimer_duration; /* hrtimer timeout for this box */
-	struct hrtimer hrtimer;
-	struct list_head list;
-	struct list_head active_list;
-	void *io_addr;
-	struct intel_uncore_extra_reg shared_regs[0];
-};
-
-#define UNCORE_BOX_FLAG_INITIATED	0
-
-struct uncore_event_desc {
-	struct kobj_attribute attr;
-	const char *config;
-};
-
-struct pci2phy_map {
-	struct list_head list;
-	int segment;
-	int pbus_to_physid[256];
-};
-
-int uncore_pcibus_to_physid(struct pci_bus *bus);
-struct pci2phy_map *__find_pci2phy_map(int segment);
-
-ssize_t uncore_event_show(struct kobject *kobj,
-			  struct kobj_attribute *attr, char *buf);
-
-#define INTEL_UNCORE_EVENT_DESC(_name, _config)			\
-{								\
-	.attr	= __ATTR(_name, 0444, uncore_event_show, NULL),	\
-	.config	= _config,					\
-}
-
-#define DEFINE_UNCORE_FORMAT_ATTR(_var, _name, _format)			\
-static ssize_t __uncore_##_var##_show(struct kobject *kobj,		\
-				struct kobj_attribute *attr,		\
-				char *page)				\
-{									\
-	BUILD_BUG_ON(sizeof(_format) >= PAGE_SIZE);			\
-	return sprintf(page, _format "\n");				\
-}									\
-static struct kobj_attribute format_attr_##_var =			\
-	__ATTR(_name, 0444, __uncore_##_var##_show, NULL)
-
-static inline unsigned uncore_pci_box_ctl(struct intel_uncore_box *box)
-{
-	return box->pmu->type->box_ctl;
-}
-
-static inline unsigned uncore_pci_fixed_ctl(struct intel_uncore_box *box)
-{
-	return box->pmu->type->fixed_ctl;
-}
-
-static inline unsigned uncore_pci_fixed_ctr(struct intel_uncore_box *box)
-{
-	return box->pmu->type->fixed_ctr;
-}
-
-static inline
-unsigned uncore_pci_event_ctl(struct intel_uncore_box *box, int idx)
-{
-	return idx * 4 + box->pmu->type->event_ctl;
-}
-
-static inline
-unsigned uncore_pci_perf_ctr(struct intel_uncore_box *box, int idx)
-{
-	return idx * 8 + box->pmu->type->perf_ctr;
-}
-
-static inline unsigned uncore_msr_box_offset(struct intel_uncore_box *box)
-{
-	struct intel_uncore_pmu *pmu = box->pmu;
-	return pmu->type->msr_offsets ?
-		pmu->type->msr_offsets[pmu->pmu_idx] :
-		pmu->type->msr_offset * pmu->pmu_idx;
-}
-
-static inline unsigned uncore_msr_box_ctl(struct intel_uncore_box *box)
-{
-	if (!box->pmu->type->box_ctl)
-		return 0;
-	return box->pmu->type->box_ctl + uncore_msr_box_offset(box);
-}
-
-static inline unsigned uncore_msr_fixed_ctl(struct intel_uncore_box *box)
-{
-	if (!box->pmu->type->fixed_ctl)
-		return 0;
-	return box->pmu->type->fixed_ctl + uncore_msr_box_offset(box);
-}
-
-static inline unsigned uncore_msr_fixed_ctr(struct intel_uncore_box *box)
-{
-	return box->pmu->type->fixed_ctr + uncore_msr_box_offset(box);
-}
-
-static inline
-unsigned uncore_msr_event_ctl(struct intel_uncore_box *box, int idx)
-{
-	return box->pmu->type->event_ctl +
-		(box->pmu->type->pair_ctr_ctl ? 2 * idx : idx) +
-		uncore_msr_box_offset(box);
-}
-
-static inline
-unsigned uncore_msr_perf_ctr(struct intel_uncore_box *box, int idx)
-{
-	return box->pmu->type->perf_ctr +
-		(box->pmu->type->pair_ctr_ctl ? 2 * idx : idx) +
-		uncore_msr_box_offset(box);
-}
-
-static inline
-unsigned uncore_fixed_ctl(struct intel_uncore_box *box)
-{
-	if (box->pci_dev)
-		return uncore_pci_fixed_ctl(box);
-	else
-		return uncore_msr_fixed_ctl(box);
-}
-
-static inline
-unsigned uncore_fixed_ctr(struct intel_uncore_box *box)
-{
-	if (box->pci_dev)
-		return uncore_pci_fixed_ctr(box);
-	else
-		return uncore_msr_fixed_ctr(box);
-}
-
-static inline
-unsigned uncore_event_ctl(struct intel_uncore_box *box, int idx)
-{
-	if (box->pci_dev)
-		return uncore_pci_event_ctl(box, idx);
-	else
-		return uncore_msr_event_ctl(box, idx);
-}
-
-static inline
-unsigned uncore_perf_ctr(struct intel_uncore_box *box, int idx)
-{
-	if (box->pci_dev)
-		return uncore_pci_perf_ctr(box, idx);
-	else
-		return uncore_msr_perf_ctr(box, idx);
-}
-
-static inline int uncore_perf_ctr_bits(struct intel_uncore_box *box)
-{
-	return box->pmu->type->perf_ctr_bits;
-}
-
-static inline int uncore_fixed_ctr_bits(struct intel_uncore_box *box)
-{
-	return box->pmu->type->fixed_ctr_bits;
-}
-
-static inline int uncore_num_counters(struct intel_uncore_box *box)
-{
-	return box->pmu->type->num_counters;
-}
-
-static inline void uncore_disable_box(struct intel_uncore_box *box)
-{
-	if (box->pmu->type->ops->disable_box)
-		box->pmu->type->ops->disable_box(box);
-}
-
-static inline void uncore_enable_box(struct intel_uncore_box *box)
-{
-	if (box->pmu->type->ops->enable_box)
-		box->pmu->type->ops->enable_box(box);
-}
-
-static inline void uncore_disable_event(struct intel_uncore_box *box,
-				struct perf_event *event)
-{
-	box->pmu->type->ops->disable_event(box, event);
-}
-
-static inline void uncore_enable_event(struct intel_uncore_box *box,
-				struct perf_event *event)
-{
-	box->pmu->type->ops->enable_event(box, event);
-}
-
-static inline u64 uncore_read_counter(struct intel_uncore_box *box,
-				struct perf_event *event)
-{
-	return box->pmu->type->ops->read_counter(box, event);
-}
-
-static inline void uncore_box_init(struct intel_uncore_box *box)
-{
-	if (!test_and_set_bit(UNCORE_BOX_FLAG_INITIATED, &box->flags)) {
-		if (box->pmu->type->ops->init_box)
-			box->pmu->type->ops->init_box(box);
-	}
-}
-
-static inline bool uncore_box_is_fake(struct intel_uncore_box *box)
-{
-	return (box->phys_id < 0);
-}
-
-struct intel_uncore_pmu *uncore_event_to_pmu(struct perf_event *event);
-struct intel_uncore_box *uncore_pmu_to_box(struct intel_uncore_pmu *pmu, int cpu);
-struct intel_uncore_box *uncore_event_to_box(struct perf_event *event);
-u64 uncore_msr_read_counter(struct intel_uncore_box *box, struct perf_event *event);
-void uncore_pmu_start_hrtimer(struct intel_uncore_box *box);
-void uncore_pmu_cancel_hrtimer(struct intel_uncore_box *box);
-void uncore_pmu_event_read(struct perf_event *event);
-void uncore_perf_event_update(struct intel_uncore_box *box, struct perf_event *event);
-struct event_constraint *
-uncore_get_constraint(struct intel_uncore_box *box, struct perf_event *event);
-void uncore_put_constraint(struct intel_uncore_box *box, struct perf_event *event);
-u64 uncore_shared_reg_config(struct intel_uncore_box *box, int idx);
-
-extern struct intel_uncore_type **uncore_msr_uncores;
-extern struct intel_uncore_type **uncore_pci_uncores;
-extern struct pci_driver *uncore_pci_driver;
-extern raw_spinlock_t pci2phy_map_lock;
-extern struct list_head pci2phy_map_head;
-extern struct pci_dev *uncore_extra_pci_dev[UNCORE_SOCKET_MAX][UNCORE_EXTRA_PCI_DEV_MAX];
-extern struct event_constraint uncore_constraint_empty;
-
-/* perf_event_intel_uncore_snb.c */
-int snb_uncore_pci_init(void);
-int ivb_uncore_pci_init(void);
-int hsw_uncore_pci_init(void);
-int bdw_uncore_pci_init(void);
-void snb_uncore_cpu_init(void);
-void nhm_uncore_cpu_init(void);
-
-/* perf_event_intel_uncore_snbep.c */
-int snbep_uncore_pci_init(void);
-void snbep_uncore_cpu_init(void);
-int ivbep_uncore_pci_init(void);
-void ivbep_uncore_cpu_init(void);
-int hswep_uncore_pci_init(void);
-void hswep_uncore_cpu_init(void);
-int bdx_uncore_pci_init(void);
-void bdx_uncore_cpu_init(void);
-
-/* perf_event_intel_uncore_nhmex.c */
-void nhmex_uncore_cpu_init(void);
--- zfcpdump-kernel-4.4.orig/arch/x86/kernel/cpu/perf_event_intel_uncore_nhmex.c
+++ /dev/null
@@ -1,1221 +0,0 @@
-/* Nehalem-EX/Westmere-EX uncore support */
-#include "perf_event_intel_uncore.h"
-
-/* NHM-EX event control */
-#define NHMEX_PMON_CTL_EV_SEL_MASK	0x000000ff
-#define NHMEX_PMON_CTL_UMASK_MASK	0x0000ff00
-#define NHMEX_PMON_CTL_EN_BIT0		(1 << 0)
-#define NHMEX_PMON_CTL_EDGE_DET		(1 << 18)
-#define NHMEX_PMON_CTL_PMI_EN		(1 << 20)
-#define NHMEX_PMON_CTL_EN_BIT22		(1 << 22)
-#define NHMEX_PMON_CTL_INVERT		(1 << 23)
-#define NHMEX_PMON_CTL_TRESH_MASK	0xff000000
-#define NHMEX_PMON_RAW_EVENT_MASK	(NHMEX_PMON_CTL_EV_SEL_MASK | \
-					 NHMEX_PMON_CTL_UMASK_MASK | \
-					 NHMEX_PMON_CTL_EDGE_DET | \
-					 NHMEX_PMON_CTL_INVERT | \
-					 NHMEX_PMON_CTL_TRESH_MASK)
-
-/* NHM-EX Ubox */
-#define NHMEX_U_MSR_PMON_GLOBAL_CTL		0xc00
-#define NHMEX_U_MSR_PMON_CTR			0xc11
-#define NHMEX_U_MSR_PMON_EV_SEL			0xc10
-
-#define NHMEX_U_PMON_GLOBAL_EN			(1 << 0)
-#define NHMEX_U_PMON_GLOBAL_PMI_CORE_SEL	0x0000001e
-#define NHMEX_U_PMON_GLOBAL_EN_ALL		(1 << 28)
-#define NHMEX_U_PMON_GLOBAL_RST_ALL		(1 << 29)
-#define NHMEX_U_PMON_GLOBAL_FRZ_ALL		(1 << 31)
-
-#define NHMEX_U_PMON_RAW_EVENT_MASK		\
-		(NHMEX_PMON_CTL_EV_SEL_MASK |	\
-		 NHMEX_PMON_CTL_EDGE_DET)
-
-/* NHM-EX Cbox */
-#define NHMEX_C0_MSR_PMON_GLOBAL_CTL		0xd00
-#define NHMEX_C0_MSR_PMON_CTR0			0xd11
-#define NHMEX_C0_MSR_PMON_EV_SEL0		0xd10
-#define NHMEX_C_MSR_OFFSET			0x20
-
-/* NHM-EX Bbox */
-#define NHMEX_B0_MSR_PMON_GLOBAL_CTL		0xc20
-#define NHMEX_B0_MSR_PMON_CTR0			0xc31
-#define NHMEX_B0_MSR_PMON_CTL0			0xc30
-#define NHMEX_B_MSR_OFFSET			0x40
-#define NHMEX_B0_MSR_MATCH			0xe45
-#define NHMEX_B0_MSR_MASK			0xe46
-#define NHMEX_B1_MSR_MATCH			0xe4d
-#define NHMEX_B1_MSR_MASK			0xe4e
-
-#define NHMEX_B_PMON_CTL_EN			(1 << 0)
-#define NHMEX_B_PMON_CTL_EV_SEL_SHIFT		1
-#define NHMEX_B_PMON_CTL_EV_SEL_MASK		\
-		(0x1f << NHMEX_B_PMON_CTL_EV_SEL_SHIFT)
-#define NHMEX_B_PMON_CTR_SHIFT		6
-#define NHMEX_B_PMON_CTR_MASK		\
-		(0x3 << NHMEX_B_PMON_CTR_SHIFT)
-#define NHMEX_B_PMON_RAW_EVENT_MASK		\
-		(NHMEX_B_PMON_CTL_EV_SEL_MASK | \
-		 NHMEX_B_PMON_CTR_MASK)
-
-/* NHM-EX Sbox */
-#define NHMEX_S0_MSR_PMON_GLOBAL_CTL		0xc40
-#define NHMEX_S0_MSR_PMON_CTR0			0xc51
-#define NHMEX_S0_MSR_PMON_CTL0			0xc50
-#define NHMEX_S_MSR_OFFSET			0x80
-#define NHMEX_S0_MSR_MM_CFG			0xe48
-#define NHMEX_S0_MSR_MATCH			0xe49
-#define NHMEX_S0_MSR_MASK			0xe4a
-#define NHMEX_S1_MSR_MM_CFG			0xe58
-#define NHMEX_S1_MSR_MATCH			0xe59
-#define NHMEX_S1_MSR_MASK			0xe5a
-
-#define NHMEX_S_PMON_MM_CFG_EN			(0x1ULL << 63)
-#define NHMEX_S_EVENT_TO_R_PROG_EV		0
-
-/* NHM-EX Mbox */
-#define NHMEX_M0_MSR_GLOBAL_CTL			0xca0
-#define NHMEX_M0_MSR_PMU_DSP			0xca5
-#define NHMEX_M0_MSR_PMU_ISS			0xca6
-#define NHMEX_M0_MSR_PMU_MAP			0xca7
-#define NHMEX_M0_MSR_PMU_MSC_THR		0xca8
-#define NHMEX_M0_MSR_PMU_PGT			0xca9
-#define NHMEX_M0_MSR_PMU_PLD			0xcaa
-#define NHMEX_M0_MSR_PMU_ZDP_CTL_FVC		0xcab
-#define NHMEX_M0_MSR_PMU_CTL0			0xcb0
-#define NHMEX_M0_MSR_PMU_CNT0			0xcb1
-#define NHMEX_M_MSR_OFFSET			0x40
-#define NHMEX_M0_MSR_PMU_MM_CFG			0xe54
-#define NHMEX_M1_MSR_PMU_MM_CFG			0xe5c
-
-#define NHMEX_M_PMON_MM_CFG_EN			(1ULL << 63)
-#define NHMEX_M_PMON_ADDR_MATCH_MASK		0x3ffffffffULL
-#define NHMEX_M_PMON_ADDR_MASK_MASK		0x7ffffffULL
-#define NHMEX_M_PMON_ADDR_MASK_SHIFT		34
-
-#define NHMEX_M_PMON_CTL_EN			(1 << 0)
-#define NHMEX_M_PMON_CTL_PMI_EN			(1 << 1)
-#define NHMEX_M_PMON_CTL_COUNT_MODE_SHIFT	2
-#define NHMEX_M_PMON_CTL_COUNT_MODE_MASK	\
-	(0x3 << NHMEX_M_PMON_CTL_COUNT_MODE_SHIFT)
-#define NHMEX_M_PMON_CTL_STORAGE_MODE_SHIFT	4
-#define NHMEX_M_PMON_CTL_STORAGE_MODE_MASK	\
-	(0x3 << NHMEX_M_PMON_CTL_STORAGE_MODE_SHIFT)
-#define NHMEX_M_PMON_CTL_WRAP_MODE		(1 << 6)
-#define NHMEX_M_PMON_CTL_FLAG_MODE		(1 << 7)
-#define NHMEX_M_PMON_CTL_INC_SEL_SHIFT		9
-#define NHMEX_M_PMON_CTL_INC_SEL_MASK		\
-	(0x1f << NHMEX_M_PMON_CTL_INC_SEL_SHIFT)
-#define NHMEX_M_PMON_CTL_SET_FLAG_SEL_SHIFT	19
-#define NHMEX_M_PMON_CTL_SET_FLAG_SEL_MASK	\
-	(0x7 << NHMEX_M_PMON_CTL_SET_FLAG_SEL_SHIFT)
-#define NHMEX_M_PMON_RAW_EVENT_MASK			\
-		(NHMEX_M_PMON_CTL_COUNT_MODE_MASK |	\
-		 NHMEX_M_PMON_CTL_STORAGE_MODE_MASK |	\
-		 NHMEX_M_PMON_CTL_WRAP_MODE |		\
-		 NHMEX_M_PMON_CTL_FLAG_MODE |		\
-		 NHMEX_M_PMON_CTL_INC_SEL_MASK |	\
-		 NHMEX_M_PMON_CTL_SET_FLAG_SEL_MASK)
-
-#define NHMEX_M_PMON_ZDP_CTL_FVC_MASK		(((1 << 11) - 1) | (1 << 23))
-#define NHMEX_M_PMON_ZDP_CTL_FVC_EVENT_MASK(n)	(0x7ULL << (11 + 3 * (n)))
-
-#define WSMEX_M_PMON_ZDP_CTL_FVC_MASK		(((1 << 12) - 1) | (1 << 24))
-#define WSMEX_M_PMON_ZDP_CTL_FVC_EVENT_MASK(n)	(0x7ULL << (12 + 3 * (n)))
-
-/*
- * use the 9~13 bits to select event If the 7th bit is not set,
- * otherwise use the 19~21 bits to select event.
- */
-#define MBOX_INC_SEL(x) ((x) << NHMEX_M_PMON_CTL_INC_SEL_SHIFT)
-#define MBOX_SET_FLAG_SEL(x) (((x) << NHMEX_M_PMON_CTL_SET_FLAG_SEL_SHIFT) | \
-				NHMEX_M_PMON_CTL_FLAG_MODE)
-#define MBOX_INC_SEL_MASK (NHMEX_M_PMON_CTL_INC_SEL_MASK | \
-			   NHMEX_M_PMON_CTL_FLAG_MODE)
-#define MBOX_SET_FLAG_SEL_MASK (NHMEX_M_PMON_CTL_SET_FLAG_SEL_MASK | \
-				NHMEX_M_PMON_CTL_FLAG_MODE)
-#define MBOX_INC_SEL_EXTAR_REG(c, r) \
-		EVENT_EXTRA_REG(MBOX_INC_SEL(c), NHMEX_M0_MSR_PMU_##r, \
-				MBOX_INC_SEL_MASK, (u64)-1, NHMEX_M_##r)
-#define MBOX_SET_FLAG_SEL_EXTRA_REG(c, r) \
-		EVENT_EXTRA_REG(MBOX_SET_FLAG_SEL(c), NHMEX_M0_MSR_PMU_##r, \
-				MBOX_SET_FLAG_SEL_MASK, \
-				(u64)-1, NHMEX_M_##r)
-
-/* NHM-EX Rbox */
-#define NHMEX_R_MSR_GLOBAL_CTL			0xe00
-#define NHMEX_R_MSR_PMON_CTL0			0xe10
-#define NHMEX_R_MSR_PMON_CNT0			0xe11
-#define NHMEX_R_MSR_OFFSET			0x20
-
-#define NHMEX_R_MSR_PORTN_QLX_CFG(n)		\
-		((n) < 4 ? (0xe0c + (n)) : (0xe2c + (n) - 4))
-#define NHMEX_R_MSR_PORTN_IPERF_CFG0(n)		(0xe04 + (n))
-#define NHMEX_R_MSR_PORTN_IPERF_CFG1(n)		(0xe24 + (n))
-#define NHMEX_R_MSR_PORTN_XBR_OFFSET(n)		\
-		(((n) < 4 ? 0 : 0x10) + (n) * 4)
-#define NHMEX_R_MSR_PORTN_XBR_SET1_MM_CFG(n)	\
-		(0xe60 + NHMEX_R_MSR_PORTN_XBR_OFFSET(n))
-#define NHMEX_R_MSR_PORTN_XBR_SET1_MATCH(n)	\
-		(NHMEX_R_MSR_PORTN_XBR_SET1_MM_CFG(n) + 1)
-#define NHMEX_R_MSR_PORTN_XBR_SET1_MASK(n)	\
-		(NHMEX_R_MSR_PORTN_XBR_SET1_MM_CFG(n) + 2)
-#define NHMEX_R_MSR_PORTN_XBR_SET2_MM_CFG(n)	\
-		(0xe70 + NHMEX_R_MSR_PORTN_XBR_OFFSET(n))
-#define NHMEX_R_MSR_PORTN_XBR_SET2_MATCH(n)	\
-		(NHMEX_R_MSR_PORTN_XBR_SET2_MM_CFG(n) + 1)
-#define NHMEX_R_MSR_PORTN_XBR_SET2_MASK(n)	\
-		(NHMEX_R_MSR_PORTN_XBR_SET2_MM_CFG(n) + 2)
-
-#define NHMEX_R_PMON_CTL_EN			(1 << 0)
-#define NHMEX_R_PMON_CTL_EV_SEL_SHIFT		1
-#define NHMEX_R_PMON_CTL_EV_SEL_MASK		\
-		(0x1f << NHMEX_R_PMON_CTL_EV_SEL_SHIFT)
-#define NHMEX_R_PMON_CTL_PMI_EN			(1 << 6)
-#define NHMEX_R_PMON_RAW_EVENT_MASK		NHMEX_R_PMON_CTL_EV_SEL_MASK
-
-/* NHM-EX Wbox */
-#define NHMEX_W_MSR_GLOBAL_CTL			0xc80
-#define NHMEX_W_MSR_PMON_CNT0			0xc90
-#define NHMEX_W_MSR_PMON_EVT_SEL0		0xc91
-#define NHMEX_W_MSR_PMON_FIXED_CTR		0x394
-#define NHMEX_W_MSR_PMON_FIXED_CTL		0x395
-
-#define NHMEX_W_PMON_GLOBAL_FIXED_EN		(1ULL << 31)
-
-#define __BITS_VALUE(x, i, n)  ((typeof(x))(((x) >> ((i) * (n))) & \
-				((1ULL << (n)) - 1)))
-
-DEFINE_UNCORE_FORMAT_ATTR(event, event, "config:0-7");
-DEFINE_UNCORE_FORMAT_ATTR(event5, event, "config:1-5");
-DEFINE_UNCORE_FORMAT_ATTR(umask, umask, "config:8-15");
-DEFINE_UNCORE_FORMAT_ATTR(edge, edge, "config:18");
-DEFINE_UNCORE_FORMAT_ATTR(inv, inv, "config:23");
-DEFINE_UNCORE_FORMAT_ATTR(thresh8, thresh, "config:24-31");
-DEFINE_UNCORE_FORMAT_ATTR(counter, counter, "config:6-7");
-DEFINE_UNCORE_FORMAT_ATTR(match, match, "config1:0-63");
-DEFINE_UNCORE_FORMAT_ATTR(mask, mask, "config2:0-63");
-
-static void nhmex_uncore_msr_init_box(struct intel_uncore_box *box)
-{
-	wrmsrl(NHMEX_U_MSR_PMON_GLOBAL_CTL, NHMEX_U_PMON_GLOBAL_EN_ALL);
-}
-
-static void nhmex_uncore_msr_disable_box(struct intel_uncore_box *box)
-{
-	unsigned msr = uncore_msr_box_ctl(box);
-	u64 config;
-
-	if (msr) {
-		rdmsrl(msr, config);
-		config &= ~((1ULL << uncore_num_counters(box)) - 1);
-		/* WBox has a fixed counter */
-		if (uncore_msr_fixed_ctl(box))
-			config &= ~NHMEX_W_PMON_GLOBAL_FIXED_EN;
-		wrmsrl(msr, config);
-	}
-}
-
-static void nhmex_uncore_msr_enable_box(struct intel_uncore_box *box)
-{
-	unsigned msr = uncore_msr_box_ctl(box);
-	u64 config;
-
-	if (msr) {
-		rdmsrl(msr, config);
-		config |= (1ULL << uncore_num_counters(box)) - 1;
-		/* WBox has a fixed counter */
-		if (uncore_msr_fixed_ctl(box))
-			config |= NHMEX_W_PMON_GLOBAL_FIXED_EN;
-		wrmsrl(msr, config);
-	}
-}
-
-static void nhmex_uncore_msr_disable_event(struct intel_uncore_box *box, struct perf_event *event)
-{
-	wrmsrl(event->hw.config_base, 0);
-}
-
-static void nhmex_uncore_msr_enable_event(struct intel_uncore_box *box, struct perf_event *event)
-{
-	struct hw_perf_event *hwc = &event->hw;
-
-	if (hwc->idx >= UNCORE_PMC_IDX_FIXED)
-		wrmsrl(hwc->config_base, NHMEX_PMON_CTL_EN_BIT0);
-	else if (box->pmu->type->event_mask & NHMEX_PMON_CTL_EN_BIT0)
-		wrmsrl(hwc->config_base, hwc->config | NHMEX_PMON_CTL_EN_BIT22);
-	else
-		wrmsrl(hwc->config_base, hwc->config | NHMEX_PMON_CTL_EN_BIT0);
-}
-
-#define NHMEX_UNCORE_OPS_COMMON_INIT()				\
-	.init_box	= nhmex_uncore_msr_init_box,		\
-	.disable_box	= nhmex_uncore_msr_disable_box,		\
-	.enable_box	= nhmex_uncore_msr_enable_box,		\
-	.disable_event	= nhmex_uncore_msr_disable_event,	\
-	.read_counter	= uncore_msr_read_counter
-
-static struct intel_uncore_ops nhmex_uncore_ops = {
-	NHMEX_UNCORE_OPS_COMMON_INIT(),
-	.enable_event	= nhmex_uncore_msr_enable_event,
-};
-
-static struct attribute *nhmex_uncore_ubox_formats_attr[] = {
-	&format_attr_event.attr,
-	&format_attr_edge.attr,
-	NULL,
-};
-
-static struct attribute_group nhmex_uncore_ubox_format_group = {
-	.name		= "format",
-	.attrs		= nhmex_uncore_ubox_formats_attr,
-};
-
-static struct intel_uncore_type nhmex_uncore_ubox = {
-	.name		= "ubox",
-	.num_counters	= 1,
-	.num_boxes	= 1,
-	.perf_ctr_bits	= 48,
-	.event_ctl	= NHMEX_U_MSR_PMON_EV_SEL,
-	.perf_ctr	= NHMEX_U_MSR_PMON_CTR,
-	.event_mask	= NHMEX_U_PMON_RAW_EVENT_MASK,
-	.box_ctl	= NHMEX_U_MSR_PMON_GLOBAL_CTL,
-	.ops		= &nhmex_uncore_ops,
-	.format_group	= &nhmex_uncore_ubox_format_group
-};
-
-static struct attribute *nhmex_uncore_cbox_formats_attr[] = {
-	&format_attr_event.attr,
-	&format_attr_umask.attr,
-	&format_attr_edge.attr,
-	&format_attr_inv.attr,
-	&format_attr_thresh8.attr,
-	NULL,
-};
-
-static struct attribute_group nhmex_uncore_cbox_format_group = {
-	.name = "format",
-	.attrs = nhmex_uncore_cbox_formats_attr,
-};
-
-/* msr offset for each instance of cbox */
-static unsigned nhmex_cbox_msr_offsets[] = {
-	0x0, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, 0x240, 0x2c0,
-};
-
-static struct intel_uncore_type nhmex_uncore_cbox = {
-	.name			= "cbox",
-	.num_counters		= 6,
-	.num_boxes		= 10,
-	.perf_ctr_bits		= 48,
-	.event_ctl		= NHMEX_C0_MSR_PMON_EV_SEL0,
-	.perf_ctr		= NHMEX_C0_MSR_PMON_CTR0,
-	.event_mask		= NHMEX_PMON_RAW_EVENT_MASK,
-	.box_ctl		= NHMEX_C0_MSR_PMON_GLOBAL_CTL,
-	.msr_offsets		= nhmex_cbox_msr_offsets,
-	.pair_ctr_ctl		= 1,
-	.ops			= &nhmex_uncore_ops,
-	.format_group		= &nhmex_uncore_cbox_format_group
-};
-
-static struct uncore_event_desc nhmex_uncore_wbox_events[] = {
-	INTEL_UNCORE_EVENT_DESC(clockticks, "event=0xff,umask=0"),
-	{ /* end: all zeroes */ },
-};
-
-static struct intel_uncore_type nhmex_uncore_wbox = {
-	.name			= "wbox",
-	.num_counters		= 4,
-	.num_boxes		= 1,
-	.perf_ctr_bits		= 48,
-	.event_ctl		= NHMEX_W_MSR_PMON_CNT0,
-	.perf_ctr		= NHMEX_W_MSR_PMON_EVT_SEL0,
-	.fixed_ctr		= NHMEX_W_MSR_PMON_FIXED_CTR,
-	.fixed_ctl		= NHMEX_W_MSR_PMON_FIXED_CTL,
-	.event_mask		= NHMEX_PMON_RAW_EVENT_MASK,
-	.box_ctl		= NHMEX_W_MSR_GLOBAL_CTL,
-	.pair_ctr_ctl		= 1,
-	.event_descs		= nhmex_uncore_wbox_events,
-	.ops			= &nhmex_uncore_ops,
-	.format_group		= &nhmex_uncore_cbox_format_group
-};
-
-static int nhmex_bbox_hw_config(struct intel_uncore_box *box, struct perf_event *event)
-{
-	struct hw_perf_event *hwc = &event->hw;
-	struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
-	struct hw_perf_event_extra *reg2 = &hwc->branch_reg;
-	int ctr, ev_sel;
-
-	ctr = (hwc->config & NHMEX_B_PMON_CTR_MASK) >>
-		NHMEX_B_PMON_CTR_SHIFT;
-	ev_sel = (hwc->config & NHMEX_B_PMON_CTL_EV_SEL_MASK) >>
-		  NHMEX_B_PMON_CTL_EV_SEL_SHIFT;
-
-	/* events that do not use the match/mask registers */
-	if ((ctr == 0 && ev_sel > 0x3) || (ctr == 1 && ev_sel > 0x6) ||
-	    (ctr == 2 && ev_sel != 0x4) || ctr == 3)
-		return 0;
-
-	if (box->pmu->pmu_idx == 0)
-		reg1->reg = NHMEX_B0_MSR_MATCH;
-	else
-		reg1->reg = NHMEX_B1_MSR_MATCH;
-	reg1->idx = 0;
-	reg1->config = event->attr.config1;
-	reg2->config = event->attr.config2;
-	return 0;
-}
-
-static void nhmex_bbox_msr_enable_event(struct intel_uncore_box *box, struct perf_event *event)
-{
-	struct hw_perf_event *hwc = &event->hw;
-	struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
-	struct hw_perf_event_extra *reg2 = &hwc->branch_reg;
-
-	if (reg1->idx != EXTRA_REG_NONE) {
-		wrmsrl(reg1->reg, reg1->config);
-		wrmsrl(reg1->reg + 1, reg2->config);
-	}
-	wrmsrl(hwc->config_base, NHMEX_PMON_CTL_EN_BIT0 |
-		(hwc->config & NHMEX_B_PMON_CTL_EV_SEL_MASK));
-}
-
-/*
- * The Bbox has 4 counters, but each counter monitors different events.
- * Use bits 6-7 in the event config to select counter.
- */
-static struct event_constraint nhmex_uncore_bbox_constraints[] = {
-	EVENT_CONSTRAINT(0 , 1, 0xc0),
-	EVENT_CONSTRAINT(0x40, 2, 0xc0),
-	EVENT_CONSTRAINT(0x80, 4, 0xc0),
-	EVENT_CONSTRAINT(0xc0, 8, 0xc0),
-	EVENT_CONSTRAINT_END,
-};
-
-static struct attribute *nhmex_uncore_bbox_formats_attr[] = {
-	&format_attr_event5.attr,
-	&format_attr_counter.attr,
-	&format_attr_match.attr,
-	&format_attr_mask.attr,
-	NULL,
-};
-
-static struct attribute_group nhmex_uncore_bbox_format_group = {
-	.name = "format",
-	.attrs = nhmex_uncore_bbox_formats_attr,
-};
-
-static struct intel_uncore_ops nhmex_uncore_bbox_ops = {
-	NHMEX_UNCORE_OPS_COMMON_INIT(),
-	.enable_event		= nhmex_bbox_msr_enable_event,
-	.hw_config		= nhmex_bbox_hw_config,
-	.get_constraint		= uncore_get_constraint,
-	.put_constraint		= uncore_put_constraint,
-};
-
-static struct intel_uncore_type nhmex_uncore_bbox = {
-	.name			= "bbox",
-	.num_counters		= 4,
-	.num_boxes		= 2,
-	.perf_ctr_bits		= 48,
-	.event_ctl		= NHMEX_B0_MSR_PMON_CTL0,
-	.perf_ctr		= NHMEX_B0_MSR_PMON_CTR0,
-	.event_mask		= NHMEX_B_PMON_RAW_EVENT_MASK,
-	.box_ctl		= NHMEX_B0_MSR_PMON_GLOBAL_CTL,
-	.msr_offset		= NHMEX_B_MSR_OFFSET,
-	.pair_ctr_ctl		= 1,
-	.num_shared_regs	= 1,
-	.constraints		= nhmex_uncore_bbox_constraints,
-	.ops			= &nhmex_uncore_bbox_ops,
-	.format_group		= &nhmex_uncore_bbox_format_group
-};
-
-static int nhmex_sbox_hw_config(struct intel_uncore_box *box, struct perf_event *event)
-{
-	struct hw_perf_event *hwc = &event->hw;
-	struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
-	struct hw_perf_event_extra *reg2 = &hwc->branch_reg;
-
-	/* only TO_R_PROG_EV event uses the match/mask register */
-	if ((hwc->config & NHMEX_PMON_CTL_EV_SEL_MASK) !=
-	    NHMEX_S_EVENT_TO_R_PROG_EV)
-		return 0;
-
-	if (box->pmu->pmu_idx == 0)
-		reg1->reg = NHMEX_S0_MSR_MM_CFG;
-	else
-		reg1->reg = NHMEX_S1_MSR_MM_CFG;
-	reg1->idx = 0;
-	reg1->config = event->attr.config1;
-	reg2->config = event->attr.config2;
-	return 0;
-}
-
-static void nhmex_sbox_msr_enable_event(struct intel_uncore_box *box, struct perf_event *event)
-{
-	struct hw_perf_event *hwc = &event->hw;
-	struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
-	struct hw_perf_event_extra *reg2 = &hwc->branch_reg;
-
-	if (reg1->idx != EXTRA_REG_NONE) {
-		wrmsrl(reg1->reg, 0);
-		wrmsrl(reg1->reg + 1, reg1->config);
-		wrmsrl(reg1->reg + 2, reg2->config);
-		wrmsrl(reg1->reg, NHMEX_S_PMON_MM_CFG_EN);
-	}
-	wrmsrl(hwc->config_base, hwc->config | NHMEX_PMON_CTL_EN_BIT22);
-}
-
-static struct attribute *nhmex_uncore_sbox_formats_attr[] = {
-	&format_attr_event.attr,
-	&format_attr_umask.attr,
-	&format_attr_edge.attr,
-	&format_attr_inv.attr,
-	&format_attr_thresh8.attr,
-	&format_attr_match.attr,
-	&format_attr_mask.attr,
-	NULL,
-};
-
-static struct attribute_group nhmex_uncore_sbox_format_group = {
-	.name			= "format",
-	.attrs			= nhmex_uncore_sbox_formats_attr,
-};
-
-static struct intel_uncore_ops nhmex_uncore_sbox_ops = {
-	NHMEX_UNCORE_OPS_COMMON_INIT(),
-	.enable_event		= nhmex_sbox_msr_enable_event,
-	.hw_config		= nhmex_sbox_hw_config,
-	.get_constraint		= uncore_get_constraint,
-	.put_constraint		= uncore_put_constraint,
-};
-
-static struct intel_uncore_type nhmex_uncore_sbox = {
-	.name			= "sbox",
-	.num_counters		= 4,
-	.num_boxes		= 2,
-	.perf_ctr_bits		= 48,
-	.event_ctl		= NHMEX_S0_MSR_PMON_CTL0,
-	.perf_ctr		= NHMEX_S0_MSR_PMON_CTR0,
-	.event_mask		= NHMEX_PMON_RAW_EVENT_MASK,
-	.box_ctl		= NHMEX_S0_MSR_PMON_GLOBAL_CTL,
-	.msr_offset		= NHMEX_S_MSR_OFFSET,
-	.pair_ctr_ctl		= 1,
-	.num_shared_regs	= 1,
-	.ops			= &nhmex_uncore_sbox_ops,
-	.format_group		= &nhmex_uncore_sbox_format_group
-};
-
-enum {
-	EXTRA_REG_NHMEX_M_FILTER,
-	EXTRA_REG_NHMEX_M_DSP,
-	EXTRA_REG_NHMEX_M_ISS,
-	EXTRA_REG_NHMEX_M_MAP,
-	EXTRA_REG_NHMEX_M_MSC_THR,
-	EXTRA_REG_NHMEX_M_PGT,
-	EXTRA_REG_NHMEX_M_PLD,
-	EXTRA_REG_NHMEX_M_ZDP_CTL_FVC,
-};
-
-static struct extra_reg nhmex_uncore_mbox_extra_regs[] = {
-	MBOX_INC_SEL_EXTAR_REG(0x0, DSP),
-	MBOX_INC_SEL_EXTAR_REG(0x4, MSC_THR),
-	MBOX_INC_SEL_EXTAR_REG(0x5, MSC_THR),
-	MBOX_INC_SEL_EXTAR_REG(0x9, ISS),
-	/* event 0xa uses two extra registers */
-	MBOX_INC_SEL_EXTAR_REG(0xa, ISS),
-	MBOX_INC_SEL_EXTAR_REG(0xa, PLD),
-	MBOX_INC_SEL_EXTAR_REG(0xb, PLD),
-	/* events 0xd ~ 0x10 use the same extra register */
-	MBOX_INC_SEL_EXTAR_REG(0xd, ZDP_CTL_FVC),
-	MBOX_INC_SEL_EXTAR_REG(0xe, ZDP_CTL_FVC),
-	MBOX_INC_SEL_EXTAR_REG(0xf, ZDP_CTL_FVC),
-	MBOX_INC_SEL_EXTAR_REG(0x10, ZDP_CTL_FVC),
-	MBOX_INC_SEL_EXTAR_REG(0x16, PGT),
-	MBOX_SET_FLAG_SEL_EXTRA_REG(0x0, DSP),
-	MBOX_SET_FLAG_SEL_EXTRA_REG(0x1, ISS),
-	MBOX_SET_FLAG_SEL_EXTRA_REG(0x5, PGT),
-	MBOX_SET_FLAG_SEL_EXTRA_REG(0x6, MAP),
-	EVENT_EXTRA_END
-};
-
-/* Nehalem-EX or Westmere-EX ? */
-static bool uncore_nhmex;
-
-static bool nhmex_mbox_get_shared_reg(struct intel_uncore_box *box, int idx, u64 config)
-{
-	struct intel_uncore_extra_reg *er;
-	unsigned long flags;
-	bool ret = false;
-	u64 mask;
-
-	if (idx < EXTRA_REG_NHMEX_M_ZDP_CTL_FVC) {
-		er = &box->shared_regs[idx];
-		raw_spin_lock_irqsave(&er->lock, flags);
-		if (!atomic_read(&er->ref) || er->config == config) {
-			atomic_inc(&er->ref);
-			er->config = config;
-			ret = true;
-		}
-		raw_spin_unlock_irqrestore(&er->lock, flags);
-
-		return ret;
-	}
-	/*
-	 * The ZDP_CTL_FVC MSR has 4 fields which are used to control
-	 * events 0xd ~ 0x10. Besides these 4 fields, there are additional
-	 * fields which are shared.
-	 */
-	idx -= EXTRA_REG_NHMEX_M_ZDP_CTL_FVC;
-	if (WARN_ON_ONCE(idx >= 4))
-		return false;
-
-	/* mask of the shared fields */
-	if (uncore_nhmex)
-		mask = NHMEX_M_PMON_ZDP_CTL_FVC_MASK;
-	else
-		mask = WSMEX_M_PMON_ZDP_CTL_FVC_MASK;
-	er = &box->shared_regs[EXTRA_REG_NHMEX_M_ZDP_CTL_FVC];
-
-	raw_spin_lock_irqsave(&er->lock, flags);
-	/* add mask of the non-shared field if it's in use */
-	if (__BITS_VALUE(atomic_read(&er->ref), idx, 8)) {
-		if (uncore_nhmex)
-			mask |= NHMEX_M_PMON_ZDP_CTL_FVC_EVENT_MASK(idx);
-		else
-			mask |= WSMEX_M_PMON_ZDP_CTL_FVC_EVENT_MASK(idx);
-	}
-
-	if (!atomic_read(&er->ref) || !((er->config ^ config) & mask)) {
-		atomic_add(1 << (idx * 8), &er->ref);
-		if (uncore_nhmex)
-			mask = NHMEX_M_PMON_ZDP_CTL_FVC_MASK |
-				NHMEX_M_PMON_ZDP_CTL_FVC_EVENT_MASK(idx);
-		else
-			mask = WSMEX_M_PMON_ZDP_CTL_FVC_MASK |
-				WSMEX_M_PMON_ZDP_CTL_FVC_EVENT_MASK(idx);
-		er->config &= ~mask;
-		er->config |= (config & mask);
-		ret = true;
-	}
-	raw_spin_unlock_irqrestore(&er->lock, flags);
-
-	return ret;
-}
-
-static void nhmex_mbox_put_shared_reg(struct intel_uncore_box *box, int idx)
-{
-	struct intel_uncore_extra_reg *er;
-
-	if (idx < EXTRA_REG_NHMEX_M_ZDP_CTL_FVC) {
-		er = &box->shared_regs[idx];
-		atomic_dec(&er->ref);
-		return;
-	}
-
-	idx -= EXTRA_REG_NHMEX_M_ZDP_CTL_FVC;
-	er = &box->shared_regs[EXTRA_REG_NHMEX_M_ZDP_CTL_FVC];
-	atomic_sub(1 << (idx * 8), &er->ref);
-}
-
-static u64 nhmex_mbox_alter_er(struct perf_event *event, int new_idx, bool modify)
-{
-	struct hw_perf_event *hwc = &event->hw;
-	struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
-	u64 idx, orig_idx = __BITS_VALUE(reg1->idx, 0, 8);
-	u64 config = reg1->config;
-
-	/* get the non-shared control bits and shift them */
-	idx = orig_idx - EXTRA_REG_NHMEX_M_ZDP_CTL_FVC;
-	if (uncore_nhmex)
-		config &= NHMEX_M_PMON_ZDP_CTL_FVC_EVENT_MASK(idx);
-	else
-		config &= WSMEX_M_PMON_ZDP_CTL_FVC_EVENT_MASK(idx);
-	if (new_idx > orig_idx) {
-		idx = new_idx - orig_idx;
-		config <<= 3 * idx;
-	} else {
-		idx = orig_idx - new_idx;
-		config >>= 3 * idx;
-	}
-
-	/* add the shared control bits back */
-	if (uncore_nhmex)
-		config |= NHMEX_M_PMON_ZDP_CTL_FVC_MASK & reg1->config;
-	else
-		config |= WSMEX_M_PMON_ZDP_CTL_FVC_MASK & reg1->config;
-	config |= NHMEX_M_PMON_ZDP_CTL_FVC_MASK & reg1->config;
-	if (modify) {
-		/* adjust the main event selector */
-		if (new_idx > orig_idx)
-			hwc->config += idx << NHMEX_M_PMON_CTL_INC_SEL_SHIFT;
-		else
-			hwc->config -= idx << NHMEX_M_PMON_CTL_INC_SEL_SHIFT;
-		reg1->config = config;
-		reg1->idx = ~0xff | new_idx;
-	}
-	return config;
-}
-
-static struct event_constraint *
-nhmex_mbox_get_constraint(struct intel_uncore_box *box, struct perf_event *event)
-{
-	struct hw_perf_event_extra *reg1 = &event->hw.extra_reg;
-	struct hw_perf_event_extra *reg2 = &event->hw.branch_reg;
-	int i, idx[2], alloc = 0;
-	u64 config1 = reg1->config;
-
-	idx[0] = __BITS_VALUE(reg1->idx, 0, 8);
-	idx[1] = __BITS_VALUE(reg1->idx, 1, 8);
-again:
-	for (i = 0; i < 2; i++) {
-		if (!uncore_box_is_fake(box) && (reg1->alloc & (0x1 << i)))
-			idx[i] = 0xff;
-
-		if (idx[i] == 0xff)
-			continue;
-
-		if (!nhmex_mbox_get_shared_reg(box, idx[i],
-				__BITS_VALUE(config1, i, 32)))
-			goto fail;
-		alloc |= (0x1 << i);
-	}
-
-	/* for the match/mask registers */
-	if (reg2->idx != EXTRA_REG_NONE &&
-	    (uncore_box_is_fake(box) || !reg2->alloc) &&
-	    !nhmex_mbox_get_shared_reg(box, reg2->idx, reg2->config))
-		goto fail;
-
-	/*
-	 * If it's a fake box -- as per validate_{group,event}() we
-	 * shouldn't touch event state and we can avoid doing so
-	 * since both will only call get_event_constraints() once
-	 * on each event, this avoids the need for reg->alloc.
-	 */
-	if (!uncore_box_is_fake(box)) {
-		if (idx[0] != 0xff && idx[0] != __BITS_VALUE(reg1->idx, 0, 8))
-			nhmex_mbox_alter_er(event, idx[0], true);
-		reg1->alloc |= alloc;
-		if (reg2->idx != EXTRA_REG_NONE)
-			reg2->alloc = 1;
-	}
-	return NULL;
-fail:
-	if (idx[0] != 0xff && !(alloc & 0x1) &&
-	    idx[0] >= EXTRA_REG_NHMEX_M_ZDP_CTL_FVC) {
-		/*
-		 * events 0xd ~ 0x10 are functional identical, but are
-		 * controlled by different fields in the ZDP_CTL_FVC
-		 * register. If we failed to take one field, try the
-		 * rest 3 choices.
-		 */
-		BUG_ON(__BITS_VALUE(reg1->idx, 1, 8) != 0xff);
-		idx[0] -= EXTRA_REG_NHMEX_M_ZDP_CTL_FVC;
-		idx[0] = (idx[0] + 1) % 4;
-		idx[0] += EXTRA_REG_NHMEX_M_ZDP_CTL_FVC;
-		if (idx[0] != __BITS_VALUE(reg1->idx, 0, 8)) {
-			config1 = nhmex_mbox_alter_er(event, idx[0], false);
-			goto again;
-		}
-	}
-
-	if (alloc & 0x1)
-		nhmex_mbox_put_shared_reg(box, idx[0]);
-	if (alloc & 0x2)
-		nhmex_mbox_put_shared_reg(box, idx[1]);
-	return &uncore_constraint_empty;
-}
-
-static void nhmex_mbox_put_constraint(struct intel_uncore_box *box, struct perf_event *event)
-{
-	struct hw_perf_event_extra *reg1 = &event->hw.extra_reg;
-	struct hw_perf_event_extra *reg2 = &event->hw.branch_reg;
-
-	if (uncore_box_is_fake(box))
-		return;
-
-	if (reg1->alloc & 0x1)
-		nhmex_mbox_put_shared_reg(box, __BITS_VALUE(reg1->idx, 0, 8));
-	if (reg1->alloc & 0x2)
-		nhmex_mbox_put_shared_reg(box, __BITS_VALUE(reg1->idx, 1, 8));
-	reg1->alloc = 0;
-
-	if (reg2->alloc) {
-		nhmex_mbox_put_shared_reg(box, reg2->idx);
-		reg2->alloc = 0;
-	}
-}
-
-static int nhmex_mbox_extra_reg_idx(struct extra_reg *er)
-{
-	if (er->idx < EXTRA_REG_NHMEX_M_ZDP_CTL_FVC)
-		return er->idx;
-	return er->idx + (er->event >> NHMEX_M_PMON_CTL_INC_SEL_SHIFT) - 0xd;
-}
-
-static int nhmex_mbox_hw_config(struct intel_uncore_box *box, struct perf_event *event)
-{
-	struct intel_uncore_type *type = box->pmu->type;
-	struct hw_perf_event_extra *reg1 = &event->hw.extra_reg;
-	struct hw_perf_event_extra *reg2 = &event->hw.branch_reg;
-	struct extra_reg *er;
-	unsigned msr;
-	int reg_idx = 0;
-	/*
-	 * The mbox events may require 2 extra MSRs at the most. But only
-	 * the lower 32 bits in these MSRs are significant, so we can use
-	 * config1 to pass two MSRs' config.
-	 */
-	for (er = nhmex_uncore_mbox_extra_regs; er->msr; er++) {
-		if (er->event != (event->hw.config & er->config_mask))
-			continue;
-		if (event->attr.config1 & ~er->valid_mask)
-			return -EINVAL;
-
-		msr = er->msr + type->msr_offset * box->pmu->pmu_idx;
-		if (WARN_ON_ONCE(msr >= 0xffff || er->idx >= 0xff))
-			return -EINVAL;
-
-		/* always use the 32~63 bits to pass the PLD config */
-		if (er->idx == EXTRA_REG_NHMEX_M_PLD)
-			reg_idx = 1;
-		else if (WARN_ON_ONCE(reg_idx > 0))
-			return -EINVAL;
-
-		reg1->idx &= ~(0xff << (reg_idx * 8));
-		reg1->reg &= ~(0xffff << (reg_idx * 16));
-		reg1->idx |= nhmex_mbox_extra_reg_idx(er) << (reg_idx * 8);
-		reg1->reg |= msr << (reg_idx * 16);
-		reg1->config = event->attr.config1;
-		reg_idx++;
-	}
-	/*
-	 * The mbox only provides ability to perform address matching
-	 * for the PLD events.
-	 */
-	if (reg_idx == 2) {
-		reg2->idx = EXTRA_REG_NHMEX_M_FILTER;
-		if (event->attr.config2 & NHMEX_M_PMON_MM_CFG_EN)
-			reg2->config = event->attr.config2;
-		else
-			reg2->config = ~0ULL;
-		if (box->pmu->pmu_idx == 0)
-			reg2->reg = NHMEX_M0_MSR_PMU_MM_CFG;
-		else
-			reg2->reg = NHMEX_M1_MSR_PMU_MM_CFG;
-	}
-	return 0;
-}
-
-static u64 nhmex_mbox_shared_reg_config(struct intel_uncore_box *box, int idx)
-{
-	struct intel_uncore_extra_reg *er;
-	unsigned long flags;
-	u64 config;
-
-	if (idx < EXTRA_REG_NHMEX_M_ZDP_CTL_FVC)
-		return box->shared_regs[idx].config;
-
-	er = &box->shared_regs[EXTRA_REG_NHMEX_M_ZDP_CTL_FVC];
-	raw_spin_lock_irqsave(&er->lock, flags);
-	config = er->config;
-	raw_spin_unlock_irqrestore(&er->lock, flags);
-	return config;
-}
-
-static void nhmex_mbox_msr_enable_event(struct intel_uncore_box *box, struct perf_event *event)
-{
-	struct hw_perf_event *hwc = &event->hw;
-	struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
-	struct hw_perf_event_extra *reg2 = &hwc->branch_reg;
-	int idx;
-
-	idx = __BITS_VALUE(reg1->idx, 0, 8);
-	if (idx != 0xff)
-		wrmsrl(__BITS_VALUE(reg1->reg, 0, 16),
-			nhmex_mbox_shared_reg_config(box, idx));
-	idx = __BITS_VALUE(reg1->idx, 1, 8);
-	if (idx != 0xff)
-		wrmsrl(__BITS_VALUE(reg1->reg, 1, 16),
-			nhmex_mbox_shared_reg_config(box, idx));
-
-	if (reg2->idx != EXTRA_REG_NONE) {
-		wrmsrl(reg2->reg, 0);
-		if (reg2->config != ~0ULL) {
-			wrmsrl(reg2->reg + 1,
-				reg2->config & NHMEX_M_PMON_ADDR_MATCH_MASK);
-			wrmsrl(reg2->reg + 2, NHMEX_M_PMON_ADDR_MASK_MASK &
-				(reg2->config >> NHMEX_M_PMON_ADDR_MASK_SHIFT));
-			wrmsrl(reg2->reg, NHMEX_M_PMON_MM_CFG_EN);
-		}
-	}
-
-	wrmsrl(hwc->config_base, hwc->config | NHMEX_PMON_CTL_EN_BIT0);
-}
-
-DEFINE_UNCORE_FORMAT_ATTR(count_mode,		count_mode,	"config:2-3");
-DEFINE_UNCORE_FORMAT_ATTR(storage_mode,		storage_mode,	"config:4-5");
-DEFINE_UNCORE_FORMAT_ATTR(wrap_mode,		wrap_mode,	"config:6");
-DEFINE_UNCORE_FORMAT_ATTR(flag_mode,		flag_mode,	"config:7");
-DEFINE_UNCORE_FORMAT_ATTR(inc_sel,		inc_sel,	"config:9-13");
-DEFINE_UNCORE_FORMAT_ATTR(set_flag_sel,		set_flag_sel,	"config:19-21");
-DEFINE_UNCORE_FORMAT_ATTR(filter_cfg_en,	filter_cfg_en,	"config2:63");
-DEFINE_UNCORE_FORMAT_ATTR(filter_match,		filter_match,	"config2:0-33");
-DEFINE_UNCORE_FORMAT_ATTR(filter_mask,		filter_mask,	"config2:34-61");
-DEFINE_UNCORE_FORMAT_ATTR(dsp,			dsp,		"config1:0-31");
-DEFINE_UNCORE_FORMAT_ATTR(thr,			thr,		"config1:0-31");
-DEFINE_UNCORE_FORMAT_ATTR(fvc,			fvc,		"config1:0-31");
-DEFINE_UNCORE_FORMAT_ATTR(pgt,			pgt,		"config1:0-31");
-DEFINE_UNCORE_FORMAT_ATTR(map,			map,		"config1:0-31");
-DEFINE_UNCORE_FORMAT_ATTR(iss,			iss,		"config1:0-31");
-DEFINE_UNCORE_FORMAT_ATTR(pld,			pld,		"config1:32-63");
-
-static struct attribute *nhmex_uncore_mbox_formats_attr[] = {
-	&format_attr_count_mode.attr,
-	&format_attr_storage_mode.attr,
-	&format_attr_wrap_mode.attr,
-	&format_attr_flag_mode.attr,
-	&format_attr_inc_sel.attr,
-	&format_attr_set_flag_sel.attr,
-	&format_attr_filter_cfg_en.attr,
-	&format_attr_filter_match.attr,
-	&format_attr_filter_mask.attr,
-	&format_attr_dsp.attr,
-	&format_attr_thr.attr,
-	&format_attr_fvc.attr,
-	&format_attr_pgt.attr,
-	&format_attr_map.attr,
-	&format_attr_iss.attr,
-	&format_attr_pld.attr,
-	NULL,
-};
-
-static struct attribute_group nhmex_uncore_mbox_format_group = {
-	.name		= "format",
-	.attrs		= nhmex_uncore_mbox_formats_attr,
-};
-
-static struct uncore_event_desc nhmex_uncore_mbox_events[] = {
-	INTEL_UNCORE_EVENT_DESC(bbox_cmds_read, "inc_sel=0xd,fvc=0x2800"),
-	INTEL_UNCORE_EVENT_DESC(bbox_cmds_write, "inc_sel=0xd,fvc=0x2820"),
-	{ /* end: all zeroes */ },
-};
-
-static struct uncore_event_desc wsmex_uncore_mbox_events[] = {
-	INTEL_UNCORE_EVENT_DESC(bbox_cmds_read, "inc_sel=0xd,fvc=0x5000"),
-	INTEL_UNCORE_EVENT_DESC(bbox_cmds_write, "inc_sel=0xd,fvc=0x5040"),
-	{ /* end: all zeroes */ },
-};
-
-static struct intel_uncore_ops nhmex_uncore_mbox_ops = {
-	NHMEX_UNCORE_OPS_COMMON_INIT(),
-	.enable_event	= nhmex_mbox_msr_enable_event,
-	.hw_config	= nhmex_mbox_hw_config,
-	.get_constraint	= nhmex_mbox_get_constraint,
-	.put_constraint	= nhmex_mbox_put_constraint,
-};
-
-static struct intel_uncore_type nhmex_uncore_mbox = {
-	.name			= "mbox",
-	.num_counters		= 6,
-	.num_boxes		= 2,
-	.perf_ctr_bits		= 48,
-	.event_ctl		= NHMEX_M0_MSR_PMU_CTL0,
-	.perf_ctr		= NHMEX_M0_MSR_PMU_CNT0,
-	.event_mask		= NHMEX_M_PMON_RAW_EVENT_MASK,
-	.box_ctl		= NHMEX_M0_MSR_GLOBAL_CTL,
-	.msr_offset		= NHMEX_M_MSR_OFFSET,
-	.pair_ctr_ctl		= 1,
-	.num_shared_regs	= 8,
-	.event_descs		= nhmex_uncore_mbox_events,
-	.ops			= &nhmex_uncore_mbox_ops,
-	.format_group		= &nhmex_uncore_mbox_format_group,
-};
-
-static void nhmex_rbox_alter_er(struct intel_uncore_box *box, struct perf_event *event)
-{
-	struct hw_perf_event *hwc = &event->hw;
-	struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
-
-	/* adjust the main event selector and extra register index */
-	if (reg1->idx % 2) {
-		reg1->idx--;
-		hwc->config -= 1 << NHMEX_R_PMON_CTL_EV_SEL_SHIFT;
-	} else {
-		reg1->idx++;
-		hwc->config += 1 << NHMEX_R_PMON_CTL_EV_SEL_SHIFT;
-	}
-
-	/* adjust extra register config */
-	switch (reg1->idx % 6) {
-	case 2:
-		/* shift the 8~15 bits to the 0~7 bits */
-		reg1->config >>= 8;
-		break;
-	case 3:
-		/* shift the 0~7 bits to the 8~15 bits */
-		reg1->config <<= 8;
-		break;
-	}
-}
-
-/*
- * Each rbox has 4 event set which monitor PQI port 0~3 or 4~7.
- * An event set consists of 6 events, the 3rd and 4th events in
- * an event set use the same extra register. So an event set uses
- * 5 extra registers.
- */
-static struct event_constraint *
-nhmex_rbox_get_constraint(struct intel_uncore_box *box, struct perf_event *event)
-{
-	struct hw_perf_event *hwc = &event->hw;
-	struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
-	struct hw_perf_event_extra *reg2 = &hwc->branch_reg;
-	struct intel_uncore_extra_reg *er;
-	unsigned long flags;
-	int idx, er_idx;
-	u64 config1;
-	bool ok = false;
-
-	if (!uncore_box_is_fake(box) && reg1->alloc)
-		return NULL;
-
-	idx = reg1->idx % 6;
-	config1 = reg1->config;
-again:
-	er_idx = idx;
-	/* the 3rd and 4th events use the same extra register */
-	if (er_idx > 2)
-		er_idx--;
-	er_idx += (reg1->idx / 6) * 5;
-
-	er = &box->shared_regs[er_idx];
-	raw_spin_lock_irqsave(&er->lock, flags);
-	if (idx < 2) {
-		if (!atomic_read(&er->ref) || er->config == reg1->config) {
-			atomic_inc(&er->ref);
-			er->config = reg1->config;
-			ok = true;
-		}
-	} else if (idx == 2 || idx == 3) {
-		/*
-		 * these two events use different fields in a extra register,
-		 * the 0~7 bits and the 8~15 bits respectively.
-		 */
-		u64 mask = 0xff << ((idx - 2) * 8);
-		if (!__BITS_VALUE(atomic_read(&er->ref), idx - 2, 8) ||
-				!((er->config ^ config1) & mask)) {
-			atomic_add(1 << ((idx - 2) * 8), &er->ref);
-			er->config &= ~mask;
-			er->config |= config1 & mask;
-			ok = true;
-		}
-	} else {
-		if (!atomic_read(&er->ref) ||
-				(er->config == (hwc->config >> 32) &&
-				 er->config1 == reg1->config &&
-				 er->config2 == reg2->config)) {
-			atomic_inc(&er->ref);
-			er->config = (hwc->config >> 32);
-			er->config1 = reg1->config;
-			er->config2 = reg2->config;
-			ok = true;
-		}
-	}
-	raw_spin_unlock_irqrestore(&er->lock, flags);
-
-	if (!ok) {
-		/*
-		 * The Rbox events are always in pairs. The paired
-		 * events are functional identical, but use different
-		 * extra registers. If we failed to take an extra
-		 * register, try the alternative.
-		 */
-		idx ^= 1;
-		if (idx != reg1->idx % 6) {
-			if (idx == 2)
-				config1 >>= 8;
-			else if (idx == 3)
-				config1 <<= 8;
-			goto again;
-		}
-	} else {
-		if (!uncore_box_is_fake(box)) {
-			if (idx != reg1->idx % 6)
-				nhmex_rbox_alter_er(box, event);
-			reg1->alloc = 1;
-		}
-		return NULL;
-	}
-	return &uncore_constraint_empty;
-}
-
-static void nhmex_rbox_put_constraint(struct intel_uncore_box *box, struct perf_event *event)
-{
-	struct intel_uncore_extra_reg *er;
-	struct hw_perf_event_extra *reg1 = &event->hw.extra_reg;
-	int idx, er_idx;
-
-	if (uncore_box_is_fake(box) || !reg1->alloc)
-		return;
-
-	idx = reg1->idx % 6;
-	er_idx = idx;
-	if (er_idx > 2)
-		er_idx--;
-	er_idx += (reg1->idx / 6) * 5;
-
-	er = &box->shared_regs[er_idx];
-	if (idx == 2 || idx == 3)
-		atomic_sub(1 << ((idx - 2) * 8), &er->ref);
-	else
-		atomic_dec(&er->ref);
-
-	reg1->alloc = 0;
-}
-
-static int nhmex_rbox_hw_config(struct intel_uncore_box *box, struct perf_event *event)
-{
-	struct hw_perf_event *hwc = &event->hw;
-	struct hw_perf_event_extra *reg1 = &event->hw.extra_reg;
-	struct hw_perf_event_extra *reg2 = &event->hw.branch_reg;
-	int idx;
-
-	idx = (event->hw.config & NHMEX_R_PMON_CTL_EV_SEL_MASK) >>
-		NHMEX_R_PMON_CTL_EV_SEL_SHIFT;
-	if (idx >= 0x18)
-		return -EINVAL;
-
-	reg1->idx = idx;
-	reg1->config = event->attr.config1;
-
-	switch (idx % 6) {
-	case 4:
-	case 5:
-		hwc->config |= event->attr.config & (~0ULL << 32);
-		reg2->config = event->attr.config2;
-		break;
-	}
-	return 0;
-}
-
-static void nhmex_rbox_msr_enable_event(struct intel_uncore_box *box, struct perf_event *event)
-{
-	struct hw_perf_event *hwc = &event->hw;
-	struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
-	struct hw_perf_event_extra *reg2 = &hwc->branch_reg;
-	int idx, port;
-
-	idx = reg1->idx;
-	port = idx / 6 + box->pmu->pmu_idx * 4;
-
-	switch (idx % 6) {
-	case 0:
-		wrmsrl(NHMEX_R_MSR_PORTN_IPERF_CFG0(port), reg1->config);
-		break;
-	case 1:
-		wrmsrl(NHMEX_R_MSR_PORTN_IPERF_CFG1(port), reg1->config);
-		break;
-	case 2:
-	case 3:
-		wrmsrl(NHMEX_R_MSR_PORTN_QLX_CFG(port),
-			uncore_shared_reg_config(box, 2 + (idx / 6) * 5));
-		break;
-	case 4:
-		wrmsrl(NHMEX_R_MSR_PORTN_XBR_SET1_MM_CFG(port),
-			hwc->config >> 32);
-		wrmsrl(NHMEX_R_MSR_PORTN_XBR_SET1_MATCH(port), reg1->config);
-		wrmsrl(NHMEX_R_MSR_PORTN_XBR_SET1_MASK(port), reg2->config);
-		break;
-	case 5:
-		wrmsrl(NHMEX_R_MSR_PORTN_XBR_SET2_MM_CFG(port),
-			hwc->config >> 32);
-		wrmsrl(NHMEX_R_MSR_PORTN_XBR_SET2_MATCH(port), reg1->config);
-		wrmsrl(NHMEX_R_MSR_PORTN_XBR_SET2_MASK(port), reg2->config);
-		break;
-	}
-
-	wrmsrl(hwc->config_base, NHMEX_PMON_CTL_EN_BIT0 |
-		(hwc->config & NHMEX_R_PMON_CTL_EV_SEL_MASK));
-}
-
-DEFINE_UNCORE_FORMAT_ATTR(xbr_mm_cfg, xbr_mm_cfg, "config:32-63");
-DEFINE_UNCORE_FORMAT_ATTR(xbr_match, xbr_match, "config1:0-63");
-DEFINE_UNCORE_FORMAT_ATTR(xbr_mask, xbr_mask, "config2:0-63");
-DEFINE_UNCORE_FORMAT_ATTR(qlx_cfg, qlx_cfg, "config1:0-15");
-DEFINE_UNCORE_FORMAT_ATTR(iperf_cfg, iperf_cfg, "config1:0-31");
-
-static struct attribute *nhmex_uncore_rbox_formats_attr[] = {
-	&format_attr_event5.attr,
-	&format_attr_xbr_mm_cfg.attr,
-	&format_attr_xbr_match.attr,
-	&format_attr_xbr_mask.attr,
-	&format_attr_qlx_cfg.attr,
-	&format_attr_iperf_cfg.attr,
-	NULL,
-};
-
-static struct attribute_group nhmex_uncore_rbox_format_group = {
-	.name = "format",
-	.attrs = nhmex_uncore_rbox_formats_attr,
-};
-
-static struct uncore_event_desc nhmex_uncore_rbox_events[] = {
-	INTEL_UNCORE_EVENT_DESC(qpi0_flit_send,		"event=0x0,iperf_cfg=0x80000000"),
-	INTEL_UNCORE_EVENT_DESC(qpi1_filt_send,		"event=0x6,iperf_cfg=0x80000000"),
-	INTEL_UNCORE_EVENT_DESC(qpi0_idle_filt,		"event=0x0,iperf_cfg=0x40000000"),
-	INTEL_UNCORE_EVENT_DESC(qpi1_idle_filt,		"event=0x6,iperf_cfg=0x40000000"),
-	INTEL_UNCORE_EVENT_DESC(qpi0_date_response,	"event=0x0,iperf_cfg=0xc4"),
-	INTEL_UNCORE_EVENT_DESC(qpi1_date_response,	"event=0x6,iperf_cfg=0xc4"),
-	{ /* end: all zeroes */ },
-};
-
-static struct intel_uncore_ops nhmex_uncore_rbox_ops = {
-	NHMEX_UNCORE_OPS_COMMON_INIT(),
-	.enable_event		= nhmex_rbox_msr_enable_event,
-	.hw_config		= nhmex_rbox_hw_config,
-	.get_constraint		= nhmex_rbox_get_constraint,
-	.put_constraint		= nhmex_rbox_put_constraint,
-};
-
-static struct intel_uncore_type nhmex_uncore_rbox = {
-	.name			= "rbox",
-	.num_counters		= 8,
-	.num_boxes		= 2,
-	.perf_ctr_bits		= 48,
-	.event_ctl		= NHMEX_R_MSR_PMON_CTL0,
-	.perf_ctr		= NHMEX_R_MSR_PMON_CNT0,
-	.event_mask		= NHMEX_R_PMON_RAW_EVENT_MASK,
-	.box_ctl		= NHMEX_R_MSR_GLOBAL_CTL,
-	.msr_offset		= NHMEX_R_MSR_OFFSET,
-	.pair_ctr_ctl		= 1,
-	.num_shared_regs	= 20,
-	.event_descs		= nhmex_uncore_rbox_events,
-	.ops			= &nhmex_uncore_rbox_ops,
-	.format_group		= &nhmex_uncore_rbox_format_group
-};
-
-static struct intel_uncore_type *nhmex_msr_uncores[] = {
-	&nhmex_uncore_ubox,
-	&nhmex_uncore_cbox,
-	&nhmex_uncore_bbox,
-	&nhmex_uncore_sbox,
-	&nhmex_uncore_mbox,
-	&nhmex_uncore_rbox,
-	&nhmex_uncore_wbox,
-	NULL,
-};
-
-void nhmex_uncore_cpu_init(void)
-{
-	if (boot_cpu_data.x86_model == 46)
-		uncore_nhmex = true;
-	else
-		nhmex_uncore_mbox.event_descs = wsmex_uncore_mbox_events;
-	if (nhmex_uncore_cbox.num_boxes > boot_cpu_data.x86_max_cores)
-		nhmex_uncore_cbox.num_boxes = boot_cpu_data.x86_max_cores;
-	uncore_msr_uncores = nhmex_msr_uncores;
-}
-/* end of Nehalem-EX uncore support */
--- zfcpdump-kernel-4.4.orig/arch/x86/kernel/cpu/perf_event_intel_uncore_snb.c
+++ /dev/null
@@ -1,697 +0,0 @@
-/* Nehalem/SandBridge/Haswell uncore support */
-#include "perf_event_intel_uncore.h"
-
-/* Uncore IMC PCI IDs */
-#define PCI_DEVICE_ID_INTEL_SNB_IMC	0x0100
-#define PCI_DEVICE_ID_INTEL_IVB_IMC	0x0154
-#define PCI_DEVICE_ID_INTEL_IVB_E3_IMC	0x0150
-#define PCI_DEVICE_ID_INTEL_HSW_IMC	0x0c00
-#define PCI_DEVICE_ID_INTEL_HSW_U_IMC	0x0a04
-#define PCI_DEVICE_ID_INTEL_BDW_IMC	0x1604
-
-/* SNB event control */
-#define SNB_UNC_CTL_EV_SEL_MASK			0x000000ff
-#define SNB_UNC_CTL_UMASK_MASK			0x0000ff00
-#define SNB_UNC_CTL_EDGE_DET			(1 << 18)
-#define SNB_UNC_CTL_EN				(1 << 22)
-#define SNB_UNC_CTL_INVERT			(1 << 23)
-#define SNB_UNC_CTL_CMASK_MASK			0x1f000000
-#define NHM_UNC_CTL_CMASK_MASK			0xff000000
-#define NHM_UNC_FIXED_CTR_CTL_EN		(1 << 0)
-
-#define SNB_UNC_RAW_EVENT_MASK			(SNB_UNC_CTL_EV_SEL_MASK | \
-						 SNB_UNC_CTL_UMASK_MASK | \
-						 SNB_UNC_CTL_EDGE_DET | \
-						 SNB_UNC_CTL_INVERT | \
-						 SNB_UNC_CTL_CMASK_MASK)
-
-#define NHM_UNC_RAW_EVENT_MASK			(SNB_UNC_CTL_EV_SEL_MASK | \
-						 SNB_UNC_CTL_UMASK_MASK | \
-						 SNB_UNC_CTL_EDGE_DET | \
-						 SNB_UNC_CTL_INVERT | \
-						 NHM_UNC_CTL_CMASK_MASK)
-
-/* SNB global control register */
-#define SNB_UNC_PERF_GLOBAL_CTL                 0x391
-#define SNB_UNC_FIXED_CTR_CTRL                  0x394
-#define SNB_UNC_FIXED_CTR                       0x395
-
-/* SNB uncore global control */
-#define SNB_UNC_GLOBAL_CTL_CORE_ALL             ((1 << 4) - 1)
-#define SNB_UNC_GLOBAL_CTL_EN                   (1 << 29)
-
-/* SNB Cbo register */
-#define SNB_UNC_CBO_0_PERFEVTSEL0               0x700
-#define SNB_UNC_CBO_0_PER_CTR0                  0x706
-#define SNB_UNC_CBO_MSR_OFFSET                  0x10
-
-/* SNB ARB register */
-#define SNB_UNC_ARB_PER_CTR0			0x3b0
-#define SNB_UNC_ARB_PERFEVTSEL0			0x3b2
-#define SNB_UNC_ARB_MSR_OFFSET			0x10
-
-/* NHM global control register */
-#define NHM_UNC_PERF_GLOBAL_CTL                 0x391
-#define NHM_UNC_FIXED_CTR                       0x394
-#define NHM_UNC_FIXED_CTR_CTRL                  0x395
-
-/* NHM uncore global control */
-#define NHM_UNC_GLOBAL_CTL_EN_PC_ALL            ((1ULL << 8) - 1)
-#define NHM_UNC_GLOBAL_CTL_EN_FC                (1ULL << 32)
-
-/* NHM uncore register */
-#define NHM_UNC_PERFEVTSEL0                     0x3c0
-#define NHM_UNC_UNCORE_PMC0                     0x3b0
-
-DEFINE_UNCORE_FORMAT_ATTR(event, event, "config:0-7");
-DEFINE_UNCORE_FORMAT_ATTR(umask, umask, "config:8-15");
-DEFINE_UNCORE_FORMAT_ATTR(edge, edge, "config:18");
-DEFINE_UNCORE_FORMAT_ATTR(inv, inv, "config:23");
-DEFINE_UNCORE_FORMAT_ATTR(cmask5, cmask, "config:24-28");
-DEFINE_UNCORE_FORMAT_ATTR(cmask8, cmask, "config:24-31");
-
-/* Sandy Bridge uncore support */
-static void snb_uncore_msr_enable_event(struct intel_uncore_box *box, struct perf_event *event)
-{
-	struct hw_perf_event *hwc = &event->hw;
-
-	if (hwc->idx < UNCORE_PMC_IDX_FIXED)
-		wrmsrl(hwc->config_base, hwc->config | SNB_UNC_CTL_EN);
-	else
-		wrmsrl(hwc->config_base, SNB_UNC_CTL_EN);
-}
-
-static void snb_uncore_msr_disable_event(struct intel_uncore_box *box, struct perf_event *event)
-{
-	wrmsrl(event->hw.config_base, 0);
-}
-
-static void snb_uncore_msr_init_box(struct intel_uncore_box *box)
-{
-	if (box->pmu->pmu_idx == 0) {
-		wrmsrl(SNB_UNC_PERF_GLOBAL_CTL,
-			SNB_UNC_GLOBAL_CTL_EN | SNB_UNC_GLOBAL_CTL_CORE_ALL);
-	}
-}
-
-static struct uncore_event_desc snb_uncore_events[] = {
-	INTEL_UNCORE_EVENT_DESC(clockticks, "event=0xff,umask=0x00"),
-	{ /* end: all zeroes */ },
-};
-
-static struct attribute *snb_uncore_formats_attr[] = {
-	&format_attr_event.attr,
-	&format_attr_umask.attr,
-	&format_attr_edge.attr,
-	&format_attr_inv.attr,
-	&format_attr_cmask5.attr,
-	NULL,
-};
-
-static struct attribute_group snb_uncore_format_group = {
-	.name		= "format",
-	.attrs		= snb_uncore_formats_attr,
-};
-
-static struct intel_uncore_ops snb_uncore_msr_ops = {
-	.init_box	= snb_uncore_msr_init_box,
-	.disable_event	= snb_uncore_msr_disable_event,
-	.enable_event	= snb_uncore_msr_enable_event,
-	.read_counter	= uncore_msr_read_counter,
-};
-
-static struct event_constraint snb_uncore_arb_constraints[] = {
-	UNCORE_EVENT_CONSTRAINT(0x80, 0x1),
-	UNCORE_EVENT_CONSTRAINT(0x83, 0x1),
-	EVENT_CONSTRAINT_END
-};
-
-static struct intel_uncore_type snb_uncore_cbox = {
-	.name		= "cbox",
-	.num_counters   = 2,
-	.num_boxes	= 4,
-	.perf_ctr_bits	= 44,
-	.fixed_ctr_bits	= 48,
-	.perf_ctr	= SNB_UNC_CBO_0_PER_CTR0,
-	.event_ctl	= SNB_UNC_CBO_0_PERFEVTSEL0,
-	.fixed_ctr	= SNB_UNC_FIXED_CTR,
-	.fixed_ctl	= SNB_UNC_FIXED_CTR_CTRL,
-	.single_fixed	= 1,
-	.event_mask	= SNB_UNC_RAW_EVENT_MASK,
-	.msr_offset	= SNB_UNC_CBO_MSR_OFFSET,
-	.ops		= &snb_uncore_msr_ops,
-	.format_group	= &snb_uncore_format_group,
-	.event_descs	= snb_uncore_events,
-};
-
-static struct intel_uncore_type snb_uncore_arb = {
-	.name		= "arb",
-	.num_counters   = 2,
-	.num_boxes	= 1,
-	.perf_ctr_bits	= 44,
-	.perf_ctr	= SNB_UNC_ARB_PER_CTR0,
-	.event_ctl	= SNB_UNC_ARB_PERFEVTSEL0,
-	.event_mask	= SNB_UNC_RAW_EVENT_MASK,
-	.msr_offset	= SNB_UNC_ARB_MSR_OFFSET,
-	.constraints	= snb_uncore_arb_constraints,
-	.ops		= &snb_uncore_msr_ops,
-	.format_group	= &snb_uncore_format_group,
-};
-
-static struct intel_uncore_type *snb_msr_uncores[] = {
-	&snb_uncore_cbox,
-	&snb_uncore_arb,
-	NULL,
-};
-
-void snb_uncore_cpu_init(void)
-{
-	uncore_msr_uncores = snb_msr_uncores;
-	if (snb_uncore_cbox.num_boxes > boot_cpu_data.x86_max_cores)
-		snb_uncore_cbox.num_boxes = boot_cpu_data.x86_max_cores;
-}
-
-enum {
-	SNB_PCI_UNCORE_IMC,
-};
-
-static struct uncore_event_desc snb_uncore_imc_events[] = {
-	INTEL_UNCORE_EVENT_DESC(data_reads,  "event=0x01"),
-	INTEL_UNCORE_EVENT_DESC(data_reads.scale, "6.103515625e-5"),
-	INTEL_UNCORE_EVENT_DESC(data_reads.unit, "MiB"),
-
-	INTEL_UNCORE_EVENT_DESC(data_writes, "event=0x02"),
-	INTEL_UNCORE_EVENT_DESC(data_writes.scale, "6.103515625e-5"),
-	INTEL_UNCORE_EVENT_DESC(data_writes.unit, "MiB"),
-
-	{ /* end: all zeroes */ },
-};
-
-#define SNB_UNCORE_PCI_IMC_EVENT_MASK		0xff
-#define SNB_UNCORE_PCI_IMC_BAR_OFFSET		0x48
-
-/* page size multiple covering all config regs */
-#define SNB_UNCORE_PCI_IMC_MAP_SIZE		0x6000
-
-#define SNB_UNCORE_PCI_IMC_DATA_READS		0x1
-#define SNB_UNCORE_PCI_IMC_DATA_READS_BASE	0x5050
-#define SNB_UNCORE_PCI_IMC_DATA_WRITES		0x2
-#define SNB_UNCORE_PCI_IMC_DATA_WRITES_BASE	0x5054
-#define SNB_UNCORE_PCI_IMC_CTR_BASE		SNB_UNCORE_PCI_IMC_DATA_READS_BASE
-
-static struct attribute *snb_uncore_imc_formats_attr[] = {
-	&format_attr_event.attr,
-	NULL,
-};
-
-static struct attribute_group snb_uncore_imc_format_group = {
-	.name = "format",
-	.attrs = snb_uncore_imc_formats_attr,
-};
-
-static void snb_uncore_imc_init_box(struct intel_uncore_box *box)
-{
-	struct pci_dev *pdev = box->pci_dev;
-	int where = SNB_UNCORE_PCI_IMC_BAR_OFFSET;
-	resource_size_t addr;
-	u32 pci_dword;
-
-	pci_read_config_dword(pdev, where, &pci_dword);
-	addr = pci_dword;
-
-#ifdef CONFIG_PHYS_ADDR_T_64BIT
-	pci_read_config_dword(pdev, where + 4, &pci_dword);
-	addr |= ((resource_size_t)pci_dword << 32);
-#endif
-
-	addr &= ~(PAGE_SIZE - 1);
-
-	box->io_addr = ioremap(addr, SNB_UNCORE_PCI_IMC_MAP_SIZE);
-	box->hrtimer_duration = UNCORE_SNB_IMC_HRTIMER_INTERVAL;
-}
-
-static void snb_uncore_imc_enable_box(struct intel_uncore_box *box)
-{}
-
-static void snb_uncore_imc_disable_box(struct intel_uncore_box *box)
-{}
-
-static void snb_uncore_imc_enable_event(struct intel_uncore_box *box, struct perf_event *event)
-{}
-
-static void snb_uncore_imc_disable_event(struct intel_uncore_box *box, struct perf_event *event)
-{}
-
-static u64 snb_uncore_imc_read_counter(struct intel_uncore_box *box, struct perf_event *event)
-{
-	struct hw_perf_event *hwc = &event->hw;
-
-	return (u64)*(unsigned int *)(box->io_addr + hwc->event_base);
-}
-
-/*
- * custom event_init() function because we define our own fixed, free
- * running counters, so we do not want to conflict with generic uncore
- * logic. Also simplifies processing
- */
-static int snb_uncore_imc_event_init(struct perf_event *event)
-{
-	struct intel_uncore_pmu *pmu;
-	struct intel_uncore_box *box;
-	struct hw_perf_event *hwc = &event->hw;
-	u64 cfg = event->attr.config & SNB_UNCORE_PCI_IMC_EVENT_MASK;
-	int idx, base;
-
-	if (event->attr.type != event->pmu->type)
-		return -ENOENT;
-
-	pmu = uncore_event_to_pmu(event);
-	/* no device found for this pmu */
-	if (pmu->func_id < 0)
-		return -ENOENT;
-
-	/* Sampling not supported yet */
-	if (hwc->sample_period)
-		return -EINVAL;
-
-	/* unsupported modes and filters */
-	if (event->attr.exclude_user   ||
-	    event->attr.exclude_kernel ||
-	    event->attr.exclude_hv     ||
-	    event->attr.exclude_idle   ||
-	    event->attr.exclude_host   ||
-	    event->attr.exclude_guest  ||
-	    event->attr.sample_period) /* no sampling */
-		return -EINVAL;
-
-	/*
-	 * Place all uncore events for a particular physical package
-	 * onto a single cpu
-	 */
-	if (event->cpu < 0)
-		return -EINVAL;
-
-	/* check only supported bits are set */
-	if (event->attr.config & ~SNB_UNCORE_PCI_IMC_EVENT_MASK)
-		return -EINVAL;
-
-	box = uncore_pmu_to_box(pmu, event->cpu);
-	if (!box || box->cpu < 0)
-		return -EINVAL;
-
-	event->cpu = box->cpu;
-
-	event->hw.idx = -1;
-	event->hw.last_tag = ~0ULL;
-	event->hw.extra_reg.idx = EXTRA_REG_NONE;
-	event->hw.branch_reg.idx = EXTRA_REG_NONE;
-	/*
-	 * check event is known (whitelist, determines counter)
-	 */
-	switch (cfg) {
-	case SNB_UNCORE_PCI_IMC_DATA_READS:
-		base = SNB_UNCORE_PCI_IMC_DATA_READS_BASE;
-		idx = UNCORE_PMC_IDX_FIXED;
-		break;
-	case SNB_UNCORE_PCI_IMC_DATA_WRITES:
-		base = SNB_UNCORE_PCI_IMC_DATA_WRITES_BASE;
-		idx = UNCORE_PMC_IDX_FIXED + 1;
-		break;
-	default:
-		return -EINVAL;
-	}
-
-	/* must be done before validate_group */
-	event->hw.event_base = base;
-	event->hw.config = cfg;
-	event->hw.idx = idx;
-
-	/* no group validation needed, we have free running counters */
-
-	return 0;
-}
-
-static int snb_uncore_imc_hw_config(struct intel_uncore_box *box, struct perf_event *event)
-{
-	return 0;
-}
-
-static void snb_uncore_imc_event_start(struct perf_event *event, int flags)
-{
-	struct intel_uncore_box *box = uncore_event_to_box(event);
-	u64 count;
-
-	if (WARN_ON_ONCE(!(event->hw.state & PERF_HES_STOPPED)))
-		return;
-
-	event->hw.state = 0;
-	box->n_active++;
-
-	list_add_tail(&event->active_entry, &box->active_list);
-
-	count = snb_uncore_imc_read_counter(box, event);
-	local64_set(&event->hw.prev_count, count);
-
-	if (box->n_active == 1)
-		uncore_pmu_start_hrtimer(box);
-}
-
-static void snb_uncore_imc_event_stop(struct perf_event *event, int flags)
-{
-	struct intel_uncore_box *box = uncore_event_to_box(event);
-	struct hw_perf_event *hwc = &event->hw;
-
-	if (!(hwc->state & PERF_HES_STOPPED)) {
-		box->n_active--;
-
-		WARN_ON_ONCE(hwc->state & PERF_HES_STOPPED);
-		hwc->state |= PERF_HES_STOPPED;
-
-		list_del(&event->active_entry);
-
-		if (box->n_active == 0)
-			uncore_pmu_cancel_hrtimer(box);
-	}
-
-	if ((flags & PERF_EF_UPDATE) && !(hwc->state & PERF_HES_UPTODATE)) {
-		/*
-		 * Drain the remaining delta count out of a event
-		 * that we are disabling:
-		 */
-		uncore_perf_event_update(box, event);
-		hwc->state |= PERF_HES_UPTODATE;
-	}
-}
-
-static int snb_uncore_imc_event_add(struct perf_event *event, int flags)
-{
-	struct intel_uncore_box *box = uncore_event_to_box(event);
-	struct hw_perf_event *hwc = &event->hw;
-
-	if (!box)
-		return -ENODEV;
-
-	hwc->state = PERF_HES_UPTODATE | PERF_HES_STOPPED;
-	if (!(flags & PERF_EF_START))
-		hwc->state |= PERF_HES_ARCH;
-
-	snb_uncore_imc_event_start(event, 0);
-
-	box->n_events++;
-
-	return 0;
-}
-
-static void snb_uncore_imc_event_del(struct perf_event *event, int flags)
-{
-	struct intel_uncore_box *box = uncore_event_to_box(event);
-	int i;
-
-	snb_uncore_imc_event_stop(event, PERF_EF_UPDATE);
-
-	for (i = 0; i < box->n_events; i++) {
-		if (event == box->event_list[i]) {
-			--box->n_events;
-			break;
-		}
-	}
-}
-
-static int snb_pci2phy_map_init(int devid)
-{
-	struct pci_dev *dev = NULL;
-	struct pci2phy_map *map;
-	int bus, segment;
-
-	dev = pci_get_device(PCI_VENDOR_ID_INTEL, devid, dev);
-	if (!dev)
-		return -ENOTTY;
-
-	bus = dev->bus->number;
-	segment = pci_domain_nr(dev->bus);
-
-	raw_spin_lock(&pci2phy_map_lock);
-	map = __find_pci2phy_map(segment);
-	if (!map) {
-		raw_spin_unlock(&pci2phy_map_lock);
-		pci_dev_put(dev);
-		return -ENOMEM;
-	}
-	map->pbus_to_physid[bus] = 0;
-	raw_spin_unlock(&pci2phy_map_lock);
-
-	pci_dev_put(dev);
-
-	return 0;
-}
-
-static struct pmu snb_uncore_imc_pmu = {
-	.task_ctx_nr	= perf_invalid_context,
-	.event_init	= snb_uncore_imc_event_init,
-	.add		= snb_uncore_imc_event_add,
-	.del		= snb_uncore_imc_event_del,
-	.start		= snb_uncore_imc_event_start,
-	.stop		= snb_uncore_imc_event_stop,
-	.read		= uncore_pmu_event_read,
-};
-
-static struct intel_uncore_ops snb_uncore_imc_ops = {
-	.init_box	= snb_uncore_imc_init_box,
-	.enable_box	= snb_uncore_imc_enable_box,
-	.disable_box	= snb_uncore_imc_disable_box,
-	.disable_event	= snb_uncore_imc_disable_event,
-	.enable_event	= snb_uncore_imc_enable_event,
-	.hw_config	= snb_uncore_imc_hw_config,
-	.read_counter	= snb_uncore_imc_read_counter,
-};
-
-static struct intel_uncore_type snb_uncore_imc = {
-	.name		= "imc",
-	.num_counters   = 2,
-	.num_boxes	= 1,
-	.fixed_ctr_bits	= 32,
-	.fixed_ctr	= SNB_UNCORE_PCI_IMC_CTR_BASE,
-	.event_descs	= snb_uncore_imc_events,
-	.format_group	= &snb_uncore_imc_format_group,
-	.perf_ctr	= SNB_UNCORE_PCI_IMC_DATA_READS_BASE,
-	.event_mask	= SNB_UNCORE_PCI_IMC_EVENT_MASK,
-	.ops		= &snb_uncore_imc_ops,
-	.pmu		= &snb_uncore_imc_pmu,
-};
-
-static struct intel_uncore_type *snb_pci_uncores[] = {
-	[SNB_PCI_UNCORE_IMC]	= &snb_uncore_imc,
-	NULL,
-};
-
-static const struct pci_device_id snb_uncore_pci_ids[] = {
-	{ /* IMC */
-		PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_SNB_IMC),
-		.driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0),
-	},
-	{ /* end: all zeroes */ },
-};
-
-static const struct pci_device_id ivb_uncore_pci_ids[] = {
-	{ /* IMC */
-		PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IVB_IMC),
-		.driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0),
-	},
-	{ /* IMC */
-		PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IVB_E3_IMC),
-		.driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0),
-	},
-	{ /* end: all zeroes */ },
-};
-
-static const struct pci_device_id hsw_uncore_pci_ids[] = {
-	{ /* IMC */
-		PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_HSW_IMC),
-		.driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0),
-	},
-	{ /* IMC */
-		PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_HSW_U_IMC),
-		.driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0),
-	},
-	{ /* end: all zeroes */ },
-};
-
-static const struct pci_device_id bdw_uncore_pci_ids[] = {
-	{ /* IMC */
-		PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BDW_IMC),
-		.driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0),
-	},
-	{ /* end: all zeroes */ },
-};
-
-static struct pci_driver snb_uncore_pci_driver = {
-	.name		= "snb_uncore",
-	.id_table	= snb_uncore_pci_ids,
-};
-
-static struct pci_driver ivb_uncore_pci_driver = {
-	.name		= "ivb_uncore",
-	.id_table	= ivb_uncore_pci_ids,
-};
-
-static struct pci_driver hsw_uncore_pci_driver = {
-	.name		= "hsw_uncore",
-	.id_table	= hsw_uncore_pci_ids,
-};
-
-static struct pci_driver bdw_uncore_pci_driver = {
-	.name		= "bdw_uncore",
-	.id_table	= bdw_uncore_pci_ids,
-};
-
-struct imc_uncore_pci_dev {
-	__u32 pci_id;
-	struct pci_driver *driver;
-};
-#define IMC_DEV(a, d) \
-	{ .pci_id = PCI_DEVICE_ID_INTEL_##a, .driver = (d) }
-
-static const struct imc_uncore_pci_dev desktop_imc_pci_ids[] = {
-	IMC_DEV(SNB_IMC, &snb_uncore_pci_driver),
-	IMC_DEV(IVB_IMC, &ivb_uncore_pci_driver),    /* 3rd Gen Core processor */
-	IMC_DEV(IVB_E3_IMC, &ivb_uncore_pci_driver), /* Xeon E3-1200 v2/3rd Gen Core processor */
-	IMC_DEV(HSW_IMC, &hsw_uncore_pci_driver),    /* 4th Gen Core Processor */
-	IMC_DEV(HSW_U_IMC, &hsw_uncore_pci_driver),  /* 4th Gen Core ULT Mobile Processor */
-	IMC_DEV(BDW_IMC, &bdw_uncore_pci_driver),    /* 5th Gen Core U */
-	{  /* end marker */ }
-};
-
-
-#define for_each_imc_pci_id(x, t) \
-	for (x = (t); (x)->pci_id; x++)
-
-static struct pci_driver *imc_uncore_find_dev(void)
-{
-	const struct imc_uncore_pci_dev *p;
-	int ret;
-
-	for_each_imc_pci_id(p, desktop_imc_pci_ids) {
-		ret = snb_pci2phy_map_init(p->pci_id);
-		if (ret == 0)
-			return p->driver;
-	}
-	return NULL;
-}
-
-static int imc_uncore_pci_init(void)
-{
-	struct pci_driver *imc_drv = imc_uncore_find_dev();
-
-	if (!imc_drv)
-		return -ENODEV;
-
-	uncore_pci_uncores = snb_pci_uncores;
-	uncore_pci_driver = imc_drv;
-
-	return 0;
-}
-
-int snb_uncore_pci_init(void)
-{
-	return imc_uncore_pci_init();
-}
-
-int ivb_uncore_pci_init(void)
-{
-	return imc_uncore_pci_init();
-}
-int hsw_uncore_pci_init(void)
-{
-	return imc_uncore_pci_init();
-}
-
-int bdw_uncore_pci_init(void)
-{
-	return imc_uncore_pci_init();
-}
-
-/* end of Sandy Bridge uncore support */
-
-/* Nehalem uncore support */
-static void nhm_uncore_msr_disable_box(struct intel_uncore_box *box)
-{
-	wrmsrl(NHM_UNC_PERF_GLOBAL_CTL, 0);
-}
-
-static void nhm_uncore_msr_enable_box(struct intel_uncore_box *box)
-{
-	wrmsrl(NHM_UNC_PERF_GLOBAL_CTL, NHM_UNC_GLOBAL_CTL_EN_PC_ALL | NHM_UNC_GLOBAL_CTL_EN_FC);
-}
-
-static void nhm_uncore_msr_enable_event(struct intel_uncore_box *box, struct perf_event *event)
-{
-	struct hw_perf_event *hwc = &event->hw;
-
-	if (hwc->idx < UNCORE_PMC_IDX_FIXED)
-		wrmsrl(hwc->config_base, hwc->config | SNB_UNC_CTL_EN);
-	else
-		wrmsrl(hwc->config_base, NHM_UNC_FIXED_CTR_CTL_EN);
-}
-
-static struct attribute *nhm_uncore_formats_attr[] = {
-	&format_attr_event.attr,
-	&format_attr_umask.attr,
-	&format_attr_edge.attr,
-	&format_attr_inv.attr,
-	&format_attr_cmask8.attr,
-	NULL,
-};
-
-static struct attribute_group nhm_uncore_format_group = {
-	.name = "format",
-	.attrs = nhm_uncore_formats_attr,
-};
-
-static struct uncore_event_desc nhm_uncore_events[] = {
-	INTEL_UNCORE_EVENT_DESC(clockticks,                "event=0xff,umask=0x00"),
-	INTEL_UNCORE_EVENT_DESC(qmc_writes_full_any,       "event=0x2f,umask=0x0f"),
-	INTEL_UNCORE_EVENT_DESC(qmc_normal_reads_any,      "event=0x2c,umask=0x0f"),
-	INTEL_UNCORE_EVENT_DESC(qhl_request_ioh_reads,     "event=0x20,umask=0x01"),
-	INTEL_UNCORE_EVENT_DESC(qhl_request_ioh_writes,    "event=0x20,umask=0x02"),
-	INTEL_UNCORE_EVENT_DESC(qhl_request_remote_reads,  "event=0x20,umask=0x04"),
-	INTEL_UNCORE_EVENT_DESC(qhl_request_remote_writes, "event=0x20,umask=0x08"),
-	INTEL_UNCORE_EVENT_DESC(qhl_request_local_reads,   "event=0x20,umask=0x10"),
-	INTEL_UNCORE_EVENT_DESC(qhl_request_local_writes,  "event=0x20,umask=0x20"),
-	{ /* end: all zeroes */ },
-};
-
-static struct intel_uncore_ops nhm_uncore_msr_ops = {
-	.disable_box	= nhm_uncore_msr_disable_box,
-	.enable_box	= nhm_uncore_msr_enable_box,
-	.disable_event	= snb_uncore_msr_disable_event,
-	.enable_event	= nhm_uncore_msr_enable_event,
-	.read_counter	= uncore_msr_read_counter,
-};
-
-static struct intel_uncore_type nhm_uncore = {
-	.name		= "",
-	.num_counters   = 8,
-	.num_boxes	= 1,
-	.perf_ctr_bits	= 48,
-	.fixed_ctr_bits	= 48,
-	.event_ctl	= NHM_UNC_PERFEVTSEL0,
-	.perf_ctr	= NHM_UNC_UNCORE_PMC0,
-	.fixed_ctr	= NHM_UNC_FIXED_CTR,
-	.fixed_ctl	= NHM_UNC_FIXED_CTR_CTRL,
-	.event_mask	= NHM_UNC_RAW_EVENT_MASK,
-	.event_descs	= nhm_uncore_events,
-	.ops		= &nhm_uncore_msr_ops,
-	.format_group	= &nhm_uncore_format_group,
-};
-
-static struct intel_uncore_type *nhm_msr_uncores[] = {
-	&nhm_uncore,
-	NULL,
-};
-
-void nhm_uncore_cpu_init(void)
-{
-	uncore_msr_uncores = nhm_msr_uncores;
-}
-
-/* end of Nehalem uncore support */
--- zfcpdump-kernel-4.4.orig/arch/x86/kernel/cpu/perf_event_intel_uncore_snbep.c
+++ /dev/null
@@ -1,2503 +0,0 @@
-/* SandyBridge-EP/IvyTown uncore support */
-#include "perf_event_intel_uncore.h"
-
-
-/* SNB-EP Box level control */
-#define SNBEP_PMON_BOX_CTL_RST_CTRL	(1 << 0)
-#define SNBEP_PMON_BOX_CTL_RST_CTRS	(1 << 1)
-#define SNBEP_PMON_BOX_CTL_FRZ		(1 << 8)
-#define SNBEP_PMON_BOX_CTL_FRZ_EN	(1 << 16)
-#define SNBEP_PMON_BOX_CTL_INT		(SNBEP_PMON_BOX_CTL_RST_CTRL | \
-					 SNBEP_PMON_BOX_CTL_RST_CTRS | \
-					 SNBEP_PMON_BOX_CTL_FRZ_EN)
-/* SNB-EP event control */
-#define SNBEP_PMON_CTL_EV_SEL_MASK	0x000000ff
-#define SNBEP_PMON_CTL_UMASK_MASK	0x0000ff00
-#define SNBEP_PMON_CTL_RST		(1 << 17)
-#define SNBEP_PMON_CTL_EDGE_DET		(1 << 18)
-#define SNBEP_PMON_CTL_EV_SEL_EXT	(1 << 21)
-#define SNBEP_PMON_CTL_EN		(1 << 22)
-#define SNBEP_PMON_CTL_INVERT		(1 << 23)
-#define SNBEP_PMON_CTL_TRESH_MASK	0xff000000
-#define SNBEP_PMON_RAW_EVENT_MASK	(SNBEP_PMON_CTL_EV_SEL_MASK | \
-					 SNBEP_PMON_CTL_UMASK_MASK | \
-					 SNBEP_PMON_CTL_EDGE_DET | \
-					 SNBEP_PMON_CTL_INVERT | \
-					 SNBEP_PMON_CTL_TRESH_MASK)
-
-/* SNB-EP Ubox event control */
-#define SNBEP_U_MSR_PMON_CTL_TRESH_MASK		0x1f000000
-#define SNBEP_U_MSR_PMON_RAW_EVENT_MASK		\
-				(SNBEP_PMON_CTL_EV_SEL_MASK | \
-				 SNBEP_PMON_CTL_UMASK_MASK | \
-				 SNBEP_PMON_CTL_EDGE_DET | \
-				 SNBEP_PMON_CTL_INVERT | \
-				 SNBEP_U_MSR_PMON_CTL_TRESH_MASK)
-
-#define SNBEP_CBO_PMON_CTL_TID_EN		(1 << 19)
-#define SNBEP_CBO_MSR_PMON_RAW_EVENT_MASK	(SNBEP_PMON_RAW_EVENT_MASK | \
-						 SNBEP_CBO_PMON_CTL_TID_EN)
-
-/* SNB-EP PCU event control */
-#define SNBEP_PCU_MSR_PMON_CTL_OCC_SEL_MASK	0x0000c000
-#define SNBEP_PCU_MSR_PMON_CTL_TRESH_MASK	0x1f000000
-#define SNBEP_PCU_MSR_PMON_CTL_OCC_INVERT	(1 << 30)
-#define SNBEP_PCU_MSR_PMON_CTL_OCC_EDGE_DET	(1 << 31)
-#define SNBEP_PCU_MSR_PMON_RAW_EVENT_MASK	\
-				(SNBEP_PMON_CTL_EV_SEL_MASK | \
-				 SNBEP_PCU_MSR_PMON_CTL_OCC_SEL_MASK | \
-				 SNBEP_PMON_CTL_EDGE_DET | \
-				 SNBEP_PMON_CTL_EV_SEL_EXT | \
-				 SNBEP_PMON_CTL_INVERT | \
-				 SNBEP_PCU_MSR_PMON_CTL_TRESH_MASK | \
-				 SNBEP_PCU_MSR_PMON_CTL_OCC_INVERT | \
-				 SNBEP_PCU_MSR_PMON_CTL_OCC_EDGE_DET)
-
-#define SNBEP_QPI_PCI_PMON_RAW_EVENT_MASK	\
-				(SNBEP_PMON_RAW_EVENT_MASK | \
-				 SNBEP_PMON_CTL_EV_SEL_EXT)
-
-/* SNB-EP pci control register */
-#define SNBEP_PCI_PMON_BOX_CTL			0xf4
-#define SNBEP_PCI_PMON_CTL0			0xd8
-/* SNB-EP pci counter register */
-#define SNBEP_PCI_PMON_CTR0			0xa0
-
-/* SNB-EP home agent register */
-#define SNBEP_HA_PCI_PMON_BOX_ADDRMATCH0	0x40
-#define SNBEP_HA_PCI_PMON_BOX_ADDRMATCH1	0x44
-#define SNBEP_HA_PCI_PMON_BOX_OPCODEMATCH	0x48
-/* SNB-EP memory controller register */
-#define SNBEP_MC_CHy_PCI_PMON_FIXED_CTL		0xf0
-#define SNBEP_MC_CHy_PCI_PMON_FIXED_CTR		0xd0
-/* SNB-EP QPI register */
-#define SNBEP_Q_Py_PCI_PMON_PKT_MATCH0		0x228
-#define SNBEP_Q_Py_PCI_PMON_PKT_MATCH1		0x22c
-#define SNBEP_Q_Py_PCI_PMON_PKT_MASK0		0x238
-#define SNBEP_Q_Py_PCI_PMON_PKT_MASK1		0x23c
-
-/* SNB-EP Ubox register */
-#define SNBEP_U_MSR_PMON_CTR0			0xc16
-#define SNBEP_U_MSR_PMON_CTL0			0xc10
-
-#define SNBEP_U_MSR_PMON_UCLK_FIXED_CTL		0xc08
-#define SNBEP_U_MSR_PMON_UCLK_FIXED_CTR		0xc09
-
-/* SNB-EP Cbo register */
-#define SNBEP_C0_MSR_PMON_CTR0			0xd16
-#define SNBEP_C0_MSR_PMON_CTL0			0xd10
-#define SNBEP_C0_MSR_PMON_BOX_CTL		0xd04
-#define SNBEP_C0_MSR_PMON_BOX_FILTER		0xd14
-#define SNBEP_CBO_MSR_OFFSET			0x20
-
-#define SNBEP_CB0_MSR_PMON_BOX_FILTER_TID	0x1f
-#define SNBEP_CB0_MSR_PMON_BOX_FILTER_NID	0x3fc00
-#define SNBEP_CB0_MSR_PMON_BOX_FILTER_STATE	0x7c0000
-#define SNBEP_CB0_MSR_PMON_BOX_FILTER_OPC	0xff800000
-
-#define SNBEP_CBO_EVENT_EXTRA_REG(e, m, i) {	\
-	.event = (e),				\
-	.msr = SNBEP_C0_MSR_PMON_BOX_FILTER,	\
-	.config_mask = (m),			\
-	.idx = (i)				\
-}
-
-/* SNB-EP PCU register */
-#define SNBEP_PCU_MSR_PMON_CTR0			0xc36
-#define SNBEP_PCU_MSR_PMON_CTL0			0xc30
-#define SNBEP_PCU_MSR_PMON_BOX_CTL		0xc24
-#define SNBEP_PCU_MSR_PMON_BOX_FILTER		0xc34
-#define SNBEP_PCU_MSR_PMON_BOX_FILTER_MASK	0xffffffff
-#define SNBEP_PCU_MSR_CORE_C3_CTR		0x3fc
-#define SNBEP_PCU_MSR_CORE_C6_CTR		0x3fd
-
-/* IVBEP event control */
-#define IVBEP_PMON_BOX_CTL_INT		(SNBEP_PMON_BOX_CTL_RST_CTRL | \
-					 SNBEP_PMON_BOX_CTL_RST_CTRS)
-#define IVBEP_PMON_RAW_EVENT_MASK		(SNBEP_PMON_CTL_EV_SEL_MASK | \
-					 SNBEP_PMON_CTL_UMASK_MASK | \
-					 SNBEP_PMON_CTL_EDGE_DET | \
-					 SNBEP_PMON_CTL_TRESH_MASK)
-/* IVBEP Ubox */
-#define IVBEP_U_MSR_PMON_GLOBAL_CTL		0xc00
-#define IVBEP_U_PMON_GLOBAL_FRZ_ALL		(1 << 31)
-#define IVBEP_U_PMON_GLOBAL_UNFRZ_ALL		(1 << 29)
-
-#define IVBEP_U_MSR_PMON_RAW_EVENT_MASK	\
-				(SNBEP_PMON_CTL_EV_SEL_MASK | \
-				 SNBEP_PMON_CTL_UMASK_MASK | \
-				 SNBEP_PMON_CTL_EDGE_DET | \
-				 SNBEP_U_MSR_PMON_CTL_TRESH_MASK)
-/* IVBEP Cbo */
-#define IVBEP_CBO_MSR_PMON_RAW_EVENT_MASK		(IVBEP_PMON_RAW_EVENT_MASK | \
-						 SNBEP_CBO_PMON_CTL_TID_EN)
-
-#define IVBEP_CB0_MSR_PMON_BOX_FILTER_TID		(0x1fULL << 0)
-#define IVBEP_CB0_MSR_PMON_BOX_FILTER_LINK	(0xfULL << 5)
-#define IVBEP_CB0_MSR_PMON_BOX_FILTER_STATE	(0x3fULL << 17)
-#define IVBEP_CB0_MSR_PMON_BOX_FILTER_NID		(0xffffULL << 32)
-#define IVBEP_CB0_MSR_PMON_BOX_FILTER_OPC		(0x1ffULL << 52)
-#define IVBEP_CB0_MSR_PMON_BOX_FILTER_C6		(0x1ULL << 61)
-#define IVBEP_CB0_MSR_PMON_BOX_FILTER_NC		(0x1ULL << 62)
-#define IVBEP_CB0_MSR_PMON_BOX_FILTER_ISOC	(0x1ULL << 63)
-
-/* IVBEP home agent */
-#define IVBEP_HA_PCI_PMON_CTL_Q_OCC_RST		(1 << 16)
-#define IVBEP_HA_PCI_PMON_RAW_EVENT_MASK		\
-				(IVBEP_PMON_RAW_EVENT_MASK | \
-				 IVBEP_HA_PCI_PMON_CTL_Q_OCC_RST)
-/* IVBEP PCU */
-#define IVBEP_PCU_MSR_PMON_RAW_EVENT_MASK	\
-				(SNBEP_PMON_CTL_EV_SEL_MASK | \
-				 SNBEP_PMON_CTL_EV_SEL_EXT | \
-				 SNBEP_PCU_MSR_PMON_CTL_OCC_SEL_MASK | \
-				 SNBEP_PMON_CTL_EDGE_DET | \
-				 SNBEP_PCU_MSR_PMON_CTL_TRESH_MASK | \
-				 SNBEP_PCU_MSR_PMON_CTL_OCC_INVERT | \
-				 SNBEP_PCU_MSR_PMON_CTL_OCC_EDGE_DET)
-/* IVBEP QPI */
-#define IVBEP_QPI_PCI_PMON_RAW_EVENT_MASK	\
-				(IVBEP_PMON_RAW_EVENT_MASK | \
-				 SNBEP_PMON_CTL_EV_SEL_EXT)
-
-#define __BITS_VALUE(x, i, n)  ((typeof(x))(((x) >> ((i) * (n))) & \
-				((1ULL << (n)) - 1)))
-
-/* Haswell-EP Ubox */
-#define HSWEP_U_MSR_PMON_CTR0			0x709
-#define HSWEP_U_MSR_PMON_CTL0			0x705
-#define HSWEP_U_MSR_PMON_FILTER			0x707
-
-#define HSWEP_U_MSR_PMON_UCLK_FIXED_CTL		0x703
-#define HSWEP_U_MSR_PMON_UCLK_FIXED_CTR		0x704
-
-#define HSWEP_U_MSR_PMON_BOX_FILTER_TID		(0x1 << 0)
-#define HSWEP_U_MSR_PMON_BOX_FILTER_CID		(0x1fULL << 1)
-#define HSWEP_U_MSR_PMON_BOX_FILTER_MASK \
-					(HSWEP_U_MSR_PMON_BOX_FILTER_TID | \
-					 HSWEP_U_MSR_PMON_BOX_FILTER_CID)
-
-/* Haswell-EP CBo */
-#define HSWEP_C0_MSR_PMON_CTR0			0xe08
-#define HSWEP_C0_MSR_PMON_CTL0			0xe01
-#define HSWEP_C0_MSR_PMON_BOX_CTL			0xe00
-#define HSWEP_C0_MSR_PMON_BOX_FILTER0		0xe05
-#define HSWEP_CBO_MSR_OFFSET			0x10
-
-
-#define HSWEP_CB0_MSR_PMON_BOX_FILTER_TID		(0x3fULL << 0)
-#define HSWEP_CB0_MSR_PMON_BOX_FILTER_LINK	(0xfULL << 6)
-#define HSWEP_CB0_MSR_PMON_BOX_FILTER_STATE	(0x7fULL << 17)
-#define HSWEP_CB0_MSR_PMON_BOX_FILTER_NID		(0xffffULL << 32)
-#define HSWEP_CB0_MSR_PMON_BOX_FILTER_OPC		(0x1ffULL << 52)
-#define HSWEP_CB0_MSR_PMON_BOX_FILTER_C6		(0x1ULL << 61)
-#define HSWEP_CB0_MSR_PMON_BOX_FILTER_NC		(0x1ULL << 62)
-#define HSWEP_CB0_MSR_PMON_BOX_FILTER_ISOC	(0x1ULL << 63)
-
-
-/* Haswell-EP Sbox */
-#define HSWEP_S0_MSR_PMON_CTR0			0x726
-#define HSWEP_S0_MSR_PMON_CTL0			0x721
-#define HSWEP_S0_MSR_PMON_BOX_CTL			0x720
-#define HSWEP_SBOX_MSR_OFFSET			0xa
-#define HSWEP_S_MSR_PMON_RAW_EVENT_MASK		(SNBEP_PMON_RAW_EVENT_MASK | \
-						 SNBEP_CBO_PMON_CTL_TID_EN)
-
-/* Haswell-EP PCU */
-#define HSWEP_PCU_MSR_PMON_CTR0			0x717
-#define HSWEP_PCU_MSR_PMON_CTL0			0x711
-#define HSWEP_PCU_MSR_PMON_BOX_CTL		0x710
-#define HSWEP_PCU_MSR_PMON_BOX_FILTER		0x715
-
-
-DEFINE_UNCORE_FORMAT_ATTR(event, event, "config:0-7");
-DEFINE_UNCORE_FORMAT_ATTR(event_ext, event, "config:0-7,21");
-DEFINE_UNCORE_FORMAT_ATTR(umask, umask, "config:8-15");
-DEFINE_UNCORE_FORMAT_ATTR(edge, edge, "config:18");
-DEFINE_UNCORE_FORMAT_ATTR(tid_en, tid_en, "config:19");
-DEFINE_UNCORE_FORMAT_ATTR(inv, inv, "config:23");
-DEFINE_UNCORE_FORMAT_ATTR(thresh8, thresh, "config:24-31");
-DEFINE_UNCORE_FORMAT_ATTR(thresh5, thresh, "config:24-28");
-DEFINE_UNCORE_FORMAT_ATTR(occ_sel, occ_sel, "config:14-15");
-DEFINE_UNCORE_FORMAT_ATTR(occ_invert, occ_invert, "config:30");
-DEFINE_UNCORE_FORMAT_ATTR(occ_edge, occ_edge, "config:14-51");
-DEFINE_UNCORE_FORMAT_ATTR(filter_tid, filter_tid, "config1:0-4");
-DEFINE_UNCORE_FORMAT_ATTR(filter_tid2, filter_tid, "config1:0");
-DEFINE_UNCORE_FORMAT_ATTR(filter_tid3, filter_tid, "config1:0-5");
-DEFINE_UNCORE_FORMAT_ATTR(filter_cid, filter_cid, "config1:5");
-DEFINE_UNCORE_FORMAT_ATTR(filter_link, filter_link, "config1:5-8");
-DEFINE_UNCORE_FORMAT_ATTR(filter_link2, filter_link, "config1:6-8");
-DEFINE_UNCORE_FORMAT_ATTR(filter_nid, filter_nid, "config1:10-17");
-DEFINE_UNCORE_FORMAT_ATTR(filter_nid2, filter_nid, "config1:32-47");
-DEFINE_UNCORE_FORMAT_ATTR(filter_state, filter_state, "config1:18-22");
-DEFINE_UNCORE_FORMAT_ATTR(filter_state2, filter_state, "config1:17-22");
-DEFINE_UNCORE_FORMAT_ATTR(filter_state3, filter_state, "config1:17-23");
-DEFINE_UNCORE_FORMAT_ATTR(filter_opc, filter_opc, "config1:23-31");
-DEFINE_UNCORE_FORMAT_ATTR(filter_opc2, filter_opc, "config1:52-60");
-DEFINE_UNCORE_FORMAT_ATTR(filter_nc, filter_nc, "config1:62");
-DEFINE_UNCORE_FORMAT_ATTR(filter_c6, filter_c6, "config1:61");
-DEFINE_UNCORE_FORMAT_ATTR(filter_isoc, filter_isoc, "config1:63");
-DEFINE_UNCORE_FORMAT_ATTR(filter_band0, filter_band0, "config1:0-7");
-DEFINE_UNCORE_FORMAT_ATTR(filter_band1, filter_band1, "config1:8-15");
-DEFINE_UNCORE_FORMAT_ATTR(filter_band2, filter_band2, "config1:16-23");
-DEFINE_UNCORE_FORMAT_ATTR(filter_band3, filter_band3, "config1:24-31");
-DEFINE_UNCORE_FORMAT_ATTR(match_rds, match_rds, "config1:48-51");
-DEFINE_UNCORE_FORMAT_ATTR(match_rnid30, match_rnid30, "config1:32-35");
-DEFINE_UNCORE_FORMAT_ATTR(match_rnid4, match_rnid4, "config1:31");
-DEFINE_UNCORE_FORMAT_ATTR(match_dnid, match_dnid, "config1:13-17");
-DEFINE_UNCORE_FORMAT_ATTR(match_mc, match_mc, "config1:9-12");
-DEFINE_UNCORE_FORMAT_ATTR(match_opc, match_opc, "config1:5-8");
-DEFINE_UNCORE_FORMAT_ATTR(match_vnw, match_vnw, "config1:3-4");
-DEFINE_UNCORE_FORMAT_ATTR(match0, match0, "config1:0-31");
-DEFINE_UNCORE_FORMAT_ATTR(match1, match1, "config1:32-63");
-DEFINE_UNCORE_FORMAT_ATTR(mask_rds, mask_rds, "config2:48-51");
-DEFINE_UNCORE_FORMAT_ATTR(mask_rnid30, mask_rnid30, "config2:32-35");
-DEFINE_UNCORE_FORMAT_ATTR(mask_rnid4, mask_rnid4, "config2:31");
-DEFINE_UNCORE_FORMAT_ATTR(mask_dnid, mask_dnid, "config2:13-17");
-DEFINE_UNCORE_FORMAT_ATTR(mask_mc, mask_mc, "config2:9-12");
-DEFINE_UNCORE_FORMAT_ATTR(mask_opc, mask_opc, "config2:5-8");
-DEFINE_UNCORE_FORMAT_ATTR(mask_vnw, mask_vnw, "config2:3-4");
-DEFINE_UNCORE_FORMAT_ATTR(mask0, mask0, "config2:0-31");
-DEFINE_UNCORE_FORMAT_ATTR(mask1, mask1, "config2:32-63");
-
-static void snbep_uncore_pci_disable_box(struct intel_uncore_box *box)
-{
-	struct pci_dev *pdev = box->pci_dev;
-	int box_ctl = uncore_pci_box_ctl(box);
-	u32 config = 0;
-
-	if (!pci_read_config_dword(pdev, box_ctl, &config)) {
-		config |= SNBEP_PMON_BOX_CTL_FRZ;
-		pci_write_config_dword(pdev, box_ctl, config);
-	}
-}
-
-static void snbep_uncore_pci_enable_box(struct intel_uncore_box *box)
-{
-	struct pci_dev *pdev = box->pci_dev;
-	int box_ctl = uncore_pci_box_ctl(box);
-	u32 config = 0;
-
-	if (!pci_read_config_dword(pdev, box_ctl, &config)) {
-		config &= ~SNBEP_PMON_BOX_CTL_FRZ;
-		pci_write_config_dword(pdev, box_ctl, config);
-	}
-}
-
-static void snbep_uncore_pci_enable_event(struct intel_uncore_box *box, struct perf_event *event)
-{
-	struct pci_dev *pdev = box->pci_dev;
-	struct hw_perf_event *hwc = &event->hw;
-
-	pci_write_config_dword(pdev, hwc->config_base, hwc->config | SNBEP_PMON_CTL_EN);
-}
-
-static void snbep_uncore_pci_disable_event(struct intel_uncore_box *box, struct perf_event *event)
-{
-	struct pci_dev *pdev = box->pci_dev;
-	struct hw_perf_event *hwc = &event->hw;
-
-	pci_write_config_dword(pdev, hwc->config_base, hwc->config);
-}
-
-static u64 snbep_uncore_pci_read_counter(struct intel_uncore_box *box, struct perf_event *event)
-{
-	struct pci_dev *pdev = box->pci_dev;
-	struct hw_perf_event *hwc = &event->hw;
-	u64 count = 0;
-
-	pci_read_config_dword(pdev, hwc->event_base, (u32 *)&count);
-	pci_read_config_dword(pdev, hwc->event_base + 4, (u32 *)&count + 1);
-
-	return count;
-}
-
-static void snbep_uncore_pci_init_box(struct intel_uncore_box *box)
-{
-	struct pci_dev *pdev = box->pci_dev;
-
-	pci_write_config_dword(pdev, SNBEP_PCI_PMON_BOX_CTL, SNBEP_PMON_BOX_CTL_INT);
-}
-
-static void snbep_uncore_msr_disable_box(struct intel_uncore_box *box)
-{
-	u64 config;
-	unsigned msr;
-
-	msr = uncore_msr_box_ctl(box);
-	if (msr) {
-		rdmsrl(msr, config);
-		config |= SNBEP_PMON_BOX_CTL_FRZ;
-		wrmsrl(msr, config);
-	}
-}
-
-static void snbep_uncore_msr_enable_box(struct intel_uncore_box *box)
-{
-	u64 config;
-	unsigned msr;
-
-	msr = uncore_msr_box_ctl(box);
-	if (msr) {
-		rdmsrl(msr, config);
-		config &= ~SNBEP_PMON_BOX_CTL_FRZ;
-		wrmsrl(msr, config);
-	}
-}
-
-static void snbep_uncore_msr_enable_event(struct intel_uncore_box *box, struct perf_event *event)
-{
-	struct hw_perf_event *hwc = &event->hw;
-	struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
-
-	if (reg1->idx != EXTRA_REG_NONE)
-		wrmsrl(reg1->reg, uncore_shared_reg_config(box, 0));
-
-	wrmsrl(hwc->config_base, hwc->config | SNBEP_PMON_CTL_EN);
-}
-
-static void snbep_uncore_msr_disable_event(struct intel_uncore_box *box,
-					struct perf_event *event)
-{
-	struct hw_perf_event *hwc = &event->hw;
-
-	wrmsrl(hwc->config_base, hwc->config);
-}
-
-static void snbep_uncore_msr_init_box(struct intel_uncore_box *box)
-{
-	unsigned msr = uncore_msr_box_ctl(box);
-
-	if (msr)
-		wrmsrl(msr, SNBEP_PMON_BOX_CTL_INT);
-}
-
-static struct attribute *snbep_uncore_formats_attr[] = {
-	&format_attr_event.attr,
-	&format_attr_umask.attr,
-	&format_attr_edge.attr,
-	&format_attr_inv.attr,
-	&format_attr_thresh8.attr,
-	NULL,
-};
-
-static struct attribute *snbep_uncore_ubox_formats_attr[] = {
-	&format_attr_event.attr,
-	&format_attr_umask.attr,
-	&format_attr_edge.attr,
-	&format_attr_inv.attr,
-	&format_attr_thresh5.attr,
-	NULL,
-};
-
-static struct attribute *snbep_uncore_cbox_formats_attr[] = {
-	&format_attr_event.attr,
-	&format_attr_umask.attr,
-	&format_attr_edge.attr,
-	&format_attr_tid_en.attr,
-	&format_attr_inv.attr,
-	&format_attr_thresh8.attr,
-	&format_attr_filter_tid.attr,
-	&format_attr_filter_nid.attr,
-	&format_attr_filter_state.attr,
-	&format_attr_filter_opc.attr,
-	NULL,
-};
-
-static struct attribute *snbep_uncore_pcu_formats_attr[] = {
-	&format_attr_event_ext.attr,
-	&format_attr_occ_sel.attr,
-	&format_attr_edge.attr,
-	&format_attr_inv.attr,
-	&format_attr_thresh5.attr,
-	&format_attr_occ_invert.attr,
-	&format_attr_occ_edge.attr,
-	&format_attr_filter_band0.attr,
-	&format_attr_filter_band1.attr,
-	&format_attr_filter_band2.attr,
-	&format_attr_filter_band3.attr,
-	NULL,
-};
-
-static struct attribute *snbep_uncore_qpi_formats_attr[] = {
-	&format_attr_event_ext.attr,
-	&format_attr_umask.attr,
-	&format_attr_edge.attr,
-	&format_attr_inv.attr,
-	&format_attr_thresh8.attr,
-	&format_attr_match_rds.attr,
-	&format_attr_match_rnid30.attr,
-	&format_attr_match_rnid4.attr,
-	&format_attr_match_dnid.attr,
-	&format_attr_match_mc.attr,
-	&format_attr_match_opc.attr,
-	&format_attr_match_vnw.attr,
-	&format_attr_match0.attr,
-	&format_attr_match1.attr,
-	&format_attr_mask_rds.attr,
-	&format_attr_mask_rnid30.attr,
-	&format_attr_mask_rnid4.attr,
-	&format_attr_mask_dnid.attr,
-	&format_attr_mask_mc.attr,
-	&format_attr_mask_opc.attr,
-	&format_attr_mask_vnw.attr,
-	&format_attr_mask0.attr,
-	&format_attr_mask1.attr,
-	NULL,
-};
-
-static struct uncore_event_desc snbep_uncore_imc_events[] = {
-	INTEL_UNCORE_EVENT_DESC(clockticks,      "event=0xff,umask=0x00"),
-	INTEL_UNCORE_EVENT_DESC(cas_count_read,  "event=0x04,umask=0x03"),
-	INTEL_UNCORE_EVENT_DESC(cas_count_read.scale, "6.103515625e-5"),
-	INTEL_UNCORE_EVENT_DESC(cas_count_read.unit, "MiB"),
-	INTEL_UNCORE_EVENT_DESC(cas_count_write, "event=0x04,umask=0x0c"),
-	INTEL_UNCORE_EVENT_DESC(cas_count_write.scale, "6.103515625e-5"),
-	INTEL_UNCORE_EVENT_DESC(cas_count_write.unit, "MiB"),
-	{ /* end: all zeroes */ },
-};
-
-static struct uncore_event_desc snbep_uncore_qpi_events[] = {
-	INTEL_UNCORE_EVENT_DESC(clockticks,       "event=0x14"),
-	INTEL_UNCORE_EVENT_DESC(txl_flits_active, "event=0x00,umask=0x06"),
-	INTEL_UNCORE_EVENT_DESC(drs_data,         "event=0x102,umask=0x08"),
-	INTEL_UNCORE_EVENT_DESC(ncb_data,         "event=0x103,umask=0x04"),
-	{ /* end: all zeroes */ },
-};
-
-static struct attribute_group snbep_uncore_format_group = {
-	.name = "format",
-	.attrs = snbep_uncore_formats_attr,
-};
-
-static struct attribute_group snbep_uncore_ubox_format_group = {
-	.name = "format",
-	.attrs = snbep_uncore_ubox_formats_attr,
-};
-
-static struct attribute_group snbep_uncore_cbox_format_group = {
-	.name = "format",
-	.attrs = snbep_uncore_cbox_formats_attr,
-};
-
-static struct attribute_group snbep_uncore_pcu_format_group = {
-	.name = "format",
-	.attrs = snbep_uncore_pcu_formats_attr,
-};
-
-static struct attribute_group snbep_uncore_qpi_format_group = {
-	.name = "format",
-	.attrs = snbep_uncore_qpi_formats_attr,
-};
-
-#define __SNBEP_UNCORE_MSR_OPS_COMMON_INIT()			\
-	.disable_box	= snbep_uncore_msr_disable_box,		\
-	.enable_box	= snbep_uncore_msr_enable_box,		\
-	.disable_event	= snbep_uncore_msr_disable_event,	\
-	.enable_event	= snbep_uncore_msr_enable_event,	\
-	.read_counter	= uncore_msr_read_counter
-
-#define SNBEP_UNCORE_MSR_OPS_COMMON_INIT()			\
-	__SNBEP_UNCORE_MSR_OPS_COMMON_INIT(),			\
-	.init_box	= snbep_uncore_msr_init_box		\
-
-static struct intel_uncore_ops snbep_uncore_msr_ops = {
-	SNBEP_UNCORE_MSR_OPS_COMMON_INIT(),
-};
-
-#define SNBEP_UNCORE_PCI_OPS_COMMON_INIT()			\
-	.init_box	= snbep_uncore_pci_init_box,		\
-	.disable_box	= snbep_uncore_pci_disable_box,		\
-	.enable_box	= snbep_uncore_pci_enable_box,		\
-	.disable_event	= snbep_uncore_pci_disable_event,	\
-	.read_counter	= snbep_uncore_pci_read_counter
-
-static struct intel_uncore_ops snbep_uncore_pci_ops = {
-	SNBEP_UNCORE_PCI_OPS_COMMON_INIT(),
-	.enable_event	= snbep_uncore_pci_enable_event,	\
-};
-
-static struct event_constraint snbep_uncore_cbox_constraints[] = {
-	UNCORE_EVENT_CONSTRAINT(0x01, 0x1),
-	UNCORE_EVENT_CONSTRAINT(0x02, 0x3),
-	UNCORE_EVENT_CONSTRAINT(0x04, 0x3),
-	UNCORE_EVENT_CONSTRAINT(0x05, 0x3),
-	UNCORE_EVENT_CONSTRAINT(0x07, 0x3),
-	UNCORE_EVENT_CONSTRAINT(0x09, 0x3),
-	UNCORE_EVENT_CONSTRAINT(0x11, 0x1),
-	UNCORE_EVENT_CONSTRAINT(0x12, 0x3),
-	UNCORE_EVENT_CONSTRAINT(0x13, 0x3),
-	UNCORE_EVENT_CONSTRAINT(0x1b, 0xc),
-	UNCORE_EVENT_CONSTRAINT(0x1c, 0xc),
-	UNCORE_EVENT_CONSTRAINT(0x1d, 0xc),
-	UNCORE_EVENT_CONSTRAINT(0x1e, 0xc),
-	EVENT_CONSTRAINT_OVERLAP(0x1f, 0xe, 0xff),
-	UNCORE_EVENT_CONSTRAINT(0x21, 0x3),
-	UNCORE_EVENT_CONSTRAINT(0x23, 0x3),
-	UNCORE_EVENT_CONSTRAINT(0x31, 0x3),
-	UNCORE_EVENT_CONSTRAINT(0x32, 0x3),
-	UNCORE_EVENT_CONSTRAINT(0x33, 0x3),
-	UNCORE_EVENT_CONSTRAINT(0x34, 0x3),
-	UNCORE_EVENT_CONSTRAINT(0x35, 0x3),
-	UNCORE_EVENT_CONSTRAINT(0x36, 0x1),
-	UNCORE_EVENT_CONSTRAINT(0x37, 0x3),
-	UNCORE_EVENT_CONSTRAINT(0x38, 0x3),
-	UNCORE_EVENT_CONSTRAINT(0x39, 0x3),
-	UNCORE_EVENT_CONSTRAINT(0x3b, 0x1),
-	EVENT_CONSTRAINT_END
-};
-
-static struct event_constraint snbep_uncore_r2pcie_constraints[] = {
-	UNCORE_EVENT_CONSTRAINT(0x10, 0x3),
-	UNCORE_EVENT_CONSTRAINT(0x11, 0x3),
-	UNCORE_EVENT_CONSTRAINT(0x12, 0x1),
-	UNCORE_EVENT_CONSTRAINT(0x23, 0x3),
-	UNCORE_EVENT_CONSTRAINT(0x24, 0x3),
-	UNCORE_EVENT_CONSTRAINT(0x25, 0x3),
-	UNCORE_EVENT_CONSTRAINT(0x26, 0x3),
-	UNCORE_EVENT_CONSTRAINT(0x32, 0x3),
-	UNCORE_EVENT_CONSTRAINT(0x33, 0x3),
-	UNCORE_EVENT_CONSTRAINT(0x34, 0x3),
-	EVENT_CONSTRAINT_END
-};
-
-static struct event_constraint snbep_uncore_r3qpi_constraints[] = {
-	UNCORE_EVENT_CONSTRAINT(0x10, 0x3),
-	UNCORE_EVENT_CONSTRAINT(0x11, 0x3),
-	UNCORE_EVENT_CONSTRAINT(0x12, 0x3),
-	UNCORE_EVENT_CONSTRAINT(0x13, 0x1),
-	UNCORE_EVENT_CONSTRAINT(0x20, 0x3),
-	UNCORE_EVENT_CONSTRAINT(0x21, 0x3),
-	UNCORE_EVENT_CONSTRAINT(0x22, 0x3),
-	UNCORE_EVENT_CONSTRAINT(0x23, 0x3),
-	UNCORE_EVENT_CONSTRAINT(0x24, 0x3),
-	UNCORE_EVENT_CONSTRAINT(0x25, 0x3),
-	UNCORE_EVENT_CONSTRAINT(0x26, 0x3),
-	UNCORE_EVENT_CONSTRAINT(0x28, 0x3),
-	UNCORE_EVENT_CONSTRAINT(0x29, 0x3),
-	UNCORE_EVENT_CONSTRAINT(0x2a, 0x3),
-	UNCORE_EVENT_CONSTRAINT(0x2b, 0x3),
-	UNCORE_EVENT_CONSTRAINT(0x2c, 0x3),
-	UNCORE_EVENT_CONSTRAINT(0x2d, 0x3),
-	UNCORE_EVENT_CONSTRAINT(0x2e, 0x3),
-	UNCORE_EVENT_CONSTRAINT(0x2f, 0x3),
-	UNCORE_EVENT_CONSTRAINT(0x30, 0x3),
-	UNCORE_EVENT_CONSTRAINT(0x31, 0x3),
-	UNCORE_EVENT_CONSTRAINT(0x32, 0x3),
-	UNCORE_EVENT_CONSTRAINT(0x33, 0x3),
-	UNCORE_EVENT_CONSTRAINT(0x34, 0x3),
-	UNCORE_EVENT_CONSTRAINT(0x36, 0x3),
-	UNCORE_EVENT_CONSTRAINT(0x37, 0x3),
-	UNCORE_EVENT_CONSTRAINT(0x38, 0x3),
-	UNCORE_EVENT_CONSTRAINT(0x39, 0x3),
-	EVENT_CONSTRAINT_END
-};
-
-static struct intel_uncore_type snbep_uncore_ubox = {
-	.name		= "ubox",
-	.num_counters   = 2,
-	.num_boxes	= 1,
-	.perf_ctr_bits	= 44,
-	.fixed_ctr_bits	= 48,
-	.perf_ctr	= SNBEP_U_MSR_PMON_CTR0,
-	.event_ctl	= SNBEP_U_MSR_PMON_CTL0,
-	.event_mask	= SNBEP_U_MSR_PMON_RAW_EVENT_MASK,
-	.fixed_ctr	= SNBEP_U_MSR_PMON_UCLK_FIXED_CTR,
-	.fixed_ctl	= SNBEP_U_MSR_PMON_UCLK_FIXED_CTL,
-	.ops		= &snbep_uncore_msr_ops,
-	.format_group	= &snbep_uncore_ubox_format_group,
-};
-
-static struct extra_reg snbep_uncore_cbox_extra_regs[] = {
-	SNBEP_CBO_EVENT_EXTRA_REG(SNBEP_CBO_PMON_CTL_TID_EN,
-				  SNBEP_CBO_PMON_CTL_TID_EN, 0x1),
-	SNBEP_CBO_EVENT_EXTRA_REG(0x0334, 0xffff, 0x4),
-	SNBEP_CBO_EVENT_EXTRA_REG(0x4334, 0xffff, 0x6),
-	SNBEP_CBO_EVENT_EXTRA_REG(0x0534, 0xffff, 0x4),
-	SNBEP_CBO_EVENT_EXTRA_REG(0x4534, 0xffff, 0x6),
-	SNBEP_CBO_EVENT_EXTRA_REG(0x0934, 0xffff, 0x4),
-	SNBEP_CBO_EVENT_EXTRA_REG(0x4934, 0xffff, 0x6),
-	SNBEP_CBO_EVENT_EXTRA_REG(0x4134, 0xffff, 0x6),
-	SNBEP_CBO_EVENT_EXTRA_REG(0x0135, 0xffff, 0x8),
-	SNBEP_CBO_EVENT_EXTRA_REG(0x0335, 0xffff, 0x8),
-	SNBEP_CBO_EVENT_EXTRA_REG(0x4135, 0xffff, 0xa),
-	SNBEP_CBO_EVENT_EXTRA_REG(0x4335, 0xffff, 0xa),
-	SNBEP_CBO_EVENT_EXTRA_REG(0x4435, 0xffff, 0x2),
-	SNBEP_CBO_EVENT_EXTRA_REG(0x4835, 0xffff, 0x2),
-	SNBEP_CBO_EVENT_EXTRA_REG(0x4a35, 0xffff, 0x2),
-	SNBEP_CBO_EVENT_EXTRA_REG(0x5035, 0xffff, 0x2),
-	SNBEP_CBO_EVENT_EXTRA_REG(0x0136, 0xffff, 0x8),
-	SNBEP_CBO_EVENT_EXTRA_REG(0x0336, 0xffff, 0x8),
-	SNBEP_CBO_EVENT_EXTRA_REG(0x4136, 0xffff, 0xa),
-	SNBEP_CBO_EVENT_EXTRA_REG(0x4336, 0xffff, 0xa),
-	SNBEP_CBO_EVENT_EXTRA_REG(0x4436, 0xffff, 0x2),
-	SNBEP_CBO_EVENT_EXTRA_REG(0x4836, 0xffff, 0x2),
-	SNBEP_CBO_EVENT_EXTRA_REG(0x4a36, 0xffff, 0x2),
-	SNBEP_CBO_EVENT_EXTRA_REG(0x4037, 0x40ff, 0x2),
-	EVENT_EXTRA_END
-};
-
-static void snbep_cbox_put_constraint(struct intel_uncore_box *box, struct perf_event *event)
-{
-	struct hw_perf_event_extra *reg1 = &event->hw.extra_reg;
-	struct intel_uncore_extra_reg *er = &box->shared_regs[0];
-	int i;
-
-	if (uncore_box_is_fake(box))
-		return;
-
-	for (i = 0; i < 5; i++) {
-		if (reg1->alloc & (0x1 << i))
-			atomic_sub(1 << (i * 6), &er->ref);
-	}
-	reg1->alloc = 0;
-}
-
-static struct event_constraint *
-__snbep_cbox_get_constraint(struct intel_uncore_box *box, struct perf_event *event,
-			    u64 (*cbox_filter_mask)(int fields))
-{
-	struct hw_perf_event_extra *reg1 = &event->hw.extra_reg;
-	struct intel_uncore_extra_reg *er = &box->shared_regs[0];
-	int i, alloc = 0;
-	unsigned long flags;
-	u64 mask;
-
-	if (reg1->idx == EXTRA_REG_NONE)
-		return NULL;
-
-	raw_spin_lock_irqsave(&er->lock, flags);
-	for (i = 0; i < 5; i++) {
-		if (!(reg1->idx & (0x1 << i)))
-			continue;
-		if (!uncore_box_is_fake(box) && (reg1->alloc & (0x1 << i)))
-			continue;
-
-		mask = cbox_filter_mask(0x1 << i);
-		if (!__BITS_VALUE(atomic_read(&er->ref), i, 6) ||
-		    !((reg1->config ^ er->config) & mask)) {
-			atomic_add(1 << (i * 6), &er->ref);
-			er->config &= ~mask;
-			er->config |= reg1->config & mask;
-			alloc |= (0x1 << i);
-		} else {
-			break;
-		}
-	}
-	raw_spin_unlock_irqrestore(&er->lock, flags);
-	if (i < 5)
-		goto fail;
-
-	if (!uncore_box_is_fake(box))
-		reg1->alloc |= alloc;
-
-	return NULL;
-fail:
-	for (; i >= 0; i--) {
-		if (alloc & (0x1 << i))
-			atomic_sub(1 << (i * 6), &er->ref);
-	}
-	return &uncore_constraint_empty;
-}
-
-static u64 snbep_cbox_filter_mask(int fields)
-{
-	u64 mask = 0;
-
-	if (fields & 0x1)
-		mask |= SNBEP_CB0_MSR_PMON_BOX_FILTER_TID;
-	if (fields & 0x2)
-		mask |= SNBEP_CB0_MSR_PMON_BOX_FILTER_NID;
-	if (fields & 0x4)
-		mask |= SNBEP_CB0_MSR_PMON_BOX_FILTER_STATE;
-	if (fields & 0x8)
-		mask |= SNBEP_CB0_MSR_PMON_BOX_FILTER_OPC;
-
-	return mask;
-}
-
-static struct event_constraint *
-snbep_cbox_get_constraint(struct intel_uncore_box *box, struct perf_event *event)
-{
-	return __snbep_cbox_get_constraint(box, event, snbep_cbox_filter_mask);
-}
-
-static int snbep_cbox_hw_config(struct intel_uncore_box *box, struct perf_event *event)
-{
-	struct hw_perf_event_extra *reg1 = &event->hw.extra_reg;
-	struct extra_reg *er;
-	int idx = 0;
-
-	for (er = snbep_uncore_cbox_extra_regs; er->msr; er++) {
-		if (er->event != (event->hw.config & er->config_mask))
-			continue;
-		idx |= er->idx;
-	}
-
-	if (idx) {
-		reg1->reg = SNBEP_C0_MSR_PMON_BOX_FILTER +
-			SNBEP_CBO_MSR_OFFSET * box->pmu->pmu_idx;
-		reg1->config = event->attr.config1 & snbep_cbox_filter_mask(idx);
-		reg1->idx = idx;
-	}
-	return 0;
-}
-
-static struct intel_uncore_ops snbep_uncore_cbox_ops = {
-	SNBEP_UNCORE_MSR_OPS_COMMON_INIT(),
-	.hw_config		= snbep_cbox_hw_config,
-	.get_constraint		= snbep_cbox_get_constraint,
-	.put_constraint		= snbep_cbox_put_constraint,
-};
-
-static struct intel_uncore_type snbep_uncore_cbox = {
-	.name			= "cbox",
-	.num_counters		= 4,
-	.num_boxes		= 8,
-	.perf_ctr_bits		= 44,
-	.event_ctl		= SNBEP_C0_MSR_PMON_CTL0,
-	.perf_ctr		= SNBEP_C0_MSR_PMON_CTR0,
-	.event_mask		= SNBEP_CBO_MSR_PMON_RAW_EVENT_MASK,
-	.box_ctl		= SNBEP_C0_MSR_PMON_BOX_CTL,
-	.msr_offset		= SNBEP_CBO_MSR_OFFSET,
-	.num_shared_regs	= 1,
-	.constraints		= snbep_uncore_cbox_constraints,
-	.ops			= &snbep_uncore_cbox_ops,
-	.format_group		= &snbep_uncore_cbox_format_group,
-};
-
-static u64 snbep_pcu_alter_er(struct perf_event *event, int new_idx, bool modify)
-{
-	struct hw_perf_event *hwc = &event->hw;
-	struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
-	u64 config = reg1->config;
-
-	if (new_idx > reg1->idx)
-		config <<= 8 * (new_idx - reg1->idx);
-	else
-		config >>= 8 * (reg1->idx - new_idx);
-
-	if (modify) {
-		hwc->config += new_idx - reg1->idx;
-		reg1->config = config;
-		reg1->idx = new_idx;
-	}
-	return config;
-}
-
-static struct event_constraint *
-snbep_pcu_get_constraint(struct intel_uncore_box *box, struct perf_event *event)
-{
-	struct hw_perf_event_extra *reg1 = &event->hw.extra_reg;
-	struct intel_uncore_extra_reg *er = &box->shared_regs[0];
-	unsigned long flags;
-	int idx = reg1->idx;
-	u64 mask, config1 = reg1->config;
-	bool ok = false;
-
-	if (reg1->idx == EXTRA_REG_NONE ||
-	    (!uncore_box_is_fake(box) && reg1->alloc))
-		return NULL;
-again:
-	mask = 0xffULL << (idx * 8);
-	raw_spin_lock_irqsave(&er->lock, flags);
-	if (!__BITS_VALUE(atomic_read(&er->ref), idx, 8) ||
-	    !((config1 ^ er->config) & mask)) {
-		atomic_add(1 << (idx * 8), &er->ref);
-		er->config &= ~mask;
-		er->config |= config1 & mask;
-		ok = true;
-	}
-	raw_spin_unlock_irqrestore(&er->lock, flags);
-
-	if (!ok) {
-		idx = (idx + 1) % 4;
-		if (idx != reg1->idx) {
-			config1 = snbep_pcu_alter_er(event, idx, false);
-			goto again;
-		}
-		return &uncore_constraint_empty;
-	}
-
-	if (!uncore_box_is_fake(box)) {
-		if (idx != reg1->idx)
-			snbep_pcu_alter_er(event, idx, true);
-		reg1->alloc = 1;
-	}
-	return NULL;
-}
-
-static void snbep_pcu_put_constraint(struct intel_uncore_box *box, struct perf_event *event)
-{
-	struct hw_perf_event_extra *reg1 = &event->hw.extra_reg;
-	struct intel_uncore_extra_reg *er = &box->shared_regs[0];
-
-	if (uncore_box_is_fake(box) || !reg1->alloc)
-		return;
-
-	atomic_sub(1 << (reg1->idx * 8), &er->ref);
-	reg1->alloc = 0;
-}
-
-static int snbep_pcu_hw_config(struct intel_uncore_box *box, struct perf_event *event)
-{
-	struct hw_perf_event *hwc = &event->hw;
-	struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
-	int ev_sel = hwc->config & SNBEP_PMON_CTL_EV_SEL_MASK;
-
-	if (ev_sel >= 0xb && ev_sel <= 0xe) {
-		reg1->reg = SNBEP_PCU_MSR_PMON_BOX_FILTER;
-		reg1->idx = ev_sel - 0xb;
-		reg1->config = event->attr.config1 & (0xff << (reg1->idx * 8));
-	}
-	return 0;
-}
-
-static struct intel_uncore_ops snbep_uncore_pcu_ops = {
-	SNBEP_UNCORE_MSR_OPS_COMMON_INIT(),
-	.hw_config		= snbep_pcu_hw_config,
-	.get_constraint		= snbep_pcu_get_constraint,
-	.put_constraint		= snbep_pcu_put_constraint,
-};
-
-static struct intel_uncore_type snbep_uncore_pcu = {
-	.name			= "pcu",
-	.num_counters		= 4,
-	.num_boxes		= 1,
-	.perf_ctr_bits		= 48,
-	.perf_ctr		= SNBEP_PCU_MSR_PMON_CTR0,
-	.event_ctl		= SNBEP_PCU_MSR_PMON_CTL0,
-	.event_mask		= SNBEP_PCU_MSR_PMON_RAW_EVENT_MASK,
-	.box_ctl		= SNBEP_PCU_MSR_PMON_BOX_CTL,
-	.num_shared_regs	= 1,
-	.ops			= &snbep_uncore_pcu_ops,
-	.format_group		= &snbep_uncore_pcu_format_group,
-};
-
-static struct intel_uncore_type *snbep_msr_uncores[] = {
-	&snbep_uncore_ubox,
-	&snbep_uncore_cbox,
-	&snbep_uncore_pcu,
-	NULL,
-};
-
-void snbep_uncore_cpu_init(void)
-{
-	if (snbep_uncore_cbox.num_boxes > boot_cpu_data.x86_max_cores)
-		snbep_uncore_cbox.num_boxes = boot_cpu_data.x86_max_cores;
-	uncore_msr_uncores = snbep_msr_uncores;
-}
-
-enum {
-	SNBEP_PCI_QPI_PORT0_FILTER,
-	SNBEP_PCI_QPI_PORT1_FILTER,
-	HSWEP_PCI_PCU_3,
-};
-
-static int snbep_qpi_hw_config(struct intel_uncore_box *box, struct perf_event *event)
-{
-	struct hw_perf_event *hwc = &event->hw;
-	struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
-	struct hw_perf_event_extra *reg2 = &hwc->branch_reg;
-
-	if ((hwc->config & SNBEP_PMON_CTL_EV_SEL_MASK) == 0x38) {
-		reg1->idx = 0;
-		reg1->reg = SNBEP_Q_Py_PCI_PMON_PKT_MATCH0;
-		reg1->config = event->attr.config1;
-		reg2->reg = SNBEP_Q_Py_PCI_PMON_PKT_MASK0;
-		reg2->config = event->attr.config2;
-	}
-	return 0;
-}
-
-static void snbep_qpi_enable_event(struct intel_uncore_box *box, struct perf_event *event)
-{
-	struct pci_dev *pdev = box->pci_dev;
-	struct hw_perf_event *hwc = &event->hw;
-	struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
-	struct hw_perf_event_extra *reg2 = &hwc->branch_reg;
-
-	if (reg1->idx != EXTRA_REG_NONE) {
-		int idx = box->pmu->pmu_idx + SNBEP_PCI_QPI_PORT0_FILTER;
-		struct pci_dev *filter_pdev = uncore_extra_pci_dev[box->phys_id][idx];
-		if (filter_pdev) {
-			pci_write_config_dword(filter_pdev, reg1->reg,
-						(u32)reg1->config);
-			pci_write_config_dword(filter_pdev, reg1->reg + 4,
-						(u32)(reg1->config >> 32));
-			pci_write_config_dword(filter_pdev, reg2->reg,
-						(u32)reg2->config);
-			pci_write_config_dword(filter_pdev, reg2->reg + 4,
-						(u32)(reg2->config >> 32));
-		}
-	}
-
-	pci_write_config_dword(pdev, hwc->config_base, hwc->config | SNBEP_PMON_CTL_EN);
-}
-
-static struct intel_uncore_ops snbep_uncore_qpi_ops = {
-	SNBEP_UNCORE_PCI_OPS_COMMON_INIT(),
-	.enable_event		= snbep_qpi_enable_event,
-	.hw_config		= snbep_qpi_hw_config,
-	.get_constraint		= uncore_get_constraint,
-	.put_constraint		= uncore_put_constraint,
-};
-
-#define SNBEP_UNCORE_PCI_COMMON_INIT()				\
-	.perf_ctr	= SNBEP_PCI_PMON_CTR0,			\
-	.event_ctl	= SNBEP_PCI_PMON_CTL0,			\
-	.event_mask	= SNBEP_PMON_RAW_EVENT_MASK,		\
-	.box_ctl	= SNBEP_PCI_PMON_BOX_CTL,		\
-	.ops		= &snbep_uncore_pci_ops,		\
-	.format_group	= &snbep_uncore_format_group
-
-static struct intel_uncore_type snbep_uncore_ha = {
-	.name		= "ha",
-	.num_counters   = 4,
-	.num_boxes	= 1,
-	.perf_ctr_bits	= 48,
-	SNBEP_UNCORE_PCI_COMMON_INIT(),
-};
-
-static struct intel_uncore_type snbep_uncore_imc = {
-	.name		= "imc",
-	.num_counters   = 4,
-	.num_boxes	= 4,
-	.perf_ctr_bits	= 48,
-	.fixed_ctr_bits	= 48,
-	.fixed_ctr	= SNBEP_MC_CHy_PCI_PMON_FIXED_CTR,
-	.fixed_ctl	= SNBEP_MC_CHy_PCI_PMON_FIXED_CTL,
-	.event_descs	= snbep_uncore_imc_events,
-	SNBEP_UNCORE_PCI_COMMON_INIT(),
-};
-
-static struct intel_uncore_type snbep_uncore_qpi = {
-	.name			= "qpi",
-	.num_counters		= 4,
-	.num_boxes		= 2,
-	.perf_ctr_bits		= 48,
-	.perf_ctr		= SNBEP_PCI_PMON_CTR0,
-	.event_ctl		= SNBEP_PCI_PMON_CTL0,
-	.event_mask		= SNBEP_QPI_PCI_PMON_RAW_EVENT_MASK,
-	.box_ctl		= SNBEP_PCI_PMON_BOX_CTL,
-	.num_shared_regs	= 1,
-	.ops			= &snbep_uncore_qpi_ops,
-	.event_descs		= snbep_uncore_qpi_events,
-	.format_group		= &snbep_uncore_qpi_format_group,
-};
-
-
-static struct intel_uncore_type snbep_uncore_r2pcie = {
-	.name		= "r2pcie",
-	.num_counters   = 4,
-	.num_boxes	= 1,
-	.perf_ctr_bits	= 44,
-	.constraints	= snbep_uncore_r2pcie_constraints,
-	SNBEP_UNCORE_PCI_COMMON_INIT(),
-};
-
-static struct intel_uncore_type snbep_uncore_r3qpi = {
-	.name		= "r3qpi",
-	.num_counters   = 3,
-	.num_boxes	= 2,
-	.perf_ctr_bits	= 44,
-	.constraints	= snbep_uncore_r3qpi_constraints,
-	SNBEP_UNCORE_PCI_COMMON_INIT(),
-};
-
-enum {
-	SNBEP_PCI_UNCORE_HA,
-	SNBEP_PCI_UNCORE_IMC,
-	SNBEP_PCI_UNCORE_QPI,
-	SNBEP_PCI_UNCORE_R2PCIE,
-	SNBEP_PCI_UNCORE_R3QPI,
-};
-
-static struct intel_uncore_type *snbep_pci_uncores[] = {
-	[SNBEP_PCI_UNCORE_HA]		= &snbep_uncore_ha,
-	[SNBEP_PCI_UNCORE_IMC]		= &snbep_uncore_imc,
-	[SNBEP_PCI_UNCORE_QPI]		= &snbep_uncore_qpi,
-	[SNBEP_PCI_UNCORE_R2PCIE]	= &snbep_uncore_r2pcie,
-	[SNBEP_PCI_UNCORE_R3QPI]	= &snbep_uncore_r3qpi,
-	NULL,
-};
-
-static const struct pci_device_id snbep_uncore_pci_ids[] = {
-	{ /* Home Agent */
-		PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_HA),
-		.driver_data = UNCORE_PCI_DEV_DATA(SNBEP_PCI_UNCORE_HA, 0),
-	},
-	{ /* MC Channel 0 */
-		PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_IMC0),
-		.driver_data = UNCORE_PCI_DEV_DATA(SNBEP_PCI_UNCORE_IMC, 0),
-	},
-	{ /* MC Channel 1 */
-		PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_IMC1),
-		.driver_data = UNCORE_PCI_DEV_DATA(SNBEP_PCI_UNCORE_IMC, 1),
-	},
-	{ /* MC Channel 2 */
-		PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_IMC2),
-		.driver_data = UNCORE_PCI_DEV_DATA(SNBEP_PCI_UNCORE_IMC, 2),
-	},
-	{ /* MC Channel 3 */
-		PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_IMC3),
-		.driver_data = UNCORE_PCI_DEV_DATA(SNBEP_PCI_UNCORE_IMC, 3),
-	},
-	{ /* QPI Port 0 */
-		PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_QPI0),
-		.driver_data = UNCORE_PCI_DEV_DATA(SNBEP_PCI_UNCORE_QPI, 0),
-	},
-	{ /* QPI Port 1 */
-		PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_QPI1),
-		.driver_data = UNCORE_PCI_DEV_DATA(SNBEP_PCI_UNCORE_QPI, 1),
-	},
-	{ /* R2PCIe */
-		PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_R2PCIE),
-		.driver_data = UNCORE_PCI_DEV_DATA(SNBEP_PCI_UNCORE_R2PCIE, 0),
-	},
-	{ /* R3QPI Link 0 */
-		PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_R3QPI0),
-		.driver_data = UNCORE_PCI_DEV_DATA(SNBEP_PCI_UNCORE_R3QPI, 0),
-	},
-	{ /* R3QPI Link 1 */
-		PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_R3QPI1),
-		.driver_data = UNCORE_PCI_DEV_DATA(SNBEP_PCI_UNCORE_R3QPI, 1),
-	},
-	{ /* QPI Port 0 filter  */
-		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x3c86),
-		.driver_data = UNCORE_PCI_DEV_DATA(UNCORE_EXTRA_PCI_DEV,
-						   SNBEP_PCI_QPI_PORT0_FILTER),
-	},
-	{ /* QPI Port 0 filter  */
-		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x3c96),
-		.driver_data = UNCORE_PCI_DEV_DATA(UNCORE_EXTRA_PCI_DEV,
-						   SNBEP_PCI_QPI_PORT1_FILTER),
-	},
-	{ /* end: all zeroes */ }
-};
-
-static struct pci_driver snbep_uncore_pci_driver = {
-	.name		= "snbep_uncore",
-	.id_table	= snbep_uncore_pci_ids,
-};
-
-/*
- * build pci bus to socket mapping
- */
-static int snbep_pci2phy_map_init(int devid)
-{
-	struct pci_dev *ubox_dev = NULL;
-	int i, bus, nodeid, segment;
-	struct pci2phy_map *map;
-	int err = 0;
-	u32 config = 0;
-
-	while (1) {
-		/* find the UBOX device */
-		ubox_dev = pci_get_device(PCI_VENDOR_ID_INTEL, devid, ubox_dev);
-		if (!ubox_dev)
-			break;
-		bus = ubox_dev->bus->number;
-		/* get the Node ID of the local register */
-		err = pci_read_config_dword(ubox_dev, 0x40, &config);
-		if (err)
-			break;
-		nodeid = config;
-		/* get the Node ID mapping */
-		err = pci_read_config_dword(ubox_dev, 0x54, &config);
-		if (err)
-			break;
-
-		segment = pci_domain_nr(ubox_dev->bus);
-		raw_spin_lock(&pci2phy_map_lock);
-		map = __find_pci2phy_map(segment);
-		if (!map) {
-			raw_spin_unlock(&pci2phy_map_lock);
-			err = -ENOMEM;
-			break;
-		}
-
-		/*
-		 * every three bits in the Node ID mapping register maps
-		 * to a particular node.
-		 */
-		for (i = 0; i < 8; i++) {
-			if (nodeid == ((config >> (3 * i)) & 0x7)) {
-				map->pbus_to_physid[bus] = i;
-				break;
-			}
-		}
-		raw_spin_unlock(&pci2phy_map_lock);
-	}
-
-	if (!err) {
-		/*
-		 * For PCI bus with no UBOX device, find the next bus
-		 * that has UBOX device and use its mapping.
-		 */
-		raw_spin_lock(&pci2phy_map_lock);
-		list_for_each_entry(map, &pci2phy_map_head, list) {
-			i = -1;
-			for (bus = 255; bus >= 0; bus--) {
-				if (map->pbus_to_physid[bus] >= 0)
-					i = map->pbus_to_physid[bus];
-				else
-					map->pbus_to_physid[bus] = i;
-			}
-		}
-		raw_spin_unlock(&pci2phy_map_lock);
-	}
-
-	pci_dev_put(ubox_dev);
-
-	return err ? pcibios_err_to_errno(err) : 0;
-}
-
-int snbep_uncore_pci_init(void)
-{
-	int ret = snbep_pci2phy_map_init(0x3ce0);
-	if (ret)
-		return ret;
-	uncore_pci_uncores = snbep_pci_uncores;
-	uncore_pci_driver = &snbep_uncore_pci_driver;
-	return 0;
-}
-/* end of Sandy Bridge-EP uncore support */
-
-/* IvyTown uncore support */
-static void ivbep_uncore_msr_init_box(struct intel_uncore_box *box)
-{
-	unsigned msr = uncore_msr_box_ctl(box);
-	if (msr)
-		wrmsrl(msr, IVBEP_PMON_BOX_CTL_INT);
-}
-
-static void ivbep_uncore_pci_init_box(struct intel_uncore_box *box)
-{
-	struct pci_dev *pdev = box->pci_dev;
-
-	pci_write_config_dword(pdev, SNBEP_PCI_PMON_BOX_CTL, IVBEP_PMON_BOX_CTL_INT);
-}
-
-#define IVBEP_UNCORE_MSR_OPS_COMMON_INIT()			\
-	.init_box	= ivbep_uncore_msr_init_box,		\
-	.disable_box	= snbep_uncore_msr_disable_box,		\
-	.enable_box	= snbep_uncore_msr_enable_box,		\
-	.disable_event	= snbep_uncore_msr_disable_event,	\
-	.enable_event	= snbep_uncore_msr_enable_event,	\
-	.read_counter	= uncore_msr_read_counter
-
-static struct intel_uncore_ops ivbep_uncore_msr_ops = {
-	IVBEP_UNCORE_MSR_OPS_COMMON_INIT(),
-};
-
-static struct intel_uncore_ops ivbep_uncore_pci_ops = {
-	.init_box	= ivbep_uncore_pci_init_box,
-	.disable_box	= snbep_uncore_pci_disable_box,
-	.enable_box	= snbep_uncore_pci_enable_box,
-	.disable_event	= snbep_uncore_pci_disable_event,
-	.enable_event	= snbep_uncore_pci_enable_event,
-	.read_counter	= snbep_uncore_pci_read_counter,
-};
-
-#define IVBEP_UNCORE_PCI_COMMON_INIT()				\
-	.perf_ctr	= SNBEP_PCI_PMON_CTR0,			\
-	.event_ctl	= SNBEP_PCI_PMON_CTL0,			\
-	.event_mask	= IVBEP_PMON_RAW_EVENT_MASK,		\
-	.box_ctl	= SNBEP_PCI_PMON_BOX_CTL,		\
-	.ops		= &ivbep_uncore_pci_ops,			\
-	.format_group	= &ivbep_uncore_format_group
-
-static struct attribute *ivbep_uncore_formats_attr[] = {
-	&format_attr_event.attr,
-	&format_attr_umask.attr,
-	&format_attr_edge.attr,
-	&format_attr_inv.attr,
-	&format_attr_thresh8.attr,
-	NULL,
-};
-
-static struct attribute *ivbep_uncore_ubox_formats_attr[] = {
-	&format_attr_event.attr,
-	&format_attr_umask.attr,
-	&format_attr_edge.attr,
-	&format_attr_inv.attr,
-	&format_attr_thresh5.attr,
-	NULL,
-};
-
-static struct attribute *ivbep_uncore_cbox_formats_attr[] = {
-	&format_attr_event.attr,
-	&format_attr_umask.attr,
-	&format_attr_edge.attr,
-	&format_attr_tid_en.attr,
-	&format_attr_thresh8.attr,
-	&format_attr_filter_tid.attr,
-	&format_attr_filter_link.attr,
-	&format_attr_filter_state2.attr,
-	&format_attr_filter_nid2.attr,
-	&format_attr_filter_opc2.attr,
-	&format_attr_filter_nc.attr,
-	&format_attr_filter_c6.attr,
-	&format_attr_filter_isoc.attr,
-	NULL,
-};
-
-static struct attribute *ivbep_uncore_pcu_formats_attr[] = {
-	&format_attr_event_ext.attr,
-	&format_attr_occ_sel.attr,
-	&format_attr_edge.attr,
-	&format_attr_thresh5.attr,
-	&format_attr_occ_invert.attr,
-	&format_attr_occ_edge.attr,
-	&format_attr_filter_band0.attr,
-	&format_attr_filter_band1.attr,
-	&format_attr_filter_band2.attr,
-	&format_attr_filter_band3.attr,
-	NULL,
-};
-
-static struct attribute *ivbep_uncore_qpi_formats_attr[] = {
-	&format_attr_event_ext.attr,
-	&format_attr_umask.attr,
-	&format_attr_edge.attr,
-	&format_attr_thresh8.attr,
-	&format_attr_match_rds.attr,
-	&format_attr_match_rnid30.attr,
-	&format_attr_match_rnid4.attr,
-	&format_attr_match_dnid.attr,
-	&format_attr_match_mc.attr,
-	&format_attr_match_opc.attr,
-	&format_attr_match_vnw.attr,
-	&format_attr_match0.attr,
-	&format_attr_match1.attr,
-	&format_attr_mask_rds.attr,
-	&format_attr_mask_rnid30.attr,
-	&format_attr_mask_rnid4.attr,
-	&format_attr_mask_dnid.attr,
-	&format_attr_mask_mc.attr,
-	&format_attr_mask_opc.attr,
-	&format_attr_mask_vnw.attr,
-	&format_attr_mask0.attr,
-	&format_attr_mask1.attr,
-	NULL,
-};
-
-static struct attribute_group ivbep_uncore_format_group = {
-	.name = "format",
-	.attrs = ivbep_uncore_formats_attr,
-};
-
-static struct attribute_group ivbep_uncore_ubox_format_group = {
-	.name = "format",
-	.attrs = ivbep_uncore_ubox_formats_attr,
-};
-
-static struct attribute_group ivbep_uncore_cbox_format_group = {
-	.name = "format",
-	.attrs = ivbep_uncore_cbox_formats_attr,
-};
-
-static struct attribute_group ivbep_uncore_pcu_format_group = {
-	.name = "format",
-	.attrs = ivbep_uncore_pcu_formats_attr,
-};
-
-static struct attribute_group ivbep_uncore_qpi_format_group = {
-	.name = "format",
-	.attrs = ivbep_uncore_qpi_formats_attr,
-};
-
-static struct intel_uncore_type ivbep_uncore_ubox = {
-	.name		= "ubox",
-	.num_counters   = 2,
-	.num_boxes	= 1,
-	.perf_ctr_bits	= 44,
-	.fixed_ctr_bits	= 48,
-	.perf_ctr	= SNBEP_U_MSR_PMON_CTR0,
-	.event_ctl	= SNBEP_U_MSR_PMON_CTL0,
-	.event_mask	= IVBEP_U_MSR_PMON_RAW_EVENT_MASK,
-	.fixed_ctr	= SNBEP_U_MSR_PMON_UCLK_FIXED_CTR,
-	.fixed_ctl	= SNBEP_U_MSR_PMON_UCLK_FIXED_CTL,
-	.ops		= &ivbep_uncore_msr_ops,
-	.format_group	= &ivbep_uncore_ubox_format_group,
-};
-
-static struct extra_reg ivbep_uncore_cbox_extra_regs[] = {
-	SNBEP_CBO_EVENT_EXTRA_REG(SNBEP_CBO_PMON_CTL_TID_EN,
-				  SNBEP_CBO_PMON_CTL_TID_EN, 0x1),
-	SNBEP_CBO_EVENT_EXTRA_REG(0x1031, 0x10ff, 0x2),
-	SNBEP_CBO_EVENT_EXTRA_REG(0x1134, 0xffff, 0x4),
-	SNBEP_CBO_EVENT_EXTRA_REG(0x4134, 0xffff, 0xc),
-	SNBEP_CBO_EVENT_EXTRA_REG(0x5134, 0xffff, 0xc),
-	SNBEP_CBO_EVENT_EXTRA_REG(0x0334, 0xffff, 0x4),
-	SNBEP_CBO_EVENT_EXTRA_REG(0x4334, 0xffff, 0xc),
-	SNBEP_CBO_EVENT_EXTRA_REG(0x0534, 0xffff, 0x4),
-	SNBEP_CBO_EVENT_EXTRA_REG(0x4534, 0xffff, 0xc),
-	SNBEP_CBO_EVENT_EXTRA_REG(0x0934, 0xffff, 0x4),
-	SNBEP_CBO_EVENT_EXTRA_REG(0x4934, 0xffff, 0xc),
-	SNBEP_CBO_EVENT_EXTRA_REG(0x0135, 0xffff, 0x10),
-	SNBEP_CBO_EVENT_EXTRA_REG(0x0335, 0xffff, 0x10),
-	SNBEP_CBO_EVENT_EXTRA_REG(0x2135, 0xffff, 0x10),
-	SNBEP_CBO_EVENT_EXTRA_REG(0x2335, 0xffff, 0x10),
-	SNBEP_CBO_EVENT_EXTRA_REG(0x4135, 0xffff, 0x18),
-	SNBEP_CBO_EVENT_EXTRA_REG(0x4335, 0xffff, 0x18),
-	SNBEP_CBO_EVENT_EXTRA_REG(0x4435, 0xffff, 0x8),
-	SNBEP_CBO_EVENT_EXTRA_REG(0x4835, 0xffff, 0x8),
-	SNBEP_CBO_EVENT_EXTRA_REG(0x4a35, 0xffff, 0x8),
-	SNBEP_CBO_EVENT_EXTRA_REG(0x5035, 0xffff, 0x8),
-	SNBEP_CBO_EVENT_EXTRA_REG(0x8135, 0xffff, 0x10),
-	SNBEP_CBO_EVENT_EXTRA_REG(0x8335, 0xffff, 0x10),
-	SNBEP_CBO_EVENT_EXTRA_REG(0x0136, 0xffff, 0x10),
-	SNBEP_CBO_EVENT_EXTRA_REG(0x0336, 0xffff, 0x10),
-	SNBEP_CBO_EVENT_EXTRA_REG(0x2136, 0xffff, 0x10),
-	SNBEP_CBO_EVENT_EXTRA_REG(0x2336, 0xffff, 0x10),
-	SNBEP_CBO_EVENT_EXTRA_REG(0x4136, 0xffff, 0x18),
-	SNBEP_CBO_EVENT_EXTRA_REG(0x4336, 0xffff, 0x18),
-	SNBEP_CBO_EVENT_EXTRA_REG(0x4436, 0xffff, 0x8),
-	SNBEP_CBO_EVENT_EXTRA_REG(0x4836, 0xffff, 0x8),
-	SNBEP_CBO_EVENT_EXTRA_REG(0x4a36, 0xffff, 0x8),
-	SNBEP_CBO_EVENT_EXTRA_REG(0x5036, 0xffff, 0x8),
-	SNBEP_CBO_EVENT_EXTRA_REG(0x8136, 0xffff, 0x10),
-	SNBEP_CBO_EVENT_EXTRA_REG(0x8336, 0xffff, 0x10),
-	SNBEP_CBO_EVENT_EXTRA_REG(0x4037, 0x40ff, 0x8),
-	EVENT_EXTRA_END
-};
-
-static u64 ivbep_cbox_filter_mask(int fields)
-{
-	u64 mask = 0;
-
-	if (fields & 0x1)
-		mask |= IVBEP_CB0_MSR_PMON_BOX_FILTER_TID;
-	if (fields & 0x2)
-		mask |= IVBEP_CB0_MSR_PMON_BOX_FILTER_LINK;
-	if (fields & 0x4)
-		mask |= IVBEP_CB0_MSR_PMON_BOX_FILTER_STATE;
-	if (fields & 0x8)
-		mask |= IVBEP_CB0_MSR_PMON_BOX_FILTER_NID;
-	if (fields & 0x10) {
-		mask |= IVBEP_CB0_MSR_PMON_BOX_FILTER_OPC;
-		mask |= IVBEP_CB0_MSR_PMON_BOX_FILTER_NC;
-		mask |= IVBEP_CB0_MSR_PMON_BOX_FILTER_C6;
-		mask |= IVBEP_CB0_MSR_PMON_BOX_FILTER_ISOC;
-	}
-
-	return mask;
-}
-
-static struct event_constraint *
-ivbep_cbox_get_constraint(struct intel_uncore_box *box, struct perf_event *event)
-{
-	return __snbep_cbox_get_constraint(box, event, ivbep_cbox_filter_mask);
-}
-
-static int ivbep_cbox_hw_config(struct intel_uncore_box *box, struct perf_event *event)
-{
-	struct hw_perf_event_extra *reg1 = &event->hw.extra_reg;
-	struct extra_reg *er;
-	int idx = 0;
-
-	for (er = ivbep_uncore_cbox_extra_regs; er->msr; er++) {
-		if (er->event != (event->hw.config & er->config_mask))
-			continue;
-		idx |= er->idx;
-	}
-
-	if (idx) {
-		reg1->reg = SNBEP_C0_MSR_PMON_BOX_FILTER +
-			SNBEP_CBO_MSR_OFFSET * box->pmu->pmu_idx;
-		reg1->config = event->attr.config1 & ivbep_cbox_filter_mask(idx);
-		reg1->idx = idx;
-	}
-	return 0;
-}
-
-static void ivbep_cbox_enable_event(struct intel_uncore_box *box, struct perf_event *event)
-{
-	struct hw_perf_event *hwc = &event->hw;
-	struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
-
-	if (reg1->idx != EXTRA_REG_NONE) {
-		u64 filter = uncore_shared_reg_config(box, 0);
-		wrmsrl(reg1->reg, filter & 0xffffffff);
-		wrmsrl(reg1->reg + 6, filter >> 32);
-	}
-
-	wrmsrl(hwc->config_base, hwc->config | SNBEP_PMON_CTL_EN);
-}
-
-static struct intel_uncore_ops ivbep_uncore_cbox_ops = {
-	.init_box		= ivbep_uncore_msr_init_box,
-	.disable_box		= snbep_uncore_msr_disable_box,
-	.enable_box		= snbep_uncore_msr_enable_box,
-	.disable_event		= snbep_uncore_msr_disable_event,
-	.enable_event		= ivbep_cbox_enable_event,
-	.read_counter		= uncore_msr_read_counter,
-	.hw_config		= ivbep_cbox_hw_config,
-	.get_constraint		= ivbep_cbox_get_constraint,
-	.put_constraint		= snbep_cbox_put_constraint,
-};
-
-static struct intel_uncore_type ivbep_uncore_cbox = {
-	.name			= "cbox",
-	.num_counters		= 4,
-	.num_boxes		= 15,
-	.perf_ctr_bits		= 44,
-	.event_ctl		= SNBEP_C0_MSR_PMON_CTL0,
-	.perf_ctr		= SNBEP_C0_MSR_PMON_CTR0,
-	.event_mask		= IVBEP_CBO_MSR_PMON_RAW_EVENT_MASK,
-	.box_ctl		= SNBEP_C0_MSR_PMON_BOX_CTL,
-	.msr_offset		= SNBEP_CBO_MSR_OFFSET,
-	.num_shared_regs	= 1,
-	.constraints		= snbep_uncore_cbox_constraints,
-	.ops			= &ivbep_uncore_cbox_ops,
-	.format_group		= &ivbep_uncore_cbox_format_group,
-};
-
-static struct intel_uncore_ops ivbep_uncore_pcu_ops = {
-	IVBEP_UNCORE_MSR_OPS_COMMON_INIT(),
-	.hw_config		= snbep_pcu_hw_config,
-	.get_constraint		= snbep_pcu_get_constraint,
-	.put_constraint		= snbep_pcu_put_constraint,
-};
-
-static struct intel_uncore_type ivbep_uncore_pcu = {
-	.name			= "pcu",
-	.num_counters		= 4,
-	.num_boxes		= 1,
-	.perf_ctr_bits		= 48,
-	.perf_ctr		= SNBEP_PCU_MSR_PMON_CTR0,
-	.event_ctl		= SNBEP_PCU_MSR_PMON_CTL0,
-	.event_mask		= IVBEP_PCU_MSR_PMON_RAW_EVENT_MASK,
-	.box_ctl		= SNBEP_PCU_MSR_PMON_BOX_CTL,
-	.num_shared_regs	= 1,
-	.ops			= &ivbep_uncore_pcu_ops,
-	.format_group		= &ivbep_uncore_pcu_format_group,
-};
-
-static struct intel_uncore_type *ivbep_msr_uncores[] = {
-	&ivbep_uncore_ubox,
-	&ivbep_uncore_cbox,
-	&ivbep_uncore_pcu,
-	NULL,
-};
-
-void ivbep_uncore_cpu_init(void)
-{
-	if (ivbep_uncore_cbox.num_boxes > boot_cpu_data.x86_max_cores)
-		ivbep_uncore_cbox.num_boxes = boot_cpu_data.x86_max_cores;
-	uncore_msr_uncores = ivbep_msr_uncores;
-}
-
-static struct intel_uncore_type ivbep_uncore_ha = {
-	.name		= "ha",
-	.num_counters   = 4,
-	.num_boxes	= 2,
-	.perf_ctr_bits	= 48,
-	IVBEP_UNCORE_PCI_COMMON_INIT(),
-};
-
-static struct intel_uncore_type ivbep_uncore_imc = {
-	.name		= "imc",
-	.num_counters   = 4,
-	.num_boxes	= 8,
-	.perf_ctr_bits	= 48,
-	.fixed_ctr_bits	= 48,
-	.fixed_ctr	= SNBEP_MC_CHy_PCI_PMON_FIXED_CTR,
-	.fixed_ctl	= SNBEP_MC_CHy_PCI_PMON_FIXED_CTL,
-	.event_descs	= snbep_uncore_imc_events,
-	IVBEP_UNCORE_PCI_COMMON_INIT(),
-};
-
-/* registers in IRP boxes are not properly aligned */
-static unsigned ivbep_uncore_irp_ctls[] = {0xd8, 0xdc, 0xe0, 0xe4};
-static unsigned ivbep_uncore_irp_ctrs[] = {0xa0, 0xb0, 0xb8, 0xc0};
-
-static void ivbep_uncore_irp_enable_event(struct intel_uncore_box *box, struct perf_event *event)
-{
-	struct pci_dev *pdev = box->pci_dev;
-	struct hw_perf_event *hwc = &event->hw;
-
-	pci_write_config_dword(pdev, ivbep_uncore_irp_ctls[hwc->idx],
-			       hwc->config | SNBEP_PMON_CTL_EN);
-}
-
-static void ivbep_uncore_irp_disable_event(struct intel_uncore_box *box, struct perf_event *event)
-{
-	struct pci_dev *pdev = box->pci_dev;
-	struct hw_perf_event *hwc = &event->hw;
-
-	pci_write_config_dword(pdev, ivbep_uncore_irp_ctls[hwc->idx], hwc->config);
-}
-
-static u64 ivbep_uncore_irp_read_counter(struct intel_uncore_box *box, struct perf_event *event)
-{
-	struct pci_dev *pdev = box->pci_dev;
-	struct hw_perf_event *hwc = &event->hw;
-	u64 count = 0;
-
-	pci_read_config_dword(pdev, ivbep_uncore_irp_ctrs[hwc->idx], (u32 *)&count);
-	pci_read_config_dword(pdev, ivbep_uncore_irp_ctrs[hwc->idx] + 4, (u32 *)&count + 1);
-
-	return count;
-}
-
-static struct intel_uncore_ops ivbep_uncore_irp_ops = {
-	.init_box	= ivbep_uncore_pci_init_box,
-	.disable_box	= snbep_uncore_pci_disable_box,
-	.enable_box	= snbep_uncore_pci_enable_box,
-	.disable_event	= ivbep_uncore_irp_disable_event,
-	.enable_event	= ivbep_uncore_irp_enable_event,
-	.read_counter	= ivbep_uncore_irp_read_counter,
-};
-
-static struct intel_uncore_type ivbep_uncore_irp = {
-	.name			= "irp",
-	.num_counters		= 4,
-	.num_boxes		= 1,
-	.perf_ctr_bits		= 48,
-	.event_mask		= IVBEP_PMON_RAW_EVENT_MASK,
-	.box_ctl		= SNBEP_PCI_PMON_BOX_CTL,
-	.ops			= &ivbep_uncore_irp_ops,
-	.format_group		= &ivbep_uncore_format_group,
-};
-
-static struct intel_uncore_ops ivbep_uncore_qpi_ops = {
-	.init_box	= ivbep_uncore_pci_init_box,
-	.disable_box	= snbep_uncore_pci_disable_box,
-	.enable_box	= snbep_uncore_pci_enable_box,
-	.disable_event	= snbep_uncore_pci_disable_event,
-	.enable_event	= snbep_qpi_enable_event,
-	.read_counter	= snbep_uncore_pci_read_counter,
-	.hw_config	= snbep_qpi_hw_config,
-	.get_constraint	= uncore_get_constraint,
-	.put_constraint	= uncore_put_constraint,
-};
-
-static struct intel_uncore_type ivbep_uncore_qpi = {
-	.name			= "qpi",
-	.num_counters		= 4,
-	.num_boxes		= 3,
-	.perf_ctr_bits		= 48,
-	.perf_ctr		= SNBEP_PCI_PMON_CTR0,
-	.event_ctl		= SNBEP_PCI_PMON_CTL0,
-	.event_mask		= IVBEP_QPI_PCI_PMON_RAW_EVENT_MASK,
-	.box_ctl		= SNBEP_PCI_PMON_BOX_CTL,
-	.num_shared_regs	= 1,
-	.ops			= &ivbep_uncore_qpi_ops,
-	.format_group		= &ivbep_uncore_qpi_format_group,
-};
-
-static struct intel_uncore_type ivbep_uncore_r2pcie = {
-	.name		= "r2pcie",
-	.num_counters   = 4,
-	.num_boxes	= 1,
-	.perf_ctr_bits	= 44,
-	.constraints	= snbep_uncore_r2pcie_constraints,
-	IVBEP_UNCORE_PCI_COMMON_INIT(),
-};
-
-static struct intel_uncore_type ivbep_uncore_r3qpi = {
-	.name		= "r3qpi",
-	.num_counters   = 3,
-	.num_boxes	= 2,
-	.perf_ctr_bits	= 44,
-	.constraints	= snbep_uncore_r3qpi_constraints,
-	IVBEP_UNCORE_PCI_COMMON_INIT(),
-};
-
-enum {
-	IVBEP_PCI_UNCORE_HA,
-	IVBEP_PCI_UNCORE_IMC,
-	IVBEP_PCI_UNCORE_IRP,
-	IVBEP_PCI_UNCORE_QPI,
-	IVBEP_PCI_UNCORE_R2PCIE,
-	IVBEP_PCI_UNCORE_R3QPI,
-};
-
-static struct intel_uncore_type *ivbep_pci_uncores[] = {
-	[IVBEP_PCI_UNCORE_HA]	= &ivbep_uncore_ha,
-	[IVBEP_PCI_UNCORE_IMC]	= &ivbep_uncore_imc,
-	[IVBEP_PCI_UNCORE_IRP]	= &ivbep_uncore_irp,
-	[IVBEP_PCI_UNCORE_QPI]	= &ivbep_uncore_qpi,
-	[IVBEP_PCI_UNCORE_R2PCIE]	= &ivbep_uncore_r2pcie,
-	[IVBEP_PCI_UNCORE_R3QPI]	= &ivbep_uncore_r3qpi,
-	NULL,
-};
-
-static const struct pci_device_id ivbep_uncore_pci_ids[] = {
-	{ /* Home Agent 0 */
-		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe30),
-		.driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_HA, 0),
-	},
-	{ /* Home Agent 1 */
-		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe38),
-		.driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_HA, 1),
-	},
-	{ /* MC0 Channel 0 */
-		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xeb4),
-		.driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_IMC, 0),
-	},
-	{ /* MC0 Channel 1 */
-		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xeb5),
-		.driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_IMC, 1),
-	},
-	{ /* MC0 Channel 3 */
-		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xeb0),
-		.driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_IMC, 2),
-	},
-	{ /* MC0 Channel 4 */
-		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xeb1),
-		.driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_IMC, 3),
-	},
-	{ /* MC1 Channel 0 */
-		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xef4),
-		.driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_IMC, 4),
-	},
-	{ /* MC1 Channel 1 */
-		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xef5),
-		.driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_IMC, 5),
-	},
-	{ /* MC1 Channel 3 */
-		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xef0),
-		.driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_IMC, 6),
-	},
-	{ /* MC1 Channel 4 */
-		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xef1),
-		.driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_IMC, 7),
-	},
-	{ /* IRP */
-		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe39),
-		.driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_IRP, 0),
-	},
-	{ /* QPI0 Port 0 */
-		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe32),
-		.driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_QPI, 0),
-	},
-	{ /* QPI0 Port 1 */
-		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe33),
-		.driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_QPI, 1),
-	},
-	{ /* QPI1 Port 2 */
-		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe3a),
-		.driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_QPI, 2),
-	},
-	{ /* R2PCIe */
-		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe34),
-		.driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_R2PCIE, 0),
-	},
-	{ /* R3QPI0 Link 0 */
-		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe36),
-		.driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_R3QPI, 0),
-	},
-	{ /* R3QPI0 Link 1 */
-		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe37),
-		.driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_R3QPI, 1),
-	},
-	{ /* R3QPI1 Link 2 */
-		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe3e),
-		.driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_R3QPI, 2),
-	},
-	{ /* QPI Port 0 filter  */
-		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe86),
-		.driver_data = UNCORE_PCI_DEV_DATA(UNCORE_EXTRA_PCI_DEV,
-						   SNBEP_PCI_QPI_PORT0_FILTER),
-	},
-	{ /* QPI Port 0 filter  */
-		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe96),
-		.driver_data = UNCORE_PCI_DEV_DATA(UNCORE_EXTRA_PCI_DEV,
-						   SNBEP_PCI_QPI_PORT1_FILTER),
-	},
-	{ /* end: all zeroes */ }
-};
-
-static struct pci_driver ivbep_uncore_pci_driver = {
-	.name		= "ivbep_uncore",
-	.id_table	= ivbep_uncore_pci_ids,
-};
-
-int ivbep_uncore_pci_init(void)
-{
-	int ret = snbep_pci2phy_map_init(0x0e1e);
-	if (ret)
-		return ret;
-	uncore_pci_uncores = ivbep_pci_uncores;
-	uncore_pci_driver = &ivbep_uncore_pci_driver;
-	return 0;
-}
-/* end of IvyTown uncore support */
-
-/* Haswell-EP uncore support */
-static struct attribute *hswep_uncore_ubox_formats_attr[] = {
-	&format_attr_event.attr,
-	&format_attr_umask.attr,
-	&format_attr_edge.attr,
-	&format_attr_inv.attr,
-	&format_attr_thresh5.attr,
-	&format_attr_filter_tid2.attr,
-	&format_attr_filter_cid.attr,
-	NULL,
-};
-
-static struct attribute_group hswep_uncore_ubox_format_group = {
-	.name = "format",
-	.attrs = hswep_uncore_ubox_formats_attr,
-};
-
-static int hswep_ubox_hw_config(struct intel_uncore_box *box, struct perf_event *event)
-{
-	struct hw_perf_event_extra *reg1 = &event->hw.extra_reg;
-	reg1->reg = HSWEP_U_MSR_PMON_FILTER;
-	reg1->config = event->attr.config1 & HSWEP_U_MSR_PMON_BOX_FILTER_MASK;
-	reg1->idx = 0;
-	return 0;
-}
-
-static struct intel_uncore_ops hswep_uncore_ubox_ops = {
-	SNBEP_UNCORE_MSR_OPS_COMMON_INIT(),
-	.hw_config		= hswep_ubox_hw_config,
-	.get_constraint		= uncore_get_constraint,
-	.put_constraint		= uncore_put_constraint,
-};
-
-static struct intel_uncore_type hswep_uncore_ubox = {
-	.name			= "ubox",
-	.num_counters		= 2,
-	.num_boxes		= 1,
-	.perf_ctr_bits		= 44,
-	.fixed_ctr_bits		= 48,
-	.perf_ctr		= HSWEP_U_MSR_PMON_CTR0,
-	.event_ctl		= HSWEP_U_MSR_PMON_CTL0,
-	.event_mask		= SNBEP_U_MSR_PMON_RAW_EVENT_MASK,
-	.fixed_ctr		= HSWEP_U_MSR_PMON_UCLK_FIXED_CTR,
-	.fixed_ctl		= HSWEP_U_MSR_PMON_UCLK_FIXED_CTL,
-	.num_shared_regs	= 1,
-	.ops			= &hswep_uncore_ubox_ops,
-	.format_group		= &hswep_uncore_ubox_format_group,
-};
-
-static struct attribute *hswep_uncore_cbox_formats_attr[] = {
-	&format_attr_event.attr,
-	&format_attr_umask.attr,
-	&format_attr_edge.attr,
-	&format_attr_tid_en.attr,
-	&format_attr_thresh8.attr,
-	&format_attr_filter_tid3.attr,
-	&format_attr_filter_link2.attr,
-	&format_attr_filter_state3.attr,
-	&format_attr_filter_nid2.attr,
-	&format_attr_filter_opc2.attr,
-	&format_attr_filter_nc.attr,
-	&format_attr_filter_c6.attr,
-	&format_attr_filter_isoc.attr,
-	NULL,
-};
-
-static struct attribute_group hswep_uncore_cbox_format_group = {
-	.name = "format",
-	.attrs = hswep_uncore_cbox_formats_attr,
-};
-
-static struct event_constraint hswep_uncore_cbox_constraints[] = {
-	UNCORE_EVENT_CONSTRAINT(0x01, 0x1),
-	UNCORE_EVENT_CONSTRAINT(0x09, 0x1),
-	UNCORE_EVENT_CONSTRAINT(0x11, 0x1),
-	UNCORE_EVENT_CONSTRAINT(0x36, 0x1),
-	UNCORE_EVENT_CONSTRAINT(0x38, 0x3),
-	UNCORE_EVENT_CONSTRAINT(0x3b, 0x1),
-	UNCORE_EVENT_CONSTRAINT(0x3e, 0x1),
-	EVENT_CONSTRAINT_END
-};
-
-static struct extra_reg hswep_uncore_cbox_extra_regs[] = {
-	SNBEP_CBO_EVENT_EXTRA_REG(SNBEP_CBO_PMON_CTL_TID_EN,
-				  SNBEP_CBO_PMON_CTL_TID_EN, 0x1),
-	SNBEP_CBO_EVENT_EXTRA_REG(0x0334, 0xffff, 0x4),
-	SNBEP_CBO_EVENT_EXTRA_REG(0x0534, 0xffff, 0x4),
-	SNBEP_CBO_EVENT_EXTRA_REG(0x0934, 0xffff, 0x4),
-	SNBEP_CBO_EVENT_EXTRA_REG(0x1134, 0xffff, 0x4),
-	SNBEP_CBO_EVENT_EXTRA_REG(0x2134, 0xffff, 0x4),
-	SNBEP_CBO_EVENT_EXTRA_REG(0x4134, 0xffff, 0x4),
-	SNBEP_CBO_EVENT_EXTRA_REG(0x4037, 0x40ff, 0x8),
-	SNBEP_CBO_EVENT_EXTRA_REG(0x4028, 0x40ff, 0x8),
-	SNBEP_CBO_EVENT_EXTRA_REG(0x4032, 0x40ff, 0x8),
-	SNBEP_CBO_EVENT_EXTRA_REG(0x4029, 0x40ff, 0x8),
-	SNBEP_CBO_EVENT_EXTRA_REG(0x4033, 0x40ff, 0x8),
-	SNBEP_CBO_EVENT_EXTRA_REG(0x402A, 0x40ff, 0x8),
-	SNBEP_CBO_EVENT_EXTRA_REG(0x0135, 0xffff, 0x12),
-	SNBEP_CBO_EVENT_EXTRA_REG(0x0335, 0xffff, 0x10),
-	SNBEP_CBO_EVENT_EXTRA_REG(0x4135, 0xffff, 0x18),
-	SNBEP_CBO_EVENT_EXTRA_REG(0x4435, 0xffff, 0x8),
-	SNBEP_CBO_EVENT_EXTRA_REG(0x4835, 0xffff, 0x8),
-	SNBEP_CBO_EVENT_EXTRA_REG(0x5035, 0xffff, 0x8),
-	SNBEP_CBO_EVENT_EXTRA_REG(0x4335, 0xffff, 0x18),
-	SNBEP_CBO_EVENT_EXTRA_REG(0x4a35, 0xffff, 0x8),
-	SNBEP_CBO_EVENT_EXTRA_REG(0x2335, 0xffff, 0x10),
-	SNBEP_CBO_EVENT_EXTRA_REG(0x8335, 0xffff, 0x10),
-	SNBEP_CBO_EVENT_EXTRA_REG(0x2135, 0xffff, 0x10),
-	SNBEP_CBO_EVENT_EXTRA_REG(0x8135, 0xffff, 0x10),
-	SNBEP_CBO_EVENT_EXTRA_REG(0x0136, 0xffff, 0x10),
-	SNBEP_CBO_EVENT_EXTRA_REG(0x0336, 0xffff, 0x10),
-	SNBEP_CBO_EVENT_EXTRA_REG(0x4136, 0xffff, 0x18),
-	SNBEP_CBO_EVENT_EXTRA_REG(0x4436, 0xffff, 0x8),
-	SNBEP_CBO_EVENT_EXTRA_REG(0x4836, 0xffff, 0x8),
-	SNBEP_CBO_EVENT_EXTRA_REG(0x4336, 0xffff, 0x18),
-	SNBEP_CBO_EVENT_EXTRA_REG(0x4a36, 0xffff, 0x8),
-	SNBEP_CBO_EVENT_EXTRA_REG(0x2336, 0xffff, 0x10),
-	SNBEP_CBO_EVENT_EXTRA_REG(0x8336, 0xffff, 0x10),
-	SNBEP_CBO_EVENT_EXTRA_REG(0x2136, 0xffff, 0x10),
-	SNBEP_CBO_EVENT_EXTRA_REG(0x8136, 0xffff, 0x10),
-	SNBEP_CBO_EVENT_EXTRA_REG(0x5036, 0xffff, 0x8),
-	EVENT_EXTRA_END
-};
-
-static u64 hswep_cbox_filter_mask(int fields)
-{
-	u64 mask = 0;
-	if (fields & 0x1)
-		mask |= HSWEP_CB0_MSR_PMON_BOX_FILTER_TID;
-	if (fields & 0x2)
-		mask |= HSWEP_CB0_MSR_PMON_BOX_FILTER_LINK;
-	if (fields & 0x4)
-		mask |= HSWEP_CB0_MSR_PMON_BOX_FILTER_STATE;
-	if (fields & 0x8)
-		mask |= HSWEP_CB0_MSR_PMON_BOX_FILTER_NID;
-	if (fields & 0x10) {
-		mask |= HSWEP_CB0_MSR_PMON_BOX_FILTER_OPC;
-		mask |= HSWEP_CB0_MSR_PMON_BOX_FILTER_NC;
-		mask |= HSWEP_CB0_MSR_PMON_BOX_FILTER_C6;
-		mask |= HSWEP_CB0_MSR_PMON_BOX_FILTER_ISOC;
-	}
-	return mask;
-}
-
-static struct event_constraint *
-hswep_cbox_get_constraint(struct intel_uncore_box *box, struct perf_event *event)
-{
-	return __snbep_cbox_get_constraint(box, event, hswep_cbox_filter_mask);
-}
-
-static int hswep_cbox_hw_config(struct intel_uncore_box *box, struct perf_event *event)
-{
-	struct hw_perf_event_extra *reg1 = &event->hw.extra_reg;
-	struct extra_reg *er;
-	int idx = 0;
-
-	for (er = hswep_uncore_cbox_extra_regs; er->msr; er++) {
-		if (er->event != (event->hw.config & er->config_mask))
-			continue;
-		idx |= er->idx;
-	}
-
-	if (idx) {
-		reg1->reg = HSWEP_C0_MSR_PMON_BOX_FILTER0 +
-			    HSWEP_CBO_MSR_OFFSET * box->pmu->pmu_idx;
-		reg1->config = event->attr.config1 & hswep_cbox_filter_mask(idx);
-		reg1->idx = idx;
-	}
-	return 0;
-}
-
-static void hswep_cbox_enable_event(struct intel_uncore_box *box,
-				  struct perf_event *event)
-{
-	struct hw_perf_event *hwc = &event->hw;
-	struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
-
-	if (reg1->idx != EXTRA_REG_NONE) {
-		u64 filter = uncore_shared_reg_config(box, 0);
-		wrmsrl(reg1->reg, filter & 0xffffffff);
-		wrmsrl(reg1->reg + 1, filter >> 32);
-	}
-
-	wrmsrl(hwc->config_base, hwc->config | SNBEP_PMON_CTL_EN);
-}
-
-static struct intel_uncore_ops hswep_uncore_cbox_ops = {
-	.init_box		= snbep_uncore_msr_init_box,
-	.disable_box		= snbep_uncore_msr_disable_box,
-	.enable_box		= snbep_uncore_msr_enable_box,
-	.disable_event		= snbep_uncore_msr_disable_event,
-	.enable_event		= hswep_cbox_enable_event,
-	.read_counter		= uncore_msr_read_counter,
-	.hw_config		= hswep_cbox_hw_config,
-	.get_constraint		= hswep_cbox_get_constraint,
-	.put_constraint		= snbep_cbox_put_constraint,
-};
-
-static struct intel_uncore_type hswep_uncore_cbox = {
-	.name			= "cbox",
-	.num_counters		= 4,
-	.num_boxes		= 18,
-	.perf_ctr_bits		= 48,
-	.event_ctl		= HSWEP_C0_MSR_PMON_CTL0,
-	.perf_ctr		= HSWEP_C0_MSR_PMON_CTR0,
-	.event_mask		= SNBEP_CBO_MSR_PMON_RAW_EVENT_MASK,
-	.box_ctl		= HSWEP_C0_MSR_PMON_BOX_CTL,
-	.msr_offset		= HSWEP_CBO_MSR_OFFSET,
-	.num_shared_regs	= 1,
-	.constraints		= hswep_uncore_cbox_constraints,
-	.ops			= &hswep_uncore_cbox_ops,
-	.format_group		= &hswep_uncore_cbox_format_group,
-};
-
-/*
- * Write SBOX Initialization register bit by bit to avoid spurious #GPs
- */
-static void hswep_uncore_sbox_msr_init_box(struct intel_uncore_box *box)
-{
-	unsigned msr = uncore_msr_box_ctl(box);
-
-	if (msr) {
-		u64 init = SNBEP_PMON_BOX_CTL_INT;
-		u64 flags = 0;
-		int i;
-
-		for_each_set_bit(i, (unsigned long *)&init, 64) {
-			flags |= (1ULL << i);
-			wrmsrl(msr, flags);
-		}
-	}
-}
-
-static struct intel_uncore_ops hswep_uncore_sbox_msr_ops = {
-	__SNBEP_UNCORE_MSR_OPS_COMMON_INIT(),
-	.init_box		= hswep_uncore_sbox_msr_init_box
-};
-
-static struct attribute *hswep_uncore_sbox_formats_attr[] = {
-	&format_attr_event.attr,
-	&format_attr_umask.attr,
-	&format_attr_edge.attr,
-	&format_attr_tid_en.attr,
-	&format_attr_inv.attr,
-	&format_attr_thresh8.attr,
-	NULL,
-};
-
-static struct attribute_group hswep_uncore_sbox_format_group = {
-	.name = "format",
-	.attrs = hswep_uncore_sbox_formats_attr,
-};
-
-static struct intel_uncore_type hswep_uncore_sbox = {
-	.name			= "sbox",
-	.num_counters		= 4,
-	.num_boxes		= 4,
-	.perf_ctr_bits		= 44,
-	.event_ctl		= HSWEP_S0_MSR_PMON_CTL0,
-	.perf_ctr		= HSWEP_S0_MSR_PMON_CTR0,
-	.event_mask		= HSWEP_S_MSR_PMON_RAW_EVENT_MASK,
-	.box_ctl		= HSWEP_S0_MSR_PMON_BOX_CTL,
-	.msr_offset		= HSWEP_SBOX_MSR_OFFSET,
-	.ops			= &hswep_uncore_sbox_msr_ops,
-	.format_group		= &hswep_uncore_sbox_format_group,
-};
-
-static int hswep_pcu_hw_config(struct intel_uncore_box *box, struct perf_event *event)
-{
-	struct hw_perf_event *hwc = &event->hw;
-	struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
-	int ev_sel = hwc->config & SNBEP_PMON_CTL_EV_SEL_MASK;
-
-	if (ev_sel >= 0xb && ev_sel <= 0xe) {
-		reg1->reg = HSWEP_PCU_MSR_PMON_BOX_FILTER;
-		reg1->idx = ev_sel - 0xb;
-		reg1->config = event->attr.config1 & (0xff << reg1->idx);
-	}
-	return 0;
-}
-
-static struct intel_uncore_ops hswep_uncore_pcu_ops = {
-	SNBEP_UNCORE_MSR_OPS_COMMON_INIT(),
-	.hw_config		= hswep_pcu_hw_config,
-	.get_constraint		= snbep_pcu_get_constraint,
-	.put_constraint		= snbep_pcu_put_constraint,
-};
-
-static struct intel_uncore_type hswep_uncore_pcu = {
-	.name			= "pcu",
-	.num_counters		= 4,
-	.num_boxes		= 1,
-	.perf_ctr_bits		= 48,
-	.perf_ctr		= HSWEP_PCU_MSR_PMON_CTR0,
-	.event_ctl		= HSWEP_PCU_MSR_PMON_CTL0,
-	.event_mask		= SNBEP_PCU_MSR_PMON_RAW_EVENT_MASK,
-	.box_ctl		= HSWEP_PCU_MSR_PMON_BOX_CTL,
-	.num_shared_regs	= 1,
-	.ops			= &hswep_uncore_pcu_ops,
-	.format_group		= &snbep_uncore_pcu_format_group,
-};
-
-static struct intel_uncore_type *hswep_msr_uncores[] = {
-	&hswep_uncore_ubox,
-	&hswep_uncore_cbox,
-	&hswep_uncore_sbox,
-	&hswep_uncore_pcu,
-	NULL,
-};
-
-void hswep_uncore_cpu_init(void)
-{
-	if (hswep_uncore_cbox.num_boxes > boot_cpu_data.x86_max_cores)
-		hswep_uncore_cbox.num_boxes = boot_cpu_data.x86_max_cores;
-
-	/* Detect 6-8 core systems with only two SBOXes */
-	if (uncore_extra_pci_dev[0][HSWEP_PCI_PCU_3]) {
-		u32 capid4;
-
-		pci_read_config_dword(uncore_extra_pci_dev[0][HSWEP_PCI_PCU_3],
-				      0x94, &capid4);
-		if (((capid4 >> 6) & 0x3) == 0)
-			hswep_uncore_sbox.num_boxes = 2;
-	}
-
-	uncore_msr_uncores = hswep_msr_uncores;
-}
-
-static struct intel_uncore_type hswep_uncore_ha = {
-	.name		= "ha",
-	.num_counters   = 5,
-	.num_boxes	= 2,
-	.perf_ctr_bits	= 48,
-	SNBEP_UNCORE_PCI_COMMON_INIT(),
-};
-
-static struct uncore_event_desc hswep_uncore_imc_events[] = {
-	INTEL_UNCORE_EVENT_DESC(clockticks,      "event=0x00,umask=0x00"),
-	INTEL_UNCORE_EVENT_DESC(cas_count_read,  "event=0x04,umask=0x03"),
-	INTEL_UNCORE_EVENT_DESC(cas_count_read.scale, "6.103515625e-5"),
-	INTEL_UNCORE_EVENT_DESC(cas_count_read.unit, "MiB"),
-	INTEL_UNCORE_EVENT_DESC(cas_count_write, "event=0x04,umask=0x0c"),
-	INTEL_UNCORE_EVENT_DESC(cas_count_write.scale, "6.103515625e-5"),
-	INTEL_UNCORE_EVENT_DESC(cas_count_write.unit, "MiB"),
-	{ /* end: all zeroes */ },
-};
-
-static struct intel_uncore_type hswep_uncore_imc = {
-	.name		= "imc",
-	.num_counters   = 5,
-	.num_boxes	= 8,
-	.perf_ctr_bits	= 48,
-	.fixed_ctr_bits	= 48,
-	.fixed_ctr	= SNBEP_MC_CHy_PCI_PMON_FIXED_CTR,
-	.fixed_ctl	= SNBEP_MC_CHy_PCI_PMON_FIXED_CTL,
-	.event_descs	= hswep_uncore_imc_events,
-	SNBEP_UNCORE_PCI_COMMON_INIT(),
-};
-
-static unsigned hswep_uncore_irp_ctrs[] = {0xa0, 0xa8, 0xb0, 0xb8};
-
-static u64 hswep_uncore_irp_read_counter(struct intel_uncore_box *box, struct perf_event *event)
-{
-	struct pci_dev *pdev = box->pci_dev;
-	struct hw_perf_event *hwc = &event->hw;
-	u64 count = 0;
-
-	pci_read_config_dword(pdev, hswep_uncore_irp_ctrs[hwc->idx], (u32 *)&count);
-	pci_read_config_dword(pdev, hswep_uncore_irp_ctrs[hwc->idx] + 4, (u32 *)&count + 1);
-
-	return count;
-}
-
-static struct intel_uncore_ops hswep_uncore_irp_ops = {
-	.init_box	= snbep_uncore_pci_init_box,
-	.disable_box	= snbep_uncore_pci_disable_box,
-	.enable_box	= snbep_uncore_pci_enable_box,
-	.disable_event	= ivbep_uncore_irp_disable_event,
-	.enable_event	= ivbep_uncore_irp_enable_event,
-	.read_counter	= hswep_uncore_irp_read_counter,
-};
-
-static struct intel_uncore_type hswep_uncore_irp = {
-	.name			= "irp",
-	.num_counters		= 4,
-	.num_boxes		= 1,
-	.perf_ctr_bits		= 48,
-	.event_mask		= SNBEP_PMON_RAW_EVENT_MASK,
-	.box_ctl		= SNBEP_PCI_PMON_BOX_CTL,
-	.ops			= &hswep_uncore_irp_ops,
-	.format_group		= &snbep_uncore_format_group,
-};
-
-static struct intel_uncore_type hswep_uncore_qpi = {
-	.name			= "qpi",
-	.num_counters		= 5,
-	.num_boxes		= 3,
-	.perf_ctr_bits		= 48,
-	.perf_ctr		= SNBEP_PCI_PMON_CTR0,
-	.event_ctl		= SNBEP_PCI_PMON_CTL0,
-	.event_mask		= SNBEP_QPI_PCI_PMON_RAW_EVENT_MASK,
-	.box_ctl		= SNBEP_PCI_PMON_BOX_CTL,
-	.num_shared_regs	= 1,
-	.ops			= &snbep_uncore_qpi_ops,
-	.format_group		= &snbep_uncore_qpi_format_group,
-};
-
-static struct event_constraint hswep_uncore_r2pcie_constraints[] = {
-	UNCORE_EVENT_CONSTRAINT(0x10, 0x3),
-	UNCORE_EVENT_CONSTRAINT(0x11, 0x3),
-	UNCORE_EVENT_CONSTRAINT(0x13, 0x1),
-	UNCORE_EVENT_CONSTRAINT(0x23, 0x1),
-	UNCORE_EVENT_CONSTRAINT(0x24, 0x1),
-	UNCORE_EVENT_CONSTRAINT(0x25, 0x1),
-	UNCORE_EVENT_CONSTRAINT(0x26, 0x3),
-	UNCORE_EVENT_CONSTRAINT(0x27, 0x1),
-	UNCORE_EVENT_CONSTRAINT(0x28, 0x3),
-	UNCORE_EVENT_CONSTRAINT(0x29, 0x3),
-	UNCORE_EVENT_CONSTRAINT(0x2a, 0x1),
-	UNCORE_EVENT_CONSTRAINT(0x2b, 0x3),
-	UNCORE_EVENT_CONSTRAINT(0x2c, 0x3),
-	UNCORE_EVENT_CONSTRAINT(0x2d, 0x3),
-	UNCORE_EVENT_CONSTRAINT(0x32, 0x3),
-	UNCORE_EVENT_CONSTRAINT(0x33, 0x3),
-	UNCORE_EVENT_CONSTRAINT(0x34, 0x3),
-	UNCORE_EVENT_CONSTRAINT(0x35, 0x3),
-	EVENT_CONSTRAINT_END
-};
-
-static struct intel_uncore_type hswep_uncore_r2pcie = {
-	.name		= "r2pcie",
-	.num_counters   = 4,
-	.num_boxes	= 1,
-	.perf_ctr_bits	= 48,
-	.constraints	= hswep_uncore_r2pcie_constraints,
-	SNBEP_UNCORE_PCI_COMMON_INIT(),
-};
-
-static struct event_constraint hswep_uncore_r3qpi_constraints[] = {
-	UNCORE_EVENT_CONSTRAINT(0x01, 0x3),
-	UNCORE_EVENT_CONSTRAINT(0x07, 0x7),
-	UNCORE_EVENT_CONSTRAINT(0x08, 0x7),
-	UNCORE_EVENT_CONSTRAINT(0x09, 0x7),
-	UNCORE_EVENT_CONSTRAINT(0x0a, 0x7),
-	UNCORE_EVENT_CONSTRAINT(0x0e, 0x7),
-	UNCORE_EVENT_CONSTRAINT(0x10, 0x3),
-	UNCORE_EVENT_CONSTRAINT(0x11, 0x3),
-	UNCORE_EVENT_CONSTRAINT(0x12, 0x3),
-	UNCORE_EVENT_CONSTRAINT(0x13, 0x1),
-	UNCORE_EVENT_CONSTRAINT(0x14, 0x3),
-	UNCORE_EVENT_CONSTRAINT(0x15, 0x3),
-	UNCORE_EVENT_CONSTRAINT(0x1f, 0x3),
-	UNCORE_EVENT_CONSTRAINT(0x20, 0x3),
-	UNCORE_EVENT_CONSTRAINT(0x21, 0x3),
-	UNCORE_EVENT_CONSTRAINT(0x22, 0x3),
-	UNCORE_EVENT_CONSTRAINT(0x23, 0x3),
-	UNCORE_EVENT_CONSTRAINT(0x25, 0x3),
-	UNCORE_EVENT_CONSTRAINT(0x26, 0x3),
-	UNCORE_EVENT_CONSTRAINT(0x28, 0x3),
-	UNCORE_EVENT_CONSTRAINT(0x29, 0x3),
-	UNCORE_EVENT_CONSTRAINT(0x2c, 0x3),
-	UNCORE_EVENT_CONSTRAINT(0x2d, 0x3),
-	UNCORE_EVENT_CONSTRAINT(0x2e, 0x3),
-	UNCORE_EVENT_CONSTRAINT(0x2f, 0x3),
-	UNCORE_EVENT_CONSTRAINT(0x31, 0x3),
-	UNCORE_EVENT_CONSTRAINT(0x32, 0x3),
-	UNCORE_EVENT_CONSTRAINT(0x33, 0x3),
-	UNCORE_EVENT_CONSTRAINT(0x34, 0x3),
-	UNCORE_EVENT_CONSTRAINT(0x36, 0x3),
-	UNCORE_EVENT_CONSTRAINT(0x37, 0x3),
-	UNCORE_EVENT_CONSTRAINT(0x38, 0x3),
-	UNCORE_EVENT_CONSTRAINT(0x39, 0x3),
-	EVENT_CONSTRAINT_END
-};
-
-static struct intel_uncore_type hswep_uncore_r3qpi = {
-	.name		= "r3qpi",
-	.num_counters   = 4,
-	.num_boxes	= 3,
-	.perf_ctr_bits	= 44,
-	.constraints	= hswep_uncore_r3qpi_constraints,
-	SNBEP_UNCORE_PCI_COMMON_INIT(),
-};
-
-enum {
-	HSWEP_PCI_UNCORE_HA,
-	HSWEP_PCI_UNCORE_IMC,
-	HSWEP_PCI_UNCORE_IRP,
-	HSWEP_PCI_UNCORE_QPI,
-	HSWEP_PCI_UNCORE_R2PCIE,
-	HSWEP_PCI_UNCORE_R3QPI,
-};
-
-static struct intel_uncore_type *hswep_pci_uncores[] = {
-	[HSWEP_PCI_UNCORE_HA]	= &hswep_uncore_ha,
-	[HSWEP_PCI_UNCORE_IMC]	= &hswep_uncore_imc,
-	[HSWEP_PCI_UNCORE_IRP]	= &hswep_uncore_irp,
-	[HSWEP_PCI_UNCORE_QPI]	= &hswep_uncore_qpi,
-	[HSWEP_PCI_UNCORE_R2PCIE]	= &hswep_uncore_r2pcie,
-	[HSWEP_PCI_UNCORE_R3QPI]	= &hswep_uncore_r3qpi,
-	NULL,
-};
-
-static const struct pci_device_id hswep_uncore_pci_ids[] = {
-	{ /* Home Agent 0 */
-		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2f30),
-		.driver_data = UNCORE_PCI_DEV_DATA(HSWEP_PCI_UNCORE_HA, 0),
-	},
-	{ /* Home Agent 1 */
-		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2f38),
-		.driver_data = UNCORE_PCI_DEV_DATA(HSWEP_PCI_UNCORE_HA, 1),
-	},
-	{ /* MC0 Channel 0 */
-		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2fb0),
-		.driver_data = UNCORE_PCI_DEV_DATA(HSWEP_PCI_UNCORE_IMC, 0),
-	},
-	{ /* MC0 Channel 1 */
-		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2fb1),
-		.driver_data = UNCORE_PCI_DEV_DATA(HSWEP_PCI_UNCORE_IMC, 1),
-	},
-	{ /* MC0 Channel 2 */
-		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2fb4),
-		.driver_data = UNCORE_PCI_DEV_DATA(HSWEP_PCI_UNCORE_IMC, 2),
-	},
-	{ /* MC0 Channel 3 */
-		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2fb5),
-		.driver_data = UNCORE_PCI_DEV_DATA(HSWEP_PCI_UNCORE_IMC, 3),
-	},
-	{ /* MC1 Channel 0 */
-		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2fd0),
-		.driver_data = UNCORE_PCI_DEV_DATA(HSWEP_PCI_UNCORE_IMC, 4),
-	},
-	{ /* MC1 Channel 1 */
-		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2fd1),
-		.driver_data = UNCORE_PCI_DEV_DATA(HSWEP_PCI_UNCORE_IMC, 5),
-	},
-	{ /* MC1 Channel 2 */
-		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2fd4),
-		.driver_data = UNCORE_PCI_DEV_DATA(HSWEP_PCI_UNCORE_IMC, 6),
-	},
-	{ /* MC1 Channel 3 */
-		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2fd5),
-		.driver_data = UNCORE_PCI_DEV_DATA(HSWEP_PCI_UNCORE_IMC, 7),
-	},
-	{ /* IRP */
-		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2f39),
-		.driver_data = UNCORE_PCI_DEV_DATA(HSWEP_PCI_UNCORE_IRP, 0),
-	},
-	{ /* QPI0 Port 0 */
-		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2f32),
-		.driver_data = UNCORE_PCI_DEV_DATA(HSWEP_PCI_UNCORE_QPI, 0),
-	},
-	{ /* QPI0 Port 1 */
-		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2f33),
-		.driver_data = UNCORE_PCI_DEV_DATA(HSWEP_PCI_UNCORE_QPI, 1),
-	},
-	{ /* QPI1 Port 2 */
-		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2f3a),
-		.driver_data = UNCORE_PCI_DEV_DATA(HSWEP_PCI_UNCORE_QPI, 2),
-	},
-	{ /* R2PCIe */
-		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2f34),
-		.driver_data = UNCORE_PCI_DEV_DATA(HSWEP_PCI_UNCORE_R2PCIE, 0),
-	},
-	{ /* R3QPI0 Link 0 */
-		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2f36),
-		.driver_data = UNCORE_PCI_DEV_DATA(HSWEP_PCI_UNCORE_R3QPI, 0),
-	},
-	{ /* R3QPI0 Link 1 */
-		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2f37),
-		.driver_data = UNCORE_PCI_DEV_DATA(HSWEP_PCI_UNCORE_R3QPI, 1),
-	},
-	{ /* R3QPI1 Link 2 */
-		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2f3e),
-		.driver_data = UNCORE_PCI_DEV_DATA(HSWEP_PCI_UNCORE_R3QPI, 2),
-	},
-	{ /* QPI Port 0 filter  */
-		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2f86),
-		.driver_data = UNCORE_PCI_DEV_DATA(UNCORE_EXTRA_PCI_DEV,
-						   SNBEP_PCI_QPI_PORT0_FILTER),
-	},
-	{ /* QPI Port 1 filter  */
-		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2f96),
-		.driver_data = UNCORE_PCI_DEV_DATA(UNCORE_EXTRA_PCI_DEV,
-						   SNBEP_PCI_QPI_PORT1_FILTER),
-	},
-	{ /* PCU.3 (for Capability registers) */
-		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2fc0),
-		.driver_data = UNCORE_PCI_DEV_DATA(UNCORE_EXTRA_PCI_DEV,
-						   HSWEP_PCI_PCU_3),
-	},
-	{ /* end: all zeroes */ }
-};
-
-static struct pci_driver hswep_uncore_pci_driver = {
-	.name		= "hswep_uncore",
-	.id_table	= hswep_uncore_pci_ids,
-};
-
-int hswep_uncore_pci_init(void)
-{
-	int ret = snbep_pci2phy_map_init(0x2f1e);
-	if (ret)
-		return ret;
-	uncore_pci_uncores = hswep_pci_uncores;
-	uncore_pci_driver = &hswep_uncore_pci_driver;
-	return 0;
-}
-/* end of Haswell-EP uncore support */
-
-/* BDX-DE uncore support */
-
-static struct intel_uncore_type bdx_uncore_ubox = {
-	.name			= "ubox",
-	.num_counters		= 2,
-	.num_boxes		= 1,
-	.perf_ctr_bits		= 48,
-	.fixed_ctr_bits		= 48,
-	.perf_ctr		= HSWEP_U_MSR_PMON_CTR0,
-	.event_ctl		= HSWEP_U_MSR_PMON_CTL0,
-	.event_mask		= SNBEP_U_MSR_PMON_RAW_EVENT_MASK,
-	.fixed_ctr		= HSWEP_U_MSR_PMON_UCLK_FIXED_CTR,
-	.fixed_ctl		= HSWEP_U_MSR_PMON_UCLK_FIXED_CTL,
-	.num_shared_regs	= 1,
-	.ops			= &ivbep_uncore_msr_ops,
-	.format_group		= &ivbep_uncore_ubox_format_group,
-};
-
-static struct event_constraint bdx_uncore_cbox_constraints[] = {
-	UNCORE_EVENT_CONSTRAINT(0x09, 0x3),
-	UNCORE_EVENT_CONSTRAINT(0x11, 0x1),
-	UNCORE_EVENT_CONSTRAINT(0x36, 0x1),
-	EVENT_CONSTRAINT_END
-};
-
-static struct intel_uncore_type bdx_uncore_cbox = {
-	.name			= "cbox",
-	.num_counters		= 4,
-	.num_boxes		= 8,
-	.perf_ctr_bits		= 48,
-	.event_ctl		= HSWEP_C0_MSR_PMON_CTL0,
-	.perf_ctr		= HSWEP_C0_MSR_PMON_CTR0,
-	.event_mask		= SNBEP_CBO_MSR_PMON_RAW_EVENT_MASK,
-	.box_ctl		= HSWEP_C0_MSR_PMON_BOX_CTL,
-	.msr_offset		= HSWEP_CBO_MSR_OFFSET,
-	.num_shared_regs	= 1,
-	.constraints		= bdx_uncore_cbox_constraints,
-	.ops			= &hswep_uncore_cbox_ops,
-	.format_group		= &hswep_uncore_cbox_format_group,
-};
-
-static struct intel_uncore_type *bdx_msr_uncores[] = {
-	&bdx_uncore_ubox,
-	&bdx_uncore_cbox,
-	&hswep_uncore_pcu,
-	NULL,
-};
-
-void bdx_uncore_cpu_init(void)
-{
-	if (bdx_uncore_cbox.num_boxes > boot_cpu_data.x86_max_cores)
-		bdx_uncore_cbox.num_boxes = boot_cpu_data.x86_max_cores;
-	uncore_msr_uncores = bdx_msr_uncores;
-}
-
-static struct intel_uncore_type bdx_uncore_ha = {
-	.name		= "ha",
-	.num_counters   = 4,
-	.num_boxes	= 1,
-	.perf_ctr_bits	= 48,
-	SNBEP_UNCORE_PCI_COMMON_INIT(),
-};
-
-static struct intel_uncore_type bdx_uncore_imc = {
-	.name		= "imc",
-	.num_counters   = 5,
-	.num_boxes	= 2,
-	.perf_ctr_bits	= 48,
-	.fixed_ctr_bits	= 48,
-	.fixed_ctr	= SNBEP_MC_CHy_PCI_PMON_FIXED_CTR,
-	.fixed_ctl	= SNBEP_MC_CHy_PCI_PMON_FIXED_CTL,
-	.event_descs	= hswep_uncore_imc_events,
-	SNBEP_UNCORE_PCI_COMMON_INIT(),
-};
-
-static struct intel_uncore_type bdx_uncore_irp = {
-	.name			= "irp",
-	.num_counters		= 4,
-	.num_boxes		= 1,
-	.perf_ctr_bits		= 48,
-	.event_mask		= SNBEP_PMON_RAW_EVENT_MASK,
-	.box_ctl		= SNBEP_PCI_PMON_BOX_CTL,
-	.ops			= &hswep_uncore_irp_ops,
-	.format_group		= &snbep_uncore_format_group,
-};
-
-
-static struct event_constraint bdx_uncore_r2pcie_constraints[] = {
-	UNCORE_EVENT_CONSTRAINT(0x10, 0x3),
-	UNCORE_EVENT_CONSTRAINT(0x11, 0x3),
-	UNCORE_EVENT_CONSTRAINT(0x13, 0x1),
-	UNCORE_EVENT_CONSTRAINT(0x23, 0x1),
-	UNCORE_EVENT_CONSTRAINT(0x25, 0x1),
-	UNCORE_EVENT_CONSTRAINT(0x26, 0x3),
-	UNCORE_EVENT_CONSTRAINT(0x2d, 0x3),
-	EVENT_CONSTRAINT_END
-};
-
-static struct intel_uncore_type bdx_uncore_r2pcie = {
-	.name		= "r2pcie",
-	.num_counters   = 4,
-	.num_boxes	= 1,
-	.perf_ctr_bits	= 48,
-	.constraints	= bdx_uncore_r2pcie_constraints,
-	SNBEP_UNCORE_PCI_COMMON_INIT(),
-};
-
-enum {
-	BDX_PCI_UNCORE_HA,
-	BDX_PCI_UNCORE_IMC,
-	BDX_PCI_UNCORE_IRP,
-	BDX_PCI_UNCORE_R2PCIE,
-};
-
-static struct intel_uncore_type *bdx_pci_uncores[] = {
-	[BDX_PCI_UNCORE_HA]	= &bdx_uncore_ha,
-	[BDX_PCI_UNCORE_IMC]	= &bdx_uncore_imc,
-	[BDX_PCI_UNCORE_IRP]	= &bdx_uncore_irp,
-	[BDX_PCI_UNCORE_R2PCIE]	= &bdx_uncore_r2pcie,
-	NULL,
-};
-
-static const struct pci_device_id bdx_uncore_pci_ids[] = {
-	{ /* Home Agent 0 */
-		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x6f30),
-		.driver_data = UNCORE_PCI_DEV_DATA(BDX_PCI_UNCORE_HA, 0),
-	},
-	{ /* MC0 Channel 0 */
-		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x6fb0),
-		.driver_data = UNCORE_PCI_DEV_DATA(BDX_PCI_UNCORE_IMC, 0),
-	},
-	{ /* MC0 Channel 1 */
-		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x6fb1),
-		.driver_data = UNCORE_PCI_DEV_DATA(BDX_PCI_UNCORE_IMC, 1),
-	},
-	{ /* IRP */
-		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x6f39),
-		.driver_data = UNCORE_PCI_DEV_DATA(BDX_PCI_UNCORE_IRP, 0),
-	},
-	{ /* R2PCIe */
-		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x6f34),
-		.driver_data = UNCORE_PCI_DEV_DATA(BDX_PCI_UNCORE_R2PCIE, 0),
-	},
-	{ /* end: all zeroes */ }
-};
-
-static struct pci_driver bdx_uncore_pci_driver = {
-	.name		= "bdx_uncore",
-	.id_table	= bdx_uncore_pci_ids,
-};
-
-int bdx_uncore_pci_init(void)
-{
-	int ret = snbep_pci2phy_map_init(0x6f1e);
-
-	if (ret)
-		return ret;
-	uncore_pci_uncores = bdx_pci_uncores;
-	uncore_pci_driver = &bdx_uncore_pci_driver;
-	return 0;
-}
-
-/* end of BDX-DE uncore support */
--- zfcpdump-kernel-4.4.orig/arch/x86/kernel/cpu/perf_event_knc.c
+++ /dev/null
@@ -1,319 +0,0 @@
-/* Driver for Intel Xeon Phi "Knights Corner" PMU */
-
-#include <linux/perf_event.h>
-#include <linux/types.h>
-
-#include <asm/hardirq.h>
-
-#include "perf_event.h"
-
-static const u64 knc_perfmon_event_map[] =
-{
-  [PERF_COUNT_HW_CPU_CYCLES]		= 0x002a,
-  [PERF_COUNT_HW_INSTRUCTIONS]		= 0x0016,
-  [PERF_COUNT_HW_CACHE_REFERENCES]	= 0x0028,
-  [PERF_COUNT_HW_CACHE_MISSES]		= 0x0029,
-  [PERF_COUNT_HW_BRANCH_INSTRUCTIONS]	= 0x0012,
-  [PERF_COUNT_HW_BRANCH_MISSES]		= 0x002b,
-};
-
-static const u64 __initconst knc_hw_cache_event_ids
-				[PERF_COUNT_HW_CACHE_MAX]
-				[PERF_COUNT_HW_CACHE_OP_MAX]
-				[PERF_COUNT_HW_CACHE_RESULT_MAX] =
-{
- [ C(L1D) ] = {
-	[ C(OP_READ) ] = {
-		/* On Xeon Phi event "0" is a valid DATA_READ          */
-		/*   (L1 Data Cache Reads) Instruction.                */
-		/* We code this as ARCH_PERFMON_EVENTSEL_INT as this   */
-		/* bit will always be set in x86_pmu_hw_config().      */
-		[ C(RESULT_ACCESS) ] = ARCH_PERFMON_EVENTSEL_INT,
-						/* DATA_READ           */
-		[ C(RESULT_MISS)   ] = 0x0003,	/* DATA_READ_MISS      */
-	},
-	[ C(OP_WRITE) ] = {
-		[ C(RESULT_ACCESS) ] = 0x0001,	/* DATA_WRITE          */
-		[ C(RESULT_MISS)   ] = 0x0004,	/* DATA_WRITE_MISS     */
-	},
-	[ C(OP_PREFETCH) ] = {
-		[ C(RESULT_ACCESS) ] = 0x0011,	/* L1_DATA_PF1         */
-		[ C(RESULT_MISS)   ] = 0x001c,	/* L1_DATA_PF1_MISS    */
-	},
- },
- [ C(L1I ) ] = {
-	[ C(OP_READ) ] = {
-		[ C(RESULT_ACCESS) ] = 0x000c,	/* CODE_READ          */
-		[ C(RESULT_MISS)   ] = 0x000e,	/* CODE_CACHE_MISS    */
-	},
-	[ C(OP_WRITE) ] = {
-		[ C(RESULT_ACCESS) ] = -1,
-		[ C(RESULT_MISS)   ] = -1,
-	},
-	[ C(OP_PREFETCH) ] = {
-		[ C(RESULT_ACCESS) ] = 0x0,
-		[ C(RESULT_MISS)   ] = 0x0,
-	},
- },
- [ C(LL  ) ] = {
-	[ C(OP_READ) ] = {
-		[ C(RESULT_ACCESS) ] = 0,
-		[ C(RESULT_MISS)   ] = 0x10cb,	/* L2_READ_MISS */
-	},
-	[ C(OP_WRITE) ] = {
-		[ C(RESULT_ACCESS) ] = 0x10cc,	/* L2_WRITE_HIT */
-		[ C(RESULT_MISS)   ] = 0,
-	},
-	[ C(OP_PREFETCH) ] = {
-		[ C(RESULT_ACCESS) ] = 0x10fc,	/* L2_DATA_PF2      */
-		[ C(RESULT_MISS)   ] = 0x10fe,	/* L2_DATA_PF2_MISS */
-	},
- },
- [ C(DTLB) ] = {
-	[ C(OP_READ) ] = {
-		[ C(RESULT_ACCESS) ] = ARCH_PERFMON_EVENTSEL_INT,
-						/* DATA_READ */
-						/* see note on L1 OP_READ */
-		[ C(RESULT_MISS)   ] = 0x0002,	/* DATA_PAGE_WALK */
-	},
-	[ C(OP_WRITE) ] = {
-		[ C(RESULT_ACCESS) ] = 0x0001,	/* DATA_WRITE */
-		[ C(RESULT_MISS)   ] = 0x0002,	/* DATA_PAGE_WALK */
-	},
-	[ C(OP_PREFETCH) ] = {
-		[ C(RESULT_ACCESS) ] = 0x0,
-		[ C(RESULT_MISS)   ] = 0x0,
-	},
- },
- [ C(ITLB) ] = {
-	[ C(OP_READ) ] = {
-		[ C(RESULT_ACCESS) ] = 0x000c,	/* CODE_READ */
-		[ C(RESULT_MISS)   ] = 0x000d,	/* CODE_PAGE_WALK */
-	},
-	[ C(OP_WRITE) ] = {
-		[ C(RESULT_ACCESS) ] = -1,
-		[ C(RESULT_MISS)   ] = -1,
-	},
-	[ C(OP_PREFETCH) ] = {
-		[ C(RESULT_ACCESS) ] = -1,
-		[ C(RESULT_MISS)   ] = -1,
-	},
- },
- [ C(BPU ) ] = {
-	[ C(OP_READ) ] = {
-		[ C(RESULT_ACCESS) ] = 0x0012,	/* BRANCHES */
-		[ C(RESULT_MISS)   ] = 0x002b,	/* BRANCHES_MISPREDICTED */
-	},
-	[ C(OP_WRITE) ] = {
-		[ C(RESULT_ACCESS) ] = -1,
-		[ C(RESULT_MISS)   ] = -1,
-	},
-	[ C(OP_PREFETCH) ] = {
-		[ C(RESULT_ACCESS) ] = -1,
-		[ C(RESULT_MISS)   ] = -1,
-	},
- },
-};
-
-
-static u64 knc_pmu_event_map(int hw_event)
-{
-	return knc_perfmon_event_map[hw_event];
-}
-
-static struct event_constraint knc_event_constraints[] =
-{
-	INTEL_EVENT_CONSTRAINT(0xc3, 0x1),	/* HWP_L2HIT */
-	INTEL_EVENT_CONSTRAINT(0xc4, 0x1),	/* HWP_L2MISS */
-	INTEL_EVENT_CONSTRAINT(0xc8, 0x1),	/* L2_READ_HIT_E */
-	INTEL_EVENT_CONSTRAINT(0xc9, 0x1),	/* L2_READ_HIT_M */
-	INTEL_EVENT_CONSTRAINT(0xca, 0x1),	/* L2_READ_HIT_S */
-	INTEL_EVENT_CONSTRAINT(0xcb, 0x1),	/* L2_READ_MISS */
-	INTEL_EVENT_CONSTRAINT(0xcc, 0x1),	/* L2_WRITE_HIT */
-	INTEL_EVENT_CONSTRAINT(0xce, 0x1),	/* L2_STRONGLY_ORDERED_STREAMING_VSTORES_MISS */
-	INTEL_EVENT_CONSTRAINT(0xcf, 0x1),	/* L2_WEAKLY_ORDERED_STREAMING_VSTORE_MISS */
-	INTEL_EVENT_CONSTRAINT(0xd7, 0x1),	/* L2_VICTIM_REQ_WITH_DATA */
-	INTEL_EVENT_CONSTRAINT(0xe3, 0x1),	/* SNP_HITM_BUNIT */
-	INTEL_EVENT_CONSTRAINT(0xe6, 0x1),	/* SNP_HIT_L2 */
-	INTEL_EVENT_CONSTRAINT(0xe7, 0x1),	/* SNP_HITM_L2 */
-	INTEL_EVENT_CONSTRAINT(0xf1, 0x1),	/* L2_DATA_READ_MISS_CACHE_FILL */
-	INTEL_EVENT_CONSTRAINT(0xf2, 0x1),	/* L2_DATA_WRITE_MISS_CACHE_FILL */
-	INTEL_EVENT_CONSTRAINT(0xf6, 0x1),	/* L2_DATA_READ_MISS_MEM_FILL */
-	INTEL_EVENT_CONSTRAINT(0xf7, 0x1),	/* L2_DATA_WRITE_MISS_MEM_FILL */
-	INTEL_EVENT_CONSTRAINT(0xfc, 0x1),	/* L2_DATA_PF2 */
-	INTEL_EVENT_CONSTRAINT(0xfd, 0x1),	/* L2_DATA_PF2_DROP */
-	INTEL_EVENT_CONSTRAINT(0xfe, 0x1),	/* L2_DATA_PF2_MISS */
-	INTEL_EVENT_CONSTRAINT(0xff, 0x1),	/* L2_DATA_HIT_INFLIGHT_PF2 */
-	EVENT_CONSTRAINT_END
-};
-
-#define MSR_KNC_IA32_PERF_GLOBAL_STATUS		0x0000002d
-#define MSR_KNC_IA32_PERF_GLOBAL_OVF_CONTROL	0x0000002e
-#define MSR_KNC_IA32_PERF_GLOBAL_CTRL		0x0000002f
-
-#define KNC_ENABLE_COUNTER0			0x00000001
-#define KNC_ENABLE_COUNTER1			0x00000002
-
-static void knc_pmu_disable_all(void)
-{
-	u64 val;
-
-	rdmsrl(MSR_KNC_IA32_PERF_GLOBAL_CTRL, val);
-	val &= ~(KNC_ENABLE_COUNTER0|KNC_ENABLE_COUNTER1);
-	wrmsrl(MSR_KNC_IA32_PERF_GLOBAL_CTRL, val);
-}
-
-static void knc_pmu_enable_all(int added)
-{
-	u64 val;
-
-	rdmsrl(MSR_KNC_IA32_PERF_GLOBAL_CTRL, val);
-	val |= (KNC_ENABLE_COUNTER0|KNC_ENABLE_COUNTER1);
-	wrmsrl(MSR_KNC_IA32_PERF_GLOBAL_CTRL, val);
-}
-
-static inline void
-knc_pmu_disable_event(struct perf_event *event)
-{
-	struct hw_perf_event *hwc = &event->hw;
-	u64 val;
-
-	val = hwc->config;
-	val &= ~ARCH_PERFMON_EVENTSEL_ENABLE;
-
-	(void)wrmsrl_safe(hwc->config_base + hwc->idx, val);
-}
-
-static void knc_pmu_enable_event(struct perf_event *event)
-{
-	struct hw_perf_event *hwc = &event->hw;
-	u64 val;
-
-	val = hwc->config;
-	val |= ARCH_PERFMON_EVENTSEL_ENABLE;
-
-	(void)wrmsrl_safe(hwc->config_base + hwc->idx, val);
-}
-
-static inline u64 knc_pmu_get_status(void)
-{
-	u64 status;
-
-	rdmsrl(MSR_KNC_IA32_PERF_GLOBAL_STATUS, status);
-
-	return status;
-}
-
-static inline void knc_pmu_ack_status(u64 ack)
-{
-	wrmsrl(MSR_KNC_IA32_PERF_GLOBAL_OVF_CONTROL, ack);
-}
-
-static int knc_pmu_handle_irq(struct pt_regs *regs)
-{
-	struct perf_sample_data data;
-	struct cpu_hw_events *cpuc;
-	int handled = 0;
-	int bit, loops;
-	u64 status;
-
-	cpuc = this_cpu_ptr(&cpu_hw_events);
-
-	knc_pmu_disable_all();
-
-	status = knc_pmu_get_status();
-	if (!status) {
-		knc_pmu_enable_all(0);
-		return handled;
-	}
-
-	loops = 0;
-again:
-	knc_pmu_ack_status(status);
-	if (++loops > 100) {
-		WARN_ONCE(1, "perf: irq loop stuck!\n");
-		perf_event_print_debug();
-		goto done;
-	}
-
-	inc_irq_stat(apic_perf_irqs);
-
-	for_each_set_bit(bit, (unsigned long *)&status, X86_PMC_IDX_MAX) {
-		struct perf_event *event = cpuc->events[bit];
-
-		handled++;
-
-		if (!test_bit(bit, cpuc->active_mask))
-			continue;
-
-		if (!intel_pmu_save_and_restart(event))
-			continue;
-
-		perf_sample_data_init(&data, 0, event->hw.last_period);
-
-		if (perf_event_overflow(event, &data, regs))
-			x86_pmu_stop(event, 0);
-	}
-
-	/*
-	 * Repeat if there is more work to be done:
-	 */
-	status = knc_pmu_get_status();
-	if (status)
-		goto again;
-
-done:
-	knc_pmu_enable_all(0);
-
-	return handled;
-}
-
-
-PMU_FORMAT_ATTR(event,	"config:0-7"	);
-PMU_FORMAT_ATTR(umask,	"config:8-15"	);
-PMU_FORMAT_ATTR(edge,	"config:18"	);
-PMU_FORMAT_ATTR(inv,	"config:23"	);
-PMU_FORMAT_ATTR(cmask,	"config:24-31"	);
-
-static struct attribute *intel_knc_formats_attr[] = {
-	&format_attr_event.attr,
-	&format_attr_umask.attr,
-	&format_attr_edge.attr,
-	&format_attr_inv.attr,
-	&format_attr_cmask.attr,
-	NULL,
-};
-
-static const struct x86_pmu knc_pmu __initconst = {
-	.name			= "knc",
-	.handle_irq		= knc_pmu_handle_irq,
-	.disable_all		= knc_pmu_disable_all,
-	.enable_all		= knc_pmu_enable_all,
-	.enable			= knc_pmu_enable_event,
-	.disable		= knc_pmu_disable_event,
-	.hw_config		= x86_pmu_hw_config,
-	.schedule_events	= x86_schedule_events,
-	.eventsel		= MSR_KNC_EVNTSEL0,
-	.perfctr		= MSR_KNC_PERFCTR0,
-	.event_map		= knc_pmu_event_map,
-	.max_events             = ARRAY_SIZE(knc_perfmon_event_map),
-	.apic			= 1,
-	.max_period		= (1ULL << 39) - 1,
-	.version		= 0,
-	.num_counters		= 2,
-	.cntval_bits		= 40,
-	.cntval_mask		= (1ULL << 40) - 1,
-	.get_event_constraints	= x86_get_event_constraints,
-	.event_constraints	= knc_event_constraints,
-	.format_attrs		= intel_knc_formats_attr,
-};
-
-__init int knc_pmu_init(void)
-{
-	x86_pmu = knc_pmu;
-
-	memcpy(hw_cache_event_ids, knc_hw_cache_event_ids, 
-		sizeof(hw_cache_event_ids));
-
-	return 0;
-}
--- zfcpdump-kernel-4.4.orig/arch/x86/kernel/cpu/perf_event_msr.c
+++ /dev/null
@@ -1,241 +0,0 @@
-#include <linux/perf_event.h>
-
-enum perf_msr_id {
-	PERF_MSR_TSC			= 0,
-	PERF_MSR_APERF			= 1,
-	PERF_MSR_MPERF			= 2,
-	PERF_MSR_PPERF			= 3,
-	PERF_MSR_SMI			= 4,
-
-	PERF_MSR_EVENT_MAX,
-};
-
-static bool test_aperfmperf(int idx)
-{
-	return boot_cpu_has(X86_FEATURE_APERFMPERF);
-}
-
-static bool test_intel(int idx)
-{
-	if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL ||
-	    boot_cpu_data.x86 != 6)
-		return false;
-
-	switch (boot_cpu_data.x86_model) {
-	case 30: /* 45nm Nehalem    */
-	case 26: /* 45nm Nehalem-EP */
-	case 46: /* 45nm Nehalem-EX */
-
-	case 37: /* 32nm Westmere    */
-	case 44: /* 32nm Westmere-EP */
-	case 47: /* 32nm Westmere-EX */
-
-	case 42: /* 32nm SandyBridge         */
-	case 45: /* 32nm SandyBridge-E/EN/EP */
-
-	case 58: /* 22nm IvyBridge       */
-	case 62: /* 22nm IvyBridge-EP/EX */
-
-	case 60: /* 22nm Haswell Core */
-	case 63: /* 22nm Haswell Server */
-	case 69: /* 22nm Haswell ULT */
-	case 70: /* 22nm Haswell + GT3e (Intel Iris Pro graphics) */
-
-	case 61: /* 14nm Broadwell Core-M */
-	case 86: /* 14nm Broadwell Xeon D */
-	case 71: /* 14nm Broadwell + GT3e (Intel Iris Pro graphics) */
-	case 79: /* 14nm Broadwell Server */
-
-	case 55: /* 22nm Atom "Silvermont"                */
-	case 77: /* 22nm Atom "Silvermont Avoton/Rangely" */
-	case 76: /* 14nm Atom "Airmont"                   */
-		if (idx == PERF_MSR_SMI)
-			return true;
-		break;
-
-	case 78: /* 14nm Skylake Mobile */
-	case 94: /* 14nm Skylake Desktop */
-		if (idx == PERF_MSR_SMI || idx == PERF_MSR_PPERF)
-			return true;
-		break;
-	}
-
-	return false;
-}
-
-struct perf_msr {
-	u64	msr;
-	struct	perf_pmu_events_attr *attr;
-	bool	(*test)(int idx);
-};
-
-PMU_EVENT_ATTR_STRING(tsc,   evattr_tsc,   "event=0x00");
-PMU_EVENT_ATTR_STRING(aperf, evattr_aperf, "event=0x01");
-PMU_EVENT_ATTR_STRING(mperf, evattr_mperf, "event=0x02");
-PMU_EVENT_ATTR_STRING(pperf, evattr_pperf, "event=0x03");
-PMU_EVENT_ATTR_STRING(smi,   evattr_smi,   "event=0x04");
-
-static struct perf_msr msr[] = {
-	[PERF_MSR_TSC]   = { 0,			&evattr_tsc,	NULL,		 },
-	[PERF_MSR_APERF] = { MSR_IA32_APERF,	&evattr_aperf,	test_aperfmperf, },
-	[PERF_MSR_MPERF] = { MSR_IA32_MPERF,	&evattr_mperf,	test_aperfmperf, },
-	[PERF_MSR_PPERF] = { MSR_PPERF,		&evattr_pperf,	test_intel,	 },
-	[PERF_MSR_SMI]   = { MSR_SMI_COUNT,	&evattr_smi,	test_intel,	 },
-};
-
-static struct attribute *events_attrs[PERF_MSR_EVENT_MAX + 1] = {
-	NULL,
-};
-
-static struct attribute_group events_attr_group = {
-	.name = "events",
-	.attrs = events_attrs,
-};
-
-PMU_FORMAT_ATTR(event, "config:0-63");
-static struct attribute *format_attrs[] = {
-	&format_attr_event.attr,
-	NULL,
-};
-static struct attribute_group format_attr_group = {
-	.name = "format",
-	.attrs = format_attrs,
-};
-
-static const struct attribute_group *attr_groups[] = {
-	&events_attr_group,
-	&format_attr_group,
-	NULL,
-};
-
-static int msr_event_init(struct perf_event *event)
-{
-	u64 cfg = event->attr.config;
-
-	if (event->attr.type != event->pmu->type)
-		return -ENOENT;
-
-	if (cfg >= PERF_MSR_EVENT_MAX)
-		return -EINVAL;
-
-	/* unsupported modes and filters */
-	if (event->attr.exclude_user   ||
-	    event->attr.exclude_kernel ||
-	    event->attr.exclude_hv     ||
-	    event->attr.exclude_idle   ||
-	    event->attr.exclude_host   ||
-	    event->attr.exclude_guest  ||
-	    event->attr.sample_period) /* no sampling */
-		return -EINVAL;
-
-	if (!msr[cfg].attr)
-		return -EINVAL;
-
-	event->hw.idx = -1;
-	event->hw.event_base = msr[cfg].msr;
-	event->hw.config = cfg;
-
-	return 0;
-}
-
-static inline u64 msr_read_counter(struct perf_event *event)
-{
-	u64 now;
-
-	if (event->hw.event_base)
-		rdmsrl(event->hw.event_base, now);
-	else
-		rdtscll(now);
-
-	return now;
-}
-static void msr_event_update(struct perf_event *event)
-{
-	u64 prev, now;
-	s64 delta;
-
-	/* Careful, an NMI might modify the previous event value. */
-again:
-	prev = local64_read(&event->hw.prev_count);
-	now = msr_read_counter(event);
-
-	if (local64_cmpxchg(&event->hw.prev_count, prev, now) != prev)
-		goto again;
-
-	delta = now - prev;
-	if (unlikely(event->hw.event_base == MSR_SMI_COUNT))
-		delta = sign_extend64(delta, 31);
-
-	local64_add(now - prev, &event->count);
-}
-
-static void msr_event_start(struct perf_event *event, int flags)
-{
-	u64 now;
-
-	now = msr_read_counter(event);
-	local64_set(&event->hw.prev_count, now);
-}
-
-static void msr_event_stop(struct perf_event *event, int flags)
-{
-	msr_event_update(event);
-}
-
-static void msr_event_del(struct perf_event *event, int flags)
-{
-	msr_event_stop(event, PERF_EF_UPDATE);
-}
-
-static int msr_event_add(struct perf_event *event, int flags)
-{
-	if (flags & PERF_EF_START)
-		msr_event_start(event, flags);
-
-	return 0;
-}
-
-static struct pmu pmu_msr = {
-	.task_ctx_nr	= perf_sw_context,
-	.attr_groups	= attr_groups,
-	.event_init	= msr_event_init,
-	.add		= msr_event_add,
-	.del		= msr_event_del,
-	.start		= msr_event_start,
-	.stop		= msr_event_stop,
-	.read		= msr_event_update,
-	.capabilities	= PERF_PMU_CAP_NO_INTERRUPT,
-};
-
-static int __init msr_init(void)
-{
-	int i, j = 0;
-
-	if (!boot_cpu_has(X86_FEATURE_TSC)) {
-		pr_cont("no MSR PMU driver.\n");
-		return 0;
-	}
-
-	/* Probe the MSRs. */
-	for (i = PERF_MSR_TSC + 1; i < PERF_MSR_EVENT_MAX; i++) {
-		u64 val;
-
-		/*
-		 * Virt sucks arse; you cannot tell if a R/O MSR is present :/
-		 */
-		if (!msr[i].test(i) || rdmsrl_safe(msr[i].msr, &val))
-			msr[i].attr = NULL;
-	}
-
-	/* List remaining MSRs in the sysfs attrs. */
-	for (i = 0; i < PERF_MSR_EVENT_MAX; i++) {
-		if (msr[i].attr)
-			events_attrs[j++] = &msr[i].attr->attr.attr;
-	}
-	events_attrs[j] = NULL;
-
-	perf_pmu_register(&pmu_msr, "msr", -1);
-
-	return 0;
-}
-device_initcall(msr_init);
--- zfcpdump-kernel-4.4.orig/arch/x86/kernel/cpu/perf_event_p4.c
+++ /dev/null
@@ -1,1376 +0,0 @@
-/*
- * Netburst Performance Events (P4, old Xeon)
- *
- *  Copyright (C) 2010 Parallels, Inc., Cyrill Gorcunov <gorcunov@openvz.org>
- *  Copyright (C) 2010 Intel Corporation, Lin Ming <ming.m.lin@intel.com>
- *
- *  For licencing details see kernel-base/COPYING
- */
-
-#include <linux/perf_event.h>
-
-#include <asm/perf_event_p4.h>
-#include <asm/hardirq.h>
-#include <asm/apic.h>
-
-#include "perf_event.h"
-
-#define P4_CNTR_LIMIT 3
-/*
- * array indices: 0,1 - HT threads, used with HT enabled cpu
- */
-struct p4_event_bind {
-	unsigned int opcode;			/* Event code and ESCR selector */
-	unsigned int escr_msr[2];		/* ESCR MSR for this event */
-	unsigned int escr_emask;		/* valid ESCR EventMask bits */
-	unsigned int shared;			/* event is shared across threads */
-	char cntr[2][P4_CNTR_LIMIT];		/* counter index (offset), -1 on abscence */
-};
-
-struct p4_pebs_bind {
-	unsigned int metric_pebs;
-	unsigned int metric_vert;
-};
-
-/* it sets P4_PEBS_ENABLE_UOP_TAG as well */
-#define P4_GEN_PEBS_BIND(name, pebs, vert)			\
-	[P4_PEBS_METRIC__##name] = {				\
-		.metric_pebs = pebs | P4_PEBS_ENABLE_UOP_TAG,	\
-		.metric_vert = vert,				\
-	}
-
-/*
- * note we have P4_PEBS_ENABLE_UOP_TAG always set here
- *
- * it's needed for mapping P4_PEBS_CONFIG_METRIC_MASK bits of
- * event configuration to find out which values are to be
- * written into MSR_IA32_PEBS_ENABLE and MSR_P4_PEBS_MATRIX_VERT
- * resgisters
- */
-static struct p4_pebs_bind p4_pebs_bind_map[] = {
-	P4_GEN_PEBS_BIND(1stl_cache_load_miss_retired,	0x0000001, 0x0000001),
-	P4_GEN_PEBS_BIND(2ndl_cache_load_miss_retired,	0x0000002, 0x0000001),
-	P4_GEN_PEBS_BIND(dtlb_load_miss_retired,	0x0000004, 0x0000001),
-	P4_GEN_PEBS_BIND(dtlb_store_miss_retired,	0x0000004, 0x0000002),
-	P4_GEN_PEBS_BIND(dtlb_all_miss_retired,		0x0000004, 0x0000003),
-	P4_GEN_PEBS_BIND(tagged_mispred_branch,		0x0018000, 0x0000010),
-	P4_GEN_PEBS_BIND(mob_load_replay_retired,	0x0000200, 0x0000001),
-	P4_GEN_PEBS_BIND(split_load_retired,		0x0000400, 0x0000001),
-	P4_GEN_PEBS_BIND(split_store_retired,		0x0000400, 0x0000002),
-};
-
-/*
- * Note that we don't use CCCR1 here, there is an
- * exception for P4_BSQ_ALLOCATION but we just have
- * no workaround
- *
- * consider this binding as resources which particular
- * event may borrow, it doesn't contain EventMask,
- * Tags and friends -- they are left to a caller
- */
-static struct p4_event_bind p4_event_bind_map[] = {
-	[P4_EVENT_TC_DELIVER_MODE] = {
-		.opcode		= P4_OPCODE(P4_EVENT_TC_DELIVER_MODE),
-		.escr_msr	= { MSR_P4_TC_ESCR0, MSR_P4_TC_ESCR1 },
-		.escr_emask	=
-			P4_ESCR_EMASK_BIT(P4_EVENT_TC_DELIVER_MODE, DD)			|
-			P4_ESCR_EMASK_BIT(P4_EVENT_TC_DELIVER_MODE, DB)			|
-			P4_ESCR_EMASK_BIT(P4_EVENT_TC_DELIVER_MODE, DI)			|
-			P4_ESCR_EMASK_BIT(P4_EVENT_TC_DELIVER_MODE, BD)			|
-			P4_ESCR_EMASK_BIT(P4_EVENT_TC_DELIVER_MODE, BB)			|
-			P4_ESCR_EMASK_BIT(P4_EVENT_TC_DELIVER_MODE, BI)			|
-			P4_ESCR_EMASK_BIT(P4_EVENT_TC_DELIVER_MODE, ID),
-		.shared		= 1,
-		.cntr		= { {4, 5, -1}, {6, 7, -1} },
-	},
-	[P4_EVENT_BPU_FETCH_REQUEST] = {
-		.opcode		= P4_OPCODE(P4_EVENT_BPU_FETCH_REQUEST),
-		.escr_msr	= { MSR_P4_BPU_ESCR0, MSR_P4_BPU_ESCR1 },
-		.escr_emask	=
-			P4_ESCR_EMASK_BIT(P4_EVENT_BPU_FETCH_REQUEST, TCMISS),
-		.cntr		= { {0, -1, -1}, {2, -1, -1} },
-	},
-	[P4_EVENT_ITLB_REFERENCE] = {
-		.opcode		= P4_OPCODE(P4_EVENT_ITLB_REFERENCE),
-		.escr_msr	= { MSR_P4_ITLB_ESCR0, MSR_P4_ITLB_ESCR1 },
-		.escr_emask	=
-			P4_ESCR_EMASK_BIT(P4_EVENT_ITLB_REFERENCE, HIT)			|
-			P4_ESCR_EMASK_BIT(P4_EVENT_ITLB_REFERENCE, MISS)		|
-			P4_ESCR_EMASK_BIT(P4_EVENT_ITLB_REFERENCE, HIT_UK),
-		.cntr		= { {0, -1, -1}, {2, -1, -1} },
-	},
-	[P4_EVENT_MEMORY_CANCEL] = {
-		.opcode		= P4_OPCODE(P4_EVENT_MEMORY_CANCEL),
-		.escr_msr	= { MSR_P4_DAC_ESCR0, MSR_P4_DAC_ESCR1 },
-		.escr_emask	=
-			P4_ESCR_EMASK_BIT(P4_EVENT_MEMORY_CANCEL, ST_RB_FULL)		|
-			P4_ESCR_EMASK_BIT(P4_EVENT_MEMORY_CANCEL, 64K_CONF),
-		.cntr		= { {8, 9, -1}, {10, 11, -1} },
-	},
-	[P4_EVENT_MEMORY_COMPLETE] = {
-		.opcode		= P4_OPCODE(P4_EVENT_MEMORY_COMPLETE),
-		.escr_msr	= { MSR_P4_SAAT_ESCR0 , MSR_P4_SAAT_ESCR1 },
-		.escr_emask	=
-			P4_ESCR_EMASK_BIT(P4_EVENT_MEMORY_COMPLETE, LSC)		|
-			P4_ESCR_EMASK_BIT(P4_EVENT_MEMORY_COMPLETE, SSC),
-		.cntr		= { {8, 9, -1}, {10, 11, -1} },
-	},
-	[P4_EVENT_LOAD_PORT_REPLAY] = {
-		.opcode		= P4_OPCODE(P4_EVENT_LOAD_PORT_REPLAY),
-		.escr_msr	= { MSR_P4_SAAT_ESCR0, MSR_P4_SAAT_ESCR1 },
-		.escr_emask	=
-			P4_ESCR_EMASK_BIT(P4_EVENT_LOAD_PORT_REPLAY, SPLIT_LD),
-		.cntr		= { {8, 9, -1}, {10, 11, -1} },
-	},
-	[P4_EVENT_STORE_PORT_REPLAY] = {
-		.opcode		= P4_OPCODE(P4_EVENT_STORE_PORT_REPLAY),
-		.escr_msr	= { MSR_P4_SAAT_ESCR0 ,  MSR_P4_SAAT_ESCR1 },
-		.escr_emask	=
-			P4_ESCR_EMASK_BIT(P4_EVENT_STORE_PORT_REPLAY, SPLIT_ST),
-		.cntr		= { {8, 9, -1}, {10, 11, -1} },
-	},
-	[P4_EVENT_MOB_LOAD_REPLAY] = {
-		.opcode		= P4_OPCODE(P4_EVENT_MOB_LOAD_REPLAY),
-		.escr_msr	= { MSR_P4_MOB_ESCR0, MSR_P4_MOB_ESCR1 },
-		.escr_emask	=
-			P4_ESCR_EMASK_BIT(P4_EVENT_MOB_LOAD_REPLAY, NO_STA)		|
-			P4_ESCR_EMASK_BIT(P4_EVENT_MOB_LOAD_REPLAY, NO_STD)		|
-			P4_ESCR_EMASK_BIT(P4_EVENT_MOB_LOAD_REPLAY, PARTIAL_DATA)	|
-			P4_ESCR_EMASK_BIT(P4_EVENT_MOB_LOAD_REPLAY, UNALGN_ADDR),
-		.cntr		= { {0, -1, -1}, {2, -1, -1} },
-	},
-	[P4_EVENT_PAGE_WALK_TYPE] = {
-		.opcode		= P4_OPCODE(P4_EVENT_PAGE_WALK_TYPE),
-		.escr_msr	= { MSR_P4_PMH_ESCR0, MSR_P4_PMH_ESCR1 },
-		.escr_emask	=
-			P4_ESCR_EMASK_BIT(P4_EVENT_PAGE_WALK_TYPE, DTMISS)		|
-			P4_ESCR_EMASK_BIT(P4_EVENT_PAGE_WALK_TYPE, ITMISS),
-		.shared		= 1,
-		.cntr		= { {0, -1, -1}, {2, -1, -1} },
-	},
-	[P4_EVENT_BSQ_CACHE_REFERENCE] = {
-		.opcode		= P4_OPCODE(P4_EVENT_BSQ_CACHE_REFERENCE),
-		.escr_msr	= { MSR_P4_BSU_ESCR0, MSR_P4_BSU_ESCR1 },
-		.escr_emask	=
-			P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_CACHE_REFERENCE, RD_2ndL_HITS)	|
-			P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_CACHE_REFERENCE, RD_2ndL_HITE)	|
-			P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_CACHE_REFERENCE, RD_2ndL_HITM)	|
-			P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_CACHE_REFERENCE, RD_3rdL_HITS)	|
-			P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_CACHE_REFERENCE, RD_3rdL_HITE)	|
-			P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_CACHE_REFERENCE, RD_3rdL_HITM)	|
-			P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_CACHE_REFERENCE, RD_2ndL_MISS)	|
-			P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_CACHE_REFERENCE, RD_3rdL_MISS)	|
-			P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_CACHE_REFERENCE, WR_2ndL_MISS),
-		.cntr		= { {0, -1, -1}, {2, -1, -1} },
-	},
-	[P4_EVENT_IOQ_ALLOCATION] = {
-		.opcode		= P4_OPCODE(P4_EVENT_IOQ_ALLOCATION),
-		.escr_msr	= { MSR_P4_FSB_ESCR0, MSR_P4_FSB_ESCR1 },
-		.escr_emask	=
-			P4_ESCR_EMASK_BIT(P4_EVENT_IOQ_ALLOCATION, DEFAULT)		|
-			P4_ESCR_EMASK_BIT(P4_EVENT_IOQ_ALLOCATION, ALL_READ)		|
-			P4_ESCR_EMASK_BIT(P4_EVENT_IOQ_ALLOCATION, ALL_WRITE)		|
-			P4_ESCR_EMASK_BIT(P4_EVENT_IOQ_ALLOCATION, MEM_UC)		|
-			P4_ESCR_EMASK_BIT(P4_EVENT_IOQ_ALLOCATION, MEM_WC)		|
-			P4_ESCR_EMASK_BIT(P4_EVENT_IOQ_ALLOCATION, MEM_WT)		|
-			P4_ESCR_EMASK_BIT(P4_EVENT_IOQ_ALLOCATION, MEM_WP)		|
-			P4_ESCR_EMASK_BIT(P4_EVENT_IOQ_ALLOCATION, MEM_WB)		|
-			P4_ESCR_EMASK_BIT(P4_EVENT_IOQ_ALLOCATION, OWN)			|
-			P4_ESCR_EMASK_BIT(P4_EVENT_IOQ_ALLOCATION, OTHER)		|
-			P4_ESCR_EMASK_BIT(P4_EVENT_IOQ_ALLOCATION, PREFETCH),
-		.cntr		= { {0, -1, -1}, {2, -1, -1} },
-	},
-	[P4_EVENT_IOQ_ACTIVE_ENTRIES] = {	/* shared ESCR */
-		.opcode		= P4_OPCODE(P4_EVENT_IOQ_ACTIVE_ENTRIES),
-		.escr_msr	= { MSR_P4_FSB_ESCR1,  MSR_P4_FSB_ESCR1 },
-		.escr_emask	=
-			P4_ESCR_EMASK_BIT(P4_EVENT_IOQ_ACTIVE_ENTRIES, DEFAULT)		|
-			P4_ESCR_EMASK_BIT(P4_EVENT_IOQ_ACTIVE_ENTRIES, ALL_READ)	|
-			P4_ESCR_EMASK_BIT(P4_EVENT_IOQ_ACTIVE_ENTRIES, ALL_WRITE)	|
-			P4_ESCR_EMASK_BIT(P4_EVENT_IOQ_ACTIVE_ENTRIES, MEM_UC)		|
-			P4_ESCR_EMASK_BIT(P4_EVENT_IOQ_ACTIVE_ENTRIES, MEM_WC)		|
-			P4_ESCR_EMASK_BIT(P4_EVENT_IOQ_ACTIVE_ENTRIES, MEM_WT)		|
-			P4_ESCR_EMASK_BIT(P4_EVENT_IOQ_ACTIVE_ENTRIES, MEM_WP)		|
-			P4_ESCR_EMASK_BIT(P4_EVENT_IOQ_ACTIVE_ENTRIES, MEM_WB)		|
-			P4_ESCR_EMASK_BIT(P4_EVENT_IOQ_ACTIVE_ENTRIES, OWN)		|
-			P4_ESCR_EMASK_BIT(P4_EVENT_IOQ_ACTIVE_ENTRIES, OTHER)		|
-			P4_ESCR_EMASK_BIT(P4_EVENT_IOQ_ACTIVE_ENTRIES, PREFETCH),
-		.cntr		= { {2, -1, -1}, {3, -1, -1} },
-	},
-	[P4_EVENT_FSB_DATA_ACTIVITY] = {
-		.opcode		= P4_OPCODE(P4_EVENT_FSB_DATA_ACTIVITY),
-		.escr_msr	= { MSR_P4_FSB_ESCR0, MSR_P4_FSB_ESCR1 },
-		.escr_emask	=
-			P4_ESCR_EMASK_BIT(P4_EVENT_FSB_DATA_ACTIVITY, DRDY_DRV)		|
-			P4_ESCR_EMASK_BIT(P4_EVENT_FSB_DATA_ACTIVITY, DRDY_OWN)		|
-			P4_ESCR_EMASK_BIT(P4_EVENT_FSB_DATA_ACTIVITY, DRDY_OTHER)	|
-			P4_ESCR_EMASK_BIT(P4_EVENT_FSB_DATA_ACTIVITY, DBSY_DRV)		|
-			P4_ESCR_EMASK_BIT(P4_EVENT_FSB_DATA_ACTIVITY, DBSY_OWN)		|
-			P4_ESCR_EMASK_BIT(P4_EVENT_FSB_DATA_ACTIVITY, DBSY_OTHER),
-		.shared		= 1,
-		.cntr		= { {0, -1, -1}, {2, -1, -1} },
-	},
-	[P4_EVENT_BSQ_ALLOCATION] = {		/* shared ESCR, broken CCCR1 */
-		.opcode		= P4_OPCODE(P4_EVENT_BSQ_ALLOCATION),
-		.escr_msr	= { MSR_P4_BSU_ESCR0, MSR_P4_BSU_ESCR0 },
-		.escr_emask	=
-			P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ALLOCATION, REQ_TYPE0)		|
-			P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ALLOCATION, REQ_TYPE1)		|
-			P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ALLOCATION, REQ_LEN0)		|
-			P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ALLOCATION, REQ_LEN1)		|
-			P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ALLOCATION, REQ_IO_TYPE)		|
-			P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ALLOCATION, REQ_LOCK_TYPE)	|
-			P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ALLOCATION, REQ_CACHE_TYPE)	|
-			P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ALLOCATION, REQ_SPLIT_TYPE)	|
-			P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ALLOCATION, REQ_DEM_TYPE)	|
-			P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ALLOCATION, REQ_ORD_TYPE)	|
-			P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ALLOCATION, MEM_TYPE0)		|
-			P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ALLOCATION, MEM_TYPE1)		|
-			P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ALLOCATION, MEM_TYPE2),
-		.cntr		= { {0, -1, -1}, {1, -1, -1} },
-	},
-	[P4_EVENT_BSQ_ACTIVE_ENTRIES] = {	/* shared ESCR */
-		.opcode		= P4_OPCODE(P4_EVENT_BSQ_ACTIVE_ENTRIES),
-		.escr_msr	= { MSR_P4_BSU_ESCR1 , MSR_P4_BSU_ESCR1 },
-		.escr_emask	=
-			P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ACTIVE_ENTRIES, REQ_TYPE0)	|
-			P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ACTIVE_ENTRIES, REQ_TYPE1)	|
-			P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ACTIVE_ENTRIES, REQ_LEN0)	|
-			P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ACTIVE_ENTRIES, REQ_LEN1)	|
-			P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ACTIVE_ENTRIES, REQ_IO_TYPE)	|
-			P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ACTIVE_ENTRIES, REQ_LOCK_TYPE)	|
-			P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ACTIVE_ENTRIES, REQ_CACHE_TYPE)	|
-			P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ACTIVE_ENTRIES, REQ_SPLIT_TYPE)	|
-			P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ACTIVE_ENTRIES, REQ_DEM_TYPE)	|
-			P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ACTIVE_ENTRIES, REQ_ORD_TYPE)	|
-			P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ACTIVE_ENTRIES, MEM_TYPE0)	|
-			P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ACTIVE_ENTRIES, MEM_TYPE1)	|
-			P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ACTIVE_ENTRIES, MEM_TYPE2),
-		.cntr		= { {2, -1, -1}, {3, -1, -1} },
-	},
-	[P4_EVENT_SSE_INPUT_ASSIST] = {
-		.opcode		= P4_OPCODE(P4_EVENT_SSE_INPUT_ASSIST),
-		.escr_msr	= { MSR_P4_FIRM_ESCR0, MSR_P4_FIRM_ESCR1 },
-		.escr_emask	=
-			P4_ESCR_EMASK_BIT(P4_EVENT_SSE_INPUT_ASSIST, ALL),
-		.shared		= 1,
-		.cntr		= { {8, 9, -1}, {10, 11, -1} },
-	},
-	[P4_EVENT_PACKED_SP_UOP] = {
-		.opcode		= P4_OPCODE(P4_EVENT_PACKED_SP_UOP),
-		.escr_msr	= { MSR_P4_FIRM_ESCR0, MSR_P4_FIRM_ESCR1 },
-		.escr_emask	=
-			P4_ESCR_EMASK_BIT(P4_EVENT_PACKED_SP_UOP, ALL),
-		.shared		= 1,
-		.cntr		= { {8, 9, -1}, {10, 11, -1} },
-	},
-	[P4_EVENT_PACKED_DP_UOP] = {
-		.opcode		= P4_OPCODE(P4_EVENT_PACKED_DP_UOP),
-		.escr_msr	= { MSR_P4_FIRM_ESCR0, MSR_P4_FIRM_ESCR1 },
-		.escr_emask	=
-			P4_ESCR_EMASK_BIT(P4_EVENT_PACKED_DP_UOP, ALL),
-		.shared		= 1,
-		.cntr		= { {8, 9, -1}, {10, 11, -1} },
-	},
-	[P4_EVENT_SCALAR_SP_UOP] = {
-		.opcode		= P4_OPCODE(P4_EVENT_SCALAR_SP_UOP),
-		.escr_msr	= { MSR_P4_FIRM_ESCR0, MSR_P4_FIRM_ESCR1 },
-		.escr_emask	=
-			P4_ESCR_EMASK_BIT(P4_EVENT_SCALAR_SP_UOP, ALL),
-		.shared		= 1,
-		.cntr		= { {8, 9, -1}, {10, 11, -1} },
-	},
-	[P4_EVENT_SCALAR_DP_UOP] = {
-		.opcode		= P4_OPCODE(P4_EVENT_SCALAR_DP_UOP),
-		.escr_msr	= { MSR_P4_FIRM_ESCR0, MSR_P4_FIRM_ESCR1 },
-		.escr_emask	=
-			P4_ESCR_EMASK_BIT(P4_EVENT_SCALAR_DP_UOP, ALL),
-		.shared		= 1,
-		.cntr		= { {8, 9, -1}, {10, 11, -1} },
-	},
-	[P4_EVENT_64BIT_MMX_UOP] = {
-		.opcode		= P4_OPCODE(P4_EVENT_64BIT_MMX_UOP),
-		.escr_msr	= { MSR_P4_FIRM_ESCR0, MSR_P4_FIRM_ESCR1 },
-		.escr_emask	=
-			P4_ESCR_EMASK_BIT(P4_EVENT_64BIT_MMX_UOP, ALL),
-		.shared		= 1,
-		.cntr		= { {8, 9, -1}, {10, 11, -1} },
-	},
-	[P4_EVENT_128BIT_MMX_UOP] = {
-		.opcode		= P4_OPCODE(P4_EVENT_128BIT_MMX_UOP),
-		.escr_msr	= { MSR_P4_FIRM_ESCR0, MSR_P4_FIRM_ESCR1 },
-		.escr_emask	=
-			P4_ESCR_EMASK_BIT(P4_EVENT_128BIT_MMX_UOP, ALL),
-		.shared		= 1,
-		.cntr		= { {8, 9, -1}, {10, 11, -1} },
-	},
-	[P4_EVENT_X87_FP_UOP] = {
-		.opcode		= P4_OPCODE(P4_EVENT_X87_FP_UOP),
-		.escr_msr	= { MSR_P4_FIRM_ESCR0, MSR_P4_FIRM_ESCR1 },
-		.escr_emask	=
-			P4_ESCR_EMASK_BIT(P4_EVENT_X87_FP_UOP, ALL),
-		.shared		= 1,
-		.cntr		= { {8, 9, -1}, {10, 11, -1} },
-	},
-	[P4_EVENT_TC_MISC] = {
-		.opcode		= P4_OPCODE(P4_EVENT_TC_MISC),
-		.escr_msr	= { MSR_P4_TC_ESCR0, MSR_P4_TC_ESCR1 },
-		.escr_emask	=
-			P4_ESCR_EMASK_BIT(P4_EVENT_TC_MISC, FLUSH),
-		.cntr		= { {4, 5, -1}, {6, 7, -1} },
-	},
-	[P4_EVENT_GLOBAL_POWER_EVENTS] = {
-		.opcode		= P4_OPCODE(P4_EVENT_GLOBAL_POWER_EVENTS),
-		.escr_msr	= { MSR_P4_FSB_ESCR0, MSR_P4_FSB_ESCR1 },
-		.escr_emask	=
-			P4_ESCR_EMASK_BIT(P4_EVENT_GLOBAL_POWER_EVENTS, RUNNING),
-		.cntr		= { {0, -1, -1}, {2, -1, -1} },
-	},
-	[P4_EVENT_TC_MS_XFER] = {
-		.opcode		= P4_OPCODE(P4_EVENT_TC_MS_XFER),
-		.escr_msr	= { MSR_P4_MS_ESCR0, MSR_P4_MS_ESCR1 },
-		.escr_emask	=
-			P4_ESCR_EMASK_BIT(P4_EVENT_TC_MS_XFER, CISC),
-		.cntr		= { {4, 5, -1}, {6, 7, -1} },
-	},
-	[P4_EVENT_UOP_QUEUE_WRITES] = {
-		.opcode		= P4_OPCODE(P4_EVENT_UOP_QUEUE_WRITES),
-		.escr_msr	= { MSR_P4_MS_ESCR0, MSR_P4_MS_ESCR1 },
-		.escr_emask	=
-			P4_ESCR_EMASK_BIT(P4_EVENT_UOP_QUEUE_WRITES, FROM_TC_BUILD)	|
-			P4_ESCR_EMASK_BIT(P4_EVENT_UOP_QUEUE_WRITES, FROM_TC_DELIVER)	|
-			P4_ESCR_EMASK_BIT(P4_EVENT_UOP_QUEUE_WRITES, FROM_ROM),
-		.cntr		= { {4, 5, -1}, {6, 7, -1} },
-	},
-	[P4_EVENT_RETIRED_MISPRED_BRANCH_TYPE] = {
-		.opcode		= P4_OPCODE(P4_EVENT_RETIRED_MISPRED_BRANCH_TYPE),
-		.escr_msr	= { MSR_P4_TBPU_ESCR0 , MSR_P4_TBPU_ESCR0 },
-		.escr_emask	=
-			P4_ESCR_EMASK_BIT(P4_EVENT_RETIRED_MISPRED_BRANCH_TYPE, CONDITIONAL)	|
-			P4_ESCR_EMASK_BIT(P4_EVENT_RETIRED_MISPRED_BRANCH_TYPE, CALL)		|
-			P4_ESCR_EMASK_BIT(P4_EVENT_RETIRED_MISPRED_BRANCH_TYPE, RETURN)		|
-			P4_ESCR_EMASK_BIT(P4_EVENT_RETIRED_MISPRED_BRANCH_TYPE, INDIRECT),
-		.cntr		= { {4, 5, -1}, {6, 7, -1} },
-	},
-	[P4_EVENT_RETIRED_BRANCH_TYPE] = {
-		.opcode		= P4_OPCODE(P4_EVENT_RETIRED_BRANCH_TYPE),
-		.escr_msr	= { MSR_P4_TBPU_ESCR0 , MSR_P4_TBPU_ESCR1 },
-		.escr_emask	=
-			P4_ESCR_EMASK_BIT(P4_EVENT_RETIRED_BRANCH_TYPE, CONDITIONAL)	|
-			P4_ESCR_EMASK_BIT(P4_EVENT_RETIRED_BRANCH_TYPE, CALL)		|
-			P4_ESCR_EMASK_BIT(P4_EVENT_RETIRED_BRANCH_TYPE, RETURN)		|
-			P4_ESCR_EMASK_BIT(P4_EVENT_RETIRED_BRANCH_TYPE, INDIRECT),
-		.cntr		= { {4, 5, -1}, {6, 7, -1} },
-	},
-	[P4_EVENT_RESOURCE_STALL] = {
-		.opcode		= P4_OPCODE(P4_EVENT_RESOURCE_STALL),
-		.escr_msr	= { MSR_P4_ALF_ESCR0, MSR_P4_ALF_ESCR1 },
-		.escr_emask	=
-			P4_ESCR_EMASK_BIT(P4_EVENT_RESOURCE_STALL, SBFULL),
-		.cntr		= { {12, 13, 16}, {14, 15, 17} },
-	},
-	[P4_EVENT_WC_BUFFER] = {
-		.opcode		= P4_OPCODE(P4_EVENT_WC_BUFFER),
-		.escr_msr	= { MSR_P4_DAC_ESCR0, MSR_P4_DAC_ESCR1 },
-		.escr_emask	=
-			P4_ESCR_EMASK_BIT(P4_EVENT_WC_BUFFER, WCB_EVICTS)		|
-			P4_ESCR_EMASK_BIT(P4_EVENT_WC_BUFFER, WCB_FULL_EVICTS),
-		.shared		= 1,
-		.cntr		= { {8, 9, -1}, {10, 11, -1} },
-	},
-	[P4_EVENT_B2B_CYCLES] = {
-		.opcode		= P4_OPCODE(P4_EVENT_B2B_CYCLES),
-		.escr_msr	= { MSR_P4_FSB_ESCR0, MSR_P4_FSB_ESCR1 },
-		.escr_emask	= 0,
-		.cntr		= { {0, -1, -1}, {2, -1, -1} },
-	},
-	[P4_EVENT_BNR] = {
-		.opcode		= P4_OPCODE(P4_EVENT_BNR),
-		.escr_msr	= { MSR_P4_FSB_ESCR0, MSR_P4_FSB_ESCR1 },
-		.escr_emask	= 0,
-		.cntr		= { {0, -1, -1}, {2, -1, -1} },
-	},
-	[P4_EVENT_SNOOP] = {
-		.opcode		= P4_OPCODE(P4_EVENT_SNOOP),
-		.escr_msr	= { MSR_P4_FSB_ESCR0, MSR_P4_FSB_ESCR1 },
-		.escr_emask	= 0,
-		.cntr		= { {0, -1, -1}, {2, -1, -1} },
-	},
-	[P4_EVENT_RESPONSE] = {
-		.opcode		= P4_OPCODE(P4_EVENT_RESPONSE),
-		.escr_msr	= { MSR_P4_FSB_ESCR0, MSR_P4_FSB_ESCR1 },
-		.escr_emask	= 0,
-		.cntr		= { {0, -1, -1}, {2, -1, -1} },
-	},
-	[P4_EVENT_FRONT_END_EVENT] = {
-		.opcode		= P4_OPCODE(P4_EVENT_FRONT_END_EVENT),
-		.escr_msr	= { MSR_P4_CRU_ESCR2, MSR_P4_CRU_ESCR3 },
-		.escr_emask	=
-			P4_ESCR_EMASK_BIT(P4_EVENT_FRONT_END_EVENT, NBOGUS)		|
-			P4_ESCR_EMASK_BIT(P4_EVENT_FRONT_END_EVENT, BOGUS),
-		.cntr		= { {12, 13, 16}, {14, 15, 17} },
-	},
-	[P4_EVENT_EXECUTION_EVENT] = {
-		.opcode		= P4_OPCODE(P4_EVENT_EXECUTION_EVENT),
-		.escr_msr	= { MSR_P4_CRU_ESCR2, MSR_P4_CRU_ESCR3 },
-		.escr_emask	=
-			P4_ESCR_EMASK_BIT(P4_EVENT_EXECUTION_EVENT, NBOGUS0)		|
-			P4_ESCR_EMASK_BIT(P4_EVENT_EXECUTION_EVENT, NBOGUS1)		|
-			P4_ESCR_EMASK_BIT(P4_EVENT_EXECUTION_EVENT, NBOGUS2)		|
-			P4_ESCR_EMASK_BIT(P4_EVENT_EXECUTION_EVENT, NBOGUS3)		|
-			P4_ESCR_EMASK_BIT(P4_EVENT_EXECUTION_EVENT, BOGUS0)		|
-			P4_ESCR_EMASK_BIT(P4_EVENT_EXECUTION_EVENT, BOGUS1)		|
-			P4_ESCR_EMASK_BIT(P4_EVENT_EXECUTION_EVENT, BOGUS2)		|
-			P4_ESCR_EMASK_BIT(P4_EVENT_EXECUTION_EVENT, BOGUS3),
-		.cntr		= { {12, 13, 16}, {14, 15, 17} },
-	},
-	[P4_EVENT_REPLAY_EVENT] = {
-		.opcode		= P4_OPCODE(P4_EVENT_REPLAY_EVENT),
-		.escr_msr	= { MSR_P4_CRU_ESCR2, MSR_P4_CRU_ESCR3 },
-		.escr_emask	=
-			P4_ESCR_EMASK_BIT(P4_EVENT_REPLAY_EVENT, NBOGUS)		|
-			P4_ESCR_EMASK_BIT(P4_EVENT_REPLAY_EVENT, BOGUS),
-		.cntr		= { {12, 13, 16}, {14, 15, 17} },
-	},
-	[P4_EVENT_INSTR_RETIRED] = {
-		.opcode		= P4_OPCODE(P4_EVENT_INSTR_RETIRED),
-		.escr_msr	= { MSR_P4_CRU_ESCR0, MSR_P4_CRU_ESCR1 },
-		.escr_emask	=
-			P4_ESCR_EMASK_BIT(P4_EVENT_INSTR_RETIRED, NBOGUSNTAG)		|
-			P4_ESCR_EMASK_BIT(P4_EVENT_INSTR_RETIRED, NBOGUSTAG)		|
-			P4_ESCR_EMASK_BIT(P4_EVENT_INSTR_RETIRED, BOGUSNTAG)		|
-			P4_ESCR_EMASK_BIT(P4_EVENT_INSTR_RETIRED, BOGUSTAG),
-		.cntr		= { {12, 13, 16}, {14, 15, 17} },
-	},
-	[P4_EVENT_UOPS_RETIRED] = {
-		.opcode		= P4_OPCODE(P4_EVENT_UOPS_RETIRED),
-		.escr_msr	= { MSR_P4_CRU_ESCR0, MSR_P4_CRU_ESCR1 },
-		.escr_emask	=
-			P4_ESCR_EMASK_BIT(P4_EVENT_UOPS_RETIRED, NBOGUS)		|
-			P4_ESCR_EMASK_BIT(P4_EVENT_UOPS_RETIRED, BOGUS),
-		.cntr		= { {12, 13, 16}, {14, 15, 17} },
-	},
-	[P4_EVENT_UOP_TYPE] = {
-		.opcode		= P4_OPCODE(P4_EVENT_UOP_TYPE),
-		.escr_msr	= { MSR_P4_RAT_ESCR0, MSR_P4_RAT_ESCR1 },
-		.escr_emask	=
-			P4_ESCR_EMASK_BIT(P4_EVENT_UOP_TYPE, TAGLOADS)			|
-			P4_ESCR_EMASK_BIT(P4_EVENT_UOP_TYPE, TAGSTORES),
-		.cntr		= { {12, 13, 16}, {14, 15, 17} },
-	},
-	[P4_EVENT_BRANCH_RETIRED] = {
-		.opcode		= P4_OPCODE(P4_EVENT_BRANCH_RETIRED),
-		.escr_msr	= { MSR_P4_CRU_ESCR2, MSR_P4_CRU_ESCR3 },
-		.escr_emask	=
-			P4_ESCR_EMASK_BIT(P4_EVENT_BRANCH_RETIRED, MMNP)		|
-			P4_ESCR_EMASK_BIT(P4_EVENT_BRANCH_RETIRED, MMNM)		|
-			P4_ESCR_EMASK_BIT(P4_EVENT_BRANCH_RETIRED, MMTP)		|
-			P4_ESCR_EMASK_BIT(P4_EVENT_BRANCH_RETIRED, MMTM),
-		.cntr		= { {12, 13, 16}, {14, 15, 17} },
-	},
-	[P4_EVENT_MISPRED_BRANCH_RETIRED] = {
-		.opcode		= P4_OPCODE(P4_EVENT_MISPRED_BRANCH_RETIRED),
-		.escr_msr	= { MSR_P4_CRU_ESCR0, MSR_P4_CRU_ESCR1 },
-		.escr_emask	=
-			P4_ESCR_EMASK_BIT(P4_EVENT_MISPRED_BRANCH_RETIRED, NBOGUS),
-		.cntr		= { {12, 13, 16}, {14, 15, 17} },
-	},
-	[P4_EVENT_X87_ASSIST] = {
-		.opcode		= P4_OPCODE(P4_EVENT_X87_ASSIST),
-		.escr_msr	= { MSR_P4_CRU_ESCR2, MSR_P4_CRU_ESCR3 },
-		.escr_emask	=
-			P4_ESCR_EMASK_BIT(P4_EVENT_X87_ASSIST, FPSU)			|
-			P4_ESCR_EMASK_BIT(P4_EVENT_X87_ASSIST, FPSO)			|
-			P4_ESCR_EMASK_BIT(P4_EVENT_X87_ASSIST, POAO)			|
-			P4_ESCR_EMASK_BIT(P4_EVENT_X87_ASSIST, POAU)			|
-			P4_ESCR_EMASK_BIT(P4_EVENT_X87_ASSIST, PREA),
-		.cntr		= { {12, 13, 16}, {14, 15, 17} },
-	},
-	[P4_EVENT_MACHINE_CLEAR] = {
-		.opcode		= P4_OPCODE(P4_EVENT_MACHINE_CLEAR),
-		.escr_msr	= { MSR_P4_CRU_ESCR2, MSR_P4_CRU_ESCR3 },
-		.escr_emask	=
-			P4_ESCR_EMASK_BIT(P4_EVENT_MACHINE_CLEAR, CLEAR)		|
-			P4_ESCR_EMASK_BIT(P4_EVENT_MACHINE_CLEAR, MOCLEAR)		|
-			P4_ESCR_EMASK_BIT(P4_EVENT_MACHINE_CLEAR, SMCLEAR),
-		.cntr		= { {12, 13, 16}, {14, 15, 17} },
-	},
-	[P4_EVENT_INSTR_COMPLETED] = {
-		.opcode		= P4_OPCODE(P4_EVENT_INSTR_COMPLETED),
-		.escr_msr	= { MSR_P4_CRU_ESCR0, MSR_P4_CRU_ESCR1 },
-		.escr_emask	=
-			P4_ESCR_EMASK_BIT(P4_EVENT_INSTR_COMPLETED, NBOGUS)		|
-			P4_ESCR_EMASK_BIT(P4_EVENT_INSTR_COMPLETED, BOGUS),
-		.cntr		= { {12, 13, 16}, {14, 15, 17} },
-	},
-};
-
-#define P4_GEN_CACHE_EVENT(event, bit, metric)				  \
-	p4_config_pack_escr(P4_ESCR_EVENT(event)			| \
-			    P4_ESCR_EMASK_BIT(event, bit))		| \
-	p4_config_pack_cccr(metric					| \
-			    P4_CCCR_ESEL(P4_OPCODE_ESEL(P4_OPCODE(event))))
-
-static __initconst const u64 p4_hw_cache_event_ids
-				[PERF_COUNT_HW_CACHE_MAX]
-				[PERF_COUNT_HW_CACHE_OP_MAX]
-				[PERF_COUNT_HW_CACHE_RESULT_MAX] =
-{
- [ C(L1D ) ] = {
-	[ C(OP_READ) ] = {
-		[ C(RESULT_ACCESS) ] = 0x0,
-		[ C(RESULT_MISS)   ] = P4_GEN_CACHE_EVENT(P4_EVENT_REPLAY_EVENT, NBOGUS,
-						P4_PEBS_METRIC__1stl_cache_load_miss_retired),
-	},
- },
- [ C(LL  ) ] = {
-	[ C(OP_READ) ] = {
-		[ C(RESULT_ACCESS) ] = 0x0,
-		[ C(RESULT_MISS)   ] = P4_GEN_CACHE_EVENT(P4_EVENT_REPLAY_EVENT, NBOGUS,
-						P4_PEBS_METRIC__2ndl_cache_load_miss_retired),
-	},
-},
- [ C(DTLB) ] = {
-	[ C(OP_READ) ] = {
-		[ C(RESULT_ACCESS) ] = 0x0,
-		[ C(RESULT_MISS)   ] = P4_GEN_CACHE_EVENT(P4_EVENT_REPLAY_EVENT, NBOGUS,
-						P4_PEBS_METRIC__dtlb_load_miss_retired),
-	},
-	[ C(OP_WRITE) ] = {
-		[ C(RESULT_ACCESS) ] = 0x0,
-		[ C(RESULT_MISS)   ] = P4_GEN_CACHE_EVENT(P4_EVENT_REPLAY_EVENT, NBOGUS,
-						P4_PEBS_METRIC__dtlb_store_miss_retired),
-	},
- },
- [ C(ITLB) ] = {
-	[ C(OP_READ) ] = {
-		[ C(RESULT_ACCESS) ] = P4_GEN_CACHE_EVENT(P4_EVENT_ITLB_REFERENCE, HIT,
-						P4_PEBS_METRIC__none),
-		[ C(RESULT_MISS)   ] = P4_GEN_CACHE_EVENT(P4_EVENT_ITLB_REFERENCE, MISS,
-						P4_PEBS_METRIC__none),
-	},
-	[ C(OP_WRITE) ] = {
-		[ C(RESULT_ACCESS) ] = -1,
-		[ C(RESULT_MISS)   ] = -1,
-	},
-	[ C(OP_PREFETCH) ] = {
-		[ C(RESULT_ACCESS) ] = -1,
-		[ C(RESULT_MISS)   ] = -1,
-	},
- },
- [ C(NODE) ] = {
-	[ C(OP_READ) ] = {
-		[ C(RESULT_ACCESS) ] = -1,
-		[ C(RESULT_MISS)   ] = -1,
-	},
-	[ C(OP_WRITE) ] = {
-		[ C(RESULT_ACCESS) ] = -1,
-		[ C(RESULT_MISS)   ] = -1,
-	},
-	[ C(OP_PREFETCH) ] = {
-		[ C(RESULT_ACCESS) ] = -1,
-		[ C(RESULT_MISS)   ] = -1,
-	},
- },
-};
-
-/*
- * Because of Netburst being quite restricted in how many
- * identical events may run simultaneously, we introduce event aliases,
- * ie the different events which have the same functionality but
- * utilize non-intersected resources (ESCR/CCCR/counter registers).
- *
- * This allow us to relax restrictions a bit and run two or more
- * identical events together.
- *
- * Never set any custom internal bits such as P4_CONFIG_HT,
- * P4_CONFIG_ALIASABLE or bits for P4_PEBS_METRIC, they are
- * either up to date automatically or not applicable at all.
- */
-struct p4_event_alias {
-	u64 original;
-	u64 alternative;
-} p4_event_aliases[] = {
-	{
-		/*
-		 * Non-halted cycles can be substituted with non-sleeping cycles (see
-		 * Intel SDM Vol3b for details). We need this alias to be able
-		 * to run nmi-watchdog and 'perf top' (or any other user space tool
-		 * which is interested in running PERF_COUNT_HW_CPU_CYCLES)
-		 * simultaneously.
-		 */
-	.original	=
-		p4_config_pack_escr(P4_ESCR_EVENT(P4_EVENT_GLOBAL_POWER_EVENTS)		|
-				    P4_ESCR_EMASK_BIT(P4_EVENT_GLOBAL_POWER_EVENTS, RUNNING)),
-	.alternative	=
-		p4_config_pack_escr(P4_ESCR_EVENT(P4_EVENT_EXECUTION_EVENT)		|
-				    P4_ESCR_EMASK_BIT(P4_EVENT_EXECUTION_EVENT, NBOGUS0)|
-				    P4_ESCR_EMASK_BIT(P4_EVENT_EXECUTION_EVENT, NBOGUS1)|
-				    P4_ESCR_EMASK_BIT(P4_EVENT_EXECUTION_EVENT, NBOGUS2)|
-				    P4_ESCR_EMASK_BIT(P4_EVENT_EXECUTION_EVENT, NBOGUS3)|
-				    P4_ESCR_EMASK_BIT(P4_EVENT_EXECUTION_EVENT, BOGUS0)	|
-				    P4_ESCR_EMASK_BIT(P4_EVENT_EXECUTION_EVENT, BOGUS1)	|
-				    P4_ESCR_EMASK_BIT(P4_EVENT_EXECUTION_EVENT, BOGUS2)	|
-				    P4_ESCR_EMASK_BIT(P4_EVENT_EXECUTION_EVENT, BOGUS3))|
-		p4_config_pack_cccr(P4_CCCR_THRESHOLD(15) | P4_CCCR_COMPLEMENT		|
-				    P4_CCCR_COMPARE),
-	},
-};
-
-static u64 p4_get_alias_event(u64 config)
-{
-	u64 config_match;
-	int i;
-
-	/*
-	 * Only event with special mark is allowed,
-	 * we're to be sure it didn't come as malformed
-	 * RAW event.
-	 */
-	if (!(config & P4_CONFIG_ALIASABLE))
-		return 0;
-
-	config_match = config & P4_CONFIG_EVENT_ALIAS_MASK;
-
-	for (i = 0; i < ARRAY_SIZE(p4_event_aliases); i++) {
-		if (config_match == p4_event_aliases[i].original) {
-			config_match = p4_event_aliases[i].alternative;
-			break;
-		} else if (config_match == p4_event_aliases[i].alternative) {
-			config_match = p4_event_aliases[i].original;
-			break;
-		}
-	}
-
-	if (i >= ARRAY_SIZE(p4_event_aliases))
-		return 0;
-
-	return config_match | (config & P4_CONFIG_EVENT_ALIAS_IMMUTABLE_BITS);
-}
-
-static u64 p4_general_events[PERF_COUNT_HW_MAX] = {
-  /* non-halted CPU clocks */
-  [PERF_COUNT_HW_CPU_CYCLES] =
-	p4_config_pack_escr(P4_ESCR_EVENT(P4_EVENT_GLOBAL_POWER_EVENTS)		|
-		P4_ESCR_EMASK_BIT(P4_EVENT_GLOBAL_POWER_EVENTS, RUNNING))	|
-		P4_CONFIG_ALIASABLE,
-
-  /*
-   * retired instructions
-   * in a sake of simplicity we don't use the FSB tagging
-   */
-  [PERF_COUNT_HW_INSTRUCTIONS] =
-	p4_config_pack_escr(P4_ESCR_EVENT(P4_EVENT_INSTR_RETIRED)		|
-		P4_ESCR_EMASK_BIT(P4_EVENT_INSTR_RETIRED, NBOGUSNTAG)		|
-		P4_ESCR_EMASK_BIT(P4_EVENT_INSTR_RETIRED, BOGUSNTAG)),
-
-  /* cache hits */
-  [PERF_COUNT_HW_CACHE_REFERENCES] =
-	p4_config_pack_escr(P4_ESCR_EVENT(P4_EVENT_BSQ_CACHE_REFERENCE)		|
-		P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_CACHE_REFERENCE, RD_2ndL_HITS)	|
-		P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_CACHE_REFERENCE, RD_2ndL_HITE)	|
-		P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_CACHE_REFERENCE, RD_2ndL_HITM)	|
-		P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_CACHE_REFERENCE, RD_3rdL_HITS)	|
-		P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_CACHE_REFERENCE, RD_3rdL_HITE)	|
-		P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_CACHE_REFERENCE, RD_3rdL_HITM)),
-
-  /* cache misses */
-  [PERF_COUNT_HW_CACHE_MISSES] =
-	p4_config_pack_escr(P4_ESCR_EVENT(P4_EVENT_BSQ_CACHE_REFERENCE)		|
-		P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_CACHE_REFERENCE, RD_2ndL_MISS)	|
-		P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_CACHE_REFERENCE, RD_3rdL_MISS)	|
-		P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_CACHE_REFERENCE, WR_2ndL_MISS)),
-
-  /* branch instructions retired */
-  [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] =
-	p4_config_pack_escr(P4_ESCR_EVENT(P4_EVENT_RETIRED_BRANCH_TYPE)		|
-		P4_ESCR_EMASK_BIT(P4_EVENT_RETIRED_BRANCH_TYPE, CONDITIONAL)	|
-		P4_ESCR_EMASK_BIT(P4_EVENT_RETIRED_BRANCH_TYPE, CALL)		|
-		P4_ESCR_EMASK_BIT(P4_EVENT_RETIRED_BRANCH_TYPE, RETURN)		|
-		P4_ESCR_EMASK_BIT(P4_EVENT_RETIRED_BRANCH_TYPE, INDIRECT)),
-
-  /* mispredicted branches retired */
-  [PERF_COUNT_HW_BRANCH_MISSES]	=
-	p4_config_pack_escr(P4_ESCR_EVENT(P4_EVENT_MISPRED_BRANCH_RETIRED)	|
-		P4_ESCR_EMASK_BIT(P4_EVENT_MISPRED_BRANCH_RETIRED, NBOGUS)),
-
-  /* bus ready clocks (cpu is driving #DRDY_DRV\#DRDY_OWN):  */
-  [PERF_COUNT_HW_BUS_CYCLES] =
-	p4_config_pack_escr(P4_ESCR_EVENT(P4_EVENT_FSB_DATA_ACTIVITY)		|
-		P4_ESCR_EMASK_BIT(P4_EVENT_FSB_DATA_ACTIVITY, DRDY_DRV)		|
-		P4_ESCR_EMASK_BIT(P4_EVENT_FSB_DATA_ACTIVITY, DRDY_OWN))	|
-	p4_config_pack_cccr(P4_CCCR_EDGE | P4_CCCR_COMPARE),
-};
-
-static struct p4_event_bind *p4_config_get_bind(u64 config)
-{
-	unsigned int evnt = p4_config_unpack_event(config);
-	struct p4_event_bind *bind = NULL;
-
-	if (evnt < ARRAY_SIZE(p4_event_bind_map))
-		bind = &p4_event_bind_map[evnt];
-
-	return bind;
-}
-
-static u64 p4_pmu_event_map(int hw_event)
-{
-	struct p4_event_bind *bind;
-	unsigned int esel;
-	u64 config;
-
-	config = p4_general_events[hw_event];
-	bind = p4_config_get_bind(config);
-	esel = P4_OPCODE_ESEL(bind->opcode);
-	config |= p4_config_pack_cccr(P4_CCCR_ESEL(esel));
-
-	return config;
-}
-
-/* check cpu model specifics */
-static bool p4_event_match_cpu_model(unsigned int event_idx)
-{
-	/* INSTR_COMPLETED event only exist for model 3, 4, 6 (Prescott) */
-	if (event_idx == P4_EVENT_INSTR_COMPLETED) {
-		if (boot_cpu_data.x86_model != 3 &&
-			boot_cpu_data.x86_model != 4 &&
-			boot_cpu_data.x86_model != 6)
-			return false;
-	}
-
-	/*
-	 * For info
-	 * - IQ_ESCR0, IQ_ESCR1 only for models 1 and 2
-	 */
-
-	return true;
-}
-
-static int p4_validate_raw_event(struct perf_event *event)
-{
-	unsigned int v, emask;
-
-	/* User data may have out-of-bound event index */
-	v = p4_config_unpack_event(event->attr.config);
-	if (v >= ARRAY_SIZE(p4_event_bind_map))
-		return -EINVAL;
-
-	/* It may be unsupported: */
-	if (!p4_event_match_cpu_model(v))
-		return -EINVAL;
-
-	/*
-	 * NOTE: P4_CCCR_THREAD_ANY has not the same meaning as
-	 * in Architectural Performance Monitoring, it means not
-	 * on _which_ logical cpu to count but rather _when_, ie it
-	 * depends on logical cpu state -- count event if one cpu active,
-	 * none, both or any, so we just allow user to pass any value
-	 * desired.
-	 *
-	 * In turn we always set Tx_OS/Tx_USR bits bound to logical
-	 * cpu without their propagation to another cpu
-	 */
-
-	/*
-	 * if an event is shared across the logical threads
-	 * the user needs special permissions to be able to use it
-	 */
-	if (p4_ht_active() && p4_event_bind_map[v].shared) {
-		if (perf_paranoid_cpu() && !capable(CAP_SYS_ADMIN))
-			return -EACCES;
-	}
-
-	/* ESCR EventMask bits may be invalid */
-	emask = p4_config_unpack_escr(event->attr.config) & P4_ESCR_EVENTMASK_MASK;
-	if (emask & ~p4_event_bind_map[v].escr_emask)
-		return -EINVAL;
-
-	/*
-	 * it may have some invalid PEBS bits
-	 */
-	if (p4_config_pebs_has(event->attr.config, P4_PEBS_CONFIG_ENABLE))
-		return -EINVAL;
-
-	v = p4_config_unpack_metric(event->attr.config);
-	if (v >= ARRAY_SIZE(p4_pebs_bind_map))
-		return -EINVAL;
-
-	return 0;
-}
-
-static int p4_hw_config(struct perf_event *event)
-{
-	int cpu = get_cpu();
-	int rc = 0;
-	u32 escr, cccr;
-
-	/*
-	 * the reason we use cpu that early is that: if we get scheduled
-	 * first time on the same cpu -- we will not need swap thread
-	 * specific flags in config (and will save some cpu cycles)
-	 */
-
-	cccr = p4_default_cccr_conf(cpu);
-	escr = p4_default_escr_conf(cpu, event->attr.exclude_kernel,
-					 event->attr.exclude_user);
-	event->hw.config = p4_config_pack_escr(escr) |
-			   p4_config_pack_cccr(cccr);
-
-	if (p4_ht_active() && p4_ht_thread(cpu))
-		event->hw.config = p4_set_ht_bit(event->hw.config);
-
-	if (event->attr.type == PERF_TYPE_RAW) {
-		struct p4_event_bind *bind;
-		unsigned int esel;
-		/*
-		 * Clear bits we reserve to be managed by kernel itself
-		 * and never allowed from a user space
-		 */
-		 event->attr.config &= P4_CONFIG_MASK;
-
-		rc = p4_validate_raw_event(event);
-		if (rc)
-			goto out;
-
-		/*
-		 * Note that for RAW events we allow user to use P4_CCCR_RESERVED
-		 * bits since we keep additional info here (for cache events and etc)
-		 */
-		event->hw.config |= event->attr.config;
-		bind = p4_config_get_bind(event->attr.config);
-		if (!bind) {
-			rc = -EINVAL;
-			goto out;
-		}
-		esel = P4_OPCODE_ESEL(bind->opcode);
-		event->hw.config |= p4_config_pack_cccr(P4_CCCR_ESEL(esel));
-	}
-
-	rc = x86_setup_perfctr(event);
-out:
-	put_cpu();
-	return rc;
-}
-
-static inline int p4_pmu_clear_cccr_ovf(struct hw_perf_event *hwc)
-{
-	u64 v;
-
-	/* an official way for overflow indication */
-	rdmsrl(hwc->config_base, v);
-	if (v & P4_CCCR_OVF) {
-		wrmsrl(hwc->config_base, v & ~P4_CCCR_OVF);
-		return 1;
-	}
-
-	/*
-	 * In some circumstances the overflow might issue an NMI but did
-	 * not set P4_CCCR_OVF bit. Because a counter holds a negative value
-	 * we simply check for high bit being set, if it's cleared it means
-	 * the counter has reached zero value and continued counting before
-	 * real NMI signal was received:
-	 */
-	rdmsrl(hwc->event_base, v);
-	if (!(v & ARCH_P4_UNFLAGGED_BIT))
-		return 1;
-
-	return 0;
-}
-
-static void p4_pmu_disable_pebs(void)
-{
-	/*
-	 * FIXME
-	 *
-	 * It's still allowed that two threads setup same cache
-	 * events so we can't simply clear metrics until we knew
-	 * no one is depending on us, so we need kind of counter
-	 * for "ReplayEvent" users.
-	 *
-	 * What is more complex -- RAW events, if user (for some
-	 * reason) will pass some cache event metric with improper
-	 * event opcode -- it's fine from hardware point of view
-	 * but completely nonsense from "meaning" of such action.
-	 *
-	 * So at moment let leave metrics turned on forever -- it's
-	 * ok for now but need to be revisited!
-	 *
-	 * (void)wrmsrl_safe(MSR_IA32_PEBS_ENABLE, 0);
-	 * (void)wrmsrl_safe(MSR_P4_PEBS_MATRIX_VERT, 0);
-	 */
-}
-
-static inline void p4_pmu_disable_event(struct perf_event *event)
-{
-	struct hw_perf_event *hwc = &event->hw;
-
-	/*
-	 * If event gets disabled while counter is in overflowed
-	 * state we need to clear P4_CCCR_OVF, otherwise interrupt get
-	 * asserted again and again
-	 */
-	(void)wrmsrl_safe(hwc->config_base,
-		p4_config_unpack_cccr(hwc->config) & ~P4_CCCR_ENABLE & ~P4_CCCR_OVF & ~P4_CCCR_RESERVED);
-}
-
-static void p4_pmu_disable_all(void)
-{
-	struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
-	int idx;
-
-	for (idx = 0; idx < x86_pmu.num_counters; idx++) {
-		struct perf_event *event = cpuc->events[idx];
-		if (!test_bit(idx, cpuc->active_mask))
-			continue;
-		p4_pmu_disable_event(event);
-	}
-
-	p4_pmu_disable_pebs();
-}
-
-/* configuration must be valid */
-static void p4_pmu_enable_pebs(u64 config)
-{
-	struct p4_pebs_bind *bind;
-	unsigned int idx;
-
-	BUILD_BUG_ON(P4_PEBS_METRIC__max > P4_PEBS_CONFIG_METRIC_MASK);
-
-	idx = p4_config_unpack_metric(config);
-	if (idx == P4_PEBS_METRIC__none)
-		return;
-
-	bind = &p4_pebs_bind_map[idx];
-
-	(void)wrmsrl_safe(MSR_IA32_PEBS_ENABLE,	(u64)bind->metric_pebs);
-	(void)wrmsrl_safe(MSR_P4_PEBS_MATRIX_VERT,	(u64)bind->metric_vert);
-}
-
-static void p4_pmu_enable_event(struct perf_event *event)
-{
-	struct hw_perf_event *hwc = &event->hw;
-	int thread = p4_ht_config_thread(hwc->config);
-	u64 escr_conf = p4_config_unpack_escr(p4_clear_ht_bit(hwc->config));
-	unsigned int idx = p4_config_unpack_event(hwc->config);
-	struct p4_event_bind *bind;
-	u64 escr_addr, cccr;
-
-	bind = &p4_event_bind_map[idx];
-	escr_addr = bind->escr_msr[thread];
-
-	/*
-	 * - we dont support cascaded counters yet
-	 * - and counter 1 is broken (erratum)
-	 */
-	WARN_ON_ONCE(p4_is_event_cascaded(hwc->config));
-	WARN_ON_ONCE(hwc->idx == 1);
-
-	/* we need a real Event value */
-	escr_conf &= ~P4_ESCR_EVENT_MASK;
-	escr_conf |= P4_ESCR_EVENT(P4_OPCODE_EVNT(bind->opcode));
-
-	cccr = p4_config_unpack_cccr(hwc->config);
-
-	/*
-	 * it could be Cache event so we need to write metrics
-	 * into additional MSRs
-	 */
-	p4_pmu_enable_pebs(hwc->config);
-
-	(void)wrmsrl_safe(escr_addr, escr_conf);
-	(void)wrmsrl_safe(hwc->config_base,
-				(cccr & ~P4_CCCR_RESERVED) | P4_CCCR_ENABLE);
-}
-
-static void p4_pmu_enable_all(int added)
-{
-	struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
-	int idx;
-
-	for (idx = 0; idx < x86_pmu.num_counters; idx++) {
-		struct perf_event *event = cpuc->events[idx];
-		if (!test_bit(idx, cpuc->active_mask))
-			continue;
-		p4_pmu_enable_event(event);
-	}
-}
-
-static int p4_pmu_handle_irq(struct pt_regs *regs)
-{
-	struct perf_sample_data data;
-	struct cpu_hw_events *cpuc;
-	struct perf_event *event;
-	struct hw_perf_event *hwc;
-	int idx, handled = 0;
-	u64 val;
-
-	cpuc = this_cpu_ptr(&cpu_hw_events);
-
-	for (idx = 0; idx < x86_pmu.num_counters; idx++) {
-		int overflow;
-
-		if (!test_bit(idx, cpuc->active_mask)) {
-			/* catch in-flight IRQs */
-			if (__test_and_clear_bit(idx, cpuc->running))
-				handled++;
-			continue;
-		}
-
-		event = cpuc->events[idx];
-		hwc = &event->hw;
-
-		WARN_ON_ONCE(hwc->idx != idx);
-
-		/* it might be unflagged overflow */
-		overflow = p4_pmu_clear_cccr_ovf(hwc);
-
-		val = x86_perf_event_update(event);
-		if (!overflow && (val & (1ULL << (x86_pmu.cntval_bits - 1))))
-			continue;
-
-		handled += overflow;
-
-		/* event overflow for sure */
-		perf_sample_data_init(&data, 0, hwc->last_period);
-
-		if (!x86_perf_event_set_period(event))
-			continue;
-
-
-		if (perf_event_overflow(event, &data, regs))
-			x86_pmu_stop(event, 0);
-	}
-
-	if (handled)
-		inc_irq_stat(apic_perf_irqs);
-
-	/*
-	 * When dealing with the unmasking of the LVTPC on P4 perf hw, it has
-	 * been observed that the OVF bit flag has to be cleared first _before_
-	 * the LVTPC can be unmasked.
-	 *
-	 * The reason is the NMI line will continue to be asserted while the OVF
-	 * bit is set.  This causes a second NMI to generate if the LVTPC is
-	 * unmasked before the OVF bit is cleared, leading to unknown NMI
-	 * messages.
-	 */
-	apic_write(APIC_LVTPC, APIC_DM_NMI);
-
-	return handled;
-}
-
-/*
- * swap thread specific fields according to a thread
- * we are going to run on
- */
-static void p4_pmu_swap_config_ts(struct hw_perf_event *hwc, int cpu)
-{
-	u32 escr, cccr;
-
-	/*
-	 * we either lucky and continue on same cpu or no HT support
-	 */
-	if (!p4_should_swap_ts(hwc->config, cpu))
-		return;
-
-	/*
-	 * the event is migrated from an another logical
-	 * cpu, so we need to swap thread specific flags
-	 */
-
-	escr = p4_config_unpack_escr(hwc->config);
-	cccr = p4_config_unpack_cccr(hwc->config);
-
-	if (p4_ht_thread(cpu)) {
-		cccr &= ~P4_CCCR_OVF_PMI_T0;
-		cccr |= P4_CCCR_OVF_PMI_T1;
-		if (escr & P4_ESCR_T0_OS) {
-			escr &= ~P4_ESCR_T0_OS;
-			escr |= P4_ESCR_T1_OS;
-		}
-		if (escr & P4_ESCR_T0_USR) {
-			escr &= ~P4_ESCR_T0_USR;
-			escr |= P4_ESCR_T1_USR;
-		}
-		hwc->config  = p4_config_pack_escr(escr);
-		hwc->config |= p4_config_pack_cccr(cccr);
-		hwc->config |= P4_CONFIG_HT;
-	} else {
-		cccr &= ~P4_CCCR_OVF_PMI_T1;
-		cccr |= P4_CCCR_OVF_PMI_T0;
-		if (escr & P4_ESCR_T1_OS) {
-			escr &= ~P4_ESCR_T1_OS;
-			escr |= P4_ESCR_T0_OS;
-		}
-		if (escr & P4_ESCR_T1_USR) {
-			escr &= ~P4_ESCR_T1_USR;
-			escr |= P4_ESCR_T0_USR;
-		}
-		hwc->config  = p4_config_pack_escr(escr);
-		hwc->config |= p4_config_pack_cccr(cccr);
-		hwc->config &= ~P4_CONFIG_HT;
-	}
-}
-
-/*
- * ESCR address hashing is tricky, ESCRs are not sequential
- * in memory but all starts from MSR_P4_BSU_ESCR0 (0x03a0) and
- * the metric between any ESCRs is laid in range [0xa0,0xe1]
- *
- * so we make ~70% filled hashtable
- */
-
-#define P4_ESCR_MSR_BASE		0x000003a0
-#define P4_ESCR_MSR_MAX			0x000003e1
-#define P4_ESCR_MSR_TABLE_SIZE		(P4_ESCR_MSR_MAX - P4_ESCR_MSR_BASE + 1)
-#define P4_ESCR_MSR_IDX(msr)		(msr - P4_ESCR_MSR_BASE)
-#define P4_ESCR_MSR_TABLE_ENTRY(msr)	[P4_ESCR_MSR_IDX(msr)] = msr
-
-static const unsigned int p4_escr_table[P4_ESCR_MSR_TABLE_SIZE] = {
-	P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_ALF_ESCR0),
-	P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_ALF_ESCR1),
-	P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_BPU_ESCR0),
-	P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_BPU_ESCR1),
-	P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_BSU_ESCR0),
-	P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_BSU_ESCR1),
-	P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_CRU_ESCR0),
-	P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_CRU_ESCR1),
-	P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_CRU_ESCR2),
-	P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_CRU_ESCR3),
-	P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_CRU_ESCR4),
-	P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_CRU_ESCR5),
-	P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_DAC_ESCR0),
-	P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_DAC_ESCR1),
-	P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_FIRM_ESCR0),
-	P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_FIRM_ESCR1),
-	P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_FLAME_ESCR0),
-	P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_FLAME_ESCR1),
-	P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_FSB_ESCR0),
-	P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_FSB_ESCR1),
-	P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_IQ_ESCR0),
-	P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_IQ_ESCR1),
-	P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_IS_ESCR0),
-	P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_IS_ESCR1),
-	P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_ITLB_ESCR0),
-	P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_ITLB_ESCR1),
-	P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_IX_ESCR0),
-	P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_IX_ESCR1),
-	P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_MOB_ESCR0),
-	P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_MOB_ESCR1),
-	P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_MS_ESCR0),
-	P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_MS_ESCR1),
-	P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_PMH_ESCR0),
-	P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_PMH_ESCR1),
-	P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_RAT_ESCR0),
-	P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_RAT_ESCR1),
-	P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_SAAT_ESCR0),
-	P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_SAAT_ESCR1),
-	P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_SSU_ESCR0),
-	P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_SSU_ESCR1),
-	P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_TBPU_ESCR0),
-	P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_TBPU_ESCR1),
-	P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_TC_ESCR0),
-	P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_TC_ESCR1),
-	P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_U2L_ESCR0),
-	P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_U2L_ESCR1),
-};
-
-static int p4_get_escr_idx(unsigned int addr)
-{
-	unsigned int idx = P4_ESCR_MSR_IDX(addr);
-
-	if (unlikely(idx >= P4_ESCR_MSR_TABLE_SIZE	||
-			!p4_escr_table[idx]		||
-			p4_escr_table[idx] != addr)) {
-		WARN_ONCE(1, "P4 PMU: Wrong address passed: %x\n", addr);
-		return -1;
-	}
-
-	return idx;
-}
-
-static int p4_next_cntr(int thread, unsigned long *used_mask,
-			struct p4_event_bind *bind)
-{
-	int i, j;
-
-	for (i = 0; i < P4_CNTR_LIMIT; i++) {
-		j = bind->cntr[thread][i];
-		if (j != -1 && !test_bit(j, used_mask))
-			return j;
-	}
-
-	return -1;
-}
-
-static int p4_pmu_schedule_events(struct cpu_hw_events *cpuc, int n, int *assign)
-{
-	unsigned long used_mask[BITS_TO_LONGS(X86_PMC_IDX_MAX)];
-	unsigned long escr_mask[BITS_TO_LONGS(P4_ESCR_MSR_TABLE_SIZE)];
-	int cpu = smp_processor_id();
-	struct hw_perf_event *hwc;
-	struct p4_event_bind *bind;
-	unsigned int i, thread, num;
-	int cntr_idx, escr_idx;
-	u64 config_alias;
-	int pass;
-
-	bitmap_zero(used_mask, X86_PMC_IDX_MAX);
-	bitmap_zero(escr_mask, P4_ESCR_MSR_TABLE_SIZE);
-
-	for (i = 0, num = n; i < n; i++, num--) {
-
-		hwc = &cpuc->event_list[i]->hw;
-		thread = p4_ht_thread(cpu);
-		pass = 0;
-
-again:
-		/*
-		 * It's possible to hit a circular lock
-		 * between original and alternative events
-		 * if both are scheduled already.
-		 */
-		if (pass > 2)
-			goto done;
-
-		bind = p4_config_get_bind(hwc->config);
-		escr_idx = p4_get_escr_idx(bind->escr_msr[thread]);
-		if (unlikely(escr_idx == -1))
-			goto done;
-
-		if (hwc->idx != -1 && !p4_should_swap_ts(hwc->config, cpu)) {
-			cntr_idx = hwc->idx;
-			if (assign)
-				assign[i] = hwc->idx;
-			goto reserve;
-		}
-
-		cntr_idx = p4_next_cntr(thread, used_mask, bind);
-		if (cntr_idx == -1 || test_bit(escr_idx, escr_mask)) {
-			/*
-			 * Check whether an event alias is still available.
-			 */
-			config_alias = p4_get_alias_event(hwc->config);
-			if (!config_alias)
-				goto done;
-			hwc->config = config_alias;
-			pass++;
-			goto again;
-		}
-		/*
-		 * Perf does test runs to see if a whole group can be assigned
-		 * together succesfully.  There can be multiple rounds of this.
-		 * Unfortunately, p4_pmu_swap_config_ts touches the hwc->config
-		 * bits, such that the next round of group assignments will
-		 * cause the above p4_should_swap_ts to pass instead of fail.
-		 * This leads to counters exclusive to thread0 being used by
-		 * thread1.
-		 *
-		 * Solve this with a cheap hack, reset the idx back to -1 to
-		 * force a new lookup (p4_next_cntr) to get the right counter
-		 * for the right thread.
-		 *
-		 * This probably doesn't comply with the general spirit of how
-		 * perf wants to work, but P4 is special. :-(
-		 */
-		if (p4_should_swap_ts(hwc->config, cpu))
-			hwc->idx = -1;
-		p4_pmu_swap_config_ts(hwc, cpu);
-		if (assign)
-			assign[i] = cntr_idx;
-reserve:
-		set_bit(cntr_idx, used_mask);
-		set_bit(escr_idx, escr_mask);
-	}
-
-done:
-	return num ? -EINVAL : 0;
-}
-
-PMU_FORMAT_ATTR(cccr, "config:0-31" );
-PMU_FORMAT_ATTR(escr, "config:32-62");
-PMU_FORMAT_ATTR(ht,   "config:63"   );
-
-static struct attribute *intel_p4_formats_attr[] = {
-	&format_attr_cccr.attr,
-	&format_attr_escr.attr,
-	&format_attr_ht.attr,
-	NULL,
-};
-
-static __initconst const struct x86_pmu p4_pmu = {
-	.name			= "Netburst P4/Xeon",
-	.handle_irq		= p4_pmu_handle_irq,
-	.disable_all		= p4_pmu_disable_all,
-	.enable_all		= p4_pmu_enable_all,
-	.enable			= p4_pmu_enable_event,
-	.disable		= p4_pmu_disable_event,
-	.eventsel		= MSR_P4_BPU_CCCR0,
-	.perfctr		= MSR_P4_BPU_PERFCTR0,
-	.event_map		= p4_pmu_event_map,
-	.max_events		= ARRAY_SIZE(p4_general_events),
-	.get_event_constraints	= x86_get_event_constraints,
-	/*
-	 * IF HT disabled we may need to use all
-	 * ARCH_P4_MAX_CCCR counters simulaneously
-	 * though leave it restricted at moment assuming
-	 * HT is on
-	 */
-	.num_counters		= ARCH_P4_MAX_CCCR,
-	.apic			= 1,
-	.cntval_bits		= ARCH_P4_CNTRVAL_BITS,
-	.cntval_mask		= ARCH_P4_CNTRVAL_MASK,
-	.max_period		= (1ULL << (ARCH_P4_CNTRVAL_BITS - 1)) - 1,
-	.hw_config		= p4_hw_config,
-	.schedule_events	= p4_pmu_schedule_events,
-	/*
-	 * This handles erratum N15 in intel doc 249199-029,
-	 * the counter may not be updated correctly on write
-	 * so we need a second write operation to do the trick
-	 * (the official workaround didn't work)
-	 *
-	 * the former idea is taken from OProfile code
-	 */
-	.perfctr_second_write	= 1,
-
-	.format_attrs		= intel_p4_formats_attr,
-};
-
-__init int p4_pmu_init(void)
-{
-	unsigned int low, high;
-	int i, reg;
-
-	/* If we get stripped -- indexing fails */
-	BUILD_BUG_ON(ARCH_P4_MAX_CCCR > INTEL_PMC_MAX_GENERIC);
-
-	rdmsr(MSR_IA32_MISC_ENABLE, low, high);
-	if (!(low & (1 << 7))) {
-		pr_cont("unsupported Netburst CPU model %d ",
-			boot_cpu_data.x86_model);
-		return -ENODEV;
-	}
-
-	memcpy(hw_cache_event_ids, p4_hw_cache_event_ids,
-		sizeof(hw_cache_event_ids));
-
-	pr_cont("Netburst events, ");
-
-	x86_pmu = p4_pmu;
-
-	/*
-	 * Even though the counters are configured to interrupt a particular
-	 * logical processor when an overflow happens, testing has shown that
-	 * on kdump kernels (which uses a single cpu), thread1's counter
-	 * continues to run and will report an NMI on thread0.  Due to the
-	 * overflow bug, this leads to a stream of unknown NMIs.
-	 *
-	 * Solve this by zero'ing out the registers to mimic a reset.
-	 */
-	for (i = 0; i < x86_pmu.num_counters; i++) {
-		reg = x86_pmu_config_addr(i);
-		wrmsrl_safe(reg, 0ULL);
-	}
-
-	return 0;
-}
--- zfcpdump-kernel-4.4.orig/arch/x86/kernel/cpu/perf_event_p6.c
+++ /dev/null
@@ -1,279 +0,0 @@
-#include <linux/perf_event.h>
-#include <linux/types.h>
-
-#include "perf_event.h"
-
-/*
- * Not sure about some of these
- */
-static const u64 p6_perfmon_event_map[] =
-{
-  [PERF_COUNT_HW_CPU_CYCLES]		= 0x0079,	/* CPU_CLK_UNHALTED */
-  [PERF_COUNT_HW_INSTRUCTIONS]		= 0x00c0,	/* INST_RETIRED     */
-  [PERF_COUNT_HW_CACHE_REFERENCES]	= 0x0f2e,	/* L2_RQSTS:M:E:S:I */
-  [PERF_COUNT_HW_CACHE_MISSES]		= 0x012e,	/* L2_RQSTS:I       */
-  [PERF_COUNT_HW_BRANCH_INSTRUCTIONS]	= 0x00c4,	/* BR_INST_RETIRED  */
-  [PERF_COUNT_HW_BRANCH_MISSES]		= 0x00c5,	/* BR_MISS_PRED_RETIRED */
-  [PERF_COUNT_HW_BUS_CYCLES]		= 0x0062,	/* BUS_DRDY_CLOCKS  */
-  [PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = 0x00a2,	/* RESOURCE_STALLS  */
-
-};
-
-static const u64 __initconst p6_hw_cache_event_ids
-				[PERF_COUNT_HW_CACHE_MAX]
-				[PERF_COUNT_HW_CACHE_OP_MAX]
-				[PERF_COUNT_HW_CACHE_RESULT_MAX] =
-{
- [ C(L1D) ] = {
-	[ C(OP_READ) ] = {
-		[ C(RESULT_ACCESS) ] = 0x0043,	/* DATA_MEM_REFS       */
-                [ C(RESULT_MISS)   ] = 0x0045,	/* DCU_LINES_IN        */
-	},
-	[ C(OP_WRITE) ] = {
-		[ C(RESULT_ACCESS) ] = 0,
-		[ C(RESULT_MISS)   ] = 0x0f29,	/* L2_LD:M:E:S:I       */
-	},
-        [ C(OP_PREFETCH) ] = {
-		[ C(RESULT_ACCESS) ] = 0,
-		[ C(RESULT_MISS)   ] = 0,
-        },
- },
- [ C(L1I ) ] = {
-	[ C(OP_READ) ] = {
-		[ C(RESULT_ACCESS) ] = 0x0080,	/* IFU_IFETCH         */
-		[ C(RESULT_MISS)   ] = 0x0f28,	/* L2_IFETCH:M:E:S:I  */
-	},
-	[ C(OP_WRITE) ] = {
-		[ C(RESULT_ACCESS) ] = -1,
-		[ C(RESULT_MISS)   ] = -1,
-	},
-	[ C(OP_PREFETCH) ] = {
-		[ C(RESULT_ACCESS) ] = 0,
-		[ C(RESULT_MISS)   ] = 0,
-	},
- },
- [ C(LL  ) ] = {
-	[ C(OP_READ) ] = {
-		[ C(RESULT_ACCESS) ] = 0,
-		[ C(RESULT_MISS)   ] = 0,
-	},
-	[ C(OP_WRITE) ] = {
-		[ C(RESULT_ACCESS) ] = 0,
-		[ C(RESULT_MISS)   ] = 0x0025,	/* L2_M_LINES_INM     */
-	},
-	[ C(OP_PREFETCH) ] = {
-		[ C(RESULT_ACCESS) ] = 0,
-		[ C(RESULT_MISS)   ] = 0,
-	},
- },
- [ C(DTLB) ] = {
-	[ C(OP_READ) ] = {
-		[ C(RESULT_ACCESS) ] = 0x0043,	/* DATA_MEM_REFS      */
-		[ C(RESULT_MISS)   ] = 0,
-	},
-	[ C(OP_WRITE) ] = {
-		[ C(RESULT_ACCESS) ] = 0,
-		[ C(RESULT_MISS)   ] = 0,
-	},
-	[ C(OP_PREFETCH) ] = {
-		[ C(RESULT_ACCESS) ] = 0,
-		[ C(RESULT_MISS)   ] = 0,
-	},
- },
- [ C(ITLB) ] = {
-	[ C(OP_READ) ] = {
-		[ C(RESULT_ACCESS) ] = 0x0080,	/* IFU_IFETCH         */
-		[ C(RESULT_MISS)   ] = 0x0085,	/* ITLB_MISS          */
-	},
-	[ C(OP_WRITE) ] = {
-		[ C(RESULT_ACCESS) ] = -1,
-		[ C(RESULT_MISS)   ] = -1,
-	},
-	[ C(OP_PREFETCH) ] = {
-		[ C(RESULT_ACCESS) ] = -1,
-		[ C(RESULT_MISS)   ] = -1,
-	},
- },
- [ C(BPU ) ] = {
-	[ C(OP_READ) ] = {
-		[ C(RESULT_ACCESS) ] = 0x00c4,	/* BR_INST_RETIRED      */
-		[ C(RESULT_MISS)   ] = 0x00c5,	/* BR_MISS_PRED_RETIRED */
-        },
-	[ C(OP_WRITE) ] = {
-		[ C(RESULT_ACCESS) ] = -1,
-		[ C(RESULT_MISS)   ] = -1,
-	},
-	[ C(OP_PREFETCH) ] = {
-		[ C(RESULT_ACCESS) ] = -1,
-		[ C(RESULT_MISS)   ] = -1,
-	},
- },
-};
-
-static u64 p6_pmu_event_map(int hw_event)
-{
-	return p6_perfmon_event_map[hw_event];
-}
-
-/*
- * Event setting that is specified not to count anything.
- * We use this to effectively disable a counter.
- *
- * L2_RQSTS with 0 MESI unit mask.
- */
-#define P6_NOP_EVENT			0x0000002EULL
-
-static struct event_constraint p6_event_constraints[] =
-{
-	INTEL_EVENT_CONSTRAINT(0xc1, 0x1),	/* FLOPS */
-	INTEL_EVENT_CONSTRAINT(0x10, 0x1),	/* FP_COMP_OPS_EXE */
-	INTEL_EVENT_CONSTRAINT(0x11, 0x2),	/* FP_ASSIST */
-	INTEL_EVENT_CONSTRAINT(0x12, 0x2),	/* MUL */
-	INTEL_EVENT_CONSTRAINT(0x13, 0x2),	/* DIV */
-	INTEL_EVENT_CONSTRAINT(0x14, 0x1),	/* CYCLES_DIV_BUSY */
-	EVENT_CONSTRAINT_END
-};
-
-static void p6_pmu_disable_all(void)
-{
-	u64 val;
-
-	/* p6 only has one enable register */
-	rdmsrl(MSR_P6_EVNTSEL0, val);
-	val &= ~ARCH_PERFMON_EVENTSEL_ENABLE;
-	wrmsrl(MSR_P6_EVNTSEL0, val);
-}
-
-static void p6_pmu_enable_all(int added)
-{
-	unsigned long val;
-
-	/* p6 only has one enable register */
-	rdmsrl(MSR_P6_EVNTSEL0, val);
-	val |= ARCH_PERFMON_EVENTSEL_ENABLE;
-	wrmsrl(MSR_P6_EVNTSEL0, val);
-}
-
-static inline void
-p6_pmu_disable_event(struct perf_event *event)
-{
-	struct hw_perf_event *hwc = &event->hw;
-	u64 val = P6_NOP_EVENT;
-
-	(void)wrmsrl_safe(hwc->config_base, val);
-}
-
-static void p6_pmu_enable_event(struct perf_event *event)
-{
-	struct hw_perf_event *hwc = &event->hw;
-	u64 val;
-
-	val = hwc->config;
-
-	/*
-	 * p6 only has a global event enable, set on PerfEvtSel0
-	 * We "disable" events by programming P6_NOP_EVENT
-	 * and we rely on p6_pmu_enable_all() being called
-	 * to actually enable the events.
-	 */
-
-	(void)wrmsrl_safe(hwc->config_base, val);
-}
-
-PMU_FORMAT_ATTR(event,	"config:0-7"	);
-PMU_FORMAT_ATTR(umask,	"config:8-15"	);
-PMU_FORMAT_ATTR(edge,	"config:18"	);
-PMU_FORMAT_ATTR(pc,	"config:19"	);
-PMU_FORMAT_ATTR(inv,	"config:23"	);
-PMU_FORMAT_ATTR(cmask,	"config:24-31"	);
-
-static struct attribute *intel_p6_formats_attr[] = {
-	&format_attr_event.attr,
-	&format_attr_umask.attr,
-	&format_attr_edge.attr,
-	&format_attr_pc.attr,
-	&format_attr_inv.attr,
-	&format_attr_cmask.attr,
-	NULL,
-};
-
-static __initconst const struct x86_pmu p6_pmu = {
-	.name			= "p6",
-	.handle_irq		= x86_pmu_handle_irq,
-	.disable_all		= p6_pmu_disable_all,
-	.enable_all		= p6_pmu_enable_all,
-	.enable			= p6_pmu_enable_event,
-	.disable		= p6_pmu_disable_event,
-	.hw_config		= x86_pmu_hw_config,
-	.schedule_events	= x86_schedule_events,
-	.eventsel		= MSR_P6_EVNTSEL0,
-	.perfctr		= MSR_P6_PERFCTR0,
-	.event_map		= p6_pmu_event_map,
-	.max_events		= ARRAY_SIZE(p6_perfmon_event_map),
-	.apic			= 1,
-	.max_period		= (1ULL << 31) - 1,
-	.version		= 0,
-	.num_counters		= 2,
-	/*
-	 * Events have 40 bits implemented. However they are designed such
-	 * that bits [32-39] are sign extensions of bit 31. As such the
-	 * effective width of a event for P6-like PMU is 32 bits only.
-	 *
-	 * See IA-32 Intel Architecture Software developer manual Vol 3B
-	 */
-	.cntval_bits		= 32,
-	.cntval_mask		= (1ULL << 32) - 1,
-	.get_event_constraints	= x86_get_event_constraints,
-	.event_constraints	= p6_event_constraints,
-
-	.format_attrs		= intel_p6_formats_attr,
-	.events_sysfs_show	= intel_event_sysfs_show,
-
-};
-
-static __init void p6_pmu_rdpmc_quirk(void)
-{
-	if (boot_cpu_data.x86_mask < 9) {
-		/*
-		 * PPro erratum 26; fixed in stepping 9 and above.
-		 */
-		pr_warn("Userspace RDPMC support disabled due to a CPU erratum\n");
-		x86_pmu.attr_rdpmc_broken = 1;
-		x86_pmu.attr_rdpmc = 0;
-	}
-}
-
-__init int p6_pmu_init(void)
-{
-	x86_pmu = p6_pmu;
-
-	switch (boot_cpu_data.x86_model) {
-	case  1: /* Pentium Pro */
-		x86_add_quirk(p6_pmu_rdpmc_quirk);
-		break;
-
-	case  3: /* Pentium II - Klamath */
-	case  5: /* Pentium II - Deschutes */
-	case  6: /* Pentium II - Mendocino */
-		break;
-
-	case  7: /* Pentium III - Katmai */
-	case  8: /* Pentium III - Coppermine */
-	case 10: /* Pentium III Xeon */
-	case 11: /* Pentium III - Tualatin */
-		break;
-
-	case  9: /* Pentium M - Banias */
-	case 13: /* Pentium M - Dothan */
-		break;
-
-	default:
-		pr_cont("unsupported p6 CPU model %d ", boot_cpu_data.x86_model);
-		return -ENODEV;
-	}
-
-	memcpy(hw_cache_event_ids, p6_hw_cache_event_ids,
-		sizeof(hw_cache_event_ids));
-
-	return 0;
-}
--- zfcpdump-kernel-4.4.orig/arch/x86/kernel/cpu/perfctr-watchdog.c
+++ zfcpdump-kernel-4.4/arch/x86/kernel/cpu/perfctr-watchdog.c
@@ -12,7 +12,7 @@
  */
 
 #include <linux/percpu.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/kernel.h>
 #include <linux/bitops.h>
 #include <linux/smp.h>
--- zfcpdump-kernel-4.4.orig/arch/x86/kernel/cpu/transmeta.c
+++ zfcpdump-kernel-4.4/arch/x86/kernel/cpu/transmeta.c
@@ -1,6 +1,6 @@
 #include <linux/kernel.h>
 #include <linux/mm.h>
-#include <asm/processor.h>
+#include <asm/cpufeature.h>
 #include <asm/msr.h>
 #include "cpu.h"
 
--- zfcpdump-kernel-4.4.orig/arch/x86/kernel/cpu/vmware.c
+++ zfcpdump-kernel-4.4/arch/x86/kernel/cpu/vmware.c
@@ -22,7 +22,8 @@
  */
 
 #include <linux/dmi.h>
-#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/export.h>
 #include <asm/div64.h>
 #include <asm/x86_init.h>
 #include <asm/hypervisor.h>
--- zfcpdump-kernel-4.4.orig/arch/x86/kernel/crash.c
+++ zfcpdump-kernel-4.4/arch/x86/kernel/crash.c
@@ -20,7 +20,7 @@
 #include <linux/delay.h>
 #include <linux/elf.h>
 #include <linux/elfcore.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/slab.h>
 #include <linux/vmalloc.h>
 
--- zfcpdump-kernel-4.4.orig/arch/x86/kernel/dumpstack_32.c
+++ zfcpdump-kernel-4.4/arch/x86/kernel/dumpstack_32.c
@@ -7,7 +7,7 @@
 #include <linux/uaccess.h>
 #include <linux/hardirq.h>
 #include <linux/kdebug.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/ptrace.h>
 #include <linux/kexec.h>
 #include <linux/sysfs.h>
--- zfcpdump-kernel-4.4.orig/arch/x86/kernel/dumpstack_64.c
+++ zfcpdump-kernel-4.4/arch/x86/kernel/dumpstack_64.c
@@ -7,7 +7,7 @@
 #include <linux/uaccess.h>
 #include <linux/hardirq.h>
 #include <linux/kdebug.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/ptrace.h>
 #include <linux/kexec.h>
 #include <linux/sysfs.h>
--- zfcpdump-kernel-4.4.orig/arch/x86/kernel/e820.c
+++ zfcpdump-kernel-4.4/arch/x86/kernel/e820.c
@@ -24,6 +24,7 @@
 #include <asm/e820.h>
 #include <asm/proto.h>
 #include <asm/setup.h>
+#include <asm/cpufeature.h>
 
 /*
  * The e820 map is the map that gets modified e.g. with command line parameters
--- zfcpdump-kernel-4.4.orig/arch/x86/kernel/early-quirks.c
+++ zfcpdump-kernel-4.4/arch/x86/kernel/early-quirks.c
@@ -11,7 +11,11 @@
 
 #include <linux/pci.h>
 #include <linux/acpi.h>
+#include <linux/delay.h>
+#include <linux/dmi.h>
 #include <linux/pci_ids.h>
+#include <linux/bcma/bcma.h>
+#include <linux/bcma/bcma_regs.h>
 #include <drm/i915_drm.h>
 #include <asm/pci-direct.h>
 #include <asm/dma.h>
@@ -21,6 +25,9 @@
 #include <asm/iommu.h>
 #include <asm/gart.h>
 #include <asm/irq_remapping.h>
+#include <asm/early_ioremap.h>
+
+#define dev_err(msg)  pr_err("pci 0000:%02x:%02x.%d: %s", bus, slot, func, msg)
 
 static void __init fix_hypertransport_config(int num, int slot, int func)
 {
@@ -76,6 +83,13 @@ static void __init nvidia_bugs(int num,
 #ifdef CONFIG_ACPI
 #ifdef CONFIG_X86_IO_APIC
 	/*
+	 * Only applies to Nvidia root ports (bus 0) and not to
+	 * Nvidia graphics cards with PCI ports on secondary buses.
+	 */
+	if (num)
+		return;
+
+	/*
 	 * All timer overrides on Nvidia are
 	 * wrong unless HPET is enabled.
 	 * Unfortunately that's not true on many Asus boards.
@@ -589,6 +603,61 @@ static void __init force_disable_hpet(in
 #endif
 }
 
+#define BCM4331_MMIO_SIZE	16384
+#define BCM4331_PM_CAP		0x40
+#define bcma_aread32(reg)	ioread32(mmio + 1 * BCMA_CORE_SIZE + reg)
+#define bcma_awrite32(reg, val)	iowrite32(val, mmio + 1 * BCMA_CORE_SIZE + reg)
+
+static void __init apple_airport_reset(int bus, int slot, int func)
+{
+	void __iomem *mmio;
+	u16 pmcsr;
+	u64 addr;
+	int i;
+
+	if (!dmi_match(DMI_SYS_VENDOR, "Apple Inc."))
+		return;
+
+	/* Card may have been put into PCI_D3hot by grub quirk */
+	pmcsr = read_pci_config_16(bus, slot, func, BCM4331_PM_CAP + PCI_PM_CTRL);
+
+	if ((pmcsr & PCI_PM_CTRL_STATE_MASK) != PCI_D0) {
+		pmcsr &= ~PCI_PM_CTRL_STATE_MASK;
+		write_pci_config_16(bus, slot, func, BCM4331_PM_CAP + PCI_PM_CTRL, pmcsr);
+		mdelay(10);
+
+		pmcsr = read_pci_config_16(bus, slot, func, BCM4331_PM_CAP + PCI_PM_CTRL);
+		if ((pmcsr & PCI_PM_CTRL_STATE_MASK) != PCI_D0) {
+			dev_err("Cannot power up Apple AirPort card\n");
+			return;
+		}
+	}
+
+	addr  =      read_pci_config(bus, slot, func, PCI_BASE_ADDRESS_0);
+	addr |= (u64)read_pci_config(bus, slot, func, PCI_BASE_ADDRESS_1) << 32;
+	addr &= PCI_BASE_ADDRESS_MEM_MASK;
+
+	mmio = early_ioremap(addr, BCM4331_MMIO_SIZE);
+	if (!mmio) {
+		dev_err("Cannot iomap Apple AirPort card\n");
+		return;
+	}
+
+	pr_info("Resetting Apple AirPort card (left enabled by EFI)\n");
+
+	for (i = 0; bcma_aread32(BCMA_RESET_ST) && i < 30; i++)
+		udelay(10);
+
+	bcma_awrite32(BCMA_RESET_CTL, BCMA_RESET_CTL_RESET);
+	bcma_aread32(BCMA_RESET_CTL);
+	udelay(1);
+
+	bcma_awrite32(BCMA_RESET_CTL, 0);
+	bcma_aread32(BCMA_RESET_CTL);
+	udelay(10);
+
+	early_iounmap(mmio, BCM4331_MMIO_SIZE);
+}
 
 #define QFLAG_APPLY_ONCE 	0x1
 #define QFLAG_APPLIED		0x2
@@ -602,12 +671,6 @@ struct chipset {
 	void (*f)(int num, int slot, int func);
 };
 
-/*
- * Only works for devices on the root bus. If you add any devices
- * not on bus 0 readd another loop level in early_quirks(). But
- * be careful because at least the Nvidia quirk here relies on
- * only matching on bus 0.
- */
 static struct chipset early_qrk[] __initdata = {
 	{ PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID,
 	  PCI_CLASS_BRIDGE_PCI, PCI_ANY_ID, QFLAG_APPLY_ONCE, nvidia_bugs },
@@ -637,9 +700,13 @@ static struct chipset early_qrk[] __init
 	 */
 	{ PCI_VENDOR_ID_INTEL, 0x0f00,
 		PCI_CLASS_BRIDGE_HOST, PCI_ANY_ID, 0, force_disable_hpet},
+	{ PCI_VENDOR_ID_BROADCOM, 0x4331,
+	  PCI_CLASS_NETWORK_OTHER, PCI_ANY_ID, 0, apple_airport_reset},
 	{}
 };
 
+static void __init early_pci_scan_bus(int bus);
+
 /**
  * check_dev_quirk - apply early quirks to a given PCI device
  * @num: bus number
@@ -648,7 +715,7 @@ static struct chipset early_qrk[] __init
  *
  * Check the vendor & device ID against the early quirks table.
  *
- * If the device is single function, let early_quirks() know so we don't
+ * If the device is single function, let early_pci_scan_bus() know so we don't
  * poke at this device again.
  */
 static int __init check_dev_quirk(int num, int slot, int func)
@@ -657,6 +724,7 @@ static int __init check_dev_quirk(int nu
 	u16 vendor;
 	u16 device;
 	u8 type;
+	u8 sec;
 	int i;
 
 	class = read_pci_config_16(num, slot, func, PCI_CLASS_DEVICE);
@@ -684,25 +752,36 @@ static int __init check_dev_quirk(int nu
 
 	type = read_pci_config_byte(num, slot, func,
 				    PCI_HEADER_TYPE);
+
+	if ((type & 0x7f) == PCI_HEADER_TYPE_BRIDGE) {
+		sec = read_pci_config_byte(num, slot, func, PCI_SECONDARY_BUS);
+		if (sec > num)
+			early_pci_scan_bus(sec);
+	}
+
 	if (!(type & 0x80))
 		return -1;
 
 	return 0;
 }
 
-void __init early_quirks(void)
+static void __init early_pci_scan_bus(int bus)
 {
 	int slot, func;
 
-	if (!early_pci_allowed())
-		return;
-
 	/* Poor man's PCI discovery */
-	/* Only scan the root bus */
 	for (slot = 0; slot < 32; slot++)
 		for (func = 0; func < 8; func++) {
 			/* Only probe function 0 on single fn devices */
-			if (check_dev_quirk(0, slot, func))
+			if (check_dev_quirk(bus, slot, func))
 				break;
 		}
 }
+
+void __init early_quirks(void)
+{
+	if (!early_pci_allowed())
+		return;
+
+	early_pci_scan_bus(0);
+}
--- zfcpdump-kernel-4.4.orig/arch/x86/kernel/head_32.S
+++ zfcpdump-kernel-4.4/arch/x86/kernel/head_32.S
@@ -19,7 +19,7 @@
 #include <asm/setup.h>
 #include <asm/processor-flags.h>
 #include <asm/msr-index.h>
-#include <asm/cpufeature.h>
+#include <asm/cpufeatures.h>
 #include <asm/percpu.h>
 #include <asm/nops.h>
 #include <asm/bootparam.h>
--- zfcpdump-kernel-4.4.orig/arch/x86/kernel/hpet.c
+++ zfcpdump-kernel-4.4/arch/x86/kernel/hpet.c
@@ -12,6 +12,7 @@
 #include <linux/pm.h>
 #include <linux/io.h>
 
+#include <asm/cpufeature.h>
 #include <asm/irqdomain.h>
 #include <asm/fixmap.h>
 #include <asm/hpet.h>
--- zfcpdump-kernel-4.4.orig/arch/x86/kernel/hw_breakpoint.c
+++ zfcpdump-kernel-4.4/arch/x86/kernel/hw_breakpoint.c
@@ -36,13 +36,14 @@
 #include <linux/percpu.h>
 #include <linux/kdebug.h>
 #include <linux/kernel.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/sched.h>
 #include <linux/smp.h>
 
 #include <asm/hw_breakpoint.h>
 #include <asm/processor.h>
 #include <asm/debugreg.h>
+#include <asm/user.h>
 
 /* Per cpu debug control register value */
 DEFINE_PER_CPU(unsigned long, cpu_dr7);
--- zfcpdump-kernel-4.4.orig/arch/x86/kernel/i386_ksyms_32.c
+++ zfcpdump-kernel-4.4/arch/x86/kernel/i386_ksyms_32.c
@@ -1,4 +1,5 @@
-#include <linux/module.h>
+#include <linux/export.h>
+#include <linux/spinlock_types.h>
 
 #include <asm/checksum.h>
 #include <asm/pgtable.h>
--- zfcpdump-kernel-4.4.orig/arch/x86/kernel/i8253.c
+++ zfcpdump-kernel-4.4/arch/x86/kernel/i8253.c
@@ -3,7 +3,7 @@
  *
  */
 #include <linux/clockchips.h>
-#include <linux/module.h>
+#include <linux/init.h>
 #include <linux/timex.h>
 #include <linux/i8253.h>
 
--- zfcpdump-kernel-4.4.orig/arch/x86/kernel/io_delay.c
+++ zfcpdump-kernel-4.4/arch/x86/kernel/io_delay.c
@@ -6,7 +6,7 @@
  * outb_p/inb_p API uses.
  */
 #include <linux/kernel.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/delay.h>
 #include <linux/init.h>
 #include <linux/dmi.h>
--- zfcpdump-kernel-4.4.orig/arch/x86/kernel/ioport.c
+++ zfcpdump-kernel-4.4/arch/x86/kernel/ioport.c
@@ -15,6 +15,7 @@
 #include <linux/thread_info.h>
 #include <linux/syscalls.h>
 #include <linux/bitmap.h>
+#include <linux/module.h>
 #include <asm/syscalls.h>
 
 /*
@@ -28,7 +29,7 @@ asmlinkage long sys_ioperm(unsigned long
 
 	if ((from + num <= from) || (from + num > IO_BITMAP_BITS))
 		return -EINVAL;
-	if (turn_on && !capable(CAP_SYS_RAWIO))
+	if (turn_on && (!capable(CAP_SYS_RAWIO) || secure_modules()))
 		return -EPERM;
 
 	/*
@@ -96,18 +97,24 @@ asmlinkage long sys_ioperm(unsigned long
 SYSCALL_DEFINE1(iopl, unsigned int, level)
 {
 	struct pt_regs *regs = current_pt_regs();
-	unsigned int old = (regs->flags >> 12) & 3;
 	struct thread_struct *t = &current->thread;
 
+	/*
+	 * Careful: the IOPL bits in regs->flags are undefined under Xen PV
+	 * and changing them has no effect.
+	 */
+	unsigned int old = t->iopl >> X86_EFLAGS_IOPL_BIT;
+
 	if (level > 3)
 		return -EINVAL;
 	/* Trying to gain more privileges? */
 	if (level > old) {
-		if (!capable(CAP_SYS_RAWIO))
+		if (!capable(CAP_SYS_RAWIO) || secure_modules())
 			return -EPERM;
 	}
-	regs->flags = (regs->flags & ~X86_EFLAGS_IOPL) | (level << 12);
-	t->iopl = level << 12;
+	regs->flags = (regs->flags & ~X86_EFLAGS_IOPL) |
+		(level << X86_EFLAGS_IOPL_BIT);
+	t->iopl = level << X86_EFLAGS_IOPL_BIT;
 	set_iopl_mask(t->iopl);
 
 	return 0;
--- zfcpdump-kernel-4.4.orig/arch/x86/kernel/irq.c
+++ zfcpdump-kernel-4.4/arch/x86/kernel/irq.c
@@ -462,7 +462,7 @@ void fixup_irqs(void)
 		 * non intr-remapping case, we can't wait till this interrupt
 		 * arrives at this cpu before completing the irq move.
 		 */
-		irq_force_complete_move(irq);
+		irq_force_complete_move(desc);
 
 		if (cpumask_any_and(affinity, cpu_online_mask) >= nr_cpu_ids) {
 			break_affinity = 1;
@@ -470,6 +470,15 @@ void fixup_irqs(void)
 		}
 
 		chip = irq_data_get_irq_chip(data);
+		/*
+		 * The interrupt descriptor might have been cleaned up
+		 * already, but it is not yet removed from the radix tree
+		 */
+		if (!chip) {
+			raw_spin_unlock(&desc->lock);
+			continue;
+		}
+
 		if (!irqd_can_move_in_process_context(data) && chip->irq_mask)
 			chip->irq_mask(data);
 
--- zfcpdump-kernel-4.4.orig/arch/x86/kernel/irq_32.c
+++ zfcpdump-kernel-4.4/arch/x86/kernel/irq_32.c
@@ -8,7 +8,6 @@
  * io_apic.c.)
  */
 
-#include <linux/module.h>
 #include <linux/seq_file.h>
 #include <linux/interrupt.h>
 #include <linux/kernel_stat.h>
--- zfcpdump-kernel-4.4.orig/arch/x86/kernel/irq_64.c
+++ zfcpdump-kernel-4.4/arch/x86/kernel/irq_64.c
@@ -11,7 +11,6 @@
 #include <linux/kernel_stat.h>
 #include <linux/interrupt.h>
 #include <linux/seq_file.h>
-#include <linux/module.h>
 #include <linux/delay.h>
 #include <linux/ftrace.h>
 #include <linux/uaccess.h>
--- zfcpdump-kernel-4.4.orig/arch/x86/kernel/kdebugfs.c
+++ zfcpdump-kernel-4.4/arch/x86/kernel/kdebugfs.c
@@ -8,7 +8,7 @@
  */
 #include <linux/debugfs.h>
 #include <linux/uaccess.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/stat.h>
--- zfcpdump-kernel-4.4.orig/arch/x86/kernel/kprobes/core.c
+++ zfcpdump-kernel-4.4/arch/x86/kernel/kprobes/core.c
@@ -959,7 +959,19 @@ int kprobe_fault_handler(struct pt_regs
 		 * normal page fault.
 		 */
 		regs->ip = (unsigned long)cur->addr;
+		/*
+		 * Trap flag (TF) has been set here because this fault
+		 * happened where the single stepping will be done.
+		 * So clear it by resetting the current kprobe:
+		 */
+		regs->flags &= ~X86_EFLAGS_TF;
+
+		/*
+		 * If the TF flag was set before the kprobe hit,
+		 * don't touch it:
+		 */
 		regs->flags |= kcb->kprobe_old_flags;
+
 		if (kcb->kprobe_status == KPROBE_REENTER)
 			restore_previous_kprobe(kcb);
 		else
--- zfcpdump-kernel-4.4.orig/arch/x86/kernel/kvm.c
+++ zfcpdump-kernel-4.4/arch/x86/kernel/kvm.c
@@ -21,7 +21,7 @@
  */
 
 #include <linux/context_tracking.h>
-#include <linux/module.h>
+#include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/kvm_para.h>
 #include <linux/cpu.h>
--- zfcpdump-kernel-4.4.orig/arch/x86/kernel/livepatch.c
+++ zfcpdump-kernel-4.4/arch/x86/kernel/livepatch.c
@@ -20,8 +20,6 @@
 
 #include <linux/module.h>
 #include <linux/uaccess.h>
-#include <asm/cacheflush.h>
-#include <asm/page_types.h>
 #include <asm/elf.h>
 #include <asm/livepatch.h>
 
@@ -38,11 +36,10 @@
 int klp_write_module_reloc(struct module *mod, unsigned long type,
 			   unsigned long loc, unsigned long value)
 {
-	int ret, numpages, size = 4;
-	bool readonly;
+	size_t size = 4;
 	unsigned long val;
-	unsigned long core = (unsigned long)mod->module_core;
-	unsigned long core_size = mod->core_size;
+	unsigned long core = (unsigned long)mod->core_layout.base;
+	unsigned long core_size = mod->core_layout.size;
 
 	switch (type) {
 	case R_X86_64_NONE:
@@ -69,23 +66,5 @@ int klp_write_module_reloc(struct module
 		/* loc does not point to any symbol inside the module */
 		return -EINVAL;
 
-	readonly = false;
-
-#ifdef CONFIG_DEBUG_SET_MODULE_RONX
-	if (loc < core + mod->core_ro_size)
-		readonly = true;
-#endif
-
-	/* determine if the relocation spans a page boundary */
-	numpages = ((loc & PAGE_MASK) == ((loc + size) & PAGE_MASK)) ? 1 : 2;
-
-	if (readonly)
-		set_memory_rw(loc & PAGE_MASK, numpages);
-
-	ret = probe_kernel_write((void *)loc, &val, size);
-
-	if (readonly)
-		set_memory_ro(loc & PAGE_MASK, numpages);
-
-	return ret;
+	return probe_kernel_write((void *)loc, &val, size);
 }
--- zfcpdump-kernel-4.4.orig/arch/x86/kernel/mpparse.c
+++ zfcpdump-kernel-4.4/arch/x86/kernel/mpparse.c
@@ -16,7 +16,6 @@
 #include <linux/mc146818rtc.h>
 #include <linux/bitops.h>
 #include <linux/acpi.h>
-#include <linux/module.h>
 #include <linux/smp.h>
 #include <linux/pci.h>
 
--- zfcpdump-kernel-4.4.orig/arch/x86/kernel/msr.c
+++ zfcpdump-kernel-4.4/arch/x86/kernel/msr.c
@@ -40,7 +40,7 @@
 #include <linux/uaccess.h>
 #include <linux/gfp.h>
 
-#include <asm/processor.h>
+#include <asm/cpufeature.h>
 #include <asm/msr.h>
 
 static struct class *msr_class;
@@ -105,6 +105,9 @@ static ssize_t msr_write(struct file *fi
 	int err = 0;
 	ssize_t bytes = 0;
 
+	if (secure_modules())
+		return -EPERM;
+
 	if (count % 8)
 		return -EINVAL;	/* Invalid chunk size */
 
@@ -152,6 +155,10 @@ static long msr_ioctl(struct file *file,
 			err = -EBADF;
 			break;
 		}
+		if (secure_modules()) {
+			err = -EPERM;
+			break;
+		}
 		if (copy_from_user(&regs, uregs, sizeof regs)) {
 			err = -EFAULT;
 			break;
--- zfcpdump-kernel-4.4.orig/arch/x86/kernel/paravirt-spinlocks.c
+++ zfcpdump-kernel-4.4/arch/x86/kernel/paravirt-spinlocks.c
@@ -3,7 +3,7 @@
  * compiled in a FTRACE-compatible way.
  */
 #include <linux/spinlock.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/jump_label.h>
 
 #include <asm/paravirt.h>
--- zfcpdump-kernel-4.4.orig/arch/x86/kernel/paravirt.c
+++ zfcpdump-kernel-4.4/arch/x86/kernel/paravirt.c
@@ -19,7 +19,8 @@
 */
 
 #include <linux/errno.h>
-#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/export.h>
 #include <linux/efi.h>
 #include <linux/bcd.h>
 #include <linux/highmem.h>
@@ -55,12 +56,12 @@ asm (".pushsection .entry.text, \"ax\"\n
      ".popsection");
 
 /* identity function, which can be inlined */
-u32 _paravirt_ident_32(u32 x)
+u32 notrace _paravirt_ident_32(u32 x)
 {
 	return x;
 }
 
-u64 _paravirt_ident_64(u64 x)
+u64 notrace _paravirt_ident_64(u64 x)
 {
 	return x;
 }
--- zfcpdump-kernel-4.4.orig/arch/x86/kernel/pci-swiotlb.c
+++ zfcpdump-kernel-4.4/arch/x86/kernel/pci-swiotlb.c
@@ -2,7 +2,7 @@
 
 #include <linux/pci.h>
 #include <linux/cache.h>
-#include <linux/module.h>
+#include <linux/init.h>
 #include <linux/swiotlb.h>
 #include <linux/bootmem.h>
 #include <linux/dma-mapping.h>
--- zfcpdump-kernel-4.4.orig/arch/x86/kernel/pmem.c
+++ zfcpdump-kernel-4.4/arch/x86/kernel/pmem.c
@@ -3,7 +3,7 @@
  * Copyright (c) 2015, Intel Corporation.
  */
 #include <linux/platform_device.h>
-#include <linux/module.h>
+#include <linux/init.h>
 #include <linux/ioport.h>
 
 static int found(u64 start, u64 end, void *data)
--- zfcpdump-kernel-4.4.orig/arch/x86/kernel/process.c
+++ zfcpdump-kernel-4.4/arch/x86/kernel/process.c
@@ -7,7 +7,8 @@
 #include <linux/prctl.h>
 #include <linux/slab.h>
 #include <linux/sched.h>
-#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/export.h>
 #include <linux/pm.h>
 #include <linux/tick.h>
 #include <linux/random.h>
@@ -402,7 +403,7 @@ static int prefer_mwait_c1_over_halt(con
 	if (c->x86_vendor != X86_VENDOR_INTEL)
 		return 0;
 
-	if (!cpu_has(c, X86_FEATURE_MWAIT))
+	if (!cpu_has(c, X86_FEATURE_MWAIT) || static_cpu_has_bug(X86_BUG_MONITOR))
 		return 0;
 
 	return 1;
--- zfcpdump-kernel-4.4.orig/arch/x86/kernel/process_32.c
+++ zfcpdump-kernel-4.4/arch/x86/kernel/process_32.c
@@ -25,7 +25,7 @@
 #include <linux/delay.h>
 #include <linux/reboot.h>
 #include <linux/mc146818rtc.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/kallsyms.h>
 #include <linux/ptrace.h>
 #include <linux/personality.h>
--- zfcpdump-kernel-4.4.orig/arch/x86/kernel/process_64.c
+++ zfcpdump-kernel-4.4/arch/x86/kernel/process_64.c
@@ -26,7 +26,7 @@
 #include <linux/user.h>
 #include <linux/interrupt.h>
 #include <linux/delay.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/ptrace.h>
 #include <linux/notifier.h>
 #include <linux/kprobes.h>
@@ -48,6 +48,7 @@
 #include <asm/syscalls.h>
 #include <asm/debugreg.h>
 #include <asm/switch_to.h>
+#include <asm/xen/hypervisor.h>
 
 asmlinkage extern void ret_from_fork(void);
 
@@ -411,6 +412,17 @@ __switch_to(struct task_struct *prev_p,
 		     task_thread_info(prev_p)->flags & _TIF_WORK_CTXSW_PREV))
 		__switch_to_xtra(prev_p, next_p, tss);
 
+#ifdef CONFIG_XEN
+	/*
+	 * On Xen PV, IOPL bits in pt_regs->flags have no effect, and
+	 * current_pt_regs()->flags may not match the current task's
+	 * intended IOPL.  We need to switch it manually.
+	 */
+	if (unlikely(static_cpu_has(X86_FEATURE_XENPV) &&
+		     prev->iopl != next->iopl))
+		xen_set_iopl_mask(next->iopl);
+#endif
+
 	if (static_cpu_has_bug(X86_BUG_SYSRET_SS_ATTRS)) {
 		/*
 		 * AMD CPUs have a misfeature: SYSRET sets the SS selector but
--- zfcpdump-kernel-4.4.orig/arch/x86/kernel/pvclock.c
+++ zfcpdump-kernel-4.4/arch/x86/kernel/pvclock.c
@@ -66,6 +66,8 @@ u8 pvclock_read_flags(struct pvclock_vcp
 
 	do {
 		version = __pvclock_read_cycles(src, &ret, &flags);
+		/* Make sure that the version double-check is last. */
+		smp_rmb();
 	} while ((src->version & 1) || version != src->version);
 
 	return flags & valid_flags;
@@ -80,6 +82,8 @@ cycle_t pvclock_clocksource_read(struct
 
 	do {
 		version = __pvclock_read_cycles(src, &ret, &flags);
+		/* Make sure that the version double-check is last. */
+		smp_rmb();
 	} while ((src->version & 1) || version != src->version);
 
 	if (unlikely((flags & PVCLOCK_GUEST_STOPPED) != 0)) {
--- zfcpdump-kernel-4.4.orig/arch/x86/kernel/reboot.c
+++ zfcpdump-kernel-4.4/arch/x86/kernel/reboot.c
@@ -1,6 +1,6 @@
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/reboot.h>
 #include <linux/init.h>
 #include <linux/pm.h>
@@ -55,6 +55,19 @@ bool port_cf9_safe = false;
  */
 
 /*
+ * Some machines require the "reboot=a" commandline options
+ */
+static int __init set_acpi_reboot(const struct dmi_system_id *d)
+{
+	if (reboot_type != BOOT_ACPI) {
+		reboot_type = BOOT_ACPI;
+		pr_info("%s series board detected. Selecting %s-method for reboots.\n",
+			d->ident, "ACPI");
+	}
+	return 0;
+}
+
+/*
  * Some machines require the "reboot=b" or "reboot=k"  commandline options,
  * this quirk makes that automatic.
  */
@@ -182,6 +195,14 @@ static struct dmi_system_id __initdata r
 			DMI_MATCH(DMI_PRODUCT_NAME, "iMac9,1"),
 		},
 	},
+	{	/* Handle problems with rebooting on the iMac10,1. */
+		.callback = set_pci_reboot,
+		.ident = "Apple iMac10,1",
+		.matches = {
+		    DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
+		    DMI_MATCH(DMI_PRODUCT_NAME, "iMac10,1"),
+		},
+	},
 
 	/* ASRock */
 	{	/* Handle problems with rebooting on ASRock Q1900DC-ITX */
@@ -387,6 +408,14 @@ static struct dmi_system_id __initdata r
 			DMI_MATCH(DMI_PRODUCT_NAME, "Dell XPS710"),
 		},
 	},
+	{	/* Handle problems with rebooting on Dell Optiplex 7450 AIO */
+		.callback = set_acpi_reboot,
+		.ident = "Dell OptiPlex 7450 AIO",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+			DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex 7450 AIO"),
+		},
+	},
 
 	/* Hewlett-Packard */
 	{	/* Handle problems with rebooting on HP laptops */
@@ -407,7 +436,46 @@ static struct dmi_system_id __initdata r
 			DMI_MATCH(DMI_PRODUCT_NAME, "VGN-Z540N"),
 		},
 	},
-
+	{	/* Handle problems with rebooting on the Latitude E6520. */
+		.callback = set_pci_reboot,
+		.ident = "Dell Latitude E6520",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+			DMI_MATCH(DMI_PRODUCT_NAME, "Latitude E6520"),
+		},
+	},
+	{       /* Handle problems with rebooting on the OptiPlex 790. */
+		.callback = set_pci_reboot,
+		.ident = "Dell OptiPlex 790",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+			DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex 790"),
+		},
+	},
+	{	/* Handle problems with rebooting on the OptiPlex 990. */
+		.callback = set_pci_reboot,
+		.ident = "Dell OptiPlex 990",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+			DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex 990"),
+		},
+	},
+	{       /* Handle problems with rebooting on the Latitude E6220. */
+		.callback = set_pci_reboot,
+		.ident = "Dell Latitude E6220",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+			DMI_MATCH(DMI_PRODUCT_NAME, "Latitude E6220"),
+		},
+	},
+	{	/* Handle problems with rebooting on the OptiPlex 390. */
+		.callback = set_pci_reboot,
+		.ident = "Dell OptiPlex 390",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+			DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex 390"),
+		},
+	},
 	{ }
 };
 
--- zfcpdump-kernel-4.4.orig/arch/x86/kernel/setup.c
+++ zfcpdump-kernel-4.4/arch/x86/kernel/setup.c
@@ -36,7 +36,7 @@
 #include <linux/console.h>
 #include <linux/root_dev.h>
 #include <linux/highmem.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/efi.h>
 #include <linux/init.h>
 #include <linux/edd.h>
@@ -1143,6 +1143,19 @@ void __init setup_arch(char **cmdline_p)
 
 	io_delay_init();
 
+#ifdef CONFIG_EFI_SECURE_BOOT_SIG_ENFORCE
+	if (boot_params.secure_boot == EFI_SECURE_BOOT) {
+		set_bit(EFI_SECURE_BOOT, &efi.flags);
+		enforce_signed_modules();
+		pr_info("Secure boot enabled\n");
+	}
+	else if (boot_params.secure_boot == EFI_MOKSBSTATE_DISABLED) {
+		set_bit(EFI_MOKSBSTATE_DISABLED, &efi.flags);
+		boot_params.secure_boot = 0;
+		pr_info("Secure boot MOKSBState disabled\n");
+    }
+#endif
+
 	/*
 	 * Parse the ACPI tables for possible boot-time SMP configuration.
 	 */
--- zfcpdump-kernel-4.4.orig/arch/x86/kernel/smpboot.c
+++ zfcpdump-kernel-4.4/arch/x86/kernel/smpboot.c
@@ -43,7 +43,7 @@
 
 #include <linux/init.h>
 #include <linux/smp.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/sched.h>
 #include <linux/percpu.h>
 #include <linux/bootmem.h>
@@ -97,6 +97,14 @@ DEFINE_PER_CPU_READ_MOSTLY(cpumask_var_t
 DEFINE_PER_CPU_READ_MOSTLY(struct cpuinfo_x86, cpu_info);
 EXPORT_PER_CPU_SYMBOL(cpu_info);
 
+/* Logical package management. We might want to allocate that dynamically */
+static int *physical_to_logical_pkg __read_mostly;
+static unsigned long *physical_package_map __read_mostly;;
+static unsigned long *logical_package_map  __read_mostly;
+static unsigned int max_physical_pkg_id __read_mostly;
+unsigned int __max_logical_packages __read_mostly;
+EXPORT_SYMBOL(__max_logical_packages);
+
 static inline void smpboot_setup_warm_reset_vector(unsigned long start_eip)
 {
 	unsigned long flags;
@@ -251,6 +259,115 @@ static void notrace start_secondary(void
 	cpu_startup_entry(CPUHP_ONLINE);
 }
 
+int topology_update_package_map(unsigned int apicid, unsigned int cpu)
+{
+	unsigned int new, pkg = apicid >> boot_cpu_data.x86_coreid_bits;
+
+	/* Called from early boot ? */
+	if (!physical_package_map)
+		return 0;
+
+	if (pkg >= max_physical_pkg_id)
+		return -EINVAL;
+
+	/* Set the logical package id */
+	if (test_and_set_bit(pkg, physical_package_map))
+		goto found;
+
+	new = find_first_zero_bit(logical_package_map, __max_logical_packages);
+	if (new >= __max_logical_packages) {
+		physical_to_logical_pkg[pkg] = -1;
+		pr_warn("APIC(%x) Package %u exceeds logical package map\n",
+			apicid, pkg);
+		return -ENOSPC;
+	}
+	set_bit(new, logical_package_map);
+	pr_info("APIC(%x) Converting physical %u to logical package %u\n",
+		apicid, pkg, new);
+	physical_to_logical_pkg[pkg] = new;
+
+found:
+	cpu_data(cpu).logical_proc_id = physical_to_logical_pkg[pkg];
+	return 0;
+}
+
+/**
+ * topology_phys_to_logical_pkg - Map a physical package id to a logical
+ *
+ * Returns logical package id or -1 if not found
+ */
+int topology_phys_to_logical_pkg(unsigned int phys_pkg)
+{
+	if (phys_pkg >= max_physical_pkg_id)
+		return -1;
+	return physical_to_logical_pkg[phys_pkg];
+}
+EXPORT_SYMBOL(topology_phys_to_logical_pkg);
+
+static void __init smp_init_package_map(void)
+{
+	unsigned int ncpus, cpu;
+	size_t size;
+
+	/*
+	 * Today neither Intel nor AMD support heterogenous systems. That
+	 * might change in the future....
+	 *
+	 * While ideally we'd want '* smp_num_siblings' in the below @ncpus
+	 * computation, this won't actually work since some Intel BIOSes
+	 * report inconsistent HT data when they disable HT.
+	 *
+	 * In particular, they reduce the APIC-IDs to only include the cores,
+	 * but leave the CPUID topology to say there are (2) siblings.
+	 * This means we don't know how many threads there will be until
+	 * after the APIC enumeration.
+	 *
+	 * By not including this we'll sometimes over-estimate the number of
+	 * logical packages by the amount of !present siblings, but this is
+	 * still better than MAX_LOCAL_APIC.
+	 *
+	 * We use total_cpus not nr_cpu_ids because nr_cpu_ids can be limited
+	 * on the command line leading to a similar issue as the HT disable
+	 * problem because the hyperthreads are usually enumerated after the
+	 * primary cores.
+	 */
+	ncpus = boot_cpu_data.x86_max_cores;
+	if (!ncpus) {
+		pr_warn("x86_max_cores == zero !?!?");
+		ncpus = 1;
+	}
+
+	__max_logical_packages = DIV_ROUND_UP(total_cpus, ncpus);
+
+	/*
+	 * Possibly larger than what we need as the number of apic ids per
+	 * package can be smaller than the actual used apic ids.
+	 */
+	max_physical_pkg_id = DIV_ROUND_UP(MAX_LOCAL_APIC, ncpus);
+	size = max_physical_pkg_id * sizeof(unsigned int);
+	physical_to_logical_pkg = kmalloc(size, GFP_KERNEL);
+	memset(physical_to_logical_pkg, 0xff, size);
+	size = BITS_TO_LONGS(max_physical_pkg_id) * sizeof(unsigned long);
+	physical_package_map = kzalloc(size, GFP_KERNEL);
+	size = BITS_TO_LONGS(__max_logical_packages) * sizeof(unsigned long);
+	logical_package_map = kzalloc(size, GFP_KERNEL);
+
+	pr_info("Max logical packages: %u\n", __max_logical_packages);
+
+	for_each_present_cpu(cpu) {
+		unsigned int apicid = apic->cpu_present_to_apicid(cpu);
+
+		if (apicid == BAD_APICID || !apic->apic_id_valid(apicid))
+			continue;
+		if (!topology_update_package_map(apicid, cpu))
+			continue;
+		pr_warn("CPU %u APICId %x disabled\n", cpu, apicid);
+		per_cpu(x86_bios_cpu_apicid, cpu) = BAD_APICID;
+		set_cpu_possible(cpu, false);
+		set_cpu_present(cpu, false);
+	}
+}
+
 void __init smp_store_boot_cpu_info(void)
 {
 	int id = 0; /* CPU 0 */
@@ -258,6 +375,7 @@ void __init smp_store_boot_cpu_info(void
 
 	*c = boot_cpu_data;
 	c->cpu_index = id;
+	smp_init_package_map();
 }
 
 /*
--- zfcpdump-kernel-4.4.orig/arch/x86/kernel/stacktrace.c
+++ zfcpdump-kernel-4.4/arch/x86/kernel/stacktrace.c
@@ -5,7 +5,7 @@
  */
 #include <linux/sched.h>
 #include <linux/stacktrace.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/uaccess.h>
 #include <asm/stacktrace.h>
 
--- zfcpdump-kernel-4.4.orig/arch/x86/kernel/sysfb_efi.c
+++ zfcpdump-kernel-4.4/arch/x86/kernel/sysfb_efi.c
@@ -106,14 +106,24 @@ static int __init efifb_set_system(const
 					continue;
 				for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
 					resource_size_t start, end;
+					unsigned long flags;
+
+					flags = pci_resource_flags(dev, i);
+					if (!(flags & IORESOURCE_MEM))
+						continue;
+
+					if (flags & IORESOURCE_UNSET)
+						continue;
+
+					if (pci_resource_len(dev, i) == 0)
+						continue;
 
 					start = pci_resource_start(dev, i);
-					if (start == 0)
-						break;
 					end = pci_resource_end(dev, i);
 					if (screen_info.lfb_base >= start &&
 					    screen_info.lfb_base < end) {
 						found_bar = 1;
+						break;
 					}
 				}
 			}
--- zfcpdump-kernel-4.4.orig/arch/x86/kernel/traps.c
+++ zfcpdump-kernel-4.4/arch/x86/kernel/traps.c
@@ -21,7 +21,7 @@
 #include <linux/kdebug.h>
 #include <linux/kgdb.h>
 #include <linux/kernel.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/ptrace.h>
 #include <linux/uprobes.h>
 #include <linux/string.h>
@@ -109,6 +109,12 @@ static inline void preempt_conditional_c
 	preempt_count_dec();
 }
 
+/*
+ * In IST context, we explicitly disable preemption.  This serves two
+ * purposes: it makes it much less likely that we would accidentally
+ * schedule in IST context and it will force a warning if we somehow
+ * manage to schedule by accident.
+ */
 void ist_enter(struct pt_regs *regs)
 {
 	if (user_mode(regs)) {
@@ -123,13 +129,7 @@ void ist_enter(struct pt_regs *regs)
 		rcu_nmi_enter();
 	}
 
-	/*
-	 * We are atomic because we're on the IST stack; or we're on
-	 * x86_32, in which case we still shouldn't schedule; or we're
-	 * on x86_64 and entered from user mode, in which case we're
-	 * still atomic unless ist_begin_non_atomic is called.
-	 */
-	preempt_count_add(HARDIRQ_OFFSET);
+	preempt_disable();
 
 	/* This code is a bit fragile.  Test it. */
 	RCU_LOCKDEP_WARN(!rcu_is_watching(), "ist_enter didn't work");
@@ -137,7 +137,7 @@ void ist_enter(struct pt_regs *regs)
 
 void ist_exit(struct pt_regs *regs)
 {
-	preempt_count_sub(HARDIRQ_OFFSET);
+	preempt_enable_no_resched();
 
 	if (!user_mode(regs))
 		rcu_nmi_exit();
@@ -168,7 +168,7 @@ void ist_begin_non_atomic(struct pt_regs
 	BUG_ON((unsigned long)(current_top_of_stack() -
 			       current_stack_pointer()) >= THREAD_SIZE);
 
-	preempt_count_sub(HARDIRQ_OFFSET);
+	preempt_enable_no_resched();
 }
 
 /**
@@ -178,7 +178,7 @@ void ist_begin_non_atomic(struct pt_regs
  */
 void ist_end_non_atomic(void)
 {
-	preempt_count_add(HARDIRQ_OFFSET);
+	preempt_disable();
 }
 
 static nokprobe_inline int
--- zfcpdump-kernel-4.4.orig/arch/x86/kernel/tsc.c
+++ zfcpdump-kernel-4.4/arch/x86/kernel/tsc.c
@@ -3,7 +3,7 @@
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/init.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/timer.h>
 #include <linux/acpi_pmtmr.h>
 #include <linux/cpufreq.h>
@@ -43,6 +43,11 @@ static DEFINE_STATIC_KEY_FALSE(__use_tsc
 
 int tsc_clocksource_reliable;
 
+static u32 art_to_tsc_numerator;
+static u32 art_to_tsc_denominator;
+static u64 art_to_tsc_offset;
+struct clocksource *art_related_clocksource;
+
 /*
  * Use a ring-buffer like data structure, where a writer advances the head by
  * writing a new data entry and a reader advances the tail when it observes a
@@ -964,6 +969,37 @@ core_initcall(cpufreq_tsc);
 
 #endif /* CONFIG_CPU_FREQ */
 
+#define ART_CPUID_LEAF (0x15)
+#define ART_MIN_DENOMINATOR (1)
+
+
+/*
+ * If ART is present detect the numerator:denominator to convert to TSC
+ */
+static void detect_art(void)
+{
+	unsigned int unused[2];
+
+	if (boot_cpu_data.cpuid_level < ART_CPUID_LEAF)
+		return;
+
+	cpuid(ART_CPUID_LEAF, &art_to_tsc_denominator,
+	      &art_to_tsc_numerator, unused, unused+1);
+
+	/* Don't enable ART in a VM, non-stop TSC required */
+	if (boot_cpu_has(X86_FEATURE_HYPERVISOR) ||
+	    !boot_cpu_has(X86_FEATURE_NONSTOP_TSC) ||
+	    art_to_tsc_denominator < ART_MIN_DENOMINATOR)
+		return;
+
+	if (rdmsrl_safe(MSR_IA32_TSC_ADJUST, &art_to_tsc_offset))
+		return;
+
+	/* Make this sticky over multiple CPU init calls */
+	setup_force_cpu_cap(X86_FEATURE_ART);
+}
+
+
 /* clocksource code */
 
 static struct clocksource clocksource_tsc;
@@ -1071,6 +1107,25 @@ int unsynchronized_tsc(void)
 	return 0;
 }
 
+/*
+ * Convert ART to TSC given numerator/denominator found in detect_art()
+ */
+struct system_counterval_t convert_art_to_tsc(cycle_t art)
+{
+	u64 tmp, res, rem;
+
+	rem = do_div(art, art_to_tsc_denominator);
+
+	res = art * art_to_tsc_numerator;
+	tmp = rem * art_to_tsc_numerator;
+
+	do_div(tmp, art_to_tsc_denominator);
+	res += tmp + art_to_tsc_offset;
+
+	return (struct system_counterval_t) {.cs = art_related_clocksource,
+			.cycles = res};
+}
+EXPORT_SYMBOL(convert_art_to_tsc);
 
 static void tsc_refine_calibration_work(struct work_struct *work);
 static DECLARE_DELAYED_WORK(tsc_irqwork, tsc_refine_calibration_work);
@@ -1142,6 +1197,8 @@ static void tsc_refine_calibration_work(
 		(unsigned long)tsc_khz % 1000);
 
 out:
+	if (boot_cpu_has(X86_FEATURE_ART))
+		art_related_clocksource = &clocksource_tsc;
 	clocksource_register_khz(&clocksource_tsc, tsc_khz);
 }
 
@@ -1237,6 +1294,8 @@ void __init tsc_init(void)
 		mark_tsc_unstable("TSCs unsynchronized");
 
 	check_system_tsc_reliable();
+
+	detect_art();
 }
 
 #ifdef CONFIG_SMP
--- zfcpdump-kernel-4.4.orig/arch/x86/kernel/tsc_msr.c
+++ zfcpdump-kernel-4.4/arch/x86/kernel/tsc_msr.c
@@ -92,7 +92,7 @@ unsigned long try_msr_calibrate_tsc(void
 
 	if (freq_desc_tables[cpu_index].msr_plat) {
 		rdmsr(MSR_PLATFORM_INFO, lo, hi);
-		ratio = (lo >> 8) & 0x1f;
+		ratio = (lo >> 8) & 0xff;
 	} else {
 		rdmsr(MSR_IA32_PERF_STATUS, lo, hi);
 		ratio = (hi >> 8) & 0x1f;
--- zfcpdump-kernel-4.4.orig/arch/x86/kernel/uprobes.c
+++ zfcpdump-kernel-4.4/arch/x86/kernel/uprobes.c
@@ -357,20 +357,22 @@ static void riprel_analyze(struct arch_u
 		*cursor &= 0xfe;
 	}
 	/*
-	 * Similar treatment for VEX3 prefix.
-	 * TODO: add XOP/EVEX treatment when insn decoder supports them
+	 * Similar treatment for VEX3/EVEX prefix.
+	 * TODO: add XOP treatment when insn decoder supports them
 	 */
-	if (insn->vex_prefix.nbytes == 3) {
+	if (insn->vex_prefix.nbytes >= 3) {
 		/*
 		 * vex2:     c5    rvvvvLpp   (has no b bit)
 		 * vex3/xop: c4/8f rxbmmmmm wvvvvLpp
 		 * evex:     62    rxbR00mm wvvvv1pp zllBVaaa
-		 *   (evex will need setting of both b and x since
-		 *   in non-sib encoding evex.x is 4th bit of MODRM.rm)
-		 * Setting VEX3.b (setting because it has inverted meaning):
+		 * Setting VEX3.b (setting because it has inverted meaning).
+		 * Setting EVEX.x since (in non-SIB encoding) EVEX.x
+		 * is the 4th bit of MODRM.rm, and needs the same treatment.
+		 * For VEX3-encoded insns, VEX3.x value has no effect in
+		 * non-SIB encoding, the change is superfluous but harmless.
 		 */
 		cursor = auprobe->insn + insn_offset_vex_prefix(insn) + 1;
-		*cursor |= 0x20;
+		*cursor |= 0x60;
 	}
 
 	/*
@@ -415,12 +417,10 @@ static void riprel_analyze(struct arch_u
 
 	reg = MODRM_REG(insn);	/* Fetch modrm.reg */
 	reg2 = 0xff;		/* Fetch vex.vvvv */
-	if (insn->vex_prefix.nbytes == 2)
-		reg2 = insn->vex_prefix.bytes[1];
-	else if (insn->vex_prefix.nbytes == 3)
+	if (insn->vex_prefix.nbytes)
 		reg2 = insn->vex_prefix.bytes[2];
 	/*
-	 * TODO: add XOP, EXEV vvvv reading.
+	 * TODO: add XOP vvvv reading.
 	 *
 	 * vex.vvvv field is in bits 6-3, bits are inverted.
 	 * But in 32-bit mode, high-order bit may be ignored.
--- zfcpdump-kernel-4.4.orig/arch/x86/kernel/verify_cpu.S
+++ zfcpdump-kernel-4.4/arch/x86/kernel/verify_cpu.S
@@ -30,7 +30,7 @@
  * 	appropriately. Either display a message or halt.
  */
 
-#include <asm/cpufeature.h>
+#include <asm/cpufeatures.h>
 #include <asm/msr-index.h>
 
 verify_cpu:
--- zfcpdump-kernel-4.4.orig/arch/x86/kernel/x8664_ksyms_64.c
+++ zfcpdump-kernel-4.4/arch/x86/kernel/x8664_ksyms_64.c
@@ -1,7 +1,7 @@
 /* Exports for assembly files.
    All C exports should go in the respective C files. */
 
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/smp.h>
 
 #include <net/checksum.h>
--- zfcpdump-kernel-4.4.orig/arch/x86/kernel/x86_init.c
+++ zfcpdump-kernel-4.4/arch/x86/kernel/x86_init.c
@@ -5,7 +5,7 @@
  */
 #include <linux/init.h>
 #include <linux/ioport.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/pci.h>
 
 #include <asm/bios_ebda.h>
--- zfcpdump-kernel-4.4.orig/arch/x86/kvm/cpuid.c
+++ zfcpdump-kernel-4.4/arch/x86/kvm/cpuid.c
@@ -509,6 +509,7 @@ static inline int __do_cpuid_ent(struct
 			do_cpuid_1_ent(&entry[i], function, idx);
 			if (idx == 1) {
 				entry[i].eax &= kvm_supported_word10_x86_features;
+				cpuid_mask(&entry[i].eax, 10);
 				entry[i].ebx = 0;
 				if (entry[i].eax & (F(XSAVES)|F(XSAVEC)))
 					entry[i].ebx =
--- zfcpdump-kernel-4.4.orig/arch/x86/kvm/emulate.c
+++ zfcpdump-kernel-4.4/arch/x86/kvm/emulate.c
@@ -650,10 +650,10 @@ static __always_inline int __linearize(s
 	u16 sel;
 
 	la = seg_base(ctxt, addr.seg) + addr.ea;
-	*linear = la;
 	*max_size = 0;
 	switch (mode) {
 	case X86EMUL_MODE_PROT64:
+		*linear = la;
 		if (is_noncanonical_address(la))
 			goto bad;
 
@@ -662,6 +662,7 @@ static __always_inline int __linearize(s
 			goto bad;
 		break;
 	default:
+		*linear = la = (u32)la;
 		usable = ctxt->ops->get_segment(ctxt, &sel, &desc, NULL,
 						addr.seg);
 		if (!usable)
@@ -689,7 +690,6 @@ static __always_inline int __linearize(s
 			if (size > *max_size)
 				goto bad;
 		}
-		la &= (u32)-1;
 		break;
 	}
 	if (insn_aligned(ctxt, size) && ((la & (size - 1)) != 0))
--- zfcpdump-kernel-4.4.orig/arch/x86/kvm/hyperv.c
+++ zfcpdump-kernel-4.4/arch/x86/kvm/hyperv.c
@@ -23,13 +23,646 @@
 
 #include "x86.h"
 #include "lapic.h"
+#include "ioapic.h"
 #include "hyperv.h"
 
 #include <linux/kvm_host.h>
+#include <linux/highmem.h>
+#include <asm/apicdef.h>
 #include <trace/events/kvm.h>
 
 #include "trace.h"
 
+static inline u64 synic_read_sint(struct kvm_vcpu_hv_synic *synic, int sint)
+{
+	return atomic64_read(&synic->sint[sint]);
+}
+
+static inline int synic_get_sint_vector(u64 sint_value)
+{
+	if (sint_value & HV_SYNIC_SINT_MASKED)
+		return -1;
+	return sint_value & HV_SYNIC_SINT_VECTOR_MASK;
+}
+
+static bool synic_has_vector_connected(struct kvm_vcpu_hv_synic *synic,
+				      int vector)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(synic->sint); i++) {
+		if (synic_get_sint_vector(synic_read_sint(synic, i)) == vector)
+			return true;
+	}
+	return false;
+}
+
+static bool synic_has_vector_auto_eoi(struct kvm_vcpu_hv_synic *synic,
+				     int vector)
+{
+	int i;
+	u64 sint_value;
+
+	for (i = 0; i < ARRAY_SIZE(synic->sint); i++) {
+		sint_value = synic_read_sint(synic, i);
+		if (synic_get_sint_vector(sint_value) == vector &&
+		    sint_value & HV_SYNIC_SINT_AUTO_EOI)
+			return true;
+	}
+	return false;
+}
+
+static int synic_set_sint(struct kvm_vcpu_hv_synic *synic, int sint, u64 data)
+{
+	int vector;
+
+	vector = data & HV_SYNIC_SINT_VECTOR_MASK;
+	if (vector < 16)
+		return 1;
+	/*
+	 * Guest may configure multiple SINTs to use the same vector, so
+	 * we maintain a bitmap of vectors handled by synic, and a
+	 * bitmap of vectors with auto-eoi behavior.  The bitmaps are
+	 * updated here, and atomically queried on fast paths.
+	 */
+
+	atomic64_set(&synic->sint[sint], data);
+
+	if (synic_has_vector_connected(synic, vector))
+		__set_bit(vector, synic->vec_bitmap);
+	else
+		__clear_bit(vector, synic->vec_bitmap);
+
+	if (synic_has_vector_auto_eoi(synic, vector))
+		__set_bit(vector, synic->auto_eoi_bitmap);
+	else
+		__clear_bit(vector, synic->auto_eoi_bitmap);
+
+	/* Load SynIC vectors into EOI exit bitmap */
+	kvm_make_request(KVM_REQ_SCAN_IOAPIC, synic_to_vcpu(synic));
+	return 0;
+}
+
+static struct kvm_vcpu_hv_synic *synic_get(struct kvm *kvm, u32 vcpu_id)
+{
+	struct kvm_vcpu *vcpu;
+	struct kvm_vcpu_hv_synic *synic;
+
+	if (vcpu_id >= atomic_read(&kvm->online_vcpus))
+		return NULL;
+	vcpu = kvm_get_vcpu(kvm, vcpu_id);
+	if (!vcpu)
+		return NULL;
+	synic = vcpu_to_synic(vcpu);
+	return (synic->active) ? synic : NULL;
+}
+
+static void synic_clear_sint_msg_pending(struct kvm_vcpu_hv_synic *synic,
+					u32 sint)
+{
+	struct kvm_vcpu *vcpu = synic_to_vcpu(synic);
+	struct page *page;
+	gpa_t gpa;
+	struct hv_message *msg;
+	struct hv_message_page *msg_page;
+
+	gpa = synic->msg_page & PAGE_MASK;
+	page = kvm_vcpu_gfn_to_page(vcpu, gpa >> PAGE_SHIFT);
+	if (is_error_page(page)) {
+		vcpu_err(vcpu, "Hyper-V SynIC can't get msg page, gpa 0x%llx\n",
+			 gpa);
+		return;
+	}
+	msg_page = kmap_atomic(page);
+
+	msg = &msg_page->sint_message[sint];
+	msg->header.message_flags.msg_pending = 0;
+
+	kunmap_atomic(msg_page);
+	kvm_release_page_dirty(page);
+	kvm_vcpu_mark_page_dirty(vcpu, gpa >> PAGE_SHIFT);
+}
+
+static void kvm_hv_notify_acked_sint(struct kvm_vcpu *vcpu, u32 sint)
+{
+	struct kvm *kvm = vcpu->kvm;
+	struct kvm_vcpu_hv_synic *synic = vcpu_to_synic(vcpu);
+	struct kvm_vcpu_hv *hv_vcpu = vcpu_to_hv_vcpu(vcpu);
+	struct kvm_vcpu_hv_stimer *stimer;
+	int gsi, idx, stimers_pending;
+
+	vcpu_debug(vcpu, "Hyper-V SynIC acked sint %d\n", sint);
+
+	if (synic->msg_page & HV_SYNIC_SIMP_ENABLE)
+		synic_clear_sint_msg_pending(synic, sint);
+
+	/* Try to deliver pending Hyper-V SynIC timers messages */
+	stimers_pending = 0;
+	for (idx = 0; idx < ARRAY_SIZE(hv_vcpu->stimer); idx++) {
+		stimer = &hv_vcpu->stimer[idx];
+		if (stimer->msg_pending &&
+		    (stimer->config & HV_STIMER_ENABLE) &&
+		    HV_STIMER_SINT(stimer->config) == sint) {
+			set_bit(stimer->index,
+				hv_vcpu->stimer_pending_bitmap);
+			stimers_pending++;
+		}
+	}
+	if (stimers_pending)
+		kvm_make_request(KVM_REQ_HV_STIMER, vcpu);
+
+	idx = srcu_read_lock(&kvm->irq_srcu);
+	gsi = atomic_read(&synic->sint_to_gsi[sint]);
+	if (gsi != -1)
+		kvm_notify_acked_gsi(kvm, gsi);
+	srcu_read_unlock(&kvm->irq_srcu, idx);
+}
+
+static void synic_exit(struct kvm_vcpu_hv_synic *synic, u32 msr)
+{
+	struct kvm_vcpu *vcpu = synic_to_vcpu(synic);
+	struct kvm_vcpu_hv *hv_vcpu = &vcpu->arch.hyperv;
+
+	hv_vcpu->exit.type = KVM_EXIT_HYPERV_SYNIC;
+	hv_vcpu->exit.u.synic.msr = msr;
+	hv_vcpu->exit.u.synic.control = synic->control;
+	hv_vcpu->exit.u.synic.evt_page = synic->evt_page;
+	hv_vcpu->exit.u.synic.msg_page = synic->msg_page;
+
+	kvm_make_request(KVM_REQ_HV_EXIT, vcpu);
+}
+
+static int synic_set_msr(struct kvm_vcpu_hv_synic *synic,
+			 u32 msr, u64 data, bool host)
+{
+	struct kvm_vcpu *vcpu = synic_to_vcpu(synic);
+	int ret;
+
+	if (!synic->active)
+		return 1;
+
+	vcpu_debug(vcpu, "Hyper-V SynIC set msr 0x%x 0x%llx host %d\n",
+		   msr, data, host);
+	ret = 0;
+	switch (msr) {
+	case HV_X64_MSR_SCONTROL:
+		synic->control = data;
+		if (!host)
+			synic_exit(synic, msr);
+		break;
+	case HV_X64_MSR_SVERSION:
+		if (!host) {
+			ret = 1;
+			break;
+		}
+		synic->version = data;
+		break;
+	case HV_X64_MSR_SIEFP:
+		if (data & HV_SYNIC_SIEFP_ENABLE)
+			if (kvm_clear_guest(vcpu->kvm,
+					    data & PAGE_MASK, PAGE_SIZE)) {
+				ret = 1;
+				break;
+			}
+		synic->evt_page = data;
+		if (!host)
+			synic_exit(synic, msr);
+		break;
+	case HV_X64_MSR_SIMP:
+		if (data & HV_SYNIC_SIMP_ENABLE)
+			if (kvm_clear_guest(vcpu->kvm,
+					    data & PAGE_MASK, PAGE_SIZE)) {
+				ret = 1;
+				break;
+			}
+		synic->msg_page = data;
+		if (!host)
+			synic_exit(synic, msr);
+		break;
+	case HV_X64_MSR_EOM: {
+		int i;
+
+		for (i = 0; i < ARRAY_SIZE(synic->sint); i++)
+			kvm_hv_notify_acked_sint(vcpu, i);
+		break;
+	}
+	case HV_X64_MSR_SINT0 ... HV_X64_MSR_SINT15:
+		ret = synic_set_sint(synic, msr - HV_X64_MSR_SINT0, data);
+		break;
+	default:
+		ret = 1;
+		break;
+	}
+	return ret;
+}
+
+static int synic_get_msr(struct kvm_vcpu_hv_synic *synic, u32 msr, u64 *pdata)
+{
+	int ret;
+
+	if (!synic->active)
+		return 1;
+
+	ret = 0;
+	switch (msr) {
+	case HV_X64_MSR_SCONTROL:
+		*pdata = synic->control;
+		break;
+	case HV_X64_MSR_SVERSION:
+		*pdata = synic->version;
+		break;
+	case HV_X64_MSR_SIEFP:
+		*pdata = synic->evt_page;
+		break;
+	case HV_X64_MSR_SIMP:
+		*pdata = synic->msg_page;
+		break;
+	case HV_X64_MSR_EOM:
+		*pdata = 0;
+		break;
+	case HV_X64_MSR_SINT0 ... HV_X64_MSR_SINT15:
+		*pdata = atomic64_read(&synic->sint[msr - HV_X64_MSR_SINT0]);
+		break;
+	default:
+		ret = 1;
+		break;
+	}
+	return ret;
+}
+
+int synic_set_irq(struct kvm_vcpu_hv_synic *synic, u32 sint)
+{
+	struct kvm_vcpu *vcpu = synic_to_vcpu(synic);
+	struct kvm_lapic_irq irq;
+	int ret, vector;
+
+	if (sint >= ARRAY_SIZE(synic->sint))
+		return -EINVAL;
+
+	vector = synic_get_sint_vector(synic_read_sint(synic, sint));
+	if (vector < 0)
+		return -ENOENT;
+
+	memset(&irq, 0, sizeof(irq));
+	irq.dest_id = kvm_apic_id(vcpu->arch.apic);
+	irq.dest_mode = APIC_DEST_PHYSICAL;
+	irq.delivery_mode = APIC_DM_FIXED;
+	irq.vector = vector;
+	irq.level = 1;
+
+	ret = kvm_irq_delivery_to_apic(vcpu->kvm, NULL, &irq, NULL);
+	vcpu_debug(vcpu, "Hyper-V SynIC set irq ret %d\n", ret);
+	return ret;
+}
+
+int kvm_hv_synic_set_irq(struct kvm *kvm, u32 vcpu_id, u32 sint)
+{
+	struct kvm_vcpu_hv_synic *synic;
+
+	synic = synic_get(kvm, vcpu_id);
+	if (!synic)
+		return -EINVAL;
+
+	return synic_set_irq(synic, sint);
+}
+
+void kvm_hv_synic_send_eoi(struct kvm_vcpu *vcpu, int vector)
+{
+	struct kvm_vcpu_hv_synic *synic = vcpu_to_synic(vcpu);
+	int i;
+
+	vcpu_debug(vcpu, "Hyper-V SynIC send eoi vec %d\n", vector);
+
+	for (i = 0; i < ARRAY_SIZE(synic->sint); i++)
+		if (synic_get_sint_vector(synic_read_sint(synic, i)) == vector)
+			kvm_hv_notify_acked_sint(vcpu, i);
+}
+
+static int kvm_hv_set_sint_gsi(struct kvm *kvm, u32 vcpu_id, u32 sint, int gsi)
+{
+	struct kvm_vcpu_hv_synic *synic;
+
+	synic = synic_get(kvm, vcpu_id);
+	if (!synic)
+		return -EINVAL;
+
+	if (sint >= ARRAY_SIZE(synic->sint_to_gsi))
+		return -EINVAL;
+
+	atomic_set(&synic->sint_to_gsi[sint], gsi);
+	return 0;
+}
+
+void kvm_hv_irq_routing_update(struct kvm *kvm)
+{
+	struct kvm_irq_routing_table *irq_rt;
+	struct kvm_kernel_irq_routing_entry *e;
+	u32 gsi;
+
+	irq_rt = srcu_dereference_check(kvm->irq_routing, &kvm->irq_srcu,
+					lockdep_is_held(&kvm->irq_lock));
+
+	for (gsi = 0; gsi < irq_rt->nr_rt_entries; gsi++) {
+		hlist_for_each_entry(e, &irq_rt->map[gsi], link) {
+			if (e->type == KVM_IRQ_ROUTING_HV_SINT)
+				kvm_hv_set_sint_gsi(kvm, e->hv_sint.vcpu,
+						    e->hv_sint.sint, gsi);
+		}
+	}
+}
+
+static void synic_init(struct kvm_vcpu_hv_synic *synic)
+{
+	int i;
+
+	memset(synic, 0, sizeof(*synic));
+	synic->version = HV_SYNIC_VERSION_1;
+	for (i = 0; i < ARRAY_SIZE(synic->sint); i++) {
+		atomic64_set(&synic->sint[i], HV_SYNIC_SINT_MASKED);
+		atomic_set(&synic->sint_to_gsi[i], -1);
+	}
+}
+
+static u64 get_time_ref_counter(struct kvm *kvm)
+{
+	return div_u64(get_kernel_ns() + kvm->arch.kvmclock_offset, 100);
+}
+
+static void stimer_mark_expired(struct kvm_vcpu_hv_stimer *stimer,
+				bool vcpu_kick)
+{
+	struct kvm_vcpu *vcpu = stimer_to_vcpu(stimer);
+
+	set_bit(stimer->index,
+		vcpu_to_hv_vcpu(vcpu)->stimer_pending_bitmap);
+	kvm_make_request(KVM_REQ_HV_STIMER, vcpu);
+	if (vcpu_kick)
+		kvm_vcpu_kick(vcpu);
+}
+
+static void stimer_stop(struct kvm_vcpu_hv_stimer *stimer)
+{
+	hrtimer_cancel(&stimer->timer);
+}
+
+static void stimer_cleanup(struct kvm_vcpu_hv_stimer *stimer)
+{
+	struct kvm_vcpu *vcpu = stimer_to_vcpu(stimer);
+
+	stimer_stop(stimer);
+	clear_bit(stimer->index,
+		  vcpu_to_hv_vcpu(vcpu)->stimer_pending_bitmap);
+	stimer->msg_pending = false;
+}
+
+static enum hrtimer_restart stimer_timer_callback(struct hrtimer *timer)
+{
+	struct kvm_vcpu_hv_stimer *stimer;
+
+	stimer = container_of(timer, struct kvm_vcpu_hv_stimer, timer);
+	stimer_mark_expired(stimer, true);
+
+	return HRTIMER_NORESTART;
+}
+
+static void stimer_restart(struct kvm_vcpu_hv_stimer *stimer)
+{
+	u64 time_now;
+	ktime_t ktime_now;
+	u64 remainder;
+
+	time_now = get_time_ref_counter(stimer_to_vcpu(stimer)->kvm);
+	ktime_now = ktime_get();
+
+	div64_u64_rem(time_now - stimer->exp_time, stimer->count, &remainder);
+	stimer->exp_time = time_now + (stimer->count - remainder);
+
+	hrtimer_start(&stimer->timer,
+		      ktime_add_ns(ktime_now,
+				   100 * (stimer->exp_time - time_now)),
+		      HRTIMER_MODE_ABS);
+}
+
+static int stimer_start(struct kvm_vcpu_hv_stimer *stimer)
+{
+	u64 time_now;
+	ktime_t ktime_now;
+
+	time_now = get_time_ref_counter(stimer_to_vcpu(stimer)->kvm);
+	ktime_now = ktime_get();
+
+	if (stimer->config & HV_STIMER_PERIODIC) {
+		if (stimer->count == 0)
+			return -EINVAL;
+
+		stimer->exp_time = time_now + stimer->count;
+		hrtimer_start(&stimer->timer,
+			      ktime_add_ns(ktime_now, 100 * stimer->count),
+			      HRTIMER_MODE_ABS);
+		return 0;
+	}
+	stimer->exp_time = stimer->count;
+	if (time_now >= stimer->count) {
+		/*
+		 * Expire timer according to Hypervisor Top-Level Functional
+		 * specification v4(15.3.1):
+		 * "If a one shot is enabled and the specified count is in
+		 * the past, it will expire immediately."
+		 */
+		stimer_mark_expired(stimer, false);
+		return 0;
+	}
+
+	hrtimer_start(&stimer->timer,
+		      ktime_add_ns(ktime_now, 100 * (stimer->count - time_now)),
+		      HRTIMER_MODE_ABS);
+	return 0;
+}
+
+static int stimer_set_config(struct kvm_vcpu_hv_stimer *stimer, u64 config,
+			     bool host)
+{
+	if (stimer->count == 0 || HV_STIMER_SINT(config) == 0)
+		config &= ~HV_STIMER_ENABLE;
+	stimer->config = config;
+	stimer_cleanup(stimer);
+	if (stimer->config & HV_STIMER_ENABLE)
+		if (stimer_start(stimer))
+			return 1;
+	return 0;
+}
+
+static int stimer_set_count(struct kvm_vcpu_hv_stimer *stimer, u64 count,
+			    bool host)
+{
+	stimer->count = count;
+
+	stimer_cleanup(stimer);
+	if (stimer->count == 0)
+		stimer->config &= ~HV_STIMER_ENABLE;
+	else if (stimer->config & HV_STIMER_AUTOENABLE) {
+		stimer->config |= HV_STIMER_ENABLE;
+		if (stimer_start(stimer))
+			return 1;
+	}
+
+	return 0;
+}
+
+static int stimer_get_config(struct kvm_vcpu_hv_stimer *stimer, u64 *pconfig)
+{
+	*pconfig = stimer->config;
+	return 0;
+}
+
+static int stimer_get_count(struct kvm_vcpu_hv_stimer *stimer, u64 *pcount)
+{
+	*pcount = stimer->count;
+	return 0;
+}
+
+static int synic_deliver_msg(struct kvm_vcpu_hv_synic *synic, u32 sint,
+			     struct hv_message *src_msg)
+{
+	struct kvm_vcpu *vcpu = synic_to_vcpu(synic);
+	struct page *page;
+	gpa_t gpa;
+	struct hv_message *dst_msg;
+	int r;
+	struct hv_message_page *msg_page;
+
+	if (!(synic->msg_page & HV_SYNIC_SIMP_ENABLE))
+		return -ENOENT;
+
+	gpa = synic->msg_page & PAGE_MASK;
+	page = kvm_vcpu_gfn_to_page(vcpu, gpa >> PAGE_SHIFT);
+	if (is_error_page(page))
+		return -EFAULT;
+
+	msg_page = kmap_atomic(page);
+	dst_msg = &msg_page->sint_message[sint];
+	if (sync_cmpxchg(&dst_msg->header.message_type, HVMSG_NONE,
+			 src_msg->header.message_type) != HVMSG_NONE) {
+		dst_msg->header.message_flags.msg_pending = 1;
+		r = -EAGAIN;
+	} else {
+		memcpy(&dst_msg->u.payload, &src_msg->u.payload,
+		       src_msg->header.payload_size);
+		dst_msg->header.message_type = src_msg->header.message_type;
+		dst_msg->header.payload_size = src_msg->header.payload_size;
+		r = synic_set_irq(synic, sint);
+		if (r >= 1)
+			r = 0;
+		else if (r == 0)
+			r = -EFAULT;
+	}
+	kunmap_atomic(msg_page);
+	kvm_release_page_dirty(page);
+	kvm_vcpu_mark_page_dirty(vcpu, gpa >> PAGE_SHIFT);
+	return r;
+}
+
+static void stimer_send_msg(struct kvm_vcpu_hv_stimer *stimer)
+{
+	struct kvm_vcpu *vcpu = stimer_to_vcpu(stimer);
+	struct hv_message *msg = &stimer->msg;
+	struct hv_timer_message_payload *payload =
+			(struct hv_timer_message_payload *)&msg->u.payload;
+	int r;
+
+	stimer->msg_pending = true;
+	payload->expiration_time = stimer->exp_time;
+	payload->delivery_time = get_time_ref_counter(vcpu->kvm);
+	r = synic_deliver_msg(vcpu_to_synic(vcpu),
+			      HV_STIMER_SINT(stimer->config), msg);
+	if (!r)
+		stimer->msg_pending = false;
+}
+
+static void stimer_expiration(struct kvm_vcpu_hv_stimer *stimer)
+{
+	stimer_send_msg(stimer);
+	if (!(stimer->config & HV_STIMER_PERIODIC))
+		stimer->config |= ~HV_STIMER_ENABLE;
+	else
+		stimer_restart(stimer);
+}
+
+void kvm_hv_process_stimers(struct kvm_vcpu *vcpu)
+{
+	struct kvm_vcpu_hv *hv_vcpu = vcpu_to_hv_vcpu(vcpu);
+	struct kvm_vcpu_hv_stimer *stimer;
+	u64 time_now;
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(hv_vcpu->stimer); i++)
+		if (test_and_clear_bit(i, hv_vcpu->stimer_pending_bitmap)) {
+			stimer = &hv_vcpu->stimer[i];
+			stimer_stop(stimer);
+			if (stimer->config & HV_STIMER_ENABLE) {
+				time_now = get_time_ref_counter(vcpu->kvm);
+				if (time_now >= stimer->exp_time)
+					stimer_expiration(stimer);
+			}
+		}
+}
+
+void kvm_hv_vcpu_uninit(struct kvm_vcpu *vcpu)
+{
+	struct kvm_vcpu_hv *hv_vcpu = vcpu_to_hv_vcpu(vcpu);
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(hv_vcpu->stimer); i++)
+		stimer_cleanup(&hv_vcpu->stimer[i]);
+}
+
+static void stimer_prepare_msg(struct kvm_vcpu_hv_stimer *stimer)
+{
+	struct hv_message *msg = &stimer->msg;
+	struct hv_timer_message_payload *payload =
+			(struct hv_timer_message_payload *)&msg->u.payload;
+
+	memset(&msg->header, 0, sizeof(msg->header));
+	msg->header.message_type = HVMSG_TIMER_EXPIRED;
+	msg->header.payload_size = sizeof(*payload);
+
+	payload->timer_index = stimer->index;
+	payload->expiration_time = 0;
+	payload->delivery_time = 0;
+}
+
+static void stimer_init(struct kvm_vcpu_hv_stimer *stimer, int timer_index)
+{
+	memset(stimer, 0, sizeof(*stimer));
+	stimer->index = timer_index;
+	hrtimer_init(&stimer->timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
+	stimer->timer.function = stimer_timer_callback;
+	stimer_prepare_msg(stimer);
+}
+
+void kvm_hv_vcpu_init(struct kvm_vcpu *vcpu)
+{
+	struct kvm_vcpu_hv *hv_vcpu = vcpu_to_hv_vcpu(vcpu);
+	int i;
+
+	synic_init(&hv_vcpu->synic);
+
+	bitmap_zero(hv_vcpu->stimer_pending_bitmap, HV_SYNIC_STIMER_COUNT);
+	for (i = 0; i < ARRAY_SIZE(hv_vcpu->stimer); i++)
+		stimer_init(&hv_vcpu->stimer[i], i);
+}
+
+int kvm_hv_activate_synic(struct kvm_vcpu *vcpu)
+{
+	/*
+	 * Hyper-V SynIC auto EOI SINT's are
+	 * not compatible with APICV, so deactivate APICV
+	 */
+	kvm_vcpu_deactivate_apicv(vcpu);
+	vcpu_to_synic(vcpu)->active = true;
+	return 0;
+}
+
 static bool kvm_hv_msr_partition_wide(u32 msr)
 {
 	bool r = false;
@@ -226,6 +859,31 @@ static int kvm_hv_set_msr(struct kvm_vcp
 			return 1;
 		hv->runtime_offset = data - current_task_runtime_100ns();
 		break;
+	case HV_X64_MSR_SCONTROL:
+	case HV_X64_MSR_SVERSION:
+	case HV_X64_MSR_SIEFP:
+	case HV_X64_MSR_SIMP:
+	case HV_X64_MSR_EOM:
+	case HV_X64_MSR_SINT0 ... HV_X64_MSR_SINT15:
+		return synic_set_msr(vcpu_to_synic(vcpu), msr, data, host);
+	case HV_X64_MSR_STIMER0_CONFIG:
+	case HV_X64_MSR_STIMER1_CONFIG:
+	case HV_X64_MSR_STIMER2_CONFIG:
+	case HV_X64_MSR_STIMER3_CONFIG: {
+		int timer_index = (msr - HV_X64_MSR_STIMER0_CONFIG)/2;
+
+		return stimer_set_config(vcpu_to_stimer(vcpu, timer_index),
+					 data, host);
+	}
+	case HV_X64_MSR_STIMER0_COUNT:
+	case HV_X64_MSR_STIMER1_COUNT:
+	case HV_X64_MSR_STIMER2_COUNT:
+	case HV_X64_MSR_STIMER3_COUNT: {
+		int timer_index = (msr - HV_X64_MSR_STIMER0_COUNT)/2;
+
+		return stimer_set_count(vcpu_to_stimer(vcpu, timer_index),
+					data, host);
+	}
 	default:
 		vcpu_unimpl(vcpu, "Hyper-V uhandled wrmsr: 0x%x data 0x%llx\n",
 			    msr, data);
@@ -248,11 +906,9 @@ static int kvm_hv_get_msr_pw(struct kvm_
 	case HV_X64_MSR_HYPERCALL:
 		data = hv->hv_hypercall;
 		break;
-	case HV_X64_MSR_TIME_REF_COUNT: {
-		data =
-		     div_u64(get_kernel_ns() + kvm->arch.kvmclock_offset, 100);
+	case HV_X64_MSR_TIME_REF_COUNT:
+		data = get_time_ref_counter(kvm);
 		break;
-	}
 	case HV_X64_MSR_REFERENCE_TSC:
 		data = hv->hv_tsc_page;
 		break;
@@ -304,6 +960,31 @@ static int kvm_hv_get_msr(struct kvm_vcp
 	case HV_X64_MSR_VP_RUNTIME:
 		data = current_task_runtime_100ns() + hv->runtime_offset;
 		break;
+	case HV_X64_MSR_SCONTROL:
+	case HV_X64_MSR_SVERSION:
+	case HV_X64_MSR_SIEFP:
+	case HV_X64_MSR_SIMP:
+	case HV_X64_MSR_EOM:
+	case HV_X64_MSR_SINT0 ... HV_X64_MSR_SINT15:
+		return synic_get_msr(vcpu_to_synic(vcpu), msr, pdata);
+	case HV_X64_MSR_STIMER0_CONFIG:
+	case HV_X64_MSR_STIMER1_CONFIG:
+	case HV_X64_MSR_STIMER2_CONFIG:
+	case HV_X64_MSR_STIMER3_CONFIG: {
+		int timer_index = (msr - HV_X64_MSR_STIMER0_CONFIG)/2;
+
+		return stimer_get_config(vcpu_to_stimer(vcpu, timer_index),
+					 pdata);
+	}
+	case HV_X64_MSR_STIMER0_COUNT:
+	case HV_X64_MSR_STIMER1_COUNT:
+	case HV_X64_MSR_STIMER2_COUNT:
+	case HV_X64_MSR_STIMER3_COUNT: {
+		int timer_index = (msr - HV_X64_MSR_STIMER0_COUNT)/2;
+
+		return stimer_get_count(vcpu_to_stimer(vcpu, timer_index),
+					pdata);
+	}
 	default:
 		vcpu_unimpl(vcpu, "Hyper-V unhandled rdmsr: 0x%x\n", msr);
 		return 1;
@@ -384,7 +1065,7 @@ int kvm_hv_hypercall(struct kvm_vcpu *vc
 	trace_kvm_hv_hypercall(code, fast, rep_cnt, rep_idx, ingpa, outgpa);
 
 	switch (code) {
-	case HV_X64_HV_NOTIFY_LONG_SPIN_WAIT:
+	case HVCALL_NOTIFY_LONG_SPIN_WAIT:
 		kvm_vcpu_on_spin(vcpu);
 		break;
 	default:
--- zfcpdump-kernel-4.4.orig/arch/x86/kvm/hyperv.h
+++ zfcpdump-kernel-4.4/arch/x86/kvm/hyperv.h
@@ -24,9 +24,64 @@
 #ifndef __ARCH_X86_KVM_HYPERV_H__
 #define __ARCH_X86_KVM_HYPERV_H__
 
+static inline struct kvm_vcpu_hv *vcpu_to_hv_vcpu(struct kvm_vcpu *vcpu)
+{
+	return &vcpu->arch.hyperv;
+}
+
+static inline struct kvm_vcpu *hv_vcpu_to_vcpu(struct kvm_vcpu_hv *hv_vcpu)
+{
+	struct kvm_vcpu_arch *arch;
+
+	arch = container_of(hv_vcpu, struct kvm_vcpu_arch, hyperv);
+	return container_of(arch, struct kvm_vcpu, arch);
+}
+
+static inline struct kvm_vcpu_hv_synic *vcpu_to_synic(struct kvm_vcpu *vcpu)
+{
+	return &vcpu->arch.hyperv.synic;
+}
+
+static inline struct kvm_vcpu *synic_to_vcpu(struct kvm_vcpu_hv_synic *synic)
+{
+	return hv_vcpu_to_vcpu(container_of(synic, struct kvm_vcpu_hv, synic));
+}
+
 int kvm_hv_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data, bool host);
 int kvm_hv_get_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata);
+
 bool kvm_hv_hypercall_enabled(struct kvm *kvm);
 int kvm_hv_hypercall(struct kvm_vcpu *vcpu);
 
+void kvm_hv_irq_routing_update(struct kvm *kvm);
+int kvm_hv_synic_set_irq(struct kvm *kvm, u32 vcpu_id, u32 sint);
+void kvm_hv_synic_send_eoi(struct kvm_vcpu *vcpu, int vector);
+int kvm_hv_activate_synic(struct kvm_vcpu *vcpu);
+
+void kvm_hv_vcpu_init(struct kvm_vcpu *vcpu);
+void kvm_hv_vcpu_uninit(struct kvm_vcpu *vcpu);
+
+static inline struct kvm_vcpu_hv_stimer *vcpu_to_stimer(struct kvm_vcpu *vcpu,
+							int timer_index)
+{
+	return &vcpu_to_hv_vcpu(vcpu)->stimer[timer_index];
+}
+
+static inline struct kvm_vcpu *stimer_to_vcpu(struct kvm_vcpu_hv_stimer *stimer)
+{
+	struct kvm_vcpu_hv *hv_vcpu;
+
+	hv_vcpu = container_of(stimer - stimer->index, struct kvm_vcpu_hv,
+			       stimer[0]);
+	return hv_vcpu_to_vcpu(hv_vcpu);
+}
+
+static inline bool kvm_hv_has_stimer_pending(struct kvm_vcpu *vcpu)
+{
+	return !bitmap_empty(vcpu->arch.hyperv.stimer_pending_bitmap,
+			     HV_SYNIC_STIMER_COUNT);
+}
+
+void kvm_hv_process_stimers(struct kvm_vcpu *vcpu);
+
 #endif
--- zfcpdump-kernel-4.4.orig/arch/x86/kvm/i8254.c
+++ zfcpdump-kernel-4.4/arch/x86/kvm/i8254.c
@@ -245,7 +245,7 @@ static void kvm_pit_ack_irq(struct kvm_i
 		 * PIC is being reset.  Handle it gracefully here
 		 */
 		atomic_inc(&ps->pending);
-	else if (value > 0)
+	else if (value > 0 && ps->reinject)
 		/* in this case, we had multiple outstanding pit interrupts
 		 * that we needed to inject.  Reinject
 		 */
@@ -288,7 +288,9 @@ static void pit_do_work(struct kthread_w
 	 * last one has been acked.
 	 */
 	spin_lock(&ps->inject_lock);
-	if (ps->irq_ack) {
+	if (!ps->reinject)
+		inject = 1;
+	else if (ps->irq_ack) {
 		ps->irq_ack = 0;
 		inject = 1;
 	}
@@ -317,10 +319,10 @@ static enum hrtimer_restart pit_timer_fn
 	struct kvm_kpit_state *ps = container_of(data, struct kvm_kpit_state, timer);
 	struct kvm_pit *pt = ps->kvm->arch.vpit;
 
-	if (ps->reinject || !atomic_read(&ps->pending)) {
+	if (ps->reinject)
 		atomic_inc(&ps->pending);
-		queue_kthread_work(&pt->worker, &pt->expired);
-	}
+
+	queue_kthread_work(&pt->worker, &pt->expired);
 
 	if (ps->is_periodic) {
 		hrtimer_add_expires_ns(&ps->timer, ps->period);
--- zfcpdump-kernel-4.4.orig/arch/x86/kvm/ioapic.c
+++ zfcpdump-kernel-4.4/arch/x86/kvm/ioapic.c
@@ -233,7 +233,7 @@ static void kvm_ioapic_inject_all(struct
 }
 
 
-void kvm_ioapic_scan_entry(struct kvm_vcpu *vcpu, u64 *eoi_exit_bitmap)
+void kvm_ioapic_scan_entry(struct kvm_vcpu *vcpu, ulong *ioapic_handled_vectors)
 {
 	struct kvm_ioapic *ioapic = vcpu->kvm->arch.vioapic;
 	union kvm_ioapic_redirect_entry *e;
@@ -250,7 +250,7 @@ void kvm_ioapic_scan_entry(struct kvm_vc
 			    (e->fields.trig_mode == IOAPIC_EDGE_TRIG &&
 			     kvm_apic_pending_eoi(vcpu, e->fields.vector)))
 				__set_bit(e->fields.vector,
-					(unsigned long *)eoi_exit_bitmap);
+					  ioapic_handled_vectors);
 		}
 	}
 	spin_unlock(&ioapic->lock);
--- zfcpdump-kernel-4.4.orig/arch/x86/kvm/ioapic.h
+++ zfcpdump-kernel-4.4/arch/x86/kvm/ioapic.h
@@ -121,7 +121,8 @@ int kvm_irq_delivery_to_apic(struct kvm
 		struct kvm_lapic_irq *irq, unsigned long *dest_map);
 int kvm_get_ioapic(struct kvm *kvm, struct kvm_ioapic_state *state);
 int kvm_set_ioapic(struct kvm *kvm, struct kvm_ioapic_state *state);
-void kvm_ioapic_scan_entry(struct kvm_vcpu *vcpu, u64 *eoi_exit_bitmap);
-void kvm_scan_ioapic_routes(struct kvm_vcpu *vcpu, u64 *eoi_exit_bitmap);
-
+void kvm_ioapic_scan_entry(struct kvm_vcpu *vcpu,
+			   ulong *ioapic_handled_vectors);
+void kvm_scan_ioapic_routes(struct kvm_vcpu *vcpu,
+			    ulong *ioapic_handled_vectors);
 #endif
--- zfcpdump-kernel-4.4.orig/arch/x86/kvm/irq.c
+++ zfcpdump-kernel-4.4/arch/x86/kvm/irq.c
@@ -76,7 +76,7 @@ int kvm_cpu_has_injectable_intr(struct k
 	if (kvm_cpu_has_extint(v))
 		return 1;
 
-	if (kvm_vcpu_apic_vid_enabled(v))
+	if (kvm_vcpu_apicv_active(v))
 		return 0;
 
 	return kvm_apic_has_interrupt(v) != -1; /* LAPIC */
--- zfcpdump-kernel-4.4.orig/arch/x86/kvm/irq_comm.c
+++ zfcpdump-kernel-4.4/arch/x86/kvm/irq_comm.c
@@ -33,6 +33,8 @@
 
 #include "lapic.h"
 
+#include "hyperv.h"
+
 static int kvm_set_pic_irq(struct kvm_kernel_irq_routing_entry *e,
 			   struct kvm *kvm, int irq_source_id, int level,
 			   bool line_status)
@@ -219,6 +221,16 @@ void kvm_fire_mask_notifiers(struct kvm
 	srcu_read_unlock(&kvm->irq_srcu, idx);
 }
 
+static int kvm_hv_set_sint(struct kvm_kernel_irq_routing_entry *e,
+		    struct kvm *kvm, int irq_source_id, int level,
+		    bool line_status)
+{
+	if (!level)
+		return -1;
+
+	return kvm_hv_synic_set_irq(kvm, e->hv_sint.vcpu, e->hv_sint.sint);
+}
+
 int kvm_set_routing_entry(struct kvm_kernel_irq_routing_entry *e,
 			  const struct kvm_irq_routing_entry *ue)
 {
@@ -257,6 +269,11 @@ int kvm_set_routing_entry(struct kvm_ker
 		e->msi.address_hi = ue->u.msi.address_hi;
 		e->msi.data = ue->u.msi.data;
 		break;
+	case KVM_IRQ_ROUTING_HV_SINT:
+		e->set = kvm_hv_set_sint;
+		e->hv_sint.vcpu = ue->u.hv_sint.vcpu;
+		e->hv_sint.sint = ue->u.hv_sint.sint;
+		break;
 	default:
 		goto out;
 	}
@@ -332,14 +349,8 @@ int kvm_setup_empty_irq_routing(struct k
 	return kvm_set_irq_routing(kvm, empty_routing, 0, 0);
 }
 
-void kvm_arch_irq_routing_update(struct kvm *kvm)
-{
-	if (ioapic_in_kernel(kvm) || !irqchip_in_kernel(kvm))
-		return;
-	kvm_make_scan_ioapic_request(kvm);
-}
-
-void kvm_scan_ioapic_routes(struct kvm_vcpu *vcpu, u64 *eoi_exit_bitmap)
+void kvm_scan_ioapic_routes(struct kvm_vcpu *vcpu,
+			    ulong *ioapic_handled_vectors)
 {
 	struct kvm *kvm = vcpu->kvm;
 	struct kvm_kernel_irq_routing_entry *entry;
@@ -369,9 +380,26 @@ void kvm_scan_ioapic_routes(struct kvm_v
 				u32 vector = entry->msi.data & 0xff;
 
 				__set_bit(vector,
-					  (unsigned long *) eoi_exit_bitmap);
+					  ioapic_handled_vectors);
 			}
 		}
 	}
 	srcu_read_unlock(&kvm->irq_srcu, idx);
 }
+
+int kvm_arch_set_irq(struct kvm_kernel_irq_routing_entry *irq, struct kvm *kvm,
+		     int irq_source_id, int level, bool line_status)
+{
+	switch (irq->type) {
+	case KVM_IRQ_ROUTING_HV_SINT:
+		return kvm_hv_set_sint(irq, kvm, irq_source_id, level,
+				       line_status);
+	default:
+		return -EWOULDBLOCK;
+	}
+}
+
+void kvm_arch_irq_routing_update(struct kvm *kvm)
+{
+	kvm_hv_irq_routing_update(kvm);
+}
--- zfcpdump-kernel-4.4.orig/arch/x86/kvm/lapic.c
+++ zfcpdump-kernel-4.4/arch/x86/kvm/lapic.c
@@ -41,6 +41,7 @@
 #include "trace.h"
 #include "x86.h"
 #include "cpuid.h"
+#include "hyperv.h"
 
 #ifndef CONFIG_X86_64
 #define mod_64(x, y) ((x) - (y) * div64_u64(x, y))
@@ -128,11 +129,6 @@ static inline int apic_enabled(struct kv
 	(LVT_MASK | APIC_MODE_MASK | APIC_INPUT_POLARITY | \
 	 APIC_LVT_REMOTE_IRR | APIC_LVT_LEVEL_TRIGGER)
 
-static inline int kvm_apic_id(struct kvm_lapic *apic)
-{
-	return (kvm_apic_get_reg(apic, APIC_ID) >> 24) & 0xff;
-}
-
 /* The logical map is definitely wrong if we have multiple
  * modes at the same time.  (Physical map is always right.)
  */
@@ -379,7 +375,8 @@ static inline int apic_find_highest_irr(
 	if (!apic->irr_pending)
 		return -1;
 
-	kvm_x86_ops->sync_pir_to_irr(apic->vcpu);
+	if (apic->vcpu->arch.apicv_active)
+		kvm_x86_ops->sync_pir_to_irr(apic->vcpu);
 	result = apic_search_irr(apic);
 	ASSERT(result == -1 || result >= 16);
 
@@ -392,7 +389,7 @@ static inline void apic_clear_irr(int ve
 
 	vcpu = apic->vcpu;
 
-	if (unlikely(kvm_vcpu_apic_vid_enabled(vcpu))) {
+	if (unlikely(vcpu->arch.apicv_active)) {
 		/* try to update RVI */
 		apic_clear_vector(vec, apic->regs + APIC_IRR);
 		kvm_make_request(KVM_REQ_EVENT, vcpu);
@@ -418,7 +415,7 @@ static inline void apic_set_isr(int vec,
 	 * because the processor can modify ISR under the hood.  Instead
 	 * just set SVI.
 	 */
-	if (unlikely(kvm_x86_ops->hwapic_isr_update))
+	if (unlikely(vcpu->arch.apicv_active))
 		kvm_x86_ops->hwapic_isr_update(vcpu->kvm, vec);
 	else {
 		++apic->isr_count;
@@ -466,7 +463,7 @@ static inline void apic_clear_isr(int ve
 	 * on the other hand isr_count and highest_isr_cache are unused
 	 * and must be left alone.
 	 */
-	if (unlikely(kvm_x86_ops->hwapic_isr_update))
+	if (unlikely(vcpu->arch.apicv_active))
 		kvm_x86_ops->hwapic_isr_update(vcpu->kvm,
 					       apic_find_highest_isr(apic));
 	else {
@@ -852,7 +849,7 @@ static int __apic_accept_irq(struct kvm_
 				apic_clear_vector(vector, apic->regs + APIC_TMR);
 		}
 
-		if (kvm_x86_ops->deliver_posted_interrupt)
+		if (vcpu->arch.apicv_active)
 			kvm_x86_ops->deliver_posted_interrupt(vcpu, vector);
 		else {
 			apic_set_irr(vector, apic);
@@ -932,7 +929,7 @@ int kvm_apic_compare_prio(struct kvm_vcp
 
 static bool kvm_ioapic_handles_vector(struct kvm_lapic *apic, int vector)
 {
-	return test_bit(vector, (ulong *)apic->vcpu->arch.eoi_exit_bitmap);
+	return test_bit(vector, apic->vcpu->arch.ioapic_handled_vectors);
 }
 
 static void kvm_ioapic_send_eoi(struct kvm_lapic *apic, int vector)
@@ -974,6 +971,9 @@ static int apic_set_eoi(struct kvm_lapic
 	apic_clear_isr(vector, apic);
 	apic_update_ppr(apic);
 
+	if (test_bit(vector, vcpu_to_synic(apic->vcpu)->vec_bitmap))
+		kvm_hv_synic_send_eoi(apic->vcpu, vector);
+
 	kvm_ioapic_send_eoi(apic, vector);
 	kvm_make_request(KVM_REQ_EVENT, apic->vcpu);
 	return vector;
@@ -1225,7 +1225,7 @@ static bool lapic_timer_int_injected(str
 		int vec = reg & APIC_VECTOR_MASK;
 		void *bitmap = apic->regs + APIC_ISR;
 
-		if (kvm_x86_ops->deliver_posted_interrupt)
+		if (vcpu->arch.apicv_active)
 			bitmap = apic->regs + APIC_IRR;
 
 		if (apic_test_vector(vec, bitmap))
@@ -1693,8 +1693,8 @@ void kvm_lapic_reset(struct kvm_vcpu *vc
 		apic_set_reg(apic, APIC_ISR + 0x10 * i, 0);
 		apic_set_reg(apic, APIC_TMR + 0x10 * i, 0);
 	}
-	apic->irr_pending = kvm_vcpu_apic_vid_enabled(vcpu);
-	apic->isr_count = kvm_x86_ops->hwapic_isr_update ? 1 : 0;
+	apic->irr_pending = vcpu->arch.apicv_active;
+	apic->isr_count = vcpu->arch.apicv_active ? 1 : 0;
 	apic->highest_isr_cache = -1;
 	update_divide_count(apic);
 	atomic_set(&apic->lapic_timer.pending, 0);
@@ -1883,6 +1883,12 @@ int kvm_get_apic_interrupt(struct kvm_vc
 	apic_set_isr(vector, apic);
 	apic_update_ppr(apic);
 	apic_clear_irr(vector, apic);
+
+	if (test_bit(vector, vcpu_to_synic(vcpu)->auto_eoi_bitmap)) {
+		apic_clear_isr(vector, apic);
+		apic_update_ppr(apic);
+	}
+
 	return vector;
 }
 
@@ -1906,15 +1912,15 @@ void kvm_apic_post_state_restore(struct
 	update_divide_count(apic);
 	start_apic_timer(apic);
 	apic->irr_pending = true;
-	apic->isr_count = kvm_x86_ops->hwapic_isr_update ?
+	apic->isr_count = vcpu->arch.apicv_active ?
 				1 : count_vectors(apic->regs + APIC_ISR);
 	apic->highest_isr_cache = -1;
-	if (kvm_x86_ops->hwapic_irr_update)
+	if (vcpu->arch.apicv_active) {
 		kvm_x86_ops->hwapic_irr_update(vcpu,
 				apic_find_highest_irr(apic));
-	if (unlikely(kvm_x86_ops->hwapic_isr_update))
 		kvm_x86_ops->hwapic_isr_update(vcpu->kvm,
 				apic_find_highest_isr(apic));
+	}
 	kvm_make_request(KVM_REQ_EVENT, vcpu);
 	if (ioapic_in_kernel(vcpu->kvm))
 		kvm_rtc_eoi_tracking_restore_one(vcpu);
--- zfcpdump-kernel-4.4.orig/arch/x86/kvm/lapic.h
+++ zfcpdump-kernel-4.4/arch/x86/kvm/lapic.h
@@ -143,9 +143,9 @@ static inline int apic_x2apic_mode(struc
 	return apic->vcpu->arch.apic_base & X2APIC_ENABLE;
 }
 
-static inline bool kvm_vcpu_apic_vid_enabled(struct kvm_vcpu *vcpu)
+static inline bool kvm_vcpu_apicv_active(struct kvm_vcpu *vcpu)
 {
-	return kvm_x86_ops->cpu_uses_apicv(vcpu);
+	return vcpu->arch.apic && vcpu->arch.apicv_active;
 }
 
 static inline bool kvm_apic_has_events(struct kvm_vcpu *vcpu)
@@ -164,6 +164,11 @@ static inline int kvm_lapic_latched_init
 	return kvm_vcpu_has_lapic(vcpu) && test_bit(KVM_APIC_INIT, &vcpu->arch.apic->pending_events);
 }
 
+static inline int kvm_apic_id(struct kvm_lapic *apic)
+{
+	return (kvm_apic_get_reg(apic, APIC_ID) >> 24) & 0xff;
+}
+
 bool kvm_apic_pending_eoi(struct kvm_vcpu *vcpu, int vector);
 
 void wait_lapic_expire(struct kvm_vcpu *vcpu);
--- zfcpdump-kernel-4.4.orig/arch/x86/kvm/mmu.c
+++ zfcpdump-kernel-4.4/arch/x86/kvm/mmu.c
@@ -3754,13 +3754,15 @@ static void reset_rsvds_bits_mask_ept(st
 void
 reset_shadow_zero_bits_mask(struct kvm_vcpu *vcpu, struct kvm_mmu *context)
 {
+	bool uses_nx = context->nx || context->base_role.smep_andnot_wp;
+
 	/*
 	 * Passing "true" to the last argument is okay; it adds a check
 	 * on bit 8 of the SPTEs which KVM doesn't use anyway.
 	 */
 	__reset_rsvds_bits_mask(vcpu, &context->shadow_zero_check,
 				boot_cpu_data.x86_phys_bits,
-				context->shadow_root_level, context->nx,
+				context->shadow_root_level, uses_nx,
 				guest_cpuid_has_gbpages(vcpu), is_pse(vcpu),
 				true);
 }
--- zfcpdump-kernel-4.4.orig/arch/x86/kvm/mtrr.c
+++ zfcpdump-kernel-4.4/arch/x86/kvm/mtrr.c
@@ -44,8 +44,6 @@ static bool msr_mtrr_valid(unsigned msr)
 	case MSR_MTRRdefType:
 	case MSR_IA32_CR_PAT:
 		return true;
-	case 0x2f8:
-		return true;
 	}
 	return false;
 }
@@ -541,6 +539,7 @@ static void mtrr_lookup_var_start(struct
 
 	iter->fixed = false;
 	iter->start_max = iter->start;
+	iter->range = NULL;
 	iter->range = list_prepare_entry(iter->range, &mtrr_state->head, node);
 
 	__mtrr_lookup_var_next(iter);
--- zfcpdump-kernel-4.4.orig/arch/x86/kvm/paging_tmpl.h
+++ zfcpdump-kernel-4.4/arch/x86/kvm/paging_tmpl.h
@@ -249,7 +249,7 @@ static int FNAME(update_accessed_dirty_b
 			return ret;
 
 		kvm_vcpu_mark_page_dirty(vcpu, table_gfn);
-		walker->ptes[level] = pte;
+		walker->ptes[level - 1] = pte;
 	}
 	return 0;
 }
--- zfcpdump-kernel-4.4.orig/arch/x86/kvm/svm.c
+++ zfcpdump-kernel-4.4/arch/x86/kvm/svm.c
@@ -3561,12 +3561,16 @@ static void svm_set_virtual_x2apic_mode(
 	return;
 }
 
-static int svm_cpu_uses_apicv(struct kvm_vcpu *vcpu)
+static bool svm_get_enable_apicv(void)
+{
+	return false;
+}
+
+static void svm_refresh_apicv_exec_ctrl(struct kvm_vcpu *vcpu)
 {
-	return 0;
 }
 
-static void svm_load_eoi_exitmap(struct kvm_vcpu *vcpu)
+static void svm_load_eoi_exitmap(struct kvm_vcpu *vcpu, u64 *eoi_exit_bitmap)
 {
 	return;
 }
@@ -4328,7 +4332,8 @@ static struct kvm_x86_ops svm_x86_ops =
 	.enable_irq_window = enable_irq_window,
 	.update_cr8_intercept = update_cr8_intercept,
 	.set_virtual_x2apic_mode = svm_set_virtual_x2apic_mode,
-	.cpu_uses_apicv = svm_cpu_uses_apicv,
+	.get_enable_apicv = svm_get_enable_apicv,
+	.refresh_apicv_exec_ctrl = svm_refresh_apicv_exec_ctrl,
 	.load_eoi_exitmap = svm_load_eoi_exitmap,
 	.sync_pir_to_irr = svm_sync_pir_to_irr,
 
--- zfcpdump-kernel-4.4.orig/arch/x86/kvm/trace.h
+++ zfcpdump-kernel-4.4/arch/x86/kvm/trace.h
@@ -268,7 +268,7 @@ TRACE_EVENT(kvm_inj_virq,
 #define kvm_trace_sym_exc						\
 	EXS(DE), EXS(DB), EXS(BP), EXS(OF), EXS(BR), EXS(UD), EXS(NM),	\
 	EXS(DF), EXS(TS), EXS(NP), EXS(SS), EXS(GP), EXS(PF),		\
-	EXS(MF), EXS(MC)
+	EXS(MF), EXS(AC), EXS(MC)
 
 /*
  * Tracepoint for kvm interrupt injection:
--- zfcpdump-kernel-4.4.orig/arch/x86/kvm/vmx.c
+++ zfcpdump-kernel-4.4/arch/x86/kvm/vmx.c
@@ -19,6 +19,7 @@
 #include "irq.h"
 #include "mmu.h"
 #include "cpuid.h"
+#include "lapic.h"
 
 #include <linux/kvm_host.h>
 #include <linux/module.h>
@@ -408,6 +409,7 @@ struct nested_vmx {
 	struct list_head vmcs02_pool;
 	int vmcs02_num;
 	u64 vmcs01_tsc_offset;
+	bool change_vmcs01_virtual_x2apic_mode;
 	/* L2 must run next, and mustn't decide to exit to L1. */
 	bool nested_run_pending;
 	/*
@@ -595,6 +597,8 @@ struct vcpu_vmx {
 	/* Support for PML */
 #define PML_ENTITY_NUM		512
 	struct page *pml_pg;
+
+	u64 current_tsc_ratio;
 };
 
 enum segment_cache_field {
@@ -862,7 +866,6 @@ static void kvm_cpu_vmxon(u64 addr);
 static void kvm_cpu_vmxoff(void);
 static bool vmx_mpx_supported(void);
 static bool vmx_xsaves_supported(void);
-static int vmx_cpu_uses_apicv(struct kvm_vcpu *vcpu);
 static int vmx_set_tss_addr(struct kvm *kvm, unsigned int addr);
 static void vmx_set_segment(struct kvm_vcpu *vcpu,
 			    struct kvm_segment *var, int seg);
@@ -870,7 +873,6 @@ static void vmx_get_segment(struct kvm_v
 			    struct kvm_segment *var, int seg);
 static bool guest_state_valid(struct kvm_vcpu *vcpu);
 static u32 vmx_segment_access_rights(struct kvm_segment *var);
-static void vmx_sync_pir_to_irr_dummy(struct kvm_vcpu *vcpu);
 static void copy_vmcs12_to_shadow(struct vcpu_vmx *vmx);
 static void copy_shadow_to_vmcs12(struct vcpu_vmx *vmx);
 static int alloc_identity_pagetable(struct kvm *kvm);
@@ -1746,6 +1748,13 @@ static void add_atomic_switch_msr(struct
 			return;
 		}
 		break;
+	case MSR_IA32_PEBS_ENABLE:
+		/* PEBS needs a quiescent period after being disabled (to write
+		 * a record).  Disabling PEBS through VMX MSR swapping doesn't
+		 * provide that period, so a CPU could write host's record into
+		 * guest's memory.
+		 */
+		wrmsrl(MSR_IA32_PEBS_ENABLE, 0);
 	}
 
 	for (i = 0; i < m->nr; ++i)
@@ -1783,26 +1792,31 @@ static void reload_tss(void)
 
 static bool update_transition_efer(struct vcpu_vmx *vmx, int efer_offset)
 {
-	u64 guest_efer;
-	u64 ignore_bits;
+	u64 guest_efer = vmx->vcpu.arch.efer;
+	u64 ignore_bits = 0;
 
-	guest_efer = vmx->vcpu.arch.efer;
+	if (!enable_ept) {
+		/*
+		 * NX is needed to handle CR0.WP=1, CR4.SMEP=1.  Testing
+		 * host CPUID is more efficient than testing guest CPUID
+		 * or CR4.  Host SMEP is anyway a requirement for guest SMEP.
+		 */
+		if (boot_cpu_has(X86_FEATURE_SMEP))
+			guest_efer |= EFER_NX;
+		else if (!(guest_efer & EFER_NX))
+			ignore_bits |= EFER_NX;
+	}
 
 	/*
-	 * NX is emulated; LMA and LME handled by hardware; SCE meaningless
-	 * outside long mode
+	 * LMA and LME handled by hardware; SCE meaningless outside long mode.
 	 */
-	ignore_bits = EFER_NX | EFER_SCE;
+	ignore_bits |= EFER_SCE;
 #ifdef CONFIG_X86_64
 	ignore_bits |= EFER_LMA | EFER_LME;
 	/* SCE is meaningful only in long mode on Intel */
 	if (guest_efer & EFER_LMA)
 		ignore_bits &= ~(u64)EFER_SCE;
 #endif
-	guest_efer &= ~ignore_bits;
-	guest_efer |= host_efer & ignore_bits;
-	vmx->guest_msrs[efer_offset].data = guest_efer;
-	vmx->guest_msrs[efer_offset].mask = ~ignore_bits;
 
 	clear_atomic_switch_msr(vmx, MSR_EFER);
 
@@ -1813,16 +1827,21 @@ static bool update_transition_efer(struc
 	 */
 	if (cpu_has_load_ia32_efer ||
 	    (enable_ept && ((vmx->vcpu.arch.efer ^ host_efer) & EFER_NX))) {
-		guest_efer = vmx->vcpu.arch.efer;
 		if (!(guest_efer & EFER_LMA))
 			guest_efer &= ~EFER_LME;
 		if (guest_efer != host_efer)
 			add_atomic_switch_msr(vmx, MSR_EFER,
 					      guest_efer, host_efer);
 		return false;
-	}
+	} else {
+		guest_efer &= ~ignore_bits;
+		guest_efer |= host_efer & ignore_bits;
 
-	return true;
+		vmx->guest_msrs[efer_offset].data = guest_efer;
+		vmx->guest_msrs[efer_offset].mask = ~ignore_bits;
+
+		return true;
+	}
 }
 
 static unsigned long segment_base(u16 selector)
@@ -2062,14 +2081,16 @@ static void vmx_vcpu_load(struct kvm_vcp
 		rdmsrl(MSR_IA32_SYSENTER_ESP, sysenter_esp);
 		vmcs_writel(HOST_IA32_SYSENTER_ESP, sysenter_esp); /* 22.2.3 */
 
-		/* Setup TSC multiplier */
-		if (cpu_has_vmx_tsc_scaling())
-			vmcs_write64(TSC_MULTIPLIER,
-				     vcpu->arch.tsc_scaling_ratio);
-
 		vmx->loaded_vmcs->cpu = cpu;
 	}
 
+	/* Setup TSC multiplier */
+	if (kvm_has_tsc_control &&
+	    vmx->current_tsc_ratio != vcpu->arch.tsc_scaling_ratio) {
+		vmx->current_tsc_ratio = vcpu->arch.tsc_scaling_ratio;
+		vmcs_write64(TSC_MULTIPLIER, vmx->current_tsc_ratio);
+	}
+
 	vmx_vcpu_pi_load(vcpu, cpu);
 }
 
@@ -2311,7 +2332,9 @@ static void vmx_set_msr_bitmap(struct kv
 
 	if (is_guest_mode(vcpu))
 		msr_bitmap = vmx_msr_bitmap_nested;
-	else if (vcpu->arch.apic_base & X2APIC_ENABLE) {
+	else if (cpu_has_secondary_exec_ctrls() &&
+		 (vmcs_read32(SECONDARY_VM_EXEC_CONTROL) &
+		  SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE)) {
 		if (is_long_mode(vcpu))
 			msr_bitmap = vmx_msr_bitmap_longmode_x2apic;
 		else
@@ -2498,7 +2521,7 @@ static void nested_vmx_setup_ctls_msrs(s
 	vmx->nested.nested_vmx_pinbased_ctls_high |=
 		PIN_BASED_ALWAYSON_WITHOUT_TRUE_MSR |
 		PIN_BASED_VMX_PREEMPTION_TIMER;
-	if (vmx_cpu_uses_apicv(&vmx->vcpu))
+	if (kvm_vcpu_apicv_active(&vmx->vcpu))
 		vmx->nested.nested_vmx_pinbased_ctls_high |=
 			PIN_BASED_POSTED_INTR;
 
@@ -2616,8 +2639,15 @@ static void nested_vmx_setup_ctls_msrs(s
 	} else
 		vmx->nested.nested_vmx_ept_caps = 0;
 
+	/*
+	 * Old versions of KVM use the single-context version without
+	 * checking for support, so declare that it is supported even
+	 * though it is treated as global context.  The alternative is
+	 * not failing the single-context invvpid, and it is worse.
+	 */
 	if (enable_vpid)
 		vmx->nested.nested_vmx_vpid_caps = VMX_VPID_INVVPID_BIT |
+				VMX_VPID_EXTENT_SINGLE_CONTEXT_BIT |
 				VMX_VPID_EXTENT_GLOBAL_CONTEXT_BIT;
 	else
 		vmx->nested.nested_vmx_vpid_caps = 0;
@@ -4462,9 +4492,9 @@ static void vmx_disable_intercept_msr_wr
 			msr, MSR_TYPE_W);
 }
 
-static int vmx_cpu_uses_apicv(struct kvm_vcpu *vcpu)
+static bool vmx_get_enable_apicv(void)
 {
-	return enable_apicv && lapic_in_kernel(vcpu);
+	return enable_apicv;
 }
 
 static int vmx_complete_nested_posted_interrupt(struct kvm_vcpu *vcpu)
@@ -4586,11 +4616,6 @@ static void vmx_sync_pir_to_irr(struct k
 	kvm_apic_update_irr(vcpu, vmx->pi_desc.pir);
 }
 
-static void vmx_sync_pir_to_irr_dummy(struct kvm_vcpu *vcpu)
-{
-	return;
-}
-
 /*
  * Set up the vmcs's constant host-state fields, i.e., host-state fields that
  * will not change in the lifetime of the guest.
@@ -4660,11 +4685,31 @@ static u32 vmx_pin_based_exec_ctrl(struc
 {
 	u32 pin_based_exec_ctrl = vmcs_config.pin_based_exec_ctrl;
 
-	if (!vmx_cpu_uses_apicv(&vmx->vcpu))
+	if (!kvm_vcpu_apicv_active(&vmx->vcpu))
 		pin_based_exec_ctrl &= ~PIN_BASED_POSTED_INTR;
 	return pin_based_exec_ctrl;
 }
 
+static void vmx_refresh_apicv_exec_ctrl(struct kvm_vcpu *vcpu)
+{
+	struct vcpu_vmx *vmx = to_vmx(vcpu);
+
+	vmcs_write32(PIN_BASED_VM_EXEC_CONTROL, vmx_pin_based_exec_ctrl(vmx));
+	if (cpu_has_secondary_exec_ctrls()) {
+		if (kvm_vcpu_apicv_active(vcpu))
+			vmcs_set_bits(SECONDARY_VM_EXEC_CONTROL,
+				      SECONDARY_EXEC_APIC_REGISTER_VIRT |
+				      SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY);
+		else
+			vmcs_clear_bits(SECONDARY_VM_EXEC_CONTROL,
+					SECONDARY_EXEC_APIC_REGISTER_VIRT |
+					SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY);
+	}
+
+	if (cpu_has_vmx_msr_bitmap())
+		vmx_set_msr_bitmap(vcpu);
+}
+
 static u32 vmx_exec_control(struct vcpu_vmx *vmx)
 {
 	u32 exec_control = vmcs_config.cpu_based_exec_ctrl;
@@ -4703,7 +4748,7 @@ static u32 vmx_secondary_exec_control(st
 		exec_control &= ~SECONDARY_EXEC_UNRESTRICTED_GUEST;
 	if (!ple_gap)
 		exec_control &= ~SECONDARY_EXEC_PAUSE_LOOP_EXITING;
-	if (!vmx_cpu_uses_apicv(&vmx->vcpu))
+	if (!kvm_vcpu_apicv_active(&vmx->vcpu))
 		exec_control &= ~(SECONDARY_EXEC_APIC_REGISTER_VIRT |
 				  SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY);
 	exec_control &= ~SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE;
@@ -4767,7 +4812,7 @@ static int vmx_vcpu_setup(struct vcpu_vm
 		vmcs_write32(SECONDARY_VM_EXEC_CONTROL,
 				vmx_secondary_exec_control(vmx));
 
-	if (vmx_cpu_uses_apicv(&vmx->vcpu)) {
+	if (kvm_vcpu_apicv_active(&vmx->vcpu)) {
 		vmcs_write64(EOI_EXIT_BITMAP0, 0);
 		vmcs_write64(EOI_EXIT_BITMAP1, 0);
 		vmcs_write64(EOI_EXIT_BITMAP2, 0);
@@ -4919,15 +4964,15 @@ static void vmx_vcpu_reset(struct kvm_vc
 
 	kvm_make_request(KVM_REQ_APIC_PAGE_RELOAD, vcpu);
 
-	if (vmx_cpu_uses_apicv(vcpu))
+	if (kvm_vcpu_apicv_active(vcpu))
 		memset(&vmx->pi_desc, 0, sizeof(struct pi_desc));
 
 	if (vmx->vpid != 0)
 		vmcs_write16(VIRTUAL_PROCESSOR_ID, vmx->vpid);
 
 	cr0 = X86_CR0_NW | X86_CR0_CD | X86_CR0_ET;
-	vmx_set_cr0(vcpu, cr0); /* enter rmode */
 	vmx->vcpu.arch.cr0 = cr0;
+	vmx_set_cr0(vcpu, cr0); /* enter rmode */
 	vmx_set_cr4(vcpu, 0);
 	vmx_set_efer(vcpu, 0);
 	vmx_fpu_activate(vcpu);
@@ -6203,15 +6248,6 @@ static __init int hardware_setup(void)
 		kvm_tsc_scaling_ratio_frac_bits = 48;
 	}
 
-	if (enable_apicv)
-		kvm_x86_ops->update_cr8_intercept = NULL;
-	else {
-		kvm_x86_ops->hwapic_irr_update = NULL;
-		kvm_x86_ops->hwapic_isr_update = NULL;
-		kvm_x86_ops->deliver_posted_interrupt = NULL;
-		kvm_x86_ops->sync_pir_to_irr = vmx_sync_pir_to_irr_dummy;
-	}
-
 	vmx_disable_intercept_for_msr(MSR_FS_BASE, false);
 	vmx_disable_intercept_for_msr(MSR_GS_BASE, false);
 	vmx_disable_intercept_for_msr(MSR_KERNEL_GS_BASE, true);
@@ -6227,23 +6263,20 @@ static __init int hardware_setup(void)
 
 	set_bit(0, vmx_vpid_bitmap); /* 0 is reserved for host */
 
-	if (enable_apicv) {
-		for (msr = 0x800; msr <= 0x8ff; msr++)
-			vmx_disable_intercept_msr_read_x2apic(msr);
+	for (msr = 0x800; msr <= 0x8ff; msr++)
+		vmx_disable_intercept_msr_read_x2apic(msr);
 
-		/* According SDM, in x2apic mode, the whole id reg is used.
-		 * But in KVM, it only use the highest eight bits. Need to
-		 * intercept it */
-		vmx_enable_intercept_msr_read_x2apic(0x802);
-		/* TMCCT */
-		vmx_enable_intercept_msr_read_x2apic(0x839);
-		/* TPR */
-		vmx_disable_intercept_msr_write_x2apic(0x808);
-		/* EOI */
-		vmx_disable_intercept_msr_write_x2apic(0x80b);
-		/* SELF-IPI */
-		vmx_disable_intercept_msr_write_x2apic(0x83f);
-	}
+	/* According SDM, in x2apic mode, the whole id reg is used.  But in
+	 * KVM, it only use the highest eight bits. Need to intercept it */
+	vmx_enable_intercept_msr_read_x2apic(0x802);
+	/* TMCCT */
+	vmx_enable_intercept_msr_read_x2apic(0x839);
+	/* TPR */
+	vmx_disable_intercept_msr_write_x2apic(0x808);
+	/* EOI */
+	vmx_disable_intercept_msr_write_x2apic(0x80b);
+	/* SELF-IPI */
+	vmx_disable_intercept_msr_write_x2apic(0x83f);
 
 	if (enable_ept) {
 		kvm_mmu_set_mask_ptes(0ull,
@@ -6551,7 +6584,13 @@ static int get_vmx_mem_address(struct kv
 
 	/* Checks for #GP/#SS exceptions. */
 	exn = false;
-	if (is_protmode(vcpu)) {
+	if (is_long_mode(vcpu)) {
+		/* Long mode: #GP(0)/#SS(0) if the memory address is in a
+		 * non-canonical form. This is the only check on the memory
+		 * destination for long mode!
+		 */
+		exn = is_noncanonical_address(*ret);
+	} else if (is_protmode(vcpu)) {
 		/* Protected mode: apply checks for segment validity in the
 		 * following order:
 		 * - segment type check (#GP(0) may be thrown)
@@ -6568,17 +6607,10 @@ static int get_vmx_mem_address(struct kv
 			 * execute-only code segment
 			 */
 			exn = ((s.type & 0xa) == 8);
-	}
-	if (exn) {
-		kvm_queue_exception_e(vcpu, GP_VECTOR, 0);
-		return 1;
-	}
-	if (is_long_mode(vcpu)) {
-		/* Long mode: #GP(0)/#SS(0) if the memory address is in a
-		 * non-canonical form. This is an only check for long mode.
-		 */
-		exn = is_noncanonical_address(*ret);
-	} else if (is_protmode(vcpu)) {
+		if (exn) {
+			kvm_queue_exception_e(vcpu, GP_VECTOR, 0);
+			return 1;
+		}
 		/* Protected mode: #GP(0)/#SS(0) if the segment is unusable.
 		 */
 		exn = (s.unusable != 0);
@@ -7319,6 +7351,7 @@ static int handle_invept(struct kvm_vcpu
 	if (!(types & (1UL << type))) {
 		nested_vmx_failValid(vcpu,
 				VMXERR_INVALID_OPERAND_TO_INVEPT_INVVPID);
+		skip_emulated_instruction(vcpu);
 		return 1;
 	}
 
@@ -7377,6 +7410,7 @@ static int handle_invvpid(struct kvm_vcp
 	if (!(types & (1UL << type))) {
 		nested_vmx_failValid(vcpu,
 			VMXERR_INVALID_OPERAND_TO_INVEPT_INVVPID);
+		skip_emulated_instruction(vcpu);
 		return 1;
 	}
 
@@ -7393,12 +7427,17 @@ static int handle_invvpid(struct kvm_vcp
 	}
 
 	switch (type) {
+	case VMX_VPID_EXTENT_SINGLE_CONTEXT:
+		/*
+		 * Old versions of KVM use the single-context version so we
+		 * have to support it; just treat it the same as all-context.
+		 */
 	case VMX_VPID_EXTENT_ALL_CONTEXT:
 		__vmx_flush_tlb(vcpu, to_vmx(vcpu)->nested.vpid02);
 		nested_vmx_succeed(vcpu);
 		break;
 	default:
-		/* Trap single context invalidation invvpid calls */
+		/* Trap individual address invalidation invvpid calls */
 		BUG_ON(1);
 		break;
 	}
@@ -8090,6 +8129,7 @@ static int vmx_handle_exit(struct kvm_vc
 	if ((vectoring_info & VECTORING_INFO_VALID_MASK) &&
 			(exit_reason != EXIT_REASON_EXCEPTION_NMI &&
 			exit_reason != EXIT_REASON_EPT_VIOLATION &&
+			exit_reason != EXIT_REASON_PML_FULL &&
 			exit_reason != EXIT_REASON_TASK_SWITCH)) {
 		vcpu->run->exit_reason = KVM_EXIT_INTERNAL_ERROR;
 		vcpu->run->internal.suberror = KVM_INTERNAL_ERROR_DELIVERY_EV;
@@ -8149,12 +8189,18 @@ static void vmx_set_virtual_x2apic_mode(
 {
 	u32 sec_exec_control;
 
+	/* Postpone execution until vmcs01 is the current VMCS. */
+	if (is_guest_mode(vcpu)) {
+		to_vmx(vcpu)->nested.change_vmcs01_virtual_x2apic_mode = true;
+		return;
+	}
+
 	/*
 	 * There is not point to enable virtualize x2apic without enable
 	 * apicv
 	 */
 	if (!cpu_has_vmx_virtualize_x2apic_mode() ||
-				!vmx_cpu_uses_apicv(vcpu))
+				!kvm_vcpu_apicv_active(vcpu))
 		return;
 
 	if (!cpu_need_tpr_shadow(vcpu))
@@ -8259,10 +8305,9 @@ static void vmx_hwapic_irr_update(struct
 	}
 }
 
-static void vmx_load_eoi_exitmap(struct kvm_vcpu *vcpu)
+static void vmx_load_eoi_exitmap(struct kvm_vcpu *vcpu, u64 *eoi_exit_bitmap)
 {
-	u64 *eoi_exit_bitmap = vcpu->arch.eoi_exit_bitmap;
-	if (!vmx_cpu_uses_apicv(vcpu))
+	if (!kvm_vcpu_apicv_active(vcpu))
 		return;
 
 	vmcs_write64(EOI_EXIT_BITMAP0, eoi_exit_bitmap[0]);
@@ -8702,6 +8747,22 @@ static void vmx_load_vmcs01(struct kvm_v
 	put_cpu();
 }
 
+/*
+ * Ensure that the current vmcs of the logical processor is the
+ * vmcs01 of the vcpu before calling free_nested().
+ */
+static void vmx_free_vcpu_nested(struct kvm_vcpu *vcpu)
+{
+       struct vcpu_vmx *vmx = to_vmx(vcpu);
+       int r;
+
+       r = vcpu_load(vcpu);
+       BUG_ON(r);
+       vmx_load_vmcs01(vcpu);
+       free_nested(vmx);
+       vcpu_put(vcpu);
+}
+
 static void vmx_free_vcpu(struct kvm_vcpu *vcpu)
 {
 	struct vcpu_vmx *vmx = to_vmx(vcpu);
@@ -8710,8 +8771,7 @@ static void vmx_free_vcpu(struct kvm_vcp
 		vmx_destroy_pml_buffer(vmx);
 	free_vpid(vmx->vpid);
 	leave_guest_mode(vcpu);
-	vmx_load_vmcs01(vcpu);
-	free_nested(vmx);
+	vmx_free_vcpu_nested(vcpu);
 	free_loaded_vmcs(vmx->loaded_vmcs);
 	kfree(vmx->guest_msrs);
 	kvm_vcpu_uninit(vcpu);
@@ -8932,7 +8992,8 @@ static void vmx_cpuid_update(struct kvm_
 			best->ebx &= ~bit(X86_FEATURE_INVPCID);
 	}
 
-	vmcs_set_secondary_exec_control(secondary_exec_ctl);
+	if (cpu_has_secondary_exec_ctrls())
+		vmcs_set_secondary_exec_control(secondary_exec_ctl);
 
 	if (static_cpu_has(X86_FEATURE_PCOMMIT) && nested) {
 		if (guest_cpuid_has_pcommit(vcpu))
@@ -10432,6 +10493,12 @@ static void nested_vmx_vmexit(struct kvm
 	/* Update TSC_OFFSET if TSC was changed while L2 ran */
 	vmcs_write64(TSC_OFFSET, vmx->nested.vmcs01_tsc_offset);
 
+	if (vmx->nested.change_vmcs01_virtual_x2apic_mode) {
+		vmx->nested.change_vmcs01_virtual_x2apic_mode = false;
+		vmx_set_virtual_x2apic_mode(vcpu,
+				vcpu->arch.apic_base & X2APIC_ENABLE);
+	}
+
 	/* This is needed for same reason as it was needed in prepare_vmcs02 */
 	vmx->host_rsp = 0;
 
@@ -10805,7 +10872,8 @@ static struct kvm_x86_ops vmx_x86_ops =
 	.update_cr8_intercept = update_cr8_intercept,
 	.set_virtual_x2apic_mode = vmx_set_virtual_x2apic_mode,
 	.set_apic_access_page_addr = vmx_set_apic_access_page_addr,
-	.cpu_uses_apicv = vmx_cpu_uses_apicv,
+	.get_enable_apicv = vmx_get_enable_apicv,
+	.refresh_apicv_exec_ctrl = vmx_refresh_apicv_exec_ctrl,
 	.load_eoi_exitmap = vmx_load_eoi_exitmap,
 	.hwapic_irr_update = vmx_hwapic_irr_update,
 	.hwapic_isr_update = vmx_hwapic_isr_update,
--- zfcpdump-kernel-4.4.orig/arch/x86/kvm/x86.c
+++ zfcpdump-kernel-4.4/arch/x86/kvm/x86.c
@@ -697,7 +697,6 @@ static int __kvm_set_xcr(struct kvm_vcpu
 		if ((xcr0 & XFEATURE_MASK_AVX512) != XFEATURE_MASK_AVX512)
 			return 1;
 	}
-	kvm_put_guest_xcr0(vcpu);
 	vcpu->arch.xcr0 = xcr0;
 
 	if ((xcr0 ^ old_xcr0) & XFEATURE_MASK_EXTEND)
@@ -951,7 +950,7 @@ static u32 msrs_to_save[] = {
 	MSR_CSTAR, MSR_KERNEL_GS_BASE, MSR_SYSCALL_MASK, MSR_LSTAR,
 #endif
 	MSR_IA32_TSC, MSR_IA32_CR_PAT, MSR_VM_HSAVE_PA,
-	MSR_IA32_FEATURE_CONTROL, MSR_IA32_BNDCFGS
+	MSR_IA32_FEATURE_CONTROL, MSR_IA32_BNDCFGS, MSR_TSC_AUX,
 };
 
 static unsigned num_msrs_to_save;
@@ -966,6 +965,8 @@ static u32 emulated_msrs[] = {
 	HV_X64_MSR_RESET,
 	HV_X64_MSR_VP_INDEX,
 	HV_X64_MSR_VP_RUNTIME,
+	HV_X64_MSR_SCONTROL,
+	HV_X64_MSR_STIMER0_CONFIG,
 	HV_X64_MSR_APIC_ASSIST_PAGE, MSR_KVM_ASYNC_PF_EN, MSR_KVM_STEAL_TIME,
 	MSR_KVM_PV_EOI_EN,
 
@@ -2198,6 +2199,7 @@ int kvm_set_msr_common(struct kvm_vcpu *
 	case HV_X64_MSR_GUEST_OS_ID ... HV_X64_MSR_SINT15:
 	case HV_X64_MSR_CRASH_P0 ... HV_X64_MSR_CRASH_P4:
 	case HV_X64_MSR_CRASH_CTL:
+	case HV_X64_MSR_STIMER0_CONFIG ... HV_X64_MSR_STIMER3_COUNT:
 		return kvm_hv_set_msr_common(vcpu, msr, data,
 					     msr_info->host_initiated);
 	case MSR_IA32_BBL_CR_CTL3:
@@ -2402,6 +2404,7 @@ int kvm_get_msr_common(struct kvm_vcpu *
 	case HV_X64_MSR_GUEST_OS_ID ... HV_X64_MSR_SINT15:
 	case HV_X64_MSR_CRASH_P0 ... HV_X64_MSR_CRASH_P4:
 	case HV_X64_MSR_CRASH_CTL:
+	case HV_X64_MSR_STIMER0_CONFIG ... HV_X64_MSR_STIMER3_COUNT:
 		return kvm_hv_get_msr_common(vcpu,
 					     msr_info->index, &msr_info->data);
 		break;
@@ -2541,6 +2544,7 @@ int kvm_vm_ioctl_check_extension(struct
 	case KVM_CAP_HYPERV:
 	case KVM_CAP_HYPERV_VAPIC:
 	case KVM_CAP_HYPERV_SPIN:
+	case KVM_CAP_HYPERV_SYNIC:
 	case KVM_CAP_PCI_SEGMENT:
 	case KVM_CAP_DEBUGREGS:
 	case KVM_CAP_X86_ROBUST_SINGLESTEP:
@@ -2748,7 +2752,9 @@ void kvm_arch_vcpu_put(struct kvm_vcpu *
 static int kvm_vcpu_ioctl_get_lapic(struct kvm_vcpu *vcpu,
 				    struct kvm_lapic_state *s)
 {
-	kvm_x86_ops->sync_pir_to_irr(vcpu);
+	if (vcpu->arch.apicv_active)
+		kvm_x86_ops->sync_pir_to_irr(vcpu);
+
 	memcpy(s->regs, vcpu->arch.apic->regs, sizeof *s);
 
 	return 0;
@@ -3014,6 +3020,11 @@ static int kvm_vcpu_ioctl_x86_set_debugr
 	if (dbgregs->flags)
 		return -EINVAL;
 
+	if (dbgregs->dr6 & ~0xffffffffull)
+		return -EINVAL;
+	if (dbgregs->dr7 & ~0xffffffffull)
+		return -EINVAL;
+
 	memcpy(vcpu->arch.db, dbgregs->db, sizeof(vcpu->arch.db));
 	kvm_update_dr0123(vcpu);
 	vcpu->arch.dr6 = dbgregs->dr6;
@@ -3191,6 +3202,20 @@ static int kvm_set_guest_paused(struct k
 	return 0;
 }
 
+static int kvm_vcpu_ioctl_enable_cap(struct kvm_vcpu *vcpu,
+				     struct kvm_enable_cap *cap)
+{
+	if (cap->flags)
+		return -EINVAL;
+
+	switch (cap->cap) {
+	case KVM_CAP_HYPERV_SYNIC:
+		return kvm_hv_activate_synic(vcpu);
+	default:
+		return -EINVAL;
+	}
+}
+
 long kvm_arch_vcpu_ioctl(struct file *filp,
 			 unsigned int ioctl, unsigned long arg)
 {
@@ -3455,6 +3480,15 @@ long kvm_arch_vcpu_ioctl(struct file *fi
 		r = kvm_set_guest_paused(vcpu);
 		goto out;
 	}
+	case KVM_ENABLE_CAP: {
+		struct kvm_enable_cap cap;
+
+		r = -EFAULT;
+		if (copy_from_user(&cap, argp, sizeof(cap)))
+			goto out;
+		r = kvm_vcpu_ioctl_enable_cap(vcpu, &cap);
+		break;
+	}
 	default:
 		r = -EINVAL;
 	}
@@ -4006,16 +4040,17 @@ static void kvm_init_msr_list(void)
 
 		/*
 		 * Even MSRs that are valid in the host may not be exposed
-		 * to the guests in some cases.  We could work around this
-		 * in VMX with the generic MSR save/load machinery, but it
-		 * is not really worthwhile since it will really only
-		 * happen with nested virtualization.
+		 * to the guests in some cases.
 		 */
 		switch (msrs_to_save[i]) {
 		case MSR_IA32_BNDCFGS:
 			if (!kvm_x86_ops->mpx_supported())
 				continue;
 			break;
+		case MSR_TSC_AUX:
+			if (!kvm_x86_ops->rdtscp_supported())
+				continue;
+			break;
 		default:
 			break;
 		}
@@ -5775,7 +5810,7 @@ int kvm_arch_init(void *opaque)
 		goto out;
 	}
 	if (ops->disabled_by_bios()) {
-		printk(KERN_ERR "kvm: disabled by bios\n");
+		printk(KERN_WARNING "kvm: disabled by bios\n");
 		r = -EOPNOTSUPP;
 		goto out;
 	}
@@ -5872,6 +5907,12 @@ static void kvm_pv_kick_cpu_op(struct kv
 	kvm_irq_delivery_to_apic(kvm, NULL, &lapic_irq, NULL);
 }
 
+void kvm_vcpu_deactivate_apicv(struct kvm_vcpu *vcpu)
+{
+	vcpu->arch.apicv_active = false;
+	kvm_x86_ops->refresh_apicv_exec_ctrl(vcpu);
+}
+
 int kvm_emulate_hypercall(struct kvm_vcpu *vcpu)
 {
 	unsigned long nr, a0, a1, a2, a3, ret;
@@ -5965,6 +6006,9 @@ static void update_cr8_intercept(struct
 	if (!vcpu->arch.apic)
 		return;
 
+	if (vcpu->arch.apicv_active)
+		return;
+
 	if (!vcpu->arch.apic->vapic_addr)
 		max_irr = kvm_lapic_find_highest_irr(vcpu);
 	else
@@ -6022,12 +6066,10 @@ static int inject_pending_event(struct k
 	}
 
 	/* try to inject new event if pending */
-	if (vcpu->arch.nmi_pending) {
-		if (kvm_x86_ops->nmi_allowed(vcpu)) {
-			--vcpu->arch.nmi_pending;
-			vcpu->arch.nmi_injected = true;
-			kvm_x86_ops->set_nmi(vcpu);
-		}
+	if (vcpu->arch.nmi_pending && kvm_x86_ops->nmi_allowed(vcpu)) {
+		--vcpu->arch.nmi_pending;
+		vcpu->arch.nmi_injected = true;
+		kvm_x86_ops->set_nmi(vcpu);
 	} else if (kvm_cpu_has_injectable_intr(vcpu)) {
 		/*
 		 * Because interrupts can be injected asynchronously, we are
@@ -6303,18 +6345,23 @@ static void process_smi(struct kvm_vcpu
 
 static void vcpu_scan_ioapic(struct kvm_vcpu *vcpu)
 {
+	u64 eoi_exit_bitmap[4];
+
 	if (!kvm_apic_hw_enabled(vcpu->arch.apic))
 		return;
 
-	memset(vcpu->arch.eoi_exit_bitmap, 0, 256 / 8);
+	bitmap_zero(vcpu->arch.ioapic_handled_vectors, 256);
 
 	if (irqchip_split(vcpu->kvm))
-		kvm_scan_ioapic_routes(vcpu, vcpu->arch.eoi_exit_bitmap);
+		kvm_scan_ioapic_routes(vcpu, vcpu->arch.ioapic_handled_vectors);
 	else {
-		kvm_x86_ops->sync_pir_to_irr(vcpu);
-		kvm_ioapic_scan_entry(vcpu, vcpu->arch.eoi_exit_bitmap);
-	}
-	kvm_x86_ops->load_eoi_exitmap(vcpu);
+		if (vcpu->arch.apicv_active)
+			kvm_x86_ops->sync_pir_to_irr(vcpu);
+		kvm_ioapic_scan_entry(vcpu, vcpu->arch.ioapic_handled_vectors);
+	}
+	bitmap_or((ulong *)eoi_exit_bitmap, vcpu->arch.ioapic_handled_vectors,
+		  vcpu_to_synic(vcpu)->vec_bitmap, 256);
+	kvm_x86_ops->load_eoi_exitmap(vcpu, eoi_exit_bitmap);
 }
 
 static void kvm_vcpu_flush_tlb(struct kvm_vcpu *vcpu)
@@ -6422,7 +6469,7 @@ static int vcpu_enter_guest(struct kvm_v
 		if (kvm_check_request(KVM_REQ_IOAPIC_EOI_EXIT, vcpu)) {
 			BUG_ON(vcpu->arch.pending_ioapic_eoi > 255);
 			if (test_bit(vcpu->arch.pending_ioapic_eoi,
-				     (void *) vcpu->arch.eoi_exit_bitmap)) {
+				     vcpu->arch.ioapic_handled_vectors)) {
 				vcpu->run->exit_reason = KVM_EXIT_IOAPIC_EOI;
 				vcpu->run->eoi.vector =
 						vcpu->arch.pending_ioapic_eoi;
@@ -6446,6 +6493,14 @@ static int vcpu_enter_guest(struct kvm_v
 			r = 0;
 			goto out;
 		}
+		if (kvm_check_request(KVM_REQ_HV_EXIT, vcpu)) {
+			vcpu->run->exit_reason = KVM_EXIT_HYPERV;
+			vcpu->run->hyperv = vcpu->arch.hyperv.exit;
+			r = 0;
+			goto out;
+		}
+		if (kvm_check_request(KVM_REQ_HV_STIMER, vcpu))
+			kvm_hv_process_stimers(vcpu);
 	}
 
 	/*
@@ -6457,7 +6512,7 @@ static int vcpu_enter_guest(struct kvm_v
 		 * Update architecture specific hints for APIC
 		 * virtual interrupt delivery.
 		 */
-		if (kvm_x86_ops->hwapic_irr_update)
+		if (vcpu->arch.apicv_active)
 			kvm_x86_ops->hwapic_irr_update(vcpu,
 				kvm_lapic_find_highest_irr(vcpu));
 	}
@@ -6472,10 +6527,12 @@ static int vcpu_enter_guest(struct kvm_v
 		if (inject_pending_event(vcpu, req_int_win) != 0)
 			req_immediate_exit = true;
 		/* enable NMI/IRQ window open exits if needed */
-		else if (vcpu->arch.nmi_pending)
-			kvm_x86_ops->enable_nmi_window(vcpu);
-		else if (kvm_cpu_has_injectable_intr(vcpu) || req_int_win)
-			kvm_x86_ops->enable_irq_window(vcpu);
+		else {
+			if (vcpu->arch.nmi_pending)
+				kvm_x86_ops->enable_nmi_window(vcpu);
+			if (kvm_cpu_has_injectable_intr(vcpu) || req_int_win)
+				kvm_x86_ops->enable_irq_window(vcpu);
+		}
 
 		if (kvm_lapic_enabled(vcpu)) {
 			update_cr8_intercept(vcpu);
@@ -6493,8 +6550,6 @@ static int vcpu_enter_guest(struct kvm_v
 	kvm_x86_ops->prepare_guest_switch(vcpu);
 	if (vcpu->fpu_active)
 		kvm_load_guest_fpu(vcpu);
-	kvm_load_guest_xcr0(vcpu);
-
 	vcpu->mode = IN_GUEST_MODE;
 
 	srcu_read_unlock(&vcpu->kvm->srcu, vcpu->srcu_idx);
@@ -6517,6 +6572,8 @@ static int vcpu_enter_guest(struct kvm_v
 		goto cancel_injection;
 	}
 
+	kvm_load_guest_xcr0(vcpu);
+
 	if (req_immediate_exit)
 		smp_send_reschedule(vcpu->cpu);
 
@@ -6543,12 +6600,12 @@ static int vcpu_enter_guest(struct kvm_v
 	 * KVM_DEBUGREG_WONT_EXIT again.
 	 */
 	if (unlikely(vcpu->arch.switch_db_regs & KVM_DEBUGREG_WONT_EXIT)) {
-		int i;
-
 		WARN_ON(vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP);
 		kvm_x86_ops->sync_dirty_debug_regs(vcpu);
-		for (i = 0; i < KVM_NR_DB_REGS; i++)
-			vcpu->arch.eff_db[i] = vcpu->arch.db[i];
+		kvm_update_dr0123(vcpu);
+		kvm_update_dr6(vcpu);
+		kvm_update_dr7(vcpu);
+		vcpu->arch.switch_db_regs &= ~KVM_DEBUGREG_RELOAD;
 	}
 
 	/*
@@ -6566,6 +6623,8 @@ static int vcpu_enter_guest(struct kvm_v
 	vcpu->mode = OUTSIDE_GUEST_MODE;
 	smp_wmb();
 
+	kvm_put_guest_xcr0(vcpu);
+
 	/* Interrupt is enabled by handle_external_intr() */
 	kvm_x86_ops->handle_external_intr(vcpu);
 
@@ -7213,7 +7272,6 @@ void kvm_load_guest_fpu(struct kvm_vcpu
 	 * and assume host would use all available bits.
 	 * Guest xcr0 would be loaded later.
 	 */
-	kvm_put_guest_xcr0(vcpu);
 	vcpu->guest_fpu_loaded = 1;
 	__kernel_fpu_begin();
 	__copy_kernel_to_fpregs(&vcpu->arch.guest_fpu.state);
@@ -7222,8 +7280,6 @@ void kvm_load_guest_fpu(struct kvm_vcpu
 
 void kvm_put_guest_fpu(struct kvm_vcpu *vcpu)
 {
-	kvm_put_guest_xcr0(vcpu);
-
 	if (!vcpu->guest_fpu_loaded) {
 		vcpu->fpu_counter = 0;
 		return;
@@ -7528,6 +7584,7 @@ int kvm_arch_vcpu_init(struct kvm_vcpu *
 	BUG_ON(vcpu->kvm == NULL);
 	kvm = vcpu->kvm;
 
+	vcpu->arch.apicv_active = kvm_x86_ops->get_enable_apicv();
 	vcpu->arch.pv.pv_unhalted = false;
 	vcpu->arch.emulate_ctxt.ops = &emulate_ops;
 	if (!irqchip_in_kernel(kvm) || kvm_vcpu_is_reset_bsp(vcpu))
@@ -7585,6 +7642,8 @@ int kvm_arch_vcpu_init(struct kvm_vcpu *
 
 	vcpu->arch.pending_external_vector = -1;
 
+	kvm_hv_vcpu_init(vcpu);
+
 	return 0;
 
 fail_free_mce_banks:
@@ -7603,6 +7662,7 @@ void kvm_arch_vcpu_uninit(struct kvm_vcp
 {
 	int idx;
 
+	kvm_hv_vcpu_uninit(vcpu);
 	kvm_pmu_destroy(vcpu);
 	kfree(vcpu->arch.mce_banks);
 	kvm_free_lapic(vcpu);
@@ -7997,6 +8057,9 @@ static inline bool kvm_vcpu_has_events(s
 	    kvm_cpu_has_interrupt(vcpu))
 		return true;
 
+	if (kvm_hv_has_stimer_pending(vcpu))
+		return true;
+
 	return false;
 }
 
--- zfcpdump-kernel-4.4.orig/arch/x86/lib/clear_page_64.S
+++ zfcpdump-kernel-4.4/arch/x86/lib/clear_page_64.S
@@ -1,5 +1,5 @@
 #include <linux/linkage.h>
-#include <asm/cpufeature.h>
+#include <asm/cpufeatures.h>
 #include <asm/alternative-asm.h>
 
 /*
--- zfcpdump-kernel-4.4.orig/arch/x86/lib/copy_page_64.S
+++ zfcpdump-kernel-4.4/arch/x86/lib/copy_page_64.S
@@ -1,7 +1,7 @@
 /* Written 2003 by Andi Kleen, based on a kernel by Evandro Menezes */
 
 #include <linux/linkage.h>
-#include <asm/cpufeature.h>
+#include <asm/cpufeatures.h>
 #include <asm/alternative-asm.h>
 
 /*
--- zfcpdump-kernel-4.4.orig/arch/x86/lib/copy_user_64.S
+++ zfcpdump-kernel-4.4/arch/x86/lib/copy_user_64.S
@@ -10,7 +10,7 @@
 #include <asm/current.h>
 #include <asm/asm-offsets.h>
 #include <asm/thread_info.h>
-#include <asm/cpufeature.h>
+#include <asm/cpufeatures.h>
 #include <asm/alternative-asm.h>
 #include <asm/asm.h>
 #include <asm/smap.h>
@@ -232,17 +232,31 @@ ENDPROC(copy_user_enhanced_fast_string)
 
 /*
  * copy_user_nocache - Uncached memory copy with exception handling
- * This will force destination/source out of cache for more performance.
+ * This will force destination out of cache for more performance.
+ *
+ * Note: Cached memory copy is used when destination or size is not
+ * naturally aligned. That is:
+ *  - Require 8-byte alignment when size is 8 bytes or larger.
+ *  - Require 4-byte alignment when size is 4 bytes.
  */
 ENTRY(__copy_user_nocache)
 	ASM_STAC
+
+	/* If size is less than 8 bytes, go to 4-byte copy */
 	cmpl $8,%edx
-	jb 20f		/* less then 8 bytes, go to byte copy loop */
+	jb .L_4b_nocache_copy_entry
+
+	/* If destination is not 8-byte aligned, "cache" copy to align it */
 	ALIGN_DESTINATION
+
+	/* Set 4x8-byte copy count and remainder */
 	movl %edx,%ecx
 	andl $63,%edx
 	shrl $6,%ecx
-	jz 17f
+	jz .L_8b_nocache_copy_entry	/* jump if count is 0 */
+
+	/* Perform 4x8-byte nocache loop-copy */
+.L_4x8b_nocache_copy_loop:
 1:	movq (%rsi),%r8
 2:	movq 1*8(%rsi),%r9
 3:	movq 2*8(%rsi),%r10
@@ -262,60 +276,106 @@ ENTRY(__copy_user_nocache)
 	leaq 64(%rsi),%rsi
 	leaq 64(%rdi),%rdi
 	decl %ecx
-	jnz 1b
-17:	movl %edx,%ecx
+	jnz .L_4x8b_nocache_copy_loop
+
+	/* Set 8-byte copy count and remainder */
+.L_8b_nocache_copy_entry:
+	movl %edx,%ecx
 	andl $7,%edx
 	shrl $3,%ecx
-	jz 20f
-18:	movq (%rsi),%r8
-19:	movnti %r8,(%rdi)
+	jz .L_4b_nocache_copy_entry	/* jump if count is 0 */
+
+	/* Perform 8-byte nocache loop-copy */
+.L_8b_nocache_copy_loop:
+20:	movq (%rsi),%r8
+21:	movnti %r8,(%rdi)
 	leaq 8(%rsi),%rsi
 	leaq 8(%rdi),%rdi
 	decl %ecx
-	jnz 18b
-20:	andl %edx,%edx
-	jz 23f
+	jnz .L_8b_nocache_copy_loop
+
+	/* If no byte left, we're done */
+.L_4b_nocache_copy_entry:
+	andl %edx,%edx
+	jz .L_finish_copy
+
+	/* If destination is not 4-byte aligned, go to byte copy: */
+	movl %edi,%ecx
+	andl $3,%ecx
+	jnz .L_1b_cache_copy_entry
+
+	/* Set 4-byte copy count (1 or 0) and remainder */
 	movl %edx,%ecx
-21:	movb (%rsi),%al
-22:	movb %al,(%rdi)
+	andl $3,%edx
+	shrl $2,%ecx
+	jz .L_1b_cache_copy_entry	/* jump if count is 0 */
+
+	/* Perform 4-byte nocache copy: */
+30:	movl (%rsi),%r8d
+31:	movnti %r8d,(%rdi)
+	leaq 4(%rsi),%rsi
+	leaq 4(%rdi),%rdi
+
+	/* If no bytes left, we're done: */
+	andl %edx,%edx
+	jz .L_finish_copy
+
+	/* Perform byte "cache" loop-copy for the remainder */
+.L_1b_cache_copy_entry:
+	movl %edx,%ecx
+.L_1b_cache_copy_loop:
+40:	movb (%rsi),%al
+41:	movb %al,(%rdi)
 	incq %rsi
 	incq %rdi
 	decl %ecx
-	jnz 21b
-23:	xorl %eax,%eax
+	jnz .L_1b_cache_copy_loop
+
+	/* Finished copying; fence the prior stores */
+.L_finish_copy:
+	xorl %eax,%eax
 	ASM_CLAC
 	sfence
 	ret
 
 	.section .fixup,"ax"
-30:	shll $6,%ecx
+.L_fixup_4x8b_copy:
+	shll $6,%ecx
 	addl %ecx,%edx
-	jmp 60f
-40:	lea (%rdx,%rcx,8),%rdx
-	jmp 60f
-50:	movl %ecx,%edx
-60:	sfence
+	jmp .L_fixup_handle_tail
+.L_fixup_8b_copy:
+	lea (%rdx,%rcx,8),%rdx
+	jmp .L_fixup_handle_tail
+.L_fixup_4b_copy:
+	lea (%rdx,%rcx,4),%rdx
+	jmp .L_fixup_handle_tail
+.L_fixup_1b_copy:
+	movl %ecx,%edx
+.L_fixup_handle_tail:
+	sfence
 	jmp copy_user_handle_tail
 	.previous
 
-	_ASM_EXTABLE(1b,30b)
-	_ASM_EXTABLE(2b,30b)
-	_ASM_EXTABLE(3b,30b)
-	_ASM_EXTABLE(4b,30b)
-	_ASM_EXTABLE(5b,30b)
-	_ASM_EXTABLE(6b,30b)
-	_ASM_EXTABLE(7b,30b)
-	_ASM_EXTABLE(8b,30b)
-	_ASM_EXTABLE(9b,30b)
-	_ASM_EXTABLE(10b,30b)
-	_ASM_EXTABLE(11b,30b)
-	_ASM_EXTABLE(12b,30b)
-	_ASM_EXTABLE(13b,30b)
-	_ASM_EXTABLE(14b,30b)
-	_ASM_EXTABLE(15b,30b)
-	_ASM_EXTABLE(16b,30b)
-	_ASM_EXTABLE(18b,40b)
-	_ASM_EXTABLE(19b,40b)
-	_ASM_EXTABLE(21b,50b)
-	_ASM_EXTABLE(22b,50b)
+	_ASM_EXTABLE(1b,.L_fixup_4x8b_copy)
+	_ASM_EXTABLE(2b,.L_fixup_4x8b_copy)
+	_ASM_EXTABLE(3b,.L_fixup_4x8b_copy)
+	_ASM_EXTABLE(4b,.L_fixup_4x8b_copy)
+	_ASM_EXTABLE(5b,.L_fixup_4x8b_copy)
+	_ASM_EXTABLE(6b,.L_fixup_4x8b_copy)
+	_ASM_EXTABLE(7b,.L_fixup_4x8b_copy)
+	_ASM_EXTABLE(8b,.L_fixup_4x8b_copy)
+	_ASM_EXTABLE(9b,.L_fixup_4x8b_copy)
+	_ASM_EXTABLE(10b,.L_fixup_4x8b_copy)
+	_ASM_EXTABLE(11b,.L_fixup_4x8b_copy)
+	_ASM_EXTABLE(12b,.L_fixup_4x8b_copy)
+	_ASM_EXTABLE(13b,.L_fixup_4x8b_copy)
+	_ASM_EXTABLE(14b,.L_fixup_4x8b_copy)
+	_ASM_EXTABLE(15b,.L_fixup_4x8b_copy)
+	_ASM_EXTABLE(16b,.L_fixup_4x8b_copy)
+	_ASM_EXTABLE(20b,.L_fixup_8b_copy)
+	_ASM_EXTABLE(21b,.L_fixup_8b_copy)
+	_ASM_EXTABLE(30b,.L_fixup_4b_copy)
+	_ASM_EXTABLE(31b,.L_fixup_4b_copy)
+	_ASM_EXTABLE(40b,.L_fixup_1b_copy)
+	_ASM_EXTABLE(41b,.L_fixup_1b_copy)
 ENDPROC(__copy_user_nocache)
--- zfcpdump-kernel-4.4.orig/arch/x86/lib/insn.c
+++ zfcpdump-kernel-4.4/arch/x86/lib/insn.c
@@ -155,14 +155,24 @@ found:
 			/*
 			 * In 32-bits mode, if the [7:6] bits (mod bits of
 			 * ModRM) on the second byte are not 11b, it is
-			 * LDS or LES.
+			 * LDS or LES or BOUND.
 			 */
 			if (X86_MODRM_MOD(b2) != 3)
 				goto vex_end;
 		}
 		insn->vex_prefix.bytes[0] = b;
 		insn->vex_prefix.bytes[1] = b2;
-		if (inat_is_vex3_prefix(attr)) {
+		if (inat_is_evex_prefix(attr)) {
+			b2 = peek_nbyte_next(insn_byte_t, insn, 2);
+			insn->vex_prefix.bytes[2] = b2;
+			b2 = peek_nbyte_next(insn_byte_t, insn, 3);
+			insn->vex_prefix.bytes[3] = b2;
+			insn->vex_prefix.nbytes = 4;
+			insn->next_byte += 4;
+			if (insn->x86_64 && X86_VEX_W(b2))
+				/* VEX.W overrides opnd_size */
+				insn->opnd_bytes = 8;
+		} else if (inat_is_vex3_prefix(attr)) {
 			b2 = peek_nbyte_next(insn_byte_t, insn, 2);
 			insn->vex_prefix.bytes[2] = b2;
 			insn->vex_prefix.nbytes = 3;
@@ -221,7 +231,9 @@ void insn_get_opcode(struct insn *insn)
 		m = insn_vex_m_bits(insn);
 		p = insn_vex_p_bits(insn);
 		insn->attr = inat_get_avx_attribute(op, m, p);
-		if (!inat_accept_vex(insn->attr) && !inat_is_group(insn->attr))
+		if ((inat_must_evex(insn->attr) && !insn_is_evex(insn)) ||
+		    (!inat_accept_vex(insn->attr) &&
+		     !inat_is_group(insn->attr)))
 			insn->attr = 0;	/* This instruction is bad */
 		goto end;	/* VEX has only 1 byte for opcode */
 	}
--- zfcpdump-kernel-4.4.orig/arch/x86/lib/memcpy_64.S
+++ zfcpdump-kernel-4.4/arch/x86/lib/memcpy_64.S
@@ -1,7 +1,7 @@
 /* Copyright 2002 Andi Kleen */
 
 #include <linux/linkage.h>
-#include <asm/cpufeature.h>
+#include <asm/cpufeatures.h>
 #include <asm/alternative-asm.h>
 
 /*
--- zfcpdump-kernel-4.4.orig/arch/x86/lib/memmove_64.S
+++ zfcpdump-kernel-4.4/arch/x86/lib/memmove_64.S
@@ -6,7 +6,7 @@
  *	- Copyright 2011 Fenghua Yu <fenghua.yu@intel.com>
  */
 #include <linux/linkage.h>
-#include <asm/cpufeature.h>
+#include <asm/cpufeatures.h>
 #include <asm/alternative-asm.h>
 
 #undef memmove
--- zfcpdump-kernel-4.4.orig/arch/x86/lib/memset_64.S
+++ zfcpdump-kernel-4.4/arch/x86/lib/memset_64.S
@@ -1,7 +1,7 @@
 /* Copyright 2002 Andi Kleen, SuSE Labs */
 
 #include <linux/linkage.h>
-#include <asm/cpufeature.h>
+#include <asm/cpufeatures.h>
 #include <asm/alternative-asm.h>
 
 .weak memset
--- zfcpdump-kernel-4.4.orig/arch/x86/lib/x86-opcode-map.txt
+++ zfcpdump-kernel-4.4/arch/x86/lib/x86-opcode-map.txt
@@ -13,12 +13,17 @@
 # opcode: escape # escaped-name
 # EndTable
 #
+# mnemonics that begin with lowercase 'v' accept a VEX or EVEX prefix
+# mnemonics that begin with lowercase 'k' accept a VEX prefix
+#
 #<group maps>
 # GrpTable: GrpXXX
 # reg:  mnemonic [operand1[,operand2...]] [(extra1)[,(extra2)...] [| 2nd-mnemonic ...]
 # EndTable
 #
 # AVX Superscripts
+#  (ev): this opcode requires EVEX prefix.
+#  (evo): this opcode is changed by EVEX prefix (EVEX opcode)
 #  (v): this opcode requires VEX prefix.
 #  (v1): this opcode only supports 128bit VEX.
 #
@@ -137,7 +142,7 @@ AVXcode:
 # 0x60 - 0x6f
 60: PUSHA/PUSHAD (i64)
 61: POPA/POPAD (i64)
-62: BOUND Gv,Ma (i64)
+62: BOUND Gv,Ma (i64) | EVEX (Prefix)
 63: ARPL Ew,Gw (i64) | MOVSXD Gv,Ev (o64)
 64: SEG=FS (Prefix)
 65: SEG=GS (Prefix)
@@ -399,17 +404,17 @@ AVXcode: 1
 3f:
 # 0x0f 0x40-0x4f
 40: CMOVO Gv,Ev
-41: CMOVNO Gv,Ev
-42: CMOVB/C/NAE Gv,Ev
+41: CMOVNO Gv,Ev | kandw/q Vk,Hk,Uk | kandb/d Vk,Hk,Uk (66)
+42: CMOVB/C/NAE Gv,Ev | kandnw/q Vk,Hk,Uk | kandnb/d Vk,Hk,Uk (66)
 43: CMOVAE/NB/NC Gv,Ev
-44: CMOVE/Z Gv,Ev
-45: CMOVNE/NZ Gv,Ev
-46: CMOVBE/NA Gv,Ev
-47: CMOVA/NBE Gv,Ev
+44: CMOVE/Z Gv,Ev | knotw/q Vk,Uk | knotb/d Vk,Uk (66)
+45: CMOVNE/NZ Gv,Ev | korw/q Vk,Hk,Uk | korb/d Vk,Hk,Uk (66)
+46: CMOVBE/NA Gv,Ev | kxnorw/q Vk,Hk,Uk | kxnorb/d Vk,Hk,Uk (66)
+47: CMOVA/NBE Gv,Ev | kxorw/q Vk,Hk,Uk | kxorb/d Vk,Hk,Uk (66)
 48: CMOVS Gv,Ev
 49: CMOVNS Gv,Ev
-4a: CMOVP/PE Gv,Ev
-4b: CMOVNP/PO Gv,Ev
+4a: CMOVP/PE Gv,Ev | kaddw/q Vk,Hk,Uk | kaddb/d Vk,Hk,Uk (66)
+4b: CMOVNP/PO Gv,Ev | kunpckbw Vk,Hk,Uk (66) | kunpckwd/dq Vk,Hk,Uk
 4c: CMOVL/NGE Gv,Ev
 4d: CMOVNL/GE Gv,Ev
 4e: CMOVLE/NG Gv,Ev
@@ -426,7 +431,7 @@ AVXcode: 1
 58: vaddps Vps,Hps,Wps | vaddpd Vpd,Hpd,Wpd (66) | vaddss Vss,Hss,Wss (F3),(v1) | vaddsd Vsd,Hsd,Wsd (F2),(v1)
 59: vmulps Vps,Hps,Wps | vmulpd Vpd,Hpd,Wpd (66) | vmulss Vss,Hss,Wss (F3),(v1) | vmulsd Vsd,Hsd,Wsd (F2),(v1)
 5a: vcvtps2pd Vpd,Wps | vcvtpd2ps Vps,Wpd (66) | vcvtss2sd Vsd,Hx,Wss (F3),(v1) | vcvtsd2ss Vss,Hx,Wsd (F2),(v1)
-5b: vcvtdq2ps Vps,Wdq | vcvtps2dq Vdq,Wps (66) | vcvttps2dq Vdq,Wps (F3)
+5b: vcvtdq2ps Vps,Wdq | vcvtqq2ps Vps,Wqq (evo) | vcvtps2dq Vdq,Wps (66) | vcvttps2dq Vdq,Wps (F3)
 5c: vsubps Vps,Hps,Wps | vsubpd Vpd,Hpd,Wpd (66) | vsubss Vss,Hss,Wss (F3),(v1) | vsubsd Vsd,Hsd,Wsd (F2),(v1)
 5d: vminps Vps,Hps,Wps | vminpd Vpd,Hpd,Wpd (66) | vminss Vss,Hss,Wss (F3),(v1) | vminsd Vsd,Hsd,Wsd (F2),(v1)
 5e: vdivps Vps,Hps,Wps | vdivpd Vpd,Hpd,Wpd (66) | vdivss Vss,Hss,Wss (F3),(v1) | vdivsd Vsd,Hsd,Wsd (F2),(v1)
@@ -447,7 +452,7 @@ AVXcode: 1
 6c: vpunpcklqdq Vx,Hx,Wx (66),(v1)
 6d: vpunpckhqdq Vx,Hx,Wx (66),(v1)
 6e: movd/q Pd,Ey | vmovd/q Vy,Ey (66),(v1)
-6f: movq Pq,Qq | vmovdqa Vx,Wx (66) | vmovdqu Vx,Wx (F3)
+6f: movq Pq,Qq | vmovdqa Vx,Wx (66) | vmovdqa32/64 Vx,Wx (66),(evo) | vmovdqu Vx,Wx (F3) | vmovdqu32/64 Vx,Wx (F3),(evo) | vmovdqu8/16 Vx,Wx (F2),(ev)
 # 0x0f 0x70-0x7f
 70: pshufw Pq,Qq,Ib | vpshufd Vx,Wx,Ib (66),(v1) | vpshufhw Vx,Wx,Ib (F3),(v1) | vpshuflw Vx,Wx,Ib (F2),(v1)
 71: Grp12 (1A)
@@ -458,14 +463,14 @@ AVXcode: 1
 76: pcmpeqd Pq,Qq | vpcmpeqd Vx,Hx,Wx (66),(v1)
 # Note: Remove (v), because vzeroall and vzeroupper becomes emms without VEX.
 77: emms | vzeroupper | vzeroall
-78: VMREAD Ey,Gy
-79: VMWRITE Gy,Ey
-7a:
-7b:
+78: VMREAD Ey,Gy | vcvttps2udq/pd2udq Vx,Wpd (evo) | vcvttsd2usi Gv,Wx (F2),(ev) | vcvttss2usi Gv,Wx (F3),(ev) | vcvttps2uqq/pd2uqq Vx,Wx (66),(ev)
+79: VMWRITE Gy,Ey | vcvtps2udq/pd2udq Vx,Wpd (evo) | vcvtsd2usi Gv,Wx (F2),(ev) | vcvtss2usi Gv,Wx (F3),(ev) | vcvtps2uqq/pd2uqq Vx,Wx (66),(ev)
+7a: vcvtudq2pd/uqq2pd Vpd,Wx (F3),(ev) | vcvtudq2ps/uqq2ps Vpd,Wx (F2),(ev) | vcvttps2qq/pd2qq Vx,Wx (66),(ev)
+7b: vcvtusi2sd Vpd,Hpd,Ev (F2),(ev) | vcvtusi2ss Vps,Hps,Ev (F3),(ev) | vcvtps2qq/pd2qq Vx,Wx (66),(ev)
 7c: vhaddpd Vpd,Hpd,Wpd (66) | vhaddps Vps,Hps,Wps (F2)
 7d: vhsubpd Vpd,Hpd,Wpd (66) | vhsubps Vps,Hps,Wps (F2)
 7e: movd/q Ey,Pd | vmovd/q Ey,Vy (66),(v1) | vmovq Vq,Wq (F3),(v1)
-7f: movq Qq,Pq | vmovdqa Wx,Vx (66) | vmovdqu Wx,Vx (F3)
+7f: movq Qq,Pq | vmovdqa Wx,Vx (66) | vmovdqa32/64 Wx,Vx (66),(evo) | vmovdqu Wx,Vx (F3) | vmovdqu32/64 Wx,Vx (F3),(evo) | vmovdqu8/16 Wx,Vx (F2),(ev)
 # 0x0f 0x80-0x8f
 # Note: "forced64" is Intel CPU behavior (see comment about CALL insn).
 80: JO Jz (f64)
@@ -485,16 +490,16 @@ AVXcode: 1
 8e: JLE/JNG Jz (f64)
 8f: JNLE/JG Jz (f64)
 # 0x0f 0x90-0x9f
-90: SETO Eb
-91: SETNO Eb
-92: SETB/C/NAE Eb
-93: SETAE/NB/NC Eb
+90: SETO Eb | kmovw/q Vk,Wk | kmovb/d Vk,Wk (66)
+91: SETNO Eb | kmovw/q Mv,Vk | kmovb/d Mv,Vk (66)
+92: SETB/C/NAE Eb | kmovw Vk,Rv | kmovb Vk,Rv (66) | kmovq/d Vk,Rv (F2)
+93: SETAE/NB/NC Eb | kmovw Gv,Uk | kmovb Gv,Uk (66) | kmovq/d Gv,Uk (F2)
 94: SETE/Z Eb
 95: SETNE/NZ Eb
 96: SETBE/NA Eb
 97: SETA/NBE Eb
-98: SETS Eb
-99: SETNS Eb
+98: SETS Eb | kortestw/q Vk,Uk | kortestb/d Vk,Uk (66)
+99: SETNS Eb | ktestw/q Vk,Uk | ktestb/d Vk,Uk (66)
 9a: SETP/PE Eb
 9b: SETNP/PO Eb
 9c: SETL/NGE Eb
@@ -564,11 +569,11 @@ d7: pmovmskb Gd,Nq | vpmovmskb Gd,Ux (66
 d8: psubusb Pq,Qq | vpsubusb Vx,Hx,Wx (66),(v1)
 d9: psubusw Pq,Qq | vpsubusw Vx,Hx,Wx (66),(v1)
 da: pminub Pq,Qq | vpminub Vx,Hx,Wx (66),(v1)
-db: pand Pq,Qq | vpand Vx,Hx,Wx (66),(v1)
+db: pand Pq,Qq | vpand Vx,Hx,Wx (66),(v1) | vpandd/q Vx,Hx,Wx (66),(evo)
 dc: paddusb Pq,Qq | vpaddusb Vx,Hx,Wx (66),(v1)
 dd: paddusw Pq,Qq | vpaddusw Vx,Hx,Wx (66),(v1)
 de: pmaxub Pq,Qq | vpmaxub Vx,Hx,Wx (66),(v1)
-df: pandn Pq,Qq | vpandn Vx,Hx,Wx (66),(v1)
+df: pandn Pq,Qq | vpandn Vx,Hx,Wx (66),(v1) | vpandnd/q Vx,Hx,Wx (66),(evo)
 # 0x0f 0xe0-0xef
 e0: pavgb Pq,Qq | vpavgb Vx,Hx,Wx (66),(v1)
 e1: psraw Pq,Qq | vpsraw Vx,Hx,Wx (66),(v1)
@@ -576,16 +581,16 @@ e2: psrad Pq,Qq | vpsrad Vx,Hx,Wx (66),(
 e3: pavgw Pq,Qq | vpavgw Vx,Hx,Wx (66),(v1)
 e4: pmulhuw Pq,Qq | vpmulhuw Vx,Hx,Wx (66),(v1)
 e5: pmulhw Pq,Qq | vpmulhw Vx,Hx,Wx (66),(v1)
-e6: vcvttpd2dq Vx,Wpd (66) | vcvtdq2pd Vx,Wdq (F3) | vcvtpd2dq Vx,Wpd (F2)
+e6: vcvttpd2dq Vx,Wpd (66) | vcvtdq2pd Vx,Wdq (F3) | vcvtdq2pd/qq2pd Vx,Wdq (F3),(evo) | vcvtpd2dq Vx,Wpd (F2)
 e7: movntq Mq,Pq | vmovntdq Mx,Vx (66)
 e8: psubsb Pq,Qq | vpsubsb Vx,Hx,Wx (66),(v1)
 e9: psubsw Pq,Qq | vpsubsw Vx,Hx,Wx (66),(v1)
 ea: pminsw Pq,Qq | vpminsw Vx,Hx,Wx (66),(v1)
-eb: por Pq,Qq | vpor Vx,Hx,Wx (66),(v1)
+eb: por Pq,Qq | vpor Vx,Hx,Wx (66),(v1) | vpord/q Vx,Hx,Wx (66),(evo)
 ec: paddsb Pq,Qq | vpaddsb Vx,Hx,Wx (66),(v1)
 ed: paddsw Pq,Qq | vpaddsw Vx,Hx,Wx (66),(v1)
 ee: pmaxsw Pq,Qq | vpmaxsw Vx,Hx,Wx (66),(v1)
-ef: pxor Pq,Qq | vpxor Vx,Hx,Wx (66),(v1)
+ef: pxor Pq,Qq | vpxor Vx,Hx,Wx (66),(v1) | vpxord/q Vx,Hx,Wx (66),(evo)
 # 0x0f 0xf0-0xff
 f0: vlddqu Vx,Mx (F2)
 f1: psllw Pq,Qq | vpsllw Vx,Hx,Wx (66),(v1)
@@ -626,81 +631,105 @@ AVXcode: 2
 0e: vtestps Vx,Wx (66),(v)
 0f: vtestpd Vx,Wx (66),(v)
 # 0x0f 0x38 0x10-0x1f
-10: pblendvb Vdq,Wdq (66)
-11:
-12:
-13: vcvtph2ps Vx,Wx,Ib (66),(v)
-14: blendvps Vdq,Wdq (66)
-15: blendvpd Vdq,Wdq (66)
-16: vpermps Vqq,Hqq,Wqq (66),(v)
+10: pblendvb Vdq,Wdq (66) | vpsrlvw Vx,Hx,Wx (66),(evo) | vpmovuswb Wx,Vx (F3),(ev)
+11: vpmovusdb Wx,Vd (F3),(ev) | vpsravw Vx,Hx,Wx (66),(ev)
+12: vpmovusqb Wx,Vq (F3),(ev) | vpsllvw Vx,Hx,Wx (66),(ev)
+13: vcvtph2ps Vx,Wx (66),(v) | vpmovusdw Wx,Vd (F3),(ev)
+14: blendvps Vdq,Wdq (66) | vpmovusqw Wx,Vq (F3),(ev) | vprorvd/q Vx,Hx,Wx (66),(evo)
+15: blendvpd Vdq,Wdq (66) | vpmovusqd Wx,Vq (F3),(ev) | vprolvd/q Vx,Hx,Wx (66),(evo)
+16: vpermps Vqq,Hqq,Wqq (66),(v) | vpermps/d Vqq,Hqq,Wqq (66),(evo)
 17: vptest Vx,Wx (66)
 18: vbroadcastss Vx,Wd (66),(v)
-19: vbroadcastsd Vqq,Wq (66),(v)
-1a: vbroadcastf128 Vqq,Mdq (66),(v)
-1b:
+19: vbroadcastsd Vqq,Wq (66),(v) | vbroadcastf32x2 Vqq,Wq (66),(evo)
+1a: vbroadcastf128 Vqq,Mdq (66),(v) | vbroadcastf32x4/64x2 Vqq,Wq (66),(evo)
+1b: vbroadcastf32x8/64x4 Vqq,Mdq (66),(ev)
 1c: pabsb Pq,Qq | vpabsb Vx,Wx (66),(v1)
 1d: pabsw Pq,Qq | vpabsw Vx,Wx (66),(v1)
 1e: pabsd Pq,Qq | vpabsd Vx,Wx (66),(v1)
-1f:
+1f: vpabsq Vx,Wx (66),(ev)
 # 0x0f 0x38 0x20-0x2f
-20: vpmovsxbw Vx,Ux/Mq (66),(v1)
-21: vpmovsxbd Vx,Ux/Md (66),(v1)
-22: vpmovsxbq Vx,Ux/Mw (66),(v1)
-23: vpmovsxwd Vx,Ux/Mq (66),(v1)
-24: vpmovsxwq Vx,Ux/Md (66),(v1)
-25: vpmovsxdq Vx,Ux/Mq (66),(v1)
-26:
-27:
-28: vpmuldq Vx,Hx,Wx (66),(v1)
-29: vpcmpeqq Vx,Hx,Wx (66),(v1)
-2a: vmovntdqa Vx,Mx (66),(v1)
+20: vpmovsxbw Vx,Ux/Mq (66),(v1) | vpmovswb Wx,Vx (F3),(ev)
+21: vpmovsxbd Vx,Ux/Md (66),(v1) | vpmovsdb Wx,Vd (F3),(ev)
+22: vpmovsxbq Vx,Ux/Mw (66),(v1) | vpmovsqb Wx,Vq (F3),(ev)
+23: vpmovsxwd Vx,Ux/Mq (66),(v1) | vpmovsdw Wx,Vd (F3),(ev)
+24: vpmovsxwq Vx,Ux/Md (66),(v1) | vpmovsqw Wx,Vq (F3),(ev)
+25: vpmovsxdq Vx,Ux/Mq (66),(v1) | vpmovsqd Wx,Vq (F3),(ev)
+26: vptestmb/w Vk,Hx,Wx (66),(ev) | vptestnmb/w Vk,Hx,Wx (F3),(ev)
+27: vptestmd/q Vk,Hx,Wx (66),(ev) | vptestnmd/q Vk,Hx,Wx (F3),(ev)
+28: vpmuldq Vx,Hx,Wx (66),(v1) | vpmovm2b/w Vx,Uk (F3),(ev)
+29: vpcmpeqq Vx,Hx,Wx (66),(v1) | vpmovb2m/w2m Vk,Ux (F3),(ev)
+2a: vmovntdqa Vx,Mx (66),(v1) | vpbroadcastmb2q Vx,Uk (F3),(ev)
 2b: vpackusdw Vx,Hx,Wx (66),(v1)
-2c: vmaskmovps Vx,Hx,Mx (66),(v)
-2d: vmaskmovpd Vx,Hx,Mx (66),(v)
+2c: vmaskmovps Vx,Hx,Mx (66),(v) | vscalefps/d Vx,Hx,Wx (66),(evo)
+2d: vmaskmovpd Vx,Hx,Mx (66),(v) | vscalefss/d Vx,Hx,Wx (66),(evo)
 2e: vmaskmovps Mx,Hx,Vx (66),(v)
 2f: vmaskmovpd Mx,Hx,Vx (66),(v)
 # 0x0f 0x38 0x30-0x3f
-30: vpmovzxbw Vx,Ux/Mq (66),(v1)
-31: vpmovzxbd Vx,Ux/Md (66),(v1)
-32: vpmovzxbq Vx,Ux/Mw (66),(v1)
-33: vpmovzxwd Vx,Ux/Mq (66),(v1)
-34: vpmovzxwq Vx,Ux/Md (66),(v1)
-35: vpmovzxdq Vx,Ux/Mq (66),(v1)
-36: vpermd Vqq,Hqq,Wqq (66),(v)
+30: vpmovzxbw Vx,Ux/Mq (66),(v1) | vpmovwb Wx,Vx (F3),(ev)
+31: vpmovzxbd Vx,Ux/Md (66),(v1) | vpmovdb Wx,Vd (F3),(ev)
+32: vpmovzxbq Vx,Ux/Mw (66),(v1) | vpmovqb Wx,Vq (F3),(ev)
+33: vpmovzxwd Vx,Ux/Mq (66),(v1) | vpmovdw Wx,Vd (F3),(ev)
+34: vpmovzxwq Vx,Ux/Md (66),(v1) | vpmovqw Wx,Vq (F3),(ev)
+35: vpmovzxdq Vx,Ux/Mq (66),(v1) | vpmovqd Wx,Vq (F3),(ev)
+36: vpermd Vqq,Hqq,Wqq (66),(v) | vpermd/q Vqq,Hqq,Wqq (66),(evo)
 37: vpcmpgtq Vx,Hx,Wx (66),(v1)
-38: vpminsb Vx,Hx,Wx (66),(v1)
-39: vpminsd Vx,Hx,Wx (66),(v1)
-3a: vpminuw Vx,Hx,Wx (66),(v1)
-3b: vpminud Vx,Hx,Wx (66),(v1)
+38: vpminsb Vx,Hx,Wx (66),(v1) | vpmovm2d/q Vx,Uk (F3),(ev)
+39: vpminsd Vx,Hx,Wx (66),(v1) | vpminsd/q Vx,Hx,Wx (66),(evo) | vpmovd2m/q2m Vk,Ux (F3),(ev)
+3a: vpminuw Vx,Hx,Wx (66),(v1) | vpbroadcastmw2d Vx,Uk (F3),(ev)
+3b: vpminud Vx,Hx,Wx (66),(v1) | vpminud/q Vx,Hx,Wx (66),(evo)
 3c: vpmaxsb Vx,Hx,Wx (66),(v1)
-3d: vpmaxsd Vx,Hx,Wx (66),(v1)
+3d: vpmaxsd Vx,Hx,Wx (66),(v1) | vpmaxsd/q Vx,Hx,Wx (66),(evo)
 3e: vpmaxuw Vx,Hx,Wx (66),(v1)
-3f: vpmaxud Vx,Hx,Wx (66),(v1)
+3f: vpmaxud Vx,Hx,Wx (66),(v1) | vpmaxud/q Vx,Hx,Wx (66),(evo)
 # 0x0f 0x38 0x40-0x8f
-40: vpmulld Vx,Hx,Wx (66),(v1)
+40: vpmulld Vx,Hx,Wx (66),(v1) | vpmulld/q Vx,Hx,Wx (66),(evo)
 41: vphminposuw Vdq,Wdq (66),(v1)
-42:
-43:
-44:
+42: vgetexpps/d Vx,Wx (66),(ev)
+43: vgetexpss/d Vx,Hx,Wx (66),(ev)
+44: vplzcntd/q Vx,Wx (66),(ev)
 45: vpsrlvd/q Vx,Hx,Wx (66),(v)
-46: vpsravd Vx,Hx,Wx (66),(v)
+46: vpsravd Vx,Hx,Wx (66),(v) | vpsravd/q Vx,Hx,Wx (66),(evo)
 47: vpsllvd/q Vx,Hx,Wx (66),(v)
-# Skip 0x48-0x57
+# Skip 0x48-0x4b
+4c: vrcp14ps/d Vpd,Wpd (66),(ev)
+4d: vrcp14ss/d Vsd,Hpd,Wsd (66),(ev)
+4e: vrsqrt14ps/d Vpd,Wpd (66),(ev)
+4f: vrsqrt14ss/d Vsd,Hsd,Wsd (66),(ev)
+# Skip 0x50-0x57
 58: vpbroadcastd Vx,Wx (66),(v)
-59: vpbroadcastq Vx,Wx (66),(v)
-5a: vbroadcasti128 Vqq,Mdq (66),(v)
-# Skip 0x5b-0x77
+59: vpbroadcastq Vx,Wx (66),(v) | vbroadcasti32x2 Vx,Wx (66),(evo)
+5a: vbroadcasti128 Vqq,Mdq (66),(v) | vbroadcasti32x4/64x2 Vx,Wx (66),(evo)
+5b: vbroadcasti32x8/64x4 Vqq,Mdq (66),(ev)
+# Skip 0x5c-0x63
+64: vpblendmd/q Vx,Hx,Wx (66),(ev)
+65: vblendmps/d Vx,Hx,Wx (66),(ev)
+66: vpblendmb/w Vx,Hx,Wx (66),(ev)
+# Skip 0x67-0x74
+75: vpermi2b/w Vx,Hx,Wx (66),(ev)
+76: vpermi2d/q Vx,Hx,Wx (66),(ev)
+77: vpermi2ps/d Vx,Hx,Wx (66),(ev)
 78: vpbroadcastb Vx,Wx (66),(v)
 79: vpbroadcastw Vx,Wx (66),(v)
-# Skip 0x7a-0x7f
+7a: vpbroadcastb Vx,Rv (66),(ev)
+7b: vpbroadcastw Vx,Rv (66),(ev)
+7c: vpbroadcastd/q Vx,Rv (66),(ev)
+7d: vpermt2b/w Vx,Hx,Wx (66),(ev)
+7e: vpermt2d/q Vx,Hx,Wx (66),(ev)
+7f: vpermt2ps/d Vx,Hx,Wx (66),(ev)
 80: INVEPT Gy,Mdq (66)
 81: INVPID Gy,Mdq (66)
 82: INVPCID Gy,Mdq (66)
+83: vpmultishiftqb Vx,Hx,Wx (66),(ev)
+88: vexpandps/d Vpd,Wpd (66),(ev)
+89: vpexpandd/q Vx,Wx (66),(ev)
+8a: vcompressps/d Wx,Vx (66),(ev)
+8b: vpcompressd/q Wx,Vx (66),(ev)
 8c: vpmaskmovd/q Vx,Hx,Mx (66),(v)
+8d: vpermb/w Vx,Hx,Wx (66),(ev)
 8e: vpmaskmovd/q Mx,Vx,Hx (66),(v)
 # 0x0f 0x38 0x90-0xbf (FMA)
-90: vgatherdd/q Vx,Hx,Wx (66),(v)
-91: vgatherqd/q Vx,Hx,Wx (66),(v)
+90: vgatherdd/q Vx,Hx,Wx (66),(v) | vpgatherdd/q Vx,Wx (66),(evo)
+91: vgatherqd/q Vx,Hx,Wx (66),(v) | vpgatherqd/q Vx,Wx (66),(evo)
 92: vgatherdps/d Vx,Hx,Wx (66),(v)
 93: vgatherqps/d Vx,Hx,Wx (66),(v)
 94:
@@ -715,6 +744,10 @@ AVXcode: 2
 9d: vfnmadd132ss/d Vx,Hx,Wx (66),(v),(v1)
 9e: vfnmsub132ps/d Vx,Hx,Wx (66),(v)
 9f: vfnmsub132ss/d Vx,Hx,Wx (66),(v),(v1)
+a0: vpscatterdd/q Wx,Vx (66),(ev)
+a1: vpscatterqd/q Wx,Vx (66),(ev)
+a2: vscatterdps/d Wx,Vx (66),(ev)
+a3: vscatterqps/d Wx,Vx (66),(ev)
 a6: vfmaddsub213ps/d Vx,Hx,Wx (66),(v)
 a7: vfmsubadd213ps/d Vx,Hx,Wx (66),(v)
 a8: vfmadd213ps/d Vx,Hx,Wx (66),(v)
@@ -725,6 +758,8 @@ ac: vfnmadd213ps/d Vx,Hx,Wx (66),(v)
 ad: vfnmadd213ss/d Vx,Hx,Wx (66),(v),(v1)
 ae: vfnmsub213ps/d Vx,Hx,Wx (66),(v)
 af: vfnmsub213ss/d Vx,Hx,Wx (66),(v),(v1)
+b4: vpmadd52luq Vx,Hx,Wx (66),(ev)
+b5: vpmadd52huq Vx,Hx,Wx (66),(ev)
 b6: vfmaddsub231ps/d Vx,Hx,Wx (66),(v)
 b7: vfmsubadd231ps/d Vx,Hx,Wx (66),(v)
 b8: vfmadd231ps/d Vx,Hx,Wx (66),(v)
@@ -736,12 +771,15 @@ bd: vfnmadd231ss/d Vx,Hx,Wx (66),(v),(v1
 be: vfnmsub231ps/d Vx,Hx,Wx (66),(v)
 bf: vfnmsub231ss/d Vx,Hx,Wx (66),(v),(v1)
 # 0x0f 0x38 0xc0-0xff
-c8: sha1nexte Vdq,Wdq
+c4: vpconflictd/q Vx,Wx (66),(ev)
+c6: Grp18 (1A)
+c7: Grp19 (1A)
+c8: sha1nexte Vdq,Wdq | vexp2ps/d Vx,Wx (66),(ev)
 c9: sha1msg1 Vdq,Wdq
-ca: sha1msg2 Vdq,Wdq
-cb: sha256rnds2 Vdq,Wdq
-cc: sha256msg1 Vdq,Wdq
-cd: sha256msg2 Vdq,Wdq
+ca: sha1msg2 Vdq,Wdq | vrcp28ps/d Vx,Wx (66),(ev)
+cb: sha256rnds2 Vdq,Wdq | vrcp28ss/d Vx,Hx,Wx (66),(ev)
+cc: sha256msg1 Vdq,Wdq | vrsqrt28ps/d Vx,Wx (66),(ev)
+cd: sha256msg2 Vdq,Wdq | vrsqrt28ss/d Vx,Hx,Wx (66),(ev)
 db: VAESIMC Vdq,Wdq (66),(v1)
 dc: VAESENC Vdq,Hdq,Wdq (66),(v1)
 dd: VAESENCLAST Vdq,Hdq,Wdq (66),(v1)
@@ -763,15 +801,15 @@ AVXcode: 3
 00: vpermq Vqq,Wqq,Ib (66),(v)
 01: vpermpd Vqq,Wqq,Ib (66),(v)
 02: vpblendd Vx,Hx,Wx,Ib (66),(v)
-03:
+03: valignd/q Vx,Hx,Wx,Ib (66),(ev)
 04: vpermilps Vx,Wx,Ib (66),(v)
 05: vpermilpd Vx,Wx,Ib (66),(v)
 06: vperm2f128 Vqq,Hqq,Wqq,Ib (66),(v)
 07:
-08: vroundps Vx,Wx,Ib (66)
-09: vroundpd Vx,Wx,Ib (66)
-0a: vroundss Vss,Wss,Ib (66),(v1)
-0b: vroundsd Vsd,Wsd,Ib (66),(v1)
+08: vroundps Vx,Wx,Ib (66) | vrndscaleps Vx,Wx,Ib (66),(evo)
+09: vroundpd Vx,Wx,Ib (66) | vrndscalepd Vx,Wx,Ib (66),(evo)
+0a: vroundss Vss,Wss,Ib (66),(v1) | vrndscaless Vx,Hx,Wx,Ib (66),(evo)
+0b: vroundsd Vsd,Wsd,Ib (66),(v1) | vrndscalesd Vx,Hx,Wx,Ib (66),(evo)
 0c: vblendps Vx,Hx,Wx,Ib (66)
 0d: vblendpd Vx,Hx,Wx,Ib (66)
 0e: vpblendw Vx,Hx,Wx,Ib (66),(v1)
@@ -780,26 +818,51 @@ AVXcode: 3
 15: vpextrw Rd/Mw,Vdq,Ib (66),(v1)
 16: vpextrd/q Ey,Vdq,Ib (66),(v1)
 17: vextractps Ed,Vdq,Ib (66),(v1)
-18: vinsertf128 Vqq,Hqq,Wqq,Ib (66),(v)
-19: vextractf128 Wdq,Vqq,Ib (66),(v)
+18: vinsertf128 Vqq,Hqq,Wqq,Ib (66),(v) | vinsertf32x4/64x2 Vqq,Hqq,Wqq,Ib (66),(evo)
+19: vextractf128 Wdq,Vqq,Ib (66),(v) | vextractf32x4/64x2 Wdq,Vqq,Ib (66),(evo)
+1a: vinsertf32x8/64x4 Vqq,Hqq,Wqq,Ib (66),(ev)
+1b: vextractf32x8/64x4 Wdq,Vqq,Ib (66),(ev)
 1d: vcvtps2ph Wx,Vx,Ib (66),(v)
+1e: vpcmpud/q Vk,Hd,Wd,Ib (66),(ev)
+1f: vpcmpd/q Vk,Hd,Wd,Ib (66),(ev)
 20: vpinsrb Vdq,Hdq,Ry/Mb,Ib (66),(v1)
 21: vinsertps Vdq,Hdq,Udq/Md,Ib (66),(v1)
 22: vpinsrd/q Vdq,Hdq,Ey,Ib (66),(v1)
-38: vinserti128 Vqq,Hqq,Wqq,Ib (66),(v)
-39: vextracti128 Wdq,Vqq,Ib (66),(v)
+23: vshuff32x4/64x2 Vx,Hx,Wx,Ib (66),(ev)
+25: vpternlogd/q Vx,Hx,Wx,Ib (66),(ev)
+26: vgetmantps/d Vx,Wx,Ib (66),(ev)
+27: vgetmantss/d Vx,Hx,Wx,Ib (66),(ev)
+30: kshiftrb/w Vk,Uk,Ib (66),(v)
+31: kshiftrd/q Vk,Uk,Ib (66),(v)
+32: kshiftlb/w Vk,Uk,Ib (66),(v)
+33: kshiftld/q Vk,Uk,Ib (66),(v)
+38: vinserti128 Vqq,Hqq,Wqq,Ib (66),(v) | vinserti32x4/64x2 Vqq,Hqq,Wqq,Ib (66),(evo)
+39: vextracti128 Wdq,Vqq,Ib (66),(v) | vextracti32x4/64x2 Wdq,Vqq,Ib (66),(evo)
+3a: vinserti32x8/64x4 Vqq,Hqq,Wqq,Ib (66),(ev)
+3b: vextracti32x8/64x4 Wdq,Vqq,Ib (66),(ev)
+3e: vpcmpub/w Vk,Hk,Wx,Ib (66),(ev)
+3f: vpcmpb/w Vk,Hk,Wx,Ib (66),(ev)
 40: vdpps Vx,Hx,Wx,Ib (66)
 41: vdppd Vdq,Hdq,Wdq,Ib (66),(v1)
-42: vmpsadbw Vx,Hx,Wx,Ib (66),(v1)
+42: vmpsadbw Vx,Hx,Wx,Ib (66),(v1) | vdbpsadbw Vx,Hx,Wx,Ib (66),(evo)
+43: vshufi32x4/64x2 Vx,Hx,Wx,Ib (66),(ev)
 44: vpclmulqdq Vdq,Hdq,Wdq,Ib (66),(v1)
 46: vperm2i128 Vqq,Hqq,Wqq,Ib (66),(v)
 4a: vblendvps Vx,Hx,Wx,Lx (66),(v)
 4b: vblendvpd Vx,Hx,Wx,Lx (66),(v)
 4c: vpblendvb Vx,Hx,Wx,Lx (66),(v1)
+50: vrangeps/d Vx,Hx,Wx,Ib (66),(ev)
+51: vrangess/d Vx,Hx,Wx,Ib (66),(ev)
+54: vfixupimmps/d Vx,Hx,Wx,Ib (66),(ev)
+55: vfixupimmss/d Vx,Hx,Wx,Ib (66),(ev)
+56: vreduceps/d Vx,Wx,Ib (66),(ev)
+57: vreducess/d Vx,Hx,Wx,Ib (66),(ev)
 60: vpcmpestrm Vdq,Wdq,Ib (66),(v1)
 61: vpcmpestri Vdq,Wdq,Ib (66),(v1)
 62: vpcmpistrm Vdq,Wdq,Ib (66),(v1)
 63: vpcmpistri Vdq,Wdq,Ib (66),(v1)
+66: vfpclassps/d Vk,Wx,Ib (66),(ev)
+67: vfpclassss/d Vk,Wx,Ib (66),(ev)
 cc: sha1rnds4 Vdq,Wdq,Ib
 df: VAESKEYGEN Vdq,Wdq,Ib (66),(v1)
 f0: RORX Gy,Ey,Ib (F2),(v)
@@ -927,8 +990,10 @@ GrpTable: Grp12
 EndTable
 
 GrpTable: Grp13
+0: vprord/q Hx,Wx,Ib (66),(ev)
+1: vprold/q Hx,Wx,Ib (66),(ev)
 2: psrld Nq,Ib (11B) | vpsrld Hx,Ux,Ib (66),(11B),(v1)
-4: psrad Nq,Ib (11B) | vpsrad Hx,Ux,Ib (66),(11B),(v1)
+4: psrad Nq,Ib (11B) | vpsrad Hx,Ux,Ib (66),(11B),(v1) | vpsrad/q Hx,Ux,Ib (66),(evo)
 6: pslld Nq,Ib (11B) | vpslld Hx,Ux,Ib (66),(11B),(v1)
 EndTable
 
@@ -963,6 +1028,20 @@ GrpTable: Grp17
 3: BLSI By,Ey (v)
 EndTable
 
+GrpTable: Grp18
+1: vgatherpf0dps/d Wx (66),(ev)
+2: vgatherpf1dps/d Wx (66),(ev)
+5: vscatterpf0dps/d Wx (66),(ev)
+6: vscatterpf1dps/d Wx (66),(ev)
+EndTable
+
+GrpTable: Grp19
+1: vgatherpf0qps/d Wx (66),(ev)
+2: vgatherpf1qps/d Wx (66),(ev)
+5: vscatterpf0qps/d Wx (66),(ev)
+6: vscatterpf1qps/d Wx (66),(ev)
+EndTable
+
 # AMD's Prefetch Group
 GrpTable: GrpP
 0: PREFETCH
--- zfcpdump-kernel-4.4.orig/arch/x86/mm/fault.c
+++ zfcpdump-kernel-4.4/arch/x86/mm/fault.c
@@ -287,6 +287,9 @@ static noinline int vmalloc_fault(unsign
 	if (!pmd_k)
 		return -1;
 
+	if (pmd_huge(*pmd_k))
+		return 0;
+
 	pte_k = pte_offset_kernel(pmd_k, address);
 	if (!pte_present(*pte_k))
 		return -1;
@@ -360,8 +363,6 @@ void vmalloc_sync_all(void)
  * 64-bit:
  *
  *   Handle a fault on the vmalloc area
- *
- * This assumes no large pages in there.
  */
 static noinline int vmalloc_fault(unsigned long address)
 {
@@ -403,17 +404,23 @@ static noinline int vmalloc_fault(unsign
 	if (pud_none(*pud_ref))
 		return -1;
 
-	if (pud_none(*pud) || pud_page_vaddr(*pud) != pud_page_vaddr(*pud_ref))
+	if (pud_none(*pud) || pud_pfn(*pud) != pud_pfn(*pud_ref))
 		BUG();
 
+	if (pud_huge(*pud))
+		return 0;
+
 	pmd = pmd_offset(pud, address);
 	pmd_ref = pmd_offset(pud_ref, address);
 	if (pmd_none(*pmd_ref))
 		return -1;
 
-	if (pmd_none(*pmd) || pmd_page(*pmd) != pmd_page(*pmd_ref))
+	if (pmd_none(*pmd) || pmd_pfn(*pmd) != pmd_pfn(*pmd_ref))
 		BUG();
 
+	if (pmd_huge(*pmd))
+		return 0;
+
 	pte_ref = pte_offset_kernel(pmd_ref, address);
 	if (!pte_present(*pte_ref))
 		return -1;
--- zfcpdump-kernel-4.4.orig/arch/x86/mm/kmmio.c
+++ zfcpdump-kernel-4.4/arch/x86/mm/kmmio.c
@@ -33,7 +33,7 @@
 struct kmmio_fault_page {
 	struct list_head list;
 	struct kmmio_fault_page *release_next;
-	unsigned long page; /* location of the fault page */
+	unsigned long addr; /* the requested address */
 	pteval_t old_presence; /* page presence prior to arming */
 	bool armed;
 
@@ -70,9 +70,16 @@ unsigned int kmmio_count;
 static struct list_head kmmio_page_table[KMMIO_PAGE_TABLE_SIZE];
 static LIST_HEAD(kmmio_probes);
 
-static struct list_head *kmmio_page_list(unsigned long page)
+static struct list_head *kmmio_page_list(unsigned long addr)
 {
-	return &kmmio_page_table[hash_long(page, KMMIO_PAGE_HASH_BITS)];
+	unsigned int l;
+	pte_t *pte = lookup_address(addr, &l);
+
+	if (!pte)
+		return NULL;
+	addr &= page_level_mask(l);
+
+	return &kmmio_page_table[hash_long(addr, KMMIO_PAGE_HASH_BITS)];
 }
 
 /* Accessed per-cpu */
@@ -98,15 +105,19 @@ static struct kmmio_probe *get_kmmio_pro
 }
 
 /* You must be holding RCU read lock. */
-static struct kmmio_fault_page *get_kmmio_fault_page(unsigned long page)
+static struct kmmio_fault_page *get_kmmio_fault_page(unsigned long addr)
 {
 	struct list_head *head;
 	struct kmmio_fault_page *f;
+	unsigned int l;
+	pte_t *pte = lookup_address(addr, &l);
 
-	page &= PAGE_MASK;
-	head = kmmio_page_list(page);
+	if (!pte)
+		return NULL;
+	addr &= page_level_mask(l);
+	head = kmmio_page_list(addr);
 	list_for_each_entry_rcu(f, head, list) {
-		if (f->page == page)
+		if (f->addr == addr)
 			return f;
 	}
 	return NULL;
@@ -137,10 +148,10 @@ static void clear_pte_presence(pte_t *pt
 static int clear_page_presence(struct kmmio_fault_page *f, bool clear)
 {
 	unsigned int level;
-	pte_t *pte = lookup_address(f->page, &level);
+	pte_t *pte = lookup_address(f->addr, &level);
 
 	if (!pte) {
-		pr_err("no pte for page 0x%08lx\n", f->page);
+		pr_err("no pte for addr 0x%08lx\n", f->addr);
 		return -1;
 	}
 
@@ -156,7 +167,7 @@ static int clear_page_presence(struct km
 		return -1;
 	}
 
-	__flush_tlb_one(f->page);
+	__flush_tlb_one(f->addr);
 	return 0;
 }
 
@@ -176,12 +187,12 @@ static int arm_kmmio_fault_page(struct k
 	int ret;
 	WARN_ONCE(f->armed, KERN_ERR pr_fmt("kmmio page already armed.\n"));
 	if (f->armed) {
-		pr_warning("double-arm: page 0x%08lx, ref %d, old %d\n",
-			   f->page, f->count, !!f->old_presence);
+		pr_warning("double-arm: addr 0x%08lx, ref %d, old %d\n",
+			   f->addr, f->count, !!f->old_presence);
 	}
 	ret = clear_page_presence(f, true);
-	WARN_ONCE(ret < 0, KERN_ERR pr_fmt("arming 0x%08lx failed.\n"),
-		  f->page);
+	WARN_ONCE(ret < 0, KERN_ERR pr_fmt("arming at 0x%08lx failed.\n"),
+		  f->addr);
 	f->armed = true;
 	return ret;
 }
@@ -191,7 +202,7 @@ static void disarm_kmmio_fault_page(stru
 {
 	int ret = clear_page_presence(f, false);
 	WARN_ONCE(ret < 0,
-			KERN_ERR "kmmio disarming 0x%08lx failed.\n", f->page);
+			KERN_ERR "kmmio disarming at 0x%08lx failed.\n", f->addr);
 	f->armed = false;
 }
 
@@ -215,6 +226,12 @@ int kmmio_handler(struct pt_regs *regs,
 	struct kmmio_context *ctx;
 	struct kmmio_fault_page *faultpage;
 	int ret = 0; /* default to fault not handled */
+	unsigned long page_base = addr;
+	unsigned int l;
+	pte_t *pte = lookup_address(addr, &l);
+	if (!pte)
+		return -EINVAL;
+	page_base &= page_level_mask(l);
 
 	/*
 	 * Preemption is now disabled to prevent process switch during
@@ -227,7 +244,7 @@ int kmmio_handler(struct pt_regs *regs,
 	preempt_disable();
 	rcu_read_lock();
 
-	faultpage = get_kmmio_fault_page(addr);
+	faultpage = get_kmmio_fault_page(page_base);
 	if (!faultpage) {
 		/*
 		 * Either this page fault is not caused by kmmio, or
@@ -239,7 +256,7 @@ int kmmio_handler(struct pt_regs *regs,
 
 	ctx = &get_cpu_var(kmmio_ctx);
 	if (ctx->active) {
-		if (addr == ctx->addr) {
+		if (page_base == ctx->addr) {
 			/*
 			 * A second fault on the same page means some other
 			 * condition needs handling by do_page_fault(), the
@@ -267,9 +284,9 @@ int kmmio_handler(struct pt_regs *regs,
 	ctx->active++;
 
 	ctx->fpage = faultpage;
-	ctx->probe = get_kmmio_probe(addr);
+	ctx->probe = get_kmmio_probe(page_base);
 	ctx->saved_flags = (regs->flags & (X86_EFLAGS_TF | X86_EFLAGS_IF));
-	ctx->addr = addr;
+	ctx->addr = page_base;
 
 	if (ctx->probe && ctx->probe->pre_handler)
 		ctx->probe->pre_handler(ctx->probe, regs, addr);
@@ -354,12 +371,11 @@ out:
 }
 
 /* You must be holding kmmio_lock. */
-static int add_kmmio_fault_page(unsigned long page)
+static int add_kmmio_fault_page(unsigned long addr)
 {
 	struct kmmio_fault_page *f;
 
-	page &= PAGE_MASK;
-	f = get_kmmio_fault_page(page);
+	f = get_kmmio_fault_page(addr);
 	if (f) {
 		if (!f->count)
 			arm_kmmio_fault_page(f);
@@ -372,26 +388,25 @@ static int add_kmmio_fault_page(unsigned
 		return -1;
 
 	f->count = 1;
-	f->page = page;
+	f->addr = addr;
 
 	if (arm_kmmio_fault_page(f)) {
 		kfree(f);
 		return -1;
 	}
 
-	list_add_rcu(&f->list, kmmio_page_list(f->page));
+	list_add_rcu(&f->list, kmmio_page_list(f->addr));
 
 	return 0;
 }
 
 /* You must be holding kmmio_lock. */
-static void release_kmmio_fault_page(unsigned long page,
+static void release_kmmio_fault_page(unsigned long addr,
 				struct kmmio_fault_page **release_list)
 {
 	struct kmmio_fault_page *f;
 
-	page &= PAGE_MASK;
-	f = get_kmmio_fault_page(page);
+	f = get_kmmio_fault_page(addr);
 	if (!f)
 		return;
 
@@ -420,18 +435,27 @@ int register_kmmio_probe(struct kmmio_pr
 	int ret = 0;
 	unsigned long size = 0;
 	const unsigned long size_lim = p->len + (p->addr & ~PAGE_MASK);
+	unsigned int l;
+	pte_t *pte;
 
 	spin_lock_irqsave(&kmmio_lock, flags);
 	if (get_kmmio_probe(p->addr)) {
 		ret = -EEXIST;
 		goto out;
 	}
+
+	pte = lookup_address(p->addr, &l);
+	if (!pte) {
+		ret = -EINVAL;
+		goto out;
+	}
+
 	kmmio_count++;
 	list_add_rcu(&p->list, &kmmio_probes);
 	while (size < size_lim) {
 		if (add_kmmio_fault_page(p->addr + size))
 			pr_err("Unable to set page fault.\n");
-		size += PAGE_SIZE;
+		size += page_level_size(l);
 	}
 out:
 	spin_unlock_irqrestore(&kmmio_lock, flags);
@@ -506,11 +530,17 @@ void unregister_kmmio_probe(struct kmmio
 	const unsigned long size_lim = p->len + (p->addr & ~PAGE_MASK);
 	struct kmmio_fault_page *release_list = NULL;
 	struct kmmio_delayed_release *drelease;
+	unsigned int l;
+	pte_t *pte;
+
+	pte = lookup_address(p->addr, &l);
+	if (!pte)
+		return;
 
 	spin_lock_irqsave(&kmmio_lock, flags);
 	while (size < size_lim) {
 		release_kmmio_fault_page(p->addr + size, &release_list);
-		size += PAGE_SIZE;
+		size += page_level_size(l);
 	}
 	list_del_rcu(&p->list);
 	kmmio_count--;
--- zfcpdump-kernel-4.4.orig/arch/x86/mm/mmap.c
+++ zfcpdump-kernel-4.4/arch/x86/mm/mmap.c
@@ -94,18 +94,6 @@ static unsigned long mmap_base(unsigned
 }
 
 /*
- * Bottom-up (legacy) layout on X86_32 did not support randomization, X86_64
- * does, but not when emulating X86_32
- */
-static unsigned long mmap_legacy_base(unsigned long rnd)
-{
-	if (mmap_is_ia32())
-		return TASK_UNMAPPED_BASE;
-	else
-		return TASK_UNMAPPED_BASE + rnd;
-}
-
-/*
  * This function, called very early during the creation of a new
  * process VM image, sets up which VM layout function to use:
  */
@@ -116,7 +104,7 @@ void arch_pick_mmap_layout(struct mm_str
 	if (current->flags & PF_RANDOMIZE)
 		random_factor = arch_mmap_rnd();
 
-	mm->mmap_legacy_base = mmap_legacy_base(random_factor);
+	mm->mmap_legacy_base = TASK_UNMAPPED_BASE + random_factor;
 
 	if (mmap_is_legacy()) {
 		mm->mmap_base = mm->mmap_legacy_base;
--- zfcpdump-kernel-4.4.orig/arch/x86/mm/mpx.c
+++ zfcpdump-kernel-4.4/arch/x86/mm/mpx.c
@@ -123,7 +123,7 @@ static int get_reg_offset(struct insn *i
 		break;
 	}
 
-	if (regno > nr_registers) {
+	if (regno >= nr_registers) {
 		WARN_ONCE(1, "decoded an instruction with an invalid register");
 		return -EINVAL;
 	}
--- zfcpdump-kernel-4.4.orig/arch/x86/mm/pageattr.c
+++ zfcpdump-kernel-4.4/arch/x86/mm/pageattr.c
@@ -33,7 +33,7 @@ struct cpa_data {
 	pgd_t		*pgd;
 	pgprot_t	mask_set;
 	pgprot_t	mask_clr;
-	int		numpages;
+	unsigned long	numpages;
 	int		flags;
 	unsigned long	pfn;
 	unsigned	force_split : 1;
@@ -414,24 +414,30 @@ pmd_t *lookup_pmd_address(unsigned long
 phys_addr_t slow_virt_to_phys(void *__virt_addr)
 {
 	unsigned long virt_addr = (unsigned long)__virt_addr;
-	unsigned long phys_addr, offset;
+	phys_addr_t phys_addr;
+	unsigned long offset;
 	enum pg_level level;
 	pte_t *pte;
 
 	pte = lookup_address(virt_addr, &level);
 	BUG_ON(!pte);
 
+	/*
+	 * pXX_pfn() returns unsigned long, which must be cast to phys_addr_t
+	 * before being left-shifted PAGE_SHIFT bits -- this trick is to
+	 * make 32-PAE kernel work correctly.
+	 */
 	switch (level) {
 	case PG_LEVEL_1G:
-		phys_addr = pud_pfn(*(pud_t *)pte) << PAGE_SHIFT;
+		phys_addr = (phys_addr_t)pud_pfn(*(pud_t *)pte) << PAGE_SHIFT;
 		offset = virt_addr & ~PUD_PAGE_MASK;
 		break;
 	case PG_LEVEL_2M:
-		phys_addr = pmd_pfn(*(pmd_t *)pte) << PAGE_SHIFT;
+		phys_addr = (phys_addr_t)pmd_pfn(*(pmd_t *)pte) << PAGE_SHIFT;
 		offset = virt_addr & ~PMD_PAGE_MASK;
 		break;
 	default:
-		phys_addr = pte_pfn(*pte) << PAGE_SHIFT;
+		phys_addr = (phys_addr_t)pte_pfn(*pte) << PAGE_SHIFT;
 		offset = virt_addr & ~PAGE_MASK;
 	}
 
@@ -1345,7 +1351,7 @@ static int __change_page_attr_set_clr(st
 		 * CPA operation. Either a large page has been
 		 * preserved or a single page update happened.
 		 */
-		BUG_ON(cpa->numpages > numpages);
+		BUG_ON(cpa->numpages > numpages || !cpa->numpages);
 		numpages -= cpa->numpages;
 		if (cpa->flags & (CPA_PAGES_ARRAY | CPA_ARRAY))
 			cpa->curpage++;
--- zfcpdump-kernel-4.4.orig/arch/x86/mm/pat.c
+++ zfcpdump-kernel-4.4/arch/x86/mm/pat.c
@@ -39,11 +39,22 @@
 static bool boot_cpu_done;
 
 static int __read_mostly __pat_enabled = IS_ENABLED(CONFIG_X86_PAT);
+static void init_cache_modes(void);
 
-static inline void pat_disable(const char *reason)
+void pat_disable(const char *reason)
 {
+	if (!__pat_enabled)
+		return;
+
+	if (boot_cpu_done) {
+		WARN_ONCE(1, "x86/PAT: PAT cannot be disabled after initialization\n");
+		return;
+	}
+
 	__pat_enabled = 0;
 	pr_info("x86/PAT: %s\n", reason);
+
+	init_cache_modes();
 }
 
 static int __init nopat(char *str)
@@ -180,7 +191,7 @@ static enum page_cache_mode pat_get_cach
  * configuration.
  * Using lower indices is preferred, so we start with highest index.
  */
-void pat_init_cache_modes(u64 pat)
+static void __init_cache_modes(u64 pat)
 {
 	enum page_cache_mode cache;
 	char pat_msg[33];
@@ -201,14 +212,11 @@ static void pat_bsp_init(u64 pat)
 {
 	u64 tmp_pat;
 
-	if (!cpu_has_pat) {
+	if (!boot_cpu_has(X86_FEATURE_PAT)) {
 		pat_disable("PAT not supported by CPU.");
 		return;
 	}
 
-	if (!pat_enabled())
-		goto done;
-
 	rdmsrl(MSR_IA32_CR_PAT, tmp_pat);
 	if (!tmp_pat) {
 		pat_disable("PAT MSR is 0, disabled.");
@@ -217,16 +225,12 @@ static void pat_bsp_init(u64 pat)
 
 	wrmsrl(MSR_IA32_CR_PAT, pat);
 
-done:
-	pat_init_cache_modes(pat);
+	__init_cache_modes(pat);
 }
 
 static void pat_ap_init(u64 pat)
 {
-	if (!pat_enabled())
-		return;
-
-	if (!cpu_has_pat) {
+	if (!boot_cpu_has(X86_FEATURE_PAT)) {
 		/*
 		 * If this happens we are on a secondary CPU, but switched to
 		 * PAT on the boot CPU. We have no way to undo PAT.
@@ -237,18 +241,32 @@ static void pat_ap_init(u64 pat)
 	wrmsrl(MSR_IA32_CR_PAT, pat);
 }
 
-void pat_init(void)
+static void init_cache_modes(void)
 {
-	u64 pat;
-	struct cpuinfo_x86 *c = &boot_cpu_data;
+	u64 pat = 0;
+	static int init_cm_done;
 
-	if (!pat_enabled()) {
+	if (init_cm_done)
+		return;
+
+	if (boot_cpu_has(X86_FEATURE_PAT)) {
+		/*
+		 * CPU supports PAT. Set PAT table to be consistent with
+		 * PAT MSR. This case supports "nopat" boot option, and
+		 * virtual machine environments which support PAT without
+		 * MTRRs. In specific, Xen has unique setup to PAT MSR.
+		 *
+		 * If PAT MSR returns 0, it is considered invalid and emulates
+		 * as No PAT.
+		 */
+		rdmsrl(MSR_IA32_CR_PAT, pat);
+	}
+
+	if (!pat) {
 		/*
 		 * No PAT. Emulate the PAT table that corresponds to the two
-		 * cache bits, PWT (Write Through) and PCD (Cache Disable). This
-		 * setup is the same as the BIOS default setup when the system
-		 * has PAT but the "nopat" boot option has been specified. This
-		 * emulated PAT table is used when MSR_IA32_CR_PAT returns 0.
+		 * cache bits, PWT (Write Through) and PCD (Cache Disable).
+		 * This setup is also the same as the BIOS default setup.
 		 *
 		 * PTE encoding:
 		 *
@@ -265,10 +283,36 @@ void pat_init(void)
 		 */
 		pat = PAT(0, WB) | PAT(1, WT) | PAT(2, UC_MINUS) | PAT(3, UC) |
 		      PAT(4, WB) | PAT(5, WT) | PAT(6, UC_MINUS) | PAT(7, UC);
+	}
+
+	__init_cache_modes(pat);
+
+	init_cm_done = 1;
+}
+
+/**
+ * pat_init - Initialize PAT MSR and PAT table
+ *
+ * This function initializes PAT MSR and PAT table with an OS-defined value
+ * to enable additional cache attributes, WC and WT.
+ *
+ * This function must be called on all CPUs using the specific sequence of
+ * operations defined in Intel SDM. mtrr_rendezvous_handler() provides this
+ * procedure for PAT.
+ */
+void pat_init(void)
+{
+	u64 pat;
+	struct cpuinfo_x86 *c = &boot_cpu_data;
+
+	if (!pat_enabled()) {
+		init_cache_modes();
+		return;
+	}
 
-	} else if ((c->x86_vendor == X86_VENDOR_INTEL) &&
-		   (((c->x86 == 0x6) && (c->x86_model <= 0xd)) ||
-		    ((c->x86 == 0xf) && (c->x86_model <= 0x6)))) {
+	if ((c->x86_vendor == X86_VENDOR_INTEL) &&
+	    (((c->x86 == 0x6) && (c->x86_model <= 0xd)) ||
+	     ((c->x86 == 0xf) && (c->x86_model <= 0x6)))) {
 		/*
 		 * PAT support with the lower four entries. Intel Pentium 2,
 		 * 3, M, and 4 are affected by PAT errata, which makes the
@@ -733,25 +777,6 @@ int phys_mem_access_prot_allowed(struct
 	if (file->f_flags & O_DSYNC)
 		pcm = _PAGE_CACHE_MODE_UC_MINUS;
 
-#ifdef CONFIG_X86_32
-	/*
-	 * On the PPro and successors, the MTRRs are used to set
-	 * memory types for physical addresses outside main memory,
-	 * so blindly setting UC or PWT on those pages is wrong.
-	 * For Pentiums and earlier, the surround logic should disable
-	 * caching for the high addresses through the KEN pin, but
-	 * we maintain the tradition of paranoia in this code.
-	 */
-	if (!pat_enabled() &&
-	    !(boot_cpu_has(X86_FEATURE_MTRR) ||
-	      boot_cpu_has(X86_FEATURE_K6_MTRR) ||
-	      boot_cpu_has(X86_FEATURE_CYRIX_ARR) ||
-	      boot_cpu_has(X86_FEATURE_CENTAUR_MCR)) &&
-	    (pfn << PAGE_SHIFT) >= __pa(high_memory)) {
-		pcm = _PAGE_CACHE_MODE_UC;
-	}
-#endif
-
 	*vma_prot = __pgprot((pgprot_val(*vma_prot) & ~_PAGE_CACHE_MASK) |
 			     cachemode2protval(pcm));
 	return 1;
--- zfcpdump-kernel-4.4.orig/arch/x86/mm/setup_nx.c
+++ zfcpdump-kernel-4.4/arch/x86/mm/setup_nx.c
@@ -4,6 +4,7 @@
 
 #include <asm/pgtable.h>
 #include <asm/proto.h>
+#include <asm/cpufeature.h>
 
 static int disable_nx;
 
--- zfcpdump-kernel-4.4.orig/arch/x86/mm/tlb.c
+++ zfcpdump-kernel-4.4/arch/x86/mm/tlb.c
@@ -106,8 +106,6 @@ static void flush_tlb_func(void *info)
 
 	if (f->flush_mm != this_cpu_read(cpu_tlbstate.active_mm))
 		return;
-	if (!f->flush_end)
-		f->flush_end = f->flush_start + PAGE_SIZE;
 
 	count_vm_tlb_event(NR_TLB_REMOTE_FLUSH_RECEIVED);
 	if (this_cpu_read(cpu_tlbstate.state) == TLBSTATE_OK) {
@@ -135,12 +133,20 @@ void native_flush_tlb_others(const struc
 				 unsigned long end)
 {
 	struct flush_tlb_info info;
+
+	if (end == 0)
+		end = start + PAGE_SIZE;
 	info.flush_mm = mm;
 	info.flush_start = start;
 	info.flush_end = end;
 
 	count_vm_tlb_event(NR_TLB_REMOTE_FLUSH);
-	trace_tlb_flush(TLB_REMOTE_SEND_IPI, end - start);
+	if (end == TLB_FLUSH_ALL)
+		trace_tlb_flush(TLB_REMOTE_SEND_IPI, TLB_FLUSH_ALL);
+	else
+		trace_tlb_flush(TLB_REMOTE_SEND_IPI,
+				(end - start) >> PAGE_SHIFT);
+
 	if (is_uv_system()) {
 		unsigned int cpu;
 
@@ -161,7 +167,10 @@ void flush_tlb_current_task(void)
 	preempt_disable();
 
 	count_vm_tlb_event(NR_TLB_LOCAL_FLUSH_ALL);
+
+	/* This is an implicit full barrier that synchronizes with switch_mm. */
 	local_flush_tlb();
+
 	trace_tlb_flush(TLB_LOCAL_SHOOTDOWN, TLB_FLUSH_ALL);
 	if (cpumask_any_but(mm_cpumask(mm), smp_processor_id()) < nr_cpu_ids)
 		flush_tlb_others(mm_cpumask(mm), mm, 0UL, TLB_FLUSH_ALL);
@@ -188,17 +197,29 @@ void flush_tlb_mm_range(struct mm_struct
 	unsigned long base_pages_to_flush = TLB_FLUSH_ALL;
 
 	preempt_disable();
-	if (current->active_mm != mm)
+	if (current->active_mm != mm) {
+		/* Synchronize with switch_mm. */
+		smp_mb();
+
 		goto out;
+	}
 
 	if (!current->mm) {
 		leave_mm(smp_processor_id());
+
+		/* Synchronize with switch_mm. */
+		smp_mb();
+
 		goto out;
 	}
 
 	if ((end != TLB_FLUSH_ALL) && !(vmflag & VM_HUGETLB))
 		base_pages_to_flush = (end - start) >> PAGE_SHIFT;
 
+	/*
+	 * Both branches below are implicit full barriers (MOV to CR or
+	 * INVLPG) that synchronize with switch_mm.
+	 */
 	if (base_pages_to_flush > tlb_single_page_flush_ceiling) {
 		base_pages_to_flush = TLB_FLUSH_ALL;
 		count_vm_tlb_event(NR_TLB_LOCAL_FLUSH_ALL);
@@ -228,10 +249,18 @@ void flush_tlb_page(struct vm_area_struc
 	preempt_disable();
 
 	if (current->active_mm == mm) {
-		if (current->mm)
+		if (current->mm) {
+			/*
+			 * Implicit full barrier (INVLPG) that synchronizes
+			 * with switch_mm.
+			 */
 			__flush_tlb_one(start);
-		else
+		} else {
 			leave_mm(smp_processor_id());
+
+			/* Synchronize with switch_mm. */
+			smp_mb();
+		}
 	}
 
 	if (cpumask_any_but(mm_cpumask(mm), smp_processor_id()) < nr_cpu_ids)
--- zfcpdump-kernel-4.4.orig/arch/x86/oprofile/op_model_amd.c
+++ zfcpdump-kernel-4.4/arch/x86/oprofile/op_model_amd.c
@@ -24,7 +24,6 @@
 #include <asm/nmi.h>
 #include <asm/apic.h>
 #include <asm/processor.h>
-#include <asm/cpufeature.h>
 
 #include "op_x86_model.h"
 #include "op_counter.h"
--- zfcpdump-kernel-4.4.orig/arch/x86/pci/common.c
+++ zfcpdump-kernel-4.4/arch/x86/pci/common.c
@@ -673,28 +673,22 @@ int pcibios_add_device(struct pci_dev *d
 	return 0;
 }
 
-int pcibios_alloc_irq(struct pci_dev *dev)
+int pcibios_enable_device(struct pci_dev *dev, int mask)
 {
-	/*
-	 * If the PCI device was already claimed by core code and has
-	 * MSI enabled, probing of the pcibios IRQ will overwrite
-	 * dev->irq.  So bail out if MSI is already enabled.
-	 */
-	if (pci_dev_msi_enabled(dev))
-		return -EBUSY;
+	int err;
 
-	return pcibios_enable_irq(dev);
-}
+	if ((err = pci_enable_resources(dev, mask)) < 0)
+		return err;
 
-void pcibios_free_irq(struct pci_dev *dev)
-{
-	if (pcibios_disable_irq)
-		pcibios_disable_irq(dev);
+	if (!pci_dev_msi_enabled(dev))
+		return pcibios_enable_irq(dev);
+	return 0;
 }
 
-int pcibios_enable_device(struct pci_dev *dev, int mask)
+void pcibios_disable_device (struct pci_dev *dev)
 {
-	return pci_enable_resources(dev, mask);
+	if (!pci_dev_msi_enabled(dev) && pcibios_disable_irq)
+		pcibios_disable_irq(dev);
 }
 
 int pci_ext_cfg_avail(void)
--- zfcpdump-kernel-4.4.orig/arch/x86/pci/fixup.c
+++ zfcpdump-kernel-4.4/arch/x86/pci/fixup.c
@@ -540,3 +540,10 @@ static void twinhead_reserve_killing_zon
         }
 }
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x27B9, twinhead_reserve_killing_zone);
+
+static void pci_bdwep_bar(struct pci_dev *dev)
+{
+	dev->non_compliant_bars = 1;
+}
+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x6fa0, pci_bdwep_bar);
+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x6fc0, pci_bdwep_bar);
--- zfcpdump-kernel-4.4.orig/arch/x86/pci/intel_mid_pci.c
+++ zfcpdump-kernel-4.4/arch/x86/pci/intel_mid_pci.c
@@ -37,6 +37,7 @@
 
 /* Quirks for the listed devices */
 #define PCI_DEVICE_ID_INTEL_MRFL_MMC	0x1190
+#define PCI_DEVICE_ID_INTEL_MRFL_HSU	0x1191
 
 /* Fixed BAR fields */
 #define PCIE_VNDR_CAP_ID_FIXED_BAR 0x00	/* Fixed BAR (TBD) */
@@ -215,7 +216,7 @@ static int intel_mid_pci_irq_enable(stru
 	int polarity;
 	int ret;
 
-	if (pci_has_managed_irq(dev))
+	if (dev->irq_managed && dev->irq > 0)
 		return 0;
 
 	switch (intel_mid_identify_cpu()) {
@@ -225,13 +226,20 @@ static int intel_mid_pci_irq_enable(stru
 		/* Special treatment for IRQ0 */
 		if (dev->irq == 0) {
 			/*
+			 * Skip HS UART common registers device since it has
+			 * IRQ0 assigned and not used by the kernel.
+			 */
+			if (dev->device == PCI_DEVICE_ID_INTEL_MRFL_HSU)
+				return -EBUSY;
+			/*
 			 * TNG has IRQ0 assigned to eMMC controller. But there
 			 * are also other devices with bogus PCI configuration
 			 * that have IRQ0 assigned. This check ensures that
-			 * eMMC gets it.
+			 * eMMC gets it. The rest of devices still could be
+			 * enabled without interrupt line being allocated.
 			 */
 			if (dev->device != PCI_DEVICE_ID_INTEL_MRFL_MMC)
-				return -EBUSY;
+				return 0;
 		}
 		break;
 	default:
@@ -256,13 +264,10 @@ static int intel_mid_pci_irq_enable(stru
 
 static void intel_mid_pci_irq_disable(struct pci_dev *dev)
 {
-	if (pci_has_managed_irq(dev)) {
+	if (!mp_should_keep_irq(&dev->dev) && dev->irq_managed &&
+	    dev->irq > 0) {
 		mp_unmap_irq(dev->irq);
 		dev->irq_managed = 0;
-		/*
-		 * Don't reset dev->irq here, otherwise
-		 * intel_mid_pci_irq_enable() will fail on next call.
-		 */
 	}
 }
 
--- zfcpdump-kernel-4.4.orig/arch/x86/pci/irq.c
+++ zfcpdump-kernel-4.4/arch/x86/pci/irq.c
@@ -1202,7 +1202,7 @@ static int pirq_enable_irq(struct pci_de
 			struct pci_dev *temp_dev;
 			int irq;
 
-			if (pci_has_managed_irq(dev))
+			if (dev->irq_managed && dev->irq > 0)
 				return 0;
 
 			irq = IO_APIC_get_PCI_irq_vector(dev->bus->number,
@@ -1230,7 +1230,8 @@ static int pirq_enable_irq(struct pci_de
 			}
 			dev = temp_dev;
 			if (irq >= 0) {
-				pci_set_managed_irq(dev, irq);
+				dev->irq_managed = 1;
+				dev->irq = irq;
 				dev_info(&dev->dev, "PCI->APIC IRQ transform: "
 					 "INT %c -> IRQ %d\n", 'A' + pin - 1, irq);
 				return 0;
@@ -1256,10 +1257,24 @@ static int pirq_enable_irq(struct pci_de
 	return 0;
 }
 
+bool mp_should_keep_irq(struct device *dev)
+{
+	if (dev->power.is_prepared)
+		return true;
+#ifdef CONFIG_PM
+	if (dev->power.runtime_status == RPM_SUSPENDING)
+		return true;
+#endif
+
+	return false;
+}
+
 static void pirq_disable_irq(struct pci_dev *dev)
 {
-	if (io_apic_assign_pci_irqs && pci_has_managed_irq(dev)) {
+	if (io_apic_assign_pci_irqs && !mp_should_keep_irq(&dev->dev) &&
+	    dev->irq_managed && dev->irq) {
 		mp_unmap_irq(dev->irq);
-		pci_reset_managed_irq(dev);
+		dev->irq = 0;
+		dev->irq_managed = 0;
 	}
 }
--- zfcpdump-kernel-4.4.orig/arch/x86/pci/xen.c
+++ zfcpdump-kernel-4.4/arch/x86/pci/xen.c
@@ -488,8 +488,11 @@ int __init pci_xen_initial_domain(void)
 #endif
 	__acpi_register_gsi = acpi_register_gsi_xen;
 	__acpi_unregister_gsi = NULL;
-	/* Pre-allocate legacy irqs */
-	for (irq = 0; irq < nr_legacy_irqs(); irq++) {
+	/*
+	 * Pre-allocate the legacy IRQs.  Use NR_LEGACY_IRQS here
+	 * because we don't have a PIC and thus nr_legacy_irqs() is zero.
+	 */
+	for (irq = 0; irq < NR_IRQS_LEGACY; irq++) {
 		int trigger, polarity;
 
 		if (acpi_get_override_irq(irq, &trigger, &polarity) == -1)
--- zfcpdump-kernel-4.4.orig/arch/x86/platform/efi/quirks.c
+++ zfcpdump-kernel-4.4/arch/x86/platform/efi/quirks.c
@@ -54,13 +54,41 @@ void efi_delete_dummy_variable(void)
 }
 
 /*
+ * In the nonblocking case we do not attempt to perform garbage
+ * collection if we do not have enough free space. Rather, we do the
+ * bare minimum check and give up immediately if the available space
+ * is below EFI_MIN_RESERVE.
+ *
+ * This function is intended to be small and simple because it is
+ * invoked from crash handler paths.
+ */
+static efi_status_t
+query_variable_store_nonblocking(u32 attributes, unsigned long size)
+{
+	efi_status_t status;
+	u64 storage_size, remaining_size, max_size;
+
+	status = efi.query_variable_info_nonblocking(attributes, &storage_size,
+						     &remaining_size,
+						     &max_size);
+	if (status != EFI_SUCCESS)
+		return status;
+
+	if (remaining_size - size < EFI_MIN_RESERVE)
+		return EFI_OUT_OF_RESOURCES;
+
+	return EFI_SUCCESS;
+}
+
+/*
  * Some firmware implementations refuse to boot if there's insufficient space
  * in the variable store. Ensure that we never use more than a safe limit.
  *
  * Return EFI_SUCCESS if it is safe to write 'size' bytes to the variable
  * store.
  */
-efi_status_t efi_query_variable_store(u32 attributes, unsigned long size)
+efi_status_t efi_query_variable_store(u32 attributes, unsigned long size,
+				      bool nonblocking)
 {
 	efi_status_t status;
 	u64 storage_size, remaining_size, max_size;
@@ -68,6 +96,9 @@ efi_status_t efi_query_variable_store(u3
 	if (!(attributes & EFI_VARIABLE_NON_VOLATILE))
 		return 0;
 
+	if (nonblocking)
+		return query_variable_store_nonblocking(attributes, size);
+
 	status = efi.query_variable_info(attributes, &storage_size,
 					 &remaining_size, &max_size);
 	if (status != EFI_SUCCESS)
--- zfcpdump-kernel-4.4.orig/arch/x86/power/hibernate_64.c
+++ zfcpdump-kernel-4.4/arch/x86/power/hibernate_64.c
@@ -19,6 +19,7 @@
 #include <asm/mtrr.h>
 #include <asm/sections.h>
 #include <asm/suspend.h>
+#include <asm/tlbflush.h>
 
 /* Defined in hibernate_asm_64.S */
 extern asmlinkage __visible int restore_image(void);
@@ -28,6 +29,7 @@ extern asmlinkage __visible int restore_
  * kernel's text (this value is passed in the image header).
  */
 unsigned long restore_jump_address __visible;
+unsigned long jump_address_phys;
 
 /*
  * Value of the cr3 register from before the hibernation (this value is passed
@@ -37,7 +39,43 @@ unsigned long restore_cr3 __visible;
 
 pgd_t *temp_level4_pgt __visible;
 
-void *relocated_restore_code __visible;
+unsigned long relocated_restore_code __visible;
+
+static int set_up_temporary_text_mapping(void)
+{
+	pmd_t *pmd;
+	pud_t *pud;
+
+	/*
+	 * The new mapping only has to cover the page containing the image
+	 * kernel's entry point (jump_address_phys), because the switch over to
+	 * it is carried out by relocated code running from a page allocated
+	 * specifically for this purpose and covered by the identity mapping, so
+	 * the temporary kernel text mapping is only needed for the final jump.
+	 * Moreover, in that mapping the virtual address of the image kernel's
+	 * entry point must be the same as its virtual address in the image
+	 * kernel (restore_jump_address), so the image kernel's
+	 * restore_registers() code doesn't find itself in a different area of
+	 * the virtual address space after switching over to the original page
+	 * tables used by the image kernel.
+	 */
+	pud = (pud_t *)get_safe_page(GFP_ATOMIC);
+	if (!pud)
+		return -ENOMEM;
+
+	pmd = (pmd_t *)get_safe_page(GFP_ATOMIC);
+	if (!pmd)
+		return -ENOMEM;
+
+	set_pmd(pmd + pmd_index(restore_jump_address),
+		__pmd((jump_address_phys & PMD_MASK) | __PAGE_KERNEL_LARGE_EXEC));
+	set_pud(pud + pud_index(restore_jump_address),
+		__pud(__pa(pmd) | _KERNPG_TABLE));
+	set_pgd(temp_level4_pgt + pgd_index(restore_jump_address),
+		__pgd(__pa(pud) | _KERNPG_TABLE));
+
+	return 0;
+}
 
 static void *alloc_pgt_page(void *context)
 {
@@ -59,9 +97,10 @@ static int set_up_temporary_mappings(voi
 	if (!temp_level4_pgt)
 		return -ENOMEM;
 
-	/* It is safe to reuse the original kernel mapping */
-	set_pgd(temp_level4_pgt + pgd_index(__START_KERNEL_map),
-		init_level4_pgt[pgd_index(__START_KERNEL_map)]);
+	/* Prepare a temporary mapping for the kernel text */
+	result = set_up_temporary_text_mapping();
+	if (result)
+		return result;
 
 	/* Set up the direct mapping from scratch */
 	for (i = 0; i < nr_pfn_mapped; i++) {
@@ -78,19 +117,50 @@ static int set_up_temporary_mappings(voi
 	return 0;
 }
 
+static int relocate_restore_code(void)
+{
+	pgd_t *pgd;
+	pud_t *pud;
+
+	relocated_restore_code = get_safe_page(GFP_ATOMIC);
+	if (!relocated_restore_code)
+		return -ENOMEM;
+
+	memcpy((void *)relocated_restore_code, &core_restore_code, PAGE_SIZE);
+
+	/* Make the page containing the relocated code executable */
+	pgd = (pgd_t *)__va(read_cr3()) + pgd_index(relocated_restore_code);
+	pud = pud_offset(pgd, relocated_restore_code);
+	if (pud_large(*pud)) {
+		set_pud(pud, __pud(pud_val(*pud) & ~_PAGE_NX));
+	} else {
+		pmd_t *pmd = pmd_offset(pud, relocated_restore_code);
+
+		if (pmd_large(*pmd)) {
+			set_pmd(pmd, __pmd(pmd_val(*pmd) & ~_PAGE_NX));
+		} else {
+			pte_t *pte = pte_offset_kernel(pmd, relocated_restore_code);
+
+			set_pte(pte, __pte(pte_val(*pte) & ~_PAGE_NX));
+		}
+	}
+	__flush_tlb_all();
+
+	return 0;
+}
+
 int swsusp_arch_resume(void)
 {
 	int error;
 
 	/* We have got enough memory and from now on we cannot recover */
-	if ((error = set_up_temporary_mappings()))
+	error = set_up_temporary_mappings();
+	if (error)
 		return error;
 
-	relocated_restore_code = (void *)get_safe_page(GFP_ATOMIC);
-	if (!relocated_restore_code)
-		return -ENOMEM;
-	memcpy(relocated_restore_code, &core_restore_code,
-	       &restore_registers - &core_restore_code);
+	error = relocate_restore_code();
+	if (error)
+		return error;
 
 	restore_image();
 	return 0;
@@ -109,11 +179,12 @@ int pfn_is_nosave(unsigned long pfn)
 
 struct restore_data_record {
 	unsigned long jump_address;
+	unsigned long jump_address_phys;
 	unsigned long cr3;
 	unsigned long magic;
 };
 
-#define RESTORE_MAGIC	0x0123456789ABCDEFUL
+#define RESTORE_MAGIC	0x123456789ABCDEF0UL
 
 /**
  *	arch_hibernation_header_save - populate the architecture specific part
@@ -126,7 +197,8 @@ int arch_hibernation_header_save(void *a
 
 	if (max_size < sizeof(struct restore_data_record))
 		return -EOVERFLOW;
-	rdr->jump_address = restore_jump_address;
+	rdr->jump_address = (unsigned long)&restore_registers;
+	rdr->jump_address_phys = __pa_symbol(&restore_registers);
 	rdr->cr3 = restore_cr3;
 	rdr->magic = RESTORE_MAGIC;
 	return 0;
@@ -142,6 +214,7 @@ int arch_hibernation_header_restore(void
 	struct restore_data_record *rdr = addr;
 
 	restore_jump_address = rdr->jump_address;
+	jump_address_phys = rdr->jump_address_phys;
 	restore_cr3 = rdr->cr3;
 	return (rdr->magic == RESTORE_MAGIC) ? 0 : -EINVAL;
 }
--- zfcpdump-kernel-4.4.orig/arch/x86/power/hibernate_asm_64.S
+++ zfcpdump-kernel-4.4/arch/x86/power/hibernate_asm_64.S
@@ -42,9 +42,6 @@ ENTRY(swsusp_arch_suspend)
 	pushfq
 	popq	pt_regs_flags(%rax)
 
-	/* save the address of restore_registers */
-	movq	$restore_registers, %rax
-	movq	%rax, restore_jump_address(%rip)
 	/* save cr3 */
 	movq	%cr3, %rax
 	movq	%rax, restore_cr3(%rip)
@@ -53,31 +50,34 @@ ENTRY(swsusp_arch_suspend)
 	ret
 
 ENTRY(restore_image)
-	/* switch to temporary page tables */
-	movq	$__PAGE_OFFSET, %rdx
-	movq	temp_level4_pgt(%rip), %rax
-	subq	%rdx, %rax
-	movq	%rax, %cr3
-	/* Flush TLB */
-	movq	mmu_cr4_features(%rip), %rax
-	movq	%rax, %rdx
-	andq	$~(X86_CR4_PGE), %rdx
-	movq	%rdx, %cr4;  # turn off PGE
-	movq	%cr3, %rcx;  # flush TLB
-	movq	%rcx, %cr3;
-	movq	%rax, %cr4;  # turn PGE back on
-
 	/* prepare to jump to the image kernel */
-	movq	restore_jump_address(%rip), %rax
-	movq	restore_cr3(%rip), %rbx
+	movq	restore_jump_address(%rip), %r8
+	movq	restore_cr3(%rip), %r9
+
+	/* prepare to switch to temporary page tables */
+	movq	temp_level4_pgt(%rip), %rax
+	movq	mmu_cr4_features(%rip), %rbx
 
 	/* prepare to copy image data to their original locations */
 	movq	restore_pblist(%rip), %rdx
+
+	/* jump to relocated restore code */
 	movq	relocated_restore_code(%rip), %rcx
 	jmpq	*%rcx
 
 	/* code below has been relocated to a safe page */
 ENTRY(core_restore_code)
+	/* switch to temporary page tables */
+	movq	$__PAGE_OFFSET, %rcx
+	subq	%rcx, %rax
+	movq	%rax, %cr3
+	/* flush TLB */
+	movq	%rbx, %rcx
+	andq	$~(X86_CR4_PGE), %rcx
+	movq	%rcx, %cr4;  # turn off PGE
+	movq	%cr3, %rcx;  # flush TLB
+	movq	%rcx, %cr3;
+	movq	%rbx, %cr4;  # turn PGE back on
 .Lloop:
 	testq	%rdx, %rdx
 	jz	.Ldone
@@ -92,23 +92,16 @@ ENTRY(core_restore_code)
 	/* progress to the next pbe */
 	movq	pbe_next(%rdx), %rdx
 	jmp	.Lloop
+
 .Ldone:
 	/* jump to the restore_registers address from the image header */
-	jmpq	*%rax
-	/*
-	 * NOTE: This assumes that the boot kernel's text mapping covers the
-	 * image kernel's page containing restore_registers and the address of
-	 * this page is the same as in the image kernel's text mapping (it
-	 * should always be true, because the text mapping is linear, starting
-	 * from 0, and is supposed to cover the entire kernel text for every
-	 * kernel).
-	 *
-	 * code below belongs to the image kernel
-	 */
+	jmpq	*%r8
 
+	 /* code below belongs to the image kernel */
+	.align PAGE_SIZE
 ENTRY(restore_registers)
 	/* go back to the original page tables */
-	movq    %rbx, %cr3
+	movq    %r9, %cr3
 
 	/* Flush TLB, including "global" things (vmalloc) */
 	movq	mmu_cr4_features(%rip), %rax
--- zfcpdump-kernel-4.4.orig/arch/x86/ras/mce_amd_inj.c
+++ zfcpdump-kernel-4.4/arch/x86/ras/mce_amd_inj.c
@@ -20,6 +20,7 @@
 #include <linux/pci.h>
 
 #include <asm/mce.h>
+#include <asm/smp.h>
 #include <asm/amd_nb.h>
 #include <asm/irq_vectors.h>
 
@@ -206,7 +207,7 @@ static u32 get_nbc_for_node(int node_id)
 	struct cpuinfo_x86 *c = &boot_cpu_data;
 	u32 cores_per_node;
 
-	cores_per_node = c->x86_max_cores / amd_get_nodes_per_socket();
+	cores_per_node = (c->x86_max_cores * smp_num_siblings) / amd_get_nodes_per_socket();
 
 	return cores_per_node * node_id;
 }
--- zfcpdump-kernel-4.4.orig/arch/x86/tools/gen-insn-attr-x86.awk
+++ zfcpdump-kernel-4.4/arch/x86/tools/gen-insn-attr-x86.awk
@@ -72,12 +72,14 @@ BEGIN {
 	lprefix_expr = "\\((66|F2|F3)\\)"
 	max_lprefix = 4
 
-	# All opcodes starting with lower-case 'v' or with (v1) superscript
+	# All opcodes starting with lower-case 'v', 'k' or with (v1) superscript
 	# accepts VEX prefix
-	vexok_opcode_expr = "^v.*"
+	vexok_opcode_expr = "^[vk].*"
 	vexok_expr = "\\(v1\\)"
 	# All opcodes with (v) superscript supports *only* VEX prefix
 	vexonly_expr = "\\(v\\)"
+	# All opcodes with (ev) superscript supports *only* EVEX prefix
+	evexonly_expr = "\\(ev\\)"
 
 	prefix_expr = "\\(Prefix\\)"
 	prefix_num["Operand-Size"] = "INAT_PFX_OPNDSZ"
@@ -95,6 +97,7 @@ BEGIN {
 	prefix_num["Address-Size"] = "INAT_PFX_ADDRSZ"
 	prefix_num["VEX+1byte"] = "INAT_PFX_VEX2"
 	prefix_num["VEX+2byte"] = "INAT_PFX_VEX3"
+	prefix_num["EVEX"] = "INAT_PFX_EVEX"
 
 	clear_vars()
 }
@@ -319,7 +322,9 @@ function convert_operands(count,opnd,
 			flags = add_flags(flags, "INAT_MODRM")
 
 		# check VEX codes
-		if (match(ext, vexonly_expr))
+		if (match(ext, evexonly_expr))
+			flags = add_flags(flags, "INAT_VEXOK | INAT_EVEXONLY")
+		else if (match(ext, vexonly_expr))
 			flags = add_flags(flags, "INAT_VEXOK | INAT_VEXONLY")
 		else if (match(ext, vexok_expr) || match(opcode, vexok_opcode_expr))
 			flags = add_flags(flags, "INAT_VEXOK")
--- zfcpdump-kernel-4.4.orig/arch/x86/um/asm/barrier.h
+++ zfcpdump-kernel-4.4/arch/x86/um/asm/barrier.h
@@ -3,7 +3,7 @@
 
 #include <asm/asm.h>
 #include <asm/segment.h>
-#include <asm/cpufeature.h>
+#include <asm/cpufeatures.h>
 #include <asm/cmpxchg.h>
 #include <asm/nops.h>
 
--- zfcpdump-kernel-4.4.orig/arch/x86/xen/apic.c
+++ zfcpdump-kernel-4.4/arch/x86/xen/apic.c
@@ -66,7 +66,7 @@ static u32 xen_apic_read(u32 reg)
 
 	ret = HYPERVISOR_dom0_op(&op);
 	if (ret)
-		return 0;
+		op.u.pcpu_info.apic_id = BAD_APICID;
 
 	return op.u.pcpu_info.apic_id << 24;
 }
@@ -142,6 +142,14 @@ static void xen_silent_inquire(int apici
 {
 }
 
+static int xen_cpu_present_to_apicid(int cpu)
+{
+	if (cpu_present(cpu))
+		return xen_get_apic_id(xen_apic_read(APIC_ID));
+	else
+		return BAD_APICID;
+}
+
 static struct apic xen_pv_apic = {
 	.name 				= "Xen PV",
 	.probe 				= xen_apic_probe_pv,
@@ -162,7 +170,7 @@ static struct apic xen_pv_apic = {
 
 	.ioapic_phys_id_map		= default_ioapic_phys_id_map, /* Used on 32-bit */
 	.setup_apic_routing		= NULL,
-	.cpu_present_to_apicid		= default_cpu_present_to_apicid,
+	.cpu_present_to_apicid		= xen_cpu_present_to_apicid,
 	.apicid_to_cpu_present		= physid_set_mask_of_physid, /* Used on 32-bit */
 	.check_phys_apicid_present	= default_check_phys_apicid_present, /* smp_sanity_check needs it */
 	.phys_pkg_id			= xen_phys_pkg_id, /* detect_ht */
--- zfcpdump-kernel-4.4.orig/arch/x86/xen/enlighten.c
+++ zfcpdump-kernel-4.4/arch/x86/xen/enlighten.c
@@ -74,7 +74,6 @@
 #include <asm/mach_traps.h>
 #include <asm/mwait.h>
 #include <asm/pci_x86.h>
-#include <asm/pat.h>
 #include <asm/cpu.h>
 
 #ifdef CONFIG_ACPI
@@ -961,7 +960,7 @@ static void xen_load_sp0(struct tss_stru
 	tss->x86_tss.sp0 = thread->sp0;
 }
 
-static void xen_set_iopl_mask(unsigned mask)
+void xen_set_iopl_mask(unsigned mask)
 {
 	struct physdev_set_iopl set_iopl;
 
@@ -1519,7 +1518,6 @@ asmlinkage __visible void __init xen_sta
 {
 	struct physdev_set_iopl set_iopl;
 	unsigned long initrd_start = 0;
-	u64 pat;
 	int rc;
 
 	if (!xen_start_info)
@@ -1627,13 +1625,6 @@ asmlinkage __visible void __init xen_sta
 				   xen_start_info->nr_pages);
 	xen_reserve_special_pages();
 
-	/*
-	 * Modify the cache mode translation tables to match Xen's PAT
-	 * configuration.
-	 */
-	rdmsrl(MSR_IA32_CR_PAT, pat);
-	pat_init_cache_modes(pat);
-
 	/* keep using Xen gdt for now; no urgent need to change it */
 
 #ifdef CONFIG_X86_32
--- zfcpdump-kernel-4.4.orig/arch/x86/xen/pmu.c
+++ zfcpdump-kernel-4.4/arch/x86/xen/pmu.c
@@ -11,7 +11,7 @@
 #include "pmu.h"
 
 /* x86_pmu.handle_irq definition */
-#include "../kernel/cpu/perf_event.h"
+#include "../events/perf_event.h"
 
 #define XENPMU_IRQ_PROCESSING    1
 struct xenpmu {
--- zfcpdump-kernel-4.4.orig/arch/x86/xen/setup.c
+++ zfcpdump-kernel-4.4/arch/x86/xen/setup.c
@@ -393,6 +393,9 @@ static unsigned long __init xen_set_iden
 	unsigned long i = 0;
 	unsigned long n = end_pfn - start_pfn;
 
+	if (remap_pfn == 0)
+		remap_pfn = nr_pages;
+
 	while (i < n) {
 		unsigned long cur_pfn = start_pfn + i;
 		unsigned long left = n - i;
@@ -438,17 +441,29 @@ static unsigned long __init xen_set_iden
 	return remap_pfn;
 }
 
-static void __init xen_set_identity_and_remap(unsigned long nr_pages)
+static unsigned long __init xen_count_remap_pages(
+	unsigned long start_pfn, unsigned long end_pfn, unsigned long nr_pages,
+	unsigned long remap_pages)
+{
+	if (start_pfn >= nr_pages)
+		return remap_pages;
+
+	return remap_pages + min(end_pfn, nr_pages) - start_pfn;
+}
+
+static unsigned long __init xen_foreach_remap_area(unsigned long nr_pages,
+	unsigned long (*func)(unsigned long start_pfn, unsigned long end_pfn,
+			      unsigned long nr_pages, unsigned long last_val))
 {
 	phys_addr_t start = 0;
-	unsigned long last_pfn = nr_pages;
+	unsigned long ret_val = 0;
 	const struct e820entry *entry = xen_e820_map;
 	int i;
 
 	/*
 	 * Combine non-RAM regions and gaps until a RAM region (or the
-	 * end of the map) is reached, then set the 1:1 map and
-	 * remap the memory in those non-RAM regions.
+	 * end of the map) is reached, then call the provided function
+	 * to perform its duty on the non-RAM region.
 	 *
 	 * The combined non-RAM regions are rounded to a whole number
 	 * of pages so any partial pages are accessible via the 1:1
@@ -466,14 +481,13 @@ static void __init xen_set_identity_and_
 				end_pfn = PFN_UP(entry->addr);
 
 			if (start_pfn < end_pfn)
-				last_pfn = xen_set_identity_and_remap_chunk(
-						start_pfn, end_pfn, nr_pages,
-						last_pfn);
+				ret_val = func(start_pfn, end_pfn, nr_pages,
+					       ret_val);
 			start = end;
 		}
 	}
 
-	pr_info("Released %ld page(s)\n", xen_released_pages);
+	return ret_val;
 }
 
 /*
@@ -596,35 +610,6 @@ static void __init xen_ignore_unusable(v
 	}
 }
 
-static unsigned long __init xen_count_remap_pages(unsigned long max_pfn)
-{
-	unsigned long extra = 0;
-	unsigned long start_pfn, end_pfn;
-	const struct e820entry *entry = xen_e820_map;
-	int i;
-
-	end_pfn = 0;
-	for (i = 0; i < xen_e820_map_entries; i++, entry++) {
-		start_pfn = PFN_DOWN(entry->addr);
-		/* Adjacent regions on non-page boundaries handling! */
-		end_pfn = min(end_pfn, start_pfn);
-
-		if (start_pfn >= max_pfn)
-			return extra + max_pfn - end_pfn;
-
-		/* Add any holes in map to result. */
-		extra += start_pfn - end_pfn;
-
-		end_pfn = PFN_UP(entry->addr + entry->size);
-		end_pfn = min(end_pfn, max_pfn);
-
-		if (entry->type != E820_RAM)
-			extra += end_pfn - start_pfn;
-	}
-
-	return extra;
-}
-
 bool __init xen_is_e820_reserved(phys_addr_t start, phys_addr_t size)
 {
 	struct e820entry *entry;
@@ -804,7 +789,7 @@ char * __init xen_memory_setup(void)
 	max_pages = xen_get_max_pages();
 
 	/* How many extra pages do we need due to remapping? */
-	max_pages += xen_count_remap_pages(max_pfn);
+	max_pages += xen_foreach_remap_area(max_pfn, xen_count_remap_pages);
 
 	if (max_pages > max_pfn)
 		extra_pages += max_pages - max_pfn;
@@ -922,7 +907,9 @@ char * __init xen_memory_setup(void)
 	 * Set identity map on non-RAM pages and prepare remapping the
 	 * underlying RAM.
 	 */
-	xen_set_identity_and_remap(max_pfn);
+	xen_foreach_remap_area(max_pfn, xen_set_identity_and_remap_chunk);
+
+	pr_info("Released %ld page(s)\n", xen_released_pages);
 
 	return "Xen";
 }
--- zfcpdump-kernel-4.4.orig/arch/x86/xen/suspend.c
+++ zfcpdump-kernel-4.4/arch/x86/xen/suspend.c
@@ -34,7 +34,8 @@ static void xen_hvm_post_suspend(int sus
 {
 #ifdef CONFIG_XEN_PVHVM
 	int cpu;
-	xen_hvm_init_shared_info();
+	if (!suspend_cancelled)
+	    xen_hvm_init_shared_info();
 	xen_callback_vector();
 	xen_unplug_emulated_devices();
 	if (xen_feature(XENFEAT_hvm_safe_pvclock)) {
--- zfcpdump-kernel-4.4.orig/arch/xtensa/kernel/head.S
+++ zfcpdump-kernel-4.4/arch/xtensa/kernel/head.S
@@ -128,7 +128,7 @@ ENTRY(_startup)
 	wsr	a0, icountlevel
 
 	.set	_index, 0
-	.rept	XCHAL_NUM_DBREAK - 1
+	.rept	XCHAL_NUM_DBREAK
 	wsr	a0, SREG_DBREAKC + _index
 	.set	_index, _index + 1
 	.endr
--- zfcpdump-kernel-4.4.orig/arch/xtensa/mm/cache.c
+++ zfcpdump-kernel-4.4/arch/xtensa/mm/cache.c
@@ -97,11 +97,11 @@ void clear_user_highpage(struct page *pa
 	unsigned long paddr;
 	void *kvaddr = coherent_kvaddr(page, TLBTEMP_BASE_1, vaddr, &paddr);
 
-	pagefault_disable();
+	preempt_disable();
 	kmap_invalidate_coherent(page, vaddr);
 	set_bit(PG_arch_1, &page->flags);
 	clear_page_alias(kvaddr, paddr);
-	pagefault_enable();
+	preempt_enable();
 }
 
 void copy_user_highpage(struct page *dst, struct page *src,
@@ -113,11 +113,11 @@ void copy_user_highpage(struct page *dst
 	void *src_vaddr = coherent_kvaddr(src, TLBTEMP_BASE_2, vaddr,
 					  &src_paddr);
 
-	pagefault_disable();
+	preempt_disable();
 	kmap_invalidate_coherent(dst, vaddr);
 	set_bit(PG_arch_1, &dst->flags);
 	copy_page_alias(dst_vaddr, src_vaddr, dst_paddr, src_paddr);
-	pagefault_enable();
+	preempt_enable();
 }
 
 #endif /* DCACHE_WAY_SIZE > PAGE_SIZE */
--- zfcpdump-kernel-4.4.orig/arch/xtensa/platforms/iss/console.c
+++ zfcpdump-kernel-4.4/arch/xtensa/platforms/iss/console.c
@@ -100,21 +100,23 @@ static void rs_poll(unsigned long priv)
 {
 	struct tty_port *port = (struct tty_port *)priv;
 	int i = 0;
+	int rd = 1;
 	unsigned char c;
 
 	spin_lock(&timer_lock);
 
 	while (simc_poll(0)) {
-		simc_read(0, &c, 1);
+		rd = simc_read(0, &c, 1);
+		if (rd <= 0)
+			break;
 		tty_insert_flip_char(port, c, TTY_NORMAL);
 		i++;
 	}
 
 	if (i)
 		tty_flip_buffer_push(port);
-
-
-	mod_timer(&serial_timer, jiffies + SERIAL_TIMER_VALUE);
+	if (rd)
+		mod_timer(&serial_timer, jiffies + SERIAL_TIMER_VALUE);
 	spin_unlock(&timer_lock);
 }
 
--- zfcpdump-kernel-4.4.orig/block/bio-integrity.c
+++ zfcpdump-kernel-4.4/block/bio-integrity.c
@@ -66,7 +66,7 @@ struct bio_integrity_payload *bio_integr
 	}
 
 	if (unlikely(!bip))
-		return NULL;
+		return ERR_PTR(-ENOMEM);
 
 	memset(bip, 0, sizeof(*bip));
 
@@ -89,7 +89,7 @@ struct bio_integrity_payload *bio_integr
 	return bip;
 err:
 	mempool_free(bip, bs->bio_integrity_pool);
-	return NULL;
+	return ERR_PTR(-ENOMEM);
 }
 EXPORT_SYMBOL(bio_integrity_alloc);
 
--- zfcpdump-kernel-4.4.orig/block/bio.c
+++ zfcpdump-kernel-4.4/block/bio.c
@@ -584,6 +584,8 @@ void __bio_clone_fast(struct bio *bio, s
 	bio->bi_rw = bio_src->bi_rw;
 	bio->bi_iter = bio_src->bi_iter;
 	bio->bi_io_vec = bio_src->bi_io_vec;
+
+	bio_clone_blkcg_association(bio, bio_src);
 }
 EXPORT_SYMBOL(__bio_clone_fast);
 
@@ -689,6 +691,8 @@ integrity_clone:
 		}
 	}
 
+	bio_clone_blkcg_association(bio, bio_src);
+
 	return bio;
 }
 EXPORT_SYMBOL(bio_clone_bioset);
@@ -1090,9 +1094,12 @@ int bio_uncopy_user(struct bio *bio)
 	if (!bio_flagged(bio, BIO_NULL_MAPPED)) {
 		/*
 		 * if we're in a workqueue, the request is orphaned, so
-		 * don't copy into a random user address space, just free.
+		 * don't copy into a random user address space, just free
+		 * and return -EINTR so user space doesn't expect any data.
 		 */
-		if (current->mm && bio_data_dir(bio) == READ)
+		if (!current->mm)
+			ret = -EINTR;
+		else if (bio_data_dir(bio) == READ)
 			ret = bio_copy_to_iter(bio, bmd->iter);
 		if (bmd->is_our_pages)
 			bio_free_pages(bio);
@@ -2011,6 +2018,17 @@ void bio_disassociate_task(struct bio *b
 	}
 }
 
+/**
+ * bio_clone_blkcg_association - clone blkcg association from src to dst bio
+ * @dst: destination bio
+ * @src: source bio
+ */
+void bio_clone_blkcg_association(struct bio *dst, struct bio *src)
+{
+	if (src->bi_css)
+		WARN_ON(bio_associate_blkcg(dst, src->bi_css));
+}
+
 #endif /* CONFIG_BLK_CGROUP */
 
 static void __init biovec_init_slabs(void)
--- zfcpdump-kernel-4.4.orig/block/blk-core.c
+++ zfcpdump-kernel-4.4/block/blk-core.c
@@ -515,7 +515,9 @@ EXPORT_SYMBOL_GPL(blk_queue_bypass_end);
 
 void blk_set_queue_dying(struct request_queue *q)
 {
-	queue_flag_set_unlocked(QUEUE_FLAG_DYING, q);
+	spin_lock_irq(q->queue_lock);
+	queue_flag_set(QUEUE_FLAG_DYING, q);
+	spin_unlock_irq(q->queue_lock);
 
 	if (q->mq_ops)
 		blk_mq_wake_waiters(q);
@@ -646,7 +648,7 @@ struct request_queue *blk_alloc_queue(gf
 }
 EXPORT_SYMBOL(blk_alloc_queue);
 
-int blk_queue_enter(struct request_queue *q, gfp_t gfp)
+int blk_queue_enter(struct request_queue *q, bool nowait)
 {
 	while (true) {
 		int ret;
@@ -654,7 +656,7 @@ int blk_queue_enter(struct request_queue
 		if (percpu_ref_tryget_live(&q->q_usage_counter))
 			return 0;
 
-		if (!gfpflags_allow_blocking(gfp))
+		if (nowait)
 			return -EBUSY;
 
 		ret = wait_event_interruptible(q->mq_freeze_wq,
@@ -680,6 +682,13 @@ static void blk_queue_usage_counter_rele
 	wake_up_all(&q->mq_freeze_wq);
 }
 
+static void blk_rq_timed_out_timer(unsigned long data)
+{
+	struct request_queue *q = (struct request_queue *)data;
+
+	kblockd_schedule_work(&q->timeout_work);
+}
+
 struct request_queue *blk_alloc_queue_node(gfp_t gfp_mask, int node_id)
 {
 	struct request_queue *q;
@@ -841,6 +850,7 @@ blk_init_allocated_queue(struct request_
 	if (blk_init_rl(&q->root_rl, q, GFP_KERNEL))
 		goto fail;
 
+	INIT_WORK(&q->timeout_work, blk_timeout_work);
 	q->request_fn		= rfn;
 	q->prep_rq_fn		= NULL;
 	q->unprep_rq_fn		= NULL;
@@ -1292,7 +1302,9 @@ static struct request *blk_old_get_reque
 struct request *blk_get_request(struct request_queue *q, int rw, gfp_t gfp_mask)
 {
 	if (q->mq_ops)
-		return blk_mq_alloc_request(q, rw, gfp_mask, false);
+		return blk_mq_alloc_request(q, rw,
+			(gfp_mask & __GFP_DIRECT_RECLAIM) ?
+				0 : BLK_MQ_REQ_NOWAIT);
 	else
 		return blk_old_get_request(q, rw, gfp_mask);
 }
@@ -2060,8 +2072,7 @@ blk_qc_t generic_make_request(struct bio
 	do {
 		struct request_queue *q = bdev_get_queue(bio->bi_bdev);
 
-		if (likely(blk_queue_enter(q, __GFP_DIRECT_RECLAIM) == 0)) {
-
+		if (likely(blk_queue_enter(q, false) == 0)) {
 			ret = q->make_request_fn(q, bio);
 
 			blk_queue_exit(q);
@@ -2189,7 +2200,7 @@ int blk_insert_cloned_request(struct req
 	if (q->mq_ops) {
 		if (blk_queue_io_stat(q))
 			blk_account_io_start(rq, true);
-		blk_mq_insert_request(rq, false, true, true);
+		blk_mq_insert_request(rq, false, true, false);
 		return 0;
 	}
 
--- zfcpdump-kernel-4.4.orig/block/blk-merge.c
+++ zfcpdump-kernel-4.4/block/blk-merge.c
@@ -68,6 +68,18 @@ static struct bio *blk_bio_write_same_sp
 	return bio_split(bio, q->limits.max_write_same_sectors, GFP_NOIO, bs);
 }
 
+static inline unsigned get_max_io_size(struct request_queue *q,
+				       struct bio *bio)
+{
+	unsigned sectors = blk_max_size_offset(q, bio->bi_iter.bi_sector);
+	unsigned mask = queue_logical_block_size(q) - 1;
+
+	/* aligned to logical block size */
+	sectors &= ~(mask >> 9);
+
+	return sectors;
+}
+
 static struct bio *blk_bio_segment_split(struct request_queue *q,
 					 struct bio *bio,
 					 struct bio_set *bs,
@@ -79,9 +91,29 @@ static struct bio *blk_bio_segment_split
 	unsigned front_seg_size = bio->bi_seg_front_size;
 	bool do_split = true;
 	struct bio *new = NULL;
+	const unsigned max_sectors = get_max_io_size(q, bio);
+	unsigned bvecs = 0;
 
 	bio_for_each_segment(bv, bio, iter) {
-		if (sectors + (bv.bv_len >> 9) > queue_max_sectors(q))
+		/*
+		 * With arbitrary bio size, the incoming bio may be very
+		 * big. We have to split the bio into small bios so that
+		 * each holds at most BIO_MAX_PAGES bvecs because
+		 * bio_clone() can fail to allocate big bvecs.
+		 *
+		 * It should have been better to apply the limit per
+		 * request queue in which bio_clone() is involved,
+		 * instead of globally. The biggest blocker is the
+		 * bio_clone() in bio bounce.
+		 *
+		 * If bio is splitted by this reason, we should have
+		 * allowed to continue bios merging, but don't do
+		 * that now for making the change simple.
+		 *
+		 * TODO: deal with bio bounce's bio_clone() gracefully
+		 * and convert the global limit into per-queue limit.
+		 */
+		if (bvecs++ >= BIO_MAX_PAGES)
 			goto split;
 
 		/*
@@ -91,6 +123,21 @@ static struct bio *blk_bio_segment_split
 		if (bvprvp && bvec_gap_to_prev(q, bvprvp, bv.bv_offset))
 			goto split;
 
+		if (sectors + (bv.bv_len >> 9) > max_sectors) {
+			/*
+			 * Consider this a new segment if we're splitting in
+			 * the middle of this vector.
+			 */
+			if (nsegs < queue_max_segments(q) &&
+			    sectors < max_sectors) {
+				nsegs++;
+				sectors = max_sectors;
+			}
+			if (sectors)
+				goto split;
+			/* Make this single bvec as the 1st segment */
+		}
+
 		if (bvprvp && blk_queue_cluster(q)) {
 			if (seg_size + bv.bv_len > queue_max_segment_size(q))
 				goto new_segment;
--- zfcpdump-kernel-4.4.orig/block/blk-mq-sysfs.c
+++ zfcpdump-kernel-4.4/block/blk-mq-sysfs.c
@@ -413,14 +413,17 @@ static void blk_mq_sysfs_init(struct req
 	struct blk_mq_hw_ctx *hctx;
 	struct blk_mq_ctx *ctx;
 	int i;
+	int cpu;
 
 	kobject_init(&q->mq_kobj, &blk_mq_ktype);
 
 	queue_for_each_hw_ctx(q, hctx, i)
 		kobject_init(&hctx->kobj, &blk_mq_hw_ktype);
 
-	queue_for_each_ctx(q, ctx, i)
+	for_each_possible_cpu(cpu) {
+		ctx = per_cpu_ptr(q->queue_ctx, cpu);
 		kobject_init(&ctx->kobj, &blk_mq_ctx_ktype);
+	}
 }
 
 int blk_mq_register_disk(struct gendisk *disk)
--- zfcpdump-kernel-4.4.orig/block/blk-mq-tag.c
+++ zfcpdump-kernel-4.4/block/blk-mq-tag.c
@@ -268,7 +268,7 @@ static int bt_get(struct blk_mq_alloc_da
 	if (tag != -1)
 		return tag;
 
-	if (!gfpflags_allow_blocking(data->gfp))
+	if (data->flags & BLK_MQ_REQ_NOWAIT)
 		return -1;
 
 	bs = bt_wait_ptr(bt, hctx);
@@ -303,7 +303,7 @@ static int bt_get(struct blk_mq_alloc_da
 		data->ctx = blk_mq_get_ctx(data->q);
 		data->hctx = data->q->mq_ops->map_queue(data->q,
 				data->ctx->cpu);
-		if (data->reserved) {
+		if (data->flags & BLK_MQ_REQ_RESERVED) {
 			bt = &data->hctx->tags->breserved_tags;
 		} else {
 			last_tag = &data->ctx->last_tag;
@@ -349,10 +349,9 @@ static unsigned int __blk_mq_get_reserve
 
 unsigned int blk_mq_get_tag(struct blk_mq_alloc_data *data)
 {
-	if (!data->reserved)
-		return __blk_mq_get_tag(data);
-
-	return __blk_mq_get_reserved_tag(data);
+	if (data->flags & BLK_MQ_REQ_RESERVED)
+		return __blk_mq_get_reserved_tag(data);
+	return __blk_mq_get_tag(data);
 }
 
 static struct bt_wait_state *bt_wake_ptr(struct blk_mq_bitmap_tags *bt)
--- zfcpdump-kernel-4.4.orig/block/blk-mq.c
+++ zfcpdump-kernel-4.4/block/blk-mq.c
@@ -229,8 +229,8 @@ __blk_mq_alloc_request(struct blk_mq_all
 	return NULL;
 }
 
-struct request *blk_mq_alloc_request(struct request_queue *q, int rw, gfp_t gfp,
-		bool reserved)
+struct request *blk_mq_alloc_request(struct request_queue *q, int rw,
+		unsigned int flags)
 {
 	struct blk_mq_ctx *ctx;
 	struct blk_mq_hw_ctx *hctx;
@@ -238,24 +238,22 @@ struct request *blk_mq_alloc_request(str
 	struct blk_mq_alloc_data alloc_data;
 	int ret;
 
-	ret = blk_queue_enter(q, gfp);
+	ret = blk_queue_enter(q, flags & BLK_MQ_REQ_NOWAIT);
 	if (ret)
 		return ERR_PTR(ret);
 
 	ctx = blk_mq_get_ctx(q);
 	hctx = q->mq_ops->map_queue(q, ctx->cpu);
-	blk_mq_set_alloc_data(&alloc_data, q, gfp & ~__GFP_DIRECT_RECLAIM,
-			reserved, ctx, hctx);
+	blk_mq_set_alloc_data(&alloc_data, q, flags, ctx, hctx);
 
 	rq = __blk_mq_alloc_request(&alloc_data, rw);
-	if (!rq && (gfp & __GFP_DIRECT_RECLAIM)) {
+	if (!rq && !(flags & BLK_MQ_REQ_NOWAIT)) {
 		__blk_mq_run_hw_queue(hctx);
 		blk_mq_put_ctx(ctx);
 
 		ctx = blk_mq_get_ctx(q);
 		hctx = q->mq_ops->map_queue(q, ctx->cpu);
-		blk_mq_set_alloc_data(&alloc_data, q, gfp, reserved, ctx,
-				hctx);
+		blk_mq_set_alloc_data(&alloc_data, q, flags, ctx, hctx);
 		rq =  __blk_mq_alloc_request(&alloc_data, rw);
 		ctx = alloc_data.ctx;
 	}
@@ -601,8 +599,10 @@ static void blk_mq_check_expired(struct
 		 * If a request wasn't started before the queue was
 		 * marked dying, kill it here or it'll go unnoticed.
 		 */
-		if (unlikely(blk_queue_dying(rq->q)))
-			blk_mq_complete_request(rq, -EIO);
+		if (unlikely(blk_queue_dying(rq->q))) {
+			rq->errors = -EIO;
+			blk_mq_end_request(rq, rq->errors);
+		}
 		return;
 	}
 	if (rq->cmd_flags & REQ_NO_TIMEOUT)
@@ -617,15 +617,32 @@ static void blk_mq_check_expired(struct
 	}
 }
 
-static void blk_mq_rq_timer(unsigned long priv)
+static void blk_mq_timeout_work(struct work_struct *work)
 {
-	struct request_queue *q = (struct request_queue *)priv;
+	struct request_queue *q =
+		container_of(work, struct request_queue, timeout_work);
 	struct blk_mq_timeout_data data = {
 		.next		= 0,
 		.next_set	= 0,
 	};
 	int i;
 
+	/* A deadlock might occur if a request is stuck requiring a
+	 * timeout at the same time a queue freeze is waiting
+	 * completion, since the timeout code would not be able to
+	 * acquire the queue reference here.
+	 *
+	 * That's why we don't use blk_queue_enter here; instead, we use
+	 * percpu_ref_tryget directly, because we need to be able to
+	 * obtain a reference even in the short window between the queue
+	 * starting to freeze, by dropping the first reference in
+	 * blk_mq_freeze_queue_start, and the moment the last request is
+	 * consumed, marked by the instant q_usage_counter reaches
+	 * zero.
+	 */
+	if (!percpu_ref_tryget(&q->q_usage_counter))
+		return;
+
 	blk_mq_queue_tag_busy_iter(q, blk_mq_check_expired, &data);
 
 	if (data.next_set) {
@@ -640,6 +657,7 @@ static void blk_mq_rq_timer(unsigned lon
 				blk_mq_tag_idle(hctx);
 		}
 	}
+	blk_queue_exit(q);
 }
 
 /*
@@ -730,11 +748,12 @@ static void __blk_mq_run_hw_queue(struct
 	struct list_head *dptr;
 	int queued;
 
-	WARN_ON(!cpumask_test_cpu(raw_smp_processor_id(), hctx->cpumask));
-
 	if (unlikely(test_bit(BLK_MQ_S_STOPPED, &hctx->state)))
 		return;
 
+	WARN_ON(!cpumask_test_cpu(raw_smp_processor_id(), hctx->cpumask) &&
+		cpu_online(hctx->next_cpu));
+
 	hctx->run++;
 
 	/*
@@ -778,7 +797,7 @@ static void __blk_mq_run_hw_queue(struct
 		switch (ret) {
 		case BLK_MQ_RQ_QUEUE_OK:
 			queued++;
-			continue;
+			break;
 		case BLK_MQ_RQ_QUEUE_BUSY:
 			list_add(&rq->queuelist, &rq_list);
 			__blk_mq_requeue_request(rq);
@@ -973,10 +992,11 @@ void blk_mq_delay_queue(struct blk_mq_hw
 EXPORT_SYMBOL(blk_mq_delay_queue);
 
 static inline void __blk_mq_insert_req_list(struct blk_mq_hw_ctx *hctx,
-					    struct blk_mq_ctx *ctx,
 					    struct request *rq,
 					    bool at_head)
 {
+	struct blk_mq_ctx *ctx = rq->mq_ctx;
+
 	trace_block_rq_insert(hctx->queue, rq);
 
 	if (at_head)
@@ -990,20 +1010,16 @@ static void __blk_mq_insert_request(stru
 {
 	struct blk_mq_ctx *ctx = rq->mq_ctx;
 
-	__blk_mq_insert_req_list(hctx, ctx, rq, at_head);
+	__blk_mq_insert_req_list(hctx, rq, at_head);
 	blk_mq_hctx_mark_pending(hctx, ctx);
 }
 
 void blk_mq_insert_request(struct request *rq, bool at_head, bool run_queue,
-		bool async)
+			   bool async)
 {
+	struct blk_mq_ctx *ctx = rq->mq_ctx;
 	struct request_queue *q = rq->q;
 	struct blk_mq_hw_ctx *hctx;
-	struct blk_mq_ctx *ctx = rq->mq_ctx, *current_ctx;
-
-	current_ctx = blk_mq_get_ctx(q);
-	if (!cpu_online(ctx->cpu))
-		rq->mq_ctx = ctx = current_ctx;
 
 	hctx = q->mq_ops->map_queue(q, ctx->cpu);
 
@@ -1013,8 +1029,6 @@ void blk_mq_insert_request(struct reques
 
 	if (run_queue)
 		blk_mq_run_hw_queue(hctx, async);
-
-	blk_mq_put_ctx(current_ctx);
 }
 
 static void blk_mq_insert_requests(struct request_queue *q,
@@ -1025,14 +1039,9 @@ static void blk_mq_insert_requests(struc
 
 {
 	struct blk_mq_hw_ctx *hctx;
-	struct blk_mq_ctx *current_ctx;
 
 	trace_block_unplug(q, depth, !from_schedule);
 
-	current_ctx = blk_mq_get_ctx(q);
-
-	if (!cpu_online(ctx->cpu))
-		ctx = current_ctx;
 	hctx = q->mq_ops->map_queue(q, ctx->cpu);
 
 	/*
@@ -1044,15 +1053,14 @@ static void blk_mq_insert_requests(struc
 		struct request *rq;
 
 		rq = list_first_entry(list, struct request, queuelist);
+		BUG_ON(rq->mq_ctx != ctx);
 		list_del_init(&rq->queuelist);
-		rq->mq_ctx = ctx;
-		__blk_mq_insert_req_list(hctx, ctx, rq, false);
+		__blk_mq_insert_req_list(hctx, rq, false);
 	}
 	blk_mq_hctx_mark_pending(hctx, ctx);
 	spin_unlock(&ctx->lock);
 
 	blk_mq_run_hw_queue(hctx, from_schedule);
-	blk_mq_put_ctx(current_ctx);
 }
 
 static int plug_ctx_cmp(void *priv, struct list_head *a, struct list_head *b)
@@ -1175,8 +1183,7 @@ static struct request *blk_mq_map_reques
 		rw |= REQ_SYNC;
 
 	trace_block_getrq(q, bio, rw);
-	blk_mq_set_alloc_data(&alloc_data, q, GFP_ATOMIC, false, ctx,
-			hctx);
+	blk_mq_set_alloc_data(&alloc_data, q, BLK_MQ_REQ_NOWAIT, ctx, hctx);
 	rq = __blk_mq_alloc_request(&alloc_data, rw);
 	if (unlikely(!rq)) {
 		__blk_mq_run_hw_queue(hctx);
@@ -1185,8 +1192,7 @@ static struct request *blk_mq_map_reques
 
 		ctx = blk_mq_get_ctx(q);
 		hctx = q->mq_ops->map_queue(q, ctx->cpu);
-		blk_mq_set_alloc_data(&alloc_data, q,
-				__GFP_RECLAIM|__GFP_HIGH, false, ctx, hctx);
+		blk_mq_set_alloc_data(&alloc_data, q, 0, ctx, hctx);
 		rq = __blk_mq_alloc_request(&alloc_data, rw);
 		ctx = alloc_data.ctx;
 		hctx = alloc_data.hctx;
@@ -1570,16 +1576,17 @@ static int blk_mq_alloc_bitmap(struct bl
 	return 0;
 }
 
+/*
+ * 'cpu' is going away. splice any existing rq_list entries from this
+ * software queue to the hw queue dispatch list, and ensure that it
+ * gets run.
+ */
 static int blk_mq_hctx_cpu_offline(struct blk_mq_hw_ctx *hctx, int cpu)
 {
-	struct request_queue *q = hctx->queue;
 	struct blk_mq_ctx *ctx;
 	LIST_HEAD(tmp);
 
-	/*
-	 * Move ctx entries to new CPU, if this one is going away.
-	 */
-	ctx = __blk_mq_get_ctx(q, cpu);
+	ctx = __blk_mq_get_ctx(hctx->queue, cpu);
 
 	spin_lock(&ctx->lock);
 	if (!list_empty(&ctx->rq_list)) {
@@ -1591,24 +1598,11 @@ static int blk_mq_hctx_cpu_offline(struc
 	if (list_empty(&tmp))
 		return NOTIFY_OK;
 
-	ctx = blk_mq_get_ctx(q);
-	spin_lock(&ctx->lock);
-
-	while (!list_empty(&tmp)) {
-		struct request *rq;
-
-		rq = list_first_entry(&tmp, struct request, queuelist);
-		rq->mq_ctx = ctx;
-		list_move_tail(&rq->queuelist, &ctx->rq_list);
-	}
-
-	hctx = q->mq_ops->map_queue(q, ctx->cpu);
-	blk_mq_hctx_mark_pending(hctx, ctx);
-
-	spin_unlock(&ctx->lock);
+	spin_lock(&hctx->lock);
+	list_splice_tail_init(&tmp, &hctx->dispatch);
+	spin_unlock(&hctx->lock);
 
 	blk_mq_run_hw_queue(hctx, true);
-	blk_mq_put_ctx(ctx);
 	return NOTIFY_OK;
 }
 
@@ -1819,11 +1813,12 @@ static void blk_mq_map_swqueue(struct re
 	/*
 	 * Map software to hardware queues
 	 */
-	queue_for_each_ctx(q, ctx, i) {
+	for_each_possible_cpu(i) {
 		/* If the cpu isn't online, the cpu is mapped to first hctx */
 		if (!cpumask_test_cpu(i, online_mask))
 			continue;
 
+		ctx = per_cpu_ptr(q->queue_ctx, i);
 		hctx = q->mq_ops->map_queue(q, i);
 		cpumask_set_cpu(i, hctx->cpumask);
 		ctx->index_hw = hctx->nr_ctx;
@@ -1854,6 +1849,7 @@ static void blk_mq_map_swqueue(struct re
 		hctx->tags = set->tags[i];
 		WARN_ON(!hctx->tags);
 
+		cpumask_copy(hctx->tags->cpumask, hctx->cpumask);
 		/*
 		 * Set the map size to the number of mapped software queues.
 		 * This is more accurate and more efficient than looping
@@ -1867,14 +1863,6 @@ static void blk_mq_map_swqueue(struct re
 		hctx->next_cpu = cpumask_first(hctx->cpumask);
 		hctx->next_cpu_batch = BLK_MQ_CPU_WORK_BATCH;
 	}
-
-	queue_for_each_ctx(q, ctx, i) {
-		if (!cpumask_test_cpu(i, online_mask))
-			continue;
-
-		hctx = q->mq_ops->map_queue(q, i);
-		cpumask_set_cpu(i, hctx->tags->cpumask);
-	}
 }
 
 static void queue_set_hctx_shared(struct request_queue *q, bool shared)
@@ -2019,7 +2007,7 @@ struct request_queue *blk_mq_init_alloca
 		hctxs[i]->queue_num = i;
 	}
 
-	setup_timer(&q->timeout, blk_mq_rq_timer, (unsigned long) q);
+	INIT_WORK(&q->timeout_work, blk_mq_timeout_work);
 	blk_queue_rq_timeout(q, set->timeout ? set->timeout : 30 * HZ);
 
 	q->nr_queues = nr_cpu_ids;
--- zfcpdump-kernel-4.4.orig/block/blk-mq.h
+++ zfcpdump-kernel-4.4/block/blk-mq.h
@@ -96,8 +96,7 @@ static inline void blk_mq_put_ctx(struct
 struct blk_mq_alloc_data {
 	/* input parameter */
 	struct request_queue *q;
-	gfp_t gfp;
-	bool reserved;
+	unsigned int flags;
 
 	/* input & output parameter */
 	struct blk_mq_ctx *ctx;
@@ -105,13 +104,11 @@ struct blk_mq_alloc_data {
 };
 
 static inline void blk_mq_set_alloc_data(struct blk_mq_alloc_data *data,
-		struct request_queue *q, gfp_t gfp, bool reserved,
-		struct blk_mq_ctx *ctx,
-		struct blk_mq_hw_ctx *hctx)
+		struct request_queue *q, unsigned int flags,
+		struct blk_mq_ctx *ctx, struct blk_mq_hw_ctx *hctx)
 {
 	data->q = q;
-	data->gfp = gfp;
-	data->reserved = reserved;
+	data->flags = flags;
 	data->ctx = ctx;
 	data->hctx = hctx;
 }
--- zfcpdump-kernel-4.4.orig/block/blk-settings.c
+++ zfcpdump-kernel-4.4/block/blk-settings.c
@@ -91,8 +91,8 @@ void blk_set_default_limits(struct queue
 	lim->seg_boundary_mask = BLK_SEG_BOUNDARY_MASK;
 	lim->virt_boundary_mask = 0;
 	lim->max_segment_size = BLK_MAX_SEGMENT_SIZE;
-	lim->max_sectors = lim->max_dev_sectors = lim->max_hw_sectors =
-		BLK_SAFE_MAX_SECTORS;
+	lim->max_sectors = lim->max_hw_sectors = BLK_SAFE_MAX_SECTORS;
+	lim->max_dev_sectors = 0;
 	lim->chunk_sectors = 0;
 	lim->max_write_same_sectors = 0;
 	lim->max_discard_sectors = 0;
--- zfcpdump-kernel-4.4.orig/block/blk-timeout.c
+++ zfcpdump-kernel-4.4/block/blk-timeout.c
@@ -127,13 +127,16 @@ static void blk_rq_check_expired(struct
 	}
 }
 
-void blk_rq_timed_out_timer(unsigned long data)
+void blk_timeout_work(struct work_struct *work)
 {
-	struct request_queue *q = (struct request_queue *) data;
+	struct request_queue *q =
+		container_of(work, struct request_queue, timeout_work);
 	unsigned long flags, next = 0;
 	struct request *rq, *tmp;
 	int next_set = 0;
 
+	if (blk_queue_enter(q, true))
+		return;
 	spin_lock_irqsave(q->queue_lock, flags);
 
 	list_for_each_entry_safe(rq, tmp, &q->timeout_list, timeout_list)
@@ -143,6 +146,7 @@ void blk_rq_timed_out_timer(unsigned lon
 		mod_timer(&q->timeout, round_jiffies_up(next));
 
 	spin_unlock_irqrestore(q->queue_lock, flags);
+	blk_queue_exit(q);
 }
 
 /**
--- zfcpdump-kernel-4.4.orig/block/blk.h
+++ zfcpdump-kernel-4.4/block/blk.h
@@ -93,7 +93,7 @@ static inline void blk_flush_integrity(v
 }
 #endif
 
-void blk_rq_timed_out_timer(unsigned long data);
+void blk_timeout_work(struct work_struct *work);
 unsigned long blk_rq_timeout(unsigned long timeout);
 void blk_add_timer(struct request *req);
 void blk_delete_timer(struct request *);
--- zfcpdump-kernel-4.4.orig/block/genhd.c
+++ zfcpdump-kernel-4.4/block/genhd.c
@@ -612,7 +612,7 @@ void add_disk(struct gendisk *disk)
 
 	/* Register BDI before referencing it from bdev */
 	bdi = &disk->queue->backing_dev_info;
-	bdi_register_dev(bdi, disk_devt(disk));
+	bdi_register_owner(bdi, disk_to_dev(disk));
 
 	blk_register_region(disk_devt(disk), disk->minors, NULL,
 			    exact_match, exact_lock, disk);
@@ -831,6 +831,7 @@ static void disk_seqf_stop(struct seq_fi
 	if (iter) {
 		class_dev_iter_exit(iter);
 		kfree(iter);
+		seqf->private = NULL;
 	}
 }
 
--- zfcpdump-kernel-4.4.orig/block/ioprio.c
+++ zfcpdump-kernel-4.4/block/ioprio.c
@@ -150,8 +150,10 @@ static int get_task_ioprio(struct task_s
 	if (ret)
 		goto out;
 	ret = IOPRIO_PRIO_VALUE(IOPRIO_CLASS_NONE, IOPRIO_NORM);
+	task_lock(p);
 	if (p->io_context)
 		ret = p->io_context->ioprio;
+	task_unlock(p);
 out:
 	return ret;
 }
--- zfcpdump-kernel-4.4.orig/block/partition-generic.c
+++ zfcpdump-kernel-4.4/block/partition-generic.c
@@ -349,15 +349,20 @@ struct hd_struct *add_partition(struct g
 			goto out_del;
 	}
 
+	err = hd_ref_init(p);
+	if (err) {
+		if (flags & ADDPART_FLAG_WHOLEDISK)
+			goto out_remove_file;
+		goto out_del;
+	}
+
 	/* everything is up and running, commence */
 	rcu_assign_pointer(ptbl->part[partno], p);
 
 	/* suppress uevent if the disk suppresses it */
 	if (!dev_get_uevent_suppress(ddev))
 		kobject_uevent(&pdev->kobj, KOBJ_ADD);
-
-	if (!hd_ref_init(p))
-		return p;
+	return p;
 
 out_free_info:
 	free_part_info(p);
@@ -366,6 +371,8 @@ out_free_stats:
 out_free:
 	kfree(p);
 	return ERR_PTR(err);
+out_remove_file:
+	device_remove_file(pdev, &dev_attr_whole_disk);
 out_del:
 	kobject_put(p->holder_dir);
 	device_del(pdev);
--- zfcpdump-kernel-4.4.orig/block/partitions/atari.c
+++ zfcpdump-kernel-4.4/block/partitions/atari.c
@@ -42,6 +42,13 @@ int atari_partition(struct parsed_partit
 	int part_fmt = 0; /* 0:unknown, 1:AHDI, 2:ICD/Supra */
 #endif
 
+	/*
+	 * ATARI partition scheme supports 512 lba only.  If this is not
+	 * the case, bail early to avoid miscalculating hd_size.
+	 */
+	if (bdev_logical_block_size(state->bdev) != 512)
+		return 0;
+
 	rs = read_part_sector(state, 0, &sect);
 	if (!rs)
 		return -1;
--- zfcpdump-kernel-4.4.orig/block/scsi_ioctl.c
+++ zfcpdump-kernel-4.4/block/scsi_ioctl.c
@@ -28,6 +28,9 @@
 #include <linux/slab.h>
 #include <linux/times.h>
 #include <linux/uio.h>
+#include <linux/fd.h>
+#include <linux/raid/md_u.h>
+#include <linux/mtio.h>
 #include <asm/uaccess.h>
 
 #include <scsi/scsi.h>
@@ -705,8 +708,17 @@ int scsi_verify_blk_ioctl(struct block_d
 	case SG_GET_RESERVED_SIZE:
 	case SG_SET_RESERVED_SIZE:
 	case SG_EMULATED_HOST:
+	case BLKFLSBUF:
+	case BLKROSET:
 		return 0;
 	case CDROM_GET_CAPABILITY:
+	case CDROM_DRIVE_STATUS:
+	case FDGETPRM:
+	case RAID_VERSION:
+	case MTIOCGET:
+#ifdef CONFIG_COMPAT
+	case 0x801c6d02:        /* MTIOCGET32 */
+#endif
 		/* Keep this until we remove the printk below.  udev sends it
 		 * and we do not want to spam dmesg about it.   CD-ROMs do
 		 * not have partitions, so we get here only for disks.
--- zfcpdump-kernel-4.4.orig/certs/Kconfig
+++ zfcpdump-kernel-4.4/certs/Kconfig
@@ -39,4 +39,20 @@ config SYSTEM_TRUSTED_KEYS
 	  form of DER-encoded *.x509 files in the top-level build directory,
 	  those are no longer used. You will need to set this option instead.
 
+config SYSTEM_EXTRA_CERTIFICATE
+	bool "Reserve area for inserting a certificate without recompiling"
+	depends on SYSTEM_TRUSTED_KEYRING
+	help
+	  If set, space for an extra certificate will be reserved in the kernel
+	  image. This allows introducing a trusted certificate to the default
+	  system keyring without recompiling the kernel.
+
+config SYSTEM_EXTRA_CERTIFICATE_SIZE
+	int "Number of bytes to reserve for the extra certificate"
+	depends on SYSTEM_EXTRA_CERTIFICATE
+	default 4096
+	help
+	  This is the number of bytes reserved in the kernel image for a
+	  certificate to be inserted.
+
 endmenu
--- zfcpdump-kernel-4.4.orig/certs/system_certificates.S
+++ zfcpdump-kernel-4.4/certs/system_certificates.S
@@ -13,6 +13,18 @@ __cert_list_start:
 	.incbin "certs/x509_certificate_list"
 __cert_list_end:
 
+#ifdef CONFIG_SYSTEM_EXTRA_CERTIFICATE
+	.globl VMLINUX_SYMBOL(system_extra_cert)
+	.size system_extra_cert, CONFIG_SYSTEM_EXTRA_CERTIFICATE_SIZE
+VMLINUX_SYMBOL(system_extra_cert):
+	.fill CONFIG_SYSTEM_EXTRA_CERTIFICATE_SIZE, 1, 0
+
+	.globl VMLINUX_SYMBOL(system_extra_cert_used)
+VMLINUX_SYMBOL(system_extra_cert_used):
+	.int 0
+
+#endif /* CONFIG_SYSTEM_EXTRA_CERTIFICATE */
+
 	.align 8
 	.globl VMLINUX_SYMBOL(system_certificate_list_size)
 VMLINUX_SYMBOL(system_certificate_list_size):
--- zfcpdump-kernel-4.4.orig/certs/system_keyring.c
+++ zfcpdump-kernel-4.4/certs/system_keyring.c
@@ -20,6 +20,9 @@
 
 struct key *system_trusted_keyring;
 EXPORT_SYMBOL_GPL(system_trusted_keyring);
+#ifdef CONFIG_SYSTEM_BLACKLIST_KEYRING
+struct key *system_blacklist_keyring;
+#endif
 
 extern __initconst const u8 system_certificate_list[];
 extern __initconst const unsigned long system_certificate_list_size;
@@ -41,6 +44,20 @@ static __init int system_trusted_keyring
 		panic("Can't allocate system trusted keyring\n");
 
 	set_bit(KEY_FLAG_TRUSTED_ONLY, &system_trusted_keyring->flags);
+
+	#ifdef CONFIG_SYSTEM_BLACKLIST_KEYRING
+	system_blacklist_keyring = keyring_alloc(".system_blacklist_keyring",
+				    KUIDT_INIT(0), KGIDT_INIT(0),
+				    current_cred(),
+				    (KEY_POS_ALL & ~KEY_POS_SETATTR) |
+				    KEY_USR_VIEW | KEY_USR_READ,
+				    KEY_ALLOC_NOT_IN_QUOTA, NULL);
+	if (IS_ERR(system_blacklist_keyring))
+		panic("Can't allocate system blacklist keyring\n");
+
+	set_bit(KEY_FLAG_TRUSTED_ONLY, &system_blacklist_keyring->flags);
+#endif
+
 	return 0;
 }
 
@@ -84,12 +101,13 @@ static __init int load_system_certificat
 					   ((KEY_POS_ALL & ~KEY_POS_SETATTR) |
 					   KEY_USR_VIEW | KEY_USR_READ),
 					   KEY_ALLOC_NOT_IN_QUOTA |
-					   KEY_ALLOC_TRUSTED);
+					   KEY_ALLOC_TRUSTED |
+					   KEY_ALLOC_BUILT_IN);
 		if (IS_ERR(key)) {
 			pr_err("Problem loading in-kernel X.509 certificate (%ld)\n",
 			       PTR_ERR(key));
+			WARN_ON_ONCE(1);
 		} else {
-			set_bit(KEY_FLAG_BUILTIN, &key_ref_to_ptr(key)->flags);
 			pr_notice("Loaded X.509 cert '%s'\n",
 				  key_ref_to_ptr(key)->description);
 			key_ref_put(key);
@@ -138,6 +156,16 @@ int system_verify_data(const void *data,
 	if (ret < 0)
 		goto error;
 
+#ifdef CONFIG_SYSTEM_BLACKLIST_KEYRING
+	ret = pkcs7_validate_trust(pkcs7, system_blacklist_keyring, &trusted);
+	if (!ret) {
+		/* module is signed with a cert in the blacklist.  reject */
+		pr_err("Module key is in the blacklist\n");
+		ret = -EKEYREJECTED;
+		goto error;
+	}
+#endif
+
 	ret = pkcs7_validate_trust(pkcs7, system_trusted_keyring, &trusted);
 	if (ret < 0)
 		goto error;
--- zfcpdump-kernel-4.4.orig/crypto/af_alg.c
+++ zfcpdump-kernel-4.4/crypto/af_alg.c
@@ -76,6 +76,8 @@ int af_alg_register_type(const struct af
 		goto unlock;
 
 	type->ops->owner = THIS_MODULE;
+	if (type->ops_nokey)
+		type->ops_nokey->owner = THIS_MODULE;
 	node->type = type;
 	list_add(&node->list, &alg_types);
 	err = 0;
@@ -125,6 +127,26 @@ int af_alg_release(struct socket *sock)
 }
 EXPORT_SYMBOL_GPL(af_alg_release);
 
+void af_alg_release_parent(struct sock *sk)
+{
+	struct alg_sock *ask = alg_sk(sk);
+	unsigned int nokey = ask->nokey_refcnt;
+	bool last = nokey && !ask->refcnt;
+
+	sk = ask->parent;
+	ask = alg_sk(sk);
+
+	lock_sock(sk);
+	ask->nokey_refcnt -= nokey;
+	if (!last)
+		last = !--ask->refcnt;
+	release_sock(sk);
+
+	if (last)
+		sock_put(sk);
+}
+EXPORT_SYMBOL_GPL(af_alg_release_parent);
+
 static int alg_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
 {
 	const u32 forbidden = CRYPTO_ALG_INTERNAL;
@@ -133,6 +155,7 @@ static int alg_bind(struct socket *sock,
 	struct sockaddr_alg *sa = (void *)uaddr;
 	const struct af_alg_type *type;
 	void *private;
+	int err;
 
 	if (sock->state == SS_CONNECTED)
 		return -EINVAL;
@@ -160,16 +183,22 @@ static int alg_bind(struct socket *sock,
 		return PTR_ERR(private);
 	}
 
+	err = -EBUSY;
 	lock_sock(sk);
+	if (ask->refcnt | ask->nokey_refcnt)
+		goto unlock;
 
 	swap(ask->type, type);
 	swap(ask->private, private);
 
+	err = 0;
+
+unlock:
 	release_sock(sk);
 
 	alg_do_release(type, private);
 
-	return 0;
+	return err;
 }
 
 static int alg_setkey(struct sock *sk, char __user *ukey,
@@ -202,11 +231,15 @@ static int alg_setsockopt(struct socket
 	struct sock *sk = sock->sk;
 	struct alg_sock *ask = alg_sk(sk);
 	const struct af_alg_type *type;
-	int err = -ENOPROTOOPT;
+	int err = -EBUSY;
 
 	lock_sock(sk);
+	if (ask->refcnt)
+		goto unlock;
+
 	type = ask->type;
 
+	err = -ENOPROTOOPT;
 	if (level != SOL_ALG || !type)
 		goto unlock;
 
@@ -238,6 +271,7 @@ int af_alg_accept(struct sock *sk, struc
 	struct alg_sock *ask = alg_sk(sk);
 	const struct af_alg_type *type;
 	struct sock *sk2;
+	unsigned int nokey;
 	int err;
 
 	lock_sock(sk);
@@ -257,20 +291,29 @@ int af_alg_accept(struct sock *sk, struc
 	security_sk_clone(sk, sk2);
 
 	err = type->accept(ask->private, sk2);
-	if (err) {
-		sk_free(sk2);
+
+	nokey = err == -ENOKEY;
+	if (nokey && type->accept_nokey)
+		err = type->accept_nokey(ask->private, sk2);
+
+	if (err)
 		goto unlock;
-	}
 
 	sk2->sk_family = PF_ALG;
 
-	sock_hold(sk);
+	if (nokey || !ask->refcnt++)
+		sock_hold(sk);
+	ask->nokey_refcnt += nokey;
 	alg_sk(sk2)->parent = sk;
 	alg_sk(sk2)->type = type;
+	alg_sk(sk2)->nokey_refcnt = nokey;
 
 	newsock->ops = type->ops;
 	newsock->state = SS_CONNECTED;
 
+	if (nokey)
+		newsock->ops = type->ops_nokey;
+
 	err = 0;
 
 unlock:
--- zfcpdump-kernel-4.4.orig/crypto/ahash.c
+++ zfcpdump-kernel-4.4/crypto/ahash.c
@@ -69,8 +69,9 @@ static int hash_walk_new_entry(struct cr
 	struct scatterlist *sg;
 
 	sg = walk->sg;
-	walk->pg = sg_page(sg);
 	walk->offset = sg->offset;
+	walk->pg = sg_page(walk->sg) + (walk->offset >> PAGE_SHIFT);
+	walk->offset = offset_in_page(walk->offset);
 	walk->entrylen = sg->length;
 
 	if (walk->entrylen > walk->total)
@@ -451,6 +452,7 @@ static int crypto_ahash_init_tfm(struct
 	struct ahash_alg *alg = crypto_ahash_alg(hash);
 
 	hash->setkey = ahash_nosetkey;
+	hash->has_setkey = false;
 	hash->export = ahash_no_export;
 	hash->import = ahash_no_import;
 
@@ -463,8 +465,10 @@ static int crypto_ahash_init_tfm(struct
 	hash->finup = alg->finup ?: ahash_def_finup;
 	hash->digest = alg->digest;
 
-	if (alg->setkey)
+	if (alg->setkey) {
 		hash->setkey = alg->setkey;
+		hash->has_setkey = true;
+	}
 	if (alg->export)
 		hash->export = alg->export;
 	if (alg->import)
--- zfcpdump-kernel-4.4.orig/crypto/algif_hash.c
+++ zfcpdump-kernel-4.4/crypto/algif_hash.c
@@ -34,6 +34,11 @@ struct hash_ctx {
 	struct ahash_request req;
 };
 
+struct algif_hash_tfm {
+	struct crypto_ahash *hash;
+	bool has_key;
+};
+
 static int hash_sendmsg(struct socket *sock, struct msghdr *msg,
 			size_t ignored)
 {
@@ -49,7 +54,8 @@ static int hash_sendmsg(struct socket *s
 
 	lock_sock(sk);
 	if (!ctx->more) {
-		err = crypto_ahash_init(&ctx->req);
+		err = af_alg_wait_for_completion(crypto_ahash_init(&ctx->req),
+						&ctx->completion);
 		if (err)
 			goto unlock;
 	}
@@ -120,6 +126,7 @@ static ssize_t hash_sendpage(struct sock
 	} else {
 		if (!ctx->more) {
 			err = crypto_ahash_init(&ctx->req);
+			err = af_alg_wait_for_completion(err, &ctx->completion);
 			if (err)
 				goto unlock;
 		}
@@ -235,19 +242,151 @@ static struct proto_ops algif_hash_ops =
 	.accept		=	hash_accept,
 };
 
+static int hash_check_key(struct socket *sock)
+{
+	int err = 0;
+	struct sock *psk;
+	struct alg_sock *pask;
+	struct algif_hash_tfm *tfm;
+	struct sock *sk = sock->sk;
+	struct alg_sock *ask = alg_sk(sk);
+
+	lock_sock(sk);
+	if (ask->refcnt)
+		goto unlock_child;
+
+	psk = ask->parent;
+	pask = alg_sk(ask->parent);
+	tfm = pask->private;
+
+	err = -ENOKEY;
+	lock_sock_nested(psk, SINGLE_DEPTH_NESTING);
+	if (!tfm->has_key)
+		goto unlock;
+
+	if (!pask->refcnt++)
+		sock_hold(psk);
+
+	ask->refcnt = 1;
+	sock_put(psk);
+
+	err = 0;
+
+unlock:
+	release_sock(psk);
+unlock_child:
+	release_sock(sk);
+
+	return err;
+}
+
+static int hash_sendmsg_nokey(struct socket *sock, struct msghdr *msg,
+			      size_t size)
+{
+	int err;
+
+	err = hash_check_key(sock);
+	if (err)
+		return err;
+
+	return hash_sendmsg(sock, msg, size);
+}
+
+static ssize_t hash_sendpage_nokey(struct socket *sock, struct page *page,
+				   int offset, size_t size, int flags)
+{
+	int err;
+
+	err = hash_check_key(sock);
+	if (err)
+		return err;
+
+	return hash_sendpage(sock, page, offset, size, flags);
+}
+
+static int hash_recvmsg_nokey(struct socket *sock, struct msghdr *msg,
+			      size_t ignored, int flags)
+{
+	int err;
+
+	err = hash_check_key(sock);
+	if (err)
+		return err;
+
+	return hash_recvmsg(sock, msg, ignored, flags);
+}
+
+static int hash_accept_nokey(struct socket *sock, struct socket *newsock,
+			     int flags)
+{
+	int err;
+
+	err = hash_check_key(sock);
+	if (err)
+		return err;
+
+	return hash_accept(sock, newsock, flags);
+}
+
+static struct proto_ops algif_hash_ops_nokey = {
+	.family		=	PF_ALG,
+
+	.connect	=	sock_no_connect,
+	.socketpair	=	sock_no_socketpair,
+	.getname	=	sock_no_getname,
+	.ioctl		=	sock_no_ioctl,
+	.listen		=	sock_no_listen,
+	.shutdown	=	sock_no_shutdown,
+	.getsockopt	=	sock_no_getsockopt,
+	.mmap		=	sock_no_mmap,
+	.bind		=	sock_no_bind,
+	.setsockopt	=	sock_no_setsockopt,
+	.poll		=	sock_no_poll,
+
+	.release	=	af_alg_release,
+	.sendmsg	=	hash_sendmsg_nokey,
+	.sendpage	=	hash_sendpage_nokey,
+	.recvmsg	=	hash_recvmsg_nokey,
+	.accept		=	hash_accept_nokey,
+};
+
 static void *hash_bind(const char *name, u32 type, u32 mask)
 {
-	return crypto_alloc_ahash(name, type, mask);
+	struct algif_hash_tfm *tfm;
+	struct crypto_ahash *hash;
+
+	tfm = kzalloc(sizeof(*tfm), GFP_KERNEL);
+	if (!tfm)
+		return ERR_PTR(-ENOMEM);
+
+	hash = crypto_alloc_ahash(name, type, mask);
+	if (IS_ERR(hash)) {
+		kfree(tfm);
+		return ERR_CAST(hash);
+	}
+
+	tfm->hash = hash;
+
+	return tfm;
 }
 
 static void hash_release(void *private)
 {
-	crypto_free_ahash(private);
+	struct algif_hash_tfm *tfm = private;
+
+	crypto_free_ahash(tfm->hash);
+	kfree(tfm);
 }
 
 static int hash_setkey(void *private, const u8 *key, unsigned int keylen)
 {
-	return crypto_ahash_setkey(private, key, keylen);
+	struct algif_hash_tfm *tfm = private;
+	int err;
+
+	err = crypto_ahash_setkey(tfm->hash, key, keylen);
+	tfm->has_key = !err;
+
+	return err;
 }
 
 static void hash_sock_destruct(struct sock *sk)
@@ -261,12 +400,14 @@ static void hash_sock_destruct(struct so
 	af_alg_release_parent(sk);
 }
 
-static int hash_accept_parent(void *private, struct sock *sk)
+static int hash_accept_parent_nokey(void *private, struct sock *sk)
 {
 	struct hash_ctx *ctx;
 	struct alg_sock *ask = alg_sk(sk);
-	unsigned len = sizeof(*ctx) + crypto_ahash_reqsize(private);
-	unsigned ds = crypto_ahash_digestsize(private);
+	struct algif_hash_tfm *tfm = private;
+	struct crypto_ahash *hash = tfm->hash;
+	unsigned len = sizeof(*ctx) + crypto_ahash_reqsize(hash);
+	unsigned ds = crypto_ahash_digestsize(hash);
 
 	ctx = sock_kmalloc(sk, len, GFP_KERNEL);
 	if (!ctx)
@@ -286,7 +427,7 @@ static int hash_accept_parent(void *priv
 
 	ask->private = ctx;
 
-	ahash_request_set_tfm(&ctx->req, private);
+	ahash_request_set_tfm(&ctx->req, hash);
 	ahash_request_set_callback(&ctx->req, CRYPTO_TFM_REQ_MAY_BACKLOG,
 				   af_alg_complete, &ctx->completion);
 
@@ -295,12 +436,24 @@ static int hash_accept_parent(void *priv
 	return 0;
 }
 
+static int hash_accept_parent(void *private, struct sock *sk)
+{
+	struct algif_hash_tfm *tfm = private;
+
+	if (!tfm->has_key && crypto_ahash_has_setkey(tfm->hash))
+		return -ENOKEY;
+
+	return hash_accept_parent_nokey(private, sk);
+}
+
 static const struct af_alg_type algif_type_hash = {
 	.bind		=	hash_bind,
 	.release	=	hash_release,
 	.setkey		=	hash_setkey,
 	.accept		=	hash_accept_parent,
+	.accept_nokey	=	hash_accept_parent_nokey,
 	.ops		=	&algif_hash_ops,
+	.ops_nokey	=	&algif_hash_ops_nokey,
 	.name		=	"hash",
 	.owner		=	THIS_MODULE
 };
--- zfcpdump-kernel-4.4.orig/crypto/algif_skcipher.c
+++ zfcpdump-kernel-4.4/crypto/algif_skcipher.c
@@ -31,6 +31,11 @@ struct skcipher_sg_list {
 	struct scatterlist sg[0];
 };
 
+struct skcipher_tfm {
+	struct crypto_skcipher *skcipher;
+	bool has_key;
+};
+
 struct skcipher_ctx {
 	struct list_head tsgl;
 	struct af_alg_sgl rsgl;
@@ -60,18 +65,10 @@ struct skcipher_async_req {
 	struct skcipher_async_rsgl first_sgl;
 	struct list_head list;
 	struct scatterlist *tsg;
-	char iv[];
+	atomic_t *inflight;
+	struct skcipher_request req;
 };
 
-#define GET_SREQ(areq, ctx) (struct skcipher_async_req *)((char *)areq + \
-	crypto_skcipher_reqsize(crypto_skcipher_reqtfm(&ctx->req)))
-
-#define GET_REQ_SIZE(ctx) \
-	crypto_skcipher_reqsize(crypto_skcipher_reqtfm(&ctx->req))
-
-#define GET_IV_SIZE(ctx) \
-	crypto_skcipher_ivsize(crypto_skcipher_reqtfm(&ctx->req))
-
 #define MAX_SGL_ENTS ((4096 - sizeof(struct skcipher_sg_list)) / \
 		      sizeof(struct scatterlist) - 1)
 
@@ -97,15 +94,12 @@ static void skcipher_free_async_sgls(str
 
 static void skcipher_async_cb(struct crypto_async_request *req, int err)
 {
-	struct sock *sk = req->data;
-	struct alg_sock *ask = alg_sk(sk);
-	struct skcipher_ctx *ctx = ask->private;
-	struct skcipher_async_req *sreq = GET_SREQ(req, ctx);
+	struct skcipher_async_req *sreq = req->data;
 	struct kiocb *iocb = sreq->iocb;
 
-	atomic_dec(&ctx->inflight);
+	atomic_dec(sreq->inflight);
 	skcipher_free_async_sgls(sreq);
-	kfree(req);
+	kzfree(sreq);
 	iocb->ki_complete(iocb, err, err);
 }
 
@@ -301,8 +295,11 @@ static int skcipher_sendmsg(struct socke
 {
 	struct sock *sk = sock->sk;
 	struct alg_sock *ask = alg_sk(sk);
+	struct sock *psk = ask->parent;
+	struct alg_sock *pask = alg_sk(psk);
 	struct skcipher_ctx *ctx = ask->private;
-	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(&ctx->req);
+	struct skcipher_tfm *skc = pask->private;
+	struct crypto_skcipher *tfm = skc->skcipher;
 	unsigned ivsize = crypto_skcipher_ivsize(tfm);
 	struct skcipher_sg_list *sgl;
 	struct af_alg_control con = {};
@@ -387,7 +384,8 @@ static int skcipher_sendmsg(struct socke
 
 		sgl = list_entry(ctx->tsgl.prev, struct skcipher_sg_list, list);
 		sg = sgl->sg;
-		sg_unmark_end(sg + sgl->cur);
+		if (sgl->cur)
+			sg_unmark_end(sg + sgl->cur - 1);
 		do {
 			i = sgl->cur;
 			plen = min_t(int, len, PAGE_SIZE);
@@ -503,37 +501,43 @@ static int skcipher_recvmsg_async(struct
 {
 	struct sock *sk = sock->sk;
 	struct alg_sock *ask = alg_sk(sk);
+	struct sock *psk = ask->parent;
+	struct alg_sock *pask = alg_sk(psk);
 	struct skcipher_ctx *ctx = ask->private;
+	struct skcipher_tfm *skc = pask->private;
+	struct crypto_skcipher *tfm = skc->skcipher;
 	struct skcipher_sg_list *sgl;
 	struct scatterlist *sg;
 	struct skcipher_async_req *sreq;
 	struct skcipher_request *req;
 	struct skcipher_async_rsgl *last_rsgl = NULL;
-	unsigned int txbufs = 0, len = 0, tx_nents = skcipher_all_sg_nents(ctx);
-	unsigned int reqlen = sizeof(struct skcipher_async_req) +
-				GET_REQ_SIZE(ctx) + GET_IV_SIZE(ctx);
+	unsigned int txbufs = 0, len = 0, tx_nents;
+	unsigned int reqsize = crypto_skcipher_reqsize(tfm);
+	unsigned int ivsize = crypto_skcipher_ivsize(tfm);
 	int err = -ENOMEM;
 	bool mark = false;
+	char *iv;
 
-	lock_sock(sk);
-	req = kmalloc(reqlen, GFP_KERNEL);
-	if (unlikely(!req))
-		goto unlock;
+	sreq = kzalloc(sizeof(*sreq) + reqsize + ivsize, GFP_KERNEL);
+	if (unlikely(!sreq))
+		goto out;
 
-	sreq = GET_SREQ(req, ctx);
+	req = &sreq->req;
+	iv = (char *)(req + 1) + reqsize;
 	sreq->iocb = msg->msg_iocb;
-	memset(&sreq->first_sgl, '\0', sizeof(struct skcipher_async_rsgl));
 	INIT_LIST_HEAD(&sreq->list);
+	sreq->inflight = &ctx->inflight;
+
+	lock_sock(sk);
+	tx_nents = skcipher_all_sg_nents(ctx);
 	sreq->tsg = kcalloc(tx_nents, sizeof(*sg), GFP_KERNEL);
-	if (unlikely(!sreq->tsg)) {
-		kfree(req);
+	if (unlikely(!sreq->tsg))
 		goto unlock;
-	}
 	sg_init_table(sreq->tsg, tx_nents);
-	memcpy(sreq->iv, ctx->iv, GET_IV_SIZE(ctx));
-	skcipher_request_set_tfm(req, crypto_skcipher_reqtfm(&ctx->req));
-	skcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
-				      skcipher_async_cb, sk);
+	memcpy(iv, ctx->iv, ivsize);
+	skcipher_request_set_tfm(req, tfm);
+	skcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_SLEEP,
+				      skcipher_async_cb, sreq);
 
 	while (iov_iter_count(&msg->msg_iter)) {
 		struct skcipher_async_rsgl *rsgl;
@@ -609,20 +613,22 @@ static int skcipher_recvmsg_async(struct
 		sg_mark_end(sreq->tsg + txbufs - 1);
 
 	skcipher_request_set_crypt(req, sreq->tsg, sreq->first_sgl.sgl.sg,
-				   len, sreq->iv);
+				   len, iv);
 	err = ctx->enc ? crypto_skcipher_encrypt(req) :
 			 crypto_skcipher_decrypt(req);
 	if (err == -EINPROGRESS) {
 		atomic_inc(&ctx->inflight);
 		err = -EIOCBQUEUED;
+		sreq = NULL;
 		goto unlock;
 	}
 free:
 	skcipher_free_async_sgls(sreq);
-	kfree(req);
 unlock:
 	skcipher_wmem_wakeup(sk);
 	release_sock(sk);
+	kzfree(sreq);
+out:
 	return err;
 }
 
@@ -631,9 +637,12 @@ static int skcipher_recvmsg_sync(struct
 {
 	struct sock *sk = sock->sk;
 	struct alg_sock *ask = alg_sk(sk);
+	struct sock *psk = ask->parent;
+	struct alg_sock *pask = alg_sk(psk);
 	struct skcipher_ctx *ctx = ask->private;
-	unsigned bs = crypto_skcipher_blocksize(crypto_skcipher_reqtfm(
-		&ctx->req));
+	struct skcipher_tfm *skc = pask->private;
+	struct crypto_skcipher *tfm = skc->skcipher;
+	unsigned bs = crypto_skcipher_blocksize(tfm);
 	struct skcipher_sg_list *sgl;
 	struct scatterlist *sg;
 	int err = -EAGAIN;
@@ -642,13 +651,6 @@ static int skcipher_recvmsg_sync(struct
 
 	lock_sock(sk);
 	while (msg_data_left(msg)) {
-		sgl = list_first_entry(&ctx->tsgl,
-				       struct skcipher_sg_list, list);
-		sg = sgl->sg;
-
-		while (!sg->length)
-			sg++;
-
 		if (!ctx->used) {
 			err = skcipher_wait_for_data(sk, flags);
 			if (err)
@@ -669,6 +671,13 @@ static int skcipher_recvmsg_sync(struct
 		if (!used)
 			goto free;
 
+		sgl = list_first_entry(&ctx->tsgl,
+				       struct skcipher_sg_list, list);
+		sg = sgl->sg;
+
+		while (!sg->length)
+			sg++;
+
 		skcipher_request_set_crypt(&ctx->req, sg, ctx->rsgl.sg, used,
 					   ctx->iv);
 
@@ -748,19 +757,139 @@ static struct proto_ops algif_skcipher_o
 	.poll		=	skcipher_poll,
 };
 
+static int skcipher_check_key(struct socket *sock)
+{
+	int err = 0;
+	struct sock *psk;
+	struct alg_sock *pask;
+	struct skcipher_tfm *tfm;
+	struct sock *sk = sock->sk;
+	struct alg_sock *ask = alg_sk(sk);
+
+	lock_sock(sk);
+	if (ask->refcnt)
+		goto unlock_child;
+
+	psk = ask->parent;
+	pask = alg_sk(ask->parent);
+	tfm = pask->private;
+
+	err = -ENOKEY;
+	lock_sock_nested(psk, SINGLE_DEPTH_NESTING);
+	if (!tfm->has_key)
+		goto unlock;
+
+	if (!pask->refcnt++)
+		sock_hold(psk);
+
+	ask->refcnt = 1;
+	sock_put(psk);
+
+	err = 0;
+
+unlock:
+	release_sock(psk);
+unlock_child:
+	release_sock(sk);
+
+	return err;
+}
+
+static int skcipher_sendmsg_nokey(struct socket *sock, struct msghdr *msg,
+				  size_t size)
+{
+	int err;
+
+	err = skcipher_check_key(sock);
+	if (err)
+		return err;
+
+	return skcipher_sendmsg(sock, msg, size);
+}
+
+static ssize_t skcipher_sendpage_nokey(struct socket *sock, struct page *page,
+				       int offset, size_t size, int flags)
+{
+	int err;
+
+	err = skcipher_check_key(sock);
+	if (err)
+		return err;
+
+	return skcipher_sendpage(sock, page, offset, size, flags);
+}
+
+static int skcipher_recvmsg_nokey(struct socket *sock, struct msghdr *msg,
+				  size_t ignored, int flags)
+{
+	int err;
+
+	err = skcipher_check_key(sock);
+	if (err)
+		return err;
+
+	return skcipher_recvmsg(sock, msg, ignored, flags);
+}
+
+static struct proto_ops algif_skcipher_ops_nokey = {
+	.family		=	PF_ALG,
+
+	.connect	=	sock_no_connect,
+	.socketpair	=	sock_no_socketpair,
+	.getname	=	sock_no_getname,
+	.ioctl		=	sock_no_ioctl,
+	.listen		=	sock_no_listen,
+	.shutdown	=	sock_no_shutdown,
+	.getsockopt	=	sock_no_getsockopt,
+	.mmap		=	sock_no_mmap,
+	.bind		=	sock_no_bind,
+	.accept		=	sock_no_accept,
+	.setsockopt	=	sock_no_setsockopt,
+
+	.release	=	af_alg_release,
+	.sendmsg	=	skcipher_sendmsg_nokey,
+	.sendpage	=	skcipher_sendpage_nokey,
+	.recvmsg	=	skcipher_recvmsg_nokey,
+	.poll		=	skcipher_poll,
+};
+
 static void *skcipher_bind(const char *name, u32 type, u32 mask)
 {
-	return crypto_alloc_skcipher(name, type, mask);
+	struct skcipher_tfm *tfm;
+	struct crypto_skcipher *skcipher;
+
+	tfm = kzalloc(sizeof(*tfm), GFP_KERNEL);
+	if (!tfm)
+		return ERR_PTR(-ENOMEM);
+
+	skcipher = crypto_alloc_skcipher(name, type, mask);
+	if (IS_ERR(skcipher)) {
+		kfree(tfm);
+		return ERR_CAST(skcipher);
+	}
+
+	tfm->skcipher = skcipher;
+
+	return tfm;
 }
 
 static void skcipher_release(void *private)
 {
-	crypto_free_skcipher(private);
+	struct skcipher_tfm *tfm = private;
+
+	crypto_free_skcipher(tfm->skcipher);
+	kfree(tfm);
 }
 
 static int skcipher_setkey(void *private, const u8 *key, unsigned int keylen)
 {
-	return crypto_skcipher_setkey(private, key, keylen);
+	struct skcipher_tfm *tfm = private;
+	int err;
+
+	err = crypto_skcipher_setkey(tfm->skcipher, key, keylen);
+	tfm->has_key = !err;
+
+	return err;
 }
 
 static void skcipher_wait(struct sock *sk)
@@ -788,24 +917,26 @@ static void skcipher_sock_destruct(struc
 	af_alg_release_parent(sk);
 }
 
-static int skcipher_accept_parent(void *private, struct sock *sk)
+static int skcipher_accept_parent_nokey(void *private, struct sock *sk)
 {
 	struct skcipher_ctx *ctx;
 	struct alg_sock *ask = alg_sk(sk);
-	unsigned int len = sizeof(*ctx) + crypto_skcipher_reqsize(private);
+	struct skcipher_tfm *tfm = private;
+	struct crypto_skcipher *skcipher = tfm->skcipher;
+	unsigned int len = sizeof(*ctx) + crypto_skcipher_reqsize(skcipher);
 
 	ctx = sock_kmalloc(sk, len, GFP_KERNEL);
 	if (!ctx)
 		return -ENOMEM;
 
-	ctx->iv = sock_kmalloc(sk, crypto_skcipher_ivsize(private),
+	ctx->iv = sock_kmalloc(sk, crypto_skcipher_ivsize(skcipher),
 			       GFP_KERNEL);
 	if (!ctx->iv) {
 		sock_kfree_s(sk, ctx, len);
 		return -ENOMEM;
 	}
 
-	memset(ctx->iv, 0, crypto_skcipher_ivsize(private));
+	memset(ctx->iv, 0, crypto_skcipher_ivsize(skcipher));
 
 	INIT_LIST_HEAD(&ctx->tsgl);
 	ctx->len = len;
@@ -818,8 +949,9 @@ static int skcipher_accept_parent(void *
 
 	ask->private = ctx;
 
-	skcipher_request_set_tfm(&ctx->req, private);
-	skcipher_request_set_callback(&ctx->req, CRYPTO_TFM_REQ_MAY_BACKLOG,
+	skcipher_request_set_tfm(&ctx->req, skcipher);
+	skcipher_request_set_callback(&ctx->req, CRYPTO_TFM_REQ_MAY_SLEEP |
+						 CRYPTO_TFM_REQ_MAY_BACKLOG,
 				      af_alg_complete, &ctx->completion);
 
 	sk->sk_destruct = skcipher_sock_destruct;
@@ -827,12 +959,24 @@ static int skcipher_accept_parent(void *
 	return 0;
 }
 
+static int skcipher_accept_parent(void *private, struct sock *sk)
+{
+	struct skcipher_tfm *tfm = private;
+
+	if (!tfm->has_key && crypto_skcipher_has_setkey(tfm->skcipher))
+		return -ENOKEY;
+
+	return skcipher_accept_parent_nokey(private, sk);
+}
+
 static const struct af_alg_type algif_type_skcipher = {
 	.bind		=	skcipher_bind,
 	.release	=	skcipher_release,
 	.setkey		=	skcipher_setkey,
 	.accept		=	skcipher_accept_parent,
+	.accept_nokey	=	skcipher_accept_parent_nokey,
 	.ops		=	&algif_skcipher_ops,
+	.ops_nokey	=	&algif_skcipher_ops_nokey,
 	.name		=	"skcipher",
 	.owner		=	THIS_MODULE
 };
--- zfcpdump-kernel-4.4.orig/crypto/asymmetric_keys/Kconfig
+++ zfcpdump-kernel-4.4/crypto/asymmetric_keys/Kconfig
@@ -14,6 +14,7 @@ config ASYMMETRIC_PUBLIC_KEY_SUBTYPE
 	select MPILIB
 	select PUBLIC_KEY_ALGO_RSA
 	select CRYPTO_HASH_INFO
+	select CRYPTO_AKCIPHER
 	help
 	  This option provides support for asymmetric public key type handling.
 	  If signature generation and/or verification are to be used,
@@ -22,7 +23,7 @@ config ASYMMETRIC_PUBLIC_KEY_SUBTYPE
 
 config PUBLIC_KEY_ALGO_RSA
 	tristate "RSA public-key algorithm"
-	select MPILIB
+	select CRYPTO_RSA
 	help
 	  This option enables support for the RSA algorithm (PKCS#1, RFC3447).
 
@@ -67,4 +68,12 @@ config SIGNED_PE_FILE_VERIFICATION
 	  This option provides support for verifying the signature(s) on a
 	  signed PE binary.
 
+config EFI_SIGNATURE_LIST_PARSER
+	bool "EFI signature list parser"
+	depends on EFI
+	select X509_CERTIFICATE_PARSER
+	help
+	  This option provides support for parsing EFI signature lists for
+	  X.509 certificates and turning them into keys.
+
 endif # ASYMMETRIC_KEY_TYPE
--- zfcpdump-kernel-4.4.orig/crypto/asymmetric_keys/Makefile
+++ zfcpdump-kernel-4.4/crypto/asymmetric_keys/Makefile
@@ -8,6 +8,7 @@ asymmetric_keys-y := asymmetric_type.o s
 
 obj-$(CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE) += public_key.o
 obj-$(CONFIG_PUBLIC_KEY_ALGO_RSA) += rsa.o
+obj-$(CONFIG_EFI_SIGNATURE_LIST_PARSER) += efi_parser.o
 
 #
 # X.509 Certificate handling
@@ -16,21 +17,18 @@ obj-$(CONFIG_X509_CERTIFICATE_PARSER) +=
 x509_key_parser-y := \
 	x509-asn1.o \
 	x509_akid-asn1.o \
-	x509_rsakey-asn1.o \
 	x509_cert_parser.o \
 	x509_public_key.o
 
 $(obj)/x509_cert_parser.o: \
 	$(obj)/x509-asn1.h \
-	$(obj)/x509_akid-asn1.h \
-	$(obj)/x509_rsakey-asn1.h
+	$(obj)/x509_akid-asn1.h
+
 $(obj)/x509-asn1.o: $(obj)/x509-asn1.c $(obj)/x509-asn1.h
 $(obj)/x509_akid-asn1.o: $(obj)/x509_akid-asn1.c $(obj)/x509_akid-asn1.h
-$(obj)/x509_rsakey-asn1.o: $(obj)/x509_rsakey-asn1.c $(obj)/x509_rsakey-asn1.h
 
 clean-files	+= x509-asn1.c x509-asn1.h
 clean-files	+= x509_akid-asn1.c x509_akid-asn1.h
-clean-files	+= x509_rsakey-asn1.c x509_rsakey-asn1.h
 
 #
 # PKCS#7 message handling
--- /dev/null
+++ zfcpdump-kernel-4.4/crypto/asymmetric_keys/efi_parser.c
@@ -0,0 +1,109 @@
+/* EFI signature/key/certificate list parser
+ *
+ * Copyright (C) 2012 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+
+#define pr_fmt(fmt) "EFI: "fmt
+#include <linux/module.h>
+#include <linux/printk.h>
+#include <linux/err.h>
+#include <linux/efi.h>
+#include <keys/asymmetric-type.h>
+
+static __initdata efi_guid_t efi_cert_x509_guid = EFI_CERT_X509_GUID;
+
+/**
+ * parse_efi_signature_list - Parse an EFI signature list for certificates
+ * @data: The data blob to parse
+ * @size: The size of the data blob
+ * @keyring: The keyring to add extracted keys to
+ */
+int __init parse_efi_signature_list(const void *data, size_t size, struct key *keyring)
+{
+	unsigned offs = 0;
+	size_t lsize, esize, hsize, elsize;
+
+	pr_devel("-->%s(,%zu)\n", __func__, size);
+
+	while (size > 0) {
+		efi_signature_list_t list;
+		const efi_signature_data_t *elem;
+		key_ref_t key;
+
+		if (size < sizeof(list))
+			return -EBADMSG;
+
+		memcpy(&list, data, sizeof(list));
+		pr_devel("LIST[%04x] guid=%pUl ls=%x hs=%x ss=%x\n",
+			 offs,
+			 list.signature_type.b, list.signature_list_size,
+			 list.signature_header_size, list.signature_size);
+
+		lsize = list.signature_list_size;
+		hsize = list.signature_header_size;
+		esize = list.signature_size;
+		elsize = lsize - sizeof(list) - hsize;
+
+		if (lsize > size) {
+			pr_devel("<--%s() = -EBADMSG [overrun @%x]\n",
+				 __func__, offs);
+			return -EBADMSG;
+		}
+		if (lsize < sizeof(list) ||
+		    lsize - sizeof(list) < hsize ||
+		    esize < sizeof(*elem) ||
+		    elsize < esize ||
+		    elsize % esize != 0) {
+			pr_devel("- bad size combo @%x\n", offs);
+			return -EBADMSG;
+		}
+
+		if (efi_guidcmp(list.signature_type, efi_cert_x509_guid) != 0) {
+			data += lsize;
+			size -= lsize;
+			offs += lsize;
+			continue;
+		}
+
+		data += sizeof(list) + hsize;
+		size -= sizeof(list) + hsize;
+		offs += sizeof(list) + hsize;
+
+		for (; elsize > 0; elsize -= esize) {
+			elem = data;
+
+			pr_devel("ELEM[%04x]\n", offs);
+
+			key = key_create_or_update(
+				make_key_ref(keyring, 1),
+				"asymmetric",
+				NULL,
+				&elem->signature_data,
+				esize - sizeof(*elem),
+				(KEY_POS_ALL & ~KEY_POS_SETATTR) |
+				KEY_USR_VIEW,
+				KEY_ALLOC_NOT_IN_QUOTA |
+				KEY_ALLOC_TRUSTED);
+
+			if (IS_ERR(key))
+				pr_err("Problem loading in-kernel X.509 certificate (%ld)\n",
+				       PTR_ERR(key));
+			else
+				pr_notice("Loaded cert '%s' linked to '%s'\n",
+					  key_ref_to_ptr(key)->description,
+					  keyring->description);
+
+			data += esize;
+			size -= esize;
+			offs += esize;
+		}
+	}
+
+	return 0;
+}
--- zfcpdump-kernel-4.4.orig/crypto/asymmetric_keys/pkcs7_parser.c
+++ zfcpdump-kernel-4.4/crypto/asymmetric_keys/pkcs7_parser.c
@@ -15,7 +15,7 @@
 #include <linux/slab.h>
 #include <linux/err.h>
 #include <linux/oid_registry.h>
-#include "public_key.h"
+#include <crypto/public_key.h>
 #include "pkcs7_parser.h"
 #include "pkcs7-asn1.h"
 
@@ -44,7 +44,7 @@ struct pkcs7_parse_context {
 static void pkcs7_free_signed_info(struct pkcs7_signed_info *sinfo)
 {
 	if (sinfo) {
-		mpi_free(sinfo->sig.mpi[0]);
+		kfree(sinfo->sig.s);
 		kfree(sinfo->sig.digest);
 		kfree(sinfo->signing_cert_id);
 		kfree(sinfo);
@@ -616,16 +616,14 @@ int pkcs7_sig_note_signature(void *conte
 			     const void *value, size_t vlen)
 {
 	struct pkcs7_parse_context *ctx = context;
-	MPI mpi;
 
 	BUG_ON(ctx->sinfo->sig.pkey_algo != PKEY_ALGO_RSA);
 
-	mpi = mpi_read_raw_data(value, vlen);
-	if (!mpi)
+	ctx->sinfo->sig.s = kmemdup(value, vlen, GFP_KERNEL);
+	if (!ctx->sinfo->sig.s)
 		return -ENOMEM;
 
-	ctx->sinfo->sig.mpi[0] = mpi;
-	ctx->sinfo->sig.nr_mpi = 1;
+	ctx->sinfo->sig.s_size = vlen;
 	return 0;
 }
 
--- zfcpdump-kernel-4.4.orig/crypto/asymmetric_keys/pkcs7_trust.c
+++ zfcpdump-kernel-4.4/crypto/asymmetric_keys/pkcs7_trust.c
@@ -17,7 +17,7 @@
 #include <linux/asn1.h>
 #include <linux/key.h>
 #include <keys/asymmetric-type.h>
-#include "public_key.h"
+#include <crypto/public_key.h>
 #include "pkcs7_parser.h"
 
 /**
@@ -178,6 +178,8 @@ int pkcs7_validate_trust(struct pkcs7_me
 	int cached_ret = -ENOKEY;
 	int ret;
 
+	*_trusted = false;
+
 	for (p = pkcs7->certs; p; p = p->next)
 		p->seen = false;
 
--- zfcpdump-kernel-4.4.orig/crypto/asymmetric_keys/pkcs7_verify.c
+++ zfcpdump-kernel-4.4/crypto/asymmetric_keys/pkcs7_verify.c
@@ -16,7 +16,7 @@
 #include <linux/err.h>
 #include <linux/asn1.h>
 #include <crypto/hash.h>
-#include "public_key.h"
+#include <crypto/public_key.h>
 #include "pkcs7_parser.h"
 
 /*
--- zfcpdump-kernel-4.4.orig/crypto/asymmetric_keys/public_key.c
+++ zfcpdump-kernel-4.4/crypto/asymmetric_keys/public_key.c
@@ -18,24 +18,16 @@
 #include <linux/slab.h>
 #include <linux/seq_file.h>
 #include <keys/asymmetric-subtype.h>
-#include "public_key.h"
+#include <crypto/public_key.h>
 
 MODULE_LICENSE("GPL");
 
 const char *const pkey_algo_name[PKEY_ALGO__LAST] = {
-	[PKEY_ALGO_DSA]		= "DSA",
-	[PKEY_ALGO_RSA]		= "RSA",
+	[PKEY_ALGO_DSA]		= "dsa",
+	[PKEY_ALGO_RSA]		= "rsa",
 };
 EXPORT_SYMBOL_GPL(pkey_algo_name);
 
-const struct public_key_algorithm *pkey_algo[PKEY_ALGO__LAST] = {
-#if defined(CONFIG_PUBLIC_KEY_ALGO_RSA) || \
-	defined(CONFIG_PUBLIC_KEY_ALGO_RSA_MODULE)
-	[PKEY_ALGO_RSA]		= &RSA_public_key_algorithm,
-#endif
-};
-EXPORT_SYMBOL_GPL(pkey_algo);
-
 const char *const pkey_id_type_name[PKEY_ID_TYPE__LAST] = {
 	[PKEY_ID_PGP]		= "PGP",
 	[PKEY_ID_X509]		= "X509",
@@ -43,6 +35,12 @@ const char *const pkey_id_type_name[PKEY
 };
 EXPORT_SYMBOL_GPL(pkey_id_type_name);
 
+static int (*alg_verify[PKEY_ALGO__LAST])(const struct public_key *pkey,
+	const struct public_key_signature *sig) = {
+	NULL,
+	rsa_verify_signature
+};
+
 /*
  * Provide a part of a description of the key for /proc/keys.
  */
@@ -53,7 +51,8 @@ static void public_key_describe(const st
 
 	if (key)
 		seq_printf(m, "%s.%s",
-			   pkey_id_type_name[key->id_type], key->algo->name);
+			   pkey_id_type_name[key->id_type],
+			   pkey_algo_name[key->pkey_algo]);
 }
 
 /*
@@ -62,50 +61,31 @@ static void public_key_describe(const st
 void public_key_destroy(void *payload)
 {
 	struct public_key *key = payload;
-	int i;
 
-	if (key) {
-		for (i = 0; i < ARRAY_SIZE(key->mpi); i++)
-			mpi_free(key->mpi[i]);
-		kfree(key);
-	}
+	if (key)
+		kfree(key->key);
+	kfree(key);
 }
 EXPORT_SYMBOL_GPL(public_key_destroy);
 
 /*
  * Verify a signature using a public key.
  */
-int public_key_verify_signature(const struct public_key *pk,
+int public_key_verify_signature(const struct public_key *pkey,
 				const struct public_key_signature *sig)
 {
-	const struct public_key_algorithm *algo;
-
-	BUG_ON(!pk);
-	BUG_ON(!pk->mpi[0]);
-	BUG_ON(!pk->mpi[1]);
+	BUG_ON(!pkey);
 	BUG_ON(!sig);
 	BUG_ON(!sig->digest);
-	BUG_ON(!sig->mpi[0]);
+	BUG_ON(!sig->s);
+
+	if (pkey->pkey_algo >= PKEY_ALGO__LAST)
+		return -ENOPKG;
 
-	algo = pk->algo;
-	if (!algo) {
-		if (pk->pkey_algo >= PKEY_ALGO__LAST)
-			return -ENOPKG;
-		algo = pkey_algo[pk->pkey_algo];
-		if (!algo)
-			return -ENOPKG;
-	}
-
-	if (!algo->verify_signature)
-		return -ENOTSUPP;
-
-	if (sig->nr_mpi != algo->n_sig_mpi) {
-		pr_debug("Signature has %u MPI not %u\n",
-			 sig->nr_mpi, algo->n_sig_mpi);
-		return -EINVAL;
-	}
+	if (!alg_verify[pkey->pkey_algo])
+		return -ENOPKG;
 
-	return algo->verify_signature(pk, sig);
+	return alg_verify[pkey->pkey_algo](pkey, sig);
 }
 EXPORT_SYMBOL_GPL(public_key_verify_signature);
 
--- zfcpdump-kernel-4.4.orig/crypto/asymmetric_keys/public_key.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/* Public key algorithm internals
- *
- * See Documentation/crypto/asymmetric-keys.txt
- *
- * Copyright (C) 2012 Red Hat, Inc. All Rights Reserved.
- * Written by David Howells (dhowells@redhat.com)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public Licence
- * as published by the Free Software Foundation; either version
- * 2 of the Licence, or (at your option) any later version.
- */
-
-#include <crypto/public_key.h>
-
-extern struct asymmetric_key_subtype public_key_subtype;
-
-/*
- * Public key algorithm definition.
- */
-struct public_key_algorithm {
-	const char	*name;
-	u8		n_pub_mpi;	/* Number of MPIs in public key */
-	u8		n_sec_mpi;	/* Number of MPIs in secret key */
-	u8		n_sig_mpi;	/* Number of MPIs in a signature */
-	int (*verify_signature)(const struct public_key *key,
-				const struct public_key_signature *sig);
-};
-
-extern const struct public_key_algorithm RSA_public_key_algorithm;
-
-/*
- * public_key.c
- */
-extern int public_key_verify_signature(const struct public_key *pk,
-				       const struct public_key_signature *sig);
--- zfcpdump-kernel-4.4.orig/crypto/asymmetric_keys/rsa.c
+++ zfcpdump-kernel-4.4/crypto/asymmetric_keys/rsa.c
@@ -11,10 +11,10 @@
 
 #define pr_fmt(fmt) "RSA: "fmt
 #include <linux/module.h>
-#include <linux/kernel.h>
 #include <linux/slab.h>
+#include <crypto/akcipher.h>
+#include <crypto/public_key.h>
 #include <crypto/algapi.h>
-#include "public_key.h"
 
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("RSA Public Key Algorithm");
@@ -84,72 +84,10 @@ static const struct {
 #undef _
 };
 
-/*
- * RSAVP1() function [RFC3447 sec 5.2.2]
- */
-static int RSAVP1(const struct public_key *key, MPI s, MPI *_m)
-{
-	MPI m;
-	int ret;
-
-	/* (1) Validate 0 <= s < n */
-	if (mpi_cmp_ui(s, 0) < 0) {
-		kleave(" = -EBADMSG [s < 0]");
-		return -EBADMSG;
-	}
-	if (mpi_cmp(s, key->rsa.n) >= 0) {
-		kleave(" = -EBADMSG [s >= n]");
-		return -EBADMSG;
-	}
-
-	m = mpi_alloc(0);
-	if (!m)
-		return -ENOMEM;
-
-	/* (2) m = s^e mod n */
-	ret = mpi_powm(m, s, key->rsa.e, key->rsa.n);
-	if (ret < 0) {
-		mpi_free(m);
-		return ret;
-	}
-
-	*_m = m;
-	return 0;
-}
-
-/*
- * Integer to Octet String conversion [RFC3447 sec 4.1]
- */
-static int RSA_I2OSP(MPI x, size_t xLen, u8 **pX)
-{
-	unsigned X_size, x_size;
-	int X_sign;
-	u8 *X;
-
-	/* Make sure the string is the right length.  The number should begin
-	 * with { 0x00, 0x01, ... } so we have to account for 15 leading zero
-	 * bits not being reported by MPI.
-	 */
-	x_size = mpi_get_nbits(x);
-	pr_devel("size(x)=%u xLen*8=%zu\n", x_size, xLen * 8);
-	if (x_size != xLen * 8 - 15)
-		return -ERANGE;
-
-	X = mpi_get_buffer(x, &X_size, &X_sign);
-	if (!X)
-		return -ENOMEM;
-	if (X_sign < 0) {
-		kfree(X);
-		return -EBADMSG;
-	}
-	if (X_size != xLen - 1) {
-		kfree(X);
-		return -EBADMSG;
-	}
-
-	*pX = X;
-	return 0;
-}
+struct rsa_completion {
+	struct completion completion;
+	int err;
+};
 
 /*
  * Perform the RSA signature verification.
@@ -160,7 +98,7 @@ static int RSA_I2OSP(MPI x, size_t xLen,
  * @asn1_template: The DigestInfo ASN.1 template
  * @asn1_size: Size of asm1_template[]
  */
-static int RSA_verify(const u8 *H, const u8 *EM, size_t k, size_t hash_size,
+static int rsa_verify(const u8 *H, const u8 *EM, size_t k, size_t hash_size,
 		      const u8 *asn1_template, size_t asn1_size)
 {
 	unsigned PS_end, T_offset, i;
@@ -170,9 +108,11 @@ static int RSA_verify(const u8 *H, const
 	if (k < 2 + 1 + asn1_size + hash_size)
 		return -EBADMSG;
 
-	/* Decode the EMSA-PKCS1-v1_5 */
-	if (EM[1] != 0x01) {
-		kleave(" = -EBADMSG [EM[1] == %02u]", EM[1]);
+	/* Decode the EMSA-PKCS1-v1_5
+	 * note: leading zeros are stripped by the RSA implementation
+	 */
+	if (EM[0] != 0x01) {
+		kleave(" = -EBADMSG [EM[0] == %02u]", EM[0]);
 		return -EBADMSG;
 	}
 
@@ -183,7 +123,7 @@ static int RSA_verify(const u8 *H, const
 		return -EBADMSG;
 	}
 
-	for (i = 2; i < PS_end; i++) {
+	for (i = 1; i < PS_end; i++) {
 		if (EM[i] != 0xff) {
 			kleave(" = -EBADMSG [EM[PS%x] == %02u]", i - 2, EM[i]);
 			return -EBADMSG;
@@ -204,75 +144,81 @@ static int RSA_verify(const u8 *H, const
 	return 0;
 }
 
-/*
- * Perform the verification step [RFC3447 sec 8.2.2].
- */
-static int RSA_verify_signature(const struct public_key *key,
-				const struct public_key_signature *sig)
+static void public_key_verify_done(struct crypto_async_request *req, int err)
 {
-	size_t tsize;
-	int ret;
+	struct rsa_completion *compl = req->data;
 
-	/* Variables as per RFC3447 sec 8.2.2 */
-	const u8 *H = sig->digest;
-	u8 *EM = NULL;
-	MPI m = NULL;
-	size_t k;
-
-	kenter("");
-
-	if (!RSA_ASN1_templates[sig->pkey_hash_algo].data)
-		return -ENOTSUPP;
-
-	/* (1) Check the signature size against the public key modulus size */
-	k = mpi_get_nbits(key->rsa.n);
-	tsize = mpi_get_nbits(sig->rsa.s);
-
-	/* According to RFC 4880 sec 3.2, length of MPI is computed starting
-	 * from most significant bit.  So the RFC 3447 sec 8.2.2 size check
-	 * must be relaxed to conform with shorter signatures - so we fail here
-	 * only if signature length is longer than modulus size.
-	 */
-	pr_devel("step 1: k=%zu size(S)=%zu\n", k, tsize);
-	if (k < tsize) {
-		ret = -EBADMSG;
-		goto error;
+	if (err == -EINPROGRESS)
+		return;
+
+	compl->err = err;
+	complete(&compl->completion);
+}
+
+int rsa_verify_signature(const struct public_key *pkey,
+			 const struct public_key_signature *sig)
+{
+	struct crypto_akcipher *tfm;
+	struct akcipher_request *req;
+	struct rsa_completion compl;
+	struct scatterlist sig_sg, sg_out;
+	void *outbuf = NULL;
+	unsigned int outlen = 0;
+	int ret = -ENOMEM;
+
+	tfm = crypto_alloc_akcipher("rsa", 0, 0);
+	if (IS_ERR(tfm))
+		goto error_out;
+
+	req = akcipher_request_alloc(tfm, GFP_KERNEL);
+	if (!req)
+		goto error_free_tfm;
+
+	ret = crypto_akcipher_set_pub_key(tfm, pkey->key, pkey->keylen);
+	if (ret)
+		goto error_free_req;
+
+	ret = -EINVAL;
+	outlen = crypto_akcipher_maxsize(tfm);
+	if (!outlen)
+		goto error_free_req;
+
+	/* Initialize the output buffer */
+	ret = -ENOMEM;
+	outbuf = kmalloc(outlen, GFP_KERNEL);
+	if (!outbuf)
+		goto error_free_req;
+
+	sg_init_one(&sig_sg, sig->s, sig->s_size);
+	sg_init_one(&sg_out, outbuf, outlen);
+	akcipher_request_set_crypt(req, &sig_sg, &sg_out, sig->s_size, outlen);
+	init_completion(&compl.completion);
+	akcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG |
+				      CRYPTO_TFM_REQ_MAY_SLEEP,
+				      public_key_verify_done, &compl);
+
+	ret = crypto_akcipher_verify(req);
+	if (ret == -EINPROGRESS) {
+		wait_for_completion(&compl.completion);
+		ret = compl.err;
 	}
 
-	/* Round up and convert to octets */
-	k = (k + 7) / 8;
+	if (ret)
+		goto error_free_req;
 
-	/* (2b) Apply the RSAVP1 verification primitive to the public key */
-	ret = RSAVP1(key, sig->rsa.s, &m);
-	if (ret < 0)
-		goto error;
-
-	/* (2c) Convert the message representative (m) to an encoded message
-	 *      (EM) of length k octets.
-	 *
-	 *      NOTE!  The leading zero byte is suppressed by MPI, so we pass a
-	 *      pointer to the _preceding_ byte to RSA_verify()!
+	/* Output from the operation is an encoded message (EM) of
+	 * length k octets.
 	 */
-	ret = RSA_I2OSP(m, k, &EM);
-	if (ret < 0)
-		goto error;
-
-	ret = RSA_verify(H, EM - 1, k, sig->digest_size,
+	outlen = req->dst_len;
+	ret = rsa_verify(sig->digest, outbuf, outlen, sig->digest_size,
 			 RSA_ASN1_templates[sig->pkey_hash_algo].data,
 			 RSA_ASN1_templates[sig->pkey_hash_algo].size);
-
-error:
-	kfree(EM);
-	mpi_free(m);
-	kleave(" = %d", ret);
+error_free_req:
+	akcipher_request_free(req);
+error_free_tfm:
+	crypto_free_akcipher(tfm);
+error_out:
+	kfree(outbuf);
 	return ret;
 }
-
-const struct public_key_algorithm RSA_public_key_algorithm = {
-	.name		= "RSA",
-	.n_pub_mpi	= 2,
-	.n_sec_mpi	= 3,
-	.n_sig_mpi	= 1,
-	.verify_signature = RSA_verify_signature,
-};
-EXPORT_SYMBOL_GPL(RSA_public_key_algorithm);
+EXPORT_SYMBOL_GPL(rsa_verify_signature);
--- zfcpdump-kernel-4.4.orig/crypto/asymmetric_keys/x509_cert_parser.c
+++ zfcpdump-kernel-4.4/crypto/asymmetric_keys/x509_cert_parser.c
@@ -15,11 +15,10 @@
 #include <linux/slab.h>
 #include <linux/err.h>
 #include <linux/oid_registry.h>
-#include "public_key.h"
+#include <crypto/public_key.h>
 #include "x509_parser.h"
 #include "x509-asn1.h"
 #include "x509_akid-asn1.h"
-#include "x509_rsakey-asn1.h"
 
 struct x509_parse_context {
 	struct x509_certificate	*cert;		/* Certificate being constructed */
@@ -56,7 +55,7 @@ void x509_free_certificate(struct x509_c
 		kfree(cert->akid_id);
 		kfree(cert->akid_skid);
 		kfree(cert->sig.digest);
-		mpi_free(cert->sig.rsa.s);
+		kfree(cert->sig.s);
 		kfree(cert);
 	}
 }
@@ -103,12 +102,12 @@ struct x509_certificate *x509_cert_parse
 		}
 	}
 
-	/* Decode the public key */
-	ret = asn1_ber_decoder(&x509_rsakey_decoder, ctx,
-			       ctx->key, ctx->key_size);
-	if (ret < 0)
+	cert->pub->key = kmemdup(ctx->key, ctx->key_size, GFP_KERNEL);
+	if (!cert->pub->key)
 		goto error_decode;
 
+	cert->pub->keylen = ctx->key_size;
+
 	/* Generate cert issuer + serial number key ID */
 	kid = asymmetric_key_generate_id(cert->raw_serial,
 					 cert->raw_serial_size,
@@ -124,6 +123,7 @@ struct x509_certificate *x509_cert_parse
 	return cert;
 
 error_decode:
+	kfree(cert->pub->key);
 	kfree(ctx);
 error_no_ctx:
 	x509_free_certificate(cert);
@@ -404,29 +404,6 @@ int x509_extract_key_data(void *context,
 	return 0;
 }
 
-/*
- * Extract a RSA public key value
- */
-int rsa_extract_mpi(void *context, size_t hdrlen,
-		    unsigned char tag,
-		    const void *value, size_t vlen)
-{
-	struct x509_parse_context *ctx = context;
-	MPI mpi;
-
-	if (ctx->nr_mpi >= ARRAY_SIZE(ctx->cert->pub->mpi)) {
-		pr_err("Too many public key MPIs in certificate\n");
-		return -EBADMSG;
-	}
-
-	mpi = mpi_read_raw_data(value, vlen);
-	if (!mpi)
-		return -ENOMEM;
-
-	ctx->cert->pub->mpi[ctx->nr_mpi++] = mpi;
-	return 0;
-}
-
 /* The keyIdentifier in AuthorityKeyIdentifier SEQUENCE is tag(CONT,PRIM,0) */
 #define SEQ_TAG_KEYID (ASN1_CONT << 6)
 
@@ -494,7 +471,7 @@ int x509_decode_time(time64_t *_t,  size
 		     unsigned char tag,
 		     const unsigned char *value, size_t vlen)
 {
-	static const unsigned char month_lengths[] = { 31, 29, 31, 30, 31, 30,
+	static const unsigned char month_lengths[] = { 31, 28, 31, 30, 31, 30,
 						       31, 31, 30, 31, 30, 31 };
 	const unsigned char *p = value;
 	unsigned year, mon, day, hour, min, sec, mon_len;
@@ -540,9 +517,9 @@ int x509_decode_time(time64_t *_t,  size
 		if (year % 4 == 0) {
 			mon_len = 29;
 			if (year % 100 == 0) {
-				year /= 100;
-				if (year % 4 != 0)
-					mon_len = 28;
+				mon_len = 28;
+				if (year % 400 == 0)
+					mon_len = 29;
 			}
 		}
 	}
--- zfcpdump-kernel-4.4.orig/crypto/asymmetric_keys/x509_public_key.c
+++ zfcpdump-kernel-4.4/crypto/asymmetric_keys/x509_public_key.c
@@ -13,15 +13,11 @@
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/slab.h>
-#include <linux/err.h>
-#include <linux/mpi.h>
-#include <linux/asn1_decoder.h>
 #include <keys/asymmetric-subtype.h>
 #include <keys/asymmetric-parser.h>
 #include <keys/system_keyring.h>
 #include <crypto/hash.h>
 #include "asymmetric_keys.h"
-#include "public_key.h"
 #include "x509_parser.h"
 
 static bool use_builtin_keys;
@@ -167,13 +163,15 @@ int x509_get_sig_params(struct x509_cert
 
 	if (cert->unsupported_crypto)
 		return -ENOPKG;
-	if (cert->sig.rsa.s)
+	if (cert->sig.s)
 		return 0;
 
-	cert->sig.rsa.s = mpi_read_raw_data(cert->raw_sig, cert->raw_sig_size);
-	if (!cert->sig.rsa.s)
+	cert->sig.s = kmemdup(cert->raw_sig, cert->raw_sig_size,
+			      GFP_KERNEL);
+	if (!cert->sig.s)
 		return -ENOMEM;
-	cert->sig.nr_mpi = 1;
+
+	cert->sig.s_size = cert->raw_sig_size;
 
 	/* Allocate the hashing algorithm we're going to need and find out how
 	 * big the hash operational data will be.
@@ -296,8 +294,6 @@ static int x509_key_preparse(struct key_
 	if (cert->pub->pkey_algo >= PKEY_ALGO__LAST ||
 	    cert->sig.pkey_algo >= PKEY_ALGO__LAST ||
 	    cert->sig.pkey_hash_algo >= PKEY_HASH__LAST ||
-	    !pkey_algo[cert->pub->pkey_algo] ||
-	    !pkey_algo[cert->sig.pkey_algo] ||
 	    !hash_algo_name[cert->sig.pkey_hash_algo]) {
 		ret = -ENOPKG;
 		goto error_free_cert;
@@ -309,7 +305,6 @@ static int x509_key_preparse(struct key_
 		 pkey_algo_name[cert->sig.pkey_algo],
 		 hash_algo_name[cert->sig.pkey_hash_algo]);
 
-	cert->pub->algo = pkey_algo[cert->pub->pkey_algo];
 	cert->pub->id_type = PKEY_ID_X509;
 
 	/* Check the signature on the key if it appears to be self-signed */
@@ -321,6 +316,8 @@ static int x509_key_preparse(struct key_
 			goto error_free_cert;
 	} else if (!prep->trusted) {
 		ret = x509_validate_trust(cert, get_system_trusted_keyring());
+		if (ret)
+			ret = x509_validate_trust(cert, get_ima_mok_keyring());
 		if (!ret)
 			prep->trusted = 1;
 	}
--- zfcpdump-kernel-4.4.orig/crypto/asymmetric_keys/x509_rsakey.asn1
+++ /dev/null
@@ -1,4 +0,0 @@
-RSAPublicKey ::= SEQUENCE {
-	modulus			INTEGER ({ rsa_extract_mpi }),	-- n
-	publicExponent		INTEGER ({ rsa_extract_mpi })	-- e
-	}
--- zfcpdump-kernel-4.4.orig/crypto/blkcipher.c
+++ zfcpdump-kernel-4.4/crypto/blkcipher.c
@@ -234,6 +234,8 @@ static int blkcipher_walk_next(struct bl
 		return blkcipher_walk_done(desc, walk, -EINVAL);
 	}
 
+	bsize = min(walk->walk_blocksize, n);
+
 	walk->flags &= ~(BLKCIPHER_WALK_SLOW | BLKCIPHER_WALK_COPY |
 			 BLKCIPHER_WALK_DIFF);
 	if (!scatterwalk_aligned(&walk->in, walk->alignmask) ||
@@ -246,7 +248,6 @@ static int blkcipher_walk_next(struct bl
 		}
 	}
 
-	bsize = min(walk->walk_blocksize, n);
 	n = scatterwalk_clamp(&walk->in, n);
 	n = scatterwalk_clamp(&walk->out, n);
 
--- zfcpdump-kernel-4.4.orig/crypto/crc32c_generic.c
+++ zfcpdump-kernel-4.4/crypto/crc32c_generic.c
@@ -172,4 +172,3 @@ MODULE_DESCRIPTION("CRC32c (Castagnoli)
 MODULE_LICENSE("GPL");
 MODULE_ALIAS_CRYPTO("crc32c");
 MODULE_ALIAS_CRYPTO("crc32c-generic");
-MODULE_SOFTDEP("pre: crc32c");
--- zfcpdump-kernel-4.4.orig/crypto/cryptd.c
+++ zfcpdump-kernel-4.4/crypto/cryptd.c
@@ -594,9 +594,14 @@ static int cryptd_hash_export(struct aha
 
 static int cryptd_hash_import(struct ahash_request *req, const void *in)
 {
-	struct cryptd_hash_request_ctx *rctx = ahash_request_ctx(req);
+	struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
+	struct cryptd_hash_ctx *ctx = crypto_ahash_ctx(tfm);
+	struct shash_desc *desc = cryptd_shash_desc(req);
 
-	return crypto_shash_import(&rctx->desc, in);
+	desc->tfm = ctx->child;
+	desc->flags = req->base.flags;
+
+	return crypto_shash_import(desc, in);
 }
 
 static int cryptd_create_hash(struct crypto_template *tmpl, struct rtattr **tb,
--- zfcpdump-kernel-4.4.orig/crypto/crypto_user.c
+++ zfcpdump-kernel-4.4/crypto/crypto_user.c
@@ -455,6 +455,7 @@ static const int crypto_msg_min[CRYPTO_N
 	[CRYPTO_MSG_NEWALG	- CRYPTO_MSG_BASE] = MSGSIZE(crypto_user_alg),
 	[CRYPTO_MSG_DELALG	- CRYPTO_MSG_BASE] = MSGSIZE(crypto_user_alg),
 	[CRYPTO_MSG_UPDATEALG	- CRYPTO_MSG_BASE] = MSGSIZE(crypto_user_alg),
+	[CRYPTO_MSG_GETALG	- CRYPTO_MSG_BASE] = MSGSIZE(crypto_user_alg),
 	[CRYPTO_MSG_DELRNG	- CRYPTO_MSG_BASE] = 0,
 };
 
@@ -499,6 +500,7 @@ static int crypto_user_rcv_msg(struct sk
 		if (link->dump == NULL)
 			return -EINVAL;
 
+		down_read(&crypto_alg_sem);
 		list_for_each_entry(alg, &crypto_alg_list, cra_list)
 			dump_alloc += CRYPTO_REPORT_MAXSIZE;
 
@@ -508,8 +510,11 @@ static int crypto_user_rcv_msg(struct sk
 				.done = link->done,
 				.min_dump_alloc = dump_alloc,
 			};
-			return netlink_dump_start(crypto_nlsk, skb, nlh, &c);
+			err = netlink_dump_start(crypto_nlsk, skb, nlh, &c);
 		}
+		up_read(&crypto_alg_sem);
+
+		return err;
 	}
 
 	err = nlmsg_parse(nlh, crypto_msg_min[type], attrs, CRYPTOCFGA_MAX,
--- zfcpdump-kernel-4.4.orig/crypto/echainiv.c
+++ zfcpdump-kernel-4.4/crypto/echainiv.c
@@ -1,8 +1,8 @@
 /*
  * echainiv: Encrypted Chain IV Generator
  *
- * This generator generates an IV based on a sequence number by xoring it
- * with a salt and then encrypting it with the same key as used to encrypt
+ * This generator generates an IV based on a sequence number by multiplying
+ * it with a salt and then encrypting it with the same key as used to encrypt
  * the plain text.  This algorithm requires that the block size be equal
  * to the IV size.  It is mainly useful for CBC.
  *
@@ -23,81 +23,17 @@
 #include <linux/err.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
-#include <linux/mm.h>
 #include <linux/module.h>
-#include <linux/percpu.h>
-#include <linux/spinlock.h>
+#include <linux/slab.h>
 #include <linux/string.h>
 
-#define MAX_IV_SIZE 16
-
-static DEFINE_PER_CPU(u32 [MAX_IV_SIZE / sizeof(u32)], echainiv_iv);
-
-/* We don't care if we get preempted and read/write IVs from the next CPU. */
-static void echainiv_read_iv(u8 *dst, unsigned size)
-{
-	u32 *a = (u32 *)dst;
-	u32 __percpu *b = echainiv_iv;
-
-	for (; size >= 4; size -= 4) {
-		*a++ = this_cpu_read(*b);
-		b++;
-	}
-}
-
-static void echainiv_write_iv(const u8 *src, unsigned size)
-{
-	const u32 *a = (const u32 *)src;
-	u32 __percpu *b = echainiv_iv;
-
-	for (; size >= 4; size -= 4) {
-		this_cpu_write(*b, *a);
-		a++;
-		b++;
-	}
-}
-
-static void echainiv_encrypt_complete2(struct aead_request *req, int err)
-{
-	struct aead_request *subreq = aead_request_ctx(req);
-	struct crypto_aead *geniv;
-	unsigned int ivsize;
-
-	if (err == -EINPROGRESS)
-		return;
-
-	if (err)
-		goto out;
-
-	geniv = crypto_aead_reqtfm(req);
-	ivsize = crypto_aead_ivsize(geniv);
-
-	echainiv_write_iv(subreq->iv, ivsize);
-
-	if (req->iv != subreq->iv)
-		memcpy(req->iv, subreq->iv, ivsize);
-
-out:
-	if (req->iv != subreq->iv)
-		kzfree(subreq->iv);
-}
-
-static void echainiv_encrypt_complete(struct crypto_async_request *base,
-					 int err)
-{
-	struct aead_request *req = base->data;
-
-	echainiv_encrypt_complete2(req, err);
-	aead_request_complete(req, err);
-}
-
 static int echainiv_encrypt(struct aead_request *req)
 {
 	struct crypto_aead *geniv = crypto_aead_reqtfm(req);
 	struct aead_geniv_ctx *ctx = crypto_aead_ctx(geniv);
 	struct aead_request *subreq = aead_request_ctx(req);
-	crypto_completion_t compl;
-	void *data;
+	__be64 nseqno;
+	u64 seqno;
 	u8 *info;
 	unsigned int ivsize = crypto_aead_ivsize(geniv);
 	int err;
@@ -107,8 +43,6 @@ static int echainiv_encrypt(struct aead_
 
 	aead_request_set_tfm(subreq, ctx->child);
 
-	compl = echainiv_encrypt_complete;
-	data = req;
 	info = req->iv;
 
 	if (req->src != req->dst) {
@@ -123,29 +57,30 @@ static int echainiv_encrypt(struct aead_
 			return err;
 	}
 
-	if (unlikely(!IS_ALIGNED((unsigned long)info,
-				 crypto_aead_alignmask(geniv) + 1))) {
-		info = kmalloc(ivsize, req->base.flags &
-				       CRYPTO_TFM_REQ_MAY_SLEEP ? GFP_KERNEL:
-								  GFP_ATOMIC);
-		if (!info)
-			return -ENOMEM;
-
-		memcpy(info, req->iv, ivsize);
-	}
-
-	aead_request_set_callback(subreq, req->base.flags, compl, data);
+	aead_request_set_callback(subreq, req->base.flags,
+				  req->base.complete, req->base.data);
 	aead_request_set_crypt(subreq, req->dst, req->dst,
 			       req->cryptlen, info);
 	aead_request_set_ad(subreq, req->assoclen);
 
-	crypto_xor(info, ctx->salt, ivsize);
+	memcpy(&nseqno, info + ivsize - 8, 8);
+	seqno = be64_to_cpu(nseqno);
+	memset(info, 0, ivsize);
+
 	scatterwalk_map_and_copy(info, req->dst, req->assoclen, ivsize, 1);
-	echainiv_read_iv(info, ivsize);
 
-	err = crypto_aead_encrypt(subreq);
-	echainiv_encrypt_complete2(req, err);
-	return err;
+	do {
+		u64 a;
+
+		memcpy(&a, ctx->salt + ivsize - 8, 8);
+
+		a |= 1;
+		a *= seqno;
+
+		memcpy(info + ivsize - 8, &a, 8);
+	} while ((ivsize -= 8));
+
+	return crypto_aead_encrypt(subreq);
 }
 
 static int echainiv_decrypt(struct aead_request *req)
@@ -192,8 +127,7 @@ static int echainiv_aead_create(struct c
 	alg = crypto_spawn_aead_alg(spawn);
 
 	err = -EINVAL;
-	if (inst->alg.ivsize & (sizeof(u32) - 1) ||
-	    inst->alg.ivsize > MAX_IV_SIZE)
+	if (inst->alg.ivsize & (sizeof(u64) - 1) || !inst->alg.ivsize)
 		goto free_inst;
 
 	inst->alg.encrypt = echainiv_encrypt;
@@ -202,7 +136,6 @@ static int echainiv_aead_create(struct c
 	inst->alg.init = aead_init_geniv;
 	inst->alg.exit = aead_exit_geniv;
 
-	inst->alg.base.cra_alignmask |= __alignof__(u32) - 1;
 	inst->alg.base.cra_ctxsize = sizeof(struct aead_geniv_ctx);
 	inst->alg.base.cra_ctxsize += inst->alg.ivsize;
 
--- zfcpdump-kernel-4.4.orig/crypto/gcm.c
+++ zfcpdump-kernel-4.4/crypto/gcm.c
@@ -639,7 +639,9 @@ static int crypto_gcm_create_common(stru
 
 	ghash_alg = crypto_find_alg(ghash_name, &crypto_ahash_type,
 				    CRYPTO_ALG_TYPE_HASH,
-				    CRYPTO_ALG_TYPE_AHASH_MASK);
+				    CRYPTO_ALG_TYPE_AHASH_MASK |
+				    crypto_requires_sync(algt->type,
+							 algt->mask));
 	if (IS_ERR(ghash_alg))
 		return PTR_ERR(ghash_alg);
 
--- zfcpdump-kernel-4.4.orig/crypto/ghash-generic.c
+++ zfcpdump-kernel-4.4/crypto/ghash-generic.c
@@ -14,24 +14,13 @@
 
 #include <crypto/algapi.h>
 #include <crypto/gf128mul.h>
+#include <crypto/ghash.h>
 #include <crypto/internal/hash.h>
 #include <linux/crypto.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 
-#define GHASH_BLOCK_SIZE	16
-#define GHASH_DIGEST_SIZE	16
-
-struct ghash_ctx {
-	struct gf128mul_4k *gf128;
-};
-
-struct ghash_desc_ctx {
-	u8 buffer[GHASH_BLOCK_SIZE];
-	u32 bytes;
-};
-
 static int ghash_init(struct shash_desc *desc)
 {
 	struct ghash_desc_ctx *dctx = shash_desc_ctx(desc);
--- zfcpdump-kernel-4.4.orig/crypto/hash_info.c
+++ zfcpdump-kernel-4.4/crypto/hash_info.c
@@ -31,6 +31,7 @@ const char *const hash_algo_name[HASH_AL
 	[HASH_ALGO_TGR_128]	= "tgr128",
 	[HASH_ALGO_TGR_160]	= "tgr160",
 	[HASH_ALGO_TGR_192]	= "tgr192",
+	[HASH_ALGO_SM3_256]	= "sm3-256",
 };
 EXPORT_SYMBOL_GPL(hash_algo_name);
 
@@ -52,5 +53,6 @@ const int hash_digest_size[HASH_ALGO__LA
 	[HASH_ALGO_TGR_128]	= TGR128_DIGEST_SIZE,
 	[HASH_ALGO_TGR_160]	= TGR160_DIGEST_SIZE,
 	[HASH_ALGO_TGR_192]	= TGR192_DIGEST_SIZE,
+	[HASH_ALGO_SM3_256]	= SM3256_DIGEST_SIZE,
 };
 EXPORT_SYMBOL_GPL(hash_digest_size);
--- zfcpdump-kernel-4.4.orig/crypto/keywrap.c
+++ zfcpdump-kernel-4.4/crypto/keywrap.c
@@ -212,7 +212,7 @@ static int crypto_kw_decrypt(struct blkc
 			  SEMIBSIZE))
 		ret = -EBADMSG;
 
-	memzero_explicit(&block, sizeof(struct crypto_kw_block));
+	memzero_explicit(block, sizeof(struct crypto_kw_block));
 
 	return ret;
 }
@@ -297,7 +297,7 @@ static int crypto_kw_encrypt(struct blkc
 	/* establish the IV for the caller to pick up */
 	memcpy(desc->info, block->A, SEMIBSIZE);
 
-	memzero_explicit(&block, sizeof(struct crypto_kw_block));
+	memzero_explicit(block, sizeof(struct crypto_kw_block));
 
 	return 0;
 }
--- zfcpdump-kernel-4.4.orig/crypto/scatterwalk.c
+++ zfcpdump-kernel-4.4/crypto/scatterwalk.c
@@ -72,7 +72,8 @@ static void scatterwalk_pagedone(struct
 
 void scatterwalk_done(struct scatter_walk *walk, int out, int more)
 {
-	if (!(scatterwalk_pagelen(walk) & (PAGE_SIZE - 1)) || !more)
+	if (!more || walk->offset >= walk->sg->offset + walk->sg->length ||
+	    !(walk->offset & (PAGE_SIZE - 1)))
 		scatterwalk_pagedone(walk, out, more);
 }
 EXPORT_SYMBOL_GPL(scatterwalk_done);
--- zfcpdump-kernel-4.4.orig/crypto/shash.c
+++ zfcpdump-kernel-4.4/crypto/shash.c
@@ -354,9 +354,10 @@ int crypto_init_shash_ops_async(struct c
 	crt->final = shash_async_final;
 	crt->finup = shash_async_finup;
 	crt->digest = shash_async_digest;
+	crt->setkey = shash_async_setkey;
+
+	crt->has_setkey = alg->setkey != shash_no_setkey;
 
-	if (alg->setkey)
-		crt->setkey = shash_async_setkey;
 	if (alg->export)
 		crt->export = shash_async_export;
 	if (alg->import)
--- zfcpdump-kernel-4.4.orig/crypto/skcipher.c
+++ zfcpdump-kernel-4.4/crypto/skcipher.c
@@ -118,6 +118,7 @@ static int crypto_init_skcipher_ops_blkc
 	skcipher->decrypt = skcipher_decrypt_blkcipher;
 
 	skcipher->ivsize = crypto_blkcipher_ivsize(blkcipher);
+	skcipher->has_setkey = calg->cra_blkcipher.max_keysize;
 
 	return 0;
 }
@@ -210,6 +211,7 @@ static int crypto_init_skcipher_ops_ablk
 	skcipher->ivsize = crypto_ablkcipher_ivsize(ablkcipher);
 	skcipher->reqsize = crypto_ablkcipher_reqsize(ablkcipher) +
 			    sizeof(struct ablkcipher_request);
+	skcipher->has_setkey = calg->cra_ablkcipher.max_keysize;
 
 	return 0;
 }
--- zfcpdump-kernel-4.4.orig/crypto/testmgr.c
+++ zfcpdump-kernel-4.4/crypto/testmgr.c
@@ -1849,6 +1849,7 @@ static int alg_test_drbg(const struct al
 static int do_test_rsa(struct crypto_akcipher *tfm,
 		       struct akcipher_testvec *vecs)
 {
+	char *xbuf[XBUFSIZE];
 	struct akcipher_request *req;
 	void *outbuf_enc = NULL;
 	void *outbuf_dec = NULL;
@@ -1857,9 +1858,12 @@ static int do_test_rsa(struct crypto_akc
 	int err = -ENOMEM;
 	struct scatterlist src, dst, src_tab[2];
 
+	if (testmgr_alloc_buf(xbuf))
+		return err;
+
 	req = akcipher_request_alloc(tfm, GFP_KERNEL);
 	if (!req)
-		return err;
+		goto free_xbuf;
 
 	init_completion(&result.completion);
 
@@ -1877,9 +1881,14 @@ static int do_test_rsa(struct crypto_akc
 	if (!outbuf_enc)
 		goto free_req;
 
+	if (WARN_ON(vecs->m_size > PAGE_SIZE))
+		goto free_all;
+
+	memcpy(xbuf[0], vecs->m, vecs->m_size);
+
 	sg_init_table(src_tab, 2);
-	sg_set_buf(&src_tab[0], vecs->m, 8);
-	sg_set_buf(&src_tab[1], vecs->m + 8, vecs->m_size - 8);
+	sg_set_buf(&src_tab[0], xbuf[0], 8);
+	sg_set_buf(&src_tab[1], xbuf[0] + 8, vecs->m_size - 8);
 	sg_init_one(&dst, outbuf_enc, out_len_max);
 	akcipher_request_set_crypt(req, src_tab, &dst, vecs->m_size,
 				   out_len_max);
@@ -1898,7 +1907,7 @@ static int do_test_rsa(struct crypto_akc
 		goto free_all;
 	}
 	/* verify that encrypted message is equal to expected */
-	if (memcmp(vecs->c, sg_virt(req->dst), vecs->c_size)) {
+	if (memcmp(vecs->c, outbuf_enc, vecs->c_size)) {
 		pr_err("alg: rsa: encrypt test failed. Invalid output\n");
 		err = -EINVAL;
 		goto free_all;
@@ -1913,7 +1922,13 @@ static int do_test_rsa(struct crypto_akc
 		err = -ENOMEM;
 		goto free_all;
 	}
-	sg_init_one(&src, vecs->c, vecs->c_size);
+
+	if (WARN_ON(vecs->c_size > PAGE_SIZE))
+		goto free_all;
+
+	memcpy(xbuf[0], vecs->c, vecs->c_size);
+
+	sg_init_one(&src, xbuf[0], vecs->c_size);
 	sg_init_one(&dst, outbuf_dec, out_len_max);
 	init_completion(&result.completion);
 	akcipher_request_set_crypt(req, &src, &dst, vecs->c_size, out_len_max);
@@ -1940,6 +1955,8 @@ free_all:
 	kfree(outbuf_enc);
 free_req:
 	akcipher_request_free(req);
+free_xbuf:
+	testmgr_free_buf(xbuf);
 	return err;
 }
 
--- zfcpdump-kernel-4.4.orig/crypto/xts.c
+++ zfcpdump-kernel-4.4/crypto/xts.c
@@ -35,16 +35,11 @@ static int setkey(struct crypto_tfm *par
 {
 	struct priv *ctx = crypto_tfm_ctx(parent);
 	struct crypto_cipher *child = ctx->tweak;
-	u32 *flags = &parent->crt_flags;
 	int err;
 
-	/* key consists of keys of equal size concatenated, therefore
-	 * the length must be even */
-	if (keylen % 2) {
-		/* tell the user why there was an error */
-		*flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
-		return -EINVAL;
-	}
+	err = xts_check_key(parent, key, keylen);
+	if (err)
+		return err;
 
 	/* we need two cipher instances: one to compute the initial 'tweak'
 	 * by encrypting the IV (usually the 'plain' iv) and the other
--- zfcpdump-kernel-4.4.orig/drivers/acpi/acpi_lpss.c
+++ zfcpdump-kernel-4.4/drivers/acpi/acpi_lpss.c
@@ -15,6 +15,7 @@
 #include <linux/clk-provider.h>
 #include <linux/err.h>
 #include <linux/io.h>
+#include <linux/mutex.h>
 #include <linux/platform_device.h>
 #include <linux/platform_data/clk-lpss.h>
 #include <linux/pm_runtime.h>
@@ -26,6 +27,10 @@ ACPI_MODULE_NAME("acpi_lpss");
 
 #ifdef CONFIG_X86_INTEL_LPSS
 
+#include <asm/cpu_device_id.h>
+#include <asm/iosf_mbi.h>
+#include <asm/pmc_atom.h>
+
 #define LPSS_ADDR(desc) ((unsigned long)&desc)
 
 #define LPSS_CLK_SIZE	0x04
@@ -71,7 +76,7 @@ struct lpss_device_desc {
 	void (*setup)(struct lpss_private_data *pdata);
 };
 
-static struct lpss_device_desc lpss_dma_desc = {
+static const struct lpss_device_desc lpss_dma_desc = {
 	.flags = LPSS_CLK,
 };
 
@@ -84,6 +89,23 @@ struct lpss_private_data {
 	u32 prv_reg_ctx[LPSS_PRV_REG_COUNT];
 };
 
+/* LPSS run time quirks */
+static unsigned int lpss_quirks;
+
+/*
+ * LPSS_QUIRK_ALWAYS_POWER_ON: override power state for LPSS DMA device.
+ *
+ * The LPSS DMA controller does not have neither _PS0 nor _PS3 method. Moreover
+ * it can be powered off automatically whenever the last LPSS device goes down.
+ * In case of no power any access to the DMA controller will hang the system.
+ * The behaviour is reproduced on some HP laptops based on Intel BayTrail as
+ * well as on ASuS T100TA transformer.
+ *
+ * This quirk overrides power state of entire LPSS island to keep DMA powered
+ * on whenever we have at least one other device in use.
+ */
+#define LPSS_QUIRK_ALWAYS_POWER_ON	BIT(0)
+
 /* UART Component Parameter Register */
 #define LPSS_UART_CPR			0xF4
 #define LPSS_UART_CPR_AFCE		BIT(4)
@@ -196,13 +218,21 @@ static const struct lpss_device_desc bsw
 	.setup = byt_i2c_setup,
 };
 
-static struct lpss_device_desc bsw_spi_dev_desc = {
+static const struct lpss_device_desc bsw_spi_dev_desc = {
 	.flags = LPSS_CLK | LPSS_CLK_GATE | LPSS_CLK_DIVIDER | LPSS_SAVE_CTX
 			| LPSS_NO_D3_DELAY,
 	.prv_offset = 0x400,
 	.setup = lpss_deassert_reset,
 };
 
+#define ICPU(model)	{ X86_VENDOR_INTEL, 6, model, X86_FEATURE_ANY, }
+
+static const struct x86_cpu_id lpss_cpu_ids[] = {
+	ICPU(0x37),	/* Valleyview, Bay Trail */
+	ICPU(0x4c),	/* Braswell, Cherry Trail */
+	{}
+};
+
 #else
 
 #define LPSS_ADDR(desc) (0UL)
@@ -628,6 +658,89 @@ static int acpi_lpss_resume_early(struct
 }
 #endif /* CONFIG_PM_SLEEP */
 
+/* IOSF SB for LPSS island */
+#define LPSS_IOSF_UNIT_LPIOEP		0xA0
+#define LPSS_IOSF_UNIT_LPIO1		0xAB
+#define LPSS_IOSF_UNIT_LPIO2		0xAC
+
+#define LPSS_IOSF_PMCSR			0x84
+#define LPSS_PMCSR_D0			0
+#define LPSS_PMCSR_D3hot		3
+#define LPSS_PMCSR_Dx_MASK		GENMASK(1, 0)
+
+#define LPSS_IOSF_GPIODEF0		0x154
+#define LPSS_GPIODEF0_DMA1_D3		BIT(2)
+#define LPSS_GPIODEF0_DMA2_D3		BIT(3)
+#define LPSS_GPIODEF0_DMA_D3_MASK	GENMASK(3, 2)
+
+static DEFINE_MUTEX(lpss_iosf_mutex);
+
+static void lpss_iosf_enter_d3_state(void)
+{
+	u32 value1 = 0;
+	u32 mask1 = LPSS_GPIODEF0_DMA_D3_MASK;
+	u32 value2 = LPSS_PMCSR_D3hot;
+	u32 mask2 = LPSS_PMCSR_Dx_MASK;
+	/*
+	 * PMC provides an information about actual status of the LPSS devices.
+	 * Here we read the values related to LPSS power island, i.e. LPSS
+	 * devices, excluding both LPSS DMA controllers, along with SCC domain.
+	 */
+	u32 func_dis, d3_sts_0, pmc_status, pmc_mask = 0xfe000ffe;
+	int ret;
+
+	ret = pmc_atom_read(PMC_FUNC_DIS, &func_dis);
+	if (ret)
+		return;
+
+	mutex_lock(&lpss_iosf_mutex);
+
+	ret = pmc_atom_read(PMC_D3_STS_0, &d3_sts_0);
+	if (ret)
+		goto exit;
+
+	/*
+	 * Get the status of entire LPSS power island per device basis.
+	 * Shutdown both LPSS DMA controllers if and only if all other devices
+	 * are already in D3hot.
+	 */
+	pmc_status = (~(d3_sts_0 | func_dis)) & pmc_mask;
+	if (pmc_status)
+		goto exit;
+
+	iosf_mbi_modify(LPSS_IOSF_UNIT_LPIO1, MBI_CFG_WRITE,
+			LPSS_IOSF_PMCSR, value2, mask2);
+
+	iosf_mbi_modify(LPSS_IOSF_UNIT_LPIO2, MBI_CFG_WRITE,
+			LPSS_IOSF_PMCSR, value2, mask2);
+
+	iosf_mbi_modify(LPSS_IOSF_UNIT_LPIOEP, MBI_CR_WRITE,
+			LPSS_IOSF_GPIODEF0, value1, mask1);
+exit:
+	mutex_unlock(&lpss_iosf_mutex);
+}
+
+static void lpss_iosf_exit_d3_state(void)
+{
+	u32 value1 = LPSS_GPIODEF0_DMA1_D3 | LPSS_GPIODEF0_DMA2_D3;
+	u32 mask1 = LPSS_GPIODEF0_DMA_D3_MASK;
+	u32 value2 = LPSS_PMCSR_D0;
+	u32 mask2 = LPSS_PMCSR_Dx_MASK;
+
+	mutex_lock(&lpss_iosf_mutex);
+
+	iosf_mbi_modify(LPSS_IOSF_UNIT_LPIOEP, MBI_CR_WRITE,
+			LPSS_IOSF_GPIODEF0, value1, mask1);
+
+	iosf_mbi_modify(LPSS_IOSF_UNIT_LPIO2, MBI_CFG_WRITE,
+			LPSS_IOSF_PMCSR, value2, mask2);
+
+	iosf_mbi_modify(LPSS_IOSF_UNIT_LPIO1, MBI_CFG_WRITE,
+			LPSS_IOSF_PMCSR, value2, mask2);
+
+	mutex_unlock(&lpss_iosf_mutex);
+}
+
 static int acpi_lpss_runtime_suspend(struct device *dev)
 {
 	struct lpss_private_data *pdata = acpi_driver_data(ACPI_COMPANION(dev));
@@ -640,7 +753,17 @@ static int acpi_lpss_runtime_suspend(str
 	if (pdata->dev_desc->flags & LPSS_SAVE_CTX)
 		acpi_lpss_save_ctx(dev, pdata);
 
-	return acpi_dev_runtime_suspend(dev);
+	ret = acpi_dev_runtime_suspend(dev);
+
+	/*
+	 * This call must be last in the sequence, otherwise PMC will return
+	 * wrong status for devices being about to be powered off. See
+	 * lpss_iosf_enter_d3_state() for further information.
+	 */
+	if (lpss_quirks & LPSS_QUIRK_ALWAYS_POWER_ON && iosf_mbi_available())
+		lpss_iosf_enter_d3_state();
+
+	return ret;
 }
 
 static int acpi_lpss_runtime_resume(struct device *dev)
@@ -648,6 +771,13 @@ static int acpi_lpss_runtime_resume(stru
 	struct lpss_private_data *pdata = acpi_driver_data(ACPI_COMPANION(dev));
 	int ret;
 
+	/*
+	 * This call is kept first to be in symmetry with
+	 * acpi_lpss_runtime_suspend() one.
+	 */
+	if (lpss_quirks & LPSS_QUIRK_ALWAYS_POWER_ON && iosf_mbi_available())
+		lpss_iosf_exit_d3_state();
+
 	ret = acpi_dev_runtime_resume(dev);
 	if (ret)
 		return ret;
@@ -754,10 +884,19 @@ static struct acpi_scan_handler lpss_han
 
 void __init acpi_lpss_init(void)
 {
-	if (!lpt_clk_init()) {
-		bus_register_notifier(&platform_bus_type, &acpi_lpss_nb);
-		acpi_scan_add_handler(&lpss_handler);
-	}
+	const struct x86_cpu_id *id;
+	int ret;
+
+	ret = lpt_clk_init();
+	if (ret)
+		return;
+
+	id = x86_match_cpu(lpss_cpu_ids);
+	if (id)
+		lpss_quirks |= LPSS_QUIRK_ALWAYS_POWER_ON;
+
+	bus_register_notifier(&platform_bus_type, &acpi_lpss_nb);
+	acpi_scan_add_handler(&lpss_handler);
 }
 
 #else
--- zfcpdump-kernel-4.4.orig/drivers/acpi/acpi_processor.c
+++ zfcpdump-kernel-4.4/drivers/acpi/acpi_processor.c
@@ -491,6 +491,58 @@ static void acpi_processor_remove(struct
 }
 #endif /* CONFIG_ACPI_HOTPLUG_CPU */
 
+#ifdef CONFIG_X86
+static bool acpi_hwp_native_thermal_lvt_set;
+static acpi_status __init acpi_hwp_native_thermal_lvt_osc(acpi_handle handle,
+							  u32 lvl,
+							  void *context,
+							  void **rv)
+{
+	u8 sb_uuid_str[] = "4077A616-290C-47BE-9EBD-D87058713953";
+	u32 capbuf[2];
+	struct acpi_osc_context osc_context = {
+		.uuid_str = sb_uuid_str,
+		.rev = 1,
+		.cap.length = 8,
+		.cap.pointer = capbuf,
+	};
+
+	if (acpi_hwp_native_thermal_lvt_set)
+		return AE_CTRL_TERMINATE;
+
+	capbuf[0] = 0x0000;
+	capbuf[1] = 0x1000; /* set bit 12 */
+
+	if (ACPI_SUCCESS(acpi_run_osc(handle, &osc_context))) {
+		if (osc_context.ret.pointer && osc_context.ret.length > 1) {
+			u32 *capbuf_ret = osc_context.ret.pointer;
+
+			if (capbuf_ret[1] & 0x1000) {
+				acpi_handle_info(handle,
+					"_OSC native thermal LVT Acked\n");
+				acpi_hwp_native_thermal_lvt_set = true;
+			}
+		}
+		kfree(osc_context.ret.pointer);
+	}
+
+	return AE_OK;
+}
+
+void __init acpi_early_processor_osc(void)
+{
+	if (boot_cpu_has(X86_FEATURE_HWP)) {
+		acpi_walk_namespace(ACPI_TYPE_PROCESSOR, ACPI_ROOT_OBJECT,
+				    ACPI_UINT32_MAX,
+				    acpi_hwp_native_thermal_lvt_osc,
+				    NULL, NULL, NULL);
+		acpi_get_devices(ACPI_PROCESSOR_DEVICE_HID,
+				 acpi_hwp_native_thermal_lvt_osc,
+				 NULL, NULL);
+	}
+}
+#endif
+
 /*
  * The following ACPI IDs are known to be suitable for representing as
  * processor devices.
--- zfcpdump-kernel-4.4.orig/drivers/acpi/acpi_video.c
+++ zfcpdump-kernel-4.4/drivers/acpi/acpi_video.c
@@ -465,6 +465,15 @@ static struct dmi_system_id video_dmi_ta
 	 * as brightness control does not work.
 	 */
 	{
+	 /* https://bugzilla.kernel.org/show_bug.cgi?id=21012 */
+	 .callback = video_disable_backlight_sysfs_if,
+	 .ident = "Toshiba Portege R700",
+	 .matches = {
+		DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
+		DMI_MATCH(DMI_PRODUCT_NAME, "PORTEGE R700"),
+		},
+	},
+	{
 	 /* https://bugs.freedesktop.org/show_bug.cgi?id=82634 */
 	 .callback = video_disable_backlight_sysfs_if,
 	 .ident = "Toshiba Portege R830",
@@ -473,6 +482,15 @@ static struct dmi_system_id video_dmi_ta
 		DMI_MATCH(DMI_PRODUCT_NAME, "PORTEGE R830"),
 		},
 	},
+	{
+	 /* https://bugzilla.kernel.org/show_bug.cgi?id=21012 */
+	 .callback = video_disable_backlight_sysfs_if,
+	 .ident = "Toshiba Satellite R830",
+	 .matches = {
+		DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
+		DMI_MATCH(DMI_PRODUCT_NAME, "SATELLITE R830"),
+		},
+	},
 	/*
 	 * Some machine's _DOD IDs don't have bit 31(Device ID Scheme) set
 	 * but the IDs actually follow the Device ID Scheme.
--- zfcpdump-kernel-4.4.orig/drivers/acpi/acpica/dsmethod.c
+++ zfcpdump-kernel-4.4/drivers/acpi/acpica/dsmethod.c
@@ -417,6 +417,9 @@ acpi_ds_begin_method_execution(struct ac
 				obj_desc->method.mutex->mutex.
 				    original_sync_level =
 				    obj_desc->method.mutex->mutex.sync_level;
+
+				obj_desc->method.mutex->mutex.thread_id =
+				    acpi_os_get_thread_id();
 			}
 		}
 
--- zfcpdump-kernel-4.4.orig/drivers/acpi/acpica/hwxface.c
+++ zfcpdump-kernel-4.4/drivers/acpi/acpica/hwxface.c
@@ -504,11 +504,20 @@ acpi_get_sleep_type_data(u8 sleep_state,
 	 * Evaluate the \_Sx namespace object containing the register values
 	 * for this state
 	 */
-	info->relative_pathname =
-	    ACPI_CAST_PTR(char, acpi_gbl_sleep_state_names[sleep_state]);
+	info->relative_pathname = ACPI_CAST_PTR(char,
+						acpi_gbl_sleep_state_names
+						[sleep_state]);
+
 	status = acpi_ns_evaluate(info);
 	if (ACPI_FAILURE(status)) {
-		goto cleanup;
+		if (status == AE_NOT_FOUND) {
+
+			/* The _Sx states are optional, ignore NOT_FOUND */
+
+			goto final_cleanup;
+		}
+
+		goto warning_cleanup;
 	}
 
 	/* Must have a return object */
@@ -517,7 +526,7 @@ acpi_get_sleep_type_data(u8 sleep_state,
 		ACPI_ERROR((AE_INFO, "No Sleep State object returned from [%s]",
 			    info->relative_pathname));
 		status = AE_AML_NO_RETURN_VALUE;
-		goto cleanup;
+		goto warning_cleanup;
 	}
 
 	/* Return object must be of type Package */
@@ -526,7 +535,7 @@ acpi_get_sleep_type_data(u8 sleep_state,
 		ACPI_ERROR((AE_INFO,
 			    "Sleep State return object is not a Package"));
 		status = AE_AML_OPERAND_TYPE;
-		goto cleanup1;
+		goto return_value_cleanup;
 	}
 
 	/*
@@ -570,16 +579,17 @@ acpi_get_sleep_type_data(u8 sleep_state,
 		break;
 	}
 
-cleanup1:
+return_value_cleanup:
 	acpi_ut_remove_reference(info->return_object);
 
-cleanup:
+warning_cleanup:
 	if (ACPI_FAILURE(status)) {
 		ACPI_EXCEPTION((AE_INFO, status,
 				"While evaluating Sleep State [%s]",
 				info->relative_pathname));
 	}
 
+final_cleanup:
 	ACPI_FREE(info);
 	return_ACPI_STATUS(status);
 }
--- zfcpdump-kernel-4.4.orig/drivers/acpi/blacklist.c
+++ zfcpdump-kernel-4.4/drivers/acpi/blacklist.c
@@ -313,6 +313,77 @@ static struct dmi_system_id acpi_osi_dmi
 	},
 
 	/*
+	 * The following Lenovo models have a broken workaround in the
+	 * acpi_video backlight implementation to meet the Windows 8
+	 * requirement of 101 backlight levels. Reverting to pre-Win8
+	 * behavior fixes the problem.
+	 */
+	{
+	.callback = dmi_disable_osi_win8,
+	.ident = "Lenovo ThinkPad L430",
+	.matches = {
+		     DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+		     DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad L430"),
+		},
+	},
+	{
+	.callback = dmi_disable_osi_win8,
+	.ident = "Lenovo ThinkPad T430",
+	.matches = {
+		     DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+		     DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T430"),
+		},
+	},
+	{
+	.callback = dmi_disable_osi_win8,
+	.ident = "Lenovo ThinkPad T430s",
+	.matches = {
+		     DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+		     DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T430s"),
+		},
+	},
+	{
+	.callback = dmi_disable_osi_win8,
+	.ident = "Lenovo ThinkPad T530",
+	.matches = {
+		     DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+		     DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T530"),
+		},
+	},
+	{
+	.callback = dmi_disable_osi_win8,
+	.ident = "Lenovo ThinkPad W530",
+	.matches = {
+		     DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+		     DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad W530"),
+		},
+	},
+	{
+	.callback = dmi_disable_osi_win8,
+	.ident = "Lenovo ThinkPad X1 Carbon",
+	.matches = {
+		     DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+		     DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad X1 Carbon"),
+		},
+	},
+	{
+	.callback = dmi_disable_osi_win8,
+	.ident = "Lenovo ThinkPad X230",
+	.matches = {
+		     DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+		     DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad X230"),
+		},
+	},
+	{
+	.callback = dmi_disable_osi_win8,
+	.ident = "Lenovo ThinkPad Edge E330",
+	.matches = {
+		     DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+		     DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad Edge E330"),
+		},
+	},
+
+	/*
 	 * BIOS invocation of _OSI(Linux) is almost always a BIOS bug.
 	 * Linux ignores it, except for the machines enumerated below.
 	 */
--- zfcpdump-kernel-4.4.orig/drivers/acpi/bus.c
+++ zfcpdump-kernel-4.4/drivers/acpi/bus.c
@@ -1004,6 +1004,9 @@ static int __init acpi_bus_init(void)
 		goto error1;
 	}
 
+	/* Set capability bits for _OSC under processor scope */
+	acpi_early_processor_osc();
+
 	/*
 	 * _OSC method may exist in module level code,
 	 * so it must be run after ACPI_FULL_INITIALIZATION
--- zfcpdump-kernel-4.4.orig/drivers/acpi/cppc_acpi.c
+++ zfcpdump-kernel-4.4/drivers/acpi/cppc_acpi.c
@@ -216,8 +216,10 @@ int acpi_get_psd_map(struct cpudata **al
 			continue;
 
 		cpc_ptr = per_cpu(cpc_desc_ptr, i);
-		if (!cpc_ptr)
-			continue;
+		if (!cpc_ptr) {
+			retval = -EFAULT;
+			goto err_ret;
+		}
 
 		pdomain = &(cpc_ptr->domain_info);
 		cpumask_set_cpu(i, pr->shared_cpu_map);
@@ -239,8 +241,10 @@ int acpi_get_psd_map(struct cpudata **al
 				continue;
 
 			match_cpc_ptr = per_cpu(cpc_desc_ptr, j);
-			if (!match_cpc_ptr)
-				continue;
+			if (!match_cpc_ptr) {
+				retval = -EFAULT;
+				goto err_ret;
+			}
 
 			match_pdomain = &(match_cpc_ptr->domain_info);
 			if (match_pdomain->domain != pdomain->domain)
@@ -270,8 +274,10 @@ int acpi_get_psd_map(struct cpudata **al
 				continue;
 
 			match_cpc_ptr = per_cpu(cpc_desc_ptr, j);
-			if (!match_cpc_ptr)
-				continue;
+			if (!match_cpc_ptr) {
+				retval = -EFAULT;
+				goto err_ret;
+			}
 
 			match_pdomain = &(match_cpc_ptr->domain_info);
 			if (match_pdomain->domain != pdomain->domain)
@@ -502,9 +508,6 @@ int acpi_cppc_processor_probe(struct acp
 	/* Store CPU Logical ID */
 	cpc_ptr->cpu_id = pr->id;
 
-	/* Plug it into this CPUs CPC descriptor. */
-	per_cpu(cpc_desc_ptr, pr->id) = cpc_ptr;
-
 	/* Parse PSD data for this CPU */
 	ret = acpi_get_psd(cpc_ptr, handle);
 	if (ret)
@@ -517,6 +520,9 @@ int acpi_cppc_processor_probe(struct acp
 			goto out_free;
 	}
 
+	/* Plug PSD data into this CPUs CPC descriptor. */
+	per_cpu(cpc_desc_ptr, pr->id) = cpc_ptr;
+
 	/* Everything looks okay */
 	pr_debug("Parsed CPC struct for CPU: %d\n", pr->id);
 
--- zfcpdump-kernel-4.4.orig/drivers/acpi/custom_method.c
+++ zfcpdump-kernel-4.4/drivers/acpi/custom_method.c
@@ -29,6 +29,9 @@ static ssize_t cm_write(struct file *fil
 	struct acpi_table_header table;
 	acpi_status status;
 
+	if (secure_modules())
+		return -EPERM;
+
 	if (!(*ppos)) {
 		/* parse the table header to get the table length */
 		if (count <= sizeof(struct acpi_table_header))
--- zfcpdump-kernel-4.4.orig/drivers/acpi/ec.c
+++ zfcpdump-kernel-4.4/drivers/acpi/ec.c
@@ -101,6 +101,7 @@ enum ec_command {
 #define ACPI_EC_UDELAY_POLL	550	/* Wait 1ms for EC transaction polling */
 #define ACPI_EC_CLEAR_MAX	100	/* Maximum number of events to query
 					 * when trying to clear the EC */
+#define ACPI_EC_MAX_QUERIES	16	/* Maximum number of parallel queries */
 
 enum {
 	EC_FLAGS_QUERY_PENDING,		/* Query is pending */
@@ -121,6 +122,10 @@ static unsigned int ec_delay __read_most
 module_param(ec_delay, uint, 0644);
 MODULE_PARM_DESC(ec_delay, "Timeout(ms) waited until an EC command completes");
 
+static unsigned int ec_max_queries __read_mostly = ACPI_EC_MAX_QUERIES;
+module_param(ec_max_queries, uint, 0644);
+MODULE_PARM_DESC(ec_max_queries, "Maximum parallel _Qxx evaluations");
+
 static bool ec_busy_polling __read_mostly;
 module_param(ec_busy_polling, bool, 0644);
 MODULE_PARM_DESC(ec_busy_polling, "Use busy polling to advance EC transaction");
@@ -174,6 +179,7 @@ static void acpi_ec_event_processor(stru
 
 struct acpi_ec *boot_ec, *first_ec;
 EXPORT_SYMBOL(first_ec);
+static struct workqueue_struct *ec_query_wq;
 
 static int EC_FLAGS_VALIDATE_ECDT; /* ASUStec ECDTs need to be validated */
 static int EC_FLAGS_SKIP_DSDT_SCAN; /* Not all BIOS survive early DSDT scan */
@@ -1097,7 +1103,7 @@ static int acpi_ec_query(struct acpi_ec
 	 * work queue execution.
 	 */
 	ec_dbg_evt("Query(0x%02x) scheduled", value);
-	if (!schedule_work(&q->work)) {
+	if (!queue_work(ec_query_wq, &q->work)) {
 		ec_dbg_evt("Query(0x%02x) overlapped", value);
 		result = -EBUSY;
 	}
@@ -1657,15 +1663,41 @@ static struct acpi_driver acpi_ec_driver
 		},
 };
 
+static inline int acpi_ec_query_init(void)
+{
+	if (!ec_query_wq) {
+		ec_query_wq = alloc_workqueue("kec_query", 0,
+					      ec_max_queries);
+		if (!ec_query_wq)
+			return -ENODEV;
+	}
+	return 0;
+}
+
+static inline void acpi_ec_query_exit(void)
+{
+	if (ec_query_wq) {
+		destroy_workqueue(ec_query_wq);
+		ec_query_wq = NULL;
+	}
+}
+
 int __init acpi_ec_init(void)
 {
-	int result = 0;
+	int result;
 
+	/* register workqueue for _Qxx evaluations */
+	result = acpi_ec_query_init();
+	if (result)
+		goto err_exit;
 	/* Now register the driver for the EC */
 	result = acpi_bus_register_driver(&acpi_ec_driver);
-	if (result < 0)
-		return -ENODEV;
+	if (result)
+		goto err_exit;
 
+err_exit:
+	if (result)
+		acpi_ec_query_exit();
 	return result;
 }
 
@@ -1675,5 +1707,6 @@ static void __exit acpi_ec_exit(void)
 {
 
 	acpi_bus_unregister_driver(&acpi_ec_driver);
+	acpi_ec_query_exit();
 }
 #endif	/* 0 */
--- zfcpdump-kernel-4.4.orig/drivers/acpi/internal.h
+++ zfcpdump-kernel-4.4/drivers/acpi/internal.h
@@ -130,6 +130,12 @@ void acpi_early_processor_set_pdc(void);
 static inline void acpi_early_processor_set_pdc(void) {}
 #endif
 
+#ifdef CONFIG_X86
+void acpi_early_processor_osc(void);
+#else
+static inline void acpi_early_processor_osc(void) {}
+#endif
+
 /* --------------------------------------------------------------------------
                                   Embedded Controller
    -------------------------------------------------------------------------- */
--- zfcpdump-kernel-4.4.orig/drivers/acpi/nfit.c
+++ zfcpdump-kernel-4.4/drivers/acpi/nfit.c
@@ -468,37 +468,16 @@ static void nfit_mem_find_spa_bdw(struct
 	nfit_mem->bdw = NULL;
 }
 
-static int nfit_mem_add(struct acpi_nfit_desc *acpi_desc,
+static void nfit_mem_init_bdw(struct acpi_nfit_desc *acpi_desc,
 		struct nfit_mem *nfit_mem, struct acpi_nfit_system_address *spa)
 {
 	u16 dcr = __to_nfit_memdev(nfit_mem)->region_index;
 	struct nfit_memdev *nfit_memdev;
 	struct nfit_flush *nfit_flush;
-	struct nfit_dcr *nfit_dcr;
 	struct nfit_bdw *nfit_bdw;
 	struct nfit_idt *nfit_idt;
 	u16 idt_idx, range_index;
 
-	list_for_each_entry(nfit_dcr, &acpi_desc->dcrs, list) {
-		if (nfit_dcr->dcr->region_index != dcr)
-			continue;
-		nfit_mem->dcr = nfit_dcr->dcr;
-		break;
-	}
-
-	if (!nfit_mem->dcr) {
-		dev_dbg(acpi_desc->dev, "SPA %d missing:%s%s\n",
-				spa->range_index, __to_nfit_memdev(nfit_mem)
-				? "" : " MEMDEV", nfit_mem->dcr ? "" : " DCR");
-		return -ENODEV;
-	}
-
-	/*
-	 * We've found enough to create an nvdimm, optionally
-	 * find an associated BDW
-	 */
-	list_add(&nfit_mem->list, &acpi_desc->dimms);
-
 	list_for_each_entry(nfit_bdw, &acpi_desc->bdws, list) {
 		if (nfit_bdw->bdw->region_index != dcr)
 			continue;
@@ -507,12 +486,12 @@ static int nfit_mem_add(struct acpi_nfit
 	}
 
 	if (!nfit_mem->bdw)
-		return 0;
+		return;
 
 	nfit_mem_find_spa_bdw(acpi_desc, nfit_mem);
 
 	if (!nfit_mem->spa_bdw)
-		return 0;
+		return;
 
 	range_index = nfit_mem->spa_bdw->range_index;
 	list_for_each_entry(nfit_memdev, &acpi_desc->memdevs, list) {
@@ -537,8 +516,6 @@ static int nfit_mem_add(struct acpi_nfit
 		}
 		break;
 	}
-
-	return 0;
 }
 
 static int nfit_mem_dcr_init(struct acpi_nfit_desc *acpi_desc,
@@ -547,7 +524,6 @@ static int nfit_mem_dcr_init(struct acpi
 	struct nfit_mem *nfit_mem, *found;
 	struct nfit_memdev *nfit_memdev;
 	int type = nfit_spa_type(spa);
-	u16 dcr;
 
 	switch (type) {
 	case NFIT_SPA_DCR:
@@ -558,14 +534,18 @@ static int nfit_mem_dcr_init(struct acpi
 	}
 
 	list_for_each_entry(nfit_memdev, &acpi_desc->memdevs, list) {
-		int rc;
+		struct nfit_dcr *nfit_dcr;
+		u32 device_handle;
+		u16 dcr;
 
 		if (nfit_memdev->memdev->range_index != spa->range_index)
 			continue;
 		found = NULL;
 		dcr = nfit_memdev->memdev->region_index;
+		device_handle = nfit_memdev->memdev->device_handle;
 		list_for_each_entry(nfit_mem, &acpi_desc->dimms, list)
-			if (__to_nfit_memdev(nfit_mem)->region_index == dcr) {
+			if (__to_nfit_memdev(nfit_mem)->device_handle
+					== device_handle) {
 				found = nfit_mem;
 				break;
 			}
@@ -578,6 +558,31 @@ static int nfit_mem_dcr_init(struct acpi
 			if (!nfit_mem)
 				return -ENOMEM;
 			INIT_LIST_HEAD(&nfit_mem->list);
+			list_add(&nfit_mem->list, &acpi_desc->dimms);
+		}
+
+		list_for_each_entry(nfit_dcr, &acpi_desc->dcrs, list) {
+			if (nfit_dcr->dcr->region_index != dcr)
+				continue;
+			/*
+			 * Record the control region for the dimm.  For
+			 * the ACPI 6.1 case, where there are separate
+			 * control regions for the pmem vs blk
+			 * interfaces, be sure to record the extended
+			 * blk details.
+			 */
+			if (!nfit_mem->dcr)
+				nfit_mem->dcr = nfit_dcr->dcr;
+			else if (nfit_mem->dcr->windows == 0
+					&& nfit_dcr->dcr->windows)
+				nfit_mem->dcr = nfit_dcr->dcr;
+			break;
+		}
+
+		if (dcr && !nfit_mem->dcr) {
+			dev_err(acpi_desc->dev, "SPA %d missing DCR %d\n",
+					spa->range_index, dcr);
+			return -ENODEV;
 		}
 
 		if (type == NFIT_SPA_DCR) {
@@ -594,6 +599,7 @@ static int nfit_mem_dcr_init(struct acpi
 				nfit_mem->idt_dcr = nfit_idt->idt;
 				break;
 			}
+			nfit_mem_init_bdw(acpi_desc, nfit_mem, spa);
 		} else {
 			/*
 			 * A single dimm may belong to multiple SPA-PM
@@ -602,13 +608,6 @@ static int nfit_mem_dcr_init(struct acpi
 			 */
 			nfit_mem->memdev_pmem = nfit_memdev->memdev;
 		}
-
-		if (found)
-			continue;
-
-		rc = nfit_mem_add(acpi_desc, nfit_mem, spa);
-		if (rc)
-			return rc;
 	}
 
 	return 0;
@@ -1073,11 +1072,12 @@ static u32 read_blk_stat(struct nfit_blk
 {
 	struct nfit_blk_mmio *mmio = &nfit_blk->mmio[DCR];
 	u64 offset = nfit_blk->stat_offset + mmio->size * bw;
+	const u32 STATUS_MASK = 0x80000037;
 
 	if (mmio->num_lines)
 		offset = to_interleave_offset(offset, mmio);
 
-	return readl(mmio->addr.base + offset);
+	return readl(mmio->addr.base + offset) & STATUS_MASK;
 }
 
 static void write_blk_ctl(struct nfit_blk *nfit_blk, unsigned int bw,
--- zfcpdump-kernel-4.4.orig/drivers/acpi/numa.c
+++ zfcpdump-kernel-4.4/drivers/acpi/numa.c
@@ -327,10 +327,18 @@ int __init acpi_numa_init(void)
 
 	/* SRAT: Static Resource Affinity Table */
 	if (!acpi_table_parse(ACPI_SIG_SRAT, acpi_parse_srat)) {
-		acpi_table_parse_srat(ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY,
-				     acpi_parse_x2apic_affinity, 0);
-		acpi_table_parse_srat(ACPI_SRAT_TYPE_CPU_AFFINITY,
-				     acpi_parse_processor_affinity, 0);
+		struct acpi_subtable_proc srat_proc[2];
+
+		memset(srat_proc, 0, sizeof(srat_proc));
+		srat_proc[0].id = ACPI_SRAT_TYPE_CPU_AFFINITY;
+		srat_proc[0].handler = acpi_parse_processor_affinity;
+		srat_proc[1].id = ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY;
+		srat_proc[1].handler = acpi_parse_x2apic_affinity;
+
+		acpi_table_parse_entries_array(ACPI_SIG_SRAT,
+					sizeof(struct acpi_table_srat),
+					srat_proc, ARRAY_SIZE(srat_proc), 0);
+
 		cnt = acpi_table_parse_srat(ACPI_SRAT_TYPE_MEMORY_AFFINITY,
 					    acpi_parse_memory_affinity,
 					    NR_NODE_MEMBLKS);
--- zfcpdump-kernel-4.4.orig/drivers/acpi/osl.c
+++ zfcpdump-kernel-4.4/drivers/acpi/osl.c
@@ -40,6 +40,7 @@
 #include <linux/list.h>
 #include <linux/jiffies.h>
 #include <linux/semaphore.h>
+#include <linux/module.h>
 
 #include <asm/io.h>
 #include <asm/uaccess.h>
@@ -135,7 +136,7 @@ static struct osi_linux {
 	unsigned int	enable:1;
 	unsigned int	dmi:1;
 	unsigned int	cmdline:1;
-	unsigned int	default_disabling:1;
+	u8		default_disabling;
 } osi_linux = {0, 0, 0, 0};
 
 static u32 acpi_osi_handler(acpi_string interface, u32 supported)
@@ -252,7 +253,7 @@ early_param("acpi_rsdp", setup_acpi_rsdp
 acpi_physical_address __init acpi_os_get_root_pointer(void)
 {
 #ifdef CONFIG_KEXEC
-	if (acpi_rsdp)
+	if (acpi_rsdp && !secure_modules())
 		return acpi_rsdp;
 #endif
 
@@ -1444,10 +1445,13 @@ void __init acpi_osi_setup(char *str)
 	if (*str == '!') {
 		str++;
 		if (*str == '\0') {
-			osi_linux.default_disabling = 1;
+			/* Do not override acpi_osi=!* */
+			if (!osi_linux.default_disabling)
+				osi_linux.default_disabling =
+					ACPI_DISABLE_ALL_VENDOR_STRINGS;
 			return;
 		} else if (*str == '*') {
-			acpi_update_interfaces(ACPI_DISABLE_ALL_STRINGS);
+			osi_linux.default_disabling = ACPI_DISABLE_ALL_STRINGS;
 			for (i = 0; i < OSI_STRING_ENTRIES_MAX; i++) {
 				osi = &osi_setup_entries[i];
 				osi->enable = false;
@@ -1520,10 +1524,13 @@ static void __init acpi_osi_setup_late(v
 	acpi_status status;
 
 	if (osi_linux.default_disabling) {
-		status = acpi_update_interfaces(ACPI_DISABLE_ALL_VENDOR_STRINGS);
+		status = acpi_update_interfaces(osi_linux.default_disabling);
 
 		if (ACPI_SUCCESS(status))
-			printk(KERN_INFO PREFIX "Disabled all _OSI OS vendors\n");
+			printk(KERN_INFO PREFIX "Disabled all _OSI OS vendors%s\n",
+				osi_linux.default_disabling ==
+				ACPI_DISABLE_ALL_STRINGS ?
+				" and feature groups" : "");
 	}
 
 	for (i = 0; i < OSI_STRING_ENTRIES_MAX; i++) {
--- zfcpdump-kernel-4.4.orig/drivers/acpi/pci_irq.c
+++ zfcpdump-kernel-4.4/drivers/acpi/pci_irq.c
@@ -409,7 +409,7 @@ int acpi_pci_irq_enable(struct pci_dev *
 		return 0;
 	}
 
-	if (pci_has_managed_irq(dev))
+	if (dev->irq_managed && dev->irq > 0)
 		return 0;
 
 	entry = acpi_pci_irq_lookup(dev, pin);
@@ -454,7 +454,8 @@ int acpi_pci_irq_enable(struct pci_dev *
 		kfree(entry);
 		return rc;
 	}
-	pci_set_managed_irq(dev, rc);
+	dev->irq = rc;
+	dev->irq_managed = 1;
 
 	if (link)
 		snprintf(link_desc, sizeof(link_desc), " -> Link[%s]", link);
@@ -477,9 +478,17 @@ void acpi_pci_irq_disable(struct pci_dev
 	u8 pin;
 
 	pin = dev->pin;
-	if (!pin || !pci_has_managed_irq(dev))
+	if (!pin || !dev->irq_managed || dev->irq <= 0)
 		return;
 
+	/* Keep IOAPIC pin configuration when suspending */
+	if (dev->dev.power.is_prepared)
+		return;
+#ifdef	CONFIG_PM
+	if (dev->dev.power.runtime_status == RPM_SUSPENDING)
+		return;
+#endif
+
 	entry = acpi_pci_irq_lookup(dev, pin);
 	if (!entry)
 		return;
@@ -499,6 +508,6 @@ void acpi_pci_irq_disable(struct pci_dev
 	dev_dbg(&dev->dev, "PCI INT %c disabled\n", pin_name(pin));
 	if (gsi >= 0) {
 		acpi_unregister_gsi(gsi);
-		pci_reset_managed_irq(dev);
+		dev->irq_managed = 0;
 	}
 }
--- zfcpdump-kernel-4.4.orig/drivers/acpi/property.c
+++ zfcpdump-kernel-4.4/drivers/acpi/property.c
@@ -346,7 +346,7 @@ void acpi_free_properties(struct acpi_de
  *
  * Return: %0 if property with @name has been found (success),
  *         %-EINVAL if the arguments are invalid,
- *         %-ENODATA if the property doesn't exist,
+ *         %-EINVAL if the property doesn't exist,
  *         %-EPROTO if the property value type doesn't match @type.
  */
 static int acpi_data_get_property(struct acpi_device_data *data,
@@ -360,7 +360,7 @@ static int acpi_data_get_property(struct
 		return -EINVAL;
 
 	if (!data->pointer || !data->properties)
-		return -ENODATA;
+		return -EINVAL;
 
 	properties = data->properties;
 	for (i = 0; i < properties->package.count; i++) {
@@ -375,13 +375,13 @@ static int acpi_data_get_property(struct
 		if (!strcmp(name, propname->string.pointer)) {
 			if (type != ACPI_TYPE_ANY && propvalue->type != type)
 				return -EPROTO;
-			else if (obj)
+			if (obj)
 				*obj = propvalue;
 
 			return 0;
 		}
 	}
-	return -ENODATA;
+	return -EINVAL;
 }
 
 /**
@@ -439,7 +439,7 @@ int acpi_node_prop_get(struct fwnode_han
  *
  * Return: %0 if array property (package) with @name has been found (success),
  *         %-EINVAL if the arguments are invalid,
- *         %-ENODATA if the property doesn't exist,
+ *         %-EINVAL if the property doesn't exist,
  *         %-EPROTO if the property is not a package or the type of its elements
  *           doesn't match @type.
  */
--- zfcpdump-kernel-4.4.orig/drivers/acpi/resource.c
+++ zfcpdump-kernel-4.4/drivers/acpi/resource.c
@@ -26,8 +26,20 @@
 
 #ifdef CONFIG_X86
 #define valid_IRQ(i) (((i) != 0) && ((i) != 2))
+static inline bool acpi_iospace_resource_valid(struct resource *res)
+{
+	/* On X86 IO space is limited to the [0 - 64K] IO port range */
+	return res->end < 0x10003;
+}
 #else
 #define valid_IRQ(i) (true)
+/*
+ * ACPI IO descriptors on arches other than X86 contain MMIO CPU physical
+ * addresses mapping IO space in CPU physical address space, IO space
+ * resources can be placed anywhere in the 64-bit physical address space.
+ */
+static inline bool
+acpi_iospace_resource_valid(struct resource *res) { return true; }
 #endif
 
 static bool acpi_dev_resource_len_valid(u64 start, u64 end, u64 len, bool io)
@@ -126,7 +138,7 @@ static void acpi_dev_ioresource_flags(st
 	if (!acpi_dev_resource_len_valid(res->start, res->end, len, true))
 		res->flags |= IORESOURCE_DISABLED | IORESOURCE_UNSET;
 
-	if (res->end >= 0x10003)
+	if (!acpi_iospace_resource_valid(res))
 		res->flags |= IORESOURCE_DISABLED | IORESOURCE_UNSET;
 
 	if (io_decode == ACPI_DECODE_16)
--- zfcpdump-kernel-4.4.orig/drivers/acpi/scan.c
+++ zfcpdump-kernel-4.4/drivers/acpi/scan.c
@@ -1958,7 +1958,7 @@ int __init acpi_scan_init(void)
 
 static struct acpi_probe_entry *ape;
 static int acpi_probe_count;
-static DEFINE_SPINLOCK(acpi_probe_lock);
+static DEFINE_MUTEX(acpi_probe_mutex);
 
 static int __init acpi_match_madt(struct acpi_subtable_header *header,
 				  const unsigned long end)
@@ -1977,7 +1977,7 @@ int __init __acpi_probe_device_table(str
 	if (acpi_disabled)
 		return 0;
 
-	spin_lock(&acpi_probe_lock);
+	mutex_lock(&acpi_probe_mutex);
 	for (ape = ap_head; nr; ape++, nr--) {
 		if (ACPI_COMPARE_NAME(ACPI_SIG_MADT, ape->id)) {
 			acpi_probe_count = 0;
@@ -1990,7 +1990,7 @@ int __init __acpi_probe_device_table(str
 				count++;
 		}
 	}
-	spin_unlock(&acpi_probe_lock);
+	mutex_unlock(&acpi_probe_mutex);
 
 	return count;
 }
--- zfcpdump-kernel-4.4.orig/drivers/acpi/sleep.c
+++ zfcpdump-kernel-4.4/drivers/acpi/sleep.c
@@ -714,6 +714,7 @@ static int acpi_hibernation_enter(void)
 
 static void acpi_hibernation_leave(void)
 {
+	pm_set_resume_via_firmware();
 	/*
 	 * If ACPI is not enabled by the BIOS and the boot kernel, we need to
 	 * enable it here.
--- zfcpdump-kernel-4.4.orig/drivers/acpi/sysfs.c
+++ zfcpdump-kernel-4.4/drivers/acpi/sysfs.c
@@ -555,23 +555,22 @@ static void acpi_global_event_handler(u3
 static int get_status(u32 index, acpi_event_status *status,
 		      acpi_handle *handle)
 {
-	int result = 0;
+	int result;
 
 	if (index >= num_gpes + ACPI_NUM_FIXED_EVENTS)
-		goto end;
+		return -EINVAL;
 
 	if (index < num_gpes) {
 		result = acpi_get_gpe_device(index, handle);
 		if (result) {
 			ACPI_EXCEPTION((AE_INFO, AE_NOT_FOUND,
 					"Invalid GPE 0x%x", index));
-			goto end;
+			return result;
 		}
 		result = acpi_get_gpe_status(*handle, index, status);
 	} else if (index < (num_gpes + ACPI_NUM_FIXED_EVENTS))
 		result = acpi_get_event_status(index - num_gpes, status);
 
-end:
 	return result;
 }
 
--- zfcpdump-kernel-4.4.orig/drivers/acpi/tables.c
+++ zfcpdump-kernel-4.4/drivers/acpi/tables.c
@@ -484,3 +484,13 @@ static int __init acpi_force_table_verif
 }
 
 early_param("acpi_force_table_verification", acpi_force_table_verification_setup);
+
+static int __init acpi_force_32bit_fadt_addr(char *s)
+{
+	pr_info("Forcing 32 Bit FADT addresses\n");
+	acpi_gbl_use32_bit_fadt_addresses = TRUE;
+
+	return 0;
+}
+
+early_param("acpi_force_32bit_fadt_addr", acpi_force_32bit_fadt_addr);
--- zfcpdump-kernel-4.4.orig/drivers/acpi/video_detect.c
+++ zfcpdump-kernel-4.4/drivers/acpi/video_detect.c
@@ -135,14 +135,6 @@ static const struct dmi_system_id video_
 		DMI_MATCH(DMI_PRODUCT_NAME, "UL30A"),
 		},
 	},
-	{
-	.callback = video_detect_force_vendor,
-	.ident = "Dell Inspiron 5737",
-	.matches = {
-		DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
-		DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 5737"),
-		},
-	},
 
 	/*
 	 * These models have a working acpi_video backlight control, and using
--- zfcpdump-kernel-4.4.orig/drivers/android/binder.c
+++ zfcpdump-kernel-4.4/drivers/android/binder.c
@@ -2074,7 +2074,7 @@ static int binder_thread_write(struct bi
 			if (get_user(cookie, (binder_uintptr_t __user *)ptr))
 				return -EFAULT;
 
-			ptr += sizeof(void *);
+			ptr += sizeof(cookie);
 			list_for_each_entry(w, &proc->delivered_death, entry) {
 				struct binder_ref_death *tmp_death = container_of(w, struct binder_ref_death, work);
 
--- zfcpdump-kernel-4.4.orig/drivers/ata/ahci.c
+++ zfcpdump-kernel-4.4/drivers/ata/ahci.c
@@ -264,6 +264,26 @@ static const struct pci_device_id ahci_p
 	{ PCI_VDEVICE(INTEL, 0x3b2b), board_ahci }, /* PCH RAID */
 	{ PCI_VDEVICE(INTEL, 0x3b2c), board_ahci }, /* PCH RAID */
 	{ PCI_VDEVICE(INTEL, 0x3b2f), board_ahci }, /* PCH AHCI */
+	{ PCI_VDEVICE(INTEL, 0x19b0), board_ahci }, /* DNV AHCI */
+	{ PCI_VDEVICE(INTEL, 0x19b1), board_ahci }, /* DNV AHCI */
+	{ PCI_VDEVICE(INTEL, 0x19b2), board_ahci }, /* DNV AHCI */
+	{ PCI_VDEVICE(INTEL, 0x19b3), board_ahci }, /* DNV AHCI */
+	{ PCI_VDEVICE(INTEL, 0x19b4), board_ahci }, /* DNV AHCI */
+	{ PCI_VDEVICE(INTEL, 0x19b5), board_ahci }, /* DNV AHCI */
+	{ PCI_VDEVICE(INTEL, 0x19b6), board_ahci }, /* DNV AHCI */
+	{ PCI_VDEVICE(INTEL, 0x19b7), board_ahci }, /* DNV AHCI */
+	{ PCI_VDEVICE(INTEL, 0x19bE), board_ahci }, /* DNV AHCI */
+	{ PCI_VDEVICE(INTEL, 0x19bF), board_ahci }, /* DNV AHCI */
+	{ PCI_VDEVICE(INTEL, 0x19c0), board_ahci }, /* DNV AHCI */
+	{ PCI_VDEVICE(INTEL, 0x19c1), board_ahci }, /* DNV AHCI */
+	{ PCI_VDEVICE(INTEL, 0x19c2), board_ahci }, /* DNV AHCI */
+	{ PCI_VDEVICE(INTEL, 0x19c3), board_ahci }, /* DNV AHCI */
+	{ PCI_VDEVICE(INTEL, 0x19c4), board_ahci }, /* DNV AHCI */
+	{ PCI_VDEVICE(INTEL, 0x19c5), board_ahci }, /* DNV AHCI */
+	{ PCI_VDEVICE(INTEL, 0x19c6), board_ahci }, /* DNV AHCI */
+	{ PCI_VDEVICE(INTEL, 0x19c7), board_ahci }, /* DNV AHCI */
+	{ PCI_VDEVICE(INTEL, 0x19cE), board_ahci }, /* DNV AHCI */
+	{ PCI_VDEVICE(INTEL, 0x19cF), board_ahci }, /* DNV AHCI */
 	{ PCI_VDEVICE(INTEL, 0x1c02), board_ahci }, /* CPT AHCI */
 	{ PCI_VDEVICE(INTEL, 0x1c03), board_ahci }, /* CPT AHCI */
 	{ PCI_VDEVICE(INTEL, 0x1c04), board_ahci }, /* CPT RAID */
@@ -347,15 +367,21 @@ static const struct pci_device_id ahci_p
 	{ PCI_VDEVICE(INTEL, 0xa107), board_ahci }, /* Sunrise Point-H RAID */
 	{ PCI_VDEVICE(INTEL, 0xa10f), board_ahci }, /* Sunrise Point-H RAID */
 	{ PCI_VDEVICE(INTEL, 0x2822), board_ahci }, /* Lewisburg RAID*/
+	{ PCI_VDEVICE(INTEL, 0x2823), board_ahci }, /* Lewisburg AHCI*/
 	{ PCI_VDEVICE(INTEL, 0x2826), board_ahci }, /* Lewisburg RAID*/
+	{ PCI_VDEVICE(INTEL, 0x2827), board_ahci }, /* Lewisburg RAID*/
 	{ PCI_VDEVICE(INTEL, 0xa182), board_ahci }, /* Lewisburg AHCI*/
 	{ PCI_VDEVICE(INTEL, 0xa184), board_ahci }, /* Lewisburg RAID*/
 	{ PCI_VDEVICE(INTEL, 0xa186), board_ahci }, /* Lewisburg RAID*/
 	{ PCI_VDEVICE(INTEL, 0xa18e), board_ahci }, /* Lewisburg RAID*/
+	{ PCI_VDEVICE(INTEL, 0xa1d2), board_ahci }, /* Lewisburg RAID*/
+	{ PCI_VDEVICE(INTEL, 0xa1d6), board_ahci }, /* Lewisburg RAID*/
 	{ PCI_VDEVICE(INTEL, 0xa202), board_ahci }, /* Lewisburg AHCI*/
 	{ PCI_VDEVICE(INTEL, 0xa204), board_ahci }, /* Lewisburg RAID*/
 	{ PCI_VDEVICE(INTEL, 0xa206), board_ahci }, /* Lewisburg RAID*/
 	{ PCI_VDEVICE(INTEL, 0xa20e), board_ahci }, /* Lewisburg RAID*/
+	{ PCI_VDEVICE(INTEL, 0xa252), board_ahci }, /* Lewisburg RAID*/
+	{ PCI_VDEVICE(INTEL, 0xa256), board_ahci }, /* Lewisburg RAID*/
 
 	/* JMicron 360/1/3/5/6, match class to avoid IDE function */
 	{ PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
@@ -1305,6 +1331,44 @@ static inline void ahci_gtf_filter_worka
 {}
 #endif
 
+#ifdef CONFIG_ARM64
+/*
+ * Due to ERRATA#22536, ThunderX needs to handle HOST_IRQ_STAT differently.
+ * Workaround is to make sure all pending IRQs are served before leaving
+ * handler.
+ */
+static irqreturn_t ahci_thunderx_irq_handler(int irq, void *dev_instance)
+{
+	struct ata_host *host = dev_instance;
+	struct ahci_host_priv *hpriv;
+	unsigned int rc = 0;
+	void __iomem *mmio;
+	u32 irq_stat, irq_masked;
+	unsigned int handled = 1;
+
+	VPRINTK("ENTER\n");
+	hpriv = host->private_data;
+	mmio = hpriv->mmio;
+	irq_stat = readl(mmio + HOST_IRQ_STAT);
+	if (!irq_stat)
+		return IRQ_NONE;
+
+	do {
+		irq_masked = irq_stat & hpriv->port_map;
+		spin_lock(&host->lock);
+		rc = ahci_handle_port_intr(host, irq_masked);
+		if (!rc)
+			handled = 0;
+		writel(irq_stat, mmio + HOST_IRQ_STAT);
+		irq_stat = readl(mmio + HOST_IRQ_STAT);
+		spin_unlock(&host->lock);
+	} while (irq_stat);
+	VPRINTK("EXIT\n");
+
+	return IRQ_RETVAL(handled);
+}
+#endif
+
 /*
  * ahci_init_msix() only implements single MSI-X support, not multiple
  * MSI-X per-port interrupts. This is needed for host controllers that only
@@ -1520,6 +1584,11 @@ static int ahci_init_one(struct pci_dev
 	if (ahci_broken_devslp(pdev))
 		hpriv->flags |= AHCI_HFLAG_NO_DEVSLP;
 
+#ifdef CONFIG_ARM64
+	if (pdev->vendor == 0x177d && pdev->device == 0xa01c)
+		hpriv->irq_handler = ahci_thunderx_irq_handler;
+#endif
+
 	/* save initial config */
 	ahci_pci_save_initial_config(pdev, hpriv);
 
--- zfcpdump-kernel-4.4.orig/drivers/ata/ahci.h
+++ zfcpdump-kernel-4.4/drivers/ata/ahci.h
@@ -240,8 +240,6 @@ enum {
 	AHCI_HFLAG_MULTI_MSI		= (1 << 16), /* multiple PCI MSIs */
 	AHCI_HFLAG_NO_DEVSLP		= (1 << 17), /* no device sleep */
 	AHCI_HFLAG_NO_FBS		= (1 << 18), /* no FBS */
-	AHCI_HFLAG_EDGE_IRQ		= (1 << 19), /* HOST_IRQ_STAT behaves as
-							Edge Triggered */
 
 	/* ap->flags bits */
 
@@ -352,6 +350,7 @@ struct ahci_host_priv {
 	 * be overridden anytime before the host is activated.
 	 */
 	void			(*start_engine)(struct ata_port *ap);
+	irqreturn_t 		(*irq_handler)(int irq, void *dev_instance);
 };
 
 extern int ahci_ignore_sss;
@@ -400,6 +399,7 @@ int ahci_reset_em(struct ata_host *host)
 void ahci_print_info(struct ata_host *host, const char *scc_s);
 int ahci_host_activate(struct ata_host *host, struct scsi_host_template *sht);
 void ahci_error_handler(struct ata_port *ap);
+u32 ahci_handle_port_intr(struct ata_host *host, u32 irq_masked);
 
 static inline void __iomem *__ahci_port_base(struct ata_host *host,
 					     unsigned int port_no)
--- zfcpdump-kernel-4.4.orig/drivers/ata/ahci_platform.c
+++ zfcpdump-kernel-4.4/drivers/ata/ahci_platform.c
@@ -51,6 +51,9 @@ static int ahci_probe(struct platform_de
 	if (rc)
 		return rc;
 
+	of_property_read_u32(dev->of_node,
+			     "ports-implemented", &hpriv->force_port_map);
+
 	if (of_device_is_compatible(dev->of_node, "hisilicon,hisi-ahci"))
 		hpriv->flags |= AHCI_HFLAG_NO_FBS | AHCI_HFLAG_NO_NCQ;
 
--- zfcpdump-kernel-4.4.orig/drivers/ata/ahci_xgene.c
+++ zfcpdump-kernel-4.4/drivers/ata/ahci_xgene.c
@@ -548,6 +548,88 @@ softreset_retry:
 	return rc;
 }
 
+/**
+ * xgene_ahci_handle_broken_edge_irq - Handle the broken irq.
+ * @ata_host: Host that recieved the irq
+ * @irq_masked: HOST_IRQ_STAT value
+ *
+ * For hardware with broken edge trigger latch
+ * the HOST_IRQ_STAT register misses the edge interrupt
+ * when clearing of HOST_IRQ_STAT register and hardware
+ * reporting the PORT_IRQ_STAT register at the
+ * same clock cycle.
+ * As such, the algorithm below outlines the workaround.
+ *
+ * 1. Read HOST_IRQ_STAT register and save the state.
+ * 2. Clear the HOST_IRQ_STAT register.
+ * 3. Read back the HOST_IRQ_STAT register.
+ * 4. If HOST_IRQ_STAT register equals to zero, then
+ *    traverse the rest of port's PORT_IRQ_STAT register
+ *    to check if an interrupt is triggered at that point else
+ *    go to step 6.
+ * 5. If PORT_IRQ_STAT register of rest ports is not equal to zero
+ *    then update the state of HOST_IRQ_STAT saved in step 1.
+ * 6. Handle port interrupts.
+ * 7. Exit
+ */
+static int xgene_ahci_handle_broken_edge_irq(struct ata_host *host,
+					     u32 irq_masked)
+{
+	struct ahci_host_priv *hpriv = host->private_data;
+	void __iomem *port_mmio;
+	int i;
+
+	if (!readl(hpriv->mmio + HOST_IRQ_STAT)) {
+		for (i = 0; i < host->n_ports; i++) {
+			if (irq_masked & (1 << i))
+				continue;
+
+			port_mmio = ahci_port_base(host->ports[i]);
+			if (readl(port_mmio + PORT_IRQ_STAT))
+				irq_masked |= (1 << i);
+		}
+	}
+
+	return ahci_handle_port_intr(host, irq_masked);
+}
+
+static irqreturn_t xgene_ahci_irq_intr(int irq, void *dev_instance)
+{
+	struct ata_host *host = dev_instance;
+	struct ahci_host_priv *hpriv;
+	unsigned int rc = 0;
+	void __iomem *mmio;
+	u32 irq_stat, irq_masked;
+
+	VPRINTK("ENTER\n");
+
+	hpriv = host->private_data;
+	mmio = hpriv->mmio;
+
+	/* sigh.  0xffffffff is a valid return from h/w */
+	irq_stat = readl(mmio + HOST_IRQ_STAT);
+	if (!irq_stat)
+		return IRQ_NONE;
+
+	irq_masked = irq_stat & hpriv->port_map;
+
+	spin_lock(&host->lock);
+
+	/*
+	 * HOST_IRQ_STAT behaves as edge triggered latch meaning that
+	 * it should be cleared before all the port events are cleared.
+	 */
+	writel(irq_stat, mmio + HOST_IRQ_STAT);
+
+	rc = xgene_ahci_handle_broken_edge_irq(host, irq_masked);
+
+	spin_unlock(&host->lock);
+
+	VPRINTK("EXIT\n");
+
+	return IRQ_RETVAL(rc);
+}
+
 static struct ata_port_operations xgene_ahci_v1_ops = {
 	.inherits = &ahci_ops,
 	.host_stop = xgene_ahci_host_stop,
@@ -739,9 +821,9 @@ static int xgene_ahci_probe(struct platf
 				dev_warn(&pdev->dev, "%s: Error reading device info. Assume version1\n",
 					__func__);
 				version = XGENE_AHCI_V1;
-			}
-			if (info->valid & ACPI_VALID_CID)
+			} else if (info->valid & ACPI_VALID_CID) {
 				version = XGENE_AHCI_V2;
+			}
 		}
 	}
 #endif
@@ -779,7 +861,8 @@ skip_clk_phy:
 		hpriv->flags = AHCI_HFLAG_NO_NCQ;
 		break;
 	case XGENE_AHCI_V2:
-		hpriv->flags |= AHCI_HFLAG_YES_FBS | AHCI_HFLAG_EDGE_IRQ;
+		hpriv->flags |= AHCI_HFLAG_YES_FBS;
+		hpriv->irq_handler = xgene_ahci_irq_intr;
 		break;
 	default:
 		break;
--- zfcpdump-kernel-4.4.orig/drivers/ata/libahci.c
+++ zfcpdump-kernel-4.4/drivers/ata/libahci.c
@@ -112,6 +112,7 @@ static ssize_t ahci_store_em_buffer(stru
 				    const char *buf, size_t size);
 static ssize_t ahci_show_em_supported(struct device *dev,
 				      struct device_attribute *attr, char *buf);
+static irqreturn_t ahci_single_level_irq_intr(int irq, void *dev_instance);
 
 static DEVICE_ATTR(ahci_host_caps, S_IRUGO, ahci_show_host_caps, NULL);
 static DEVICE_ATTR(ahci_host_cap2, S_IRUGO, ahci_show_host_cap2, NULL);
@@ -467,6 +468,7 @@ void ahci_save_initial_config(struct dev
 		dev_info(dev, "forcing port_map 0x%x -> 0x%x\n",
 			 port_map, hpriv->force_port_map);
 		port_map = hpriv->force_port_map;
+		hpriv->saved_port_map = port_map;
 	}
 
 	if (hpriv->mask_port_map) {
@@ -495,8 +497,8 @@ void ahci_save_initial_config(struct dev
 		}
 	}
 
-	/* fabricate port_map from cap.nr_ports */
-	if (!port_map) {
+	/* fabricate port_map from cap.nr_ports for < AHCI 1.3 */
+	if (!port_map && vers < 0x10300) {
 		port_map = (1 << ahci_nr_ports(cap)) - 1;
 		dev_warn(dev, "forcing PORTS_IMPL to 0x%x\n", port_map);
 
@@ -511,6 +513,9 @@ void ahci_save_initial_config(struct dev
 
 	if (!hpriv->start_engine)
 		hpriv->start_engine = ahci_start_engine;
+
+	if (!hpriv->irq_handler)
+		hpriv->irq_handler = ahci_single_level_irq_intr;
 }
 EXPORT_SYMBOL_GPL(ahci_save_initial_config);
 
@@ -1142,8 +1147,7 @@ static void ahci_port_init(struct device
 
 	/* mark esata ports */
 	tmp = readl(port_mmio + PORT_CMD);
-	if ((tmp & PORT_CMD_HPCP) ||
-	    ((tmp & PORT_CMD_ESP) && (hpriv->cap & HOST_CAP_SXS)))
+	if ((tmp & PORT_CMD_ESP) && (hpriv->cap & HOST_CAP_SXS))
 		ap->pflags |= ATA_PFLAG_EXTERNAL;
 }
 
@@ -1841,7 +1845,7 @@ static irqreturn_t ahci_multi_irqs_intr(
 	return IRQ_WAKE_THREAD;
 }
 
-static u32 ahci_handle_port_intr(struct ata_host *host, u32 irq_masked)
+u32 ahci_handle_port_intr(struct ata_host *host, u32 irq_masked)
 {
 	unsigned int i, handled = 0;
 
@@ -1867,43 +1871,7 @@ static u32 ahci_handle_port_intr(struct
 
 	return handled;
 }
-
-static irqreturn_t ahci_single_edge_irq_intr(int irq, void *dev_instance)
-{
-	struct ata_host *host = dev_instance;
-	struct ahci_host_priv *hpriv;
-	unsigned int rc = 0;
-	void __iomem *mmio;
-	u32 irq_stat, irq_masked;
-
-	VPRINTK("ENTER\n");
-
-	hpriv = host->private_data;
-	mmio = hpriv->mmio;
-
-	/* sigh.  0xffffffff is a valid return from h/w */
-	irq_stat = readl(mmio + HOST_IRQ_STAT);
-	if (!irq_stat)
-		return IRQ_NONE;
-
-	irq_masked = irq_stat & hpriv->port_map;
-
-	spin_lock(&host->lock);
-
-	/*
-	 * HOST_IRQ_STAT behaves as edge triggered latch meaning that
-	 * it should be cleared before all the port events are cleared.
-	 */
-	writel(irq_stat, mmio + HOST_IRQ_STAT);
-
-	rc = ahci_handle_port_intr(host, irq_masked);
-
-	spin_unlock(&host->lock);
-
-	VPRINTK("EXIT\n");
-
-	return IRQ_RETVAL(rc);
-}
+EXPORT_SYMBOL_GPL(ahci_handle_port_intr);
 
 static irqreturn_t ahci_single_level_irq_intr(int irq, void *dev_instance)
 {
@@ -2528,14 +2496,18 @@ int ahci_host_activate(struct ata_host *
 	int irq = hpriv->irq;
 	int rc;
 
-	if (hpriv->flags & AHCI_HFLAG_MULTI_MSI)
+	if (hpriv->flags & AHCI_HFLAG_MULTI_MSI) {
+		if (hpriv->irq_handler)
+			dev_warn(host->dev, "both AHCI_HFLAG_MULTI_MSI flag set \
+				 and custom irq handler implemented\n");
+
 		rc = ahci_host_activate_multi_irqs(host, irq, sht);
-	else if (hpriv->flags & AHCI_HFLAG_EDGE_IRQ)
-		rc = ata_host_activate(host, irq, ahci_single_edge_irq_intr,
-				       IRQF_SHARED, sht);
-	else
-		rc = ata_host_activate(host, irq, ahci_single_level_irq_intr,
+	} else {
+		rc = ata_host_activate(host, irq, hpriv->irq_handler,
 				       IRQF_SHARED, sht);
+	}
+
+
 	return rc;
 }
 EXPORT_SYMBOL_GPL(ahci_host_activate);
--- zfcpdump-kernel-4.4.orig/drivers/ata/libata-core.c
+++ zfcpdump-kernel-4.4/drivers/ata/libata-core.c
@@ -4138,6 +4138,12 @@ static const struct ata_blacklist_entry
 	 */
 	{ "ST380013AS",		"3.20",		ATA_HORKAGE_MAX_SEC_1024 },
 
+	/*
+	 * Device times out with higher max sects.
+	 * https://bugzilla.kernel.org/show_bug.cgi?id=121671
+	 */
+	{ "LITEON CX1-JB256-HP", NULL,		ATA_HORKAGE_MAX_SEC_1024 },
+
 	/* Devices we expect to fail diagnostics */
 
 	/* Devices where NCQ should be avoided */
--- zfcpdump-kernel-4.4.orig/drivers/ata/libata-eh.c
+++ zfcpdump-kernel-4.4/drivers/ata/libata-eh.c
@@ -606,7 +606,7 @@ void ata_scsi_error(struct Scsi_Host *ho
 	ata_scsi_port_error_handler(host, ap);
 
 	/* finish or retry handled scmd's and clean up */
-	WARN_ON(host->host_failed || !list_empty(&eh_work_q));
+	WARN_ON(!list_empty(&eh_work_q));
 
 	DPRINTK("EXIT\n");
 }
--- zfcpdump-kernel-4.4.orig/drivers/ata/libata-scsi.c
+++ zfcpdump-kernel-4.4/drivers/ata/libata-scsi.c
@@ -675,19 +675,18 @@ static int ata_ioc32(struct ata_port *ap
 int ata_sas_scsi_ioctl(struct ata_port *ap, struct scsi_device *scsidev,
 		     int cmd, void __user *arg)
 {
-	int val = -EINVAL, rc = -EINVAL;
+	unsigned long val;
+	int rc = -EINVAL;
 	unsigned long flags;
 
 	switch (cmd) {
-	case ATA_IOC_GET_IO32:
+	case HDIO_GET_32BIT:
 		spin_lock_irqsave(ap->lock, flags);
 		val = ata_ioc32(ap);
 		spin_unlock_irqrestore(ap->lock, flags);
-		if (copy_to_user(arg, &val, 1))
-			return -EFAULT;
-		return 0;
+		return put_user(val, (unsigned long __user *)arg);
 
-	case ATA_IOC_SET_IO32:
+	case HDIO_SET_32BIT:
 		val = (unsigned long) arg;
 		rc = 0;
 		spin_lock_irqsave(ap->lock, flags);
--- zfcpdump-kernel-4.4.orig/drivers/ata/libata-sff.c
+++ zfcpdump-kernel-4.4/drivers/ata/libata-sff.c
@@ -997,12 +997,9 @@ static inline int ata_hsm_ok_in_wq(struc
 static void ata_hsm_qc_complete(struct ata_queued_cmd *qc, int in_wq)
 {
 	struct ata_port *ap = qc->ap;
-	unsigned long flags;
 
 	if (ap->ops->error_handler) {
 		if (in_wq) {
-			spin_lock_irqsave(ap->lock, flags);
-
 			/* EH might have kicked in while host lock is
 			 * released.
 			 */
@@ -1014,8 +1011,6 @@ static void ata_hsm_qc_complete(struct a
 				} else
 					ata_port_freeze(ap);
 			}
-
-			spin_unlock_irqrestore(ap->lock, flags);
 		} else {
 			if (likely(!(qc->err_mask & AC_ERR_HSM)))
 				ata_qc_complete(qc);
@@ -1024,10 +1019,8 @@ static void ata_hsm_qc_complete(struct a
 		}
 	} else {
 		if (in_wq) {
-			spin_lock_irqsave(ap->lock, flags);
 			ata_sff_irq_on(ap);
 			ata_qc_complete(qc);
-			spin_unlock_irqrestore(ap->lock, flags);
 		} else
 			ata_qc_complete(qc);
 	}
@@ -1048,9 +1041,10 @@ int ata_sff_hsm_move(struct ata_port *ap
 {
 	struct ata_link *link = qc->dev->link;
 	struct ata_eh_info *ehi = &link->eh_info;
-	unsigned long flags = 0;
 	int poll_next;
 
+	lockdep_assert_held(ap->lock);
+
 	WARN_ON_ONCE((qc->flags & ATA_QCFLAG_ACTIVE) == 0);
 
 	/* Make sure ata_sff_qc_issue() does not throw things
@@ -1112,14 +1106,6 @@ fsm_start:
 			}
 		}
 
-		/* Send the CDB (atapi) or the first data block (ata pio out).
-		 * During the state transition, interrupt handler shouldn't
-		 * be invoked before the data transfer is complete and
-		 * hsm_task_state is changed. Hence, the following locking.
-		 */
-		if (in_wq)
-			spin_lock_irqsave(ap->lock, flags);
-
 		if (qc->tf.protocol == ATA_PROT_PIO) {
 			/* PIO data out protocol.
 			 * send first data block.
@@ -1135,9 +1121,6 @@ fsm_start:
 			/* send CDB */
 			atapi_send_cdb(ap, qc);
 
-		if (in_wq)
-			spin_unlock_irqrestore(ap->lock, flags);
-
 		/* if polling, ata_sff_pio_task() handles the rest.
 		 * otherwise, interrupt handler takes over from here.
 		 */
@@ -1361,12 +1344,14 @@ static void ata_sff_pio_task(struct work
 	u8 status;
 	int poll_next;
 
+	spin_lock_irq(ap->lock);
+
 	BUG_ON(ap->sff_pio_task_link == NULL);
 	/* qc can be NULL if timeout occurred */
 	qc = ata_qc_from_tag(ap, link->active_tag);
 	if (!qc) {
 		ap->sff_pio_task_link = NULL;
-		return;
+		goto out_unlock;
 	}
 
 fsm_start:
@@ -1381,11 +1366,14 @@ fsm_start:
 	 */
 	status = ata_sff_busy_wait(ap, ATA_BUSY, 5);
 	if (status & ATA_BUSY) {
+		spin_unlock_irq(ap->lock);
 		ata_msleep(ap, 2);
+		spin_lock_irq(ap->lock);
+
 		status = ata_sff_busy_wait(ap, ATA_BUSY, 10);
 		if (status & ATA_BUSY) {
 			ata_sff_queue_pio_task(link, ATA_SHORT_PAUSE);
-			return;
+			goto out_unlock;
 		}
 	}
 
@@ -1402,6 +1390,8 @@ fsm_start:
 	 */
 	if (poll_next)
 		goto fsm_start;
+out_unlock:
+	spin_unlock_irq(ap->lock);
 }
 
 /**
--- zfcpdump-kernel-4.4.orig/drivers/ata/pata_rb532_cf.c
+++ zfcpdump-kernel-4.4/drivers/ata/pata_rb532_cf.c
@@ -32,6 +32,8 @@
 #include <linux/libata.h>
 #include <scsi/scsi_host.h>
 
+#include <asm/mach-rc32434/rb.h>
+
 #define DRV_NAME	"pata-rb532-cf"
 #define DRV_VERSION	"0.1.0"
 #define DRV_DESC	"PATA driver for RouterBOARD 532 Compact Flash"
@@ -107,6 +109,7 @@ static int rb532_pata_driver_probe(struc
 	int gpio;
 	struct resource *res;
 	struct ata_host *ah;
+	struct cf_device *pdata;
 	struct rb532_cf_info *info;
 	int ret;
 
@@ -122,7 +125,13 @@ static int rb532_pata_driver_probe(struc
 		return -ENOENT;
 	}
 
-	gpio = irq_to_gpio(irq);
+	pdata = dev_get_platdata(&pdev->dev);
+	if (!pdata) {
+		dev_err(&pdev->dev, "no platform data specified\n");
+		return -EINVAL;
+	}
+
+	gpio = pdata->gpio_pin;
 	if (gpio < 0) {
 		dev_err(&pdev->dev, "no GPIO found for irq%d\n", irq);
 		return -ENOENT;
--- zfcpdump-kernel-4.4.orig/drivers/base/core.c
+++ zfcpdump-kernel-4.4/drivers/base/core.c
@@ -2261,7 +2261,10 @@ void set_primary_fwnode(struct device *d
 		if (fwnode_is_primary(fn))
 			fn = fn->secondary;
 
-		fwnode->secondary = fn;
+		if (fn) {
+			WARN_ON(fwnode->secondary);
+			fwnode->secondary = fn;
+		}
 		dev->fwnode = fwnode;
 	} else {
 		dev->fwnode = fwnode_is_primary(dev->fwnode) ?
--- zfcpdump-kernel-4.4.orig/drivers/base/module.c
+++ zfcpdump-kernel-4.4/drivers/base/module.c
@@ -24,10 +24,12 @@ static char *make_driver_name(struct dev
 
 static void module_create_drivers_dir(struct module_kobject *mk)
 {
-	if (!mk || mk->drivers_dir)
-		return;
+	static DEFINE_MUTEX(drivers_dir_mutex);
 
-	mk->drivers_dir = kobject_create_and_add("drivers", &mk->kobj);
+	mutex_lock(&drivers_dir_mutex);
+	if (mk && !mk->drivers_dir)
+		mk->drivers_dir = kobject_create_and_add("drivers", &mk->kobj);
+	mutex_unlock(&drivers_dir_mutex);
 }
 
 void module_add_driver(struct module *mod, struct device_driver *drv)
--- zfcpdump-kernel-4.4.orig/drivers/base/platform.c
+++ zfcpdump-kernel-4.4/drivers/base/platform.c
@@ -26,6 +26,7 @@
 #include <linux/acpi.h>
 #include <linux/clk/clk-conf.h>
 #include <linux/limits.h>
+#include <linux/property.h>
 
 #include "base.h"
 #include "power/power.h"
@@ -299,6 +300,22 @@ int platform_device_add_data(struct plat
 EXPORT_SYMBOL_GPL(platform_device_add_data);
 
 /**
+ * platform_device_add_properties - add built-in properties to a platform device
+ * @pdev: platform device to add properties to
+ * @pset: properties to add
+ *
+ * The function will take deep copy of the properties in @pset and attach
+ * the copy to the platform device. The memory associated with properties
+ * will be freed when the platform device is released.
+ */
+int platform_device_add_properties(struct platform_device *pdev,
+				   const struct property_set *pset)
+{
+	return device_add_property_set(&pdev->dev, pset);
+}
+EXPORT_SYMBOL_GPL(platform_device_add_properties);
+
+/**
  * platform_device_add - add a platform device to device hierarchy
  * @pdev: platform device we're adding
  *
@@ -409,6 +426,8 @@ void platform_device_del(struct platform
 			if (r->parent)
 				release_resource(r);
 		}
+
+		device_remove_property_set(&pdev->dev);
 	}
 }
 EXPORT_SYMBOL_GPL(platform_device_del);
@@ -487,6 +506,12 @@ struct platform_device *platform_device_
 	if (ret)
 		goto err;
 
+	if (pdevinfo->pset) {
+		ret = platform_device_add_properties(pdev, pdevinfo->pset);
+		if (ret)
+			goto err;
+	}
+
 	ret = platform_device_add(pdev);
 	if (ret) {
 err:
@@ -513,10 +538,15 @@ static int platform_drv_probe(struct dev
 		return ret;
 
 	ret = dev_pm_domain_attach(_dev, true);
-	if (ret != -EPROBE_DEFER && drv->probe) {
-		ret = drv->probe(dev);
-		if (ret)
-			dev_pm_domain_detach(_dev, true);
+	if (ret != -EPROBE_DEFER) {
+		if (drv->probe) {
+			ret = drv->probe(dev);
+			if (ret)
+				dev_pm_domain_detach(_dev, true);
+		} else {
+			/* don't fail if just dev_pm_domain_attach failed */
+			ret = 0;
+		}
 	}
 
 	if (drv->prevent_deferred_probe && ret == -EPROBE_DEFER) {
--- zfcpdump-kernel-4.4.orig/drivers/base/power/domain.c
+++ zfcpdump-kernel-4.4/drivers/base/power/domain.c
@@ -1381,7 +1381,7 @@ int pm_genpd_remove_subdomain(struct gen
 
 	mutex_lock(&genpd->lock);
 
-	if (!list_empty(&subdomain->slave_links) || subdomain->device_count) {
+	if (!list_empty(&subdomain->master_links) || subdomain->device_count) {
 		pr_warn("%s: unable to remove subdomain %s\n", genpd->name,
 			subdomain->name);
 		ret = -EBUSY;
--- zfcpdump-kernel-4.4.orig/drivers/base/power/main.c
+++ zfcpdump-kernel-4.4/drivers/base/power/main.c
@@ -1262,14 +1262,15 @@ int dpm_suspend_late(pm_message_t state)
 		error = device_suspend_late(dev);
 
 		mutex_lock(&dpm_list_mtx);
+		if (!list_empty(&dev->power.entry))
+			list_move(&dev->power.entry, &dpm_late_early_list);
+
 		if (error) {
 			pm_dev_err(dev, state, " late", error);
 			dpm_save_failed_dev(dev_name(dev));
 			put_device(dev);
 			break;
 		}
-		if (!list_empty(&dev->power.entry))
-			list_move(&dev->power.entry, &dpm_late_early_list);
 		put_device(dev);
 
 		if (async_error)
--- zfcpdump-kernel-4.4.orig/drivers/base/power/opp/core.c
+++ zfcpdump-kernel-4.4/drivers/base/power/opp/core.c
@@ -809,8 +809,14 @@ static int opp_parse_supplies(struct dev
 	}
 
 	opp->u_volt = microvolt[0];
-	opp->u_volt_min = microvolt[1];
-	opp->u_volt_max = microvolt[2];
+
+	if (count == 1) {
+		opp->u_volt_min = opp->u_volt;
+		opp->u_volt_max = opp->u_volt;
+	} else {
+		opp->u_volt_min = microvolt[1];
+		opp->u_volt_max = microvolt[2];
+	}
 
 	if (!of_property_read_u32(opp->np, "opp-microamp", &val))
 		opp->u_amp = val;
--- zfcpdump-kernel-4.4.orig/drivers/base/power/runtime.c
+++ zfcpdump-kernel-4.4/drivers/base/power/runtime.c
@@ -966,6 +966,30 @@ int __pm_runtime_resume(struct device *d
 EXPORT_SYMBOL_GPL(__pm_runtime_resume);
 
 /**
+ * pm_runtime_get_if_in_use - Conditionally bump up the device's usage counter.
+ * @dev: Device to handle.
+ *
+ * Return -EINVAL if runtime PM is disabled for the device.
+ *
+ * If that's not the case and if the device's runtime PM status is RPM_ACTIVE
+ * and the runtime PM usage counter is nonzero, increment the counter and
+ * return 1.  Otherwise return 0 without changing the counter.
+ */
+int pm_runtime_get_if_in_use(struct device *dev)
+{
+	unsigned long flags;
+	int retval;
+
+	spin_lock_irqsave(&dev->power.lock, flags);
+	retval = dev->power.disable_depth > 0 ? -EINVAL :
+		dev->power.runtime_status == RPM_ACTIVE
+			&& atomic_inc_not_zero(&dev->power.usage_count);
+	spin_unlock_irqrestore(&dev->power.lock, flags);
+	return retval;
+}
+EXPORT_SYMBOL_GPL(pm_runtime_get_if_in_use);
+
+/**
  * __pm_runtime_set_status - Set runtime PM status of a device.
  * @dev: Device to handle.
  * @status: New runtime PM status of the device.
@@ -1468,11 +1492,16 @@ int pm_runtime_force_resume(struct devic
 		goto out;
 	}
 
-	ret = callback(dev);
+	ret = pm_runtime_set_active(dev);
 	if (ret)
 		goto out;
 
-	pm_runtime_set_active(dev);
+	ret = callback(dev);
+	if (ret) {
+		pm_runtime_set_suspended(dev);
+		goto out;
+	}
+
 	pm_runtime_mark_last_busy(dev);
 out:
 	pm_runtime_enable(dev);
--- zfcpdump-kernel-4.4.orig/drivers/base/property.c
+++ zfcpdump-kernel-4.4/drivers/base/property.c
@@ -19,32 +19,14 @@
 #include <linux/etherdevice.h>
 #include <linux/phy.h>
 
-/**
- * device_add_property_set - Add a collection of properties to a device object.
- * @dev: Device to add properties to.
- * @pset: Collection of properties to add.
- *
- * Associate a collection of device properties represented by @pset with @dev
- * as its secondary firmware node.
- */
-void device_add_property_set(struct device *dev, struct property_set *pset)
-{
-	if (!pset)
-		return;
-
-	pset->fwnode.type = FWNODE_PDATA;
-	set_secondary_fwnode(dev, &pset->fwnode);
-}
-EXPORT_SYMBOL_GPL(device_add_property_set);
-
-static inline bool is_pset(struct fwnode_handle *fwnode)
+static inline bool is_pset_node(struct fwnode_handle *fwnode)
 {
 	return fwnode && fwnode->type == FWNODE_PDATA;
 }
 
-static inline struct property_set *to_pset(struct fwnode_handle *fwnode)
+static inline struct property_set *to_pset_node(struct fwnode_handle *fwnode)
 {
-	return is_pset(fwnode) ?
+	return is_pset_node(fwnode) ?
 		container_of(fwnode, struct property_set, fwnode) : NULL;
 }
 
@@ -63,45 +45,135 @@ static struct property_entry *pset_prop_
 	return NULL;
 }
 
-static int pset_prop_read_array(struct property_set *pset, const char *name,
-				enum dev_prop_type type, void *val, size_t nval)
+static void *pset_prop_find(struct property_set *pset, const char *propname,
+			    size_t length)
 {
 	struct property_entry *prop;
-	unsigned int item_size;
+	void *pointer;
 
-	prop = pset_prop_get(pset, name);
+	prop = pset_prop_get(pset, propname);
 	if (!prop)
-		return -ENODATA;
+		return ERR_PTR(-EINVAL);
+	if (prop->is_array)
+		pointer = prop->pointer.raw_data;
+	else
+		pointer = &prop->value.raw_data;
+	if (!pointer)
+		return ERR_PTR(-ENODATA);
+	if (length > prop->length)
+		return ERR_PTR(-EOVERFLOW);
+	return pointer;
+}
+
+static int pset_prop_read_u8_array(struct property_set *pset,
+				   const char *propname,
+				   u8 *values, size_t nval)
+{
+	void *pointer;
+	size_t length = nval * sizeof(*values);
+
+	pointer = pset_prop_find(pset, propname, length);
+	if (IS_ERR(pointer))
+		return PTR_ERR(pointer);
+
+	memcpy(values, pointer, length);
+	return 0;
+}
+
+static int pset_prop_read_u16_array(struct property_set *pset,
+				    const char *propname,
+				    u16 *values, size_t nval)
+{
+	void *pointer;
+	size_t length = nval * sizeof(*values);
+
+	pointer = pset_prop_find(pset, propname, length);
+	if (IS_ERR(pointer))
+		return PTR_ERR(pointer);
+
+	memcpy(values, pointer, length);
+	return 0;
+}
 
-	if (prop->type != type)
-		return -EPROTO;
+static int pset_prop_read_u32_array(struct property_set *pset,
+				    const char *propname,
+				    u32 *values, size_t nval)
+{
+	void *pointer;
+	size_t length = nval * sizeof(*values);
+
+	pointer = pset_prop_find(pset, propname, length);
+	if (IS_ERR(pointer))
+		return PTR_ERR(pointer);
+
+	memcpy(values, pointer, length);
+	return 0;
+}
+
+static int pset_prop_read_u64_array(struct property_set *pset,
+				    const char *propname,
+				    u64 *values, size_t nval)
+{
+	void *pointer;
+	size_t length = nval * sizeof(*values);
+
+	pointer = pset_prop_find(pset, propname, length);
+	if (IS_ERR(pointer))
+		return PTR_ERR(pointer);
+
+	memcpy(values, pointer, length);
+	return 0;
+}
+
+static int pset_prop_count_elems_of_size(struct property_set *pset,
+					 const char *propname, size_t length)
+{
+	struct property_entry *prop;
+
+	prop = pset_prop_get(pset, propname);
+	if (!prop)
+		return -EINVAL;
+
+	return prop->length / length;
+}
+
+static int pset_prop_read_string_array(struct property_set *pset,
+				       const char *propname,
+				       const char **strings, size_t nval)
+{
+	void *pointer;
+	size_t length = nval * sizeof(*strings);
+
+	pointer = pset_prop_find(pset, propname, length);
+	if (IS_ERR(pointer))
+		return PTR_ERR(pointer);
+
+	memcpy(strings, pointer, length);
+	return 0;
+}
 
-	if (!val)
-		return prop->nval;
+static int pset_prop_read_string(struct property_set *pset,
+				 const char *propname, const char **strings)
+{
+	struct property_entry *prop;
+	const char **pointer;
 
-	if (prop->nval < nval)
-		return -EOVERFLOW;
-
-	switch (type) {
-	case DEV_PROP_U8:
-		item_size = sizeof(u8);
-		break;
-	case DEV_PROP_U16:
-		item_size = sizeof(u16);
-		break;
-	case DEV_PROP_U32:
-		item_size = sizeof(u32);
-		break;
-	case DEV_PROP_U64:
-		item_size = sizeof(u64);
-		break;
-	case DEV_PROP_STRING:
-		item_size = sizeof(const char *);
-		break;
-	default:
+	prop = pset_prop_get(pset, propname);
+	if (!prop)
 		return -EINVAL;
+	if (!prop->is_string)
+		return -EILSEQ;
+	if (prop->is_array) {
+		pointer = prop->pointer.str;
+		if (!pointer)
+			return -ENODATA;
+	} else {
+		pointer = &prop->value.str;
+		if (*pointer && strnlen(*pointer, prop->length) >= prop->length)
+			return -EILSEQ;
 	}
-	memcpy(val, prop->value.raw_data, nval * item_size);
+
+	*strings = *pointer;
 	return 0;
 }
 
@@ -124,6 +196,18 @@ bool device_property_present(struct devi
 }
 EXPORT_SYMBOL_GPL(device_property_present);
 
+static bool __fwnode_property_present(struct fwnode_handle *fwnode,
+				      const char *propname)
+{
+	if (is_of_node(fwnode))
+		return of_property_read_bool(to_of_node(fwnode), propname);
+	else if (is_acpi_node(fwnode))
+		return !acpi_node_prop_get(fwnode, propname, NULL);
+	else if (is_pset_node(fwnode))
+		return !!pset_prop_get(to_pset_node(fwnode), propname);
+	return false;
+}
+
 /**
  * fwnode_property_present - check if a property of a firmware node is present
  * @fwnode: Firmware node whose property to check
@@ -131,12 +215,12 @@ EXPORT_SYMBOL_GPL(device_property_presen
  */
 bool fwnode_property_present(struct fwnode_handle *fwnode, const char *propname)
 {
-	if (is_of_node(fwnode))
-		return of_property_read_bool(to_of_node(fwnode), propname);
-	else if (is_acpi_node(fwnode))
-		return !acpi_node_prop_get(fwnode, propname, NULL);
+	bool ret;
 
-	return !!pset_prop_get(to_pset(fwnode), propname);
+	ret = __fwnode_property_present(fwnode, propname);
+	if (ret == false && fwnode->secondary)
+		ret = __fwnode_property_present(fwnode->secondary, propname);
+	return ret;
 }
 EXPORT_SYMBOL_GPL(fwnode_property_present);
 
@@ -309,25 +393,40 @@ int device_property_match_string(struct
 }
 EXPORT_SYMBOL_GPL(device_property_match_string);
 
-#define OF_DEV_PROP_READ_ARRAY(node, propname, type, val, nval) \
-	(val) ? of_property_read_##type##_array((node), (propname), (val), (nval)) \
+#define OF_DEV_PROP_READ_ARRAY(node, propname, type, val, nval)				\
+	(val) ? of_property_read_##type##_array((node), (propname), (val), (nval))	\
 	      : of_property_count_elems_of_size((node), (propname), sizeof(type))
 
-#define FWNODE_PROP_READ_ARRAY(_fwnode_, _propname_, _type_, _proptype_, _val_, _nval_) \
-({ \
-	int _ret_; \
-	if (is_of_node(_fwnode_)) \
-		_ret_ = OF_DEV_PROP_READ_ARRAY(to_of_node(_fwnode_), _propname_, \
-					       _type_, _val_, _nval_); \
-	else if (is_acpi_node(_fwnode_)) \
-		_ret_ = acpi_node_prop_read(_fwnode_, _propname_, _proptype_, \
-					    _val_, _nval_); \
-	else if (is_pset(_fwnode_)) \
-		_ret_ = pset_prop_read_array(to_pset(_fwnode_), _propname_, \
-					     _proptype_, _val_, _nval_); \
-	else \
-		_ret_ = -ENXIO; \
-	_ret_; \
+#define PSET_PROP_READ_ARRAY(node, propname, type, val, nval)				\
+	(val) ? pset_prop_read_##type##_array((node), (propname), (val), (nval))	\
+	      : pset_prop_count_elems_of_size((node), (propname), sizeof(type))
+
+#define FWNODE_PROP_READ(_fwnode_, _propname_, _type_, _proptype_, _val_, _nval_)	\
+({											\
+	int _ret_;									\
+	if (is_of_node(_fwnode_))							\
+		_ret_ = OF_DEV_PROP_READ_ARRAY(to_of_node(_fwnode_), _propname_,	\
+					       _type_, _val_, _nval_);			\
+	else if (is_acpi_node(_fwnode_))						\
+		_ret_ = acpi_node_prop_read(_fwnode_, _propname_, _proptype_,		\
+					    _val_, _nval_);				\
+	else if (is_pset_node(_fwnode_)) 						\
+		_ret_ = PSET_PROP_READ_ARRAY(to_pset_node(_fwnode_), _propname_,	\
+					     _type_, _val_, _nval_);			\
+	else										\
+		_ret_ = -ENXIO;								\
+	_ret_;										\
+})
+
+#define FWNODE_PROP_READ_ARRAY(_fwnode_, _propname_, _type_, _proptype_, _val_, _nval_)	\
+({											\
+	int _ret_;									\
+	_ret_ = FWNODE_PROP_READ(_fwnode_, _propname_, _type_, _proptype_,		\
+				 _val_, _nval_);					\
+	if (_ret_ == -EINVAL && _fwnode_->secondary)					\
+		_ret_ = FWNODE_PROP_READ(_fwnode_->secondary, _propname_, _type_,	\
+				_proptype_, _val_, _nval_);				\
+	_ret_;										\
 })
 
 /**
@@ -434,6 +533,41 @@ int fwnode_property_read_u64_array(struc
 }
 EXPORT_SYMBOL_GPL(fwnode_property_read_u64_array);
 
+static int __fwnode_property_read_string_array(struct fwnode_handle *fwnode,
+					       const char *propname,
+					       const char **val, size_t nval)
+{
+	if (is_of_node(fwnode))
+		return val ?
+			of_property_read_string_array(to_of_node(fwnode),
+						      propname, val, nval) :
+			of_property_count_strings(to_of_node(fwnode), propname);
+	else if (is_acpi_node(fwnode))
+		return acpi_node_prop_read(fwnode, propname, DEV_PROP_STRING,
+					   val, nval);
+	else if (is_pset_node(fwnode))
+		return val ?
+			pset_prop_read_string_array(to_pset_node(fwnode),
+						    propname, val, nval) :
+			pset_prop_count_elems_of_size(to_pset_node(fwnode),
+						      propname,
+						      sizeof(const char *));
+	return -ENXIO;
+}
+
+static int __fwnode_property_read_string(struct fwnode_handle *fwnode,
+					 const char *propname, const char **val)
+{
+	if (is_of_node(fwnode))
+		return of_property_read_string(to_of_node(fwnode), propname, val);
+	else if (is_acpi_node(fwnode))
+		return acpi_node_prop_read(fwnode, propname, DEV_PROP_STRING,
+					   val, 1);
+	else if (is_pset_node(fwnode))
+		return pset_prop_read_string(to_pset_node(fwnode), propname, val);
+	return -ENXIO;
+}
+
 /**
  * fwnode_property_read_string_array - return string array property of a node
  * @fwnode: Firmware node to get the property of
@@ -456,18 +590,13 @@ int fwnode_property_read_string_array(st
 				      const char *propname, const char **val,
 				      size_t nval)
 {
-	if (is_of_node(fwnode))
-		return val ?
-			of_property_read_string_array(to_of_node(fwnode),
-						      propname, val, nval) :
-			of_property_count_strings(to_of_node(fwnode), propname);
-	else if (is_acpi_node(fwnode))
-		return acpi_node_prop_read(fwnode, propname, DEV_PROP_STRING,
-					   val, nval);
-	else if (is_pset(fwnode))
-		return pset_prop_read_array(to_pset(fwnode), propname,
-					    DEV_PROP_STRING, val, nval);
-	return -ENXIO;
+	int ret;
+
+	ret = __fwnode_property_read_string_array(fwnode, propname, val, nval);
+	if (ret == -EINVAL && fwnode->secondary)
+		ret = __fwnode_property_read_string_array(fwnode->secondary,
+							  propname, val, nval);
+	return ret;
 }
 EXPORT_SYMBOL_GPL(fwnode_property_read_string_array);
 
@@ -489,14 +618,13 @@ EXPORT_SYMBOL_GPL(fwnode_property_read_s
 int fwnode_property_read_string(struct fwnode_handle *fwnode,
 				const char *propname, const char **val)
 {
-	if (is_of_node(fwnode))
-		return of_property_read_string(to_of_node(fwnode), propname, val);
-	else if (is_acpi_node(fwnode))
-		return acpi_node_prop_read(fwnode, propname, DEV_PROP_STRING,
-					   val, 1);
+	int ret;
 
-	return pset_prop_read_array(to_pset(fwnode), propname,
-				    DEV_PROP_STRING, val, 1);
+	ret = __fwnode_property_read_string(fwnode, propname, val);
+	if (ret == -EINVAL && fwnode->secondary)
+		ret = __fwnode_property_read_string(fwnode->secondary,
+						    propname, val);
+	return ret;
 }
 EXPORT_SYMBOL_GPL(fwnode_property_read_string);
 
@@ -547,6 +675,179 @@ out:
 EXPORT_SYMBOL_GPL(fwnode_property_match_string);
 
 /**
+ * pset_free_set - releases memory allocated for copied property set
+ * @pset: Property set to release
+ *
+ * Function takes previously copied property set and releases all the
+ * memory allocated to it.
+ */
+static void pset_free_set(struct property_set *pset)
+{
+	const struct property_entry *prop;
+	size_t i, nval;
+
+	if (!pset)
+		return;
+
+	for (prop = pset->properties; prop->name; prop++) {
+		if (prop->is_array) {
+			if (prop->is_string && prop->pointer.str) {
+				nval = prop->length / sizeof(const char *);
+				for (i = 0; i < nval; i++)
+					kfree(prop->pointer.str[i]);
+			}
+			kfree(prop->pointer.raw_data);
+		} else if (prop->is_string) {
+			kfree(prop->value.str);
+		}
+		kfree(prop->name);
+	}
+
+	kfree(pset->properties);
+	kfree(pset);
+}
+
+static int pset_copy_entry(struct property_entry *dst,
+			   const struct property_entry *src)
+{
+	const char **d, **s;
+	size_t i, nval;
+
+	dst->name = kstrdup(src->name, GFP_KERNEL);
+	if (!dst->name)
+		return -ENOMEM;
+
+	if (src->is_array) {
+		if (src->is_string) {
+			nval = src->length / sizeof(const char *);
+			dst->pointer.str = kcalloc(nval, sizeof(const char *),
+						   GFP_KERNEL);
+			if (!dst->pointer.str)
+				return -ENOMEM;
+
+			d = dst->pointer.str;
+			s = src->pointer.str;
+			for (i = 0; i < nval; i++) {
+				d[i] = kstrdup(s[i], GFP_KERNEL);
+				if (!d[i] && s[i])
+					return -ENOMEM;
+			}
+		} else {
+			dst->pointer.raw_data = kmemdup(src->pointer.raw_data,
+							src->length, GFP_KERNEL);
+			if (!dst->pointer.raw_data)
+				return -ENOMEM;
+		}
+	} else if (src->is_string) {
+		dst->value.str = kstrdup(src->value.str, GFP_KERNEL);
+		if (!dst->value.str && src->value.str)
+			return -ENOMEM;
+	} else {
+		dst->value.raw_data = src->value.raw_data;
+	}
+
+	dst->length = src->length;
+	dst->is_array = src->is_array;
+	dst->is_string = src->is_string;
+
+	return 0;
+}
+
+/**
+ * pset_copy_set - copies property set
+ * @pset: Property set to copy
+ *
+ * This function takes a deep copy of the given property set and returns
+ * pointer to the copy. Call device_free_property_set() to free resources
+ * allocated in this function.
+ *
+ * Return: Pointer to the new property set or error pointer.
+ */
+static struct property_set *pset_copy_set(const struct property_set *pset)
+{
+	const struct property_entry *entry;
+	struct property_set *p;
+	size_t i, n = 0;
+
+	p = kzalloc(sizeof(*p), GFP_KERNEL);
+	if (!p)
+		return ERR_PTR(-ENOMEM);
+
+	while (pset->properties[n].name)
+		n++;
+
+	p->properties = kcalloc(n + 1, sizeof(*entry), GFP_KERNEL);
+	if (!p->properties) {
+		kfree(p);
+		return ERR_PTR(-ENOMEM);
+	}
+
+	for (i = 0; i < n; i++) {
+		int ret = pset_copy_entry(&p->properties[i],
+					  &pset->properties[i]);
+		if (ret) {
+			pset_free_set(p);
+			return ERR_PTR(ret);
+		}
+	}
+
+	return p;
+}
+
+/**
+ * device_remove_property_set - Remove properties from a device object.
+ * @dev: Device whose properties to remove.
+ *
+ * The function removes properties previously associated to the device
+ * secondary firmware node with device_add_property_set(). Memory allocated
+ * to the properties will also be released.
+ */
+void device_remove_property_set(struct device *dev)
+{
+	struct fwnode_handle *fwnode;
+
+	fwnode = dev_fwnode(dev);
+	if (!fwnode)
+		return;
+	/*
+	 * Pick either primary or secondary node depending which one holds
+	 * the pset. If there is no real firmware node (ACPI/DT) primary
+	 * will hold the pset.
+	 */
+	if (!is_pset_node(fwnode))
+		fwnode = fwnode->secondary;
+	if (!IS_ERR(fwnode) && is_pset_node(fwnode))
+		pset_free_set(to_pset_node(fwnode));
+	set_secondary_fwnode(dev, NULL);
+}
+EXPORT_SYMBOL_GPL(device_remove_property_set);
+
+/**
+ * device_add_property_set - Add a collection of properties to a device object.
+ * @dev: Device to add properties to.
+ * @pset: Collection of properties to add.
+ *
+ * Associate a collection of device properties represented by @pset with @dev
+ * as its secondary firmware node. The function takes a copy of @pset.
+ */
+int device_add_property_set(struct device *dev, const struct property_set *pset)
+{
+	struct property_set *p;
+
+	if (!pset)
+		return -EINVAL;
+
+	p = pset_copy_set(pset);
+	if (IS_ERR(p))
+		return PTR_ERR(p);
+
+	p->fwnode.type = FWNODE_PDATA;
+	set_secondary_fwnode(dev, &p->fwnode);
+	return 0;
+}
+EXPORT_SYMBOL_GPL(device_add_property_set);
+
+/**
  * device_get_next_child_node - Return the next child node handle for a device
  * @dev: Device to find the next child node for.
  * @child: Handle to one of the device's child nodes or a null handle.
--- zfcpdump-kernel-4.4.orig/drivers/base/regmap/regmap-spmi.c
+++ zfcpdump-kernel-4.4/drivers/base/regmap/regmap-spmi.c
@@ -142,7 +142,7 @@ static int regmap_spmi_ext_read(void *co
 	while (val_size) {
 		len = min_t(size_t, val_size, 8);
 
-		err = spmi_ext_register_readl(context, addr, val, val_size);
+		err = spmi_ext_register_readl(context, addr, val, len);
 		if (err)
 			goto err_out;
 
--- zfcpdump-kernel-4.4.orig/drivers/bcma/bcma_private.h
+++ zfcpdump-kernel-4.4/drivers/bcma/bcma_private.h
@@ -8,8 +8,6 @@
 #include <linux/bcma/bcma.h>
 #include <linux/delay.h>
 
-#define BCMA_CORE_SIZE		0x1000
-
 #define bcma_err(bus, fmt, ...) \
 	pr_err("bus%d: " fmt, (bus)->num, ##__VA_ARGS__)
 #define bcma_warn(bus, fmt, ...) \
--- zfcpdump-kernel-4.4.orig/drivers/block/brd.c
+++ zfcpdump-kernel-4.4/drivers/block/brd.c
@@ -338,7 +338,7 @@ static blk_qc_t brd_make_request(struct
 
 	if (unlikely(bio->bi_rw & REQ_DISCARD)) {
 		if (sector & ((PAGE_SIZE >> SECTOR_SHIFT) - 1) ||
-		    bio->bi_iter.bi_size & PAGE_MASK)
+		    bio->bi_iter.bi_size & ~PAGE_MASK)
 			goto io_error;
 		discard_from_brd(brd, sector, bio->bi_iter.bi_size);
 		goto out;
--- zfcpdump-kernel-4.4.orig/drivers/block/loop.c
+++ zfcpdump-kernel-4.4/drivers/block/loop.c
@@ -488,6 +488,12 @@ static int lo_rw_aio(struct loop_device
 	bvec = __bvec_iter_bvec(bio->bi_io_vec, bio->bi_iter);
 	iov_iter_bvec(&iter, ITER_BVEC | rw, bvec,
 		      bio_segments(bio), blk_rq_bytes(cmd->rq));
+	/*
+	 * This bio may be started from the middle of the 'bvec'
+	 * because of bio splitting, so offset from the bvec must
+	 * be passed to iov iterator
+	 */
+	iter.iov_offset = bio->bi_iter.bi_bvec_done;
 
 	cmd->iocb.ki_pos = pos;
 	cmd->iocb.ki_filp = file;
@@ -556,7 +562,7 @@ static int do_req_filebacked(struct loop
 }
 
 struct switch_request {
-	struct file *file;
+	struct file *file, *virt_file;
 	struct completion wait;
 };
 
@@ -582,6 +588,7 @@ static void do_loop_switch(struct loop_d
 	mapping = file->f_mapping;
 	mapping_set_gfp_mask(old_file->f_mapping, lo->old_gfp_mask);
 	lo->lo_backing_file = file;
+	lo->lo_backing_virt_file = p->virt_file;
 	lo->lo_blocksize = S_ISBLK(mapping->host->i_mode) ?
 		mapping->host->i_bdev->bd_block_size : PAGE_SIZE;
 	lo->old_gfp_mask = mapping_gfp_mask(mapping);
@@ -594,11 +601,13 @@ static void do_loop_switch(struct loop_d
  * First it needs to flush existing IO, it does this by sending a magic
  * BIO down the pipe. The completion of this BIO does the actual switch.
  */
-static int loop_switch(struct loop_device *lo, struct file *file)
+static int loop_switch(struct loop_device *lo, struct file *file,
+		       struct file *virt_file)
 {
 	struct switch_request w;
 
 	w.file = file;
+	w.virt_file = virt_file;
 
 	/* freeze queue and wait for completion of scheduled requests */
 	blk_mq_freeze_queue(lo->lo_queue);
@@ -617,7 +626,16 @@ static int loop_switch(struct loop_devic
  */
 static int loop_flush(struct loop_device *lo)
 {
-	return loop_switch(lo, NULL);
+	return loop_switch(lo, NULL, NULL);
+}
+
+static struct file *loop_real_file(struct file *file)
+{
+	struct file *f = NULL;
+
+	if (file->f_path.dentry->d_sb->s_op->real_loop)
+		f = file->f_path.dentry->d_sb->s_op->real_loop(file);
+	return f;
 }
 
 static void loop_reread_partitions(struct loop_device *lo,
@@ -654,6 +672,7 @@ static int loop_change_fd(struct loop_de
 			  unsigned int arg)
 {
 	struct file	*file, *old_file;
+	struct file	*f, *virt_file = NULL, *old_virt_file;
 	struct inode	*inode;
 	int		error;
 
@@ -670,9 +689,16 @@ static int loop_change_fd(struct loop_de
 	file = fget(arg);
 	if (!file)
 		goto out;
+	f = loop_real_file(file);
+	if (f) {
+		virt_file = file;
+		file = f;
+		get_file(file);
+	}
 
 	inode = file->f_mapping->host;
 	old_file = lo->lo_backing_file;
+	old_virt_file = lo->lo_backing_virt_file;
 
 	error = -EINVAL;
 
@@ -684,17 +710,21 @@ static int loop_change_fd(struct loop_de
 		goto out_putf;
 
 	/* and ... switch */
-	error = loop_switch(lo, file);
+	error = loop_switch(lo, file, virt_file);
 	if (error)
 		goto out_putf;
 
 	fput(old_file);
+	if (old_virt_file)
+		fput(old_virt_file);
 	if (lo->lo_flags & LO_FLAGS_PARTSCAN)
 		loop_reread_partitions(lo, bdev);
 	return 0;
 
  out_putf:
 	fput(file);
+	if (virt_file)
+		fput(virt_file);
  out:
 	return error;
 }
@@ -706,6 +736,24 @@ static inline int is_loop_device(struct
 	return i && S_ISBLK(i->i_mode) && MAJOR(i->i_rdev) == LOOP_MAJOR;
 }
 
+/*
+ * for AUFS
+ * no get/put for file.
+ */
+struct file *loop_backing_file(struct super_block *sb)
+{
+	struct file *ret;
+	struct loop_device *l;
+
+	ret = NULL;
+	if (MAJOR(sb->s_dev) == LOOP_MAJOR) {
+		l = sb->s_bdev->bd_disk->private_data;
+		ret = l->lo_backing_file;
+	}
+	return ret;
+}
+EXPORT_SYMBOL(loop_backing_file);
+
 /* loop sysfs attributes */
 
 static ssize_t loop_attr_show(struct device *dev, char *page,
@@ -863,7 +911,7 @@ static int loop_prepare_queue(struct loo
 static int loop_set_fd(struct loop_device *lo, fmode_t mode,
 		       struct block_device *bdev, unsigned int arg)
 {
-	struct file	*file, *f;
+	struct file	*file, *f, *virt_file = NULL;
 	struct inode	*inode;
 	struct address_space *mapping;
 	unsigned lo_blocksize;
@@ -878,6 +926,12 @@ static int loop_set_fd(struct loop_devic
 	file = fget(arg);
 	if (!file)
 		goto out;
+	f = loop_real_file(file);
+	if (f) {
+		virt_file = file;
+		file = f;
+		get_file(file);
+	}
 
 	error = -EBUSY;
 	if (lo->lo_state != Lo_unbound)
@@ -930,6 +984,7 @@ static int loop_set_fd(struct loop_devic
 	lo->lo_device = bdev;
 	lo->lo_flags = lo_flags;
 	lo->lo_backing_file = file;
+	lo->lo_backing_virt_file = virt_file;
 	lo->transfer = NULL;
 	lo->ioctl = NULL;
 	lo->lo_sizelimit = 0;
@@ -962,6 +1017,8 @@ static int loop_set_fd(struct loop_devic
 
  out_putf:
 	fput(file);
+	if (virt_file)
+		fput(virt_file);
  out:
 	/* This is safe: open() is still holding a reference. */
 	module_put(THIS_MODULE);
@@ -1008,6 +1065,7 @@ loop_init_xfer(struct loop_device *lo, s
 static int loop_clr_fd(struct loop_device *lo)
 {
 	struct file *filp = lo->lo_backing_file;
+	struct file *virt_filp = lo->lo_backing_virt_file;
 	gfp_t gfp = lo->old_gfp_mask;
 	struct block_device *bdev = lo->lo_device;
 
@@ -1039,6 +1097,7 @@ static int loop_clr_fd(struct loop_devic
 	spin_lock_irq(&lo->lo_lock);
 	lo->lo_state = Lo_rundown;
 	lo->lo_backing_file = NULL;
+	lo->lo_backing_virt_file = NULL;
 	spin_unlock_irq(&lo->lo_lock);
 
 	loop_release_xfer(lo);
@@ -1083,6 +1142,8 @@ static int loop_clr_fd(struct loop_devic
 	 * bd_mutex which is usually taken before lo_ctl_mutex.
 	 */
 	fput(filp);
+	if (virt_filp)
+		fput(virt_filp);
 	return 0;
 }
 
--- zfcpdump-kernel-4.4.orig/drivers/block/loop.h
+++ zfcpdump-kernel-4.4/drivers/block/loop.h
@@ -46,7 +46,7 @@ struct loop_device {
 	int		(*ioctl)(struct loop_device *, int cmd, 
 				 unsigned long arg); 
 
-	struct file *	lo_backing_file;
+	struct file *	lo_backing_file, *lo_backing_virt_file;
 	struct block_device *lo_device;
 	unsigned	lo_blocksize;
 	void		*key_data; 
--- zfcpdump-kernel-4.4.orig/drivers/block/mtip32xx/mtip32xx.c
+++ zfcpdump-kernel-4.4/drivers/block/mtip32xx/mtip32xx.c
@@ -173,7 +173,13 @@ static struct mtip_cmd *mtip_get_int_com
 {
 	struct request *rq;
 
-	rq = blk_mq_alloc_request(dd->queue, 0, __GFP_RECLAIM, true);
+	if (mtip_check_surprise_removal(dd->pdev))
+		return NULL;
+
+	rq = blk_mq_alloc_request(dd->queue, 0, BLK_MQ_REQ_RESERVED);
+	if (IS_ERR(rq))
+		return NULL;
+
 	return blk_mq_rq_to_pdu(rq);
 }
 
@@ -233,15 +239,9 @@ static void mtip_async_complete(struct m
 			"Command tag %d failed due to TFE\n", tag);
 	}
 
-	/* Unmap the DMA scatter list entries */
-	dma_unmap_sg(&dd->pdev->dev, cmd->sg, cmd->scatter_ents, cmd->direction);
-
 	rq = mtip_rq_from_tag(dd, tag);
 
-	if (unlikely(cmd->unaligned))
-		up(&port->cmd_slot_unal);
-
-	blk_mq_end_request(rq, status ? -EIO : 0);
+	blk_mq_complete_request(rq, status);
 }
 
 /*
@@ -581,6 +581,8 @@ static void mtip_completion(struct mtip_
 		dev_warn(&port->dd->pdev->dev,
 			"Internal command %d completed with TFE\n", tag);
 
+	command->comp_func = NULL;
+	command->comp_data = NULL;
 	complete(waiting);
 }
 
@@ -618,8 +620,6 @@ static void mtip_handle_tfe(struct drive
 
 	port = dd->port;
 
-	set_bit(MTIP_PF_EH_ACTIVE_BIT, &port->flags);
-
 	if (test_bit(MTIP_PF_IC_ACTIVE_BIT, &port->flags)) {
 		cmd = mtip_cmd_from_tag(dd, MTIP_TAG_INTERNAL);
 		dbg_printk(MTIP_DRV_NAME " TFE for the internal command\n");
@@ -628,7 +628,7 @@ static void mtip_handle_tfe(struct drive
 			cmd->comp_func(port, MTIP_TAG_INTERNAL,
 					cmd, PORT_IRQ_TF_ERR);
 		}
-		goto handle_tfe_exit;
+		return;
 	}
 
 	/* clear the tag accumulator */
@@ -701,7 +701,7 @@ static void mtip_handle_tfe(struct drive
 			fail_reason = "thermal shutdown";
 		}
 		if (buf[288] == 0xBF) {
-			set_bit(MTIP_DDF_SEC_LOCK_BIT, &dd->dd_flag);
+			set_bit(MTIP_DDF_REBUILD_FAILED_BIT, &dd->dd_flag);
 			dev_info(&dd->pdev->dev,
 				"Drive indicates rebuild has failed. Secure erase required.\n");
 			fail_all_ncq_cmds = 1;
@@ -771,11 +771,6 @@ static void mtip_handle_tfe(struct drive
 		}
 	}
 	print_tags(dd, "reissued (TFE)", tagaccum, cmd_cnt);
-
-handle_tfe_exit:
-	/* clear eh_active */
-	clear_bit(MTIP_PF_EH_ACTIVE_BIT, &port->flags);
-	wake_up_interruptible(&port->svc_wait);
 }
 
 /*
@@ -1007,6 +1002,7 @@ static bool mtip_pause_ncq(struct mtip_p
 			(fis->features == 0x27 || fis->features == 0x72 ||
 			 fis->features == 0x62 || fis->features == 0x26))) {
 		clear_bit(MTIP_DDF_SEC_LOCK_BIT, &port->dd->dd_flag);
+		clear_bit(MTIP_DDF_REBUILD_FAILED_BIT, &port->dd->dd_flag);
 		/* Com reset after secure erase or lowlevel format */
 		mtip_restart_port(port);
 		clear_bit(MTIP_PF_SE_ACTIVE_BIT, &port->flags);
@@ -1021,12 +1017,14 @@ static bool mtip_pause_ncq(struct mtip_p
  *
  * @port    Pointer to port data structure
  * @timeout Max duration to wait (ms)
+ * @atomic  gfp_t flag to indicate blockable context or not
  *
  * return value
  *	0	Success
  *	-EBUSY  Commands still active
  */
-static int mtip_quiesce_io(struct mtip_port *port, unsigned long timeout)
+static int mtip_quiesce_io(struct mtip_port *port, unsigned long timeout,
+								gfp_t atomic)
 {
 	unsigned long to;
 	unsigned int n;
@@ -1037,16 +1035,21 @@ static int mtip_quiesce_io(struct mtip_p
 	to = jiffies + msecs_to_jiffies(timeout);
 	do {
 		if (test_bit(MTIP_PF_SVC_THD_ACTIVE_BIT, &port->flags) &&
-			test_bit(MTIP_PF_ISSUE_CMDS_BIT, &port->flags)) {
+			test_bit(MTIP_PF_ISSUE_CMDS_BIT, &port->flags) &&
+			atomic == GFP_KERNEL) {
 			msleep(20);
 			continue; /* svc thd is actively issuing commands */
 		}
 
-		msleep(100);
+		if (atomic == GFP_KERNEL)
+			msleep(100);
+		else {
+			cpu_relax();
+			udelay(100);
+		}
+
 		if (mtip_check_surprise_removal(port->dd->pdev))
 			goto err_fault;
-		if (test_bit(MTIP_DDF_REMOVE_PENDING_BIT, &port->dd->dd_flag))
-			goto err_fault;
 
 		/*
 		 * Ignore s_active bit 0 of array element 0.
@@ -1099,6 +1102,7 @@ static int mtip_exec_internal_command(st
 	struct mtip_cmd *int_cmd;
 	struct driver_data *dd = port->dd;
 	int rv = 0;
+	unsigned long start;
 
 	/* Make sure the buffer is 8 byte aligned. This is asic specific. */
 	if (buffer & 0x00000007) {
@@ -1107,6 +1111,10 @@ static int mtip_exec_internal_command(st
 	}
 
 	int_cmd = mtip_get_int_command(dd);
+	if (!int_cmd) {
+		dbg_printk(MTIP_DRV_NAME "Unable to allocate tag for PIO cmd\n");
+		return -EFAULT;
+	}
 
 	set_bit(MTIP_PF_IC_ACTIVE_BIT, &port->flags);
 
@@ -1119,7 +1127,7 @@ static int mtip_exec_internal_command(st
 		if (fis->command != ATA_CMD_STANDBYNOW1) {
 			/* wait for io to complete if non atomic */
 			if (mtip_quiesce_io(port,
-					MTIP_QUIESCE_IO_TIMEOUT_MS) < 0) {
+				MTIP_QUIESCE_IO_TIMEOUT_MS, atomic) < 0) {
 				dev_warn(&dd->pdev->dev,
 					"Failed to quiesce IO\n");
 				mtip_put_int_command(dd, int_cmd);
@@ -1162,6 +1170,8 @@ static int mtip_exec_internal_command(st
 	/* Populate the command header */
 	int_cmd->command_header->byte_count = 0;
 
+	start = jiffies;
+
 	/* Issue the command to the hardware */
 	mtip_issue_non_ncq_command(port, MTIP_TAG_INTERNAL);
 
@@ -1170,10 +1180,12 @@ static int mtip_exec_internal_command(st
 		if ((rv = wait_for_completion_interruptible_timeout(
 				&wait,
 				msecs_to_jiffies(timeout))) <= 0) {
+
 			if (rv == -ERESTARTSYS) { /* interrupted */
 				dev_err(&dd->pdev->dev,
-					"Internal command [%02X] was interrupted after %lu ms\n",
-					fis->command, timeout);
+					"Internal command [%02X] was interrupted after %u ms\n",
+					fis->command,
+					jiffies_to_msecs(jiffies - start));
 				rv = -EINTR;
 				goto exec_ic_exit;
 			} else if (rv == 0) /* timeout */
@@ -2897,6 +2909,42 @@ static int mtip_ftl_rebuild_poll(struct
 	return -EFAULT;
 }
 
+static void mtip_softirq_done_fn(struct request *rq)
+{
+	struct mtip_cmd *cmd = blk_mq_rq_to_pdu(rq);
+	struct driver_data *dd = rq->q->queuedata;
+
+	/* Unmap the DMA scatter list entries */
+	dma_unmap_sg(&dd->pdev->dev, cmd->sg, cmd->scatter_ents,
+							cmd->direction);
+
+	if (unlikely(cmd->unaligned))
+		up(&dd->port->cmd_slot_unal);
+
+	blk_mq_end_request(rq, rq->errors);
+}
+
+static void mtip_abort_cmd(struct request *req, void *data,
+							bool reserved)
+{
+	struct driver_data *dd = data;
+
+	dbg_printk(MTIP_DRV_NAME " Aborting request, tag = %d\n", req->tag);
+
+	clear_bit(req->tag, dd->port->cmds_to_issue);
+	req->errors = -EIO;
+	mtip_softirq_done_fn(req);
+}
+
+static void mtip_queue_cmd(struct request *req, void *data,
+							bool reserved)
+{
+	struct driver_data *dd = data;
+
+	set_bit(req->tag, dd->port->cmds_to_issue);
+	blk_abort_request(req);
+}
+
 /*
  * service thread to issue queued commands
  *
@@ -2909,7 +2957,7 @@ static int mtip_ftl_rebuild_poll(struct
 static int mtip_service_thread(void *data)
 {
 	struct driver_data *dd = (struct driver_data *)data;
-	unsigned long slot, slot_start, slot_wrap;
+	unsigned long slot, slot_start, slot_wrap, to;
 	unsigned int num_cmd_slots = dd->slot_groups * 32;
 	struct mtip_port *port = dd->port;
 
@@ -2924,9 +2972,7 @@ static int mtip_service_thread(void *dat
 		 * is in progress nor error handling is active
 		 */
 		wait_event_interruptible(port->svc_wait, (port->flags) &&
-			!(port->flags & MTIP_PF_PAUSE_IO));
-
-		set_bit(MTIP_PF_SVC_THD_ACTIVE_BIT, &port->flags);
+			(port->flags & MTIP_PF_SVC_THD_WORK));
 
 		if (kthread_should_stop() ||
 			test_bit(MTIP_PF_SVC_THD_STOP_BIT, &port->flags))
@@ -2936,6 +2982,8 @@ static int mtip_service_thread(void *dat
 				&dd->dd_flag)))
 			goto st_out;
 
+		set_bit(MTIP_PF_SVC_THD_ACTIVE_BIT, &port->flags);
+
 restart_eh:
 		/* Demux bits: start with error handling */
 		if (test_bit(MTIP_PF_EH_ACTIVE_BIT, &port->flags)) {
@@ -2946,6 +2994,32 @@ restart_eh:
 		if (test_bit(MTIP_PF_EH_ACTIVE_BIT, &port->flags))
 			goto restart_eh;
 
+		if (test_bit(MTIP_PF_TO_ACTIVE_BIT, &port->flags)) {
+			to = jiffies + msecs_to_jiffies(5000);
+
+			do {
+				mdelay(100);
+			} while (atomic_read(&dd->irq_workers_active) != 0 &&
+				time_before(jiffies, to));
+
+			if (atomic_read(&dd->irq_workers_active) != 0)
+				dev_warn(&dd->pdev->dev,
+					"Completion workers still active!");
+
+			spin_lock(dd->queue->queue_lock);
+			blk_mq_all_tag_busy_iter(*dd->tags.tags,
+							mtip_queue_cmd, dd);
+			spin_unlock(dd->queue->queue_lock);
+
+			set_bit(MTIP_PF_ISSUE_CMDS_BIT, &dd->port->flags);
+
+			if (mtip_device_reset(dd))
+				blk_mq_all_tag_busy_iter(*dd->tags.tags,
+							mtip_abort_cmd, dd);
+
+			clear_bit(MTIP_PF_TO_ACTIVE_BIT, &dd->port->flags);
+		}
+
 		if (test_bit(MTIP_PF_ISSUE_CMDS_BIT, &port->flags)) {
 			slot = 1;
 			/* used to restrict the loop to one iteration */
@@ -2978,10 +3052,8 @@ restart_eh:
 		}
 
 		if (test_bit(MTIP_PF_REBUILD_BIT, &port->flags)) {
-			if (mtip_ftl_rebuild_poll(dd) < 0)
-				set_bit(MTIP_DDF_REBUILD_FAILED_BIT,
-							&dd->dd_flag);
-			clear_bit(MTIP_PF_REBUILD_BIT, &port->flags);
+			if (mtip_ftl_rebuild_poll(dd) == 0)
+				clear_bit(MTIP_PF_REBUILD_BIT, &port->flags);
 		}
 	}
 
@@ -3096,7 +3168,7 @@ static int mtip_hw_get_identify(struct d
 		if (buf[288] == 0xBF) {
 			dev_info(&dd->pdev->dev,
 				"Drive indicates rebuild has failed.\n");
-			/* TODO */
+			set_bit(MTIP_DDF_REBUILD_FAILED_BIT, &dd->dd_flag);
 		}
 	}
 
@@ -3270,20 +3342,25 @@ out1:
 	return rv;
 }
 
-static void mtip_standby_drive(struct driver_data *dd)
+static int mtip_standby_drive(struct driver_data *dd)
 {
-	if (dd->sr)
-		return;
+	int rv = 0;
 
+	if (dd->sr || !dd->port)
+		return -ENODEV;
 	/*
 	 * Send standby immediate (E0h) to the drive so that it
 	 * saves its state.
 	 */
 	if (!test_bit(MTIP_PF_REBUILD_BIT, &dd->port->flags) &&
-	    !test_bit(MTIP_DDF_SEC_LOCK_BIT, &dd->dd_flag))
-		if (mtip_standby_immediate(dd->port))
+	    !test_bit(MTIP_DDF_REBUILD_FAILED_BIT, &dd->dd_flag) &&
+	    !test_bit(MTIP_DDF_SEC_LOCK_BIT, &dd->dd_flag)) {
+		rv = mtip_standby_immediate(dd->port);
+		if (rv)
 			dev_warn(&dd->pdev->dev,
 				"STANDBY IMMEDIATE failed\n");
+	}
+	return rv;
 }
 
 /*
@@ -3296,10 +3373,6 @@ static void mtip_standby_drive(struct dr
  */
 static int mtip_hw_exit(struct driver_data *dd)
 {
-	/*
-	 * Send standby immediate (E0h) to the drive so that it
-	 * saves its state.
-	 */
 	if (!dd->sr) {
 		/* de-initialize the port. */
 		mtip_deinit_port(dd->port);
@@ -3341,8 +3414,7 @@ static int mtip_hw_shutdown(struct drive
 	 * Send standby immediate (E0h) to the drive so that it
 	 * saves its state.
 	 */
-	if (!dd->sr && dd->port)
-		mtip_standby_immediate(dd->port);
+	mtip_standby_drive(dd);
 
 	return 0;
 }
@@ -3365,7 +3437,7 @@ static int mtip_hw_suspend(struct driver
 	 * Send standby immediate (E0h) to the drive
 	 * so that it saves its state.
 	 */
-	if (mtip_standby_immediate(dd->port) != 0) {
+	if (mtip_standby_drive(dd) != 0) {
 		dev_err(&dd->pdev->dev,
 			"Failed standby-immediate command\n");
 		return -EFAULT;
@@ -3603,6 +3675,28 @@ static int mtip_block_getgeo(struct bloc
 	return 0;
 }
 
+static int mtip_block_open(struct block_device *dev, fmode_t mode)
+{
+	struct driver_data *dd;
+
+	if (dev && dev->bd_disk) {
+		dd = (struct driver_data *) dev->bd_disk->private_data;
+
+		if (dd) {
+			if (test_bit(MTIP_DDF_REMOVAL_BIT,
+							&dd->dd_flag)) {
+				return -ENODEV;
+			}
+			return 0;
+		}
+	}
+	return -ENODEV;
+}
+
+void mtip_block_release(struct gendisk *disk, fmode_t mode)
+{
+}
+
 /*
  * Block device operation function.
  *
@@ -3610,6 +3704,8 @@ static int mtip_block_getgeo(struct bloc
  * layer.
  */
 static const struct block_device_operations mtip_block_ops = {
+	.open		= mtip_block_open,
+	.release	= mtip_block_release,
 	.ioctl		= mtip_block_ioctl,
 #ifdef CONFIG_COMPAT
 	.compat_ioctl	= mtip_block_compat_ioctl,
@@ -3671,10 +3767,9 @@ static int mtip_submit_request(struct bl
 				rq_data_dir(rq))) {
 			return -ENODATA;
 		}
-		if (unlikely(test_bit(MTIP_DDF_SEC_LOCK_BIT, &dd->dd_flag)))
+		if (unlikely(test_bit(MTIP_DDF_SEC_LOCK_BIT, &dd->dd_flag) ||
+			test_bit(MTIP_DDF_REBUILD_FAILED_BIT, &dd->dd_flag)))
 			return -ENODATA;
-		if (test_bit(MTIP_DDF_REBUILD_FAILED_BIT, &dd->dd_flag))
-			return -ENXIO;
 	}
 
 	if (rq->cmd_flags & REQ_DISCARD) {
@@ -3786,11 +3881,33 @@ static int mtip_init_cmd(void *data, str
 	return 0;
 }
 
+static enum blk_eh_timer_return mtip_cmd_timeout(struct request *req,
+								bool reserved)
+{
+	struct driver_data *dd = req->q->queuedata;
+	int ret = BLK_EH_RESET_TIMER;
+
+	if (reserved)
+		goto exit_handler;
+
+	if (test_bit(req->tag, dd->port->cmds_to_issue))
+		goto exit_handler;
+
+	if (test_and_set_bit(MTIP_PF_TO_ACTIVE_BIT, &dd->port->flags))
+		goto exit_handler;
+
+	wake_up_interruptible(&dd->port->svc_wait);
+exit_handler:
+	return ret;
+}
+
 static struct blk_mq_ops mtip_mq_ops = {
 	.queue_rq	= mtip_queue_rq,
 	.map_queue	= blk_mq_map_queue,
 	.init_request	= mtip_init_cmd,
 	.exit_request	= mtip_free_cmd,
+	.complete	= mtip_softirq_done_fn,
+	.timeout        = mtip_cmd_timeout,
 };
 
 /*
@@ -3857,7 +3974,6 @@ static int mtip_block_initialize(struct
 
 	mtip_hw_debugfs_init(dd);
 
-skip_create_disk:
 	memset(&dd->tags, 0, sizeof(dd->tags));
 	dd->tags.ops = &mtip_mq_ops;
 	dd->tags.nr_hw_queues = 1;
@@ -3867,12 +3983,13 @@ skip_create_disk:
 	dd->tags.numa_node = dd->numa_node;
 	dd->tags.flags = BLK_MQ_F_SHOULD_MERGE;
 	dd->tags.driver_data = dd;
+	dd->tags.timeout = MTIP_NCQ_CMD_TIMEOUT_MS;
 
 	rv = blk_mq_alloc_tag_set(&dd->tags);
 	if (rv) {
 		dev_err(&dd->pdev->dev,
 			"Unable to allocate request queue\n");
-		goto block_queue_alloc_init_error;
+		goto block_queue_alloc_tag_error;
 	}
 
 	/* Allocate the request queue. */
@@ -3887,6 +4004,7 @@ skip_create_disk:
 	dd->disk->queue		= dd->queue;
 	dd->queue->queuedata	= dd;
 
+skip_create_disk:
 	/* Initialize the protocol layer. */
 	wait_for_rebuild = mtip_hw_get_identify(dd);
 	if (wait_for_rebuild < 0) {
@@ -3983,8 +4101,9 @@ kthread_run_error:
 read_capacity_error:
 init_hw_cmds_error:
 	blk_cleanup_queue(dd->queue);
-	blk_mq_free_tag_set(&dd->tags);
 block_queue_alloc_init_error:
+	blk_mq_free_tag_set(&dd->tags);
+block_queue_alloc_tag_error:
 	mtip_hw_debugfs_exit(dd);
 disk_index_error:
 	spin_lock(&rssd_index_lock);
@@ -4001,6 +4120,22 @@ protocol_init_error:
 	return rv;
 }
 
+static void mtip_no_dev_cleanup(struct request *rq, void *data, bool reserv)
+{
+	struct driver_data *dd = (struct driver_data *)data;
+	struct mtip_cmd *cmd;
+
+	if (likely(!reserv))
+		blk_mq_complete_request(rq, -ENODEV);
+	else if (test_bit(MTIP_PF_IC_ACTIVE_BIT, &dd->port->flags)) {
+
+		cmd = mtip_cmd_from_tag(dd, MTIP_TAG_INTERNAL);
+		if (cmd->comp_func)
+			cmd->comp_func(dd->port, MTIP_TAG_INTERNAL,
+					cmd, -ENODEV);
+	}
+}
+
 /*
  * Block layer deinitialization function.
  *
@@ -4032,12 +4167,23 @@ static int mtip_block_remove(struct driv
 		}
 	}
 
-	if (!dd->sr)
-		mtip_standby_drive(dd);
+	if (!dd->sr) {
+		/*
+		 * Explicitly wait here for IOs to quiesce,
+		 * as mtip_standby_drive usually won't wait for IOs.
+		 */
+		if (!mtip_quiesce_io(dd->port, MTIP_QUIESCE_IO_TIMEOUT_MS,
+								GFP_KERNEL))
+			mtip_standby_drive(dd);
+	}
 	else
 		dev_info(&dd->pdev->dev, "device %s surprise removal\n",
 						dd->disk->disk_name);
 
+	blk_mq_freeze_queue_start(dd->queue);
+	blk_mq_stop_hw_queues(dd->queue);
+	blk_mq_all_tag_busy_iter(dd->tags.tags[0], mtip_no_dev_cleanup, dd);
+
 	/*
 	 * Delete our gendisk structure. This also removes the device
 	 * from /dev
@@ -4047,7 +4193,8 @@ static int mtip_block_remove(struct driv
 		dd->bdev = NULL;
 	}
 	if (dd->disk) {
-		del_gendisk(dd->disk);
+		if (test_bit(MTIP_DDF_INIT_DONE_BIT, &dd->dd_flag))
+			del_gendisk(dd->disk);
 		if (dd->disk->queue) {
 			blk_cleanup_queue(dd->queue);
 			blk_mq_free_tag_set(&dd->tags);
@@ -4088,7 +4235,8 @@ static int mtip_block_shutdown(struct dr
 		dev_info(&dd->pdev->dev,
 			"Shutting down %s ...\n", dd->disk->disk_name);
 
-		del_gendisk(dd->disk);
+		if (test_bit(MTIP_DDF_INIT_DONE_BIT, &dd->dd_flag))
+			del_gendisk(dd->disk);
 		if (dd->disk->queue) {
 			blk_cleanup_queue(dd->queue);
 			blk_mq_free_tag_set(&dd->tags);
@@ -4433,7 +4581,7 @@ static void mtip_pci_remove(struct pci_d
 	struct driver_data *dd = pci_get_drvdata(pdev);
 	unsigned long flags, to;
 
-	set_bit(MTIP_DDF_REMOVE_PENDING_BIT, &dd->dd_flag);
+	set_bit(MTIP_DDF_REMOVAL_BIT, &dd->dd_flag);
 
 	spin_lock_irqsave(&dev_lock, flags);
 	list_del_init(&dd->online_list);
@@ -4450,12 +4598,17 @@ static void mtip_pci_remove(struct pci_d
 	} while (atomic_read(&dd->irq_workers_active) != 0 &&
 		time_before(jiffies, to));
 
+	if (!dd->sr)
+		fsync_bdev(dd->bdev);
+
 	if (atomic_read(&dd->irq_workers_active) != 0) {
 		dev_warn(&dd->pdev->dev,
 			"Completion workers still active!\n");
 	}
 
-	blk_mq_stop_hw_queues(dd->queue);
+	blk_set_queue_dying(dd->queue);
+	set_bit(MTIP_DDF_REMOVE_PENDING_BIT, &dd->dd_flag);
+
 	/* Clean up the block layer. */
 	mtip_block_remove(dd);
 
--- zfcpdump-kernel-4.4.orig/drivers/block/mtip32xx/mtip32xx.h
+++ zfcpdump-kernel-4.4/drivers/block/mtip32xx/mtip32xx.h
@@ -134,16 +134,24 @@ enum {
 	MTIP_PF_EH_ACTIVE_BIT       = 1, /* error handling */
 	MTIP_PF_SE_ACTIVE_BIT       = 2, /* secure erase */
 	MTIP_PF_DM_ACTIVE_BIT       = 3, /* download microcde */
+	MTIP_PF_TO_ACTIVE_BIT       = 9, /* timeout handling */
 	MTIP_PF_PAUSE_IO      =	((1 << MTIP_PF_IC_ACTIVE_BIT) |
 				(1 << MTIP_PF_EH_ACTIVE_BIT) |
 				(1 << MTIP_PF_SE_ACTIVE_BIT) |
-				(1 << MTIP_PF_DM_ACTIVE_BIT)),
+				(1 << MTIP_PF_DM_ACTIVE_BIT) |
+				(1 << MTIP_PF_TO_ACTIVE_BIT)),
 
 	MTIP_PF_SVC_THD_ACTIVE_BIT  = 4,
 	MTIP_PF_ISSUE_CMDS_BIT      = 5,
 	MTIP_PF_REBUILD_BIT         = 6,
 	MTIP_PF_SVC_THD_STOP_BIT    = 8,
 
+	MTIP_PF_SVC_THD_WORK	= ((1 << MTIP_PF_EH_ACTIVE_BIT) |
+				  (1 << MTIP_PF_ISSUE_CMDS_BIT) |
+				  (1 << MTIP_PF_REBUILD_BIT) |
+				  (1 << MTIP_PF_SVC_THD_STOP_BIT) |
+				  (1 << MTIP_PF_TO_ACTIVE_BIT)),
+
 	/* below are bit numbers in 'dd_flag' defined in driver_data */
 	MTIP_DDF_SEC_LOCK_BIT	    = 0,
 	MTIP_DDF_REMOVE_PENDING_BIT = 1,
@@ -153,6 +161,7 @@ enum {
 	MTIP_DDF_RESUME_BIT         = 6,
 	MTIP_DDF_INIT_DONE_BIT      = 7,
 	MTIP_DDF_REBUILD_FAILED_BIT = 8,
+	MTIP_DDF_REMOVAL_BIT	    = 9,
 
 	MTIP_DDF_STOP_IO      = ((1 << MTIP_DDF_REMOVE_PENDING_BIT) |
 				(1 << MTIP_DDF_SEC_LOCK_BIT) |
--- zfcpdump-kernel-4.4.orig/drivers/block/nbd.c
+++ zfcpdump-kernel-4.4/drivers/block/nbd.c
@@ -79,7 +79,7 @@ static struct dentry *nbd_dbg_dir;
 
 static unsigned int nbds_max = 16;
 static struct nbd_device *nbd_dev;
-static int max_part;
+static int max_part = 15;
 
 /*
  * Use just one lock (or at most 1 per NIC). Two arguments for this:
@@ -618,8 +618,8 @@ static void nbd_request_handler(struct r
 			req, req->cmd_type);
 
 		if (unlikely(!nbd->sock)) {
-			dev_err(disk_to_dev(nbd->disk),
-				"Attempted send on closed socket\n");
+			dev_err_ratelimited(disk_to_dev(nbd->disk),
+					    "Attempted send on closed socket\n");
 			req->errors++;
 			nbd_end_request(nbd, req);
 			spin_lock_irq(q->queue_lock);
--- zfcpdump-kernel-4.4.orig/drivers/block/null_blk.c
+++ zfcpdump-kernel-4.4/drivers/block/null_blk.c
@@ -436,9 +436,8 @@ static void null_del_dev(struct nullb *n
 static void null_lnvm_end_io(struct request *rq, int error)
 {
 	struct nvm_rq *rqd = rq->end_io_data;
-	struct nvm_dev *dev = rqd->dev;
 
-	dev->mt->end_io(rqd, error);
+	nvm_end_io(rqd, error);
 
 	blk_put_request(rq);
 }
@@ -449,7 +448,7 @@ static int null_lnvm_submit_io(struct nv
 	struct request *rq;
 	struct bio *bio = rqd->bio;
 
-	rq = blk_mq_alloc_request(q, bio_rw(bio), GFP_KERNEL, 0);
+	rq = blk_mq_alloc_request(q, bio_rw(bio), 0);
 	if (IS_ERR(rq))
 		return -ENOMEM;
 
--- zfcpdump-kernel-4.4.orig/drivers/block/paride/pd.c
+++ zfcpdump-kernel-4.4/drivers/block/paride/pd.c
@@ -126,7 +126,7 @@
 */
 #include <linux/types.h>
 
-static bool verbose = 0;
+static int verbose = 0;
 static int major = PD_MAJOR;
 static char *name = PD_NAME;
 static int cluster = 64;
@@ -161,7 +161,7 @@ enum {D_PRT, D_PRO, D_UNI, D_MOD, D_GEO,
 static DEFINE_MUTEX(pd_mutex);
 static DEFINE_SPINLOCK(pd_lock);
 
-module_param(verbose, bool, 0);
+module_param(verbose, int, 0);
 module_param(major, int, 0);
 module_param(name, charp, 0);
 module_param(cluster, int, 0);
--- zfcpdump-kernel-4.4.orig/drivers/block/paride/pt.c
+++ zfcpdump-kernel-4.4/drivers/block/paride/pt.c
@@ -117,7 +117,7 @@
 
 */
 
-static bool verbose = 0;
+static int verbose = 0;
 static int major = PT_MAJOR;
 static char *name = PT_NAME;
 static int disable = 0;
@@ -152,7 +152,7 @@ static int (*drives[4])[6] = {&drive0, &
 
 #include <asm/uaccess.h>
 
-module_param(verbose, bool, 0);
+module_param(verbose, int, 0);
 module_param(major, int, 0);
 module_param(name, charp, 0);
 module_param_array(drive0, int, NULL, 0);
--- zfcpdump-kernel-4.4.orig/drivers/block/rbd.c
+++ zfcpdump-kernel-4.4/drivers/block/rbd.c
@@ -1955,7 +1955,7 @@ static struct ceph_osd_request *rbd_osd_
 
 	osdc = &rbd_dev->rbd_client->client->osdc;
 	osd_req = ceph_osdc_alloc_request(osdc, snapc, num_ops, false,
-					  GFP_ATOMIC);
+					  GFP_NOIO);
 	if (!osd_req)
 		return NULL;	/* ENOMEM */
 
@@ -2004,7 +2004,7 @@ rbd_osd_req_create_copyup(struct rbd_obj
 	rbd_dev = img_request->rbd_dev;
 	osdc = &rbd_dev->rbd_client->client->osdc;
 	osd_req = ceph_osdc_alloc_request(osdc, snapc, num_osd_ops,
-						false, GFP_ATOMIC);
+						false, GFP_NOIO);
 	if (!osd_req)
 		return NULL;	/* ENOMEM */
 
@@ -2506,7 +2506,7 @@ static int rbd_img_request_fill(struct r
 					bio_chain_clone_range(&bio_list,
 								&bio_offset,
 								clone_size,
-								GFP_ATOMIC);
+								GFP_NOIO);
 			if (!obj_request->bio_list)
 				goto out_unwind;
 		} else if (type == OBJ_REQUEST_PAGES) {
--- zfcpdump-kernel-4.4.orig/drivers/block/zram/zcomp.c
+++ zfcpdump-kernel-4.4/drivers/block/zram/zcomp.c
@@ -76,7 +76,7 @@ static void zcomp_strm_free(struct zcomp
  */
 static struct zcomp_strm *zcomp_strm_alloc(struct zcomp *comp)
 {
-	struct zcomp_strm *zstrm = kmalloc(sizeof(*zstrm), GFP_KERNEL);
+	struct zcomp_strm *zstrm = kmalloc(sizeof(*zstrm), GFP_NOIO);
 	if (!zstrm)
 		return NULL;
 
@@ -85,7 +85,7 @@ static struct zcomp_strm *zcomp_strm_all
 	 * allocate 2 pages. 1 for compressed data, plus 1 extra for the
 	 * case when compressed size is larger than the original one
 	 */
-	zstrm->buffer = (void *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, 1);
+	zstrm->buffer = (void *)__get_free_pages(GFP_NOIO | __GFP_ZERO, 1);
 	if (!zstrm->private || !zstrm->buffer) {
 		zcomp_strm_free(comp, zstrm);
 		zstrm = NULL;
--- zfcpdump-kernel-4.4.orig/drivers/block/zram/zcomp_lz4.c
+++ zfcpdump-kernel-4.4/drivers/block/zram/zcomp_lz4.c
@@ -10,17 +10,36 @@
 #include <linux/kernel.h>
 #include <linux/slab.h>
 #include <linux/lz4.h>
+#include <linux/vmalloc.h>
+#include <linux/mm.h>
 
 #include "zcomp_lz4.h"
 
 static void *zcomp_lz4_create(void)
 {
-	return kzalloc(LZ4_MEM_COMPRESS, GFP_KERNEL);
+	void *ret;
+
+	/*
+	 * This function can be called in swapout/fs write path
+	 * so we can't use GFP_FS|IO. And it assumes we already
+	 * have at least one stream in zram initialization so we
+	 * don't do best effort to allocate more stream in here.
+	 * A default stream will work well without further multiple
+	 * streams. That's why we use NORETRY | NOWARN.
+	 */
+	ret = kzalloc(LZ4_MEM_COMPRESS, GFP_NOIO | __GFP_NORETRY |
+					__GFP_NOWARN);
+	if (!ret)
+		ret = __vmalloc(LZ4_MEM_COMPRESS,
+				GFP_NOIO | __GFP_NORETRY | __GFP_NOWARN |
+				__GFP_ZERO | __GFP_HIGHMEM,
+				PAGE_KERNEL);
+	return ret;
 }
 
 static void zcomp_lz4_destroy(void *private)
 {
-	kfree(private);
+	kvfree(private);
 }
 
 static int zcomp_lz4_compress(const unsigned char *src, unsigned char *dst,
--- zfcpdump-kernel-4.4.orig/drivers/block/zram/zcomp_lzo.c
+++ zfcpdump-kernel-4.4/drivers/block/zram/zcomp_lzo.c
@@ -10,17 +10,36 @@
 #include <linux/kernel.h>
 #include <linux/slab.h>
 #include <linux/lzo.h>
+#include <linux/vmalloc.h>
+#include <linux/mm.h>
 
 #include "zcomp_lzo.h"
 
 static void *lzo_create(void)
 {
-	return kzalloc(LZO1X_MEM_COMPRESS, GFP_KERNEL);
+	void *ret;
+
+	/*
+	 * This function can be called in swapout/fs write path
+	 * so we can't use GFP_FS|IO. And it assumes we already
+	 * have at least one stream in zram initialization so we
+	 * don't do best effort to allocate more stream in here.
+	 * A default stream will work well without further multiple
+	 * streams. That's why we use NORETRY | NOWARN.
+	 */
+	ret = kzalloc(LZO1X_MEM_COMPRESS, GFP_NOIO | __GFP_NORETRY |
+					__GFP_NOWARN);
+	if (!ret)
+		ret = __vmalloc(LZO1X_MEM_COMPRESS,
+				GFP_NOIO | __GFP_NORETRY | __GFP_NOWARN |
+				__GFP_ZERO | __GFP_HIGHMEM,
+				PAGE_KERNEL);
+	return ret;
 }
 
 static void lzo_destroy(void *private)
 {
-	kfree(private);
+	kvfree(private);
 }
 
 static int lzo_compress(const unsigned char *src, unsigned char *dst,
--- zfcpdump-kernel-4.4.orig/drivers/block/zram/zram_drv.c
+++ zfcpdump-kernel-4.4/drivers/block/zram/zram_drv.c
@@ -1325,7 +1325,6 @@ static int zram_remove(struct zram *zram
 
 	pr_info("Removed device: %s\n", zram->disk->disk_name);
 
-	idr_remove(&zram_index_idr, zram->disk->first_minor);
 	blk_cleanup_queue(zram->disk->queue);
 	del_gendisk(zram->disk);
 	put_disk(zram->disk);
@@ -1367,10 +1366,12 @@ static ssize_t hot_remove_store(struct c
 	mutex_lock(&zram_index_mutex);
 
 	zram = idr_find(&zram_index_idr, dev_id);
-	if (zram)
+	if (zram) {
 		ret = zram_remove(zram);
-	else
+		idr_remove(&zram_index_idr, dev_id);
+	} else {
 		ret = -ENODEV;
+	}
 
 	mutex_unlock(&zram_index_mutex);
 	return ret ? ret : count;
--- zfcpdump-kernel-4.4.orig/drivers/bluetooth/ath3k.c
+++ zfcpdump-kernel-4.4/drivers/bluetooth/ath3k.c
@@ -82,6 +82,7 @@ static const struct usb_device_id ath3k_
 	{ USB_DEVICE(0x0489, 0xe05f) },
 	{ USB_DEVICE(0x0489, 0xe076) },
 	{ USB_DEVICE(0x0489, 0xe078) },
+	{ USB_DEVICE(0x0489, 0xe095) },
 	{ USB_DEVICE(0x04c5, 0x1330) },
 	{ USB_DEVICE(0x04CA, 0x3004) },
 	{ USB_DEVICE(0x04CA, 0x3005) },
@@ -92,6 +93,7 @@ static const struct usb_device_id ath3k_
 	{ USB_DEVICE(0x04CA, 0x300d) },
 	{ USB_DEVICE(0x04CA, 0x300f) },
 	{ USB_DEVICE(0x04CA, 0x3010) },
+	{ USB_DEVICE(0x04CA, 0x3014) },
 	{ USB_DEVICE(0x0930, 0x0219) },
 	{ USB_DEVICE(0x0930, 0x021c) },
 	{ USB_DEVICE(0x0930, 0x0220) },
@@ -113,10 +115,12 @@ static const struct usb_device_id ath3k_
 	{ USB_DEVICE(0x13d3, 0x3362) },
 	{ USB_DEVICE(0x13d3, 0x3375) },
 	{ USB_DEVICE(0x13d3, 0x3393) },
+	{ USB_DEVICE(0x13d3, 0x3395) },
 	{ USB_DEVICE(0x13d3, 0x3402) },
 	{ USB_DEVICE(0x13d3, 0x3408) },
 	{ USB_DEVICE(0x13d3, 0x3423) },
 	{ USB_DEVICE(0x13d3, 0x3432) },
+	{ USB_DEVICE(0x13d3, 0x3472) },
 	{ USB_DEVICE(0x13d3, 0x3474) },
 
 	/* Atheros AR5BBU12 with sflash firmware */
@@ -144,6 +148,7 @@ static const struct usb_device_id ath3k_
 	{ USB_DEVICE(0x0489, 0xe05f), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x0489, 0xe076), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x0489, 0xe078), .driver_info = BTUSB_ATH3012 },
+	{ USB_DEVICE(0x0489, 0xe095), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x04c5, 0x1330), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x04ca, 0x3004), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 },
@@ -154,6 +159,7 @@ static const struct usb_device_id ath3k_
 	{ USB_DEVICE(0x04ca, 0x300d), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x04ca, 0x300f), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x04ca, 0x3010), .driver_info = BTUSB_ATH3012 },
+	{ USB_DEVICE(0x04ca, 0x3014), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x0930, 0x0219), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x0930, 0x021c), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x0930, 0x0220), .driver_info = BTUSB_ATH3012 },
@@ -175,10 +181,12 @@ static const struct usb_device_id ath3k_
 	{ USB_DEVICE(0x13d3, 0x3362), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x13d3, 0x3375), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x13d3, 0x3393), .driver_info = BTUSB_ATH3012 },
+	{ USB_DEVICE(0x13d3, 0x3395), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x13d3, 0x3402), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x13d3, 0x3408), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x13d3, 0x3423), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x13d3, 0x3432), .driver_info = BTUSB_ATH3012 },
+	{ USB_DEVICE(0x13d3, 0x3472), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x13d3, 0x3474), .driver_info = BTUSB_ATH3012 },
 
 	/* Atheros AR5BBU22 with sflash firmware */
--- zfcpdump-kernel-4.4.orig/drivers/bluetooth/btusb.c
+++ zfcpdump-kernel-4.4/drivers/bluetooth/btusb.c
@@ -24,6 +24,7 @@
 #include <linux/module.h>
 #include <linux/usb.h>
 #include <linux/firmware.h>
+#include <linux/pci.h>
 #include <asm/unaligned.h>
 
 #include <net/bluetooth/bluetooth.h>
@@ -153,6 +154,10 @@ static const struct usb_device_id btusb_
 	{ USB_VENDOR_AND_INTERFACE_INFO(0x13d3, 0xff, 0x01, 0x01),
 	  .driver_info = BTUSB_BCM_PATCHRAM },
 
+	/* Toshiba Corp - Broadcom based */
+	{ USB_VENDOR_AND_INTERFACE_INFO(0x0930, 0xff, 0x01, 0x01),
+	  .driver_info = BTUSB_BCM_PATCHRAM },
+
 	/* Intel Bluetooth USB Bootloader (RAM module) */
 	{ USB_DEVICE(0x8087, 0x0a5a),
 	  .driver_info = BTUSB_INTEL_BOOT | BTUSB_BROKEN_ISOC },
@@ -192,6 +197,7 @@ static const struct usb_device_id blackl
 	{ USB_DEVICE(0x0489, 0xe05f), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x0489, 0xe076), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x0489, 0xe078), .driver_info = BTUSB_ATH3012 },
+	{ USB_DEVICE(0x0489, 0xe095), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x04c5, 0x1330), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x04ca, 0x3004), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 },
@@ -202,6 +208,7 @@ static const struct usb_device_id blackl
 	{ USB_DEVICE(0x04ca, 0x300d), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x04ca, 0x300f), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x04ca, 0x3010), .driver_info = BTUSB_ATH3012 },
+	{ USB_DEVICE(0x04ca, 0x3014), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x0930, 0x0219), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x0930, 0x021c), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x0930, 0x0220), .driver_info = BTUSB_ATH3012 },
@@ -223,10 +230,12 @@ static const struct usb_device_id blackl
 	{ USB_DEVICE(0x13d3, 0x3362), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x13d3, 0x3375), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x13d3, 0x3393), .driver_info = BTUSB_ATH3012 },
+	{ USB_DEVICE(0x13d3, 0x3395), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x13d3, 0x3402), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x13d3, 0x3408), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x13d3, 0x3423), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x13d3, 0x3432), .driver_info = BTUSB_ATH3012 },
+	{ USB_DEVICE(0x13d3, 0x3472), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x13d3, 0x3474), .driver_info = BTUSB_ATH3012 },
 
 	/* Atheros AR5BBU12 with sflash firmware */
@@ -305,6 +314,7 @@ static const struct usb_device_id blackl
 	{ USB_DEVICE(0x8087, 0x07dc), .driver_info = BTUSB_INTEL },
 	{ USB_DEVICE(0x8087, 0x0a2a), .driver_info = BTUSB_INTEL },
 	{ USB_DEVICE(0x8087, 0x0a2b), .driver_info = BTUSB_INTEL_NEW },
+	{ USB_DEVICE(0x8087, 0x0aa7), .driver_info = BTUSB_INTEL },
 
 	/* Other Intel Bluetooth devices */
 	{ USB_VENDOR_AND_INTERFACE_INFO(0x8087, 0xe0, 0x01, 0x01),
@@ -2048,12 +2058,13 @@ static int btusb_setup_intel_new(struct
 		return -EINVAL;
 	}
 
-	/* At the moment only the hardware variant iBT 3.0 (LnP/SfP) is
-	 * supported by this firmware loading method. This check has been
-	 * put in place to ensure correct forward compatibility options
-	 * when newer hardware variants come along.
+	/* At the moment the iBT 3.0 hardware variants 0x0b (LnP/SfP)
+	 * and 0x0c (WsP) are supported by this firmware loading method.
+	 *
+	 * This check has been put in place to ensure correct forward
+	 * compatibility options when newer hardware variants come along.
 	 */
-	if (ver->hw_variant != 0x0b) {
+	if (ver->hw_variant != 0x0b && ver->hw_variant != 0x0c) {
 		BT_ERR("%s: Unsupported Intel hardware variant (%u)",
 		       hdev->name, ver->hw_variant);
 		kfree_skb(skb);
@@ -2766,6 +2777,33 @@ static int btusb_bcm_set_diag(struct hci
 }
 #endif
 
+#define BTUSB_EDGE_LED_COMMAND		0xfc77
+static void btusb_edge_set_led(struct hci_dev *hdev, bool state)
+{
+	struct sk_buff *skb;
+	u8 config_led[] = { 0x09, 0x00, 0x01, 0x01 };
+
+	if (state)
+		config_led[1] = 0x01;
+
+	skb = __hci_cmd_sync(hdev, BTUSB_EDGE_LED_COMMAND, sizeof(config_led), config_led, HCI_INIT_TIMEOUT);
+	if (IS_ERR(skb))
+		BT_ERR("%s fail to set LED (%ld)", hdev->name, PTR_ERR(skb));
+	else
+		kfree_skb(skb);
+}
+
+static void btusb_edge_post_open(struct hci_dev *hdev)
+{
+	btusb_edge_set_led(hdev, true);
+}
+
+static int btusb_edge_shutdown(struct hci_dev *hdev)
+{
+	btusb_edge_set_led(hdev, false);
+	return 0;
+}
+
 static int btusb_probe(struct usb_interface *intf,
 		       const struct usb_device_id *id)
 {
@@ -2936,8 +2974,14 @@ static int btusb_probe(struct usb_interf
 		set_bit(HCI_QUIRK_NON_PERSISTENT_DIAG, &hdev->quirks);
 	}
 
-	if (id->driver_info & BTUSB_MARVELL)
+	if (id->driver_info & BTUSB_MARVELL) {
 		hdev->set_bdaddr = btusb_set_bdaddr_marvell;
+		if (pci_get_subsys(PCI_ANY_ID, PCI_ANY_ID, 0x1028, 0x0720, NULL) ||
+			pci_get_subsys(PCI_ANY_ID, PCI_ANY_ID, 0x1028, 0x0733, NULL)) {
+			hdev->post_open = btusb_edge_post_open;
+			hdev->shutdown = btusb_edge_shutdown;
+		}
+	}
 
 	if (id->driver_info & BTUSB_SWAVE) {
 		set_bit(HCI_QUIRK_FIXUP_INQUIRY_MODE, &hdev->quirks);
--- zfcpdump-kernel-4.4.orig/drivers/bluetooth/hci_intel.c
+++ zfcpdump-kernel-4.4/drivers/bluetooth/hci_intel.c
@@ -1234,8 +1234,7 @@ static int intel_probe(struct platform_d
 
 	idev->pdev = pdev;
 
-	idev->reset = devm_gpiod_get_optional(&pdev->dev, "reset",
-					      GPIOD_OUT_LOW);
+	idev->reset = devm_gpiod_get(&pdev->dev, "reset", GPIOD_OUT_LOW);
 	if (IS_ERR(idev->reset)) {
 		dev_err(&pdev->dev, "Unable to retrieve gpio\n");
 		return PTR_ERR(idev->reset);
@@ -1247,8 +1246,7 @@ static int intel_probe(struct platform_d
 
 		dev_err(&pdev->dev, "No IRQ, falling back to gpio-irq\n");
 
-		host_wake = devm_gpiod_get_optional(&pdev->dev, "host-wake",
-						    GPIOD_IN);
+		host_wake = devm_gpiod_get(&pdev->dev, "host-wake", GPIOD_IN);
 		if (IS_ERR(host_wake)) {
 			dev_err(&pdev->dev, "Unable to retrieve IRQ\n");
 			goto no_irq;
--- zfcpdump-kernel-4.4.orig/drivers/bluetooth/hci_vhci.c
+++ zfcpdump-kernel-4.4/drivers/bluetooth/hci_vhci.c
@@ -50,6 +50,7 @@ struct vhci_data {
 	wait_queue_head_t read_wait;
 	struct sk_buff_head readq;
 
+	struct mutex open_mutex;
 	struct delayed_work open_timeout;
 };
 
@@ -87,12 +88,15 @@ static int vhci_send_frame(struct hci_de
 	return 0;
 }
 
-static int vhci_create_device(struct vhci_data *data, __u8 opcode)
+static int __vhci_create_device(struct vhci_data *data, __u8 opcode)
 {
 	struct hci_dev *hdev;
 	struct sk_buff *skb;
 	__u8 dev_type;
 
+	if (data->hdev)
+		return -EBADFD;
+
 	/* bits 0-1 are dev_type (BR/EDR or AMP) */
 	dev_type = opcode & 0x03;
 
@@ -151,6 +155,17 @@ static int vhci_create_device(struct vhc
 	return 0;
 }
 
+static int vhci_create_device(struct vhci_data *data, __u8 opcode)
+{
+	int err;
+
+	mutex_lock(&data->open_mutex);
+	err = __vhci_create_device(data, opcode);
+	mutex_unlock(&data->open_mutex);
+
+	return err;
+}
+
 static inline ssize_t vhci_get_user(struct vhci_data *data,
 				    struct iov_iter *from)
 {
@@ -189,11 +204,6 @@ static inline ssize_t vhci_get_user(stru
 		break;
 
 	case HCI_VENDOR_PKT:
-		if (data->hdev) {
-			kfree_skb(skb);
-			return -EBADFD;
-		}
-
 		cancel_delayed_work_sync(&data->open_timeout);
 
 		opcode = *((__u8 *) skb->data);
@@ -320,6 +330,7 @@ static int vhci_open(struct inode *inode
 	skb_queue_head_init(&data->readq);
 	init_waitqueue_head(&data->read_wait);
 
+	mutex_init(&data->open_mutex);
 	INIT_DELAYED_WORK(&data->open_timeout, vhci_open_timeout);
 
 	file->private_data = data;
@@ -333,15 +344,18 @@ static int vhci_open(struct inode *inode
 static int vhci_release(struct inode *inode, struct file *file)
 {
 	struct vhci_data *data = file->private_data;
-	struct hci_dev *hdev = data->hdev;
+	struct hci_dev *hdev;
 
 	cancel_delayed_work_sync(&data->open_timeout);
 
+	hdev = data->hdev;
+
 	if (hdev) {
 		hci_unregister_dev(hdev);
 		hci_free_dev(hdev);
 	}
 
+	skb_queue_purge(&data->readq);
 	file->private_data = NULL;
 	kfree(data);
 
--- zfcpdump-kernel-4.4.orig/drivers/bus/arm-ccn.c
+++ zfcpdump-kernel-4.4/drivers/bus/arm-ccn.c
@@ -187,6 +187,7 @@ struct arm_ccn {
 	struct arm_ccn_component *xp;
 
 	struct arm_ccn_dt dt;
+	int mn_id;
 };
 
 
@@ -326,6 +327,7 @@ struct arm_ccn_pmu_event {
 static ssize_t arm_ccn_pmu_event_show(struct device *dev,
 		struct device_attribute *attr, char *buf)
 {
+	struct arm_ccn *ccn = pmu_to_arm_ccn(dev_get_drvdata(dev));
 	struct arm_ccn_pmu_event *event = container_of(attr,
 			struct arm_ccn_pmu_event, attr);
 	ssize_t res;
@@ -352,6 +354,9 @@ static ssize_t arm_ccn_pmu_event_show(st
 			res += snprintf(buf + res, PAGE_SIZE - res,
 					",cmp_l=?,cmp_h=?,mask=?");
 		break;
+	case CCN_TYPE_MN:
+		res += snprintf(buf + res, PAGE_SIZE - res, ",node=%d", ccn->mn_id);
+		break;
 	default:
 		res += snprintf(buf + res, PAGE_SIZE - res, ",node=?");
 		break;
@@ -381,9 +386,9 @@ static umode_t arm_ccn_pmu_events_is_vis
 }
 
 static struct arm_ccn_pmu_event arm_ccn_pmu_events[] = {
-	CCN_EVENT_MN(eobarrier, "dir=0,vc=0,cmp_h=0x1c00", CCN_IDX_MASK_OPCODE),
-	CCN_EVENT_MN(ecbarrier, "dir=0,vc=0,cmp_h=0x1e00", CCN_IDX_MASK_OPCODE),
-	CCN_EVENT_MN(dvmop, "dir=0,vc=0,cmp_h=0x2800", CCN_IDX_MASK_OPCODE),
+	CCN_EVENT_MN(eobarrier, "dir=1,vc=0,cmp_h=0x1c00", CCN_IDX_MASK_OPCODE),
+	CCN_EVENT_MN(ecbarrier, "dir=1,vc=0,cmp_h=0x1e00", CCN_IDX_MASK_OPCODE),
+	CCN_EVENT_MN(dvmop, "dir=1,vc=0,cmp_h=0x2800", CCN_IDX_MASK_OPCODE),
 	CCN_EVENT_HNI(txdatflits, "dir=1,vc=3", CCN_IDX_MASK_ANY),
 	CCN_EVENT_HNI(rxdatflits, "dir=0,vc=3", CCN_IDX_MASK_ANY),
 	CCN_EVENT_HNI(txreqflits, "dir=1,vc=0", CCN_IDX_MASK_ANY),
@@ -757,6 +762,12 @@ static int arm_ccn_pmu_event_init(struct
 
 	/* Validate node/xp vs topology */
 	switch (type) {
+	case CCN_TYPE_MN:
+		if (node_xp != ccn->mn_id) {
+			dev_warn(ccn->dev, "Invalid MN ID %d!\n", node_xp);
+			return -EINVAL;
+		}
+		break;
 	case CCN_TYPE_XP:
 		if (node_xp >= ccn->num_xps) {
 			dev_warn(ccn->dev, "Invalid XP ID %d!\n", node_xp);
@@ -884,6 +895,10 @@ static void arm_ccn_pmu_xp_dt_config(str
 	struct arm_ccn_component *xp;
 	u32 val, dt_cfg;
 
+	/* Nothing to do for cycle counter */
+	if (hw->idx == CCN_IDX_PMU_CYCLE_COUNTER)
+		return;
+
 	if (CCN_CONFIG_TYPE(event->attr.config) == CCN_TYPE_XP)
 		xp = &ccn->xp[CCN_CONFIG_XP(event->attr.config)];
 	else
@@ -986,7 +1001,7 @@ static void arm_ccn_pmu_xp_watchpoint_co
 
 	/* Comparison values */
 	writel(cmp_l & 0xffffffff, source->base + CCN_XP_DT_CMP_VAL_L(wp));
-	writel((cmp_l >> 32) & 0xefffffff,
+	writel((cmp_l >> 32) & 0x7fffffff,
 			source->base + CCN_XP_DT_CMP_VAL_L(wp) + 4);
 	writel(cmp_h & 0xffffffff, source->base + CCN_XP_DT_CMP_VAL_H(wp));
 	writel((cmp_h >> 32) & 0x0fffffff,
@@ -994,7 +1009,7 @@ static void arm_ccn_pmu_xp_watchpoint_co
 
 	/* Mask */
 	writel(mask_l & 0xffffffff, source->base + CCN_XP_DT_CMP_MASK_L(wp));
-	writel((mask_l >> 32) & 0xefffffff,
+	writel((mask_l >> 32) & 0x7fffffff,
 			source->base + CCN_XP_DT_CMP_MASK_L(wp) + 4);
 	writel(mask_h & 0xffffffff, source->base + CCN_XP_DT_CMP_MASK_H(wp));
 	writel((mask_h >> 32) & 0x0fffffff,
@@ -1368,6 +1383,8 @@ static int arm_ccn_init_nodes(struct arm
 
 	switch (type) {
 	case CCN_TYPE_MN:
+		ccn->mn_id = id;
+		return 0;
 	case CCN_TYPE_DT:
 		return 0;
 	case CCN_TYPE_XP:
--- zfcpdump-kernel-4.4.orig/drivers/bus/imx-weim.c
+++ zfcpdump-kernel-4.4/drivers/bus/imx-weim.c
@@ -150,7 +150,7 @@ static int __init weim_parse_dt(struct p
 			return ret;
 	}
 
-	for_each_child_of_node(pdev->dev.of_node, child) {
+	for_each_available_child_of_node(pdev->dev.of_node, child) {
 		if (!child->name)
 			continue;
 
--- zfcpdump-kernel-4.4.orig/drivers/cdrom/cdrom.c
+++ zfcpdump-kernel-4.4/drivers/cdrom/cdrom.c
@@ -289,7 +289,7 @@ static bool debug;
 /* default compatibility mode */
 static bool autoclose=1;
 static bool autoeject;
-static bool lockdoor = 1;
+static bool lockdoor = 0;
 /* will we ever get to use this... sigh. */
 static bool check_media_type;
 /* automatically restart mrw format */
--- zfcpdump-kernel-4.4.orig/drivers/char/hw_random/exynos-rng.c
+++ zfcpdump-kernel-4.4/drivers/char/hw_random/exynos-rng.c
@@ -89,6 +89,7 @@ static int exynos_read(struct hwrng *rng
 						struct exynos_rng, rng);
 	u32 *data = buf;
 	int retry = 100;
+	int ret = 4;
 
 	pm_runtime_get_sync(exynos_rng->dev);
 
@@ -97,23 +98,27 @@ static int exynos_read(struct hwrng *rng
 	while (!(exynos_rng_readl(exynos_rng,
 			EXYNOS_PRNG_STATUS_OFFSET) & PRNG_DONE) && --retry)
 		cpu_relax();
-	if (!retry)
-		return -ETIMEDOUT;
+	if (!retry) {
+		ret = -ETIMEDOUT;
+		goto out;
+	}
 
 	exynos_rng_writel(exynos_rng, PRNG_DONE, EXYNOS_PRNG_STATUS_OFFSET);
 
 	*data = exynos_rng_readl(exynos_rng, EXYNOS_PRNG_OUT1_OFFSET);
 
+out:
 	pm_runtime_mark_last_busy(exynos_rng->dev);
 	pm_runtime_put_sync_autosuspend(exynos_rng->dev);
 
-	return 4;
+	return ret;
 }
 
 static int exynos_rng_probe(struct platform_device *pdev)
 {
 	struct exynos_rng *exynos_rng;
 	struct resource *res;
+	int ret;
 
 	exynos_rng = devm_kzalloc(&pdev->dev, sizeof(struct exynos_rng),
 					GFP_KERNEL);
@@ -141,7 +146,13 @@ static int exynos_rng_probe(struct platf
 	pm_runtime_use_autosuspend(&pdev->dev);
 	pm_runtime_enable(&pdev->dev);
 
-	return devm_hwrng_register(&pdev->dev, &exynos_rng->rng);
+	ret = devm_hwrng_register(&pdev->dev, &exynos_rng->rng);
+	if (ret) {
+		pm_runtime_dont_use_autosuspend(&pdev->dev);
+		pm_runtime_disable(&pdev->dev);
+	}
+
+	return ret;
 }
 
 #ifdef CONFIG_PM
--- zfcpdump-kernel-4.4.orig/drivers/char/hw_random/omap-rng.c
+++ zfcpdump-kernel-4.4/drivers/char/hw_random/omap-rng.c
@@ -384,7 +384,12 @@ static int omap_rng_probe(struct platfor
 	}
 
 	pm_runtime_enable(&pdev->dev);
-	pm_runtime_get_sync(&pdev->dev);
+	ret = pm_runtime_get_sync(&pdev->dev);
+	if (ret) {
+		dev_err(&pdev->dev, "Failed to runtime_get device: %d\n", ret);
+		pm_runtime_put_noidle(&pdev->dev);
+		goto err_ioremap;
+	}
 
 	ret = (dev->of_node) ? of_get_omap_rng_device_details(priv, pdev) :
 				get_omap_rng_device_details(priv);
@@ -435,8 +440,15 @@ static int __maybe_unused omap_rng_suspe
 static int __maybe_unused omap_rng_resume(struct device *dev)
 {
 	struct omap_rng_dev *priv = dev_get_drvdata(dev);
+	int ret;
+
+	ret = pm_runtime_get_sync(dev);
+	if (ret) {
+		dev_err(dev, "Failed to runtime_get device: %d\n", ret);
+		pm_runtime_put_noidle(dev);
+		return ret;
+	}
 
-	pm_runtime_get_sync(dev);
 	priv->pdata->init(priv);
 
 	return 0;
--- zfcpdump-kernel-4.4.orig/drivers/char/ipmi/ipmi_msghandler.c
+++ zfcpdump-kernel-4.4/drivers/char/ipmi/ipmi_msghandler.c
@@ -3819,6 +3819,7 @@ static void handle_new_recv_msgs(ipmi_sm
 	while (!list_empty(&intf->waiting_rcv_msgs)) {
 		smi_msg = list_entry(intf->waiting_rcv_msgs.next,
 				     struct ipmi_smi_msg, link);
+		list_del(&smi_msg->link);
 		if (!run_to_completion)
 			spin_unlock_irqrestore(&intf->waiting_rcv_msgs_lock,
 					       flags);
@@ -3828,11 +3829,14 @@ static void handle_new_recv_msgs(ipmi_sm
 		if (rv > 0) {
 			/*
 			 * To preserve message order, quit if we
-			 * can't handle a message.
+			 * can't handle a message.  Add the message
+			 * back at the head, this is safe because this
+			 * tasklet is the only thing that pulls the
+			 * messages.
 			 */
+			list_add(&smi_msg->link, &intf->waiting_rcv_msgs);
 			break;
 		} else {
-			list_del(&smi_msg->link);
 			if (rv == 0)
 				/* Message handled */
 				ipmi_free_smi_msg(smi_msg);
--- zfcpdump-kernel-4.4.orig/drivers/char/mem.c
+++ zfcpdump-kernel-4.4/drivers/char/mem.c
@@ -27,6 +27,7 @@
 #include <linux/export.h>
 #include <linux/io.h>
 #include <linux/uio.h>
+#include <linux/module.h>
 
 #include <linux/uaccess.h>
 
@@ -166,6 +167,9 @@ static ssize_t write_mem(struct file *fi
 	if (p != *ppos)
 		return -EFBIG;
 
+	if (secure_modules())
+		return -EPERM;
+
 	if (!valid_phys_addr_range(p, count))
 		return -EFAULT;
 
@@ -512,6 +516,9 @@ static ssize_t write_kmem(struct file *f
 	char *kbuf; /* k-addr because vwrite() takes vmlist_lock rwlock */
 	int err = 0;
 
+	if (secure_modules())
+		return -EPERM;
+
 	if (p < (unsigned long) high_memory) {
 		unsigned long to_write = min_t(unsigned long, count,
 					       (unsigned long)high_memory - p);
@@ -577,6 +584,9 @@ static ssize_t write_port(struct file *f
 	unsigned long i = *ppos;
 	const char __user *tmp = buf;
 
+	if (secure_modules())
+		return -EPERM;
+
 	if (!access_ok(VERIFY_READ, buf, count))
 		return -EFAULT;
 	while (count-- > 0 && i < 65536) {
--- zfcpdump-kernel-4.4.orig/drivers/char/random.c
+++ zfcpdump-kernel-4.4/drivers/char/random.c
@@ -722,15 +722,18 @@ retry:
 	}
 }
 
-static void credit_entropy_bits_safe(struct entropy_store *r, int nbits)
+static int credit_entropy_bits_safe(struct entropy_store *r, int nbits)
 {
 	const int nbits_max = (int)(~0U >> (ENTROPY_SHIFT + 1));
 
+	if (nbits < 0)
+		return -EINVAL;
+
 	/* Cap the value to avoid overflows */
 	nbits = min(nbits,  nbits_max);
-	nbits = max(nbits, -nbits_max);
 
 	credit_entropy_bits(r, nbits);
+	return 0;
 }
 
 /*********************************************************************
@@ -945,6 +948,7 @@ void add_interrupt_randomness(int irq, i
 	/* award one bit for the contents of the fast pool */
 	credit_entropy_bits(r, credit + 1);
 }
+EXPORT_SYMBOL_GPL(add_interrupt_randomness);
 
 #ifdef CONFIG_BLOCK
 void add_disk_randomness(struct gendisk *disk)
@@ -1457,12 +1461,16 @@ random_read(struct file *file, char __us
 static ssize_t
 urandom_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos)
 {
+	static int maxwarn = 10;
 	int ret;
 
-	if (unlikely(nonblocking_pool.initialized == 0))
-		printk_once(KERN_NOTICE "random: %s urandom read "
-			    "with %d bits of entropy available\n",
-			    current->comm, nonblocking_pool.entropy_total);
+	if (unlikely(nonblocking_pool.initialized == 0) &&
+	    maxwarn > 0) {
+		maxwarn--;
+		printk(KERN_NOTICE "random: %s: uninitialized urandom read "
+		       "(%zd bytes read, %d bits of entropy available)\n",
+		       current->comm, nbytes, nonblocking_pool.entropy_total);
+	}
 
 	nbytes = min_t(size_t, nbytes, INT_MAX >> (ENTROPY_SHIFT + 3));
 	ret = extract_entropy_user(&nonblocking_pool, buf, nbytes);
@@ -1542,8 +1550,7 @@ static long random_ioctl(struct file *f,
 			return -EPERM;
 		if (get_user(ent_count, p))
 			return -EFAULT;
-		credit_entropy_bits_safe(&input_pool, ent_count);
-		return 0;
+		return credit_entropy_bits_safe(&input_pool, ent_count);
 	case RNDADDENTROPY:
 		if (!capable(CAP_SYS_ADMIN))
 			return -EPERM;
@@ -1557,8 +1564,7 @@ static long random_ioctl(struct file *f,
 				    size);
 		if (retval < 0)
 			return retval;
-		credit_entropy_bits_safe(&input_pool, ent_count);
-		return 0;
+		return credit_entropy_bits_safe(&input_pool, ent_count);
 	case RNDZAPENTCNT:
 	case RNDCLEARPOOL:
 		/*
@@ -1846,12 +1852,18 @@ void add_hwgenerator_randomness(const ch
 {
 	struct entropy_store *poolp = &input_pool;
 
-	/* Suspend writing if we're above the trickle threshold.
-	 * We'll be woken up again once below random_write_wakeup_thresh,
-	 * or when the calling thread is about to terminate.
-	 */
-	wait_event_interruptible(random_write_wait, kthread_should_stop() ||
+	if (unlikely(nonblocking_pool.initialized == 0))
+		poolp = &nonblocking_pool;
+	else {
+		/* Suspend writing if we're above the trickle
+		 * threshold.  We'll be woken up again once below
+		 * random_write_wakeup_thresh, or when the calling
+		 * thread is about to terminate.
+		 */
+		wait_event_interruptible(random_write_wait,
+					 kthread_should_stop() ||
 			ENTROPY_BITS(&input_pool) <= random_write_wakeup_bits);
+	}
 	mix_pool_bytes(poolp, buffer, count);
 	credit_entropy_bits(poolp, entropy);
 }
--- zfcpdump-kernel-4.4.orig/drivers/char/tpm/tpm-chip.c
+++ zfcpdump-kernel-4.4/drivers/char/tpm/tpm-chip.c
@@ -88,6 +88,7 @@ struct tpm_chip *tpmm_chip_alloc(struct
 				 const struct tpm_class_ops *ops)
 {
 	struct tpm_chip *chip;
+	int rc;
 
 	chip = kzalloc(sizeof(*chip), GFP_KERNEL);
 	if (chip == NULL)
@@ -136,11 +137,17 @@ struct tpm_chip *tpmm_chip_alloc(struct
 	chip->cdev.owner = chip->pdev->driver->owner;
 	chip->cdev.kobj.parent = &chip->dev.kobj;
 
+	rc = devm_add_action(dev, (void (*)(void *)) put_device, &chip->dev);
+	if (rc) {
+		put_device(&chip->dev);
+		return ERR_PTR(rc);
+	}
+
 	return chip;
 }
 EXPORT_SYMBOL_GPL(tpmm_chip_alloc);
 
-static int tpm_dev_add_device(struct tpm_chip *chip)
+static int tpm_add_char_device(struct tpm_chip *chip)
 {
 	int rc;
 
@@ -151,7 +158,6 @@ static int tpm_dev_add_device(struct tpm
 			chip->devname, MAJOR(chip->dev.devt),
 			MINOR(chip->dev.devt), rc);
 
-		device_unregister(&chip->dev);
 		return rc;
 	}
 
@@ -162,16 +168,17 @@ static int tpm_dev_add_device(struct tpm
 			chip->devname, MAJOR(chip->dev.devt),
 			MINOR(chip->dev.devt), rc);
 
+		cdev_del(&chip->cdev);
 		return rc;
 	}
 
 	return rc;
 }
 
-static void tpm_dev_del_device(struct tpm_chip *chip)
+static void tpm_del_char_device(struct tpm_chip *chip)
 {
 	cdev_del(&chip->cdev);
-	device_unregister(&chip->dev);
+	device_del(&chip->dev);
 }
 
 static int tpm1_chip_register(struct tpm_chip *chip)
@@ -222,7 +229,7 @@ int tpm_chip_register(struct tpm_chip *c
 
 	tpm_add_ppi(chip);
 
-	rc = tpm_dev_add_device(chip);
+	rc = tpm_add_char_device(chip);
 	if (rc)
 		goto out_err;
 
@@ -274,6 +281,6 @@ void tpm_chip_unregister(struct tpm_chip
 		sysfs_remove_link(&chip->pdev->kobj, "ppi");
 
 	tpm1_chip_unregister(chip);
-	tpm_dev_del_device(chip);
+	tpm_del_char_device(chip);
 }
 EXPORT_SYMBOL_GPL(tpm_chip_unregister);
--- zfcpdump-kernel-4.4.orig/drivers/char/tpm/tpm-interface.c
+++ zfcpdump-kernel-4.4/drivers/char/tpm/tpm-interface.c
@@ -310,10 +310,12 @@ unsigned long tpm_calc_ordinal_duration(
 {
 	int duration_idx = TPM_UNDEFINED;
 	int duration = 0;
-	u8 category = (ordinal >> 24) & 0xFF;
 
-	if ((category == TPM_PROTECTED_COMMAND && ordinal < TPM_MAX_ORDINAL) ||
-	    (category == TPM_CONNECTION_COMMAND && ordinal < TSC_MAX_ORDINAL))
+	/*
+	 * We only have a duration table for protected commands, where the upper
+	 * 16 bits are 0. For the few other ordinals the fallback will be used.
+	 */
+	if (ordinal < TPM_MAX_ORDINAL)
 		duration_idx = tpm_ordinal_duration[ordinal];
 
 	if (duration_idx != TPM_UNDEFINED)
@@ -501,6 +503,21 @@ int tpm_get_timeouts(struct tpm_chip *ch
 	struct duration_t *duration_cap;
 	ssize_t rc;
 
+	if (chip->flags & TPM_CHIP_FLAG_TPM2) {
+		/* Fixed timeouts for TPM2 */
+		chip->vendor.timeout_a = msecs_to_jiffies(TPM2_TIMEOUT_A);
+		chip->vendor.timeout_b = msecs_to_jiffies(TPM2_TIMEOUT_B);
+		chip->vendor.timeout_c = msecs_to_jiffies(TPM2_TIMEOUT_C);
+		chip->vendor.timeout_d = msecs_to_jiffies(TPM2_TIMEOUT_D);
+		chip->vendor.duration[TPM_SHORT] =
+		    msecs_to_jiffies(TPM2_DURATION_SHORT);
+		chip->vendor.duration[TPM_MEDIUM] =
+		    msecs_to_jiffies(TPM2_DURATION_MEDIUM);
+		chip->vendor.duration[TPM_LONG] =
+		    msecs_to_jiffies(TPM2_DURATION_LONG);
+		return 0;
+	}
+
 	tpm_cmd.header.in = tpm_getcap_header;
 	tpm_cmd.params.getcap_in.cap = TPM_CAP_PROP;
 	tpm_cmd.params.getcap_in.subcap_size = cpu_to_be32(4);
--- zfcpdump-kernel-4.4.orig/drivers/char/tpm/tpm.h
+++ zfcpdump-kernel-4.4/drivers/char/tpm/tpm.h
@@ -83,16 +83,20 @@ enum tpm2_structures {
 };
 
 enum tpm2_return_codes {
-	TPM2_RC_INITIALIZE	= 0x0100,
-	TPM2_RC_TESTING		= 0x090A,
+	TPM2_RC_HASH		= 0x0083, /* RC_FMT1 */
+	TPM2_RC_INITIALIZE	= 0x0100, /* RC_VER1 */
 	TPM2_RC_DISABLED	= 0x0120,
+	TPM2_RC_TESTING		= 0x090A, /* RC_WARN */
 };
 
 enum tpm2_algorithms {
 	TPM2_ALG_SHA1		= 0x0004,
 	TPM2_ALG_KEYEDHASH	= 0x0008,
 	TPM2_ALG_SHA256		= 0x000B,
-	TPM2_ALG_NULL		= 0x0010
+	TPM2_ALG_SHA384		= 0x000C,
+	TPM2_ALG_SHA512		= 0x000D,
+	TPM2_ALG_NULL		= 0x0010,
+	TPM2_ALG_SM3_256	= 0x0012,
 };
 
 enum tpm2_command_codes {
@@ -124,13 +128,6 @@ enum tpm2_startup_types {
 	TPM2_SU_STATE	= 0x0001,
 };
 
-enum tpm2_start_method {
-	TPM2_START_ACPI = 2,
-	TPM2_START_FIFO = 6,
-	TPM2_START_CRB = 7,
-	TPM2_START_CRB_WITH_ACPI = 8,
-};
-
 struct tpm_chip;
 
 struct tpm_vendor_specific {
@@ -138,7 +135,6 @@ struct tpm_vendor_specific {
 	unsigned long base;		/* TPM base address */
 
 	int irq;
-	int probed_irq;
 
 	int region_size;
 	int have_region;
--- zfcpdump-kernel-4.4.orig/drivers/char/tpm/tpm2-cmd.c
+++ zfcpdump-kernel-4.4/drivers/char/tpm/tpm2-cmd.c
@@ -16,10 +16,15 @@
  */
 
 #include "tpm.h"
+#include <crypto/hash_info.h>
 #include <keys/trusted-type.h>
 
 enum tpm2_object_attributes {
-	TPM2_ATTR_USER_WITH_AUTH	= BIT(6),
+	TPM2_OA_USER_WITH_AUTH		= BIT(6),
+};
+
+enum tpm2_session_attributes {
+	TPM2_SA_CONTINUE_SESSION	= BIT(0),
 };
 
 struct tpm2_startup_in {
@@ -104,6 +109,19 @@ struct tpm2_cmd {
 	union tpm2_cmd_params	params;
 } __packed;
 
+struct tpm2_hash {
+	unsigned int crypto_id;
+	unsigned int tpm_id;
+};
+
+static struct tpm2_hash tpm2_hash_map[] = {
+	{HASH_ALGO_SHA1, TPM2_ALG_SHA1},
+	{HASH_ALGO_SHA256, TPM2_ALG_SHA256},
+	{HASH_ALGO_SHA384, TPM2_ALG_SHA384},
+	{HASH_ALGO_SHA512, TPM2_ALG_SHA512},
+	{HASH_ALGO_SM3_256, TPM2_ALG_SM3_256},
+};
+
 /*
  * Array with one entry per ordinal defining the maximum amount
  * of time the chip could take to return the result. The values
@@ -429,8 +447,20 @@ int tpm2_seal_trusted(struct tpm_chip *c
 {
 	unsigned int blob_len;
 	struct tpm_buf buf;
+	u32 hash;
+	int i;
 	int rc;
 
+	for (i = 0; i < ARRAY_SIZE(tpm2_hash_map); i++) {
+		if (options->hash == tpm2_hash_map[i].crypto_id) {
+			hash = tpm2_hash_map[i].tpm_id;
+			break;
+		}
+	}
+
+	if (i == ARRAY_SIZE(tpm2_hash_map))
+		return -EINVAL;
+
 	rc = tpm_buf_init(&buf, TPM2_ST_SESSIONS, TPM2_CC_CREATE);
 	if (rc)
 		return rc;
@@ -452,12 +482,22 @@ int tpm2_seal_trusted(struct tpm_chip *c
 	tpm_buf_append_u8(&buf, payload->migratable);
 
 	/* public */
-	tpm_buf_append_u16(&buf, 14);
-
+	tpm_buf_append_u16(&buf, 14 + options->policydigest_len);
 	tpm_buf_append_u16(&buf, TPM2_ALG_KEYEDHASH);
-	tpm_buf_append_u16(&buf, TPM2_ALG_SHA256);
-	tpm_buf_append_u32(&buf, TPM2_ATTR_USER_WITH_AUTH);
-	tpm_buf_append_u16(&buf, 0); /* policy digest size */
+	tpm_buf_append_u16(&buf, hash);
+
+	/* policy */
+	if (options->policydigest_len) {
+		tpm_buf_append_u32(&buf, 0);
+		tpm_buf_append_u16(&buf, options->policydigest_len);
+		tpm_buf_append(&buf, options->policydigest,
+			       options->policydigest_len);
+	} else {
+		tpm_buf_append_u32(&buf, TPM2_OA_USER_WITH_AUTH);
+		tpm_buf_append_u16(&buf, 0);
+	}
+
+	/* public parameters */
 	tpm_buf_append_u16(&buf, TPM2_ALG_NULL);
 	tpm_buf_append_u16(&buf, 0);
 
@@ -488,8 +528,12 @@ int tpm2_seal_trusted(struct tpm_chip *c
 out:
 	tpm_buf_destroy(&buf);
 
-	if (rc > 0)
-		rc = -EPERM;
+	if (rc > 0) {
+		if ((rc & TPM2_RC_HASH) == TPM2_RC_HASH)
+			rc = -EINVAL;
+		else
+			rc = -EPERM;
+	}
 
 	return rc;
 }
@@ -583,9 +627,11 @@ static int tpm2_unseal(struct tpm_chip *
 		return rc;
 
 	tpm_buf_append_u32(&buf, blob_handle);
-	tpm2_buf_append_auth(&buf, TPM2_RS_PW,
+	tpm2_buf_append_auth(&buf,
+			     options->policyhandle ?
+			     options->policyhandle : TPM2_RS_PW,
 			     NULL /* nonce */, 0,
-			     0 /* session_attributes */,
+			     TPM2_SA_CONTINUE_SESSION,
 			     options->blobauth /* hmac */,
 			     TPM_DIGEST_SIZE);
 
@@ -657,7 +703,7 @@ ssize_t tpm2_get_tpm_pt(struct tpm_chip
 
 	rc = tpm_transmit_cmd(chip, &cmd, sizeof(cmd), desc);
 	if (!rc)
-		*value = cmd.params.get_tpm_pt_out.value;
+		*value = be32_to_cpu(cmd.params.get_tpm_pt_out.value);
 
 	return rc;
 }
--- zfcpdump-kernel-4.4.orig/drivers/char/tpm/tpm_crb.c
+++ zfcpdump-kernel-4.4/drivers/char/tpm/tpm_crb.c
@@ -34,14 +34,6 @@ enum crb_defaults {
 	CRB_ACPI_START_INDEX = 1,
 };
 
-struct acpi_tpm2 {
-	struct acpi_table_header hdr;
-	u16 platform_class;
-	u16 reserved;
-	u64 control_area_pa;
-	u32 start_method;
-} __packed;
-
 enum crb_ca_request {
 	CRB_CA_REQ_GO_IDLE	= BIT(0),
 	CRB_CA_REQ_CMD_READY	= BIT(1),
@@ -85,6 +77,7 @@ enum crb_flags {
 
 struct crb_priv {
 	unsigned int flags;
+	void __iomem *iobase;
 	struct crb_control_area __iomem *cca;
 	u8 __iomem *cmd;
 	u8 __iomem *rsp;
@@ -97,7 +90,7 @@ static u8 crb_status(struct tpm_chip *ch
 	struct crb_priv *priv = chip->vendor.priv;
 	u8 sts = 0;
 
-	if ((le32_to_cpu(ioread32(&priv->cca->start)) & CRB_START_INVOKE) !=
+	if ((ioread32(&priv->cca->start) & CRB_START_INVOKE) !=
 	    CRB_START_INVOKE)
 		sts |= CRB_STS_COMPLETE;
 
@@ -113,7 +106,7 @@ static int crb_recv(struct tpm_chip *chi
 	if (count < 6)
 		return -EIO;
 
-	if (le32_to_cpu(ioread32(&priv->cca->sts)) & CRB_CA_STS_ERROR)
+	if (ioread32(&priv->cca->sts) & CRB_CA_STS_ERROR)
 		return -EIO;
 
 	memcpy_fromio(buf, priv->rsp, 6);
@@ -149,11 +142,11 @@ static int crb_send(struct tpm_chip *chi
 	struct crb_priv *priv = chip->vendor.priv;
 	int rc = 0;
 
-	if (len > le32_to_cpu(ioread32(&priv->cca->cmd_size))) {
+	if (len > ioread32(&priv->cca->cmd_size)) {
 		dev_err(&chip->dev,
 			"invalid command count value %x %zx\n",
 			(unsigned int) len,
-			(size_t) le32_to_cpu(ioread32(&priv->cca->cmd_size)));
+			(size_t) ioread32(&priv->cca->cmd_size));
 		return -E2BIG;
 	}
 
@@ -189,7 +182,7 @@ static void crb_cancel(struct tpm_chip *
 static bool crb_req_canceled(struct tpm_chip *chip, u8 status)
 {
 	struct crb_priv *priv = chip->vendor.priv;
-	u32 cancel = le32_to_cpu(ioread32(&priv->cca->cancel));
+	u32 cancel = ioread32(&priv->cca->cancel);
 
 	return (cancel & CRB_CANCEL_INVOKE) == CRB_CANCEL_INVOKE;
 }
@@ -204,105 +197,166 @@ static const struct tpm_class_ops tpm_cr
 	.req_complete_val = CRB_STS_COMPLETE,
 };
 
-static int crb_acpi_add(struct acpi_device *device)
+static int crb_init(struct acpi_device *device, struct crb_priv *priv)
 {
 	struct tpm_chip *chip;
-	struct acpi_tpm2 *buf;
+	int rc;
+
+	chip = tpmm_chip_alloc(&device->dev, &tpm_crb);
+	if (IS_ERR(chip))
+		return PTR_ERR(chip);
+
+	chip->vendor.priv = priv;
+	chip->acpi_dev_handle = device->handle;
+	chip->flags = TPM_CHIP_FLAG_TPM2;
+
+	rc = tpm_get_timeouts(chip);
+	if (rc)
+		return rc;
+
+	rc = tpm2_do_selftest(chip);
+	if (rc)
+		return rc;
+
+	return tpm_chip_register(chip);
+}
+
+static int crb_check_resource(struct acpi_resource *ares, void *data)
+{
+	struct resource *io_res = data;
+	struct resource res;
+
+	if (acpi_dev_resource_memory(ares, &res)) {
+		*io_res = res;
+		io_res->name = NULL;
+	}
+
+	return 1;
+}
+
+static void __iomem *crb_map_res(struct device *dev, struct crb_priv *priv,
+				 struct resource *io_res, u64 start, u32 size)
+{
+	struct resource new_res = {
+		.start	= start,
+		.end	= start + size - 1,
+		.flags	= IORESOURCE_MEM,
+	};
+
+	/* Detect a 64 bit address on a 32 bit system */
+	if (start != new_res.start)
+		return ERR_PTR(-EINVAL);
+
+	if (!resource_contains(io_res, &new_res))
+		return devm_ioremap_resource(dev, &new_res);
+
+	return priv->iobase + (new_res.start - io_res->start);
+}
+
+static int crb_map_io(struct acpi_device *device, struct crb_priv *priv,
+		      struct acpi_table_tpm2 *buf)
+{
+	struct list_head resources;
+	struct resource io_res;
+	struct device *dev = &device->dev;
+	u64 cmd_pa;
+	u32 cmd_size;
+	u64 rsp_pa;
+	u32 rsp_size;
+	int ret;
+
+	INIT_LIST_HEAD(&resources);
+	ret = acpi_dev_get_resources(device, &resources, crb_check_resource,
+				     &io_res);
+	if (ret < 0)
+		return ret;
+	acpi_dev_free_resource_list(&resources);
+
+	if (resource_type(&io_res) != IORESOURCE_MEM) {
+		dev_err(dev,
+			FW_BUG "TPM2 ACPI table does not define a memory resource\n");
+		return -EINVAL;
+	}
+
+	priv->iobase = devm_ioremap_resource(dev, &io_res);
+	if (IS_ERR(priv->iobase))
+		return PTR_ERR(priv->iobase);
+
+	priv->cca = crb_map_res(dev, priv, &io_res, buf->control_address,
+				sizeof(struct crb_control_area));
+	if (IS_ERR(priv->cca))
+		return PTR_ERR(priv->cca);
+
+	cmd_pa = ((u64) ioread32(&priv->cca->cmd_pa_high) << 32) |
+		  (u64) ioread32(&priv->cca->cmd_pa_low);
+	cmd_size = ioread32(&priv->cca->cmd_size);
+	priv->cmd = crb_map_res(dev, priv, &io_res, cmd_pa, cmd_size);
+	if (IS_ERR(priv->cmd))
+		return PTR_ERR(priv->cmd);
+
+	memcpy_fromio(&rsp_pa, &priv->cca->rsp_pa, 8);
+	rsp_pa = le64_to_cpu(rsp_pa);
+	rsp_size = ioread32(&priv->cca->rsp_size);
+
+	if (cmd_pa != rsp_pa) {
+		priv->rsp = crb_map_res(dev, priv, &io_res, rsp_pa, rsp_size);
+		return PTR_ERR_OR_ZERO(priv->rsp);
+	}
+
+	/* According to the PTP specification, overlapping command and response
+	 * buffer sizes must be identical.
+	 */
+	if (cmd_size != rsp_size) {
+		dev_err(dev, FW_BUG "overlapping command and response buffer sizes are not identical");
+		return -EINVAL;
+	}
+
+	priv->rsp = priv->cmd;
+	return 0;
+}
+
+static int crb_acpi_add(struct acpi_device *device)
+{
+	struct acpi_table_tpm2 *buf;
 	struct crb_priv *priv;
 	struct device *dev = &device->dev;
 	acpi_status status;
 	u32 sm;
-	u64 pa;
 	int rc;
 
 	status = acpi_get_table(ACPI_SIG_TPM2, 1,
 				(struct acpi_table_header **) &buf);
-	if (ACPI_FAILURE(status)) {
-		dev_err(dev, "failed to get TPM2 ACPI table\n");
-		return -ENODEV;
+	if (ACPI_FAILURE(status) || buf->header.length < sizeof(*buf)) {
+		dev_err(dev, FW_BUG "failed to get TPM2 ACPI table\n");
+		return -EINVAL;
 	}
 
 	/* Should the FIFO driver handle this? */
-	if (buf->start_method == TPM2_START_FIFO)
+	sm = buf->start_method;
+	if (sm == ACPI_TPM2_MEMORY_MAPPED)
 		return -ENODEV;
 
-	chip = tpmm_chip_alloc(dev, &tpm_crb);
-	if (IS_ERR(chip))
-		return PTR_ERR(chip);
-
-	chip->flags = TPM_CHIP_FLAG_TPM2;
-
-	if (buf->hdr.length < sizeof(struct acpi_tpm2)) {
-		dev_err(dev, "TPM2 ACPI table has wrong size");
-		return -EINVAL;
-	}
-
-	priv = (struct crb_priv *) devm_kzalloc(dev, sizeof(struct crb_priv),
-						GFP_KERNEL);
-	if (!priv) {
-		dev_err(dev, "failed to devm_kzalloc for private data\n");
+	priv = devm_kzalloc(dev, sizeof(struct crb_priv), GFP_KERNEL);
+	if (!priv)
 		return -ENOMEM;
-	}
-
-	sm = le32_to_cpu(buf->start_method);
 
 	/* The reason for the extra quirk is that the PTT in 4th Gen Core CPUs
 	 * report only ACPI start but in practice seems to require both
 	 * ACPI start and CRB start.
 	 */
-	if (sm == TPM2_START_CRB || sm == TPM2_START_FIFO ||
+	if (sm == ACPI_TPM2_COMMAND_BUFFER || sm == ACPI_TPM2_MEMORY_MAPPED ||
 	    !strcmp(acpi_device_hid(device), "MSFT0101"))
 		priv->flags |= CRB_FL_CRB_START;
 
-	if (sm == TPM2_START_ACPI || sm == TPM2_START_CRB_WITH_ACPI)
+	if (sm == ACPI_TPM2_START_METHOD ||
+	    sm == ACPI_TPM2_COMMAND_BUFFER_WITH_START_METHOD)
 		priv->flags |= CRB_FL_ACPI_START;
 
-	priv->cca = (struct crb_control_area __iomem *)
-		devm_ioremap_nocache(dev, buf->control_area_pa, 0x1000);
-	if (!priv->cca) {
-		dev_err(dev, "ioremap of the control area failed\n");
-		return -ENOMEM;
-	}
-
-	pa = ((u64) le32_to_cpu(ioread32(&priv->cca->cmd_pa_high)) << 32) |
-		(u64) le32_to_cpu(ioread32(&priv->cca->cmd_pa_low));
-	priv->cmd = devm_ioremap_nocache(dev, pa,
-					 ioread32(&priv->cca->cmd_size));
-	if (!priv->cmd) {
-		dev_err(dev, "ioremap of the command buffer failed\n");
-		return -ENOMEM;
-	}
-
-	memcpy_fromio(&pa, &priv->cca->rsp_pa, 8);
-	pa = le64_to_cpu(pa);
-	priv->rsp = devm_ioremap_nocache(dev, pa,
-					 ioread32(&priv->cca->rsp_size));
-	if (!priv->rsp) {
-		dev_err(dev, "ioremap of the response buffer failed\n");
-		return -ENOMEM;
-	}
-
-	chip->vendor.priv = priv;
-
-	/* Default timeouts and durations */
-	chip->vendor.timeout_a = msecs_to_jiffies(TPM2_TIMEOUT_A);
-	chip->vendor.timeout_b = msecs_to_jiffies(TPM2_TIMEOUT_B);
-	chip->vendor.timeout_c = msecs_to_jiffies(TPM2_TIMEOUT_C);
-	chip->vendor.timeout_d = msecs_to_jiffies(TPM2_TIMEOUT_D);
-	chip->vendor.duration[TPM_SHORT] =
-		msecs_to_jiffies(TPM2_DURATION_SHORT);
-	chip->vendor.duration[TPM_MEDIUM] =
-		msecs_to_jiffies(TPM2_DURATION_MEDIUM);
-	chip->vendor.duration[TPM_LONG] =
-		msecs_to_jiffies(TPM2_DURATION_LONG);
-
-	chip->acpi_dev_handle = device->handle;
-
-	rc = tpm2_do_selftest(chip);
+	rc = crb_map_io(device, priv, buf);
 	if (rc)
 		return rc;
 
-	return tpm_chip_register(chip);
+	return crb_init(device, priv);
 }
 
 static int crb_acpi_remove(struct acpi_device *device)
@@ -310,11 +364,11 @@ static int crb_acpi_remove(struct acpi_d
 	struct device *dev = &device->dev;
 	struct tpm_chip *chip = dev_get_drvdata(dev);
 
-	tpm_chip_unregister(chip);
-
 	if (chip->flags & TPM_CHIP_FLAG_TPM2)
 		tpm2_shutdown(chip, TPM2_SU_CLEAR);
 
+	tpm_chip_unregister(chip);
+
 	return 0;
 }
 
--- zfcpdump-kernel-4.4.orig/drivers/char/tpm/tpm_eventlog.c
+++ zfcpdump-kernel-4.4/drivers/char/tpm/tpm_eventlog.c
@@ -232,7 +232,7 @@ static int tpm_binary_bios_measurements_
 {
 	struct tcpa_event *event = v;
 	struct tcpa_event temp_event;
-	char *tempPtr;
+	char *temp_ptr;
 	int i;
 
 	memcpy(&temp_event, event, sizeof(struct tcpa_event));
@@ -242,10 +242,16 @@ static int tpm_binary_bios_measurements_
 	temp_event.event_type = do_endian_conversion(event->event_type);
 	temp_event.event_size = do_endian_conversion(event->event_size);
 
-	tempPtr = (char *)&temp_event;
+	temp_ptr = (char *) &temp_event;
 
-	for (i = 0; i < sizeof(struct tcpa_event) + temp_event.event_size; i++)
-		seq_putc(m, tempPtr[i]);
+	for (i = 0; i < (sizeof(struct tcpa_event) - 1) ; i++)
+		seq_putc(m, temp_ptr[i]);
+
+	temp_ptr = (char *) v;
+
+	for (i = (sizeof(struct tcpa_event) - 1);
+	     i < (sizeof(struct tcpa_event) + temp_event.event_size); i++)
+		seq_putc(m, temp_ptr[i]);
 
 	return 0;
 
--- zfcpdump-kernel-4.4.orig/drivers/char/tpm/tpm_ibmvtpm.c
+++ zfcpdump-kernel-4.4/drivers/char/tpm/tpm_ibmvtpm.c
@@ -90,7 +90,7 @@ static int tpm_ibmvtpm_recv(struct tpm_c
 		return 0;
 	}
 
-	sig = wait_event_interruptible(ibmvtpm->wq, ibmvtpm->res_len != 0);
+	sig = wait_event_interruptible(ibmvtpm->wq, !ibmvtpm->tpm_processing_cmd);
 	if (sig)
 		return -EINTR;
 
@@ -125,7 +125,7 @@ static int tpm_ibmvtpm_send(struct tpm_c
 	struct ibmvtpm_dev *ibmvtpm;
 	struct ibmvtpm_crq crq;
 	__be64 *word = (__be64 *)&crq;
-	int rc;
+	int rc, sig;
 
 	ibmvtpm = (struct ibmvtpm_dev *)TPM_VPRIV(chip);
 
@@ -141,18 +141,35 @@ static int tpm_ibmvtpm_send(struct tpm_c
 		return -EIO;
 	}
 
+	if (ibmvtpm->tpm_processing_cmd) {
+		dev_info(ibmvtpm->dev,
+		         "Need to wait for TPM to finish\n");
+		/* wait for previous command to finish */
+		sig = wait_event_interruptible(ibmvtpm->wq, !ibmvtpm->tpm_processing_cmd);
+		if (sig)
+			return -EINTR;
+	}
+
 	spin_lock(&ibmvtpm->rtce_lock);
+	ibmvtpm->res_len = 0;
 	memcpy((void *)ibmvtpm->rtce_buf, (void *)buf, count);
 	crq.valid = (u8)IBMVTPM_VALID_CMD;
 	crq.msg = (u8)VTPM_TPM_COMMAND;
 	crq.len = cpu_to_be16(count);
 	crq.data = cpu_to_be32(ibmvtpm->rtce_dma_handle);
 
+	/*
+	 * set the processing flag before the Hcall, since we may get the
+	 * result (interrupt) before even being able to check rc.
+	 */
+	ibmvtpm->tpm_processing_cmd = true;
+
 	rc = ibmvtpm_send_crq(ibmvtpm->vdev, be64_to_cpu(word[0]),
 			      be64_to_cpu(word[1]));
 	if (rc != H_SUCCESS) {
 		dev_err(ibmvtpm->dev, "tpm_ibmvtpm_send failed rc=%d\n", rc);
 		rc = 0;
+		ibmvtpm->tpm_processing_cmd = false;
 	} else
 		rc = count;
 
@@ -515,6 +532,7 @@ static void ibmvtpm_crq_process(struct i
 		case VTPM_TPM_COMMAND_RES:
 			/* len of the data in rtce buffer */
 			ibmvtpm->res_len = be16_to_cpu(crq->len);
+			ibmvtpm->tpm_processing_cmd = false;
 			wake_up_interruptible(&ibmvtpm->wq);
 			return;
 		default:
--- zfcpdump-kernel-4.4.orig/drivers/char/tpm/tpm_ibmvtpm.h
+++ zfcpdump-kernel-4.4/drivers/char/tpm/tpm_ibmvtpm.h
@@ -45,6 +45,7 @@ struct ibmvtpm_dev {
 	wait_queue_head_t wq;
 	u16 res_len;
 	u32 vtpm_version;
+	bool tpm_processing_cmd;
 };
 
 #define CRQ_RES_BUF_SIZE	PAGE_SIZE
--- zfcpdump-kernel-4.4.orig/drivers/char/tpm/tpm_tis.c
+++ zfcpdump-kernel-4.4/drivers/char/tpm/tpm_tis.c
@@ -28,7 +28,6 @@
 #include <linux/wait.h>
 #include <linux/acpi.h>
 #include <linux/freezer.h>
-#include <acpi/actbl2.h>
 #include "tpm.h"
 
 enum tis_access {
@@ -60,22 +59,18 @@ enum tis_int_flags {
 };
 
 enum tis_defaults {
-	TIS_MEM_BASE = 0xFED40000,
 	TIS_MEM_LEN = 0x5000,
 	TIS_SHORT_TIMEOUT = 750,	/* ms */
 	TIS_LONG_TIMEOUT = 2000,	/* 2 sec */
 };
 
 struct tpm_info {
-	unsigned long start;
-	unsigned long len;
-	unsigned int irq;
-};
-
-static struct tpm_info tis_default_info = {
-	.start = TIS_MEM_BASE,
-	.len = TIS_MEM_LEN,
-	.irq = 0,
+	struct resource res;
+	/* irq > 0 means: use irq $irq;
+	 * irq = 0 means: autoprobe for an irq;
+	 * irq = -1 means: no irq support
+	 */
+	int irq;
 };
 
 /* Some timeout values are needed before it is known whether the chip is
@@ -118,39 +113,11 @@ static inline int is_itpm(struct acpi_de
 {
 	return has_hid(dev, "INTC0102");
 }
-
-static inline int is_fifo(struct acpi_device *dev)
-{
-	struct acpi_table_tpm2 *tbl;
-	acpi_status st;
-
-	/* TPM 1.2 FIFO */
-	if (!has_hid(dev, "MSFT0101"))
-		return 1;
-
-	st = acpi_get_table(ACPI_SIG_TPM2, 1,
-			    (struct acpi_table_header **) &tbl);
-	if (ACPI_FAILURE(st)) {
-		dev_err(&dev->dev, "failed to get TPM2 ACPI table\n");
-		return 0;
-	}
-
-	if (le32_to_cpu(tbl->start_method) != TPM2_START_FIFO)
-		return 0;
-
-	/* TPM 2.0 FIFO */
-	return 1;
-}
 #else
 static inline int is_itpm(struct acpi_device *dev)
 {
 	return 0;
 }
-
-static inline int is_fifo(struct acpi_device *dev)
-{
-	return 1;
-}
 #endif
 
 /* Before we attempt to access the TPM we must see that the valid bit is set.
@@ -401,7 +368,7 @@ static void disable_interrupts(struct tp
 	iowrite32(intmask,
 		  chip->vendor.iobase +
 		  TPM_INT_ENABLE(chip->vendor.locality));
-	free_irq(chip->vendor.irq, chip);
+	devm_free_irq(chip->pdev, chip->vendor.irq, chip);
 	chip->vendor.irq = 0;
 }
 
@@ -461,11 +428,8 @@ static int tpm_tis_send(struct tpm_chip
 	chip->vendor.irq = irq;
 	if (!priv->irq_tested)
 		msleep(1);
-	if (!priv->irq_tested) {
+	if (!priv->irq_tested)
 		disable_interrupts(chip);
-		dev_err(chip->pdev,
-			FW_BUG "TPM interrupt not working, polling instead\n");
-	}
 	priv->irq_tested = true;
 	return rc;
 }
@@ -570,26 +534,6 @@ static const struct tpm_class_ops tpm_ti
 	.req_canceled = tpm_tis_req_canceled,
 };
 
-static irqreturn_t tis_int_probe(int irq, void *dev_id)
-{
-	struct tpm_chip *chip = dev_id;
-	u32 interrupt;
-
-	interrupt = ioread32(chip->vendor.iobase +
-			     TPM_INT_STATUS(chip->vendor.locality));
-
-	if (interrupt == 0)
-		return IRQ_NONE;
-
-	chip->vendor.probed_irq = irq;
-
-	/* Clear interrupts handled with TPM_EOI */
-	iowrite32(interrupt,
-		  chip->vendor.iobase +
-		  TPM_INT_STATUS(chip->vendor.locality));
-	return IRQ_HANDLED;
-}
-
 static irqreturn_t tis_int_handler(int dummy, void *dev_id)
 {
 	struct tpm_chip *chip = dev_id;
@@ -622,6 +566,84 @@ static irqreturn_t tis_int_handler(int d
 	return IRQ_HANDLED;
 }
 
+/* Register the IRQ and issue a command that will cause an interrupt. If an
+ * irq is seen then leave the chip setup for IRQ operation, otherwise reverse
+ * everything and leave in polling mode. Returns 0 on success.
+ */
+static int tpm_tis_probe_irq_single(struct tpm_chip *chip, u32 intmask,
+				    int flags, int irq)
+{
+	struct priv_data *priv = chip->vendor.priv;
+	u8 original_int_vec;
+
+	if (devm_request_irq(chip->pdev, irq, tis_int_handler, flags,
+			     chip->devname, chip) != 0) {
+		dev_info(chip->pdev, "Unable to request irq: %d for probe\n",
+			 irq);
+		return -1;
+	}
+	chip->vendor.irq = irq;
+
+	original_int_vec = ioread8(chip->vendor.iobase +
+				   TPM_INT_VECTOR(chip->vendor.locality));
+	iowrite8(irq,
+		 chip->vendor.iobase + TPM_INT_VECTOR(chip->vendor.locality));
+
+	/* Clear all existing */
+	iowrite32(ioread32(chip->vendor.iobase +
+			   TPM_INT_STATUS(chip->vendor.locality)),
+		  chip->vendor.iobase + TPM_INT_STATUS(chip->vendor.locality));
+
+	/* Turn on */
+	iowrite32(intmask | TPM_GLOBAL_INT_ENABLE,
+		  chip->vendor.iobase + TPM_INT_ENABLE(chip->vendor.locality));
+
+	priv->irq_tested = false;
+
+	/* Generate an interrupt by having the core call through to
+	 * tpm_tis_send
+	 */
+	if (chip->flags & TPM_CHIP_FLAG_TPM2)
+		tpm2_gen_interrupt(chip);
+	else
+		tpm_gen_interrupt(chip);
+
+	/* tpm_tis_send will either confirm the interrupt is working or it
+	 * will call disable_irq which undoes all of the above.
+	 */
+	if (!chip->vendor.irq) {
+		iowrite8(original_int_vec,
+			 chip->vendor.iobase +
+			     TPM_INT_VECTOR(chip->vendor.locality));
+		return 1;
+	}
+
+	return 0;
+}
+
+/* Try to find the IRQ the TPM is using. This is for legacy x86 systems that
+ * do not have ACPI/etc. We typically expect the interrupt to be declared if
+ * present.
+ */
+static void tpm_tis_probe_irq(struct tpm_chip *chip, u32 intmask)
+{
+	u8 original_int_vec;
+	int i;
+
+	original_int_vec = ioread8(chip->vendor.iobase +
+				   TPM_INT_VECTOR(chip->vendor.locality));
+
+	if (!original_int_vec) {
+		if (IS_ENABLED(CONFIG_X86))
+			for (i = 3; i <= 15; i++)
+				if (!tpm_tis_probe_irq_single(chip, intmask, 0,
+							      i))
+					return;
+	} else if (!tpm_tis_probe_irq_single(chip, intmask, 0,
+					     original_int_vec))
+		return;
+}
+
 static bool interrupts = true;
 module_param(interrupts, bool, 0444);
 MODULE_PARM_DESC(interrupts, "Enable interrupts");
@@ -644,8 +666,7 @@ static int tpm_tis_init(struct device *d
 			acpi_handle acpi_dev_handle)
 {
 	u32 vendor, intfcaps, intmask;
-	int rc, i, irq_s, irq_e, probe;
-	int irq_r = -1;
+	int rc, probe;
 	struct tpm_chip *chip;
 	struct priv_data *priv;
 
@@ -662,9 +683,9 @@ static int tpm_tis_init(struct device *d
 	chip->acpi_dev_handle = acpi_dev_handle;
 #endif
 
-	chip->vendor.iobase = devm_ioremap(dev, tpm_info->start, tpm_info->len);
-	if (!chip->vendor.iobase)
-		return -EIO;
+	chip->vendor.iobase = devm_ioremap_resource(dev, &tpm_info->res);
+	if (IS_ERR(chip->vendor.iobase))
+		return PTR_ERR(chip->vendor.iobase);
 
 	/* Maximum timeouts */
 	chip->vendor.timeout_a = TIS_TIMEOUT_A_MAX;
@@ -677,6 +698,15 @@ static int tpm_tis_init(struct device *d
 		goto out_err;
 	}
 
+	/* Take control of the TPM's interrupt hardware and shut it off */
+	intmask = ioread32(chip->vendor.iobase +
+			   TPM_INT_ENABLE(chip->vendor.locality));
+	intmask |= TPM_INTF_CMD_READY_INT | TPM_INTF_LOCALITY_CHANGE_INT |
+		   TPM_INTF_DATA_AVAIL_INT | TPM_INTF_STS_VALID_INT;
+	intmask &= ~TPM_GLOBAL_INT_ENABLE;
+	iowrite32(intmask,
+		  chip->vendor.iobase + TPM_INT_ENABLE(chip->vendor.locality));
+
 	if (request_locality(chip, 0) != 0) {
 		rc = -ENODEV;
 		goto out_err;
@@ -731,126 +761,31 @@ static int tpm_tis_init(struct device *d
 	if (intfcaps & TPM_INTF_DATA_AVAIL_INT)
 		dev_dbg(dev, "\tData Avail Int Support\n");
 
+	/* Very early on issue a command to the TPM in polling mode to make
+	 * sure it works. May as well use that command to set the proper
+	 *  timeouts for the driver.
+	 */
+	if (tpm_get_timeouts(chip)) {
+		dev_err(dev, "Could not get TPM timeouts and durations\n");
+		rc = -ENODEV;
+		goto out_err;
+	}
+
 	/* INTERRUPT Setup */
 	init_waitqueue_head(&chip->vendor.read_queue);
 	init_waitqueue_head(&chip->vendor.int_queue);
-
-	intmask =
-	    ioread32(chip->vendor.iobase +
-		     TPM_INT_ENABLE(chip->vendor.locality));
-
-	intmask |= TPM_INTF_CMD_READY_INT
-	    | TPM_INTF_LOCALITY_CHANGE_INT | TPM_INTF_DATA_AVAIL_INT
-	    | TPM_INTF_STS_VALID_INT;
-
-	iowrite32(intmask,
-		  chip->vendor.iobase +
-		  TPM_INT_ENABLE(chip->vendor.locality));
-	if (interrupts)
-		chip->vendor.irq = tpm_info->irq;
-	if (interrupts && !chip->vendor.irq) {
-		irq_s =
-		    ioread8(chip->vendor.iobase +
-			    TPM_INT_VECTOR(chip->vendor.locality));
-		irq_r = irq_s;
-		if (irq_s) {
-			irq_e = irq_s;
-		} else {
-			irq_s = 3;
-			irq_e = 15;
-		}
-
-		for (i = irq_s; i <= irq_e && chip->vendor.irq == 0; i++) {
-			iowrite8(i, chip->vendor.iobase +
-				 TPM_INT_VECTOR(chip->vendor.locality));
-			if (devm_request_irq
-			    (dev, i, tis_int_probe, IRQF_SHARED,
-			     chip->devname, chip) != 0) {
-				dev_info(chip->pdev,
-					 "Unable to request irq: %d for probe\n",
-					 i);
-				continue;
-			}
-
-			/* Clear all existing */
-			iowrite32(ioread32
-				  (chip->vendor.iobase +
-				   TPM_INT_STATUS(chip->vendor.locality)),
-				  chip->vendor.iobase +
-				  TPM_INT_STATUS(chip->vendor.locality));
-
-			/* Turn on */
-			iowrite32(intmask | TPM_GLOBAL_INT_ENABLE,
-				  chip->vendor.iobase +
-				  TPM_INT_ENABLE(chip->vendor.locality));
-
-			chip->vendor.probed_irq = 0;
-
-			/* Generate Interrupts */
-			if (chip->flags & TPM_CHIP_FLAG_TPM2)
-				tpm2_gen_interrupt(chip);
-			else
-				tpm_gen_interrupt(chip);
-
-			chip->vendor.irq = chip->vendor.probed_irq;
-
-			/* free_irq will call into tis_int_probe;
-			   clear all irqs we haven't seen while doing
-			   tpm_gen_interrupt */
-			iowrite32(ioread32
-				  (chip->vendor.iobase +
-				   TPM_INT_STATUS(chip->vendor.locality)),
-				  chip->vendor.iobase +
-				  TPM_INT_STATUS(chip->vendor.locality));
-
-			/* Turn off */
-			iowrite32(intmask,
-				  chip->vendor.iobase +
-				  TPM_INT_ENABLE(chip->vendor.locality));
-
-			devm_free_irq(dev, i, chip);
-		}
+	if (interrupts && tpm_info->irq != -1) {
+		if (tpm_info->irq) {
+			tpm_tis_probe_irq_single(chip, intmask, IRQF_SHARED,
+						 tpm_info->irq);
+			if (!chip->vendor.irq)
+				dev_err(chip->pdev, FW_BUG
+					"TPM interrupt not working, polling instead\n");
+		} else
+			tpm_tis_probe_irq(chip, intmask);
 	}
-	if (chip->vendor.irq) {
-		iowrite8(chip->vendor.irq,
-			 chip->vendor.iobase +
-			 TPM_INT_VECTOR(chip->vendor.locality));
-		if (devm_request_irq
-		    (dev, chip->vendor.irq, tis_int_handler, IRQF_SHARED,
-		     chip->devname, chip) != 0) {
-			dev_info(chip->pdev,
-				 "Unable to request irq: %d for use\n",
-				 chip->vendor.irq);
-			chip->vendor.irq = 0;
-		} else {
-			/* Clear all existing */
-			iowrite32(ioread32
-				  (chip->vendor.iobase +
-				   TPM_INT_STATUS(chip->vendor.locality)),
-				  chip->vendor.iobase +
-				  TPM_INT_STATUS(chip->vendor.locality));
-
-			/* Turn on */
-			iowrite32(intmask | TPM_GLOBAL_INT_ENABLE,
-				  chip->vendor.iobase +
-				  TPM_INT_ENABLE(chip->vendor.locality));
-		}
-	} else if (irq_r != -1)
-		iowrite8(irq_r, chip->vendor.iobase +
-			 TPM_INT_VECTOR(chip->vendor.locality));
 
 	if (chip->flags & TPM_CHIP_FLAG_TPM2) {
-		chip->vendor.timeout_a = msecs_to_jiffies(TPM2_TIMEOUT_A);
-		chip->vendor.timeout_b = msecs_to_jiffies(TPM2_TIMEOUT_B);
-		chip->vendor.timeout_c = msecs_to_jiffies(TPM2_TIMEOUT_C);
-		chip->vendor.timeout_d = msecs_to_jiffies(TPM2_TIMEOUT_D);
-		chip->vendor.duration[TPM_SHORT] =
-			msecs_to_jiffies(TPM2_DURATION_SHORT);
-		chip->vendor.duration[TPM_MEDIUM] =
-			msecs_to_jiffies(TPM2_DURATION_MEDIUM);
-		chip->vendor.duration[TPM_LONG] =
-			msecs_to_jiffies(TPM2_DURATION_LONG);
-
 		rc = tpm2_do_selftest(chip);
 		if (rc == TPM2_RC_INITIALIZE) {
 			dev_warn(dev, "Firmware has not started TPM\n");
@@ -866,12 +801,6 @@ static int tpm_tis_init(struct device *d
 			goto out_err;
 		}
 	} else {
-		if (tpm_get_timeouts(chip)) {
-			dev_err(dev, "Could not get TPM timeouts and durations\n");
-			rc = -ENODEV;
-			goto out_err;
-		}
-
 		if (tpm_do_selftest(chip)) {
 			dev_err(dev, "TPM self test failed\n");
 			rc = -ENODEV;
@@ -931,29 +860,29 @@ static int tpm_tis_resume(struct device
 
 static SIMPLE_DEV_PM_OPS(tpm_tis_pm, tpm_pm_suspend, tpm_tis_resume);
 
-#ifdef CONFIG_PNP
 static int tpm_tis_pnp_init(struct pnp_dev *pnp_dev,
-				      const struct pnp_device_id *pnp_id)
+			    const struct pnp_device_id *pnp_id)
 {
-	struct tpm_info tpm_info = tis_default_info;
+	struct tpm_info tpm_info = {};
 	acpi_handle acpi_dev_handle = NULL;
+	struct resource *res;
 
-	tpm_info.start = pnp_mem_start(pnp_dev, 0);
-	tpm_info.len = pnp_mem_len(pnp_dev, 0);
+	res = pnp_get_resource(pnp_dev, IORESOURCE_MEM, 0);
+	if (!res)
+		return -ENODEV;
+	tpm_info.res = *res;
 
 	if (pnp_irq_valid(pnp_dev, 0))
 		tpm_info.irq = pnp_irq(pnp_dev, 0);
 	else
-		interrupts = false;
+		tpm_info.irq = -1;
 
-#ifdef CONFIG_ACPI
 	if (pnp_acpi_device(pnp_dev)) {
 		if (is_itpm(pnp_acpi_device(pnp_dev)))
 			itpm = true;
 
-		acpi_dev_handle = pnp_acpi_device(pnp_dev)->handle;
+		acpi_dev_handle = ACPI_HANDLE(&pnp_dev->dev);
 	}
-#endif
 
 	return tpm_tis_init(&pnp_dev->dev, &tpm_info, acpi_dev_handle);
 }
@@ -994,7 +923,6 @@ static struct pnp_driver tis_pnp_driver
 module_param_string(hid, tpm_pnp_tbl[TIS_HID_USR_IDX].id,
 		    sizeof(tpm_pnp_tbl[TIS_HID_USR_IDX].id), 0444);
 MODULE_PARM_DESC(hid, "Set additional specific HID for this driver to probe");
-#endif
 
 #ifdef CONFIG_ACPI
 static int tpm_check_resource(struct acpi_resource *ares, void *data)
@@ -1002,11 +930,11 @@ static int tpm_check_resource(struct acp
 	struct tpm_info *tpm_info = (struct tpm_info *) data;
 	struct resource res;
 
-	if (acpi_dev_resource_interrupt(ares, 0, &res)) {
+	if (acpi_dev_resource_interrupt(ares, 0, &res))
 		tpm_info->irq = res.start;
-	} else if (acpi_dev_resource_memory(ares, &res)) {
-		tpm_info->start = res.start;
-		tpm_info->len = resource_size(&res);
+	else if (acpi_dev_resource_memory(ares, &res)) {
+		tpm_info->res = res;
+		tpm_info->res.name = NULL;
 	}
 
 	return 1;
@@ -1014,14 +942,25 @@ static int tpm_check_resource(struct acp
 
 static int tpm_tis_acpi_init(struct acpi_device *acpi_dev)
 {
+	struct acpi_table_tpm2 *tbl;
+	acpi_status st;
 	struct list_head resources;
-	struct tpm_info tpm_info = tis_default_info;
+	struct tpm_info tpm_info = {};
 	int ret;
 
-	if (!is_fifo(acpi_dev))
+	st = acpi_get_table(ACPI_SIG_TPM2, 1,
+			    (struct acpi_table_header **) &tbl);
+	if (ACPI_FAILURE(st) || tbl->header.length < sizeof(*tbl)) {
+		dev_err(&acpi_dev->dev,
+			FW_BUG "failed to get TPM2 ACPI table\n");
+		return -EINVAL;
+	}
+
+	if (tbl->start_method != ACPI_TPM2_MEMORY_MAPPED)
 		return -ENODEV;
 
 	INIT_LIST_HEAD(&resources);
+	tpm_info.irq = -1;
 	ret = acpi_dev_get_resources(acpi_dev, &resources, tpm_check_resource,
 				     &tpm_info);
 	if (ret < 0)
@@ -1029,8 +968,11 @@ static int tpm_tis_acpi_init(struct acpi
 
 	acpi_dev_free_resource_list(&resources);
 
-	if (!tpm_info.irq)
-		interrupts = false;
+	if (resource_type(&tpm_info.res) != IORESOURCE_MEM) {
+		dev_err(&acpi_dev->dev,
+			FW_BUG "TPM2 ACPI table does not define a memory resource\n");
+		return -EINVAL;
+	}
 
 	if (is_itpm(acpi_dev))
 		itpm = true;
@@ -1069,80 +1011,135 @@ static struct acpi_driver tis_acpi_drive
 };
 #endif
 
+static struct platform_device *force_pdev;
+
+static int tpm_tis_plat_probe(struct platform_device *pdev)
+{
+	struct tpm_info tpm_info = {};
+	struct resource *res;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (res == NULL) {
+		dev_err(&pdev->dev, "no memory resource defined\n");
+		return -ENODEV;
+	}
+	tpm_info.res = *res;
+
+	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+	if (res) {
+		tpm_info.irq = res->start;
+	} else {
+		if (pdev == force_pdev)
+			tpm_info.irq = -1;
+		else
+			/* When forcing auto probe the IRQ */
+			tpm_info.irq = 0;
+	}
+
+	return tpm_tis_init(&pdev->dev, &tpm_info, NULL);
+}
+
+static int tpm_tis_plat_remove(struct platform_device *pdev)
+{
+	struct tpm_chip *chip = dev_get_drvdata(&pdev->dev);
+
+	tpm_chip_unregister(chip);
+	tpm_tis_remove(chip);
+
+	return 0;
+}
+
 static struct platform_driver tis_drv = {
+	.probe = tpm_tis_plat_probe,
+	.remove = tpm_tis_plat_remove,
 	.driver = {
 		.name		= "tpm_tis",
 		.pm		= &tpm_tis_pm,
 	},
 };
 
-static struct platform_device *pdev;
-
 static bool force;
+#ifdef CONFIG_X86
 module_param(force, bool, 0444);
 MODULE_PARM_DESC(force, "Force device probe rather than using ACPI entry");
+#endif
+
+static int tpm_tis_force_device(void)
+{
+	struct platform_device *pdev;
+	static const struct resource x86_resources[] = {
+		{
+			.start = 0xFED40000,
+			.end = 0xFED40000 + TIS_MEM_LEN - 1,
+			.flags = IORESOURCE_MEM,
+		},
+	};
+
+	if (!force)
+		return 0;
+
+	/* The driver core will match the name tpm_tis of the device to
+	 * the tpm_tis platform driver and complete the setup via
+	 * tpm_tis_plat_probe
+	 */
+	pdev = platform_device_register_simple("tpm_tis", -1, x86_resources,
+					       ARRAY_SIZE(x86_resources));
+	if (IS_ERR(pdev))
+		return PTR_ERR(pdev);
+	force_pdev = pdev;
+
+	return 0;
+}
+
 static int __init init_tis(void)
 {
 	int rc;
-#ifdef CONFIG_PNP
-	if (!force) {
-		rc = pnp_register_driver(&tis_pnp_driver);
-		if (rc)
-			return rc;
-	}
-#endif
+
+	rc = tpm_tis_force_device();
+	if (rc)
+		goto err_force;
+
+	rc = platform_driver_register(&tis_drv);
+	if (rc)
+		goto err_platform;
+
 #ifdef CONFIG_ACPI
-	if (!force) {
-		rc = acpi_bus_register_driver(&tis_acpi_driver);
-		if (rc) {
-#ifdef CONFIG_PNP
-			pnp_unregister_driver(&tis_pnp_driver);
-#endif
-			return rc;
-		}
-	}
+	rc = acpi_bus_register_driver(&tis_acpi_driver);
+	if (rc)
+		goto err_acpi;
 #endif
-	if (!force)
-		return 0;
 
-	rc = platform_driver_register(&tis_drv);
-	if (rc < 0)
-		return rc;
-	pdev = platform_device_register_simple("tpm_tis", -1, NULL, 0);
-	if (IS_ERR(pdev)) {
-		rc = PTR_ERR(pdev);
-		goto err_dev;
+	if (IS_ENABLED(CONFIG_PNP)) {
+		rc = pnp_register_driver(&tis_pnp_driver);
+		if (rc)
+			goto err_pnp;
 	}
-	rc = tpm_tis_init(&pdev->dev, &tis_default_info, NULL);
-	if (rc)
-		goto err_init;
+
 	return 0;
-err_init:
-	platform_device_unregister(pdev);
-err_dev:
-	platform_driver_unregister(&tis_drv);
+
+err_pnp:
+#ifdef CONFIG_ACPI
+	acpi_bus_unregister_driver(&tis_acpi_driver);
+err_acpi:
+#endif
+	platform_device_unregister(force_pdev);
+err_platform:
+	if (force_pdev)
+		platform_device_unregister(force_pdev);
+err_force:
 	return rc;
 }
 
 static void __exit cleanup_tis(void)
 {
-	struct tpm_chip *chip;
-#if defined(CONFIG_PNP) || defined(CONFIG_ACPI)
-	if (!force) {
+	pnp_unregister_driver(&tis_pnp_driver);
 #ifdef CONFIG_ACPI
-		acpi_bus_unregister_driver(&tis_acpi_driver);
-#endif
-#ifdef CONFIG_PNP
-		pnp_unregister_driver(&tis_pnp_driver);
+	acpi_bus_unregister_driver(&tis_acpi_driver);
 #endif
-		return;
-	}
-#endif
-	chip = dev_get_drvdata(&pdev->dev);
-	tpm_chip_unregister(chip);
-	tpm_tis_remove(chip);
-	platform_device_unregister(pdev);
 	platform_driver_unregister(&tis_drv);
+
+	if (force_pdev)
+		platform_device_unregister(force_pdev);
 }
 
 module_init(init_tis);
--- zfcpdump-kernel-4.4.orig/drivers/clk/at91/clk-h32mx.c
+++ zfcpdump-kernel-4.4/drivers/clk/at91/clk-h32mx.c
@@ -116,7 +116,7 @@ void __init of_sama5d4_clk_h32mx_setup(s
 	h32mxclk->pmc = pmc;
 
 	clk = clk_register(NULL, &h32mxclk->hw);
-	if (!clk) {
+	if (IS_ERR(clk)) {
 		kfree(h32mxclk);
 		return;
 	}
--- zfcpdump-kernel-4.4.orig/drivers/clk/bcm/clk-bcm2835.c
+++ zfcpdump-kernel-4.4/drivers/clk/bcm/clk-bcm2835.c
@@ -890,8 +890,14 @@ static void bcm2835_pll_off(struct clk_h
 	struct bcm2835_cprman *cprman = pll->cprman;
 	const struct bcm2835_pll_data *data = pll->data;
 
-	cprman_write(cprman, data->cm_ctrl_reg, CM_PLL_ANARST);
-	cprman_write(cprman, data->a2w_ctrl_reg, A2W_PLL_CTRL_PWRDN);
+	spin_lock(&cprman->regs_lock);
+	cprman_write(cprman, data->cm_ctrl_reg,
+		     cprman_read(cprman, data->cm_ctrl_reg) |
+		     CM_PLL_ANARST);
+	cprman_write(cprman, data->a2w_ctrl_reg,
+		     cprman_read(cprman, data->a2w_ctrl_reg) |
+		     A2W_PLL_CTRL_PWRDN);
+	spin_unlock(&cprman->regs_lock);
 }
 
 static int bcm2835_pll_on(struct clk_hw *hw)
@@ -901,6 +907,10 @@ static int bcm2835_pll_on(struct clk_hw
 	const struct bcm2835_pll_data *data = pll->data;
 	ktime_t timeout;
 
+	cprman_write(cprman, data->a2w_ctrl_reg,
+		     cprman_read(cprman, data->a2w_ctrl_reg) &
+		     ~A2W_PLL_CTRL_PWRDN);
+
 	/* Take the PLL out of reset. */
 	cprman_write(cprman, data->cm_ctrl_reg,
 		     cprman_read(cprman, data->cm_ctrl_reg) & ~CM_PLL_ANARST);
@@ -1068,10 +1078,12 @@ static void bcm2835_pll_divider_off(stru
 	struct bcm2835_cprman *cprman = divider->cprman;
 	const struct bcm2835_pll_divider_data *data = divider->data;
 
+	spin_lock(&cprman->regs_lock);
 	cprman_write(cprman, data->cm_reg,
 		     (cprman_read(cprman, data->cm_reg) &
 		      ~data->load_mask) | data->hold_mask);
 	cprman_write(cprman, data->a2w_reg, A2W_PLL_CHANNEL_DISABLE);
+	spin_unlock(&cprman->regs_lock);
 }
 
 static int bcm2835_pll_divider_on(struct clk_hw *hw)
@@ -1080,12 +1092,14 @@ static int bcm2835_pll_divider_on(struct
 	struct bcm2835_cprman *cprman = divider->cprman;
 	const struct bcm2835_pll_divider_data *data = divider->data;
 
+	spin_lock(&cprman->regs_lock);
 	cprman_write(cprman, data->a2w_reg,
 		     cprman_read(cprman, data->a2w_reg) &
 		     ~A2W_PLL_CHANNEL_DISABLE);
 
 	cprman_write(cprman, data->cm_reg,
 		     cprman_read(cprman, data->cm_reg) & ~data->hold_mask);
+	spin_unlock(&cprman->regs_lock);
 
 	return 0;
 }
@@ -1097,13 +1111,15 @@ static int bcm2835_pll_divider_set_rate(
 	struct bcm2835_pll_divider *divider = bcm2835_pll_divider_from_hw(hw);
 	struct bcm2835_cprman *cprman = divider->cprman;
 	const struct bcm2835_pll_divider_data *data = divider->data;
-	u32 cm;
-	int ret;
+	u32 cm, div, max_div = 1 << A2W_PLL_DIV_BITS;
+
+	div = DIV_ROUND_UP_ULL(parent_rate, rate);
 
-	ret = clk_divider_ops.set_rate(hw, rate, parent_rate);
-	if (ret)
-		return ret;
+	div = min(div, max_div);
+	if (div == max_div)
+		div = 0;
 
+	cprman_write(cprman, data->a2w_reg, div);
 	cm = cprman_read(cprman, data->cm_reg);
 	cprman_write(cprman, data->cm_reg, cm | data->load_mask);
 	cprman_write(cprman, data->cm_reg, cm & ~data->load_mask);
@@ -1165,8 +1181,9 @@ static u32 bcm2835_clock_choose_div(stru
 		div &= ~unused_frac_mask;
 	}
 
-	/* Clamp to the limits. */
-	div = max(div, unused_frac_mask + 1);
+	/* clamp to min divider of 1 */
+	div = max_t(u32, div, 1 << CM_DIV_FRAC_BITS);
+	/* clamp to the highest possible fractional divider */
 	div = min_t(u32, div, GENMASK(data->int_bits + CM_DIV_FRAC_BITS - 1,
 				      CM_DIV_FRAC_BITS - data->frac_bits));
 
--- zfcpdump-kernel-4.4.orig/drivers/clk/clk-divider.c
+++ zfcpdump-kernel-4.4/drivers/clk/clk-divider.c
@@ -422,6 +422,12 @@ const struct clk_ops clk_divider_ops = {
 };
 EXPORT_SYMBOL_GPL(clk_divider_ops);
 
+const struct clk_ops clk_divider_ro_ops = {
+	.recalc_rate = clk_divider_recalc_rate,
+	.round_rate = clk_divider_round_rate,
+};
+EXPORT_SYMBOL_GPL(clk_divider_ro_ops);
+
 static struct clk *_register_divider(struct device *dev, const char *name,
 		const char *parent_name, unsigned long flags,
 		void __iomem *reg, u8 shift, u8 width,
@@ -445,7 +451,10 @@ static struct clk *_register_divider(str
 		return ERR_PTR(-ENOMEM);
 
 	init.name = name;
-	init.ops = &clk_divider_ops;
+	if (clk_divider_flags & CLK_DIVIDER_READ_ONLY)
+		init.ops = &clk_divider_ro_ops;
+	else
+		init.ops = &clk_divider_ops;
 	init.flags = flags | CLK_IS_BASIC;
 	init.parent_names = (parent_name ? &parent_name: NULL);
 	init.num_parents = (parent_name ? 1 : 0);
--- zfcpdump-kernel-4.4.orig/drivers/clk/clk-xgene.c
+++ zfcpdump-kernel-4.4/drivers/clk/clk-xgene.c
@@ -29,7 +29,9 @@
 #include <linux/of_address.h>
 
 /* Register SCU_PCPPLL bit fields */
-#define N_DIV_RD(src)			(((src) & 0x000001ff))
+#define N_DIV_RD(src)			((src) & 0x000001ff)
+#define SC_N_DIV_RD(src)		((src) & 0x0000007f)
+#define SC_OUTDIV2(src)			(((src) & 0x00000100) >> 8)
 
 /* Register SCU_SOCPLL bit fields */
 #define CLKR_RD(src)			(((src) & 0x07000000)>>24)
@@ -63,6 +65,7 @@ struct xgene_clk_pll {
 	spinlock_t	*lock;
 	u32		pll_offset;
 	enum xgene_pll_type	type;
+	int		version;
 };
 
 #define to_xgene_clk_pll(_hw) container_of(_hw, struct xgene_clk_pll, hw)
@@ -92,27 +95,37 @@ static unsigned long xgene_clk_pll_recal
 
 	pll = xgene_clk_read(pllclk->reg + pllclk->pll_offset);
 
-	if (pllclk->type == PLL_TYPE_PCP) {
-		/*
-		 * PLL VCO = Reference clock * NF
-		 * PCP PLL = PLL_VCO / 2
-		 */
-		nout = 2;
-		fvco = parent_rate * (N_DIV_RD(pll) + 4);
+	if (pllclk->version <= 1) {
+		if (pllclk->type == PLL_TYPE_PCP) {
+			/*
+			* PLL VCO = Reference clock * NF
+			* PCP PLL = PLL_VCO / 2
+			*/
+			nout = 2;
+			fvco = parent_rate * (N_DIV_RD(pll) + 4);
+		} else {
+			/*
+			* Fref = Reference Clock / NREF;
+			* Fvco = Fref * NFB;
+			* Fout = Fvco / NOUT;
+			*/
+			nref = CLKR_RD(pll) + 1;
+			nout = CLKOD_RD(pll) + 1;
+			nfb = CLKF_RD(pll);
+			fref = parent_rate / nref;
+			fvco = fref * nfb;
+		}
 	} else {
 		/*
-		 * Fref = Reference Clock / NREF;
-		 * Fvco = Fref * NFB;
-		 * Fout = Fvco / NOUT;
+		 * fvco = Reference clock * FBDIVC
+		 * PLL freq = fvco / NOUT
 		 */
-		nref = CLKR_RD(pll) + 1;
-		nout = CLKOD_RD(pll) + 1;
-		nfb = CLKF_RD(pll);
-		fref = parent_rate / nref;
-		fvco = fref * nfb;
+		nout = SC_OUTDIV2(pll) ? 2 : 3;
+		fvco = parent_rate * SC_N_DIV_RD(pll);
 	}
-	pr_debug("%s pll recalc rate %ld parent %ld\n", clk_hw_get_name(hw),
-		fvco / nout, parent_rate);
+	pr_debug("%s pll recalc rate %ld parent %ld version %d\n",
+		 clk_hw_get_name(hw), fvco / nout, parent_rate,
+		 pllclk->version);
 
 	return fvco / nout;
 }
@@ -125,7 +138,7 @@ static const struct clk_ops xgene_clk_pl
 static struct clk *xgene_register_clk_pll(struct device *dev,
 	const char *name, const char *parent_name,
 	unsigned long flags, void __iomem *reg, u32 pll_offset,
-	u32 type, spinlock_t *lock)
+	u32 type, spinlock_t *lock, int version)
 {
 	struct xgene_clk_pll *apmclk;
 	struct clk *clk;
@@ -144,6 +157,7 @@ static struct clk *xgene_register_clk_pl
 	init.parent_names = parent_name ? &parent_name : NULL;
 	init.num_parents = parent_name ? 1 : 0;
 
+	apmclk->version = version;
 	apmclk->reg = reg;
 	apmclk->lock = lock;
 	apmclk->pll_offset = pll_offset;
@@ -160,26 +174,37 @@ static struct clk *xgene_register_clk_pl
 	return clk;
 }
 
+static int xgene_pllclk_version(struct device_node *np)
+{
+	if (of_device_is_compatible(np, "apm,xgene-socpll-clock"))
+		return 1;
+	if (of_device_is_compatible(np, "apm,xgene-pcppll-clock"))
+		return 1;
+	return 2;
+}
+
 static void xgene_pllclk_init(struct device_node *np, enum xgene_pll_type pll_type)
 {
-        const char *clk_name = np->full_name;
-        struct clk *clk;
-        void __iomem *reg;
-
-        reg = of_iomap(np, 0);
-        if (reg == NULL) {
-                pr_err("Unable to map CSR register for %s\n", np->full_name);
-                return;
-        }
-        of_property_read_string(np, "clock-output-names", &clk_name);
-        clk = xgene_register_clk_pll(NULL,
-                        clk_name, of_clk_get_parent_name(np, 0),
-                        CLK_IS_ROOT, reg, 0, pll_type, &clk_lock);
-        if (!IS_ERR(clk)) {
-                of_clk_add_provider(np, of_clk_src_simple_get, clk);
-                clk_register_clkdev(clk, clk_name, NULL);
-                pr_debug("Add %s clock PLL\n", clk_name);
-        }
+	const char *clk_name = np->full_name;
+	struct clk *clk;
+	void __iomem *reg;
+	int version = xgene_pllclk_version(np);
+
+	reg = of_iomap(np, 0);
+	if (reg == NULL) {
+		pr_err("Unable to map CSR register for %s\n", np->full_name);
+		return;
+	}
+	of_property_read_string(np, "clock-output-names", &clk_name);
+	clk = xgene_register_clk_pll(NULL,
+			clk_name, of_clk_get_parent_name(np, 0),
+			CLK_IS_ROOT, reg, 0, pll_type, &clk_lock,
+			version);
+	if (!IS_ERR(clk)) {
+		of_clk_add_provider(np, of_clk_src_simple_get, clk);
+		clk_register_clkdev(clk, clk_name, NULL);
+		pr_debug("Add %s clock PLL\n", clk_name);
+	}
 }
 
 static void xgene_socpllclk_init(struct device_node *np)
@@ -351,7 +376,8 @@ static int xgene_clk_set_rate(struct clk
 		/* Set new divider */
 		data = xgene_clk_read(pclk->param.divider_reg +
 				pclk->param.reg_divider_offset);
-		data &= ~((1 << pclk->param.reg_divider_width) - 1);
+		data &= ~(((1 << pclk->param.reg_divider_width) - 1)
+				<< pclk->param.reg_divider_shift);
 		data |= divider;
 		xgene_clk_write(data, pclk->param.divider_reg +
 					pclk->param.reg_divider_offset);
@@ -459,7 +485,7 @@ static void __init xgene_devclk_init(str
 		rc = of_address_to_resource(np, i, &res);
 		if (rc != 0) {
 			if (i == 0) {
-				pr_err("no DTS register for %s\n", 
+				pr_err("no DTS register for %s\n",
 					np->full_name);
 				return;
 			}
@@ -517,4 +543,8 @@ err:
 
 CLK_OF_DECLARE(xgene_socpll_clock, "apm,xgene-socpll-clock", xgene_socpllclk_init);
 CLK_OF_DECLARE(xgene_pcppll_clock, "apm,xgene-pcppll-clock", xgene_pcppllclk_init);
+CLK_OF_DECLARE(xgene_socpll_v2_clock, "apm,xgene-socpll-v2-clock",
+	       xgene_socpllclk_init);
+CLK_OF_DECLARE(xgene_pcppll_v2_clock, "apm,xgene-pcppll-v2-clock",
+	       xgene_pcppllclk_init);
 CLK_OF_DECLARE(xgene_dev_clock, "apm,xgene-device-clock", xgene_devclk_init);
--- zfcpdump-kernel-4.4.orig/drivers/clk/imx/clk-imx35.c
+++ zfcpdump-kernel-4.4/drivers/clk/imx/clk-imx35.c
@@ -66,7 +66,7 @@ static const char *std_sel[] = {"ppll",
 static const char *ipg_per_sel[] = {"ahb_per_div", "arm_per_div"};
 
 enum mx35_clks {
-	ckih, ckil, mpll, ppll, mpll_075, arm, hsp, hsp_div, hsp_sel, ahb, ipg,
+	ckih, mpll, ppll, mpll_075, arm, hsp, hsp_div, hsp_sel, ahb, ipg,
 	arm_per_div, ahb_per_div, ipg_per, uart_sel, uart_div, esdhc_sel,
 	esdhc1_div, esdhc2_div, esdhc3_div, spdif_sel, spdif_div_pre,
 	spdif_div_post, ssi_sel, ssi1_div_pre, ssi1_div_post, ssi2_div_pre,
@@ -79,7 +79,7 @@ enum mx35_clks {
 	rtc_gate, rtic_gate, scc_gate, sdma_gate, spba_gate, spdif_gate,
 	ssi1_gate, ssi2_gate, uart1_gate, uart2_gate, uart3_gate, usbotg_gate,
 	wdog_gate, max_gate, admux_gate, csi_gate, csi_div, csi_sel, iim_gate,
-	gpu2d_gate, clk_max
+	gpu2d_gate, ckil, clk_max
 };
 
 static struct clk *clk[clk_max];
--- zfcpdump-kernel-4.4.orig/drivers/clk/meson/clkc.c
+++ zfcpdump-kernel-4.4/drivers/clk/meson/clkc.c
@@ -198,7 +198,7 @@ meson_clk_register_fixed_rate(const stru
 }
 
 void __init meson_clk_register_clks(const struct clk_conf *clk_confs,
-				    size_t nr_confs,
+				    unsigned int nr_confs,
 				    void __iomem *clk_base)
 {
 	unsigned int i;
--- zfcpdump-kernel-4.4.orig/drivers/clk/nxp/clk-lpc18xx-ccu.c
+++ zfcpdump-kernel-4.4/drivers/clk/nxp/clk-lpc18xx-ccu.c
@@ -222,7 +222,7 @@ static void lpc18xx_ccu_register_branch_
 		div->width = 1;
 
 		div_hw = &div->hw;
-		div_ops = &clk_divider_ops;
+		div_ops = &clk_divider_ro_ops;
 	}
 
 	branch->gate.reg = branch->offset + reg_base;
--- zfcpdump-kernel-4.4.orig/drivers/clk/qcom/gcc-msm8916.c
+++ zfcpdump-kernel-4.4/drivers/clk/qcom/gcc-msm8916.c
@@ -2346,6 +2346,7 @@ static struct clk_branch gcc_crypto_ahb_
 				"pcnoc_bfdcd_clk_src",
 			},
 			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
 			.ops = &clk_branch2_ops,
 		},
 	},
@@ -2381,6 +2382,7 @@ static struct clk_branch gcc_crypto_clk
 				"crypto_clk_src",
 			},
 			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
 			.ops = &clk_branch2_ops,
 		},
 	},
--- zfcpdump-kernel-4.4.orig/drivers/clk/qcom/gcc-msm8960.c
+++ zfcpdump-kernel-4.4/drivers/clk/qcom/gcc-msm8960.c
@@ -2753,7 +2753,7 @@ static struct clk_rcg ce3_src = {
 	},
 	.freq_tbl = clk_tbl_ce3,
 	.clkr = {
-		.enable_reg = 0x2c08,
+		.enable_reg = 0x36c0,
 		.enable_mask = BIT(7),
 		.hw.init = &(struct clk_init_data){
 			.name = "ce3_src",
@@ -2769,7 +2769,7 @@ static struct clk_branch ce3_core_clk =
 	.halt_reg = 0x2fdc,
 	.halt_bit = 5,
 	.clkr = {
-		.enable_reg = 0x36c4,
+		.enable_reg = 0x36cc,
 		.enable_mask = BIT(4),
 		.hw.init = &(struct clk_init_data){
 			.name = "ce3_core_clk",
--- zfcpdump-kernel-4.4.orig/drivers/clk/rockchip/clk-mmc-phase.c
+++ zfcpdump-kernel-4.4/drivers/clk/rockchip/clk-mmc-phase.c
@@ -153,6 +153,7 @@ struct clk *rockchip_clk_register_mmc(co
 		return NULL;
 
 	init.name = name;
+	init.flags = 0;
 	init.num_parents = num_parents;
 	init.parent_names = parent_names;
 	init.ops = &rockchip_mmc_clk_ops;
--- zfcpdump-kernel-4.4.orig/drivers/clk/rockchip/clk-rk3188.c
+++ zfcpdump-kernel-4.4/drivers/clk/rockchip/clk-rk3188.c
@@ -718,6 +718,7 @@ static const char *const rk3188_critical
 	"hclk_peri",
 	"pclk_cpu",
 	"pclk_peri",
+	"hclk_cpubus"
 };
 
 static void __init rk3188_common_clk_init(struct device_node *np)
--- zfcpdump-kernel-4.4.orig/drivers/clk/rockchip/clk-rk3368.c
+++ zfcpdump-kernel-4.4/drivers/clk/rockchip/clk-rk3368.c
@@ -165,7 +165,7 @@ static const struct rockchip_cpuclk_reg_
 	.core_reg = RK3368_CLKSEL_CON(0),
 	.div_core_shift = 0,
 	.div_core_mask = 0x1f,
-	.mux_core_shift = 15,
+	.mux_core_shift = 7,
 };
 
 static const struct rockchip_cpuclk_reg_data rk3368_cpuclkl_data = {
@@ -218,29 +218,29 @@ static const struct rockchip_cpuclk_reg_
 	}
 
 static struct rockchip_cpuclk_rate_table rk3368_cpuclkb_rates[] __initdata = {
-	RK3368_CPUCLKB_RATE(1512000000, 2, 6, 6),
-	RK3368_CPUCLKB_RATE(1488000000, 2, 5, 5),
-	RK3368_CPUCLKB_RATE(1416000000, 2, 5, 5),
-	RK3368_CPUCLKB_RATE(1200000000, 2, 4, 4),
-	RK3368_CPUCLKB_RATE(1008000000, 2, 4, 4),
-	RK3368_CPUCLKB_RATE( 816000000, 2, 3, 3),
-	RK3368_CPUCLKB_RATE( 696000000, 2, 3, 3),
-	RK3368_CPUCLKB_RATE( 600000000, 2, 2, 2),
-	RK3368_CPUCLKB_RATE( 408000000, 2, 2, 2),
-	RK3368_CPUCLKB_RATE( 312000000, 2, 2, 2),
+	RK3368_CPUCLKB_RATE(1512000000, 1, 5, 5),
+	RK3368_CPUCLKB_RATE(1488000000, 1, 4, 4),
+	RK3368_CPUCLKB_RATE(1416000000, 1, 4, 4),
+	RK3368_CPUCLKB_RATE(1200000000, 1, 3, 3),
+	RK3368_CPUCLKB_RATE(1008000000, 1, 3, 3),
+	RK3368_CPUCLKB_RATE( 816000000, 1, 2, 2),
+	RK3368_CPUCLKB_RATE( 696000000, 1, 2, 2),
+	RK3368_CPUCLKB_RATE( 600000000, 1, 1, 1),
+	RK3368_CPUCLKB_RATE( 408000000, 1, 1, 1),
+	RK3368_CPUCLKB_RATE( 312000000, 1, 1, 1),
 };
 
 static struct rockchip_cpuclk_rate_table rk3368_cpuclkl_rates[] __initdata = {
-	RK3368_CPUCLKL_RATE(1512000000, 2, 7, 7),
-	RK3368_CPUCLKL_RATE(1488000000, 2, 6, 6),
-	RK3368_CPUCLKL_RATE(1416000000, 2, 6, 6),
-	RK3368_CPUCLKL_RATE(1200000000, 2, 5, 5),
-	RK3368_CPUCLKL_RATE(1008000000, 2, 5, 5),
-	RK3368_CPUCLKL_RATE( 816000000, 2, 4, 4),
-	RK3368_CPUCLKL_RATE( 696000000, 2, 3, 3),
-	RK3368_CPUCLKL_RATE( 600000000, 2, 3, 3),
-	RK3368_CPUCLKL_RATE( 408000000, 2, 2, 2),
-	RK3368_CPUCLKL_RATE( 312000000, 2, 2, 2),
+	RK3368_CPUCLKL_RATE(1512000000, 1, 6, 6),
+	RK3368_CPUCLKL_RATE(1488000000, 1, 5, 5),
+	RK3368_CPUCLKL_RATE(1416000000, 1, 5, 5),
+	RK3368_CPUCLKL_RATE(1200000000, 1, 4, 4),
+	RK3368_CPUCLKL_RATE(1008000000, 1, 4, 4),
+	RK3368_CPUCLKL_RATE( 816000000, 1, 3, 3),
+	RK3368_CPUCLKL_RATE( 696000000, 1, 2, 2),
+	RK3368_CPUCLKL_RATE( 600000000, 1, 2, 2),
+	RK3368_CPUCLKL_RATE( 408000000, 1, 1, 1),
+	RK3368_CPUCLKL_RATE( 312000000, 1, 1, 1),
 };
 
 static struct rockchip_clk_branch rk3368_clk_branches[] __initdata = {
@@ -384,10 +384,10 @@ static struct rockchip_clk_branch rk3368
 	 * Clock-Architecture Diagram 3
 	 */
 
-	COMPOSITE(0, "aclk_vepu", mux_pll_src_cpll_gpll_usb_p, 0,
+	COMPOSITE(0, "aclk_vepu", mux_pll_src_cpll_gpll_npll_usb_p, 0,
 			RK3368_CLKSEL_CON(15), 6, 2, MFLAGS, 0, 5, DFLAGS,
 			RK3368_CLKGATE_CON(4), 6, GFLAGS),
-	COMPOSITE(0, "aclk_vdpu", mux_pll_src_cpll_gpll_usb_p, 0,
+	COMPOSITE(0, "aclk_vdpu", mux_pll_src_cpll_gpll_npll_usb_p, 0,
 			RK3368_CLKSEL_CON(15), 14, 2, MFLAGS, 8, 5, DFLAGS,
 			RK3368_CLKGATE_CON(4), 7, GFLAGS),
 
@@ -442,7 +442,7 @@ static struct rockchip_clk_branch rk3368
 	GATE(SCLK_HDMI_HDCP, "sclk_hdmi_hdcp", "xin24m", 0,
 			RK3368_CLKGATE_CON(4), 13, GFLAGS),
 	GATE(SCLK_HDMI_CEC, "sclk_hdmi_cec", "xin32k", 0,
-			RK3368_CLKGATE_CON(5), 12, GFLAGS),
+			RK3368_CLKGATE_CON(4), 12, GFLAGS),
 
 	COMPOSITE_NODIV(0, "vip_src", mux_pll_src_cpll_gpll_p, 0,
 			RK3368_CLKSEL_CON(21), 15, 1, MFLAGS,
--- zfcpdump-kernel-4.4.orig/drivers/clk/rockchip/clk.c
+++ zfcpdump-kernel-4.4/drivers/clk/rockchip/clk.c
@@ -70,7 +70,7 @@ static struct clk *rockchip_clk_register
 	if (gate_offset >= 0) {
 		gate = kzalloc(sizeof(*gate), GFP_KERNEL);
 		if (!gate)
-			return ERR_PTR(-ENOMEM);
+			goto err_gate;
 
 		gate->flags = gate_flags;
 		gate->reg = base + gate_offset;
@@ -82,7 +82,7 @@ static struct clk *rockchip_clk_register
 	if (div_width > 0) {
 		div = kzalloc(sizeof(*div), GFP_KERNEL);
 		if (!div)
-			return ERR_PTR(-ENOMEM);
+			goto err_div;
 
 		div->flags = div_flags;
 		div->reg = base + muxdiv_offset;
@@ -90,7 +90,9 @@ static struct clk *rockchip_clk_register
 		div->width = div_width;
 		div->lock = lock;
 		div->table = div_table;
-		div_ops = &clk_divider_ops;
+		div_ops = (div_flags & CLK_DIVIDER_READ_ONLY)
+						? &clk_divider_ro_ops
+						: &clk_divider_ops;
 	}
 
 	clk = clk_register_composite(NULL, name, parent_names, num_parents,
@@ -100,6 +102,11 @@ static struct clk *rockchip_clk_register
 				     flags);
 
 	return clk;
+err_div:
+	kfree(gate);
+err_gate:
+	kfree(mux);
+	return ERR_PTR(-ENOMEM);
 }
 
 static struct clk *rockchip_clk_register_frac_branch(const char *name,
--- zfcpdump-kernel-4.4.orig/drivers/clk/samsung/clk-cpu.c
+++ zfcpdump-kernel-4.4/drivers/clk/samsung/clk-cpu.c
@@ -148,6 +148,7 @@ static int exynos_cpuclk_pre_rate_change
 	unsigned long alt_prate = clk_get_rate(cpuclk->alt_parent);
 	unsigned long alt_div = 0, alt_div_mask = DIV_MASK;
 	unsigned long div0, div1 = 0, mux_reg;
+	unsigned long flags;
 
 	/* find out the divider values to use for clock data */
 	while ((cfg_data->prate * 1000) != ndata->new_rate) {
@@ -156,7 +157,7 @@ static int exynos_cpuclk_pre_rate_change
 		cfg_data++;
 	}
 
-	spin_lock(cpuclk->lock);
+	spin_lock_irqsave(cpuclk->lock, flags);
 
 	/*
 	 * For the selected PLL clock frequency, get the pre-defined divider
@@ -212,7 +213,7 @@ static int exynos_cpuclk_pre_rate_change
 				DIV_MASK_ALL);
 	}
 
-	spin_unlock(cpuclk->lock);
+	spin_unlock_irqrestore(cpuclk->lock, flags);
 	return 0;
 }
 
@@ -223,6 +224,7 @@ static int exynos_cpuclk_post_rate_chang
 	const struct exynos_cpuclk_cfg_data *cfg_data = cpuclk->cfg;
 	unsigned long div = 0, div_mask = DIV_MASK;
 	unsigned long mux_reg;
+	unsigned long flags;
 
 	/* find out the divider values to use for clock data */
 	if (cpuclk->flags & CLK_CPU_NEEDS_DEBUG_ALT_DIV) {
@@ -233,7 +235,7 @@ static int exynos_cpuclk_post_rate_chang
 		}
 	}
 
-	spin_lock(cpuclk->lock);
+	spin_lock_irqsave(cpuclk->lock, flags);
 
 	/* select mout_apll as the alternate parent */
 	mux_reg = readl(base + E4210_SRC_CPU);
@@ -246,7 +248,7 @@ static int exynos_cpuclk_post_rate_chang
 	}
 
 	exynos_set_safe_div(base, div, div_mask);
-	spin_unlock(cpuclk->lock);
+	spin_unlock_irqrestore(cpuclk->lock, flags);
 	return 0;
 }
 
--- zfcpdump-kernel-4.4.orig/drivers/clk/versatile/clk-sp810.c
+++ zfcpdump-kernel-4.4/drivers/clk/versatile/clk-sp810.c
@@ -92,6 +92,7 @@ static void __init clk_sp810_of_setup(st
 	int num = ARRAY_SIZE(parent_names);
 	char name[12];
 	struct clk_init_data init;
+	static int instance;
 	int i;
 	bool deprecated;
 
@@ -118,7 +119,7 @@ static void __init clk_sp810_of_setup(st
 	deprecated = !of_find_property(node, "assigned-clock-parents", NULL);
 
 	for (i = 0; i < ARRAY_SIZE(sp810->timerclken); i++) {
-		snprintf(name, ARRAY_SIZE(name), "timerclken%d", i);
+		snprintf(name, sizeof(name), "sp810_%d_%d", instance, i);
 
 		sp810->timerclken[i].sp810 = sp810;
 		sp810->timerclken[i].channel = i;
@@ -139,5 +140,6 @@ static void __init clk_sp810_of_setup(st
 	}
 
 	of_clk_add_provider(node, clk_sp810_timerclken_of_get, sp810);
+	instance++;
 }
 CLK_OF_DECLARE(sp810, "arm,sp810", clk_sp810_of_setup);
--- zfcpdump-kernel-4.4.orig/drivers/clocksource/sun4i_timer.c
+++ zfcpdump-kernel-4.4/drivers/clocksource/sun4i_timer.c
@@ -123,12 +123,16 @@ static struct clock_event_device sun4i_c
 	.set_next_event = sun4i_clkevt_next_event,
 };
 
+static void sun4i_timer_clear_interrupt(void)
+{
+	writel(TIMER_IRQ_EN(0), timer_base + TIMER_IRQ_ST_REG);
+}
 
 static irqreturn_t sun4i_timer_interrupt(int irq, void *dev_id)
 {
 	struct clock_event_device *evt = (struct clock_event_device *)dev_id;
 
-	writel(0x1, timer_base + TIMER_IRQ_ST_REG);
+	sun4i_timer_clear_interrupt();
 	evt->event_handler(evt);
 
 	return IRQ_HANDLED;
@@ -193,6 +197,9 @@ static void __init sun4i_timer_init(stru
 	/* Make sure timer is stopped before playing with interrupts */
 	sun4i_clkevt_time_stop(0);
 
+	/* clear timer0 interrupt */
+	sun4i_timer_clear_interrupt();
+
 	sun4i_clockevent.cpumask = cpu_possible_mask;
 	sun4i_clockevent.irq = irq;
 
--- zfcpdump-kernel-4.4.orig/drivers/clocksource/tcb_clksrc.c
+++ zfcpdump-kernel-4.4/drivers/clocksource/tcb_clksrc.c
@@ -98,7 +98,8 @@ static int tc_shutdown(struct clock_even
 
 	__raw_writel(0xff, regs + ATMEL_TC_REG(2, IDR));
 	__raw_writel(ATMEL_TC_CLKDIS, regs + ATMEL_TC_REG(2, CCR));
-	clk_disable(tcd->clk);
+	if (!clockevent_state_detached(d))
+		clk_disable(tcd->clk);
 
 	return 0;
 }
--- zfcpdump-kernel-4.4.orig/drivers/clocksource/vt8500_timer.c
+++ zfcpdump-kernel-4.4/drivers/clocksource/vt8500_timer.c
@@ -50,6 +50,8 @@
 
 #define msecs_to_loops(t) (loops_per_jiffy / 1000 * HZ * t)
 
+#define MIN_OSCR_DELTA		16
+
 static void __iomem *regbase;
 
 static cycle_t vt8500_timer_read(struct clocksource *cs)
@@ -80,7 +82,7 @@ static int vt8500_timer_set_next_event(u
 		cpu_relax();
 	writel((unsigned long)alarm, regbase + TIMER_MATCH_VAL);
 
-	if ((signed)(alarm - clocksource.read(&clocksource)) <= 16)
+	if ((signed)(alarm - clocksource.read(&clocksource)) <= MIN_OSCR_DELTA)
 		return -ETIME;
 
 	writel(1, regbase + TIMER_IER_VAL);
@@ -151,7 +153,7 @@ static void __init vt8500_timer_init(str
 		pr_err("%s: setup_irq failed for %s\n", __func__,
 							clockevent.name);
 	clockevents_config_and_register(&clockevent, VT8500_TIMER_HZ,
-					4, 0xf0000000);
+					MIN_OSCR_DELTA * 2, 0xf0000000);
 }
 
 CLOCKSOURCE_OF_DECLARE(vt8500, "via,vt8500-timer", vt8500_timer_init);
--- zfcpdump-kernel-4.4.orig/drivers/cpufreq/cpufreq.c
+++ zfcpdump-kernel-4.4/drivers/cpufreq/cpufreq.c
@@ -1026,6 +1026,7 @@ static struct cpufreq_policy *cpufreq_po
 {
 	struct device *dev = get_cpu_device(cpu);
 	struct cpufreq_policy *policy;
+	int ret;
 
 	if (WARN_ON(!dev))
 		return NULL;
@@ -1043,7 +1044,13 @@ static struct cpufreq_policy *cpufreq_po
 	if (!zalloc_cpumask_var(&policy->real_cpus, GFP_KERNEL))
 		goto err_free_rcpumask;
 
-	kobject_init(&policy->kobj, &ktype_cpufreq);
+	ret = kobject_init_and_add(&policy->kobj, &ktype_cpufreq,
+				   cpufreq_global_kobject, "policy%u", cpu);
+	if (ret) {
+		pr_err("%s: failed to init policy->kobj: %d\n", __func__, ret);
+		goto err_free_real_cpus;
+	}
+
 	INIT_LIST_HEAD(&policy->policy_list);
 	init_rwsem(&policy->rwsem);
 	spin_lock_init(&policy->transition_lock);
@@ -1054,6 +1061,8 @@ static struct cpufreq_policy *cpufreq_po
 	policy->cpu = cpu;
 	return policy;
 
+err_free_real_cpus:
+	free_cpumask_var(policy->real_cpus);
 err_free_rcpumask:
 	free_cpumask_var(policy->related_cpus);
 err_free_cpumask:
@@ -1158,16 +1167,6 @@ static int cpufreq_online(unsigned int c
 		cpumask_copy(policy->related_cpus, policy->cpus);
 		/* Remember CPUs present at the policy creation time. */
 		cpumask_and(policy->real_cpus, policy->cpus, cpu_present_mask);
-
-		/* Name and add the kobject */
-		ret = kobject_add(&policy->kobj, cpufreq_global_kobject,
-				  "policy%u",
-				  cpumask_first(policy->related_cpus));
-		if (ret) {
-			pr_err("%s: failed to add policy->kobj: %d\n", __func__,
-			       ret);
-			goto out_exit_policy;
-		}
 	}
 
 	/*
@@ -2392,6 +2391,20 @@ EXPORT_SYMBOL_GPL(cpufreq_boost_enabled)
  *               REGISTER / UNREGISTER CPUFREQ DRIVER                *
  *********************************************************************/
 
+static char cpufreq_driver_name[CPUFREQ_NAME_LEN];
+
+static int __init cpufreq_driver_setup(char *str)
+{
+	strlcpy(cpufreq_driver_name, str, CPUFREQ_NAME_LEN);
+	return 1;
+}
+
+/*
+ * Set this name to only allow one specific cpu freq driver, e.g.,
+ * cpufreq_driver=powernow-k8
+ */
+__setup("cpufreq_driver=", cpufreq_driver_setup);
+
 /**
  * cpufreq_register_driver - register a CPU Frequency driver
  * @driver_data: A struct cpufreq_driver containing the values#
@@ -2418,7 +2431,13 @@ int cpufreq_register_driver(struct cpufr
 	     (!!driver_data->get_intermediate != !!driver_data->target_intermediate))
 		return -EINVAL;
 
-	pr_debug("trying to register driver %s\n", driver_data->name);
+	pr_debug("trying to register driver %s, cpufreq_driver=%s\n",
+		driver_data->name, cpufreq_driver_name);
+
+	if (cpufreq_driver_name[0])
+		if (!driver_data->name ||
+			strcmp(cpufreq_driver_name, driver_data->name))
+				return -EINVAL;
 
 	/* Protect against concurrent CPU online/offline. */
 	get_online_cpus();
--- zfcpdump-kernel-4.4.orig/drivers/cpufreq/cpufreq_governor.c
+++ zfcpdump-kernel-4.4/drivers/cpufreq/cpufreq_governor.c
@@ -356,16 +356,18 @@ static int cpufreq_governor_init(struct
 	if (!have_governor_per_policy())
 		cdata->gdbs_data = dbs_data;
 
+	policy->governor_data = dbs_data;
+
 	ret = sysfs_create_group(get_governor_parent_kobj(policy),
 				 get_sysfs_attr(dbs_data));
 	if (ret)
 		goto reset_gdbs_data;
 
-	policy->governor_data = dbs_data;
-
 	return 0;
 
 reset_gdbs_data:
+	policy->governor_data = NULL;
+
 	if (!have_governor_per_policy())
 		cdata->gdbs_data = NULL;
 	cdata->exit(dbs_data, !policy->governor->initialized);
@@ -386,16 +388,19 @@ static int cpufreq_governor_exit(struct
 	if (!cdbs->shared || cdbs->shared->policy)
 		return -EBUSY;
 
-	policy->governor_data = NULL;
 	if (!--dbs_data->usage_count) {
 		sysfs_remove_group(get_governor_parent_kobj(policy),
 				   get_sysfs_attr(dbs_data));
 
+		policy->governor_data = NULL;
+
 		if (!have_governor_per_policy())
 			cdata->gdbs_data = NULL;
 
 		cdata->exit(dbs_data, policy->governor->initialized == 1);
 		kfree(dbs_data);
+	} else {
+		policy->governor_data = NULL;
 	}
 
 	free_common_dbs_info(policy, cdata);
--- zfcpdump-kernel-4.4.orig/drivers/cpufreq/cpufreq_userspace.c
+++ zfcpdump-kernel-4.4/drivers/cpufreq/cpufreq_userspace.c
@@ -17,6 +17,7 @@
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/mutex.h>
+#include <linux/slab.h>
 
 static DEFINE_PER_CPU(unsigned int, cpu_is_managed);
 static DEFINE_MUTEX(userspace_mutex);
@@ -31,6 +32,7 @@ static DEFINE_MUTEX(userspace_mutex);
 static int cpufreq_set(struct cpufreq_policy *policy, unsigned int freq)
 {
 	int ret = -EINVAL;
+	unsigned int *setspeed = policy->governor_data;
 
 	pr_debug("cpufreq_set for cpu %u, freq %u kHz\n", policy->cpu, freq);
 
@@ -38,6 +40,8 @@ static int cpufreq_set(struct cpufreq_po
 	if (!per_cpu(cpu_is_managed, policy->cpu))
 		goto err;
 
+	*setspeed = freq;
+
 	ret = __cpufreq_driver_target(policy, freq, CPUFREQ_RELATION_L);
  err:
 	mutex_unlock(&userspace_mutex);
@@ -49,19 +53,45 @@ static ssize_t show_speed(struct cpufreq
 	return sprintf(buf, "%u\n", policy->cur);
 }
 
+static int cpufreq_userspace_policy_init(struct cpufreq_policy *policy)
+{
+	unsigned int *setspeed;
+
+	setspeed = kzalloc(sizeof(*setspeed), GFP_KERNEL);
+	if (!setspeed)
+		return -ENOMEM;
+
+	policy->governor_data = setspeed;
+	return 0;
+}
+
 static int cpufreq_governor_userspace(struct cpufreq_policy *policy,
 				   unsigned int event)
 {
+	unsigned int *setspeed = policy->governor_data;
 	unsigned int cpu = policy->cpu;
 	int rc = 0;
 
+	if (event == CPUFREQ_GOV_POLICY_INIT)
+		return cpufreq_userspace_policy_init(policy);
+
+	if (!setspeed)
+		return -EINVAL;
+
 	switch (event) {
+	case CPUFREQ_GOV_POLICY_EXIT:
+		mutex_lock(&userspace_mutex);
+		policy->governor_data = NULL;
+		kfree(setspeed);
+		mutex_unlock(&userspace_mutex);
+		break;
 	case CPUFREQ_GOV_START:
 		BUG_ON(!policy->cur);
 		pr_debug("started managing cpu %u\n", cpu);
 
 		mutex_lock(&userspace_mutex);
 		per_cpu(cpu_is_managed, cpu) = 1;
+		*setspeed = policy->cur;
 		mutex_unlock(&userspace_mutex);
 		break;
 	case CPUFREQ_GOV_STOP:
@@ -69,20 +99,23 @@ static int cpufreq_governor_userspace(st
 
 		mutex_lock(&userspace_mutex);
 		per_cpu(cpu_is_managed, cpu) = 0;
+		*setspeed = 0;
 		mutex_unlock(&userspace_mutex);
 		break;
 	case CPUFREQ_GOV_LIMITS:
 		mutex_lock(&userspace_mutex);
-		pr_debug("limit event for cpu %u: %u - %u kHz, currently %u kHz\n",
-			cpu, policy->min, policy->max,
-			policy->cur);
+		pr_debug("limit event for cpu %u: %u - %u kHz, currently %u kHz, last set to %u kHz\n",
+			cpu, policy->min, policy->max, policy->cur, *setspeed);
 
-		if (policy->max < policy->cur)
+		if (policy->max < *setspeed)
 			__cpufreq_driver_target(policy, policy->max,
 						CPUFREQ_RELATION_H);
-		else if (policy->min > policy->cur)
+		else if (policy->min > *setspeed)
 			__cpufreq_driver_target(policy, policy->min,
 						CPUFREQ_RELATION_L);
+		else
+			__cpufreq_driver_target(policy, *setspeed,
+						CPUFREQ_RELATION_L);
 		mutex_unlock(&userspace_mutex);
 		break;
 	}
--- zfcpdump-kernel-4.4.orig/drivers/cpufreq/intel_pstate.c
+++ zfcpdump-kernel-4.4/drivers/cpufreq/intel_pstate.c
@@ -662,11 +662,16 @@ static int core_get_max_pstate(void)
 			if (err)
 				goto skip_tar;
 
-			tdp_msr = MSR_CONFIG_TDP_NOMINAL + tdp_ctrl;
+			tdp_msr = MSR_CONFIG_TDP_NOMINAL + (tdp_ctrl & 0x3);
 			err = rdmsrl_safe(tdp_msr, &tdp_ratio);
 			if (err)
 				goto skip_tar;
 
+			/* For level 1 and 2, bits[23:16] contain the ratio */
+			if (tdp_ctrl)
+				tdp_ratio >>= 16;
+
+			tdp_ratio &= 0xff; /* ratios are only 8 bits long */
 			if (tdp_ratio - 1 == tar) {
 				max_pstate = tar;
 				pr_debug("max_pstate=TAC %x\n", max_pstate);
--- zfcpdump-kernel-4.4.orig/drivers/cpufreq/powernv-cpufreq.c
+++ zfcpdump-kernel-4.4/drivers/cpufreq/powernv-cpufreq.c
@@ -28,6 +28,8 @@
 #include <linux/of.h>
 #include <linux/reboot.h>
 #include <linux/slab.h>
+#include <linux/cpu.h>
+#include <trace/events/power.h>
 
 #include <asm/cputhreads.h>
 #include <asm/firmware.h>
@@ -43,15 +45,39 @@
 static struct cpufreq_frequency_table powernv_freqs[POWERNV_MAX_PSTATES+1];
 static bool rebooting, throttled, occ_reset;
 
+static const char * const throttle_reason[] = {
+	"No throttling",
+	"Power Cap",
+	"Processor Over Temperature",
+	"Power Supply Failure",
+	"Over Current",
+	"OCC Reset"
+};
+
+enum throttle_reason_type {
+	NO_THROTTLE = 0,
+	POWERCAP,
+	CPU_OVERTEMP,
+	POWER_SUPPLY_FAILURE,
+	OVERCURRENT,
+	OCC_RESET_THROTTLE,
+	OCC_MAX_REASON
+};
+
 static struct chip {
 	unsigned int id;
 	bool throttled;
+	bool restore;
+	u8 throttle_reason;
 	cpumask_t mask;
 	struct work_struct throttle;
-	bool restore;
+	int throttle_turbo;
+	int throttle_sub_turbo;
+	int reason[OCC_MAX_REASON];
 } *chips;
 
 static int nr_chips;
+static DEFINE_PER_CPU(struct chip *, chip_info);
 
 /*
  * Note: The set of pstates consists of contiguous integers, the
@@ -183,6 +209,42 @@ static struct freq_attr *powernv_cpu_fre
 	NULL,
 };
 
+#define throttle_attr(name, member)					\
+static ssize_t name##_show(struct cpufreq_policy *policy, char *buf)	\
+{									\
+	struct chip *chip = per_cpu(chip_info, policy->cpu);		\
+									\
+	return sprintf(buf, "%u\n", chip->member);			\
+}									\
+									\
+static struct freq_attr throttle_attr_##name = __ATTR_RO(name)		\
+
+throttle_attr(unthrottle, reason[NO_THROTTLE]);
+throttle_attr(powercap, reason[POWERCAP]);
+throttle_attr(overtemp, reason[CPU_OVERTEMP]);
+throttle_attr(supply_fault, reason[POWER_SUPPLY_FAILURE]);
+throttle_attr(overcurrent, reason[OVERCURRENT]);
+throttle_attr(occ_reset, reason[OCC_RESET_THROTTLE]);
+throttle_attr(turbo_stat, throttle_turbo);
+throttle_attr(sub_turbo_stat, throttle_sub_turbo);
+
+static struct attribute *throttle_attrs[] = {
+	&throttle_attr_unthrottle.attr,
+	&throttle_attr_powercap.attr,
+	&throttle_attr_overtemp.attr,
+	&throttle_attr_supply_fault.attr,
+	&throttle_attr_overcurrent.attr,
+	&throttle_attr_occ_reset.attr,
+	&throttle_attr_turbo_stat.attr,
+	&throttle_attr_sub_turbo_stat.attr,
+	NULL,
+};
+
+static const struct attribute_group throttle_attr_grp = {
+	.name	= "throttle_stats",
+	.attrs	= throttle_attrs,
+};
+
 /* Helper routines */
 
 /* Access helpers to power mgt SPR */
@@ -311,34 +373,36 @@ static inline unsigned int get_nominal_i
 
 static void powernv_cpufreq_throttle_check(void *data)
 {
+	struct chip *chip;
 	unsigned int cpu = smp_processor_id();
 	unsigned long pmsr;
-	int pmsr_pmax, i;
+	int pmsr_pmax;
 
 	pmsr = get_pmspr(SPRN_PMSR);
-
-	for (i = 0; i < nr_chips; i++)
-		if (chips[i].id == cpu_to_chip_id(cpu))
-			break;
+	chip = this_cpu_read(chip_info);
 
 	/* Check for Pmax Capping */
 	pmsr_pmax = (s8)PMSR_MAX(pmsr);
 	if (pmsr_pmax != powernv_pstate_info.max) {
-		if (chips[i].throttled)
+		if (chip->throttled)
 			goto next;
-		chips[i].throttled = true;
-		if (pmsr_pmax < powernv_pstate_info.nominal)
-			pr_crit("CPU %d on Chip %u has Pmax reduced below nominal frequency (%d < %d)\n",
-				cpu, chips[i].id, pmsr_pmax,
-				powernv_pstate_info.nominal);
-		else
-			pr_info("CPU %d on Chip %u has Pmax reduced below turbo frequency (%d < %d)\n",
-				cpu, chips[i].id, pmsr_pmax,
-				powernv_pstate_info.max);
-	} else if (chips[i].throttled) {
-		chips[i].throttled = false;
-		pr_info("CPU %d on Chip %u has Pmax restored to %d\n", cpu,
-			chips[i].id, pmsr_pmax);
+		chip->throttled = true;
+		if (pmsr_pmax < powernv_pstate_info.nominal) {
+			pr_warn_once("CPU %d on Chip %u has Pmax reduced below nominal frequency (%d < %d)\n",
+				     cpu, chip->id, pmsr_pmax,
+				     powernv_pstate_info.nominal);
+			chip->throttle_sub_turbo++;
+		} else {
+			chip->throttle_turbo++;
+		}
+		trace_powernv_throttle(chip->id,
+				      throttle_reason[chip->throttle_reason],
+				      pmsr_pmax);
+	} else if (chip->throttled) {
+		chip->throttled = false;
+		trace_powernv_throttle(chip->id,
+				      throttle_reason[chip->throttle_reason],
+				      pmsr_pmax);
 	}
 
 	/* Check if Psafe_mode_active is set in PMSR. */
@@ -356,7 +420,7 @@ next:
 
 	if (throttled) {
 		pr_info("PMSR = %16lx\n", pmsr);
-		pr_crit("CPU Frequency could be throttled\n");
+		pr_warn("CPU Frequency could be throttled\n");
 	}
 }
 
@@ -397,6 +461,21 @@ static int powernv_cpufreq_cpu_init(stru
 	for (i = 0; i < threads_per_core; i++)
 		cpumask_set_cpu(base + i, policy->cpus);
 
+	if (!policy->driver_data) {
+		int ret;
+
+		ret = sysfs_create_group(&policy->kobj, &throttle_attr_grp);
+		if (ret) {
+			pr_info("Failed to create throttle stats directory for cpu %d\n",
+				policy->cpu);
+			return ret;
+		}
+		/*
+		 * policy->driver_data is used as a flag for one-time
+		 * creation of throttle sysfs files.
+		 */
+		policy->driver_data = policy;
+	}
 	return cpufreq_table_validate_and_show(policy, powernv_freqs);
 }
 
@@ -423,18 +502,19 @@ void powernv_cpufreq_work_fn(struct work
 {
 	struct chip *chip = container_of(work, struct chip, throttle);
 	unsigned int cpu;
-	cpumask_var_t mask;
+	cpumask_t mask;
 
-	smp_call_function_any(&chip->mask,
+	get_online_cpus();
+	cpumask_and(&mask, &chip->mask, cpu_online_mask);
+	smp_call_function_any(&mask,
 			      powernv_cpufreq_throttle_check, NULL, 0);
 
 	if (!chip->restore)
-		return;
+		goto out;
 
 	chip->restore = false;
-	cpumask_copy(mask, &chip->mask);
-	for_each_cpu_and(cpu, mask, cpu_online_mask) {
-		int index, tcpu;
+	for_each_cpu(cpu, &mask) {
+		int index;
 		struct cpufreq_policy policy;
 
 		cpufreq_get_policy(&policy, cpu);
@@ -442,20 +522,12 @@ void powernv_cpufreq_work_fn(struct work
 					       policy.cur,
 					       CPUFREQ_RELATION_C, &index);
 		powernv_cpufreq_target_index(&policy, index);
-		for_each_cpu(tcpu, policy.cpus)
-			cpumask_clear_cpu(tcpu, mask);
+		cpumask_andnot(&mask, &mask, policy.cpus);
 	}
+out:
+	put_online_cpus();
 }
 
-static char throttle_reason[][30] = {
-					"No throttling",
-					"Power Cap",
-					"Processor Over Temperature",
-					"Power Supply Failure",
-					"Over Current",
-					"OCC Reset"
-				     };
-
 static int powernv_cpufreq_occ_msg(struct notifier_block *nb,
 				   unsigned long msg_type, void *_msg)
 {
@@ -481,7 +553,7 @@ static int powernv_cpufreq_occ_msg(struc
 		 */
 		if (!throttled) {
 			throttled = true;
-			pr_crit("CPU frequency is throttled for duration\n");
+			pr_warn("CPU frequency is throttled for duration\n");
 		}
 
 		break;
@@ -505,23 +577,20 @@ static int powernv_cpufreq_occ_msg(struc
 			return 0;
 		}
 
-		if (omsg.throttle_status &&
-		    omsg.throttle_status <= OCC_MAX_THROTTLE_STATUS)
-			pr_info("OCC: Chip %u Pmax reduced due to %s\n",
-				(unsigned int)omsg.chip,
-				throttle_reason[omsg.throttle_status]);
-		else if (!omsg.throttle_status)
-			pr_info("OCC: Chip %u %s\n", (unsigned int)omsg.chip,
-				throttle_reason[omsg.throttle_status]);
-		else
-			return 0;
-
 		for (i = 0; i < nr_chips; i++)
-			if (chips[i].id == omsg.chip) {
-				if (!omsg.throttle_status)
-					chips[i].restore = true;
-				schedule_work(&chips[i].throttle);
-			}
+			if (chips[i].id == omsg.chip)
+				break;
+
+		if (omsg.throttle_status >= 0 &&
+		    omsg.throttle_status <= OCC_MAX_THROTTLE_STATUS) {
+			chips[i].throttle_reason = omsg.throttle_status;
+			chips[i].reason[omsg.throttle_status]++;
+		}
+
+		if (!omsg.throttle_status)
+			chips[i].restore = true;
+
+		schedule_work(&chips[i].throttle);
 	}
 	return 0;
 }
@@ -566,21 +635,33 @@ static int init_chip_info(void)
 		}
 	}
 
-	chips = kmalloc_array(nr_chips, sizeof(struct chip), GFP_KERNEL);
+	chips = kcalloc(nr_chips, sizeof(struct chip), GFP_KERNEL);
 	if (!chips)
 		return -ENOMEM;
 
 	for (i = 0; i < nr_chips; i++) {
 		chips[i].id = chip[i];
-		chips[i].throttled = false;
 		cpumask_copy(&chips[i].mask, cpumask_of_node(chip[i]));
 		INIT_WORK(&chips[i].throttle, powernv_cpufreq_work_fn);
-		chips[i].restore = false;
+		for_each_cpu(cpu, &chips[i].mask)
+			per_cpu(chip_info, cpu) =  &chips[i];
 	}
 
 	return 0;
 }
 
+static inline void clean_chip_info(void)
+{
+	kfree(chips);
+}
+
+static inline void unregister_all_notifiers(void)
+{
+	opal_message_notifier_unregister(OPAL_MSG_OCC,
+					 &powernv_cpufreq_opal_nb);
+	unregister_reboot_notifier(&powernv_cpufreq_reboot_nb);
+}
+
 static int __init powernv_cpufreq_init(void)
 {
 	int rc = 0;
@@ -591,28 +672,35 @@ static int __init powernv_cpufreq_init(v
 
 	/* Discover pstates from device tree and init */
 	rc = init_powernv_pstates();
-	if (rc) {
-		pr_info("powernv-cpufreq disabled. System does not support PState control\n");
-		return rc;
-	}
+	if (rc)
+		goto out;
 
 	/* Populate chip info */
 	rc = init_chip_info();
 	if (rc)
-		return rc;
+		goto out;
 
 	register_reboot_notifier(&powernv_cpufreq_reboot_nb);
 	opal_message_notifier_register(OPAL_MSG_OCC, &powernv_cpufreq_opal_nb);
-	return cpufreq_register_driver(&powernv_cpufreq_driver);
+
+	rc = cpufreq_register_driver(&powernv_cpufreq_driver);
+	if (!rc)
+		return 0;
+
+	pr_info("Failed to register the cpufreq driver (%d)\n", rc);
+	unregister_all_notifiers();
+	clean_chip_info();
+out:
+	pr_info("Platform driver disabled. System does not support PState control\n");
+	return rc;
 }
 module_init(powernv_cpufreq_init);
 
 static void __exit powernv_cpufreq_exit(void)
 {
-	unregister_reboot_notifier(&powernv_cpufreq_reboot_nb);
-	opal_message_notifier_unregister(OPAL_MSG_OCC,
-					 &powernv_cpufreq_opal_nb);
 	cpufreq_unregister_driver(&powernv_cpufreq_driver);
+	unregister_all_notifiers();
+	clean_chip_info();
 }
 module_exit(powernv_cpufreq_exit);
 
--- zfcpdump-kernel-4.4.orig/drivers/cpufreq/pxa2xx-cpufreq.c
+++ zfcpdump-kernel-4.4/drivers/cpufreq/pxa2xx-cpufreq.c
@@ -202,7 +202,7 @@ static void __init pxa_cpufreq_init_volt
 	}
 }
 #else
-static int pxa_cpufreq_change_voltage(struct pxa_freqs *pxa_freq)
+static int pxa_cpufreq_change_voltage(const struct pxa_freqs *pxa_freq)
 {
 	return 0;
 }
--- zfcpdump-kernel-4.4.orig/drivers/cpuidle/cpuidle-arm.c
+++ zfcpdump-kernel-4.4/drivers/cpuidle/cpuidle-arm.c
@@ -50,7 +50,7 @@ static int arm_enter_idle_state(struct c
 		 * call the CPU ops suspend protocol with idle index as a
 		 * parameter.
 		 */
-		arm_cpuidle_suspend(idx);
+		ret = arm_cpuidle_suspend(idx);
 
 		cpu_pm_exit();
 	}
--- zfcpdump-kernel-4.4.orig/drivers/cpuidle/cpuidle.c
+++ zfcpdump-kernel-4.4/drivers/cpuidle/cpuidle.c
@@ -214,7 +214,7 @@ int cpuidle_enter_state(struct cpuidle_d
 		tick_broadcast_exit();
 	}
 
-	if (!cpuidle_state_is_coupled(drv, entered_state))
+	if (!cpuidle_state_is_coupled(drv, index))
 		local_irq_enable();
 
 	diff = ktime_to_us(ktime_sub(time_end, time_start));
@@ -433,6 +433,8 @@ static void __cpuidle_unregister_device(
 	list_del(&dev->device_list);
 	per_cpu(cpuidle_devices, dev->cpu) = NULL;
 	module_put(drv->owner);
+
+	dev->registered = 0;
 }
 
 static void __cpuidle_device_init(struct cpuidle_device *dev)
--- zfcpdump-kernel-4.4.orig/drivers/crypto/atmel-aes.c
+++ zfcpdump-kernel-4.4/drivers/crypto/atmel-aes.c
@@ -1396,9 +1396,9 @@ static int atmel_aes_probe(struct platfo
 	}
 
 	aes_dd->io_base = devm_ioremap_resource(&pdev->dev, aes_res);
-	if (!aes_dd->io_base) {
+	if (IS_ERR(aes_dd->io_base)) {
 		dev_err(dev, "can't ioremap\n");
-		err = -ENOMEM;
+		err = PTR_ERR(aes_dd->io_base);
 		goto res_err;
 	}
 
--- zfcpdump-kernel-4.4.orig/drivers/crypto/atmel-sha.c
+++ zfcpdump-kernel-4.4/drivers/crypto/atmel-sha.c
@@ -783,7 +783,7 @@ static void atmel_sha_finish_req(struct
 	dd->flags &= ~(SHA_FLAGS_BUSY | SHA_FLAGS_FINAL | SHA_FLAGS_CPU |
 			SHA_FLAGS_DMA_READY | SHA_FLAGS_OUTPUT_READY);
 
-	clk_disable_unprepare(dd->iclk);
+	clk_disable(dd->iclk);
 
 	if (req->base.complete)
 		req->base.complete(&req->base, err);
@@ -796,7 +796,7 @@ static int atmel_sha_hw_init(struct atme
 {
 	int err;
 
-	err = clk_prepare_enable(dd->iclk);
+	err = clk_enable(dd->iclk);
 	if (err)
 		return err;
 
@@ -823,7 +823,7 @@ static void atmel_sha_hw_version_init(st
 	dev_info(dd->dev,
 			"version: 0x%x\n", dd->hw_version);
 
-	clk_disable_unprepare(dd->iclk);
+	clk_disable(dd->iclk);
 }
 
 static int atmel_sha_handle_queue(struct atmel_sha_dev *dd,
@@ -1405,12 +1405,16 @@ static int atmel_sha_probe(struct platfo
 	}
 
 	sha_dd->io_base = devm_ioremap_resource(&pdev->dev, sha_res);
-	if (!sha_dd->io_base) {
+	if (IS_ERR(sha_dd->io_base)) {
 		dev_err(dev, "can't ioremap\n");
-		err = -ENOMEM;
+		err = PTR_ERR(sha_dd->io_base);
 		goto res_err;
 	}
 
+	err = clk_prepare(sha_dd->iclk);
+	if (err)
+		goto res_err;
+
 	atmel_sha_hw_version_init(sha_dd);
 
 	atmel_sha_get_cap(sha_dd);
@@ -1422,12 +1426,12 @@ static int atmel_sha_probe(struct platfo
 			if (IS_ERR(pdata)) {
 				dev_err(&pdev->dev, "platform data not available\n");
 				err = PTR_ERR(pdata);
-				goto res_err;
+				goto iclk_unprepare;
 			}
 		}
 		if (!pdata->dma_slave) {
 			err = -ENXIO;
-			goto res_err;
+			goto iclk_unprepare;
 		}
 		err = atmel_sha_dma_init(sha_dd, pdata);
 		if (err)
@@ -1458,6 +1462,8 @@ err_algs:
 	if (sha_dd->caps.has_dma)
 		atmel_sha_dma_cleanup(sha_dd);
 err_sha_dma:
+iclk_unprepare:
+	clk_unprepare(sha_dd->iclk);
 res_err:
 	tasklet_kill(&sha_dd->done_task);
 sha_dd_err:
@@ -1484,12 +1490,7 @@ static int atmel_sha_remove(struct platf
 	if (sha_dd->caps.has_dma)
 		atmel_sha_dma_cleanup(sha_dd);
 
-	iounmap(sha_dd->io_base);
-
-	clk_put(sha_dd->iclk);
-
-	if (sha_dd->irq >= 0)
-		free_irq(sha_dd->irq, sha_dd);
+	clk_unprepare(sha_dd->iclk);
 
 	return 0;
 }
--- zfcpdump-kernel-4.4.orig/drivers/crypto/atmel-tdes.c
+++ zfcpdump-kernel-4.4/drivers/crypto/atmel-tdes.c
@@ -1417,9 +1417,9 @@ static int atmel_tdes_probe(struct platf
 	}
 
 	tdes_dd->io_base = devm_ioremap_resource(&pdev->dev, tdes_res);
-	if (!tdes_dd->io_base) {
+	if (IS_ERR(tdes_dd->io_base)) {
 		dev_err(dev, "can't ioremap\n");
-		err = -ENOMEM;
+		err = PTR_ERR(tdes_dd->io_base);
 		goto res_err;
 	}
 
--- zfcpdump-kernel-4.4.orig/drivers/crypto/caam/caamalg.c
+++ zfcpdump-kernel-4.4/drivers/crypto/caam/caamalg.c
@@ -441,6 +441,9 @@ static int aead_set_sh_desc(struct crypt
 			       OP_ALG_AAI_CTR_MOD128);
 	const bool is_rfc3686 = alg->caam.rfc3686;
 
+	if (!ctx->authsize)
+		return 0;
+
 	/* NULL encryption / decryption */
 	if (!ctx->enckeylen)
 		return aead_null_set_sh_desc(aead);
@@ -553,7 +556,10 @@ skip_enc:
 
 	/* Read and write assoclen bytes */
 	append_math_add(desc, VARSEQINLEN, ZERO, REG3, CAAM_CMD_SZ);
-	append_math_add(desc, VARSEQOUTLEN, ZERO, REG3, CAAM_CMD_SZ);
+	if (alg->caam.geniv)
+		append_math_add_imm_u32(desc, VARSEQOUTLEN, REG3, IMM, ivsize);
+	else
+		append_math_add(desc, VARSEQOUTLEN, ZERO, REG3, CAAM_CMD_SZ);
 
 	/* Skip assoc data */
 	append_seq_fifo_store(desc, 0, FIFOST_TYPE_SKIP | FIFOLDST_VLF);
@@ -562,6 +568,14 @@ skip_enc:
 	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS2 | FIFOLD_TYPE_MSG |
 			     KEY_VLF);
 
+	if (alg->caam.geniv) {
+		append_seq_load(desc, ivsize, LDST_CLASS_1_CCB |
+				LDST_SRCDST_BYTE_CONTEXT |
+				(ctx1_iv_off << LDST_OFFSET_SHIFT));
+		append_move(desc, MOVE_SRC_CLASS1CTX | MOVE_DEST_CLASS2INFIFO |
+			    (ctx1_iv_off << MOVE_OFFSET_SHIFT) | ivsize);
+	}
+
 	/* Load Counter into CONTEXT1 reg */
 	if (is_rfc3686)
 		append_load_imm_u32(desc, be32_to_cpu(1), LDST_IMM |
@@ -614,7 +628,7 @@ skip_enc:
 		keys_fit_inline = true;
 
 	/* aead_givencrypt shared descriptor */
-	desc = ctx->sh_desc_givenc;
+	desc = ctx->sh_desc_enc;
 
 	/* Note: Context registers are saved. */
 	init_sh_desc_key_aead(desc, ctx, keys_fit_inline, is_rfc3686);
@@ -645,13 +659,13 @@ copy_iv:
 	append_operation(desc, ctx->class2_alg_type |
 			 OP_ALG_AS_INITFINAL | OP_ALG_ENCRYPT);
 
-	/* ivsize + cryptlen = seqoutlen - authsize */
-	append_math_sub_imm_u32(desc, REG3, SEQOUTLEN, IMM, ctx->authsize);
-
 	/* Read and write assoclen bytes */
 	append_math_add(desc, VARSEQINLEN, ZERO, REG3, CAAM_CMD_SZ);
 	append_math_add(desc, VARSEQOUTLEN, ZERO, REG3, CAAM_CMD_SZ);
 
+	/* ivsize + cryptlen = seqoutlen - authsize */
+	append_math_sub_imm_u32(desc, REG3, SEQOUTLEN, IMM, ctx->authsize);
+
 	/* Skip assoc data */
 	append_seq_fifo_store(desc, 0, FIFOST_TYPE_SKIP | FIFOLDST_VLF);
 
@@ -697,7 +711,7 @@ copy_iv:
 	ctx->sh_desc_enc_dma = dma_map_single(jrdev, desc,
 					      desc_bytes(desc),
 					      DMA_TO_DEVICE);
-	if (dma_mapping_error(jrdev, ctx->sh_desc_givenc_dma)) {
+	if (dma_mapping_error(jrdev, ctx->sh_desc_enc_dma)) {
 		dev_err(jrdev, "unable to map shared descriptor\n");
 		return -ENOMEM;
 	}
@@ -2147,7 +2161,7 @@ static void init_authenc_job(struct aead
 
 	init_aead_job(req, edesc, all_contig, encrypt);
 
-	if (ivsize && (is_rfc3686 || !(alg->caam.geniv && encrypt)))
+	if (ivsize && ((is_rfc3686 && encrypt) || !alg->caam.geniv))
 		append_load_as_imm(desc, req->iv, ivsize,
 				   LDST_CLASS_1_CCB |
 				   LDST_SRCDST_BYTE_CONTEXT |
@@ -2534,20 +2548,6 @@ static int aead_decrypt(struct aead_requ
 	return ret;
 }
 
-static int aead_givdecrypt(struct aead_request *req)
-{
-	struct crypto_aead *aead = crypto_aead_reqtfm(req);
-	unsigned int ivsize = crypto_aead_ivsize(aead);
-
-	if (req->cryptlen < ivsize)
-		return -EINVAL;
-
-	req->cryptlen -= ivsize;
-	req->assoclen += ivsize;
-
-	return aead_decrypt(req);
-}
-
 /*
  * allocate and map the ablkcipher extended descriptor for ablkcipher
  */
@@ -3207,7 +3207,7 @@ static struct caam_aead_alg driver_aeads
 			.setkey = aead_setkey,
 			.setauthsize = aead_setauthsize,
 			.encrypt = aead_encrypt,
-			.decrypt = aead_givdecrypt,
+			.decrypt = aead_decrypt,
 			.ivsize = AES_BLOCK_SIZE,
 			.maxauthsize = MD5_DIGEST_SIZE,
 		},
@@ -3253,7 +3253,7 @@ static struct caam_aead_alg driver_aeads
 			.setkey = aead_setkey,
 			.setauthsize = aead_setauthsize,
 			.encrypt = aead_encrypt,
-			.decrypt = aead_givdecrypt,
+			.decrypt = aead_decrypt,
 			.ivsize = AES_BLOCK_SIZE,
 			.maxauthsize = SHA1_DIGEST_SIZE,
 		},
@@ -3299,7 +3299,7 @@ static struct caam_aead_alg driver_aeads
 			.setkey = aead_setkey,
 			.setauthsize = aead_setauthsize,
 			.encrypt = aead_encrypt,
-			.decrypt = aead_givdecrypt,
+			.decrypt = aead_decrypt,
 			.ivsize = AES_BLOCK_SIZE,
 			.maxauthsize = SHA224_DIGEST_SIZE,
 		},
@@ -3345,7 +3345,7 @@ static struct caam_aead_alg driver_aeads
 			.setkey = aead_setkey,
 			.setauthsize = aead_setauthsize,
 			.encrypt = aead_encrypt,
-			.decrypt = aead_givdecrypt,
+			.decrypt = aead_decrypt,
 			.ivsize = AES_BLOCK_SIZE,
 			.maxauthsize = SHA256_DIGEST_SIZE,
 		},
@@ -3391,7 +3391,7 @@ static struct caam_aead_alg driver_aeads
 			.setkey = aead_setkey,
 			.setauthsize = aead_setauthsize,
 			.encrypt = aead_encrypt,
-			.decrypt = aead_givdecrypt,
+			.decrypt = aead_decrypt,
 			.ivsize = AES_BLOCK_SIZE,
 			.maxauthsize = SHA384_DIGEST_SIZE,
 		},
@@ -3437,7 +3437,7 @@ static struct caam_aead_alg driver_aeads
 			.setkey = aead_setkey,
 			.setauthsize = aead_setauthsize,
 			.encrypt = aead_encrypt,
-			.decrypt = aead_givdecrypt,
+			.decrypt = aead_decrypt,
 			.ivsize = AES_BLOCK_SIZE,
 			.maxauthsize = SHA512_DIGEST_SIZE,
 		},
@@ -3483,7 +3483,7 @@ static struct caam_aead_alg driver_aeads
 			.setkey = aead_setkey,
 			.setauthsize = aead_setauthsize,
 			.encrypt = aead_encrypt,
-			.decrypt = aead_givdecrypt,
+			.decrypt = aead_decrypt,
 			.ivsize = DES3_EDE_BLOCK_SIZE,
 			.maxauthsize = MD5_DIGEST_SIZE,
 		},
@@ -3531,7 +3531,7 @@ static struct caam_aead_alg driver_aeads
 			.setkey = aead_setkey,
 			.setauthsize = aead_setauthsize,
 			.encrypt = aead_encrypt,
-			.decrypt = aead_givdecrypt,
+			.decrypt = aead_decrypt,
 			.ivsize = DES3_EDE_BLOCK_SIZE,
 			.maxauthsize = SHA1_DIGEST_SIZE,
 		},
@@ -3579,7 +3579,7 @@ static struct caam_aead_alg driver_aeads
 			.setkey = aead_setkey,
 			.setauthsize = aead_setauthsize,
 			.encrypt = aead_encrypt,
-			.decrypt = aead_givdecrypt,
+			.decrypt = aead_decrypt,
 			.ivsize = DES3_EDE_BLOCK_SIZE,
 			.maxauthsize = SHA224_DIGEST_SIZE,
 		},
@@ -3627,7 +3627,7 @@ static struct caam_aead_alg driver_aeads
 			.setkey = aead_setkey,
 			.setauthsize = aead_setauthsize,
 			.encrypt = aead_encrypt,
-			.decrypt = aead_givdecrypt,
+			.decrypt = aead_decrypt,
 			.ivsize = DES3_EDE_BLOCK_SIZE,
 			.maxauthsize = SHA256_DIGEST_SIZE,
 		},
@@ -3675,7 +3675,7 @@ static struct caam_aead_alg driver_aeads
 			.setkey = aead_setkey,
 			.setauthsize = aead_setauthsize,
 			.encrypt = aead_encrypt,
-			.decrypt = aead_givdecrypt,
+			.decrypt = aead_decrypt,
 			.ivsize = DES3_EDE_BLOCK_SIZE,
 			.maxauthsize = SHA384_DIGEST_SIZE,
 		},
@@ -3723,7 +3723,7 @@ static struct caam_aead_alg driver_aeads
 			.setkey = aead_setkey,
 			.setauthsize = aead_setauthsize,
 			.encrypt = aead_encrypt,
-			.decrypt = aead_givdecrypt,
+			.decrypt = aead_decrypt,
 			.ivsize = DES3_EDE_BLOCK_SIZE,
 			.maxauthsize = SHA512_DIGEST_SIZE,
 		},
@@ -3769,7 +3769,7 @@ static struct caam_aead_alg driver_aeads
 			.setkey = aead_setkey,
 			.setauthsize = aead_setauthsize,
 			.encrypt = aead_encrypt,
-			.decrypt = aead_givdecrypt,
+			.decrypt = aead_decrypt,
 			.ivsize = DES_BLOCK_SIZE,
 			.maxauthsize = MD5_DIGEST_SIZE,
 		},
@@ -3815,7 +3815,7 @@ static struct caam_aead_alg driver_aeads
 			.setkey = aead_setkey,
 			.setauthsize = aead_setauthsize,
 			.encrypt = aead_encrypt,
-			.decrypt = aead_givdecrypt,
+			.decrypt = aead_decrypt,
 			.ivsize = DES_BLOCK_SIZE,
 			.maxauthsize = SHA1_DIGEST_SIZE,
 		},
@@ -3861,7 +3861,7 @@ static struct caam_aead_alg driver_aeads
 			.setkey = aead_setkey,
 			.setauthsize = aead_setauthsize,
 			.encrypt = aead_encrypt,
-			.decrypt = aead_givdecrypt,
+			.decrypt = aead_decrypt,
 			.ivsize = DES_BLOCK_SIZE,
 			.maxauthsize = SHA224_DIGEST_SIZE,
 		},
@@ -3907,7 +3907,7 @@ static struct caam_aead_alg driver_aeads
 			.setkey = aead_setkey,
 			.setauthsize = aead_setauthsize,
 			.encrypt = aead_encrypt,
-			.decrypt = aead_givdecrypt,
+			.decrypt = aead_decrypt,
 			.ivsize = DES_BLOCK_SIZE,
 			.maxauthsize = SHA256_DIGEST_SIZE,
 		},
@@ -3953,7 +3953,7 @@ static struct caam_aead_alg driver_aeads
 			.setkey = aead_setkey,
 			.setauthsize = aead_setauthsize,
 			.encrypt = aead_encrypt,
-			.decrypt = aead_givdecrypt,
+			.decrypt = aead_decrypt,
 			.ivsize = DES_BLOCK_SIZE,
 			.maxauthsize = SHA384_DIGEST_SIZE,
 		},
@@ -3999,7 +3999,7 @@ static struct caam_aead_alg driver_aeads
 			.setkey = aead_setkey,
 			.setauthsize = aead_setauthsize,
 			.encrypt = aead_encrypt,
-			.decrypt = aead_givdecrypt,
+			.decrypt = aead_decrypt,
 			.ivsize = DES_BLOCK_SIZE,
 			.maxauthsize = SHA512_DIGEST_SIZE,
 		},
@@ -4048,7 +4048,7 @@ static struct caam_aead_alg driver_aeads
 			.setkey = aead_setkey,
 			.setauthsize = aead_setauthsize,
 			.encrypt = aead_encrypt,
-			.decrypt = aead_givdecrypt,
+			.decrypt = aead_decrypt,
 			.ivsize = CTR_RFC3686_IV_SIZE,
 			.maxauthsize = MD5_DIGEST_SIZE,
 		},
@@ -4099,7 +4099,7 @@ static struct caam_aead_alg driver_aeads
 			.setkey = aead_setkey,
 			.setauthsize = aead_setauthsize,
 			.encrypt = aead_encrypt,
-			.decrypt = aead_givdecrypt,
+			.decrypt = aead_decrypt,
 			.ivsize = CTR_RFC3686_IV_SIZE,
 			.maxauthsize = SHA1_DIGEST_SIZE,
 		},
@@ -4150,7 +4150,7 @@ static struct caam_aead_alg driver_aeads
 			.setkey = aead_setkey,
 			.setauthsize = aead_setauthsize,
 			.encrypt = aead_encrypt,
-			.decrypt = aead_givdecrypt,
+			.decrypt = aead_decrypt,
 			.ivsize = CTR_RFC3686_IV_SIZE,
 			.maxauthsize = SHA224_DIGEST_SIZE,
 		},
@@ -4201,7 +4201,7 @@ static struct caam_aead_alg driver_aeads
 			.setkey = aead_setkey,
 			.setauthsize = aead_setauthsize,
 			.encrypt = aead_encrypt,
-			.decrypt = aead_givdecrypt,
+			.decrypt = aead_decrypt,
 			.ivsize = CTR_RFC3686_IV_SIZE,
 			.maxauthsize = SHA256_DIGEST_SIZE,
 		},
@@ -4252,7 +4252,7 @@ static struct caam_aead_alg driver_aeads
 			.setkey = aead_setkey,
 			.setauthsize = aead_setauthsize,
 			.encrypt = aead_encrypt,
-			.decrypt = aead_givdecrypt,
+			.decrypt = aead_decrypt,
 			.ivsize = CTR_RFC3686_IV_SIZE,
 			.maxauthsize = SHA384_DIGEST_SIZE,
 		},
@@ -4303,7 +4303,7 @@ static struct caam_aead_alg driver_aeads
 			.setkey = aead_setkey,
 			.setauthsize = aead_setauthsize,
 			.encrypt = aead_encrypt,
-			.decrypt = aead_givdecrypt,
+			.decrypt = aead_decrypt,
 			.ivsize = CTR_RFC3686_IV_SIZE,
 			.maxauthsize = SHA512_DIGEST_SIZE,
 		},
--- zfcpdump-kernel-4.4.orig/drivers/crypto/caam/caamhash.c
+++ zfcpdump-kernel-4.4/drivers/crypto/caam/caamhash.c
@@ -1873,6 +1873,7 @@ caam_hash_alloc(struct caam_hash_templat
 			 template->name);
 		snprintf(alg->cra_driver_name, CRYPTO_MAX_ALG_NAME, "%s",
 			 template->driver_name);
+		t_alg->ahash_alg.setkey = NULL;
 	}
 	alg->cra_module = THIS_MODULE;
 	alg->cra_init = caam_hash_cra_init;
--- zfcpdump-kernel-4.4.orig/drivers/crypto/caam/ctrl.c
+++ zfcpdump-kernel-4.4/drivers/crypto/caam/ctrl.c
@@ -534,8 +534,8 @@ static int caam_probe(struct platform_de
 	 * long pointers in master configuration register
 	 */
 	clrsetbits_32(&ctrl->mcr, MCFGR_AWCACHE_MASK, MCFGR_AWCACHE_CACH |
-		      MCFGR_WDENABLE | (sizeof(dma_addr_t) == sizeof(u64) ?
-					MCFGR_LONG_PTR : 0));
+		      MCFGR_AWCACHE_BUFF | MCFGR_WDENABLE |
+		      (sizeof(dma_addr_t) == sizeof(u64) ? MCFGR_LONG_PTR : 0));
 
 	/*
 	 *  Read the Compile Time paramters and SCFGR to determine
--- zfcpdump-kernel-4.4.orig/drivers/crypto/caam/jr.c
+++ zfcpdump-kernel-4.4/drivers/crypto/caam/jr.c
@@ -248,7 +248,7 @@ static void caam_jr_dequeue(unsigned lon
 struct device *caam_jr_alloc(void)
 {
 	struct caam_drv_private_jr *jrpriv, *min_jrpriv = NULL;
-	struct device *dev = NULL;
+	struct device *dev = ERR_PTR(-ENODEV);
 	int min_tfm_cnt	= INT_MAX;
 	int tfm_cnt;
 
--- zfcpdump-kernel-4.4.orig/drivers/crypto/ccp/ccp-crypto-aes-cmac.c
+++ zfcpdump-kernel-4.4/drivers/crypto/ccp/ccp-crypto-aes-cmac.c
@@ -220,6 +220,42 @@ static int ccp_aes_cmac_digest(struct ah
 	return ccp_aes_cmac_finup(req);
 }
 
+static int ccp_aes_cmac_export(struct ahash_request *req, void *out)
+{
+	struct ccp_aes_cmac_req_ctx *rctx = ahash_request_ctx(req);
+	struct ccp_aes_cmac_exp_ctx state;
+
+	/* Don't let anything leak to 'out' */
+	memset(&state, 0, sizeof(state));
+
+	state.null_msg = rctx->null_msg;
+	memcpy(state.iv, rctx->iv, sizeof(state.iv));
+	state.buf_count = rctx->buf_count;
+	memcpy(state.buf, rctx->buf, sizeof(state.buf));
+
+	/* 'out' may not be aligned so memcpy from local variable */
+	memcpy(out, &state, sizeof(state));
+
+	return 0;
+}
+
+static int ccp_aes_cmac_import(struct ahash_request *req, const void *in)
+{
+	struct ccp_aes_cmac_req_ctx *rctx = ahash_request_ctx(req);
+	struct ccp_aes_cmac_exp_ctx state;
+
+	/* 'in' may not be aligned so memcpy to local variable */
+	memcpy(&state, in, sizeof(state));
+
+	memset(rctx, 0, sizeof(*rctx));
+	rctx->null_msg = state.null_msg;
+	memcpy(rctx->iv, state.iv, sizeof(rctx->iv));
+	rctx->buf_count = state.buf_count;
+	memcpy(rctx->buf, state.buf, sizeof(rctx->buf));
+
+	return 0;
+}
+
 static int ccp_aes_cmac_setkey(struct crypto_ahash *tfm, const u8 *key,
 			       unsigned int key_len)
 {
@@ -352,10 +388,13 @@ int ccp_register_aes_cmac_algs(struct li
 	alg->final = ccp_aes_cmac_final;
 	alg->finup = ccp_aes_cmac_finup;
 	alg->digest = ccp_aes_cmac_digest;
+	alg->export = ccp_aes_cmac_export;
+	alg->import = ccp_aes_cmac_import;
 	alg->setkey = ccp_aes_cmac_setkey;
 
 	halg = &alg->halg;
 	halg->digestsize = AES_BLOCK_SIZE;
+	halg->statesize = sizeof(struct ccp_aes_cmac_exp_ctx);
 
 	base = &halg->base;
 	snprintf(base->cra_name, CRYPTO_MAX_ALG_NAME, "cmac(aes)");
--- zfcpdump-kernel-4.4.orig/drivers/crypto/ccp/ccp-crypto-aes-xts.c
+++ zfcpdump-kernel-4.4/drivers/crypto/ccp/ccp-crypto-aes-xts.c
@@ -122,6 +122,7 @@ static int ccp_aes_xts_crypt(struct ablk
 	struct ccp_ctx *ctx = crypto_tfm_ctx(req->base.tfm);
 	struct ccp_aes_req_ctx *rctx = ablkcipher_request_ctx(req);
 	unsigned int unit;
+	u32 unit_size;
 	int ret;
 
 	if (!ctx->u.aes.key_len)
@@ -133,11 +134,17 @@ static int ccp_aes_xts_crypt(struct ablk
 	if (!req->info)
 		return -EINVAL;
 
-	for (unit = 0; unit < ARRAY_SIZE(unit_size_map); unit++)
-		if (!(req->nbytes & (unit_size_map[unit].size - 1)))
-			break;
+	unit_size = CCP_XTS_AES_UNIT_SIZE__LAST;
+	if (req->nbytes <= unit_size_map[0].size) {
+		for (unit = 0; unit < ARRAY_SIZE(unit_size_map); unit++) {
+			if (!(req->nbytes & (unit_size_map[unit].size - 1))) {
+				unit_size = unit_size_map[unit].value;
+				break;
+			}
+		}
+	}
 
-	if ((unit_size_map[unit].value == CCP_XTS_AES_UNIT_SIZE__LAST) ||
+	if ((unit_size == CCP_XTS_AES_UNIT_SIZE__LAST) ||
 	    (ctx->u.aes.key_len != AES_KEYSIZE_128)) {
 		/* Use the fallback to process the request for any
 		 * unsupported unit sizes or key sizes
@@ -158,7 +165,7 @@ static int ccp_aes_xts_crypt(struct ablk
 	rctx->cmd.engine = CCP_ENGINE_XTS_AES_128;
 	rctx->cmd.u.xts.action = (encrypt) ? CCP_AES_ACTION_ENCRYPT
 					   : CCP_AES_ACTION_DECRYPT;
-	rctx->cmd.u.xts.unit_size = unit_size_map[unit].value;
+	rctx->cmd.u.xts.unit_size = unit_size;
 	rctx->cmd.u.xts.key = &ctx->u.aes.key_sg;
 	rctx->cmd.u.xts.key_len = ctx->u.aes.key_len;
 	rctx->cmd.u.xts.iv = &rctx->iv_sg;
--- zfcpdump-kernel-4.4.orig/drivers/crypto/ccp/ccp-crypto-sha.c
+++ zfcpdump-kernel-4.4/drivers/crypto/ccp/ccp-crypto-sha.c
@@ -207,6 +207,46 @@ static int ccp_sha_digest(struct ahash_r
 	return ccp_sha_finup(req);
 }
 
+static int ccp_sha_export(struct ahash_request *req, void *out)
+{
+	struct ccp_sha_req_ctx *rctx = ahash_request_ctx(req);
+	struct ccp_sha_exp_ctx state;
+
+	/* Don't let anything leak to 'out' */
+	memset(&state, 0, sizeof(state));
+
+	state.type = rctx->type;
+	state.msg_bits = rctx->msg_bits;
+	state.first = rctx->first;
+	memcpy(state.ctx, rctx->ctx, sizeof(state.ctx));
+	state.buf_count = rctx->buf_count;
+	memcpy(state.buf, rctx->buf, sizeof(state.buf));
+
+	/* 'out' may not be aligned so memcpy from local variable */
+	memcpy(out, &state, sizeof(state));
+
+	return 0;
+}
+
+static int ccp_sha_import(struct ahash_request *req, const void *in)
+{
+	struct ccp_sha_req_ctx *rctx = ahash_request_ctx(req);
+	struct ccp_sha_exp_ctx state;
+
+	/* 'in' may not be aligned so memcpy to local variable */
+	memcpy(&state, in, sizeof(state));
+
+	memset(rctx, 0, sizeof(*rctx));
+	rctx->type = state.type;
+	rctx->msg_bits = state.msg_bits;
+	rctx->first = state.first;
+	memcpy(rctx->ctx, state.ctx, sizeof(rctx->ctx));
+	rctx->buf_count = state.buf_count;
+	memcpy(rctx->buf, state.buf, sizeof(rctx->buf));
+
+	return 0;
+}
+
 static int ccp_sha_setkey(struct crypto_ahash *tfm, const u8 *key,
 			  unsigned int key_len)
 {
@@ -403,9 +443,12 @@ static int ccp_register_sha_alg(struct l
 	alg->final = ccp_sha_final;
 	alg->finup = ccp_sha_finup;
 	alg->digest = ccp_sha_digest;
+	alg->export = ccp_sha_export;
+	alg->import = ccp_sha_import;
 
 	halg = &alg->halg;
 	halg->digestsize = def->digest_size;
+	halg->statesize = sizeof(struct ccp_sha_exp_ctx);
 
 	base = &halg->base;
 	snprintf(base->cra_name, CRYPTO_MAX_ALG_NAME, "%s", def->name);
--- zfcpdump-kernel-4.4.orig/drivers/crypto/ccp/ccp-crypto.h
+++ zfcpdump-kernel-4.4/drivers/crypto/ccp/ccp-crypto.h
@@ -129,6 +129,15 @@ struct ccp_aes_cmac_req_ctx {
 	struct ccp_cmd cmd;
 };
 
+struct ccp_aes_cmac_exp_ctx {
+	unsigned int null_msg;
+
+	u8 iv[AES_BLOCK_SIZE];
+
+	unsigned int buf_count;
+	u8 buf[AES_BLOCK_SIZE];
+};
+
 /***** SHA related defines *****/
 #define MAX_SHA_CONTEXT_SIZE	SHA256_DIGEST_SIZE
 #define MAX_SHA_BLOCK_SIZE	SHA256_BLOCK_SIZE
@@ -171,6 +180,19 @@ struct ccp_sha_req_ctx {
 	struct ccp_cmd cmd;
 };
 
+struct ccp_sha_exp_ctx {
+	enum ccp_sha_type type;
+
+	u64 msg_bits;
+
+	unsigned int first;
+
+	u8 ctx[MAX_SHA_CONTEXT_SIZE];
+
+	unsigned int buf_count;
+	u8 buf[MAX_SHA_BLOCK_SIZE];
+};
+
 /***** Common Context Structure *****/
 struct ccp_ctx {
 	int (*complete)(struct crypto_async_request *req, int ret);
--- zfcpdump-kernel-4.4.orig/drivers/crypto/marvell/cesa.c
+++ zfcpdump-kernel-4.4/drivers/crypto/marvell/cesa.c
@@ -306,7 +306,7 @@ static int mv_cesa_dev_dma_init(struct m
 		return -ENOMEM;
 
 	dma->padding_pool = dmam_pool_create("cesa_padding", dev, 72, 1, 0);
-	if (!dma->cache_pool)
+	if (!dma->padding_pool)
 		return -ENOMEM;
 
 	cesa->dma = dma;
@@ -420,7 +420,7 @@ static int mv_cesa_probe(struct platform
 	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "regs");
 	cesa->regs = devm_ioremap_resource(dev, res);
 	if (IS_ERR(cesa->regs))
-		return -ENOMEM;
+		return PTR_ERR(cesa->regs);
 
 	ret = mv_cesa_dev_dma_init(cesa);
 	if (ret)
--- zfcpdump-kernel-4.4.orig/drivers/crypto/nx/nx-842-powernv.c
+++ zfcpdump-kernel-4.4/drivers/crypto/nx/nx-842-powernv.c
@@ -442,6 +442,14 @@ static int nx842_powernv_function(const
 			     (unsigned int)ccw,
 			     (unsigned int)be32_to_cpu(crb->ccw));
 
+	/*
+	 * NX842 coprocessor sets 3rd bit in CR register with XER[S0].
+	 * XER[S0] is the integer summary overflow bit which is nothing
+	 * to do NX. Since this bit can be set with other return values,
+	 * mask this bit.
+	 */
+	ret &= ~ICSWX_XERS0;
+
 	switch (ret) {
 	case ICSWX_INITIATED:
 		ret = wait_for_csb(wmem, csb);
@@ -454,10 +462,6 @@ static int nx842_powernv_function(const
 		pr_err_ratelimited("ICSWX rejected\n");
 		ret = -EPROTO;
 		break;
-	default:
-		pr_err_ratelimited("Invalid ICSWX return code %x\n", ret);
-		ret = -EPROTO;
-		break;
 	}
 
 	if (!ret)
@@ -491,7 +495,7 @@ static int nx842_powernv_compress(const
 				  void *wmem)
 {
 	return nx842_powernv_function(in, inlen, out, outlenp,
-				      wmem, CCW_FC_842_COMP_CRC);
+				      wmem, CCW_FC_842_COMP_NOCRC);
 }
 
 /**
@@ -519,7 +523,7 @@ static int nx842_powernv_decompress(cons
 				    void *wmem)
 {
 	return nx842_powernv_function(in, inlen, out, outlenp,
-				      wmem, CCW_FC_842_DECOMP_CRC);
+				      wmem, CCW_FC_842_DECOMP_NOCRC);
 }
 
 static int __init nx842_powernv_probe(struct device_node *dn)
--- zfcpdump-kernel-4.4.orig/drivers/crypto/nx/nx-842-pseries.c
+++ zfcpdump-kernel-4.4/drivers/crypto/nx/nx-842-pseries.c
@@ -234,10 +234,6 @@ static int nx842_validate_result(struct
 		dev_dbg(dev, "%s: Out of space in output buffer\n",
 					__func__);
 		return -ENOSPC;
-	case 65: /* Calculated CRC doesn't match the passed value */
-		dev_dbg(dev, "%s: CRC mismatch for decompression\n",
-					__func__);
-		return -EINVAL;
 	case 66: /* Input data contains an illegal template field */
 	case 67: /* Template indicates data past the end of the input stream */
 		dev_dbg(dev, "%s: Bad data for decompression (code:%d)\n",
@@ -328,7 +324,7 @@ static int nx842_pseries_compress(const
 	slout.entries = (struct nx842_slentry *)workmem->slout;
 
 	/* Init operation */
-	op.flags = NX842_OP_COMPRESS_CRC;
+	op.flags = NX842_OP_COMPRESS;
 	csbcpb = &workmem->csbcpb;
 	memset(csbcpb, 0, sizeof(*csbcpb));
 	op.csbcpb = nx842_get_pa(csbcpb);
@@ -461,7 +457,7 @@ static int nx842_pseries_decompress(cons
 	slout.entries = (struct nx842_slentry *)workmem->slout;
 
 	/* Init operation */
-	op.flags = NX842_OP_DECOMPRESS_CRC;
+	op.flags = NX842_OP_DECOMPRESS;
 	csbcpb = &workmem->csbcpb;
 	memset(csbcpb, 0, sizeof(*csbcpb));
 	op.csbcpb = nx842_get_pa(csbcpb);
--- zfcpdump-kernel-4.4.orig/drivers/crypto/nx/nx.c
+++ zfcpdump-kernel-4.4/drivers/crypto/nx/nx.c
@@ -392,7 +392,7 @@ static void nx_of_update_msc(struct devi
 		     ((bytes_so_far + sizeof(struct msc_triplet)) <= lenp) &&
 		     i < msc->triplets;
 		     i++) {
-			if (msc->fc > NX_MAX_FC || msc->mode > NX_MAX_MODE) {
+			if (msc->fc >= NX_MAX_FC || msc->mode >= NX_MAX_MODE) {
 				dev_err(dev, "unknown function code/mode "
 					"combo: %d/%d (ignored)\n", msc->fc,
 					msc->mode);
--- zfcpdump-kernel-4.4.orig/drivers/crypto/qat/qat_common/Makefile
+++ zfcpdump-kernel-4.4/drivers/crypto/qat/qat_common/Makefile
@@ -2,6 +2,7 @@ $(obj)/qat_rsapubkey-asn1.o: $(obj)/qat_
 			     $(obj)/qat_rsapubkey-asn1.h
 $(obj)/qat_rsaprivkey-asn1.o: $(obj)/qat_rsaprivkey-asn1.c \
 			      $(obj)/qat_rsaprivkey-asn1.h
+$(obj)/qat_asym_algs.o: $(obj)/qat_rsapubkey-asn1.h $(obj)/qat_rsaprivkey-asn1.h
 
 clean-files += qat_rsapubkey-asn1.c qat_rsapubkey-asn1.h
 clean-files += qat_rsaprivkey-asn1.c qat_rsapvivkey-asn1.h
--- zfcpdump-kernel-4.4.orig/drivers/crypto/qat/qat_common/adf_common_drv.h
+++ zfcpdump-kernel-4.4/drivers/crypto/qat/qat_common/adf_common_drv.h
@@ -227,6 +227,8 @@ void adf_disable_vf2pf_interrupts(struct
 				  uint32_t vf_mask);
 void adf_enable_vf2pf_interrupts(struct adf_accel_dev *accel_dev,
 				 uint32_t vf_mask);
+int adf_init_pf_wq(void);
+void adf_exit_pf_wq(void);
 #else
 static inline int adf_sriov_configure(struct pci_dev *pdev, int numvfs)
 {
@@ -236,5 +238,14 @@ static inline int adf_sriov_configure(st
 static inline void adf_disable_sriov(struct adf_accel_dev *accel_dev)
 {
 }
+
+static inline int adf_init_pf_wq(void)
+{
+	return 0;
+}
+
+static inline void adf_exit_pf_wq(void)
+{
+}
 #endif
 #endif
--- zfcpdump-kernel-4.4.orig/drivers/crypto/qat/qat_common/adf_ctl_drv.c
+++ zfcpdump-kernel-4.4/drivers/crypto/qat/qat_common/adf_ctl_drv.c
@@ -469,12 +469,17 @@ static int __init adf_register_ctl_devic
 	if (adf_init_aer())
 		goto err_aer;
 
+	if (adf_init_pf_wq())
+		goto err_pf_wq;
+
 	if (qat_crypto_register())
 		goto err_crypto_register;
 
 	return 0;
 
 err_crypto_register:
+	adf_exit_pf_wq();
+err_pf_wq:
 	adf_exit_aer();
 err_aer:
 	adf_chr_drv_destroy();
@@ -487,6 +492,7 @@ static void __exit adf_unregister_ctl_de
 {
 	adf_chr_drv_destroy();
 	adf_exit_aer();
+	adf_exit_pf_wq();
 	qat_crypto_unregister();
 	adf_clean_vf_map(false);
 	mutex_destroy(&adf_ctl_lock);
--- zfcpdump-kernel-4.4.orig/drivers/crypto/qat/qat_common/adf_sriov.c
+++ zfcpdump-kernel-4.4/drivers/crypto/qat/qat_common/adf_sriov.c
@@ -119,11 +119,6 @@ static int adf_enable_sriov(struct adf_a
 	int i;
 	u32 reg;
 
-	/* Workqueue for PF2VF responses */
-	pf2vf_resp_wq = create_workqueue("qat_pf2vf_resp_wq");
-	if (!pf2vf_resp_wq)
-		return -ENOMEM;
-
 	for (i = 0, vf_info = accel_dev->pf.vf_info; i < totalvfs;
 	     i++, vf_info++) {
 		/* This ptr will be populated when VFs will be created */
@@ -216,11 +211,6 @@ void adf_disable_sriov(struct adf_accel_
 
 	kfree(accel_dev->pf.vf_info);
 	accel_dev->pf.vf_info = NULL;
-
-	if (pf2vf_resp_wq) {
-		destroy_workqueue(pf2vf_resp_wq);
-		pf2vf_resp_wq = NULL;
-	}
 }
 EXPORT_SYMBOL_GPL(adf_disable_sriov);
 
@@ -304,3 +294,19 @@ int adf_sriov_configure(struct pci_dev *
 	return numvfs;
 }
 EXPORT_SYMBOL_GPL(adf_sriov_configure);
+
+int __init adf_init_pf_wq(void)
+{
+	/* Workqueue for PF2VF responses */
+	pf2vf_resp_wq = create_workqueue("qat_pf2vf_resp_wq");
+
+	return !pf2vf_resp_wq ? -ENOMEM : 0;
+}
+
+void adf_exit_pf_wq(void)
+{
+	if (pf2vf_resp_wq) {
+		destroy_workqueue(pf2vf_resp_wq);
+		pf2vf_resp_wq = NULL;
+	}
+}
--- zfcpdump-kernel-4.4.orig/drivers/crypto/qat/qat_common/qat_algs.c
+++ zfcpdump-kernel-4.4/drivers/crypto/qat/qat_common/qat_algs.c
@@ -1262,8 +1262,8 @@ static struct crypto_alg qat_algs[] = {
 			.setkey = qat_alg_ablkcipher_xts_setkey,
 			.decrypt = qat_alg_ablkcipher_decrypt,
 			.encrypt = qat_alg_ablkcipher_encrypt,
-			.min_keysize = AES_MIN_KEY_SIZE,
-			.max_keysize = AES_MAX_KEY_SIZE,
+			.min_keysize = 2 * AES_MIN_KEY_SIZE,
+			.max_keysize = 2 * AES_MAX_KEY_SIZE,
 			.ivsize = AES_BLOCK_SIZE,
 		},
 	},
--- zfcpdump-kernel-4.4.orig/drivers/crypto/sunxi-ss/sun4i-ss-cipher.c
+++ zfcpdump-kernel-4.4/drivers/crypto/sunxi-ss/sun4i-ss-cipher.c
@@ -35,6 +35,7 @@ static int sun4i_ss_opti_poll(struct abl
 	unsigned int todo;
 	struct sg_mapping_iter mi, mo;
 	unsigned int oi, oo; /* offset for in and out */
+	unsigned long flags;
 
 	if (areq->nbytes == 0)
 		return 0;
@@ -49,7 +50,7 @@ static int sun4i_ss_opti_poll(struct abl
 		return -EINVAL;
 	}
 
-	spin_lock_bh(&ss->slock);
+	spin_lock_irqsave(&ss->slock, flags);
 
 	for (i = 0; i < op->keylen; i += 4)
 		writel(*(op->key + i / 4), ss->base + SS_KEY0 + i);
@@ -117,7 +118,7 @@ release_ss:
 	sg_miter_stop(&mi);
 	sg_miter_stop(&mo);
 	writel(0, ss->base + SS_CTL);
-	spin_unlock_bh(&ss->slock);
+	spin_unlock_irqrestore(&ss->slock, flags);
 	return err;
 }
 
@@ -149,6 +150,7 @@ static int sun4i_ss_cipher_poll(struct a
 	unsigned int ob = 0;	/* offset in buf */
 	unsigned int obo = 0;	/* offset in bufo*/
 	unsigned int obl = 0;	/* length of data in bufo */
+	unsigned long flags;
 
 	if (areq->nbytes == 0)
 		return 0;
@@ -181,7 +183,7 @@ static int sun4i_ss_cipher_poll(struct a
 	if (no_chunk == 1)
 		return sun4i_ss_opti_poll(areq);
 
-	spin_lock_bh(&ss->slock);
+	spin_lock_irqsave(&ss->slock, flags);
 
 	for (i = 0; i < op->keylen; i += 4)
 		writel(*(op->key + i / 4), ss->base + SS_KEY0 + i);
@@ -308,7 +310,7 @@ release_ss:
 	sg_miter_stop(&mi);
 	sg_miter_stop(&mo);
 	writel(0, ss->base + SS_CTL);
-	spin_unlock_bh(&ss->slock);
+	spin_unlock_irqrestore(&ss->slock, flags);
 
 	return err;
 }
--- zfcpdump-kernel-4.4.orig/drivers/crypto/sunxi-ss/sun4i-ss-core.c
+++ zfcpdump-kernel-4.4/drivers/crypto/sunxi-ss/sun4i-ss-core.c
@@ -39,6 +39,7 @@ static struct sun4i_ss_alg_template ss_a
 		.import = sun4i_hash_import_md5,
 		.halg = {
 			.digestsize = MD5_DIGEST_SIZE,
+			.statesize = sizeof(struct md5_state),
 			.base = {
 				.cra_name = "md5",
 				.cra_driver_name = "md5-sun4i-ss",
@@ -66,6 +67,7 @@ static struct sun4i_ss_alg_template ss_a
 		.import = sun4i_hash_import_sha1,
 		.halg = {
 			.digestsize = SHA1_DIGEST_SIZE,
+			.statesize = sizeof(struct sha1_state),
 			.base = {
 				.cra_name = "sha1",
 				.cra_driver_name = "sha1-sun4i-ss",
--- zfcpdump-kernel-4.4.orig/drivers/crypto/talitos.c
+++ zfcpdump-kernel-4.4/drivers/crypto/talitos.c
@@ -63,6 +63,14 @@ static void to_talitos_ptr(struct talito
 		ptr->eptr = upper_32_bits(dma_addr);
 }
 
+static void copy_talitos_ptr(struct talitos_ptr *dst_ptr,
+			     struct talitos_ptr *src_ptr, bool is_sec1)
+{
+	dst_ptr->ptr = src_ptr->ptr;
+	if (!is_sec1)
+		dst_ptr->eptr = src_ptr->eptr;
+}
+
 static void to_talitos_ptr_len(struct talitos_ptr *ptr, unsigned int len,
 			       bool is_sec1)
 {
@@ -827,6 +835,16 @@ struct talitos_ahash_req_ctx {
 	struct scatterlist *psrc;
 };
 
+struct talitos_export_state {
+	u32 hw_context[TALITOS_MDEU_MAX_CONTEXT_SIZE / sizeof(u32)];
+	u8 buf[HASH_MAX_BLOCK_SIZE];
+	unsigned int swinit;
+	unsigned int first;
+	unsigned int last;
+	unsigned int to_hash_later;
+	unsigned int nbuf;
+};
+
 static int aead_setkey(struct crypto_aead *authenc,
 		       const u8 *key, unsigned int keylen)
 {
@@ -1083,21 +1101,20 @@ static int ipsec_esp(struct talitos_edes
 	sg_count = dma_map_sg(dev, areq->src, edesc->src_nents ?: 1,
 			      (areq->src == areq->dst) ? DMA_BIDIRECTIONAL
 							   : DMA_TO_DEVICE);
-
 	/* hmac data */
 	desc->ptr[1].len = cpu_to_be16(areq->assoclen);
 	if (sg_count > 1 &&
 	    (ret = sg_to_link_tbl_offset(areq->src, sg_count, 0,
 					 areq->assoclen,
 					 &edesc->link_tbl[tbl_off])) > 1) {
-		tbl_off += ret;
-
 		to_talitos_ptr(&desc->ptr[1], edesc->dma_link_tbl + tbl_off *
 			       sizeof(struct talitos_ptr), 0);
 		desc->ptr[1].j_extent = DESC_PTR_LNKTBL_JUMP;
 
 		dma_sync_single_for_device(dev, edesc->dma_link_tbl,
 					   edesc->dma_len, DMA_BIDIRECTIONAL);
+
+		tbl_off += ret;
 	} else {
 		to_talitos_ptr(&desc->ptr[1], sg_dma_address(areq->src), 0);
 		desc->ptr[1].j_extent = 0;
@@ -1126,11 +1143,13 @@ static int ipsec_esp(struct talitos_edes
 	if (edesc->desc.hdr & DESC_HDR_MODE1_MDEU_CICV)
 		sg_link_tbl_len += authsize;
 
-	if (sg_count > 1 &&
-	    (ret = sg_to_link_tbl_offset(areq->src, sg_count, areq->assoclen,
-					 sg_link_tbl_len,
-					 &edesc->link_tbl[tbl_off])) > 1) {
-		tbl_off += ret;
+	if (sg_count == 1) {
+		to_talitos_ptr(&desc->ptr[4], sg_dma_address(areq->src) +
+			       areq->assoclen, 0);
+	} else if ((ret = sg_to_link_tbl_offset(areq->src, sg_count,
+						areq->assoclen, sg_link_tbl_len,
+						&edesc->link_tbl[tbl_off])) >
+		   1) {
 		desc->ptr[4].j_extent |= DESC_PTR_LNKTBL_JUMP;
 		to_talitos_ptr(&desc->ptr[4], edesc->dma_link_tbl +
 					      tbl_off *
@@ -1138,8 +1157,10 @@ static int ipsec_esp(struct talitos_edes
 		dma_sync_single_for_device(dev, edesc->dma_link_tbl,
 					   edesc->dma_len,
 					   DMA_BIDIRECTIONAL);
-	} else
-		to_talitos_ptr(&desc->ptr[4], sg_dma_address(areq->src), 0);
+		tbl_off += ret;
+	} else {
+		copy_talitos_ptr(&desc->ptr[4], &edesc->link_tbl[tbl_off], 0);
+	}
 
 	/* cipher out */
 	desc->ptr[5].len = cpu_to_be16(cryptlen);
@@ -1151,11 +1172,13 @@ static int ipsec_esp(struct talitos_edes
 
 	edesc->icv_ool = false;
 
-	if (sg_count > 1 &&
-	    (sg_count = sg_to_link_tbl_offset(areq->dst, sg_count,
+	if (sg_count == 1) {
+		to_talitos_ptr(&desc->ptr[5], sg_dma_address(areq->dst) +
+			       areq->assoclen, 0);
+	} else if ((sg_count =
+			sg_to_link_tbl_offset(areq->dst, sg_count,
 					      areq->assoclen, cryptlen,
-					      &edesc->link_tbl[tbl_off])) >
-	    1) {
+					      &edesc->link_tbl[tbl_off])) > 1) {
 		struct talitos_ptr *tbl_ptr = &edesc->link_tbl[tbl_off];
 
 		to_talitos_ptr(&desc->ptr[5], edesc->dma_link_tbl +
@@ -1178,8 +1201,9 @@ static int ipsec_esp(struct talitos_edes
 					   edesc->dma_len, DMA_BIDIRECTIONAL);
 
 		edesc->icv_ool = true;
-	} else
-		to_talitos_ptr(&desc->ptr[5], sg_dma_address(areq->dst), 0);
+	} else {
+		copy_talitos_ptr(&desc->ptr[5], &edesc->link_tbl[tbl_off], 0);
+	}
 
 	/* iv out */
 	map_single_talitos_ptr(dev, &desc->ptr[6], ivsize, ctx->iv,
@@ -1940,6 +1964,46 @@ static int ahash_digest(struct ahash_req
 	return ahash_process_req(areq, areq->nbytes);
 }
 
+static int ahash_export(struct ahash_request *areq, void *out)
+{
+	struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
+	struct talitos_export_state *export = out;
+
+	memcpy(export->hw_context, req_ctx->hw_context,
+	       req_ctx->hw_context_size);
+	memcpy(export->buf, req_ctx->buf, req_ctx->nbuf);
+	export->swinit = req_ctx->swinit;
+	export->first = req_ctx->first;
+	export->last = req_ctx->last;
+	export->to_hash_later = req_ctx->to_hash_later;
+	export->nbuf = req_ctx->nbuf;
+
+	return 0;
+}
+
+static int ahash_import(struct ahash_request *areq, const void *in)
+{
+	struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
+	struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
+	const struct talitos_export_state *export = in;
+
+	memset(req_ctx, 0, sizeof(*req_ctx));
+	req_ctx->hw_context_size =
+		(crypto_ahash_digestsize(tfm) <= SHA256_DIGEST_SIZE)
+			? TALITOS_MDEU_CONTEXT_SIZE_MD5_SHA1_SHA256
+			: TALITOS_MDEU_CONTEXT_SIZE_SHA384_SHA512;
+	memcpy(req_ctx->hw_context, export->hw_context,
+	       req_ctx->hw_context_size);
+	memcpy(req_ctx->buf, export->buf, export->nbuf);
+	req_ctx->swinit = export->swinit;
+	req_ctx->first = export->first;
+	req_ctx->last = export->last;
+	req_ctx->to_hash_later = export->to_hash_later;
+	req_ctx->nbuf = export->nbuf;
+
+	return 0;
+}
+
 struct keyhash_result {
 	struct completion completion;
 	int err;
@@ -2334,6 +2398,7 @@ static struct talitos_alg_template drive
 	{	.type = CRYPTO_ALG_TYPE_AHASH,
 		.alg.hash = {
 			.halg.digestsize = MD5_DIGEST_SIZE,
+			.halg.statesize = sizeof(struct talitos_export_state),
 			.halg.base = {
 				.cra_name = "md5",
 				.cra_driver_name = "md5-talitos",
@@ -2349,6 +2414,7 @@ static struct talitos_alg_template drive
 	{	.type = CRYPTO_ALG_TYPE_AHASH,
 		.alg.hash = {
 			.halg.digestsize = SHA1_DIGEST_SIZE,
+			.halg.statesize = sizeof(struct talitos_export_state),
 			.halg.base = {
 				.cra_name = "sha1",
 				.cra_driver_name = "sha1-talitos",
@@ -2364,6 +2430,7 @@ static struct talitos_alg_template drive
 	{	.type = CRYPTO_ALG_TYPE_AHASH,
 		.alg.hash = {
 			.halg.digestsize = SHA224_DIGEST_SIZE,
+			.halg.statesize = sizeof(struct talitos_export_state),
 			.halg.base = {
 				.cra_name = "sha224",
 				.cra_driver_name = "sha224-talitos",
@@ -2379,6 +2446,7 @@ static struct talitos_alg_template drive
 	{	.type = CRYPTO_ALG_TYPE_AHASH,
 		.alg.hash = {
 			.halg.digestsize = SHA256_DIGEST_SIZE,
+			.halg.statesize = sizeof(struct talitos_export_state),
 			.halg.base = {
 				.cra_name = "sha256",
 				.cra_driver_name = "sha256-talitos",
@@ -2394,6 +2462,7 @@ static struct talitos_alg_template drive
 	{	.type = CRYPTO_ALG_TYPE_AHASH,
 		.alg.hash = {
 			.halg.digestsize = SHA384_DIGEST_SIZE,
+			.halg.statesize = sizeof(struct talitos_export_state),
 			.halg.base = {
 				.cra_name = "sha384",
 				.cra_driver_name = "sha384-talitos",
@@ -2409,6 +2478,7 @@ static struct talitos_alg_template drive
 	{	.type = CRYPTO_ALG_TYPE_AHASH,
 		.alg.hash = {
 			.halg.digestsize = SHA512_DIGEST_SIZE,
+			.halg.statesize = sizeof(struct talitos_export_state),
 			.halg.base = {
 				.cra_name = "sha512",
 				.cra_driver_name = "sha512-talitos",
@@ -2424,6 +2494,7 @@ static struct talitos_alg_template drive
 	{	.type = CRYPTO_ALG_TYPE_AHASH,
 		.alg.hash = {
 			.halg.digestsize = MD5_DIGEST_SIZE,
+			.halg.statesize = sizeof(struct talitos_export_state),
 			.halg.base = {
 				.cra_name = "hmac(md5)",
 				.cra_driver_name = "hmac-md5-talitos",
@@ -2439,6 +2510,7 @@ static struct talitos_alg_template drive
 	{	.type = CRYPTO_ALG_TYPE_AHASH,
 		.alg.hash = {
 			.halg.digestsize = SHA1_DIGEST_SIZE,
+			.halg.statesize = sizeof(struct talitos_export_state),
 			.halg.base = {
 				.cra_name = "hmac(sha1)",
 				.cra_driver_name = "hmac-sha1-talitos",
@@ -2454,6 +2526,7 @@ static struct talitos_alg_template drive
 	{	.type = CRYPTO_ALG_TYPE_AHASH,
 		.alg.hash = {
 			.halg.digestsize = SHA224_DIGEST_SIZE,
+			.halg.statesize = sizeof(struct talitos_export_state),
 			.halg.base = {
 				.cra_name = "hmac(sha224)",
 				.cra_driver_name = "hmac-sha224-talitos",
@@ -2469,6 +2542,7 @@ static struct talitos_alg_template drive
 	{	.type = CRYPTO_ALG_TYPE_AHASH,
 		.alg.hash = {
 			.halg.digestsize = SHA256_DIGEST_SIZE,
+			.halg.statesize = sizeof(struct talitos_export_state),
 			.halg.base = {
 				.cra_name = "hmac(sha256)",
 				.cra_driver_name = "hmac-sha256-talitos",
@@ -2484,6 +2558,7 @@ static struct talitos_alg_template drive
 	{	.type = CRYPTO_ALG_TYPE_AHASH,
 		.alg.hash = {
 			.halg.digestsize = SHA384_DIGEST_SIZE,
+			.halg.statesize = sizeof(struct talitos_export_state),
 			.halg.base = {
 				.cra_name = "hmac(sha384)",
 				.cra_driver_name = "hmac-sha384-talitos",
@@ -2499,6 +2574,7 @@ static struct talitos_alg_template drive
 	{	.type = CRYPTO_ALG_TYPE_AHASH,
 		.alg.hash = {
 			.halg.digestsize = SHA512_DIGEST_SIZE,
+			.halg.statesize = sizeof(struct talitos_export_state),
 			.halg.base = {
 				.cra_name = "hmac(sha512)",
 				.cra_driver_name = "hmac-sha512-talitos",
@@ -2519,21 +2595,11 @@ struct talitos_crypto_alg {
 	struct talitos_alg_template algt;
 };
 
-static int talitos_cra_init(struct crypto_tfm *tfm)
+static int talitos_init_common(struct talitos_ctx *ctx,
+			       struct talitos_crypto_alg *talitos_alg)
 {
-	struct crypto_alg *alg = tfm->__crt_alg;
-	struct talitos_crypto_alg *talitos_alg;
-	struct talitos_ctx *ctx = crypto_tfm_ctx(tfm);
 	struct talitos_private *priv;
 
-	if ((alg->cra_flags & CRYPTO_ALG_TYPE_MASK) == CRYPTO_ALG_TYPE_AHASH)
-		talitos_alg = container_of(__crypto_ahash_alg(alg),
-					   struct talitos_crypto_alg,
-					   algt.alg.hash);
-	else
-		talitos_alg = container_of(alg, struct talitos_crypto_alg,
-					   algt.alg.crypto);
-
 	/* update context with ptr to dev */
 	ctx->dev = talitos_alg->dev;
 
@@ -2551,10 +2617,33 @@ static int talitos_cra_init(struct crypt
 	return 0;
 }
 
+static int talitos_cra_init(struct crypto_tfm *tfm)
+{
+	struct crypto_alg *alg = tfm->__crt_alg;
+	struct talitos_crypto_alg *talitos_alg;
+	struct talitos_ctx *ctx = crypto_tfm_ctx(tfm);
+
+	if ((alg->cra_flags & CRYPTO_ALG_TYPE_MASK) == CRYPTO_ALG_TYPE_AHASH)
+		talitos_alg = container_of(__crypto_ahash_alg(alg),
+					   struct talitos_crypto_alg,
+					   algt.alg.hash);
+	else
+		talitos_alg = container_of(alg, struct talitos_crypto_alg,
+					   algt.alg.crypto);
+
+	return talitos_init_common(ctx, talitos_alg);
+}
+
 static int talitos_cra_init_aead(struct crypto_aead *tfm)
 {
-	talitos_cra_init(crypto_aead_tfm(tfm));
-	return 0;
+	struct aead_alg *alg = crypto_aead_alg(tfm);
+	struct talitos_crypto_alg *talitos_alg;
+	struct talitos_ctx *ctx = crypto_aead_ctx(tfm);
+
+	talitos_alg = container_of(alg, struct talitos_crypto_alg,
+				   algt.alg.aead);
+
+	return talitos_init_common(ctx, talitos_alg);
 }
 
 static int talitos_cra_init_ahash(struct crypto_tfm *tfm)
@@ -2677,6 +2766,8 @@ static struct talitos_crypto_alg *talito
 		t_alg->algt.alg.hash.finup = ahash_finup;
 		t_alg->algt.alg.hash.digest = ahash_digest;
 		t_alg->algt.alg.hash.setkey = ahash_setkey;
+		t_alg->algt.alg.hash.import = ahash_import;
+		t_alg->algt.alg.hash.export = ahash_export;
 
 		if (!(priv->features & TALITOS_FTR_HMAC_OK) &&
 		    !strncmp(alg->cra_name, "hmac", 4)) {
--- zfcpdump-kernel-4.4.orig/drivers/crypto/ux500/cryp/cryp_core.c
+++ zfcpdump-kernel-4.4/drivers/crypto/ux500/cryp/cryp_core.c
@@ -1440,9 +1440,9 @@ static int ux500_cryp_probe(struct platf
 
 	device_data->phybase = res->start;
 	device_data->base = devm_ioremap_resource(dev, res);
-	if (!device_data->base) {
+	if (IS_ERR(device_data->base)) {
 		dev_err(dev, "[%s]: ioremap failed!", __func__);
-		ret = -ENOMEM;
+		ret = PTR_ERR(device_data->base);
 		goto out;
 	}
 
--- zfcpdump-kernel-4.4.orig/drivers/crypto/ux500/hash/hash_core.c
+++ zfcpdump-kernel-4.4/drivers/crypto/ux500/hash/hash_core.c
@@ -797,7 +797,7 @@ static int hash_process_data(struct hash
 						&device_data->state);
 				memmove(req_ctx->state.buffer,
 					device_data->state.buffer,
-					HASH_BLOCK_SIZE / sizeof(u32));
+					HASH_BLOCK_SIZE);
 				if (ret) {
 					dev_err(device_data->dev,
 						"%s: hash_resume_state() failed!\n",
@@ -848,7 +848,7 @@ static int hash_process_data(struct hash
 
 			memmove(device_data->state.buffer,
 				req_ctx->state.buffer,
-				HASH_BLOCK_SIZE / sizeof(u32));
+				HASH_BLOCK_SIZE);
 			if (ret) {
 				dev_err(device_data->dev, "%s: hash_save_state() failed!\n",
 					__func__);
@@ -1675,9 +1675,9 @@ static int ux500_hash_probe(struct platf
 
 	device_data->phybase = res->start;
 	device_data->base = devm_ioremap_resource(dev, res);
-	if (!device_data->base) {
+	if (IS_ERR(device_data->base)) {
 		dev_err(dev, "%s: ioremap() failed!\n", __func__);
-		ret = -ENOMEM;
+		ret = PTR_ERR(device_data->base);
 		goto out;
 	}
 	spin_lock_init(&device_data->ctx_lock);
--- zfcpdump-kernel-4.4.orig/drivers/crypto/vmx/Kconfig
+++ zfcpdump-kernel-4.4/drivers/crypto/vmx/Kconfig
@@ -1,6 +1,7 @@
 config CRYPTO_DEV_VMX_ENCRYPT
 	tristate "Encryption acceleration support on P8 CPU"
 	depends on CRYPTO_DEV_VMX
+	select CRYPTO_GHASH
 	default y
 	help
 	  Support for VMX cryptographic acceleration instructions on Power8 CPU.
--- zfcpdump-kernel-4.4.orig/drivers/crypto/vmx/Makefile
+++ zfcpdump-kernel-4.4/drivers/crypto/vmx/Makefile
@@ -1,5 +1,5 @@
 obj-$(CONFIG_CRYPTO_DEV_VMX_ENCRYPT) += vmx-crypto.o
-vmx-crypto-objs := vmx.o aesp8-ppc.o ghashp8-ppc.o aes.o aes_cbc.o aes_ctr.o ghash.o
+vmx-crypto-objs := vmx.o aesp8-ppc.o ghashp8-ppc.o aes.o aes_cbc.o aes_ctr.o aes_xts.o ghash.o
 
 ifeq ($(CONFIG_CPU_LITTLE_ENDIAN),y)
 TARGET := linux-ppc64le
--- zfcpdump-kernel-4.4.orig/drivers/crypto/vmx/aes.c
+++ zfcpdump-kernel-4.4/drivers/crypto/vmx/aes.c
@@ -83,10 +83,10 @@ static int p8_aes_setkey(struct crypto_t
 
 	preempt_disable();
 	pagefault_disable();
-	enable_kernel_altivec();
 	enable_kernel_vsx();
 	ret = aes_p8_set_encrypt_key(key, keylen * 8, &ctx->enc_key);
 	ret += aes_p8_set_decrypt_key(key, keylen * 8, &ctx->dec_key);
+	disable_kernel_vsx();
 	pagefault_enable();
 	preempt_enable();
 
@@ -103,9 +103,9 @@ static void p8_aes_encrypt(struct crypto
 	} else {
 		preempt_disable();
 		pagefault_disable();
-		enable_kernel_altivec();
 		enable_kernel_vsx();
 		aes_p8_encrypt(src, dst, &ctx->enc_key);
+		disable_kernel_vsx();
 		pagefault_enable();
 		preempt_enable();
 	}
@@ -120,9 +120,9 @@ static void p8_aes_decrypt(struct crypto
 	} else {
 		preempt_disable();
 		pagefault_disable();
-		enable_kernel_altivec();
 		enable_kernel_vsx();
 		aes_p8_decrypt(src, dst, &ctx->dec_key);
+		disable_kernel_vsx();
 		pagefault_enable();
 		preempt_enable();
 	}
--- zfcpdump-kernel-4.4.orig/drivers/crypto/vmx/aes_cbc.c
+++ zfcpdump-kernel-4.4/drivers/crypto/vmx/aes_cbc.c
@@ -84,10 +84,10 @@ static int p8_aes_cbc_setkey(struct cryp
 
 	preempt_disable();
 	pagefault_disable();
-	enable_kernel_altivec();
 	enable_kernel_vsx();
 	ret = aes_p8_set_encrypt_key(key, keylen * 8, &ctx->enc_key);
 	ret += aes_p8_set_decrypt_key(key, keylen * 8, &ctx->dec_key);
+	disable_kernel_vsx();
 	pagefault_enable();
 	preempt_enable();
 
@@ -115,7 +115,6 @@ static int p8_aes_cbc_encrypt(struct blk
 	} else {
 		preempt_disable();
 		pagefault_disable();
-		enable_kernel_altivec();
 		enable_kernel_vsx();
 
 		blkcipher_walk_init(&walk, dst, src, nbytes);
@@ -129,6 +128,7 @@ static int p8_aes_cbc_encrypt(struct blk
 			ret = blkcipher_walk_done(desc, &walk, nbytes);
 		}
 
+		disable_kernel_vsx();
 		pagefault_enable();
 		preempt_enable();
 	}
@@ -156,7 +156,6 @@ static int p8_aes_cbc_decrypt(struct blk
 	} else {
 		preempt_disable();
 		pagefault_disable();
-		enable_kernel_altivec();
 		enable_kernel_vsx();
 
 		blkcipher_walk_init(&walk, dst, src, nbytes);
@@ -170,6 +169,7 @@ static int p8_aes_cbc_decrypt(struct blk
 			ret = blkcipher_walk_done(desc, &walk, nbytes);
 		}
 
+		disable_kernel_vsx();
 		pagefault_enable();
 		preempt_enable();
 	}
@@ -182,7 +182,7 @@ struct crypto_alg p8_aes_cbc_alg = {
 	.cra_name = "cbc(aes)",
 	.cra_driver_name = "p8_aes_cbc",
 	.cra_module = THIS_MODULE,
-	.cra_priority = 1000,
+	.cra_priority = 2000,
 	.cra_type = &crypto_blkcipher_type,
 	.cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER | CRYPTO_ALG_NEED_FALLBACK,
 	.cra_alignmask = 0,
@@ -191,7 +191,7 @@ struct crypto_alg p8_aes_cbc_alg = {
 	.cra_init = p8_aes_cbc_init,
 	.cra_exit = p8_aes_cbc_exit,
 	.cra_blkcipher = {
-			  .ivsize = 0,
+			  .ivsize = AES_BLOCK_SIZE,
 			  .min_keysize = AES_MIN_KEY_SIZE,
 			  .max_keysize = AES_MAX_KEY_SIZE,
 			  .setkey = p8_aes_cbc_setkey,
--- zfcpdump-kernel-4.4.orig/drivers/crypto/vmx/aes_ctr.c
+++ zfcpdump-kernel-4.4/drivers/crypto/vmx/aes_ctr.c
@@ -81,9 +81,9 @@ static int p8_aes_ctr_setkey(struct cryp
 	struct p8_aes_ctr_ctx *ctx = crypto_tfm_ctx(tfm);
 
 	pagefault_disable();
-	enable_kernel_altivec();
 	enable_kernel_vsx();
 	ret = aes_p8_set_encrypt_key(key, keylen * 8, &ctx->enc_key);
+	disable_kernel_vsx();
 	pagefault_enable();
 
 	ret += crypto_blkcipher_setkey(ctx->fallback, key, keylen);
@@ -100,9 +100,9 @@ static void p8_aes_ctr_final(struct p8_a
 	unsigned int nbytes = walk->nbytes;
 
 	pagefault_disable();
-	enable_kernel_altivec();
 	enable_kernel_vsx();
 	aes_p8_encrypt(ctrblk, keystream, &ctx->enc_key);
+	disable_kernel_vsx();
 	pagefault_enable();
 
 	crypto_xor(keystream, src, nbytes);
@@ -133,7 +133,6 @@ static int p8_aes_ctr_crypt(struct blkci
 		ret = blkcipher_walk_virt_block(desc, &walk, AES_BLOCK_SIZE);
 		while ((nbytes = walk.nbytes) >= AES_BLOCK_SIZE) {
 			pagefault_disable();
-			enable_kernel_altivec();
 			enable_kernel_vsx();
 			aes_p8_ctr32_encrypt_blocks(walk.src.virt.addr,
 						    walk.dst.virt.addr,
@@ -142,6 +141,7 @@ static int p8_aes_ctr_crypt(struct blkci
 						    AES_BLOCK_SIZE,
 						    &ctx->enc_key,
 						    walk.iv);
+			disable_kernel_vsx();
 			pagefault_enable();
 
 			/* We need to update IV mostly for last bytes/round */
@@ -166,7 +166,7 @@ struct crypto_alg p8_aes_ctr_alg = {
 	.cra_name = "ctr(aes)",
 	.cra_driver_name = "p8_aes_ctr",
 	.cra_module = THIS_MODULE,
-	.cra_priority = 1000,
+	.cra_priority = 2000,
 	.cra_type = &crypto_blkcipher_type,
 	.cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER | CRYPTO_ALG_NEED_FALLBACK,
 	.cra_alignmask = 0,
@@ -175,7 +175,7 @@ struct crypto_alg p8_aes_ctr_alg = {
 	.cra_init = p8_aes_ctr_init,
 	.cra_exit = p8_aes_ctr_exit,
 	.cra_blkcipher = {
-			  .ivsize = 0,
+			  .ivsize = AES_BLOCK_SIZE,
 			  .min_keysize = AES_MIN_KEY_SIZE,
 			  .max_keysize = AES_MAX_KEY_SIZE,
 			  .setkey = p8_aes_ctr_setkey,
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/crypto/vmx/aes_xts.c
@@ -0,0 +1,190 @@
+/**
+ * AES XTS routines supporting VMX In-core instructions on Power 8
+ *
+ * Copyright (C) 2015 International Business Machines Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundations; version 2 only.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY of FITNESS FOR A PARTICUPAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Author: Leonidas S. Barbosa <leosilva@linux.vnet.ibm.com>
+ */
+
+#include <linux/types.h>
+#include <linux/err.h>
+#include <linux/crypto.h>
+#include <linux/delay.h>
+#include <linux/hardirq.h>
+#include <asm/switch_to.h>
+#include <crypto/aes.h>
+#include <crypto/scatterwalk.h>
+#include <crypto/xts.h>
+
+#include "aesp8-ppc.h"
+
+struct p8_aes_xts_ctx {
+	struct crypto_blkcipher *fallback;
+	struct aes_key enc_key;
+	struct aes_key dec_key;
+	struct aes_key tweak_key;
+};
+
+static int p8_aes_xts_init(struct crypto_tfm *tfm)
+{
+	const char *alg;
+	struct crypto_blkcipher *fallback;
+	struct p8_aes_xts_ctx *ctx = crypto_tfm_ctx(tfm);
+
+	if (!(alg = crypto_tfm_alg_name(tfm))) {
+		printk(KERN_ERR "Failed to get algorithm name.\n");
+		return -ENOENT;
+	}
+
+	fallback =
+		crypto_alloc_blkcipher(alg, 0, CRYPTO_ALG_NEED_FALLBACK);
+	if (IS_ERR(fallback)) {
+		printk(KERN_ERR
+			"Failed to allocate transformation for '%s': %ld\n",
+			alg, PTR_ERR(fallback));
+		return PTR_ERR(fallback);
+	}
+	printk(KERN_INFO "Using '%s' as fallback implementation.\n",
+		crypto_tfm_alg_driver_name((struct crypto_tfm *) fallback));
+
+	crypto_blkcipher_set_flags(
+		fallback,
+		crypto_blkcipher_get_flags((struct crypto_blkcipher *)tfm));
+	ctx->fallback = fallback;
+
+	return 0;
+}
+
+static void p8_aes_xts_exit(struct crypto_tfm *tfm)
+{
+	struct p8_aes_xts_ctx *ctx = crypto_tfm_ctx(tfm);
+
+	if (ctx->fallback) {
+		crypto_free_blkcipher(ctx->fallback);
+		ctx->fallback = NULL;
+	}
+}
+
+static int p8_aes_xts_setkey(struct crypto_tfm *tfm, const u8 *key,
+			     unsigned int keylen)
+{
+	int ret;
+	struct p8_aes_xts_ctx *ctx = crypto_tfm_ctx(tfm);
+
+	ret = xts_check_key(tfm, key, keylen);
+	if (ret)
+		return ret;
+
+	preempt_disable();
+	pagefault_disable();
+	enable_kernel_vsx();
+	ret = aes_p8_set_encrypt_key(key + keylen/2, (keylen/2) * 8, &ctx->tweak_key);
+	ret += aes_p8_set_encrypt_key(key, (keylen/2) * 8, &ctx->enc_key);
+	ret += aes_p8_set_decrypt_key(key, (keylen/2) * 8, &ctx->dec_key);
+	disable_kernel_vsx();
+	pagefault_enable();
+	preempt_enable();
+
+	ret += crypto_blkcipher_setkey(ctx->fallback, key, keylen);
+	return ret;
+}
+
+static int p8_aes_xts_crypt(struct blkcipher_desc *desc,
+			    struct scatterlist *dst,
+			    struct scatterlist *src,
+			    unsigned int nbytes, int enc)
+{
+	int ret;
+	u8 tweak[AES_BLOCK_SIZE];
+	u8 *iv;
+	struct blkcipher_walk walk;
+	struct p8_aes_xts_ctx *ctx =
+		crypto_tfm_ctx(crypto_blkcipher_tfm(desc->tfm));
+	struct blkcipher_desc fallback_desc = {
+		.tfm = ctx->fallback,
+		.info = desc->info,
+		.flags = desc->flags
+	};
+
+	if (in_interrupt()) {
+		ret = enc ? crypto_blkcipher_encrypt(&fallback_desc, dst, src, nbytes) :
+                            crypto_blkcipher_decrypt(&fallback_desc, dst, src, nbytes);
+	} else {
+		preempt_disable();
+		pagefault_disable();
+		enable_kernel_vsx();
+
+		blkcipher_walk_init(&walk, dst, src, nbytes);
+
+		ret = blkcipher_walk_virt(desc, &walk);
+		iv = walk.iv;
+		memset(tweak, 0, AES_BLOCK_SIZE);
+		aes_p8_encrypt(iv, tweak, &ctx->tweak_key);
+
+		while ((nbytes = walk.nbytes)) {
+			if (enc)
+				aes_p8_xts_encrypt(walk.src.virt.addr, walk.dst.virt.addr,
+						nbytes & AES_BLOCK_MASK, &ctx->enc_key, NULL, tweak);
+			else
+				aes_p8_xts_decrypt(walk.src.virt.addr, walk.dst.virt.addr,
+						nbytes & AES_BLOCK_MASK, &ctx->dec_key, NULL, tweak);
+
+			nbytes &= AES_BLOCK_SIZE - 1;
+			ret = blkcipher_walk_done(desc, &walk, nbytes);
+		}
+
+		disable_kernel_vsx();
+		pagefault_enable();
+		preempt_enable();
+	}
+	return ret;
+}
+
+static int p8_aes_xts_encrypt(struct blkcipher_desc *desc,
+			      struct scatterlist *dst,
+			      struct scatterlist *src, unsigned int nbytes)
+{
+	return p8_aes_xts_crypt(desc, dst, src, nbytes, 1);
+}
+
+static int p8_aes_xts_decrypt(struct blkcipher_desc *desc,
+			      struct scatterlist *dst,
+			      struct scatterlist *src, unsigned int nbytes)
+{
+	return p8_aes_xts_crypt(desc, dst, src, nbytes, 0);
+}
+
+struct crypto_alg p8_aes_xts_alg = {
+	.cra_name = "xts(aes)",
+	.cra_driver_name = "p8_aes_xts",
+	.cra_module = THIS_MODULE,
+	.cra_priority = 2000,
+	.cra_type = &crypto_blkcipher_type,
+	.cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER | CRYPTO_ALG_NEED_FALLBACK,
+	.cra_alignmask = 0,
+	.cra_blocksize = AES_BLOCK_SIZE,
+	.cra_ctxsize = sizeof(struct p8_aes_xts_ctx),
+	.cra_init = p8_aes_xts_init,
+	.cra_exit = p8_aes_xts_exit,
+	.cra_blkcipher = {
+			.ivsize = AES_BLOCK_SIZE,
+			.min_keysize = 2 * AES_MIN_KEY_SIZE,
+			.max_keysize = 2 * AES_MAX_KEY_SIZE,
+			.setkey	 = p8_aes_xts_setkey,
+			.encrypt = p8_aes_xts_encrypt,
+			.decrypt = p8_aes_xts_decrypt,
+	}
+};
--- zfcpdump-kernel-4.4.orig/drivers/crypto/vmx/aesp8-ppc.h
+++ zfcpdump-kernel-4.4/drivers/crypto/vmx/aesp8-ppc.h
@@ -19,3 +19,7 @@ void aes_p8_cbc_encrypt(const u8 *in, u8
 void aes_p8_ctr32_encrypt_blocks(const u8 *in, u8 *out,
 				 size_t len, const struct aes_key *key,
 				 const u8 *iv);
+void aes_p8_xts_encrypt(const u8 *in, u8 *out, size_t len,
+			const struct aes_key *key1, const struct aes_key *key2, u8 *iv);
+void aes_p8_xts_decrypt(const u8 *in, u8 *out, size_t len,
+			const struct aes_key *key1, const struct aes_key *key2, u8 *iv);
--- zfcpdump-kernel-4.4.orig/drivers/crypto/vmx/aesp8-ppc.pl
+++ zfcpdump-kernel-4.4/drivers/crypto/vmx/aesp8-ppc.pl
@@ -1,4 +1,11 @@
-#!/usr/bin/env perl
+#! /usr/bin/env perl
+# Copyright 2014-2016 The OpenSSL Project Authors. All Rights Reserved.
+#
+# Licensed under the OpenSSL license (the "License").  You may not use
+# this file except in compliance with the License.  You can obtain a copy
+# in the file LICENSE in the source distribution or at
+# https://www.openssl.org/source/license.html
+
 #
 # ====================================================================
 # Written by Andy Polyakov <appro@openssl.org> for the OpenSSL
@@ -20,6 +27,19 @@
 # instructions are interleaved. It's reckoned that eventual
 # misalignment penalties at page boundaries are in average lower
 # than additional overhead in pure AltiVec approach.
+#
+# May 2016
+#
+# Add XTS subroutine, 9x on little- and 12x improvement on big-endian
+# systems were measured.
+#
+######################################################################
+# Current large-block performance in cycles per byte processed with
+# 128-bit key (less is better).
+#
+#		CBC en-/decrypt	CTR	XTS
+# POWER8[le]	3.96/0.72	0.74	1.1
+# POWER8[be]	3.75/0.65	0.66	1.0
 
 $flavour = shift;
 
@@ -1875,6 +1895,1845 @@ Lctr32_enc8x_done:
 ___
 }}	}}}
 
+#########################################################################
+{{{	# XTS procedures						#
+# int aes_p8_xts_[en|de]crypt(const char *inp, char *out, size_t len,	#
+#                             const AES_KEY *key1, const AES_KEY *key2,	#
+#                             [const] unsigned char iv[16]);		#
+# If $key2 is NULL, then a "tweak chaining" mode is engaged, in which	#
+# input tweak value is assumed to be encrypted already, and last tweak	#
+# value, one suitable for consecutive call on same chunk of data, is	#
+# written back to original buffer. In addition, in "tweak chaining"	#
+# mode only complete input blocks are processed.			#
+
+my ($inp,$out,$len,$key1,$key2,$ivp,$rounds,$idx) =	map("r$_",(3..10));
+my ($rndkey0,$rndkey1,$inout) =				map("v$_",(0..2));
+my ($output,$inptail,$inpperm,$leperm,$keyperm) =	map("v$_",(3..7));
+my ($tweak,$seven,$eighty7,$tmp,$tweak1) =		map("v$_",(8..12));
+my $taillen = $key2;
+
+   ($inp,$idx) = ($idx,$inp);				# reassign
+
+$code.=<<___;
+.globl	.${prefix}_xts_encrypt
+	mr		$inp,r3				# reassign
+	li		r3,-1
+	${UCMP}i	$len,16
+	bltlr-
+
+	lis		r0,0xfff0
+	mfspr		r12,256				# save vrsave
+	li		r11,0
+	mtspr		256,r0
+
+	vspltisb	$seven,0x07			# 0x070707..07
+	le?lvsl		$leperm,r11,r11
+	le?vspltisb	$tmp,0x0f
+	le?vxor		$leperm,$leperm,$seven
+
+	li		$idx,15
+	lvx		$tweak,0,$ivp			# load [unaligned] iv
+	lvsl		$inpperm,0,$ivp
+	lvx		$inptail,$idx,$ivp
+	le?vxor		$inpperm,$inpperm,$tmp
+	vperm		$tweak,$tweak,$inptail,$inpperm
+
+	neg		r11,$inp
+	lvsr		$inpperm,0,r11			# prepare for unaligned load
+	lvx		$inout,0,$inp
+	addi		$inp,$inp,15			# 15 is not typo
+	le?vxor		$inpperm,$inpperm,$tmp
+
+	${UCMP}i	$key2,0				# key2==NULL?
+	beq		Lxts_enc_no_key2
+
+	?lvsl		$keyperm,0,$key2		# prepare for unaligned key
+	lwz		$rounds,240($key2)
+	srwi		$rounds,$rounds,1
+	subi		$rounds,$rounds,1
+	li		$idx,16
+
+	lvx		$rndkey0,0,$key2
+	lvx		$rndkey1,$idx,$key2
+	addi		$idx,$idx,16
+	?vperm		$rndkey0,$rndkey0,$rndkey1,$keyperm
+	vxor		$tweak,$tweak,$rndkey0
+	lvx		$rndkey0,$idx,$key2
+	addi		$idx,$idx,16
+	mtctr		$rounds
+
+Ltweak_xts_enc:
+	?vperm		$rndkey1,$rndkey1,$rndkey0,$keyperm
+	vcipher		$tweak,$tweak,$rndkey1
+	lvx		$rndkey1,$idx,$key2
+	addi		$idx,$idx,16
+	?vperm		$rndkey0,$rndkey0,$rndkey1,$keyperm
+	vcipher		$tweak,$tweak,$rndkey0
+	lvx		$rndkey0,$idx,$key2
+	addi		$idx,$idx,16
+	bdnz		Ltweak_xts_enc
+
+	?vperm		$rndkey1,$rndkey1,$rndkey0,$keyperm
+	vcipher		$tweak,$tweak,$rndkey1
+	lvx		$rndkey1,$idx,$key2
+	?vperm		$rndkey0,$rndkey0,$rndkey1,$keyperm
+	vcipherlast	$tweak,$tweak,$rndkey0
+
+	li		$ivp,0				# don't chain the tweak
+	b		Lxts_enc
+
+Lxts_enc_no_key2:
+	li		$idx,-16
+	and		$len,$len,$idx			# in "tweak chaining"
+							# mode only complete
+							# blocks are processed
+Lxts_enc:
+	lvx		$inptail,0,$inp
+	addi		$inp,$inp,16
+
+	?lvsl		$keyperm,0,$key1		# prepare for unaligned key
+	lwz		$rounds,240($key1)
+	srwi		$rounds,$rounds,1
+	subi		$rounds,$rounds,1
+	li		$idx,16
+
+	vslb		$eighty7,$seven,$seven		# 0x808080..80
+	vor		$eighty7,$eighty7,$seven	# 0x878787..87
+	vspltisb	$tmp,1				# 0x010101..01
+	vsldoi		$eighty7,$eighty7,$tmp,15	# 0x870101..01
+
+	${UCMP}i	$len,96
+	bge		_aesp8_xts_encrypt6x
+
+	andi.		$taillen,$len,15
+	subic		r0,$len,32
+	subi		$taillen,$taillen,16
+	subfe		r0,r0,r0
+	and		r0,r0,$taillen
+	add		$inp,$inp,r0
+
+	lvx		$rndkey0,0,$key1
+	lvx		$rndkey1,$idx,$key1
+	addi		$idx,$idx,16
+	vperm		$inout,$inout,$inptail,$inpperm
+	?vperm		$rndkey0,$rndkey0,$rndkey1,$keyperm
+	vxor		$inout,$inout,$tweak
+	vxor		$inout,$inout,$rndkey0
+	lvx		$rndkey0,$idx,$key1
+	addi		$idx,$idx,16
+	mtctr		$rounds
+	b		Loop_xts_enc
+
+.align	5
+Loop_xts_enc:
+	?vperm		$rndkey1,$rndkey1,$rndkey0,$keyperm
+	vcipher		$inout,$inout,$rndkey1
+	lvx		$rndkey1,$idx,$key1
+	addi		$idx,$idx,16
+	?vperm		$rndkey0,$rndkey0,$rndkey1,$keyperm
+	vcipher		$inout,$inout,$rndkey0
+	lvx		$rndkey0,$idx,$key1
+	addi		$idx,$idx,16
+	bdnz		Loop_xts_enc
+
+	?vperm		$rndkey1,$rndkey1,$rndkey0,$keyperm
+	vcipher		$inout,$inout,$rndkey1
+	lvx		$rndkey1,$idx,$key1
+	li		$idx,16
+	?vperm		$rndkey0,$rndkey0,$rndkey1,$keyperm
+	vxor		$rndkey0,$rndkey0,$tweak
+	vcipherlast	$output,$inout,$rndkey0
+
+	le?vperm	$tmp,$output,$output,$leperm
+	be?nop
+	le?stvx_u	$tmp,0,$out
+	be?stvx_u	$output,0,$out
+	addi		$out,$out,16
+
+	subic.		$len,$len,16
+	beq		Lxts_enc_done
+
+	vmr		$inout,$inptail
+	lvx		$inptail,0,$inp
+	addi		$inp,$inp,16
+	lvx		$rndkey0,0,$key1
+	lvx		$rndkey1,$idx,$key1
+	addi		$idx,$idx,16
+
+	subic		r0,$len,32
+	subfe		r0,r0,r0
+	and		r0,r0,$taillen
+	add		$inp,$inp,r0
+
+	vsrab		$tmp,$tweak,$seven		# next tweak value
+	vaddubm		$tweak,$tweak,$tweak
+	vsldoi		$tmp,$tmp,$tmp,15
+	vand		$tmp,$tmp,$eighty7
+	vxor		$tweak,$tweak,$tmp
+
+	vperm		$inout,$inout,$inptail,$inpperm
+	?vperm		$rndkey0,$rndkey0,$rndkey1,$keyperm
+	vxor		$inout,$inout,$tweak
+	vxor		$output,$output,$rndkey0	# just in case $len<16
+	vxor		$inout,$inout,$rndkey0
+	lvx		$rndkey0,$idx,$key1
+	addi		$idx,$idx,16
+
+	mtctr		$rounds
+	${UCMP}i	$len,16
+	bge		Loop_xts_enc
+
+	vxor		$output,$output,$tweak
+	lvsr		$inpperm,0,$len			# $inpperm is no longer needed
+	vxor		$inptail,$inptail,$inptail	# $inptail is no longer needed
+	vspltisb	$tmp,-1
+	vperm		$inptail,$inptail,$tmp,$inpperm
+	vsel		$inout,$inout,$output,$inptail
+
+	subi		r11,$out,17
+	subi		$out,$out,16
+	mtctr		$len
+	li		$len,16
+Loop_xts_enc_steal:
+	lbzu		r0,1(r11)
+	stb		r0,16(r11)
+	bdnz		Loop_xts_enc_steal
+
+	mtctr		$rounds
+	b		Loop_xts_enc			# one more time...
+
+Lxts_enc_done:
+	${UCMP}i	$ivp,0
+	beq		Lxts_enc_ret
+
+	vsrab		$tmp,$tweak,$seven		# next tweak value
+	vaddubm		$tweak,$tweak,$tweak
+	vsldoi		$tmp,$tmp,$tmp,15
+	vand		$tmp,$tmp,$eighty7
+	vxor		$tweak,$tweak,$tmp
+
+	le?vperm	$tweak,$tweak,$tweak,$leperm
+	stvx_u		$tweak,0,$ivp
+
+Lxts_enc_ret:
+	mtspr		256,r12				# restore vrsave
+	li		r3,0
+	blr
+	.long		0
+	.byte		0,12,0x04,0,0x80,6,6,0
+	.long		0
+.size	.${prefix}_xts_encrypt,.-.${prefix}_xts_encrypt
+
+.globl	.${prefix}_xts_decrypt
+	mr		$inp,r3				# reassign
+	li		r3,-1
+	${UCMP}i	$len,16
+	bltlr-
+
+	lis		r0,0xfff8
+	mfspr		r12,256				# save vrsave
+	li		r11,0
+	mtspr		256,r0
+
+	andi.		r0,$len,15
+	neg		r0,r0
+	andi.		r0,r0,16
+	sub		$len,$len,r0
+
+	vspltisb	$seven,0x07			# 0x070707..07
+	le?lvsl		$leperm,r11,r11
+	le?vspltisb	$tmp,0x0f
+	le?vxor		$leperm,$leperm,$seven
+
+	li		$idx,15
+	lvx		$tweak,0,$ivp			# load [unaligned] iv
+	lvsl		$inpperm,0,$ivp
+	lvx		$inptail,$idx,$ivp
+	le?vxor		$inpperm,$inpperm,$tmp
+	vperm		$tweak,$tweak,$inptail,$inpperm
+
+	neg		r11,$inp
+	lvsr		$inpperm,0,r11			# prepare for unaligned load
+	lvx		$inout,0,$inp
+	addi		$inp,$inp,15			# 15 is not typo
+	le?vxor		$inpperm,$inpperm,$tmp
+
+	${UCMP}i	$key2,0				# key2==NULL?
+	beq		Lxts_dec_no_key2
+
+	?lvsl		$keyperm,0,$key2		# prepare for unaligned key
+	lwz		$rounds,240($key2)
+	srwi		$rounds,$rounds,1
+	subi		$rounds,$rounds,1
+	li		$idx,16
+
+	lvx		$rndkey0,0,$key2
+	lvx		$rndkey1,$idx,$key2
+	addi		$idx,$idx,16
+	?vperm		$rndkey0,$rndkey0,$rndkey1,$keyperm
+	vxor		$tweak,$tweak,$rndkey0
+	lvx		$rndkey0,$idx,$key2
+	addi		$idx,$idx,16
+	mtctr		$rounds
+
+Ltweak_xts_dec:
+	?vperm		$rndkey1,$rndkey1,$rndkey0,$keyperm
+	vcipher		$tweak,$tweak,$rndkey1
+	lvx		$rndkey1,$idx,$key2
+	addi		$idx,$idx,16
+	?vperm		$rndkey0,$rndkey0,$rndkey1,$keyperm
+	vcipher		$tweak,$tweak,$rndkey0
+	lvx		$rndkey0,$idx,$key2
+	addi		$idx,$idx,16
+	bdnz		Ltweak_xts_dec
+
+	?vperm		$rndkey1,$rndkey1,$rndkey0,$keyperm
+	vcipher		$tweak,$tweak,$rndkey1
+	lvx		$rndkey1,$idx,$key2
+	?vperm		$rndkey0,$rndkey0,$rndkey1,$keyperm
+	vcipherlast	$tweak,$tweak,$rndkey0
+
+	li		$ivp,0				# don't chain the tweak
+	b		Lxts_dec
+
+Lxts_dec_no_key2:
+	neg		$idx,$len
+	andi.		$idx,$idx,15
+	add		$len,$len,$idx			# in "tweak chaining"
+							# mode only complete
+							# blocks are processed
+Lxts_dec:
+	lvx		$inptail,0,$inp
+	addi		$inp,$inp,16
+
+	?lvsl		$keyperm,0,$key1		# prepare for unaligned key
+	lwz		$rounds,240($key1)
+	srwi		$rounds,$rounds,1
+	subi		$rounds,$rounds,1
+	li		$idx,16
+
+	vslb		$eighty7,$seven,$seven		# 0x808080..80
+	vor		$eighty7,$eighty7,$seven	# 0x878787..87
+	vspltisb	$tmp,1				# 0x010101..01
+	vsldoi		$eighty7,$eighty7,$tmp,15	# 0x870101..01
+
+	${UCMP}i	$len,96
+	bge		_aesp8_xts_decrypt6x
+
+	lvx		$rndkey0,0,$key1
+	lvx		$rndkey1,$idx,$key1
+	addi		$idx,$idx,16
+	vperm		$inout,$inout,$inptail,$inpperm
+	?vperm		$rndkey0,$rndkey0,$rndkey1,$keyperm
+	vxor		$inout,$inout,$tweak
+	vxor		$inout,$inout,$rndkey0
+	lvx		$rndkey0,$idx,$key1
+	addi		$idx,$idx,16
+	mtctr		$rounds
+
+	${UCMP}i	$len,16
+	blt		Ltail_xts_dec
+	be?b		Loop_xts_dec
+
+.align	5
+Loop_xts_dec:
+	?vperm		$rndkey1,$rndkey1,$rndkey0,$keyperm
+	vncipher	$inout,$inout,$rndkey1
+	lvx		$rndkey1,$idx,$key1
+	addi		$idx,$idx,16
+	?vperm		$rndkey0,$rndkey0,$rndkey1,$keyperm
+	vncipher	$inout,$inout,$rndkey0
+	lvx		$rndkey0,$idx,$key1
+	addi		$idx,$idx,16
+	bdnz		Loop_xts_dec
+
+	?vperm		$rndkey1,$rndkey1,$rndkey0,$keyperm
+	vncipher	$inout,$inout,$rndkey1
+	lvx		$rndkey1,$idx,$key1
+	li		$idx,16
+	?vperm		$rndkey0,$rndkey0,$rndkey1,$keyperm
+	vxor		$rndkey0,$rndkey0,$tweak
+	vncipherlast	$output,$inout,$rndkey0
+
+	le?vperm	$tmp,$output,$output,$leperm
+	be?nop
+	le?stvx_u	$tmp,0,$out
+	be?stvx_u	$output,0,$out
+	addi		$out,$out,16
+
+	subic.		$len,$len,16
+	beq		Lxts_dec_done
+
+	vmr		$inout,$inptail
+	lvx		$inptail,0,$inp
+	addi		$inp,$inp,16
+	lvx		$rndkey0,0,$key1
+	lvx		$rndkey1,$idx,$key1
+	addi		$idx,$idx,16
+
+	vsrab		$tmp,$tweak,$seven		# next tweak value
+	vaddubm		$tweak,$tweak,$tweak
+	vsldoi		$tmp,$tmp,$tmp,15
+	vand		$tmp,$tmp,$eighty7
+	vxor		$tweak,$tweak,$tmp
+
+	vperm		$inout,$inout,$inptail,$inpperm
+	?vperm		$rndkey0,$rndkey0,$rndkey1,$keyperm
+	vxor		$inout,$inout,$tweak
+	vxor		$inout,$inout,$rndkey0
+	lvx		$rndkey0,$idx,$key1
+	addi		$idx,$idx,16
+
+	mtctr		$rounds
+	${UCMP}i	$len,16
+	bge		Loop_xts_dec
+
+Ltail_xts_dec:
+	vsrab		$tmp,$tweak,$seven		# next tweak value
+	vaddubm		$tweak1,$tweak,$tweak
+	vsldoi		$tmp,$tmp,$tmp,15
+	vand		$tmp,$tmp,$eighty7
+	vxor		$tweak1,$tweak1,$tmp
+
+	subi		$inp,$inp,16
+	add		$inp,$inp,$len
+
+	vxor		$inout,$inout,$tweak		# :-(
+	vxor		$inout,$inout,$tweak1		# :-)
+
+Loop_xts_dec_short:
+	?vperm		$rndkey1,$rndkey1,$rndkey0,$keyperm
+	vncipher	$inout,$inout,$rndkey1
+	lvx		$rndkey1,$idx,$key1
+	addi		$idx,$idx,16
+	?vperm		$rndkey0,$rndkey0,$rndkey1,$keyperm
+	vncipher	$inout,$inout,$rndkey0
+	lvx		$rndkey0,$idx,$key1
+	addi		$idx,$idx,16
+	bdnz		Loop_xts_dec_short
+
+	?vperm		$rndkey1,$rndkey1,$rndkey0,$keyperm
+	vncipher	$inout,$inout,$rndkey1
+	lvx		$rndkey1,$idx,$key1
+	li		$idx,16
+	?vperm		$rndkey0,$rndkey0,$rndkey1,$keyperm
+	vxor		$rndkey0,$rndkey0,$tweak1
+	vncipherlast	$output,$inout,$rndkey0
+
+	le?vperm	$tmp,$output,$output,$leperm
+	be?nop
+	le?stvx_u	$tmp,0,$out
+	be?stvx_u	$output,0,$out
+
+	vmr		$inout,$inptail
+	lvx		$inptail,0,$inp
+	#addi		$inp,$inp,16
+	lvx		$rndkey0,0,$key1
+	lvx		$rndkey1,$idx,$key1
+	addi		$idx,$idx,16
+	vperm		$inout,$inout,$inptail,$inpperm
+	?vperm		$rndkey0,$rndkey0,$rndkey1,$keyperm
+
+	lvsr		$inpperm,0,$len			# $inpperm is no longer needed
+	vxor		$inptail,$inptail,$inptail	# $inptail is no longer needed
+	vspltisb	$tmp,-1
+	vperm		$inptail,$inptail,$tmp,$inpperm
+	vsel		$inout,$inout,$output,$inptail
+
+	vxor		$rndkey0,$rndkey0,$tweak
+	vxor		$inout,$inout,$rndkey0
+	lvx		$rndkey0,$idx,$key1
+	addi		$idx,$idx,16
+
+	subi		r11,$out,1
+	mtctr		$len
+	li		$len,16
+Loop_xts_dec_steal:
+	lbzu		r0,1(r11)
+	stb		r0,16(r11)
+	bdnz		Loop_xts_dec_steal
+
+	mtctr		$rounds
+	b		Loop_xts_dec			# one more time...
+
+Lxts_dec_done:
+	${UCMP}i	$ivp,0
+	beq		Lxts_dec_ret
+
+	vsrab		$tmp,$tweak,$seven		# next tweak value
+	vaddubm		$tweak,$tweak,$tweak
+	vsldoi		$tmp,$tmp,$tmp,15
+	vand		$tmp,$tmp,$eighty7
+	vxor		$tweak,$tweak,$tmp
+
+	le?vperm	$tweak,$tweak,$tweak,$leperm
+	stvx_u		$tweak,0,$ivp
+
+Lxts_dec_ret:
+	mtspr		256,r12				# restore vrsave
+	li		r3,0
+	blr
+	.long		0
+	.byte		0,12,0x04,0,0x80,6,6,0
+	.long		0
+.size	.${prefix}_xts_decrypt,.-.${prefix}_xts_decrypt
+___
+#########################################################################
+{{	# Optimized XTS procedures					#
+my $key_=$key2;
+my ($x00,$x10,$x20,$x30,$x40,$x50,$x60,$x70)=map("r$_",(0,3,26..31));
+    $x00=0 if ($flavour =~ /osx/);
+my ($in0,  $in1,  $in2,  $in3,  $in4,  $in5 )=map("v$_",(0..5));
+my ($out0, $out1, $out2, $out3, $out4, $out5)=map("v$_",(7,12..16));
+my ($twk0, $twk1, $twk2, $twk3, $twk4, $twk5)=map("v$_",(17..22));
+my $rndkey0="v23";	# v24-v25 rotating buffer for first found keys
+			# v26-v31 last 6 round keys
+my ($keyperm)=($out0);	# aliases with "caller", redundant assignment
+my $taillen=$x70;
+
+$code.=<<___;
+.align	5
+_aesp8_xts_encrypt6x:
+	$STU		$sp,-`($FRAME+21*16+6*$SIZE_T)`($sp)
+	mflr		r11
+	li		r7,`$FRAME+8*16+15`
+	li		r3,`$FRAME+8*16+31`
+	$PUSH		r11,`$FRAME+21*16+6*$SIZE_T+$LRSAVE`($sp)
+	stvx		v20,r7,$sp		# ABI says so
+	addi		r7,r7,32
+	stvx		v21,r3,$sp
+	addi		r3,r3,32
+	stvx		v22,r7,$sp
+	addi		r7,r7,32
+	stvx		v23,r3,$sp
+	addi		r3,r3,32
+	stvx		v24,r7,$sp
+	addi		r7,r7,32
+	stvx		v25,r3,$sp
+	addi		r3,r3,32
+	stvx		v26,r7,$sp
+	addi		r7,r7,32
+	stvx		v27,r3,$sp
+	addi		r3,r3,32
+	stvx		v28,r7,$sp
+	addi		r7,r7,32
+	stvx		v29,r3,$sp
+	addi		r3,r3,32
+	stvx		v30,r7,$sp
+	stvx		v31,r3,$sp
+	li		r0,-1
+	stw		$vrsave,`$FRAME+21*16-4`($sp)	# save vrsave
+	li		$x10,0x10
+	$PUSH		r26,`$FRAME+21*16+0*$SIZE_T`($sp)
+	li		$x20,0x20
+	$PUSH		r27,`$FRAME+21*16+1*$SIZE_T`($sp)
+	li		$x30,0x30
+	$PUSH		r28,`$FRAME+21*16+2*$SIZE_T`($sp)
+	li		$x40,0x40
+	$PUSH		r29,`$FRAME+21*16+3*$SIZE_T`($sp)
+	li		$x50,0x50
+	$PUSH		r30,`$FRAME+21*16+4*$SIZE_T`($sp)
+	li		$x60,0x60
+	$PUSH		r31,`$FRAME+21*16+5*$SIZE_T`($sp)
+	li		$x70,0x70
+	mtspr		256,r0
+
+	subi		$rounds,$rounds,3	# -4 in total
+
+	lvx		$rndkey0,$x00,$key1	# load key schedule
+	lvx		v30,$x10,$key1
+	addi		$key1,$key1,0x20
+	lvx		v31,$x00,$key1
+	?vperm		$rndkey0,$rndkey0,v30,$keyperm
+	addi		$key_,$sp,$FRAME+15
+	mtctr		$rounds
+
+Load_xts_enc_key:
+	?vperm		v24,v30,v31,$keyperm
+	lvx		v30,$x10,$key1
+	addi		$key1,$key1,0x20
+	stvx		v24,$x00,$key_		# off-load round[1]
+	?vperm		v25,v31,v30,$keyperm
+	lvx		v31,$x00,$key1
+	stvx		v25,$x10,$key_		# off-load round[2]
+	addi		$key_,$key_,0x20
+	bdnz		Load_xts_enc_key
+
+	lvx		v26,$x10,$key1
+	?vperm		v24,v30,v31,$keyperm
+	lvx		v27,$x20,$key1
+	stvx		v24,$x00,$key_		# off-load round[3]
+	?vperm		v25,v31,v26,$keyperm
+	lvx		v28,$x30,$key1
+	stvx		v25,$x10,$key_		# off-load round[4]
+	addi		$key_,$sp,$FRAME+15	# rewind $key_
+	?vperm		v26,v26,v27,$keyperm
+	lvx		v29,$x40,$key1
+	?vperm		v27,v27,v28,$keyperm
+	lvx		v30,$x50,$key1
+	?vperm		v28,v28,v29,$keyperm
+	lvx		v31,$x60,$key1
+	?vperm		v29,v29,v30,$keyperm
+	lvx		$twk5,$x70,$key1	# borrow $twk5
+	?vperm		v30,v30,v31,$keyperm
+	lvx		v24,$x00,$key_		# pre-load round[1]
+	?vperm		v31,v31,$twk5,$keyperm
+	lvx		v25,$x10,$key_		# pre-load round[2]
+
+	 vperm		$in0,$inout,$inptail,$inpperm
+	 subi		$inp,$inp,31		# undo "caller"
+	vxor		$twk0,$tweak,$rndkey0
+	vsrab		$tmp,$tweak,$seven	# next tweak value
+	vaddubm		$tweak,$tweak,$tweak
+	vsldoi		$tmp,$tmp,$tmp,15
+	vand		$tmp,$tmp,$eighty7
+	 vxor		$out0,$in0,$twk0
+	vxor		$tweak,$tweak,$tmp
+
+	 lvx_u		$in1,$x10,$inp
+	vxor		$twk1,$tweak,$rndkey0
+	vsrab		$tmp,$tweak,$seven	# next tweak value
+	vaddubm		$tweak,$tweak,$tweak
+	vsldoi		$tmp,$tmp,$tmp,15
+	 le?vperm	$in1,$in1,$in1,$leperm
+	vand		$tmp,$tmp,$eighty7
+	 vxor		$out1,$in1,$twk1
+	vxor		$tweak,$tweak,$tmp
+
+	 lvx_u		$in2,$x20,$inp
+	 andi.		$taillen,$len,15
+	vxor		$twk2,$tweak,$rndkey0
+	vsrab		$tmp,$tweak,$seven	# next tweak value
+	vaddubm		$tweak,$tweak,$tweak
+	vsldoi		$tmp,$tmp,$tmp,15
+	 le?vperm	$in2,$in2,$in2,$leperm
+	vand		$tmp,$tmp,$eighty7
+	 vxor		$out2,$in2,$twk2
+	vxor		$tweak,$tweak,$tmp
+
+	 lvx_u		$in3,$x30,$inp
+	 sub		$len,$len,$taillen
+	vxor		$twk3,$tweak,$rndkey0
+	vsrab		$tmp,$tweak,$seven	# next tweak value
+	vaddubm		$tweak,$tweak,$tweak
+	vsldoi		$tmp,$tmp,$tmp,15
+	 le?vperm	$in3,$in3,$in3,$leperm
+	vand		$tmp,$tmp,$eighty7
+	 vxor		$out3,$in3,$twk3
+	vxor		$tweak,$tweak,$tmp
+
+	 lvx_u		$in4,$x40,$inp
+	 subi		$len,$len,0x60
+	vxor		$twk4,$tweak,$rndkey0
+	vsrab		$tmp,$tweak,$seven	# next tweak value
+	vaddubm		$tweak,$tweak,$tweak
+	vsldoi		$tmp,$tmp,$tmp,15
+	 le?vperm	$in4,$in4,$in4,$leperm
+	vand		$tmp,$tmp,$eighty7
+	 vxor		$out4,$in4,$twk4
+	vxor		$tweak,$tweak,$tmp
+
+	 lvx_u		$in5,$x50,$inp
+	 addi		$inp,$inp,0x60
+	vxor		$twk5,$tweak,$rndkey0
+	vsrab		$tmp,$tweak,$seven	# next tweak value
+	vaddubm		$tweak,$tweak,$tweak
+	vsldoi		$tmp,$tmp,$tmp,15
+	 le?vperm	$in5,$in5,$in5,$leperm
+	vand		$tmp,$tmp,$eighty7
+	 vxor		$out5,$in5,$twk5
+	vxor		$tweak,$tweak,$tmp
+
+	vxor		v31,v31,$rndkey0
+	mtctr		$rounds
+	b		Loop_xts_enc6x
+
+.align	5
+Loop_xts_enc6x:
+	vcipher		$out0,$out0,v24
+	vcipher		$out1,$out1,v24
+	vcipher		$out2,$out2,v24
+	vcipher		$out3,$out3,v24
+	vcipher		$out4,$out4,v24
+	vcipher		$out5,$out5,v24
+	lvx		v24,$x20,$key_		# round[3]
+	addi		$key_,$key_,0x20
+
+	vcipher		$out0,$out0,v25
+	vcipher		$out1,$out1,v25
+	vcipher		$out2,$out2,v25
+	vcipher		$out3,$out3,v25
+	vcipher		$out4,$out4,v25
+	vcipher		$out5,$out5,v25
+	lvx		v25,$x10,$key_		# round[4]
+	bdnz		Loop_xts_enc6x
+
+	subic		$len,$len,96		# $len-=96
+	 vxor		$in0,$twk0,v31		# xor with last round key
+	vcipher		$out0,$out0,v24
+	vcipher		$out1,$out1,v24
+	 vsrab		$tmp,$tweak,$seven	# next tweak value
+	 vxor		$twk0,$tweak,$rndkey0
+	 vaddubm	$tweak,$tweak,$tweak
+	vcipher		$out2,$out2,v24
+	vcipher		$out3,$out3,v24
+	 vsldoi		$tmp,$tmp,$tmp,15
+	vcipher		$out4,$out4,v24
+	vcipher		$out5,$out5,v24
+
+	subfe.		r0,r0,r0		# borrow?-1:0
+	 vand		$tmp,$tmp,$eighty7
+	vcipher		$out0,$out0,v25
+	vcipher		$out1,$out1,v25
+	 vxor		$tweak,$tweak,$tmp
+	vcipher		$out2,$out2,v25
+	vcipher		$out3,$out3,v25
+	 vxor		$in1,$twk1,v31
+	 vsrab		$tmp,$tweak,$seven	# next tweak value
+	 vxor		$twk1,$tweak,$rndkey0
+	vcipher		$out4,$out4,v25
+	vcipher		$out5,$out5,v25
+
+	and		r0,r0,$len
+	 vaddubm	$tweak,$tweak,$tweak
+	 vsldoi		$tmp,$tmp,$tmp,15
+	vcipher		$out0,$out0,v26
+	vcipher		$out1,$out1,v26
+	 vand		$tmp,$tmp,$eighty7
+	vcipher		$out2,$out2,v26
+	vcipher		$out3,$out3,v26
+	 vxor		$tweak,$tweak,$tmp
+	vcipher		$out4,$out4,v26
+	vcipher		$out5,$out5,v26
+
+	add		$inp,$inp,r0		# $inp is adjusted in such
+						# way that at exit from the
+						# loop inX-in5 are loaded
+						# with last "words"
+	 vxor		$in2,$twk2,v31
+	 vsrab		$tmp,$tweak,$seven	# next tweak value
+	 vxor		$twk2,$tweak,$rndkey0
+	 vaddubm	$tweak,$tweak,$tweak
+	vcipher		$out0,$out0,v27
+	vcipher		$out1,$out1,v27
+	 vsldoi		$tmp,$tmp,$tmp,15
+	vcipher		$out2,$out2,v27
+	vcipher		$out3,$out3,v27
+	 vand		$tmp,$tmp,$eighty7
+	vcipher		$out4,$out4,v27
+	vcipher		$out5,$out5,v27
+
+	addi		$key_,$sp,$FRAME+15	# rewind $key_
+	 vxor		$tweak,$tweak,$tmp
+	vcipher		$out0,$out0,v28
+	vcipher		$out1,$out1,v28
+	 vxor		$in3,$twk3,v31
+	 vsrab		$tmp,$tweak,$seven	# next tweak value
+	 vxor		$twk3,$tweak,$rndkey0
+	vcipher		$out2,$out2,v28
+	vcipher		$out3,$out3,v28
+	 vaddubm	$tweak,$tweak,$tweak
+	 vsldoi		$tmp,$tmp,$tmp,15
+	vcipher		$out4,$out4,v28
+	vcipher		$out5,$out5,v28
+	lvx		v24,$x00,$key_		# re-pre-load round[1]
+	 vand		$tmp,$tmp,$eighty7
+
+	vcipher		$out0,$out0,v29
+	vcipher		$out1,$out1,v29
+	 vxor		$tweak,$tweak,$tmp
+	vcipher		$out2,$out2,v29
+	vcipher		$out3,$out3,v29
+	 vxor		$in4,$twk4,v31
+	 vsrab		$tmp,$tweak,$seven	# next tweak value
+	 vxor		$twk4,$tweak,$rndkey0
+	vcipher		$out4,$out4,v29
+	vcipher		$out5,$out5,v29
+	lvx		v25,$x10,$key_		# re-pre-load round[2]
+	 vaddubm	$tweak,$tweak,$tweak
+	 vsldoi		$tmp,$tmp,$tmp,15
+
+	vcipher		$out0,$out0,v30
+	vcipher		$out1,$out1,v30
+	 vand		$tmp,$tmp,$eighty7
+	vcipher		$out2,$out2,v30
+	vcipher		$out3,$out3,v30
+	 vxor		$tweak,$tweak,$tmp
+	vcipher		$out4,$out4,v30
+	vcipher		$out5,$out5,v30
+	 vxor		$in5,$twk5,v31
+	 vsrab		$tmp,$tweak,$seven	# next tweak value
+	 vxor		$twk5,$tweak,$rndkey0
+
+	vcipherlast	$out0,$out0,$in0
+	 lvx_u		$in0,$x00,$inp		# load next input block
+	 vaddubm	$tweak,$tweak,$tweak
+	 vsldoi		$tmp,$tmp,$tmp,15
+	vcipherlast	$out1,$out1,$in1
+	 lvx_u		$in1,$x10,$inp
+	vcipherlast	$out2,$out2,$in2
+	 le?vperm	$in0,$in0,$in0,$leperm
+	 lvx_u		$in2,$x20,$inp
+	 vand		$tmp,$tmp,$eighty7
+	vcipherlast	$out3,$out3,$in3
+	 le?vperm	$in1,$in1,$in1,$leperm
+	 lvx_u		$in3,$x30,$inp
+	vcipherlast	$out4,$out4,$in4
+	 le?vperm	$in2,$in2,$in2,$leperm
+	 lvx_u		$in4,$x40,$inp
+	 vxor		$tweak,$tweak,$tmp
+	vcipherlast	$tmp,$out5,$in5		# last block might be needed
+						# in stealing mode
+	 le?vperm	$in3,$in3,$in3,$leperm
+	 lvx_u		$in5,$x50,$inp
+	 addi		$inp,$inp,0x60
+	 le?vperm	$in4,$in4,$in4,$leperm
+	 le?vperm	$in5,$in5,$in5,$leperm
+
+	le?vperm	$out0,$out0,$out0,$leperm
+	le?vperm	$out1,$out1,$out1,$leperm
+	stvx_u		$out0,$x00,$out		# store output
+	 vxor		$out0,$in0,$twk0
+	le?vperm	$out2,$out2,$out2,$leperm
+	stvx_u		$out1,$x10,$out
+	 vxor		$out1,$in1,$twk1
+	le?vperm	$out3,$out3,$out3,$leperm
+	stvx_u		$out2,$x20,$out
+	 vxor		$out2,$in2,$twk2
+	le?vperm	$out4,$out4,$out4,$leperm
+	stvx_u		$out3,$x30,$out
+	 vxor		$out3,$in3,$twk3
+	le?vperm	$out5,$tmp,$tmp,$leperm
+	stvx_u		$out4,$x40,$out
+	 vxor		$out4,$in4,$twk4
+	le?stvx_u	$out5,$x50,$out
+	be?stvx_u	$tmp, $x50,$out
+	 vxor		$out5,$in5,$twk5
+	addi		$out,$out,0x60
+
+	mtctr		$rounds
+	beq		Loop_xts_enc6x		# did $len-=96 borrow?
+
+	addic.		$len,$len,0x60
+	beq		Lxts_enc6x_zero
+	cmpwi		$len,0x20
+	blt		Lxts_enc6x_one
+	nop
+	beq		Lxts_enc6x_two
+	cmpwi		$len,0x40
+	blt		Lxts_enc6x_three
+	nop
+	beq		Lxts_enc6x_four
+
+Lxts_enc6x_five:
+	vxor		$out0,$in1,$twk0
+	vxor		$out1,$in2,$twk1
+	vxor		$out2,$in3,$twk2
+	vxor		$out3,$in4,$twk3
+	vxor		$out4,$in5,$twk4
+
+	bl		_aesp8_xts_enc5x
+
+	le?vperm	$out0,$out0,$out0,$leperm
+	vmr		$twk0,$twk5		# unused tweak
+	le?vperm	$out1,$out1,$out1,$leperm
+	stvx_u		$out0,$x00,$out		# store output
+	le?vperm	$out2,$out2,$out2,$leperm
+	stvx_u		$out1,$x10,$out
+	le?vperm	$out3,$out3,$out3,$leperm
+	stvx_u		$out2,$x20,$out
+	vxor		$tmp,$out4,$twk5	# last block prep for stealing
+	le?vperm	$out4,$out4,$out4,$leperm
+	stvx_u		$out3,$x30,$out
+	stvx_u		$out4,$x40,$out
+	addi		$out,$out,0x50
+	bne		Lxts_enc6x_steal
+	b		Lxts_enc6x_done
+
+.align	4
+Lxts_enc6x_four:
+	vxor		$out0,$in2,$twk0
+	vxor		$out1,$in3,$twk1
+	vxor		$out2,$in4,$twk2
+	vxor		$out3,$in5,$twk3
+	vxor		$out4,$out4,$out4
+
+	bl		_aesp8_xts_enc5x
+
+	le?vperm	$out0,$out0,$out0,$leperm
+	vmr		$twk0,$twk4		# unused tweak
+	le?vperm	$out1,$out1,$out1,$leperm
+	stvx_u		$out0,$x00,$out		# store output
+	le?vperm	$out2,$out2,$out2,$leperm
+	stvx_u		$out1,$x10,$out
+	vxor		$tmp,$out3,$twk4	# last block prep for stealing
+	le?vperm	$out3,$out3,$out3,$leperm
+	stvx_u		$out2,$x20,$out
+	stvx_u		$out3,$x30,$out
+	addi		$out,$out,0x40
+	bne		Lxts_enc6x_steal
+	b		Lxts_enc6x_done
+
+.align	4
+Lxts_enc6x_three:
+	vxor		$out0,$in3,$twk0
+	vxor		$out1,$in4,$twk1
+	vxor		$out2,$in5,$twk2
+	vxor		$out3,$out3,$out3
+	vxor		$out4,$out4,$out4
+
+	bl		_aesp8_xts_enc5x
+
+	le?vperm	$out0,$out0,$out0,$leperm
+	vmr		$twk0,$twk3		# unused tweak
+	le?vperm	$out1,$out1,$out1,$leperm
+	stvx_u		$out0,$x00,$out		# store output
+	vxor		$tmp,$out2,$twk3	# last block prep for stealing
+	le?vperm	$out2,$out2,$out2,$leperm
+	stvx_u		$out1,$x10,$out
+	stvx_u		$out2,$x20,$out
+	addi		$out,$out,0x30
+	bne		Lxts_enc6x_steal
+	b		Lxts_enc6x_done
+
+.align	4
+Lxts_enc6x_two:
+	vxor		$out0,$in4,$twk0
+	vxor		$out1,$in5,$twk1
+	vxor		$out2,$out2,$out2
+	vxor		$out3,$out3,$out3
+	vxor		$out4,$out4,$out4
+
+	bl		_aesp8_xts_enc5x
+
+	le?vperm	$out0,$out0,$out0,$leperm
+	vmr		$twk0,$twk2		# unused tweak
+	vxor		$tmp,$out1,$twk2	# last block prep for stealing
+	le?vperm	$out1,$out1,$out1,$leperm
+	stvx_u		$out0,$x00,$out		# store output
+	stvx_u		$out1,$x10,$out
+	addi		$out,$out,0x20
+	bne		Lxts_enc6x_steal
+	b		Lxts_enc6x_done
+
+.align	4
+Lxts_enc6x_one:
+	vxor		$out0,$in5,$twk0
+	nop
+Loop_xts_enc1x:
+	vcipher		$out0,$out0,v24
+	lvx		v24,$x20,$key_		# round[3]
+	addi		$key_,$key_,0x20
+
+	vcipher		$out0,$out0,v25
+	lvx		v25,$x10,$key_		# round[4]
+	bdnz		Loop_xts_enc1x
+
+	add		$inp,$inp,$taillen
+	cmpwi		$taillen,0
+	vcipher		$out0,$out0,v24
+
+	subi		$inp,$inp,16
+	vcipher		$out0,$out0,v25
+
+	lvsr		$inpperm,0,$taillen
+	vcipher		$out0,$out0,v26
+
+	lvx_u		$in0,0,$inp
+	vcipher		$out0,$out0,v27
+
+	addi		$key_,$sp,$FRAME+15	# rewind $key_
+	vcipher		$out0,$out0,v28
+	lvx		v24,$x00,$key_		# re-pre-load round[1]
+
+	vcipher		$out0,$out0,v29
+	lvx		v25,$x10,$key_		# re-pre-load round[2]
+	 vxor		$twk0,$twk0,v31
+
+	le?vperm	$in0,$in0,$in0,$leperm
+	vcipher		$out0,$out0,v30
+
+	vperm		$in0,$in0,$in0,$inpperm
+	vcipherlast	$out0,$out0,$twk0
+
+	vmr		$twk0,$twk1		# unused tweak
+	vxor		$tmp,$out0,$twk1	# last block prep for stealing
+	le?vperm	$out0,$out0,$out0,$leperm
+	stvx_u		$out0,$x00,$out		# store output
+	addi		$out,$out,0x10
+	bne		Lxts_enc6x_steal
+	b		Lxts_enc6x_done
+
+.align	4
+Lxts_enc6x_zero:
+	cmpwi		$taillen,0
+	beq		Lxts_enc6x_done
+
+	add		$inp,$inp,$taillen
+	subi		$inp,$inp,16
+	lvx_u		$in0,0,$inp
+	lvsr		$inpperm,0,$taillen	# $in5 is no more
+	le?vperm	$in0,$in0,$in0,$leperm
+	vperm		$in0,$in0,$in0,$inpperm
+	vxor		$tmp,$tmp,$twk0
+Lxts_enc6x_steal:
+	vxor		$in0,$in0,$twk0
+	vxor		$out0,$out0,$out0
+	vspltisb	$out1,-1
+	vperm		$out0,$out0,$out1,$inpperm
+	vsel		$out0,$in0,$tmp,$out0	# $tmp is last block, remember?
+
+	subi		r30,$out,17
+	subi		$out,$out,16
+	mtctr		$taillen
+Loop_xts_enc6x_steal:
+	lbzu		r0,1(r30)
+	stb		r0,16(r30)
+	bdnz		Loop_xts_enc6x_steal
+
+	li		$taillen,0
+	mtctr		$rounds
+	b		Loop_xts_enc1x		# one more time...
+
+.align	4
+Lxts_enc6x_done:
+	${UCMP}i	$ivp,0
+	beq		Lxts_enc6x_ret
+
+	vxor		$tweak,$twk0,$rndkey0
+	le?vperm	$tweak,$tweak,$tweak,$leperm
+	stvx_u		$tweak,0,$ivp
+
+Lxts_enc6x_ret:
+	mtlr		r11
+	li		r10,`$FRAME+15`
+	li		r11,`$FRAME+31`
+	stvx		$seven,r10,$sp		# wipe copies of round keys
+	addi		r10,r10,32
+	stvx		$seven,r11,$sp
+	addi		r11,r11,32
+	stvx		$seven,r10,$sp
+	addi		r10,r10,32
+	stvx		$seven,r11,$sp
+	addi		r11,r11,32
+	stvx		$seven,r10,$sp
+	addi		r10,r10,32
+	stvx		$seven,r11,$sp
+	addi		r11,r11,32
+	stvx		$seven,r10,$sp
+	addi		r10,r10,32
+	stvx		$seven,r11,$sp
+	addi		r11,r11,32
+
+	mtspr		256,$vrsave
+	lvx		v20,r10,$sp		# ABI says so
+	addi		r10,r10,32
+	lvx		v21,r11,$sp
+	addi		r11,r11,32
+	lvx		v22,r10,$sp
+	addi		r10,r10,32
+	lvx		v23,r11,$sp
+	addi		r11,r11,32
+	lvx		v24,r10,$sp
+	addi		r10,r10,32
+	lvx		v25,r11,$sp
+	addi		r11,r11,32
+	lvx		v26,r10,$sp
+	addi		r10,r10,32
+	lvx		v27,r11,$sp
+	addi		r11,r11,32
+	lvx		v28,r10,$sp
+	addi		r10,r10,32
+	lvx		v29,r11,$sp
+	addi		r11,r11,32
+	lvx		v30,r10,$sp
+	lvx		v31,r11,$sp
+	$POP		r26,`$FRAME+21*16+0*$SIZE_T`($sp)
+	$POP		r27,`$FRAME+21*16+1*$SIZE_T`($sp)
+	$POP		r28,`$FRAME+21*16+2*$SIZE_T`($sp)
+	$POP		r29,`$FRAME+21*16+3*$SIZE_T`($sp)
+	$POP		r30,`$FRAME+21*16+4*$SIZE_T`($sp)
+	$POP		r31,`$FRAME+21*16+5*$SIZE_T`($sp)
+	addi		$sp,$sp,`$FRAME+21*16+6*$SIZE_T`
+	blr
+	.long		0
+	.byte		0,12,0x04,1,0x80,6,6,0
+	.long		0
+
+.align	5
+_aesp8_xts_enc5x:
+	vcipher		$out0,$out0,v24
+	vcipher		$out1,$out1,v24
+	vcipher		$out2,$out2,v24
+	vcipher		$out3,$out3,v24
+	vcipher		$out4,$out4,v24
+	lvx		v24,$x20,$key_		# round[3]
+	addi		$key_,$key_,0x20
+
+	vcipher		$out0,$out0,v25
+	vcipher		$out1,$out1,v25
+	vcipher		$out2,$out2,v25
+	vcipher		$out3,$out3,v25
+	vcipher		$out4,$out4,v25
+	lvx		v25,$x10,$key_		# round[4]
+	bdnz		_aesp8_xts_enc5x
+
+	add		$inp,$inp,$taillen
+	cmpwi		$taillen,0
+	vcipher		$out0,$out0,v24
+	vcipher		$out1,$out1,v24
+	vcipher		$out2,$out2,v24
+	vcipher		$out3,$out3,v24
+	vcipher		$out4,$out4,v24
+
+	subi		$inp,$inp,16
+	vcipher		$out0,$out0,v25
+	vcipher		$out1,$out1,v25
+	vcipher		$out2,$out2,v25
+	vcipher		$out3,$out3,v25
+	vcipher		$out4,$out4,v25
+	 vxor		$twk0,$twk0,v31
+
+	vcipher		$out0,$out0,v26
+	lvsr		$inpperm,r0,$taillen	# $in5 is no more
+	vcipher		$out1,$out1,v26
+	vcipher		$out2,$out2,v26
+	vcipher		$out3,$out3,v26
+	vcipher		$out4,$out4,v26
+	 vxor		$in1,$twk1,v31
+
+	vcipher		$out0,$out0,v27
+	lvx_u		$in0,0,$inp
+	vcipher		$out1,$out1,v27
+	vcipher		$out2,$out2,v27
+	vcipher		$out3,$out3,v27
+	vcipher		$out4,$out4,v27
+	 vxor		$in2,$twk2,v31
+
+	addi		$key_,$sp,$FRAME+15	# rewind $key_
+	vcipher		$out0,$out0,v28
+	vcipher		$out1,$out1,v28
+	vcipher		$out2,$out2,v28
+	vcipher		$out3,$out3,v28
+	vcipher		$out4,$out4,v28
+	lvx		v24,$x00,$key_		# re-pre-load round[1]
+	 vxor		$in3,$twk3,v31
+
+	vcipher		$out0,$out0,v29
+	le?vperm	$in0,$in0,$in0,$leperm
+	vcipher		$out1,$out1,v29
+	vcipher		$out2,$out2,v29
+	vcipher		$out3,$out3,v29
+	vcipher		$out4,$out4,v29
+	lvx		v25,$x10,$key_		# re-pre-load round[2]
+	 vxor		$in4,$twk4,v31
+
+	vcipher		$out0,$out0,v30
+	vperm		$in0,$in0,$in0,$inpperm
+	vcipher		$out1,$out1,v30
+	vcipher		$out2,$out2,v30
+	vcipher		$out3,$out3,v30
+	vcipher		$out4,$out4,v30
+
+	vcipherlast	$out0,$out0,$twk0
+	vcipherlast	$out1,$out1,$in1
+	vcipherlast	$out2,$out2,$in2
+	vcipherlast	$out3,$out3,$in3
+	vcipherlast	$out4,$out4,$in4
+	blr
+        .long   	0
+        .byte   	0,12,0x14,0,0,0,0,0
+
+.align	5
+_aesp8_xts_decrypt6x:
+	$STU		$sp,-`($FRAME+21*16+6*$SIZE_T)`($sp)
+	mflr		r11
+	li		r7,`$FRAME+8*16+15`
+	li		r3,`$FRAME+8*16+31`
+	$PUSH		r11,`$FRAME+21*16+6*$SIZE_T+$LRSAVE`($sp)
+	stvx		v20,r7,$sp		# ABI says so
+	addi		r7,r7,32
+	stvx		v21,r3,$sp
+	addi		r3,r3,32
+	stvx		v22,r7,$sp
+	addi		r7,r7,32
+	stvx		v23,r3,$sp
+	addi		r3,r3,32
+	stvx		v24,r7,$sp
+	addi		r7,r7,32
+	stvx		v25,r3,$sp
+	addi		r3,r3,32
+	stvx		v26,r7,$sp
+	addi		r7,r7,32
+	stvx		v27,r3,$sp
+	addi		r3,r3,32
+	stvx		v28,r7,$sp
+	addi		r7,r7,32
+	stvx		v29,r3,$sp
+	addi		r3,r3,32
+	stvx		v30,r7,$sp
+	stvx		v31,r3,$sp
+	li		r0,-1
+	stw		$vrsave,`$FRAME+21*16-4`($sp)	# save vrsave
+	li		$x10,0x10
+	$PUSH		r26,`$FRAME+21*16+0*$SIZE_T`($sp)
+	li		$x20,0x20
+	$PUSH		r27,`$FRAME+21*16+1*$SIZE_T`($sp)
+	li		$x30,0x30
+	$PUSH		r28,`$FRAME+21*16+2*$SIZE_T`($sp)
+	li		$x40,0x40
+	$PUSH		r29,`$FRAME+21*16+3*$SIZE_T`($sp)
+	li		$x50,0x50
+	$PUSH		r30,`$FRAME+21*16+4*$SIZE_T`($sp)
+	li		$x60,0x60
+	$PUSH		r31,`$FRAME+21*16+5*$SIZE_T`($sp)
+	li		$x70,0x70
+	mtspr		256,r0
+
+	subi		$rounds,$rounds,3	# -4 in total
+
+	lvx		$rndkey0,$x00,$key1	# load key schedule
+	lvx		v30,$x10,$key1
+	addi		$key1,$key1,0x20
+	lvx		v31,$x00,$key1
+	?vperm		$rndkey0,$rndkey0,v30,$keyperm
+	addi		$key_,$sp,$FRAME+15
+	mtctr		$rounds
+
+Load_xts_dec_key:
+	?vperm		v24,v30,v31,$keyperm
+	lvx		v30,$x10,$key1
+	addi		$key1,$key1,0x20
+	stvx		v24,$x00,$key_		# off-load round[1]
+	?vperm		v25,v31,v30,$keyperm
+	lvx		v31,$x00,$key1
+	stvx		v25,$x10,$key_		# off-load round[2]
+	addi		$key_,$key_,0x20
+	bdnz		Load_xts_dec_key
+
+	lvx		v26,$x10,$key1
+	?vperm		v24,v30,v31,$keyperm
+	lvx		v27,$x20,$key1
+	stvx		v24,$x00,$key_		# off-load round[3]
+	?vperm		v25,v31,v26,$keyperm
+	lvx		v28,$x30,$key1
+	stvx		v25,$x10,$key_		# off-load round[4]
+	addi		$key_,$sp,$FRAME+15	# rewind $key_
+	?vperm		v26,v26,v27,$keyperm
+	lvx		v29,$x40,$key1
+	?vperm		v27,v27,v28,$keyperm
+	lvx		v30,$x50,$key1
+	?vperm		v28,v28,v29,$keyperm
+	lvx		v31,$x60,$key1
+	?vperm		v29,v29,v30,$keyperm
+	lvx		$twk5,$x70,$key1	# borrow $twk5
+	?vperm		v30,v30,v31,$keyperm
+	lvx		v24,$x00,$key_		# pre-load round[1]
+	?vperm		v31,v31,$twk5,$keyperm
+	lvx		v25,$x10,$key_		# pre-load round[2]
+
+	 vperm		$in0,$inout,$inptail,$inpperm
+	 subi		$inp,$inp,31		# undo "caller"
+	vxor		$twk0,$tweak,$rndkey0
+	vsrab		$tmp,$tweak,$seven	# next tweak value
+	vaddubm		$tweak,$tweak,$tweak
+	vsldoi		$tmp,$tmp,$tmp,15
+	vand		$tmp,$tmp,$eighty7
+	 vxor		$out0,$in0,$twk0
+	vxor		$tweak,$tweak,$tmp
+
+	 lvx_u		$in1,$x10,$inp
+	vxor		$twk1,$tweak,$rndkey0
+	vsrab		$tmp,$tweak,$seven	# next tweak value
+	vaddubm		$tweak,$tweak,$tweak
+	vsldoi		$tmp,$tmp,$tmp,15
+	 le?vperm	$in1,$in1,$in1,$leperm
+	vand		$tmp,$tmp,$eighty7
+	 vxor		$out1,$in1,$twk1
+	vxor		$tweak,$tweak,$tmp
+
+	 lvx_u		$in2,$x20,$inp
+	 andi.		$taillen,$len,15
+	vxor		$twk2,$tweak,$rndkey0
+	vsrab		$tmp,$tweak,$seven	# next tweak value
+	vaddubm		$tweak,$tweak,$tweak
+	vsldoi		$tmp,$tmp,$tmp,15
+	 le?vperm	$in2,$in2,$in2,$leperm
+	vand		$tmp,$tmp,$eighty7
+	 vxor		$out2,$in2,$twk2
+	vxor		$tweak,$tweak,$tmp
+
+	 lvx_u		$in3,$x30,$inp
+	 sub		$len,$len,$taillen
+	vxor		$twk3,$tweak,$rndkey0
+	vsrab		$tmp,$tweak,$seven	# next tweak value
+	vaddubm		$tweak,$tweak,$tweak
+	vsldoi		$tmp,$tmp,$tmp,15
+	 le?vperm	$in3,$in3,$in3,$leperm
+	vand		$tmp,$tmp,$eighty7
+	 vxor		$out3,$in3,$twk3
+	vxor		$tweak,$tweak,$tmp
+
+	 lvx_u		$in4,$x40,$inp
+	 subi		$len,$len,0x60
+	vxor		$twk4,$tweak,$rndkey0
+	vsrab		$tmp,$tweak,$seven	# next tweak value
+	vaddubm		$tweak,$tweak,$tweak
+	vsldoi		$tmp,$tmp,$tmp,15
+	 le?vperm	$in4,$in4,$in4,$leperm
+	vand		$tmp,$tmp,$eighty7
+	 vxor		$out4,$in4,$twk4
+	vxor		$tweak,$tweak,$tmp
+
+	 lvx_u		$in5,$x50,$inp
+	 addi		$inp,$inp,0x60
+	vxor		$twk5,$tweak,$rndkey0
+	vsrab		$tmp,$tweak,$seven	# next tweak value
+	vaddubm		$tweak,$tweak,$tweak
+	vsldoi		$tmp,$tmp,$tmp,15
+	 le?vperm	$in5,$in5,$in5,$leperm
+	vand		$tmp,$tmp,$eighty7
+	 vxor		$out5,$in5,$twk5
+	vxor		$tweak,$tweak,$tmp
+
+	vxor		v31,v31,$rndkey0
+	mtctr		$rounds
+	b		Loop_xts_dec6x
+
+.align	5
+Loop_xts_dec6x:
+	vncipher	$out0,$out0,v24
+	vncipher	$out1,$out1,v24
+	vncipher	$out2,$out2,v24
+	vncipher	$out3,$out3,v24
+	vncipher	$out4,$out4,v24
+	vncipher	$out5,$out5,v24
+	lvx		v24,$x20,$key_		# round[3]
+	addi		$key_,$key_,0x20
+
+	vncipher	$out0,$out0,v25
+	vncipher	$out1,$out1,v25
+	vncipher	$out2,$out2,v25
+	vncipher	$out3,$out3,v25
+	vncipher	$out4,$out4,v25
+	vncipher	$out5,$out5,v25
+	lvx		v25,$x10,$key_		# round[4]
+	bdnz		Loop_xts_dec6x
+
+	subic		$len,$len,96		# $len-=96
+	 vxor		$in0,$twk0,v31		# xor with last round key
+	vncipher	$out0,$out0,v24
+	vncipher	$out1,$out1,v24
+	 vsrab		$tmp,$tweak,$seven	# next tweak value
+	 vxor		$twk0,$tweak,$rndkey0
+	 vaddubm	$tweak,$tweak,$tweak
+	vncipher	$out2,$out2,v24
+	vncipher	$out3,$out3,v24
+	 vsldoi		$tmp,$tmp,$tmp,15
+	vncipher	$out4,$out4,v24
+	vncipher	$out5,$out5,v24
+
+	subfe.		r0,r0,r0		# borrow?-1:0
+	 vand		$tmp,$tmp,$eighty7
+	vncipher	$out0,$out0,v25
+	vncipher	$out1,$out1,v25
+	 vxor		$tweak,$tweak,$tmp
+	vncipher	$out2,$out2,v25
+	vncipher	$out3,$out3,v25
+	 vxor		$in1,$twk1,v31
+	 vsrab		$tmp,$tweak,$seven	# next tweak value
+	 vxor		$twk1,$tweak,$rndkey0
+	vncipher	$out4,$out4,v25
+	vncipher	$out5,$out5,v25
+
+	and		r0,r0,$len
+	 vaddubm	$tweak,$tweak,$tweak
+	 vsldoi		$tmp,$tmp,$tmp,15
+	vncipher	$out0,$out0,v26
+	vncipher	$out1,$out1,v26
+	 vand		$tmp,$tmp,$eighty7
+	vncipher	$out2,$out2,v26
+	vncipher	$out3,$out3,v26
+	 vxor		$tweak,$tweak,$tmp
+	vncipher	$out4,$out4,v26
+	vncipher	$out5,$out5,v26
+
+	add		$inp,$inp,r0		# $inp is adjusted in such
+						# way that at exit from the
+						# loop inX-in5 are loaded
+						# with last "words"
+	 vxor		$in2,$twk2,v31
+	 vsrab		$tmp,$tweak,$seven	# next tweak value
+	 vxor		$twk2,$tweak,$rndkey0
+	 vaddubm	$tweak,$tweak,$tweak
+	vncipher	$out0,$out0,v27
+	vncipher	$out1,$out1,v27
+	 vsldoi		$tmp,$tmp,$tmp,15
+	vncipher	$out2,$out2,v27
+	vncipher	$out3,$out3,v27
+	 vand		$tmp,$tmp,$eighty7
+	vncipher	$out4,$out4,v27
+	vncipher	$out5,$out5,v27
+
+	addi		$key_,$sp,$FRAME+15	# rewind $key_
+	 vxor		$tweak,$tweak,$tmp
+	vncipher	$out0,$out0,v28
+	vncipher	$out1,$out1,v28
+	 vxor		$in3,$twk3,v31
+	 vsrab		$tmp,$tweak,$seven	# next tweak value
+	 vxor		$twk3,$tweak,$rndkey0
+	vncipher	$out2,$out2,v28
+	vncipher	$out3,$out3,v28
+	 vaddubm	$tweak,$tweak,$tweak
+	 vsldoi		$tmp,$tmp,$tmp,15
+	vncipher	$out4,$out4,v28
+	vncipher	$out5,$out5,v28
+	lvx		v24,$x00,$key_		# re-pre-load round[1]
+	 vand		$tmp,$tmp,$eighty7
+
+	vncipher	$out0,$out0,v29
+	vncipher	$out1,$out1,v29
+	 vxor		$tweak,$tweak,$tmp
+	vncipher	$out2,$out2,v29
+	vncipher	$out3,$out3,v29
+	 vxor		$in4,$twk4,v31
+	 vsrab		$tmp,$tweak,$seven	# next tweak value
+	 vxor		$twk4,$tweak,$rndkey0
+	vncipher	$out4,$out4,v29
+	vncipher	$out5,$out5,v29
+	lvx		v25,$x10,$key_		# re-pre-load round[2]
+	 vaddubm	$tweak,$tweak,$tweak
+	 vsldoi		$tmp,$tmp,$tmp,15
+
+	vncipher	$out0,$out0,v30
+	vncipher	$out1,$out1,v30
+	 vand		$tmp,$tmp,$eighty7
+	vncipher	$out2,$out2,v30
+	vncipher	$out3,$out3,v30
+	 vxor		$tweak,$tweak,$tmp
+	vncipher	$out4,$out4,v30
+	vncipher	$out5,$out5,v30
+	 vxor		$in5,$twk5,v31
+	 vsrab		$tmp,$tweak,$seven	# next tweak value
+	 vxor		$twk5,$tweak,$rndkey0
+
+	vncipherlast	$out0,$out0,$in0
+	 lvx_u		$in0,$x00,$inp		# load next input block
+	 vaddubm	$tweak,$tweak,$tweak
+	 vsldoi		$tmp,$tmp,$tmp,15
+	vncipherlast	$out1,$out1,$in1
+	 lvx_u		$in1,$x10,$inp
+	vncipherlast	$out2,$out2,$in2
+	 le?vperm	$in0,$in0,$in0,$leperm
+	 lvx_u		$in2,$x20,$inp
+	 vand		$tmp,$tmp,$eighty7
+	vncipherlast	$out3,$out3,$in3
+	 le?vperm	$in1,$in1,$in1,$leperm
+	 lvx_u		$in3,$x30,$inp
+	vncipherlast	$out4,$out4,$in4
+	 le?vperm	$in2,$in2,$in2,$leperm
+	 lvx_u		$in4,$x40,$inp
+	 vxor		$tweak,$tweak,$tmp
+	vncipherlast	$out5,$out5,$in5
+	 le?vperm	$in3,$in3,$in3,$leperm
+	 lvx_u		$in5,$x50,$inp
+	 addi		$inp,$inp,0x60
+	 le?vperm	$in4,$in4,$in4,$leperm
+	 le?vperm	$in5,$in5,$in5,$leperm
+
+	le?vperm	$out0,$out0,$out0,$leperm
+	le?vperm	$out1,$out1,$out1,$leperm
+	stvx_u		$out0,$x00,$out		# store output
+	 vxor		$out0,$in0,$twk0
+	le?vperm	$out2,$out2,$out2,$leperm
+	stvx_u		$out1,$x10,$out
+	 vxor		$out1,$in1,$twk1
+	le?vperm	$out3,$out3,$out3,$leperm
+	stvx_u		$out2,$x20,$out
+	 vxor		$out2,$in2,$twk2
+	le?vperm	$out4,$out4,$out4,$leperm
+	stvx_u		$out3,$x30,$out
+	 vxor		$out3,$in3,$twk3
+	le?vperm	$out5,$out5,$out5,$leperm
+	stvx_u		$out4,$x40,$out
+	 vxor		$out4,$in4,$twk4
+	stvx_u		$out5,$x50,$out
+	 vxor		$out5,$in5,$twk5
+	addi		$out,$out,0x60
+
+	mtctr		$rounds
+	beq		Loop_xts_dec6x		# did $len-=96 borrow?
+
+	addic.		$len,$len,0x60
+	beq		Lxts_dec6x_zero
+	cmpwi		$len,0x20
+	blt		Lxts_dec6x_one
+	nop
+	beq		Lxts_dec6x_two
+	cmpwi		$len,0x40
+	blt		Lxts_dec6x_three
+	nop
+	beq		Lxts_dec6x_four
+
+Lxts_dec6x_five:
+	vxor		$out0,$in1,$twk0
+	vxor		$out1,$in2,$twk1
+	vxor		$out2,$in3,$twk2
+	vxor		$out3,$in4,$twk3
+	vxor		$out4,$in5,$twk4
+
+	bl		_aesp8_xts_dec5x
+
+	le?vperm	$out0,$out0,$out0,$leperm
+	vmr		$twk0,$twk5		# unused tweak
+	vxor		$twk1,$tweak,$rndkey0
+	le?vperm	$out1,$out1,$out1,$leperm
+	stvx_u		$out0,$x00,$out		# store output
+	vxor		$out0,$in0,$twk1
+	le?vperm	$out2,$out2,$out2,$leperm
+	stvx_u		$out1,$x10,$out
+	le?vperm	$out3,$out3,$out3,$leperm
+	stvx_u		$out2,$x20,$out
+	le?vperm	$out4,$out4,$out4,$leperm
+	stvx_u		$out3,$x30,$out
+	stvx_u		$out4,$x40,$out
+	addi		$out,$out,0x50
+	bne		Lxts_dec6x_steal
+	b		Lxts_dec6x_done
+
+.align	4
+Lxts_dec6x_four:
+	vxor		$out0,$in2,$twk0
+	vxor		$out1,$in3,$twk1
+	vxor		$out2,$in4,$twk2
+	vxor		$out3,$in5,$twk3
+	vxor		$out4,$out4,$out4
+
+	bl		_aesp8_xts_dec5x
+
+	le?vperm	$out0,$out0,$out0,$leperm
+	vmr		$twk0,$twk4		# unused tweak
+	vmr		$twk1,$twk5
+	le?vperm	$out1,$out1,$out1,$leperm
+	stvx_u		$out0,$x00,$out		# store output
+	vxor		$out0,$in0,$twk5
+	le?vperm	$out2,$out2,$out2,$leperm
+	stvx_u		$out1,$x10,$out
+	le?vperm	$out3,$out3,$out3,$leperm
+	stvx_u		$out2,$x20,$out
+	stvx_u		$out3,$x30,$out
+	addi		$out,$out,0x40
+	bne		Lxts_dec6x_steal
+	b		Lxts_dec6x_done
+
+.align	4
+Lxts_dec6x_three:
+	vxor		$out0,$in3,$twk0
+	vxor		$out1,$in4,$twk1
+	vxor		$out2,$in5,$twk2
+	vxor		$out3,$out3,$out3
+	vxor		$out4,$out4,$out4
+
+	bl		_aesp8_xts_dec5x
+
+	le?vperm	$out0,$out0,$out0,$leperm
+	vmr		$twk0,$twk3		# unused tweak
+	vmr		$twk1,$twk4
+	le?vperm	$out1,$out1,$out1,$leperm
+	stvx_u		$out0,$x00,$out		# store output
+	vxor		$out0,$in0,$twk4
+	le?vperm	$out2,$out2,$out2,$leperm
+	stvx_u		$out1,$x10,$out
+	stvx_u		$out2,$x20,$out
+	addi		$out,$out,0x30
+	bne		Lxts_dec6x_steal
+	b		Lxts_dec6x_done
+
+.align	4
+Lxts_dec6x_two:
+	vxor		$out0,$in4,$twk0
+	vxor		$out1,$in5,$twk1
+	vxor		$out2,$out2,$out2
+	vxor		$out3,$out3,$out3
+	vxor		$out4,$out4,$out4
+
+	bl		_aesp8_xts_dec5x
+
+	le?vperm	$out0,$out0,$out0,$leperm
+	vmr		$twk0,$twk2		# unused tweak
+	vmr		$twk1,$twk3
+	le?vperm	$out1,$out1,$out1,$leperm
+	stvx_u		$out0,$x00,$out		# store output
+	vxor		$out0,$in0,$twk3
+	stvx_u		$out1,$x10,$out
+	addi		$out,$out,0x20
+	bne		Lxts_dec6x_steal
+	b		Lxts_dec6x_done
+
+.align	4
+Lxts_dec6x_one:
+	vxor		$out0,$in5,$twk0
+	nop
+Loop_xts_dec1x:
+	vncipher	$out0,$out0,v24
+	lvx		v24,$x20,$key_		# round[3]
+	addi		$key_,$key_,0x20
+
+	vncipher	$out0,$out0,v25
+	lvx		v25,$x10,$key_		# round[4]
+	bdnz		Loop_xts_dec1x
+
+	subi		r0,$taillen,1
+	vncipher	$out0,$out0,v24
+
+	andi.		r0,r0,16
+	cmpwi		$taillen,0
+	vncipher	$out0,$out0,v25
+
+	sub		$inp,$inp,r0
+	vncipher	$out0,$out0,v26
+
+	lvx_u		$in0,0,$inp
+	vncipher	$out0,$out0,v27
+
+	addi		$key_,$sp,$FRAME+15	# rewind $key_
+	vncipher	$out0,$out0,v28
+	lvx		v24,$x00,$key_		# re-pre-load round[1]
+
+	vncipher	$out0,$out0,v29
+	lvx		v25,$x10,$key_		# re-pre-load round[2]
+	 vxor		$twk0,$twk0,v31
+
+	le?vperm	$in0,$in0,$in0,$leperm
+	vncipher	$out0,$out0,v30
+
+	mtctr		$rounds
+	vncipherlast	$out0,$out0,$twk0
+
+	vmr		$twk0,$twk1		# unused tweak
+	vmr		$twk1,$twk2
+	le?vperm	$out0,$out0,$out0,$leperm
+	stvx_u		$out0,$x00,$out		# store output
+	addi		$out,$out,0x10
+	vxor		$out0,$in0,$twk2
+	bne		Lxts_dec6x_steal
+	b		Lxts_dec6x_done
+
+.align	4
+Lxts_dec6x_zero:
+	cmpwi		$taillen,0
+	beq		Lxts_dec6x_done
+
+	lvx_u		$in0,0,$inp
+	le?vperm	$in0,$in0,$in0,$leperm
+	vxor		$out0,$in0,$twk1
+Lxts_dec6x_steal:
+	vncipher	$out0,$out0,v24
+	lvx		v24,$x20,$key_		# round[3]
+	addi		$key_,$key_,0x20
+
+	vncipher	$out0,$out0,v25
+	lvx		v25,$x10,$key_		# round[4]
+	bdnz		Lxts_dec6x_steal
+
+	add		$inp,$inp,$taillen
+	vncipher	$out0,$out0,v24
+
+	cmpwi		$taillen,0
+	vncipher	$out0,$out0,v25
+
+	lvx_u		$in0,0,$inp
+	vncipher	$out0,$out0,v26
+
+	lvsr		$inpperm,0,$taillen	# $in5 is no more
+	vncipher	$out0,$out0,v27
+
+	addi		$key_,$sp,$FRAME+15	# rewind $key_
+	vncipher	$out0,$out0,v28
+	lvx		v24,$x00,$key_		# re-pre-load round[1]
+
+	vncipher	$out0,$out0,v29
+	lvx		v25,$x10,$key_		# re-pre-load round[2]
+	 vxor		$twk1,$twk1,v31
+
+	le?vperm	$in0,$in0,$in0,$leperm
+	vncipher	$out0,$out0,v30
+
+	vperm		$in0,$in0,$in0,$inpperm
+	vncipherlast	$tmp,$out0,$twk1
+
+	le?vperm	$out0,$tmp,$tmp,$leperm
+	le?stvx_u	$out0,0,$out
+	be?stvx_u	$tmp,0,$out
+
+	vxor		$out0,$out0,$out0
+	vspltisb	$out1,-1
+	vperm		$out0,$out0,$out1,$inpperm
+	vsel		$out0,$in0,$tmp,$out0
+	vxor		$out0,$out0,$twk0
+
+	subi		r30,$out,1
+	mtctr		$taillen
+Loop_xts_dec6x_steal:
+	lbzu		r0,1(r30)
+	stb		r0,16(r30)
+	bdnz		Loop_xts_dec6x_steal
+
+	li		$taillen,0
+	mtctr		$rounds
+	b		Loop_xts_dec1x		# one more time...
+
+.align	4
+Lxts_dec6x_done:
+	${UCMP}i	$ivp,0
+	beq		Lxts_dec6x_ret
+
+	vxor		$tweak,$twk0,$rndkey0
+	le?vperm	$tweak,$tweak,$tweak,$leperm
+	stvx_u		$tweak,0,$ivp
+
+Lxts_dec6x_ret:
+	mtlr		r11
+	li		r10,`$FRAME+15`
+	li		r11,`$FRAME+31`
+	stvx		$seven,r10,$sp		# wipe copies of round keys
+	addi		r10,r10,32
+	stvx		$seven,r11,$sp
+	addi		r11,r11,32
+	stvx		$seven,r10,$sp
+	addi		r10,r10,32
+	stvx		$seven,r11,$sp
+	addi		r11,r11,32
+	stvx		$seven,r10,$sp
+	addi		r10,r10,32
+	stvx		$seven,r11,$sp
+	addi		r11,r11,32
+	stvx		$seven,r10,$sp
+	addi		r10,r10,32
+	stvx		$seven,r11,$sp
+	addi		r11,r11,32
+
+	mtspr		256,$vrsave
+	lvx		v20,r10,$sp		# ABI says so
+	addi		r10,r10,32
+	lvx		v21,r11,$sp
+	addi		r11,r11,32
+	lvx		v22,r10,$sp
+	addi		r10,r10,32
+	lvx		v23,r11,$sp
+	addi		r11,r11,32
+	lvx		v24,r10,$sp
+	addi		r10,r10,32
+	lvx		v25,r11,$sp
+	addi		r11,r11,32
+	lvx		v26,r10,$sp
+	addi		r10,r10,32
+	lvx		v27,r11,$sp
+	addi		r11,r11,32
+	lvx		v28,r10,$sp
+	addi		r10,r10,32
+	lvx		v29,r11,$sp
+	addi		r11,r11,32
+	lvx		v30,r10,$sp
+	lvx		v31,r11,$sp
+	$POP		r26,`$FRAME+21*16+0*$SIZE_T`($sp)
+	$POP		r27,`$FRAME+21*16+1*$SIZE_T`($sp)
+	$POP		r28,`$FRAME+21*16+2*$SIZE_T`($sp)
+	$POP		r29,`$FRAME+21*16+3*$SIZE_T`($sp)
+	$POP		r30,`$FRAME+21*16+4*$SIZE_T`($sp)
+	$POP		r31,`$FRAME+21*16+5*$SIZE_T`($sp)
+	addi		$sp,$sp,`$FRAME+21*16+6*$SIZE_T`
+	blr
+	.long		0
+	.byte		0,12,0x04,1,0x80,6,6,0
+	.long		0
+
+.align	5
+_aesp8_xts_dec5x:
+	vncipher	$out0,$out0,v24
+	vncipher	$out1,$out1,v24
+	vncipher	$out2,$out2,v24
+	vncipher	$out3,$out3,v24
+	vncipher	$out4,$out4,v24
+	lvx		v24,$x20,$key_		# round[3]
+	addi		$key_,$key_,0x20
+
+	vncipher	$out0,$out0,v25
+	vncipher	$out1,$out1,v25
+	vncipher	$out2,$out2,v25
+	vncipher	$out3,$out3,v25
+	vncipher	$out4,$out4,v25
+	lvx		v25,$x10,$key_		# round[4]
+	bdnz		_aesp8_xts_dec5x
+
+	subi		r0,$taillen,1
+	vncipher	$out0,$out0,v24
+	vncipher	$out1,$out1,v24
+	vncipher	$out2,$out2,v24
+	vncipher	$out3,$out3,v24
+	vncipher	$out4,$out4,v24
+
+	andi.		r0,r0,16
+	cmpwi		$taillen,0
+	vncipher	$out0,$out0,v25
+	vncipher	$out1,$out1,v25
+	vncipher	$out2,$out2,v25
+	vncipher	$out3,$out3,v25
+	vncipher	$out4,$out4,v25
+	 vxor		$twk0,$twk0,v31
+
+	sub		$inp,$inp,r0
+	vncipher	$out0,$out0,v26
+	vncipher	$out1,$out1,v26
+	vncipher	$out2,$out2,v26
+	vncipher	$out3,$out3,v26
+	vncipher	$out4,$out4,v26
+	 vxor		$in1,$twk1,v31
+
+	vncipher	$out0,$out0,v27
+	lvx_u		$in0,0,$inp
+	vncipher	$out1,$out1,v27
+	vncipher	$out2,$out2,v27
+	vncipher	$out3,$out3,v27
+	vncipher	$out4,$out4,v27
+	 vxor		$in2,$twk2,v31
+
+	addi		$key_,$sp,$FRAME+15	# rewind $key_
+	vncipher	$out0,$out0,v28
+	vncipher	$out1,$out1,v28
+	vncipher	$out2,$out2,v28
+	vncipher	$out3,$out3,v28
+	vncipher	$out4,$out4,v28
+	lvx		v24,$x00,$key_		# re-pre-load round[1]
+	 vxor		$in3,$twk3,v31
+
+	vncipher	$out0,$out0,v29
+	le?vperm	$in0,$in0,$in0,$leperm
+	vncipher	$out1,$out1,v29
+	vncipher	$out2,$out2,v29
+	vncipher	$out3,$out3,v29
+	vncipher	$out4,$out4,v29
+	lvx		v25,$x10,$key_		# re-pre-load round[2]
+	 vxor		$in4,$twk4,v31
+
+	vncipher	$out0,$out0,v30
+	vncipher	$out1,$out1,v30
+	vncipher	$out2,$out2,v30
+	vncipher	$out3,$out3,v30
+	vncipher	$out4,$out4,v30
+
+	vncipherlast	$out0,$out0,$twk0
+	vncipherlast	$out1,$out1,$in1
+	vncipherlast	$out2,$out2,$in2
+	vncipherlast	$out3,$out3,$in3
+	vncipherlast	$out4,$out4,$in4
+	mtctr		$rounds
+	blr
+        .long   	0
+        .byte   	0,12,0x14,0,0,0,0,0
+___
+}}	}}}
+
 my $consts=1;
 foreach(split("\n",$code)) {
         s/\`([^\`]*)\`/eval($1)/geo;
@@ -1898,7 +3757,7 @@ foreach(split("\n",$code)) {
 	    if ($flavour =~ /le$/o) {
 		SWITCH: for($conv)  {
 		    /\?inv/ && do   { @bytes=map($_^0xf,@bytes); last; };
-		    /\?rev/ && do   { @bytes=reverse(@bytes);    last; }; 
+		    /\?rev/ && do   { @bytes=reverse(@bytes);    last; };
 		}
 	    }
 
--- zfcpdump-kernel-4.4.orig/drivers/crypto/vmx/ghash.c
+++ zfcpdump-kernel-4.4/drivers/crypto/vmx/ghash.c
@@ -26,16 +26,13 @@
 #include <linux/hardirq.h>
 #include <asm/switch_to.h>
 #include <crypto/aes.h>
+#include <crypto/ghash.h>
 #include <crypto/scatterwalk.h>
 #include <crypto/internal/hash.h>
 #include <crypto/b128ops.h>
 
 #define IN_INTERRUPT in_interrupt()
 
-#define GHASH_BLOCK_SIZE (16)
-#define GHASH_DIGEST_SIZE (16)
-#define GHASH_KEY_LEN (16)
-
 void gcm_init_p8(u128 htable[16], const u64 Xi[2]);
 void gcm_gmult_p8(u64 Xi[2], const u128 htable[16]);
 void gcm_ghash_p8(u64 Xi[2], const u128 htable[16],
@@ -55,16 +52,11 @@ struct p8_ghash_desc_ctx {
 
 static int p8_ghash_init_tfm(struct crypto_tfm *tfm)
 {
-	const char *alg;
+	const char *alg = "ghash-generic";
 	struct crypto_shash *fallback;
 	struct crypto_shash *shash_tfm = __crypto_shash_cast(tfm);
 	struct p8_ghash_ctx *ctx = crypto_tfm_ctx(tfm);
 
-	if (!(alg = crypto_tfm_alg_name(tfm))) {
-		printk(KERN_ERR "Failed to get algorithm name.\n");
-		return -ENOENT;
-	}
-
 	fallback = crypto_alloc_shash(alg, 0, CRYPTO_ALG_NEED_FALLBACK);
 	if (IS_ERR(fallback)) {
 		printk(KERN_ERR
@@ -78,10 +70,18 @@ static int p8_ghash_init_tfm(struct cryp
 	crypto_shash_set_flags(fallback,
 			       crypto_shash_get_flags((struct crypto_shash
 						       *) tfm));
-	ctx->fallback = fallback;
 
-	shash_tfm->descsize = sizeof(struct p8_ghash_desc_ctx)
-	    + crypto_shash_descsize(fallback);
+	/* Check if the descsize defined in the algorithm is still enough. */
+	if (shash_tfm->descsize < sizeof(struct p8_ghash_desc_ctx)
+	    + crypto_shash_descsize(fallback)) {
+		printk(KERN_ERR
+		       "Desc size of the fallback implementation (%s) does not match the expected value: %lu vs %u\n",
+		       alg,
+		       shash_tfm->descsize - sizeof(struct p8_ghash_desc_ctx),
+		       crypto_shash_descsize(fallback));
+		return -EINVAL;
+	}
+	ctx->fallback = fallback;
 
 	return 0;
 }
@@ -113,15 +113,14 @@ static int p8_ghash_setkey(struct crypto
 {
 	struct p8_ghash_ctx *ctx = crypto_tfm_ctx(crypto_shash_tfm(tfm));
 
-	if (keylen != GHASH_KEY_LEN)
+	if (keylen != GHASH_BLOCK_SIZE)
 		return -EINVAL;
 
 	preempt_disable();
 	pagefault_disable();
-	enable_kernel_altivec();
 	enable_kernel_vsx();
-	enable_kernel_fp();
 	gcm_init_p8(ctx->htable, (const u64 *) key);
+	disable_kernel_vsx();
 	pagefault_enable();
 	preempt_enable();
 	return crypto_shash_setkey(ctx->fallback, key, keylen);
@@ -149,11 +148,10 @@ static int p8_ghash_update(struct shash_
 			       GHASH_DIGEST_SIZE - dctx->bytes);
 			preempt_disable();
 			pagefault_disable();
-			enable_kernel_altivec();
 			enable_kernel_vsx();
-			enable_kernel_fp();
 			gcm_ghash_p8(dctx->shash, ctx->htable,
 				     dctx->buffer, GHASH_DIGEST_SIZE);
+			disable_kernel_vsx();
 			pagefault_enable();
 			preempt_enable();
 			src += GHASH_DIGEST_SIZE - dctx->bytes;
@@ -164,10 +162,9 @@ static int p8_ghash_update(struct shash_
 		if (len) {
 			preempt_disable();
 			pagefault_disable();
-			enable_kernel_altivec();
 			enable_kernel_vsx();
-			enable_kernel_fp();
 			gcm_ghash_p8(dctx->shash, ctx->htable, src, len);
+			disable_kernel_vsx();
 			pagefault_enable();
 			preempt_enable();
 			src += len;
@@ -195,11 +192,10 @@ static int p8_ghash_final(struct shash_d
 				dctx->buffer[i] = 0;
 			preempt_disable();
 			pagefault_disable();
-			enable_kernel_altivec();
 			enable_kernel_vsx();
-			enable_kernel_fp();
 			gcm_ghash_p8(dctx->shash, ctx->htable,
 				     dctx->buffer, GHASH_DIGEST_SIZE);
+			disable_kernel_vsx();
 			pagefault_enable();
 			preempt_enable();
 			dctx->bytes = 0;
@@ -215,7 +211,8 @@ struct shash_alg p8_ghash_alg = {
 	.update = p8_ghash_update,
 	.final = p8_ghash_final,
 	.setkey = p8_ghash_setkey,
-	.descsize = sizeof(struct p8_ghash_desc_ctx),
+	.descsize = sizeof(struct p8_ghash_desc_ctx)
+		+ sizeof(struct ghash_desc_ctx),
 	.base = {
 		 .cra_name = "ghash",
 		 .cra_driver_name = "p8_ghash",
--- zfcpdump-kernel-4.4.orig/drivers/crypto/vmx/ppc-xlate.pl
+++ zfcpdump-kernel-4.4/drivers/crypto/vmx/ppc-xlate.pl
@@ -139,6 +139,26 @@ my $vmr = sub {
     "	vor	$vx,$vy,$vy";
 };
 
+# Some ABIs specify vrsave, special-purpose register #256, as reserved
+# for system use.
+my $no_vrsave = ($flavour =~ /linux-ppc64le/);
+my $mtspr = sub {
+    my ($f,$idx,$ra) = @_;
+    if ($idx == 256 && $no_vrsave) {
+	"	or	$ra,$ra,$ra";
+    } else {
+	"	mtspr	$idx,$ra";
+    }
+};
+my $mfspr = sub {
+    my ($f,$rd,$idx) = @_;
+    if ($idx == 256 && $no_vrsave) {
+	"	li	$rd,-1";
+    } else {
+	"	mfspr	$rd,$idx";
+    }
+};
+
 # PowerISA 2.06 stuff
 sub vsxmem_op {
     my ($f, $vrt, $ra, $rb, $op) = @_;
--- zfcpdump-kernel-4.4.orig/drivers/crypto/vmx/vmx.c
+++ zfcpdump-kernel-4.4/drivers/crypto/vmx/vmx.c
@@ -31,10 +31,12 @@ extern struct shash_alg p8_ghash_alg;
 extern struct crypto_alg p8_aes_alg;
 extern struct crypto_alg p8_aes_cbc_alg;
 extern struct crypto_alg p8_aes_ctr_alg;
+extern struct crypto_alg p8_aes_xts_alg;
 static struct crypto_alg *algs[] = {
 	&p8_aes_alg,
 	&p8_aes_cbc_alg,
 	&p8_aes_ctr_alg,
+	&p8_aes_xts_alg,
 	NULL,
 };
 
--- zfcpdump-kernel-4.4.orig/drivers/dma/at_xdmac.c
+++ zfcpdump-kernel-4.4/drivers/dma/at_xdmac.c
@@ -176,6 +176,7 @@
 #define AT_XDMAC_MAX_CHAN	0x20
 #define AT_XDMAC_MAX_CSIZE	16	/* 16 data */
 #define AT_XDMAC_MAX_DWIDTH	8	/* 64 bits */
+#define AT_XDMAC_RESIDUE_MAX_RETRIES	5
 
 #define AT_XDMAC_DMA_BUSWIDTHS\
 	(BIT(DMA_SLAVE_BUSWIDTH_UNDEFINED) |\
@@ -241,7 +242,7 @@ struct at_xdmac_lld {
 	u32		mbr_dus;	/* Destination Microblock Stride Register */
 };
 
-
+/* 64-bit alignment needed to update CNDA and CUBC registers in an atomic way. */
 struct at_xdmac_desc {
 	struct at_xdmac_lld		lld;
 	enum dma_transfer_direction	direction;
@@ -252,7 +253,7 @@ struct at_xdmac_desc {
 	unsigned int			xfer_size;
 	struct list_head		descs_list;
 	struct list_head		xfer_node;
-};
+} __aligned(sizeof(u64));
 
 static inline void __iomem *at_xdmac_chan_reg_base(struct at_xdmac *atxdmac, unsigned int chan_nb)
 {
@@ -1182,8 +1183,8 @@ static struct at_xdmac_desc *at_xdmac_me
 	desc->lld.mbr_cfg = chan_cc;
 
 	dev_dbg(chan2dev(chan),
-		"%s: lld: mbr_da=%pad, mbr_ds=%pad, mbr_ubc=0x%08x, mbr_cfg=0x%08x\n",
-		__func__, &desc->lld.mbr_da, &desc->lld.mbr_ds, desc->lld.mbr_ubc,
+		"%s: lld: mbr_da=%pad, mbr_ds=0x%08x, mbr_ubc=0x%08x, mbr_cfg=0x%08x\n",
+		__func__, &desc->lld.mbr_da, desc->lld.mbr_ds, desc->lld.mbr_ubc,
 		desc->lld.mbr_cfg);
 
 	return desc;
@@ -1383,10 +1384,11 @@ at_xdmac_tx_status(struct dma_chan *chan
 	struct at_xdmac_desc	*desc, *_desc;
 	struct list_head	*descs_list;
 	enum dma_status		ret;
-	int			residue;
-	u32			cur_nda, mask, value;
+	int			residue, retry;
+	u32			cur_nda, check_nda, cur_ubc, mask, value;
 	u8			dwidth = 0;
 	unsigned long		flags;
+	bool			initd;
 
 	ret = dma_cookie_status(chan, cookie, txstate);
 	if (ret == DMA_COMPLETE)
@@ -1411,7 +1413,16 @@ at_xdmac_tx_status(struct dma_chan *chan
 	residue = desc->xfer_size;
 	/*
 	 * Flush FIFO: only relevant when the transfer is source peripheral
-	 * synchronized.
+	 * synchronized. Flush is needed before reading CUBC because data in
+	 * the FIFO are not reported by CUBC. Reporting a residue of the
+	 * transfer length while we have data in FIFO can cause issue.
+	 * Usecase: atmel USART has a timeout which means I have received
+	 * characters but there is no more character received for a while. On
+	 * timeout, it requests the residue. If the data are in the DMA FIFO,
+	 * we will return a residue of the transfer length. It means no data
+	 * received. If an application is waiting for these data, it will hang
+	 * since we won't have another USART timeout without receiving new
+	 * data.
 	 */
 	mask = AT_XDMAC_CC_TYPE | AT_XDMAC_CC_DSYNC;
 	value = AT_XDMAC_CC_TYPE_PER_TRAN | AT_XDMAC_CC_DSYNC_PER2MEM;
@@ -1421,7 +1432,64 @@ at_xdmac_tx_status(struct dma_chan *chan
 			cpu_relax();
 	}
 
-	cur_nda = at_xdmac_chan_read(atchan, AT_XDMAC_CNDA) & 0xfffffffc;
+	/*
+	 * The easiest way to compute the residue should be to pause the DMA
+	 * but doing this can lead to miss some data as some devices don't
+	 * have FIFO.
+	 * We need to read several registers because:
+	 * - DMA is running therefore a descriptor change is possible while
+	 * reading these registers
+	 * - When the block transfer is done, the value of the CUBC register
+	 * is set to its initial value until the fetch of the next descriptor.
+	 * This value will corrupt the residue calculation so we have to skip
+	 * it.
+	 *
+	 * INITD --------                    ------------
+	 *              |____________________|
+	 *       _______________________  _______________
+	 * NDA       @desc2             \/   @desc3
+	 *       _______________________/\_______________
+	 *       __________  ___________  _______________
+	 * CUBC       0    \/ MAX desc1 \/  MAX desc2
+	 *       __________/\___________/\_______________
+	 *
+	 * Since descriptors are aligned on 64 bits, we can assume that
+	 * the update of NDA and CUBC is atomic.
+	 * Memory barriers are used to ensure the read order of the registers.
+	 * A max number of retries is set because unlikely it could never ends.
+	 */
+	for (retry = 0; retry < AT_XDMAC_RESIDUE_MAX_RETRIES; retry++) {
+		check_nda = at_xdmac_chan_read(atchan, AT_XDMAC_CNDA) & 0xfffffffc;
+		rmb();
+		initd = !!(at_xdmac_chan_read(atchan, AT_XDMAC_CC) & AT_XDMAC_CC_INITD);
+		rmb();
+		cur_ubc = at_xdmac_chan_read(atchan, AT_XDMAC_CUBC);
+		rmb();
+		cur_nda = at_xdmac_chan_read(atchan, AT_XDMAC_CNDA) & 0xfffffffc;
+		rmb();
+
+		if ((check_nda == cur_nda) && initd)
+			break;
+	}
+
+	if (unlikely(retry >= AT_XDMAC_RESIDUE_MAX_RETRIES)) {
+		ret = DMA_ERROR;
+		goto spin_unlock;
+	}
+
+	/*
+	 * Flush FIFO: only relevant when the transfer is source peripheral
+	 * synchronized. Another flush is needed here because CUBC is updated
+	 * when the controller sends the data write command. It can lead to
+	 * report data that are not written in the memory or the device. The
+	 * FIFO flush ensures that data are really written.
+	 */
+	if ((desc->lld.mbr_cfg & mask) == value) {
+		at_xdmac_write(atxdmac, AT_XDMAC_GSWF, atchan->mask);
+		while (!(at_xdmac_chan_read(atchan, AT_XDMAC_CIS) & AT_XDMAC_CIS_FIS))
+			cpu_relax();
+	}
+
 	/*
 	 * Remove size of all microblocks already transferred and the current
 	 * one. Then add the remaining size to transfer of the current
@@ -1434,7 +1502,7 @@ at_xdmac_tx_status(struct dma_chan *chan
 		if ((desc->lld.mbr_nda & 0xfffffffc) == cur_nda)
 			break;
 	}
-	residue += at_xdmac_chan_read(atchan, AT_XDMAC_CUBC) << dwidth;
+	residue += cur_ubc << dwidth;
 
 	dma_set_residue(txstate, residue);
 
@@ -1688,6 +1756,7 @@ static int at_xdmac_device_terminate_all
 	list_for_each_entry_safe(desc, _desc, &atchan->xfers_list, xfer_node)
 		at_xdmac_remove_xfer(atchan, desc);
 
+	clear_bit(AT_XDMAC_CHAN_IS_PAUSED, &atchan->status);
 	clear_bit(AT_XDMAC_CHAN_IS_CYCLIC, &atchan->status);
 	spin_unlock_irqrestore(&atchan->lock, flags);
 
@@ -1820,6 +1889,8 @@ static int atmel_xdmac_resume(struct dev
 		atchan = to_at_xdmac_chan(chan);
 		at_xdmac_chan_write(atchan, AT_XDMAC_CC, atchan->save_cc);
 		if (at_xdmac_chan_is_cyclic(atchan)) {
+			if (at_xdmac_chan_is_paused(atchan))
+				at_xdmac_device_resume(chan);
 			at_xdmac_chan_write(atchan, AT_XDMAC_CNDA, atchan->save_cnda);
 			at_xdmac_chan_write(atchan, AT_XDMAC_CNDC, atchan->save_cndc);
 			at_xdmac_chan_write(atchan, AT_XDMAC_CIE, atchan->save_cim);
@@ -1984,7 +2055,7 @@ err_dma_unregister:
 err_clk_disable:
 	clk_disable_unprepare(atxdmac->clk);
 err_free_irq:
-	free_irq(atxdmac->irq, atxdmac->dma.dev);
+	free_irq(atxdmac->irq, atxdmac);
 	return ret;
 }
 
@@ -2000,7 +2071,7 @@ static int at_xdmac_remove(struct platfo
 
 	synchronize_irq(atxdmac->irq);
 
-	free_irq(atxdmac->irq, atxdmac->dma.dev);
+	free_irq(atxdmac->irq, atxdmac);
 
 	for (i = 0; i < atxdmac->dma.chancnt; i++) {
 		struct at_xdmac_chan *atchan = &atxdmac->chan[i];
--- zfcpdump-kernel-4.4.orig/drivers/dma/dw/core.c
+++ zfcpdump-kernel-4.4/drivers/dma/dw/core.c
@@ -130,26 +130,14 @@ static void dwc_desc_put(struct dw_dma_c
 static void dwc_initialize(struct dw_dma_chan *dwc)
 {
 	struct dw_dma *dw = to_dw_dma(dwc->chan.device);
-	struct dw_dma_slave *dws = dwc->chan.private;
 	u32 cfghi = DWC_CFGH_FIFO_MODE;
 	u32 cfglo = DWC_CFGL_CH_PRIOR(dwc->priority);
 
 	if (dwc->initialized == true)
 		return;
 
-	if (dws) {
-		/*
-		 * We need controller-specific data to set up slave
-		 * transfers.
-		 */
-		BUG_ON(!dws->dma_dev || dws->dma_dev != dw->dma.dev);
-
-		cfghi |= DWC_CFGH_DST_PER(dws->dst_id);
-		cfghi |= DWC_CFGH_SRC_PER(dws->src_id);
-	} else {
-		cfghi |= DWC_CFGH_DST_PER(dwc->dst_id);
-		cfghi |= DWC_CFGH_SRC_PER(dwc->src_id);
-	}
+	cfghi |= DWC_CFGH_DST_PER(dwc->dst_id);
+	cfghi |= DWC_CFGH_SRC_PER(dwc->src_id);
 
 	channel_writel(dwc, CFG_LO, cfglo);
 	channel_writel(dwc, CFG_HI, cfghi);
@@ -536,16 +524,17 @@ EXPORT_SYMBOL(dw_dma_get_dst_addr);
 
 /* Called with dwc->lock held and all DMAC interrupts disabled */
 static void dwc_handle_cyclic(struct dw_dma *dw, struct dw_dma_chan *dwc,
-		u32 status_err, u32 status_xfer)
+		u32 status_block, u32 status_err, u32 status_xfer)
 {
 	unsigned long flags;
 
-	if (dwc->mask) {
+	if (status_block & dwc->mask) {
 		void (*callback)(void *param);
 		void *callback_param;
 
 		dev_vdbg(chan2dev(&dwc->chan), "new cyclic period llp 0x%08x\n",
 				channel_readl(dwc, LLP));
+		dma_writel(dw, CLEAR.BLOCK, dwc->mask);
 
 		callback = dwc->cdesc->period_callback;
 		callback_param = dwc->cdesc->period_callback_param;
@@ -577,6 +566,7 @@ static void dwc_handle_cyclic(struct dw_
 		channel_writel(dwc, CTL_LO, 0);
 		channel_writel(dwc, CTL_HI, 0);
 
+		dma_writel(dw, CLEAR.BLOCK, dwc->mask);
 		dma_writel(dw, CLEAR.ERROR, dwc->mask);
 		dma_writel(dw, CLEAR.XFER, dwc->mask);
 
@@ -585,6 +575,9 @@ static void dwc_handle_cyclic(struct dw_
 
 		spin_unlock_irqrestore(&dwc->lock, flags);
 	}
+
+	/* Re-enable interrupts */
+	channel_set_bit(dw, MASK.BLOCK, dwc->mask);
 }
 
 /* ------------------------------------------------------------------------- */
@@ -593,10 +586,12 @@ static void dw_dma_tasklet(unsigned long
 {
 	struct dw_dma *dw = (struct dw_dma *)data;
 	struct dw_dma_chan *dwc;
+	u32 status_block;
 	u32 status_xfer;
 	u32 status_err;
 	int i;
 
+	status_block = dma_readl(dw, RAW.BLOCK);
 	status_xfer = dma_readl(dw, RAW.XFER);
 	status_err = dma_readl(dw, RAW.ERROR);
 
@@ -605,16 +600,15 @@ static void dw_dma_tasklet(unsigned long
 	for (i = 0; i < dw->dma.chancnt; i++) {
 		dwc = &dw->chan[i];
 		if (test_bit(DW_DMA_IS_CYCLIC, &dwc->flags))
-			dwc_handle_cyclic(dw, dwc, status_err, status_xfer);
+			dwc_handle_cyclic(dw, dwc, status_block, status_err,
+					status_xfer);
 		else if (status_err & (1 << i))
 			dwc_handle_error(dw, dwc);
 		else if (status_xfer & (1 << i))
 			dwc_scan_descriptors(dw, dwc);
 	}
 
-	/*
-	 * Re-enable interrupts.
-	 */
+	/* Re-enable interrupts */
 	channel_set_bit(dw, MASK.XFER, dw->all_chan_mask);
 	channel_set_bit(dw, MASK.ERROR, dw->all_chan_mask);
 }
@@ -635,6 +629,7 @@ static irqreturn_t dw_dma_interrupt(int
 	 * softirq handler.
 	 */
 	channel_clear_bit(dw, MASK.XFER, dw->all_chan_mask);
+	channel_clear_bit(dw, MASK.BLOCK, dw->all_chan_mask);
 	channel_clear_bit(dw, MASK.ERROR, dw->all_chan_mask);
 
 	status = dma_readl(dw, STATUS_INT);
@@ -645,6 +640,7 @@ static irqreturn_t dw_dma_interrupt(int
 
 		/* Try to recover */
 		channel_clear_bit(dw, MASK.XFER, (1 << 8) - 1);
+		channel_clear_bit(dw, MASK.BLOCK, (1 << 8) - 1);
 		channel_clear_bit(dw, MASK.SRC_TRAN, (1 << 8) - 1);
 		channel_clear_bit(dw, MASK.DST_TRAN, (1 << 8) - 1);
 		channel_clear_bit(dw, MASK.ERROR, (1 << 8) - 1);
@@ -928,7 +924,7 @@ bool dw_dma_filter(struct dma_chan *chan
 	struct dw_dma_chan *dwc = to_dw_dma_chan(chan);
 	struct dw_dma_slave *dws = param;
 
-	if (!dws || dws->dma_dev != chan->device->dev)
+	if (dws->dma_dev != chan->device->dev)
 		return false;
 
 	/* We have to copy data since dws can be temporary storage */
@@ -1111,6 +1107,7 @@ static void dw_dma_off(struct dw_dma *dw
 	dma_writel(dw, CFG, 0);
 
 	channel_clear_bit(dw, MASK.XFER, dw->all_chan_mask);
+	channel_clear_bit(dw, MASK.BLOCK, dw->all_chan_mask);
 	channel_clear_bit(dw, MASK.SRC_TRAN, dw->all_chan_mask);
 	channel_clear_bit(dw, MASK.DST_TRAN, dw->all_chan_mask);
 	channel_clear_bit(dw, MASK.ERROR, dw->all_chan_mask);
@@ -1151,6 +1148,14 @@ static int dwc_alloc_chan_resources(stru
 	 * doesn't mean what you think it means), and status writeback.
 	 */
 
+	/*
+	 * We need controller-specific data to set up slave transfers.
+	 */
+	if (chan->private && !dw_dma_filter(chan, chan->private)) {
+		dev_warn(chan2dev(chan), "Wrong controller-specific data\n");
+		return -EINVAL;
+	}
+
 	/* Enable controller here if needed */
 	if (!dw->in_use)
 		dw_dma_on(dw);
@@ -1212,10 +1217,19 @@ static void dwc_free_chan_resources(stru
 	spin_lock_irqsave(&dwc->lock, flags);
 	list_splice_init(&dwc->free_list, &list);
 	dwc->descs_allocated = 0;
+
+	/* Clear custom channel configuration */
+	dwc->src_id = 0;
+	dwc->dst_id = 0;
+
+	dwc->src_master = 0;
+	dwc->dst_master = 0;
+
 	dwc->initialized = false;
 
 	/* Disable interrupts */
 	channel_clear_bit(dw, MASK.XFER, dwc->mask);
+	channel_clear_bit(dw, MASK.BLOCK, dwc->mask);
 	channel_clear_bit(dw, MASK.ERROR, dwc->mask);
 
 	spin_unlock_irqrestore(&dwc->lock, flags);
@@ -1245,7 +1259,7 @@ static void dwc_free_chan_resources(stru
 int dw_dma_cyclic_start(struct dma_chan *chan)
 {
 	struct dw_dma_chan	*dwc = to_dw_dma_chan(chan);
-	struct dw_dma		*dw = to_dw_dma(dwc->chan.device);
+	struct dw_dma		*dw = to_dw_dma(chan->device);
 	unsigned long		flags;
 
 	if (!test_bit(DW_DMA_IS_CYCLIC, &dwc->flags)) {
@@ -1255,25 +1269,10 @@ int dw_dma_cyclic_start(struct dma_chan
 
 	spin_lock_irqsave(&dwc->lock, flags);
 
-	/* Assert channel is idle */
-	if (dma_readl(dw, CH_EN) & dwc->mask) {
-		dev_err(chan2dev(&dwc->chan),
-			"%s: BUG: Attempted to start non-idle channel\n",
-			__func__);
-		dwc_dump_chan_regs(dwc);
-		spin_unlock_irqrestore(&dwc->lock, flags);
-		return -EBUSY;
-	}
+	/* Enable interrupts to perform cyclic transfer */
+	channel_set_bit(dw, MASK.BLOCK, dwc->mask);
 
-	dma_writel(dw, CLEAR.ERROR, dwc->mask);
-	dma_writel(dw, CLEAR.XFER, dwc->mask);
-
-	/* Setup DMAC channel registers */
-	channel_writel(dwc, LLP, dwc->cdesc->desc[0]->txd.phys);
-	channel_writel(dwc, CTL_LO, DWC_CTLL_LLP_D_EN | DWC_CTLL_LLP_S_EN);
-	channel_writel(dwc, CTL_HI, 0);
-
-	channel_set_bit(dw, CH_EN, dwc->mask);
+	dwc_dostart(dwc, dwc->cdesc->desc[0]);
 
 	spin_unlock_irqrestore(&dwc->lock, flags);
 
@@ -1479,6 +1478,7 @@ void dw_dma_cyclic_free(struct dma_chan
 
 	dwc_chan_disable(dw, dwc);
 
+	dma_writel(dw, CLEAR.BLOCK, dwc->mask);
 	dma_writel(dw, CLEAR.ERROR, dwc->mask);
 	dma_writel(dw, CLEAR.XFER, dwc->mask);
 
@@ -1567,9 +1567,6 @@ int dw_dma_probe(struct dw_dma_chip *chi
 	/* Force dma off, just in case */
 	dw_dma_off(dw);
 
-	/* Disable BLOCK interrupts as well */
-	channel_clear_bit(dw, MASK.BLOCK, dw->all_chan_mask);
-
 	/* Create a pool of consistent memory blocks for hardware descriptors */
 	dw->desc_pool = dmam_pool_create("dw_dmac_desc_pool", chip->dev,
 					 sizeof(struct dw_desc), 4, 0);
--- zfcpdump-kernel-4.4.orig/drivers/dma/dw/platform.c
+++ zfcpdump-kernel-4.4/drivers/dma/dw/platform.c
@@ -239,7 +239,19 @@ static void dw_shutdown(struct platform_
 {
 	struct dw_dma_chip *chip = platform_get_drvdata(pdev);
 
+	/*
+	 * We have to call dw_dma_disable() to stop any ongoing transfer. On
+	 * some platforms we can't do that since DMA device is powered off.
+	 * Moreover we have no possibility to check if the platform is affected
+	 * or not. That's why we call pm_runtime_get_sync() / pm_runtime_put()
+	 * unconditionally. On the other hand we can't use
+	 * pm_runtime_suspended() because runtime PM framework is not fully
+	 * used by the driver.
+	 */
+	pm_runtime_get_sync(chip->dev);
 	dw_dma_disable(chip);
+	pm_runtime_put_sync_suspend(chip->dev);
+
 	clk_disable_unprepare(chip->clk);
 }
 
--- zfcpdump-kernel-4.4.orig/drivers/dma/hsu/hsu.c
+++ zfcpdump-kernel-4.4/drivers/dma/hsu/hsu.c
@@ -135,7 +135,7 @@ static u32 hsu_dma_chan_get_sr(struct hs
 	sr = hsu_chan_readl(hsuc, HSU_CH_SR);
 	spin_unlock_irqrestore(&hsuc->vchan.lock, flags);
 
-	return sr;
+	return sr & ~(HSU_CH_SR_DESCE_ANY | HSU_CH_SR_CDESC_ANY);
 }
 
 irqreturn_t hsu_dma_irq(struct hsu_dma_chip *chip, unsigned short nr)
--- zfcpdump-kernel-4.4.orig/drivers/dma/hsu/hsu.h
+++ zfcpdump-kernel-4.4/drivers/dma/hsu/hsu.h
@@ -41,6 +41,9 @@
 #define HSU_CH_SR_DESCTO(x)	BIT(8 + (x))
 #define HSU_CH_SR_DESCTO_ANY	(BIT(11) | BIT(10) | BIT(9) | BIT(8))
 #define HSU_CH_SR_CHE		BIT(15)
+#define HSU_CH_SR_DESCE(x)	BIT(16 + (x))
+#define HSU_CH_SR_DESCE_ANY	(BIT(19) | BIT(18) | BIT(17) | BIT(16))
+#define HSU_CH_SR_CDESC_ANY	(BIT(31) | BIT(30))
 
 /* Bits in HSU_CH_CR */
 #define HSU_CH_CR_CHA		BIT(0)
--- zfcpdump-kernel-4.4.orig/drivers/dma/ioat/prep.c
+++ zfcpdump-kernel-4.4/drivers/dma/ioat/prep.c
@@ -26,7 +26,7 @@
 #include "hw.h"
 #include "dma.h"
 
-#define MAX_SCF	1024
+#define MAX_SCF	256
 
 /* provide a lookup table for setting the source address in the base or
  * extended descriptor of an xor or pq descriptor
--- zfcpdump-kernel-4.4.orig/drivers/dma/pxa_dma.c
+++ zfcpdump-kernel-4.4/drivers/dma/pxa_dma.c
@@ -122,6 +122,7 @@ struct pxad_chan {
 struct pxad_device {
 	struct dma_device		slave;
 	int				nr_chans;
+	int				nr_requestors;
 	void __iomem			*base;
 	struct pxad_phy			*phys;
 	spinlock_t			phy_lock;	/* Phy association */
@@ -473,7 +474,7 @@ static void pxad_free_phy(struct pxad_ch
 		return;
 
 	/* clear the channel mapping in DRCMR */
-	if (chan->drcmr <= DRCMR_CHLNUM) {
+	if (chan->drcmr <= pdev->nr_requestors) {
 		reg = pxad_drcmr(chan->drcmr);
 		writel_relaxed(0, chan->phy->base + reg);
 	}
@@ -509,6 +510,7 @@ static bool is_running_chan_misaligned(s
 
 static void phy_enable(struct pxad_phy *phy, bool misaligned)
 {
+	struct pxad_device *pdev;
 	u32 reg, dalgn;
 
 	if (!phy->vchan)
@@ -518,7 +520,8 @@ static void phy_enable(struct pxad_phy *
 		"%s(); phy=%p(%d) misaligned=%d\n", __func__,
 		phy, phy->idx, misaligned);
 
-	if (phy->vchan->drcmr <= DRCMR_CHLNUM) {
+	pdev = to_pxad_dev(phy->vchan->vc.chan.device);
+	if (phy->vchan->drcmr <= pdev->nr_requestors) {
 		reg = pxad_drcmr(phy->vchan->drcmr);
 		writel_relaxed(DRCMR_MAPVLD | phy->idx, phy->base + reg);
 	}
@@ -583,6 +586,8 @@ static void set_updater_desc(struct pxad
 		(PXA_DCMD_LENGTH & sizeof(u32));
 	if (flags & DMA_PREP_INTERRUPT)
 		updater->dcmd |= PXA_DCMD_ENDIRQEN;
+	if (sw_desc->cyclic)
+		sw_desc->hw_desc[sw_desc->nb_desc - 2]->ddadr = sw_desc->first;
 }
 
 static bool is_desc_completed(struct virt_dma_desc *vd)
@@ -673,6 +678,10 @@ static irqreturn_t pxad_chan_handler(int
 		dev_dbg(&chan->vc.chan.dev->device,
 			"%s(): checking txd %p[%x]: completed=%d\n",
 			__func__, vd, vd->tx.cookie, is_desc_completed(vd));
+		if (to_pxad_sw_desc(vd)->cyclic) {
+			vchan_cyclic_callback(vd);
+			break;
+		}
 		if (is_desc_completed(vd)) {
 			list_del(&vd->node);
 			vchan_cookie_complete(vd);
@@ -908,6 +917,7 @@ static void pxad_get_config(struct pxad_
 {
 	u32 maxburst = 0, dev_addr = 0;
 	enum dma_slave_buswidth width = DMA_SLAVE_BUSWIDTH_UNDEFINED;
+	struct pxad_device *pdev = to_pxad_dev(chan->vc.chan.device);
 
 	*dcmd = 0;
 	if (dir == DMA_DEV_TO_MEM) {
@@ -916,7 +926,7 @@ static void pxad_get_config(struct pxad_
 		dev_addr = chan->cfg.src_addr;
 		*dev_src = dev_addr;
 		*dcmd |= PXA_DCMD_INCTRGADDR;
-		if (chan->drcmr <= DRCMR_CHLNUM)
+		if (chan->drcmr <= pdev->nr_requestors)
 			*dcmd |= PXA_DCMD_FLOWSRC;
 	}
 	if (dir == DMA_MEM_TO_DEV) {
@@ -925,7 +935,7 @@ static void pxad_get_config(struct pxad_
 		dev_addr = chan->cfg.dst_addr;
 		*dev_dst = dev_addr;
 		*dcmd |= PXA_DCMD_INCSRCADDR;
-		if (chan->drcmr <= DRCMR_CHLNUM)
+		if (chan->drcmr <= pdev->nr_requestors)
 			*dcmd |= PXA_DCMD_FLOWTRG;
 	}
 	if (dir == DMA_MEM_TO_MEM)
@@ -1080,7 +1090,7 @@ pxad_prep_dma_cyclic(struct dma_chan *dc
 		return NULL;
 
 	pxad_get_config(chan, dir, &dcmd, &dsadr, &dtadr);
-	dcmd |= PXA_DCMD_ENDIRQEN | (PXA_DCMD_LENGTH | period_len);
+	dcmd |= PXA_DCMD_ENDIRQEN | (PXA_DCMD_LENGTH & period_len);
 	dev_dbg(&chan->vc.chan.dev->device,
 		"%s(): buf_addr=0x%lx len=%zu period=%zu dir=%d flags=%lx\n",
 		__func__, (unsigned long)buf_addr, len, period_len, dir, flags);
@@ -1335,13 +1345,15 @@ static struct dma_chan *pxad_dma_xlate(s
 
 static int pxad_init_dmadev(struct platform_device *op,
 			    struct pxad_device *pdev,
-			    unsigned int nr_phy_chans)
+			    unsigned int nr_phy_chans,
+			    unsigned int nr_requestors)
 {
 	int ret;
 	unsigned int i;
 	struct pxad_chan *c;
 
 	pdev->nr_chans = nr_phy_chans;
+	pdev->nr_requestors = nr_requestors;
 	INIT_LIST_HEAD(&pdev->slave.channels);
 	pdev->slave.device_alloc_chan_resources = pxad_alloc_chan_resources;
 	pdev->slave.device_free_chan_resources = pxad_free_chan_resources;
@@ -1376,7 +1388,7 @@ static int pxad_probe(struct platform_de
 	const struct of_device_id *of_id;
 	struct mmp_dma_platdata *pdata = dev_get_platdata(&op->dev);
 	struct resource *iores;
-	int ret, dma_channels = 0;
+	int ret, dma_channels = 0, nb_requestors = 0;
 	const enum dma_slave_buswidth widths =
 		DMA_SLAVE_BUSWIDTH_1_BYTE   | DMA_SLAVE_BUSWIDTH_2_BYTES |
 		DMA_SLAVE_BUSWIDTH_4_BYTES;
@@ -1393,13 +1405,23 @@ static int pxad_probe(struct platform_de
 		return PTR_ERR(pdev->base);
 
 	of_id = of_match_device(pxad_dt_ids, &op->dev);
-	if (of_id)
+	if (of_id) {
 		of_property_read_u32(op->dev.of_node, "#dma-channels",
 				     &dma_channels);
-	else if (pdata && pdata->dma_channels)
+		ret = of_property_read_u32(op->dev.of_node, "#dma-requests",
+					   &nb_requestors);
+		if (ret) {
+			dev_warn(pdev->slave.dev,
+				 "#dma-requests set to default 32 as missing in OF: %d",
+				 ret);
+			nb_requestors = 32;
+		};
+	} else if (pdata && pdata->dma_channels) {
 		dma_channels = pdata->dma_channels;
-	else
+		nb_requestors = pdata->nb_requestors;
+	} else {
 		dma_channels = 32;	/* default 32 channel */
+	}
 
 	dma_cap_set(DMA_SLAVE, pdev->slave.cap_mask);
 	dma_cap_set(DMA_MEMCPY, pdev->slave.cap_mask);
@@ -1416,7 +1438,7 @@ static int pxad_probe(struct platform_de
 	pdev->slave.residue_granularity = DMA_RESIDUE_GRANULARITY_DESCRIPTOR;
 
 	pdev->slave.dev = &op->dev;
-	ret = pxad_init_dmadev(op, pdev, dma_channels);
+	ret = pxad_init_dmadev(op, pdev, dma_channels, nb_requestors);
 	if (ret) {
 		dev_err(pdev->slave.dev, "unable to register\n");
 		return ret;
@@ -1435,7 +1457,8 @@ static int pxad_probe(struct platform_de
 
 	platform_set_drvdata(op, pdev);
 	pxad_init_debugfs(pdev);
-	dev_info(pdev->slave.dev, "initialized %d channels\n", dma_channels);
+	dev_info(pdev->slave.dev, "initialized %d channels on %d requestors\n",
+		 dma_channels, nb_requestors);
 	return 0;
 }
 
--- zfcpdump-kernel-4.4.orig/drivers/dma/sh/usb-dmac.c
+++ zfcpdump-kernel-4.4/drivers/dma/sh/usb-dmac.c
@@ -600,27 +600,30 @@ static irqreturn_t usb_dmac_isr_channel(
 {
 	struct usb_dmac_chan *chan = dev;
 	irqreturn_t ret = IRQ_NONE;
-	u32 mask = USB_DMACHCR_TE;
-	u32 check_bits = USB_DMACHCR_TE | USB_DMACHCR_SP;
+	u32 mask = 0;
 	u32 chcr;
+	bool xfer_end = false;
 
 	spin_lock(&chan->vc.lock);
 
 	chcr = usb_dmac_chan_read(chan, USB_DMACHCR);
-	if (chcr & check_bits)
-		mask |= USB_DMACHCR_DE | check_bits;
+	if (chcr & (USB_DMACHCR_TE | USB_DMACHCR_SP)) {
+		mask |= USB_DMACHCR_DE | USB_DMACHCR_TE | USB_DMACHCR_SP;
+		if (chcr & USB_DMACHCR_DE)
+			xfer_end = true;
+		ret |= IRQ_HANDLED;
+	}
 	if (chcr & USB_DMACHCR_NULL) {
 		/* An interruption of TE will happen after we set FTE */
 		mask |= USB_DMACHCR_NULL;
 		chcr |= USB_DMACHCR_FTE;
 		ret |= IRQ_HANDLED;
 	}
-	usb_dmac_chan_write(chan, USB_DMACHCR, chcr & ~mask);
+	if (mask)
+		usb_dmac_chan_write(chan, USB_DMACHCR, chcr & ~mask);
 
-	if (chcr & check_bits) {
+	if (xfer_end)
 		usb_dmac_isr_transfer_end(chan);
-		ret |= IRQ_HANDLED;
-	}
 
 	spin_unlock(&chan->vc.lock);
 
--- zfcpdump-kernel-4.4.orig/drivers/edac/Kconfig
+++ zfcpdump-kernel-4.4/drivers/edac/Kconfig
@@ -251,6 +251,14 @@ config EDAC_SBRIDGE
 	  Support for error detection and correction the Intel
 	  Sandy Bridge, Ivy Bridge and Haswell Integrated Memory Controllers.
 
+config EDAC_SKX
+	tristate "Intel Skylake server Integrated MC"
+	depends on EDAC_MM_EDAC && PCI && X86_64 && X86_MCE_INTEL
+	depends on PCI_MMCONFIG
+	help
+	  Support for error detection and correction the Intel
+	  Skylake server Integrated Memory Controllers.
+
 config EDAC_MPC85XX
 	tristate "Freescale MPC83xx / MPC85xx"
 	depends on EDAC_MM_EDAC && FSL_SOC
--- zfcpdump-kernel-4.4.orig/drivers/edac/Makefile
+++ zfcpdump-kernel-4.4/drivers/edac/Makefile
@@ -31,6 +31,7 @@ obj-$(CONFIG_EDAC_I5400)		+= i5400_edac.
 obj-$(CONFIG_EDAC_I7300)		+= i7300_edac.o
 obj-$(CONFIG_EDAC_I7CORE)		+= i7core_edac.o
 obj-$(CONFIG_EDAC_SBRIDGE)		+= sb_edac.o
+obj-$(CONFIG_EDAC_SKX)			+= skx_edac.o
 obj-$(CONFIG_EDAC_E7XXX)		+= e7xxx_edac.o
 obj-$(CONFIG_EDAC_E752X)		+= e752x_edac.o
 obj-$(CONFIG_EDAC_I82443BXGX)		+= i82443bxgx_edac.o
--- zfcpdump-kernel-4.4.orig/drivers/edac/amd64_edac.c
+++ zfcpdump-kernel-4.4/drivers/edac/amd64_edac.c
@@ -1452,7 +1452,7 @@ static u64 f1x_get_norm_dct_addr(struct
 	u64 chan_off;
 	u64 dram_base		= get_dram_base(pvt, range);
 	u64 hole_off		= f10_dhar_offset(pvt);
-	u64 dct_sel_base_off	= (pvt->dct_sel_hi & 0xFFFFFC00) << 16;
+	u64 dct_sel_base_off	= (u64)(pvt->dct_sel_hi & 0xFFFFFC00) << 16;
 
 	if (hi_rng) {
 		/*
--- zfcpdump-kernel-4.4.orig/drivers/edac/edac_device.c
+++ zfcpdump-kernel-4.4/drivers/edac/edac_device.c
@@ -435,16 +435,13 @@ void edac_device_workq_setup(struct edac
  */
 void edac_device_workq_teardown(struct edac_device_ctl_info *edac_dev)
 {
-	int status;
-
 	if (!edac_dev->edac_check)
 		return;
 
-	status = cancel_delayed_work(&edac_dev->work);
-	if (status == 0) {
-		/* workq instance might be running, wait for it */
-		flush_workqueue(edac_workqueue);
-	}
+	edac_dev->op_state = OP_OFFLINE;
+
+	cancel_delayed_work_sync(&edac_dev->work);
+	flush_workqueue(edac_workqueue);
 }
 
 /*
--- zfcpdump-kernel-4.4.orig/drivers/edac/edac_mc.c
+++ zfcpdump-kernel-4.4/drivers/edac/edac_mc.c
@@ -586,18 +586,10 @@ static void edac_mc_workq_setup(struct m
  */
 static void edac_mc_workq_teardown(struct mem_ctl_info *mci)
 {
-	int status;
-
-	if (mci->op_state != OP_RUNNING_POLL)
-		return;
-
-	status = cancel_delayed_work(&mci->work);
-	if (status == 0) {
-		edac_dbg(0, "not canceled, flush the queue\n");
+	mci->op_state = OP_OFFLINE;
 
-		/* workq instance might be running, wait for it */
-		flush_workqueue(edac_workqueue);
-	}
+	cancel_delayed_work_sync(&mci->work);
+	flush_workqueue(edac_workqueue);
 }
 
 /*
@@ -974,7 +966,7 @@ static void edac_inc_ue_error(struct mem
 	mci->ue_mc += count;
 
 	if (!enable_per_layer_report) {
-		mci->ce_noinfo_count += count;
+		mci->ue_noinfo_count += count;
 		return;
 	}
 
--- zfcpdump-kernel-4.4.orig/drivers/edac/edac_mc_sysfs.c
+++ zfcpdump-kernel-4.4/drivers/edac/edac_mc_sysfs.c
@@ -313,7 +313,6 @@ static struct device_type csrow_attr_typ
  * possible dynamic channel DIMM Label attribute files
  *
  */
-
 DEVICE_CHANNEL(ch0_dimm_label, S_IRUGO | S_IWUSR,
 	channel_dimm_label_show, channel_dimm_label_store, 0);
 DEVICE_CHANNEL(ch1_dimm_label, S_IRUGO | S_IWUSR,
@@ -326,6 +325,10 @@ DEVICE_CHANNEL(ch4_dimm_label, S_IRUGO |
 	channel_dimm_label_show, channel_dimm_label_store, 4);
 DEVICE_CHANNEL(ch5_dimm_label, S_IRUGO | S_IWUSR,
 	channel_dimm_label_show, channel_dimm_label_store, 5);
+DEVICE_CHANNEL(ch6_dimm_label, S_IRUGO | S_IWUSR,
+	channel_dimm_label_show, channel_dimm_label_store, 6);
+DEVICE_CHANNEL(ch7_dimm_label, S_IRUGO | S_IWUSR,
+	channel_dimm_label_show, channel_dimm_label_store, 7);
 
 /* Total possible dynamic DIMM Label attribute file table */
 static struct attribute *dynamic_csrow_dimm_attr[] = {
@@ -335,6 +338,8 @@ static struct attribute *dynamic_csrow_d
 	&dev_attr_legacy_ch3_dimm_label.attr.attr,
 	&dev_attr_legacy_ch4_dimm_label.attr.attr,
 	&dev_attr_legacy_ch5_dimm_label.attr.attr,
+	&dev_attr_legacy_ch6_dimm_label.attr.attr,
+	&dev_attr_legacy_ch7_dimm_label.attr.attr,
 	NULL
 };
 
@@ -351,6 +356,10 @@ DEVICE_CHANNEL(ch4_ce_count, S_IRUGO,
 		   channel_ce_count_show, NULL, 4);
 DEVICE_CHANNEL(ch5_ce_count, S_IRUGO,
 		   channel_ce_count_show, NULL, 5);
+DEVICE_CHANNEL(ch6_ce_count, S_IRUGO,
+		   channel_ce_count_show, NULL, 6);
+DEVICE_CHANNEL(ch7_ce_count, S_IRUGO,
+		   channel_ce_count_show, NULL, 7);
 
 /* Total possible dynamic ce_count attribute file table */
 static struct attribute *dynamic_csrow_ce_count_attr[] = {
@@ -360,6 +369,8 @@ static struct attribute *dynamic_csrow_c
 	&dev_attr_legacy_ch3_ce_count.attr.attr,
 	&dev_attr_legacy_ch4_ce_count.attr.attr,
 	&dev_attr_legacy_ch5_ce_count.attr.attr,
+	&dev_attr_legacy_ch6_ce_count.attr.attr,
+	&dev_attr_legacy_ch7_ce_count.attr.attr,
 	NULL
 };
 
@@ -371,9 +382,16 @@ static umode_t csrow_dev_is_visible(stru
 
 	if (idx >= csrow->nr_channels)
 		return 0;
+
+	if (idx >= ARRAY_SIZE(dynamic_csrow_ce_count_attr) - 1) {
+		WARN_ONCE(1, "idx: %d\n", idx);
+		return 0;
+	}
+
 	/* Only expose populated DIMMs */
 	if (!csrow->channels[idx]->dimm->nr_pages)
 		return 0;
+
 	return attr->mode;
 }
 
@@ -880,21 +898,26 @@ static struct device_type mci_attr_type
 int edac_create_sysfs_mci_device(struct mem_ctl_info *mci,
 				 const struct attribute_group **groups)
 {
+	char *name;
 	int i, err;
 
 	/*
 	 * The memory controller needs its own bus, in order to avoid
 	 * namespace conflicts at /sys/bus/edac.
 	 */
-	mci->bus->name = kasprintf(GFP_KERNEL, "mc%d", mci->mc_idx);
-	if (!mci->bus->name)
+	name = kasprintf(GFP_KERNEL, "mc%d", mci->mc_idx);
+	if (!name)
 		return -ENOMEM;
 
+	mci->bus->name = name;
+
 	edac_dbg(0, "creating bus %s\n", mci->bus->name);
 
 	err = bus_register(mci->bus);
-	if (err < 0)
-		goto fail_free_name;
+	if (err < 0) {
+		kfree(name);
+		return err;
+	}
 
 	/* get the /sys/devices/system/edac subsys reference */
 	mci->dev.type = &mci_attr_type;
@@ -961,8 +984,8 @@ fail_unregister_dimm:
 	device_unregister(&mci->dev);
 fail_unregister_bus:
 	bus_unregister(mci->bus);
-fail_free_name:
-	kfree(mci->bus->name);
+	kfree(name);
+
 	return err;
 }
 
@@ -993,10 +1016,12 @@ void edac_remove_sysfs_mci_device(struct
 
 void edac_unregister_sysfs(struct mem_ctl_info *mci)
 {
+	const char *name = mci->bus->name;
+
 	edac_dbg(1, "Unregistering device %s\n", dev_name(&mci->dev));
 	device_unregister(&mci->dev);
 	bus_unregister(mci->bus);
-	kfree(mci->bus->name);
+	kfree(name);
 }
 
 static void mc_attr_release(struct device *dev)
--- zfcpdump-kernel-4.4.orig/drivers/edac/edac_pci.c
+++ zfcpdump-kernel-4.4/drivers/edac/edac_pci.c
@@ -274,13 +274,12 @@ static void edac_pci_workq_setup(struct
  */
 static void edac_pci_workq_teardown(struct edac_pci_ctl_info *pci)
 {
-	int status;
-
 	edac_dbg(0, "\n");
 
-	status = cancel_delayed_work(&pci->work);
-	if (status == 0)
-		flush_workqueue(edac_workqueue);
+	pci->op_state = OP_OFFLINE;
+
+	cancel_delayed_work_sync(&pci->work);
+	flush_workqueue(edac_workqueue);
 }
 
 /*
--- zfcpdump-kernel-4.4.orig/drivers/edac/i7core_edac.c
+++ zfcpdump-kernel-4.4/drivers/edac/i7core_edac.c
@@ -1866,7 +1866,7 @@ static int i7core_mce_check_error(struct
 
 	i7_dev = get_i7core_dev(mce->socketid);
 	if (!i7_dev)
-		return NOTIFY_BAD;
+		return NOTIFY_DONE;
 
 	mci = i7_dev->mci;
 	pvt = mci->pvt_info;
--- zfcpdump-kernel-4.4.orig/drivers/edac/ie31200_edac.c
+++ zfcpdump-kernel-4.4/drivers/edac/ie31200_edac.c
@@ -17,6 +17,7 @@
  * 015c: Xeon E3-1200 v2/3rd Gen Core processor DRAM Controller
  * 0c04: Xeon E3-1200 v3/4th Gen Core Processor DRAM Controller
  * 0c08: Xeon E3-1200 v3 Processor DRAM Controller
+ * 1918: Xeon E3-1200 v5 Skylake Host Bridge/DRAM Registers
  *
  * Based on Intel specification:
  * http://www.intel.com/content/dam/www/public/us/en/documents/datasheets/xeon-e3-1200v3-vol-2-datasheet.pdf
@@ -55,6 +56,7 @@
 #define PCI_DEVICE_ID_INTEL_IE31200_HB_5 0x015c
 #define PCI_DEVICE_ID_INTEL_IE31200_HB_6 0x0c04
 #define PCI_DEVICE_ID_INTEL_IE31200_HB_7 0x0c08
+#define PCI_DEVICE_ID_INTEL_IE31200_HB_8 0x1918
 
 #define IE31200_DIMMS			4
 #define IE31200_RANKS			8
@@ -105,8 +107,11 @@
  *    1  Multiple Bit Error Status (MERRSTS)
  *    0  Correctable Error Status (CERRSTS)
  */
+
 #define IE31200_C0ECCERRLOG			0x40c8
 #define IE31200_C1ECCERRLOG			0x44c8
+#define IE31200_C0ECCERRLOG_SKL			0x4048
+#define IE31200_C1ECCERRLOG_SKL			0x4448
 #define IE31200_ECCERRLOG_CE			BIT(0)
 #define IE31200_ECCERRLOG_UE			BIT(1)
 #define IE31200_ECCERRLOG_RANK_BITS		GENMASK_ULL(28, 27)
@@ -123,17 +128,28 @@
 #define IE31200_CAPID0_DDPCD		BIT(6)
 #define IE31200_CAPID0_ECC		BIT(1)
 
-#define IE31200_MAD_DIMM_0_OFFSET	0x5004
-#define IE31200_MAD_DIMM_SIZE		GENMASK_ULL(7, 0)
-#define IE31200_MAD_DIMM_A_RANK		BIT(17)
-#define IE31200_MAD_DIMM_A_WIDTH	BIT(19)
-
-#define IE31200_PAGES(n)		(n << (28 - PAGE_SHIFT))
+#define IE31200_MAD_DIMM_0_OFFSET		0x5004
+#define IE31200_MAD_DIMM_0_OFFSET_SKL		0x500C
+#define IE31200_MAD_DIMM_SIZE			GENMASK_ULL(7, 0)
+#define IE31200_MAD_DIMM_A_RANK			BIT(17)
+#define IE31200_MAD_DIMM_A_RANK_SHIFT		17
+#define IE31200_MAD_DIMM_A_RANK_SKL		BIT(10)
+#define IE31200_MAD_DIMM_A_RANK_SKL_SHIFT	10
+#define IE31200_MAD_DIMM_A_WIDTH		BIT(19)
+#define IE31200_MAD_DIMM_A_WIDTH_SHIFT		19
+#define IE31200_MAD_DIMM_A_WIDTH_SKL		GENMASK_ULL(9, 8)
+#define IE31200_MAD_DIMM_A_WIDTH_SKL_SHIFT	8
+
+/* Skylake reports 1GB increments, everything else is 256MB */
+#define IE31200_PAGES(n, skl)	\
+	(n << (28 + (2 * skl) - PAGE_SHIFT))
 
 static int nr_channels;
 
 struct ie31200_priv {
 	void __iomem *window;
+	void __iomem *c0errlog;
+	void __iomem *c1errlog;
 };
 
 enum ie31200_chips {
@@ -157,9 +173,9 @@ static const struct ie31200_dev_info ie3
 };
 
 struct dimm_data {
-	u8 size; /* in 256MB multiples */
+	u8 size; /* in multiples of 256MB, except Skylake is 1GB */
 	u8 dual_rank : 1,
-	   x16_width : 1; /* 0 means x8 width */
+	   x16_width : 2; /* 0 means x8 width */
 };
 
 static int how_many_channels(struct pci_dev *pdev)
@@ -197,11 +213,10 @@ static bool ecc_capable(struct pci_dev *
 	return true;
 }
 
-static int eccerrlog_row(int channel, u64 log)
+static int eccerrlog_row(u64 log)
 {
-	int rank = ((log & IE31200_ECCERRLOG_RANK_BITS) >>
-		IE31200_ECCERRLOG_RANK_SHIFT);
-	return rank | (channel * IE31200_RANKS_PER_CHANNEL);
+	return ((log & IE31200_ECCERRLOG_RANK_BITS) >>
+				IE31200_ECCERRLOG_RANK_SHIFT);
 }
 
 static void ie31200_clear_error_info(struct mem_ctl_info *mci)
@@ -219,7 +234,6 @@ static void ie31200_get_and_clear_error_
 {
 	struct pci_dev *pdev;
 	struct ie31200_priv *priv = mci->pvt_info;
-	void __iomem *window = priv->window;
 
 	pdev = to_pci_dev(mci->pdev);
 
@@ -232,9 +246,9 @@ static void ie31200_get_and_clear_error_
 	if (!(info->errsts & IE31200_ERRSTS_BITS))
 		return;
 
-	info->eccerrlog[0] = lo_hi_readq(window + IE31200_C0ECCERRLOG);
+	info->eccerrlog[0] = lo_hi_readq(priv->c0errlog);
 	if (nr_channels == 2)
-		info->eccerrlog[1] = lo_hi_readq(window + IE31200_C1ECCERRLOG);
+		info->eccerrlog[1] = lo_hi_readq(priv->c1errlog);
 
 	pci_read_config_word(pdev, IE31200_ERRSTS, &info->errsts2);
 
@@ -245,10 +259,10 @@ static void ie31200_get_and_clear_error_
 	 * should be UE info.
 	 */
 	if ((info->errsts ^ info->errsts2) & IE31200_ERRSTS_BITS) {
-		info->eccerrlog[0] = lo_hi_readq(window + IE31200_C0ECCERRLOG);
+		info->eccerrlog[0] = lo_hi_readq(priv->c0errlog);
 		if (nr_channels == 2)
 			info->eccerrlog[1] =
-				lo_hi_readq(window + IE31200_C1ECCERRLOG);
+				lo_hi_readq(priv->c1errlog);
 	}
 
 	ie31200_clear_error_info(mci);
@@ -274,14 +288,14 @@ static void ie31200_process_error_info(s
 		if (log & IE31200_ECCERRLOG_UE) {
 			edac_mc_handle_error(HW_EVENT_ERR_UNCORRECTED, mci, 1,
 					     0, 0, 0,
-					     eccerrlog_row(channel, log),
+					     eccerrlog_row(log),
 					     channel, -1,
 					     "ie31200 UE", "");
 		} else if (log & IE31200_ECCERRLOG_CE) {
 			edac_mc_handle_error(HW_EVENT_ERR_CORRECTED, mci, 1,
 					     0, 0,
 					     IE31200_ECCERRLOG_SYNDROME(log),
-					     eccerrlog_row(channel, log),
+					     eccerrlog_row(log),
 					     channel, -1,
 					     "ie31200 CE", "");
 		}
@@ -326,6 +340,33 @@ static void __iomem *ie31200_map_mchbar(
 	return window;
 }
 
+static void __skl_populate_dimm_info(struct dimm_data *dd, u32 addr_decode,
+				     int chan)
+{
+	dd->size = (addr_decode >> (chan << 4)) & IE31200_MAD_DIMM_SIZE;
+	dd->dual_rank = (addr_decode & (IE31200_MAD_DIMM_A_RANK_SKL << (chan << 4))) ? 1 : 0;
+	dd->x16_width = ((addr_decode & (IE31200_MAD_DIMM_A_WIDTH_SKL << (chan << 4))) >>
+				(IE31200_MAD_DIMM_A_WIDTH_SKL_SHIFT + (chan << 4)));
+}
+
+static void __populate_dimm_info(struct dimm_data *dd, u32 addr_decode,
+				 int chan)
+{
+	dd->size = (addr_decode >> (chan << 3)) & IE31200_MAD_DIMM_SIZE;
+	dd->dual_rank = (addr_decode & (IE31200_MAD_DIMM_A_RANK << chan)) ? 1 : 0;
+	dd->x16_width = (addr_decode & (IE31200_MAD_DIMM_A_WIDTH << chan)) ? 1 : 0;
+}
+
+static void populate_dimm_info(struct dimm_data *dd, u32 addr_decode, int chan,
+			       bool skl)
+{
+	if (skl)
+		__skl_populate_dimm_info(dd, addr_decode, chan);
+	else
+		__populate_dimm_info(dd, addr_decode, chan);
+}
+
+
 static int ie31200_probe1(struct pci_dev *pdev, int dev_idx)
 {
 	int i, j, ret;
@@ -334,7 +375,8 @@ static int ie31200_probe1(struct pci_dev
 	struct dimm_data dimm_info[IE31200_CHANNELS][IE31200_DIMMS_PER_CHANNEL];
 	void __iomem *window;
 	struct ie31200_priv *priv;
-	u32 addr_decode;
+	u32 addr_decode, mad_offset;
+	bool skl = (pdev->device == PCI_DEVICE_ID_INTEL_IE31200_HB_8);
 
 	edac_dbg(0, "MC:\n");
 
@@ -363,7 +405,10 @@ static int ie31200_probe1(struct pci_dev
 
 	edac_dbg(3, "MC: init mci\n");
 	mci->pdev = &pdev->dev;
-	mci->mtype_cap = MEM_FLAG_DDR3;
+	if (skl)
+		mci->mtype_cap = MEM_FLAG_DDR4;
+	else
+		mci->mtype_cap = MEM_FLAG_DDR3;
 	mci->edac_ctl_cap = EDAC_FLAG_SECDED;
 	mci->edac_cap = EDAC_FLAG_SECDED;
 	mci->mod_name = EDAC_MOD_STR;
@@ -374,19 +419,24 @@ static int ie31200_probe1(struct pci_dev
 	mci->ctl_page_to_phys = NULL;
 	priv = mci->pvt_info;
 	priv->window = window;
+	if (skl) {
+		priv->c0errlog = window + IE31200_C0ECCERRLOG_SKL;
+		priv->c1errlog = window + IE31200_C1ECCERRLOG_SKL;
+		mad_offset = IE31200_MAD_DIMM_0_OFFSET_SKL;
+	} else {
+		priv->c0errlog = window + IE31200_C0ECCERRLOG;
+		priv->c1errlog = window + IE31200_C1ECCERRLOG;
+		mad_offset = IE31200_MAD_DIMM_0_OFFSET;
+	}
 
 	/* populate DIMM info */
 	for (i = 0; i < IE31200_CHANNELS; i++) {
-		addr_decode = readl(window + IE31200_MAD_DIMM_0_OFFSET +
+		addr_decode = readl(window + mad_offset +
 					(i * 4));
 		edac_dbg(0, "addr_decode: 0x%x\n", addr_decode);
 		for (j = 0; j < IE31200_DIMMS_PER_CHANNEL; j++) {
-			dimm_info[i][j].size = (addr_decode >> (j * 8)) &
-						IE31200_MAD_DIMM_SIZE;
-			dimm_info[i][j].dual_rank = (addr_decode &
-				(IE31200_MAD_DIMM_A_RANK << j)) ? 1 : 0;
-			dimm_info[i][j].x16_width = (addr_decode &
-				(IE31200_MAD_DIMM_A_WIDTH << j)) ? 1 : 0;
+			populate_dimm_info(&dimm_info[i][j], addr_decode, j,
+					   skl);
 			edac_dbg(0, "size: 0x%x, rank: %d, width: %d\n",
 				 dimm_info[i][j].size,
 				 dimm_info[i][j].dual_rank,
@@ -405,7 +455,7 @@ static int ie31200_probe1(struct pci_dev
 			struct dimm_info *dimm;
 			unsigned long nr_pages;
 
-			nr_pages = IE31200_PAGES(dimm_info[j][i].size);
+			nr_pages = IE31200_PAGES(dimm_info[j][i].size, skl);
 			if (nr_pages == 0)
 				continue;
 
@@ -417,7 +467,10 @@ static int ie31200_probe1(struct pci_dev
 				dimm->nr_pages = nr_pages;
 				edac_dbg(0, "set nr pages: 0x%lx\n", nr_pages);
 				dimm->grain = 8; /* just a guess */
-				dimm->mtype = MEM_DDR3;
+				if (skl)
+					dimm->mtype = MEM_DDR4;
+				else
+					dimm->mtype = MEM_DDR3;
 				dimm->dtype = DEV_UNKNOWN;
 				dimm->edac_mode = EDAC_UNKNOWN;
 			}
@@ -426,7 +479,10 @@ static int ie31200_probe1(struct pci_dev
 			dimm->nr_pages = nr_pages;
 			edac_dbg(0, "set nr pages: 0x%lx\n", nr_pages);
 			dimm->grain = 8; /* same guess */
-			dimm->mtype = MEM_DDR3;
+			if (skl)
+				dimm->mtype = MEM_DDR4;
+			else
+				dimm->mtype = MEM_DDR3;
 			dimm->dtype = DEV_UNKNOWN;
 			dimm->edac_mode = EDAC_UNKNOWN;
 		}
@@ -501,6 +557,9 @@ static const struct pci_device_id ie3120
 		PCI_VEND_DEV(INTEL, IE31200_HB_7), PCI_ANY_ID, PCI_ANY_ID, 0, 0,
 		IE31200},
 	{
+		PCI_VEND_DEV(INTEL, IE31200_HB_8), PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		IE31200},
+	{
 		0,
 	}            /* 0 terminated list. */
 };
--- zfcpdump-kernel-4.4.orig/drivers/edac/sb_edac.c
+++ zfcpdump-kernel-4.4/drivers/edac/sb_edac.c
@@ -65,15 +65,20 @@ static const u32 ibridge_dram_rule[] = {
 	0xd8, 0xe0, 0xe8, 0xf0, 0xf8,
 };
 
-#define SAD_LIMIT(reg)		((GET_BITFIELD(reg, 6, 25) << 26) | 0x3ffffff)
-#define DRAM_ATTR(reg)		GET_BITFIELD(reg, 2,  3)
-#define INTERLEAVE_MODE(reg)	GET_BITFIELD(reg, 1,  1)
+static const u32 knl_dram_rule[] = {
+	0x60, 0x68, 0x70, 0x78, 0x80, /* 0-4 */
+	0x88, 0x90, 0x98, 0xa0, 0xa8, /* 5-9 */
+	0xb0, 0xb8, 0xc0, 0xc8, 0xd0, /* 10-14 */
+	0xd8, 0xe0, 0xe8, 0xf0, 0xf8, /* 15-19 */
+	0x100, 0x108, 0x110, 0x118,   /* 20-23 */
+};
+
 #define DRAM_RULE_ENABLE(reg)	GET_BITFIELD(reg, 0,  0)
 #define A7MODE(reg)		GET_BITFIELD(reg, 26, 26)
 
-static char *get_dram_attr(u32 reg)
+static char *show_dram_attr(u32 attr)
 {
-	switch(DRAM_ATTR(reg)) {
+	switch (attr) {
 		case 0:
 			return "DRAM";
 		case 1:
@@ -97,6 +102,14 @@ static const u32 ibridge_interleave_list
 	0xdc, 0xe4, 0xec, 0xf4, 0xfc,
 };
 
+static const u32 knl_interleave_list[] = {
+	0x64, 0x6c, 0x74, 0x7c, 0x84, /* 0-4 */
+	0x8c, 0x94, 0x9c, 0xa4, 0xac, /* 5-9 */
+	0xb4, 0xbc, 0xc4, 0xcc, 0xd4, /* 10-14 */
+	0xdc, 0xe4, 0xec, 0xf4, 0xfc, /* 15-19 */
+	0x104, 0x10c, 0x114, 0x11c,   /* 20-23 */
+};
+
 struct interleave_pkg {
 	unsigned char start;
 	unsigned char end;
@@ -134,10 +147,13 @@ static inline int sad_pkg(const struct i
 /* Devices 12 Function 7 */
 
 #define TOLM		0x80
-#define	TOHM		0x84
+#define TOHM		0x84
 #define HASWELL_TOLM	0xd0
 #define HASWELL_TOHM_0	0xd4
 #define HASWELL_TOHM_1	0xd8
+#define KNL_TOLM	0xd0
+#define KNL_TOHM_0	0xd4
+#define KNL_TOHM_1	0xd8
 
 #define GET_TOLM(reg)		((GET_BITFIELD(reg, 0,  3) << 28) | 0x3ffffff)
 #define GET_TOHM(reg)		((GET_BITFIELD(reg, 0, 20) << 25) | 0x3ffffff)
@@ -148,6 +164,8 @@ static inline int sad_pkg(const struct i
 
 #define SOURCE_ID(reg)		GET_BITFIELD(reg, 9, 11)
 
+#define SOURCE_ID_KNL(reg)	GET_BITFIELD(reg, 12, 14)
+
 #define SAD_CONTROL	0xf4
 
 /* Device 14 function 0 */
@@ -170,6 +188,7 @@ static const u32 tad_dram_rule[] = {
 /* Device 15, function 0 */
 
 #define MCMTR			0x7c
+#define KNL_MCMTR		0x624
 
 #define IS_ECC_ENABLED(mcmtr)		GET_BITFIELD(mcmtr, 2, 2)
 #define IS_LOCKSTEP_ENABLED(mcmtr)	GET_BITFIELD(mcmtr, 1, 1)
@@ -186,6 +205,8 @@ static const int mtr_regs[] = {
 	0x80, 0x84, 0x88,
 };
 
+static const int knl_mtr_reg = 0xb60;
+
 #define RANK_DISABLE(mtr)		GET_BITFIELD(mtr, 16, 19)
 #define IS_DIMM_PRESENT(mtr)		GET_BITFIELD(mtr, 14, 14)
 #define RANK_CNT_BITS(mtr)		GET_BITFIELD(mtr, 12, 13)
@@ -218,8 +239,11 @@ static const u32 rir_offset[MAX_RIR_RANG
 	{ 0x1a0, 0x1a4, 0x1a8, 0x1ac, 0x1b0, 0x1b4, 0x1b8, 0x1bc },
 };
 
-#define RIR_RNK_TGT(reg)		GET_BITFIELD(reg, 16, 19)
-#define RIR_OFFSET(reg)		GET_BITFIELD(reg,  2, 14)
+#define RIR_RNK_TGT(type, reg) (((type) == BROADWELL) ? \
+	GET_BITFIELD(reg, 20, 23) : GET_BITFIELD(reg, 16, 19))
+
+#define RIR_OFFSET(type, reg) (((type) == HASWELL || (type) == BROADWELL) ? \
+	GET_BITFIELD(reg,  2, 15) : GET_BITFIELD(reg,  2, 14))
 
 /* Device 16, functions 2-7 */
 
@@ -256,6 +280,9 @@ static const u32 correrrthrsld[] = {
 
 #define NUM_CHANNELS		8	/* 2MC per socket, four chan per MC */
 #define MAX_DIMMS		3	/* Max DIMMS per channel */
+#define KNL_MAX_CHAS		38	/* KNL max num. of Cache Home Agents */
+#define KNL_MAX_CHANNELS	6	/* KNL max num. of PCI channels */
+#define KNL_MAX_EDCS		8	/* Embedded DRAM controllers */
 #define CHANNEL_UNSPECIFIED	0xf	/* Intel IA32 SDM 15-14 */
 
 enum type {
@@ -263,6 +290,7 @@ enum type {
 	IVY_BRIDGE,
 	HASWELL,
 	BROADWELL,
+	KNIGHTS_LANDING,
 };
 
 struct sbridge_pvt;
@@ -273,6 +301,10 @@ struct sbridge_info {
 	u64		(*get_tolm)(struct sbridge_pvt *pvt);
 	u64		(*get_tohm)(struct sbridge_pvt *pvt);
 	u64		(*rir_limit)(u32 reg);
+	u64		(*sad_limit)(u32 reg);
+	u32		(*interleave_mode)(u32 reg);
+	char*		(*show_interleave_mode)(u32 reg);
+	u32		(*dram_attr)(u32 reg);
 	const u32	*dram_rule;
 	const u32	*interleave_list;
 	const struct interleave_pkg *interleave_pkg;
@@ -308,6 +340,16 @@ struct sbridge_dev {
 	struct mem_ctl_info	*mci;
 };
 
+struct knl_pvt {
+	struct pci_dev          *pci_cha[KNL_MAX_CHAS];
+	struct pci_dev          *pci_channel[KNL_MAX_CHANNELS];
+	struct pci_dev          *pci_mc0;
+	struct pci_dev          *pci_mc1;
+	struct pci_dev          *pci_mc0_misc;
+	struct pci_dev          *pci_mc1_misc;
+	struct pci_dev          *pci_mc_info; /* tolm, tohm */
+};
+
 struct sbridge_pvt {
 	struct pci_dev		*pci_ta, *pci_ddrio, *pci_ras;
 	struct pci_dev		*pci_sad0, *pci_sad1;
@@ -336,6 +378,7 @@ struct sbridge_pvt {
 
 	/* Memory description */
 	u64			tolm, tohm;
+	struct knl_pvt knl;
 };
 
 #define PCI_DESCR(device_id, opt)	\
@@ -509,6 +552,50 @@ static const struct pci_id_table pci_dev
 	{0,}			/* 0 terminated list. */
 };
 
+/* Knight's Landing Support */
+/*
+ * KNL's memory channels are swizzled between memory controllers.
+ * MC0 is mapped to CH3,5,6 and MC1 is mapped to CH0,1,2
+ */
+#define knl_channel_remap(channel) ((channel + 3) % 6)
+
+/* Memory controller, TAD tables, error injection - 2-8-0, 2-9-0 (2 of these) */
+#define PCI_DEVICE_ID_INTEL_KNL_IMC_MC       0x7840
+/* DRAM channel stuff; bank addrs, dimmmtr, etc.. 2-8-2 - 2-9-4 (6 of these) */
+#define PCI_DEVICE_ID_INTEL_KNL_IMC_CHANNEL  0x7843
+/* kdrwdbu TAD limits/offsets, MCMTR - 2-10-1, 2-11-1 (2 of these) */
+#define PCI_DEVICE_ID_INTEL_KNL_IMC_TA       0x7844
+/* CHA broadcast registers, dram rules - 1-29-0 (1 of these) */
+#define PCI_DEVICE_ID_INTEL_KNL_IMC_SAD0     0x782a
+/* SAD target - 1-29-1 (1 of these) */
+#define PCI_DEVICE_ID_INTEL_KNL_IMC_SAD1     0x782b
+/* Caching / Home Agent */
+#define PCI_DEVICE_ID_INTEL_KNL_IMC_CHA      0x782c
+/* Device with TOLM and TOHM, 0-5-0 (1 of these) */
+#define PCI_DEVICE_ID_INTEL_KNL_IMC_TOLHM    0x7810
+
+/*
+ * KNL differs from SB, IB, and Haswell in that it has multiple
+ * instances of the same device with the same device ID, so we handle that
+ * by creating as many copies in the table as we expect to find.
+ * (Like device ID must be grouped together.)
+ */
+
+static const struct pci_id_descr pci_dev_descr_knl[] = {
+	[0]         = { PCI_DESCR(PCI_DEVICE_ID_INTEL_KNL_IMC_SAD0, 0) },
+	[1]         = { PCI_DESCR(PCI_DEVICE_ID_INTEL_KNL_IMC_SAD1, 0) },
+	[2 ... 3]   = { PCI_DESCR(PCI_DEVICE_ID_INTEL_KNL_IMC_MC, 0)},
+	[4 ... 41]  = { PCI_DESCR(PCI_DEVICE_ID_INTEL_KNL_IMC_CHA, 0) },
+	[42 ... 47] = { PCI_DESCR(PCI_DEVICE_ID_INTEL_KNL_IMC_CHANNEL, 0) },
+	[48]        = { PCI_DESCR(PCI_DEVICE_ID_INTEL_KNL_IMC_TA, 0) },
+	[49]        = { PCI_DESCR(PCI_DEVICE_ID_INTEL_KNL_IMC_TOLHM, 0) },
+};
+
+static const struct pci_id_table pci_dev_descr_knl_table[] = {
+	PCI_ID_TABLE_ENTRY(pci_dev_descr_knl),
+	{0,}
+};
+
 /*
  * Broadwell support
  *
@@ -585,6 +672,7 @@ static const struct pci_device_id sbridg
 	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IBRIDGE_IMC_HA0_TA)},
 	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_HASWELL_IMC_HA0)},
 	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BROADWELL_IMC_HA0)},
+	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_KNL_IMC_SAD0)},
 	{0,}			/* 0 terminated list. */
 };
 
@@ -598,7 +686,7 @@ static inline int numrank(enum type type
 	int ranks = (1 << RANK_CNT_BITS(mtr));
 	int max = 4;
 
-	if (type == HASWELL || type == BROADWELL)
+	if (type == HASWELL || type == BROADWELL || type == KNIGHTS_LANDING)
 		max = 8;
 
 	if (ranks > max) {
@@ -636,10 +724,19 @@ static inline int numcol(u32 mtr)
 	return 1 << cols;
 }
 
-static struct sbridge_dev *get_sbridge_dev(u8 bus)
+static struct sbridge_dev *get_sbridge_dev(u8 bus, int multi_bus)
 {
 	struct sbridge_dev *sbridge_dev;
 
+	/*
+	 * If we have devices scattered across several busses that pertain
+	 * to the same memory controller, we'll lump them all together.
+	 */
+	if (multi_bus) {
+		return list_first_entry_or_null(&sbridge_edac_list,
+				struct sbridge_dev, list);
+	}
+
 	list_for_each_entry(sbridge_dev, &sbridge_edac_list, list) {
 		if (sbridge_dev->bus == bus)
 			return sbridge_dev;
@@ -718,6 +815,67 @@ static u64 rir_limit(u32 reg)
 	return ((u64)GET_BITFIELD(reg,  1, 10) << 29) | 0x1fffffff;
 }
 
+static u64 sad_limit(u32 reg)
+{
+	return (GET_BITFIELD(reg, 6, 25) << 26) | 0x3ffffff;
+}
+
+static u32 interleave_mode(u32 reg)
+{
+	return GET_BITFIELD(reg, 1, 1);
+}
+
+char *show_interleave_mode(u32 reg)
+{
+	return interleave_mode(reg) ? "8:6" : "[8:6]XOR[18:16]";
+}
+
+static u32 dram_attr(u32 reg)
+{
+	return GET_BITFIELD(reg, 2, 3);
+}
+
+static u64 knl_sad_limit(u32 reg)
+{
+	return (GET_BITFIELD(reg, 7, 26) << 26) | 0x3ffffff;
+}
+
+static u32 knl_interleave_mode(u32 reg)
+{
+	return GET_BITFIELD(reg, 1, 2);
+}
+
+static char *knl_show_interleave_mode(u32 reg)
+{
+	char *s;
+
+	switch (knl_interleave_mode(reg)) {
+	case 0:
+		s = "use address bits [8:6]";
+		break;
+	case 1:
+		s = "use address bits [10:8]";
+		break;
+	case 2:
+		s = "use address bits [14:12]";
+		break;
+	case 3:
+		s = "use address bits [32:30]";
+		break;
+	default:
+		WARN_ON(1);
+		break;
+	}
+
+	return s;
+}
+
+static u32 dram_attr_knl(u32 reg)
+{
+	return GET_BITFIELD(reg, 3, 4);
+}
+
+
 static enum mem_type get_memory_type(struct sbridge_pvt *pvt)
 {
 	u32 reg;
@@ -769,6 +927,12 @@ out:
 	return mtype;
 }
 
+static enum dev_type knl_get_width(struct sbridge_pvt *pvt, u32 mtr)
+{
+	/* for KNL value is fixed */
+	return DEV_X16;
+}
+
 static enum dev_type sbridge_get_width(struct sbridge_pvt *pvt, u32 mtr)
 {
 	/* there's no way to figure out */
@@ -812,6 +976,12 @@ static enum dev_type broadwell_get_width
 	return __ibridge_get_width(GET_BITFIELD(mtr, 8, 9));
 }
 
+static enum mem_type knl_get_memory_type(struct sbridge_pvt *pvt)
+{
+	/* DDR4 RDIMMS and LRDIMMS are supported */
+	return MEM_RDDR4;
+}
+
 static u8 get_node_id(struct sbridge_pvt *pvt)
 {
 	u32 reg;
@@ -827,6 +997,15 @@ static u8 haswell_get_node_id(struct sbr
 	return GET_BITFIELD(reg, 0, 3);
 }
 
+static u8 knl_get_node_id(struct sbridge_pvt *pvt)
+{
+	u32 reg;
+
+	pci_read_config_dword(pvt->pci_sad1, SAD_CONTROL, &reg);
+	return GET_BITFIELD(reg, 0, 2);
+}
+
+
 static u64 haswell_get_tolm(struct sbridge_pvt *pvt)
 {
 	u32 reg;
@@ -848,6 +1027,26 @@ static u64 haswell_get_tohm(struct sbrid
 	return rc | 0x1ffffff;
 }
 
+static u64 knl_get_tolm(struct sbridge_pvt *pvt)
+{
+	u32 reg;
+
+	pci_read_config_dword(pvt->knl.pci_mc_info, KNL_TOLM, &reg);
+	return (GET_BITFIELD(reg, 26, 31) << 26) | 0x3ffffff;
+}
+
+static u64 knl_get_tohm(struct sbridge_pvt *pvt)
+{
+	u64 rc;
+	u32 reg_lo, reg_hi;
+
+	pci_read_config_dword(pvt->knl.pci_mc_info, KNL_TOHM_0, &reg_lo);
+	pci_read_config_dword(pvt->knl.pci_mc_info, KNL_TOHM_1, &reg_hi);
+	rc = ((u64)reg_hi << 32) | reg_lo;
+	return rc | 0x3ffffff;
+}
+
+
 static u64 haswell_rir_limit(u32 reg)
 {
 	return (((u64)GET_BITFIELD(reg,  1, 11) + 1) << 29) - 1;
@@ -905,11 +1104,22 @@ static int check_if_ecc_is_active(const
 	case BROADWELL:
 		id = PCI_DEVICE_ID_INTEL_BROADWELL_IMC_HA0_TA;
 		break;
+	case KNIGHTS_LANDING:
+		/*
+		 * KNL doesn't group things by bus the same way
+		 * SB/IB/Haswell does.
+		 */
+		id = PCI_DEVICE_ID_INTEL_KNL_IMC_TA;
+		break;
 	default:
 		return -ENODEV;
 	}
 
-	pdev = get_pdev_same_bus(bus, id);
+	if (type != KNIGHTS_LANDING)
+		pdev = get_pdev_same_bus(bus, id);
+	else
+		pdev = pci_get_device(PCI_VENDOR_ID_INTEL, id, 0);
+
 	if (!pdev) {
 		sbridge_printk(KERN_ERR, "Couldn't find PCI device "
 					"%04x:%04x! on bus %02d\n",
@@ -917,7 +1127,8 @@ static int check_if_ecc_is_active(const
 		return -ENODEV;
 	}
 
-	pci_read_config_dword(pdev, MCMTR, &mcmtr);
+	pci_read_config_dword(pdev,
+			type == KNIGHTS_LANDING ? KNL_MCMTR : MCMTR, &mcmtr);
 	if (!IS_ECC_ENABLED(mcmtr)) {
 		sbridge_printk(KERN_ERR, "ECC is disabled. Aborting\n");
 		return -ENODEV;
@@ -925,6 +1136,476 @@ static int check_if_ecc_is_active(const
 	return 0;
 }
 
+/* Low bits of TAD limit, and some metadata. */
+static const u32 knl_tad_dram_limit_lo[] = {
+	0x400, 0x500, 0x600, 0x700,
+	0x800, 0x900, 0xa00, 0xb00,
+};
+
+/* Low bits of TAD offset. */
+static const u32 knl_tad_dram_offset_lo[] = {
+	0x404, 0x504, 0x604, 0x704,
+	0x804, 0x904, 0xa04, 0xb04,
+};
+
+/* High 16 bits of TAD limit and offset. */
+static const u32 knl_tad_dram_hi[] = {
+	0x408, 0x508, 0x608, 0x708,
+	0x808, 0x908, 0xa08, 0xb08,
+};
+
+/* Number of ways a tad entry is interleaved. */
+static const u32 knl_tad_ways[] = {
+	8, 6, 4, 3, 2, 1,
+};
+
+/*
+ * Retrieve the n'th Target Address Decode table entry
+ * from the memory controller's TAD table.
+ *
+ * @pvt:	driver private data
+ * @entry:	which entry you want to retrieve
+ * @mc:		which memory controller (0 or 1)
+ * @offset:	output tad range offset
+ * @limit:	output address of first byte above tad range
+ * @ways:	output number of interleave ways
+ *
+ * The offset value has curious semantics.  It's a sort of running total
+ * of the sizes of all the memory regions that aren't mapped in this
+ * tad table.
+ */
+static int knl_get_tad(const struct sbridge_pvt *pvt,
+		const int entry,
+		const int mc,
+		u64 *offset,
+		u64 *limit,
+		int *ways)
+{
+	u32 reg_limit_lo, reg_offset_lo, reg_hi;
+	struct pci_dev *pci_mc;
+	int way_id;
+
+	switch (mc) {
+	case 0:
+		pci_mc = pvt->knl.pci_mc0;
+		break;
+	case 1:
+		pci_mc = pvt->knl.pci_mc1;
+		break;
+	default:
+		WARN_ON(1);
+		return -EINVAL;
+	}
+
+	pci_read_config_dword(pci_mc,
+			knl_tad_dram_limit_lo[entry], &reg_limit_lo);
+	pci_read_config_dword(pci_mc,
+			knl_tad_dram_offset_lo[entry], &reg_offset_lo);
+	pci_read_config_dword(pci_mc,
+			knl_tad_dram_hi[entry], &reg_hi);
+
+	/* Is this TAD entry enabled? */
+	if (!GET_BITFIELD(reg_limit_lo, 0, 0))
+		return -ENODEV;
+
+	way_id = GET_BITFIELD(reg_limit_lo, 3, 5);
+
+	if (way_id < ARRAY_SIZE(knl_tad_ways)) {
+		*ways = knl_tad_ways[way_id];
+	} else {
+		*ways = 0;
+		sbridge_printk(KERN_ERR,
+				"Unexpected value %d in mc_tad_limit_lo wayness field\n",
+				way_id);
+		return -ENODEV;
+	}
+
+	/*
+	 * The least significant 6 bits of base and limit are truncated.
+	 * For limit, we fill the missing bits with 1s.
+	 */
+	*offset = ((u64) GET_BITFIELD(reg_offset_lo, 6, 31) << 6) |
+				((u64) GET_BITFIELD(reg_hi, 0,  15) << 32);
+	*limit = ((u64) GET_BITFIELD(reg_limit_lo,  6, 31) << 6) | 63 |
+				((u64) GET_BITFIELD(reg_hi, 16, 31) << 32);
+
+	return 0;
+}
+
+/* Determine which memory controller is responsible for a given channel. */
+static int knl_channel_mc(int channel)
+{
+	WARN_ON(channel < 0 || channel >= 6);
+
+	return channel < 3 ? 1 : 0;
+}
+
+/*
+ * Get the Nth entry from EDC_ROUTE_TABLE register.
+ * (This is the per-tile mapping of logical interleave targets to
+ *  physical EDC modules.)
+ *
+ * entry 0: 0:2
+ *       1: 3:5
+ *       2: 6:8
+ *       3: 9:11
+ *       4: 12:14
+ *       5: 15:17
+ *       6: 18:20
+ *       7: 21:23
+ * reserved: 24:31
+ */
+static u32 knl_get_edc_route(int entry, u32 reg)
+{
+	WARN_ON(entry >= KNL_MAX_EDCS);
+	return GET_BITFIELD(reg, entry*3, (entry*3)+2);
+}
+
+/*
+ * Get the Nth entry from MC_ROUTE_TABLE register.
+ * (This is the per-tile mapping of logical interleave targets to
+ *  physical DRAM channels modules.)
+ *
+ * entry 0: mc 0:2   channel 18:19
+ *       1: mc 3:5   channel 20:21
+ *       2: mc 6:8   channel 22:23
+ *       3: mc 9:11  channel 24:25
+ *       4: mc 12:14 channel 26:27
+ *       5: mc 15:17 channel 28:29
+ * reserved: 30:31
+ *
+ * Though we have 3 bits to identify the MC, we should only see
+ * the values 0 or 1.
+ */
+
+static u32 knl_get_mc_route(int entry, u32 reg)
+{
+	int mc, chan;
+
+	WARN_ON(entry >= KNL_MAX_CHANNELS);
+
+	mc = GET_BITFIELD(reg, entry*3, (entry*3)+2);
+	chan = GET_BITFIELD(reg, (entry*2) + 18, (entry*2) + 18 + 1);
+
+	return knl_channel_remap(mc*3 + chan);
+}
+
+/*
+ * Render the EDC_ROUTE register in human-readable form.
+ * Output string s should be at least KNL_MAX_EDCS*2 bytes.
+ */
+static void knl_show_edc_route(u32 reg, char *s)
+{
+	int i;
+
+	for (i = 0; i < KNL_MAX_EDCS; i++) {
+		s[i*2] = knl_get_edc_route(i, reg) + '0';
+		s[i*2+1] = '-';
+	}
+
+	s[KNL_MAX_EDCS*2 - 1] = '\0';
+}
+
+/*
+ * Render the MC_ROUTE register in human-readable form.
+ * Output string s should be at least KNL_MAX_CHANNELS*2 bytes.
+ */
+static void knl_show_mc_route(u32 reg, char *s)
+{
+	int i;
+
+	for (i = 0; i < KNL_MAX_CHANNELS; i++) {
+		s[i*2] = knl_get_mc_route(i, reg) + '0';
+		s[i*2+1] = '-';
+	}
+
+	s[KNL_MAX_CHANNELS*2 - 1] = '\0';
+}
+
+#define KNL_EDC_ROUTE 0xb8
+#define KNL_MC_ROUTE 0xb4
+
+/* Is this dram rule backed by regular DRAM in flat mode? */
+#define KNL_EDRAM(reg) GET_BITFIELD(reg, 29, 29)
+
+/* Is this dram rule cached? */
+#define KNL_CACHEABLE(reg) GET_BITFIELD(reg, 28, 28)
+
+/* Is this rule backed by edc ? */
+#define KNL_EDRAM_ONLY(reg) GET_BITFIELD(reg, 29, 29)
+
+/* Is this rule backed by DRAM, cacheable in EDRAM? */
+#define KNL_CACHEABLE(reg) GET_BITFIELD(reg, 28, 28)
+
+/* Is this rule mod3? */
+#define KNL_MOD3(reg) GET_BITFIELD(reg, 27, 27)
+
+/*
+ * Figure out how big our RAM modules are.
+ *
+ * The DIMMMTR register in KNL doesn't tell us the size of the DIMMs, so we
+ * have to figure this out from the SAD rules, interleave lists, route tables,
+ * and TAD rules.
+ *
+ * SAD rules can have holes in them (e.g. the 3G-4G hole), so we have to
+ * inspect the TAD rules to figure out how large the SAD regions really are.
+ *
+ * When we know the real size of a SAD region and how many ways it's
+ * interleaved, we know the individual contribution of each channel to
+ * TAD is size/ways.
+ *
+ * Finally, we have to check whether each channel participates in each SAD
+ * region.
+ *
+ * Fortunately, KNL only supports one DIMM per channel, so once we know how
+ * much memory the channel uses, we know the DIMM is at least that large.
+ * (The BIOS might possibly choose not to map all available memory, in which
+ * case we will underreport the size of the DIMM.)
+ *
+ * In theory, we could try to determine the EDC sizes as well, but that would
+ * only work in flat mode, not in cache mode.
+ *
+ * @mc_sizes: Output sizes of channels (must have space for KNL_MAX_CHANNELS
+ *            elements)
+ */
+static int knl_get_dimm_capacity(struct sbridge_pvt *pvt, u64 *mc_sizes)
+{
+	u64 sad_base, sad_size, sad_limit = 0;
+	u64 tad_base, tad_size, tad_limit, tad_deadspace, tad_livespace;
+	int sad_rule = 0;
+	int tad_rule = 0;
+	int intrlv_ways, tad_ways;
+	u32 first_pkg, pkg;
+	int i;
+	u64 sad_actual_size[2]; /* sad size accounting for holes, per mc */
+	u32 dram_rule, interleave_reg;
+	u32 mc_route_reg[KNL_MAX_CHAS];
+	u32 edc_route_reg[KNL_MAX_CHAS];
+	int edram_only;
+	char edc_route_string[KNL_MAX_EDCS*2];
+	char mc_route_string[KNL_MAX_CHANNELS*2];
+	int cur_reg_start;
+	int mc;
+	int channel;
+	int way;
+	int participants[KNL_MAX_CHANNELS];
+	int participant_count = 0;
+
+	for (i = 0; i < KNL_MAX_CHANNELS; i++)
+		mc_sizes[i] = 0;
+
+	/* Read the EDC route table in each CHA. */
+	cur_reg_start = 0;
+	for (i = 0; i < KNL_MAX_CHAS; i++) {
+		pci_read_config_dword(pvt->knl.pci_cha[i],
+				KNL_EDC_ROUTE, &edc_route_reg[i]);
+
+		if (i > 0 && edc_route_reg[i] != edc_route_reg[i-1]) {
+			knl_show_edc_route(edc_route_reg[i-1],
+					edc_route_string);
+			if (cur_reg_start == i-1)
+				edac_dbg(0, "edc route table for CHA %d: %s\n",
+					cur_reg_start, edc_route_string);
+			else
+				edac_dbg(0, "edc route table for CHA %d-%d: %s\n",
+					cur_reg_start, i-1, edc_route_string);
+			cur_reg_start = i;
+		}
+	}
+	knl_show_edc_route(edc_route_reg[i-1], edc_route_string);
+	if (cur_reg_start == i-1)
+		edac_dbg(0, "edc route table for CHA %d: %s\n",
+			cur_reg_start, edc_route_string);
+	else
+		edac_dbg(0, "edc route table for CHA %d-%d: %s\n",
+			cur_reg_start, i-1, edc_route_string);
+
+	/* Read the MC route table in each CHA. */
+	cur_reg_start = 0;
+	for (i = 0; i < KNL_MAX_CHAS; i++) {
+		pci_read_config_dword(pvt->knl.pci_cha[i],
+			KNL_MC_ROUTE, &mc_route_reg[i]);
+
+		if (i > 0 && mc_route_reg[i] != mc_route_reg[i-1]) {
+			knl_show_mc_route(mc_route_reg[i-1], mc_route_string);
+			if (cur_reg_start == i-1)
+				edac_dbg(0, "mc route table for CHA %d: %s\n",
+					cur_reg_start, mc_route_string);
+			else
+				edac_dbg(0, "mc route table for CHA %d-%d: %s\n",
+					cur_reg_start, i-1, mc_route_string);
+			cur_reg_start = i;
+		}
+	}
+	knl_show_mc_route(mc_route_reg[i-1], mc_route_string);
+	if (cur_reg_start == i-1)
+		edac_dbg(0, "mc route table for CHA %d: %s\n",
+			cur_reg_start, mc_route_string);
+	else
+		edac_dbg(0, "mc route table for CHA %d-%d: %s\n",
+			cur_reg_start, i-1, mc_route_string);
+
+	/* Process DRAM rules */
+	for (sad_rule = 0; sad_rule < pvt->info.max_sad; sad_rule++) {
+		/* previous limit becomes the new base */
+		sad_base = sad_limit;
+
+		pci_read_config_dword(pvt->pci_sad0,
+			pvt->info.dram_rule[sad_rule], &dram_rule);
+
+		if (!DRAM_RULE_ENABLE(dram_rule))
+			break;
+
+		edram_only = KNL_EDRAM_ONLY(dram_rule);
+
+		sad_limit = pvt->info.sad_limit(dram_rule)+1;
+		sad_size = sad_limit - sad_base;
+
+		pci_read_config_dword(pvt->pci_sad0,
+			pvt->info.interleave_list[sad_rule], &interleave_reg);
+
+		/*
+		 * Find out how many ways this dram rule is interleaved.
+		 * We stop when we see the first channel again.
+		 */
+		first_pkg = sad_pkg(pvt->info.interleave_pkg,
+						interleave_reg, 0);
+		for (intrlv_ways = 1; intrlv_ways < 8; intrlv_ways++) {
+			pkg = sad_pkg(pvt->info.interleave_pkg,
+						interleave_reg, intrlv_ways);
+
+			if ((pkg & 0x8) == 0) {
+				/*
+				 * 0 bit means memory is non-local,
+				 * which KNL doesn't support
+				 */
+				edac_dbg(0, "Unexpected interleave target %d\n",
+					pkg);
+				return -1;
+			}
+
+			if (pkg == first_pkg)
+				break;
+		}
+		if (KNL_MOD3(dram_rule))
+			intrlv_ways *= 3;
+
+		edac_dbg(3, "dram rule %d (base 0x%llx, limit 0x%llx), %d way interleave%s\n",
+			sad_rule,
+			sad_base,
+			sad_limit,
+			intrlv_ways,
+			edram_only ? ", EDRAM" : "");
+
+		/*
+		 * Find out how big the SAD region really is by iterating
+		 * over TAD tables (SAD regions may contain holes).
+		 * Each memory controller might have a different TAD table, so
+		 * we have to look at both.
+		 *
+		 * Livespace is the memory that's mapped in this TAD table,
+		 * deadspace is the holes (this could be the MMIO hole, or it
+		 * could be memory that's mapped by the other TAD table but
+		 * not this one).
+		 */
+		for (mc = 0; mc < 2; mc++) {
+			sad_actual_size[mc] = 0;
+			tad_livespace = 0;
+			for (tad_rule = 0;
+					tad_rule < ARRAY_SIZE(
+						knl_tad_dram_limit_lo);
+					tad_rule++) {
+				if (knl_get_tad(pvt,
+						tad_rule,
+						mc,
+						&tad_deadspace,
+						&tad_limit,
+						&tad_ways))
+					break;
+
+				tad_size = (tad_limit+1) -
+					(tad_livespace + tad_deadspace);
+				tad_livespace += tad_size;
+				tad_base = (tad_limit+1) - tad_size;
+
+				if (tad_base < sad_base) {
+					if (tad_limit > sad_base)
+						edac_dbg(0, "TAD region overlaps lower SAD boundary -- TAD tables may be configured incorrectly.\n");
+				} else if (tad_base < sad_limit) {
+					if (tad_limit+1 > sad_limit) {
+						edac_dbg(0, "TAD region overlaps upper SAD boundary -- TAD tables may be configured incorrectly.\n");
+					} else {
+						/* TAD region is completely inside SAD region */
+						edac_dbg(3, "TAD region %d 0x%llx - 0x%llx (%lld bytes) table%d\n",
+							tad_rule, tad_base,
+							tad_limit, tad_size,
+							mc);
+						sad_actual_size[mc] += tad_size;
+					}
+				}
+				tad_base = tad_limit+1;
+			}
+		}
+
+		for (mc = 0; mc < 2; mc++) {
+			edac_dbg(3, " total TAD DRAM footprint in table%d : 0x%llx (%lld bytes)\n",
+				mc, sad_actual_size[mc], sad_actual_size[mc]);
+		}
+
+		/* Ignore EDRAM rule */
+		if (edram_only)
+			continue;
+
+		/* Figure out which channels participate in interleave. */
+		for (channel = 0; channel < KNL_MAX_CHANNELS; channel++)
+			participants[channel] = 0;
+
+		/* For each channel, does at least one CHA have
+		 * this channel mapped to the given target?
+		 */
+		for (channel = 0; channel < KNL_MAX_CHANNELS; channel++) {
+			for (way = 0; way < intrlv_ways; way++) {
+				int target;
+				int cha;
+
+				if (KNL_MOD3(dram_rule))
+					target = way;
+				else
+					target = 0x7 & sad_pkg(
+				pvt->info.interleave_pkg, interleave_reg, way);
+
+				for (cha = 0; cha < KNL_MAX_CHAS; cha++) {
+					if (knl_get_mc_route(target,
+						mc_route_reg[cha]) == channel
+						&& participants[channel]) {
+						participant_count++;
+						participants[channel] = 1;
+						break;
+					}
+				}
+			}
+		}
+
+		if (participant_count != intrlv_ways)
+			edac_dbg(0, "participant_count (%d) != interleave_ways (%d): DIMM size may be incorrect\n",
+				participant_count, intrlv_ways);
+
+		for (channel = 0; channel < KNL_MAX_CHANNELS; channel++) {
+			mc = knl_channel_mc(channel);
+			if (participants[channel]) {
+				edac_dbg(4, "mc channel %d contributes %lld bytes via sad entry %d\n",
+					channel,
+					sad_actual_size[mc]/intrlv_ways,
+					sad_rule);
+				mc_sizes[channel] +=
+					sad_actual_size[mc]/intrlv_ways;
+			}
+		}
+	}
+
+	return 0;
+}
+
 static int get_dimm_config(struct mem_ctl_info *mci)
 {
 	struct sbridge_pvt *pvt = mci->pvt_info;
@@ -934,13 +1615,20 @@ static int get_dimm_config(struct mem_ct
 	u32 reg;
 	enum edac_type mode;
 	enum mem_type mtype;
+	int channels = pvt->info.type == KNIGHTS_LANDING ?
+		KNL_MAX_CHANNELS : NUM_CHANNELS;
+	u64 knl_mc_sizes[KNL_MAX_CHANNELS];
 
-	if (pvt->info.type == HASWELL || pvt->info.type == BROADWELL)
+	if (pvt->info.type == HASWELL || pvt->info.type == BROADWELL ||
+			pvt->info.type == KNIGHTS_LANDING)
 		pci_read_config_dword(pvt->pci_sad1, SAD_TARGET, &reg);
 	else
 		pci_read_config_dword(pvt->pci_br0, SAD_TARGET, &reg);
 
-	pvt->sbridge_dev->source_id = SOURCE_ID(reg);
+	if (pvt->info.type == KNIGHTS_LANDING)
+		pvt->sbridge_dev->source_id = SOURCE_ID_KNL(reg);
+	else
+		pvt->sbridge_dev->source_id = SOURCE_ID(reg);
 
 	pvt->sbridge_dev->node_id = pvt->info.get_node_id(pvt);
 	edac_dbg(0, "mc#%d: Node ID: %d, source ID: %d\n",
@@ -948,31 +1636,42 @@ static int get_dimm_config(struct mem_ct
 		 pvt->sbridge_dev->node_id,
 		 pvt->sbridge_dev->source_id);
 
-	pci_read_config_dword(pvt->pci_ras, RASENABLES, &reg);
-	if (IS_MIRROR_ENABLED(reg)) {
-		edac_dbg(0, "Memory mirror is enabled\n");
-		pvt->is_mirrored = true;
-	} else {
-		edac_dbg(0, "Memory mirror is disabled\n");
+	/* KNL doesn't support mirroring or lockstep,
+	 * and is always closed page
+	 */
+	if (pvt->info.type == KNIGHTS_LANDING) {
+		mode = EDAC_S4ECD4ED;
 		pvt->is_mirrored = false;
-	}
 
-	pci_read_config_dword(pvt->pci_ta, MCMTR, &pvt->info.mcmtr);
-	if (IS_LOCKSTEP_ENABLED(pvt->info.mcmtr)) {
-		edac_dbg(0, "Lockstep is enabled\n");
-		mode = EDAC_S8ECD8ED;
-		pvt->is_lockstep = true;
+		if (knl_get_dimm_capacity(pvt, knl_mc_sizes) != 0)
+			return -1;
 	} else {
-		edac_dbg(0, "Lockstep is disabled\n");
-		mode = EDAC_S4ECD4ED;
-		pvt->is_lockstep = false;
-	}
-	if (IS_CLOSE_PG(pvt->info.mcmtr)) {
-		edac_dbg(0, "address map is on closed page mode\n");
-		pvt->is_close_pg = true;
-	} else {
-		edac_dbg(0, "address map is on open page mode\n");
-		pvt->is_close_pg = false;
+		pci_read_config_dword(pvt->pci_ras, RASENABLES, &reg);
+		if (IS_MIRROR_ENABLED(reg)) {
+			edac_dbg(0, "Memory mirror is enabled\n");
+			pvt->is_mirrored = true;
+		} else {
+			edac_dbg(0, "Memory mirror is disabled\n");
+			pvt->is_mirrored = false;
+		}
+
+		pci_read_config_dword(pvt->pci_ta, MCMTR, &pvt->info.mcmtr);
+		if (IS_LOCKSTEP_ENABLED(pvt->info.mcmtr)) {
+			edac_dbg(0, "Lockstep is enabled\n");
+			mode = EDAC_S8ECD8ED;
+			pvt->is_lockstep = true;
+		} else {
+			edac_dbg(0, "Lockstep is disabled\n");
+			mode = EDAC_S4ECD4ED;
+			pvt->is_lockstep = false;
+		}
+		if (IS_CLOSE_PG(pvt->info.mcmtr)) {
+			edac_dbg(0, "address map is on closed page mode\n");
+			pvt->is_close_pg = true;
+		} else {
+			edac_dbg(0, "address map is on open page mode\n");
+			pvt->is_close_pg = false;
+		}
 	}
 
 	mtype = pvt->info.get_memory_type(pvt);
@@ -988,23 +1687,46 @@ static int get_dimm_config(struct mem_ct
 	else
 		banks = 8;
 
-	for (i = 0; i < NUM_CHANNELS; i++) {
+	for (i = 0; i < channels; i++) {
 		u32 mtr;
 
-		if (!pvt->pci_tad[i])
-			continue;
-		for (j = 0; j < ARRAY_SIZE(mtr_regs); j++) {
+		int max_dimms_per_channel;
+
+		if (pvt->info.type == KNIGHTS_LANDING) {
+			max_dimms_per_channel = 1;
+			if (!pvt->knl.pci_channel[i])
+				continue;
+		} else {
+			max_dimms_per_channel = ARRAY_SIZE(mtr_regs);
+			if (!pvt->pci_tad[i])
+				continue;
+		}
+
+		for (j = 0; j < max_dimms_per_channel; j++) {
 			dimm = EDAC_DIMM_PTR(mci->layers, mci->dimms, mci->n_layers,
 				       i, j, 0);
-			pci_read_config_dword(pvt->pci_tad[i],
-					      mtr_regs[j], &mtr);
+			if (pvt->info.type == KNIGHTS_LANDING) {
+				pci_read_config_dword(pvt->knl.pci_channel[i],
+					knl_mtr_reg, &mtr);
+			} else {
+				pci_read_config_dword(pvt->pci_tad[i],
+					mtr_regs[j], &mtr);
+			}
 			edac_dbg(4, "Channel #%d  MTR%d = %x\n", i, j, mtr);
 			if (IS_DIMM_PRESENT(mtr)) {
 				pvt->channel[i].dimms++;
 
 				ranks = numrank(pvt->info.type, mtr);
-				rows = numrow(mtr);
-				cols = numcol(mtr);
+
+				if (pvt->info.type == KNIGHTS_LANDING) {
+					/* For DDR4, this is fixed. */
+					cols = 1 << 10;
+					rows = knl_mc_sizes[i] /
+						((u64) cols * ranks * banks * 8);
+				} else {
+					rows = numrow(mtr);
+					cols = numcol(mtr);
+				}
 
 				size = ((u64)rows * cols * banks * ranks) >> (20 - 3);
 				npages = MiB_TO_PAGES(size);
@@ -1069,7 +1791,7 @@ static void get_memory_layout(const stru
 		/* SAD_LIMIT Address range is 45:26 */
 		pci_read_config_dword(pvt->pci_sad0, pvt->info.dram_rule[n_sads],
 				      &reg);
-		limit = SAD_LIMIT(reg);
+		limit = pvt->info.sad_limit(reg);
 
 		if (!DRAM_RULE_ENABLE(reg))
 			continue;
@@ -1081,10 +1803,10 @@ static void get_memory_layout(const stru
 		gb = div_u64_rem(tmp_mb, 1024, &mb);
 		edac_dbg(0, "SAD#%d %s up to %u.%03u GB (0x%016Lx) Interleave: %s reg=0x%08x\n",
 			 n_sads,
-			 get_dram_attr(reg),
+			 show_dram_attr(pvt->info.dram_attr(reg)),
 			 gb, (mb*1000)/1024,
 			 ((u64)tmp_mb) << 20L,
-			 INTERLEAVE_MODE(reg) ? "8:6" : "[8:6]XOR[18:16]",
+			 pvt->info.show_interleave_mode(reg),
 			 reg);
 		prv = limit;
 
@@ -1101,6 +1823,9 @@ static void get_memory_layout(const stru
 		}
 	}
 
+	if (pvt->info.type == KNIGHTS_LANDING)
+		return;
+
 	/*
 	 * Step 3) Get TAD range
 	 */
@@ -1117,8 +1842,8 @@ static void get_memory_layout(const stru
 		edac_dbg(0, "TAD#%d: up to %u.%03u GB (0x%016Lx), socket interleave %d, memory interleave %d, TGT: %d, %d, %d, %d, reg=0x%08x\n",
 			 n_tads, gb, (mb*1000)/1024,
 			 ((u64)tmp_mb) << 20L,
-			 (u32)TAD_SOCK(reg),
-			 (u32)TAD_CH(reg),
+			 (u32)(1 << TAD_SOCK(reg)),
+			 (u32)TAD_CH(reg) + 1,
 			 (u32)TAD_TGT0(reg),
 			 (u32)TAD_TGT1(reg),
 			 (u32)TAD_TGT2(reg),
@@ -1175,14 +1900,14 @@ static void get_memory_layout(const stru
 				pci_read_config_dword(pvt->pci_tad[i],
 						      rir_offset[j][k],
 						      &reg);
-				tmp_mb = RIR_OFFSET(reg) << 6;
+				tmp_mb = RIR_OFFSET(pvt->info.type, reg) << 6;
 
 				gb = div_u64_rem(tmp_mb, 1024, &mb);
 				edac_dbg(0, "CH#%d RIR#%d INTL#%d, offset %u.%03u GB (0x%016Lx), tgt: %d, reg=0x%08x\n",
 					 i, j, k,
 					 gb, (mb*1000)/1024,
 					 ((u64)tmp_mb) << 20L,
-					 (u32)RIR_RNK_TGT(reg),
+					 (u32)RIR_RNK_TGT(pvt->info.type, reg),
 					 reg);
 			}
 		}
@@ -1248,7 +1973,7 @@ static int get_memory_error_data(struct
 		if (!DRAM_RULE_ENABLE(reg))
 			continue;
 
-		limit = SAD_LIMIT(reg);
+		limit = pvt->info.sad_limit(reg);
 		if (limit <= prv) {
 			sprintf(msg, "Can't discover the memory socket");
 			return -EINVAL;
@@ -1262,8 +1987,8 @@ static int get_memory_error_data(struct
 		return -EINVAL;
 	}
 	dram_rule = reg;
-	*area_type = get_dram_attr(dram_rule);
-	interleave_mode = INTERLEAVE_MODE(dram_rule);
+	*area_type = show_dram_attr(pvt->info.dram_attr(dram_rule));
+	interleave_mode = pvt->info.interleave_mode(dram_rule);
 
 	pci_read_config_dword(pvt->pci_sad0, pvt->info.interleave_list[n_sads],
 			      &reg);
@@ -1396,7 +2121,7 @@ static int get_memory_error_data(struct
 	}
 
 	ch_way = TAD_CH(reg) + 1;
-	sck_way = TAD_SOCK(reg) + 1;
+	sck_way = TAD_SOCK(reg);
 
 	if (ch_way == 3)
 		idx = addr >> 6;
@@ -1435,7 +2160,7 @@ static int get_memory_error_data(struct
 		switch(ch_way) {
 		case 2:
 		case 4:
-			sck_xch = 1 << sck_way * (ch_way >> 1);
+			sck_xch = (1 << sck_way) * (ch_way >> 1);
 			break;
 		default:
 			sprintf(msg, "Invalid mirror set. Can't decode addr");
@@ -1453,7 +2178,7 @@ static int get_memory_error_data(struct
 		 n_tads,
 		 addr,
 		 limit,
-		 (u32)TAD_SOCK(reg),
+		 sck_way,
 		 ch_way,
 		 offset,
 		 idx,
@@ -1468,18 +2193,12 @@ static int get_memory_error_data(struct
 			offset, addr);
 		return -EINVAL;
 	}
-	addr -= offset;
-	/* Store the low bits [0:6] of the addr */
-	ch_addr = addr & 0x7f;
-	/* Remove socket wayness and remove 6 bits */
-	addr >>= 6;
-	addr = div_u64(addr, sck_xch);
-#if 0
-	/* Divide by channel way */
-	addr = addr / ch_way;
-#endif
-	/* Recover the last 6 bits */
-	ch_addr |= addr << 6;
+
+	ch_addr = addr - offset;
+	ch_addr >>= (6 + shiftup);
+	ch_addr /= sck_xch;
+	ch_addr <<= (6 + shiftup);
+	ch_addr |= addr & ((1 << (6 + shiftup)) - 1);
 
 	/*
 	 * Step 3) Decode rank
@@ -1518,7 +2237,7 @@ static int get_memory_error_data(struct
 	pci_read_config_dword(pvt->pci_tad[ch_add + base_ch],
 			      rir_offset[n_rir][idx],
 			      &reg);
-	*rank = RIR_RNK_TGT(reg);
+	*rank = RIR_RNK_TGT(pvt->info.type, reg);
 
 	edac_dbg(0, "RIR#%d: channel address 0x%08Lx < 0x%08Lx, RIR interleave %d, index %d\n",
 		 n_rir,
@@ -1567,7 +2286,8 @@ static void sbridge_put_all_devices(void
 static int sbridge_get_onedevice(struct pci_dev **prev,
 				 u8 *num_mc,
 				 const struct pci_id_table *table,
-				 const unsigned devno)
+				 const unsigned devno,
+				 const int multi_bus)
 {
 	struct sbridge_dev *sbridge_dev;
 	const struct pci_id_descr *dev_descr = &table->descr[devno];
@@ -1603,7 +2323,7 @@ static int sbridge_get_onedevice(struct
 	}
 	bus = pdev->bus->number;
 
-	sbridge_dev = get_sbridge_dev(bus);
+	sbridge_dev = get_sbridge_dev(bus, multi_bus);
 	if (!sbridge_dev) {
 		sbridge_dev = alloc_sbridge_dev(bus, table);
 		if (!sbridge_dev) {
@@ -1652,21 +2372,32 @@ static int sbridge_get_onedevice(struct
  * @num_mc: pointer to the memory controllers count, to be incremented in case
  *	    of success.
  * @table: model specific table
+ * @allow_dups: allow for multiple devices to exist with the same device id
+ *              (as implemented, this isn't expected to work correctly in the
+ *              multi-socket case).
+ * @multi_bus: don't assume devices on different buses belong to different
+ *             memory controllers.
  *
  * returns 0 in case of success or error code
  */
-static int sbridge_get_all_devices(u8 *num_mc,
-				   const struct pci_id_table *table)
+static int sbridge_get_all_devices_full(u8 *num_mc,
+					const struct pci_id_table *table,
+					int allow_dups,
+					int multi_bus)
 {
 	int i, rc;
 	struct pci_dev *pdev = NULL;
 
 	while (table && table->descr) {
 		for (i = 0; i < table->n_devs; i++) {
-			pdev = NULL;
+			if (!allow_dups || i == 0 ||
+					table->descr[i].dev_id !=
+						table->descr[i-1].dev_id) {
+				pdev = NULL;
+			}
 			do {
 				rc = sbridge_get_onedevice(&pdev, num_mc,
-							   table, i);
+							   table, i, multi_bus);
 				if (rc < 0) {
 					if (i == 0) {
 						i = table->n_devs;
@@ -1675,7 +2406,7 @@ static int sbridge_get_all_devices(u8 *n
 					sbridge_put_all_devices();
 					return -ENODEV;
 				}
-			} while (pdev);
+			} while (pdev && !allow_dups);
 		}
 		table++;
 	}
@@ -1683,6 +2414,11 @@ static int sbridge_get_all_devices(u8 *n
 	return 0;
 }
 
+#define sbridge_get_all_devices(num_mc, table) \
+		sbridge_get_all_devices_full(num_mc, table, 0, 0)
+#define sbridge_get_all_devices_knl(num_mc, table) \
+		sbridge_get_all_devices_full(num_mc, table, 1, 1)
+
 static int sbridge_mci_bind_devs(struct mem_ctl_info *mci,
 				 struct sbridge_dev *sbridge_dev)
 {
@@ -2038,6 +2774,131 @@ enodev:
 	return -ENODEV;
 }
 
+static int knl_mci_bind_devs(struct mem_ctl_info *mci,
+			struct sbridge_dev *sbridge_dev)
+{
+	struct sbridge_pvt *pvt = mci->pvt_info;
+	struct pci_dev *pdev;
+	int dev, func;
+
+	int i;
+	int devidx;
+
+	for (i = 0; i < sbridge_dev->n_devs; i++) {
+		pdev = sbridge_dev->pdev[i];
+		if (!pdev)
+			continue;
+
+		/* Extract PCI device and function. */
+		dev = (pdev->devfn >> 3) & 0x1f;
+		func = pdev->devfn & 0x7;
+
+		switch (pdev->device) {
+		case PCI_DEVICE_ID_INTEL_KNL_IMC_MC:
+			if (dev == 8)
+				pvt->knl.pci_mc0 = pdev;
+			else if (dev == 9)
+				pvt->knl.pci_mc1 = pdev;
+			else {
+				sbridge_printk(KERN_ERR,
+					"Memory controller in unexpected place! (dev %d, fn %d)\n",
+					dev, func);
+				continue;
+			}
+			break;
+
+		case PCI_DEVICE_ID_INTEL_KNL_IMC_SAD0:
+			pvt->pci_sad0 = pdev;
+			break;
+
+		case PCI_DEVICE_ID_INTEL_KNL_IMC_SAD1:
+			pvt->pci_sad1 = pdev;
+			break;
+
+		case PCI_DEVICE_ID_INTEL_KNL_IMC_CHA:
+			/* There are one of these per tile, and range from
+			 * 1.14.0 to 1.18.5.
+			 */
+			devidx = ((dev-14)*8)+func;
+
+			if (devidx < 0 || devidx >= KNL_MAX_CHAS) {
+				sbridge_printk(KERN_ERR,
+					"Caching and Home Agent in unexpected place! (dev %d, fn %d)\n",
+					dev, func);
+				continue;
+			}
+
+			WARN_ON(pvt->knl.pci_cha[devidx] != NULL);
+
+			pvt->knl.pci_cha[devidx] = pdev;
+			break;
+
+		case PCI_DEVICE_ID_INTEL_KNL_IMC_CHANNEL:
+			devidx = -1;
+
+			/*
+			 *  MC0 channels 0-2 are device 9 function 2-4,
+			 *  MC1 channels 3-5 are device 8 function 2-4.
+			 */
+
+			if (dev == 9)
+				devidx = func-2;
+			else if (dev == 8)
+				devidx = 3 + (func-2);
+
+			if (devidx < 0 || devidx >= KNL_MAX_CHANNELS) {
+				sbridge_printk(KERN_ERR,
+					"DRAM Channel Registers in unexpected place! (dev %d, fn %d)\n",
+					dev, func);
+				continue;
+			}
+
+			WARN_ON(pvt->knl.pci_channel[devidx] != NULL);
+			pvt->knl.pci_channel[devidx] = pdev;
+			break;
+
+		case PCI_DEVICE_ID_INTEL_KNL_IMC_TOLHM:
+			pvt->knl.pci_mc_info = pdev;
+			break;
+
+		case PCI_DEVICE_ID_INTEL_KNL_IMC_TA:
+			pvt->pci_ta = pdev;
+			break;
+
+		default:
+			sbridge_printk(KERN_ERR, "Unexpected device %d\n",
+				pdev->device);
+			break;
+		}
+	}
+
+	if (!pvt->knl.pci_mc0  || !pvt->knl.pci_mc1 ||
+	    !pvt->pci_sad0     || !pvt->pci_sad1    ||
+	    !pvt->pci_ta) {
+		goto enodev;
+	}
+
+	for (i = 0; i < KNL_MAX_CHANNELS; i++) {
+		if (!pvt->knl.pci_channel[i]) {
+			sbridge_printk(KERN_ERR, "Missing channel %d\n", i);
+			goto enodev;
+		}
+	}
+
+	for (i = 0; i < KNL_MAX_CHAS; i++) {
+		if (!pvt->knl.pci_cha[i]) {
+			sbridge_printk(KERN_ERR, "Missing CHA %d\n", i);
+			goto enodev;
+		}
+	}
+
+	return 0;
+
+enodev:
+	sbridge_printk(KERN_ERR, "Some needed devices are missing\n");
+	return -ENODEV;
+}
+
 /****************************************************************************
 			Error check routines
  ****************************************************************************/
@@ -2127,8 +2988,36 @@ static void sbridge_mce_output_error(str
 	if (!GET_BITFIELD(m->status, 58, 58))
 		return;
 
-	rc = get_memory_error_data(mci, m->addr, &socket, &ha,
-				   &channel_mask, &rank, &area_type, msg);
+	if (pvt->info.type == KNIGHTS_LANDING) {
+		if (channel == 14) {
+			edac_dbg(0, "%s%s err_code:%04x:%04x EDRAM bank %d\n",
+				overflow ? " OVERFLOW" : "",
+				(uncorrected_error && recoverable)
+				? " recoverable" : "",
+				mscod, errcode,
+				m->bank);
+		} else {
+			char A = *("A");
+
+			channel = knl_channel_remap(channel);
+			channel_mask = 1 << channel;
+			snprintf(msg, sizeof(msg),
+				"%s%s err_code:%04x:%04x channel:%d (DIMM_%c)",
+				overflow ? " OVERFLOW" : "",
+				(uncorrected_error && recoverable)
+				? " recoverable" : " ",
+				mscod, errcode, channel, A + channel);
+			edac_mc_handle_error(tp_event, mci, core_err_cnt,
+				m->addr >> PAGE_SHIFT, m->addr & ~PAGE_MASK, 0,
+				channel, 0, -1,
+				optype, msg);
+		}
+		return;
+	} else {
+		rc = get_memory_error_data(mci, m->addr, &socket, &ha,
+				&channel_mask, &rank, &area_type, msg);
+	}
+
 	if (rc < 0)
 		goto err_parsing;
 	new_mci = get_mci_for_node_id(socket);
@@ -2260,7 +3149,7 @@ static int sbridge_mce_check_error(struc
 
 	mci = get_mci_for_node_id(mce->socketid);
 	if (!mci)
-		return NOTIFY_BAD;
+		return NOTIFY_DONE;
 	pvt = mci->pvt_info;
 
 	/*
@@ -2359,10 +3248,11 @@ static int sbridge_register_mci(struct s
 
 	/* allocate a new MC control structure */
 	layers[0].type = EDAC_MC_LAYER_CHANNEL;
-	layers[0].size = NUM_CHANNELS;
+	layers[0].size = type == KNIGHTS_LANDING ?
+		KNL_MAX_CHANNELS : NUM_CHANNELS;
 	layers[0].is_virt_csrow = false;
 	layers[1].type = EDAC_MC_LAYER_SLOT;
-	layers[1].size = MAX_DIMMS;
+	layers[1].size = type == KNIGHTS_LANDING ? 1 : MAX_DIMMS;
 	layers[1].is_virt_csrow = true;
 	mci = edac_mc_alloc(sbridge_dev->mc, ARRAY_SIZE(layers), layers,
 			    sizeof(*pvt));
@@ -2380,7 +3270,8 @@ static int sbridge_register_mci(struct s
 	pvt->sbridge_dev = sbridge_dev;
 	sbridge_dev->mci = mci;
 
-	mci->mtype_cap = MEM_FLAG_DDR3;
+	mci->mtype_cap = type == KNIGHTS_LANDING ?
+		MEM_FLAG_DDR4 : MEM_FLAG_DDR3;
 	mci->edac_ctl_cap = EDAC_FLAG_NONE;
 	mci->edac_cap = EDAC_FLAG_NONE;
 	mci->mod_name = "sbridge_edac.c";
@@ -2401,6 +3292,10 @@ static int sbridge_register_mci(struct s
 		pvt->info.get_memory_type = get_memory_type;
 		pvt->info.get_node_id = get_node_id;
 		pvt->info.rir_limit = rir_limit;
+		pvt->info.sad_limit = sad_limit;
+		pvt->info.interleave_mode = interleave_mode;
+		pvt->info.show_interleave_mode = show_interleave_mode;
+		pvt->info.dram_attr = dram_attr;
 		pvt->info.max_sad = ARRAY_SIZE(ibridge_dram_rule);
 		pvt->info.interleave_list = ibridge_interleave_list;
 		pvt->info.max_interleave = ARRAY_SIZE(ibridge_interleave_list);
@@ -2421,6 +3316,10 @@ static int sbridge_register_mci(struct s
 		pvt->info.get_memory_type = get_memory_type;
 		pvt->info.get_node_id = get_node_id;
 		pvt->info.rir_limit = rir_limit;
+		pvt->info.sad_limit = sad_limit;
+		pvt->info.interleave_mode = interleave_mode;
+		pvt->info.show_interleave_mode = show_interleave_mode;
+		pvt->info.dram_attr = dram_attr;
 		pvt->info.max_sad = ARRAY_SIZE(sbridge_dram_rule);
 		pvt->info.interleave_list = sbridge_interleave_list;
 		pvt->info.max_interleave = ARRAY_SIZE(sbridge_interleave_list);
@@ -2441,6 +3340,10 @@ static int sbridge_register_mci(struct s
 		pvt->info.get_memory_type = haswell_get_memory_type;
 		pvt->info.get_node_id = haswell_get_node_id;
 		pvt->info.rir_limit = haswell_rir_limit;
+		pvt->info.sad_limit = sad_limit;
+		pvt->info.interleave_mode = interleave_mode;
+		pvt->info.show_interleave_mode = show_interleave_mode;
+		pvt->info.dram_attr = dram_attr;
 		pvt->info.max_sad = ARRAY_SIZE(ibridge_dram_rule);
 		pvt->info.interleave_list = ibridge_interleave_list;
 		pvt->info.max_interleave = ARRAY_SIZE(ibridge_interleave_list);
@@ -2461,6 +3364,10 @@ static int sbridge_register_mci(struct s
 		pvt->info.get_memory_type = haswell_get_memory_type;
 		pvt->info.get_node_id = haswell_get_node_id;
 		pvt->info.rir_limit = haswell_rir_limit;
+		pvt->info.sad_limit = sad_limit;
+		pvt->info.interleave_mode = interleave_mode;
+		pvt->info.show_interleave_mode = show_interleave_mode;
+		pvt->info.dram_attr = dram_attr;
 		pvt->info.max_sad = ARRAY_SIZE(ibridge_dram_rule);
 		pvt->info.interleave_list = ibridge_interleave_list;
 		pvt->info.max_interleave = ARRAY_SIZE(ibridge_interleave_list);
@@ -2473,6 +3380,30 @@ static int sbridge_register_mci(struct s
 		if (unlikely(rc < 0))
 			goto fail0;
 		break;
+	case KNIGHTS_LANDING:
+		/* pvt->info.rankcfgr == ??? */
+		pvt->info.get_tolm = knl_get_tolm;
+		pvt->info.get_tohm = knl_get_tohm;
+		pvt->info.dram_rule = knl_dram_rule;
+		pvt->info.get_memory_type = knl_get_memory_type;
+		pvt->info.get_node_id = knl_get_node_id;
+		pvt->info.rir_limit = NULL;
+		pvt->info.sad_limit = knl_sad_limit;
+		pvt->info.interleave_mode = knl_interleave_mode;
+		pvt->info.show_interleave_mode = knl_show_interleave_mode;
+		pvt->info.dram_attr = dram_attr_knl;
+		pvt->info.max_sad = ARRAY_SIZE(knl_dram_rule);
+		pvt->info.interleave_list = knl_interleave_list;
+		pvt->info.max_interleave = ARRAY_SIZE(knl_interleave_list);
+		pvt->info.interleave_pkg = ibridge_interleave_pkg;
+		pvt->info.get_width = knl_get_width;
+		mci->ctl_name = kasprintf(GFP_KERNEL,
+			"Knights Landing Socket#%d", mci->mc_idx);
+
+		rc = knl_mci_bind_devs(mci, sbridge_dev);
+		if (unlikely(rc < 0))
+			goto fail0;
+		break;
 	}
 
 	/* Get dimm basic config and the memory layout */
@@ -2527,20 +3458,29 @@ static int sbridge_probe(struct pci_dev
 
 	switch (pdev->device) {
 	case PCI_DEVICE_ID_INTEL_IBRIDGE_IMC_HA0_TA:
-		rc = sbridge_get_all_devices(&num_mc, pci_dev_descr_ibridge_table);
+		rc = sbridge_get_all_devices(&num_mc,
+					pci_dev_descr_ibridge_table);
 		type = IVY_BRIDGE;
 		break;
 	case PCI_DEVICE_ID_INTEL_SBRIDGE_IMC_HA0:
-		rc = sbridge_get_all_devices(&num_mc, pci_dev_descr_sbridge_table);
+		rc = sbridge_get_all_devices(&num_mc,
+					pci_dev_descr_sbridge_table);
 		type = SANDY_BRIDGE;
 		break;
 	case PCI_DEVICE_ID_INTEL_HASWELL_IMC_HA0:
-		rc = sbridge_get_all_devices(&num_mc, pci_dev_descr_haswell_table);
+		rc = sbridge_get_all_devices(&num_mc,
+					pci_dev_descr_haswell_table);
 		type = HASWELL;
 		break;
 	case PCI_DEVICE_ID_INTEL_BROADWELL_IMC_HA0:
-		rc = sbridge_get_all_devices(&num_mc, pci_dev_descr_broadwell_table);
+		rc = sbridge_get_all_devices(&num_mc,
+					pci_dev_descr_broadwell_table);
 		type = BROADWELL;
+	    break;
+	case PCI_DEVICE_ID_INTEL_KNL_IMC_SAD0:
+		rc = sbridge_get_all_devices_knl(&num_mc,
+					pci_dev_descr_knl_table);
+		type = KNIGHTS_LANDING;
 		break;
 	}
 	if (unlikely(rc < 0)) {
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/edac/skx_edac.c
@@ -0,0 +1,1121 @@
+/*
+ * EDAC driver for Intel(R) Xeon(R) Skylake processors
+ * Copyright (c) 2016, Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/pci_ids.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/edac.h>
+#include <linux/mmzone.h>
+#include <linux/smp.h>
+#include <linux/bitmap.h>
+#include <linux/math64.h>
+#include <linux/mod_devicetable.h>
+#include <asm/cpu_device_id.h>
+#include <asm/processor.h>
+#include <asm/mce.h>
+
+#include "edac_core.h"
+
+#define SKX_REVISION    " Ver: 1.0 "
+
+/*
+ * Debug macros
+ */
+#define skx_printk(level, fmt, arg...)			\
+	edac_printk(level, "skx", fmt, ##arg)
+
+#define skx_mc_printk(mci, level, fmt, arg...)		\
+	edac_mc_chipset_printk(mci, level, "skx", fmt, ##arg)
+
+/*
+ * Get a bit field at register value <v>, from bit <lo> to bit <hi>
+ */
+#define GET_BITFIELD(v, lo, hi) \
+	(((v) & GENMASK_ULL((hi), (lo))) >> (lo))
+
+static LIST_HEAD(skx_edac_list);
+
+static u64 skx_tolm, skx_tohm;
+
+#define NUM_IMC			2	/* memory controllers per socket */
+#define NUM_CHANNELS		3	/* channels per memory controller */
+#define NUM_DIMMS		2	/* Max DIMMS per channel */
+
+#define	MASK26	0x3FFFFFF		/* Mask for 2^26 */
+#define MASK29	0x1FFFFFFF		/* Mask for 2^29 */
+
+/*
+ * Each cpu socket contains some pci devices that provide global
+ * information, and also some that are local to each of the two
+ * memory controllers on the die.
+ */
+struct skx_dev {
+	struct list_head	list;
+	u8			bus[4];
+	struct pci_dev	*sad_all;
+	struct pci_dev	*util_all;
+	u32	mcroute;
+	struct skx_imc {
+		struct mem_ctl_info *mci;
+		u8	mc;	/* system wide mc# */
+		u8	lmc;	/* socket relative mc# */
+		u8	src_id, node_id;
+		struct skx_channel {
+			struct pci_dev *cdev;
+			struct skx_dimm {
+				u8	close_pg;
+				u8	bank_xor_enable;
+				u8	fine_grain_bank;
+				u8	rowbits;
+				u8	colbits;
+			} dimms[NUM_DIMMS];
+		} chan[NUM_CHANNELS];
+	} imc[NUM_IMC];
+};
+static int skx_num_sockets;
+
+struct skx_pvt {
+	struct skx_imc	*imc;
+};
+
+struct decoded_addr {
+	struct skx_dev *dev;
+	u64	addr;
+	int	socket;
+	int	imc;
+	int	channel;
+	u64	chan_addr;
+	int	sktways;
+	int	chanways;
+	int	dimm;
+	int	rank;
+	int	channel_rank;
+	u64	rank_address;
+	int	row;
+	int	column;
+	int	bank_address;
+	int	bank_group;
+};
+
+static struct skx_dev *get_skx_dev(u8 bus, u8 idx)
+{
+	struct skx_dev *d;
+
+	list_for_each_entry(d, &skx_edac_list, list) {
+		if (d->bus[idx] == bus)
+			return d;
+	}
+
+	return NULL;
+}
+
+enum munittype {
+	CHAN0, CHAN1, CHAN2, SAD_ALL, UTIL_ALL, SAD
+};
+
+struct munit {
+	u16	did;
+	u16	devfn[NUM_IMC];
+	u8	busidx;
+	u8	per_socket;
+	enum munittype mtype;
+};
+
+/*
+ * List of PCI device ids that we need together with some device
+ * number and function numbers to tell which memory controller the
+ * device belongs to.
+ */
+static const struct munit skx_all_munits[] = {
+	{ 0x2054, { }, 1, 1, SAD_ALL },
+	{ 0x2055, { }, 1, 1, UTIL_ALL },
+	{ 0x2040, { PCI_DEVFN(10, 0), PCI_DEVFN(12, 0) }, 2, 2, CHAN0 },
+	{ 0x2044, { PCI_DEVFN(10, 4), PCI_DEVFN(12, 4) }, 2, 2, CHAN1 },
+	{ 0x2048, { PCI_DEVFN(11, 0), PCI_DEVFN(13, 0) }, 2, 2, CHAN2 },
+	{ 0x208e, { }, 1, 0, SAD },
+	{ }
+};
+
+/*
+ * We use the per-socket device 0x2016 to count how many sockets are present,
+ * and to detemine which PCI buses are associated with each socket. Allocate
+ * and build the full list of all the skx_dev structures that we need here.
+ */
+static int get_all_bus_mappings(void)
+{
+	struct pci_dev *pdev, *prev;
+	struct skx_dev *d;
+	u32 reg;
+	int ndev = 0;
+
+	prev = NULL;
+	for (;;) {
+		pdev = pci_get_device(PCI_VENDOR_ID_INTEL, 0x2016, prev);
+		if (!pdev)
+			break;
+		ndev++;
+		d = kzalloc(sizeof(*d), GFP_KERNEL);
+		if (!d) {
+			pci_dev_put(pdev);
+			return -ENOMEM;
+		}
+		pci_read_config_dword(pdev, 0xCC, &reg);
+		d->bus[0] =  GET_BITFIELD(reg, 0, 7);
+		d->bus[1] =  GET_BITFIELD(reg, 8, 15);
+		d->bus[2] =  GET_BITFIELD(reg, 16, 23);
+		d->bus[3] =  GET_BITFIELD(reg, 24, 31);
+		edac_dbg(2, "busses: %x, %x, %x, %x\n",
+			 d->bus[0], d->bus[1], d->bus[2], d->bus[3]);
+		list_add_tail(&d->list, &skx_edac_list);
+		skx_num_sockets++;
+		prev = pdev;
+	}
+
+	return ndev;
+}
+
+static int get_all_munits(const struct munit *m)
+{
+	struct pci_dev *pdev, *prev;
+	struct skx_dev *d;
+	u32 reg;
+	int i = 0, ndev = 0;
+
+	prev = NULL;
+	for (;;) {
+		pdev = pci_get_device(PCI_VENDOR_ID_INTEL, m->did, prev);
+		if (!pdev)
+			break;
+		ndev++;
+		if (m->per_socket == NUM_IMC) {
+			for (i = 0; i < NUM_IMC; i++)
+				if (m->devfn[i] == pdev->devfn)
+					break;
+			if (i == NUM_IMC)
+				goto fail;
+		}
+		d = get_skx_dev(pdev->bus->number, m->busidx);
+		if (!d)
+			goto fail;
+
+		/* Be sure that the device is enabled */
+		if (unlikely(pci_enable_device(pdev) < 0)) {
+			skx_printk(KERN_ERR,
+				"Couldn't enable %04x:%04x\n", PCI_VENDOR_ID_INTEL, m->did);
+			goto fail;
+		}
+
+		switch (m->mtype) {
+		case CHAN0: case CHAN1: case CHAN2:
+			pci_dev_get(pdev);
+			d->imc[i].chan[m->mtype].cdev = pdev;
+			break;
+		case SAD_ALL:
+			pci_dev_get(pdev);
+			d->sad_all = pdev;
+			break;
+		case UTIL_ALL:
+			pci_dev_get(pdev);
+			d->util_all = pdev;
+			break;
+		case SAD:
+			/*
+			 * one of these devices per core, including cores
+			 * that don't exist on this SKU. Ignore any that
+			 * read a route table of zero, make sure all the
+			 * non-zero values match.
+			 */
+			pci_read_config_dword(pdev, 0xB4, &reg);
+			if (reg != 0) {
+				if (d->mcroute == 0)
+					d->mcroute = reg;
+				else if (d->mcroute != reg) {
+					skx_printk(KERN_ERR,
+						"mcroute mismatch\n");
+					goto fail;
+				}
+			}
+			ndev--;
+			break;
+		}
+
+		prev = pdev;
+	}
+
+	return ndev;
+fail:
+	pci_dev_put(pdev);
+	return -ENODEV;
+}
+
+const struct x86_cpu_id skx_cpuids[] = {
+	{ X86_VENDOR_INTEL, 6, 0x55, 0, 0 },	/* Skylake */
+	{ }
+};
+MODULE_DEVICE_TABLE(x86cpu, skx_cpuids);
+
+static u8 get_src_id(struct skx_dev *d)
+{
+	u32 reg;
+
+	pci_read_config_dword(d->util_all, 0xF0, &reg);
+
+	return GET_BITFIELD(reg, 12, 14);
+}
+
+static u8 skx_get_node_id(struct skx_dev *d)
+{
+	u32 reg;
+
+	pci_read_config_dword(d->util_all, 0xF4, &reg);
+
+	return GET_BITFIELD(reg, 0, 2);
+}
+
+static int get_dimm_attr(u32 reg, int lobit, int hibit, int add, int minval,
+			 int maxval, char *name)
+{
+	u32 val = GET_BITFIELD(reg, lobit, hibit);
+
+	if (val < minval || val > maxval) {
+		edac_dbg(2, "bad %s = %d (raw=%x)\n", name, val, reg);
+		return -EINVAL;
+	}
+	return val + add;
+}
+
+#define IS_DIMM_PRESENT(mtr)		GET_BITFIELD((mtr), 15, 15)
+
+#define numrank(reg) get_dimm_attr((reg), 12, 13, 0, 1, 2, "ranks")
+#define numrow(reg) get_dimm_attr((reg), 2, 4, 12, 1, 6, "rows")
+#define numcol(reg) get_dimm_attr((reg), 0, 1, 10, 0, 2, "cols")
+
+static int get_width(u32 mtr)
+{
+	switch (GET_BITFIELD(mtr, 8, 9)) {
+	case 0:
+		return DEV_X4;
+	case 1:
+		return DEV_X8;
+	case 2:
+		return DEV_X16;
+	}
+	return DEV_UNKNOWN;
+}
+
+static int skx_get_hi_lo(void)
+{
+	struct pci_dev *pdev;
+	u32 reg;
+
+	pdev = pci_get_device(PCI_VENDOR_ID_INTEL, 0x2034, NULL);
+	if (!pdev) {
+		edac_dbg(0, "Can't get tolm/tohm\n");
+		return -ENODEV;
+	}
+
+	pci_read_config_dword(pdev, 0xD0, &reg);
+	skx_tolm = reg;
+	pci_read_config_dword(pdev, 0xD4, &reg);
+	skx_tohm = reg;
+	pci_read_config_dword(pdev, 0xD8, &reg);
+	skx_tohm |= (u64)reg << 32;
+
+	pci_dev_put(pdev);
+	edac_dbg(2, "tolm=%llx tohm=%llx\n", skx_tolm, skx_tohm);
+
+	return 0;
+}
+
+static int get_dimm_info(u32 mtr, u32 amap, struct dimm_info *dimm,
+			 struct skx_imc *imc, int chan, int dimmno)
+{
+	int  banks = 16, ranks, rows, cols, npages;
+	u64 size;
+
+	if (!IS_DIMM_PRESENT(mtr))
+		return 0;
+	ranks = numrank(mtr);
+	rows = numrow(mtr);
+	cols = numcol(mtr);
+
+	/*
+	 * Compute size in 8-byte (2^3) words, then shift to MiB (2^20)
+	 */
+	size = ((1ull << (rows + cols + ranks)) * banks) >> (20 - 3);
+	npages = MiB_TO_PAGES(size);
+
+	edac_dbg(0, "mc#%d: channel %d, dimm %d, %lld Mb (%d pages) bank: %d, rank: %d, row: %#x, col: %#x\n",
+		 imc->mc, chan, dimmno, size, npages,
+		 banks, ranks, rows, cols);
+
+	imc->chan[chan].dimms[dimmno].close_pg = GET_BITFIELD(mtr, 0, 0);
+	imc->chan[chan].dimms[dimmno].bank_xor_enable = GET_BITFIELD(mtr, 9, 9);
+	imc->chan[chan].dimms[dimmno].fine_grain_bank = GET_BITFIELD(amap, 0, 0);
+	imc->chan[chan].dimms[dimmno].rowbits = rows;
+	imc->chan[chan].dimms[dimmno].colbits = cols;
+
+	dimm->nr_pages = npages;
+	dimm->grain = 32;
+	dimm->dtype = get_width(mtr);
+	dimm->mtype = MEM_DDR4;
+	dimm->edac_mode = EDAC_SECDED; /* likely better than this */
+	snprintf(dimm->label, sizeof(dimm->label), "CPU_SrcID#%u_MC#%u_Chan#%u_DIMM#%u",
+		 imc->src_id, imc->lmc, chan, dimmno);
+
+	return 1;
+}
+
+#define SKX_GET_MTMTR(dev, reg) \
+	pci_read_config_dword((dev), 0x87c, &reg)
+
+static bool skx_check_ecc(struct pci_dev *pdev)
+{
+	u32 mtmtr;
+
+	SKX_GET_MTMTR(pdev, mtmtr);
+
+	return !!GET_BITFIELD(mtmtr, 2, 2);
+}
+
+static int skx_get_dimm_config(struct mem_ctl_info *mci)
+{
+	struct skx_pvt *pvt = mci->pvt_info;
+	struct skx_imc *imc = pvt->imc;
+	struct dimm_info *dimm;
+	int i, j;
+	u32 mtr, amap;
+	int ndimms;
+
+	for (i = 0; i < NUM_CHANNELS; i++) {
+		ndimms = 0;
+		pci_read_config_dword(imc->chan[i].cdev, 0x8C, &amap);
+		for (j = 0; j < NUM_DIMMS; j++) {
+			dimm = EDAC_DIMM_PTR(mci->layers, mci->dimms,
+					     mci->n_layers, i, j, 0);
+			pci_read_config_dword(imc->chan[i].cdev,
+					0x80 + 4*j, &mtr);
+			ndimms += get_dimm_info(mtr, amap, dimm, imc, i, j);
+		}
+		if (ndimms && !skx_check_ecc(imc->chan[0].cdev)) {
+			skx_printk(KERN_ERR, "ECC is disabled on imc %d\n", imc->mc);
+			return -ENODEV;
+		}
+	}
+
+	return 0;
+}
+
+static void skx_unregister_mci(struct skx_imc *imc)
+{
+	struct mem_ctl_info *mci = imc->mci;
+
+	if (!mci)
+		return;
+
+	edac_dbg(0, "MC%d: mci = %p\n", imc->mc, mci);
+
+	/* Remove MC sysfs nodes */
+	edac_mc_del_mc(mci->pdev);
+
+	edac_dbg(1, "%s: free mci struct\n", mci->ctl_name);
+	kfree(mci->ctl_name);
+	edac_mc_free(mci);
+}
+
+static int skx_register_mci(struct skx_imc *imc)
+{
+	struct mem_ctl_info *mci;
+	struct edac_mc_layer layers[2];
+	struct pci_dev *pdev = imc->chan[0].cdev;
+	struct skx_pvt *pvt;
+	int rc;
+
+	/* allocate a new MC control structure */
+	layers[0].type = EDAC_MC_LAYER_CHANNEL;
+	layers[0].size = NUM_CHANNELS;
+	layers[0].is_virt_csrow = false;
+	layers[1].type = EDAC_MC_LAYER_SLOT;
+	layers[1].size = NUM_DIMMS;
+	layers[1].is_virt_csrow = true;
+	mci = edac_mc_alloc(imc->mc, ARRAY_SIZE(layers), layers,
+			    sizeof(struct skx_pvt));
+
+	if (unlikely(!mci))
+		return -ENOMEM;
+
+	edac_dbg(0, "MC#%d: mci = %p\n", imc->mc, mci);
+
+	/* Associate skx_dev and mci for future usage */
+	imc->mci = mci;
+	pvt = mci->pvt_info;
+	pvt->imc = imc;
+
+	mci->ctl_name = kasprintf(GFP_KERNEL, "Skylake Socket#%d IMC#%d",
+				  imc->node_id, imc->lmc);
+	mci->mtype_cap = MEM_FLAG_DDR4;
+	mci->edac_ctl_cap = EDAC_FLAG_NONE;
+	mci->edac_cap = EDAC_FLAG_NONE;
+	mci->mod_name = "skx_edac.c";
+	mci->dev_name = pci_name(imc->chan[0].cdev);
+	mci->mod_ver = SKX_REVISION;
+	mci->ctl_page_to_phys = NULL;
+
+	rc = skx_get_dimm_config(mci);
+	if (rc < 0)
+		goto fail;
+
+	/* record ptr to the generic device */
+	mci->pdev = &pdev->dev;
+
+	/* add this new MC control structure to EDAC's list of MCs */
+	if (unlikely(edac_mc_add_mc(mci))) {
+		edac_dbg(0, "MC: failed edac_mc_add_mc()\n");
+		rc = -EINVAL;
+		goto fail;
+	}
+
+	return 0;
+
+fail:
+	kfree(mci->ctl_name);
+	edac_mc_free(mci);
+	imc->mci = NULL;
+	return rc;
+}
+
+#define	SKX_MAX_SAD 24
+
+#define SKX_GET_SAD(d, i, reg)	\
+	pci_read_config_dword((d)->sad_all, 0x60 + 8 * (i), &reg)
+#define SKX_GET_ILV(d, i, reg)	\
+	pci_read_config_dword((d)->sad_all, 0x64 + 8 * (i), &reg)
+
+#define	SKX_SAD_MOD3MODE(sad)	GET_BITFIELD((sad), 30, 31)
+#define	SKX_SAD_MOD3(sad)	GET_BITFIELD((sad), 27, 27)
+#define SKX_SAD_LIMIT(sad)	(((u64)GET_BITFIELD((sad), 7, 26) << 26) | MASK26)
+#define	SKX_SAD_MOD3ASMOD2(sad)	GET_BITFIELD((sad), 5, 6)
+#define	SKX_SAD_ATTR(sad)	GET_BITFIELD((sad), 3, 4)
+#define	SKX_SAD_INTERLEAVE(sad)	GET_BITFIELD((sad), 1, 2)
+#define SKX_SAD_ENABLE(sad)	GET_BITFIELD((sad), 0, 0)
+
+#define SKX_ILV_REMOTE(tgt)	(((tgt) & 8) == 0)
+#define SKX_ILV_TARGET(tgt)	((tgt) & 7)
+
+static bool skx_sad_decode(struct decoded_addr *res)
+{
+	struct skx_dev *d = list_first_entry(&skx_edac_list, typeof(*d), list);
+	u64 addr = res->addr;
+	int i, idx, tgt, lchan, shift;
+	u32 sad, ilv;
+	u64 limit, prev_limit;
+	int remote = 0;
+
+	/* Simple sanity check for I/O space or out of range */
+	if (addr >= skx_tohm || (addr >= skx_tolm && addr < BIT_ULL(32))) {
+		edac_dbg(0, "Address %llx out of range\n", addr);
+		return false;
+	}
+
+restart:
+	prev_limit = 0;
+	for (i = 0; i < SKX_MAX_SAD; i++) {
+		SKX_GET_SAD(d, i, sad);
+		limit = SKX_SAD_LIMIT(sad);
+		if (SKX_SAD_ENABLE(sad)) {
+			if (addr >= prev_limit && addr <= limit)
+				goto sad_found;
+		}
+		prev_limit = limit + 1;
+	}
+	edac_dbg(0, "No SAD entry for %llx\n", addr);
+	return false;
+
+sad_found:
+	SKX_GET_ILV(d, i, ilv);
+
+	switch (SKX_SAD_INTERLEAVE(sad)) {
+	case 0:
+		idx = GET_BITFIELD(addr, 6, 8);
+		break;
+	case 1:
+		idx = GET_BITFIELD(addr, 8, 10);
+		break;
+	case 2:
+		idx = GET_BITFIELD(addr, 12, 14);
+		break;
+	case 3:
+		idx = GET_BITFIELD(addr, 30, 32);
+		break;
+	}
+
+	tgt = GET_BITFIELD(ilv, 4 * idx, 4 * idx + 3);
+
+	/* If point to another node, find it and start over */
+	if (SKX_ILV_REMOTE(tgt)) {
+		if (remote) {
+			edac_dbg(0, "Double remote!\n");
+			return false;
+		}
+		remote = 1;
+		list_for_each_entry(d, &skx_edac_list, list) {
+			if (d->imc[0].src_id == SKX_ILV_TARGET(tgt))
+				goto restart;
+		}
+		edac_dbg(0, "Can't find node %d\n", SKX_ILV_TARGET(tgt));
+		return false;
+	}
+
+	if (SKX_SAD_MOD3(sad) == 0)
+		lchan = SKX_ILV_TARGET(tgt);
+	else {
+		switch (SKX_SAD_MOD3MODE(sad)) {
+		case 0:
+			shift = 6;
+			break;
+		case 1:
+			shift = 8;
+			break;
+		case 2:
+			shift = 12;
+			break;
+		default:
+			edac_dbg(0, "illegal mod3mode\n");
+			return false;
+		}
+		switch (SKX_SAD_MOD3ASMOD2(sad)) {
+		case 0:
+			lchan = (addr >> shift) % 3;
+			break;
+		case 1:
+			lchan = (addr >> shift) % 2;
+			break;
+		case 2:
+			lchan = (addr >> shift) % 2;
+			lchan = (lchan << 1) | ~lchan;
+			break;
+		case 3:
+			lchan = ((addr >> shift) % 2) << 1;
+			break;
+		}
+		lchan = (lchan << 1) | (SKX_ILV_TARGET(tgt) & 1);
+	}
+
+	res->dev = d;
+	res->socket = d->imc[0].src_id;
+	res->imc = GET_BITFIELD(d->mcroute, lchan * 3, lchan * 3 + 2);
+	res->channel = GET_BITFIELD(d->mcroute, lchan * 2 + 18, lchan * 2 + 19);
+
+	edac_dbg(2, "%llx: socket=%d imc=%d channel=%d\n",
+		 res->addr, res->socket, res->imc, res->channel);
+	return true;
+}
+
+#define	SKX_MAX_TAD 8
+
+#define SKX_GET_TADBASE(d, mc, i, reg)			\
+	pci_read_config_dword((d)->imc[mc].chan[0].cdev, 0x850 + 4 * (i), &reg)
+#define SKX_GET_TADWAYNESS(d, mc, i, reg)		\
+	pci_read_config_dword((d)->imc[mc].chan[0].cdev, 0x880 + 4 * (i), &reg)
+#define SKX_GET_TADCHNILVOFFSET(d, mc, ch, i, reg)	\
+	pci_read_config_dword((d)->imc[mc].chan[ch].cdev, 0x90 + 4 * (i), &reg)
+
+#define	SKX_TAD_BASE(b)		((u64)GET_BITFIELD((b), 12, 31) << 26)
+#define SKX_TAD_SKT_GRAN(b)	GET_BITFIELD((b), 4, 5)
+#define SKX_TAD_CHN_GRAN(b)	GET_BITFIELD((b), 6, 7)
+#define	SKX_TAD_LIMIT(b)	(((u64)GET_BITFIELD((b), 12, 31) << 26) | MASK26)
+#define	SKX_TAD_OFFSET(b)	((u64)GET_BITFIELD((b), 4, 23) << 26)
+#define	SKX_TAD_SKTWAYS(b)	(1 << GET_BITFIELD((b), 10, 11))
+#define	SKX_TAD_CHNWAYS(b)	(GET_BITFIELD((b), 8, 9) + 1)
+
+/* which bit used for both socket and channel interleave */
+static int skx_granularity[] = { 6, 8, 12, 30 };
+
+static u64 skx_do_interleave(u64 addr, int shift, int ways, u64 lowbits)
+{
+	addr >>= shift;
+	addr /= ways;
+	addr <<= shift;
+
+	return addr | (lowbits & ((1ull << shift) - 1));
+}
+
+static bool skx_tad_decode(struct decoded_addr *res)
+{
+	int i;
+	u32 base, wayness, chnilvoffset;
+	int skt_interleave_bit, chn_interleave_bit;
+	u64 channel_addr;
+
+	for (i = 0; i < SKX_MAX_TAD; i++) {
+		SKX_GET_TADBASE(res->dev, res->imc, i, base);
+		SKX_GET_TADWAYNESS(res->dev, res->imc, i, wayness);
+		if (SKX_TAD_BASE(base) <= res->addr && res->addr <= SKX_TAD_LIMIT(wayness))
+			goto tad_found;
+	}
+	edac_dbg(0, "No TAD entry for %llx\n", res->addr);
+	return false;
+
+tad_found:
+	res->sktways = SKX_TAD_SKTWAYS(wayness);
+	res->chanways = SKX_TAD_CHNWAYS(wayness);
+	skt_interleave_bit = skx_granularity[SKX_TAD_SKT_GRAN(base)];
+	chn_interleave_bit = skx_granularity[SKX_TAD_CHN_GRAN(base)];
+
+	SKX_GET_TADCHNILVOFFSET(res->dev, res->imc, res->channel, i, chnilvoffset);
+	channel_addr = res->addr - SKX_TAD_OFFSET(chnilvoffset);
+
+	if (res->chanways == 3 && skt_interleave_bit > chn_interleave_bit) {
+		/* Must handle channel first, then socket */
+		channel_addr = skx_do_interleave(channel_addr, chn_interleave_bit,
+						 res->chanways, channel_addr);
+		channel_addr = skx_do_interleave(channel_addr, skt_interleave_bit,
+						 res->sktways, channel_addr);
+	} else {
+		/* Handle socket then channel. Preserve low bits from original address */
+		channel_addr = skx_do_interleave(channel_addr, skt_interleave_bit,
+						 res->sktways, res->addr);
+		channel_addr = skx_do_interleave(channel_addr, chn_interleave_bit,
+						 res->chanways, res->addr);
+	}
+
+	res->chan_addr = channel_addr;
+
+	edac_dbg(2, "%llx: chan_addr=%llx sktways=%d chanways=%d\n",
+		 res->addr, res->chan_addr, res->sktways, res->chanways);
+	return true;
+}
+
+#define SKX_MAX_RIR 4
+
+#define SKX_GET_RIRWAYNESS(d, mc, ch, i, reg)		\
+	pci_read_config_dword((d)->imc[mc].chan[ch].cdev,	\
+			      0x108 + 4 * (i), &reg)
+#define SKX_GET_RIRILV(d, mc, ch, idx, i, reg)		\
+	pci_read_config_dword((d)->imc[mc].chan[ch].cdev,	\
+			      0x120 + 16 * idx + 4 * (i), &reg)
+
+#define	SKX_RIR_VALID(b) GET_BITFIELD((b), 31, 31)
+#define	SKX_RIR_LIMIT(b) (((u64)GET_BITFIELD((b), 1, 11) << 29) | MASK29)
+#define	SKX_RIR_WAYS(b) (1 << GET_BITFIELD((b), 28, 29))
+#define	SKX_RIR_CHAN_RANK(b) GET_BITFIELD((b), 16, 19)
+#define	SKX_RIR_OFFSET(b) ((u64)(GET_BITFIELD((b), 2, 15) << 26))
+
+static bool skx_rir_decode(struct decoded_addr *res)
+{
+	int i, idx, chan_rank;
+	int shift;
+	u32 rirway, rirlv;
+	u64 rank_addr, prev_limit = 0, limit;
+
+	if (res->dev->imc[res->imc].chan[res->channel].dimms[0].close_pg)
+		shift = 6;
+	else
+		shift = 13;
+
+	for (i = 0; i < SKX_MAX_RIR; i++) {
+		SKX_GET_RIRWAYNESS(res->dev, res->imc, res->channel, i, rirway);
+		limit = SKX_RIR_LIMIT(rirway);
+		if (SKX_RIR_VALID(rirway)) {
+			if (prev_limit <= res->chan_addr &&
+			    res->chan_addr <= limit)
+				goto rir_found;
+		}
+		prev_limit = limit;
+	}
+	edac_dbg(0, "No RIR entry for %llx\n", res->addr);
+	return false;
+
+rir_found:
+	rank_addr = res->chan_addr >> shift;
+	rank_addr /= SKX_RIR_WAYS(rirway);
+	rank_addr <<= shift;
+	rank_addr |= res->chan_addr & GENMASK_ULL(shift - 1, 0);
+
+	res->rank_address = rank_addr;
+	idx = (res->chan_addr >> shift) % SKX_RIR_WAYS(rirway);
+
+	SKX_GET_RIRILV(res->dev, res->imc, res->channel, idx, i, rirlv);
+	res->rank_address = rank_addr - SKX_RIR_OFFSET(rirlv);
+	chan_rank = SKX_RIR_CHAN_RANK(rirlv);
+	res->channel_rank = chan_rank;
+	res->dimm = chan_rank / 4;
+	res->rank = chan_rank % 4;
+
+	edac_dbg(2, "%llx: dimm=%d rank=%d chan_rank=%d rank_addr=%llx\n",
+		 res->addr, res->dimm, res->rank,
+		 res->channel_rank, res->rank_address);
+	return true;
+}
+
+static u8 skx_close_row[] = {
+	15, 16, 17, 18, 20, 21, 22, 28, 10, 11, 12, 13, 29, 30, 31, 32, 33
+};
+static u8 skx_close_column[] = {
+	3, 4, 5, 14, 19, 23, 24, 25, 26, 27
+};
+static u8 skx_open_row[] = {
+	14, 15, 16, 20, 28, 21, 22, 23, 24, 25, 26, 27, 29, 30, 31, 32, 33
+};
+static u8 skx_open_column[] = {
+	3, 4, 5, 6, 7, 8, 9, 10, 11, 12
+};
+static u8 skx_open_fine_column[] = {
+	3, 4, 5, 7, 8, 9, 10, 11, 12, 13
+};
+
+static int skx_bits(u64 addr, int nbits, u8 *bits)
+{
+	int i, res = 0;
+
+	for (i = 0; i < nbits; i++)
+		res |= ((addr >> bits[i]) & 1) << i;
+	return res;
+}
+
+static int skx_bank_bits(u64 addr, int b0, int b1, int do_xor, int x0, int x1)
+{
+	int ret = GET_BITFIELD(addr, b0, b0) | (GET_BITFIELD(addr, b1, b1) << 1);
+
+	if (do_xor)
+		ret ^= GET_BITFIELD(addr, x0, x0) | (GET_BITFIELD(addr, x1, x1) << 1);
+
+	return ret;
+}
+
+static bool skx_mad_decode(struct decoded_addr *r)
+{
+	struct skx_dimm *dimm = &r->dev->imc[r->imc].chan[r->channel].dimms[r->dimm];
+	int bg0 = dimm->fine_grain_bank ? 6 : 13;
+
+	if (dimm->close_pg) {
+		r->row = skx_bits(r->rank_address, dimm->rowbits, skx_close_row);
+		r->column = skx_bits(r->rank_address, dimm->colbits, skx_close_column);
+		r->column |= 0x400; /* C10 is autoprecharge, always set */
+		r->bank_address = skx_bank_bits(r->rank_address, 8, 9, dimm->bank_xor_enable, 22, 28);
+		r->bank_group = skx_bank_bits(r->rank_address, 6, 7, dimm->bank_xor_enable, 20, 21);
+	} else {
+		r->row = skx_bits(r->rank_address, dimm->rowbits, skx_open_row);
+		if (dimm->fine_grain_bank)
+			r->column = skx_bits(r->rank_address, dimm->colbits, skx_open_fine_column);
+		else
+			r->column = skx_bits(r->rank_address, dimm->colbits, skx_open_column);
+		r->bank_address = skx_bank_bits(r->rank_address, 18, 19, dimm->bank_xor_enable, 22, 23);
+		r->bank_group = skx_bank_bits(r->rank_address, bg0, 17, dimm->bank_xor_enable, 20, 21);
+	}
+	r->row &= (1u << dimm->rowbits) - 1;
+
+	edac_dbg(2, "%llx: row=%x col=%x bank_addr=%d bank_group=%d\n",
+		 r->addr, r->row, r->column, r->bank_address,
+		 r->bank_group);
+	return true;
+}
+
+static bool skx_decode(struct decoded_addr *res)
+{
+
+	return skx_sad_decode(res) && skx_tad_decode(res) &&
+		skx_rir_decode(res) && skx_mad_decode(res);
+}
+
+#ifdef CONFIG_EDAC_DEBUG
+/*
+ * Debug feature. Make /sys/kernel/debug/skx_edac_test/addr.
+ * Write an address to this file to exercise the address decode
+ * logic in this driver.
+ */
+static struct dentry *skx_test;
+static u64 skx_fake_addr;
+
+static int debugfs_u64_set(void *data, u64 val)
+{
+	struct decoded_addr res;
+
+	res.addr = val;
+	skx_decode(&res);
+
+	return 0;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(fops_u64_wo, NULL, debugfs_u64_set, "%llu\n");
+
+static struct dentry *mydebugfs_create(const char *name, umode_t mode,
+				       struct dentry *parent, u64 *value)
+{
+	return debugfs_create_file(name, mode, parent, value, &fops_u64_wo);
+}
+
+static void setup_skx_debug(void)
+{
+	skx_test = debugfs_create_dir("skx_edac_test", NULL);
+	mydebugfs_create("addr", S_IWUSR, skx_test, &skx_fake_addr);
+}
+
+static void teardown_skx_debug(void)
+{
+	debugfs_remove_recursive(skx_test);
+}
+#else
+static void setup_skx_debug(void)
+{
+}
+
+static void teardown_skx_debug(void)
+{
+}
+#endif /*CONFIG_EDAC_DEBUG*/
+
+static void skx_mce_output_error(struct mem_ctl_info *mci,
+				 const struct mce *m,
+				 struct decoded_addr *res)
+{
+	enum hw_event_mc_err_type tp_event;
+	char *type, *optype, msg[256];
+	bool ripv = GET_BITFIELD(m->mcgstatus, 0, 0);
+	bool overflow = GET_BITFIELD(m->status, 62, 62);
+	bool uncorrected_error = GET_BITFIELD(m->status, 61, 61);
+	bool recoverable;
+	u32 core_err_cnt = GET_BITFIELD(m->status, 38, 52);
+	u32 mscod = GET_BITFIELD(m->status, 16, 31);
+	u32 errcode = GET_BITFIELD(m->status, 0, 15);
+	u32 optypenum = GET_BITFIELD(m->status, 4, 6);
+
+	recoverable = GET_BITFIELD(m->status, 56, 56);
+
+	if (uncorrected_error) {
+		if (ripv) {
+			type = "FATAL";
+			tp_event = HW_EVENT_ERR_FATAL;
+		} else {
+			type = "NON_FATAL";
+			tp_event = HW_EVENT_ERR_UNCORRECTED;
+		}
+	} else {
+		type = "CORRECTED";
+		tp_event = HW_EVENT_ERR_CORRECTED;
+	}
+
+	/*
+	 * According with Table 15-9 of the Intel Architecture spec vol 3A,
+	 * memory errors should fit in this mask:
+	 *	000f 0000 1mmm cccc (binary)
+	 * where:
+	 *	f = Correction Report Filtering Bit. If 1, subsequent errors
+	 *	    won't be shown
+	 *	mmm = error type
+	 *	cccc = channel
+	 * If the mask doesn't match, report an error to the parsing logic
+	 */
+	if (!((errcode & 0xef80) == 0x80)) {
+		optype = "Can't parse: it is not a mem";
+	} else {
+		switch (optypenum) {
+		case 0:
+			optype = "generic undef request error";
+			break;
+		case 1:
+			optype = "memory read error";
+			break;
+		case 2:
+			optype = "memory write error";
+			break;
+		case 3:
+			optype = "addr/cmd error";
+			break;
+		case 4:
+			optype = "memory scrubbing error";
+			break;
+		default:
+			optype = "reserved";
+			break;
+		}
+	}
+
+	snprintf(msg, sizeof(msg),
+		 "%s%s err_code:%04x:%04x socket:%d imc:%d rank:%d bg:%d ba:%d row:%x col:%x",
+		 overflow ? " OVERFLOW" : "",
+		 (uncorrected_error && recoverable) ? " recoverable" : "",
+		 mscod, errcode,
+		 res->socket, res->imc, res->rank,
+		 res->bank_group, res->bank_address, res->row, res->column);
+
+	edac_dbg(0, "%s\n", msg);
+
+	/* Call the helper to output message */
+	edac_mc_handle_error(tp_event, mci, core_err_cnt,
+			     m->addr >> PAGE_SHIFT, m->addr & ~PAGE_MASK, 0,
+			     res->channel, res->dimm, -1,
+			     optype, msg);
+}
+
+static int skx_mce_check_error(struct notifier_block *nb, unsigned long val,
+			       void *data)
+{
+	struct mce *mce = (struct mce *)data;
+	struct decoded_addr res;
+	struct mem_ctl_info *mci;
+	char *type;
+
+	if (get_edac_report_status() == EDAC_REPORTING_DISABLED)
+		return NOTIFY_DONE;
+
+	/* ignore unless this is memory related with an address */
+	if ((mce->status & 0xefff) >> 7 != 1 || !(mce->status & MCI_STATUS_ADDRV))
+		return NOTIFY_DONE;
+
+	res.addr = mce->addr;
+	if (!skx_decode(&res))
+		return NOTIFY_DONE;
+	mci = res.dev->imc[res.imc].mci;
+
+	if (mce->mcgstatus & MCG_STATUS_MCIP)
+		type = "Exception";
+	else
+		type = "Event";
+
+	skx_mc_printk(mci, KERN_DEBUG, "HANDLING MCE MEMORY ERROR\n");
+
+	skx_mc_printk(mci, KERN_DEBUG, "CPU %d: Machine Check %s: %Lx "
+			  "Bank %d: %016Lx\n", mce->extcpu, type,
+			  mce->mcgstatus, mce->bank, mce->status);
+	skx_mc_printk(mci, KERN_DEBUG, "TSC %llx ", mce->tsc);
+	skx_mc_printk(mci, KERN_DEBUG, "ADDR %llx ", mce->addr);
+	skx_mc_printk(mci, KERN_DEBUG, "MISC %llx ", mce->misc);
+
+	skx_mc_printk(mci, KERN_DEBUG, "PROCESSOR %u:%x TIME %llu SOCKET "
+			  "%u APIC %x\n", mce->cpuvendor, mce->cpuid,
+			  mce->time, mce->socketid, mce->apicid);
+
+	skx_mce_output_error(mci, mce, &res);
+
+	return NOTIFY_DONE;
+}
+
+static struct notifier_block skx_mce_dec = {
+	.notifier_call = skx_mce_check_error,
+};
+
+static void skx_remove(void)
+{
+	int i, j;
+	struct skx_dev *d, *tmp;
+
+	edac_dbg(0, "\n");
+
+	list_for_each_entry_safe(d, tmp, &skx_edac_list, list) {
+		list_del(&d->list);
+		for (i = 0; i < NUM_IMC; i++) {
+			skx_unregister_mci(&d->imc[i]);
+			for (j = 0; j < NUM_CHANNELS; j++)
+				pci_dev_put(d->imc[i].chan[j].cdev);
+		}
+		pci_dev_put(d->util_all);
+		pci_dev_put(d->sad_all);
+
+		kfree(d);
+	}
+}
+
+/*
+ * skx_init:
+ *	make sure we are running on the correct cpu model
+ *	search for all the devices we need
+ *	check which DIMMs are present.
+ */
+int __init skx_init(void)
+{
+	const struct x86_cpu_id *id;
+	const struct munit *m;
+	int rc = 0, i;
+	u8 mc = 0, src_id, node_id;
+	struct skx_dev *d;
+
+	edac_dbg(2, "\n");
+
+	id = x86_match_cpu(skx_cpuids);
+	if (!id)
+		return -ENODEV;
+
+	rc = skx_get_hi_lo();
+	if (rc)
+		return rc;
+
+	rc = get_all_bus_mappings();
+	if (rc < 0)
+		goto fail;
+	if (rc == 0) {
+		edac_dbg(2, "No memory controllers found\n");
+		return -ENODEV;
+	}
+
+	for (m = skx_all_munits; m->did; m++) {
+		rc = get_all_munits(m);
+		if (rc < 0)
+			goto fail;
+		if (rc != m->per_socket * skx_num_sockets) {
+			edac_dbg(2, "Expected %d, got %d of %x\n",
+				 m->per_socket * skx_num_sockets, rc, m->did);
+			rc = -ENODEV;
+			goto fail;
+		}
+	}
+
+	list_for_each_entry(d, &skx_edac_list, list) {
+		src_id = get_src_id(d);
+		node_id = skx_get_node_id(d);
+		edac_dbg(2, "src_id=%d node_id=%d\n", src_id, node_id);
+		for (i = 0; i < NUM_IMC; i++) {
+			d->imc[i].mc = mc++;
+			d->imc[i].lmc = i;
+			d->imc[i].src_id = src_id;
+			d->imc[i].node_id = node_id;
+			rc = skx_register_mci(&d->imc[i]);
+			if (rc < 0)
+				goto fail;
+		}
+	}
+
+	/* Ensure that the OPSTATE is set correctly for POLL or NMI */
+	opstate_init();
+
+	setup_skx_debug();
+
+	mce_register_decode_chain(&skx_mce_dec);
+
+	return 0;
+fail:
+	skx_remove();
+	return rc;
+}
+
+static void __exit skx_exit(void)
+{
+	edac_dbg(2, "\n");
+	mce_unregister_decode_chain(&skx_mce_dec);
+	skx_remove();
+	teardown_skx_debug();
+}
+
+module_init(skx_init);
+module_exit(skx_exit);
+
+module_param(edac_op_state, int, 0444);
+MODULE_PARM_DESC(edac_op_state, "EDAC Error Reporting state: 0=Poll,1=NMI");
+
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Tony Luck");
+MODULE_DESCRIPTION("MC Driver for Intel Skylake server processors");
--- zfcpdump-kernel-4.4.orig/drivers/extcon/extcon-max77843.c
+++ zfcpdump-kernel-4.4/drivers/extcon/extcon-max77843.c
@@ -803,7 +803,7 @@ static int max77843_muic_probe(struct pl
 	/* Clear IRQ bits before request IRQs */
 	ret = regmap_bulk_read(max77843->regmap_muic,
 			MAX77843_MUIC_REG_INT1, info->status,
-			MAX77843_MUIC_IRQ_NUM);
+			MAX77843_MUIC_STATUS_NUM);
 	if (ret) {
 		dev_err(&pdev->dev, "Failed to Clear IRQ bits\n");
 		goto err_muic_irq;
--- zfcpdump-kernel-4.4.orig/drivers/firmware/efi/efi.c
+++ zfcpdump-kernel-4.4/drivers/firmware/efi/efi.c
@@ -180,6 +180,7 @@ static int generic_ops_register(void)
 {
 	generic_ops.get_variable = efi.get_variable;
 	generic_ops.set_variable = efi.set_variable;
+	generic_ops.set_variable_nonblocking = efi.set_variable_nonblocking;
 	generic_ops.get_next_variable = efi.get_next_variable;
 	generic_ops.query_variable_store = efi_query_variable_store;
 
@@ -611,13 +612,16 @@ char * __init efi_md_typeattr_format(cha
 	if (attr & ~(EFI_MEMORY_UC | EFI_MEMORY_WC | EFI_MEMORY_WT |
 		     EFI_MEMORY_WB | EFI_MEMORY_UCE | EFI_MEMORY_RO |
 		     EFI_MEMORY_WP | EFI_MEMORY_RP | EFI_MEMORY_XP |
+		     EFI_MEMORY_NV |
 		     EFI_MEMORY_RUNTIME | EFI_MEMORY_MORE_RELIABLE))
 		snprintf(pos, size, "|attr=0x%016llx]",
 			 (unsigned long long)attr);
 	else
-		snprintf(pos, size, "|%3s|%2s|%2s|%2s|%2s|%2s|%3s|%2s|%2s|%2s|%2s]",
+		snprintf(pos, size,
+			 "|%3s|%2s|%2s|%2s|%2s|%2s|%2s|%3s|%2s|%2s|%2s|%2s]",
 			 attr & EFI_MEMORY_RUNTIME ? "RUN" : "",
 			 attr & EFI_MEMORY_MORE_RELIABLE ? "MR" : "",
+			 attr & EFI_MEMORY_NV      ? "NV"  : "",
 			 attr & EFI_MEMORY_XP      ? "XP"  : "",
 			 attr & EFI_MEMORY_RP      ? "RP"  : "",
 			 attr & EFI_MEMORY_WP      ? "WP"  : "",
--- zfcpdump-kernel-4.4.orig/drivers/firmware/efi/efivars.c
+++ zfcpdump-kernel-4.4/drivers/firmware/efi/efivars.c
@@ -221,7 +221,7 @@ sanity_check(struct efi_variable *var, e
 	}
 
 	if ((attributes & ~EFI_VARIABLE_MASK) != 0 ||
-	    efivar_validate(name, data, size) == false) {
+	    efivar_validate(vendor, name, data, size) == false) {
 		printk(KERN_ERR "efivars: Malformed variable content\n");
 		return -EINVAL;
 	}
@@ -447,7 +447,8 @@ static ssize_t efivar_create(struct file
 	}
 
 	if ((attributes & ~EFI_VARIABLE_MASK) != 0 ||
-	    efivar_validate(name, data, size) == false) {
+	    efivar_validate(new_var->VendorGuid, name, data,
+			    size) == false) {
 		printk(KERN_ERR "efivars: Malformed variable content\n");
 		return -EINVAL;
 	}
@@ -540,38 +541,30 @@ static ssize_t efivar_delete(struct file
 static int
 efivar_create_sysfs_entry(struct efivar_entry *new_var)
 {
-	int i, short_name_size;
+	int short_name_size;
 	char *short_name;
-	unsigned long variable_name_size;
-	efi_char16_t *variable_name;
+	unsigned long utf8_name_size;
+	efi_char16_t *variable_name = new_var->var.VariableName;
 	int ret;
 
-	variable_name = new_var->var.VariableName;
-	variable_name_size = ucs2_strlen(variable_name) * sizeof(efi_char16_t);
-
 	/*
-	 * Length of the variable bytes in ASCII, plus the '-' separator,
+	 * Length of the variable bytes in UTF8, plus the '-' separator,
 	 * plus the GUID, plus trailing NUL
 	 */
-	short_name_size = variable_name_size / sizeof(efi_char16_t)
-				+ 1 + EFI_VARIABLE_GUID_LEN + 1;
-
-	short_name = kzalloc(short_name_size, GFP_KERNEL);
+	utf8_name_size = ucs2_utf8size(variable_name);
+	short_name_size = utf8_name_size + 1 + EFI_VARIABLE_GUID_LEN + 1;
 
+	short_name = kmalloc(short_name_size, GFP_KERNEL);
 	if (!short_name)
 		return -ENOMEM;
 
-	/* Convert Unicode to normal chars (assume top bits are 0),
-	   ala UTF-8 */
-	for (i=0; i < (int)(variable_name_size / sizeof(efi_char16_t)); i++) {
-		short_name[i] = variable_name[i] & 0xFF;
-	}
+	ucs2_as_utf8(short_name, variable_name, short_name_size);
+
 	/* This is ugly, but necessary to separate one vendor's
 	   private variables from another's.         */
-
-	*(short_name + strlen(short_name)) = '-';
+	short_name[utf8_name_size] = '-';
 	efi_guid_to_str(&new_var->var.VendorGuid,
-			 short_name + strlen(short_name));
+			 short_name + utf8_name_size + 1);
 
 	new_var->kobj.kset = efivars_kset;
 
--- zfcpdump-kernel-4.4.orig/drivers/firmware/efi/libstub/Makefile
+++ zfcpdump-kernel-4.4/drivers/firmware/efi/libstub/Makefile
@@ -34,7 +34,7 @@ $(obj)/lib-%.o: $(srctree)/lib/%.c FORCE
 lib-$(CONFIG_EFI_ARMSTUB)	+= arm-stub.o fdt.o string.o \
 				   $(patsubst %.c,lib-%.o,$(arm-deps))
 
-lib-$(CONFIG_ARM64)		+= arm64-stub.o
+lib-$(CONFIG_ARM64)		+= arm64-stub.o random.o
 CFLAGS_arm64-stub.o 		:= -DTEXT_OFFSET=$(TEXT_OFFSET)
 
 #
--- zfcpdump-kernel-4.4.orig/drivers/firmware/efi/libstub/efistub.h
+++ zfcpdump-kernel-4.4/drivers/firmware/efi/libstub/efistub.h
@@ -43,4 +43,7 @@ void efi_get_virtmap(efi_memory_desc_t *
 		     unsigned long desc_size, efi_memory_desc_t *runtime_map,
 		     int *count);
 
+efi_status_t efi_get_random_bytes(efi_system_table_t *sys_table,
+				  unsigned long size, u8 *out);
+
 #endif
--- zfcpdump-kernel-4.4.orig/drivers/firmware/efi/libstub/fdt.c
+++ zfcpdump-kernel-4.4/drivers/firmware/efi/libstub/fdt.c
@@ -24,7 +24,7 @@ efi_status_t update_fdt(efi_system_table
 			unsigned long map_size, unsigned long desc_size,
 			u32 desc_ver)
 {
-	int node, prev, num_rsv;
+	int node, num_rsv;
 	int status;
 	u32 fdt_val32;
 	u64 fdt_val64;
@@ -54,28 +54,6 @@ efi_status_t update_fdt(efi_system_table
 		goto fdt_set_fail;
 
 	/*
-	 * Delete any memory nodes present. We must delete nodes which
-	 * early_init_dt_scan_memory may try to use.
-	 */
-	prev = 0;
-	for (;;) {
-		const char *type;
-		int len;
-
-		node = fdt_next_node(fdt, prev, NULL);
-		if (node < 0)
-			break;
-
-		type = fdt_getprop(fdt, node, "device_type", &len);
-		if (type && strncmp(type, "memory", len) == 0) {
-			fdt_del_node(fdt, node);
-			continue;
-		}
-
-		prev = node;
-	}
-
-	/*
 	 * Delete all memory reserve map entries. When booting via UEFI,
 	 * kernel will use the UEFI memory map to find reserved regions.
 	 */
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/firmware/efi/libstub/random.c
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2016 Linaro Ltd;  <ard.biesheuvel@linaro.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/efi.h>
+#include <asm/efi.h>
+
+#include "efistub.h"
+
+struct efi_rng_protocol {
+	efi_status_t (*get_info)(struct efi_rng_protocol *,
+				 unsigned long *, efi_guid_t *);
+	efi_status_t (*get_rng)(struct efi_rng_protocol *,
+				efi_guid_t *, unsigned long, u8 *out);
+};
+
+efi_status_t efi_get_random_bytes(efi_system_table_t *sys_table_arg,
+				  unsigned long size, u8 *out)
+{
+	efi_guid_t rng_proto = EFI_RNG_PROTOCOL_GUID;
+	efi_status_t status;
+	struct efi_rng_protocol *rng;
+
+	status = efi_call_early(locate_protocol, &rng_proto, NULL,
+				(void **)&rng);
+	if (status != EFI_SUCCESS)
+		return status;
+
+	return rng->get_rng(rng, NULL, size, out);
+}
--- zfcpdump-kernel-4.4.orig/drivers/firmware/efi/runtime-wrappers.c
+++ zfcpdump-kernel-4.4/drivers/firmware/efi/runtime-wrappers.c
@@ -230,6 +230,27 @@ static efi_status_t virt_efi_query_varia
 	return status;
 }
 
+static efi_status_t
+virt_efi_query_variable_info_nonblocking(u32 attr,
+					 u64 *storage_space,
+					 u64 *remaining_space,
+					 u64 *max_variable_size)
+{
+	unsigned long flags;
+	efi_status_t status;
+
+	if (efi.runtime_version < EFI_2_00_SYSTEM_TABLE_REVISION)
+		return EFI_UNSUPPORTED;
+
+	if (!spin_trylock_irqsave(&efi_runtime_lock, flags))
+		return EFI_NOT_READY;
+
+	status = efi_call_virt(query_variable_info, attr, storage_space,
+			       remaining_space, max_variable_size);
+	spin_unlock_irqrestore(&efi_runtime_lock, flags);
+	return status;
+}
+
 static efi_status_t virt_efi_get_next_high_mono_count(u32 *count)
 {
 	unsigned long flags;
@@ -300,6 +321,7 @@ void efi_native_runtime_setup(void)
 	efi.get_next_high_mono_count = virt_efi_get_next_high_mono_count;
 	efi.reset_system = virt_efi_reset_system;
 	efi.query_variable_info = virt_efi_query_variable_info;
+	efi.query_variable_info_nonblocking = virt_efi_query_variable_info_nonblocking;
 	efi.update_capsule = virt_efi_update_capsule;
 	efi.query_capsule_caps = virt_efi_query_capsule_caps;
 }
--- zfcpdump-kernel-4.4.orig/drivers/firmware/efi/vars.c
+++ zfcpdump-kernel-4.4/drivers/firmware/efi/vars.c
@@ -165,67 +165,148 @@ validate_ascii_string(efi_char16_t *var_
 }
 
 struct variable_validate {
+	efi_guid_t vendor;
 	char *name;
 	bool (*validate)(efi_char16_t *var_name, int match, u8 *data,
 			 unsigned long len);
 };
 
+/*
+ * This is the list of variables we need to validate, as well as the
+ * whitelist for what we think is safe not to default to immutable.
+ *
+ * If it has a validate() method that's not NULL, it'll go into the
+ * validation routine.  If not, it is assumed valid, but still used for
+ * whitelisting.
+ *
+ * Note that it's sorted by {vendor,name}, but globbed names must come after
+ * any other name with the same prefix.
+ */
 static const struct variable_validate variable_validate[] = {
-	{ "BootNext", validate_uint16 },
-	{ "BootOrder", validate_boot_order },
-	{ "DriverOrder", validate_boot_order },
-	{ "Boot*", validate_load_option },
-	{ "Driver*", validate_load_option },
-	{ "ConIn", validate_device_path },
-	{ "ConInDev", validate_device_path },
-	{ "ConOut", validate_device_path },
-	{ "ConOutDev", validate_device_path },
-	{ "ErrOut", validate_device_path },
-	{ "ErrOutDev", validate_device_path },
-	{ "Timeout", validate_uint16 },
-	{ "Lang", validate_ascii_string },
-	{ "PlatformLang", validate_ascii_string },
-	{ "", NULL },
+	{ EFI_GLOBAL_VARIABLE_GUID, "BootNext", validate_uint16 },
+	{ EFI_GLOBAL_VARIABLE_GUID, "BootOrder", validate_boot_order },
+	{ EFI_GLOBAL_VARIABLE_GUID, "Boot*", validate_load_option },
+	{ EFI_GLOBAL_VARIABLE_GUID, "DriverOrder", validate_boot_order },
+	{ EFI_GLOBAL_VARIABLE_GUID, "Driver*", validate_load_option },
+	{ EFI_GLOBAL_VARIABLE_GUID, "ConIn", validate_device_path },
+	{ EFI_GLOBAL_VARIABLE_GUID, "ConInDev", validate_device_path },
+	{ EFI_GLOBAL_VARIABLE_GUID, "ConOut", validate_device_path },
+	{ EFI_GLOBAL_VARIABLE_GUID, "ConOutDev", validate_device_path },
+	{ EFI_GLOBAL_VARIABLE_GUID, "ErrOut", validate_device_path },
+	{ EFI_GLOBAL_VARIABLE_GUID, "ErrOutDev", validate_device_path },
+	{ EFI_GLOBAL_VARIABLE_GUID, "Lang", validate_ascii_string },
+	{ EFI_GLOBAL_VARIABLE_GUID, "OsIndications", NULL },
+	{ EFI_GLOBAL_VARIABLE_GUID, "PlatformLang", validate_ascii_string },
+	{ EFI_GLOBAL_VARIABLE_GUID, "Timeout", validate_uint16 },
+	{ LINUX_EFI_CRASH_GUID, "*", NULL },
+	{ NULL_GUID, "", NULL },
 };
 
+/*
+ * Check if @var_name matches the pattern given in @match_name.
+ *
+ * @var_name: an array of @len non-NUL characters.
+ * @match_name: a NUL-terminated pattern string, optionally ending in "*". A
+ *              final "*" character matches any trailing characters @var_name,
+ *              including the case when there are none left in @var_name.
+ * @match: on output, the number of non-wildcard characters in @match_name
+ *         that @var_name matches, regardless of the return value.
+ * @return: whether @var_name fully matches @match_name.
+ */
+static bool
+variable_matches(const char *var_name, size_t len, const char *match_name,
+		 int *match)
+{
+	for (*match = 0; ; (*match)++) {
+		char c = match_name[*match];
+
+		switch (c) {
+		case '*':
+			/* Wildcard in @match_name means we've matched. */
+			return true;
+
+		case '\0':
+			/* @match_name has ended. Has @var_name too? */
+			return (*match == len);
+
+		default:
+			/*
+			 * We've reached a non-wildcard char in @match_name.
+			 * Continue only if there's an identical character in
+			 * @var_name.
+			 */
+			if (*match < len && c == var_name[*match])
+				continue;
+			return false;
+		}
+	}
+}
+
 bool
-efivar_validate(efi_char16_t *var_name, u8 *data, unsigned long len)
+efivar_validate(efi_guid_t vendor, efi_char16_t *var_name, u8 *data,
+		unsigned long data_size)
 {
 	int i;
-	u16 *unicode_name = var_name;
+	unsigned long utf8_size;
+	u8 *utf8_name;
+
+	utf8_size = ucs2_utf8size(var_name);
+	utf8_name = kmalloc(utf8_size + 1, GFP_KERNEL);
+	if (!utf8_name)
+		return false;
 
-	for (i = 0; variable_validate[i].validate != NULL; i++) {
+	ucs2_as_utf8(utf8_name, var_name, utf8_size);
+	utf8_name[utf8_size] = '\0';
+
+	for (i = 0; variable_validate[i].name[0] != '\0'; i++) {
 		const char *name = variable_validate[i].name;
-		int match;
+		int match = 0;
 
-		for (match = 0; ; match++) {
-			char c = name[match];
-			u16 u = unicode_name[match];
-
-			/* All special variables are plain ascii */
-			if (u > 127)
-				return true;
-
-			/* Wildcard in the matching name means we've matched */
-			if (c == '*')
-				return variable_validate[i].validate(var_name,
-							     match, data, len);
+		if (efi_guidcmp(vendor, variable_validate[i].vendor))
+			continue;
 
-			/* Case sensitive match */
-			if (c != u)
+		if (variable_matches(utf8_name, utf8_size+1, name, &match)) {
+			if (variable_validate[i].validate == NULL)
 				break;
-
-			/* Reached the end of the string while matching */
-			if (!c)
-				return variable_validate[i].validate(var_name,
-							     match, data, len);
+			kfree(utf8_name);
+			return variable_validate[i].validate(var_name, match,
+							     data, data_size);
 		}
 	}
-
+	kfree(utf8_name);
 	return true;
 }
 EXPORT_SYMBOL_GPL(efivar_validate);
 
+bool
+efivar_variable_is_removable(efi_guid_t vendor, const char *var_name,
+			     size_t len)
+{
+	int i;
+	bool found = false;
+	int match = 0;
+
+	/*
+	 * Check if our variable is in the validated variables list
+	 */
+	for (i = 0; variable_validate[i].name[0] != '\0'; i++) {
+		if (efi_guidcmp(variable_validate[i].vendor, vendor))
+			continue;
+
+		if (variable_matches(var_name, len,
+				     variable_validate[i].name, &match)) {
+			found = true;
+			break;
+		}
+	}
+
+	/*
+	 * If it's in our list, it is removable.
+	 */
+	return found;
+}
+EXPORT_SYMBOL_GPL(efivar_variable_is_removable);
+
 static efi_status_t
 check_var_size(u32 attributes, unsigned long size)
 {
@@ -234,7 +315,18 @@ check_var_size(u32 attributes, unsigned
 	if (!fops->query_variable_store)
 		return EFI_UNSUPPORTED;
 
-	return fops->query_variable_store(attributes, size);
+	return fops->query_variable_store(attributes, size, false);
+}
+
+static efi_status_t
+check_var_size_nonblocking(u32 attributes, unsigned long size)
+{
+	const struct efivar_operations *fops = __efivars->ops;
+
+	if (!fops->query_variable_store)
+		return EFI_UNSUPPORTED;
+
+	return fops->query_variable_store(attributes, size, true);
 }
 
 static int efi_status_to_err(efi_status_t status)
@@ -615,7 +707,8 @@ efivar_entry_set_nonblocking(efi_char16_
 	if (!spin_trylock_irqsave(&__efivars->lock, flags))
 		return -EBUSY;
 
-	status = check_var_size(attributes, size + ucs2_strsize(name, 1024));
+	status = check_var_size_nonblocking(attributes,
+					    size + ucs2_strsize(name, 1024));
 	if (status != EFI_SUCCESS) {
 		spin_unlock_irqrestore(&__efivars->lock, flags);
 		return -ENOSPC;
@@ -852,7 +945,7 @@ int efivar_entry_set_get_size(struct efi
 
 	*set = false;
 
-	if (efivar_validate(name, data, *size) == false)
+	if (efivar_validate(*vendor, name, data, *size) == false)
 		return -EINVAL;
 
 	/*
--- zfcpdump-kernel-4.4.orig/drivers/gpio/Kconfig
+++ zfcpdump-kernel-4.4/drivers/gpio/Kconfig
@@ -50,6 +50,7 @@ config GPIO_DEVRES
 config OF_GPIO
 	def_bool y
 	depends on OF
+	depends on HAS_IOMEM
 
 config GPIO_ACPI
 	def_bool y
--- zfcpdump-kernel-4.4.orig/drivers/gpio/gpio-bcm-kona.c
+++ zfcpdump-kernel-4.4/drivers/gpio/gpio-bcm-kona.c
@@ -551,11 +551,11 @@ static void bcm_kona_gpio_reset(struct b
 	/* disable interrupts and clear status */
 	for (i = 0; i < kona_gpio->num_bank; i++) {
 		/* Unlock the entire bank first */
-		bcm_kona_gpio_write_lock_regs(kona_gpio, i, UNLOCK_CODE);
+		bcm_kona_gpio_write_lock_regs(reg_base, i, UNLOCK_CODE);
 		writel(0xffffffff, reg_base + GPIO_INT_MASK(i));
 		writel(0xffffffff, reg_base + GPIO_INT_STATUS(i));
 		/* Now re-lock the bank */
-		bcm_kona_gpio_write_lock_regs(kona_gpio, i, LOCK_CODE);
+		bcm_kona_gpio_write_lock_regs(reg_base, i, LOCK_CODE);
 	}
 }
 
--- zfcpdump-kernel-4.4.orig/drivers/gpio/gpio-intel-mid.c
+++ zfcpdump-kernel-4.4/drivers/gpio/gpio-intel-mid.c
@@ -17,7 +17,6 @@
  * Moorestown platform Langwell chip.
  * Medfield platform Penwell chip.
  * Clovertrail platform Cloverview chip.
- * Merrifield platform Tangier chip.
  */
 
 #include <linux/module.h>
@@ -64,10 +63,6 @@ enum GPIO_REG {
 /* intel_mid gpio driver data */
 struct intel_mid_gpio_ddata {
 	u16 ngpio;		/* number of gpio pins */
-	u32 gplr_offset;	/* offset of first GPLR register from base */
-	u32 flis_base;		/* base address of FLIS registers */
-	u32 flis_len;		/* length of FLIS registers */
-	u32 (*get_flis_offset)(int gpio);
 	u32 chip_irq_type;	/* chip interrupt type */
 };
 
@@ -257,15 +252,6 @@ static const struct intel_mid_gpio_ddata
 	.chip_irq_type = INTEL_MID_IRQ_TYPE_EDGE,
 };
 
-static const struct intel_mid_gpio_ddata gpio_tangier = {
-	.ngpio = 192,
-	.gplr_offset = 4,
-	.flis_base = 0xff0c0000,
-	.flis_len = 0x8000,
-	.get_flis_offset = NULL,
-	.chip_irq_type = INTEL_MID_IRQ_TYPE_EDGE,
-};
-
 static const struct pci_device_id intel_gpio_ids[] = {
 	{
 		/* Lincroft */
@@ -292,11 +278,6 @@ static const struct pci_device_id intel_
 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x08f7),
 		.driver_data = (kernel_ulong_t)&gpio_cloverview_core,
 	},
-	{
-		/* Tangier */
-		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x1199),
-		.driver_data = (kernel_ulong_t)&gpio_tangier,
-	},
 	{ 0 }
 };
 MODULE_DEVICE_TABLE(pci, intel_gpio_ids);
--- zfcpdump-kernel-4.4.orig/drivers/gpio/gpio-pca953x.c
+++ zfcpdump-kernel-4.4/drivers/gpio/gpio-pca953x.c
@@ -86,7 +86,7 @@ MODULE_DEVICE_TABLE(acpi, pca953x_acpi_i
 #define MAX_BANK 5
 #define BANK_SZ 8
 
-#define NBANK(chip) (chip->gpio_chip.ngpio / BANK_SZ)
+#define NBANK(chip) DIV_ROUND_UP(chip->gpio_chip.ngpio, BANK_SZ)
 
 struct pca953x_chip {
 	unsigned gpio_start;
--- zfcpdump-kernel-4.4.orig/drivers/gpio/gpio-sa1100.c
+++ zfcpdump-kernel-4.4/drivers/gpio/gpio-sa1100.c
@@ -155,7 +155,7 @@ static int sa1100_gpio_irqdomain_map(str
 {
 	irq_set_chip_and_handler(irq, &sa1100_gpio_irq_chip,
 				 handle_edge_irq);
-	irq_set_noprobe(irq);
+	irq_set_probe(irq);
 
 	return 0;
 }
--- zfcpdump-kernel-4.4.orig/drivers/gpio/gpiolib-legacy.c
+++ zfcpdump-kernel-4.4/drivers/gpio/gpiolib-legacy.c
@@ -28,6 +28,10 @@ int gpio_request_one(unsigned gpio, unsi
 	if (!desc && gpio_is_valid(gpio))
 		return -EPROBE_DEFER;
 
+	err = gpiod_request(desc, label);
+	if (err)
+		return err;
+
 	if (flags & GPIOF_OPEN_DRAIN)
 		set_bit(FLAG_OPEN_DRAIN, &desc->flags);
 
@@ -37,10 +41,6 @@ int gpio_request_one(unsigned gpio, unsi
 	if (flags & GPIOF_ACTIVE_LOW)
 		set_bit(FLAG_ACTIVE_LOW, &desc->flags);
 
-	err = gpiod_request(desc, label);
-	if (err)
-		return err;
-
 	if (flags & GPIOF_DIR_IN)
 		err = gpiod_direction_input(desc);
 	else
--- zfcpdump-kernel-4.4.orig/drivers/gpio/gpiolib.c
+++ zfcpdump-kernel-4.4/drivers/gpio/gpiolib.c
@@ -927,14 +927,6 @@ static int __gpiod_request(struct gpio_d
 		spin_lock_irqsave(&gpio_lock, flags);
 	}
 done:
-	if (status < 0) {
-		/* Clear flags that might have been set by the caller before
-		 * requesting the GPIO.
-		 */
-		clear_bit(FLAG_ACTIVE_LOW, &desc->flags);
-		clear_bit(FLAG_OPEN_DRAIN, &desc->flags);
-		clear_bit(FLAG_OPEN_SOURCE, &desc->flags);
-	}
 	spin_unlock_irqrestore(&gpio_lock, flags);
 	return status;
 }
@@ -2062,28 +2054,13 @@ struct gpio_desc *__must_check gpiod_get
 }
 EXPORT_SYMBOL_GPL(gpiod_get_optional);
 
-/**
- * gpiod_parse_flags - helper function to parse GPIO lookup flags
- * @desc:	gpio to be setup
- * @lflags:	gpio_lookup_flags - returned from of_find_gpio() or
- *		of_get_gpio_hog()
- *
- * Set the GPIO descriptor flags based on the given GPIO lookup flags.
- */
-static void gpiod_parse_flags(struct gpio_desc *desc, unsigned long lflags)
-{
-	if (lflags & GPIO_ACTIVE_LOW)
-		set_bit(FLAG_ACTIVE_LOW, &desc->flags);
-	if (lflags & GPIO_OPEN_DRAIN)
-		set_bit(FLAG_OPEN_DRAIN, &desc->flags);
-	if (lflags & GPIO_OPEN_SOURCE)
-		set_bit(FLAG_OPEN_SOURCE, &desc->flags);
-}
 
 /**
  * gpiod_configure_flags - helper function to configure a given GPIO
  * @desc:	gpio whose value will be assigned
  * @con_id:	function within the GPIO consumer
+ * @lflags:	gpio_lookup_flags - returned from of_find_gpio() or
+ *		of_get_gpio_hog()
  * @dflags:	gpiod_flags - optional GPIO initialization flags
  *
  * Return 0 on success, -ENOENT if no GPIO has been assigned to the
@@ -2091,10 +2068,17 @@ static void gpiod_parse_flags(struct gpi
  * occurred while trying to acquire the GPIO.
  */
 static int gpiod_configure_flags(struct gpio_desc *desc, const char *con_id,
-				 enum gpiod_flags dflags)
+		unsigned long lflags, enum gpiod_flags dflags)
 {
 	int status;
 
+	if (lflags & GPIO_ACTIVE_LOW)
+		set_bit(FLAG_ACTIVE_LOW, &desc->flags);
+	if (lflags & GPIO_OPEN_DRAIN)
+		set_bit(FLAG_OPEN_DRAIN, &desc->flags);
+	if (lflags & GPIO_OPEN_SOURCE)
+		set_bit(FLAG_OPEN_SOURCE, &desc->flags);
+
 	/* No particular flag request, return here... */
 	if (!(dflags & GPIOD_FLAGS_BIT_DIR_SET)) {
 		pr_debug("no flags found for %s\n", con_id);
@@ -2161,13 +2145,11 @@ struct gpio_desc *__must_check gpiod_get
 		return desc;
 	}
 
-	gpiod_parse_flags(desc, lookupflags);
-
 	status = gpiod_request(desc, con_id);
 	if (status < 0)
 		return ERR_PTR(status);
 
-	status = gpiod_configure_flags(desc, con_id, flags);
+	status = gpiod_configure_flags(desc, con_id, lookupflags, flags);
 	if (status < 0) {
 		dev_dbg(dev, "setup of GPIO %s failed\n", con_id);
 		gpiod_put(desc);
@@ -2223,6 +2205,10 @@ struct gpio_desc *fwnode_get_named_gpiod
 	if (IS_ERR(desc))
 		return desc;
 
+	ret = gpiod_request(desc, NULL);
+	if (ret)
+		return ERR_PTR(ret);
+
 	if (active_low)
 		set_bit(FLAG_ACTIVE_LOW, &desc->flags);
 
@@ -2233,10 +2219,6 @@ struct gpio_desc *fwnode_get_named_gpiod
 			set_bit(FLAG_OPEN_SOURCE, &desc->flags);
 	}
 
-	ret = gpiod_request(desc, NULL);
-	if (ret)
-		return ERR_PTR(ret);
-
 	return desc;
 }
 EXPORT_SYMBOL_GPL(fwnode_get_named_gpiod);
@@ -2289,8 +2271,6 @@ int gpiod_hog(struct gpio_desc *desc, co
 	chip = gpiod_to_chip(desc);
 	hwnum = gpio_chip_hwgpio(desc);
 
-	gpiod_parse_flags(desc, lflags);
-
 	local_desc = gpiochip_request_own_desc(chip, hwnum, name);
 	if (IS_ERR(local_desc)) {
 		pr_err("requesting hog GPIO %s (chip %s, offset %d) failed\n",
@@ -2298,7 +2278,7 @@ int gpiod_hog(struct gpio_desc *desc, co
 		return PTR_ERR(local_desc);
 	}
 
-	status = gpiod_configure_flags(desc, name, dflags);
+	status = gpiod_configure_flags(desc, name, lflags, dflags);
 	if (status < 0) {
 		pr_err("setup of hog GPIO %s (chip %s, offset %d) failed\n",
 		       name, chip->label, hwnum);
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/Kconfig
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/Kconfig
@@ -25,6 +25,14 @@ config DRM_MIPI_DSI
 	bool
 	depends on DRM
 
+config DRM_DP_AUX_CHARDEV
+	bool "DRM DP AUX Interface"
+	depends on DRM
+	help
+	  Choose this option to enable a /dev/drm_dp_auxN node that allows to
+	  read and write values to arbitrary DPCD registers on the DP aux
+	  channel.
+
 config DRM_KMS_HELPER
 	tristate
 	depends on DRM
@@ -160,6 +168,7 @@ config DRM_AMDGPU
 	  If M is selected, the module will be called amdgpu.
 
 source "drivers/gpu/drm/amd/amdgpu/Kconfig"
+source "drivers/gpu/drm/amd/powerplay/Kconfig"
 
 source "drivers/gpu/drm/nouveau/Kconfig"
 
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/Makefile
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/Makefile
@@ -24,10 +24,13 @@ drm-$(CONFIG_AGP) += drm_agpsupport.o
 drm-y += $(drm-m)
 
 drm_kms_helper-y := drm_crtc_helper.o drm_dp_helper.o drm_probe_helper.o \
-		drm_plane_helper.o drm_dp_mst_topology.o drm_atomic_helper.o
+		drm_plane_helper.o drm_dp_mst_topology.o drm_atomic_helper.o \
+		drm_kms_helper_common.o drm_dp_dual_mode_helper.o
+
 drm_kms_helper-$(CONFIG_DRM_LOAD_EDID_FIRMWARE) += drm_edid_load.o
 drm_kms_helper-$(CONFIG_DRM_FBDEV_EMULATION) += drm_fb_helper.o
 drm_kms_helper-$(CONFIG_DRM_KMS_CMA_HELPER) += drm_fb_cma_helper.o
+drm_kms_helper-$(CONFIG_DRM_DP_AUX_CHARDEV) += drm_dp_aux_dev.o
 
 obj-$(CONFIG_DRM_KMS_HELPER) += drm_kms_helper.o
 
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/amd/amdgpu/Makefile
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/amdgpu/Makefile
@@ -2,10 +2,13 @@
 # Makefile for the drm device driver.  This driver provides support for the
 # Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher.
 
-ccflags-y := -Iinclude/drm -Idrivers/gpu/drm/amd/include/asic_reg \
-	-Idrivers/gpu/drm/amd/include \
-	-Idrivers/gpu/drm/amd/amdgpu \
-	-Idrivers/gpu/drm/amd/scheduler
+FULL_AMD_PATH=$(src)/..
+
+ccflags-y := -Iinclude/drm -I$(FULL_AMD_PATH)/include/asic_reg \
+	-I$(FULL_AMD_PATH)/include \
+	-I$(FULL_AMD_PATH)/amdgpu \
+	-I$(FULL_AMD_PATH)/scheduler \
+	-I$(FULL_AMD_PATH)/powerplay/inc
 
 amdgpu-y := amdgpu_drv.o
 
@@ -22,7 +25,7 @@ amdgpu-y += amdgpu_device.o amdgpu_kms.o
 	amdgpu_ucode.o amdgpu_bo_list.o amdgpu_ctx.o amdgpu_sync.o
 
 # add asic specific block
-amdgpu-$(CONFIG_DRM_AMDGPU_CIK)+= cik.o gmc_v7_0.o cik_ih.o kv_smc.o kv_dpm.o \
+amdgpu-$(CONFIG_DRM_AMDGPU_CIK)+= cik.o cik_ih.o kv_smc.o kv_dpm.o \
 	ci_smc.o ci_dpm.o dce_v8_0.o gfx_v7_0.o cik_sdma.o uvd_v4_2.o vce_v2_0.o \
 	amdgpu_amdkfd_gfx_v7.o
 
@@ -31,6 +34,7 @@ amdgpu-y += \
 
 # add GMC block
 amdgpu-y += \
+	gmc_v7_0.o \
 	gmc_v8_0.o
 
 # add IH block
@@ -44,6 +48,7 @@ amdgpu-y += \
 # add SMC block
 amdgpu-y += \
 	amdgpu_dpm.o \
+	amdgpu_powerplay.o \
 	cz_smc.o cz_dpm.o \
 	tonga_smc.o tonga_dpm.o \
 	fiji_smc.o fiji_dpm.o \
@@ -94,6 +99,14 @@ amdgpu-$(CONFIG_VGA_SWITCHEROO) += amdgp
 amdgpu-$(CONFIG_ACPI) += amdgpu_acpi.o
 amdgpu-$(CONFIG_MMU_NOTIFIER) += amdgpu_mn.o
 
+ifneq ($(CONFIG_DRM_AMD_POWERPLAY),)
+
+include $(FULL_AMD_PATH)/powerplay/Makefile
+
+amdgpu-y += $(AMD_POWERPLAY_FILES)
+
+endif
+
 obj-$(CONFIG_DRM_AMDGPU)+= amdgpu.o
 
 CFLAGS_amdgpu_trace_points.o := -I$(src)
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/amdgpu/amdgpu.h
@@ -52,6 +52,7 @@
 #include "amdgpu_irq.h"
 #include "amdgpu_ucode.h"
 #include "amdgpu_gds.h"
+#include "amd_powerplay.h"
 
 #include "gpu_scheduler.h"
 
@@ -85,6 +86,9 @@ extern int amdgpu_enable_scheduler;
 extern int amdgpu_sched_jobs;
 extern int amdgpu_sched_hw_submission;
 extern int amdgpu_enable_semaphores;
+extern int amdgpu_powerplay;
+extern unsigned amdgpu_pcie_gen_cap;
+extern unsigned amdgpu_pcie_lane_cap;
 
 #define AMDGPU_WAIT_IDLE_TIMEOUT_IN_MS	        3000
 #define AMDGPU_MAX_USEC_TIMEOUT			100000	/* 100 ms */
@@ -130,47 +134,6 @@ extern int amdgpu_enable_semaphores;
 #define AMDGPU_RESET_VCE			(1 << 13)
 #define AMDGPU_RESET_VCE1			(1 << 14)
 
-/* CG block flags */
-#define AMDGPU_CG_BLOCK_GFX			(1 << 0)
-#define AMDGPU_CG_BLOCK_MC			(1 << 1)
-#define AMDGPU_CG_BLOCK_SDMA			(1 << 2)
-#define AMDGPU_CG_BLOCK_UVD			(1 << 3)
-#define AMDGPU_CG_BLOCK_VCE			(1 << 4)
-#define AMDGPU_CG_BLOCK_HDP			(1 << 5)
-#define AMDGPU_CG_BLOCK_BIF			(1 << 6)
-
-/* CG flags */
-#define AMDGPU_CG_SUPPORT_GFX_MGCG		(1 << 0)
-#define AMDGPU_CG_SUPPORT_GFX_MGLS		(1 << 1)
-#define AMDGPU_CG_SUPPORT_GFX_CGCG		(1 << 2)
-#define AMDGPU_CG_SUPPORT_GFX_CGLS		(1 << 3)
-#define AMDGPU_CG_SUPPORT_GFX_CGTS		(1 << 4)
-#define AMDGPU_CG_SUPPORT_GFX_CGTS_LS		(1 << 5)
-#define AMDGPU_CG_SUPPORT_GFX_CP_LS		(1 << 6)
-#define AMDGPU_CG_SUPPORT_GFX_RLC_LS		(1 << 7)
-#define AMDGPU_CG_SUPPORT_MC_LS			(1 << 8)
-#define AMDGPU_CG_SUPPORT_MC_MGCG		(1 << 9)
-#define AMDGPU_CG_SUPPORT_SDMA_LS		(1 << 10)
-#define AMDGPU_CG_SUPPORT_SDMA_MGCG		(1 << 11)
-#define AMDGPU_CG_SUPPORT_BIF_LS		(1 << 12)
-#define AMDGPU_CG_SUPPORT_UVD_MGCG		(1 << 13)
-#define AMDGPU_CG_SUPPORT_VCE_MGCG		(1 << 14)
-#define AMDGPU_CG_SUPPORT_HDP_LS		(1 << 15)
-#define AMDGPU_CG_SUPPORT_HDP_MGCG		(1 << 16)
-
-/* PG flags */
-#define AMDGPU_PG_SUPPORT_GFX_PG		(1 << 0)
-#define AMDGPU_PG_SUPPORT_GFX_SMG		(1 << 1)
-#define AMDGPU_PG_SUPPORT_GFX_DMG		(1 << 2)
-#define AMDGPU_PG_SUPPORT_UVD			(1 << 3)
-#define AMDGPU_PG_SUPPORT_VCE			(1 << 4)
-#define AMDGPU_PG_SUPPORT_CP			(1 << 5)
-#define AMDGPU_PG_SUPPORT_GDS			(1 << 6)
-#define AMDGPU_PG_SUPPORT_RLC_SMU_HS		(1 << 7)
-#define AMDGPU_PG_SUPPORT_SDMA			(1 << 8)
-#define AMDGPU_PG_SUPPORT_ACP			(1 << 9)
-#define AMDGPU_PG_SUPPORT_SAMU			(1 << 10)
-
 /* GFX current status */
 #define AMDGPU_GFX_NORMAL_MODE			0x00000000L
 #define AMDGPU_GFX_SAFE_MODE			0x00000001L
@@ -604,8 +567,6 @@ struct amdgpu_sa_manager {
 	uint32_t		align;
 };
 
-struct amdgpu_sa_bo;
-
 /* sub-allocation buffer */
 struct amdgpu_sa_bo {
 	struct list_head		olist;
@@ -712,9 +673,9 @@ int amdgpu_gart_table_vram_pin(struct am
 void amdgpu_gart_table_vram_unpin(struct amdgpu_device *adev);
 int amdgpu_gart_init(struct amdgpu_device *adev);
 void amdgpu_gart_fini(struct amdgpu_device *adev);
-void amdgpu_gart_unbind(struct amdgpu_device *adev, unsigned offset,
+void amdgpu_gart_unbind(struct amdgpu_device *adev, uint64_t offset,
 			int pages);
-int amdgpu_gart_bind(struct amdgpu_device *adev, unsigned offset,
+int amdgpu_gart_bind(struct amdgpu_device *adev, uint64_t offset,
 		     int pages, struct page **pagelist,
 		     dma_addr_t *dma_addr, uint32_t flags);
 
@@ -918,8 +879,8 @@ struct amdgpu_ring {
 #define AMDGPU_VM_FAULT_STOP_ALWAYS	2
 
 struct amdgpu_vm_pt {
-	struct amdgpu_bo	*bo;
-	uint64_t		addr;
+	struct amdgpu_bo_list_entry	entry;
+	uint64_t			addr;
 };
 
 struct amdgpu_vm_id {
@@ -981,9 +942,12 @@ struct amdgpu_vm_manager {
 void amdgpu_vm_manager_fini(struct amdgpu_device *adev);
 int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm);
 void amdgpu_vm_fini(struct amdgpu_device *adev, struct amdgpu_vm *vm);
-struct amdgpu_bo_list_entry *amdgpu_vm_get_bos(struct amdgpu_device *adev,
-					       struct amdgpu_vm *vm,
-					       struct list_head *head);
+void amdgpu_vm_get_pd_bo(struct amdgpu_vm *vm,
+			 struct list_head *validated,
+			 struct amdgpu_bo_list_entry *entry);
+void amdgpu_vm_get_pt_bos(struct amdgpu_vm *vm, struct list_head *duplicates);
+void amdgpu_vm_move_pt_bos_in_lru(struct amdgpu_device *adev,
+				  struct amdgpu_vm *vm);
 int amdgpu_vm_grab_id(struct amdgpu_vm *vm, struct amdgpu_ring *ring,
 		      struct amdgpu_sync *sync);
 void amdgpu_vm_flush(struct amdgpu_ring *ring,
@@ -1024,11 +988,9 @@ int amdgpu_vm_free_job(struct amdgpu_job
  * context related structures
  */
 
-#define AMDGPU_CTX_MAX_CS_PENDING	16
-
 struct amdgpu_ctx_ring {
 	uint64_t		sequence;
-	struct fence		*fences[AMDGPU_CTX_MAX_CS_PENDING];
+	struct fence		**fences;
 	struct amd_sched_entity	entity;
 };
 
@@ -1037,6 +999,7 @@ struct amdgpu_ctx {
 	struct amdgpu_device    *adev;
 	unsigned		reset_counter;
 	spinlock_t		ring_lock;
+	struct fence            **fences;
 	struct amdgpu_ctx_ring	rings[AMDGPU_MAX_RINGS];
 };
 
@@ -1047,7 +1010,7 @@ struct amdgpu_ctx_mgr {
 	struct idr		ctx_handles;
 };
 
-int amdgpu_ctx_init(struct amdgpu_device *adev, bool kernel,
+int amdgpu_ctx_init(struct amdgpu_device *adev, enum amd_sched_priority pri,
 		    struct amdgpu_ctx *ctx);
 void amdgpu_ctx_fini(struct amdgpu_ctx *ctx);
 
@@ -1254,7 +1217,7 @@ struct amdgpu_cs_parser {
 	unsigned		nchunks;
 	struct amdgpu_cs_chunk	*chunks;
 	/* relocations */
-	struct amdgpu_bo_list_entry	*vm_bos;
+	struct amdgpu_bo_list_entry	vm_pd;
 	struct list_head	validated;
 	struct fence		*fence;
 
@@ -1301,31 +1264,7 @@ struct amdgpu_wb {
 int amdgpu_wb_get(struct amdgpu_device *adev, u32 *wb);
 void amdgpu_wb_free(struct amdgpu_device *adev, u32 wb);
 
-/**
- * struct amdgpu_pm - power management datas
- * It keeps track of various data needed to take powermanagement decision.
- */
-
-enum amdgpu_pm_state_type {
-	/* not used for dpm */
-	POWER_STATE_TYPE_DEFAULT,
-	POWER_STATE_TYPE_POWERSAVE,
-	/* user selectable states */
-	POWER_STATE_TYPE_BATTERY,
-	POWER_STATE_TYPE_BALANCED,
-	POWER_STATE_TYPE_PERFORMANCE,
-	/* internal states */
-	POWER_STATE_TYPE_INTERNAL_UVD,
-	POWER_STATE_TYPE_INTERNAL_UVD_SD,
-	POWER_STATE_TYPE_INTERNAL_UVD_HD,
-	POWER_STATE_TYPE_INTERNAL_UVD_HD2,
-	POWER_STATE_TYPE_INTERNAL_UVD_MVC,
-	POWER_STATE_TYPE_INTERNAL_BOOT,
-	POWER_STATE_TYPE_INTERNAL_THERMAL,
-	POWER_STATE_TYPE_INTERNAL_ACPI,
-	POWER_STATE_TYPE_INTERNAL_ULV,
-	POWER_STATE_TYPE_INTERNAL_3DPERF,
-};
+
 
 enum amdgpu_int_thermal_type {
 	THERMAL_TYPE_NONE,
@@ -1607,8 +1546,8 @@ struct amdgpu_dpm {
 	/* vce requirements */
 	struct amdgpu_vce_state vce_states[AMDGPU_MAX_VCE_LEVELS];
 	enum amdgpu_vce_level vce_level;
-	enum amdgpu_pm_state_type state;
-	enum amdgpu_pm_state_type user_state;
+	enum amd_pm_state_type state;
+	enum amd_pm_state_type user_state;
 	u32                     platform_caps;
 	u32                     voltage_response_time;
 	u32                     backbias_response_time;
@@ -1661,8 +1600,13 @@ struct amdgpu_pm {
 	const struct firmware	*fw;	/* SMC firmware */
 	uint32_t                fw_version;
 	const struct amdgpu_dpm_funcs *funcs;
+	uint32_t                pcie_gen_mask;
+	uint32_t                pcie_mlw_mask;
+	struct amd_pp_display_configuration pm_display_cfg;/* set by DAL */
 };
 
+void amdgpu_get_pcie_info(struct amdgpu_device *adev);
+
 /*
  * UVD
  */
@@ -1675,6 +1619,7 @@ struct amdgpu_uvd {
 	struct amdgpu_bo	*vcpu_bo;
 	void			*cpu_addr;
 	uint64_t		gpu_addr;
+	unsigned		fw_version;
 	atomic_t		handles[AMDGPU_MAX_UVD_HANDLES];
 	struct drm_file		*filp[AMDGPU_MAX_UVD_HANDLES];
 	struct delayed_work	idle_work;
@@ -1830,6 +1775,8 @@ struct amdgpu_cu_info {
  */
 struct amdgpu_asic_funcs {
 	bool (*read_disabled_bios)(struct amdgpu_device *adev);
+	bool (*read_bios_from_rom)(struct amdgpu_device *adev,
+				   u8 *bios, u32 length_bytes);
 	int (*read_register)(struct amdgpu_device *adev, u32 se_num,
 			     u32 sh_num, u32 reg_offset, u32 *value);
 	void (*set_vga_state)(struct amdgpu_device *adev, bool state);
@@ -2060,6 +2007,10 @@ struct amdgpu_device {
 	/* interrupts */
 	struct amdgpu_irq		irq;
 
+	/* powerplay */
+	struct amd_powerplay		powerplay;
+	bool				pp_enabled;
+
 	/* dpm */
 	struct amdgpu_pm		pm;
 	u32				cg_flags;
@@ -2236,6 +2187,7 @@ amdgpu_get_sdma_instance(struct amdgpu_r
 #define amdgpu_asic_set_vce_clocks(adev, ev, ec) (adev)->asic_funcs->set_vce_clocks((adev), (ev), (ec))
 #define amdgpu_asic_get_gpu_clock_counter(adev) (adev)->asic_funcs->get_gpu_clock_counter((adev))
 #define amdgpu_asic_read_disabled_bios(adev) (adev)->asic_funcs->read_disabled_bios((adev))
+#define amdgpu_asic_read_bios_from_rom(adev, b, l) (adev)->asic_funcs->read_bios_from_rom((adev), (b), (l))
 #define amdgpu_asic_read_register(adev, se, sh, offset, v)((adev)->asic_funcs->read_register((adev), (se), (sh), (offset), (v)))
 #define amdgpu_asic_get_cu_info(adev, info) (adev)->asic_funcs->get_cu_info((adev), (info))
 #define amdgpu_gart_flush_gpu_tlb(adev, vmid) (adev)->gart.gart_funcs->flush_gpu_tlb((adev), (vmid))
@@ -2277,24 +2229,78 @@ amdgpu_get_sdma_instance(struct amdgpu_r
 #define amdgpu_display_resume_mc_access(adev, s) (adev)->mode_info.funcs->resume_mc_access((adev), (s))
 #define amdgpu_emit_copy_buffer(adev, ib, s, d, b) (adev)->mman.buffer_funcs->emit_copy_buffer((ib),  (s), (d), (b))
 #define amdgpu_emit_fill_buffer(adev, ib, s, d, b) (adev)->mman.buffer_funcs->emit_fill_buffer((ib), (s), (d), (b))
-#define amdgpu_dpm_get_temperature(adev) (adev)->pm.funcs->get_temperature((adev))
 #define amdgpu_dpm_pre_set_power_state(adev) (adev)->pm.funcs->pre_set_power_state((adev))
 #define amdgpu_dpm_set_power_state(adev) (adev)->pm.funcs->set_power_state((adev))
 #define amdgpu_dpm_post_set_power_state(adev) (adev)->pm.funcs->post_set_power_state((adev))
 #define amdgpu_dpm_display_configuration_changed(adev) (adev)->pm.funcs->display_configuration_changed((adev))
-#define amdgpu_dpm_get_sclk(adev, l) (adev)->pm.funcs->get_sclk((adev), (l))
-#define amdgpu_dpm_get_mclk(adev, l) (adev)->pm.funcs->get_mclk((adev), (l))
 #define amdgpu_dpm_print_power_state(adev, ps) (adev)->pm.funcs->print_power_state((adev), (ps))
-#define amdgpu_dpm_debugfs_print_current_performance_level(adev, m) (adev)->pm.funcs->debugfs_print_current_performance_level((adev), (m))
-#define amdgpu_dpm_force_performance_level(adev, l) (adev)->pm.funcs->force_performance_level((adev), (l))
 #define amdgpu_dpm_vblank_too_short(adev) (adev)->pm.funcs->vblank_too_short((adev))
-#define amdgpu_dpm_powergate_uvd(adev, g) (adev)->pm.funcs->powergate_uvd((adev), (g))
-#define amdgpu_dpm_powergate_vce(adev, g) (adev)->pm.funcs->powergate_vce((adev), (g))
 #define amdgpu_dpm_enable_bapm(adev, e) (adev)->pm.funcs->enable_bapm((adev), (e))
-#define amdgpu_dpm_set_fan_control_mode(adev, m) (adev)->pm.funcs->set_fan_control_mode((adev), (m))
-#define amdgpu_dpm_get_fan_control_mode(adev) (adev)->pm.funcs->get_fan_control_mode((adev))
-#define amdgpu_dpm_set_fan_speed_percent(adev, s) (adev)->pm.funcs->set_fan_speed_percent((adev), (s))
-#define amdgpu_dpm_get_fan_speed_percent(adev, s) (adev)->pm.funcs->get_fan_speed_percent((adev), (s))
+
+#define amdgpu_dpm_get_temperature(adev) \
+	((adev)->pp_enabled ?						\
+	      (adev)->powerplay.pp_funcs->get_temperature((adev)->powerplay.pp_handle) : \
+	      (adev)->pm.funcs->get_temperature((adev)))
+
+#define amdgpu_dpm_set_fan_control_mode(adev, m) \
+	((adev)->pp_enabled ?						\
+	      (adev)->powerplay.pp_funcs->set_fan_control_mode((adev)->powerplay.pp_handle, (m)) : \
+	      (adev)->pm.funcs->set_fan_control_mode((adev), (m)))
+
+#define amdgpu_dpm_get_fan_control_mode(adev) \
+	((adev)->pp_enabled ?						\
+	      (adev)->powerplay.pp_funcs->get_fan_control_mode((adev)->powerplay.pp_handle) : \
+	      (adev)->pm.funcs->get_fan_control_mode((adev)))
+
+#define amdgpu_dpm_set_fan_speed_percent(adev, s) \
+	((adev)->pp_enabled ?						\
+	      (adev)->powerplay.pp_funcs->set_fan_speed_percent((adev)->powerplay.pp_handle, (s)) : \
+	      (adev)->pm.funcs->set_fan_speed_percent((adev), (s)))
+
+#define amdgpu_dpm_get_fan_speed_percent(adev, s) \
+	((adev)->pp_enabled ?						\
+	      (adev)->powerplay.pp_funcs->get_fan_speed_percent((adev)->powerplay.pp_handle, (s)) : \
+	      (adev)->pm.funcs->get_fan_speed_percent((adev), (s)))
+
+#define amdgpu_dpm_get_sclk(adev, l) \
+	((adev)->pp_enabled ?						\
+	      (adev)->powerplay.pp_funcs->get_sclk((adev)->powerplay.pp_handle, (l)) : \
+		(adev)->pm.funcs->get_sclk((adev), (l)))
+
+#define amdgpu_dpm_get_mclk(adev, l)  \
+	((adev)->pp_enabled ?						\
+	      (adev)->powerplay.pp_funcs->get_mclk((adev)->powerplay.pp_handle, (l)) : \
+	      (adev)->pm.funcs->get_mclk((adev), (l)))
+
+
+#define amdgpu_dpm_force_performance_level(adev, l) \
+	((adev)->pp_enabled ?						\
+	      (adev)->powerplay.pp_funcs->force_performance_level((adev)->powerplay.pp_handle, (l)) : \
+	      (adev)->pm.funcs->force_performance_level((adev), (l)))
+
+#define amdgpu_dpm_powergate_uvd(adev, g) \
+	((adev)->pp_enabled ?						\
+	      (adev)->powerplay.pp_funcs->powergate_uvd((adev)->powerplay.pp_handle, (g)) : \
+	      (adev)->pm.funcs->powergate_uvd((adev), (g)))
+
+#define amdgpu_dpm_powergate_vce(adev, g) \
+	((adev)->pp_enabled ?						\
+	      (adev)->powerplay.pp_funcs->powergate_vce((adev)->powerplay.pp_handle, (g)) : \
+	      (adev)->pm.funcs->powergate_vce((adev), (g)))
+
+#define amdgpu_dpm_debugfs_print_current_performance_level(adev, m) \
+	((adev)->pp_enabled ?						\
+	      (adev)->powerplay.pp_funcs->print_current_performance_level((adev)->powerplay.pp_handle, (m)) : \
+	      (adev)->pm.funcs->debugfs_print_current_performance_level((adev), (m)))
+
+#define amdgpu_dpm_get_current_power_state(adev) \
+	(adev)->powerplay.pp_funcs->get_current_power_state((adev)->powerplay.pp_handle)
+
+#define amdgpu_dpm_get_performance_level(adev) \
+	(adev)->powerplay.pp_funcs->get_performance_level((adev)->powerplay.pp_handle)
+
+#define amdgpu_dpm_dispatch_task(adev, event_id, input, output)		\
+	(adev)->powerplay.pp_funcs->dispatch_tasks((adev)->powerplay.pp_handle, (event_id), (input), (output))
 
 #define amdgpu_gds_switch(adev, r, v, d, w, a) (adev)->gds.funcs->patch_gds_switch((r), (v), (d), (w), (a))
 
@@ -2314,6 +2320,8 @@ bool amdgpu_ttm_bo_is_amdgpu_bo(struct t
 int amdgpu_ttm_tt_set_userptr(struct ttm_tt *ttm, uint64_t addr,
 				     uint32_t flags);
 bool amdgpu_ttm_tt_has_userptr(struct ttm_tt *ttm);
+bool amdgpu_ttm_tt_affect_userptr(struct ttm_tt *ttm, unsigned long start,
+				  unsigned long end);
 bool amdgpu_ttm_tt_is_readonly(struct ttm_tt *ttm);
 uint32_t amdgpu_ttm_tt_pte_flags(struct amdgpu_device *adev, struct ttm_tt *ttm,
 				 struct ttm_mem_reg *mem);
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c
@@ -29,66 +29,10 @@
 #include <drm/drmP.h>
 #include <drm/drm_crtc_helper.h>
 #include "amdgpu.h"
-#include "amdgpu_acpi.h"
+#include "amd_acpi.h"
 #include "atom.h"
 
-#define ACPI_AC_CLASS           "ac_adapter"
-
 extern void amdgpu_pm_acpi_event_handler(struct amdgpu_device *adev);
-
-struct atif_verify_interface {
-	u16 size;		/* structure size in bytes (includes size field) */
-	u16 version;		/* version */
-	u32 notification_mask;	/* supported notifications mask */
-	u32 function_bits;	/* supported functions bit vector */
-} __packed;
-
-struct atif_system_params {
-	u16 size;		/* structure size in bytes (includes size field) */
-	u32 valid_mask;		/* valid flags mask */
-	u32 flags;		/* flags */
-	u8 command_code;	/* notify command code */
-} __packed;
-
-struct atif_sbios_requests {
-	u16 size;		/* structure size in bytes (includes size field) */
-	u32 pending;		/* pending sbios requests */
-	u8 panel_exp_mode;	/* panel expansion mode */
-	u8 thermal_gfx;		/* thermal state: target gfx controller */
-	u8 thermal_state;	/* thermal state: state id (0: exit state, non-0: state) */
-	u8 forced_power_gfx;	/* forced power state: target gfx controller */
-	u8 forced_power_state;	/* forced power state: state id */
-	u8 system_power_src;	/* system power source */
-	u8 backlight_level;	/* panel backlight level (0-255) */
-} __packed;
-
-#define ATIF_NOTIFY_MASK	0x3
-#define ATIF_NOTIFY_NONE	0
-#define ATIF_NOTIFY_81		1
-#define ATIF_NOTIFY_N		2
-
-struct atcs_verify_interface {
-	u16 size;		/* structure size in bytes (includes size field) */
-	u16 version;		/* version */
-	u32 function_bits;	/* supported functions bit vector */
-} __packed;
-
-#define ATCS_VALID_FLAGS_MASK	0x3
-
-struct atcs_pref_req_input {
-	u16 size;		/* structure size in bytes (includes size field) */
-	u16 client_id;		/* client id (bit 2-0: func num, 7-3: dev num, 15-8: bus num) */
-	u16 valid_flags_mask;	/* valid flags mask */
-	u16 flags;		/* flags */
-	u8 req_type;		/* request type */
-	u8 perf_req;		/* performance request */
-} __packed;
-
-struct atcs_pref_req_output {
-	u16 size;		/* structure size in bytes (includes size field) */
-	u8 ret_val;		/* return value */
-} __packed;
-
 /* Call the ATIF method
  */
 /**
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.h
+++ /dev/null
@@ -1,445 +0,0 @@
-/*
- * Copyright 2012 Advanced Micro Devices, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- */
-
-#ifndef AMDGPU_ACPI_H
-#define AMDGPU_ACPI_H
-
-struct amdgpu_device;
-struct acpi_bus_event;
-
-int amdgpu_atif_handler(struct amdgpu_device *adev,
-		struct acpi_bus_event *event);
-
-/* AMD hw uses four ACPI control methods:
- * 1. ATIF
- * ARG0: (ACPI_INTEGER) function code
- * ARG1: (ACPI_BUFFER) parameter buffer, 256 bytes
- * OUTPUT: (ACPI_BUFFER) output buffer, 256 bytes
- * ATIF provides an entry point for the gfx driver to interact with the sbios.
- * The AMD ACPI notification mechanism uses Notify (VGA, 0x81) or a custom
- * notification. Which notification is used as indicated by the ATIF Control
- * Method GET_SYSTEM_PARAMETERS. When the driver receives Notify (VGA, 0x81) or
- * a custom notification it invokes ATIF Control Method GET_SYSTEM_BIOS_REQUESTS
- * to identify pending System BIOS requests and associated parameters. For
- * example, if one of the pending requests is DISPLAY_SWITCH_REQUEST, the driver
- * will perform display device detection and invoke ATIF Control Method
- * SELECT_ACTIVE_DISPLAYS.
- *
- * 2. ATPX
- * ARG0: (ACPI_INTEGER) function code
- * ARG1: (ACPI_BUFFER) parameter buffer, 256 bytes
- * OUTPUT: (ACPI_BUFFER) output buffer, 256 bytes
- * ATPX methods are used on PowerXpress systems to handle mux switching and
- * discrete GPU power control.
- *
- * 3. ATRM
- * ARG0: (ACPI_INTEGER) offset of vbios rom data
- * ARG1: (ACPI_BUFFER) size of the buffer to fill (up to 4K).
- * OUTPUT: (ACPI_BUFFER) output buffer
- * ATRM provides an interfacess to access the discrete GPU vbios image on
- * PowerXpress systems with multiple GPUs.
- *
- * 4. ATCS
- * ARG0: (ACPI_INTEGER) function code
- * ARG1: (ACPI_BUFFER) parameter buffer, 256 bytes
- * OUTPUT: (ACPI_BUFFER) output buffer, 256 bytes
- * ATCS provides an interface to AMD chipset specific functionality.
- *
- */
-/* ATIF */
-#define ATIF_FUNCTION_VERIFY_INTERFACE                             0x0
-/* ARG0: ATIF_FUNCTION_VERIFY_INTERFACE
- * ARG1: none
- * OUTPUT:
- * WORD  - structure size in bytes (includes size field)
- * WORD  - version
- * DWORD - supported notifications mask
- * DWORD - supported functions bit vector
- */
-/* Notifications mask */
-#       define ATIF_DISPLAY_SWITCH_REQUEST_SUPPORTED               (1 << 0)
-#       define ATIF_EXPANSION_MODE_CHANGE_REQUEST_SUPPORTED        (1 << 1)
-#       define ATIF_THERMAL_STATE_CHANGE_REQUEST_SUPPORTED         (1 << 2)
-#       define ATIF_FORCED_POWER_STATE_CHANGE_REQUEST_SUPPORTED    (1 << 3)
-#       define ATIF_SYSTEM_POWER_SOURCE_CHANGE_REQUEST_SUPPORTED   (1 << 4)
-#       define ATIF_DISPLAY_CONF_CHANGE_REQUEST_SUPPORTED          (1 << 5)
-#       define ATIF_PX_GFX_SWITCH_REQUEST_SUPPORTED                (1 << 6)
-#       define ATIF_PANEL_BRIGHTNESS_CHANGE_REQUEST_SUPPORTED      (1 << 7)
-#       define ATIF_DGPU_DISPLAY_EVENT_SUPPORTED                   (1 << 8)
-/* supported functions vector */
-#       define ATIF_GET_SYSTEM_PARAMETERS_SUPPORTED               (1 << 0)
-#       define ATIF_GET_SYSTEM_BIOS_REQUESTS_SUPPORTED            (1 << 1)
-#       define ATIF_SELECT_ACTIVE_DISPLAYS_SUPPORTED              (1 << 2)
-#       define ATIF_GET_LID_STATE_SUPPORTED                       (1 << 3)
-#       define ATIF_GET_TV_STANDARD_FROM_CMOS_SUPPORTED           (1 << 4)
-#       define ATIF_SET_TV_STANDARD_IN_CMOS_SUPPORTED             (1 << 5)
-#       define ATIF_GET_PANEL_EXPANSION_MODE_FROM_CMOS_SUPPORTED  (1 << 6)
-#       define ATIF_SET_PANEL_EXPANSION_MODE_IN_CMOS_SUPPORTED    (1 << 7)
-#       define ATIF_TEMPERATURE_CHANGE_NOTIFICATION_SUPPORTED     (1 << 12)
-#       define ATIF_GET_GRAPHICS_DEVICE_TYPES_SUPPORTED           (1 << 14)
-#define ATIF_FUNCTION_GET_SYSTEM_PARAMETERS                        0x1
-/* ARG0: ATIF_FUNCTION_GET_SYSTEM_PARAMETERS
- * ARG1: none
- * OUTPUT:
- * WORD  - structure size in bytes (includes size field)
- * DWORD - valid flags mask
- * DWORD - flags
- *
- * OR
- *
- * WORD  - structure size in bytes (includes size field)
- * DWORD - valid flags mask
- * DWORD - flags
- * BYTE  - notify command code
- *
- * flags
- * bits 1:0:
- * 0 - Notify(VGA, 0x81) is not used for notification
- * 1 - Notify(VGA, 0x81) is used for notification
- * 2 - Notify(VGA, n) is used for notification where
- * n (0xd0-0xd9) is specified in notify command code.
- * bit 2:
- * 1 - lid changes not reported though int10
- */
-#define ATIF_FUNCTION_GET_SYSTEM_BIOS_REQUESTS                     0x2
-/* ARG0: ATIF_FUNCTION_GET_SYSTEM_BIOS_REQUESTS
- * ARG1: none
- * OUTPUT:
- * WORD  - structure size in bytes (includes size field)
- * DWORD - pending sbios requests
- * BYTE  - panel expansion mode
- * BYTE  - thermal state: target gfx controller
- * BYTE  - thermal state: state id (0: exit state, non-0: state)
- * BYTE  - forced power state: target gfx controller
- * BYTE  - forced power state: state id
- * BYTE  - system power source
- * BYTE  - panel backlight level (0-255)
- */
-/* pending sbios requests */
-#       define ATIF_DISPLAY_SWITCH_REQUEST                         (1 << 0)
-#       define ATIF_EXPANSION_MODE_CHANGE_REQUEST                  (1 << 1)
-#       define ATIF_THERMAL_STATE_CHANGE_REQUEST                   (1 << 2)
-#       define ATIF_FORCED_POWER_STATE_CHANGE_REQUEST              (1 << 3)
-#       define ATIF_SYSTEM_POWER_SOURCE_CHANGE_REQUEST             (1 << 4)
-#       define ATIF_DISPLAY_CONF_CHANGE_REQUEST                    (1 << 5)
-#       define ATIF_PX_GFX_SWITCH_REQUEST                          (1 << 6)
-#       define ATIF_PANEL_BRIGHTNESS_CHANGE_REQUEST                (1 << 7)
-#       define ATIF_DGPU_DISPLAY_EVENT                             (1 << 8)
-/* panel expansion mode */
-#       define ATIF_PANEL_EXPANSION_DISABLE                        0
-#       define ATIF_PANEL_EXPANSION_FULL                           1
-#       define ATIF_PANEL_EXPANSION_ASPECT                         2
-/* target gfx controller */
-#       define ATIF_TARGET_GFX_SINGLE                              0
-#       define ATIF_TARGET_GFX_PX_IGPU                             1
-#       define ATIF_TARGET_GFX_PX_DGPU                             2
-/* system power source */
-#       define ATIF_POWER_SOURCE_AC                                1
-#       define ATIF_POWER_SOURCE_DC                                2
-#       define ATIF_POWER_SOURCE_RESTRICTED_AC_1                   3
-#       define ATIF_POWER_SOURCE_RESTRICTED_AC_2                   4
-#define ATIF_FUNCTION_SELECT_ACTIVE_DISPLAYS                       0x3
-/* ARG0: ATIF_FUNCTION_SELECT_ACTIVE_DISPLAYS
- * ARG1:
- * WORD  - structure size in bytes (includes size field)
- * WORD  - selected displays
- * WORD  - connected displays
- * OUTPUT:
- * WORD  - structure size in bytes (includes size field)
- * WORD  - selected displays
- */
-#       define ATIF_LCD1                                           (1 << 0)
-#       define ATIF_CRT1                                           (1 << 1)
-#       define ATIF_TV                                             (1 << 2)
-#       define ATIF_DFP1                                           (1 << 3)
-#       define ATIF_CRT2                                           (1 << 4)
-#       define ATIF_LCD2                                           (1 << 5)
-#       define ATIF_DFP2                                           (1 << 7)
-#       define ATIF_CV                                             (1 << 8)
-#       define ATIF_DFP3                                           (1 << 9)
-#       define ATIF_DFP4                                           (1 << 10)
-#       define ATIF_DFP5                                           (1 << 11)
-#       define ATIF_DFP6                                           (1 << 12)
-#define ATIF_FUNCTION_GET_LID_STATE                                0x4
-/* ARG0: ATIF_FUNCTION_GET_LID_STATE
- * ARG1: none
- * OUTPUT:
- * WORD  - structure size in bytes (includes size field)
- * BYTE  - lid state (0: open, 1: closed)
- *
- * GET_LID_STATE only works at boot and resume, for general lid
- * status, use the kernel provided status
- */
-#define ATIF_FUNCTION_GET_TV_STANDARD_FROM_CMOS                    0x5
-/* ARG0: ATIF_FUNCTION_GET_TV_STANDARD_FROM_CMOS
- * ARG1: none
- * OUTPUT:
- * WORD  - structure size in bytes (includes size field)
- * BYTE  - 0
- * BYTE  - TV standard
- */
-#       define ATIF_TV_STD_NTSC                                    0
-#       define ATIF_TV_STD_PAL                                     1
-#       define ATIF_TV_STD_PALM                                    2
-#       define ATIF_TV_STD_PAL60                                   3
-#       define ATIF_TV_STD_NTSCJ                                   4
-#       define ATIF_TV_STD_PALCN                                   5
-#       define ATIF_TV_STD_PALN                                    6
-#       define ATIF_TV_STD_SCART_RGB                               9
-#define ATIF_FUNCTION_SET_TV_STANDARD_IN_CMOS                      0x6
-/* ARG0: ATIF_FUNCTION_SET_TV_STANDARD_IN_CMOS
- * ARG1:
- * WORD  - structure size in bytes (includes size field)
- * BYTE  - 0
- * BYTE  - TV standard
- * OUTPUT: none
- */
-#define ATIF_FUNCTION_GET_PANEL_EXPANSION_MODE_FROM_CMOS           0x7
-/* ARG0: ATIF_FUNCTION_GET_PANEL_EXPANSION_MODE_FROM_CMOS
- * ARG1: none
- * OUTPUT:
- * WORD  - structure size in bytes (includes size field)
- * BYTE  - panel expansion mode
- */
-#define ATIF_FUNCTION_SET_PANEL_EXPANSION_MODE_IN_CMOS             0x8
-/* ARG0: ATIF_FUNCTION_SET_PANEL_EXPANSION_MODE_IN_CMOS
- * ARG1:
- * WORD  - structure size in bytes (includes size field)
- * BYTE  - panel expansion mode
- * OUTPUT: none
- */
-#define ATIF_FUNCTION_TEMPERATURE_CHANGE_NOTIFICATION              0xD
-/* ARG0: ATIF_FUNCTION_TEMPERATURE_CHANGE_NOTIFICATION
- * ARG1:
- * WORD  - structure size in bytes (includes size field)
- * WORD  - gfx controller id
- * BYTE  - current temperature (degress Celsius)
- * OUTPUT: none
- */
-#define ATIF_FUNCTION_GET_GRAPHICS_DEVICE_TYPES                    0xF
-/* ARG0: ATIF_FUNCTION_GET_GRAPHICS_DEVICE_TYPES
- * ARG1: none
- * OUTPUT:
- * WORD  - number of gfx devices
- * WORD  - device structure size in bytes (excludes device size field)
- * DWORD - flags         \
- * WORD  - bus number     } repeated structure
- * WORD  - device number /
- */
-/* flags */
-#       define ATIF_PX_REMOVABLE_GRAPHICS_DEVICE                   (1 << 0)
-#       define ATIF_XGP_PORT                                       (1 << 1)
-#       define ATIF_VGA_ENABLED_GRAPHICS_DEVICE                    (1 << 2)
-#       define ATIF_XGP_PORT_IN_DOCK                               (1 << 3)
-
-/* ATPX */
-#define ATPX_FUNCTION_VERIFY_INTERFACE                             0x0
-/* ARG0: ATPX_FUNCTION_VERIFY_INTERFACE
- * ARG1: none
- * OUTPUT:
- * WORD  - structure size in bytes (includes size field)
- * WORD  - version
- * DWORD - supported functions bit vector
- */
-/* supported functions vector */
-#       define ATPX_GET_PX_PARAMETERS_SUPPORTED                    (1 << 0)
-#       define ATPX_POWER_CONTROL_SUPPORTED                        (1 << 1)
-#       define ATPX_DISPLAY_MUX_CONTROL_SUPPORTED                  (1 << 2)
-#       define ATPX_I2C_MUX_CONTROL_SUPPORTED                      (1 << 3)
-#       define ATPX_GRAPHICS_DEVICE_SWITCH_START_NOTIFICATION_SUPPORTED (1 << 4)
-#       define ATPX_GRAPHICS_DEVICE_SWITCH_END_NOTIFICATION_SUPPORTED   (1 << 5)
-#       define ATPX_GET_DISPLAY_CONNECTORS_MAPPING_SUPPORTED       (1 << 7)
-#       define ATPX_GET_DISPLAY_DETECTION_PORTS_SUPPORTED          (1 << 8)
-#define ATPX_FUNCTION_GET_PX_PARAMETERS                            0x1
-/* ARG0: ATPX_FUNCTION_GET_PX_PARAMETERS
- * ARG1: none
- * OUTPUT:
- * WORD  - structure size in bytes (includes size field)
- * DWORD - valid flags mask
- * DWORD - flags
- */
-/* flags */
-#       define ATPX_LVDS_I2C_AVAILABLE_TO_BOTH_GPUS                (1 << 0)
-#       define ATPX_CRT1_I2C_AVAILABLE_TO_BOTH_GPUS                (1 << 1)
-#       define ATPX_DVI1_I2C_AVAILABLE_TO_BOTH_GPUS                (1 << 2)
-#       define ATPX_CRT1_RGB_SIGNAL_MUXED                          (1 << 3)
-#       define ATPX_TV_SIGNAL_MUXED                                (1 << 4)
-#       define ATPX_DFP_SIGNAL_MUXED                               (1 << 5)
-#       define ATPX_SEPARATE_MUX_FOR_I2C                           (1 << 6)
-#       define ATPX_DYNAMIC_PX_SUPPORTED                           (1 << 7)
-#       define ATPX_ACF_NOT_SUPPORTED                              (1 << 8)
-#       define ATPX_FIXED_NOT_SUPPORTED                            (1 << 9)
-#       define ATPX_DYNAMIC_DGPU_POWER_OFF_SUPPORTED               (1 << 10)
-#       define ATPX_DGPU_REQ_POWER_FOR_DISPLAYS                    (1 << 11)
-#define ATPX_FUNCTION_POWER_CONTROL                                0x2
-/* ARG0: ATPX_FUNCTION_POWER_CONTROL
- * ARG1:
- * WORD  - structure size in bytes (includes size field)
- * BYTE  - dGPU power state (0: power off, 1: power on)
- * OUTPUT: none
- */
-#define ATPX_FUNCTION_DISPLAY_MUX_CONTROL                          0x3
-/* ARG0: ATPX_FUNCTION_DISPLAY_MUX_CONTROL
- * ARG1:
- * WORD  - structure size in bytes (includes size field)
- * WORD  - display mux control (0: iGPU, 1: dGPU)
- * OUTPUT: none
- */
-#       define ATPX_INTEGRATED_GPU                                 0
-#       define ATPX_DISCRETE_GPU                                   1
-#define ATPX_FUNCTION_I2C_MUX_CONTROL                              0x4
-/* ARG0: ATPX_FUNCTION_I2C_MUX_CONTROL
- * ARG1:
- * WORD  - structure size in bytes (includes size field)
- * WORD  - i2c/aux/hpd mux control (0: iGPU, 1: dGPU)
- * OUTPUT: none
- */
-#define ATPX_FUNCTION_GRAPHICS_DEVICE_SWITCH_START_NOTIFICATION    0x5
-/* ARG0: ATPX_FUNCTION_GRAPHICS_DEVICE_SWITCH_START_NOTIFICATION
- * ARG1:
- * WORD  - structure size in bytes (includes size field)
- * WORD  - target gpu (0: iGPU, 1: dGPU)
- * OUTPUT: none
- */
-#define ATPX_FUNCTION_GRAPHICS_DEVICE_SWITCH_END_NOTIFICATION      0x6
-/* ARG0: ATPX_FUNCTION_GRAPHICS_DEVICE_SWITCH_END_NOTIFICATION
- * ARG1:
- * WORD  - structure size in bytes (includes size field)
- * WORD  - target gpu (0: iGPU, 1: dGPU)
- * OUTPUT: none
- */
-#define ATPX_FUNCTION_GET_DISPLAY_CONNECTORS_MAPPING               0x8
-/* ARG0: ATPX_FUNCTION_GET_DISPLAY_CONNECTORS_MAPPING
- * ARG1: none
- * OUTPUT:
- * WORD  - number of display connectors
- * WORD  - connector structure size in bytes (excludes connector size field)
- * BYTE  - flags                                                     \
- * BYTE  - ATIF display vector bit position                           } repeated
- * BYTE  - adapter id (0: iGPU, 1-n: dGPU ordered by pcie bus number) } structure
- * WORD  - connector ACPI id                                         /
- */
-/* flags */
-#       define ATPX_DISPLAY_OUTPUT_SUPPORTED_BY_ADAPTER_ID_DEVICE  (1 << 0)
-#       define ATPX_DISPLAY_HPD_SUPPORTED_BY_ADAPTER_ID_DEVICE     (1 << 1)
-#       define ATPX_DISPLAY_I2C_SUPPORTED_BY_ADAPTER_ID_DEVICE     (1 << 2)
-#define ATPX_FUNCTION_GET_DISPLAY_DETECTION_PORTS                  0x9
-/* ARG0: ATPX_FUNCTION_GET_DISPLAY_DETECTION_PORTS
- * ARG1: none
- * OUTPUT:
- * WORD  - number of HPD/DDC ports
- * WORD  - port structure size in bytes (excludes port size field)
- * BYTE  - ATIF display vector bit position \
- * BYTE  - hpd id                            } reapeated structure
- * BYTE  - ddc id                           /
- *
- * available on A+A systems only
- */
-/* hpd id */
-#       define ATPX_HPD_NONE                                       0
-#       define ATPX_HPD1                                           1
-#       define ATPX_HPD2                                           2
-#       define ATPX_HPD3                                           3
-#       define ATPX_HPD4                                           4
-#       define ATPX_HPD5                                           5
-#       define ATPX_HPD6                                           6
-/* ddc id */
-#       define ATPX_DDC_NONE                                       0
-#       define ATPX_DDC1                                           1
-#       define ATPX_DDC2                                           2
-#       define ATPX_DDC3                                           3
-#       define ATPX_DDC4                                           4
-#       define ATPX_DDC5                                           5
-#       define ATPX_DDC6                                           6
-#       define ATPX_DDC7                                           7
-#       define ATPX_DDC8                                           8
-
-/* ATCS */
-#define ATCS_FUNCTION_VERIFY_INTERFACE                             0x0
-/* ARG0: ATCS_FUNCTION_VERIFY_INTERFACE
- * ARG1: none
- * OUTPUT:
- * WORD  - structure size in bytes (includes size field)
- * WORD  - version
- * DWORD - supported functions bit vector
- */
-/* supported functions vector */
-#       define ATCS_GET_EXTERNAL_STATE_SUPPORTED                   (1 << 0)
-#       define ATCS_PCIE_PERFORMANCE_REQUEST_SUPPORTED             (1 << 1)
-#       define ATCS_PCIE_DEVICE_READY_NOTIFICATION_SUPPORTED       (1 << 2)
-#       define ATCS_SET_PCIE_BUS_WIDTH_SUPPORTED                   (1 << 3)
-#define ATCS_FUNCTION_GET_EXTERNAL_STATE                           0x1
-/* ARG0: ATCS_FUNCTION_GET_EXTERNAL_STATE
- * ARG1: none
- * OUTPUT:
- * WORD  - structure size in bytes (includes size field)
- * DWORD - valid flags mask
- * DWORD - flags (0: undocked, 1: docked)
- */
-/* flags */
-#       define ATCS_DOCKED                                         (1 << 0)
-#define ATCS_FUNCTION_PCIE_PERFORMANCE_REQUEST                     0x2
-/* ARG0: ATCS_FUNCTION_PCIE_PERFORMANCE_REQUEST
- * ARG1:
- * WORD  - structure size in bytes (includes size field)
- * WORD  - client id (bit 2-0: func num, 7-3: dev num, 15-8: bus num)
- * WORD  - valid flags mask
- * WORD  - flags
- * BYTE  - request type
- * BYTE  - performance request
- * OUTPUT:
- * WORD  - structure size in bytes (includes size field)
- * BYTE  - return value
- */
-/* flags */
-#       define ATCS_ADVERTISE_CAPS                                 (1 << 0)
-#       define ATCS_WAIT_FOR_COMPLETION                            (1 << 1)
-/* request type */
-#       define ATCS_PCIE_LINK_SPEED                                1
-/* performance request */
-#       define ATCS_REMOVE                                         0
-#       define ATCS_FORCE_LOW_POWER                                1
-#       define ATCS_PERF_LEVEL_1                                   2 /* PCIE Gen 1 */
-#       define ATCS_PERF_LEVEL_2                                   3 /* PCIE Gen 2 */
-#       define ATCS_PERF_LEVEL_3                                   4 /* PCIE Gen 3 */
-/* return value */
-#       define ATCS_REQUEST_REFUSED                                1
-#       define ATCS_REQUEST_COMPLETE                               2
-#       define ATCS_REQUEST_IN_PROGRESS                            3
-#define ATCS_FUNCTION_PCIE_DEVICE_READY_NOTIFICATION               0x3
-/* ARG0: ATCS_FUNCTION_PCIE_DEVICE_READY_NOTIFICATION
- * ARG1: none
- * OUTPUT: none
- */
-#define ATCS_FUNCTION_SET_PCIE_BUS_WIDTH                           0x4
-/* ARG0: ATCS_FUNCTION_SET_PCIE_BUS_WIDTH
- * ARG1:
- * WORD  - structure size in bytes (includes size field)
- * WORD  - client id (bit 2-0: func num, 7-3: dev num, 15-8: bus num)
- * BYTE  - number of active lanes
- * OUTPUT:
- * WORD  - structure size in bytes (includes size field)
- * BYTE  - number of active lanes
- */
-
-#endif
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c
@@ -154,7 +154,7 @@ static const struct kfd2kgd_calls kfd2kg
 	.get_fw_version = get_fw_version
 };
 
-struct kfd2kgd_calls *amdgpu_amdkfd_gfx_7_get_functions()
+struct kfd2kgd_calls *amdgpu_amdkfd_gfx_7_get_functions(void)
 {
 	return (struct kfd2kgd_calls *)&kfd2kgd;
 }
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c
@@ -115,7 +115,7 @@ static const struct kfd2kgd_calls kfd2kg
 	.get_fw_version = get_fw_version
 };
 
-struct kfd2kgd_calls *amdgpu_amdkfd_gfx_8_0_get_functions()
+struct kfd2kgd_calls *amdgpu_amdkfd_gfx_8_0_get_functions(void)
 {
 	return (struct kfd2kgd_calls *)&kfd2kgd;
 }
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c
@@ -331,6 +331,19 @@ bool amdgpu_atombios_get_connector_info_
 			    (le16_to_cpu(path->usConnObjectId) &
 			     OBJECT_TYPE_MASK) >> OBJECT_TYPE_SHIFT;
 
+			/* Skip TV/CV support */
+			if ((le16_to_cpu(path->usDeviceTag) ==
+			     ATOM_DEVICE_TV1_SUPPORT) ||
+			    (le16_to_cpu(path->usDeviceTag) ==
+			     ATOM_DEVICE_CV_SUPPORT))
+				continue;
+
+			if (con_obj_id >= ARRAY_SIZE(object_connector_convert)) {
+				DRM_ERROR("invalid con_obj_id %d for device tag 0x%04x\n",
+					  con_obj_id, le16_to_cpu(path->usDeviceTag));
+				continue;
+			}
+
 			connector_type =
 				object_connector_convert[con_obj_id];
 			connector_object_id = con_obj_id;
@@ -566,28 +579,19 @@ int amdgpu_atombios_get_clock_info(struc
 		    le16_to_cpu(firmware_info->info.usReferenceClock);
 		ppll->reference_div = 0;
 
-		if (crev < 2)
-			ppll->pll_out_min =
-				le16_to_cpu(firmware_info->info.usMinPixelClockPLL_Output);
-		else
-			ppll->pll_out_min =
-				le32_to_cpu(firmware_info->info_12.ulMinPixelClockPLL_Output);
+		ppll->pll_out_min =
+			le32_to_cpu(firmware_info->info_12.ulMinPixelClockPLL_Output);
 		ppll->pll_out_max =
 		    le32_to_cpu(firmware_info->info.ulMaxPixelClockPLL_Output);
 
-		if (crev >= 4) {
-			ppll->lcd_pll_out_min =
-				le16_to_cpu(firmware_info->info_14.usLcdMinPixelClockPLL_Output) * 100;
-			if (ppll->lcd_pll_out_min == 0)
-				ppll->lcd_pll_out_min = ppll->pll_out_min;
-			ppll->lcd_pll_out_max =
-				le16_to_cpu(firmware_info->info_14.usLcdMaxPixelClockPLL_Output) * 100;
-			if (ppll->lcd_pll_out_max == 0)
-				ppll->lcd_pll_out_max = ppll->pll_out_max;
-		} else {
+		ppll->lcd_pll_out_min =
+			le16_to_cpu(firmware_info->info_14.usLcdMinPixelClockPLL_Output) * 100;
+		if (ppll->lcd_pll_out_min == 0)
 			ppll->lcd_pll_out_min = ppll->pll_out_min;
+		ppll->lcd_pll_out_max =
+			le16_to_cpu(firmware_info->info_14.usLcdMaxPixelClockPLL_Output) * 100;
+		if (ppll->lcd_pll_out_max == 0)
 			ppll->lcd_pll_out_max = ppll->pll_out_max;
-		}
 
 		if (ppll->pll_out_min == 0)
 			ppll->pll_out_min = 64800;
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c
@@ -10,8 +10,9 @@
 #include <linux/slab.h>
 #include <linux/acpi.h>
 #include <linux/pci.h>
+#include <linux/delay.h>
 
-#include "amdgpu_acpi.h"
+#include "amd_acpi.h"
 
 struct amdgpu_atpx_functions {
 	bool px_params;
@@ -256,6 +257,10 @@ static int amdgpu_atpx_set_discrete_stat
 		if (!info)
 			return -EIO;
 		kfree(info);
+
+		/* 200ms delay is required after off */
+		if (state == 0)
+			msleep(200);
 	}
 	return 0;
 }
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c
@@ -35,6 +35,13 @@
  * BIOS.
  */
 
+#define AMD_VBIOS_SIGNATURE " 761295520"
+#define AMD_VBIOS_SIGNATURE_OFFSET 0x30
+#define AMD_VBIOS_SIGNATURE_SIZE sizeof(AMD_VBIOS_SIGNATURE)
+#define AMD_VBIOS_SIGNATURE_END (AMD_VBIOS_SIGNATURE_OFFSET + AMD_VBIOS_SIGNATURE_SIZE)
+#define AMD_IS_VALID_VBIOS(p) ((p)[0] == 0x55 && (p)[1] == 0xAA)
+#define AMD_VBIOS_LENGTH(p) ((p)[2] << 9)
+
 /* If you boot an IGP board with a discrete card as the primary,
  * the IGP rom is not accessible via the rom bar as the IGP rom is
  * part of the system bios.  On boot, the system bios puts a
@@ -58,7 +65,7 @@ static bool igp_read_bios_from_vram(stru
 		return false;
 	}
 
-	if (size == 0 || bios[0] != 0x55 || bios[1] != 0xaa) {
+	if (size == 0 || !AMD_IS_VALID_VBIOS(bios)) {
 		iounmap(bios);
 		return false;
 	}
@@ -74,7 +81,7 @@ static bool igp_read_bios_from_vram(stru
 
 bool amdgpu_read_bios(struct amdgpu_device *adev)
 {
-	uint8_t __iomem *bios, val1, val2;
+	uint8_t __iomem *bios, val[2];
 	size_t size;
 
 	adev->bios = NULL;
@@ -84,10 +91,10 @@ bool amdgpu_read_bios(struct amdgpu_devi
 		return false;
 	}
 
-	val1 = readb(&bios[0]);
-	val2 = readb(&bios[1]);
+	val[0] = readb(&bios[0]);
+	val[1] = readb(&bios[1]);
 
-	if (size == 0 || val1 != 0x55 || val2 != 0xaa) {
+	if (size == 0 || !AMD_IS_VALID_VBIOS(val)) {
 		pci_unmap_rom(adev->pdev, bios);
 		return false;
 	}
@@ -101,6 +108,38 @@ bool amdgpu_read_bios(struct amdgpu_devi
 	return true;
 }
 
+static bool amdgpu_read_bios_from_rom(struct amdgpu_device *adev)
+{
+	u8 header[AMD_VBIOS_SIGNATURE_END+1] = {0};
+	int len;
+
+	if (!adev->asic_funcs->read_bios_from_rom)
+		return false;
+
+	/* validate VBIOS signature */
+	if (amdgpu_asic_read_bios_from_rom(adev, &header[0], sizeof(header)) == false)
+		return false;
+	header[AMD_VBIOS_SIGNATURE_END] = 0;
+
+	if ((!AMD_IS_VALID_VBIOS(header)) ||
+	    0 != memcmp((char *)&header[AMD_VBIOS_SIGNATURE_OFFSET],
+			AMD_VBIOS_SIGNATURE,
+			strlen(AMD_VBIOS_SIGNATURE)))
+		return false;
+
+	/* valid vbios, go on */
+	len = AMD_VBIOS_LENGTH(header);
+	len = ALIGN(len, 4);
+	adev->bios = kmalloc(len, GFP_KERNEL);
+	if (!adev->bios) {
+		DRM_ERROR("no memory to allocate for BIOS\n");
+		return false;
+	}
+
+	/* read complete BIOS */
+	return amdgpu_asic_read_bios_from_rom(adev, adev->bios, len);
+}
+
 static bool amdgpu_read_platform_bios(struct amdgpu_device *adev)
 {
 	uint8_t __iomem *bios;
@@ -113,7 +152,7 @@ static bool amdgpu_read_platform_bios(st
 		return false;
 	}
 
-	if (size == 0 || bios[0] != 0x55 || bios[1] != 0xaa) {
+	if (size == 0 || !AMD_IS_VALID_VBIOS(bios)) {
 		return false;
 	}
 	adev->bios = kmemdup(bios, size, GFP_KERNEL);
@@ -230,7 +269,7 @@ static bool amdgpu_atrm_get_bios(struct
 			break;
 	}
 
-	if (i == 0 || adev->bios[0] != 0x55 || adev->bios[1] != 0xaa) {
+	if (i == 0 || !AMD_IS_VALID_VBIOS(adev->bios)) {
 		kfree(adev->bios);
 		return false;
 	}
@@ -320,6 +359,9 @@ bool amdgpu_get_bios(struct amdgpu_devic
 	if (r == false)
 		r = amdgpu_read_bios(adev);
 	if (r == false) {
+		r = amdgpu_read_bios_from_rom(adev);
+	}
+	if (r == false) {
 		r = amdgpu_read_disabled_bios(adev);
 	}
 	if (r == false) {
@@ -330,7 +372,7 @@ bool amdgpu_get_bios(struct amdgpu_devic
 		adev->bios = NULL;
 		return false;
 	}
-	if (adev->bios[0] != 0x55 || adev->bios[1] != 0xaa) {
+	if (!AMD_IS_VALID_VBIOS(adev->bios)) {
 		printk("BIOS signature incorrect %x %x\n", adev->bios[0], adev->bios[1]);
 		goto free_bios;
 	}
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c
@@ -24,6 +24,7 @@
 #include <linux/list.h>
 #include <linux/slab.h>
 #include <linux/pci.h>
+#include <linux/acpi.h>
 #include <drm/drmP.h>
 #include <linux/firmware.h>
 #include <drm/amdgpu_drm.h>
@@ -32,7 +33,6 @@
 #include "atom.h"
 #include "amdgpu_ucode.h"
 
-
 struct amdgpu_cgs_device {
 	struct cgs_device base;
 	struct amdgpu_device *adev;
@@ -398,6 +398,41 @@ static void amdgpu_cgs_write_pci_config_
 	WARN(ret, "pci_write_config_dword error");
 }
 
+
+static int amdgpu_cgs_get_pci_resource(void *cgs_device,
+				       enum cgs_resource_type resource_type,
+				       uint64_t size,
+				       uint64_t offset,
+				       uint64_t *resource_base)
+{
+	CGS_FUNC_ADEV;
+
+	if (resource_base == NULL)
+		return -EINVAL;
+
+	switch (resource_type) {
+	case CGS_RESOURCE_TYPE_MMIO:
+		if (adev->rmmio_size == 0)
+			return -ENOENT;
+		if ((offset + size) > adev->rmmio_size)
+			return -EINVAL;
+		*resource_base = adev->rmmio_base;
+		return 0;
+	case CGS_RESOURCE_TYPE_DOORBELL:
+		if (adev->doorbell.size == 0)
+			return -ENOENT;
+		if ((offset + size) > adev->doorbell.size)
+			return -EINVAL;
+		*resource_base = adev->doorbell.base;
+		return 0;
+	case CGS_RESOURCE_TYPE_FB:
+	case CGS_RESOURCE_TYPE_IO:
+	case CGS_RESOURCE_TYPE_ROM:
+	default:
+		return -EINVAL;
+	}
+}
+
 static const void *amdgpu_cgs_atom_get_data_table(void *cgs_device,
 						  unsigned table, uint16_t *size,
 						  uint8_t *frev, uint8_t *crev)
@@ -703,6 +738,9 @@ static int amdgpu_cgs_get_firmware_info(
 		case CHIP_TONGA:
 			strcpy(fw_name, "amdgpu/tonga_smc.bin");
 			break;
+		case CHIP_FIJI:
+			strcpy(fw_name, "amdgpu/fiji_smc.bin");
+			break;
 		default:
 			DRM_ERROR("SMC firmware not supported\n");
 			return -EINVAL;
@@ -736,6 +774,297 @@ static int amdgpu_cgs_get_firmware_info(
 	return 0;
 }
 
+static int amdgpu_cgs_query_system_info(void *cgs_device,
+				struct cgs_system_info *sys_info)
+{
+	CGS_FUNC_ADEV;
+
+	if (NULL == sys_info)
+		return -ENODEV;
+
+	if (sizeof(struct cgs_system_info) != sys_info->size)
+		return -ENODEV;
+
+	switch (sys_info->info_id) {
+	case CGS_SYSTEM_INFO_ADAPTER_BDF_ID:
+		sys_info->value = adev->pdev->devfn | (adev->pdev->bus->number << 8);
+		break;
+	case CGS_SYSTEM_INFO_PCIE_GEN_INFO:
+		sys_info->value = adev->pm.pcie_gen_mask;
+		break;
+	case CGS_SYSTEM_INFO_PCIE_MLW:
+		sys_info->value = adev->pm.pcie_mlw_mask;
+		break;
+	case CGS_SYSTEM_INFO_CG_FLAGS:
+		sys_info->value = adev->cg_flags;
+		break;
+	case CGS_SYSTEM_INFO_PG_FLAGS:
+		sys_info->value = adev->pg_flags;
+		break;
+	default:
+		return -ENODEV;
+	}
+
+	return 0;
+}
+
+static int amdgpu_cgs_get_active_displays_info(void *cgs_device,
+					  struct cgs_display_info *info)
+{
+	CGS_FUNC_ADEV;
+	struct amdgpu_crtc *amdgpu_crtc;
+	struct drm_device *ddev = adev->ddev;
+	struct drm_crtc *crtc;
+	uint32_t line_time_us, vblank_lines;
+	struct cgs_mode_info *mode_info;
+
+	if (info == NULL)
+		return -EINVAL;
+
+	mode_info = info->mode_info;
+
+	if (adev->mode_info.num_crtc && adev->mode_info.mode_config_initialized) {
+		list_for_each_entry(crtc,
+				&ddev->mode_config.crtc_list, head) {
+			amdgpu_crtc = to_amdgpu_crtc(crtc);
+			if (crtc->enabled) {
+				info->active_display_mask |= (1 << amdgpu_crtc->crtc_id);
+				info->display_count++;
+			}
+			if (mode_info != NULL &&
+				crtc->enabled && amdgpu_crtc->enabled &&
+				amdgpu_crtc->hw_mode.clock) {
+				line_time_us = (amdgpu_crtc->hw_mode.crtc_htotal * 1000) /
+							amdgpu_crtc->hw_mode.clock;
+				vblank_lines = amdgpu_crtc->hw_mode.crtc_vblank_end -
+							amdgpu_crtc->hw_mode.crtc_vdisplay +
+							(amdgpu_crtc->v_border * 2);
+				mode_info->vblank_time_us = vblank_lines * line_time_us;
+				mode_info->refresh_rate = drm_mode_vrefresh(&amdgpu_crtc->hw_mode);
+				mode_info->ref_clock = adev->clock.spll.reference_freq;
+				mode_info = NULL;
+			}
+		}
+	}
+
+	return 0;
+}
+
+/** \brief evaluate acpi namespace object, handle or pathname must be valid
+ *  \param cgs_device
+ *  \param info input/output arguments for the control method
+ *  \return status
+ */
+
+#if defined(CONFIG_ACPI)
+static int amdgpu_cgs_acpi_eval_object(void *cgs_device,
+				    struct cgs_acpi_method_info *info)
+{
+	CGS_FUNC_ADEV;
+	acpi_handle handle;
+	struct acpi_object_list input;
+	struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
+	union acpi_object *params = NULL;
+	union acpi_object *obj = NULL;
+	uint8_t name[5] = {'\0'};
+	struct cgs_acpi_method_argument *argument = NULL;
+	uint32_t i, count;
+	acpi_status status;
+	int result;
+	uint32_t func_no = 0xFFFFFFFF;
+
+	handle = ACPI_HANDLE(&adev->pdev->dev);
+	if (!handle)
+		return -ENODEV;
+
+	memset(&input, 0, sizeof(struct acpi_object_list));
+
+	/* validate input info */
+	if (info->size != sizeof(struct cgs_acpi_method_info))
+		return -EINVAL;
+
+	input.count = info->input_count;
+	if (info->input_count > 0) {
+		if (info->pinput_argument == NULL)
+			return -EINVAL;
+		argument = info->pinput_argument;
+		func_no = argument->value;
+		for (i = 0; i < info->input_count; i++) {
+			if (((argument->type == ACPI_TYPE_STRING) ||
+			     (argument->type == ACPI_TYPE_BUFFER)) &&
+			    (argument->pointer == NULL))
+				return -EINVAL;
+			argument++;
+		}
+	}
+
+	if (info->output_count > 0) {
+		if (info->poutput_argument == NULL)
+			return -EINVAL;
+		argument = info->poutput_argument;
+		for (i = 0; i < info->output_count; i++) {
+			if (((argument->type == ACPI_TYPE_STRING) ||
+				(argument->type == ACPI_TYPE_BUFFER))
+				&& (argument->pointer == NULL))
+				return -EINVAL;
+			argument++;
+		}
+	}
+
+	/* The path name passed to acpi_evaluate_object should be null terminated */
+	if ((info->field & CGS_ACPI_FIELD_METHOD_NAME) != 0) {
+		strncpy(name, (char *)&(info->name), sizeof(uint32_t));
+		name[4] = '\0';
+	}
+
+	/* parse input parameters */
+	if (input.count > 0) {
+		input.pointer = params =
+				kzalloc(sizeof(union acpi_object) * input.count, GFP_KERNEL);
+		if (params == NULL)
+			return -EINVAL;
+
+		argument = info->pinput_argument;
+
+		for (i = 0; i < input.count; i++) {
+			params->type = argument->type;
+			switch (params->type) {
+			case ACPI_TYPE_INTEGER:
+				params->integer.value = argument->value;
+				break;
+			case ACPI_TYPE_STRING:
+				params->string.length = argument->method_length;
+				params->string.pointer = argument->pointer;
+				break;
+			case ACPI_TYPE_BUFFER:
+				params->buffer.length = argument->method_length;
+				params->buffer.pointer = argument->pointer;
+				break;
+			default:
+				break;
+			}
+			params++;
+			argument++;
+		}
+	}
+
+	/* parse output info */
+	count = info->output_count;
+	argument = info->poutput_argument;
+
+	/* evaluate the acpi method */
+	status = acpi_evaluate_object(handle, name, &input, &output);
+
+	if (ACPI_FAILURE(status)) {
+		result = -EIO;
+		goto error;
+	}
+
+	/* return the output info */
+	obj = output.pointer;
+
+	if (count > 1) {
+		if ((obj->type != ACPI_TYPE_PACKAGE) ||
+			(obj->package.count != count)) {
+			result = -EIO;
+			goto error;
+		}
+		params = obj->package.elements;
+	} else
+		params = obj;
+
+	if (params == NULL) {
+		result = -EIO;
+		goto error;
+	}
+
+	for (i = 0; i < count; i++) {
+		if (argument->type != params->type) {
+			result = -EIO;
+			goto error;
+		}
+		switch (params->type) {
+		case ACPI_TYPE_INTEGER:
+			argument->value = params->integer.value;
+			break;
+		case ACPI_TYPE_STRING:
+			if ((params->string.length != argument->data_length) ||
+				(params->string.pointer == NULL)) {
+				result = -EIO;
+				goto error;
+			}
+			strncpy(argument->pointer,
+				params->string.pointer,
+				params->string.length);
+			break;
+		case ACPI_TYPE_BUFFER:
+			if (params->buffer.pointer == NULL) {
+				result = -EIO;
+				goto error;
+			}
+			memcpy(argument->pointer,
+				params->buffer.pointer,
+				argument->data_length);
+			break;
+		default:
+			break;
+		}
+		argument++;
+		params++;
+	}
+
+error:
+	if (obj != NULL)
+		kfree(obj);
+	kfree((void *)input.pointer);
+	return result;
+}
+#else
+static int amdgpu_cgs_acpi_eval_object(void *cgs_device,
+				struct cgs_acpi_method_info *info)
+{
+	return -EIO;
+}
+#endif
+
+int amdgpu_cgs_call_acpi_method(void *cgs_device,
+					uint32_t acpi_method,
+					uint32_t acpi_function,
+					void *pinput, void *poutput,
+					uint32_t output_count,
+					uint32_t input_size,
+					uint32_t output_size)
+{
+	struct cgs_acpi_method_argument acpi_input[2] = { {0}, {0} };
+	struct cgs_acpi_method_argument acpi_output = {0};
+	struct cgs_acpi_method_info info = {0};
+
+	acpi_input[0].type = CGS_ACPI_TYPE_INTEGER;
+	acpi_input[0].method_length = sizeof(uint32_t);
+	acpi_input[0].data_length = sizeof(uint32_t);
+	acpi_input[0].value = acpi_function;
+
+	acpi_input[1].type = CGS_ACPI_TYPE_BUFFER;
+	acpi_input[1].method_length = CGS_ACPI_MAX_BUFFER_SIZE;
+	acpi_input[1].data_length = input_size;
+	acpi_input[1].pointer = pinput;
+
+	acpi_output.type = CGS_ACPI_TYPE_BUFFER;
+	acpi_output.method_length = CGS_ACPI_MAX_BUFFER_SIZE;
+	acpi_output.data_length = output_size;
+	acpi_output.pointer = poutput;
+
+	info.size = sizeof(struct cgs_acpi_method_info);
+	info.field = CGS_ACPI_FIELD_METHOD_NAME | CGS_ACPI_FIELD_INPUT_ARGUMENT_COUNT;
+	info.input_count = 2;
+	info.name = acpi_method;
+	info.pinput_argument = acpi_input;
+	info.output_count = output_count;
+	info.poutput_argument = &acpi_output;
+
+	return amdgpu_cgs_acpi_eval_object(cgs_device, &info);
+}
+
 static const struct cgs_ops amdgpu_cgs_ops = {
 	amdgpu_cgs_gpu_mem_info,
 	amdgpu_cgs_gmap_kmem,
@@ -756,6 +1085,7 @@ static const struct cgs_ops amdgpu_cgs_o
 	amdgpu_cgs_write_pci_config_byte,
 	amdgpu_cgs_write_pci_config_word,
 	amdgpu_cgs_write_pci_config_dword,
+	amdgpu_cgs_get_pci_resource,
 	amdgpu_cgs_atom_get_data_table,
 	amdgpu_cgs_atom_get_cmd_table_revs,
 	amdgpu_cgs_atom_exec_cmd_table,
@@ -768,7 +1098,10 @@ static const struct cgs_ops amdgpu_cgs_o
 	amdgpu_cgs_set_camera_voltages,
 	amdgpu_cgs_get_firmware_info,
 	amdgpu_cgs_set_powergating_state,
-	amdgpu_cgs_set_clockgating_state
+	amdgpu_cgs_set_clockgating_state,
+	amdgpu_cgs_get_active_displays_info,
+	amdgpu_cgs_call_acpi_method,
+	amdgpu_cgs_query_system_info,
 };
 
 static const struct cgs_os_ops amdgpu_cgs_os_ops = {
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c
@@ -77,7 +77,7 @@ void amdgpu_connector_hotplug(struct drm
 			} else if (amdgpu_atombios_dp_needs_link_train(amdgpu_connector)) {
 				/* Don't try to start link training before we
 				 * have the dpcd */
-				if (!amdgpu_atombios_dp_get_dpcd(amdgpu_connector))
+				if (amdgpu_atombios_dp_get_dpcd(amdgpu_connector))
 					return;
 
 				/* set it to OFF so that drm_helper_connector_dpms()
@@ -194,12 +194,12 @@ int amdgpu_connector_get_monitor_bpc(str
 				bpc = 8;
 				DRM_DEBUG("%s: HDMI deep color 10 bpc exceeds max tmds clock. Using %d bpc.\n",
 					  connector->name, bpc);
-			} else if (bpc > 8) {
-				/* max_tmds_clock missing, but hdmi spec mandates it for deep color. */
-				DRM_DEBUG("%s: Required max tmds clock for HDMI deep color missing. Using 8 bpc.\n",
-					  connector->name);
-				bpc = 8;
 			}
+		} else if (bpc > 8) {
+			/* max_tmds_clock missing, but hdmi spec mandates it for deep color. */
+			DRM_DEBUG("%s: Required max tmds clock for HDMI deep color missing. Using 8 bpc.\n",
+				  connector->name);
+			bpc = 8;
 		}
 	}
 
@@ -1690,7 +1690,6 @@ amdgpu_connector_add(struct amdgpu_devic
 						   DRM_MODE_SCALE_NONE);
 			/* no HPD on analog connectors */
 			amdgpu_connector->hpd.hpd = AMDGPU_HPD_NONE;
-			connector->polled = DRM_CONNECTOR_POLL_CONNECT;
 			connector->interlace_allowed = true;
 			connector->doublescan_allowed = true;
 			break;
@@ -1893,8 +1892,10 @@ amdgpu_connector_add(struct amdgpu_devic
 	}
 
 	if (amdgpu_connector->hpd.hpd == AMDGPU_HPD_NONE) {
-		if (i2c_bus->valid)
-			connector->polled = DRM_CONNECTOR_POLL_CONNECT;
+		if (i2c_bus->valid) {
+			connector->polled = DRM_CONNECTOR_POLL_CONNECT |
+			                    DRM_CONNECTOR_POLL_DISCONNECT;
+		}
 	} else
 		connector->polled = DRM_CONNECTOR_POLL_HPD;
 
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
@@ -406,8 +406,8 @@ static int amdgpu_cs_parser_relocs(struc
 		amdgpu_cs_buckets_get_list(&buckets, &p->validated);
 	}
 
-	p->vm_bos = amdgpu_vm_get_bos(p->adev, &fpriv->vm,
-				      &p->validated);
+	INIT_LIST_HEAD(&duplicates);
+	amdgpu_vm_get_pd_bo(&fpriv->vm, &p->validated, &p->vm_pd);
 
 	if (p->uf.bo)
 		list_add(&p->uf_entry.tv.head, &p->validated);
@@ -415,20 +415,23 @@ static int amdgpu_cs_parser_relocs(struc
 	if (need_mmap_lock)
 		down_read(&current->mm->mmap_sem);
 
-	INIT_LIST_HEAD(&duplicates);
 	r = ttm_eu_reserve_buffers(&p->ticket, &p->validated, true, &duplicates);
 	if (unlikely(r != 0))
 		goto error_reserve;
 
-	r = amdgpu_cs_list_validate(p->adev, &fpriv->vm, &p->validated);
+	amdgpu_vm_get_pt_bos(&fpriv->vm, &duplicates);
+
+	r = amdgpu_cs_list_validate(p->adev, &fpriv->vm, &duplicates);
 	if (r)
 		goto error_validate;
 
-	r = amdgpu_cs_list_validate(p->adev, &fpriv->vm, &duplicates);
+	r = amdgpu_cs_list_validate(p->adev, &fpriv->vm, &p->validated);
 
 error_validate:
-	if (r)
+	if (r) {
+		amdgpu_vm_move_pt_bos_in_lru(p->adev, &fpriv->vm);
 		ttm_eu_backoff_reservation(&p->ticket, &p->validated);
+	}
 
 error_reserve:
 	if (need_mmap_lock)
@@ -472,9 +475,12 @@ static int cmp_size_smaller_first(void *
  **/
 static void amdgpu_cs_parser_fini(struct amdgpu_cs_parser *parser, int error, bool backoff)
 {
+	struct amdgpu_fpriv *fpriv = parser->filp->driver_priv;
 	unsigned i;
 
 	if (!error) {
+		amdgpu_vm_move_pt_bos_in_lru(parser->adev, &fpriv->vm);
+
 		/* Sort the buffer list from the smallest to largest buffer,
 		 * which affects the order of buffers in the LRU list.
 		 * This assures that the smallest buffers are added first
@@ -501,7 +507,6 @@ static void amdgpu_cs_parser_fini(struct
 	if (parser->bo_list)
 		amdgpu_bo_list_put(parser->bo_list);
 
-	drm_free_large(parser->vm_bos);
 	for (i = 0; i < parser->nchunks; i++)
 		drm_free_large(parser->chunks[i].kdata);
 	kfree(parser->chunks);
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c
@@ -25,7 +25,7 @@
 #include <drm/drmP.h>
 #include "amdgpu.h"
 
-int amdgpu_ctx_init(struct amdgpu_device *adev, bool kernel,
+int amdgpu_ctx_init(struct amdgpu_device *adev, enum amd_sched_priority pri,
 		    struct amdgpu_ctx *ctx)
 {
 	unsigned i, j;
@@ -35,17 +35,25 @@ int amdgpu_ctx_init(struct amdgpu_device
 	ctx->adev = adev;
 	kref_init(&ctx->refcount);
 	spin_lock_init(&ctx->ring_lock);
-	for (i = 0; i < AMDGPU_MAX_RINGS; ++i)
-		ctx->rings[i].sequence = 1;
+	ctx->fences = kzalloc(sizeof(struct fence *) * amdgpu_sched_jobs *
+			 AMDGPU_MAX_RINGS, GFP_KERNEL);
+	if (!ctx->fences)
+		return -ENOMEM;
 
+	for (i = 0; i < AMDGPU_MAX_RINGS; ++i) {
+		ctx->rings[i].sequence = 1;
+		ctx->rings[i].fences = (void *)ctx->fences + sizeof(struct fence *) *
+			amdgpu_sched_jobs * i;
+	}
 	if (amdgpu_enable_scheduler) {
 		/* create context entity for each ring */
 		for (i = 0; i < adev->num_rings; i++) {
 			struct amd_sched_rq *rq;
-			if (kernel)
-				rq = &adev->rings[i]->sched.kernel_rq;
-			else
-				rq = &adev->rings[i]->sched.sched_rq;
+			if (pri >= AMD_SCHED_MAX_PRIORITY) {
+				kfree(ctx->fences);
+				return -EINVAL;
+			}
+			rq = &adev->rings[i]->sched.sched_rq[pri];
 			r = amd_sched_entity_init(&adev->rings[i]->sched,
 						  &ctx->rings[i].entity,
 						  rq, amdgpu_sched_jobs);
@@ -57,7 +65,7 @@ int amdgpu_ctx_init(struct amdgpu_device
 			for (j = 0; j < i; j++)
 				amd_sched_entity_fini(&adev->rings[j]->sched,
 						      &ctx->rings[j].entity);
-			kfree(ctx);
+			kfree(ctx->fences);
 			return r;
 		}
 	}
@@ -73,8 +81,9 @@ void amdgpu_ctx_fini(struct amdgpu_ctx *
 		return;
 
 	for (i = 0; i < AMDGPU_MAX_RINGS; ++i)
-		for (j = 0; j < AMDGPU_CTX_MAX_CS_PENDING; ++j)
+		for (j = 0; j < amdgpu_sched_jobs; ++j)
 			fence_put(ctx->rings[i].fences[j]);
+	kfree(ctx->fences);
 
 	if (amdgpu_enable_scheduler) {
 		for (i = 0; i < adev->num_rings; i++)
@@ -103,9 +112,13 @@ static int amdgpu_ctx_alloc(struct amdgp
 		return r;
 	}
 	*id = (uint32_t)r;
-	r = amdgpu_ctx_init(adev, false, ctx);
+	r = amdgpu_ctx_init(adev, AMD_SCHED_PRIORITY_NORMAL, ctx);
+	if (r) {
+		idr_remove(&mgr->ctx_handles, *id);
+		*id = 0;
+		kfree(ctx);
+	}
 	mutex_unlock(&mgr->lock);
-
 	return r;
 }
 
@@ -239,7 +252,7 @@ uint64_t amdgpu_ctx_add_fence(struct amd
 	unsigned idx = 0;
 	struct fence *other = NULL;
 
-	idx = seq % AMDGPU_CTX_MAX_CS_PENDING;
+	idx = seq & (amdgpu_sched_jobs - 1);
 	other = cring->fences[idx];
 	if (other) {
 		signed long r;
@@ -274,12 +287,12 @@ struct fence *amdgpu_ctx_get_fence(struc
 	}
 
 
-	if (seq + AMDGPU_CTX_MAX_CS_PENDING < cring->sequence) {
+	if (seq + amdgpu_sched_jobs < cring->sequence) {
 		spin_unlock(&ctx->ring_lock);
 		return NULL;
 	}
 
-	fence = fence_get(cring->fences[seq % AMDGPU_CTX_MAX_CS_PENDING]);
+	fence = fence_get(cring->fences[seq & (amdgpu_sched_jobs - 1)]);
 	spin_unlock(&ctx->ring_lock);
 
 	return fence;
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
@@ -38,6 +38,7 @@
 #include "amdgpu_i2c.h"
 #include "atom.h"
 #include "amdgpu_atombios.h"
+#include "amd_pcie.h"
 #ifdef CONFIG_DRM_AMDGPU_CIK
 #include "cik.h"
 #endif
@@ -949,6 +950,15 @@ static bool amdgpu_check_pot_argument(in
  */
 static void amdgpu_check_arguments(struct amdgpu_device *adev)
 {
+	if (amdgpu_sched_jobs < 4) {
+		dev_warn(adev->dev, "sched jobs (%d) must be at least 4\n",
+			 amdgpu_sched_jobs);
+		amdgpu_sched_jobs = 4;
+	} else if (!amdgpu_check_pot_argument(amdgpu_sched_jobs)){
+		dev_warn(adev->dev, "sched jobs (%d) must be a power of 2\n",
+			 amdgpu_sched_jobs);
+		amdgpu_sched_jobs = roundup_pow_of_two(amdgpu_sched_jobs);
+	}
 	/* vramlimit must be a power of two */
 	if (!amdgpu_check_pot_argument(amdgpu_vram_limit)) {
 		dev_warn(adev->dev, "vram limit (%d) must be a power of 2\n",
@@ -1214,12 +1224,14 @@ static int amdgpu_early_init(struct amdg
 		} else {
 			if (adev->ip_blocks[i].funcs->early_init) {
 				r = adev->ip_blocks[i].funcs->early_init((void *)adev);
-				if (r == -ENOENT)
+				if (r == -ENOENT) {
 					adev->ip_block_status[i].valid = false;
-				else if (r)
+				} else if (r) {
+					DRM_ERROR("early_init %d failed %d\n", i, r);
 					return r;
-				else
+				} else {
 					adev->ip_block_status[i].valid = true;
+				}
 			} else {
 				adev->ip_block_status[i].valid = true;
 			}
@@ -1237,20 +1249,28 @@ static int amdgpu_init(struct amdgpu_dev
 		if (!adev->ip_block_status[i].valid)
 			continue;
 		r = adev->ip_blocks[i].funcs->sw_init((void *)adev);
-		if (r)
+		if (r) {
+			DRM_ERROR("sw_init %d failed %d\n", i, r);
 			return r;
+		}
 		adev->ip_block_status[i].sw = true;
 		/* need to do gmc hw init early so we can allocate gpu mem */
 		if (adev->ip_blocks[i].type == AMD_IP_BLOCK_TYPE_GMC) {
 			r = amdgpu_vram_scratch_init(adev);
-			if (r)
+			if (r) {
+				DRM_ERROR("amdgpu_vram_scratch_init failed %d\n", r);
 				return r;
+			}
 			r = adev->ip_blocks[i].funcs->hw_init((void *)adev);
-			if (r)
+			if (r) {
+				DRM_ERROR("hw_init %d failed %d\n", i, r);
 				return r;
+			}
 			r = amdgpu_wb_init(adev);
-			if (r)
+			if (r) {
+				DRM_ERROR("amdgpu_wb_init failed %d\n", r);
 				return r;
+			}
 			adev->ip_block_status[i].hw = true;
 		}
 	}
@@ -1262,8 +1282,10 @@ static int amdgpu_init(struct amdgpu_dev
 		if (adev->ip_blocks[i].type == AMD_IP_BLOCK_TYPE_GMC)
 			continue;
 		r = adev->ip_blocks[i].funcs->hw_init((void *)adev);
-		if (r)
+		if (r) {
+			DRM_ERROR("hw_init %d failed %d\n", i, r);
 			return r;
+		}
 		adev->ip_block_status[i].hw = true;
 	}
 
@@ -1280,12 +1302,16 @@ static int amdgpu_late_init(struct amdgp
 		/* enable clockgating to save power */
 		r = adev->ip_blocks[i].funcs->set_clockgating_state((void *)adev,
 								    AMD_CG_STATE_GATE);
-		if (r)
+		if (r) {
+			DRM_ERROR("set_clockgating_state(gate) %d failed %d\n", i, r);
 			return r;
+		}
 		if (adev->ip_blocks[i].funcs->late_init) {
 			r = adev->ip_blocks[i].funcs->late_init((void *)adev);
-			if (r)
+			if (r) {
+				DRM_ERROR("late_init %d failed %d\n", i, r);
 				return r;
+			}
 		}
 	}
 
@@ -1306,10 +1332,15 @@ static int amdgpu_fini(struct amdgpu_dev
 		/* ungate blocks before hw fini so that we can shutdown the blocks safely */
 		r = adev->ip_blocks[i].funcs->set_clockgating_state((void *)adev,
 								    AMD_CG_STATE_UNGATE);
-		if (r)
+		if (r) {
+			DRM_ERROR("set_clockgating_state(ungate) %d failed %d\n", i, r);
 			return r;
+		}
 		r = adev->ip_blocks[i].funcs->hw_fini((void *)adev);
 		/* XXX handle errors */
+		if (r) {
+			DRM_DEBUG("hw_fini %d failed %d\n", i, r);
+		}
 		adev->ip_block_status[i].hw = false;
 	}
 
@@ -1318,6 +1349,9 @@ static int amdgpu_fini(struct amdgpu_dev
 			continue;
 		r = adev->ip_blocks[i].funcs->sw_fini((void *)adev);
 		/* XXX handle errors */
+		if (r) {
+			DRM_DEBUG("sw_fini %d failed %d\n", i, r);
+		}
 		adev->ip_block_status[i].sw = false;
 		adev->ip_block_status[i].valid = false;
 	}
@@ -1335,9 +1369,15 @@ static int amdgpu_suspend(struct amdgpu_
 		/* ungate blocks so that suspend can properly shut them down */
 		r = adev->ip_blocks[i].funcs->set_clockgating_state((void *)adev,
 								    AMD_CG_STATE_UNGATE);
+		if (r) {
+			DRM_ERROR("set_clockgating_state(ungate) %d failed %d\n", i, r);
+		}
 		/* XXX handle errors */
 		r = adev->ip_blocks[i].funcs->suspend(adev);
 		/* XXX handle errors */
+		if (r) {
+			DRM_ERROR("suspend %d failed %d\n", i, r);
+		}
 	}
 
 	return 0;
@@ -1351,8 +1391,10 @@ static int amdgpu_resume(struct amdgpu_d
 		if (!adev->ip_block_status[i].valid)
 			continue;
 		r = adev->ip_blocks[i].funcs->resume(adev);
-		if (r)
+		if (r) {
+			DRM_ERROR("resume %d failed %d\n", i, r);
 			return r;
+		}
 	}
 
 	return 0;
@@ -1484,8 +1526,10 @@ int amdgpu_device_init(struct amdgpu_dev
 		return -EINVAL;
 	}
 	r = amdgpu_atombios_init(adev);
-	if (r)
+	if (r) {
+		dev_err(adev->dev, "amdgpu_atombios_init failed\n");
 		return r;
+	}
 
 	/* Post card if necessary */
 	if (!amdgpu_card_posted(adev)) {
@@ -1499,21 +1543,26 @@ int amdgpu_device_init(struct amdgpu_dev
 
 	/* Initialize clocks */
 	r = amdgpu_atombios_get_clock_info(adev);
-	if (r)
+	if (r) {
+		dev_err(adev->dev, "amdgpu_atombios_get_clock_info failed\n");
 		return r;
+	}
 	/* init i2c buses */
 	amdgpu_atombios_i2c_init(adev);
 
 	/* Fence driver */
 	r = amdgpu_fence_driver_init(adev);
-	if (r)
+	if (r) {
+		dev_err(adev->dev, "amdgpu_fence_driver_init failed\n");
 		return r;
+	}
 
 	/* init the mode config */
 	drm_mode_config_init(adev->ddev);
 
 	r = amdgpu_init(adev);
 	if (r) {
+		dev_err(adev->dev, "amdgpu_init failed\n");
 		amdgpu_fini(adev);
 		return r;
 	}
@@ -1528,7 +1577,7 @@ int amdgpu_device_init(struct amdgpu_dev
 		return r;
 	}
 
-	r = amdgpu_ctx_init(adev, true, &adev->kernel_ctx);
+	r = amdgpu_ctx_init(adev, AMD_SCHED_PRIORITY_KERNEL, &adev->kernel_ctx);
 	if (r) {
 		dev_err(adev->dev, "failed to create kernel context (%d).\n", r);
 		return r;
@@ -1570,8 +1619,10 @@ int amdgpu_device_init(struct amdgpu_dev
 	 * explicit gating rather than handling it automatically.
 	 */
 	r = amdgpu_late_init(adev);
-	if (r)
+	if (r) {
+		dev_err(adev->dev, "amdgpu_late_init failed\n");
 		return r;
+	}
 
 	return 0;
 }
@@ -1744,15 +1795,20 @@ int amdgpu_resume_kms(struct drm_device
 	}
 
 	/* post card */
-	amdgpu_atom_asic_init(adev->mode_info.atom_context);
+	if (!amdgpu_card_posted(adev))
+		amdgpu_atom_asic_init(adev->mode_info.atom_context);
 
 	r = amdgpu_resume(adev);
+	if (r)
+		DRM_ERROR("amdgpu_resume failed (%d).\n", r);
 
 	amdgpu_fence_driver_resume(adev);
 
-	r = amdgpu_ib_ring_tests(adev);
-	if (r)
-		DRM_ERROR("ib ring test failed (%d).\n", r);
+	if (resume) {
+		r = amdgpu_ib_ring_tests(adev);
+		if (r)
+			DRM_ERROR("ib ring test failed (%d).\n", r);
+	}
 
 	r = amdgpu_late_init(adev);
 	if (r)
@@ -1789,6 +1845,23 @@ int amdgpu_resume_kms(struct drm_device
 
 	drm_kms_helper_poll_enable(dev);
 
+	/*
+	 * Most of the connector probing functions try to acquire runtime pm
+	 * refs to ensure that the GPU is powered on when connector polling is
+	 * performed. Since we're calling this from a runtime PM callback,
+	 * trying to acquire rpm refs will cause us to deadlock.
+	 *
+	 * Since we're guaranteed to be holding the rpm lock, it's safe to
+	 * temporarily disable the rpm helpers so this doesn't deadlock us.
+	 */
+#ifdef CONFIG_PM
+	dev->dev->power.disable_depth++;
+#endif
+	drm_helper_hpd_irq_event(dev);
+#ifdef CONFIG_PM
+	dev->dev->power.disable_depth--;
+#endif
+
 	if (fbcon) {
 		amdgpu_fbdev_set_suspend(adev, 0);
 		console_unlock();
@@ -1881,6 +1954,100 @@ retry:
 	return r;
 }
 
+#define AMDGPU_DEFAULT_PCIE_GEN_MASK 0x30007  /* gen: chipset 1/2, asic 1/2/3 */
+#define AMDGPU_DEFAULT_PCIE_MLW_MASK 0x2f0000 /* 1/2/4/8/16 lanes */
+
+void amdgpu_get_pcie_info(struct amdgpu_device *adev)
+{
+	u32 mask;
+	int ret;
+
+	if (amdgpu_pcie_gen_cap)
+		adev->pm.pcie_gen_mask = amdgpu_pcie_gen_cap;
+
+	if (amdgpu_pcie_lane_cap)
+		adev->pm.pcie_mlw_mask = amdgpu_pcie_lane_cap;
+
+	/* covers APUs as well */
+	if (pci_is_root_bus(adev->pdev->bus)) {
+		if (adev->pm.pcie_gen_mask == 0)
+			adev->pm.pcie_gen_mask = AMDGPU_DEFAULT_PCIE_GEN_MASK;
+		if (adev->pm.pcie_mlw_mask == 0)
+			adev->pm.pcie_mlw_mask = AMDGPU_DEFAULT_PCIE_MLW_MASK;
+		return;
+	}
+
+	if (adev->pm.pcie_gen_mask == 0) {
+		ret = drm_pcie_get_speed_cap_mask(adev->ddev, &mask);
+		if (!ret) {
+			adev->pm.pcie_gen_mask = (CAIL_ASIC_PCIE_LINK_SPEED_SUPPORT_GEN1 |
+						  CAIL_ASIC_PCIE_LINK_SPEED_SUPPORT_GEN2 |
+						  CAIL_ASIC_PCIE_LINK_SPEED_SUPPORT_GEN3);
+
+			if (mask & DRM_PCIE_SPEED_25)
+				adev->pm.pcie_gen_mask |= CAIL_PCIE_LINK_SPEED_SUPPORT_GEN1;
+			if (mask & DRM_PCIE_SPEED_50)
+				adev->pm.pcie_gen_mask |= CAIL_PCIE_LINK_SPEED_SUPPORT_GEN2;
+			if (mask & DRM_PCIE_SPEED_80)
+				adev->pm.pcie_gen_mask |= CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3;
+		} else {
+			adev->pm.pcie_gen_mask = AMDGPU_DEFAULT_PCIE_GEN_MASK;
+		}
+	}
+	if (adev->pm.pcie_mlw_mask == 0) {
+		ret = drm_pcie_get_max_link_width(adev->ddev, &mask);
+		if (!ret) {
+			switch (mask) {
+			case 32:
+				adev->pm.pcie_mlw_mask = (CAIL_PCIE_LINK_WIDTH_SUPPORT_X32 |
+							  CAIL_PCIE_LINK_WIDTH_SUPPORT_X16 |
+							  CAIL_PCIE_LINK_WIDTH_SUPPORT_X12 |
+							  CAIL_PCIE_LINK_WIDTH_SUPPORT_X8 |
+							  CAIL_PCIE_LINK_WIDTH_SUPPORT_X4 |
+							  CAIL_PCIE_LINK_WIDTH_SUPPORT_X2 |
+							  CAIL_PCIE_LINK_WIDTH_SUPPORT_X1);
+				break;
+			case 16:
+				adev->pm.pcie_mlw_mask = (CAIL_PCIE_LINK_WIDTH_SUPPORT_X16 |
+							  CAIL_PCIE_LINK_WIDTH_SUPPORT_X12 |
+							  CAIL_PCIE_LINK_WIDTH_SUPPORT_X8 |
+							  CAIL_PCIE_LINK_WIDTH_SUPPORT_X4 |
+							  CAIL_PCIE_LINK_WIDTH_SUPPORT_X2 |
+							  CAIL_PCIE_LINK_WIDTH_SUPPORT_X1);
+				break;
+			case 12:
+				adev->pm.pcie_mlw_mask = (CAIL_PCIE_LINK_WIDTH_SUPPORT_X12 |
+							  CAIL_PCIE_LINK_WIDTH_SUPPORT_X8 |
+							  CAIL_PCIE_LINK_WIDTH_SUPPORT_X4 |
+							  CAIL_PCIE_LINK_WIDTH_SUPPORT_X2 |
+							  CAIL_PCIE_LINK_WIDTH_SUPPORT_X1);
+				break;
+			case 8:
+				adev->pm.pcie_mlw_mask = (CAIL_PCIE_LINK_WIDTH_SUPPORT_X8 |
+							  CAIL_PCIE_LINK_WIDTH_SUPPORT_X4 |
+							  CAIL_PCIE_LINK_WIDTH_SUPPORT_X2 |
+							  CAIL_PCIE_LINK_WIDTH_SUPPORT_X1);
+				break;
+			case 4:
+				adev->pm.pcie_mlw_mask = (CAIL_PCIE_LINK_WIDTH_SUPPORT_X4 |
+							  CAIL_PCIE_LINK_WIDTH_SUPPORT_X2 |
+							  CAIL_PCIE_LINK_WIDTH_SUPPORT_X1);
+				break;
+			case 2:
+				adev->pm.pcie_mlw_mask = (CAIL_PCIE_LINK_WIDTH_SUPPORT_X2 |
+							  CAIL_PCIE_LINK_WIDTH_SUPPORT_X1);
+				break;
+			case 1:
+				adev->pm.pcie_mlw_mask = CAIL_PCIE_LINK_WIDTH_SUPPORT_X1;
+				break;
+			default:
+				break;
+			}
+		} else {
+			adev->pm.pcie_mlw_mask = AMDGPU_DEFAULT_PCIE_MLW_MASK;
+		}
+	}
+}
 
 /*
  * Debugfs
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
@@ -72,8 +72,8 @@ static void amdgpu_flip_work_func(struct
 
 	struct drm_crtc *crtc = &amdgpuCrtc->base;
 	unsigned long flags;
-	unsigned i;
-	int vpos, hpos, stat, min_udelay;
+	unsigned i, repcnt = 4;
+	int vpos, hpos, stat, min_udelay = 0;
 	struct drm_vblank_crtc *vblank = &crtc->dev->vblank[work->crtc_id];
 
 	amdgpu_flip_wait_fence(adev, &work->excl);
@@ -96,7 +96,7 @@ static void amdgpu_flip_work_func(struct
 	 * In practice this won't execute very often unless on very fast
 	 * machines because the time window for this to happen is very small.
 	 */
-	for (;;) {
+	while (amdgpuCrtc->enabled && --repcnt) {
 		/* GET_DISTANCE_TO_VBLANKSTART returns distance to real vblank
 		 * start in hpos, and to the "fudged earlier" vblank start in
 		 * vpos.
@@ -112,12 +112,24 @@ static void amdgpu_flip_work_func(struct
 			break;
 
 		/* Sleep at least until estimated real start of hw vblank */
-		spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
 		min_udelay = (-hpos + 1) * max(vblank->linedur_ns / 1000, 5);
+		if (min_udelay > vblank->framedur_ns / 2000) {
+			/* Don't wait ridiculously long - something is wrong */
+			repcnt = 0;
+			break;
+		}
+		spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
 		usleep_range(min_udelay, 2 * min_udelay);
 		spin_lock_irqsave(&crtc->dev->event_lock, flags);
 	};
 
+	if (!repcnt)
+		DRM_DEBUG_DRIVER("Delay problem on crtc %d: min_udelay %d, "
+				 "framedur %d, linedur %d, stat %d, vpos %d, "
+				 "hpos %d\n", work->crtc_id, min_udelay,
+				 vblank->framedur_ns / 1000,
+				 vblank->linedur_ns / 1000, stat, vpos, hpos);
+
 	/* do the flip (mmio) */
 	adev->mode_info.funcs->page_flip(adev, work->crtc_id, work->base);
 	/* set the flip status */
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.c
@@ -150,7 +150,7 @@ u32 amdgpu_dpm_get_vrefresh(struct amdgp
 		list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
 			amdgpu_crtc = to_amdgpu_crtc(crtc);
 			if (crtc->enabled && amdgpu_crtc->enabled && amdgpu_crtc->hw_mode.clock) {
-				vrefresh = amdgpu_crtc->hw_mode.vrefresh;
+				vrefresh = drm_mode_vrefresh(&amdgpu_crtc->hw_mode);
 				break;
 			}
 		}
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
@@ -79,9 +79,12 @@ int amdgpu_vm_fault_stop = 0;
 int amdgpu_vm_debug = 0;
 int amdgpu_exp_hw_support = 0;
 int amdgpu_enable_scheduler = 1;
-int amdgpu_sched_jobs = 16;
+int amdgpu_sched_jobs = 32;
 int amdgpu_sched_hw_submission = 2;
 int amdgpu_enable_semaphores = 0;
+int amdgpu_powerplay = -1;
+unsigned amdgpu_pcie_gen_cap = 0;
+unsigned amdgpu_pcie_lane_cap = 0;
 
 MODULE_PARM_DESC(vramlimit, "Restrict VRAM for testing, in megabytes");
 module_param_named(vramlimit, amdgpu_vram_limit, int, 0600);
@@ -155,7 +158,7 @@ module_param_named(exp_hw_support, amdgp
 MODULE_PARM_DESC(enable_scheduler, "enable SW GPU scheduler (1 = enable (default), 0 = disable)");
 module_param_named(enable_scheduler, amdgpu_enable_scheduler, int, 0444);
 
-MODULE_PARM_DESC(sched_jobs, "the max number of jobs supported in the sw queue (default 16)");
+MODULE_PARM_DESC(sched_jobs, "the max number of jobs supported in the sw queue (default 32)");
 module_param_named(sched_jobs, amdgpu_sched_jobs, int, 0444);
 
 MODULE_PARM_DESC(sched_hw_submission, "the max number of HW submissions (default 2)");
@@ -164,6 +167,17 @@ module_param_named(sched_hw_submission,
 MODULE_PARM_DESC(enable_semaphores, "Enable semaphores (1 = enable, 0 = disable (default))");
 module_param_named(enable_semaphores, amdgpu_enable_semaphores, int, 0644);
 
+#ifdef CONFIG_DRM_AMD_POWERPLAY
+MODULE_PARM_DESC(powerplay, "Powerplay component (1 = enable, 0 = disable, -1 = auto (default))");
+module_param_named(powerplay, amdgpu_powerplay, int, 0444);
+#endif
+
+MODULE_PARM_DESC(pcie_gen_cap, "PCIE Gen Caps (0: autodetect (default))");
+module_param_named(pcie_gen_cap, amdgpu_pcie_gen_cap, uint, 0444);
+
+MODULE_PARM_DESC(pcie_lane_cap, "PCIE Lane Caps (0: autodetect (default))");
+module_param_named(pcie_lane_cap, amdgpu_pcie_lane_cap, uint, 0444);
+
 static struct pci_device_id pciidlist[] = {
 #ifdef CONFIG_DRM_AMDGPU_CIK
 	/* Kaveri */
@@ -250,11 +264,11 @@ static struct pci_device_id pciidlist[]
 	{0x1002, 0x985F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MULLINS|AMD_IS_MOBILITY|AMD_IS_APU},
 #endif
 	/* topaz */
-	{0x1002, 0x6900, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TOPAZ|AMD_EXP_HW_SUPPORT},
-	{0x1002, 0x6901, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TOPAZ|AMD_EXP_HW_SUPPORT},
-	{0x1002, 0x6902, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TOPAZ|AMD_EXP_HW_SUPPORT},
-	{0x1002, 0x6903, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TOPAZ|AMD_EXP_HW_SUPPORT},
-	{0x1002, 0x6907, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TOPAZ|AMD_EXP_HW_SUPPORT},
+	{0x1002, 0x6900, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TOPAZ},
+	{0x1002, 0x6901, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TOPAZ},
+	{0x1002, 0x6902, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TOPAZ},
+	{0x1002, 0x6903, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TOPAZ},
+	{0x1002, 0x6907, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TOPAZ},
 	/* tonga */
 	{0x1002, 0x6920, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TONGA},
 	{0x1002, 0x6921, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TONGA},
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c
@@ -264,7 +264,7 @@ out_unref:
 
 	}
 	if (fb && ret) {
-		drm_gem_object_unreference(gobj);
+		drm_gem_object_unreference_unlocked(gobj);
 		drm_framebuffer_unregister_private(fb);
 		drm_framebuffer_cleanup(fb);
 		kfree(fb);
@@ -334,6 +334,10 @@ int amdgpu_fbdev_init(struct amdgpu_devi
 	if (!adev->mode_info.mode_config_initialized)
 		return 0;
 
+	/* don't init fbdev if there are no connectors */
+	if (list_empty(&adev->ddev->mode_config.connector_list))
+		return 0;
+
 	/* select 8 bpp console on low vram cards */
 	if (adev->mc.real_vram_size <= (32*1024*1024))
 		bpp_sel = 8;
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c
@@ -221,7 +221,7 @@ void amdgpu_gart_table_vram_free(struct
  * Unbinds the requested pages from the gart page table and
  * replaces them with the dummy page (all asics).
  */
-void amdgpu_gart_unbind(struct amdgpu_device *adev, unsigned offset,
+void amdgpu_gart_unbind(struct amdgpu_device *adev, uint64_t offset,
 			int pages)
 {
 	unsigned t;
@@ -269,7 +269,7 @@ void amdgpu_gart_unbind(struct amdgpu_de
  * (all asics).
  * Returns 0 for success, -EINVAL for failure.
  */
-int amdgpu_gart_bind(struct amdgpu_device *adev, unsigned offset,
+int amdgpu_gart_bind(struct amdgpu_device *adev, uint64_t offset,
 		     int pages, struct page **pagelist, dma_addr_t *dma_addr,
 		     uint32_t flags)
 {
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
@@ -448,7 +448,7 @@ static void amdgpu_gem_va_update_vm(stru
 				    struct amdgpu_bo_va *bo_va, uint32_t operation)
 {
 	struct ttm_validate_buffer tv, *entry;
-	struct amdgpu_bo_list_entry *vm_bos;
+	struct amdgpu_bo_list_entry vm_pd;
 	struct ww_acquire_ctx ticket;
 	struct list_head list, duplicates;
 	unsigned domain;
@@ -461,15 +461,14 @@ static void amdgpu_gem_va_update_vm(stru
 	tv.shared = true;
 	list_add(&tv.head, &list);
 
-	vm_bos = amdgpu_vm_get_bos(adev, bo_va->vm, &list);
-	if (!vm_bos)
-		return;
+	amdgpu_vm_get_pd_bo(bo_va->vm, &list, &vm_pd);
 
 	/* Provide duplicates to avoid -EALREADY */
 	r = ttm_eu_reserve_buffers(&ticket, &list, true, &duplicates);
 	if (r)
-		goto error_free;
+		goto error_print;
 
+	amdgpu_vm_get_pt_bos(bo_va->vm, &duplicates);
 	list_for_each_entry(entry, &list, head) {
 		domain = amdgpu_mem_type_to_domain(entry->bo->mem.mem_type);
 		/* if anything is swapped out don't swap it in here,
@@ -499,9 +498,7 @@ static void amdgpu_gem_va_update_vm(stru
 error_unreserve:
 	ttm_eu_backoff_reservation(&ticket, &list);
 
-error_free:
-	drm_free_large(vm_bos);
-
+error_print:
 	if (r && r != -ERESTARTSYS)
 		DRM_ERROR("Couldn't update BO_VA (%d)\n", r);
 }
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c
@@ -288,7 +288,7 @@ void amdgpu_ib_pool_fini(struct amdgpu_d
 int amdgpu_ib_ring_tests(struct amdgpu_device *adev)
 {
 	unsigned i;
-	int r;
+	int r, ret = 0;
 
 	for (i = 0; i < AMDGPU_MAX_RINGS; ++i) {
 		struct amdgpu_ring *ring = adev->rings[i];
@@ -309,10 +309,11 @@ int amdgpu_ib_ring_tests(struct amdgpu_d
 			} else {
 				/* still not good, but we can live with it */
 				DRM_ERROR("amdgpu: failed testing IB on ring %d (%d).\n", i, r);
+				ret = r;
 			}
 		}
 	}
-	return 0;
+	return ret;
 }
 
 /*
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c
@@ -25,6 +25,7 @@
  *          Alex Deucher
  *          Jerome Glisse
  */
+#include <linux/irq.h>
 #include <drm/drmP.h>
 #include <drm/drm_crtc_helper.h>
 #include <drm/amdgpu_drm.h>
@@ -312,6 +313,7 @@ int amdgpu_irq_add_id(struct amdgpu_devi
 	}
 
 	adev->irq.sources[src_id] = source;
+
 	return 0;
 }
 
@@ -335,15 +337,19 @@ void amdgpu_irq_dispatch(struct amdgpu_d
 		return;
 	}
 
-	src = adev->irq.sources[src_id];
-	if (!src) {
-		DRM_DEBUG("Unhandled interrupt src_id: %d\n", src_id);
-		return;
-	}
+	if (adev->irq.virq[src_id]) {
+		generic_handle_irq(irq_find_mapping(adev->irq.domain, src_id));
+	} else {
+		src = adev->irq.sources[src_id];
+		if (!src) {
+			DRM_DEBUG("Unhandled interrupt src_id: %d\n", src_id);
+			return;
+		}
 
-	r = src->funcs->process(adev, src, entry);
-	if (r)
-		DRM_ERROR("error processing interrupt (%d)\n", r);
+		r = src->funcs->process(adev, src, entry);
+		if (r)
+			DRM_ERROR("error processing interrupt (%d)\n", r);
+	}
 }
 
 /**
@@ -461,3 +467,90 @@ bool amdgpu_irq_enabled(struct amdgpu_de
 
 	return !!atomic_read(&src->enabled_types[type]);
 }
+
+/* gen irq */
+static void amdgpu_irq_mask(struct irq_data *irqd)
+{
+	/* XXX */
+}
+
+static void amdgpu_irq_unmask(struct irq_data *irqd)
+{
+	/* XXX */
+}
+
+static struct irq_chip amdgpu_irq_chip = {
+	.name = "amdgpu-ih",
+	.irq_mask = amdgpu_irq_mask,
+	.irq_unmask = amdgpu_irq_unmask,
+};
+
+static int amdgpu_irqdomain_map(struct irq_domain *d,
+				unsigned int irq, irq_hw_number_t hwirq)
+{
+	if (hwirq >= AMDGPU_MAX_IRQ_SRC_ID)
+		return -EPERM;
+
+	irq_set_chip_and_handler(irq,
+				 &amdgpu_irq_chip, handle_simple_irq);
+	return 0;
+}
+
+static struct irq_domain_ops amdgpu_hw_irqdomain_ops = {
+	.map = amdgpu_irqdomain_map,
+};
+
+/**
+ * amdgpu_irq_add_domain - create a linear irq domain
+ *
+ * @adev: amdgpu device pointer
+ *
+ * Create an irq domain for GPU interrupt sources
+ * that may be driven by another driver (e.g., ACP).
+ */
+int amdgpu_irq_add_domain(struct amdgpu_device *adev)
+{
+	adev->irq.domain = irq_domain_add_linear(NULL, AMDGPU_MAX_IRQ_SRC_ID,
+						 &amdgpu_hw_irqdomain_ops, adev);
+	if (!adev->irq.domain) {
+		DRM_ERROR("GPU irq add domain failed\n");
+		return -ENODEV;
+	}
+
+	return 0;
+}
+
+/**
+ * amdgpu_irq_remove_domain - remove the irq domain
+ *
+ * @adev: amdgpu device pointer
+ *
+ * Remove the irq domain for GPU interrupt sources
+ * that may be driven by another driver (e.g., ACP).
+ */
+void amdgpu_irq_remove_domain(struct amdgpu_device *adev)
+{
+	if (adev->irq.domain) {
+		irq_domain_remove(adev->irq.domain);
+		adev->irq.domain = NULL;
+	}
+}
+
+/**
+ * amdgpu_irq_create_mapping - create a mapping between a domain irq and a
+ *                             Linux irq
+ *
+ * @adev: amdgpu device pointer
+ * @src_id: IH source id
+ *
+ * Create a mapping between a domain irq (GPU IH src id) and a Linux irq
+ * Use this for components that generate a GPU interrupt, but are driven
+ * by a different driver (e.g., ACP).
+ * Returns the Linux irq.
+ */
+unsigned amdgpu_irq_create_mapping(struct amdgpu_device *adev, unsigned src_id)
+{
+	adev->irq.virq[src_id] = irq_create_mapping(adev->irq.domain, src_id);
+
+	return adev->irq.virq[src_id];
+}
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.h
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.h
@@ -24,6 +24,7 @@
 #ifndef __AMDGPU_IRQ_H__
 #define __AMDGPU_IRQ_H__
 
+#include <linux/irqdomain.h>
 #include "amdgpu_ih.h"
 
 #define AMDGPU_MAX_IRQ_SRC_ID	0x100
@@ -65,6 +66,10 @@ struct amdgpu_irq {
 	/* interrupt ring */
 	struct amdgpu_ih_ring		ih;
 	const struct amdgpu_ih_funcs	*ih_funcs;
+
+	/* gen irq stuff */
+	struct irq_domain		*domain; /* GPU irq controller domain */
+	unsigned			virq[AMDGPU_MAX_IRQ_SRC_ID];
 };
 
 void amdgpu_irq_preinstall(struct drm_device *dev);
@@ -90,4 +95,8 @@ int amdgpu_irq_put(struct amdgpu_device
 bool amdgpu_irq_enabled(struct amdgpu_device *adev, struct amdgpu_irq_src *src,
 			unsigned type);
 
+int amdgpu_irq_add_domain(struct amdgpu_device *adev);
+void amdgpu_irq_remove_domain(struct amdgpu_device *adev);
+unsigned amdgpu_irq_create_mapping(struct amdgpu_device *adev, unsigned src_id);
+
 #endif
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
@@ -303,7 +303,7 @@ static int amdgpu_info_ioctl(struct drm_
 			fw_info.feature = adev->vce.fb_version;
 			break;
 		case AMDGPU_INFO_FW_UVD:
-			fw_info.ver = 0;
+			fw_info.ver = adev->uvd.fw_version;
 			fw_info.feature = 0;
 			break;
 		case AMDGPU_INFO_FW_GMC:
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c
@@ -142,7 +142,8 @@ static void amdgpu_mn_invalidate_range_s
 
 		list_for_each_entry(bo, &node->bos, mn_list) {
 
-			if (!bo->tbo.ttm || bo->tbo.ttm->state != tt_bound)
+			if (!amdgpu_ttm_tt_affect_userptr(bo->tbo.ttm, start,
+							  end))
 				continue;
 
 			r = amdgpu_bo_reserve(bo, true);
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
@@ -52,7 +52,7 @@ struct amdgpu_hpd;
 
 #define AMDGPU_MAX_HPD_PINS 6
 #define AMDGPU_MAX_CRTCS 6
-#define AMDGPU_MAX_AFMT_BLOCKS 7
+#define AMDGPU_MAX_AFMT_BLOCKS 9
 
 enum amdgpu_rmx_type {
 	RMX_OFF,
@@ -308,8 +308,8 @@ struct amdgpu_mode_info {
 	struct atom_context *atom_context;
 	struct card_info *atom_card_info;
 	bool mode_config_initialized;
-	struct amdgpu_crtc *crtcs[6];
-	struct amdgpu_afmt *afmt[7];
+	struct amdgpu_crtc *crtcs[AMDGPU_MAX_CRTCS];
+	struct amdgpu_afmt *afmt[AMDGPU_MAX_AFMT_BLOCKS];
 	/* DVI-I properties */
 	struct drm_property *coherent_mode_property;
 	/* DAC enable load detect */
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
@@ -33,6 +33,7 @@
 #include <linux/slab.h>
 #include <drm/drmP.h>
 #include <drm/amdgpu_drm.h>
+#include <drm/drm_cache.h>
 #include "amdgpu.h"
 #include "amdgpu_trace.h"
 
@@ -261,6 +262,13 @@ int amdgpu_bo_create_restricted(struct a
 				       AMDGPU_GEM_DOMAIN_OA);
 
 	bo->flags = flags;
+
+	/* For architectures that don't support WC memory,
+	 * mask out the WC flag from the BO
+	 */
+	if (!drm_arch_can_wc_memory())
+		bo->flags &= ~AMDGPU_GEM_CREATE_CPU_GTT_USWC;
+
 	amdgpu_fill_placement_to_bo(bo, placement);
 	/* Kernel allocation are uninterruptible */
 	r = ttm_bo_init(&adev->mman.bdev, &bo->tbo, size, type,
@@ -399,7 +407,8 @@ int amdgpu_bo_pin_restricted(struct amdg
 		}
 		if (fpfn > bo->placements[i].fpfn)
 			bo->placements[i].fpfn = fpfn;
-		if (lpfn && lpfn < bo->placements[i].lpfn)
+		if (!bo->placements[i].lpfn ||
+		    (lpfn && lpfn < bo->placements[i].lpfn))
 			bo->placements[i].lpfn = lpfn;
 		bo->placements[i].flags |= TTM_PL_FLAG_NO_EVICT;
 	}
@@ -531,6 +540,7 @@ int amdgpu_bo_set_metadata (struct amdgp
 	if (!metadata_size) {
 		if (bo->metadata_size) {
 			kfree(bo->metadata);
+			bo->metadata = NULL;
 			bo->metadata_size = 0;
 		}
 		return 0;
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h
@@ -96,6 +96,7 @@ static inline void amdgpu_bo_unreserve(s
  */
 static inline u64 amdgpu_bo_gpu_offset(struct amdgpu_bo *bo)
 {
+	WARN_ON_ONCE(bo->tbo.mem.mem_type == TTM_PL_SYSTEM);
 	return bo->tbo.offset;
 }
 
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
@@ -30,10 +30,16 @@
 #include <linux/hwmon.h>
 #include <linux/hwmon-sysfs.h>
 
+#include "amd_powerplay.h"
+
 static int amdgpu_debugfs_pm_init(struct amdgpu_device *adev);
 
 void amdgpu_pm_acpi_event_handler(struct amdgpu_device *adev)
 {
+	if (adev->pp_enabled)
+		/* TODO */
+		return;
+
 	if (adev->pm.dpm_enabled) {
 		mutex_lock(&adev->pm.mutex);
 		if (power_supply_is_system_supplied() > 0)
@@ -52,7 +58,12 @@ static ssize_t amdgpu_get_dpm_state(stru
 {
 	struct drm_device *ddev = dev_get_drvdata(dev);
 	struct amdgpu_device *adev = ddev->dev_private;
-	enum amdgpu_pm_state_type pm = adev->pm.dpm.user_state;
+	enum amd_pm_state_type pm;
+
+	if (adev->pp_enabled) {
+		pm = amdgpu_dpm_get_current_power_state(adev);
+	} else
+		pm = adev->pm.dpm.user_state;
 
 	return snprintf(buf, PAGE_SIZE, "%s\n",
 			(pm == POWER_STATE_TYPE_BATTERY) ? "battery" :
@@ -66,40 +77,57 @@ static ssize_t amdgpu_set_dpm_state(stru
 {
 	struct drm_device *ddev = dev_get_drvdata(dev);
 	struct amdgpu_device *adev = ddev->dev_private;
+	enum amd_pm_state_type  state;
 
-	mutex_lock(&adev->pm.mutex);
 	if (strncmp("battery", buf, strlen("battery")) == 0)
-		adev->pm.dpm.user_state = POWER_STATE_TYPE_BATTERY;
+		state = POWER_STATE_TYPE_BATTERY;
 	else if (strncmp("balanced", buf, strlen("balanced")) == 0)
-		adev->pm.dpm.user_state = POWER_STATE_TYPE_BALANCED;
+		state = POWER_STATE_TYPE_BALANCED;
 	else if (strncmp("performance", buf, strlen("performance")) == 0)
-		adev->pm.dpm.user_state = POWER_STATE_TYPE_PERFORMANCE;
+		state = POWER_STATE_TYPE_PERFORMANCE;
 	else {
-		mutex_unlock(&adev->pm.mutex);
 		count = -EINVAL;
 		goto fail;
 	}
-	mutex_unlock(&adev->pm.mutex);
 
-	/* Can't set dpm state when the card is off */
-	if (!(adev->flags & AMD_IS_PX) ||
-	    (ddev->switch_power_state == DRM_SWITCH_POWER_ON))
-		amdgpu_pm_compute_clocks(adev);
+	if (adev->pp_enabled) {
+		amdgpu_dpm_dispatch_task(adev, AMD_PP_EVENT_ENABLE_USER_STATE, &state, NULL);
+	} else {
+		mutex_lock(&adev->pm.mutex);
+		adev->pm.dpm.user_state = state;
+		mutex_unlock(&adev->pm.mutex);
+
+		/* Can't set dpm state when the card is off */
+		if (!(adev->flags & AMD_IS_PX) ||
+		    (ddev->switch_power_state == DRM_SWITCH_POWER_ON))
+			amdgpu_pm_compute_clocks(adev);
+	}
 fail:
 	return count;
 }
 
 static ssize_t amdgpu_get_dpm_forced_performance_level(struct device *dev,
-						       struct device_attribute *attr,
-						       char *buf)
+						struct device_attribute *attr,
+								char *buf)
 {
 	struct drm_device *ddev = dev_get_drvdata(dev);
 	struct amdgpu_device *adev = ddev->dev_private;
-	enum amdgpu_dpm_forced_level level = adev->pm.dpm.forced_level;
 
-	return snprintf(buf, PAGE_SIZE, "%s\n",
-			(level == AMDGPU_DPM_FORCED_LEVEL_AUTO) ? "auto" :
-			(level == AMDGPU_DPM_FORCED_LEVEL_LOW) ? "low" : "high");
+	if (adev->pp_enabled) {
+		enum amd_dpm_forced_level level;
+
+		level = amdgpu_dpm_get_performance_level(adev);
+		return snprintf(buf, PAGE_SIZE, "%s\n",
+				(level == AMD_DPM_FORCED_LEVEL_AUTO) ? "auto" :
+				(level == AMD_DPM_FORCED_LEVEL_LOW) ? "low" : "high");
+	} else {
+		enum amdgpu_dpm_forced_level level;
+
+		level = adev->pm.dpm.forced_level;
+		return snprintf(buf, PAGE_SIZE, "%s\n",
+				(level == AMDGPU_DPM_FORCED_LEVEL_AUTO) ? "auto" :
+				(level == AMDGPU_DPM_FORCED_LEVEL_LOW) ? "low" : "high");
+	}
 }
 
 static ssize_t amdgpu_set_dpm_forced_performance_level(struct device *dev,
@@ -112,7 +140,6 @@ static ssize_t amdgpu_set_dpm_forced_per
 	enum amdgpu_dpm_forced_level level;
 	int ret = 0;
 
-	mutex_lock(&adev->pm.mutex);
 	if (strncmp("low", buf, strlen("low")) == 0) {
 		level = AMDGPU_DPM_FORCED_LEVEL_LOW;
 	} else if (strncmp("high", buf, strlen("high")) == 0) {
@@ -123,7 +150,11 @@ static ssize_t amdgpu_set_dpm_forced_per
 		count = -EINVAL;
 		goto fail;
 	}
-	if (adev->pm.funcs->force_performance_level) {
+
+	if (adev->pp_enabled)
+		amdgpu_dpm_force_performance_level(adev, level);
+	else {
+		mutex_lock(&adev->pm.mutex);
 		if (adev->pm.dpm.thermal_active) {
 			count = -EINVAL;
 			goto fail;
@@ -131,6 +162,9 @@ static ssize_t amdgpu_set_dpm_forced_per
 		ret = amdgpu_dpm_force_performance_level(adev, level);
 		if (ret)
 			count = -EINVAL;
+		else
+			adev->pm.dpm.forced_level = level;
+		mutex_unlock(&adev->pm.mutex);
 	}
 fail:
 	mutex_unlock(&adev->pm.mutex);
@@ -150,10 +184,10 @@ static ssize_t amdgpu_hwmon_show_temp(st
 	struct amdgpu_device *adev = dev_get_drvdata(dev);
 	int temp;
 
-	if (adev->pm.funcs->get_temperature)
-		temp = amdgpu_dpm_get_temperature(adev);
-	else
+	if (!adev->pp_enabled && !adev->pm.funcs->get_temperature)
 		temp = 0;
+	else
+		temp = amdgpu_dpm_get_temperature(adev);
 
 	return snprintf(buf, PAGE_SIZE, "%d\n", temp);
 }
@@ -181,8 +215,10 @@ static ssize_t amdgpu_hwmon_get_pwm1_ena
 	struct amdgpu_device *adev = dev_get_drvdata(dev);
 	u32 pwm_mode = 0;
 
-	if (adev->pm.funcs->get_fan_control_mode)
-		pwm_mode = amdgpu_dpm_get_fan_control_mode(adev);
+	if (!adev->pp_enabled && !adev->pm.funcs->get_fan_control_mode)
+		return -EINVAL;
+
+	pwm_mode = amdgpu_dpm_get_fan_control_mode(adev);
 
 	/* never 0 (full-speed), fuse or smc-controlled always */
 	return sprintf(buf, "%i\n", pwm_mode == FDO_PWM_MODE_STATIC ? 1 : 2);
@@ -197,7 +233,7 @@ static ssize_t amdgpu_hwmon_set_pwm1_ena
 	int err;
 	int value;
 
-	if(!adev->pm.funcs->set_fan_control_mode)
+	if (!adev->pp_enabled && !adev->pm.funcs->set_fan_control_mode)
 		return -EINVAL;
 
 	err = kstrtoint(buf, 10, &value);
@@ -290,11 +326,11 @@ static struct attribute *hwmon_attribute
 static umode_t hwmon_attributes_visible(struct kobject *kobj,
 					struct attribute *attr, int index)
 {
-	struct device *dev = container_of(kobj, struct device, kobj);
+	struct device *dev = kobj_to_dev(kobj);
 	struct amdgpu_device *adev = dev_get_drvdata(dev);
 	umode_t effective_mode = attr->mode;
 
-	/* Skip attributes if DPM is not enabled */
+	/* Skip limit attributes if DPM is not enabled */
 	if (!adev->pm.dpm_enabled &&
 	    (attr == &sensor_dev_attr_temp1_crit.dev_attr.attr ||
 	     attr == &sensor_dev_attr_temp1_crit_hyst.dev_attr.attr ||
@@ -304,6 +340,9 @@ static umode_t hwmon_attributes_visible(
 	     attr == &sensor_dev_attr_pwm1_min.dev_attr.attr))
 		return 0;
 
+	if (adev->pp_enabled)
+		return effective_mode;
+
 	/* Skip fan attributes if fan is not present */
 	if (adev->pm.no_fan &&
 	    (attr == &sensor_dev_attr_pwm1.dev_attr.attr ||
@@ -351,7 +390,7 @@ void amdgpu_dpm_thermal_work_handler(str
 		container_of(work, struct amdgpu_device,
 			     pm.dpm.thermal.work);
 	/* switch to the thermal state */
-	enum amdgpu_pm_state_type dpm_state = POWER_STATE_TYPE_INTERNAL_THERMAL;
+	enum amd_pm_state_type dpm_state = POWER_STATE_TYPE_INTERNAL_THERMAL;
 
 	if (!adev->pm.dpm_enabled)
 		return;
@@ -379,7 +418,7 @@ void amdgpu_dpm_thermal_work_handler(str
 }
 
 static struct amdgpu_ps *amdgpu_dpm_pick_power_state(struct amdgpu_device *adev,
-						     enum amdgpu_pm_state_type dpm_state)
+						     enum amd_pm_state_type dpm_state)
 {
 	int i;
 	struct amdgpu_ps *ps;
@@ -516,7 +555,7 @@ static void amdgpu_dpm_change_power_stat
 {
 	int i;
 	struct amdgpu_ps *ps;
-	enum amdgpu_pm_state_type dpm_state;
+	enum amd_pm_state_type dpm_state;
 	int ret;
 
 	/* if dpm init failed */
@@ -595,11 +634,6 @@ force:
 
 	/* update display watermarks based on new power state */
 	amdgpu_display_bandwidth_update(adev);
-	/* update displays */
-	amdgpu_dpm_display_configuration_changed(adev);
-
-	adev->pm.dpm.current_active_crtcs = adev->pm.dpm.new_active_crtcs;
-	adev->pm.dpm.current_active_crtc_count = adev->pm.dpm.new_active_crtc_count;
 
 	/* wait for the rings to drain */
 	for (i = 0; i < AMDGPU_MAX_RINGS; i++) {
@@ -616,6 +650,12 @@ force:
 
 	amdgpu_dpm_post_set_power_state(adev);
 
+	/* update displays */
+	amdgpu_dpm_display_configuration_changed(adev);
+
+	adev->pm.dpm.current_active_crtcs = adev->pm.dpm.new_active_crtcs;
+	adev->pm.dpm.current_active_crtc_count = adev->pm.dpm.new_active_crtc_count;
+
 	if (adev->pm.funcs->force_performance_level) {
 		if (adev->pm.dpm.thermal_active) {
 			enum amdgpu_dpm_forced_level level = adev->pm.dpm.forced_level;
@@ -635,49 +675,54 @@ done:
 
 void amdgpu_dpm_enable_uvd(struct amdgpu_device *adev, bool enable)
 {
-	if (adev->pm.funcs->powergate_uvd) {
-		mutex_lock(&adev->pm.mutex);
-		/* enable/disable UVD */
+	if (adev->pp_enabled)
 		amdgpu_dpm_powergate_uvd(adev, !enable);
-		mutex_unlock(&adev->pm.mutex);
-	} else {
-		if (enable) {
+	else {
+		if (adev->pm.funcs->powergate_uvd) {
 			mutex_lock(&adev->pm.mutex);
-			adev->pm.dpm.uvd_active = true;
-			adev->pm.dpm.state = POWER_STATE_TYPE_INTERNAL_UVD;
+			/* enable/disable UVD */
+			amdgpu_dpm_powergate_uvd(adev, !enable);
 			mutex_unlock(&adev->pm.mutex);
 		} else {
-			mutex_lock(&adev->pm.mutex);
-			adev->pm.dpm.uvd_active = false;
-			mutex_unlock(&adev->pm.mutex);
+			if (enable) {
+				mutex_lock(&adev->pm.mutex);
+				adev->pm.dpm.uvd_active = true;
+				adev->pm.dpm.state = POWER_STATE_TYPE_INTERNAL_UVD;
+				mutex_unlock(&adev->pm.mutex);
+			} else {
+				mutex_lock(&adev->pm.mutex);
+				adev->pm.dpm.uvd_active = false;
+				mutex_unlock(&adev->pm.mutex);
+			}
+			amdgpu_pm_compute_clocks(adev);
 		}
 
-		amdgpu_pm_compute_clocks(adev);
 	}
 }
 
 void amdgpu_dpm_enable_vce(struct amdgpu_device *adev, bool enable)
 {
-	if (adev->pm.funcs->powergate_vce) {
-		mutex_lock(&adev->pm.mutex);
-		/* enable/disable VCE */
+	if (adev->pp_enabled)
 		amdgpu_dpm_powergate_vce(adev, !enable);
-
-		mutex_unlock(&adev->pm.mutex);
-	} else {
-		if (enable) {
+	else {
+		if (adev->pm.funcs->powergate_vce) {
 			mutex_lock(&adev->pm.mutex);
-			adev->pm.dpm.vce_active = true;
-			/* XXX select vce level based on ring/task */
-			adev->pm.dpm.vce_level = AMDGPU_VCE_LEVEL_AC_ALL;
+			amdgpu_dpm_powergate_vce(adev, !enable);
 			mutex_unlock(&adev->pm.mutex);
 		} else {
-			mutex_lock(&adev->pm.mutex);
-			adev->pm.dpm.vce_active = false;
-			mutex_unlock(&adev->pm.mutex);
+			if (enable) {
+				mutex_lock(&adev->pm.mutex);
+				adev->pm.dpm.vce_active = true;
+				/* XXX select vce level based on ring/task */
+				adev->pm.dpm.vce_level = AMDGPU_VCE_LEVEL_AC_ALL;
+				mutex_unlock(&adev->pm.mutex);
+			} else {
+				mutex_lock(&adev->pm.mutex);
+				adev->pm.dpm.vce_active = false;
+				mutex_unlock(&adev->pm.mutex);
+			}
+			amdgpu_pm_compute_clocks(adev);
 		}
-
-		amdgpu_pm_compute_clocks(adev);
 	}
 }
 
@@ -685,10 +730,13 @@ void amdgpu_pm_print_power_states(struct
 {
 	int i;
 
-	for (i = 0; i < adev->pm.dpm.num_ps; i++) {
-		printk("== power state %d ==\n", i);
+	if (adev->pp_enabled)
+		/* TO DO */
+		return;
+
+	for (i = 0; i < adev->pm.dpm.num_ps; i++)
 		amdgpu_dpm_print_power_state(adev, &adev->pm.dpm.ps[i]);
-	}
+
 }
 
 int amdgpu_pm_sysfs_init(struct amdgpu_device *adev)
@@ -698,8 +746,11 @@ int amdgpu_pm_sysfs_init(struct amdgpu_d
 	if (adev->pm.sysfs_initialized)
 		return 0;
 
-	if (adev->pm.funcs->get_temperature == NULL)
-		return 0;
+	if (!adev->pp_enabled) {
+		if (adev->pm.funcs->get_temperature == NULL)
+			return 0;
+	}
+
 	adev->pm.int_hwmon_dev = hwmon_device_register_with_groups(adev->dev,
 								   DRIVER_NAME, adev,
 								   hwmon_groups);
@@ -748,32 +799,43 @@ void amdgpu_pm_compute_clocks(struct amd
 	if (!adev->pm.dpm_enabled)
 		return;
 
-	mutex_lock(&adev->pm.mutex);
+	if (adev->pp_enabled) {
+		int i = 0;
 
-	/* update active crtc counts */
-	adev->pm.dpm.new_active_crtcs = 0;
-	adev->pm.dpm.new_active_crtc_count = 0;
-	if (adev->mode_info.num_crtc && adev->mode_info.mode_config_initialized) {
-		list_for_each_entry(crtc,
-				    &ddev->mode_config.crtc_list, head) {
-			amdgpu_crtc = to_amdgpu_crtc(crtc);
-			if (crtc->enabled) {
-				adev->pm.dpm.new_active_crtcs |= (1 << amdgpu_crtc->crtc_id);
-				adev->pm.dpm.new_active_crtc_count++;
+		amdgpu_display_bandwidth_update(adev);
+		mutex_lock(&adev->ring_lock);
+			for (i = 0; i < AMDGPU_MAX_RINGS; i++) {
+				struct amdgpu_ring *ring = adev->rings[i];
+				if (ring && ring->ready)
+					amdgpu_fence_wait_empty(ring);
 			}
-		}
-	}
+		mutex_unlock(&adev->ring_lock);
 
-	/* update battery/ac status */
-	if (power_supply_is_system_supplied() > 0)
-		adev->pm.dpm.ac_power = true;
-	else
-		adev->pm.dpm.ac_power = false;
-
-	amdgpu_dpm_change_power_state_locked(adev);
+		amdgpu_dpm_dispatch_task(adev, AMD_PP_EVENT_DISPLAY_CONFIG_CHANGE, NULL, NULL);
+	} else {
+		mutex_lock(&adev->pm.mutex);
+		adev->pm.dpm.new_active_crtcs = 0;
+		adev->pm.dpm.new_active_crtc_count = 0;
+		if (adev->mode_info.num_crtc && adev->mode_info.mode_config_initialized) {
+			list_for_each_entry(crtc,
+					    &ddev->mode_config.crtc_list, head) {
+				amdgpu_crtc = to_amdgpu_crtc(crtc);
+				if (crtc->enabled) {
+					adev->pm.dpm.new_active_crtcs |= (1 << amdgpu_crtc->crtc_id);
+					adev->pm.dpm.new_active_crtc_count++;
+				}
+			}
+		}
+		/* update battery/ac status */
+		if (power_supply_is_system_supplied() > 0)
+			adev->pm.dpm.ac_power = true;
+		else
+			adev->pm.dpm.ac_power = false;
 
-	mutex_unlock(&adev->pm.mutex);
+		amdgpu_dpm_change_power_state_locked(adev);
 
+		mutex_unlock(&adev->pm.mutex);
+	}
 }
 
 /*
@@ -787,7 +849,13 @@ static int amdgpu_debugfs_pm_info(struct
 	struct drm_device *dev = node->minor->dev;
 	struct amdgpu_device *adev = dev->dev_private;
 
-	if (adev->pm.dpm_enabled) {
+	if (!adev->pm.dpm_enabled) {
+		seq_printf(m, "dpm not enabled\n");
+		return 0;
+	}
+	if (adev->pp_enabled) {
+		amdgpu_dpm_debugfs_print_current_performance_level(adev, m);
+	} else {
 		mutex_lock(&adev->pm.mutex);
 		if (adev->pm.funcs->debugfs_print_current_performance_level)
 			amdgpu_dpm_debugfs_print_current_performance_level(adev, m);
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/amdgpu/amdgpu_powerplay.c
@@ -0,0 +1,328 @@
+/*
+ * Copyright 2015 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+#include "atom.h"
+#include "amdgpu.h"
+#include "amd_shared.h"
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include "amdgpu_pm.h"
+#include <drm/amdgpu_drm.h>
+#include "amdgpu_powerplay.h"
+#include "cik_dpm.h"
+#include "vi_dpm.h"
+
+static int amdgpu_powerplay_init(struct amdgpu_device *adev)
+{
+	int ret = 0;
+	struct amd_powerplay *amd_pp;
+
+	amd_pp = &(adev->powerplay);
+
+	if (adev->pp_enabled) {
+#ifdef CONFIG_DRM_AMD_POWERPLAY
+		struct amd_pp_init *pp_init;
+
+		pp_init = kzalloc(sizeof(struct amd_pp_init), GFP_KERNEL);
+
+		if (pp_init == NULL)
+			return -ENOMEM;
+
+		pp_init->chip_family = adev->family;
+		pp_init->chip_id = adev->asic_type;
+		pp_init->device = amdgpu_cgs_create_device(adev);
+
+		ret = amd_powerplay_init(pp_init, amd_pp);
+		kfree(pp_init);
+#endif
+	} else {
+		amd_pp->pp_handle = (void *)adev;
+
+		switch (adev->asic_type) {
+#ifdef CONFIG_DRM_AMDGPU_CIK
+		case CHIP_BONAIRE:
+		case CHIP_HAWAII:
+			amd_pp->ip_funcs = &ci_dpm_ip_funcs;
+			break;
+		case CHIP_KABINI:
+		case CHIP_MULLINS:
+		case CHIP_KAVERI:
+			amd_pp->ip_funcs = &kv_dpm_ip_funcs;
+			break;
+#endif
+		case CHIP_TOPAZ:
+			amd_pp->ip_funcs = &iceland_dpm_ip_funcs;
+			break;
+		case CHIP_TONGA:
+			amd_pp->ip_funcs = &tonga_dpm_ip_funcs;
+			break;
+		case CHIP_FIJI:
+			amd_pp->ip_funcs = &fiji_dpm_ip_funcs;
+			break;
+		case CHIP_CARRIZO:
+		case CHIP_STONEY:
+			amd_pp->ip_funcs = &cz_dpm_ip_funcs;
+			break;
+		default:
+			ret = -EINVAL;
+			break;
+		}
+	}
+	return ret;
+}
+
+static int amdgpu_pp_early_init(void *handle)
+{
+	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
+	int ret = 0;
+
+#ifdef CONFIG_DRM_AMD_POWERPLAY
+	switch (adev->asic_type) {
+	case CHIP_TONGA:
+	case CHIP_FIJI:
+		adev->pp_enabled = (amdgpu_powerplay == 0) ? false : true;
+		break;
+	case CHIP_CARRIZO:
+	case CHIP_STONEY:
+		adev->pp_enabled = (amdgpu_powerplay > 0) ? true : false;
+		break;
+	/* These chips don't have powerplay implemenations */
+	case CHIP_BONAIRE:
+	case CHIP_HAWAII:
+	case CHIP_KABINI:
+	case CHIP_MULLINS:
+	case CHIP_KAVERI:
+	case CHIP_TOPAZ:
+	default:
+		adev->pp_enabled = false;
+		break;
+	}
+#else
+	adev->pp_enabled = false;
+#endif
+
+	ret = amdgpu_powerplay_init(adev);
+	if (ret)
+		return ret;
+
+	if (adev->powerplay.ip_funcs->early_init)
+		ret = adev->powerplay.ip_funcs->early_init(
+					adev->powerplay.pp_handle);
+	return ret;
+}
+
+
+static int amdgpu_pp_late_init(void *handle)
+{
+	int ret = 0;
+	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
+
+	if (adev->powerplay.ip_funcs->late_init)
+		ret = adev->powerplay.ip_funcs->late_init(
+					adev->powerplay.pp_handle);
+
+#ifdef CONFIG_DRM_AMD_POWERPLAY
+	if (adev->pp_enabled)
+		amdgpu_pm_sysfs_init(adev);
+#endif
+	return ret;
+}
+
+static int amdgpu_pp_sw_init(void *handle)
+{
+	int ret = 0;
+	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
+
+	if (adev->powerplay.ip_funcs->sw_init)
+		ret = adev->powerplay.ip_funcs->sw_init(
+					adev->powerplay.pp_handle);
+
+#ifdef CONFIG_DRM_AMD_POWERPLAY
+	if (adev->pp_enabled) {
+		if (amdgpu_dpm == 0)
+			adev->pm.dpm_enabled = false;
+		else
+			adev->pm.dpm_enabled = true;
+	}
+#endif
+
+	return ret;
+}
+
+static int amdgpu_pp_sw_fini(void *handle)
+{
+	int ret = 0;
+	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
+
+	if (adev->powerplay.ip_funcs->sw_fini)
+		ret = adev->powerplay.ip_funcs->sw_fini(
+					adev->powerplay.pp_handle);
+	if (ret)
+		return ret;
+
+#ifdef CONFIG_DRM_AMD_POWERPLAY
+	if (adev->pp_enabled) {
+		amdgpu_pm_sysfs_fini(adev);
+		amd_powerplay_fini(adev->powerplay.pp_handle);
+	}
+#endif
+
+	return ret;
+}
+
+static int amdgpu_pp_hw_init(void *handle)
+{
+	int ret = 0;
+	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
+
+	if (adev->pp_enabled && adev->firmware.smu_load)
+		amdgpu_ucode_init_bo(adev);
+
+	if (adev->powerplay.ip_funcs->hw_init)
+		ret = adev->powerplay.ip_funcs->hw_init(
+					adev->powerplay.pp_handle);
+
+	return ret;
+}
+
+static int amdgpu_pp_hw_fini(void *handle)
+{
+	int ret = 0;
+	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
+
+	if (adev->powerplay.ip_funcs->hw_fini)
+		ret = adev->powerplay.ip_funcs->hw_fini(
+					adev->powerplay.pp_handle);
+
+	if (adev->pp_enabled && adev->firmware.smu_load)
+		amdgpu_ucode_fini_bo(adev);
+
+	return ret;
+}
+
+static int amdgpu_pp_suspend(void *handle)
+{
+	int ret = 0;
+	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
+
+	if (adev->powerplay.ip_funcs->suspend)
+		ret = adev->powerplay.ip_funcs->suspend(
+					 adev->powerplay.pp_handle);
+	return ret;
+}
+
+static int amdgpu_pp_resume(void *handle)
+{
+	int ret = 0;
+	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
+
+	if (adev->powerplay.ip_funcs->resume)
+		ret = adev->powerplay.ip_funcs->resume(
+					adev->powerplay.pp_handle);
+	return ret;
+}
+
+static int amdgpu_pp_set_clockgating_state(void *handle,
+					enum amd_clockgating_state state)
+{
+	int ret = 0;
+	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
+
+	if (adev->powerplay.ip_funcs->set_clockgating_state)
+		ret = adev->powerplay.ip_funcs->set_clockgating_state(
+				adev->powerplay.pp_handle, state);
+	return ret;
+}
+
+static int amdgpu_pp_set_powergating_state(void *handle,
+					enum amd_powergating_state state)
+{
+	int ret = 0;
+	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
+
+	if (adev->powerplay.ip_funcs->set_powergating_state)
+		ret = adev->powerplay.ip_funcs->set_powergating_state(
+				 adev->powerplay.pp_handle, state);
+	return ret;
+}
+
+
+static bool amdgpu_pp_is_idle(void *handle)
+{
+	bool ret = true;
+	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
+
+	if (adev->powerplay.ip_funcs->is_idle)
+		ret = adev->powerplay.ip_funcs->is_idle(
+					adev->powerplay.pp_handle);
+	return ret;
+}
+
+static int amdgpu_pp_wait_for_idle(void *handle)
+{
+	int ret = 0;
+	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
+
+	if (adev->powerplay.ip_funcs->wait_for_idle)
+		ret = adev->powerplay.ip_funcs->wait_for_idle(
+					adev->powerplay.pp_handle);
+	return ret;
+}
+
+static int amdgpu_pp_soft_reset(void *handle)
+{
+	int ret = 0;
+	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
+
+	if (adev->powerplay.ip_funcs->soft_reset)
+		ret = adev->powerplay.ip_funcs->soft_reset(
+					adev->powerplay.pp_handle);
+	return ret;
+}
+
+static void amdgpu_pp_print_status(void *handle)
+{
+	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
+
+	if (adev->powerplay.ip_funcs->print_status)
+		adev->powerplay.ip_funcs->print_status(
+					adev->powerplay.pp_handle);
+}
+
+const struct amd_ip_funcs amdgpu_pp_ip_funcs = {
+	.early_init = amdgpu_pp_early_init,
+	.late_init = amdgpu_pp_late_init,
+	.sw_init = amdgpu_pp_sw_init,
+	.sw_fini = amdgpu_pp_sw_fini,
+	.hw_init = amdgpu_pp_hw_init,
+	.hw_fini = amdgpu_pp_hw_fini,
+	.suspend = amdgpu_pp_suspend,
+	.resume = amdgpu_pp_resume,
+	.is_idle = amdgpu_pp_is_idle,
+	.wait_for_idle = amdgpu_pp_wait_for_idle,
+	.soft_reset = amdgpu_pp_soft_reset,
+	.print_status = amdgpu_pp_print_status,
+	.set_clockgating_state = amdgpu_pp_set_clockgating_state,
+	.set_powergating_state = amdgpu_pp_set_powergating_state,
+};
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/amdgpu/amdgpu_powerplay.h
@@ -0,0 +1,33 @@
+/*
+ *  Copyright 2015 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+
+#ifndef __AMDGPU_POPWERPLAY_H__
+#define __AMDGPU_POPWERPLAY_H__
+
+#include "amd_shared.h"
+
+extern const struct amd_ip_funcs amdgpu_pp_ip_funcs;
+
+#endif /* __AMDSOC_DM_H__ */
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c
@@ -487,7 +487,7 @@ static int amdgpu_debugfs_ring_info(stru
 	seq_printf(m, "rptr: 0x%08x [%5d]\n",
 		   rptr, rptr);
 
-	rptr_next = ~0;
+	rptr_next = le32_to_cpu(*ring->next_rptr_cpu_addr);
 
 	seq_printf(m, "driver's copy of the wptr: 0x%08x [%5d]\n",
 		   ring->wptr, ring->wptr);
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_sa.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/amdgpu/amdgpu_sa.c
@@ -354,12 +354,15 @@ int amdgpu_sa_bo_new(struct amdgpu_sa_ma
 
 		for (i = 0, count = 0; i < AMDGPU_MAX_RINGS; ++i)
 			if (fences[i])
-				fences[count++] = fences[i];
+				fences[count++] = fence_get(fences[i]);
 
 		if (count) {
 			spin_unlock(&sa_manager->wq.lock);
 			t = fence_wait_any_timeout(fences, count, false,
 						   MAX_SCHEDULE_TIMEOUT);
+			for (i = 0; i < count; ++i)
+				fence_put(fences[i]);
+
 			r = (t > 0) ? 0 : t;
 			spin_lock(&sa_manager->wq.lock);
 		} else {
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c
@@ -293,7 +293,8 @@ int amdgpu_sync_rings(struct amdgpu_sync
 		fence = to_amdgpu_fence(sync->sync_to[i]);
 
 		/* check if we really need to sync */
-		if (!amdgpu_fence_need_sync(fence, ring))
+		if (!amdgpu_enable_scheduler &&
+		    !amdgpu_fence_need_sync(fence, ring))
 			continue;
 
 		/* prevent GPU deadlocks */
@@ -303,7 +304,7 @@ int amdgpu_sync_rings(struct amdgpu_sync
 		}
 
 		if (amdgpu_enable_scheduler || !amdgpu_enable_semaphores) {
-			r = fence_wait(&fence->base, true);
+			r = fence_wait(sync->sync_to[i], true);
 			if (r)
 				return r;
 			continue;
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
@@ -233,8 +233,8 @@ static int amdgpu_move_blit(struct ttm_b
 
 	adev = amdgpu_get_adev(bo->bdev);
 	ring = adev->mman.buffer_funcs_ring;
-	old_start = old_mem->start << PAGE_SHIFT;
-	new_start = new_mem->start << PAGE_SHIFT;
+	old_start = (u64)old_mem->start << PAGE_SHIFT;
+	new_start = (u64)new_mem->start << PAGE_SHIFT;
 
 	switch (old_mem->mem_type) {
 	case TTM_PL_VRAM:
@@ -712,7 +712,7 @@ static int amdgpu_ttm_tt_populate(struct
 						       0, PAGE_SIZE,
 						       PCI_DMA_BIDIRECTIONAL);
 		if (pci_dma_mapping_error(adev->pdev, gtt->ttm.dma_address[i])) {
-			while (--i) {
+			while (i--) {
 				pci_unmap_page(adev->pdev, gtt->ttm.dma_address[i],
 					       PAGE_SIZE, PCI_DMA_BIDIRECTIONAL);
 				gtt->ttm.dma_address[i] = 0;
@@ -783,6 +783,25 @@ bool amdgpu_ttm_tt_has_userptr(struct tt
 	return !!gtt->userptr;
 }
 
+bool amdgpu_ttm_tt_affect_userptr(struct ttm_tt *ttm, unsigned long start,
+				  unsigned long end)
+{
+	struct amdgpu_ttm_tt *gtt = (void *)ttm;
+	unsigned long size;
+
+	if (gtt == NULL)
+		return false;
+
+	if (gtt->ttm.ttm.state != tt_bound || !gtt->userptr)
+		return false;
+
+	size = (unsigned long)gtt->ttm.ttm.num_pages * PAGE_SIZE;
+	if (gtt->userptr > end || gtt->userptr + size <= start)
+		return false;
+
+	return true;
+}
+
 bool amdgpu_ttm_tt_is_readonly(struct ttm_tt *ttm)
 {
 	struct amdgpu_ttm_tt *gtt = (void *)ttm;
@@ -808,7 +827,7 @@ uint32_t amdgpu_ttm_tt_pte_flags(struct
 			flags |= AMDGPU_PTE_SNOOPED;
 	}
 
-	if (adev->asic_type >= CHIP_TOPAZ)
+	if (adev->asic_type >= CHIP_TONGA)
 		flags |= AMDGPU_PTE_EXECUTABLE;
 
 	flags |= AMDGPU_PTE_READABLE;
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c
@@ -156,6 +156,9 @@ int amdgpu_uvd_sw_init(struct amdgpu_dev
 	DRM_INFO("Found UVD firmware Version: %hu.%hu Family ID: %hu\n",
 		version_major, version_minor, family_id);
 
+	adev->uvd.fw_version = ((version_major << 24) | (version_minor << 16) |
+				(family_id << 8));
+
 	bo_size = AMDGPU_GPU_PAGE_ALIGN(le32_to_cpu(hdr->ucode_size_bytes) + 8)
 		 +  AMDGPU_UVD_STACK_SIZE + AMDGPU_UVD_HEAP_SIZE;
 	r = amdgpu_bo_create(adev, bo_size, PAGE_SIZE, true,
@@ -273,6 +276,8 @@ int amdgpu_uvd_resume(struct amdgpu_devi
 	memcpy(adev->uvd.cpu_addr, (adev->uvd.fw->data) + offset,
 		(adev->uvd.fw->size) - offset);
 
+	cancel_delayed_work_sync(&adev->uvd.idle_work);
+
 	size = amdgpu_bo_size(adev->uvd.vcpu_bo);
 	size -= le32_to_cpu(hdr->ucode_size_bytes);
 	ptr = adev->uvd.cpu_addr;
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c
@@ -220,6 +220,7 @@ int amdgpu_vce_suspend(struct amdgpu_dev
 	if (i == AMDGPU_MAX_VCE_HANDLES)
 		return 0;
 
+	cancel_delayed_work_sync(&adev->vce.idle_work);
 	/* TODO: suspending running encoding sessions isn't supported */
 	return -EINVAL;
 }
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
@@ -75,50 +75,77 @@ static unsigned amdgpu_vm_directory_size
 }
 
 /**
- * amdgpu_vm_get_bos - add the vm BOs to a validation list
+ * amdgpu_vm_get_pd_bo - add the VM PD to a validation list
  *
  * @vm: vm providing the BOs
- * @head: head of validation list
+ * @validated: head of validation list
+ * @entry: entry to add
  *
  * Add the page directory to the list of BOs to
- * validate for command submission (cayman+).
+ * validate for command submission.
  */
-struct amdgpu_bo_list_entry *amdgpu_vm_get_bos(struct amdgpu_device *adev,
-					  struct amdgpu_vm *vm,
-					  struct list_head *head)
-{
-	struct amdgpu_bo_list_entry *list;
-	unsigned i, idx;
-
-	list = drm_malloc_ab(vm->max_pde_used + 2,
-			     sizeof(struct amdgpu_bo_list_entry));
-	if (!list) {
-		return NULL;
-	}
+void amdgpu_vm_get_pd_bo(struct amdgpu_vm *vm,
+			 struct list_head *validated,
+			 struct amdgpu_bo_list_entry *entry)
+{
+	entry->robj = vm->page_directory;
+	entry->prefered_domains = AMDGPU_GEM_DOMAIN_VRAM;
+	entry->allowed_domains = AMDGPU_GEM_DOMAIN_VRAM;
+	entry->priority = 0;
+	entry->tv.bo = &vm->page_directory->tbo;
+	entry->tv.shared = true;
+	list_add(&entry->tv.head, validated);
+}
+
+/**
+ * amdgpu_vm_get_bos - add the vm BOs to a duplicates list
+ *
+ * @vm: vm providing the BOs
+ * @duplicates: head of duplicates list
+ *
+ * Add the page directory to the BO duplicates list
+ * for command submission.
+ */
+void amdgpu_vm_get_pt_bos(struct amdgpu_vm *vm, struct list_head *duplicates)
+{
+	unsigned i;
 
 	/* add the vm page table to the list */
-	list[0].robj = vm->page_directory;
-	list[0].prefered_domains = AMDGPU_GEM_DOMAIN_VRAM;
-	list[0].allowed_domains = AMDGPU_GEM_DOMAIN_VRAM;
-	list[0].priority = 0;
-	list[0].tv.bo = &vm->page_directory->tbo;
-	list[0].tv.shared = true;
-	list_add(&list[0].tv.head, head);
+	for (i = 0; i <= vm->max_pde_used; ++i) {
+		struct amdgpu_bo_list_entry *entry = &vm->page_tables[i].entry;
 
-	for (i = 0, idx = 1; i <= vm->max_pde_used; i++) {
-		if (!vm->page_tables[i].bo)
+		if (!entry->robj)
 			continue;
 
-		list[idx].robj = vm->page_tables[i].bo;
-		list[idx].prefered_domains = AMDGPU_GEM_DOMAIN_VRAM;
-		list[idx].allowed_domains = AMDGPU_GEM_DOMAIN_VRAM;
-		list[idx].priority = 0;
-		list[idx].tv.bo = &list[idx].robj->tbo;
-		list[idx].tv.shared = true;
-		list_add(&list[idx++].tv.head, head);
+		list_add(&entry->tv.head, duplicates);
 	}
 
-	return list;
+}
+
+/**
+ * amdgpu_vm_move_pt_bos_in_lru - move the PT BOs to the LRU tail
+ *
+ * @adev: amdgpu device instance
+ * @vm: vm providing the BOs
+ *
+ * Move the PT BOs to the tail of the LRU.
+ */
+void amdgpu_vm_move_pt_bos_in_lru(struct amdgpu_device *adev,
+				  struct amdgpu_vm *vm)
+{
+	struct ttm_bo_global *glob = adev->mman.bdev.glob;
+	unsigned i;
+
+	spin_lock(&glob->lru_lock);
+	for (i = 0; i <= vm->max_pde_used; ++i) {
+		struct amdgpu_bo_list_entry *entry = &vm->page_tables[i].entry;
+
+		if (!entry->robj)
+			continue;
+
+		ttm_bo_move_to_lru_tail(&entry->robj->tbo);
+	}
+	spin_unlock(&glob->lru_lock);
 }
 
 /**
@@ -461,7 +488,7 @@ int amdgpu_vm_update_page_directory(stru
 
 	/* walk over the address space and update the page directory */
 	for (pt_idx = 0; pt_idx <= vm->max_pde_used; ++pt_idx) {
-		struct amdgpu_bo *bo = vm->page_tables[pt_idx].bo;
+		struct amdgpu_bo *bo = vm->page_tables[pt_idx].entry.robj;
 		uint64_t pde, pt;
 
 		if (bo == NULL)
@@ -638,7 +665,7 @@ static int amdgpu_vm_update_ptes(struct
 	/* walk over the address space and update the page tables */
 	for (addr = start; addr < end; ) {
 		uint64_t pt_idx = addr >> amdgpu_vm_block_size;
-		struct amdgpu_bo *pt = vm->page_tables[pt_idx].bo;
+		struct amdgpu_bo *pt = vm->page_tables[pt_idx].entry.robj;
 		unsigned nptes;
 		uint64_t pte;
 		int r;
@@ -1010,13 +1037,13 @@ int amdgpu_vm_bo_map(struct amdgpu_devic
 		return -EINVAL;
 
 	/* make sure object fit at this offset */
-	eaddr = saddr + size;
+	eaddr = saddr + size - 1;
 	if ((saddr >= eaddr) || (offset + size > amdgpu_bo_size(bo_va->bo)))
 		return -EINVAL;
 
 	last_pfn = eaddr / AMDGPU_GPU_PAGE_SIZE;
-	if (last_pfn > adev->vm_manager.max_pfn) {
-		dev_err(adev->dev, "va above limit (0x%08X > 0x%08X)\n",
+	if (last_pfn >= adev->vm_manager.max_pfn) {
+		dev_err(adev->dev, "va above limit (0x%08X >= 0x%08X)\n",
 			last_pfn, adev->vm_manager.max_pfn);
 		return -EINVAL;
 	}
@@ -1025,7 +1052,7 @@ int amdgpu_vm_bo_map(struct amdgpu_devic
 	eaddr /= AMDGPU_GPU_PAGE_SIZE;
 
 	spin_lock(&vm->it_lock);
-	it = interval_tree_iter_first(&vm->va, saddr, eaddr - 1);
+	it = interval_tree_iter_first(&vm->va, saddr, eaddr);
 	spin_unlock(&vm->it_lock);
 	if (it) {
 		struct amdgpu_bo_va_mapping *tmp;
@@ -1046,7 +1073,7 @@ int amdgpu_vm_bo_map(struct amdgpu_devic
 
 	INIT_LIST_HEAD(&mapping->list);
 	mapping->it.start = saddr;
-	mapping->it.last = eaddr - 1;
+	mapping->it.last = eaddr;
 	mapping->offset = offset;
 	mapping->flags = flags;
 
@@ -1070,9 +1097,11 @@ int amdgpu_vm_bo_map(struct amdgpu_devic
 	/* walk over the address space and allocate the page tables */
 	for (pt_idx = saddr; pt_idx <= eaddr; ++pt_idx) {
 		struct reservation_object *resv = vm->page_directory->tbo.resv;
+		struct amdgpu_bo_list_entry *entry;
 		struct amdgpu_bo *pt;
 
-		if (vm->page_tables[pt_idx].bo)
+		entry = &vm->page_tables[pt_idx].entry;
+		if (entry->robj)
 			continue;
 
 		r = amdgpu_bo_create(adev, AMDGPU_VM_PTE_COUNT * 8,
@@ -1094,8 +1123,13 @@ int amdgpu_vm_bo_map(struct amdgpu_devic
 			goto error_free;
 		}
 
+		entry->robj = pt;
+		entry->prefered_domains = AMDGPU_GEM_DOMAIN_VRAM;
+		entry->allowed_domains = AMDGPU_GEM_DOMAIN_VRAM;
+		entry->priority = 0;
+		entry->tv.bo = &entry->robj->tbo;
+		entry->tv.shared = true;
 		vm->page_tables[pt_idx].addr = 0;
-		vm->page_tables[pt_idx].bo = pt;
 	}
 
 	return 0;
@@ -1248,7 +1282,7 @@ int amdgpu_vm_init(struct amdgpu_device
 {
 	const unsigned align = min(AMDGPU_VM_PTB_ALIGN_SIZE,
 		AMDGPU_VM_PTE_COUNT * 8);
-	unsigned pd_size, pd_entries, pts_size;
+	unsigned pd_size, pd_entries;
 	int i, r;
 
 	for (i = 0; i < AMDGPU_MAX_RINGS; ++i) {
@@ -1266,8 +1300,7 @@ int amdgpu_vm_init(struct amdgpu_device
 	pd_entries = amdgpu_vm_num_pdes(adev);
 
 	/* allocate page table array */
-	pts_size = pd_entries * sizeof(struct amdgpu_vm_pt);
-	vm->page_tables = kzalloc(pts_size, GFP_KERNEL);
+	vm->page_tables = drm_calloc_large(pd_entries, sizeof(struct amdgpu_vm_pt));
 	if (vm->page_tables == NULL) {
 		DRM_ERROR("Cannot allocate memory for page table array\n");
 		return -ENOMEM;
@@ -1326,8 +1359,8 @@ void amdgpu_vm_fini(struct amdgpu_device
 	}
 
 	for (i = 0; i < amdgpu_vm_num_pdes(adev); i++)
-		amdgpu_bo_unref(&vm->page_tables[i].bo);
-	kfree(vm->page_tables);
+		amdgpu_bo_unref(&vm->page_tables[i].entry.robj);
+	drm_free_large(vm->page_tables);
 
 	amdgpu_bo_unref(&vm->page_directory);
 	fence_put(vm->page_directory_fence);
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/amd/amdgpu/atombios_dp.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/amdgpu/atombios_dp.c
@@ -243,7 +243,7 @@ static void amdgpu_atombios_dp_get_adjus
 
 /* convert bits per color to bits per pixel */
 /* get bpc from the EDID */
-static int amdgpu_atombios_dp_convert_bpc_to_bpp(int bpc)
+static unsigned amdgpu_atombios_dp_convert_bpc_to_bpp(int bpc)
 {
 	if (bpc == 0)
 		return 24;
@@ -251,64 +251,32 @@ static int amdgpu_atombios_dp_convert_bp
 		return bpc * 3;
 }
 
-/* get the max pix clock supported by the link rate and lane num */
-static int amdgpu_atombios_dp_get_max_dp_pix_clock(int link_rate,
-					    int lane_num,
-					    int bpp)
-{
-	return (link_rate * lane_num * 8) / bpp;
-}
-
 /***** amdgpu specific DP functions *****/
 
-/* First get the min lane# when low rate is used according to pixel clock
- * (prefer low rate), second check max lane# supported by DP panel,
- * if the max lane# < low rate lane# then use max lane# instead.
- */
-static int amdgpu_atombios_dp_get_dp_lane_number(struct drm_connector *connector,
+static int amdgpu_atombios_dp_get_dp_link_config(struct drm_connector *connector,
 						 const u8 dpcd[DP_DPCD_SIZE],
-						 int pix_clock)
+						 unsigned pix_clock,
+						 unsigned *dp_lanes, unsigned *dp_rate)
 {
-	int bpp = amdgpu_atombios_dp_convert_bpc_to_bpp(amdgpu_connector_get_monitor_bpc(connector));
-	int max_link_rate = drm_dp_max_link_rate(dpcd);
-	int max_lane_num = drm_dp_max_lane_count(dpcd);
-	int lane_num;
-	int max_dp_pix_clock;
-
-	for (lane_num = 1; lane_num < max_lane_num; lane_num <<= 1) {
-		max_dp_pix_clock = amdgpu_atombios_dp_get_max_dp_pix_clock(max_link_rate, lane_num, bpp);
-		if (pix_clock <= max_dp_pix_clock)
-			break;
-	}
-
-	return lane_num;
-}
-
-static int amdgpu_atombios_dp_get_dp_link_clock(struct drm_connector *connector,
-						const u8 dpcd[DP_DPCD_SIZE],
-						int pix_clock)
-{
-	int bpp = amdgpu_atombios_dp_convert_bpc_to_bpp(amdgpu_connector_get_monitor_bpc(connector));
-	int lane_num, max_pix_clock;
-
-	if (amdgpu_connector_encoder_get_dp_bridge_encoder_id(connector) ==
-	    ENCODER_OBJECT_ID_NUTMEG)
-		return 270000;
-
-	lane_num = amdgpu_atombios_dp_get_dp_lane_number(connector, dpcd, pix_clock);
-	max_pix_clock = amdgpu_atombios_dp_get_max_dp_pix_clock(162000, lane_num, bpp);
-	if (pix_clock <= max_pix_clock)
-		return 162000;
-	max_pix_clock = amdgpu_atombios_dp_get_max_dp_pix_clock(270000, lane_num, bpp);
-	if (pix_clock <= max_pix_clock)
-		return 270000;
-	if (amdgpu_connector_is_dp12_capable(connector)) {
-		max_pix_clock = amdgpu_atombios_dp_get_max_dp_pix_clock(540000, lane_num, bpp);
-		if (pix_clock <= max_pix_clock)
-			return 540000;
+	unsigned bpp =
+		amdgpu_atombios_dp_convert_bpc_to_bpp(amdgpu_connector_get_monitor_bpc(connector));
+	static const unsigned link_rates[3] = { 162000, 270000, 540000 };
+	unsigned max_link_rate = drm_dp_max_link_rate(dpcd);
+	unsigned max_lane_num = drm_dp_max_lane_count(dpcd);
+	unsigned lane_num, i, max_pix_clock;
+
+	for (lane_num = 1; lane_num <= max_lane_num; lane_num <<= 1) {
+		for (i = 0; i < ARRAY_SIZE(link_rates) && link_rates[i] <= max_link_rate; i++) {
+			max_pix_clock = (lane_num * link_rates[i] * 8) / bpp;
+			if (max_pix_clock >= pix_clock) {
+				*dp_lanes = lane_num;
+				*dp_rate = link_rates[i];
+				return 0;
+			}
+		}
 	}
 
-	return drm_dp_max_link_rate(dpcd);
+	return -EINVAL;
 }
 
 static u8 amdgpu_atombios_dp_encoder_service(struct amdgpu_device *adev,
@@ -422,6 +390,7 @@ void amdgpu_atombios_dp_set_link_config(
 {
 	struct amdgpu_connector *amdgpu_connector = to_amdgpu_connector(connector);
 	struct amdgpu_connector_atom_dig *dig_connector;
+	int ret;
 
 	if (!amdgpu_connector->con_priv)
 		return;
@@ -429,10 +398,14 @@ void amdgpu_atombios_dp_set_link_config(
 
 	if ((dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) ||
 	    (dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP)) {
-		dig_connector->dp_clock =
-			amdgpu_atombios_dp_get_dp_link_clock(connector, dig_connector->dpcd, mode->clock);
-		dig_connector->dp_lane_count =
-			amdgpu_atombios_dp_get_dp_lane_number(connector, dig_connector->dpcd, mode->clock);
+		ret = amdgpu_atombios_dp_get_dp_link_config(connector, dig_connector->dpcd,
+							    mode->clock,
+							    &dig_connector->dp_lane_count,
+							    &dig_connector->dp_clock);
+		if (ret) {
+			dig_connector->dp_clock = 0;
+			dig_connector->dp_lane_count = 0;
+		}
 	}
 }
 
@@ -441,14 +414,17 @@ int amdgpu_atombios_dp_mode_valid_helper
 {
 	struct amdgpu_connector *amdgpu_connector = to_amdgpu_connector(connector);
 	struct amdgpu_connector_atom_dig *dig_connector;
-	int dp_clock;
+	unsigned dp_lanes, dp_clock;
+	int ret;
 
 	if (!amdgpu_connector->con_priv)
 		return MODE_CLOCK_HIGH;
 	dig_connector = amdgpu_connector->con_priv;
 
-	dp_clock =
-		amdgpu_atombios_dp_get_dp_link_clock(connector, dig_connector->dpcd, mode->clock);
+	ret = amdgpu_atombios_dp_get_dp_link_config(connector, dig_connector->dpcd,
+						    mode->clock, &dp_lanes, &dp_clock);
+	if (ret)
+		return MODE_CLOCK_HIGH;
 
 	if ((dp_clock == 540000) &&
 	    (!amdgpu_connector_is_dp12_capable(connector)))
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/amd/amdgpu/atombios_encoders.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/amdgpu/atombios_encoders.c
@@ -98,6 +98,7 @@ amdgpu_atombios_encoder_set_backlight_le
 		case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
 		case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
 		case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
+		case ENCODER_OBJECT_ID_INTERNAL_UNIPHY3:
 			if (dig->backlight_level == 0)
 				amdgpu_atombios_encoder_setup_dig_transmitter(encoder,
 								       ATOM_TRANSMITTER_ACTION_LCD_BLOFF, 0, 0);
@@ -298,6 +299,10 @@ bool amdgpu_atombios_encoder_mode_fixup(
 	    && (mode->crtc_vsync_start < (mode->crtc_vdisplay + 2)))
 		adjusted_mode->crtc_vsync_start = adjusted_mode->crtc_vdisplay + 2;
 
+	/* vertical FP must be at least 1 */
+	if (mode->crtc_vsync_start == mode->crtc_vdisplay)
+		adjusted_mode->crtc_vsync_start++;
+
 	/* get the native mode for scaling */
 	if (amdgpu_encoder->active_device & (ATOM_DEVICE_LCD_SUPPORT))
 		amdgpu_panel_mode_fixup(encoder, adjusted_mode);
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/amd/amdgpu/ci_dpm.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/amdgpu/ci_dpm.c
@@ -31,6 +31,7 @@
 #include "ci_dpm.h"
 #include "gfx_v7_0.h"
 #include "atom.h"
+#include "amd_pcie.h"
 #include <linux/seq_file.h>
 
 #include "smu/smu_7_0_1_d.h"
@@ -1395,7 +1396,6 @@ static void ci_thermal_stop_thermal_cont
 		ci_fan_ctrl_set_default_mode(adev);
 }
 
-#if 0
 static int ci_read_smc_soft_register(struct amdgpu_device *adev,
 				     u16 reg_offset, u32 *value)
 {
@@ -1405,7 +1405,6 @@ static int ci_read_smc_soft_register(str
 				      pi->soft_regs_start + reg_offset,
 				      value, pi->sram_end);
 }
-#endif
 
 static int ci_write_smc_soft_register(struct amdgpu_device *adev,
 				      u16 reg_offset, u32 value)
@@ -5837,18 +5836,16 @@ static int ci_dpm_init(struct amdgpu_dev
 	u8 frev, crev;
 	struct ci_power_info *pi;
 	int ret;
-	u32 mask;
 
 	pi = kzalloc(sizeof(struct ci_power_info), GFP_KERNEL);
 	if (pi == NULL)
 		return -ENOMEM;
 	adev->pm.dpm.priv = pi;
 
-	ret = drm_pcie_get_speed_cap_mask(adev->ddev, &mask);
-	if (ret)
-		pi->sys_pcie_mask = 0;
-	else
-		pi->sys_pcie_mask = mask;
+	pi->sys_pcie_mask =
+		(adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_MASK) >>
+		CAIL_PCIE_LINK_SPEED_SUPPORT_SHIFT;
+
 	pi->force_pcie_gen = AMDGPU_PCIE_GEN_INVALID;
 
 	pi->pcie_gen_performance.max = AMDGPU_PCIE_GEN1;
@@ -6084,11 +6081,23 @@ ci_dpm_debugfs_print_current_performance
 	struct amdgpu_ps *rps = &pi->current_rps;
 	u32 sclk = ci_get_average_sclk_freq(adev);
 	u32 mclk = ci_get_average_mclk_freq(adev);
+	u32 activity_percent = 50;
+	int ret;
+
+	ret = ci_read_smc_soft_register(adev, offsetof(SMU7_SoftRegisters, AverageGraphicsA),
+					&activity_percent);
+
+	if (ret == 0) {
+		activity_percent += 0x80;
+		activity_percent >>= 8;
+		activity_percent = activity_percent > 100 ? 100 : activity_percent;
+	}
 
 	seq_printf(m, "uvd %sabled\n", pi->uvd_enabled ? "en" : "dis");
 	seq_printf(m, "vce %sabled\n", rps->vce_active ? "en" : "dis");
 	seq_printf(m, "power level avg    sclk: %u mclk: %u\n",
 		   sclk, mclk);
+	seq_printf(m, "GPU load: %u %%\n", activity_percent);
 }
 
 static void ci_dpm_print_power_state(struct amdgpu_device *adev,
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/amd/amdgpu/cik.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/amdgpu/cik.c
@@ -32,6 +32,7 @@
 #include "amdgpu_vce.h"
 #include "cikd.h"
 #include "atom.h"
+#include "amd_pcie.h"
 
 #include "cik.h"
 #include "gmc_v7_0.h"
@@ -65,6 +66,7 @@
 #include "oss/oss_2_0_sh_mask.h"
 
 #include "amdgpu_amdkfd.h"
+#include "amdgpu_powerplay.h"
 
 /*
  * Indirect registers accessor
@@ -929,6 +931,37 @@ static bool cik_read_disabled_bios(struc
 	return r;
 }
 
+static bool cik_read_bios_from_rom(struct amdgpu_device *adev,
+				   u8 *bios, u32 length_bytes)
+{
+	u32 *dw_ptr;
+	unsigned long flags;
+	u32 i, length_dw;
+
+	if (bios == NULL)
+		return false;
+	if (length_bytes == 0)
+		return false;
+	/* APU vbios image is part of sbios image */
+	if (adev->flags & AMD_IS_APU)
+		return false;
+
+	dw_ptr = (u32 *)bios;
+	length_dw = ALIGN(length_bytes, 4) / 4;
+	/* take the smc lock since we are using the smc index */
+	spin_lock_irqsave(&adev->smc_idx_lock, flags);
+	/* set rom index to 0 */
+	WREG32(mmSMC_IND_INDEX_0, ixROM_INDEX);
+	WREG32(mmSMC_IND_DATA_0, 0);
+	/* set index to data for continous read */
+	WREG32(mmSMC_IND_INDEX_0, ixROM_DATA);
+	for (i = 0; i < length_dw; i++)
+		dw_ptr[i] = RREG32(mmSMC_IND_DATA_0);
+	spin_unlock_irqrestore(&adev->smc_idx_lock, flags);
+
+	return true;
+}
+
 static struct amdgpu_allowed_register_entry cik_allowed_read_registers[] = {
 	{mmGRBM_STATUS, false},
 	{mmGB_ADDR_CONFIG, false},
@@ -1563,8 +1596,8 @@ static void cik_pcie_gen3_enable(struct
 {
 	struct pci_dev *root = adev->pdev->bus->self;
 	int bridge_pos, gpu_pos;
-	u32 speed_cntl, mask, current_data_rate;
-	int ret, i;
+	u32 speed_cntl, current_data_rate;
+	int i;
 	u16 tmp16;
 
 	if (pci_is_root_bus(adev->pdev->bus))
@@ -1576,23 +1609,20 @@ static void cik_pcie_gen3_enable(struct
 	if (adev->flags & AMD_IS_APU)
 		return;
 
-	ret = drm_pcie_get_speed_cap_mask(adev->ddev, &mask);
-	if (ret != 0)
-		return;
-
-	if (!(mask & (DRM_PCIE_SPEED_50 | DRM_PCIE_SPEED_80)))
+	if (!(adev->pm.pcie_gen_mask & (CAIL_PCIE_LINK_SPEED_SUPPORT_GEN2 |
+					CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3)))
 		return;
 
 	speed_cntl = RREG32_PCIE(ixPCIE_LC_SPEED_CNTL);
 	current_data_rate = (speed_cntl & PCIE_LC_SPEED_CNTL__LC_CURRENT_DATA_RATE_MASK) >>
 		PCIE_LC_SPEED_CNTL__LC_CURRENT_DATA_RATE__SHIFT;
-	if (mask & DRM_PCIE_SPEED_80) {
+	if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3) {
 		if (current_data_rate == 2) {
 			DRM_INFO("PCIE gen 3 link speeds already enabled\n");
 			return;
 		}
 		DRM_INFO("enabling PCIE gen 3 link speeds, disable with amdgpu.pcie_gen2=0\n");
-	} else if (mask & DRM_PCIE_SPEED_50) {
+	} else if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN2) {
 		if (current_data_rate == 1) {
 			DRM_INFO("PCIE gen 2 link speeds already enabled\n");
 			return;
@@ -1608,7 +1638,7 @@ static void cik_pcie_gen3_enable(struct
 	if (!gpu_pos)
 		return;
 
-	if (mask & DRM_PCIE_SPEED_80) {
+	if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3) {
 		/* re-try equalization if gen3 is not already enabled */
 		if (current_data_rate != 2) {
 			u16 bridge_cfg, gpu_cfg;
@@ -1703,9 +1733,9 @@ static void cik_pcie_gen3_enable(struct
 
 	pci_read_config_word(adev->pdev, gpu_pos + PCI_EXP_LNKCTL2, &tmp16);
 	tmp16 &= ~0xf;
-	if (mask & DRM_PCIE_SPEED_80)
+	if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3)
 		tmp16 |= 3; /* gen3 */
-	else if (mask & DRM_PCIE_SPEED_50)
+	else if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN2)
 		tmp16 |= 2; /* gen2 */
 	else
 		tmp16 |= 1; /* gen1 */
@@ -1732,6 +1762,9 @@ static void cik_program_aspm(struct amdg
 	if (amdgpu_aspm == 0)
 		return;
 
+	if (pci_is_root_bus(adev->pdev->bus))
+		return;
+
 	/* XXX double check APUs */
 	if (adev->flags & AMD_IS_APU)
 		return;
@@ -1922,7 +1955,7 @@ static const struct amdgpu_ip_block_vers
 		.major = 7,
 		.minor = 0,
 		.rev = 0,
-		.funcs = &ci_dpm_ip_funcs,
+		.funcs = &amdgpu_pp_ip_funcs,
 	},
 	{
 		.type = AMD_IP_BLOCK_TYPE_DCE,
@@ -1990,7 +2023,7 @@ static const struct amdgpu_ip_block_vers
 		.major = 7,
 		.minor = 0,
 		.rev = 0,
-		.funcs = &ci_dpm_ip_funcs,
+		.funcs = &amdgpu_pp_ip_funcs,
 	},
 	{
 		.type = AMD_IP_BLOCK_TYPE_DCE,
@@ -2058,7 +2091,7 @@ static const struct amdgpu_ip_block_vers
 		.major = 7,
 		.minor = 0,
 		.rev = 0,
-		.funcs = &kv_dpm_ip_funcs,
+		.funcs = &amdgpu_pp_ip_funcs,
 	},
 	{
 		.type = AMD_IP_BLOCK_TYPE_DCE,
@@ -2126,7 +2159,7 @@ static const struct amdgpu_ip_block_vers
 		.major = 7,
 		.minor = 0,
 		.rev = 0,
-		.funcs = &kv_dpm_ip_funcs,
+		.funcs = &amdgpu_pp_ip_funcs,
 	},
 	{
 		.type = AMD_IP_BLOCK_TYPE_DCE,
@@ -2194,7 +2227,7 @@ static const struct amdgpu_ip_block_vers
 		.major = 7,
 		.minor = 0,
 		.rev = 0,
-		.funcs = &kv_dpm_ip_funcs,
+		.funcs = &amdgpu_pp_ip_funcs,
 	},
 	{
 		.type = AMD_IP_BLOCK_TYPE_DCE,
@@ -2267,6 +2300,7 @@ int cik_set_ip_blocks(struct amdgpu_devi
 static const struct amdgpu_asic_funcs cik_asic_funcs =
 {
 	.read_disabled_bios = &cik_read_disabled_bios,
+	.read_bios_from_rom = &cik_read_bios_from_rom,
 	.read_register = &cik_read_register,
 	.reset = &cik_asic_reset,
 	.set_vga_state = &cik_vga_set_state,
@@ -2301,72 +2335,72 @@ static int cik_common_early_init(void *h
 	switch (adev->asic_type) {
 	case CHIP_BONAIRE:
 		adev->cg_flags =
-			AMDGPU_CG_SUPPORT_GFX_MGCG |
-			AMDGPU_CG_SUPPORT_GFX_MGLS |
-			/*AMDGPU_CG_SUPPORT_GFX_CGCG |*/
-			AMDGPU_CG_SUPPORT_GFX_CGLS |
-			AMDGPU_CG_SUPPORT_GFX_CGTS |
-			AMDGPU_CG_SUPPORT_GFX_CGTS_LS |
-			AMDGPU_CG_SUPPORT_GFX_CP_LS |
-			AMDGPU_CG_SUPPORT_MC_LS |
-			AMDGPU_CG_SUPPORT_MC_MGCG |
-			AMDGPU_CG_SUPPORT_SDMA_MGCG |
-			AMDGPU_CG_SUPPORT_SDMA_LS |
-			AMDGPU_CG_SUPPORT_BIF_LS |
-			AMDGPU_CG_SUPPORT_VCE_MGCG |
-			AMDGPU_CG_SUPPORT_UVD_MGCG |
-			AMDGPU_CG_SUPPORT_HDP_LS |
-			AMDGPU_CG_SUPPORT_HDP_MGCG;
+			AMD_CG_SUPPORT_GFX_MGCG |
+			AMD_CG_SUPPORT_GFX_MGLS |
+			/*AMD_CG_SUPPORT_GFX_CGCG |*/
+			AMD_CG_SUPPORT_GFX_CGLS |
+			AMD_CG_SUPPORT_GFX_CGTS |
+			AMD_CG_SUPPORT_GFX_CGTS_LS |
+			AMD_CG_SUPPORT_GFX_CP_LS |
+			AMD_CG_SUPPORT_MC_LS |
+			AMD_CG_SUPPORT_MC_MGCG |
+			AMD_CG_SUPPORT_SDMA_MGCG |
+			AMD_CG_SUPPORT_SDMA_LS |
+			AMD_CG_SUPPORT_BIF_LS |
+			AMD_CG_SUPPORT_VCE_MGCG |
+			AMD_CG_SUPPORT_UVD_MGCG |
+			AMD_CG_SUPPORT_HDP_LS |
+			AMD_CG_SUPPORT_HDP_MGCG;
 		adev->pg_flags = 0;
 		adev->external_rev_id = adev->rev_id + 0x14;
 		break;
 	case CHIP_HAWAII:
 		adev->cg_flags =
-			AMDGPU_CG_SUPPORT_GFX_MGCG |
-			AMDGPU_CG_SUPPORT_GFX_MGLS |
-			/*AMDGPU_CG_SUPPORT_GFX_CGCG |*/
-			AMDGPU_CG_SUPPORT_GFX_CGLS |
-			AMDGPU_CG_SUPPORT_GFX_CGTS |
-			AMDGPU_CG_SUPPORT_GFX_CP_LS |
-			AMDGPU_CG_SUPPORT_MC_LS |
-			AMDGPU_CG_SUPPORT_MC_MGCG |
-			AMDGPU_CG_SUPPORT_SDMA_MGCG |
-			AMDGPU_CG_SUPPORT_SDMA_LS |
-			AMDGPU_CG_SUPPORT_BIF_LS |
-			AMDGPU_CG_SUPPORT_VCE_MGCG |
-			AMDGPU_CG_SUPPORT_UVD_MGCG |
-			AMDGPU_CG_SUPPORT_HDP_LS |
-			AMDGPU_CG_SUPPORT_HDP_MGCG;
+			AMD_CG_SUPPORT_GFX_MGCG |
+			AMD_CG_SUPPORT_GFX_MGLS |
+			/*AMD_CG_SUPPORT_GFX_CGCG |*/
+			AMD_CG_SUPPORT_GFX_CGLS |
+			AMD_CG_SUPPORT_GFX_CGTS |
+			AMD_CG_SUPPORT_GFX_CP_LS |
+			AMD_CG_SUPPORT_MC_LS |
+			AMD_CG_SUPPORT_MC_MGCG |
+			AMD_CG_SUPPORT_SDMA_MGCG |
+			AMD_CG_SUPPORT_SDMA_LS |
+			AMD_CG_SUPPORT_BIF_LS |
+			AMD_CG_SUPPORT_VCE_MGCG |
+			AMD_CG_SUPPORT_UVD_MGCG |
+			AMD_CG_SUPPORT_HDP_LS |
+			AMD_CG_SUPPORT_HDP_MGCG;
 		adev->pg_flags = 0;
 		adev->external_rev_id = 0x28;
 		break;
 	case CHIP_KAVERI:
 		adev->cg_flags =
-			AMDGPU_CG_SUPPORT_GFX_MGCG |
-			AMDGPU_CG_SUPPORT_GFX_MGLS |
-			/*AMDGPU_CG_SUPPORT_GFX_CGCG |*/
-			AMDGPU_CG_SUPPORT_GFX_CGLS |
-			AMDGPU_CG_SUPPORT_GFX_CGTS |
-			AMDGPU_CG_SUPPORT_GFX_CGTS_LS |
-			AMDGPU_CG_SUPPORT_GFX_CP_LS |
-			AMDGPU_CG_SUPPORT_SDMA_MGCG |
-			AMDGPU_CG_SUPPORT_SDMA_LS |
-			AMDGPU_CG_SUPPORT_BIF_LS |
-			AMDGPU_CG_SUPPORT_VCE_MGCG |
-			AMDGPU_CG_SUPPORT_UVD_MGCG |
-			AMDGPU_CG_SUPPORT_HDP_LS |
-			AMDGPU_CG_SUPPORT_HDP_MGCG;
+			AMD_CG_SUPPORT_GFX_MGCG |
+			AMD_CG_SUPPORT_GFX_MGLS |
+			/*AMD_CG_SUPPORT_GFX_CGCG |*/
+			AMD_CG_SUPPORT_GFX_CGLS |
+			AMD_CG_SUPPORT_GFX_CGTS |
+			AMD_CG_SUPPORT_GFX_CGTS_LS |
+			AMD_CG_SUPPORT_GFX_CP_LS |
+			AMD_CG_SUPPORT_SDMA_MGCG |
+			AMD_CG_SUPPORT_SDMA_LS |
+			AMD_CG_SUPPORT_BIF_LS |
+			AMD_CG_SUPPORT_VCE_MGCG |
+			AMD_CG_SUPPORT_UVD_MGCG |
+			AMD_CG_SUPPORT_HDP_LS |
+			AMD_CG_SUPPORT_HDP_MGCG;
 		adev->pg_flags =
-			/*AMDGPU_PG_SUPPORT_GFX_PG |
-			  AMDGPU_PG_SUPPORT_GFX_SMG |
-			  AMDGPU_PG_SUPPORT_GFX_DMG |*/
-			AMDGPU_PG_SUPPORT_UVD |
-			/*AMDGPU_PG_SUPPORT_VCE |
-			  AMDGPU_PG_SUPPORT_CP |
-			  AMDGPU_PG_SUPPORT_GDS |
-			  AMDGPU_PG_SUPPORT_RLC_SMU_HS |
-			  AMDGPU_PG_SUPPORT_ACP |
-			  AMDGPU_PG_SUPPORT_SAMU |*/
+			/*AMD_PG_SUPPORT_GFX_PG |
+			  AMD_PG_SUPPORT_GFX_SMG |
+			  AMD_PG_SUPPORT_GFX_DMG |*/
+			AMD_PG_SUPPORT_UVD |
+			/*AMD_PG_SUPPORT_VCE |
+			  AMD_PG_SUPPORT_CP |
+			  AMD_PG_SUPPORT_GDS |
+			  AMD_PG_SUPPORT_RLC_SMU_HS |
+			  AMD_PG_SUPPORT_ACP |
+			  AMD_PG_SUPPORT_SAMU |*/
 			0;
 		if (adev->pdev->device == 0x1312 ||
 			adev->pdev->device == 0x1316 ||
@@ -2378,29 +2412,29 @@ static int cik_common_early_init(void *h
 	case CHIP_KABINI:
 	case CHIP_MULLINS:
 		adev->cg_flags =
-			AMDGPU_CG_SUPPORT_GFX_MGCG |
-			AMDGPU_CG_SUPPORT_GFX_MGLS |
-			/*AMDGPU_CG_SUPPORT_GFX_CGCG |*/
-			AMDGPU_CG_SUPPORT_GFX_CGLS |
-			AMDGPU_CG_SUPPORT_GFX_CGTS |
-			AMDGPU_CG_SUPPORT_GFX_CGTS_LS |
-			AMDGPU_CG_SUPPORT_GFX_CP_LS |
-			AMDGPU_CG_SUPPORT_SDMA_MGCG |
-			AMDGPU_CG_SUPPORT_SDMA_LS |
-			AMDGPU_CG_SUPPORT_BIF_LS |
-			AMDGPU_CG_SUPPORT_VCE_MGCG |
-			AMDGPU_CG_SUPPORT_UVD_MGCG |
-			AMDGPU_CG_SUPPORT_HDP_LS |
-			AMDGPU_CG_SUPPORT_HDP_MGCG;
+			AMD_CG_SUPPORT_GFX_MGCG |
+			AMD_CG_SUPPORT_GFX_MGLS |
+			/*AMD_CG_SUPPORT_GFX_CGCG |*/
+			AMD_CG_SUPPORT_GFX_CGLS |
+			AMD_CG_SUPPORT_GFX_CGTS |
+			AMD_CG_SUPPORT_GFX_CGTS_LS |
+			AMD_CG_SUPPORT_GFX_CP_LS |
+			AMD_CG_SUPPORT_SDMA_MGCG |
+			AMD_CG_SUPPORT_SDMA_LS |
+			AMD_CG_SUPPORT_BIF_LS |
+			AMD_CG_SUPPORT_VCE_MGCG |
+			AMD_CG_SUPPORT_UVD_MGCG |
+			AMD_CG_SUPPORT_HDP_LS |
+			AMD_CG_SUPPORT_HDP_MGCG;
 		adev->pg_flags =
-			/*AMDGPU_PG_SUPPORT_GFX_PG |
-			  AMDGPU_PG_SUPPORT_GFX_SMG | */
-			AMDGPU_PG_SUPPORT_UVD |
-			/*AMDGPU_PG_SUPPORT_VCE |
-			  AMDGPU_PG_SUPPORT_CP |
-			  AMDGPU_PG_SUPPORT_GDS |
-			  AMDGPU_PG_SUPPORT_RLC_SMU_HS |
-			  AMDGPU_PG_SUPPORT_SAMU |*/
+			/*AMD_PG_SUPPORT_GFX_PG |
+			  AMD_PG_SUPPORT_GFX_SMG | */
+			AMD_PG_SUPPORT_UVD |
+			/*AMD_PG_SUPPORT_VCE |
+			  AMD_PG_SUPPORT_CP |
+			  AMD_PG_SUPPORT_GDS |
+			  AMD_PG_SUPPORT_RLC_SMU_HS |
+			  AMD_PG_SUPPORT_SAMU |*/
 			0;
 		if (adev->asic_type == CHIP_KABINI) {
 			if (adev->rev_id == 0)
@@ -2417,6 +2451,8 @@ static int cik_common_early_init(void *h
 		return -EINVAL;
 	}
 
+	amdgpu_get_pcie_info(adev);
+
 	return 0;
 }
 
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/amd/amdgpu/cik_ih.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/amdgpu/cik_ih.c
@@ -274,6 +274,11 @@ static void cik_ih_set_rptr(struct amdgp
 static int cik_ih_early_init(void *handle)
 {
 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
+	int ret;
+
+	ret = amdgpu_irq_add_domain(adev);
+	if (ret)
+		return ret;
 
 	cik_ih_set_interrupt_funcs(adev);
 
@@ -300,6 +305,7 @@ static int cik_ih_sw_fini(void *handle)
 
 	amdgpu_irq_fini(adev);
 	amdgpu_ih_ring_fini(adev);
+	amdgpu_irq_remove_domain(adev);
 
 	return 0;
 }
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/amd/amdgpu/cik_sdma.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/amdgpu/cik_sdma.c
@@ -52,6 +52,7 @@ static void cik_sdma_set_ring_funcs(stru
 static void cik_sdma_set_irq_funcs(struct amdgpu_device *adev);
 static void cik_sdma_set_buffer_funcs(struct amdgpu_device *adev);
 static void cik_sdma_set_vm_pte_funcs(struct amdgpu_device *adev);
+static int cik_sdma_soft_reset(void *handle);
 
 MODULE_FIRMWARE("radeon/bonaire_sdma.bin");
 MODULE_FIRMWARE("radeon/bonaire_sdma1.bin");
@@ -885,7 +886,7 @@ static void cik_enable_sdma_mgcg(struct
 {
 	u32 orig, data;
 
-	if (enable && (adev->cg_flags & AMDGPU_CG_SUPPORT_SDMA_MGCG)) {
+	if (enable && (adev->cg_flags & AMD_CG_SUPPORT_SDMA_MGCG)) {
 		WREG32(mmSDMA0_CLK_CTRL + SDMA0_REGISTER_OFFSET, 0x00000100);
 		WREG32(mmSDMA0_CLK_CTRL + SDMA1_REGISTER_OFFSET, 0x00000100);
 	} else {
@@ -906,7 +907,7 @@ static void cik_enable_sdma_mgls(struct
 {
 	u32 orig, data;
 
-	if (enable && (adev->cg_flags & AMDGPU_CG_SUPPORT_SDMA_LS)) {
+	if (enable && (adev->cg_flags & AMD_CG_SUPPORT_SDMA_LS)) {
 		orig = data = RREG32(mmSDMA0_POWER_CNTL + SDMA0_REGISTER_OFFSET);
 		data |= 0x100;
 		if (orig != data)
@@ -1030,6 +1031,8 @@ static int cik_sdma_resume(void *handle)
 {
 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
 
+	cik_sdma_soft_reset(handle);
+
 	return cik_sdma_hw_init(adev);
 }
 
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/amd/amdgpu/cz_dpm.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/amdgpu/cz_dpm.c
@@ -445,13 +445,13 @@ static int cz_dpm_init(struct amdgpu_dev
 	pi->gfx_pg_threshold = 500;
 	pi->caps_fps = true;
 	/* uvd */
-	pi->caps_uvd_pg = (adev->pg_flags & AMDGPU_PG_SUPPORT_UVD) ? true : false;
+	pi->caps_uvd_pg = (adev->pg_flags & AMD_PG_SUPPORT_UVD) ? true : false;
 	pi->caps_uvd_dpm = true;
 	/* vce */
-	pi->caps_vce_pg = (adev->pg_flags & AMDGPU_PG_SUPPORT_VCE) ? true : false;
+	pi->caps_vce_pg = (adev->pg_flags & AMD_PG_SUPPORT_VCE) ? true : false;
 	pi->caps_vce_dpm = true;
 	/* acp */
-	pi->caps_acp_pg = (adev->pg_flags & AMDGPU_PG_SUPPORT_ACP) ? true : false;
+	pi->caps_acp_pg = (adev->pg_flags & AMD_PG_SUPPORT_ACP) ? true : false;
 	pi->caps_acp_dpm = true;
 
 	pi->caps_stable_power_state = false;
@@ -1078,6 +1078,37 @@ static uint32_t cz_get_eclk_level(struct
 	return i;
 }
 
+static uint32_t cz_get_uvd_level(struct amdgpu_device *adev,
+				 uint32_t clock, uint16_t msg)
+{
+	int i = 0;
+	struct amdgpu_uvd_clock_voltage_dependency_table *table =
+		&adev->pm.dpm.dyn_state.uvd_clock_voltage_dependency_table;
+
+	switch (msg) {
+	case PPSMC_MSG_SetUvdSoftMin:
+	case PPSMC_MSG_SetUvdHardMin:
+		for (i = 0; i < table->count; i++)
+			if (clock <= table->entries[i].vclk)
+				break;
+		if (i == table->count)
+			i = table->count - 1;
+		break;
+	case PPSMC_MSG_SetUvdSoftMax:
+	case PPSMC_MSG_SetUvdHardMax:
+		for (i = table->count - 1; i >= 0; i--)
+			if (clock >= table->entries[i].vclk)
+				break;
+		if (i < 0)
+			i = 0;
+		break;
+	default:
+		break;
+	}
+
+	return i;
+}
+
 static int cz_program_bootup_state(struct amdgpu_device *adev)
 {
 	struct cz_power_info *pi = cz_get_pi(adev);
@@ -1739,6 +1770,200 @@ static int cz_dpm_unforce_dpm_levels(str
 	return 0;
 }
 
+static int cz_dpm_uvd_force_highest(struct amdgpu_device *adev)
+{
+	struct cz_power_info *pi = cz_get_pi(adev);
+	int ret = 0;
+
+	if (pi->uvd_dpm.soft_min_clk != pi->uvd_dpm.soft_max_clk) {
+		pi->uvd_dpm.soft_min_clk =
+			pi->uvd_dpm.soft_max_clk;
+		ret = cz_send_msg_to_smc_with_parameter(adev,
+				PPSMC_MSG_SetUvdSoftMin,
+				cz_get_uvd_level(adev,
+					pi->uvd_dpm.soft_min_clk,
+					PPSMC_MSG_SetUvdSoftMin));
+		if (ret)
+			return ret;
+	}
+
+	return ret;
+}
+
+static int cz_dpm_uvd_force_lowest(struct amdgpu_device *adev)
+{
+	struct cz_power_info *pi = cz_get_pi(adev);
+	int ret = 0;
+
+	if (pi->uvd_dpm.soft_max_clk != pi->uvd_dpm.soft_min_clk) {
+		pi->uvd_dpm.soft_max_clk = pi->uvd_dpm.soft_min_clk;
+		ret = cz_send_msg_to_smc_with_parameter(adev,
+				PPSMC_MSG_SetUvdSoftMax,
+				cz_get_uvd_level(adev,
+					pi->uvd_dpm.soft_max_clk,
+					PPSMC_MSG_SetUvdSoftMax));
+		if (ret)
+			return ret;
+	}
+
+	return ret;
+}
+
+static uint32_t cz_dpm_get_max_uvd_level(struct amdgpu_device *adev)
+{
+	struct cz_power_info *pi = cz_get_pi(adev);
+
+	if (!pi->max_uvd_level) {
+		cz_send_msg_to_smc(adev, PPSMC_MSG_GetMaxUvdLevel);
+		pi->max_uvd_level = cz_get_argument(adev) + 1;
+	}
+
+	if (pi->max_uvd_level > CZ_MAX_HARDWARE_POWERLEVELS) {
+		DRM_ERROR("Invalid max uvd level!\n");
+		return -EINVAL;
+	}
+
+	return pi->max_uvd_level;
+}
+
+static int cz_dpm_unforce_uvd_dpm_levels(struct amdgpu_device *adev)
+{
+	struct cz_power_info *pi = cz_get_pi(adev);
+	struct amdgpu_uvd_clock_voltage_dependency_table *dep_table =
+		&adev->pm.dpm.dyn_state.uvd_clock_voltage_dependency_table;
+	uint32_t level = 0;
+	int ret = 0;
+
+	pi->uvd_dpm.soft_min_clk = dep_table->entries[0].vclk;
+	level = cz_dpm_get_max_uvd_level(adev) - 1;
+	if (level < dep_table->count)
+		pi->uvd_dpm.soft_max_clk = dep_table->entries[level].vclk;
+	else
+		pi->uvd_dpm.soft_max_clk =
+			dep_table->entries[dep_table->count - 1].vclk;
+
+	/* get min/max sclk soft value
+	 * notify SMU to execute */
+	ret = cz_send_msg_to_smc_with_parameter(adev,
+				PPSMC_MSG_SetUvdSoftMin,
+				cz_get_uvd_level(adev,
+					pi->uvd_dpm.soft_min_clk,
+					PPSMC_MSG_SetUvdSoftMin));
+	if (ret)
+		return ret;
+
+	ret = cz_send_msg_to_smc_with_parameter(adev,
+				PPSMC_MSG_SetUvdSoftMax,
+				cz_get_uvd_level(adev,
+					pi->uvd_dpm.soft_max_clk,
+					PPSMC_MSG_SetUvdSoftMax));
+	if (ret)
+		return ret;
+
+	DRM_DEBUG("DPM uvd unforce state min=%d, max=%d.\n",
+		  pi->uvd_dpm.soft_min_clk,
+		  pi->uvd_dpm.soft_max_clk);
+
+	return 0;
+}
+
+static int cz_dpm_vce_force_highest(struct amdgpu_device *adev)
+{
+	struct cz_power_info *pi = cz_get_pi(adev);
+	int ret = 0;
+
+	if (pi->vce_dpm.soft_min_clk != pi->vce_dpm.soft_max_clk) {
+		pi->vce_dpm.soft_min_clk =
+			pi->vce_dpm.soft_max_clk;
+		ret = cz_send_msg_to_smc_with_parameter(adev,
+				PPSMC_MSG_SetEclkSoftMin,
+				cz_get_eclk_level(adev,
+					pi->vce_dpm.soft_min_clk,
+					PPSMC_MSG_SetEclkSoftMin));
+		if (ret)
+			return ret;
+	}
+
+	return ret;
+}
+
+static int cz_dpm_vce_force_lowest(struct amdgpu_device *adev)
+{
+	struct cz_power_info *pi = cz_get_pi(adev);
+	int ret = 0;
+
+	if (pi->vce_dpm.soft_max_clk != pi->vce_dpm.soft_min_clk) {
+		pi->vce_dpm.soft_max_clk = pi->vce_dpm.soft_min_clk;
+		ret = cz_send_msg_to_smc_with_parameter(adev,
+				PPSMC_MSG_SetEclkSoftMax,
+				cz_get_uvd_level(adev,
+					pi->vce_dpm.soft_max_clk,
+					PPSMC_MSG_SetEclkSoftMax));
+		if (ret)
+			return ret;
+	}
+
+	return ret;
+}
+
+static uint32_t cz_dpm_get_max_vce_level(struct amdgpu_device *adev)
+{
+	struct cz_power_info *pi = cz_get_pi(adev);
+
+	if (!pi->max_vce_level) {
+		cz_send_msg_to_smc(adev, PPSMC_MSG_GetMaxEclkLevel);
+		pi->max_vce_level = cz_get_argument(adev) + 1;
+	}
+
+	if (pi->max_vce_level > CZ_MAX_HARDWARE_POWERLEVELS) {
+		DRM_ERROR("Invalid max vce level!\n");
+		return -EINVAL;
+	}
+
+	return pi->max_vce_level;
+}
+
+static int cz_dpm_unforce_vce_dpm_levels(struct amdgpu_device *adev)
+{
+	struct cz_power_info *pi = cz_get_pi(adev);
+	struct amdgpu_vce_clock_voltage_dependency_table *dep_table =
+		&adev->pm.dpm.dyn_state.vce_clock_voltage_dependency_table;
+	uint32_t level = 0;
+	int ret = 0;
+
+	pi->vce_dpm.soft_min_clk = dep_table->entries[0].ecclk;
+	level = cz_dpm_get_max_vce_level(adev) - 1;
+	if (level < dep_table->count)
+		pi->vce_dpm.soft_max_clk = dep_table->entries[level].ecclk;
+	else
+		pi->vce_dpm.soft_max_clk =
+			dep_table->entries[dep_table->count - 1].ecclk;
+
+	/* get min/max sclk soft value
+	 * notify SMU to execute */
+	ret = cz_send_msg_to_smc_with_parameter(adev,
+				PPSMC_MSG_SetEclkSoftMin,
+				cz_get_eclk_level(adev,
+					pi->vce_dpm.soft_min_clk,
+					PPSMC_MSG_SetEclkSoftMin));
+	if (ret)
+		return ret;
+
+	ret = cz_send_msg_to_smc_with_parameter(adev,
+				PPSMC_MSG_SetEclkSoftMax,
+				cz_get_eclk_level(adev,
+					pi->vce_dpm.soft_max_clk,
+					PPSMC_MSG_SetEclkSoftMax));
+	if (ret)
+		return ret;
+
+	DRM_DEBUG("DPM vce unforce state min=%d, max=%d.\n",
+		  pi->vce_dpm.soft_min_clk,
+		  pi->vce_dpm.soft_max_clk);
+
+	return 0;
+}
+
 static int cz_dpm_force_dpm_level(struct amdgpu_device *adev,
 				  enum amdgpu_dpm_forced_level level)
 {
@@ -1746,25 +1971,70 @@ static int cz_dpm_force_dpm_level(struct
 
 	switch (level) {
 	case AMDGPU_DPM_FORCED_LEVEL_HIGH:
+		/* sclk */
 		ret = cz_dpm_unforce_dpm_levels(adev);
 		if (ret)
 			return ret;
 		ret = cz_dpm_force_highest(adev);
 		if (ret)
 			return ret;
+
+		/* uvd */
+		ret = cz_dpm_unforce_uvd_dpm_levels(adev);
+		if (ret)
+			return ret;
+		ret = cz_dpm_uvd_force_highest(adev);
+		if (ret)
+			return ret;
+
+		/* vce */
+		ret = cz_dpm_unforce_vce_dpm_levels(adev);
+		if (ret)
+			return ret;
+		ret = cz_dpm_vce_force_highest(adev);
+		if (ret)
+			return ret;
 		break;
 	case AMDGPU_DPM_FORCED_LEVEL_LOW:
+		/* sclk */
 		ret = cz_dpm_unforce_dpm_levels(adev);
 		if (ret)
 			return ret;
 		ret = cz_dpm_force_lowest(adev);
 		if (ret)
 			return ret;
+
+		/* uvd */
+		ret = cz_dpm_unforce_uvd_dpm_levels(adev);
+		if (ret)
+			return ret;
+		ret = cz_dpm_uvd_force_lowest(adev);
+		if (ret)
+			return ret;
+
+		/* vce */
+		ret = cz_dpm_unforce_vce_dpm_levels(adev);
+		if (ret)
+			return ret;
+		ret = cz_dpm_vce_force_lowest(adev);
+		if (ret)
+			return ret;
 		break;
 	case AMDGPU_DPM_FORCED_LEVEL_AUTO:
+		/* sclk */
 		ret = cz_dpm_unforce_dpm_levels(adev);
 		if (ret)
 			return ret;
+
+		/* uvd */
+		ret = cz_dpm_unforce_uvd_dpm_levels(adev);
+		if (ret)
+			return ret;
+
+		/* vce */
+		ret = cz_dpm_unforce_vce_dpm_levels(adev);
+		if (ret)
+			return ret;
 		break;
 	default:
 		break;
@@ -1905,7 +2175,8 @@ static int cz_update_vce_dpm(struct amdg
 		pi->vce_dpm.hard_min_clk = table->entries[table->count-1].ecclk;
 
 	} else { /* non-stable p-state cases. without vce.Arbiter.EcclkHardMin */
-		pi->vce_dpm.hard_min_clk = table->entries[0].ecclk;
+		/* leave it as set by user */
+		/*pi->vce_dpm.hard_min_clk = table->entries[0].ecclk;*/
 	}
 
 	cz_send_msg_to_smc_with_parameter(adev,
@@ -1955,10 +2226,8 @@ static void cz_dpm_powergate_vce(struct
 		}
 	} else { /*pi->caps_vce_pg*/
 		cz_update_vce_dpm(adev);
-		cz_enable_vce_dpm(adev, true);
+		cz_enable_vce_dpm(adev, !gate);
 	}
-
-	return;
 }
 
 const struct amd_ip_funcs cz_dpm_ip_funcs = {
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/amd/amdgpu/cz_dpm.h
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/amdgpu/cz_dpm.h
@@ -183,6 +183,8 @@ struct cz_power_info {
 	uint32_t voltage_drop_threshold;
 	uint32_t gfx_pg_threshold;
 	uint32_t max_sclk_level;
+	uint32_t max_uvd_level;
+	uint32_t max_vce_level;
 	/* flags */
 	bool didt_enabled;
 	bool video_start;
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/amd/amdgpu/cz_ih.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/amdgpu/cz_ih.c
@@ -253,8 +253,14 @@ static void cz_ih_set_rptr(struct amdgpu
 static int cz_ih_early_init(void *handle)
 {
 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
+	int ret;
+
+	ret = amdgpu_irq_add_domain(adev);
+	if (ret)
+		return ret;
 
 	cz_ih_set_interrupt_funcs(adev);
+
 	return 0;
 }
 
@@ -278,6 +284,7 @@ static int cz_ih_sw_fini(void *handle)
 
 	amdgpu_irq_fini(adev);
 	amdgpu_ih_ring_fini(adev);
+	amdgpu_irq_remove_domain(adev);
 
 	return 0;
 }
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/amd/amdgpu/cz_ppsmc.h
+++ /dev/null
@@ -1,185 +0,0 @@
-/*
- * Copyright 2014 Advanced Micro Devices, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- */
-
-#ifndef CZ_PP_SMC_H
-#define CZ_PP_SMC_H
-
-#pragma pack(push, 1)
-
-/* Fan control algorithm:*/
-#define FDO_MODE_HARDWARE 0
-#define FDO_MODE_PIECE_WISE_LINEAR 1
-
-enum FAN_CONTROL {
-    FAN_CONTROL_FUZZY,
-    FAN_CONTROL_TABLE
-};
-
-enum DPM_ARRAY {
-    DPM_ARRAY_HARD_MAX,
-    DPM_ARRAY_HARD_MIN,
-    DPM_ARRAY_SOFT_MAX,
-    DPM_ARRAY_SOFT_MIN
-};
-
-/*
- * Return codes for driver to SMC communication.
- * Leave these #define-s, enums might not be exactly 8-bits on the microcontroller.
- */
-#define PPSMC_Result_OK             ((uint16_t)0x01)
-#define PPSMC_Result_NoMore         ((uint16_t)0x02)
-#define PPSMC_Result_NotNow         ((uint16_t)0x03)
-#define PPSMC_Result_Failed         ((uint16_t)0xFF)
-#define PPSMC_Result_UnknownCmd     ((uint16_t)0xFE)
-#define PPSMC_Result_UnknownVT      ((uint16_t)0xFD)
-
-#define PPSMC_isERROR(x)            ((uint16_t)0x80 & (x))
-
-/*
- * Supported driver messages
- */
-#define PPSMC_MSG_Test                        ((uint16_t) 0x1)
-#define PPSMC_MSG_GetFeatureStatus            ((uint16_t) 0x2)
-#define PPSMC_MSG_EnableAllSmuFeatures        ((uint16_t) 0x3)
-#define PPSMC_MSG_DisableAllSmuFeatures       ((uint16_t) 0x4)
-#define PPSMC_MSG_OptimizeBattery             ((uint16_t) 0x5)
-#define PPSMC_MSG_MaximizePerf                ((uint16_t) 0x6)
-#define PPSMC_MSG_UVDPowerOFF                 ((uint16_t) 0x7)
-#define PPSMC_MSG_UVDPowerON                  ((uint16_t) 0x8)
-#define PPSMC_MSG_VCEPowerOFF                 ((uint16_t) 0x9)
-#define PPSMC_MSG_VCEPowerON                  ((uint16_t) 0xA)
-#define PPSMC_MSG_ACPPowerOFF                 ((uint16_t) 0xB)
-#define PPSMC_MSG_ACPPowerON                  ((uint16_t) 0xC)
-#define PPSMC_MSG_SDMAPowerOFF                ((uint16_t) 0xD)
-#define PPSMC_MSG_SDMAPowerON                 ((uint16_t) 0xE)
-#define PPSMC_MSG_XDMAPowerOFF                ((uint16_t) 0xF)
-#define PPSMC_MSG_XDMAPowerON                 ((uint16_t) 0x10)
-#define PPSMC_MSG_SetMinDeepSleepSclk         ((uint16_t) 0x11)
-#define PPSMC_MSG_SetSclkSoftMin              ((uint16_t) 0x12)
-#define PPSMC_MSG_SetSclkSoftMax              ((uint16_t) 0x13)
-#define PPSMC_MSG_SetSclkHardMin              ((uint16_t) 0x14)
-#define PPSMC_MSG_SetSclkHardMax              ((uint16_t) 0x15)
-#define PPSMC_MSG_SetLclkSoftMin              ((uint16_t) 0x16)
-#define PPSMC_MSG_SetLclkSoftMax              ((uint16_t) 0x17)
-#define PPSMC_MSG_SetLclkHardMin              ((uint16_t) 0x18)
-#define PPSMC_MSG_SetLclkHardMax              ((uint16_t) 0x19)
-#define PPSMC_MSG_SetUvdSoftMin               ((uint16_t) 0x1A)
-#define PPSMC_MSG_SetUvdSoftMax               ((uint16_t) 0x1B)
-#define PPSMC_MSG_SetUvdHardMin               ((uint16_t) 0x1C)
-#define PPSMC_MSG_SetUvdHardMax               ((uint16_t) 0x1D)
-#define PPSMC_MSG_SetEclkSoftMin              ((uint16_t) 0x1E)
-#define PPSMC_MSG_SetEclkSoftMax              ((uint16_t) 0x1F)
-#define PPSMC_MSG_SetEclkHardMin              ((uint16_t) 0x20)
-#define PPSMC_MSG_SetEclkHardMax              ((uint16_t) 0x21)
-#define PPSMC_MSG_SetAclkSoftMin              ((uint16_t) 0x22)
-#define PPSMC_MSG_SetAclkSoftMax              ((uint16_t) 0x23)
-#define PPSMC_MSG_SetAclkHardMin              ((uint16_t) 0x24)
-#define PPSMC_MSG_SetAclkHardMax              ((uint16_t) 0x25)
-#define PPSMC_MSG_SetNclkSoftMin              ((uint16_t) 0x26)
-#define PPSMC_MSG_SetNclkSoftMax              ((uint16_t) 0x27)
-#define PPSMC_MSG_SetNclkHardMin              ((uint16_t) 0x28)
-#define PPSMC_MSG_SetNclkHardMax              ((uint16_t) 0x29)
-#define PPSMC_MSG_SetPstateSoftMin            ((uint16_t) 0x2A)
-#define PPSMC_MSG_SetPstateSoftMax            ((uint16_t) 0x2B)
-#define PPSMC_MSG_SetPstateHardMin            ((uint16_t) 0x2C)
-#define PPSMC_MSG_SetPstateHardMax            ((uint16_t) 0x2D)
-#define PPSMC_MSG_DisableLowMemoryPstate      ((uint16_t) 0x2E)
-#define PPSMC_MSG_EnableLowMemoryPstate       ((uint16_t) 0x2F)
-#define PPSMC_MSG_UcodeAddressLow             ((uint16_t) 0x30)
-#define PPSMC_MSG_UcodeAddressHigh            ((uint16_t) 0x31)
-#define PPSMC_MSG_UcodeLoadStatus             ((uint16_t) 0x32)
-#define PPSMC_MSG_DriverDramAddrHi            ((uint16_t) 0x33)
-#define PPSMC_MSG_DriverDramAddrLo            ((uint16_t) 0x34)
-#define PPSMC_MSG_CondExecDramAddrHi          ((uint16_t) 0x35)
-#define PPSMC_MSG_CondExecDramAddrLo          ((uint16_t) 0x36)
-#define PPSMC_MSG_LoadUcodes                  ((uint16_t) 0x37)
-#define PPSMC_MSG_DriverResetMode             ((uint16_t) 0x38)
-#define PPSMC_MSG_PowerStateNotify            ((uint16_t) 0x39)
-#define PPSMC_MSG_SetDisplayPhyConfig         ((uint16_t) 0x3A)
-#define PPSMC_MSG_GetMaxSclkLevel             ((uint16_t) 0x3B)
-#define PPSMC_MSG_GetMaxLclkLevel             ((uint16_t) 0x3C)
-#define PPSMC_MSG_GetMaxUvdLevel              ((uint16_t) 0x3D)
-#define PPSMC_MSG_GetMaxEclkLevel             ((uint16_t) 0x3E)
-#define PPSMC_MSG_GetMaxAclkLevel             ((uint16_t) 0x3F)
-#define PPSMC_MSG_GetMaxNclkLevel             ((uint16_t) 0x40)
-#define PPSMC_MSG_GetMaxPstate                ((uint16_t) 0x41)
-#define PPSMC_MSG_DramAddrHiVirtual           ((uint16_t) 0x42)
-#define PPSMC_MSG_DramAddrLoVirtual           ((uint16_t) 0x43)
-#define PPSMC_MSG_DramAddrHiPhysical          ((uint16_t) 0x44)
-#define PPSMC_MSG_DramAddrLoPhysical          ((uint16_t) 0x45)
-#define PPSMC_MSG_DramBufferSize              ((uint16_t) 0x46)
-#define PPSMC_MSG_SetMmPwrLogDramAddrHi       ((uint16_t) 0x47)
-#define PPSMC_MSG_SetMmPwrLogDramAddrLo       ((uint16_t) 0x48)
-#define PPSMC_MSG_SetClkTableAddrHi           ((uint16_t) 0x49)
-#define PPSMC_MSG_SetClkTableAddrLo           ((uint16_t) 0x4A)
-#define PPSMC_MSG_GetConservativePowerLimit   ((uint16_t) 0x4B)
-
-#define PPSMC_MSG_InitJobs                    ((uint16_t) 0x252)
-#define PPSMC_MSG_ExecuteJob                  ((uint16_t) 0x254)
-
-#define PPSMC_MSG_NBDPM_Enable                ((uint16_t) 0x140)
-#define PPSMC_MSG_NBDPM_Disable               ((uint16_t) 0x141)
-
-#define PPSMC_MSG_DPM_FPS_Mode                ((uint16_t) 0x15d)
-#define PPSMC_MSG_DPM_Activity_Mode           ((uint16_t) 0x15e)
-
-#define PPSMC_MSG_PmStatusLogStart            ((uint16_t) 0x170)
-#define PPSMC_MSG_PmStatusLogSample           ((uint16_t) 0x171)
-
-#define PPSMC_MSG_AllowLowSclkInterrupt       ((uint16_t) 0x184)
-#define PPSMC_MSG_MmPowerMonitorStart         ((uint16_t) 0x18F)
-#define PPSMC_MSG_MmPowerMonitorStop          ((uint16_t) 0x190)
-#define PPSMC_MSG_MmPowerMonitorRestart       ((uint16_t) 0x191)
-
-#define PPSMC_MSG_SetClockGateMask            ((uint16_t) 0x260)
-#define PPSMC_MSG_SetFpsThresholdLo           ((uint16_t) 0x264)
-#define PPSMC_MSG_SetFpsThresholdHi           ((uint16_t) 0x265)
-#define PPSMC_MSG_SetLowSclkIntrThreshold     ((uint16_t) 0x266)
-
-#define PPSMC_MSG_ClkTableXferToDram          ((uint16_t) 0x267)
-#define PPSMC_MSG_ClkTableXferToSmu           ((uint16_t) 0x268)
-#define PPSMC_MSG_GetAverageGraphicsActivity  ((uint16_t) 0x269)
-#define PPSMC_MSG_GetAverageGioActivity       ((uint16_t) 0x26A)
-#define PPSMC_MSG_SetLoggerBufferSize         ((uint16_t) 0x26B)
-#define PPSMC_MSG_SetLoggerAddressHigh        ((uint16_t) 0x26C)
-#define PPSMC_MSG_SetLoggerAddressLow         ((uint16_t) 0x26D)
-#define PPSMC_MSG_SetWatermarkFrequency       ((uint16_t) 0x26E)
-
-/* REMOVE LATER*/
-#define PPSMC_MSG_DPM_ForceState              ((uint16_t) 0x104)
-
-/* Feature Enable Masks*/
-#define NB_DPM_MASK             0x00000800
-#define VDDGFX_MASK             0x00800000
-#define VCE_DPM_MASK            0x00400000
-#define ACP_DPM_MASK            0x00040000
-#define UVD_DPM_MASK            0x00010000
-#define GFX_CU_PG_MASK          0x00004000
-#define SCLK_DPM_MASK           0x00080000
-
-#if !defined(SMC_MICROCODE)
-#pragma pack(pop)
-
-#endif
-
-#endif
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/amd/amdgpu/fiji_dpm.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/amdgpu/fiji_dpm.c
@@ -24,7 +24,7 @@
 #include <linux/firmware.h>
 #include "drmP.h"
 #include "amdgpu.h"
-#include "fiji_smumgr.h"
+#include "fiji_smum.h"
 
 MODULE_FIRMWARE("amdgpu/fiji_smc.bin");
 
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/amd/amdgpu/fiji_ppsmc.h
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
- * Copyright 2014 Advanced Micro Devices, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- */
-
-#ifndef FIJI_PP_SMC_H
-#define FIJI_PP_SMC_H
-
-#pragma pack(push, 1)
-
-#define PPSMC_SWSTATE_FLAG_DC                           0x01
-#define PPSMC_SWSTATE_FLAG_UVD                          0x02
-#define PPSMC_SWSTATE_FLAG_VCE                          0x04
-
-#define PPSMC_THERMAL_PROTECT_TYPE_INTERNAL             0x00
-#define PPSMC_THERMAL_PROTECT_TYPE_EXTERNAL             0x01
-#define PPSMC_THERMAL_PROTECT_TYPE_NONE                 0xff
-
-#define PPSMC_SYSTEMFLAG_GPIO_DC                        0x01
-#define PPSMC_SYSTEMFLAG_STEPVDDC                       0x02
-#define PPSMC_SYSTEMFLAG_GDDR5                          0x04
-
-#define PPSMC_SYSTEMFLAG_DISABLE_BABYSTEP               0x08
-
-#define PPSMC_SYSTEMFLAG_REGULATOR_HOT                  0x10
-#define PPSMC_SYSTEMFLAG_REGULATOR_HOT_ANALOG           0x20
-
-#define PPSMC_EXTRAFLAGS_AC2DC_ACTION_MASK              0x07
-#define PPSMC_EXTRAFLAGS_AC2DC_DONT_WAIT_FOR_VBLANK     0x08
-
-#define PPSMC_EXTRAFLAGS_AC2DC_ACTION_GOTODPMLOWSTATE   0x00
-#define PPSMC_EXTRAFLAGS_AC2DC_ACTION_GOTOINITIALSTATE  0x01
-
-#define PPSMC_DPM2FLAGS_TDPCLMP                         0x01
-#define PPSMC_DPM2FLAGS_PWRSHFT                         0x02
-#define PPSMC_DPM2FLAGS_OCP                             0x04
-
-#define PPSMC_DISPLAY_WATERMARK_LOW                     0
-#define PPSMC_DISPLAY_WATERMARK_HIGH                    1
-
-#define PPSMC_STATEFLAG_AUTO_PULSE_SKIP    		0x01
-#define PPSMC_STATEFLAG_POWERBOOST         		0x02
-#define PPSMC_STATEFLAG_PSKIP_ON_TDP_FAULT 		0x04
-#define PPSMC_STATEFLAG_POWERSHIFT         		0x08
-#define PPSMC_STATEFLAG_SLOW_READ_MARGIN   		0x10
-#define PPSMC_STATEFLAG_DEEPSLEEP_THROTTLE 		0x20
-#define PPSMC_STATEFLAG_DEEPSLEEP_BYPASS   		0x40
-
-#define FDO_MODE_HARDWARE 0
-#define FDO_MODE_PIECE_WISE_LINEAR 1
-
-enum FAN_CONTROL {
-	FAN_CONTROL_FUZZY,
-	FAN_CONTROL_TABLE
-};
-
-//Gemini Modes
-#define PPSMC_GeminiModeNone   0  //Single GPU board
-#define PPSMC_GeminiModeMaster 1  //Master GPU on a Gemini board
-#define PPSMC_GeminiModeSlave  2  //Slave GPU on a Gemini board
-
-#define PPSMC_Result_OK             			((uint16_t)0x01)
-#define PPSMC_Result_NoMore         			((uint16_t)0x02)
-#define PPSMC_Result_NotNow         			((uint16_t)0x03)
-#define PPSMC_Result_Failed         			((uint16_t)0xFF)
-#define PPSMC_Result_UnknownCmd     			((uint16_t)0xFE)
-#define PPSMC_Result_UnknownVT      			((uint16_t)0xFD)
-
-typedef uint16_t PPSMC_Result;
-
-#define PPSMC_isERROR(x) ((uint16_t)0x80 & (x))
-
-#define PPSMC_MSG_Halt                      		((uint16_t)0x10)
-#define PPSMC_MSG_Resume                    		((uint16_t)0x11)
-#define PPSMC_MSG_EnableDPMLevel            		((uint16_t)0x12)
-#define PPSMC_MSG_ZeroLevelsDisabled        		((uint16_t)0x13)
-#define PPSMC_MSG_OneLevelsDisabled         		((uint16_t)0x14)
-#define PPSMC_MSG_TwoLevelsDisabled         		((uint16_t)0x15)
-#define PPSMC_MSG_EnableThermalInterrupt    		((uint16_t)0x16)
-#define PPSMC_MSG_RunningOnAC               		((uint16_t)0x17)
-#define PPSMC_MSG_LevelUp                   		((uint16_t)0x18)
-#define PPSMC_MSG_LevelDown                 		((uint16_t)0x19)
-#define PPSMC_MSG_ResetDPMCounters          		((uint16_t)0x1a)
-#define PPSMC_MSG_SwitchToSwState           		((uint16_t)0x20)
-#define PPSMC_MSG_SwitchToSwStateLast       		((uint16_t)0x3f)
-#define PPSMC_MSG_SwitchToInitialState      		((uint16_t)0x40)
-#define PPSMC_MSG_NoForcedLevel             		((uint16_t)0x41)
-#define PPSMC_MSG_ForceHigh                 		((uint16_t)0x42)
-#define PPSMC_MSG_ForceMediumOrHigh         		((uint16_t)0x43)
-#define PPSMC_MSG_SwitchToMinimumPower      		((uint16_t)0x51)
-#define PPSMC_MSG_ResumeFromMinimumPower    		((uint16_t)0x52)
-#define PPSMC_MSG_EnableCac                 		((uint16_t)0x53)
-#define PPSMC_MSG_DisableCac                		((uint16_t)0x54)
-#define PPSMC_DPMStateHistoryStart          		((uint16_t)0x55)
-#define PPSMC_DPMStateHistoryStop           		((uint16_t)0x56)
-#define PPSMC_CACHistoryStart               		((uint16_t)0x57)
-#define PPSMC_CACHistoryStop                		((uint16_t)0x58)
-#define PPSMC_TDPClampingActive             		((uint16_t)0x59)
-#define PPSMC_TDPClampingInactive           		((uint16_t)0x5A)
-#define PPSMC_StartFanControl               		((uint16_t)0x5B)
-#define PPSMC_StopFanControl                		((uint16_t)0x5C)
-#define PPSMC_NoDisplay                     		((uint16_t)0x5D)
-#define PPSMC_HasDisplay                    		((uint16_t)0x5E)
-#define PPSMC_MSG_UVDPowerOFF               		((uint16_t)0x60)
-#define PPSMC_MSG_UVDPowerON                		((uint16_t)0x61)
-#define PPSMC_MSG_EnableULV                 		((uint16_t)0x62)
-#define PPSMC_MSG_DisableULV                		((uint16_t)0x63)
-#define PPSMC_MSG_EnterULV                  		((uint16_t)0x64)
-#define PPSMC_MSG_ExitULV                   		((uint16_t)0x65)
-#define PPSMC_PowerShiftActive              		((uint16_t)0x6A)
-#define PPSMC_PowerShiftInactive            		((uint16_t)0x6B)
-#define PPSMC_OCPActive                     		((uint16_t)0x6C)
-#define PPSMC_OCPInactive                   		((uint16_t)0x6D)
-#define PPSMC_CACLongTermAvgEnable          		((uint16_t)0x6E)
-#define PPSMC_CACLongTermAvgDisable         		((uint16_t)0x6F)
-#define PPSMC_MSG_InferredStateSweep_Start  		((uint16_t)0x70)
-#define PPSMC_MSG_InferredStateSweep_Stop   		((uint16_t)0x71)
-#define PPSMC_MSG_SwitchToLowestInfState    		((uint16_t)0x72)
-#define PPSMC_MSG_SwitchToNonInfState       		((uint16_t)0x73)
-#define PPSMC_MSG_AllStateSweep_Start       		((uint16_t)0x74)
-#define PPSMC_MSG_AllStateSweep_Stop        		((uint16_t)0x75)
-#define PPSMC_MSG_SwitchNextLowerInfState   		((uint16_t)0x76)
-#define PPSMC_MSG_SwitchNextHigherInfState  		((uint16_t)0x77)
-#define PPSMC_MSG_MclkRetrainingTest        		((uint16_t)0x78)
-#define PPSMC_MSG_ForceTDPClamping          		((uint16_t)0x79)
-#define PPSMC_MSG_CollectCAC_PowerCorreln   		((uint16_t)0x7A)
-#define PPSMC_MSG_CollectCAC_WeightCalib    		((uint16_t)0x7B)
-#define PPSMC_MSG_CollectCAC_SQonly         		((uint16_t)0x7C)
-#define PPSMC_MSG_CollectCAC_TemperaturePwr 		((uint16_t)0x7D)
-#define PPSMC_MSG_ExtremitiesTest_Start     		((uint16_t)0x7E)
-#define PPSMC_MSG_ExtremitiesTest_Stop      		((uint16_t)0x7F)
-#define PPSMC_FlushDataCache                		((uint16_t)0x80)
-#define PPSMC_FlushInstrCache               		((uint16_t)0x81)
-#define PPSMC_MSG_SetEnabledLevels          		((uint16_t)0x82)
-#define PPSMC_MSG_SetForcedLevels           		((uint16_t)0x83)
-#define PPSMC_MSG_ResetToDefaults           		((uint16_t)0x84)
-#define PPSMC_MSG_SetForcedLevelsAndJump    		((uint16_t)0x85)
-#define PPSMC_MSG_SetCACHistoryMode         		((uint16_t)0x86)
-#define PPSMC_MSG_EnableDTE                 		((uint16_t)0x87)
-#define PPSMC_MSG_DisableDTE                		((uint16_t)0x88)
-#define PPSMC_MSG_SmcSpaceSetAddress        		((uint16_t)0x89)
-#define PPSMC_MSG_SmcSpaceWriteDWordInc     		((uint16_t)0x8A)
-#define PPSMC_MSG_SmcSpaceWriteWordInc      		((uint16_t)0x8B)
-#define PPSMC_MSG_SmcSpaceWriteByteInc      		((uint16_t)0x8C)
-
-#define PPSMC_MSG_BREAK                     		((uint16_t)0xF8)
-
-#define PPSMC_MSG_Test                      		((uint16_t)0x100)
-#define PPSMC_MSG_DRV_DRAM_ADDR_HI            		((uint16_t)0x250)
-#define PPSMC_MSG_DRV_DRAM_ADDR_LO            		((uint16_t)0x251)
-#define PPSMC_MSG_SMU_DRAM_ADDR_HI            		((uint16_t)0x252)
-#define PPSMC_MSG_SMU_DRAM_ADDR_LO            		((uint16_t)0x253)
-#define PPSMC_MSG_LoadUcodes                  		((uint16_t)0x254)
-
-typedef uint16_t PPSMC_Msg;
-
-#define PPSMC_EVENT_STATUS_THERMAL          		0x00000001
-#define PPSMC_EVENT_STATUS_REGULATORHOT     		0x00000002
-#define PPSMC_EVENT_STATUS_DC               		0x00000004
-#define PPSMC_EVENT_STATUS_GPIO17           		0x00000008
-
-#pragma pack(pop)
-
-#endif
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/amd/amdgpu/fiji_smc.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/amdgpu/fiji_smc.c
@@ -25,7 +25,7 @@
 #include "drmP.h"
 #include "amdgpu.h"
 #include "fiji_ppsmc.h"
-#include "fiji_smumgr.h"
+#include "fiji_smum.h"
 #include "smu_ucode_xfer_vi.h"
 #include "amdgpu_ucode.h"
 
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/amdgpu/fiji_smum.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2014 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#ifndef FIJI_SMUMGR_H
+#define FIJI_SMUMGR_H
+
+#include "fiji_ppsmc.h"
+
+int fiji_smu_init(struct amdgpu_device *adev);
+int fiji_smu_fini(struct amdgpu_device *adev);
+int fiji_smu_start(struct amdgpu_device *adev);
+
+struct fiji_smu_private_data
+{
+	uint8_t *header;
+	uint32_t smu_buffer_addr_high;
+	uint32_t smu_buffer_addr_low;
+	uint32_t header_addr_high;
+	uint32_t header_addr_low;
+};
+
+#endif
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/amd/amdgpu/fiji_smumgr.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright 2014 Advanced Micro Devices, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- */
-
-#ifndef FIJI_SMUMGR_H
-#define FIJI_SMUMGR_H
-
-#include "fiji_ppsmc.h"
-
-int fiji_smu_init(struct amdgpu_device *adev);
-int fiji_smu_fini(struct amdgpu_device *adev);
-int fiji_smu_start(struct amdgpu_device *adev);
-
-struct fiji_smu_private_data
-{
-	uint8_t *header;
-	uint32_t smu_buffer_addr_high;
-	uint32_t smu_buffer_addr_low;
-	uint32_t header_addr_high;
-	uint32_t header_addr_low;
-};
-
-#endif
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c
@@ -3628,6 +3628,19 @@ static void gfx_v7_0_ring_emit_vm_flush(
 					unsigned vm_id, uint64_t pd_addr)
 {
 	int usepfp = (ring->type == AMDGPU_RING_TYPE_GFX);
+	uint32_t seq = ring->fence_drv.sync_seq[ring->idx];
+	uint64_t addr = ring->fence_drv.gpu_addr;
+
+	amdgpu_ring_write(ring, PACKET3(PACKET3_WAIT_REG_MEM, 5));
+	amdgpu_ring_write(ring, (WAIT_REG_MEM_MEM_SPACE(1) | /* memory */
+				 WAIT_REG_MEM_FUNCTION(3) | /* equal */
+				 WAIT_REG_MEM_ENGINE(usepfp)));   /* pfp or me */
+	amdgpu_ring_write(ring, addr & 0xfffffffc);
+	amdgpu_ring_write(ring, upper_32_bits(addr) & 0xffffffff);
+	amdgpu_ring_write(ring, seq);
+	amdgpu_ring_write(ring, 0xffffffff);
+	amdgpu_ring_write(ring, 4); /* poll interval */
+
 	if (usepfp) {
 		/* synce CE with ME to prevent CE fetch CEIB before context switch done */
 		amdgpu_ring_write(ring, PACKET3(PACKET3_SWITCH_BUFFER, 0));
@@ -4109,7 +4122,7 @@ static void gfx_v7_0_enable_cgcg(struct
 
 	orig = data = RREG32(mmRLC_CGCG_CGLS_CTRL);
 
-	if (enable && (adev->cg_flags & AMDGPU_CG_SUPPORT_GFX_CGCG)) {
+	if (enable && (adev->cg_flags & AMD_CG_SUPPORT_GFX_CGCG)) {
 		gfx_v7_0_enable_gui_idle_interrupt(adev, true);
 
 		tmp = gfx_v7_0_halt_rlc(adev);
@@ -4147,9 +4160,9 @@ static void gfx_v7_0_enable_mgcg(struct
 {
 	u32 data, orig, tmp = 0;
 
-	if (enable && (adev->cg_flags & AMDGPU_CG_SUPPORT_GFX_MGCG)) {
-		if (adev->cg_flags & AMDGPU_CG_SUPPORT_GFX_MGLS) {
-			if (adev->cg_flags & AMDGPU_CG_SUPPORT_GFX_CP_LS) {
+	if (enable && (adev->cg_flags & AMD_CG_SUPPORT_GFX_MGCG)) {
+		if (adev->cg_flags & AMD_CG_SUPPORT_GFX_MGLS) {
+			if (adev->cg_flags & AMD_CG_SUPPORT_GFX_CP_LS) {
 				orig = data = RREG32(mmCP_MEM_SLP_CNTL);
 				data |= CP_MEM_SLP_CNTL__CP_MEM_LS_EN_MASK;
 				if (orig != data)
@@ -4176,14 +4189,14 @@ static void gfx_v7_0_enable_mgcg(struct
 
 		gfx_v7_0_update_rlc(adev, tmp);
 
-		if (adev->cg_flags & AMDGPU_CG_SUPPORT_GFX_CGTS) {
+		if (adev->cg_flags & AMD_CG_SUPPORT_GFX_CGTS) {
 			orig = data = RREG32(mmCGTS_SM_CTRL_REG);
 			data &= ~CGTS_SM_CTRL_REG__SM_MODE_MASK;
 			data |= (0x2 << CGTS_SM_CTRL_REG__SM_MODE__SHIFT);
 			data |= CGTS_SM_CTRL_REG__SM_MODE_ENABLE_MASK;
 			data &= ~CGTS_SM_CTRL_REG__OVERRIDE_MASK;
-			if ((adev->cg_flags & AMDGPU_CG_SUPPORT_GFX_MGLS) &&
-			    (adev->cg_flags & AMDGPU_CG_SUPPORT_GFX_CGTS_LS))
+			if ((adev->cg_flags & AMD_CG_SUPPORT_GFX_MGLS) &&
+			    (adev->cg_flags & AMD_CG_SUPPORT_GFX_CGTS_LS))
 				data &= ~CGTS_SM_CTRL_REG__LS_OVERRIDE_MASK;
 			data &= ~CGTS_SM_CTRL_REG__ON_MONITOR_ADD_MASK;
 			data |= CGTS_SM_CTRL_REG__ON_MONITOR_ADD_EN_MASK;
@@ -4249,7 +4262,7 @@ static void gfx_v7_0_enable_sclk_slowdow
 	u32 data, orig;
 
 	orig = data = RREG32(mmRLC_PG_CNTL);
-	if (enable && (adev->pg_flags & AMDGPU_PG_SUPPORT_RLC_SMU_HS))
+	if (enable && (adev->pg_flags & AMD_PG_SUPPORT_RLC_SMU_HS))
 		data |= RLC_PG_CNTL__SMU_CLK_SLOWDOWN_ON_PU_ENABLE_MASK;
 	else
 		data &= ~RLC_PG_CNTL__SMU_CLK_SLOWDOWN_ON_PU_ENABLE_MASK;
@@ -4263,7 +4276,7 @@ static void gfx_v7_0_enable_sclk_slowdow
 	u32 data, orig;
 
 	orig = data = RREG32(mmRLC_PG_CNTL);
-	if (enable && (adev->pg_flags & AMDGPU_PG_SUPPORT_RLC_SMU_HS))
+	if (enable && (adev->pg_flags & AMD_PG_SUPPORT_RLC_SMU_HS))
 		data |= RLC_PG_CNTL__SMU_CLK_SLOWDOWN_ON_PD_ENABLE_MASK;
 	else
 		data &= ~RLC_PG_CNTL__SMU_CLK_SLOWDOWN_ON_PD_ENABLE_MASK;
@@ -4276,7 +4289,7 @@ static void gfx_v7_0_enable_cp_pg(struct
 	u32 data, orig;
 
 	orig = data = RREG32(mmRLC_PG_CNTL);
-	if (enable && (adev->pg_flags & AMDGPU_PG_SUPPORT_CP))
+	if (enable && (adev->pg_flags & AMD_PG_SUPPORT_CP))
 		data &= ~0x8000;
 	else
 		data |= 0x8000;
@@ -4289,7 +4302,7 @@ static void gfx_v7_0_enable_gds_pg(struc
 	u32 data, orig;
 
 	orig = data = RREG32(mmRLC_PG_CNTL);
-	if (enable && (adev->pg_flags & AMDGPU_PG_SUPPORT_GDS))
+	if (enable && (adev->pg_flags & AMD_PG_SUPPORT_GDS))
 		data &= ~0x2000;
 	else
 		data |= 0x2000;
@@ -4370,7 +4383,7 @@ static void gfx_v7_0_enable_gfx_cgpg(str
 {
 	u32 data, orig;
 
-	if (enable && (adev->pg_flags & AMDGPU_PG_SUPPORT_GFX_PG)) {
+	if (enable && (adev->pg_flags & AMD_PG_SUPPORT_GFX_PG)) {
 		orig = data = RREG32(mmRLC_PG_CNTL);
 		data |= RLC_PG_CNTL__GFX_POWER_GATING_ENABLE_MASK;
 		if (orig != data)
@@ -4442,7 +4455,7 @@ static void gfx_v7_0_enable_gfx_static_m
 	u32 data, orig;
 
 	orig = data = RREG32(mmRLC_PG_CNTL);
-	if (enable && (adev->pg_flags & AMDGPU_PG_SUPPORT_GFX_SMG))
+	if (enable && (adev->pg_flags & AMD_PG_SUPPORT_GFX_SMG))
 		data |= RLC_PG_CNTL__STATIC_PER_CU_PG_ENABLE_MASK;
 	else
 		data &= ~RLC_PG_CNTL__STATIC_PER_CU_PG_ENABLE_MASK;
@@ -4456,7 +4469,7 @@ static void gfx_v7_0_enable_gfx_dynamic_
 	u32 data, orig;
 
 	orig = data = RREG32(mmRLC_PG_CNTL);
-	if (enable && (adev->pg_flags & AMDGPU_PG_SUPPORT_GFX_DMG))
+	if (enable && (adev->pg_flags & AMD_PG_SUPPORT_GFX_DMG))
 		data |= RLC_PG_CNTL__DYN_PER_CU_PG_ENABLE_MASK;
 	else
 		data &= ~RLC_PG_CNTL__DYN_PER_CU_PG_ENABLE_MASK;
@@ -4623,15 +4636,15 @@ static void gfx_v7_0_get_csb_buffer(stru
 
 static void gfx_v7_0_init_pg(struct amdgpu_device *adev)
 {
-	if (adev->pg_flags & (AMDGPU_PG_SUPPORT_GFX_PG |
-			      AMDGPU_PG_SUPPORT_GFX_SMG |
-			      AMDGPU_PG_SUPPORT_GFX_DMG |
-			      AMDGPU_PG_SUPPORT_CP |
-			      AMDGPU_PG_SUPPORT_GDS |
-			      AMDGPU_PG_SUPPORT_RLC_SMU_HS)) {
+	if (adev->pg_flags & (AMD_PG_SUPPORT_GFX_PG |
+			      AMD_PG_SUPPORT_GFX_SMG |
+			      AMD_PG_SUPPORT_GFX_DMG |
+			      AMD_PG_SUPPORT_CP |
+			      AMD_PG_SUPPORT_GDS |
+			      AMD_PG_SUPPORT_RLC_SMU_HS)) {
 		gfx_v7_0_enable_sclk_slowdown_on_pu(adev, true);
 		gfx_v7_0_enable_sclk_slowdown_on_pd(adev, true);
-		if (adev->pg_flags & AMDGPU_PG_SUPPORT_GFX_PG) {
+		if (adev->pg_flags & AMD_PG_SUPPORT_GFX_PG) {
 			gfx_v7_0_init_gfx_cgpg(adev);
 			gfx_v7_0_enable_cp_pg(adev, true);
 			gfx_v7_0_enable_gds_pg(adev, true);
@@ -4643,14 +4656,14 @@ static void gfx_v7_0_init_pg(struct amdg
 
 static void gfx_v7_0_fini_pg(struct amdgpu_device *adev)
 {
-	if (adev->pg_flags & (AMDGPU_PG_SUPPORT_GFX_PG |
-			      AMDGPU_PG_SUPPORT_GFX_SMG |
-			      AMDGPU_PG_SUPPORT_GFX_DMG |
-			      AMDGPU_PG_SUPPORT_CP |
-			      AMDGPU_PG_SUPPORT_GDS |
-			      AMDGPU_PG_SUPPORT_RLC_SMU_HS)) {
+	if (adev->pg_flags & (AMD_PG_SUPPORT_GFX_PG |
+			      AMD_PG_SUPPORT_GFX_SMG |
+			      AMD_PG_SUPPORT_GFX_DMG |
+			      AMD_PG_SUPPORT_CP |
+			      AMD_PG_SUPPORT_GDS |
+			      AMD_PG_SUPPORT_RLC_SMU_HS)) {
 		gfx_v7_0_update_gfx_pg(adev, false);
-		if (adev->pg_flags & AMDGPU_PG_SUPPORT_GFX_PG) {
+		if (adev->pg_flags & AMD_PG_SUPPORT_GFX_PG) {
 			gfx_v7_0_enable_cp_pg(adev, false);
 			gfx_v7_0_enable_gds_pg(adev, false);
 		}
@@ -4738,6 +4751,22 @@ static int gfx_v7_0_early_init(void *han
 	return 0;
 }
 
+static int gfx_v7_0_late_init(void *handle)
+{
+	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
+	int r;
+
+	r = amdgpu_irq_get(adev, &adev->gfx.priv_reg_irq, 0);
+	if (r)
+		return r;
+
+	r = amdgpu_irq_get(adev, &adev->gfx.priv_inst_irq, 0);
+	if (r)
+		return r;
+
+	return 0;
+}
+
 static int gfx_v7_0_sw_init(void *handle)
 {
 	struct amdgpu_ring *ring;
@@ -4890,6 +4919,8 @@ static int gfx_v7_0_hw_fini(void *handle
 {
 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
 
+	amdgpu_irq_put(adev, &adev->gfx.priv_reg_irq, 0);
+	amdgpu_irq_put(adev, &adev->gfx.priv_inst_irq, 0);
 	gfx_v7_0_cp_enable(adev, false);
 	gfx_v7_0_rlc_stop(adev);
 	gfx_v7_0_fini_pg(adev);
@@ -5450,7 +5481,7 @@ static int gfx_v7_0_eop_irq(struct amdgp
 	case 2:
 		for (i = 0; i < adev->gfx.num_compute_rings; i++) {
 			ring = &adev->gfx.compute_ring[i];
-			if ((ring->me == me_id) & (ring->pipe == pipe_id))
+			if ((ring->me == me_id) && (ring->pipe == pipe_id))
 				amdgpu_fence_process(ring);
 		}
 		break;
@@ -5509,14 +5540,14 @@ static int gfx_v7_0_set_powergating_stat
 	if (state == AMD_PG_STATE_GATE)
 		gate = true;
 
-	if (adev->pg_flags & (AMDGPU_PG_SUPPORT_GFX_PG |
-			      AMDGPU_PG_SUPPORT_GFX_SMG |
-			      AMDGPU_PG_SUPPORT_GFX_DMG |
-			      AMDGPU_PG_SUPPORT_CP |
-			      AMDGPU_PG_SUPPORT_GDS |
-			      AMDGPU_PG_SUPPORT_RLC_SMU_HS)) {
+	if (adev->pg_flags & (AMD_PG_SUPPORT_GFX_PG |
+			      AMD_PG_SUPPORT_GFX_SMG |
+			      AMD_PG_SUPPORT_GFX_DMG |
+			      AMD_PG_SUPPORT_CP |
+			      AMD_PG_SUPPORT_GDS |
+			      AMD_PG_SUPPORT_RLC_SMU_HS)) {
 		gfx_v7_0_update_gfx_pg(adev, gate);
-		if (adev->pg_flags & AMDGPU_PG_SUPPORT_GFX_PG) {
+		if (adev->pg_flags & AMD_PG_SUPPORT_GFX_PG) {
 			gfx_v7_0_enable_cp_pg(adev, gate);
 			gfx_v7_0_enable_gds_pg(adev, gate);
 		}
@@ -5527,7 +5558,7 @@ static int gfx_v7_0_set_powergating_stat
 
 const struct amd_ip_funcs gfx_v7_0_ip_funcs = {
 	.early_init = gfx_v7_0_early_init,
-	.late_init = NULL,
+	.late_init = gfx_v7_0_late_init,
 	.sw_init = gfx_v7_0_sw_init,
 	.sw_fini = gfx_v7_0_sw_fini,
 	.hw_init = gfx_v7_0_hw_init,
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c
@@ -66,6 +66,27 @@
 #define MACRO_TILE_ASPECT(x)				((x) << GB_MACROTILE_MODE0__MACRO_TILE_ASPECT__SHIFT)
 #define NUM_BANKS(x)					((x) << GB_MACROTILE_MODE0__NUM_BANKS__SHIFT)
 
+#define RLC_CGTT_MGCG_OVERRIDE__CPF_MASK            0x00000001L
+#define RLC_CGTT_MGCG_OVERRIDE__RLC_MASK            0x00000002L
+#define RLC_CGTT_MGCG_OVERRIDE__MGCG_MASK           0x00000004L
+#define RLC_CGTT_MGCG_OVERRIDE__CGCG_MASK           0x00000008L
+#define RLC_CGTT_MGCG_OVERRIDE__CGLS_MASK           0x00000010L
+#define RLC_CGTT_MGCG_OVERRIDE__GRBM_MASK           0x00000020L
+
+/* BPM SERDES CMD */
+#define SET_BPM_SERDES_CMD    1
+#define CLE_BPM_SERDES_CMD    0
+
+/* BPM Register Address*/
+enum {
+	BPM_REG_CGLS_EN = 0,        /* Enable/Disable CGLS */
+	BPM_REG_CGLS_ON,            /* ON/OFF CGLS: shall be controlled by RLC FW */
+	BPM_REG_CGCG_OVERRIDE,      /* Set/Clear CGCG Override */
+	BPM_REG_MGCG_OVERRIDE,      /* Set/Clear MGCG Override */
+	BPM_REG_FGCG_OVERRIDE,      /* Set/Clear FGCG Override */
+	BPM_REG_FGCG_MAX
+};
+
 MODULE_FIRMWARE("amdgpu/carrizo_ce.bin");
 MODULE_FIRMWARE("amdgpu/carrizo_pfp.bin");
 MODULE_FIRMWARE("amdgpu/carrizo_me.bin");
@@ -90,7 +111,6 @@ MODULE_FIRMWARE("amdgpu/topaz_ce.bin");
 MODULE_FIRMWARE("amdgpu/topaz_pfp.bin");
 MODULE_FIRMWARE("amdgpu/topaz_me.bin");
 MODULE_FIRMWARE("amdgpu/topaz_mec.bin");
-MODULE_FIRMWARE("amdgpu/topaz_mec2.bin");
 MODULE_FIRMWARE("amdgpu/topaz_rlc.bin");
 
 MODULE_FIRMWARE("amdgpu/fiji_ce.bin");
@@ -807,7 +827,8 @@ static int gfx_v8_0_init_microcode(struc
 	adev->gfx.mec_fw_version = le32_to_cpu(cp_hdr->header.ucode_version);
 	adev->gfx.mec_feature_version = le32_to_cpu(cp_hdr->ucode_feature_version);
 
-	if (adev->asic_type != CHIP_STONEY) {
+	if ((adev->asic_type != CHIP_STONEY) &&
+	    (adev->asic_type != CHIP_TOPAZ)) {
 		snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_mec2.bin", chip_name);
 		err = request_firmware(&adev->gfx.mec2_fw, fw_name, adev->dev);
 		if (!err) {
@@ -964,6 +985,322 @@ static int gfx_v8_0_mec_init(struct amdg
 	return 0;
 }
 
+static const u32 vgpr_init_compute_shader[] =
+{
+	0x7e000209, 0x7e020208,
+	0x7e040207, 0x7e060206,
+	0x7e080205, 0x7e0a0204,
+	0x7e0c0203, 0x7e0e0202,
+	0x7e100201, 0x7e120200,
+	0x7e140209, 0x7e160208,
+	0x7e180207, 0x7e1a0206,
+	0x7e1c0205, 0x7e1e0204,
+	0x7e200203, 0x7e220202,
+	0x7e240201, 0x7e260200,
+	0x7e280209, 0x7e2a0208,
+	0x7e2c0207, 0x7e2e0206,
+	0x7e300205, 0x7e320204,
+	0x7e340203, 0x7e360202,
+	0x7e380201, 0x7e3a0200,
+	0x7e3c0209, 0x7e3e0208,
+	0x7e400207, 0x7e420206,
+	0x7e440205, 0x7e460204,
+	0x7e480203, 0x7e4a0202,
+	0x7e4c0201, 0x7e4e0200,
+	0x7e500209, 0x7e520208,
+	0x7e540207, 0x7e560206,
+	0x7e580205, 0x7e5a0204,
+	0x7e5c0203, 0x7e5e0202,
+	0x7e600201, 0x7e620200,
+	0x7e640209, 0x7e660208,
+	0x7e680207, 0x7e6a0206,
+	0x7e6c0205, 0x7e6e0204,
+	0x7e700203, 0x7e720202,
+	0x7e740201, 0x7e760200,
+	0x7e780209, 0x7e7a0208,
+	0x7e7c0207, 0x7e7e0206,
+	0xbf8a0000, 0xbf810000,
+};
+
+static const u32 sgpr_init_compute_shader[] =
+{
+	0xbe8a0100, 0xbe8c0102,
+	0xbe8e0104, 0xbe900106,
+	0xbe920108, 0xbe940100,
+	0xbe960102, 0xbe980104,
+	0xbe9a0106, 0xbe9c0108,
+	0xbe9e0100, 0xbea00102,
+	0xbea20104, 0xbea40106,
+	0xbea60108, 0xbea80100,
+	0xbeaa0102, 0xbeac0104,
+	0xbeae0106, 0xbeb00108,
+	0xbeb20100, 0xbeb40102,
+	0xbeb60104, 0xbeb80106,
+	0xbeba0108, 0xbebc0100,
+	0xbebe0102, 0xbec00104,
+	0xbec20106, 0xbec40108,
+	0xbec60100, 0xbec80102,
+	0xbee60004, 0xbee70005,
+	0xbeea0006, 0xbeeb0007,
+	0xbee80008, 0xbee90009,
+	0xbefc0000, 0xbf8a0000,
+	0xbf810000, 0x00000000,
+};
+
+static const u32 vgpr_init_regs[] =
+{
+	mmCOMPUTE_STATIC_THREAD_MGMT_SE0, 0xffffffff,
+	mmCOMPUTE_RESOURCE_LIMITS, 0,
+	mmCOMPUTE_NUM_THREAD_X, 256*4,
+	mmCOMPUTE_NUM_THREAD_Y, 1,
+	mmCOMPUTE_NUM_THREAD_Z, 1,
+	mmCOMPUTE_PGM_RSRC2, 20,
+	mmCOMPUTE_USER_DATA_0, 0xedcedc00,
+	mmCOMPUTE_USER_DATA_1, 0xedcedc01,
+	mmCOMPUTE_USER_DATA_2, 0xedcedc02,
+	mmCOMPUTE_USER_DATA_3, 0xedcedc03,
+	mmCOMPUTE_USER_DATA_4, 0xedcedc04,
+	mmCOMPUTE_USER_DATA_5, 0xedcedc05,
+	mmCOMPUTE_USER_DATA_6, 0xedcedc06,
+	mmCOMPUTE_USER_DATA_7, 0xedcedc07,
+	mmCOMPUTE_USER_DATA_8, 0xedcedc08,
+	mmCOMPUTE_USER_DATA_9, 0xedcedc09,
+};
+
+static const u32 sgpr1_init_regs[] =
+{
+	mmCOMPUTE_STATIC_THREAD_MGMT_SE0, 0x0f,
+	mmCOMPUTE_RESOURCE_LIMITS, 0x1000000,
+	mmCOMPUTE_NUM_THREAD_X, 256*5,
+	mmCOMPUTE_NUM_THREAD_Y, 1,
+	mmCOMPUTE_NUM_THREAD_Z, 1,
+	mmCOMPUTE_PGM_RSRC2, 20,
+	mmCOMPUTE_USER_DATA_0, 0xedcedc00,
+	mmCOMPUTE_USER_DATA_1, 0xedcedc01,
+	mmCOMPUTE_USER_DATA_2, 0xedcedc02,
+	mmCOMPUTE_USER_DATA_3, 0xedcedc03,
+	mmCOMPUTE_USER_DATA_4, 0xedcedc04,
+	mmCOMPUTE_USER_DATA_5, 0xedcedc05,
+	mmCOMPUTE_USER_DATA_6, 0xedcedc06,
+	mmCOMPUTE_USER_DATA_7, 0xedcedc07,
+	mmCOMPUTE_USER_DATA_8, 0xedcedc08,
+	mmCOMPUTE_USER_DATA_9, 0xedcedc09,
+};
+
+static const u32 sgpr2_init_regs[] =
+{
+	mmCOMPUTE_STATIC_THREAD_MGMT_SE0, 0xf0,
+	mmCOMPUTE_RESOURCE_LIMITS, 0x1000000,
+	mmCOMPUTE_NUM_THREAD_X, 256*5,
+	mmCOMPUTE_NUM_THREAD_Y, 1,
+	mmCOMPUTE_NUM_THREAD_Z, 1,
+	mmCOMPUTE_PGM_RSRC2, 20,
+	mmCOMPUTE_USER_DATA_0, 0xedcedc00,
+	mmCOMPUTE_USER_DATA_1, 0xedcedc01,
+	mmCOMPUTE_USER_DATA_2, 0xedcedc02,
+	mmCOMPUTE_USER_DATA_3, 0xedcedc03,
+	mmCOMPUTE_USER_DATA_4, 0xedcedc04,
+	mmCOMPUTE_USER_DATA_5, 0xedcedc05,
+	mmCOMPUTE_USER_DATA_6, 0xedcedc06,
+	mmCOMPUTE_USER_DATA_7, 0xedcedc07,
+	mmCOMPUTE_USER_DATA_8, 0xedcedc08,
+	mmCOMPUTE_USER_DATA_9, 0xedcedc09,
+};
+
+static const u32 sec_ded_counter_registers[] =
+{
+	mmCPC_EDC_ATC_CNT,
+	mmCPC_EDC_SCRATCH_CNT,
+	mmCPC_EDC_UCODE_CNT,
+	mmCPF_EDC_ATC_CNT,
+	mmCPF_EDC_ROQ_CNT,
+	mmCPF_EDC_TAG_CNT,
+	mmCPG_EDC_ATC_CNT,
+	mmCPG_EDC_DMA_CNT,
+	mmCPG_EDC_TAG_CNT,
+	mmDC_EDC_CSINVOC_CNT,
+	mmDC_EDC_RESTORE_CNT,
+	mmDC_EDC_STATE_CNT,
+	mmGDS_EDC_CNT,
+	mmGDS_EDC_GRBM_CNT,
+	mmGDS_EDC_OA_DED,
+	mmSPI_EDC_CNT,
+	mmSQC_ATC_EDC_GATCL1_CNT,
+	mmSQC_EDC_CNT,
+	mmSQ_EDC_DED_CNT,
+	mmSQ_EDC_INFO,
+	mmSQ_EDC_SEC_CNT,
+	mmTCC_EDC_CNT,
+	mmTCP_ATC_EDC_GATCL1_CNT,
+	mmTCP_EDC_CNT,
+	mmTD_EDC_CNT
+};
+
+static int gfx_v8_0_do_edc_gpr_workarounds(struct amdgpu_device *adev)
+{
+	struct amdgpu_ring *ring = &adev->gfx.compute_ring[0];
+	struct amdgpu_ib ib;
+	struct fence *f = NULL;
+	int r, i;
+	u32 tmp;
+	unsigned total_size, vgpr_offset, sgpr_offset;
+	u64 gpu_addr;
+
+	/* only supported on CZ */
+	if (adev->asic_type != CHIP_CARRIZO)
+		return 0;
+
+	/* bail if the compute ring is not ready */
+	if (!ring->ready)
+		return 0;
+
+	tmp = RREG32(mmGB_EDC_MODE);
+	WREG32(mmGB_EDC_MODE, 0);
+
+	total_size =
+		(((ARRAY_SIZE(vgpr_init_regs) / 2) * 3) + 4 + 5 + 2) * 4;
+	total_size +=
+		(((ARRAY_SIZE(sgpr1_init_regs) / 2) * 3) + 4 + 5 + 2) * 4;
+	total_size +=
+		(((ARRAY_SIZE(sgpr2_init_regs) / 2) * 3) + 4 + 5 + 2) * 4;
+	total_size = ALIGN(total_size, 256);
+	vgpr_offset = total_size;
+	total_size += ALIGN(sizeof(vgpr_init_compute_shader), 256);
+	sgpr_offset = total_size;
+	total_size += sizeof(sgpr_init_compute_shader);
+
+	/* allocate an indirect buffer to put the commands in */
+	memset(&ib, 0, sizeof(ib));
+	r = amdgpu_ib_get(ring, NULL, total_size, &ib);
+	if (r) {
+		DRM_ERROR("amdgpu: failed to get ib (%d).\n", r);
+		return r;
+	}
+
+	/* load the compute shaders */
+	for (i = 0; i < ARRAY_SIZE(vgpr_init_compute_shader); i++)
+		ib.ptr[i + (vgpr_offset / 4)] = vgpr_init_compute_shader[i];
+
+	for (i = 0; i < ARRAY_SIZE(sgpr_init_compute_shader); i++)
+		ib.ptr[i + (sgpr_offset / 4)] = sgpr_init_compute_shader[i];
+
+	/* init the ib length to 0 */
+	ib.length_dw = 0;
+
+	/* VGPR */
+	/* write the register state for the compute dispatch */
+	for (i = 0; i < ARRAY_SIZE(vgpr_init_regs); i += 2) {
+		ib.ptr[ib.length_dw++] = PACKET3(PACKET3_SET_SH_REG, 1);
+		ib.ptr[ib.length_dw++] = vgpr_init_regs[i] - PACKET3_SET_SH_REG_START;
+		ib.ptr[ib.length_dw++] = vgpr_init_regs[i + 1];
+	}
+	/* write the shader start address: mmCOMPUTE_PGM_LO, mmCOMPUTE_PGM_HI */
+	gpu_addr = (ib.gpu_addr + (u64)vgpr_offset) >> 8;
+	ib.ptr[ib.length_dw++] = PACKET3(PACKET3_SET_SH_REG, 2);
+	ib.ptr[ib.length_dw++] = mmCOMPUTE_PGM_LO - PACKET3_SET_SH_REG_START;
+	ib.ptr[ib.length_dw++] = lower_32_bits(gpu_addr);
+	ib.ptr[ib.length_dw++] = upper_32_bits(gpu_addr);
+
+	/* write dispatch packet */
+	ib.ptr[ib.length_dw++] = PACKET3(PACKET3_DISPATCH_DIRECT, 3);
+	ib.ptr[ib.length_dw++] = 8; /* x */
+	ib.ptr[ib.length_dw++] = 1; /* y */
+	ib.ptr[ib.length_dw++] = 1; /* z */
+	ib.ptr[ib.length_dw++] =
+		REG_SET_FIELD(0, COMPUTE_DISPATCH_INITIATOR, COMPUTE_SHADER_EN, 1);
+
+	/* write CS partial flush packet */
+	ib.ptr[ib.length_dw++] = PACKET3(PACKET3_EVENT_WRITE, 0);
+	ib.ptr[ib.length_dw++] = EVENT_TYPE(7) | EVENT_INDEX(4);
+
+	/* SGPR1 */
+	/* write the register state for the compute dispatch */
+	for (i = 0; i < ARRAY_SIZE(sgpr1_init_regs); i += 2) {
+		ib.ptr[ib.length_dw++] = PACKET3(PACKET3_SET_SH_REG, 1);
+		ib.ptr[ib.length_dw++] = sgpr1_init_regs[i] - PACKET3_SET_SH_REG_START;
+		ib.ptr[ib.length_dw++] = sgpr1_init_regs[i + 1];
+	}
+	/* write the shader start address: mmCOMPUTE_PGM_LO, mmCOMPUTE_PGM_HI */
+	gpu_addr = (ib.gpu_addr + (u64)sgpr_offset) >> 8;
+	ib.ptr[ib.length_dw++] = PACKET3(PACKET3_SET_SH_REG, 2);
+	ib.ptr[ib.length_dw++] = mmCOMPUTE_PGM_LO - PACKET3_SET_SH_REG_START;
+	ib.ptr[ib.length_dw++] = lower_32_bits(gpu_addr);
+	ib.ptr[ib.length_dw++] = upper_32_bits(gpu_addr);
+
+	/* write dispatch packet */
+	ib.ptr[ib.length_dw++] = PACKET3(PACKET3_DISPATCH_DIRECT, 3);
+	ib.ptr[ib.length_dw++] = 8; /* x */
+	ib.ptr[ib.length_dw++] = 1; /* y */
+	ib.ptr[ib.length_dw++] = 1; /* z */
+	ib.ptr[ib.length_dw++] =
+		REG_SET_FIELD(0, COMPUTE_DISPATCH_INITIATOR, COMPUTE_SHADER_EN, 1);
+
+	/* write CS partial flush packet */
+	ib.ptr[ib.length_dw++] = PACKET3(PACKET3_EVENT_WRITE, 0);
+	ib.ptr[ib.length_dw++] = EVENT_TYPE(7) | EVENT_INDEX(4);
+
+	/* SGPR2 */
+	/* write the register state for the compute dispatch */
+	for (i = 0; i < ARRAY_SIZE(sgpr2_init_regs); i += 2) {
+		ib.ptr[ib.length_dw++] = PACKET3(PACKET3_SET_SH_REG, 1);
+		ib.ptr[ib.length_dw++] = sgpr2_init_regs[i] - PACKET3_SET_SH_REG_START;
+		ib.ptr[ib.length_dw++] = sgpr2_init_regs[i + 1];
+	}
+	/* write the shader start address: mmCOMPUTE_PGM_LO, mmCOMPUTE_PGM_HI */
+	gpu_addr = (ib.gpu_addr + (u64)sgpr_offset) >> 8;
+	ib.ptr[ib.length_dw++] = PACKET3(PACKET3_SET_SH_REG, 2);
+	ib.ptr[ib.length_dw++] = mmCOMPUTE_PGM_LO - PACKET3_SET_SH_REG_START;
+	ib.ptr[ib.length_dw++] = lower_32_bits(gpu_addr);
+	ib.ptr[ib.length_dw++] = upper_32_bits(gpu_addr);
+
+	/* write dispatch packet */
+	ib.ptr[ib.length_dw++] = PACKET3(PACKET3_DISPATCH_DIRECT, 3);
+	ib.ptr[ib.length_dw++] = 8; /* x */
+	ib.ptr[ib.length_dw++] = 1; /* y */
+	ib.ptr[ib.length_dw++] = 1; /* z */
+	ib.ptr[ib.length_dw++] =
+		REG_SET_FIELD(0, COMPUTE_DISPATCH_INITIATOR, COMPUTE_SHADER_EN, 1);
+
+	/* write CS partial flush packet */
+	ib.ptr[ib.length_dw++] = PACKET3(PACKET3_EVENT_WRITE, 0);
+	ib.ptr[ib.length_dw++] = EVENT_TYPE(7) | EVENT_INDEX(4);
+
+	/* shedule the ib on the ring */
+	r = amdgpu_sched_ib_submit_kernel_helper(adev, ring, &ib, 1, NULL,
+						 AMDGPU_FENCE_OWNER_UNDEFINED,
+						 &f);
+	if (r) {
+		DRM_ERROR("amdgpu: ib submit failed (%d).\n", r);
+		goto fail;
+	}
+
+	/* wait for the GPU to finish processing the IB */
+	r = fence_wait(f, false);
+	if (r) {
+		DRM_ERROR("amdgpu: fence wait failed (%d).\n", r);
+		goto fail;
+	}
+
+	tmp = REG_SET_FIELD(tmp, GB_EDC_MODE, DED_MODE, 2);
+	tmp = REG_SET_FIELD(tmp, GB_EDC_MODE, PROP_FED, 1);
+	WREG32(mmGB_EDC_MODE, tmp);
+
+	tmp = RREG32(mmCC_GC_EDC_CONFIG);
+	tmp = REG_SET_FIELD(tmp, CC_GC_EDC_CONFIG, DIS_EDC, 0) | 1;
+	WREG32(mmCC_GC_EDC_CONFIG, tmp);
+
+
+	/* read back registers to clear the counters */
+	for (i = 0; i < ARRAY_SIZE(sec_ded_counter_registers); i++)
+		RREG32(sec_ded_counter_registers[i]);
+
+fail:
+	fence_put(f);
+	amdgpu_ib_free(adev, &ib);
+
+	return r;
+}
+
 static void gfx_v8_0_gpu_early_init(struct amdgpu_device *adev)
 {
 	u32 gb_addr_config;
@@ -2809,7 +3146,7 @@ static void gfx_v8_0_setup_rb(struct amd
 	mutex_lock(&adev->grbm_idx_mutex);
 	for (i = 0; i < se_num; i++) {
 		gfx_v8_0_select_se_sh(adev, i, 0xffffffff);
-		data = 0;
+		data = RREG32(mmPA_SC_RASTER_CONFIG);
 		for (j = 0; j < sh_per_se; j++) {
 			switch (enabled_rbs & 3) {
 			case 0:
@@ -3087,16 +3424,18 @@ static int gfx_v8_0_rlc_resume(struct am
 
 	gfx_v8_0_rlc_reset(adev);
 
-	if (!adev->firmware.smu_load) {
-		/* legacy rlc firmware loading */
-		r = gfx_v8_0_rlc_load_microcode(adev);
-		if (r)
-			return r;
-	} else {
-		r = adev->smu.smumgr_funcs->check_fw_load_finish(adev,
-						AMDGPU_UCODE_ID_RLC_G);
-		if (r)
-			return -EINVAL;
+	if (!adev->pp_enabled) {
+		if (!adev->firmware.smu_load) {
+			/* legacy rlc firmware loading */
+			r = gfx_v8_0_rlc_load_microcode(adev);
+			if (r)
+				return r;
+		} else {
+			r = adev->smu.smumgr_funcs->check_fw_load_finish(adev,
+							AMDGPU_UCODE_ID_RLC_G);
+			if (r)
+				return -EINVAL;
+		}
 	}
 
 	gfx_v8_0_rlc_start(adev);
@@ -3941,6 +4280,11 @@ static int gfx_v8_0_cp_compute_resume(st
 		tmp = REG_SET_FIELD(tmp, CP_HQD_PERSISTENT_STATE, PRELOAD_SIZE, 0x53);
 		WREG32(mmCP_HQD_PERSISTENT_STATE, tmp);
 		mqd->cp_hqd_persistent_state = tmp;
+		if (adev->asic_type == CHIP_STONEY) {
+			tmp = RREG32(mmCP_ME1_PIPE3_INT_CNTL);
+			tmp = REG_SET_FIELD(tmp, CP_ME1_PIPE3_INT_CNTL, GENERIC2_INT_ENABLE, 1);
+			WREG32(mmCP_ME1_PIPE3_INT_CNTL, tmp);
+		}
 
 		/* activate the queue */
 		mqd->cp_hqd_active = 1;
@@ -3982,35 +4326,43 @@ static int gfx_v8_0_cp_resume(struct amd
 	if (!(adev->flags & AMD_IS_APU))
 		gfx_v8_0_enable_gui_idle_interrupt(adev, false);
 
-	if (!adev->firmware.smu_load) {
-		/* legacy firmware loading */
-		r = gfx_v8_0_cp_gfx_load_microcode(adev);
-		if (r)
-			return r;
-
-		r = gfx_v8_0_cp_compute_load_microcode(adev);
-		if (r)
-			return r;
-	} else {
-		r = adev->smu.smumgr_funcs->check_fw_load_finish(adev,
-						AMDGPU_UCODE_ID_CP_CE);
-		if (r)
-			return -EINVAL;
-
-		r = adev->smu.smumgr_funcs->check_fw_load_finish(adev,
-						AMDGPU_UCODE_ID_CP_PFP);
-		if (r)
-			return -EINVAL;
-
-		r = adev->smu.smumgr_funcs->check_fw_load_finish(adev,
-						AMDGPU_UCODE_ID_CP_ME);
-		if (r)
-			return -EINVAL;
+	if (!adev->pp_enabled) {
+		if (!adev->firmware.smu_load) {
+			/* legacy firmware loading */
+			r = gfx_v8_0_cp_gfx_load_microcode(adev);
+			if (r)
+				return r;
 
-		r = adev->smu.smumgr_funcs->check_fw_load_finish(adev,
-						AMDGPU_UCODE_ID_CP_MEC1);
-		if (r)
-			return -EINVAL;
+			r = gfx_v8_0_cp_compute_load_microcode(adev);
+			if (r)
+				return r;
+		} else {
+			r = adev->smu.smumgr_funcs->check_fw_load_finish(adev,
+							AMDGPU_UCODE_ID_CP_CE);
+			if (r)
+				return -EINVAL;
+
+			r = adev->smu.smumgr_funcs->check_fw_load_finish(adev,
+							AMDGPU_UCODE_ID_CP_PFP);
+			if (r)
+				return -EINVAL;
+
+			r = adev->smu.smumgr_funcs->check_fw_load_finish(adev,
+							AMDGPU_UCODE_ID_CP_ME);
+			if (r)
+				return -EINVAL;
+
+			if (adev->asic_type == CHIP_TOPAZ) {
+				r = gfx_v8_0_cp_compute_load_microcode(adev);
+				if (r)
+					return r;
+			} else {
+				r = adev->smu.smumgr_funcs->check_fw_load_finish(adev,
+										 AMDGPU_UCODE_ID_CP_MEC1);
+				if (r)
+					return -EINVAL;
+			}
+		}
 	}
 
 	r = gfx_v8_0_cp_gfx_resume(adev);
@@ -4056,6 +4408,8 @@ static int gfx_v8_0_hw_fini(void *handle
 {
 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
 
+	amdgpu_irq_put(adev, &adev->gfx.priv_reg_irq, 0);
+	amdgpu_irq_put(adev, &adev->gfx.priv_inst_irq, 0);
 	gfx_v8_0_cp_enable(adev, false);
 	gfx_v8_0_rlc_stop(adev);
 	gfx_v8_0_cp_compute_fini(adev);
@@ -4341,7 +4695,18 @@ static int gfx_v8_0_soft_reset(void *han
 		gfx_v8_0_cp_gfx_enable(adev, false);
 
 		/* Disable MEC parsing/prefetching */
-		/* XXX todo */
+		gfx_v8_0_cp_compute_enable(adev, false);
+
+		if (grbm_soft_reset || srbm_soft_reset) {
+			tmp = RREG32(mmGMCON_DEBUG);
+			tmp = REG_SET_FIELD(tmp,
+					    GMCON_DEBUG, GFX_STALL, 1);
+			tmp = REG_SET_FIELD(tmp,
+					    GMCON_DEBUG, GFX_CLEAR, 1);
+			WREG32(mmGMCON_DEBUG, tmp);
+
+			udelay(50);
+		}
 
 		if (grbm_soft_reset) {
 			tmp = RREG32(mmGRBM_SOFT_RESET);
@@ -4370,6 +4735,16 @@ static int gfx_v8_0_soft_reset(void *han
 			WREG32(mmSRBM_SOFT_RESET, tmp);
 			tmp = RREG32(mmSRBM_SOFT_RESET);
 		}
+
+		if (grbm_soft_reset || srbm_soft_reset) {
+			tmp = RREG32(mmGMCON_DEBUG);
+			tmp = REG_SET_FIELD(tmp,
+					    GMCON_DEBUG, GFX_STALL, 0);
+			tmp = REG_SET_FIELD(tmp,
+					    GMCON_DEBUG, GFX_CLEAR, 0);
+			WREG32(mmGMCON_DEBUG, tmp);
+		}
+
 		/* Wait a little for things to settle down */
 		udelay(50);
 		gfx_v8_0_print_status((void *)adev);
@@ -4458,15 +4833,269 @@ static int gfx_v8_0_early_init(void *han
 	return 0;
 }
 
+static int gfx_v8_0_late_init(void *handle)
+{
+	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
+	int r;
+
+	r = amdgpu_irq_get(adev, &adev->gfx.priv_reg_irq, 0);
+	if (r)
+		return r;
+
+	r = amdgpu_irq_get(adev, &adev->gfx.priv_inst_irq, 0);
+	if (r)
+		return r;
+
+	/* requires IBs so do in late init after IB pool is initialized */
+	r = gfx_v8_0_do_edc_gpr_workarounds(adev);
+	if (r)
+		return r;
+
+	return 0;
+}
+
 static int gfx_v8_0_set_powergating_state(void *handle,
 					  enum amd_powergating_state state)
 {
 	return 0;
 }
 
+static void fiji_send_serdes_cmd(struct amdgpu_device *adev,
+		uint32_t reg_addr, uint32_t cmd)
+{
+	uint32_t data;
+
+	gfx_v8_0_select_se_sh(adev, 0xffffffff, 0xffffffff);
+
+	WREG32(mmRLC_SERDES_WR_CU_MASTER_MASK, 0xffffffff);
+	WREG32(mmRLC_SERDES_WR_NONCU_MASTER_MASK, 0xffffffff);
+
+	data = RREG32(mmRLC_SERDES_WR_CTRL);
+	data &= ~(RLC_SERDES_WR_CTRL__WRITE_COMMAND_MASK |
+			RLC_SERDES_WR_CTRL__READ_COMMAND_MASK |
+			RLC_SERDES_WR_CTRL__P1_SELECT_MASK |
+			RLC_SERDES_WR_CTRL__P2_SELECT_MASK |
+			RLC_SERDES_WR_CTRL__RDDATA_RESET_MASK |
+			RLC_SERDES_WR_CTRL__POWER_DOWN_MASK |
+			RLC_SERDES_WR_CTRL__POWER_UP_MASK |
+			RLC_SERDES_WR_CTRL__SHORT_FORMAT_MASK |
+			RLC_SERDES_WR_CTRL__BPM_DATA_MASK |
+			RLC_SERDES_WR_CTRL__REG_ADDR_MASK |
+			RLC_SERDES_WR_CTRL__SRBM_OVERRIDE_MASK);
+	data |= (RLC_SERDES_WR_CTRL__RSVD_BPM_ADDR_MASK |
+			(cmd << RLC_SERDES_WR_CTRL__BPM_DATA__SHIFT) |
+			(reg_addr << RLC_SERDES_WR_CTRL__REG_ADDR__SHIFT) |
+			(0xff << RLC_SERDES_WR_CTRL__BPM_ADDR__SHIFT));
+
+	WREG32(mmRLC_SERDES_WR_CTRL, data);
+}
+
+static void fiji_update_medium_grain_clock_gating(struct amdgpu_device *adev,
+		bool enable)
+{
+	uint32_t temp, data;
+
+	/* It is disabled by HW by default */
+	if (enable) {
+		/* 1 - RLC memory Light sleep */
+		temp = data = RREG32(mmRLC_MEM_SLP_CNTL);
+		data |= RLC_MEM_SLP_CNTL__RLC_MEM_LS_EN_MASK;
+		if (temp != data)
+			WREG32(mmRLC_MEM_SLP_CNTL, data);
+
+		/* 2 - CP memory Light sleep */
+		temp = data = RREG32(mmCP_MEM_SLP_CNTL);
+		data |= CP_MEM_SLP_CNTL__CP_MEM_LS_EN_MASK;
+		if (temp != data)
+			WREG32(mmCP_MEM_SLP_CNTL, data);
+
+		/* 3 - RLC_CGTT_MGCG_OVERRIDE */
+		temp = data = RREG32(mmRLC_CGTT_MGCG_OVERRIDE);
+		data &= ~(RLC_CGTT_MGCG_OVERRIDE__CPF_MASK |
+				RLC_CGTT_MGCG_OVERRIDE__RLC_MASK |
+				RLC_CGTT_MGCG_OVERRIDE__MGCG_MASK |
+				RLC_CGTT_MGCG_OVERRIDE__GRBM_MASK);
+
+		if (temp != data)
+			WREG32(mmRLC_CGTT_MGCG_OVERRIDE, data);
+
+		/* 4 - wait for RLC_SERDES_CU_MASTER & RLC_SERDES_NONCU_MASTER idle */
+		gfx_v8_0_wait_for_rlc_serdes(adev);
+
+		/* 5 - clear mgcg override */
+		fiji_send_serdes_cmd(adev, BPM_REG_MGCG_OVERRIDE, CLE_BPM_SERDES_CMD);
+
+		/* 6 - Enable CGTS(Tree Shade) MGCG /MGLS */
+		temp = data = RREG32(mmCGTS_SM_CTRL_REG);
+		data &= ~(CGTS_SM_CTRL_REG__SM_MODE_MASK);
+		data |= (0x2 << CGTS_SM_CTRL_REG__SM_MODE__SHIFT);
+		data |= CGTS_SM_CTRL_REG__SM_MODE_ENABLE_MASK;
+		data &= ~CGTS_SM_CTRL_REG__OVERRIDE_MASK;
+		data &= ~CGTS_SM_CTRL_REG__LS_OVERRIDE_MASK;
+		data |= CGTS_SM_CTRL_REG__ON_MONITOR_ADD_EN_MASK;
+		data |= (0x96 << CGTS_SM_CTRL_REG__ON_MONITOR_ADD__SHIFT);
+		if (temp != data)
+			WREG32(mmCGTS_SM_CTRL_REG, data);
+		udelay(50);
+
+		/* 7 - wait for RLC_SERDES_CU_MASTER & RLC_SERDES_NONCU_MASTER idle */
+		gfx_v8_0_wait_for_rlc_serdes(adev);
+	} else {
+		/* 1 - MGCG_OVERRIDE[0] for CP and MGCG_OVERRIDE[1] for RLC */
+		temp = data = RREG32(mmRLC_CGTT_MGCG_OVERRIDE);
+		data |= (RLC_CGTT_MGCG_OVERRIDE__CPF_MASK |
+				RLC_CGTT_MGCG_OVERRIDE__RLC_MASK |
+				RLC_CGTT_MGCG_OVERRIDE__MGCG_MASK |
+				RLC_CGTT_MGCG_OVERRIDE__GRBM_MASK);
+		if (temp != data)
+			WREG32(mmRLC_CGTT_MGCG_OVERRIDE, data);
+
+		/* 2 - disable MGLS in RLC */
+		data = RREG32(mmRLC_MEM_SLP_CNTL);
+		if (data & RLC_MEM_SLP_CNTL__RLC_MEM_LS_EN_MASK) {
+			data &= ~RLC_MEM_SLP_CNTL__RLC_MEM_LS_EN_MASK;
+			WREG32(mmRLC_MEM_SLP_CNTL, data);
+		}
+
+		/* 3 - disable MGLS in CP */
+		data = RREG32(mmCP_MEM_SLP_CNTL);
+		if (data & CP_MEM_SLP_CNTL__CP_MEM_LS_EN_MASK) {
+			data &= ~CP_MEM_SLP_CNTL__CP_MEM_LS_EN_MASK;
+			WREG32(mmCP_MEM_SLP_CNTL, data);
+		}
+
+		/* 4 - Disable CGTS(Tree Shade) MGCG and MGLS */
+		temp = data = RREG32(mmCGTS_SM_CTRL_REG);
+		data |= (CGTS_SM_CTRL_REG__OVERRIDE_MASK |
+				CGTS_SM_CTRL_REG__LS_OVERRIDE_MASK);
+		if (temp != data)
+			WREG32(mmCGTS_SM_CTRL_REG, data);
+
+		/* 5 - wait for RLC_SERDES_CU_MASTER & RLC_SERDES_NONCU_MASTER idle */
+		gfx_v8_0_wait_for_rlc_serdes(adev);
+
+		/* 6 - set mgcg override */
+		fiji_send_serdes_cmd(adev, BPM_REG_MGCG_OVERRIDE, SET_BPM_SERDES_CMD);
+
+		udelay(50);
+
+		/* 7- wait for RLC_SERDES_CU_MASTER & RLC_SERDES_NONCU_MASTER idle */
+		gfx_v8_0_wait_for_rlc_serdes(adev);
+	}
+}
+
+static void fiji_update_coarse_grain_clock_gating(struct amdgpu_device *adev,
+		bool enable)
+{
+	uint32_t temp, temp1, data, data1;
+
+	temp = data = RREG32(mmRLC_CGCG_CGLS_CTRL);
+
+	if (enable) {
+		/* 1 enable cntx_empty_int_enable/cntx_busy_int_enable/
+		 * Cmp_busy/GFX_Idle interrupts
+		 */
+		gfx_v8_0_enable_gui_idle_interrupt(adev, true);
+
+		temp1 = data1 =	RREG32(mmRLC_CGTT_MGCG_OVERRIDE);
+		data1 &= ~RLC_CGTT_MGCG_OVERRIDE__CGCG_MASK;
+		if (temp1 != data1)
+			WREG32(mmRLC_CGTT_MGCG_OVERRIDE, data1);
+
+		/* 2 wait for RLC_SERDES_CU_MASTER & RLC_SERDES_NONCU_MASTER idle */
+		gfx_v8_0_wait_for_rlc_serdes(adev);
+
+		/* 3 - clear cgcg override */
+		fiji_send_serdes_cmd(adev, BPM_REG_CGCG_OVERRIDE, CLE_BPM_SERDES_CMD);
+
+		/* wait for RLC_SERDES_CU_MASTER & RLC_SERDES_NONCU_MASTER idle */
+		gfx_v8_0_wait_for_rlc_serdes(adev);
+
+		/* 4 - write cmd to set CGLS */
+		fiji_send_serdes_cmd(adev, BPM_REG_CGLS_EN, SET_BPM_SERDES_CMD);
+
+		/* 5 - enable cgcg */
+		data |= RLC_CGCG_CGLS_CTRL__CGCG_EN_MASK;
+
+		/* enable cgls*/
+		data |= RLC_CGCG_CGLS_CTRL__CGLS_EN_MASK;
+
+		temp1 = data1 =	RREG32(mmRLC_CGTT_MGCG_OVERRIDE);
+		data1 &= ~RLC_CGTT_MGCG_OVERRIDE__CGLS_MASK;
+
+		if (temp1 != data1)
+			WREG32(mmRLC_CGTT_MGCG_OVERRIDE, data1);
+
+		if (temp != data)
+			WREG32(mmRLC_CGCG_CGLS_CTRL, data);
+	} else {
+		/* disable cntx_empty_int_enable & GFX Idle interrupt */
+		gfx_v8_0_enable_gui_idle_interrupt(adev, false);
+
+		/* TEST CGCG */
+		temp1 = data1 =	RREG32(mmRLC_CGTT_MGCG_OVERRIDE);
+		data1 |= (RLC_CGTT_MGCG_OVERRIDE__CGCG_MASK |
+				RLC_CGTT_MGCG_OVERRIDE__CGLS_MASK);
+		if (temp1 != data1)
+			WREG32(mmRLC_CGTT_MGCG_OVERRIDE, data1);
+
+		/* read gfx register to wake up cgcg */
+		RREG32(mmCB_CGTT_SCLK_CTRL);
+		RREG32(mmCB_CGTT_SCLK_CTRL);
+		RREG32(mmCB_CGTT_SCLK_CTRL);
+		RREG32(mmCB_CGTT_SCLK_CTRL);
+
+		/* wait for RLC_SERDES_CU_MASTER & RLC_SERDES_NONCU_MASTER idle */
+		gfx_v8_0_wait_for_rlc_serdes(adev);
+
+		/* write cmd to Set CGCG Overrride */
+		fiji_send_serdes_cmd(adev, BPM_REG_CGCG_OVERRIDE, SET_BPM_SERDES_CMD);
+
+		/* wait for RLC_SERDES_CU_MASTER & RLC_SERDES_NONCU_MASTER idle */
+		gfx_v8_0_wait_for_rlc_serdes(adev);
+
+		/* write cmd to Clear CGLS */
+		fiji_send_serdes_cmd(adev, BPM_REG_CGLS_EN, CLE_BPM_SERDES_CMD);
+
+		/* disable cgcg, cgls should be disabled too. */
+		data &= ~(RLC_CGCG_CGLS_CTRL__CGCG_EN_MASK |
+				RLC_CGCG_CGLS_CTRL__CGLS_EN_MASK);
+		if (temp != data)
+			WREG32(mmRLC_CGCG_CGLS_CTRL, data);
+	}
+}
+static int fiji_update_gfx_clock_gating(struct amdgpu_device *adev,
+		bool enable)
+{
+	if (enable) {
+		/* CGCG/CGLS should be enabled after MGCG/MGLS/TS(CG/LS)
+		 * ===  MGCG + MGLS + TS(CG/LS) ===
+		 */
+		fiji_update_medium_grain_clock_gating(adev, enable);
+		fiji_update_coarse_grain_clock_gating(adev, enable);
+	} else {
+		/* CGCG/CGLS should be disabled before MGCG/MGLS/TS(CG/LS)
+		 * ===  CGCG + CGLS ===
+		 */
+		fiji_update_coarse_grain_clock_gating(adev, enable);
+		fiji_update_medium_grain_clock_gating(adev, enable);
+	}
+	return 0;
+}
+
 static int gfx_v8_0_set_clockgating_state(void *handle,
 					  enum amd_clockgating_state state)
 {
+	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
+
+	switch (adev->asic_type) {
+	case CHIP_FIJI:
+		fiji_update_gfx_clock_gating(adev,
+				state == AMD_CG_STATE_GATE ? true : false);
+		break;
+	default:
+		break;
+	}
 	return 0;
 }
 
@@ -4681,7 +5310,8 @@ static void gfx_v8_0_ring_emit_vm_flush(
 
 	amdgpu_ring_write(ring, PACKET3(PACKET3_WAIT_REG_MEM, 5));
 	amdgpu_ring_write(ring, (WAIT_REG_MEM_MEM_SPACE(1) | /* memory */
-		 WAIT_REG_MEM_FUNCTION(3))); /* equal */
+				 WAIT_REG_MEM_FUNCTION(3) | /* equal */
+				 WAIT_REG_MEM_ENGINE(usepfp))); /* pfp or me */
 	amdgpu_ring_write(ring, addr & 0xfffffffc);
 	amdgpu_ring_write(ring, upper_32_bits(addr) & 0xffffffff);
 	amdgpu_ring_write(ring, seq);
@@ -4995,7 +5625,7 @@ static int gfx_v8_0_priv_inst_irq(struct
 
 const struct amd_ip_funcs gfx_v8_0_ip_funcs = {
 	.early_init = gfx_v8_0_early_init,
-	.late_init = NULL,
+	.late_init = gfx_v8_0_late_init,
 	.sw_init = gfx_v8_0_sw_init,
 	.sw_fini = gfx_v8_0_sw_fini,
 	.hw_init = gfx_v8_0_hw_init,
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c
@@ -42,9 +42,39 @@ static void gmc_v7_0_set_irq_funcs(struc
 
 MODULE_FIRMWARE("radeon/bonaire_mc.bin");
 MODULE_FIRMWARE("radeon/hawaii_mc.bin");
+MODULE_FIRMWARE("amdgpu/topaz_mc.bin");
+
+static const u32 golden_settings_iceland_a11[] =
+{
+	mmVM_PRT_APERTURE0_LOW_ADDR, 0x0fffffff, 0x0fffffff,
+	mmVM_PRT_APERTURE1_LOW_ADDR, 0x0fffffff, 0x0fffffff,
+	mmVM_PRT_APERTURE2_LOW_ADDR, 0x0fffffff, 0x0fffffff,
+	mmVM_PRT_APERTURE3_LOW_ADDR, 0x0fffffff, 0x0fffffff
+};
+
+static const u32 iceland_mgcg_cgcg_init[] =
+{
+	mmMC_MEM_POWER_LS, 0xffffffff, 0x00000104
+};
+
+static void gmc_v7_0_init_golden_registers(struct amdgpu_device *adev)
+{
+	switch (adev->asic_type) {
+	case CHIP_TOPAZ:
+		amdgpu_program_register_sequence(adev,
+						 iceland_mgcg_cgcg_init,
+						 (const u32)ARRAY_SIZE(iceland_mgcg_cgcg_init));
+		amdgpu_program_register_sequence(adev,
+						 golden_settings_iceland_a11,
+						 (const u32)ARRAY_SIZE(golden_settings_iceland_a11));
+		break;
+	default:
+		break;
+	}
+}
 
 /**
- * gmc8_mc_wait_for_idle - wait for MC idle callback.
+ * gmc7_mc_wait_for_idle - wait for MC idle callback.
  *
  * @adev: amdgpu_device pointer
  *
@@ -132,13 +162,21 @@ static int gmc_v7_0_init_microcode(struc
 	case CHIP_HAWAII:
 		chip_name = "hawaii";
 		break;
+	case CHIP_TOPAZ:
+		chip_name = "topaz";
+		break;
 	case CHIP_KAVERI:
 	case CHIP_KABINI:
+	case CHIP_MULLINS:
 		return 0;
 	default: BUG();
 	}
 
-	snprintf(fw_name, sizeof(fw_name), "radeon/%s_mc.bin", chip_name);
+	if (adev->asic_type == CHIP_TOPAZ)
+		snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_mc.bin", chip_name);
+	else
+		snprintf(fw_name, sizeof(fw_name), "radeon/%s_mc.bin", chip_name);
+
 	err = request_firmware(&adev->mc.fw, fw_name, adev->dev);
 	if (err)
 		goto out;
@@ -370,6 +408,10 @@ static int gmc_v7_0_mc_init(struct amdgp
 	adev->mc.real_vram_size = RREG32(mmCONFIG_MEMSIZE) * 1024ULL * 1024ULL;
 	adev->mc.visible_vram_size = adev->mc.aper_size;
 
+	/* In case the PCI BAR is larger than the actual amount of vram */
+	if (adev->mc.visible_vram_size > adev->mc.real_vram_size)
+		adev->mc.visible_vram_size = adev->mc.real_vram_size;
+
 	/* unless the user had overridden it, set the gart
 	 * size equal to the 1024 or vram, whichever is larger.
 	 */
@@ -751,7 +793,7 @@ static void gmc_v7_0_enable_mc_ls(struct
 
 	for (i = 0; i < ARRAY_SIZE(mc_cg_registers); i++) {
 		orig = data = RREG32(mc_cg_registers[i]);
-		if (enable && (adev->cg_flags & AMDGPU_CG_SUPPORT_MC_LS))
+		if (enable && (adev->cg_flags & AMD_CG_SUPPORT_MC_LS))
 			data |= mc_cg_ls_en[i];
 		else
 			data &= ~mc_cg_ls_en[i];
@@ -768,7 +810,7 @@ static void gmc_v7_0_enable_mc_mgcg(stru
 
 	for (i = 0; i < ARRAY_SIZE(mc_cg_registers); i++) {
 		orig = data = RREG32(mc_cg_registers[i]);
-		if (enable && (adev->cg_flags & AMDGPU_CG_SUPPORT_MC_MGCG))
+		if (enable && (adev->cg_flags & AMD_CG_SUPPORT_MC_MGCG))
 			data |= mc_cg_en[i];
 		else
 			data &= ~mc_cg_en[i];
@@ -784,7 +826,7 @@ static void gmc_v7_0_enable_bif_mgls(str
 
 	orig = data = RREG32_PCIE(ixPCIE_CNTL2);
 
-	if (enable && (adev->cg_flags & AMDGPU_CG_SUPPORT_BIF_LS)) {
+	if (enable && (adev->cg_flags & AMD_CG_SUPPORT_BIF_LS)) {
 		data = REG_SET_FIELD(data, PCIE_CNTL2, SLV_MEM_LS_EN, 1);
 		data = REG_SET_FIELD(data, PCIE_CNTL2, MST_MEM_LS_EN, 1);
 		data = REG_SET_FIELD(data, PCIE_CNTL2, REPLAY_MEM_LS_EN, 1);
@@ -807,7 +849,7 @@ static void gmc_v7_0_enable_hdp_mgcg(str
 
 	orig = data = RREG32(mmHDP_HOST_PATH_CNTL);
 
-	if (enable && (adev->cg_flags & AMDGPU_CG_SUPPORT_HDP_MGCG))
+	if (enable && (adev->cg_flags & AMD_CG_SUPPORT_HDP_MGCG))
 		data = REG_SET_FIELD(data, HDP_HOST_PATH_CNTL, CLOCK_GATING_DIS, 0);
 	else
 		data = REG_SET_FIELD(data, HDP_HOST_PATH_CNTL, CLOCK_GATING_DIS, 1);
@@ -823,7 +865,7 @@ static void gmc_v7_0_enable_hdp_ls(struc
 
 	orig = data = RREG32(mmHDP_MEM_POWER_LS);
 
-	if (enable && (adev->cg_flags & AMDGPU_CG_SUPPORT_HDP_LS))
+	if (enable && (adev->cg_flags & AMD_CG_SUPPORT_HDP_LS))
 		data = REG_SET_FIELD(data, HDP_MEM_POWER_LS, LS_ENABLE, 1);
 	else
 		data = REG_SET_FIELD(data, HDP_MEM_POWER_LS, LS_ENABLE, 0);
@@ -861,14 +903,6 @@ static int gmc_v7_0_early_init(void *han
 	gmc_v7_0_set_gart_funcs(adev);
 	gmc_v7_0_set_irq_funcs(adev);
 
-	if (adev->flags & AMD_IS_APU) {
-		adev->mc.vram_type = AMDGPU_VRAM_TYPE_UNKNOWN;
-	} else {
-		u32 tmp = RREG32(mmMC_SEQ_MISC0);
-		tmp &= MC_SEQ_MISC0__MT__MASK;
-		adev->mc.vram_type = gmc_v7_0_convert_vram_type(tmp);
-	}
-
 	return 0;
 }
 
@@ -889,6 +923,14 @@ static int gmc_v7_0_sw_init(void *handle
 	if (r)
 		return r;
 
+	if (adev->flags & AMD_IS_APU) {
+		adev->mc.vram_type = AMDGPU_VRAM_TYPE_UNKNOWN;
+	} else {
+		u32 tmp = RREG32(mmMC_SEQ_MISC0);
+		tmp &= MC_SEQ_MISC0__MT__MASK;
+		adev->mc.vram_type = gmc_v7_0_convert_vram_type(tmp);
+	}
+
 	r = amdgpu_irq_add_id(adev, 146, &adev->mc.vm_fault);
 	if (r)
 		return r;
@@ -964,7 +1006,6 @@ static int gmc_v7_0_sw_fini(void *handle
 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
 
 	if (adev->vm_manager.enabled) {
-		amdgpu_vm_manager_fini(adev);
 		gmc_v7_0_vm_fini(adev);
 		adev->vm_manager.enabled = false;
 	}
@@ -980,6 +1021,8 @@ static int gmc_v7_0_hw_init(void *handle
 	int r;
 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
 
+	gmc_v7_0_init_golden_registers(adev);
+
 	gmc_v7_0_mc_program(adev);
 
 	if (!(adev->flags & AMD_IS_APU)) {
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c
@@ -42,9 +42,7 @@
 static void gmc_v8_0_set_gart_funcs(struct amdgpu_device *adev);
 static void gmc_v8_0_set_irq_funcs(struct amdgpu_device *adev);
 
-MODULE_FIRMWARE("amdgpu/topaz_mc.bin");
 MODULE_FIRMWARE("amdgpu/tonga_mc.bin");
-MODULE_FIRMWARE("amdgpu/fiji_mc.bin");
 
 static const u32 golden_settings_tonga_a11[] =
 {
@@ -75,19 +73,6 @@ static const u32 fiji_mgcg_cgcg_init[] =
 	mmMC_MEM_POWER_LS, 0xffffffff, 0x00000104
 };
 
-static const u32 golden_settings_iceland_a11[] =
-{
-	mmVM_PRT_APERTURE0_LOW_ADDR, 0x0fffffff, 0x0fffffff,
-	mmVM_PRT_APERTURE1_LOW_ADDR, 0x0fffffff, 0x0fffffff,
-	mmVM_PRT_APERTURE2_LOW_ADDR, 0x0fffffff, 0x0fffffff,
-	mmVM_PRT_APERTURE3_LOW_ADDR, 0x0fffffff, 0x0fffffff
-};
-
-static const u32 iceland_mgcg_cgcg_init[] =
-{
-	mmMC_MEM_POWER_LS, 0xffffffff, 0x00000104
-};
-
 static const u32 cz_mgcg_cgcg_init[] =
 {
 	mmMC_MEM_POWER_LS, 0xffffffff, 0x00000104
@@ -102,14 +87,6 @@ static const u32 stoney_mgcg_cgcg_init[]
 static void gmc_v8_0_init_golden_registers(struct amdgpu_device *adev)
 {
 	switch (adev->asic_type) {
-	case CHIP_TOPAZ:
-		amdgpu_program_register_sequence(adev,
-						 iceland_mgcg_cgcg_init,
-						 (const u32)ARRAY_SIZE(iceland_mgcg_cgcg_init));
-		amdgpu_program_register_sequence(adev,
-						 golden_settings_iceland_a11,
-						 (const u32)ARRAY_SIZE(golden_settings_iceland_a11));
-		break;
 	case CHIP_FIJI:
 		amdgpu_program_register_sequence(adev,
 						 fiji_mgcg_cgcg_init,
@@ -229,15 +206,10 @@ static int gmc_v8_0_init_microcode(struc
 	DRM_DEBUG("\n");
 
 	switch (adev->asic_type) {
-	case CHIP_TOPAZ:
-		chip_name = "topaz";
-		break;
 	case CHIP_TONGA:
 		chip_name = "tonga";
 		break;
 	case CHIP_FIJI:
-		chip_name = "fiji";
-		break;
 	case CHIP_CARRIZO:
 	case CHIP_STONEY:
 		return 0;
@@ -476,6 +448,10 @@ static int gmc_v8_0_mc_init(struct amdgp
 	adev->mc.real_vram_size = RREG32(mmCONFIG_MEMSIZE) * 1024ULL * 1024ULL;
 	adev->mc.visible_vram_size = adev->mc.aper_size;
 
+	/* In case the PCI BAR is larger than the actual amount of vram */
+	if (adev->mc.visible_vram_size > adev->mc.real_vram_size)
+		adev->mc.visible_vram_size = adev->mc.real_vram_size;
+
 	/* unless the user had overridden it, set the gart
 	 * size equal to the 1024 or vram, whichever is larger.
 	 */
@@ -880,14 +856,6 @@ static int gmc_v8_0_early_init(void *han
 	gmc_v8_0_set_gart_funcs(adev);
 	gmc_v8_0_set_irq_funcs(adev);
 
-	if (adev->flags & AMD_IS_APU) {
-		adev->mc.vram_type = AMDGPU_VRAM_TYPE_UNKNOWN;
-	} else {
-		u32 tmp = RREG32(mmMC_SEQ_MISC0);
-		tmp &= MC_SEQ_MISC0__MT__MASK;
-		adev->mc.vram_type = gmc_v8_0_convert_vram_type(tmp);
-	}
-
 	return 0;
 }
 
@@ -898,6 +866,8 @@ static int gmc_v8_0_late_init(void *hand
 	return amdgpu_irq_get(adev, &adev->mc.vm_fault, 0);
 }
 
+#define mmMC_SEQ_MISC0_FIJI 0xA71
+
 static int gmc_v8_0_sw_init(void *handle)
 {
 	int r;
@@ -908,6 +878,19 @@ static int gmc_v8_0_sw_init(void *handle
 	if (r)
 		return r;
 
+	if (adev->flags & AMD_IS_APU) {
+		adev->mc.vram_type = AMDGPU_VRAM_TYPE_UNKNOWN;
+	} else {
+		u32 tmp;
+
+		if (adev->asic_type == CHIP_FIJI)
+			tmp = RREG32(mmMC_SEQ_MISC0_FIJI);
+		else
+			tmp = RREG32(mmMC_SEQ_MISC0);
+		tmp &= MC_SEQ_MISC0__MT__MASK;
+		adev->mc.vram_type = gmc_v8_0_convert_vram_type(tmp);
+	}
+
 	r = amdgpu_irq_add_id(adev, 146, &adev->mc.vm_fault);
 	if (r)
 		return r;
@@ -1003,7 +986,7 @@ static int gmc_v8_0_hw_init(void *handle
 
 	gmc_v8_0_mc_program(adev);
 
-	if (!(adev->flags & AMD_IS_APU)) {
+	if (adev->asic_type == CHIP_TONGA) {
 		r = gmc_v8_0_mc_load_microcode(adev);
 		if (r) {
 			DRM_ERROR("Failed to load MC firmware!\n");
@@ -1033,7 +1016,6 @@ static int gmc_v8_0_suspend(void *handle
 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
 
 	if (adev->vm_manager.enabled) {
-		amdgpu_vm_manager_fini(adev);
 		gmc_v8_0_vm_fini(adev);
 		adev->vm_manager.enabled = false;
 	}
@@ -1324,9 +1306,181 @@ static int gmc_v8_0_process_interrupt(st
 	return 0;
 }
 
+static void fiji_update_mc_medium_grain_clock_gating(struct amdgpu_device *adev,
+		bool enable)
+{
+	uint32_t data;
+
+	if (enable) {
+		data = RREG32(mmMC_HUB_MISC_HUB_CG);
+		data |= MC_HUB_MISC_HUB_CG__ENABLE_MASK;
+		WREG32(mmMC_HUB_MISC_HUB_CG, data);
+
+		data = RREG32(mmMC_HUB_MISC_SIP_CG);
+		data |= MC_HUB_MISC_SIP_CG__ENABLE_MASK;
+		WREG32(mmMC_HUB_MISC_SIP_CG, data);
+
+		data = RREG32(mmMC_HUB_MISC_VM_CG);
+		data |= MC_HUB_MISC_VM_CG__ENABLE_MASK;
+		WREG32(mmMC_HUB_MISC_VM_CG, data);
+
+		data = RREG32(mmMC_XPB_CLK_GAT);
+		data |= MC_XPB_CLK_GAT__ENABLE_MASK;
+		WREG32(mmMC_XPB_CLK_GAT, data);
+
+		data = RREG32(mmATC_MISC_CG);
+		data |= ATC_MISC_CG__ENABLE_MASK;
+		WREG32(mmATC_MISC_CG, data);
+
+		data = RREG32(mmMC_CITF_MISC_WR_CG);
+		data |= MC_CITF_MISC_WR_CG__ENABLE_MASK;
+		WREG32(mmMC_CITF_MISC_WR_CG, data);
+
+		data = RREG32(mmMC_CITF_MISC_RD_CG);
+		data |= MC_CITF_MISC_RD_CG__ENABLE_MASK;
+		WREG32(mmMC_CITF_MISC_RD_CG, data);
+
+		data = RREG32(mmMC_CITF_MISC_VM_CG);
+		data |= MC_CITF_MISC_VM_CG__ENABLE_MASK;
+		WREG32(mmMC_CITF_MISC_VM_CG, data);
+
+		data = RREG32(mmVM_L2_CG);
+		data |= VM_L2_CG__ENABLE_MASK;
+		WREG32(mmVM_L2_CG, data);
+	} else {
+		data = RREG32(mmMC_HUB_MISC_HUB_CG);
+		data &= ~MC_HUB_MISC_HUB_CG__ENABLE_MASK;
+		WREG32(mmMC_HUB_MISC_HUB_CG, data);
+
+		data = RREG32(mmMC_HUB_MISC_SIP_CG);
+		data &= ~MC_HUB_MISC_SIP_CG__ENABLE_MASK;
+		WREG32(mmMC_HUB_MISC_SIP_CG, data);
+
+		data = RREG32(mmMC_HUB_MISC_VM_CG);
+		data &= ~MC_HUB_MISC_VM_CG__ENABLE_MASK;
+		WREG32(mmMC_HUB_MISC_VM_CG, data);
+
+		data = RREG32(mmMC_XPB_CLK_GAT);
+		data &= ~MC_XPB_CLK_GAT__ENABLE_MASK;
+		WREG32(mmMC_XPB_CLK_GAT, data);
+
+		data = RREG32(mmATC_MISC_CG);
+		data &= ~ATC_MISC_CG__ENABLE_MASK;
+		WREG32(mmATC_MISC_CG, data);
+
+		data = RREG32(mmMC_CITF_MISC_WR_CG);
+		data &= ~MC_CITF_MISC_WR_CG__ENABLE_MASK;
+		WREG32(mmMC_CITF_MISC_WR_CG, data);
+
+		data = RREG32(mmMC_CITF_MISC_RD_CG);
+		data &= ~MC_CITF_MISC_RD_CG__ENABLE_MASK;
+		WREG32(mmMC_CITF_MISC_RD_CG, data);
+
+		data = RREG32(mmMC_CITF_MISC_VM_CG);
+		data &= ~MC_CITF_MISC_VM_CG__ENABLE_MASK;
+		WREG32(mmMC_CITF_MISC_VM_CG, data);
+
+		data = RREG32(mmVM_L2_CG);
+		data &= ~VM_L2_CG__ENABLE_MASK;
+		WREG32(mmVM_L2_CG, data);
+	}
+}
+
+static void fiji_update_mc_light_sleep(struct amdgpu_device *adev,
+		bool enable)
+{
+	uint32_t data;
+
+	if (enable) {
+		data = RREG32(mmMC_HUB_MISC_HUB_CG);
+		data |= MC_HUB_MISC_HUB_CG__MEM_LS_ENABLE_MASK;
+		WREG32(mmMC_HUB_MISC_HUB_CG, data);
+
+		data = RREG32(mmMC_HUB_MISC_SIP_CG);
+		data |= MC_HUB_MISC_SIP_CG__MEM_LS_ENABLE_MASK;
+		WREG32(mmMC_HUB_MISC_SIP_CG, data);
+
+		data = RREG32(mmMC_HUB_MISC_VM_CG);
+		data |= MC_HUB_MISC_VM_CG__MEM_LS_ENABLE_MASK;
+		WREG32(mmMC_HUB_MISC_VM_CG, data);
+
+		data = RREG32(mmMC_XPB_CLK_GAT);
+		data |= MC_XPB_CLK_GAT__MEM_LS_ENABLE_MASK;
+		WREG32(mmMC_XPB_CLK_GAT, data);
+
+		data = RREG32(mmATC_MISC_CG);
+		data |= ATC_MISC_CG__MEM_LS_ENABLE_MASK;
+		WREG32(mmATC_MISC_CG, data);
+
+		data = RREG32(mmMC_CITF_MISC_WR_CG);
+		data |= MC_CITF_MISC_WR_CG__MEM_LS_ENABLE_MASK;
+		WREG32(mmMC_CITF_MISC_WR_CG, data);
+
+		data = RREG32(mmMC_CITF_MISC_RD_CG);
+		data |= MC_CITF_MISC_RD_CG__MEM_LS_ENABLE_MASK;
+		WREG32(mmMC_CITF_MISC_RD_CG, data);
+
+		data = RREG32(mmMC_CITF_MISC_VM_CG);
+		data |= MC_CITF_MISC_VM_CG__MEM_LS_ENABLE_MASK;
+		WREG32(mmMC_CITF_MISC_VM_CG, data);
+
+		data = RREG32(mmVM_L2_CG);
+		data |= VM_L2_CG__MEM_LS_ENABLE_MASK;
+		WREG32(mmVM_L2_CG, data);
+	} else {
+		data = RREG32(mmMC_HUB_MISC_HUB_CG);
+		data &= ~MC_HUB_MISC_HUB_CG__MEM_LS_ENABLE_MASK;
+		WREG32(mmMC_HUB_MISC_HUB_CG, data);
+
+		data = RREG32(mmMC_HUB_MISC_SIP_CG);
+		data &= ~MC_HUB_MISC_SIP_CG__MEM_LS_ENABLE_MASK;
+		WREG32(mmMC_HUB_MISC_SIP_CG, data);
+
+		data = RREG32(mmMC_HUB_MISC_VM_CG);
+		data &= ~MC_HUB_MISC_VM_CG__MEM_LS_ENABLE_MASK;
+		WREG32(mmMC_HUB_MISC_VM_CG, data);
+
+		data = RREG32(mmMC_XPB_CLK_GAT);
+		data &= ~MC_XPB_CLK_GAT__MEM_LS_ENABLE_MASK;
+		WREG32(mmMC_XPB_CLK_GAT, data);
+
+		data = RREG32(mmATC_MISC_CG);
+		data &= ~ATC_MISC_CG__MEM_LS_ENABLE_MASK;
+		WREG32(mmATC_MISC_CG, data);
+
+		data = RREG32(mmMC_CITF_MISC_WR_CG);
+		data &= ~MC_CITF_MISC_WR_CG__MEM_LS_ENABLE_MASK;
+		WREG32(mmMC_CITF_MISC_WR_CG, data);
+
+		data = RREG32(mmMC_CITF_MISC_RD_CG);
+		data &= ~MC_CITF_MISC_RD_CG__MEM_LS_ENABLE_MASK;
+		WREG32(mmMC_CITF_MISC_RD_CG, data);
+
+		data = RREG32(mmMC_CITF_MISC_VM_CG);
+		data &= ~MC_CITF_MISC_VM_CG__MEM_LS_ENABLE_MASK;
+		WREG32(mmMC_CITF_MISC_VM_CG, data);
+
+		data = RREG32(mmVM_L2_CG);
+		data &= ~VM_L2_CG__MEM_LS_ENABLE_MASK;
+		WREG32(mmVM_L2_CG, data);
+	}
+}
+
 static int gmc_v8_0_set_clockgating_state(void *handle,
 					  enum amd_clockgating_state state)
 {
+	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
+
+	switch (adev->asic_type) {
+	case CHIP_FIJI:
+		fiji_update_mc_medium_grain_clock_gating(adev,
+				state == AMD_CG_STATE_GATE ? true : false);
+		fiji_update_mc_light_sleep(adev,
+				state == AMD_CG_STATE_GATE ? true : false);
+		break;
+	default:
+		break;
+	}
 	return 0;
 }
 
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/amd/amdgpu/iceland_ih.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/amdgpu/iceland_ih.c
@@ -253,8 +253,14 @@ static void iceland_ih_set_rptr(struct a
 static int iceland_ih_early_init(void *handle)
 {
 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
+	int ret;
+
+	ret = amdgpu_irq_add_domain(adev);
+	if (ret)
+		return ret;
 
 	iceland_ih_set_interrupt_funcs(adev);
+
 	return 0;
 }
 
@@ -278,6 +284,7 @@ static int iceland_ih_sw_fini(void *hand
 
 	amdgpu_irq_fini(adev);
 	amdgpu_ih_ring_fini(adev);
+	amdgpu_irq_remove_domain(adev);
 
 	return 0;
 }
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/amd/amdgpu/iceland_smc.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/amdgpu/iceland_smc.c
@@ -432,7 +432,7 @@ static uint32_t iceland_smu_get_mask_for
 		case AMDGPU_UCODE_ID_CP_ME:
 			return UCODE_ID_CP_ME_MASK;
 		case AMDGPU_UCODE_ID_CP_MEC1:
-			return UCODE_ID_CP_MEC_MASK | UCODE_ID_CP_MEC_JT1_MASK | UCODE_ID_CP_MEC_JT2_MASK;
+			return UCODE_ID_CP_MEC_MASK | UCODE_ID_CP_MEC_JT1_MASK;
 		case AMDGPU_UCODE_ID_CP_MEC2:
 			return UCODE_ID_CP_MEC_MASK;
 		case AMDGPU_UCODE_ID_RLC_G:
@@ -522,12 +522,6 @@ static int iceland_smu_request_load_fw(s
 		return -EINVAL;
 	}
 
-	if (iceland_smu_populate_single_firmware_entry(adev, UCODE_ID_CP_MEC_JT2,
-			&toc->entry[toc->num_entries++])) {
-		DRM_ERROR("Failed to get firmware entry for MEC_JT2\n");
-		return -EINVAL;
-	}
-
 	if (iceland_smu_populate_single_firmware_entry(adev, UCODE_ID_SDMA0,
 			&toc->entry[toc->num_entries++])) {
 		DRM_ERROR("Failed to get firmware entry for SDMA0\n");
@@ -550,8 +544,8 @@ static int iceland_smu_request_load_fw(s
 			UCODE_ID_CP_ME_MASK |
 			UCODE_ID_CP_PFP_MASK |
 			UCODE_ID_CP_MEC_MASK |
-			UCODE_ID_CP_MEC_JT1_MASK |
-			UCODE_ID_CP_MEC_JT2_MASK;
+			UCODE_ID_CP_MEC_JT1_MASK;
+
 
 	if (iceland_send_msg_to_smc_with_parameter_without_waiting(adev, PPSMC_MSG_LoadUcodes, fw_to_load)) {
 		DRM_ERROR("Fail to request SMU load ucode\n");
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/amd/amdgpu/kv_dpm.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/amdgpu/kv_dpm.c
@@ -2859,11 +2859,11 @@ static int kv_dpm_init(struct amdgpu_dev
 	pi->voltage_drop_t = 0;
 	pi->caps_sclk_throttle_low_notification = false;
 	pi->caps_fps = false; /* true? */
-	pi->caps_uvd_pg = (adev->pg_flags & AMDGPU_PG_SUPPORT_UVD) ? true : false;
+	pi->caps_uvd_pg = (adev->pg_flags & AMD_PG_SUPPORT_UVD) ? true : false;
 	pi->caps_uvd_dpm = true;
-	pi->caps_vce_pg = (adev->pg_flags & AMDGPU_PG_SUPPORT_VCE) ? true : false;
-	pi->caps_samu_pg = (adev->pg_flags & AMDGPU_PG_SUPPORT_SAMU) ? true : false;
-	pi->caps_acp_pg = (adev->pg_flags & AMDGPU_PG_SUPPORT_ACP) ? true : false;
+	pi->caps_vce_pg = (adev->pg_flags & AMD_PG_SUPPORT_VCE) ? true : false;
+	pi->caps_samu_pg = (adev->pg_flags & AMD_PG_SUPPORT_SAMU) ? true : false;
+	pi->caps_acp_pg = (adev->pg_flags & AMD_PG_SUPPORT_ACP) ? true : false;
 	pi->caps_stable_p_state = false;
 
 	ret = kv_parse_sys_info_table(adev);
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c
@@ -32,8 +32,8 @@
 #include "oss/oss_2_4_d.h"
 #include "oss/oss_2_4_sh_mask.h"
 
-#include "gmc/gmc_8_1_d.h"
-#include "gmc/gmc_8_1_sh_mask.h"
+#include "gmc/gmc_7_1_d.h"
+#include "gmc/gmc_7_1_sh_mask.h"
 
 #include "gca/gfx_8_0_d.h"
 #include "gca/gfx_8_0_enum.h"
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c
@@ -727,18 +727,20 @@ static int sdma_v3_0_start(struct amdgpu
 {
 	int r, i;
 
-	if (!adev->firmware.smu_load) {
-		r = sdma_v3_0_load_microcode(adev);
-		if (r)
-			return r;
-	} else {
-		for (i = 0; i < adev->sdma.num_instances; i++) {
-			r = adev->smu.smumgr_funcs->check_fw_load_finish(adev,
-									 (i == 0) ?
-									 AMDGPU_UCODE_ID_SDMA0 :
-									 AMDGPU_UCODE_ID_SDMA1);
+	if (!adev->pp_enabled) {
+		if (!adev->firmware.smu_load) {
+			r = sdma_v3_0_load_microcode(adev);
 			if (r)
-				return -EINVAL;
+				return r;
+		} else {
+			for (i = 0; i < adev->sdma.num_instances; i++) {
+				r = adev->smu.smumgr_funcs->check_fw_load_finish(adev,
+										 (i == 0) ?
+										 AMDGPU_UCODE_ID_SDMA0 :
+										 AMDGPU_UCODE_ID_SDMA1);
+				if (r)
+					return -EINVAL;
+			}
 		}
 	}
 
@@ -1427,9 +1429,114 @@ static int sdma_v3_0_process_illegal_ins
 	return 0;
 }
 
+static void fiji_update_sdma_medium_grain_clock_gating(
+		struct amdgpu_device *adev,
+		bool enable)
+{
+	uint32_t temp, data;
+
+	if (enable) {
+		temp = data = RREG32(mmSDMA0_CLK_CTRL);
+		data &= ~(SDMA0_CLK_CTRL__SOFT_OVERRIDE7_MASK |
+				SDMA0_CLK_CTRL__SOFT_OVERRIDE6_MASK |
+				SDMA0_CLK_CTRL__SOFT_OVERRIDE5_MASK |
+				SDMA0_CLK_CTRL__SOFT_OVERRIDE4_MASK |
+				SDMA0_CLK_CTRL__SOFT_OVERRIDE3_MASK |
+				SDMA0_CLK_CTRL__SOFT_OVERRIDE2_MASK |
+				SDMA0_CLK_CTRL__SOFT_OVERRIDE1_MASK |
+				SDMA0_CLK_CTRL__SOFT_OVERRIDE0_MASK);
+		if (data != temp)
+			WREG32(mmSDMA0_CLK_CTRL, data);
+
+		temp = data = RREG32(mmSDMA1_CLK_CTRL);
+		data &= ~(SDMA1_CLK_CTRL__SOFT_OVERRIDE7_MASK |
+				SDMA1_CLK_CTRL__SOFT_OVERRIDE6_MASK |
+				SDMA1_CLK_CTRL__SOFT_OVERRIDE5_MASK |
+				SDMA1_CLK_CTRL__SOFT_OVERRIDE4_MASK |
+				SDMA1_CLK_CTRL__SOFT_OVERRIDE3_MASK |
+				SDMA1_CLK_CTRL__SOFT_OVERRIDE2_MASK |
+				SDMA1_CLK_CTRL__SOFT_OVERRIDE1_MASK |
+				SDMA1_CLK_CTRL__SOFT_OVERRIDE0_MASK);
+
+		if (data != temp)
+			WREG32(mmSDMA1_CLK_CTRL, data);
+	} else {
+		temp = data = RREG32(mmSDMA0_CLK_CTRL);
+		data |= SDMA0_CLK_CTRL__SOFT_OVERRIDE7_MASK |
+				SDMA0_CLK_CTRL__SOFT_OVERRIDE6_MASK |
+				SDMA0_CLK_CTRL__SOFT_OVERRIDE5_MASK |
+				SDMA0_CLK_CTRL__SOFT_OVERRIDE4_MASK |
+				SDMA0_CLK_CTRL__SOFT_OVERRIDE3_MASK |
+				SDMA0_CLK_CTRL__SOFT_OVERRIDE2_MASK |
+				SDMA0_CLK_CTRL__SOFT_OVERRIDE1_MASK |
+				SDMA0_CLK_CTRL__SOFT_OVERRIDE0_MASK;
+
+		if (data != temp)
+			WREG32(mmSDMA0_CLK_CTRL, data);
+
+		temp = data = RREG32(mmSDMA1_CLK_CTRL);
+		data |= SDMA1_CLK_CTRL__SOFT_OVERRIDE7_MASK |
+				SDMA1_CLK_CTRL__SOFT_OVERRIDE6_MASK |
+				SDMA1_CLK_CTRL__SOFT_OVERRIDE5_MASK |
+				SDMA1_CLK_CTRL__SOFT_OVERRIDE4_MASK |
+				SDMA1_CLK_CTRL__SOFT_OVERRIDE3_MASK |
+				SDMA1_CLK_CTRL__SOFT_OVERRIDE2_MASK |
+				SDMA1_CLK_CTRL__SOFT_OVERRIDE1_MASK |
+				SDMA1_CLK_CTRL__SOFT_OVERRIDE0_MASK;
+
+		if (data != temp)
+			WREG32(mmSDMA1_CLK_CTRL, data);
+	}
+}
+
+static void fiji_update_sdma_medium_grain_light_sleep(
+		struct amdgpu_device *adev,
+		bool enable)
+{
+	uint32_t temp, data;
+
+	if (enable) {
+		temp = data = RREG32(mmSDMA0_POWER_CNTL);
+		data |= SDMA0_POWER_CNTL__MEM_POWER_OVERRIDE_MASK;
+
+		if (temp != data)
+			WREG32(mmSDMA0_POWER_CNTL, data);
+
+		temp = data = RREG32(mmSDMA1_POWER_CNTL);
+		data |= SDMA1_POWER_CNTL__MEM_POWER_OVERRIDE_MASK;
+
+		if (temp != data)
+			WREG32(mmSDMA1_POWER_CNTL, data);
+	} else {
+		temp = data = RREG32(mmSDMA0_POWER_CNTL);
+		data &= ~SDMA0_POWER_CNTL__MEM_POWER_OVERRIDE_MASK;
+
+		if (temp != data)
+			WREG32(mmSDMA0_POWER_CNTL, data);
+
+		temp = data = RREG32(mmSDMA1_POWER_CNTL);
+		data &= ~SDMA1_POWER_CNTL__MEM_POWER_OVERRIDE_MASK;
+
+		if (temp != data)
+			WREG32(mmSDMA1_POWER_CNTL, data);
+	}
+}
+
 static int sdma_v3_0_set_clockgating_state(void *handle,
 					  enum amd_clockgating_state state)
 {
+	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
+
+	switch (adev->asic_type) {
+	case CHIP_FIJI:
+		fiji_update_sdma_medium_grain_clock_gating(adev,
+				state == AMD_CG_STATE_GATE ? true : false);
+		fiji_update_sdma_medium_grain_light_sleep(adev,
+				state == AMD_CG_STATE_GATE ? true : false);
+		break;
+	default:
+		break;
+	}
 	return 0;
 }
 
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/amd/amdgpu/smu7.h
+++ /dev/null
@@ -1,170 +0,0 @@
-/*
- * Copyright 2013 Advanced Micro Devices, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- */
-
-#ifndef SMU7_H
-#define SMU7_H
-
-#pragma pack(push, 1)
-
-#define SMU7_CONTEXT_ID_SMC        1
-#define SMU7_CONTEXT_ID_VBIOS      2
-
-
-#define SMU7_CONTEXT_ID_SMC        1
-#define SMU7_CONTEXT_ID_VBIOS      2
-
-#define SMU7_MAX_LEVELS_VDDC            8
-#define SMU7_MAX_LEVELS_VDDCI           4
-#define SMU7_MAX_LEVELS_MVDD            4
-#define SMU7_MAX_LEVELS_VDDNB           8
-
-#define SMU7_MAX_LEVELS_GRAPHICS        SMU__NUM_SCLK_DPM_STATE   // SCLK + SQ DPM + ULV
-#define SMU7_MAX_LEVELS_MEMORY          SMU__NUM_MCLK_DPM_LEVELS   // MCLK Levels DPM
-#define SMU7_MAX_LEVELS_GIO             SMU__NUM_LCLK_DPM_LEVELS  // LCLK Levels
-#define SMU7_MAX_LEVELS_LINK            SMU__NUM_PCIE_DPM_LEVELS  // PCIe speed and number of lanes.
-#define SMU7_MAX_LEVELS_UVD             8   // VCLK/DCLK levels for UVD.
-#define SMU7_MAX_LEVELS_VCE             8   // ECLK levels for VCE.
-#define SMU7_MAX_LEVELS_ACP             8   // ACLK levels for ACP.
-#define SMU7_MAX_LEVELS_SAMU            8   // SAMCLK levels for SAMU.
-#define SMU7_MAX_ENTRIES_SMIO           32  // Number of entries in SMIO table.
-
-#define DPM_NO_LIMIT 0
-#define DPM_NO_UP 1
-#define DPM_GO_DOWN 2
-#define DPM_GO_UP 3
-
-#define SMU7_FIRST_DPM_GRAPHICS_LEVEL    0
-#define SMU7_FIRST_DPM_MEMORY_LEVEL      0
-
-#define GPIO_CLAMP_MODE_VRHOT      1
-#define GPIO_CLAMP_MODE_THERM      2
-#define GPIO_CLAMP_MODE_DC         4
-
-#define SCRATCH_B_TARG_PCIE_INDEX_SHIFT 0
-#define SCRATCH_B_TARG_PCIE_INDEX_MASK  (0x7<<SCRATCH_B_TARG_PCIE_INDEX_SHIFT)
-#define SCRATCH_B_CURR_PCIE_INDEX_SHIFT 3
-#define SCRATCH_B_CURR_PCIE_INDEX_MASK  (0x7<<SCRATCH_B_CURR_PCIE_INDEX_SHIFT)
-#define SCRATCH_B_TARG_UVD_INDEX_SHIFT  6
-#define SCRATCH_B_TARG_UVD_INDEX_MASK   (0x7<<SCRATCH_B_TARG_UVD_INDEX_SHIFT)
-#define SCRATCH_B_CURR_UVD_INDEX_SHIFT  9
-#define SCRATCH_B_CURR_UVD_INDEX_MASK   (0x7<<SCRATCH_B_CURR_UVD_INDEX_SHIFT)
-#define SCRATCH_B_TARG_VCE_INDEX_SHIFT  12
-#define SCRATCH_B_TARG_VCE_INDEX_MASK   (0x7<<SCRATCH_B_TARG_VCE_INDEX_SHIFT)
-#define SCRATCH_B_CURR_VCE_INDEX_SHIFT  15
-#define SCRATCH_B_CURR_VCE_INDEX_MASK   (0x7<<SCRATCH_B_CURR_VCE_INDEX_SHIFT)
-#define SCRATCH_B_TARG_ACP_INDEX_SHIFT  18
-#define SCRATCH_B_TARG_ACP_INDEX_MASK   (0x7<<SCRATCH_B_TARG_ACP_INDEX_SHIFT)
-#define SCRATCH_B_CURR_ACP_INDEX_SHIFT  21
-#define SCRATCH_B_CURR_ACP_INDEX_MASK   (0x7<<SCRATCH_B_CURR_ACP_INDEX_SHIFT)
-#define SCRATCH_B_TARG_SAMU_INDEX_SHIFT 24
-#define SCRATCH_B_TARG_SAMU_INDEX_MASK  (0x7<<SCRATCH_B_TARG_SAMU_INDEX_SHIFT)
-#define SCRATCH_B_CURR_SAMU_INDEX_SHIFT 27
-#define SCRATCH_B_CURR_SAMU_INDEX_MASK  (0x7<<SCRATCH_B_CURR_SAMU_INDEX_SHIFT)
-
-
-struct SMU7_PIDController
-{
-    uint32_t Ki;
-    int32_t LFWindupUL;
-    int32_t LFWindupLL;
-    uint32_t StatePrecision;
-    uint32_t LfPrecision;
-    uint32_t LfOffset;
-    uint32_t MaxState;
-    uint32_t MaxLfFraction;
-    uint32_t StateShift;
-};
-
-typedef struct SMU7_PIDController SMU7_PIDController;
-
-// -------------------------------------------------------------------------------------------------------------------------
-#define SMU7_MAX_PCIE_LINK_SPEEDS 3 /* 0:Gen1 1:Gen2 2:Gen3 */
-
-#define SMU7_SCLK_DPM_CONFIG_MASK                        0x01
-#define SMU7_VOLTAGE_CONTROLLER_CONFIG_MASK              0x02
-#define SMU7_THERMAL_CONTROLLER_CONFIG_MASK              0x04
-#define SMU7_MCLK_DPM_CONFIG_MASK                        0x08
-#define SMU7_UVD_DPM_CONFIG_MASK                         0x10
-#define SMU7_VCE_DPM_CONFIG_MASK                         0x20
-#define SMU7_ACP_DPM_CONFIG_MASK                         0x40
-#define SMU7_SAMU_DPM_CONFIG_MASK                        0x80
-#define SMU7_PCIEGEN_DPM_CONFIG_MASK                    0x100
-
-#define SMU7_ACP_MCLK_HANDSHAKE_DISABLE                  0x00000001
-#define SMU7_ACP_SCLK_HANDSHAKE_DISABLE                  0x00000002
-#define SMU7_UVD_MCLK_HANDSHAKE_DISABLE                  0x00000100
-#define SMU7_UVD_SCLK_HANDSHAKE_DISABLE                  0x00000200
-#define SMU7_VCE_MCLK_HANDSHAKE_DISABLE                  0x00010000
-#define SMU7_VCE_SCLK_HANDSHAKE_DISABLE                  0x00020000
-
-struct SMU7_Firmware_Header
-{
-    uint32_t Digest[5];
-    uint32_t Version;
-    uint32_t HeaderSize;
-    uint32_t Flags;
-    uint32_t EntryPoint;
-    uint32_t CodeSize;
-    uint32_t ImageSize;
-
-    uint32_t Rtos;
-    uint32_t SoftRegisters;
-    uint32_t DpmTable;
-    uint32_t FanTable;
-    uint32_t CacConfigTable;
-    uint32_t CacStatusTable;
-
-    uint32_t mcRegisterTable;
-
-    uint32_t mcArbDramTimingTable;
-
-    uint32_t PmFuseTable;
-    uint32_t Globals;
-    uint32_t Reserved[42];
-    uint32_t Signature;
-};
-
-typedef struct SMU7_Firmware_Header SMU7_Firmware_Header;
-
-#define SMU7_FIRMWARE_HEADER_LOCATION 0x20000
-
-enum  DisplayConfig {
-    PowerDown = 1,
-    DP54x4,
-    DP54x2,
-    DP54x1,
-    DP27x4,
-    DP27x2,
-    DP27x1,
-    HDMI297,
-    HDMI162,
-    LVDS,
-    DP324x4,
-    DP324x2,
-    DP324x1
-};
-
-#pragma pack(pop)
-
-#endif
-
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/amd/amdgpu/smu7_discrete.h
+++ /dev/null
@@ -1,514 +0,0 @@
-/*
- * Copyright 2013 Advanced Micro Devices, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- */
-
-#ifndef SMU7_DISCRETE_H
-#define SMU7_DISCRETE_H
-
-#include "smu7.h"
-
-#pragma pack(push, 1)
-
-#define SMU7_DTE_ITERATIONS 5
-#define SMU7_DTE_SOURCES 3
-#define SMU7_DTE_SINKS 1
-#define SMU7_NUM_CPU_TES 0
-#define SMU7_NUM_GPU_TES 1
-#define SMU7_NUM_NON_TES 2
-
-struct SMU7_SoftRegisters
-{
-    uint32_t        RefClockFrequency;
-    uint32_t        PmTimerP;
-    uint32_t        FeatureEnables;
-    uint32_t        PreVBlankGap;
-    uint32_t        VBlankTimeout;
-    uint32_t        TrainTimeGap;
-
-    uint32_t        MvddSwitchTime;
-    uint32_t        LongestAcpiTrainTime;
-    uint32_t        AcpiDelay;
-    uint32_t        G5TrainTime;
-    uint32_t        DelayMpllPwron;
-    uint32_t        VoltageChangeTimeout;
-    uint32_t        HandshakeDisables;
-
-    uint8_t         DisplayPhy1Config;
-    uint8_t         DisplayPhy2Config;
-    uint8_t         DisplayPhy3Config;
-    uint8_t         DisplayPhy4Config;
-
-    uint8_t         DisplayPhy5Config;
-    uint8_t         DisplayPhy6Config;
-    uint8_t         DisplayPhy7Config;
-    uint8_t         DisplayPhy8Config;
-
-    uint32_t        AverageGraphicsA;
-    uint32_t        AverageMemoryA;
-    uint32_t        AverageGioA;
-
-    uint8_t         SClkDpmEnabledLevels;
-    uint8_t         MClkDpmEnabledLevels;
-    uint8_t         LClkDpmEnabledLevels;
-    uint8_t         PCIeDpmEnabledLevels;
-
-    uint8_t         UVDDpmEnabledLevels;
-    uint8_t         SAMUDpmEnabledLevels;
-    uint8_t         ACPDpmEnabledLevels;
-    uint8_t         VCEDpmEnabledLevels;
-
-    uint32_t        DRAM_LOG_ADDR_H;
-    uint32_t        DRAM_LOG_ADDR_L;
-    uint32_t        DRAM_LOG_PHY_ADDR_H;
-    uint32_t        DRAM_LOG_PHY_ADDR_L;
-    uint32_t        DRAM_LOG_BUFF_SIZE;
-    uint32_t        UlvEnterC;
-    uint32_t        UlvTime;
-    uint32_t        Reserved[3];
-
-};
-
-typedef struct SMU7_SoftRegisters SMU7_SoftRegisters;
-
-struct SMU7_Discrete_VoltageLevel
-{
-    uint16_t    Voltage;
-    uint16_t    StdVoltageHiSidd;
-    uint16_t    StdVoltageLoSidd;
-    uint8_t     Smio;
-    uint8_t     padding;
-};
-
-typedef struct SMU7_Discrete_VoltageLevel SMU7_Discrete_VoltageLevel;
-
-struct SMU7_Discrete_GraphicsLevel
-{
-    uint32_t    Flags;
-    uint32_t    MinVddc;
-    uint32_t    MinVddcPhases;
-
-    uint32_t    SclkFrequency;
-
-    uint8_t     padding1[2];
-    uint16_t    ActivityLevel;
-
-    uint32_t    CgSpllFuncCntl3;
-    uint32_t    CgSpllFuncCntl4;
-    uint32_t    SpllSpreadSpectrum;
-    uint32_t    SpllSpreadSpectrum2;
-    uint32_t    CcPwrDynRm;
-    uint32_t    CcPwrDynRm1;
-    uint8_t     SclkDid;
-    uint8_t     DisplayWatermark;
-    uint8_t     EnabledForActivity;
-    uint8_t     EnabledForThrottle;
-    uint8_t     UpH;
-    uint8_t     DownH;
-    uint8_t     VoltageDownH;
-    uint8_t     PowerThrottle;
-    uint8_t     DeepSleepDivId;
-    uint8_t     padding[3];
-};
-
-typedef struct SMU7_Discrete_GraphicsLevel SMU7_Discrete_GraphicsLevel;
-
-struct SMU7_Discrete_ACPILevel
-{
-    uint32_t    Flags;
-    uint32_t    MinVddc;
-    uint32_t    MinVddcPhases;
-    uint32_t    SclkFrequency;
-    uint8_t     SclkDid;
-    uint8_t     DisplayWatermark;
-    uint8_t     DeepSleepDivId;
-    uint8_t     padding;
-    uint32_t    CgSpllFuncCntl;
-    uint32_t    CgSpllFuncCntl2;
-    uint32_t    CgSpllFuncCntl3;
-    uint32_t    CgSpllFuncCntl4;
-    uint32_t    SpllSpreadSpectrum;
-    uint32_t    SpllSpreadSpectrum2;
-    uint32_t    CcPwrDynRm;
-    uint32_t    CcPwrDynRm1;
-};
-
-typedef struct SMU7_Discrete_ACPILevel SMU7_Discrete_ACPILevel;
-
-struct SMU7_Discrete_Ulv
-{
-    uint32_t    CcPwrDynRm;
-    uint32_t    CcPwrDynRm1;
-    uint16_t    VddcOffset;
-    uint8_t     VddcOffsetVid;
-    uint8_t     VddcPhase;
-    uint32_t    Reserved;
-};
-
-typedef struct SMU7_Discrete_Ulv SMU7_Discrete_Ulv;
-
-struct SMU7_Discrete_MemoryLevel
-{
-    uint32_t    MinVddc;
-    uint32_t    MinVddcPhases;
-    uint32_t    MinVddci;
-    uint32_t    MinMvdd;
-
-    uint32_t    MclkFrequency;
-
-    uint8_t     EdcReadEnable;
-    uint8_t     EdcWriteEnable;
-    uint8_t     RttEnable;
-    uint8_t     StutterEnable;
-
-    uint8_t     StrobeEnable;
-    uint8_t     StrobeRatio;
-    uint8_t     EnabledForThrottle;
-    uint8_t     EnabledForActivity;
-
-    uint8_t     UpH;
-    uint8_t     DownH;
-    uint8_t     VoltageDownH;
-    uint8_t     padding;
-
-    uint16_t    ActivityLevel;
-    uint8_t     DisplayWatermark;
-    uint8_t     padding1;
-
-    uint32_t    MpllFuncCntl;
-    uint32_t    MpllFuncCntl_1;
-    uint32_t    MpllFuncCntl_2;
-    uint32_t    MpllAdFuncCntl;
-    uint32_t    MpllDqFuncCntl;
-    uint32_t    MclkPwrmgtCntl;
-    uint32_t    DllCntl;
-    uint32_t    MpllSs1;
-    uint32_t    MpllSs2;
-};
-
-typedef struct SMU7_Discrete_MemoryLevel SMU7_Discrete_MemoryLevel;
-
-struct SMU7_Discrete_LinkLevel
-{
-    uint8_t     PcieGenSpeed;
-    uint8_t     PcieLaneCount;
-    uint8_t     EnabledForActivity;
-    uint8_t     Padding;
-    uint32_t    DownT;
-    uint32_t    UpT;
-    uint32_t    Reserved;
-};
-
-typedef struct SMU7_Discrete_LinkLevel SMU7_Discrete_LinkLevel;
-
-
-struct SMU7_Discrete_MCArbDramTimingTableEntry
-{
-    uint32_t McArbDramTiming;
-    uint32_t McArbDramTiming2;
-    uint8_t  McArbBurstTime;
-    uint8_t  padding[3];
-};
-
-typedef struct SMU7_Discrete_MCArbDramTimingTableEntry SMU7_Discrete_MCArbDramTimingTableEntry;
-
-struct SMU7_Discrete_MCArbDramTimingTable
-{
-    SMU7_Discrete_MCArbDramTimingTableEntry entries[SMU__NUM_SCLK_DPM_STATE][SMU__NUM_MCLK_DPM_LEVELS];
-};
-
-typedef struct SMU7_Discrete_MCArbDramTimingTable SMU7_Discrete_MCArbDramTimingTable;
-
-struct SMU7_Discrete_UvdLevel
-{
-    uint32_t VclkFrequency;
-    uint32_t DclkFrequency;
-    uint16_t MinVddc;
-    uint8_t  MinVddcPhases;
-    uint8_t  VclkDivider;
-    uint8_t  DclkDivider;
-    uint8_t  padding[3];
-};
-
-typedef struct SMU7_Discrete_UvdLevel SMU7_Discrete_UvdLevel;
-
-struct SMU7_Discrete_ExtClkLevel
-{
-    uint32_t Frequency;
-    uint16_t MinVoltage;
-    uint8_t  MinPhases;
-    uint8_t  Divider;
-};
-
-typedef struct SMU7_Discrete_ExtClkLevel SMU7_Discrete_ExtClkLevel;
-
-struct SMU7_Discrete_StateInfo
-{
-    uint32_t SclkFrequency;
-    uint32_t MclkFrequency;
-    uint32_t VclkFrequency;
-    uint32_t DclkFrequency;
-    uint32_t SamclkFrequency;
-    uint32_t AclkFrequency;
-    uint32_t EclkFrequency;
-    uint16_t MvddVoltage;
-    uint16_t padding16;
-    uint8_t  DisplayWatermark;
-    uint8_t  McArbIndex;
-    uint8_t  McRegIndex;
-    uint8_t  SeqIndex;
-    uint8_t  SclkDid;
-    int8_t   SclkIndex;
-    int8_t   MclkIndex;
-    uint8_t  PCIeGen;
-
-};
-
-typedef struct SMU7_Discrete_StateInfo SMU7_Discrete_StateInfo;
-
-
-struct SMU7_Discrete_DpmTable
-{
-    SMU7_PIDController                  GraphicsPIDController;
-    SMU7_PIDController                  MemoryPIDController;
-    SMU7_PIDController                  LinkPIDController;
-
-    uint32_t                            SystemFlags;
-
-
-    uint32_t                            SmioMaskVddcVid;
-    uint32_t                            SmioMaskVddcPhase;
-    uint32_t                            SmioMaskVddciVid;
-    uint32_t                            SmioMaskMvddVid;
-
-    uint32_t                            VddcLevelCount;
-    uint32_t                            VddciLevelCount;
-    uint32_t                            MvddLevelCount;
-
-    SMU7_Discrete_VoltageLevel          VddcLevel               [SMU7_MAX_LEVELS_VDDC];
-//    SMU7_Discrete_VoltageLevel          VddcStandardReference   [SMU7_MAX_LEVELS_VDDC];
-    SMU7_Discrete_VoltageLevel          VddciLevel              [SMU7_MAX_LEVELS_VDDCI];
-    SMU7_Discrete_VoltageLevel          MvddLevel               [SMU7_MAX_LEVELS_MVDD];
-
-    uint8_t                             GraphicsDpmLevelCount;
-    uint8_t                             MemoryDpmLevelCount;
-    uint8_t                             LinkLevelCount;
-    uint8_t                             UvdLevelCount;
-    uint8_t                             VceLevelCount;
-    uint8_t                             AcpLevelCount;
-    uint8_t                             SamuLevelCount;
-    uint8_t                             MasterDeepSleepControl;
-    uint32_t                            Reserved[5];
-//    uint32_t                            SamuDefaultLevel;
-
-    SMU7_Discrete_GraphicsLevel         GraphicsLevel           [SMU7_MAX_LEVELS_GRAPHICS];
-    SMU7_Discrete_MemoryLevel           MemoryACPILevel;
-    SMU7_Discrete_MemoryLevel           MemoryLevel             [SMU7_MAX_LEVELS_MEMORY];
-    SMU7_Discrete_LinkLevel             LinkLevel               [SMU7_MAX_LEVELS_LINK];
-    SMU7_Discrete_ACPILevel             ACPILevel;
-    SMU7_Discrete_UvdLevel              UvdLevel                [SMU7_MAX_LEVELS_UVD];
-    SMU7_Discrete_ExtClkLevel           VceLevel                [SMU7_MAX_LEVELS_VCE];
-    SMU7_Discrete_ExtClkLevel           AcpLevel                [SMU7_MAX_LEVELS_ACP];
-    SMU7_Discrete_ExtClkLevel           SamuLevel               [SMU7_MAX_LEVELS_SAMU];
-    SMU7_Discrete_Ulv                   Ulv;
-
-    uint32_t                            SclkStepSize;
-    uint32_t                            Smio                    [SMU7_MAX_ENTRIES_SMIO];
-
-    uint8_t                             UvdBootLevel;
-    uint8_t                             VceBootLevel;
-    uint8_t                             AcpBootLevel;
-    uint8_t                             SamuBootLevel;
-
-    uint8_t                             UVDInterval;
-    uint8_t                             VCEInterval;
-    uint8_t                             ACPInterval;
-    uint8_t                             SAMUInterval;
-
-    uint8_t                             GraphicsBootLevel;
-    uint8_t                             GraphicsVoltageChangeEnable;
-    uint8_t                             GraphicsThermThrottleEnable;
-    uint8_t                             GraphicsInterval;
-
-    uint8_t                             VoltageInterval;
-    uint8_t                             ThermalInterval;
-    uint16_t                            TemperatureLimitHigh;
-
-    uint16_t                            TemperatureLimitLow;
-    uint8_t                             MemoryBootLevel;
-    uint8_t                             MemoryVoltageChangeEnable;
-
-    uint8_t                             MemoryInterval;
-    uint8_t                             MemoryThermThrottleEnable;
-    uint16_t                            VddcVddciDelta;
-
-    uint16_t                            VoltageResponseTime;
-    uint16_t                            PhaseResponseTime;
-
-    uint8_t                             PCIeBootLinkLevel;
-    uint8_t                             PCIeGenInterval;
-    uint8_t                             DTEInterval;
-    uint8_t                             DTEMode;
-
-    uint8_t                             SVI2Enable;
-    uint8_t                             VRHotGpio;
-    uint8_t                             AcDcGpio;
-    uint8_t                             ThermGpio;
-
-    uint16_t                            PPM_PkgPwrLimit;
-    uint16_t                            PPM_TemperatureLimit;
-
-    uint16_t                            DefaultTdp;
-    uint16_t                            TargetTdp;
-
-    uint16_t                            FpsHighT;
-    uint16_t                            FpsLowT;
-
-    uint16_t                            BAPMTI_R  [SMU7_DTE_ITERATIONS][SMU7_DTE_SOURCES][SMU7_DTE_SINKS];
-    uint16_t                            BAPMTI_RC [SMU7_DTE_ITERATIONS][SMU7_DTE_SOURCES][SMU7_DTE_SINKS];
-
-    uint8_t                             DTEAmbientTempBase;
-    uint8_t                             DTETjOffset;
-    uint8_t                             GpuTjMax;
-    uint8_t                             GpuTjHyst;
-
-    uint16_t                            BootVddc;
-    uint16_t                            BootVddci;
-
-    uint16_t                            BootMVdd;
-    uint16_t                            padding;
-
-    uint32_t                            BAPM_TEMP_GRADIENT;
-
-    uint32_t                            LowSclkInterruptT;
-};
-
-typedef struct SMU7_Discrete_DpmTable SMU7_Discrete_DpmTable;
-
-#define SMU7_DISCRETE_MC_REGISTER_ARRAY_SIZE 16
-#define SMU7_DISCRETE_MC_REGISTER_ARRAY_SET_COUNT SMU7_MAX_LEVELS_MEMORY
-
-struct SMU7_Discrete_MCRegisterAddress
-{
-    uint16_t s0;
-    uint16_t s1;
-};
-
-typedef struct SMU7_Discrete_MCRegisterAddress SMU7_Discrete_MCRegisterAddress;
-
-struct SMU7_Discrete_MCRegisterSet
-{
-    uint32_t value[SMU7_DISCRETE_MC_REGISTER_ARRAY_SIZE];
-};
-
-typedef struct SMU7_Discrete_MCRegisterSet SMU7_Discrete_MCRegisterSet;
-
-struct SMU7_Discrete_MCRegisters
-{
-    uint8_t                             last;
-    uint8_t                             reserved[3];
-    SMU7_Discrete_MCRegisterAddress     address[SMU7_DISCRETE_MC_REGISTER_ARRAY_SIZE];
-    SMU7_Discrete_MCRegisterSet         data[SMU7_DISCRETE_MC_REGISTER_ARRAY_SET_COUNT];
-};
-
-typedef struct SMU7_Discrete_MCRegisters SMU7_Discrete_MCRegisters;
-
-struct SMU7_Discrete_FanTable
-{
-	uint16_t FdoMode;
-	int16_t  TempMin;
-	int16_t  TempMed;
-	int16_t  TempMax;
-	int16_t  Slope1;
-	int16_t  Slope2;
-	int16_t  FdoMin;
-	int16_t  HystUp;
-	int16_t  HystDown;
-	int16_t  HystSlope;
-	int16_t  TempRespLim;
-	int16_t  TempCurr;
-	int16_t  SlopeCurr;
-	int16_t  PwmCurr;
-	uint32_t RefreshPeriod;
-	int16_t  FdoMax;
-	uint8_t  TempSrc;
-	int8_t   Padding;
-};
-
-typedef struct SMU7_Discrete_FanTable SMU7_Discrete_FanTable;
-
-
-struct SMU7_Discrete_PmFuses {
-  // dw0-dw1
-  uint8_t BapmVddCVidHiSidd[8];
-
-  // dw2-dw3
-  uint8_t BapmVddCVidLoSidd[8];
-
-  // dw4-dw5
-  uint8_t VddCVid[8];
-
-  // dw6
-  uint8_t SviLoadLineEn;
-  uint8_t SviLoadLineVddC;
-  uint8_t SviLoadLineTrimVddC;
-  uint8_t SviLoadLineOffsetVddC;
-
-  // dw7
-  uint16_t TDC_VDDC_PkgLimit;
-  uint8_t TDC_VDDC_ThrottleReleaseLimitPerc;
-  uint8_t TDC_MAWt;
-
-  // dw8
-  uint8_t TdcWaterfallCtl;
-  uint8_t LPMLTemperatureMin;
-  uint8_t LPMLTemperatureMax;
-  uint8_t Reserved;
-
-  // dw9-dw10
-  uint8_t BapmVddCVidHiSidd2[8];
-
-  // dw11-dw12
-  int16_t FuzzyFan_ErrorSetDelta;
-  int16_t FuzzyFan_ErrorRateSetDelta;
-  int16_t FuzzyFan_PwmSetDelta;
-  uint16_t CalcMeasPowerBlend;
-
-  // dw13-dw16
-  uint8_t GnbLPML[16];
-
-  // dw17
-  uint8_t GnbLPMLMaxVid;
-  uint8_t GnbLPMLMinVid;
-  uint8_t Reserved1[2];
-
-  // dw18
-  uint16_t BapmVddCBaseLeakageHiSidd;
-  uint16_t BapmVddCBaseLeakageLoSidd;
-};
-
-typedef struct SMU7_Discrete_PmFuses SMU7_Discrete_PmFuses;
-
-
-#pragma pack(pop)
-
-#endif
-
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/amd/amdgpu/smu7_fusion.h
+++ /dev/null
@@ -1,300 +0,0 @@
-/*
- * Copyright 2013 Advanced Micro Devices, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- */
-
-#ifndef SMU7_FUSION_H
-#define SMU7_FUSION_H
-
-#include "smu7.h"
-
-#pragma pack(push, 1)
-
-#define SMU7_DTE_ITERATIONS 5
-#define SMU7_DTE_SOURCES 5
-#define SMU7_DTE_SINKS 3
-#define SMU7_NUM_CPU_TES 2
-#define SMU7_NUM_GPU_TES 1
-#define SMU7_NUM_NON_TES 2
-
-// All 'soft registers' should be uint32_t.
-struct SMU7_SoftRegisters
-{
-    uint32_t        RefClockFrequency;
-    uint32_t        PmTimerP;
-    uint32_t        FeatureEnables;
-    uint32_t        HandshakeDisables;
-
-    uint8_t         DisplayPhy1Config;
-    uint8_t         DisplayPhy2Config;
-    uint8_t         DisplayPhy3Config;
-    uint8_t         DisplayPhy4Config;
-
-    uint8_t         DisplayPhy5Config;
-    uint8_t         DisplayPhy6Config;
-    uint8_t         DisplayPhy7Config;
-    uint8_t         DisplayPhy8Config;
-
-    uint32_t        AverageGraphicsA;
-    uint32_t        AverageMemoryA;
-    uint32_t        AverageGioA;
-
-    uint8_t         SClkDpmEnabledLevels;
-    uint8_t         MClkDpmEnabledLevels;
-    uint8_t         LClkDpmEnabledLevels;
-    uint8_t         PCIeDpmEnabledLevels;
-
-    uint8_t         UVDDpmEnabledLevels;
-    uint8_t         SAMUDpmEnabledLevels;
-    uint8_t         ACPDpmEnabledLevels;
-    uint8_t         VCEDpmEnabledLevels;
-
-    uint32_t        DRAM_LOG_ADDR_H;
-    uint32_t        DRAM_LOG_ADDR_L;
-    uint32_t        DRAM_LOG_PHY_ADDR_H;
-    uint32_t        DRAM_LOG_PHY_ADDR_L;
-    uint32_t        DRAM_LOG_BUFF_SIZE;
-    uint32_t        UlvEnterC;
-    uint32_t        UlvTime;
-    uint32_t        Reserved[3];
-
-};
-
-typedef struct SMU7_SoftRegisters SMU7_SoftRegisters;
-
-struct SMU7_Fusion_GraphicsLevel
-{
-    uint32_t    MinVddNb;
-
-    uint32_t    SclkFrequency;
-
-    uint8_t     Vid;
-    uint8_t     VidOffset;
-    uint16_t    AT;
-
-    uint8_t     PowerThrottle;
-    uint8_t     GnbSlow;
-    uint8_t     ForceNbPs1;
-    uint8_t     SclkDid;
-
-    uint8_t     DisplayWatermark;
-    uint8_t     EnabledForActivity;
-    uint8_t     EnabledForThrottle;
-    uint8_t     UpH;
-
-    uint8_t     DownH;
-    uint8_t     VoltageDownH;
-    uint8_t     DeepSleepDivId;
-
-    uint8_t     ClkBypassCntl;
-
-    uint32_t    reserved;
-};
-
-typedef struct SMU7_Fusion_GraphicsLevel SMU7_Fusion_GraphicsLevel;
-
-struct SMU7_Fusion_GIOLevel
-{
-    uint8_t     EnabledForActivity;
-    uint8_t     LclkDid;
-    uint8_t     Vid;
-    uint8_t     VoltageDownH;
-
-    uint32_t    MinVddNb;
-
-    uint16_t    ResidencyCounter;
-    uint8_t     UpH;
-    uint8_t     DownH;
-
-    uint32_t    LclkFrequency;
-
-    uint8_t     ActivityLevel;
-    uint8_t     EnabledForThrottle;
-
-    uint8_t     ClkBypassCntl;
-
-    uint8_t     padding;
-};
-
-typedef struct SMU7_Fusion_GIOLevel SMU7_Fusion_GIOLevel;
-
-// UVD VCLK/DCLK state (level) definition.
-struct SMU7_Fusion_UvdLevel
-{
-    uint32_t VclkFrequency;
-    uint32_t DclkFrequency;
-    uint16_t MinVddNb;
-    uint8_t  VclkDivider;
-    uint8_t  DclkDivider;
-
-    uint8_t     VClkBypassCntl;
-    uint8_t     DClkBypassCntl;
-
-    uint8_t     padding[2];
-
-};
-
-typedef struct SMU7_Fusion_UvdLevel SMU7_Fusion_UvdLevel;
-
-// Clocks for other external blocks (VCE, ACP, SAMU).
-struct SMU7_Fusion_ExtClkLevel
-{
-    uint32_t Frequency;
-    uint16_t MinVoltage;
-    uint8_t  Divider;
-    uint8_t  ClkBypassCntl;
-
-    uint32_t Reserved;
-};
-typedef struct SMU7_Fusion_ExtClkLevel SMU7_Fusion_ExtClkLevel;
-
-struct SMU7_Fusion_ACPILevel
-{
-    uint32_t    Flags;
-    uint32_t    MinVddNb;
-    uint32_t    SclkFrequency;
-    uint8_t     SclkDid;
-    uint8_t     GnbSlow;
-    uint8_t     ForceNbPs1;
-    uint8_t     DisplayWatermark;
-    uint8_t     DeepSleepDivId;
-    uint8_t     padding[3];
-};
-
-typedef struct SMU7_Fusion_ACPILevel SMU7_Fusion_ACPILevel;
-
-struct SMU7_Fusion_NbDpm
-{
-    uint8_t DpmXNbPsHi;
-    uint8_t DpmXNbPsLo;
-    uint8_t Dpm0PgNbPsHi;
-    uint8_t Dpm0PgNbPsLo;
-    uint8_t EnablePsi1;
-    uint8_t SkipDPM0;
-    uint8_t SkipPG;
-    uint8_t Hysteresis;
-    uint8_t EnableDpmPstatePoll;
-    uint8_t padding[3];
-};
-
-typedef struct SMU7_Fusion_NbDpm SMU7_Fusion_NbDpm;
-
-struct SMU7_Fusion_StateInfo
-{
-    uint32_t SclkFrequency;
-    uint32_t LclkFrequency;
-    uint32_t VclkFrequency;
-    uint32_t DclkFrequency;
-    uint32_t SamclkFrequency;
-    uint32_t AclkFrequency;
-    uint32_t EclkFrequency;
-    uint8_t  DisplayWatermark;
-    uint8_t  McArbIndex;
-    int8_t   SclkIndex;
-    int8_t   MclkIndex;
-};
-
-typedef struct SMU7_Fusion_StateInfo SMU7_Fusion_StateInfo;
-
-struct SMU7_Fusion_DpmTable
-{
-    uint32_t                            SystemFlags;
-
-    SMU7_PIDController                  GraphicsPIDController;
-    SMU7_PIDController                  GioPIDController;
-
-    uint8_t                            GraphicsDpmLevelCount;
-    uint8_t                            GIOLevelCount;
-    uint8_t                            UvdLevelCount;
-    uint8_t                            VceLevelCount;
-
-    uint8_t                            AcpLevelCount;
-    uint8_t                            SamuLevelCount;
-    uint16_t                           FpsHighT;
-
-    SMU7_Fusion_GraphicsLevel         GraphicsLevel           [SMU__NUM_SCLK_DPM_STATE];
-    SMU7_Fusion_ACPILevel             ACPILevel;
-    SMU7_Fusion_UvdLevel              UvdLevel                [SMU7_MAX_LEVELS_UVD];
-    SMU7_Fusion_ExtClkLevel           VceLevel                [SMU7_MAX_LEVELS_VCE];
-    SMU7_Fusion_ExtClkLevel           AcpLevel                [SMU7_MAX_LEVELS_ACP];
-    SMU7_Fusion_ExtClkLevel           SamuLevel               [SMU7_MAX_LEVELS_SAMU];
-
-    uint8_t                           UvdBootLevel;
-    uint8_t                           VceBootLevel;
-    uint8_t                           AcpBootLevel;
-    uint8_t                           SamuBootLevel;
-    uint8_t                           UVDInterval;
-    uint8_t                           VCEInterval;
-    uint8_t                           ACPInterval;
-    uint8_t                           SAMUInterval;
-
-    uint8_t                           GraphicsBootLevel;
-    uint8_t                           GraphicsInterval;
-    uint8_t                           GraphicsThermThrottleEnable;
-    uint8_t                           GraphicsVoltageChangeEnable;
-
-    uint8_t                           GraphicsClkSlowEnable;
-    uint8_t                           GraphicsClkSlowDivider;
-    uint16_t                          FpsLowT;
-
-    uint32_t                          DisplayCac;
-    uint32_t                          LowSclkInterruptT;
-
-    uint32_t                          DRAM_LOG_ADDR_H;
-    uint32_t                          DRAM_LOG_ADDR_L;
-    uint32_t                          DRAM_LOG_PHY_ADDR_H;
-    uint32_t                          DRAM_LOG_PHY_ADDR_L;
-    uint32_t                          DRAM_LOG_BUFF_SIZE;
-
-};
-
-struct SMU7_Fusion_GIODpmTable
-{
-
-    SMU7_Fusion_GIOLevel              GIOLevel                [SMU7_MAX_LEVELS_GIO];
-
-    SMU7_PIDController                GioPIDController;
-
-    uint32_t                          GIOLevelCount;
-
-    uint8_t                           Enable;
-    uint8_t                           GIOVoltageChangeEnable;
-    uint8_t                           GIOBootLevel;
-    uint8_t                           padding;
-    uint8_t                           padding1[2];
-    uint8_t                           TargetState;
-    uint8_t                           CurrenttState;
-    uint8_t                           ThrottleOnHtc;
-    uint8_t                           ThermThrottleStatus;
-    uint8_t                           ThermThrottleTempSelect;
-    uint8_t                           ThermThrottleEnable;
-    uint16_t                          TemperatureLimitHigh;
-    uint16_t                          TemperatureLimitLow;
-
-};
-
-typedef struct SMU7_Fusion_DpmTable SMU7_Fusion_DpmTable;
-typedef struct SMU7_Fusion_GIODpmTable SMU7_Fusion_GIODpmTable;
-
-#pragma pack(pop)
-
-#endif
-
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/amd/amdgpu/smu8.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright 2014 Advanced Micro Devices, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- */
-
-#ifndef SMU8_H
-#define SMU8_H
-
-#pragma pack(push, 1)
-
-#define ENABLE_DEBUG_FEATURES
-
-struct SMU8_Firmware_Header {
-	uint32_t Version;
-	uint32_t ImageSize;
-	uint32_t CodeSize;
-	uint32_t HeaderSize;
-	uint32_t EntryPoint;
-	uint32_t Rtos;
-	uint32_t UcodeLoadStatus;
-	uint32_t DpmTable;
-	uint32_t FanTable;
-	uint32_t PmFuseTable;
-	uint32_t Globals;
-	uint32_t Reserved[20];
-	uint32_t Signature;
-};
-
-struct SMU8_MultimediaPowerLogData {
-	uint32_t avgTotalPower;
-	uint32_t avgGpuPower;
-	uint32_t avgUvdPower;
-	uint32_t avgVcePower;
-
-	uint32_t avgSclk;
-	uint32_t avgDclk;
-	uint32_t avgVclk;
-	uint32_t avgEclk;
-
-	uint32_t startTimeHi;
-	uint32_t startTimeLo;
-
-	uint32_t endTimeHi;
-	uint32_t endTimeLo;
-};
-
-#define SMU8_FIRMWARE_HEADER_LOCATION 0x1FF80
-#define SMU8_UNBCSR_START_ADDR 0xC0100000
-
-#define SMN_MP1_SRAM_START_ADDR 0x10000000
-
-#pragma pack(pop)
-
-#endif
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/amd/amdgpu/smu8_fusion.h
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * Copyright 2014 Advanced Micro Devices, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- */
-
-#ifndef SMU8_FUSION_H
-#define SMU8_FUSION_H
-
-#include "smu8.h"
-
-#pragma pack(push, 1)
-
-#define SMU8_MAX_CUS 2
-#define SMU8_PSMS_PER_CU 4
-#define SMU8_CACS_PER_CU 4
-
-struct SMU8_GfxCuPgScoreboard {
-    uint8_t Enabled;
-    uint8_t spare[3];
-};
-
-struct SMU8_Port80MonitorTable {
-	uint32_t MmioAddress;
-	uint32_t MemoryBaseHi;
-	uint32_t MemoryBaseLo;
-	uint16_t MemoryBufferSize;
-	uint16_t MemoryPosition;
-	uint16_t PollingInterval;
-	uint8_t  EnableCsrShadow;
-	uint8_t  EnableDramShadow;
-};
-
-/* Clock Table Definitions */
-#define NUM_SCLK_LEVELS     8
-#define NUM_LCLK_LEVELS     8
-#define NUM_UVD_LEVELS      8
-#define NUM_ECLK_LEVELS     8
-#define NUM_ACLK_LEVELS     8
-
-struct SMU8_Fusion_ClkLevel {
-	uint8_t		GnbVid;
-	uint8_t		GfxVid;
-	uint8_t		DfsDid;
-	uint8_t		DeepSleepDid;
-	uint32_t	DfsBypass;
-	uint32_t	Frequency;
-};
-
-struct SMU8_Fusion_SclkBreakdownTable {
-	struct SMU8_Fusion_ClkLevel ClkLevel[NUM_SCLK_LEVELS];
-	struct SMU8_Fusion_ClkLevel DpmOffLevel;
-	/* SMU8_Fusion_ClkLevel PwrOffLevel; */
-	uint32_t    SclkValidMask;
-	uint32_t    MaxSclkIndex;
-};
-
-struct SMU8_Fusion_LclkBreakdownTable {
-	struct SMU8_Fusion_ClkLevel ClkLevel[NUM_LCLK_LEVELS];
-	struct SMU8_Fusion_ClkLevel DpmOffLevel;
-    /* SMU8_Fusion_ClkLevel PwrOffLevel; */
-	uint32_t    LclkValidMask;
-	uint32_t    MaxLclkIndex;
-};
-
-struct SMU8_Fusion_EclkBreakdownTable {
-	struct SMU8_Fusion_ClkLevel ClkLevel[NUM_ECLK_LEVELS];
-	struct SMU8_Fusion_ClkLevel DpmOffLevel;
-	struct SMU8_Fusion_ClkLevel PwrOffLevel;
-	uint32_t    EclkValidMask;
-	uint32_t    MaxEclkIndex;
-};
-
-struct SMU8_Fusion_VclkBreakdownTable {
-	struct SMU8_Fusion_ClkLevel ClkLevel[NUM_UVD_LEVELS];
-	struct SMU8_Fusion_ClkLevel DpmOffLevel;
-	struct SMU8_Fusion_ClkLevel PwrOffLevel;
-	uint32_t    VclkValidMask;
-	uint32_t    MaxVclkIndex;
-};
-
-struct SMU8_Fusion_DclkBreakdownTable {
-	struct SMU8_Fusion_ClkLevel ClkLevel[NUM_UVD_LEVELS];
-	struct SMU8_Fusion_ClkLevel DpmOffLevel;
-	struct SMU8_Fusion_ClkLevel PwrOffLevel;
-	uint32_t    DclkValidMask;
-	uint32_t    MaxDclkIndex;
-};
-
-struct SMU8_Fusion_AclkBreakdownTable {
-	struct SMU8_Fusion_ClkLevel ClkLevel[NUM_ACLK_LEVELS];
-	struct SMU8_Fusion_ClkLevel DpmOffLevel;
-	struct SMU8_Fusion_ClkLevel PwrOffLevel;
-	uint32_t    AclkValidMask;
-	uint32_t    MaxAclkIndex;
-};
-
-
-struct SMU8_Fusion_ClkTable {
-	struct SMU8_Fusion_SclkBreakdownTable SclkBreakdownTable;
-	struct SMU8_Fusion_LclkBreakdownTable LclkBreakdownTable;
-	struct SMU8_Fusion_EclkBreakdownTable EclkBreakdownTable;
-	struct SMU8_Fusion_VclkBreakdownTable VclkBreakdownTable;
-	struct SMU8_Fusion_DclkBreakdownTable DclkBreakdownTable;
-	struct SMU8_Fusion_AclkBreakdownTable AclkBreakdownTable;
-};
-
-#pragma pack(pop)
-
-#endif
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/amd/amdgpu/smu_ucode_xfer_cz.h
+++ /dev/null
@@ -1,147 +0,0 @@
-// CZ Ucode Loading Definitions
-#ifndef SMU_UCODE_XFER_CZ_H
-#define SMU_UCODE_XFER_CZ_H
-
-#define NUM_JOBLIST_ENTRIES      32
-
-#define TASK_TYPE_NO_ACTION      0
-#define TASK_TYPE_UCODE_LOAD     1
-#define TASK_TYPE_UCODE_SAVE     2
-#define TASK_TYPE_REG_LOAD       3
-#define TASK_TYPE_REG_SAVE       4
-#define TASK_TYPE_INITIALIZE     5
-
-#define TASK_ARG_REG_SMCIND      0
-#define TASK_ARG_REG_MMIO        1
-#define TASK_ARG_REG_FCH         2
-#define TASK_ARG_REG_UNB         3
-
-#define TASK_ARG_INIT_MM_PWR_LOG 0
-#define TASK_ARG_INIT_CLK_TABLE  1
-
-#define JOB_GFX_SAVE             0
-#define JOB_GFX_RESTORE          1
-#define JOB_FCH_SAVE             2
-#define JOB_FCH_RESTORE          3
-#define JOB_UNB_SAVE             4
-#define JOB_UNB_RESTORE          5
-#define JOB_GMC_SAVE             6
-#define JOB_GMC_RESTORE          7
-#define JOB_GNB_SAVE             8
-#define JOB_GNB_RESTORE          9
-
-#define IGNORE_JOB               0xff
-#define END_OF_TASK_LIST     (uint16_t)0xffff
-
-// Size of DRAM regions (in bytes) requested by SMU:
-#define SMU_DRAM_REQ_MM_PWR_LOG 48 
-
-#define UCODE_ID_SDMA0           0
-#define UCODE_ID_SDMA1           1
-#define UCODE_ID_CP_CE           2
-#define UCODE_ID_CP_PFP          3
-#define UCODE_ID_CP_ME           4
-#define UCODE_ID_CP_MEC_JT1      5
-#define UCODE_ID_CP_MEC_JT2      6
-#define UCODE_ID_GMCON_RENG      7
-#define UCODE_ID_RLC_G           8
-#define UCODE_ID_RLC_SCRATCH     9
-#define UCODE_ID_RLC_SRM_ARAM    10
-#define UCODE_ID_RLC_SRM_DRAM    11
-#define UCODE_ID_DMCU_ERAM       12
-#define UCODE_ID_DMCU_IRAM       13
-
-#define UCODE_ID_SDMA0_MASK           0x00000001       
-#define UCODE_ID_SDMA1_MASK           0x00000002        
-#define UCODE_ID_CP_CE_MASK           0x00000004      
-#define UCODE_ID_CP_PFP_MASK          0x00000008         
-#define UCODE_ID_CP_ME_MASK           0x00000010          
-#define UCODE_ID_CP_MEC_JT1_MASK      0x00000020             
-#define UCODE_ID_CP_MEC_JT2_MASK      0x00000040          
-#define UCODE_ID_GMCON_RENG_MASK      0x00000080            
-#define UCODE_ID_RLC_G_MASK           0x00000100           
-#define UCODE_ID_RLC_SCRATCH_MASK     0x00000200         
-#define UCODE_ID_RLC_SRM_ARAM_MASK    0x00000400                
-#define UCODE_ID_RLC_SRM_DRAM_MASK    0x00000800                 
-#define UCODE_ID_DMCU_ERAM_MASK       0x00001000             
-#define UCODE_ID_DMCU_IRAM_MASK       0x00002000              
-
-#define UCODE_ID_SDMA0_SIZE_BYTE           10368        
-#define UCODE_ID_SDMA1_SIZE_BYTE           10368          
-#define UCODE_ID_CP_CE_SIZE_BYTE           8576        
-#define UCODE_ID_CP_PFP_SIZE_BYTE          16768           
-#define UCODE_ID_CP_ME_SIZE_BYTE           16768            
-#define UCODE_ID_CP_MEC_JT1_SIZE_BYTE      384               
-#define UCODE_ID_CP_MEC_JT2_SIZE_BYTE      384            
-#define UCODE_ID_GMCON_RENG_SIZE_BYTE      4096              
-#define UCODE_ID_RLC_G_SIZE_BYTE           2048             
-#define UCODE_ID_RLC_SCRATCH_SIZE_BYTE     132           
-#define UCODE_ID_RLC_SRM_ARAM_SIZE_BYTE    8192                  
-#define UCODE_ID_RLC_SRM_DRAM_SIZE_BYTE    4096                   
-#define UCODE_ID_DMCU_ERAM_SIZE_BYTE       24576               
-#define UCODE_ID_DMCU_IRAM_SIZE_BYTE       1024                 
-
-#define NUM_UCODES               14
-
-typedef struct {
-	uint32_t high;
-	uint32_t low;
-} data_64_t;
-
-struct SMU_Task {
-    uint8_t type;
-    uint8_t arg;
-    uint16_t next;
-    data_64_t addr;
-    uint32_t size_bytes;
-};
-typedef struct SMU_Task SMU_Task;
-
-struct TOC {
-    uint8_t JobList[NUM_JOBLIST_ENTRIES];
-    SMU_Task tasks[1];
-};
-
-// META DATA COMMAND Definitions
-#define METADATA_CMD_MODE0         0x00000103 
-#define METADATA_CMD_MODE1         0x00000113 
-#define METADATA_CMD_MODE2         0x00000123 
-#define METADATA_CMD_MODE3         0x00000133
-#define METADATA_CMD_DELAY         0x00000203
-#define METADATA_CMD_CHNG_REGSPACE 0x00000303
-#define METADATA_PERFORM_ON_SAVE   0x00001000
-#define METADATA_PERFORM_ON_LOAD   0x00002000
-#define METADATA_CMD_ARG_MASK      0xFFFF0000
-#define METADATA_CMD_ARG_SHIFT     16
-
-// Simple register addr/data fields
-struct SMU_MetaData_Mode0 {
-    uint32_t register_address;
-    uint32_t register_data;
-};
-typedef struct SMU_MetaData_Mode0 SMU_MetaData_Mode0;
-
-// Register addr/data with mask
-struct SMU_MetaData_Mode1 {
-    uint32_t register_address;
-    uint32_t register_mask;
-    uint32_t register_data;
-};
-typedef struct SMU_MetaData_Mode1 SMU_MetaData_Mode1;
-
-struct SMU_MetaData_Mode2 {
-    uint32_t register_address;
-    uint32_t register_mask;
-    uint32_t target_value;
-};
-typedef struct SMU_MetaData_Mode2 SMU_MetaData_Mode2;
-
-// Always write data (even on a save operation)
-struct SMU_MetaData_Mode3 {
-    uint32_t register_address;
-    uint32_t register_mask;
-    uint32_t register_data;
-};
-typedef struct SMU_MetaData_Mode3 SMU_MetaData_Mode3;
-
-#endif
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/amd/amdgpu/tonga_dpm.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/amdgpu/tonga_dpm.c
@@ -24,7 +24,7 @@
 #include <linux/firmware.h>
 #include "drmP.h"
 #include "amdgpu.h"
-#include "tonga_smumgr.h"
+#include "tonga_smum.h"
 
 MODULE_FIRMWARE("amdgpu/tonga_smc.bin");
 
@@ -122,25 +122,12 @@ static int tonga_dpm_hw_fini(void *handl
 
 static int tonga_dpm_suspend(void *handle)
 {
-	return 0;
+	return tonga_dpm_hw_fini(handle);
 }
 
 static int tonga_dpm_resume(void *handle)
 {
-	int ret;
-	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
-
-	mutex_lock(&adev->pm.mutex);
-
-	ret = tonga_smu_start(adev);
-	if (ret) {
-		DRM_ERROR("SMU start failed\n");
-		goto fail;
-	}
-
-fail:
-	mutex_unlock(&adev->pm.mutex);
-	return ret;
+	return tonga_dpm_hw_init(handle);
 }
 
 static int tonga_dpm_set_clockgating_state(void *handle,
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/amd/amdgpu/tonga_ih.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/amdgpu/tonga_ih.c
@@ -273,8 +273,14 @@ static void tonga_ih_set_rptr(struct amd
 static int tonga_ih_early_init(void *handle)
 {
 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
+	int ret;
+
+	ret = amdgpu_irq_add_domain(adev);
+	if (ret)
+		return ret;
 
 	tonga_ih_set_interrupt_funcs(adev);
+
 	return 0;
 }
 
@@ -301,6 +307,7 @@ static int tonga_ih_sw_fini(void *handle
 
 	amdgpu_irq_fini(adev);
 	amdgpu_ih_ring_fini(adev);
+	amdgpu_irq_add_domain(adev);
 
 	return 0;
 }
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/amd/amdgpu/tonga_ppsmc.h
+++ /dev/null
@@ -1,198 +0,0 @@
-/*
- * Copyright 2014 Advanced Micro Devices, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- */
-
-#ifndef TONGA_PP_SMC_H
-#define TONGA_PP_SMC_H
-
-#pragma pack(push, 1)
-
-#define PPSMC_SWSTATE_FLAG_DC                           0x01
-#define PPSMC_SWSTATE_FLAG_UVD                          0x02
-#define PPSMC_SWSTATE_FLAG_VCE                          0x04
-#define PPSMC_SWSTATE_FLAG_PCIE_X1                      0x08
-
-#define PPSMC_THERMAL_PROTECT_TYPE_INTERNAL             0x00
-#define PPSMC_THERMAL_PROTECT_TYPE_EXTERNAL             0x01
-#define PPSMC_THERMAL_PROTECT_TYPE_NONE                 0xff 
-
-#define PPSMC_SYSTEMFLAG_GPIO_DC                        0x01 
-#define PPSMC_SYSTEMFLAG_STEPVDDC                       0x02 
-#define PPSMC_SYSTEMFLAG_GDDR5                          0x04 
-
-#define PPSMC_SYSTEMFLAG_DISABLE_BABYSTEP               0x08 
-
-#define PPSMC_SYSTEMFLAG_REGULATOR_HOT                  0x10 
-#define PPSMC_SYSTEMFLAG_REGULATOR_HOT_ANALOG           0x20 
-#define PPSMC_SYSTEMFLAG_12CHANNEL                      0x40
-
-#define PPSMC_EXTRAFLAGS_AC2DC_ACTION_MASK              0x07
-#define PPSMC_EXTRAFLAGS_AC2DC_DONT_WAIT_FOR_VBLANK     0x08
-
-#define PPSMC_EXTRAFLAGS_AC2DC_ACTION_GOTODPMLOWSTATE   0x00
-#define PPSMC_EXTRAFLAGS_AC2DC_ACTION_GOTOINITIALSTATE  0x01
-
-#define PPSMC_EXTRAFLAGS_AC2DC_GPIO5_POLARITY_HIGH      0x10
-#define PPSMC_EXTRAFLAGS_DRIVER_TO_GPIO17               0x20
-#define PPSMC_EXTRAFLAGS_PCC_TO_GPIO17                  0x40
-
-#define PPSMC_DPM2FLAGS_TDPCLMP                         0x01 
-#define PPSMC_DPM2FLAGS_PWRSHFT                         0x02 
-#define PPSMC_DPM2FLAGS_OCP                             0x04 
-
-#define PPSMC_DISPLAY_WATERMARK_LOW                     0
-#define PPSMC_DISPLAY_WATERMARK_HIGH                    1
-
-#define PPSMC_STATEFLAG_AUTO_PULSE_SKIP    		0x01
-#define PPSMC_STATEFLAG_POWERBOOST         		0x02
-#define PPSMC_STATEFLAG_PSKIP_ON_TDP_FAULT 		0x04
-#define PPSMC_STATEFLAG_POWERSHIFT         		0x08
-#define PPSMC_STATEFLAG_SLOW_READ_MARGIN   		0x10
-#define PPSMC_STATEFLAG_DEEPSLEEP_THROTTLE 		0x20
-#define PPSMC_STATEFLAG_DEEPSLEEP_BYPASS   		0x40
-
-#define FDO_MODE_HARDWARE 0
-#define FDO_MODE_PIECE_WISE_LINEAR 1
-
-enum FAN_CONTROL {
-	FAN_CONTROL_FUZZY,
-	FAN_CONTROL_TABLE
-};
-
-#define PPSMC_Result_OK             			((uint16_t)0x01)
-#define PPSMC_Result_NoMore         			((uint16_t)0x02)
-#define PPSMC_Result_NotNow         			((uint16_t)0x03)
-#define PPSMC_Result_Failed         			((uint16_t)0xFF) 
-#define PPSMC_Result_UnknownCmd     			((uint16_t)0xFE) 
-#define PPSMC_Result_UnknownVT      			((uint16_t)0xFD) 
-
-typedef uint16_t PPSMC_Result;
-
-#define PPSMC_isERROR(x) ((uint16_t)0x80 & (x))
-
-#define PPSMC_MSG_Halt                      		((uint16_t)0x10)
-#define PPSMC_MSG_Resume                    		((uint16_t)0x11)
-#define PPSMC_MSG_EnableDPMLevel            		((uint16_t)0x12)
-#define PPSMC_MSG_ZeroLevelsDisabled        		((uint16_t)0x13)
-#define PPSMC_MSG_OneLevelsDisabled         		((uint16_t)0x14)
-#define PPSMC_MSG_TwoLevelsDisabled         		((uint16_t)0x15)
-#define PPSMC_MSG_EnableThermalInterrupt    		((uint16_t)0x16)
-#define PPSMC_MSG_RunningOnAC               		((uint16_t)0x17)
-#define PPSMC_MSG_LevelUp                   		((uint16_t)0x18)
-#define PPSMC_MSG_LevelDown                 		((uint16_t)0x19)
-#define PPSMC_MSG_ResetDPMCounters          		((uint16_t)0x1a)
-#define PPSMC_MSG_SwitchToSwState           		((uint16_t)0x20)
-#define PPSMC_MSG_SwitchToSwStateLast       		((uint16_t)0x3f)
-#define PPSMC_MSG_SwitchToInitialState      		((uint16_t)0x40)
-#define PPSMC_MSG_NoForcedLevel             		((uint16_t)0x41)
-#define PPSMC_MSG_ForceHigh                 		((uint16_t)0x42)
-#define PPSMC_MSG_ForceMediumOrHigh         		((uint16_t)0x43)
-#define PPSMC_MSG_SwitchToMinimumPower      		((uint16_t)0x51)
-#define PPSMC_MSG_ResumeFromMinimumPower    		((uint16_t)0x52)
-#define PPSMC_MSG_EnableCac                 		((uint16_t)0x53)
-#define PPSMC_MSG_DisableCac                		((uint16_t)0x54)
-#define PPSMC_DPMStateHistoryStart          		((uint16_t)0x55)
-#define PPSMC_DPMStateHistoryStop           		((uint16_t)0x56)
-#define PPSMC_CACHistoryStart               		((uint16_t)0x57)
-#define PPSMC_CACHistoryStop                		((uint16_t)0x58)
-#define PPSMC_TDPClampingActive             		((uint16_t)0x59)
-#define PPSMC_TDPClampingInactive           		((uint16_t)0x5A)
-#define PPSMC_StartFanControl               		((uint16_t)0x5B)
-#define PPSMC_StopFanControl                		((uint16_t)0x5C)
-#define PPSMC_NoDisplay                     		((uint16_t)0x5D)
-#define PPSMC_HasDisplay                    		((uint16_t)0x5E)
-#define PPSMC_MSG_UVDPowerOFF               		((uint16_t)0x60)
-#define PPSMC_MSG_UVDPowerON                		((uint16_t)0x61)
-#define PPSMC_MSG_EnableULV                 		((uint16_t)0x62)
-#define PPSMC_MSG_DisableULV                		((uint16_t)0x63)
-#define PPSMC_MSG_EnterULV                  		((uint16_t)0x64)
-#define PPSMC_MSG_ExitULV                   		((uint16_t)0x65)
-#define PPSMC_PowerShiftActive              		((uint16_t)0x6A)
-#define PPSMC_PowerShiftInactive            		((uint16_t)0x6B)
-#define PPSMC_OCPActive                     		((uint16_t)0x6C)
-#define PPSMC_OCPInactive                   		((uint16_t)0x6D)
-#define PPSMC_CACLongTermAvgEnable          		((uint16_t)0x6E)
-#define PPSMC_CACLongTermAvgDisable         		((uint16_t)0x6F)
-#define PPSMC_MSG_InferredStateSweep_Start  		((uint16_t)0x70)
-#define PPSMC_MSG_InferredStateSweep_Stop   		((uint16_t)0x71)
-#define PPSMC_MSG_SwitchToLowestInfState    		((uint16_t)0x72)
-#define PPSMC_MSG_SwitchToNonInfState       		((uint16_t)0x73)
-#define PPSMC_MSG_AllStateSweep_Start       		((uint16_t)0x74)
-#define PPSMC_MSG_AllStateSweep_Stop        		((uint16_t)0x75)
-#define PPSMC_MSG_SwitchNextLowerInfState   		((uint16_t)0x76)
-#define PPSMC_MSG_SwitchNextHigherInfState  		((uint16_t)0x77)
-#define PPSMC_MSG_MclkRetrainingTest        		((uint16_t)0x78)
-#define PPSMC_MSG_ForceTDPClamping          		((uint16_t)0x79)
-#define PPSMC_MSG_CollectCAC_PowerCorreln   		((uint16_t)0x7A)
-#define PPSMC_MSG_CollectCAC_WeightCalib    		((uint16_t)0x7B)
-#define PPSMC_MSG_CollectCAC_SQonly         		((uint16_t)0x7C)
-#define PPSMC_MSG_CollectCAC_TemperaturePwr 		((uint16_t)0x7D)
-#define PPSMC_MSG_ExtremitiesTest_Start     		((uint16_t)0x7E)
-#define PPSMC_MSG_ExtremitiesTest_Stop      		((uint16_t)0x7F)
-#define PPSMC_FlushDataCache                		((uint16_t)0x80)
-#define PPSMC_FlushInstrCache               		((uint16_t)0x81)
-#define PPSMC_MSG_SetEnabledLevels          		((uint16_t)0x82)
-#define PPSMC_MSG_SetForcedLevels           		((uint16_t)0x83)
-#define PPSMC_MSG_ResetToDefaults           		((uint16_t)0x84)
-#define PPSMC_MSG_SetForcedLevelsAndJump    		((uint16_t)0x85)
-#define PPSMC_MSG_SetCACHistoryMode         		((uint16_t)0x86)
-#define PPSMC_MSG_EnableDTE                 		((uint16_t)0x87)
-#define PPSMC_MSG_DisableDTE                		((uint16_t)0x88)
-#define PPSMC_MSG_SmcSpaceSetAddress        		((uint16_t)0x89)
-#define PPSMC_MSG_SmcSpaceWriteDWordInc     		((uint16_t)0x8A)
-#define PPSMC_MSG_SmcSpaceWriteWordInc      		((uint16_t)0x8B)
-#define PPSMC_MSG_SmcSpaceWriteByteInc      		((uint16_t)0x8C)
-#define PPSMC_MSG_ChangeNearTDPLimit        		((uint16_t)0x90)
-#define PPSMC_MSG_ChangeSafePowerLimit      		((uint16_t)0x91)
-#define PPSMC_MSG_DPMStateSweepStart        		((uint16_t)0x92)
-#define PPSMC_MSG_DPMStateSweepStop         		((uint16_t)0x93)
-#define PPSMC_MSG_OVRDDisableSCLKDS         		((uint16_t)0x94)
-#define PPSMC_MSG_CancelDisableOVRDSCLKDS   		((uint16_t)0x95)
-#define PPSMC_MSG_ThrottleOVRDSCLKDS        		((uint16_t)0x96)
-#define PPSMC_MSG_CancelThrottleOVRDSCLKDS  		((uint16_t)0x97)
-#define PPSMC_MSG_GPIO17                    		((uint16_t)0x98)
-#define PPSMC_MSG_API_SetSvi2Volt_Vddc      		((uint16_t)0x99)
-#define PPSMC_MSG_API_SetSvi2Volt_Vddci     		((uint16_t)0x9A)
-#define PPSMC_MSG_API_SetSvi2Volt_Mvdd      		((uint16_t)0x9B)
-#define PPSMC_MSG_API_GetSvi2Volt_Vddc      		((uint16_t)0x9C)
-#define PPSMC_MSG_API_GetSvi2Volt_Vddci     		((uint16_t)0x9D)
-#define PPSMC_MSG_API_GetSvi2Volt_Mvdd      		((uint16_t)0x9E)
-
-#define PPSMC_MSG_BREAK                     		((uint16_t)0xF8)
-
-#define PPSMC_MSG_Test                      		((uint16_t)0x100)
-#define PPSMC_MSG_DRV_DRAM_ADDR_HI            		((uint16_t)0x250)
-#define PPSMC_MSG_DRV_DRAM_ADDR_LO            		((uint16_t)0x251)
-#define PPSMC_MSG_SMU_DRAM_ADDR_HI            		((uint16_t)0x252)
-#define PPSMC_MSG_SMU_DRAM_ADDR_LO            		((uint16_t)0x253)
-#define PPSMC_MSG_LoadUcodes                  		((uint16_t)0x254)
-
-typedef uint16_t PPSMC_Msg;
-
-#define PPSMC_EVENT_STATUS_THERMAL          		0x00000001
-#define PPSMC_EVENT_STATUS_REGULATORHOT     		0x00000002
-#define PPSMC_EVENT_STATUS_DC               		0x00000004
-#define PPSMC_EVENT_STATUS_GPIO17           		0x00000008
-
-#pragma pack(pop)
-
-#endif
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/amd/amdgpu/tonga_smc.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/amdgpu/tonga_smc.c
@@ -25,7 +25,7 @@
 #include "drmP.h"
 #include "amdgpu.h"
 #include "tonga_ppsmc.h"
-#include "tonga_smumgr.h"
+#include "tonga_smum.h"
 #include "smu_ucode_xfer_vi.h"
 #include "amdgpu_ucode.h"
 
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/amdgpu/tonga_smum.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2014 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#ifndef TONGA_SMUMGR_H
+#define TONGA_SMUMGR_H
+
+#include "tonga_ppsmc.h"
+
+int tonga_smu_init(struct amdgpu_device *adev);
+int tonga_smu_fini(struct amdgpu_device *adev);
+int tonga_smu_start(struct amdgpu_device *adev);
+
+struct tonga_smu_private_data
+{
+	uint8_t *header;
+	uint32_t smu_buffer_addr_high;
+	uint32_t smu_buffer_addr_low;
+	uint32_t header_addr_high;
+	uint32_t header_addr_low;
+};
+
+#endif
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/amd/amdgpu/tonga_smumgr.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright 2014 Advanced Micro Devices, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- */
-
-#ifndef TONGA_SMUMGR_H
-#define TONGA_SMUMGR_H
-
-#include "tonga_ppsmc.h"
-
-int tonga_smu_init(struct amdgpu_device *adev);
-int tonga_smu_fini(struct amdgpu_device *adev);
-int tonga_smu_start(struct amdgpu_device *adev);
-
-struct tonga_smu_private_data
-{
-	uint8_t *header;
-	uint32_t smu_buffer_addr_high;
-	uint32_t smu_buffer_addr_low;
-	uint32_t header_addr_high;
-	uint32_t header_addr_low;
-};
-
-#endif
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/amd/amdgpu/uvd_v4_2.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/amdgpu/uvd_v4_2.c
@@ -611,7 +611,7 @@ static void uvd_v4_2_enable_mgcg(struct
 {
 	u32 orig, data;
 
-	if (enable && (adev->cg_flags & AMDGPU_CG_SUPPORT_UVD_MGCG)) {
+	if (enable && (adev->cg_flags & AMD_CG_SUPPORT_UVD_MGCG)) {
 		data = RREG32_UVD_CTX(ixUVD_CGC_MEM_CTRL);
 		data = 0xfff;
 		WREG32_UVD_CTX(ixUVD_CGC_MEM_CTRL, data);
@@ -830,6 +830,9 @@ static int uvd_v4_2_set_clockgating_stat
 	bool gate = false;
 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
 
+	if (!(adev->cg_flags & AMD_CG_SUPPORT_UVD_MGCG))
+		return 0;
+
 	if (state == AMD_CG_STATE_GATE)
 		gate = true;
 
@@ -848,7 +851,10 @@ static int uvd_v4_2_set_powergating_stat
 	 * revisit this when there is a cleaner line between
 	 * the smc and the hw blocks
 	 */
-	 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
+	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
+
+	if (!(adev->pg_flags & AMD_PG_SUPPORT_UVD))
+		return 0;
 
 	if (state == AMD_PG_STATE_GATE) {
 		uvd_v4_2_stop(adev);
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/amd/amdgpu/uvd_v5_0.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/amdgpu/uvd_v5_0.c
@@ -774,6 +774,11 @@ static int uvd_v5_0_process_interrupt(st
 static int uvd_v5_0_set_clockgating_state(void *handle,
 					  enum amd_clockgating_state state)
 {
+	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
+
+	if (!(adev->cg_flags & AMD_CG_SUPPORT_UVD_MGCG))
+		return 0;
+
 	return 0;
 }
 
@@ -789,6 +794,9 @@ static int uvd_v5_0_set_powergating_stat
 	 */
 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
 
+	if (!(adev->pg_flags & AMD_PG_SUPPORT_UVD))
+		return 0;
+
 	if (state == AMD_PG_STATE_GATE) {
 		uvd_v5_0_stop(adev);
 		return 0;
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c
@@ -279,6 +279,234 @@ static void uvd_v6_0_mc_resume(struct am
 	WREG32(mmUVD_VCPU_CACHE_SIZE2, size);
 }
 
+static void cz_set_uvd_clock_gating_branches(struct amdgpu_device *adev,
+		bool enable)
+{
+	u32 data, data1;
+
+	data = RREG32(mmUVD_CGC_GATE);
+	data1 = RREG32(mmUVD_SUVD_CGC_GATE);
+	if (enable) {
+		data |= UVD_CGC_GATE__SYS_MASK |
+				UVD_CGC_GATE__UDEC_MASK |
+				UVD_CGC_GATE__MPEG2_MASK |
+				UVD_CGC_GATE__RBC_MASK |
+				UVD_CGC_GATE__LMI_MC_MASK |
+				UVD_CGC_GATE__IDCT_MASK |
+				UVD_CGC_GATE__MPRD_MASK |
+				UVD_CGC_GATE__MPC_MASK |
+				UVD_CGC_GATE__LBSI_MASK |
+				UVD_CGC_GATE__LRBBM_MASK |
+				UVD_CGC_GATE__UDEC_RE_MASK |
+				UVD_CGC_GATE__UDEC_CM_MASK |
+				UVD_CGC_GATE__UDEC_IT_MASK |
+				UVD_CGC_GATE__UDEC_DB_MASK |
+				UVD_CGC_GATE__UDEC_MP_MASK |
+				UVD_CGC_GATE__WCB_MASK |
+				UVD_CGC_GATE__VCPU_MASK |
+				UVD_CGC_GATE__SCPU_MASK;
+		data1 |= UVD_SUVD_CGC_GATE__SRE_MASK |
+				UVD_SUVD_CGC_GATE__SIT_MASK |
+				UVD_SUVD_CGC_GATE__SMP_MASK |
+				UVD_SUVD_CGC_GATE__SCM_MASK |
+				UVD_SUVD_CGC_GATE__SDB_MASK |
+				UVD_SUVD_CGC_GATE__SRE_H264_MASK |
+				UVD_SUVD_CGC_GATE__SRE_HEVC_MASK |
+				UVD_SUVD_CGC_GATE__SIT_H264_MASK |
+				UVD_SUVD_CGC_GATE__SIT_HEVC_MASK |
+				UVD_SUVD_CGC_GATE__SCM_H264_MASK |
+				UVD_SUVD_CGC_GATE__SCM_HEVC_MASK |
+				UVD_SUVD_CGC_GATE__SDB_H264_MASK |
+				UVD_SUVD_CGC_GATE__SDB_HEVC_MASK;
+	} else {
+		data &= ~(UVD_CGC_GATE__SYS_MASK |
+				UVD_CGC_GATE__UDEC_MASK |
+				UVD_CGC_GATE__MPEG2_MASK |
+				UVD_CGC_GATE__RBC_MASK |
+				UVD_CGC_GATE__LMI_MC_MASK |
+				UVD_CGC_GATE__LMI_UMC_MASK |
+				UVD_CGC_GATE__IDCT_MASK |
+				UVD_CGC_GATE__MPRD_MASK |
+				UVD_CGC_GATE__MPC_MASK |
+				UVD_CGC_GATE__LBSI_MASK |
+				UVD_CGC_GATE__LRBBM_MASK |
+				UVD_CGC_GATE__UDEC_RE_MASK |
+				UVD_CGC_GATE__UDEC_CM_MASK |
+				UVD_CGC_GATE__UDEC_IT_MASK |
+				UVD_CGC_GATE__UDEC_DB_MASK |
+				UVD_CGC_GATE__UDEC_MP_MASK |
+				UVD_CGC_GATE__WCB_MASK |
+				UVD_CGC_GATE__VCPU_MASK |
+				UVD_CGC_GATE__SCPU_MASK);
+		data1 &= ~(UVD_SUVD_CGC_GATE__SRE_MASK |
+				UVD_SUVD_CGC_GATE__SIT_MASK |
+				UVD_SUVD_CGC_GATE__SMP_MASK |
+				UVD_SUVD_CGC_GATE__SCM_MASK |
+				UVD_SUVD_CGC_GATE__SDB_MASK |
+				UVD_SUVD_CGC_GATE__SRE_H264_MASK |
+				UVD_SUVD_CGC_GATE__SRE_HEVC_MASK |
+				UVD_SUVD_CGC_GATE__SIT_H264_MASK |
+				UVD_SUVD_CGC_GATE__SIT_HEVC_MASK |
+				UVD_SUVD_CGC_GATE__SCM_H264_MASK |
+				UVD_SUVD_CGC_GATE__SCM_HEVC_MASK |
+				UVD_SUVD_CGC_GATE__SDB_H264_MASK |
+				UVD_SUVD_CGC_GATE__SDB_HEVC_MASK);
+	}
+	WREG32(mmUVD_CGC_GATE, data);
+	WREG32(mmUVD_SUVD_CGC_GATE, data1);
+}
+
+static void tonga_set_uvd_clock_gating_branches(struct amdgpu_device *adev,
+		bool enable)
+{
+	u32 data, data1;
+
+	data = RREG32(mmUVD_CGC_GATE);
+	data1 = RREG32(mmUVD_SUVD_CGC_GATE);
+	if (enable) {
+		data |= UVD_CGC_GATE__SYS_MASK |
+				UVD_CGC_GATE__UDEC_MASK |
+				UVD_CGC_GATE__MPEG2_MASK |
+				UVD_CGC_GATE__RBC_MASK |
+				UVD_CGC_GATE__LMI_MC_MASK |
+				UVD_CGC_GATE__IDCT_MASK |
+				UVD_CGC_GATE__MPRD_MASK |
+				UVD_CGC_GATE__MPC_MASK |
+				UVD_CGC_GATE__LBSI_MASK |
+				UVD_CGC_GATE__LRBBM_MASK |
+				UVD_CGC_GATE__UDEC_RE_MASK |
+				UVD_CGC_GATE__UDEC_CM_MASK |
+				UVD_CGC_GATE__UDEC_IT_MASK |
+				UVD_CGC_GATE__UDEC_DB_MASK |
+				UVD_CGC_GATE__UDEC_MP_MASK |
+				UVD_CGC_GATE__WCB_MASK |
+				UVD_CGC_GATE__VCPU_MASK |
+				UVD_CGC_GATE__SCPU_MASK;
+		data1 |= UVD_SUVD_CGC_GATE__SRE_MASK |
+				UVD_SUVD_CGC_GATE__SIT_MASK |
+				UVD_SUVD_CGC_GATE__SMP_MASK |
+				UVD_SUVD_CGC_GATE__SCM_MASK |
+				UVD_SUVD_CGC_GATE__SDB_MASK;
+	} else {
+		data &= ~(UVD_CGC_GATE__SYS_MASK |
+				UVD_CGC_GATE__UDEC_MASK |
+				UVD_CGC_GATE__MPEG2_MASK |
+				UVD_CGC_GATE__RBC_MASK |
+				UVD_CGC_GATE__LMI_MC_MASK |
+				UVD_CGC_GATE__LMI_UMC_MASK |
+				UVD_CGC_GATE__IDCT_MASK |
+				UVD_CGC_GATE__MPRD_MASK |
+				UVD_CGC_GATE__MPC_MASK |
+				UVD_CGC_GATE__LBSI_MASK |
+				UVD_CGC_GATE__LRBBM_MASK |
+				UVD_CGC_GATE__UDEC_RE_MASK |
+				UVD_CGC_GATE__UDEC_CM_MASK |
+				UVD_CGC_GATE__UDEC_IT_MASK |
+				UVD_CGC_GATE__UDEC_DB_MASK |
+				UVD_CGC_GATE__UDEC_MP_MASK |
+				UVD_CGC_GATE__WCB_MASK |
+				UVD_CGC_GATE__VCPU_MASK |
+				UVD_CGC_GATE__SCPU_MASK);
+		data1 &= ~(UVD_SUVD_CGC_GATE__SRE_MASK |
+				UVD_SUVD_CGC_GATE__SIT_MASK |
+				UVD_SUVD_CGC_GATE__SMP_MASK |
+				UVD_SUVD_CGC_GATE__SCM_MASK |
+				UVD_SUVD_CGC_GATE__SDB_MASK);
+	}
+	WREG32(mmUVD_CGC_GATE, data);
+	WREG32(mmUVD_SUVD_CGC_GATE, data1);
+}
+
+static void uvd_v6_0_set_uvd_dynamic_clock_mode(struct amdgpu_device *adev,
+		bool swmode)
+{
+	u32 data, data1 = 0, data2;
+
+	/* Always un-gate UVD REGS bit */
+	data = RREG32(mmUVD_CGC_GATE);
+	data &= ~(UVD_CGC_GATE__REGS_MASK);
+	WREG32(mmUVD_CGC_GATE, data);
+
+	data = RREG32(mmUVD_CGC_CTRL);
+	data &= ~(UVD_CGC_CTRL__CLK_OFF_DELAY_MASK |
+			UVD_CGC_CTRL__CLK_GATE_DLY_TIMER_MASK);
+	data |= UVD_CGC_CTRL__DYN_CLOCK_MODE_MASK |
+			1 << REG_FIELD_SHIFT(UVD_CGC_CTRL, CLK_GATE_DLY_TIMER) |
+			4 << REG_FIELD_SHIFT(UVD_CGC_CTRL, CLK_OFF_DELAY);
+
+	data2 = RREG32(mmUVD_SUVD_CGC_CTRL);
+	if (swmode) {
+		data &= ~(UVD_CGC_CTRL__UDEC_RE_MODE_MASK |
+				UVD_CGC_CTRL__UDEC_CM_MODE_MASK |
+				UVD_CGC_CTRL__UDEC_IT_MODE_MASK |
+				UVD_CGC_CTRL__UDEC_DB_MODE_MASK |
+				UVD_CGC_CTRL__UDEC_MP_MODE_MASK |
+				UVD_CGC_CTRL__SYS_MODE_MASK |
+				UVD_CGC_CTRL__UDEC_MODE_MASK |
+				UVD_CGC_CTRL__MPEG2_MODE_MASK |
+				UVD_CGC_CTRL__REGS_MODE_MASK |
+				UVD_CGC_CTRL__RBC_MODE_MASK |
+				UVD_CGC_CTRL__LMI_MC_MODE_MASK |
+				UVD_CGC_CTRL__LMI_UMC_MODE_MASK |
+				UVD_CGC_CTRL__IDCT_MODE_MASK |
+				UVD_CGC_CTRL__MPRD_MODE_MASK |
+				UVD_CGC_CTRL__MPC_MODE_MASK |
+				UVD_CGC_CTRL__LBSI_MODE_MASK |
+				UVD_CGC_CTRL__LRBBM_MODE_MASK |
+				UVD_CGC_CTRL__WCB_MODE_MASK |
+				UVD_CGC_CTRL__VCPU_MODE_MASK |
+				UVD_CGC_CTRL__JPEG_MODE_MASK |
+				UVD_CGC_CTRL__SCPU_MODE_MASK);
+		data1 |= UVD_CGC_CTRL2__DYN_OCLK_RAMP_EN_MASK |
+				UVD_CGC_CTRL2__DYN_RCLK_RAMP_EN_MASK;
+		data1 &= ~UVD_CGC_CTRL2__GATER_DIV_ID_MASK;
+		data1 |= 7 << REG_FIELD_SHIFT(UVD_CGC_CTRL2, GATER_DIV_ID);
+		data2 &= ~(UVD_SUVD_CGC_CTRL__SRE_MODE_MASK |
+				UVD_SUVD_CGC_CTRL__SIT_MODE_MASK |
+				UVD_SUVD_CGC_CTRL__SMP_MODE_MASK |
+				UVD_SUVD_CGC_CTRL__SCM_MODE_MASK |
+				UVD_SUVD_CGC_CTRL__SDB_MODE_MASK);
+	} else {
+		data |= UVD_CGC_CTRL__UDEC_RE_MODE_MASK |
+				UVD_CGC_CTRL__UDEC_CM_MODE_MASK |
+				UVD_CGC_CTRL__UDEC_IT_MODE_MASK |
+				UVD_CGC_CTRL__UDEC_DB_MODE_MASK |
+				UVD_CGC_CTRL__UDEC_MP_MODE_MASK |
+				UVD_CGC_CTRL__SYS_MODE_MASK |
+				UVD_CGC_CTRL__UDEC_MODE_MASK |
+				UVD_CGC_CTRL__MPEG2_MODE_MASK |
+				UVD_CGC_CTRL__REGS_MODE_MASK |
+				UVD_CGC_CTRL__RBC_MODE_MASK |
+				UVD_CGC_CTRL__LMI_MC_MODE_MASK |
+				UVD_CGC_CTRL__LMI_UMC_MODE_MASK |
+				UVD_CGC_CTRL__IDCT_MODE_MASK |
+				UVD_CGC_CTRL__MPRD_MODE_MASK |
+				UVD_CGC_CTRL__MPC_MODE_MASK |
+				UVD_CGC_CTRL__LBSI_MODE_MASK |
+				UVD_CGC_CTRL__LRBBM_MODE_MASK |
+				UVD_CGC_CTRL__WCB_MODE_MASK |
+				UVD_CGC_CTRL__VCPU_MODE_MASK |
+				UVD_CGC_CTRL__SCPU_MODE_MASK;
+		data2 |= UVD_SUVD_CGC_CTRL__SRE_MODE_MASK |
+				UVD_SUVD_CGC_CTRL__SIT_MODE_MASK |
+				UVD_SUVD_CGC_CTRL__SMP_MODE_MASK |
+				UVD_SUVD_CGC_CTRL__SCM_MODE_MASK |
+				UVD_SUVD_CGC_CTRL__SDB_MODE_MASK;
+	}
+	WREG32(mmUVD_CGC_CTRL, data);
+	WREG32(mmUVD_SUVD_CGC_CTRL, data2);
+
+	data = RREG32_UVD_CTX(ixUVD_CGC_CTRL2);
+	data &= ~(REG_FIELD_MASK(UVD_CGC_CTRL2, DYN_OCLK_RAMP_EN) |
+			REG_FIELD_MASK(UVD_CGC_CTRL2, DYN_RCLK_RAMP_EN) |
+			REG_FIELD_MASK(UVD_CGC_CTRL2, GATER_DIV_ID));
+	data1 &= (REG_FIELD_MASK(UVD_CGC_CTRL2, DYN_OCLK_RAMP_EN) |
+			REG_FIELD_MASK(UVD_CGC_CTRL2, DYN_RCLK_RAMP_EN) |
+			REG_FIELD_MASK(UVD_CGC_CTRL2, GATER_DIV_ID));
+	data |= data1;
+	WREG32_UVD_CTX(ixUVD_CGC_CTRL2, data);
+}
+
 /**
  * uvd_v6_0_start - start UVD block
  *
@@ -303,8 +531,19 @@ static int uvd_v6_0_start(struct amdgpu_
 
 	uvd_v6_0_mc_resume(adev);
 
-	/* disable clock gating */
-	WREG32(mmUVD_CGC_GATE, 0);
+	/* Set dynamic clock gating in S/W control mode */
+	if (adev->cg_flags & AMD_CG_SUPPORT_UVD_MGCG) {
+		if (adev->flags & AMD_IS_APU)
+			cz_set_uvd_clock_gating_branches(adev, false);
+		else
+			tonga_set_uvd_clock_gating_branches(adev, false);
+		uvd_v6_0_set_uvd_dynamic_clock_mode(adev, true);
+	} else {
+		/* disable clock gating */
+		uint32_t data = RREG32(mmUVD_CGC_CTRL);
+		data &= ~UVD_CGC_CTRL__DYN_CLOCK_MODE_MASK;
+		WREG32(mmUVD_CGC_CTRL, data);
+	}
 
 	/* disable interupt */
 	WREG32_P(mmUVD_MASTINT_EN, 0, ~(1 << 1));
@@ -758,6 +997,24 @@ static int uvd_v6_0_process_interrupt(st
 static int uvd_v6_0_set_clockgating_state(void *handle,
 					  enum amd_clockgating_state state)
 {
+	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
+	bool enable = (state == AMD_CG_STATE_GATE) ? true : false;
+
+	if (!(adev->cg_flags & AMD_CG_SUPPORT_UVD_MGCG))
+		return 0;
+
+	if (enable) {
+		if (adev->flags & AMD_IS_APU)
+			cz_set_uvd_clock_gating_branches(adev, enable);
+		else
+			tonga_set_uvd_clock_gating_branches(adev, enable);
+		uvd_v6_0_set_uvd_dynamic_clock_mode(adev, true);
+	} else {
+		uint32_t data = RREG32(mmUVD_CGC_CTRL);
+		data &= ~UVD_CGC_CTRL__DYN_CLOCK_MODE_MASK;
+		WREG32(mmUVD_CGC_CTRL, data);
+	}
+
 	return 0;
 }
 
@@ -773,6 +1030,9 @@ static int uvd_v6_0_set_powergating_stat
 	 */
 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
 
+	if (!(adev->pg_flags & AMD_PG_SUPPORT_UVD))
+		return 0;
+
 	if (state == AMD_PG_STATE_GATE) {
 		uvd_v6_0_stop(adev);
 		return 0;
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/amd/amdgpu/vce_v2_0.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/amdgpu/vce_v2_0.c
@@ -373,7 +373,7 @@ static void vce_v2_0_enable_mgcg(struct
 {
 	bool sw_cg = false;
 
-	if (enable && (adev->cg_flags & AMDGPU_CG_SUPPORT_VCE_MGCG)) {
+	if (enable && (adev->cg_flags & AMD_CG_SUPPORT_VCE_MGCG)) {
 		if (sw_cg)
 			vce_v2_0_set_sw_cg(adev, true);
 		else
@@ -608,6 +608,9 @@ static int vce_v2_0_set_powergating_stat
 	 */
 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
 
+	if (!(adev->pg_flags & AMD_PG_SUPPORT_VCE))
+		return 0;
+
 	if (state == AMD_PG_STATE_GATE)
 		/* XXX do we need a vce_v2_0_stop()? */
 		return 0;
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c
@@ -103,6 +103,108 @@ static void vce_v3_0_ring_set_wptr(struc
 		WREG32(mmVCE_RB_WPTR2, ring->wptr);
 }
 
+static void vce_v3_0_override_vce_clock_gating(struct amdgpu_device *adev, bool override)
+{
+	u32 tmp, data;
+
+	tmp = data = RREG32(mmVCE_RB_ARB_CTRL);
+	if (override)
+		data |= VCE_RB_ARB_CTRL__VCE_CGTT_OVERRIDE_MASK;
+	else
+		data &= ~VCE_RB_ARB_CTRL__VCE_CGTT_OVERRIDE_MASK;
+
+	if (tmp != data)
+		WREG32(mmVCE_RB_ARB_CTRL, data);
+}
+
+static void vce_v3_0_set_vce_sw_clock_gating(struct amdgpu_device *adev,
+					     bool gated)
+{
+	u32 tmp, data;
+	/* Set Override to disable Clock Gating */
+	vce_v3_0_override_vce_clock_gating(adev, true);
+
+	if (!gated) {
+		/* Force CLOCK ON for VCE_CLOCK_GATING_B,
+		 * {*_FORCE_ON, *_FORCE_OFF} = {1, 0}
+		 * VREG can be FORCE ON or set to Dynamic, but can't be OFF
+		 */
+		tmp = data = RREG32(mmVCE_CLOCK_GATING_B);
+		data |= 0x1ff;
+		data &= ~0xef0000;
+		if (tmp != data)
+			WREG32(mmVCE_CLOCK_GATING_B, data);
+
+		/* Force CLOCK ON for VCE_UENC_CLOCK_GATING,
+		 * {*_FORCE_ON, *_FORCE_OFF} = {1, 0}
+		 */
+		tmp = data = RREG32(mmVCE_UENC_CLOCK_GATING);
+		data |= 0x3ff000;
+		data &= ~0xffc00000;
+		if (tmp != data)
+			WREG32(mmVCE_UENC_CLOCK_GATING, data);
+
+		/* set VCE_UENC_CLOCK_GATING_2 */
+		tmp = data = RREG32(mmVCE_UENC_CLOCK_GATING_2);
+		data |= 0x2;
+		data &= ~0x2;
+		if (tmp != data)
+			WREG32(mmVCE_UENC_CLOCK_GATING_2, data);
+
+		/* Force CLOCK ON for VCE_UENC_REG_CLOCK_GATING */
+		tmp = data = RREG32(mmVCE_UENC_REG_CLOCK_GATING);
+		data |= 0x37f;
+		if (tmp != data)
+			WREG32(mmVCE_UENC_REG_CLOCK_GATING, data);
+
+		/* Force VCE_UENC_DMA_DCLK_CTRL Clock ON */
+		tmp = data = RREG32(mmVCE_UENC_DMA_DCLK_CTRL);
+		data |= VCE_UENC_DMA_DCLK_CTRL__WRDMCLK_FORCEON_MASK |
+				VCE_UENC_DMA_DCLK_CTRL__RDDMCLK_FORCEON_MASK |
+				VCE_UENC_DMA_DCLK_CTRL__REGCLK_FORCEON_MASK  |
+				0x8;
+		if (tmp != data)
+			WREG32(mmVCE_UENC_DMA_DCLK_CTRL, data);
+	} else {
+		/* Force CLOCK OFF for VCE_CLOCK_GATING_B,
+		 * {*, *_FORCE_OFF} = {*, 1}
+		 * set VREG to Dynamic, as it can't be OFF
+		 */
+		tmp = data = RREG32(mmVCE_CLOCK_GATING_B);
+		data &= ~0x80010;
+		data |= 0xe70008;
+		if (tmp != data)
+			WREG32(mmVCE_CLOCK_GATING_B, data);
+		/* Force CLOCK OFF for VCE_UENC_CLOCK_GATING,
+		 * Force ClOCK OFF takes precedent over Force CLOCK ON setting.
+		 * {*_FORCE_ON, *_FORCE_OFF} = {*, 1}
+		 */
+		tmp = data = RREG32(mmVCE_UENC_CLOCK_GATING);
+		data |= 0xffc00000;
+		if (tmp != data)
+			WREG32(mmVCE_UENC_CLOCK_GATING, data);
+		/* Set VCE_UENC_CLOCK_GATING_2 */
+		tmp = data = RREG32(mmVCE_UENC_CLOCK_GATING_2);
+		data |= 0x10000;
+		if (tmp != data)
+			WREG32(mmVCE_UENC_CLOCK_GATING_2, data);
+		/* Set VCE_UENC_REG_CLOCK_GATING to dynamic */
+		tmp = data = RREG32(mmVCE_UENC_REG_CLOCK_GATING);
+		data &= ~0xffc00000;
+		if (tmp != data)
+			WREG32(mmVCE_UENC_REG_CLOCK_GATING, data);
+		/* Set VCE_UENC_DMA_DCLK_CTRL CG always in dynamic mode */
+		tmp = data = RREG32(mmVCE_UENC_DMA_DCLK_CTRL);
+		data &= ~(VCE_UENC_DMA_DCLK_CTRL__WRDMCLK_FORCEON_MASK |
+				VCE_UENC_DMA_DCLK_CTRL__RDDMCLK_FORCEON_MASK |
+				VCE_UENC_DMA_DCLK_CTRL__REGCLK_FORCEON_MASK  |
+				0x8);
+		if (tmp != data)
+			WREG32(mmVCE_UENC_DMA_DCLK_CTRL, data);
+	}
+	vce_v3_0_override_vce_clock_gating(adev, false);
+}
+
 /**
  * vce_v3_0_start - start VCE block
  *
@@ -121,7 +223,7 @@ static int vce_v3_0_start(struct amdgpu_
 		if (adev->vce.harvest_config & (1 << idx))
 			continue;
 
-		if(idx == 0)
+		if (idx == 0)
 			WREG32_P(mmGRBM_GFX_INDEX, 0,
 				~GRBM_GFX_INDEX__VCE_INSTANCE_MASK);
 		else
@@ -174,6 +276,10 @@ static int vce_v3_0_start(struct amdgpu_
 		/* clear BUSY flag */
 		WREG32_P(mmVCE_STATUS, 0, ~1);
 
+		/* Set Clock-Gating off */
+		if (adev->cg_flags & AMD_CG_SUPPORT_VCE_MGCG)
+			vce_v3_0_set_vce_sw_clock_gating(adev, false);
+
 		if (r) {
 			DRM_ERROR("VCE not responding, giving up!!!\n");
 			mutex_unlock(&adev->grbm_idx_mutex);
@@ -609,6 +715,47 @@ static int vce_v3_0_process_interrupt(st
 static int vce_v3_0_set_clockgating_state(void *handle,
 					  enum amd_clockgating_state state)
 {
+	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
+	bool enable = (state == AMD_CG_STATE_GATE) ? true : false;
+	int i;
+
+	if (!(adev->cg_flags & AMD_CG_SUPPORT_VCE_MGCG))
+		return 0;
+
+	mutex_lock(&adev->grbm_idx_mutex);
+	for (i = 0; i < 2; i++) {
+		/* Program VCE Instance 0 or 1 if not harvested */
+		if (adev->vce.harvest_config & (1 << i))
+			continue;
+
+		if (i == 0)
+			WREG32_P(mmGRBM_GFX_INDEX, 0,
+					~GRBM_GFX_INDEX__VCE_INSTANCE_MASK);
+		else
+			WREG32_P(mmGRBM_GFX_INDEX,
+					GRBM_GFX_INDEX__VCE_INSTANCE_MASK,
+					~GRBM_GFX_INDEX__VCE_INSTANCE_MASK);
+
+		if (enable) {
+			/* initialize VCE_CLOCK_GATING_A: Clock ON/OFF delay */
+			uint32_t data = RREG32(mmVCE_CLOCK_GATING_A);
+			data &= ~(0xf | 0xff0);
+			data |= ((0x0 << 0) | (0x04 << 4));
+			WREG32(mmVCE_CLOCK_GATING_A, data);
+
+			/* initialize VCE_UENC_CLOCK_GATING: Clock ON/OFF delay */
+			data = RREG32(mmVCE_UENC_CLOCK_GATING);
+			data &= ~(0xf | 0xff0);
+			data |= ((0x0 << 0) | (0x04 << 4));
+			WREG32(mmVCE_UENC_CLOCK_GATING, data);
+		}
+
+		vce_v3_0_set_vce_sw_clock_gating(adev, enable);
+	}
+
+	WREG32_P(mmGRBM_GFX_INDEX, 0, ~GRBM_GFX_INDEX__VCE_INSTANCE_MASK);
+	mutex_unlock(&adev->grbm_idx_mutex);
+
 	return 0;
 }
 
@@ -624,6 +771,9 @@ static int vce_v3_0_set_powergating_stat
 	 */
 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
 
+	if (!(adev->pg_flags & AMD_PG_SUPPORT_VCE))
+		return 0;
+
 	if (state == AMD_PG_STATE_GATE)
 		/* XXX do we need a vce_v3_0_stop()? */
 		return 0;
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/amd/amdgpu/vi.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/amdgpu/vi.c
@@ -31,6 +31,7 @@
 #include "amdgpu_vce.h"
 #include "amdgpu_ucode.h"
 #include "atom.h"
+#include "amd_pcie.h"
 
 #include "gmc/gmc_8_1_d.h"
 #include "gmc/gmc_8_1_sh_mask.h"
@@ -60,6 +61,7 @@
 #include "vi.h"
 #include "vi_dpm.h"
 #include "gmc_v8_0.h"
+#include "gmc_v7_0.h"
 #include "gfx_v8_0.h"
 #include "sdma_v2_4.h"
 #include "sdma_v3_0.h"
@@ -71,6 +73,7 @@
 #include "uvd_v5_0.h"
 #include "uvd_v6_0.h"
 #include "vce_v3_0.h"
+#include "amdgpu_powerplay.h"
 
 /*
  * Indirect registers accessor
@@ -376,6 +379,38 @@ static bool vi_read_disabled_bios(struct
 	WREG32_SMC(ixROM_CNTL, rom_cntl);
 	return r;
 }
+
+static bool vi_read_bios_from_rom(struct amdgpu_device *adev,
+				  u8 *bios, u32 length_bytes)
+{
+	u32 *dw_ptr;
+	unsigned long flags;
+	u32 i, length_dw;
+
+	if (bios == NULL)
+		return false;
+	if (length_bytes == 0)
+		return false;
+	/* APU vbios image is part of sbios image */
+	if (adev->flags & AMD_IS_APU)
+		return false;
+
+	dw_ptr = (u32 *)bios;
+	length_dw = ALIGN(length_bytes, 4) / 4;
+	/* take the smc lock since we are using the smc index */
+	spin_lock_irqsave(&adev->smc_idx_lock, flags);
+	/* set rom index to 0 */
+	WREG32(mmSMC_IND_INDEX_0, ixROM_INDEX);
+	WREG32(mmSMC_IND_DATA_0, 0);
+	/* set index to data for continous read */
+	WREG32(mmSMC_IND_INDEX_0, ixROM_DATA);
+	for (i = 0; i < length_dw; i++)
+		dw_ptr[i] = RREG32(mmSMC_IND_DATA_0);
+	spin_unlock_irqrestore(&adev->smc_idx_lock, flags);
+
+	return true;
+}
+
 static struct amdgpu_allowed_register_entry tonga_allowed_read_registers[] = {
 	{mmGB_MACROTILE_MODE7, true},
 };
@@ -1019,9 +1054,6 @@ static int vi_set_vce_clocks(struct amdg
 
 static void vi_pcie_gen3_enable(struct amdgpu_device *adev)
 {
-	u32 mask;
-	int ret;
-
 	if (pci_is_root_bus(adev->pdev->bus))
 		return;
 
@@ -1031,11 +1063,8 @@ static void vi_pcie_gen3_enable(struct a
 	if (adev->flags & AMD_IS_APU)
 		return;
 
-	ret = drm_pcie_get_speed_cap_mask(adev->ddev, &mask);
-	if (ret != 0)
-		return;
-
-	if (!(mask & (DRM_PCIE_SPEED_50 | DRM_PCIE_SPEED_80)))
+	if (!(adev->pm.pcie_gen_mask & (CAIL_PCIE_LINK_SPEED_SUPPORT_GEN2 |
+					CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3)))
 		return;
 
 	/* todo */
@@ -1081,10 +1110,10 @@ static const struct amdgpu_ip_block_vers
 	},
 	{
 		.type = AMD_IP_BLOCK_TYPE_GMC,
-		.major = 8,
-		.minor = 0,
+		.major = 7,
+		.minor = 4,
 		.rev = 0,
-		.funcs = &gmc_v8_0_ip_funcs,
+		.funcs = &gmc_v7_0_ip_funcs,
 	},
 	{
 		.type = AMD_IP_BLOCK_TYPE_IH,
@@ -1098,7 +1127,7 @@ static const struct amdgpu_ip_block_vers
 		.major = 7,
 		.minor = 1,
 		.rev = 0,
-		.funcs = &iceland_dpm_ip_funcs,
+		.funcs = &amdgpu_pp_ip_funcs,
 	},
 	{
 		.type = AMD_IP_BLOCK_TYPE_GFX,
@@ -1145,7 +1174,7 @@ static const struct amdgpu_ip_block_vers
 		.major = 7,
 		.minor = 1,
 		.rev = 0,
-		.funcs = &tonga_dpm_ip_funcs,
+		.funcs = &amdgpu_pp_ip_funcs,
 	},
 	{
 		.type = AMD_IP_BLOCK_TYPE_DCE,
@@ -1213,7 +1242,7 @@ static const struct amdgpu_ip_block_vers
 		.major = 7,
 		.minor = 1,
 		.rev = 0,
-		.funcs = &fiji_dpm_ip_funcs,
+		.funcs = &amdgpu_pp_ip_funcs,
 	},
 	{
 		.type = AMD_IP_BLOCK_TYPE_DCE,
@@ -1281,7 +1310,7 @@ static const struct amdgpu_ip_block_vers
 		.major = 8,
 		.minor = 0,
 		.rev = 0,
-		.funcs = &cz_dpm_ip_funcs,
+		.funcs = &amdgpu_pp_ip_funcs
 	},
 	{
 		.type = AMD_IP_BLOCK_TYPE_DCE,
@@ -1354,20 +1383,18 @@ int vi_set_ip_blocks(struct amdgpu_devic
 
 static uint32_t vi_get_rev_id(struct amdgpu_device *adev)
 {
-	if (adev->asic_type == CHIP_TOPAZ)
-		return (RREG32(mmPCIE_EFUSE4) & PCIE_EFUSE4__STRAP_BIF_ATI_REV_ID_MASK)
-			>> PCIE_EFUSE4__STRAP_BIF_ATI_REV_ID__SHIFT;
-	else if (adev->flags & AMD_IS_APU)
+	if (adev->flags & AMD_IS_APU)
 		return (RREG32_SMC(ATI_REV_ID_FUSE_MACRO__ADDRESS) & ATI_REV_ID_FUSE_MACRO__MASK)
 			>> ATI_REV_ID_FUSE_MACRO__SHIFT;
 	else
-		return (RREG32(mmCC_DRM_ID_STRAPS) & CC_DRM_ID_STRAPS__ATI_REV_ID_MASK)
-			>> CC_DRM_ID_STRAPS__ATI_REV_ID__SHIFT;
+		return (RREG32(mmPCIE_EFUSE4) & PCIE_EFUSE4__STRAP_BIF_ATI_REV_ID_MASK)
+			>> PCIE_EFUSE4__STRAP_BIF_ATI_REV_ID__SHIFT;
 }
 
 static const struct amdgpu_asic_funcs vi_asic_funcs =
 {
 	.read_disabled_bios = &vi_read_disabled_bios,
+	.read_bios_from_rom = &vi_read_bios_from_rom,
 	.read_register = &vi_read_register,
 	.reset = &vi_asic_reset,
 	.set_vga_state = &vi_vga_set_state,
@@ -1430,8 +1457,7 @@ static int vi_common_early_init(void *ha
 	case CHIP_STONEY:
 		adev->has_uvd = true;
 		adev->cg_flags = 0;
-		/* Disable UVD pg */
-		adev->pg_flags = /* AMDGPU_PG_SUPPORT_UVD | */AMDGPU_PG_SUPPORT_VCE;
+		adev->pg_flags = 0;
 		adev->external_rev_id = adev->rev_id + 0x1;
 		break;
 	default:
@@ -1442,6 +1468,8 @@ static int vi_common_early_init(void *ha
 	if (amdgpu_smc_load_fw && smc_enabled)
 		adev->firmware.smu_load = true;
 
+	amdgpu_get_pcie_info(adev);
+
 	return 0;
 }
 
@@ -1515,9 +1543,95 @@ static int vi_common_soft_reset(void *ha
 	return 0;
 }
 
+static void fiji_update_bif_medium_grain_light_sleep(struct amdgpu_device *adev,
+		bool enable)
+{
+	uint32_t temp, data;
+
+	temp = data = RREG32_PCIE(ixPCIE_CNTL2);
+
+	if (enable)
+		data |= PCIE_CNTL2__SLV_MEM_LS_EN_MASK |
+				PCIE_CNTL2__MST_MEM_LS_EN_MASK |
+				PCIE_CNTL2__REPLAY_MEM_LS_EN_MASK;
+	else
+		data &= ~(PCIE_CNTL2__SLV_MEM_LS_EN_MASK |
+				PCIE_CNTL2__MST_MEM_LS_EN_MASK |
+				PCIE_CNTL2__REPLAY_MEM_LS_EN_MASK);
+
+	if (temp != data)
+		WREG32_PCIE(ixPCIE_CNTL2, data);
+}
+
+static void fiji_update_hdp_medium_grain_clock_gating(struct amdgpu_device *adev,
+		bool enable)
+{
+	uint32_t temp, data;
+
+	temp = data = RREG32(mmHDP_HOST_PATH_CNTL);
+
+	if (enable)
+		data &= ~HDP_HOST_PATH_CNTL__CLOCK_GATING_DIS_MASK;
+	else
+		data |= HDP_HOST_PATH_CNTL__CLOCK_GATING_DIS_MASK;
+
+	if (temp != data)
+		WREG32(mmHDP_HOST_PATH_CNTL, data);
+}
+
+static void fiji_update_hdp_light_sleep(struct amdgpu_device *adev,
+		bool enable)
+{
+	uint32_t temp, data;
+
+	temp = data = RREG32(mmHDP_MEM_POWER_LS);
+
+	if (enable)
+		data |= HDP_MEM_POWER_LS__LS_ENABLE_MASK;
+	else
+		data &= ~HDP_MEM_POWER_LS__LS_ENABLE_MASK;
+
+	if (temp != data)
+		WREG32(mmHDP_MEM_POWER_LS, data);
+}
+
+static void fiji_update_rom_medium_grain_clock_gating(struct amdgpu_device *adev,
+		bool enable)
+{
+	uint32_t temp, data;
+
+	temp = data = RREG32_SMC(ixCGTT_ROM_CLK_CTRL0);
+
+	if (enable)
+		data &= ~(CGTT_ROM_CLK_CTRL0__SOFT_OVERRIDE0_MASK |
+				CGTT_ROM_CLK_CTRL0__SOFT_OVERRIDE1_MASK);
+	else
+		data |= CGTT_ROM_CLK_CTRL0__SOFT_OVERRIDE0_MASK |
+				CGTT_ROM_CLK_CTRL0__SOFT_OVERRIDE1_MASK;
+
+	if (temp != data)
+		WREG32_SMC(ixCGTT_ROM_CLK_CTRL0, data);
+}
+
 static int vi_common_set_clockgating_state(void *handle,
 					    enum amd_clockgating_state state)
 {
+	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
+
+	switch (adev->asic_type) {
+	case CHIP_FIJI:
+		fiji_update_bif_medium_grain_light_sleep(adev,
+				state == AMD_CG_STATE_GATE ? true : false);
+		fiji_update_hdp_medium_grain_clock_gating(adev,
+				state == AMD_CG_STATE_GATE ? true : false);
+		fiji_update_hdp_light_sleep(adev,
+				state == AMD_CG_STATE_GATE ? true : false);
+		fiji_update_rom_medium_grain_clock_gating(adev,
+				state == AMD_CG_STATE_GATE ? true : false);
+		break;
+	default:
+		break;
+	}
 	return 0;
 }
 
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
@@ -558,20 +558,10 @@ static int kfd_ioctl_dbg_address_watch(s
 		return -EINVAL;
 
 	/* this is the actual buffer to work with */
-
-	args_buff = kmalloc(args->buf_size_in_bytes -
-					sizeof(*args), GFP_KERNEL);
-	if (args_buff == NULL)
-		return -ENOMEM;
-
-	status = copy_from_user(args_buff, cmd_from_user,
+	args_buff = memdup_user(cmd_from_user,
 				args->buf_size_in_bytes - sizeof(*args));
-
-	if (status != 0) {
-		pr_debug("Failed to copy address watch user data\n");
-		kfree(args_buff);
-		return -EINVAL;
-	}
+	if (IS_ERR(args_buff))
+		return PTR_ERR(args_buff);
 
 	aw_info.process = p;
 
@@ -677,22 +667,12 @@ static int kfd_ioctl_dbg_wave_control(st
 	if (cmd_from_user == NULL)
 		return -EINVAL;
 
-	/* this is the actual buffer to work with */
-
-	args_buff = kmalloc(args->buf_size_in_bytes - sizeof(*args),
-			GFP_KERNEL);
-
-	if (args_buff == NULL)
-		return -ENOMEM;
+	/* copy the entire buffer from user */
 
-	/* Now copy the entire buffer from user */
-	status = copy_from_user(args_buff, cmd_from_user,
+	args_buff = memdup_user(cmd_from_user,
 				args->buf_size_in_bytes - sizeof(*args));
-	if (status != 0) {
-		pr_debug("Failed to copy wave control user data\n");
-		kfree(args_buff);
-		return -EINVAL;
-	}
+	if (IS_ERR(args_buff))
+		return PTR_ERR(args_buff);
 
 	/* move ptr to the start of the "pay-load" area */
 	wac_info.process = p;
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/amd/amdkfd/kfd_dbgdev.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/amdkfd/kfd_dbgdev.c
@@ -513,7 +513,7 @@ static int dbgdev_wave_control_set_regis
 				union SQ_CMD_BITS *in_reg_sq_cmd,
 				union GRBM_GFX_INDEX_BITS *in_reg_gfx_index)
 {
-	int status;
+	int status = 0;
 	union SQ_CMD_BITS reg_sq_cmd;
 	union GRBM_GFX_INDEX_BITS reg_gfx_index;
 	struct HsaDbgWaveMsgAMDGen2 *pMsg;
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/amd/amdkfd/kfd_process.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/amdkfd/kfd_process.c
@@ -194,7 +194,7 @@ static void kfd_process_wq_release(struc
 
 	kfree(p);
 
-	kfree((void *)work);
+	kfree(work);
 }
 
 static void kfd_process_destroy_delayed(struct rcu_head *rcu)
@@ -242,13 +242,19 @@ static void kfd_process_notifier_release
 	pqm_uninit(&p->pqm);
 
 	/* Iterate over all process device data structure and check
-	 * if we should reset all wavefronts */
-	list_for_each_entry(pdd, &p->per_device_data, per_device_list)
+	 * if we should delete debug managers and reset all wavefronts
+	 */
+	list_for_each_entry(pdd, &p->per_device_data, per_device_list) {
+		if ((pdd->dev->dbgmgr) &&
+				(pdd->dev->dbgmgr->pasid == p->pasid))
+			kfd_dbgmgr_destroy(pdd->dev->dbgmgr);
+
 		if (pdd->reset_wavefronts) {
 			pr_warn("amdkfd: Resetting all wave fronts\n");
 			dbgdev_wave_reset_wavefronts(pdd->dev, p);
 			pdd->reset_wavefronts = false;
 		}
+	}
 
 	mutex_unlock(&p->mutex);
 
@@ -404,42 +410,52 @@ void kfd_unbind_process_from_device(stru
 
 	idx = srcu_read_lock(&kfd_processes_srcu);
 
+	/*
+	 * Look for the process that matches the pasid. If there is no such
+	 * process, we either released it in amdkfd's own notifier, or there
+	 * is a bug. Unfortunately, there is no way to tell...
+	 */
 	hash_for_each_rcu(kfd_processes_table, i, p, kfd_processes)
-		if (p->pasid == pasid)
-			break;
+		if (p->pasid == pasid) {
 
-	srcu_read_unlock(&kfd_processes_srcu, idx);
+			srcu_read_unlock(&kfd_processes_srcu, idx);
 
-	BUG_ON(p->pasid != pasid);
+			pr_debug("Unbinding process %d from IOMMU\n", pasid);
 
-	mutex_lock(&p->mutex);
+			mutex_lock(&p->mutex);
 
-	if ((dev->dbgmgr) && (dev->dbgmgr->pasid == p->pasid))
-		kfd_dbgmgr_destroy(dev->dbgmgr);
+			if ((dev->dbgmgr) && (dev->dbgmgr->pasid == p->pasid))
+				kfd_dbgmgr_destroy(dev->dbgmgr);
 
-	pqm_uninit(&p->pqm);
+			pqm_uninit(&p->pqm);
 
-	pdd = kfd_get_process_device_data(dev, p);
+			pdd = kfd_get_process_device_data(dev, p);
 
-	if (!pdd) {
-		mutex_unlock(&p->mutex);
-		return;
-	}
+			if (!pdd) {
+				mutex_unlock(&p->mutex);
+				return;
+			}
 
-	if (pdd->reset_wavefronts) {
-		dbgdev_wave_reset_wavefronts(pdd->dev, p);
-		pdd->reset_wavefronts = false;
-	}
+			if (pdd->reset_wavefronts) {
+				dbgdev_wave_reset_wavefronts(pdd->dev, p);
+				pdd->reset_wavefronts = false;
+			}
 
-	/*
-	 * Just mark pdd as unbound, because we still need it to call
-	 * amd_iommu_unbind_pasid() in when the process exits.
-	 * We don't call amd_iommu_unbind_pasid() here
-	 * because the IOMMU called us.
-	 */
-	pdd->bound = false;
+			/*
+			 * Just mark pdd as unbound, because we still need it
+			 * to call amd_iommu_unbind_pasid() in when the
+			 * process exits.
+			 * We don't call amd_iommu_unbind_pasid() here
+			 * because the IOMMU called us.
+			 */
+			pdd->bound = false;
 
-	mutex_unlock(&p->mutex);
+			mutex_unlock(&p->mutex);
+
+			return;
+		}
+
+	srcu_read_unlock(&kfd_processes_srcu, idx);
 }
 
 struct kfd_process_device *kfd_get_first_process_device_data(struct kfd_process *p)
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/include/amd_acpi.h
@@ -0,0 +1,494 @@
+/*
+ * Copyright 2012 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#ifndef AMD_ACPI_H
+#define AMD_ACPI_H
+
+#define ACPI_AC_CLASS           "ac_adapter"
+
+struct atif_verify_interface {
+	u16 size;		/* structure size in bytes (includes size field) */
+	u16 version;		/* version */
+	u32 notification_mask;	/* supported notifications mask */
+	u32 function_bits;	/* supported functions bit vector */
+} __packed;
+
+struct atif_system_params {
+	u16 size;		/* structure size in bytes (includes size field) */
+	u32 valid_mask;		/* valid flags mask */
+	u32 flags;		/* flags */
+	u8 command_code;	/* notify command code */
+} __packed;
+
+struct atif_sbios_requests {
+	u16 size;		/* structure size in bytes (includes size field) */
+	u32 pending;		/* pending sbios requests */
+	u8 panel_exp_mode;	/* panel expansion mode */
+	u8 thermal_gfx;		/* thermal state: target gfx controller */
+	u8 thermal_state;	/* thermal state: state id (0: exit state, non-0: state) */
+	u8 forced_power_gfx;	/* forced power state: target gfx controller */
+	u8 forced_power_state;	/* forced power state: state id */
+	u8 system_power_src;	/* system power source */
+	u8 backlight_level;	/* panel backlight level (0-255) */
+} __packed;
+
+#define ATIF_NOTIFY_MASK	0x3
+#define ATIF_NOTIFY_NONE	0
+#define ATIF_NOTIFY_81		1
+#define ATIF_NOTIFY_N		2
+
+struct atcs_verify_interface {
+	u16 size;		/* structure size in bytes (includes size field) */
+	u16 version;		/* version */
+	u32 function_bits;	/* supported functions bit vector */
+} __packed;
+
+#define ATCS_VALID_FLAGS_MASK	0x3
+
+struct atcs_pref_req_input {
+	u16 size;		/* structure size in bytes (includes size field) */
+	u16 client_id;		/* client id (bit 2-0: func num, 7-3: dev num, 15-8: bus num) */
+	u16 valid_flags_mask;	/* valid flags mask */
+	u16 flags;		/* flags */
+	u8 req_type;		/* request type */
+	u8 perf_req;		/* performance request */
+} __packed;
+
+struct atcs_pref_req_output {
+	u16 size;		/* structure size in bytes (includes size field) */
+	u8 ret_val;		/* return value */
+} __packed;
+
+/* AMD hw uses four ACPI control methods:
+ * 1. ATIF
+ * ARG0: (ACPI_INTEGER) function code
+ * ARG1: (ACPI_BUFFER) parameter buffer, 256 bytes
+ * OUTPUT: (ACPI_BUFFER) output buffer, 256 bytes
+ * ATIF provides an entry point for the gfx driver to interact with the sbios.
+ * The AMD ACPI notification mechanism uses Notify (VGA, 0x81) or a custom
+ * notification. Which notification is used as indicated by the ATIF Control
+ * Method GET_SYSTEM_PARAMETERS. When the driver receives Notify (VGA, 0x81) or
+ * a custom notification it invokes ATIF Control Method GET_SYSTEM_BIOS_REQUESTS
+ * to identify pending System BIOS requests and associated parameters. For
+ * example, if one of the pending requests is DISPLAY_SWITCH_REQUEST, the driver
+ * will perform display device detection and invoke ATIF Control Method
+ * SELECT_ACTIVE_DISPLAYS.
+ *
+ * 2. ATPX
+ * ARG0: (ACPI_INTEGER) function code
+ * ARG1: (ACPI_BUFFER) parameter buffer, 256 bytes
+ * OUTPUT: (ACPI_BUFFER) output buffer, 256 bytes
+ * ATPX methods are used on PowerXpress systems to handle mux switching and
+ * discrete GPU power control.
+ *
+ * 3. ATRM
+ * ARG0: (ACPI_INTEGER) offset of vbios rom data
+ * ARG1: (ACPI_BUFFER) size of the buffer to fill (up to 4K).
+ * OUTPUT: (ACPI_BUFFER) output buffer
+ * ATRM provides an interfacess to access the discrete GPU vbios image on
+ * PowerXpress systems with multiple GPUs.
+ *
+ * 4. ATCS
+ * ARG0: (ACPI_INTEGER) function code
+ * ARG1: (ACPI_BUFFER) parameter buffer, 256 bytes
+ * OUTPUT: (ACPI_BUFFER) output buffer, 256 bytes
+ * ATCS provides an interface to AMD chipset specific functionality.
+ *
+ */
+/* ATIF */
+#define ATIF_FUNCTION_VERIFY_INTERFACE                             0x0
+/* ARG0: ATIF_FUNCTION_VERIFY_INTERFACE
+ * ARG1: none
+ * OUTPUT:
+ * WORD  - structure size in bytes (includes size field)
+ * WORD  - version
+ * DWORD - supported notifications mask
+ * DWORD - supported functions bit vector
+ */
+/* Notifications mask */
+#       define ATIF_DISPLAY_SWITCH_REQUEST_SUPPORTED               (1 << 0)
+#       define ATIF_EXPANSION_MODE_CHANGE_REQUEST_SUPPORTED        (1 << 1)
+#       define ATIF_THERMAL_STATE_CHANGE_REQUEST_SUPPORTED         (1 << 2)
+#       define ATIF_FORCED_POWER_STATE_CHANGE_REQUEST_SUPPORTED    (1 << 3)
+#       define ATIF_SYSTEM_POWER_SOURCE_CHANGE_REQUEST_SUPPORTED   (1 << 4)
+#       define ATIF_DISPLAY_CONF_CHANGE_REQUEST_SUPPORTED          (1 << 5)
+#       define ATIF_PX_GFX_SWITCH_REQUEST_SUPPORTED                (1 << 6)
+#       define ATIF_PANEL_BRIGHTNESS_CHANGE_REQUEST_SUPPORTED      (1 << 7)
+#       define ATIF_DGPU_DISPLAY_EVENT_SUPPORTED                   (1 << 8)
+/* supported functions vector */
+#       define ATIF_GET_SYSTEM_PARAMETERS_SUPPORTED               (1 << 0)
+#       define ATIF_GET_SYSTEM_BIOS_REQUESTS_SUPPORTED            (1 << 1)
+#       define ATIF_SELECT_ACTIVE_DISPLAYS_SUPPORTED              (1 << 2)
+#       define ATIF_GET_LID_STATE_SUPPORTED                       (1 << 3)
+#       define ATIF_GET_TV_STANDARD_FROM_CMOS_SUPPORTED           (1 << 4)
+#       define ATIF_SET_TV_STANDARD_IN_CMOS_SUPPORTED             (1 << 5)
+#       define ATIF_GET_PANEL_EXPANSION_MODE_FROM_CMOS_SUPPORTED  (1 << 6)
+#       define ATIF_SET_PANEL_EXPANSION_MODE_IN_CMOS_SUPPORTED    (1 << 7)
+#       define ATIF_TEMPERATURE_CHANGE_NOTIFICATION_SUPPORTED     (1 << 12)
+#       define ATIF_GET_GRAPHICS_DEVICE_TYPES_SUPPORTED           (1 << 14)
+#define ATIF_FUNCTION_GET_SYSTEM_PARAMETERS                        0x1
+/* ARG0: ATIF_FUNCTION_GET_SYSTEM_PARAMETERS
+ * ARG1: none
+ * OUTPUT:
+ * WORD  - structure size in bytes (includes size field)
+ * DWORD - valid flags mask
+ * DWORD - flags
+ *
+ * OR
+ *
+ * WORD  - structure size in bytes (includes size field)
+ * DWORD - valid flags mask
+ * DWORD - flags
+ * BYTE  - notify command code
+ *
+ * flags
+ * bits 1:0:
+ * 0 - Notify(VGA, 0x81) is not used for notification
+ * 1 - Notify(VGA, 0x81) is used for notification
+ * 2 - Notify(VGA, n) is used for notification where
+ * n (0xd0-0xd9) is specified in notify command code.
+ * bit 2:
+ * 1 - lid changes not reported though int10
+ */
+#define ATIF_FUNCTION_GET_SYSTEM_BIOS_REQUESTS                     0x2
+/* ARG0: ATIF_FUNCTION_GET_SYSTEM_BIOS_REQUESTS
+ * ARG1: none
+ * OUTPUT:
+ * WORD  - structure size in bytes (includes size field)
+ * DWORD - pending sbios requests
+ * BYTE  - panel expansion mode
+ * BYTE  - thermal state: target gfx controller
+ * BYTE  - thermal state: state id (0: exit state, non-0: state)
+ * BYTE  - forced power state: target gfx controller
+ * BYTE  - forced power state: state id
+ * BYTE  - system power source
+ * BYTE  - panel backlight level (0-255)
+ */
+/* pending sbios requests */
+#       define ATIF_DISPLAY_SWITCH_REQUEST                         (1 << 0)
+#       define ATIF_EXPANSION_MODE_CHANGE_REQUEST                  (1 << 1)
+#       define ATIF_THERMAL_STATE_CHANGE_REQUEST                   (1 << 2)
+#       define ATIF_FORCED_POWER_STATE_CHANGE_REQUEST              (1 << 3)
+#       define ATIF_SYSTEM_POWER_SOURCE_CHANGE_REQUEST             (1 << 4)
+#       define ATIF_DISPLAY_CONF_CHANGE_REQUEST                    (1 << 5)
+#       define ATIF_PX_GFX_SWITCH_REQUEST                          (1 << 6)
+#       define ATIF_PANEL_BRIGHTNESS_CHANGE_REQUEST                (1 << 7)
+#       define ATIF_DGPU_DISPLAY_EVENT                             (1 << 8)
+/* panel expansion mode */
+#       define ATIF_PANEL_EXPANSION_DISABLE                        0
+#       define ATIF_PANEL_EXPANSION_FULL                           1
+#       define ATIF_PANEL_EXPANSION_ASPECT                         2
+/* target gfx controller */
+#       define ATIF_TARGET_GFX_SINGLE                              0
+#       define ATIF_TARGET_GFX_PX_IGPU                             1
+#       define ATIF_TARGET_GFX_PX_DGPU                             2
+/* system power source */
+#       define ATIF_POWER_SOURCE_AC                                1
+#       define ATIF_POWER_SOURCE_DC                                2
+#       define ATIF_POWER_SOURCE_RESTRICTED_AC_1                   3
+#       define ATIF_POWER_SOURCE_RESTRICTED_AC_2                   4
+#define ATIF_FUNCTION_SELECT_ACTIVE_DISPLAYS                       0x3
+/* ARG0: ATIF_FUNCTION_SELECT_ACTIVE_DISPLAYS
+ * ARG1:
+ * WORD  - structure size in bytes (includes size field)
+ * WORD  - selected displays
+ * WORD  - connected displays
+ * OUTPUT:
+ * WORD  - structure size in bytes (includes size field)
+ * WORD  - selected displays
+ */
+#       define ATIF_LCD1                                           (1 << 0)
+#       define ATIF_CRT1                                           (1 << 1)
+#       define ATIF_TV                                             (1 << 2)
+#       define ATIF_DFP1                                           (1 << 3)
+#       define ATIF_CRT2                                           (1 << 4)
+#       define ATIF_LCD2                                           (1 << 5)
+#       define ATIF_DFP2                                           (1 << 7)
+#       define ATIF_CV                                             (1 << 8)
+#       define ATIF_DFP3                                           (1 << 9)
+#       define ATIF_DFP4                                           (1 << 10)
+#       define ATIF_DFP5                                           (1 << 11)
+#       define ATIF_DFP6                                           (1 << 12)
+#define ATIF_FUNCTION_GET_LID_STATE                                0x4
+/* ARG0: ATIF_FUNCTION_GET_LID_STATE
+ * ARG1: none
+ * OUTPUT:
+ * WORD  - structure size in bytes (includes size field)
+ * BYTE  - lid state (0: open, 1: closed)
+ *
+ * GET_LID_STATE only works at boot and resume, for general lid
+ * status, use the kernel provided status
+ */
+#define ATIF_FUNCTION_GET_TV_STANDARD_FROM_CMOS                    0x5
+/* ARG0: ATIF_FUNCTION_GET_TV_STANDARD_FROM_CMOS
+ * ARG1: none
+ * OUTPUT:
+ * WORD  - structure size in bytes (includes size field)
+ * BYTE  - 0
+ * BYTE  - TV standard
+ */
+#       define ATIF_TV_STD_NTSC                                    0
+#       define ATIF_TV_STD_PAL                                     1
+#       define ATIF_TV_STD_PALM                                    2
+#       define ATIF_TV_STD_PAL60                                   3
+#       define ATIF_TV_STD_NTSCJ                                   4
+#       define ATIF_TV_STD_PALCN                                   5
+#       define ATIF_TV_STD_PALN                                    6
+#       define ATIF_TV_STD_SCART_RGB                               9
+#define ATIF_FUNCTION_SET_TV_STANDARD_IN_CMOS                      0x6
+/* ARG0: ATIF_FUNCTION_SET_TV_STANDARD_IN_CMOS
+ * ARG1:
+ * WORD  - structure size in bytes (includes size field)
+ * BYTE  - 0
+ * BYTE  - TV standard
+ * OUTPUT: none
+ */
+#define ATIF_FUNCTION_GET_PANEL_EXPANSION_MODE_FROM_CMOS           0x7
+/* ARG0: ATIF_FUNCTION_GET_PANEL_EXPANSION_MODE_FROM_CMOS
+ * ARG1: none
+ * OUTPUT:
+ * WORD  - structure size in bytes (includes size field)
+ * BYTE  - panel expansion mode
+ */
+#define ATIF_FUNCTION_SET_PANEL_EXPANSION_MODE_IN_CMOS             0x8
+/* ARG0: ATIF_FUNCTION_SET_PANEL_EXPANSION_MODE_IN_CMOS
+ * ARG1:
+ * WORD  - structure size in bytes (includes size field)
+ * BYTE  - panel expansion mode
+ * OUTPUT: none
+ */
+#define ATIF_FUNCTION_TEMPERATURE_CHANGE_NOTIFICATION              0xD
+/* ARG0: ATIF_FUNCTION_TEMPERATURE_CHANGE_NOTIFICATION
+ * ARG1:
+ * WORD  - structure size in bytes (includes size field)
+ * WORD  - gfx controller id
+ * BYTE  - current temperature (degress Celsius)
+ * OUTPUT: none
+ */
+#define ATIF_FUNCTION_GET_GRAPHICS_DEVICE_TYPES                    0xF
+/* ARG0: ATIF_FUNCTION_GET_GRAPHICS_DEVICE_TYPES
+ * ARG1: none
+ * OUTPUT:
+ * WORD  - number of gfx devices
+ * WORD  - device structure size in bytes (excludes device size field)
+ * DWORD - flags         \
+ * WORD  - bus number     } repeated structure
+ * WORD  - device number /
+ */
+/* flags */
+#       define ATIF_PX_REMOVABLE_GRAPHICS_DEVICE                   (1 << 0)
+#       define ATIF_XGP_PORT                                       (1 << 1)
+#       define ATIF_VGA_ENABLED_GRAPHICS_DEVICE                    (1 << 2)
+#       define ATIF_XGP_PORT_IN_DOCK                               (1 << 3)
+
+/* ATPX */
+#define ATPX_FUNCTION_VERIFY_INTERFACE                             0x0
+/* ARG0: ATPX_FUNCTION_VERIFY_INTERFACE
+ * ARG1: none
+ * OUTPUT:
+ * WORD  - structure size in bytes (includes size field)
+ * WORD  - version
+ * DWORD - supported functions bit vector
+ */
+/* supported functions vector */
+#       define ATPX_GET_PX_PARAMETERS_SUPPORTED                    (1 << 0)
+#       define ATPX_POWER_CONTROL_SUPPORTED                        (1 << 1)
+#       define ATPX_DISPLAY_MUX_CONTROL_SUPPORTED                  (1 << 2)
+#       define ATPX_I2C_MUX_CONTROL_SUPPORTED                      (1 << 3)
+#       define ATPX_GRAPHICS_DEVICE_SWITCH_START_NOTIFICATION_SUPPORTED (1 << 4)
+#       define ATPX_GRAPHICS_DEVICE_SWITCH_END_NOTIFICATION_SUPPORTED   (1 << 5)
+#       define ATPX_GET_DISPLAY_CONNECTORS_MAPPING_SUPPORTED       (1 << 7)
+#       define ATPX_GET_DISPLAY_DETECTION_PORTS_SUPPORTED          (1 << 8)
+#define ATPX_FUNCTION_GET_PX_PARAMETERS                            0x1
+/* ARG0: ATPX_FUNCTION_GET_PX_PARAMETERS
+ * ARG1: none
+ * OUTPUT:
+ * WORD  - structure size in bytes (includes size field)
+ * DWORD - valid flags mask
+ * DWORD - flags
+ */
+/* flags */
+#       define ATPX_LVDS_I2C_AVAILABLE_TO_BOTH_GPUS                (1 << 0)
+#       define ATPX_CRT1_I2C_AVAILABLE_TO_BOTH_GPUS                (1 << 1)
+#       define ATPX_DVI1_I2C_AVAILABLE_TO_BOTH_GPUS                (1 << 2)
+#       define ATPX_CRT1_RGB_SIGNAL_MUXED                          (1 << 3)
+#       define ATPX_TV_SIGNAL_MUXED                                (1 << 4)
+#       define ATPX_DFP_SIGNAL_MUXED                               (1 << 5)
+#       define ATPX_SEPARATE_MUX_FOR_I2C                           (1 << 6)
+#       define ATPX_DYNAMIC_PX_SUPPORTED                           (1 << 7)
+#       define ATPX_ACF_NOT_SUPPORTED                              (1 << 8)
+#       define ATPX_FIXED_NOT_SUPPORTED                            (1 << 9)
+#       define ATPX_DYNAMIC_DGPU_POWER_OFF_SUPPORTED               (1 << 10)
+#       define ATPX_DGPU_REQ_POWER_FOR_DISPLAYS                    (1 << 11)
+#define ATPX_FUNCTION_POWER_CONTROL                                0x2
+/* ARG0: ATPX_FUNCTION_POWER_CONTROL
+ * ARG1:
+ * WORD  - structure size in bytes (includes size field)
+ * BYTE  - dGPU power state (0: power off, 1: power on)
+ * OUTPUT: none
+ */
+#define ATPX_FUNCTION_DISPLAY_MUX_CONTROL                          0x3
+/* ARG0: ATPX_FUNCTION_DISPLAY_MUX_CONTROL
+ * ARG1:
+ * WORD  - structure size in bytes (includes size field)
+ * WORD  - display mux control (0: iGPU, 1: dGPU)
+ * OUTPUT: none
+ */
+#       define ATPX_INTEGRATED_GPU                                 0
+#       define ATPX_DISCRETE_GPU                                   1
+#define ATPX_FUNCTION_I2C_MUX_CONTROL                              0x4
+/* ARG0: ATPX_FUNCTION_I2C_MUX_CONTROL
+ * ARG1:
+ * WORD  - structure size in bytes (includes size field)
+ * WORD  - i2c/aux/hpd mux control (0: iGPU, 1: dGPU)
+ * OUTPUT: none
+ */
+#define ATPX_FUNCTION_GRAPHICS_DEVICE_SWITCH_START_NOTIFICATION    0x5
+/* ARG0: ATPX_FUNCTION_GRAPHICS_DEVICE_SWITCH_START_NOTIFICATION
+ * ARG1:
+ * WORD  - structure size in bytes (includes size field)
+ * WORD  - target gpu (0: iGPU, 1: dGPU)
+ * OUTPUT: none
+ */
+#define ATPX_FUNCTION_GRAPHICS_DEVICE_SWITCH_END_NOTIFICATION      0x6
+/* ARG0: ATPX_FUNCTION_GRAPHICS_DEVICE_SWITCH_END_NOTIFICATION
+ * ARG1:
+ * WORD  - structure size in bytes (includes size field)
+ * WORD  - target gpu (0: iGPU, 1: dGPU)
+ * OUTPUT: none
+ */
+#define ATPX_FUNCTION_GET_DISPLAY_CONNECTORS_MAPPING               0x8
+/* ARG0: ATPX_FUNCTION_GET_DISPLAY_CONNECTORS_MAPPING
+ * ARG1: none
+ * OUTPUT:
+ * WORD  - number of display connectors
+ * WORD  - connector structure size in bytes (excludes connector size field)
+ * BYTE  - flags                                                     \
+ * BYTE  - ATIF display vector bit position                           } repeated
+ * BYTE  - adapter id (0: iGPU, 1-n: dGPU ordered by pcie bus number) } structure
+ * WORD  - connector ACPI id                                         /
+ */
+/* flags */
+#       define ATPX_DISPLAY_OUTPUT_SUPPORTED_BY_ADAPTER_ID_DEVICE  (1 << 0)
+#       define ATPX_DISPLAY_HPD_SUPPORTED_BY_ADAPTER_ID_DEVICE     (1 << 1)
+#       define ATPX_DISPLAY_I2C_SUPPORTED_BY_ADAPTER_ID_DEVICE     (1 << 2)
+#define ATPX_FUNCTION_GET_DISPLAY_DETECTION_PORTS                  0x9
+/* ARG0: ATPX_FUNCTION_GET_DISPLAY_DETECTION_PORTS
+ * ARG1: none
+ * OUTPUT:
+ * WORD  - number of HPD/DDC ports
+ * WORD  - port structure size in bytes (excludes port size field)
+ * BYTE  - ATIF display vector bit position \
+ * BYTE  - hpd id                            } reapeated structure
+ * BYTE  - ddc id                           /
+ *
+ * available on A+A systems only
+ */
+/* hpd id */
+#       define ATPX_HPD_NONE                                       0
+#       define ATPX_HPD1                                           1
+#       define ATPX_HPD2                                           2
+#       define ATPX_HPD3                                           3
+#       define ATPX_HPD4                                           4
+#       define ATPX_HPD5                                           5
+#       define ATPX_HPD6                                           6
+/* ddc id */
+#       define ATPX_DDC_NONE                                       0
+#       define ATPX_DDC1                                           1
+#       define ATPX_DDC2                                           2
+#       define ATPX_DDC3                                           3
+#       define ATPX_DDC4                                           4
+#       define ATPX_DDC5                                           5
+#       define ATPX_DDC6                                           6
+#       define ATPX_DDC7                                           7
+#       define ATPX_DDC8                                           8
+
+/* ATCS */
+#define ATCS_FUNCTION_VERIFY_INTERFACE                             0x0
+/* ARG0: ATCS_FUNCTION_VERIFY_INTERFACE
+ * ARG1: none
+ * OUTPUT:
+ * WORD  - structure size in bytes (includes size field)
+ * WORD  - version
+ * DWORD - supported functions bit vector
+ */
+/* supported functions vector */
+#       define ATCS_GET_EXTERNAL_STATE_SUPPORTED                   (1 << 0)
+#       define ATCS_PCIE_PERFORMANCE_REQUEST_SUPPORTED             (1 << 1)
+#       define ATCS_PCIE_DEVICE_READY_NOTIFICATION_SUPPORTED       (1 << 2)
+#       define ATCS_SET_PCIE_BUS_WIDTH_SUPPORTED                   (1 << 3)
+#define ATCS_FUNCTION_GET_EXTERNAL_STATE                           0x1
+/* ARG0: ATCS_FUNCTION_GET_EXTERNAL_STATE
+ * ARG1: none
+ * OUTPUT:
+ * WORD  - structure size in bytes (includes size field)
+ * DWORD - valid flags mask
+ * DWORD - flags (0: undocked, 1: docked)
+ */
+/* flags */
+#       define ATCS_DOCKED                                         (1 << 0)
+#define ATCS_FUNCTION_PCIE_PERFORMANCE_REQUEST                     0x2
+/* ARG0: ATCS_FUNCTION_PCIE_PERFORMANCE_REQUEST
+ * ARG1:
+ * WORD  - structure size in bytes (includes size field)
+ * WORD  - client id (bit 2-0: func num, 7-3: dev num, 15-8: bus num)
+ * WORD  - valid flags mask
+ * WORD  - flags
+ * BYTE  - request type
+ * BYTE  - performance request
+ * OUTPUT:
+ * WORD  - structure size in bytes (includes size field)
+ * BYTE  - return value
+ */
+/* flags */
+#       define ATCS_ADVERTISE_CAPS                                 (1 << 0)
+#       define ATCS_WAIT_FOR_COMPLETION                            (1 << 1)
+/* request type */
+#       define ATCS_PCIE_LINK_SPEED                                1
+/* performance request */
+#       define ATCS_REMOVE                                         0
+#       define ATCS_FORCE_LOW_POWER                                1
+#       define ATCS_PERF_LEVEL_1                                   2 /* PCIE Gen 1 */
+#       define ATCS_PERF_LEVEL_2                                   3 /* PCIE Gen 2 */
+#       define ATCS_PERF_LEVEL_3                                   4 /* PCIE Gen 3 */
+/* return value */
+#       define ATCS_REQUEST_REFUSED                                1
+#       define ATCS_REQUEST_COMPLETE                               2
+#       define ATCS_REQUEST_IN_PROGRESS                            3
+#define ATCS_FUNCTION_PCIE_DEVICE_READY_NOTIFICATION               0x3
+/* ARG0: ATCS_FUNCTION_PCIE_DEVICE_READY_NOTIFICATION
+ * ARG1: none
+ * OUTPUT: none
+ */
+#define ATCS_FUNCTION_SET_PCIE_BUS_WIDTH                           0x4
+/* ARG0: ATCS_FUNCTION_SET_PCIE_BUS_WIDTH
+ * ARG1:
+ * WORD  - structure size in bytes (includes size field)
+ * WORD  - client id (bit 2-0: func num, 7-3: dev num, 15-8: bus num)
+ * BYTE  - number of active lanes
+ * OUTPUT:
+ * WORD  - structure size in bytes (includes size field)
+ * BYTE  - number of active lanes
+ */
+
+#endif
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/include/amd_pcie.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2015 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef __AMD_PCIE_H__
+#define __AMD_PCIE_H__
+
+/* Following flags shows PCIe link speed supported in driver which are decided by chipset and ASIC */
+#define CAIL_PCIE_LINK_SPEED_SUPPORT_GEN1        0x00010000
+#define CAIL_PCIE_LINK_SPEED_SUPPORT_GEN2        0x00020000
+#define CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3        0x00040000
+#define CAIL_PCIE_LINK_SPEED_SUPPORT_MASK        0xFFFF0000
+#define CAIL_PCIE_LINK_SPEED_SUPPORT_SHIFT       16
+
+/* Following flags shows PCIe link speed supported by ASIC H/W.*/
+#define CAIL_ASIC_PCIE_LINK_SPEED_SUPPORT_GEN1   0x00000001
+#define CAIL_ASIC_PCIE_LINK_SPEED_SUPPORT_GEN2   0x00000002
+#define CAIL_ASIC_PCIE_LINK_SPEED_SUPPORT_GEN3   0x00000004
+#define CAIL_ASIC_PCIE_LINK_SPEED_SUPPORT_MASK   0x0000FFFF
+#define CAIL_ASIC_PCIE_LINK_SPEED_SUPPORT_SHIFT  0
+
+/* Following flags shows PCIe lane width switch supported in driver which are decided by chipset and ASIC */
+#define CAIL_PCIE_LINK_WIDTH_SUPPORT_X1          0x00010000
+#define CAIL_PCIE_LINK_WIDTH_SUPPORT_X2          0x00020000
+#define CAIL_PCIE_LINK_WIDTH_SUPPORT_X4          0x00040000
+#define CAIL_PCIE_LINK_WIDTH_SUPPORT_X8          0x00080000
+#define CAIL_PCIE_LINK_WIDTH_SUPPORT_X12         0x00100000
+#define CAIL_PCIE_LINK_WIDTH_SUPPORT_X16         0x00200000
+#define CAIL_PCIE_LINK_WIDTH_SUPPORT_X32         0x00400000
+#define CAIL_PCIE_LINK_WIDTH_SUPPORT_SHIFT       16
+
+#endif
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/include/amd_pcie_helpers.h
@@ -0,0 +1,141 @@
+/*
+ * Copyright 2015 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef __AMD_PCIE_HELPERS_H__
+#define __AMD_PCIE_HELPERS_H__
+
+#include "amd_pcie.h"
+
+static inline bool is_pcie_gen3_supported(uint32_t pcie_link_speed_cap)
+{
+	if (pcie_link_speed_cap & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3)
+		return true;
+
+	return false;
+}
+
+static inline bool is_pcie_gen2_supported(uint32_t pcie_link_speed_cap)
+{
+	if (pcie_link_speed_cap & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN2)
+		return true;
+
+	return false;
+}
+
+/* Get the new PCIE speed given the ASIC PCIE Cap and the NewState's requested PCIE speed*/
+static inline uint16_t get_pcie_gen_support(uint32_t pcie_link_speed_cap,
+					    uint16_t ns_pcie_gen)
+{
+	uint32_t asic_pcie_link_speed_cap = (pcie_link_speed_cap &
+		CAIL_ASIC_PCIE_LINK_SPEED_SUPPORT_MASK);
+	uint32_t sys_pcie_link_speed_cap  = (pcie_link_speed_cap &
+		CAIL_PCIE_LINK_SPEED_SUPPORT_MASK);
+
+	switch (asic_pcie_link_speed_cap) {
+	case CAIL_ASIC_PCIE_LINK_SPEED_SUPPORT_GEN1:
+		return PP_PCIEGen1;
+
+	case CAIL_ASIC_PCIE_LINK_SPEED_SUPPORT_GEN2:
+		return PP_PCIEGen2;
+
+	case CAIL_ASIC_PCIE_LINK_SPEED_SUPPORT_GEN3:
+		return PP_PCIEGen3;
+
+	default:
+		if (is_pcie_gen3_supported(sys_pcie_link_speed_cap) &&
+			(ns_pcie_gen == PP_PCIEGen3)) {
+			return PP_PCIEGen3;
+		} else if (is_pcie_gen2_supported(sys_pcie_link_speed_cap) &&
+			((ns_pcie_gen == PP_PCIEGen3) || (ns_pcie_gen == PP_PCIEGen2))) {
+			return PP_PCIEGen2;
+		}
+	}
+
+	return PP_PCIEGen1;
+}
+
+static inline uint16_t get_pcie_lane_support(uint32_t pcie_lane_width_cap,
+					     uint16_t ns_pcie_lanes)
+{
+	int i, j;
+	uint16_t new_pcie_lanes = ns_pcie_lanes;
+	uint16_t pcie_lanes[7] = {1, 2, 4, 8, 12, 16, 32};
+
+	switch (pcie_lane_width_cap) {
+	case 0:
+		printk(KERN_ERR "No valid PCIE lane width reported");
+		break;
+	case CAIL_PCIE_LINK_WIDTH_SUPPORT_X1:
+		new_pcie_lanes = 1;
+		break;
+	case CAIL_PCIE_LINK_WIDTH_SUPPORT_X2:
+		new_pcie_lanes = 2;
+		break;
+	case CAIL_PCIE_LINK_WIDTH_SUPPORT_X4:
+		new_pcie_lanes = 4;
+		break;
+	case CAIL_PCIE_LINK_WIDTH_SUPPORT_X8:
+		new_pcie_lanes = 8;
+		break;
+	case CAIL_PCIE_LINK_WIDTH_SUPPORT_X12:
+		new_pcie_lanes = 12;
+		break;
+	case CAIL_PCIE_LINK_WIDTH_SUPPORT_X16:
+		new_pcie_lanes = 16;
+		break;
+	case CAIL_PCIE_LINK_WIDTH_SUPPORT_X32:
+		new_pcie_lanes = 32;
+		break;
+	default:
+		for (i = 0; i < 7; i++) {
+			if (ns_pcie_lanes == pcie_lanes[i]) {
+				if (pcie_lane_width_cap & (0x10000 << i)) {
+					break;
+				} else {
+					for (j = i - 1; j >= 0; j--) {
+						if (pcie_lane_width_cap & (0x10000 << j)) {
+							new_pcie_lanes = pcie_lanes[j];
+							break;
+						}
+					}
+
+					if (j < 0) {
+						for (j = i + 1; j < 7; j++) {
+							if (pcie_lane_width_cap & (0x10000 << j)) {
+								new_pcie_lanes = pcie_lanes[j];
+								break;
+							}
+						}
+						if (j > 7)
+							printk(KERN_ERR "Cannot find a valid PCIE lane width!");
+					}
+				}
+				break;
+			}
+		}
+		break;
+	}
+
+	return new_pcie_lanes;
+}
+
+#endif
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/amd/include/amd_shared.h
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/include/amd_shared.h
@@ -85,6 +85,59 @@ enum amd_powergating_state {
 	AMD_PG_STATE_UNGATE,
 };
 
+/* CG flags */
+#define AMD_CG_SUPPORT_GFX_MGCG			(1 << 0)
+#define AMD_CG_SUPPORT_GFX_MGLS			(1 << 1)
+#define AMD_CG_SUPPORT_GFX_CGCG			(1 << 2)
+#define AMD_CG_SUPPORT_GFX_CGLS			(1 << 3)
+#define AMD_CG_SUPPORT_GFX_CGTS			(1 << 4)
+#define AMD_CG_SUPPORT_GFX_CGTS_LS		(1 << 5)
+#define AMD_CG_SUPPORT_GFX_CP_LS		(1 << 6)
+#define AMD_CG_SUPPORT_GFX_RLC_LS		(1 << 7)
+#define AMD_CG_SUPPORT_MC_LS			(1 << 8)
+#define AMD_CG_SUPPORT_MC_MGCG			(1 << 9)
+#define AMD_CG_SUPPORT_SDMA_LS			(1 << 10)
+#define AMD_CG_SUPPORT_SDMA_MGCG		(1 << 11)
+#define AMD_CG_SUPPORT_BIF_LS			(1 << 12)
+#define AMD_CG_SUPPORT_UVD_MGCG			(1 << 13)
+#define AMD_CG_SUPPORT_VCE_MGCG			(1 << 14)
+#define AMD_CG_SUPPORT_HDP_LS			(1 << 15)
+#define AMD_CG_SUPPORT_HDP_MGCG			(1 << 16)
+
+/* PG flags */
+#define AMD_PG_SUPPORT_GFX_PG			(1 << 0)
+#define AMD_PG_SUPPORT_GFX_SMG			(1 << 1)
+#define AMD_PG_SUPPORT_GFX_DMG			(1 << 2)
+#define AMD_PG_SUPPORT_UVD			(1 << 3)
+#define AMD_PG_SUPPORT_VCE			(1 << 4)
+#define AMD_PG_SUPPORT_CP			(1 << 5)
+#define AMD_PG_SUPPORT_GDS			(1 << 6)
+#define AMD_PG_SUPPORT_RLC_SMU_HS		(1 << 7)
+#define AMD_PG_SUPPORT_SDMA			(1 << 8)
+#define AMD_PG_SUPPORT_ACP			(1 << 9)
+#define AMD_PG_SUPPORT_SAMU			(1 << 10)
+
+enum amd_pm_state_type {
+	/* not used for dpm */
+	POWER_STATE_TYPE_DEFAULT,
+	POWER_STATE_TYPE_POWERSAVE,
+	/* user selectable states */
+	POWER_STATE_TYPE_BATTERY,
+	POWER_STATE_TYPE_BALANCED,
+	POWER_STATE_TYPE_PERFORMANCE,
+	/* internal states */
+	POWER_STATE_TYPE_INTERNAL_UVD,
+	POWER_STATE_TYPE_INTERNAL_UVD_SD,
+	POWER_STATE_TYPE_INTERNAL_UVD_HD,
+	POWER_STATE_TYPE_INTERNAL_UVD_HD2,
+	POWER_STATE_TYPE_INTERNAL_UVD_MVC,
+	POWER_STATE_TYPE_INTERNAL_BOOT,
+	POWER_STATE_TYPE_INTERNAL_THERMAL,
+	POWER_STATE_TYPE_INTERNAL_ACPI,
+	POWER_STATE_TYPE_INTERNAL_ULV,
+	POWER_STATE_TYPE_INTERNAL_3DPERF,
+};
+
 struct amd_ip_funcs {
 	/* sets up early driver state (pre sw_init), does not configure hw - Optional */
 	int (*early_init)(void *handle);
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/amd/include/asic_reg/bif/bif_5_0_d.h
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/include/asic_reg/bif/bif_5_0_d.h
@@ -596,6 +596,7 @@
 #define mmSWRST_EP_CONTROL_0                                                    0x14ac
 #define mmCPM_CONTROL                                                           0x14b8
 #define mmGSKT_CONTROL                                                          0x14bf
+#define ixSWRST_COMMAND_1                                                       0x1400103
 #define ixLM_CONTROL                                                            0x1400120
 #define ixLM_PCIETXMUX0                                                         0x1400121
 #define ixLM_PCIETXMUX1                                                         0x1400122
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/amd/include/asic_reg/gca/gfx_8_0_d.h
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/include/asic_reg/gca/gfx_8_0_d.h
@@ -2807,5 +2807,18 @@
 #define ixDIDT_DBR_WEIGHT0_3                                                    0x90
 #define ixDIDT_DBR_WEIGHT4_7                                                    0x91
 #define ixDIDT_DBR_WEIGHT8_11                                                   0x92
+#define mmTD_EDC_CNT                                                            0x252e
+#define mmCPF_EDC_TAG_CNT                                                       0x3188
+#define mmCPF_EDC_ROQ_CNT                                                       0x3189
+#define mmCPF_EDC_ATC_CNT                                                       0x318a
+#define mmCPG_EDC_TAG_CNT                                                       0x318b
+#define mmCPG_EDC_ATC_CNT                                                       0x318c
+#define mmCPG_EDC_DMA_CNT                                                       0x318d
+#define mmCPC_EDC_SCRATCH_CNT                                                   0x318e
+#define mmCPC_EDC_UCODE_CNT                                                     0x318f
+#define mmCPC_EDC_ATC_CNT                                                       0x3190
+#define mmDC_EDC_STATE_CNT                                                      0x3191
+#define mmDC_EDC_CSINVOC_CNT                                                    0x3192
+#define mmDC_EDC_RESTORE_CNT                                                    0x3193
 
 #endif /* GFX_8_0_D_H */
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/amd/include/atombios.h
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/include/atombios.h
@@ -550,6 +550,13 @@ typedef struct _COMPUTE_MEMORY_CLOCK_PAR
 //MPLL_CNTL_FLAG_BYPASS_AD_PLL has a wrong name, should be BYPASS_DQ_PLL
 #define MPLL_CNTL_FLAG_BYPASS_AD_PLL            0x04
 
+// use for ComputeMemoryClockParamTable
+typedef struct _COMPUTE_MEMORY_CLOCK_PARAM_PARAMETERS_V2_2
+{
+  COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_V4 ulClock;
+  ULONG ulReserved;
+}COMPUTE_MEMORY_CLOCK_PARAM_PARAMETERS_V2_2;
+
 typedef struct _DYNAMICE_MEMORY_SETTINGS_PARAMETER
 {
   ATOM_COMPUTE_CLOCK_FREQ ulClock;
@@ -4988,6 +4995,78 @@ typedef struct  _ATOM_ASIC_PROFILING_INF
   ULONG  ulSDCMargine;
 }ATOM_ASIC_PROFILING_INFO_V3_3;
 
+// for Fiji speed EVV algorithm
+typedef struct  _ATOM_ASIC_PROFILING_INFO_V3_4
+{
+  ATOM_COMMON_TABLE_HEADER         asHeader;
+  ULONG  ulEvvLkgFactor;
+  ULONG  ulBoardCoreTemp;
+  ULONG  ulMaxVddc;
+  ULONG  ulMinVddc;
+  ULONG  ulLoadLineSlop;
+  ULONG  ulLeakageTemp;
+  ULONG  ulLeakageVoltage;
+  EFUSE_LINEAR_FUNC_PARAM sCACm;
+  EFUSE_LINEAR_FUNC_PARAM sCACb;
+  EFUSE_LOGISTIC_FUNC_PARAM sKt_b;
+  EFUSE_LOGISTIC_FUNC_PARAM sKv_m;
+  EFUSE_LOGISTIC_FUNC_PARAM sKv_b;
+  USHORT usLkgEuseIndex;
+  UCHAR  ucLkgEfuseBitLSB;
+  UCHAR  ucLkgEfuseLength;
+  ULONG  ulLkgEncodeLn_MaxDivMin;
+  ULONG  ulLkgEncodeMax;
+  ULONG  ulLkgEncodeMin;
+  ULONG  ulEfuseLogisticAlpha;
+  USHORT usPowerDpm0;
+  USHORT usPowerDpm1;
+  USHORT usPowerDpm2;
+  USHORT usPowerDpm3;
+  USHORT usPowerDpm4;
+  USHORT usPowerDpm5;
+  USHORT usPowerDpm6;
+  USHORT usPowerDpm7;
+  ULONG  ulTdpDerateDPM0;
+  ULONG  ulTdpDerateDPM1;
+  ULONG  ulTdpDerateDPM2;
+  ULONG  ulTdpDerateDPM3;
+  ULONG  ulTdpDerateDPM4;
+  ULONG  ulTdpDerateDPM5;
+  ULONG  ulTdpDerateDPM6;
+  ULONG  ulTdpDerateDPM7;
+  EFUSE_LINEAR_FUNC_PARAM sRoFuse;
+  ULONG  ulEvvDefaultVddc;
+  ULONG  ulEvvNoCalcVddc;
+  USHORT usParamNegFlag;
+  USHORT usSpeed_Model;
+  ULONG  ulSM_A0;
+  ULONG  ulSM_A1;
+  ULONG  ulSM_A2;
+  ULONG  ulSM_A3;
+  ULONG  ulSM_A4;
+  ULONG  ulSM_A5;
+  ULONG  ulSM_A6;
+  ULONG  ulSM_A7;
+  UCHAR  ucSM_A0_sign;
+  UCHAR  ucSM_A1_sign;
+  UCHAR  ucSM_A2_sign;
+  UCHAR  ucSM_A3_sign;
+  UCHAR  ucSM_A4_sign;
+  UCHAR  ucSM_A5_sign;
+  UCHAR  ucSM_A6_sign;
+  UCHAR  ucSM_A7_sign;
+  ULONG ulMargin_RO_a;
+  ULONG ulMargin_RO_b;
+  ULONG ulMargin_RO_c;
+  ULONG ulMargin_fixed;
+  ULONG ulMargin_Fmax_mean;
+  ULONG ulMargin_plat_mean;
+  ULONG ulMargin_Fmax_sigma;
+  ULONG ulMargin_plat_sigma;
+  ULONG ulMargin_DC_sigma;
+  ULONG ulReserved[8];            // Reserved for future ASIC
+}ATOM_ASIC_PROFILING_INFO_V3_4;
+
 typedef struct _ATOM_POWER_SOURCE_OBJECT
 {
    UCHAR  ucPwrSrcId;                                   // Power source
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/amd/include/cgs_common.h
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/include/cgs_common.h
@@ -105,6 +105,36 @@ enum cgs_ucode_id {
 	CGS_UCODE_ID_MAXIMUM,
 };
 
+enum cgs_system_info_id {
+	CGS_SYSTEM_INFO_ADAPTER_BDF_ID = 1,
+	CGS_SYSTEM_INFO_PCIE_GEN_INFO,
+	CGS_SYSTEM_INFO_PCIE_MLW,
+	CGS_SYSTEM_INFO_CG_FLAGS,
+	CGS_SYSTEM_INFO_PG_FLAGS,
+	CGS_SYSTEM_INFO_ID_MAXIMUM,
+};
+
+struct cgs_system_info {
+	uint64_t       size;
+	uint64_t       info_id;
+	union {
+		void           *ptr;
+		uint64_t        value;
+	};
+	uint64_t               padding[13];
+};
+
+/*
+ * enum cgs_resource_type - GPU resource type
+ */
+enum cgs_resource_type {
+	CGS_RESOURCE_TYPE_MMIO = 0,
+	CGS_RESOURCE_TYPE_FB,
+	CGS_RESOURCE_TYPE_IO,
+	CGS_RESOURCE_TYPE_DOORBELL,
+	CGS_RESOURCE_TYPE_ROM,
+};
+
 /**
  * struct cgs_clock_limits - Clock limits
  *
@@ -127,8 +157,53 @@ struct cgs_firmware_info {
 	void			*kptr;
 };
 
+struct cgs_mode_info {
+	uint32_t		refresh_rate;
+	uint32_t		ref_clock;
+	uint32_t		vblank_time_us;
+};
+
+struct cgs_display_info {
+	uint32_t		display_count;
+	uint32_t		active_display_mask;
+	struct cgs_mode_info *mode_info;
+};
+
 typedef unsigned long cgs_handle_t;
 
+#define CGS_ACPI_METHOD_ATCS          0x53435441
+#define CGS_ACPI_METHOD_ATIF          0x46495441
+#define CGS_ACPI_METHOD_ATPX          0x58505441
+#define CGS_ACPI_FIELD_METHOD_NAME                      0x00000001
+#define CGS_ACPI_FIELD_INPUT_ARGUMENT_COUNT             0x00000002
+#define CGS_ACPI_MAX_BUFFER_SIZE     256
+#define CGS_ACPI_TYPE_ANY                      0x00
+#define CGS_ACPI_TYPE_INTEGER               0x01
+#define CGS_ACPI_TYPE_STRING                0x02
+#define CGS_ACPI_TYPE_BUFFER                0x03
+#define CGS_ACPI_TYPE_PACKAGE               0x04
+
+struct cgs_acpi_method_argument {
+	uint32_t type;
+	uint32_t method_length;
+	uint32_t data_length;
+	union{
+		uint32_t value;
+		void *pointer;
+	};
+};
+
+struct cgs_acpi_method_info {
+	uint32_t size;
+	uint32_t field;
+	uint32_t input_count;
+	uint32_t name;
+	struct cgs_acpi_method_argument *pinput_argument;
+	uint32_t output_count;
+	struct cgs_acpi_method_argument *poutput_argument;
+	uint32_t padding[9];
+};
+
 /**
  * cgs_gpu_mem_info() - Return information about memory heaps
  * @cgs_device: opaque device handle
@@ -355,6 +430,23 @@ typedef void (*cgs_write_pci_config_word
 typedef void (*cgs_write_pci_config_dword_t)(void *cgs_device, unsigned addr,
 					     uint32_t value);
 
+
+/**
+ * cgs_get_pci_resource() - provide access to a device resource (PCI BAR)
+ * @cgs_device:	opaque device handle
+ * @resource_type:	Type of Resource (MMIO, IO, ROM, FB, DOORBELL)
+ * @size:	size of the region
+ * @offset:	offset from the start of the region
+ * @resource_base:	base address (not including offset) returned
+ *
+ * Return: 0 on success, -errno otherwise
+ */
+typedef int (*cgs_get_pci_resource_t)(void *cgs_device,
+				      enum cgs_resource_type resource_type,
+				      uint64_t size,
+				      uint64_t offset,
+				      uint64_t *resource_base);
+
 /**
  * cgs_atom_get_data_table() - Get a pointer to an ATOM BIOS data table
  * @cgs_device:	opaque device handle
@@ -493,6 +585,21 @@ typedef int(*cgs_set_clockgating_state)(
 				  enum amd_ip_block_type block_type,
 				  enum amd_clockgating_state state);
 
+typedef int(*cgs_get_active_displays_info)(
+					void *cgs_device,
+					struct cgs_display_info *info);
+
+typedef int (*cgs_call_acpi_method)(void *cgs_device,
+					uint32_t acpi_method,
+					uint32_t acpi_function,
+					void *pinput, void *poutput,
+					uint32_t output_count,
+					uint32_t input_size,
+					uint32_t output_size);
+
+typedef int (*cgs_query_system_info)(void *cgs_device,
+				struct cgs_system_info *sys_info);
+
 struct cgs_ops {
 	/* memory management calls (similar to KFD interface) */
 	cgs_gpu_mem_info_t gpu_mem_info;
@@ -516,6 +623,8 @@ struct cgs_ops {
 	cgs_write_pci_config_byte_t write_pci_config_byte;
 	cgs_write_pci_config_word_t write_pci_config_word;
 	cgs_write_pci_config_dword_t write_pci_config_dword;
+	/* PCI resources */
+	cgs_get_pci_resource_t get_pci_resource;
 	/* ATOM BIOS */
 	cgs_atom_get_data_table_t atom_get_data_table;
 	cgs_atom_get_cmd_table_revs_t atom_get_cmd_table_revs;
@@ -533,7 +642,12 @@ struct cgs_ops {
 	/* cg pg interface*/
 	cgs_set_powergating_state set_powergating_state;
 	cgs_set_clockgating_state set_clockgating_state;
-	/* ACPI (TODO) */
+	/* display manager */
+	cgs_get_active_displays_info get_active_displays_info;
+	/* ACPI */
+	cgs_call_acpi_method call_acpi_method;
+	/* get system info */
+	cgs_query_system_info query_system_info;
 };
 
 struct cgs_os_ops; /* To be define in OS-specific CGS header */
@@ -620,5 +734,15 @@ struct cgs_device
 	CGS_CALL(set_powergating_state, dev, block_type, state)
 #define cgs_set_clockgating_state(dev, block_type, state)	\
 	CGS_CALL(set_clockgating_state, dev, block_type, state)
+#define cgs_get_active_displays_info(dev, info)	\
+	CGS_CALL(get_active_displays_info, dev, info)
+#define cgs_call_acpi_method(dev, acpi_method, acpi_function, pintput, poutput, output_count, input_size, output_size)	\
+	CGS_CALL(call_acpi_method, dev, acpi_method, acpi_function, pintput, poutput, output_count, input_size, output_size)
+#define cgs_query_system_info(dev, sys_info)	\
+	CGS_CALL(query_system_info, dev, sys_info)
+#define cgs_get_pci_resource(cgs_device, resource_type, size, offset, \
+	resource_base) \
+	CGS_CALL(get_pci_resource, cgs_device, resource_type, size, offset, \
+	resource_base)
 
 #endif /* _CGS_COMMON_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/powerplay/Kconfig
@@ -0,0 +1,6 @@
+config DRM_AMD_POWERPLAY
+	bool  "Enable AMD powerplay component"
+	depends on DRM_AMDGPU
+	default n
+	help
+	  select this option will enable AMD powerplay component.
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/powerplay/Makefile
@@ -0,0 +1,22 @@
+
+subdir-ccflags-y += -Iinclude/drm  \
+		-Idrivers/gpu/drm/amd/powerplay/inc/  \
+		-Idrivers/gpu/drm/amd/include/asic_reg  \
+		-Idrivers/gpu/drm/amd/include  \
+		-Idrivers/gpu/drm/amd/powerplay/smumgr\
+		-Idrivers/gpu/drm/amd/powerplay/hwmgr \
+		-Idrivers/gpu/drm/amd/powerplay/eventmgr
+
+AMD_PP_PATH = ../powerplay
+
+PP_LIBS = smumgr hwmgr eventmgr
+
+AMD_POWERPLAY = $(addsuffix /Makefile,$(addprefix drivers/gpu/drm/amd/powerplay/,$(PP_LIBS)))
+
+include $(AMD_POWERPLAY)
+
+POWER_MGR = amd_powerplay.o
+
+AMD_PP_POWER = $(addprefix $(AMD_PP_PATH)/,$(POWER_MGR))
+
+AMD_POWERPLAY_FILES += $(AMD_PP_POWER)
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/powerplay/amd_powerplay.c
@@ -0,0 +1,665 @@
+/*
+ * Copyright 2015 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/gfp.h>
+#include <linux/slab.h>
+#include "amd_shared.h"
+#include "amd_powerplay.h"
+#include "pp_instance.h"
+#include "power_state.h"
+#include "eventmanager.h"
+
+#define PP_CHECK(handle)						\
+	do {								\
+		if ((handle) == NULL || (handle)->pp_valid != PP_VALID)	\
+			return -EINVAL;					\
+	} while (0)
+
+static int pp_early_init(void *handle)
+{
+	return 0;
+}
+
+static int pp_sw_init(void *handle)
+{
+	struct pp_instance *pp_handle;
+	struct pp_hwmgr  *hwmgr;
+	int ret = 0;
+
+	if (handle == NULL)
+		return -EINVAL;
+
+	pp_handle = (struct pp_instance *)handle;
+	hwmgr = pp_handle->hwmgr;
+
+	if (hwmgr == NULL || hwmgr->pptable_func == NULL ||
+	    hwmgr->hwmgr_func == NULL ||
+	    hwmgr->pptable_func->pptable_init == NULL ||
+	    hwmgr->hwmgr_func->backend_init == NULL)
+		return -EINVAL;
+
+	ret = hwmgr->pptable_func->pptable_init(hwmgr);
+
+	if (ret == 0)
+		ret = hwmgr->hwmgr_func->backend_init(hwmgr);
+
+	if (ret)
+		printk("amdgpu: powerplay initialization failed\n");
+	else
+		printk("amdgpu: powerplay initialized\n");
+
+	return ret;
+}
+
+static int pp_sw_fini(void *handle)
+{
+	struct pp_instance *pp_handle;
+	struct pp_hwmgr  *hwmgr;
+	int ret = 0;
+
+	if (handle == NULL)
+		return -EINVAL;
+
+	pp_handle = (struct pp_instance *)handle;
+	hwmgr = pp_handle->hwmgr;
+
+	if (hwmgr != NULL || hwmgr->hwmgr_func != NULL ||
+	    hwmgr->hwmgr_func->backend_fini != NULL)
+		ret = hwmgr->hwmgr_func->backend_fini(hwmgr);
+
+	return ret;
+}
+
+static int pp_hw_init(void *handle)
+{
+	struct pp_instance *pp_handle;
+	struct pp_smumgr *smumgr;
+	struct pp_eventmgr *eventmgr;
+	int ret = 0;
+
+	if (handle == NULL)
+		return -EINVAL;
+
+	pp_handle = (struct pp_instance *)handle;
+	smumgr = pp_handle->smu_mgr;
+
+	if (smumgr == NULL || smumgr->smumgr_funcs == NULL ||
+		smumgr->smumgr_funcs->smu_init == NULL ||
+		smumgr->smumgr_funcs->start_smu == NULL)
+		return -EINVAL;
+
+	ret = smumgr->smumgr_funcs->smu_init(smumgr);
+	if (ret) {
+		printk(KERN_ERR "[ powerplay ] smc initialization failed\n");
+		return ret;
+	}
+
+	ret = smumgr->smumgr_funcs->start_smu(smumgr);
+	if (ret) {
+		printk(KERN_ERR "[ powerplay ] smc start failed\n");
+		smumgr->smumgr_funcs->smu_fini(smumgr);
+		return ret;
+	}
+
+	hw_init_power_state_table(pp_handle->hwmgr);
+	eventmgr = pp_handle->eventmgr;
+
+	if (eventmgr == NULL || eventmgr->pp_eventmgr_init == NULL)
+		return -EINVAL;
+
+	ret = eventmgr->pp_eventmgr_init(eventmgr);
+	return 0;
+}
+
+static int pp_hw_fini(void *handle)
+{
+	struct pp_instance *pp_handle;
+	struct pp_smumgr *smumgr;
+	struct pp_eventmgr *eventmgr;
+
+	if (handle == NULL)
+		return -EINVAL;
+
+	pp_handle = (struct pp_instance *)handle;
+	eventmgr = pp_handle->eventmgr;
+
+	if (eventmgr != NULL || eventmgr->pp_eventmgr_fini != NULL)
+		eventmgr->pp_eventmgr_fini(eventmgr);
+
+	smumgr = pp_handle->smu_mgr;
+
+	if (smumgr != NULL || smumgr->smumgr_funcs != NULL ||
+		smumgr->smumgr_funcs->smu_fini != NULL)
+		smumgr->smumgr_funcs->smu_fini(smumgr);
+
+	return 0;
+}
+
+static bool pp_is_idle(void *handle)
+{
+	return 0;
+}
+
+static int pp_wait_for_idle(void *handle)
+{
+	return 0;
+}
+
+static int pp_sw_reset(void *handle)
+{
+	return 0;
+}
+
+static void pp_print_status(void *handle)
+{
+
+}
+
+static int pp_set_clockgating_state(void *handle,
+				    enum amd_clockgating_state state)
+{
+	return 0;
+}
+
+static int pp_set_powergating_state(void *handle,
+				    enum amd_powergating_state state)
+{
+	return 0;
+}
+
+static int pp_suspend(void *handle)
+{
+	struct pp_instance *pp_handle;
+	struct pp_eventmgr *eventmgr;
+	struct pem_event_data event_data = { {0} };
+
+	if (handle == NULL)
+		return -EINVAL;
+
+	pp_handle = (struct pp_instance *)handle;
+	eventmgr = pp_handle->eventmgr;
+	pem_handle_event(eventmgr, AMD_PP_EVENT_SUSPEND, &event_data);
+	return 0;
+}
+
+static int pp_resume(void *handle)
+{
+	struct pp_instance *pp_handle;
+	struct pp_eventmgr *eventmgr;
+	struct pem_event_data event_data = { {0} };
+	struct pp_smumgr *smumgr;
+	int ret;
+
+	if (handle == NULL)
+		return -EINVAL;
+
+	pp_handle = (struct pp_instance *)handle;
+	smumgr = pp_handle->smu_mgr;
+
+	if (smumgr == NULL || smumgr->smumgr_funcs == NULL ||
+		smumgr->smumgr_funcs->start_smu == NULL)
+		return -EINVAL;
+
+	ret = smumgr->smumgr_funcs->start_smu(smumgr);
+	if (ret) {
+		printk(KERN_ERR "[ powerplay ] smc start failed\n");
+		smumgr->smumgr_funcs->smu_fini(smumgr);
+		return ret;
+	}
+
+	eventmgr = pp_handle->eventmgr;
+	pem_handle_event(eventmgr, AMD_PP_EVENT_RESUME, &event_data);
+
+	return 0;
+}
+
+const struct amd_ip_funcs pp_ip_funcs = {
+	.early_init = pp_early_init,
+	.late_init = NULL,
+	.sw_init = pp_sw_init,
+	.sw_fini = pp_sw_fini,
+	.hw_init = pp_hw_init,
+	.hw_fini = pp_hw_fini,
+	.suspend = pp_suspend,
+	.resume = pp_resume,
+	.is_idle = pp_is_idle,
+	.wait_for_idle = pp_wait_for_idle,
+	.soft_reset = pp_sw_reset,
+	.print_status = pp_print_status,
+	.set_clockgating_state = pp_set_clockgating_state,
+	.set_powergating_state = pp_set_powergating_state,
+};
+
+static int pp_dpm_load_fw(void *handle)
+{
+	return 0;
+}
+
+static int pp_dpm_fw_loading_complete(void *handle)
+{
+	return 0;
+}
+
+static int pp_dpm_force_performance_level(void *handle,
+					enum amd_dpm_forced_level level)
+{
+	struct pp_instance *pp_handle;
+	struct pp_hwmgr  *hwmgr;
+
+	if (handle == NULL)
+		return -EINVAL;
+
+	pp_handle = (struct pp_instance *)handle;
+
+	hwmgr = pp_handle->hwmgr;
+
+	if (hwmgr == NULL || hwmgr->hwmgr_func == NULL ||
+	    hwmgr->hwmgr_func->force_dpm_level == NULL)
+		return -EINVAL;
+
+	hwmgr->hwmgr_func->force_dpm_level(hwmgr, level);
+
+	return 0;
+}
+
+static enum amd_dpm_forced_level pp_dpm_get_performance_level(
+								void *handle)
+{
+	struct pp_hwmgr  *hwmgr;
+
+	if (handle == NULL)
+		return -EINVAL;
+
+	hwmgr = ((struct pp_instance *)handle)->hwmgr;
+
+	if (hwmgr == NULL)
+		return -EINVAL;
+
+	return (((struct pp_instance *)handle)->hwmgr->dpm_level);
+}
+
+static int pp_dpm_get_sclk(void *handle, bool low)
+{
+	struct pp_hwmgr  *hwmgr;
+
+	if (handle == NULL)
+		return -EINVAL;
+
+	hwmgr = ((struct pp_instance *)handle)->hwmgr;
+
+	if (hwmgr == NULL || hwmgr->hwmgr_func == NULL ||
+	    hwmgr->hwmgr_func->get_sclk == NULL)
+		return -EINVAL;
+
+	return hwmgr->hwmgr_func->get_sclk(hwmgr, low);
+}
+
+static int pp_dpm_get_mclk(void *handle, bool low)
+{
+	struct pp_hwmgr  *hwmgr;
+
+	if (handle == NULL)
+		return -EINVAL;
+
+	hwmgr = ((struct pp_instance *)handle)->hwmgr;
+
+	if (hwmgr == NULL || hwmgr->hwmgr_func == NULL ||
+	    hwmgr->hwmgr_func->get_mclk == NULL)
+		return -EINVAL;
+
+	return hwmgr->hwmgr_func->get_mclk(hwmgr, low);
+}
+
+static int pp_dpm_powergate_vce(void *handle, bool gate)
+{
+	struct pp_hwmgr  *hwmgr;
+
+	if (handle == NULL)
+		return -EINVAL;
+
+	hwmgr = ((struct pp_instance *)handle)->hwmgr;
+
+	if (hwmgr == NULL || hwmgr->hwmgr_func == NULL ||
+	    hwmgr->hwmgr_func->powergate_vce == NULL)
+		return -EINVAL;
+
+	return hwmgr->hwmgr_func->powergate_vce(hwmgr, gate);
+}
+
+static int pp_dpm_powergate_uvd(void *handle, bool gate)
+{
+	struct pp_hwmgr  *hwmgr;
+
+	if (handle == NULL)
+		return -EINVAL;
+
+	hwmgr = ((struct pp_instance *)handle)->hwmgr;
+
+	if (hwmgr == NULL || hwmgr->hwmgr_func == NULL ||
+	    hwmgr->hwmgr_func->powergate_uvd == NULL)
+		return -EINVAL;
+
+	return hwmgr->hwmgr_func->powergate_uvd(hwmgr, gate);
+}
+
+static enum PP_StateUILabel power_state_convert(enum amd_pm_state_type  state)
+{
+	switch (state) {
+	case POWER_STATE_TYPE_BATTERY:
+		return PP_StateUILabel_Battery;
+	case POWER_STATE_TYPE_BALANCED:
+		return PP_StateUILabel_Balanced;
+	case POWER_STATE_TYPE_PERFORMANCE:
+		return PP_StateUILabel_Performance;
+	default:
+		return PP_StateUILabel_None;
+	}
+}
+
+int pp_dpm_dispatch_tasks(void *handle, enum amd_pp_event event_id, void *input, void *output)
+{
+	int ret = 0;
+	struct pp_instance *pp_handle;
+	struct pem_event_data data = { {0} };
+
+	pp_handle = (struct pp_instance *)handle;
+
+	if (pp_handle == NULL)
+		return -EINVAL;
+
+	switch (event_id) {
+	case AMD_PP_EVENT_DISPLAY_CONFIG_CHANGE:
+		ret = pem_handle_event(pp_handle->eventmgr, event_id, &data);
+		break;
+	case AMD_PP_EVENT_ENABLE_USER_STATE:
+	{
+		enum amd_pm_state_type  ps;
+
+		if (input == NULL)
+			return -EINVAL;
+		ps = *(unsigned long *)input;
+
+		data.requested_ui_label = power_state_convert(ps);
+		ret = pem_handle_event(pp_handle->eventmgr, event_id, &data);
+	}
+	break;
+	default:
+		break;
+	}
+	return ret;
+}
+
+enum amd_pm_state_type pp_dpm_get_current_power_state(void *handle)
+{
+	struct pp_hwmgr *hwmgr;
+	struct pp_power_state *state;
+
+	if (handle == NULL)
+		return -EINVAL;
+
+	hwmgr = ((struct pp_instance *)handle)->hwmgr;
+
+	if (hwmgr == NULL || hwmgr->current_ps == NULL)
+		return -EINVAL;
+
+	state = hwmgr->current_ps;
+
+	switch (state->classification.ui_label) {
+	case PP_StateUILabel_Battery:
+		return POWER_STATE_TYPE_BATTERY;
+	case PP_StateUILabel_Balanced:
+		return POWER_STATE_TYPE_BALANCED;
+	case PP_StateUILabel_Performance:
+		return POWER_STATE_TYPE_PERFORMANCE;
+	default:
+		return POWER_STATE_TYPE_DEFAULT;
+	}
+}
+
+static void
+pp_debugfs_print_current_performance_level(void *handle,
+					       struct seq_file *m)
+{
+	struct pp_hwmgr  *hwmgr;
+
+	if (handle == NULL)
+		return;
+
+	hwmgr = ((struct pp_instance *)handle)->hwmgr;
+
+	if (hwmgr == NULL || hwmgr->hwmgr_func == NULL ||
+	  hwmgr->hwmgr_func->print_current_perforce_level == NULL)
+		return;
+
+	hwmgr->hwmgr_func->print_current_perforce_level(hwmgr, m);
+}
+
+static int pp_dpm_set_fan_control_mode(void *handle, uint32_t mode)
+{
+	struct pp_hwmgr  *hwmgr;
+
+	if (handle == NULL)
+		return -EINVAL;
+
+	hwmgr = ((struct pp_instance *)handle)->hwmgr;
+
+	if (hwmgr == NULL || hwmgr->hwmgr_func == NULL ||
+	  hwmgr->hwmgr_func->set_fan_control_mode == NULL)
+		return -EINVAL;
+
+	return hwmgr->hwmgr_func->set_fan_control_mode(hwmgr, mode);
+}
+
+static int pp_dpm_get_fan_control_mode(void *handle)
+{
+	struct pp_hwmgr  *hwmgr;
+
+	if (handle == NULL)
+		return -EINVAL;
+
+	hwmgr = ((struct pp_instance *)handle)->hwmgr;
+
+	if (hwmgr == NULL || hwmgr->hwmgr_func == NULL ||
+	  hwmgr->hwmgr_func->get_fan_control_mode == NULL)
+		return -EINVAL;
+
+	return hwmgr->hwmgr_func->get_fan_control_mode(hwmgr);
+}
+
+static int pp_dpm_set_fan_speed_percent(void *handle, uint32_t percent)
+{
+	struct pp_hwmgr  *hwmgr;
+
+	if (handle == NULL)
+		return -EINVAL;
+
+	hwmgr = ((struct pp_instance *)handle)->hwmgr;
+
+	if (hwmgr == NULL || hwmgr->hwmgr_func == NULL ||
+	  hwmgr->hwmgr_func->set_fan_speed_percent == NULL)
+		return -EINVAL;
+
+	return hwmgr->hwmgr_func->set_fan_speed_percent(hwmgr, percent);
+}
+
+static int pp_dpm_get_fan_speed_percent(void *handle, uint32_t *speed)
+{
+	struct pp_hwmgr  *hwmgr;
+
+	if (handle == NULL)
+		return -EINVAL;
+
+	hwmgr = ((struct pp_instance *)handle)->hwmgr;
+
+	if (hwmgr == NULL || hwmgr->hwmgr_func == NULL ||
+	  hwmgr->hwmgr_func->get_fan_speed_percent == NULL)
+		return -EINVAL;
+
+	return hwmgr->hwmgr_func->get_fan_speed_percent(hwmgr, speed);
+}
+
+static int pp_dpm_get_temperature(void *handle)
+{
+	struct pp_hwmgr  *hwmgr;
+
+	if (handle == NULL)
+		return -EINVAL;
+
+	hwmgr = ((struct pp_instance *)handle)->hwmgr;
+
+	if (hwmgr == NULL || hwmgr->hwmgr_func == NULL ||
+	  hwmgr->hwmgr_func->get_temperature == NULL)
+		return -EINVAL;
+
+	return hwmgr->hwmgr_func->get_temperature(hwmgr);
+}
+
+const struct amd_powerplay_funcs pp_dpm_funcs = {
+	.get_temperature = pp_dpm_get_temperature,
+	.load_firmware = pp_dpm_load_fw,
+	.wait_for_fw_loading_complete = pp_dpm_fw_loading_complete,
+	.force_performance_level = pp_dpm_force_performance_level,
+	.get_performance_level = pp_dpm_get_performance_level,
+	.get_current_power_state = pp_dpm_get_current_power_state,
+	.get_sclk = pp_dpm_get_sclk,
+	.get_mclk = pp_dpm_get_mclk,
+	.powergate_vce = pp_dpm_powergate_vce,
+	.powergate_uvd = pp_dpm_powergate_uvd,
+	.dispatch_tasks = pp_dpm_dispatch_tasks,
+	.print_current_performance_level = pp_debugfs_print_current_performance_level,
+	.set_fan_control_mode = pp_dpm_set_fan_control_mode,
+	.get_fan_control_mode = pp_dpm_get_fan_control_mode,
+	.set_fan_speed_percent = pp_dpm_set_fan_speed_percent,
+	.get_fan_speed_percent = pp_dpm_get_fan_speed_percent,
+};
+
+static int amd_pp_instance_init(struct amd_pp_init *pp_init,
+				struct amd_powerplay *amd_pp)
+{
+	int ret;
+	struct pp_instance *handle;
+
+	handle = kzalloc(sizeof(struct pp_instance), GFP_KERNEL);
+	if (handle == NULL)
+		return -ENOMEM;
+
+	handle->pp_valid = PP_VALID;
+
+	ret = smum_init(pp_init, handle);
+	if (ret)
+		goto fail_smum;
+
+	ret = hwmgr_init(pp_init, handle);
+	if (ret)
+		goto fail_hwmgr;
+
+	ret = eventmgr_init(handle);
+	if (ret)
+		goto fail_eventmgr;
+
+	amd_pp->pp_handle = handle;
+	return 0;
+
+fail_eventmgr:
+	hwmgr_fini(handle->hwmgr);
+fail_hwmgr:
+	smum_fini(handle->smu_mgr);
+fail_smum:
+	kfree(handle);
+	return ret;
+}
+
+static int amd_pp_instance_fini(void *handle)
+{
+	struct pp_instance *instance = (struct pp_instance *)handle;
+
+	if (instance == NULL)
+		return -EINVAL;
+
+	eventmgr_fini(instance->eventmgr);
+
+	hwmgr_fini(instance->hwmgr);
+
+	smum_fini(instance->smu_mgr);
+
+	kfree(handle);
+	return 0;
+}
+
+int amd_powerplay_init(struct amd_pp_init *pp_init,
+		       struct amd_powerplay *amd_pp)
+{
+	int ret;
+
+	if (pp_init == NULL || amd_pp == NULL)
+		return -EINVAL;
+
+	ret = amd_pp_instance_init(pp_init, amd_pp);
+
+	if (ret)
+		return ret;
+
+	amd_pp->ip_funcs = &pp_ip_funcs;
+	amd_pp->pp_funcs = &pp_dpm_funcs;
+
+	return 0;
+}
+
+int amd_powerplay_fini(void *handle)
+{
+	amd_pp_instance_fini(handle);
+
+	return 0;
+}
+
+/* export this function to DAL */
+
+int amd_powerplay_display_configuration_change(void *handle, const void *input)
+{
+	struct pp_hwmgr  *hwmgr;
+	const struct amd_pp_display_configuration *display_config = input;
+
+	PP_CHECK((struct pp_instance *)handle);
+
+	hwmgr = ((struct pp_instance *)handle)->hwmgr;
+
+	phm_store_dal_configuration_data(hwmgr, display_config);
+
+	return 0;
+}
+
+int amd_powerplay_get_display_power_level(void *handle,
+		struct amd_pp_dal_clock_info *output)
+{
+	struct pp_hwmgr  *hwmgr;
+
+	PP_CHECK((struct pp_instance *)handle);
+
+	if (output == NULL)
+		return -EINVAL;
+
+	hwmgr = ((struct pp_instance *)handle)->hwmgr;
+
+	return phm_get_dal_power_level(hwmgr, output);
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/powerplay/eventmgr/Makefile
@@ -0,0 +1,11 @@
+#
+# Makefile for the 'event manager' sub-component of powerplay.
+# It provides the event management services for the driver.
+
+EVENT_MGR = eventmgr.o eventinit.o eventmanagement.o  \
+		eventactionchains.o eventsubchains.o eventtasks.o psm.o
+
+AMD_PP_EVENT = $(addprefix $(AMD_PP_PATH)/eventmgr/,$(EVENT_MGR))
+
+AMD_POWERPLAY_FILES += $(AMD_PP_EVENT)
+
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/powerplay/eventmgr/eventactionchains.c
@@ -0,0 +1,289 @@
+/*
+ * Copyright 2015 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+#include "eventmgr.h"
+#include "eventactionchains.h"
+#include "eventsubchains.h"
+
+static const pem_event_action *initialize_event[] = {
+	block_adjust_power_state_tasks,
+	power_budget_tasks,
+	system_config_tasks,
+	setup_asic_tasks,
+	enable_dynamic_state_management_tasks,
+	enable_clock_power_gatings_tasks,
+	get_2d_performance_state_tasks,
+	set_performance_state_tasks,
+	initialize_thermal_controller_tasks,
+	conditionally_force_3d_performance_state_tasks,
+	process_vbios_eventinfo_tasks,
+	broadcast_power_policy_tasks,
+	NULL
+};
+
+const struct action_chain initialize_action_chain = {
+	"Initialize",
+	initialize_event
+};
+
+static const pem_event_action *uninitialize_event[] = {
+	ungate_all_display_phys_tasks,
+	uninitialize_display_phy_access_tasks,
+	disable_gfx_voltage_island_power_gating_tasks,
+	disable_gfx_clock_gating_tasks,
+	set_boot_state_tasks,
+	adjust_power_state_tasks,
+	disable_dynamic_state_management_tasks,
+	disable_clock_power_gatings_tasks,
+	cleanup_asic_tasks,
+	prepare_for_pnp_stop_tasks,
+	NULL
+};
+
+const struct action_chain uninitialize_action_chain = {
+	"Uninitialize",
+	uninitialize_event
+};
+
+static const pem_event_action *power_source_change_event_pp_enabled[] = {
+	set_power_source_tasks,
+	set_power_saving_state_tasks,
+	adjust_power_state_tasks,
+	enable_disable_fps_tasks,
+	set_nbmcu_state_tasks,
+	broadcast_power_policy_tasks,
+	NULL
+};
+
+const struct action_chain power_source_change_action_chain_pp_enabled = {
+	"Power source change - PowerPlay enabled",
+	power_source_change_event_pp_enabled
+};
+
+static const pem_event_action *power_source_change_event_pp_disabled[] = {
+	set_power_source_tasks,
+	set_nbmcu_state_tasks,
+	NULL
+};
+
+const struct action_chain power_source_changes_action_chain_pp_disabled = {
+	"Power source change - PowerPlay disabled",
+	power_source_change_event_pp_disabled
+};
+
+static const pem_event_action *power_source_change_event_hardware_dc[] = {
+	set_power_source_tasks,
+	set_power_saving_state_tasks,
+	adjust_power_state_tasks,
+	enable_disable_fps_tasks,
+	reset_hardware_dc_notification_tasks,
+	set_nbmcu_state_tasks,
+	broadcast_power_policy_tasks,
+	NULL
+};
+
+const struct action_chain power_source_change_action_chain_hardware_dc = {
+	"Power source change - with Hardware DC switching",
+	power_source_change_event_hardware_dc
+};
+
+static const pem_event_action *suspend_event[] = {
+	reset_display_phy_access_tasks,
+	unregister_interrupt_tasks,
+	disable_gfx_voltage_island_power_gating_tasks,
+	disable_gfx_clock_gating_tasks,
+	notify_smu_suspend_tasks,
+	disable_smc_firmware_ctf_tasks,
+	set_boot_state_tasks,
+	adjust_power_state_tasks,
+	disable_fps_tasks,
+	vari_bright_suspend_tasks,
+	reset_fan_speed_to_default_tasks,
+	power_down_asic_tasks,
+	disable_stutter_mode_tasks,
+	set_connected_standby_tasks,
+	block_hw_access_tasks,
+	NULL
+};
+
+const struct action_chain suspend_action_chain = {
+	"Suspend",
+	suspend_event
+};
+
+static const pem_event_action *resume_event[] = {
+	unblock_hw_access_tasks,
+	resume_connected_standby_tasks,
+	notify_smu_resume_tasks,
+	reset_display_configCounter_tasks,
+	update_dal_configuration_tasks,
+	vari_bright_resume_tasks,
+	block_adjust_power_state_tasks,
+	setup_asic_tasks,
+	enable_stutter_mode_tasks, /*must do this in boot state and before SMC is started */
+	enable_dynamic_state_management_tasks,
+	enable_clock_power_gatings_tasks,
+	enable_disable_bapm_tasks,
+	initialize_thermal_controller_tasks,
+	reset_boot_state_tasks,
+	adjust_power_state_tasks,
+	enable_disable_fps_tasks,
+	notify_hw_power_source_tasks,
+	process_vbios_event_info_tasks,
+	enable_gfx_clock_gating_tasks,
+	enable_gfx_voltage_island_power_gating_tasks,
+	reset_clock_gating_tasks,
+	notify_smu_vpu_recovery_end_tasks,
+	disable_vpu_cap_tasks,
+	execute_escape_sequence_tasks,
+	NULL
+};
+
+
+const struct action_chain resume_action_chain = {
+	"resume",
+	resume_event
+};
+
+static const pem_event_action *complete_init_event[] = {
+	adjust_power_state_tasks,
+	enable_gfx_clock_gating_tasks,
+	enable_gfx_voltage_island_power_gating_tasks,
+	notify_power_state_change_tasks,
+	NULL
+};
+
+const struct action_chain complete_init_action_chain = {
+	"complete init",
+	complete_init_event
+};
+
+static const pem_event_action *enable_gfx_clock_gating_event[] = {
+	enable_gfx_clock_gating_tasks,
+	NULL
+};
+
+const struct action_chain enable_gfx_clock_gating_action_chain = {
+	"enable gfx clock gate",
+	enable_gfx_clock_gating_event
+};
+
+static const pem_event_action *disable_gfx_clock_gating_event[] = {
+	disable_gfx_clock_gating_tasks,
+	NULL
+};
+
+const struct action_chain disable_gfx_clock_gating_action_chain = {
+	"disable gfx clock gate",
+	disable_gfx_clock_gating_event
+};
+
+static const pem_event_action *enable_cgpg_event[] = {
+	enable_cgpg_tasks,
+	NULL
+};
+
+const struct action_chain enable_cgpg_action_chain = {
+	"eable cg pg",
+	enable_cgpg_event
+};
+
+static const pem_event_action *disable_cgpg_event[] = {
+	disable_cgpg_tasks,
+	NULL
+};
+
+const struct action_chain disable_cgpg_action_chain = {
+	"disable cg pg",
+	disable_cgpg_event
+};
+
+
+/* Enable user _2d performance and activate */
+
+static const pem_event_action *enable_user_state_event[] = {
+	create_new_user_performance_state_tasks,
+	adjust_power_state_tasks,
+	NULL
+};
+
+const struct action_chain enable_user_state_action_chain = {
+	"Enable user state",
+	enable_user_state_event
+};
+
+static const pem_event_action *enable_user_2d_performance_event[] = {
+	enable_user_2d_performance_tasks,
+	add_user_2d_performance_state_tasks,
+	set_performance_state_tasks,
+	adjust_power_state_tasks,
+	delete_user_2d_performance_state_tasks,
+	NULL
+};
+
+const struct action_chain enable_user_2d_performance_action_chain = {
+	"enable_user_2d_performance_event_activate",
+	enable_user_2d_performance_event
+};
+
+
+static const pem_event_action *disable_user_2d_performance_event[] = {
+	disable_user_2d_performance_tasks,
+	delete_user_2d_performance_state_tasks,
+	NULL
+};
+
+const struct action_chain disable_user_2d_performance_action_chain = {
+	"disable_user_2d_performance_event",
+	disable_user_2d_performance_event
+};
+
+
+static const pem_event_action *display_config_change_event[] = {
+	/* countDisplayConfigurationChangeEventTasks, */
+	unblock_adjust_power_state_tasks,
+	set_cpu_power_state,
+	notify_hw_power_source_tasks,
+	/* updateDALConfigurationTasks,
+	variBrightDisplayConfigurationChangeTasks, */
+	adjust_power_state_tasks,
+	/*enableDisableFPSTasks,
+	setNBMCUStateTasks,
+	notifyPCIEDeviceReadyTasks,*/
+	NULL
+};
+
+const struct action_chain display_config_change_action_chain = {
+	"Display configuration change",
+	display_config_change_event
+};
+
+static const pem_event_action *readjust_power_state_event[] = {
+	adjust_power_state_tasks,
+	NULL
+};
+
+const struct action_chain readjust_power_state_action_chain = {
+	"re-adjust power state",
+	readjust_power_state_event
+};
+
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/powerplay/eventmgr/eventactionchains.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2015 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+#ifndef _EVENT_ACTION_CHAINS_H_
+#define _EVENT_ACTION_CHAINS_H_
+#include "eventmgr.h"
+
+extern const struct action_chain initialize_action_chain;
+
+extern const struct action_chain uninitialize_action_chain;
+
+extern const struct action_chain power_source_change_action_chain_pp_enabled;
+
+extern const struct action_chain power_source_changes_action_chain_pp_disabled;
+
+extern const struct action_chain power_source_change_action_chain_hardware_dc;
+
+extern const struct action_chain suspend_action_chain;
+
+extern const struct action_chain resume_action_chain;
+
+extern const struct action_chain complete_init_action_chain;
+
+extern const struct action_chain enable_gfx_clock_gating_action_chain;
+
+extern const struct action_chain disable_gfx_clock_gating_action_chain;
+
+extern const struct action_chain enable_cgpg_action_chain;
+
+extern const struct action_chain disable_cgpg_action_chain;
+
+extern const struct action_chain enable_user_2d_performance_action_chain;
+
+extern const struct action_chain disable_user_2d_performance_action_chain;
+
+extern const struct action_chain enable_user_state_action_chain;
+
+extern const struct action_chain readjust_power_state_action_chain;
+
+extern const struct action_chain display_config_change_action_chain;
+
+#endif /*_EVENT_ACTION_CHAINS_H_*/
+
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/powerplay/eventmgr/eventinit.c
@@ -0,0 +1,195 @@
+/*
+ * Copyright 2015 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+#include "eventmgr.h"
+#include "eventinit.h"
+#include "ppinterrupt.h"
+#include "hardwaremanager.h"
+
+void pem_init_feature_info(struct pp_eventmgr *eventmgr)
+{
+
+	/* PowerPlay info */
+	eventmgr->ui_state_info[PP_PowerSource_AC].default_ui_lable =
+					    PP_StateUILabel_Performance;
+
+	eventmgr->ui_state_info[PP_PowerSource_AC].current_ui_label =
+					    PP_StateUILabel_Performance;
+
+	eventmgr->ui_state_info[PP_PowerSource_DC].default_ui_lable =
+						  PP_StateUILabel_Battery;
+
+	eventmgr->ui_state_info[PP_PowerSource_DC].current_ui_label =
+						  PP_StateUILabel_Battery;
+
+	if (phm_cap_enabled(eventmgr->platform_descriptor->platformCaps, PHM_PlatformCaps_PowerPlaySupport)) {
+		eventmgr->features[PP_Feature_PowerPlay].supported = true;
+		eventmgr->features[PP_Feature_PowerPlay].version = PEM_CURRENT_POWERPLAY_FEATURE_VERSION;
+		eventmgr->features[PP_Feature_PowerPlay].enabled_default = true;
+		eventmgr->features[PP_Feature_PowerPlay].enabled = true;
+	} else {
+		eventmgr->features[PP_Feature_PowerPlay].supported = false;
+		eventmgr->features[PP_Feature_PowerPlay].enabled = false;
+		eventmgr->features[PP_Feature_PowerPlay].enabled_default = false;
+	}
+
+	eventmgr->features[PP_Feature_Force3DClock].supported = true;
+	eventmgr->features[PP_Feature_Force3DClock].enabled = false;
+	eventmgr->features[PP_Feature_Force3DClock].enabled_default = false;
+	eventmgr->features[PP_Feature_Force3DClock].version = 1;
+
+	/* over drive*/
+	eventmgr->features[PP_Feature_User2DPerformance].version = 4;
+	eventmgr->features[PP_Feature_User3DPerformance].version = 4;
+	eventmgr->features[PP_Feature_OverdriveTest].version = 4;
+
+	eventmgr->features[PP_Feature_OverDrive].version = 4;
+	eventmgr->features[PP_Feature_OverDrive].enabled = false;
+	eventmgr->features[PP_Feature_OverDrive].enabled_default = false;
+
+	eventmgr->features[PP_Feature_User2DPerformance].supported = false;
+	eventmgr->features[PP_Feature_User2DPerformance].enabled = false;
+	eventmgr->features[PP_Feature_User2DPerformance].enabled_default = false;
+
+	eventmgr->features[PP_Feature_User3DPerformance].supported = false;
+	eventmgr->features[PP_Feature_User3DPerformance].enabled = false;
+	eventmgr->features[PP_Feature_User3DPerformance].enabled_default = false;
+
+	eventmgr->features[PP_Feature_OverdriveTest].supported = false;
+	eventmgr->features[PP_Feature_OverdriveTest].enabled = false;
+	eventmgr->features[PP_Feature_OverdriveTest].enabled_default = false;
+
+	eventmgr->features[PP_Feature_OverDrive].supported = false;
+
+	eventmgr->features[PP_Feature_PowerBudgetWaiver].enabled_default = false;
+	eventmgr->features[PP_Feature_PowerBudgetWaiver].version = 1;
+	eventmgr->features[PP_Feature_PowerBudgetWaiver].supported = false;
+	eventmgr->features[PP_Feature_PowerBudgetWaiver].enabled = false;
+
+	/* Multi UVD States support */
+	eventmgr->features[PP_Feature_MultiUVDState].supported = false;
+	eventmgr->features[PP_Feature_MultiUVDState].enabled = false;
+	eventmgr->features[PP_Feature_MultiUVDState].enabled_default = false;
+
+	/* Dynamic UVD States support */
+	eventmgr->features[PP_Feature_DynamicUVDState].supported = false;
+	eventmgr->features[PP_Feature_DynamicUVDState].enabled = false;
+	eventmgr->features[PP_Feature_DynamicUVDState].enabled_default = false;
+
+	/* VCE DPM support */
+	eventmgr->features[PP_Feature_VCEDPM].supported = false;
+	eventmgr->features[PP_Feature_VCEDPM].enabled = false;
+	eventmgr->features[PP_Feature_VCEDPM].enabled_default = false;
+
+	/* ACP PowerGating support */
+	eventmgr->features[PP_Feature_ACP_POWERGATING].supported = false;
+	eventmgr->features[PP_Feature_ACP_POWERGATING].enabled = false;
+	eventmgr->features[PP_Feature_ACP_POWERGATING].enabled_default = false;
+
+	/* PPM support */
+	eventmgr->features[PP_Feature_PPM].version = 1;
+	eventmgr->features[PP_Feature_PPM].supported = false;
+	eventmgr->features[PP_Feature_PPM].enabled = false;
+
+	/* FFC support (enables fan and temp settings, Gemini needs temp settings) */
+	if (phm_cap_enabled(eventmgr->platform_descriptor->platformCaps, PHM_PlatformCaps_ODFuzzyFanControlSupport) ||
+	    phm_cap_enabled(eventmgr->platform_descriptor->platformCaps, PHM_PlatformCaps_GeminiRegulatorFanControlSupport)) {
+		eventmgr->features[PP_Feature_FFC].version = 1;
+		eventmgr->features[PP_Feature_FFC].supported = true;
+		eventmgr->features[PP_Feature_FFC].enabled = true;
+		eventmgr->features[PP_Feature_FFC].enabled_default = true;
+	} else {
+		eventmgr->features[PP_Feature_FFC].supported = false;
+		eventmgr->features[PP_Feature_FFC].enabled = false;
+		eventmgr->features[PP_Feature_FFC].enabled_default = false;
+	}
+
+	eventmgr->features[PP_Feature_VariBright].supported = false;
+	eventmgr->features[PP_Feature_VariBright].enabled = false;
+	eventmgr->features[PP_Feature_VariBright].enabled_default = false;
+
+	eventmgr->features[PP_Feature_BACO].supported = false;
+	eventmgr->features[PP_Feature_BACO].supported = false;
+	eventmgr->features[PP_Feature_BACO].enabled_default = false;
+
+	/* PowerDown feature support */
+	eventmgr->features[PP_Feature_PowerDown].supported = false;
+	eventmgr->features[PP_Feature_PowerDown].enabled = false;
+	eventmgr->features[PP_Feature_PowerDown].enabled_default = false;
+
+	eventmgr->features[PP_Feature_FPS].version = 1;
+	eventmgr->features[PP_Feature_FPS].supported = false;
+	eventmgr->features[PP_Feature_FPS].enabled_default = false;
+	eventmgr->features[PP_Feature_FPS].enabled = false;
+
+	eventmgr->features[PP_Feature_ViPG].version = 1;
+	eventmgr->features[PP_Feature_ViPG].supported = false;
+	eventmgr->features[PP_Feature_ViPG].enabled_default = false;
+	eventmgr->features[PP_Feature_ViPG].enabled = false;
+}
+
+static int thermal_interrupt_callback(void *private_data,
+				      unsigned src_id, const uint32_t *iv_entry)
+{
+	/* TO DO hanle PEM_Event_ThermalNotification (struct pp_eventmgr *)private_data*/
+	printk("current thermal is out of range \n");
+	return 0;
+}
+
+int pem_register_interrupts(struct pp_eventmgr *eventmgr)
+{
+	int result = 0;
+	struct pp_interrupt_registration_info info;
+
+	info.call_back = thermal_interrupt_callback;
+	info.context = eventmgr;
+
+	result = phm_register_thermal_interrupt(eventmgr->hwmgr, &info);
+
+	/* TODO:
+	 * 2. Register CTF event interrupt
+	 * 3. Register for vbios events interrupt
+	 * 4. Register External Throttle Interrupt
+	 * 5. Register Smc To Host Interrupt
+	 * */
+	return result;
+}
+
+
+int pem_unregister_interrupts(struct pp_eventmgr *eventmgr)
+{
+	return 0;
+}
+
+
+void pem_uninit_featureInfo(struct pp_eventmgr *eventmgr)
+{
+	eventmgr->features[PP_Feature_MultiUVDState].supported = false;
+	eventmgr->features[PP_Feature_VariBright].supported = false;
+	eventmgr->features[PP_Feature_PowerBudgetWaiver].supported = false;
+	eventmgr->features[PP_Feature_OverDrive].supported = false;
+	eventmgr->features[PP_Feature_OverdriveTest].supported = false;
+	eventmgr->features[PP_Feature_User3DPerformance].supported = false;
+	eventmgr->features[PP_Feature_User2DPerformance].supported = false;
+	eventmgr->features[PP_Feature_PowerPlay].supported = false;
+	eventmgr->features[PP_Feature_Force3DClock].supported = false;
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/powerplay/eventmgr/eventinit.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2015 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#ifndef _EVENTINIT_H_
+#define _EVENTINIT_H_
+
+#define PEM_CURRENT_POWERPLAY_FEATURE_VERSION 4
+
+void pem_init_feature_info(struct pp_eventmgr *eventmgr);
+void pem_uninit_featureInfo(struct pp_eventmgr *eventmgr);
+int pem_register_interrupts(struct pp_eventmgr *eventmgr);
+int pem_unregister_interrupts(struct pp_eventmgr *eventmgr);
+
+#endif /* _EVENTINIT_H_ */
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/powerplay/eventmgr/eventmanagement.c
@@ -0,0 +1,215 @@
+/*
+ * Copyright 2015 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+#include "eventmanagement.h"
+#include "eventmgr.h"
+#include "eventactionchains.h"
+
+int pem_init_event_action_chains(struct pp_eventmgr *eventmgr)
+{
+	int i;
+
+	for (i = 0; i < AMD_PP_EVENT_MAX; i++)
+		eventmgr->event_chain[i] = NULL;
+
+	eventmgr->event_chain[AMD_PP_EVENT_SUSPEND] = pem_get_suspend_action_chain(eventmgr);
+	eventmgr->event_chain[AMD_PP_EVENT_INITIALIZE] = pem_get_initialize_action_chain(eventmgr);
+	eventmgr->event_chain[AMD_PP_EVENT_UNINITIALIZE] = pem_get_uninitialize_action_chain(eventmgr);
+	eventmgr->event_chain[AMD_PP_EVENT_POWER_SOURCE_CHANGE] = pem_get_power_source_change_action_chain(eventmgr);
+	eventmgr->event_chain[AMD_PP_EVENT_HIBERNATE] = pem_get_hibernate_action_chain(eventmgr);
+	eventmgr->event_chain[AMD_PP_EVENT_RESUME] = pem_get_resume_action_chain(eventmgr);
+	eventmgr->event_chain[AMD_PP_EVENT_THERMAL_NOTIFICATION] = pem_get_thermal_notification_action_chain(eventmgr);
+	eventmgr->event_chain[AMD_PP_EVENT_VBIOS_NOTIFICATION] = pem_get_vbios_notification_action_chain(eventmgr);
+	eventmgr->event_chain[AMD_PP_EVENT_ENTER_THERMAL_STATE] = pem_get_enter_thermal_state_action_chain(eventmgr);
+	eventmgr->event_chain[AMD_PP_EVENT_EXIT_THERMAL_STATE] = pem_get_exit_thermal_state_action_chain(eventmgr);
+	eventmgr->event_chain[AMD_PP_EVENT_ENABLE_POWER_PLAY] = pem_get_enable_powerplay_action_chain(eventmgr);
+	eventmgr->event_chain[AMD_PP_EVENT_DISABLE_POWER_PLAY] = pem_get_disable_powerplay_action_chain(eventmgr);
+	eventmgr->event_chain[AMD_PP_EVENT_ENABLE_OVER_DRIVE_TEST] = pem_get_enable_overdrive_test_action_chain(eventmgr);
+	eventmgr->event_chain[AMD_PP_EVENT_DISABLE_OVER_DRIVE_TEST] = pem_get_disable_overdrive_test_action_chain(eventmgr);
+	eventmgr->event_chain[AMD_PP_EVENT_ENABLE_GFX_CLOCK_GATING] = pem_get_enable_gfx_clock_gating_action_chain(eventmgr);
+	eventmgr->event_chain[AMD_PP_EVENT_DISABLE_GFX_CLOCK_GATING] = pem_get_disable_gfx_clock_gating_action_chain(eventmgr);
+	eventmgr->event_chain[AMD_PP_EVENT_ENABLE_CGPG] = pem_get_enable_cgpg_action_chain(eventmgr);
+	eventmgr->event_chain[AMD_PP_EVENT_DISABLE_CGPG] = pem_get_disable_cgpg_action_chain(eventmgr);
+	eventmgr->event_chain[AMD_PP_EVENT_COMPLETE_INIT] = pem_get_complete_init_action_chain(eventmgr);
+	eventmgr->event_chain[AMD_PP_EVENT_SCREEN_ON] = pem_get_screen_on_action_chain(eventmgr);
+	eventmgr->event_chain[AMD_PP_EVENT_SCREEN_OFF] = pem_get_screen_off_action_chain(eventmgr);
+	eventmgr->event_chain[AMD_PP_EVENT_PRE_SUSPEND] = pem_get_pre_suspend_action_chain(eventmgr);
+	eventmgr->event_chain[AMD_PP_EVENT_PRE_RESUME] = pem_get_pre_resume_action_chain(eventmgr);
+	eventmgr->event_chain[AMD_PP_EVENT_ENABLE_USER_STATE] = pem_enable_user_state_action_chain(eventmgr);
+	eventmgr->event_chain[AMD_PP_EVENT_READJUST_POWER_STATE] = pem_readjust_power_state_action_chain(eventmgr);
+	eventmgr->event_chain[AMD_PP_EVENT_DISPLAY_CONFIG_CHANGE] = pem_display_config_change_action_chain(eventmgr);
+	return 0;
+}
+
+int pem_excute_event_chain(struct pp_eventmgr *eventmgr, const struct action_chain *event_chain, struct pem_event_data *event_data)
+{
+	const pem_event_action **paction_chain;
+	const pem_event_action *psub_chain;
+	int tmp_result = 0;
+	int result = 0;
+
+	if (eventmgr == NULL || event_chain == NULL || event_data == NULL)
+		return -EINVAL;
+
+	for (paction_chain = event_chain->action_chain; NULL != *paction_chain; paction_chain++) {
+		if (0 != result)
+			return result;
+
+		for (psub_chain = *paction_chain; NULL != *psub_chain; psub_chain++) {
+			tmp_result = (*psub_chain)(eventmgr, event_data);
+			if (0 == result)
+				result = tmp_result;
+		}
+	}
+
+	return result;
+}
+
+const struct action_chain *pem_get_suspend_action_chain(struct pp_eventmgr *eventmgr)
+{
+	return &suspend_action_chain;
+}
+
+const struct action_chain *pem_get_initialize_action_chain(struct pp_eventmgr *eventmgr)
+{
+	return &initialize_action_chain;
+}
+
+const struct action_chain *pem_get_uninitialize_action_chain(struct pp_eventmgr *eventmgr)
+{
+	return &uninitialize_action_chain;
+}
+
+const struct action_chain *pem_get_power_source_change_action_chain(struct pp_eventmgr *eventmgr)
+{
+	return &power_source_change_action_chain_pp_enabled;  /* other case base on feature info*/
+}
+
+const struct action_chain *pem_get_resume_action_chain(struct pp_eventmgr *eventmgr)
+{
+	return &resume_action_chain;
+}
+
+const struct action_chain *pem_get_hibernate_action_chain(struct pp_eventmgr *eventmgr)
+{
+	return NULL;
+}
+
+const struct action_chain *pem_get_thermal_notification_action_chain(struct pp_eventmgr *eventmgr)
+{
+	return NULL;
+}
+
+const struct action_chain *pem_get_vbios_notification_action_chain(struct pp_eventmgr *eventmgr)
+{
+	return NULL;
+}
+
+const struct action_chain *pem_get_enter_thermal_state_action_chain(struct pp_eventmgr *eventmgr)
+{
+	return NULL;
+}
+
+const struct action_chain *pem_get_exit_thermal_state_action_chain(struct pp_eventmgr *eventmgr)
+{
+	return NULL;
+}
+
+const struct action_chain *pem_get_enable_powerplay_action_chain(struct pp_eventmgr *eventmgr)
+{
+	return NULL;
+}
+
+const struct action_chain *pem_get_disable_powerplay_action_chain(struct pp_eventmgr *eventmgr)
+{
+	return NULL;
+}
+
+const struct action_chain *pem_get_enable_overdrive_test_action_chain(struct pp_eventmgr *eventmgr)
+{
+	return NULL;
+}
+
+const struct action_chain *pem_get_disable_overdrive_test_action_chain(struct pp_eventmgr *eventmgr)
+{
+	return NULL;
+}
+
+const struct action_chain *pem_get_enable_gfx_clock_gating_action_chain(struct pp_eventmgr *eventmgr)
+{
+	return &enable_gfx_clock_gating_action_chain;
+}
+
+const struct action_chain *pem_get_disable_gfx_clock_gating_action_chain(struct pp_eventmgr *eventmgr)
+{
+	return &disable_gfx_clock_gating_action_chain;
+}
+
+const struct action_chain *pem_get_enable_cgpg_action_chain(struct pp_eventmgr *eventmgr)
+{
+	return &enable_cgpg_action_chain;
+}
+
+const struct action_chain *pem_get_disable_cgpg_action_chain(struct pp_eventmgr *eventmgr)
+{
+	return &disable_cgpg_action_chain;
+}
+
+const struct action_chain *pem_get_complete_init_action_chain(struct pp_eventmgr *eventmgr)
+{
+	return &complete_init_action_chain;
+}
+
+const struct action_chain *pem_get_screen_on_action_chain(struct pp_eventmgr *eventmgr)
+{
+	return NULL;
+}
+
+const struct action_chain *pem_get_screen_off_action_chain(struct pp_eventmgr *eventmgr)
+{
+	return NULL;
+}
+
+const struct action_chain *pem_get_pre_suspend_action_chain(struct pp_eventmgr *eventmgr)
+{
+	return NULL;
+}
+
+const struct action_chain *pem_get_pre_resume_action_chain(struct pp_eventmgr *eventmgr)
+{
+	return NULL;
+}
+
+const struct action_chain *pem_enable_user_state_action_chain(struct pp_eventmgr *eventmgr)
+{
+	return &enable_user_state_action_chain;
+}
+
+const struct action_chain *pem_readjust_power_state_action_chain(struct pp_eventmgr *eventmgr)
+{
+	return &readjust_power_state_action_chain;
+}
+
+const struct action_chain *pem_display_config_change_action_chain(struct pp_eventmgr *eventmgr)
+{
+	return &display_config_change_action_chain;
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/powerplay/eventmgr/eventmanagement.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2015 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+#ifndef _EVENT_MANAGEMENT_H_
+#define _EVENT_MANAGEMENT_H_
+
+#include "eventmgr.h"
+
+int pem_init_event_action_chains(struct pp_eventmgr *eventmgr);
+int pem_excute_event_chain(struct pp_eventmgr *eventmgr, const struct action_chain *event_chain, struct pem_event_data *event_data);
+const struct action_chain *pem_get_suspend_action_chain(struct pp_eventmgr *eventmgr);
+const struct action_chain *pem_get_initialize_action_chain(struct pp_eventmgr *eventmgr);
+const struct action_chain *pem_get_uninitialize_action_chain(struct pp_eventmgr *eventmgr);
+const struct action_chain *pem_get_power_source_change_action_chain(struct pp_eventmgr *eventmgr);
+const struct action_chain *pem_get_resume_action_chain(struct pp_eventmgr *eventmgr);
+const struct action_chain *pem_get_hibernate_action_chain(struct pp_eventmgr *eventmgr);
+const struct action_chain *pem_get_thermal_notification_action_chain(struct pp_eventmgr *eventmgr);
+const struct action_chain *pem_get_vbios_notification_action_chain(struct pp_eventmgr *eventmgr);
+const struct action_chain *pem_get_enter_thermal_state_action_chain(struct pp_eventmgr *eventmgr);
+const struct action_chain *pem_get_exit_thermal_state_action_chain(struct pp_eventmgr *eventmgr);
+const struct action_chain *pem_get_enable_powerplay_action_chain(struct pp_eventmgr *eventmgr);
+const struct action_chain *pem_get_disable_powerplay_action_chain(struct pp_eventmgr *eventmgr);
+const struct action_chain *pem_get_enable_overdrive_test_action_chain(struct pp_eventmgr *eventmgr);
+const struct action_chain *pem_get_disable_overdrive_test_action_chain(struct pp_eventmgr *eventmgr);
+const struct action_chain *pem_get_enable_gfx_clock_gating_action_chain(struct pp_eventmgr *eventmgr);
+const struct action_chain *pem_get_disable_gfx_clock_gating_action_chain(struct pp_eventmgr *eventmgr);
+const struct action_chain *pem_get_enable_cgpg_action_chain(struct pp_eventmgr *eventmgr);
+const struct action_chain *pem_get_disable_cgpg_action_chain(struct pp_eventmgr *eventmgr);
+const struct action_chain *pem_get_complete_init_action_chain(struct pp_eventmgr *eventmgr);
+const struct action_chain *pem_get_screen_on_action_chain(struct pp_eventmgr *eventmgr);
+const struct action_chain *pem_get_screen_off_action_chain(struct pp_eventmgr *eventmgr);
+const struct action_chain *pem_get_pre_suspend_action_chain(struct pp_eventmgr *eventmgr);
+const struct action_chain *pem_get_pre_resume_action_chain(struct pp_eventmgr *eventmgr);
+
+extern const struct action_chain *pem_enable_user_state_action_chain(struct pp_eventmgr *eventmgr);
+extern const struct action_chain *pem_readjust_power_state_action_chain(struct pp_eventmgr *eventmgr);
+const struct action_chain *pem_display_config_change_action_chain(struct pp_eventmgr *eventmgr);
+
+
+#endif /* _EVENT_MANAGEMENT_H_ */
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/powerplay/eventmgr/eventmgr.c
@@ -0,0 +1,114 @@
+/*
+ * Copyright 2015 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include "eventmgr.h"
+#include "hwmgr.h"
+#include "eventinit.h"
+#include "eventmanagement.h"
+
+static int pem_init(struct pp_eventmgr *eventmgr)
+{
+	int result = 0;
+	struct pem_event_data event_data;
+
+	/* Initialize PowerPlay feature info */
+	pem_init_feature_info(eventmgr);
+
+	/* Initialize event action chains */
+	pem_init_event_action_chains(eventmgr);
+
+	/* Call initialization event */
+	result = pem_handle_event(eventmgr, AMD_PP_EVENT_INITIALIZE, &event_data);
+
+	if (0 != result)
+		return result;
+
+	/* Register interrupt callback functions */
+	result = pem_register_interrupts(eventmgr);
+	return 0;
+}
+
+static void pem_fini(struct pp_eventmgr *eventmgr)
+{
+	struct pem_event_data event_data;
+
+	pem_uninit_featureInfo(eventmgr);
+	pem_unregister_interrupts(eventmgr);
+
+	pem_handle_event(eventmgr, AMD_PP_EVENT_UNINITIALIZE, &event_data);
+
+	if (eventmgr != NULL)
+		kfree(eventmgr);
+}
+
+int eventmgr_init(struct pp_instance *handle)
+{
+	int result = 0;
+	struct pp_eventmgr *eventmgr;
+
+	if (handle == NULL)
+		return -EINVAL;
+
+	eventmgr = kzalloc(sizeof(struct pp_eventmgr), GFP_KERNEL);
+	if (eventmgr == NULL)
+		return -ENOMEM;
+
+	eventmgr->hwmgr = handle->hwmgr;
+	handle->eventmgr = eventmgr;
+
+	eventmgr->platform_descriptor = &(eventmgr->hwmgr->platform_descriptor);
+	eventmgr->pp_eventmgr_init = pem_init;
+	eventmgr->pp_eventmgr_fini = pem_fini;
+
+	return result;
+}
+
+int eventmgr_fini(struct pp_eventmgr *eventmgr)
+{
+	kfree(eventmgr);
+	return 0;
+}
+
+static int pem_handle_event_unlocked(struct pp_eventmgr *eventmgr, enum amd_pp_event event, struct pem_event_data *data)
+{
+	if (eventmgr == NULL || event >= AMD_PP_EVENT_MAX || data == NULL)
+		return -EINVAL;
+
+	return pem_excute_event_chain(eventmgr, eventmgr->event_chain[event], data);
+}
+
+int pem_handle_event(struct pp_eventmgr *eventmgr, enum amd_pp_event event, struct pem_event_data *event_data)
+{
+	int r = 0;
+
+	r = pem_handle_event_unlocked(eventmgr, event, event_data);
+
+	return r;
+}
+
+bool pem_is_hw_access_blocked(struct pp_eventmgr *eventmgr)
+{
+	return (eventmgr->block_adjust_power_state || phm_is_hw_access_blocked(eventmgr->hwmgr));
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/powerplay/eventmgr/eventsubchains.c
@@ -0,0 +1,410 @@
+/*
+ * Copyright 2015 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#include "eventmgr.h"
+#include "eventsubchains.h"
+#include "eventtasks.h"
+#include "hardwaremanager.h"
+
+const pem_event_action reset_display_phy_access_tasks[] = {
+	pem_task_reset_display_phys_access,
+	NULL
+};
+
+const pem_event_action broadcast_power_policy_tasks[] = {
+	/* PEM_Task_BroadcastPowerPolicyChange, */
+	NULL
+};
+
+const pem_event_action unregister_interrupt_tasks[] = {
+	pem_task_unregister_interrupts,
+	NULL
+};
+
+/* Disable GFX Voltage Islands Power Gating */
+const pem_event_action disable_gfx_voltage_island_powergating_tasks[] = {
+	pem_task_disable_voltage_island_power_gating,
+	NULL
+};
+
+const pem_event_action disable_gfx_clockgating_tasks[] = {
+	pem_task_disable_gfx_clock_gating,
+	NULL
+};
+
+const pem_event_action block_adjust_power_state_tasks[] = {
+	pem_task_block_adjust_power_state,
+	NULL
+};
+
+
+const pem_event_action unblock_adjust_power_state_tasks[] = {
+	pem_task_unblock_adjust_power_state,
+	NULL
+};
+
+const pem_event_action set_performance_state_tasks[] = {
+	pem_task_set_performance_state,
+	NULL
+};
+
+const pem_event_action get_2d_performance_state_tasks[] = {
+	pem_task_get_2D_performance_state_id,
+	NULL
+};
+
+const pem_event_action conditionally_force3D_performance_state_tasks[] = {
+	pem_task_conditionally_force_3d_performance_state,
+	NULL
+};
+
+const pem_event_action process_vbios_eventinfo_tasks[] = {
+	/* PEM_Task_ProcessVbiosEventInfo,*/
+	NULL
+};
+
+const pem_event_action enable_dynamic_state_management_tasks[] = {
+	/* PEM_Task_ResetBAPMPolicyChangedFlag,*/
+	pem_task_get_boot_state_id,
+	pem_task_enable_dynamic_state_management,
+	pem_task_register_interrupts,
+	NULL
+};
+
+const pem_event_action enable_clock_power_gatings_tasks[] = {
+	pem_task_enable_clock_power_gatings_tasks,
+	pem_task_powerdown_uvd_tasks,
+	pem_task_powerdown_vce_tasks,
+	NULL
+};
+
+const pem_event_action setup_asic_tasks[] = {
+	pem_task_setup_asic,
+	NULL
+};
+
+const pem_event_action power_budget_tasks[] = {
+	/* TODO
+	 * PEM_Task_PowerBudgetWaiverAvailable,
+	 * PEM_Task_PowerBudgetWarningMessage,
+	 * PEM_Task_PruneStatesBasedOnPowerBudget,
+	*/
+	NULL
+};
+
+const pem_event_action system_config_tasks[] = {
+	/* PEM_Task_PruneStatesBasedOnSystemConfig,*/
+	NULL
+};
+
+
+const pem_event_action conditionally_force_3d_performance_state_tasks[] = {
+	pem_task_conditionally_force_3d_performance_state,
+	NULL
+};
+
+const pem_event_action ungate_all_display_phys_tasks[] = {
+	/* PEM_Task_GetDisplayPhyAccessInfo */
+	NULL
+};
+
+const pem_event_action uninitialize_display_phy_access_tasks[] = {
+	/* PEM_Task_UninitializeDisplayPhysAccess, */
+	NULL
+};
+
+const pem_event_action disable_gfx_voltage_island_power_gating_tasks[] = {
+	/* PEM_Task_DisableVoltageIslandPowerGating, */
+	NULL
+};
+
+const pem_event_action disable_gfx_clock_gating_tasks[] = {
+	pem_task_disable_gfx_clock_gating,
+	NULL
+};
+
+const pem_event_action set_boot_state_tasks[] = {
+	pem_task_get_boot_state_id,
+	pem_task_set_boot_state,
+	NULL
+};
+
+const pem_event_action adjust_power_state_tasks[] = {
+	pem_task_notify_hw_mgr_display_configuration_change,
+	pem_task_adjust_power_state,
+	pem_task_notify_smc_display_config_after_power_state_adjustment,
+	pem_task_update_allowed_performance_levels,
+	/* to do pem_task_Enable_disable_bapm, */
+	NULL
+};
+
+const pem_event_action disable_dynamic_state_management_tasks[] = {
+	pem_task_unregister_interrupts,
+	pem_task_get_boot_state_id,
+	pem_task_disable_dynamic_state_management,
+	NULL
+};
+
+const pem_event_action disable_clock_power_gatings_tasks[] = {
+	pem_task_disable_clock_power_gatings_tasks,
+	NULL
+};
+
+const pem_event_action cleanup_asic_tasks[] = {
+	/* PEM_Task_DisableFPS,*/
+	pem_task_cleanup_asic,
+	NULL
+};
+
+const pem_event_action prepare_for_pnp_stop_tasks[] = {
+	/* PEM_Task_PrepareForPnpStop,*/
+	NULL
+};
+
+const pem_event_action set_power_source_tasks[] = {
+	pem_task_set_power_source,
+	pem_task_notify_hw_of_power_source,
+	NULL
+};
+
+const pem_event_action set_power_saving_state_tasks[] = {
+	pem_task_reset_power_saving_state,
+	pem_task_get_power_saving_state,
+	pem_task_set_power_saving_state,
+	/* PEM_Task_ResetODDCState,
+	 * PEM_Task_GetODDCState,
+	 * PEM_Task_SetODDCState,*/
+	NULL
+};
+
+const pem_event_action enable_disable_fps_tasks[] = {
+	/* PEM_Task_EnableDisableFPS,*/
+	NULL
+};
+
+const pem_event_action set_nbmcu_state_tasks[] = {
+	/* PEM_Task_NBMCUStateChange,*/
+	NULL
+};
+
+const pem_event_action reset_hardware_dc_notification_tasks[] = {
+	/* PEM_Task_ResetHardwareDCNotification,*/
+	NULL
+};
+
+
+const pem_event_action notify_smu_suspend_tasks[] = {
+	/* PEM_Task_NotifySMUSuspend,*/
+	NULL
+};
+
+const pem_event_action disable_smc_firmware_ctf_tasks[] = {
+	/* PEM_Task_DisableSMCFirmwareCTF,*/
+	NULL
+};
+
+const pem_event_action disable_fps_tasks[] = {
+	/* PEM_Task_DisableFPS,*/
+	NULL
+};
+
+const pem_event_action vari_bright_suspend_tasks[] = {
+	/* PEM_Task_VariBright_Suspend,*/
+	NULL
+};
+
+const pem_event_action reset_fan_speed_to_default_tasks[] = {
+	/* PEM_Task_ResetFanSpeedToDefault,*/
+	NULL
+};
+
+const pem_event_action power_down_asic_tasks[] = {
+	/* PEM_Task_DisableFPS,*/
+	pem_task_power_down_asic,
+	NULL
+};
+
+const pem_event_action disable_stutter_mode_tasks[] = {
+	/* PEM_Task_DisableStutterMode,*/
+	NULL
+};
+
+const pem_event_action set_connected_standby_tasks[] = {
+	/* PEM_Task_SetConnectedStandby,*/
+	NULL
+};
+
+const pem_event_action block_hw_access_tasks[] = {
+	pem_task_block_hw_access,
+	NULL
+};
+
+const pem_event_action unblock_hw_access_tasks[] = {
+	pem_task_un_block_hw_access,
+	NULL
+};
+
+const pem_event_action resume_connected_standby_tasks[] = {
+	/* PEM_Task_ResumeConnectedStandby,*/
+	NULL
+};
+
+const pem_event_action notify_smu_resume_tasks[] = {
+	/* PEM_Task_NotifySMUResume,*/
+	NULL
+};
+
+const pem_event_action reset_display_configCounter_tasks[] = {
+	pem_task_reset_display_phys_access,
+	NULL
+};
+
+const pem_event_action update_dal_configuration_tasks[] = {
+	/* PEM_Task_CheckVBlankTime,*/
+	NULL
+};
+
+const pem_event_action vari_bright_resume_tasks[] = {
+	/* PEM_Task_VariBright_Resume,*/
+	NULL
+};
+
+const pem_event_action notify_hw_power_source_tasks[] = {
+	pem_task_notify_hw_of_power_source,
+	NULL
+};
+
+const pem_event_action process_vbios_event_info_tasks[] = {
+	/* PEM_Task_ProcessVbiosEventInfo,*/
+	NULL
+};
+
+const pem_event_action enable_gfx_clock_gating_tasks[] = {
+	pem_task_enable_gfx_clock_gating,
+	NULL
+};
+
+const pem_event_action enable_gfx_voltage_island_power_gating_tasks[] = {
+	pem_task_enable_voltage_island_power_gating,
+	NULL
+};
+
+const pem_event_action reset_clock_gating_tasks[] = {
+	/* PEM_Task_ResetClockGating*/
+	NULL
+};
+
+const pem_event_action notify_smu_vpu_recovery_end_tasks[] = {
+	/* PEM_Task_NotifySmuVPURecoveryEnd,*/
+	NULL
+};
+
+const pem_event_action disable_vpu_cap_tasks[] = {
+	/* PEM_Task_DisableVPUCap,*/
+	NULL
+};
+
+const pem_event_action execute_escape_sequence_tasks[] = {
+	/* PEM_Task_ExecuteEscapesequence,*/
+	NULL
+};
+
+const pem_event_action notify_power_state_change_tasks[] = {
+	pem_task_notify_power_state_change,
+	NULL
+};
+
+const pem_event_action enable_cgpg_tasks[] = {
+	pem_task_enable_cgpg,
+	NULL
+};
+
+const pem_event_action disable_cgpg_tasks[] = {
+	pem_task_disable_cgpg,
+	NULL
+};
+
+const pem_event_action enable_user_2d_performance_tasks[] = {
+	/* PEM_Task_SetUser2DPerformanceFlag,*/
+	/* PEM_Task_UpdateUser2DPerformanceEnableEvents,*/
+	NULL
+};
+
+const pem_event_action add_user_2d_performance_state_tasks[] = {
+	/* PEM_Task_Get2DPerformanceTemplate,*/
+	/* PEM_Task_AllocateNewPowerStateMemory,*/
+	/* PEM_Task_CopyNewPowerStateInfo,*/
+	/* PEM_Task_UpdateNewPowerStateClocks,*/
+	/* PEM_Task_UpdateNewPowerStateUser2DPerformanceFlag,*/
+	/* PEM_Task_AddPowerState,*/
+	/* PEM_Task_ReleaseNewPowerStateMemory,*/
+	NULL
+};
+
+const pem_event_action delete_user_2d_performance_state_tasks[] = {
+	/* PEM_Task_GetCurrentUser2DPerformanceStateID,*/
+	/* PEM_Task_DeletePowerState,*/
+	/* PEM_Task_SetCurrentUser2DPerformanceStateID,*/
+	NULL
+};
+
+const pem_event_action disable_user_2d_performance_tasks[] = {
+	/* PEM_Task_ResetUser2DPerformanceFlag,*/
+	/* PEM_Task_UpdateUser2DPerformanceDisableEvents,*/
+	NULL
+};
+
+const pem_event_action enable_stutter_mode_tasks[] = {
+	pem_task_enable_stutter_mode,
+	NULL
+};
+
+const pem_event_action enable_disable_bapm_tasks[] = {
+	/*PEM_Task_EnableDisableBAPM,*/
+	NULL
+};
+
+const pem_event_action reset_boot_state_tasks[] = {
+	pem_task_reset_boot_state,
+	NULL
+};
+
+const pem_event_action create_new_user_performance_state_tasks[] = {
+	pem_task_create_user_performance_state,
+	NULL
+};
+
+const pem_event_action initialize_thermal_controller_tasks[] = {
+	pem_task_initialize_thermal_controller,
+	NULL
+};
+
+const pem_event_action uninitialize_thermal_controller_tasks[] = {
+	pem_task_uninitialize_thermal_controller,
+	NULL
+};
+
+const pem_event_action set_cpu_power_state[] = {
+	pem_task_set_cpu_power_state,
+	NULL
+};
\ No newline at end of file
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/powerplay/eventmgr/eventsubchains.h
@@ -0,0 +1,100 @@
+/*
+ * Copyright 2015 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#ifndef _EVENT_SUB_CHAINS_H_
+#define _EVENT_SUB_CHAINS_H_
+
+#include "eventmgr.h"
+
+extern const pem_event_action reset_display_phy_access_tasks[];
+extern const pem_event_action broadcast_power_policy_tasks[];
+extern const pem_event_action unregister_interrupt_tasks[];
+extern const pem_event_action disable_GFX_voltage_island_powergating_tasks[];
+extern const pem_event_action disable_GFX_clockgating_tasks[];
+extern const pem_event_action block_adjust_power_state_tasks[];
+extern const pem_event_action unblock_adjust_power_state_tasks[];
+extern const pem_event_action set_performance_state_tasks[];
+extern const pem_event_action get_2D_performance_state_tasks[];
+extern const pem_event_action conditionally_force3D_performance_state_tasks[];
+extern const pem_event_action process_vbios_eventinfo_tasks[];
+extern const pem_event_action enable_dynamic_state_management_tasks[];
+extern const pem_event_action enable_clock_power_gatings_tasks[];
+extern const pem_event_action conditionally_force3D_performance_state_tasks[];
+extern const pem_event_action setup_asic_tasks[];
+extern const pem_event_action power_budget_tasks[];
+extern const pem_event_action system_config_tasks[];
+extern const pem_event_action get_2d_performance_state_tasks[];
+extern const pem_event_action conditionally_force_3d_performance_state_tasks[];
+extern const pem_event_action ungate_all_display_phys_tasks[];
+extern const pem_event_action uninitialize_display_phy_access_tasks[];
+extern const pem_event_action disable_gfx_voltage_island_power_gating_tasks[];
+extern const pem_event_action disable_gfx_clock_gating_tasks[];
+extern const pem_event_action set_boot_state_tasks[];
+extern const pem_event_action adjust_power_state_tasks[];
+extern const pem_event_action disable_dynamic_state_management_tasks[];
+extern const pem_event_action disable_clock_power_gatings_tasks[];
+extern const pem_event_action cleanup_asic_tasks[];
+extern const pem_event_action prepare_for_pnp_stop_tasks[];
+extern const pem_event_action set_power_source_tasks[];
+extern const pem_event_action set_power_saving_state_tasks[];
+extern const pem_event_action enable_disable_fps_tasks[];
+extern const pem_event_action set_nbmcu_state_tasks[];
+extern const pem_event_action reset_hardware_dc_notification_tasks[];
+extern const pem_event_action notify_smu_suspend_tasks[];
+extern const pem_event_action disable_smc_firmware_ctf_tasks[];
+extern const pem_event_action disable_fps_tasks[];
+extern const pem_event_action vari_bright_suspend_tasks[];
+extern const pem_event_action reset_fan_speed_to_default_tasks[];
+extern const pem_event_action power_down_asic_tasks[];
+extern const pem_event_action disable_stutter_mode_tasks[];
+extern const pem_event_action set_connected_standby_tasks[];
+extern const pem_event_action block_hw_access_tasks[];
+extern const pem_event_action unblock_hw_access_tasks[];
+extern const pem_event_action resume_connected_standby_tasks[];
+extern const pem_event_action notify_smu_resume_tasks[];
+extern const pem_event_action reset_display_configCounter_tasks[];
+extern const pem_event_action update_dal_configuration_tasks[];
+extern const pem_event_action vari_bright_resume_tasks[];
+extern const pem_event_action notify_hw_power_source_tasks[];
+extern const pem_event_action process_vbios_event_info_tasks[];
+extern const pem_event_action enable_gfx_clock_gating_tasks[];
+extern const pem_event_action enable_gfx_voltage_island_power_gating_tasks[];
+extern const pem_event_action reset_clock_gating_tasks[];
+extern const pem_event_action notify_smu_vpu_recovery_end_tasks[];
+extern const pem_event_action disable_vpu_cap_tasks[];
+extern const pem_event_action execute_escape_sequence_tasks[];
+extern const pem_event_action notify_power_state_change_tasks[];
+extern const pem_event_action enable_cgpg_tasks[];
+extern const pem_event_action disable_cgpg_tasks[];
+extern const pem_event_action enable_user_2d_performance_tasks[];
+extern const pem_event_action add_user_2d_performance_state_tasks[];
+extern const pem_event_action delete_user_2d_performance_state_tasks[];
+extern const pem_event_action disable_user_2d_performance_tasks[];
+extern const pem_event_action enable_stutter_mode_tasks[];
+extern const pem_event_action enable_disable_bapm_tasks[];
+extern const pem_event_action reset_boot_state_tasks[];
+extern const pem_event_action create_new_user_performance_state_tasks[];
+extern const pem_event_action initialize_thermal_controller_tasks[];
+extern const pem_event_action uninitialize_thermal_controller_tasks[];
+extern const pem_event_action set_cpu_power_state[];
+#endif /* _EVENT_SUB_CHAINS_H_ */
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/powerplay/eventmgr/eventtasks.c
@@ -0,0 +1,438 @@
+/*
+ * Copyright 2015 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#include "eventmgr.h"
+#include "eventinit.h"
+#include "eventmanagement.h"
+#include "eventmanager.h"
+#include "hardwaremanager.h"
+#include "eventtasks.h"
+#include "power_state.h"
+#include "hwmgr.h"
+#include "amd_powerplay.h"
+#include "psm.h"
+
+#define TEMP_RANGE_MIN (90 * 1000)
+#define TEMP_RANGE_MAX (120 * 1000)
+
+int pem_task_update_allowed_performance_levels(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data)
+{
+
+	if (pem_is_hw_access_blocked(eventmgr))
+		return 0;
+
+	phm_force_dpm_levels(eventmgr->hwmgr, AMD_DPM_FORCED_LEVEL_AUTO);
+
+	return 0;
+}
+
+/* eventtasks_generic.c */
+int pem_task_adjust_power_state(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data)
+{
+	struct pp_hwmgr *hwmgr;
+
+	if (pem_is_hw_access_blocked(eventmgr))
+		return 0;
+
+	hwmgr = eventmgr->hwmgr;
+	if (event_data->pnew_power_state != NULL)
+		hwmgr->request_ps = event_data->pnew_power_state;
+
+	if (phm_cap_enabled(eventmgr->platform_descriptor->platformCaps, PHM_PlatformCaps_DynamicPatchPowerState))
+		psm_adjust_power_state_dynamic(eventmgr, event_data->skip_state_adjust_rules);
+	else
+		psm_adjust_power_state_static(eventmgr, event_data->skip_state_adjust_rules);
+
+	return 0;
+}
+
+int pem_task_power_down_asic(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data)
+{
+	return phm_power_down_asic(eventmgr->hwmgr);
+}
+
+int pem_task_set_boot_state(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data)
+{
+	if (pem_is_event_data_valid(event_data->valid_fields, PEM_EventDataValid_RequestedStateID))
+		return psm_set_states(eventmgr, &(event_data->requested_state_id));
+
+	return 0;
+}
+
+int pem_task_reset_boot_state(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data)
+{
+	/* TODO */
+	return 0;
+}
+
+int pem_task_update_new_power_state_clocks(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data)
+{
+	/* TODO */
+	return 0;
+}
+
+int pem_task_system_shutdown(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data)
+{
+	/* TODO */
+	return 0;
+}
+
+int pem_task_register_interrupts(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data)
+{
+	/* TODO */
+	return 0;
+}
+
+int pem_task_unregister_interrupts(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data)
+{
+	return pem_unregister_interrupts(eventmgr);
+}
+
+int pem_task_get_boot_state_id(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data)
+{
+	int result;
+
+	result = psm_get_state_by_classification(eventmgr,
+		PP_StateClassificationFlag_Boot,
+		&(event_data->requested_state_id)
+	);
+
+	if (0 == result)
+		pem_set_event_data_valid(event_data->valid_fields, PEM_EventDataValid_RequestedStateID);
+	else
+		pem_unset_event_data_valid(event_data->valid_fields, PEM_EventDataValid_RequestedStateID);
+
+	return result;
+}
+
+int pem_task_enable_dynamic_state_management(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data)
+{
+	return phm_enable_dynamic_state_management(eventmgr->hwmgr);
+}
+
+int pem_task_disable_dynamic_state_management(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data)
+{
+	/* TODO */
+	return 0;
+}
+
+int pem_task_enable_clock_power_gatings_tasks(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data)
+{
+	return phm_enable_clock_power_gatings(eventmgr->hwmgr);
+}
+
+int pem_task_powerdown_uvd_tasks(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data)
+{
+	return phm_powerdown_uvd(eventmgr->hwmgr);
+}
+
+int pem_task_powerdown_vce_tasks(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data)
+{
+	phm_powergate_uvd(eventmgr->hwmgr, true);
+	phm_powergate_vce(eventmgr->hwmgr, true);
+	return 0;
+}
+
+int pem_task_disable_clock_power_gatings_tasks(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data)
+{
+	/* TODO */
+	return 0;
+}
+
+int pem_task_start_asic_block_usage(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data)
+{
+	/* TODO */
+	return 0;
+}
+
+int pem_task_stop_asic_block_usage(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data)
+{
+	/* TODO */
+	return 0;
+}
+
+int pem_task_setup_asic(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data)
+{
+	return phm_setup_asic(eventmgr->hwmgr);
+}
+
+int pem_task_cleanup_asic(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data)
+{
+	/* TODO */
+	return 0;
+}
+
+int pem_task_store_dal_configuration(struct pp_eventmgr *eventmgr, const struct amd_display_configuration *display_config)
+{
+	/* TODO */
+	return 0;
+	/*phm_store_dal_configuration_data(eventmgr->hwmgr, display_config) */
+}
+
+int pem_task_notify_hw_mgr_display_configuration_change(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data)
+{
+	if (pem_is_hw_access_blocked(eventmgr))
+		return 0;
+
+	return phm_display_configuration_changed(eventmgr->hwmgr);
+}
+
+int pem_task_notify_hw_mgr_pre_display_configuration_change(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data)
+{
+	return 0;
+}
+
+int pem_task_notify_smc_display_config_after_power_state_adjustment(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data)
+{
+	if (pem_is_hw_access_blocked(eventmgr))
+		return 0;
+
+	return phm_notify_smc_display_config_after_ps_adjustment(eventmgr->hwmgr);
+}
+
+int pem_task_block_adjust_power_state(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data)
+{
+	eventmgr->block_adjust_power_state = true;
+	/* to do PHM_ResetIPSCounter(pEventMgr->pHwMgr);*/
+	return 0;
+}
+
+int pem_task_unblock_adjust_power_state(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data)
+{
+	eventmgr->block_adjust_power_state = false;
+	return 0;
+}
+
+int pem_task_notify_power_state_change(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data)
+{
+	/* TODO */
+	return 0;
+}
+
+int pem_task_block_hw_access(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data)
+{
+	/* TODO */
+	return 0;
+}
+
+int pem_task_un_block_hw_access(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data)
+{
+	/* TODO */
+	return 0;
+}
+
+int pem_task_reset_display_phys_access(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data)
+{
+	/* TODO */
+	return 0;
+}
+
+int pem_task_set_cpu_power_state(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data)
+{
+	return phm_set_cpu_power_state(eventmgr->hwmgr);
+}
+
+/*powersaving*/
+
+int pem_task_set_power_source(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data)
+{
+	/* TODO */
+	return 0;
+}
+
+int pem_task_notify_hw_of_power_source(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data)
+{
+	/* TODO */
+	return 0;
+}
+
+int pem_task_get_power_saving_state(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data)
+{
+	/* TODO */
+	return 0;
+}
+
+int pem_task_reset_power_saving_state(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data)
+{
+	/* TODO */
+	return 0;
+}
+
+int pem_task_set_power_saving_state(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data)
+{
+	/* TODO */
+	return 0;
+}
+
+int pem_task_set_screen_state_on(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data)
+{
+	/* TODO */
+	return 0;
+}
+
+int pem_task_set_screen_state_off(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data)
+{
+	/* TODO */
+	return 0;
+}
+
+int pem_task_enable_voltage_island_power_gating(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data)
+{
+	/* TODO */
+	return 0;
+}
+
+int pem_task_disable_voltage_island_power_gating(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data)
+{
+	/* TODO */
+	return 0;
+}
+
+int pem_task_enable_cgpg(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data)
+{
+	/* TODO */
+	return 0;
+}
+
+int pem_task_disable_cgpg(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data)
+{
+	/* TODO */
+	return 0;
+}
+
+int pem_task_enable_clock_power_gating(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data)
+{
+	/* TODO */
+	return 0;
+}
+
+
+int pem_task_enable_gfx_clock_gating(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data)
+{
+	/* TODO */
+	return 0;
+}
+
+int pem_task_disable_gfx_clock_gating(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data)
+{
+	/* TODO */
+	return 0;
+}
+
+
+/* performance */
+int pem_task_set_performance_state(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data)
+{
+	if (pem_is_event_data_valid(event_data->valid_fields, PEM_EventDataValid_RequestedStateID))
+		return psm_set_states(eventmgr, &(event_data->requested_state_id));
+
+	return 0;
+}
+
+int pem_task_conditionally_force_3d_performance_state(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data)
+{
+	/* TODO */
+	return 0;
+}
+
+int pem_task_enable_stutter_mode(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data)
+{
+	/* TODO */
+	return 0;
+}
+
+int pem_task_get_2D_performance_state_id(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data)
+{
+	int result;
+
+	if (eventmgr->features[PP_Feature_PowerPlay].supported &&
+		!(eventmgr->features[PP_Feature_PowerPlay].enabled))
+			result = psm_get_state_by_classification(eventmgr,
+					PP_StateClassificationFlag_Boot,
+					&(event_data->requested_state_id));
+	else if (eventmgr->features[PP_Feature_User2DPerformance].enabled)
+			result = psm_get_state_by_classification(eventmgr,
+				   PP_StateClassificationFlag_User2DPerformance,
+					&(event_data->requested_state_id));
+	else
+		result = psm_get_ui_state(eventmgr, PP_StateUILabel_Performance,
+					&(event_data->requested_state_id));
+
+	if (0 == result)
+		pem_set_event_data_valid(event_data->valid_fields, PEM_EventDataValid_RequestedStateID);
+	else
+		pem_unset_event_data_valid(event_data->valid_fields, PEM_EventDataValid_RequestedStateID);
+
+	return result;
+}
+
+int pem_task_create_user_performance_state(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data)
+{
+	struct pp_power_state *state;
+	int table_entries;
+	struct pp_hwmgr *hwmgr = eventmgr->hwmgr;
+	int i;
+
+	table_entries = hwmgr->num_ps;
+	state = hwmgr->ps;
+
+restart_search:
+	for (i = 0; i < table_entries; i++) {
+		if (state->classification.ui_label & event_data->requested_ui_label) {
+			event_data->pnew_power_state = state;
+			return 0;
+		}
+		state = (struct pp_power_state *)((unsigned long)state + hwmgr->ps_size);
+	}
+
+	switch (event_data->requested_ui_label) {
+	case PP_StateUILabel_Battery:
+	case PP_StateUILabel_Balanced:
+		event_data->requested_ui_label = PP_StateUILabel_Performance;
+		goto restart_search;
+	default:
+		break;
+	}
+	return -1;
+}
+
+int pem_task_initialize_thermal_controller(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data)
+{
+	struct PP_TemperatureRange range;
+
+	range.max = TEMP_RANGE_MAX;
+	range.min = TEMP_RANGE_MIN;
+
+	if (eventmgr == NULL || eventmgr->platform_descriptor == NULL)
+		return -EINVAL;
+
+	if (phm_cap_enabled(eventmgr->platform_descriptor->platformCaps, PHM_PlatformCaps_ThermalController))
+		return phm_start_thermal_controller(eventmgr->hwmgr, &range);
+
+	return 0;
+}
+
+int pem_task_uninitialize_thermal_controller(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data)
+{
+	return phm_stop_thermal_controller(eventmgr->hwmgr);
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/powerplay/eventmgr/eventtasks.h
@@ -0,0 +1,88 @@
+/*
+ * Copyright 2015 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#ifndef _EVENT_TASKS_H_
+#define _EVENT_TASKS_H_
+#include "eventmgr.h"
+
+struct amd_display_configuration;
+
+/* eventtasks_generic.c */
+int pem_task_adjust_power_state(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data);
+int pem_task_power_down_asic(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data);
+int pem_task_get_boot_state_id(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data);
+int pem_task_set_boot_state(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data);
+int pem_task_reset_boot_state(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data);
+int pem_task_update_new_power_state_clocks(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data);
+int pem_task_system_shutdown(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data);
+int pem_task_register_interrupts(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data);
+int pem_task_unregister_interrupts(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data);
+int pem_task_enable_dynamic_state_management(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data);
+int pem_task_disable_dynamic_state_management(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data);
+int pem_task_enable_clock_power_gatings_tasks(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data);
+int pem_task_powerdown_uvd_tasks(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data);
+int pem_task_powerdown_vce_tasks(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data);
+int pem_task_disable_clock_power_gatings_tasks(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data);
+int pem_task_start_asic_block_usage(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data);
+int pem_task_stop_asic_block_usage(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data);
+int pem_task_setup_asic(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data);
+int pem_task_cleanup_asic(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data);
+int pem_task_store_dal_configuration (struct pp_eventmgr *eventmgr, const struct amd_display_configuration *display_config);
+int pem_task_notify_hw_mgr_display_configuration_change(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data);
+int pem_task_notify_hw_mgr_pre_display_configuration_change(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data);
+int pem_task_block_adjust_power_state(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data);
+int pem_task_unblock_adjust_power_state(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data);
+int pem_task_notify_power_state_change(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data);
+int pem_task_block_hw_access(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data);
+int pem_task_un_block_hw_access(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data);
+int pem_task_reset_display_phys_access(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data);
+int pem_task_set_cpu_power_state(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data);
+int pem_task_notify_smc_display_config_after_power_state_adjustment(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data);
+/*powersaving*/
+
+int pem_task_set_power_source(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data);
+int pem_task_notify_hw_of_power_source(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data);
+int pem_task_get_power_saving_state(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data);
+int pem_task_reset_power_saving_state(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data);
+int pem_task_set_power_saving_state(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data);
+int pem_task_set_screen_state_on(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data);
+int pem_task_set_screen_state_off(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data);
+int pem_task_enable_voltage_island_power_gating(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data);
+int pem_task_disable_voltage_island_power_gating(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data);
+int pem_task_enable_cgpg(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data);
+int pem_task_disable_cgpg(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data);
+int pem_task_enable_gfx_clock_gating(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data);
+int pem_task_disable_gfx_clock_gating(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data);
+int pem_task_enable_stutter_mode(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data);
+
+/* performance */
+int pem_task_set_performance_state(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data);
+int pem_task_conditionally_force_3d_performance_state(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data);
+int pem_task_get_2D_performance_state_id(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data);
+int pem_task_create_user_performance_state(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data);
+int pem_task_update_allowed_performance_levels(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data);
+/*thermal */
+int pem_task_initialize_thermal_controller(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data);
+int pem_task_uninitialize_thermal_controller(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data);
+
+#endif /* _EVENT_TASKS_H_ */
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/powerplay/eventmgr/psm.c
@@ -0,0 +1,117 @@
+/*
+ * Copyright 2015 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+#include "psm.h"
+
+int psm_get_ui_state(struct pp_eventmgr *eventmgr, enum PP_StateUILabel ui_label, unsigned long *state_id)
+{
+	struct pp_power_state *state;
+	int table_entries;
+	struct pp_hwmgr *hwmgr = eventmgr->hwmgr;
+	int i;
+
+	table_entries = hwmgr->num_ps;
+	state = hwmgr->ps;
+
+	for (i = 0; i < table_entries; i++) {
+		if (state->classification.ui_label & ui_label) {
+			*state_id = state->id;
+			return 0;
+		}
+		state = (struct pp_power_state *)((unsigned long)state + hwmgr->ps_size);
+	}
+	return -1;
+}
+
+int psm_get_state_by_classification(struct pp_eventmgr *eventmgr, enum PP_StateClassificationFlag flag, unsigned long *state_id)
+{
+	struct pp_power_state *state;
+	int table_entries;
+	struct pp_hwmgr *hwmgr = eventmgr->hwmgr;
+	int i;
+
+	table_entries = hwmgr->num_ps;
+	state = hwmgr->ps;
+
+	for (i = 0; i < table_entries; i++) {
+		if (state->classification.flags & flag) {
+			*state_id = state->id;
+			return 0;
+		}
+		state = (struct pp_power_state *)((unsigned long)state + hwmgr->ps_size);
+	}
+	return -1;
+}
+
+int psm_set_states(struct pp_eventmgr *eventmgr, unsigned long *state_id)
+{
+	struct pp_power_state *state;
+	int table_entries;
+	struct pp_hwmgr *hwmgr = eventmgr->hwmgr;
+	int i;
+
+	table_entries = hwmgr->num_ps;
+	state = hwmgr->ps;
+
+	for (i = 0; i < table_entries; i++) {
+		if (state->id == *state_id) {
+			hwmgr->request_ps = state;
+			return 0;
+		}
+		state = (struct pp_power_state *)((unsigned long)state + hwmgr->ps_size);
+	}
+	return -1;
+}
+
+int psm_adjust_power_state_dynamic(struct pp_eventmgr *eventmgr, bool skip)
+{
+
+	struct pp_power_state *pcurrent;
+	struct pp_power_state *requested;
+	struct pp_hwmgr *hwmgr;
+	bool equal;
+
+	if (skip)
+		return 0;
+
+	hwmgr = eventmgr->hwmgr;
+	pcurrent = hwmgr->current_ps;
+	requested = hwmgr->request_ps;
+
+	if (requested == NULL)
+		return 0;
+
+	if (pcurrent == NULL || (0 != phm_check_states_equal(hwmgr, &pcurrent->hardware, &requested->hardware, &equal)))
+		equal = false;
+
+	if (!equal || phm_check_smc_update_required_for_display_configuration(hwmgr)) {
+		phm_apply_state_adjust_rules(hwmgr, requested, pcurrent);
+		phm_set_power_state(hwmgr, &pcurrent->hardware, &requested->hardware);
+		hwmgr->current_ps = requested;
+	}
+	return 0;
+}
+
+int psm_adjust_power_state_static(struct pp_eventmgr *eventmgr, bool skip)
+{
+	return 0;
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/powerplay/eventmgr/psm.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2015 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+#include "eventmgr.h"
+#include "eventinit.h"
+#include "eventmanagement.h"
+#include "eventmanager.h"
+#include "power_state.h"
+#include "hardwaremanager.h"
+
+int psm_get_ui_state(struct pp_eventmgr *eventmgr, enum PP_StateUILabel ui_label, unsigned long *state_id);
+
+int psm_get_state_by_classification(struct pp_eventmgr *eventmgr, enum PP_StateClassificationFlag flag, unsigned long *state_id);
+
+int psm_set_states(struct pp_eventmgr *eventmgr, unsigned long *state_id);
+
+int psm_adjust_power_state_dynamic(struct pp_eventmgr *eventmgr, bool skip);
+
+int psm_adjust_power_state_static(struct pp_eventmgr *eventmgr, bool skip);
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/powerplay/hwmgr/Makefile
@@ -0,0 +1,15 @@
+#
+# Makefile for the 'hw manager' sub-component of powerplay.
+# It provides the hardware management services for the driver.
+
+HARDWARE_MGR = hwmgr.o processpptables.o functiontables.o \
+	       hardwaremanager.o pp_acpi.o cz_hwmgr.o \
+               cz_clockpowergating.o \
+	       tonga_processpptables.o ppatomctrl.o \
+               tonga_hwmgr.o pppcielanes.o  tonga_thermal.o\
+               fiji_powertune.o fiji_hwmgr.o tonga_clockpowergating.o \
+               fiji_clockpowergating.o fiji_thermal.o
+
+AMD_PP_HWMGR = $(addprefix $(AMD_PP_PATH)/hwmgr/,$(HARDWARE_MGR))
+
+AMD_POWERPLAY_FILES += $(AMD_PP_HWMGR)
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/powerplay/hwmgr/cz_clockpowergating.c
@@ -0,0 +1,252 @@
+/*
+ * Copyright 2015 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#include "hwmgr.h"
+#include "cz_clockpowergating.h"
+#include "cz_ppsmc.h"
+
+/* PhyID -> Status Mapping in DDI_PHY_GEN_STATUS
+    0    GFX0L (3:0),                  (27:24),
+    1    GFX0H (7:4),                  (31:28),
+    2    GFX1L (3:0),                  (19:16),
+    3    GFX1H (7:4),                  (23:20),
+    4    DDIL   (3:0),                   (11: 8),
+    5    DDIH  (7:4),                   (15:12),
+    6    DDI2L (3:0),                   ( 3: 0),
+    7    DDI2H (7:4),                   ( 7: 4),
+*/
+#define DDI_PHY_GEN_STATUS_VAL(phyID)   (1 << ((3 - ((phyID & 0x07)/2))*8 + (phyID & 0x01)*4))
+#define IS_PHY_ID_USED_BY_PLL(PhyID)    (((0xF3 & (1 << PhyID)) & 0xFF) ? true : false)
+
+
+int cz_phm_set_asic_block_gating(struct pp_hwmgr *hwmgr, enum PHM_AsicBlock block, enum PHM_ClockGateSetting gating)
+{
+	int ret = 0;
+
+	switch (block) {
+	case PHM_AsicBlock_UVD_MVC:
+	case PHM_AsicBlock_UVD:
+	case PHM_AsicBlock_UVD_HD:
+	case PHM_AsicBlock_UVD_SD:
+		if (gating == PHM_ClockGateSetting_StaticOff)
+			ret = cz_dpm_powerdown_uvd(hwmgr);
+		else
+			ret = cz_dpm_powerup_uvd(hwmgr);
+		break;
+	case PHM_AsicBlock_GFX:
+	default:
+		break;
+	}
+
+	return ret;
+}
+
+
+bool cz_phm_is_safe_for_asic_block(struct pp_hwmgr *hwmgr, const struct pp_hw_power_state *state, enum PHM_AsicBlock block)
+{
+	return true;
+}
+
+
+int cz_phm_enable_disable_gfx_power_gating(struct pp_hwmgr *hwmgr, bool enable)
+{
+	return 0;
+}
+
+int cz_phm_smu_power_up_down_pcie(struct pp_hwmgr *hwmgr, uint32_t target, bool up, uint32_t args)
+{
+	/* TODO */
+	return 0;
+}
+
+int cz_phm_initialize_display_phy_access(struct pp_hwmgr *hwmgr, bool initialize, bool accesshw)
+{
+	/* TODO */
+	return 0;
+}
+
+int cz_phm_get_display_phy_access_info(struct pp_hwmgr *hwmgr)
+{
+	/* TODO */
+	return 0;
+}
+
+int cz_phm_gate_unused_display_phys(struct pp_hwmgr *hwmgr)
+{
+	/* TODO */
+	return 0;
+}
+
+int cz_phm_ungate_all_display_phys(struct pp_hwmgr *hwmgr)
+{
+	/* TODO */
+	return 0;
+}
+
+static int cz_tf_uvd_power_gating_initialize(struct pp_hwmgr *hwmgr, void *pInput, void *pOutput, void *pStorage, int Result)
+{
+	return 0;
+}
+
+static int cz_tf_vce_power_gating_initialize(struct pp_hwmgr *hwmgr, void *pInput, void *pOutput, void *pStorage, int Result)
+{
+	return 0;
+}
+
+int cz_enable_disable_uvd_dpm(struct pp_hwmgr *hwmgr, bool enable)
+{
+	struct cz_hwmgr *cz_hwmgr = (struct cz_hwmgr *)(hwmgr->backend);
+	uint32_t dpm_features = 0;
+
+	if (enable &&
+		phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
+				  PHM_PlatformCaps_UVDDPM)) {
+		cz_hwmgr->dpm_flags |= DPMFlags_UVD_Enabled;
+		dpm_features |= UVD_DPM_MASK;
+		smum_send_msg_to_smc_with_parameter(hwmgr->smumgr,
+			    PPSMC_MSG_EnableAllSmuFeatures, dpm_features);
+	} else {
+		dpm_features |= UVD_DPM_MASK;
+		cz_hwmgr->dpm_flags &= ~DPMFlags_UVD_Enabled;
+		smum_send_msg_to_smc_with_parameter(hwmgr->smumgr,
+			   PPSMC_MSG_DisableAllSmuFeatures, dpm_features);
+	}
+	return 0;
+}
+
+int cz_enable_disable_vce_dpm(struct pp_hwmgr *hwmgr, bool enable)
+{
+	struct cz_hwmgr *cz_hwmgr = (struct cz_hwmgr *)(hwmgr->backend);
+	uint32_t dpm_features = 0;
+
+	if (enable && phm_cap_enabled(
+				hwmgr->platform_descriptor.platformCaps,
+				PHM_PlatformCaps_VCEDPM)) {
+		cz_hwmgr->dpm_flags |= DPMFlags_VCE_Enabled;
+		dpm_features |= VCE_DPM_MASK;
+		smum_send_msg_to_smc_with_parameter(hwmgr->smumgr,
+			    PPSMC_MSG_EnableAllSmuFeatures, dpm_features);
+	} else {
+		dpm_features |= VCE_DPM_MASK;
+		cz_hwmgr->dpm_flags &= ~DPMFlags_VCE_Enabled;
+		smum_send_msg_to_smc_with_parameter(hwmgr->smumgr,
+			   PPSMC_MSG_DisableAllSmuFeatures, dpm_features);
+	}
+
+	return 0;
+}
+
+
+int cz_dpm_powergate_uvd(struct pp_hwmgr *hwmgr, bool bgate)
+{
+	struct cz_hwmgr *cz_hwmgr = (struct cz_hwmgr *)(hwmgr->backend);
+
+	if (cz_hwmgr->uvd_power_gated == bgate)
+		return 0;
+
+	cz_hwmgr->uvd_power_gated = bgate;
+
+	if (bgate) {
+		cgs_set_clockgating_state(hwmgr->device,
+						AMD_IP_BLOCK_TYPE_UVD,
+						AMD_CG_STATE_UNGATE);
+		cgs_set_powergating_state(hwmgr->device,
+						AMD_IP_BLOCK_TYPE_UVD,
+						AMD_PG_STATE_GATE);
+		cz_dpm_update_uvd_dpm(hwmgr, true);
+		cz_dpm_powerdown_uvd(hwmgr);
+	} else {
+		cz_dpm_powerup_uvd(hwmgr);
+		cgs_set_clockgating_state(hwmgr->device,
+						AMD_IP_BLOCK_TYPE_UVD,
+						AMD_PG_STATE_GATE);
+		cgs_set_powergating_state(hwmgr->device,
+						AMD_IP_BLOCK_TYPE_UVD,
+						AMD_CG_STATE_UNGATE);
+		cz_dpm_update_uvd_dpm(hwmgr, false);
+	}
+
+	return 0;
+}
+
+int cz_dpm_powergate_vce(struct pp_hwmgr *hwmgr, bool bgate)
+{
+	struct cz_hwmgr *cz_hwmgr = (struct cz_hwmgr *)(hwmgr->backend);
+
+	if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
+					PHM_PlatformCaps_VCEPowerGating)) {
+		if (cz_hwmgr->vce_power_gated != bgate) {
+			if (bgate) {
+				cgs_set_clockgating_state(
+							hwmgr->device,
+							AMD_IP_BLOCK_TYPE_VCE,
+							AMD_CG_STATE_UNGATE);
+				cgs_set_powergating_state(
+							hwmgr->device,
+							AMD_IP_BLOCK_TYPE_VCE,
+							AMD_PG_STATE_GATE);
+				cz_enable_disable_vce_dpm(hwmgr, false);
+			/* TODO: to figure out why vce can't be poweroff*/
+				cz_hwmgr->vce_power_gated = true;
+			} else {
+				cz_dpm_powerup_vce(hwmgr);
+				cz_hwmgr->vce_power_gated = false;
+				cgs_set_clockgating_state(
+							hwmgr->device,
+							AMD_IP_BLOCK_TYPE_VCE,
+							AMD_PG_STATE_GATE);
+				cgs_set_powergating_state(
+							hwmgr->device,
+							AMD_IP_BLOCK_TYPE_VCE,
+							AMD_CG_STATE_UNGATE);
+				cz_dpm_update_vce_dpm(hwmgr);
+				cz_enable_disable_vce_dpm(hwmgr, true);
+				return 0;
+			}
+		}
+	} else {
+		cz_dpm_update_vce_dpm(hwmgr);
+		cz_enable_disable_vce_dpm(hwmgr, true);
+		return 0;
+	}
+
+	if (!cz_hwmgr->vce_power_gated)
+		cz_dpm_update_vce_dpm(hwmgr);
+
+	return 0;
+}
+
+
+static struct phm_master_table_item cz_enable_clock_power_gatings_list[] = {
+	/*we don't need an exit table here, because there is only D3 cold on Kv*/
+	{ phm_cf_want_uvd_power_gating, cz_tf_uvd_power_gating_initialize },
+	{ phm_cf_want_vce_power_gating, cz_tf_vce_power_gating_initialize },
+	/* to do { NULL, cz_tf_xdma_power_gating_enable }, */
+	{ NULL, NULL }
+};
+
+struct phm_master_table_header cz_phm_enable_clock_power_gatings_master = {
+	0,
+	PHM_MasterTableFlag_None,
+	cz_enable_clock_power_gatings_list
+};
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/powerplay/hwmgr/cz_clockpowergating.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2015 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#ifndef _CZ_CLOCK_POWER_GATING_H_
+#define _CZ_CLOCK_POWER_GATING_H_
+
+#include "cz_hwmgr.h"
+#include "pp_asicblocks.h"
+
+extern int cz_phm_set_asic_block_gating(struct pp_hwmgr *hwmgr, enum PHM_AsicBlock block, enum PHM_ClockGateSetting gating);
+extern struct phm_master_table_header cz_phm_enable_clock_power_gatings_master;
+extern struct phm_master_table_header cz_phm_disable_clock_power_gatings_master;
+extern int cz_dpm_powergate_vce(struct pp_hwmgr *hwmgr, bool bgate);
+extern int cz_dpm_powergate_uvd(struct pp_hwmgr *hwmgr, bool bgate);
+extern int cz_enable_disable_vce_dpm(struct pp_hwmgr *hwmgr, bool enable);
+extern int cz_enable_disable_uvd_dpm(struct pp_hwmgr *hwmgr, bool enable);
+#endif /* _CZ_CLOCK_POWER_GATING_H_ */
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/powerplay/hwmgr/cz_hwmgr.c
@@ -0,0 +1,1760 @@
+/*
+ * Copyright 2015 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include "atom-types.h"
+#include "atombios.h"
+#include "processpptables.h"
+#include "pp_debug.h"
+#include "cgs_common.h"
+#include "smu/smu_8_0_d.h"
+#include "smu8_fusion.h"
+#include "smu/smu_8_0_sh_mask.h"
+#include "smumgr.h"
+#include "hwmgr.h"
+#include "hardwaremanager.h"
+#include "cz_ppsmc.h"
+#include "cz_hwmgr.h"
+#include "power_state.h"
+#include "cz_clockpowergating.h"
+#include "pp_debug.h"
+
+#define ixSMUSVI_NB_CURRENTVID 0xD8230044
+#define CURRENT_NB_VID_MASK 0xff000000
+#define CURRENT_NB_VID__SHIFT 24
+#define ixSMUSVI_GFX_CURRENTVID  0xD8230048
+#define CURRENT_GFX_VID_MASK 0xff000000
+#define CURRENT_GFX_VID__SHIFT 24
+
+static const unsigned long PhwCz_Magic = (unsigned long) PHM_Cz_Magic;
+
+static struct cz_power_state *cast_PhwCzPowerState(struct pp_hw_power_state *hw_ps)
+{
+	if (PhwCz_Magic != hw_ps->magic)
+		return NULL;
+
+	return (struct cz_power_state *)hw_ps;
+}
+
+static const struct cz_power_state *cast_const_PhwCzPowerState(
+				const struct pp_hw_power_state *hw_ps)
+{
+	if (PhwCz_Magic != hw_ps->magic)
+		return NULL;
+
+	return (struct cz_power_state *)hw_ps;
+}
+
+uint32_t cz_get_eclk_level(struct pp_hwmgr *hwmgr,
+					uint32_t clock, uint32_t msg)
+{
+	int i = 0;
+	struct phm_vce_clock_voltage_dependency_table *ptable =
+		hwmgr->dyn_state.vce_clock_voltage_dependency_table;
+
+	switch (msg) {
+	case PPSMC_MSG_SetEclkSoftMin:
+	case PPSMC_MSG_SetEclkHardMin:
+		for (i = 0; i < (int)ptable->count; i++) {
+			if (clock <= ptable->entries[i].ecclk)
+				break;
+		}
+		break;
+
+	case PPSMC_MSG_SetEclkSoftMax:
+	case PPSMC_MSG_SetEclkHardMax:
+		for (i = ptable->count - 1; i >= 0; i--) {
+			if (clock >= ptable->entries[i].ecclk)
+				break;
+		}
+		break;
+
+	default:
+		break;
+	}
+
+	return i;
+}
+
+static uint32_t cz_get_sclk_level(struct pp_hwmgr *hwmgr,
+				uint32_t clock, uint32_t msg)
+{
+	int i = 0;
+	struct phm_clock_voltage_dependency_table *table =
+				hwmgr->dyn_state.vddc_dependency_on_sclk;
+
+	switch (msg) {
+	case PPSMC_MSG_SetSclkSoftMin:
+	case PPSMC_MSG_SetSclkHardMin:
+		for (i = 0; i < (int)table->count; i++) {
+			if (clock <= table->entries[i].clk)
+				break;
+		}
+		break;
+
+	case PPSMC_MSG_SetSclkSoftMax:
+	case PPSMC_MSG_SetSclkHardMax:
+		for (i = table->count - 1; i >= 0; i--) {
+			if (clock >= table->entries[i].clk)
+				break;
+		}
+		break;
+
+	default:
+		break;
+	}
+	return i;
+}
+
+static uint32_t cz_get_uvd_level(struct pp_hwmgr *hwmgr,
+					uint32_t clock, uint32_t msg)
+{
+	int i = 0;
+	struct phm_uvd_clock_voltage_dependency_table *ptable =
+		hwmgr->dyn_state.uvd_clock_voltage_dependency_table;
+
+	switch (msg) {
+	case PPSMC_MSG_SetUvdSoftMin:
+	case PPSMC_MSG_SetUvdHardMin:
+		for (i = 0; i < (int)ptable->count; i++) {
+			if (clock <= ptable->entries[i].vclk)
+				break;
+		}
+		break;
+
+	case PPSMC_MSG_SetUvdSoftMax:
+	case PPSMC_MSG_SetUvdHardMax:
+		for (i = ptable->count - 1; i >= 0; i--) {
+			if (clock >= ptable->entries[i].vclk)
+				break;
+		}
+		break;
+
+	default:
+		break;
+	}
+
+	return i;
+}
+
+static uint32_t cz_get_max_sclk_level(struct pp_hwmgr *hwmgr)
+{
+	struct cz_hwmgr *cz_hwmgr = (struct cz_hwmgr *)(hwmgr->backend);
+
+	if (cz_hwmgr->max_sclk_level == 0) {
+		smum_send_msg_to_smc(hwmgr->smumgr, PPSMC_MSG_GetMaxSclkLevel);
+		cz_hwmgr->max_sclk_level = smum_get_argument(hwmgr->smumgr) + 1;
+	}
+
+	return cz_hwmgr->max_sclk_level;
+}
+
+static int cz_initialize_dpm_defaults(struct pp_hwmgr *hwmgr)
+{
+	struct cz_hwmgr *cz_hwmgr = (struct cz_hwmgr *)(hwmgr->backend);
+	uint32_t i;
+	struct cgs_system_info sys_info = {0};
+	int result;
+
+	cz_hwmgr->gfx_ramp_step = 256*25/100;
+
+	cz_hwmgr->gfx_ramp_delay = 1; /* by default, we delay 1us */
+
+	for (i = 0; i < CZ_MAX_HARDWARE_POWERLEVELS; i++)
+		cz_hwmgr->activity_target[i] = CZ_AT_DFLT;
+
+	cz_hwmgr->mgcg_cgtt_local0 = 0x00000000;
+	cz_hwmgr->mgcg_cgtt_local1 = 0x00000000;
+
+	cz_hwmgr->clock_slow_down_freq = 25000;
+
+	cz_hwmgr->skip_clock_slow_down = 1;
+
+	cz_hwmgr->enable_nb_ps_policy = 1; /* disable until UNB is ready, Enabled */
+
+	cz_hwmgr->voltage_drop_in_dce_power_gating = 0; /* disable until fully verified */
+
+	cz_hwmgr->voting_rights_clients = 0x00C00033;
+
+	cz_hwmgr->static_screen_threshold = 8;
+
+	cz_hwmgr->ddi_power_gating_disabled = 0;
+
+	cz_hwmgr->bapm_enabled = 1;
+
+	cz_hwmgr->voltage_drop_threshold = 0;
+
+	cz_hwmgr->gfx_power_gating_threshold = 500;
+
+	cz_hwmgr->vce_slow_sclk_threshold = 20000;
+
+	cz_hwmgr->dce_slow_sclk_threshold = 30000;
+
+	cz_hwmgr->disable_driver_thermal_policy = 1;
+
+	cz_hwmgr->disable_nb_ps3_in_battery = 0;
+
+	phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
+							PHM_PlatformCaps_ABM);
+
+	phm_cap_set(hwmgr->platform_descriptor.platformCaps,
+				    PHM_PlatformCaps_NonABMSupportInPPLib);
+
+	phm_cap_set(hwmgr->platform_descriptor.platformCaps,
+					   PHM_PlatformCaps_SclkDeepSleep);
+
+	phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
+					PHM_PlatformCaps_DynamicM3Arbiter);
+
+	cz_hwmgr->override_dynamic_mgpg = 1;
+
+	phm_cap_set(hwmgr->platform_descriptor.platformCaps,
+				  PHM_PlatformCaps_DynamicPatchPowerState);
+
+	cz_hwmgr->thermal_auto_throttling_treshold = 0;
+
+	cz_hwmgr->tdr_clock = 0;
+
+	cz_hwmgr->disable_gfx_power_gating_in_uvd = 0;
+
+	phm_cap_set(hwmgr->platform_descriptor.platformCaps,
+					PHM_PlatformCaps_DynamicUVDState);
+
+	phm_cap_set(hwmgr->platform_descriptor.platformCaps,
+			PHM_PlatformCaps_UVDDPM);
+	phm_cap_set(hwmgr->platform_descriptor.platformCaps,
+			PHM_PlatformCaps_VCEDPM);
+
+	cz_hwmgr->cc6_settings.cpu_cc6_disable = false;
+	cz_hwmgr->cc6_settings.cpu_pstate_disable = false;
+	cz_hwmgr->cc6_settings.nb_pstate_switch_disable = false;
+	cz_hwmgr->cc6_settings.cpu_pstate_separation_time = 0;
+
+	phm_cap_set(hwmgr->platform_descriptor.platformCaps,
+				   PHM_PlatformCaps_DisableVoltageIsland);
+
+	phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
+		      PHM_PlatformCaps_UVDPowerGating);
+	phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
+		      PHM_PlatformCaps_VCEPowerGating);
+	sys_info.size = sizeof(struct cgs_system_info);
+	sys_info.info_id = CGS_SYSTEM_INFO_PG_FLAGS;
+	result = cgs_query_system_info(hwmgr->device, &sys_info);
+	if (!result) {
+		if (sys_info.value & AMD_PG_SUPPORT_UVD)
+			phm_cap_set(hwmgr->platform_descriptor.platformCaps,
+				      PHM_PlatformCaps_UVDPowerGating);
+		if (sys_info.value & AMD_PG_SUPPORT_VCE)
+			phm_cap_set(hwmgr->platform_descriptor.platformCaps,
+				      PHM_PlatformCaps_VCEPowerGating);
+	}
+
+	return 0;
+}
+
+static uint32_t cz_convert_8Bit_index_to_voltage(
+			struct pp_hwmgr *hwmgr, uint16_t voltage)
+{
+	return 6200 - (voltage * 25);
+}
+
+static int cz_construct_max_power_limits_table(struct pp_hwmgr *hwmgr,
+			struct phm_clock_and_voltage_limits *table)
+{
+	struct cz_hwmgr *cz_hwmgr = (struct cz_hwmgr *)hwmgr->backend;
+	struct cz_sys_info *sys_info = &cz_hwmgr->sys_info;
+	struct phm_clock_voltage_dependency_table *dep_table =
+				hwmgr->dyn_state.vddc_dependency_on_sclk;
+
+	if (dep_table->count > 0) {
+		table->sclk = dep_table->entries[dep_table->count-1].clk;
+		table->vddc = cz_convert_8Bit_index_to_voltage(hwmgr,
+		   (uint16_t)dep_table->entries[dep_table->count-1].v);
+	}
+	table->mclk = sys_info->nbp_memory_clock[0];
+	return 0;
+}
+
+static int cz_init_dynamic_state_adjustment_rule_settings(
+			struct pp_hwmgr *hwmgr,
+			ATOM_CLK_VOLT_CAPABILITY *disp_voltage_table)
+{
+	uint32_t table_size =
+		sizeof(struct phm_clock_voltage_dependency_table) +
+		(7 * sizeof(struct phm_clock_voltage_dependency_record));
+
+	struct phm_clock_voltage_dependency_table *table_clk_vlt =
+					kzalloc(table_size, GFP_KERNEL);
+
+	if (NULL == table_clk_vlt) {
+		printk(KERN_ERR "[ powerplay ] Can not allocate memory!\n");
+		return -ENOMEM;
+	}
+
+	table_clk_vlt->count = 8;
+	table_clk_vlt->entries[0].clk = PP_DAL_POWERLEVEL_0;
+	table_clk_vlt->entries[0].v = 0;
+	table_clk_vlt->entries[1].clk = PP_DAL_POWERLEVEL_1;
+	table_clk_vlt->entries[1].v = 1;
+	table_clk_vlt->entries[2].clk = PP_DAL_POWERLEVEL_2;
+	table_clk_vlt->entries[2].v = 2;
+	table_clk_vlt->entries[3].clk = PP_DAL_POWERLEVEL_3;
+	table_clk_vlt->entries[3].v = 3;
+	table_clk_vlt->entries[4].clk = PP_DAL_POWERLEVEL_4;
+	table_clk_vlt->entries[4].v = 4;
+	table_clk_vlt->entries[5].clk = PP_DAL_POWERLEVEL_5;
+	table_clk_vlt->entries[5].v = 5;
+	table_clk_vlt->entries[6].clk = PP_DAL_POWERLEVEL_6;
+	table_clk_vlt->entries[6].v = 6;
+	table_clk_vlt->entries[7].clk = PP_DAL_POWERLEVEL_7;
+	table_clk_vlt->entries[7].v = 7;
+	hwmgr->dyn_state.vddc_dep_on_dal_pwrl = table_clk_vlt;
+
+	return 0;
+}
+
+static int cz_get_system_info_data(struct pp_hwmgr *hwmgr)
+{
+	struct cz_hwmgr *cz_hwmgr = (struct cz_hwmgr *)hwmgr->backend;
+	ATOM_INTEGRATED_SYSTEM_INFO_V1_9 *info = NULL;
+	uint32_t i;
+	int result = 0;
+	uint8_t frev, crev;
+	uint16_t size;
+
+	info = (ATOM_INTEGRATED_SYSTEM_INFO_V1_9 *) cgs_atom_get_data_table(
+			hwmgr->device,
+			GetIndexIntoMasterTable(DATA, IntegratedSystemInfo),
+			&size, &frev, &crev);
+
+	if (crev != 9) {
+		printk(KERN_ERR "[ powerplay ] Unsupported IGP table: %d %d\n", frev, crev);
+		return -EINVAL;
+	}
+
+	if (info == NULL) {
+		printk(KERN_ERR "[ powerplay ] Could not retrieve the Integrated System Info Table!\n");
+		return -EINVAL;
+	}
+
+	cz_hwmgr->sys_info.bootup_uma_clock =
+				   le32_to_cpu(info->ulBootUpUMAClock);
+
+	cz_hwmgr->sys_info.bootup_engine_clock =
+				le32_to_cpu(info->ulBootUpEngineClock);
+
+	cz_hwmgr->sys_info.dentist_vco_freq =
+				   le32_to_cpu(info->ulDentistVCOFreq);
+
+	cz_hwmgr->sys_info.system_config =
+				     le32_to_cpu(info->ulSystemConfig);
+
+	cz_hwmgr->sys_info.bootup_nb_voltage_index =
+				  le16_to_cpu(info->usBootUpNBVoltage);
+
+	cz_hwmgr->sys_info.htc_hyst_lmt =
+			(info->ucHtcHystLmt == 0) ? 5 : info->ucHtcHystLmt;
+
+	cz_hwmgr->sys_info.htc_tmp_lmt =
+			(info->ucHtcTmpLmt == 0) ? 203 : info->ucHtcTmpLmt;
+
+	if (cz_hwmgr->sys_info.htc_tmp_lmt <=
+			cz_hwmgr->sys_info.htc_hyst_lmt) {
+		printk(KERN_ERR "[ powerplay ] The htcTmpLmt should be larger than htcHystLmt.\n");
+		return -EINVAL;
+	}
+
+	cz_hwmgr->sys_info.nb_dpm_enable =
+				cz_hwmgr->enable_nb_ps_policy &&
+				(le32_to_cpu(info->ulSystemConfig) >> 3 & 0x1);
+
+	for (i = 0; i < CZ_NUM_NBPSTATES; i++) {
+		if (i < CZ_NUM_NBPMEMORYCLOCK) {
+			cz_hwmgr->sys_info.nbp_memory_clock[i] =
+			  le32_to_cpu(info->ulNbpStateMemclkFreq[i]);
+		}
+		cz_hwmgr->sys_info.nbp_n_clock[i] =
+			    le32_to_cpu(info->ulNbpStateNClkFreq[i]);
+	}
+
+	for (i = 0; i < MAX_DISPLAY_CLOCK_LEVEL; i++) {
+		cz_hwmgr->sys_info.display_clock[i] =
+					le32_to_cpu(info->sDispClkVoltageMapping[i].ulMaximumSupportedCLK);
+	}
+
+	/* Here use 4 levels, make sure not exceed */
+	for (i = 0; i < CZ_NUM_NBPSTATES; i++) {
+		cz_hwmgr->sys_info.nbp_voltage_index[i] =
+			     le16_to_cpu(info->usNBPStateVoltage[i]);
+	}
+
+	if (!cz_hwmgr->sys_info.nb_dpm_enable) {
+		for (i = 1; i < CZ_NUM_NBPSTATES; i++) {
+			if (i < CZ_NUM_NBPMEMORYCLOCK) {
+				cz_hwmgr->sys_info.nbp_memory_clock[i] =
+				    cz_hwmgr->sys_info.nbp_memory_clock[0];
+			}
+			cz_hwmgr->sys_info.nbp_n_clock[i] =
+				    cz_hwmgr->sys_info.nbp_n_clock[0];
+			cz_hwmgr->sys_info.nbp_voltage_index[i] =
+				    cz_hwmgr->sys_info.nbp_voltage_index[0];
+		}
+	}
+
+	if (le32_to_cpu(info->ulGPUCapInfo) &
+		SYS_INFO_GPUCAPS__ENABEL_DFS_BYPASS) {
+		phm_cap_set(hwmgr->platform_descriptor.platformCaps,
+				    PHM_PlatformCaps_EnableDFSBypass);
+	}
+
+	cz_hwmgr->sys_info.uma_channel_number = info->ucUMAChannelNumber;
+
+	cz_construct_max_power_limits_table (hwmgr,
+				    &hwmgr->dyn_state.max_clock_voltage_on_ac);
+
+	cz_init_dynamic_state_adjustment_rule_settings(hwmgr,
+				    &info->sDISPCLK_Voltage[0]);
+
+	return result;
+}
+
+static int cz_construct_boot_state(struct pp_hwmgr *hwmgr)
+{
+	struct cz_hwmgr *cz_hwmgr = (struct cz_hwmgr *)(hwmgr->backend);
+
+	cz_hwmgr->boot_power_level.engineClock =
+				cz_hwmgr->sys_info.bootup_engine_clock;
+
+	cz_hwmgr->boot_power_level.vddcIndex =
+			(uint8_t)cz_hwmgr->sys_info.bootup_nb_voltage_index;
+
+	cz_hwmgr->boot_power_level.dsDividerIndex = 0;
+
+	cz_hwmgr->boot_power_level.ssDividerIndex = 0;
+
+	cz_hwmgr->boot_power_level.allowGnbSlow = 1;
+
+	cz_hwmgr->boot_power_level.forceNBPstate = 0;
+
+	cz_hwmgr->boot_power_level.hysteresis_up = 0;
+
+	cz_hwmgr->boot_power_level.numSIMDToPowerDown = 0;
+
+	cz_hwmgr->boot_power_level.display_wm = 0;
+
+	cz_hwmgr->boot_power_level.vce_wm = 0;
+
+	return 0;
+}
+
+static int cz_tf_reset_active_process_mask(struct pp_hwmgr *hwmgr, void *input,
+					void *output, void *storage, int result)
+{
+	return 0;
+}
+
+static int cz_tf_upload_pptable_to_smu(struct pp_hwmgr *hwmgr, void *input,
+				       void *output, void *storage, int result)
+{
+	struct SMU8_Fusion_ClkTable *clock_table;
+	int ret;
+	uint32_t i;
+	void *table = NULL;
+	pp_atomctrl_clock_dividers_kong dividers;
+
+	struct phm_clock_voltage_dependency_table *vddc_table =
+		hwmgr->dyn_state.vddc_dependency_on_sclk;
+	struct phm_clock_voltage_dependency_table *vdd_gfx_table =
+		hwmgr->dyn_state.vdd_gfx_dependency_on_sclk;
+	struct phm_acp_clock_voltage_dependency_table *acp_table =
+		hwmgr->dyn_state.acp_clock_voltage_dependency_table;
+	struct phm_uvd_clock_voltage_dependency_table *uvd_table =
+		hwmgr->dyn_state.uvd_clock_voltage_dependency_table;
+	struct phm_vce_clock_voltage_dependency_table *vce_table =
+		hwmgr->dyn_state.vce_clock_voltage_dependency_table;
+
+	if (!hwmgr->need_pp_table_upload)
+		return 0;
+
+	ret = smum_download_powerplay_table(hwmgr->smumgr, &table);
+
+	PP_ASSERT_WITH_CODE((0 == ret && NULL != table),
+			    "Fail to get clock table from SMU!", return -EINVAL;);
+
+	clock_table = (struct SMU8_Fusion_ClkTable *)table;
+
+	/* patch clock table */
+	PP_ASSERT_WITH_CODE((vddc_table->count <= CZ_MAX_HARDWARE_POWERLEVELS),
+			    "Dependency table entry exceeds max limit!", return -EINVAL;);
+	PP_ASSERT_WITH_CODE((vdd_gfx_table->count <= CZ_MAX_HARDWARE_POWERLEVELS),
+			    "Dependency table entry exceeds max limit!", return -EINVAL;);
+	PP_ASSERT_WITH_CODE((acp_table->count <= CZ_MAX_HARDWARE_POWERLEVELS),
+			    "Dependency table entry exceeds max limit!", return -EINVAL;);
+	PP_ASSERT_WITH_CODE((uvd_table->count <= CZ_MAX_HARDWARE_POWERLEVELS),
+			    "Dependency table entry exceeds max limit!", return -EINVAL;);
+	PP_ASSERT_WITH_CODE((vce_table->count <= CZ_MAX_HARDWARE_POWERLEVELS),
+			    "Dependency table entry exceeds max limit!", return -EINVAL;);
+
+	for (i = 0; i < CZ_MAX_HARDWARE_POWERLEVELS; i++) {
+
+		/* vddc_sclk */
+		clock_table->SclkBreakdownTable.ClkLevel[i].GnbVid =
+			(i < vddc_table->count) ? (uint8_t)vddc_table->entries[i].v : 0;
+		clock_table->SclkBreakdownTable.ClkLevel[i].Frequency =
+			(i < vddc_table->count) ? vddc_table->entries[i].clk : 0;
+
+		atomctrl_get_engine_pll_dividers_kong(hwmgr,
+						      clock_table->SclkBreakdownTable.ClkLevel[i].Frequency,
+						      &dividers);
+
+		clock_table->SclkBreakdownTable.ClkLevel[i].DfsDid =
+			(uint8_t)dividers.pll_post_divider;
+
+		/* vddgfx_sclk */
+		clock_table->SclkBreakdownTable.ClkLevel[i].GfxVid =
+			(i < vdd_gfx_table->count) ? (uint8_t)vdd_gfx_table->entries[i].v : 0;
+
+		/* acp breakdown */
+		clock_table->AclkBreakdownTable.ClkLevel[i].GfxVid =
+			(i < acp_table->count) ? (uint8_t)acp_table->entries[i].v : 0;
+		clock_table->AclkBreakdownTable.ClkLevel[i].Frequency =
+			(i < acp_table->count) ? acp_table->entries[i].acpclk : 0;
+
+		atomctrl_get_engine_pll_dividers_kong(hwmgr,
+						      clock_table->AclkBreakdownTable.ClkLevel[i].Frequency,
+						      &dividers);
+
+		clock_table->AclkBreakdownTable.ClkLevel[i].DfsDid =
+			(uint8_t)dividers.pll_post_divider;
+
+
+		/* uvd breakdown */
+		clock_table->VclkBreakdownTable.ClkLevel[i].GfxVid =
+			(i < uvd_table->count) ? (uint8_t)uvd_table->entries[i].v : 0;
+		clock_table->VclkBreakdownTable.ClkLevel[i].Frequency =
+			(i < uvd_table->count) ? uvd_table->entries[i].vclk : 0;
+
+		atomctrl_get_engine_pll_dividers_kong(hwmgr,
+						      clock_table->VclkBreakdownTable.ClkLevel[i].Frequency,
+						      &dividers);
+
+		clock_table->VclkBreakdownTable.ClkLevel[i].DfsDid =
+			(uint8_t)dividers.pll_post_divider;
+
+		clock_table->DclkBreakdownTable.ClkLevel[i].GfxVid =
+			(i < uvd_table->count) ? (uint8_t)uvd_table->entries[i].v : 0;
+		clock_table->DclkBreakdownTable.ClkLevel[i].Frequency =
+			(i < uvd_table->count) ? uvd_table->entries[i].dclk : 0;
+
+		atomctrl_get_engine_pll_dividers_kong(hwmgr,
+						      clock_table->DclkBreakdownTable.ClkLevel[i].Frequency,
+						      &dividers);
+
+		clock_table->DclkBreakdownTable.ClkLevel[i].DfsDid =
+			(uint8_t)dividers.pll_post_divider;
+
+		/* vce breakdown */
+		clock_table->EclkBreakdownTable.ClkLevel[i].GfxVid =
+			(i < vce_table->count) ? (uint8_t)vce_table->entries[i].v : 0;
+		clock_table->EclkBreakdownTable.ClkLevel[i].Frequency =
+			(i < vce_table->count) ? vce_table->entries[i].ecclk : 0;
+
+
+		atomctrl_get_engine_pll_dividers_kong(hwmgr,
+						      clock_table->EclkBreakdownTable.ClkLevel[i].Frequency,
+						      &dividers);
+
+		clock_table->EclkBreakdownTable.ClkLevel[i].DfsDid =
+			(uint8_t)dividers.pll_post_divider;
+
+	}
+	ret = smum_upload_powerplay_table(hwmgr->smumgr);
+
+	return ret;
+}
+
+static int cz_tf_init_sclk_limit(struct pp_hwmgr *hwmgr, void *input,
+				 void *output, void *storage, int result)
+{
+	struct cz_hwmgr *cz_hwmgr = (struct cz_hwmgr *)(hwmgr->backend);
+	struct phm_clock_voltage_dependency_table *table =
+					hwmgr->dyn_state.vddc_dependency_on_sclk;
+	unsigned long clock = 0, level;
+
+	if (NULL == table || table->count <= 0)
+		return -EINVAL;
+
+	cz_hwmgr->sclk_dpm.soft_min_clk = table->entries[0].clk;
+	cz_hwmgr->sclk_dpm.hard_min_clk = table->entries[0].clk;
+
+	level = cz_get_max_sclk_level(hwmgr) - 1;
+
+	if (level < table->count)
+		clock = table->entries[level].clk;
+	else
+		clock = table->entries[table->count - 1].clk;
+
+	cz_hwmgr->sclk_dpm.soft_max_clk = clock;
+	cz_hwmgr->sclk_dpm.hard_max_clk = clock;
+
+	return 0;
+}
+
+static int cz_tf_init_uvd_limit(struct pp_hwmgr *hwmgr, void *input,
+				void *output, void *storage, int result)
+{
+	struct cz_hwmgr *cz_hwmgr = (struct cz_hwmgr *)(hwmgr->backend);
+	struct phm_uvd_clock_voltage_dependency_table *table =
+				hwmgr->dyn_state.uvd_clock_voltage_dependency_table;
+	unsigned long clock = 0, level;
+
+	if (NULL == table || table->count <= 0)
+		return -EINVAL;
+
+	cz_hwmgr->uvd_dpm.soft_min_clk = 0;
+	cz_hwmgr->uvd_dpm.hard_min_clk = 0;
+
+	smum_send_msg_to_smc(hwmgr->smumgr, PPSMC_MSG_GetMaxUvdLevel);
+	level = smum_get_argument(hwmgr->smumgr);
+
+	if (level < table->count)
+		clock = table->entries[level].vclk;
+	else
+		clock = table->entries[table->count - 1].vclk;
+
+	cz_hwmgr->uvd_dpm.soft_max_clk = clock;
+	cz_hwmgr->uvd_dpm.hard_max_clk = clock;
+
+	return 0;
+}
+
+static int cz_tf_init_vce_limit(struct pp_hwmgr *hwmgr, void *input,
+				void *output, void *storage, int result)
+{
+	struct cz_hwmgr *cz_hwmgr = (struct cz_hwmgr *)(hwmgr->backend);
+	struct phm_vce_clock_voltage_dependency_table *table =
+				hwmgr->dyn_state.vce_clock_voltage_dependency_table;
+	unsigned long clock = 0, level;
+
+	if (NULL == table || table->count <= 0)
+		return -EINVAL;
+
+	cz_hwmgr->vce_dpm.soft_min_clk = 0;
+	cz_hwmgr->vce_dpm.hard_min_clk = 0;
+
+	smum_send_msg_to_smc(hwmgr->smumgr, PPSMC_MSG_GetMaxEclkLevel);
+	level = smum_get_argument(hwmgr->smumgr);
+
+	if (level < table->count)
+		clock = table->entries[level].ecclk;
+	else
+		clock = table->entries[table->count - 1].ecclk;
+
+	cz_hwmgr->vce_dpm.soft_max_clk = clock;
+	cz_hwmgr->vce_dpm.hard_max_clk = clock;
+
+	return 0;
+}
+
+static int cz_tf_init_acp_limit(struct pp_hwmgr *hwmgr, void *input,
+				void *output, void *storage, int result)
+{
+	struct cz_hwmgr *cz_hwmgr = (struct cz_hwmgr *)(hwmgr->backend);
+	struct phm_acp_clock_voltage_dependency_table *table =
+				hwmgr->dyn_state.acp_clock_voltage_dependency_table;
+	unsigned long clock = 0, level;
+
+	if (NULL == table || table->count <= 0)
+		return -EINVAL;
+
+	cz_hwmgr->acp_dpm.soft_min_clk = 0;
+	cz_hwmgr->acp_dpm.hard_min_clk = 0;
+
+	smum_send_msg_to_smc(hwmgr->smumgr, PPSMC_MSG_GetMaxAclkLevel);
+	level = smum_get_argument(hwmgr->smumgr);
+
+	if (level < table->count)
+		clock = table->entries[level].acpclk;
+	else
+		clock = table->entries[table->count - 1].acpclk;
+
+	cz_hwmgr->acp_dpm.soft_max_clk = clock;
+	cz_hwmgr->acp_dpm.hard_max_clk = clock;
+	return 0;
+}
+
+static int cz_tf_init_power_gate_state(struct pp_hwmgr *hwmgr, void *input,
+				void *output, void *storage, int result)
+{
+	struct cz_hwmgr *cz_hwmgr = (struct cz_hwmgr *)(hwmgr->backend);
+
+	cz_hwmgr->uvd_power_gated = false;
+	cz_hwmgr->vce_power_gated = false;
+	cz_hwmgr->samu_power_gated = false;
+	cz_hwmgr->acp_power_gated = false;
+	cz_hwmgr->pgacpinit = true;
+
+	return 0;
+}
+
+static int cz_tf_init_sclk_threshold(struct pp_hwmgr *hwmgr, void *input,
+				void *output, void *storage, int result)
+{
+	struct cz_hwmgr *cz_hwmgr = (struct cz_hwmgr *)(hwmgr->backend);
+
+	cz_hwmgr->low_sclk_interrupt_threshold = 0;
+
+	return 0;
+}
+static int cz_tf_update_sclk_limit(struct pp_hwmgr *hwmgr,
+					void *input, void *output,
+					void *storage, int result)
+{
+	struct cz_hwmgr *cz_hwmgr = (struct cz_hwmgr *)(hwmgr->backend);
+	struct phm_clock_voltage_dependency_table *table =
+					hwmgr->dyn_state.vddc_dependency_on_sclk;
+
+	unsigned long clock = 0;
+	unsigned long level;
+	unsigned long stable_pstate_sclk;
+	struct PP_Clocks clocks;
+	unsigned long percentage;
+
+	cz_hwmgr->sclk_dpm.soft_min_clk = table->entries[0].clk;
+	level = cz_get_max_sclk_level(hwmgr) - 1;
+
+	if (level < table->count)
+		cz_hwmgr->sclk_dpm.soft_max_clk  = table->entries[level].clk;
+	else
+		cz_hwmgr->sclk_dpm.soft_max_clk  = table->entries[table->count - 1].clk;
+
+	/*PECI_GetMinClockSettings(pHwMgr->pPECI, &clocks);*/
+	clock = clocks.engineClock;
+
+	if (cz_hwmgr->sclk_dpm.hard_min_clk != clock) {
+		cz_hwmgr->sclk_dpm.hard_min_clk = clock;
+
+		smum_send_msg_to_smc_with_parameter(hwmgr->smumgr,
+						PPSMC_MSG_SetSclkHardMin,
+						 cz_get_sclk_level(hwmgr,
+					cz_hwmgr->sclk_dpm.hard_min_clk,
+					     PPSMC_MSG_SetSclkHardMin));
+	}
+
+	clock = cz_hwmgr->sclk_dpm.soft_min_clk;
+
+	/* update minimum clocks for Stable P-State feature */
+	if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
+				     PHM_PlatformCaps_StablePState)) {
+		percentage = 75;
+		/*Sclk - calculate sclk value based on percentage and find FLOOR sclk from VddcDependencyOnSCLK table  */
+		stable_pstate_sclk = (hwmgr->dyn_state.max_clock_voltage_on_ac.mclk *
+					percentage) / 100;
+
+		if (clock < stable_pstate_sclk)
+			clock = stable_pstate_sclk;
+	} else {
+		if (clock < hwmgr->gfx_arbiter.sclk)
+			clock = hwmgr->gfx_arbiter.sclk;
+	}
+
+	if (cz_hwmgr->sclk_dpm.soft_min_clk != clock) {
+		cz_hwmgr->sclk_dpm.soft_min_clk = clock;
+		smum_send_msg_to_smc_with_parameter(hwmgr->smumgr,
+						PPSMC_MSG_SetSclkSoftMin,
+						cz_get_sclk_level(hwmgr,
+					cz_hwmgr->sclk_dpm.soft_min_clk,
+					     PPSMC_MSG_SetSclkSoftMin));
+	}
+
+	if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
+				    PHM_PlatformCaps_StablePState) &&
+			 cz_hwmgr->sclk_dpm.soft_max_clk != clock) {
+		cz_hwmgr->sclk_dpm.soft_max_clk = clock;
+		smum_send_msg_to_smc_with_parameter(hwmgr->smumgr,
+						PPSMC_MSG_SetSclkSoftMax,
+						cz_get_sclk_level(hwmgr,
+					cz_hwmgr->sclk_dpm.soft_max_clk,
+					PPSMC_MSG_SetSclkSoftMax));
+	}
+
+	return 0;
+}
+
+static int cz_tf_set_deep_sleep_sclk_threshold(struct pp_hwmgr *hwmgr,
+					void *input, void *output,
+					void *storage, int result)
+{
+	if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
+				PHM_PlatformCaps_SclkDeepSleep)) {
+		uint32_t clks = hwmgr->display_config.min_core_set_clock_in_sr;
+		if (clks == 0)
+			clks = CZ_MIN_DEEP_SLEEP_SCLK;
+
+		PP_DBG_LOG("Setting Deep Sleep Clock: %d\n", clks);
+
+		smum_send_msg_to_smc_with_parameter(hwmgr->smumgr,
+				PPSMC_MSG_SetMinDeepSleepSclk,
+				clks);
+	}
+
+	return 0;
+}
+
+static int cz_tf_set_watermark_threshold(struct pp_hwmgr *hwmgr,
+					void *input, void *output,
+					void *storage, int result)
+{
+	struct cz_hwmgr *cz_hwmgr =
+				  (struct cz_hwmgr *)(hwmgr->backend);
+
+	smum_send_msg_to_smc_with_parameter(hwmgr->smumgr,
+					PPSMC_MSG_SetWatermarkFrequency,
+				      cz_hwmgr->sclk_dpm.soft_max_clk);
+
+	return 0;
+}
+
+static int cz_tf_set_enabled_levels(struct pp_hwmgr *hwmgr,
+					void *input, void *output,
+					void *storage, int result)
+{
+	return 0;
+}
+
+
+static int cz_tf_enable_nb_dpm(struct pp_hwmgr *hwmgr,
+					void *input, void *output,
+					void *storage, int result)
+{
+	int ret = 0;
+
+	struct cz_hwmgr *cz_hwmgr = (struct cz_hwmgr *)(hwmgr->backend);
+	unsigned long dpm_features = 0;
+
+	if (!cz_hwmgr->is_nb_dpm_enabled) {
+		PP_DBG_LOG("enabling ALL SMU features.\n");
+		dpm_features |= NB_DPM_MASK;
+		ret = smum_send_msg_to_smc_with_parameter(
+							     hwmgr->smumgr,
+					 PPSMC_MSG_EnableAllSmuFeatures,
+							     dpm_features);
+		if (ret == 0)
+			cz_hwmgr->is_nb_dpm_enabled = true;
+	}
+
+	return ret;
+}
+
+static int cz_nbdpm_pstate_enable_disable(struct pp_hwmgr *hwmgr, bool enable, bool lock)
+{
+	struct cz_hwmgr *hw_data = (struct cz_hwmgr *)(hwmgr->backend);
+
+	if (hw_data->is_nb_dpm_enabled) {
+		if (enable) {
+			PP_DBG_LOG("enable Low Memory PState.\n");
+
+			return smum_send_msg_to_smc_with_parameter(hwmgr->smumgr,
+						PPSMC_MSG_EnableLowMemoryPstate,
+						(lock ? 1 : 0));
+		} else {
+			PP_DBG_LOG("disable Low Memory PState.\n");
+
+			return smum_send_msg_to_smc_with_parameter(hwmgr->smumgr,
+						PPSMC_MSG_DisableLowMemoryPstate,
+						(lock ? 1 : 0));
+		}
+	}
+
+	return 0;
+}
+
+static int cz_tf_update_low_mem_pstate(struct pp_hwmgr *hwmgr,
+					void *input, void *output,
+					void *storage, int result)
+{
+	bool disable_switch;
+	bool enable_low_mem_state;
+	struct cz_hwmgr *hw_data = (struct cz_hwmgr *)(hwmgr->backend);
+	const struct phm_set_power_state_input *states = (struct phm_set_power_state_input *)input;
+	const struct cz_power_state *pnew_state = cast_const_PhwCzPowerState(states->pnew_state);
+
+	if (hw_data->sys_info.nb_dpm_enable) {
+		disable_switch = hw_data->cc6_settings.nb_pstate_switch_disable ? true : false;
+		enable_low_mem_state = hw_data->cc6_settings.nb_pstate_switch_disable ? false : true;
+
+		if (pnew_state->action == FORCE_HIGH)
+			cz_nbdpm_pstate_enable_disable(hwmgr, false, disable_switch);
+		else if(pnew_state->action == CANCEL_FORCE_HIGH)
+			cz_nbdpm_pstate_enable_disable(hwmgr, false, disable_switch);
+		else 
+			cz_nbdpm_pstate_enable_disable(hwmgr, enable_low_mem_state, disable_switch);
+	}
+	return 0;
+}
+
+static struct phm_master_table_item cz_set_power_state_list[] = {
+	{NULL, cz_tf_update_sclk_limit},
+	{NULL, cz_tf_set_deep_sleep_sclk_threshold},
+	{NULL, cz_tf_set_watermark_threshold},
+	{NULL, cz_tf_set_enabled_levels},
+	{NULL, cz_tf_enable_nb_dpm},
+	{NULL, cz_tf_update_low_mem_pstate},
+	{NULL, NULL}
+};
+
+static struct phm_master_table_header cz_set_power_state_master = {
+	0,
+	PHM_MasterTableFlag_None,
+	cz_set_power_state_list
+};
+
+static struct phm_master_table_item cz_setup_asic_list[] = {
+	{NULL, cz_tf_reset_active_process_mask},
+	{NULL, cz_tf_upload_pptable_to_smu},
+	{NULL, cz_tf_init_sclk_limit},
+	{NULL, cz_tf_init_uvd_limit},
+	{NULL, cz_tf_init_vce_limit},
+	{NULL, cz_tf_init_acp_limit},
+	{NULL, cz_tf_init_power_gate_state},
+	{NULL, cz_tf_init_sclk_threshold},
+	{NULL, NULL}
+};
+
+static struct phm_master_table_header cz_setup_asic_master = {
+	0,
+	PHM_MasterTableFlag_None,
+	cz_setup_asic_list
+};
+
+static int cz_tf_power_up_display_clock_sys_pll(struct pp_hwmgr *hwmgr,
+					void *input, void *output,
+					void *storage, int result)
+{
+	struct cz_hwmgr *hw_data = (struct cz_hwmgr *)(hwmgr->backend);
+	hw_data->disp_clk_bypass_pending = false;
+	hw_data->disp_clk_bypass = false;
+
+	return 0;
+}
+
+static int cz_tf_clear_nb_dpm_flag(struct pp_hwmgr *hwmgr,
+					void *input, void *output,
+					void *storage, int result)
+{
+	struct cz_hwmgr *hw_data = (struct cz_hwmgr *)(hwmgr->backend);
+	hw_data->is_nb_dpm_enabled = false;
+
+	return 0;
+}
+
+static int cz_tf_reset_cc6_data(struct pp_hwmgr *hwmgr,
+					void *input, void *output,
+					void *storage, int result)
+{
+	struct cz_hwmgr *hw_data = (struct cz_hwmgr *)(hwmgr->backend);
+
+	hw_data->cc6_settings.cc6_setting_changed = false;
+	hw_data->cc6_settings.cpu_pstate_separation_time = 0;
+	hw_data->cc6_settings.cpu_cc6_disable = false;
+	hw_data->cc6_settings.cpu_pstate_disable = false;
+
+	return 0;
+}
+
+static struct phm_master_table_item cz_power_down_asic_list[] = {
+	{NULL, cz_tf_power_up_display_clock_sys_pll},
+	{NULL, cz_tf_clear_nb_dpm_flag},
+	{NULL, cz_tf_reset_cc6_data},
+	{NULL, NULL}
+};
+
+static struct phm_master_table_header cz_power_down_asic_master = {
+	0,
+	PHM_MasterTableFlag_None,
+	cz_power_down_asic_list
+};
+
+static int cz_tf_program_voting_clients(struct pp_hwmgr *hwmgr, void *input,
+				void *output, void *storage, int result)
+{
+	PHMCZ_WRITE_SMC_REGISTER(hwmgr->device, CG_FREQ_TRAN_VOTING_0,
+				PPCZ_VOTINGRIGHTSCLIENTS_DFLT0);
+	return 0;
+}
+
+static int cz_tf_start_dpm(struct pp_hwmgr *hwmgr, void *input, void *output,
+			   void *storage, int result)
+{
+	int res = 0xff;
+	struct cz_hwmgr *cz_hwmgr = (struct cz_hwmgr *)(hwmgr->backend);
+	unsigned long dpm_features = 0;
+
+	cz_hwmgr->dpm_flags |= DPMFlags_SCLK_Enabled;
+	dpm_features |= SCLK_DPM_MASK;
+
+	res = smum_send_msg_to_smc_with_parameter(hwmgr->smumgr,
+				PPSMC_MSG_EnableAllSmuFeatures,
+				dpm_features);
+
+	return res;
+}
+
+static int cz_tf_program_bootup_state(struct pp_hwmgr *hwmgr, void *input,
+				void *output, void *storage, int result)
+{
+	struct cz_hwmgr *cz_hwmgr = (struct cz_hwmgr *)(hwmgr->backend);
+
+	cz_hwmgr->sclk_dpm.soft_min_clk = cz_hwmgr->sys_info.bootup_engine_clock;
+	cz_hwmgr->sclk_dpm.soft_max_clk = cz_hwmgr->sys_info.bootup_engine_clock;
+
+	smum_send_msg_to_smc_with_parameter(hwmgr->smumgr,
+				PPSMC_MSG_SetSclkSoftMin,
+				cz_get_sclk_level(hwmgr,
+				cz_hwmgr->sclk_dpm.soft_min_clk,
+				PPSMC_MSG_SetSclkSoftMin));
+
+	smum_send_msg_to_smc_with_parameter(hwmgr->smumgr,
+				PPSMC_MSG_SetSclkSoftMax,
+				cz_get_sclk_level(hwmgr,
+				cz_hwmgr->sclk_dpm.soft_max_clk,
+				PPSMC_MSG_SetSclkSoftMax));
+
+	return 0;
+}
+
+int cz_tf_reset_acp_boot_level(struct pp_hwmgr *hwmgr, void *input,
+				void *output, void *storage, int result)
+{
+	struct cz_hwmgr *cz_hwmgr = (struct cz_hwmgr *)(hwmgr->backend);
+
+	cz_hwmgr->acp_boot_level = 0xff;
+	return 0;
+}
+
+static bool cz_dpm_check_smu_features(struct pp_hwmgr *hwmgr,
+				unsigned long check_feature)
+{
+	int result;
+	unsigned long features;
+
+	result = smum_send_msg_to_smc_with_parameter(hwmgr->smumgr, PPSMC_MSG_GetFeatureStatus, 0);
+	if (result == 0) {
+		features = smum_get_argument(hwmgr->smumgr);
+		if (features & check_feature)
+			return true;
+	}
+
+	return result;
+}
+
+static int cz_tf_check_for_dpm_disabled(struct pp_hwmgr *hwmgr, void *input,
+				void *output, void *storage, int result)
+{
+	if (cz_dpm_check_smu_features(hwmgr, SMU_EnabledFeatureScoreboard_SclkDpmOn))
+		return PP_Result_TableImmediateExit;
+	return 0;
+}
+
+static int cz_tf_enable_didt(struct pp_hwmgr *hwmgr, void *input,
+				void *output, void *storage, int result)
+{
+	/* TO DO */
+	return 0;
+}
+
+static int cz_tf_check_for_dpm_enabled(struct pp_hwmgr *hwmgr,
+						void *input, void *output,
+						void *storage, int result)
+{
+	if (!cz_dpm_check_smu_features(hwmgr,
+			     SMU_EnabledFeatureScoreboard_SclkDpmOn))
+		return PP_Result_TableImmediateExit;
+	return 0;
+}
+
+static struct phm_master_table_item cz_disable_dpm_list[] = {
+	{ NULL, cz_tf_check_for_dpm_enabled},
+	{NULL, NULL},
+};
+
+
+static struct phm_master_table_header cz_disable_dpm_master = {
+	0,
+	PHM_MasterTableFlag_None,
+	cz_disable_dpm_list
+};
+
+static struct phm_master_table_item cz_enable_dpm_list[] = {
+	{ NULL, cz_tf_check_for_dpm_disabled },
+	{ NULL, cz_tf_program_voting_clients },
+	{ NULL, cz_tf_start_dpm},
+	{ NULL, cz_tf_program_bootup_state},
+	{ NULL, cz_tf_enable_didt },
+	{ NULL, cz_tf_reset_acp_boot_level },
+	{NULL, NULL},
+};
+
+static struct phm_master_table_header cz_enable_dpm_master = {
+	0,
+	PHM_MasterTableFlag_None,
+	cz_enable_dpm_list
+};
+
+static int cz_apply_state_adjust_rules(struct pp_hwmgr *hwmgr,
+				struct pp_power_state  *prequest_ps,
+			const struct pp_power_state *pcurrent_ps)
+{
+	struct cz_power_state *cz_ps =
+				cast_PhwCzPowerState(&prequest_ps->hardware);
+
+	const struct cz_power_state *cz_current_ps =
+				cast_const_PhwCzPowerState(&pcurrent_ps->hardware);
+
+	struct cz_hwmgr *cz_hwmgr = (struct cz_hwmgr *)(hwmgr->backend);
+	struct PP_Clocks clocks;
+	bool force_high;
+	unsigned long  num_of_active_displays = 4;
+
+	cz_ps->evclk = hwmgr->vce_arbiter.evclk;
+	cz_ps->ecclk = hwmgr->vce_arbiter.ecclk;
+
+	cz_ps->need_dfs_bypass = true;
+
+	cz_hwmgr->video_start = (hwmgr->uvd_arbiter.vclk != 0 || hwmgr->uvd_arbiter.dclk != 0 ||
+				hwmgr->vce_arbiter.evclk != 0 || hwmgr->vce_arbiter.ecclk != 0);
+
+	cz_hwmgr->battery_state = (PP_StateUILabel_Battery == prequest_ps->classification.ui_label);
+
+	/* to do PECI_GetMinClockSettings(pHwMgr->pPECI, &clocks); */
+	/* PECI_GetNumberOfActiveDisplays(pHwMgr->pPECI, &numOfActiveDisplays); */
+	if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_StablePState))
+		clocks.memoryClock = hwmgr->dyn_state.max_clock_voltage_on_ac.mclk;
+	else
+		clocks.memoryClock = 0;
+
+	if (clocks.memoryClock < hwmgr->gfx_arbiter.mclk)
+		clocks.memoryClock = hwmgr->gfx_arbiter.mclk;
+
+	force_high = (clocks.memoryClock > cz_hwmgr->sys_info.nbp_memory_clock[CZ_NUM_NBPMEMORYCLOCK - 1])
+			|| (num_of_active_displays >= 3);
+
+	cz_ps->action = cz_current_ps->action;
+
+	if ((force_high == false) && (cz_ps->action == FORCE_HIGH))
+		cz_ps->action = CANCEL_FORCE_HIGH;
+	else if ((force_high == true) && (cz_ps->action != FORCE_HIGH))
+		cz_ps->action = FORCE_HIGH;
+	else
+		cz_ps->action = DO_NOTHING;
+
+	return 0;
+}
+
+static int cz_hwmgr_backend_init(struct pp_hwmgr *hwmgr)
+{
+	int result = 0;
+
+	result = cz_initialize_dpm_defaults(hwmgr);
+	if (result != 0) {
+		printk(KERN_ERR "[ powerplay ] cz_initialize_dpm_defaults failed\n");
+		return result;
+	}
+
+	result = cz_get_system_info_data(hwmgr);
+	if (result != 0) {
+		printk(KERN_ERR "[ powerplay ] cz_get_system_info_data failed\n");
+		return result;
+	}
+
+	cz_construct_boot_state(hwmgr);
+
+	result = phm_construct_table(hwmgr, &cz_setup_asic_master,
+				&(hwmgr->setup_asic));
+	if (result != 0) {
+		printk(KERN_ERR "[ powerplay ] Fail to construct setup ASIC\n");
+		return result;
+	}
+
+	result = phm_construct_table(hwmgr, &cz_power_down_asic_master,
+				&(hwmgr->power_down_asic));
+	if (result != 0) {
+		printk(KERN_ERR "[ powerplay ] Fail to construct power down ASIC\n");
+		return result;
+	}
+
+	result = phm_construct_table(hwmgr, &cz_disable_dpm_master,
+				&(hwmgr->disable_dynamic_state_management));
+	if (result != 0) {
+		printk(KERN_ERR "[ powerplay ] Fail to disable_dynamic_state\n");
+		return result;
+	}
+	result = phm_construct_table(hwmgr, &cz_enable_dpm_master,
+				&(hwmgr->enable_dynamic_state_management));
+	if (result != 0) {
+		printk(KERN_ERR "[ powerplay ] Fail to enable_dynamic_state\n");
+		return result;
+	}
+	result = phm_construct_table(hwmgr, &cz_set_power_state_master,
+				&(hwmgr->set_power_state));
+	if (result != 0) {
+		printk(KERN_ERR "[ powerplay ] Fail to construct set_power_state\n");
+		return result;
+	}
+
+	result = phm_construct_table(hwmgr, &cz_phm_enable_clock_power_gatings_master, &(hwmgr->enable_clock_power_gatings));
+	if (result != 0) {
+		printk(KERN_ERR "[ powerplay ] Fail to construct enable_clock_power_gatings\n");
+		return result;
+	}
+	return result;
+}
+
+static int cz_hwmgr_backend_fini(struct pp_hwmgr *hwmgr)
+{
+	if (hwmgr != NULL || hwmgr->backend != NULL) {
+		kfree(hwmgr->backend);
+		kfree(hwmgr);
+	}
+	return 0;
+}
+
+int cz_phm_force_dpm_highest(struct pp_hwmgr *hwmgr)
+{
+	struct cz_hwmgr *cz_hwmgr = (struct cz_hwmgr *)(hwmgr->backend);
+
+	if (cz_hwmgr->sclk_dpm.soft_min_clk !=
+				cz_hwmgr->sclk_dpm.soft_max_clk)
+		smum_send_msg_to_smc_with_parameter(hwmgr->smumgr,
+						PPSMC_MSG_SetSclkSoftMin,
+						cz_get_sclk_level(hwmgr,
+						cz_hwmgr->sclk_dpm.soft_max_clk,
+						PPSMC_MSG_SetSclkSoftMin));
+	return 0;
+}
+
+int cz_phm_unforce_dpm_levels(struct pp_hwmgr *hwmgr)
+{
+	struct cz_hwmgr *cz_hwmgr = (struct cz_hwmgr *)(hwmgr->backend);
+	struct phm_clock_voltage_dependency_table *table =
+				hwmgr->dyn_state.vddc_dependency_on_sclk;
+	unsigned long clock = 0, level;
+
+	if (NULL == table || table->count <= 0)
+		return -EINVAL;
+
+	cz_hwmgr->sclk_dpm.soft_min_clk = table->entries[0].clk;
+	cz_hwmgr->sclk_dpm.hard_min_clk = table->entries[0].clk;
+
+	level = cz_get_max_sclk_level(hwmgr) - 1;
+
+	if (level < table->count)
+		clock = table->entries[level].clk;
+	else
+		clock = table->entries[table->count - 1].clk;
+
+	cz_hwmgr->sclk_dpm.soft_max_clk = clock;
+	cz_hwmgr->sclk_dpm.hard_max_clk = clock;
+
+	smum_send_msg_to_smc_with_parameter(hwmgr->smumgr,
+				PPSMC_MSG_SetSclkSoftMin,
+				cz_get_sclk_level(hwmgr,
+				cz_hwmgr->sclk_dpm.soft_min_clk,
+				PPSMC_MSG_SetSclkSoftMin));
+
+	smum_send_msg_to_smc_with_parameter(hwmgr->smumgr,
+				PPSMC_MSG_SetSclkSoftMax,
+				cz_get_sclk_level(hwmgr,
+				cz_hwmgr->sclk_dpm.soft_max_clk,
+				PPSMC_MSG_SetSclkSoftMax));
+
+	return 0;
+}
+
+int cz_phm_force_dpm_lowest(struct pp_hwmgr *hwmgr)
+{
+	struct cz_hwmgr *cz_hwmgr = (struct cz_hwmgr *)(hwmgr->backend);
+
+	if (cz_hwmgr->sclk_dpm.soft_min_clk !=
+				cz_hwmgr->sclk_dpm.soft_max_clk) {
+		cz_hwmgr->sclk_dpm.soft_max_clk =
+			cz_hwmgr->sclk_dpm.soft_min_clk;
+
+		smum_send_msg_to_smc_with_parameter(hwmgr->smumgr,
+				PPSMC_MSG_SetSclkSoftMax,
+				cz_get_sclk_level(hwmgr,
+				cz_hwmgr->sclk_dpm.soft_max_clk,
+				PPSMC_MSG_SetSclkSoftMax));
+	}
+
+	return 0;
+}
+
+static int cz_dpm_force_dpm_level(struct pp_hwmgr *hwmgr,
+				enum amd_dpm_forced_level level)
+{
+	int ret = 0;
+
+	switch (level) {
+	case AMD_DPM_FORCED_LEVEL_HIGH:
+		ret = cz_phm_force_dpm_highest(hwmgr);
+		if (ret)
+			return ret;
+		break;
+	case AMD_DPM_FORCED_LEVEL_LOW:
+		ret = cz_phm_force_dpm_lowest(hwmgr);
+		if (ret)
+			return ret;
+		break;
+	case AMD_DPM_FORCED_LEVEL_AUTO:
+		ret = cz_phm_unforce_dpm_levels(hwmgr);
+		if (ret)
+			return ret;
+		break;
+	default:
+		break;
+	}
+
+	hwmgr->dpm_level = level;
+
+	return ret;
+}
+
+int cz_dpm_powerdown_uvd(struct pp_hwmgr *hwmgr)
+{
+	if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
+					 PHM_PlatformCaps_UVDPowerGating))
+		return smum_send_msg_to_smc(hwmgr->smumgr,
+						     PPSMC_MSG_UVDPowerOFF);
+	return 0;
+}
+
+int cz_dpm_powerup_uvd(struct pp_hwmgr *hwmgr)
+{
+	if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
+					 PHM_PlatformCaps_UVDPowerGating)) {
+		if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
+				  PHM_PlatformCaps_UVDDynamicPowerGating)) {
+			return smum_send_msg_to_smc_with_parameter(
+								hwmgr->smumgr,
+						   PPSMC_MSG_UVDPowerON, 1);
+		} else {
+			return smum_send_msg_to_smc_with_parameter(
+								hwmgr->smumgr,
+						   PPSMC_MSG_UVDPowerON, 0);
+		}
+	}
+
+	return 0;
+}
+
+int cz_dpm_update_uvd_dpm(struct pp_hwmgr *hwmgr, bool bgate)
+{
+	struct cz_hwmgr *cz_hwmgr = (struct cz_hwmgr *)(hwmgr->backend);
+	struct phm_uvd_clock_voltage_dependency_table *ptable =
+		hwmgr->dyn_state.uvd_clock_voltage_dependency_table;
+
+	if (!bgate) {
+		/* Stable Pstate is enabled and we need to set the UVD DPM to highest level */
+		if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
+					 PHM_PlatformCaps_StablePState)) {
+			cz_hwmgr->uvd_dpm.hard_min_clk =
+				   ptable->entries[ptable->count - 1].vclk;
+
+			smum_send_msg_to_smc_with_parameter(hwmgr->smumgr,
+						     PPSMC_MSG_SetUvdHardMin,
+						      cz_get_uvd_level(hwmgr,
+					     cz_hwmgr->uvd_dpm.hard_min_clk,
+						   PPSMC_MSG_SetUvdHardMin));
+
+			cz_enable_disable_uvd_dpm(hwmgr, true);
+		} else
+			cz_enable_disable_uvd_dpm(hwmgr, true);
+	} else
+		cz_enable_disable_uvd_dpm(hwmgr, false);
+
+	return 0;
+}
+
+int  cz_dpm_update_vce_dpm(struct pp_hwmgr *hwmgr)
+{
+	struct cz_hwmgr *cz_hwmgr = (struct cz_hwmgr *)(hwmgr->backend);
+	struct phm_vce_clock_voltage_dependency_table *ptable =
+		hwmgr->dyn_state.vce_clock_voltage_dependency_table;
+
+	/* Stable Pstate is enabled and we need to set the VCE DPM to highest level */
+	if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
+					 PHM_PlatformCaps_StablePState)) {
+		cz_hwmgr->vce_dpm.hard_min_clk =
+				  ptable->entries[ptable->count - 1].ecclk;
+
+		smum_send_msg_to_smc_with_parameter(hwmgr->smumgr,
+					PPSMC_MSG_SetEclkHardMin,
+					cz_get_eclk_level(hwmgr,
+					     cz_hwmgr->vce_dpm.hard_min_clk,
+						PPSMC_MSG_SetEclkHardMin));
+	} else {
+		/*EPR# 419220 -HW limitation to to */
+		cz_hwmgr->vce_dpm.hard_min_clk = hwmgr->vce_arbiter.ecclk;
+		smum_send_msg_to_smc_with_parameter(hwmgr->smumgr,
+					    PPSMC_MSG_SetEclkHardMin,
+					    cz_get_eclk_level(hwmgr,
+				     cz_hwmgr->vce_dpm.hard_min_clk,
+					  PPSMC_MSG_SetEclkHardMin));
+
+	}
+	return 0;
+}
+
+int cz_dpm_powerdown_vce(struct pp_hwmgr *hwmgr)
+{
+	if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
+					 PHM_PlatformCaps_VCEPowerGating))
+		return smum_send_msg_to_smc(hwmgr->smumgr,
+						     PPSMC_MSG_VCEPowerOFF);
+	return 0;
+}
+
+int cz_dpm_powerup_vce(struct pp_hwmgr *hwmgr)
+{
+	if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
+					 PHM_PlatformCaps_VCEPowerGating))
+		return smum_send_msg_to_smc(hwmgr->smumgr,
+						     PPSMC_MSG_VCEPowerON);
+	return 0;
+}
+
+static int cz_dpm_get_mclk(struct pp_hwmgr *hwmgr, bool low)
+{
+	struct cz_hwmgr *cz_hwmgr = (struct cz_hwmgr *)(hwmgr->backend);
+
+	return cz_hwmgr->sys_info.bootup_uma_clock;
+}
+
+static int cz_dpm_get_sclk(struct pp_hwmgr *hwmgr, bool low)
+{
+	struct pp_power_state  *ps;
+	struct cz_power_state  *cz_ps;
+
+	if (hwmgr == NULL)
+		return -EINVAL;
+
+	ps = hwmgr->request_ps;
+
+	if (ps == NULL)
+		return -EINVAL;
+
+	cz_ps = cast_PhwCzPowerState(&ps->hardware);
+
+	if (low)
+		return cz_ps->levels[0].engineClock;
+	else
+		return cz_ps->levels[cz_ps->level-1].engineClock;
+}
+
+static int cz_dpm_patch_boot_state(struct pp_hwmgr *hwmgr,
+					struct pp_hw_power_state *hw_ps)
+{
+	struct cz_hwmgr *cz_hwmgr = (struct cz_hwmgr *)(hwmgr->backend);
+	struct cz_power_state *cz_ps = cast_PhwCzPowerState(hw_ps);
+
+	cz_ps->level = 1;
+	cz_ps->nbps_flags = 0;
+	cz_ps->bapm_flags = 0;
+	cz_ps->levels[0] = cz_hwmgr->boot_power_level;
+
+	return 0;
+}
+
+static int cz_dpm_get_pp_table_entry_callback(
+						     struct pp_hwmgr *hwmgr,
+					   struct pp_hw_power_state *hw_ps,
+							  unsigned int index,
+						     const void *clock_info)
+{
+	struct cz_power_state *cz_ps = cast_PhwCzPowerState(hw_ps);
+
+	const ATOM_PPLIB_CZ_CLOCK_INFO *cz_clock_info = clock_info;
+
+	struct phm_clock_voltage_dependency_table *table =
+				    hwmgr->dyn_state.vddc_dependency_on_sclk;
+	uint8_t clock_info_index = cz_clock_info->index;
+
+	if (clock_info_index > (uint8_t)(hwmgr->platform_descriptor.hardwareActivityPerformanceLevels - 1))
+		clock_info_index = (uint8_t)(hwmgr->platform_descriptor.hardwareActivityPerformanceLevels - 1);
+
+	cz_ps->levels[index].engineClock = table->entries[clock_info_index].clk;
+	cz_ps->levels[index].vddcIndex = (uint8_t)table->entries[clock_info_index].v;
+
+	cz_ps->level = index + 1;
+
+	if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_SclkDeepSleep)) {
+		cz_ps->levels[index].dsDividerIndex = 5;
+		cz_ps->levels[index].ssDividerIndex = 5;
+	}
+
+	return 0;
+}
+
+static int cz_dpm_get_num_of_pp_table_entries(struct pp_hwmgr *hwmgr)
+{
+	int result;
+	unsigned long ret = 0;
+
+	result = pp_tables_get_num_of_entries(hwmgr, &ret);
+
+	return result ? 0 : ret;
+}
+
+static int cz_dpm_get_pp_table_entry(struct pp_hwmgr *hwmgr,
+		    unsigned long entry, struct pp_power_state *ps)
+{
+	int result;
+	struct cz_power_state *cz_ps;
+
+	ps->hardware.magic = PhwCz_Magic;
+
+	cz_ps = cast_PhwCzPowerState(&(ps->hardware));
+
+	result = pp_tables_get_entry(hwmgr, entry, ps,
+			cz_dpm_get_pp_table_entry_callback);
+
+	cz_ps->uvd_clocks.vclk = ps->uvd_clocks.VCLK;
+	cz_ps->uvd_clocks.dclk = ps->uvd_clocks.DCLK;
+
+	return result;
+}
+
+int cz_get_power_state_size(struct pp_hwmgr *hwmgr)
+{
+	return sizeof(struct cz_power_state);
+}
+
+static void
+cz_print_current_perforce_level(struct pp_hwmgr *hwmgr, struct seq_file *m)
+{
+	struct cz_hwmgr *cz_hwmgr = (struct cz_hwmgr *)(hwmgr->backend);
+
+	struct phm_clock_voltage_dependency_table *table =
+				hwmgr->dyn_state.vddc_dependency_on_sclk;
+
+	struct phm_vce_clock_voltage_dependency_table *vce_table =
+		hwmgr->dyn_state.vce_clock_voltage_dependency_table;
+
+	struct phm_uvd_clock_voltage_dependency_table *uvd_table =
+		hwmgr->dyn_state.uvd_clock_voltage_dependency_table;
+
+	uint32_t sclk_index = PHM_GET_FIELD(cgs_read_ind_register(hwmgr->device, CGS_IND_REG__SMC, ixTARGET_AND_CURRENT_PROFILE_INDEX),
+					TARGET_AND_CURRENT_PROFILE_INDEX, CURR_SCLK_INDEX);
+	uint32_t uvd_index = PHM_GET_FIELD(cgs_read_ind_register(hwmgr->device, CGS_IND_REG__SMC, ixTARGET_AND_CURRENT_PROFILE_INDEX_2),
+					TARGET_AND_CURRENT_PROFILE_INDEX_2, CURR_UVD_INDEX);
+	uint32_t vce_index = PHM_GET_FIELD(cgs_read_ind_register(hwmgr->device, CGS_IND_REG__SMC, ixTARGET_AND_CURRENT_PROFILE_INDEX_2),
+					TARGET_AND_CURRENT_PROFILE_INDEX_2, CURR_VCE_INDEX);
+
+	uint32_t sclk, vclk, dclk, ecclk, tmp, activity_percent;
+	uint16_t vddnb, vddgfx;
+	int result;
+
+	if (sclk_index >= NUM_SCLK_LEVELS) {
+		seq_printf(m, "\n invalid sclk dpm profile %d\n", sclk_index);
+	} else {
+		sclk = table->entries[sclk_index].clk;
+		seq_printf(m, "\n index: %u sclk: %u MHz\n", sclk_index, sclk/100);
+	}
+
+	tmp = (cgs_read_ind_register(hwmgr->device, CGS_IND_REG__SMC, ixSMUSVI_NB_CURRENTVID) &
+		CURRENT_NB_VID_MASK) >> CURRENT_NB_VID__SHIFT;
+	vddnb = cz_convert_8Bit_index_to_voltage(hwmgr, tmp);
+	tmp = (cgs_read_ind_register(hwmgr->device, CGS_IND_REG__SMC, ixSMUSVI_GFX_CURRENTVID) &
+		CURRENT_GFX_VID_MASK) >> CURRENT_GFX_VID__SHIFT;
+	vddgfx = cz_convert_8Bit_index_to_voltage(hwmgr, (u16)tmp);
+	seq_printf(m, "\n vddnb: %u vddgfx: %u\n", vddnb, vddgfx);
+
+	seq_printf(m, "\n uvd    %sabled\n", cz_hwmgr->uvd_power_gated ? "dis" : "en");
+	if (!cz_hwmgr->uvd_power_gated) {
+		if (uvd_index >= CZ_MAX_HARDWARE_POWERLEVELS) {
+			seq_printf(m, "\n invalid uvd dpm level %d\n", uvd_index);
+		} else {
+			vclk = uvd_table->entries[uvd_index].vclk;
+			dclk = uvd_table->entries[uvd_index].dclk;
+			seq_printf(m, "\n index: %u uvd vclk: %u MHz dclk: %u MHz\n", uvd_index, vclk/100, dclk/100);
+		}
+	}
+
+	seq_printf(m, "\n vce    %sabled\n", cz_hwmgr->vce_power_gated ? "dis" : "en");
+	if (!cz_hwmgr->vce_power_gated) {
+		if (vce_index >= CZ_MAX_HARDWARE_POWERLEVELS) {
+			seq_printf(m, "\n invalid vce dpm level %d\n", vce_index);
+		} else {
+			ecclk = vce_table->entries[vce_index].ecclk;
+			seq_printf(m, "\n index: %u vce ecclk: %u MHz\n", vce_index, ecclk/100);
+		}
+	}
+
+	result = smum_send_msg_to_smc(hwmgr->smumgr, PPSMC_MSG_GetAverageGraphicsActivity);
+	if (0 == result) {
+		activity_percent = cgs_read_register(hwmgr->device, mmSMU_MP1_SRBM2P_ARG_0);
+		activity_percent = activity_percent > 100 ? 100 : activity_percent;
+	} else {
+		activity_percent = 50;
+	}
+
+	seq_printf(m, "\n [GPU load]: %u %%\n\n", activity_percent);
+}
+
+static void cz_hw_print_display_cfg(
+	const struct cc6_settings *cc6_settings)
+{
+	PP_DBG_LOG("New Display Configuration:\n");
+
+	PP_DBG_LOG("   cpu_cc6_disable: %d\n",
+			cc6_settings->cpu_cc6_disable);
+	PP_DBG_LOG("   cpu_pstate_disable: %d\n",
+			cc6_settings->cpu_pstate_disable);
+	PP_DBG_LOG("   nb_pstate_switch_disable: %d\n",
+			cc6_settings->nb_pstate_switch_disable);
+	PP_DBG_LOG("   cpu_pstate_separation_time: %d\n\n",
+			cc6_settings->cpu_pstate_separation_time);
+}
+
+ static int cz_set_cpu_power_state(struct pp_hwmgr *hwmgr)
+{
+	struct cz_hwmgr *hw_data = (struct cz_hwmgr *)(hwmgr->backend);
+	uint32_t data = 0;
+
+	if (hw_data->cc6_settings.cc6_setting_changed == true) {
+
+		hw_data->cc6_settings.cc6_setting_changed = false;
+
+		cz_hw_print_display_cfg(&hw_data->cc6_settings);
+
+		data |= (hw_data->cc6_settings.cpu_pstate_separation_time
+			& PWRMGT_SEPARATION_TIME_MASK)
+			<< PWRMGT_SEPARATION_TIME_SHIFT;
+
+		data|= (hw_data->cc6_settings.cpu_cc6_disable ? 0x1 : 0x0)
+			<< PWRMGT_DISABLE_CPU_CSTATES_SHIFT;
+
+		data|= (hw_data->cc6_settings.cpu_pstate_disable ? 0x1 : 0x0)
+			<< PWRMGT_DISABLE_CPU_PSTATES_SHIFT;
+
+		PP_DBG_LOG("SetDisplaySizePowerParams data: 0x%X\n",
+			data);
+
+		smum_send_msg_to_smc_with_parameter(hwmgr->smumgr,
+						PPSMC_MSG_SetDisplaySizePowerParams,
+						data);
+	}
+
+	return 0;
+}
+
+
+ static int cz_store_cc6_data(struct pp_hwmgr *hwmgr, uint32_t separation_time,
+			bool cc6_disable, bool pstate_disable, bool pstate_switch_disable)
+ {
+	struct cz_hwmgr *hw_data = (struct cz_hwmgr *)(hwmgr->backend);
+
+	if (separation_time !=
+		hw_data->cc6_settings.cpu_pstate_separation_time
+		|| cc6_disable !=
+		hw_data->cc6_settings.cpu_cc6_disable
+		|| pstate_disable !=
+		hw_data->cc6_settings.cpu_pstate_disable
+		|| pstate_switch_disable !=
+		hw_data->cc6_settings.nb_pstate_switch_disable) {
+
+		hw_data->cc6_settings.cc6_setting_changed = true;
+
+		hw_data->cc6_settings.cpu_pstate_separation_time =
+			separation_time;
+		hw_data->cc6_settings.cpu_cc6_disable =
+			cc6_disable;
+		hw_data->cc6_settings.cpu_pstate_disable =
+			pstate_disable;
+		hw_data->cc6_settings.nb_pstate_switch_disable =
+			pstate_switch_disable;
+
+	}
+
+	return 0;
+}
+
+ static int cz_get_dal_power_level(struct pp_hwmgr *hwmgr,
+		struct amd_pp_dal_clock_info*info)
+{
+	uint32_t i;
+	const struct phm_clock_voltage_dependency_table * table =
+			hwmgr->dyn_state.vddc_dep_on_dal_pwrl;
+	const struct phm_clock_and_voltage_limits* limits =
+			&hwmgr->dyn_state.max_clock_voltage_on_ac;
+
+	info->engine_max_clock = limits->sclk;
+	info->memory_max_clock = limits->mclk;
+
+	for (i = table->count - 1; i > 0; i--) {
+
+		if (limits->vddc >= table->entries[i].v) {
+			info->level = table->entries[i].clk;
+			return 0;
+		}
+	}
+	return -EINVAL;
+}
+
+static const struct pp_hwmgr_func cz_hwmgr_funcs = {
+	.backend_init = cz_hwmgr_backend_init,
+	.backend_fini = cz_hwmgr_backend_fini,
+	.asic_setup = NULL,
+	.apply_state_adjust_rules = cz_apply_state_adjust_rules,
+	.force_dpm_level = cz_dpm_force_dpm_level,
+	.get_power_state_size = cz_get_power_state_size,
+	.powerdown_uvd = cz_dpm_powerdown_uvd,
+	.powergate_uvd = cz_dpm_powergate_uvd,
+	.powergate_vce = cz_dpm_powergate_vce,
+	.get_mclk = cz_dpm_get_mclk,
+	.get_sclk = cz_dpm_get_sclk,
+	.patch_boot_state = cz_dpm_patch_boot_state,
+	.get_pp_table_entry = cz_dpm_get_pp_table_entry,
+	.get_num_of_pp_table_entries = cz_dpm_get_num_of_pp_table_entries,
+	.print_current_perforce_level = cz_print_current_perforce_level,
+	.set_cpu_power_state = cz_set_cpu_power_state,
+	.store_cc6_data = cz_store_cc6_data,
+	.get_dal_power_level= cz_get_dal_power_level,
+};
+
+int cz_hwmgr_init(struct pp_hwmgr *hwmgr)
+{
+	struct cz_hwmgr *cz_hwmgr;
+	int ret = 0;
+
+	cz_hwmgr = kzalloc(sizeof(struct cz_hwmgr), GFP_KERNEL);
+	if (cz_hwmgr == NULL)
+		return -ENOMEM;
+
+	hwmgr->backend = cz_hwmgr;
+	hwmgr->hwmgr_func = &cz_hwmgr_funcs;
+	hwmgr->pptable_func = &pptable_funcs;
+	return ret;
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/powerplay/hwmgr/cz_hwmgr.h
@@ -0,0 +1,326 @@
+/*
+ * Copyright 2015 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#ifndef _CZ_HWMGR_H_
+#define _CZ_HWMGR_H_
+
+#include "cgs_common.h"
+#include "ppatomctrl.h"
+
+#define CZ_NUM_NBPSTATES               4
+#define CZ_NUM_NBPMEMORYCLOCK          2
+#define MAX_DISPLAY_CLOCK_LEVEL        8
+#define CZ_AT_DFLT                     30
+#define CZ_MAX_HARDWARE_POWERLEVELS    8
+#define PPCZ_VOTINGRIGHTSCLIENTS_DFLT0   0x3FFFC102
+#define CZ_MIN_DEEP_SLEEP_SCLK         800
+
+/* Carrizo device IDs */
+#define DEVICE_ID_CZ_9870             0x9870
+#define DEVICE_ID_CZ_9874             0x9874
+#define DEVICE_ID_CZ_9875             0x9875
+#define DEVICE_ID_CZ_9876             0x9876
+#define DEVICE_ID_CZ_9877             0x9877
+
+#define PHMCZ_WRITE_SMC_REGISTER(device, reg, value)                            \
+		cgs_write_ind_register(device, CGS_IND_REG__SMC, ix##reg, value)
+
+struct cz_dpm_entry {
+	uint32_t soft_min_clk;
+	uint32_t hard_min_clk;
+	uint32_t soft_max_clk;
+	uint32_t hard_max_clk;
+};
+
+struct cz_sys_info {
+	uint32_t bootup_uma_clock;
+	uint32_t bootup_engine_clock;
+	uint32_t dentist_vco_freq;
+	uint32_t nb_dpm_enable;
+	uint32_t nbp_memory_clock[CZ_NUM_NBPMEMORYCLOCK];
+	uint32_t nbp_n_clock[CZ_NUM_NBPSTATES];
+	uint16_t nbp_voltage_index[CZ_NUM_NBPSTATES];
+	uint32_t display_clock[MAX_DISPLAY_CLOCK_LEVEL];
+	uint16_t bootup_nb_voltage_index;
+	uint8_t htc_tmp_lmt;
+	uint8_t htc_hyst_lmt;
+	uint32_t system_config;
+	uint32_t uma_channel_number;
+};
+
+#define MAX_DISPLAYPHY_IDS			0x8
+#define DISPLAYPHY_LANEMASK			0xF
+#define UNKNOWN_TRANSMITTER_PHY_ID		(-1)
+
+#define DISPLAYPHY_PHYID_SHIFT			24
+#define DISPLAYPHY_LANESELECT_SHIFT		16
+
+#define DISPLAYPHY_RX_SELECT			0x1
+#define DISPLAYPHY_TX_SELECT			0x2
+#define DISPLAYPHY_CORE_SELECT			0x4
+
+#define DDI_POWERGATING_ARG(phyID, lanemask, rx, tx, core) \
+		(((uint32_t)(phyID))<<DISPLAYPHY_PHYID_SHIFT | \
+		((uint32_t)(lanemask))<<DISPLAYPHY_LANESELECT_SHIFT | \
+		((rx) ? DISPLAYPHY_RX_SELECT : 0) | \
+		((tx) ? DISPLAYPHY_TX_SELECT : 0) | \
+		((core) ? DISPLAYPHY_CORE_SELECT : 0))
+
+struct cz_display_phy_info_entry {
+	uint8_t phy_present;
+	uint8_t active_lane_mapping;
+	uint8_t display_config_type;
+	uint8_t active_number_of_lanes;
+};
+
+#define CZ_MAX_DISPLAYPHY_IDS			10
+
+struct cz_display_phy_info {
+	bool display_phy_access_initialized;
+	struct cz_display_phy_info_entry entries[CZ_MAX_DISPLAYPHY_IDS];
+};
+
+struct cz_power_level {
+	uint32_t engineClock;
+	uint8_t vddcIndex;
+	uint8_t dsDividerIndex;
+	uint8_t ssDividerIndex;
+	uint8_t allowGnbSlow;
+	uint8_t forceNBPstate;
+	uint8_t display_wm;
+	uint8_t vce_wm;
+	uint8_t numSIMDToPowerDown;
+	uint8_t hysteresis_up;
+	uint8_t rsv[3];
+};
+
+struct cz_uvd_clocks {
+	uint32_t vclk;
+	uint32_t dclk;
+	uint32_t vclk_low_divider;
+	uint32_t vclk_high_divider;
+	uint32_t dclk_low_divider;
+	uint32_t dclk_high_divider;
+};
+
+enum cz_pstate_previous_action {
+	DO_NOTHING = 1,
+	FORCE_HIGH,
+	CANCEL_FORCE_HIGH
+};
+
+struct pp_disable_nb_ps_flags {
+	union {
+		struct {
+			uint32_t entry : 1;
+			uint32_t display : 1;
+			uint32_t driver: 1;
+			uint32_t vce : 1;
+			uint32_t uvd : 1;
+			uint32_t acp : 1;
+			uint32_t reserved: 26;
+		} bits;
+		uint32_t u32All;
+	};
+};
+
+struct cz_power_state {
+	unsigned int magic;
+	uint32_t level;
+	struct cz_uvd_clocks uvd_clocks;
+	uint32_t evclk;
+	uint32_t ecclk;
+	uint32_t samclk;
+	uint32_t acpclk;
+	bool need_dfs_bypass;
+	uint32_t nbps_flags;
+	uint32_t bapm_flags;
+	uint8_t dpm_0_pg_nb_ps_low;
+	uint8_t dpm_0_pg_nb_ps_high;
+	uint8_t dpm_x_nb_ps_low;
+	uint8_t dpm_x_nb_ps_high;
+	enum cz_pstate_previous_action action;
+	struct cz_power_level levels[CZ_MAX_HARDWARE_POWERLEVELS];
+	struct pp_disable_nb_ps_flags disable_nb_ps_flag;
+};
+
+#define DPMFlags_SCLK_Enabled			0x00000001
+#define DPMFlags_UVD_Enabled			0x00000002
+#define DPMFlags_VCE_Enabled			0x00000004
+#define DPMFlags_ACP_Enabled			0x00000008
+#define DPMFlags_ForceHighestValid		0x40000000
+#define DPMFlags_Debug				0x80000000
+
+#define SMU_EnabledFeatureScoreboard_AcpDpmOn   0x00000001 /* bit 0 */
+#define SMU_EnabledFeatureScoreboard_SclkDpmOn    0x00200000
+#define SMU_EnabledFeatureScoreboard_UvdDpmOn   0x00800000 /* bit 23 */
+#define SMU_EnabledFeatureScoreboard_VceDpmOn   0x01000000 /* bit 24 */
+
+struct cc6_settings {
+	bool cc6_setting_changed;
+	bool nb_pstate_switch_disable;/* controls NB PState switch */
+	bool cpu_cc6_disable; /* controls CPU CState switch ( on or off) */
+	bool cpu_pstate_disable;
+	uint32_t cpu_pstate_separation_time;
+};
+
+struct cz_hwmgr {
+	uint32_t activity_target[CZ_MAX_HARDWARE_POWERLEVELS];
+	uint32_t dpm_interval;
+
+	uint32_t voltage_drop_threshold;
+
+	uint32_t voting_rights_clients;
+
+	uint32_t disable_driver_thermal_policy;
+
+	uint32_t static_screen_threshold;
+
+	uint32_t gfx_power_gating_threshold;
+
+	uint32_t activity_hysteresis;
+	uint32_t bootup_sclk_divider;
+	uint32_t gfx_ramp_step;
+	uint32_t gfx_ramp_delay; /* in micro-seconds */
+
+	uint32_t thermal_auto_throttling_treshold;
+
+	struct cz_sys_info sys_info;
+
+	struct cz_power_level boot_power_level;
+	struct cz_power_state *cz_current_ps;
+	struct cz_power_state *cz_requested_ps;
+
+	uint32_t mgcg_cgtt_local0;
+	uint32_t mgcg_cgtt_local1;
+
+	uint32_t tdr_clock; /* in 10khz unit */
+
+	uint32_t ddi_power_gating_disabled;
+	uint32_t disable_gfx_power_gating_in_uvd;
+	uint32_t disable_nb_ps3_in_battery;
+
+	uint32_t lock_nb_ps_in_uvd_play_back;
+
+	struct cz_display_phy_info display_phy_info;
+	uint32_t vce_slow_sclk_threshold; /* default 200mhz */
+	uint32_t dce_slow_sclk_threshold; /* default 300mhz */
+	uint32_t min_sclk_did;  /* minimum sclk divider */
+
+	bool disp_clk_bypass;
+	bool disp_clk_bypass_pending;
+	uint32_t bapm_enabled;
+	uint32_t clock_slow_down_freq;
+	uint32_t skip_clock_slow_down;
+	uint32_t enable_nb_ps_policy;
+	uint32_t voltage_drop_in_dce_power_gating;
+	uint32_t uvd_dpm_interval;
+	uint32_t override_dynamic_mgpg;
+	uint32_t lclk_deep_enabled;
+
+	uint32_t uvd_performance;
+
+	bool video_start;
+	bool battery_state;
+	uint32_t lowest_valid;
+	uint32_t highest_valid;
+	uint32_t high_voltage_threshold;
+	uint32_t is_nb_dpm_enabled;
+	struct cc6_settings cc6_settings;
+	uint32_t is_voltage_island_enabled;
+
+	bool pgacpinit;
+
+	uint8_t disp_config;
+
+	/* PowerTune */
+	uint32_t power_containment_features;
+	bool cac_enabled;
+	bool disable_uvd_power_tune_feature;
+	bool enable_ba_pm_feature;
+	bool enable_tdc_limit_feature;
+
+	uint32_t sram_end;
+	uint32_t dpm_table_start;
+	uint32_t soft_regs_start;
+
+	uint8_t uvd_level_count;
+	uint8_t vce_level_count;
+
+	uint8_t acp_level_count;
+	uint8_t samu_level_count;
+	uint32_t fps_high_threshold;
+	uint32_t fps_low_threshold;
+
+	uint32_t dpm_flags;
+	struct cz_dpm_entry sclk_dpm;
+	struct cz_dpm_entry uvd_dpm;
+	struct cz_dpm_entry vce_dpm;
+	struct cz_dpm_entry acp_dpm;
+
+	uint8_t uvd_boot_level;
+	uint8_t vce_boot_level;
+	uint8_t acp_boot_level;
+	uint8_t samu_boot_level;
+	uint8_t uvd_interval;
+	uint8_t vce_interval;
+	uint8_t acp_interval;
+	uint8_t samu_interval;
+
+	uint8_t graphics_interval;
+	uint8_t graphics_therm_throttle_enable;
+	uint8_t graphics_voltage_change_enable;
+
+	uint8_t graphics_clk_slow_enable;
+	uint8_t graphics_clk_slow_divider;
+
+	uint32_t display_cac;
+	uint32_t low_sclk_interrupt_threshold;
+
+	uint32_t dram_log_addr_h;
+	uint32_t dram_log_addr_l;
+	uint32_t dram_log_phy_addr_h;
+	uint32_t dram_log_phy_addr_l;
+	uint32_t dram_log_buff_size;
+
+	bool uvd_power_gated;
+	bool vce_power_gated;
+	bool samu_power_gated;
+	bool acp_power_gated;
+	bool acp_power_up_no_dsp;
+	uint32_t active_process_mask;
+
+	uint32_t max_sclk_level;
+	uint32_t num_of_clk_entries;
+};
+
+struct pp_hwmgr;
+
+int cz_hwmgr_init(struct pp_hwmgr *hwmgr);
+int cz_dpm_powerdown_uvd(struct pp_hwmgr *hwmgr);
+int cz_dpm_powerup_uvd(struct pp_hwmgr *hwmgr);
+int cz_dpm_powerdown_vce(struct pp_hwmgr *hwmgr);
+int cz_dpm_powerup_vce(struct pp_hwmgr *hwmgr);
+int cz_dpm_update_uvd_dpm(struct pp_hwmgr *hwmgr, bool bgate);
+int  cz_dpm_update_vce_dpm(struct pp_hwmgr *hwmgr);
+#endif /* _CZ_HWMGR_H_ */
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/powerplay/hwmgr/fiji_clockpowergating.c
@@ -0,0 +1,114 @@
+/*
+ * Copyright 2015 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#include "hwmgr.h"
+#include "fiji_clockpowergating.h"
+#include "fiji_ppsmc.h"
+#include "fiji_hwmgr.h"
+
+int fiji_phm_disable_clock_power_gating(struct pp_hwmgr *hwmgr)
+{
+	struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend);
+
+	data->uvd_power_gated = false;
+	data->vce_power_gated = false;
+	data->samu_power_gated = false;
+	data->acp_power_gated = false;
+
+	return 0;
+}
+
+int fiji_phm_powergate_uvd(struct pp_hwmgr *hwmgr, bool bgate)
+{
+	struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend);
+
+	if (data->uvd_power_gated == bgate)
+		return 0;
+
+	data->uvd_power_gated = bgate;
+
+	if (bgate)
+		fiji_update_uvd_dpm(hwmgr, true);
+	else
+		fiji_update_uvd_dpm(hwmgr, false);
+
+	return 0;
+}
+
+int fiji_phm_powergate_vce(struct pp_hwmgr *hwmgr, bool bgate)
+{
+	struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend);
+	struct phm_set_power_state_input states;
+	const struct pp_power_state  *pcurrent;
+	struct pp_power_state  *requested;
+
+	if (data->vce_power_gated == bgate)
+		return 0;
+
+	data->vce_power_gated = bgate;
+
+	pcurrent = hwmgr->current_ps;
+	requested = hwmgr->request_ps;
+
+	states.pcurrent_state = &(pcurrent->hardware);
+	states.pnew_state = &(requested->hardware);
+
+	fiji_update_vce_dpm(hwmgr, &states);
+	fiji_enable_disable_vce_dpm(hwmgr, !bgate);
+
+	return 0;
+}
+
+int fiji_phm_powergate_samu(struct pp_hwmgr *hwmgr, bool bgate)
+{
+	struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend);
+
+	if (data->samu_power_gated == bgate)
+		return 0;
+
+	data->samu_power_gated = bgate;
+
+	if (bgate)
+		fiji_update_samu_dpm(hwmgr, true);
+	else
+		fiji_update_samu_dpm(hwmgr, false);
+
+	return 0;
+}
+
+int fiji_phm_powergate_acp(struct pp_hwmgr *hwmgr, bool bgate)
+{
+	struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend);
+
+	if (data->acp_power_gated == bgate)
+		return 0;
+
+	data->acp_power_gated = bgate;
+
+	if (bgate)
+		fiji_update_acp_dpm(hwmgr, true);
+	else
+		fiji_update_acp_dpm(hwmgr, false);
+
+	return 0;
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/powerplay/hwmgr/fiji_clockpowergating.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2015 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#ifndef _FIJI_CLOCK_POWER_GATING_H_
+#define _FIJI_CLOCK_POWER_GATING_H_
+
+#include "fiji_hwmgr.h"
+#include "pp_asicblocks.h"
+
+extern int fiji_phm_powergate_vce(struct pp_hwmgr *hwmgr, bool bgate);
+extern int fiji_phm_powergate_uvd(struct pp_hwmgr *hwmgr, bool bgate);
+extern int fiji_phm_powergate_samu(struct pp_hwmgr *hwmgr, bool bgate);
+extern int fiji_phm_powergate_acp(struct pp_hwmgr *hwmgr, bool bgate);
+extern int fiji_phm_disable_clock_power_gating(struct pp_hwmgr *hwmgr);
+#endif /* _TONGA_CLOCK_POWER_GATING_H_ */
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/powerplay/hwmgr/fiji_dyn_defaults.h
@@ -0,0 +1,105 @@
+/*
+ * Copyright 2015 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#ifndef FIJI_DYN_DEFAULTS_H
+#define FIJI_DYN_DEFAULTS_H
+
+/** \file
+* Volcanic Islands Dynamic default parameters.
+*/
+
+enum FIJIdpm_TrendDetection
+{
+    FIJIAdpm_TrendDetection_AUTO,
+    FIJIAdpm_TrendDetection_UP,
+    FIJIAdpm_TrendDetection_DOWN
+};
+typedef enum FIJIdpm_TrendDetection FIJIdpm_TrendDetection;
+
+/* We need to fill in the default values!!!!!!!!!!!!!!!!!!!!!!! */
+
+/* Bit vector representing same fields as hardware register. */
+#define PPFIJI_VOTINGRIGHTSCLIENTS_DFLT0    0x3FFFC102  /* CP_Gfx_busy ????
+                                                         * HDP_busy
+                                                         * IH_busy
+                                                         * UVD_busy
+                                                         * VCE_busy
+                                                         * ACP_busy
+                                                         * SAMU_busy
+                                                         * SDMA enabled */
+#define PPFIJI_VOTINGRIGHTSCLIENTS_DFLT1    0x000400  /* FE_Gfx_busy  - Intended for primary usage.   Rest are for flexibility. ????
+                                                       * SH_Gfx_busy
+                                                       * RB_Gfx_busy
+                                                       * VCE_busy */
+
+#define PPFIJI_VOTINGRIGHTSCLIENTS_DFLT2    0xC00080  /* SH_Gfx_busy - Intended for primary usage.   Rest are for flexibility.
+                                                       * FE_Gfx_busy
+                                                       * RB_Gfx_busy
+                                                       * ACP_busy */
+
+#define PPFIJI_VOTINGRIGHTSCLIENTS_DFLT3    0xC00200  /* RB_Gfx_busy - Intended for primary usage.   Rest are for flexibility.
+                                                       * FE_Gfx_busy
+                                                       * SH_Gfx_busy
+                                                       * UVD_busy */
+
+#define PPFIJI_VOTINGRIGHTSCLIENTS_DFLT4    0xC01680  /* UVD_busy
+                                                       * VCE_busy
+                                                       * ACP_busy
+                                                       * SAMU_busy */
+
+#define PPFIJI_VOTINGRIGHTSCLIENTS_DFLT5    0xC00033  /* GFX, HDP */
+#define PPFIJI_VOTINGRIGHTSCLIENTS_DFLT6    0xC00033  /* GFX, HDP */
+#define PPFIJI_VOTINGRIGHTSCLIENTS_DFLT7    0x3FFFC000  /* GFX, HDP */
+
+
+/* thermal protection counter (units). */
+#define PPFIJI_THERMALPROTECTCOUNTER_DFLT            0x200 /* ~19us */
+
+/* static screen threshold unit */
+#define PPFIJI_STATICSCREENTHRESHOLDUNIT_DFLT    0
+
+/* static screen threshold */
+#define PPFIJI_STATICSCREENTHRESHOLD_DFLT        0x00C8
+
+/* gfx idle clock stop threshold */
+#define PPFIJI_GFXIDLECLOCKSTOPTHRESHOLD_DFLT        0x200 /* ~19us with static screen threshold unit of 0 */
+
+/* Fixed reference divider to use when building baby stepping tables. */
+#define PPFIJI_REFERENCEDIVIDER_DFLT                  4
+
+/* ULV voltage change delay time
+ * Used to be delay_vreg in N.I. split for S.I.
+ * Using N.I. delay_vreg value as default
+ * ReferenceClock = 2700
+ * VoltageResponseTime = 1000
+ * VDDCDelayTime = (VoltageResponseTime * ReferenceClock) / 1600 = 1687
+ */
+#define PPFIJI_ULVVOLTAGECHANGEDELAY_DFLT             1687
+
+#define PPFIJI_CGULVPARAMETER_DFLT			0x00040035
+#define PPFIJI_CGULVCONTROL_DFLT			0x00007450
+#define PPFIJI_TARGETACTIVITY_DFLT			30 /* 30%*/
+#define PPFIJI_MCLK_TARGETACTIVITY_DFLT		10 /* 10% */
+
+#endif
+
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/powerplay/hwmgr/fiji_hwmgr.c
@@ -0,0 +1,5127 @@
+/*
+ * Copyright 2015 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/fb.h>
+#include "linux/delay.h"
+
+#include "hwmgr.h"
+#include "fiji_smumgr.h"
+#include "atombios.h"
+#include "hardwaremanager.h"
+#include "ppatomctrl.h"
+#include "atombios.h"
+#include "cgs_common.h"
+#include "fiji_dyn_defaults.h"
+#include "fiji_powertune.h"
+#include "smu73.h"
+#include "smu/smu_7_1_3_d.h"
+#include "smu/smu_7_1_3_sh_mask.h"
+#include "gmc/gmc_8_1_d.h"
+#include "gmc/gmc_8_1_sh_mask.h"
+#include "bif/bif_5_0_d.h"
+#include "bif/bif_5_0_sh_mask.h"
+#include "dce/dce_10_0_d.h"
+#include "dce/dce_10_0_sh_mask.h"
+#include "pppcielanes.h"
+#include "fiji_hwmgr.h"
+#include "tonga_processpptables.h"
+#include "tonga_pptable.h"
+#include "pp_debug.h"
+#include "pp_acpi.h"
+#include "amd_pcie_helpers.h"
+#include "cgs_linux.h"
+#include "ppinterrupt.h"
+
+#include "fiji_clockpowergating.h"
+#include "fiji_thermal.h"
+
+#define VOLTAGE_SCALE	4
+#define SMC_RAM_END		0x40000
+#define VDDC_VDDCI_DELTA	300
+
+#define MC_SEQ_MISC0_GDDR5_SHIFT 28
+#define MC_SEQ_MISC0_GDDR5_MASK  0xf0000000
+#define MC_SEQ_MISC0_GDDR5_VALUE 5
+
+#define MC_CG_ARB_FREQ_F0           0x0a /* boot-up default */
+#define MC_CG_ARB_FREQ_F1           0x0b
+#define MC_CG_ARB_FREQ_F2           0x0c
+#define MC_CG_ARB_FREQ_F3           0x0d
+
+/* From smc_reg.h */
+#define SMC_CG_IND_START            0xc0030000
+#define SMC_CG_IND_END              0xc0040000  /* First byte after SMC_CG_IND */
+
+#define VOLTAGE_SCALE               4
+#define VOLTAGE_VID_OFFSET_SCALE1   625
+#define VOLTAGE_VID_OFFSET_SCALE2   100
+
+#define VDDC_VDDCI_DELTA            300
+
+#define ixSWRST_COMMAND_1           0x1400103
+#define MC_SEQ_CNTL__CAC_EN_MASK    0x40000000
+
+/** Values for the CG_THERMAL_CTRL::DPM_EVENT_SRC field. */
+enum DPM_EVENT_SRC {
+    DPM_EVENT_SRC_ANALOG = 0,               /* Internal analog trip point */
+    DPM_EVENT_SRC_EXTERNAL = 1,             /* External (GPIO 17) signal */
+    DPM_EVENT_SRC_DIGITAL = 2,              /* Internal digital trip point (DIG_THERM_DPM) */
+    DPM_EVENT_SRC_ANALOG_OR_EXTERNAL = 3,   /* Internal analog or external */
+    DPM_EVENT_SRC_DIGITAL_OR_EXTERNAL = 4   /* Internal digital or external */
+};
+
+
+/* [2.5%,~2.5%] Clock stretched is multiple of 2.5% vs
+ * not and [Fmin, Fmax, LDO_REFSEL, USE_FOR_LOW_FREQ]
+ */
+uint16_t fiji_clock_stretcher_lookup_table[2][4] = { {600, 1050, 3, 0},
+                                                {600, 1050, 6, 1} };
+
+/* [FF, SS] type, [] 4 voltage ranges, and
+ * [Floor Freq, Boundary Freq, VID min , VID max]
+ */
+uint32_t fiji_clock_stretcher_ddt_table[2][4][4] =
+{ { {265, 529, 120, 128}, {325, 650, 96, 119}, {430, 860, 32, 95}, {0, 0, 0, 31} },
+  { {275, 550, 104, 112}, {319, 638, 96, 103}, {360, 720, 64, 95}, {384, 768, 32, 63} } };
+
+/* [Use_For_Low_freq] value, [0%, 5%, 10%, 7.14%, 14.28%, 20%]
+ * (coming from PWR_CKS_CNTL.stretch_amount reg spec)
+ */
+uint8_t fiji_clock_stretch_amount_conversion[2][6] = { {0, 1, 3, 2, 4, 5},
+                                                  {0, 2, 4, 5, 6, 5} };
+
+const unsigned long PhwFiji_Magic = (unsigned long)(PHM_VIslands_Magic);
+
+struct fiji_power_state *cast_phw_fiji_power_state(
+				  struct pp_hw_power_state *hw_ps)
+{
+	PP_ASSERT_WITH_CODE((PhwFiji_Magic == hw_ps->magic),
+				"Invalid Powerstate Type!",
+				 return NULL;);
+
+	return (struct fiji_power_state *)hw_ps;
+}
+
+const struct fiji_power_state *cast_const_phw_fiji_power_state(
+				 const struct pp_hw_power_state *hw_ps)
+{
+	PP_ASSERT_WITH_CODE((PhwFiji_Magic == hw_ps->magic),
+				"Invalid Powerstate Type!",
+				 return NULL;);
+
+	return (const struct fiji_power_state *)hw_ps;
+}
+
+static bool fiji_is_dpm_running(struct pp_hwmgr *hwmgr)
+{
+	return (1 == PHM_READ_INDIRECT_FIELD(hwmgr->device,
+			CGS_IND_REG__SMC, FEATURE_STATUS, VOLTAGE_CONTROLLER_ON))
+			? true : false;
+}
+
+static void fiji_init_dpm_defaults(struct pp_hwmgr *hwmgr)
+{
+	struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend);
+	struct fiji_ulv_parm *ulv = &data->ulv;
+
+	ulv->cg_ulv_parameter = PPFIJI_CGULVPARAMETER_DFLT;
+	data->voting_rights_clients0 = PPFIJI_VOTINGRIGHTSCLIENTS_DFLT0;
+	data->voting_rights_clients1 = PPFIJI_VOTINGRIGHTSCLIENTS_DFLT1;
+	data->voting_rights_clients2 = PPFIJI_VOTINGRIGHTSCLIENTS_DFLT2;
+	data->voting_rights_clients3 = PPFIJI_VOTINGRIGHTSCLIENTS_DFLT3;
+	data->voting_rights_clients4 = PPFIJI_VOTINGRIGHTSCLIENTS_DFLT4;
+	data->voting_rights_clients5 = PPFIJI_VOTINGRIGHTSCLIENTS_DFLT5;
+	data->voting_rights_clients6 = PPFIJI_VOTINGRIGHTSCLIENTS_DFLT6;
+	data->voting_rights_clients7 = PPFIJI_VOTINGRIGHTSCLIENTS_DFLT7;
+
+	data->static_screen_threshold_unit =
+			PPFIJI_STATICSCREENTHRESHOLDUNIT_DFLT;
+	data->static_screen_threshold =
+			PPFIJI_STATICSCREENTHRESHOLD_DFLT;
+
+	/* Unset ABM cap as it moved to DAL.
+	 * Add PHM_PlatformCaps_NonABMSupportInPPLib
+	 * for re-direct ABM related request to DAL
+	 */
+	phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
+			PHM_PlatformCaps_ABM);
+	phm_cap_set(hwmgr->platform_descriptor.platformCaps,
+			PHM_PlatformCaps_NonABMSupportInPPLib);
+
+	phm_cap_set(hwmgr->platform_descriptor.platformCaps,
+			PHM_PlatformCaps_DynamicACTiming);
+
+	fiji_initialize_power_tune_defaults(hwmgr);
+
+	data->mclk_stutter_mode_threshold = 60000;
+	data->pcie_gen_performance.max = PP_PCIEGen1;
+	data->pcie_gen_performance.min = PP_PCIEGen3;
+	data->pcie_gen_power_saving.max = PP_PCIEGen1;
+	data->pcie_gen_power_saving.min = PP_PCIEGen3;
+	data->pcie_lane_performance.max = 0;
+	data->pcie_lane_performance.min = 16;
+	data->pcie_lane_power_saving.max = 0;
+	data->pcie_lane_power_saving.min = 16;
+
+	phm_cap_set(hwmgr->platform_descriptor.platformCaps,
+			PHM_PlatformCaps_DynamicUVDState);
+}
+
+static int fiji_get_sclk_for_voltage_evv(struct pp_hwmgr *hwmgr,
+	phm_ppt_v1_voltage_lookup_table *lookup_table,
+	uint16_t virtual_voltage_id, int32_t *sclk)
+{
+	uint8_t entryId;
+	uint8_t voltageId;
+	struct phm_ppt_v1_information *table_info =
+			(struct phm_ppt_v1_information *)(hwmgr->pptable);
+
+	PP_ASSERT_WITH_CODE(lookup_table->count != 0, "Lookup table is empty", return -EINVAL);
+
+	/* search for leakage voltage ID 0xff01 ~ 0xff08 and sckl */
+	for (entryId = 0; entryId < table_info->vdd_dep_on_sclk->count; entryId++) {
+		voltageId = table_info->vdd_dep_on_sclk->entries[entryId].vddInd;
+		if (lookup_table->entries[voltageId].us_vdd == virtual_voltage_id)
+			break;
+	}
+
+	PP_ASSERT_WITH_CODE(entryId < table_info->vdd_dep_on_sclk->count,
+			"Can't find requested voltage id in vdd_dep_on_sclk table!",
+			return -EINVAL;
+			);
+
+	*sclk = table_info->vdd_dep_on_sclk->entries[entryId].clk;
+
+	return 0;
+}
+
+/**
+* Get Leakage VDDC based on leakage ID.
+*
+* @param    hwmgr  the address of the powerplay hardware manager.
+* @return   always 0
+*/
+static int fiji_get_evv_voltages(struct pp_hwmgr *hwmgr)
+{
+	struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend);
+	uint16_t    vv_id;
+	uint16_t    vddc = 0;
+	uint16_t    evv_default = 1150;
+	uint16_t    i, j;
+	uint32_t  sclk = 0;
+	struct phm_ppt_v1_information *table_info =
+			(struct phm_ppt_v1_information *)hwmgr->pptable;
+	struct phm_ppt_v1_clock_voltage_dependency_table *sclk_table =
+			table_info->vdd_dep_on_sclk;
+	int result;
+
+	for (i = 0; i < FIJI_MAX_LEAKAGE_COUNT; i++) {
+		vv_id = ATOM_VIRTUAL_VOLTAGE_ID0 + i;
+		if (!fiji_get_sclk_for_voltage_evv(hwmgr,
+				table_info->vddc_lookup_table, vv_id, &sclk)) {
+			if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
+					PHM_PlatformCaps_ClockStretcher)) {
+				for (j = 1; j < sclk_table->count; j++) {
+					if (sclk_table->entries[j].clk == sclk &&
+							sclk_table->entries[j].cks_enable == 0) {
+						sclk += 5000;
+						break;
+					}
+				}
+			}
+
+			if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
+					PHM_PlatformCaps_EnableDriverEVV))
+				result = atomctrl_calculate_voltage_evv_on_sclk(hwmgr,
+						VOLTAGE_TYPE_VDDC, sclk, vv_id, &vddc, i, true);
+			else
+				result = -EINVAL;
+
+			if (result)
+				result = atomctrl_get_voltage_evv_on_sclk(hwmgr,
+						VOLTAGE_TYPE_VDDC, sclk,vv_id, &vddc);
+
+			/* need to make sure vddc is less than 2v or else, it could burn the ASIC. */
+			PP_ASSERT_WITH_CODE((vddc < 2000),
+					"Invalid VDDC value, greater than 2v!", result = -EINVAL;);
+
+			if (result)
+				/* 1.15V is the default safe value for Fiji */
+				vddc = evv_default;
+
+			/* the voltage should not be zero nor equal to leakage ID */
+			if (vddc != 0 && vddc != vv_id) {
+				data->vddc_leakage.actual_voltage
+				[data->vddc_leakage.count] = vddc;
+				data->vddc_leakage.leakage_id
+				[data->vddc_leakage.count] = vv_id;
+				data->vddc_leakage.count++;
+			}
+		}
+	}
+	return 0;
+}
+
+/**
+ * Change virtual leakage voltage to actual value.
+ *
+ * @param     hwmgr  the address of the powerplay hardware manager.
+ * @param     pointer to changing voltage
+ * @param     pointer to leakage table
+ */
+static void fiji_patch_with_vdd_leakage(struct pp_hwmgr *hwmgr,
+		uint16_t *voltage, struct fiji_leakage_voltage *leakage_table)
+{
+	uint32_t index;
+
+	/* search for leakage voltage ID 0xff01 ~ 0xff08 */
+	for (index = 0; index < leakage_table->count; index++) {
+		/* if this voltage matches a leakage voltage ID */
+		/* patch with actual leakage voltage */
+		if (leakage_table->leakage_id[index] == *voltage) {
+			*voltage = leakage_table->actual_voltage[index];
+			break;
+		}
+	}
+
+	if (*voltage > ATOM_VIRTUAL_VOLTAGE_ID0)
+		printk(KERN_ERR "Voltage value looks like a Leakage ID but it's not patched \n");
+}
+
+/**
+* Patch voltage lookup table by EVV leakages.
+*
+* @param     hwmgr  the address of the powerplay hardware manager.
+* @param     pointer to voltage lookup table
+* @param     pointer to leakage table
+* @return     always 0
+*/
+static int fiji_patch_lookup_table_with_leakage(struct pp_hwmgr *hwmgr,
+		phm_ppt_v1_voltage_lookup_table *lookup_table,
+		struct fiji_leakage_voltage *leakage_table)
+{
+	uint32_t i;
+
+	for (i = 0; i < lookup_table->count; i++)
+		fiji_patch_with_vdd_leakage(hwmgr,
+				&lookup_table->entries[i].us_vdd, leakage_table);
+
+	return 0;
+}
+
+static int fiji_patch_clock_voltage_limits_with_vddc_leakage(
+		struct pp_hwmgr *hwmgr, struct fiji_leakage_voltage *leakage_table,
+		uint16_t *vddc)
+{
+	struct phm_ppt_v1_information *table_info =
+			(struct phm_ppt_v1_information *)(hwmgr->pptable);
+	fiji_patch_with_vdd_leakage(hwmgr, (uint16_t *)vddc, leakage_table);
+	hwmgr->dyn_state.max_clock_voltage_on_dc.vddc =
+			table_info->max_clock_voltage_on_dc.vddc;
+	return 0;
+}
+
+static int fiji_patch_voltage_dependency_tables_with_lookup_table(
+		struct pp_hwmgr *hwmgr)
+{
+	uint8_t entryId;
+	uint8_t voltageId;
+	struct phm_ppt_v1_information *table_info =
+			(struct phm_ppt_v1_information *)(hwmgr->pptable);
+
+	struct phm_ppt_v1_clock_voltage_dependency_table *sclk_table =
+			table_info->vdd_dep_on_sclk;
+	struct phm_ppt_v1_clock_voltage_dependency_table *mclk_table =
+			table_info->vdd_dep_on_mclk;
+	struct phm_ppt_v1_mm_clock_voltage_dependency_table *mm_table =
+			table_info->mm_dep_table;
+
+	for (entryId = 0; entryId < sclk_table->count; ++entryId) {
+		voltageId = sclk_table->entries[entryId].vddInd;
+		sclk_table->entries[entryId].vddc =
+				table_info->vddc_lookup_table->entries[voltageId].us_vdd;
+	}
+
+	for (entryId = 0; entryId < mclk_table->count; ++entryId) {
+		voltageId = mclk_table->entries[entryId].vddInd;
+		mclk_table->entries[entryId].vddc =
+			table_info->vddc_lookup_table->entries[voltageId].us_vdd;
+	}
+
+	for (entryId = 0; entryId < mm_table->count; ++entryId) {
+		voltageId = mm_table->entries[entryId].vddcInd;
+		mm_table->entries[entryId].vddc =
+			table_info->vddc_lookup_table->entries[voltageId].us_vdd;
+	}
+
+	return 0;
+
+}
+
+static int fiji_calc_voltage_dependency_tables(struct pp_hwmgr *hwmgr)
+{
+	/* Need to determine if we need calculated voltage. */
+	return 0;
+}
+
+static int fiji_calc_mm_voltage_dependency_table(struct pp_hwmgr *hwmgr)
+{
+	/* Need to determine if we need calculated voltage from mm table. */
+	return 0;
+}
+
+static int fiji_sort_lookup_table(struct pp_hwmgr *hwmgr,
+		struct phm_ppt_v1_voltage_lookup_table *lookup_table)
+{
+	uint32_t table_size, i, j;
+	struct phm_ppt_v1_voltage_lookup_record tmp_voltage_lookup_record;
+	table_size = lookup_table->count;
+
+	PP_ASSERT_WITH_CODE(0 != lookup_table->count,
+		"Lookup table is empty", return -EINVAL);
+
+	/* Sorting voltages */
+	for (i = 0; i < table_size - 1; i++) {
+		for (j = i + 1; j > 0; j--) {
+			if (lookup_table->entries[j].us_vdd <
+					lookup_table->entries[j - 1].us_vdd) {
+				tmp_voltage_lookup_record = lookup_table->entries[j - 1];
+				lookup_table->entries[j - 1] = lookup_table->entries[j];
+				lookup_table->entries[j] = tmp_voltage_lookup_record;
+			}
+		}
+	}
+
+	return 0;
+}
+
+static int fiji_complete_dependency_tables(struct pp_hwmgr *hwmgr)
+{
+	int result = 0;
+	int tmp_result;
+	struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend);
+	struct phm_ppt_v1_information *table_info =
+			(struct phm_ppt_v1_information *)(hwmgr->pptable);
+
+	tmp_result = fiji_patch_lookup_table_with_leakage(hwmgr,
+			table_info->vddc_lookup_table, &(data->vddc_leakage));
+	if (tmp_result)
+		result = tmp_result;
+
+	tmp_result = fiji_patch_clock_voltage_limits_with_vddc_leakage(hwmgr,
+			&(data->vddc_leakage), &table_info->max_clock_voltage_on_dc.vddc);
+	if (tmp_result)
+		result = tmp_result;
+
+	tmp_result = fiji_patch_voltage_dependency_tables_with_lookup_table(hwmgr);
+	if (tmp_result)
+		result = tmp_result;
+
+	tmp_result = fiji_calc_voltage_dependency_tables(hwmgr);
+	if (tmp_result)
+		result = tmp_result;
+
+	tmp_result = fiji_calc_mm_voltage_dependency_table(hwmgr);
+	if (tmp_result)
+		result = tmp_result;
+
+	tmp_result = fiji_sort_lookup_table(hwmgr, table_info->vddc_lookup_table);
+	if(tmp_result)
+		result = tmp_result;
+
+	return result;
+}
+
+static int fiji_set_private_data_based_on_pptable(struct pp_hwmgr *hwmgr)
+{
+	struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend);
+	struct phm_ppt_v1_information *table_info =
+			(struct phm_ppt_v1_information *)(hwmgr->pptable);
+
+	struct phm_ppt_v1_clock_voltage_dependency_table *allowed_sclk_vdd_table =
+			table_info->vdd_dep_on_sclk;
+	struct phm_ppt_v1_clock_voltage_dependency_table *allowed_mclk_vdd_table =
+			table_info->vdd_dep_on_mclk;
+
+	PP_ASSERT_WITH_CODE(allowed_sclk_vdd_table != NULL,
+		"VDD dependency on SCLK table is missing. 	\
+		This table is mandatory", return -EINVAL);
+	PP_ASSERT_WITH_CODE(allowed_sclk_vdd_table->count >= 1,
+		"VDD dependency on SCLK table has to have is missing. 	\
+		This table is mandatory", return -EINVAL);
+
+	PP_ASSERT_WITH_CODE(allowed_mclk_vdd_table != NULL,
+		"VDD dependency on MCLK table is missing. 	\
+		This table is mandatory", return -EINVAL);
+	PP_ASSERT_WITH_CODE(allowed_mclk_vdd_table->count >= 1,
+		"VDD dependency on MCLK table has to have is missing.	 \
+		This table is mandatory", return -EINVAL);
+
+	data->min_vddc_in_pptable = (uint16_t)allowed_sclk_vdd_table->entries[0].vddc;
+	data->max_vddc_in_pptable =	(uint16_t)allowed_sclk_vdd_table->
+			entries[allowed_sclk_vdd_table->count - 1].vddc;
+
+	table_info->max_clock_voltage_on_ac.sclk =
+		allowed_sclk_vdd_table->entries[allowed_sclk_vdd_table->count - 1].clk;
+	table_info->max_clock_voltage_on_ac.mclk =
+		allowed_mclk_vdd_table->entries[allowed_mclk_vdd_table->count - 1].clk;
+	table_info->max_clock_voltage_on_ac.vddc =
+		allowed_sclk_vdd_table->entries[allowed_sclk_vdd_table->count - 1].vddc;
+	table_info->max_clock_voltage_on_ac.vddci =
+		allowed_mclk_vdd_table->entries[allowed_mclk_vdd_table->count - 1].vddci;
+
+	hwmgr->dyn_state.max_clock_voltage_on_ac.sclk =
+		table_info->max_clock_voltage_on_ac.sclk;
+	hwmgr->dyn_state.max_clock_voltage_on_ac.mclk =
+		table_info->max_clock_voltage_on_ac.mclk;
+	hwmgr->dyn_state.max_clock_voltage_on_ac.vddc =
+		table_info->max_clock_voltage_on_ac.vddc;
+	hwmgr->dyn_state.max_clock_voltage_on_ac.vddci =
+		table_info->max_clock_voltage_on_ac.vddci;
+
+	return 0;
+}
+
+static uint16_t fiji_get_current_pcie_speed(struct pp_hwmgr *hwmgr)
+{
+	uint32_t speedCntl = 0;
+
+	/* mmPCIE_PORT_INDEX rename as mmPCIE_INDEX */
+	speedCntl = cgs_read_ind_register(hwmgr->device, CGS_IND_REG__PCIE,
+			ixPCIE_LC_SPEED_CNTL);
+	return((uint16_t)PHM_GET_FIELD(speedCntl,
+			PCIE_LC_SPEED_CNTL, LC_CURRENT_DATA_RATE));
+}
+
+static int fiji_get_current_pcie_lane_number(struct pp_hwmgr *hwmgr)
+{
+	uint32_t link_width;
+
+	/* mmPCIE_PORT_INDEX rename as mmPCIE_INDEX */
+	link_width = PHM_READ_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__PCIE,
+			PCIE_LC_LINK_WIDTH_CNTL, LC_LINK_WIDTH_RD);
+
+	PP_ASSERT_WITH_CODE((7 >= link_width),
+			"Invalid PCIe lane width!", return 0);
+
+	return decode_pcie_lane_width(link_width);
+}
+
+/** Patch the Boot State to match VBIOS boot clocks and voltage.
+*
+* @param hwmgr Pointer to the hardware manager.
+* @param pPowerState The address of the PowerState instance being created.
+*
+*/
+static int fiji_patch_boot_state(struct pp_hwmgr *hwmgr,
+		struct pp_hw_power_state *hw_ps)
+{
+	struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend);
+	struct fiji_power_state *ps = (struct fiji_power_state *)hw_ps;
+	ATOM_FIRMWARE_INFO_V2_2 *fw_info;
+	uint16_t size;
+	uint8_t frev, crev;
+	int index = GetIndexIntoMasterTable(DATA, FirmwareInfo);
+
+	/* First retrieve the Boot clocks and VDDC from the firmware info table.
+	 * We assume here that fw_info is unchanged if this call fails.
+	 */
+	fw_info = (ATOM_FIRMWARE_INFO_V2_2 *)cgs_atom_get_data_table(
+			hwmgr->device, index,
+			&size, &frev, &crev);
+	if (!fw_info)
+		/* During a test, there is no firmware info table. */
+		return 0;
+
+	/* Patch the state. */
+	data->vbios_boot_state.sclk_bootup_value =
+			le32_to_cpu(fw_info->ulDefaultEngineClock);
+	data->vbios_boot_state.mclk_bootup_value =
+			le32_to_cpu(fw_info->ulDefaultMemoryClock);
+	data->vbios_boot_state.mvdd_bootup_value =
+			le16_to_cpu(fw_info->usBootUpMVDDCVoltage);
+	data->vbios_boot_state.vddc_bootup_value =
+			le16_to_cpu(fw_info->usBootUpVDDCVoltage);
+	data->vbios_boot_state.vddci_bootup_value =
+			le16_to_cpu(fw_info->usBootUpVDDCIVoltage);
+	data->vbios_boot_state.pcie_gen_bootup_value =
+			fiji_get_current_pcie_speed(hwmgr);
+	data->vbios_boot_state.pcie_lane_bootup_value =
+			(uint16_t)fiji_get_current_pcie_lane_number(hwmgr);
+
+	/* set boot power state */
+	ps->performance_levels[0].memory_clock = data->vbios_boot_state.mclk_bootup_value;
+	ps->performance_levels[0].engine_clock = data->vbios_boot_state.sclk_bootup_value;
+	ps->performance_levels[0].pcie_gen = data->vbios_boot_state.pcie_gen_bootup_value;
+	ps->performance_levels[0].pcie_lane = data->vbios_boot_state.pcie_lane_bootup_value;
+
+	return 0;
+}
+
+static int fiji_hwmgr_backend_init(struct pp_hwmgr *hwmgr)
+{
+	struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend);
+	uint32_t i;
+	struct phm_ppt_v1_information *table_info =
+			(struct phm_ppt_v1_information *)(hwmgr->pptable);
+	bool stay_in_boot;
+	int result;
+
+	data->dll_default_on = false;
+	data->sram_end = SMC_RAM_END;
+
+	for (i = 0; i < SMU73_MAX_LEVELS_GRAPHICS; i++)
+		data->activity_target[i] = FIJI_AT_DFLT;
+
+	data->vddc_vddci_delta = VDDC_VDDCI_DELTA;
+
+	data->mclk_activity_target = PPFIJI_MCLK_TARGETACTIVITY_DFLT;
+	data->mclk_dpm0_activity_target = 0xa;
+
+	data->sclk_dpm_key_disabled = 0;
+	data->mclk_dpm_key_disabled = 0;
+	data->pcie_dpm_key_disabled = 0;
+
+	phm_cap_set(hwmgr->platform_descriptor.platformCaps,
+			PHM_PlatformCaps_UnTabledHardwareInterface);
+	phm_cap_set(hwmgr->platform_descriptor.platformCaps,
+			PHM_PlatformCaps_TablelessHardwareInterface);
+
+	phm_cap_set(hwmgr->platform_descriptor.platformCaps,
+			PHM_PlatformCaps_SclkDeepSleep);
+
+	data->gpio_debug = 0;
+
+	phm_cap_set(hwmgr->platform_descriptor.platformCaps,
+			PHM_PlatformCaps_DynamicPatchPowerState);
+
+	/* need to set voltage control types before EVV patching */
+	data->voltage_control = FIJI_VOLTAGE_CONTROL_NONE;
+	data->vddci_control = FIJI_VOLTAGE_CONTROL_NONE;
+	data->mvdd_control = FIJI_VOLTAGE_CONTROL_NONE;
+
+	if (atomctrl_is_voltage_controled_by_gpio_v3(hwmgr,
+			VOLTAGE_TYPE_VDDC, VOLTAGE_OBJ_SVID2))
+		data->voltage_control = FIJI_VOLTAGE_CONTROL_BY_SVID2;
+
+	if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
+			PHM_PlatformCaps_EnableMVDDControl))
+		if (atomctrl_is_voltage_controled_by_gpio_v3(hwmgr,
+				VOLTAGE_TYPE_MVDDC, VOLTAGE_OBJ_GPIO_LUT))
+			data->mvdd_control = FIJI_VOLTAGE_CONTROL_BY_GPIO;
+
+	if (data->mvdd_control == FIJI_VOLTAGE_CONTROL_NONE)
+		phm_cap_set(hwmgr->platform_descriptor.platformCaps,
+			PHM_PlatformCaps_EnableMVDDControl);
+
+	if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
+			PHM_PlatformCaps_ControlVDDCI)) {
+		if (atomctrl_is_voltage_controled_by_gpio_v3(hwmgr,
+				VOLTAGE_TYPE_VDDCI, VOLTAGE_OBJ_GPIO_LUT))
+			data->vddci_control = FIJI_VOLTAGE_CONTROL_BY_GPIO;
+		else if (atomctrl_is_voltage_controled_by_gpio_v3(hwmgr,
+				VOLTAGE_TYPE_VDDCI, VOLTAGE_OBJ_SVID2))
+			data->vddci_control = FIJI_VOLTAGE_CONTROL_BY_SVID2;
+	}
+
+	if (data->vddci_control == FIJI_VOLTAGE_CONTROL_NONE)
+		phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
+				PHM_PlatformCaps_ControlVDDCI);
+
+	if (table_info && table_info->cac_dtp_table->usClockStretchAmount)
+		phm_cap_set(hwmgr->platform_descriptor.platformCaps,
+				PHM_PlatformCaps_ClockStretcher);
+
+	fiji_init_dpm_defaults(hwmgr);
+
+	/* Get leakage voltage based on leakage ID. */
+	fiji_get_evv_voltages(hwmgr);
+
+	/* Patch our voltage dependency table with actual leakage voltage
+	 * We need to perform leakage translation before it's used by other functions
+	 */
+	fiji_complete_dependency_tables(hwmgr);
+
+	/* Parse pptable data read from VBIOS */
+	fiji_set_private_data_based_on_pptable(hwmgr);
+
+	/* ULV Support */
+	data->ulv.ulv_supported = true; /* ULV feature is enabled by default */
+
+	/* Initalize Dynamic State Adjustment Rule Settings */
+	result = tonga_initializa_dynamic_state_adjustment_rule_settings(hwmgr);
+
+	if (!result) {
+		data->uvd_enabled = false;
+		phm_cap_set(hwmgr->platform_descriptor.platformCaps,
+				PHM_PlatformCaps_EnableSMU7ThermalManagement);
+		data->vddc_phase_shed_control = false;
+	}
+
+	stay_in_boot = phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
+			PHM_PlatformCaps_StayInBootState);
+
+	if (0 == result) {
+		struct cgs_system_info sys_info = {0};
+
+		data->is_tlu_enabled = 0;
+		hwmgr->platform_descriptor.hardwareActivityPerformanceLevels =
+				FIJI_MAX_HARDWARE_POWERLEVELS;
+		hwmgr->platform_descriptor.hardwarePerformanceLevels = 2;
+		hwmgr->platform_descriptor.minimumClocksReductionPercentage  = 50;
+
+		phm_cap_set(hwmgr->platform_descriptor.platformCaps,
+				PHM_PlatformCaps_FanSpeedInTableIsRPM);
+
+		if (table_info->cac_dtp_table->usDefaultTargetOperatingTemp &&
+				hwmgr->thermal_controller.
+				advanceFanControlParameters.ucFanControlMode) {
+			hwmgr->thermal_controller.advanceFanControlParameters.usMaxFanPWM =
+					hwmgr->thermal_controller.advanceFanControlParameters.usDefaultMaxFanPWM;
+			hwmgr->thermal_controller.advanceFanControlParameters.usMaxFanRPM =
+					hwmgr->thermal_controller.advanceFanControlParameters.usDefaultMaxFanRPM;
+			hwmgr->dyn_state.cac_dtp_table->usOperatingTempMinLimit =
+					table_info->cac_dtp_table->usOperatingTempMinLimit;
+			hwmgr->dyn_state.cac_dtp_table->usOperatingTempMaxLimit =
+					table_info->cac_dtp_table->usOperatingTempMaxLimit;
+			hwmgr->dyn_state.cac_dtp_table->usDefaultTargetOperatingTemp =
+					table_info->cac_dtp_table->usDefaultTargetOperatingTemp;
+			hwmgr->dyn_state.cac_dtp_table->usOperatingTempStep =
+					table_info->cac_dtp_table->usOperatingTempStep;
+			hwmgr->dyn_state.cac_dtp_table->usTargetOperatingTemp =
+					table_info->cac_dtp_table->usTargetOperatingTemp;
+
+			phm_cap_set(hwmgr->platform_descriptor.platformCaps,
+					PHM_PlatformCaps_ODFuzzyFanControlSupport);
+		}
+
+		sys_info.size = sizeof(struct cgs_system_info);
+		sys_info.info_id = CGS_SYSTEM_INFO_PCIE_GEN_INFO;
+		result = cgs_query_system_info(hwmgr->device, &sys_info);
+		if (result)
+			data->pcie_gen_cap = 0x30007;
+		else
+			data->pcie_gen_cap = (uint32_t)sys_info.value;
+		if (data->pcie_gen_cap & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3)
+			data->pcie_spc_cap = 20;
+		sys_info.size = sizeof(struct cgs_system_info);
+		sys_info.info_id = CGS_SYSTEM_INFO_PCIE_MLW;
+		result = cgs_query_system_info(hwmgr->device, &sys_info);
+		if (result)
+			data->pcie_lane_cap = 0x2f0000;
+		else
+			data->pcie_lane_cap = (uint32_t)sys_info.value;
+	} else {
+		/* Ignore return value in here, we are cleaning up a mess. */
+		tonga_hwmgr_backend_fini(hwmgr);
+	}
+
+	return 0;
+}
+
+/**
+ * Read clock related registers.
+ *
+ * @param    hwmgr  the address of the powerplay hardware manager.
+ * @return   always 0
+ */
+static int fiji_read_clock_registers(struct pp_hwmgr *hwmgr)
+{
+	struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend);
+
+	data->clock_registers.vCG_SPLL_FUNC_CNTL =
+		cgs_read_ind_register(hwmgr->device, CGS_IND_REG__SMC,
+				ixCG_SPLL_FUNC_CNTL);
+	data->clock_registers.vCG_SPLL_FUNC_CNTL_2 =
+		cgs_read_ind_register(hwmgr->device, CGS_IND_REG__SMC,
+				ixCG_SPLL_FUNC_CNTL_2);
+	data->clock_registers.vCG_SPLL_FUNC_CNTL_3 =
+		cgs_read_ind_register(hwmgr->device, CGS_IND_REG__SMC,
+				ixCG_SPLL_FUNC_CNTL_3);
+	data->clock_registers.vCG_SPLL_FUNC_CNTL_4 =
+		cgs_read_ind_register(hwmgr->device, CGS_IND_REG__SMC,
+				ixCG_SPLL_FUNC_CNTL_4);
+	data->clock_registers.vCG_SPLL_SPREAD_SPECTRUM =
+		cgs_read_ind_register(hwmgr->device, CGS_IND_REG__SMC,
+				ixCG_SPLL_SPREAD_SPECTRUM);
+	data->clock_registers.vCG_SPLL_SPREAD_SPECTRUM_2 =
+		cgs_read_ind_register(hwmgr->device, CGS_IND_REG__SMC,
+				ixCG_SPLL_SPREAD_SPECTRUM_2);
+
+	return 0;
+}
+
+/**
+ * Find out if memory is GDDR5.
+ *
+ * @param    hwmgr  the address of the powerplay hardware manager.
+ * @return   always 0
+ */
+static int fiji_get_memory_type(struct pp_hwmgr *hwmgr)
+{
+	struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend);
+	uint32_t temp;
+
+	temp = cgs_read_register(hwmgr->device, mmMC_SEQ_MISC0);
+
+	data->is_memory_gddr5 = (MC_SEQ_MISC0_GDDR5_VALUE ==
+			((temp & MC_SEQ_MISC0_GDDR5_MASK) >>
+			 MC_SEQ_MISC0_GDDR5_SHIFT));
+
+	return 0;
+}
+
+/**
+ * Enables Dynamic Power Management by SMC
+ *
+ * @param    hwmgr  the address of the powerplay hardware manager.
+ * @return   always 0
+ */
+static int fiji_enable_acpi_power_management(struct pp_hwmgr *hwmgr)
+{
+	PHM_WRITE_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC,
+			GENERAL_PWRMGT, STATIC_PM_EN, 1);
+
+	return 0;
+}
+
+/**
+ * Initialize PowerGating States for different engines
+ *
+ * @param    hwmgr  the address of the powerplay hardware manager.
+ * @return   always 0
+ */
+static int fiji_init_power_gate_state(struct pp_hwmgr *hwmgr)
+{
+	struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend);
+
+	data->uvd_power_gated = false;
+	data->vce_power_gated = false;
+	data->samu_power_gated = false;
+	data->acp_power_gated = false;
+	data->pg_acp_init = true;
+
+	return 0;
+}
+
+static int fiji_init_sclk_threshold(struct pp_hwmgr *hwmgr)
+{
+	struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend);
+	data->low_sclk_interrupt_threshold = 0;
+
+	return 0;
+}
+
+static int fiji_setup_asic_task(struct pp_hwmgr *hwmgr)
+{
+	int tmp_result, result = 0;
+
+	tmp_result = fiji_read_clock_registers(hwmgr);
+	PP_ASSERT_WITH_CODE((0 == tmp_result),
+			"Failed to read clock registers!", result = tmp_result);
+
+	tmp_result = fiji_get_memory_type(hwmgr);
+	PP_ASSERT_WITH_CODE((0 == tmp_result),
+			"Failed to get memory type!", result = tmp_result);
+
+	tmp_result = fiji_enable_acpi_power_management(hwmgr);
+	PP_ASSERT_WITH_CODE((0 == tmp_result),
+			"Failed to enable ACPI power management!", result = tmp_result);
+
+	tmp_result = fiji_init_power_gate_state(hwmgr);
+	PP_ASSERT_WITH_CODE((0 == tmp_result),
+			"Failed to init power gate state!", result = tmp_result);
+
+	tmp_result = tonga_get_mc_microcode_version(hwmgr);
+	PP_ASSERT_WITH_CODE((0 == tmp_result),
+			"Failed to get MC microcode version!", result = tmp_result);
+
+	tmp_result = fiji_init_sclk_threshold(hwmgr);
+	PP_ASSERT_WITH_CODE((0 == tmp_result),
+			"Failed to init sclk threshold!", result = tmp_result);
+
+	return result;
+}
+
+/**
+* Checks if we want to support voltage control
+*
+* @param    hwmgr  the address of the powerplay hardware manager.
+*/
+static bool fiji_voltage_control(const struct pp_hwmgr *hwmgr)
+{
+	const struct fiji_hwmgr *data =
+			(const struct fiji_hwmgr *)(hwmgr->backend);
+
+	return (FIJI_VOLTAGE_CONTROL_NONE != data->voltage_control);
+}
+
+/**
+* Enable voltage control
+*
+* @param    hwmgr  the address of the powerplay hardware manager.
+* @return   always 0
+*/
+static int fiji_enable_voltage_control(struct pp_hwmgr *hwmgr)
+{
+	/* enable voltage control */
+	PHM_WRITE_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC,
+			GENERAL_PWRMGT, VOLT_PWRMGT_EN, 1);
+
+	return 0;
+}
+
+/**
+* Remove repeated voltage values and create table with unique values.
+*
+* @param    hwmgr  the address of the powerplay hardware manager.
+* @param    vol_table  the pointer to changing voltage table
+* @return    0 in success
+*/
+
+static int fiji_trim_voltage_table(struct pp_hwmgr *hwmgr,
+		struct pp_atomctrl_voltage_table *vol_table)
+{
+	uint32_t i, j;
+	uint16_t vvalue;
+	bool found = false;
+	struct pp_atomctrl_voltage_table *table;
+
+	PP_ASSERT_WITH_CODE((NULL != vol_table),
+			"Voltage Table empty.", return -EINVAL);
+	table = kzalloc(sizeof(struct pp_atomctrl_voltage_table),
+			GFP_KERNEL);
+
+	if (NULL == table)
+		return -ENOMEM;
+
+	table->mask_low = vol_table->mask_low;
+	table->phase_delay = vol_table->phase_delay;
+
+	for (i = 0; i < vol_table->count; i++) {
+		vvalue = vol_table->entries[i].value;
+		found = false;
+
+		for (j = 0; j < table->count; j++) {
+			if (vvalue == table->entries[j].value) {
+				found = true;
+				break;
+			}
+		}
+
+		if (!found) {
+			table->entries[table->count].value = vvalue;
+			table->entries[table->count].smio_low =
+					vol_table->entries[i].smio_low;
+			table->count++;
+		}
+	}
+
+	memcpy(vol_table, table, sizeof(struct pp_atomctrl_voltage_table));
+	kfree(table);
+
+	return 0;
+}
+
+static int fiji_get_svi2_mvdd_voltage_table(struct pp_hwmgr *hwmgr,
+		phm_ppt_v1_clock_voltage_dependency_table *dep_table)
+{
+	uint32_t i;
+	int result;
+	struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend);
+	struct pp_atomctrl_voltage_table *vol_table = &(data->mvdd_voltage_table);
+
+	PP_ASSERT_WITH_CODE((0 != dep_table->count),
+			"Voltage Dependency Table empty.", return -EINVAL);
+
+	vol_table->mask_low = 0;
+	vol_table->phase_delay = 0;
+	vol_table->count = dep_table->count;
+
+	for (i = 0; i < dep_table->count; i++) {
+		vol_table->entries[i].value = dep_table->entries[i].mvdd;
+		vol_table->entries[i].smio_low = 0;
+	}
+
+	result = fiji_trim_voltage_table(hwmgr, vol_table);
+	PP_ASSERT_WITH_CODE((0 == result),
+			"Failed to trim MVDD table.", return result);
+
+	return 0;
+}
+
+static int fiji_get_svi2_vddci_voltage_table(struct pp_hwmgr *hwmgr,
+		phm_ppt_v1_clock_voltage_dependency_table *dep_table)
+{
+	uint32_t i;
+	int result;
+	struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend);
+	struct pp_atomctrl_voltage_table *vol_table = &(data->vddci_voltage_table);
+
+	PP_ASSERT_WITH_CODE((0 != dep_table->count),
+			"Voltage Dependency Table empty.", return -EINVAL);
+
+	vol_table->mask_low = 0;
+	vol_table->phase_delay = 0;
+	vol_table->count = dep_table->count;
+
+	for (i = 0; i < dep_table->count; i++) {
+		vol_table->entries[i].value = dep_table->entries[i].vddci;
+		vol_table->entries[i].smio_low = 0;
+	}
+
+	result = fiji_trim_voltage_table(hwmgr, vol_table);
+	PP_ASSERT_WITH_CODE((0 == result),
+			"Failed to trim VDDCI table.", return result);
+
+	return 0;
+}
+
+static int fiji_get_svi2_vdd_voltage_table(struct pp_hwmgr *hwmgr,
+		phm_ppt_v1_voltage_lookup_table *lookup_table)
+{
+	int i = 0;
+	struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend);
+	struct pp_atomctrl_voltage_table *vol_table = &(data->vddc_voltage_table);
+
+	PP_ASSERT_WITH_CODE((0 != lookup_table->count),
+			"Voltage Lookup Table empty.", return -EINVAL);
+
+	vol_table->mask_low = 0;
+	vol_table->phase_delay = 0;
+
+	vol_table->count = lookup_table->count;
+
+	for (i = 0; i < vol_table->count; i++) {
+		vol_table->entries[i].value = lookup_table->entries[i].us_vdd;
+		vol_table->entries[i].smio_low = 0;
+	}
+
+	return 0;
+}
+
+/* ---- Voltage Tables ----
+ * If the voltage table would be bigger than
+ * what will fit into the state table on
+ * the SMC keep only the higher entries.
+ */
+static void fiji_trim_voltage_table_to_fit_state_table(struct pp_hwmgr *hwmgr,
+		uint32_t max_vol_steps, struct pp_atomctrl_voltage_table *vol_table)
+{
+	unsigned int i, diff;
+
+	if (vol_table->count <= max_vol_steps)
+		return;
+
+	diff = vol_table->count - max_vol_steps;
+
+	for (i = 0; i < max_vol_steps; i++)
+		vol_table->entries[i] = vol_table->entries[i + diff];
+
+	vol_table->count = max_vol_steps;
+
+	return;
+}
+
+/**
+* Create Voltage Tables.
+*
+* @param    hwmgr  the address of the powerplay hardware manager.
+* @return   always 0
+*/
+static int fiji_construct_voltage_tables(struct pp_hwmgr *hwmgr)
+{
+	struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend);
+	struct phm_ppt_v1_information *table_info =
+			(struct phm_ppt_v1_information *)hwmgr->pptable;
+	int result;
+
+	if (FIJI_VOLTAGE_CONTROL_BY_GPIO == data->mvdd_control) {
+		result = atomctrl_get_voltage_table_v3(hwmgr,
+				VOLTAGE_TYPE_MVDDC,	VOLTAGE_OBJ_GPIO_LUT,
+				&(data->mvdd_voltage_table));
+		PP_ASSERT_WITH_CODE((0 == result),
+				"Failed to retrieve MVDD table.",
+				return result);
+	} else if (FIJI_VOLTAGE_CONTROL_BY_SVID2 == data->mvdd_control) {
+		result = fiji_get_svi2_mvdd_voltage_table(hwmgr,
+				table_info->vdd_dep_on_mclk);
+		PP_ASSERT_WITH_CODE((0 == result),
+				"Failed to retrieve SVI2 MVDD table from dependancy table.",
+				return result;);
+	}
+
+	if (FIJI_VOLTAGE_CONTROL_BY_GPIO == data->vddci_control) {
+		result = atomctrl_get_voltage_table_v3(hwmgr,
+				VOLTAGE_TYPE_VDDCI, VOLTAGE_OBJ_GPIO_LUT,
+				&(data->vddci_voltage_table));
+		PP_ASSERT_WITH_CODE((0 == result),
+				"Failed to retrieve VDDCI table.",
+				return result);
+	} else if (FIJI_VOLTAGE_CONTROL_BY_SVID2 == data->vddci_control) {
+		result = fiji_get_svi2_vddci_voltage_table(hwmgr,
+				table_info->vdd_dep_on_mclk);
+		PP_ASSERT_WITH_CODE((0 == result),
+				"Failed to retrieve SVI2 VDDCI table from dependancy table.",
+				return result);
+	}
+
+	if(FIJI_VOLTAGE_CONTROL_BY_SVID2 == data->voltage_control) {
+		result = fiji_get_svi2_vdd_voltage_table(hwmgr,
+				table_info->vddc_lookup_table);
+		PP_ASSERT_WITH_CODE((0 == result),
+				"Failed to retrieve SVI2 VDDC table from lookup table.",
+				return result);
+	}
+
+	PP_ASSERT_WITH_CODE(
+			(data->vddc_voltage_table.count <= (SMU73_MAX_LEVELS_VDDC)),
+			"Too many voltage values for VDDC. Trimming to fit state table.",
+			fiji_trim_voltage_table_to_fit_state_table(hwmgr,
+					SMU73_MAX_LEVELS_VDDC, &(data->vddc_voltage_table)));
+
+	PP_ASSERT_WITH_CODE(
+			(data->vddci_voltage_table.count <= (SMU73_MAX_LEVELS_VDDCI)),
+			"Too many voltage values for VDDCI. Trimming to fit state table.",
+			fiji_trim_voltage_table_to_fit_state_table(hwmgr,
+					SMU73_MAX_LEVELS_VDDCI, &(data->vddci_voltage_table)));
+
+	PP_ASSERT_WITH_CODE(
+			(data->mvdd_voltage_table.count <= (SMU73_MAX_LEVELS_MVDD)),
+			"Too many voltage values for MVDD. Trimming to fit state table.",
+			fiji_trim_voltage_table_to_fit_state_table(hwmgr,
+					SMU73_MAX_LEVELS_MVDD, &(data->mvdd_voltage_table)));
+
+	return 0;
+}
+
+static int fiji_initialize_mc_reg_table(struct pp_hwmgr *hwmgr)
+{
+	/* Program additional LP registers
+	 * that are no longer programmed by VBIOS
+	 */
+	cgs_write_register(hwmgr->device, mmMC_SEQ_RAS_TIMING_LP,
+			cgs_read_register(hwmgr->device, mmMC_SEQ_RAS_TIMING));
+	cgs_write_register(hwmgr->device, mmMC_SEQ_CAS_TIMING_LP,
+			cgs_read_register(hwmgr->device, mmMC_SEQ_CAS_TIMING));
+	cgs_write_register(hwmgr->device, mmMC_SEQ_MISC_TIMING2_LP,
+			cgs_read_register(hwmgr->device, mmMC_SEQ_MISC_TIMING2));
+	cgs_write_register(hwmgr->device, mmMC_SEQ_WR_CTL_D1_LP,
+			cgs_read_register(hwmgr->device, mmMC_SEQ_WR_CTL_D1));
+	cgs_write_register(hwmgr->device, mmMC_SEQ_RD_CTL_D0_LP,
+			cgs_read_register(hwmgr->device, mmMC_SEQ_RD_CTL_D0));
+	cgs_write_register(hwmgr->device, mmMC_SEQ_RD_CTL_D1_LP,
+			cgs_read_register(hwmgr->device, mmMC_SEQ_RD_CTL_D1));
+	cgs_write_register(hwmgr->device, mmMC_SEQ_PMG_TIMING_LP,
+			cgs_read_register(hwmgr->device, mmMC_SEQ_PMG_TIMING));
+
+	return 0;
+}
+
+/**
+* Programs static screed detection parameters
+*
+* @param    hwmgr  the address of the powerplay hardware manager.
+* @return   always 0
+*/
+static int fiji_program_static_screen_threshold_parameters(
+		struct pp_hwmgr *hwmgr)
+{
+	struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend);
+
+	/* Set static screen threshold unit */
+	PHM_WRITE_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC,
+			CG_STATIC_SCREEN_PARAMETER, STATIC_SCREEN_THRESHOLD_UNIT,
+			data->static_screen_threshold_unit);
+	/* Set static screen threshold */
+	PHM_WRITE_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC,
+			CG_STATIC_SCREEN_PARAMETER, STATIC_SCREEN_THRESHOLD,
+			data->static_screen_threshold);
+
+	return 0;
+}
+
+/**
+* Setup display gap for glitch free memory clock switching.
+*
+* @param    hwmgr  the address of the powerplay hardware manager.
+* @return   always  0
+*/
+static int fiji_enable_display_gap(struct pp_hwmgr *hwmgr)
+{
+	uint32_t displayGap =
+			cgs_read_ind_register(hwmgr->device, CGS_IND_REG__SMC,
+					ixCG_DISPLAY_GAP_CNTL);
+
+	displayGap = PHM_SET_FIELD(displayGap, CG_DISPLAY_GAP_CNTL,
+			DISP_GAP, DISPLAY_GAP_IGNORE);
+
+	displayGap = PHM_SET_FIELD(displayGap, CG_DISPLAY_GAP_CNTL,
+			DISP_GAP_MCHG, DISPLAY_GAP_VBLANK);
+
+	cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC,
+			ixCG_DISPLAY_GAP_CNTL, displayGap);
+
+	return 0;
+}
+
+/**
+* Programs activity state transition voting clients
+*
+* @param    hwmgr  the address of the powerplay hardware manager.
+* @return   always  0
+*/
+static int fiji_program_voting_clients(struct pp_hwmgr *hwmgr)
+{
+	struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend);
+
+	/* Clear reset for voting clients before enabling DPM */
+	PHM_WRITE_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC,
+			SCLK_PWRMGT_CNTL, RESET_SCLK_CNT, 0);
+	PHM_WRITE_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC,
+			SCLK_PWRMGT_CNTL, RESET_BUSY_CNT, 0);
+
+	cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC,
+			ixCG_FREQ_TRAN_VOTING_0, data->voting_rights_clients0);
+	cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC,
+			ixCG_FREQ_TRAN_VOTING_1, data->voting_rights_clients1);
+	cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC,
+			ixCG_FREQ_TRAN_VOTING_2, data->voting_rights_clients2);
+	cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC,
+			ixCG_FREQ_TRAN_VOTING_3, data->voting_rights_clients3);
+	cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC,
+			ixCG_FREQ_TRAN_VOTING_4, data->voting_rights_clients4);
+	cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC,
+			ixCG_FREQ_TRAN_VOTING_5, data->voting_rights_clients5);
+	cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC,
+			ixCG_FREQ_TRAN_VOTING_6, data->voting_rights_clients6);
+	cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC,
+			ixCG_FREQ_TRAN_VOTING_7, data->voting_rights_clients7);
+
+	return 0;
+}
+
+/**
+* Get the location of various tables inside the FW image.
+*
+* @param    hwmgr  the address of the powerplay hardware manager.
+* @return   always  0
+*/
+static int fiji_process_firmware_header(struct pp_hwmgr *hwmgr)
+{
+	struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend);
+	struct fiji_smumgr *smu_data = (struct fiji_smumgr *)(hwmgr->smumgr->backend);
+	uint32_t tmp;
+	int result;
+	bool error = false;
+
+	result = fiji_read_smc_sram_dword(hwmgr->smumgr,
+			SMU7_FIRMWARE_HEADER_LOCATION +
+			offsetof(SMU73_Firmware_Header, DpmTable),
+			&tmp, data->sram_end);
+
+	if (0 == result)
+		data->dpm_table_start = tmp;
+
+	error |= (0 != result);
+
+	result = fiji_read_smc_sram_dword(hwmgr->smumgr,
+			SMU7_FIRMWARE_HEADER_LOCATION +
+			offsetof(SMU73_Firmware_Header, SoftRegisters),
+			&tmp, data->sram_end);
+
+	if (!result) {
+		data->soft_regs_start = tmp;
+		smu_data->soft_regs_start = tmp;
+	}
+
+	error |= (0 != result);
+
+	result = fiji_read_smc_sram_dword(hwmgr->smumgr,
+			SMU7_FIRMWARE_HEADER_LOCATION +
+			offsetof(SMU73_Firmware_Header, mcRegisterTable),
+			&tmp, data->sram_end);
+
+	if (!result)
+		data->mc_reg_table_start = tmp;
+
+	result = fiji_read_smc_sram_dword(hwmgr->smumgr,
+			SMU7_FIRMWARE_HEADER_LOCATION +
+			offsetof(SMU73_Firmware_Header, FanTable),
+			&tmp, data->sram_end);
+
+	if (!result)
+		data->fan_table_start = tmp;
+
+	error |= (0 != result);
+
+	result = fiji_read_smc_sram_dword(hwmgr->smumgr,
+			SMU7_FIRMWARE_HEADER_LOCATION +
+			offsetof(SMU73_Firmware_Header, mcArbDramTimingTable),
+			&tmp, data->sram_end);
+
+	if (!result)
+		data->arb_table_start = tmp;
+
+	error |= (0 != result);
+
+	result = fiji_read_smc_sram_dword(hwmgr->smumgr,
+			SMU7_FIRMWARE_HEADER_LOCATION +
+			offsetof(SMU73_Firmware_Header, Version),
+			&tmp, data->sram_end);
+
+	if (!result)
+		hwmgr->microcode_version_info.SMC = tmp;
+
+	error |= (0 != result);
+
+	return error ? -1 : 0;
+}
+
+/* Copy one arb setting to another and then switch the active set.
+ * arb_src and arb_dest is one of the MC_CG_ARB_FREQ_Fx constants.
+ */
+static int fiji_copy_and_switch_arb_sets(struct pp_hwmgr *hwmgr,
+		uint32_t arb_src, uint32_t arb_dest)
+{
+	uint32_t mc_arb_dram_timing;
+	uint32_t mc_arb_dram_timing2;
+	uint32_t burst_time;
+	uint32_t mc_cg_config;
+
+	switch (arb_src) {
+	case MC_CG_ARB_FREQ_F0:
+		mc_arb_dram_timing  = cgs_read_register(hwmgr->device, mmMC_ARB_DRAM_TIMING);
+		mc_arb_dram_timing2 = cgs_read_register(hwmgr->device, mmMC_ARB_DRAM_TIMING2);
+		burst_time = PHM_READ_FIELD(hwmgr->device, MC_ARB_BURST_TIME, STATE0);
+		break;
+	case MC_CG_ARB_FREQ_F1:
+		mc_arb_dram_timing  = cgs_read_register(hwmgr->device, mmMC_ARB_DRAM_TIMING_1);
+		mc_arb_dram_timing2 = cgs_read_register(hwmgr->device, mmMC_ARB_DRAM_TIMING2_1);
+		burst_time = PHM_READ_FIELD(hwmgr->device, MC_ARB_BURST_TIME, STATE1);
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	switch (arb_dest) {
+	case MC_CG_ARB_FREQ_F0:
+		cgs_write_register(hwmgr->device, mmMC_ARB_DRAM_TIMING, mc_arb_dram_timing);
+		cgs_write_register(hwmgr->device, mmMC_ARB_DRAM_TIMING2, mc_arb_dram_timing2);
+		PHM_WRITE_FIELD(hwmgr->device, MC_ARB_BURST_TIME, STATE0, burst_time);
+		break;
+	case MC_CG_ARB_FREQ_F1:
+		cgs_write_register(hwmgr->device, mmMC_ARB_DRAM_TIMING_1, mc_arb_dram_timing);
+		cgs_write_register(hwmgr->device, mmMC_ARB_DRAM_TIMING2_1, mc_arb_dram_timing2);
+		PHM_WRITE_FIELD(hwmgr->device, MC_ARB_BURST_TIME, STATE1, burst_time);
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	mc_cg_config = cgs_read_register(hwmgr->device, mmMC_CG_CONFIG);
+	mc_cg_config |= 0x0000000F;
+	cgs_write_register(hwmgr->device, mmMC_CG_CONFIG, mc_cg_config);
+	PHM_WRITE_FIELD(hwmgr->device, MC_ARB_CG, CG_ARB_REQ, arb_dest);
+
+	return 0;
+}
+
+/**
+* Initial switch from ARB F0->F1
+*
+* @param    hwmgr  the address of the powerplay hardware manager.
+* @return   always 0
+* This function is to be called from the SetPowerState table.
+*/
+static int fiji_initial_switch_from_arbf0_to_f1(struct pp_hwmgr *hwmgr)
+{
+	return fiji_copy_and_switch_arb_sets(hwmgr,
+			MC_CG_ARB_FREQ_F0, MC_CG_ARB_FREQ_F1);
+}
+
+static int fiji_reset_single_dpm_table(struct pp_hwmgr *hwmgr,
+		struct fiji_single_dpm_table *dpm_table, uint32_t count)
+{
+	int i;
+	PP_ASSERT_WITH_CODE(count <= MAX_REGULAR_DPM_NUMBER,
+			"Fatal error, can not set up single DPM table entries "
+			"to exceed max number!",);
+
+	dpm_table->count = count;
+	for (i = 0; i < MAX_REGULAR_DPM_NUMBER; i++)
+		dpm_table->dpm_levels[i].enabled = false;
+
+	return 0;
+}
+
+static void fiji_setup_pcie_table_entry(
+	struct fiji_single_dpm_table *dpm_table,
+	uint32_t index, uint32_t pcie_gen,
+	uint32_t pcie_lanes)
+{
+	dpm_table->dpm_levels[index].value = pcie_gen;
+	dpm_table->dpm_levels[index].param1 = pcie_lanes;
+	dpm_table->dpm_levels[index].enabled = 1;
+}
+
+static int fiji_setup_default_pcie_table(struct pp_hwmgr *hwmgr)
+{
+	struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend);
+	struct phm_ppt_v1_information *table_info =
+			(struct phm_ppt_v1_information *)(hwmgr->pptable);
+	struct phm_ppt_v1_pcie_table *pcie_table = table_info->pcie_table;
+	uint32_t i, max_entry;
+
+	PP_ASSERT_WITH_CODE((data->use_pcie_performance_levels ||
+			data->use_pcie_power_saving_levels), "No pcie performance levels!",
+			return -EINVAL);
+
+	if (data->use_pcie_performance_levels &&
+			!data->use_pcie_power_saving_levels) {
+		data->pcie_gen_power_saving = data->pcie_gen_performance;
+		data->pcie_lane_power_saving = data->pcie_lane_performance;
+	} else if (!data->use_pcie_performance_levels &&
+			data->use_pcie_power_saving_levels) {
+		data->pcie_gen_performance = data->pcie_gen_power_saving;
+		data->pcie_lane_performance = data->pcie_lane_power_saving;
+	}
+
+	fiji_reset_single_dpm_table(hwmgr,
+			&data->dpm_table.pcie_speed_table, SMU73_MAX_LEVELS_LINK);
+
+	if (pcie_table != NULL) {
+		/* max_entry is used to make sure we reserve one PCIE level
+		 * for boot level (fix for A+A PSPP issue).
+		 * If PCIE table from PPTable have ULV entry + 8 entries,
+		 * then ignore the last entry.*/
+		max_entry = (SMU73_MAX_LEVELS_LINK < pcie_table->count) ?
+				SMU73_MAX_LEVELS_LINK : pcie_table->count;
+		for (i = 1; i < max_entry; i++) {
+			fiji_setup_pcie_table_entry(&data->dpm_table.pcie_speed_table, i - 1,
+					get_pcie_gen_support(data->pcie_gen_cap,
+							pcie_table->entries[i].gen_speed),
+					get_pcie_lane_support(data->pcie_lane_cap,
+							pcie_table->entries[i].lane_width));
+		}
+		data->dpm_table.pcie_speed_table.count = max_entry - 1;
+	} else {
+		/* Hardcode Pcie Table */
+		fiji_setup_pcie_table_entry(&data->dpm_table.pcie_speed_table, 0,
+				get_pcie_gen_support(data->pcie_gen_cap,
+						PP_Min_PCIEGen),
+				get_pcie_lane_support(data->pcie_lane_cap,
+						PP_Max_PCIELane));
+		fiji_setup_pcie_table_entry(&data->dpm_table.pcie_speed_table, 1,
+				get_pcie_gen_support(data->pcie_gen_cap,
+						PP_Min_PCIEGen),
+				get_pcie_lane_support(data->pcie_lane_cap,
+						PP_Max_PCIELane));
+		fiji_setup_pcie_table_entry(&data->dpm_table.pcie_speed_table, 2,
+				get_pcie_gen_support(data->pcie_gen_cap,
+						PP_Max_PCIEGen),
+				get_pcie_lane_support(data->pcie_lane_cap,
+						PP_Max_PCIELane));
+		fiji_setup_pcie_table_entry(&data->dpm_table.pcie_speed_table, 3,
+				get_pcie_gen_support(data->pcie_gen_cap,
+						PP_Max_PCIEGen),
+				get_pcie_lane_support(data->pcie_lane_cap,
+						PP_Max_PCIELane));
+		fiji_setup_pcie_table_entry(&data->dpm_table.pcie_speed_table, 4,
+				get_pcie_gen_support(data->pcie_gen_cap,
+						PP_Max_PCIEGen),
+				get_pcie_lane_support(data->pcie_lane_cap,
+						PP_Max_PCIELane));
+		fiji_setup_pcie_table_entry(&data->dpm_table.pcie_speed_table, 5,
+				get_pcie_gen_support(data->pcie_gen_cap,
+						PP_Max_PCIEGen),
+				get_pcie_lane_support(data->pcie_lane_cap,
+						PP_Max_PCIELane));
+
+		data->dpm_table.pcie_speed_table.count = 6;
+	}
+	/* Populate last level for boot PCIE level, but do not increment count. */
+	fiji_setup_pcie_table_entry(&data->dpm_table.pcie_speed_table,
+			data->dpm_table.pcie_speed_table.count,
+			get_pcie_gen_support(data->pcie_gen_cap,
+					PP_Min_PCIEGen),
+			get_pcie_lane_support(data->pcie_lane_cap,
+					PP_Max_PCIELane));
+
+	return 0;
+}
+
+/*
+ * This function is to initalize all DPM state tables
+ * for SMU7 based on the dependency table.
+ * Dynamic state patching function will then trim these
+ * state tables to the allowed range based
+ * on the power policy or external client requests,
+ * such as UVD request, etc.
+ */
+static int fiji_setup_default_dpm_tables(struct pp_hwmgr *hwmgr)
+{
+	struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend);
+	struct phm_ppt_v1_information *table_info =
+			(struct phm_ppt_v1_information *)(hwmgr->pptable);
+	uint32_t i;
+
+	struct phm_ppt_v1_clock_voltage_dependency_table *dep_sclk_table =
+			table_info->vdd_dep_on_sclk;
+	struct phm_ppt_v1_clock_voltage_dependency_table *dep_mclk_table =
+			table_info->vdd_dep_on_mclk;
+
+	PP_ASSERT_WITH_CODE(dep_sclk_table != NULL,
+			"SCLK dependency table is missing. This table is mandatory",
+			return -EINVAL);
+	PP_ASSERT_WITH_CODE(dep_sclk_table->count >= 1,
+			"SCLK dependency table has to have is missing. "
+			"This table is mandatory",
+			return -EINVAL);
+
+	PP_ASSERT_WITH_CODE(dep_mclk_table != NULL,
+			"MCLK dependency table is missing. This table is mandatory",
+			return -EINVAL);
+	PP_ASSERT_WITH_CODE(dep_mclk_table->count >= 1,
+			"MCLK dependency table has to have is missing. "
+			"This table is mandatory",
+			return -EINVAL);
+
+	/* clear the state table to reset everything to default */
+	fiji_reset_single_dpm_table(hwmgr,
+			&data->dpm_table.sclk_table, SMU73_MAX_LEVELS_GRAPHICS);
+	fiji_reset_single_dpm_table(hwmgr,
+			&data->dpm_table.mclk_table, SMU73_MAX_LEVELS_MEMORY);
+
+	/* Initialize Sclk DPM table based on allow Sclk values */
+	data->dpm_table.sclk_table.count = 0;
+	for (i = 0; i < dep_sclk_table->count; i++) {
+		if (i == 0 || data->dpm_table.sclk_table.dpm_levels
+				[data->dpm_table.sclk_table.count - 1].value !=
+						dep_sclk_table->entries[i].clk) {
+			data->dpm_table.sclk_table.dpm_levels
+			[data->dpm_table.sclk_table.count].value =
+					dep_sclk_table->entries[i].clk;
+			data->dpm_table.sclk_table.dpm_levels
+			[data->dpm_table.sclk_table.count].enabled =
+					(i == 0) ? true : false;
+			data->dpm_table.sclk_table.count++;
+		}
+	}
+
+	/* Initialize Mclk DPM table based on allow Mclk values */
+	data->dpm_table.mclk_table.count = 0;
+	for (i=0; i<dep_mclk_table->count; i++) {
+		if ( i==0 || data->dpm_table.mclk_table.dpm_levels
+				[data->dpm_table.mclk_table.count - 1].value !=
+						dep_mclk_table->entries[i].clk) {
+			data->dpm_table.mclk_table.dpm_levels
+			[data->dpm_table.mclk_table.count].value =
+					dep_mclk_table->entries[i].clk;
+			data->dpm_table.mclk_table.dpm_levels
+			[data->dpm_table.mclk_table.count].enabled =
+					(i == 0) ? true : false;
+			data->dpm_table.mclk_table.count++;
+		}
+	}
+
+	/* setup PCIE gen speed levels */
+	fiji_setup_default_pcie_table(hwmgr);
+
+	/* save a copy of the default DPM table */
+	memcpy(&(data->golden_dpm_table), &(data->dpm_table),
+			sizeof(struct fiji_dpm_table));
+
+	return 0;
+}
+
+/**
+ * @brief PhwFiji_GetVoltageOrder
+ *  Returns index of requested voltage record in lookup(table)
+ * @param lookup_table - lookup list to search in
+ * @param voltage - voltage to look for
+ * @return 0 on success
+ */
+uint8_t fiji_get_voltage_index(
+		struct phm_ppt_v1_voltage_lookup_table *lookup_table, uint16_t voltage)
+{
+	uint8_t count = (uint8_t) (lookup_table->count);
+	uint8_t i;
+
+	PP_ASSERT_WITH_CODE((NULL != lookup_table),
+			"Lookup Table empty.", return 0);
+	PP_ASSERT_WITH_CODE((0 != count),
+			"Lookup Table empty.", return 0);
+
+	for (i = 0; i < lookup_table->count; i++) {
+		/* find first voltage equal or bigger than requested */
+		if (lookup_table->entries[i].us_vdd >= voltage)
+			return i;
+	}
+	/* voltage is bigger than max voltage in the table */
+	return i - 1;
+}
+
+/**
+* Preparation of vddc and vddgfx CAC tables for SMC.
+*
+* @param    hwmgr  the address of the hardware manager
+* @param    table  the SMC DPM table structure to be populated
+* @return   always 0
+*/
+static int fiji_populate_cac_table(struct pp_hwmgr *hwmgr,
+		struct SMU73_Discrete_DpmTable *table)
+{
+	uint32_t count;
+	uint8_t index;
+	int result = 0;
+	struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend);
+	struct phm_ppt_v1_information *table_info =
+			(struct phm_ppt_v1_information *)(hwmgr->pptable);
+	struct phm_ppt_v1_voltage_lookup_table *lookup_table =
+			table_info->vddc_lookup_table;
+	/* tables is already swapped, so in order to use the value from it,
+	 * we need to swap it back.
+	 * We are populating vddc CAC data to BapmVddc table
+	 * in split and merged mode
+	 */
+	for( count = 0; count<lookup_table->count; count++) {
+		index = fiji_get_voltage_index(lookup_table,
+				data->vddc_voltage_table.entries[count].value);
+		table->BapmVddcVidLoSidd[count] = (uint8_t) ((6200 -
+				(lookup_table->entries[index].us_cac_low *
+						VOLTAGE_SCALE)) / 25);
+		table->BapmVddcVidHiSidd[count] = (uint8_t) ((6200 -
+				(lookup_table->entries[index].us_cac_high *
+						VOLTAGE_SCALE)) / 25);
+	}
+
+	return result;
+}
+
+/**
+* Preparation of voltage tables for SMC.
+*
+* @param    hwmgr   the address of the hardware manager
+* @param    table   the SMC DPM table structure to be populated
+* @return   always  0
+*/
+
+int fiji_populate_smc_voltage_tables(struct pp_hwmgr *hwmgr,
+		struct SMU73_Discrete_DpmTable *table)
+{
+	int result;
+
+	result = fiji_populate_cac_table(hwmgr, table);
+	PP_ASSERT_WITH_CODE(0 == result,
+			"can not populate CAC voltage tables to SMC",
+			return -EINVAL);
+
+	return 0;
+}
+
+static int fiji_populate_ulv_level(struct pp_hwmgr *hwmgr,
+		struct SMU73_Discrete_Ulv *state)
+{
+	int result = 0;
+	struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend);
+	struct phm_ppt_v1_information *table_info =
+			(struct phm_ppt_v1_information *)(hwmgr->pptable);
+
+	state->CcPwrDynRm = 0;
+	state->CcPwrDynRm1 = 0;
+
+	state->VddcOffset = (uint16_t) table_info->us_ulv_voltage_offset;
+	state->VddcOffsetVid = (uint8_t)( table_info->us_ulv_voltage_offset *
+			VOLTAGE_VID_OFFSET_SCALE2 / VOLTAGE_VID_OFFSET_SCALE1 );
+
+	state->VddcPhase = (data->vddc_phase_shed_control) ? 0 : 1;
+
+	if (!result) {
+		CONVERT_FROM_HOST_TO_SMC_UL(state->CcPwrDynRm);
+		CONVERT_FROM_HOST_TO_SMC_UL(state->CcPwrDynRm1);
+		CONVERT_FROM_HOST_TO_SMC_US(state->VddcOffset);
+	}
+	return result;
+}
+
+static int fiji_populate_ulv_state(struct pp_hwmgr *hwmgr,
+		struct SMU73_Discrete_DpmTable *table)
+{
+	return fiji_populate_ulv_level(hwmgr, &table->Ulv);
+}
+
+static int32_t fiji_get_dpm_level_enable_mask_value(
+		struct fiji_single_dpm_table* dpm_table)
+{
+	int32_t i;
+	int32_t mask = 0;
+
+	for (i = dpm_table->count; i > 0; i--) {
+		mask = mask << 1;
+		if (dpm_table->dpm_levels[i - 1].enabled)
+			mask |= 0x1;
+		else
+			mask &= 0xFFFFFFFE;
+	}
+	return mask;
+}
+
+static int fiji_populate_smc_link_level(struct pp_hwmgr *hwmgr,
+		struct SMU73_Discrete_DpmTable *table)
+{
+	struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend);
+	struct fiji_dpm_table *dpm_table = &data->dpm_table;
+	int i;
+
+	/* Index (dpm_table->pcie_speed_table.count)
+	 * is reserved for PCIE boot level. */
+	for (i = 0; i <= dpm_table->pcie_speed_table.count; i++) {
+		table->LinkLevel[i].PcieGenSpeed  =
+				(uint8_t)dpm_table->pcie_speed_table.dpm_levels[i].value;
+		table->LinkLevel[i].PcieLaneCount = (uint8_t)encode_pcie_lane_width(
+				dpm_table->pcie_speed_table.dpm_levels[i].param1);
+		table->LinkLevel[i].EnabledForActivity = 1;
+		table->LinkLevel[i].SPC = (uint8_t)(data->pcie_spc_cap & 0xff);
+		table->LinkLevel[i].DownThreshold = PP_HOST_TO_SMC_UL(5);
+		table->LinkLevel[i].UpThreshold = PP_HOST_TO_SMC_UL(30);
+	}
+
+	data->smc_state_table.LinkLevelCount =
+			(uint8_t)dpm_table->pcie_speed_table.count;
+	data->dpm_level_enable_mask.pcie_dpm_enable_mask =
+			fiji_get_dpm_level_enable_mask_value(&dpm_table->pcie_speed_table);
+
+	return 0;
+}
+
+/**
+* Calculates the SCLK dividers using the provided engine clock
+*
+* @param    hwmgr  the address of the hardware manager
+* @param    clock  the engine clock to use to populate the structure
+* @param    sclk   the SMC SCLK structure to be populated
+*/
+static int fiji_calculate_sclk_params(struct pp_hwmgr *hwmgr,
+		uint32_t clock, struct SMU73_Discrete_GraphicsLevel *sclk)
+{
+	const struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend);
+	struct pp_atomctrl_clock_dividers_vi dividers;
+	uint32_t spll_func_cntl            = data->clock_registers.vCG_SPLL_FUNC_CNTL;
+	uint32_t spll_func_cntl_3          = data->clock_registers.vCG_SPLL_FUNC_CNTL_3;
+	uint32_t spll_func_cntl_4          = data->clock_registers.vCG_SPLL_FUNC_CNTL_4;
+	uint32_t cg_spll_spread_spectrum   = data->clock_registers.vCG_SPLL_SPREAD_SPECTRUM;
+	uint32_t cg_spll_spread_spectrum_2 = data->clock_registers.vCG_SPLL_SPREAD_SPECTRUM_2;
+	uint32_t ref_clock;
+	uint32_t ref_divider;
+	uint32_t fbdiv;
+	int result;
+
+	/* get the engine clock dividers for this clock value */
+	result = atomctrl_get_engine_pll_dividers_vi(hwmgr, clock,  &dividers);
+
+	PP_ASSERT_WITH_CODE(result == 0,
+			"Error retrieving Engine Clock dividers from VBIOS.",
+			return result);
+
+	/* To get FBDIV we need to multiply this by 16384 and divide it by Fref. */
+	ref_clock = atomctrl_get_reference_clock(hwmgr);
+	ref_divider = 1 + dividers.uc_pll_ref_div;
+
+	/* low 14 bits is fraction and high 12 bits is divider */
+	fbdiv = dividers.ul_fb_div.ul_fb_divider & 0x3FFFFFF;
+
+	/* SPLL_FUNC_CNTL setup */
+	spll_func_cntl = PHM_SET_FIELD(spll_func_cntl, CG_SPLL_FUNC_CNTL,
+			SPLL_REF_DIV, dividers.uc_pll_ref_div);
+	spll_func_cntl = PHM_SET_FIELD(spll_func_cntl, CG_SPLL_FUNC_CNTL,
+			SPLL_PDIV_A,  dividers.uc_pll_post_div);
+
+	/* SPLL_FUNC_CNTL_3 setup*/
+	spll_func_cntl_3 = PHM_SET_FIELD(spll_func_cntl_3, CG_SPLL_FUNC_CNTL_3,
+			SPLL_FB_DIV, fbdiv);
+
+	/* set to use fractional accumulation*/
+	spll_func_cntl_3 = PHM_SET_FIELD(spll_func_cntl_3, CG_SPLL_FUNC_CNTL_3,
+			SPLL_DITHEN, 1);
+
+	if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
+				PHM_PlatformCaps_EngineSpreadSpectrumSupport)) {
+		struct pp_atomctrl_internal_ss_info ssInfo;
+
+		uint32_t vco_freq = clock * dividers.uc_pll_post_div;
+		if (!atomctrl_get_engine_clock_spread_spectrum(hwmgr,
+				vco_freq, &ssInfo)) {
+			/*
+			 * ss_info.speed_spectrum_percentage -- in unit of 0.01%
+			 * ss_info.speed_spectrum_rate -- in unit of khz
+			 *
+			 * clks = reference_clock * 10 / (REFDIV + 1) / speed_spectrum_rate / 2
+			 */
+			uint32_t clk_s = ref_clock * 5 /
+					(ref_divider * ssInfo.speed_spectrum_rate);
+			/* clkv = 2 * D * fbdiv / NS */
+			uint32_t clk_v = 4 * ssInfo.speed_spectrum_percentage *
+					fbdiv / (clk_s * 10000);
+
+			cg_spll_spread_spectrum = PHM_SET_FIELD(cg_spll_spread_spectrum,
+					CG_SPLL_SPREAD_SPECTRUM, CLKS, clk_s);
+			cg_spll_spread_spectrum = PHM_SET_FIELD(cg_spll_spread_spectrum,
+					CG_SPLL_SPREAD_SPECTRUM, SSEN, 1);
+			cg_spll_spread_spectrum_2 = PHM_SET_FIELD(cg_spll_spread_spectrum_2,
+					CG_SPLL_SPREAD_SPECTRUM_2, CLKV, clk_v);
+		}
+	}
+
+	sclk->SclkFrequency        = clock;
+	sclk->CgSpllFuncCntl3      = spll_func_cntl_3;
+	sclk->CgSpllFuncCntl4      = spll_func_cntl_4;
+	sclk->SpllSpreadSpectrum   = cg_spll_spread_spectrum;
+	sclk->SpllSpreadSpectrum2  = cg_spll_spread_spectrum_2;
+	sclk->SclkDid              = (uint8_t)dividers.pll_post_divider;
+
+	return 0;
+}
+
+static uint16_t fiji_find_closest_vddci(struct pp_hwmgr *hwmgr, uint16_t vddci)
+{
+	uint32_t  i;
+	struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend);
+	struct pp_atomctrl_voltage_table *vddci_table =
+			&(data->vddci_voltage_table);
+
+	for (i = 0; i < vddci_table->count; i++) {
+		if (vddci_table->entries[i].value >= vddci)
+			return vddci_table->entries[i].value;
+	}
+
+	PP_ASSERT_WITH_CODE(false,
+			"VDDCI is larger than max VDDCI in VDDCI Voltage Table!",
+			return vddci_table->entries[i].value);
+}
+
+static int fiji_get_dependency_volt_by_clk(struct pp_hwmgr *hwmgr,
+		struct phm_ppt_v1_clock_voltage_dependency_table* dep_table,
+		uint32_t clock, SMU_VoltageLevel *voltage, uint32_t *mvdd)
+{
+	uint32_t i;
+	uint16_t vddci;
+	struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend);
+
+	*voltage = *mvdd = 0;
+
+	/* clock - voltage dependency table is empty table */
+	if (dep_table->count == 0)
+		return -EINVAL;
+
+	for (i = 0; i < dep_table->count; i++) {
+		/* find first sclk bigger than request */
+		if (dep_table->entries[i].clk >= clock) {
+			*voltage |= (dep_table->entries[i].vddc *
+					VOLTAGE_SCALE) << VDDC_SHIFT;
+			if (FIJI_VOLTAGE_CONTROL_NONE == data->vddci_control)
+				*voltage |= (data->vbios_boot_state.vddci_bootup_value *
+						VOLTAGE_SCALE) << VDDCI_SHIFT;
+			else if (dep_table->entries[i].vddci)
+				*voltage |= (dep_table->entries[i].vddci *
+						VOLTAGE_SCALE) << VDDCI_SHIFT;
+			else {
+				vddci = fiji_find_closest_vddci(hwmgr,
+						(dep_table->entries[i].vddc -
+								(uint16_t)data->vddc_vddci_delta));
+				*voltage |= (vddci * VOLTAGE_SCALE) <<	VDDCI_SHIFT;
+			}
+
+			if (FIJI_VOLTAGE_CONTROL_NONE == data->mvdd_control)
+				*mvdd = data->vbios_boot_state.mvdd_bootup_value *
+					VOLTAGE_SCALE;
+			else if (dep_table->entries[i].mvdd)
+				*mvdd = (uint32_t) dep_table->entries[i].mvdd *
+					VOLTAGE_SCALE;
+
+			*voltage |= 1 << PHASES_SHIFT;
+			return 0;
+		}
+	}
+
+	/* sclk is bigger than max sclk in the dependence table */
+	*voltage |= (dep_table->entries[i - 1].vddc * VOLTAGE_SCALE) << VDDC_SHIFT;
+
+	if (FIJI_VOLTAGE_CONTROL_NONE == data->vddci_control)
+		*voltage |= (data->vbios_boot_state.vddci_bootup_value *
+				VOLTAGE_SCALE) << VDDCI_SHIFT;
+	else if (dep_table->entries[i-1].vddci) {
+		vddci = fiji_find_closest_vddci(hwmgr,
+				(dep_table->entries[i].vddc -
+						(uint16_t)data->vddc_vddci_delta));
+		*voltage |= (vddci * VOLTAGE_SCALE) << VDDCI_SHIFT;
+	}
+
+	if (FIJI_VOLTAGE_CONTROL_NONE == data->mvdd_control)
+		*mvdd = data->vbios_boot_state.mvdd_bootup_value * VOLTAGE_SCALE;
+	else if (dep_table->entries[i].mvdd)
+		*mvdd = (uint32_t) dep_table->entries[i - 1].mvdd * VOLTAGE_SCALE;
+
+	return 0;
+}
+/**
+* Populates single SMC SCLK structure using the provided engine clock
+*
+* @param    hwmgr      the address of the hardware manager
+* @param    clock the engine clock to use to populate the structure
+* @param    sclk        the SMC SCLK structure to be populated
+*/
+
+static int fiji_populate_single_graphic_level(struct pp_hwmgr *hwmgr,
+		uint32_t clock, uint16_t sclk_al_threshold,
+		struct SMU73_Discrete_GraphicsLevel *level)
+{
+	int result;
+	/* PP_Clocks minClocks; */
+	uint32_t threshold, mvdd;
+	struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend);
+	struct phm_ppt_v1_information *table_info =
+			(struct phm_ppt_v1_information *)(hwmgr->pptable);
+
+	result = fiji_calculate_sclk_params(hwmgr, clock, level);
+
+	/* populate graphics levels */
+	result = fiji_get_dependency_volt_by_clk(hwmgr,
+			table_info->vdd_dep_on_sclk, clock,
+			&level->MinVoltage, &mvdd);
+	PP_ASSERT_WITH_CODE((0 == result),
+			"can not find VDDC voltage value for "
+			"VDDC engine clock dependency table",
+			return result);
+
+	level->SclkFrequency = clock;
+	level->ActivityLevel = sclk_al_threshold;
+	level->CcPwrDynRm = 0;
+	level->CcPwrDynRm1 = 0;
+	level->EnabledForActivity = 0;
+	level->EnabledForThrottle = 1;
+	level->UpHyst = 10;
+	level->DownHyst = 0;
+	level->VoltageDownHyst = 0;
+	level->PowerThrottle = 0;
+
+	threshold = clock * data->fast_watermark_threshold / 100;
+
+	/*
+	* TODO: get minimum clocks from dal configaration
+	* PECI_GetMinClockSettings(hwmgr->pPECI, &minClocks);
+	*/
+	/* data->DisplayTiming.minClockInSR = minClocks.engineClockInSR; */
+
+	/* get level->DeepSleepDivId
+	if (phm_cap_enabled(hwmgr->platformDescriptor.platformCaps, PHM_PlatformCaps_SclkDeepSleep))
+	{
+	level->DeepSleepDivId = PhwFiji_GetSleepDividerIdFromClock(hwmgr, clock, minClocks.engineClockInSR);
+	} */
+
+	/* Default to slow, highest DPM level will be
+	 * set to PPSMC_DISPLAY_WATERMARK_LOW later.
+	 */
+	level->DisplayWatermark = PPSMC_DISPLAY_WATERMARK_LOW;
+
+	CONVERT_FROM_HOST_TO_SMC_UL(level->MinVoltage);
+	CONVERT_FROM_HOST_TO_SMC_UL(level->SclkFrequency);
+	CONVERT_FROM_HOST_TO_SMC_US(level->ActivityLevel);
+	CONVERT_FROM_HOST_TO_SMC_UL(level->CgSpllFuncCntl3);
+	CONVERT_FROM_HOST_TO_SMC_UL(level->CgSpllFuncCntl4);
+	CONVERT_FROM_HOST_TO_SMC_UL(level->SpllSpreadSpectrum);
+	CONVERT_FROM_HOST_TO_SMC_UL(level->SpllSpreadSpectrum2);
+	CONVERT_FROM_HOST_TO_SMC_UL(level->CcPwrDynRm);
+	CONVERT_FROM_HOST_TO_SMC_UL(level->CcPwrDynRm1);
+
+	return 0;
+}
+/**
+* Populates all SMC SCLK levels' structure based on the trimmed allowed dpm engine clock states
+*
+* @param    hwmgr      the address of the hardware manager
+*/
+static int fiji_populate_all_graphic_levels(struct pp_hwmgr *hwmgr)
+{
+	struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend);
+	struct fiji_dpm_table *dpm_table = &data->dpm_table;
+	struct phm_ppt_v1_information *table_info =
+			(struct phm_ppt_v1_information *)(hwmgr->pptable);
+	struct phm_ppt_v1_pcie_table *pcie_table = table_info->pcie_table;
+	uint8_t pcie_entry_cnt = (uint8_t) data->dpm_table.pcie_speed_table.count;
+	int result = 0;
+	uint32_t array = data->dpm_table_start +
+			offsetof(SMU73_Discrete_DpmTable, GraphicsLevel);
+	uint32_t array_size = sizeof(struct SMU73_Discrete_GraphicsLevel) *
+			SMU73_MAX_LEVELS_GRAPHICS;
+	struct SMU73_Discrete_GraphicsLevel *levels =
+			data->smc_state_table.GraphicsLevel;
+	uint32_t i, max_entry;
+	uint8_t hightest_pcie_level_enabled = 0,
+			lowest_pcie_level_enabled = 0,
+			mid_pcie_level_enabled = 0,
+			count = 0;
+
+	for (i = 0; i < dpm_table->sclk_table.count; i++) {
+		result = fiji_populate_single_graphic_level(hwmgr,
+				dpm_table->sclk_table.dpm_levels[i].value,
+				(uint16_t)data->activity_target[i],
+				&levels[i]);
+		if (result)
+			return result;
+
+		/* Making sure only DPM level 0-1 have Deep Sleep Div ID populated. */
+		if (i > 1)
+			levels[i].DeepSleepDivId = 0;
+	}
+
+	/* Only enable level 0 for now.*/
+	levels[0].EnabledForActivity = 1;
+
+	/* set highest level watermark to high */
+	levels[dpm_table->sclk_table.count - 1].DisplayWatermark =
+			PPSMC_DISPLAY_WATERMARK_HIGH;
+
+	data->smc_state_table.GraphicsDpmLevelCount =
+			(uint8_t)dpm_table->sclk_table.count;
+	data->dpm_level_enable_mask.sclk_dpm_enable_mask =
+			fiji_get_dpm_level_enable_mask_value(&dpm_table->sclk_table);
+
+	if (pcie_table != NULL) {
+		PP_ASSERT_WITH_CODE((1 <= pcie_entry_cnt),
+				"There must be 1 or more PCIE levels defined in PPTable.",
+				return -EINVAL);
+		max_entry = pcie_entry_cnt - 1;
+		for (i = 0; i < dpm_table->sclk_table.count; i++)
+			levels[i].pcieDpmLevel =
+					(uint8_t) ((i < max_entry)? i : max_entry);
+	} else {
+		while (data->dpm_level_enable_mask.pcie_dpm_enable_mask &&
+				((data->dpm_level_enable_mask.pcie_dpm_enable_mask &
+						(1 << (hightest_pcie_level_enabled + 1))) != 0 ))
+			hightest_pcie_level_enabled++;
+
+		while (data->dpm_level_enable_mask.pcie_dpm_enable_mask &&
+				((data->dpm_level_enable_mask.pcie_dpm_enable_mask &
+						(1 << lowest_pcie_level_enabled)) == 0 ))
+			lowest_pcie_level_enabled++;
+
+		while ((count < hightest_pcie_level_enabled) &&
+				((data->dpm_level_enable_mask.pcie_dpm_enable_mask &
+						(1 << (lowest_pcie_level_enabled + 1 + count))) == 0 ))
+			count++;
+
+		mid_pcie_level_enabled = (lowest_pcie_level_enabled + 1+ count) <
+				hightest_pcie_level_enabled?
+						(lowest_pcie_level_enabled + 1 + count) :
+						hightest_pcie_level_enabled;
+
+		/* set pcieDpmLevel to hightest_pcie_level_enabled */
+		for(i = 2; i < dpm_table->sclk_table.count; i++)
+			levels[i].pcieDpmLevel = hightest_pcie_level_enabled;
+
+		/* set pcieDpmLevel to lowest_pcie_level_enabled */
+		levels[0].pcieDpmLevel = lowest_pcie_level_enabled;
+
+		/* set pcieDpmLevel to mid_pcie_level_enabled */
+		levels[1].pcieDpmLevel = mid_pcie_level_enabled;
+	}
+	/* level count will send to smc once at init smc table and never change */
+	result = fiji_copy_bytes_to_smc(hwmgr->smumgr, array, (uint8_t *)levels,
+			(uint32_t)array_size, data->sram_end);
+
+	return result;
+}
+
+/**
+ * MCLK Frequency Ratio
+ * SEQ_CG_RESP  Bit[31:24] - 0x0
+ * Bit[27:24] \96 DDR3 Frequency ratio
+ * 0x0 <= 100MHz,       450 < 0x8 <= 500MHz
+ * 100 < 0x1 <= 150MHz,       500 < 0x9 <= 550MHz
+ * 150 < 0x2 <= 200MHz,       550 < 0xA <= 600MHz
+ * 200 < 0x3 <= 250MHz,       600 < 0xB <= 650MHz
+ * 250 < 0x4 <= 300MHz,       650 < 0xC <= 700MHz
+ * 300 < 0x5 <= 350MHz,       700 < 0xD <= 750MHz
+ * 350 < 0x6 <= 400MHz,       750 < 0xE <= 800MHz
+ * 400 < 0x7 <= 450MHz,       800 < 0xF
+ */
+static uint8_t fiji_get_mclk_frequency_ratio(uint32_t mem_clock)
+{
+	if (mem_clock <= 10000) return 0x0;
+	if (mem_clock <= 15000) return 0x1;
+	if (mem_clock <= 20000) return 0x2;
+	if (mem_clock <= 25000) return 0x3;
+	if (mem_clock <= 30000) return 0x4;
+	if (mem_clock <= 35000) return 0x5;
+	if (mem_clock <= 40000) return 0x6;
+	if (mem_clock <= 45000) return 0x7;
+	if (mem_clock <= 50000) return 0x8;
+	if (mem_clock <= 55000) return 0x9;
+	if (mem_clock <= 60000) return 0xa;
+	if (mem_clock <= 65000) return 0xb;
+	if (mem_clock <= 70000) return 0xc;
+	if (mem_clock <= 75000) return 0xd;
+	if (mem_clock <= 80000) return 0xe;
+	/* mem_clock > 800MHz */
+	return 0xf;
+}
+
+/**
+* Populates the SMC MCLK structure using the provided memory clock
+*
+* @param    hwmgr   the address of the hardware manager
+* @param    clock   the memory clock to use to populate the structure
+* @param    sclk    the SMC SCLK structure to be populated
+*/
+static int fiji_calculate_mclk_params(struct pp_hwmgr *hwmgr,
+    uint32_t clock, struct SMU73_Discrete_MemoryLevel *mclk)
+{
+	struct pp_atomctrl_memory_clock_param mem_param;
+	int result;
+
+	result = atomctrl_get_memory_pll_dividers_vi(hwmgr, clock, &mem_param);
+	PP_ASSERT_WITH_CODE((0 == result),
+			"Failed to get Memory PLL Dividers.",);
+
+	/* Save the result data to outpupt memory level structure */
+	mclk->MclkFrequency   = clock;
+	mclk->MclkDivider     = (uint8_t)mem_param.mpll_post_divider;
+	mclk->FreqRange       = fiji_get_mclk_frequency_ratio(clock);
+
+	return result;
+}
+
+static int fiji_populate_single_memory_level(struct pp_hwmgr *hwmgr,
+		uint32_t clock, struct SMU73_Discrete_MemoryLevel *mem_level)
+{
+	struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend);
+	struct phm_ppt_v1_information *table_info =
+			(struct phm_ppt_v1_information *)(hwmgr->pptable);
+	int result = 0;
+
+	if (table_info->vdd_dep_on_mclk) {
+		result = fiji_get_dependency_volt_by_clk(hwmgr,
+				table_info->vdd_dep_on_mclk, clock,
+				&mem_level->MinVoltage, &mem_level->MinMvdd);
+		PP_ASSERT_WITH_CODE((0 == result),
+				"can not find MinVddc voltage value from memory "
+				"VDDC voltage dependency table", return result);
+	}
+
+	mem_level->EnabledForThrottle = 1;
+	mem_level->EnabledForActivity = 0;
+	mem_level->UpHyst = 0;
+	mem_level->DownHyst = 100;
+	mem_level->VoltageDownHyst = 0;
+	mem_level->ActivityLevel = (uint16_t)data->mclk_activity_target;
+	mem_level->StutterEnable = false;
+
+	mem_level->DisplayWatermark = PPSMC_DISPLAY_WATERMARK_LOW;
+
+	/* enable stutter mode if all the follow condition applied
+	 * PECI_GetNumberOfActiveDisplays(hwmgr->pPECI,
+	 * &(data->DisplayTiming.numExistingDisplays));
+	 */
+	data->display_timing.num_existing_displays = 1;
+
+	if ((data->mclk_stutter_mode_threshold) &&
+		(clock <= data->mclk_stutter_mode_threshold) &&
+		(!data->is_uvd_enabled) &&
+		(PHM_READ_FIELD(hwmgr->device, DPG_PIPE_STUTTER_CONTROL,
+				STUTTER_ENABLE) & 0x1))
+		mem_level->StutterEnable = true;
+
+	result = fiji_calculate_mclk_params(hwmgr, clock, mem_level);
+	if (!result) {
+		CONVERT_FROM_HOST_TO_SMC_UL(mem_level->MinMvdd);
+		CONVERT_FROM_HOST_TO_SMC_UL(mem_level->MclkFrequency);
+		CONVERT_FROM_HOST_TO_SMC_US(mem_level->ActivityLevel);
+		CONVERT_FROM_HOST_TO_SMC_UL(mem_level->MinVoltage);
+	}
+	return result;
+}
+
+/**
+* Populates all SMC MCLK levels' structure based on the trimmed allowed dpm memory clock states
+*
+* @param    hwmgr      the address of the hardware manager
+*/
+static int fiji_populate_all_memory_levels(struct pp_hwmgr *hwmgr)
+{
+	struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend);
+	struct fiji_dpm_table *dpm_table = &data->dpm_table;
+	int result;
+	/* populate MCLK dpm table to SMU7 */
+	uint32_t array = data->dpm_table_start +
+			offsetof(SMU73_Discrete_DpmTable, MemoryLevel);
+	uint32_t array_size = sizeof(SMU73_Discrete_MemoryLevel) *
+			SMU73_MAX_LEVELS_MEMORY;
+	struct SMU73_Discrete_MemoryLevel *levels =
+			data->smc_state_table.MemoryLevel;
+	uint32_t i;
+
+	for (i = 0; i < dpm_table->mclk_table.count; i++) {
+		PP_ASSERT_WITH_CODE((0 != dpm_table->mclk_table.dpm_levels[i].value),
+				"can not populate memory level as memory clock is zero",
+				return -EINVAL);
+		result = fiji_populate_single_memory_level(hwmgr,
+				dpm_table->mclk_table.dpm_levels[i].value,
+				&levels[i]);
+		if (result)
+			return result;
+	}
+
+	/* Only enable level 0 for now. */
+	levels[0].EnabledForActivity = 1;
+
+	/* in order to prevent MC activity from stutter mode to push DPM up.
+	 * the UVD change complements this by putting the MCLK in
+	 * a higher state by default such that we are not effected by
+	 * up threshold or and MCLK DPM latency.
+	 */
+	levels[0].ActivityLevel = (uint16_t)data->mclk_dpm0_activity_target;
+	CONVERT_FROM_HOST_TO_SMC_US(levels[0].ActivityLevel);
+
+	data->smc_state_table.MemoryDpmLevelCount =
+			(uint8_t)dpm_table->mclk_table.count;
+	data->dpm_level_enable_mask.mclk_dpm_enable_mask =
+			fiji_get_dpm_level_enable_mask_value(&dpm_table->mclk_table);
+	/* set highest level watermark to high */
+	levels[dpm_table->mclk_table.count - 1].DisplayWatermark =
+			PPSMC_DISPLAY_WATERMARK_HIGH;
+
+	/* level count will send to smc once at init smc table and never change */
+	result = fiji_copy_bytes_to_smc(hwmgr->smumgr, array, (uint8_t *)levels,
+			(uint32_t)array_size, data->sram_end);
+
+	return result;
+}
+
+/**
+* Populates the SMC MVDD structure using the provided memory clock.
+*
+* @param    hwmgr      the address of the hardware manager
+* @param    mclk        the MCLK value to be used in the decision if MVDD should be high or low.
+* @param    voltage     the SMC VOLTAGE structure to be populated
+*/
+int fiji_populate_mvdd_value(struct pp_hwmgr *hwmgr,
+		uint32_t mclk, SMIO_Pattern *smio_pat)
+{
+	const struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend);
+	struct phm_ppt_v1_information *table_info =
+			(struct phm_ppt_v1_information *)(hwmgr->pptable);
+	uint32_t i = 0;
+
+	if (FIJI_VOLTAGE_CONTROL_NONE != data->mvdd_control) {
+		/* find mvdd value which clock is more than request */
+		for (i = 0; i < table_info->vdd_dep_on_mclk->count; i++) {
+			if (mclk <= table_info->vdd_dep_on_mclk->entries[i].clk) {
+				smio_pat->Voltage = data->mvdd_voltage_table.entries[i].value;
+				break;
+			}
+		}
+		PP_ASSERT_WITH_CODE(i < table_info->vdd_dep_on_mclk->count,
+				"MVDD Voltage is outside the supported range.",
+				return -EINVAL);
+	} else
+		return -EINVAL;
+
+	return 0;
+}
+
+static int fiji_populate_smc_acpi_level(struct pp_hwmgr *hwmgr,
+		SMU73_Discrete_DpmTable *table)
+{
+	int result = 0;
+	const struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend);
+	struct phm_ppt_v1_information *table_info =
+			(struct phm_ppt_v1_information *)(hwmgr->pptable);
+	struct pp_atomctrl_clock_dividers_vi dividers;
+	SMIO_Pattern vol_level;
+	uint32_t mvdd;
+	uint16_t us_mvdd;
+	uint32_t spll_func_cntl    = data->clock_registers.vCG_SPLL_FUNC_CNTL;
+	uint32_t spll_func_cntl_2  = data->clock_registers.vCG_SPLL_FUNC_CNTL_2;
+
+	table->ACPILevel.Flags &= ~PPSMC_SWSTATE_FLAG_DC;
+
+	if (!data->sclk_dpm_key_disabled) {
+		/* Get MinVoltage and Frequency from DPM0,
+		 * already converted to SMC_UL */
+		table->ACPILevel.SclkFrequency =
+				data->dpm_table.sclk_table.dpm_levels[0].value;
+		result = fiji_get_dependency_volt_by_clk(hwmgr,
+				table_info->vdd_dep_on_sclk,
+				table->ACPILevel.SclkFrequency,
+				&table->ACPILevel.MinVoltage, &mvdd);
+		PP_ASSERT_WITH_CODE((0 == result),
+				"Cannot find ACPI VDDC voltage value "
+				"in Clock Dependency Table",);
+	} else {
+		table->ACPILevel.SclkFrequency =
+				data->vbios_boot_state.sclk_bootup_value;
+		table->ACPILevel.MinVoltage =
+				data->vbios_boot_state.vddc_bootup_value * VOLTAGE_SCALE;
+	}
+
+	/* get the engine clock dividers for this clock value */
+	result = atomctrl_get_engine_pll_dividers_vi(hwmgr,
+			table->ACPILevel.SclkFrequency,  &dividers);
+	PP_ASSERT_WITH_CODE(result == 0,
+			"Error retrieving Engine Clock dividers from VBIOS.",
+			return result);
+
+	table->ACPILevel.SclkDid = (uint8_t)dividers.pll_post_divider;
+	table->ACPILevel.DisplayWatermark = PPSMC_DISPLAY_WATERMARK_LOW;
+	table->ACPILevel.DeepSleepDivId = 0;
+
+	spll_func_cntl = PHM_SET_FIELD(spll_func_cntl, CG_SPLL_FUNC_CNTL,
+			SPLL_PWRON, 0);
+	spll_func_cntl = PHM_SET_FIELD(spll_func_cntl, CG_SPLL_FUNC_CNTL,
+			SPLL_RESET, 1);
+	spll_func_cntl_2 = PHM_SET_FIELD(spll_func_cntl_2, CG_SPLL_FUNC_CNTL_2,
+			SCLK_MUX_SEL, 4);
+
+	table->ACPILevel.CgSpllFuncCntl = spll_func_cntl;
+	table->ACPILevel.CgSpllFuncCntl2 = spll_func_cntl_2;
+	table->ACPILevel.CgSpllFuncCntl3 = data->clock_registers.vCG_SPLL_FUNC_CNTL_3;
+	table->ACPILevel.CgSpllFuncCntl4 = data->clock_registers.vCG_SPLL_FUNC_CNTL_4;
+	table->ACPILevel.SpllSpreadSpectrum = data->clock_registers.vCG_SPLL_SPREAD_SPECTRUM;
+	table->ACPILevel.SpllSpreadSpectrum2 = data->clock_registers.vCG_SPLL_SPREAD_SPECTRUM_2;
+	table->ACPILevel.CcPwrDynRm = 0;
+	table->ACPILevel.CcPwrDynRm1 = 0;
+
+	CONVERT_FROM_HOST_TO_SMC_UL(table->ACPILevel.Flags);
+	CONVERT_FROM_HOST_TO_SMC_UL(table->ACPILevel.SclkFrequency);
+	CONVERT_FROM_HOST_TO_SMC_UL(table->ACPILevel.MinVoltage);
+	CONVERT_FROM_HOST_TO_SMC_UL(table->ACPILevel.CgSpllFuncCntl);
+	CONVERT_FROM_HOST_TO_SMC_UL(table->ACPILevel.CgSpllFuncCntl2);
+	CONVERT_FROM_HOST_TO_SMC_UL(table->ACPILevel.CgSpllFuncCntl3);
+	CONVERT_FROM_HOST_TO_SMC_UL(table->ACPILevel.CgSpllFuncCntl4);
+	CONVERT_FROM_HOST_TO_SMC_UL(table->ACPILevel.SpllSpreadSpectrum);
+	CONVERT_FROM_HOST_TO_SMC_UL(table->ACPILevel.SpllSpreadSpectrum2);
+	CONVERT_FROM_HOST_TO_SMC_UL(table->ACPILevel.CcPwrDynRm);
+	CONVERT_FROM_HOST_TO_SMC_UL(table->ACPILevel.CcPwrDynRm1);
+
+	if (!data->mclk_dpm_key_disabled) {
+		/* Get MinVoltage and Frequency from DPM0, already converted to SMC_UL */
+		table->MemoryACPILevel.MclkFrequency =
+				data->dpm_table.mclk_table.dpm_levels[0].value;
+		result = fiji_get_dependency_volt_by_clk(hwmgr,
+				table_info->vdd_dep_on_mclk,
+				table->MemoryACPILevel.MclkFrequency,
+				&table->MemoryACPILevel.MinVoltage, &mvdd);
+		PP_ASSERT_WITH_CODE((0 == result),
+				"Cannot find ACPI VDDCI voltage value "
+				"in Clock Dependency Table",);
+	} else {
+		table->MemoryACPILevel.MclkFrequency =
+				data->vbios_boot_state.mclk_bootup_value;
+		table->MemoryACPILevel.MinVoltage =
+				data->vbios_boot_state.vddci_bootup_value * VOLTAGE_SCALE;
+	}
+
+	us_mvdd = 0;
+	if ((FIJI_VOLTAGE_CONTROL_NONE == data->mvdd_control) ||
+			(data->mclk_dpm_key_disabled))
+		us_mvdd = data->vbios_boot_state.mvdd_bootup_value;
+	else {
+		if (!fiji_populate_mvdd_value(hwmgr,
+				data->dpm_table.mclk_table.dpm_levels[0].value,
+				&vol_level))
+			us_mvdd = vol_level.Voltage;
+	}
+
+	table->MemoryACPILevel.MinMvdd =
+			PP_HOST_TO_SMC_UL(us_mvdd * VOLTAGE_SCALE);
+
+	table->MemoryACPILevel.EnabledForThrottle = 0;
+	table->MemoryACPILevel.EnabledForActivity = 0;
+	table->MemoryACPILevel.UpHyst = 0;
+	table->MemoryACPILevel.DownHyst = 100;
+	table->MemoryACPILevel.VoltageDownHyst = 0;
+	table->MemoryACPILevel.ActivityLevel =
+			PP_HOST_TO_SMC_US((uint16_t)data->mclk_activity_target);
+
+	table->MemoryACPILevel.StutterEnable = false;
+	CONVERT_FROM_HOST_TO_SMC_UL(table->MemoryACPILevel.MclkFrequency);
+	CONVERT_FROM_HOST_TO_SMC_UL(table->MemoryACPILevel.MinVoltage);
+
+	return result;
+}
+
+static int fiji_populate_smc_vce_level(struct pp_hwmgr *hwmgr,
+		SMU73_Discrete_DpmTable *table)
+{
+	int result = -EINVAL;
+	uint8_t count;
+	struct pp_atomctrl_clock_dividers_vi dividers;
+	struct phm_ppt_v1_information *table_info =
+			(struct phm_ppt_v1_information *)(hwmgr->pptable);
+	struct phm_ppt_v1_mm_clock_voltage_dependency_table *mm_table =
+			table_info->mm_dep_table;
+	struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend);
+
+	table->VceLevelCount = (uint8_t)(mm_table->count);
+	table->VceBootLevel = 0;
+
+	for(count = 0; count < table->VceLevelCount; count++) {
+		table->VceLevel[count].Frequency = mm_table->entries[count].eclk;
+		table->VceLevel[count].MinVoltage |=
+				(mm_table->entries[count].vddc * VOLTAGE_SCALE) << VDDC_SHIFT;
+		table->VceLevel[count].MinVoltage |=
+				((mm_table->entries[count].vddc - data->vddc_vddci_delta) *
+						VOLTAGE_SCALE) << VDDCI_SHIFT;
+		table->VceLevel[count].MinVoltage |= 1 << PHASES_SHIFT;
+
+		/*retrieve divider value for VBIOS */
+		result = atomctrl_get_dfs_pll_dividers_vi(hwmgr,
+				table->VceLevel[count].Frequency, &dividers);
+		PP_ASSERT_WITH_CODE((0 == result),
+				"can not find divide id for VCE engine clock",
+				return result);
+
+		table->VceLevel[count].Divider = (uint8_t)dividers.pll_post_divider;
+
+		CONVERT_FROM_HOST_TO_SMC_UL(table->VceLevel[count].Frequency);
+		CONVERT_FROM_HOST_TO_SMC_UL(table->VceLevel[count].MinVoltage);
+	}
+	return result;
+}
+
+static int fiji_populate_smc_acp_level(struct pp_hwmgr *hwmgr,
+		SMU73_Discrete_DpmTable *table)
+{
+	int result = -EINVAL;
+	uint8_t count;
+	struct pp_atomctrl_clock_dividers_vi dividers;
+	struct phm_ppt_v1_information *table_info =
+			(struct phm_ppt_v1_information *)(hwmgr->pptable);
+	struct phm_ppt_v1_mm_clock_voltage_dependency_table *mm_table =
+			table_info->mm_dep_table;
+	struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend);
+
+	table->AcpLevelCount = (uint8_t)(mm_table->count);
+	table->AcpBootLevel = 0;
+
+	for (count = 0; count < table->AcpLevelCount; count++) {
+		table->AcpLevel[count].Frequency = mm_table->entries[count].aclk;
+		table->AcpLevel[count].MinVoltage |= (mm_table->entries[count].vddc *
+				VOLTAGE_SCALE) << VDDC_SHIFT;
+		table->AcpLevel[count].MinVoltage |= ((mm_table->entries[count].vddc -
+				data->vddc_vddci_delta) * VOLTAGE_SCALE) << VDDCI_SHIFT;
+		table->AcpLevel[count].MinVoltage |= 1 << PHASES_SHIFT;
+
+		/* retrieve divider value for VBIOS */
+		result = atomctrl_get_dfs_pll_dividers_vi(hwmgr,
+				table->AcpLevel[count].Frequency, &dividers);
+		PP_ASSERT_WITH_CODE((0 == result),
+				"can not find divide id for engine clock", return result);
+
+		table->AcpLevel[count].Divider = (uint8_t)dividers.pll_post_divider;
+
+		CONVERT_FROM_HOST_TO_SMC_UL(table->AcpLevel[count].Frequency);
+		CONVERT_FROM_HOST_TO_SMC_UL(table->AcpLevel[count].MinVoltage);
+	}
+	return result;
+}
+
+static int fiji_populate_smc_samu_level(struct pp_hwmgr *hwmgr,
+		SMU73_Discrete_DpmTable *table)
+{
+	int result = -EINVAL;
+	uint8_t count;
+	struct pp_atomctrl_clock_dividers_vi dividers;
+	struct phm_ppt_v1_information *table_info =
+			(struct phm_ppt_v1_information *)(hwmgr->pptable);
+	struct phm_ppt_v1_mm_clock_voltage_dependency_table *mm_table =
+			table_info->mm_dep_table;
+	struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend);
+
+	table->SamuBootLevel = 0;
+	table->SamuLevelCount = (uint8_t)(mm_table->count);
+
+	for (count = 0; count < table->SamuLevelCount; count++) {
+		/* not sure whether we need evclk or not */
+		table->SamuLevel[count].Frequency = mm_table->entries[count].samclock;
+		table->SamuLevel[count].MinVoltage |= (mm_table->entries[count].vddc *
+				VOLTAGE_SCALE) << VDDC_SHIFT;
+		table->SamuLevel[count].MinVoltage |= ((mm_table->entries[count].vddc -
+				data->vddc_vddci_delta) * VOLTAGE_SCALE) << VDDCI_SHIFT;
+		table->SamuLevel[count].MinVoltage |= 1 << PHASES_SHIFT;
+
+		/* retrieve divider value for VBIOS */
+		result = atomctrl_get_dfs_pll_dividers_vi(hwmgr,
+				table->SamuLevel[count].Frequency, &dividers);
+		PP_ASSERT_WITH_CODE((0 == result),
+				"can not find divide id for samu clock", return result);
+
+		table->SamuLevel[count].Divider = (uint8_t)dividers.pll_post_divider;
+
+		CONVERT_FROM_HOST_TO_SMC_UL(table->SamuLevel[count].Frequency);
+		CONVERT_FROM_HOST_TO_SMC_UL(table->SamuLevel[count].MinVoltage);
+	}
+	return result;
+}
+
+static int fiji_populate_memory_timing_parameters(struct pp_hwmgr *hwmgr,
+		int32_t eng_clock, int32_t mem_clock,
+		struct SMU73_Discrete_MCArbDramTimingTableEntry *arb_regs)
+{
+	uint32_t dram_timing;
+	uint32_t dram_timing2;
+	uint32_t burstTime;
+	ULONG state, trrds, trrdl;
+	int result;
+
+	result = atomctrl_set_engine_dram_timings_rv770(hwmgr,
+			eng_clock, mem_clock);
+	PP_ASSERT_WITH_CODE(result == 0,
+			"Error calling VBIOS to set DRAM_TIMING.", return result);
+
+	dram_timing = cgs_read_register(hwmgr->device, mmMC_ARB_DRAM_TIMING);
+	dram_timing2 = cgs_read_register(hwmgr->device, mmMC_ARB_DRAM_TIMING2);
+	burstTime = cgs_read_register(hwmgr->device, mmMC_ARB_BURST_TIME);
+
+	state = PHM_GET_FIELD(burstTime, MC_ARB_BURST_TIME, STATE0);
+	trrds = PHM_GET_FIELD(burstTime, MC_ARB_BURST_TIME, TRRDS0);
+	trrdl = PHM_GET_FIELD(burstTime, MC_ARB_BURST_TIME, TRRDL0);
+
+	arb_regs->McArbDramTiming  = PP_HOST_TO_SMC_UL(dram_timing);
+	arb_regs->McArbDramTiming2 = PP_HOST_TO_SMC_UL(dram_timing2);
+	arb_regs->McArbBurstTime   = (uint8_t)burstTime;
+	arb_regs->TRRDS            = (uint8_t)trrds;
+	arb_regs->TRRDL            = (uint8_t)trrdl;
+
+	return 0;
+}
+
+static int fiji_program_memory_timing_parameters(struct pp_hwmgr *hwmgr)
+{
+	struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend);
+	struct SMU73_Discrete_MCArbDramTimingTable arb_regs;
+	uint32_t i, j;
+	int result = 0;
+
+	for (i = 0; i < data->dpm_table.sclk_table.count; i++) {
+		for (j = 0; j < data->dpm_table.mclk_table.count; j++) {
+			result = fiji_populate_memory_timing_parameters(hwmgr,
+					data->dpm_table.sclk_table.dpm_levels[i].value,
+					data->dpm_table.mclk_table.dpm_levels[j].value,
+					&arb_regs.entries[i][j]);
+			if (result)
+				break;
+		}
+	}
+
+	if (!result)
+		result = fiji_copy_bytes_to_smc(
+				hwmgr->smumgr,
+				data->arb_table_start,
+				(uint8_t *)&arb_regs,
+				sizeof(SMU73_Discrete_MCArbDramTimingTable),
+				data->sram_end);
+	return result;
+}
+
+static int fiji_populate_smc_uvd_level(struct pp_hwmgr *hwmgr,
+		struct SMU73_Discrete_DpmTable *table)
+{
+	int result = -EINVAL;
+	uint8_t count;
+	struct pp_atomctrl_clock_dividers_vi dividers;
+	struct phm_ppt_v1_information *table_info =
+			(struct phm_ppt_v1_information *)(hwmgr->pptable);
+	struct phm_ppt_v1_mm_clock_voltage_dependency_table *mm_table =
+			table_info->mm_dep_table;
+	struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend);
+
+	table->UvdLevelCount = (uint8_t)(mm_table->count);
+	table->UvdBootLevel = 0;
+
+	for (count = 0; count < table->UvdLevelCount; count++) {
+		table->UvdLevel[count].VclkFrequency = mm_table->entries[count].vclk;
+		table->UvdLevel[count].DclkFrequency = mm_table->entries[count].dclk;
+		table->UvdLevel[count].MinVoltage |= (mm_table->entries[count].vddc *
+				VOLTAGE_SCALE) << VDDC_SHIFT;
+		table->UvdLevel[count].MinVoltage |= ((mm_table->entries[count].vddc -
+				data->vddc_vddci_delta) * VOLTAGE_SCALE) << VDDCI_SHIFT;
+		table->UvdLevel[count].MinVoltage |= 1 << PHASES_SHIFT;
+
+		/* retrieve divider value for VBIOS */
+		result = atomctrl_get_dfs_pll_dividers_vi(hwmgr,
+				table->UvdLevel[count].VclkFrequency, &dividers);
+		PP_ASSERT_WITH_CODE((0 == result),
+				"can not find divide id for Vclk clock", return result);
+
+		table->UvdLevel[count].VclkDivider = (uint8_t)dividers.pll_post_divider;
+
+		result = atomctrl_get_dfs_pll_dividers_vi(hwmgr,
+				table->UvdLevel[count].DclkFrequency, &dividers);
+		PP_ASSERT_WITH_CODE((0 == result),
+				"can not find divide id for Dclk clock", return result);
+
+		table->UvdLevel[count].DclkDivider = (uint8_t)dividers.pll_post_divider;
+
+		CONVERT_FROM_HOST_TO_SMC_UL(table->UvdLevel[count].VclkFrequency);
+		CONVERT_FROM_HOST_TO_SMC_UL(table->UvdLevel[count].DclkFrequency);
+		CONVERT_FROM_HOST_TO_SMC_UL(table->UvdLevel[count].MinVoltage);
+
+	}
+	return result;
+}
+
+static int fiji_find_boot_level(struct fiji_single_dpm_table *table,
+		uint32_t value, uint32_t *boot_level)
+{
+	int result = -EINVAL;
+	uint32_t i;
+
+	for (i = 0; i < table->count; i++) {
+		if (value == table->dpm_levels[i].value) {
+			*boot_level = i;
+			result = 0;
+		}
+	}
+	return result;
+}
+
+static int fiji_populate_smc_boot_level(struct pp_hwmgr *hwmgr,
+		struct SMU73_Discrete_DpmTable *table)
+{
+	int result = 0;
+	struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend);
+
+	table->GraphicsBootLevel = 0;
+	table->MemoryBootLevel = 0;
+
+	/* find boot level from dpm table */
+	result = fiji_find_boot_level(&(data->dpm_table.sclk_table),
+			data->vbios_boot_state.sclk_bootup_value,
+			(uint32_t *)&(table->GraphicsBootLevel));
+
+	result = fiji_find_boot_level(&(data->dpm_table.mclk_table),
+			data->vbios_boot_state.mclk_bootup_value,
+			(uint32_t *)&(table->MemoryBootLevel));
+
+	table->BootVddc  = data->vbios_boot_state.vddc_bootup_value *
+			VOLTAGE_SCALE;
+	table->BootVddci = data->vbios_boot_state.vddci_bootup_value *
+			VOLTAGE_SCALE;
+	table->BootMVdd  = data->vbios_boot_state.mvdd_bootup_value *
+			VOLTAGE_SCALE;
+
+	CONVERT_FROM_HOST_TO_SMC_US(table->BootVddc);
+	CONVERT_FROM_HOST_TO_SMC_US(table->BootVddci);
+	CONVERT_FROM_HOST_TO_SMC_US(table->BootMVdd);
+
+	return 0;
+}
+
+static int fiji_populate_smc_initailial_state(struct pp_hwmgr *hwmgr)
+{
+	struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend);
+	struct phm_ppt_v1_information *table_info =
+			(struct phm_ppt_v1_information *)(hwmgr->pptable);
+	uint8_t count, level;
+
+	count = (uint8_t)(table_info->vdd_dep_on_sclk->count);
+	for (level = 0; level < count; level++) {
+		if(table_info->vdd_dep_on_sclk->entries[level].clk >=
+				data->vbios_boot_state.sclk_bootup_value) {
+			data->smc_state_table.GraphicsBootLevel = level;
+			break;
+		}
+	}
+
+	count = (uint8_t)(table_info->vdd_dep_on_mclk->count);
+	for (level = 0; level < count; level++) {
+		if(table_info->vdd_dep_on_mclk->entries[level].clk >=
+				data->vbios_boot_state.mclk_bootup_value) {
+			data->smc_state_table.MemoryBootLevel = level;
+			break;
+		}
+	}
+
+	return 0;
+}
+
+static int fiji_populate_clock_stretcher_data_table(struct pp_hwmgr *hwmgr)
+{
+	uint32_t ro, efuse, efuse2, clock_freq, volt_without_cks,
+			volt_with_cks, value;
+	uint16_t clock_freq_u16;
+	struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend);
+	uint8_t type, i, j, cks_setting, stretch_amount, stretch_amount2,
+			volt_offset = 0;
+	struct phm_ppt_v1_information *table_info =
+			(struct phm_ppt_v1_information *)(hwmgr->pptable);
+	struct phm_ppt_v1_clock_voltage_dependency_table *sclk_table =
+			table_info->vdd_dep_on_sclk;
+
+	stretch_amount = (uint8_t)table_info->cac_dtp_table->usClockStretchAmount;
+
+	/* Read SMU_Eefuse to read and calculate RO and determine
+	 * if the part is SS or FF. if RO >= 1660MHz, part is FF.
+	 */
+	efuse = cgs_read_ind_register(hwmgr->device, CGS_IND_REG__SMC,
+			ixSMU_EFUSE_0 + (146 * 4));
+	efuse2 = cgs_read_ind_register(hwmgr->device, CGS_IND_REG__SMC,
+			ixSMU_EFUSE_0 + (148 * 4));
+	efuse &= 0xFF000000;
+	efuse = efuse >> 24;
+	efuse2 &= 0xF;
+
+	if (efuse2 == 1)
+		ro = (2300 - 1350) * efuse / 255 + 1350;
+	else
+		ro = (2500 - 1000) * efuse / 255 + 1000;
+
+	if (ro >= 1660)
+		type = 0;
+	else
+		type = 1;
+
+	/* Populate Stretch amount */
+	data->smc_state_table.ClockStretcherAmount = stretch_amount;
+
+	/* Populate Sclk_CKS_masterEn0_7 and Sclk_voltageOffset */
+	for (i = 0; i < sclk_table->count; i++) {
+		data->smc_state_table.Sclk_CKS_masterEn0_7 |=
+				sclk_table->entries[i].cks_enable << i;
+		volt_without_cks = (uint32_t)((14041 *
+			(sclk_table->entries[i].clk/100) / 10000 + 3571 + 75 - ro) * 1000 /
+			(4026 - (13924 * (sclk_table->entries[i].clk/100) / 10000)));
+		volt_with_cks = (uint32_t)((13946 *
+			(sclk_table->entries[i].clk/100) / 10000 + 3320 + 45 - ro) * 1000 /
+			(3664 - (11454 * (sclk_table->entries[i].clk/100) / 10000)));
+		if (volt_without_cks >= volt_with_cks)
+			volt_offset = (uint8_t)(((volt_without_cks - volt_with_cks +
+					sclk_table->entries[i].cks_voffset) * 100 / 625) + 1);
+		data->smc_state_table.Sclk_voltageOffset[i] = volt_offset;
+	}
+
+	PHM_WRITE_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, PWR_CKS_ENABLE,
+			STRETCH_ENABLE, 0x0);
+	PHM_WRITE_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, PWR_CKS_ENABLE,
+			masterReset, 0x1);
+	PHM_WRITE_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, PWR_CKS_ENABLE,
+			staticEnable, 0x1);
+	PHM_WRITE_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, PWR_CKS_ENABLE,
+			masterReset, 0x0);
+
+	/* Populate CKS Lookup Table */
+	if (stretch_amount == 1 || stretch_amount == 2 || stretch_amount == 5)
+		stretch_amount2 = 0;
+	else if (stretch_amount == 3 || stretch_amount == 4)
+		stretch_amount2 = 1;
+	else {
+		phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
+				PHM_PlatformCaps_ClockStretcher);
+		PP_ASSERT_WITH_CODE(false,
+				"Stretch Amount in PPTable not supported\n",
+				return -EINVAL);
+	}
+
+	value = cgs_read_ind_register(hwmgr->device, CGS_IND_REG__SMC,
+			ixPWR_CKS_CNTL);
+	value &= 0xFFC2FF87;
+	data->smc_state_table.CKS_LOOKUPTable.CKS_LOOKUPTableEntry[0].minFreq =
+			fiji_clock_stretcher_lookup_table[stretch_amount2][0];
+	data->smc_state_table.CKS_LOOKUPTable.CKS_LOOKUPTableEntry[0].maxFreq =
+			fiji_clock_stretcher_lookup_table[stretch_amount2][1];
+	clock_freq_u16 = (uint16_t)(PP_SMC_TO_HOST_UL(data->smc_state_table.
+			GraphicsLevel[data->smc_state_table.GraphicsDpmLevelCount - 1].
+			SclkFrequency) / 100);
+	if (fiji_clock_stretcher_lookup_table[stretch_amount2][0] <
+			clock_freq_u16 &&
+	    fiji_clock_stretcher_lookup_table[stretch_amount2][1] >
+			clock_freq_u16) {
+		/* Program PWR_CKS_CNTL. CKS_USE_FOR_LOW_FREQ */
+		value |= (fiji_clock_stretcher_lookup_table[stretch_amount2][3]) << 16;
+		/* Program PWR_CKS_CNTL. CKS_LDO_REFSEL */
+		value |= (fiji_clock_stretcher_lookup_table[stretch_amount2][2]) << 18;
+		/* Program PWR_CKS_CNTL. CKS_STRETCH_AMOUNT */
+		value |= (fiji_clock_stretch_amount_conversion
+				[fiji_clock_stretcher_lookup_table[stretch_amount2][3]]
+				 [stretch_amount]) << 3;
+	}
+	CONVERT_FROM_HOST_TO_SMC_US(data->smc_state_table.CKS_LOOKUPTable.
+			CKS_LOOKUPTableEntry[0].minFreq);
+	CONVERT_FROM_HOST_TO_SMC_US(data->smc_state_table.CKS_LOOKUPTable.
+			CKS_LOOKUPTableEntry[0].maxFreq);
+	data->smc_state_table.CKS_LOOKUPTable.CKS_LOOKUPTableEntry[0].setting =
+			fiji_clock_stretcher_lookup_table[stretch_amount2][2] & 0x7F;
+	data->smc_state_table.CKS_LOOKUPTable.CKS_LOOKUPTableEntry[0].setting |=
+			(fiji_clock_stretcher_lookup_table[stretch_amount2][3]) << 7;
+
+	cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC,
+			ixPWR_CKS_CNTL, value);
+
+	/* Populate DDT Lookup Table */
+	for (i = 0; i < 4; i++) {
+		/* Assign the minimum and maximum VID stored
+		 * in the last row of Clock Stretcher Voltage Table.
+		 */
+		data->smc_state_table.ClockStretcherDataTable.
+		ClockStretcherDataTableEntry[i].minVID =
+				(uint8_t) fiji_clock_stretcher_ddt_table[type][i][2];
+		data->smc_state_table.ClockStretcherDataTable.
+		ClockStretcherDataTableEntry[i].maxVID =
+				(uint8_t) fiji_clock_stretcher_ddt_table[type][i][3];
+		/* Loop through each SCLK and check the frequency
+		 * to see if it lies within the frequency for clock stretcher.
+		 */
+		for (j = 0; j < data->smc_state_table.GraphicsDpmLevelCount; j++) {
+			cks_setting = 0;
+			clock_freq = PP_SMC_TO_HOST_UL(
+					data->smc_state_table.GraphicsLevel[j].SclkFrequency);
+			/* Check the allowed frequency against the sclk level[j].
+			 *  Sclk's endianness has already been converted,
+			 *  and it's in 10Khz unit,
+			 *  as opposed to Data table, which is in Mhz unit.
+			 */
+			if (clock_freq >=
+					(fiji_clock_stretcher_ddt_table[type][i][0]) * 100) {
+				cks_setting |= 0x2;
+				if (clock_freq <
+						(fiji_clock_stretcher_ddt_table[type][i][1]) * 100)
+					cks_setting |= 0x1;
+			}
+			data->smc_state_table.ClockStretcherDataTable.
+			ClockStretcherDataTableEntry[i].setting |= cks_setting << (j * 2);
+		}
+		CONVERT_FROM_HOST_TO_SMC_US(data->smc_state_table.
+				ClockStretcherDataTable.
+				ClockStretcherDataTableEntry[i].setting);
+	}
+
+	value = cgs_read_ind_register(hwmgr->device, CGS_IND_REG__SMC, ixPWR_CKS_CNTL);
+	value &= 0xFFFFFFFE;
+	cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC, ixPWR_CKS_CNTL, value);
+
+	return 0;
+}
+
+/**
+* Populates the SMC VRConfig field in DPM table.
+*
+* @param    hwmgr   the address of the hardware manager
+* @param    table   the SMC DPM table structure to be populated
+* @return   always 0
+*/
+static int fiji_populate_vr_config(struct pp_hwmgr *hwmgr,
+		struct SMU73_Discrete_DpmTable *table)
+{
+	struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend);
+	uint16_t config;
+
+	config = VR_MERGED_WITH_VDDC;
+	table->VRConfig |= (config << VRCONF_VDDGFX_SHIFT);
+
+	/* Set Vddc Voltage Controller */
+	if(FIJI_VOLTAGE_CONTROL_BY_SVID2 == data->voltage_control) {
+		config = VR_SVI2_PLANE_1;
+		table->VRConfig |= config;
+	} else {
+		PP_ASSERT_WITH_CODE(false,
+				"VDDC should be on SVI2 control in merged mode!",);
+	}
+	/* Set Vddci Voltage Controller */
+	if(FIJI_VOLTAGE_CONTROL_BY_SVID2 == data->vddci_control) {
+		config = VR_SVI2_PLANE_2;  /* only in merged mode */
+		table->VRConfig |= (config << VRCONF_VDDCI_SHIFT);
+	} else if (FIJI_VOLTAGE_CONTROL_BY_GPIO == data->vddci_control) {
+		config = VR_SMIO_PATTERN_1;
+		table->VRConfig |= (config << VRCONF_VDDCI_SHIFT);
+	} else {
+		config = VR_STATIC_VOLTAGE;
+		table->VRConfig |= (config << VRCONF_VDDCI_SHIFT);
+	}
+	/* Set Mvdd Voltage Controller */
+	if(FIJI_VOLTAGE_CONTROL_BY_SVID2 == data->mvdd_control) {
+		config = VR_SVI2_PLANE_2;
+		table->VRConfig |= (config << VRCONF_MVDD_SHIFT);
+	} else if(FIJI_VOLTAGE_CONTROL_BY_GPIO == data->mvdd_control) {
+		config = VR_SMIO_PATTERN_2;
+		table->VRConfig |= (config << VRCONF_MVDD_SHIFT);
+	} else {
+		config = VR_STATIC_VOLTAGE;
+		table->VRConfig |= (config << VRCONF_MVDD_SHIFT);
+	}
+
+	return 0;
+}
+
+/**
+* Initializes the SMC table and uploads it
+*
+* @param    hwmgr  the address of the powerplay hardware manager.
+* @param    pInput  the pointer to input data (PowerState)
+* @return   always 0
+*/
+static int fiji_init_smc_table(struct pp_hwmgr *hwmgr)
+{
+	int result;
+	struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend);
+	struct phm_ppt_v1_information *table_info =
+			(struct phm_ppt_v1_information *)(hwmgr->pptable);
+	struct SMU73_Discrete_DpmTable *table = &(data->smc_state_table);
+	const struct fiji_ulv_parm *ulv = &(data->ulv);
+	uint8_t i;
+	struct pp_atomctrl_gpio_pin_assignment gpio_pin;
+
+	result = fiji_setup_default_dpm_tables(hwmgr);
+	PP_ASSERT_WITH_CODE(0 == result,
+			"Failed to setup default DPM tables!", return result);
+
+	if(FIJI_VOLTAGE_CONTROL_NONE != data->voltage_control)
+		fiji_populate_smc_voltage_tables(hwmgr, table);
+
+	if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
+			PHM_PlatformCaps_AutomaticDCTransition))
+		table->SystemFlags |= PPSMC_SYSTEMFLAG_GPIO_DC;
+
+	if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
+			PHM_PlatformCaps_StepVddc))
+		table->SystemFlags |= PPSMC_SYSTEMFLAG_STEPVDDC;
+
+	if (data->is_memory_gddr5)
+		table->SystemFlags |= PPSMC_SYSTEMFLAG_GDDR5;
+
+	if (ulv->ulv_supported && table_info->us_ulv_voltage_offset) {
+		result = fiji_populate_ulv_state(hwmgr, table);
+		PP_ASSERT_WITH_CODE(0 == result,
+				"Failed to initialize ULV state!", return result);
+		cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC,
+				ixCG_ULV_PARAMETER, ulv->cg_ulv_parameter);
+	}
+
+	result = fiji_populate_smc_link_level(hwmgr, table);
+	PP_ASSERT_WITH_CODE(0 == result,
+			"Failed to initialize Link Level!", return result);
+
+	result = fiji_populate_all_graphic_levels(hwmgr);
+	PP_ASSERT_WITH_CODE(0 == result,
+			"Failed to initialize Graphics Level!", return result);
+
+	result = fiji_populate_all_memory_levels(hwmgr);
+	PP_ASSERT_WITH_CODE(0 == result,
+			"Failed to initialize Memory Level!", return result);
+
+	result = fiji_populate_smc_acpi_level(hwmgr, table);
+	PP_ASSERT_WITH_CODE(0 == result,
+			"Failed to initialize ACPI Level!", return result);
+
+	result = fiji_populate_smc_vce_level(hwmgr, table);
+	PP_ASSERT_WITH_CODE(0 == result,
+			"Failed to initialize VCE Level!", return result);
+
+	result = fiji_populate_smc_acp_level(hwmgr, table);
+	PP_ASSERT_WITH_CODE(0 == result,
+			"Failed to initialize ACP Level!", return result);
+
+	result = fiji_populate_smc_samu_level(hwmgr, table);
+	PP_ASSERT_WITH_CODE(0 == result,
+			"Failed to initialize SAMU Level!", return result);
+
+	/* Since only the initial state is completely set up at this point
+	 * (the other states are just copies of the boot state) we only
+	 * need to populate the  ARB settings for the initial state.
+	 */
+	result = fiji_program_memory_timing_parameters(hwmgr);
+	PP_ASSERT_WITH_CODE(0 == result,
+			"Failed to Write ARB settings for the initial state.", return result);
+
+	result = fiji_populate_smc_uvd_level(hwmgr, table);
+	PP_ASSERT_WITH_CODE(0 == result,
+			"Failed to initialize UVD Level!", return result);
+
+	result = fiji_populate_smc_boot_level(hwmgr, table);
+	PP_ASSERT_WITH_CODE(0 == result,
+			"Failed to initialize Boot Level!", return result);
+
+	result = fiji_populate_smc_initailial_state(hwmgr);
+	PP_ASSERT_WITH_CODE(0 == result,
+			"Failed to initialize Boot State!", return result);
+
+	result = fiji_populate_bapm_parameters_in_dpm_table(hwmgr);
+	PP_ASSERT_WITH_CODE(0 == result,
+			"Failed to populate BAPM Parameters!", return result);
+
+	if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
+			PHM_PlatformCaps_ClockStretcher)) {
+		result = fiji_populate_clock_stretcher_data_table(hwmgr);
+		PP_ASSERT_WITH_CODE(0 == result,
+				"Failed to populate Clock Stretcher Data Table!",
+				return result);
+	}
+
+	table->GraphicsVoltageChangeEnable  = 1;
+	table->GraphicsThermThrottleEnable  = 1;
+	table->GraphicsInterval = 1;
+	table->VoltageInterval  = 1;
+	table->ThermalInterval  = 1;
+	table->TemperatureLimitHigh =
+			table_info->cac_dtp_table->usTargetOperatingTemp *
+			FIJI_Q88_FORMAT_CONVERSION_UNIT;
+	table->TemperatureLimitLow  =
+			(table_info->cac_dtp_table->usTargetOperatingTemp - 1) *
+			FIJI_Q88_FORMAT_CONVERSION_UNIT;
+	table->MemoryVoltageChangeEnable = 1;
+	table->MemoryInterval = 1;
+	table->VoltageResponseTime = 0;
+	table->PhaseResponseTime = 0;
+	table->MemoryThermThrottleEnable = 1;
+	table->PCIeBootLinkLevel = 0;      /* 0:Gen1 1:Gen2 2:Gen3*/
+	table->PCIeGenInterval = 1;
+
+	result = fiji_populate_vr_config(hwmgr, table);
+	PP_ASSERT_WITH_CODE(0 == result,
+			"Failed to populate VRConfig setting!", return result);
+
+	table->ThermGpio = 17;
+	table->SclkStepSize = 0x4000;
+
+	if (atomctrl_get_pp_assign_pin(hwmgr, VDDC_VRHOT_GPIO_PINID, &gpio_pin)) {
+		table->VRHotGpio = gpio_pin.uc_gpio_pin_bit_shift;
+		phm_cap_set(hwmgr->platform_descriptor.platformCaps,
+				PHM_PlatformCaps_RegulatorHot);
+	} else {
+		table->VRHotGpio = FIJI_UNUSED_GPIO_PIN;
+		phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
+				PHM_PlatformCaps_RegulatorHot);
+	}
+
+	if (atomctrl_get_pp_assign_pin(hwmgr, PP_AC_DC_SWITCH_GPIO_PINID,
+			&gpio_pin)) {
+		table->AcDcGpio = gpio_pin.uc_gpio_pin_bit_shift;
+		phm_cap_set(hwmgr->platform_descriptor.platformCaps,
+				PHM_PlatformCaps_AutomaticDCTransition);
+	} else {
+		table->AcDcGpio = FIJI_UNUSED_GPIO_PIN;
+		phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
+				PHM_PlatformCaps_AutomaticDCTransition);
+	}
+
+	/* Thermal Output GPIO */
+	if (atomctrl_get_pp_assign_pin(hwmgr, THERMAL_INT_OUTPUT_GPIO_PINID,
+			&gpio_pin)) {
+		phm_cap_set(hwmgr->platform_descriptor.platformCaps,
+				PHM_PlatformCaps_ThermalOutGPIO);
+
+		table->ThermOutGpio = gpio_pin.uc_gpio_pin_bit_shift;
+
+		/* For porlarity read GPIOPAD_A with assigned Gpio pin
+		 * since VBIOS will program this register to set 'inactive state',
+		 * driver can then determine 'active state' from this and
+		 * program SMU with correct polarity
+		 */
+		table->ThermOutPolarity = (0 == (cgs_read_register(hwmgr->device, mmGPIOPAD_A) &
+				(1 << gpio_pin.uc_gpio_pin_bit_shift))) ? 1:0;
+		table->ThermOutMode = SMU7_THERM_OUT_MODE_THERM_ONLY;
+
+		/* if required, combine VRHot/PCC with thermal out GPIO */
+		if(phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
+				PHM_PlatformCaps_RegulatorHot) &&
+			phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
+					PHM_PlatformCaps_CombinePCCWithThermalSignal))
+			table->ThermOutMode = SMU7_THERM_OUT_MODE_THERM_VRHOT;
+	} else {
+		phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
+				PHM_PlatformCaps_ThermalOutGPIO);
+		table->ThermOutGpio = 17;
+		table->ThermOutPolarity = 1;
+		table->ThermOutMode = SMU7_THERM_OUT_MODE_DISABLE;
+	}
+
+	for (i = 0; i < SMU73_MAX_ENTRIES_SMIO; i++)
+		table->Smio[i] = PP_HOST_TO_SMC_UL(table->Smio[i]);
+
+	CONVERT_FROM_HOST_TO_SMC_UL(table->SystemFlags);
+	CONVERT_FROM_HOST_TO_SMC_UL(table->VRConfig);
+	CONVERT_FROM_HOST_TO_SMC_UL(table->SmioMask1);
+	CONVERT_FROM_HOST_TO_SMC_UL(table->SmioMask2);
+	CONVERT_FROM_HOST_TO_SMC_UL(table->SclkStepSize);
+	CONVERT_FROM_HOST_TO_SMC_US(table->TemperatureLimitHigh);
+	CONVERT_FROM_HOST_TO_SMC_US(table->TemperatureLimitLow);
+	CONVERT_FROM_HOST_TO_SMC_US(table->VoltageResponseTime);
+	CONVERT_FROM_HOST_TO_SMC_US(table->PhaseResponseTime);
+
+	/* Upload all dpm data to SMC memory.(dpm level, dpm level count etc) */
+	result = fiji_copy_bytes_to_smc(hwmgr->smumgr,
+			data->dpm_table_start +
+			offsetof(SMU73_Discrete_DpmTable, SystemFlags),
+			(uint8_t *)&(table->SystemFlags),
+			sizeof(SMU73_Discrete_DpmTable) - 3 * sizeof(SMU73_PIDController),
+			data->sram_end);
+	PP_ASSERT_WITH_CODE(0 == result,
+			"Failed to upload dpm data to SMC memory!", return result);
+
+	return 0;
+}
+
+/**
+* Initialize the ARB DRAM timing table's index field.
+*
+* @param    hwmgr  the address of the powerplay hardware manager.
+* @return   always 0
+*/
+static int fiji_init_arb_table_index(struct pp_hwmgr *hwmgr)
+{
+	const struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend);
+	uint32_t tmp;
+	int result;
+
+	/* This is a read-modify-write on the first byte of the ARB table.
+	 * The first byte in the SMU73_Discrete_MCArbDramTimingTable structure
+	 * is the field 'current'.
+	 * This solution is ugly, but we never write the whole table only
+	 * individual fields in it.
+	 * In reality this field should not be in that structure
+	 * but in a soft register.
+	 */
+	result = fiji_read_smc_sram_dword(hwmgr->smumgr,
+			data->arb_table_start, &tmp, data->sram_end);
+
+	if (result)
+		return result;
+
+	tmp &= 0x00FFFFFF;
+	tmp |= ((uint32_t)MC_CG_ARB_FREQ_F1) << 24;
+
+	return fiji_write_smc_sram_dword(hwmgr->smumgr,
+			data->arb_table_start,  tmp, data->sram_end);
+}
+
+static int fiji_enable_vrhot_gpio_interrupt(struct pp_hwmgr *hwmgr)
+{
+	if(phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
+			PHM_PlatformCaps_RegulatorHot))
+		return smum_send_msg_to_smc(hwmgr->smumgr,
+				PPSMC_MSG_EnableVRHotGPIOInterrupt);
+
+	return 0;
+}
+
+static int fiji_enable_sclk_control(struct pp_hwmgr *hwmgr)
+{
+	PHM_WRITE_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, SCLK_PWRMGT_CNTL,
+			SCLK_PWRMGT_OFF, 0);
+	return 0;
+}
+
+static int fiji_enable_ulv(struct pp_hwmgr *hwmgr)
+{
+	struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend);
+	struct fiji_ulv_parm *ulv = &(data->ulv);
+
+	if (ulv->ulv_supported)
+		return smum_send_msg_to_smc(hwmgr->smumgr, PPSMC_MSG_EnableULV);
+
+	return 0;
+}
+
+static int fiji_enable_deep_sleep_master_switch(struct pp_hwmgr *hwmgr)
+{
+	if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
+			PHM_PlatformCaps_SclkDeepSleep)) {
+		if (smum_send_msg_to_smc(hwmgr->smumgr, PPSMC_MSG_MASTER_DeepSleep_ON))
+			PP_ASSERT_WITH_CODE(false,
+					"Attempt to enable Master Deep Sleep switch failed!",
+					return -1);
+	} else {
+		if (smum_send_msg_to_smc(hwmgr->smumgr,
+				PPSMC_MSG_MASTER_DeepSleep_OFF)) {
+			PP_ASSERT_WITH_CODE(false,
+					"Attempt to disable Master Deep Sleep switch failed!",
+					return -1);
+		}
+	}
+
+	return 0;
+}
+
+static int fiji_enable_sclk_mclk_dpm(struct pp_hwmgr *hwmgr)
+{
+	struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend);
+	uint32_t   val, val0, val2;
+	uint32_t   i, cpl_cntl, cpl_threshold, mc_threshold;
+
+	/* enable SCLK dpm */
+	if(!data->sclk_dpm_key_disabled)
+		PP_ASSERT_WITH_CODE(
+		(0 == smum_send_msg_to_smc(hwmgr->smumgr, PPSMC_MSG_DPM_Enable)),
+		"Failed to enable SCLK DPM during DPM Start Function!",
+		return -1);
+
+	/* enable MCLK dpm */
+	if(0 == data->mclk_dpm_key_disabled) {
+		cpl_threshold = 0;
+		mc_threshold = 0;
+
+		/* Read per MCD tile (0 - 7) */
+		for (i = 0; i < 8; i++) {
+			PHM_WRITE_FIELD(hwmgr->device, MC_CONFIG_MCD, MC_RD_ENABLE, i);
+			val = cgs_read_register(hwmgr->device, mmMC_SEQ_RESERVE_0_S) & 0xf0000000;
+			if (0xf0000000 != val) {
+				/* count number of MCQ that has channel(s) enabled */
+				cpl_threshold++;
+				/* only harvest 3 or full 4 supported */
+				mc_threshold = val ? 3 : 4;
+			}
+		}
+		PP_ASSERT_WITH_CODE(0 != cpl_threshold,
+				"Number of MCQ is zero!", return -EINVAL;);
+
+		mc_threshold = ((mc_threshold & LCAC_MC0_CNTL__MC0_THRESHOLD_MASK) <<
+				LCAC_MC0_CNTL__MC0_THRESHOLD__SHIFT) |
+						LCAC_MC0_CNTL__MC0_ENABLE_MASK;
+		cpl_cntl = ((cpl_threshold & LCAC_CPL_CNTL__CPL_THRESHOLD_MASK) <<
+				LCAC_CPL_CNTL__CPL_THRESHOLD__SHIFT) |
+						LCAC_CPL_CNTL__CPL_ENABLE_MASK;
+		cpl_cntl = (cpl_cntl | (8 << LCAC_CPL_CNTL__CPL_BLOCK_ID__SHIFT));
+		cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC,
+				ixLCAC_MC0_CNTL, mc_threshold);
+		cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC,
+				ixLCAC_MC1_CNTL, mc_threshold);
+		if (8 == cpl_threshold) {
+			cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC,
+					ixLCAC_MC2_CNTL, mc_threshold);
+			cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC,
+					ixLCAC_MC3_CNTL, mc_threshold);
+			cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC,
+					ixLCAC_MC4_CNTL, mc_threshold);
+			cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC,
+					ixLCAC_MC5_CNTL, mc_threshold);
+			cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC,
+					ixLCAC_MC6_CNTL, mc_threshold);
+			cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC,
+					ixLCAC_MC7_CNTL, mc_threshold);
+		}
+		cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC,
+				ixLCAC_CPL_CNTL, cpl_cntl);
+
+		udelay(5);
+
+		mc_threshold = mc_threshold |
+				(1 << LCAC_MC0_CNTL__MC0_SIGNAL_ID__SHIFT);
+		cpl_cntl = cpl_cntl | (1 << LCAC_CPL_CNTL__CPL_SIGNAL_ID__SHIFT);
+		cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC,
+				ixLCAC_MC0_CNTL, mc_threshold);
+		cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC,
+				ixLCAC_MC1_CNTL, mc_threshold);
+		if (8 == cpl_threshold) {
+			cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC,
+					ixLCAC_MC2_CNTL, mc_threshold);
+			cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC,
+					ixLCAC_MC3_CNTL, mc_threshold);
+			cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC,
+					ixLCAC_MC4_CNTL, mc_threshold);
+			cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC,
+					ixLCAC_MC5_CNTL, mc_threshold);
+			cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC,
+					ixLCAC_MC6_CNTL, mc_threshold);
+			cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC,
+					ixLCAC_MC7_CNTL, mc_threshold);
+		}
+		cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC,
+				ixLCAC_CPL_CNTL, cpl_cntl);
+
+		/* Program CAC_EN per MCD (0-7) Tile */
+		val0 = val = cgs_read_register(hwmgr->device, mmMC_CONFIG_MCD);
+		val &= ~(MC_CONFIG_MCD__MCD0_WR_ENABLE_MASK |
+				MC_CONFIG_MCD__MCD1_WR_ENABLE_MASK |
+				MC_CONFIG_MCD__MCD2_WR_ENABLE_MASK |
+				MC_CONFIG_MCD__MCD3_WR_ENABLE_MASK |
+				MC_CONFIG_MCD__MCD4_WR_ENABLE_MASK |
+				MC_CONFIG_MCD__MCD5_WR_ENABLE_MASK |
+				MC_CONFIG_MCD__MCD6_WR_ENABLE_MASK |
+				MC_CONFIG_MCD__MCD7_WR_ENABLE_MASK |
+				MC_CONFIG_MCD__MC_RD_ENABLE_MASK);
+
+		for (i = 0; i < 8; i++) {
+			/* Enable MCD i Tile read & write */
+			val2  = (val | (i << MC_CONFIG_MCD__MC_RD_ENABLE__SHIFT) |
+					(1 << i));
+			cgs_write_register(hwmgr->device, mmMC_CONFIG_MCD, val2);
+			/* Enbale CAC_ON MCD i Tile */
+			val2 = cgs_read_register(hwmgr->device, mmMC_SEQ_CNTL);
+			val2 |= MC_SEQ_CNTL__CAC_EN_MASK;
+			cgs_write_register(hwmgr->device, mmMC_SEQ_CNTL, val2);
+		}
+		/* Set MC_CONFIG_MCD back to its default setting val0 */
+		cgs_write_register(hwmgr->device, mmMC_CONFIG_MCD, val0);
+
+		PP_ASSERT_WITH_CODE(
+				(0 == smum_send_msg_to_smc(hwmgr->smumgr,
+						PPSMC_MSG_MCLKDPM_Enable)),
+				"Failed to enable MCLK DPM during DPM Start Function!",
+				return -1);
+	}
+	return 0;
+}
+
+static int fiji_start_dpm(struct pp_hwmgr *hwmgr)
+{
+	struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend);
+
+	/*enable general power management */
+	PHM_WRITE_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, GENERAL_PWRMGT,
+			GLOBAL_PWRMGT_EN, 1);
+	/* enable sclk deep sleep */
+	PHM_WRITE_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, SCLK_PWRMGT_CNTL,
+			DYNAMIC_PM_EN, 1);
+	/* prepare for PCIE DPM */
+	cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC,
+			data->soft_regs_start + offsetof(SMU73_SoftRegisters,
+					VoltageChangeTimeout), 0x1000);
+	PHM_WRITE_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__PCIE,
+			SWRST_COMMAND_1, RESETLC, 0x0);
+
+	PP_ASSERT_WITH_CODE(
+			(0 == smum_send_msg_to_smc(hwmgr->smumgr,
+					PPSMC_MSG_Voltage_Cntl_Enable)),
+			"Failed to enable voltage DPM during DPM Start Function!",
+			return -1);
+
+	if (fiji_enable_sclk_mclk_dpm(hwmgr)) {
+		printk(KERN_ERR "Failed to enable Sclk DPM and Mclk DPM!");
+		return -1;
+	}
+
+	/* enable PCIE dpm */
+	if(!data->pcie_dpm_key_disabled) {
+		PP_ASSERT_WITH_CODE(
+				(0 == smum_send_msg_to_smc(hwmgr->smumgr,
+						PPSMC_MSG_PCIeDPM_Enable)),
+				"Failed to enable pcie DPM during DPM Start Function!",
+				return -1);
+	}
+
+	return 0;
+}
+
+static void fiji_set_dpm_event_sources(struct pp_hwmgr *hwmgr,
+		uint32_t sources)
+{
+	bool protection;
+	enum DPM_EVENT_SRC src;
+
+	switch (sources) {
+	default:
+		printk(KERN_ERR "Unknown throttling event sources.");
+		/* fall through */
+	case 0:
+		protection = false;
+		/* src is unused */
+		break;
+	case (1 << PHM_AutoThrottleSource_Thermal):
+		protection = true;
+		src = DPM_EVENT_SRC_DIGITAL;
+		break;
+	case (1 << PHM_AutoThrottleSource_External):
+		protection = true;
+		src = DPM_EVENT_SRC_EXTERNAL;
+		break;
+	case (1 << PHM_AutoThrottleSource_External) |
+			(1 << PHM_AutoThrottleSource_Thermal):
+		protection = true;
+		src = DPM_EVENT_SRC_DIGITAL_OR_EXTERNAL;
+		break;
+	}
+	/* Order matters - don't enable thermal protection for the wrong source. */
+	if (protection) {
+		PHM_WRITE_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, CG_THERMAL_CTRL,
+				DPM_EVENT_SRC, src);
+		PHM_WRITE_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, GENERAL_PWRMGT,
+				THERMAL_PROTECTION_DIS,
+				phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
+						PHM_PlatformCaps_ThermalController));
+	} else
+		PHM_WRITE_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, GENERAL_PWRMGT,
+				THERMAL_PROTECTION_DIS, 1);
+}
+
+static int fiji_enable_auto_throttle_source(struct pp_hwmgr *hwmgr,
+		PHM_AutoThrottleSource source)
+{
+	struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend);
+
+	if (!(data->active_auto_throttle_sources & (1 << source))) {
+		data->active_auto_throttle_sources |= 1 << source;
+		fiji_set_dpm_event_sources(hwmgr, data->active_auto_throttle_sources);
+	}
+	return 0;
+}
+
+static int fiji_enable_thermal_auto_throttle(struct pp_hwmgr *hwmgr)
+{
+	return fiji_enable_auto_throttle_source(hwmgr, PHM_AutoThrottleSource_Thermal);
+}
+
+static int fiji_enable_dpm_tasks(struct pp_hwmgr *hwmgr)
+{
+	int tmp_result, result = 0;
+
+	tmp_result = (!fiji_is_dpm_running(hwmgr))? 0 : -1;
+	PP_ASSERT_WITH_CODE(result == 0,
+			"DPM is already running right now, no need to enable DPM!",
+			return 0);
+
+	if (fiji_voltage_control(hwmgr)) {
+		tmp_result = fiji_enable_voltage_control(hwmgr);
+		PP_ASSERT_WITH_CODE(tmp_result == 0,
+				"Failed to enable voltage control!",
+				result = tmp_result);
+	}
+
+	if (fiji_voltage_control(hwmgr)) {
+		tmp_result = fiji_construct_voltage_tables(hwmgr);
+		PP_ASSERT_WITH_CODE((0 == tmp_result),
+				"Failed to contruct voltage tables!",
+				result = tmp_result);
+	}
+
+	tmp_result = fiji_initialize_mc_reg_table(hwmgr);
+	PP_ASSERT_WITH_CODE((0 == tmp_result),
+			"Failed to initialize MC reg table!", result = tmp_result);
+
+	if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
+			PHM_PlatformCaps_EngineSpreadSpectrumSupport))
+		PHM_WRITE_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC,
+				GENERAL_PWRMGT, DYN_SPREAD_SPECTRUM_EN, 1);
+
+	if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
+			PHM_PlatformCaps_ThermalController))
+		PHM_WRITE_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC,
+				GENERAL_PWRMGT, THERMAL_PROTECTION_DIS, 0);
+
+	tmp_result = fiji_program_static_screen_threshold_parameters(hwmgr);
+	PP_ASSERT_WITH_CODE((0 == tmp_result),
+			"Failed to program static screen threshold parameters!",
+			result = tmp_result);
+
+	tmp_result = fiji_enable_display_gap(hwmgr);
+	PP_ASSERT_WITH_CODE((0 == tmp_result),
+			"Failed to enable display gap!", result = tmp_result);
+
+	tmp_result = fiji_program_voting_clients(hwmgr);
+	PP_ASSERT_WITH_CODE((0 == tmp_result),
+			"Failed to program voting clients!", result = tmp_result);
+
+	tmp_result = fiji_process_firmware_header(hwmgr);
+	PP_ASSERT_WITH_CODE((0 == tmp_result),
+			"Failed to process firmware header!", result = tmp_result);
+
+	tmp_result = fiji_initial_switch_from_arbf0_to_f1(hwmgr);
+	PP_ASSERT_WITH_CODE((0 == tmp_result),
+			"Failed to initialize switch from ArbF0 to F1!",
+			result = tmp_result);
+
+	tmp_result = fiji_init_smc_table(hwmgr);
+	PP_ASSERT_WITH_CODE((0 == tmp_result),
+			"Failed to initialize SMC table!", result = tmp_result);
+
+	tmp_result = fiji_init_arb_table_index(hwmgr);
+	PP_ASSERT_WITH_CODE((0 == tmp_result),
+			"Failed to initialize ARB table index!", result = tmp_result);
+
+	tmp_result = fiji_populate_pm_fuses(hwmgr);
+	PP_ASSERT_WITH_CODE((0 == tmp_result),
+			"Failed to populate PM fuses!", result = tmp_result);
+
+	tmp_result = fiji_enable_vrhot_gpio_interrupt(hwmgr);
+	PP_ASSERT_WITH_CODE((0 == tmp_result),
+			"Failed to enable VR hot GPIO interrupt!", result = tmp_result);
+
+	tmp_result = tonga_notify_smc_display_change(hwmgr, false);
+	PP_ASSERT_WITH_CODE((0 == tmp_result),
+			"Failed to notify no display!", result = tmp_result);
+
+	tmp_result = fiji_enable_sclk_control(hwmgr);
+	PP_ASSERT_WITH_CODE((0 == tmp_result),
+			"Failed to enable SCLK control!", result = tmp_result);
+
+	tmp_result = fiji_enable_ulv(hwmgr);
+	PP_ASSERT_WITH_CODE((0 == tmp_result),
+			"Failed to enable ULV!", result = tmp_result);
+
+	tmp_result = fiji_enable_deep_sleep_master_switch(hwmgr);
+	PP_ASSERT_WITH_CODE((0 == tmp_result),
+			"Failed to enable deep sleep master switch!", result = tmp_result);
+
+	tmp_result = fiji_start_dpm(hwmgr);
+	PP_ASSERT_WITH_CODE((0 == tmp_result),
+			"Failed to start DPM!", result = tmp_result);
+
+	tmp_result = fiji_enable_smc_cac(hwmgr);
+	PP_ASSERT_WITH_CODE((0 == tmp_result),
+			"Failed to enable SMC CAC!", result = tmp_result);
+
+	tmp_result = fiji_enable_power_containment(hwmgr);
+	PP_ASSERT_WITH_CODE((0 == tmp_result),
+			"Failed to enable power containment!", result = tmp_result);
+
+	tmp_result = fiji_power_control_set_level(hwmgr);
+	PP_ASSERT_WITH_CODE((0 == tmp_result),
+			"Failed to power control set level!", result = tmp_result);
+
+	tmp_result = fiji_enable_thermal_auto_throttle(hwmgr);
+	PP_ASSERT_WITH_CODE((0 == tmp_result),
+			"Failed to enable thermal auto throttle!", result = tmp_result);
+
+	return result;
+}
+
+static int fiji_force_dpm_highest(struct pp_hwmgr *hwmgr)
+{
+	struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend);
+	uint32_t level, tmp;
+
+	if (!data->sclk_dpm_key_disabled) {
+		if (data->dpm_level_enable_mask.sclk_dpm_enable_mask) {
+			level = 0;
+			tmp = data->dpm_level_enable_mask.sclk_dpm_enable_mask;
+			while (tmp >>= 1)
+				level++;
+			if (level)
+				smum_send_msg_to_smc_with_parameter(hwmgr->smumgr,
+						PPSMC_MSG_SCLKDPM_SetEnabledMask,
+						(1 << level));
+		}
+	}
+
+	if (!data->mclk_dpm_key_disabled) {
+		if (data->dpm_level_enable_mask.mclk_dpm_enable_mask) {
+			level = 0;
+			tmp = data->dpm_level_enable_mask.mclk_dpm_enable_mask;
+			while (tmp >>= 1)
+				level++;
+			if (level)
+				smum_send_msg_to_smc_with_parameter(hwmgr->smumgr,
+						PPSMC_MSG_MCLKDPM_SetEnabledMask,
+						(1 << level));
+		}
+	}
+
+	if (!data->pcie_dpm_key_disabled) {
+		if (data->dpm_level_enable_mask.pcie_dpm_enable_mask) {
+			level = 0;
+			tmp = data->dpm_level_enable_mask.pcie_dpm_enable_mask;
+			while (tmp >>= 1)
+				level++;
+			if (level)
+				smum_send_msg_to_smc_with_parameter(hwmgr->smumgr,
+						PPSMC_MSG_PCIeDPM_ForceLevel,
+						(1 << level));
+		}
+	}
+	return 0;
+}
+
+static void fiji_apply_dal_min_voltage_request(struct pp_hwmgr *hwmgr)
+{
+	struct phm_ppt_v1_information *table_info =
+			(struct phm_ppt_v1_information *)hwmgr->pptable;
+	struct phm_clock_voltage_dependency_table *table =
+				table_info->vddc_dep_on_dal_pwrl;
+	struct phm_ppt_v1_clock_voltage_dependency_table *vddc_table;
+	enum PP_DAL_POWERLEVEL dal_power_level = hwmgr->dal_power_level;
+	uint32_t req_vddc = 0, req_volt, i;
+
+	if (!table && !(dal_power_level >= PP_DAL_POWERLEVEL_ULTRALOW &&
+			dal_power_level <= PP_DAL_POWERLEVEL_PERFORMANCE))
+		return;
+
+	for (i= 0; i < table->count; i++) {
+		if (dal_power_level == table->entries[i].clk) {
+			req_vddc = table->entries[i].v;
+			break;
+		}
+	}
+
+	vddc_table = table_info->vdd_dep_on_sclk;
+	for (i= 0; i < vddc_table->count; i++) {
+		if (req_vddc <= vddc_table->entries[i].vddc) {
+			req_volt = (((uint32_t)vddc_table->entries[i].vddc) * VOLTAGE_SCALE)
+					<< VDDC_SHIFT;
+			smum_send_msg_to_smc_with_parameter(hwmgr->smumgr,
+					PPSMC_MSG_VddC_Request, req_volt);
+			return;
+		}
+	}
+	printk(KERN_ERR "DAL requested level can not"
+			" found a available voltage in VDDC DPM Table \n");
+}
+
+static int fiji_upload_dpmlevel_enable_mask(struct pp_hwmgr *hwmgr)
+{
+	struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend);
+
+	fiji_apply_dal_min_voltage_request(hwmgr);
+
+	if (!data->sclk_dpm_key_disabled) {
+		if (data->dpm_level_enable_mask.sclk_dpm_enable_mask)
+			smum_send_msg_to_smc_with_parameter(hwmgr->smumgr,
+					PPSMC_MSG_SCLKDPM_SetEnabledMask,
+					data->dpm_level_enable_mask.sclk_dpm_enable_mask);
+	}
+	return 0;
+}
+
+static int fiji_unforce_dpm_levels(struct pp_hwmgr *hwmgr)
+{
+	struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend);
+
+	if (!fiji_is_dpm_running(hwmgr))
+		return -EINVAL;
+
+	if (!data->pcie_dpm_key_disabled) {
+		smum_send_msg_to_smc(hwmgr->smumgr,
+				PPSMC_MSG_PCIeDPM_UnForceLevel);
+	}
+
+	return fiji_upload_dpmlevel_enable_mask(hwmgr);
+}
+
+static uint32_t fiji_get_lowest_enabled_level(
+		struct pp_hwmgr *hwmgr, uint32_t mask)
+{
+	uint32_t level = 0;
+
+	while(0 == (mask & (1 << level)))
+		level++;
+
+	return level;
+}
+
+static int fiji_force_dpm_lowest(struct pp_hwmgr *hwmgr)
+{
+	struct fiji_hwmgr *data =
+			(struct fiji_hwmgr *)(hwmgr->backend);
+	uint32_t level;
+
+	if (!data->sclk_dpm_key_disabled)
+		if (data->dpm_level_enable_mask.sclk_dpm_enable_mask) {
+			level = fiji_get_lowest_enabled_level(hwmgr,
+							      data->dpm_level_enable_mask.sclk_dpm_enable_mask);
+			smum_send_msg_to_smc_with_parameter(hwmgr->smumgr,
+							    PPSMC_MSG_SCLKDPM_SetEnabledMask,
+							    (1 << level));
+
+	}
+
+	if (!data->mclk_dpm_key_disabled) {
+		if (data->dpm_level_enable_mask.mclk_dpm_enable_mask) {
+			level = fiji_get_lowest_enabled_level(hwmgr,
+							      data->dpm_level_enable_mask.mclk_dpm_enable_mask);
+			smum_send_msg_to_smc_with_parameter(hwmgr->smumgr,
+							    PPSMC_MSG_MCLKDPM_SetEnabledMask,
+							    (1 << level));
+		}
+	}
+
+	if (!data->pcie_dpm_key_disabled) {
+		if (data->dpm_level_enable_mask.pcie_dpm_enable_mask) {
+			level = fiji_get_lowest_enabled_level(hwmgr,
+							      data->dpm_level_enable_mask.pcie_dpm_enable_mask);
+			smum_send_msg_to_smc_with_parameter(hwmgr->smumgr,
+							    PPSMC_MSG_PCIeDPM_ForceLevel,
+							    (1 << level));
+		}
+	}
+
+	return 0;
+
+}
+static int fiji_dpm_force_dpm_level(struct pp_hwmgr *hwmgr,
+				enum amd_dpm_forced_level level)
+{
+	int ret = 0;
+
+	switch (level) {
+	case AMD_DPM_FORCED_LEVEL_HIGH:
+		ret = fiji_force_dpm_highest(hwmgr);
+		if (ret)
+			return ret;
+		break;
+	case AMD_DPM_FORCED_LEVEL_LOW:
+		ret = fiji_force_dpm_lowest(hwmgr);
+		if (ret)
+			return ret;
+		break;
+	case AMD_DPM_FORCED_LEVEL_AUTO:
+		ret = fiji_unforce_dpm_levels(hwmgr);
+		if (ret)
+			return ret;
+		break;
+	default:
+		break;
+	}
+
+	hwmgr->dpm_level = level;
+
+	return ret;
+}
+
+static int fiji_get_power_state_size(struct pp_hwmgr *hwmgr)
+{
+	return sizeof(struct fiji_power_state);
+}
+
+static int fiji_get_pp_table_entry_callback_func(struct pp_hwmgr *hwmgr,
+		void *state, struct pp_power_state *power_state,
+		void *pp_table, uint32_t classification_flag)
+{
+	struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend);
+	struct fiji_power_state  *fiji_power_state =
+			(struct fiji_power_state *)(&(power_state->hardware));
+	struct fiji_performance_level *performance_level;
+	ATOM_Tonga_State *state_entry = (ATOM_Tonga_State *)state;
+	ATOM_Tonga_POWERPLAYTABLE *powerplay_table =
+			(ATOM_Tonga_POWERPLAYTABLE *)pp_table;
+	ATOM_Tonga_SCLK_Dependency_Table *sclk_dep_table =
+			(ATOM_Tonga_SCLK_Dependency_Table *)
+			(((unsigned long)powerplay_table) +
+				le16_to_cpu(powerplay_table->usSclkDependencyTableOffset));
+	ATOM_Tonga_MCLK_Dependency_Table *mclk_dep_table =
+			(ATOM_Tonga_MCLK_Dependency_Table *)
+			(((unsigned long)powerplay_table) +
+				le16_to_cpu(powerplay_table->usMclkDependencyTableOffset));
+
+	/* The following fields are not initialized here: id orderedList allStatesList */
+	power_state->classification.ui_label =
+			(le16_to_cpu(state_entry->usClassification) &
+			ATOM_PPLIB_CLASSIFICATION_UI_MASK) >>
+			ATOM_PPLIB_CLASSIFICATION_UI_SHIFT;
+	power_state->classification.flags = classification_flag;
+	/* NOTE: There is a classification2 flag in BIOS that is not being used right now */
+
+	power_state->classification.temporary_state = false;
+	power_state->classification.to_be_deleted = false;
+
+	power_state->validation.disallowOnDC =
+			(0 != (le32_to_cpu(state_entry->ulCapsAndSettings) &
+					ATOM_Tonga_DISALLOW_ON_DC));
+
+	power_state->pcie.lanes = 0;
+
+	power_state->display.disableFrameModulation = false;
+	power_state->display.limitRefreshrate = false;
+	power_state->display.enableVariBright =
+			(0 != (le32_to_cpu(state_entry->ulCapsAndSettings) &
+					ATOM_Tonga_ENABLE_VARIBRIGHT));
+
+	power_state->validation.supportedPowerLevels = 0;
+	power_state->uvd_clocks.VCLK = 0;
+	power_state->uvd_clocks.DCLK = 0;
+	power_state->temperatures.min = 0;
+	power_state->temperatures.max = 0;
+
+	performance_level = &(fiji_power_state->performance_levels
+			[fiji_power_state->performance_level_count++]);
+
+	PP_ASSERT_WITH_CODE(
+			(fiji_power_state->performance_level_count < SMU73_MAX_LEVELS_GRAPHICS),
+			"Performance levels exceeds SMC limit!",
+			return -1);
+
+	PP_ASSERT_WITH_CODE(
+			(fiji_power_state->performance_level_count <=
+					hwmgr->platform_descriptor.hardwareActivityPerformanceLevels),
+			"Performance levels exceeds Driver limit!",
+			return -1);
+
+	/* Performance levels are arranged from low to high. */
+	performance_level->memory_clock = mclk_dep_table->entries
+			[state_entry->ucMemoryClockIndexLow].ulMclk;
+	performance_level->engine_clock = sclk_dep_table->entries
+			[state_entry->ucEngineClockIndexLow].ulSclk;
+	performance_level->pcie_gen = get_pcie_gen_support(data->pcie_gen_cap,
+			state_entry->ucPCIEGenLow);
+	performance_level->pcie_lane = get_pcie_lane_support(data->pcie_lane_cap,
+			state_entry->ucPCIELaneHigh);
+
+	performance_level = &(fiji_power_state->performance_levels
+			[fiji_power_state->performance_level_count++]);
+	performance_level->memory_clock = mclk_dep_table->entries
+			[state_entry->ucMemoryClockIndexHigh].ulMclk;
+	performance_level->engine_clock = sclk_dep_table->entries
+			[state_entry->ucEngineClockIndexHigh].ulSclk;
+	performance_level->pcie_gen = get_pcie_gen_support(data->pcie_gen_cap,
+			state_entry->ucPCIEGenHigh);
+	performance_level->pcie_lane = get_pcie_lane_support(data->pcie_lane_cap,
+			state_entry->ucPCIELaneHigh);
+
+	return 0;
+}
+
+static int fiji_get_pp_table_entry(struct pp_hwmgr *hwmgr,
+		unsigned long entry_index, struct pp_power_state *state)
+{
+	int result;
+	struct fiji_power_state *ps;
+	struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend);
+	struct phm_ppt_v1_information *table_info =
+			(struct phm_ppt_v1_information *)(hwmgr->pptable);
+	struct phm_ppt_v1_clock_voltage_dependency_table *dep_mclk_table =
+			table_info->vdd_dep_on_mclk;
+
+	state->hardware.magic = PHM_VIslands_Magic;
+
+	ps = (struct fiji_power_state *)(&state->hardware);
+
+	result = tonga_get_powerplay_table_entry(hwmgr, entry_index, state,
+			fiji_get_pp_table_entry_callback_func);
+
+	/* This is the earliest time we have all the dependency table and the VBIOS boot state
+	 * as PP_Tables_GetPowerPlayTableEntry retrieves the VBIOS boot state
+	 * if there is only one VDDCI/MCLK level, check if it's the same as VBIOS boot state
+	 */
+	if (dep_mclk_table != NULL && dep_mclk_table->count == 1) {
+		if (dep_mclk_table->entries[0].clk !=
+				data->vbios_boot_state.mclk_bootup_value)
+			printk(KERN_ERR "Single MCLK entry VDDCI/MCLK dependency table "
+					"does not match VBIOS boot MCLK level");
+		if (dep_mclk_table->entries[0].vddci !=
+				data->vbios_boot_state.vddci_bootup_value)
+			printk(KERN_ERR "Single VDDCI entry VDDCI/MCLK dependency table "
+					"does not match VBIOS boot VDDCI level");
+	}
+
+	/* set DC compatible flag if this state supports DC */
+	if (!state->validation.disallowOnDC)
+		ps->dc_compatible = true;
+
+	if (state->classification.flags & PP_StateClassificationFlag_ACPI)
+		data->acpi_pcie_gen = ps->performance_levels[0].pcie_gen;
+
+	ps->uvd_clks.vclk = state->uvd_clocks.VCLK;
+	ps->uvd_clks.dclk = state->uvd_clocks.DCLK;
+
+	if (!result) {
+		uint32_t i;
+
+		switch (state->classification.ui_label) {
+		case PP_StateUILabel_Performance:
+			data->use_pcie_performance_levels = true;
+
+			for (i = 0; i < ps->performance_level_count; i++) {
+				if (data->pcie_gen_performance.max <
+						ps->performance_levels[i].pcie_gen)
+					data->pcie_gen_performance.max =
+							ps->performance_levels[i].pcie_gen;
+
+				if (data->pcie_gen_performance.min >
+						ps->performance_levels[i].pcie_gen)
+					data->pcie_gen_performance.min =
+							ps->performance_levels[i].pcie_gen;
+
+				if (data->pcie_lane_performance.max <
+						ps->performance_levels[i].pcie_lane)
+					data->pcie_lane_performance.max =
+							ps->performance_levels[i].pcie_lane;
+
+				if (data->pcie_lane_performance.min >
+						ps->performance_levels[i].pcie_lane)
+					data->pcie_lane_performance.min =
+							ps->performance_levels[i].pcie_lane;
+			}
+			break;
+		case PP_StateUILabel_Battery:
+			data->use_pcie_power_saving_levels = true;
+
+			for (i = 0; i < ps->performance_level_count; i++) {
+				if (data->pcie_gen_power_saving.max <
+						ps->performance_levels[i].pcie_gen)
+					data->pcie_gen_power_saving.max =
+							ps->performance_levels[i].pcie_gen;
+
+				if (data->pcie_gen_power_saving.min >
+						ps->performance_levels[i].pcie_gen)
+					data->pcie_gen_power_saving.min =
+							ps->performance_levels[i].pcie_gen;
+
+				if (data->pcie_lane_power_saving.max <
+						ps->performance_levels[i].pcie_lane)
+					data->pcie_lane_power_saving.max =
+							ps->performance_levels[i].pcie_lane;
+
+				if (data->pcie_lane_power_saving.min >
+						ps->performance_levels[i].pcie_lane)
+					data->pcie_lane_power_saving.min =
+							ps->performance_levels[i].pcie_lane;
+			}
+			break;
+		default:
+			break;
+		}
+	}
+	return 0;
+}
+
+static int fiji_apply_state_adjust_rules(struct pp_hwmgr *hwmgr,
+				struct pp_power_state  *request_ps,
+			const struct pp_power_state *current_ps)
+{
+	struct fiji_power_state *fiji_ps =
+				cast_phw_fiji_power_state(&request_ps->hardware);
+	uint32_t sclk;
+	uint32_t mclk;
+	struct PP_Clocks minimum_clocks = {0};
+	bool disable_mclk_switching;
+	bool disable_mclk_switching_for_frame_lock;
+	struct cgs_display_info info = {0};
+	const struct phm_clock_and_voltage_limits *max_limits;
+	uint32_t i;
+	struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend);
+	struct phm_ppt_v1_information *table_info =
+			(struct phm_ppt_v1_information *)(hwmgr->pptable);
+	int32_t count;
+	int32_t stable_pstate_sclk = 0, stable_pstate_mclk = 0;
+
+	data->battery_state = (PP_StateUILabel_Battery ==
+			request_ps->classification.ui_label);
+
+	PP_ASSERT_WITH_CODE(fiji_ps->performance_level_count == 2,
+				 "VI should always have 2 performance levels",);
+
+	max_limits = (PP_PowerSource_AC == hwmgr->power_source) ?
+			&(hwmgr->dyn_state.max_clock_voltage_on_ac) :
+			&(hwmgr->dyn_state.max_clock_voltage_on_dc);
+
+	/* Cap clock DPM tables at DC MAX if it is in DC. */
+	if (PP_PowerSource_DC == hwmgr->power_source) {
+		for (i = 0; i < fiji_ps->performance_level_count; i++) {
+			if (fiji_ps->performance_levels[i].memory_clock > max_limits->mclk)
+				fiji_ps->performance_levels[i].memory_clock = max_limits->mclk;
+			if (fiji_ps->performance_levels[i].engine_clock > max_limits->sclk)
+				fiji_ps->performance_levels[i].engine_clock = max_limits->sclk;
+		}
+	}
+
+	fiji_ps->vce_clks.evclk = hwmgr->vce_arbiter.evclk;
+	fiji_ps->vce_clks.ecclk = hwmgr->vce_arbiter.ecclk;
+
+	fiji_ps->acp_clk = hwmgr->acp_arbiter.acpclk;
+
+	cgs_get_active_displays_info(hwmgr->device, &info);
+
+	/*TO DO result = PHM_CheckVBlankTime(hwmgr, &vblankTooShort);*/
+
+	/* TO DO GetMinClockSettings(hwmgr->pPECI, &minimum_clocks); */
+
+	if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
+			PHM_PlatformCaps_StablePState)) {
+		max_limits = &(hwmgr->dyn_state.max_clock_voltage_on_ac);
+		stable_pstate_sclk = (max_limits->sclk * 75) / 100;
+
+		for (count = table_info->vdd_dep_on_sclk->count - 1;
+				count >= 0; count--) {
+			if (stable_pstate_sclk >=
+					table_info->vdd_dep_on_sclk->entries[count].clk) {
+				stable_pstate_sclk =
+						table_info->vdd_dep_on_sclk->entries[count].clk;
+				break;
+			}
+		}
+
+		if (count < 0)
+			stable_pstate_sclk = table_info->vdd_dep_on_sclk->entries[0].clk;
+
+		stable_pstate_mclk = max_limits->mclk;
+
+		minimum_clocks.engineClock = stable_pstate_sclk;
+		minimum_clocks.memoryClock = stable_pstate_mclk;
+	}
+
+	if (minimum_clocks.engineClock < hwmgr->gfx_arbiter.sclk)
+		minimum_clocks.engineClock = hwmgr->gfx_arbiter.sclk;
+
+	if (minimum_clocks.memoryClock < hwmgr->gfx_arbiter.mclk)
+		minimum_clocks.memoryClock = hwmgr->gfx_arbiter.mclk;
+
+	fiji_ps->sclk_threshold = hwmgr->gfx_arbiter.sclk_threshold;
+
+	if (0 != hwmgr->gfx_arbiter.sclk_over_drive) {
+		PP_ASSERT_WITH_CODE((hwmgr->gfx_arbiter.sclk_over_drive <=
+				hwmgr->platform_descriptor.overdriveLimit.engineClock),
+				"Overdrive sclk exceeds limit",
+				hwmgr->gfx_arbiter.sclk_over_drive =
+						hwmgr->platform_descriptor.overdriveLimit.engineClock);
+
+		if (hwmgr->gfx_arbiter.sclk_over_drive >= hwmgr->gfx_arbiter.sclk)
+			fiji_ps->performance_levels[1].engine_clock =
+					hwmgr->gfx_arbiter.sclk_over_drive;
+	}
+
+	if (0 != hwmgr->gfx_arbiter.mclk_over_drive) {
+		PP_ASSERT_WITH_CODE((hwmgr->gfx_arbiter.mclk_over_drive <=
+				hwmgr->platform_descriptor.overdriveLimit.memoryClock),
+				"Overdrive mclk exceeds limit",
+				hwmgr->gfx_arbiter.mclk_over_drive =
+						hwmgr->platform_descriptor.overdriveLimit.memoryClock);
+
+		if (hwmgr->gfx_arbiter.mclk_over_drive >= hwmgr->gfx_arbiter.mclk)
+			fiji_ps->performance_levels[1].memory_clock =
+					hwmgr->gfx_arbiter.mclk_over_drive;
+	}
+
+	disable_mclk_switching_for_frame_lock = phm_cap_enabled(
+				    hwmgr->platform_descriptor.platformCaps,
+				    PHM_PlatformCaps_DisableMclkSwitchingForFrameLock);
+
+	disable_mclk_switching = (1 < info.display_count) ||
+				    disable_mclk_switching_for_frame_lock;
+
+	sclk = fiji_ps->performance_levels[0].engine_clock;
+	mclk = fiji_ps->performance_levels[0].memory_clock;
+
+	if (disable_mclk_switching)
+		mclk = fiji_ps->performance_levels
+		[fiji_ps->performance_level_count - 1].memory_clock;
+
+	if (sclk < minimum_clocks.engineClock)
+		sclk = (minimum_clocks.engineClock > max_limits->sclk) ?
+				max_limits->sclk : minimum_clocks.engineClock;
+
+	if (mclk < minimum_clocks.memoryClock)
+		mclk = (minimum_clocks.memoryClock > max_limits->mclk) ?
+				max_limits->mclk : minimum_clocks.memoryClock;
+
+	fiji_ps->performance_levels[0].engine_clock = sclk;
+	fiji_ps->performance_levels[0].memory_clock = mclk;
+
+	fiji_ps->performance_levels[1].engine_clock =
+		(fiji_ps->performance_levels[1].engine_clock >=
+				fiji_ps->performance_levels[0].engine_clock) ?
+						fiji_ps->performance_levels[1].engine_clock :
+						fiji_ps->performance_levels[0].engine_clock;
+
+	if (disable_mclk_switching) {
+		if (mclk < fiji_ps->performance_levels[1].memory_clock)
+			mclk = fiji_ps->performance_levels[1].memory_clock;
+
+		fiji_ps->performance_levels[0].memory_clock = mclk;
+		fiji_ps->performance_levels[1].memory_clock = mclk;
+	} else {
+		if (fiji_ps->performance_levels[1].memory_clock <
+				fiji_ps->performance_levels[0].memory_clock)
+			fiji_ps->performance_levels[1].memory_clock =
+					fiji_ps->performance_levels[0].memory_clock;
+	}
+
+	if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
+			PHM_PlatformCaps_StablePState)) {
+		for (i = 0; i < fiji_ps->performance_level_count; i++) {
+			fiji_ps->performance_levels[i].engine_clock = stable_pstate_sclk;
+			fiji_ps->performance_levels[i].memory_clock = stable_pstate_mclk;
+			fiji_ps->performance_levels[i].pcie_gen = data->pcie_gen_performance.max;
+			fiji_ps->performance_levels[i].pcie_lane = data->pcie_gen_performance.max;
+		}
+	}
+
+	return 0;
+}
+
+static int fiji_find_dpm_states_clocks_in_dpm_table(struct pp_hwmgr *hwmgr, const void *input)
+{
+	const struct phm_set_power_state_input *states =
+			(const struct phm_set_power_state_input *)input;
+	const struct fiji_power_state *fiji_ps =
+			cast_const_phw_fiji_power_state(states->pnew_state);
+	struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend);
+	struct fiji_single_dpm_table *sclk_table = &(data->dpm_table.sclk_table);
+	uint32_t sclk = fiji_ps->performance_levels
+			[fiji_ps->performance_level_count - 1].engine_clock;
+	struct fiji_single_dpm_table *mclk_table = &(data->dpm_table.mclk_table);
+	uint32_t mclk = fiji_ps->performance_levels
+			[fiji_ps->performance_level_count - 1].memory_clock;
+	struct PP_Clocks min_clocks = {0};
+	uint32_t i;
+	struct cgs_display_info info = {0};
+
+	data->need_update_smu7_dpm_table = 0;
+
+	for (i = 0; i < sclk_table->count; i++) {
+		if (sclk == sclk_table->dpm_levels[i].value)
+			break;
+	}
+
+	if (i >= sclk_table->count)
+		data->need_update_smu7_dpm_table |= DPMTABLE_OD_UPDATE_SCLK;
+	else {
+	/* TODO: Check SCLK in DAL's minimum clocks
+	 * in case DeepSleep divider update is required.
+	 */
+		if(data->display_timing.min_clock_in_sr != min_clocks.engineClockInSR)
+			data->need_update_smu7_dpm_table |= DPMTABLE_UPDATE_SCLK;
+	}
+
+	for (i = 0; i < mclk_table->count; i++) {
+		if (mclk == mclk_table->dpm_levels[i].value)
+			break;
+	}
+
+	if (i >= mclk_table->count)
+		data->need_update_smu7_dpm_table |= DPMTABLE_OD_UPDATE_MCLK;
+
+	cgs_get_active_displays_info(hwmgr->device, &info);
+
+	if (data->display_timing.num_existing_displays != info.display_count)
+		data->need_update_smu7_dpm_table |= DPMTABLE_UPDATE_MCLK;
+
+	return 0;
+}
+
+static uint16_t fiji_get_maximum_link_speed(struct pp_hwmgr *hwmgr,
+		const struct fiji_power_state *fiji_ps)
+{
+	uint32_t i;
+	uint32_t sclk, max_sclk = 0;
+	struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend);
+	struct fiji_dpm_table *dpm_table = &data->dpm_table;
+
+	for (i = 0; i < fiji_ps->performance_level_count; i++) {
+		sclk = fiji_ps->performance_levels[i].engine_clock;
+		if (max_sclk < sclk)
+			max_sclk = sclk;
+	}
+
+	for (i = 0; i < dpm_table->sclk_table.count; i++) {
+		if (dpm_table->sclk_table.dpm_levels[i].value == max_sclk)
+			return (uint16_t) ((i >= dpm_table->pcie_speed_table.count) ?
+					dpm_table->pcie_speed_table.dpm_levels
+					[dpm_table->pcie_speed_table.count - 1].value :
+					dpm_table->pcie_speed_table.dpm_levels[i].value);
+	}
+
+	return 0;
+}
+
+static int fiji_request_link_speed_change_before_state_change(
+		struct pp_hwmgr *hwmgr, const void *input)
+{
+	const struct phm_set_power_state_input *states =
+			(const struct phm_set_power_state_input *)input;
+	struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend);
+	const struct fiji_power_state *fiji_nps =
+			cast_const_phw_fiji_power_state(states->pnew_state);
+	const struct fiji_power_state *fiji_cps =
+			cast_const_phw_fiji_power_state(states->pcurrent_state);
+
+	uint16_t target_link_speed = fiji_get_maximum_link_speed(hwmgr, fiji_nps);
+	uint16_t current_link_speed;
+
+	if (data->force_pcie_gen == PP_PCIEGenInvalid)
+		current_link_speed = fiji_get_maximum_link_speed(hwmgr, fiji_cps);
+	else
+		current_link_speed = data->force_pcie_gen;
+
+	data->force_pcie_gen = PP_PCIEGenInvalid;
+	data->pspp_notify_required = false;
+	if (target_link_speed > current_link_speed) {
+		switch(target_link_speed) {
+		case PP_PCIEGen3:
+			if (0 == acpi_pcie_perf_request(hwmgr->device, PCIE_PERF_REQ_GEN3, false))
+				break;
+			data->force_pcie_gen = PP_PCIEGen2;
+			if (current_link_speed == PP_PCIEGen2)
+				break;
+		case PP_PCIEGen2:
+			if (0 == acpi_pcie_perf_request(hwmgr->device, PCIE_PERF_REQ_GEN2, false))
+				break;
+		default:
+			data->force_pcie_gen = fiji_get_current_pcie_speed(hwmgr);
+			break;
+		}
+	} else {
+		if (target_link_speed < current_link_speed)
+			data->pspp_notify_required = true;
+	}
+
+	return 0;
+}
+
+static int fiji_freeze_sclk_mclk_dpm(struct pp_hwmgr *hwmgr)
+{
+	struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend);
+
+	if (0 == data->need_update_smu7_dpm_table)
+		return 0;
+
+	if ((0 == data->sclk_dpm_key_disabled) &&
+		(data->need_update_smu7_dpm_table &
+			(DPMTABLE_OD_UPDATE_SCLK + DPMTABLE_UPDATE_SCLK))) {
+		PP_ASSERT_WITH_CODE(true == fiji_is_dpm_running(hwmgr),
+				"Trying to freeze SCLK DPM when DPM is disabled",);
+		PP_ASSERT_WITH_CODE(0 == smum_send_msg_to_smc(hwmgr->smumgr,
+				PPSMC_MSG_SCLKDPM_FreezeLevel),
+				"Failed to freeze SCLK DPM during FreezeSclkMclkDPM Function!",
+				return -1);
+	}
+
+	if ((0 == data->mclk_dpm_key_disabled) &&
+		(data->need_update_smu7_dpm_table &
+		 DPMTABLE_OD_UPDATE_MCLK)) {
+		PP_ASSERT_WITH_CODE(true == fiji_is_dpm_running(hwmgr),
+				"Trying to freeze MCLK DPM when DPM is disabled",);
+		PP_ASSERT_WITH_CODE(0 == smum_send_msg_to_smc(hwmgr->smumgr,
+				PPSMC_MSG_MCLKDPM_FreezeLevel),
+				"Failed to freeze MCLK DPM during FreezeSclkMclkDPM Function!",
+				return -1);
+	}
+
+	return 0;
+}
+
+static int fiji_populate_and_upload_sclk_mclk_dpm_levels(
+		struct pp_hwmgr *hwmgr, const void *input)
+{
+	int result = 0;
+	const struct phm_set_power_state_input *states =
+			(const struct phm_set_power_state_input *)input;
+	const struct fiji_power_state *fiji_ps =
+			cast_const_phw_fiji_power_state(states->pnew_state);
+	struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend);
+	uint32_t sclk = fiji_ps->performance_levels
+			[fiji_ps->performance_level_count - 1].engine_clock;
+	uint32_t mclk = fiji_ps->performance_levels
+			[fiji_ps->performance_level_count - 1].memory_clock;
+	struct fiji_dpm_table *dpm_table = &data->dpm_table;
+
+	struct fiji_dpm_table *golden_dpm_table = &data->golden_dpm_table;
+	uint32_t dpm_count, clock_percent;
+	uint32_t i;
+
+	if (0 == data->need_update_smu7_dpm_table)
+		return 0;
+
+	if (data->need_update_smu7_dpm_table & DPMTABLE_OD_UPDATE_SCLK) {
+		dpm_table->sclk_table.dpm_levels
+		[dpm_table->sclk_table.count - 1].value = sclk;
+
+		if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
+				PHM_PlatformCaps_OD6PlusinACSupport) ||
+			phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
+					PHM_PlatformCaps_OD6PlusinDCSupport)) {
+		/* Need to do calculation based on the golden DPM table
+		 * as the Heatmap GPU Clock axis is also based on the default values
+		 */
+			PP_ASSERT_WITH_CODE(
+				(golden_dpm_table->sclk_table.dpm_levels
+						[golden_dpm_table->sclk_table.count - 1].value != 0),
+				"Divide by 0!",
+				return -1);
+			dpm_count = dpm_table->sclk_table.count < 2 ?
+					0 : dpm_table->sclk_table.count - 2;
+			for (i = dpm_count; i > 1; i--) {
+				if (sclk > golden_dpm_table->sclk_table.dpm_levels
+						[golden_dpm_table->sclk_table.count-1].value) {
+					clock_percent =
+						((sclk - golden_dpm_table->sclk_table.dpm_levels
+							[golden_dpm_table->sclk_table.count-1].value) * 100) /
+						golden_dpm_table->sclk_table.dpm_levels
+							[golden_dpm_table->sclk_table.count-1].value;
+
+					dpm_table->sclk_table.dpm_levels[i].value =
+							golden_dpm_table->sclk_table.dpm_levels[i].value +
+							(golden_dpm_table->sclk_table.dpm_levels[i].value *
+								clock_percent)/100;
+
+				} else if (golden_dpm_table->sclk_table.dpm_levels
+						[dpm_table->sclk_table.count-1].value > sclk) {
+					clock_percent =
+						((golden_dpm_table->sclk_table.dpm_levels
+						[golden_dpm_table->sclk_table.count - 1].value - sclk) *
+								100) /
+						golden_dpm_table->sclk_table.dpm_levels
+							[golden_dpm_table->sclk_table.count-1].value;
+
+					dpm_table->sclk_table.dpm_levels[i].value =
+							golden_dpm_table->sclk_table.dpm_levels[i].value -
+							(golden_dpm_table->sclk_table.dpm_levels[i].value *
+									clock_percent) / 100;
+				} else
+					dpm_table->sclk_table.dpm_levels[i].value =
+							golden_dpm_table->sclk_table.dpm_levels[i].value;
+			}
+		}
+	}
+
+	if (data->need_update_smu7_dpm_table & DPMTABLE_OD_UPDATE_MCLK) {
+		dpm_table->mclk_table.dpm_levels
+			[dpm_table->mclk_table.count - 1].value = mclk;
+
+		if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
+				PHM_PlatformCaps_OD6PlusinACSupport) ||
+			phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
+				PHM_PlatformCaps_OD6PlusinDCSupport)) {
+
+			PP_ASSERT_WITH_CODE(
+					(golden_dpm_table->mclk_table.dpm_levels
+						[golden_dpm_table->mclk_table.count-1].value != 0),
+					"Divide by 0!",
+					return -1);
+			dpm_count = dpm_table->mclk_table.count < 2 ?
+					0 : dpm_table->mclk_table.count - 2;
+			for (i = dpm_count; i > 1; i--) {
+				if (mclk > golden_dpm_table->mclk_table.dpm_levels
+						[golden_dpm_table->mclk_table.count-1].value) {
+					clock_percent = ((mclk -
+							golden_dpm_table->mclk_table.dpm_levels
+							[golden_dpm_table->mclk_table.count-1].value) * 100) /
+							golden_dpm_table->mclk_table.dpm_levels
+							[golden_dpm_table->mclk_table.count-1].value;
+
+					dpm_table->mclk_table.dpm_levels[i].value =
+							golden_dpm_table->mclk_table.dpm_levels[i].value +
+							(golden_dpm_table->mclk_table.dpm_levels[i].value *
+									clock_percent) / 100;
+
+				} else if (golden_dpm_table->mclk_table.dpm_levels
+						[dpm_table->mclk_table.count-1].value > mclk) {
+					clock_percent = ((golden_dpm_table->mclk_table.dpm_levels
+							[golden_dpm_table->mclk_table.count-1].value - mclk) * 100) /
+									golden_dpm_table->mclk_table.dpm_levels
+									[golden_dpm_table->mclk_table.count-1].value;
+
+					dpm_table->mclk_table.dpm_levels[i].value =
+							golden_dpm_table->mclk_table.dpm_levels[i].value -
+							(golden_dpm_table->mclk_table.dpm_levels[i].value *
+									clock_percent) / 100;
+				} else
+					dpm_table->mclk_table.dpm_levels[i].value =
+							golden_dpm_table->mclk_table.dpm_levels[i].value;
+			}
+		}
+	}
+
+	if (data->need_update_smu7_dpm_table &
+			(DPMTABLE_OD_UPDATE_SCLK + DPMTABLE_UPDATE_SCLK)) {
+		result = fiji_populate_all_memory_levels(hwmgr);
+		PP_ASSERT_WITH_CODE((0 == result),
+				"Failed to populate SCLK during PopulateNewDPMClocksStates Function!",
+				return result);
+	}
+
+	if (data->need_update_smu7_dpm_table &
+			(DPMTABLE_OD_UPDATE_MCLK + DPMTABLE_UPDATE_MCLK)) {
+		/*populate MCLK dpm table to SMU7 */
+		result = fiji_populate_all_memory_levels(hwmgr);
+		PP_ASSERT_WITH_CODE((0 == result),
+				"Failed to populate MCLK during PopulateNewDPMClocksStates Function!",
+				return result);
+	}
+
+	return result;
+}
+
+static int fiji_trim_single_dpm_states(struct pp_hwmgr *hwmgr,
+			  struct fiji_single_dpm_table * dpm_table,
+			     uint32_t low_limit, uint32_t high_limit)
+{
+	uint32_t i;
+
+	for (i = 0; i < dpm_table->count; i++) {
+		if ((dpm_table->dpm_levels[i].value < low_limit) ||
+		    (dpm_table->dpm_levels[i].value > high_limit))
+			dpm_table->dpm_levels[i].enabled = false;
+		else
+			dpm_table->dpm_levels[i].enabled = true;
+	}
+	return 0;
+}
+
+static int fiji_trim_dpm_states(struct pp_hwmgr *hwmgr,
+		const struct fiji_power_state *fiji_ps)
+{
+	int result = 0;
+	struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend);
+	uint32_t high_limit_count;
+
+	PP_ASSERT_WITH_CODE((fiji_ps->performance_level_count >= 1),
+			"power state did not have any performance level",
+			return -1);
+
+	high_limit_count = (1 == fiji_ps->performance_level_count) ? 0 : 1;
+
+	fiji_trim_single_dpm_states(hwmgr,
+			&(data->dpm_table.sclk_table),
+			fiji_ps->performance_levels[0].engine_clock,
+			fiji_ps->performance_levels[high_limit_count].engine_clock);
+
+	fiji_trim_single_dpm_states(hwmgr,
+			&(data->dpm_table.mclk_table),
+			fiji_ps->performance_levels[0].memory_clock,
+			fiji_ps->performance_levels[high_limit_count].memory_clock);
+
+	return result;
+}
+
+static int fiji_generate_dpm_level_enable_mask(
+		struct pp_hwmgr *hwmgr, const void *input)
+{
+	int result;
+	const struct phm_set_power_state_input *states =
+			(const struct phm_set_power_state_input *)input;
+	struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend);
+	const struct fiji_power_state *fiji_ps =
+			cast_const_phw_fiji_power_state(states->pnew_state);
+
+	result = fiji_trim_dpm_states(hwmgr, fiji_ps);
+	if (result)
+		return result;
+
+	data->dpm_level_enable_mask.sclk_dpm_enable_mask =
+			fiji_get_dpm_level_enable_mask_value(&data->dpm_table.sclk_table);
+	data->dpm_level_enable_mask.mclk_dpm_enable_mask =
+			fiji_get_dpm_level_enable_mask_value(&data->dpm_table.mclk_table);
+	data->last_mclk_dpm_enable_mask =
+			data->dpm_level_enable_mask.mclk_dpm_enable_mask;
+
+	if (data->uvd_enabled) {
+		if (data->dpm_level_enable_mask.mclk_dpm_enable_mask & 1)
+			data->dpm_level_enable_mask.mclk_dpm_enable_mask &= 0xFFFFFFFE;
+	}
+
+	data->dpm_level_enable_mask.pcie_dpm_enable_mask =
+			fiji_get_dpm_level_enable_mask_value(&data->dpm_table.pcie_speed_table);
+
+	return 0;
+}
+
+int fiji_enable_disable_uvd_dpm(struct pp_hwmgr *hwmgr, bool enable)
+{
+	return smum_send_msg_to_smc(hwmgr->smumgr, enable ?
+				  (PPSMC_Msg)PPSMC_MSG_UVDDPM_Enable :
+				  (PPSMC_Msg)PPSMC_MSG_UVDDPM_Disable);
+}
+
+int fiji_enable_disable_vce_dpm(struct pp_hwmgr *hwmgr, bool enable)
+{
+	return smum_send_msg_to_smc(hwmgr->smumgr, enable?
+			PPSMC_MSG_VCEDPM_Enable :
+			PPSMC_MSG_VCEDPM_Disable);
+}
+
+int fiji_enable_disable_samu_dpm(struct pp_hwmgr *hwmgr, bool enable)
+{
+	return smum_send_msg_to_smc(hwmgr->smumgr, enable?
+			PPSMC_MSG_SAMUDPM_Enable :
+			PPSMC_MSG_SAMUDPM_Disable);
+}
+
+int fiji_enable_disable_acp_dpm(struct pp_hwmgr *hwmgr, bool enable)
+{
+	return smum_send_msg_to_smc(hwmgr->smumgr, enable?
+			PPSMC_MSG_ACPDPM_Enable :
+			PPSMC_MSG_ACPDPM_Disable);
+}
+
+int fiji_update_uvd_dpm(struct pp_hwmgr *hwmgr, bool bgate)
+{
+	struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend);
+	uint32_t mm_boot_level_offset, mm_boot_level_value;
+	struct phm_ppt_v1_information *table_info =
+			(struct phm_ppt_v1_information *)(hwmgr->pptable);
+
+	if (!bgate) {
+		data->smc_state_table.UvdBootLevel = 0;
+		if (table_info->mm_dep_table->count > 0)
+			data->smc_state_table.UvdBootLevel =
+					(uint8_t) (table_info->mm_dep_table->count - 1);
+		mm_boot_level_offset = data->dpm_table_start +
+				offsetof(SMU73_Discrete_DpmTable, UvdBootLevel);
+		mm_boot_level_offset /= 4;
+		mm_boot_level_offset *= 4;
+		mm_boot_level_value = cgs_read_ind_register(hwmgr->device,
+				CGS_IND_REG__SMC, mm_boot_level_offset);
+		mm_boot_level_value &= 0x00FFFFFF;
+		mm_boot_level_value |= data->smc_state_table.UvdBootLevel << 24;
+		cgs_write_ind_register(hwmgr->device,
+				CGS_IND_REG__SMC, mm_boot_level_offset, mm_boot_level_value);
+
+		if (!phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
+				PHM_PlatformCaps_UVDDPM) ||
+			phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
+				PHM_PlatformCaps_StablePState))
+			smum_send_msg_to_smc_with_parameter(hwmgr->smumgr,
+					PPSMC_MSG_UVDDPM_SetEnabledMask,
+					(uint32_t)(1 << data->smc_state_table.UvdBootLevel));
+	}
+
+	return fiji_enable_disable_uvd_dpm(hwmgr, !bgate);
+}
+
+int fiji_update_vce_dpm(struct pp_hwmgr *hwmgr, const void *input)
+{
+	const struct phm_set_power_state_input *states =
+			(const struct phm_set_power_state_input *)input;
+	struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend);
+	const struct fiji_power_state *fiji_nps =
+			cast_const_phw_fiji_power_state(states->pnew_state);
+	const struct fiji_power_state *fiji_cps =
+			cast_const_phw_fiji_power_state(states->pcurrent_state);
+
+	uint32_t mm_boot_level_offset, mm_boot_level_value;
+	struct phm_ppt_v1_information *table_info =
+			(struct phm_ppt_v1_information *)(hwmgr->pptable);
+
+	if (fiji_nps->vce_clks.evclk >0 &&
+	(fiji_cps == NULL || fiji_cps->vce_clks.evclk == 0)) {
+		data->smc_state_table.VceBootLevel =
+				(uint8_t) (table_info->mm_dep_table->count - 1);
+
+		mm_boot_level_offset = data->dpm_table_start +
+				offsetof(SMU73_Discrete_DpmTable, VceBootLevel);
+		mm_boot_level_offset /= 4;
+		mm_boot_level_offset *= 4;
+		mm_boot_level_value = cgs_read_ind_register(hwmgr->device,
+				CGS_IND_REG__SMC, mm_boot_level_offset);
+		mm_boot_level_value &= 0xFF00FFFF;
+		mm_boot_level_value |= data->smc_state_table.VceBootLevel << 16;
+		cgs_write_ind_register(hwmgr->device,
+				CGS_IND_REG__SMC, mm_boot_level_offset, mm_boot_level_value);
+
+		if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
+				PHM_PlatformCaps_StablePState)) {
+			smum_send_msg_to_smc_with_parameter(hwmgr->smumgr,
+					PPSMC_MSG_VCEDPM_SetEnabledMask,
+					(uint32_t)1 << data->smc_state_table.VceBootLevel);
+
+			fiji_enable_disable_vce_dpm(hwmgr, true);
+		} else if (fiji_nps->vce_clks.evclk == 0 &&
+				fiji_cps != NULL &&
+				fiji_cps->vce_clks.evclk > 0)
+			fiji_enable_disable_vce_dpm(hwmgr, false);
+	}
+
+	return 0;
+}
+
+int fiji_update_samu_dpm(struct pp_hwmgr *hwmgr, bool bgate)
+{
+	struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend);
+	uint32_t mm_boot_level_offset, mm_boot_level_value;
+	struct phm_ppt_v1_information *table_info =
+			(struct phm_ppt_v1_information *)(hwmgr->pptable);
+
+	if (!bgate) {
+		data->smc_state_table.SamuBootLevel =
+				(uint8_t) (table_info->mm_dep_table->count - 1);
+		mm_boot_level_offset = data->dpm_table_start +
+				offsetof(SMU73_Discrete_DpmTable, SamuBootLevel);
+		mm_boot_level_offset /= 4;
+		mm_boot_level_offset *= 4;
+		mm_boot_level_value = cgs_read_ind_register(hwmgr->device,
+				CGS_IND_REG__SMC, mm_boot_level_offset);
+		mm_boot_level_value &= 0xFFFFFF00;
+		mm_boot_level_value |= data->smc_state_table.SamuBootLevel << 0;
+		cgs_write_ind_register(hwmgr->device,
+				CGS_IND_REG__SMC, mm_boot_level_offset, mm_boot_level_value);
+
+		if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
+				PHM_PlatformCaps_StablePState))
+			smum_send_msg_to_smc_with_parameter(hwmgr->smumgr,
+					PPSMC_MSG_SAMUDPM_SetEnabledMask,
+					(uint32_t)(1 << data->smc_state_table.SamuBootLevel));
+	}
+
+	return fiji_enable_disable_samu_dpm(hwmgr, !bgate);
+}
+
+int fiji_update_acp_dpm(struct pp_hwmgr *hwmgr, bool bgate)
+{
+	struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend);
+	uint32_t mm_boot_level_offset, mm_boot_level_value;
+	struct phm_ppt_v1_information *table_info =
+			(struct phm_ppt_v1_information *)(hwmgr->pptable);
+
+	if (!bgate) {
+		data->smc_state_table.AcpBootLevel =
+				(uint8_t) (table_info->mm_dep_table->count - 1);
+		mm_boot_level_offset = data->dpm_table_start +
+				offsetof(SMU73_Discrete_DpmTable, AcpBootLevel);
+		mm_boot_level_offset /= 4;
+		mm_boot_level_offset *= 4;
+		mm_boot_level_value = cgs_read_ind_register(hwmgr->device,
+				CGS_IND_REG__SMC, mm_boot_level_offset);
+		mm_boot_level_value &= 0xFFFF00FF;
+		mm_boot_level_value |= data->smc_state_table.AcpBootLevel << 8;
+		cgs_write_ind_register(hwmgr->device,
+				CGS_IND_REG__SMC, mm_boot_level_offset, mm_boot_level_value);
+
+		if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
+				PHM_PlatformCaps_StablePState))
+			smum_send_msg_to_smc_with_parameter(hwmgr->smumgr,
+						PPSMC_MSG_ACPDPM_SetEnabledMask,
+						(uint32_t)(1 << data->smc_state_table.AcpBootLevel));
+	}
+
+	return fiji_enable_disable_acp_dpm(hwmgr, !bgate);
+}
+
+static int fiji_update_sclk_threshold(struct pp_hwmgr *hwmgr)
+{
+	struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend);
+
+	int result = 0;
+	uint32_t low_sclk_interrupt_threshold = 0;
+
+	if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
+			PHM_PlatformCaps_SclkThrottleLowNotification)
+		&& (hwmgr->gfx_arbiter.sclk_threshold !=
+				data->low_sclk_interrupt_threshold)) {
+		data->low_sclk_interrupt_threshold =
+				hwmgr->gfx_arbiter.sclk_threshold;
+		low_sclk_interrupt_threshold =
+				data->low_sclk_interrupt_threshold;
+
+		CONVERT_FROM_HOST_TO_SMC_UL(low_sclk_interrupt_threshold);
+
+		result = fiji_copy_bytes_to_smc(
+				hwmgr->smumgr,
+				data->dpm_table_start +
+				offsetof(SMU73_Discrete_DpmTable,
+					LowSclkInterruptThreshold),
+				(uint8_t *)&low_sclk_interrupt_threshold,
+				sizeof(uint32_t),
+				data->sram_end);
+	}
+
+	return result;
+}
+
+static int fiji_program_mem_timing_parameters(struct pp_hwmgr *hwmgr)
+{
+	struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend);
+
+	if (data->need_update_smu7_dpm_table &
+		(DPMTABLE_OD_UPDATE_SCLK + DPMTABLE_OD_UPDATE_MCLK))
+		return fiji_program_memory_timing_parameters(hwmgr);
+
+	return 0;
+}
+
+static int fiji_unfreeze_sclk_mclk_dpm(struct pp_hwmgr *hwmgr)
+{
+	struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend);
+
+	if (0 == data->need_update_smu7_dpm_table)
+		return 0;
+
+	if ((0 == data->sclk_dpm_key_disabled) &&
+		(data->need_update_smu7_dpm_table &
+		(DPMTABLE_OD_UPDATE_SCLK + DPMTABLE_UPDATE_SCLK))) {
+
+		PP_ASSERT_WITH_CODE(true == fiji_is_dpm_running(hwmgr),
+				"Trying to Unfreeze SCLK DPM when DPM is disabled",);
+		PP_ASSERT_WITH_CODE(0 == smum_send_msg_to_smc(hwmgr->smumgr,
+				PPSMC_MSG_SCLKDPM_UnfreezeLevel),
+			"Failed to unfreeze SCLK DPM during UnFreezeSclkMclkDPM Function!",
+			return -1);
+	}
+
+	if ((0 == data->mclk_dpm_key_disabled) &&
+		(data->need_update_smu7_dpm_table & DPMTABLE_OD_UPDATE_MCLK)) {
+
+		PP_ASSERT_WITH_CODE(true == fiji_is_dpm_running(hwmgr),
+				"Trying to Unfreeze MCLK DPM when DPM is disabled",);
+		PP_ASSERT_WITH_CODE(0 == smum_send_msg_to_smc(hwmgr->smumgr,
+				PPSMC_MSG_SCLKDPM_UnfreezeLevel),
+		    "Failed to unfreeze MCLK DPM during UnFreezeSclkMclkDPM Function!",
+		    return -1);
+	}
+
+	data->need_update_smu7_dpm_table = 0;
+
+	return 0;
+}
+
+/* Look up the voltaged based on DAL's requested level.
+ * and then send the requested VDDC voltage to SMC
+ */
+static void fiji_apply_dal_minimum_voltage_request(struct pp_hwmgr *hwmgr)
+{
+	return;
+}
+
+int fiji_upload_dpm_level_enable_mask(struct pp_hwmgr *hwmgr)
+{
+	int result;
+	struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend);
+
+	/* Apply minimum voltage based on DAL's request level */
+	fiji_apply_dal_minimum_voltage_request(hwmgr);
+
+	if (0 == data->sclk_dpm_key_disabled) {
+		/* Checking if DPM is running.  If we discover hang because of this,
+		 *  we should skip this message.
+		 */
+		if (!fiji_is_dpm_running(hwmgr))
+			printk(KERN_ERR "[ powerplay ] "
+					"Trying to set Enable Mask when DPM is disabled \n");
+
+		if (data->dpm_level_enable_mask.sclk_dpm_enable_mask) {
+			result = smum_send_msg_to_smc_with_parameter(hwmgr->smumgr,
+					PPSMC_MSG_SCLKDPM_SetEnabledMask,
+					data->dpm_level_enable_mask.sclk_dpm_enable_mask);
+			PP_ASSERT_WITH_CODE((0 == result),
+				"Set Sclk Dpm enable Mask failed", return -1);
+		}
+	}
+
+	if (0 == data->mclk_dpm_key_disabled) {
+		/* Checking if DPM is running.  If we discover hang because of this,
+		 *  we should skip this message.
+		 */
+		if (!fiji_is_dpm_running(hwmgr))
+			printk(KERN_ERR "[ powerplay ]"
+					" Trying to set Enable Mask when DPM is disabled \n");
+
+		if (data->dpm_level_enable_mask.mclk_dpm_enable_mask) {
+			result = smum_send_msg_to_smc_with_parameter(hwmgr->smumgr,
+					PPSMC_MSG_MCLKDPM_SetEnabledMask,
+					data->dpm_level_enable_mask.mclk_dpm_enable_mask);
+			PP_ASSERT_WITH_CODE((0 == result),
+				"Set Mclk Dpm enable Mask failed", return -1);
+		}
+	}
+
+	return 0;
+}
+
+static int fiji_notify_link_speed_change_after_state_change(
+		struct pp_hwmgr *hwmgr, const void *input)
+{
+	const struct phm_set_power_state_input *states =
+			(const struct phm_set_power_state_input *)input;
+	struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend);
+	const struct fiji_power_state *fiji_ps =
+			cast_const_phw_fiji_power_state(states->pnew_state);
+	uint16_t target_link_speed = fiji_get_maximum_link_speed(hwmgr, fiji_ps);
+	uint8_t  request;
+
+	if (data->pspp_notify_required) {
+		if (target_link_speed == PP_PCIEGen3)
+			request = PCIE_PERF_REQ_GEN3;
+		else if (target_link_speed == PP_PCIEGen2)
+			request = PCIE_PERF_REQ_GEN2;
+		else
+			request = PCIE_PERF_REQ_GEN1;
+
+		if(request == PCIE_PERF_REQ_GEN1 &&
+				fiji_get_current_pcie_speed(hwmgr) > 0)
+			return 0;
+
+		if (acpi_pcie_perf_request(hwmgr->device, request, false)) {
+			if (PP_PCIEGen2 == target_link_speed)
+				printk("PSPP request to switch to Gen2 from Gen3 Failed!");
+			else
+				printk("PSPP request to switch to Gen1 from Gen2 Failed!");
+		}
+	}
+
+	return 0;
+}
+
+static int fiji_set_power_state_tasks(struct pp_hwmgr *hwmgr,
+		const void *input)
+{
+	int tmp_result, result = 0;
+
+	tmp_result = fiji_find_dpm_states_clocks_in_dpm_table(hwmgr, input);
+	PP_ASSERT_WITH_CODE((0 == tmp_result),
+			"Failed to find DPM states clocks in DPM table!",
+			result = tmp_result);
+
+	if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
+			PHM_PlatformCaps_PCIEPerformanceRequest)) {
+		tmp_result =
+			fiji_request_link_speed_change_before_state_change(hwmgr, input);
+		PP_ASSERT_WITH_CODE((0 == tmp_result),
+				"Failed to request link speed change before state change!",
+				result = tmp_result);
+	}
+
+	tmp_result = fiji_freeze_sclk_mclk_dpm(hwmgr);
+	PP_ASSERT_WITH_CODE((0 == tmp_result),
+			"Failed to freeze SCLK MCLK DPM!", result = tmp_result);
+
+	tmp_result = fiji_populate_and_upload_sclk_mclk_dpm_levels(hwmgr, input);
+	PP_ASSERT_WITH_CODE((0 == tmp_result),
+			"Failed to populate and upload SCLK MCLK DPM levels!",
+			result = tmp_result);
+
+	tmp_result = fiji_generate_dpm_level_enable_mask(hwmgr, input);
+	PP_ASSERT_WITH_CODE((0 == tmp_result),
+			"Failed to generate DPM level enabled mask!",
+			result = tmp_result);
+
+	tmp_result = fiji_update_vce_dpm(hwmgr, input);
+	PP_ASSERT_WITH_CODE((0 == tmp_result),
+			"Failed to update VCE DPM!",
+			result = tmp_result);
+
+	tmp_result = fiji_update_sclk_threshold(hwmgr);
+	PP_ASSERT_WITH_CODE((0 == tmp_result),
+			"Failed to update SCLK threshold!",
+			result = tmp_result);
+
+	tmp_result = fiji_program_mem_timing_parameters(hwmgr);
+	PP_ASSERT_WITH_CODE((0 == tmp_result),
+			"Failed to program memory timing parameters!",
+			result = tmp_result);
+
+	tmp_result = fiji_unfreeze_sclk_mclk_dpm(hwmgr);
+	PP_ASSERT_WITH_CODE((0 == tmp_result),
+			"Failed to unfreeze SCLK MCLK DPM!",
+			result = tmp_result);
+
+	tmp_result = fiji_upload_dpm_level_enable_mask(hwmgr);
+	PP_ASSERT_WITH_CODE((0 == tmp_result),
+			"Failed to upload DPM level enabled mask!",
+			result = tmp_result);
+
+	if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
+			PHM_PlatformCaps_PCIEPerformanceRequest)) {
+		tmp_result =
+			fiji_notify_link_speed_change_after_state_change(hwmgr, input);
+		PP_ASSERT_WITH_CODE((0 == tmp_result),
+				"Failed to notify link speed change after state change!",
+				result = tmp_result);
+	}
+
+	return result;
+}
+
+static int fiji_dpm_get_sclk(struct pp_hwmgr *hwmgr, bool low)
+{
+	struct pp_power_state  *ps;
+	struct fiji_power_state  *fiji_ps;
+
+	if (hwmgr == NULL)
+		return -EINVAL;
+
+	ps = hwmgr->request_ps;
+
+	if (ps == NULL)
+		return -EINVAL;
+
+	fiji_ps = cast_phw_fiji_power_state(&ps->hardware);
+
+	if (low)
+		return fiji_ps->performance_levels[0].engine_clock;
+	else
+		return fiji_ps->performance_levels
+				[fiji_ps->performance_level_count-1].engine_clock;
+}
+
+static int fiji_dpm_get_mclk(struct pp_hwmgr *hwmgr, bool low)
+{
+	struct pp_power_state  *ps;
+	struct fiji_power_state  *fiji_ps;
+
+	if (hwmgr == NULL)
+		return -EINVAL;
+
+	ps = hwmgr->request_ps;
+
+	if (ps == NULL)
+		return -EINVAL;
+
+	fiji_ps = cast_phw_fiji_power_state(&ps->hardware);
+
+	if (low)
+		return fiji_ps->performance_levels[0].memory_clock;
+	else
+		return fiji_ps->performance_levels
+				[fiji_ps->performance_level_count-1].memory_clock;
+}
+
+static void fiji_print_current_perforce_level(
+		struct pp_hwmgr *hwmgr, struct seq_file *m)
+{
+	uint32_t sclk, mclk, activity_percent = 0;
+	uint32_t offset;
+	struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend);
+
+	smum_send_msg_to_smc(hwmgr->smumgr, PPSMC_MSG_API_GetSclkFrequency);
+
+	sclk = cgs_read_register(hwmgr->device, mmSMC_MSG_ARG_0);
+
+	smum_send_msg_to_smc(hwmgr->smumgr, PPSMC_MSG_API_GetMclkFrequency);
+
+	mclk = cgs_read_register(hwmgr->device, mmSMC_MSG_ARG_0);
+	seq_printf(m, "\n [  mclk  ]: %u MHz\n\n [  sclk  ]: %u MHz\n",
+			mclk / 100, sclk / 100);
+
+	offset = data->soft_regs_start + offsetof(SMU73_SoftRegisters, AverageGraphicsActivity);
+	activity_percent = cgs_read_ind_register(hwmgr->device, CGS_IND_REG__SMC, offset);
+	activity_percent += 0x80;
+	activity_percent >>= 8;
+
+	seq_printf(m, "\n [GPU load]: %u%%\n\n", activity_percent > 100 ? 100 : activity_percent);
+}
+
+static int fiji_program_display_gap(struct pp_hwmgr *hwmgr)
+{
+	struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend);
+	uint32_t num_active_displays = 0;
+	uint32_t display_gap = cgs_read_ind_register(hwmgr->device,
+			CGS_IND_REG__SMC, ixCG_DISPLAY_GAP_CNTL);
+	uint32_t display_gap2;
+	uint32_t pre_vbi_time_in_us;
+	uint32_t frame_time_in_us;
+	uint32_t ref_clock;
+	uint32_t refresh_rate = 0;
+	struct cgs_display_info info = {0};
+	struct cgs_mode_info mode_info;
+
+	info.mode_info = &mode_info;
+
+	cgs_get_active_displays_info(hwmgr->device, &info);
+	num_active_displays = info.display_count;
+
+	display_gap = PHM_SET_FIELD(display_gap, CG_DISPLAY_GAP_CNTL,
+			DISP_GAP, (num_active_displays > 0)?
+			DISPLAY_GAP_VBLANK_OR_WM : DISPLAY_GAP_IGNORE);
+	cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC,
+			ixCG_DISPLAY_GAP_CNTL, display_gap);
+
+	ref_clock = mode_info.ref_clock;
+	refresh_rate = mode_info.refresh_rate;
+
+	if (refresh_rate == 0)
+		refresh_rate = 60;
+
+	frame_time_in_us = 1000000 / refresh_rate;
+
+	pre_vbi_time_in_us = frame_time_in_us - 200 - mode_info.vblank_time_us;
+	display_gap2 = pre_vbi_time_in_us * (ref_clock / 100);
+
+	cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC,
+			ixCG_DISPLAY_GAP_CNTL2, display_gap2);
+
+	cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC,
+			data->soft_regs_start +
+			offsetof(SMU73_SoftRegisters, PreVBlankGap), 0x64);
+
+	cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC,
+			data->soft_regs_start +
+			offsetof(SMU73_SoftRegisters, VBlankTimeout),
+			(frame_time_in_us - pre_vbi_time_in_us));
+
+	if (num_active_displays == 1)
+		tonga_notify_smc_display_change(hwmgr, true);
+
+	return 0;
+}
+
+int fiji_display_configuration_changed_task(struct pp_hwmgr *hwmgr)
+{
+	return fiji_program_display_gap(hwmgr);
+}
+
+static int fiji_set_max_fan_pwm_output(struct pp_hwmgr *hwmgr,
+		uint16_t us_max_fan_pwm)
+{
+	hwmgr->thermal_controller.
+	advanceFanControlParameters.usMaxFanPWM = us_max_fan_pwm;
+
+	if (phm_is_hw_access_blocked(hwmgr))
+		return 0;
+
+	return smum_send_msg_to_smc_with_parameter(hwmgr->smumgr,
+			PPSMC_MSG_SetFanPwmMax, us_max_fan_pwm);
+}
+
+static int fiji_set_max_fan_rpm_output(struct pp_hwmgr *hwmgr,
+		uint16_t us_max_fan_rpm)
+{
+	hwmgr->thermal_controller.
+	advanceFanControlParameters.usMaxFanRPM = us_max_fan_rpm;
+
+	if (phm_is_hw_access_blocked(hwmgr))
+		return 0;
+
+	return smum_send_msg_to_smc_with_parameter(hwmgr->smumgr,
+			PPSMC_MSG_SetFanRpmMax, us_max_fan_rpm);
+}
+
+int fiji_dpm_set_interrupt_state(void *private_data,
+					 unsigned src_id, unsigned type,
+					 int enabled)
+{
+	uint32_t cg_thermal_int;
+	struct pp_hwmgr *hwmgr = ((struct pp_eventmgr *)private_data)->hwmgr;
+
+	if (hwmgr == NULL)
+		return -EINVAL;
+
+	switch (type) {
+	case AMD_THERMAL_IRQ_LOW_TO_HIGH:
+		if (enabled) {
+			cg_thermal_int = cgs_read_ind_register(hwmgr->device,
+					CGS_IND_REG__SMC, ixCG_THERMAL_INT);
+			cg_thermal_int |= CG_THERMAL_INT_CTRL__THERM_INTH_MASK_MASK;
+			cgs_write_ind_register(hwmgr->device,
+					CGS_IND_REG__SMC, ixCG_THERMAL_INT, cg_thermal_int);
+		} else {
+			cg_thermal_int = cgs_read_ind_register(hwmgr->device,
+					CGS_IND_REG__SMC, ixCG_THERMAL_INT);
+			cg_thermal_int &= ~CG_THERMAL_INT_CTRL__THERM_INTH_MASK_MASK;
+			cgs_write_ind_register(hwmgr->device,
+					CGS_IND_REG__SMC, ixCG_THERMAL_INT, cg_thermal_int);
+		}
+		break;
+
+	case AMD_THERMAL_IRQ_HIGH_TO_LOW:
+		if (enabled) {
+			cg_thermal_int = cgs_read_ind_register(hwmgr->device,
+					CGS_IND_REG__SMC, ixCG_THERMAL_INT);
+			cg_thermal_int |= CG_THERMAL_INT_CTRL__THERM_INTL_MASK_MASK;
+			cgs_write_ind_register(hwmgr->device,
+					CGS_IND_REG__SMC, ixCG_THERMAL_INT, cg_thermal_int);
+		} else {
+			cg_thermal_int = cgs_read_ind_register(hwmgr->device,
+					CGS_IND_REG__SMC, ixCG_THERMAL_INT);
+			cg_thermal_int &= ~CG_THERMAL_INT_CTRL__THERM_INTL_MASK_MASK;
+			cgs_write_ind_register(hwmgr->device,
+					CGS_IND_REG__SMC, ixCG_THERMAL_INT, cg_thermal_int);
+		}
+		break;
+	default:
+		break;
+	}
+	return 0;
+}
+
+int fiji_register_internal_thermal_interrupt(struct pp_hwmgr *hwmgr,
+					const void *thermal_interrupt_info)
+{
+	int result;
+	const struct pp_interrupt_registration_info *info =
+			(const struct pp_interrupt_registration_info *)
+			thermal_interrupt_info;
+
+	if (info == NULL)
+		return -EINVAL;
+
+	result = cgs_add_irq_source(hwmgr->device, 230, AMD_THERMAL_IRQ_LAST,
+				fiji_dpm_set_interrupt_state,
+				info->call_back, info->context);
+
+	if (result)
+		return -EINVAL;
+
+	result = cgs_add_irq_source(hwmgr->device, 231, AMD_THERMAL_IRQ_LAST,
+				fiji_dpm_set_interrupt_state,
+				info->call_back, info->context);
+
+	if (result)
+		return -EINVAL;
+
+	return 0;
+}
+
+static int fiji_set_fan_control_mode(struct pp_hwmgr *hwmgr, uint32_t mode)
+{
+	if (mode) {
+		/* stop auto-manage */
+		if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
+				PHM_PlatformCaps_MicrocodeFanControl))
+			fiji_fan_ctrl_stop_smc_fan_control(hwmgr);
+		fiji_fan_ctrl_set_static_mode(hwmgr, mode);
+	} else
+		/* restart auto-manage */
+		fiji_fan_ctrl_reset_fan_speed_to_default(hwmgr);
+
+	return 0;
+}
+
+static int fiji_get_fan_control_mode(struct pp_hwmgr *hwmgr)
+{
+	if (hwmgr->fan_ctrl_is_in_default_mode)
+		return hwmgr->fan_ctrl_default_mode;
+	else
+		return PHM_READ_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC,
+				CG_FDO_CTRL2, FDO_PWM_MODE);
+}
+
+static const struct pp_hwmgr_func fiji_hwmgr_funcs = {
+	.backend_init = &fiji_hwmgr_backend_init,
+	.backend_fini = &tonga_hwmgr_backend_fini,
+	.asic_setup = &fiji_setup_asic_task,
+	.dynamic_state_management_enable = &fiji_enable_dpm_tasks,
+	.force_dpm_level = &fiji_dpm_force_dpm_level,
+	.get_num_of_pp_table_entries = &tonga_get_number_of_powerplay_table_entries,
+	.get_power_state_size = &fiji_get_power_state_size,
+	.get_pp_table_entry = &fiji_get_pp_table_entry,
+	.patch_boot_state = &fiji_patch_boot_state,
+	.apply_state_adjust_rules = &fiji_apply_state_adjust_rules,
+	.power_state_set = &fiji_set_power_state_tasks,
+	.get_sclk = &fiji_dpm_get_sclk,
+	.get_mclk = &fiji_dpm_get_mclk,
+	.print_current_perforce_level = &fiji_print_current_perforce_level,
+	.powergate_uvd = &fiji_phm_powergate_uvd,
+	.powergate_vce = &fiji_phm_powergate_vce,
+	.disable_clock_power_gating = &fiji_phm_disable_clock_power_gating,
+	.notify_smc_display_config_after_ps_adjustment =
+			&tonga_notify_smc_display_config_after_ps_adjustment,
+	.display_config_changed = &fiji_display_configuration_changed_task,
+	.set_max_fan_pwm_output = fiji_set_max_fan_pwm_output,
+	.set_max_fan_rpm_output = fiji_set_max_fan_rpm_output,
+	.get_temperature = fiji_thermal_get_temperature,
+	.stop_thermal_controller = fiji_thermal_stop_thermal_controller,
+	.get_fan_speed_info = fiji_fan_ctrl_get_fan_speed_info,
+	.get_fan_speed_percent = fiji_fan_ctrl_get_fan_speed_percent,
+	.set_fan_speed_percent = fiji_fan_ctrl_set_fan_speed_percent,
+	.reset_fan_speed_to_default = fiji_fan_ctrl_reset_fan_speed_to_default,
+	.get_fan_speed_rpm = fiji_fan_ctrl_get_fan_speed_rpm,
+	.set_fan_speed_rpm = fiji_fan_ctrl_set_fan_speed_rpm,
+	.uninitialize_thermal_controller = fiji_thermal_ctrl_uninitialize_thermal_controller,
+	.register_internal_thermal_interrupt = fiji_register_internal_thermal_interrupt,
+	.set_fan_control_mode = fiji_set_fan_control_mode,
+	.get_fan_control_mode = fiji_get_fan_control_mode,
+};
+
+int fiji_hwmgr_init(struct pp_hwmgr *hwmgr)
+{
+	struct fiji_hwmgr  *data;
+	int ret = 0;
+
+	data = kzalloc(sizeof(struct fiji_hwmgr), GFP_KERNEL);
+	if (data == NULL)
+		return -ENOMEM;
+
+	hwmgr->backend = data;
+	hwmgr->hwmgr_func = &fiji_hwmgr_funcs;
+	hwmgr->pptable_func = &tonga_pptable_funcs;
+	pp_fiji_thermal_initialize(hwmgr);
+	return ret;
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/powerplay/hwmgr/fiji_hwmgr.h
@@ -0,0 +1,361 @@
+/*
+ * Copyright 2015 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#ifndef _FIJI_HWMGR_H_
+#define _FIJI_HWMGR_H_
+
+#include "hwmgr.h"
+#include "smu73.h"
+#include "smu73_discrete.h"
+#include "ppatomctrl.h"
+#include "fiji_ppsmc.h"
+
+#define FIJI_MAX_HARDWARE_POWERLEVELS	2
+#define FIJI_AT_DFLT	30
+
+#define FIJI_VOLTAGE_CONTROL_NONE                   0x0
+#define FIJI_VOLTAGE_CONTROL_BY_GPIO                0x1
+#define FIJI_VOLTAGE_CONTROL_BY_SVID2               0x2
+#define FIJI_VOLTAGE_CONTROL_MERGED                 0x3
+
+#define DPMTABLE_OD_UPDATE_SCLK     0x00000001
+#define DPMTABLE_OD_UPDATE_MCLK     0x00000002
+#define DPMTABLE_UPDATE_SCLK        0x00000004
+#define DPMTABLE_UPDATE_MCLK        0x00000008
+
+struct fiji_performance_level {
+	uint32_t  memory_clock;
+	uint32_t  engine_clock;
+	uint16_t  pcie_gen;
+	uint16_t  pcie_lane;
+};
+
+struct fiji_uvd_clocks {
+	uint32_t  vclk;
+	uint32_t  dclk;
+};
+
+struct fiji_vce_clocks {
+	uint32_t  evclk;
+	uint32_t  ecclk;
+};
+
+struct fiji_power_state {
+    uint32_t                  magic;
+    struct fiji_uvd_clocks    uvd_clks;
+    struct fiji_vce_clocks    vce_clks;
+    uint32_t                  sam_clk;
+    uint32_t                  acp_clk;
+    uint16_t                  performance_level_count;
+    bool                      dc_compatible;
+    uint32_t                  sclk_threshold;
+    struct fiji_performance_level  performance_levels[FIJI_MAX_HARDWARE_POWERLEVELS];
+};
+
+struct fiji_dpm_level {
+	bool	enabled;
+    uint32_t	value;
+    uint32_t	param1;
+};
+
+#define FIJI_MAX_DEEPSLEEP_DIVIDER_ID 5
+#define MAX_REGULAR_DPM_NUMBER 8
+#define FIJI_MINIMUM_ENGINE_CLOCK 2500
+
+struct fiji_single_dpm_table {
+	uint32_t		count;
+	struct fiji_dpm_level	dpm_levels[MAX_REGULAR_DPM_NUMBER];
+};
+
+struct fiji_dpm_table {
+	struct fiji_single_dpm_table  sclk_table;
+	struct fiji_single_dpm_table  mclk_table;
+	struct fiji_single_dpm_table  pcie_speed_table;
+	struct fiji_single_dpm_table  vddc_table;
+	struct fiji_single_dpm_table  vddci_table;
+	struct fiji_single_dpm_table  mvdd_table;
+};
+
+struct fiji_clock_registers {
+	uint32_t  vCG_SPLL_FUNC_CNTL;
+	uint32_t  vCG_SPLL_FUNC_CNTL_2;
+	uint32_t  vCG_SPLL_FUNC_CNTL_3;
+	uint32_t  vCG_SPLL_FUNC_CNTL_4;
+	uint32_t  vCG_SPLL_SPREAD_SPECTRUM;
+	uint32_t  vCG_SPLL_SPREAD_SPECTRUM_2;
+	uint32_t  vDLL_CNTL;
+	uint32_t  vMCLK_PWRMGT_CNTL;
+	uint32_t  vMPLL_AD_FUNC_CNTL;
+	uint32_t  vMPLL_DQ_FUNC_CNTL;
+	uint32_t  vMPLL_FUNC_CNTL;
+	uint32_t  vMPLL_FUNC_CNTL_1;
+	uint32_t  vMPLL_FUNC_CNTL_2;
+	uint32_t  vMPLL_SS1;
+	uint32_t  vMPLL_SS2;
+};
+
+struct fiji_voltage_smio_registers {
+	uint32_t vS0_VID_LOWER_SMIO_CNTL;
+};
+
+#define FIJI_MAX_LEAKAGE_COUNT  8
+struct fiji_leakage_voltage {
+	uint16_t  count;
+	uint16_t  leakage_id[FIJI_MAX_LEAKAGE_COUNT];
+	uint16_t  actual_voltage[FIJI_MAX_LEAKAGE_COUNT];
+};
+
+struct fiji_vbios_boot_state {
+	uint16_t    mvdd_bootup_value;
+	uint16_t    vddc_bootup_value;
+	uint16_t    vddci_bootup_value;
+	uint32_t    sclk_bootup_value;
+	uint32_t    mclk_bootup_value;
+	uint16_t    pcie_gen_bootup_value;
+	uint16_t    pcie_lane_bootup_value;
+};
+
+struct fiji_bacos {
+	uint32_t                       best_match;
+	uint32_t                       baco_flags;
+	struct fiji_performance_level  performance_level;
+};
+
+/* Ultra Low Voltage parameter structure */
+struct fiji_ulv_parm {
+	bool                           ulv_supported;
+	uint32_t                       cg_ulv_parameter;
+	uint32_t                       ulv_volt_change_delay;
+	struct fiji_performance_level  ulv_power_level;
+};
+
+struct fiji_display_timing {
+	uint32_t  min_clock_in_sr;
+	uint32_t  num_existing_displays;
+};
+
+struct fiji_dpmlevel_enable_mask {
+	uint32_t  uvd_dpm_enable_mask;
+	uint32_t  vce_dpm_enable_mask;
+	uint32_t  acp_dpm_enable_mask;
+	uint32_t  samu_dpm_enable_mask;
+	uint32_t  sclk_dpm_enable_mask;
+	uint32_t  mclk_dpm_enable_mask;
+	uint32_t  pcie_dpm_enable_mask;
+};
+
+struct fiji_pcie_perf_range {
+	uint16_t  max;
+	uint16_t  min;
+};
+
+struct fiji_hwmgr {
+	struct fiji_dpm_table			dpm_table;
+	struct fiji_dpm_table			golden_dpm_table;
+
+	uint32_t						voting_rights_clients0;
+	uint32_t						voting_rights_clients1;
+	uint32_t						voting_rights_clients2;
+	uint32_t						voting_rights_clients3;
+	uint32_t						voting_rights_clients4;
+	uint32_t						voting_rights_clients5;
+	uint32_t						voting_rights_clients6;
+	uint32_t						voting_rights_clients7;
+	uint32_t						static_screen_threshold_unit;
+	uint32_t						static_screen_threshold;
+	uint32_t						voltage_control;
+	uint32_t						vddc_vddci_delta;
+
+	uint32_t						active_auto_throttle_sources;
+
+	struct fiji_clock_registers            clock_registers;
+	struct fiji_voltage_smio_registers      voltage_smio_registers;
+
+	bool                           is_memory_gddr5;
+	uint16_t                       acpi_vddc;
+	bool                           pspp_notify_required;
+	uint16_t                       force_pcie_gen;
+	uint16_t                       acpi_pcie_gen;
+	uint32_t                       pcie_gen_cap;
+	uint32_t                       pcie_lane_cap;
+	uint32_t                       pcie_spc_cap;
+	struct fiji_leakage_voltage          vddc_leakage;
+	struct fiji_leakage_voltage          Vddci_leakage;
+
+	uint32_t                             mvdd_control;
+	uint32_t                             vddc_mask_low;
+	uint32_t                             mvdd_mask_low;
+	uint16_t                            max_vddc_in_pptable;
+	uint16_t                            min_vddc_in_pptable;
+	uint16_t                            max_vddci_in_pptable;
+	uint16_t                            min_vddci_in_pptable;
+	uint32_t                             mclk_strobe_mode_threshold;
+	uint32_t                             mclk_stutter_mode_threshold;
+	uint32_t                             mclk_edc_enable_threshold;
+	uint32_t                             mclk_edcwr_enable_threshold;
+	bool                                is_uvd_enabled;
+	struct fiji_vbios_boot_state        vbios_boot_state;
+
+	bool                           battery_state;
+	bool                           is_tlu_enabled;
+
+	/* ---- SMC SRAM Address of firmware header tables ---- */
+	uint32_t                             sram_end;
+	uint32_t                             dpm_table_start;
+	uint32_t                             soft_regs_start;
+	uint32_t                             mc_reg_table_start;
+	uint32_t                             fan_table_start;
+	uint32_t                             arb_table_start;
+	struct SMU73_Discrete_DpmTable       smc_state_table;
+	struct SMU73_Discrete_Ulv            ulv_setting;
+
+	/* ---- Stuff originally coming from Evergreen ---- */
+	uint32_t                             vddci_control;
+	struct pp_atomctrl_voltage_table     vddc_voltage_table;
+	struct pp_atomctrl_voltage_table     vddci_voltage_table;
+	struct pp_atomctrl_voltage_table     mvdd_voltage_table;
+
+	uint32_t                             mgcg_cgtt_local2;
+	uint32_t                             mgcg_cgtt_local3;
+	uint32_t                             gpio_debug;
+	uint32_t                             mc_micro_code_feature;
+	uint32_t                             highest_mclk;
+	uint16_t                             acpi_vddci;
+	uint8_t                              mvdd_high_index;
+	uint8_t                              mvdd_low_index;
+	bool                                 dll_default_on;
+	bool                                 performance_request_registered;
+
+	/* ---- Low Power Features ---- */
+	struct fiji_bacos                    bacos;
+	struct fiji_ulv_parm                 ulv;
+
+	/* ---- CAC Stuff ---- */
+	uint32_t                       cac_table_start;
+	bool                           cac_configuration_required;
+	bool                           driver_calculate_cac_leakage;
+	bool                           cac_enabled;
+
+	/* ---- DPM2 Parameters ---- */
+	uint32_t                       power_containment_features;
+	bool                           enable_dte_feature;
+	bool                           enable_tdc_limit_feature;
+	bool                           enable_pkg_pwr_tracking_feature;
+	bool                           disable_uvd_power_tune_feature;
+	struct fiji_pt_defaults       *power_tune_defaults;
+	struct SMU73_Discrete_PmFuses  power_tune_table;
+	uint32_t                       dte_tj_offset;
+	uint32_t                       fast_watermark_threshold;
+
+	/* ---- Phase Shedding ---- */
+	bool                           vddc_phase_shed_control;
+
+	/* ---- DI/DT ---- */
+	struct fiji_display_timing        display_timing;
+
+	/* ---- Thermal Temperature Setting ---- */
+	struct fiji_dpmlevel_enable_mask     dpm_level_enable_mask;
+	uint32_t                             need_update_smu7_dpm_table;
+	uint32_t                             sclk_dpm_key_disabled;
+	uint32_t                             mclk_dpm_key_disabled;
+	uint32_t                             pcie_dpm_key_disabled;
+	uint32_t                             min_engine_clocks;
+	struct fiji_pcie_perf_range          pcie_gen_performance;
+	struct fiji_pcie_perf_range          pcie_lane_performance;
+	struct fiji_pcie_perf_range          pcie_gen_power_saving;
+	struct fiji_pcie_perf_range          pcie_lane_power_saving;
+	bool                                 use_pcie_performance_levels;
+	bool                                 use_pcie_power_saving_levels;
+	uint32_t                             activity_target[SMU73_MAX_LEVELS_GRAPHICS];
+	uint32_t                             mclk_activity_target;
+	uint32_t                             mclk_dpm0_activity_target;
+	uint32_t                             low_sclk_interrupt_threshold;
+	uint32_t                             last_mclk_dpm_enable_mask;
+	bool                                 uvd_enabled;
+
+	/* ---- Power Gating States ---- */
+	bool                           uvd_power_gated;
+	bool                           vce_power_gated;
+	bool                           samu_power_gated;
+	bool                           acp_power_gated;
+	bool                           pg_acp_init;
+	bool                           frtc_enabled;
+	bool                           frtc_status_changed;
+};
+
+/* To convert to Q8.8 format for firmware */
+#define FIJI_Q88_FORMAT_CONVERSION_UNIT             256
+
+enum Fiji_I2CLineID {
+    Fiji_I2CLineID_DDC1 = 0x90,
+    Fiji_I2CLineID_DDC2 = 0x91,
+    Fiji_I2CLineID_DDC3 = 0x92,
+    Fiji_I2CLineID_DDC4 = 0x93,
+    Fiji_I2CLineID_DDC5 = 0x94,
+    Fiji_I2CLineID_DDC6 = 0x95,
+    Fiji_I2CLineID_SCLSDA = 0x96,
+    Fiji_I2CLineID_DDCVGA = 0x97
+};
+
+#define Fiji_I2C_DDC1DATA          0
+#define Fiji_I2C_DDC1CLK           1
+#define Fiji_I2C_DDC2DATA          2
+#define Fiji_I2C_DDC2CLK           3
+#define Fiji_I2C_DDC3DATA          4
+#define Fiji_I2C_DDC3CLK           5
+#define Fiji_I2C_SDA               40
+#define Fiji_I2C_SCL               41
+#define Fiji_I2C_DDC4DATA          65
+#define Fiji_I2C_DDC4CLK           66
+#define Fiji_I2C_DDC5DATA          0x48
+#define Fiji_I2C_DDC5CLK           0x49
+#define Fiji_I2C_DDC6DATA          0x4a
+#define Fiji_I2C_DDC6CLK           0x4b
+#define Fiji_I2C_DDCVGADATA        0x4c
+#define Fiji_I2C_DDCVGACLK         0x4d
+
+#define FIJI_UNUSED_GPIO_PIN       0x7F
+
+extern int tonga_initializa_dynamic_state_adjustment_rule_settings(struct pp_hwmgr *hwmgr);
+extern int tonga_hwmgr_backend_fini(struct pp_hwmgr *hwmgr);
+extern int tonga_get_mc_microcode_version (struct pp_hwmgr *hwmgr);
+extern int tonga_notify_smc_display_config_after_ps_adjustment(struct pp_hwmgr *hwmgr);
+extern int tonga_notify_smc_display_change(struct pp_hwmgr *hwmgr, bool has_display);
+int fiji_update_vce_dpm(struct pp_hwmgr *hwmgr, const void *input);
+int fiji_update_uvd_dpm(struct pp_hwmgr *hwmgr, bool bgate);
+int fiji_update_samu_dpm(struct pp_hwmgr *hwmgr, bool bgate);
+int fiji_update_acp_dpm(struct pp_hwmgr *hwmgr, bool bgate);
+int fiji_enable_disable_vce_dpm(struct pp_hwmgr *hwmgr, bool enable);
+
+#define PP_HOST_TO_SMC_UL(X) cpu_to_be32(X)
+#define PP_SMC_TO_HOST_UL(X) be32_to_cpu(X)
+
+#define PP_HOST_TO_SMC_US(X) cpu_to_be16(X)
+#define PP_SMC_TO_HOST_US(X) be16_to_cpu(X)
+
+#define CONVERT_FROM_HOST_TO_SMC_UL(X) ((X) = PP_HOST_TO_SMC_UL(X))
+#define CONVERT_FROM_SMC_TO_HOST_UL(X) ((X) = PP_SMC_TO_HOST_UL(X))
+
+#define CONVERT_FROM_HOST_TO_SMC_US(X) ((X) = PP_HOST_TO_SMC_US(X))
+
+#endif /* _FIJI_HWMGR_H_ */
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/powerplay/hwmgr/fiji_powertune.c
@@ -0,0 +1,553 @@
+/*
+ * Copyright 2015 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#include "hwmgr.h"
+#include "smumgr.h"
+#include "fiji_hwmgr.h"
+#include "fiji_powertune.h"
+#include "fiji_smumgr.h"
+#include "smu73_discrete.h"
+#include "pp_debug.h"
+
+#define VOLTAGE_SCALE  4
+#define POWERTUNE_DEFAULT_SET_MAX    1
+
+struct fiji_pt_defaults fiji_power_tune_data_set_array[POWERTUNE_DEFAULT_SET_MAX] = {
+		/*sviLoadLIneEn,  SviLoadLineVddC, TDC_VDDC_ThrottleReleaseLimitPerc */
+		{1,               0xF,             0xFD,
+		/* TDC_MAWt, TdcWaterfallCtl, DTEAmbientTempBase */
+		0x19,        5,               45}
+};
+
+void fiji_initialize_power_tune_defaults(struct pp_hwmgr *hwmgr)
+{
+	struct fiji_hwmgr *fiji_hwmgr = (struct fiji_hwmgr *)(hwmgr->backend);
+	struct  phm_ppt_v1_information *table_info =
+			(struct  phm_ppt_v1_information *)(hwmgr->pptable);
+	uint32_t tmp = 0;
+
+	if(table_info &&
+			table_info->cac_dtp_table->usPowerTuneDataSetID <= POWERTUNE_DEFAULT_SET_MAX &&
+			table_info->cac_dtp_table->usPowerTuneDataSetID)
+		fiji_hwmgr->power_tune_defaults =
+				&fiji_power_tune_data_set_array
+				[table_info->cac_dtp_table->usPowerTuneDataSetID - 1];
+	else
+		fiji_hwmgr->power_tune_defaults = &fiji_power_tune_data_set_array[0];
+
+	/* Assume disabled */
+	phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
+			PHM_PlatformCaps_PowerContainment);
+	phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
+			PHM_PlatformCaps_CAC);
+	phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
+			PHM_PlatformCaps_SQRamping);
+	phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
+			PHM_PlatformCaps_DBRamping);
+	phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
+			PHM_PlatformCaps_TDRamping);
+	phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
+			PHM_PlatformCaps_TCPRamping);
+
+	fiji_hwmgr->dte_tj_offset = tmp;
+
+	if (!tmp) {
+		phm_cap_set(hwmgr->platform_descriptor.platformCaps,
+				PHM_PlatformCaps_PowerContainment);
+
+		phm_cap_set(hwmgr->platform_descriptor.platformCaps,
+				PHM_PlatformCaps_CAC);
+
+		fiji_hwmgr->fast_watermark_threshold = 100;
+
+		tmp = 1;
+		fiji_hwmgr->enable_dte_feature = tmp ? false : true;
+		fiji_hwmgr->enable_tdc_limit_feature = tmp ? true : false;
+		fiji_hwmgr->enable_pkg_pwr_tracking_feature = tmp ? true : false;
+	}
+}
+
+/* PPGen has the gain setting generated in x * 100 unit
+ * This function is to convert the unit to x * 4096(0x1000) unit.
+ *  This is the unit expected by SMC firmware
+ */
+static uint16_t scale_fan_gain_settings(uint16_t raw_setting)
+{
+	uint32_t tmp;
+	tmp = raw_setting * 4096 / 100;
+	return (uint16_t)tmp;
+}
+
+static void get_scl_sda_value(uint8_t line, uint8_t *scl, uint8_t* sda)
+{
+	switch (line) {
+	case Fiji_I2CLineID_DDC1 :
+		*scl = Fiji_I2C_DDC1CLK;
+		*sda = Fiji_I2C_DDC1DATA;
+		break;
+	case Fiji_I2CLineID_DDC2 :
+		*scl = Fiji_I2C_DDC2CLK;
+		*sda = Fiji_I2C_DDC2DATA;
+		break;
+	case Fiji_I2CLineID_DDC3 :
+		*scl = Fiji_I2C_DDC3CLK;
+		*sda = Fiji_I2C_DDC3DATA;
+		break;
+	case Fiji_I2CLineID_DDC4 :
+		*scl = Fiji_I2C_DDC4CLK;
+		*sda = Fiji_I2C_DDC4DATA;
+		break;
+	case Fiji_I2CLineID_DDC5 :
+		*scl = Fiji_I2C_DDC5CLK;
+		*sda = Fiji_I2C_DDC5DATA;
+		break;
+	case Fiji_I2CLineID_DDC6 :
+		*scl = Fiji_I2C_DDC6CLK;
+		*sda = Fiji_I2C_DDC6DATA;
+		break;
+	case Fiji_I2CLineID_SCLSDA :
+		*scl = Fiji_I2C_SCL;
+		*sda = Fiji_I2C_SDA;
+		break;
+	case Fiji_I2CLineID_DDCVGA :
+		*scl = Fiji_I2C_DDCVGACLK;
+		*sda = Fiji_I2C_DDCVGADATA;
+		break;
+	default:
+		*scl = 0;
+		*sda = 0;
+		break;
+	}
+}
+
+int fiji_populate_bapm_parameters_in_dpm_table(struct pp_hwmgr *hwmgr)
+{
+	struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend);
+	struct fiji_pt_defaults *defaults = data->power_tune_defaults;
+	SMU73_Discrete_DpmTable  *dpm_table = &(data->smc_state_table);
+	struct phm_ppt_v1_information *table_info =
+			(struct phm_ppt_v1_information *)(hwmgr->pptable);
+	struct phm_cac_tdp_table *cac_dtp_table = table_info->cac_dtp_table;
+	struct pp_advance_fan_control_parameters *fan_table=
+			&hwmgr->thermal_controller.advanceFanControlParameters;
+	uint8_t uc_scl, uc_sda;
+
+	/* TDP number of fraction bits are changed from 8 to 7 for Fiji
+	 * as requested by SMC team
+	 */
+	dpm_table->DefaultTdp = PP_HOST_TO_SMC_US(
+			(uint16_t)(cac_dtp_table->usTDP * 128));
+	dpm_table->TargetTdp = PP_HOST_TO_SMC_US(
+			(uint16_t)(cac_dtp_table->usTDP * 128));
+
+	PP_ASSERT_WITH_CODE(cac_dtp_table->usTargetOperatingTemp <= 255,
+			"Target Operating Temp is out of Range!",);
+
+	dpm_table->GpuTjMax = (uint8_t)(cac_dtp_table->usTargetOperatingTemp);
+	dpm_table->GpuTjHyst = 8;
+
+	dpm_table->DTEAmbientTempBase = defaults->DTEAmbientTempBase;
+
+	/* The following are for new Fiji Multi-input fan/thermal control */
+	dpm_table->TemperatureLimitEdge = PP_HOST_TO_SMC_US(
+			cac_dtp_table->usTargetOperatingTemp * 256);
+	dpm_table->TemperatureLimitHotspot = PP_HOST_TO_SMC_US(
+			cac_dtp_table->usTemperatureLimitHotspot * 256);
+	dpm_table->TemperatureLimitLiquid1 = PP_HOST_TO_SMC_US(
+			cac_dtp_table->usTemperatureLimitLiquid1 * 256);
+	dpm_table->TemperatureLimitLiquid2 = PP_HOST_TO_SMC_US(
+			cac_dtp_table->usTemperatureLimitLiquid2 * 256);
+	dpm_table->TemperatureLimitVrVddc = PP_HOST_TO_SMC_US(
+			cac_dtp_table->usTemperatureLimitVrVddc * 256);
+	dpm_table->TemperatureLimitVrMvdd = PP_HOST_TO_SMC_US(
+			cac_dtp_table->usTemperatureLimitVrMvdd * 256);
+	dpm_table->TemperatureLimitPlx = PP_HOST_TO_SMC_US(
+			cac_dtp_table->usTemperatureLimitPlx * 256);
+
+	dpm_table->FanGainEdge = PP_HOST_TO_SMC_US(
+			scale_fan_gain_settings(fan_table->usFanGainEdge));
+	dpm_table->FanGainHotspot = PP_HOST_TO_SMC_US(
+			scale_fan_gain_settings(fan_table->usFanGainHotspot));
+	dpm_table->FanGainLiquid = PP_HOST_TO_SMC_US(
+			scale_fan_gain_settings(fan_table->usFanGainLiquid));
+	dpm_table->FanGainVrVddc = PP_HOST_TO_SMC_US(
+			scale_fan_gain_settings(fan_table->usFanGainVrVddc));
+	dpm_table->FanGainVrMvdd = PP_HOST_TO_SMC_US(
+			scale_fan_gain_settings(fan_table->usFanGainVrMvdd));
+	dpm_table->FanGainPlx = PP_HOST_TO_SMC_US(
+			scale_fan_gain_settings(fan_table->usFanGainPlx));
+	dpm_table->FanGainHbm = PP_HOST_TO_SMC_US(
+			scale_fan_gain_settings(fan_table->usFanGainHbm));
+
+	dpm_table->Liquid1_I2C_address = cac_dtp_table->ucLiquid1_I2C_address;
+	dpm_table->Liquid2_I2C_address = cac_dtp_table->ucLiquid2_I2C_address;
+	dpm_table->Vr_I2C_address = cac_dtp_table->ucVr_I2C_address;
+	dpm_table->Plx_I2C_address = cac_dtp_table->ucPlx_I2C_address;
+
+	get_scl_sda_value(cac_dtp_table->ucLiquid_I2C_Line, &uc_scl, &uc_sda);
+	dpm_table->Liquid_I2C_LineSCL = uc_scl;
+	dpm_table->Liquid_I2C_LineSDA = uc_sda;
+
+	get_scl_sda_value(cac_dtp_table->ucVr_I2C_Line, &uc_scl, &uc_sda);
+	dpm_table->Vr_I2C_LineSCL = uc_scl;
+	dpm_table->Vr_I2C_LineSDA = uc_sda;
+
+	get_scl_sda_value(cac_dtp_table->ucPlx_I2C_Line, &uc_scl, &uc_sda);
+	dpm_table->Plx_I2C_LineSCL = uc_scl;
+	dpm_table->Plx_I2C_LineSDA = uc_sda;
+
+	return 0;
+}
+
+static int fiji_populate_svi_load_line(struct pp_hwmgr *hwmgr)
+{
+    struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend);
+    struct fiji_pt_defaults *defaults = data->power_tune_defaults;
+
+    data->power_tune_table.SviLoadLineEn = defaults->SviLoadLineEn;
+    data->power_tune_table.SviLoadLineVddC = defaults->SviLoadLineVddC;
+    data->power_tune_table.SviLoadLineTrimVddC = 3;
+    data->power_tune_table.SviLoadLineOffsetVddC = 0;
+
+    return 0;
+}
+
+static int fiji_populate_tdc_limit(struct pp_hwmgr *hwmgr)
+{
+	uint16_t tdc_limit;
+	struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend);
+	struct phm_ppt_v1_information *table_info =
+			(struct phm_ppt_v1_information *)(hwmgr->pptable);
+	struct  fiji_pt_defaults *defaults = data->power_tune_defaults;
+
+	/* TDC number of fraction bits are changed from 8 to 7
+	 * for Fiji as requested by SMC team
+	 */
+	tdc_limit = (uint16_t)(table_info->cac_dtp_table->usTDC * 128);
+	data->power_tune_table.TDC_VDDC_PkgLimit =
+			CONVERT_FROM_HOST_TO_SMC_US(tdc_limit);
+	data->power_tune_table.TDC_VDDC_ThrottleReleaseLimitPerc =
+			defaults->TDC_VDDC_ThrottleReleaseLimitPerc;
+	data->power_tune_table.TDC_MAWt = defaults->TDC_MAWt;
+
+	return 0;
+}
+
+static int fiji_populate_dw8(struct pp_hwmgr *hwmgr, uint32_t fuse_table_offset)
+{
+	struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend);
+	struct  fiji_pt_defaults *defaults = data->power_tune_defaults;
+	uint32_t temp;
+
+	if (fiji_read_smc_sram_dword(hwmgr->smumgr,
+			fuse_table_offset +
+			offsetof(SMU73_Discrete_PmFuses, TdcWaterfallCtl),
+			(uint32_t *)&temp, data->sram_end))
+		PP_ASSERT_WITH_CODE(false,
+				"Attempt to read PmFuses.DW6 (SviLoadLineEn) from SMC Failed!",
+				return -EINVAL);
+	else {
+		data->power_tune_table.TdcWaterfallCtl = defaults->TdcWaterfallCtl;
+		data->power_tune_table.LPMLTemperatureMin =
+				(uint8_t)((temp >> 16) & 0xff);
+		data->power_tune_table.LPMLTemperatureMax =
+				(uint8_t)((temp >> 8) & 0xff);
+		data->power_tune_table.Reserved = (uint8_t)(temp & 0xff);
+	}
+	return 0;
+}
+
+static int fiji_populate_temperature_scaler(struct pp_hwmgr *hwmgr)
+{
+	int i;
+	struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend);
+
+	/* Currently not used. Set all to zero. */
+	for (i = 0; i < 16; i++)
+		data->power_tune_table.LPMLTemperatureScaler[i] = 0;
+
+	return 0;
+}
+
+static int fiji_populate_fuzzy_fan(struct pp_hwmgr *hwmgr)
+{
+	struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend);
+
+	if( (hwmgr->thermal_controller.advanceFanControlParameters.
+			usFanOutputSensitivity & (1 << 15)) ||
+			0 == hwmgr->thermal_controller.advanceFanControlParameters.
+			usFanOutputSensitivity )
+		hwmgr->thermal_controller.advanceFanControlParameters.
+		usFanOutputSensitivity = hwmgr->thermal_controller.
+			advanceFanControlParameters.usDefaultFanOutputSensitivity;
+
+	data->power_tune_table.FuzzyFan_PwmSetDelta =
+			PP_HOST_TO_SMC_US(hwmgr->thermal_controller.
+					advanceFanControlParameters.usFanOutputSensitivity);
+	return 0;
+}
+
+static int fiji_populate_gnb_lpml(struct pp_hwmgr *hwmgr)
+{
+	int i;
+	struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend);
+
+	/* Currently not used. Set all to zero. */
+	for (i = 0; i < 16; i++)
+		data->power_tune_table.GnbLPML[i] = 0;
+
+	return 0;
+}
+
+static int fiji_min_max_vgnb_lpml_id_from_bapm_vddc(struct pp_hwmgr *hwmgr)
+{
+ /*   int  i, min, max;
+    struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend);
+    uint8_t * pHiVID = data->power_tune_table.BapmVddCVidHiSidd;
+    uint8_t * pLoVID = data->power_tune_table.BapmVddCVidLoSidd;
+
+    min = max = pHiVID[0];
+    for (i = 0; i < 8; i++) {
+        if (0 != pHiVID[i]) {
+            if (min > pHiVID[i])
+                min = pHiVID[i];
+            if (max < pHiVID[i])
+                max = pHiVID[i];
+        }
+
+        if (0 != pLoVID[i]) {
+            if (min > pLoVID[i])
+                min = pLoVID[i];
+            if (max < pLoVID[i])
+                max = pLoVID[i];
+        }
+    }
+
+    PP_ASSERT_WITH_CODE((0 != min) && (0 != max), "BapmVddcVidSidd table does not exist!", return int_Failed);
+    data->power_tune_table.GnbLPMLMaxVid = (uint8_t)max;
+    data->power_tune_table.GnbLPMLMinVid = (uint8_t)min;
+*/
+    return 0;
+}
+
+static int fiji_populate_bapm_vddc_base_leakage_sidd(struct pp_hwmgr *hwmgr)
+{
+	struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend);
+	struct phm_ppt_v1_information *table_info =
+			(struct phm_ppt_v1_information *)(hwmgr->pptable);
+	uint16_t HiSidd = data->power_tune_table.BapmVddCBaseLeakageHiSidd;
+	uint16_t LoSidd = data->power_tune_table.BapmVddCBaseLeakageLoSidd;
+	struct phm_cac_tdp_table *cac_table = table_info->cac_dtp_table;
+
+	HiSidd = (uint16_t)(cac_table->usHighCACLeakage / 100 * 256);
+	LoSidd = (uint16_t)(cac_table->usLowCACLeakage / 100 * 256);
+
+	data->power_tune_table.BapmVddCBaseLeakageHiSidd =
+			CONVERT_FROM_HOST_TO_SMC_US(HiSidd);
+	data->power_tune_table.BapmVddCBaseLeakageLoSidd =
+			CONVERT_FROM_HOST_TO_SMC_US(LoSidd);
+
+	return 0;
+}
+
+int fiji_populate_pm_fuses(struct pp_hwmgr *hwmgr)
+{
+	struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend);
+	uint32_t pm_fuse_table_offset;
+
+	if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
+			PHM_PlatformCaps_PowerContainment)) {
+		if (fiji_read_smc_sram_dword(hwmgr->smumgr,
+				SMU7_FIRMWARE_HEADER_LOCATION +
+				offsetof(SMU73_Firmware_Header, PmFuseTable),
+				&pm_fuse_table_offset, data->sram_end))
+			PP_ASSERT_WITH_CODE(false,
+					"Attempt to get pm_fuse_table_offset Failed!",
+					return -EINVAL);
+
+		/* DW6 */
+		if (fiji_populate_svi_load_line(hwmgr))
+			PP_ASSERT_WITH_CODE(false,
+					"Attempt to populate SviLoadLine Failed!",
+					return -EINVAL);
+		/* DW7 */
+		if (fiji_populate_tdc_limit(hwmgr))
+			PP_ASSERT_WITH_CODE(false,
+					"Attempt to populate TDCLimit Failed!", return -EINVAL);
+		/* DW8 */
+		if (fiji_populate_dw8(hwmgr, pm_fuse_table_offset))
+			PP_ASSERT_WITH_CODE(false,
+					"Attempt to populate TdcWaterfallCtl, "
+					"LPMLTemperature Min and Max Failed!",
+					return -EINVAL);
+
+		/* DW9-DW12 */
+		if (0 != fiji_populate_temperature_scaler(hwmgr))
+			PP_ASSERT_WITH_CODE(false,
+					"Attempt to populate LPMLTemperatureScaler Failed!",
+					return -EINVAL);
+
+		/* DW13-DW14 */
+		if(fiji_populate_fuzzy_fan(hwmgr))
+			PP_ASSERT_WITH_CODE(false,
+					"Attempt to populate Fuzzy Fan Control parameters Failed!",
+					return -EINVAL);
+
+		/* DW15-DW18 */
+		if (fiji_populate_gnb_lpml(hwmgr))
+			PP_ASSERT_WITH_CODE(false,
+					"Attempt to populate GnbLPML Failed!",
+					return -EINVAL);
+
+		/* DW19 */
+		if (fiji_min_max_vgnb_lpml_id_from_bapm_vddc(hwmgr))
+			PP_ASSERT_WITH_CODE(false,
+					"Attempt to populate GnbLPML Min and Max Vid Failed!",
+					return -EINVAL);
+
+		/* DW20 */
+		if (fiji_populate_bapm_vddc_base_leakage_sidd(hwmgr))
+			PP_ASSERT_WITH_CODE(false,
+					"Attempt to populate BapmVddCBaseLeakage Hi and Lo "
+					"Sidd Failed!", return -EINVAL);
+
+		if (fiji_copy_bytes_to_smc(hwmgr->smumgr, pm_fuse_table_offset,
+				(uint8_t *)&data->power_tune_table,
+				sizeof(struct SMU73_Discrete_PmFuses), data->sram_end))
+			PP_ASSERT_WITH_CODE(false,
+					"Attempt to download PmFuseTable Failed!",
+					return -EINVAL);
+	}
+	return 0;
+}
+
+int fiji_enable_smc_cac(struct pp_hwmgr *hwmgr)
+{
+	struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend);
+	int result = 0;
+
+	if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
+			PHM_PlatformCaps_CAC)) {
+		int smc_result;
+		smc_result = smum_send_msg_to_smc(hwmgr->smumgr,
+				(uint16_t)(PPSMC_MSG_EnableCac));
+		PP_ASSERT_WITH_CODE((0 == smc_result),
+				"Failed to enable CAC in SMC.", result = -1);
+
+        data->cac_enabled = (0 == smc_result) ? true : false;
+	}
+	return result;
+}
+
+int fiji_set_power_limit(struct pp_hwmgr *hwmgr, uint32_t n)
+{
+	struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend);
+
+	if(data->power_containment_features &
+			POWERCONTAINMENT_FEATURE_PkgPwrLimit)
+		return smum_send_msg_to_smc_with_parameter(hwmgr->smumgr,
+				PPSMC_MSG_PkgPwrSetLimit, n);
+	return 0;
+}
+
+static int fiji_set_overdriver_target_tdp(struct pp_hwmgr *pHwMgr, uint32_t target_tdp)
+{
+	return smum_send_msg_to_smc_with_parameter(pHwMgr->smumgr,
+			PPSMC_MSG_OverDriveSetTargetTdp, target_tdp);
+}
+
+int fiji_enable_power_containment(struct pp_hwmgr *hwmgr)
+{
+	struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend);
+	struct phm_ppt_v1_information *table_info =
+			(struct phm_ppt_v1_information *)(hwmgr->pptable);
+	int smc_result;
+	int result = 0;
+
+	data->power_containment_features = 0;
+	if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
+			PHM_PlatformCaps_PowerContainment)) {
+		if (data->enable_dte_feature) {
+			smc_result = smum_send_msg_to_smc(hwmgr->smumgr,
+					(uint16_t)(PPSMC_MSG_EnableDTE));
+			PP_ASSERT_WITH_CODE((0 == smc_result),
+					"Failed to enable DTE in SMC.", result = -1;);
+			if (0 == smc_result)
+				data->power_containment_features |= POWERCONTAINMENT_FEATURE_DTE;
+		}
+
+		if (data->enable_tdc_limit_feature) {
+			smc_result = smum_send_msg_to_smc(hwmgr->smumgr,
+					(uint16_t)(PPSMC_MSG_TDCLimitEnable));
+			PP_ASSERT_WITH_CODE((0 == smc_result),
+					"Failed to enable TDCLimit in SMC.", result = -1;);
+			if (0 == smc_result)
+				data->power_containment_features |=
+						POWERCONTAINMENT_FEATURE_TDCLimit;
+		}
+
+		if (data->enable_pkg_pwr_tracking_feature) {
+			smc_result = smum_send_msg_to_smc(hwmgr->smumgr,
+					(uint16_t)(PPSMC_MSG_PkgPwrLimitEnable));
+			PP_ASSERT_WITH_CODE((0 == smc_result),
+					"Failed to enable PkgPwrTracking in SMC.", result = -1;);
+			if (0 == smc_result) {
+				struct phm_cac_tdp_table *cac_table =
+						table_info->cac_dtp_table;
+				uint32_t default_limit =
+					(uint32_t)(cac_table->usMaximumPowerDeliveryLimit * 256);
+
+				data->power_containment_features |=
+						POWERCONTAINMENT_FEATURE_PkgPwrLimit;
+
+				if (fiji_set_power_limit(hwmgr, default_limit))
+					printk(KERN_ERR "Failed to set Default Power Limit in SMC!");
+			}
+		}
+	}
+	return result;
+}
+
+int fiji_power_control_set_level(struct pp_hwmgr *hwmgr)
+{
+	struct phm_ppt_v1_information *table_info =
+			(struct phm_ppt_v1_information *)(hwmgr->pptable);
+	struct phm_cac_tdp_table *cac_table = table_info->cac_dtp_table;
+	int adjust_percent, target_tdp;
+	int result = 0;
+
+	if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
+			PHM_PlatformCaps_PowerContainment)) {
+		/* adjustment percentage has already been validated */
+		adjust_percent = hwmgr->platform_descriptor.TDPAdjustmentPolarity ?
+				hwmgr->platform_descriptor.TDPAdjustment :
+				(-1 * hwmgr->platform_descriptor.TDPAdjustment);
+		/* SMC requested that target_tdp to be 7 bit fraction in DPM table
+		 * but message to be 8 bit fraction for messages
+		 */
+		target_tdp = ((100 + adjust_percent) * (int)(cac_table->usTDP * 256)) / 100;
+		result = fiji_set_overdriver_target_tdp(hwmgr, (uint32_t)target_tdp);
+	}
+
+	return result;
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/powerplay/hwmgr/fiji_powertune.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2015 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+#ifndef FIJI_POWERTUNE_H
+#define FIJI_POWERTUNE_H
+
+enum fiji_pt_config_reg_type {
+	FIJI_CONFIGREG_MMR = 0,
+	FIJI_CONFIGREG_SMC_IND,
+	FIJI_CONFIGREG_DIDT_IND,
+	FIJI_CONFIGREG_CACHE,
+	FIJI_CONFIGREG_MAX
+};
+
+/* PowerContainment Features */
+#define POWERCONTAINMENT_FEATURE_DTE             0x00000001
+#define POWERCONTAINMENT_FEATURE_TDCLimit        0x00000002
+#define POWERCONTAINMENT_FEATURE_PkgPwrLimit     0x00000004
+
+struct fiji_pt_config_reg {
+	uint32_t                           offset;
+	uint32_t                           mask;
+	uint32_t                           shift;
+	uint32_t                           value;
+	enum fiji_pt_config_reg_type       type;
+};
+
+struct fiji_pt_defaults
+{
+    uint8_t   SviLoadLineEn;
+    uint8_t   SviLoadLineVddC;
+    uint8_t   TDC_VDDC_ThrottleReleaseLimitPerc;
+    uint8_t   TDC_MAWt;
+    uint8_t   TdcWaterfallCtl;
+    uint8_t   DTEAmbientTempBase;
+};
+
+void fiji_initialize_power_tune_defaults(struct pp_hwmgr *hwmgr);
+int fiji_populate_bapm_parameters_in_dpm_table(struct pp_hwmgr *hwmgr);
+int fiji_populate_pm_fuses(struct pp_hwmgr *hwmgr);
+int fiji_enable_smc_cac(struct pp_hwmgr *hwmgr);
+int fiji_enable_power_containment(struct pp_hwmgr *hwmgr);
+int fiji_set_power_limit(struct pp_hwmgr *hwmgr, uint32_t n);
+int fiji_power_control_set_level(struct pp_hwmgr *hwmgr);
+
+#endif  /* FIJI_POWERTUNE_H */
+
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/powerplay/hwmgr/fiji_thermal.c
@@ -0,0 +1,687 @@
+/*
+ * Copyright 2015 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+#include <asm/div64.h>
+#include "fiji_thermal.h"
+#include "fiji_hwmgr.h"
+#include "fiji_smumgr.h"
+#include "fiji_ppsmc.h"
+#include "smu/smu_7_1_3_d.h"
+#include "smu/smu_7_1_3_sh_mask.h"
+
+int fiji_fan_ctrl_get_fan_speed_info(struct pp_hwmgr *hwmgr,
+		struct phm_fan_speed_info *fan_speed_info)
+{
+
+	if (hwmgr->thermal_controller.fanInfo.bNoFan)
+		return 0;
+
+	fan_speed_info->supports_percent_read = true;
+	fan_speed_info->supports_percent_write = true;
+	fan_speed_info->min_percent = 0;
+	fan_speed_info->max_percent = 100;
+
+	if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
+			PHM_PlatformCaps_FanSpeedInTableIsRPM) &&
+		hwmgr->thermal_controller.fanInfo.ucTachometerPulsesPerRevolution) {
+		fan_speed_info->supports_rpm_read = true;
+		fan_speed_info->supports_rpm_write = true;
+		fan_speed_info->min_rpm = hwmgr->thermal_controller.fanInfo.ulMinRPM;
+		fan_speed_info->max_rpm = hwmgr->thermal_controller.fanInfo.ulMaxRPM;
+	} else {
+		fan_speed_info->min_rpm = 0;
+		fan_speed_info->max_rpm = 0;
+	}
+
+	return 0;
+}
+
+int fiji_fan_ctrl_get_fan_speed_percent(struct pp_hwmgr *hwmgr,
+		uint32_t *speed)
+{
+	uint32_t duty100;
+	uint32_t duty;
+	uint64_t tmp64;
+
+	if (hwmgr->thermal_controller.fanInfo.bNoFan)
+		return 0;
+
+	duty100 = PHM_READ_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC,
+			CG_FDO_CTRL1, FMAX_DUTY100);
+	duty = PHM_READ_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC,
+			CG_THERMAL_STATUS, FDO_PWM_DUTY);
+
+	if (duty100 == 0)
+		return -EINVAL;
+
+
+	tmp64 = (uint64_t)duty * 100;
+	do_div(tmp64, duty100);
+	*speed = (uint32_t)tmp64;
+
+	if (*speed > 100)
+		*speed = 100;
+
+	return 0;
+}
+
+int fiji_fan_ctrl_get_fan_speed_rpm(struct pp_hwmgr *hwmgr, uint32_t *speed)
+{
+	uint32_t tach_period;
+	uint32_t crystal_clock_freq;
+
+	if (hwmgr->thermal_controller.fanInfo.bNoFan ||
+			(hwmgr->thermal_controller.fanInfo.
+				ucTachometerPulsesPerRevolution == 0))
+		return 0;
+
+	tach_period = PHM_READ_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC,
+			CG_TACH_STATUS, TACH_PERIOD);
+
+	if (tach_period == 0)
+		return -EINVAL;
+
+	crystal_clock_freq = tonga_get_xclk(hwmgr);
+
+	*speed = 60 * crystal_clock_freq * 10000/ tach_period;
+
+	return 0;
+}
+
+/**
+* Set Fan Speed Control to static mode, so that the user can decide what speed to use.
+* @param    hwmgr  the address of the powerplay hardware manager.
+*           mode    the fan control mode, 0 default, 1 by percent, 5, by RPM
+* @exception Should always succeed.
+*/
+int fiji_fan_ctrl_set_static_mode(struct pp_hwmgr *hwmgr, uint32_t mode)
+{
+
+	if (hwmgr->fan_ctrl_is_in_default_mode) {
+		hwmgr->fan_ctrl_default_mode =
+				PHM_READ_VFPF_INDIRECT_FIELD(hwmgr->device,	CGS_IND_REG__SMC,
+						CG_FDO_CTRL2, FDO_PWM_MODE);
+		hwmgr->tmin =
+				PHM_READ_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC,
+						CG_FDO_CTRL2, TMIN);
+		hwmgr->fan_ctrl_is_in_default_mode = false;
+	}
+
+	PHM_WRITE_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC,
+			CG_FDO_CTRL2, TMIN, 0);
+	PHM_WRITE_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC,
+			CG_FDO_CTRL2, FDO_PWM_MODE, mode);
+
+	return 0;
+}
+
+/**
+* Reset Fan Speed Control to default mode.
+* @param    hwmgr  the address of the powerplay hardware manager.
+* @exception Should always succeed.
+*/
+int fiji_fan_ctrl_set_default_mode(struct pp_hwmgr *hwmgr)
+{
+	if (!hwmgr->fan_ctrl_is_in_default_mode) {
+		PHM_WRITE_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC,
+				CG_FDO_CTRL2, FDO_PWM_MODE, hwmgr->fan_ctrl_default_mode);
+		PHM_WRITE_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC,
+				CG_FDO_CTRL2, TMIN, hwmgr->tmin);
+		hwmgr->fan_ctrl_is_in_default_mode = true;
+	}
+
+	return 0;
+}
+
+int fiji_fan_ctrl_start_smc_fan_control(struct pp_hwmgr *hwmgr)
+{
+	int result;
+
+	if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
+			PHM_PlatformCaps_ODFuzzyFanControlSupport)) {
+		cgs_write_register(hwmgr->device, mmSMC_MSG_ARG_0, FAN_CONTROL_FUZZY);
+		result = smum_send_msg_to_smc(hwmgr->smumgr, PPSMC_StartFanControl);
+
+		if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
+				PHM_PlatformCaps_FanSpeedInTableIsRPM))
+			hwmgr->hwmgr_func->set_max_fan_rpm_output(hwmgr,
+					hwmgr->thermal_controller.
+					advanceFanControlParameters.usMaxFanRPM);
+		else
+			hwmgr->hwmgr_func->set_max_fan_pwm_output(hwmgr,
+					hwmgr->thermal_controller.
+					advanceFanControlParameters.usMaxFanPWM);
+
+	} else {
+		cgs_write_register(hwmgr->device, mmSMC_MSG_ARG_0, FAN_CONTROL_TABLE);
+		result = smum_send_msg_to_smc(hwmgr->smumgr, PPSMC_StartFanControl);
+	}
+
+	if (!result && hwmgr->thermal_controller.
+			advanceFanControlParameters.ucTargetTemperature)
+		result = smum_send_msg_to_smc_with_parameter(hwmgr->smumgr,
+				PPSMC_MSG_SetFanTemperatureTarget,
+				hwmgr->thermal_controller.
+				advanceFanControlParameters.ucTargetTemperature);
+
+	return result;
+}
+
+
+int fiji_fan_ctrl_stop_smc_fan_control(struct pp_hwmgr *hwmgr)
+{
+	return smum_send_msg_to_smc(hwmgr->smumgr, PPSMC_StopFanControl);
+}
+
+/**
+* Set Fan Speed in percent.
+* @param    hwmgr  the address of the powerplay hardware manager.
+* @param    speed is the percentage value (0% - 100%) to be set.
+* @exception Fails is the 100% setting appears to be 0.
+*/
+int fiji_fan_ctrl_set_fan_speed_percent(struct pp_hwmgr *hwmgr,
+		uint32_t speed)
+{
+	uint32_t duty100;
+	uint32_t duty;
+	uint64_t tmp64;
+
+	if (hwmgr->thermal_controller.fanInfo.bNoFan)
+		return 0;
+
+	if (speed > 100)
+		speed = 100;
+
+	if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
+			PHM_PlatformCaps_MicrocodeFanControl))
+		fiji_fan_ctrl_stop_smc_fan_control(hwmgr);
+
+	duty100 = PHM_READ_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC,
+			CG_FDO_CTRL1, FMAX_DUTY100);
+
+	if (duty100 == 0)
+		return -EINVAL;
+
+	tmp64 = (uint64_t)speed * 100;
+	do_div(tmp64, duty100);
+	duty = (uint32_t)tmp64;
+
+	PHM_WRITE_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC,
+			CG_FDO_CTRL0, FDO_STATIC_DUTY, duty);
+
+	return fiji_fan_ctrl_set_static_mode(hwmgr, FDO_PWM_MODE_STATIC);
+}
+
+/**
+* Reset Fan Speed to default.
+* @param    hwmgr  the address of the powerplay hardware manager.
+* @exception Always succeeds.
+*/
+int fiji_fan_ctrl_reset_fan_speed_to_default(struct pp_hwmgr *hwmgr)
+{
+	int result;
+
+	if (hwmgr->thermal_controller.fanInfo.bNoFan)
+		return 0;
+
+	if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
+			PHM_PlatformCaps_MicrocodeFanControl)) {
+		result = fiji_fan_ctrl_set_static_mode(hwmgr, FDO_PWM_MODE_STATIC);
+		if (!result)
+			result = fiji_fan_ctrl_start_smc_fan_control(hwmgr);
+	} else
+		result = fiji_fan_ctrl_set_default_mode(hwmgr);
+
+	return result;
+}
+
+/**
+* Set Fan Speed in RPM.
+* @param    hwmgr  the address of the powerplay hardware manager.
+* @param    speed is the percentage value (min - max) to be set.
+* @exception Fails is the speed not lie between min and max.
+*/
+int fiji_fan_ctrl_set_fan_speed_rpm(struct pp_hwmgr *hwmgr, uint32_t speed)
+{
+	uint32_t tach_period;
+	uint32_t crystal_clock_freq;
+
+	if (hwmgr->thermal_controller.fanInfo.bNoFan ||
+			(hwmgr->thermal_controller.fanInfo.
+			ucTachometerPulsesPerRevolution == 0) ||
+			(speed < hwmgr->thermal_controller.fanInfo.ulMinRPM) ||
+			(speed > hwmgr->thermal_controller.fanInfo.ulMaxRPM))
+		return 0;
+
+	crystal_clock_freq = tonga_get_xclk(hwmgr);
+
+	tach_period = 60 * crystal_clock_freq * 10000 / (8 * speed);
+
+	PHM_WRITE_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC,
+				CG_TACH_STATUS, TACH_PERIOD, tach_period);
+
+	return fiji_fan_ctrl_set_static_mode(hwmgr, FDO_PWM_MODE_STATIC);
+}
+
+/**
+* Reads the remote temperature from the SIslands thermal controller.
+*
+* @param    hwmgr The address of the hardware manager.
+*/
+int fiji_thermal_get_temperature(struct pp_hwmgr *hwmgr)
+{
+	int temp;
+
+	temp = PHM_READ_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC,
+			CG_MULT_THERMAL_STATUS, CTF_TEMP);
+
+	/* Bit 9 means the reading is lower than the lowest usable value. */
+	if (temp & 0x200)
+		temp = FIJI_THERMAL_MAXIMUM_TEMP_READING;
+	else
+		temp = temp & 0x1ff;
+
+	temp *= PP_TEMPERATURE_UNITS_PER_CENTIGRADES;
+
+	return temp;
+}
+
+/**
+* Set the requested temperature range for high and low alert signals
+*
+* @param    hwmgr The address of the hardware manager.
+* @param    range Temperature range to be programmed for high and low alert signals
+* @exception PP_Result_BadInput if the input data is not valid.
+*/
+static int fiji_thermal_set_temperature_range(struct pp_hwmgr *hwmgr,
+		uint32_t low_temp, uint32_t high_temp)
+{
+	uint32_t low = FIJI_THERMAL_MINIMUM_ALERT_TEMP *
+			PP_TEMPERATURE_UNITS_PER_CENTIGRADES;
+	uint32_t high = FIJI_THERMAL_MAXIMUM_ALERT_TEMP *
+			PP_TEMPERATURE_UNITS_PER_CENTIGRADES;
+
+	if (low < low_temp)
+		low = low_temp;
+	if (high > high_temp)
+		high = high_temp;
+
+	if (low > high)
+		return -EINVAL;
+
+	PHM_WRITE_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC,
+			CG_THERMAL_INT, DIG_THERM_INTH,
+			(high / PP_TEMPERATURE_UNITS_PER_CENTIGRADES));
+	PHM_WRITE_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC,
+			CG_THERMAL_INT, DIG_THERM_INTL,
+			(low / PP_TEMPERATURE_UNITS_PER_CENTIGRADES));
+	PHM_WRITE_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC,
+			CG_THERMAL_CTRL, DIG_THERM_DPM,
+			(high / PP_TEMPERATURE_UNITS_PER_CENTIGRADES));
+
+	return 0;
+}
+
+/**
+* Programs thermal controller one-time setting registers
+*
+* @param    hwmgr The address of the hardware manager.
+*/
+static int fiji_thermal_initialize(struct pp_hwmgr *hwmgr)
+{
+	if (hwmgr->thermal_controller.fanInfo.ucTachometerPulsesPerRevolution)
+		PHM_WRITE_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC,
+				CG_TACH_CTRL, EDGE_PER_REV,
+				hwmgr->thermal_controller.fanInfo.
+				ucTachometerPulsesPerRevolution - 1);
+
+	PHM_WRITE_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC,
+			CG_FDO_CTRL2, TACH_PWM_RESP_RATE, 0x28);
+
+	return 0;
+}
+
+/**
+* Enable thermal alerts on the RV770 thermal controller.
+*
+* @param    hwmgr The address of the hardware manager.
+*/
+static int fiji_thermal_enable_alert(struct pp_hwmgr *hwmgr)
+{
+	uint32_t alert;
+
+	alert = PHM_READ_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC,
+			CG_THERMAL_INT, THERM_INT_MASK);
+	alert &= ~(FIJI_THERMAL_HIGH_ALERT_MASK | FIJI_THERMAL_LOW_ALERT_MASK);
+	PHM_WRITE_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC,
+			CG_THERMAL_INT, THERM_INT_MASK, alert);
+
+	/* send message to SMU to enable internal thermal interrupts */
+	return smum_send_msg_to_smc(hwmgr->smumgr, PPSMC_MSG_Thermal_Cntl_Enable);
+}
+
+/**
+* Disable thermal alerts on the RV770 thermal controller.
+* @param    hwmgr The address of the hardware manager.
+*/
+static int fiji_thermal_disable_alert(struct pp_hwmgr *hwmgr)
+{
+	uint32_t alert;
+
+	alert = PHM_READ_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC,
+			CG_THERMAL_INT, THERM_INT_MASK);
+	alert |= (FIJI_THERMAL_HIGH_ALERT_MASK | FIJI_THERMAL_LOW_ALERT_MASK);
+	PHM_WRITE_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC,
+			CG_THERMAL_INT, THERM_INT_MASK, alert);
+
+	/* send message to SMU to disable internal thermal interrupts */
+	return smum_send_msg_to_smc(hwmgr->smumgr, PPSMC_MSG_Thermal_Cntl_Disable);
+}
+
+/**
+* Uninitialize the thermal controller.
+* Currently just disables alerts.
+* @param    hwmgr The address of the hardware manager.
+*/
+int fiji_thermal_stop_thermal_controller(struct pp_hwmgr *hwmgr)
+{
+	int result = fiji_thermal_disable_alert(hwmgr);
+
+	if (hwmgr->thermal_controller.fanInfo.bNoFan)
+		fiji_fan_ctrl_set_default_mode(hwmgr);
+
+	return result;
+}
+
+/**
+* Set up the fan table to control the fan using the SMC.
+* @param    hwmgr  the address of the powerplay hardware manager.
+* @param    pInput the pointer to input data
+* @param    pOutput the pointer to output data
+* @param    pStorage the pointer to temporary storage
+* @param    Result the last failure code
+* @return   result from set temperature range routine
+*/
+int tf_fiji_thermal_setup_fan_table(struct pp_hwmgr *hwmgr,
+		void *input, void *output, void *storage, int result)
+{
+	struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend);
+	SMU73_Discrete_FanTable fan_table = { FDO_MODE_HARDWARE };
+	uint32_t duty100;
+	uint32_t t_diff1, t_diff2, pwm_diff1, pwm_diff2;
+	uint16_t fdo_min, slope1, slope2;
+	uint32_t reference_clock;
+	int res;
+	uint64_t tmp64;
+
+	if (data->fan_table_start == 0) {
+		phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
+				PHM_PlatformCaps_MicrocodeFanControl);
+		return 0;
+	}
+
+	duty100 = PHM_READ_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC,
+			CG_FDO_CTRL1, FMAX_DUTY100);
+
+	if (duty100 == 0) {
+		phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
+				PHM_PlatformCaps_MicrocodeFanControl);
+		return 0;
+	}
+
+	tmp64 = hwmgr->thermal_controller.advanceFanControlParameters.
+			usPWMMin * duty100;
+	do_div(tmp64, 10000);
+	fdo_min = (uint16_t)tmp64;
+
+	t_diff1 = hwmgr->thermal_controller.advanceFanControlParameters.usTMed -
+			hwmgr->thermal_controller.advanceFanControlParameters.usTMin;
+	t_diff2 = hwmgr->thermal_controller.advanceFanControlParameters.usTHigh -
+			hwmgr->thermal_controller.advanceFanControlParameters.usTMed;
+
+	pwm_diff1 = hwmgr->thermal_controller.advanceFanControlParameters.usPWMMed -
+			hwmgr->thermal_controller.advanceFanControlParameters.usPWMMin;
+	pwm_diff2 = hwmgr->thermal_controller.advanceFanControlParameters.usPWMHigh -
+			hwmgr->thermal_controller.advanceFanControlParameters.usPWMMed;
+
+	slope1 = (uint16_t)((50 + ((16 * duty100 * pwm_diff1) / t_diff1)) / 100);
+	slope2 = (uint16_t)((50 + ((16 * duty100 * pwm_diff2) / t_diff2)) / 100);
+
+	fan_table.TempMin = cpu_to_be16((50 + hwmgr->
+			thermal_controller.advanceFanControlParameters.usTMin) / 100);
+	fan_table.TempMed = cpu_to_be16((50 + hwmgr->
+			thermal_controller.advanceFanControlParameters.usTMed) / 100);
+	fan_table.TempMax = cpu_to_be16((50 + hwmgr->
+			thermal_controller.advanceFanControlParameters.usTMax) / 100);
+
+	fan_table.Slope1 = cpu_to_be16(slope1);
+	fan_table.Slope2 = cpu_to_be16(slope2);
+
+	fan_table.FdoMin = cpu_to_be16(fdo_min);
+
+	fan_table.HystDown = cpu_to_be16(hwmgr->
+			thermal_controller.advanceFanControlParameters.ucTHyst);
+
+	fan_table.HystUp = cpu_to_be16(1);
+
+	fan_table.HystSlope = cpu_to_be16(1);
+
+	fan_table.TempRespLim = cpu_to_be16(5);
+
+	reference_clock = tonga_get_xclk(hwmgr);
+
+	fan_table.RefreshPeriod = cpu_to_be32((hwmgr->
+			thermal_controller.advanceFanControlParameters.ulCycleDelay *
+			reference_clock) / 1600);
+
+	fan_table.FdoMax = cpu_to_be16((uint16_t)duty100);
+
+	fan_table.TempSrc = (uint8_t)PHM_READ_VFPF_INDIRECT_FIELD(
+			hwmgr->device, CGS_IND_REG__SMC,
+			CG_MULT_THERMAL_CTRL, TEMP_SEL);
+
+	res = fiji_copy_bytes_to_smc(hwmgr->smumgr, data->fan_table_start,
+			(uint8_t *)&fan_table, (uint32_t)sizeof(fan_table),
+			data->sram_end);
+
+	if (!res && hwmgr->thermal_controller.
+			advanceFanControlParameters.ucMinimumPWMLimit)
+		res = smum_send_msg_to_smc_with_parameter(hwmgr->smumgr,
+				PPSMC_MSG_SetFanMinPwm,
+				hwmgr->thermal_controller.
+				advanceFanControlParameters.ucMinimumPWMLimit);
+
+	if (!res && hwmgr->thermal_controller.
+			advanceFanControlParameters.ulMinFanSCLKAcousticLimit)
+		res = smum_send_msg_to_smc_with_parameter(hwmgr->smumgr,
+				PPSMC_MSG_SetFanSclkTarget,
+				hwmgr->thermal_controller.
+				advanceFanControlParameters.ulMinFanSCLKAcousticLimit);
+
+	if (res)
+		phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
+				PHM_PlatformCaps_MicrocodeFanControl);
+
+	return 0;
+}
+
+/**
+* Start the fan control on the SMC.
+* @param    hwmgr  the address of the powerplay hardware manager.
+* @param    pInput the pointer to input data
+* @param    pOutput the pointer to output data
+* @param    pStorage the pointer to temporary storage
+* @param    Result the last failure code
+* @return   result from set temperature range routine
+*/
+int tf_fiji_thermal_start_smc_fan_control(struct pp_hwmgr *hwmgr,
+		void *input, void *output, void *storage, int result)
+{
+/* If the fantable setup has failed we could have disabled
+ * PHM_PlatformCaps_MicrocodeFanControl even after
+ * this function was included in the table.
+ * Make sure that we still think controlling the fan is OK.
+*/
+	if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
+			PHM_PlatformCaps_MicrocodeFanControl)) {
+		fiji_fan_ctrl_start_smc_fan_control(hwmgr);
+		fiji_fan_ctrl_set_static_mode(hwmgr, FDO_PWM_MODE_STATIC);
+	}
+
+	return 0;
+}
+
+/**
+* Set temperature range for high and low alerts
+* @param    hwmgr  the address of the powerplay hardware manager.
+* @param    pInput the pointer to input data
+* @param    pOutput the pointer to output data
+* @param    pStorage the pointer to temporary storage
+* @param    Result the last failure code
+* @return   result from set temperature range routine
+*/
+int tf_fiji_thermal_set_temperature_range(struct pp_hwmgr *hwmgr,
+		void *input, void *output, void *storage, int result)
+{
+	struct PP_TemperatureRange *range = (struct PP_TemperatureRange *)input;
+
+	if (range == NULL)
+		return -EINVAL;
+
+	return fiji_thermal_set_temperature_range(hwmgr, range->min, range->max);
+}
+
+/**
+* Programs one-time setting registers
+* @param    hwmgr  the address of the powerplay hardware manager.
+* @param    pInput the pointer to input data
+* @param    pOutput the pointer to output data
+* @param    pStorage the pointer to temporary storage
+* @param    Result the last failure code
+* @return   result from initialize thermal controller routine
+*/
+int tf_fiji_thermal_initialize(struct pp_hwmgr *hwmgr,
+		void *input, void *output, void *storage, int result)
+{
+    return fiji_thermal_initialize(hwmgr);
+}
+
+/**
+* Enable high and low alerts
+* @param    hwmgr  the address of the powerplay hardware manager.
+* @param    pInput the pointer to input data
+* @param    pOutput the pointer to output data
+* @param    pStorage the pointer to temporary storage
+* @param    Result the last failure code
+* @return   result from enable alert routine
+*/
+int tf_fiji_thermal_enable_alert(struct pp_hwmgr *hwmgr,
+		void *input, void *output, void *storage, int result)
+{
+	return fiji_thermal_enable_alert(hwmgr);
+}
+
+/**
+* Disable high and low alerts
+* @param    hwmgr  the address of the powerplay hardware manager.
+* @param    pInput the pointer to input data
+* @param    pOutput the pointer to output data
+* @param    pStorage the pointer to temporary storage
+* @param    Result the last failure code
+* @return   result from disable alert routine
+*/
+static int tf_fiji_thermal_disable_alert(struct pp_hwmgr *hwmgr,
+		void *input, void *output, void *storage, int result)
+{
+	return fiji_thermal_disable_alert(hwmgr);
+}
+
+static struct phm_master_table_item
+fiji_thermal_start_thermal_controller_master_list[] = {
+	{NULL, tf_fiji_thermal_initialize},
+	{NULL, tf_fiji_thermal_set_temperature_range},
+	{NULL, tf_fiji_thermal_enable_alert},
+/* We should restrict performance levels to low before we halt the SMC.
+ * On the other hand we are still in boot state when we do this
+ * so it would be pointless.
+ * If this assumption changes we have to revisit this table.
+ */
+	{NULL, tf_fiji_thermal_setup_fan_table},
+	{NULL, tf_fiji_thermal_start_smc_fan_control},
+	{NULL, NULL}
+};
+
+static struct phm_master_table_header
+fiji_thermal_start_thermal_controller_master = {
+	0,
+	PHM_MasterTableFlag_None,
+	fiji_thermal_start_thermal_controller_master_list
+};
+
+static struct phm_master_table_item
+fiji_thermal_set_temperature_range_master_list[] = {
+	{NULL, tf_fiji_thermal_disable_alert},
+	{NULL, tf_fiji_thermal_set_temperature_range},
+	{NULL, tf_fiji_thermal_enable_alert},
+	{NULL, NULL}
+};
+
+struct phm_master_table_header
+fiji_thermal_set_temperature_range_master = {
+	0,
+	PHM_MasterTableFlag_None,
+	fiji_thermal_set_temperature_range_master_list
+};
+
+int fiji_thermal_ctrl_uninitialize_thermal_controller(struct pp_hwmgr *hwmgr)
+{
+	if (!hwmgr->thermal_controller.fanInfo.bNoFan)
+		fiji_fan_ctrl_set_default_mode(hwmgr);
+	return 0;
+}
+
+/**
+* Initializes the thermal controller related functions in the Hardware Manager structure.
+* @param    hwmgr The address of the hardware manager.
+* @exception Any error code from the low-level communication.
+*/
+int pp_fiji_thermal_initialize(struct pp_hwmgr *hwmgr)
+{
+	int result;
+
+	result = phm_construct_table(hwmgr,
+			&fiji_thermal_set_temperature_range_master,
+			&(hwmgr->set_temperature_range));
+
+	if (!result) {
+		result = phm_construct_table(hwmgr,
+				&fiji_thermal_start_thermal_controller_master,
+				&(hwmgr->start_thermal_controller));
+		if (result)
+			phm_destroy_table(hwmgr, &(hwmgr->set_temperature_range));
+	}
+
+	if (!result)
+		hwmgr->fan_ctrl_is_in_default_mode = true;
+	return result;
+}
+
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/powerplay/hwmgr/fiji_thermal.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2015 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#ifndef FIJI_THERMAL_H
+#define FIJI_THERMAL_H
+
+#include "hwmgr.h"
+
+#define FIJI_THERMAL_HIGH_ALERT_MASK         0x1
+#define FIJI_THERMAL_LOW_ALERT_MASK          0x2
+
+#define FIJI_THERMAL_MINIMUM_TEMP_READING    -256
+#define FIJI_THERMAL_MAXIMUM_TEMP_READING    255
+
+#define FIJI_THERMAL_MINIMUM_ALERT_TEMP      0
+#define FIJI_THERMAL_MAXIMUM_ALERT_TEMP      255
+
+#define FDO_PWM_MODE_STATIC  1
+#define FDO_PWM_MODE_STATIC_RPM 5
+
+
+extern int tf_fiji_thermal_initialize(struct pp_hwmgr *hwmgr, void *input, void *output, void *storage, int result);
+extern int tf_fiji_thermal_set_temperature_range(struct pp_hwmgr *hwmgr, void *input, void *output, void *storage, int result);
+extern int tf_fiji_thermal_enable_alert(struct pp_hwmgr *hwmgr, void *input, void *output, void *storage, int result);
+
+extern int fiji_thermal_get_temperature(struct pp_hwmgr *hwmgr);
+extern int fiji_thermal_stop_thermal_controller(struct pp_hwmgr *hwmgr);
+extern int fiji_fan_ctrl_get_fan_speed_info(struct pp_hwmgr *hwmgr, struct phm_fan_speed_info *fan_speed_info);
+extern int fiji_fan_ctrl_get_fan_speed_percent(struct pp_hwmgr *hwmgr, uint32_t *speed);
+extern int fiji_fan_ctrl_set_default_mode(struct pp_hwmgr *hwmgr);
+extern int fiji_fan_ctrl_set_static_mode(struct pp_hwmgr *hwmgr, uint32_t mode);
+extern int fiji_fan_ctrl_set_fan_speed_percent(struct pp_hwmgr *hwmgr, uint32_t speed);
+extern int fiji_fan_ctrl_reset_fan_speed_to_default(struct pp_hwmgr *hwmgr);
+extern int pp_fiji_thermal_initialize(struct pp_hwmgr *hwmgr);
+extern int fiji_thermal_ctrl_uninitialize_thermal_controller(struct pp_hwmgr *hwmgr);
+extern int fiji_fan_ctrl_set_fan_speed_rpm(struct pp_hwmgr *hwmgr, uint32_t speed);
+extern int fiji_fan_ctrl_get_fan_speed_rpm(struct pp_hwmgr *hwmgr, uint32_t *speed);
+extern int fiji_fan_ctrl_stop_smc_fan_control(struct pp_hwmgr *hwmgr);
+extern uint32_t tonga_get_xclk(struct pp_hwmgr *hwmgr);
+
+#endif
+
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/powerplay/hwmgr/functiontables.c
@@ -0,0 +1,155 @@
+/*
+ * Copyright 2015 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include "hwmgr.h"
+
+static int phm_run_table(struct pp_hwmgr *hwmgr,
+			 struct phm_runtime_table_header *rt_table,
+			 void *input,
+			 void *output,
+			 void *temp_storage)
+{
+	int result = 0;
+	phm_table_function *function;
+
+	for (function = rt_table->function_list; NULL != *function; function++) {
+		int tmp = (*function)(hwmgr, input, output, temp_storage, result);
+
+		if (tmp == PP_Result_TableImmediateExit)
+			break;
+		if (tmp) {
+			if (0 == result)
+				result = tmp;
+			if (rt_table->exit_error)
+				break;
+		}
+	}
+
+	return result;
+}
+
+int phm_dispatch_table(struct pp_hwmgr *hwmgr,
+		       struct phm_runtime_table_header *rt_table,
+		       void *input, void *output)
+{
+	int result = 0;
+	void *temp_storage = NULL;
+
+	if (hwmgr == NULL || rt_table == NULL || rt_table->function_list == NULL) {
+		printk(KERN_ERR "[ powerplay ] Invalid Parameter!\n");
+		return 0; /*temp return ture because some function not implement on some asic */
+	}
+
+	if (0 != rt_table->storage_size) {
+		temp_storage = kzalloc(rt_table->storage_size, GFP_KERNEL);
+		if (temp_storage == NULL) {
+			printk(KERN_ERR "[ powerplay ] Could not allocate table temporary storage\n");
+			return -ENOMEM;
+		}
+	}
+
+	result = phm_run_table(hwmgr, rt_table, input, output, temp_storage);
+
+	if (NULL != temp_storage)
+		kfree(temp_storage);
+
+	return result;
+}
+
+int phm_construct_table(struct pp_hwmgr *hwmgr,
+			struct phm_master_table_header *master_table,
+			struct phm_runtime_table_header *rt_table)
+{
+	uint32_t function_count = 0;
+	const struct phm_master_table_item *table_item;
+	uint32_t size;
+	phm_table_function *run_time_list;
+	phm_table_function *rtf;
+
+	if (hwmgr == NULL || master_table == NULL || rt_table == NULL) {
+		printk(KERN_ERR "[ powerplay ] Invalid Parameter!\n");
+		return -EINVAL;
+	}
+
+	for (table_item = master_table->master_list;
+		NULL != table_item->tableFunction; table_item++) {
+		if ((NULL == table_item->isFunctionNeededInRuntimeTable) ||
+		    (table_item->isFunctionNeededInRuntimeTable(hwmgr)))
+			function_count++;
+	}
+
+	size = (function_count + 1) * sizeof(phm_table_function);
+	run_time_list = kzalloc(size, GFP_KERNEL);
+
+	if (NULL == run_time_list)
+		return -ENOMEM;
+
+	rtf = run_time_list;
+	for (table_item = master_table->master_list;
+		NULL != table_item->tableFunction; table_item++) {
+		if ((rtf - run_time_list) > function_count) {
+			printk(KERN_ERR "[ powerplay ] Check function results have changed\n");
+			kfree(run_time_list);
+			return -EINVAL;
+		}
+
+		if ((NULL == table_item->isFunctionNeededInRuntimeTable) ||
+		     (table_item->isFunctionNeededInRuntimeTable(hwmgr))) {
+			*(rtf++) = table_item->tableFunction;
+		}
+	}
+
+	if ((rtf - run_time_list) > function_count) {
+		printk(KERN_ERR "[ powerplay ] Check function results have changed\n");
+		kfree(run_time_list);
+		return -EINVAL;
+	}
+
+	*rtf = NULL;
+	rt_table->function_list = run_time_list;
+	rt_table->exit_error = (0 != (master_table->flags & PHM_MasterTableFlag_ExitOnError));
+	rt_table->storage_size = master_table->storage_size;
+	return 0;
+}
+
+int phm_destroy_table(struct pp_hwmgr *hwmgr,
+		      struct phm_runtime_table_header *rt_table)
+{
+	if (hwmgr == NULL || rt_table == NULL) {
+		printk(KERN_ERR "[ powerplay ] Invalid Parameter\n");
+		return -EINVAL;
+	}
+
+	if (NULL == rt_table->function_list)
+		return 0;
+
+	kfree(rt_table->function_list);
+
+	rt_table->function_list = NULL;
+	rt_table->storage_size = 0;
+	rt_table->exit_error = false;
+
+	return 0;
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/powerplay/hwmgr/hardwaremanager.c
@@ -0,0 +1,334 @@
+/*
+ * Copyright 2015 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+#include <linux/errno.h>
+#include "hwmgr.h"
+#include "hardwaremanager.h"
+#include "power_state.h"
+#include "pp_acpi.h"
+#include "amd_acpi.h"
+#include "amd_powerplay.h"
+
+#define PHM_FUNC_CHECK(hw) \
+	do {							\
+		if ((hw) == NULL || (hw)->hwmgr_func == NULL)	\
+			return -EINVAL;				\
+	} while (0)
+
+void phm_init_dynamic_caps(struct pp_hwmgr *hwmgr)
+{
+	phm_cap_unset(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_DisableVoltageTransition);
+	phm_cap_unset(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_DisableEngineTransition);
+	phm_cap_unset(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_DisableMemoryTransition);
+	phm_cap_unset(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_DisableMGClockGating);
+	phm_cap_unset(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_DisableMGCGTSSM);
+	phm_cap_unset(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_DisableLSClockGating);
+	phm_cap_unset(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_Force3DClockSupport);
+	phm_cap_unset(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_DisableLightSleep);
+	phm_cap_unset(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_DisableMCLS);
+	phm_cap_set(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_DisablePowerGating);
+
+	phm_cap_unset(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_DisableDPM);
+	phm_cap_unset(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_DisableSMUUVDHandshake);
+	phm_cap_unset(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_ThermalAutoThrottling);
+
+	phm_cap_unset(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_PCIEPerformanceRequest);
+
+	phm_cap_unset(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_NoOD5Support);
+	phm_cap_unset(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_UserMaxClockForMultiDisplays);
+
+	phm_cap_unset(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_VpuRecoveryInProgress);
+
+	if (acpi_atcs_functions_supported(hwmgr->device, ATCS_FUNCTION_PCIE_PERFORMANCE_REQUEST) &&
+		acpi_atcs_functions_supported(hwmgr->device, ATCS_FUNCTION_PCIE_DEVICE_READY_NOTIFICATION))
+		phm_cap_set(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_PCIEPerformanceRequest);
+}
+
+bool phm_is_hw_access_blocked(struct pp_hwmgr *hwmgr)
+{
+	return hwmgr->block_hw_access;
+}
+
+int phm_block_hw_access(struct pp_hwmgr *hwmgr, bool block)
+{
+	hwmgr->block_hw_access = block;
+	return 0;
+}
+
+int phm_setup_asic(struct pp_hwmgr *hwmgr)
+{
+	PHM_FUNC_CHECK(hwmgr);
+
+	if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
+		PHM_PlatformCaps_TablelessHardwareInterface)) {
+		if (NULL != hwmgr->hwmgr_func->asic_setup)
+			return hwmgr->hwmgr_func->asic_setup(hwmgr);
+	} else {
+		return phm_dispatch_table(hwmgr, &(hwmgr->setup_asic),
+					  NULL, NULL);
+	}
+
+	return 0;
+}
+
+int phm_power_down_asic(struct pp_hwmgr *hwmgr)
+{
+	PHM_FUNC_CHECK(hwmgr);
+
+	if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
+		PHM_PlatformCaps_TablelessHardwareInterface)) {
+		if (NULL != hwmgr->hwmgr_func->power_off_asic)
+			return hwmgr->hwmgr_func->power_off_asic(hwmgr);
+	} else {
+		return phm_dispatch_table(hwmgr, &(hwmgr->power_down_asic),
+					  NULL, NULL);
+	}
+
+	return 0;
+}
+
+int phm_set_power_state(struct pp_hwmgr *hwmgr,
+		    const struct pp_hw_power_state *pcurrent_state,
+		    const struct pp_hw_power_state *pnew_power_state)
+{
+	struct phm_set_power_state_input states;
+
+	PHM_FUNC_CHECK(hwmgr);
+
+	states.pcurrent_state = pcurrent_state;
+	states.pnew_state = pnew_power_state;
+
+	if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
+		PHM_PlatformCaps_TablelessHardwareInterface)) {
+		if (NULL != hwmgr->hwmgr_func->power_state_set)
+			return hwmgr->hwmgr_func->power_state_set(hwmgr, &states);
+	} else {
+		return phm_dispatch_table(hwmgr, &(hwmgr->set_power_state), &states, NULL);
+	}
+
+	return 0;
+}
+
+int phm_enable_dynamic_state_management(struct pp_hwmgr *hwmgr)
+{
+	PHM_FUNC_CHECK(hwmgr);
+
+	if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
+		PHM_PlatformCaps_TablelessHardwareInterface)) {
+		if (NULL != hwmgr->hwmgr_func->dynamic_state_management_enable)
+			return hwmgr->hwmgr_func->dynamic_state_management_enable(hwmgr);
+	} else {
+		return phm_dispatch_table(hwmgr,
+				&(hwmgr->enable_dynamic_state_management),
+				NULL, NULL);
+	}
+	return 0;
+}
+
+int phm_force_dpm_levels(struct pp_hwmgr *hwmgr, enum amd_dpm_forced_level level)
+{
+	PHM_FUNC_CHECK(hwmgr);
+
+	if (hwmgr->hwmgr_func->force_dpm_level != NULL)
+		return hwmgr->hwmgr_func->force_dpm_level(hwmgr, level);
+
+	return 0;
+}
+
+int phm_apply_state_adjust_rules(struct pp_hwmgr *hwmgr,
+				   struct pp_power_state *adjusted_ps,
+			     const struct pp_power_state *current_ps)
+{
+	PHM_FUNC_CHECK(hwmgr);
+
+	if (hwmgr->hwmgr_func->apply_state_adjust_rules != NULL)
+		return hwmgr->hwmgr_func->apply_state_adjust_rules(
+									hwmgr,
+								 adjusted_ps,
+								 current_ps);
+	return 0;
+}
+
+int phm_powerdown_uvd(struct pp_hwmgr *hwmgr)
+{
+	PHM_FUNC_CHECK(hwmgr);
+
+	if (hwmgr->hwmgr_func->powerdown_uvd != NULL)
+		return hwmgr->hwmgr_func->powerdown_uvd(hwmgr);
+	return 0;
+}
+
+int phm_powergate_uvd(struct pp_hwmgr *hwmgr, bool gate)
+{
+	PHM_FUNC_CHECK(hwmgr);
+
+	if (hwmgr->hwmgr_func->powergate_uvd != NULL)
+		return hwmgr->hwmgr_func->powergate_uvd(hwmgr, gate);
+	return 0;
+}
+
+int phm_powergate_vce(struct pp_hwmgr *hwmgr, bool gate)
+{
+	PHM_FUNC_CHECK(hwmgr);
+
+	if (hwmgr->hwmgr_func->powergate_vce != NULL)
+		return hwmgr->hwmgr_func->powergate_vce(hwmgr, gate);
+	return 0;
+}
+
+int phm_enable_clock_power_gatings(struct pp_hwmgr *hwmgr)
+{
+	PHM_FUNC_CHECK(hwmgr);
+
+	if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
+		PHM_PlatformCaps_TablelessHardwareInterface)) {
+		if (NULL != hwmgr->hwmgr_func->enable_clock_power_gating)
+			return hwmgr->hwmgr_func->enable_clock_power_gating(hwmgr);
+	} else {
+		return phm_dispatch_table(hwmgr, &(hwmgr->enable_clock_power_gatings), NULL, NULL);
+	}
+	return 0;
+}
+
+int phm_display_configuration_changed(struct pp_hwmgr *hwmgr)
+{
+	PHM_FUNC_CHECK(hwmgr);
+
+	if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
+				 PHM_PlatformCaps_TablelessHardwareInterface)) {
+		if (NULL != hwmgr->hwmgr_func->display_config_changed)
+			hwmgr->hwmgr_func->display_config_changed(hwmgr);
+	} else
+		return phm_dispatch_table(hwmgr, &hwmgr->display_configuration_changed, NULL, NULL);
+	return 0;
+}
+
+int phm_notify_smc_display_config_after_ps_adjustment(struct pp_hwmgr *hwmgr)
+{
+	PHM_FUNC_CHECK(hwmgr);
+
+	if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
+				 PHM_PlatformCaps_TablelessHardwareInterface))
+		if (NULL != hwmgr->hwmgr_func->display_config_changed)
+			hwmgr->hwmgr_func->notify_smc_display_config_after_ps_adjustment(hwmgr);
+
+	return 0;
+}
+
+int phm_stop_thermal_controller(struct pp_hwmgr *hwmgr)
+{
+	PHM_FUNC_CHECK(hwmgr);
+
+	if (hwmgr->hwmgr_func->stop_thermal_controller == NULL)
+		return -EINVAL;
+
+	return hwmgr->hwmgr_func->stop_thermal_controller(hwmgr);
+}
+
+int phm_register_thermal_interrupt(struct pp_hwmgr *hwmgr, const void *info)
+{
+	PHM_FUNC_CHECK(hwmgr);
+
+	if (hwmgr->hwmgr_func->register_internal_thermal_interrupt == NULL)
+		return -EINVAL;
+
+	return hwmgr->hwmgr_func->register_internal_thermal_interrupt(hwmgr, info);
+}
+
+/**
+* Initializes the thermal controller subsystem.
+*
+* @param    pHwMgr  the address of the powerplay hardware manager.
+* @param    pTemperatureRange the address of the structure holding the temperature range.
+* @exception PP_Result_Failed if any of the paramters is NULL, otherwise the return value from the dispatcher.
+*/
+int phm_start_thermal_controller(struct pp_hwmgr *hwmgr, struct PP_TemperatureRange *temperature_range)
+{
+	return phm_dispatch_table(hwmgr, &(hwmgr->start_thermal_controller), temperature_range, NULL);
+}
+
+
+bool phm_check_smc_update_required_for_display_configuration(struct pp_hwmgr *hwmgr)
+{
+	PHM_FUNC_CHECK(hwmgr);
+
+	if (hwmgr->hwmgr_func->check_smc_update_required_for_display_configuration == NULL)
+		return -EINVAL;
+
+	return hwmgr->hwmgr_func->check_smc_update_required_for_display_configuration(hwmgr);
+}
+
+
+int phm_check_states_equal(struct pp_hwmgr *hwmgr,
+				 const struct pp_hw_power_state *pstate1,
+				 const struct pp_hw_power_state *pstate2,
+				 bool *equal)
+{
+	PHM_FUNC_CHECK(hwmgr);
+
+	if (hwmgr->hwmgr_func->check_states_equal == NULL)
+		return -EINVAL;
+
+	return hwmgr->hwmgr_func->check_states_equal(hwmgr, pstate1, pstate2, equal);
+}
+
+int phm_store_dal_configuration_data(struct pp_hwmgr *hwmgr,
+		    const struct amd_pp_display_configuration *display_config)
+{
+	PHM_FUNC_CHECK(hwmgr);
+
+	if (hwmgr->hwmgr_func->store_cc6_data == NULL)
+		return -EINVAL;
+
+	hwmgr->display_config = *display_config;
+	/* to do pass other display configuration in furture */
+
+	if (hwmgr->hwmgr_func->store_cc6_data)
+		hwmgr->hwmgr_func->store_cc6_data(hwmgr,
+				display_config->cpu_pstate_separation_time,
+				display_config->cpu_cc6_disable,
+				display_config->cpu_pstate_disable,
+				display_config->nb_pstate_switch_disable);
+
+	return 0;
+}
+
+int phm_get_dal_power_level(struct pp_hwmgr *hwmgr,
+		struct amd_pp_dal_clock_info *info)
+{
+	PHM_FUNC_CHECK(hwmgr);
+
+	if (info == NULL || hwmgr->hwmgr_func->get_dal_power_level == NULL)
+		return -EINVAL;
+
+	return hwmgr->hwmgr_func->get_dal_power_level(hwmgr, info);
+}
+
+int phm_set_cpu_power_state(struct pp_hwmgr *hwmgr)
+{
+	PHM_FUNC_CHECK(hwmgr);
+
+	if (hwmgr->hwmgr_func->set_cpu_power_state != NULL)
+		return hwmgr->hwmgr_func->set_cpu_power_state(hwmgr);
+
+	return 0;
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr.c
@@ -0,0 +1,563 @@
+/*
+ * Copyright 2015 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+#include "linux/delay.h"
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include "cgs_common.h"
+#include "power_state.h"
+#include "hwmgr.h"
+#include "pppcielanes.h"
+#include "pp_debug.h"
+#include "ppatomctrl.h"
+
+extern int cz_hwmgr_init(struct pp_hwmgr *hwmgr);
+extern int tonga_hwmgr_init(struct pp_hwmgr *hwmgr);
+extern int fiji_hwmgr_init(struct pp_hwmgr *hwmgr);
+
+int hwmgr_init(struct amd_pp_init *pp_init, struct pp_instance *handle)
+{
+	struct pp_hwmgr *hwmgr;
+
+	if ((handle == NULL) || (pp_init == NULL))
+		return -EINVAL;
+
+	hwmgr = kzalloc(sizeof(struct pp_hwmgr), GFP_KERNEL);
+	if (hwmgr == NULL)
+		return -ENOMEM;
+
+	handle->hwmgr = hwmgr;
+	hwmgr->smumgr = handle->smu_mgr;
+	hwmgr->device = pp_init->device;
+	hwmgr->chip_family = pp_init->chip_family;
+	hwmgr->chip_id = pp_init->chip_id;
+	hwmgr->hw_revision = pp_init->rev_id;
+	hwmgr->usec_timeout = AMD_MAX_USEC_TIMEOUT;
+	hwmgr->power_source = PP_PowerSource_AC;
+
+	switch (hwmgr->chip_family) {
+	case AMD_FAMILY_CZ:
+		cz_hwmgr_init(hwmgr);
+		break;
+	case AMD_FAMILY_VI:
+		switch (hwmgr->chip_id) {
+		case CHIP_TONGA:
+			tonga_hwmgr_init(hwmgr);
+			break;
+		case CHIP_FIJI:
+			fiji_hwmgr_init(hwmgr);
+			break;
+		default:
+			return -EINVAL;
+		}
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	phm_init_dynamic_caps(hwmgr);
+
+	return 0;
+}
+
+int hwmgr_fini(struct pp_hwmgr *hwmgr)
+{
+	if (hwmgr == NULL || hwmgr->ps == NULL)
+		return -EINVAL;
+
+	kfree(hwmgr->ps);
+	kfree(hwmgr);
+	return 0;
+}
+
+int hw_init_power_state_table(struct pp_hwmgr *hwmgr)
+{
+	int result;
+	unsigned int i;
+	unsigned int table_entries;
+	struct pp_power_state *state;
+	int size;
+
+	if (hwmgr->hwmgr_func->get_num_of_pp_table_entries == NULL)
+		return -EINVAL;
+
+	if (hwmgr->hwmgr_func->get_power_state_size == NULL)
+		return -EINVAL;
+
+	hwmgr->num_ps = table_entries = hwmgr->hwmgr_func->get_num_of_pp_table_entries(hwmgr);
+
+	hwmgr->ps_size = size = hwmgr->hwmgr_func->get_power_state_size(hwmgr) +
+					  sizeof(struct pp_power_state);
+
+	hwmgr->ps = kzalloc(size * table_entries, GFP_KERNEL);
+
+	if (hwmgr->ps == NULL)
+		return -ENOMEM;
+
+	state = hwmgr->ps;
+
+	for (i = 0; i < table_entries; i++) {
+		result = hwmgr->hwmgr_func->get_pp_table_entry(hwmgr, i, state);
+
+		if (state->classification.flags & PP_StateClassificationFlag_Boot) {
+			hwmgr->boot_ps = state;
+			hwmgr->current_ps = hwmgr->request_ps = state;
+		}
+
+		state->id = i + 1; /* assigned unique num for every power state id */
+
+		if (state->classification.flags & PP_StateClassificationFlag_Uvd)
+			hwmgr->uvd_ps = state;
+		state = (struct pp_power_state *)((unsigned long)state + size);
+	}
+
+	return 0;
+}
+
+
+/**
+ * Returns once the part of the register indicated by the mask has
+ * reached the given value.
+ */
+int phm_wait_on_register(struct pp_hwmgr *hwmgr, uint32_t index,
+			 uint32_t value, uint32_t mask)
+{
+	uint32_t i;
+	uint32_t cur_value;
+
+	if (hwmgr == NULL || hwmgr->device == NULL) {
+		printk(KERN_ERR "[ powerplay ] Invalid Hardware Manager!");
+		return -EINVAL;
+	}
+
+	for (i = 0; i < hwmgr->usec_timeout; i++) {
+		cur_value = cgs_read_register(hwmgr->device, index);
+		if ((cur_value & mask) == (value & mask))
+			break;
+		udelay(1);
+	}
+
+	/* timeout means wrong logic*/
+	if (i == hwmgr->usec_timeout)
+		return -1;
+	return 0;
+}
+
+int phm_wait_for_register_unequal(struct pp_hwmgr *hwmgr,
+				uint32_t index, uint32_t value, uint32_t mask)
+{
+	uint32_t i;
+	uint32_t cur_value;
+
+	if (hwmgr == NULL || hwmgr->device == NULL) {
+		printk(KERN_ERR "[ powerplay ] Invalid Hardware Manager!");
+		return -EINVAL;
+	}
+
+	for (i = 0; i < hwmgr->usec_timeout; i++) {
+		cur_value = cgs_read_register(hwmgr->device, index);
+		if ((cur_value & mask) != (value & mask))
+			break;
+		udelay(1);
+	}
+
+	/* timeout means wrong logic*/
+	if (i == hwmgr->usec_timeout)
+		return -1;
+	return 0;
+}
+
+
+/**
+ * Returns once the part of the register indicated by the mask has
+ * reached the given value.The indirect space is described by giving
+ * the memory-mapped index of the indirect index register.
+ */
+void phm_wait_on_indirect_register(struct pp_hwmgr *hwmgr,
+				uint32_t indirect_port,
+				uint32_t index,
+				uint32_t value,
+				uint32_t mask)
+{
+	if (hwmgr == NULL || hwmgr->device == NULL) {
+		printk(KERN_ERR "[ powerplay ] Invalid Hardware Manager!");
+		return;
+	}
+
+	cgs_write_register(hwmgr->device, indirect_port, index);
+	phm_wait_on_register(hwmgr, indirect_port + 1, mask, value);
+}
+
+void phm_wait_for_indirect_register_unequal(struct pp_hwmgr *hwmgr,
+					uint32_t indirect_port,
+					uint32_t index,
+					uint32_t value,
+					uint32_t mask)
+{
+	if (hwmgr == NULL || hwmgr->device == NULL) {
+		printk(KERN_ERR "[ powerplay ] Invalid Hardware Manager!");
+		return;
+	}
+
+	cgs_write_register(hwmgr->device, indirect_port, index);
+	phm_wait_for_register_unequal(hwmgr, indirect_port + 1,
+				      value, mask);
+}
+
+bool phm_cf_want_uvd_power_gating(struct pp_hwmgr *hwmgr)
+{
+	return phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_UVDPowerGating);
+}
+
+bool phm_cf_want_vce_power_gating(struct pp_hwmgr *hwmgr)
+{
+	return phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_VCEPowerGating);
+}
+
+
+int phm_trim_voltage_table(struct pp_atomctrl_voltage_table *vol_table)
+{
+	uint32_t i, j;
+	uint16_t vvalue;
+	bool found = false;
+	struct pp_atomctrl_voltage_table *table;
+
+	PP_ASSERT_WITH_CODE((NULL != vol_table),
+			"Voltage Table empty.", return -EINVAL);
+
+	table = kzalloc(sizeof(struct pp_atomctrl_voltage_table),
+			GFP_KERNEL);
+
+	if (NULL == table)
+		return -EINVAL;
+
+	table->mask_low = vol_table->mask_low;
+	table->phase_delay = vol_table->phase_delay;
+
+	for (i = 0; i < vol_table->count; i++) {
+		vvalue = vol_table->entries[i].value;
+		found = false;
+
+		for (j = 0; j < table->count; j++) {
+			if (vvalue == table->entries[j].value) {
+				found = true;
+				break;
+			}
+		}
+
+		if (!found) {
+			table->entries[table->count].value = vvalue;
+			table->entries[table->count].smio_low =
+					vol_table->entries[i].smio_low;
+			table->count++;
+		}
+	}
+
+	memcpy(vol_table, table, sizeof(struct pp_atomctrl_voltage_table));
+	kfree(table);
+
+	return 0;
+}
+
+int phm_get_svi2_mvdd_voltage_table(struct pp_atomctrl_voltage_table *vol_table,
+		phm_ppt_v1_clock_voltage_dependency_table *dep_table)
+{
+	uint32_t i;
+	int result;
+
+	PP_ASSERT_WITH_CODE((0 != dep_table->count),
+			"Voltage Dependency Table empty.", return -EINVAL);
+
+	PP_ASSERT_WITH_CODE((NULL != vol_table),
+			"vol_table empty.", return -EINVAL);
+
+	vol_table->mask_low = 0;
+	vol_table->phase_delay = 0;
+	vol_table->count = dep_table->count;
+
+	for (i = 0; i < dep_table->count; i++) {
+		vol_table->entries[i].value = dep_table->entries[i].mvdd;
+		vol_table->entries[i].smio_low = 0;
+	}
+
+	result = phm_trim_voltage_table(vol_table);
+	PP_ASSERT_WITH_CODE((0 == result),
+			"Failed to trim MVDD table.", return result);
+
+	return 0;
+}
+
+int phm_get_svi2_vddci_voltage_table(struct pp_atomctrl_voltage_table *vol_table,
+		phm_ppt_v1_clock_voltage_dependency_table *dep_table)
+{
+	uint32_t i;
+	int result;
+
+	PP_ASSERT_WITH_CODE((0 != dep_table->count),
+			"Voltage Dependency Table empty.", return -EINVAL);
+
+	PP_ASSERT_WITH_CODE((NULL != vol_table),
+			"vol_table empty.", return -EINVAL);
+
+	vol_table->mask_low = 0;
+	vol_table->phase_delay = 0;
+	vol_table->count = dep_table->count;
+
+	for (i = 0; i < dep_table->count; i++) {
+		vol_table->entries[i].value = dep_table->entries[i].vddci;
+		vol_table->entries[i].smio_low = 0;
+	}
+
+	result = phm_trim_voltage_table(vol_table);
+	PP_ASSERT_WITH_CODE((0 == result),
+			"Failed to trim VDDCI table.", return result);
+
+	return 0;
+}
+
+int phm_get_svi2_vdd_voltage_table(struct pp_atomctrl_voltage_table *vol_table,
+		phm_ppt_v1_voltage_lookup_table *lookup_table)
+{
+	int i = 0;
+
+	PP_ASSERT_WITH_CODE((0 != lookup_table->count),
+			"Voltage Lookup Table empty.", return -EINVAL);
+
+	PP_ASSERT_WITH_CODE((NULL != vol_table),
+			"vol_table empty.", return -EINVAL);
+
+	vol_table->mask_low = 0;
+	vol_table->phase_delay = 0;
+
+	vol_table->count = lookup_table->count;
+
+	for (i = 0; i < vol_table->count; i++) {
+		vol_table->entries[i].value = lookup_table->entries[i].us_vdd;
+		vol_table->entries[i].smio_low = 0;
+	}
+
+	return 0;
+}
+
+void phm_trim_voltage_table_to_fit_state_table(uint32_t max_vol_steps,
+				struct pp_atomctrl_voltage_table *vol_table)
+{
+	unsigned int i, diff;
+
+	if (vol_table->count <= max_vol_steps)
+		return;
+
+	diff = vol_table->count - max_vol_steps;
+
+	for (i = 0; i < max_vol_steps; i++)
+		vol_table->entries[i] = vol_table->entries[i + diff];
+
+	vol_table->count = max_vol_steps;
+
+	return;
+}
+
+int phm_reset_single_dpm_table(void *table,
+				uint32_t count, int max)
+{
+	int i;
+
+	struct vi_dpm_table *dpm_table = (struct vi_dpm_table *)table;
+
+	PP_ASSERT_WITH_CODE(count <= max,
+			"Fatal error, can not set up single DPM table entries to exceed max number!",
+			   );
+
+	dpm_table->count = count;
+	for (i = 0; i < max; i++)
+		dpm_table->dpm_level[i].enabled = false;
+
+	return 0;
+}
+
+void phm_setup_pcie_table_entry(
+	void *table,
+	uint32_t index, uint32_t pcie_gen,
+	uint32_t pcie_lanes)
+{
+	struct vi_dpm_table *dpm_table = (struct vi_dpm_table *)table;
+	dpm_table->dpm_level[index].value = pcie_gen;
+	dpm_table->dpm_level[index].param1 = pcie_lanes;
+	dpm_table->dpm_level[index].enabled = 1;
+}
+
+int32_t phm_get_dpm_level_enable_mask_value(void *table)
+{
+	int32_t i;
+	int32_t mask = 0;
+	struct vi_dpm_table *dpm_table = (struct vi_dpm_table *)table;
+
+	for (i = dpm_table->count; i > 0; i--) {
+		mask = mask << 1;
+		if (dpm_table->dpm_level[i - 1].enabled)
+			mask |= 0x1;
+		else
+			mask &= 0xFFFFFFFE;
+	}
+
+	return mask;
+}
+
+uint8_t phm_get_voltage_index(
+		struct phm_ppt_v1_voltage_lookup_table *lookup_table, uint16_t voltage)
+{
+	uint8_t count = (uint8_t) (lookup_table->count);
+	uint8_t i;
+
+	PP_ASSERT_WITH_CODE((NULL != lookup_table),
+			"Lookup Table empty.", return 0);
+	PP_ASSERT_WITH_CODE((0 != count),
+			"Lookup Table empty.", return 0);
+
+	for (i = 0; i < lookup_table->count; i++) {
+		/* find first voltage equal or bigger than requested */
+		if (lookup_table->entries[i].us_vdd >= voltage)
+			return i;
+	}
+	/* voltage is bigger than max voltage in the table */
+	return i - 1;
+}
+
+uint16_t phm_find_closest_vddci(struct pp_atomctrl_voltage_table *vddci_table, uint16_t vddci)
+{
+	uint32_t  i;
+
+	for (i = 0; i < vddci_table->count; i++) {
+		if (vddci_table->entries[i].value >= vddci)
+			return vddci_table->entries[i].value;
+	}
+
+	PP_ASSERT_WITH_CODE(false,
+			"VDDCI is larger than max VDDCI in VDDCI Voltage Table!",
+			return vddci_table->entries[i].value);
+}
+
+int phm_find_boot_level(void *table,
+		uint32_t value, uint32_t *boot_level)
+{
+	int result = -EINVAL;
+	uint32_t i;
+	struct vi_dpm_table *dpm_table = (struct vi_dpm_table *)table;
+
+	for (i = 0; i < dpm_table->count; i++) {
+		if (value == dpm_table->dpm_level[i].value) {
+			*boot_level = i;
+			result = 0;
+		}
+	}
+
+	return result;
+}
+
+int phm_get_sclk_for_voltage_evv(struct pp_hwmgr *hwmgr,
+	phm_ppt_v1_voltage_lookup_table *lookup_table,
+	uint16_t virtual_voltage_id, int32_t *sclk)
+{
+	uint8_t entryId;
+	uint8_t voltageId;
+	struct phm_ppt_v1_information *table_info =
+			(struct phm_ppt_v1_information *)(hwmgr->pptable);
+
+	PP_ASSERT_WITH_CODE(lookup_table->count != 0, "Lookup table is empty", return -EINVAL);
+
+	/* search for leakage voltage ID 0xff01 ~ 0xff08 and sckl */
+	for (entryId = 0; entryId < table_info->vdd_dep_on_sclk->count; entryId++) {
+		voltageId = table_info->vdd_dep_on_sclk->entries[entryId].vddInd;
+		if (lookup_table->entries[voltageId].us_vdd == virtual_voltage_id)
+			break;
+	}
+
+	PP_ASSERT_WITH_CODE(entryId < table_info->vdd_dep_on_sclk->count,
+			"Can't find requested voltage id in vdd_dep_on_sclk table!",
+			return -EINVAL;
+			);
+
+	*sclk = table_info->vdd_dep_on_sclk->entries[entryId].clk;
+
+	return 0;
+}
+
+/**
+ * Initialize Dynamic State Adjustment Rule Settings
+ *
+ * @param    hwmgr  the address of the powerplay hardware manager.
+ */
+int phm_initializa_dynamic_state_adjustment_rule_settings(struct pp_hwmgr *hwmgr)
+{
+	uint32_t table_size;
+	struct phm_clock_voltage_dependency_table *table_clk_vlt;
+	struct phm_ppt_v1_information *pptable_info = (struct phm_ppt_v1_information *)(hwmgr->pptable);
+
+	/* initialize vddc_dep_on_dal_pwrl table */
+	table_size = sizeof(uint32_t) + 4 * sizeof(struct phm_clock_voltage_dependency_record);
+	table_clk_vlt = (struct phm_clock_voltage_dependency_table *)kzalloc(table_size, GFP_KERNEL);
+
+	if (NULL == table_clk_vlt) {
+		printk(KERN_ERR "[ powerplay ] Can not allocate space for vddc_dep_on_dal_pwrl! \n");
+		return -ENOMEM;
+	} else {
+		table_clk_vlt->count = 4;
+		table_clk_vlt->entries[0].clk = PP_DAL_POWERLEVEL_ULTRALOW;
+		table_clk_vlt->entries[0].v = 0;
+		table_clk_vlt->entries[1].clk = PP_DAL_POWERLEVEL_LOW;
+		table_clk_vlt->entries[1].v = 720;
+		table_clk_vlt->entries[2].clk = PP_DAL_POWERLEVEL_NOMINAL;
+		table_clk_vlt->entries[2].v = 810;
+		table_clk_vlt->entries[3].clk = PP_DAL_POWERLEVEL_PERFORMANCE;
+		table_clk_vlt->entries[3].v = 900;
+		pptable_info->vddc_dep_on_dal_pwrl = table_clk_vlt;
+		hwmgr->dyn_state.vddc_dep_on_dal_pwrl = table_clk_vlt;
+	}
+
+	return 0;
+}
+
+int phm_hwmgr_backend_fini(struct pp_hwmgr *hwmgr)
+{
+	if (NULL != hwmgr->dyn_state.vddc_dep_on_dal_pwrl) {
+		kfree(hwmgr->dyn_state.vddc_dep_on_dal_pwrl);
+		hwmgr->dyn_state.vddc_dep_on_dal_pwrl = NULL;
+	}
+
+	if (NULL != hwmgr->backend) {
+		kfree(hwmgr->backend);
+		hwmgr->backend = NULL;
+	}
+
+	return 0;
+}
+
+uint32_t phm_get_lowest_enabled_level(struct pp_hwmgr *hwmgr, uint32_t mask)
+{
+	uint32_t level = 0;
+
+	while (0 == (mask & (1 << level)))
+		level++;
+
+	return level;
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr_ppt.h
@@ -0,0 +1,105 @@
+/*
+ * Copyright 2015 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#ifndef PP_HWMGR_PPT_H
+#define PP_HWMGR_PPT_H
+
+#include "hardwaremanager.h"
+#include "smumgr.h"
+#include "atom-types.h"
+
+struct phm_ppt_v1_clock_voltage_dependency_record {
+	uint32_t clk;
+	uint8_t vddInd;
+	uint16_t vdd_offset;
+	uint16_t vddc;
+	uint16_t vddgfx;
+	uint16_t vddci;
+	uint16_t mvdd;
+	uint8_t phases;
+	uint8_t cks_enable;
+	uint8_t cks_voffset;
+};
+
+typedef struct phm_ppt_v1_clock_voltage_dependency_record phm_ppt_v1_clock_voltage_dependency_record;
+
+struct phm_ppt_v1_clock_voltage_dependency_table {
+	uint32_t count;                                            /* Number of entries. */
+	phm_ppt_v1_clock_voltage_dependency_record entries[1];     /* Dynamically allocate count entries. */
+};
+
+typedef struct phm_ppt_v1_clock_voltage_dependency_table phm_ppt_v1_clock_voltage_dependency_table;
+
+
+/* Multimedia Clock Voltage Dependency records and table */
+struct phm_ppt_v1_mm_clock_voltage_dependency_record {
+	uint32_t  dclk;                                              /* UVD D-clock */
+	uint32_t  vclk;                                              /* UVD V-clock */
+	uint32_t  eclk;                                              /* VCE clock */
+	uint32_t  aclk;                                              /* ACP clock */
+	uint32_t  samclock;                                          /* SAMU clock */
+	uint8_t	vddcInd;
+	uint16_t vddgfx_offset;
+	uint16_t vddc;
+	uint16_t vddgfx;
+	uint8_t phases;
+};
+typedef struct phm_ppt_v1_mm_clock_voltage_dependency_record phm_ppt_v1_mm_clock_voltage_dependency_record;
+
+struct phm_ppt_v1_mm_clock_voltage_dependency_table {
+	uint32_t count;													/* Number of entries. */
+	phm_ppt_v1_mm_clock_voltage_dependency_record entries[1];		/* Dynamically allocate count entries. */
+};
+typedef struct phm_ppt_v1_mm_clock_voltage_dependency_table phm_ppt_v1_mm_clock_voltage_dependency_table;
+
+struct phm_ppt_v1_voltage_lookup_record {
+	uint16_t us_calculated;
+	uint16_t us_vdd;												/* Base voltage */
+	uint16_t us_cac_low;
+	uint16_t us_cac_mid;
+	uint16_t us_cac_high;
+};
+typedef struct phm_ppt_v1_voltage_lookup_record phm_ppt_v1_voltage_lookup_record;
+
+struct phm_ppt_v1_voltage_lookup_table {
+	uint32_t count;
+	phm_ppt_v1_voltage_lookup_record entries[1];    /* Dynamically allocate count entries. */
+};
+typedef struct phm_ppt_v1_voltage_lookup_table phm_ppt_v1_voltage_lookup_table;
+
+/* PCIE records and Table */
+
+struct phm_ppt_v1_pcie_record {
+	uint8_t gen_speed;
+	uint8_t lane_width;
+};
+typedef struct phm_ppt_v1_pcie_record phm_ppt_v1_pcie_record;
+
+struct phm_ppt_v1_pcie_table {
+	uint32_t count;                                            /* Number of entries. */
+	phm_ppt_v1_pcie_record entries[1];                         /* Dynamically allocate count entries. */
+};
+typedef struct phm_ppt_v1_pcie_table phm_ppt_v1_pcie_table;
+
+#endif
+
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/powerplay/hwmgr/pp_acpi.c
@@ -0,0 +1,76 @@
+#include <linux/errno.h>
+#include "linux/delay.h"
+#include "hwmgr.h"
+#include "amd_acpi.h"
+
+bool acpi_atcs_functions_supported(void *device, uint32_t index)
+{
+	int32_t result;
+	struct atcs_verify_interface output_buf = {0};
+
+	int32_t temp_buffer = 1;
+
+	result = cgs_call_acpi_method(device, CGS_ACPI_METHOD_ATCS,
+						ATCS_FUNCTION_VERIFY_INTERFACE,
+						&temp_buffer,
+						&output_buf,
+						1,
+						sizeof(temp_buffer),
+						sizeof(output_buf));
+
+	return result == 0 ? (output_buf.function_bits & (1 << (index - 1))) != 0 : false;
+}
+
+int acpi_pcie_perf_request(void *device, uint8_t perf_req, bool advertise)
+{
+	struct atcs_pref_req_input atcs_input;
+	struct atcs_pref_req_output atcs_output;
+	u32 retry = 3;
+	int result;
+	struct cgs_system_info info = {0};
+
+	if (!acpi_atcs_functions_supported(device, ATCS_FUNCTION_PCIE_PERFORMANCE_REQUEST))
+		return -EINVAL;
+
+	info.size = sizeof(struct cgs_system_info);
+	info.info_id = CGS_SYSTEM_INFO_ADAPTER_BDF_ID;
+	result = cgs_query_system_info(device, &info);
+	if (result != 0)
+		return -EINVAL;
+	atcs_input.client_id = (uint16_t)info.value;
+	atcs_input.size = sizeof(struct atcs_pref_req_input);
+	atcs_input.valid_flags_mask = ATCS_VALID_FLAGS_MASK;
+	atcs_input.flags = ATCS_WAIT_FOR_COMPLETION;
+	if (advertise)
+		atcs_input.flags |= ATCS_ADVERTISE_CAPS;
+	atcs_input.req_type = ATCS_PCIE_LINK_SPEED;
+	atcs_input.perf_req = perf_req;
+
+	atcs_output.size = sizeof(struct atcs_pref_req_input);
+
+	while (retry--) {
+		result = cgs_call_acpi_method(device,
+						CGS_ACPI_METHOD_ATCS,
+						ATCS_FUNCTION_PCIE_PERFORMANCE_REQUEST,
+						&atcs_input,
+						&atcs_output,
+						0,
+						sizeof(atcs_input),
+						sizeof(atcs_output));
+		if (result != 0)
+			return -EIO;
+
+		switch (atcs_output.ret_val) {
+		case ATCS_REQUEST_REFUSED:
+		default:
+			return -EINVAL;
+		case ATCS_REQUEST_COMPLETE:
+			return 0;
+		case ATCS_REQUEST_IN_PROGRESS:
+			udelay(10);
+			break;
+		}
+	}
+
+	return 0;
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/powerplay/hwmgr/ppatomctrl.c
@@ -0,0 +1,1207 @@
+/*
+ * Copyright 2015 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/fb.h>
+
+#include "ppatomctrl.h"
+#include "atombios.h"
+#include "cgs_common.h"
+#include "pp_debug.h"
+#include "ppevvmath.h"
+
+#define MEM_ID_MASK           0xff000000
+#define MEM_ID_SHIFT          24
+#define CLOCK_RANGE_MASK      0x00ffffff
+#define CLOCK_RANGE_SHIFT     0
+#define LOW_NIBBLE_MASK       0xf
+#define DATA_EQU_PREV         0
+#define DATA_FROM_TABLE       4
+
+union voltage_object_info {
+	struct _ATOM_VOLTAGE_OBJECT_INFO v1;
+	struct _ATOM_VOLTAGE_OBJECT_INFO_V2 v2;
+	struct _ATOM_VOLTAGE_OBJECT_INFO_V3_1 v3;
+};
+
+static int atomctrl_retrieve_ac_timing(
+		uint8_t index,
+		ATOM_INIT_REG_BLOCK *reg_block,
+		pp_atomctrl_mc_reg_table *table)
+{
+	uint32_t i, j;
+	uint8_t tmem_id;
+	ATOM_MEMORY_SETTING_DATA_BLOCK *reg_data = (ATOM_MEMORY_SETTING_DATA_BLOCK *)
+		((uint8_t *)reg_block + (2 * sizeof(uint16_t)) + le16_to_cpu(reg_block->usRegIndexTblSize));
+
+	uint8_t num_ranges = 0;
+
+	while (*(uint32_t *)reg_data != END_OF_REG_DATA_BLOCK &&
+			num_ranges < VBIOS_MAX_AC_TIMING_ENTRIES) {
+		tmem_id = (uint8_t)((*(uint32_t *)reg_data & MEM_ID_MASK) >> MEM_ID_SHIFT);
+
+		if (index == tmem_id) {
+			table->mc_reg_table_entry[num_ranges].mclk_max =
+				(uint32_t)((*(uint32_t *)reg_data & CLOCK_RANGE_MASK) >>
+						CLOCK_RANGE_SHIFT);
+
+			for (i = 0, j = 1; i < table->last; i++) {
+				if ((table->mc_reg_address[i].uc_pre_reg_data &
+							LOW_NIBBLE_MASK) == DATA_FROM_TABLE) {
+					table->mc_reg_table_entry[num_ranges].mc_data[i] =
+						(uint32_t)*((uint32_t *)reg_data + j);
+					j++;
+				} else if ((table->mc_reg_address[i].uc_pre_reg_data &
+							LOW_NIBBLE_MASK) == DATA_EQU_PREV) {
+					table->mc_reg_table_entry[num_ranges].mc_data[i] =
+						table->mc_reg_table_entry[num_ranges].mc_data[i-1];
+				}
+			}
+			num_ranges++;
+		}
+
+		reg_data = (ATOM_MEMORY_SETTING_DATA_BLOCK *)
+			((uint8_t *)reg_data + le16_to_cpu(reg_block->usRegDataBlkSize)) ;
+	}
+
+	PP_ASSERT_WITH_CODE((*(uint32_t *)reg_data == END_OF_REG_DATA_BLOCK),
+			"Invalid VramInfo table.", return -1);
+	table->num_entries = num_ranges;
+
+	return 0;
+}
+
+/**
+ * Get memory clock AC timing registers index from VBIOS table
+ * VBIOS set end of memory clock AC timing registers by ucPreRegDataLength bit6 = 1
+ * @param    reg_block the address ATOM_INIT_REG_BLOCK
+ * @param    table the address of MCRegTable
+ * @return   0
+ */
+static int atomctrl_set_mc_reg_address_table(
+		ATOM_INIT_REG_BLOCK *reg_block,
+		pp_atomctrl_mc_reg_table *table)
+{
+	uint8_t i = 0;
+	uint8_t num_entries = (uint8_t)((le16_to_cpu(reg_block->usRegIndexTblSize))
+			/ sizeof(ATOM_INIT_REG_INDEX_FORMAT));
+	ATOM_INIT_REG_INDEX_FORMAT *format = &reg_block->asRegIndexBuf[0];
+
+	num_entries--;        /* subtract 1 data end mark entry */
+
+	PP_ASSERT_WITH_CODE((num_entries <= VBIOS_MC_REGISTER_ARRAY_SIZE),
+			"Invalid VramInfo table.", return -1);
+
+	/* ucPreRegDataLength bit6 = 1 is the end of memory clock AC timing registers */
+	while ((!(format->ucPreRegDataLength & ACCESS_PLACEHOLDER)) &&
+			(i < num_entries)) {
+		table->mc_reg_address[i].s1 =
+			(uint16_t)(le16_to_cpu(format->usRegIndex));
+		table->mc_reg_address[i].uc_pre_reg_data =
+			format->ucPreRegDataLength;
+
+		i++;
+		format = (ATOM_INIT_REG_INDEX_FORMAT *)
+			((uint8_t *)format + sizeof(ATOM_INIT_REG_INDEX_FORMAT));
+	}
+
+	table->last = i;
+	return 0;
+}
+
+
+int atomctrl_initialize_mc_reg_table(
+		struct pp_hwmgr *hwmgr,
+		uint8_t module_index,
+		pp_atomctrl_mc_reg_table *table)
+{
+	ATOM_VRAM_INFO_HEADER_V2_1 *vram_info;
+	ATOM_INIT_REG_BLOCK *reg_block;
+	int result = 0;
+	u8 frev, crev;
+	u16 size;
+
+	vram_info = (ATOM_VRAM_INFO_HEADER_V2_1 *)
+		cgs_atom_get_data_table(hwmgr->device,
+				GetIndexIntoMasterTable(DATA, VRAM_Info), &size, &frev, &crev);
+
+	if (module_index >= vram_info->ucNumOfVRAMModule) {
+		printk(KERN_ERR "[ powerplay ] Invalid VramInfo table.");
+		result = -1;
+	} else if (vram_info->sHeader.ucTableFormatRevision < 2) {
+		printk(KERN_ERR "[ powerplay ] Invalid VramInfo table.");
+		result = -1;
+	}
+
+	if (0 == result) {
+		reg_block = (ATOM_INIT_REG_BLOCK *)
+			((uint8_t *)vram_info + le16_to_cpu(vram_info->usMemClkPatchTblOffset));
+		result = atomctrl_set_mc_reg_address_table(reg_block, table);
+	}
+
+	if (0 == result) {
+		result = atomctrl_retrieve_ac_timing(module_index,
+					reg_block, table);
+	}
+
+	return result;
+}
+
+/**
+ * Set DRAM timings based on engine clock and memory clock.
+ */
+int atomctrl_set_engine_dram_timings_rv770(
+		struct pp_hwmgr *hwmgr,
+		uint32_t engine_clock,
+		uint32_t memory_clock)
+{
+	SET_ENGINE_CLOCK_PS_ALLOCATION engine_clock_parameters;
+
+	/* They are both in 10KHz Units. */
+	engine_clock_parameters.ulTargetEngineClock =
+		(uint32_t) engine_clock & SET_CLOCK_FREQ_MASK;
+	engine_clock_parameters.ulTargetEngineClock |=
+		(COMPUTE_ENGINE_PLL_PARAM << 24);
+
+	/* in 10 khz units.*/
+	engine_clock_parameters.sReserved.ulClock =
+		(uint32_t) memory_clock & SET_CLOCK_FREQ_MASK;
+	return cgs_atom_exec_cmd_table(hwmgr->device,
+			GetIndexIntoMasterTable(COMMAND, DynamicMemorySettings),
+			&engine_clock_parameters);
+}
+
+/**
+ * Private Function to get the PowerPlay Table Address.
+ * WARNING: The tabled returned by this function is in
+ * dynamically allocated memory.
+ * The caller has to release if by calling kfree.
+ */
+static ATOM_VOLTAGE_OBJECT_INFO *get_voltage_info_table(void *device)
+{
+	int index = GetIndexIntoMasterTable(DATA, VoltageObjectInfo);
+	u8 frev, crev;
+	u16 size;
+	union voltage_object_info *voltage_info;
+
+	voltage_info = (union voltage_object_info *)
+		cgs_atom_get_data_table(device, index,
+			&size, &frev, &crev);
+
+	if (voltage_info != NULL)
+		return (ATOM_VOLTAGE_OBJECT_INFO *) &(voltage_info->v3);
+	else
+		return NULL;
+}
+
+static const ATOM_VOLTAGE_OBJECT_V3 *atomctrl_lookup_voltage_type_v3(
+		const ATOM_VOLTAGE_OBJECT_INFO_V3_1 * voltage_object_info_table,
+		uint8_t voltage_type, uint8_t voltage_mode)
+{
+	unsigned int size = le16_to_cpu(voltage_object_info_table->sHeader.usStructureSize);
+	unsigned int offset = offsetof(ATOM_VOLTAGE_OBJECT_INFO_V3_1, asVoltageObj[0]);
+	uint8_t *start = (uint8_t *)voltage_object_info_table;
+
+	while (offset < size) {
+		const ATOM_VOLTAGE_OBJECT_V3 *voltage_object =
+			(const ATOM_VOLTAGE_OBJECT_V3 *)(start + offset);
+
+		if (voltage_type == voltage_object->asGpioVoltageObj.sHeader.ucVoltageType &&
+			voltage_mode == voltage_object->asGpioVoltageObj.sHeader.ucVoltageMode)
+			return voltage_object;
+
+		offset += le16_to_cpu(voltage_object->asGpioVoltageObj.sHeader.usSize);
+	}
+
+	return NULL;
+}
+
+/** atomctrl_get_memory_pll_dividers_si().
+ *
+ * @param hwmgr                 input parameter: pointer to HwMgr
+ * @param clock_value             input parameter: memory clock
+ * @param dividers                 output parameter: memory PLL dividers
+ * @param strobe_mode            input parameter: 1 for strobe mode,  0 for performance mode
+ */
+int atomctrl_get_memory_pll_dividers_si(
+		struct pp_hwmgr *hwmgr,
+		uint32_t clock_value,
+		pp_atomctrl_memory_clock_param *mpll_param,
+		bool strobe_mode)
+{
+	COMPUTE_MEMORY_CLOCK_PARAM_PARAMETERS_V2_1 mpll_parameters;
+	int result;
+
+	mpll_parameters.ulClock = (uint32_t) clock_value;
+	mpll_parameters.ucInputFlag = (uint8_t)((strobe_mode) ? 1 : 0);
+
+	result = cgs_atom_exec_cmd_table
+		(hwmgr->device,
+		 GetIndexIntoMasterTable(COMMAND, ComputeMemoryClockParam),
+		 &mpll_parameters);
+
+	if (0 == result) {
+		mpll_param->mpll_fb_divider.clk_frac =
+			mpll_parameters.ulFbDiv.usFbDivFrac;
+		mpll_param->mpll_fb_divider.cl_kf =
+			mpll_parameters.ulFbDiv.usFbDiv;
+		mpll_param->mpll_post_divider =
+			(uint32_t)mpll_parameters.ucPostDiv;
+		mpll_param->vco_mode =
+			(uint32_t)(mpll_parameters.ucPllCntlFlag &
+					MPLL_CNTL_FLAG_VCO_MODE_MASK);
+		mpll_param->yclk_sel =
+			(uint32_t)((mpll_parameters.ucPllCntlFlag &
+						MPLL_CNTL_FLAG_BYPASS_DQ_PLL) ? 1 : 0);
+		mpll_param->qdr =
+			(uint32_t)((mpll_parameters.ucPllCntlFlag &
+						MPLL_CNTL_FLAG_QDR_ENABLE) ? 1 : 0);
+		mpll_param->half_rate =
+			(uint32_t)((mpll_parameters.ucPllCntlFlag &
+						MPLL_CNTL_FLAG_AD_HALF_RATE) ? 1 : 0);
+		mpll_param->dll_speed =
+			(uint32_t)(mpll_parameters.ucDllSpeed);
+		mpll_param->bw_ctrl =
+			(uint32_t)(mpll_parameters.ucBWCntl);
+	}
+
+	return result;
+}
+
+/** atomctrl_get_memory_pll_dividers_vi().
+ *
+ * @param hwmgr                 input parameter: pointer to HwMgr
+ * @param clock_value             input parameter: memory clock
+ * @param dividers               output parameter: memory PLL dividers
+ */
+int atomctrl_get_memory_pll_dividers_vi(struct pp_hwmgr *hwmgr,
+		uint32_t clock_value, pp_atomctrl_memory_clock_param *mpll_param)
+{
+	COMPUTE_MEMORY_CLOCK_PARAM_PARAMETERS_V2_2 mpll_parameters;
+	int result;
+
+	mpll_parameters.ulClock.ulClock = (uint32_t)clock_value;
+
+	result = cgs_atom_exec_cmd_table(hwmgr->device,
+			GetIndexIntoMasterTable(COMMAND, ComputeMemoryClockParam),
+			&mpll_parameters);
+
+	if (!result)
+		mpll_param->mpll_post_divider =
+				(uint32_t)mpll_parameters.ulClock.ucPostDiv;
+
+	return result;
+}
+
+int atomctrl_get_engine_pll_dividers_kong(struct pp_hwmgr *hwmgr,
+					  uint32_t clock_value,
+					  pp_atomctrl_clock_dividers_kong *dividers)
+{
+	COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_V4 pll_parameters;
+	int result;
+
+	pll_parameters.ulClock = clock_value;
+
+	result = cgs_atom_exec_cmd_table
+		(hwmgr->device,
+		 GetIndexIntoMasterTable(COMMAND, ComputeMemoryEnginePLL),
+		 &pll_parameters);
+
+	if (0 == result) {
+		dividers->pll_post_divider = pll_parameters.ucPostDiv;
+		dividers->real_clock = pll_parameters.ulClock;
+	}
+
+	return result;
+}
+
+int atomctrl_get_engine_pll_dividers_vi(
+		struct pp_hwmgr *hwmgr,
+		uint32_t clock_value,
+		pp_atomctrl_clock_dividers_vi *dividers)
+{
+	COMPUTE_GPU_CLOCK_OUTPUT_PARAMETERS_V1_6 pll_patameters;
+	int result;
+
+	pll_patameters.ulClock.ulClock = clock_value;
+	pll_patameters.ulClock.ucPostDiv = COMPUTE_GPUCLK_INPUT_FLAG_SCLK;
+
+	result = cgs_atom_exec_cmd_table
+		(hwmgr->device,
+		 GetIndexIntoMasterTable(COMMAND, ComputeMemoryEnginePLL),
+		 &pll_patameters);
+
+	if (0 == result) {
+		dividers->pll_post_divider =
+			pll_patameters.ulClock.ucPostDiv;
+		dividers->real_clock =
+			pll_patameters.ulClock.ulClock;
+
+		dividers->ul_fb_div.ul_fb_div_frac =
+			pll_patameters.ulFbDiv.usFbDivFrac;
+		dividers->ul_fb_div.ul_fb_div =
+			pll_patameters.ulFbDiv.usFbDiv;
+
+		dividers->uc_pll_ref_div =
+			pll_patameters.ucPllRefDiv;
+		dividers->uc_pll_post_div =
+			pll_patameters.ucPllPostDiv;
+		dividers->uc_pll_cntl_flag =
+			pll_patameters.ucPllCntlFlag;
+	}
+
+	return result;
+}
+
+int atomctrl_get_dfs_pll_dividers_vi(
+		struct pp_hwmgr *hwmgr,
+		uint32_t clock_value,
+		pp_atomctrl_clock_dividers_vi *dividers)
+{
+	COMPUTE_GPU_CLOCK_OUTPUT_PARAMETERS_V1_6 pll_patameters;
+	int result;
+
+	pll_patameters.ulClock.ulClock = clock_value;
+	pll_patameters.ulClock.ucPostDiv =
+		COMPUTE_GPUCLK_INPUT_FLAG_DEFAULT_GPUCLK;
+
+	result = cgs_atom_exec_cmd_table
+		(hwmgr->device,
+		 GetIndexIntoMasterTable(COMMAND, ComputeMemoryEnginePLL),
+		 &pll_patameters);
+
+	if (0 == result) {
+		dividers->pll_post_divider =
+			pll_patameters.ulClock.ucPostDiv;
+		dividers->real_clock =
+			pll_patameters.ulClock.ulClock;
+
+		dividers->ul_fb_div.ul_fb_div_frac =
+			pll_patameters.ulFbDiv.usFbDivFrac;
+		dividers->ul_fb_div.ul_fb_div =
+			pll_patameters.ulFbDiv.usFbDiv;
+
+		dividers->uc_pll_ref_div =
+			pll_patameters.ucPllRefDiv;
+		dividers->uc_pll_post_div =
+			pll_patameters.ucPllPostDiv;
+		dividers->uc_pll_cntl_flag =
+			pll_patameters.ucPllCntlFlag;
+	}
+
+	return result;
+}
+
+/**
+ * Get the reference clock in 10KHz
+ */
+uint32_t atomctrl_get_reference_clock(struct pp_hwmgr *hwmgr)
+{
+	ATOM_FIRMWARE_INFO *fw_info;
+	u8 frev, crev;
+	u16 size;
+	uint32_t clock;
+
+	fw_info = (ATOM_FIRMWARE_INFO *)
+		cgs_atom_get_data_table(hwmgr->device,
+			GetIndexIntoMasterTable(DATA, FirmwareInfo),
+			&size, &frev, &crev);
+
+	if (fw_info == NULL)
+		clock = 2700;
+	else
+		clock = (uint32_t)(le16_to_cpu(fw_info->usReferenceClock));
+
+	return clock;
+}
+
+/**
+ * Returns true if the given voltage type is controlled by GPIO pins.
+ * voltage_type is one of SET_VOLTAGE_TYPE_ASIC_VDDC,
+ * SET_VOLTAGE_TYPE_ASIC_MVDDC, SET_VOLTAGE_TYPE_ASIC_MVDDQ.
+ * voltage_mode is one of ATOM_SET_VOLTAGE, ATOM_SET_VOLTAGE_PHASE
+ */
+bool atomctrl_is_voltage_controled_by_gpio_v3(
+		struct pp_hwmgr *hwmgr,
+		uint8_t voltage_type,
+		uint8_t voltage_mode)
+{
+	ATOM_VOLTAGE_OBJECT_INFO_V3_1 *voltage_info =
+		(ATOM_VOLTAGE_OBJECT_INFO_V3_1 *)get_voltage_info_table(hwmgr->device);
+	bool ret;
+
+	PP_ASSERT_WITH_CODE((NULL != voltage_info),
+			"Could not find Voltage Table in BIOS.", return false;);
+
+	ret = (NULL != atomctrl_lookup_voltage_type_v3
+			(voltage_info, voltage_type, voltage_mode)) ? true : false;
+
+	return ret;
+}
+
+int atomctrl_get_voltage_table_v3(
+		struct pp_hwmgr *hwmgr,
+		uint8_t voltage_type,
+		uint8_t voltage_mode,
+		pp_atomctrl_voltage_table *voltage_table)
+{
+	ATOM_VOLTAGE_OBJECT_INFO_V3_1 *voltage_info =
+		(ATOM_VOLTAGE_OBJECT_INFO_V3_1 *)get_voltage_info_table(hwmgr->device);
+	const ATOM_VOLTAGE_OBJECT_V3 *voltage_object;
+	unsigned int i;
+
+	PP_ASSERT_WITH_CODE((NULL != voltage_info),
+			"Could not find Voltage Table in BIOS.", return -1;);
+
+	voltage_object = atomctrl_lookup_voltage_type_v3
+		(voltage_info, voltage_type, voltage_mode);
+
+	if (voltage_object == NULL)
+		return -1;
+
+	PP_ASSERT_WITH_CODE(
+			(voltage_object->asGpioVoltageObj.ucGpioEntryNum <=
+			PP_ATOMCTRL_MAX_VOLTAGE_ENTRIES),
+			"Too many voltage entries!",
+			return -1;
+			);
+
+	for (i = 0; i < voltage_object->asGpioVoltageObj.ucGpioEntryNum; i++) {
+		voltage_table->entries[i].value =
+			voltage_object->asGpioVoltageObj.asVolGpioLut[i].usVoltageValue;
+		voltage_table->entries[i].smio_low =
+			voltage_object->asGpioVoltageObj.asVolGpioLut[i].ulVoltageId;
+	}
+
+	voltage_table->mask_low    =
+		voltage_object->asGpioVoltageObj.ulGpioMaskVal;
+	voltage_table->count      =
+		voltage_object->asGpioVoltageObj.ucGpioEntryNum;
+	voltage_table->phase_delay =
+		voltage_object->asGpioVoltageObj.ucPhaseDelay;
+
+	return 0;
+}
+
+static bool atomctrl_lookup_gpio_pin(
+		ATOM_GPIO_PIN_LUT * gpio_lookup_table,
+		const uint32_t pinId,
+		pp_atomctrl_gpio_pin_assignment *gpio_pin_assignment)
+{
+	unsigned int size = le16_to_cpu(gpio_lookup_table->sHeader.usStructureSize);
+	unsigned int offset = offsetof(ATOM_GPIO_PIN_LUT, asGPIO_Pin[0]);
+	uint8_t *start = (uint8_t *)gpio_lookup_table;
+
+	while (offset < size) {
+		const ATOM_GPIO_PIN_ASSIGNMENT *pin_assignment =
+			(const ATOM_GPIO_PIN_ASSIGNMENT *)(start + offset);
+
+		if (pinId == pin_assignment->ucGPIO_ID) {
+			gpio_pin_assignment->uc_gpio_pin_bit_shift =
+				pin_assignment->ucGpioPinBitShift;
+			gpio_pin_assignment->us_gpio_pin_aindex =
+				le16_to_cpu(pin_assignment->usGpioPin_AIndex);
+			return false;
+		}
+
+		offset += offsetof(ATOM_GPIO_PIN_ASSIGNMENT, ucGPIO_ID) + 1;
+	}
+
+	return true;
+}
+
+/**
+ * Private Function to get the PowerPlay Table Address.
+ * WARNING: The tabled returned by this function is in
+ * dynamically allocated memory.
+ * The caller has to release if by calling kfree.
+ */
+static ATOM_GPIO_PIN_LUT *get_gpio_lookup_table(void *device)
+{
+	u8 frev, crev;
+	u16 size;
+	void *table_address;
+
+	table_address = (ATOM_GPIO_PIN_LUT *)
+		cgs_atom_get_data_table(device,
+				GetIndexIntoMasterTable(DATA, GPIO_Pin_LUT),
+				&size, &frev, &crev);
+
+	PP_ASSERT_WITH_CODE((NULL != table_address),
+			"Error retrieving BIOS Table Address!", return NULL;);
+
+	return (ATOM_GPIO_PIN_LUT *)table_address;
+}
+
+/**
+ * Returns 1 if the given pin id find in lookup table.
+ */
+bool atomctrl_get_pp_assign_pin(
+		struct pp_hwmgr *hwmgr,
+		const uint32_t pinId,
+		pp_atomctrl_gpio_pin_assignment *gpio_pin_assignment)
+{
+	bool bRet = 0;
+	ATOM_GPIO_PIN_LUT *gpio_lookup_table =
+		get_gpio_lookup_table(hwmgr->device);
+
+	PP_ASSERT_WITH_CODE((NULL != gpio_lookup_table),
+			"Could not find GPIO lookup Table in BIOS.", return -1);
+
+	bRet = atomctrl_lookup_gpio_pin(gpio_lookup_table, pinId,
+		gpio_pin_assignment);
+
+	return bRet;
+}
+
+int atomctrl_calculate_voltage_evv_on_sclk(
+		struct pp_hwmgr *hwmgr,
+		uint8_t voltage_type,
+		uint32_t sclk,
+		uint16_t virtual_voltage_Id,
+		uint16_t *voltage,
+		uint16_t dpm_level,
+		bool debug)
+{
+	ATOM_ASIC_PROFILING_INFO_V3_4 *getASICProfilingInfo;
+
+	EFUSE_LINEAR_FUNC_PARAM sRO_fuse;
+	EFUSE_LINEAR_FUNC_PARAM sCACm_fuse;
+	EFUSE_LINEAR_FUNC_PARAM sCACb_fuse;
+	EFUSE_LOGISTIC_FUNC_PARAM sKt_Beta_fuse;
+	EFUSE_LOGISTIC_FUNC_PARAM sKv_m_fuse;
+	EFUSE_LOGISTIC_FUNC_PARAM sKv_b_fuse;
+	EFUSE_INPUT_PARAMETER sInput_FuseValues;
+	READ_EFUSE_VALUE_PARAMETER sOutput_FuseValues;
+
+	uint32_t ul_RO_fused, ul_CACb_fused, ul_CACm_fused, ul_Kt_Beta_fused, ul_Kv_m_fused, ul_Kv_b_fused;
+	fInt fSM_A0, fSM_A1, fSM_A2, fSM_A3, fSM_A4, fSM_A5, fSM_A6, fSM_A7;
+	fInt fMargin_RO_a, fMargin_RO_b, fMargin_RO_c, fMargin_fixed, fMargin_FMAX_mean, fMargin_Plat_mean, fMargin_FMAX_sigma, fMargin_Plat_sigma, fMargin_DC_sigma;
+	fInt fLkg_FT, repeat;
+	fInt fMicro_FMAX, fMicro_CR, fSigma_FMAX, fSigma_CR, fSigma_DC, fDC_SCLK, fSquared_Sigma_DC, fSquared_Sigma_CR, fSquared_Sigma_FMAX;
+	fInt fRLL_LoadLine, fPowerDPMx, fDerateTDP, fVDDC_base, fA_Term, fC_Term, fB_Term, fRO_DC_margin;
+	fInt fRO_fused, fCACm_fused, fCACb_fused, fKv_m_fused, fKv_b_fused, fKt_Beta_fused, fFT_Lkg_V0NORM;
+	fInt fSclk_margin, fSclk, fEVV_V;
+	fInt fV_min, fV_max, fT_prod, fLKG_Factor, fT_FT, fV_FT, fV_x, fTDP_Power, fTDP_Power_right, fTDP_Power_left, fTDP_Current, fV_NL;
+	uint32_t ul_FT_Lkg_V0NORM;
+	fInt fLn_MaxDivMin, fMin, fAverage, fRange;
+	fInt fRoots[2];
+	fInt fStepSize = GetScaledFraction(625, 100000);
+
+	int result;
+
+	getASICProfilingInfo = (ATOM_ASIC_PROFILING_INFO_V3_4 *)
+			cgs_atom_get_data_table(hwmgr->device,
+					GetIndexIntoMasterTable(DATA, ASIC_ProfilingInfo),
+					NULL, NULL, NULL);
+
+	if (!getASICProfilingInfo)
+		return -1;
+
+	if(getASICProfilingInfo->asHeader.ucTableFormatRevision < 3 ||
+			(getASICProfilingInfo->asHeader.ucTableFormatRevision == 3 &&
+			getASICProfilingInfo->asHeader.ucTableContentRevision < 4))
+		return -1;
+
+	/*-----------------------------------------------------------
+	 *GETTING MULTI-STEP PARAMETERS RELATED TO CURRENT DPM LEVEL
+	 *-----------------------------------------------------------
+	 */
+	fRLL_LoadLine = Divide(getASICProfilingInfo->ulLoadLineSlop, 1000);
+
+	switch (dpm_level) {
+	case 1:
+		fPowerDPMx = Convert_ULONG_ToFraction(getASICProfilingInfo->usPowerDpm1);
+		fDerateTDP = GetScaledFraction(getASICProfilingInfo->ulTdpDerateDPM1, 1000);
+		break;
+	case 2:
+		fPowerDPMx = Convert_ULONG_ToFraction(getASICProfilingInfo->usPowerDpm2);
+		fDerateTDP = GetScaledFraction(getASICProfilingInfo->ulTdpDerateDPM2, 1000);
+		break;
+	case 3:
+		fPowerDPMx = Convert_ULONG_ToFraction(getASICProfilingInfo->usPowerDpm3);
+		fDerateTDP = GetScaledFraction(getASICProfilingInfo->ulTdpDerateDPM3, 1000);
+		break;
+	case 4:
+		fPowerDPMx = Convert_ULONG_ToFraction(getASICProfilingInfo->usPowerDpm4);
+		fDerateTDP = GetScaledFraction(getASICProfilingInfo->ulTdpDerateDPM4, 1000);
+		break;
+	case 5:
+		fPowerDPMx = Convert_ULONG_ToFraction(getASICProfilingInfo->usPowerDpm5);
+		fDerateTDP = GetScaledFraction(getASICProfilingInfo->ulTdpDerateDPM5, 1000);
+		break;
+	case 6:
+		fPowerDPMx = Convert_ULONG_ToFraction(getASICProfilingInfo->usPowerDpm6);
+		fDerateTDP = GetScaledFraction(getASICProfilingInfo->ulTdpDerateDPM6, 1000);
+		break;
+	case 7:
+		fPowerDPMx = Convert_ULONG_ToFraction(getASICProfilingInfo->usPowerDpm7);
+		fDerateTDP = GetScaledFraction(getASICProfilingInfo->ulTdpDerateDPM7, 1000);
+		break;
+	default:
+		printk(KERN_ERR "DPM Level not supported\n");
+		fPowerDPMx = Convert_ULONG_ToFraction(1);
+		fDerateTDP = GetScaledFraction(getASICProfilingInfo->ulTdpDerateDPM0, 1000);
+	}
+
+	/*-------------------------
+	 * DECODING FUSE VALUES
+	 * ------------------------
+	 */
+	/*Decode RO_Fused*/
+	sRO_fuse = getASICProfilingInfo->sRoFuse;
+
+	sInput_FuseValues.usEfuseIndex = sRO_fuse.usEfuseIndex;
+	sInput_FuseValues.ucBitShift = sRO_fuse.ucEfuseBitLSB;
+	sInput_FuseValues.ucBitLength = sRO_fuse.ucEfuseLength;
+
+	sOutput_FuseValues.sEfuse = sInput_FuseValues;
+
+	result = cgs_atom_exec_cmd_table(hwmgr->device,
+			GetIndexIntoMasterTable(COMMAND, ReadEfuseValue),
+			&sOutput_FuseValues);
+
+	if (result)
+		return result;
+
+	/* Finally, the actual fuse value */
+	ul_RO_fused = sOutput_FuseValues.ulEfuseValue;
+	fMin = GetScaledFraction(sRO_fuse.ulEfuseMin, 1);
+	fRange = GetScaledFraction(sRO_fuse.ulEfuseEncodeRange, 1);
+	fRO_fused = fDecodeLinearFuse(ul_RO_fused, fMin, fRange, sRO_fuse.ucEfuseLength);
+
+	sCACm_fuse = getASICProfilingInfo->sCACm;
+
+	sInput_FuseValues.usEfuseIndex = sCACm_fuse.usEfuseIndex;
+	sInput_FuseValues.ucBitShift = sCACm_fuse.ucEfuseBitLSB;
+	sInput_FuseValues.ucBitLength = sCACm_fuse.ucEfuseLength;
+
+	sOutput_FuseValues.sEfuse = sInput_FuseValues;
+
+	result = cgs_atom_exec_cmd_table(hwmgr->device,
+			GetIndexIntoMasterTable(COMMAND, ReadEfuseValue),
+			&sOutput_FuseValues);
+
+	if (result)
+		return result;
+
+	ul_CACm_fused = sOutput_FuseValues.ulEfuseValue;
+	fMin = GetScaledFraction(sCACm_fuse.ulEfuseMin, 1000);
+	fRange = GetScaledFraction(sCACm_fuse.ulEfuseEncodeRange, 1000);
+
+	fCACm_fused = fDecodeLinearFuse(ul_CACm_fused, fMin, fRange, sCACm_fuse.ucEfuseLength);
+
+	sCACb_fuse = getASICProfilingInfo->sCACb;
+
+	sInput_FuseValues.usEfuseIndex = sCACb_fuse.usEfuseIndex;
+	sInput_FuseValues.ucBitShift = sCACb_fuse.ucEfuseBitLSB;
+	sInput_FuseValues.ucBitLength = sCACb_fuse.ucEfuseLength;
+	sOutput_FuseValues.sEfuse = sInput_FuseValues;
+
+	result = cgs_atom_exec_cmd_table(hwmgr->device,
+			GetIndexIntoMasterTable(COMMAND, ReadEfuseValue),
+			&sOutput_FuseValues);
+
+	if (result)
+		return result;
+
+	ul_CACb_fused = sOutput_FuseValues.ulEfuseValue;
+	fMin = GetScaledFraction(sCACb_fuse.ulEfuseMin, 1000);
+	fRange = GetScaledFraction(sCACb_fuse.ulEfuseEncodeRange, 1000);
+
+	fCACb_fused = fDecodeLinearFuse(ul_CACb_fused, fMin, fRange, sCACb_fuse.ucEfuseLength);
+
+	sKt_Beta_fuse = getASICProfilingInfo->sKt_b;
+
+	sInput_FuseValues.usEfuseIndex = sKt_Beta_fuse.usEfuseIndex;
+	sInput_FuseValues.ucBitShift = sKt_Beta_fuse.ucEfuseBitLSB;
+	sInput_FuseValues.ucBitLength = sKt_Beta_fuse.ucEfuseLength;
+
+	sOutput_FuseValues.sEfuse = sInput_FuseValues;
+
+	result = cgs_atom_exec_cmd_table(hwmgr->device,
+			GetIndexIntoMasterTable(COMMAND, ReadEfuseValue),
+			&sOutput_FuseValues);
+
+	if (result)
+		return result;
+
+	ul_Kt_Beta_fused = sOutput_FuseValues.ulEfuseValue;
+	fAverage = GetScaledFraction(sKt_Beta_fuse.ulEfuseEncodeAverage, 1000);
+	fRange = GetScaledFraction(sKt_Beta_fuse.ulEfuseEncodeRange, 1000);
+
+	fKt_Beta_fused = fDecodeLogisticFuse(ul_Kt_Beta_fused,
+			fAverage, fRange, sKt_Beta_fuse.ucEfuseLength);
+
+	sKv_m_fuse = getASICProfilingInfo->sKv_m;
+
+	sInput_FuseValues.usEfuseIndex = sKv_m_fuse.usEfuseIndex;
+	sInput_FuseValues.ucBitShift = sKv_m_fuse.ucEfuseBitLSB;
+	sInput_FuseValues.ucBitLength = sKv_m_fuse.ucEfuseLength;
+
+	sOutput_FuseValues.sEfuse = sInput_FuseValues;
+
+	result = cgs_atom_exec_cmd_table(hwmgr->device,
+			GetIndexIntoMasterTable(COMMAND, ReadEfuseValue),
+			&sOutput_FuseValues);
+	if (result)
+		return result;
+
+	ul_Kv_m_fused = sOutput_FuseValues.ulEfuseValue;
+	fAverage = GetScaledFraction(sKv_m_fuse.ulEfuseEncodeAverage, 1000);
+	fRange = GetScaledFraction((sKv_m_fuse.ulEfuseEncodeRange & 0x7fffffff), 1000);
+	fRange = fMultiply(fRange, ConvertToFraction(-1));
+
+	fKv_m_fused = fDecodeLogisticFuse(ul_Kv_m_fused,
+			fAverage, fRange, sKv_m_fuse.ucEfuseLength);
+
+	sKv_b_fuse = getASICProfilingInfo->sKv_b;
+
+	sInput_FuseValues.usEfuseIndex = sKv_b_fuse.usEfuseIndex;
+	sInput_FuseValues.ucBitShift = sKv_b_fuse.ucEfuseBitLSB;
+	sInput_FuseValues.ucBitLength = sKv_b_fuse.ucEfuseLength;
+	sOutput_FuseValues.sEfuse = sInput_FuseValues;
+
+	result = cgs_atom_exec_cmd_table(hwmgr->device,
+			GetIndexIntoMasterTable(COMMAND, ReadEfuseValue),
+			&sOutput_FuseValues);
+
+	if (result)
+		return result;
+
+	ul_Kv_b_fused = sOutput_FuseValues.ulEfuseValue;
+	fAverage = GetScaledFraction(sKv_b_fuse.ulEfuseEncodeAverage, 1000);
+	fRange = GetScaledFraction(sKv_b_fuse.ulEfuseEncodeRange, 1000);
+
+	fKv_b_fused = fDecodeLogisticFuse(ul_Kv_b_fused,
+			fAverage, fRange, sKv_b_fuse.ucEfuseLength);
+
+	/* Decoding the Leakage - No special struct container */
+	/*
+	 * usLkgEuseIndex=56
+	 * ucLkgEfuseBitLSB=6
+	 * ucLkgEfuseLength=10
+	 * ulLkgEncodeLn_MaxDivMin=69077
+	 * ulLkgEncodeMax=1000000
+	 * ulLkgEncodeMin=1000
+	 * ulEfuseLogisticAlpha=13
+	 */
+
+	sInput_FuseValues.usEfuseIndex = getASICProfilingInfo->usLkgEuseIndex;
+	sInput_FuseValues.ucBitShift = getASICProfilingInfo->ucLkgEfuseBitLSB;
+	sInput_FuseValues.ucBitLength = getASICProfilingInfo->ucLkgEfuseLength;
+
+	sOutput_FuseValues.sEfuse = sInput_FuseValues;
+
+	result = cgs_atom_exec_cmd_table(hwmgr->device,
+			GetIndexIntoMasterTable(COMMAND, ReadEfuseValue),
+			&sOutput_FuseValues);
+
+	if (result)
+		return result;
+
+	ul_FT_Lkg_V0NORM = sOutput_FuseValues.ulEfuseValue;
+	fLn_MaxDivMin = GetScaledFraction(getASICProfilingInfo->ulLkgEncodeLn_MaxDivMin, 10000);
+	fMin = GetScaledFraction(getASICProfilingInfo->ulLkgEncodeMin, 10000);
+
+	fFT_Lkg_V0NORM = fDecodeLeakageID(ul_FT_Lkg_V0NORM,
+			fLn_MaxDivMin, fMin, getASICProfilingInfo->ucLkgEfuseLength);
+	fLkg_FT = fFT_Lkg_V0NORM;
+
+	/*-------------------------------------------
+	 * PART 2 - Grabbing all required values
+	 *-------------------------------------------
+	 */
+	fSM_A0 = fMultiply(GetScaledFraction(getASICProfilingInfo->ulSM_A0, 1000000),
+			ConvertToFraction(uPow(-1, getASICProfilingInfo->ucSM_A0_sign)));
+	fSM_A1 = fMultiply(GetScaledFraction(getASICProfilingInfo->ulSM_A1, 1000000),
+			ConvertToFraction(uPow(-1, getASICProfilingInfo->ucSM_A1_sign)));
+	fSM_A2 = fMultiply(GetScaledFraction(getASICProfilingInfo->ulSM_A2, 100000),
+			ConvertToFraction(uPow(-1, getASICProfilingInfo->ucSM_A2_sign)));
+	fSM_A3 = fMultiply(GetScaledFraction(getASICProfilingInfo->ulSM_A3, 1000000),
+			ConvertToFraction(uPow(-1, getASICProfilingInfo->ucSM_A3_sign)));
+	fSM_A4 = fMultiply(GetScaledFraction(getASICProfilingInfo->ulSM_A4, 1000000),
+			ConvertToFraction(uPow(-1, getASICProfilingInfo->ucSM_A4_sign)));
+	fSM_A5 = fMultiply(GetScaledFraction(getASICProfilingInfo->ulSM_A5, 1000),
+			ConvertToFraction(uPow(-1, getASICProfilingInfo->ucSM_A5_sign)));
+	fSM_A6 = fMultiply(GetScaledFraction(getASICProfilingInfo->ulSM_A6, 1000),
+			ConvertToFraction(uPow(-1, getASICProfilingInfo->ucSM_A6_sign)));
+	fSM_A7 = fMultiply(GetScaledFraction(getASICProfilingInfo->ulSM_A7, 1000),
+			ConvertToFraction(uPow(-1, getASICProfilingInfo->ucSM_A7_sign)));
+
+	fMargin_RO_a = ConvertToFraction(getASICProfilingInfo->ulMargin_RO_a);
+	fMargin_RO_b = ConvertToFraction(getASICProfilingInfo->ulMargin_RO_b);
+	fMargin_RO_c = ConvertToFraction(getASICProfilingInfo->ulMargin_RO_c);
+
+	fMargin_fixed = ConvertToFraction(getASICProfilingInfo->ulMargin_fixed);
+
+	fMargin_FMAX_mean = GetScaledFraction(
+			getASICProfilingInfo->ulMargin_Fmax_mean, 10000);
+	fMargin_Plat_mean = GetScaledFraction(
+			getASICProfilingInfo->ulMargin_plat_mean, 10000);
+	fMargin_FMAX_sigma = GetScaledFraction(
+			getASICProfilingInfo->ulMargin_Fmax_sigma, 10000);
+	fMargin_Plat_sigma = GetScaledFraction(
+			getASICProfilingInfo->ulMargin_plat_sigma, 10000);
+
+	fMargin_DC_sigma = GetScaledFraction(
+			getASICProfilingInfo->ulMargin_DC_sigma, 100);
+	fMargin_DC_sigma = fDivide(fMargin_DC_sigma, ConvertToFraction(1000));
+
+	fCACm_fused = fDivide(fCACm_fused, ConvertToFraction(100));
+	fCACb_fused = fDivide(fCACb_fused, ConvertToFraction(100));
+	fKt_Beta_fused = fDivide(fKt_Beta_fused, ConvertToFraction(100));
+	fKv_m_fused =  fNegate(fDivide(fKv_m_fused, ConvertToFraction(100)));
+	fKv_b_fused = fDivide(fKv_b_fused, ConvertToFraction(10));
+
+	fSclk = GetScaledFraction(sclk, 100);
+
+	fV_max = fDivide(GetScaledFraction(
+			getASICProfilingInfo->ulMaxVddc, 1000), ConvertToFraction(4));
+	fT_prod = GetScaledFraction(getASICProfilingInfo->ulBoardCoreTemp, 10);
+	fLKG_Factor = GetScaledFraction(getASICProfilingInfo->ulEvvLkgFactor, 100);
+	fT_FT = GetScaledFraction(getASICProfilingInfo->ulLeakageTemp, 10);
+	fV_FT = fDivide(GetScaledFraction(
+			getASICProfilingInfo->ulLeakageVoltage, 1000), ConvertToFraction(4));
+	fV_min = fDivide(GetScaledFraction(
+			getASICProfilingInfo->ulMinVddc, 1000), ConvertToFraction(4));
+
+	/*-----------------------
+	 * PART 3
+	 *-----------------------
+	 */
+
+	fA_Term = fAdd(fMargin_RO_a, fAdd(fMultiply(fSM_A4,fSclk), fSM_A5));
+	fB_Term = fAdd(fAdd(fMultiply(fSM_A2, fSclk), fSM_A6), fMargin_RO_b);
+	fC_Term = fAdd(fMargin_RO_c,
+			fAdd(fMultiply(fSM_A0,fLkg_FT),
+			fAdd(fMultiply(fSM_A1, fMultiply(fLkg_FT,fSclk)),
+			fAdd(fMultiply(fSM_A3, fSclk),
+			fSubtract(fSM_A7,fRO_fused)))));
+
+	fVDDC_base = fSubtract(fRO_fused,
+			fSubtract(fMargin_RO_c,
+					fSubtract(fSM_A3, fMultiply(fSM_A1, fSclk))));
+	fVDDC_base = fDivide(fVDDC_base, fAdd(fMultiply(fSM_A0,fSclk), fSM_A2));
+
+	repeat = fSubtract(fVDDC_base,
+			fDivide(fMargin_DC_sigma, ConvertToFraction(1000)));
+
+	fRO_DC_margin = fAdd(fMultiply(fMargin_RO_a,
+			fGetSquare(repeat)),
+			fAdd(fMultiply(fMargin_RO_b, repeat),
+			fMargin_RO_c));
+
+	fDC_SCLK = fSubtract(fRO_fused,
+			fSubtract(fRO_DC_margin,
+			fSubtract(fSM_A3,
+			fMultiply(fSM_A2, repeat))));
+	fDC_SCLK = fDivide(fDC_SCLK, fAdd(fMultiply(fSM_A0,repeat), fSM_A1));
+
+	fSigma_DC = fSubtract(fSclk, fDC_SCLK);
+
+	fMicro_FMAX = fMultiply(fSclk, fMargin_FMAX_mean);
+	fMicro_CR = fMultiply(fSclk, fMargin_Plat_mean);
+	fSigma_FMAX = fMultiply(fSclk, fMargin_FMAX_sigma);
+	fSigma_CR = fMultiply(fSclk, fMargin_Plat_sigma);
+
+	fSquared_Sigma_DC = fGetSquare(fSigma_DC);
+	fSquared_Sigma_CR = fGetSquare(fSigma_CR);
+	fSquared_Sigma_FMAX = fGetSquare(fSigma_FMAX);
+
+	fSclk_margin = fAdd(fMicro_FMAX,
+			fAdd(fMicro_CR,
+			fAdd(fMargin_fixed,
+			fSqrt(fAdd(fSquared_Sigma_FMAX,
+			fAdd(fSquared_Sigma_DC, fSquared_Sigma_CR))))));
+	/*
+	 fA_Term = fSM_A4 * (fSclk + fSclk_margin) + fSM_A5;
+	 fB_Term = fSM_A2 * (fSclk + fSclk_margin) + fSM_A6;
+	 fC_Term = fRO_DC_margin + fSM_A0 * fLkg_FT + fSM_A1 * fLkg_FT * (fSclk + fSclk_margin) + fSM_A3 * (fSclk + fSclk_margin) + fSM_A7 - fRO_fused;
+	 */
+
+	fA_Term = fAdd(fMultiply(fSM_A4, fAdd(fSclk, fSclk_margin)), fSM_A5);
+	fB_Term = fAdd(fMultiply(fSM_A2, fAdd(fSclk, fSclk_margin)), fSM_A6);
+	fC_Term = fAdd(fRO_DC_margin,
+			fAdd(fMultiply(fSM_A0, fLkg_FT),
+			fAdd(fMultiply(fMultiply(fSM_A1, fLkg_FT),
+			fAdd(fSclk, fSclk_margin)),
+			fAdd(fMultiply(fSM_A3,
+			fAdd(fSclk, fSclk_margin)),
+			fSubtract(fSM_A7, fRO_fused)))));
+
+	SolveQuadracticEqn(fA_Term, fB_Term, fC_Term, fRoots);
+
+	if (GreaterThan(fRoots[0], fRoots[1]))
+		fEVV_V = fRoots[1];
+	else
+		fEVV_V = fRoots[0];
+
+	if (GreaterThan(fV_min, fEVV_V))
+		fEVV_V = fV_min;
+	else if (GreaterThan(fEVV_V, fV_max))
+		fEVV_V = fSubtract(fV_max, fStepSize);
+
+	fEVV_V = fRoundUpByStepSize(fEVV_V, fStepSize, 0);
+
+	/*-----------------
+	 * PART 4
+	 *-----------------
+	 */
+
+	fV_x = fV_min;
+
+	while (GreaterThan(fAdd(fV_max, fStepSize), fV_x)) {
+		fTDP_Power_left = fMultiply(fMultiply(fMultiply(fAdd(
+				fMultiply(fCACm_fused, fV_x), fCACb_fused), fSclk),
+				fGetSquare(fV_x)), fDerateTDP);
+
+		fTDP_Power_right = fMultiply(fFT_Lkg_V0NORM, fMultiply(fLKG_Factor,
+				fMultiply(fExponential(fMultiply(fAdd(fMultiply(fKv_m_fused,
+				fT_prod), fKv_b_fused), fV_x)), fV_x)));
+		fTDP_Power_right = fMultiply(fTDP_Power_right, fExponential(fMultiply(
+				fKt_Beta_fused, fT_prod)));
+		fTDP_Power_right = fDivide(fTDP_Power_right, fExponential(fMultiply(
+				fAdd(fMultiply(fKv_m_fused, fT_prod), fKv_b_fused), fV_FT)));
+		fTDP_Power_right = fDivide(fTDP_Power_right, fExponential(fMultiply(
+				fKt_Beta_fused, fT_FT)));
+
+		fTDP_Power = fAdd(fTDP_Power_left, fTDP_Power_right);
+
+		fTDP_Current = fDivide(fTDP_Power, fV_x);
+
+		fV_NL = fAdd(fV_x, fDivide(fMultiply(fTDP_Current, fRLL_LoadLine),
+				ConvertToFraction(10)));
+
+		fV_NL = fRoundUpByStepSize(fV_NL, fStepSize, 0);
+
+		if (GreaterThan(fV_max, fV_NL) &&
+			(GreaterThan(fV_NL,fEVV_V) ||
+			Equal(fV_NL, fEVV_V))) {
+			fV_NL = fMultiply(fV_NL, ConvertToFraction(1000));
+
+			*voltage = (uint16_t)fV_NL.partial.real;
+			break;
+		} else
+			fV_x = fAdd(fV_x, fStepSize);
+	}
+
+	return result;
+}
+
+/** atomctrl_get_voltage_evv_on_sclk gets voltage via call to ATOM COMMAND table.
+ * @param hwmgr               	input: pointer to hwManager
+ * @param voltage_type            input: type of EVV voltage VDDC or VDDGFX
+ * @param sclk                        input: in 10Khz unit. DPM state SCLK frequency
+ *                                   		which is define in PPTable SCLK/VDDC dependence
+ *				table associated with this virtual_voltage_Id
+ * @param virtual_voltage_Id      input: voltage id which match per voltage DPM state: 0xff01, 0xff02.. 0xff08
+ * @param voltage		       output: real voltage level in unit of mv
+ */
+int atomctrl_get_voltage_evv_on_sclk(
+		struct pp_hwmgr *hwmgr,
+		uint8_t voltage_type,
+		uint32_t sclk, uint16_t virtual_voltage_Id,
+		uint16_t *voltage)
+{
+	int result;
+	GET_VOLTAGE_INFO_INPUT_PARAMETER_V1_2 get_voltage_info_param_space;
+
+	get_voltage_info_param_space.ucVoltageType   =
+		voltage_type;
+	get_voltage_info_param_space.ucVoltageMode   =
+		ATOM_GET_VOLTAGE_EVV_VOLTAGE;
+	get_voltage_info_param_space.usVoltageLevel  =
+		virtual_voltage_Id;
+	get_voltage_info_param_space.ulSCLKFreq      =
+		sclk;
+
+	result = cgs_atom_exec_cmd_table(hwmgr->device,
+			GetIndexIntoMasterTable(COMMAND, GetVoltageInfo),
+			&get_voltage_info_param_space);
+
+	if (0 != result)
+		return result;
+
+	*voltage = ((GET_EVV_VOLTAGE_INFO_OUTPUT_PARAMETER_V1_2 *)
+			(&get_voltage_info_param_space))->usVoltageLevel;
+
+	return result;
+}
+
+/**
+ * Get the mpll reference clock in 10KHz
+ */
+uint32_t atomctrl_get_mpll_reference_clock(struct pp_hwmgr *hwmgr)
+{
+	ATOM_COMMON_TABLE_HEADER *fw_info;
+	uint32_t clock;
+	u8 frev, crev;
+	u16 size;
+
+	fw_info = (ATOM_COMMON_TABLE_HEADER *)
+		cgs_atom_get_data_table(hwmgr->device,
+				GetIndexIntoMasterTable(DATA, FirmwareInfo),
+				&size, &frev, &crev);
+
+	if (fw_info == NULL)
+		clock = 2700;
+	else {
+		if ((fw_info->ucTableFormatRevision == 2) &&
+			(le16_to_cpu(fw_info->usStructureSize) >= sizeof(ATOM_FIRMWARE_INFO_V2_1))) {
+			ATOM_FIRMWARE_INFO_V2_1 *fwInfo_2_1 =
+				(ATOM_FIRMWARE_INFO_V2_1 *)fw_info;
+			clock = (uint32_t)(le16_to_cpu(fwInfo_2_1->usMemoryReferenceClock));
+		} else {
+			ATOM_FIRMWARE_INFO *fwInfo_0_0 =
+				(ATOM_FIRMWARE_INFO *)fw_info;
+			clock = (uint32_t)(le16_to_cpu(fwInfo_0_0->usReferenceClock));
+		}
+	}
+
+	return clock;
+}
+
+/**
+ * Get the asic internal spread spectrum table
+ */
+static ATOM_ASIC_INTERNAL_SS_INFO *asic_internal_ss_get_ss_table(void *device)
+{
+	ATOM_ASIC_INTERNAL_SS_INFO *table = NULL;
+	u8 frev, crev;
+	u16 size;
+
+	table = (ATOM_ASIC_INTERNAL_SS_INFO *)
+		cgs_atom_get_data_table(device,
+			GetIndexIntoMasterTable(DATA, ASIC_InternalSS_Info),
+			&size, &frev, &crev);
+
+	return table;
+}
+
+/**
+ * Get the asic internal spread spectrum assignment
+ */
+static int asic_internal_ss_get_ss_asignment(struct pp_hwmgr *hwmgr,
+		const uint8_t clockSource,
+		const uint32_t clockSpeed,
+		pp_atomctrl_internal_ss_info *ssEntry)
+{
+	ATOM_ASIC_INTERNAL_SS_INFO *table;
+	ATOM_ASIC_SS_ASSIGNMENT *ssInfo;
+	int entry_found = 0;
+
+	memset(ssEntry, 0x00, sizeof(pp_atomctrl_internal_ss_info));
+
+	table = asic_internal_ss_get_ss_table(hwmgr->device);
+
+	if (NULL == table)
+		return -1;
+
+	ssInfo = &table->asSpreadSpectrum[0];
+
+	while (((uint8_t *)ssInfo - (uint8_t *)table) <
+		le16_to_cpu(table->sHeader.usStructureSize)) {
+		if ((clockSource == ssInfo->ucClockIndication) &&
+			((uint32_t)clockSpeed <= le32_to_cpu(ssInfo->ulTargetClockRange))) {
+			entry_found = 1;
+			break;
+		}
+
+		ssInfo = (ATOM_ASIC_SS_ASSIGNMENT *)((uint8_t *)ssInfo +
+				sizeof(ATOM_ASIC_SS_ASSIGNMENT));
+	}
+
+	if (entry_found) {
+		ssEntry->speed_spectrum_percentage =
+			ssInfo->usSpreadSpectrumPercentage;
+		ssEntry->speed_spectrum_rate = ssInfo->usSpreadRateInKhz;
+
+		if (((GET_DATA_TABLE_MAJOR_REVISION(table) == 2) &&
+			(GET_DATA_TABLE_MINOR_REVISION(table) >= 2)) ||
+			(GET_DATA_TABLE_MAJOR_REVISION(table) == 3)) {
+			ssEntry->speed_spectrum_rate /= 100;
+		}
+
+		switch (ssInfo->ucSpreadSpectrumMode) {
+		case 0:
+			ssEntry->speed_spectrum_mode =
+				pp_atomctrl_spread_spectrum_mode_down;
+			break;
+		case 1:
+			ssEntry->speed_spectrum_mode =
+				pp_atomctrl_spread_spectrum_mode_center;
+			break;
+		default:
+			ssEntry->speed_spectrum_mode =
+				pp_atomctrl_spread_spectrum_mode_down;
+			break;
+		}
+	}
+
+	return entry_found ? 0 : 1;
+}
+
+/**
+ * Get the memory clock spread spectrum info
+ */
+int atomctrl_get_memory_clock_spread_spectrum(
+		struct pp_hwmgr *hwmgr,
+		const uint32_t memory_clock,
+		pp_atomctrl_internal_ss_info *ssInfo)
+{
+	return asic_internal_ss_get_ss_asignment(hwmgr,
+			ASIC_INTERNAL_MEMORY_SS, memory_clock, ssInfo);
+}
+/**
+ * Get the engine clock spread spectrum info
+ */
+int atomctrl_get_engine_clock_spread_spectrum(
+		struct pp_hwmgr *hwmgr,
+		const uint32_t engine_clock,
+		pp_atomctrl_internal_ss_info *ssInfo)
+{
+	return asic_internal_ss_get_ss_asignment(hwmgr,
+			ASIC_INTERNAL_ENGINE_SS, engine_clock, ssInfo);
+}
+
+int atomctrl_read_efuse(void *device, uint16_t start_index,
+		uint16_t end_index, uint32_t mask, uint32_t *efuse)
+{
+	int result;
+	READ_EFUSE_VALUE_PARAMETER efuse_param;
+
+	efuse_param.sEfuse.usEfuseIndex = (start_index / 32) * 4;
+	efuse_param.sEfuse.ucBitShift = (uint8_t)
+			(start_index - ((start_index / 32) * 32));
+	efuse_param.sEfuse.ucBitLength  = (uint8_t)
+			((end_index - start_index) + 1);
+
+	result = cgs_atom_exec_cmd_table(device,
+			GetIndexIntoMasterTable(COMMAND, ReadEfuseValue),
+			&efuse_param);
+	if (!result)
+		*efuse = efuse_param.ulEfuseValue & mask;
+
+	return result;
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/powerplay/hwmgr/ppatomctrl.h
@@ -0,0 +1,246 @@
+/*
+ * Copyright 2015 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#ifndef PP_ATOMVOLTAGECTRL_H
+#define PP_ATOMVOLTAGECTRL_H
+
+#include "hwmgr.h"
+
+#define MEM_TYPE_GDDR5  0x50
+#define MEM_TYPE_GDDR4  0x40
+#define MEM_TYPE_GDDR3  0x30
+#define MEM_TYPE_DDR2   0x20
+#define MEM_TYPE_GDDR1  0x10
+#define MEM_TYPE_DDR3   0xb0
+#define MEM_TYPE_MASK   0xF0
+
+
+/* As returned from PowerConnectorDetectionTable. */
+#define PP_ATOM_POWER_BUDGET_DISABLE_OVERDRIVE  0x80
+#define PP_ATOM_POWER_BUDGET_SHOW_WARNING       0x40
+#define PP_ATOM_POWER_BUDGET_SHOW_WAIVER        0x20
+#define PP_ATOM_POWER_POWER_BUDGET_BEHAVIOUR    0x0F
+
+/* New functions for Evergreen and beyond. */
+#define PP_ATOMCTRL_MAX_VOLTAGE_ENTRIES 32
+
+struct pp_atomctrl_clock_dividers {
+	uint32_t pll_post_divider;
+	uint32_t pll_feedback_divider;
+	uint32_t pll_ref_divider;
+	bool  enable_post_divider;
+};
+
+typedef struct pp_atomctrl_clock_dividers pp_atomctrl_clock_dividers;
+
+union pp_atomctrl_tcipll_fb_divider {
+	struct {
+		uint32_t ul_fb_div_frac : 14;
+		uint32_t ul_fb_div : 12;
+		uint32_t un_used : 6;
+	};
+	uint32_t ul_fb_divider;
+};
+
+typedef union pp_atomctrl_tcipll_fb_divider pp_atomctrl_tcipll_fb_divider;
+
+struct pp_atomctrl_clock_dividers_rv730 {
+	uint32_t pll_post_divider;
+	pp_atomctrl_tcipll_fb_divider mpll_feedback_divider;
+	uint32_t pll_ref_divider;
+	bool  enable_post_divider;
+	bool  enable_dithen;
+	uint32_t vco_mode;
+};
+typedef struct pp_atomctrl_clock_dividers_rv730 pp_atomctrl_clock_dividers_rv730;
+
+
+struct pp_atomctrl_clock_dividers_kong {
+	uint32_t    pll_post_divider;
+	uint32_t    real_clock;
+};
+typedef struct pp_atomctrl_clock_dividers_kong pp_atomctrl_clock_dividers_kong;
+
+struct pp_atomctrl_clock_dividers_ci {
+	uint32_t    pll_post_divider;               /* post divider value */
+	uint32_t    real_clock;
+	pp_atomctrl_tcipll_fb_divider   ul_fb_div;         /* Output Parameter: PLL FB divider */
+	uint8_t   uc_pll_ref_div;                      /* Output Parameter: PLL ref divider */
+	uint8_t   uc_pll_post_div;                      /* Output Parameter: PLL post divider */
+	uint8_t   uc_pll_cntl_flag;                    /*Output Flags: control flag */
+};
+typedef struct pp_atomctrl_clock_dividers_ci pp_atomctrl_clock_dividers_ci;
+
+struct pp_atomctrl_clock_dividers_vi {
+	uint32_t    pll_post_divider;               /* post divider value */
+	uint32_t    real_clock;
+	pp_atomctrl_tcipll_fb_divider   ul_fb_div;         /*Output Parameter: PLL FB divider */
+	uint8_t   uc_pll_ref_div;                      /*Output Parameter: PLL ref divider */
+	uint8_t   uc_pll_post_div;                     /*Output Parameter: PLL post divider */
+	uint8_t   uc_pll_cntl_flag;                    /*Output Flags: control flag */
+};
+typedef struct pp_atomctrl_clock_dividers_vi pp_atomctrl_clock_dividers_vi;
+
+union pp_atomctrl_s_mpll_fb_divider {
+	struct {
+		uint32_t cl_kf : 12;
+		uint32_t clk_frac : 12;
+		uint32_t un_used : 8;
+	};
+	uint32_t ul_fb_divider;
+};
+typedef union pp_atomctrl_s_mpll_fb_divider pp_atomctrl_s_mpll_fb_divider;
+
+enum pp_atomctrl_spread_spectrum_mode {
+	pp_atomctrl_spread_spectrum_mode_down = 0,
+	pp_atomctrl_spread_spectrum_mode_center
+};
+typedef enum pp_atomctrl_spread_spectrum_mode pp_atomctrl_spread_spectrum_mode;
+
+struct pp_atomctrl_memory_clock_param {
+	pp_atomctrl_s_mpll_fb_divider mpll_fb_divider;
+	uint32_t mpll_post_divider;
+	uint32_t bw_ctrl;
+	uint32_t dll_speed;
+	uint32_t vco_mode;
+	uint32_t yclk_sel;
+	uint32_t qdr;
+	uint32_t half_rate;
+};
+typedef struct pp_atomctrl_memory_clock_param pp_atomctrl_memory_clock_param;
+
+struct pp_atomctrl_internal_ss_info {
+	uint32_t speed_spectrum_percentage;                      /* in 1/100 percentage */
+	uint32_t speed_spectrum_rate;                            /* in KHz */
+	pp_atomctrl_spread_spectrum_mode speed_spectrum_mode;
+};
+typedef struct pp_atomctrl_internal_ss_info pp_atomctrl_internal_ss_info;
+
+#ifndef NUMBER_OF_M3ARB_PARAMS
+#define NUMBER_OF_M3ARB_PARAMS 3
+#endif
+
+#ifndef NUMBER_OF_M3ARB_PARAM_SETS
+#define NUMBER_OF_M3ARB_PARAM_SETS 10
+#endif
+
+struct pp_atomctrl_kong_system_info {
+	uint32_t			ul_bootup_uma_clock;          /* in 10kHz unit */
+	uint16_t			us_max_nb_voltage;            /* high NB voltage, calculated using current VDDNB (D24F2xDC) and VDDNB offset fuse; */
+	uint16_t			us_min_nb_voltage;            /* low NB voltage, calculated using current VDDNB (D24F2xDC) and VDDNB offset fuse; */
+	uint16_t			us_bootup_nb_voltage;         /* boot up NB voltage */
+	uint8_t			uc_htc_tmp_lmt;               /* bit [22:16] of D24F3x64 Hardware Thermal Control (HTC) Register, may not be needed, TBD */
+	uint8_t			uc_tj_offset;                /* bit [28:22] of D24F3xE4 Thermtrip Status Register,may not be needed, TBD */
+	/* 0: default 1: uvd 2: fs-3d */
+	uint32_t          ul_csr_m3_srb_cntl[NUMBER_OF_M3ARB_PARAM_SETS][NUMBER_OF_M3ARB_PARAMS];/* arrays with values for CSR M3 arbiter for default */
+};
+typedef struct pp_atomctrl_kong_system_info pp_atomctrl_kong_system_info;
+
+struct pp_atomctrl_memory_info {
+	uint8_t memory_vendor;
+	uint8_t memory_type;
+};
+typedef struct pp_atomctrl_memory_info pp_atomctrl_memory_info;
+
+#define MAX_AC_TIMING_ENTRIES 16
+
+struct pp_atomctrl_memory_clock_range_table {
+	uint8_t   num_entries;
+	uint8_t   rsv[3];
+
+	uint32_t mclk[MAX_AC_TIMING_ENTRIES];
+};
+typedef struct pp_atomctrl_memory_clock_range_table pp_atomctrl_memory_clock_range_table;
+
+struct pp_atomctrl_voltage_table_entry {
+	uint16_t value;
+	uint32_t smio_low;
+};
+
+typedef struct pp_atomctrl_voltage_table_entry pp_atomctrl_voltage_table_entry;
+
+struct pp_atomctrl_voltage_table {
+	uint32_t count;
+	uint32_t mask_low;
+	uint32_t phase_delay;   /* Used for ATOM_GPIO_VOLTAGE_OBJECT_V3 and later */
+	pp_atomctrl_voltage_table_entry entries[PP_ATOMCTRL_MAX_VOLTAGE_ENTRIES];
+};
+
+typedef struct pp_atomctrl_voltage_table pp_atomctrl_voltage_table;
+
+#define VBIOS_MC_REGISTER_ARRAY_SIZE           32
+#define VBIOS_MAX_AC_TIMING_ENTRIES            20
+
+struct pp_atomctrl_mc_reg_entry {
+	uint32_t           mclk_max;
+	uint32_t mc_data[VBIOS_MC_REGISTER_ARRAY_SIZE];
+};
+typedef struct pp_atomctrl_mc_reg_entry pp_atomctrl_mc_reg_entry;
+
+struct pp_atomctrl_mc_register_address {
+	uint16_t s1;
+	uint8_t  uc_pre_reg_data;
+};
+
+typedef struct pp_atomctrl_mc_register_address pp_atomctrl_mc_register_address;
+
+struct pp_atomctrl_mc_reg_table {
+	uint8_t                         last;                    /* number of registers */
+	uint8_t                         num_entries;             /* number of AC timing entries */
+	pp_atomctrl_mc_reg_entry        mc_reg_table_entry[VBIOS_MAX_AC_TIMING_ENTRIES];
+	pp_atomctrl_mc_register_address mc_reg_address[VBIOS_MC_REGISTER_ARRAY_SIZE];
+};
+typedef struct pp_atomctrl_mc_reg_table pp_atomctrl_mc_reg_table;
+
+struct pp_atomctrl_gpio_pin_assignment {
+	uint16_t                   us_gpio_pin_aindex;
+	uint8_t                    uc_gpio_pin_bit_shift;
+};
+typedef struct pp_atomctrl_gpio_pin_assignment pp_atomctrl_gpio_pin_assignment;
+
+extern bool atomctrl_get_pp_assign_pin(struct pp_hwmgr *hwmgr, const uint32_t pinId, pp_atomctrl_gpio_pin_assignment *gpio_pin_assignment);
+extern int atomctrl_get_voltage_evv_on_sclk(struct pp_hwmgr *hwmgr, uint8_t voltage_type, uint32_t sclk, uint16_t virtual_voltage_Id, uint16_t *voltage);
+extern uint32_t atomctrl_get_mpll_reference_clock(struct pp_hwmgr *hwmgr);
+extern int atomctrl_get_memory_clock_spread_spectrum(struct pp_hwmgr *hwmgr, const uint32_t memory_clock, pp_atomctrl_internal_ss_info *ssInfo);
+extern int atomctrl_get_engine_clock_spread_spectrum(struct pp_hwmgr *hwmgr, const uint32_t engine_clock, pp_atomctrl_internal_ss_info *ssInfo);
+extern int atomctrl_initialize_mc_reg_table(struct pp_hwmgr *hwmgr, uint8_t module_index, pp_atomctrl_mc_reg_table *table);
+extern int atomctrl_set_engine_dram_timings_rv770(struct pp_hwmgr *hwmgr, uint32_t engine_clock, uint32_t memory_clock);
+extern uint32_t atomctrl_get_reference_clock(struct pp_hwmgr *hwmgr);
+extern int atomctrl_get_memory_pll_dividers_si(struct pp_hwmgr *hwmgr, uint32_t clock_value, pp_atomctrl_memory_clock_param *mpll_param, bool strobe_mode);
+extern int atomctrl_get_engine_pll_dividers_vi(struct pp_hwmgr *hwmgr, uint32_t clock_value, pp_atomctrl_clock_dividers_vi *dividers);
+extern int atomctrl_get_dfs_pll_dividers_vi(struct pp_hwmgr *hwmgr, uint32_t clock_value, pp_atomctrl_clock_dividers_vi *dividers);
+extern bool atomctrl_is_voltage_controled_by_gpio_v3(struct pp_hwmgr *hwmgr, uint8_t voltage_type, uint8_t voltage_mode);
+extern int atomctrl_get_voltage_table_v3(struct pp_hwmgr *hwmgr, uint8_t voltage_type, uint8_t voltage_mode, pp_atomctrl_voltage_table *voltage_table);
+extern int atomctrl_get_memory_pll_dividers_vi(struct pp_hwmgr *hwmgr,
+		uint32_t clock_value, pp_atomctrl_memory_clock_param *mpll_param);
+extern int atomctrl_get_engine_pll_dividers_kong(struct pp_hwmgr *hwmgr,
+						 uint32_t clock_value,
+						 pp_atomctrl_clock_dividers_kong *dividers);
+extern int atomctrl_read_efuse(void *device, uint16_t start_index,
+		uint16_t end_index, uint32_t mask, uint32_t *efuse);
+extern int atomctrl_calculate_voltage_evv_on_sclk(struct pp_hwmgr *hwmgr, uint8_t voltage_type,
+		uint32_t sclk, uint16_t virtual_voltage_Id, uint16_t *voltage, uint16_t dpm_level, bool debug);
+
+
+#endif
+
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/powerplay/hwmgr/ppevvmath.h
@@ -0,0 +1,612 @@
+/*
+ * Copyright 2015 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+#include <asm/div64.h>
+
+#define SHIFT_AMOUNT 16 /* We multiply all original integers with 2^SHIFT_AMOUNT to get the fInt representation */
+
+#define PRECISION 5 /* Change this value to change the number of decimal places in the final output - 5 is a good default */
+
+#define SHIFTED_2 (2 << SHIFT_AMOUNT)
+#define MAX (1 << (SHIFT_AMOUNT - 1)) - 1 /* 32767 - Might change in the future */
+
+/* -------------------------------------------------------------------------------
+ * NEW TYPE - fINT
+ * -------------------------------------------------------------------------------
+ * A variable of type fInt can be accessed in 3 ways using the dot (.) operator
+ * fInt A;
+ * A.full => The full number as it is. Generally not easy to read
+ * A.partial.real => Only the integer portion
+ * A.partial.decimal => Only the fractional portion
+ */
+typedef union _fInt {
+    int full;
+    struct _partial {
+        unsigned int decimal: SHIFT_AMOUNT; /*Needs to always be unsigned*/
+        int real: 32 - SHIFT_AMOUNT;
+    } partial;
+} fInt;
+
+/* -------------------------------------------------------------------------------
+ * Function Declarations
+ *  -------------------------------------------------------------------------------
+ */
+fInt ConvertToFraction(int);                       /* Use this to convert an INT to a FINT */
+fInt Convert_ULONG_ToFraction(uint32_t);              /* Use this to convert an uint32_t to a FINT */
+fInt GetScaledFraction(int, int);                  /* Use this to convert an INT to a FINT after scaling it by a factor */
+int ConvertBackToInteger(fInt);                    /* Convert a FINT back to an INT that is scaled by 1000 (i.e. last 3 digits are the decimal digits) */
+
+fInt fNegate(fInt);                                /* Returns -1 * input fInt value */
+fInt fAdd (fInt, fInt);                            /* Returns the sum of two fInt numbers */
+fInt fSubtract (fInt A, fInt B);                   /* Returns A-B - Sometimes easier than Adding negative numbers */
+fInt fMultiply (fInt, fInt);                       /* Returns the product of two fInt numbers */
+fInt fDivide (fInt A, fInt B);                     /* Returns A/B */
+fInt fGetSquare(fInt);                             /* Returns the square of a fInt number */
+fInt fSqrt(fInt);                                  /* Returns the Square Root of a fInt number */
+
+int uAbs(int);                                     /* Returns the Absolute value of the Int */
+fInt fAbs(fInt);                                   /* Returns the Absolute value of the fInt */
+int uPow(int base, int exponent);                  /* Returns base^exponent an INT */
+
+void SolveQuadracticEqn(fInt, fInt, fInt, fInt[]); /* Returns the 2 roots via the array */
+bool Equal(fInt, fInt);                         /* Returns true if two fInts are equal to each other */
+bool GreaterThan(fInt A, fInt B);               /* Returns true if A > B */
+
+fInt fExponential(fInt exponent);                  /* Can be used to calculate e^exponent */
+fInt fNaturalLog(fInt value);                      /* Can be used to calculate ln(value) */
+
+/* Fuse decoding functions
+ * -------------------------------------------------------------------------------------
+ */
+fInt fDecodeLinearFuse(uint32_t fuse_value, fInt f_min, fInt f_range, uint32_t bitlength);
+fInt fDecodeLogisticFuse(uint32_t fuse_value, fInt f_average, fInt f_range, uint32_t bitlength);
+fInt fDecodeLeakageID (uint32_t leakageID_fuse, fInt ln_max_div_min, fInt f_min, uint32_t bitlength);
+
+/* Internal Support Functions - Use these ONLY for testing or adding to internal functions
+ * -------------------------------------------------------------------------------------
+ * Some of the following functions take two INTs as their input - This is unsafe for a variety of reasons.
+ */
+fInt Add (int, int);                               /* Add two INTs and return Sum as FINT */
+fInt Multiply (int, int);                          /* Multiply two INTs and return Product as FINT */
+fInt Divide (int, int);                            /* You get the idea... */
+fInt fNegate(fInt);
+
+int uGetScaledDecimal (fInt);                      /* Internal function */
+int GetReal (fInt A);                              /* Internal function */
+
+/* Future Additions and Incomplete Functions
+ * -------------------------------------------------------------------------------------
+ */
+int GetRoundedValue(fInt);                         /* Incomplete function - Useful only when Precision is lacking */
+                                                   /* Let us say we have 2.126 but can only handle 2 decimal points. We could */
+                                                   /* either chop of 6 and keep 2.12 or use this function to get 2.13, which is more accurate */
+
+/* -------------------------------------------------------------------------------------
+ * TROUBLESHOOTING INFORMATION
+ * -------------------------------------------------------------------------------------
+ * 1) ConvertToFraction - InputOutOfRangeException: Only accepts numbers smaller than MAX (default: 32767)
+ * 2) fAdd - OutputOutOfRangeException: Output bigger than MAX (default: 32767)
+ * 3) fMultiply - OutputOutOfRangeException:
+ * 4) fGetSquare - OutputOutOfRangeException:
+ * 5) fDivide - DivideByZeroException
+ * 6) fSqrt - NegativeSquareRootException: Input cannot be a negative number
+ */
+
+/* -------------------------------------------------------------------------------------
+ * START OF CODE
+ * -------------------------------------------------------------------------------------
+ */
+fInt fExponential(fInt exponent)        /*Can be used to calculate e^exponent*/
+{
+	uint32_t i;
+	bool bNegated = false;
+
+	fInt fPositiveOne = ConvertToFraction(1);
+	fInt fZERO = ConvertToFraction(0);
+
+	fInt lower_bound = Divide(78, 10000);
+	fInt solution = fPositiveOne; /*Starting off with baseline of 1 */
+	fInt error_term;
+
+	uint32_t k_array[11] = {55452, 27726, 13863, 6931, 4055, 2231, 1178, 606, 308, 155, 78};
+	uint32_t expk_array[11] = {2560000, 160000, 40000, 20000, 15000, 12500, 11250, 10625, 10313, 10156, 10078};
+
+	if (GreaterThan(fZERO, exponent)) {
+		exponent = fNegate(exponent);
+		bNegated = true;
+	}
+
+	while (GreaterThan(exponent, lower_bound)) {
+		for (i = 0; i < 11; i++) {
+			if (GreaterThan(exponent, GetScaledFraction(k_array[i], 10000))) {
+				exponent = fSubtract(exponent, GetScaledFraction(k_array[i], 10000));
+				solution = fMultiply(solution, GetScaledFraction(expk_array[i], 10000));
+			}
+		}
+	}
+
+	error_term = fAdd(fPositiveOne, exponent);
+
+	solution = fMultiply(solution, error_term);
+
+	if (bNegated)
+		solution = fDivide(fPositiveOne, solution);
+
+	return solution;
+}
+
+fInt fNaturalLog(fInt value)
+{
+	uint32_t i;
+	fInt upper_bound = Divide(8, 1000);
+	fInt fNegativeOne = ConvertToFraction(-1);
+	fInt solution = ConvertToFraction(0); /*Starting off with baseline of 0 */
+	fInt error_term;
+
+	uint32_t k_array[10] = {160000, 40000, 20000, 15000, 12500, 11250, 10625, 10313, 10156, 10078};
+	uint32_t logk_array[10] = {27726, 13863, 6931, 4055, 2231, 1178, 606, 308, 155, 78};
+
+	while (GreaterThan(fAdd(value, fNegativeOne), upper_bound)) {
+		for (i = 0; i < 10; i++) {
+			if (GreaterThan(value, GetScaledFraction(k_array[i], 10000))) {
+				value = fDivide(value, GetScaledFraction(k_array[i], 10000));
+				solution = fAdd(solution, GetScaledFraction(logk_array[i], 10000));
+			}
+		}
+	}
+
+	error_term = fAdd(fNegativeOne, value);
+
+	return (fAdd(solution, error_term));
+}
+
+fInt fDecodeLinearFuse(uint32_t fuse_value, fInt f_min, fInt f_range, uint32_t bitlength)
+{
+	fInt f_fuse_value = Convert_ULONG_ToFraction(fuse_value);
+	fInt f_bit_max_value = Convert_ULONG_ToFraction((uPow(2, bitlength)) - 1);
+
+	fInt f_decoded_value;
+
+	f_decoded_value = fDivide(f_fuse_value, f_bit_max_value);
+	f_decoded_value = fMultiply(f_decoded_value, f_range);
+	f_decoded_value = fAdd(f_decoded_value, f_min);
+
+	return f_decoded_value;
+}
+
+
+fInt fDecodeLogisticFuse(uint32_t fuse_value, fInt f_average, fInt f_range, uint32_t bitlength)
+{
+	fInt f_fuse_value = Convert_ULONG_ToFraction(fuse_value);
+	fInt f_bit_max_value = Convert_ULONG_ToFraction((uPow(2, bitlength)) - 1);
+
+	fInt f_CONSTANT_NEG13 = ConvertToFraction(-13);
+	fInt f_CONSTANT1 = ConvertToFraction(1);
+
+	fInt f_decoded_value;
+
+	f_decoded_value = fSubtract(fDivide(f_bit_max_value, f_fuse_value), f_CONSTANT1);
+	f_decoded_value = fNaturalLog(f_decoded_value);
+	f_decoded_value = fMultiply(f_decoded_value, fDivide(f_range, f_CONSTANT_NEG13));
+	f_decoded_value = fAdd(f_decoded_value, f_average);
+
+	return f_decoded_value;
+}
+
+fInt fDecodeLeakageID (uint32_t leakageID_fuse, fInt ln_max_div_min, fInt f_min, uint32_t bitlength)
+{
+	fInt fLeakage;
+	fInt f_bit_max_value = Convert_ULONG_ToFraction((uPow(2, bitlength)) - 1);
+
+	fLeakage = fMultiply(ln_max_div_min, Convert_ULONG_ToFraction(leakageID_fuse));
+	fLeakage = fDivide(fLeakage, f_bit_max_value);
+	fLeakage = fExponential(fLeakage);
+	fLeakage = fMultiply(fLeakage, f_min);
+
+	return fLeakage;
+}
+
+fInt ConvertToFraction(int X) /*Add all range checking here. Is it possible to make fInt a private declaration? */
+{
+	fInt temp;
+
+	if (X <= MAX)
+		temp.full = (X << SHIFT_AMOUNT);
+	else
+		temp.full = 0;
+
+	return temp;
+}
+
+fInt fNegate(fInt X)
+{
+	fInt CONSTANT_NEGONE = ConvertToFraction(-1);
+	return (fMultiply(X, CONSTANT_NEGONE));
+}
+
+fInt Convert_ULONG_ToFraction(uint32_t X)
+{
+	fInt temp;
+
+	if (X <= MAX)
+		temp.full = (X << SHIFT_AMOUNT);
+	else
+		temp.full = 0;
+
+	return temp;
+}
+
+fInt GetScaledFraction(int X, int factor)
+{
+	int times_shifted, factor_shifted;
+	bool bNEGATED;
+	fInt fValue;
+
+	times_shifted = 0;
+	factor_shifted = 0;
+	bNEGATED = false;
+
+	if (X < 0) {
+		X = -1*X;
+		bNEGATED = true;
+	}
+
+	if (factor < 0) {
+		factor = -1*factor;
+		bNEGATED = !bNEGATED; /*If bNEGATED = true due to X < 0, this will cover the case of negative cancelling negative */
+	}
+
+	if ((X > MAX) || factor > MAX) {
+		if ((X/factor) <= MAX) {
+			while (X > MAX) {
+				X = X >> 1;
+				times_shifted++;
+			}
+
+			while (factor > MAX) {
+				factor = factor >> 1;
+				factor_shifted++;
+			}
+		} else {
+			fValue.full = 0;
+			return fValue;
+		}
+	}
+
+	if (factor == 1)
+	return (ConvertToFraction(X));
+
+	fValue = fDivide(ConvertToFraction(X * uPow(-1, bNEGATED)), ConvertToFraction(factor));
+
+	fValue.full = fValue.full << times_shifted;
+	fValue.full = fValue.full >> factor_shifted;
+
+	return fValue;
+}
+
+/* Addition using two fInts */
+fInt fAdd (fInt X, fInt Y)
+{
+	fInt Sum;
+
+	Sum.full = X.full + Y.full;
+
+	return Sum;
+}
+
+/* Addition using two fInts */
+fInt fSubtract (fInt X, fInt Y)
+{
+	fInt Difference;
+
+	Difference.full = X.full - Y.full;
+
+	return Difference;
+}
+
+bool Equal(fInt A, fInt B)
+{
+	if (A.full == B.full)
+		return true;
+	else
+		return false;
+}
+
+bool GreaterThan(fInt A, fInt B)
+{
+	if (A.full > B.full)
+		return true;
+	else
+		return false;
+}
+
+fInt fMultiply (fInt X, fInt Y) /* Uses 64-bit integers (int64_t) */
+{
+	fInt Product;
+	int64_t tempProduct;
+	bool X_LessThanOne, Y_LessThanOne;
+
+	X_LessThanOne = (X.partial.real == 0 && X.partial.decimal != 0 && X.full >= 0);
+	Y_LessThanOne = (Y.partial.real == 0 && Y.partial.decimal != 0 && Y.full >= 0);
+
+	/*The following is for a very specific common case: Non-zero number with ONLY fractional portion*/
+	/* TEMPORARILY DISABLED - CAN BE USED TO IMPROVE PRECISION
+
+	if (X_LessThanOne && Y_LessThanOne) {
+		Product.full = X.full * Y.full;
+		return Product
+	}*/
+
+	tempProduct = ((int64_t)X.full) * ((int64_t)Y.full); /*Q(16,16)*Q(16,16) = Q(32, 32) - Might become a negative number! */
+	tempProduct = tempProduct >> 16; /*Remove lagging 16 bits - Will lose some precision from decimal; */
+	Product.full = (int)tempProduct; /*The int64_t will lose the leading 16 bits that were part of the integer portion */
+
+	return Product;
+}
+
+fInt fDivide (fInt X, fInt Y)
+{
+	fInt fZERO, fQuotient;
+	int64_t longlongX, longlongY;
+
+	fZERO = ConvertToFraction(0);
+
+	if (Equal(Y, fZERO))
+	return fZERO;
+
+	longlongX = (int64_t)X.full;
+	longlongY = (int64_t)Y.full;
+
+	longlongX = longlongX << 16; /*Q(16,16) -> Q(32,32) */
+
+	div64_s64(longlongX, longlongY); /*Q(32,32) divided by Q(16,16) = Q(16,16) Back to original format */
+
+	fQuotient.full = (int)longlongX;
+	return fQuotient;
+}
+
+int ConvertBackToInteger (fInt A) /*THIS is the function that will be used to check with the Golden settings table*/
+{
+	fInt fullNumber, scaledDecimal, scaledReal;
+
+	scaledReal.full = GetReal(A) * uPow(10, PRECISION-1); /* DOUBLE CHECK THISSSS!!! */
+
+	scaledDecimal.full = uGetScaledDecimal(A);
+
+	fullNumber = fAdd(scaledDecimal,scaledReal);
+
+	return fullNumber.full;
+}
+
+fInt fGetSquare(fInt A)
+{
+	return fMultiply(A,A);
+}
+
+/* x_new = x_old - (x_old^2 - C) / (2 * x_old) */
+fInt fSqrt(fInt num)
+{
+	fInt F_divide_Fprime, Fprime;
+	fInt test;
+	fInt twoShifted;
+	int seed, counter, error;
+	fInt x_new, x_old, C, y;
+
+	fInt fZERO = ConvertToFraction(0);
+
+	/* (0 > num) is the same as (num < 0), i.e., num is negative */
+
+	if (GreaterThan(fZERO, num) || Equal(fZERO, num))
+		return fZERO;
+
+	C = num;
+
+	if (num.partial.real > 3000)
+		seed = 60;
+	else if (num.partial.real > 1000)
+		seed = 30;
+	else if (num.partial.real > 100)
+		seed = 10;
+	else
+		seed = 2;
+
+	counter = 0;
+
+	if (Equal(num, fZERO)) /*Square Root of Zero is zero */
+		return fZERO;
+
+	twoShifted = ConvertToFraction(2);
+	x_new = ConvertToFraction(seed);
+
+	do {
+		counter++;
+
+		x_old.full = x_new.full;
+
+		test = fGetSquare(x_old); /*1.75*1.75 is reverting back to 1 when shifted down */
+		y = fSubtract(test, C); /*y = f(x) = x^2 - C; */
+
+		Fprime = fMultiply(twoShifted, x_old);
+		F_divide_Fprime = fDivide(y, Fprime);
+
+		x_new = fSubtract(x_old, F_divide_Fprime);
+
+		error = ConvertBackToInteger(x_new) - ConvertBackToInteger(x_old);
+
+		if (counter > 20) /*20 is already way too many iterations. If we dont have an answer by then, we never will*/
+			return x_new;
+
+	} while (uAbs(error) > 0);
+
+	return (x_new);
+}
+
+void SolveQuadracticEqn(fInt A, fInt B, fInt C, fInt Roots[])
+{
+	fInt *pRoots = &Roots[0];
+	fInt temp, root_first, root_second;
+	fInt f_CONSTANT10, f_CONSTANT100;
+
+	f_CONSTANT100 = ConvertToFraction(100);
+	f_CONSTANT10 = ConvertToFraction(10);
+
+	while(GreaterThan(A, f_CONSTANT100) || GreaterThan(B, f_CONSTANT100) || GreaterThan(C, f_CONSTANT100)) {
+		A = fDivide(A, f_CONSTANT10);
+		B = fDivide(B, f_CONSTANT10);
+		C = fDivide(C, f_CONSTANT10);
+	}
+
+	temp = fMultiply(ConvertToFraction(4), A); /* root = 4*A */
+	temp = fMultiply(temp, C); /* root = 4*A*C */
+	temp = fSubtract(fGetSquare(B), temp); /* root = b^2 - 4AC */
+	temp = fSqrt(temp); /*root = Sqrt (b^2 - 4AC); */
+
+	root_first = fSubtract(fNegate(B), temp); /* b - Sqrt(b^2 - 4AC) */
+	root_second = fAdd(fNegate(B), temp); /* b + Sqrt(b^2 - 4AC) */
+
+	root_first = fDivide(root_first, ConvertToFraction(2)); /* [b +- Sqrt(b^2 - 4AC)]/[2] */
+	root_first = fDivide(root_first, A); /*[b +- Sqrt(b^2 - 4AC)]/[2*A] */
+
+	root_second = fDivide(root_second, ConvertToFraction(2)); /* [b +- Sqrt(b^2 - 4AC)]/[2] */
+	root_second = fDivide(root_second, A); /*[b +- Sqrt(b^2 - 4AC)]/[2*A] */
+
+	*(pRoots + 0) = root_first;
+	*(pRoots + 1) = root_second;
+}
+
+/* -----------------------------------------------------------------------------
+ * SUPPORT FUNCTIONS
+ * -----------------------------------------------------------------------------
+ */
+
+/* Addition using two normal ints - Temporary - Use only for testing purposes?. */
+fInt Add (int X, int Y)
+{
+	fInt A, B, Sum;
+
+	A.full = (X << SHIFT_AMOUNT);
+	B.full = (Y << SHIFT_AMOUNT);
+
+	Sum.full = A.full + B.full;
+
+	return Sum;
+}
+
+/* Conversion Functions */
+int GetReal (fInt A)
+{
+	return (A.full >> SHIFT_AMOUNT);
+}
+
+/* Temporarily Disabled */
+int GetRoundedValue(fInt A) /*For now, round the 3rd decimal place */
+{
+	/* ROUNDING TEMPORARLY DISABLED
+	int temp = A.full;
+	int decimal_cutoff, decimal_mask = 0x000001FF;
+	decimal_cutoff = temp & decimal_mask;
+	if (decimal_cutoff > 0x147) {
+		temp += 673;
+	}*/
+
+	return ConvertBackToInteger(A)/10000; /*Temporary - in case this was used somewhere else */
+}
+
+fInt Multiply (int X, int Y)
+{
+	fInt A, B, Product;
+
+	A.full = X << SHIFT_AMOUNT;
+	B.full = Y << SHIFT_AMOUNT;
+
+	Product = fMultiply(A, B);
+
+	return Product;
+}
+
+fInt Divide (int X, int Y)
+{
+	fInt A, B, Quotient;
+
+	A.full = X << SHIFT_AMOUNT;
+	B.full = Y << SHIFT_AMOUNT;
+
+	Quotient = fDivide(A, B);
+
+	return Quotient;
+}
+
+int uGetScaledDecimal (fInt A) /*Converts the fractional portion to whole integers - Costly function */
+{
+	int dec[PRECISION];
+	int i, scaledDecimal = 0, tmp = A.partial.decimal;
+
+	for (i = 0; i < PRECISION; i++) {
+		dec[i] = tmp / (1 << SHIFT_AMOUNT);
+		tmp = tmp - ((1 << SHIFT_AMOUNT)*dec[i]);
+		tmp *= 10;
+		scaledDecimal = scaledDecimal + dec[i]*uPow(10, PRECISION - 1 -i);
+	}
+
+	return scaledDecimal;
+}
+
+int uPow(int base, int power)
+{
+	if (power == 0)
+		return 1;
+	else
+		return (base)*uPow(base, power - 1);
+}
+
+fInt fAbs(fInt A)
+{
+	if (A.partial.real < 0)
+		return (fMultiply(A, ConvertToFraction(-1)));
+	else
+		return A;
+}
+
+int uAbs(int X)
+{
+	if (X < 0)
+		return (X * -1);
+	else
+		return X;
+}
+
+fInt fRoundUpByStepSize(fInt A, fInt fStepSize, bool error_term)
+{
+	fInt solution;
+
+	solution = fDivide(A, fStepSize);
+	solution.partial.decimal = 0; /*All fractional digits changes to 0 */
+
+	if (error_term)
+		solution.partial.real += 1; /*Error term of 1 added */
+
+	solution = fMultiply(solution, fStepSize);
+	solution = fAdd(solution, fStepSize);
+
+	return solution;
+}
+
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/powerplay/hwmgr/pppcielanes.c
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2015 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#include <linux/types.h>
+#include "atom-types.h"
+#include "atombios.h"
+#include "pppcielanes.h"
+
+/** \file
+ * Functions related to PCIe lane changes.
+ */
+
+/* For converting from number of lanes to lane bits.  */
+static const unsigned char pp_r600_encode_lanes[] = {
+	0,          /*  0 Not Supported  */
+	1,          /*  1 Lane  */
+	2,          /*  2 Lanes  */
+	0,          /*  3 Not Supported  */
+	3,          /*  4 Lanes  */
+	0,          /*  5 Not Supported  */
+	0,          /*  6 Not Supported  */
+	0,          /*  7 Not Supported  */
+	4,          /*  8 Lanes  */
+	0,          /*  9 Not Supported  */
+	0,          /* 10 Not Supported  */
+	0,          /* 11 Not Supported  */
+	5,          /* 12 Lanes (Not actually supported)  */
+	0,          /* 13 Not Supported  */
+	0,          /* 14 Not Supported  */
+	0,          /* 15 Not Supported  */
+	6           /* 16 Lanes  */
+};
+
+static const unsigned char pp_r600_decoded_lanes[8] = { 16, 1, 2, 4, 8, 12, 16, };
+
+uint8_t encode_pcie_lane_width(uint32_t num_lanes)
+{
+	return pp_r600_encode_lanes[num_lanes];
+}
+
+uint8_t decode_pcie_lane_width(uint32_t num_lanes)
+{
+	return pp_r600_decoded_lanes[num_lanes];
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/powerplay/hwmgr/pppcielanes.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2015 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#ifndef PP_PCIELANES_H
+#define PP_PCIELANES_H
+
+extern uint8_t encode_pcie_lane_width(uint32_t num_lanes);
+extern uint8_t decode_pcie_lane_width(uint32_t num_lanes);
+
+#endif
+
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/powerplay/hwmgr/processpptables.c
@@ -0,0 +1,1688 @@
+/*
+ * Copyright 2015 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+
+#include "processpptables.h"
+#include <atom-types.h>
+#include <atombios.h>
+#include "pp_debug.h"
+#include "pptable.h"
+#include "power_state.h"
+#include "hwmgr.h"
+#include "hardwaremanager.h"
+
+
+#define SIZE_OF_ATOM_PPLIB_EXTENDEDHEADER_V2 12
+#define SIZE_OF_ATOM_PPLIB_EXTENDEDHEADER_V3 14
+#define SIZE_OF_ATOM_PPLIB_EXTENDEDHEADER_V4 16
+#define SIZE_OF_ATOM_PPLIB_EXTENDEDHEADER_V5 18
+#define SIZE_OF_ATOM_PPLIB_EXTENDEDHEADER_V6 20
+#define SIZE_OF_ATOM_PPLIB_EXTENDEDHEADER_V7 22
+#define SIZE_OF_ATOM_PPLIB_EXTENDEDHEADER_V8 24
+#define SIZE_OF_ATOM_PPLIB_EXTENDEDHEADER_V9 26
+
+#define NUM_BITS_CLOCK_INFO_ARRAY_INDEX 6
+
+static uint16_t get_vce_table_offset(struct pp_hwmgr *hwmgr,
+			const ATOM_PPLIB_POWERPLAYTABLE *powerplay_table)
+{
+	uint16_t vce_table_offset = 0;
+
+	if (le16_to_cpu(powerplay_table->usTableSize) >=
+	   sizeof(ATOM_PPLIB_POWERPLAYTABLE3)) {
+		const ATOM_PPLIB_POWERPLAYTABLE3 *powerplay_table3 =
+			(const ATOM_PPLIB_POWERPLAYTABLE3 *)powerplay_table;
+
+		if (powerplay_table3->usExtendendedHeaderOffset > 0) {
+			const ATOM_PPLIB_EXTENDEDHEADER  *extended_header =
+						(const ATOM_PPLIB_EXTENDEDHEADER *)
+						(((unsigned long)powerplay_table3) +
+						le16_to_cpu(powerplay_table3->usExtendendedHeaderOffset));
+			if (le16_to_cpu(extended_header->usSize) >=
+			   SIZE_OF_ATOM_PPLIB_EXTENDEDHEADER_V2)
+				vce_table_offset = le16_to_cpu(extended_header->usVCETableOffset);
+		}
+	}
+
+	return vce_table_offset;
+}
+
+static uint16_t get_vce_clock_info_array_offset(struct pp_hwmgr *hwmgr,
+			const ATOM_PPLIB_POWERPLAYTABLE *powerplay_table)
+{
+	uint16_t table_offset = get_vce_table_offset(hwmgr,
+						powerplay_table);
+
+	if (table_offset > 0)
+		return table_offset + 1;
+
+	return 0;
+}
+
+static uint16_t get_vce_clock_info_array_size(struct pp_hwmgr *hwmgr,
+			const ATOM_PPLIB_POWERPLAYTABLE *powerplay_table)
+{
+	uint16_t table_offset = get_vce_clock_info_array_offset(hwmgr,
+							powerplay_table);
+	uint16_t table_size = 0;
+
+	if (table_offset > 0) {
+		const VCEClockInfoArray *p = (const VCEClockInfoArray *)
+			(((unsigned long) powerplay_table) + table_offset);
+		table_size = sizeof(uint8_t) + p->ucNumEntries * sizeof(VCEClockInfo);
+	}
+
+	return table_size;
+}
+
+static uint16_t get_vce_clock_voltage_limit_table_offset(struct pp_hwmgr *hwmgr,
+				const ATOM_PPLIB_POWERPLAYTABLE *powerplay_table)
+{
+	uint16_t table_offset = get_vce_clock_info_array_offset(hwmgr,
+							powerplay_table);
+
+	if (table_offset > 0)
+		return table_offset + get_vce_clock_info_array_size(hwmgr,
+							powerplay_table);
+
+	return 0;
+}
+
+static uint16_t get_vce_clock_voltage_limit_table_size(struct pp_hwmgr *hwmgr,
+							const ATOM_PPLIB_POWERPLAYTABLE *powerplay_table)
+{
+	uint16_t table_offset = get_vce_clock_voltage_limit_table_offset(hwmgr, powerplay_table);
+	uint16_t table_size = 0;
+
+	if (table_offset > 0) {
+		const ATOM_PPLIB_VCE_Clock_Voltage_Limit_Table *ptable =
+			(const ATOM_PPLIB_VCE_Clock_Voltage_Limit_Table *)(((unsigned long) powerplay_table) + table_offset);
+
+		table_size = sizeof(uint8_t) + ptable->numEntries * sizeof(ATOM_PPLIB_VCE_Clock_Voltage_Limit_Record);
+	}
+	return table_size;
+}
+
+static uint16_t get_vce_state_table_offset(struct pp_hwmgr *hwmgr, const ATOM_PPLIB_POWERPLAYTABLE *powerplay_table)
+{
+	uint16_t table_offset = get_vce_clock_voltage_limit_table_offset(hwmgr, powerplay_table);
+
+	if (table_offset > 0)
+		return table_offset + get_vce_clock_voltage_limit_table_size(hwmgr, powerplay_table);
+
+	return 0;
+}
+
+static const ATOM_PPLIB_VCE_State_Table *get_vce_state_table(
+						struct pp_hwmgr *hwmgr,
+						const ATOM_PPLIB_POWERPLAYTABLE *powerplay_table)
+{
+	uint16_t table_offset = get_vce_state_table_offset(hwmgr, powerplay_table);
+
+	if (table_offset > 0)
+		return (const ATOM_PPLIB_VCE_State_Table *)(((unsigned long) powerplay_table) + table_offset);
+
+	return NULL;
+}
+
+static uint16_t get_uvd_table_offset(struct pp_hwmgr *hwmgr,
+			const ATOM_PPLIB_POWERPLAYTABLE *powerplay_table)
+{
+	uint16_t uvd_table_offset = 0;
+
+	if (le16_to_cpu(powerplay_table->usTableSize) >=
+	    sizeof(ATOM_PPLIB_POWERPLAYTABLE3)) {
+		const ATOM_PPLIB_POWERPLAYTABLE3 *powerplay_table3 =
+			(const ATOM_PPLIB_POWERPLAYTABLE3 *)powerplay_table;
+		if (powerplay_table3->usExtendendedHeaderOffset > 0) {
+			const ATOM_PPLIB_EXTENDEDHEADER  *extended_header =
+					(const ATOM_PPLIB_EXTENDEDHEADER *)
+					(((unsigned long)powerplay_table3) +
+				le16_to_cpu(powerplay_table3->usExtendendedHeaderOffset));
+			if (le16_to_cpu(extended_header->usSize) >=
+			    SIZE_OF_ATOM_PPLIB_EXTENDEDHEADER_V3)
+				uvd_table_offset = le16_to_cpu(extended_header->usUVDTableOffset);
+		}
+	}
+	return uvd_table_offset;
+}
+
+static uint16_t get_uvd_clock_info_array_offset(struct pp_hwmgr *hwmgr,
+			 const ATOM_PPLIB_POWERPLAYTABLE *powerplay_table)
+{
+	uint16_t table_offset = get_uvd_table_offset(hwmgr,
+						    powerplay_table);
+
+	if (table_offset > 0)
+		return table_offset + 1;
+	return 0;
+}
+
+static uint16_t get_uvd_clock_info_array_size(struct pp_hwmgr *hwmgr,
+			const ATOM_PPLIB_POWERPLAYTABLE *powerplay_table)
+{
+	uint16_t table_offset = get_uvd_clock_info_array_offset(hwmgr,
+						    powerplay_table);
+	uint16_t table_size = 0;
+
+	if (table_offset > 0) {
+		const UVDClockInfoArray *p = (const UVDClockInfoArray *)
+					(((unsigned long) powerplay_table)
+					+ table_offset);
+		table_size = sizeof(UCHAR) +
+			     p->ucNumEntries * sizeof(UVDClockInfo);
+	}
+
+	return table_size;
+}
+
+static uint16_t get_uvd_clock_voltage_limit_table_offset(
+			struct pp_hwmgr *hwmgr,
+			const ATOM_PPLIB_POWERPLAYTABLE *powerplay_table)
+{
+	uint16_t table_offset = get_uvd_clock_info_array_offset(hwmgr,
+						     powerplay_table);
+
+	if (table_offset > 0)
+		return table_offset +
+			get_uvd_clock_info_array_size(hwmgr, powerplay_table);
+
+	return 0;
+}
+
+static uint16_t get_samu_table_offset(struct pp_hwmgr *hwmgr,
+			const ATOM_PPLIB_POWERPLAYTABLE *powerplay_table)
+{
+	uint16_t samu_table_offset = 0;
+
+	if (le16_to_cpu(powerplay_table->usTableSize) >=
+	    sizeof(ATOM_PPLIB_POWERPLAYTABLE3)) {
+		const ATOM_PPLIB_POWERPLAYTABLE3 *powerplay_table3 =
+			(const ATOM_PPLIB_POWERPLAYTABLE3 *)powerplay_table;
+		if (powerplay_table3->usExtendendedHeaderOffset > 0) {
+			const ATOM_PPLIB_EXTENDEDHEADER  *extended_header =
+				(const ATOM_PPLIB_EXTENDEDHEADER *)
+				(((unsigned long)powerplay_table3) +
+				le16_to_cpu(powerplay_table3->usExtendendedHeaderOffset));
+			if (le16_to_cpu(extended_header->usSize) >=
+			    SIZE_OF_ATOM_PPLIB_EXTENDEDHEADER_V4)
+				samu_table_offset = le16_to_cpu(extended_header->usSAMUTableOffset);
+		}
+	}
+
+	return samu_table_offset;
+}
+
+static uint16_t get_samu_clock_voltage_limit_table_offset(
+			struct pp_hwmgr *hwmgr,
+			const ATOM_PPLIB_POWERPLAYTABLE *powerplay_table)
+{
+	uint16_t table_offset = get_samu_table_offset(hwmgr,
+					    powerplay_table);
+
+	if (table_offset > 0)
+		return table_offset + 1;
+
+	return 0;
+}
+
+static uint16_t get_acp_table_offset(struct pp_hwmgr *hwmgr,
+				const ATOM_PPLIB_POWERPLAYTABLE *powerplay_table)
+{
+	uint16_t acp_table_offset = 0;
+
+	if (le16_to_cpu(powerplay_table->usTableSize) >=
+	    sizeof(ATOM_PPLIB_POWERPLAYTABLE3)) {
+		const ATOM_PPLIB_POWERPLAYTABLE3 *powerplay_table3 =
+			(const ATOM_PPLIB_POWERPLAYTABLE3 *)powerplay_table;
+		if (powerplay_table3->usExtendendedHeaderOffset > 0) {
+			const ATOM_PPLIB_EXTENDEDHEADER  *pExtendedHeader =
+				(const ATOM_PPLIB_EXTENDEDHEADER *)
+				(((unsigned long)powerplay_table3) +
+				le16_to_cpu(powerplay_table3->usExtendendedHeaderOffset));
+			if (le16_to_cpu(pExtendedHeader->usSize) >=
+			    SIZE_OF_ATOM_PPLIB_EXTENDEDHEADER_V6)
+				acp_table_offset = le16_to_cpu(pExtendedHeader->usACPTableOffset);
+		}
+	}
+
+	return acp_table_offset;
+}
+
+static uint16_t get_acp_clock_voltage_limit_table_offset(
+				struct pp_hwmgr *hwmgr,
+				const ATOM_PPLIB_POWERPLAYTABLE *powerplay_table)
+{
+	uint16_t tableOffset = get_acp_table_offset(hwmgr, powerplay_table);
+
+	if (tableOffset > 0)
+		return tableOffset + 1;
+
+	return 0;
+}
+
+static uint16_t get_cacp_tdp_table_offset(
+				struct pp_hwmgr *hwmgr,
+				const ATOM_PPLIB_POWERPLAYTABLE *powerplay_table)
+{
+	uint16_t cacTdpTableOffset = 0;
+
+	if (le16_to_cpu(powerplay_table->usTableSize) >=
+	    sizeof(ATOM_PPLIB_POWERPLAYTABLE3)) {
+		const ATOM_PPLIB_POWERPLAYTABLE3 *powerplay_table3 =
+				(const ATOM_PPLIB_POWERPLAYTABLE3 *)powerplay_table;
+		if (powerplay_table3->usExtendendedHeaderOffset > 0) {
+			const ATOM_PPLIB_EXTENDEDHEADER  *pExtendedHeader =
+					(const ATOM_PPLIB_EXTENDEDHEADER *)
+					(((unsigned long)powerplay_table3) +
+				le16_to_cpu(powerplay_table3->usExtendendedHeaderOffset));
+			if (le16_to_cpu(pExtendedHeader->usSize) >=
+			    SIZE_OF_ATOM_PPLIB_EXTENDEDHEADER_V7)
+				cacTdpTableOffset = le16_to_cpu(pExtendedHeader->usPowerTuneTableOffset);
+		}
+	}
+
+	return cacTdpTableOffset;
+}
+
+static int get_cac_tdp_table(struct pp_hwmgr *hwmgr,
+				struct phm_cac_tdp_table **ptable,
+				const ATOM_PowerTune_Table *table,
+				uint16_t us_maximum_power_delivery_limit)
+{
+	unsigned long table_size;
+	struct phm_cac_tdp_table *tdp_table;
+
+	table_size = sizeof(unsigned long) + sizeof(struct phm_cac_tdp_table);
+
+	tdp_table = kzalloc(table_size, GFP_KERNEL);
+	if (NULL == tdp_table)
+		return -ENOMEM;
+
+	tdp_table->usTDP = le16_to_cpu(table->usTDP);
+	tdp_table->usConfigurableTDP = le16_to_cpu(table->usConfigurableTDP);
+	tdp_table->usTDC = le16_to_cpu(table->usTDC);
+	tdp_table->usBatteryPowerLimit = le16_to_cpu(table->usBatteryPowerLimit);
+	tdp_table->usSmallPowerLimit = le16_to_cpu(table->usSmallPowerLimit);
+	tdp_table->usLowCACLeakage = le16_to_cpu(table->usLowCACLeakage);
+	tdp_table->usHighCACLeakage = le16_to_cpu(table->usHighCACLeakage);
+	tdp_table->usMaximumPowerDeliveryLimit = us_maximum_power_delivery_limit;
+
+	*ptable = tdp_table;
+
+	return 0;
+}
+
+static uint16_t get_sclk_vdd_gfx_table_offset(struct pp_hwmgr *hwmgr,
+			const ATOM_PPLIB_POWERPLAYTABLE *powerplay_table)
+{
+	uint16_t sclk_vdd_gfx_table_offset = 0;
+
+	if (le16_to_cpu(powerplay_table->usTableSize) >=
+	    sizeof(ATOM_PPLIB_POWERPLAYTABLE3)) {
+		const ATOM_PPLIB_POWERPLAYTABLE3 *powerplay_table3 =
+				(const ATOM_PPLIB_POWERPLAYTABLE3 *)powerplay_table;
+		if (powerplay_table3->usExtendendedHeaderOffset > 0) {
+			const ATOM_PPLIB_EXTENDEDHEADER  *pExtendedHeader =
+				(const ATOM_PPLIB_EXTENDEDHEADER *)
+				(((unsigned long)powerplay_table3) +
+				le16_to_cpu(powerplay_table3->usExtendendedHeaderOffset));
+			if (le16_to_cpu(pExtendedHeader->usSize) >=
+			    SIZE_OF_ATOM_PPLIB_EXTENDEDHEADER_V8)
+				sclk_vdd_gfx_table_offset =
+					le16_to_cpu(pExtendedHeader->usSclkVddgfxTableOffset);
+		}
+	}
+
+	return sclk_vdd_gfx_table_offset;
+}
+
+static uint16_t get_sclk_vdd_gfx_clock_voltage_dependency_table_offset(
+			struct pp_hwmgr *hwmgr,
+			const ATOM_PPLIB_POWERPLAYTABLE *powerplay_table)
+{
+	uint16_t tableOffset = get_sclk_vdd_gfx_table_offset(hwmgr, powerplay_table);
+
+	if (tableOffset > 0)
+		return tableOffset;
+
+	return 0;
+}
+
+
+static int get_clock_voltage_dependency_table(struct pp_hwmgr *hwmgr,
+		struct phm_clock_voltage_dependency_table **ptable,
+		const ATOM_PPLIB_Clock_Voltage_Dependency_Table *table)
+{
+
+	unsigned long table_size, i;
+	struct phm_clock_voltage_dependency_table *dep_table;
+
+	table_size = sizeof(unsigned long) +
+		sizeof(struct phm_clock_voltage_dependency_table)
+		* table->ucNumEntries;
+
+	dep_table = kzalloc(table_size, GFP_KERNEL);
+	if (NULL == dep_table)
+		return -ENOMEM;
+
+	dep_table->count = (unsigned long)table->ucNumEntries;
+
+	for (i = 0; i < dep_table->count; i++) {
+		dep_table->entries[i].clk =
+			((unsigned long)table->entries[i].ucClockHigh << 16) |
+			le16_to_cpu(table->entries[i].usClockLow);
+			dep_table->entries[i].v =
+				(unsigned long)le16_to_cpu(table->entries[i].usVoltage);
+	}
+
+	*ptable = dep_table;
+
+	return 0;
+}
+
+static int get_valid_clk(struct pp_hwmgr *hwmgr,
+			struct phm_clock_array **ptable,
+			const struct phm_clock_voltage_dependency_table *table)
+{
+	unsigned long table_size, i;
+	struct phm_clock_array *clock_table;
+
+	table_size = sizeof(unsigned long) + sizeof(unsigned long) * table->count;
+	clock_table = kzalloc(table_size, GFP_KERNEL);
+	if (NULL == clock_table)
+		return -ENOMEM;
+
+	clock_table->count = (unsigned long)table->count;
+
+	for (i = 0; i < clock_table->count; i++)
+		clock_table->values[i] = (unsigned long)table->entries[i].clk;
+
+	*ptable = clock_table;
+
+	return 0;
+}
+
+static int get_clock_voltage_limit(struct pp_hwmgr *hwmgr,
+			struct phm_clock_and_voltage_limits *limits,
+			const ATOM_PPLIB_Clock_Voltage_Limit_Table *table)
+{
+	limits->sclk = ((unsigned long)table->entries[0].ucSclkHigh << 16) |
+			le16_to_cpu(table->entries[0].usSclkLow);
+	limits->mclk = ((unsigned long)table->entries[0].ucMclkHigh << 16) |
+			le16_to_cpu(table->entries[0].usMclkLow);
+	limits->vddc = (unsigned long)le16_to_cpu(table->entries[0].usVddc);
+	limits->vddci = (unsigned long)le16_to_cpu(table->entries[0].usVddci);
+
+	return 0;
+}
+
+
+static void set_hw_cap(struct pp_hwmgr *hwmgr, bool enable,
+		       enum phm_platform_caps cap)
+{
+	if (enable)
+		phm_cap_set(hwmgr->platform_descriptor.platformCaps, cap);
+	else
+		phm_cap_unset(hwmgr->platform_descriptor.platformCaps, cap);
+}
+
+static int set_platform_caps(struct pp_hwmgr *hwmgr,
+			unsigned long powerplay_caps)
+{
+	set_hw_cap(
+		hwmgr,
+		0 != (powerplay_caps & ATOM_PP_PLATFORM_CAP_POWERPLAY),
+		PHM_PlatformCaps_PowerPlaySupport
+	);
+
+	set_hw_cap(
+		hwmgr,
+		0 != (powerplay_caps & ATOM_PP_PLATFORM_CAP_SBIOSPOWERSOURCE),
+		PHM_PlatformCaps_BiosPowerSourceControl
+	);
+
+	set_hw_cap(
+		hwmgr,
+		0 != (powerplay_caps & ATOM_PP_PLATFORM_CAP_ASPM_L0s),
+		PHM_PlatformCaps_EnableASPML0s
+	);
+
+	set_hw_cap(
+		hwmgr,
+		0 != (powerplay_caps & ATOM_PP_PLATFORM_CAP_ASPM_L1),
+		PHM_PlatformCaps_EnableASPML1
+	);
+
+	set_hw_cap(
+		hwmgr,
+		0 != (powerplay_caps & ATOM_PP_PLATFORM_CAP_BACKBIAS),
+		PHM_PlatformCaps_EnableBackbias
+	);
+
+	set_hw_cap(
+		hwmgr,
+		0 != (powerplay_caps & ATOM_PP_PLATFORM_CAP_HARDWAREDC),
+		PHM_PlatformCaps_AutomaticDCTransition
+	);
+
+	set_hw_cap(
+		hwmgr,
+		0 != (powerplay_caps & ATOM_PP_PLATFORM_CAP_GEMINIPRIMARY),
+		PHM_PlatformCaps_GeminiPrimary
+	);
+
+	set_hw_cap(
+		hwmgr,
+		0 != (powerplay_caps & ATOM_PP_PLATFORM_CAP_STEPVDDC),
+		PHM_PlatformCaps_StepVddc
+	);
+
+	set_hw_cap(
+		hwmgr,
+		0 != (powerplay_caps & ATOM_PP_PLATFORM_CAP_VOLTAGECONTROL),
+		PHM_PlatformCaps_EnableVoltageControl
+	);
+
+	set_hw_cap(
+		hwmgr,
+		0 != (powerplay_caps & ATOM_PP_PLATFORM_CAP_SIDEPORTCONTROL),
+		PHM_PlatformCaps_EnableSideportControl
+	);
+
+	set_hw_cap(
+		hwmgr,
+		0 != (powerplay_caps & ATOM_PP_PLATFORM_CAP_TURNOFFPLL_ASPML1),
+		PHM_PlatformCaps_TurnOffPll_ASPML1
+	);
+
+	set_hw_cap(
+		hwmgr,
+		0 != (powerplay_caps & ATOM_PP_PLATFORM_CAP_HTLINKCONTROL),
+		PHM_PlatformCaps_EnableHTLinkControl
+	);
+
+	set_hw_cap(
+		hwmgr,
+		0 != (powerplay_caps & ATOM_PP_PLATFORM_CAP_MVDDCONTROL),
+		PHM_PlatformCaps_EnableMVDDControl
+	);
+
+	set_hw_cap(
+		hwmgr,
+		0 != (powerplay_caps & ATOM_PP_PLATFORM_CAP_VDDCI_CONTROL),
+		PHM_PlatformCaps_ControlVDDCI
+	);
+
+	set_hw_cap(
+		hwmgr,
+		0 != (powerplay_caps & ATOM_PP_PLATFORM_CAP_REGULATOR_HOT),
+		PHM_PlatformCaps_RegulatorHot
+	);
+
+	set_hw_cap(
+		hwmgr,
+		0 != (powerplay_caps & ATOM_PP_PLATFORM_CAP_GOTO_BOOT_ON_ALERT),
+		PHM_PlatformCaps_BootStateOnAlert
+	);
+
+	set_hw_cap(
+		hwmgr,
+		0 != (powerplay_caps & ATOM_PP_PLATFORM_CAP_DONT_WAIT_FOR_VBLANK_ON_ALERT),
+		PHM_PlatformCaps_DontWaitForVBlankOnAlert
+	);
+
+	set_hw_cap(
+		hwmgr,
+		0 != (powerplay_caps & ATOM_PP_PLATFORM_CAP_BACO),
+		PHM_PlatformCaps_BACO
+	);
+
+	set_hw_cap(
+		hwmgr,
+		0 != (powerplay_caps & ATOM_PP_PLATFORM_CAP_NEW_CAC_VOLTAGE),
+		PHM_PlatformCaps_NewCACVoltage
+	);
+
+	set_hw_cap(
+		hwmgr,
+		0 != (powerplay_caps & ATOM_PP_PLATFORM_CAP_REVERT_GPIO5_POLARITY),
+		PHM_PlatformCaps_RevertGPIO5Polarity
+	);
+
+	set_hw_cap(
+		hwmgr,
+		0 != (powerplay_caps & ATOM_PP_PLATFORM_CAP_OUTPUT_THERMAL2GPIO17),
+		PHM_PlatformCaps_Thermal2GPIO17
+	);
+
+	set_hw_cap(
+		hwmgr,
+		0 != (powerplay_caps & ATOM_PP_PLATFORM_CAP_VRHOT_GPIO_CONFIGURABLE),
+		PHM_PlatformCaps_VRHotGPIOConfigurable
+	);
+
+	set_hw_cap(
+		hwmgr,
+		0 != (powerplay_caps & ATOM_PP_PLATFORM_CAP_TEMP_INVERSION),
+		PHM_PlatformCaps_TempInversion
+	);
+
+	set_hw_cap(
+		hwmgr,
+		0 != (powerplay_caps & ATOM_PP_PLATFORM_CAP_EVV),
+		PHM_PlatformCaps_EVV
+	);
+
+	set_hw_cap(
+		hwmgr,
+		0 != (powerplay_caps & ATOM_PP_PLATFORM_COMBINE_PCC_WITH_THERMAL_SIGNAL),
+		PHM_PlatformCaps_CombinePCCWithThermalSignal
+	);
+
+	set_hw_cap(
+		hwmgr,
+		0 != (powerplay_caps & ATOM_PP_PLATFORM_LOAD_POST_PRODUCTION_FIRMWARE),
+		PHM_PlatformCaps_LoadPostProductionFirmware
+	);
+
+	set_hw_cap(
+		hwmgr,
+		0 != (powerplay_caps & ATOM_PP_PLATFORM_CAP_DISABLE_USING_ACTUAL_TEMPERATURE_FOR_POWER_CALC),
+		PHM_PlatformCaps_DisableUsingActualTemperatureForPowerCalc
+	);
+
+	return 0;
+}
+
+static PP_StateClassificationFlags make_classification_flags(
+						   struct pp_hwmgr *hwmgr,
+						    USHORT classification,
+						   USHORT classification2)
+{
+	PP_StateClassificationFlags result = 0;
+
+	if (classification & ATOM_PPLIB_CLASSIFICATION_BOOT)
+		result |= PP_StateClassificationFlag_Boot;
+
+	if (classification & ATOM_PPLIB_CLASSIFICATION_THERMAL)
+		result |= PP_StateClassificationFlag_Thermal;
+
+	if (classification &
+			ATOM_PPLIB_CLASSIFICATION_LIMITEDPOWERSOURCE)
+		result |= PP_StateClassificationFlag_LimitedPowerSource;
+
+	if (classification & ATOM_PPLIB_CLASSIFICATION_REST)
+		result |= PP_StateClassificationFlag_Rest;
+
+	if (classification & ATOM_PPLIB_CLASSIFICATION_FORCED)
+		result |= PP_StateClassificationFlag_Forced;
+
+	if (classification & ATOM_PPLIB_CLASSIFICATION_3DPERFORMANCE)
+		result |= PP_StateClassificationFlag_3DPerformance;
+
+
+	if (classification & ATOM_PPLIB_CLASSIFICATION_OVERDRIVETEMPLATE)
+		result |= PP_StateClassificationFlag_ACOverdriveTemplate;
+
+	if (classification & ATOM_PPLIB_CLASSIFICATION_UVDSTATE)
+		result |= PP_StateClassificationFlag_Uvd;
+
+	if (classification & ATOM_PPLIB_CLASSIFICATION_HDSTATE)
+		result |= PP_StateClassificationFlag_UvdHD;
+
+	if (classification & ATOM_PPLIB_CLASSIFICATION_SDSTATE)
+		result |= PP_StateClassificationFlag_UvdSD;
+
+	if (classification & ATOM_PPLIB_CLASSIFICATION_HD2STATE)
+		result |= PP_StateClassificationFlag_HD2;
+
+	if (classification & ATOM_PPLIB_CLASSIFICATION_ACPI)
+		result |= PP_StateClassificationFlag_ACPI;
+
+	if (classification2 & ATOM_PPLIB_CLASSIFICATION2_LIMITEDPOWERSOURCE_2)
+		result |= PP_StateClassificationFlag_LimitedPowerSource_2;
+
+
+	if (classification2 & ATOM_PPLIB_CLASSIFICATION2_ULV)
+		result |= PP_StateClassificationFlag_ULV;
+
+	if (classification2 & ATOM_PPLIB_CLASSIFICATION2_MVC)
+		result |= PP_StateClassificationFlag_UvdMVC;
+
+	return result;
+}
+
+static int init_non_clock_fields(struct pp_hwmgr *hwmgr,
+						struct pp_power_state *ps,
+							    uint8_t version,
+			 const ATOM_PPLIB_NONCLOCK_INFO *pnon_clock_info) {
+	unsigned long rrr_index;
+	unsigned long tmp;
+
+	ps->classification.ui_label = (le16_to_cpu(pnon_clock_info->usClassification) &
+					ATOM_PPLIB_CLASSIFICATION_UI_MASK) >> ATOM_PPLIB_CLASSIFICATION_UI_SHIFT;
+	ps->classification.flags = make_classification_flags(hwmgr,
+				le16_to_cpu(pnon_clock_info->usClassification),
+				le16_to_cpu(pnon_clock_info->usClassification2));
+
+	ps->classification.temporary_state = false;
+	ps->classification.to_be_deleted = false;
+	tmp = le32_to_cpu(pnon_clock_info->ulCapsAndSettings) &
+		ATOM_PPLIB_SINGLE_DISPLAY_ONLY;
+
+	ps->validation.singleDisplayOnly = (0 != tmp);
+
+	tmp = le32_to_cpu(pnon_clock_info->ulCapsAndSettings) &
+		ATOM_PPLIB_DISALLOW_ON_DC;
+
+	ps->validation.disallowOnDC = (0 != tmp);
+
+	ps->pcie.lanes = ((le32_to_cpu(pnon_clock_info->ulCapsAndSettings) &
+				ATOM_PPLIB_PCIE_LINK_WIDTH_MASK) >>
+				ATOM_PPLIB_PCIE_LINK_WIDTH_SHIFT) + 1;
+
+	ps->pcie.lanes = 0;
+
+	ps->display.disableFrameModulation = false;
+
+	rrr_index = (le32_to_cpu(pnon_clock_info->ulCapsAndSettings) &
+			ATOM_PPLIB_LIMITED_REFRESHRATE_VALUE_MASK) >>
+			ATOM_PPLIB_LIMITED_REFRESHRATE_VALUE_SHIFT;
+
+	if (rrr_index != ATOM_PPLIB_LIMITED_REFRESHRATE_UNLIMITED) {
+		static const uint8_t look_up[(ATOM_PPLIB_LIMITED_REFRESHRATE_VALUE_MASK >> ATOM_PPLIB_LIMITED_REFRESHRATE_VALUE_SHIFT) + 1] = \
+								{ 0, 50, 0 };
+
+		ps->display.refreshrateSource = PP_RefreshrateSource_Explicit;
+		ps->display.explicitRefreshrate = look_up[rrr_index];
+		ps->display.limitRefreshrate = true;
+
+		if (ps->display.explicitRefreshrate == 0)
+			ps->display.limitRefreshrate = false;
+	} else
+		ps->display.limitRefreshrate = false;
+
+	tmp = le32_to_cpu(pnon_clock_info->ulCapsAndSettings) &
+		ATOM_PPLIB_ENABLE_VARIBRIGHT;
+
+	ps->display.enableVariBright = (0 != tmp);
+
+	tmp = le32_to_cpu(pnon_clock_info->ulCapsAndSettings) &
+		ATOM_PPLIB_SWSTATE_MEMORY_DLL_OFF;
+
+	ps->memory.dllOff = (0 != tmp);
+
+	ps->memory.m3arb = (le32_to_cpu(pnon_clock_info->ulCapsAndSettings) &
+			    ATOM_PPLIB_M3ARB_MASK) >> ATOM_PPLIB_M3ARB_SHIFT;
+
+	ps->temperatures.min = PP_TEMPERATURE_UNITS_PER_CENTIGRADES *
+				     pnon_clock_info->ucMinTemperature;
+
+	ps->temperatures.max = PP_TEMPERATURE_UNITS_PER_CENTIGRADES *
+				     pnon_clock_info->ucMaxTemperature;
+
+	tmp = le32_to_cpu(pnon_clock_info->ulCapsAndSettings) &
+		ATOM_PPLIB_SOFTWARE_DISABLE_LOADBALANCING;
+
+	ps->software.disableLoadBalancing = tmp;
+
+	tmp = le32_to_cpu(pnon_clock_info->ulCapsAndSettings) &
+		ATOM_PPLIB_SOFTWARE_ENABLE_SLEEP_FOR_TIMESTAMPS;
+
+	ps->software.enableSleepForTimestamps = (0 != tmp);
+
+	ps->validation.supportedPowerLevels = pnon_clock_info->ucRequiredPower;
+
+	if (ATOM_PPLIB_NONCLOCKINFO_VER1 < version) {
+		ps->uvd_clocks.VCLK = pnon_clock_info->ulVCLK;
+		ps->uvd_clocks.DCLK = pnon_clock_info->ulDCLK;
+	} else {
+		ps->uvd_clocks.VCLK = 0;
+		ps->uvd_clocks.DCLK = 0;
+	}
+
+	return 0;
+}
+
+static ULONG size_of_entry_v2(ULONG num_dpm_levels)
+{
+	return (sizeof(UCHAR) + sizeof(UCHAR) +
+			(num_dpm_levels * sizeof(UCHAR)));
+}
+
+static const ATOM_PPLIB_STATE_V2 *get_state_entry_v2(
+					const StateArray * pstate_arrays,
+							 ULONG entry_index)
+{
+	ULONG i;
+	const ATOM_PPLIB_STATE_V2 *pstate;
+
+	pstate = pstate_arrays->states;
+	if (entry_index <= pstate_arrays->ucNumEntries) {
+		for (i = 0; i < entry_index; i++)
+			pstate = (ATOM_PPLIB_STATE_V2 *)(
+						  (unsigned long)pstate +
+			     size_of_entry_v2(pstate->ucNumDPMLevels));
+	}
+	return pstate;
+}
+
+
+static const ATOM_PPLIB_POWERPLAYTABLE *get_powerplay_table(
+				     struct pp_hwmgr *hwmgr)
+{
+	const void *table_addr = NULL;
+	uint8_t frev, crev;
+	uint16_t size;
+
+	table_addr = cgs_atom_get_data_table(hwmgr->device,
+			GetIndexIntoMasterTable(DATA, PowerPlayInfo),
+			&size, &frev, &crev);
+
+	hwmgr->soft_pp_table = table_addr;
+
+	return (const ATOM_PPLIB_POWERPLAYTABLE *)table_addr;
+}
+
+
+int pp_tables_get_num_of_entries(struct pp_hwmgr *hwmgr,
+				     unsigned long *num_of_entries)
+{
+	const StateArray *pstate_arrays;
+	const ATOM_PPLIB_POWERPLAYTABLE *powerplay_table = get_powerplay_table(hwmgr);
+
+	if (powerplay_table == NULL)
+		return -1;
+
+	if (powerplay_table->sHeader.ucTableFormatRevision >= 6) {
+		pstate_arrays = (StateArray *)(((unsigned long)powerplay_table) +
+					le16_to_cpu(powerplay_table->usStateArrayOffset));
+
+		*num_of_entries = (unsigned long)(pstate_arrays->ucNumEntries);
+	} else
+		*num_of_entries = (unsigned long)(powerplay_table->ucNumStates);
+
+	return 0;
+}
+
+int pp_tables_get_entry(struct pp_hwmgr *hwmgr,
+				unsigned long entry_index,
+				struct pp_power_state *ps,
+			 pp_tables_hw_clock_info_callback func)
+{
+	int i;
+	const StateArray *pstate_arrays;
+	const ATOM_PPLIB_STATE_V2 *pstate_entry_v2;
+	const ATOM_PPLIB_NONCLOCK_INFO *pnon_clock_info;
+	const ATOM_PPLIB_POWERPLAYTABLE *powerplay_table = get_powerplay_table(hwmgr);
+	int result = 0;
+	int res = 0;
+
+	const ClockInfoArray *pclock_arrays;
+
+	const NonClockInfoArray *pnon_clock_arrays;
+
+	const ATOM_PPLIB_STATE *pstate_entry;
+
+	if (powerplay_table == NULL)
+		return -1;
+
+	ps->classification.bios_index = entry_index;
+
+	if (powerplay_table->sHeader.ucTableFormatRevision >= 6) {
+		pstate_arrays = (StateArray *)(((unsigned long)powerplay_table) +
+					le16_to_cpu(powerplay_table->usStateArrayOffset));
+
+		if (entry_index > pstate_arrays->ucNumEntries)
+			return -1;
+
+		pstate_entry_v2 = get_state_entry_v2(pstate_arrays, entry_index);
+		pclock_arrays = (ClockInfoArray *)(((unsigned long)powerplay_table) +
+					le16_to_cpu(powerplay_table->usClockInfoArrayOffset));
+
+		pnon_clock_arrays = (NonClockInfoArray *)(((unsigned long)powerplay_table) +
+						le16_to_cpu(powerplay_table->usNonClockInfoArrayOffset));
+
+		pnon_clock_info = (ATOM_PPLIB_NONCLOCK_INFO *)((unsigned long)(pnon_clock_arrays->nonClockInfo) +
+					(pstate_entry_v2->nonClockInfoIndex * pnon_clock_arrays->ucEntrySize));
+
+		result = init_non_clock_fields(hwmgr, ps, pnon_clock_arrays->ucEntrySize, pnon_clock_info);
+
+		for (i = 0; i < pstate_entry_v2->ucNumDPMLevels; i++) {
+			const void *pclock_info = (const void *)(
+							(unsigned long)(pclock_arrays->clockInfo) +
+							(pstate_entry_v2->clockInfoIndex[i] * pclock_arrays->ucEntrySize));
+			res = func(hwmgr, &ps->hardware, i, pclock_info);
+			if ((0 == result) && (0 != res))
+				result = res;
+		}
+	} else {
+		if (entry_index > powerplay_table->ucNumStates)
+			return -1;
+
+		pstate_entry = (ATOM_PPLIB_STATE *)((unsigned long)powerplay_table + powerplay_table->usStateArrayOffset +
+				entry_index * powerplay_table->ucStateEntrySize);
+
+		pnon_clock_info = (ATOM_PPLIB_NONCLOCK_INFO *)((unsigned long)powerplay_table +
+						le16_to_cpu(powerplay_table->usNonClockInfoArrayOffset) +
+						pstate_entry->ucNonClockStateIndex *
+						powerplay_table->ucNonClockSize);
+
+		result = init_non_clock_fields(hwmgr, ps,
+							powerplay_table->ucNonClockSize,
+							pnon_clock_info);
+
+		for (i = 0; i < powerplay_table->ucStateEntrySize-1; i++) {
+			const void *pclock_info = (const void *)((unsigned long)powerplay_table +
+						le16_to_cpu(powerplay_table->usClockInfoArrayOffset) +
+						pstate_entry->ucClockStateIndices[i] *
+						powerplay_table->ucClockInfoSize);
+
+			int res = func(hwmgr, &ps->hardware, i, pclock_info);
+
+			if ((0 == result) && (0 != res))
+					result = res;
+		}
+	}
+
+	if ((0 == result) &&
+		(0 != (ps->classification.flags & PP_StateClassificationFlag_Boot)))
+		result = hwmgr->hwmgr_func->patch_boot_state(hwmgr, &(ps->hardware));
+
+	return result;
+}
+
+
+
+static int init_powerplay_tables(
+			struct pp_hwmgr *hwmgr,
+			const ATOM_PPLIB_POWERPLAYTABLE *powerplay_table
+)
+{
+	return 0;
+}
+
+
+static int init_thermal_controller(
+			struct pp_hwmgr *hwmgr,
+			const ATOM_PPLIB_POWERPLAYTABLE *powerplay_table)
+{
+	return 0;
+}
+
+static int init_overdrive_limits_V1_4(struct pp_hwmgr *hwmgr,
+			const ATOM_PPLIB_POWERPLAYTABLE *powerplay_table,
+			const ATOM_FIRMWARE_INFO_V1_4 *fw_info)
+{
+	hwmgr->platform_descriptor.overdriveLimit.engineClock =
+				le32_to_cpu(fw_info->ulASICMaxEngineClock);
+
+	hwmgr->platform_descriptor.overdriveLimit.memoryClock =
+				le32_to_cpu(fw_info->ulASICMaxMemoryClock);
+
+	hwmgr->platform_descriptor.maxOverdriveVDDC =
+		le32_to_cpu(fw_info->ul3DAccelerationEngineClock) & 0x7FF;
+
+	hwmgr->platform_descriptor.minOverdriveVDDC =
+			   le16_to_cpu(fw_info->usBootUpVDDCVoltage);
+
+	hwmgr->platform_descriptor.maxOverdriveVDDC =
+			   le16_to_cpu(fw_info->usBootUpVDDCVoltage);
+
+	hwmgr->platform_descriptor.overdriveVDDCStep = 0;
+	return 0;
+}
+
+static int init_overdrive_limits_V2_1(struct pp_hwmgr *hwmgr,
+			const ATOM_PPLIB_POWERPLAYTABLE *powerplay_table,
+			const ATOM_FIRMWARE_INFO_V2_1 *fw_info)
+{
+	const ATOM_PPLIB_POWERPLAYTABLE3 *powerplay_table3;
+	const ATOM_PPLIB_EXTENDEDHEADER *header;
+
+	if (le16_to_cpu(powerplay_table->usTableSize) <
+	    sizeof(ATOM_PPLIB_POWERPLAYTABLE3))
+		return 0;
+
+	powerplay_table3 = (const ATOM_PPLIB_POWERPLAYTABLE3 *)powerplay_table;
+
+	if (0 == powerplay_table3->usExtendendedHeaderOffset)
+		return 0;
+
+	header = (ATOM_PPLIB_EXTENDEDHEADER *)(((unsigned long) powerplay_table) +
+			le16_to_cpu(powerplay_table3->usExtendendedHeaderOffset));
+
+	hwmgr->platform_descriptor.overdriveLimit.engineClock = le32_to_cpu(header->ulMaxEngineClock);
+	hwmgr->platform_descriptor.overdriveLimit.memoryClock = le32_to_cpu(header->ulMaxMemoryClock);
+
+
+	hwmgr->platform_descriptor.minOverdriveVDDC = 0;
+	hwmgr->platform_descriptor.maxOverdriveVDDC = 0;
+	hwmgr->platform_descriptor.overdriveVDDCStep = 0;
+
+	return 0;
+}
+
+static int init_overdrive_limits(struct pp_hwmgr *hwmgr,
+			const ATOM_PPLIB_POWERPLAYTABLE *powerplay_table)
+{
+	int result;
+	uint8_t frev, crev;
+	uint16_t size;
+
+	const ATOM_COMMON_TABLE_HEADER *fw_info = NULL;
+
+	hwmgr->platform_descriptor.overdriveLimit.engineClock = 0;
+	hwmgr->platform_descriptor.overdriveLimit.memoryClock = 0;
+	hwmgr->platform_descriptor.minOverdriveVDDC = 0;
+	hwmgr->platform_descriptor.maxOverdriveVDDC = 0;
+
+	/* We assume here that fw_info is unchanged if this call fails.*/
+	fw_info = cgs_atom_get_data_table(hwmgr->device,
+			 GetIndexIntoMasterTable(DATA, FirmwareInfo),
+			 &size, &frev, &crev);
+
+	if ((fw_info->ucTableFormatRevision == 1)
+		&& (fw_info->usStructureSize >= sizeof(ATOM_FIRMWARE_INFO_V1_4)))
+		result = init_overdrive_limits_V1_4(hwmgr,
+				powerplay_table,
+				(const ATOM_FIRMWARE_INFO_V1_4 *)fw_info);
+
+	else if ((fw_info->ucTableFormatRevision == 2)
+		&& (fw_info->usStructureSize >= sizeof(ATOM_FIRMWARE_INFO_V2_1)))
+		result = init_overdrive_limits_V2_1(hwmgr,
+				powerplay_table,
+				(const ATOM_FIRMWARE_INFO_V2_1 *)fw_info);
+
+	if (hwmgr->platform_descriptor.overdriveLimit.engineClock > 0
+		&& hwmgr->platform_descriptor.overdriveLimit.memoryClock > 0
+		&& !phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
+			PHM_PlatformCaps_OverdriveDisabledByPowerBudget))
+		phm_cap_set(hwmgr->platform_descriptor.platformCaps,
+				PHM_PlatformCaps_ACOverdriveSupport);
+
+	return result;
+}
+
+static int get_uvd_clock_voltage_limit_table(struct pp_hwmgr *hwmgr,
+		struct phm_uvd_clock_voltage_dependency_table **ptable,
+		const ATOM_PPLIB_UVD_Clock_Voltage_Limit_Table *table,
+		const UVDClockInfoArray *array)
+{
+	unsigned long table_size, i;
+	struct phm_uvd_clock_voltage_dependency_table *uvd_table;
+
+	table_size = sizeof(unsigned long) +
+		 sizeof(struct phm_uvd_clock_voltage_dependency_table) *
+		 table->numEntries;
+
+	uvd_table = kzalloc(table_size, GFP_KERNEL);
+	if (NULL == uvd_table)
+		return -ENOMEM;
+
+	uvd_table->count = table->numEntries;
+
+	for (i = 0; i < table->numEntries; i++) {
+		const UVDClockInfo *entry =
+			&array->entries[table->entries[i].ucUVDClockInfoIndex];
+		uvd_table->entries[i].v = (unsigned long)le16_to_cpu(table->entries[i].usVoltage);
+		uvd_table->entries[i].vclk = ((unsigned long)entry->ucVClkHigh << 16)
+					 | le16_to_cpu(entry->usVClkLow);
+		uvd_table->entries[i].dclk = ((unsigned long)entry->ucDClkHigh << 16)
+					 | le16_to_cpu(entry->usDClkLow);
+	}
+
+	*ptable = uvd_table;
+
+	return 0;
+}
+
+static int get_vce_clock_voltage_limit_table(struct pp_hwmgr *hwmgr,
+		struct phm_vce_clock_voltage_dependency_table **ptable,
+		const ATOM_PPLIB_VCE_Clock_Voltage_Limit_Table *table,
+		const VCEClockInfoArray    *array)
+{
+	unsigned long table_size, i;
+	struct phm_vce_clock_voltage_dependency_table *vce_table = NULL;
+
+	table_size = sizeof(unsigned long) +
+			sizeof(struct phm_vce_clock_voltage_dependency_table)
+			* table->numEntries;
+
+	vce_table = kzalloc(table_size, GFP_KERNEL);
+	if (NULL == vce_table)
+		return -ENOMEM;
+
+	vce_table->count = table->numEntries;
+	for (i = 0; i < table->numEntries; i++) {
+		const VCEClockInfo *entry = &array->entries[table->entries[i].ucVCEClockInfoIndex];
+
+		vce_table->entries[i].v = (unsigned long)le16_to_cpu(table->entries[i].usVoltage);
+		vce_table->entries[i].evclk = ((unsigned long)entry->ucEVClkHigh << 16)
+					| le16_to_cpu(entry->usEVClkLow);
+		vce_table->entries[i].ecclk = ((unsigned long)entry->ucECClkHigh << 16)
+					| le16_to_cpu(entry->usECClkLow);
+	}
+
+	*ptable = vce_table;
+
+	return 0;
+}
+
+static int get_samu_clock_voltage_limit_table(struct pp_hwmgr *hwmgr,
+		 struct phm_samu_clock_voltage_dependency_table **ptable,
+		 const ATOM_PPLIB_SAMClk_Voltage_Limit_Table *table)
+{
+	unsigned long table_size, i;
+	struct phm_samu_clock_voltage_dependency_table *samu_table;
+
+	table_size = sizeof(unsigned long) +
+		sizeof(struct phm_samu_clock_voltage_dependency_table) *
+		table->numEntries;
+
+	samu_table = kzalloc(table_size, GFP_KERNEL);
+	if (NULL == samu_table)
+		return -ENOMEM;
+
+	samu_table->count = table->numEntries;
+
+	for (i = 0; i < table->numEntries; i++) {
+		samu_table->entries[i].v = (unsigned long)le16_to_cpu(table->entries[i].usVoltage);
+		samu_table->entries[i].samclk = ((unsigned long)table->entries[i].ucSAMClockHigh << 16)
+					 | le16_to_cpu(table->entries[i].usSAMClockLow);
+	}
+
+	*ptable = samu_table;
+
+	return 0;
+}
+
+static int get_acp_clock_voltage_limit_table(struct pp_hwmgr *hwmgr,
+		struct phm_acp_clock_voltage_dependency_table **ptable,
+		const ATOM_PPLIB_ACPClk_Voltage_Limit_Table *table)
+{
+	unsigned table_size, i;
+	struct phm_acp_clock_voltage_dependency_table *acp_table;
+
+	table_size = sizeof(unsigned long) +
+		sizeof(struct phm_acp_clock_voltage_dependency_table) *
+		table->numEntries;
+
+	acp_table = kzalloc(table_size, GFP_KERNEL);
+	if (NULL == acp_table)
+		return -ENOMEM;
+
+	acp_table->count = (unsigned long)table->numEntries;
+
+	for (i = 0; i < table->numEntries; i++) {
+		acp_table->entries[i].v = (unsigned long)le16_to_cpu(table->entries[i].usVoltage);
+		acp_table->entries[i].acpclk = ((unsigned long)table->entries[i].ucACPClockHigh << 16)
+					 | le16_to_cpu(table->entries[i].usACPClockLow);
+	}
+
+	*ptable = acp_table;
+
+	return 0;
+}
+
+static int init_clock_voltage_dependency(struct pp_hwmgr *hwmgr,
+			const ATOM_PPLIB_POWERPLAYTABLE *powerplay_table)
+{
+	ATOM_PPLIB_Clock_Voltage_Dependency_Table *table;
+	ATOM_PPLIB_Clock_Voltage_Limit_Table *limit_table;
+	int result = 0;
+
+	uint16_t vce_clock_info_array_offset;
+	uint16_t uvd_clock_info_array_offset;
+	uint16_t table_offset;
+
+	hwmgr->dyn_state.vddc_dependency_on_sclk = NULL;
+	hwmgr->dyn_state.vddci_dependency_on_mclk = NULL;
+	hwmgr->dyn_state.vddc_dependency_on_mclk = NULL;
+	hwmgr->dyn_state.vddc_dep_on_dal_pwrl = NULL;
+	hwmgr->dyn_state.mvdd_dependency_on_mclk = NULL;
+	hwmgr->dyn_state.vce_clock_voltage_dependency_table = NULL;
+	hwmgr->dyn_state.uvd_clock_voltage_dependency_table = NULL;
+	hwmgr->dyn_state.samu_clock_voltage_dependency_table = NULL;
+	hwmgr->dyn_state.acp_clock_voltage_dependency_table = NULL;
+	hwmgr->dyn_state.ppm_parameter_table = NULL;
+	hwmgr->dyn_state.vdd_gfx_dependency_on_sclk = NULL;
+
+	vce_clock_info_array_offset = get_vce_clock_info_array_offset(
+						hwmgr, powerplay_table);
+	table_offset = get_vce_clock_voltage_limit_table_offset(hwmgr,
+						powerplay_table);
+	if (vce_clock_info_array_offset > 0 && table_offset > 0) {
+		const VCEClockInfoArray *array = (const VCEClockInfoArray *)
+				(((unsigned long) powerplay_table) +
+				vce_clock_info_array_offset);
+		const ATOM_PPLIB_VCE_Clock_Voltage_Limit_Table *table =
+				(const ATOM_PPLIB_VCE_Clock_Voltage_Limit_Table *)
+				(((unsigned long) powerplay_table) + table_offset);
+		result = get_vce_clock_voltage_limit_table(hwmgr,
+				&hwmgr->dyn_state.vce_clock_voltage_dependency_table,
+				table, array);
+	}
+
+	uvd_clock_info_array_offset = get_uvd_clock_info_array_offset(hwmgr, powerplay_table);
+	table_offset = get_uvd_clock_voltage_limit_table_offset(hwmgr, powerplay_table);
+
+	if (uvd_clock_info_array_offset > 0 && table_offset > 0) {
+		const UVDClockInfoArray *array = (const UVDClockInfoArray *)
+				(((unsigned long) powerplay_table) +
+				uvd_clock_info_array_offset);
+		const ATOM_PPLIB_UVD_Clock_Voltage_Limit_Table *ptable =
+				(const ATOM_PPLIB_UVD_Clock_Voltage_Limit_Table *)
+				(((unsigned long) powerplay_table) + table_offset);
+		result = get_uvd_clock_voltage_limit_table(hwmgr,
+				&hwmgr->dyn_state.uvd_clock_voltage_dependency_table, ptable, array);
+	}
+
+	table_offset = get_samu_clock_voltage_limit_table_offset(hwmgr,
+							    powerplay_table);
+
+	if (table_offset > 0) {
+		const ATOM_PPLIB_SAMClk_Voltage_Limit_Table *ptable =
+				(const ATOM_PPLIB_SAMClk_Voltage_Limit_Table *)
+				(((unsigned long) powerplay_table) + table_offset);
+		result = get_samu_clock_voltage_limit_table(hwmgr,
+				&hwmgr->dyn_state.samu_clock_voltage_dependency_table, ptable);
+	}
+
+	table_offset = get_acp_clock_voltage_limit_table_offset(hwmgr,
+							     powerplay_table);
+
+	if (table_offset > 0) {
+		const ATOM_PPLIB_ACPClk_Voltage_Limit_Table *ptable =
+				(const ATOM_PPLIB_ACPClk_Voltage_Limit_Table *)
+				(((unsigned long) powerplay_table) + table_offset);
+		result = get_acp_clock_voltage_limit_table(hwmgr,
+				&hwmgr->dyn_state.acp_clock_voltage_dependency_table, ptable);
+	}
+
+	table_offset = get_cacp_tdp_table_offset(hwmgr, powerplay_table);
+	if (table_offset > 0) {
+		UCHAR rev_id = *(UCHAR *)(((unsigned long)powerplay_table) + table_offset);
+
+		if (rev_id > 0) {
+			const ATOM_PPLIB_POWERTUNE_Table_V1 *tune_table =
+				(const ATOM_PPLIB_POWERTUNE_Table_V1 *)
+				(((unsigned long) powerplay_table) + table_offset);
+			result = get_cac_tdp_table(hwmgr, &hwmgr->dyn_state.cac_dtp_table,
+				&tune_table->power_tune_table,
+				le16_to_cpu(tune_table->usMaximumPowerDeliveryLimit));
+			hwmgr->dyn_state.cac_dtp_table->usDefaultTargetOperatingTemp =
+				le16_to_cpu(tune_table->usTjMax);
+		} else {
+			const ATOM_PPLIB_POWERTUNE_Table *tune_table =
+				(const ATOM_PPLIB_POWERTUNE_Table *)
+				(((unsigned long) powerplay_table) + table_offset);
+			result = get_cac_tdp_table(hwmgr,
+				&hwmgr->dyn_state.cac_dtp_table,
+				&tune_table->power_tune_table, 255);
+		}
+	}
+
+	if (le16_to_cpu(powerplay_table->usTableSize) >=
+		sizeof(ATOM_PPLIB_POWERPLAYTABLE4)) {
+		const ATOM_PPLIB_POWERPLAYTABLE4 *powerplay_table4 =
+				(const ATOM_PPLIB_POWERPLAYTABLE4 *)powerplay_table;
+		if (0 != powerplay_table4->usVddcDependencyOnSCLKOffset) {
+			table = (ATOM_PPLIB_Clock_Voltage_Dependency_Table *)
+				(((unsigned long) powerplay_table4) +
+				powerplay_table4->usVddcDependencyOnSCLKOffset);
+			result = get_clock_voltage_dependency_table(hwmgr,
+				&hwmgr->dyn_state.vddc_dependency_on_sclk, table);
+		}
+
+		if (result == 0 && (0 != powerplay_table4->usVddciDependencyOnMCLKOffset)) {
+			table = (ATOM_PPLIB_Clock_Voltage_Dependency_Table *)
+				(((unsigned long) powerplay_table4) +
+				powerplay_table4->usVddciDependencyOnMCLKOffset);
+			result = get_clock_voltage_dependency_table(hwmgr,
+				&hwmgr->dyn_state.vddci_dependency_on_mclk, table);
+		}
+
+		if (result == 0 && (0 != powerplay_table4->usVddcDependencyOnMCLKOffset)) {
+			table = (ATOM_PPLIB_Clock_Voltage_Dependency_Table *)
+				(((unsigned long) powerplay_table4) +
+				powerplay_table4->usVddcDependencyOnMCLKOffset);
+			result = get_clock_voltage_dependency_table(hwmgr,
+				&hwmgr->dyn_state.vddc_dependency_on_mclk, table);
+		}
+
+		if (result == 0 && (0 != powerplay_table4->usMaxClockVoltageOnDCOffset)) {
+			limit_table = (ATOM_PPLIB_Clock_Voltage_Limit_Table *)
+				(((unsigned long) powerplay_table4) +
+				powerplay_table4->usMaxClockVoltageOnDCOffset);
+			result = get_clock_voltage_limit(hwmgr,
+				&hwmgr->dyn_state.max_clock_voltage_on_dc, limit_table);
+		}
+
+		if (result == 0 && (NULL != hwmgr->dyn_state.vddc_dependency_on_mclk) &&
+			(0 != hwmgr->dyn_state.vddc_dependency_on_mclk->count))
+			result = get_valid_clk(hwmgr, &hwmgr->dyn_state.valid_mclk_values,
+					hwmgr->dyn_state.vddc_dependency_on_mclk);
+
+		if(result == 0 && (NULL != hwmgr->dyn_state.vddc_dependency_on_sclk) &&
+			(0 != hwmgr->dyn_state.vddc_dependency_on_sclk->count))
+			result = get_valid_clk(hwmgr,
+				&hwmgr->dyn_state.valid_sclk_values,
+				hwmgr->dyn_state.vddc_dependency_on_sclk);
+
+		if (result == 0 && (0 != powerplay_table4->usMvddDependencyOnMCLKOffset)) {
+			table = (ATOM_PPLIB_Clock_Voltage_Dependency_Table *)
+				(((unsigned long) powerplay_table4) +
+				powerplay_table4->usMvddDependencyOnMCLKOffset);
+			result = get_clock_voltage_dependency_table(hwmgr,
+				&hwmgr->dyn_state.mvdd_dependency_on_mclk, table);
+		}
+	}
+
+	table_offset = get_sclk_vdd_gfx_clock_voltage_dependency_table_offset(hwmgr,
+								powerplay_table);
+
+	if (table_offset > 0) {
+		table = (ATOM_PPLIB_Clock_Voltage_Dependency_Table *)
+			(((unsigned long) powerplay_table) + table_offset);
+		result = get_clock_voltage_dependency_table(hwmgr,
+			&hwmgr->dyn_state.vdd_gfx_dependency_on_sclk, table);
+	}
+
+	return result;
+}
+
+static int get_cac_leakage_table(struct pp_hwmgr *hwmgr,
+				 struct phm_cac_leakage_table **ptable,
+				const ATOM_PPLIB_CAC_Leakage_Table *table)
+{
+	struct phm_cac_leakage_table  *cac_leakage_table;
+	unsigned long            table_size, i;
+
+	if (hwmgr == NULL || table == NULL || ptable == NULL)
+		return -EINVAL;
+
+	table_size = sizeof(ULONG) +
+		(sizeof(struct phm_cac_leakage_table) * table->ucNumEntries);
+
+	cac_leakage_table = kzalloc(table_size, GFP_KERNEL);
+
+	if (cac_leakage_table == NULL)
+		return -ENOMEM;
+
+	cac_leakage_table->count = (ULONG)table->ucNumEntries;
+
+	for (i = 0; i < cac_leakage_table->count; i++) {
+		if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
+				PHM_PlatformCaps_EVV)) {
+			cac_leakage_table->entries[i].Vddc1 = le16_to_cpu(table->entries[i].usVddc1);
+			cac_leakage_table->entries[i].Vddc2 = le16_to_cpu(table->entries[i].usVddc2);
+			cac_leakage_table->entries[i].Vddc3 = le16_to_cpu(table->entries[i].usVddc3);
+		} else {
+			cac_leakage_table->entries[i].Vddc    = le16_to_cpu(table->entries[i].usVddc);
+			cac_leakage_table->entries[i].Leakage = le32_to_cpu(table->entries[i].ulLeakageValue);
+		}
+	}
+
+	*ptable = cac_leakage_table;
+
+	return 0;
+}
+
+static int get_platform_power_management_table(struct pp_hwmgr *hwmgr,
+			ATOM_PPLIB_PPM_Table *atom_ppm_table)
+{
+	struct phm_ppm_table *ptr = kzalloc(sizeof(struct phm_ppm_table), GFP_KERNEL);
+
+	if (NULL == ptr)
+		return -ENOMEM;
+
+	ptr->ppm_design            = atom_ppm_table->ucPpmDesign;
+	ptr->cpu_core_number        = le16_to_cpu(atom_ppm_table->usCpuCoreNumber);
+	ptr->platform_tdp          = le32_to_cpu(atom_ppm_table->ulPlatformTDP);
+	ptr->small_ac_platform_tdp   = le32_to_cpu(atom_ppm_table->ulSmallACPlatformTDP);
+	ptr->platform_tdc          = le32_to_cpu(atom_ppm_table->ulPlatformTDC);
+	ptr->small_ac_platform_tdc   = le32_to_cpu(atom_ppm_table->ulSmallACPlatformTDC);
+	ptr->apu_tdp               = le32_to_cpu(atom_ppm_table->ulApuTDP);
+	ptr->dgpu_tdp              = le32_to_cpu(atom_ppm_table->ulDGpuTDP);
+	ptr->dgpu_ulv_power         = le32_to_cpu(atom_ppm_table->ulDGpuUlvPower);
+	ptr->tj_max                = le32_to_cpu(atom_ppm_table->ulTjmax);
+	hwmgr->dyn_state.ppm_parameter_table = ptr;
+
+	return 0;
+}
+
+static int init_dpm2_parameters(struct pp_hwmgr *hwmgr,
+			const ATOM_PPLIB_POWERPLAYTABLE *powerplay_table)
+{
+	int result = 0;
+
+	if (le16_to_cpu(powerplay_table->usTableSize) >=
+	    sizeof(ATOM_PPLIB_POWERPLAYTABLE5)) {
+		const  ATOM_PPLIB_POWERPLAYTABLE5 *ptable5 =
+				(const ATOM_PPLIB_POWERPLAYTABLE5 *)powerplay_table;
+		const  ATOM_PPLIB_POWERPLAYTABLE4 *ptable4 =
+				(const ATOM_PPLIB_POWERPLAYTABLE4 *)
+				(&ptable5->basicTable4);
+		const  ATOM_PPLIB_POWERPLAYTABLE3 *ptable3 =
+				(const ATOM_PPLIB_POWERPLAYTABLE3 *)
+				(&ptable4->basicTable3);
+		const  ATOM_PPLIB_EXTENDEDHEADER  *extended_header;
+		uint16_t table_offset;
+		ATOM_PPLIB_PPM_Table *atom_ppm_table;
+
+		hwmgr->platform_descriptor.TDPLimit     = le32_to_cpu(ptable5->ulTDPLimit);
+		hwmgr->platform_descriptor.nearTDPLimit = le32_to_cpu(ptable5->ulNearTDPLimit);
+
+		hwmgr->platform_descriptor.TDPODLimit   = le16_to_cpu(ptable5->usTDPODLimit);
+		hwmgr->platform_descriptor.TDPAdjustment = 0;
+
+		hwmgr->platform_descriptor.VidAdjustment = 0;
+		hwmgr->platform_descriptor.VidAdjustmentPolarity = 0;
+		hwmgr->platform_descriptor.VidMinLimit     = 0;
+		hwmgr->platform_descriptor.VidMaxLimit     = 1500000;
+		hwmgr->platform_descriptor.VidStep         = 6250;
+
+		hwmgr->platform_descriptor.nearTDPLimitAdjusted = le32_to_cpu(ptable5->ulNearTDPLimit);
+
+		if (hwmgr->platform_descriptor.TDPODLimit != 0)
+			phm_cap_set(hwmgr->platform_descriptor.platformCaps,
+					PHM_PlatformCaps_PowerControl);
+
+		hwmgr->platform_descriptor.SQRampingThreshold = le32_to_cpu(ptable5->ulSQRampingThreshold);
+
+		hwmgr->platform_descriptor.CACLeakage = le32_to_cpu(ptable5->ulCACLeakage);
+
+		hwmgr->dyn_state.cac_leakage_table = NULL;
+
+		if (0 != ptable5->usCACLeakageTableOffset) {
+			const ATOM_PPLIB_CAC_Leakage_Table *pCAC_leakage_table =
+				(ATOM_PPLIB_CAC_Leakage_Table *)(((unsigned long)ptable5) +
+				le16_to_cpu(ptable5->usCACLeakageTableOffset));
+			result = get_cac_leakage_table(hwmgr,
+				&hwmgr->dyn_state.cac_leakage_table, pCAC_leakage_table);
+		}
+
+		hwmgr->platform_descriptor.LoadLineSlope = le16_to_cpu(ptable5->usLoadLineSlope);
+
+		hwmgr->dyn_state.ppm_parameter_table = NULL;
+
+		if (0 != ptable3->usExtendendedHeaderOffset) {
+			extended_header = (const ATOM_PPLIB_EXTENDEDHEADER *)
+					(((unsigned long)powerplay_table) +
+					le16_to_cpu(ptable3->usExtendendedHeaderOffset));
+			if ((extended_header->usPPMTableOffset > 0) &&
+				le16_to_cpu(extended_header->usSize) >=
+				    SIZE_OF_ATOM_PPLIB_EXTENDEDHEADER_V5) {
+				table_offset = le16_to_cpu(extended_header->usPPMTableOffset);
+				atom_ppm_table = (ATOM_PPLIB_PPM_Table *)
+					(((unsigned long)powerplay_table) + table_offset);
+				if (0 == get_platform_power_management_table(hwmgr, atom_ppm_table))
+					phm_cap_set(hwmgr->platform_descriptor.platformCaps,
+						PHM_PlatformCaps_EnablePlatformPowerManagement);
+			}
+		}
+	}
+	return result;
+}
+
+static int init_phase_shedding_table(struct pp_hwmgr *hwmgr,
+		const ATOM_PPLIB_POWERPLAYTABLE *powerplay_table)
+{
+	if (le16_to_cpu(powerplay_table->usTableSize) >=
+	    sizeof(ATOM_PPLIB_POWERPLAYTABLE4)) {
+		const ATOM_PPLIB_POWERPLAYTABLE4 *powerplay_table4 =
+				(const ATOM_PPLIB_POWERPLAYTABLE4 *)powerplay_table;
+
+		if (0 != powerplay_table4->usVddcPhaseShedLimitsTableOffset) {
+			const ATOM_PPLIB_PhaseSheddingLimits_Table *ptable =
+				(ATOM_PPLIB_PhaseSheddingLimits_Table *)
+				(((unsigned long)powerplay_table4) +
+				le16_to_cpu(powerplay_table4->usVddcPhaseShedLimitsTableOffset));
+			struct phm_phase_shedding_limits_table *table;
+			unsigned long size, i;
+
+
+			size = sizeof(unsigned long) +
+				(sizeof(struct phm_phase_shedding_limits_table) *
+				ptable->ucNumEntries);
+
+			table = kzalloc(size, GFP_KERNEL);
+
+			if (table == NULL)
+				return -ENOMEM;
+
+			table->count = (unsigned long)ptable->ucNumEntries;
+
+			for (i = 0; i < table->count; i++) {
+				table->entries[i].Voltage = (unsigned long)le16_to_cpu(ptable->entries[i].usVoltage);
+				table->entries[i].Sclk    = ((unsigned long)ptable->entries[i].ucSclkHigh << 16)
+							| le16_to_cpu(ptable->entries[i].usSclkLow);
+				table->entries[i].Mclk    = ((unsigned long)ptable->entries[i].ucMclkHigh << 16)
+							| le16_to_cpu(ptable->entries[i].usMclkLow);
+			}
+			hwmgr->dyn_state.vddc_phase_shed_limits_table = table;
+		}
+	}
+
+	return 0;
+}
+
+int get_number_of_vce_state_table_entries(
+						  struct pp_hwmgr *hwmgr)
+{
+	const ATOM_PPLIB_POWERPLAYTABLE *table =
+					     get_powerplay_table(hwmgr);
+	const ATOM_PPLIB_VCE_State_Table *vce_table =
+				    get_vce_state_table(hwmgr, table);
+
+	if (vce_table > 0)
+		return vce_table->numEntries;
+
+	return 0;
+}
+
+int get_vce_state_table_entry(struct pp_hwmgr *hwmgr,
+							unsigned long i,
+							struct PP_VCEState *vce_state,
+							void **clock_info,
+							unsigned long *flag)
+{
+	const ATOM_PPLIB_POWERPLAYTABLE *powerplay_table = get_powerplay_table(hwmgr);
+
+	const ATOM_PPLIB_VCE_State_Table *vce_state_table = get_vce_state_table(hwmgr, powerplay_table);
+
+	unsigned short vce_clock_info_array_offset = get_vce_clock_info_array_offset(hwmgr, powerplay_table);
+
+	const VCEClockInfoArray *vce_clock_info_array = (const VCEClockInfoArray *)(((unsigned long) powerplay_table) + vce_clock_info_array_offset);
+
+	const ClockInfoArray *clock_arrays = (ClockInfoArray *)(((unsigned long)powerplay_table) + powerplay_table->usClockInfoArrayOffset);
+
+	const ATOM_PPLIB_VCE_State_Record *record = &vce_state_table->entries[i];
+
+	const VCEClockInfo *vce_clock_info = &vce_clock_info_array->entries[record->ucVCEClockInfoIndex];
+
+	unsigned long clockInfoIndex = record->ucClockInfoIndex & 0x3F;
+
+	*flag = (record->ucClockInfoIndex >> NUM_BITS_CLOCK_INFO_ARRAY_INDEX);
+
+	vce_state->evclk = ((uint32_t)vce_clock_info->ucEVClkHigh << 16) | vce_clock_info->usEVClkLow;
+	vce_state->ecclk = ((uint32_t)vce_clock_info->ucECClkHigh << 16) | vce_clock_info->usECClkLow;
+
+	*clock_info = (void *)((unsigned long)(clock_arrays->clockInfo) + (clockInfoIndex * clock_arrays->ucEntrySize));
+
+	return 0;
+}
+
+
+static int pp_tables_initialize(struct pp_hwmgr *hwmgr)
+{
+	int result;
+	const ATOM_PPLIB_POWERPLAYTABLE *powerplay_table;
+
+	hwmgr->need_pp_table_upload = true;
+
+	powerplay_table = get_powerplay_table(hwmgr);
+
+	result = init_powerplay_tables(hwmgr, powerplay_table);
+
+	PP_ASSERT_WITH_CODE((result == 0),
+			    "init_powerplay_tables failed", return result);
+
+	result = set_platform_caps(hwmgr,
+				le32_to_cpu(powerplay_table->ulPlatformCaps));
+
+	PP_ASSERT_WITH_CODE((result == 0),
+			    "set_platform_caps failed", return result);
+
+	result = init_thermal_controller(hwmgr, powerplay_table);
+
+	PP_ASSERT_WITH_CODE((result == 0),
+			    "init_thermal_controller failed", return result);
+
+	result = init_overdrive_limits(hwmgr, powerplay_table);
+
+	PP_ASSERT_WITH_CODE((result == 0),
+			    "init_overdrive_limits failed", return result);
+
+	result = init_clock_voltage_dependency(hwmgr,
+					       powerplay_table);
+
+	PP_ASSERT_WITH_CODE((result == 0),
+			    "init_clock_voltage_dependency failed", return result);
+
+	result = init_dpm2_parameters(hwmgr, powerplay_table);
+
+	PP_ASSERT_WITH_CODE((result == 0),
+			    "init_dpm2_parameters failed", return result);
+
+	result = init_phase_shedding_table(hwmgr, powerplay_table);
+
+	PP_ASSERT_WITH_CODE((result == 0),
+			    "init_phase_shedding_table failed", return result);
+
+	return result;
+}
+
+static int pp_tables_uninitialize(struct pp_hwmgr *hwmgr)
+{
+	if (NULL != hwmgr->soft_pp_table) {
+		kfree(hwmgr->soft_pp_table);
+		hwmgr->soft_pp_table = NULL;
+	}
+
+	if (NULL != hwmgr->dyn_state.vddc_dependency_on_sclk) {
+		kfree(hwmgr->dyn_state.vddc_dependency_on_sclk);
+		hwmgr->dyn_state.vddc_dependency_on_sclk = NULL;
+	}
+
+	if (NULL != hwmgr->dyn_state.vddci_dependency_on_mclk) {
+		kfree(hwmgr->dyn_state.vddci_dependency_on_mclk);
+		hwmgr->dyn_state.vddci_dependency_on_mclk = NULL;
+	}
+
+	if (NULL != hwmgr->dyn_state.vddc_dependency_on_mclk) {
+		kfree(hwmgr->dyn_state.vddc_dependency_on_mclk);
+		hwmgr->dyn_state.vddc_dependency_on_mclk = NULL;
+	}
+
+	if (NULL != hwmgr->dyn_state.mvdd_dependency_on_mclk) {
+		kfree(hwmgr->dyn_state.mvdd_dependency_on_mclk);
+		hwmgr->dyn_state.mvdd_dependency_on_mclk = NULL;
+	}
+
+	if (NULL != hwmgr->dyn_state.valid_mclk_values) {
+		kfree(hwmgr->dyn_state.valid_mclk_values);
+		hwmgr->dyn_state.valid_mclk_values = NULL;
+	}
+
+	if (NULL != hwmgr->dyn_state.valid_sclk_values) {
+		kfree(hwmgr->dyn_state.valid_sclk_values);
+		hwmgr->dyn_state.valid_sclk_values = NULL;
+	}
+
+	if (NULL != hwmgr->dyn_state.cac_leakage_table) {
+		kfree(hwmgr->dyn_state.cac_leakage_table);
+		hwmgr->dyn_state.cac_leakage_table = NULL;
+	}
+
+	if (NULL != hwmgr->dyn_state.vddc_phase_shed_limits_table) {
+		kfree(hwmgr->dyn_state.vddc_phase_shed_limits_table);
+		hwmgr->dyn_state.vddc_phase_shed_limits_table = NULL;
+	}
+
+	if (NULL != hwmgr->dyn_state.vce_clock_voltage_dependency_table) {
+		kfree(hwmgr->dyn_state.vce_clock_voltage_dependency_table);
+		hwmgr->dyn_state.vce_clock_voltage_dependency_table = NULL;
+	}
+
+	if (NULL != hwmgr->dyn_state.uvd_clock_voltage_dependency_table) {
+		kfree(hwmgr->dyn_state.uvd_clock_voltage_dependency_table);
+		hwmgr->dyn_state.uvd_clock_voltage_dependency_table = NULL;
+	}
+
+	if (NULL != hwmgr->dyn_state.samu_clock_voltage_dependency_table) {
+		kfree(hwmgr->dyn_state.samu_clock_voltage_dependency_table);
+		hwmgr->dyn_state.samu_clock_voltage_dependency_table = NULL;
+	}
+
+	if (NULL != hwmgr->dyn_state.acp_clock_voltage_dependency_table) {
+		kfree(hwmgr->dyn_state.acp_clock_voltage_dependency_table);
+		hwmgr->dyn_state.acp_clock_voltage_dependency_table = NULL;
+	}
+
+	if (NULL != hwmgr->dyn_state.cac_dtp_table) {
+		kfree(hwmgr->dyn_state.cac_dtp_table);
+		hwmgr->dyn_state.cac_dtp_table = NULL;
+	}
+
+	if (NULL != hwmgr->dyn_state.ppm_parameter_table) {
+		kfree(hwmgr->dyn_state.ppm_parameter_table);
+		hwmgr->dyn_state.ppm_parameter_table = NULL;
+	}
+
+	if (NULL != hwmgr->dyn_state.vdd_gfx_dependency_on_sclk) {
+		kfree(hwmgr->dyn_state.vdd_gfx_dependency_on_sclk);
+		hwmgr->dyn_state.vdd_gfx_dependency_on_sclk = NULL;
+	}
+
+	if (NULL != hwmgr->dyn_state.vq_budgeting_table) {
+		kfree(hwmgr->dyn_state.vq_budgeting_table);
+		hwmgr->dyn_state.vq_budgeting_table = NULL;
+	}
+
+	return 0;
+}
+
+const struct pp_table_func pptable_funcs = {
+	.pptable_init = pp_tables_initialize,
+	.pptable_fini = pp_tables_uninitialize,
+	.pptable_get_number_of_vce_state_table_entries =
+				get_number_of_vce_state_table_entries,
+	.pptable_get_vce_state_table_entry =
+						get_vce_state_table_entry,
+};
+
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/powerplay/hwmgr/processpptables.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2015 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ * Interface Functions related to the BIOS PowerPlay Tables.
+ *
+ */
+
+#ifndef PROCESSPPTABLES_H
+#define PROCESSPPTABLES_H
+
+struct pp_hwmgr;
+struct pp_power_state;
+struct pp_hw_power_state;
+
+extern const struct pp_table_func pptable_funcs;
+
+typedef int (*pp_tables_hw_clock_info_callback)(struct pp_hwmgr *hwmgr,
+					struct pp_hw_power_state *hw_ps,
+							unsigned int index,
+						 const void *clock_info);
+
+int pp_tables_get_num_of_entries(struct pp_hwmgr *hwmgr,
+				     unsigned long *num_of_entries);
+
+int pp_tables_get_entry(struct pp_hwmgr *hwmgr,
+						unsigned long entry_index,
+						struct pp_power_state *ps,
+				pp_tables_hw_clock_info_callback func);
+
+#endif
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_clockpowergating.c
@@ -0,0 +1,350 @@
+/*
+ * Copyright 2015 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#include "hwmgr.h"
+#include "tonga_clockpowergating.h"
+#include "tonga_ppsmc.h"
+#include "tonga_hwmgr.h"
+
+int tonga_phm_powerdown_uvd(struct pp_hwmgr *hwmgr)
+{
+	if (phm_cf_want_uvd_power_gating(hwmgr))
+		return smum_send_msg_to_smc(hwmgr->smumgr,
+						     PPSMC_MSG_UVDPowerOFF);
+	return 0;
+}
+
+int tonga_phm_powerup_uvd(struct pp_hwmgr *hwmgr)
+{
+	if (phm_cf_want_uvd_power_gating(hwmgr)) {
+		if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
+				  PHM_PlatformCaps_UVDDynamicPowerGating)) {
+			return smum_send_msg_to_smc_with_parameter(hwmgr->smumgr,
+								PPSMC_MSG_UVDPowerON, 1);
+		} else {
+			return smum_send_msg_to_smc_with_parameter(hwmgr->smumgr,
+								PPSMC_MSG_UVDPowerON, 0);
+		}
+	}
+
+	return 0;
+}
+
+int tonga_phm_powerdown_vce(struct pp_hwmgr *hwmgr)
+{
+	if (phm_cf_want_vce_power_gating(hwmgr))
+		return smum_send_msg_to_smc(hwmgr->smumgr,
+						  PPSMC_MSG_VCEPowerOFF);
+	return 0;
+}
+
+int tonga_phm_powerup_vce(struct pp_hwmgr *hwmgr)
+{
+	if (phm_cf_want_vce_power_gating(hwmgr))
+		return smum_send_msg_to_smc(hwmgr->smumgr,
+						  PPSMC_MSG_VCEPowerON);
+	return 0;
+}
+
+int tonga_phm_set_asic_block_gating(struct pp_hwmgr *hwmgr, enum PHM_AsicBlock block, enum PHM_ClockGateSetting gating)
+{
+	int ret = 0;
+
+	switch (block) {
+	case PHM_AsicBlock_UVD_MVC:
+	case PHM_AsicBlock_UVD:
+	case PHM_AsicBlock_UVD_HD:
+	case PHM_AsicBlock_UVD_SD:
+		if (gating == PHM_ClockGateSetting_StaticOff)
+			ret = tonga_phm_powerdown_uvd(hwmgr);
+		else
+			ret = tonga_phm_powerup_uvd(hwmgr);
+		break;
+	case PHM_AsicBlock_GFX:
+	default:
+		break;
+	}
+
+	return ret;
+}
+
+int tonga_phm_disable_clock_power_gating(struct pp_hwmgr *hwmgr)
+{
+	struct tonga_hwmgr *data = (struct tonga_hwmgr *)(hwmgr->backend);
+
+	data->uvd_power_gated = false;
+	data->vce_power_gated = false;
+
+	tonga_phm_powerup_uvd(hwmgr);
+	tonga_phm_powerup_vce(hwmgr);
+
+	return 0;
+}
+
+int tonga_phm_powergate_uvd(struct pp_hwmgr *hwmgr, bool bgate)
+{
+	struct tonga_hwmgr *data = (struct tonga_hwmgr *)(hwmgr->backend);
+
+	if (data->uvd_power_gated == bgate)
+		return 0;
+
+	data->uvd_power_gated = bgate;
+
+	if (bgate) {
+		cgs_set_clockgating_state(hwmgr->device,
+						AMD_IP_BLOCK_TYPE_UVD,
+						AMD_CG_STATE_UNGATE);
+		cgs_set_powergating_state(hwmgr->device,
+						AMD_IP_BLOCK_TYPE_UVD,
+						AMD_PG_STATE_GATE);
+		tonga_update_uvd_dpm(hwmgr, true);
+		tonga_phm_powerdown_uvd(hwmgr);
+	} else {
+		tonga_phm_powerup_uvd(hwmgr);
+		cgs_set_powergating_state(hwmgr->device,
+						AMD_IP_BLOCK_TYPE_UVD,
+						AMD_PG_STATE_UNGATE);
+		cgs_set_clockgating_state(hwmgr->device,
+						AMD_IP_BLOCK_TYPE_UVD,
+						AMD_PG_STATE_GATE);
+
+		tonga_update_uvd_dpm(hwmgr, false);
+	}
+
+	return 0;
+}
+
+int tonga_phm_powergate_vce(struct pp_hwmgr *hwmgr, bool bgate)
+{
+	struct tonga_hwmgr *data = (struct tonga_hwmgr *)(hwmgr->backend);
+	struct phm_set_power_state_input states;
+	const struct pp_power_state  *pcurrent;
+	struct pp_power_state  *requested;
+
+	pcurrent = hwmgr->current_ps;
+	requested = hwmgr->request_ps;
+
+	states.pcurrent_state = &(pcurrent->hardware);
+	states.pnew_state = &(requested->hardware);
+
+	if (phm_cf_want_vce_power_gating(hwmgr)) {
+		if (data->vce_power_gated != bgate) {
+			if (bgate) {
+				cgs_set_clockgating_state(
+							hwmgr->device,
+							AMD_IP_BLOCK_TYPE_VCE,
+							AMD_CG_STATE_UNGATE);
+				cgs_set_powergating_state(
+							hwmgr->device,
+							AMD_IP_BLOCK_TYPE_VCE,
+							AMD_PG_STATE_GATE);
+				tonga_enable_disable_vce_dpm(hwmgr, false);
+				data->vce_power_gated = true;
+			} else {
+				tonga_phm_powerup_vce(hwmgr);
+				data->vce_power_gated = false;
+				cgs_set_powergating_state(
+							hwmgr->device,
+							AMD_IP_BLOCK_TYPE_VCE,
+							AMD_PG_STATE_UNGATE);
+				cgs_set_clockgating_state(
+							hwmgr->device,
+							AMD_IP_BLOCK_TYPE_VCE,
+							AMD_PG_STATE_GATE);
+
+				tonga_update_vce_dpm(hwmgr, &states);
+				tonga_enable_disable_vce_dpm(hwmgr, true);
+				return 0;
+			}
+		}
+	} else {
+		tonga_update_vce_dpm(hwmgr, &states);
+		tonga_enable_disable_vce_dpm(hwmgr, true);
+		return 0;
+	}
+
+	if (!data->vce_power_gated)
+		tonga_update_vce_dpm(hwmgr, &states);
+
+	return 0;
+}
+
+int tonga_phm_update_clock_gatings(struct pp_hwmgr *hwmgr,
+					const uint32_t *msg_id)
+{
+	PPSMC_Msg msg;
+	uint32_t value;
+
+	switch ((*msg_id & PP_GROUP_MASK) >> PP_GROUP_SHIFT) {
+	case PP_GROUP_GFX:
+		switch ((*msg_id & PP_BLOCK_MASK) >> PP_BLOCK_SHIFT) {
+		case PP_BLOCK_GFX_CG:
+			if (PP_STATE_SUPPORT_CG & *msg_id) {
+				msg = ((*msg_id & PP_STATE_MASK) & PP_STATE_CG)
+				  ? PPSMC_MSG_EnableClockGatingFeature
+				  : PPSMC_MSG_DisableClockGatingFeature;
+				value = CG_GFX_CGCG_MASK;
+
+				if (0 != smum_send_msg_to_smc_with_parameter(hwmgr->smumgr, msg, value))
+					return -1;
+			}
+			if (PP_STATE_SUPPORT_LS & *msg_id) {
+				msg = (*msg_id & PP_STATE_MASK) & PP_STATE_LS
+					? PPSMC_MSG_EnableClockGatingFeature
+					: PPSMC_MSG_DisableClockGatingFeature;
+				value = CG_GFX_CGLS_MASK;
+
+				if (0 != smum_send_msg_to_smc_with_parameter(hwmgr->smumgr, msg, value))
+					return -1;
+			}
+			break;
+
+		case PP_BLOCK_GFX_MG:
+			/* For GFX MGCG, there are three different ones;
+			 * CPF, RLC, and all others.  CPF MGCG will not be used for Tonga.
+			 * For GFX MGLS, Tonga will not support it.
+			 * */
+			if (PP_STATE_SUPPORT_CG & *msg_id) {
+				msg = ((*msg_id & PP_STATE_MASK) & PP_STATE_CG)
+				? PPSMC_MSG_EnableClockGatingFeature
+				: PPSMC_MSG_DisableClockGatingFeature;
+				value = (CG_RLC_MGCG_MASK | CG_GFX_OTHERS_MGCG_MASK);
+
+				if (0 != smum_send_msg_to_smc_with_parameter(hwmgr->smumgr, msg, value))
+					return -1;
+			}
+			break;
+
+		default:
+			return -1;
+		}
+		break;
+
+	case PP_GROUP_SYS:
+		switch ((*msg_id & PP_BLOCK_MASK) >> PP_BLOCK_SHIFT) {
+		case PP_BLOCK_SYS_BIF:
+			if (PP_STATE_SUPPORT_LS & *msg_id) {
+				msg = (*msg_id & PP_STATE_MASK) & PP_STATE_LS
+				? PPSMC_MSG_EnableClockGatingFeature
+				: PPSMC_MSG_DisableClockGatingFeature;
+				value = CG_SYS_BIF_MGLS_MASK;
+
+				if (0 != smum_send_msg_to_smc_with_parameter(hwmgr->smumgr, msg, value))
+					return -1;
+			}
+			break;
+
+		case PP_BLOCK_SYS_MC:
+			if (PP_STATE_SUPPORT_CG & *msg_id) {
+				msg = ((*msg_id & PP_STATE_MASK) & PP_STATE_CG)
+				? PPSMC_MSG_EnableClockGatingFeature
+				: PPSMC_MSG_DisableClockGatingFeature;
+				value = CG_SYS_MC_MGCG_MASK;
+
+				if (0 != smum_send_msg_to_smc_with_parameter(hwmgr->smumgr, msg, value))
+					return -1;
+			}
+
+			if (PP_STATE_SUPPORT_LS & *msg_id) {
+				msg = (*msg_id & PP_STATE_MASK) & PP_STATE_LS
+				? PPSMC_MSG_EnableClockGatingFeature
+				: PPSMC_MSG_DisableClockGatingFeature;
+				value = CG_SYS_MC_MGLS_MASK;
+
+				if (0 != smum_send_msg_to_smc_with_parameter(hwmgr->smumgr, msg, value))
+					return -1;
+
+			}
+			break;
+
+		case PP_BLOCK_SYS_HDP:
+			if (PP_STATE_SUPPORT_CG & *msg_id) {
+				msg = ((*msg_id & PP_STATE_MASK) & PP_STATE_CG)
+					? PPSMC_MSG_EnableClockGatingFeature
+					: PPSMC_MSG_DisableClockGatingFeature;
+				value = CG_SYS_HDP_MGCG_MASK;
+
+				if (0 != smum_send_msg_to_smc_with_parameter(hwmgr->smumgr, msg, value))
+					return -1;
+			}
+
+			if (PP_STATE_SUPPORT_LS & *msg_id) {
+				msg = (*msg_id & PP_STATE_MASK) & PP_STATE_LS
+					? PPSMC_MSG_EnableClockGatingFeature
+					: PPSMC_MSG_DisableClockGatingFeature;
+
+				value = CG_SYS_HDP_MGLS_MASK;
+
+				if (0 != smum_send_msg_to_smc_with_parameter(hwmgr->smumgr, msg, value))
+					return -1;
+			}
+			break;
+
+		case PP_BLOCK_SYS_SDMA:
+			if (PP_STATE_SUPPORT_CG & *msg_id) {
+				msg = ((*msg_id & PP_STATE_MASK) & PP_STATE_CG)
+				? PPSMC_MSG_EnableClockGatingFeature
+				: PPSMC_MSG_DisableClockGatingFeature;
+				value = CG_SYS_SDMA_MGCG_MASK;
+
+				if (0 != smum_send_msg_to_smc_with_parameter(hwmgr->smumgr, msg, value))
+					return -1;
+			}
+
+			if (PP_STATE_SUPPORT_LS & *msg_id) {
+				msg = (*msg_id & PP_STATE_MASK) & PP_STATE_LS
+				? PPSMC_MSG_EnableClockGatingFeature
+				: PPSMC_MSG_DisableClockGatingFeature;
+
+				value = CG_SYS_SDMA_MGLS_MASK;
+
+				if (0 != smum_send_msg_to_smc_with_parameter(hwmgr->smumgr, msg, value))
+					return -1;
+			}
+			break;
+
+		case PP_BLOCK_SYS_ROM:
+			if (PP_STATE_SUPPORT_CG & *msg_id) {
+				msg = ((*msg_id & PP_STATE_MASK) & PP_STATE_CG)
+				? PPSMC_MSG_EnableClockGatingFeature
+				: PPSMC_MSG_DisableClockGatingFeature;
+				value = CG_SYS_ROM_MASK;
+
+				if (0 != smum_send_msg_to_smc_with_parameter(hwmgr->smumgr, msg, value))
+					return -1;
+			}
+			break;
+
+		default:
+			return -1;
+
+		}
+		break;
+
+	default:
+		return -1;
+
+	}
+
+	return 0;
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_clockpowergating.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2015 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#ifndef _TONGA_CLOCK_POWER_GATING_H_
+#define _TONGA_CLOCK_POWER_GATING_H_
+
+#include "tonga_hwmgr.h"
+#include "pp_asicblocks.h"
+
+extern int tonga_phm_set_asic_block_gating(struct pp_hwmgr *hwmgr, enum PHM_AsicBlock block, enum PHM_ClockGateSetting gating);
+extern int tonga_phm_powergate_vce(struct pp_hwmgr *hwmgr, bool bgate);
+extern int tonga_phm_powergate_uvd(struct pp_hwmgr *hwmgr, bool bgate);
+extern int tonga_phm_powerdown_uvd(struct pp_hwmgr *hwmgr);
+extern int tonga_phm_disable_clock_power_gating(struct pp_hwmgr *hwmgr);
+extern int tonga_phm_update_clock_gatings(struct pp_hwmgr *hwmgr, const uint32_t *msg_id);
+#endif /* _TONGA_CLOCK_POWER_GATING_H_ */
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_dyn_defaults.h
@@ -0,0 +1,107 @@
+/*
+ * Copyright 2015 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+#ifndef TONGA_DYN_DEFAULTS_H
+#define TONGA_DYN_DEFAULTS_H
+
+
+/** \file
+ * Volcanic Islands Dynamic default parameters.
+ */
+
+enum TONGAdpm_TrendDetection {
+	TONGAdpm_TrendDetection_AUTO,
+	TONGAdpm_TrendDetection_UP,
+	TONGAdpm_TrendDetection_DOWN
+};
+typedef enum TONGAdpm_TrendDetection TONGAdpm_TrendDetection;
+
+/* Bit vector representing same fields as hardware register. */
+#define PPTONGA_VOTINGRIGHTSCLIENTS_DFLT0              0x3FFFC102  /* CP_Gfx_busy */
+/* HDP_busy */
+/* IH_busy */
+/* DRM_busy */
+/* DRMDMA_busy */
+/* UVD_busy */
+/* VCE_busy */
+/* ACP_busy */
+/* SAMU_busy */
+/* AVP_busy  */
+/* SDMA enabled */
+#define PPTONGA_VOTINGRIGHTSCLIENTS_DFLT1              0x000400  /* FE_Gfx_busy  - Intended for primary usage.   Rest are for flexibility. */
+/* SH_Gfx_busy */
+/* RB_Gfx_busy */
+/* VCE_busy */
+
+#define PPTONGA_VOTINGRIGHTSCLIENTS_DFLT2              0xC00080  /* SH_Gfx_busy - Intended for primary usage.   Rest are for flexibility. */
+/* FE_Gfx_busy */
+/* RB_Gfx_busy */
+/* ACP_busy */
+
+#define PPTONGA_VOTINGRIGHTSCLIENTS_DFLT3              0xC00200  /* RB_Gfx_busy - Intended for primary usage.   Rest are for flexibility. */
+/* FE_Gfx_busy */
+/* SH_Gfx_busy */
+/* UVD_busy */
+
+#define PPTONGA_VOTINGRIGHTSCLIENTS_DFLT4              0xC01680  /* UVD_busy */
+/* VCE_busy */
+/* ACP_busy */
+/* SAMU_busy */
+
+#define PPTONGA_VOTINGRIGHTSCLIENTS_DFLT5              0xC00033  /* GFX, HDP, DRMDMA */
+#define PPTONGA_VOTINGRIGHTSCLIENTS_DFLT6              0xC00033  /* GFX, HDP, DRMDMA */
+#define PPTONGA_VOTINGRIGHTSCLIENTS_DFLT7              0x3FFFC000  /* GFX, HDP, DRMDMA */
+
+
+/* thermal protection counter (units).*/
+#define PPTONGA_THERMALPROTECTCOUNTER_DFLT            0x200 /* ~19us */
+
+/* static screen threshold unit */
+#define PPTONGA_STATICSCREENTHRESHOLDUNIT_DFLT        0
+
+/* static screen threshold */
+#define PPTONGA_STATICSCREENTHRESHOLD_DFLT            0x00C8
+
+/* gfx idle clock stop threshold */
+#define PPTONGA_GFXIDLECLOCKSTOPTHRESHOLD_DFLT        0x200 /* ~19us with static screen threshold unit of 0 */
+
+/* Fixed reference divider to use when building baby stepping tables. */
+#define PPTONGA_REFERENCEDIVIDER_DFLT                  4
+
+/*
+ * ULV voltage change delay time
+ * Used to be delay_vreg in N.I. split for S.I.
+ * Using N.I. delay_vreg value as default
+ * ReferenceClock = 2700
+ * VoltageResponseTime = 1000
+ * VDDCDelayTime = (VoltageResponseTime * ReferenceClock) / 1600 = 1687
+ */
+
+#define PPTONGA_ULVVOLTAGECHANGEDELAY_DFLT             1687
+
+#define PPTONGA_CGULVPARAMETER_DFLT                    0x00040035
+#define PPTONGA_CGULVCONTROL_DFLT                      0x00007450
+#define PPTONGA_TARGETACTIVITY_DFLT                     30  /*30%  */
+#define PPTONGA_MCLK_TARGETACTIVITY_DFLT                10  /*10%  */
+
+#endif
+
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_hwmgr.c
@@ -0,0 +1,6090 @@
+/*
+ * Copyright 2015 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/fb.h>
+#include "linux/delay.h"
+#include "pp_acpi.h"
+#include "hwmgr.h"
+#include <atombios.h>
+#include "tonga_hwmgr.h"
+#include "pptable.h"
+#include "processpptables.h"
+#include "tonga_processpptables.h"
+#include "tonga_pptable.h"
+#include "pp_debug.h"
+#include "tonga_ppsmc.h"
+#include "cgs_common.h"
+#include "pppcielanes.h"
+#include "tonga_dyn_defaults.h"
+#include "smumgr.h"
+#include "tonga_smumgr.h"
+#include "tonga_clockpowergating.h"
+#include "tonga_thermal.h"
+
+#include "smu/smu_7_1_2_d.h"
+#include "smu/smu_7_1_2_sh_mask.h"
+
+#include "gmc/gmc_8_1_d.h"
+#include "gmc/gmc_8_1_sh_mask.h"
+
+#include "bif/bif_5_0_d.h"
+#include "bif/bif_5_0_sh_mask.h"
+
+#include "cgs_linux.h"
+#include "eventmgr.h"
+#include "amd_pcie_helpers.h"
+
+#define MC_CG_ARB_FREQ_F0           0x0a
+#define MC_CG_ARB_FREQ_F1           0x0b
+#define MC_CG_ARB_FREQ_F2           0x0c
+#define MC_CG_ARB_FREQ_F3           0x0d
+
+#define MC_CG_SEQ_DRAMCONF_S0       0x05
+#define MC_CG_SEQ_DRAMCONF_S1       0x06
+#define MC_CG_SEQ_YCLK_SUSPEND      0x04
+#define MC_CG_SEQ_YCLK_RESUME       0x0a
+
+#define PCIE_BUS_CLK                10000
+#define TCLK                        (PCIE_BUS_CLK / 10)
+
+#define SMC_RAM_END 0x40000
+#define SMC_CG_IND_START            0xc0030000
+#define SMC_CG_IND_END              0xc0040000  /* First byte after SMC_CG_IND*/
+
+#define VOLTAGE_SCALE               4
+#define VOLTAGE_VID_OFFSET_SCALE1   625
+#define VOLTAGE_VID_OFFSET_SCALE2   100
+
+#define VDDC_VDDCI_DELTA            200
+#define VDDC_VDDGFX_DELTA           300
+
+#define MC_SEQ_MISC0_GDDR5_SHIFT 28
+#define MC_SEQ_MISC0_GDDR5_MASK  0xf0000000
+#define MC_SEQ_MISC0_GDDR5_VALUE 5
+
+typedef uint32_t PECI_RegistryValue;
+
+/* [2.5%,~2.5%] Clock stretched is multiple of 2.5% vs not and [Fmin, Fmax, LDO_REFSEL, USE_FOR_LOW_FREQ] */
+uint16_t PP_ClockStretcherLookupTable[2][4] = {
+	{600, 1050, 3, 0},
+	{600, 1050, 6, 1} };
+
+/* [FF, SS] type, [] 4 voltage ranges, and [Floor Freq, Boundary Freq, VID min , VID max] */
+uint32_t PP_ClockStretcherDDTTable[2][4][4] = {
+	{ {265, 529, 120, 128}, {325, 650, 96, 119}, {430, 860, 32, 95}, {0, 0, 0, 31} },
+	{ {275, 550, 104, 112}, {319, 638, 96, 103}, {360, 720, 64, 95}, {384, 768, 32, 63} } };
+
+/* [Use_For_Low_freq] value, [0%, 5%, 10%, 7.14%, 14.28%, 20%] (coming from PWR_CKS_CNTL.stretch_amount reg spec) */
+uint8_t PP_ClockStretchAmountConversion[2][6] = {
+	{0, 1, 3, 2, 4, 5},
+	{0, 2, 4, 5, 6, 5} };
+
+/* Values for the CG_THERMAL_CTRL::DPM_EVENT_SRC field. */
+enum DPM_EVENT_SRC {
+	DPM_EVENT_SRC_ANALOG = 0,               /* Internal analog trip point */
+	DPM_EVENT_SRC_EXTERNAL = 1,             /* External (GPIO 17) signal */
+	DPM_EVENT_SRC_DIGITAL = 2,              /* Internal digital trip point (DIG_THERM_DPM) */
+	DPM_EVENT_SRC_ANALOG_OR_EXTERNAL = 3,   /* Internal analog or external */
+	DPM_EVENT_SRC_DIGITAL_OR_EXTERNAL = 4   /* Internal digital or external */
+};
+typedef enum DPM_EVENT_SRC DPM_EVENT_SRC;
+
+const unsigned long PhwTonga_Magic = (unsigned long)(PHM_VIslands_Magic);
+
+struct tonga_power_state *cast_phw_tonga_power_state(
+				  struct pp_hw_power_state *hw_ps)
+{
+	if (hw_ps == NULL)
+		return NULL;
+
+	PP_ASSERT_WITH_CODE((PhwTonga_Magic == hw_ps->magic),
+				"Invalid Powerstate Type!",
+				 return NULL);
+
+	return (struct tonga_power_state *)hw_ps;
+}
+
+const struct tonga_power_state *cast_const_phw_tonga_power_state(
+				 const struct pp_hw_power_state *hw_ps)
+{
+	if (hw_ps == NULL)
+		return NULL;
+
+	PP_ASSERT_WITH_CODE((PhwTonga_Magic == hw_ps->magic),
+				"Invalid Powerstate Type!",
+				 return NULL);
+
+	return (const struct tonga_power_state *)hw_ps;
+}
+
+int tonga_add_voltage(struct pp_hwmgr *hwmgr,
+	phm_ppt_v1_voltage_lookup_table *look_up_table,
+	phm_ppt_v1_voltage_lookup_record *record)
+{
+	uint32_t i;
+	PP_ASSERT_WITH_CODE((NULL != look_up_table),
+		"Lookup Table empty.", return -1;);
+	PP_ASSERT_WITH_CODE((0 != look_up_table->count),
+		"Lookup Table empty.", return -1;);
+	PP_ASSERT_WITH_CODE((SMU72_MAX_LEVELS_VDDGFX >= look_up_table->count),
+		"Lookup Table is full.", return -1;);
+
+	/* This is to avoid entering duplicate calculated records. */
+	for (i = 0; i < look_up_table->count; i++) {
+		if (look_up_table->entries[i].us_vdd == record->us_vdd) {
+			if (look_up_table->entries[i].us_calculated == 1)
+				return 0;
+			else
+				break;
+		}
+	}
+
+	look_up_table->entries[i].us_calculated = 1;
+	look_up_table->entries[i].us_vdd = record->us_vdd;
+	look_up_table->entries[i].us_cac_low = record->us_cac_low;
+	look_up_table->entries[i].us_cac_mid = record->us_cac_mid;
+	look_up_table->entries[i].us_cac_high = record->us_cac_high;
+	/* Only increment the count when we're appending, not replacing duplicate entry. */
+	if (i == look_up_table->count)
+		look_up_table->count++;
+
+	return 0;
+}
+
+int tonga_notify_smc_display_change(struct pp_hwmgr *hwmgr, bool has_display)
+{
+	PPSMC_Msg msg = has_display? (PPSMC_Msg)PPSMC_HasDisplay : (PPSMC_Msg)PPSMC_NoDisplay;
+
+	return (smum_send_msg_to_smc(hwmgr->smumgr, msg) == 0) ?  0 : -1;
+}
+
+uint8_t tonga_get_voltage_id(pp_atomctrl_voltage_table *voltage_table,
+		uint32_t voltage)
+{
+	uint8_t count = (uint8_t) (voltage_table->count);
+	uint8_t i = 0;
+
+	PP_ASSERT_WITH_CODE((NULL != voltage_table),
+		"Voltage Table empty.", return 0;);
+	PP_ASSERT_WITH_CODE((0 != count),
+		"Voltage Table empty.", return 0;);
+
+	for (i = 0; i < count; i++) {
+		/* find first voltage bigger than requested */
+		if (voltage_table->entries[i].value >= voltage)
+			return i;
+	}
+
+	/* voltage is bigger than max voltage in the table */
+	return i - 1;
+}
+
+/**
+ * @brief PhwTonga_GetVoltageOrder
+ *  Returns index of requested voltage record in lookup(table)
+ * @param hwmgr - pointer to hardware manager
+ * @param lookupTable - lookup list to search in
+ * @param voltage - voltage to look for
+ * @return 0 on success
+ */
+uint8_t tonga_get_voltage_index(phm_ppt_v1_voltage_lookup_table *look_up_table,
+		uint16_t voltage)
+{
+	uint8_t count = (uint8_t) (look_up_table->count);
+	uint8_t i;
+
+	PP_ASSERT_WITH_CODE((NULL != look_up_table), "Lookup Table empty.", return 0;);
+	PP_ASSERT_WITH_CODE((0 != count), "Lookup Table empty.", return 0;);
+
+	for (i = 0; i < count; i++) {
+		/* find first voltage equal or bigger than requested */
+		if (look_up_table->entries[i].us_vdd >= voltage)
+			return i;
+	}
+
+	/* voltage is bigger than max voltage in the table */
+	return i-1;
+}
+
+bool tonga_is_dpm_running(struct pp_hwmgr *hwmgr)
+{
+	/*
+	 * We return the status of Voltage Control instead of checking SCLK/MCLK DPM
+	 * because we may have test scenarios that need us intentionly disable SCLK/MCLK DPM,
+	 * whereas voltage control is a fundemental change that will not be disabled
+	 */
+
+	return (0 == PHM_READ_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC,
+					FEATURE_STATUS, VOLTAGE_CONTROLLER_ON) ? 1 : 0);
+}
+
+/**
+ * Re-generate the DPM level mask value
+ * @param    hwmgr      the address of the hardware manager
+ */
+static uint32_t tonga_get_dpm_level_enable_mask_value(
+			struct tonga_single_dpm_table * dpm_table)
+{
+	uint32_t i;
+	uint32_t mask_value = 0;
+
+	for (i = dpm_table->count; i > 0; i--) {
+		mask_value = mask_value << 1;
+
+		if (dpm_table->dpm_levels[i-1].enabled)
+			mask_value |= 0x1;
+		else
+			mask_value &= 0xFFFFFFFE;
+	}
+	return mask_value;
+}
+
+/**
+ * Retrieve DPM default values from registry (if available)
+ *
+ * @param    hwmgr  the address of the powerplay hardware manager.
+ */
+void tonga_initialize_dpm_defaults(struct pp_hwmgr *hwmgr)
+{
+	tonga_hwmgr *data = (tonga_hwmgr *)(hwmgr->backend);
+	phw_tonga_ulv_parm *ulv = &(data->ulv);
+	uint32_t tmp;
+
+	ulv->ch_ulv_parameter = PPTONGA_CGULVPARAMETER_DFLT;
+	data->voting_rights_clients0 = PPTONGA_VOTINGRIGHTSCLIENTS_DFLT0;
+	data->voting_rights_clients1 = PPTONGA_VOTINGRIGHTSCLIENTS_DFLT1;
+	data->voting_rights_clients2 = PPTONGA_VOTINGRIGHTSCLIENTS_DFLT2;
+	data->voting_rights_clients3 = PPTONGA_VOTINGRIGHTSCLIENTS_DFLT3;
+	data->voting_rights_clients4 = PPTONGA_VOTINGRIGHTSCLIENTS_DFLT4;
+	data->voting_rights_clients5 = PPTONGA_VOTINGRIGHTSCLIENTS_DFLT5;
+	data->voting_rights_clients6 = PPTONGA_VOTINGRIGHTSCLIENTS_DFLT6;
+	data->voting_rights_clients7 = PPTONGA_VOTINGRIGHTSCLIENTS_DFLT7;
+
+	data->static_screen_threshold_unit = PPTONGA_STATICSCREENTHRESHOLDUNIT_DFLT;
+	data->static_screen_threshold = PPTONGA_STATICSCREENTHRESHOLD_DFLT;
+
+	phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
+		PHM_PlatformCaps_ABM);
+	phm_cap_set(hwmgr->platform_descriptor.platformCaps,
+		PHM_PlatformCaps_NonABMSupportInPPLib);
+
+	tmp = 0;
+	if (tmp == 0)
+		phm_cap_set(hwmgr->platform_descriptor.platformCaps,
+			PHM_PlatformCaps_DynamicACTiming);
+
+	tmp = 0;
+	if (0 != tmp)
+		phm_cap_set(hwmgr->platform_descriptor.platformCaps,
+			PHM_PlatformCaps_DisableMemoryTransition);
+
+	data->mclk_strobe_mode_threshold = 40000;
+	data->mclk_stutter_mode_threshold = 30000;
+	data->mclk_edc_enable_threshold = 40000;
+	data->mclk_edc_wr_enable_threshold = 40000;
+
+	tmp = 0;
+	if (tmp != 0)
+		phm_cap_set(hwmgr->platform_descriptor.platformCaps,
+			PHM_PlatformCaps_DisableMCLS);
+
+	data->pcie_gen_performance.max = PP_PCIEGen1;
+	data->pcie_gen_performance.min = PP_PCIEGen3;
+	data->pcie_gen_power_saving.max = PP_PCIEGen1;
+	data->pcie_gen_power_saving.min = PP_PCIEGen3;
+
+	data->pcie_lane_performance.max = 0;
+	data->pcie_lane_performance.min = 16;
+	data->pcie_lane_power_saving.max = 0;
+	data->pcie_lane_power_saving.min = 16;
+
+	tmp = 0;
+
+	if (tmp)
+		phm_cap_set(hwmgr->platform_descriptor.platformCaps,
+			PHM_PlatformCaps_SclkThrottleLowNotification);
+
+	phm_cap_set(hwmgr->platform_descriptor.platformCaps,
+		PHM_PlatformCaps_DynamicUVDState);
+
+}
+
+int tonga_update_sclk_threshold(struct pp_hwmgr *hwmgr)
+{
+	tonga_hwmgr *data = (tonga_hwmgr *)(hwmgr->backend);
+
+	int result = 0;
+	uint32_t low_sclk_interrupt_threshold = 0;
+
+	if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
+			PHM_PlatformCaps_SclkThrottleLowNotification)
+		&& (hwmgr->gfx_arbiter.sclk_threshold != data->low_sclk_interrupt_threshold)) {
+		data->low_sclk_interrupt_threshold = hwmgr->gfx_arbiter.sclk_threshold;
+		low_sclk_interrupt_threshold = data->low_sclk_interrupt_threshold;
+
+		CONVERT_FROM_HOST_TO_SMC_UL(low_sclk_interrupt_threshold);
+
+		result = tonga_copy_bytes_to_smc(
+				hwmgr->smumgr,
+				data->dpm_table_start + offsetof(SMU72_Discrete_DpmTable,
+				LowSclkInterruptThreshold),
+				(uint8_t *)&low_sclk_interrupt_threshold,
+				sizeof(uint32_t),
+				data->sram_end
+				);
+	}
+
+	return result;
+}
+
+/**
+ * Find SCLK value that is associated with specified virtual_voltage_Id.
+ *
+ * @param    hwmgr  the address of the powerplay hardware manager.
+ * @param    virtual_voltage_Id  voltageId to look for.
+ * @param    sclk output value .
+ * @return   always 0 if success and 2 if association not found
+ */
+static int tonga_get_sclk_for_voltage_evv(struct pp_hwmgr *hwmgr,
+	phm_ppt_v1_voltage_lookup_table *lookup_table,
+	uint16_t virtual_voltage_id, uint32_t *sclk)
+{
+	uint8_t entryId;
+	uint8_t voltageId;
+	struct phm_ppt_v1_information *pptable_info =
+					(struct phm_ppt_v1_information *)(hwmgr->pptable);
+
+	PP_ASSERT_WITH_CODE(lookup_table->count != 0, "Lookup table is empty", return -1);
+
+	/* search for leakage voltage ID 0xff01 ~ 0xff08 and sckl */
+	for (entryId = 0; entryId < pptable_info->vdd_dep_on_sclk->count; entryId++) {
+		voltageId = pptable_info->vdd_dep_on_sclk->entries[entryId].vddInd;
+		if (lookup_table->entries[voltageId].us_vdd == virtual_voltage_id)
+			break;
+	}
+
+	PP_ASSERT_WITH_CODE(entryId < pptable_info->vdd_dep_on_sclk->count,
+			"Can't find requested voltage id in vdd_dep_on_sclk table!",
+			return -1;
+			);
+
+	*sclk = pptable_info->vdd_dep_on_sclk->entries[entryId].clk;
+
+	return 0;
+}
+
+/**
+ * Get Leakage VDDC based on leakage ID.
+ *
+ * @param    hwmgr  the address of the powerplay hardware manager.
+ * @return   2 if vddgfx returned is greater than 2V or if BIOS
+ */
+int tonga_get_evv_voltage(struct pp_hwmgr *hwmgr)
+{
+	tonga_hwmgr *data = (tonga_hwmgr *)(hwmgr->backend);
+	struct phm_ppt_v1_information *pptable_info = (struct phm_ppt_v1_information *)(hwmgr->pptable);
+	phm_ppt_v1_clock_voltage_dependency_table *sclk_table = pptable_info->vdd_dep_on_sclk;
+	uint16_t    virtual_voltage_id;
+	uint16_t    vddc = 0;
+	uint16_t    vddgfx = 0;
+	uint16_t    i, j;
+	uint32_t  sclk = 0;
+
+	/* retrieve voltage for leakage ID (0xff01 + i) */
+	for (i = 0; i < TONGA_MAX_LEAKAGE_COUNT; i++) {
+		virtual_voltage_id = ATOM_VIRTUAL_VOLTAGE_ID0 + i;
+
+		/* in split mode we should have only vddgfx EVV leakages */
+		if (data->vdd_gfx_control == TONGA_VOLTAGE_CONTROL_BY_SVID2) {
+			if (0 == tonga_get_sclk_for_voltage_evv(hwmgr,
+						pptable_info->vddgfx_lookup_table, virtual_voltage_id, &sclk)) {
+				if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
+							PHM_PlatformCaps_ClockStretcher)) {
+					for (j = 1; j < sclk_table->count; j++) {
+						if (sclk_table->entries[j].clk == sclk &&
+								sclk_table->entries[j].cks_enable == 0) {
+							sclk += 5000;
+							break;
+						}
+					}
+				}
+				PP_ASSERT_WITH_CODE(0 == atomctrl_get_voltage_evv_on_sclk
+						(hwmgr, VOLTAGE_TYPE_VDDGFX, sclk,
+						 virtual_voltage_id, &vddgfx),
+						"Error retrieving EVV voltage value!", continue);
+
+				/* need to make sure vddgfx is less than 2v or else, it could burn the ASIC. */
+				PP_ASSERT_WITH_CODE((vddgfx < 2000 && vddgfx != 0), "Invalid VDDGFX value!", return -1);
+
+				/* the voltage should not be zero nor equal to leakage ID */
+				if (vddgfx != 0 && vddgfx != virtual_voltage_id) {
+					data->vddcgfx_leakage.actual_voltage[data->vddcgfx_leakage.count] = vddgfx;
+					data->vddcgfx_leakage.leakage_id[data->vddcgfx_leakage.count] = virtual_voltage_id;
+					data->vddcgfx_leakage.count++;
+				}
+			}
+		} else {
+			/*  in merged mode we have only vddc EVV leakages */
+			if (0 == tonga_get_sclk_for_voltage_evv(hwmgr,
+						pptable_info->vddc_lookup_table,
+						virtual_voltage_id, &sclk)) {
+				PP_ASSERT_WITH_CODE(0 == atomctrl_get_voltage_evv_on_sclk
+						(hwmgr, VOLTAGE_TYPE_VDDC, sclk,
+						 virtual_voltage_id, &vddc),
+						"Error retrieving EVV voltage value!", continue);
+
+				/* need to make sure vddc is less than 2v or else, it could burn the ASIC. */
+				if (vddc > 2000)
+					printk(KERN_ERR "[ powerplay ] Invalid VDDC value! \n");
+
+				/* the voltage should not be zero nor equal to leakage ID */
+				if (vddc != 0 && vddc != virtual_voltage_id) {
+					data->vddc_leakage.actual_voltage[data->vddc_leakage.count] = vddc;
+					data->vddc_leakage.leakage_id[data->vddc_leakage.count] = virtual_voltage_id;
+					data->vddc_leakage.count++;
+				}
+			}
+		}
+	}
+
+	return 0;
+}
+
+int tonga_enable_sclk_mclk_dpm(struct pp_hwmgr *hwmgr)
+{
+	tonga_hwmgr *data = (tonga_hwmgr *)(hwmgr->backend);
+
+	/* enable SCLK dpm */
+	if (0 == data->sclk_dpm_key_disabled) {
+		PP_ASSERT_WITH_CODE(
+				(0 == smum_send_msg_to_smc(hwmgr->smumgr,
+						   PPSMC_MSG_DPM_Enable)),
+				"Failed to enable SCLK DPM during DPM Start Function!",
+				return -1);
+	}
+
+	/* enable MCLK dpm */
+	if (0 == data->mclk_dpm_key_disabled) {
+		PP_ASSERT_WITH_CODE(
+				(0 == smum_send_msg_to_smc(hwmgr->smumgr,
+					     PPSMC_MSG_MCLKDPM_Enable)),
+				"Failed to enable MCLK DPM during DPM Start Function!",
+				return -1);
+
+		PHM_WRITE_FIELD(hwmgr->device, MC_SEQ_CNTL_3, CAC_EN, 0x1);
+
+		cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC,
+			ixLCAC_MC0_CNTL, 0x05);/* CH0,1 read */
+		cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC,
+			ixLCAC_MC1_CNTL, 0x05);/* CH2,3 read */
+		cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC,
+			ixLCAC_CPL_CNTL, 0x100005);/*Read */
+
+		udelay(10);
+
+		cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC,
+			ixLCAC_MC0_CNTL, 0x400005);/* CH0,1 write */
+		cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC,
+			ixLCAC_MC1_CNTL, 0x400005);/* CH2,3 write */
+		cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC,
+			ixLCAC_CPL_CNTL, 0x500005);/* write */
+
+	}
+
+	return 0;
+}
+
+int tonga_start_dpm(struct pp_hwmgr *hwmgr)
+{
+	tonga_hwmgr *data = (tonga_hwmgr *)(hwmgr->backend);
+
+	/* enable general power management */
+	PHM_WRITE_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, GENERAL_PWRMGT, GLOBAL_PWRMGT_EN, 1);
+	/* enable sclk deep sleep */
+	PHM_WRITE_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, SCLK_PWRMGT_CNTL, DYNAMIC_PM_EN, 1);
+
+	/* prepare for PCIE DPM */
+	cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC, data->soft_regs_start +
+			offsetof(SMU72_SoftRegisters, VoltageChangeTimeout), 0x1000);
+
+	PHM_WRITE_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__PCIE, SWRST_COMMAND_1, RESETLC, 0x0);
+
+	PP_ASSERT_WITH_CODE(
+			(0 == smum_send_msg_to_smc(hwmgr->smumgr,
+					PPSMC_MSG_Voltage_Cntl_Enable)),
+			"Failed to enable voltage DPM during DPM Start Function!",
+			return -1);
+
+	if (0 != tonga_enable_sclk_mclk_dpm(hwmgr)) {
+		PP_ASSERT_WITH_CODE(0, "Failed to enable Sclk DPM and Mclk DPM!", return -1);
+	}
+
+	/* enable PCIE dpm */
+	if (0 == data->pcie_dpm_key_disabled) {
+		PP_ASSERT_WITH_CODE(
+				(0 == smum_send_msg_to_smc(hwmgr->smumgr,
+						PPSMC_MSG_PCIeDPM_Enable)),
+				"Failed to enable pcie DPM during DPM Start Function!",
+				return -1
+				);
+	}
+
+	if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
+				PHM_PlatformCaps_Falcon_QuickTransition)) {
+				   smum_send_msg_to_smc(hwmgr->smumgr,
+				    PPSMC_MSG_EnableACDCGPIOInterrupt);
+	}
+
+	return 0;
+}
+
+int tonga_disable_sclk_mclk_dpm(struct pp_hwmgr *hwmgr)
+{
+	tonga_hwmgr *data = (tonga_hwmgr *)(hwmgr->backend);
+
+	/* disable SCLK dpm */
+	if (0 == data->sclk_dpm_key_disabled) {
+		/* Checking if DPM is running.  If we discover hang because of this, we should skip this message.*/
+		PP_ASSERT_WITH_CODE(
+				(0 == tonga_is_dpm_running(hwmgr)),
+				"Trying to Disable SCLK DPM when DPM is disabled",
+				return -1
+				);
+
+		PP_ASSERT_WITH_CODE(
+				(0 == smum_send_msg_to_smc(hwmgr->smumgr,
+						  PPSMC_MSG_DPM_Disable)),
+				"Failed to disable SCLK DPM during DPM stop Function!",
+				return -1);
+	}
+
+	/* disable MCLK dpm */
+	if (0 == data->mclk_dpm_key_disabled) {
+		/* Checking if DPM is running.  If we discover hang because of this, we should skip this message. */
+		PP_ASSERT_WITH_CODE(
+				(0 == tonga_is_dpm_running(hwmgr)),
+				"Trying to Disable MCLK DPM when DPM is disabled",
+				return -1
+				);
+
+		PP_ASSERT_WITH_CODE(
+				(0 == smum_send_msg_to_smc(hwmgr->smumgr,
+					    PPSMC_MSG_MCLKDPM_Disable)),
+				"Failed to Disable MCLK DPM during DPM stop Function!",
+				return -1);
+	}
+
+	return 0;
+}
+
+int tonga_stop_dpm(struct pp_hwmgr *hwmgr)
+{
+	tonga_hwmgr *data = (tonga_hwmgr *)(hwmgr->backend);
+
+	PHM_WRITE_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, GENERAL_PWRMGT, GLOBAL_PWRMGT_EN, 0);
+	/* disable sclk deep sleep*/
+	PHM_WRITE_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, SCLK_PWRMGT_CNTL, DYNAMIC_PM_EN, 0);
+
+	/* disable PCIE dpm */
+	if (0 == data->pcie_dpm_key_disabled) {
+		/* Checking if DPM is running.  If we discover hang because of this, we should skip this message.*/
+		PP_ASSERT_WITH_CODE(
+				(0 == tonga_is_dpm_running(hwmgr)),
+				"Trying to Disable PCIE DPM when DPM is disabled",
+				return -1
+				);
+		PP_ASSERT_WITH_CODE(
+				(0 == smum_send_msg_to_smc(hwmgr->smumgr,
+						PPSMC_MSG_PCIeDPM_Disable)),
+				"Failed to disable pcie DPM during DPM stop Function!",
+				return -1);
+	}
+
+	if (0 != tonga_disable_sclk_mclk_dpm(hwmgr))
+		PP_ASSERT_WITH_CODE(0, "Failed to disable Sclk DPM and Mclk DPM!", return -1);
+
+	/* Checking if DPM is running.  If we discover hang because of this, we should skip this message.*/
+	PP_ASSERT_WITH_CODE(
+			(0 == tonga_is_dpm_running(hwmgr)),
+			"Trying to Disable Voltage CNTL when DPM is disabled",
+			return -1
+			);
+
+	PP_ASSERT_WITH_CODE(
+			(0 == smum_send_msg_to_smc(hwmgr->smumgr,
+					PPSMC_MSG_Voltage_Cntl_Disable)),
+			"Failed to disable voltage DPM during DPM stop Function!",
+			return -1);
+
+	return 0;
+}
+
+int tonga_enable_sclk_control(struct pp_hwmgr *hwmgr)
+{
+	PHM_WRITE_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, SCLK_PWRMGT_CNTL, SCLK_PWRMGT_OFF, 0);
+
+	return 0;
+}
+
+/**
+ * Send a message to the SMC and return a parameter
+ *
+ * @param    hwmgr:  the address of the powerplay hardware manager.
+ * @param    msg: the message to send.
+ * @param    parameter: pointer to the received parameter
+ * @return   The response that came from the SMC.
+ */
+PPSMC_Result tonga_send_msg_to_smc_return_parameter(
+		struct pp_hwmgr *hwmgr,
+		PPSMC_Msg msg,
+		uint32_t *parameter)
+{
+	int result;
+
+	result = smum_send_msg_to_smc(hwmgr->smumgr, msg);
+
+	if ((0 == result) && parameter) {
+		*parameter = cgs_read_register(hwmgr->device, mmSMC_MSG_ARG_0);
+	}
+
+	return result;
+}
+
+/**
+ * force DPM power State
+ *
+ * @param    hwmgr:  the address of the powerplay hardware manager.
+ * @param    n     :  DPM level
+ * @return   The response that came from the SMC.
+ */
+int tonga_dpm_force_state(struct pp_hwmgr *hwmgr, uint32_t n)
+{
+	tonga_hwmgr *data = (tonga_hwmgr *)(hwmgr->backend);
+	uint32_t level_mask = 1 << n;
+
+	/* Checking if DPM is running.  If we discover hang because of this, we should skip this message. */
+	PP_ASSERT_WITH_CODE(0 == tonga_is_dpm_running(hwmgr),
+			"Trying to force SCLK when DPM is disabled", return -1;);
+	if (0 == data->sclk_dpm_key_disabled)
+		return (0 == smum_send_msg_to_smc_with_parameter(
+							     hwmgr->smumgr,
+		     (PPSMC_Msg)(PPSMC_MSG_SCLKDPM_SetEnabledMask),
+						    level_mask) ? 0 : 1);
+
+	return 0;
+}
+
+/**
+ * force DPM power State
+ *
+ * @param    hwmgr:  the address of the powerplay hardware manager.
+ * @param    n     :  DPM level
+ * @return   The response that came from the SMC.
+ */
+int tonga_dpm_force_state_mclk(struct pp_hwmgr *hwmgr, uint32_t n)
+{
+	tonga_hwmgr *data = (tonga_hwmgr *)(hwmgr->backend);
+	uint32_t level_mask = 1 << n;
+
+	/* Checking if DPM is running.  If we discover hang because of this, we should skip this message. */
+	PP_ASSERT_WITH_CODE(0 == tonga_is_dpm_running(hwmgr),
+			"Trying to Force MCLK when DPM is disabled", return -1;);
+	if (0 == data->mclk_dpm_key_disabled)
+		return (0 == smum_send_msg_to_smc_with_parameter(
+								hwmgr->smumgr,
+								(PPSMC_Msg)(PPSMC_MSG_MCLKDPM_SetEnabledMask),
+								level_mask) ? 0 : 1);
+
+	return 0;
+}
+
+/**
+ * force DPM power State
+ *
+ * @param    hwmgr:  the address of the powerplay hardware manager.
+ * @param    n     :  DPM level
+ * @return   The response that came from the SMC.
+ */
+int tonga_dpm_force_state_pcie(struct pp_hwmgr *hwmgr, uint32_t n)
+{
+	tonga_hwmgr *data = (tonga_hwmgr *)(hwmgr->backend);
+
+	/* Checking if DPM is running.  If we discover hang because of this, we should skip this message.*/
+	PP_ASSERT_WITH_CODE(0 == tonga_is_dpm_running(hwmgr),
+			"Trying to Force PCIE level when DPM is disabled", return -1;);
+	if (0 == data->pcie_dpm_key_disabled)
+		return (0 == smum_send_msg_to_smc_with_parameter(
+							     hwmgr->smumgr,
+			   (PPSMC_Msg)(PPSMC_MSG_PCIeDPM_ForceLevel),
+								n) ? 0 : 1);
+
+	return 0;
+}
+
+/**
+ * Set the initial state by calling SMC to switch to this state directly
+ *
+ * @param    hwmgr  the address of the powerplay hardware manager.
+ * @return   always 0
+ */
+int tonga_set_boot_state(struct pp_hwmgr *hwmgr)
+{
+	/*
+	* SMC only stores one state that SW will ask to switch too,
+	* so we switch the the just uploaded one
+	*/
+	return (0 == tonga_disable_sclk_mclk_dpm(hwmgr)) ? 0 : 1;
+}
+
+/**
+ * Get the location of various tables inside the FW image.
+ *
+ * @param    hwmgr  the address of the powerplay hardware manager.
+ * @return   always 0
+ */
+int tonga_process_firmware_header(struct pp_hwmgr *hwmgr)
+{
+	tonga_hwmgr *data = (tonga_hwmgr *)(hwmgr->backend);
+	struct tonga_smumgr *tonga_smu = (struct tonga_smumgr *)(hwmgr->smumgr->backend);
+
+	uint32_t tmp;
+	int result;
+	bool error = 0;
+
+	result = tonga_read_smc_sram_dword(hwmgr->smumgr,
+				SMU72_FIRMWARE_HEADER_LOCATION +
+				offsetof(SMU72_Firmware_Header, DpmTable),
+				&tmp, data->sram_end);
+
+	if (0 == result) {
+		data->dpm_table_start = tmp;
+	}
+
+	error |= (0 != result);
+
+	result = tonga_read_smc_sram_dword(hwmgr->smumgr,
+				SMU72_FIRMWARE_HEADER_LOCATION +
+				offsetof(SMU72_Firmware_Header, SoftRegisters),
+				&tmp, data->sram_end);
+
+	if (0 == result) {
+		data->soft_regs_start = tmp;
+		tonga_smu->ulSoftRegsStart = tmp;
+	}
+
+	error |= (0 != result);
+
+
+	result = tonga_read_smc_sram_dword(hwmgr->smumgr,
+				SMU72_FIRMWARE_HEADER_LOCATION +
+				offsetof(SMU72_Firmware_Header, mcRegisterTable),
+				&tmp, data->sram_end);
+
+	if (0 == result) {
+		data->mc_reg_table_start = tmp;
+	}
+
+	result = tonga_read_smc_sram_dword(hwmgr->smumgr,
+				SMU72_FIRMWARE_HEADER_LOCATION +
+				offsetof(SMU72_Firmware_Header, FanTable),
+				&tmp, data->sram_end);
+
+	if (0 == result) {
+		data->fan_table_start = tmp;
+	}
+
+	error |= (0 != result);
+
+	result = tonga_read_smc_sram_dword(hwmgr->smumgr,
+				SMU72_FIRMWARE_HEADER_LOCATION +
+				offsetof(SMU72_Firmware_Header, mcArbDramTimingTable),
+				&tmp, data->sram_end);
+
+	if (0 == result) {
+		data->arb_table_start = tmp;
+	}
+
+	error |= (0 != result);
+
+
+	result = tonga_read_smc_sram_dword(hwmgr->smumgr,
+				SMU72_FIRMWARE_HEADER_LOCATION +
+				offsetof(SMU72_Firmware_Header, Version),
+				&tmp, data->sram_end);
+
+	if (0 == result) {
+		hwmgr->microcode_version_info.SMC = tmp;
+	}
+
+	error |= (0 != result);
+
+	return error ? 1 : 0;
+}
+
+/**
+ * Read clock related registers.
+ *
+ * @param    hwmgr  the address of the powerplay hardware manager.
+ * @return   always 0
+ */
+int tonga_read_clock_registers(struct pp_hwmgr *hwmgr)
+{
+	tonga_hwmgr *data = (tonga_hwmgr *)(hwmgr->backend);
+
+	data->clock_registers.vCG_SPLL_FUNC_CNTL         =
+		cgs_read_ind_register(hwmgr->device, CGS_IND_REG__SMC, ixCG_SPLL_FUNC_CNTL);
+	data->clock_registers.vCG_SPLL_FUNC_CNTL_2       =
+		cgs_read_ind_register(hwmgr->device, CGS_IND_REG__SMC, ixCG_SPLL_FUNC_CNTL_2);
+	data->clock_registers.vCG_SPLL_FUNC_CNTL_3       =
+		cgs_read_ind_register(hwmgr->device, CGS_IND_REG__SMC, ixCG_SPLL_FUNC_CNTL_3);
+	data->clock_registers.vCG_SPLL_FUNC_CNTL_4       =
+		cgs_read_ind_register(hwmgr->device, CGS_IND_REG__SMC, ixCG_SPLL_FUNC_CNTL_4);
+	data->clock_registers.vCG_SPLL_SPREAD_SPECTRUM   =
+		cgs_read_ind_register(hwmgr->device, CGS_IND_REG__SMC, ixCG_SPLL_SPREAD_SPECTRUM);
+	data->clock_registers.vCG_SPLL_SPREAD_SPECTRUM_2 =
+		cgs_read_ind_register(hwmgr->device, CGS_IND_REG__SMC, ixCG_SPLL_SPREAD_SPECTRUM_2);
+	data->clock_registers.vDLL_CNTL                  =
+		cgs_read_register(hwmgr->device, mmDLL_CNTL);
+	data->clock_registers.vMCLK_PWRMGT_CNTL          =
+		cgs_read_register(hwmgr->device, mmMCLK_PWRMGT_CNTL);
+	data->clock_registers.vMPLL_AD_FUNC_CNTL         =
+		cgs_read_register(hwmgr->device, mmMPLL_AD_FUNC_CNTL);
+	data->clock_registers.vMPLL_DQ_FUNC_CNTL         =
+		cgs_read_register(hwmgr->device, mmMPLL_DQ_FUNC_CNTL);
+	data->clock_registers.vMPLL_FUNC_CNTL            =
+		cgs_read_register(hwmgr->device, mmMPLL_FUNC_CNTL);
+	data->clock_registers.vMPLL_FUNC_CNTL_1          =
+		cgs_read_register(hwmgr->device, mmMPLL_FUNC_CNTL_1);
+	data->clock_registers.vMPLL_FUNC_CNTL_2          =
+		cgs_read_register(hwmgr->device, mmMPLL_FUNC_CNTL_2);
+	data->clock_registers.vMPLL_SS1                  =
+		cgs_read_register(hwmgr->device, mmMPLL_SS1);
+	data->clock_registers.vMPLL_SS2                  =
+		cgs_read_register(hwmgr->device, mmMPLL_SS2);
+
+	return 0;
+}
+
+/**
+ * Find out if memory is GDDR5.
+ *
+ * @param    hwmgr  the address of the powerplay hardware manager.
+ * @return   always 0
+ */
+int tonga_get_memory_type(struct pp_hwmgr *hwmgr)
+{
+	tonga_hwmgr *data = (tonga_hwmgr *)(hwmgr->backend);
+	uint32_t temp;
+
+	temp = cgs_read_register(hwmgr->device, mmMC_SEQ_MISC0);
+
+	data->is_memory_GDDR5 = (MC_SEQ_MISC0_GDDR5_VALUE ==
+			((temp & MC_SEQ_MISC0_GDDR5_MASK) >>
+			 MC_SEQ_MISC0_GDDR5_SHIFT));
+
+	return 0;
+}
+
+/**
+ * Enables Dynamic Power Management by SMC
+ *
+ * @param    hwmgr  the address of the powerplay hardware manager.
+ * @return   always 0
+ */
+int tonga_enable_acpi_power_management(struct pp_hwmgr *hwmgr)
+{
+	PHM_WRITE_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, GENERAL_PWRMGT, STATIC_PM_EN, 1);
+
+	return 0;
+}
+
+/**
+ * Initialize PowerGating States for different engines
+ *
+ * @param    hwmgr  the address of the powerplay hardware manager.
+ * @return   always 0
+ */
+int tonga_init_power_gate_state(struct pp_hwmgr *hwmgr)
+{
+	tonga_hwmgr *data = (tonga_hwmgr *)(hwmgr->backend);
+
+	data->uvd_power_gated = 0;
+	data->vce_power_gated = 0;
+	data->samu_power_gated = 0;
+	data->acp_power_gated = 0;
+	data->pg_acp_init = 1;
+
+	return 0;
+}
+
+/**
+ * Checks if DPM is enabled
+ *
+ * @param    hwmgr  the address of the powerplay hardware manager.
+ * @return   always 0
+ */
+int tonga_check_for_dpm_running(struct pp_hwmgr *hwmgr)
+{
+	/*
+	 * We return the status of Voltage Control instead of checking SCLK/MCLK DPM
+	 * because we may have test scenarios that need us intentionly disable SCLK/MCLK DPM,
+	 * whereas voltage control is a fundemental change that will not be disabled
+	 */
+	return (0 == tonga_is_dpm_running(hwmgr) ? 0 : 1);
+}
+
+/**
+ * Checks if DPM is stopped
+ *
+ * @param    hwmgr  the address of the powerplay hardware manager.
+ * @return   always 0
+ */
+int tonga_check_for_dpm_stopped(struct pp_hwmgr *hwmgr)
+{
+	tonga_hwmgr *data = (tonga_hwmgr *)(hwmgr->backend);
+
+	if (0 != tonga_is_dpm_running(hwmgr)) {
+		/* If HW Virtualization is enabled, dpm_table_start will not have a valid value */
+		if (!data->dpm_table_start) {
+			return 1;
+		}
+	}
+
+	return 0;
+}
+
+/**
+ * Remove repeated voltage values and create table with unique values.
+ *
+ * @param    hwmgr  the address of the powerplay hardware manager.
+ * @param    voltage_table  the pointer to changing voltage table
+ * @return    1 in success
+ */
+
+static int tonga_trim_voltage_table(struct pp_hwmgr *hwmgr,
+			pp_atomctrl_voltage_table *voltage_table)
+{
+	uint32_t table_size, i, j;
+	uint16_t vvalue;
+	bool bVoltageFound = 0;
+	pp_atomctrl_voltage_table *table;
+
+	PP_ASSERT_WITH_CODE((NULL != voltage_table), "Voltage Table empty.", return -1;);
+	table_size = sizeof(pp_atomctrl_voltage_table);
+	table = kzalloc(table_size, GFP_KERNEL);
+
+	if (NULL == table)
+		return -ENOMEM;
+
+	memset(table, 0x00, table_size);
+	table->mask_low = voltage_table->mask_low;
+	table->phase_delay = voltage_table->phase_delay;
+
+	for (i = 0; i < voltage_table->count; i++) {
+		vvalue = voltage_table->entries[i].value;
+		bVoltageFound = 0;
+
+		for (j = 0; j < table->count; j++) {
+			if (vvalue == table->entries[j].value) {
+				bVoltageFound = 1;
+				break;
+			}
+		}
+
+		if (!bVoltageFound) {
+			table->entries[table->count].value = vvalue;
+			table->entries[table->count].smio_low =
+				voltage_table->entries[i].smio_low;
+			table->count++;
+		}
+	}
+
+	memcpy(table, voltage_table, sizeof(pp_atomctrl_voltage_table));
+
+	kfree(table);
+
+	return 0;
+}
+
+static int tonga_get_svi2_vdd_ci_voltage_table(
+		struct pp_hwmgr *hwmgr,
+		phm_ppt_v1_clock_voltage_dependency_table *voltage_dependency_table)
+{
+	uint32_t i;
+	int result;
+	tonga_hwmgr *data = (tonga_hwmgr *)(hwmgr->backend);
+	pp_atomctrl_voltage_table *vddci_voltage_table = &(data->vddci_voltage_table);
+
+	PP_ASSERT_WITH_CODE((0 != voltage_dependency_table->count),
+			"Voltage Dependency Table empty.", return -1;);
+
+	vddci_voltage_table->mask_low = 0;
+	vddci_voltage_table->phase_delay = 0;
+	vddci_voltage_table->count = voltage_dependency_table->count;
+
+	for (i = 0; i < voltage_dependency_table->count; i++) {
+		vddci_voltage_table->entries[i].value =
+			voltage_dependency_table->entries[i].vddci;
+		vddci_voltage_table->entries[i].smio_low = 0;
+	}
+
+	result = tonga_trim_voltage_table(hwmgr, vddci_voltage_table);
+	PP_ASSERT_WITH_CODE((0 == result),
+			"Failed to trim VDDCI table.", return result;);
+
+	return 0;
+}
+
+
+
+static int tonga_get_svi2_vdd_voltage_table(
+		struct pp_hwmgr *hwmgr,
+		phm_ppt_v1_voltage_lookup_table *look_up_table,
+		pp_atomctrl_voltage_table *voltage_table)
+{
+	uint8_t i = 0;
+
+	PP_ASSERT_WITH_CODE((0 != look_up_table->count),
+			"Voltage Lookup Table empty.", return -1;);
+
+	voltage_table->mask_low = 0;
+	voltage_table->phase_delay = 0;
+
+	voltage_table->count = look_up_table->count;
+
+	for (i = 0; i < voltage_table->count; i++) {
+		voltage_table->entries[i].value = look_up_table->entries[i].us_vdd;
+		voltage_table->entries[i].smio_low = 0;
+	}
+
+	return 0;
+}
+
+/*
+ * -------------------------------------------------------- Voltage Tables --------------------------------------------------------------------------
+ * If the voltage table would be bigger than what will fit into the state table on the SMC keep only the higher entries.
+ */
+
+static void tonga_trim_voltage_table_to_fit_state_table(
+		struct pp_hwmgr *hwmgr,
+		uint32_t max_voltage_steps,
+		pp_atomctrl_voltage_table *voltage_table)
+{
+	unsigned int i, diff;
+
+	if (voltage_table->count <= max_voltage_steps) {
+		return;
+	}
+
+	diff = voltage_table->count - max_voltage_steps;
+
+	for (i = 0; i < max_voltage_steps; i++) {
+		voltage_table->entries[i] = voltage_table->entries[i + diff];
+	}
+
+	voltage_table->count = max_voltage_steps;
+
+	return;
+}
+
+/**
+ * Create Voltage Tables.
+ *
+ * @param    hwmgr  the address of the powerplay hardware manager.
+ * @return   always 0
+ */
+int tonga_construct_voltage_tables(struct pp_hwmgr *hwmgr)
+{
+	tonga_hwmgr *data = (tonga_hwmgr *)(hwmgr->backend);
+	struct phm_ppt_v1_information *pptable_info = (struct phm_ppt_v1_information *)(hwmgr->pptable);
+	int result;
+
+	/* MVDD has only GPIO voltage control */
+	if (TONGA_VOLTAGE_CONTROL_BY_GPIO == data->mvdd_control) {
+		result = atomctrl_get_voltage_table_v3(hwmgr,
+					VOLTAGE_TYPE_MVDDC, VOLTAGE_OBJ_GPIO_LUT, &(data->mvdd_voltage_table));
+		PP_ASSERT_WITH_CODE((0 == result),
+			"Failed to retrieve MVDD table.", return result;);
+	}
+
+	if (TONGA_VOLTAGE_CONTROL_BY_GPIO == data->vdd_ci_control) {
+		/* GPIO voltage */
+		result = atomctrl_get_voltage_table_v3(hwmgr,
+					VOLTAGE_TYPE_VDDCI, VOLTAGE_OBJ_GPIO_LUT, &(data->vddci_voltage_table));
+		PP_ASSERT_WITH_CODE((0 == result),
+			"Failed to retrieve VDDCI table.", return result;);
+	} else if (TONGA_VOLTAGE_CONTROL_BY_SVID2 == data->vdd_ci_control) {
+		/* SVI2 voltage */
+		result = tonga_get_svi2_vdd_ci_voltage_table(hwmgr,
+					pptable_info->vdd_dep_on_mclk);
+		PP_ASSERT_WITH_CODE((0 == result),
+			"Failed to retrieve SVI2 VDDCI table from dependancy table.", return result;);
+	}
+
+	if (TONGA_VOLTAGE_CONTROL_BY_SVID2 == data->vdd_gfx_control) {
+		/* VDDGFX has only SVI2 voltage control */
+		result = tonga_get_svi2_vdd_voltage_table(hwmgr,
+					pptable_info->vddgfx_lookup_table, &(data->vddgfx_voltage_table));
+		PP_ASSERT_WITH_CODE((0 == result),
+			"Failed to retrieve SVI2 VDDGFX table from lookup table.", return result;);
+	}
+
+	if (TONGA_VOLTAGE_CONTROL_BY_SVID2 == data->voltage_control) {
+		/* VDDC has only SVI2 voltage control */
+		result = tonga_get_svi2_vdd_voltage_table(hwmgr,
+					pptable_info->vddc_lookup_table, &(data->vddc_voltage_table));
+		PP_ASSERT_WITH_CODE((0 == result),
+			"Failed to retrieve SVI2 VDDC table from lookup table.", return result;);
+	}
+
+	PP_ASSERT_WITH_CODE(
+			(data->vddc_voltage_table.count <= (SMU72_MAX_LEVELS_VDDC)),
+			"Too many voltage values for VDDC. Trimming to fit state table.",
+			tonga_trim_voltage_table_to_fit_state_table(hwmgr,
+			SMU72_MAX_LEVELS_VDDC, &(data->vddc_voltage_table));
+			);
+
+	PP_ASSERT_WITH_CODE(
+			(data->vddgfx_voltage_table.count <= (SMU72_MAX_LEVELS_VDDGFX)),
+			"Too many voltage values for VDDGFX. Trimming to fit state table.",
+			tonga_trim_voltage_table_to_fit_state_table(hwmgr,
+			SMU72_MAX_LEVELS_VDDGFX, &(data->vddgfx_voltage_table));
+			);
+
+	PP_ASSERT_WITH_CODE(
+			(data->vddci_voltage_table.count <= (SMU72_MAX_LEVELS_VDDCI)),
+			"Too many voltage values for VDDCI. Trimming to fit state table.",
+			tonga_trim_voltage_table_to_fit_state_table(hwmgr,
+			SMU72_MAX_LEVELS_VDDCI, &(data->vddci_voltage_table));
+			);
+
+	PP_ASSERT_WITH_CODE(
+			(data->mvdd_voltage_table.count <= (SMU72_MAX_LEVELS_MVDD)),
+			"Too many voltage values for MVDD. Trimming to fit state table.",
+			tonga_trim_voltage_table_to_fit_state_table(hwmgr,
+			SMU72_MAX_LEVELS_MVDD, &(data->mvdd_voltage_table));
+			);
+
+	return 0;
+}
+
+/**
+ * Vddc table preparation for SMC.
+ *
+ * @param    hwmgr      the address of the hardware manager
+ * @param    table     the SMC DPM table structure to be populated
+ * @return   always 0
+ */
+static int tonga_populate_smc_vddc_table(struct pp_hwmgr *hwmgr,
+			SMU72_Discrete_DpmTable *table)
+{
+	unsigned int count;
+	tonga_hwmgr *data = (tonga_hwmgr *)(hwmgr->backend);
+
+	if (TONGA_VOLTAGE_CONTROL_BY_SVID2 == data->voltage_control) {
+		table->VddcLevelCount = data->vddc_voltage_table.count;
+		for (count = 0; count < table->VddcLevelCount; count++) {
+			table->VddcTable[count] =
+				PP_HOST_TO_SMC_US(data->vddc_voltage_table.entries[count].value * VOLTAGE_SCALE);
+		}
+		CONVERT_FROM_HOST_TO_SMC_UL(table->VddcLevelCount);
+	}
+	return 0;
+}
+
+/**
+ * VddGfx table preparation for SMC.
+ *
+ * @param    hwmgr      the address of the hardware manager
+ * @param    table     the SMC DPM table structure to be populated
+ * @return   always 0
+ */
+static int tonga_populate_smc_vdd_gfx_table(struct pp_hwmgr *hwmgr,
+			SMU72_Discrete_DpmTable *table)
+{
+	unsigned int count;
+	tonga_hwmgr *data = (tonga_hwmgr *)(hwmgr->backend);
+
+	if (TONGA_VOLTAGE_CONTROL_BY_SVID2 == data->vdd_gfx_control) {
+		table->VddGfxLevelCount = data->vddgfx_voltage_table.count;
+		for (count = 0; count < data->vddgfx_voltage_table.count; count++) {
+			table->VddGfxTable[count] =
+				PP_HOST_TO_SMC_US(data->vddgfx_voltage_table.entries[count].value * VOLTAGE_SCALE);
+		}
+		CONVERT_FROM_HOST_TO_SMC_UL(table->VddGfxLevelCount);
+	}
+	return 0;
+}
+
+/**
+ * Vddci table preparation for SMC.
+ *
+ * @param    *hwmgr The address of the hardware manager.
+ * @param    *table The SMC DPM table structure to be populated.
+ * @return   0
+ */
+static int tonga_populate_smc_vdd_ci_table(struct pp_hwmgr *hwmgr,
+			SMU72_Discrete_DpmTable *table)
+{
+	tonga_hwmgr *data = (tonga_hwmgr *)(hwmgr->backend);
+	uint32_t count;
+
+	table->VddciLevelCount = data->vddci_voltage_table.count;
+	for (count = 0; count < table->VddciLevelCount; count++) {
+		if (TONGA_VOLTAGE_CONTROL_BY_SVID2 == data->vdd_ci_control) {
+			table->VddciTable[count] =
+				PP_HOST_TO_SMC_US(data->vddci_voltage_table.entries[count].value * VOLTAGE_SCALE);
+		} else if (TONGA_VOLTAGE_CONTROL_BY_GPIO == data->vdd_ci_control) {
+			table->SmioTable1.Pattern[count].Voltage =
+				PP_HOST_TO_SMC_US(data->vddci_voltage_table.entries[count].value * VOLTAGE_SCALE);
+			/* Index into DpmTable.Smio. Drive bits from Smio entry to get this voltage level. */
+			table->SmioTable1.Pattern[count].Smio =
+				(uint8_t) count;
+			table->Smio[count] |=
+				data->vddci_voltage_table.entries[count].smio_low;
+			table->VddciTable[count] =
+				PP_HOST_TO_SMC_US(data->vddci_voltage_table.entries[count].value * VOLTAGE_SCALE);
+		}
+	}
+
+	table->SmioMask1 = data->vddci_voltage_table.mask_low;
+	CONVERT_FROM_HOST_TO_SMC_UL(table->VddciLevelCount);
+
+	return 0;
+}
+
+/**
+ * Mvdd table preparation for SMC.
+ *
+ * @param    *hwmgr The address of the hardware manager.
+ * @param    *table The SMC DPM table structure to be populated.
+ * @return   0
+ */
+static int tonga_populate_smc_mvdd_table(struct pp_hwmgr *hwmgr,
+			SMU72_Discrete_DpmTable *table)
+{
+	tonga_hwmgr *data = (tonga_hwmgr *)(hwmgr->backend);
+	uint32_t count;
+
+	if (TONGA_VOLTAGE_CONTROL_BY_GPIO == data->mvdd_control) {
+		table->MvddLevelCount = data->mvdd_voltage_table.count;
+		for (count = 0; count < table->MvddLevelCount; count++) {
+			table->SmioTable2.Pattern[count].Voltage =
+				PP_HOST_TO_SMC_US(data->mvdd_voltage_table.entries[count].value * VOLTAGE_SCALE);
+			/* Index into DpmTable.Smio. Drive bits from Smio entry to get this voltage level.*/
+			table->SmioTable2.Pattern[count].Smio =
+				(uint8_t) count;
+			table->Smio[count] |=
+				data->mvdd_voltage_table.entries[count].smio_low;
+		}
+		table->SmioMask2 = data->vddci_voltage_table.mask_low;
+
+		CONVERT_FROM_HOST_TO_SMC_UL(table->MvddLevelCount);
+	}
+
+	return 0;
+}
+
+/**
+ * Convert a voltage value in mv unit to VID number required by SMU firmware
+ */
+static uint8_t convert_to_vid(uint16_t vddc)
+{
+	return (uint8_t) ((6200 - (vddc * VOLTAGE_SCALE)) / 25);
+}
+
+
+/**
+ * Preparation of vddc and vddgfx CAC tables for SMC.
+ *
+ * @param    hwmgr      the address of the hardware manager
+ * @param    table     the SMC DPM table structure to be populated
+ * @return   always 0
+ */
+static int tonga_populate_cac_tables(struct pp_hwmgr *hwmgr,
+			SMU72_Discrete_DpmTable *table)
+{
+	uint32_t count;
+	uint8_t index;
+	int result = 0;
+	tonga_hwmgr *data = (tonga_hwmgr *)(hwmgr->backend);
+	struct phm_ppt_v1_information *pptable_info = (struct phm_ppt_v1_information *)(hwmgr->pptable);
+	struct phm_ppt_v1_voltage_lookup_table *vddgfx_lookup_table = pptable_info->vddgfx_lookup_table;
+	struct phm_ppt_v1_voltage_lookup_table *vddc_lookup_table = pptable_info->vddc_lookup_table;
+
+	/* pTables is already swapped, so in order to use the value from it, we need to swap it back. */
+	uint32_t vddcLevelCount = PP_SMC_TO_HOST_UL(table->VddcLevelCount);
+	uint32_t vddgfxLevelCount = PP_SMC_TO_HOST_UL(table->VddGfxLevelCount);
+
+	for (count = 0; count < vddcLevelCount; count++) {
+		/* We are populating vddc CAC data to BapmVddc table in split and merged mode */
+		index = tonga_get_voltage_index(vddc_lookup_table,
+			data->vddc_voltage_table.entries[count].value);
+		table->BapmVddcVidLoSidd[count] =
+			convert_to_vid(vddc_lookup_table->entries[index].us_cac_low);
+		table->BapmVddcVidHiSidd[count] =
+			convert_to_vid(vddc_lookup_table->entries[index].us_cac_mid);
+		table->BapmVddcVidHiSidd2[count] =
+			convert_to_vid(vddc_lookup_table->entries[index].us_cac_high);
+	}
+
+	if ((data->vdd_gfx_control == TONGA_VOLTAGE_CONTROL_BY_SVID2)) {
+		/* We are populating vddgfx CAC data to BapmVddgfx table in split mode */
+		for (count = 0; count < vddgfxLevelCount; count++) {
+			index = tonga_get_voltage_index(vddgfx_lookup_table,
+				data->vddgfx_voltage_table.entries[count].value);
+			table->BapmVddGfxVidLoSidd[count] =
+				convert_to_vid(vddgfx_lookup_table->entries[index].us_cac_low);
+			table->BapmVddGfxVidHiSidd[count] =
+				convert_to_vid(vddgfx_lookup_table->entries[index].us_cac_mid);
+			table->BapmVddGfxVidHiSidd2[count] =
+				convert_to_vid(vddgfx_lookup_table->entries[index].us_cac_high);
+		}
+	} else {
+		for (count = 0; count < vddcLevelCount; count++) {
+			index = tonga_get_voltage_index(vddc_lookup_table,
+				data->vddc_voltage_table.entries[count].value);
+			table->BapmVddGfxVidLoSidd[count] =
+				convert_to_vid(vddc_lookup_table->entries[index].us_cac_low);
+			table->BapmVddGfxVidHiSidd[count] =
+				convert_to_vid(vddc_lookup_table->entries[index].us_cac_mid);
+			table->BapmVddGfxVidHiSidd2[count] =
+				convert_to_vid(vddc_lookup_table->entries[index].us_cac_high);
+		}
+	}
+
+	return result;
+}
+
+
+/**
+ * Preparation of voltage tables for SMC.
+ *
+ * @param    hwmgr      the address of the hardware manager
+ * @param    table     the SMC DPM table structure to be populated
+ * @return   always 0
+ */
+
+int tonga_populate_smc_voltage_tables(struct pp_hwmgr *hwmgr,
+	SMU72_Discrete_DpmTable *table)
+{
+	int result;
+
+	result = tonga_populate_smc_vddc_table(hwmgr, table);
+	PP_ASSERT_WITH_CODE(0 == result,
+			"can not populate VDDC voltage table to SMC", return -1);
+
+	result = tonga_populate_smc_vdd_ci_table(hwmgr, table);
+	PP_ASSERT_WITH_CODE(0 == result,
+			"can not populate VDDCI voltage table to SMC", return -1);
+
+	result = tonga_populate_smc_vdd_gfx_table(hwmgr, table);
+	PP_ASSERT_WITH_CODE(0 == result,
+			"can not populate VDDGFX voltage table to SMC", return -1);
+
+	result = tonga_populate_smc_mvdd_table(hwmgr, table);
+	PP_ASSERT_WITH_CODE(0 == result,
+			"can not populate MVDD voltage table to SMC", return -1);
+
+	result = tonga_populate_cac_tables(hwmgr, table);
+	PP_ASSERT_WITH_CODE(0 == result,
+			"can not populate CAC voltage tables to SMC", return -1);
+
+	return 0;
+}
+
+/**
+ * Populates the SMC VRConfig field in DPM table.
+ *
+ * @param    hwmgr      the address of the hardware manager
+ * @param    table     the SMC DPM table structure to be populated
+ * @return   always 0
+ */
+static int tonga_populate_vr_config(struct pp_hwmgr *hwmgr,
+			SMU72_Discrete_DpmTable *table)
+{
+	tonga_hwmgr *data = (tonga_hwmgr *)(hwmgr->backend);
+	uint16_t config;
+
+	if (TONGA_VOLTAGE_CONTROL_BY_SVID2 == data->vdd_gfx_control) {
+		/*  Splitted mode */
+		config = VR_SVI2_PLANE_1;
+		table->VRConfig |= (config<<VRCONF_VDDGFX_SHIFT);
+
+		if (TONGA_VOLTAGE_CONTROL_BY_SVID2 == data->voltage_control) {
+			config = VR_SVI2_PLANE_2;
+			table->VRConfig |= config;
+		} else {
+			printk(KERN_ERR "[ powerplay ] VDDC and VDDGFX should be both on SVI2 control in splitted mode! \n");
+		}
+	} else {
+		/* Merged mode  */
+		config = VR_MERGED_WITH_VDDC;
+		table->VRConfig |= (config<<VRCONF_VDDGFX_SHIFT);
+
+		/* Set Vddc Voltage Controller  */
+		if (TONGA_VOLTAGE_CONTROL_BY_SVID2 == data->voltage_control) {
+			config = VR_SVI2_PLANE_1;
+			table->VRConfig |= config;
+		} else {
+			printk(KERN_ERR "[ powerplay ] VDDC should be on SVI2 control in merged mode! \n");
+		}
+	}
+
+	/* Set Vddci Voltage Controller  */
+	if (TONGA_VOLTAGE_CONTROL_BY_SVID2 == data->vdd_ci_control) {
+		config = VR_SVI2_PLANE_2;  /* only in merged mode */
+		table->VRConfig |= (config<<VRCONF_VDDCI_SHIFT);
+	} else if (TONGA_VOLTAGE_CONTROL_BY_GPIO == data->vdd_ci_control) {
+		config = VR_SMIO_PATTERN_1;
+		table->VRConfig |= (config<<VRCONF_VDDCI_SHIFT);
+	}
+
+	/* Set Mvdd Voltage Controller */
+	if (TONGA_VOLTAGE_CONTROL_BY_GPIO == data->mvdd_control) {
+		config = VR_SMIO_PATTERN_2;
+		table->VRConfig |= (config<<VRCONF_MVDD_SHIFT);
+	}
+
+	return 0;
+}
+
+static int tonga_get_dependecy_volt_by_clk(struct pp_hwmgr *hwmgr,
+	phm_ppt_v1_clock_voltage_dependency_table *allowed_clock_voltage_table,
+	uint32_t clock, SMU_VoltageLevel *voltage, uint32_t *mvdd)
+{
+	uint32_t i = 0;
+	tonga_hwmgr *data = (tonga_hwmgr *)(hwmgr->backend);
+	struct phm_ppt_v1_information *pptable_info = (struct phm_ppt_v1_information *)(hwmgr->pptable);
+
+	/* clock - voltage dependency table is empty table */
+	if (allowed_clock_voltage_table->count == 0)
+		return -1;
+
+	for (i = 0; i < allowed_clock_voltage_table->count; i++) {
+		/* find first sclk bigger than request */
+		if (allowed_clock_voltage_table->entries[i].clk >= clock) {
+			voltage->VddGfx = tonga_get_voltage_index(pptable_info->vddgfx_lookup_table,
+								allowed_clock_voltage_table->entries[i].vddgfx);
+
+			voltage->Vddc = tonga_get_voltage_index(pptable_info->vddc_lookup_table,
+								allowed_clock_voltage_table->entries[i].vddc);
+
+			if (allowed_clock_voltage_table->entries[i].vddci) {
+				voltage->Vddci = tonga_get_voltage_id(&data->vddci_voltage_table,
+									allowed_clock_voltage_table->entries[i].vddci);
+			} else {
+				voltage->Vddci = tonga_get_voltage_id(&data->vddci_voltage_table,
+									allowed_clock_voltage_table->entries[i].vddc - data->vddc_vddci_delta);
+			}
+
+			if (allowed_clock_voltage_table->entries[i].mvdd) {
+				*mvdd = (uint32_t) allowed_clock_voltage_table->entries[i].mvdd;
+			}
+
+			voltage->Phases = 1;
+			return 0;
+		}
+	}
+
+	/* sclk is bigger than max sclk in the dependence table */
+	voltage->VddGfx = tonga_get_voltage_index(pptable_info->vddgfx_lookup_table,
+		allowed_clock_voltage_table->entries[i-1].vddgfx);
+	voltage->Vddc = tonga_get_voltage_index(pptable_info->vddc_lookup_table,
+		allowed_clock_voltage_table->entries[i-1].vddc);
+
+	if (allowed_clock_voltage_table->entries[i-1].vddci) {
+		voltage->Vddci = tonga_get_voltage_id(&data->vddci_voltage_table,
+			allowed_clock_voltage_table->entries[i-1].vddci);
+	}
+	if (allowed_clock_voltage_table->entries[i-1].mvdd) {
+		*mvdd = (uint32_t) allowed_clock_voltage_table->entries[i-1].mvdd;
+	}
+
+	return 0;
+}
+
+/**
+ * Call SMC to reset S0/S1 to S1 and Reset SMIO to initial value
+ *
+ * @param    hwmgr  the address of the powerplay hardware manager.
+ * @return   always 0
+ */
+int tonga_reset_to_default(struct pp_hwmgr *hwmgr)
+{
+	return (smum_send_msg_to_smc(hwmgr->smumgr, PPSMC_MSG_ResetToDefaults) == 0) ? 0 : 1;
+}
+
+int tonga_populate_memory_timing_parameters(
+		struct pp_hwmgr *hwmgr,
+		uint32_t engine_clock,
+		uint32_t memory_clock,
+		struct SMU72_Discrete_MCArbDramTimingTableEntry *arb_regs
+		)
+{
+	uint32_t dramTiming;
+	uint32_t dramTiming2;
+	uint32_t burstTime;
+	int result;
+
+	result = atomctrl_set_engine_dram_timings_rv770(hwmgr,
+				engine_clock, memory_clock);
+
+	PP_ASSERT_WITH_CODE(result == 0,
+		"Error calling VBIOS to set DRAM_TIMING.", return result);
+
+	dramTiming  = cgs_read_register(hwmgr->device, mmMC_ARB_DRAM_TIMING);
+	dramTiming2 = cgs_read_register(hwmgr->device, mmMC_ARB_DRAM_TIMING2);
+	burstTime = PHM_READ_FIELD(hwmgr->device, MC_ARB_BURST_TIME, STATE0);
+
+	arb_regs->McArbDramTiming  = PP_HOST_TO_SMC_UL(dramTiming);
+	arb_regs->McArbDramTiming2 = PP_HOST_TO_SMC_UL(dramTiming2);
+	arb_regs->McArbBurstTime = (uint8_t)burstTime;
+
+	return 0;
+}
+
+/**
+ * Setup parameters for the MC ARB.
+ *
+ * @param    hwmgr  the address of the powerplay hardware manager.
+ * @return   always 0
+ * This function is to be called from the SetPowerState table.
+ */
+int tonga_program_memory_timing_parameters(struct pp_hwmgr *hwmgr)
+{
+	tonga_hwmgr *data = (tonga_hwmgr *)(hwmgr->backend);
+	int result = 0;
+	SMU72_Discrete_MCArbDramTimingTable  arb_regs;
+	uint32_t i, j;
+
+	memset(&arb_regs, 0x00, sizeof(SMU72_Discrete_MCArbDramTimingTable));
+
+	for (i = 0; i < data->dpm_table.sclk_table.count; i++) {
+		for (j = 0; j < data->dpm_table.mclk_table.count; j++) {
+			result = tonga_populate_memory_timing_parameters
+				(hwmgr, data->dpm_table.sclk_table.dpm_levels[i].value,
+				 data->dpm_table.mclk_table.dpm_levels[j].value,
+				 &arb_regs.entries[i][j]);
+
+			if (0 != result) {
+				break;
+			}
+		}
+	}
+
+	if (0 == result) {
+		result = tonga_copy_bytes_to_smc(
+				hwmgr->smumgr,
+				data->arb_table_start,
+				(uint8_t *)&arb_regs,
+				sizeof(SMU72_Discrete_MCArbDramTimingTable),
+				data->sram_end
+				);
+	}
+
+	return result;
+}
+
+static int tonga_populate_smc_link_level(struct pp_hwmgr *hwmgr, SMU72_Discrete_DpmTable *table)
+{
+	tonga_hwmgr *data = (tonga_hwmgr *)(hwmgr->backend);
+	struct tonga_dpm_table *dpm_table = &data->dpm_table;
+	uint32_t i;
+
+	/* Index (dpm_table->pcie_speed_table.count) is reserved for PCIE boot level. */
+	for (i = 0; i <= dpm_table->pcie_speed_table.count; i++) {
+		table->LinkLevel[i].PcieGenSpeed  =
+			(uint8_t)dpm_table->pcie_speed_table.dpm_levels[i].value;
+		table->LinkLevel[i].PcieLaneCount =
+			(uint8_t)encode_pcie_lane_width(dpm_table->pcie_speed_table.dpm_levels[i].param1);
+		table->LinkLevel[i].EnabledForActivity =
+			1;
+		table->LinkLevel[i].SPC =
+			(uint8_t)(data->pcie_spc_cap & 0xff);
+		table->LinkLevel[i].DownThreshold =
+			PP_HOST_TO_SMC_UL(5);
+		table->LinkLevel[i].UpThreshold =
+			PP_HOST_TO_SMC_UL(30);
+	}
+
+	data->smc_state_table.LinkLevelCount =
+		(uint8_t)dpm_table->pcie_speed_table.count;
+	data->dpm_level_enable_mask.pcie_dpm_enable_mask =
+		tonga_get_dpm_level_enable_mask_value(&dpm_table->pcie_speed_table);
+
+	return 0;
+}
+
+static int tonga_populate_smc_uvd_level(struct pp_hwmgr *hwmgr,
+					SMU72_Discrete_DpmTable *table)
+{
+	int result = 0;
+
+	uint8_t count;
+	pp_atomctrl_clock_dividers_vi dividers;
+	tonga_hwmgr *data = (tonga_hwmgr *)(hwmgr->backend);
+	struct phm_ppt_v1_information *pptable_info = (struct phm_ppt_v1_information *)(hwmgr->pptable);
+	phm_ppt_v1_mm_clock_voltage_dependency_table *mm_table = pptable_info->mm_dep_table;
+
+	table->UvdLevelCount = (uint8_t) (mm_table->count);
+	table->UvdBootLevel = 0;
+
+	for (count = 0; count < table->UvdLevelCount; count++) {
+		table->UvdLevel[count].VclkFrequency = mm_table->entries[count].vclk;
+		table->UvdLevel[count].DclkFrequency = mm_table->entries[count].dclk;
+		table->UvdLevel[count].MinVoltage.Vddc =
+			tonga_get_voltage_index(pptable_info->vddc_lookup_table,
+						mm_table->entries[count].vddc);
+		table->UvdLevel[count].MinVoltage.VddGfx =
+			(data->vdd_gfx_control == TONGA_VOLTAGE_CONTROL_BY_SVID2) ?
+			tonga_get_voltage_index(pptable_info->vddgfx_lookup_table,
+						mm_table->entries[count].vddgfx) : 0;
+		table->UvdLevel[count].MinVoltage.Vddci =
+			tonga_get_voltage_id(&data->vddci_voltage_table,
+					     mm_table->entries[count].vddc - data->vddc_vddci_delta);
+		table->UvdLevel[count].MinVoltage.Phases = 1;
+
+		/* retrieve divider value for VBIOS */
+		result = atomctrl_get_dfs_pll_dividers_vi(hwmgr,
+							  table->UvdLevel[count].VclkFrequency, &dividers);
+		PP_ASSERT_WITH_CODE((0 == result),
+				    "can not find divide id for Vclk clock", return result);
+
+		table->UvdLevel[count].VclkDivider = (uint8_t)dividers.pll_post_divider;
+
+		result = atomctrl_get_dfs_pll_dividers_vi(hwmgr,
+							  table->UvdLevel[count].DclkFrequency, &dividers);
+		PP_ASSERT_WITH_CODE((0 == result),
+				    "can not find divide id for Dclk clock", return result);
+
+		table->UvdLevel[count].DclkDivider = (uint8_t)dividers.pll_post_divider;
+
+		CONVERT_FROM_HOST_TO_SMC_UL(table->UvdLevel[count].VclkFrequency);
+		CONVERT_FROM_HOST_TO_SMC_UL(table->UvdLevel[count].DclkFrequency);
+		//CONVERT_FROM_HOST_TO_SMC_UL((uint32_t)table->UvdLevel[count].MinVoltage);
+	}
+
+	return result;
+
+}
+
+static int tonga_populate_smc_vce_level(struct pp_hwmgr *hwmgr,
+		SMU72_Discrete_DpmTable *table)
+{
+	int result = 0;
+
+	uint8_t count;
+	pp_atomctrl_clock_dividers_vi dividers;
+	tonga_hwmgr *data = (tonga_hwmgr *)(hwmgr->backend);
+	struct phm_ppt_v1_information *pptable_info = (struct phm_ppt_v1_information *)(hwmgr->pptable);
+	phm_ppt_v1_mm_clock_voltage_dependency_table *mm_table = pptable_info->mm_dep_table;
+
+	table->VceLevelCount = (uint8_t) (mm_table->count);
+	table->VceBootLevel = 0;
+
+	for (count = 0; count < table->VceLevelCount; count++) {
+		table->VceLevel[count].Frequency =
+			mm_table->entries[count].eclk;
+		table->VceLevel[count].MinVoltage.Vddc =
+			tonga_get_voltage_index(pptable_info->vddc_lookup_table,
+				mm_table->entries[count].vddc);
+		table->VceLevel[count].MinVoltage.VddGfx =
+			(data->vdd_gfx_control == TONGA_VOLTAGE_CONTROL_BY_SVID2) ?
+			tonga_get_voltage_index(pptable_info->vddgfx_lookup_table,
+				mm_table->entries[count].vddgfx) : 0;
+		table->VceLevel[count].MinVoltage.Vddci =
+			tonga_get_voltage_id(&data->vddci_voltage_table,
+				mm_table->entries[count].vddc - data->vddc_vddci_delta);
+		table->VceLevel[count].MinVoltage.Phases = 1;
+
+		/* retrieve divider value for VBIOS */
+		result = atomctrl_get_dfs_pll_dividers_vi(hwmgr,
+					table->VceLevel[count].Frequency, &dividers);
+		PP_ASSERT_WITH_CODE((0 == result),
+				"can not find divide id for VCE engine clock", return result);
+
+		table->VceLevel[count].Divider = (uint8_t)dividers.pll_post_divider;
+
+		CONVERT_FROM_HOST_TO_SMC_UL(table->VceLevel[count].Frequency);
+	}
+
+	return result;
+}
+
+static int tonga_populate_smc_acp_level(struct pp_hwmgr *hwmgr,
+		SMU72_Discrete_DpmTable *table)
+{
+	int result = 0;
+	uint8_t count;
+	pp_atomctrl_clock_dividers_vi dividers;
+	tonga_hwmgr *data = (tonga_hwmgr *)(hwmgr->backend);
+	struct phm_ppt_v1_information *pptable_info = (struct phm_ppt_v1_information *)(hwmgr->pptable);
+	phm_ppt_v1_mm_clock_voltage_dependency_table *mm_table = pptable_info->mm_dep_table;
+
+	table->AcpLevelCount = (uint8_t) (mm_table->count);
+	table->AcpBootLevel = 0;
+
+	for (count = 0; count < table->AcpLevelCount; count++) {
+		table->AcpLevel[count].Frequency =
+			pptable_info->mm_dep_table->entries[count].aclk;
+		table->AcpLevel[count].MinVoltage.Vddc =
+			tonga_get_voltage_index(pptable_info->vddc_lookup_table,
+			mm_table->entries[count].vddc);
+		table->AcpLevel[count].MinVoltage.VddGfx =
+			(data->vdd_gfx_control == TONGA_VOLTAGE_CONTROL_BY_SVID2) ?
+			tonga_get_voltage_index(pptable_info->vddgfx_lookup_table,
+				mm_table->entries[count].vddgfx) : 0;
+		table->AcpLevel[count].MinVoltage.Vddci =
+			tonga_get_voltage_id(&data->vddci_voltage_table,
+				mm_table->entries[count].vddc - data->vddc_vddci_delta);
+		table->AcpLevel[count].MinVoltage.Phases = 1;
+
+		/* retrieve divider value for VBIOS */
+		result = atomctrl_get_dfs_pll_dividers_vi(hwmgr,
+			table->AcpLevel[count].Frequency, &dividers);
+		PP_ASSERT_WITH_CODE((0 == result),
+			"can not find divide id for engine clock", return result);
+
+		table->AcpLevel[count].Divider = (uint8_t)dividers.pll_post_divider;
+
+		CONVERT_FROM_HOST_TO_SMC_UL(table->AcpLevel[count].Frequency);
+	}
+
+	return result;
+}
+
+static int tonga_populate_smc_samu_level(struct pp_hwmgr *hwmgr,
+	SMU72_Discrete_DpmTable *table)
+{
+	int result = 0;
+	uint8_t count;
+	pp_atomctrl_clock_dividers_vi dividers;
+	tonga_hwmgr *data = (tonga_hwmgr *)(hwmgr->backend);
+	struct phm_ppt_v1_information *pptable_info = (struct phm_ppt_v1_information *)(hwmgr->pptable);
+	phm_ppt_v1_mm_clock_voltage_dependency_table *mm_table = pptable_info->mm_dep_table;
+
+	table->SamuBootLevel = 0;
+	table->SamuLevelCount = (uint8_t) (mm_table->count);
+
+	for (count = 0; count < table->SamuLevelCount; count++) {
+		/* not sure whether we need evclk or not */
+		table->SamuLevel[count].Frequency =
+			pptable_info->mm_dep_table->entries[count].samclock;
+		table->SamuLevel[count].MinVoltage.Vddc =
+			tonga_get_voltage_index(pptable_info->vddc_lookup_table,
+				mm_table->entries[count].vddc);
+		table->SamuLevel[count].MinVoltage.VddGfx =
+			(data->vdd_gfx_control == TONGA_VOLTAGE_CONTROL_BY_SVID2) ?
+			tonga_get_voltage_index(pptable_info->vddgfx_lookup_table,
+				mm_table->entries[count].vddgfx) : 0;
+		table->SamuLevel[count].MinVoltage.Vddci =
+			tonga_get_voltage_id(&data->vddci_voltage_table,
+				mm_table->entries[count].vddc - data->vddc_vddci_delta);
+		table->SamuLevel[count].MinVoltage.Phases = 1;
+
+		/* retrieve divider value for VBIOS */
+		result = atomctrl_get_dfs_pll_dividers_vi(hwmgr,
+					table->SamuLevel[count].Frequency, &dividers);
+		PP_ASSERT_WITH_CODE((0 == result),
+			"can not find divide id for samu clock", return result);
+
+		table->SamuLevel[count].Divider = (uint8_t)dividers.pll_post_divider;
+
+		CONVERT_FROM_HOST_TO_SMC_UL(table->SamuLevel[count].Frequency);
+	}
+
+	return result;
+}
+
+/**
+ * Populates the SMC MCLK structure using the provided memory clock
+ *
+ * @param    hwmgr      the address of the hardware manager
+ * @param    memory_clock the memory clock to use to populate the structure
+ * @param    sclk        the SMC SCLK structure to be populated
+ */
+static int tonga_calculate_mclk_params(
+		struct pp_hwmgr *hwmgr,
+		uint32_t memory_clock,
+		SMU72_Discrete_MemoryLevel *mclk,
+		bool strobe_mode,
+		bool dllStateOn
+		)
+{
+	const tonga_hwmgr *data = (tonga_hwmgr *)(hwmgr->backend);
+	uint32_t  dll_cntl = data->clock_registers.vDLL_CNTL;
+	uint32_t  mclk_pwrmgt_cntl = data->clock_registers.vMCLK_PWRMGT_CNTL;
+	uint32_t  mpll_ad_func_cntl = data->clock_registers.vMPLL_AD_FUNC_CNTL;
+	uint32_t  mpll_dq_func_cntl = data->clock_registers.vMPLL_DQ_FUNC_CNTL;
+	uint32_t  mpll_func_cntl = data->clock_registers.vMPLL_FUNC_CNTL;
+	uint32_t  mpll_func_cntl_1 = data->clock_registers.vMPLL_FUNC_CNTL_1;
+	uint32_t  mpll_func_cntl_2 = data->clock_registers.vMPLL_FUNC_CNTL_2;
+	uint32_t  mpll_ss1 = data->clock_registers.vMPLL_SS1;
+	uint32_t  mpll_ss2 = data->clock_registers.vMPLL_SS2;
+
+	pp_atomctrl_memory_clock_param mpll_param;
+	int result;
+
+	result = atomctrl_get_memory_pll_dividers_si(hwmgr,
+				memory_clock, &mpll_param, strobe_mode);
+	PP_ASSERT_WITH_CODE(0 == result,
+		"Error retrieving Memory Clock Parameters from VBIOS.", return result);
+
+	/* MPLL_FUNC_CNTL setup*/
+	mpll_func_cntl = PHM_SET_FIELD(mpll_func_cntl, MPLL_FUNC_CNTL, BWCTRL, mpll_param.bw_ctrl);
+
+	/* MPLL_FUNC_CNTL_1 setup*/
+	mpll_func_cntl_1  = PHM_SET_FIELD(mpll_func_cntl_1,
+							MPLL_FUNC_CNTL_1, CLKF, mpll_param.mpll_fb_divider.cl_kf);
+	mpll_func_cntl_1  = PHM_SET_FIELD(mpll_func_cntl_1,
+							MPLL_FUNC_CNTL_1, CLKFRAC, mpll_param.mpll_fb_divider.clk_frac);
+	mpll_func_cntl_1  = PHM_SET_FIELD(mpll_func_cntl_1,
+							MPLL_FUNC_CNTL_1, VCO_MODE, mpll_param.vco_mode);
+
+	/* MPLL_AD_FUNC_CNTL setup*/
+	mpll_ad_func_cntl = PHM_SET_FIELD(mpll_ad_func_cntl,
+							MPLL_AD_FUNC_CNTL, YCLK_POST_DIV, mpll_param.mpll_post_divider);
+
+	if (data->is_memory_GDDR5) {
+		/* MPLL_DQ_FUNC_CNTL setup*/
+		mpll_dq_func_cntl  = PHM_SET_FIELD(mpll_dq_func_cntl,
+								MPLL_DQ_FUNC_CNTL, YCLK_SEL, mpll_param.yclk_sel);
+		mpll_dq_func_cntl  = PHM_SET_FIELD(mpll_dq_func_cntl,
+								MPLL_DQ_FUNC_CNTL, YCLK_POST_DIV, mpll_param.mpll_post_divider);
+	}
+
+	if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
+			PHM_PlatformCaps_MemorySpreadSpectrumSupport)) {
+		/*
+		 ************************************
+		 Fref = Reference Frequency
+		 NF = Feedback divider ratio
+		 NR = Reference divider ratio
+		 Fnom = Nominal VCO output frequency = Fref * NF / NR
+		 Fs = Spreading Rate
+		 D = Percentage down-spread / 2
+		 Fint = Reference input frequency to PFD = Fref / NR
+		 NS = Spreading rate divider ratio = int(Fint / (2 * Fs))
+		 CLKS = NS - 1 = ISS_STEP_NUM[11:0]
+		 NV = D * Fs / Fnom * 4 * ((Fnom/Fref * NR) ^ 2)
+		 CLKV = 65536 * NV = ISS_STEP_SIZE[25:0]
+		 *************************************
+		 */
+		pp_atomctrl_internal_ss_info ss_info;
+		uint32_t freq_nom;
+		uint32_t tmp;
+		uint32_t reference_clock = atomctrl_get_mpll_reference_clock(hwmgr);
+
+		/* for GDDR5 for all modes and DDR3 */
+		if (1 == mpll_param.qdr)
+			freq_nom = memory_clock * 4 * (1 << mpll_param.mpll_post_divider);
+		else
+			freq_nom = memory_clock * 2 * (1 << mpll_param.mpll_post_divider);
+
+		/* tmp = (freq_nom / reference_clock * reference_divider) ^ 2  Note: S.I. reference_divider = 1*/
+		tmp = (freq_nom / reference_clock);
+		tmp = tmp * tmp;
+
+		if (0 == atomctrl_get_memory_clock_spread_spectrum(hwmgr, freq_nom, &ss_info)) {
+			/* ss_info.speed_spectrum_percentage -- in unit of 0.01% */
+			/* ss.Info.speed_spectrum_rate -- in unit of khz */
+			/* CLKS = reference_clock / (2 * speed_spectrum_rate * reference_divider) * 10 */
+			/*     = reference_clock * 5 / speed_spectrum_rate */
+			uint32_t clks = reference_clock * 5 / ss_info.speed_spectrum_rate;
+
+			/* CLKV = 65536 * speed_spectrum_percentage / 2 * spreadSpecrumRate / freq_nom * 4 / 100000 * ((freq_nom / reference_clock) ^ 2) */
+			/*     = 131 * speed_spectrum_percentage * speed_spectrum_rate / 100 * ((freq_nom / reference_clock) ^ 2) / freq_nom */
+			uint32_t clkv =
+				(uint32_t)((((131 * ss_info.speed_spectrum_percentage *
+							ss_info.speed_spectrum_rate) / 100) * tmp) / freq_nom);
+
+			mpll_ss1 = PHM_SET_FIELD(mpll_ss1, MPLL_SS1, CLKV, clkv);
+			mpll_ss2 = PHM_SET_FIELD(mpll_ss2, MPLL_SS2, CLKS, clks);
+		}
+	}
+
+	/* MCLK_PWRMGT_CNTL setup */
+	mclk_pwrmgt_cntl = PHM_SET_FIELD(mclk_pwrmgt_cntl,
+		MCLK_PWRMGT_CNTL, DLL_SPEED, mpll_param.dll_speed);
+	mclk_pwrmgt_cntl = PHM_SET_FIELD(mclk_pwrmgt_cntl,
+		MCLK_PWRMGT_CNTL, MRDCK0_PDNB, dllStateOn);
+	mclk_pwrmgt_cntl = PHM_SET_FIELD(mclk_pwrmgt_cntl,
+		MCLK_PWRMGT_CNTL, MRDCK1_PDNB, dllStateOn);
+
+
+	/* Save the result data to outpupt memory level structure */
+	mclk->MclkFrequency   = memory_clock;
+	mclk->MpllFuncCntl    = mpll_func_cntl;
+	mclk->MpllFuncCntl_1  = mpll_func_cntl_1;
+	mclk->MpllFuncCntl_2  = mpll_func_cntl_2;
+	mclk->MpllAdFuncCntl  = mpll_ad_func_cntl;
+	mclk->MpllDqFuncCntl  = mpll_dq_func_cntl;
+	mclk->MclkPwrmgtCntl  = mclk_pwrmgt_cntl;
+	mclk->DllCntl         = dll_cntl;
+	mclk->MpllSs1         = mpll_ss1;
+	mclk->MpllSs2         = mpll_ss2;
+
+	return 0;
+}
+
+static uint8_t tonga_get_mclk_frequency_ratio(uint32_t memory_clock,
+		bool strobe_mode)
+{
+	uint8_t mc_para_index;
+
+	if (strobe_mode) {
+		if (memory_clock < 12500) {
+			mc_para_index = 0x00;
+		} else if (memory_clock > 47500) {
+			mc_para_index = 0x0f;
+		} else {
+			mc_para_index = (uint8_t)((memory_clock - 10000) / 2500);
+		}
+	} else {
+		if (memory_clock < 65000) {
+			mc_para_index = 0x00;
+		} else if (memory_clock > 135000) {
+			mc_para_index = 0x0f;
+		} else {
+			mc_para_index = (uint8_t)((memory_clock - 60000) / 5000);
+		}
+	}
+
+	return mc_para_index;
+}
+
+static uint8_t tonga_get_ddr3_mclk_frequency_ratio(uint32_t memory_clock)
+{
+	uint8_t mc_para_index;
+
+	if (memory_clock < 10000) {
+		mc_para_index = 0;
+	} else if (memory_clock >= 80000) {
+		mc_para_index = 0x0f;
+	} else {
+		mc_para_index = (uint8_t)((memory_clock - 10000) / 5000 + 1);
+	}
+
+	return mc_para_index;
+}
+
+static int tonga_populate_single_memory_level(
+		struct pp_hwmgr *hwmgr,
+		uint32_t memory_clock,
+		SMU72_Discrete_MemoryLevel *memory_level
+		)
+{
+	uint32_t minMvdd = 0;
+	tonga_hwmgr *data = (tonga_hwmgr *)(hwmgr->backend);
+	struct phm_ppt_v1_information *pptable_info = (struct phm_ppt_v1_information *)(hwmgr->pptable);
+	int result = 0;
+	bool dllStateOn;
+	struct cgs_display_info info = {0};
+
+
+	if (NULL != pptable_info->vdd_dep_on_mclk) {
+		result = tonga_get_dependecy_volt_by_clk(hwmgr,
+			pptable_info->vdd_dep_on_mclk, memory_clock, &memory_level->MinVoltage, &minMvdd);
+		PP_ASSERT_WITH_CODE((0 == result),
+			"can not find MinVddc voltage value from memory VDDC voltage dependency table", return result);
+	}
+
+	if (data->mvdd_control == TONGA_VOLTAGE_CONTROL_NONE) {
+		memory_level->MinMvdd = data->vbios_boot_state.mvdd_bootup_value;
+	} else {
+		memory_level->MinMvdd = minMvdd;
+	}
+	memory_level->EnabledForThrottle = 1;
+	memory_level->EnabledForActivity = 0;
+	memory_level->UpHyst = 0;
+	memory_level->DownHyst = 100;
+	memory_level->VoltageDownHyst = 0;
+
+	/* Indicates maximum activity level for this performance level.*/
+	memory_level->ActivityLevel = (uint16_t)data->mclk_activity_target;
+	memory_level->StutterEnable = 0;
+	memory_level->StrobeEnable = 0;
+	memory_level->EdcReadEnable = 0;
+	memory_level->EdcWriteEnable = 0;
+	memory_level->RttEnable = 0;
+
+	/* default set to low watermark. Highest level will be set to high later.*/
+	memory_level->DisplayWatermark = PPSMC_DISPLAY_WATERMARK_LOW;
+
+	cgs_get_active_displays_info(hwmgr->device, &info);
+	data->display_timing.num_existing_displays = info.display_count;
+
+	if ((data->mclk_stutter_mode_threshold != 0) &&
+			(memory_clock <= data->mclk_stutter_mode_threshold) &&
+			(data->is_uvd_enabled == 0)
+#if defined(LINUX)
+			&& (PHM_READ_FIELD(hwmgr->device, DPG_PIPE_STUTTER_CONTROL, STUTTER_ENABLE) & 0x1)
+			&& (data->display_timing.num_existing_displays <= 2)
+			&& (data->display_timing.num_existing_displays != 0)
+#endif
+	)
+		memory_level->StutterEnable = 1;
+
+	/* decide strobe mode*/
+	memory_level->StrobeEnable = (data->mclk_strobe_mode_threshold != 0) &&
+		(memory_clock <= data->mclk_strobe_mode_threshold);
+
+	/* decide EDC mode and memory clock ratio*/
+	if (data->is_memory_GDDR5) {
+		memory_level->StrobeRatio = tonga_get_mclk_frequency_ratio(memory_clock,
+					memory_level->StrobeEnable);
+
+		if ((data->mclk_edc_enable_threshold != 0) &&
+				(memory_clock > data->mclk_edc_enable_threshold)) {
+			memory_level->EdcReadEnable = 1;
+		}
+
+		if ((data->mclk_edc_wr_enable_threshold != 0) &&
+				(memory_clock > data->mclk_edc_wr_enable_threshold)) {
+			memory_level->EdcWriteEnable = 1;
+		}
+
+		if (memory_level->StrobeEnable) {
+			if (tonga_get_mclk_frequency_ratio(memory_clock, 1) >=
+					((cgs_read_register(hwmgr->device, mmMC_SEQ_MISC7) >> 16) & 0xf)) {
+				dllStateOn = ((cgs_read_register(hwmgr->device, mmMC_SEQ_MISC5) >> 1) & 0x1) ? 1 : 0;
+			} else {
+				dllStateOn = ((cgs_read_register(hwmgr->device, mmMC_SEQ_MISC6) >> 1) & 0x1) ? 1 : 0;
+			}
+
+		} else {
+			dllStateOn = data->dll_defaule_on;
+		}
+	} else {
+		memory_level->StrobeRatio =
+			tonga_get_ddr3_mclk_frequency_ratio(memory_clock);
+		dllStateOn = ((cgs_read_register(hwmgr->device, mmMC_SEQ_MISC5) >> 1) & 0x1) ? 1 : 0;
+	}
+
+	result = tonga_calculate_mclk_params(hwmgr,
+		memory_clock, memory_level, memory_level->StrobeEnable, dllStateOn);
+
+	if (0 == result) {
+		CONVERT_FROM_HOST_TO_SMC_UL(memory_level->MinMvdd);
+		/* MCLK frequency in units of 10KHz*/
+		CONVERT_FROM_HOST_TO_SMC_UL(memory_level->MclkFrequency);
+		/* Indicates maximum activity level for this performance level.*/
+		CONVERT_FROM_HOST_TO_SMC_US(memory_level->ActivityLevel);
+		CONVERT_FROM_HOST_TO_SMC_UL(memory_level->MpllFuncCntl);
+		CONVERT_FROM_HOST_TO_SMC_UL(memory_level->MpllFuncCntl_1);
+		CONVERT_FROM_HOST_TO_SMC_UL(memory_level->MpllFuncCntl_2);
+		CONVERT_FROM_HOST_TO_SMC_UL(memory_level->MpllAdFuncCntl);
+		CONVERT_FROM_HOST_TO_SMC_UL(memory_level->MpllDqFuncCntl);
+		CONVERT_FROM_HOST_TO_SMC_UL(memory_level->MclkPwrmgtCntl);
+		CONVERT_FROM_HOST_TO_SMC_UL(memory_level->DllCntl);
+		CONVERT_FROM_HOST_TO_SMC_UL(memory_level->MpllSs1);
+		CONVERT_FROM_HOST_TO_SMC_UL(memory_level->MpllSs2);
+	}
+
+	return result;
+}
+
+/**
+ * Populates the SMC MVDD structure using the provided memory clock.
+ *
+ * @param    hwmgr      the address of the hardware manager
+ * @param    mclk        the MCLK value to be used in the decision if MVDD should be high or low.
+ * @param    voltage     the SMC VOLTAGE structure to be populated
+ */
+int tonga_populate_mvdd_value(struct pp_hwmgr *hwmgr, uint32_t mclk, SMIO_Pattern *smio_pattern)
+{
+	const tonga_hwmgr *data = (tonga_hwmgr *)(hwmgr->backend);
+	struct phm_ppt_v1_information *pptable_info = (struct phm_ppt_v1_information *)(hwmgr->pptable);
+	uint32_t i = 0;
+
+	if (TONGA_VOLTAGE_CONTROL_NONE != data->mvdd_control) {
+		/* find mvdd value which clock is more than request */
+		for (i = 0; i < pptable_info->vdd_dep_on_mclk->count; i++) {
+			if (mclk <= pptable_info->vdd_dep_on_mclk->entries[i].clk) {
+				/* Always round to higher voltage. */
+				smio_pattern->Voltage = data->mvdd_voltage_table.entries[i].value;
+				break;
+			}
+		}
+
+		PP_ASSERT_WITH_CODE(i < pptable_info->vdd_dep_on_mclk->count,
+			"MVDD Voltage is outside the supported range.", return -1);
+
+	} else {
+		return -1;
+	}
+
+	return 0;
+}
+
+
+static int tonga_populate_smv_acpi_level(struct pp_hwmgr *hwmgr,
+	SMU72_Discrete_DpmTable *table)
+{
+	int result = 0;
+	const tonga_hwmgr *data = (tonga_hwmgr *)(hwmgr->backend);
+	pp_atomctrl_clock_dividers_vi dividers;
+	SMIO_Pattern voltage_level;
+	uint32_t spll_func_cntl    = data->clock_registers.vCG_SPLL_FUNC_CNTL;
+	uint32_t spll_func_cntl_2  = data->clock_registers.vCG_SPLL_FUNC_CNTL_2;
+	uint32_t dll_cntl          = data->clock_registers.vDLL_CNTL;
+	uint32_t mclk_pwrmgt_cntl  = data->clock_registers.vMCLK_PWRMGT_CNTL;
+
+	/* The ACPI state should not do DPM on DC (or ever).*/
+	table->ACPILevel.Flags &= ~PPSMC_SWSTATE_FLAG_DC;
+
+	table->ACPILevel.MinVoltage = data->smc_state_table.GraphicsLevel[0].MinVoltage;
+
+	/* assign zero for now*/
+	table->ACPILevel.SclkFrequency = atomctrl_get_reference_clock(hwmgr);
+
+	/* get the engine clock dividers for this clock value*/
+	result = atomctrl_get_engine_pll_dividers_vi(hwmgr,
+		table->ACPILevel.SclkFrequency,  &dividers);
+
+	PP_ASSERT_WITH_CODE(result == 0,
+		"Error retrieving Engine Clock dividers from VBIOS.", return result);
+
+	/* divider ID for required SCLK*/
+	table->ACPILevel.SclkDid = (uint8_t)dividers.pll_post_divider;
+	table->ACPILevel.DisplayWatermark = PPSMC_DISPLAY_WATERMARK_LOW;
+	table->ACPILevel.DeepSleepDivId = 0;
+
+	spll_func_cntl      = PHM_SET_FIELD(spll_func_cntl,
+							CG_SPLL_FUNC_CNTL,   SPLL_PWRON,     0);
+	spll_func_cntl      = PHM_SET_FIELD(spll_func_cntl,
+							CG_SPLL_FUNC_CNTL,   SPLL_RESET,     1);
+	spll_func_cntl_2    = PHM_SET_FIELD(spll_func_cntl_2,
+							CG_SPLL_FUNC_CNTL_2, SCLK_MUX_SEL,   4);
+
+	table->ACPILevel.CgSpllFuncCntl = spll_func_cntl;
+	table->ACPILevel.CgSpllFuncCntl2 = spll_func_cntl_2;
+	table->ACPILevel.CgSpllFuncCntl3 = data->clock_registers.vCG_SPLL_FUNC_CNTL_3;
+	table->ACPILevel.CgSpllFuncCntl4 = data->clock_registers.vCG_SPLL_FUNC_CNTL_4;
+	table->ACPILevel.SpllSpreadSpectrum = data->clock_registers.vCG_SPLL_SPREAD_SPECTRUM;
+	table->ACPILevel.SpllSpreadSpectrum2 = data->clock_registers.vCG_SPLL_SPREAD_SPECTRUM_2;
+	table->ACPILevel.CcPwrDynRm = 0;
+	table->ACPILevel.CcPwrDynRm1 = 0;
+
+
+	/* For various features to be enabled/disabled while this level is active.*/
+	CONVERT_FROM_HOST_TO_SMC_UL(table->ACPILevel.Flags);
+	/* SCLK frequency in units of 10KHz*/
+	CONVERT_FROM_HOST_TO_SMC_UL(table->ACPILevel.SclkFrequency);
+	CONVERT_FROM_HOST_TO_SMC_UL(table->ACPILevel.CgSpllFuncCntl);
+	CONVERT_FROM_HOST_TO_SMC_UL(table->ACPILevel.CgSpllFuncCntl2);
+	CONVERT_FROM_HOST_TO_SMC_UL(table->ACPILevel.CgSpllFuncCntl3);
+	CONVERT_FROM_HOST_TO_SMC_UL(table->ACPILevel.CgSpllFuncCntl4);
+	CONVERT_FROM_HOST_TO_SMC_UL(table->ACPILevel.SpllSpreadSpectrum);
+	CONVERT_FROM_HOST_TO_SMC_UL(table->ACPILevel.SpllSpreadSpectrum2);
+	CONVERT_FROM_HOST_TO_SMC_UL(table->ACPILevel.CcPwrDynRm);
+	CONVERT_FROM_HOST_TO_SMC_UL(table->ACPILevel.CcPwrDynRm1);
+
+	/* table->MemoryACPILevel.MinVddcPhases = table->ACPILevel.MinVddcPhases;*/
+	table->MemoryACPILevel.MinVoltage = data->smc_state_table.MemoryLevel[0].MinVoltage;
+
+	/*  CONVERT_FROM_HOST_TO_SMC_UL(table->MemoryACPILevel.MinVoltage);*/
+
+	if (0 == tonga_populate_mvdd_value(hwmgr, 0, &voltage_level))
+		table->MemoryACPILevel.MinMvdd =
+			PP_HOST_TO_SMC_UL(voltage_level.Voltage * VOLTAGE_SCALE);
+	else
+		table->MemoryACPILevel.MinMvdd = 0;
+
+	/* Force reset on DLL*/
+	mclk_pwrmgt_cntl    = PHM_SET_FIELD(mclk_pwrmgt_cntl,
+		MCLK_PWRMGT_CNTL, MRDCK0_RESET, 0x1);
+	mclk_pwrmgt_cntl    = PHM_SET_FIELD(mclk_pwrmgt_cntl,
+		MCLK_PWRMGT_CNTL, MRDCK1_RESET, 0x1);
+
+	/* Disable DLL in ACPIState*/
+	mclk_pwrmgt_cntl    = PHM_SET_FIELD(mclk_pwrmgt_cntl,
+		MCLK_PWRMGT_CNTL, MRDCK0_PDNB, 0);
+	mclk_pwrmgt_cntl    = PHM_SET_FIELD(mclk_pwrmgt_cntl,
+		MCLK_PWRMGT_CNTL, MRDCK1_PDNB, 0);
+
+	/* Enable DLL bypass signal*/
+	dll_cntl            = PHM_SET_FIELD(dll_cntl,
+		DLL_CNTL, MRDCK0_BYPASS, 0);
+	dll_cntl            = PHM_SET_FIELD(dll_cntl,
+		DLL_CNTL, MRDCK1_BYPASS, 0);
+
+	table->MemoryACPILevel.DllCntl            =
+		PP_HOST_TO_SMC_UL(dll_cntl);
+	table->MemoryACPILevel.MclkPwrmgtCntl     =
+		PP_HOST_TO_SMC_UL(mclk_pwrmgt_cntl);
+	table->MemoryACPILevel.MpllAdFuncCntl     =
+		PP_HOST_TO_SMC_UL(data->clock_registers.vMPLL_AD_FUNC_CNTL);
+	table->MemoryACPILevel.MpllDqFuncCntl     =
+		PP_HOST_TO_SMC_UL(data->clock_registers.vMPLL_DQ_FUNC_CNTL);
+	table->MemoryACPILevel.MpllFuncCntl       =
+		PP_HOST_TO_SMC_UL(data->clock_registers.vMPLL_FUNC_CNTL);
+	table->MemoryACPILevel.MpllFuncCntl_1     =
+		PP_HOST_TO_SMC_UL(data->clock_registers.vMPLL_FUNC_CNTL_1);
+	table->MemoryACPILevel.MpllFuncCntl_2     =
+		PP_HOST_TO_SMC_UL(data->clock_registers.vMPLL_FUNC_CNTL_2);
+	table->MemoryACPILevel.MpllSs1            =
+		PP_HOST_TO_SMC_UL(data->clock_registers.vMPLL_SS1);
+	table->MemoryACPILevel.MpllSs2            =
+		PP_HOST_TO_SMC_UL(data->clock_registers.vMPLL_SS2);
+
+	table->MemoryACPILevel.EnabledForThrottle = 0;
+	table->MemoryACPILevel.EnabledForActivity = 0;
+	table->MemoryACPILevel.UpHyst = 0;
+	table->MemoryACPILevel.DownHyst = 100;
+	table->MemoryACPILevel.VoltageDownHyst = 0;
+	/* Indicates maximum activity level for this performance level.*/
+	table->MemoryACPILevel.ActivityLevel = PP_HOST_TO_SMC_US((uint16_t)data->mclk_activity_target);
+
+	table->MemoryACPILevel.StutterEnable = 0;
+	table->MemoryACPILevel.StrobeEnable = 0;
+	table->MemoryACPILevel.EdcReadEnable = 0;
+	table->MemoryACPILevel.EdcWriteEnable = 0;
+	table->MemoryACPILevel.RttEnable = 0;
+
+	return result;
+}
+
+static int tonga_find_boot_level(struct tonga_single_dpm_table *table, uint32_t value, uint32_t *boot_level)
+{
+	int result = 0;
+	uint32_t i;
+
+	for (i = 0; i < table->count; i++) {
+		if (value == table->dpm_levels[i].value) {
+			*boot_level = i;
+			result = 0;
+		}
+	}
+	return result;
+}
+
+static int tonga_populate_smc_boot_level(struct pp_hwmgr *hwmgr,
+			SMU72_Discrete_DpmTable *table)
+{
+	int result = 0;
+	tonga_hwmgr *data = (tonga_hwmgr *)(hwmgr->backend);
+
+	table->GraphicsBootLevel  = 0;        /* 0 == DPM[0] (low), etc. */
+	table->MemoryBootLevel    = 0;        /* 0 == DPM[0] (low), etc. */
+
+	/* find boot level from dpm table*/
+	result = tonga_find_boot_level(&(data->dpm_table.sclk_table),
+	data->vbios_boot_state.sclk_bootup_value,
+	(uint32_t *)&(data->smc_state_table.GraphicsBootLevel));
+
+	if (0 != result) {
+		data->smc_state_table.GraphicsBootLevel = 0;
+		printk(KERN_ERR "[ powerplay ] VBIOS did not find boot engine clock value \
+			in dependency table. Using Graphics DPM level 0!");
+		result = 0;
+	}
+
+	result = tonga_find_boot_level(&(data->dpm_table.mclk_table),
+		data->vbios_boot_state.mclk_bootup_value,
+		(uint32_t *)&(data->smc_state_table.MemoryBootLevel));
+
+	if (0 != result) {
+		data->smc_state_table.MemoryBootLevel = 0;
+		printk(KERN_ERR "[ powerplay ] VBIOS did not find boot engine clock value \
+			in dependency table. Using Memory DPM level 0!");
+		result = 0;
+	}
+
+	table->BootVoltage.Vddc =
+		tonga_get_voltage_id(&(data->vddc_voltage_table),
+			data->vbios_boot_state.vddc_bootup_value);
+	table->BootVoltage.VddGfx =
+		tonga_get_voltage_id(&(data->vddgfx_voltage_table),
+			data->vbios_boot_state.vddgfx_bootup_value);
+	table->BootVoltage.Vddci =
+		tonga_get_voltage_id(&(data->vddci_voltage_table),
+			data->vbios_boot_state.vddci_bootup_value);
+	table->BootMVdd = data->vbios_boot_state.mvdd_bootup_value;
+
+	CONVERT_FROM_HOST_TO_SMC_US(table->BootMVdd);
+
+	return result;
+}
+
+
+/**
+ * Calculates the SCLK dividers using the provided engine clock
+ *
+ * @param    hwmgr      the address of the hardware manager
+ * @param    engine_clock the engine clock to use to populate the structure
+ * @param    sclk        the SMC SCLK structure to be populated
+ */
+int tonga_calculate_sclk_params(struct pp_hwmgr *hwmgr,
+		uint32_t engine_clock, SMU72_Discrete_GraphicsLevel *sclk)
+{
+	const tonga_hwmgr *data = (tonga_hwmgr *)(hwmgr->backend);
+	pp_atomctrl_clock_dividers_vi dividers;
+	uint32_t spll_func_cntl            = data->clock_registers.vCG_SPLL_FUNC_CNTL;
+	uint32_t spll_func_cntl_3          = data->clock_registers.vCG_SPLL_FUNC_CNTL_3;
+	uint32_t spll_func_cntl_4          = data->clock_registers.vCG_SPLL_FUNC_CNTL_4;
+	uint32_t cg_spll_spread_spectrum   = data->clock_registers.vCG_SPLL_SPREAD_SPECTRUM;
+	uint32_t cg_spll_spread_spectrum_2 = data->clock_registers.vCG_SPLL_SPREAD_SPECTRUM_2;
+	uint32_t    reference_clock;
+	uint32_t reference_divider;
+	uint32_t fbdiv;
+	int result;
+
+	/* get the engine clock dividers for this clock value*/
+	result = atomctrl_get_engine_pll_dividers_vi(hwmgr, engine_clock,  &dividers);
+
+	PP_ASSERT_WITH_CODE(result == 0,
+		"Error retrieving Engine Clock dividers from VBIOS.", return result);
+
+	/* To get FBDIV we need to multiply this by 16384 and divide it by Fref.*/
+	reference_clock = atomctrl_get_reference_clock(hwmgr);
+
+	reference_divider = 1 + dividers.uc_pll_ref_div;
+
+	/* low 14 bits is fraction and high 12 bits is divider*/
+	fbdiv = dividers.ul_fb_div.ul_fb_divider & 0x3FFFFFF;
+
+	/* SPLL_FUNC_CNTL setup*/
+	spll_func_cntl = PHM_SET_FIELD(spll_func_cntl,
+		CG_SPLL_FUNC_CNTL, SPLL_REF_DIV, dividers.uc_pll_ref_div);
+	spll_func_cntl = PHM_SET_FIELD(spll_func_cntl,
+		CG_SPLL_FUNC_CNTL, SPLL_PDIV_A,  dividers.uc_pll_post_div);
+
+	/* SPLL_FUNC_CNTL_3 setup*/
+	spll_func_cntl_3 = PHM_SET_FIELD(spll_func_cntl_3,
+		CG_SPLL_FUNC_CNTL_3, SPLL_FB_DIV, fbdiv);
+
+	/* set to use fractional accumulation*/
+	spll_func_cntl_3 = PHM_SET_FIELD(spll_func_cntl_3,
+		CG_SPLL_FUNC_CNTL_3, SPLL_DITHEN, 1);
+
+	if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
+			PHM_PlatformCaps_EngineSpreadSpectrumSupport)) {
+		pp_atomctrl_internal_ss_info ss_info;
+
+		uint32_t vcoFreq = engine_clock * dividers.uc_pll_post_div;
+		if (0 == atomctrl_get_engine_clock_spread_spectrum(hwmgr, vcoFreq, &ss_info)) {
+			/*
+			* ss_info.speed_spectrum_percentage -- in unit of 0.01%
+			* ss_info.speed_spectrum_rate -- in unit of khz
+			*/
+			/* clks = reference_clock * 10 / (REFDIV + 1) / speed_spectrum_rate / 2 */
+			uint32_t clkS = reference_clock * 5 / (reference_divider * ss_info.speed_spectrum_rate);
+
+			/* clkv = 2 * D * fbdiv / NS */
+			uint32_t clkV = 4 * ss_info.speed_spectrum_percentage * fbdiv / (clkS * 10000);
+
+			cg_spll_spread_spectrum =
+				PHM_SET_FIELD(cg_spll_spread_spectrum, CG_SPLL_SPREAD_SPECTRUM, CLKS, clkS);
+			cg_spll_spread_spectrum =
+				PHM_SET_FIELD(cg_spll_spread_spectrum, CG_SPLL_SPREAD_SPECTRUM, SSEN, 1);
+			cg_spll_spread_spectrum_2 =
+				PHM_SET_FIELD(cg_spll_spread_spectrum_2, CG_SPLL_SPREAD_SPECTRUM_2, CLKV, clkV);
+		}
+	}
+
+	sclk->SclkFrequency        = engine_clock;
+	sclk->CgSpllFuncCntl3      = spll_func_cntl_3;
+	sclk->CgSpllFuncCntl4      = spll_func_cntl_4;
+	sclk->SpllSpreadSpectrum   = cg_spll_spread_spectrum;
+	sclk->SpllSpreadSpectrum2  = cg_spll_spread_spectrum_2;
+	sclk->SclkDid              = (uint8_t)dividers.pll_post_divider;
+
+	return 0;
+}
+
+/**
+ * Populates single SMC SCLK structure using the provided engine clock
+ *
+ * @param    hwmgr      the address of the hardware manager
+ * @param    engine_clock the engine clock to use to populate the structure
+ * @param    sclk        the SMC SCLK structure to be populated
+ */
+static int tonga_populate_single_graphic_level(struct pp_hwmgr *hwmgr, uint32_t engine_clock, uint16_t sclk_activity_level_threshold, SMU72_Discrete_GraphicsLevel *graphic_level)
+{
+	int result;
+	uint32_t threshold;
+	uint32_t mvdd;
+	tonga_hwmgr *data = (tonga_hwmgr *)(hwmgr->backend);
+	struct phm_ppt_v1_information *pptable_info = (struct phm_ppt_v1_information *)(hwmgr->pptable);
+
+	result = tonga_calculate_sclk_params(hwmgr, engine_clock, graphic_level);
+
+
+	/* populate graphics levels*/
+	result = tonga_get_dependecy_volt_by_clk(hwmgr,
+		pptable_info->vdd_dep_on_sclk, engine_clock,
+		&graphic_level->MinVoltage, &mvdd);
+	PP_ASSERT_WITH_CODE((0 == result),
+		"can not find VDDC voltage value for VDDC	\
+		engine clock dependency table", return result);
+
+	/* SCLK frequency in units of 10KHz*/
+	graphic_level->SclkFrequency = engine_clock;
+
+	/* Indicates maximum activity level for this performance level. 50% for now*/
+	graphic_level->ActivityLevel = sclk_activity_level_threshold;
+
+	graphic_level->CcPwrDynRm = 0;
+	graphic_level->CcPwrDynRm1 = 0;
+	/* this level can be used if activity is high enough.*/
+	graphic_level->EnabledForActivity = 0;
+	/* this level can be used for throttling.*/
+	graphic_level->EnabledForThrottle = 1;
+	graphic_level->UpHyst = 0;
+	graphic_level->DownHyst = 0;
+	graphic_level->VoltageDownHyst = 0;
+	graphic_level->PowerThrottle = 0;
+
+	threshold = engine_clock * data->fast_watemark_threshold / 100;
+/*
+	*get the DAL clock. do it in funture.
+	PECI_GetMinClockSettings(hwmgr->peci, &minClocks);
+	data->display_timing.min_clock_insr = minClocks.engineClockInSR;
+
+	if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_SclkDeepSleep))
+	{
+		graphic_level->DeepSleepDivId = PhwTonga_GetSleepDividerIdFromClock(hwmgr, engine_clock, minClocks.engineClockInSR);
+	}
+*/
+
+	/* Default to slow, highest DPM level will be set to PPSMC_DISPLAY_WATERMARK_LOW later.*/
+	graphic_level->DisplayWatermark = PPSMC_DISPLAY_WATERMARK_LOW;
+
+	if (0 == result) {
+		/* CONVERT_FROM_HOST_TO_SMC_UL(graphic_level->MinVoltage);*/
+		/* CONVERT_FROM_HOST_TO_SMC_UL(graphic_level->MinVddcPhases);*/
+		CONVERT_FROM_HOST_TO_SMC_UL(graphic_level->SclkFrequency);
+		CONVERT_FROM_HOST_TO_SMC_US(graphic_level->ActivityLevel);
+		CONVERT_FROM_HOST_TO_SMC_UL(graphic_level->CgSpllFuncCntl3);
+		CONVERT_FROM_HOST_TO_SMC_UL(graphic_level->CgSpllFuncCntl4);
+		CONVERT_FROM_HOST_TO_SMC_UL(graphic_level->SpllSpreadSpectrum);
+		CONVERT_FROM_HOST_TO_SMC_UL(graphic_level->SpllSpreadSpectrum2);
+		CONVERT_FROM_HOST_TO_SMC_UL(graphic_level->CcPwrDynRm);
+		CONVERT_FROM_HOST_TO_SMC_UL(graphic_level->CcPwrDynRm1);
+	}
+
+	return result;
+}
+
+/**
+ * Populates all SMC SCLK levels' structure based on the trimmed allowed dpm engine clock states
+ *
+ * @param    hwmgr      the address of the hardware manager
+ */
+static int tonga_populate_all_graphic_levels(struct pp_hwmgr *hwmgr)
+{
+	tonga_hwmgr *data = (tonga_hwmgr *)(hwmgr->backend);
+	struct phm_ppt_v1_information *pptable_info = (struct phm_ppt_v1_information *)(hwmgr->pptable);
+	struct tonga_dpm_table *dpm_table = &data->dpm_table;
+	phm_ppt_v1_pcie_table *pcie_table = pptable_info->pcie_table;
+	uint8_t pcie_entry_count = (uint8_t) data->dpm_table.pcie_speed_table.count;
+	int result = 0;
+	uint32_t level_array_adress = data->dpm_table_start +
+		offsetof(SMU72_Discrete_DpmTable, GraphicsLevel);
+	uint32_t level_array_size = sizeof(SMU72_Discrete_GraphicsLevel) *
+		SMU72_MAX_LEVELS_GRAPHICS;   /* 64 -> long; 32 -> int*/
+	SMU72_Discrete_GraphicsLevel *levels = data->smc_state_table.GraphicsLevel;
+	uint32_t i, maxEntry;
+	uint8_t highest_pcie_level_enabled = 0, lowest_pcie_level_enabled = 0, mid_pcie_level_enabled = 0, count = 0;
+	PECI_RegistryValue reg_value;
+	memset(levels, 0x00, level_array_size);
+
+	for (i = 0; i < dpm_table->sclk_table.count; i++) {
+		result = tonga_populate_single_graphic_level(hwmgr,
+					dpm_table->sclk_table.dpm_levels[i].value,
+					(uint16_t)data->activity_target[i],
+					&(data->smc_state_table.GraphicsLevel[i]));
+
+		if (0 != result)
+			return result;
+
+		/* Making sure only DPM level 0-1 have Deep Sleep Div ID populated. */
+		if (i > 1)
+			data->smc_state_table.GraphicsLevel[i].DeepSleepDivId = 0;
+
+		if (0 == i) {
+			reg_value = 0;
+			if (reg_value != 0)
+				data->smc_state_table.GraphicsLevel[0].UpHyst = (uint8_t)reg_value;
+		}
+
+		if (1 == i) {
+			reg_value = 0;
+			if (reg_value != 0)
+				data->smc_state_table.GraphicsLevel[1].UpHyst = (uint8_t)reg_value;
+		}
+	}
+
+	/* Only enable level 0 for now. */
+	data->smc_state_table.GraphicsLevel[0].EnabledForActivity = 1;
+
+	/* set highest level watermark to high */
+	if (dpm_table->sclk_table.count > 1)
+		data->smc_state_table.GraphicsLevel[dpm_table->sclk_table.count-1].DisplayWatermark =
+			PPSMC_DISPLAY_WATERMARK_HIGH;
+
+	data->smc_state_table.GraphicsDpmLevelCount =
+		(uint8_t)dpm_table->sclk_table.count;
+	data->dpm_level_enable_mask.sclk_dpm_enable_mask =
+		tonga_get_dpm_level_enable_mask_value(&dpm_table->sclk_table);
+
+	if (pcie_table != NULL) {
+		PP_ASSERT_WITH_CODE((pcie_entry_count >= 1),
+			"There must be 1 or more PCIE levels defined in PPTable.", return -1);
+		maxEntry = pcie_entry_count - 1; /* for indexing, we need to decrement by 1.*/
+		for (i = 0; i < dpm_table->sclk_table.count; i++) {
+			data->smc_state_table.GraphicsLevel[i].pcieDpmLevel =
+				(uint8_t) ((i < maxEntry) ? i : maxEntry);
+		}
+	} else {
+		if (0 == data->dpm_level_enable_mask.pcie_dpm_enable_mask)
+			printk(KERN_ERR "[ powerplay ] Pcie Dpm Enablemask is 0!");
+
+		while (data->dpm_level_enable_mask.pcie_dpm_enable_mask &&
+				((data->dpm_level_enable_mask.pcie_dpm_enable_mask &
+					(1<<(highest_pcie_level_enabled+1))) != 0)) {
+			highest_pcie_level_enabled++;
+		}
+
+		while (data->dpm_level_enable_mask.pcie_dpm_enable_mask &&
+				((data->dpm_level_enable_mask.pcie_dpm_enable_mask &
+					(1<<lowest_pcie_level_enabled)) == 0)) {
+			lowest_pcie_level_enabled++;
+		}
+
+		while ((count < highest_pcie_level_enabled) &&
+				((data->dpm_level_enable_mask.pcie_dpm_enable_mask &
+					(1<<(lowest_pcie_level_enabled+1+count))) == 0)) {
+			count++;
+		}
+		mid_pcie_level_enabled = (lowest_pcie_level_enabled+1+count) < highest_pcie_level_enabled ?
+			(lowest_pcie_level_enabled+1+count) : highest_pcie_level_enabled;
+
+
+		/* set pcieDpmLevel to highest_pcie_level_enabled*/
+		for (i = 2; i < dpm_table->sclk_table.count; i++) {
+			data->smc_state_table.GraphicsLevel[i].pcieDpmLevel = highest_pcie_level_enabled;
+		}
+
+		/* set pcieDpmLevel to lowest_pcie_level_enabled*/
+		data->smc_state_table.GraphicsLevel[0].pcieDpmLevel = lowest_pcie_level_enabled;
+
+		/* set pcieDpmLevel to mid_pcie_level_enabled*/
+		data->smc_state_table.GraphicsLevel[1].pcieDpmLevel = mid_pcie_level_enabled;
+	}
+	/* level count will send to smc once at init smc table and never change*/
+	result = tonga_copy_bytes_to_smc(hwmgr->smumgr, level_array_adress, (uint8_t *)levels, (uint32_t)level_array_size, data->sram_end);
+
+	if (0 != result)
+		return result;
+
+	return 0;
+}
+
+/**
+ * Populates all SMC MCLK levels' structure based on the trimmed allowed dpm memory clock states
+ *
+ * @param    hwmgr      the address of the hardware manager
+ */
+
+static int tonga_populate_all_memory_levels(struct pp_hwmgr *hwmgr)
+{
+	tonga_hwmgr *data = (tonga_hwmgr *)(hwmgr->backend);
+	struct tonga_dpm_table *dpm_table = &data->dpm_table;
+	int result;
+	/* populate MCLK dpm table to SMU7 */
+	uint32_t level_array_adress = data->dpm_table_start + offsetof(SMU72_Discrete_DpmTable, MemoryLevel);
+	uint32_t level_array_size = sizeof(SMU72_Discrete_MemoryLevel) * SMU72_MAX_LEVELS_MEMORY;
+	SMU72_Discrete_MemoryLevel *levels = data->smc_state_table.MemoryLevel;
+	uint32_t i;
+
+	memset(levels, 0x00, level_array_size);
+
+	for (i = 0; i < dpm_table->mclk_table.count; i++) {
+		PP_ASSERT_WITH_CODE((0 != dpm_table->mclk_table.dpm_levels[i].value),
+			"can not populate memory level as memory clock is zero", return -1);
+		result = tonga_populate_single_memory_level(hwmgr, dpm_table->mclk_table.dpm_levels[i].value,
+			&(data->smc_state_table.MemoryLevel[i]));
+		if (0 != result) {
+			return result;
+		}
+	}
+
+	/* Only enable level 0 for now.*/
+	data->smc_state_table.MemoryLevel[0].EnabledForActivity = 1;
+
+	/*
+	* in order to prevent MC activity from stutter mode to push DPM up.
+	* the UVD change complements this by putting the MCLK in a higher state
+	* by default such that we are not effected by up threshold or and MCLK DPM latency.
+	*/
+	data->smc_state_table.MemoryLevel[0].ActivityLevel = 0x1F;
+	CONVERT_FROM_HOST_TO_SMC_US(data->smc_state_table.MemoryLevel[0].ActivityLevel);
+
+	data->smc_state_table.MemoryDpmLevelCount = (uint8_t)dpm_table->mclk_table.count;
+	data->dpm_level_enable_mask.mclk_dpm_enable_mask = tonga_get_dpm_level_enable_mask_value(&dpm_table->mclk_table);
+	/* set highest level watermark to high*/
+	data->smc_state_table.MemoryLevel[dpm_table->mclk_table.count-1].DisplayWatermark = PPSMC_DISPLAY_WATERMARK_HIGH;
+
+	/* level count will send to smc once at init smc table and never change*/
+	result = tonga_copy_bytes_to_smc(hwmgr->smumgr,
+		level_array_adress, (uint8_t *)levels, (uint32_t)level_array_size, data->sram_end);
+
+	if (0 != result) {
+		return result;
+	}
+
+	return 0;
+}
+
+struct TONGA_DLL_SPEED_SETTING {
+	uint16_t            Min;                          /* Minimum Data Rate*/
+	uint16_t            Max;                          /* Maximum Data Rate*/
+	uint32_t 			dll_speed;                     /* The desired DLL_SPEED setting*/
+};
+
+static int tonga_populate_clock_stretcher_data_table(struct pp_hwmgr *hwmgr)
+{
+	return 0;
+}
+
+/* ---------------------------------------- ULV related functions ----------------------------------------------------*/
+
+
+static int tonga_reset_single_dpm_table(
+	struct pp_hwmgr *hwmgr,
+	struct tonga_single_dpm_table *dpm_table,
+	uint32_t count)
+{
+	uint32_t i;
+	if (!(count <= MAX_REGULAR_DPM_NUMBER))
+		printk(KERN_ERR "[ powerplay ] Fatal error, can not set up single DPM \
+			table entries to exceed max number! \n");
+
+	dpm_table->count = count;
+	for (i = 0; i < MAX_REGULAR_DPM_NUMBER; i++) {
+		dpm_table->dpm_levels[i].enabled = 0;
+	}
+
+	return 0;
+}
+
+static void tonga_setup_pcie_table_entry(
+	struct tonga_single_dpm_table *dpm_table,
+	uint32_t index, uint32_t pcie_gen,
+	uint32_t pcie_lanes)
+{
+	dpm_table->dpm_levels[index].value = pcie_gen;
+	dpm_table->dpm_levels[index].param1 = pcie_lanes;
+	dpm_table->dpm_levels[index].enabled = 1;
+}
+
+static int tonga_setup_default_pcie_tables(struct pp_hwmgr *hwmgr)
+{
+	tonga_hwmgr *data = (tonga_hwmgr *)(hwmgr->backend);
+	struct phm_ppt_v1_information *pptable_info = (struct phm_ppt_v1_information *)(hwmgr->pptable);
+	phm_ppt_v1_pcie_table *pcie_table = pptable_info->pcie_table;
+	uint32_t i, maxEntry;
+
+	if (data->use_pcie_performance_levels && !data->use_pcie_power_saving_levels) {
+		data->pcie_gen_power_saving = data->pcie_gen_performance;
+		data->pcie_lane_power_saving = data->pcie_lane_performance;
+	} else if (!data->use_pcie_performance_levels && data->use_pcie_power_saving_levels) {
+		data->pcie_gen_performance = data->pcie_gen_power_saving;
+		data->pcie_lane_performance = data->pcie_lane_power_saving;
+	}
+
+	tonga_reset_single_dpm_table(hwmgr, &data->dpm_table.pcie_speed_table, SMU72_MAX_LEVELS_LINK);
+
+	if (pcie_table != NULL) {
+		/*
+		* maxEntry is used to make sure we reserve one PCIE level for boot level (fix for A+A PSPP issue).
+		* If PCIE table from PPTable have ULV entry + 8 entries, then ignore the last entry.
+		*/
+		maxEntry = (SMU72_MAX_LEVELS_LINK < pcie_table->count) ?
+						SMU72_MAX_LEVELS_LINK : pcie_table->count;
+		for (i = 1; i < maxEntry; i++) {
+			tonga_setup_pcie_table_entry(&data->dpm_table.pcie_speed_table, i-1,
+				get_pcie_gen_support(data->pcie_gen_cap, pcie_table->entries[i].gen_speed),
+				get_pcie_lane_support(data->pcie_lane_cap, PP_Max_PCIELane));
+		}
+		data->dpm_table.pcie_speed_table.count = maxEntry - 1;
+	} else {
+		/* Hardcode Pcie Table */
+		tonga_setup_pcie_table_entry(&data->dpm_table.pcie_speed_table, 0,
+			get_pcie_gen_support(data->pcie_gen_cap, PP_Min_PCIEGen),
+			get_pcie_lane_support(data->pcie_lane_cap, PP_Max_PCIELane));
+		tonga_setup_pcie_table_entry(&data->dpm_table.pcie_speed_table, 1,
+			get_pcie_gen_support(data->pcie_gen_cap, PP_Min_PCIEGen),
+			get_pcie_lane_support(data->pcie_lane_cap, PP_Max_PCIELane));
+		tonga_setup_pcie_table_entry(&data->dpm_table.pcie_speed_table, 2,
+			get_pcie_gen_support(data->pcie_gen_cap, PP_Max_PCIEGen),
+			get_pcie_lane_support(data->pcie_lane_cap, PP_Max_PCIELane));
+		tonga_setup_pcie_table_entry(&data->dpm_table.pcie_speed_table, 3,
+			get_pcie_gen_support(data->pcie_gen_cap, PP_Max_PCIEGen),
+			get_pcie_lane_support(data->pcie_lane_cap, PP_Max_PCIELane));
+		tonga_setup_pcie_table_entry(&data->dpm_table.pcie_speed_table, 4,
+			get_pcie_gen_support(data->pcie_gen_cap, PP_Max_PCIEGen),
+			get_pcie_lane_support(data->pcie_lane_cap, PP_Max_PCIELane));
+		tonga_setup_pcie_table_entry(&data->dpm_table.pcie_speed_table, 5,
+			get_pcie_gen_support(data->pcie_gen_cap, PP_Max_PCIEGen),
+			get_pcie_lane_support(data->pcie_lane_cap, PP_Max_PCIELane));
+		data->dpm_table.pcie_speed_table.count = 6;
+	}
+	/* Populate last level for boot PCIE level, but do not increment count. */
+	tonga_setup_pcie_table_entry(&data->dpm_table.pcie_speed_table,
+		data->dpm_table.pcie_speed_table.count,
+		get_pcie_gen_support(data->pcie_gen_cap, PP_Min_PCIEGen),
+		get_pcie_lane_support(data->pcie_lane_cap, PP_Max_PCIELane));
+
+	return 0;
+
+}
+
+/*
+ * This function is to initalize all DPM state tables for SMU7 based on the dependency table.
+ * Dynamic state patching function will then trim these state tables to the allowed range based
+ * on the power policy or external client requests, such as UVD request, etc.
+ */
+static int tonga_setup_default_dpm_tables(struct pp_hwmgr *hwmgr)
+{
+	tonga_hwmgr *data = (tonga_hwmgr *)(hwmgr->backend);
+	struct phm_ppt_v1_information *pptable_info = (struct phm_ppt_v1_information *)(hwmgr->pptable);
+	uint32_t i;
+
+	phm_ppt_v1_clock_voltage_dependency_table *allowed_vdd_sclk_table =
+		pptable_info->vdd_dep_on_sclk;
+	phm_ppt_v1_clock_voltage_dependency_table *allowed_vdd_mclk_table =
+		pptable_info->vdd_dep_on_mclk;
+
+	PP_ASSERT_WITH_CODE(allowed_vdd_sclk_table != NULL,
+		"SCLK dependency table is missing. This table is mandatory", return -1);
+	PP_ASSERT_WITH_CODE(allowed_vdd_sclk_table->count >= 1,
+		"SCLK dependency table has to have is missing. This table is mandatory", return -1);
+
+	PP_ASSERT_WITH_CODE(allowed_vdd_mclk_table != NULL,
+		"MCLK dependency table is missing. This table is mandatory", return -1);
+	PP_ASSERT_WITH_CODE(allowed_vdd_mclk_table->count >= 1,
+		"VMCLK dependency table has to have is missing. This table is mandatory", return -1);
+
+	/* clear the state table to reset everything to default */
+	memset(&(data->dpm_table), 0x00, sizeof(data->dpm_table));
+	tonga_reset_single_dpm_table(hwmgr, &data->dpm_table.sclk_table, SMU72_MAX_LEVELS_GRAPHICS);
+	tonga_reset_single_dpm_table(hwmgr, &data->dpm_table.mclk_table, SMU72_MAX_LEVELS_MEMORY);
+	/* tonga_reset_single_dpm_table(hwmgr, &tonga_hwmgr->dpm_table.VddcTable, SMU72_MAX_LEVELS_VDDC); */
+	/* tonga_reset_single_dpm_table(hwmgr, &tonga_hwmgr->dpm_table.vdd_gfx_table, SMU72_MAX_LEVELS_VDDGFX);*/
+	/* tonga_reset_single_dpm_table(hwmgr, &tonga_hwmgr->dpm_table.vdd_ci_table, SMU72_MAX_LEVELS_VDDCI);*/
+	/* tonga_reset_single_dpm_table(hwmgr, &tonga_hwmgr->dpm_table.mvdd_table, SMU72_MAX_LEVELS_MVDD);*/
+
+	PP_ASSERT_WITH_CODE(allowed_vdd_sclk_table != NULL,
+		"SCLK dependency table is missing. This table is mandatory", return -1);
+	/* Initialize Sclk DPM table based on allow Sclk values*/
+	data->dpm_table.sclk_table.count = 0;
+
+	for (i = 0; i < allowed_vdd_sclk_table->count; i++) {
+		if (i == 0 || data->dpm_table.sclk_table.dpm_levels[data->dpm_table.sclk_table.count-1].value !=
+				allowed_vdd_sclk_table->entries[i].clk) {
+			data->dpm_table.sclk_table.dpm_levels[data->dpm_table.sclk_table.count].value =
+				allowed_vdd_sclk_table->entries[i].clk;
+			data->dpm_table.sclk_table.dpm_levels[data->dpm_table.sclk_table.count].enabled = 1; /*(i==0) ? 1 : 0; to do */
+			data->dpm_table.sclk_table.count++;
+		}
+	}
+
+	PP_ASSERT_WITH_CODE(allowed_vdd_mclk_table != NULL,
+		"MCLK dependency table is missing. This table is mandatory", return -1);
+	/* Initialize Mclk DPM table based on allow Mclk values */
+	data->dpm_table.mclk_table.count = 0;
+	for (i = 0; i < allowed_vdd_mclk_table->count; i++) {
+		if (i == 0 || data->dpm_table.mclk_table.dpm_levels[data->dpm_table.mclk_table.count-1].value !=
+			allowed_vdd_mclk_table->entries[i].clk) {
+			data->dpm_table.mclk_table.dpm_levels[data->dpm_table.mclk_table.count].value =
+				allowed_vdd_mclk_table->entries[i].clk;
+			data->dpm_table.mclk_table.dpm_levels[data->dpm_table.mclk_table.count].enabled = 1; /*(i==0) ? 1 : 0; */
+			data->dpm_table.mclk_table.count++;
+		}
+	}
+
+	/* Initialize Vddc DPM table based on allow Vddc values.  And populate corresponding std values. */
+	for (i = 0; i < allowed_vdd_sclk_table->count; i++) {
+		data->dpm_table.vddc_table.dpm_levels[i].value = allowed_vdd_mclk_table->entries[i].vddc;
+		/* tonga_hwmgr->dpm_table.VddcTable.dpm_levels[i].param1 = stdVoltageTable->entries[i].Leakage; */
+		/* param1 is for corresponding std voltage */
+		data->dpm_table.vddc_table.dpm_levels[i].enabled = 1;
+	}
+	data->dpm_table.vddc_table.count = allowed_vdd_sclk_table->count;
+
+	if (NULL != allowed_vdd_mclk_table) {
+		/* Initialize Vddci DPM table based on allow Mclk values */
+		for (i = 0; i < allowed_vdd_mclk_table->count; i++) {
+			data->dpm_table.vdd_ci_table.dpm_levels[i].value = allowed_vdd_mclk_table->entries[i].vddci;
+			data->dpm_table.vdd_ci_table.dpm_levels[i].enabled = 1;
+			data->dpm_table.mvdd_table.dpm_levels[i].value = allowed_vdd_mclk_table->entries[i].mvdd;
+			data->dpm_table.mvdd_table.dpm_levels[i].enabled = 1;
+		}
+		data->dpm_table.vdd_ci_table.count = allowed_vdd_mclk_table->count;
+		data->dpm_table.mvdd_table.count = allowed_vdd_mclk_table->count;
+	}
+
+	/* setup PCIE gen speed levels*/
+	tonga_setup_default_pcie_tables(hwmgr);
+
+	/* save a copy of the default DPM table*/
+	memcpy(&(data->golden_dpm_table), &(data->dpm_table), sizeof(struct tonga_dpm_table));
+
+	return 0;
+}
+
+int tonga_populate_smc_initial_state(struct pp_hwmgr *hwmgr,
+		const struct tonga_power_state *bootState)
+{
+	tonga_hwmgr *data = (tonga_hwmgr *)(hwmgr->backend);
+	struct phm_ppt_v1_information *pptable_info = (struct phm_ppt_v1_information *)(hwmgr->pptable);
+	uint8_t count, level;
+
+	count = (uint8_t) (pptable_info->vdd_dep_on_sclk->count);
+	for (level = 0; level < count; level++) {
+		if (pptable_info->vdd_dep_on_sclk->entries[level].clk >=
+			bootState->performance_levels[0].engine_clock) {
+			data->smc_state_table.GraphicsBootLevel = level;
+			break;
+		}
+	}
+
+	count = (uint8_t) (pptable_info->vdd_dep_on_mclk->count);
+	for (level = 0; level < count; level++) {
+		if (pptable_info->vdd_dep_on_mclk->entries[level].clk >=
+			bootState->performance_levels[0].memory_clock) {
+			data->smc_state_table.MemoryBootLevel = level;
+			break;
+		}
+	}
+
+	return 0;
+}
+
+/**
+ * Initializes the SMC table and uploads it
+ *
+ * @param    hwmgr  the address of the powerplay hardware manager.
+ * @param    pInput  the pointer to input data (PowerState)
+ * @return   always 0
+ */
+int tonga_init_smc_table(struct pp_hwmgr *hwmgr)
+{
+	int result;
+	tonga_hwmgr *data = (tonga_hwmgr *)(hwmgr->backend);
+	struct phm_ppt_v1_information *pptable_info = (struct phm_ppt_v1_information *)(hwmgr->pptable);
+	SMU72_Discrete_DpmTable  *table = &(data->smc_state_table);
+	const phw_tonga_ulv_parm *ulv = &(data->ulv);
+	uint8_t i;
+	PECI_RegistryValue reg_value;
+	pp_atomctrl_gpio_pin_assignment gpio_pin_assignment;
+
+	result = tonga_setup_default_dpm_tables(hwmgr);
+	PP_ASSERT_WITH_CODE(0 == result,
+		"Failed to setup default DPM tables!", return result;);
+	memset(&(data->smc_state_table), 0x00, sizeof(data->smc_state_table));
+	if (TONGA_VOLTAGE_CONTROL_NONE != data->voltage_control) {
+		tonga_populate_smc_voltage_tables(hwmgr, table);
+	}
+
+	if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
+			PHM_PlatformCaps_AutomaticDCTransition)) {
+		table->SystemFlags |= PPSMC_SYSTEMFLAG_GPIO_DC;
+	}
+
+	if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
+			PHM_PlatformCaps_StepVddc)) {
+		table->SystemFlags |= PPSMC_SYSTEMFLAG_STEPVDDC;
+	}
+
+	if (data->is_memory_GDDR5) {
+		table->SystemFlags |= PPSMC_SYSTEMFLAG_GDDR5;
+	}
+
+	i = PHM_READ_FIELD(hwmgr->device, CC_MC_MAX_CHANNEL, NOOFCHAN);
+
+	if (i == 1 || i == 0) {
+		table->SystemFlags |= PPSMC_SYSTEMFLAG_12CHANNEL;
+	}
+
+	if (ulv->ulv_supported && pptable_info->us_ulv_voltage_offset) {
+		PP_ASSERT_WITH_CODE(0 == result,
+			"Failed to initialize ULV state!", return result;);
+
+		cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC,
+			ixCG_ULV_PARAMETER, ulv->ch_ulv_parameter);
+	}
+
+	result = tonga_populate_smc_link_level(hwmgr, table);
+	PP_ASSERT_WITH_CODE(0 == result,
+		"Failed to initialize Link Level!", return result;);
+
+	result = tonga_populate_all_graphic_levels(hwmgr);
+	PP_ASSERT_WITH_CODE(0 == result,
+		"Failed to initialize Graphics Level!", return result;);
+
+	result = tonga_populate_all_memory_levels(hwmgr);
+	PP_ASSERT_WITH_CODE(0 == result,
+		"Failed to initialize Memory Level!", return result;);
+
+	result = tonga_populate_smv_acpi_level(hwmgr, table);
+	PP_ASSERT_WITH_CODE(0 == result,
+		"Failed to initialize ACPI Level!", return result;);
+
+	result = tonga_populate_smc_vce_level(hwmgr, table);
+	PP_ASSERT_WITH_CODE(0 == result,
+		"Failed to initialize VCE Level!", return result;);
+
+	result = tonga_populate_smc_acp_level(hwmgr, table);
+	PP_ASSERT_WITH_CODE(0 == result,
+		"Failed to initialize ACP Level!", return result;);
+
+	result = tonga_populate_smc_samu_level(hwmgr, table);
+	PP_ASSERT_WITH_CODE(0 == result,
+		"Failed to initialize SAMU Level!", return result;);
+
+	/* Since only the initial state is completely set up at this point (the other states are just copies of the boot state) we only */
+	/* need to populate the  ARB settings for the initial state. */
+	result = tonga_program_memory_timing_parameters(hwmgr);
+	PP_ASSERT_WITH_CODE(0 == result,
+		"Failed to Write ARB settings for the initial state.", return result;);
+
+	result = tonga_populate_smc_uvd_level(hwmgr, table);
+	PP_ASSERT_WITH_CODE(0 == result,
+		"Failed to initialize UVD Level!", return result;);
+
+	result = tonga_populate_smc_boot_level(hwmgr, table);
+	PP_ASSERT_WITH_CODE(0 == result,
+		"Failed to initialize Boot Level!", return result;);
+
+	if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
+			PHM_PlatformCaps_ClockStretcher)) {
+		result = tonga_populate_clock_stretcher_data_table(hwmgr);
+		PP_ASSERT_WITH_CODE(0 == result,
+			"Failed to populate Clock Stretcher Data Table!", return result;);
+	}
+	table->GraphicsVoltageChangeEnable  = 1;
+	table->GraphicsThermThrottleEnable  = 1;
+	table->GraphicsInterval = 1;
+	table->VoltageInterval  = 1;
+	table->ThermalInterval  = 1;
+	table->TemperatureLimitHigh =
+		pptable_info->cac_dtp_table->usTargetOperatingTemp *
+		TONGA_Q88_FORMAT_CONVERSION_UNIT;
+	table->TemperatureLimitLow =
+		(pptable_info->cac_dtp_table->usTargetOperatingTemp - 1) *
+		TONGA_Q88_FORMAT_CONVERSION_UNIT;
+	table->MemoryVoltageChangeEnable  = 1;
+	table->MemoryInterval  = 1;
+	table->VoltageResponseTime  = 0;
+	table->PhaseResponseTime  = 0;
+	table->MemoryThermThrottleEnable  = 1;
+
+	/*
+	* Cail reads current link status and reports it as cap (we cannot change this due to some previous issues we had)
+	* SMC drops the link status to lowest level after enabling DPM by PowerPlay. After pnp or toggling CF, driver gets reloaded again
+	* but this time Cail reads current link status which was set to low by SMC and reports it as cap to powerplay
+	* To avoid it, we set PCIeBootLinkLevel to highest dpm level
+	*/
+	PP_ASSERT_WITH_CODE((1 <= data->dpm_table.pcie_speed_table.count),
+			"There must be 1 or more PCIE levels defined in PPTable.",
+			return -1);
+
+	table->PCIeBootLinkLevel = (uint8_t) (data->dpm_table.pcie_speed_table.count);
+
+	table->PCIeGenInterval  = 1;
+
+	result = tonga_populate_vr_config(hwmgr, table);
+	PP_ASSERT_WITH_CODE(0 == result,
+		"Failed to populate VRConfig setting!", return result);
+
+	table->ThermGpio  = 17;
+	table->SclkStepSize = 0x4000;
+
+	reg_value = 0;
+	if ((0 == reg_value) &&
+		(0 == atomctrl_get_pp_assign_pin(hwmgr,
+			VDDC_VRHOT_GPIO_PINID, &gpio_pin_assignment))) {
+		table->VRHotGpio = gpio_pin_assignment.uc_gpio_pin_bit_shift;
+		phm_cap_set(hwmgr->platform_descriptor.platformCaps,
+			PHM_PlatformCaps_RegulatorHot);
+	} else {
+		table->VRHotGpio = TONGA_UNUSED_GPIO_PIN;
+		phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
+			PHM_PlatformCaps_RegulatorHot);
+	}
+
+	/* ACDC Switch GPIO */
+	reg_value = 0;
+	if ((0 == reg_value) &&
+		(0 == atomctrl_get_pp_assign_pin(hwmgr,
+			PP_AC_DC_SWITCH_GPIO_PINID, &gpio_pin_assignment))) {
+		table->AcDcGpio = gpio_pin_assignment.uc_gpio_pin_bit_shift;
+		phm_cap_set(hwmgr->platform_descriptor.platformCaps,
+			PHM_PlatformCaps_AutomaticDCTransition);
+	} else {
+		table->AcDcGpio = TONGA_UNUSED_GPIO_PIN;
+		phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
+			PHM_PlatformCaps_AutomaticDCTransition);
+	}
+
+	phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
+		PHM_PlatformCaps_Falcon_QuickTransition);
+
+	reg_value = 0;
+	if (1 == reg_value) {
+		phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
+			PHM_PlatformCaps_AutomaticDCTransition);
+		phm_cap_set(hwmgr->platform_descriptor.platformCaps,
+			PHM_PlatformCaps_Falcon_QuickTransition);
+	}
+
+	reg_value = 0;
+	if ((0 == reg_value) &&
+		(0 == atomctrl_get_pp_assign_pin(hwmgr,
+			THERMAL_INT_OUTPUT_GPIO_PINID, &gpio_pin_assignment))) {
+		phm_cap_set(hwmgr->platform_descriptor.platformCaps,
+			PHM_PlatformCaps_ThermalOutGPIO);
+
+		table->ThermOutGpio = gpio_pin_assignment.uc_gpio_pin_bit_shift;
+
+		table->ThermOutPolarity =
+			(0 == (cgs_read_register(hwmgr->device, mmGPIOPAD_A) &
+			(1 << gpio_pin_assignment.uc_gpio_pin_bit_shift))) ? 1:0;
+
+		table->ThermOutMode = SMU7_THERM_OUT_MODE_THERM_ONLY;
+
+		/* if required, combine VRHot/PCC with thermal out GPIO*/
+		if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
+			PHM_PlatformCaps_RegulatorHot) &&
+			phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
+			PHM_PlatformCaps_CombinePCCWithThermalSignal)){
+			table->ThermOutMode = SMU7_THERM_OUT_MODE_THERM_VRHOT;
+		}
+	} else {
+		phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
+			PHM_PlatformCaps_ThermalOutGPIO);
+
+		table->ThermOutGpio = 17;
+		table->ThermOutPolarity = 1;
+		table->ThermOutMode = SMU7_THERM_OUT_MODE_DISABLE;
+	}
+
+	for (i = 0; i < SMU72_MAX_ENTRIES_SMIO; i++) {
+		table->Smio[i] = PP_HOST_TO_SMC_UL(table->Smio[i]);
+	}
+	CONVERT_FROM_HOST_TO_SMC_UL(table->SystemFlags);
+	CONVERT_FROM_HOST_TO_SMC_UL(table->VRConfig);
+	CONVERT_FROM_HOST_TO_SMC_UL(table->SmioMask1);
+	CONVERT_FROM_HOST_TO_SMC_UL(table->SmioMask2);
+	CONVERT_FROM_HOST_TO_SMC_UL(table->SclkStepSize);
+	CONVERT_FROM_HOST_TO_SMC_US(table->TemperatureLimitHigh);
+	CONVERT_FROM_HOST_TO_SMC_US(table->TemperatureLimitLow);
+	CONVERT_FROM_HOST_TO_SMC_US(table->VoltageResponseTime);
+	CONVERT_FROM_HOST_TO_SMC_US(table->PhaseResponseTime);
+
+	/* Upload all dpm data to SMC memory.(dpm level, dpm level count etc) */
+	result = tonga_copy_bytes_to_smc(hwmgr->smumgr, data->dpm_table_start +
+										offsetof(SMU72_Discrete_DpmTable, SystemFlags),
+										(uint8_t *)&(table->SystemFlags),
+										sizeof(SMU72_Discrete_DpmTable)-3 * sizeof(SMU72_PIDController),
+										data->sram_end);
+
+	PP_ASSERT_WITH_CODE(0 == result,
+		"Failed to upload dpm data to SMC memory!", return result;);
+
+	return result;
+}
+
+/* Look up the voltaged based on DAL's requested level. and then send the requested VDDC voltage to SMC*/
+static void tonga_apply_dal_minimum_voltage_request(struct pp_hwmgr *hwmgr)
+{
+	return;
+}
+
+int tonga_upload_dpm_level_enable_mask(struct pp_hwmgr *hwmgr)
+{
+	PPSMC_Result result;
+	tonga_hwmgr *data = (tonga_hwmgr *)(hwmgr->backend);
+
+	/* Apply minimum voltage based on DAL's request level */
+	tonga_apply_dal_minimum_voltage_request(hwmgr);
+
+	if (0 == data->sclk_dpm_key_disabled) {
+		/* Checking if DPM is running.  If we discover hang because of this, we should skip this message.*/
+		if (0 != tonga_is_dpm_running(hwmgr))
+			printk(KERN_ERR "[ powerplay ] Trying to set Enable Mask when DPM is disabled \n");
+
+		if (0 != data->dpm_level_enable_mask.sclk_dpm_enable_mask) {
+			result = smum_send_msg_to_smc_with_parameter(
+								hwmgr->smumgr,
+				(PPSMC_Msg)PPSMC_MSG_SCLKDPM_SetEnabledMask,
+				data->dpm_level_enable_mask.sclk_dpm_enable_mask);
+			PP_ASSERT_WITH_CODE((0 == result),
+				"Set Sclk Dpm enable Mask failed", return -1);
+		}
+	}
+
+	if (0 == data->mclk_dpm_key_disabled) {
+		/* Checking if DPM is running.  If we discover hang because of this, we should skip this message.*/
+		if (0 != tonga_is_dpm_running(hwmgr))
+			printk(KERN_ERR "[ powerplay ] Trying to set Enable Mask when DPM is disabled \n");
+
+		if (0 != data->dpm_level_enable_mask.mclk_dpm_enable_mask) {
+			result = smum_send_msg_to_smc_with_parameter(
+								hwmgr->smumgr,
+				(PPSMC_Msg)PPSMC_MSG_MCLKDPM_SetEnabledMask,
+				data->dpm_level_enable_mask.mclk_dpm_enable_mask);
+			PP_ASSERT_WITH_CODE((0 == result),
+				"Set Mclk Dpm enable Mask failed", return -1);
+		}
+	}
+
+	return 0;
+}
+
+
+int tonga_force_dpm_highest(struct pp_hwmgr *hwmgr)
+{
+	uint32_t level, tmp;
+	tonga_hwmgr *data = (tonga_hwmgr *)(hwmgr->backend);
+
+	if (0 == data->pcie_dpm_key_disabled) {
+		/* PCIE */
+		if (data->dpm_level_enable_mask.pcie_dpm_enable_mask != 0) {
+			level = 0;
+			tmp = data->dpm_level_enable_mask.pcie_dpm_enable_mask;
+			while (tmp >>= 1)
+				level++ ;
+
+			if (0 != level) {
+				PP_ASSERT_WITH_CODE((0 == tonga_dpm_force_state_pcie(hwmgr, level)),
+					"force highest pcie dpm state failed!", return -1);
+			}
+		}
+	}
+
+	if (0 == data->sclk_dpm_key_disabled) {
+		/* SCLK */
+		if (data->dpm_level_enable_mask.sclk_dpm_enable_mask != 0) {
+			level = 0;
+			tmp = data->dpm_level_enable_mask.sclk_dpm_enable_mask;
+			while (tmp >>= 1)
+				level++ ;
+
+			if (0 != level) {
+				PP_ASSERT_WITH_CODE((0 == tonga_dpm_force_state(hwmgr, level)),
+					"force highest sclk dpm state failed!", return -1);
+				if (PHM_READ_VFPF_INDIRECT_FIELD(hwmgr->device,
+					CGS_IND_REG__SMC, TARGET_AND_CURRENT_PROFILE_INDEX, CURR_SCLK_INDEX) != level)
+					printk(KERN_ERR "[ powerplay ] Target_and_current_Profile_Index. \
+						Curr_Sclk_Index does not match the level \n");
+
+			}
+		}
+	}
+
+	if (0 == data->mclk_dpm_key_disabled) {
+		/* MCLK */
+		if (data->dpm_level_enable_mask.mclk_dpm_enable_mask != 0) {
+			level = 0;
+			tmp = data->dpm_level_enable_mask.mclk_dpm_enable_mask;
+			while (tmp >>= 1)
+				level++ ;
+
+			if (0 != level) {
+				PP_ASSERT_WITH_CODE((0 == tonga_dpm_force_state_mclk(hwmgr, level)),
+					"force highest mclk dpm state failed!", return -1);
+				if (PHM_READ_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC,
+					TARGET_AND_CURRENT_PROFILE_INDEX, CURR_MCLK_INDEX) != level)
+					printk(KERN_ERR "[ powerplay ] Target_and_current_Profile_Index. \
+						Curr_Mclk_Index does not match the level \n");
+			}
+		}
+	}
+
+	return 0;
+}
+
+/**
+ * Find the MC microcode version and store it in the HwMgr struct
+ *
+ * @param    hwmgr  the address of the powerplay hardware manager.
+ * @return   always 0
+ */
+int tonga_get_mc_microcode_version (struct pp_hwmgr *hwmgr)
+{
+	cgs_write_register(hwmgr->device, mmMC_SEQ_IO_DEBUG_INDEX, 0x9F);
+
+	hwmgr->microcode_version_info.MC = cgs_read_register(hwmgr->device, mmMC_SEQ_IO_DEBUG_DATA);
+
+	return 0;
+}
+
+/**
+ * Initialize Dynamic State Adjustment Rule Settings
+ *
+ * @param    hwmgr  the address of the powerplay hardware manager.
+ */
+int tonga_initializa_dynamic_state_adjustment_rule_settings(struct pp_hwmgr *hwmgr)
+{
+	uint32_t table_size;
+	struct phm_clock_voltage_dependency_table *table_clk_vlt;
+	struct phm_ppt_v1_information *pptable_info = (struct phm_ppt_v1_information *)(hwmgr->pptable);
+
+	hwmgr->dyn_state.mclk_sclk_ratio = 4;
+	hwmgr->dyn_state.sclk_mclk_delta = 15000;      /* 150 MHz */
+	hwmgr->dyn_state.vddc_vddci_delta = 200;       /* 200mV */
+
+	/* initialize vddc_dep_on_dal_pwrl table */
+	table_size = sizeof(uint32_t) + 4 * sizeof(struct phm_clock_voltage_dependency_record);
+	table_clk_vlt = (struct phm_clock_voltage_dependency_table *)kzalloc(table_size, GFP_KERNEL);
+
+	if (NULL == table_clk_vlt) {
+		printk(KERN_ERR "[ powerplay ] Can not allocate space for vddc_dep_on_dal_pwrl! \n");
+		return -ENOMEM;
+	} else {
+		table_clk_vlt->count = 4;
+		table_clk_vlt->entries[0].clk = PP_DAL_POWERLEVEL_ULTRALOW;
+		table_clk_vlt->entries[0].v = 0;
+		table_clk_vlt->entries[1].clk = PP_DAL_POWERLEVEL_LOW;
+		table_clk_vlt->entries[1].v = 720;
+		table_clk_vlt->entries[2].clk = PP_DAL_POWERLEVEL_NOMINAL;
+		table_clk_vlt->entries[2].v = 810;
+		table_clk_vlt->entries[3].clk = PP_DAL_POWERLEVEL_PERFORMANCE;
+		table_clk_vlt->entries[3].v = 900;
+		pptable_info->vddc_dep_on_dal_pwrl = table_clk_vlt;
+		hwmgr->dyn_state.vddc_dep_on_dal_pwrl = table_clk_vlt;
+	}
+
+	return 0;
+}
+
+static int tonga_set_private_var_based_on_pptale(struct pp_hwmgr *hwmgr)
+{
+	tonga_hwmgr *data = (tonga_hwmgr *)(hwmgr->backend);
+	struct phm_ppt_v1_information *pptable_info = (struct phm_ppt_v1_information *)(hwmgr->pptable);
+
+	phm_ppt_v1_clock_voltage_dependency_table *allowed_sclk_vdd_table =
+		pptable_info->vdd_dep_on_sclk;
+	phm_ppt_v1_clock_voltage_dependency_table *allowed_mclk_vdd_table =
+		pptable_info->vdd_dep_on_mclk;
+
+	PP_ASSERT_WITH_CODE(allowed_sclk_vdd_table != NULL,
+		"VDD dependency on SCLK table is missing. 	\
+		This table is mandatory", return -1);
+	PP_ASSERT_WITH_CODE(allowed_sclk_vdd_table->count >= 1,
+		"VDD dependency on SCLK table has to have is missing. 	\
+		This table is mandatory", return -1);
+
+	PP_ASSERT_WITH_CODE(allowed_mclk_vdd_table != NULL,
+		"VDD dependency on MCLK table is missing. 	\
+		This table is mandatory", return -1);
+	PP_ASSERT_WITH_CODE(allowed_mclk_vdd_table->count >= 1,
+		"VDD dependency on MCLK table has to have is missing.	 \
+		This table is mandatory", return -1);
+
+	data->min_vddc_in_pp_table = (uint16_t)allowed_sclk_vdd_table->entries[0].vddc;
+	data->max_vddc_in_pp_table = (uint16_t)allowed_sclk_vdd_table->entries[allowed_sclk_vdd_table->count - 1].vddc;
+
+	pptable_info->max_clock_voltage_on_ac.sclk =
+		allowed_sclk_vdd_table->entries[allowed_sclk_vdd_table->count - 1].clk;
+	pptable_info->max_clock_voltage_on_ac.mclk =
+		allowed_mclk_vdd_table->entries[allowed_mclk_vdd_table->count - 1].clk;
+	pptable_info->max_clock_voltage_on_ac.vddc =
+		allowed_sclk_vdd_table->entries[allowed_sclk_vdd_table->count - 1].vddc;
+	pptable_info->max_clock_voltage_on_ac.vddci =
+		allowed_mclk_vdd_table->entries[allowed_mclk_vdd_table->count - 1].vddci;
+
+	hwmgr->dyn_state.max_clock_voltage_on_ac.sclk =
+		pptable_info->max_clock_voltage_on_ac.sclk;
+	hwmgr->dyn_state.max_clock_voltage_on_ac.mclk =
+		pptable_info->max_clock_voltage_on_ac.mclk;
+	hwmgr->dyn_state.max_clock_voltage_on_ac.vddc =
+		pptable_info->max_clock_voltage_on_ac.vddc;
+	hwmgr->dyn_state.max_clock_voltage_on_ac.vddci =
+		pptable_info->max_clock_voltage_on_ac.vddci;
+
+	return 0;
+}
+
+int tonga_unforce_dpm_levels(struct pp_hwmgr *hwmgr)
+{
+	tonga_hwmgr *data = (tonga_hwmgr *)(hwmgr->backend);
+	int result = 1;
+
+	PP_ASSERT_WITH_CODE (0 == tonga_is_dpm_running(hwmgr),
+		"Trying to Unforce DPM when DPM is disabled. Returning without sending SMC message.",
+							return result);
+
+	if (0 == data->pcie_dpm_key_disabled) {
+		PP_ASSERT_WITH_CODE((0 == smum_send_msg_to_smc(
+							     hwmgr->smumgr,
+					PPSMC_MSG_PCIeDPM_UnForceLevel)),
+					   "unforce pcie level failed!",
+								return -1);
+	}
+
+	result = tonga_upload_dpm_level_enable_mask(hwmgr);
+
+	return result;
+}
+
+static uint32_t tonga_get_lowest_enable_level(
+				struct pp_hwmgr *hwmgr, uint32_t level_mask)
+{
+	uint32_t level = 0;
+
+	while (0 == (level_mask & (1 << level)))
+		level++;
+
+	return level;
+}
+
+static int tonga_force_dpm_lowest(struct pp_hwmgr *hwmgr)
+{
+	uint32_t level;
+	tonga_hwmgr *data = (tonga_hwmgr *)(hwmgr->backend);
+
+	if (0 == data->pcie_dpm_key_disabled) {
+		/* PCIE */
+		if (data->dpm_level_enable_mask.pcie_dpm_enable_mask != 0) {
+			level = tonga_get_lowest_enable_level(hwmgr,
+							      data->dpm_level_enable_mask.pcie_dpm_enable_mask);
+			PP_ASSERT_WITH_CODE((0 == tonga_dpm_force_state_pcie(hwmgr, level)),
+					    "force lowest pcie dpm state failed!", return -1);
+		}
+	}
+
+	if (0 == data->sclk_dpm_key_disabled) {
+		/* SCLK */
+		if (0 != data->dpm_level_enable_mask.sclk_dpm_enable_mask) {
+			level = tonga_get_lowest_enable_level(hwmgr,
+							      data->dpm_level_enable_mask.sclk_dpm_enable_mask);
+
+			PP_ASSERT_WITH_CODE((0 == tonga_dpm_force_state(hwmgr, level)),
+					    "force sclk dpm state failed!", return -1);
+
+			if (PHM_READ_VFPF_INDIRECT_FIELD(hwmgr->device,
+							 CGS_IND_REG__SMC, TARGET_AND_CURRENT_PROFILE_INDEX, CURR_SCLK_INDEX) != level)
+				printk(KERN_ERR "[ powerplay ] Target_and_current_Profile_Index.	\
+				Curr_Sclk_Index does not match the level \n");
+		}
+	}
+
+	if (0 == data->mclk_dpm_key_disabled) {
+		/* MCLK */
+		if (data->dpm_level_enable_mask.mclk_dpm_enable_mask != 0) {
+			level = tonga_get_lowest_enable_level(hwmgr,
+							      data->dpm_level_enable_mask.mclk_dpm_enable_mask);
+			PP_ASSERT_WITH_CODE((0 == tonga_dpm_force_state_mclk(hwmgr, level)),
+					    "force lowest mclk dpm state failed!", return -1);
+			if (PHM_READ_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC,
+							 TARGET_AND_CURRENT_PROFILE_INDEX, CURR_MCLK_INDEX) != level)
+				printk(KERN_ERR "[ powerplay ] Target_and_current_Profile_Index. \
+						Curr_Mclk_Index does not match the level \n");
+		}
+	}
+
+	return 0;
+}
+
+static int tonga_patch_voltage_dependency_tables_with_lookup_table(struct pp_hwmgr *hwmgr)
+{
+	uint8_t entryId;
+	uint8_t voltageId;
+	tonga_hwmgr *data = (tonga_hwmgr *)(hwmgr->backend);
+	struct phm_ppt_v1_information *pptable_info = (struct phm_ppt_v1_information *)(hwmgr->pptable);
+
+	phm_ppt_v1_clock_voltage_dependency_table *sclk_table = pptable_info->vdd_dep_on_sclk;
+	phm_ppt_v1_clock_voltage_dependency_table *mclk_table = pptable_info->vdd_dep_on_mclk;
+	phm_ppt_v1_mm_clock_voltage_dependency_table *mm_table = pptable_info->mm_dep_table;
+
+	if (data->vdd_gfx_control == TONGA_VOLTAGE_CONTROL_BY_SVID2) {
+		for (entryId = 0; entryId < sclk_table->count; ++entryId) {
+			voltageId = sclk_table->entries[entryId].vddInd;
+			sclk_table->entries[entryId].vddgfx =
+				pptable_info->vddgfx_lookup_table->entries[voltageId].us_vdd;
+		}
+	} else {
+		for (entryId = 0; entryId < sclk_table->count; ++entryId) {
+			voltageId = sclk_table->entries[entryId].vddInd;
+			sclk_table->entries[entryId].vddc =
+				pptable_info->vddc_lookup_table->entries[voltageId].us_vdd;
+		}
+	}
+
+	for (entryId = 0; entryId < mclk_table->count; ++entryId) {
+		voltageId = mclk_table->entries[entryId].vddInd;
+		mclk_table->entries[entryId].vddc =
+			pptable_info->vddc_lookup_table->entries[voltageId].us_vdd;
+	}
+
+	for (entryId = 0; entryId < mm_table->count; ++entryId) {
+		voltageId = mm_table->entries[entryId].vddcInd;
+		mm_table->entries[entryId].vddc =
+			pptable_info->vddc_lookup_table->entries[voltageId].us_vdd;
+	}
+
+	return 0;
+
+}
+
+static int tonga_calc_voltage_dependency_tables(struct pp_hwmgr *hwmgr)
+{
+	uint8_t entryId;
+	phm_ppt_v1_voltage_lookup_record v_record;
+	tonga_hwmgr *data = (tonga_hwmgr *)(hwmgr->backend);
+	struct phm_ppt_v1_information *pptable_info = (struct phm_ppt_v1_information *)(hwmgr->pptable);
+
+	phm_ppt_v1_clock_voltage_dependency_table *sclk_table = pptable_info->vdd_dep_on_sclk;
+	phm_ppt_v1_clock_voltage_dependency_table *mclk_table = pptable_info->vdd_dep_on_mclk;
+
+	if (data->vdd_gfx_control == TONGA_VOLTAGE_CONTROL_BY_SVID2) {
+		for (entryId = 0; entryId < sclk_table->count; ++entryId) {
+			if (sclk_table->entries[entryId].vdd_offset & (1 << 15))
+				v_record.us_vdd = sclk_table->entries[entryId].vddgfx +
+					sclk_table->entries[entryId].vdd_offset - 0xFFFF;
+			else
+				v_record.us_vdd = sclk_table->entries[entryId].vddgfx +
+					sclk_table->entries[entryId].vdd_offset;
+
+			sclk_table->entries[entryId].vddc =
+				v_record.us_cac_low = v_record.us_cac_mid =
+				v_record.us_cac_high = v_record.us_vdd;
+
+			tonga_add_voltage(hwmgr, pptable_info->vddc_lookup_table, &v_record);
+		}
+
+		for (entryId = 0; entryId < mclk_table->count; ++entryId) {
+			if (mclk_table->entries[entryId].vdd_offset & (1 << 15))
+				v_record.us_vdd = mclk_table->entries[entryId].vddc +
+					mclk_table->entries[entryId].vdd_offset - 0xFFFF;
+			else
+				v_record.us_vdd = mclk_table->entries[entryId].vddc +
+					mclk_table->entries[entryId].vdd_offset;
+
+			mclk_table->entries[entryId].vddgfx = v_record.us_cac_low =
+				v_record.us_cac_mid = v_record.us_cac_high = v_record.us_vdd;
+			tonga_add_voltage(hwmgr, pptable_info->vddgfx_lookup_table, &v_record);
+		}
+	}
+
+	return 0;
+
+}
+
+static int tonga_calc_mm_voltage_dependency_table(struct pp_hwmgr *hwmgr)
+{
+	uint32_t entryId;
+	phm_ppt_v1_voltage_lookup_record v_record;
+	tonga_hwmgr *data = (tonga_hwmgr *)(hwmgr->backend);
+	struct phm_ppt_v1_information *pptable_info = (struct phm_ppt_v1_information *)(hwmgr->pptable);
+	phm_ppt_v1_mm_clock_voltage_dependency_table *mm_table = pptable_info->mm_dep_table;
+
+	if (data->vdd_gfx_control == TONGA_VOLTAGE_CONTROL_BY_SVID2) {
+		for (entryId = 0; entryId < mm_table->count; entryId++) {
+			if (mm_table->entries[entryId].vddgfx_offset & (1 << 15))
+				v_record.us_vdd = mm_table->entries[entryId].vddc +
+					mm_table->entries[entryId].vddgfx_offset - 0xFFFF;
+			else
+				v_record.us_vdd = mm_table->entries[entryId].vddc +
+					mm_table->entries[entryId].vddgfx_offset;
+
+			/* Add the calculated VDDGFX to the VDDGFX lookup table */
+			mm_table->entries[entryId].vddgfx = v_record.us_cac_low =
+				v_record.us_cac_mid = v_record.us_cac_high = v_record.us_vdd;
+			tonga_add_voltage(hwmgr, pptable_info->vddgfx_lookup_table, &v_record);
+		}
+	}
+	return 0;
+}
+
+
+/**
+ * Change virtual leakage voltage to actual value.
+ *
+ * @param     hwmgr  the address of the powerplay hardware manager.
+ * @param     pointer to changing voltage
+ * @param     pointer to leakage table
+ */
+static void tonga_patch_with_vdd_leakage(struct pp_hwmgr *hwmgr,
+		uint16_t *voltage, phw_tonga_leakage_voltage *pLeakageTable)
+{
+	uint32_t leakage_index;
+
+	/* search for leakage voltage ID 0xff01 ~ 0xff08 */
+	for (leakage_index = 0; leakage_index < pLeakageTable->count; leakage_index++) {
+		/* if this voltage matches a leakage voltage ID */
+		/* patch with actual leakage voltage */
+		if (pLeakageTable->leakage_id[leakage_index] == *voltage) {
+			*voltage = pLeakageTable->actual_voltage[leakage_index];
+			break;
+		}
+	}
+
+	if (*voltage > ATOM_VIRTUAL_VOLTAGE_ID0)
+		printk(KERN_ERR "[ powerplay ] Voltage value looks like a Leakage ID but it's not patched \n");
+}
+
+/**
+ * Patch voltage lookup table by EVV leakages.
+ *
+ * @param     hwmgr  the address of the powerplay hardware manager.
+ * @param     pointer to voltage lookup table
+ * @param     pointer to leakage table
+ * @return     always 0
+ */
+static int tonga_patch_lookup_table_with_leakage(struct pp_hwmgr *hwmgr,
+		phm_ppt_v1_voltage_lookup_table *lookup_table,
+		phw_tonga_leakage_voltage *pLeakageTable)
+{
+	uint32_t i;
+
+	for (i = 0; i < lookup_table->count; i++) {
+		tonga_patch_with_vdd_leakage(hwmgr,
+			&lookup_table->entries[i].us_vdd, pLeakageTable);
+	}
+
+	return 0;
+}
+
+static int tonga_patch_clock_voltage_lomits_with_vddc_leakage(struct pp_hwmgr *hwmgr,
+		phw_tonga_leakage_voltage *pLeakageTable, uint16_t *Vddc)
+{
+	struct phm_ppt_v1_information *pptable_info = (struct phm_ppt_v1_information *)(hwmgr->pptable);
+
+	tonga_patch_with_vdd_leakage(hwmgr, (uint16_t *)Vddc, pLeakageTable);
+	hwmgr->dyn_state.max_clock_voltage_on_dc.vddc =
+		pptable_info->max_clock_voltage_on_dc.vddc;
+
+	return 0;
+}
+
+static int tonga_patch_clock_voltage_limits_with_vddgfx_leakage(
+		struct pp_hwmgr *hwmgr, phw_tonga_leakage_voltage *pLeakageTable,
+		uint16_t *Vddgfx)
+{
+	tonga_patch_with_vdd_leakage(hwmgr, (uint16_t *)Vddgfx, pLeakageTable);
+	return 0;
+}
+
+int tonga_sort_lookup_table(struct pp_hwmgr *hwmgr,
+		phm_ppt_v1_voltage_lookup_table *lookup_table)
+{
+	uint32_t table_size, i, j;
+	phm_ppt_v1_voltage_lookup_record tmp_voltage_lookup_record;
+	table_size = lookup_table->count;
+
+	PP_ASSERT_WITH_CODE(0 != lookup_table->count,
+		"Lookup table is empty", return -1);
+
+	/* Sorting voltages */
+	for (i = 0; i < table_size - 1; i++) {
+		for (j = i + 1; j > 0; j--) {
+			if (lookup_table->entries[j].us_vdd < lookup_table->entries[j-1].us_vdd) {
+				tmp_voltage_lookup_record = lookup_table->entries[j-1];
+				lookup_table->entries[j-1] = lookup_table->entries[j];
+				lookup_table->entries[j] = tmp_voltage_lookup_record;
+			}
+		}
+	}
+
+	return 0;
+}
+
+static int tonga_complete_dependency_tables(struct pp_hwmgr *hwmgr)
+{
+	int result = 0;
+	int tmp_result;
+	tonga_hwmgr *data = (struct tonga_hwmgr *)(hwmgr->backend);
+	struct phm_ppt_v1_information *pptable_info = (struct phm_ppt_v1_information *)(hwmgr->pptable);
+
+	if (data->vdd_gfx_control == TONGA_VOLTAGE_CONTROL_BY_SVID2) {
+		tmp_result = tonga_patch_lookup_table_with_leakage(hwmgr,
+			pptable_info->vddgfx_lookup_table, &(data->vddcgfx_leakage));
+		if (tmp_result != 0)
+			result = tmp_result;
+
+		tmp_result = tonga_patch_clock_voltage_limits_with_vddgfx_leakage(hwmgr,
+			&(data->vddcgfx_leakage), &pptable_info->max_clock_voltage_on_dc.vddgfx);
+		if (tmp_result != 0)
+			result = tmp_result;
+	} else {
+		tmp_result = tonga_patch_lookup_table_with_leakage(hwmgr,
+			pptable_info->vddc_lookup_table, &(data->vddc_leakage));
+		if (tmp_result != 0)
+			result = tmp_result;
+
+		tmp_result = tonga_patch_clock_voltage_lomits_with_vddc_leakage(hwmgr,
+			&(data->vddc_leakage), &pptable_info->max_clock_voltage_on_dc.vddc);
+		if (tmp_result != 0)
+			result = tmp_result;
+	}
+
+	tmp_result = tonga_patch_voltage_dependency_tables_with_lookup_table(hwmgr);
+	if (tmp_result != 0)
+		result = tmp_result;
+
+	tmp_result = tonga_calc_voltage_dependency_tables(hwmgr);
+	if (tmp_result != 0)
+		result = tmp_result;
+
+	tmp_result = tonga_calc_mm_voltage_dependency_table(hwmgr);
+	if (tmp_result != 0)
+		result = tmp_result;
+
+	tmp_result = tonga_sort_lookup_table(hwmgr, pptable_info->vddgfx_lookup_table);
+	if (tmp_result != 0)
+		result = tmp_result;
+
+	tmp_result = tonga_sort_lookup_table(hwmgr, pptable_info->vddc_lookup_table);
+	if (tmp_result != 0)
+		result = tmp_result;
+
+	return result;
+}
+
+int tonga_init_sclk_threshold(struct pp_hwmgr *hwmgr)
+{
+	tonga_hwmgr *data = (tonga_hwmgr *)(hwmgr->backend);
+	data->low_sclk_interrupt_threshold = 0;
+
+	return 0;
+}
+
+int tonga_setup_asic_task(struct pp_hwmgr *hwmgr)
+{
+	int tmp_result, result = 0;
+
+	tmp_result = tonga_read_clock_registers(hwmgr);
+	PP_ASSERT_WITH_CODE((0 == tmp_result),
+		"Failed to read clock registers!", result = tmp_result);
+
+	tmp_result = tonga_get_memory_type(hwmgr);
+	PP_ASSERT_WITH_CODE((0 == tmp_result),
+		"Failed to get memory type!", result = tmp_result);
+
+	tmp_result = tonga_enable_acpi_power_management(hwmgr);
+	PP_ASSERT_WITH_CODE((0 == tmp_result),
+		"Failed to enable ACPI power management!", result = tmp_result);
+
+	tmp_result = tonga_init_power_gate_state(hwmgr);
+	PP_ASSERT_WITH_CODE((0 == tmp_result),
+		"Failed to init power gate state!", result = tmp_result);
+
+	tmp_result = tonga_get_mc_microcode_version(hwmgr);
+	PP_ASSERT_WITH_CODE((0 == tmp_result),
+		"Failed to get MC microcode version!", result = tmp_result);
+
+	tmp_result = tonga_init_sclk_threshold(hwmgr);
+	PP_ASSERT_WITH_CODE((0 == tmp_result),
+		"Failed to init sclk threshold!", result = tmp_result);
+
+	return result;
+}
+
+/**
+ * Enable voltage control
+ *
+ * @param    hwmgr  the address of the powerplay hardware manager.
+ * @return   always 0
+ */
+int tonga_enable_voltage_control(struct pp_hwmgr *hwmgr)
+{
+	/* enable voltage control */
+	PHM_WRITE_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, GENERAL_PWRMGT, VOLT_PWRMGT_EN, 1);
+
+	return 0;
+}
+
+/**
+ * Checks if we want to support voltage control
+ *
+ * @param    hwmgr  the address of the powerplay hardware manager.
+ */
+bool cf_tonga_voltage_control(const struct pp_hwmgr *hwmgr)
+{
+	const struct tonga_hwmgr *data = (struct tonga_hwmgr *)(hwmgr->backend);
+
+	return(TONGA_VOLTAGE_CONTROL_NONE != data->voltage_control);
+}
+
+/*---------------------------MC----------------------------*/
+
+uint8_t tonga_get_memory_modile_index(struct pp_hwmgr *hwmgr)
+{
+	return (uint8_t) (0xFF & (cgs_read_register(hwmgr->device, mmBIOS_SCRATCH_4) >> 16));
+}
+
+bool tonga_check_s0_mc_reg_index(uint16_t inReg, uint16_t *outReg)
+{
+	bool result = 1;
+
+	switch (inReg) {
+	case  mmMC_SEQ_RAS_TIMING:
+		*outReg = mmMC_SEQ_RAS_TIMING_LP;
+		break;
+
+	case  mmMC_SEQ_DLL_STBY:
+		*outReg = mmMC_SEQ_DLL_STBY_LP;
+		break;
+
+	case  mmMC_SEQ_G5PDX_CMD0:
+		*outReg = mmMC_SEQ_G5PDX_CMD0_LP;
+		break;
+
+	case  mmMC_SEQ_G5PDX_CMD1:
+		*outReg = mmMC_SEQ_G5PDX_CMD1_LP;
+		break;
+
+	case  mmMC_SEQ_G5PDX_CTRL:
+		*outReg = mmMC_SEQ_G5PDX_CTRL_LP;
+		break;
+
+	case mmMC_SEQ_CAS_TIMING:
+		*outReg = mmMC_SEQ_CAS_TIMING_LP;
+		break;
+
+	case mmMC_SEQ_MISC_TIMING:
+		*outReg = mmMC_SEQ_MISC_TIMING_LP;
+		break;
+
+	case mmMC_SEQ_MISC_TIMING2:
+		*outReg = mmMC_SEQ_MISC_TIMING2_LP;
+		break;
+
+	case mmMC_SEQ_PMG_DVS_CMD:
+		*outReg = mmMC_SEQ_PMG_DVS_CMD_LP;
+		break;
+
+	case mmMC_SEQ_PMG_DVS_CTL:
+		*outReg = mmMC_SEQ_PMG_DVS_CTL_LP;
+		break;
+
+	case mmMC_SEQ_RD_CTL_D0:
+		*outReg = mmMC_SEQ_RD_CTL_D0_LP;
+		break;
+
+	case mmMC_SEQ_RD_CTL_D1:
+		*outReg = mmMC_SEQ_RD_CTL_D1_LP;
+		break;
+
+	case mmMC_SEQ_WR_CTL_D0:
+		*outReg = mmMC_SEQ_WR_CTL_D0_LP;
+		break;
+
+	case mmMC_SEQ_WR_CTL_D1:
+		*outReg = mmMC_SEQ_WR_CTL_D1_LP;
+		break;
+
+	case mmMC_PMG_CMD_EMRS:
+		*outReg = mmMC_SEQ_PMG_CMD_EMRS_LP;
+		break;
+
+	case mmMC_PMG_CMD_MRS:
+		*outReg = mmMC_SEQ_PMG_CMD_MRS_LP;
+		break;
+
+	case mmMC_PMG_CMD_MRS1:
+		*outReg = mmMC_SEQ_PMG_CMD_MRS1_LP;
+		break;
+
+	case mmMC_SEQ_PMG_TIMING:
+		*outReg = mmMC_SEQ_PMG_TIMING_LP;
+		break;
+
+	case mmMC_PMG_CMD_MRS2:
+		*outReg = mmMC_SEQ_PMG_CMD_MRS2_LP;
+		break;
+
+	case mmMC_SEQ_WR_CTL_2:
+		*outReg = mmMC_SEQ_WR_CTL_2_LP;
+		break;
+
+	default:
+		result = 0;
+		break;
+	}
+
+	return result;
+}
+
+int tonga_set_s0_mc_reg_index(phw_tonga_mc_reg_table *table)
+{
+	uint32_t i;
+	uint16_t address;
+
+	for (i = 0; i < table->last; i++) {
+		table->mc_reg_address[i].s0 =
+			tonga_check_s0_mc_reg_index(table->mc_reg_address[i].s1, &address)
+			? address : table->mc_reg_address[i].s1;
+	}
+	return 0;
+}
+
+int tonga_copy_vbios_smc_reg_table(const pp_atomctrl_mc_reg_table *table, phw_tonga_mc_reg_table *ni_table)
+{
+	uint8_t i, j;
+
+	PP_ASSERT_WITH_CODE((table->last <= SMU72_DISCRETE_MC_REGISTER_ARRAY_SIZE),
+		"Invalid VramInfo table.", return -1);
+	PP_ASSERT_WITH_CODE((table->num_entries <= MAX_AC_TIMING_ENTRIES),
+		"Invalid VramInfo table.", return -1);
+
+	for (i = 0; i < table->last; i++) {
+		ni_table->mc_reg_address[i].s1 = table->mc_reg_address[i].s1;
+	}
+	ni_table->last = table->last;
+
+	for (i = 0; i < table->num_entries; i++) {
+		ni_table->mc_reg_table_entry[i].mclk_max =
+			table->mc_reg_table_entry[i].mclk_max;
+		for (j = 0; j < table->last; j++) {
+			ni_table->mc_reg_table_entry[i].mc_data[j] =
+				table->mc_reg_table_entry[i].mc_data[j];
+		}
+	}
+
+	ni_table->num_entries = table->num_entries;
+
+	return 0;
+}
+
+/**
+ * VBIOS omits some information to reduce size, we need to recover them here.
+ * 1.   when we see mmMC_SEQ_MISC1, bit[31:16] EMRS1, need to be write to  mmMC_PMG_CMD_EMRS /_LP[15:0].
+ *      Bit[15:0] MRS, need to be update mmMC_PMG_CMD_MRS/_LP[15:0]
+ * 2.   when we see mmMC_SEQ_RESERVE_M, bit[15:0] EMRS2, need to be write to mmMC_PMG_CMD_MRS1/_LP[15:0].
+ * 3.   need to set these data for each clock range
+ *
+ * @param    hwmgr the address of the powerplay hardware manager.
+ * @param    table the address of MCRegTable
+ * @return   always 0
+ */
+int tonga_set_mc_special_registers(struct pp_hwmgr *hwmgr, phw_tonga_mc_reg_table *table)
+{
+	uint8_t i, j, k;
+	uint32_t temp_reg;
+	const tonga_hwmgr *data = (struct tonga_hwmgr *)(hwmgr->backend);
+
+	for (i = 0, j = table->last; i < table->last; i++) {
+		PP_ASSERT_WITH_CODE((j < SMU72_DISCRETE_MC_REGISTER_ARRAY_SIZE),
+			"Invalid VramInfo table.", return -1);
+		switch (table->mc_reg_address[i].s1) {
+		/*
+		* mmMC_SEQ_MISC1, bit[31:16] EMRS1, need to be write to  mmMC_PMG_CMD_EMRS /_LP[15:0].
+		* Bit[15:0] MRS, need to be update mmMC_PMG_CMD_MRS/_LP[15:0]
+		*/
+		case mmMC_SEQ_MISC1:
+			temp_reg = cgs_read_register(hwmgr->device, mmMC_PMG_CMD_EMRS);
+			table->mc_reg_address[j].s1 = mmMC_PMG_CMD_EMRS;
+			table->mc_reg_address[j].s0 = mmMC_SEQ_PMG_CMD_EMRS_LP;
+			for (k = 0; k < table->num_entries; k++) {
+				table->mc_reg_table_entry[k].mc_data[j] =
+					((temp_reg & 0xffff0000)) |
+					((table->mc_reg_table_entry[k].mc_data[i] & 0xffff0000) >> 16);
+			}
+			j++;
+			PP_ASSERT_WITH_CODE((j < SMU72_DISCRETE_MC_REGISTER_ARRAY_SIZE),
+				"Invalid VramInfo table.", return -1);
+
+			temp_reg = cgs_read_register(hwmgr->device, mmMC_PMG_CMD_MRS);
+			table->mc_reg_address[j].s1 = mmMC_PMG_CMD_MRS;
+			table->mc_reg_address[j].s0 = mmMC_SEQ_PMG_CMD_MRS_LP;
+			for (k = 0; k < table->num_entries; k++) {
+				table->mc_reg_table_entry[k].mc_data[j] =
+					(temp_reg & 0xffff0000) |
+					(table->mc_reg_table_entry[k].mc_data[i] & 0x0000ffff);
+
+				if (!data->is_memory_GDDR5) {
+					table->mc_reg_table_entry[k].mc_data[j] |= 0x100;
+				}
+			}
+			j++;
+			PP_ASSERT_WITH_CODE((j <= SMU72_DISCRETE_MC_REGISTER_ARRAY_SIZE),
+				"Invalid VramInfo table.", return -1);
+
+			if (!data->is_memory_GDDR5) {
+				table->mc_reg_address[j].s1 = mmMC_PMG_AUTO_CMD;
+				table->mc_reg_address[j].s0 = mmMC_PMG_AUTO_CMD;
+				for (k = 0; k < table->num_entries; k++) {
+					table->mc_reg_table_entry[k].mc_data[j] =
+						(table->mc_reg_table_entry[k].mc_data[i] & 0xffff0000) >> 16;
+				}
+				j++;
+				PP_ASSERT_WITH_CODE((j <= SMU72_DISCRETE_MC_REGISTER_ARRAY_SIZE),
+					"Invalid VramInfo table.", return -1);
+			}
+
+			break;
+
+		case mmMC_SEQ_RESERVE_M:
+			temp_reg = cgs_read_register(hwmgr->device, mmMC_PMG_CMD_MRS1);
+			table->mc_reg_address[j].s1 = mmMC_PMG_CMD_MRS1;
+			table->mc_reg_address[j].s0 = mmMC_SEQ_PMG_CMD_MRS1_LP;
+			for (k = 0; k < table->num_entries; k++) {
+				table->mc_reg_table_entry[k].mc_data[j] =
+					(temp_reg & 0xffff0000) |
+					(table->mc_reg_table_entry[k].mc_data[i] & 0x0000ffff);
+			}
+			j++;
+			PP_ASSERT_WITH_CODE((j <= SMU72_DISCRETE_MC_REGISTER_ARRAY_SIZE),
+				"Invalid VramInfo table.", return -1);
+			break;
+
+		default:
+			break;
+		}
+
+	}
+
+	table->last = j;
+
+	return 0;
+}
+
+int tonga_set_valid_flag(phw_tonga_mc_reg_table *table)
+{
+	uint8_t i, j;
+	for (i = 0; i < table->last; i++) {
+		for (j = 1; j < table->num_entries; j++) {
+			if (table->mc_reg_table_entry[j-1].mc_data[i] !=
+				table->mc_reg_table_entry[j].mc_data[i]) {
+				table->validflag |= (1<<i);
+				break;
+			}
+		}
+	}
+
+	return 0;
+}
+
+int tonga_initialize_mc_reg_table(struct pp_hwmgr *hwmgr)
+{
+	int result;
+	tonga_hwmgr *data = (tonga_hwmgr *)(hwmgr->backend);
+	pp_atomctrl_mc_reg_table *table;
+	phw_tonga_mc_reg_table *ni_table = &data->tonga_mc_reg_table;
+	uint8_t module_index = tonga_get_memory_modile_index(hwmgr);
+
+	table = kzalloc(sizeof(pp_atomctrl_mc_reg_table), GFP_KERNEL);
+
+	if (NULL == table)
+		return -ENOMEM;
+
+	/* Program additional LP registers that are no longer programmed by VBIOS */
+	cgs_write_register(hwmgr->device, mmMC_SEQ_RAS_TIMING_LP, cgs_read_register(hwmgr->device, mmMC_SEQ_RAS_TIMING));
+	cgs_write_register(hwmgr->device, mmMC_SEQ_CAS_TIMING_LP, cgs_read_register(hwmgr->device, mmMC_SEQ_CAS_TIMING));
+	cgs_write_register(hwmgr->device, mmMC_SEQ_DLL_STBY_LP, cgs_read_register(hwmgr->device, mmMC_SEQ_DLL_STBY));
+	cgs_write_register(hwmgr->device, mmMC_SEQ_G5PDX_CMD0_LP, cgs_read_register(hwmgr->device, mmMC_SEQ_G5PDX_CMD0));
+	cgs_write_register(hwmgr->device, mmMC_SEQ_G5PDX_CMD1_LP, cgs_read_register(hwmgr->device, mmMC_SEQ_G5PDX_CMD1));
+	cgs_write_register(hwmgr->device, mmMC_SEQ_G5PDX_CTRL_LP, cgs_read_register(hwmgr->device, mmMC_SEQ_G5PDX_CTRL));
+	cgs_write_register(hwmgr->device, mmMC_SEQ_PMG_DVS_CMD_LP, cgs_read_register(hwmgr->device, mmMC_SEQ_PMG_DVS_CMD));
+	cgs_write_register(hwmgr->device, mmMC_SEQ_PMG_DVS_CTL_LP, cgs_read_register(hwmgr->device, mmMC_SEQ_PMG_DVS_CTL));
+	cgs_write_register(hwmgr->device, mmMC_SEQ_MISC_TIMING_LP, cgs_read_register(hwmgr->device, mmMC_SEQ_MISC_TIMING));
+	cgs_write_register(hwmgr->device, mmMC_SEQ_MISC_TIMING2_LP, cgs_read_register(hwmgr->device, mmMC_SEQ_MISC_TIMING2));
+	cgs_write_register(hwmgr->device, mmMC_SEQ_PMG_CMD_EMRS_LP, cgs_read_register(hwmgr->device, mmMC_PMG_CMD_EMRS));
+	cgs_write_register(hwmgr->device, mmMC_SEQ_PMG_CMD_MRS_LP, cgs_read_register(hwmgr->device, mmMC_PMG_CMD_MRS));
+	cgs_write_register(hwmgr->device, mmMC_SEQ_PMG_CMD_MRS1_LP, cgs_read_register(hwmgr->device, mmMC_PMG_CMD_MRS1));
+	cgs_write_register(hwmgr->device, mmMC_SEQ_WR_CTL_D0_LP, cgs_read_register(hwmgr->device, mmMC_SEQ_WR_CTL_D0));
+	cgs_write_register(hwmgr->device, mmMC_SEQ_WR_CTL_D1_LP, cgs_read_register(hwmgr->device, mmMC_SEQ_WR_CTL_D1));
+	cgs_write_register(hwmgr->device, mmMC_SEQ_RD_CTL_D0_LP, cgs_read_register(hwmgr->device, mmMC_SEQ_RD_CTL_D0));
+	cgs_write_register(hwmgr->device, mmMC_SEQ_RD_CTL_D1_LP, cgs_read_register(hwmgr->device, mmMC_SEQ_RD_CTL_D1));
+	cgs_write_register(hwmgr->device, mmMC_SEQ_PMG_TIMING_LP, cgs_read_register(hwmgr->device, mmMC_SEQ_PMG_TIMING));
+	cgs_write_register(hwmgr->device, mmMC_SEQ_PMG_CMD_MRS2_LP, cgs_read_register(hwmgr->device, mmMC_PMG_CMD_MRS2));
+	cgs_write_register(hwmgr->device, mmMC_SEQ_WR_CTL_2_LP, cgs_read_register(hwmgr->device, mmMC_SEQ_WR_CTL_2));
+
+	memset(table, 0x00, sizeof(pp_atomctrl_mc_reg_table));
+
+	result = atomctrl_initialize_mc_reg_table(hwmgr, module_index, table);
+
+	if (0 == result)
+		result = tonga_copy_vbios_smc_reg_table(table, ni_table);
+
+	if (0 == result) {
+		tonga_set_s0_mc_reg_index(ni_table);
+		result = tonga_set_mc_special_registers(hwmgr, ni_table);
+	}
+
+	if (0 == result)
+		tonga_set_valid_flag(ni_table);
+
+	kfree(table);
+	return result;
+}
+
+/*
+* Copy one arb setting to another and then switch the active set.
+* arbFreqSrc and arbFreqDest is one of the MC_CG_ARB_FREQ_Fx constants.
+*/
+int tonga_copy_and_switch_arb_sets(struct pp_hwmgr *hwmgr,
+		uint32_t arbFreqSrc, uint32_t arbFreqDest)
+{
+	uint32_t mc_arb_dram_timing;
+	uint32_t mc_arb_dram_timing2;
+	uint32_t burst_time;
+	uint32_t mc_cg_config;
+
+	switch (arbFreqSrc) {
+	case MC_CG_ARB_FREQ_F0:
+		mc_arb_dram_timing  = cgs_read_register(hwmgr->device, mmMC_ARB_DRAM_TIMING);
+		mc_arb_dram_timing2 = cgs_read_register(hwmgr->device, mmMC_ARB_DRAM_TIMING2);
+		burst_time = PHM_READ_FIELD(hwmgr->device, MC_ARB_BURST_TIME, STATE0);
+		break;
+
+	case MC_CG_ARB_FREQ_F1:
+		mc_arb_dram_timing  = cgs_read_register(hwmgr->device, mmMC_ARB_DRAM_TIMING_1);
+		mc_arb_dram_timing2 = cgs_read_register(hwmgr->device, mmMC_ARB_DRAM_TIMING2_1);
+		burst_time = PHM_READ_FIELD(hwmgr->device, MC_ARB_BURST_TIME, STATE1);
+		break;
+
+	default:
+		return -1;
+	}
+
+	switch (arbFreqDest) {
+	case MC_CG_ARB_FREQ_F0:
+		cgs_write_register(hwmgr->device, mmMC_ARB_DRAM_TIMING, mc_arb_dram_timing);
+		cgs_write_register(hwmgr->device, mmMC_ARB_DRAM_TIMING2, mc_arb_dram_timing2);
+		PHM_WRITE_FIELD(hwmgr->device, MC_ARB_BURST_TIME, STATE0, burst_time);
+		break;
+
+	case MC_CG_ARB_FREQ_F1:
+		cgs_write_register(hwmgr->device, mmMC_ARB_DRAM_TIMING_1, mc_arb_dram_timing);
+		cgs_write_register(hwmgr->device, mmMC_ARB_DRAM_TIMING2_1, mc_arb_dram_timing2);
+		PHM_WRITE_FIELD(hwmgr->device, MC_ARB_BURST_TIME, STATE1, burst_time);
+		break;
+
+	default:
+		return -1;
+	}
+
+	mc_cg_config = cgs_read_register(hwmgr->device, mmMC_CG_CONFIG);
+	mc_cg_config |= 0x0000000F;
+	cgs_write_register(hwmgr->device, mmMC_CG_CONFIG, mc_cg_config);
+	PHM_WRITE_FIELD(hwmgr->device, MC_ARB_CG, CG_ARB_REQ, arbFreqDest);
+
+	return 0;
+}
+
+/**
+ * Initial switch from ARB F0->F1
+ *
+ * @param    hwmgr  the address of the powerplay hardware manager.
+ * @return   always 0
+ * This function is to be called from the SetPowerState table.
+ */
+int tonga_initial_switch_from_arb_f0_to_f1(struct pp_hwmgr *hwmgr)
+{
+	return tonga_copy_and_switch_arb_sets(hwmgr, MC_CG_ARB_FREQ_F0, MC_CG_ARB_FREQ_F1);
+}
+
+/**
+ * Initialize the ARB DRAM timing table's index field.
+ *
+ * @param    hwmgr  the address of the powerplay hardware manager.
+ * @return   always 0
+ */
+int tonga_init_arb_table_index(struct pp_hwmgr *hwmgr)
+{
+	const tonga_hwmgr *data = (struct tonga_hwmgr *)(hwmgr->backend);
+	uint32_t tmp;
+	int result;
+
+	/*
+	* This is a read-modify-write on the first byte of the ARB table.
+	* The first byte in the SMU72_Discrete_MCArbDramTimingTable structure is the field 'current'.
+	* This solution is ugly, but we never write the whole table only individual fields in it.
+	* In reality this field should not be in that structure but in a soft register.
+	*/
+	result = tonga_read_smc_sram_dword(hwmgr->smumgr,
+				data->arb_table_start, &tmp, data->sram_end);
+
+	if (0 != result)
+		return result;
+
+	tmp &= 0x00FFFFFF;
+	tmp |= ((uint32_t)MC_CG_ARB_FREQ_F1) << 24;
+
+	return tonga_write_smc_sram_dword(hwmgr->smumgr,
+			data->arb_table_start,  tmp, data->sram_end);
+}
+
+int tonga_populate_mc_reg_address(struct pp_hwmgr *hwmgr, SMU72_Discrete_MCRegisters *mc_reg_table)
+{
+	const struct tonga_hwmgr *data = (struct tonga_hwmgr *)(hwmgr->backend);
+
+	uint32_t i, j;
+
+	for (i = 0, j = 0; j < data->tonga_mc_reg_table.last; j++) {
+		if (data->tonga_mc_reg_table.validflag & 1<<j) {
+			PP_ASSERT_WITH_CODE(i < SMU72_DISCRETE_MC_REGISTER_ARRAY_SIZE,
+				"Index of mc_reg_table->address[] array out of boundary", return -1);
+			mc_reg_table->address[i].s0 =
+				PP_HOST_TO_SMC_US(data->tonga_mc_reg_table.mc_reg_address[j].s0);
+			mc_reg_table->address[i].s1 =
+				PP_HOST_TO_SMC_US(data->tonga_mc_reg_table.mc_reg_address[j].s1);
+			i++;
+		}
+	}
+
+	mc_reg_table->last = (uint8_t)i;
+
+	return 0;
+}
+
+/*convert register values from driver to SMC format */
+void tonga_convert_mc_registers(
+	const phw_tonga_mc_reg_entry * pEntry,
+	SMU72_Discrete_MCRegisterSet *pData,
+	uint32_t numEntries, uint32_t validflag)
+{
+	uint32_t i, j;
+
+	for (i = 0, j = 0; j < numEntries; j++) {
+		if (validflag & 1<<j) {
+			pData->value[i] = PP_HOST_TO_SMC_UL(pEntry->mc_data[j]);
+			i++;
+		}
+	}
+}
+
+/* find the entry in the memory range table, then populate the value to SMC's tonga_mc_reg_table */
+int tonga_convert_mc_reg_table_entry_to_smc(
+		struct pp_hwmgr *hwmgr,
+		const uint32_t memory_clock,
+		SMU72_Discrete_MCRegisterSet *mc_reg_table_data
+		)
+{
+	const tonga_hwmgr *data = (struct tonga_hwmgr *)(hwmgr->backend);
+	uint32_t i = 0;
+
+	for (i = 0; i < data->tonga_mc_reg_table.num_entries; i++) {
+		if (memory_clock <=
+			data->tonga_mc_reg_table.mc_reg_table_entry[i].mclk_max) {
+			break;
+		}
+	}
+
+	if ((i == data->tonga_mc_reg_table.num_entries) && (i > 0))
+		--i;
+
+	tonga_convert_mc_registers(&data->tonga_mc_reg_table.mc_reg_table_entry[i],
+		mc_reg_table_data, data->tonga_mc_reg_table.last, data->tonga_mc_reg_table.validflag);
+
+	return 0;
+}
+
+int tonga_convert_mc_reg_table_to_smc(struct pp_hwmgr *hwmgr,
+		SMU72_Discrete_MCRegisters *mc_reg_table)
+{
+	int result = 0;
+	tonga_hwmgr *data = (struct tonga_hwmgr *)(hwmgr->backend);
+	int res;
+	uint32_t i;
+
+	for (i = 0; i < data->dpm_table.mclk_table.count; i++) {
+		res = tonga_convert_mc_reg_table_entry_to_smc(
+				hwmgr,
+				data->dpm_table.mclk_table.dpm_levels[i].value,
+				&mc_reg_table->data[i]
+				);
+
+		if (0 != res)
+			result = res;
+	}
+
+	return result;
+}
+
+int tonga_populate_initial_mc_reg_table(struct pp_hwmgr *hwmgr)
+{
+	int result;
+	struct tonga_hwmgr *data = (struct tonga_hwmgr *)(hwmgr->backend);
+
+	memset(&data->mc_reg_table, 0x00, sizeof(SMU72_Discrete_MCRegisters));
+	result = tonga_populate_mc_reg_address(hwmgr, &(data->mc_reg_table));
+	PP_ASSERT_WITH_CODE(0 == result,
+		"Failed to initialize MCRegTable for the MC register addresses!", return result;);
+
+	result = tonga_convert_mc_reg_table_to_smc(hwmgr, &data->mc_reg_table);
+	PP_ASSERT_WITH_CODE(0 == result,
+		"Failed to initialize MCRegTable for driver state!", return result;);
+
+	return tonga_copy_bytes_to_smc(hwmgr->smumgr, data->mc_reg_table_start,
+			(uint8_t *)&data->mc_reg_table, sizeof(SMU72_Discrete_MCRegisters), data->sram_end);
+}
+
+/**
+ * Programs static screed detection parameters
+ *
+ * @param   hwmgr  the address of the powerplay hardware manager.
+ * @return   always 0
+ */
+int tonga_program_static_screen_threshold_parameters(struct pp_hwmgr *hwmgr)
+{
+	tonga_hwmgr *data = (tonga_hwmgr *)(hwmgr->backend);
+
+	/* Set static screen threshold unit*/
+	PHM_WRITE_VFPF_INDIRECT_FIELD(hwmgr->device,
+		CGS_IND_REG__SMC, CG_STATIC_SCREEN_PARAMETER, STATIC_SCREEN_THRESHOLD_UNIT,
+		data->static_screen_threshold_unit);
+	/* Set static screen threshold*/
+	PHM_WRITE_VFPF_INDIRECT_FIELD(hwmgr->device,
+		CGS_IND_REG__SMC, CG_STATIC_SCREEN_PARAMETER, STATIC_SCREEN_THRESHOLD,
+		data->static_screen_threshold);
+
+	return 0;
+}
+
+/**
+ * Setup display gap for glitch free memory clock switching.
+ *
+ * @param    hwmgr  the address of the powerplay hardware manager.
+ * @return   always 0
+ */
+int tonga_enable_display_gap(struct pp_hwmgr *hwmgr)
+{
+	uint32_t display_gap = cgs_read_ind_register(hwmgr->device,
+							CGS_IND_REG__SMC, ixCG_DISPLAY_GAP_CNTL);
+
+	display_gap = PHM_SET_FIELD(display_gap,
+					CG_DISPLAY_GAP_CNTL, DISP_GAP, DISPLAY_GAP_IGNORE);
+
+	display_gap = PHM_SET_FIELD(display_gap,
+					CG_DISPLAY_GAP_CNTL, DISP_GAP_MCHG, DISPLAY_GAP_VBLANK);
+
+	cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC,
+		ixCG_DISPLAY_GAP_CNTL, display_gap);
+
+	return 0;
+}
+
+/**
+ * Programs activity state transition voting clients
+ *
+ * @param    hwmgr  the address of the powerplay hardware manager.
+ * @return   always 0
+ */
+int tonga_program_voting_clients(struct pp_hwmgr *hwmgr)
+{
+	tonga_hwmgr *data = (tonga_hwmgr *)(hwmgr->backend);
+
+	/* Clear reset for voting clients before enabling DPM */
+	PHM_WRITE_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC,
+		SCLK_PWRMGT_CNTL, RESET_SCLK_CNT, 0);
+	PHM_WRITE_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC,
+		SCLK_PWRMGT_CNTL, RESET_BUSY_CNT, 0);
+
+	cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC,
+		ixCG_FREQ_TRAN_VOTING_0, data->voting_rights_clients0);
+	cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC,
+		ixCG_FREQ_TRAN_VOTING_1, data->voting_rights_clients1);
+	cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC,
+		ixCG_FREQ_TRAN_VOTING_2, data->voting_rights_clients2);
+	cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC,
+		ixCG_FREQ_TRAN_VOTING_3, data->voting_rights_clients3);
+	cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC,
+		ixCG_FREQ_TRAN_VOTING_4, data->voting_rights_clients4);
+	cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC,
+		ixCG_FREQ_TRAN_VOTING_5, data->voting_rights_clients5);
+	cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC,
+		ixCG_FREQ_TRAN_VOTING_6, data->voting_rights_clients6);
+	cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC,
+		ixCG_FREQ_TRAN_VOTING_7, data->voting_rights_clients7);
+
+	return 0;
+}
+
+
+int tonga_enable_dpm_tasks(struct pp_hwmgr *hwmgr)
+{
+	int tmp_result, result = 0;
+
+	tmp_result = tonga_check_for_dpm_stopped(hwmgr);
+
+	if (cf_tonga_voltage_control(hwmgr)) {
+		tmp_result = tonga_enable_voltage_control(hwmgr);
+		PP_ASSERT_WITH_CODE((0 == tmp_result),
+			"Failed to enable voltage control!", result = tmp_result);
+
+		tmp_result = tonga_construct_voltage_tables(hwmgr);
+		PP_ASSERT_WITH_CODE((0 == tmp_result),
+			"Failed to contruct voltage tables!", result = tmp_result);
+	}
+
+	tmp_result = tonga_initialize_mc_reg_table(hwmgr);
+	PP_ASSERT_WITH_CODE((0 == tmp_result),
+		"Failed to initialize MC reg table!", result = tmp_result);
+
+	tmp_result = tonga_program_static_screen_threshold_parameters(hwmgr);
+	PP_ASSERT_WITH_CODE((0 == tmp_result),
+		"Failed to program static screen threshold parameters!", result = tmp_result);
+
+	tmp_result = tonga_enable_display_gap(hwmgr);
+	PP_ASSERT_WITH_CODE((0 == tmp_result),
+		"Failed to enable display gap!", result = tmp_result);
+
+	tmp_result = tonga_program_voting_clients(hwmgr);
+	PP_ASSERT_WITH_CODE((0 == tmp_result),
+		"Failed to program voting clients!", result = tmp_result);
+
+	tmp_result = tonga_process_firmware_header(hwmgr);
+	PP_ASSERT_WITH_CODE((0 == tmp_result),
+		"Failed to process firmware header!", result = tmp_result);
+
+	tmp_result = tonga_initial_switch_from_arb_f0_to_f1(hwmgr);
+	PP_ASSERT_WITH_CODE((0 == tmp_result),
+		"Failed to initialize switch from ArbF0 to F1!", result = tmp_result);
+
+	tmp_result = tonga_init_smc_table(hwmgr);
+	PP_ASSERT_WITH_CODE((0 == tmp_result),
+		"Failed to initialize SMC table!", result = tmp_result);
+
+	tmp_result = tonga_init_arb_table_index(hwmgr);
+	PP_ASSERT_WITH_CODE((0 == tmp_result),
+		"Failed to initialize ARB table index!", result = tmp_result);
+
+	tmp_result = tonga_populate_initial_mc_reg_table(hwmgr);
+	PP_ASSERT_WITH_CODE((0 == tmp_result),
+		"Failed to populate initialize MC Reg table!", result = tmp_result);
+
+	tmp_result = tonga_notify_smc_display_change(hwmgr, false);
+	PP_ASSERT_WITH_CODE((0 == tmp_result),
+		"Failed to notify no display!", result = tmp_result);
+
+	/* enable SCLK control */
+	tmp_result = tonga_enable_sclk_control(hwmgr);
+	PP_ASSERT_WITH_CODE((0 == tmp_result),
+		"Failed to enable SCLK control!", result = tmp_result);
+
+	/* enable DPM */
+	tmp_result = tonga_start_dpm(hwmgr);
+	PP_ASSERT_WITH_CODE((0 == tmp_result),
+		"Failed to start DPM!", result = tmp_result);
+
+	return result;
+}
+
+int tonga_disable_dpm_tasks(struct pp_hwmgr *hwmgr)
+{
+	int tmp_result, result = 0;
+
+	tmp_result = tonga_check_for_dpm_running(hwmgr);
+	PP_ASSERT_WITH_CODE((0 == tmp_result),
+		"SMC is still running!", return 0);
+
+	tmp_result = tonga_stop_dpm(hwmgr);
+	PP_ASSERT_WITH_CODE((0 == tmp_result),
+		"Failed to stop DPM!", result = tmp_result);
+
+	tmp_result = tonga_reset_to_default(hwmgr);
+	PP_ASSERT_WITH_CODE((0 == tmp_result),
+		"Failed to reset to default!", result = tmp_result);
+
+	return result;
+}
+
+int tonga_reset_asic_tasks(struct pp_hwmgr *hwmgr)
+{
+	int result;
+
+	result = tonga_set_boot_state(hwmgr);
+	if (0 != result)
+		printk(KERN_ERR "[ powerplay ] Failed to reset asic via set boot state! \n");
+
+	return result;
+}
+
+int tonga_hwmgr_backend_fini(struct pp_hwmgr *hwmgr)
+{
+	if (NULL != hwmgr->dyn_state.vddc_dep_on_dal_pwrl) {
+		kfree(hwmgr->dyn_state.vddc_dep_on_dal_pwrl);
+		hwmgr->dyn_state.vddc_dep_on_dal_pwrl = NULL;
+	}
+
+	if (NULL != hwmgr->backend) {
+		kfree(hwmgr->backend);
+		hwmgr->backend = NULL;
+	}
+
+	return 0;
+}
+
+/**
+ * Initializes the Volcanic Islands Hardware Manager
+ *
+ * @param   hwmgr the address of the powerplay hardware manager.
+ * @return   1 if success; otherwise appropriate error code.
+ */
+int tonga_hwmgr_backend_init(struct pp_hwmgr *hwmgr)
+{
+	int result = 0;
+	SMU72_Discrete_DpmTable  *table = NULL;
+	tonga_hwmgr *data = (struct tonga_hwmgr *)(hwmgr->backend);
+	pp_atomctrl_gpio_pin_assignment gpio_pin_assignment;
+	struct phm_ppt_v1_information *pptable_info = (struct phm_ppt_v1_information *)(hwmgr->pptable);
+	phw_tonga_ulv_parm *ulv;
+	struct cgs_system_info sys_info = {0};
+
+	PP_ASSERT_WITH_CODE((NULL != hwmgr),
+		"Invalid Parameter!", return -1;);
+
+	data->dll_defaule_on = 0;
+	data->sram_end = SMC_RAM_END;
+
+	data->activity_target[0] = PPTONGA_TARGETACTIVITY_DFLT;
+	data->activity_target[1] = PPTONGA_TARGETACTIVITY_DFLT;
+	data->activity_target[2] = PPTONGA_TARGETACTIVITY_DFLT;
+	data->activity_target[3] = PPTONGA_TARGETACTIVITY_DFLT;
+	data->activity_target[4] = PPTONGA_TARGETACTIVITY_DFLT;
+	data->activity_target[5] = PPTONGA_TARGETACTIVITY_DFLT;
+	data->activity_target[6] = PPTONGA_TARGETACTIVITY_DFLT;
+	data->activity_target[7] = PPTONGA_TARGETACTIVITY_DFLT;
+
+	data->vddc_vddci_delta = VDDC_VDDCI_DELTA;
+	data->vddc_vddgfx_delta = VDDC_VDDGFX_DELTA;
+	data->mclk_activity_target = PPTONGA_MCLK_TARGETACTIVITY_DFLT;
+
+	phm_cap_set(hwmgr->platform_descriptor.platformCaps,
+		PHM_PlatformCaps_DisableVoltageIsland);
+
+	data->sclk_dpm_key_disabled = 0;
+	data->mclk_dpm_key_disabled = 0;
+	data->pcie_dpm_key_disabled = 0;
+	data->pcc_monitor_enabled = 0;
+
+	phm_cap_set(hwmgr->platform_descriptor.platformCaps,
+		PHM_PlatformCaps_UnTabledHardwareInterface);
+
+	data->gpio_debug = 0;
+	data->engine_clock_data = 0;
+	data->memory_clock_data = 0;
+	phm_cap_set(hwmgr->platform_descriptor.platformCaps,
+		PHM_PlatformCaps_DynamicPatchPowerState);
+
+	/* need to set voltage control types before EVV patching*/
+	data->voltage_control = TONGA_VOLTAGE_CONTROL_NONE;
+	data->vdd_ci_control = TONGA_VOLTAGE_CONTROL_NONE;
+	data->vdd_gfx_control = TONGA_VOLTAGE_CONTROL_NONE;
+	data->mvdd_control = TONGA_VOLTAGE_CONTROL_NONE;
+
+	if (atomctrl_is_voltage_controled_by_gpio_v3(hwmgr,
+				VOLTAGE_TYPE_VDDC, VOLTAGE_OBJ_SVID2)) {
+		data->voltage_control = TONGA_VOLTAGE_CONTROL_BY_SVID2;
+	}
+
+	if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
+			PHM_PlatformCaps_ControlVDDGFX)) {
+		if (atomctrl_is_voltage_controled_by_gpio_v3(hwmgr,
+			VOLTAGE_TYPE_VDDGFX, VOLTAGE_OBJ_SVID2)) {
+			data->vdd_gfx_control = TONGA_VOLTAGE_CONTROL_BY_SVID2;
+		}
+	}
+
+	if (TONGA_VOLTAGE_CONTROL_NONE == data->vdd_gfx_control) {
+		phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
+			PHM_PlatformCaps_ControlVDDGFX);
+	}
+
+	if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
+			PHM_PlatformCaps_EnableMVDDControl)) {
+		if (atomctrl_is_voltage_controled_by_gpio_v3(hwmgr,
+					VOLTAGE_TYPE_MVDDC, VOLTAGE_OBJ_GPIO_LUT)) {
+			data->mvdd_control = TONGA_VOLTAGE_CONTROL_BY_GPIO;
+		}
+	}
+
+	if (TONGA_VOLTAGE_CONTROL_NONE == data->mvdd_control) {
+		phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
+			PHM_PlatformCaps_EnableMVDDControl);
+	}
+
+	if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
+			PHM_PlatformCaps_ControlVDDCI)) {
+		if (atomctrl_is_voltage_controled_by_gpio_v3(hwmgr,
+					VOLTAGE_TYPE_VDDCI, VOLTAGE_OBJ_GPIO_LUT))
+			data->vdd_ci_control = TONGA_VOLTAGE_CONTROL_BY_GPIO;
+		else if (atomctrl_is_voltage_controled_by_gpio_v3(hwmgr,
+						VOLTAGE_TYPE_VDDCI, VOLTAGE_OBJ_SVID2))
+			data->vdd_ci_control = TONGA_VOLTAGE_CONTROL_BY_SVID2;
+	}
+
+	if (TONGA_VOLTAGE_CONTROL_NONE == data->vdd_ci_control)
+		phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
+		PHM_PlatformCaps_ControlVDDCI);
+
+	phm_cap_set(hwmgr->platform_descriptor.platformCaps,
+		PHM_PlatformCaps_TablelessHardwareInterface);
+
+	if (pptable_info->cac_dtp_table->usClockStretchAmount != 0)
+		phm_cap_set(hwmgr->platform_descriptor.platformCaps,
+			PHM_PlatformCaps_ClockStretcher);
+
+	/* Initializes DPM default values*/
+	tonga_initialize_dpm_defaults(hwmgr);
+
+	/* Get leakage voltage based on leakage ID.*/
+	PP_ASSERT_WITH_CODE((0 == tonga_get_evv_voltage(hwmgr)),
+		"Get EVV Voltage Failed.  Abort Driver loading!", return -1);
+
+	tonga_complete_dependency_tables(hwmgr);
+
+	/* Parse pptable data read from VBIOS*/
+	tonga_set_private_var_based_on_pptale(hwmgr);
+
+	/* ULV Support*/
+	ulv = &(data->ulv);
+	ulv->ulv_supported = 0;
+
+	/* Initalize Dynamic State Adjustment Rule Settings*/
+	result = tonga_initializa_dynamic_state_adjustment_rule_settings(hwmgr);
+	if (result)
+		printk(KERN_ERR "[ powerplay ] tonga_initializa_dynamic_state_adjustment_rule_settings failed!\n");
+	data->uvd_enabled = 0;
+
+	table = &(data->smc_state_table);
+
+	/*
+	* if ucGPIO_ID=VDDC_PCC_GPIO_PINID in GPIO_LUTable,
+	* Peak Current Control feature is enabled and we should program PCC HW register
+	*/
+	if (0 == atomctrl_get_pp_assign_pin(hwmgr, VDDC_PCC_GPIO_PINID, &gpio_pin_assignment)) {
+		uint32_t temp_reg = cgs_read_ind_register(hwmgr->device,
+										CGS_IND_REG__SMC, ixCNB_PWRMGT_CNTL);
+
+		switch (gpio_pin_assignment.uc_gpio_pin_bit_shift) {
+		case 0:
+			temp_reg = PHM_SET_FIELD(temp_reg,
+				CNB_PWRMGT_CNTL, GNB_SLOW_MODE, 0x1);
+			break;
+		case 1:
+			temp_reg = PHM_SET_FIELD(temp_reg,
+				CNB_PWRMGT_CNTL, GNB_SLOW_MODE, 0x2);
+			break;
+		case 2:
+			temp_reg = PHM_SET_FIELD(temp_reg,
+				CNB_PWRMGT_CNTL, GNB_SLOW, 0x1);
+			break;
+		case 3:
+			temp_reg = PHM_SET_FIELD(temp_reg,
+				CNB_PWRMGT_CNTL, FORCE_NB_PS1, 0x1);
+			break;
+		case 4:
+			temp_reg = PHM_SET_FIELD(temp_reg,
+				CNB_PWRMGT_CNTL, DPM_ENABLED, 0x1);
+			break;
+		default:
+			printk(KERN_ERR "[ powerplay ] Failed to setup PCC HW register!	\
+				Wrong GPIO assigned for VDDC_PCC_GPIO_PINID! \n");
+			break;
+		}
+		cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC,
+			ixCNB_PWRMGT_CNTL, temp_reg);
+	}
+
+	phm_cap_set(hwmgr->platform_descriptor.platformCaps,
+		PHM_PlatformCaps_EnableSMU7ThermalManagement);
+	phm_cap_set(hwmgr->platform_descriptor.platformCaps,
+		PHM_PlatformCaps_SMU7);
+
+	data->vddc_phase_shed_control = 0;
+
+	phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
+		      PHM_PlatformCaps_UVDPowerGating);
+	phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
+		      PHM_PlatformCaps_VCEPowerGating);
+	sys_info.size = sizeof(struct cgs_system_info);
+	sys_info.info_id = CGS_SYSTEM_INFO_PG_FLAGS;
+	result = cgs_query_system_info(hwmgr->device, &sys_info);
+	if (!result) {
+		if (sys_info.value & AMD_PG_SUPPORT_UVD)
+			phm_cap_set(hwmgr->platform_descriptor.platformCaps,
+				      PHM_PlatformCaps_UVDPowerGating);
+		if (sys_info.value & AMD_PG_SUPPORT_VCE)
+			phm_cap_set(hwmgr->platform_descriptor.platformCaps,
+				      PHM_PlatformCaps_VCEPowerGating);
+	}
+
+	if (0 == result) {
+		data->is_tlu_enabled = 0;
+		hwmgr->platform_descriptor.hardwareActivityPerformanceLevels =
+			TONGA_MAX_HARDWARE_POWERLEVELS;
+		hwmgr->platform_descriptor.hardwarePerformanceLevels = 2;
+		hwmgr->platform_descriptor.minimumClocksReductionPercentage  = 50;
+
+		sys_info.size = sizeof(struct cgs_system_info);
+		sys_info.info_id = CGS_SYSTEM_INFO_PCIE_GEN_INFO;
+		result = cgs_query_system_info(hwmgr->device, &sys_info);
+		if (result)
+			data->pcie_gen_cap = 0x30007;
+		else
+			data->pcie_gen_cap = (uint32_t)sys_info.value;
+		if (data->pcie_gen_cap & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3)
+			data->pcie_spc_cap = 20;
+		sys_info.size = sizeof(struct cgs_system_info);
+		sys_info.info_id = CGS_SYSTEM_INFO_PCIE_MLW;
+		result = cgs_query_system_info(hwmgr->device, &sys_info);
+		if (result)
+			data->pcie_lane_cap = 0x2f0000;
+		else
+			data->pcie_lane_cap = (uint32_t)sys_info.value;
+	} else {
+		/* Ignore return value in here, we are cleaning up a mess. */
+		tonga_hwmgr_backend_fini(hwmgr);
+	}
+
+	return result;
+}
+
+static int tonga_force_dpm_level(struct pp_hwmgr *hwmgr,
+		enum amd_dpm_forced_level level)
+{
+	int ret = 0;
+
+	switch (level) {
+	case AMD_DPM_FORCED_LEVEL_HIGH:
+		ret = tonga_force_dpm_highest(hwmgr);
+		if (ret)
+			return ret;
+		break;
+	case AMD_DPM_FORCED_LEVEL_LOW:
+		ret = tonga_force_dpm_lowest(hwmgr);
+		if (ret)
+			return ret;
+		break;
+	case AMD_DPM_FORCED_LEVEL_AUTO:
+		ret = tonga_unforce_dpm_levels(hwmgr);
+		if (ret)
+			return ret;
+		break;
+	default:
+		break;
+	}
+
+	hwmgr->dpm_level = level;
+	return ret;
+}
+
+static int tonga_apply_state_adjust_rules(struct pp_hwmgr *hwmgr,
+				struct pp_power_state  *prequest_ps,
+			const struct pp_power_state *pcurrent_ps)
+{
+	struct tonga_power_state *tonga_ps =
+				cast_phw_tonga_power_state(&prequest_ps->hardware);
+
+	uint32_t sclk;
+	uint32_t mclk;
+	struct PP_Clocks minimum_clocks = {0};
+	bool disable_mclk_switching;
+	bool disable_mclk_switching_for_frame_lock;
+	struct cgs_display_info info = {0};
+	const struct phm_clock_and_voltage_limits *max_limits;
+	uint32_t i;
+	tonga_hwmgr *data = (struct tonga_hwmgr *)(hwmgr->backend);
+	struct phm_ppt_v1_information *pptable_info = (struct phm_ppt_v1_information *)(hwmgr->pptable);
+
+	int32_t count;
+	int32_t stable_pstate_sclk = 0, stable_pstate_mclk = 0;
+
+	data->battery_state = (PP_StateUILabel_Battery == prequest_ps->classification.ui_label);
+
+	PP_ASSERT_WITH_CODE(tonga_ps->performance_level_count == 2,
+				 "VI should always have 2 performance levels",
+				 );
+
+	max_limits = (PP_PowerSource_AC == hwmgr->power_source) ?
+			&(hwmgr->dyn_state.max_clock_voltage_on_ac) :
+			&(hwmgr->dyn_state.max_clock_voltage_on_dc);
+
+	if (PP_PowerSource_DC == hwmgr->power_source) {
+		for (i = 0; i < tonga_ps->performance_level_count; i++) {
+			if (tonga_ps->performance_levels[i].memory_clock > max_limits->mclk)
+				tonga_ps->performance_levels[i].memory_clock = max_limits->mclk;
+			if (tonga_ps->performance_levels[i].engine_clock > max_limits->sclk)
+				tonga_ps->performance_levels[i].engine_clock = max_limits->sclk;
+		}
+	}
+
+	tonga_ps->vce_clocks.EVCLK = hwmgr->vce_arbiter.evclk;
+	tonga_ps->vce_clocks.ECCLK = hwmgr->vce_arbiter.ecclk;
+
+	tonga_ps->acp_clk = hwmgr->acp_arbiter.acpclk;
+
+	cgs_get_active_displays_info(hwmgr->device, &info);
+
+	/*TO DO result = PHM_CheckVBlankTime(hwmgr, &vblankTooShort);*/
+
+	/* TO DO GetMinClockSettings(hwmgr->pPECI, &minimum_clocks); */
+
+	if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_StablePState)) {
+
+		max_limits = &(hwmgr->dyn_state.max_clock_voltage_on_ac);
+		stable_pstate_sclk = (max_limits->sclk * 75) / 100;
+
+		for (count = pptable_info->vdd_dep_on_sclk->count-1; count >= 0; count--) {
+			if (stable_pstate_sclk >= pptable_info->vdd_dep_on_sclk->entries[count].clk) {
+				stable_pstate_sclk = pptable_info->vdd_dep_on_sclk->entries[count].clk;
+				break;
+			}
+		}
+
+		if (count < 0)
+			stable_pstate_sclk = pptable_info->vdd_dep_on_sclk->entries[0].clk;
+
+		stable_pstate_mclk = max_limits->mclk;
+
+		minimum_clocks.engineClock = stable_pstate_sclk;
+		minimum_clocks.memoryClock = stable_pstate_mclk;
+	}
+
+	if (minimum_clocks.engineClock < hwmgr->gfx_arbiter.sclk)
+		minimum_clocks.engineClock = hwmgr->gfx_arbiter.sclk;
+
+	if (minimum_clocks.memoryClock < hwmgr->gfx_arbiter.mclk)
+		minimum_clocks.memoryClock = hwmgr->gfx_arbiter.mclk;
+
+	tonga_ps->sclk_threshold = hwmgr->gfx_arbiter.sclk_threshold;
+
+	if (0 != hwmgr->gfx_arbiter.sclk_over_drive) {
+		PP_ASSERT_WITH_CODE((hwmgr->gfx_arbiter.sclk_over_drive <= hwmgr->platform_descriptor.overdriveLimit.engineClock),
+					"Overdrive sclk exceeds limit",
+					hwmgr->gfx_arbiter.sclk_over_drive = hwmgr->platform_descriptor.overdriveLimit.engineClock);
+
+		if (hwmgr->gfx_arbiter.sclk_over_drive >= hwmgr->gfx_arbiter.sclk)
+			tonga_ps->performance_levels[1].engine_clock = hwmgr->gfx_arbiter.sclk_over_drive;
+	}
+
+	if (0 != hwmgr->gfx_arbiter.mclk_over_drive) {
+		PP_ASSERT_WITH_CODE((hwmgr->gfx_arbiter.mclk_over_drive <= hwmgr->platform_descriptor.overdriveLimit.memoryClock),
+			"Overdrive mclk exceeds limit",
+			hwmgr->gfx_arbiter.mclk_over_drive = hwmgr->platform_descriptor.overdriveLimit.memoryClock);
+
+		if (hwmgr->gfx_arbiter.mclk_over_drive >= hwmgr->gfx_arbiter.mclk)
+			tonga_ps->performance_levels[1].memory_clock = hwmgr->gfx_arbiter.mclk_over_drive;
+	}
+
+	disable_mclk_switching_for_frame_lock = phm_cap_enabled(
+				    hwmgr->platform_descriptor.platformCaps,
+				    PHM_PlatformCaps_DisableMclkSwitchingForFrameLock);
+
+	disable_mclk_switching = (1 < info.display_count) ||
+				    disable_mclk_switching_for_frame_lock;
+
+	sclk  = tonga_ps->performance_levels[0].engine_clock;
+	mclk  = tonga_ps->performance_levels[0].memory_clock;
+
+	if (disable_mclk_switching)
+		mclk  = tonga_ps->performance_levels[tonga_ps->performance_level_count - 1].memory_clock;
+
+	if (sclk < minimum_clocks.engineClock)
+		sclk = (minimum_clocks.engineClock > max_limits->sclk) ? max_limits->sclk : minimum_clocks.engineClock;
+
+	if (mclk < minimum_clocks.memoryClock)
+		mclk = (minimum_clocks.memoryClock > max_limits->mclk) ? max_limits->mclk : minimum_clocks.memoryClock;
+
+	tonga_ps->performance_levels[0].engine_clock = sclk;
+	tonga_ps->performance_levels[0].memory_clock = mclk;
+
+	tonga_ps->performance_levels[1].engine_clock =
+		(tonga_ps->performance_levels[1].engine_clock >= tonga_ps->performance_levels[0].engine_clock) ?
+			      tonga_ps->performance_levels[1].engine_clock :
+			      tonga_ps->performance_levels[0].engine_clock;
+
+	if (disable_mclk_switching) {
+		if (mclk < tonga_ps->performance_levels[1].memory_clock)
+			mclk = tonga_ps->performance_levels[1].memory_clock;
+
+		tonga_ps->performance_levels[0].memory_clock = mclk;
+		tonga_ps->performance_levels[1].memory_clock = mclk;
+	} else {
+		if (tonga_ps->performance_levels[1].memory_clock < tonga_ps->performance_levels[0].memory_clock)
+			tonga_ps->performance_levels[1].memory_clock = tonga_ps->performance_levels[0].memory_clock;
+	}
+
+	if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_StablePState)) {
+		for (i=0; i < tonga_ps->performance_level_count; i++) {
+			tonga_ps->performance_levels[i].engine_clock = stable_pstate_sclk;
+			tonga_ps->performance_levels[i].memory_clock = stable_pstate_mclk;
+			tonga_ps->performance_levels[i].pcie_gen = data->pcie_gen_performance.max;
+			tonga_ps->performance_levels[i].pcie_lane = data->pcie_gen_performance.max;
+		}
+	}
+
+	return 0;
+}
+
+int tonga_get_power_state_size(struct pp_hwmgr *hwmgr)
+{
+	return sizeof(struct tonga_power_state);
+}
+
+static int tonga_dpm_get_mclk(struct pp_hwmgr *hwmgr, bool low)
+{
+	struct pp_power_state  *ps;
+	struct tonga_power_state  *tonga_ps;
+
+	if (hwmgr == NULL)
+		return -EINVAL;
+
+	ps = hwmgr->request_ps;
+
+	if (ps == NULL)
+		return -EINVAL;
+
+	tonga_ps = cast_phw_tonga_power_state(&ps->hardware);
+
+	if (low)
+		return tonga_ps->performance_levels[0].memory_clock;
+	else
+		return tonga_ps->performance_levels[tonga_ps->performance_level_count-1].memory_clock;
+}
+
+static int tonga_dpm_get_sclk(struct pp_hwmgr *hwmgr, bool low)
+{
+	struct pp_power_state  *ps;
+	struct tonga_power_state  *tonga_ps;
+
+	if (hwmgr == NULL)
+		return -EINVAL;
+
+	ps = hwmgr->request_ps;
+
+	if (ps == NULL)
+		return -EINVAL;
+
+	tonga_ps = cast_phw_tonga_power_state(&ps->hardware);
+
+	if (low)
+		return tonga_ps->performance_levels[0].engine_clock;
+	else
+		return tonga_ps->performance_levels[tonga_ps->performance_level_count-1].engine_clock;
+}
+
+static uint16_t tonga_get_current_pcie_speed(
+						   struct pp_hwmgr *hwmgr)
+{
+	uint32_t speed_cntl = 0;
+
+	speed_cntl = cgs_read_ind_register(hwmgr->device,
+						   CGS_IND_REG__PCIE,
+						   ixPCIE_LC_SPEED_CNTL);
+	return((uint16_t)PHM_GET_FIELD(speed_cntl,
+			PCIE_LC_SPEED_CNTL, LC_CURRENT_DATA_RATE));
+}
+
+static int tonga_get_current_pcie_lane_number(
+						   struct pp_hwmgr *hwmgr)
+{
+	uint32_t link_width;
+
+	link_width = PHM_READ_INDIRECT_FIELD(hwmgr->device,
+							CGS_IND_REG__PCIE,
+						  PCIE_LC_LINK_WIDTH_CNTL,
+							LC_LINK_WIDTH_RD);
+
+	PP_ASSERT_WITH_CODE((7 >= link_width),
+			"Invalid PCIe lane width!", return 0);
+
+	return decode_pcie_lane_width(link_width);
+}
+
+static int tonga_dpm_patch_boot_state(struct pp_hwmgr *hwmgr,
+					struct pp_hw_power_state *hw_ps)
+{
+	struct tonga_hwmgr *data = (struct tonga_hwmgr *)(hwmgr->backend);
+	struct tonga_power_state *ps = (struct tonga_power_state *)hw_ps;
+	ATOM_FIRMWARE_INFO_V2_2 *fw_info;
+	uint16_t size;
+	uint8_t frev, crev;
+	int index = GetIndexIntoMasterTable(DATA, FirmwareInfo);
+
+	/* First retrieve the Boot clocks and VDDC from the firmware info table.
+	 * We assume here that fw_info is unchanged if this call fails.
+	 */
+	fw_info = (ATOM_FIRMWARE_INFO_V2_2 *)cgs_atom_get_data_table(
+			hwmgr->device, index,
+			&size, &frev, &crev);
+	if (!fw_info)
+		/* During a test, there is no firmware info table. */
+		return 0;
+
+	/* Patch the state. */
+	data->vbios_boot_state.sclk_bootup_value  = le32_to_cpu(fw_info->ulDefaultEngineClock);
+	data->vbios_boot_state.mclk_bootup_value  = le32_to_cpu(fw_info->ulDefaultMemoryClock);
+	data->vbios_boot_state.mvdd_bootup_value  = le16_to_cpu(fw_info->usBootUpMVDDCVoltage);
+	data->vbios_boot_state.vddc_bootup_value  = le16_to_cpu(fw_info->usBootUpVDDCVoltage);
+	data->vbios_boot_state.vddci_bootup_value = le16_to_cpu(fw_info->usBootUpVDDCIVoltage);
+	data->vbios_boot_state.pcie_gen_bootup_value = tonga_get_current_pcie_speed(hwmgr);
+	data->vbios_boot_state.pcie_lane_bootup_value =
+			(uint16_t)tonga_get_current_pcie_lane_number(hwmgr);
+
+	/* set boot power state */
+	ps->performance_levels[0].memory_clock = data->vbios_boot_state.mclk_bootup_value;
+	ps->performance_levels[0].engine_clock = data->vbios_boot_state.sclk_bootup_value;
+	ps->performance_levels[0].pcie_gen = data->vbios_boot_state.pcie_gen_bootup_value;
+	ps->performance_levels[0].pcie_lane = data->vbios_boot_state.pcie_lane_bootup_value;
+
+	return 0;
+}
+
+static int tonga_get_pp_table_entry_callback_func(struct pp_hwmgr *hwmgr,
+		void *state, struct pp_power_state *power_state,
+		void *pp_table, uint32_t classification_flag)
+{
+	struct tonga_hwmgr *data = (struct tonga_hwmgr *)(hwmgr->backend);
+
+	struct tonga_power_state  *tonga_ps =
+			(struct tonga_power_state *)(&(power_state->hardware));
+
+	struct tonga_performance_level *performance_level;
+
+	ATOM_Tonga_State *state_entry = (ATOM_Tonga_State *)state;
+
+	ATOM_Tonga_POWERPLAYTABLE *powerplay_table =
+			(ATOM_Tonga_POWERPLAYTABLE *)pp_table;
+
+	ATOM_Tonga_SCLK_Dependency_Table *sclk_dep_table =
+			(ATOM_Tonga_SCLK_Dependency_Table *)
+			(((unsigned long)powerplay_table) +
+			le16_to_cpu(powerplay_table->usSclkDependencyTableOffset));
+
+	ATOM_Tonga_MCLK_Dependency_Table *mclk_dep_table =
+			(ATOM_Tonga_MCLK_Dependency_Table *)
+			(((unsigned long)powerplay_table) +
+			le16_to_cpu(powerplay_table->usMclkDependencyTableOffset));
+
+	/* The following fields are not initialized here: id orderedList allStatesList */
+	power_state->classification.ui_label =
+			(le16_to_cpu(state_entry->usClassification) &
+			ATOM_PPLIB_CLASSIFICATION_UI_MASK) >>
+			ATOM_PPLIB_CLASSIFICATION_UI_SHIFT;
+	power_state->classification.flags = classification_flag;
+	/* NOTE: There is a classification2 flag in BIOS that is not being used right now */
+
+	power_state->classification.temporary_state = false;
+	power_state->classification.to_be_deleted = false;
+
+	power_state->validation.disallowOnDC =
+			(0 != (le32_to_cpu(state_entry->ulCapsAndSettings) & ATOM_Tonga_DISALLOW_ON_DC));
+
+	power_state->pcie.lanes = 0;
+
+	power_state->display.disableFrameModulation = false;
+	power_state->display.limitRefreshrate = false;
+	power_state->display.enableVariBright =
+			(0 != (le32_to_cpu(state_entry->ulCapsAndSettings) & ATOM_Tonga_ENABLE_VARIBRIGHT));
+
+	power_state->validation.supportedPowerLevels = 0;
+	power_state->uvd_clocks.VCLK = 0;
+	power_state->uvd_clocks.DCLK = 0;
+	power_state->temperatures.min = 0;
+	power_state->temperatures.max = 0;
+
+	performance_level = &(tonga_ps->performance_levels
+			[tonga_ps->performance_level_count++]);
+
+	PP_ASSERT_WITH_CODE(
+			(tonga_ps->performance_level_count < SMU72_MAX_LEVELS_GRAPHICS),
+			"Performance levels exceeds SMC limit!",
+			return -1);
+
+	PP_ASSERT_WITH_CODE(
+			(tonga_ps->performance_level_count <=
+					hwmgr->platform_descriptor.hardwareActivityPerformanceLevels),
+			"Performance levels exceeds Driver limit!",
+			return -1);
+
+	/* Performance levels are arranged from low to high. */
+	performance_level->memory_clock =
+				le32_to_cpu(mclk_dep_table->entries[state_entry->ucMemoryClockIndexLow].ulMclk);
+
+	performance_level->engine_clock =
+				le32_to_cpu(sclk_dep_table->entries[state_entry->ucEngineClockIndexLow].ulSclk);
+
+	performance_level->pcie_gen = get_pcie_gen_support(
+							data->pcie_gen_cap,
+					     state_entry->ucPCIEGenLow);
+
+	performance_level->pcie_lane = get_pcie_lane_support(
+						    data->pcie_lane_cap,
+					   state_entry->ucPCIELaneHigh);
+
+	performance_level =
+			&(tonga_ps->performance_levels[tonga_ps->performance_level_count++]);
+
+	performance_level->memory_clock =
+				le32_to_cpu(mclk_dep_table->entries[state_entry->ucMemoryClockIndexHigh].ulMclk);
+
+	performance_level->engine_clock =
+				le32_to_cpu(sclk_dep_table->entries[state_entry->ucEngineClockIndexHigh].ulSclk);
+
+	performance_level->pcie_gen = get_pcie_gen_support(
+							data->pcie_gen_cap,
+					    state_entry->ucPCIEGenHigh);
+
+	performance_level->pcie_lane = get_pcie_lane_support(
+						    data->pcie_lane_cap,
+					   state_entry->ucPCIELaneHigh);
+
+	return 0;
+}
+
+static int tonga_get_pp_table_entry(struct pp_hwmgr *hwmgr,
+		    unsigned long entry_index, struct pp_power_state *ps)
+{
+	int result;
+	struct tonga_power_state *tonga_ps;
+	struct tonga_hwmgr *data = (struct tonga_hwmgr *)(hwmgr->backend);
+
+	struct phm_ppt_v1_information *table_info =
+			(struct phm_ppt_v1_information *)(hwmgr->pptable);
+
+	struct phm_ppt_v1_clock_voltage_dependency_table *dep_mclk_table =
+					   table_info->vdd_dep_on_mclk;
+
+	ps->hardware.magic = PhwTonga_Magic;
+
+	tonga_ps = cast_phw_tonga_power_state(&(ps->hardware));
+
+	result = tonga_get_powerplay_table_entry(hwmgr, entry_index, ps,
+			tonga_get_pp_table_entry_callback_func);
+
+	/* This is the earliest time we have all the dependency table and the VBIOS boot state
+	 * as PP_Tables_GetPowerPlayTableEntry retrieves the VBIOS boot state
+	 * if there is only one VDDCI/MCLK level, check if it's the same as VBIOS boot state
+	 */
+	if (dep_mclk_table != NULL && dep_mclk_table->count == 1) {
+		if (dep_mclk_table->entries[0].clk !=
+				data->vbios_boot_state.mclk_bootup_value)
+			printk(KERN_ERR "Single MCLK entry VDDCI/MCLK dependency table "
+					"does not match VBIOS boot MCLK level");
+		if (dep_mclk_table->entries[0].vddci !=
+				data->vbios_boot_state.vddci_bootup_value)
+			printk(KERN_ERR "Single VDDCI entry VDDCI/MCLK dependency table "
+					"does not match VBIOS boot VDDCI level");
+	}
+
+	/* set DC compatible flag if this state supports DC */
+	if (!ps->validation.disallowOnDC)
+		tonga_ps->dc_compatible = true;
+
+	if (ps->classification.flags & PP_StateClassificationFlag_ACPI)
+		data->acpi_pcie_gen = tonga_ps->performance_levels[0].pcie_gen;
+	else if (ps->classification.flags & PP_StateClassificationFlag_Boot) {
+		if (data->bacos.best_match == 0xffff) {
+			/* For V.I. use boot state as base BACO state */
+			data->bacos.best_match = PP_StateClassificationFlag_Boot;
+			data->bacos.performance_level = tonga_ps->performance_levels[0];
+		}
+	}
+
+	tonga_ps->uvd_clocks.VCLK = ps->uvd_clocks.VCLK;
+	tonga_ps->uvd_clocks.DCLK = ps->uvd_clocks.DCLK;
+
+	if (!result) {
+		uint32_t i;
+
+		switch (ps->classification.ui_label) {
+		case PP_StateUILabel_Performance:
+			data->use_pcie_performance_levels = true;
+
+			for (i = 0; i < tonga_ps->performance_level_count; i++) {
+				if (data->pcie_gen_performance.max <
+						tonga_ps->performance_levels[i].pcie_gen)
+					data->pcie_gen_performance.max =
+							tonga_ps->performance_levels[i].pcie_gen;
+
+				if (data->pcie_gen_performance.min >
+						tonga_ps->performance_levels[i].pcie_gen)
+					data->pcie_gen_performance.min =
+							tonga_ps->performance_levels[i].pcie_gen;
+
+				if (data->pcie_lane_performance.max <
+						tonga_ps->performance_levels[i].pcie_lane)
+					data->pcie_lane_performance.max =
+							tonga_ps->performance_levels[i].pcie_lane;
+
+				if (data->pcie_lane_performance.min >
+						tonga_ps->performance_levels[i].pcie_lane)
+					data->pcie_lane_performance.min =
+							tonga_ps->performance_levels[i].pcie_lane;
+			}
+			break;
+		case PP_StateUILabel_Battery:
+			data->use_pcie_power_saving_levels = true;
+
+			for (i = 0; i < tonga_ps->performance_level_count; i++) {
+				if (data->pcie_gen_power_saving.max <
+						tonga_ps->performance_levels[i].pcie_gen)
+					data->pcie_gen_power_saving.max =
+							tonga_ps->performance_levels[i].pcie_gen;
+
+				if (data->pcie_gen_power_saving.min >
+						tonga_ps->performance_levels[i].pcie_gen)
+					data->pcie_gen_power_saving.min =
+							tonga_ps->performance_levels[i].pcie_gen;
+
+				if (data->pcie_lane_power_saving.max <
+						tonga_ps->performance_levels[i].pcie_lane)
+					data->pcie_lane_power_saving.max =
+							tonga_ps->performance_levels[i].pcie_lane;
+
+				if (data->pcie_lane_power_saving.min >
+						tonga_ps->performance_levels[i].pcie_lane)
+					data->pcie_lane_power_saving.min =
+							tonga_ps->performance_levels[i].pcie_lane;
+			}
+			break;
+		default:
+			break;
+		}
+	}
+	return 0;
+}
+
+static void
+tonga_print_current_perforce_level(struct pp_hwmgr *hwmgr, struct seq_file *m)
+{
+	uint32_t sclk, mclk, activity_percent;
+	uint32_t offset;
+	struct tonga_hwmgr *data = (struct tonga_hwmgr *)(hwmgr->backend);
+
+	smum_send_msg_to_smc(hwmgr->smumgr, (PPSMC_Msg)(PPSMC_MSG_API_GetSclkFrequency));
+
+	sclk = cgs_read_register(hwmgr->device, mmSMC_MSG_ARG_0);
+
+	smum_send_msg_to_smc(hwmgr->smumgr, (PPSMC_Msg)(PPSMC_MSG_API_GetMclkFrequency));
+
+	mclk = cgs_read_register(hwmgr->device, mmSMC_MSG_ARG_0);
+	seq_printf(m, "\n [  mclk  ]: %u MHz\n\n [  sclk  ]: %u MHz\n", mclk/100, sclk/100);
+
+
+	offset = data->soft_regs_start + offsetof(SMU72_SoftRegisters, AverageGraphicsActivity);
+	activity_percent = cgs_read_ind_register(hwmgr->device, CGS_IND_REG__SMC, offset);
+	activity_percent += 0x80;
+	activity_percent >>= 8;
+
+	seq_printf(m, "\n [GPU load]: %u%%\n\n", activity_percent > 100 ? 100 : activity_percent);
+
+}
+
+static int tonga_find_dpm_states_clocks_in_dpm_table(struct pp_hwmgr *hwmgr, const void *input)
+{
+	const struct phm_set_power_state_input *states = (const struct phm_set_power_state_input *)input;
+	const struct tonga_power_state *tonga_ps = cast_const_phw_tonga_power_state(states->pnew_state);
+	struct tonga_hwmgr *data = (struct tonga_hwmgr *)(hwmgr->backend);
+	struct tonga_single_dpm_table *psclk_table = &(data->dpm_table.sclk_table);
+	uint32_t sclk = tonga_ps->performance_levels[tonga_ps->performance_level_count-1].engine_clock;
+	struct tonga_single_dpm_table *pmclk_table = &(data->dpm_table.mclk_table);
+	uint32_t mclk = tonga_ps->performance_levels[tonga_ps->performance_level_count-1].memory_clock;
+	struct PP_Clocks min_clocks = {0};
+	uint32_t i;
+	struct cgs_display_info info = {0};
+
+	data->need_update_smu7_dpm_table = 0;
+
+	for (i = 0; i < psclk_table->count; i++) {
+		if (sclk == psclk_table->dpm_levels[i].value)
+			break;
+	}
+
+	if (i >= psclk_table->count)
+		data->need_update_smu7_dpm_table |= DPMTABLE_OD_UPDATE_SCLK;
+	else {
+	/* TODO: Check SCLK in DAL's minimum clocks in case DeepSleep divider update is required.*/
+		if(data->display_timing.min_clock_insr != min_clocks.engineClockInSR)
+			data->need_update_smu7_dpm_table |= DPMTABLE_UPDATE_SCLK;
+	}
+
+	for (i=0; i < pmclk_table->count; i++) {
+		if (mclk == pmclk_table->dpm_levels[i].value)
+			break;
+	}
+
+	if (i >= pmclk_table->count)
+		data->need_update_smu7_dpm_table |= DPMTABLE_OD_UPDATE_MCLK;
+
+	cgs_get_active_displays_info(hwmgr->device, &info);
+
+	if (data->display_timing.num_existing_displays != info.display_count)
+		data->need_update_smu7_dpm_table |= DPMTABLE_UPDATE_MCLK;
+
+	return 0;
+}
+
+static uint16_t tonga_get_maximum_link_speed(struct pp_hwmgr *hwmgr, const struct tonga_power_state *hw_ps)
+{
+	uint32_t i;
+	uint32_t sclk, max_sclk = 0;
+	struct tonga_hwmgr *data = (struct tonga_hwmgr *)(hwmgr->backend);
+	struct tonga_dpm_table *pdpm_table = &data->dpm_table;
+
+	for (i = 0; i < hw_ps->performance_level_count; i++) {
+		sclk = hw_ps->performance_levels[i].engine_clock;
+		if (max_sclk < sclk)
+			max_sclk = sclk;
+	}
+
+	for (i = 0; i < pdpm_table->sclk_table.count; i++) {
+		if (pdpm_table->sclk_table.dpm_levels[i].value == max_sclk)
+			return (uint16_t) ((i >= pdpm_table->pcie_speed_table.count) ?
+					pdpm_table->pcie_speed_table.dpm_levels[pdpm_table->pcie_speed_table.count-1].value :
+					pdpm_table->pcie_speed_table.dpm_levels[i].value);
+	}
+
+	return 0;
+}
+
+static int tonga_request_link_speed_change_before_state_change(struct pp_hwmgr *hwmgr, const void *input)
+{
+	const struct phm_set_power_state_input *states = (const struct phm_set_power_state_input *)input;
+	struct tonga_hwmgr *data = (struct tonga_hwmgr *)(hwmgr->backend);
+	const struct tonga_power_state *tonga_nps = cast_const_phw_tonga_power_state(states->pnew_state);
+	const struct tonga_power_state *tonga_cps = cast_const_phw_tonga_power_state(states->pcurrent_state);
+
+	uint16_t target_link_speed = tonga_get_maximum_link_speed(hwmgr, tonga_nps);
+	uint16_t current_link_speed;
+
+	if (data->force_pcie_gen == PP_PCIEGenInvalid)
+		current_link_speed = tonga_get_maximum_link_speed(hwmgr, tonga_cps);
+	else
+		current_link_speed = data->force_pcie_gen;
+
+	data->force_pcie_gen = PP_PCIEGenInvalid;
+	data->pspp_notify_required = false;
+	if (target_link_speed > current_link_speed) {
+		switch(target_link_speed) {
+		case PP_PCIEGen3:
+			if (0 == acpi_pcie_perf_request(hwmgr->device, PCIE_PERF_REQ_GEN3, false))
+				break;
+			data->force_pcie_gen = PP_PCIEGen2;
+			if (current_link_speed == PP_PCIEGen2)
+				break;
+		case PP_PCIEGen2:
+			if (0 == acpi_pcie_perf_request(hwmgr->device, PCIE_PERF_REQ_GEN2, false))
+				break;
+		default:
+			data->force_pcie_gen = tonga_get_current_pcie_speed(hwmgr);
+			break;
+		}
+	} else {
+		if (target_link_speed < current_link_speed)
+			data->pspp_notify_required = true;
+	}
+
+	return 0;
+}
+
+static int tonga_freeze_sclk_mclk_dpm(struct pp_hwmgr *hwmgr)
+{
+	struct tonga_hwmgr *data = (struct tonga_hwmgr *)(hwmgr->backend);
+
+	if (0 == data->need_update_smu7_dpm_table)
+		return 0;
+
+	if ((0 == data->sclk_dpm_key_disabled) &&
+		(data->need_update_smu7_dpm_table &
+		(DPMTABLE_OD_UPDATE_SCLK + DPMTABLE_UPDATE_SCLK))) {
+		PP_ASSERT_WITH_CODE(
+			true == tonga_is_dpm_running(hwmgr),
+			"Trying to freeze SCLK DPM when DPM is disabled",
+			);
+		PP_ASSERT_WITH_CODE(
+			0 == smum_send_msg_to_smc(hwmgr->smumgr,
+					  PPSMC_MSG_SCLKDPM_FreezeLevel),
+			"Failed to freeze SCLK DPM during FreezeSclkMclkDPM Function!",
+			return -1);
+	}
+
+	if ((0 == data->mclk_dpm_key_disabled) &&
+		(data->need_update_smu7_dpm_table &
+		 DPMTABLE_OD_UPDATE_MCLK)) {
+		PP_ASSERT_WITH_CODE(true == tonga_is_dpm_running(hwmgr),
+			"Trying to freeze MCLK DPM when DPM is disabled",
+			);
+		PP_ASSERT_WITH_CODE(
+			0 == smum_send_msg_to_smc(hwmgr->smumgr,
+							PPSMC_MSG_MCLKDPM_FreezeLevel),
+			"Failed to freeze MCLK DPM during FreezeSclkMclkDPM Function!",
+			return -1);
+	}
+
+	return 0;
+}
+
+static int tonga_populate_and_upload_sclk_mclk_dpm_levels(struct pp_hwmgr *hwmgr, const void *input)
+{
+	int result = 0;
+
+	const struct phm_set_power_state_input *states = (const struct phm_set_power_state_input *)input;
+	const struct tonga_power_state *tonga_ps = cast_const_phw_tonga_power_state(states->pnew_state);
+	struct tonga_hwmgr *data = (struct tonga_hwmgr *)(hwmgr->backend);
+	uint32_t sclk = tonga_ps->performance_levels[tonga_ps->performance_level_count-1].engine_clock;
+	uint32_t mclk = tonga_ps->performance_levels[tonga_ps->performance_level_count-1].memory_clock;
+	struct tonga_dpm_table *pdpm_table = &data->dpm_table;
+
+	struct tonga_dpm_table *pgolden_dpm_table = &data->golden_dpm_table;
+	uint32_t dpm_count, clock_percent;
+	uint32_t i;
+
+	if (0 == data->need_update_smu7_dpm_table)
+		return 0;
+
+	if (data->need_update_smu7_dpm_table & DPMTABLE_OD_UPDATE_SCLK) {
+		pdpm_table->sclk_table.dpm_levels[pdpm_table->sclk_table.count-1].value = sclk;
+
+		if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_OD6PlusinACSupport) ||
+		    phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_OD6PlusinDCSupport)) {
+		/* Need to do calculation based on the golden DPM table
+		 * as the Heatmap GPU Clock axis is also based on the default values
+		 */
+			PP_ASSERT_WITH_CODE(
+				(pgolden_dpm_table->sclk_table.dpm_levels[pgolden_dpm_table->sclk_table.count-1].value != 0),
+				"Divide by 0!",
+				return -1);
+			dpm_count = pdpm_table->sclk_table.count < 2 ? 0 : pdpm_table->sclk_table.count-2;
+			for (i = dpm_count; i > 1; i--) {
+				if (sclk > pgolden_dpm_table->sclk_table.dpm_levels[pgolden_dpm_table->sclk_table.count-1].value) {
+					clock_percent = ((sclk - pgolden_dpm_table->sclk_table.dpm_levels[pgolden_dpm_table->sclk_table.count-1].value)*100) /
+							pgolden_dpm_table->sclk_table.dpm_levels[pgolden_dpm_table->sclk_table.count-1].value;
+
+					pdpm_table->sclk_table.dpm_levels[i].value =
+							pgolden_dpm_table->sclk_table.dpm_levels[i].value +
+							(pgolden_dpm_table->sclk_table.dpm_levels[i].value * clock_percent)/100;
+
+				} else if (pgolden_dpm_table->sclk_table.dpm_levels[pdpm_table->sclk_table.count-1].value > sclk) {
+					clock_percent = ((pgolden_dpm_table->sclk_table.dpm_levels[pgolden_dpm_table->sclk_table.count-1].value - sclk)*100) /
+								pgolden_dpm_table->sclk_table.dpm_levels[pgolden_dpm_table->sclk_table.count-1].value;
+
+					pdpm_table->sclk_table.dpm_levels[i].value =
+							pgolden_dpm_table->sclk_table.dpm_levels[i].value -
+							(pgolden_dpm_table->sclk_table.dpm_levels[i].value * clock_percent)/100;
+				} else
+					pdpm_table->sclk_table.dpm_levels[i].value =
+							pgolden_dpm_table->sclk_table.dpm_levels[i].value;
+			}
+		}
+	}
+
+	if (data->need_update_smu7_dpm_table & DPMTABLE_OD_UPDATE_MCLK) {
+		pdpm_table->mclk_table.dpm_levels[pdpm_table->mclk_table.count-1].value = mclk;
+
+		if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_OD6PlusinACSupport) ||
+			phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_OD6PlusinDCSupport)) {
+
+			PP_ASSERT_WITH_CODE(
+					(pgolden_dpm_table->mclk_table.dpm_levels[pgolden_dpm_table->mclk_table.count-1].value != 0),
+					"Divide by 0!",
+					return -1);
+			dpm_count = pdpm_table->mclk_table.count < 2? 0 : pdpm_table->mclk_table.count-2;
+			for (i = dpm_count; i > 1; i--) {
+				if (mclk > pgolden_dpm_table->mclk_table.dpm_levels[pgolden_dpm_table->mclk_table.count-1].value) {
+						clock_percent = ((mclk - pgolden_dpm_table->mclk_table.dpm_levels[pgolden_dpm_table->mclk_table.count-1].value)*100) /
+								    pgolden_dpm_table->mclk_table.dpm_levels[pgolden_dpm_table->mclk_table.count-1].value;
+
+						pdpm_table->mclk_table.dpm_levels[i].value =
+										pgolden_dpm_table->mclk_table.dpm_levels[i].value +
+										(pgolden_dpm_table->mclk_table.dpm_levels[i].value * clock_percent)/100;
+
+				} else if (pgolden_dpm_table->mclk_table.dpm_levels[pdpm_table->mclk_table.count-1].value > mclk) {
+						clock_percent = ((pgolden_dpm_table->mclk_table.dpm_levels[pgolden_dpm_table->mclk_table.count-1].value - mclk)*100) /
+								    pgolden_dpm_table->mclk_table.dpm_levels[pgolden_dpm_table->mclk_table.count-1].value;
+
+						pdpm_table->mclk_table.dpm_levels[i].value =
+									pgolden_dpm_table->mclk_table.dpm_levels[i].value -
+									(pgolden_dpm_table->mclk_table.dpm_levels[i].value * clock_percent)/100;
+				} else
+					pdpm_table->mclk_table.dpm_levels[i].value = pgolden_dpm_table->mclk_table.dpm_levels[i].value;
+			}
+		}
+	}
+
+	if (data->need_update_smu7_dpm_table & (DPMTABLE_OD_UPDATE_SCLK + DPMTABLE_UPDATE_SCLK)) {
+		result = tonga_populate_all_memory_levels(hwmgr);
+		PP_ASSERT_WITH_CODE((0 == result),
+			"Failed to populate SCLK during PopulateNewDPMClocksStates Function!",
+			return result);
+	}
+
+	if (data->need_update_smu7_dpm_table & (DPMTABLE_OD_UPDATE_MCLK + DPMTABLE_UPDATE_MCLK)) {
+		/*populate MCLK dpm table to SMU7 */
+		result = tonga_populate_all_memory_levels(hwmgr);
+		PP_ASSERT_WITH_CODE((0 == result),
+				"Failed to populate MCLK during PopulateNewDPMClocksStates Function!",
+				return result);
+	}
+
+	return result;
+}
+
+static	int tonga_trim_single_dpm_states(struct pp_hwmgr *hwmgr,
+			  struct tonga_single_dpm_table * pdpm_table,
+			     uint32_t low_limit, uint32_t high_limit)
+{
+	uint32_t i;
+
+	for (i = 0; i < pdpm_table->count; i++) {
+		if ((pdpm_table->dpm_levels[i].value < low_limit) ||
+		    (pdpm_table->dpm_levels[i].value > high_limit))
+			pdpm_table->dpm_levels[i].enabled = false;
+		else
+			pdpm_table->dpm_levels[i].enabled = true;
+	}
+	return 0;
+}
+
+static int tonga_trim_dpm_states(struct pp_hwmgr *hwmgr, const struct tonga_power_state *hw_state)
+{
+	int result = 0;
+	struct tonga_hwmgr *data = (struct tonga_hwmgr *)(hwmgr->backend);
+	uint32_t high_limit_count;
+
+	PP_ASSERT_WITH_CODE((hw_state->performance_level_count >= 1),
+				"power state did not have any performance level",
+				 return -1);
+
+	high_limit_count = (1 == hw_state->performance_level_count) ? 0: 1;
+
+	tonga_trim_single_dpm_states(hwmgr,
+					&(data->dpm_table.sclk_table),
+					hw_state->performance_levels[0].engine_clock,
+					hw_state->performance_levels[high_limit_count].engine_clock);
+
+	tonga_trim_single_dpm_states(hwmgr,
+						&(data->dpm_table.mclk_table),
+						hw_state->performance_levels[0].memory_clock,
+						hw_state->performance_levels[high_limit_count].memory_clock);
+
+	return result;
+}
+
+static int tonga_generate_dpm_level_enable_mask(struct pp_hwmgr *hwmgr, const void *input)
+{
+	int result;
+	const struct phm_set_power_state_input *states = (const struct phm_set_power_state_input *)input;
+	struct tonga_hwmgr *data = (struct tonga_hwmgr *)(hwmgr->backend);
+	const struct tonga_power_state *tonga_ps = cast_const_phw_tonga_power_state(states->pnew_state);
+
+	result = tonga_trim_dpm_states(hwmgr, tonga_ps);
+	if (0 != result)
+		return result;
+
+	data->dpm_level_enable_mask.sclk_dpm_enable_mask = tonga_get_dpm_level_enable_mask_value(&data->dpm_table.sclk_table);
+	data->dpm_level_enable_mask.mclk_dpm_enable_mask = tonga_get_dpm_level_enable_mask_value(&data->dpm_table.mclk_table);
+	data->last_mclk_dpm_enable_mask = data->dpm_level_enable_mask.mclk_dpm_enable_mask;
+	if (data->uvd_enabled)
+		data->dpm_level_enable_mask.mclk_dpm_enable_mask &= 0xFFFFFFFE;
+
+	data->dpm_level_enable_mask.pcie_dpm_enable_mask = tonga_get_dpm_level_enable_mask_value(&data->dpm_table.pcie_speed_table);
+
+	return 0;
+}
+
+int tonga_enable_disable_vce_dpm(struct pp_hwmgr *hwmgr, bool enable)
+{
+	return smum_send_msg_to_smc(hwmgr->smumgr, enable ?
+				  (PPSMC_Msg)PPSMC_MSG_VCEDPM_Enable :
+				  (PPSMC_Msg)PPSMC_MSG_VCEDPM_Disable);
+}
+
+int tonga_enable_disable_uvd_dpm(struct pp_hwmgr *hwmgr, bool enable)
+{
+	return smum_send_msg_to_smc(hwmgr->smumgr, enable ?
+				  (PPSMC_Msg)PPSMC_MSG_UVDDPM_Enable :
+				  (PPSMC_Msg)PPSMC_MSG_UVDDPM_Disable);
+}
+
+int tonga_update_uvd_dpm(struct pp_hwmgr *hwmgr, bool bgate)
+{
+	struct tonga_hwmgr *data = (struct tonga_hwmgr *)(hwmgr->backend);
+	uint32_t mm_boot_level_offset, mm_boot_level_value;
+	struct phm_ppt_v1_information *ptable_information = (struct phm_ppt_v1_information *)(hwmgr->pptable);
+
+	if (!bgate) {
+		data->smc_state_table.UvdBootLevel = (uint8_t) (ptable_information->mm_dep_table->count - 1);
+		mm_boot_level_offset = data->dpm_table_start + offsetof(SMU72_Discrete_DpmTable, UvdBootLevel);
+		mm_boot_level_offset /= 4;
+		mm_boot_level_offset *= 4;
+		mm_boot_level_value = cgs_read_ind_register(hwmgr->device, CGS_IND_REG__SMC, mm_boot_level_offset);
+		mm_boot_level_value &= 0x00FFFFFF;
+		mm_boot_level_value |= data->smc_state_table.UvdBootLevel << 24;
+		cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC, mm_boot_level_offset, mm_boot_level_value);
+
+		if (!phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_UVDDPM) ||
+		    phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_StablePState))
+			smum_send_msg_to_smc_with_parameter(hwmgr->smumgr,
+						PPSMC_MSG_UVDDPM_SetEnabledMask,
+						(uint32_t)(1 << data->smc_state_table.UvdBootLevel));
+	}
+
+	return tonga_enable_disable_uvd_dpm(hwmgr, !bgate);
+}
+
+int tonga_update_vce_dpm(struct pp_hwmgr *hwmgr, const void *input)
+{
+	const struct phm_set_power_state_input *states = (const struct phm_set_power_state_input *)input;
+	struct tonga_hwmgr *data = (struct tonga_hwmgr *)(hwmgr->backend);
+	const struct tonga_power_state *tonga_nps = cast_const_phw_tonga_power_state(states->pnew_state);
+	const struct tonga_power_state *tonga_cps = cast_const_phw_tonga_power_state(states->pcurrent_state);
+
+	uint32_t mm_boot_level_offset, mm_boot_level_value;
+	struct phm_ppt_v1_information *pptable_info = (struct phm_ppt_v1_information *)(hwmgr->pptable);
+
+	if (tonga_nps->vce_clocks.EVCLK > 0 && (tonga_cps == NULL || tonga_cps->vce_clocks.EVCLK == 0)) {
+		data->smc_state_table.VceBootLevel = (uint8_t) (pptable_info->mm_dep_table->count - 1);
+
+		mm_boot_level_offset = data->dpm_table_start + offsetof(SMU72_Discrete_DpmTable, VceBootLevel);
+		mm_boot_level_offset /= 4;
+		mm_boot_level_offset *= 4;
+		mm_boot_level_value = cgs_read_ind_register(hwmgr->device, CGS_IND_REG__SMC, mm_boot_level_offset);
+		mm_boot_level_value &= 0xFF00FFFF;
+		mm_boot_level_value |= data->smc_state_table.VceBootLevel << 16;
+		cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC, mm_boot_level_offset, mm_boot_level_value);
+
+		if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_StablePState))
+			smum_send_msg_to_smc_with_parameter(hwmgr->smumgr,
+					PPSMC_MSG_VCEDPM_SetEnabledMask,
+				(uint32_t)(1 << data->smc_state_table.VceBootLevel));
+
+		tonga_enable_disable_vce_dpm(hwmgr, true);
+	} else if (tonga_nps->vce_clocks.EVCLK == 0 && tonga_cps != NULL && tonga_cps->vce_clocks.EVCLK > 0)
+		tonga_enable_disable_vce_dpm(hwmgr, false);
+
+	return 0;
+}
+
+static int tonga_update_and_upload_mc_reg_table(struct pp_hwmgr *hwmgr)
+{
+	struct tonga_hwmgr *data = (struct tonga_hwmgr *)(hwmgr->backend);
+
+	uint32_t address;
+	int32_t result;
+
+	if (0 == (data->need_update_smu7_dpm_table & DPMTABLE_OD_UPDATE_MCLK))
+		return 0;
+
+
+	memset(&data->mc_reg_table, 0, sizeof(SMU72_Discrete_MCRegisters));
+
+	result = tonga_convert_mc_reg_table_to_smc(hwmgr, &(data->mc_reg_table));
+
+	if(result != 0)
+		return result;
+
+
+	address = data->mc_reg_table_start + (uint32_t)offsetof(SMU72_Discrete_MCRegisters, data[0]);
+
+	return  tonga_copy_bytes_to_smc(hwmgr->smumgr, address,
+				 (uint8_t *)&data->mc_reg_table.data[0],
+				sizeof(SMU72_Discrete_MCRegisterSet) * data->dpm_table.mclk_table.count,
+				data->sram_end);
+}
+
+static int tonga_program_memory_timing_parameters_conditionally(struct pp_hwmgr *hwmgr)
+{
+	struct tonga_hwmgr *data = (struct tonga_hwmgr *)(hwmgr->backend);
+
+	if (data->need_update_smu7_dpm_table &
+		(DPMTABLE_OD_UPDATE_SCLK + DPMTABLE_OD_UPDATE_MCLK))
+		return tonga_program_memory_timing_parameters(hwmgr);
+
+	return 0;
+}
+
+static int tonga_unfreeze_sclk_mclk_dpm(struct pp_hwmgr *hwmgr)
+{
+	struct tonga_hwmgr *data = (struct tonga_hwmgr *)(hwmgr->backend);
+
+	if (0 == data->need_update_smu7_dpm_table)
+		return 0;
+
+	if ((0 == data->sclk_dpm_key_disabled) &&
+		(data->need_update_smu7_dpm_table &
+		(DPMTABLE_OD_UPDATE_SCLK + DPMTABLE_UPDATE_SCLK))) {
+
+		PP_ASSERT_WITH_CODE(true == tonga_is_dpm_running(hwmgr),
+			"Trying to Unfreeze SCLK DPM when DPM is disabled",
+			);
+		PP_ASSERT_WITH_CODE(
+			 0 == smum_send_msg_to_smc(hwmgr->smumgr,
+					 PPSMC_MSG_SCLKDPM_UnfreezeLevel),
+			"Failed to unfreeze SCLK DPM during UnFreezeSclkMclkDPM Function!",
+			return -1);
+	}
+
+	if ((0 == data->mclk_dpm_key_disabled) &&
+		(data->need_update_smu7_dpm_table & DPMTABLE_OD_UPDATE_MCLK)) {
+
+		PP_ASSERT_WITH_CODE(
+				true == tonga_is_dpm_running(hwmgr),
+				"Trying to Unfreeze MCLK DPM when DPM is disabled",
+				);
+		PP_ASSERT_WITH_CODE(
+			 0 == smum_send_msg_to_smc(hwmgr->smumgr,
+					 PPSMC_MSG_SCLKDPM_UnfreezeLevel),
+		    "Failed to unfreeze MCLK DPM during UnFreezeSclkMclkDPM Function!",
+		    return -1);
+	}
+
+	data->need_update_smu7_dpm_table = 0;
+
+	return 0;
+}
+
+static int tonga_notify_link_speed_change_after_state_change(struct pp_hwmgr *hwmgr, const void *input)
+{
+	const struct phm_set_power_state_input *states = (const struct phm_set_power_state_input *)input;
+	struct tonga_hwmgr *data = (struct tonga_hwmgr *)(hwmgr->backend);
+	const struct tonga_power_state *tonga_ps = cast_const_phw_tonga_power_state(states->pnew_state);
+	uint16_t target_link_speed = tonga_get_maximum_link_speed(hwmgr, tonga_ps);
+	uint8_t  request;
+
+	if (data->pspp_notify_required  ||
+	    data->pcie_performance_request) {
+		if (target_link_speed == PP_PCIEGen3)
+			request = PCIE_PERF_REQ_GEN3;
+		else if (target_link_speed == PP_PCIEGen2)
+			request = PCIE_PERF_REQ_GEN2;
+		else
+			request = PCIE_PERF_REQ_GEN1;
+
+		if(request == PCIE_PERF_REQ_GEN1 && tonga_get_current_pcie_speed(hwmgr) > 0) {
+			data->pcie_performance_request = false;
+			return 0;
+		}
+
+		if (0 != acpi_pcie_perf_request(hwmgr->device, request, false)) {
+			if (PP_PCIEGen2 == target_link_speed)
+				printk("PSPP request to switch to Gen2 from Gen3 Failed!");
+			else
+				printk("PSPP request to switch to Gen1 from Gen2 Failed!");
+		}
+	}
+
+	data->pcie_performance_request = false;
+	return 0;
+}
+
+static int tonga_set_power_state_tasks(struct pp_hwmgr *hwmgr, const void *input)
+{
+	int tmp_result, result = 0;
+
+	tmp_result = tonga_find_dpm_states_clocks_in_dpm_table(hwmgr, input);
+	PP_ASSERT_WITH_CODE((0 == tmp_result), "Failed to find DPM states clocks in DPM table!", result = tmp_result);
+
+	if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_PCIEPerformanceRequest)) {
+		tmp_result = tonga_request_link_speed_change_before_state_change(hwmgr, input);
+		PP_ASSERT_WITH_CODE((0 == tmp_result), "Failed to request link speed change before state change!", result = tmp_result);
+	}
+
+	tmp_result = tonga_freeze_sclk_mclk_dpm(hwmgr);
+	PP_ASSERT_WITH_CODE((0 == tmp_result), "Failed to freeze SCLK MCLK DPM!", result = tmp_result);
+
+	tmp_result = tonga_populate_and_upload_sclk_mclk_dpm_levels(hwmgr, input);
+	PP_ASSERT_WITH_CODE((0 == tmp_result), "Failed to populate and upload SCLK MCLK DPM levels!", result = tmp_result);
+
+	tmp_result = tonga_generate_dpm_level_enable_mask(hwmgr, input);
+	PP_ASSERT_WITH_CODE((0 == tmp_result), "Failed to generate DPM level enabled mask!", result = tmp_result);
+
+	tmp_result = tonga_update_vce_dpm(hwmgr, input);
+	PP_ASSERT_WITH_CODE((0 == tmp_result), "Failed to update VCE DPM!", result = tmp_result);
+
+	tmp_result = tonga_update_sclk_threshold(hwmgr);
+	PP_ASSERT_WITH_CODE((0 == tmp_result), "Failed to update SCLK threshold!", result = tmp_result);
+
+	tmp_result = tonga_update_and_upload_mc_reg_table(hwmgr);
+	PP_ASSERT_WITH_CODE((0 == tmp_result), "Failed to upload MC reg table!", result = tmp_result);
+
+	tmp_result = tonga_program_memory_timing_parameters_conditionally(hwmgr);
+	PP_ASSERT_WITH_CODE((0 == tmp_result), "Failed to program memory timing parameters!", result = tmp_result);
+
+	tmp_result = tonga_unfreeze_sclk_mclk_dpm(hwmgr);
+	PP_ASSERT_WITH_CODE((0 == tmp_result), "Failed to unfreeze SCLK MCLK DPM!", result = tmp_result);
+
+	tmp_result = tonga_upload_dpm_level_enable_mask(hwmgr);
+	PP_ASSERT_WITH_CODE((0 == tmp_result), "Failed to upload DPM level enabled mask!", result = tmp_result);
+
+	if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_PCIEPerformanceRequest)) {
+		tmp_result = tonga_notify_link_speed_change_after_state_change(hwmgr, input);
+		PP_ASSERT_WITH_CODE((0 == tmp_result), "Failed to notify link speed change after state change!", result = tmp_result);
+	}
+
+	return result;
+}
+
+/**
+*  Set maximum target operating fan output PWM
+*
+* @param    pHwMgr:  the address of the powerplay hardware manager.
+* @param    usMaxFanPwm:  max operating fan PWM in percents
+* @return   The response that came from the SMC.
+*/
+static int tonga_set_max_fan_pwm_output(struct pp_hwmgr *hwmgr, uint16_t us_max_fan_pwm)
+{
+	hwmgr->thermal_controller.advanceFanControlParameters.usMaxFanPWM = us_max_fan_pwm;
+
+	if (phm_is_hw_access_blocked(hwmgr))
+		return 0;
+
+	return (0 == smum_send_msg_to_smc_with_parameter(hwmgr->smumgr, PPSMC_MSG_SetFanPwmMax, us_max_fan_pwm) ? 0 : -1);
+}
+
+int tonga_notify_smc_display_config_after_ps_adjustment(struct pp_hwmgr *hwmgr)
+{
+	uint32_t num_active_displays = 0;
+	struct cgs_display_info info = {0};
+	info.mode_info = NULL;
+
+	cgs_get_active_displays_info(hwmgr->device, &info);
+
+	num_active_displays = info.display_count;
+
+	if (num_active_displays > 1)  /* to do && (pHwMgr->pPECI->displayConfiguration.bMultiMonitorInSync != TRUE)) */
+		tonga_notify_smc_display_change(hwmgr, false);
+	else
+		tonga_notify_smc_display_change(hwmgr, true);
+
+	return 0;
+}
+
+/**
+* Programs the display gap
+*
+* @param    hwmgr  the address of the powerplay hardware manager.
+* @return   always OK
+*/
+int tonga_program_display_gap(struct pp_hwmgr *hwmgr)
+{
+	struct tonga_hwmgr *data = (struct tonga_hwmgr *)(hwmgr->backend);
+	uint32_t num_active_displays = 0;
+	uint32_t display_gap = cgs_read_ind_register(hwmgr->device, CGS_IND_REG__SMC, ixCG_DISPLAY_GAP_CNTL);
+	uint32_t display_gap2;
+	uint32_t pre_vbi_time_in_us;
+	uint32_t frame_time_in_us;
+	uint32_t ref_clock;
+	uint32_t refresh_rate = 0;
+	struct cgs_display_info info = {0};
+	struct cgs_mode_info mode_info;
+
+	info.mode_info = &mode_info;
+
+	cgs_get_active_displays_info(hwmgr->device, &info);
+	num_active_displays = info.display_count;
+
+	display_gap = PHM_SET_FIELD(display_gap, CG_DISPLAY_GAP_CNTL, DISP_GAP, (num_active_displays > 0)? DISPLAY_GAP_VBLANK_OR_WM : DISPLAY_GAP_IGNORE);
+	cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC, ixCG_DISPLAY_GAP_CNTL, display_gap);
+
+	ref_clock = mode_info.ref_clock;
+	refresh_rate = mode_info.refresh_rate;
+
+	if(0 == refresh_rate)
+		refresh_rate = 60;
+
+	frame_time_in_us = 1000000 / refresh_rate;
+
+	pre_vbi_time_in_us = frame_time_in_us - 200 - mode_info.vblank_time_us;
+	display_gap2 = pre_vbi_time_in_us * (ref_clock / 100);
+
+	cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC, ixCG_DISPLAY_GAP_CNTL2, display_gap2);
+
+	cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC, data->soft_regs_start + offsetof(SMU72_SoftRegisters, PreVBlankGap), 0x64);
+
+	cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC, data->soft_regs_start + offsetof(SMU72_SoftRegisters, VBlankTimeout), (frame_time_in_us - pre_vbi_time_in_us));
+
+	if (num_active_displays == 1)
+		tonga_notify_smc_display_change(hwmgr, true);
+
+	return 0;
+}
+
+int tonga_display_configuration_changed_task(struct pp_hwmgr *hwmgr)
+{
+
+	tonga_program_display_gap(hwmgr);
+
+	/* to do PhwTonga_CacUpdateDisplayConfiguration(pHwMgr); */
+	return 0;
+}
+
+/**
+*  Set maximum target operating fan output RPM
+*
+* @param    pHwMgr:  the address of the powerplay hardware manager.
+* @param    usMaxFanRpm:  max operating fan RPM value.
+* @return   The response that came from the SMC.
+*/
+static int tonga_set_max_fan_rpm_output(struct pp_hwmgr *hwmgr, uint16_t us_max_fan_pwm)
+{
+	hwmgr->thermal_controller.advanceFanControlParameters.usMaxFanRPM = us_max_fan_pwm;
+
+	if (phm_is_hw_access_blocked(hwmgr))
+		return 0;
+
+	return (0 == smum_send_msg_to_smc_with_parameter(hwmgr->smumgr, PPSMC_MSG_SetFanRpmMax, us_max_fan_pwm) ? 0 : -1);
+}
+
+uint32_t tonga_get_xclk(struct pp_hwmgr *hwmgr)
+{
+	uint32_t reference_clock;
+	uint32_t tc;
+	uint32_t divide;
+
+	ATOM_FIRMWARE_INFO *fw_info;
+	uint16_t size;
+	uint8_t frev, crev;
+	int index = GetIndexIntoMasterTable(DATA, FirmwareInfo);
+
+	tc = PHM_READ_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, CG_CLKPIN_CNTL_2, MUX_TCLK_TO_XCLK);
+
+	if (tc)
+		return TCLK;
+
+	fw_info = (ATOM_FIRMWARE_INFO *)cgs_atom_get_data_table(hwmgr->device, index,
+						  &size, &frev, &crev);
+
+	if (!fw_info)
+		return 0;
+
+	reference_clock = le16_to_cpu(fw_info->usMinPixelClockPLL_Output);
+
+	divide = PHM_READ_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, CG_CLKPIN_CNTL, XTALIN_DIVIDE);
+
+	if (0 != divide)
+		return reference_clock / 4;
+
+	return reference_clock;
+}
+
+int tonga_dpm_set_interrupt_state(void *private_data,
+					 unsigned src_id, unsigned type,
+					 int enabled)
+{
+	uint32_t cg_thermal_int;
+	struct pp_hwmgr *hwmgr = ((struct pp_eventmgr *)private_data)->hwmgr;
+
+	if (hwmgr == NULL)
+		return -EINVAL;
+
+	switch (type) {
+	case AMD_THERMAL_IRQ_LOW_TO_HIGH:
+		if (enabled) {
+			cg_thermal_int = cgs_read_ind_register(hwmgr->device, CGS_IND_REG__SMC, ixCG_THERMAL_INT);
+			cg_thermal_int |= CG_THERMAL_INT_CTRL__THERM_INTH_MASK_MASK;
+			cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC, ixCG_THERMAL_INT, cg_thermal_int);
+		} else {
+			cg_thermal_int = cgs_read_ind_register(hwmgr->device, CGS_IND_REG__SMC, ixCG_THERMAL_INT);
+			cg_thermal_int &= ~CG_THERMAL_INT_CTRL__THERM_INTH_MASK_MASK;
+			cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC, ixCG_THERMAL_INT, cg_thermal_int);
+		}
+		break;
+
+	case AMD_THERMAL_IRQ_HIGH_TO_LOW:
+		if (enabled) {
+			cg_thermal_int = cgs_read_ind_register(hwmgr->device, CGS_IND_REG__SMC, ixCG_THERMAL_INT);
+			cg_thermal_int |= CG_THERMAL_INT_CTRL__THERM_INTL_MASK_MASK;
+			cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC, ixCG_THERMAL_INT, cg_thermal_int);
+		} else {
+			cg_thermal_int = cgs_read_ind_register(hwmgr->device, CGS_IND_REG__SMC, ixCG_THERMAL_INT);
+			cg_thermal_int &= ~CG_THERMAL_INT_CTRL__THERM_INTL_MASK_MASK;
+			cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC, ixCG_THERMAL_INT, cg_thermal_int);
+		}
+		break;
+	default:
+		break;
+	}
+	return 0;
+}
+
+int tonga_register_internal_thermal_interrupt(struct pp_hwmgr *hwmgr,
+					const void *thermal_interrupt_info)
+{
+	int result;
+	const struct pp_interrupt_registration_info *info =
+			(const struct pp_interrupt_registration_info *)thermal_interrupt_info;
+
+	if (info == NULL)
+		return -EINVAL;
+
+	result = cgs_add_irq_source(hwmgr->device, 230, AMD_THERMAL_IRQ_LAST,
+				tonga_dpm_set_interrupt_state,
+				info->call_back, info->context);
+
+	if (result)
+		return -EINVAL;
+
+	result = cgs_add_irq_source(hwmgr->device, 231, AMD_THERMAL_IRQ_LAST,
+				tonga_dpm_set_interrupt_state,
+				info->call_back, info->context);
+
+	if (result)
+		return -EINVAL;
+
+	return 0;
+}
+
+bool tonga_check_smc_update_required_for_display_configuration(struct pp_hwmgr *hwmgr)
+{
+	struct tonga_hwmgr *data = (struct tonga_hwmgr *)(hwmgr->backend);
+	bool is_update_required = false;
+	struct cgs_display_info info = {0,0,NULL};
+
+	cgs_get_active_displays_info(hwmgr->device, &info);
+
+	if (data->display_timing.num_existing_displays != info.display_count)
+		is_update_required = true;
+/* TO DO NEED TO GET DEEP SLEEP CLOCK FROM DAL
+	if (phm_cap_enabled(hwmgr->hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_SclkDeepSleep)) {
+		cgs_get_min_clock_settings(hwmgr->device, &min_clocks);
+		if(min_clocks.engineClockInSR != data->display_timing.minClockInSR)
+			is_update_required = true;
+*/
+	return is_update_required;
+}
+
+static inline bool tonga_are_power_levels_equal(const struct tonga_performance_level *pl1,
+							   const struct tonga_performance_level *pl2)
+{
+	return ((pl1->memory_clock == pl2->memory_clock) &&
+		  (pl1->engine_clock == pl2->engine_clock) &&
+		  (pl1->pcie_gen == pl2->pcie_gen) &&
+		  (pl1->pcie_lane == pl2->pcie_lane));
+}
+
+int tonga_check_states_equal(struct pp_hwmgr *hwmgr, const struct pp_hw_power_state *pstate1, const struct pp_hw_power_state *pstate2, bool *equal)
+{
+	const struct tonga_power_state *psa = cast_const_phw_tonga_power_state(pstate1);
+	const struct tonga_power_state *psb = cast_const_phw_tonga_power_state(pstate2);
+	int i;
+
+	if (equal == NULL || psa == NULL || psb == NULL)
+		return -EINVAL;
+
+	/* If the two states don't even have the same number of performance levels they cannot be the same state. */
+	if (psa->performance_level_count != psb->performance_level_count) {
+		*equal = false;
+		return 0;
+	}
+
+	for (i = 0; i < psa->performance_level_count; i++) {
+		if (!tonga_are_power_levels_equal(&(psa->performance_levels[i]), &(psb->performance_levels[i]))) {
+			/* If we have found even one performance level pair that is different the states are different. */
+			*equal = false;
+			return 0;
+		}
+	}
+
+	/* If all performance levels are the same try to use the UVD clocks to break the tie.*/
+	*equal = ((psa->uvd_clocks.VCLK == psb->uvd_clocks.VCLK) && (psa->uvd_clocks.DCLK == psb->uvd_clocks.DCLK));
+	*equal &= ((psa->vce_clocks.EVCLK == psb->vce_clocks.EVCLK) && (psa->vce_clocks.ECCLK == psb->vce_clocks.ECCLK));
+	*equal &= (psa->sclk_threshold == psb->sclk_threshold);
+	*equal &= (psa->acp_clk == psb->acp_clk);
+
+	return 0;
+}
+
+static int tonga_set_fan_control_mode(struct pp_hwmgr *hwmgr, uint32_t mode)
+{
+	if (mode) {
+		/* stop auto-manage */
+		if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
+				PHM_PlatformCaps_MicrocodeFanControl))
+			tonga_fan_ctrl_stop_smc_fan_control(hwmgr);
+		tonga_fan_ctrl_set_static_mode(hwmgr, mode);
+	} else
+		/* restart auto-manage */
+		tonga_fan_ctrl_reset_fan_speed_to_default(hwmgr);
+
+	return 0;
+}
+
+static int tonga_get_fan_control_mode(struct pp_hwmgr *hwmgr)
+{
+	if (hwmgr->fan_ctrl_is_in_default_mode)
+		return hwmgr->fan_ctrl_default_mode;
+	else
+		return PHM_READ_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC,
+				CG_FDO_CTRL2, FDO_PWM_MODE);
+}
+
+static const struct pp_hwmgr_func tonga_hwmgr_funcs = {
+	.backend_init = &tonga_hwmgr_backend_init,
+	.backend_fini = &tonga_hwmgr_backend_fini,
+	.asic_setup = &tonga_setup_asic_task,
+	.dynamic_state_management_enable = &tonga_enable_dpm_tasks,
+	.apply_state_adjust_rules = tonga_apply_state_adjust_rules,
+	.force_dpm_level = &tonga_force_dpm_level,
+	.power_state_set = tonga_set_power_state_tasks,
+	.get_power_state_size = tonga_get_power_state_size,
+	.get_mclk = tonga_dpm_get_mclk,
+	.get_sclk = tonga_dpm_get_sclk,
+	.patch_boot_state = tonga_dpm_patch_boot_state,
+	.get_pp_table_entry = tonga_get_pp_table_entry,
+	.get_num_of_pp_table_entries = tonga_get_number_of_powerplay_table_entries,
+	.print_current_perforce_level = tonga_print_current_perforce_level,
+	.powerdown_uvd = tonga_phm_powerdown_uvd,
+	.powergate_uvd = tonga_phm_powergate_uvd,
+	.powergate_vce = tonga_phm_powergate_vce,
+	.disable_clock_power_gating = tonga_phm_disable_clock_power_gating,
+	.notify_smc_display_config_after_ps_adjustment = tonga_notify_smc_display_config_after_ps_adjustment,
+	.display_config_changed = tonga_display_configuration_changed_task,
+	.set_max_fan_pwm_output = tonga_set_max_fan_pwm_output,
+	.set_max_fan_rpm_output = tonga_set_max_fan_rpm_output,
+	.get_temperature = tonga_thermal_get_temperature,
+	.stop_thermal_controller = tonga_thermal_stop_thermal_controller,
+	.get_fan_speed_info = tonga_fan_ctrl_get_fan_speed_info,
+	.get_fan_speed_percent = tonga_fan_ctrl_get_fan_speed_percent,
+	.set_fan_speed_percent = tonga_fan_ctrl_set_fan_speed_percent,
+	.reset_fan_speed_to_default = tonga_fan_ctrl_reset_fan_speed_to_default,
+	.get_fan_speed_rpm = tonga_fan_ctrl_get_fan_speed_rpm,
+	.set_fan_speed_rpm = tonga_fan_ctrl_set_fan_speed_rpm,
+	.uninitialize_thermal_controller = tonga_thermal_ctrl_uninitialize_thermal_controller,
+	.register_internal_thermal_interrupt = tonga_register_internal_thermal_interrupt,
+	.check_smc_update_required_for_display_configuration = tonga_check_smc_update_required_for_display_configuration,
+	.check_states_equal = tonga_check_states_equal,
+	.set_fan_control_mode = tonga_set_fan_control_mode,
+	.get_fan_control_mode = tonga_get_fan_control_mode,
+};
+
+int tonga_hwmgr_init(struct pp_hwmgr *hwmgr)
+{
+	tonga_hwmgr  *data;
+
+	data = kzalloc (sizeof(tonga_hwmgr), GFP_KERNEL);
+	if (data == NULL)
+		return -ENOMEM;
+	memset(data, 0x00, sizeof(tonga_hwmgr));
+
+	hwmgr->backend = data;
+	hwmgr->hwmgr_func = &tonga_hwmgr_funcs;
+	hwmgr->pptable_func = &tonga_pptable_funcs;
+	pp_tonga_thermal_initialize(hwmgr);
+	return 0;
+}
+
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_hwmgr.h
@@ -0,0 +1,408 @@
+/*
+ * Copyright 2015 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+#ifndef TONGA_HWMGR_H
+#define TONGA_HWMGR_H
+
+#include "hwmgr.h"
+#include "smu72_discrete.h"
+#include "ppatomctrl.h"
+#include "ppinterrupt.h"
+#include "tonga_powertune.h"
+
+#define TONGA_MAX_HARDWARE_POWERLEVELS 2
+#define TONGA_DYNCLK_NUMBER_OF_TREND_COEFFICIENTS 15
+
+struct tonga_performance_level {
+	uint32_t	memory_clock;
+	uint32_t	engine_clock;
+	uint16_t    pcie_gen;
+	uint16_t    pcie_lane;
+};
+
+struct _phw_tonga_bacos {
+	uint32_t                          best_match;
+	uint32_t                          baco_flags;
+	struct tonga_performance_level		  performance_level;
+};
+typedef struct _phw_tonga_bacos phw_tonga_bacos;
+
+struct _phw_tonga_uvd_clocks {
+	uint32_t   VCLK;
+	uint32_t   DCLK;
+};
+
+typedef struct _phw_tonga_uvd_clocks phw_tonga_uvd_clocks;
+
+struct _phw_tonga_vce_clocks {
+	uint32_t   EVCLK;
+	uint32_t   ECCLK;
+};
+
+typedef struct _phw_tonga_vce_clocks phw_tonga_vce_clocks;
+
+struct tonga_power_state {
+	uint32_t                    magic;
+	phw_tonga_uvd_clocks        uvd_clocks;
+	phw_tonga_vce_clocks        vce_clocks;
+	uint32_t                    sam_clk;
+	uint32_t                    acp_clk;
+	uint16_t                    performance_level_count;
+	bool                        dc_compatible;
+	uint32_t                    sclk_threshold;
+	struct tonga_performance_level performance_levels[TONGA_MAX_HARDWARE_POWERLEVELS];
+};
+
+struct _phw_tonga_dpm_level {
+	bool  		enabled;
+	uint32_t    value;
+	uint32_t    param1;
+};
+typedef struct _phw_tonga_dpm_level phw_tonga_dpm_level;
+
+#define TONGA_MAX_DEEPSLEEP_DIVIDER_ID 5
+#define MAX_REGULAR_DPM_NUMBER 8
+#define TONGA_MINIMUM_ENGINE_CLOCK 2500
+
+struct tonga_single_dpm_table {
+	uint32_t count;
+	phw_tonga_dpm_level dpm_levels[MAX_REGULAR_DPM_NUMBER];
+};
+
+struct tonga_dpm_table {
+	struct tonga_single_dpm_table  sclk_table;
+	struct tonga_single_dpm_table  mclk_table;
+	struct tonga_single_dpm_table  pcie_speed_table;
+	struct tonga_single_dpm_table  vddc_table;
+	struct tonga_single_dpm_table  vdd_gfx_table;
+	struct tonga_single_dpm_table  vdd_ci_table;
+	struct tonga_single_dpm_table  mvdd_table;
+};
+typedef struct _phw_tonga_dpm_table phw_tonga_dpm_table;
+
+
+struct _phw_tonga_clock_regisiters {
+	uint32_t  vCG_SPLL_FUNC_CNTL;
+	uint32_t  vCG_SPLL_FUNC_CNTL_2;
+	uint32_t  vCG_SPLL_FUNC_CNTL_3;
+	uint32_t  vCG_SPLL_FUNC_CNTL_4;
+	uint32_t  vCG_SPLL_SPREAD_SPECTRUM;
+	uint32_t  vCG_SPLL_SPREAD_SPECTRUM_2;
+	uint32_t  vDLL_CNTL;
+	uint32_t  vMCLK_PWRMGT_CNTL;
+	uint32_t  vMPLL_AD_FUNC_CNTL;
+	uint32_t  vMPLL_DQ_FUNC_CNTL;
+	uint32_t  vMPLL_FUNC_CNTL;
+	uint32_t  vMPLL_FUNC_CNTL_1;
+	uint32_t  vMPLL_FUNC_CNTL_2;
+	uint32_t  vMPLL_SS1;
+	uint32_t  vMPLL_SS2;
+};
+typedef struct _phw_tonga_clock_regisiters phw_tonga_clock_registers;
+
+struct _phw_tonga_voltage_smio_registers {
+	uint32_t vs0_vid_lower_smio_cntl;
+};
+typedef struct _phw_tonga_voltage_smio_registers phw_tonga_voltage_smio_registers;
+
+
+struct _phw_tonga_mc_reg_entry {
+	uint32_t mclk_max;
+	uint32_t mc_data[SMU72_DISCRETE_MC_REGISTER_ARRAY_SIZE];
+};
+typedef struct _phw_tonga_mc_reg_entry phw_tonga_mc_reg_entry;
+
+struct _phw_tonga_mc_reg_table {
+	uint8_t   last;               /* number of registers*/
+	uint8_t   num_entries;        /* number of entries in mc_reg_table_entry used*/
+	uint16_t  validflag;          /* indicate the corresponding register is valid or not. 1: valid, 0: invalid. bit0->address[0], bit1->address[1], etc.*/
+	phw_tonga_mc_reg_entry    mc_reg_table_entry[MAX_AC_TIMING_ENTRIES];
+	SMU72_Discrete_MCRegisterAddress mc_reg_address[SMU72_DISCRETE_MC_REGISTER_ARRAY_SIZE];
+};
+typedef struct _phw_tonga_mc_reg_table phw_tonga_mc_reg_table;
+
+#define DISABLE_MC_LOADMICROCODE   1
+#define DISABLE_MC_CFGPROGRAMMING  2
+
+/*Ultra Low Voltage parameter structure */
+struct _phw_tonga_ulv_parm{
+	bool	ulv_supported;
+	uint32_t   ch_ulv_parameter;
+	uint32_t   ulv_volt_change_delay;
+	struct tonga_performance_level   ulv_power_level;
+};
+typedef struct _phw_tonga_ulv_parm phw_tonga_ulv_parm;
+
+#define TONGA_MAX_LEAKAGE_COUNT  8
+
+struct _phw_tonga_leakage_voltage {
+	uint16_t  count;
+	uint16_t  leakage_id[TONGA_MAX_LEAKAGE_COUNT];
+	uint16_t  actual_voltage[TONGA_MAX_LEAKAGE_COUNT];
+};
+typedef struct _phw_tonga_leakage_voltage phw_tonga_leakage_voltage;
+
+struct _phw_tonga_display_timing {
+	uint32_t min_clock_insr;
+	uint32_t num_existing_displays;
+};
+typedef struct _phw_tonga_display_timing phw_tonga_display_timing;
+
+struct _phw_tonga_dpmlevel_enable_mask {
+	uint32_t uvd_dpm_enable_mask;
+	uint32_t vce_dpm_enable_mask;
+	uint32_t acp_dpm_enable_mask;
+	uint32_t samu_dpm_enable_mask;
+	uint32_t sclk_dpm_enable_mask;
+	uint32_t mclk_dpm_enable_mask;
+	uint32_t pcie_dpm_enable_mask;
+};
+typedef struct _phw_tonga_dpmlevel_enable_mask phw_tonga_dpmlevel_enable_mask;
+
+struct _phw_tonga_pcie_perf_range {
+	uint16_t max;
+	uint16_t min;
+};
+typedef struct _phw_tonga_pcie_perf_range phw_tonga_pcie_perf_range;
+
+struct _phw_tonga_vbios_boot_state {
+	uint16_t					mvdd_bootup_value;
+	uint16_t					vddc_bootup_value;
+	uint16_t					vddci_bootup_value;
+	uint16_t					vddgfx_bootup_value;
+	uint32_t					sclk_bootup_value;
+	uint32_t					mclk_bootup_value;
+	uint16_t					pcie_gen_bootup_value;
+	uint16_t					pcie_lane_bootup_value;
+};
+typedef struct _phw_tonga_vbios_boot_state phw_tonga_vbios_boot_state;
+
+#define DPMTABLE_OD_UPDATE_SCLK     0x00000001
+#define DPMTABLE_OD_UPDATE_MCLK     0x00000002
+#define DPMTABLE_UPDATE_SCLK        0x00000004
+#define DPMTABLE_UPDATE_MCLK        0x00000008
+
+/* We need to review which fields are needed. */
+/* This is mostly a copy of the RV7xx/Evergreen structure which is close, but not identical to the N.Islands one. */
+struct tonga_hwmgr {
+	struct tonga_dpm_table               dpm_table;
+	struct tonga_dpm_table               golden_dpm_table;
+
+	uint32_t                           voting_rights_clients0;
+	uint32_t                           voting_rights_clients1;
+	uint32_t                           voting_rights_clients2;
+	uint32_t                           voting_rights_clients3;
+	uint32_t                           voting_rights_clients4;
+	uint32_t                           voting_rights_clients5;
+	uint32_t                           voting_rights_clients6;
+	uint32_t                           voting_rights_clients7;
+	uint32_t                           static_screen_threshold_unit;
+	uint32_t                           static_screen_threshold;
+	uint32_t                           voltage_control;
+	uint32_t                           vdd_gfx_control;
+
+	uint32_t                           vddc_vddci_delta;
+	uint32_t                           vddc_vddgfx_delta;
+
+	struct pp_interrupt_registration_info    internal_high_thermal_interrupt_info;
+	struct pp_interrupt_registration_info    internal_low_thermal_interrupt_info;
+	struct pp_interrupt_registration_info    smc_to_host_interrupt_info;
+	uint32_t                          active_auto_throttle_sources;
+
+	struct pp_interrupt_registration_info    external_throttle_interrupt;
+	irq_handler_func_t             external_throttle_callback;
+	void                             *external_throttle_context;
+
+	struct pp_interrupt_registration_info    ctf_interrupt_info;
+	irq_handler_func_t             ctf_callback;
+	void                             *ctf_context;
+
+	phw_tonga_clock_registers      	  clock_registers;
+	phw_tonga_voltage_smio_registers  voltage_smio_registers;
+
+	bool                         	is_memory_GDDR5;
+	uint16_t                          acpi_vddc;
+	bool                         	pspp_notify_required;        /* Flag to indicate if PSPP notification to SBIOS is required */
+	uint16_t                          force_pcie_gen;            /* The forced PCI-E speed if not 0xffff */
+	uint16_t                          acpi_pcie_gen;             /* The PCI-E speed at ACPI time */
+	uint32_t                           pcie_gen_cap;             /* The PCI-E speed capabilities bitmap from CAIL */
+	uint32_t                           pcie_lane_cap;            /* The PCI-E lane capabilities bitmap from CAIL */
+	uint32_t                           pcie_spc_cap;             /* Symbol Per Clock Capabilities from registry */
+	phw_tonga_leakage_voltage       	vddc_leakage;            /* The Leakage VDDC supported (based on leakage ID).*/
+	phw_tonga_leakage_voltage       	vddcgfx_leakage;         /* The Leakage VDDC supported (based on leakage ID). */
+	phw_tonga_leakage_voltage       	vddci_leakage;           /* The Leakage VDDCI supported (based on leakage ID). */
+
+	uint32_t                           mvdd_control;
+	uint32_t                           vddc_mask_low;
+	uint32_t                           mvdd_mask_low;
+	uint16_t                          max_vddc_in_pp_table;        /* the maximum VDDC value in the powerplay table*/
+	uint16_t                          min_vddc_in_pp_table;
+	uint16_t                          max_vddci_in_pp_table;       /* the maximum VDDCI value in the powerplay table */
+	uint16_t                          min_vddci_in_pp_table;
+	uint32_t                           mclk_strobe_mode_threshold;
+	uint32_t                           mclk_stutter_mode_threshold;
+	uint32_t                           mclk_edc_enable_threshold;
+	uint32_t                           mclk_edc_wr_enable_threshold;
+	bool                         	is_uvd_enabled;
+	bool                         	is_xdma_enabled;
+	phw_tonga_vbios_boot_state      vbios_boot_state;
+
+	bool                         battery_state;
+	bool                         is_tlu_enabled;
+	bool                         pcie_performance_request;
+
+	/* -------------- SMC SRAM Address of firmware header tables ----------------*/
+	uint32_t                           sram_end;                 /* The first address after the SMC SRAM. */
+	uint32_t                           dpm_table_start;          /* The start of the dpm table in the SMC SRAM. */
+	uint32_t                           soft_regs_start;          /* The start of the soft registers in the SMC SRAM. */
+	uint32_t                           mc_reg_table_start;       /* The start of the mc register table in the SMC SRAM. */
+	uint32_t                           fan_table_start;          /* The start of the fan table in the SMC SRAM. */
+	uint32_t                           arb_table_start;          /* The start of the ARB setting table in the SMC SRAM. */
+	SMU72_Discrete_DpmTable         smc_state_table;             /* The carbon copy of the SMC state table. */
+	SMU72_Discrete_MCRegisters      mc_reg_table;
+	SMU72_Discrete_Ulv              ulv_setting;                 /* The carbon copy of ULV setting. */
+	/* -------------- Stuff originally coming from Evergreen --------------------*/
+	phw_tonga_mc_reg_table			tonga_mc_reg_table;
+	uint32_t                         vdd_ci_control;
+	pp_atomctrl_voltage_table        vddc_voltage_table;
+	pp_atomctrl_voltage_table        vddci_voltage_table;
+	pp_atomctrl_voltage_table        vddgfx_voltage_table;
+	pp_atomctrl_voltage_table        mvdd_voltage_table;
+
+	uint32_t                           mgcg_cgtt_local2;
+	uint32_t                           mgcg_cgtt_local3;
+	uint32_t                           gpio_debug;
+	uint32_t							mc_micro_code_feature;
+	uint32_t							highest_mclk;
+	uint16_t                          acpi_vdd_ci;
+	uint8_t                           mvdd_high_index;
+	uint8_t                           mvdd_low_index;
+	bool                         dll_defaule_on;
+	bool                         performance_request_registered;
+
+	/* ----------------- Low Power Features ---------------------*/
+	phw_tonga_bacos					bacos;
+	phw_tonga_ulv_parm              ulv;
+	/* ----------------- CAC Stuff ---------------------*/
+	uint32_t					cac_table_start;
+	bool                         cac_configuration_required;    /* TRUE if PP_CACConfigurationRequired == 1 */
+	bool                         driver_calculate_cac_leakage;  /* TRUE if PP_DriverCalculateCACLeakage == 1 */
+	bool                         cac_enabled;
+	/* ----------------- DPM2 Parameters ---------------------*/
+	uint32_t					power_containment_features;
+	bool                         enable_bapm_feature;
+	bool                         enable_tdc_limit_feature;
+	bool                         enable_pkg_pwr_tracking_feature;
+	bool                         disable_uvd_power_tune_feature;
+	phw_tonga_pt_defaults           *power_tune_defaults;
+	SMU72_Discrete_PmFuses           power_tune_table;
+	uint32_t                           ul_dte_tj_offset;             /* Fudge factor in DPM table to correct HW DTE errors */
+	uint32_t                           fast_watemark_threshold;      /* use fast watermark if clock is equal or above this. In percentage of the target high sclk. */
+
+	/* ----------------- Phase Shedding ---------------------*/
+	bool                         vddc_phase_shed_control;
+	/* --------------------- DI/DT --------------------------*/
+	phw_tonga_display_timing       display_timing;
+	/* --------- ReadRegistry data for memory and engine clock margins ---- */
+	uint32_t                           engine_clock_data;
+	uint32_t                           memory_clock_data;
+	/* -------- Thermal Temperature Setting --------------*/
+	phw_tonga_dpmlevel_enable_mask     dpm_level_enable_mask;
+	uint32_t                           need_update_smu7_dpm_table;
+	uint32_t                           sclk_dpm_key_disabled;
+	uint32_t                           mclk_dpm_key_disabled;
+	uint32_t                           pcie_dpm_key_disabled;
+	uint32_t                           min_engine_clocks; /* used to store the previous dal min sclock */
+	phw_tonga_pcie_perf_range       pcie_gen_performance;
+	phw_tonga_pcie_perf_range       pcie_lane_performance;
+	phw_tonga_pcie_perf_range       pcie_gen_power_saving;
+	phw_tonga_pcie_perf_range       pcie_lane_power_saving;
+	bool                            use_pcie_performance_levels;
+	bool                            use_pcie_power_saving_levels;
+	uint32_t                           activity_target[SMU72_MAX_LEVELS_GRAPHICS]; /* percentage value from 0-100, default 50 */
+	uint32_t                           mclk_activity_target;
+	uint32_t                           low_sclk_interrupt_threshold;
+	uint32_t                           last_mclk_dpm_enable_mask;
+	bool								uvd_enabled;
+	uint32_t                           pcc_monitor_enabled;
+
+	/* --------- Power Gating States ------------*/
+	bool                           uvd_power_gated;  /* 1: gated, 0:not gated */
+	bool                           vce_power_gated;  /* 1: gated, 0:not gated */
+	bool                           samu_power_gated; /* 1: gated, 0:not gated */
+	bool                           acp_power_gated;  /* 1: gated, 0:not gated */
+	bool                           pg_acp_init;
+
+};
+
+typedef struct tonga_hwmgr tonga_hwmgr;
+
+#define TONGA_DPM2_NEAR_TDP_DEC          10
+#define TONGA_DPM2_ABOVE_SAFE_INC        5
+#define TONGA_DPM2_BELOW_SAFE_INC        20
+
+#define TONGA_DPM2_LTA_WINDOW_SIZE       7  /* Log2 of the LTA window size (l2numWin_TDP). Eg. If LTA windows size is 128, then this value should be Log2(128) = 7. */
+
+#define TONGA_DPM2_LTS_TRUNCATE          0
+
+#define TONGA_DPM2_TDP_SAFE_LIMIT_PERCENT            80  /* Maximum 100 */
+
+#define TONGA_DPM2_MAXPS_PERCENT_H                   90  /* Maximum 0xFF */
+#define TONGA_DPM2_MAXPS_PERCENT_M                   90  /* Maximum 0xFF */
+
+#define TONGA_DPM2_PWREFFICIENCYRATIO_MARGIN         50
+
+#define TONGA_DPM2_SQ_RAMP_MAX_POWER                 0x3FFF
+#define TONGA_DPM2_SQ_RAMP_MIN_POWER                 0x12
+#define TONGA_DPM2_SQ_RAMP_MAX_POWER_DELTA           0x15
+#define TONGA_DPM2_SQ_RAMP_SHORT_TERM_INTERVAL_SIZE  0x1E
+#define TONGA_DPM2_SQ_RAMP_LONG_TERM_INTERVAL_RATIO  0xF
+
+#define TONGA_VOLTAGE_CONTROL_NONE                   0x0
+#define TONGA_VOLTAGE_CONTROL_BY_GPIO                0x1
+#define TONGA_VOLTAGE_CONTROL_BY_SVID2               0x2
+#define TONGA_VOLTAGE_CONTROL_MERGED                 0x3
+
+#define TONGA_Q88_FORMAT_CONVERSION_UNIT             256 /*To convert to Q8.8 format for firmware */
+
+#define TONGA_UNUSED_GPIO_PIN                        0x7F
+
+#define PP_HOST_TO_SMC_UL(X) cpu_to_be32(X)
+#define PP_SMC_TO_HOST_UL(X) be32_to_cpu(X)
+
+#define PP_HOST_TO_SMC_US(X) cpu_to_be16(X)
+#define PP_SMC_TO_HOST_US(X) be16_to_cpu(X)
+
+#define CONVERT_FROM_HOST_TO_SMC_UL(X) ((X) = PP_HOST_TO_SMC_UL(X))
+#define CONVERT_FROM_SMC_TO_HOST_UL(X) ((X) = PP_SMC_TO_HOST_UL(X))
+
+#define CONVERT_FROM_HOST_TO_SMC_US(X) ((X) = PP_HOST_TO_SMC_US(X))
+
+int tonga_hwmgr_init(struct pp_hwmgr *hwmgr);
+int tonga_update_vce_dpm(struct pp_hwmgr *hwmgr, const void *input);
+int tonga_update_uvd_dpm(struct pp_hwmgr *hwmgr, bool bgate);
+int tonga_enable_disable_uvd_dpm(struct pp_hwmgr *hwmgr, bool enable);
+int tonga_enable_disable_vce_dpm(struct pp_hwmgr *hwmgr, bool enable);
+uint32_t tonga_get_xclk(struct pp_hwmgr *hwmgr);
+
+#endif
+
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_powertune.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2015 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#ifndef TONGA_POWERTUNE_H
+#define TONGA_POWERTUNE_H
+
+enum _phw_tonga_ptc_config_reg_type {
+	TONGA_CONFIGREG_MMR = 0,
+	TONGA_CONFIGREG_SMC_IND,
+	TONGA_CONFIGREG_DIDT_IND,
+	TONGA_CONFIGREG_CACHE,
+
+	TONGA_CONFIGREG_MAX
+};
+typedef enum _phw_tonga_ptc_config_reg_type phw_tonga_ptc_config_reg_type;
+
+/* PowerContainment Features */
+#define POWERCONTAINMENT_FEATURE_BAPM            0x00000001
+#define POWERCONTAINMENT_FEATURE_TDCLimit        0x00000002
+#define POWERCONTAINMENT_FEATURE_PkgPwrLimit     0x00000004
+
+struct _phw_tonga_pt_config_reg {
+	uint32_t                           Offset;
+	uint32_t                           Mask;
+	uint32_t                           Shift;
+	uint32_t                           Value;
+	phw_tonga_ptc_config_reg_type     Type;
+};
+typedef struct _phw_tonga_pt_config_reg phw_tonga_pt_config_reg;
+
+struct _phw_tonga_pt_defaults {
+	uint8_t   svi_load_line_en;
+	uint8_t   svi_load_line_vddC;
+	uint8_t   tdc_vddc_throttle_release_limit_perc;
+	uint8_t   tdc_mawt;
+	uint8_t   tdc_waterfall_ctl;
+	uint8_t   dte_ambient_temp_base;
+	uint32_t  display_cac;
+	uint32_t  bamp_temp_gradient;
+	uint16_t  bapmti_r[SMU72_DTE_ITERATIONS * SMU72_DTE_SOURCES * SMU72_DTE_SINKS];
+	uint16_t  bapmti_rc[SMU72_DTE_ITERATIONS * SMU72_DTE_SOURCES * SMU72_DTE_SINKS];
+};
+typedef struct _phw_tonga_pt_defaults phw_tonga_pt_defaults;
+
+#endif
+
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_pptable.h
@@ -0,0 +1,406 @@
+/*
+ * Copyright 2015 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#ifndef TONGA_PPTABLE_H
+#define TONGA_PPTABLE_H
+
+/** \file
+ * This is a PowerPlay table header file
+ */
+#pragma pack(push, 1)
+
+#include "hwmgr.h"
+
+#define ATOM_TONGA_PP_FANPARAMETERS_TACHOMETER_PULSES_PER_REVOLUTION_MASK 0x0f
+#define ATOM_TONGA_PP_FANPARAMETERS_NOFAN                                 0x80    /* No fan is connected to this controller. */
+
+#define ATOM_TONGA_PP_THERMALCONTROLLER_NONE      0
+#define ATOM_TONGA_PP_THERMALCONTROLLER_LM96163   17
+#define ATOM_TONGA_PP_THERMALCONTROLLER_TONGA     21
+#define ATOM_TONGA_PP_THERMALCONTROLLER_FIJI      22
+
+/*
+ * Thermal controller 'combo type' to use an external controller for Fan control and an internal controller for thermal.
+ * We probably should reserve the bit 0x80 for this use.
+ * To keep the number of these types low we should also use the same code for all ASICs (i.e. do not distinguish RV6xx and RV7xx Internal here).
+ * The driver can pick the correct internal controller based on the ASIC.
+ */
+
+#define ATOM_TONGA_PP_THERMALCONTROLLER_ADT7473_WITH_INTERNAL   0x89    /* ADT7473 Fan Control + Internal Thermal Controller */
+#define ATOM_TONGA_PP_THERMALCONTROLLER_EMC2103_WITH_INTERNAL   0x8D    /* EMC2103 Fan Control + Internal Thermal Controller */
+
+/*/* ATOM_TONGA_POWERPLAYTABLE::ulPlatformCaps */
+#define ATOM_TONGA_PP_PLATFORM_CAP_VDDGFX_CONTROL              0x1            /* This cap indicates whether vddgfx will be a separated power rail. */
+#define ATOM_TONGA_PP_PLATFORM_CAP_POWERPLAY                   0x2            /* This cap indicates whether this is a mobile part and CCC need to show Powerplay page. */
+#define ATOM_TONGA_PP_PLATFORM_CAP_SBIOSPOWERSOURCE            0x4            /* This cap indicates whether power source notificaiton is done by SBIOS directly. */
+#define ATOM_TONGA_PP_PLATFORM_CAP_DISABLE_VOLTAGE_ISLAND      0x8            /* Enable the option to overwrite voltage island feature to be disabled, regardless of VddGfx power rail support. */
+#define ____RETIRE16____                                0x10
+#define ATOM_TONGA_PP_PLATFORM_CAP_HARDWAREDC                 0x20            /* This cap indicates whether power source notificaiton is done by GPIO directly. */
+#define ____RETIRE64____                                0x40
+#define ____RETIRE128____                               0x80
+#define ____RETIRE256____                              0x100
+#define ____RETIRE512____                              0x200
+#define ____RETIRE1024____                             0x400
+#define ____RETIRE2048____                             0x800
+#define ATOM_TONGA_PP_PLATFORM_CAP_MVDD_CONTROL             0x1000            /* This cap indicates dynamic MVDD is required. Uncheck to disable it. */
+#define ____RETIRE2000____                            0x2000
+#define ____RETIRE4000____                            0x4000
+#define ATOM_TONGA_PP_PLATFORM_CAP_VDDCI_CONTROL            0x8000            /* This cap indicates dynamic VDDCI is required. Uncheck to disable it. */
+#define ____RETIRE10000____                          0x10000
+#define ATOM_TONGA_PP_PLATFORM_CAP_BACO                    0x20000            /* Enable to indicate the driver supports BACO state. */
+
+#define ATOM_TONGA_PP_PLATFORM_CAP_OUTPUT_THERMAL2GPIO17         0x100000     /* Enable to indicate the driver supports thermal2GPIO17. */
+#define ATOM_TONGA_PP_PLATFORM_COMBINE_PCC_WITH_THERMAL_SIGNAL  0x1000000     /* Enable to indicate if thermal and PCC are sharing the same GPIO */
+#define ATOM_TONGA_PLATFORM_LOAD_POST_PRODUCTION_FIRMWARE       0x2000000
+
+/* ATOM_PPLIB_NONCLOCK_INFO::usClassification */
+#define ATOM_PPLIB_CLASSIFICATION_UI_MASK               0x0007
+#define ATOM_PPLIB_CLASSIFICATION_UI_SHIFT              0
+#define ATOM_PPLIB_CLASSIFICATION_UI_NONE               0
+#define ATOM_PPLIB_CLASSIFICATION_UI_BATTERY            1
+#define ATOM_PPLIB_CLASSIFICATION_UI_BALANCED           3
+#define ATOM_PPLIB_CLASSIFICATION_UI_PERFORMANCE        5
+/* 2, 4, 6, 7 are reserved */
+
+#define ATOM_PPLIB_CLASSIFICATION_BOOT                  0x0008
+#define ATOM_PPLIB_CLASSIFICATION_THERMAL               0x0010
+#define ATOM_PPLIB_CLASSIFICATION_LIMITEDPOWERSOURCE    0x0020
+#define ATOM_PPLIB_CLASSIFICATION_REST                  0x0040
+#define ATOM_PPLIB_CLASSIFICATION_FORCED                0x0080
+#define ATOM_PPLIB_CLASSIFICATION_ACPI                  0x1000
+
+/* ATOM_PPLIB_NONCLOCK_INFO::usClassification2 */
+#define ATOM_PPLIB_CLASSIFICATION2_LIMITEDPOWERSOURCE_2 0x0001
+
+#define ATOM_Tonga_DISALLOW_ON_DC                       0x00004000
+#define ATOM_Tonga_ENABLE_VARIBRIGHT                    0x00008000
+
+#define ATOM_Tonga_TABLE_REVISION_TONGA                 7
+
+typedef struct _ATOM_Tonga_POWERPLAYTABLE {
+	ATOM_COMMON_TABLE_HEADER sHeader;
+
+	UCHAR  ucTableRevision;
+	USHORT usTableSize;						/*the size of header structure */
+
+	ULONG	ulGoldenPPID;
+	ULONG	ulGoldenRevision;
+	USHORT	usFormatID;
+
+	USHORT	usVoltageTime;					 /*in microseconds */
+	ULONG	ulPlatformCaps;					  /*See ATOM_Tonga_CAPS_* */
+
+	ULONG	ulMaxODEngineClock; 			   /*For Overdrive.  */
+	ULONG	ulMaxODMemoryClock; 			   /*For Overdrive. */
+
+	USHORT	usPowerControlLimit;
+	USHORT	usUlvVoltageOffset;				  /*in mv units */
+
+	USHORT	usStateArrayOffset;				  /*points to ATOM_Tonga_State_Array */
+	USHORT	usFanTableOffset;				  /*points to ATOM_Tonga_Fan_Table */
+	USHORT	usThermalControllerOffset;		   /*points to ATOM_Tonga_Thermal_Controller */
+	USHORT	usReserv;						   /*CustomThermalPolicy removed for Tonga. Keep this filed as reserved. */
+
+	USHORT	usMclkDependencyTableOffset;	   /*points to ATOM_Tonga_MCLK_Dependency_Table */
+	USHORT	usSclkDependencyTableOffset;	   /*points to ATOM_Tonga_SCLK_Dependency_Table */
+	USHORT	usVddcLookupTableOffset;		   /*points to ATOM_Tonga_Voltage_Lookup_Table */
+	USHORT	usVddgfxLookupTableOffset; 		/*points to ATOM_Tonga_Voltage_Lookup_Table */
+
+	USHORT	usMMDependencyTableOffset;		  /*points to ATOM_Tonga_MM_Dependency_Table */
+
+	USHORT	usVCEStateTableOffset;			   /*points to ATOM_Tonga_VCE_State_Table; */
+
+	USHORT	usPPMTableOffset;				  /*points to ATOM_Tonga_PPM_Table */
+	USHORT	usPowerTuneTableOffset;			  /*points to ATOM_PowerTune_Table */
+
+	USHORT	usHardLimitTableOffset; 		   /*points to ATOM_Tonga_Hard_Limit_Table */
+
+	USHORT	usPCIETableOffset;				  /*points to ATOM_Tonga_PCIE_Table */
+
+	USHORT	usGPIOTableOffset;				  /*points to ATOM_Tonga_GPIO_Table */
+
+	USHORT	usReserved[6];					   /*TODO: modify reserved size to fit structure aligning */
+} ATOM_Tonga_POWERPLAYTABLE;
+
+typedef struct _ATOM_Tonga_State {
+	UCHAR  ucEngineClockIndexHigh;
+	UCHAR  ucEngineClockIndexLow;
+
+	UCHAR  ucMemoryClockIndexHigh;
+	UCHAR  ucMemoryClockIndexLow;
+
+	UCHAR  ucPCIEGenLow;
+	UCHAR  ucPCIEGenHigh;
+
+	UCHAR  ucPCIELaneLow;
+	UCHAR  ucPCIELaneHigh;
+
+	USHORT usClassification;
+	ULONG ulCapsAndSettings;
+	USHORT usClassification2;
+	UCHAR  ucUnused[4];
+} ATOM_Tonga_State;
+
+typedef struct _ATOM_Tonga_State_Array {
+	UCHAR ucRevId;
+	UCHAR ucNumEntries;		/* Number of entries. */
+	ATOM_Tonga_State states[1];	/* Dynamically allocate entries. */
+} ATOM_Tonga_State_Array;
+
+typedef struct _ATOM_Tonga_MCLK_Dependency_Record {
+	UCHAR  ucVddcInd;	/* Vddc voltage */
+	USHORT usVddci;
+	USHORT usVddgfxOffset;	/* Offset relative to Vddc voltage */
+	USHORT usMvdd;
+	ULONG ulMclk;
+	USHORT usReserved;
+} ATOM_Tonga_MCLK_Dependency_Record;
+
+typedef struct _ATOM_Tonga_MCLK_Dependency_Table {
+	UCHAR ucRevId;
+	UCHAR ucNumEntries; 										/* Number of entries. */
+	ATOM_Tonga_MCLK_Dependency_Record entries[1];				/* Dynamically allocate entries. */
+} ATOM_Tonga_MCLK_Dependency_Table;
+
+typedef struct _ATOM_Tonga_SCLK_Dependency_Record {
+	UCHAR  ucVddInd;											/* Base voltage */
+	USHORT usVddcOffset;										/* Offset relative to base voltage */
+	ULONG ulSclk;
+	USHORT usEdcCurrent;
+	UCHAR  ucReliabilityTemperature;
+	UCHAR  ucCKSVOffsetandDisable;							  /* Bits 0~6: Voltage offset for CKS, Bit 7: Disable/enable for the SCLK level. */
+} ATOM_Tonga_SCLK_Dependency_Record;
+
+typedef struct _ATOM_Tonga_SCLK_Dependency_Table {
+	UCHAR ucRevId;
+	UCHAR ucNumEntries; 										/* Number of entries. */
+	ATOM_Tonga_SCLK_Dependency_Record entries[1];				 /* Dynamically allocate entries. */
+} ATOM_Tonga_SCLK_Dependency_Table;
+
+typedef struct _ATOM_Tonga_PCIE_Record {
+	UCHAR ucPCIEGenSpeed;
+	UCHAR usPCIELaneWidth;
+	UCHAR ucReserved[2];
+} ATOM_Tonga_PCIE_Record;
+
+typedef struct _ATOM_Tonga_PCIE_Table {
+	UCHAR ucRevId;
+	UCHAR ucNumEntries; 										/* Number of entries. */
+	ATOM_Tonga_PCIE_Record entries[1];							/* Dynamically allocate entries. */
+} ATOM_Tonga_PCIE_Table;
+
+typedef struct _ATOM_Tonga_MM_Dependency_Record {
+	UCHAR   ucVddcInd;											 /* VDDC voltage */
+	USHORT  usVddgfxOffset;									  /* Offset relative to VDDC voltage */
+	ULONG  ulDClk;												/* UVD D-clock */
+	ULONG  ulVClk;												/* UVD V-clock */
+	ULONG  ulEClk;												/* VCE clock */
+	ULONG  ulAClk;												/* ACP clock */
+	ULONG  ulSAMUClk;											/* SAMU clock */
+} ATOM_Tonga_MM_Dependency_Record;
+
+typedef struct _ATOM_Tonga_MM_Dependency_Table {
+	UCHAR ucRevId;
+	UCHAR ucNumEntries; 										/* Number of entries. */
+	ATOM_Tonga_MM_Dependency_Record entries[1]; 			   /* Dynamically allocate entries. */
+} ATOM_Tonga_MM_Dependency_Table;
+
+typedef struct _ATOM_Tonga_Voltage_Lookup_Record {
+	USHORT usVdd;											   /* Base voltage */
+	USHORT usCACLow;
+	USHORT usCACMid;
+	USHORT usCACHigh;
+} ATOM_Tonga_Voltage_Lookup_Record;
+
+typedef struct _ATOM_Tonga_Voltage_Lookup_Table {
+	UCHAR ucRevId;
+	UCHAR ucNumEntries; 										/* Number of entries. */
+	ATOM_Tonga_Voltage_Lookup_Record entries[1];				/* Dynamically allocate entries. */
+} ATOM_Tonga_Voltage_Lookup_Table;
+
+typedef struct _ATOM_Tonga_Fan_Table {
+	UCHAR   ucRevId;						 /* Change this if the table format changes or version changes so that the other fields are not the same. */
+	UCHAR   ucTHyst;						 /* Temperature hysteresis. Integer. */
+	USHORT  usTMin; 						 /* The temperature, in 0.01 centigrades, below which we just run at a minimal PWM. */
+	USHORT  usTMed; 						 /* The middle temperature where we change slopes. */
+	USHORT  usTHigh;						 /* The high point above TMed for adjusting the second slope. */
+	USHORT  usPWMMin;						 /* The minimum PWM value in percent (0.01% increments). */
+	USHORT  usPWMMed;						 /* The PWM value (in percent) at TMed. */
+	USHORT  usPWMHigh;						 /* The PWM value at THigh. */
+	USHORT  usTMax; 						 /* The max temperature */
+	UCHAR   ucFanControlMode;				  /* Legacy or Fuzzy Fan mode */
+	USHORT  usFanPWMMax;					  /* Maximum allowed fan power in percent */
+	USHORT  usFanOutputSensitivity;		  /* Sensitivity of fan reaction to temepature changes */
+	USHORT  usFanRPMMax;					  /* The default value in RPM */
+	ULONG  ulMinFanSCLKAcousticLimit;	   /* Minimum Fan Controller SCLK Frequency Acoustic Limit. */
+	UCHAR   ucTargetTemperature;			 /* Advanced fan controller target temperature. */
+	UCHAR   ucMinimumPWMLimit; 			  /* The minimum PWM that the advanced fan controller can set.	This should be set to the highest PWM that will run the fan at its lowest RPM. */
+	USHORT  usReserved;
+} ATOM_Tonga_Fan_Table;
+
+typedef struct _ATOM_Fiji_Fan_Table {
+	UCHAR   ucRevId;						 /* Change this if the table format changes or version changes so that the other fields are not the same. */
+	UCHAR   ucTHyst;						 /* Temperature hysteresis. Integer. */
+	USHORT  usTMin; 						 /* The temperature, in 0.01 centigrades, below which we just run at a minimal PWM. */
+	USHORT  usTMed; 						 /* The middle temperature where we change slopes. */
+	USHORT  usTHigh;						 /* The high point above TMed for adjusting the second slope. */
+	USHORT  usPWMMin;						 /* The minimum PWM value in percent (0.01% increments). */
+	USHORT  usPWMMed;						 /* The PWM value (in percent) at TMed. */
+	USHORT  usPWMHigh;						 /* The PWM value at THigh. */
+	USHORT  usTMax; 						 /* The max temperature */
+	UCHAR   ucFanControlMode;				  /* Legacy or Fuzzy Fan mode */
+	USHORT  usFanPWMMax;					  /* Maximum allowed fan power in percent */
+	USHORT  usFanOutputSensitivity;		  /* Sensitivity of fan reaction to temepature changes */
+	USHORT  usFanRPMMax;					  /* The default value in RPM */
+	ULONG  ulMinFanSCLKAcousticLimit;		/* Minimum Fan Controller SCLK Frequency Acoustic Limit. */
+	UCHAR   ucTargetTemperature;			 /* Advanced fan controller target temperature. */
+	UCHAR   ucMinimumPWMLimit; 			  /* The minimum PWM that the advanced fan controller can set.	This should be set to the highest PWM that will run the fan at its lowest RPM. */
+	USHORT  usFanGainEdge;
+	USHORT  usFanGainHotspot;
+	USHORT  usFanGainLiquid;
+	USHORT  usFanGainVrVddc;
+	USHORT  usFanGainVrMvdd;
+	USHORT  usFanGainPlx;
+	USHORT  usFanGainHbm;
+	USHORT  usReserved;
+} ATOM_Fiji_Fan_Table;
+
+typedef struct _ATOM_Tonga_Thermal_Controller {
+	UCHAR ucRevId;
+	UCHAR ucType;		   /* one of ATOM_TONGA_PP_THERMALCONTROLLER_* */
+	UCHAR ucI2cLine;		/* as interpreted by DAL I2C */
+	UCHAR ucI2cAddress;
+	UCHAR ucFanParameters;	/* Fan Control Parameters. */
+	UCHAR ucFanMinRPM; 	 /* Fan Minimum RPM (hundreds) -- for display purposes only. */
+	UCHAR ucFanMaxRPM; 	 /* Fan Maximum RPM (hundreds) -- for display purposes only. */
+	UCHAR ucReserved;
+	UCHAR ucFlags;		   /* to be defined */
+} ATOM_Tonga_Thermal_Controller;
+
+typedef struct _ATOM_Tonga_VCE_State_Record {
+	UCHAR  ucVCEClockIndex;	/*index into usVCEDependencyTableOffset of 'ATOM_Tonga_MM_Dependency_Table' type */
+	UCHAR  ucFlag;		/* 2 bits indicates memory p-states */
+	UCHAR  ucSCLKIndex;		/*index into ATOM_Tonga_SCLK_Dependency_Table */
+	UCHAR  ucMCLKIndex;		/*index into ATOM_Tonga_MCLK_Dependency_Table */
+} ATOM_Tonga_VCE_State_Record;
+
+typedef struct _ATOM_Tonga_VCE_State_Table {
+	UCHAR ucRevId;
+	UCHAR ucNumEntries;
+	ATOM_Tonga_VCE_State_Record entries[1];
+} ATOM_Tonga_VCE_State_Table;
+
+typedef struct _ATOM_Tonga_PowerTune_Table {
+	UCHAR  ucRevId;
+	USHORT usTDP;
+	USHORT usConfigurableTDP;
+	USHORT usTDC;
+	USHORT usBatteryPowerLimit;
+	USHORT usSmallPowerLimit;
+	USHORT usLowCACLeakage;
+	USHORT usHighCACLeakage;
+	USHORT usMaximumPowerDeliveryLimit;
+	USHORT usTjMax;
+	USHORT usPowerTuneDataSetID;
+	USHORT usEDCLimit;
+	USHORT usSoftwareShutdownTemp;
+	USHORT usClockStretchAmount;
+	USHORT usReserve[2];
+} ATOM_Tonga_PowerTune_Table;
+
+typedef struct _ATOM_Fiji_PowerTune_Table {
+	UCHAR  ucRevId;
+	USHORT usTDP;
+	USHORT usConfigurableTDP;
+	USHORT usTDC;
+	USHORT usBatteryPowerLimit;
+	USHORT usSmallPowerLimit;
+	USHORT usLowCACLeakage;
+	USHORT usHighCACLeakage;
+	USHORT usMaximumPowerDeliveryLimit;
+	USHORT usTjMax;  /* For Fiji, this is also usTemperatureLimitEdge; */
+	USHORT usPowerTuneDataSetID;
+	USHORT usEDCLimit;
+	USHORT usSoftwareShutdownTemp;
+	USHORT usClockStretchAmount;
+	USHORT usTemperatureLimitHotspot;  /*The following are added for Fiji */
+	USHORT usTemperatureLimitLiquid1;
+	USHORT usTemperatureLimitLiquid2;
+	USHORT usTemperatureLimitVrVddc;
+	USHORT usTemperatureLimitVrMvdd;
+	USHORT usTemperatureLimitPlx;
+	UCHAR  ucLiquid1_I2C_address;  /*Liquid */
+	UCHAR  ucLiquid2_I2C_address;
+	UCHAR  ucLiquid_I2C_Line;
+	UCHAR  ucVr_I2C_address;	/*VR */
+	UCHAR  ucVr_I2C_Line;
+	UCHAR  ucPlx_I2C_address;  /*PLX */
+	UCHAR  ucPlx_I2C_Line;
+	USHORT usReserved;
+} ATOM_Fiji_PowerTune_Table;
+
+#define ATOM_PPM_A_A    1
+#define ATOM_PPM_A_I    2
+typedef struct _ATOM_Tonga_PPM_Table {
+	UCHAR   ucRevId;
+	UCHAR   ucPpmDesign;		  /*A+I or A+A */
+	USHORT  usCpuCoreNumber;
+	ULONG  ulPlatformTDP;
+	ULONG  ulSmallACPlatformTDP;
+	ULONG  ulPlatformTDC;
+	ULONG  ulSmallACPlatformTDC;
+	ULONG  ulApuTDP;
+	ULONG  ulDGpuTDP;
+	ULONG  ulDGpuUlvPower;
+	ULONG  ulTjmax;
+} ATOM_Tonga_PPM_Table;
+
+typedef struct _ATOM_Tonga_Hard_Limit_Record {
+	ULONG  ulSCLKLimit;
+	ULONG  ulMCLKLimit;
+	USHORT  usVddcLimit;
+	USHORT  usVddciLimit;
+	USHORT  usVddgfxLimit;
+} ATOM_Tonga_Hard_Limit_Record;
+
+typedef struct _ATOM_Tonga_Hard_Limit_Table {
+	UCHAR ucRevId;
+	UCHAR ucNumEntries;
+	ATOM_Tonga_Hard_Limit_Record entries[1];
+} ATOM_Tonga_Hard_Limit_Table;
+
+typedef struct _ATOM_Tonga_GPIO_Table {
+	UCHAR  ucRevId;
+	UCHAR  ucVRHotTriggeredSclkDpmIndex;		/* If VRHot signal is triggered SCLK will be limited to this DPM level */
+	UCHAR  ucReserve[5];
+} ATOM_Tonga_GPIO_Table;
+
+typedef struct _PPTable_Generic_SubTable_Header {
+	UCHAR  ucRevId;
+} PPTable_Generic_SubTable_Header;
+
+
+#pragma pack(pop)
+
+
+#endif
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_processpptables.c
@@ -0,0 +1,1142 @@
+/*
+ * Copyright 2015 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/fb.h>
+
+#include "tonga_processpptables.h"
+#include "ppatomctrl.h"
+#include "atombios.h"
+#include "pp_debug.h"
+#include "hwmgr.h"
+#include "cgs_common.h"
+#include "tonga_pptable.h"
+
+/**
+ * Private Function used during initialization.
+ * @param hwmgr Pointer to the hardware manager.
+ * @param setIt A flag indication if the capability should be set (TRUE) or reset (FALSE).
+ * @param cap Which capability to set/reset.
+ */
+static void set_hw_cap(struct pp_hwmgr *hwmgr, bool setIt, enum phm_platform_caps cap)
+{
+	if (setIt)
+		phm_cap_set(hwmgr->platform_descriptor.platformCaps, cap);
+	else
+		phm_cap_unset(hwmgr->platform_descriptor.platformCaps, cap);
+}
+
+
+/**
+ * Private Function used during initialization.
+ * @param hwmgr Pointer to the hardware manager.
+ * @param powerplay_caps the bit array (from BIOS) of capability bits.
+ * @exception the current implementation always returns 1.
+ */
+static int set_platform_caps(struct pp_hwmgr *hwmgr, uint32_t powerplay_caps)
+{
+	PP_ASSERT_WITH_CODE((~powerplay_caps & ____RETIRE16____),
+		"ATOM_PP_PLATFORM_CAP_ASPM_L1 is not supported!", continue);
+	PP_ASSERT_WITH_CODE((~powerplay_caps & ____RETIRE64____),
+		"ATOM_PP_PLATFORM_CAP_GEMINIPRIMARY is not supported!", continue);
+	PP_ASSERT_WITH_CODE((~powerplay_caps & ____RETIRE512____),
+		"ATOM_PP_PLATFORM_CAP_SIDEPORTCONTROL is not supported!", continue);
+	PP_ASSERT_WITH_CODE((~powerplay_caps & ____RETIRE1024____),
+		"ATOM_PP_PLATFORM_CAP_TURNOFFPLL_ASPML1 is not supported!", continue);
+	PP_ASSERT_WITH_CODE((~powerplay_caps & ____RETIRE2048____),
+		"ATOM_PP_PLATFORM_CAP_HTLINKCONTROL is not supported!", continue);
+
+	set_hw_cap(
+			hwmgr,
+			0 != (powerplay_caps & ATOM_TONGA_PP_PLATFORM_CAP_POWERPLAY),
+			PHM_PlatformCaps_PowerPlaySupport
+		  );
+
+	set_hw_cap(
+			hwmgr,
+			0 != (powerplay_caps & ATOM_TONGA_PP_PLATFORM_CAP_SBIOSPOWERSOURCE),
+			PHM_PlatformCaps_BiosPowerSourceControl
+		  );
+
+	set_hw_cap(
+			hwmgr,
+			0 != (powerplay_caps & ATOM_TONGA_PP_PLATFORM_CAP_HARDWAREDC),
+			PHM_PlatformCaps_AutomaticDCTransition
+		  );
+
+	set_hw_cap(
+			hwmgr,
+			0 != (powerplay_caps & ATOM_TONGA_PP_PLATFORM_CAP_MVDD_CONTROL),
+			PHM_PlatformCaps_EnableMVDDControl
+		  );
+
+	set_hw_cap(
+			hwmgr,
+			0 != (powerplay_caps & ATOM_TONGA_PP_PLATFORM_CAP_VDDCI_CONTROL),
+			PHM_PlatformCaps_ControlVDDCI
+		  );
+
+	set_hw_cap(
+			hwmgr,
+			0 != (powerplay_caps & ATOM_TONGA_PP_PLATFORM_CAP_VDDGFX_CONTROL),
+			PHM_PlatformCaps_ControlVDDGFX
+		  );
+
+	set_hw_cap(
+			hwmgr,
+			0 != (powerplay_caps & ATOM_TONGA_PP_PLATFORM_CAP_BACO),
+			PHM_PlatformCaps_BACO
+		  );
+
+	set_hw_cap(
+			hwmgr,
+			0 != (powerplay_caps & ATOM_TONGA_PP_PLATFORM_CAP_DISABLE_VOLTAGE_ISLAND),
+			PHM_PlatformCaps_DisableVoltageIsland
+		  );
+
+	set_hw_cap(
+			hwmgr,
+			0 != (powerplay_caps & ATOM_TONGA_PP_PLATFORM_COMBINE_PCC_WITH_THERMAL_SIGNAL),
+			PHM_PlatformCaps_CombinePCCWithThermalSignal
+		  );
+
+	set_hw_cap(
+			hwmgr,
+			0 != (powerplay_caps & ATOM_TONGA_PLATFORM_LOAD_POST_PRODUCTION_FIRMWARE),
+			PHM_PlatformCaps_LoadPostProductionFirmware
+		  );
+
+	return 0;
+}
+
+/**
+ * Private Function to get the PowerPlay Table Address.
+ */
+const void *get_powerplay_table(struct pp_hwmgr *hwmgr)
+{
+	int index = GetIndexIntoMasterTable(DATA, PowerPlayInfo);
+
+	u16 size;
+	u8 frev, crev;
+	void *table_address;
+
+	table_address = (ATOM_Tonga_POWERPLAYTABLE *)
+		cgs_atom_get_data_table(hwmgr->device, index, &size, &frev, &crev);
+
+	hwmgr->soft_pp_table = table_address;	/*Cache the result in RAM.*/
+
+	return table_address;
+}
+
+static int get_vddc_lookup_table(
+		struct pp_hwmgr	*hwmgr,
+		phm_ppt_v1_voltage_lookup_table	**lookup_table,
+		const ATOM_Tonga_Voltage_Lookup_Table	*vddc_lookup_pp_tables,
+		uint32_t	max_levels
+		)
+{
+	uint32_t table_size, i;
+	phm_ppt_v1_voltage_lookup_table *table;
+
+	PP_ASSERT_WITH_CODE((0 != vddc_lookup_pp_tables->ucNumEntries),
+		"Invalid CAC Leakage PowerPlay Table!", return 1);
+
+	table_size = sizeof(uint32_t) +
+		sizeof(phm_ppt_v1_voltage_lookup_record) * max_levels;
+
+	table = (phm_ppt_v1_voltage_lookup_table *)
+		kzalloc(table_size, GFP_KERNEL);
+
+	if (NULL == table)
+		return -ENOMEM;
+
+	memset(table, 0x00, table_size);
+
+	table->count = vddc_lookup_pp_tables->ucNumEntries;
+
+	for (i = 0; i < vddc_lookup_pp_tables->ucNumEntries; i++) {
+		table->entries[i].us_calculated = 0;
+		table->entries[i].us_vdd =
+			vddc_lookup_pp_tables->entries[i].usVdd;
+		table->entries[i].us_cac_low =
+			vddc_lookup_pp_tables->entries[i].usCACLow;
+		table->entries[i].us_cac_mid =
+			vddc_lookup_pp_tables->entries[i].usCACMid;
+		table->entries[i].us_cac_high =
+			vddc_lookup_pp_tables->entries[i].usCACHigh;
+	}
+
+	*lookup_table = table;
+
+	return 0;
+}
+
+/**
+ * Private Function used during initialization.
+ * Initialize Platform Power Management Parameter table
+ * @param hwmgr Pointer to the hardware manager.
+ * @param atom_ppm_table Pointer to PPM table in VBIOS
+ */
+static int get_platform_power_management_table(
+		struct pp_hwmgr *hwmgr,
+		ATOM_Tonga_PPM_Table *atom_ppm_table)
+{
+	struct phm_ppm_table *ptr = kzalloc(sizeof(ATOM_Tonga_PPM_Table), GFP_KERNEL);
+	struct phm_ppt_v1_information *pp_table_information =
+		(struct phm_ppt_v1_information *)(hwmgr->pptable);
+
+	if (NULL == ptr)
+		return -ENOMEM;
+
+	ptr->ppm_design
+		= atom_ppm_table->ucPpmDesign;
+	ptr->cpu_core_number
+		= atom_ppm_table->usCpuCoreNumber;
+	ptr->platform_tdp
+		= atom_ppm_table->ulPlatformTDP;
+	ptr->small_ac_platform_tdp
+		= atom_ppm_table->ulSmallACPlatformTDP;
+	ptr->platform_tdc
+		= atom_ppm_table->ulPlatformTDC;
+	ptr->small_ac_platform_tdc
+		= atom_ppm_table->ulSmallACPlatformTDC;
+	ptr->apu_tdp
+		= atom_ppm_table->ulApuTDP;
+	ptr->dgpu_tdp
+		= atom_ppm_table->ulDGpuTDP;
+	ptr->dgpu_ulv_power
+		= atom_ppm_table->ulDGpuUlvPower;
+	ptr->tj_max
+		= atom_ppm_table->ulTjmax;
+
+	pp_table_information->ppm_parameter_table = ptr;
+
+	return 0;
+}
+
+/**
+ * Private Function used during initialization.
+ * Initialize TDP limits for DPM2
+ * @param hwmgr Pointer to the hardware manager.
+ * @param powerplay_table Pointer to the PowerPlay Table.
+ */
+static int init_dpm_2_parameters(
+		struct pp_hwmgr *hwmgr,
+		const ATOM_Tonga_POWERPLAYTABLE *powerplay_table
+		)
+{
+	int result = 0;
+	struct phm_ppt_v1_information *pp_table_information = (struct phm_ppt_v1_information *)(hwmgr->pptable);
+	ATOM_Tonga_PPM_Table *atom_ppm_table;
+	uint32_t disable_ppm = 0;
+	uint32_t disable_power_control = 0;
+
+	pp_table_information->us_ulv_voltage_offset =
+		le16_to_cpu(powerplay_table->usUlvVoltageOffset);
+
+	pp_table_information->ppm_parameter_table = NULL;
+	pp_table_information->vddc_lookup_table = NULL;
+	pp_table_information->vddgfx_lookup_table = NULL;
+	/* TDP limits */
+	hwmgr->platform_descriptor.TDPODLimit =
+		le16_to_cpu(powerplay_table->usPowerControlLimit);
+	hwmgr->platform_descriptor.TDPAdjustment = 0;
+	hwmgr->platform_descriptor.VidAdjustment = 0;
+	hwmgr->platform_descriptor.VidAdjustmentPolarity = 0;
+	hwmgr->platform_descriptor.VidMinLimit = 0;
+	hwmgr->platform_descriptor.VidMaxLimit = 1500000;
+	hwmgr->platform_descriptor.VidStep = 6250;
+
+	disable_power_control = 0;
+	if (0 == disable_power_control) {
+		/* enable TDP overdrive (PowerControl) feature as well if supported */
+		if (hwmgr->platform_descriptor.TDPODLimit != 0)
+			phm_cap_set(hwmgr->platform_descriptor.platformCaps,
+			PHM_PlatformCaps_PowerControl);
+	}
+
+	if (0 != powerplay_table->usVddcLookupTableOffset) {
+		const ATOM_Tonga_Voltage_Lookup_Table *pVddcCACTable =
+			(ATOM_Tonga_Voltage_Lookup_Table *)(((unsigned long)powerplay_table) +
+			le16_to_cpu(powerplay_table->usVddcLookupTableOffset));
+
+		result = get_vddc_lookup_table(hwmgr,
+			&pp_table_information->vddc_lookup_table, pVddcCACTable, 16);
+	}
+
+	if (0 != powerplay_table->usVddgfxLookupTableOffset) {
+		const ATOM_Tonga_Voltage_Lookup_Table *pVddgfxCACTable =
+			(ATOM_Tonga_Voltage_Lookup_Table *)(((unsigned long)powerplay_table) +
+			le16_to_cpu(powerplay_table->usVddgfxLookupTableOffset));
+
+		result = get_vddc_lookup_table(hwmgr,
+			&pp_table_information->vddgfx_lookup_table, pVddgfxCACTable, 16);
+	}
+
+	disable_ppm = 0;
+	if (0 == disable_ppm) {
+		atom_ppm_table = (ATOM_Tonga_PPM_Table *)
+			(((unsigned long)powerplay_table) + le16_to_cpu(powerplay_table->usPPMTableOffset));
+
+		if (0 != powerplay_table->usPPMTableOffset) {
+			if (1 == get_platform_power_management_table(hwmgr, atom_ppm_table)) {
+				phm_cap_set(hwmgr->platform_descriptor.platformCaps,
+					PHM_PlatformCaps_EnablePlatformPowerManagement);
+			}
+		}
+	}
+
+	return result;
+}
+
+static int get_valid_clk(
+		struct pp_hwmgr *hwmgr,
+		struct phm_clock_array **clk_table,
+		const phm_ppt_v1_clock_voltage_dependency_table  * clk_volt_pp_table
+		)
+{
+	uint32_t table_size, i;
+	struct phm_clock_array *table;
+
+	PP_ASSERT_WITH_CODE((0 != clk_volt_pp_table->count),
+		"Invalid PowerPlay Table!", return -1);
+
+	table_size = sizeof(uint32_t) +
+		sizeof(uint32_t) * clk_volt_pp_table->count;
+
+	table = (struct phm_clock_array *)kzalloc(table_size, GFP_KERNEL);
+
+	if (NULL == table)
+		return -ENOMEM;
+
+	memset(table, 0x00, table_size);
+
+	table->count = (uint32_t)clk_volt_pp_table->count;
+
+	for (i = 0; i < table->count; i++)
+		table->values[i] = (uint32_t)clk_volt_pp_table->entries[i].clk;
+
+	*clk_table = table;
+
+	return 0;
+}
+
+static int get_hard_limits(
+		struct pp_hwmgr *hwmgr,
+		struct phm_clock_and_voltage_limits *limits,
+		const ATOM_Tonga_Hard_Limit_Table * limitable
+		)
+{
+	PP_ASSERT_WITH_CODE((0 != limitable->ucNumEntries), "Invalid PowerPlay Table!", return -1);
+
+	/* currently we always take entries[0] parameters */
+	limits->sclk = (uint32_t)limitable->entries[0].ulSCLKLimit;
+	limits->mclk = (uint32_t)limitable->entries[0].ulMCLKLimit;
+	limits->vddc = (uint16_t)limitable->entries[0].usVddcLimit;
+	limits->vddci = (uint16_t)limitable->entries[0].usVddciLimit;
+	limits->vddgfx = (uint16_t)limitable->entries[0].usVddgfxLimit;
+
+	return 0;
+}
+
+static int get_mclk_voltage_dependency_table(
+		struct pp_hwmgr *hwmgr,
+		phm_ppt_v1_clock_voltage_dependency_table **pp_tonga_mclk_dep_table,
+		const ATOM_Tonga_MCLK_Dependency_Table * mclk_dep_table
+		)
+{
+	uint32_t table_size, i;
+	phm_ppt_v1_clock_voltage_dependency_table *mclk_table;
+
+	PP_ASSERT_WITH_CODE((0 != mclk_dep_table->ucNumEntries),
+		"Invalid PowerPlay Table!", return -1);
+
+	table_size = sizeof(uint32_t) + sizeof(phm_ppt_v1_clock_voltage_dependency_record)
+		* mclk_dep_table->ucNumEntries;
+
+	mclk_table = (phm_ppt_v1_clock_voltage_dependency_table *)
+		kzalloc(table_size, GFP_KERNEL);
+
+	if (NULL == mclk_table)
+		return -ENOMEM;
+
+	memset(mclk_table, 0x00, table_size);
+
+	mclk_table->count = (uint32_t)mclk_dep_table->ucNumEntries;
+
+	for (i = 0; i < mclk_dep_table->ucNumEntries; i++) {
+		mclk_table->entries[i].vddInd =
+			mclk_dep_table->entries[i].ucVddcInd;
+		mclk_table->entries[i].vdd_offset =
+			mclk_dep_table->entries[i].usVddgfxOffset;
+		mclk_table->entries[i].vddci =
+			mclk_dep_table->entries[i].usVddci;
+		mclk_table->entries[i].mvdd =
+			mclk_dep_table->entries[i].usMvdd;
+		mclk_table->entries[i].clk =
+			mclk_dep_table->entries[i].ulMclk;
+	}
+
+	*pp_tonga_mclk_dep_table = mclk_table;
+
+	return 0;
+}
+
+static int get_sclk_voltage_dependency_table(
+		struct pp_hwmgr *hwmgr,
+		phm_ppt_v1_clock_voltage_dependency_table **pp_tonga_sclk_dep_table,
+		const ATOM_Tonga_SCLK_Dependency_Table * sclk_dep_table
+		)
+{
+	uint32_t table_size, i;
+	phm_ppt_v1_clock_voltage_dependency_table *sclk_table;
+
+	PP_ASSERT_WITH_CODE((0 != sclk_dep_table->ucNumEntries),
+		"Invalid PowerPlay Table!", return -1);
+
+	table_size = sizeof(uint32_t) + sizeof(phm_ppt_v1_clock_voltage_dependency_record)
+		* sclk_dep_table->ucNumEntries;
+
+	sclk_table = (phm_ppt_v1_clock_voltage_dependency_table *)
+		kzalloc(table_size, GFP_KERNEL);
+
+	if (NULL == sclk_table)
+		return -ENOMEM;
+
+	memset(sclk_table, 0x00, table_size);
+
+	sclk_table->count = (uint32_t)sclk_dep_table->ucNumEntries;
+
+	for (i = 0; i < sclk_dep_table->ucNumEntries; i++) {
+		sclk_table->entries[i].vddInd =
+			sclk_dep_table->entries[i].ucVddInd;
+		sclk_table->entries[i].vdd_offset =
+			sclk_dep_table->entries[i].usVddcOffset;
+		sclk_table->entries[i].clk =
+			sclk_dep_table->entries[i].ulSclk;
+		sclk_table->entries[i].cks_enable =
+			(((sclk_dep_table->entries[i].ucCKSVOffsetandDisable & 0x80) >> 7) == 0) ? 1 : 0;
+		sclk_table->entries[i].cks_voffset =
+			(sclk_dep_table->entries[i].ucCKSVOffsetandDisable & 0x7F);
+	}
+
+	*pp_tonga_sclk_dep_table = sclk_table;
+
+	return 0;
+}
+
+static int get_pcie_table(
+		struct pp_hwmgr *hwmgr,
+		phm_ppt_v1_pcie_table **pp_tonga_pcie_table,
+		const ATOM_Tonga_PCIE_Table * atom_pcie_table
+		)
+{
+	uint32_t table_size, i, pcie_count;
+	phm_ppt_v1_pcie_table *pcie_table;
+	struct phm_ppt_v1_information *pp_table_information =
+		(struct phm_ppt_v1_information *)(hwmgr->pptable);
+	PP_ASSERT_WITH_CODE((0 != atom_pcie_table->ucNumEntries),
+		"Invalid PowerPlay Table!", return -1);
+
+	table_size = sizeof(uint32_t) +
+		sizeof(phm_ppt_v1_pcie_record) * atom_pcie_table->ucNumEntries;
+
+	pcie_table = (phm_ppt_v1_pcie_table *)kzalloc(table_size, GFP_KERNEL);
+
+	if (NULL == pcie_table)
+		return -ENOMEM;
+
+	memset(pcie_table, 0x00, table_size);
+
+	/*
+	* Make sure the number of pcie entries are less than or equal to sclk dpm levels.
+	* Since first PCIE entry is for ULV, #pcie has to be <= SclkLevel + 1.
+	*/
+	pcie_count = (pp_table_information->vdd_dep_on_sclk->count) + 1;
+	if ((uint32_t)atom_pcie_table->ucNumEntries <= pcie_count)
+		pcie_count = (uint32_t)atom_pcie_table->ucNumEntries;
+	else
+		printk(KERN_ERR "[ powerplay ] Number of Pcie Entries exceed the number of SCLK Dpm Levels! \
+		Disregarding the excess entries... \n");
+
+	pcie_table->count = pcie_count;
+
+	for (i = 0; i < pcie_count; i++) {
+		pcie_table->entries[i].gen_speed =
+			atom_pcie_table->entries[i].ucPCIEGenSpeed;
+		pcie_table->entries[i].lane_width =
+			atom_pcie_table->entries[i].usPCIELaneWidth;
+	}
+
+	*pp_tonga_pcie_table = pcie_table;
+
+	return 0;
+}
+
+static int get_cac_tdp_table(
+		struct pp_hwmgr *hwmgr,
+		struct phm_cac_tdp_table **cac_tdp_table,
+		const PPTable_Generic_SubTable_Header * table
+		)
+{
+	uint32_t table_size;
+	struct phm_cac_tdp_table *tdp_table;
+
+	table_size = sizeof(uint32_t) + sizeof(struct phm_cac_tdp_table);
+	tdp_table = kzalloc(table_size, GFP_KERNEL);
+
+	if (NULL == tdp_table)
+		return -ENOMEM;
+
+	memset(tdp_table, 0x00, table_size);
+
+	hwmgr->dyn_state.cac_dtp_table = kzalloc(table_size, GFP_KERNEL);
+
+	if (NULL == hwmgr->dyn_state.cac_dtp_table)
+		return -ENOMEM;
+
+	memset(hwmgr->dyn_state.cac_dtp_table, 0x00, table_size);
+
+	if (table->ucRevId < 3) {
+		const ATOM_Tonga_PowerTune_Table *tonga_table =
+			(ATOM_Tonga_PowerTune_Table *)table;
+		tdp_table->usTDP = tonga_table->usTDP;
+		tdp_table->usConfigurableTDP =
+			tonga_table->usConfigurableTDP;
+		tdp_table->usTDC = tonga_table->usTDC;
+		tdp_table->usBatteryPowerLimit =
+			tonga_table->usBatteryPowerLimit;
+		tdp_table->usSmallPowerLimit =
+			tonga_table->usSmallPowerLimit;
+		tdp_table->usLowCACLeakage =
+			tonga_table->usLowCACLeakage;
+		tdp_table->usHighCACLeakage =
+			tonga_table->usHighCACLeakage;
+		tdp_table->usMaximumPowerDeliveryLimit =
+			tonga_table->usMaximumPowerDeliveryLimit;
+		tdp_table->usDefaultTargetOperatingTemp =
+			tonga_table->usTjMax;
+		tdp_table->usTargetOperatingTemp =
+			tonga_table->usTjMax; /*Set the initial temp to the same as default */
+		tdp_table->usPowerTuneDataSetID =
+			tonga_table->usPowerTuneDataSetID;
+		tdp_table->usSoftwareShutdownTemp =
+			tonga_table->usSoftwareShutdownTemp;
+		tdp_table->usClockStretchAmount =
+			tonga_table->usClockStretchAmount;
+	} else {   /* Fiji and newer */
+		const ATOM_Fiji_PowerTune_Table *fijitable =
+			(ATOM_Fiji_PowerTune_Table *)table;
+		tdp_table->usTDP = fijitable->usTDP;
+		tdp_table->usConfigurableTDP = fijitable->usConfigurableTDP;
+		tdp_table->usTDC = fijitable->usTDC;
+		tdp_table->usBatteryPowerLimit = fijitable->usBatteryPowerLimit;
+		tdp_table->usSmallPowerLimit = fijitable->usSmallPowerLimit;
+		tdp_table->usLowCACLeakage = fijitable->usLowCACLeakage;
+		tdp_table->usHighCACLeakage = fijitable->usHighCACLeakage;
+		tdp_table->usMaximumPowerDeliveryLimit =
+			fijitable->usMaximumPowerDeliveryLimit;
+		tdp_table->usDefaultTargetOperatingTemp =
+			fijitable->usTjMax;
+		tdp_table->usTargetOperatingTemp =
+			fijitable->usTjMax; /*Set the initial temp to the same as default */
+		tdp_table->usPowerTuneDataSetID =
+			fijitable->usPowerTuneDataSetID;
+		tdp_table->usSoftwareShutdownTemp =
+			fijitable->usSoftwareShutdownTemp;
+		tdp_table->usClockStretchAmount =
+			fijitable->usClockStretchAmount;
+		tdp_table->usTemperatureLimitHotspot =
+			fijitable->usTemperatureLimitHotspot;
+		tdp_table->usTemperatureLimitLiquid1 =
+			fijitable->usTemperatureLimitLiquid1;
+		tdp_table->usTemperatureLimitLiquid2 =
+			fijitable->usTemperatureLimitLiquid2;
+		tdp_table->usTemperatureLimitVrVddc =
+			fijitable->usTemperatureLimitVrVddc;
+		tdp_table->usTemperatureLimitVrMvdd =
+			fijitable->usTemperatureLimitVrMvdd;
+		tdp_table->usTemperatureLimitPlx =
+			fijitable->usTemperatureLimitPlx;
+		tdp_table->ucLiquid1_I2C_address =
+			fijitable->ucLiquid1_I2C_address;
+		tdp_table->ucLiquid2_I2C_address =
+			fijitable->ucLiquid2_I2C_address;
+		tdp_table->ucLiquid_I2C_Line =
+			fijitable->ucLiquid_I2C_Line;
+		tdp_table->ucVr_I2C_address = fijitable->ucVr_I2C_address;
+		tdp_table->ucVr_I2C_Line = fijitable->ucVr_I2C_Line;
+		tdp_table->ucPlx_I2C_address = fijitable->ucPlx_I2C_address;
+		tdp_table->ucPlx_I2C_Line = fijitable->ucPlx_I2C_Line;
+	}
+
+	*cac_tdp_table = tdp_table;
+
+	return 0;
+}
+
+static int get_mm_clock_voltage_table(
+		struct pp_hwmgr *hwmgr,
+		phm_ppt_v1_mm_clock_voltage_dependency_table **tonga_mm_table,
+		const ATOM_Tonga_MM_Dependency_Table * mm_dependency_table
+		)
+{
+	uint32_t table_size, i;
+	const ATOM_Tonga_MM_Dependency_Record *mm_dependency_record;
+	phm_ppt_v1_mm_clock_voltage_dependency_table *mm_table;
+
+	PP_ASSERT_WITH_CODE((0 != mm_dependency_table->ucNumEntries),
+		"Invalid PowerPlay Table!", return -1);
+	table_size = sizeof(uint32_t) +
+		sizeof(phm_ppt_v1_mm_clock_voltage_dependency_record)
+		* mm_dependency_table->ucNumEntries;
+	mm_table = (phm_ppt_v1_mm_clock_voltage_dependency_table *)
+		kzalloc(table_size, GFP_KERNEL);
+
+	if (NULL == mm_table)
+		return -ENOMEM;
+
+	memset(mm_table, 0x00, table_size);
+
+	mm_table->count = mm_dependency_table->ucNumEntries;
+
+	for (i = 0; i < mm_dependency_table->ucNumEntries; i++) {
+		mm_dependency_record = &mm_dependency_table->entries[i];
+		mm_table->entries[i].vddcInd = mm_dependency_record->ucVddcInd;
+		mm_table->entries[i].vddgfx_offset = mm_dependency_record->usVddgfxOffset;
+		mm_table->entries[i].aclk = mm_dependency_record->ulAClk;
+		mm_table->entries[i].samclock = mm_dependency_record->ulSAMUClk;
+		mm_table->entries[i].eclk = mm_dependency_record->ulEClk;
+		mm_table->entries[i].vclk = mm_dependency_record->ulVClk;
+		mm_table->entries[i].dclk = mm_dependency_record->ulDClk;
+	}
+
+	*tonga_mm_table = mm_table;
+
+	return 0;
+}
+
+/**
+ * Private Function used during initialization.
+ * Initialize clock voltage dependency
+ * @param hwmgr Pointer to the hardware manager.
+ * @param powerplay_table Pointer to the PowerPlay Table.
+ */
+static int init_clock_voltage_dependency(
+		struct pp_hwmgr *hwmgr,
+		const ATOM_Tonga_POWERPLAYTABLE *powerplay_table
+		)
+{
+	int result = 0;
+	struct phm_ppt_v1_information *pp_table_information =
+		(struct phm_ppt_v1_information *)(hwmgr->pptable);
+
+	const ATOM_Tonga_MM_Dependency_Table *mm_dependency_table =
+		(const ATOM_Tonga_MM_Dependency_Table *)(((unsigned long) powerplay_table) +
+		le16_to_cpu(powerplay_table->usMMDependencyTableOffset));
+	const PPTable_Generic_SubTable_Header *pPowerTuneTable =
+		(const PPTable_Generic_SubTable_Header *)(((unsigned long) powerplay_table) +
+		le16_to_cpu(powerplay_table->usPowerTuneTableOffset));
+	const ATOM_Tonga_MCLK_Dependency_Table *mclk_dep_table =
+		(const ATOM_Tonga_MCLK_Dependency_Table *)(((unsigned long) powerplay_table) +
+		le16_to_cpu(powerplay_table->usMclkDependencyTableOffset));
+	const ATOM_Tonga_SCLK_Dependency_Table *sclk_dep_table =
+		(const ATOM_Tonga_SCLK_Dependency_Table *)(((unsigned long) powerplay_table) +
+		le16_to_cpu(powerplay_table->usSclkDependencyTableOffset));
+	const ATOM_Tonga_Hard_Limit_Table *pHardLimits =
+		(const ATOM_Tonga_Hard_Limit_Table *)(((unsigned long) powerplay_table) +
+		le16_to_cpu(powerplay_table->usHardLimitTableOffset));
+	const ATOM_Tonga_PCIE_Table *pcie_table =
+		(const ATOM_Tonga_PCIE_Table *)(((unsigned long) powerplay_table) +
+		le16_to_cpu(powerplay_table->usPCIETableOffset));
+
+	pp_table_information->vdd_dep_on_sclk = NULL;
+	pp_table_information->vdd_dep_on_mclk = NULL;
+	pp_table_information->mm_dep_table = NULL;
+	pp_table_information->pcie_table = NULL;
+
+	if (powerplay_table->usMMDependencyTableOffset != 0)
+		result = get_mm_clock_voltage_table(hwmgr,
+		&pp_table_information->mm_dep_table, mm_dependency_table);
+
+	if (result == 0 && powerplay_table->usPowerTuneTableOffset != 0)
+		result = get_cac_tdp_table(hwmgr,
+		&pp_table_information->cac_dtp_table, pPowerTuneTable);
+
+	if (result == 0 && powerplay_table->usSclkDependencyTableOffset != 0)
+		result = get_sclk_voltage_dependency_table(hwmgr,
+		&pp_table_information->vdd_dep_on_sclk, sclk_dep_table);
+
+	if (result == 0 && powerplay_table->usMclkDependencyTableOffset != 0)
+		result = get_mclk_voltage_dependency_table(hwmgr,
+		&pp_table_information->vdd_dep_on_mclk, mclk_dep_table);
+
+	if (result == 0 && powerplay_table->usPCIETableOffset != 0)
+		result = get_pcie_table(hwmgr,
+		&pp_table_information->pcie_table, pcie_table);
+
+	if (result == 0 && powerplay_table->usHardLimitTableOffset != 0)
+		result = get_hard_limits(hwmgr,
+		&pp_table_information->max_clock_voltage_on_dc, pHardLimits);
+
+	hwmgr->dyn_state.max_clock_voltage_on_dc.sclk =
+		pp_table_information->max_clock_voltage_on_dc.sclk;
+	hwmgr->dyn_state.max_clock_voltage_on_dc.mclk =
+		pp_table_information->max_clock_voltage_on_dc.mclk;
+	hwmgr->dyn_state.max_clock_voltage_on_dc.vddc =
+		pp_table_information->max_clock_voltage_on_dc.vddc;
+	hwmgr->dyn_state.max_clock_voltage_on_dc.vddci =
+		pp_table_information->max_clock_voltage_on_dc.vddci;
+
+	if (result == 0 && (NULL != pp_table_information->vdd_dep_on_mclk)
+		&& (0 != pp_table_information->vdd_dep_on_mclk->count))
+		result = get_valid_clk(hwmgr, &pp_table_information->valid_mclk_values,
+		pp_table_information->vdd_dep_on_mclk);
+
+	if (result == 0 && (NULL != pp_table_information->vdd_dep_on_sclk)
+		&& (0 != pp_table_information->vdd_dep_on_sclk->count))
+		result = get_valid_clk(hwmgr, &pp_table_information->valid_sclk_values,
+		pp_table_information->vdd_dep_on_sclk);
+
+	return result;
+}
+
+/** Retrieves the (signed) Overdrive limits from VBIOS.
+ * The max engine clock, memory clock and max temperature come from the firmware info table.
+ *
+ * The information is placed into the platform descriptor.
+ *
+ * @param hwmgr source of the VBIOS table and owner of the platform descriptor to be updated.
+ * @param powerplay_table the address of the PowerPlay table.
+ *
+ * @return 1 as long as the firmware info table was present and of a supported version.
+ */
+static int init_over_drive_limits(
+		struct pp_hwmgr *hwmgr,
+		const ATOM_Tonga_POWERPLAYTABLE *powerplay_table)
+{
+	hwmgr->platform_descriptor.overdriveLimit.engineClock =
+		le16_to_cpu(powerplay_table->ulMaxODEngineClock);
+	hwmgr->platform_descriptor.overdriveLimit.memoryClock =
+		le16_to_cpu(powerplay_table->ulMaxODMemoryClock);
+
+	hwmgr->platform_descriptor.minOverdriveVDDC = 0;
+	hwmgr->platform_descriptor.maxOverdriveVDDC = 0;
+	hwmgr->platform_descriptor.overdriveVDDCStep = 0;
+
+	if (hwmgr->platform_descriptor.overdriveLimit.engineClock > 0 \
+		&& hwmgr->platform_descriptor.overdriveLimit.memoryClock > 0) {
+		phm_cap_set(hwmgr->platform_descriptor.platformCaps,
+			PHM_PlatformCaps_ACOverdriveSupport);
+	}
+
+	return 0;
+}
+
+/**
+ * Private Function used during initialization.
+ * Inspect the PowerPlay table for obvious signs of corruption.
+ * @param hwmgr Pointer to the hardware manager.
+ * @param powerplay_table Pointer to the PowerPlay Table.
+ * @exception This implementation always returns 1.
+ */
+static int init_thermal_controller(
+		struct pp_hwmgr *hwmgr,
+		const ATOM_Tonga_POWERPLAYTABLE *powerplay_table
+		)
+{
+	const PPTable_Generic_SubTable_Header *fan_table;
+	ATOM_Tonga_Thermal_Controller *thermal_controller;
+
+	thermal_controller = (ATOM_Tonga_Thermal_Controller *)
+		(((unsigned long)powerplay_table) +
+		le16_to_cpu(powerplay_table->usThermalControllerOffset));
+	PP_ASSERT_WITH_CODE((0 != powerplay_table->usThermalControllerOffset),
+		"Thermal controller table not set!", return -1);
+
+	hwmgr->thermal_controller.ucType = thermal_controller->ucType;
+	hwmgr->thermal_controller.ucI2cLine = thermal_controller->ucI2cLine;
+	hwmgr->thermal_controller.ucI2cAddress = thermal_controller->ucI2cAddress;
+
+	hwmgr->thermal_controller.fanInfo.bNoFan =
+		(0 != (thermal_controller->ucFanParameters & ATOM_TONGA_PP_FANPARAMETERS_NOFAN));
+
+	hwmgr->thermal_controller.fanInfo.ucTachometerPulsesPerRevolution =
+		thermal_controller->ucFanParameters &
+		ATOM_TONGA_PP_FANPARAMETERS_TACHOMETER_PULSES_PER_REVOLUTION_MASK;
+
+	hwmgr->thermal_controller.fanInfo.ulMinRPM
+		= thermal_controller->ucFanMinRPM * 100UL;
+	hwmgr->thermal_controller.fanInfo.ulMaxRPM
+		= thermal_controller->ucFanMaxRPM * 100UL;
+
+	set_hw_cap(
+			hwmgr,
+			ATOM_TONGA_PP_THERMALCONTROLLER_NONE != hwmgr->thermal_controller.ucType,
+			PHM_PlatformCaps_ThermalController
+		  );
+
+	if (0 == powerplay_table->usFanTableOffset)
+		return 0;
+
+	fan_table = (const PPTable_Generic_SubTable_Header *)
+		(((unsigned long)powerplay_table) +
+		le16_to_cpu(powerplay_table->usFanTableOffset));
+
+	PP_ASSERT_WITH_CODE((0 != powerplay_table->usFanTableOffset),
+		"Fan table not set!", return -1);
+	PP_ASSERT_WITH_CODE((0 < fan_table->ucRevId),
+		"Unsupported fan table format!", return -1);
+
+	hwmgr->thermal_controller.advanceFanControlParameters.ulCycleDelay
+		= 100000;
+	phm_cap_set(hwmgr->platform_descriptor.platformCaps,
+		PHM_PlatformCaps_MicrocodeFanControl);
+
+	if (fan_table->ucRevId < 8) {
+		const ATOM_Tonga_Fan_Table *tonga_fan_table =
+			(ATOM_Tonga_Fan_Table *)fan_table;
+		hwmgr->thermal_controller.advanceFanControlParameters.ucTHyst
+			= tonga_fan_table->ucTHyst;
+		hwmgr->thermal_controller.advanceFanControlParameters.usTMin
+			= tonga_fan_table->usTMin;
+		hwmgr->thermal_controller.advanceFanControlParameters.usTMed
+			= tonga_fan_table->usTMed;
+		hwmgr->thermal_controller.advanceFanControlParameters.usTHigh
+			= tonga_fan_table->usTHigh;
+		hwmgr->thermal_controller.advanceFanControlParameters.usPWMMin
+			= tonga_fan_table->usPWMMin;
+		hwmgr->thermal_controller.advanceFanControlParameters.usPWMMed
+			= tonga_fan_table->usPWMMed;
+		hwmgr->thermal_controller.advanceFanControlParameters.usPWMHigh
+			= tonga_fan_table->usPWMHigh;
+		hwmgr->thermal_controller.advanceFanControlParameters.usTMax
+			= 10900;                  /* hard coded */
+		hwmgr->thermal_controller.advanceFanControlParameters.usTMax
+			= tonga_fan_table->usTMax;
+		hwmgr->thermal_controller.advanceFanControlParameters.ucFanControlMode
+			= tonga_fan_table->ucFanControlMode;
+		hwmgr->thermal_controller.advanceFanControlParameters.usDefaultMaxFanPWM
+			= tonga_fan_table->usFanPWMMax;
+		hwmgr->thermal_controller.advanceFanControlParameters.usDefaultFanOutputSensitivity
+			= 4836;
+		hwmgr->thermal_controller.advanceFanControlParameters.usFanOutputSensitivity
+			= tonga_fan_table->usFanOutputSensitivity;
+		hwmgr->thermal_controller.advanceFanControlParameters.usDefaultMaxFanRPM
+			= tonga_fan_table->usFanRPMMax;
+		hwmgr->thermal_controller.advanceFanControlParameters.ulMinFanSCLKAcousticLimit
+			= (tonga_fan_table->ulMinFanSCLKAcousticLimit / 100); /* PPTable stores it in 10Khz unit for 2 decimal places.  SMC wants MHz. */
+		hwmgr->thermal_controller.advanceFanControlParameters.ucTargetTemperature
+			= tonga_fan_table->ucTargetTemperature;
+		hwmgr->thermal_controller.advanceFanControlParameters.ucMinimumPWMLimit
+			= tonga_fan_table->ucMinimumPWMLimit;
+	} else {
+		const ATOM_Fiji_Fan_Table *fiji_fan_table =
+			(ATOM_Fiji_Fan_Table *)fan_table;
+		hwmgr->thermal_controller.advanceFanControlParameters.ucTHyst
+			= fiji_fan_table->ucTHyst;
+		hwmgr->thermal_controller.advanceFanControlParameters.usTMin
+			= fiji_fan_table->usTMin;
+		hwmgr->thermal_controller.advanceFanControlParameters.usTMed
+			= fiji_fan_table->usTMed;
+		hwmgr->thermal_controller.advanceFanControlParameters.usTHigh
+			= fiji_fan_table->usTHigh;
+		hwmgr->thermal_controller.advanceFanControlParameters.usPWMMin
+			= fiji_fan_table->usPWMMin;
+		hwmgr->thermal_controller.advanceFanControlParameters.usPWMMed
+			= fiji_fan_table->usPWMMed;
+		hwmgr->thermal_controller.advanceFanControlParameters.usPWMHigh
+			= fiji_fan_table->usPWMHigh;
+		hwmgr->thermal_controller.advanceFanControlParameters.usTMax
+			= fiji_fan_table->usTMax;
+		hwmgr->thermal_controller.advanceFanControlParameters.ucFanControlMode
+			= fiji_fan_table->ucFanControlMode;
+		hwmgr->thermal_controller.advanceFanControlParameters.usDefaultMaxFanPWM
+			= fiji_fan_table->usFanPWMMax;
+		hwmgr->thermal_controller.advanceFanControlParameters.usDefaultFanOutputSensitivity
+			= 4836;
+		hwmgr->thermal_controller.advanceFanControlParameters.usFanOutputSensitivity
+			= fiji_fan_table->usFanOutputSensitivity;
+		hwmgr->thermal_controller.advanceFanControlParameters.usDefaultMaxFanRPM
+			= fiji_fan_table->usFanRPMMax;
+		hwmgr->thermal_controller.advanceFanControlParameters.ulMinFanSCLKAcousticLimit
+			= (fiji_fan_table->ulMinFanSCLKAcousticLimit / 100); /* PPTable stores it in 10Khz unit for 2 decimal places.  SMC wants MHz. */
+		hwmgr->thermal_controller.advanceFanControlParameters.ucTargetTemperature
+			= fiji_fan_table->ucTargetTemperature;
+		hwmgr->thermal_controller.advanceFanControlParameters.ucMinimumPWMLimit
+			= fiji_fan_table->ucMinimumPWMLimit;
+
+		hwmgr->thermal_controller.advanceFanControlParameters.usFanGainEdge
+			= fiji_fan_table->usFanGainEdge;
+		hwmgr->thermal_controller.advanceFanControlParameters.usFanGainHotspot
+			= fiji_fan_table->usFanGainHotspot;
+		hwmgr->thermal_controller.advanceFanControlParameters.usFanGainLiquid
+			= fiji_fan_table->usFanGainLiquid;
+		hwmgr->thermal_controller.advanceFanControlParameters.usFanGainVrVddc
+			= fiji_fan_table->usFanGainVrVddc;
+		hwmgr->thermal_controller.advanceFanControlParameters.usFanGainVrMvdd
+			= fiji_fan_table->usFanGainVrMvdd;
+		hwmgr->thermal_controller.advanceFanControlParameters.usFanGainPlx
+			= fiji_fan_table->usFanGainPlx;
+		hwmgr->thermal_controller.advanceFanControlParameters.usFanGainHbm
+			= fiji_fan_table->usFanGainHbm;
+	}
+
+	return 0;
+}
+
+/**
+ * Private Function used during initialization.
+ * Inspect the PowerPlay table for obvious signs of corruption.
+ * @param hwmgr Pointer to the hardware manager.
+ * @param powerplay_table Pointer to the PowerPlay Table.
+ * @exception 2 if the powerplay table is incorrect.
+ */
+static int check_powerplay_tables(
+		struct pp_hwmgr *hwmgr,
+		const ATOM_Tonga_POWERPLAYTABLE *powerplay_table
+		)
+{
+	const ATOM_Tonga_State_Array *state_arrays;
+
+	state_arrays = (ATOM_Tonga_State_Array *)(((unsigned long)powerplay_table) +
+		le16_to_cpu(powerplay_table->usStateArrayOffset));
+
+	PP_ASSERT_WITH_CODE((ATOM_Tonga_TABLE_REVISION_TONGA <=
+		powerplay_table->sHeader.ucTableFormatRevision),
+		"Unsupported PPTable format!", return -1);
+	PP_ASSERT_WITH_CODE((0 != powerplay_table->usStateArrayOffset),
+		"State table is not set!", return -1);
+	PP_ASSERT_WITH_CODE((0 < powerplay_table->sHeader.usStructureSize),
+		"Invalid PowerPlay Table!", return -1);
+	PP_ASSERT_WITH_CODE((0 < state_arrays->ucNumEntries),
+		"Invalid PowerPlay Table!", return -1);
+
+	return 0;
+}
+
+int tonga_pp_tables_initialize(struct pp_hwmgr *hwmgr)
+{
+	int result = 0;
+	const ATOM_Tonga_POWERPLAYTABLE *powerplay_table;
+
+	hwmgr->pptable = kzalloc(sizeof(struct phm_ppt_v1_information), GFP_KERNEL);
+
+	PP_ASSERT_WITH_CODE((NULL != hwmgr->pptable),
+			    "Failed to allocate hwmgr->pptable!", return -ENOMEM);
+
+	memset(hwmgr->pptable, 0x00, sizeof(struct phm_ppt_v1_information));
+
+	powerplay_table = get_powerplay_table(hwmgr);
+
+	PP_ASSERT_WITH_CODE((NULL != powerplay_table),
+		"Missing PowerPlay Table!", return -1);
+
+	result = check_powerplay_tables(hwmgr, powerplay_table);
+
+	PP_ASSERT_WITH_CODE((result == 0),
+			    "check_powerplay_tables failed", return result);
+
+	result = set_platform_caps(hwmgr,
+				   le32_to_cpu(powerplay_table->ulPlatformCaps));
+
+	PP_ASSERT_WITH_CODE((result == 0),
+			    "set_platform_caps failed", return result);
+
+	result = init_thermal_controller(hwmgr, powerplay_table);
+
+	PP_ASSERT_WITH_CODE((result == 0),
+			    "init_thermal_controller failed", return result);
+
+	result = init_over_drive_limits(hwmgr, powerplay_table);
+
+	PP_ASSERT_WITH_CODE((result == 0),
+			    "init_over_drive_limits failed", return result);
+
+	result = init_clock_voltage_dependency(hwmgr, powerplay_table);
+
+	PP_ASSERT_WITH_CODE((result == 0),
+			    "init_clock_voltage_dependency failed", return result);
+
+	result = init_dpm_2_parameters(hwmgr, powerplay_table);
+
+	PP_ASSERT_WITH_CODE((result == 0),
+			    "init_dpm_2_parameters failed", return result);
+
+	return result;
+}
+
+int tonga_pp_tables_uninitialize(struct pp_hwmgr *hwmgr)
+{
+	int result = 0;
+	struct phm_ppt_v1_information *pp_table_information =
+		(struct phm_ppt_v1_information *)(hwmgr->pptable);
+
+	if (NULL != hwmgr->soft_pp_table) {
+		kfree(hwmgr->soft_pp_table);
+		hwmgr->soft_pp_table = NULL;
+	}
+
+	if (NULL != pp_table_information->vdd_dep_on_sclk)
+		pp_table_information->vdd_dep_on_sclk = NULL;
+
+	if (NULL != pp_table_information->vdd_dep_on_mclk)
+		pp_table_information->vdd_dep_on_mclk = NULL;
+
+	if (NULL != pp_table_information->valid_mclk_values)
+		pp_table_information->valid_mclk_values = NULL;
+
+	if (NULL != pp_table_information->valid_sclk_values)
+		pp_table_information->valid_sclk_values = NULL;
+
+	if (NULL != pp_table_information->vddc_lookup_table)
+		pp_table_information->vddc_lookup_table = NULL;
+
+	if (NULL != pp_table_information->vddgfx_lookup_table)
+		pp_table_information->vddgfx_lookup_table = NULL;
+
+	if (NULL != pp_table_information->mm_dep_table)
+		pp_table_information->mm_dep_table = NULL;
+
+	if (NULL != pp_table_information->cac_dtp_table)
+		pp_table_information->cac_dtp_table = NULL;
+
+	if (NULL != hwmgr->dyn_state.cac_dtp_table)
+		hwmgr->dyn_state.cac_dtp_table = NULL;
+
+	if (NULL != pp_table_information->ppm_parameter_table)
+		pp_table_information->ppm_parameter_table = NULL;
+
+	if (NULL != pp_table_information->pcie_table)
+		pp_table_information->pcie_table = NULL;
+
+	if (NULL != hwmgr->pptable) {
+		kfree(hwmgr->pptable);
+		hwmgr->pptable = NULL;
+	}
+
+	return result;
+}
+
+const struct pp_table_func tonga_pptable_funcs = {
+	.pptable_init = tonga_pp_tables_initialize,
+	.pptable_fini = tonga_pp_tables_uninitialize,
+};
+
+int tonga_get_number_of_powerplay_table_entries(struct pp_hwmgr *hwmgr)
+{
+	const ATOM_Tonga_State_Array * state_arrays;
+	const ATOM_Tonga_POWERPLAYTABLE *pp_table = get_powerplay_table(hwmgr);
+
+	PP_ASSERT_WITH_CODE((NULL != pp_table),
+			"Missing PowerPlay Table!", return -1);
+	PP_ASSERT_WITH_CODE((pp_table->sHeader.ucTableFormatRevision >=
+			ATOM_Tonga_TABLE_REVISION_TONGA),
+			"Incorrect PowerPlay table revision!", return -1);
+
+	state_arrays = (ATOM_Tonga_State_Array *)(((unsigned long)pp_table) +
+			le16_to_cpu(pp_table->usStateArrayOffset));
+
+	return (uint32_t)(state_arrays->ucNumEntries);
+}
+
+/**
+* Private function to convert flags stored in the BIOS to software flags in PowerPlay.
+*/
+static uint32_t make_classification_flags(struct pp_hwmgr *hwmgr,
+		uint16_t classification, uint16_t classification2)
+{
+	uint32_t result = 0;
+
+	if (classification & ATOM_PPLIB_CLASSIFICATION_BOOT)
+		result |= PP_StateClassificationFlag_Boot;
+
+	if (classification & ATOM_PPLIB_CLASSIFICATION_THERMAL)
+		result |= PP_StateClassificationFlag_Thermal;
+
+	if (classification & ATOM_PPLIB_CLASSIFICATION_LIMITEDPOWERSOURCE)
+		result |= PP_StateClassificationFlag_LimitedPowerSource;
+
+	if (classification & ATOM_PPLIB_CLASSIFICATION_REST)
+		result |= PP_StateClassificationFlag_Rest;
+
+	if (classification & ATOM_PPLIB_CLASSIFICATION_FORCED)
+		result |= PP_StateClassificationFlag_Forced;
+
+	if (classification & ATOM_PPLIB_CLASSIFICATION_ACPI)
+		result |= PP_StateClassificationFlag_ACPI;
+
+	if (classification2 & ATOM_PPLIB_CLASSIFICATION2_LIMITEDPOWERSOURCE_2)
+		result |= PP_StateClassificationFlag_LimitedPowerSource_2;
+
+	return result;
+}
+
+/**
+* Create a Power State out of an entry in the PowerPlay table.
+* This function is called by the hardware back-end.
+* @param hwmgr Pointer to the hardware manager.
+* @param entry_index The index of the entry to be extracted from the table.
+* @param power_state The address of the PowerState instance being created.
+* @return -1 if the entry cannot be retrieved.
+*/
+int tonga_get_powerplay_table_entry(struct pp_hwmgr *hwmgr,
+		uint32_t entry_index, struct pp_power_state *power_state,
+		int (*call_back_func)(struct pp_hwmgr *, void *,
+				struct pp_power_state *, void *, uint32_t))
+{
+	int result = 0;
+	const ATOM_Tonga_State_Array * state_arrays;
+	const ATOM_Tonga_State *state_entry;
+	const ATOM_Tonga_POWERPLAYTABLE *pp_table = get_powerplay_table(hwmgr);
+
+	PP_ASSERT_WITH_CODE((NULL != pp_table), "Missing PowerPlay Table!", return -1;);
+	power_state->classification.bios_index = entry_index;
+
+	if (pp_table->sHeader.ucTableFormatRevision >=
+			ATOM_Tonga_TABLE_REVISION_TONGA) {
+		state_arrays = (ATOM_Tonga_State_Array *)(((unsigned long)pp_table) +
+				le16_to_cpu(pp_table->usStateArrayOffset));
+
+		PP_ASSERT_WITH_CODE((0 < pp_table->usStateArrayOffset),
+				"Invalid PowerPlay Table State Array Offset.", return -1);
+		PP_ASSERT_WITH_CODE((0 < state_arrays->ucNumEntries),
+				"Invalid PowerPlay Table State Array.", return -1);
+		PP_ASSERT_WITH_CODE((entry_index <= state_arrays->ucNumEntries),
+				"Invalid PowerPlay Table State Array Entry.", return -1);
+
+		state_entry = &(state_arrays->states[entry_index]);
+
+		result = call_back_func(hwmgr, (void *)state_entry, power_state,
+				(void *)pp_table,
+				make_classification_flags(hwmgr,
+					le16_to_cpu(state_entry->usClassification),
+					le16_to_cpu(state_entry->usClassification2)));
+	}
+
+	if (!result && (power_state->classification.flags &
+			PP_StateClassificationFlag_Boot))
+		result = hwmgr->hwmgr_func->patch_boot_state(hwmgr, &(power_state->hardware));
+
+	return result;
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_processpptables.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2015 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+#ifndef TONGA_PROCESSPPTABLES_H
+#define TONGA_PROCESSPPTABLES_H
+
+#include "hwmgr.h"
+
+extern const struct pp_table_func tonga_pptable_funcs;
+extern int tonga_get_number_of_powerplay_table_entries(struct pp_hwmgr *hwmgr);
+extern int tonga_get_powerplay_table_entry(struct pp_hwmgr *hwmgr, uint32_t entry_index,
+		struct pp_power_state *power_state, int (*call_back_func)(struct pp_hwmgr *, void *,
+				struct pp_power_state *, void *, uint32_t));
+
+#endif
+
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_thermal.c
@@ -0,0 +1,587 @@
+/*
+ * Copyright 2015 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+#include <asm/div64.h>
+#include "tonga_thermal.h"
+#include "tonga_hwmgr.h"
+#include "tonga_smumgr.h"
+#include "tonga_ppsmc.h"
+#include "smu/smu_7_1_2_d.h"
+#include "smu/smu_7_1_2_sh_mask.h"
+
+/**
+* Get Fan Speed Control Parameters.
+* @param    hwmgr  the address of the powerplay hardware manager.
+* @param    pSpeed is the address of the structure where the result is to be placed.
+* @exception Always succeeds except if we cannot zero out the output structure.
+*/
+int tonga_fan_ctrl_get_fan_speed_info(struct pp_hwmgr *hwmgr, struct phm_fan_speed_info *fan_speed_info)
+{
+
+	if (hwmgr->thermal_controller.fanInfo.bNoFan)
+		return 0;
+
+	fan_speed_info->supports_percent_read = true;
+	fan_speed_info->supports_percent_write = true;
+	fan_speed_info->min_percent = 0;
+	fan_speed_info->max_percent = 100;
+
+	if (0 != hwmgr->thermal_controller.fanInfo.ucTachometerPulsesPerRevolution) {
+		fan_speed_info->supports_rpm_read = true;
+		fan_speed_info->supports_rpm_write = true;
+		fan_speed_info->min_rpm = hwmgr->thermal_controller.fanInfo.ulMinRPM;
+		fan_speed_info->max_rpm = hwmgr->thermal_controller.fanInfo.ulMaxRPM;
+	} else {
+		fan_speed_info->min_rpm = 0;
+		fan_speed_info->max_rpm = 0;
+	}
+
+	return 0;
+}
+
+/**
+* Get Fan Speed in percent.
+* @param    hwmgr  the address of the powerplay hardware manager.
+* @param    pSpeed is the address of the structure where the result is to be placed.
+* @exception Fails is the 100% setting appears to be 0.
+*/
+int tonga_fan_ctrl_get_fan_speed_percent(struct pp_hwmgr *hwmgr, uint32_t *speed)
+{
+	uint32_t duty100;
+	uint32_t duty;
+	uint64_t tmp64;
+
+	if (hwmgr->thermal_controller.fanInfo.bNoFan)
+		return 0;
+
+	duty100 = PHM_READ_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, CG_FDO_CTRL1, FMAX_DUTY100);
+	duty = PHM_READ_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, CG_THERMAL_STATUS, FDO_PWM_DUTY);
+
+	if (0 == duty100)
+		return -EINVAL;
+
+
+	tmp64 = (uint64_t)duty * 100;
+	do_div(tmp64, duty100);
+	*speed = (uint32_t)tmp64;
+
+	if (*speed > 100)
+		*speed = 100;
+
+	return 0;
+}
+
+/**
+* Get Fan Speed in RPM.
+* @param    hwmgr  the address of the powerplay hardware manager.
+* @param    speed is the address of the structure where the result is to be placed.
+* @exception Returns not supported if no fan is found or if pulses per revolution are not set
+*/
+int tonga_fan_ctrl_get_fan_speed_rpm(struct pp_hwmgr *hwmgr, uint32_t *speed)
+{
+	return 0;
+}
+
+/**
+* Set Fan Speed Control to static mode, so that the user can decide what speed to use.
+* @param    hwmgr  the address of the powerplay hardware manager.
+*           mode    the fan control mode, 0 default, 1 by percent, 5, by RPM
+* @exception Should always succeed.
+*/
+int tonga_fan_ctrl_set_static_mode(struct pp_hwmgr *hwmgr, uint32_t mode)
+{
+
+	if (hwmgr->fan_ctrl_is_in_default_mode) {
+		hwmgr->fan_ctrl_default_mode = PHM_READ_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, CG_FDO_CTRL2, FDO_PWM_MODE);
+		hwmgr->tmin = PHM_READ_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, CG_FDO_CTRL2, TMIN);
+		hwmgr->fan_ctrl_is_in_default_mode = false;
+	}
+
+	PHM_WRITE_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, CG_FDO_CTRL2, TMIN, 0);
+	PHM_WRITE_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, CG_FDO_CTRL2, FDO_PWM_MODE, mode);
+
+	return 0;
+}
+
+/**
+* Reset Fan Speed Control to default mode.
+* @param    hwmgr  the address of the powerplay hardware manager.
+* @exception Should always succeed.
+*/
+int tonga_fan_ctrl_set_default_mode(struct pp_hwmgr *hwmgr)
+{
+	if (!hwmgr->fan_ctrl_is_in_default_mode) {
+		PHM_WRITE_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, CG_FDO_CTRL2, FDO_PWM_MODE, hwmgr->fan_ctrl_default_mode);
+		PHM_WRITE_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, CG_FDO_CTRL2, TMIN, hwmgr->tmin);
+		hwmgr->fan_ctrl_is_in_default_mode = true;
+	}
+
+	return 0;
+}
+
+int tonga_fan_ctrl_start_smc_fan_control(struct pp_hwmgr *hwmgr)
+{
+	int result;
+
+	if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_ODFuzzyFanControlSupport)) {
+		cgs_write_register(hwmgr->device, mmSMC_MSG_ARG_0, FAN_CONTROL_FUZZY);
+		result = (smum_send_msg_to_smc(hwmgr->smumgr, PPSMC_StartFanControl) == 0) ?  0 : -EINVAL;
+/*
+		if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_FanSpeedInTableIsRPM))
+			hwmgr->set_max_fan_rpm_output(hwmgr, hwmgr->thermal_controller.advanceFanControlParameters.usMaxFanRPM);
+		else
+			hwmgr->set_max_fan_pwm_output(hwmgr, hwmgr->thermal_controller.advanceFanControlParameters.usMaxFanPWM);
+*/
+	} else {
+		cgs_write_register(hwmgr->device, mmSMC_MSG_ARG_0, FAN_CONTROL_TABLE);
+		result = (smum_send_msg_to_smc(hwmgr->smumgr, PPSMC_StartFanControl) == 0) ?  0 : -EINVAL;
+	}
+/* TO DO FOR SOME DEVICE ID 0X692b, send this msg return invalid command.
+	if (result == 0 && hwmgr->thermal_controller.advanceFanControlParameters.ucTargetTemperature != 0)
+		result = (0 == smum_send_msg_to_smc_with_parameter(hwmgr->smumgr, PPSMC_MSG_SetFanTemperatureTarget, \
+								hwmgr->thermal_controller.advanceFanControlParameters.ucTargetTemperature) ? 0 : -EINVAL);
+*/
+	return result;
+}
+
+
+int tonga_fan_ctrl_stop_smc_fan_control(struct pp_hwmgr *hwmgr)
+{
+	return (smum_send_msg_to_smc(hwmgr->smumgr, PPSMC_StopFanControl) == 0) ?  0 : -EINVAL;
+}
+
+/**
+* Set Fan Speed in percent.
+* @param    hwmgr  the address of the powerplay hardware manager.
+* @param    speed is the percentage value (0% - 100%) to be set.
+* @exception Fails is the 100% setting appears to be 0.
+*/
+int tonga_fan_ctrl_set_fan_speed_percent(struct pp_hwmgr *hwmgr, uint32_t speed)
+{
+	uint32_t duty100;
+	uint32_t duty;
+	uint64_t tmp64;
+
+	if (hwmgr->thermal_controller.fanInfo.bNoFan)
+		return -EINVAL;
+
+	if (speed > 100)
+		speed = 100;
+
+	if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_MicrocodeFanControl))
+		tonga_fan_ctrl_stop_smc_fan_control(hwmgr);
+
+	duty100 = PHM_READ_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, CG_FDO_CTRL1, FMAX_DUTY100);
+
+	if (0 == duty100)
+		return -EINVAL;
+
+	tmp64 = (uint64_t)speed * 100;
+	do_div(tmp64, duty100);
+	duty = (uint32_t)tmp64;
+
+	PHM_WRITE_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, CG_FDO_CTRL0, FDO_STATIC_DUTY, duty);
+
+	return tonga_fan_ctrl_set_static_mode(hwmgr, FDO_PWM_MODE_STATIC);
+}
+
+/**
+* Reset Fan Speed to default.
+* @param    hwmgr  the address of the powerplay hardware manager.
+* @exception Always succeeds.
+*/
+int tonga_fan_ctrl_reset_fan_speed_to_default(struct pp_hwmgr *hwmgr)
+{
+	int result;
+
+	if (hwmgr->thermal_controller.fanInfo.bNoFan)
+		return 0;
+
+	if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_MicrocodeFanControl)) {
+		result = tonga_fan_ctrl_set_static_mode(hwmgr, FDO_PWM_MODE_STATIC);
+		if (0 == result)
+			result = tonga_fan_ctrl_start_smc_fan_control(hwmgr);
+	} else
+		result = tonga_fan_ctrl_set_default_mode(hwmgr);
+
+	return result;
+}
+
+/**
+* Set Fan Speed in RPM.
+* @param    hwmgr  the address of the powerplay hardware manager.
+* @param    speed is the percentage value (min - max) to be set.
+* @exception Fails is the speed not lie between min and max.
+*/
+int tonga_fan_ctrl_set_fan_speed_rpm(struct pp_hwmgr *hwmgr, uint32_t speed)
+{
+	return 0;
+}
+
+/**
+* Reads the remote temperature from the SIslands thermal controller.
+*
+* @param    hwmgr The address of the hardware manager.
+*/
+int tonga_thermal_get_temperature(struct pp_hwmgr *hwmgr)
+{
+	int temp;
+
+	temp = PHM_READ_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, CG_MULT_THERMAL_STATUS, CTF_TEMP);
+
+/* Bit 9 means the reading is lower than the lowest usable value. */
+	if (0 != (0x200 & temp))
+		temp = TONGA_THERMAL_MAXIMUM_TEMP_READING;
+	else
+		temp = (temp & 0x1ff);
+
+	temp = temp * PP_TEMPERATURE_UNITS_PER_CENTIGRADES;
+
+	return temp;
+}
+
+/**
+* Set the requested temperature range for high and low alert signals
+*
+* @param    hwmgr The address of the hardware manager.
+* @param    range Temperature range to be programmed for high and low alert signals
+* @exception PP_Result_BadInput if the input data is not valid.
+*/
+static int tonga_thermal_set_temperature_range(struct pp_hwmgr *hwmgr, uint32_t low_temp, uint32_t high_temp)
+{
+	uint32_t low = TONGA_THERMAL_MINIMUM_ALERT_TEMP * PP_TEMPERATURE_UNITS_PER_CENTIGRADES;
+	uint32_t high = TONGA_THERMAL_MAXIMUM_ALERT_TEMP * PP_TEMPERATURE_UNITS_PER_CENTIGRADES;
+
+	if (low < low_temp)
+		low = low_temp;
+	if (high > high_temp)
+		high = high_temp;
+
+	if (low > high)
+		return -EINVAL;
+
+	PHM_WRITE_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, CG_THERMAL_INT, DIG_THERM_INTH, (high / PP_TEMPERATURE_UNITS_PER_CENTIGRADES));
+	PHM_WRITE_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, CG_THERMAL_INT, DIG_THERM_INTL, (low / PP_TEMPERATURE_UNITS_PER_CENTIGRADES));
+	PHM_WRITE_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, CG_THERMAL_CTRL, DIG_THERM_DPM, (high / PP_TEMPERATURE_UNITS_PER_CENTIGRADES));
+
+	return 0;
+}
+
+/**
+* Programs thermal controller one-time setting registers
+*
+* @param    hwmgr The address of the hardware manager.
+*/
+static int tonga_thermal_initialize(struct pp_hwmgr *hwmgr)
+{
+	if (0 != hwmgr->thermal_controller.fanInfo.ucTachometerPulsesPerRevolution)
+		PHM_WRITE_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC,
+						CG_TACH_CTRL, EDGE_PER_REV,
+						hwmgr->thermal_controller.fanInfo.ucTachometerPulsesPerRevolution - 1);
+
+	PHM_WRITE_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, CG_FDO_CTRL2, TACH_PWM_RESP_RATE, 0x28);
+
+	return 0;
+}
+
+/**
+* Enable thermal alerts on the RV770 thermal controller.
+*
+* @param    hwmgr The address of the hardware manager.
+*/
+static int tonga_thermal_enable_alert(struct pp_hwmgr *hwmgr)
+{
+	uint32_t alert;
+
+	alert = PHM_READ_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, CG_THERMAL_INT, THERM_INT_MASK);
+	alert &= ~(TONGA_THERMAL_HIGH_ALERT_MASK | TONGA_THERMAL_LOW_ALERT_MASK);
+	PHM_WRITE_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, CG_THERMAL_INT, THERM_INT_MASK, alert);
+
+	/* send message to SMU to enable internal thermal interrupts */
+	return (smum_send_msg_to_smc(hwmgr->smumgr, PPSMC_MSG_Thermal_Cntl_Enable) == 0) ? 0 : -1;
+}
+
+/**
+* Disable thermal alerts on the RV770 thermal controller.
+* @param    hwmgr The address of the hardware manager.
+*/
+static int tonga_thermal_disable_alert(struct pp_hwmgr *hwmgr)
+{
+	uint32_t alert;
+
+	alert = PHM_READ_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, CG_THERMAL_INT, THERM_INT_MASK);
+	alert |= (TONGA_THERMAL_HIGH_ALERT_MASK | TONGA_THERMAL_LOW_ALERT_MASK);
+	PHM_WRITE_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, CG_THERMAL_INT, THERM_INT_MASK, alert);
+
+	/* send message to SMU to disable internal thermal interrupts */
+	return (smum_send_msg_to_smc(hwmgr->smumgr, PPSMC_MSG_Thermal_Cntl_Disable) == 0) ? 0 : -1;
+}
+
+/**
+* Uninitialize the thermal controller.
+* Currently just disables alerts.
+* @param    hwmgr The address of the hardware manager.
+*/
+int tonga_thermal_stop_thermal_controller(struct pp_hwmgr *hwmgr)
+{
+	int result = tonga_thermal_disable_alert(hwmgr);
+
+	if (hwmgr->thermal_controller.fanInfo.bNoFan)
+		tonga_fan_ctrl_set_default_mode(hwmgr);
+
+	return result;
+}
+
+/**
+* Set up the fan table to control the fan using the SMC.
+* @param    hwmgr  the address of the powerplay hardware manager.
+* @param    pInput the pointer to input data
+* @param    pOutput the pointer to output data
+* @param    pStorage the pointer to temporary storage
+* @param    Result the last failure code
+* @return   result from set temperature range routine
+*/
+int tf_tonga_thermal_setup_fan_table(struct pp_hwmgr *hwmgr, void *input, void *output, void *storage, int result)
+{
+	struct tonga_hwmgr *data = (struct tonga_hwmgr *)(hwmgr->backend);
+	SMU72_Discrete_FanTable fan_table = { FDO_MODE_HARDWARE };
+	uint32_t duty100;
+	uint32_t t_diff1, t_diff2, pwm_diff1, pwm_diff2;
+	uint16_t fdo_min, slope1, slope2;
+	uint32_t reference_clock;
+	int res;
+	uint64_t tmp64;
+
+	if (0 == data->fan_table_start) {
+		phm_cap_unset(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_MicrocodeFanControl);
+		return 0;
+	}
+
+	duty100 = PHM_READ_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, CG_FDO_CTRL1, FMAX_DUTY100);
+
+	if (0 == duty100) {
+		phm_cap_unset(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_MicrocodeFanControl);
+		return 0;
+	}
+
+	tmp64 = hwmgr->thermal_controller.advanceFanControlParameters.usPWMMin * duty100;
+	do_div(tmp64, 10000);
+	fdo_min = (uint16_t)tmp64;
+
+	t_diff1 = hwmgr->thermal_controller.advanceFanControlParameters.usTMed - hwmgr->thermal_controller.advanceFanControlParameters.usTMin;
+	t_diff2 = hwmgr->thermal_controller.advanceFanControlParameters.usTHigh - hwmgr->thermal_controller.advanceFanControlParameters.usTMed;
+
+	pwm_diff1 = hwmgr->thermal_controller.advanceFanControlParameters.usPWMMed - hwmgr->thermal_controller.advanceFanControlParameters.usPWMMin;
+	pwm_diff2 = hwmgr->thermal_controller.advanceFanControlParameters.usPWMHigh - hwmgr->thermal_controller.advanceFanControlParameters.usPWMMed;
+
+	slope1 = (uint16_t)((50 + ((16 * duty100 * pwm_diff1) / t_diff1)) / 100);
+	slope2 = (uint16_t)((50 + ((16 * duty100 * pwm_diff2) / t_diff2)) / 100);
+
+	fan_table.TempMin = cpu_to_be16((50 + hwmgr->thermal_controller.advanceFanControlParameters.usTMin) / 100);
+	fan_table.TempMed = cpu_to_be16((50 + hwmgr->thermal_controller.advanceFanControlParameters.usTMed) / 100);
+	fan_table.TempMax = cpu_to_be16((50 + hwmgr->thermal_controller.advanceFanControlParameters.usTMax) / 100);
+
+	fan_table.Slope1 = cpu_to_be16(slope1);
+	fan_table.Slope2 = cpu_to_be16(slope2);
+
+	fan_table.FdoMin = cpu_to_be16(fdo_min);
+
+	fan_table.HystDown = cpu_to_be16(hwmgr->thermal_controller.advanceFanControlParameters.ucTHyst);
+
+	fan_table.HystUp = cpu_to_be16(1);
+
+	fan_table.HystSlope = cpu_to_be16(1);
+
+	fan_table.TempRespLim = cpu_to_be16(5);
+
+	reference_clock = tonga_get_xclk(hwmgr);
+
+	fan_table.RefreshPeriod = cpu_to_be32((hwmgr->thermal_controller.advanceFanControlParameters.ulCycleDelay * reference_clock) / 1600);
+
+	fan_table.FdoMax = cpu_to_be16((uint16_t)duty100);
+
+	fan_table.TempSrc = (uint8_t)PHM_READ_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, CG_MULT_THERMAL_CTRL, TEMP_SEL);
+
+	fan_table.FanControl_GL_Flag = 1;
+
+	res = tonga_copy_bytes_to_smc(hwmgr->smumgr, data->fan_table_start, (uint8_t *)&fan_table, (uint32_t)sizeof(fan_table), data->sram_end);
+/* TO DO FOR SOME DEVICE ID 0X692b, send this msg return invalid command.
+	if (res == 0 && hwmgr->thermal_controller.advanceFanControlParameters.ucMinimumPWMLimit != 0)
+		res = (0 == smum_send_msg_to_smc_with_parameter(hwmgr->smumgr, PPSMC_MSG_SetFanMinPwm, \
+						hwmgr->thermal_controller.advanceFanControlParameters.ucMinimumPWMLimit) ? 0 : -1);
+
+	if (res == 0 && hwmgr->thermal_controller.advanceFanControlParameters.ulMinFanSCLKAcousticLimit != 0)
+		res = (0 == smum_send_msg_to_smc_with_parameter(hwmgr->smumgr, PPSMC_MSG_SetFanSclkTarget, \
+					hwmgr->thermal_controller.advanceFanControlParameters.ulMinFanSCLKAcousticLimit) ? 0 : -1);
+
+	if (0 != res)
+		phm_cap_unset(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_MicrocodeFanControl);
+*/
+	return 0;
+}
+
+/**
+* Start the fan control on the SMC.
+* @param    hwmgr  the address of the powerplay hardware manager.
+* @param    pInput the pointer to input data
+* @param    pOutput the pointer to output data
+* @param    pStorage the pointer to temporary storage
+* @param    Result the last failure code
+* @return   result from set temperature range routine
+*/
+int tf_tonga_thermal_start_smc_fan_control(struct pp_hwmgr *hwmgr, void *input, void *output, void *storage, int result)
+{
+/* If the fantable setup has failed we could have disabled PHM_PlatformCaps_MicrocodeFanControl even after this function was included in the table.
+ * Make sure that we still think controlling the fan is OK.
+*/
+	if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_MicrocodeFanControl)) {
+		tonga_fan_ctrl_start_smc_fan_control(hwmgr);
+		tonga_fan_ctrl_set_static_mode(hwmgr, FDO_PWM_MODE_STATIC);
+	}
+
+	return 0;
+}
+
+/**
+* Set temperature range for high and low alerts
+* @param    hwmgr  the address of the powerplay hardware manager.
+* @param    pInput the pointer to input data
+* @param    pOutput the pointer to output data
+* @param    pStorage the pointer to temporary storage
+* @param    Result the last failure code
+* @return   result from set temperature range routine
+*/
+int tf_tonga_thermal_set_temperature_range(struct pp_hwmgr *hwmgr, void *input, void *output, void *storage, int result)
+{
+	struct PP_TemperatureRange *range = (struct PP_TemperatureRange *)input;
+
+	if (range == NULL)
+		return -EINVAL;
+
+	return tonga_thermal_set_temperature_range(hwmgr, range->min, range->max);
+}
+
+/**
+* Programs one-time setting registers
+* @param    hwmgr  the address of the powerplay hardware manager.
+* @param    pInput the pointer to input data
+* @param    pOutput the pointer to output data
+* @param    pStorage the pointer to temporary storage
+* @param    Result the last failure code
+* @return   result from initialize thermal controller routine
+*/
+int tf_tonga_thermal_initialize(struct pp_hwmgr *hwmgr, void *input, void *output, void *storage, int result)
+{
+    return tonga_thermal_initialize(hwmgr);
+}
+
+/**
+* Enable high and low alerts
+* @param    hwmgr  the address of the powerplay hardware manager.
+* @param    pInput the pointer to input data
+* @param    pOutput the pointer to output data
+* @param    pStorage the pointer to temporary storage
+* @param    Result the last failure code
+* @return   result from enable alert routine
+*/
+int tf_tonga_thermal_enable_alert(struct pp_hwmgr *hwmgr, void *input, void *output, void *storage, int result)
+{
+	return tonga_thermal_enable_alert(hwmgr);
+}
+
+/**
+* Disable high and low alerts
+* @param    hwmgr  the address of the powerplay hardware manager.
+* @param    pInput the pointer to input data
+* @param    pOutput the pointer to output data
+* @param    pStorage the pointer to temporary storage
+* @param    Result the last failure code
+* @return   result from disable alert routine
+*/
+static int tf_tonga_thermal_disable_alert(struct pp_hwmgr *hwmgr, void *input, void *output, void *storage, int result)
+{
+	return tonga_thermal_disable_alert(hwmgr);
+}
+
+static struct phm_master_table_item tonga_thermal_start_thermal_controller_master_list[] = {
+	{ NULL, tf_tonga_thermal_initialize },
+	{ NULL, tf_tonga_thermal_set_temperature_range },
+	{ NULL, tf_tonga_thermal_enable_alert },
+/* We should restrict performance levels to low before we halt the SMC.
+ * On the other hand we are still in boot state when we do this so it would be pointless.
+ * If this assumption changes we have to revisit this table.
+ */
+	{ NULL, tf_tonga_thermal_setup_fan_table},
+	{ NULL, tf_tonga_thermal_start_smc_fan_control},
+	{ NULL, NULL }
+};
+
+static struct phm_master_table_header tonga_thermal_start_thermal_controller_master = {
+	0,
+	PHM_MasterTableFlag_None,
+	tonga_thermal_start_thermal_controller_master_list
+};
+
+static struct phm_master_table_item tonga_thermal_set_temperature_range_master_list[] = {
+	{ NULL, tf_tonga_thermal_disable_alert},
+	{ NULL, tf_tonga_thermal_set_temperature_range},
+	{ NULL, tf_tonga_thermal_enable_alert},
+	{ NULL, NULL }
+};
+
+struct phm_master_table_header tonga_thermal_set_temperature_range_master = {
+	0,
+	PHM_MasterTableFlag_None,
+	tonga_thermal_set_temperature_range_master_list
+};
+
+int tonga_thermal_ctrl_uninitialize_thermal_controller(struct pp_hwmgr *hwmgr)
+{
+	if (!hwmgr->thermal_controller.fanInfo.bNoFan)
+		tonga_fan_ctrl_set_default_mode(hwmgr);
+	return 0;
+}
+
+/**
+* Initializes the thermal controller related functions in the Hardware Manager structure.
+* @param    hwmgr The address of the hardware manager.
+* @exception Any error code from the low-level communication.
+*/
+int pp_tonga_thermal_initialize(struct pp_hwmgr *hwmgr)
+{
+	int result;
+
+	result = phm_construct_table(hwmgr, &tonga_thermal_set_temperature_range_master, &(hwmgr->set_temperature_range));
+
+	if (0 == result) {
+		result = phm_construct_table(hwmgr,
+						&tonga_thermal_start_thermal_controller_master,
+						&(hwmgr->start_thermal_controller));
+		if (0 != result)
+			phm_destroy_table(hwmgr, &(hwmgr->set_temperature_range));
+	}
+
+	if (0 == result)
+		hwmgr->fan_ctrl_is_in_default_mode = true;
+	return result;
+}
+
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_thermal.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2015 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#ifndef TONGA_THERMAL_H
+#define TONGA_THERMAL_H
+
+#include "hwmgr.h"
+
+#define TONGA_THERMAL_HIGH_ALERT_MASK         0x1
+#define TONGA_THERMAL_LOW_ALERT_MASK          0x2
+
+#define TONGA_THERMAL_MINIMUM_TEMP_READING    -256
+#define TONGA_THERMAL_MAXIMUM_TEMP_READING    255
+
+#define TONGA_THERMAL_MINIMUM_ALERT_TEMP      0
+#define TONGA_THERMAL_MAXIMUM_ALERT_TEMP      255
+
+#define FDO_PWM_MODE_STATIC  1
+#define FDO_PWM_MODE_STATIC_RPM 5
+
+
+extern int tf_tonga_thermal_initialize(struct pp_hwmgr *hwmgr, void *input, void *output, void *storage, int result);
+extern int tf_tonga_thermal_set_temperature_range(struct pp_hwmgr *hwmgr, void *input, void *output, void *storage, int result);
+extern int tf_tonga_thermal_enable_alert(struct pp_hwmgr *hwmgr, void *input, void *output, void *storage, int result);
+
+extern int tonga_thermal_get_temperature(struct pp_hwmgr *hwmgr);
+extern int tonga_thermal_stop_thermal_controller(struct pp_hwmgr *hwmgr);
+extern int tonga_fan_ctrl_get_fan_speed_info(struct pp_hwmgr *hwmgr, struct phm_fan_speed_info *fan_speed_info);
+extern int tonga_fan_ctrl_get_fan_speed_percent(struct pp_hwmgr *hwmgr, uint32_t *speed);
+extern int tonga_fan_ctrl_set_default_mode(struct pp_hwmgr *hwmgr);
+extern int tonga_fan_ctrl_set_static_mode(struct pp_hwmgr *hwmgr, uint32_t mode);
+extern int tonga_fan_ctrl_set_fan_speed_percent(struct pp_hwmgr *hwmgr, uint32_t speed);
+extern int tonga_fan_ctrl_reset_fan_speed_to_default(struct pp_hwmgr *hwmgr);
+extern int pp_tonga_thermal_initialize(struct pp_hwmgr *hwmgr);
+extern int tonga_thermal_ctrl_uninitialize_thermal_controller(struct pp_hwmgr *hwmgr);
+extern int tonga_fan_ctrl_set_fan_speed_rpm(struct pp_hwmgr *hwmgr, uint32_t speed);
+extern int tonga_fan_ctrl_get_fan_speed_rpm(struct pp_hwmgr *hwmgr, uint32_t *speed);
+extern int tonga_fan_ctrl_stop_smc_fan_control(struct pp_hwmgr *hwmgr);
+
+#endif
+
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/powerplay/inc/amd_powerplay.h
@@ -0,0 +1,298 @@
+/*
+ * Copyright 2015 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+#ifndef _AMD_POWERPLAY_H_
+#define _AMD_POWERPLAY_H_
+
+#include <linux/seq_file.h>
+#include <linux/types.h>
+#include "amd_shared.h"
+#include "cgs_common.h"
+
+enum amd_pp_event {
+	AMD_PP_EVENT_INITIALIZE = 0,
+	AMD_PP_EVENT_UNINITIALIZE,
+	AMD_PP_EVENT_POWER_SOURCE_CHANGE,
+	AMD_PP_EVENT_SUSPEND,
+	AMD_PP_EVENT_RESUME,
+	AMD_PP_EVENT_ENTER_REST_STATE,
+	AMD_PP_EVENT_EXIT_REST_STATE,
+	AMD_PP_EVENT_DISPLAY_CONFIG_CHANGE,
+	AMD_PP_EVENT_THERMAL_NOTIFICATION,
+	AMD_PP_EVENT_VBIOS_NOTIFICATION,
+	AMD_PP_EVENT_ENTER_THERMAL_STATE,
+	AMD_PP_EVENT_EXIT_THERMAL_STATE,
+	AMD_PP_EVENT_ENTER_FORCED_STATE,
+	AMD_PP_EVENT_EXIT_FORCED_STATE,
+	AMD_PP_EVENT_ENTER_EXCLUSIVE_MODE,
+	AMD_PP_EVENT_EXIT_EXCLUSIVE_MODE,
+	AMD_PP_EVENT_ENTER_SCREEN_SAVER,
+	AMD_PP_EVENT_EXIT_SCREEN_SAVER,
+	AMD_PP_EVENT_VPU_RECOVERY_BEGIN,
+	AMD_PP_EVENT_VPU_RECOVERY_END,
+	AMD_PP_EVENT_ENABLE_POWER_PLAY,
+	AMD_PP_EVENT_DISABLE_POWER_PLAY,
+	AMD_PP_EVENT_CHANGE_POWER_SOURCE_UI_LABEL,
+	AMD_PP_EVENT_ENABLE_USER2D_PERFORMANCE,
+	AMD_PP_EVENT_DISABLE_USER2D_PERFORMANCE,
+	AMD_PP_EVENT_ENABLE_USER3D_PERFORMANCE,
+	AMD_PP_EVENT_DISABLE_USER3D_PERFORMANCE,
+	AMD_PP_EVENT_ENABLE_OVER_DRIVE_TEST,
+	AMD_PP_EVENT_DISABLE_OVER_DRIVE_TEST,
+	AMD_PP_EVENT_ENABLE_REDUCED_REFRESH_RATE,
+	AMD_PP_EVENT_DISABLE_REDUCED_REFRESH_RATE,
+	AMD_PP_EVENT_ENABLE_GFX_CLOCK_GATING,
+	AMD_PP_EVENT_DISABLE_GFX_CLOCK_GATING,
+	AMD_PP_EVENT_ENABLE_CGPG,
+	AMD_PP_EVENT_DISABLE_CGPG,
+	AMD_PP_EVENT_ENTER_TEXT_MODE,
+	AMD_PP_EVENT_EXIT_TEXT_MODE,
+	AMD_PP_EVENT_VIDEO_START,
+	AMD_PP_EVENT_VIDEO_STOP,
+	AMD_PP_EVENT_ENABLE_USER_STATE,
+	AMD_PP_EVENT_DISABLE_USER_STATE,
+	AMD_PP_EVENT_READJUST_POWER_STATE,
+	AMD_PP_EVENT_START_INACTIVITY,
+	AMD_PP_EVENT_STOP_INACTIVITY,
+	AMD_PP_EVENT_LINKED_ADAPTERS_READY,
+	AMD_PP_EVENT_ADAPTER_SAFE_TO_DISABLE,
+	AMD_PP_EVENT_COMPLETE_INIT,
+	AMD_PP_EVENT_CRITICAL_THERMAL_FAULT,
+	AMD_PP_EVENT_BACKLIGHT_CHANGED,
+	AMD_PP_EVENT_ENABLE_VARI_BRIGHT,
+	AMD_PP_EVENT_DISABLE_VARI_BRIGHT,
+	AMD_PP_EVENT_ENABLE_VARI_BRIGHT_ON_POWER_XPRESS,
+	AMD_PP_EVENT_DISABLE_VARI_BRIGHT_ON_POWER_XPRESS,
+	AMD_PP_EVENT_SET_VARI_BRIGHT_LEVEL,
+	AMD_PP_EVENT_VARI_BRIGHT_MONITOR_MEASUREMENT,
+	AMD_PP_EVENT_SCREEN_ON,
+	AMD_PP_EVENT_SCREEN_OFF,
+	AMD_PP_EVENT_PRE_DISPLAY_CONFIG_CHANGE,
+	AMD_PP_EVENT_ENTER_ULP_STATE,
+	AMD_PP_EVENT_EXIT_ULP_STATE,
+	AMD_PP_EVENT_REGISTER_IP_STATE,
+	AMD_PP_EVENT_UNREGISTER_IP_STATE,
+	AMD_PP_EVENT_ENTER_MGPU_MODE,
+	AMD_PP_EVENT_EXIT_MGPU_MODE,
+	AMD_PP_EVENT_ENTER_MULTI_GPU_MODE,
+	AMD_PP_EVENT_PRE_SUSPEND,
+	AMD_PP_EVENT_PRE_RESUME,
+	AMD_PP_EVENT_ENTER_BACOS,
+	AMD_PP_EVENT_EXIT_BACOS,
+	AMD_PP_EVENT_RESUME_BACO,
+	AMD_PP_EVENT_RESET_BACO,
+	AMD_PP_EVENT_PRE_DISPLAY_PHY_ACCESS,
+	AMD_PP_EVENT_POST_DISPLAY_PHY_CCESS,
+	AMD_PP_EVENT_START_COMPUTE_APPLICATION,
+	AMD_PP_EVENT_STOP_COMPUTE_APPLICATION,
+	AMD_PP_EVENT_REDUCE_POWER_LIMIT,
+	AMD_PP_EVENT_ENTER_FRAME_LOCK,
+	AMD_PP_EVENT_EXIT_FRAME_LOOCK,
+	AMD_PP_EVENT_LONG_IDLE_REQUEST_BACO,
+	AMD_PP_EVENT_LONG_IDLE_ENTER_BACO,
+	AMD_PP_EVENT_LONG_IDLE_EXIT_BACO,
+	AMD_PP_EVENT_HIBERNATE,
+	AMD_PP_EVENT_CONNECTED_STANDBY,
+	AMD_PP_EVENT_ENTER_SELF_REFRESH,
+	AMD_PP_EVENT_EXIT_SELF_REFRESH,
+	AMD_PP_EVENT_START_AVFS_BTC,
+	AMD_PP_EVENT_MAX
+};
+
+enum amd_dpm_forced_level {
+	AMD_DPM_FORCED_LEVEL_AUTO = 0,
+	AMD_DPM_FORCED_LEVEL_LOW = 1,
+	AMD_DPM_FORCED_LEVEL_HIGH = 2,
+};
+
+struct amd_pp_init {
+	struct cgs_device *device;
+	uint32_t chip_family;
+	uint32_t chip_id;
+	uint32_t rev_id;
+};
+enum amd_pp_display_config_type{
+	AMD_PP_DisplayConfigType_None = 0,
+	AMD_PP_DisplayConfigType_DP54 ,
+	AMD_PP_DisplayConfigType_DP432 ,
+	AMD_PP_DisplayConfigType_DP324 ,
+	AMD_PP_DisplayConfigType_DP27,
+	AMD_PP_DisplayConfigType_DP243,
+	AMD_PP_DisplayConfigType_DP216,
+	AMD_PP_DisplayConfigType_DP162,
+	AMD_PP_DisplayConfigType_HDMI6G ,
+	AMD_PP_DisplayConfigType_HDMI297 ,
+	AMD_PP_DisplayConfigType_HDMI162,
+	AMD_PP_DisplayConfigType_LVDS,
+	AMD_PP_DisplayConfigType_DVI,
+	AMD_PP_DisplayConfigType_WIRELESS,
+	AMD_PP_DisplayConfigType_VGA
+};
+
+struct single_display_configuration
+{
+	uint32_t controller_index;
+	uint32_t controller_id;
+	uint32_t signal_type;
+	uint32_t display_state;
+	/* phy id for the primary internal transmitter */
+	uint8_t primary_transmitter_phyi_d;
+	/* bitmap with the active lanes */
+	uint8_t primary_transmitter_active_lanemap;
+	/* phy id for the secondary internal transmitter (for dual-link dvi) */
+	uint8_t secondary_transmitter_phy_id;
+	/* bitmap with the active lanes */
+	uint8_t secondary_transmitter_active_lanemap;
+	/* misc phy settings for SMU. */
+	uint32_t config_flags;
+	uint32_t display_type;
+	uint32_t view_resolution_cx;
+	uint32_t view_resolution_cy;
+	enum amd_pp_display_config_type displayconfigtype;
+	uint32_t vertical_refresh; /* for active display */
+};
+
+#define MAX_NUM_DISPLAY 32
+
+struct amd_pp_display_configuration {
+	bool nb_pstate_switch_disable;/* controls NB PState switch */
+	bool cpu_cc6_disable; /* controls CPU CState switch ( on or off) */
+	bool cpu_pstate_disable;
+	uint32_t cpu_pstate_separation_time;
+
+	uint32_t num_display;  /* total number of display*/
+	uint32_t num_path_including_non_display;
+	uint32_t crossfire_display_index;
+	uint32_t min_mem_set_clock;
+	uint32_t min_core_set_clock;
+	/* unit 10KHz x bit*/
+	uint32_t min_bus_bandwidth;
+	/* minimum required stutter sclk, in 10khz uint32_t ulMinCoreSetClk;*/
+	uint32_t min_core_set_clock_in_sr;
+
+	struct single_display_configuration displays[MAX_NUM_DISPLAY];
+
+	uint32_t vrefresh; /* for active display*/
+
+	uint32_t min_vblank_time; /* for active display*/
+	bool multi_monitor_in_sync;
+	/* Controller Index of primary display - used in MCLK SMC switching hang
+	 * SW Workaround*/
+	uint32_t crtc_index;
+	/* htotal*1000/pixelclk - used in MCLK SMC switching hang SW Workaround*/
+	uint32_t line_time_in_us;
+	bool invalid_vblank_time;
+
+	uint32_t display_clk;
+	/*
+	 * for given display configuration if multimonitormnsync == false then
+	 * Memory clock DPMS with this latency or below is allowed, DPMS with
+	 * higher latency not allowed.
+	 */
+	uint32_t dce_tolerable_mclk_in_active_latency;
+};
+
+struct amd_pp_dal_clock_info {
+	uint32_t	engine_max_clock;
+	uint32_t	memory_max_clock;
+	uint32_t	level;
+};
+
+enum {
+	PP_GROUP_UNKNOWN = 0,
+	PP_GROUP_GFX = 1,
+	PP_GROUP_SYS,
+	PP_GROUP_MAX
+};
+
+#define PP_GROUP_MASK        0xF0000000
+#define PP_GROUP_SHIFT       28
+
+#define PP_BLOCK_MASK        0x0FFFFF00
+#define PP_BLOCK_SHIFT       8
+
+#define PP_BLOCK_GFX_CG         0x01
+#define PP_BLOCK_GFX_MG         0x02
+#define PP_BLOCK_SYS_BIF        0x01
+#define PP_BLOCK_SYS_MC         0x02
+#define PP_BLOCK_SYS_ROM        0x04
+#define PP_BLOCK_SYS_DRM        0x08
+#define PP_BLOCK_SYS_HDP        0x10
+#define PP_BLOCK_SYS_SDMA       0x20
+
+#define PP_STATE_MASK           0x0000000F
+#define PP_STATE_SHIFT          0
+#define PP_STATE_SUPPORT_MASK   0x000000F0
+#define PP_STATE_SUPPORT_SHIFT  0
+
+#define PP_STATE_CG             0x01
+#define PP_STATE_LS             0x02
+#define PP_STATE_DS             0x04
+#define PP_STATE_SD             0x08
+#define PP_STATE_SUPPORT_CG     0x10
+#define PP_STATE_SUPPORT_LS     0x20
+#define PP_STATE_SUPPORT_DS     0x40
+#define PP_STATE_SUPPORT_SD     0x80
+
+#define PP_CG_MSG_ID(group, block, support, state) (group << PP_GROUP_SHIFT |\
+								block << PP_BLOCK_SHIFT |\
+								support << PP_STATE_SUPPORT_SHIFT |\
+								state << PP_STATE_SHIFT)
+
+struct amd_powerplay_funcs {
+	int (*get_temperature)(void *handle);
+	int (*load_firmware)(void *handle);
+	int (*wait_for_fw_loading_complete)(void *handle);
+	int (*force_performance_level)(void *handle, enum amd_dpm_forced_level level);
+	enum amd_dpm_forced_level (*get_performance_level)(void *handle);
+	enum amd_pm_state_type (*get_current_power_state)(void *handle);
+	int (*get_sclk)(void *handle, bool low);
+	int (*get_mclk)(void *handle, bool low);
+	int (*powergate_vce)(void *handle, bool gate);
+	int (*powergate_uvd)(void *handle, bool gate);
+	int (*dispatch_tasks)(void *handle, enum amd_pp_event event_id,
+				   void *input, void *output);
+	void (*print_current_performance_level)(void *handle,
+						      struct seq_file *m);
+	int (*set_fan_control_mode)(void *handle, uint32_t mode);
+	int (*get_fan_control_mode)(void *handle);
+	int (*set_fan_speed_percent)(void *handle, uint32_t percent);
+	int (*get_fan_speed_percent)(void *handle, uint32_t *speed);
+};
+
+struct amd_powerplay {
+	void *pp_handle;
+	const struct amd_ip_funcs *ip_funcs;
+	const struct amd_powerplay_funcs *pp_funcs;
+};
+
+int amd_powerplay_init(struct amd_pp_init *pp_init,
+		       struct amd_powerplay *amd_pp);
+int amd_powerplay_fini(void *handle);
+
+int amd_powerplay_display_configuration_change(void *handle, const void *input);
+
+int amd_powerplay_get_display_power_level(void *handle,
+		struct amd_pp_dal_clock_info *output);
+
+
+#endif /* _AMD_POWERPLAY_H_ */
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/powerplay/inc/cz_ppsmc.h
@@ -0,0 +1,186 @@
+/*
+ * Copyright 2014 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#ifndef CZ_PP_SMC_H
+#define CZ_PP_SMC_H
+
+#pragma pack(push, 1)
+
+/* Fan control algorithm:*/
+#define FDO_MODE_HARDWARE 0
+#define FDO_MODE_PIECE_WISE_LINEAR 1
+
+enum FAN_CONTROL {
+    FAN_CONTROL_FUZZY,
+    FAN_CONTROL_TABLE
+};
+
+enum DPM_ARRAY {
+    DPM_ARRAY_HARD_MAX,
+    DPM_ARRAY_HARD_MIN,
+    DPM_ARRAY_SOFT_MAX,
+    DPM_ARRAY_SOFT_MIN
+};
+
+/*
+ * Return codes for driver to SMC communication.
+ * Leave these #define-s, enums might not be exactly 8-bits on the microcontroller.
+ */
+#define PPSMC_Result_OK             ((uint16_t)0x01)
+#define PPSMC_Result_NoMore         ((uint16_t)0x02)
+#define PPSMC_Result_NotNow         ((uint16_t)0x03)
+#define PPSMC_Result_Failed         ((uint16_t)0xFF)
+#define PPSMC_Result_UnknownCmd     ((uint16_t)0xFE)
+#define PPSMC_Result_UnknownVT      ((uint16_t)0xFD)
+
+#define PPSMC_isERROR(x)            ((uint16_t)0x80 & (x))
+
+/*
+ * Supported driver messages
+ */
+#define PPSMC_MSG_Test                        ((uint16_t) 0x1)
+#define PPSMC_MSG_GetFeatureStatus            ((uint16_t) 0x2)
+#define PPSMC_MSG_EnableAllSmuFeatures        ((uint16_t) 0x3)
+#define PPSMC_MSG_DisableAllSmuFeatures       ((uint16_t) 0x4)
+#define PPSMC_MSG_OptimizeBattery             ((uint16_t) 0x5)
+#define PPSMC_MSG_MaximizePerf                ((uint16_t) 0x6)
+#define PPSMC_MSG_UVDPowerOFF                 ((uint16_t) 0x7)
+#define PPSMC_MSG_UVDPowerON                  ((uint16_t) 0x8)
+#define PPSMC_MSG_VCEPowerOFF                 ((uint16_t) 0x9)
+#define PPSMC_MSG_VCEPowerON                  ((uint16_t) 0xA)
+#define PPSMC_MSG_ACPPowerOFF                 ((uint16_t) 0xB)
+#define PPSMC_MSG_ACPPowerON                  ((uint16_t) 0xC)
+#define PPSMC_MSG_SDMAPowerOFF                ((uint16_t) 0xD)
+#define PPSMC_MSG_SDMAPowerON                 ((uint16_t) 0xE)
+#define PPSMC_MSG_XDMAPowerOFF                ((uint16_t) 0xF)
+#define PPSMC_MSG_XDMAPowerON                 ((uint16_t) 0x10)
+#define PPSMC_MSG_SetMinDeepSleepSclk         ((uint16_t) 0x11)
+#define PPSMC_MSG_SetSclkSoftMin              ((uint16_t) 0x12)
+#define PPSMC_MSG_SetSclkSoftMax              ((uint16_t) 0x13)
+#define PPSMC_MSG_SetSclkHardMin              ((uint16_t) 0x14)
+#define PPSMC_MSG_SetSclkHardMax              ((uint16_t) 0x15)
+#define PPSMC_MSG_SetLclkSoftMin              ((uint16_t) 0x16)
+#define PPSMC_MSG_SetLclkSoftMax              ((uint16_t) 0x17)
+#define PPSMC_MSG_SetLclkHardMin              ((uint16_t) 0x18)
+#define PPSMC_MSG_SetLclkHardMax              ((uint16_t) 0x19)
+#define PPSMC_MSG_SetUvdSoftMin               ((uint16_t) 0x1A)
+#define PPSMC_MSG_SetUvdSoftMax               ((uint16_t) 0x1B)
+#define PPSMC_MSG_SetUvdHardMin               ((uint16_t) 0x1C)
+#define PPSMC_MSG_SetUvdHardMax               ((uint16_t) 0x1D)
+#define PPSMC_MSG_SetEclkSoftMin              ((uint16_t) 0x1E)
+#define PPSMC_MSG_SetEclkSoftMax              ((uint16_t) 0x1F)
+#define PPSMC_MSG_SetEclkHardMin              ((uint16_t) 0x20)
+#define PPSMC_MSG_SetEclkHardMax              ((uint16_t) 0x21)
+#define PPSMC_MSG_SetAclkSoftMin              ((uint16_t) 0x22)
+#define PPSMC_MSG_SetAclkSoftMax              ((uint16_t) 0x23)
+#define PPSMC_MSG_SetAclkHardMin              ((uint16_t) 0x24)
+#define PPSMC_MSG_SetAclkHardMax              ((uint16_t) 0x25)
+#define PPSMC_MSG_SetNclkSoftMin              ((uint16_t) 0x26)
+#define PPSMC_MSG_SetNclkSoftMax              ((uint16_t) 0x27)
+#define PPSMC_MSG_SetNclkHardMin              ((uint16_t) 0x28)
+#define PPSMC_MSG_SetNclkHardMax              ((uint16_t) 0x29)
+#define PPSMC_MSG_SetPstateSoftMin            ((uint16_t) 0x2A)
+#define PPSMC_MSG_SetPstateSoftMax            ((uint16_t) 0x2B)
+#define PPSMC_MSG_SetPstateHardMin            ((uint16_t) 0x2C)
+#define PPSMC_MSG_SetPstateHardMax            ((uint16_t) 0x2D)
+#define PPSMC_MSG_DisableLowMemoryPstate      ((uint16_t) 0x2E)
+#define PPSMC_MSG_EnableLowMemoryPstate       ((uint16_t) 0x2F)
+#define PPSMC_MSG_UcodeAddressLow             ((uint16_t) 0x30)
+#define PPSMC_MSG_UcodeAddressHigh            ((uint16_t) 0x31)
+#define PPSMC_MSG_UcodeLoadStatus             ((uint16_t) 0x32)
+#define PPSMC_MSG_DriverDramAddrHi            ((uint16_t) 0x33)
+#define PPSMC_MSG_DriverDramAddrLo            ((uint16_t) 0x34)
+#define PPSMC_MSG_CondExecDramAddrHi          ((uint16_t) 0x35)
+#define PPSMC_MSG_CondExecDramAddrLo          ((uint16_t) 0x36)
+#define PPSMC_MSG_LoadUcodes                  ((uint16_t) 0x37)
+#define PPSMC_MSG_DriverResetMode             ((uint16_t) 0x38)
+#define PPSMC_MSG_PowerStateNotify            ((uint16_t) 0x39)
+#define PPSMC_MSG_SetDisplayPhyConfig         ((uint16_t) 0x3A)
+#define PPSMC_MSG_GetMaxSclkLevel             ((uint16_t) 0x3B)
+#define PPSMC_MSG_GetMaxLclkLevel             ((uint16_t) 0x3C)
+#define PPSMC_MSG_GetMaxUvdLevel              ((uint16_t) 0x3D)
+#define PPSMC_MSG_GetMaxEclkLevel             ((uint16_t) 0x3E)
+#define PPSMC_MSG_GetMaxAclkLevel             ((uint16_t) 0x3F)
+#define PPSMC_MSG_GetMaxNclkLevel             ((uint16_t) 0x40)
+#define PPSMC_MSG_GetMaxPstate                ((uint16_t) 0x41)
+#define PPSMC_MSG_DramAddrHiVirtual           ((uint16_t) 0x42)
+#define PPSMC_MSG_DramAddrLoVirtual           ((uint16_t) 0x43)
+#define PPSMC_MSG_DramAddrHiPhysical          ((uint16_t) 0x44)
+#define PPSMC_MSG_DramAddrLoPhysical          ((uint16_t) 0x45)
+#define PPSMC_MSG_DramBufferSize              ((uint16_t) 0x46)
+#define PPSMC_MSG_SetMmPwrLogDramAddrHi       ((uint16_t) 0x47)
+#define PPSMC_MSG_SetMmPwrLogDramAddrLo       ((uint16_t) 0x48)
+#define PPSMC_MSG_SetClkTableAddrHi           ((uint16_t) 0x49)
+#define PPSMC_MSG_SetClkTableAddrLo           ((uint16_t) 0x4A)
+#define PPSMC_MSG_GetConservativePowerLimit   ((uint16_t) 0x4B)
+
+#define PPSMC_MSG_InitJobs                    ((uint16_t) 0x252)
+#define PPSMC_MSG_ExecuteJob                  ((uint16_t) 0x254)
+
+#define PPSMC_MSG_NBDPM_Enable                ((uint16_t) 0x140)
+#define PPSMC_MSG_NBDPM_Disable               ((uint16_t) 0x141)
+
+#define PPSMC_MSG_DPM_FPS_Mode                ((uint16_t) 0x15d)
+#define PPSMC_MSG_DPM_Activity_Mode           ((uint16_t) 0x15e)
+
+#define PPSMC_MSG_PmStatusLogStart            ((uint16_t) 0x170)
+#define PPSMC_MSG_PmStatusLogSample           ((uint16_t) 0x171)
+
+#define PPSMC_MSG_AllowLowSclkInterrupt       ((uint16_t) 0x184)
+#define PPSMC_MSG_MmPowerMonitorStart         ((uint16_t) 0x18F)
+#define PPSMC_MSG_MmPowerMonitorStop          ((uint16_t) 0x190)
+#define PPSMC_MSG_MmPowerMonitorRestart       ((uint16_t) 0x191)
+
+#define PPSMC_MSG_SetClockGateMask            ((uint16_t) 0x260)
+#define PPSMC_MSG_SetFpsThresholdLo           ((uint16_t) 0x264)
+#define PPSMC_MSG_SetFpsThresholdHi           ((uint16_t) 0x265)
+#define PPSMC_MSG_SetLowSclkIntrThreshold     ((uint16_t) 0x266)
+
+#define PPSMC_MSG_ClkTableXferToDram          ((uint16_t) 0x267)
+#define PPSMC_MSG_ClkTableXferToSmu           ((uint16_t) 0x268)
+#define PPSMC_MSG_GetAverageGraphicsActivity  ((uint16_t) 0x269)
+#define PPSMC_MSG_GetAverageGioActivity       ((uint16_t) 0x26A)
+#define PPSMC_MSG_SetLoggerBufferSize         ((uint16_t) 0x26B)
+#define PPSMC_MSG_SetLoggerAddressHigh        ((uint16_t) 0x26C)
+#define PPSMC_MSG_SetLoggerAddressLow         ((uint16_t) 0x26D)
+#define PPSMC_MSG_SetWatermarkFrequency       ((uint16_t) 0x26E)
+#define PPSMC_MSG_SetDisplaySizePowerParams   ((uint16_t) 0x26F)
+
+/* REMOVE LATER*/
+#define PPSMC_MSG_DPM_ForceState              ((uint16_t) 0x104)
+
+/* Feature Enable Masks*/
+#define NB_DPM_MASK             0x00000800
+#define VDDGFX_MASK             0x00800000
+#define VCE_DPM_MASK            0x00400000
+#define ACP_DPM_MASK            0x00040000
+#define UVD_DPM_MASK            0x00010000
+#define GFX_CU_PG_MASK          0x00004000
+#define SCLK_DPM_MASK           0x00080000
+
+#if !defined(SMC_MICROCODE)
+#pragma pack(pop)
+
+#endif
+
+#endif
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/powerplay/inc/eventmanager.h
@@ -0,0 +1,109 @@
+/*
+ * Copyright 2015 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+#ifndef _EVENT_MANAGER_H_
+#define _EVENT_MANAGER_H_
+
+#include "power_state.h"
+#include "pp_power_source.h"
+#include "hardwaremanager.h"
+#include "pp_asicblocks.h"
+
+struct pp_eventmgr;
+enum amd_pp_event;
+
+enum PEM_EventDataValid {
+	PEM_EventDataValid_RequestedStateID = 0,
+	PEM_EventDataValid_RequestedUILabel,
+	PEM_EventDataValid_NewPowerState,
+	PEM_EventDataValid_RequestedPowerSource,
+	PEM_EventDataValid_RequestedClocks,
+	PEM_EventDataValid_CurrentTemperature,
+	PEM_EventDataValid_AsicBlocks,
+	PEM_EventDataValid_ODParameters,
+	PEM_EventDataValid_PXAdapterPrefs,
+	PEM_EventDataValid_PXUserPrefs,
+	PEM_EventDataValid_PXSwitchReason,
+	PEM_EventDataValid_PXSwitchPhase,
+	PEM_EventDataValid_HdVideo,
+	PEM_EventDataValid_BacklightLevel,
+	PEM_EventDatavalid_VariBrightParams,
+	PEM_EventDataValid_VariBrightLevel,
+	PEM_EventDataValid_VariBrightImmediateChange,
+	PEM_EventDataValid_PercentWhite,
+	PEM_EventDataValid_SdVideo,
+	PEM_EventDataValid_HTLinkChangeReason,
+	PEM_EventDataValid_HWBlocks,
+	PEM_EventDataValid_RequestedThermalState,
+	PEM_EventDataValid_MvcVideo,
+	PEM_EventDataValid_Max
+};
+
+typedef enum PEM_EventDataValid PEM_EventDataValid;
+
+/* Number of bits in ULONG variable */
+#define PEM_MAX_NUM_EVENTDATAVALID_BITS_PER_FIELD (sizeof(unsigned long)*8)
+
+/* Number of ULONG entries used by event data valid bits */
+#define PEM_MAX_NUM_EVENTDATAVALID_ULONG_ENTRIES                                 \
+		((PEM_EventDataValid_Max + PEM_MAX_NUM_EVENTDATAVALID_BITS_PER_FIELD - 1) /  \
+		PEM_MAX_NUM_EVENTDATAVALID_BITS_PER_FIELD)
+
+static inline void pem_set_event_data_valid(unsigned long *fields, PEM_EventDataValid valid_field)
+{
+	fields[valid_field / PEM_MAX_NUM_EVENTDATAVALID_BITS_PER_FIELD] |=
+		(1UL << (valid_field % PEM_MAX_NUM_EVENTDATAVALID_BITS_PER_FIELD));
+}
+
+static inline void pem_unset_event_data_valid(unsigned long *fields, PEM_EventDataValid valid_field)
+{
+	fields[valid_field / PEM_MAX_NUM_EVENTDATAVALID_BITS_PER_FIELD] &=
+		~(1UL << (valid_field % PEM_MAX_NUM_EVENTDATAVALID_BITS_PER_FIELD));
+}
+
+static inline unsigned long pem_is_event_data_valid(const unsigned long *fields, PEM_EventDataValid valid_field)
+{
+	return fields[valid_field / PEM_MAX_NUM_EVENTDATAVALID_BITS_PER_FIELD] &
+		(1UL << (valid_field % PEM_MAX_NUM_EVENTDATAVALID_BITS_PER_FIELD));
+}
+
+struct pem_event_data {
+	unsigned long	valid_fields[100];
+	unsigned long   requested_state_id;
+	enum PP_StateUILabel requested_ui_label;
+	struct pp_power_state  *pnew_power_state;
+	enum pp_power_source  requested_power_source;
+	struct PP_Clocks       requested_clocks;
+	bool         skip_state_adjust_rules;
+	struct phm_asic_blocks  asic_blocks;
+	/* to doPP_ThermalState requestedThermalState;
+	enum ThermalStateRequestSrc requestThermalStateSrc;
+	PP_Temperature  currentTemperature;*/
+
+};
+
+int pem_handle_event(struct pp_eventmgr *eventmgr, enum amd_pp_event event,
+		     struct pem_event_data *event_data);
+
+bool pem_is_hw_access_blocked(struct pp_eventmgr *eventmgr);
+
+#endif /* _EVENT_MANAGER_H_ */
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/powerplay/inc/eventmgr.h
@@ -0,0 +1,125 @@
+/*
+ * Copyright 2015 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#ifndef _EVENTMGR_H_
+#define _EVENTMGR_H_
+
+#include <linux/mutex.h>
+#include "pp_instance.h"
+#include "hardwaremanager.h"
+#include "eventmanager.h"
+#include "pp_feature.h"
+#include "pp_power_source.h"
+#include "power_state.h"
+
+typedef int (*pem_event_action)(struct pp_eventmgr *eventmgr,
+				struct pem_event_data *event_data);
+
+struct action_chain {
+	const char *description;  /* action chain description for debugging purpose */
+	const pem_event_action **action_chain; /* pointer to chain of event actions */
+};
+
+struct pem_power_source_ui_state_info {
+	enum PP_StateUILabel current_ui_label;
+	enum PP_StateUILabel default_ui_lable;
+	unsigned long    configurable_ui_mapping;
+};
+
+struct pp_clock_range {
+	uint32_t min_sclk_khz;
+	uint32_t max_sclk_khz;
+
+	uint32_t min_mclk_khz;
+	uint32_t max_mclk_khz;
+
+	uint32_t min_vclk_khz;
+	uint32_t max_vclk_khz;
+
+	uint32_t min_dclk_khz;
+	uint32_t max_dclk_khz;
+
+	uint32_t min_aclk_khz;
+	uint32_t max_aclk_khz;
+
+	uint32_t min_eclk_khz;
+	uint32_t max_eclk_khz;
+};
+
+enum pp_state {
+	UNINITIALIZED,
+	INACTIVE,
+	ACTIVE
+};
+
+enum pp_ring_index {
+	PP_RING_TYPE_GFX_INDEX = 0,
+	PP_RING_TYPE_DMA_INDEX,
+	PP_RING_TYPE_DMA1_INDEX,
+	PP_RING_TYPE_UVD_INDEX,
+	PP_RING_TYPE_VCE0_INDEX,
+	PP_RING_TYPE_VCE1_INDEX,
+	PP_RING_TYPE_CP1_INDEX,
+	PP_RING_TYPE_CP2_INDEX,
+	PP_NUM_RINGS,
+};
+
+struct pp_request {
+	uint32_t flags;
+	uint32_t sclk;
+	uint32_t sclk_throttle;
+	uint32_t mclk;
+	uint32_t vclk;
+	uint32_t dclk;
+	uint32_t eclk;
+	uint32_t aclk;
+	uint32_t iclk;
+	uint32_t vp8clk;
+	uint32_t rsv[32];
+};
+
+struct pp_eventmgr {
+	struct pp_hwmgr	*hwmgr;
+	struct pp_smumgr *smumgr;
+
+	struct pp_feature_info features[PP_Feature_Max];
+	const struct action_chain *event_chain[AMD_PP_EVENT_MAX];
+	struct phm_platform_descriptor   *platform_descriptor;
+	struct pp_clock_range clock_range;
+	enum pp_power_source  current_power_source;
+	struct pem_power_source_ui_state_info  ui_state_info[PP_PowerSource_Max];
+	enum pp_state states[PP_NUM_RINGS];
+	struct pp_request hi_req;
+	struct list_head context_list;
+	struct mutex lock;
+	bool  block_adjust_power_state;
+	bool enable_cg;
+	bool enable_gfx_cgpg;
+	int (*pp_eventmgr_init)(struct pp_eventmgr *eventmgr);
+	void (*pp_eventmgr_fini)(struct pp_eventmgr *eventmgr);
+};
+
+int eventmgr_init(struct pp_instance *handle);
+int eventmgr_fini(struct pp_eventmgr *eventmgr);
+
+#endif /* _EVENTMGR_H_ */
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/powerplay/inc/fiji_ppsmc.h
@@ -0,0 +1,412 @@
+/*
+ * Copyright 2015 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+
+#ifndef _FIJI_PP_SMC_H_
+#define _FIJI_PP_SMC_H_
+
+#pragma pack(push, 1)
+
+#define PPSMC_SWSTATE_FLAG_DC                           0x01
+#define PPSMC_SWSTATE_FLAG_UVD                          0x02
+#define PPSMC_SWSTATE_FLAG_VCE                          0x04
+
+#define PPSMC_THERMAL_PROTECT_TYPE_INTERNAL             0x00
+#define PPSMC_THERMAL_PROTECT_TYPE_EXTERNAL             0x01
+#define PPSMC_THERMAL_PROTECT_TYPE_NONE                 0xff
+
+#define PPSMC_SYSTEMFLAG_GPIO_DC                        0x01
+#define PPSMC_SYSTEMFLAG_STEPVDDC                       0x02
+#define PPSMC_SYSTEMFLAG_GDDR5                          0x04
+
+#define PPSMC_SYSTEMFLAG_DISABLE_BABYSTEP               0x08
+
+#define PPSMC_SYSTEMFLAG_REGULATOR_HOT                  0x10
+#define PPSMC_SYSTEMFLAG_REGULATOR_HOT_ANALOG           0x20
+
+#define PPSMC_EXTRAFLAGS_AC2DC_ACTION_MASK              0x07
+#define PPSMC_EXTRAFLAGS_AC2DC_DONT_WAIT_FOR_VBLANK     0x08
+
+#define PPSMC_EXTRAFLAGS_AC2DC_ACTION_GOTODPMLOWSTATE   0x00
+#define PPSMC_EXTRAFLAGS_AC2DC_ACTION_GOTOINITIALSTATE  0x01
+
+/* Defines for DPM 2.0 */
+#define PPSMC_DPM2FLAGS_TDPCLMP                         0x01
+#define PPSMC_DPM2FLAGS_PWRSHFT                         0x02
+#define PPSMC_DPM2FLAGS_OCP                             0x04
+
+/* Defines for display watermark level */
+#define PPSMC_DISPLAY_WATERMARK_LOW                     0
+#define PPSMC_DISPLAY_WATERMARK_HIGH                    1
+
+/* In the HW performance level's state flags: */
+#define PPSMC_STATEFLAG_AUTO_PULSE_SKIP    0x01
+#define PPSMC_STATEFLAG_POWERBOOST         0x02
+#define PPSMC_STATEFLAG_PSKIP_ON_TDP_FAULT 0x04
+#define PPSMC_STATEFLAG_POWERSHIFT         0x08
+#define PPSMC_STATEFLAG_SLOW_READ_MARGIN   0x10
+#define PPSMC_STATEFLAG_DEEPSLEEP_THROTTLE 0x20
+#define PPSMC_STATEFLAG_DEEPSLEEP_BYPASS   0x40
+
+/* Fan control algorithm: */
+#define FDO_MODE_HARDWARE 0
+#define FDO_MODE_PIECE_WISE_LINEAR 1
+
+enum FAN_CONTROL {
+  FAN_CONTROL_FUZZY,
+  FAN_CONTROL_TABLE
+};
+
+/* Gemini Modes*/
+#define PPSMC_GeminiModeNone   0  /*Single GPU board*/
+#define PPSMC_GeminiModeMaster 1  /*Master GPU on a Gemini board*/
+#define PPSMC_GeminiModeSlave  2  /*Slave GPU on a Gemini board*/
+
+
+/* Return codes for driver to SMC communication. */
+#define PPSMC_Result_OK             ((uint16_t)0x01)
+#define PPSMC_Result_NoMore         ((uint16_t)0x02)
+
+#define PPSMC_Result_NotNow         ((uint16_t)0x03)
+
+#define PPSMC_Result_Failed         ((uint16_t)0xFF)
+#define PPSMC_Result_UnknownCmd     ((uint16_t)0xFE)
+#define PPSMC_Result_UnknownVT      ((uint16_t)0xFD)
+
+#define PPSMC_isERROR(x) ((uint16_t)0x80 & (x))
+
+
+#define PPSMC_MSG_Halt                      ((uint16_t)0x10)
+#define PPSMC_MSG_Resume                    ((uint16_t)0x11)
+#define PPSMC_MSG_EnableDPMLevel            ((uint16_t)0x12)
+#define PPSMC_MSG_ZeroLevelsDisabled        ((uint16_t)0x13)
+#define PPSMC_MSG_OneLevelsDisabled         ((uint16_t)0x14)
+#define PPSMC_MSG_TwoLevelsDisabled         ((uint16_t)0x15)
+#define PPSMC_MSG_EnableThermalInterrupt    ((uint16_t)0x16)
+#define PPSMC_MSG_RunningOnAC               ((uint16_t)0x17)
+#define PPSMC_MSG_LevelUp                   ((uint16_t)0x18)
+#define PPSMC_MSG_LevelDown                 ((uint16_t)0x19)
+#define PPSMC_MSG_ResetDPMCounters          ((uint16_t)0x1a)
+#define PPSMC_MSG_SwitchToSwState           ((uint16_t)0x20)
+
+#define PPSMC_MSG_SwitchToSwStateLast       ((uint16_t)0x3f)
+#define PPSMC_MSG_SwitchToInitialState      ((uint16_t)0x40)
+#define PPSMC_MSG_NoForcedLevel             ((uint16_t)0x41)
+#define PPSMC_MSG_ForceHigh                 ((uint16_t)0x42)
+#define PPSMC_MSG_ForceMediumOrHigh         ((uint16_t)0x43)
+
+#define PPSMC_MSG_SwitchToMinimumPower      ((uint16_t)0x51)
+#define PPSMC_MSG_ResumeFromMinimumPower    ((uint16_t)0x52)
+#define PPSMC_MSG_EnableCac                 ((uint16_t)0x53)
+#define PPSMC_MSG_DisableCac                ((uint16_t)0x54)
+#define PPSMC_DPMStateHistoryStart          ((uint16_t)0x55)
+#define PPSMC_DPMStateHistoryStop           ((uint16_t)0x56)
+#define PPSMC_CACHistoryStart               ((uint16_t)0x57)
+#define PPSMC_CACHistoryStop                ((uint16_t)0x58)
+#define PPSMC_TDPClampingActive             ((uint16_t)0x59)
+#define PPSMC_TDPClampingInactive           ((uint16_t)0x5A)
+#define PPSMC_StartFanControl               ((uint16_t)0x5B)
+#define PPSMC_StopFanControl                ((uint16_t)0x5C)
+#define PPSMC_NoDisplay                     ((uint16_t)0x5D)
+#define PPSMC_HasDisplay                    ((uint16_t)0x5E)
+#define PPSMC_MSG_UVDPowerOFF               ((uint16_t)0x60)
+#define PPSMC_MSG_UVDPowerON                ((uint16_t)0x61)
+#define PPSMC_MSG_EnableULV                 ((uint16_t)0x62)
+#define PPSMC_MSG_DisableULV                ((uint16_t)0x63)
+#define PPSMC_MSG_EnterULV                  ((uint16_t)0x64)
+#define PPSMC_MSG_ExitULV                   ((uint16_t)0x65)
+#define PPSMC_PowerShiftActive              ((uint16_t)0x6A)
+#define PPSMC_PowerShiftInactive            ((uint16_t)0x6B)
+#define PPSMC_OCPActive                     ((uint16_t)0x6C)
+#define PPSMC_OCPInactive                   ((uint16_t)0x6D)
+#define PPSMC_CACLongTermAvgEnable          ((uint16_t)0x6E)
+#define PPSMC_CACLongTermAvgDisable         ((uint16_t)0x6F)
+#define PPSMC_MSG_InferredStateSweep_Start  ((uint16_t)0x70)
+#define PPSMC_MSG_InferredStateSweep_Stop   ((uint16_t)0x71)
+#define PPSMC_MSG_SwitchToLowestInfState    ((uint16_t)0x72)
+#define PPSMC_MSG_SwitchToNonInfState       ((uint16_t)0x73)
+#define PPSMC_MSG_AllStateSweep_Start       ((uint16_t)0x74)
+#define PPSMC_MSG_AllStateSweep_Stop        ((uint16_t)0x75)
+#define PPSMC_MSG_SwitchNextLowerInfState   ((uint16_t)0x76)
+#define PPSMC_MSG_SwitchNextHigherInfState  ((uint16_t)0x77)
+#define PPSMC_MSG_MclkRetrainingTest        ((uint16_t)0x78)
+#define PPSMC_MSG_ForceTDPClamping          ((uint16_t)0x79)
+#define PPSMC_MSG_CollectCAC_PowerCorreln   ((uint16_t)0x7A)
+#define PPSMC_MSG_CollectCAC_WeightCalib    ((uint16_t)0x7B)
+#define PPSMC_MSG_CollectCAC_SQonly         ((uint16_t)0x7C)
+#define PPSMC_MSG_CollectCAC_TemperaturePwr ((uint16_t)0x7D)
+
+#define PPSMC_MSG_ExtremitiesTest_Start     ((uint16_t)0x7E)
+#define PPSMC_MSG_ExtremitiesTest_Stop      ((uint16_t)0x7F)
+#define PPSMC_FlushDataCache                ((uint16_t)0x80)
+#define PPSMC_FlushInstrCache               ((uint16_t)0x81)
+
+#define PPSMC_MSG_SetEnabledLevels          ((uint16_t)0x82)
+#define PPSMC_MSG_SetForcedLevels           ((uint16_t)0x83)
+
+#define PPSMC_MSG_ResetToDefaults           ((uint16_t)0x84)
+
+#define PPSMC_MSG_SetForcedLevelsAndJump      ((uint16_t)0x85)
+#define PPSMC_MSG_SetCACHistoryMode           ((uint16_t)0x86)
+#define PPSMC_MSG_EnableDTE                   ((uint16_t)0x87)
+#define PPSMC_MSG_DisableDTE                  ((uint16_t)0x88)
+
+#define PPSMC_MSG_SmcSpaceSetAddress          ((uint16_t)0x89)
+
+#define PPSMC_MSG_BREAK                       ((uint16_t)0xF8)
+
+/* Trinity Specific Messages*/
+#define PPSMC_MSG_Test                        ((uint16_t) 0x100)
+#define PPSMC_MSG_DPM_Voltage_Pwrmgt          ((uint16_t) 0x101)
+#define PPSMC_MSG_DPM_Config                  ((uint16_t) 0x102)
+#define PPSMC_MSG_PM_Controller_Start         ((uint16_t) 0x103)
+#define PPSMC_MSG_DPM_ForceState              ((uint16_t) 0x104)
+#define PPSMC_MSG_PG_PowerDownSIMD            ((uint16_t) 0x105)
+#define PPSMC_MSG_PG_PowerUpSIMD              ((uint16_t) 0x106)
+#define PPSMC_MSG_PM_Controller_Stop          ((uint16_t) 0x107)
+#define PPSMC_MSG_PG_SIMD_Config              ((uint16_t) 0x108)
+#define PPSMC_MSG_Voltage_Cntl_Enable         ((uint16_t) 0x109)
+#define PPSMC_MSG_Thermal_Cntl_Enable         ((uint16_t) 0x10a)
+#define PPSMC_MSG_Reset_Service               ((uint16_t) 0x10b)
+#define PPSMC_MSG_VCEPowerOFF                 ((uint16_t) 0x10e)
+#define PPSMC_MSG_VCEPowerON                  ((uint16_t) 0x10f)
+#define PPSMC_MSG_DPM_Disable_VCE_HS          ((uint16_t) 0x110)
+#define PPSMC_MSG_DPM_Enable_VCE_HS           ((uint16_t) 0x111)
+#define PPSMC_MSG_DPM_N_LevelsDisabled        ((uint16_t) 0x112)
+#define PPSMC_MSG_DCEPowerOFF                 ((uint16_t) 0x113)
+#define PPSMC_MSG_DCEPowerON                  ((uint16_t) 0x114)
+#define PPSMC_MSG_PCIE_DDIPowerDown           ((uint16_t) 0x117)
+#define PPSMC_MSG_PCIE_DDIPowerUp             ((uint16_t) 0x118)
+#define PPSMC_MSG_PCIE_CascadePLLPowerDown    ((uint16_t) 0x119)
+#define PPSMC_MSG_PCIE_CascadePLLPowerUp      ((uint16_t) 0x11a)
+#define PPSMC_MSG_SYSPLLPowerOff              ((uint16_t) 0x11b)
+#define PPSMC_MSG_SYSPLLPowerOn               ((uint16_t) 0x11c)
+#define PPSMC_MSG_DCE_RemoveVoltageAdjustment ((uint16_t) 0x11d)
+#define PPSMC_MSG_DCE_AllowVoltageAdjustment  ((uint16_t) 0x11e)
+#define PPSMC_MSG_DISPLAYPHYStatusNotify      ((uint16_t) 0x11f)
+#define PPSMC_MSG_EnableBAPM                  ((uint16_t) 0x120)
+#define PPSMC_MSG_DisableBAPM                 ((uint16_t) 0x121)
+#define PPSMC_MSG_Spmi_Enable                 ((uint16_t) 0x122)
+#define PPSMC_MSG_Spmi_Timer                  ((uint16_t) 0x123)
+#define PPSMC_MSG_LCLK_DPM_Config             ((uint16_t) 0x124)
+#define PPSMC_MSG_VddNB_Request               ((uint16_t) 0x125)
+#define PPSMC_MSG_PCIE_DDIPhyPowerDown        ((uint32_t) 0x126)
+#define PPSMC_MSG_PCIE_DDIPhyPowerUp          ((uint32_t) 0x127)
+#define PPSMC_MSG_MCLKDPM_Config              ((uint16_t) 0x128)
+
+#define PPSMC_MSG_UVDDPM_Config               ((uint16_t) 0x129)
+#define PPSMC_MSG_VCEDPM_Config               ((uint16_t) 0x12A)
+#define PPSMC_MSG_ACPDPM_Config               ((uint16_t) 0x12B)
+#define PPSMC_MSG_SAMUDPM_Config              ((uint16_t) 0x12C)
+#define PPSMC_MSG_UVDDPM_SetEnabledMask       ((uint16_t) 0x12D)
+#define PPSMC_MSG_VCEDPM_SetEnabledMask       ((uint16_t) 0x12E)
+#define PPSMC_MSG_ACPDPM_SetEnabledMask       ((uint16_t) 0x12F)
+#define PPSMC_MSG_SAMUDPM_SetEnabledMask      ((uint16_t) 0x130)
+#define PPSMC_MSG_MCLKDPM_ForceState          ((uint16_t) 0x131)
+#define PPSMC_MSG_MCLKDPM_NoForcedLevel       ((uint16_t) 0x132)
+#define PPSMC_MSG_Thermal_Cntl_Disable        ((uint16_t) 0x133)
+#define PPSMC_MSG_SetTDPLimit                 ((uint16_t) 0x134)
+#define PPSMC_MSG_Voltage_Cntl_Disable        ((uint16_t) 0x135)
+#define PPSMC_MSG_PCIeDPM_Enable              ((uint16_t) 0x136)
+#define PPSMC_MSG_ACPPowerOFF                 ((uint16_t) 0x137)
+#define PPSMC_MSG_ACPPowerON                  ((uint16_t) 0x138)
+#define PPSMC_MSG_SAMPowerOFF                 ((uint16_t) 0x139)
+#define PPSMC_MSG_SAMPowerON                  ((uint16_t) 0x13a)
+#define PPSMC_MSG_SDMAPowerOFF                ((uint16_t) 0x13b)
+#define PPSMC_MSG_SDMAPowerON                 ((uint16_t) 0x13c)
+#define PPSMC_MSG_PCIeDPM_Disable             ((uint16_t) 0x13d)
+#define PPSMC_MSG_IOMMUPowerOFF               ((uint16_t) 0x13e)
+#define PPSMC_MSG_IOMMUPowerON                ((uint16_t) 0x13f)
+#define PPSMC_MSG_NBDPM_Enable                ((uint16_t) 0x140)
+#define PPSMC_MSG_NBDPM_Disable               ((uint16_t) 0x141)
+#define PPSMC_MSG_NBDPM_ForceNominal          ((uint16_t) 0x142)
+#define PPSMC_MSG_NBDPM_ForcePerformance      ((uint16_t) 0x143)
+#define PPSMC_MSG_NBDPM_UnForce               ((uint16_t) 0x144)
+#define PPSMC_MSG_SCLKDPM_SetEnabledMask      ((uint16_t) 0x145)
+#define PPSMC_MSG_MCLKDPM_SetEnabledMask      ((uint16_t) 0x146)
+#define PPSMC_MSG_PCIeDPM_ForceLevel          ((uint16_t) 0x147)
+#define PPSMC_MSG_PCIeDPM_UnForceLevel        ((uint16_t) 0x148)
+#define PPSMC_MSG_EnableACDCGPIOInterrupt     ((uint16_t) 0x149)
+#define PPSMC_MSG_EnableVRHotGPIOInterrupt    ((uint16_t) 0x14a)
+#define PPSMC_MSG_SwitchToAC                  ((uint16_t) 0x14b)
+
+#define PPSMC_MSG_XDMAPowerOFF                ((uint16_t) 0x14c)
+#define PPSMC_MSG_XDMAPowerON                 ((uint16_t) 0x14d)
+
+#define PPSMC_MSG_DPM_Enable                  ((uint16_t) 0x14e)
+#define PPSMC_MSG_DPM_Disable                 ((uint16_t) 0x14f)
+#define PPSMC_MSG_MCLKDPM_Enable              ((uint16_t) 0x150)
+#define PPSMC_MSG_MCLKDPM_Disable             ((uint16_t) 0x151)
+#define PPSMC_MSG_LCLKDPM_Enable              ((uint16_t) 0x152)
+#define PPSMC_MSG_LCLKDPM_Disable             ((uint16_t) 0x153)
+#define PPSMC_MSG_UVDDPM_Enable               ((uint16_t) 0x154)
+#define PPSMC_MSG_UVDDPM_Disable              ((uint16_t) 0x155)
+#define PPSMC_MSG_SAMUDPM_Enable              ((uint16_t) 0x156)
+#define PPSMC_MSG_SAMUDPM_Disable             ((uint16_t) 0x157)
+#define PPSMC_MSG_ACPDPM_Enable               ((uint16_t) 0x158)
+#define PPSMC_MSG_ACPDPM_Disable              ((uint16_t) 0x159)
+#define PPSMC_MSG_VCEDPM_Enable               ((uint16_t) 0x15a)
+#define PPSMC_MSG_VCEDPM_Disable              ((uint16_t) 0x15b)
+#define PPSMC_MSG_LCLKDPM_SetEnabledMask      ((uint16_t) 0x15c)
+#define PPSMC_MSG_DPM_FPS_Mode                ((uint16_t) 0x15d)
+#define PPSMC_MSG_DPM_Activity_Mode           ((uint16_t) 0x15e)
+#define PPSMC_MSG_VddC_Request                ((uint16_t) 0x15f)
+#define PPSMC_MSG_MCLKDPM_GetEnabledMask      ((uint16_t) 0x160)
+#define PPSMC_MSG_LCLKDPM_GetEnabledMask      ((uint16_t) 0x161)
+#define PPSMC_MSG_SCLKDPM_GetEnabledMask      ((uint16_t) 0x162)
+#define PPSMC_MSG_UVDDPM_GetEnabledMask       ((uint16_t) 0x163)
+#define PPSMC_MSG_SAMUDPM_GetEnabledMask      ((uint16_t) 0x164)
+#define PPSMC_MSG_ACPDPM_GetEnabledMask       ((uint16_t) 0x165)
+#define PPSMC_MSG_VCEDPM_GetEnabledMask       ((uint16_t) 0x166)
+#define PPSMC_MSG_PCIeDPM_SetEnabledMask      ((uint16_t) 0x167)
+#define PPSMC_MSG_PCIeDPM_GetEnabledMask      ((uint16_t) 0x168)
+#define PPSMC_MSG_TDCLimitEnable              ((uint16_t) 0x169)
+#define PPSMC_MSG_TDCLimitDisable             ((uint16_t) 0x16a)
+#define PPSMC_MSG_DPM_AutoRotate_Mode         ((uint16_t) 0x16b)
+#define PPSMC_MSG_DISPCLK_FROM_FCH            ((uint16_t) 0x16c)
+#define PPSMC_MSG_DISPCLK_FROM_DFS            ((uint16_t) 0x16d)
+#define PPSMC_MSG_DPREFCLK_FROM_FCH           ((uint16_t) 0x16e)
+#define PPSMC_MSG_DPREFCLK_FROM_DFS           ((uint16_t) 0x16f)
+#define PPSMC_MSG_PmStatusLogStart            ((uint16_t) 0x170)
+#define PPSMC_MSG_PmStatusLogSample           ((uint16_t) 0x171)
+#define PPSMC_MSG_SCLK_AutoDPM_ON             ((uint16_t) 0x172)
+#define PPSMC_MSG_MCLK_AutoDPM_ON             ((uint16_t) 0x173)
+#define PPSMC_MSG_LCLK_AutoDPM_ON             ((uint16_t) 0x174)
+#define PPSMC_MSG_UVD_AutoDPM_ON              ((uint16_t) 0x175)
+#define PPSMC_MSG_SAMU_AutoDPM_ON             ((uint16_t) 0x176)
+#define PPSMC_MSG_ACP_AutoDPM_ON              ((uint16_t) 0x177)
+#define PPSMC_MSG_VCE_AutoDPM_ON              ((uint16_t) 0x178)
+#define PPSMC_MSG_PCIe_AutoDPM_ON             ((uint16_t) 0x179)
+#define PPSMC_MSG_MASTER_AutoDPM_ON           ((uint16_t) 0x17a)
+#define PPSMC_MSG_MASTER_AutoDPM_OFF          ((uint16_t) 0x17b)
+#define PPSMC_MSG_DYNAMICDISPPHYPOWER         ((uint16_t) 0x17c)
+#define PPSMC_MSG_CAC_COLLECTION_ON           ((uint16_t) 0x17d)
+#define PPSMC_MSG_CAC_COLLECTION_OFF          ((uint16_t) 0x17e)
+#define PPSMC_MSG_CAC_CORRELATION_ON          ((uint16_t) 0x17f)
+#define PPSMC_MSG_CAC_CORRELATION_OFF         ((uint16_t) 0x180)
+#define PPSMC_MSG_PM_STATUS_TO_DRAM_ON        ((uint16_t) 0x181)
+#define PPSMC_MSG_PM_STATUS_TO_DRAM_OFF       ((uint16_t) 0x182)
+#define PPSMC_MSG_ALLOW_LOWSCLK_INTERRUPT     ((uint16_t) 0x184)
+#define PPSMC_MSG_PkgPwrLimitEnable           ((uint16_t) 0x185)
+#define PPSMC_MSG_PkgPwrLimitDisable          ((uint16_t) 0x186)
+#define PPSMC_MSG_PkgPwrSetLimit              ((uint16_t) 0x187)
+#define PPSMC_MSG_OverDriveSetTargetTdp       ((uint16_t) 0x188)
+#define PPSMC_MSG_SCLKDPM_FreezeLevel         ((uint16_t) 0x189)
+#define PPSMC_MSG_SCLKDPM_UnfreezeLevel       ((uint16_t) 0x18A)
+#define PPSMC_MSG_MCLKDPM_FreezeLevel         ((uint16_t) 0x18B)
+#define PPSMC_MSG_MCLKDPM_UnfreezeLevel       ((uint16_t) 0x18C)
+#define PPSMC_MSG_START_DRAM_LOGGING          ((uint16_t) 0x18D)
+#define PPSMC_MSG_STOP_DRAM_LOGGING           ((uint16_t) 0x18E)
+#define PPSMC_MSG_MASTER_DeepSleep_ON         ((uint16_t) 0x18F)
+#define PPSMC_MSG_MASTER_DeepSleep_OFF        ((uint16_t) 0x190)
+#define PPSMC_MSG_Remove_DC_Clamp             ((uint16_t) 0x191)
+#define PPSMC_MSG_DisableACDCGPIOInterrupt    ((uint16_t) 0x192)
+#define PPSMC_MSG_OverrideVoltageControl_SetVddc       ((uint16_t) 0x193)
+#define PPSMC_MSG_OverrideVoltageControl_SetVddci      ((uint16_t) 0x194)
+#define PPSMC_MSG_SetVidOffset_1              ((uint16_t) 0x195)
+#define PPSMC_MSG_SetVidOffset_2              ((uint16_t) 0x207)
+#define PPSMC_MSG_GetVidOffset_1              ((uint16_t) 0x196)
+#define PPSMC_MSG_GetVidOffset_2              ((uint16_t) 0x208)
+#define PPSMC_MSG_THERMAL_OVERDRIVE_Enable    ((uint16_t) 0x197)
+#define PPSMC_MSG_THERMAL_OVERDRIVE_Disable   ((uint16_t) 0x198)
+#define PPSMC_MSG_SetTjMax                    ((uint16_t) 0x199)
+#define PPSMC_MSG_SetFanPwmMax                ((uint16_t) 0x19A)
+#define PPSMC_MSG_WaitForMclkSwitchFinish     ((uint16_t) 0x19B)
+#define PPSMC_MSG_ENABLE_THERMAL_DPM          ((uint16_t) 0x19C)
+#define PPSMC_MSG_DISABLE_THERMAL_DPM         ((uint16_t) 0x19D)
+
+#define PPSMC_MSG_API_GetSclkFrequency        ((uint16_t) 0x200)
+#define PPSMC_MSG_API_GetMclkFrequency        ((uint16_t) 0x201)
+#define PPSMC_MSG_API_GetSclkBusy             ((uint16_t) 0x202)
+#define PPSMC_MSG_API_GetMclkBusy             ((uint16_t) 0x203)
+#define PPSMC_MSG_API_GetAsicPower            ((uint16_t) 0x204)
+#define PPSMC_MSG_SetFanRpmMax                ((uint16_t) 0x205)
+#define PPSMC_MSG_SetFanSclkTarget            ((uint16_t) 0x206)
+#define PPSMC_MSG_SetFanMinPwm                ((uint16_t) 0x209)
+#define PPSMC_MSG_SetFanTemperatureTarget     ((uint16_t) 0x20A)
+
+#define PPSMC_MSG_BACO_StartMonitor           ((uint16_t) 0x240)
+#define PPSMC_MSG_BACO_Cancel                 ((uint16_t) 0x241)
+#define PPSMC_MSG_EnableVddGfx                ((uint16_t) 0x242)
+#define PPSMC_MSG_DisableVddGfx               ((uint16_t) 0x243)
+#define PPSMC_MSG_UcodeAddressLow             ((uint16_t) 0x244)
+#define PPSMC_MSG_UcodeAddressHigh            ((uint16_t) 0x245)
+#define PPSMC_MSG_UcodeLoadStatus             ((uint16_t) 0x246)
+
+#define PPSMC_MSG_DRV_DRAM_ADDR_HI            ((uint16_t) 0x250)
+#define PPSMC_MSG_DRV_DRAM_ADDR_LO            ((uint16_t) 0x251)
+#define PPSMC_MSG_SMU_DRAM_ADDR_HI            ((uint16_t) 0x252)
+#define PPSMC_MSG_SMU_DRAM_ADDR_LO            ((uint16_t) 0x253)
+#define PPSMC_MSG_LoadUcodes                  ((uint16_t) 0x254)
+#define PPSMC_MSG_PowerStateNotify            ((uint16_t) 0x255)
+#define PPSMC_MSG_COND_EXEC_DRAM_ADDR_HI      ((uint16_t) 0x256)
+#define PPSMC_MSG_COND_EXEC_DRAM_ADDR_LO      ((uint16_t) 0x257)
+#define PPSMC_MSG_VBIOS_DRAM_ADDR_HI          ((uint16_t) 0x258)
+#define PPSMC_MSG_VBIOS_DRAM_ADDR_LO          ((uint16_t) 0x259)
+#define PPSMC_MSG_LoadVBios                   ((uint16_t) 0x25A)
+#define PPSMC_MSG_GetUcodeVersion             ((uint16_t) 0x25B)
+#define DMCUSMC_MSG_PSREntry                  ((uint16_t) 0x25C)
+#define DMCUSMC_MSG_PSRExit                   ((uint16_t) 0x25D)
+#define PPSMC_MSG_EnableClockGatingFeature    ((uint16_t) 0x260)
+#define PPSMC_MSG_DisableClockGatingFeature   ((uint16_t) 0x261)
+#define PPSMC_MSG_IsDeviceRunning             ((uint16_t) 0x262)
+#define PPSMC_MSG_LoadMetaData                ((uint16_t) 0x263)
+#define PPSMC_MSG_TMON_AutoCaliberate_Enable  ((uint16_t) 0x264)
+#define PPSMC_MSG_TMON_AutoCaliberate_Disable ((uint16_t) 0x265)
+#define PPSMC_MSG_GetTelemetry1Slope          ((uint16_t) 0x266)
+#define PPSMC_MSG_GetTelemetry1Offset         ((uint16_t) 0x267)
+#define PPSMC_MSG_GetTelemetry2Slope          ((uint16_t) 0x268)
+#define PPSMC_MSG_GetTelemetry2Offset         ((uint16_t) 0x269)
+#define PPSMC_MSG_EnableAvfs                  ((uint16_t) 0x26A)
+#define PPSMC_MSG_DisableAvfs                 ((uint16_t) 0x26B)
+#define PPSMC_MSG_PerformBtc                  ((uint16_t) 0x26C)
+#define PPSMC_MSG_GetHbmCode                  ((uint16_t) 0x26D)
+#define PPSMC_MSG_GetVrVddcTemperature        ((uint16_t) 0x26E)
+#define PPSMC_MSG_GetVrMvddTemperature        ((uint16_t) 0x26F)
+#define PPSMC_MSG_GetLiquidTemperature        ((uint16_t) 0x270)
+#define PPSMC_MSG_GetPlxTemperature           ((uint16_t) 0x271)
+#define PPSMC_MSG_RequestI2CControl           ((uint16_t) 0x272)
+#define PPSMC_MSG_ReleaseI2CControl           ((uint16_t) 0x273)
+#define PPSMC_MSG_LedConfig                   ((uint16_t) 0x274)
+#define PPSMC_MSG_SetHbmFanCode               ((uint16_t) 0x275)
+#define PPSMC_MSG_SetHbmThrottleCode          ((uint16_t) 0x276)
+
+#define PPSMC_MSG_GetEnabledPsm               ((uint16_t) 0x400)
+#define PPSMC_MSG_AgmStartPsm                 ((uint16_t) 0x401)
+#define PPSMC_MSG_AgmReadPsm                  ((uint16_t) 0x402)
+#define PPSMC_MSG_AgmResetPsm                 ((uint16_t) 0x403)
+#define PPSMC_MSG_ReadVftCell                 ((uint16_t) 0x404)
+
+/* AVFS Only - Remove Later */
+#define PPSMC_MSG_VftTableIsValid             ((uint16_t) 0x666)
+
+/* If the SMC firmware has an event status soft register this is what the individual bits mean.*/
+#define PPSMC_EVENT_STATUS_THERMAL          0x00000001
+#define PPSMC_EVENT_STATUS_REGULATORHOT     0x00000002
+#define PPSMC_EVENT_STATUS_DC               0x00000004
+
+typedef uint16_t PPSMC_Msg;
+
+#pragma pack(pop)
+
+#endif
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/powerplay/inc/fiji_pwrvirus.h
@@ -0,0 +1,10299 @@
+/*
+ * Copyright 2015 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+#ifndef _FIJI_PWRVIRUS_H_
+#define _FIJI_PWRVIRUS_H_
+
+#define mmCP_HYP_MEC1_UCODE_ADDR	0xf81a
+#define mmCP_HYP_MEC1_UCODE_DATA	0xf81b
+#define mmCP_HYP_MEC2_UCODE_ADDR	0xf81c
+#define mmCP_HYP_MEC2_UCODE_DATA	0xf81d
+
+enum PWR_Command
+{
+   PwrCmdNull = 0,
+   PwrCmdWrite,
+   PwrCmdEnd,
+   PwrCmdMax
+};
+typedef enum PWR_Command PWR_Command;
+
+struct PWR_Command_Table
+{
+   PWR_Command        command;
+   ULONG              data;
+   ULONG              reg;
+};
+typedef struct PWR_Command_Table PWR_Command_Table;
+
+#define PWR_VIRUS_TABLE_SIZE  10243
+static PWR_Command_Table PwrVirusTable[PWR_VIRUS_TABLE_SIZE] =
+{
+    { PwrCmdWrite, 0x100100b6, mmPCIE_INDEX                               },
+    { PwrCmdWrite, 0x00000000, mmPCIE_DATA                                },
+    { PwrCmdWrite, 0x100100b6, mmPCIE_INDEX                               },
+    { PwrCmdWrite, 0x0300078c, mmPCIE_DATA                                },
+    { PwrCmdWrite, 0x00000000, mmBIF_CLK_CTRL                             },
+    { PwrCmdWrite, 0x00000001, mmBIF_CLK_CTRL                             },
+    { PwrCmdWrite, 0x00000000, mmBIF_CLK_CTRL                             },
+    { PwrCmdWrite, 0x00000003, mmBIF_FB_EN                                },
+    { PwrCmdWrite, 0x00000000, mmBIF_FB_EN                                },
+    { PwrCmdWrite, 0x00000001, mmBIF_DOORBELL_APER_EN                     },
+    { PwrCmdWrite, 0x00000000, mmBIF_DOORBELL_APER_EN                     },
+    { PwrCmdWrite, 0x014000c0, mmPCIE_INDEX                               },
+    { PwrCmdWrite, 0x00000000, mmPCIE_DATA                                },
+    { PwrCmdWrite, 0x014000c0, mmPCIE_INDEX                               },
+    { PwrCmdWrite, 0x22000000, mmPCIE_DATA                                },
+    { PwrCmdWrite, 0x014000c0, mmPCIE_INDEX                               },
+    { PwrCmdWrite, 0x00000000, mmPCIE_DATA                                },
+    /*
+    { PwrCmdWrite, 0x009f0090, mmMC_VM_FB_LOCATION                        },
+    { PwrCmdWrite, 0x00000000, mmMC_CITF_CNTL                             },
+    { PwrCmdWrite, 0x00000000, mmMC_VM_FB_LOCATION                        },
+    { PwrCmdWrite, 0x009f0090, mmMC_VM_FB_LOCATION                        },
+    { PwrCmdWrite, 0x00000000, mmMC_VM_FB_LOCATION                        },
+    { PwrCmdWrite, 0x009f0090, mmMC_VM_FB_LOCATION                        },
+    { PwrCmdWrite, 0x00000000, mmMC_VM_FB_OFFSET                          },*/
+    { PwrCmdWrite, 0x00000000, mmRLC_CSIB_ADDR_LO                         },
+    { PwrCmdWrite, 0x00000000, mmRLC_CSIB_ADDR_HI                         },
+    { PwrCmdWrite, 0x00000000, mmRLC_CSIB_LENGTH                          },
+    /*
+    { PwrCmdWrite, 0x00000000, mmMC_VM_MX_L1_TLB_CNTL                     },
+    { PwrCmdWrite, 0x00000001, mmMC_VM_SYSTEM_APERTURE_LOW_ADDR           },
+    { PwrCmdWrite, 0x00000000, mmMC_VM_SYSTEM_APERTURE_HIGH_ADDR          },
+    { PwrCmdWrite, 0x00000000, mmMC_VM_FB_LOCATION                        },
+    { PwrCmdWrite, 0x009f0090, mmMC_VM_FB_LOCATION                        },*/
+    { PwrCmdWrite, 0x00000000, mmVM_CONTEXT0_CNTL                         },
+    { PwrCmdWrite, 0x00000000, mmVM_CONTEXT1_CNTL                         },
+    /*
+    { PwrCmdWrite, 0x00000000, mmMC_VM_AGP_BASE                           },
+    { PwrCmdWrite, 0x00000002, mmMC_VM_AGP_BOT                            },
+    { PwrCmdWrite, 0x00000000, mmMC_VM_AGP_TOP                            },*/
+    { PwrCmdWrite, 0x04000000, mmATC_VM_APERTURE0_LOW_ADDR                },
+    { PwrCmdWrite, 0x0400ff20, mmATC_VM_APERTURE0_HIGH_ADDR               },
+    { PwrCmdWrite, 0x00000002, mmATC_VM_APERTURE0_CNTL                    },
+    { PwrCmdWrite, 0x0000ffff, mmATC_VM_APERTURE0_CNTL2                   },
+    { PwrCmdWrite, 0x00000001, mmATC_VM_APERTURE1_LOW_ADDR                },
+    { PwrCmdWrite, 0x00000000, mmATC_VM_APERTURE1_HIGH_ADDR               },
+    { PwrCmdWrite, 0x00000000, mmATC_VM_APERTURE1_CNTL                    },
+    { PwrCmdWrite, 0x00000000, mmATC_VM_APERTURE1_CNTL2                   },
+    //{ PwrCmdWrite, 0x00000000, mmMC_ARB_RAMCFG                            },
+    { PwrCmdWrite, 0x12011003, mmGB_ADDR_CONFIG                           },
+    { PwrCmdWrite, 0x00800010, mmGB_TILE_MODE0                            },
+    { PwrCmdWrite, 0x00800810, mmGB_TILE_MODE1                            },
+    { PwrCmdWrite, 0x00801010, mmGB_TILE_MODE2                            },
+    { PwrCmdWrite, 0x00801810, mmGB_TILE_MODE3                            },
+    { PwrCmdWrite, 0x00802810, mmGB_TILE_MODE4                            },
+    { PwrCmdWrite, 0x00802808, mmGB_TILE_MODE5                            },
+    { PwrCmdWrite, 0x00802814, mmGB_TILE_MODE6                            },
+    { PwrCmdWrite, 0x00000000, mmGB_TILE_MODE7                            },
+    { PwrCmdWrite, 0x00000004, mmGB_TILE_MODE8                            },
+    { PwrCmdWrite, 0x02000008, mmGB_TILE_MODE9                            },
+    { PwrCmdWrite, 0x02000010, mmGB_TILE_MODE10                           },
+    { PwrCmdWrite, 0x06000014, mmGB_TILE_MODE11                           },
+    { PwrCmdWrite, 0x00000000, mmGB_TILE_MODE12                           },
+    { PwrCmdWrite, 0x02400008, mmGB_TILE_MODE13                           },
+    { PwrCmdWrite, 0x02400010, mmGB_TILE_MODE14                           },
+    { PwrCmdWrite, 0x02400030, mmGB_TILE_MODE15                           },
+    { PwrCmdWrite, 0x06400014, mmGB_TILE_MODE16                           },
+    { PwrCmdWrite, 0x00000000, mmGB_TILE_MODE17                           },
+    { PwrCmdWrite, 0x0040000c, mmGB_TILE_MODE18                           },
+    { PwrCmdWrite, 0x0100000c, mmGB_TILE_MODE19                           },
+    { PwrCmdWrite, 0x0100001c, mmGB_TILE_MODE20                           },
+    { PwrCmdWrite, 0x01000034, mmGB_TILE_MODE21                           },
+    { PwrCmdWrite, 0x01000024, mmGB_TILE_MODE22                           },
+    { PwrCmdWrite, 0x00000000, mmGB_TILE_MODE23                           },
+    { PwrCmdWrite, 0x0040001c, mmGB_TILE_MODE24                           },
+    { PwrCmdWrite, 0x01000020, mmGB_TILE_MODE25                           },
+    { PwrCmdWrite, 0x01000038, mmGB_TILE_MODE26                           },
+    { PwrCmdWrite, 0x02c00008, mmGB_TILE_MODE27                           },
+    { PwrCmdWrite, 0x02c00010, mmGB_TILE_MODE28                           },
+    { PwrCmdWrite, 0x06c00014, mmGB_TILE_MODE29                           },
+    { PwrCmdWrite, 0x00000000, mmGB_TILE_MODE30                           },
+    { PwrCmdWrite, 0x00000000, mmGB_TILE_MODE31                           },
+    { PwrCmdWrite, 0x000000a8, mmGB_MACROTILE_MODE0                       },
+    { PwrCmdWrite, 0x000000a4, mmGB_MACROTILE_MODE1                       },
+    { PwrCmdWrite, 0x00000090, mmGB_MACROTILE_MODE2                       },
+    { PwrCmdWrite, 0x00000090, mmGB_MACROTILE_MODE3                       },
+    { PwrCmdWrite, 0x00000090, mmGB_MACROTILE_MODE4                       },
+    { PwrCmdWrite, 0x00000090, mmGB_MACROTILE_MODE5                       },
+    { PwrCmdWrite, 0x00000090, mmGB_MACROTILE_MODE6                       },
+    { PwrCmdWrite, 0x00000000, mmGB_MACROTILE_MODE7                       },
+    { PwrCmdWrite, 0x000000ee, mmGB_MACROTILE_MODE8                       },
+    { PwrCmdWrite, 0x000000ea, mmGB_MACROTILE_MODE9                       },
+    { PwrCmdWrite, 0x000000e9, mmGB_MACROTILE_MODE10                      },
+    { PwrCmdWrite, 0x000000e5, mmGB_MACROTILE_MODE11                      },
+    { PwrCmdWrite, 0x000000e4, mmGB_MACROTILE_MODE12                      },
+    { PwrCmdWrite, 0x000000e0, mmGB_MACROTILE_MODE13                      },
+    { PwrCmdWrite, 0x00000090, mmGB_MACROTILE_MODE14                      },
+    { PwrCmdWrite, 0x00000000, mmGB_MACROTILE_MODE15                      },
+    { PwrCmdWrite, 0x00900000, mmHDP_NONSURFACE_BASE                      },
+    { PwrCmdWrite, 0x00008000, mmHDP_NONSURFACE_INFO                      },
+    { PwrCmdWrite, 0x3fffffff, mmHDP_NONSURFACE_SIZE                      },
+    { PwrCmdWrite, 0x00000003, mmBIF_FB_EN                                },
+    //{ PwrCmdWrite, 0x00000000, mmMC_VM_FB_OFFSET                          },
+    { PwrCmdWrite, 0x00000000, mmSRBM_CNTL                                },
+    { PwrCmdWrite, 0x00020000, mmSRBM_CNTL                                },
+    { PwrCmdWrite, 0x80000000, mmATC_VMID0_PASID_MAPPING                  },
+    { PwrCmdWrite, 0x00000000, mmATC_VMID_PASID_MAPPING_UPDATE_STATUS     },
+    { PwrCmdWrite, 0x00000000, mmRLC_CNTL                                 },
+    { PwrCmdWrite, 0x00000000, mmRLC_CNTL                                 },
+    { PwrCmdWrite, 0x00000000, mmRLC_CNTL                                 },
+    { PwrCmdWrite, 0xe0000000, mmGRBM_GFX_INDEX                           },
+    { PwrCmdWrite, 0x00000000, mmCGTS_TCC_DISABLE                         },
+    { PwrCmdWrite, 0x00000000, mmTCP_ADDR_CONFIG                          },
+    { PwrCmdWrite, 0x000000ff, mmTCP_ADDR_CONFIG                          },
+    { PwrCmdWrite, 0x76543210, mmTCP_CHAN_STEER_LO                        },
+    { PwrCmdWrite, 0xfedcba98, mmTCP_CHAN_STEER_HI                        },
+    { PwrCmdWrite, 0x00000000, mmDB_DEBUG2                                },
+    { PwrCmdWrite, 0x00000000, mmDB_DEBUG                                 },
+    { PwrCmdWrite, 0x00002b16, mmCP_QUEUE_THRESHOLDS                      },
+    { PwrCmdWrite, 0x00006030, mmCP_MEQ_THRESHOLDS                        },
+    { PwrCmdWrite, 0x01000104, mmSPI_CONFIG_CNTL_1                        },
+    { PwrCmdWrite, 0x98184020, mmPA_SC_FIFO_SIZE                          },
+    { PwrCmdWrite, 0x00000001, mmVGT_NUM_INSTANCES                        },
+    { PwrCmdWrite, 0x00000000, mmCP_PERFMON_CNTL                          },
+    { PwrCmdWrite, 0x01180000, mmSQ_CONFIG                                },
+    { PwrCmdWrite, 0x00000000, mmVGT_CACHE_INVALIDATION                   },
+    { PwrCmdWrite, 0x00000000, mmSQ_THREAD_TRACE_BASE                     },
+    { PwrCmdWrite, 0x0000df80, mmSQ_THREAD_TRACE_MASK                     },
+    { PwrCmdWrite, 0x02249249, mmSQ_THREAD_TRACE_MODE                     },
+    { PwrCmdWrite, 0x00000000, mmPA_SC_LINE_STIPPLE_STATE                 },
+    { PwrCmdWrite, 0x00000000, mmCB_PERFCOUNTER0_SELECT1                  },
+    { PwrCmdWrite, 0x06000100, mmCGTT_VGT_CLK_CTRL                        },
+    { PwrCmdWrite, 0x00000007, mmPA_CL_ENHANCE                            },
+    { PwrCmdWrite, 0x00000001, mmPA_SC_ENHANCE                            },
+    { PwrCmdWrite, 0x00ffffff, mmPA_SC_FORCE_EOV_MAX_CNTS                 },
+    { PwrCmdWrite, 0x00000000, mmSRBM_GFX_CNTL                            },
+    { PwrCmdWrite, 0x00000320, mmSH_MEM_CONFIG                            },
+    { PwrCmdWrite, 0x00000010, mmSRBM_GFX_CNTL                            },
+    { PwrCmdWrite, 0x00000320, mmSH_MEM_CONFIG                            },
+    { PwrCmdWrite, 0x00000020, mmSRBM_GFX_CNTL                            },
+    { PwrCmdWrite, 0x00000320, mmSH_MEM_CONFIG                            },
+    { PwrCmdWrite, 0x00000030, mmSRBM_GFX_CNTL                            },
+    { PwrCmdWrite, 0x00000320, mmSH_MEM_CONFIG                            },
+    { PwrCmdWrite, 0x00000040, mmSRBM_GFX_CNTL                            },
+    { PwrCmdWrite, 0x00000320, mmSH_MEM_CONFIG                            },
+    { PwrCmdWrite, 0x00000050, mmSRBM_GFX_CNTL                            },
+    { PwrCmdWrite, 0x00000320, mmSH_MEM_CONFIG                            },
+    { PwrCmdWrite, 0x00000060, mmSRBM_GFX_CNTL                            },
+    { PwrCmdWrite, 0x00000320, mmSH_MEM_CONFIG                            },
+    { PwrCmdWrite, 0x00000070, mmSRBM_GFX_CNTL                            },
+    { PwrCmdWrite, 0x00000320, mmSH_MEM_CONFIG                            },
+    { PwrCmdWrite, 0x00000080, mmSRBM_GFX_CNTL                            },
+    { PwrCmdWrite, 0x00000320, mmSH_MEM_CONFIG                            },
+    { PwrCmdWrite, 0x00000090, mmSRBM_GFX_CNTL                            },
+    { PwrCmdWrite, 0x00000320, mmSH_MEM_CONFIG                            },
+    { PwrCmdWrite, 0x000000a0, mmSRBM_GFX_CNTL                            },
+    { PwrCmdWrite, 0x00000320, mmSH_MEM_CONFIG                            },
+    { PwrCmdWrite, 0x000000b0, mmSRBM_GFX_CNTL                            },
+    { PwrCmdWrite, 0x00000320, mmSH_MEM_CONFIG                            },
+    { PwrCmdWrite, 0x000000c0, mmSRBM_GFX_CNTL                            },
+    { PwrCmdWrite, 0x00000320, mmSH_MEM_CONFIG                            },
+    { PwrCmdWrite, 0x000000d0, mmSRBM_GFX_CNTL                            },
+    { PwrCmdWrite, 0x00000320, mmSH_MEM_CONFIG                            },
+    { PwrCmdWrite, 0x000000e0, mmSRBM_GFX_CNTL                            },
+    { PwrCmdWrite, 0x00000320, mmSH_MEM_CONFIG                            },
+    { PwrCmdWrite, 0x000000f0, mmSRBM_GFX_CNTL                            },
+    { PwrCmdWrite, 0x00000320, mmSH_MEM_CONFIG                            },
+    { PwrCmdWrite, 0x00000000, mmSRBM_GFX_CNTL                            },
+    { PwrCmdWrite, 0x00000000, mmGRBM_STATUS                              },
+    { PwrCmdWrite, 0x00000000, mmGRBM_STATUS                              },
+    { PwrCmdWrite, 0x00000000, mmGRBM_STATUS                              },
+    { PwrCmdWrite, 0x00000000, mmGRBM_STATUS                              },
+    { PwrCmdWrite, 0x00000000, mmGRBM_STATUS                              },
+    { PwrCmdWrite, 0x00000000, mmGRBM_STATUS                              },
+    { PwrCmdWrite, 0x00000000, mmGRBM_STATUS                              },
+    { PwrCmdWrite, 0x00000000, mmGRBM_STATUS                              },
+    { PwrCmdWrite, 0x00000000, mmGRBM_STATUS                              },
+    { PwrCmdWrite, 0x00000000, mmGRBM_STATUS                              },
+    { PwrCmdWrite, 0x00000000, mmGRBM_STATUS                              },
+    { PwrCmdWrite, 0x00000000, mmGRBM_STATUS                              },
+    { PwrCmdWrite, 0x00000000, mmGRBM_STATUS                              },
+    { PwrCmdWrite, 0x00000000, mmGRBM_STATUS                              },
+    { PwrCmdWrite, 0x00000000, mmGRBM_STATUS                              },
+    { PwrCmdWrite, 0x00000000, mmGRBM_STATUS                              },
+    { PwrCmdWrite, 0x00000000, mmGRBM_STATUS                              },
+    { PwrCmdWrite, 0x00000000, mmGRBM_STATUS                              },
+    { PwrCmdWrite, 0x00000000, mmGRBM_STATUS                              },
+    { PwrCmdWrite, 0x00000000, mmGRBM_STATUS                              },
+    { PwrCmdWrite, 0x00000000, mmGRBM_STATUS                              },
+    { PwrCmdWrite, 0x00000000, mmGRBM_STATUS                              },
+    { PwrCmdWrite, 0x00000000, mmGRBM_STATUS                              },
+    { PwrCmdWrite, 0x00000000, mmGRBM_STATUS                              },
+    { PwrCmdWrite, 0x00000000, mmGRBM_STATUS                              },
+    { PwrCmdWrite, 0x00000000, mmGRBM_STATUS                              },
+    { PwrCmdWrite, 0x00000000, mmGRBM_STATUS                              },
+    { PwrCmdWrite, 0x00000000, mmGRBM_STATUS                              },
+    { PwrCmdWrite, 0x00000000, mmGRBM_STATUS                              },
+    { PwrCmdWrite, 0x00000000, mmRLC_PG_CNTL                              },
+    { PwrCmdWrite, 0x00000000, mmGRBM_STATUS2                             },
+    { PwrCmdWrite, 0x15000000, mmCP_ME_CNTL                               },
+    { PwrCmdWrite, 0x50000000, mmCP_MEC_CNTL                              },
+    { PwrCmdWrite, 0x00000000, mmSRBM_GFX_CNTL                            },
+    { PwrCmdWrite, 0x0000000e, mmSH_MEM_APE1_BASE                         },
+    { PwrCmdWrite, 0x0000020d, mmSH_MEM_APE1_LIMIT                        },
+    { PwrCmdWrite, 0x00000000, mmSRBM_GFX_CNTL                            },
+    { PwrCmdWrite, 0x00000000, mmSRBM_GFX_CNTL                            },
+    { PwrCmdWrite, 0x00000000, mmSH_MEM_CONFIG                            },
+    { PwrCmdWrite, 0x00000320, mmSH_MEM_CONFIG                            },
+    { PwrCmdWrite, 0x00000000, mmSRBM_GFX_CNTL                            },
+    { PwrCmdWrite, 0x00000000, mmCP_RB_VMID                               },
+    { PwrCmdWrite, 0x00000000, mmGRBM_STATUS                              },
+    { PwrCmdWrite, 0x00000000, mmRLC_CNTL                                 },
+    { PwrCmdWrite, 0x00000000, mmRLC_CNTL                                 },
+    { PwrCmdWrite, 0x00000000, mmRLC_SRM_CNTL                             },
+    { PwrCmdWrite, 0x00000002, mmRLC_SRM_CNTL                             },
+    { PwrCmdWrite, 0x00000000, mmCP_ME_CNTL                               },
+    { PwrCmdWrite, 0x15000000, mmCP_ME_CNTL                               },
+    { PwrCmdWrite, 0x00000000, mmCP_MEC_CNTL                              },
+    { PwrCmdWrite, 0x50000000, mmCP_MEC_CNTL                              },
+    { PwrCmdWrite, 0x80000004, mmCP_DFY_CNTL                              },
+    { PwrCmdWrite, 0x0840800a, mmCP_RB0_CNTL                              },
+    { PwrCmdWrite, 0xf30fff0f, mmTCC_CTRL                                 },
+    { PwrCmdWrite, 0x00000002, mmTCC_EXE_DISABLE                          },
+    { PwrCmdWrite, 0x000000ff, mmTCP_ADDR_CONFIG                          },
+    { PwrCmdWrite, 0x540ff000, mmCP_CPC_IC_BASE_LO                        },
+    { PwrCmdWrite, 0x000000b4, mmCP_CPC_IC_BASE_HI                        },
+    { PwrCmdWrite, 0x00010000, mmCP_HYP_MEC1_UCODE_ADDR                   },
+    { PwrCmdWrite, 0x00041b75, mmCP_HYP_MEC1_UCODE_DATA                   },
+    { PwrCmdWrite, 0x000710e8, mmCP_HYP_MEC1_UCODE_DATA                   },
+    { PwrCmdWrite, 0x000910dd, mmCP_HYP_MEC1_UCODE_DATA                   },
+    { PwrCmdWrite, 0x000a1081, mmCP_HYP_MEC1_UCODE_DATA                   },
+    { PwrCmdWrite, 0x000b016f, mmCP_HYP_MEC1_UCODE_DATA                   },
+    { PwrCmdWrite, 0x000c0e3c, mmCP_HYP_MEC1_UCODE_DATA                   },
+    { PwrCmdWrite, 0x000d10ec, mmCP_HYP_MEC1_UCODE_DATA                   },
+    { PwrCmdWrite, 0x000e0188, mmCP_HYP_MEC1_UCODE_DATA                   },
+    { PwrCmdWrite, 0x00101b5d, mmCP_HYP_MEC1_UCODE_DATA                   },
+    { PwrCmdWrite, 0x00150a6c, mmCP_HYP_MEC1_UCODE_DATA                   },
+    { PwrCmdWrite, 0x00170c5e, mmCP_HYP_MEC1_UCODE_DATA                   },
+    { PwrCmdWrite, 0x001d0c8c, mmCP_HYP_MEC1_UCODE_DATA                   },
+    { PwrCmdWrite, 0x001e0cfe, mmCP_HYP_MEC1_UCODE_DATA                   },
+    { PwrCmdWrite, 0x00221408, mmCP_HYP_MEC1_UCODE_DATA                   },
+    { PwrCmdWrite, 0x00370d7b, mmCP_HYP_MEC1_UCODE_DATA                   },
+    { PwrCmdWrite, 0x00390dcb, mmCP_HYP_MEC1_UCODE_DATA                   },
+    { PwrCmdWrite, 0x003c142f, mmCP_HYP_MEC1_UCODE_DATA                   },
+    { PwrCmdWrite, 0x003f0b27, mmCP_HYP_MEC1_UCODE_DATA                   },
+    { PwrCmdWrite, 0x00400e63, mmCP_HYP_MEC1_UCODE_DATA                   },
+    { PwrCmdWrite, 0x00500f62, mmCP_HYP_MEC1_UCODE_DATA                   },
+    { PwrCmdWrite, 0x00460fa7, mmCP_HYP_MEC1_UCODE_DATA                   },
+    { PwrCmdWrite, 0x00490fa7, mmCP_HYP_MEC1_UCODE_DATA                   },
+    { PwrCmdWrite, 0x005811d4, mmCP_HYP_MEC1_UCODE_DATA                   },
+    { PwrCmdWrite, 0x00680ad6, mmCP_HYP_MEC1_UCODE_DATA                   },
+    { PwrCmdWrite, 0x00760b00, mmCP_HYP_MEC1_UCODE_DATA                   },
+    { PwrCmdWrite, 0x00780b0c, mmCP_HYP_MEC1_UCODE_DATA                   },
+    { PwrCmdWrite, 0x00790af7, mmCP_HYP_MEC1_UCODE_DATA                   },
+    { PwrCmdWrite, 0x007d1aba, mmCP_HYP_MEC1_UCODE_DATA                   },
+    { PwrCmdWrite, 0x007e1abe, mmCP_HYP_MEC1_UCODE_DATA                   },
+    { PwrCmdWrite, 0x00591260, mmCP_HYP_MEC1_UCODE_DATA                   },
+    { PwrCmdWrite, 0x005a12fb, mmCP_HYP_MEC1_UCODE_DATA                   },
+    { PwrCmdWrite, 0x00861ac7, mmCP_HYP_MEC1_UCODE_DATA                   },
+    { PwrCmdWrite, 0x008c1b01, mmCP_HYP_MEC1_UCODE_DATA                   },
+    { PwrCmdWrite, 0x008d1b34, mmCP_HYP_MEC1_UCODE_DATA                   },
+    { PwrCmdWrite, 0x00a014b9, mmCP_HYP_MEC1_UCODE_DATA                   },
+    { PwrCmdWrite, 0x00a1152e, mmCP_HYP_MEC1_UCODE_DATA                   },
+    { PwrCmdWrite, 0x00a216fb, mmCP_HYP_MEC1_UCODE_DATA                   },
+    { PwrCmdWrite, 0x00a41890, mmCP_HYP_MEC1_UCODE_DATA                   },
+    { PwrCmdWrite, 0x00a31906, mmCP_HYP_MEC1_UCODE_DATA                   },
+    { PwrCmdWrite, 0x00a50b14, mmCP_HYP_MEC1_UCODE_DATA                   },
+    { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA                   },
+    { PwrCmdWrite, 0x00621387, mmCP_HYP_MEC1_UCODE_DATA                   },
+    { PwrCmdWrite, 0x005c0b27, mmCP_HYP_MEC1_UCODE_DATA                   },
+    { PwrCmdWrite, 0x00160a75, mmCP_HYP_MEC1_UCODE_DATA                   },
+    { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA                   },
+    { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA                   },
+    { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA                   },
+    { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA                   },
+    { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA                   },
+    { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA                   },
+    { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA                   },
+    { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA                   },
+    { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA                   },
+    { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA                   },
+    { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA                   },
+    { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA                   },
+    { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA                   },
+    { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA                   },
+    { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA                   },
+    { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA                   },
+    { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA                   },
+    { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA                   },
+    { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA                   },
+    { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA                   },
+    { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA                   },
+    { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA                   },
+    { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA                   },
+    { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA                   },
+    { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA                   },
+    { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA                   },
+    { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA                   },
+    { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA                   },
+    { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA                   },
+    { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA                   },
+    { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA                   },
+    { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA                   },
+    { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA                   },
+    { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA                   },
+    { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA                   },
+    { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA                   },
+    { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA                   },
+    { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA                   },
+    { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA                   },
+    { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA                   },
+    { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA                   },
+    { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA                   },
+    { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA                   },
+    { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA                   },
+    { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA                   },
+    { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA                   },
+    { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA                   },
+    { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA                   },
+    { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA                   },
+    { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA                   },
+    { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA                   },
+    { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA                   },
+    { PwrCmdWrite, 0x00010000, mmCP_HYP_MEC2_UCODE_ADDR                   },
+    { PwrCmdWrite, 0x00041b75, mmCP_HYP_MEC2_UCODE_DATA                   },
+    { PwrCmdWrite, 0x000710e8, mmCP_HYP_MEC2_UCODE_DATA                   },
+    { PwrCmdWrite, 0x000910dd, mmCP_HYP_MEC2_UCODE_DATA                   },
+    { PwrCmdWrite, 0x000a1081, mmCP_HYP_MEC2_UCODE_DATA                   },
+    { PwrCmdWrite, 0x000b016f, mmCP_HYP_MEC2_UCODE_DATA                   },
+    { PwrCmdWrite, 0x000c0e3c, mmCP_HYP_MEC2_UCODE_DATA                   },
+    { PwrCmdWrite, 0x000d10ec, mmCP_HYP_MEC2_UCODE_DATA                   },
+    { PwrCmdWrite, 0x000e0188, mmCP_HYP_MEC2_UCODE_DATA                   },
+    { PwrCmdWrite, 0x00101b5d, mmCP_HYP_MEC2_UCODE_DATA                   },
+    { PwrCmdWrite, 0x00150a6c, mmCP_HYP_MEC2_UCODE_DATA                   },
+    { PwrCmdWrite, 0x00170c5e, mmCP_HYP_MEC2_UCODE_DATA                   },
+    { PwrCmdWrite, 0x001d0c8c, mmCP_HYP_MEC2_UCODE_DATA                   },
+    { PwrCmdWrite, 0x001e0cfe, mmCP_HYP_MEC2_UCODE_DATA                   },
+    { PwrCmdWrite, 0x00221408, mmCP_HYP_MEC2_UCODE_DATA                   },
+    { PwrCmdWrite, 0x00370d7b, mmCP_HYP_MEC2_UCODE_DATA                   },
+    { PwrCmdWrite, 0x00390dcb, mmCP_HYP_MEC2_UCODE_DATA                   },
+    { PwrCmdWrite, 0x003c142f, mmCP_HYP_MEC2_UCODE_DATA                   },
+    { PwrCmdWrite, 0x003f0b27, mmCP_HYP_MEC2_UCODE_DATA                   },
+    { PwrCmdWrite, 0x00400e63, mmCP_HYP_MEC2_UCODE_DATA                   },
+    { PwrCmdWrite, 0x00500f62, mmCP_HYP_MEC2_UCODE_DATA                   },
+    { PwrCmdWrite, 0x00460fa7, mmCP_HYP_MEC2_UCODE_DATA                   },
+    { PwrCmdWrite, 0x00490fa7, mmCP_HYP_MEC2_UCODE_DATA                   },
+    { PwrCmdWrite, 0x005811d4, mmCP_HYP_MEC2_UCODE_DATA                   },
+    { PwrCmdWrite, 0x00680ad6, mmCP_HYP_MEC2_UCODE_DATA                   },
+    { PwrCmdWrite, 0x00760b00, mmCP_HYP_MEC2_UCODE_DATA                   },
+    { PwrCmdWrite, 0x00780b0c, mmCP_HYP_MEC2_UCODE_DATA                   },
+    { PwrCmdWrite, 0x00790af7, mmCP_HYP_MEC2_UCODE_DATA                   },
+    { PwrCmdWrite, 0x007d1aba, mmCP_HYP_MEC2_UCODE_DATA                   },
+    { PwrCmdWrite, 0x007e1abe, mmCP_HYP_MEC2_UCODE_DATA                   },
+    { PwrCmdWrite, 0x00591260, mmCP_HYP_MEC2_UCODE_DATA                   },
+    { PwrCmdWrite, 0x005a12fb, mmCP_HYP_MEC2_UCODE_DATA                   },
+    { PwrCmdWrite, 0x00861ac7, mmCP_HYP_MEC2_UCODE_DATA                   },
+    { PwrCmdWrite, 0x008c1b01, mmCP_HYP_MEC2_UCODE_DATA                   },
+    { PwrCmdWrite, 0x008d1b34, mmCP_HYP_MEC2_UCODE_DATA                   },
+    { PwrCmdWrite, 0x00a014b9, mmCP_HYP_MEC2_UCODE_DATA                   },
+    { PwrCmdWrite, 0x00a1152e, mmCP_HYP_MEC2_UCODE_DATA                   },
+    { PwrCmdWrite, 0x00a216fb, mmCP_HYP_MEC2_UCODE_DATA                   },
+    { PwrCmdWrite, 0x00a41890, mmCP_HYP_MEC2_UCODE_DATA                   },
+    { PwrCmdWrite, 0x00a31906, mmCP_HYP_MEC2_UCODE_DATA                   },
+    { PwrCmdWrite, 0x00a50b14, mmCP_HYP_MEC2_UCODE_DATA                   },
+    { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA                   },
+    { PwrCmdWrite, 0x00621387, mmCP_HYP_MEC2_UCODE_DATA                   },
+    { PwrCmdWrite, 0x005c0b27, mmCP_HYP_MEC2_UCODE_DATA                   },
+    { PwrCmdWrite, 0x00160a75, mmCP_HYP_MEC2_UCODE_DATA                   },
+    { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA                   },
+    { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA                   },
+    { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA                   },
+    { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA                   },
+    { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA                   },
+    { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA                   },
+    { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA                   },
+    { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA                   },
+    { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA                   },
+    { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA                   },
+    { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA                   },
+    { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA                   },
+    { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA                   },
+    { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA                   },
+    { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA                   },
+    { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA                   },
+    { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA                   },
+    { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA                   },
+    { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA                   },
+    { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA                   },
+    { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA                   },
+    { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA                   },
+    { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA                   },
+    { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA                   },
+    { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA                   },
+    { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA                   },
+    { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA                   },
+    { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA                   },
+    { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA                   },
+    { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA                   },
+    { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA                   },
+    { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA                   },
+    { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA                   },
+    { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA                   },
+    { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA                   },
+    { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA                   },
+    { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA                   },
+    { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA                   },
+    { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA                   },
+    { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA                   },
+    { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA                   },
+    { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA                   },
+    { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA                   },
+    { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA                   },
+    { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA                   },
+    { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA                   },
+    { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA                   },
+    { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA                   },
+    { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA                   },
+    { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA                   },
+    { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA                   },
+    { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA                   },
+    { PwrCmdWrite, 0x80000004, mmCP_DFY_CNTL                              },
+    { PwrCmdWrite, 0x000000b4, mmCP_DFY_ADDR_HI                           },
+    { PwrCmdWrite, 0x540fe800, mmCP_DFY_ADDR_LO                           },
+    { PwrCmdWrite, 0x7e000200, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7e020201, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7e040204, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7e060205, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xbf810000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000005, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x54106f00, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x000400b4, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00004000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00804fac, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000004, mmCP_DFY_CNTL                              },
+    { PwrCmdWrite, 0x000000b4, mmCP_DFY_ADDR_HI                           },
+    { PwrCmdWrite, 0x540fef00, mmCP_DFY_ADDR_LO                           },
+    { PwrCmdWrite, 0xc0031502, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00001e00, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000004, mmCP_DFY_CNTL                              },
+    { PwrCmdWrite, 0x000000b4, mmCP_DFY_ADDR_HI                           },
+    { PwrCmdWrite, 0x540ff000, mmCP_DFY_ADDR_LO                           },
+    { PwrCmdWrite, 0xc424000b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000145, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x94800001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x94c00001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x95000001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x95400001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x95800001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xdc810000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xdcc10000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xdd010000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xdd410000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xdd810000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4080061, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8000003, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc40c0001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x24ccffff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x3cd08000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9500fffd, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1cd0ffcf, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7d018001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4140004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x050c0019, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x84c00000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000023, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000067, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8000006a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8000006d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000079, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000084, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8000008f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000099, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x800000a0, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x800000af, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400053, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4080007, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x388c0001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x08880002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04100003, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x94c00005, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x98800003, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04100004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8000002d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04100005, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8c00003f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8c000043, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x28cc0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xccc00050, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8c000055, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x28080001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcc000004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7d808001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd88130b8, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd400008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xdc180000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xdc140000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xdc100000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xdc0c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcc800005, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xdc080000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000168, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc40c000e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x28cc0008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xccc00013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd013278, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4113278, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x95000001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x24cc0700, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400029, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4113255, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd01324f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4113254, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1d10ffdf, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd013254, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x10cc0014, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1d10c017, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7d0d000a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd0130b7, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x14cc0010, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd9c00036, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8000005d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc00c4000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xccc130b5, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc40c000e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x28cc0008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xccc00013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc40c0021, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x14d00011, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9500fffe, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xdc030000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd800000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd800000d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc40c005e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x94c01b10, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc00e0080, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xccc130b5, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8000013b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc00e0800, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xccc130b5, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8000013b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400053, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04100006, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8c00003f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8c000043, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x28cc0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xccc00050, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8c000055, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x280c0008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xccc00052, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8000021, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x28180039, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000034, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400053, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04100007, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8c00003f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8c000043, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x28cc0001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xccc00050, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8c000055, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x280c0010, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xccc00052, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x28180039, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000034, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400053, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04100008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8c00003f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8c000043, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x28cc0003, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xccc00050, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8c000055, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x280c0020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xccc00052, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x28180039, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000034, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xdc030000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8000069, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x28080001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc428000d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7ca88004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcc800079, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04280001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcc00006f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8000013b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000034, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04100010, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8c00003f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8c000043, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xccc00078, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8c000055, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x28180080, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000034, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04100001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc40c000e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x28cc0008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xccc00013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd013278, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4113278, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x95000001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc00c4000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4113254, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1d10c017, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xccc130b5, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd0130b7, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8000013b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x95c00001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x96000001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x96400001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x96800001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x96c00001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x97000001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x97400001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x97800001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x97c00001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xdc810000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc40c000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd4c0380, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcdcc0388, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x55dc0020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcdcc038c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce0c0390, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x56200020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce0c0394, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce4c0398, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x56640020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce4c039c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce8c03a0, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x56a80020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce8c03a4, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcecc03a8, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x56ec0020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcecc03ac, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf0c03b0, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x57300020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf0c03b4, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf4c03b8, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x57740020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf4c03bc, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf8c03c0, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x57b80020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf8c03c4, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcfcc03c8, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x57fc0020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcfcc03cc, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd9000033, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc41c0009, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x25dc0010, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x95c0fffe, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc41c000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x05dc002f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcdc12009, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc41d200a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcc012009, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd9000034, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x25e01c00, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x12200013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x25e40300, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x12640008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x25e800c0, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x12a80002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x25ec003f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7e25c00a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7eae400a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7de5c00a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xddc10000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc02ee000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcec1c200, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc40c005f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xccc00037, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x24d000ff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x31100006, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9500007b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8c000190, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xdc1c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcdc1c200, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc40c000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4df0388, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4d7038c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x51540020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7d5dc01a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4e30390, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4d70394, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x51540020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7d62001a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4e70398, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4d7039c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x51540020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7d66401a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4eb03a0, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4d703a4, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x51540020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7d6a801a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4ef03a8, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4d703ac, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x51540020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7d6ec01a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4f303b0, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4d703b4, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x51540020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7d73001a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4f703b8, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4d703bc, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x51540020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7d77401a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4fb03c0, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4d703c4, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x51540020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7d7b801a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4ff03c8, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4d703cc, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x51540020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7d7fc01a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xdc080000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcc800013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4d70380, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4080001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1c88001c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd400008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc40c0083, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x94c00010, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xdc0e0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x94c0000e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc40c0082, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x24d00001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9900000b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x18cc01e3, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x3cd00004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x95000008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc40c0085, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x18cc006a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x98c00005, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc40c0082, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x18cc01e3, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x3cd00004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9900fffa, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xdc180000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xdc140000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xdc100000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xdc0c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcc800004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xdc080000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4080001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1c88001c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd400008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xdc180000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xdc140000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xdc100000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xdc0c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcc800004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xdc080000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400051, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc428000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04180018, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x32640002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9a80001f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9a40001e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd800013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4293265, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x040c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1aac0027, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x2aa80080, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce813265, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9ac00017, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd80002f1, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04080002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x08880001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8080250, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8080258, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8080230, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8080238, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8080240, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8080248, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8080268, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8080270, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8080278, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8080280, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8080228, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8000367, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9880fff3, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04080010, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x08880001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd80c0309, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd80c0319, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04cc0001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9880fffc, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c408001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x88000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc00e0100, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xccc130b5, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8000016e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4180032, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x29980008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd800013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x95800001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c40c001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x18d0003f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x24d4001f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x24d80001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x155c0001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x05e80180, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9900000b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x202c003d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd800010, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcec1325b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc42d325b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x96c00001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x86800000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000168, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000aa7, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000bfc, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x800012e9, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4200007, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a200001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce000010, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80001b70, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c40c001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8c000190, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc410001b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8000032, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8000031, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9900091a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c408001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x88000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x24d000ff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x05280196, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x18d4fe04, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x29540008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x86800000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x800001b4, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8000032b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000350, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000352, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8000035f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000701, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8000047c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8000019f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000800, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc419325b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1d98001f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd81325b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8c00003f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4140004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04100002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8c000043, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x28cc0002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xccc00050, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc43c0044, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x27fc0003, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9bc00002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x97c00006, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc00c4000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xccc130b5, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8c000055, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd88130b8, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd400008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7d40c001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400028, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400029, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd9400036, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4193256, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc41d3254, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x15540008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd400009, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd40005b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd40005e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd40005d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd840006d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc421325a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc42d3249, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x11540015, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x19a4003c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1998003f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1af0007d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x11dc000b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1264001f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x15dc000d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7d65400a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x13300018, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1a38003f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7dd5c00a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7df1c00a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd800045, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcdc00100, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc411326a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc415326b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc419326c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc41d326d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc425326e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4293279, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce800077, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd000056, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd400057, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd800058, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcdc00059, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4193265, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x259c8000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x99c00004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce40005a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x29988000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd813265, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4113248, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x2510000f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd000073, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc418000d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc411326f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x17300019, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x97000009, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x25140fff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x95400007, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd800003a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8c001b6d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4153279, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd400077, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd00005f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8000075, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x26f00001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x15100010, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7d190004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd000035, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x97000035, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1af07fe8, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8800013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400010, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf00000d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf00000a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8c001427, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04340022, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x07740001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04300010, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xdf430000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c434001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c408001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd4412e01, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0434001e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xdf430000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd4400078, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xdf030000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd4412e40, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcc41c030, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcc41c031, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc43dc031, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xccc00013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04343000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4113246, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc41d3245, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf413267, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x51100020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7dd1c01a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4353267, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x45dc0160, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc810001f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1b4c0057, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1b700213, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1b740199, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7f4f400a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7f73400a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x55180020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x2198003f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd1c00025, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf400024, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd000026, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd800026, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400027, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9bc00001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x248dfffe, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8800013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xccc12e00, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c434001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c434001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8c00142b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc43c000e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1af4007d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x2bfc0008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x33740003, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x26d80001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcfc00013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1ae8003e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9680000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4253277, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x26680001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x96800009, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x2a640002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce413277, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4253348, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce413348, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4253348, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x96400001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcfc00013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9b400003, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x958000d8, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000315, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4253277, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04303000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x26680001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf013267, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4193246, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc41d3245, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4313267, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x96800041, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x51980020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1b342010, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7d9d801a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1714000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x25540800, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1b30c012, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x459801b0, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7d77400a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7f37000a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x2b300000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf00001c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd180001e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04240010, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x199c01e2, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7e5e4002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x3e5c0004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x3e540002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc428000f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9a80ffff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x95c00006, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc80c0011, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc8140011, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x54d00020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x55580020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000282, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x95400015, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc80c0011, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a640002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x041c0001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x45980008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x54d00020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x96400004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc8140011, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x45980004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x041c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf00001c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd180001e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc428000f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9a80ffff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x99c00003, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc8180011, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000282, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc8140011, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x55580020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000282, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x45980004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc80c0011, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf00001c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd180001e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc428000f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9a80ffff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc8100011, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc8140011, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x55580020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xccc1334e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd01334f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd413350, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd813351, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd881334d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcfc00013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4193273, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc41d3275, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc40d3271, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4113270, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4153274, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x50cc0020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7cd0c01a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7cdcc011, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x05900008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd00006a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcdc0006b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc41d3272, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7d594002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x54d00020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8800013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xccc12e23, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd012e24, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcdc12e25, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcfc00013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4193246, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc41d3245, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4313267, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x15540002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x51980020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7d9d801a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc81c001f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1b340057, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1b280213, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1b300199, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x45980198, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7f37000a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7f2b000a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x55e40020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf000024, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd1800025, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcdc00026, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce400026, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400027, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd40000d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd40000a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc40d3249, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x20cc003c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xccc13249, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4113274, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xdd430000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc01e0001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x29dc0002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04280000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8000036, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcc400078, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcc400078, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x2d540002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x95400022, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x078c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x07d40000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8c00120d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8c001239, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8c001232, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04f80000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x057c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcdc00013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc414000d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc41c0019, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7dd5c005, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x25dc0001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd840007c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400074, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400069, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc40c005e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x94c018a6, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd4412e22, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd800007c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc40c005e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x94c018a2, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x95c00007, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc40c0019, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7cd4c005, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x24cc0001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x94c00008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9680fffc, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x800002e3, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc40c0057, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7cd0c002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x94c00003, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9680fffd, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x800002e3, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8000069, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcfc00013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd013273, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd013275, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8000074, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc414005e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9540188f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcfc00013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc40d3249, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc013cfff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7cd0c009, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xccc13249, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9680000b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc40c0077, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x38d00001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x99000006, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04cc0002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xdcc30000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc40c005e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x94c01882, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd4400078, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd800000d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000304, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c41c001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c41c001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd840002f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc41c0015, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x95c0ffff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400030, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc41c0016, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x95c0ffff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8000030, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc41c0016, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x99c0ffff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd800002f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc41c0015, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x99c0ffff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc81c001f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x49980198, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x55e40020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x459801a0, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf000024, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd1800025, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcdc00026, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce400026, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400027, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04302000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcfc00013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf013267, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4313267, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x96800004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x97000001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8000036, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000329, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8800013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcc812e00, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04302000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcfc00013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf013267, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4313267, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x97000001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4193256, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc42d3249, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x16ec001f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8000028, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd800002b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1998003e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcec00031, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8000036, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8000010, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x97800004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400010, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce00000a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1a18003e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd800008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4380004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd88130b8, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04100000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7d43c001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4093249, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1888003e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x94800015, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400074, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8c000671, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9a400006, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc419324c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x259c0001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1598001f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x95c0000d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9580000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x99000003, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400036, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04100001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc40c0021, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x14d80011, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x24dc00ff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x31e00002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x31dc0003, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9580fff0, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9a000003, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x99c00002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd9c00036, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x94800004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8000074, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc418005e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x95801827, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf800008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8800036, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8c00036, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc424000b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x32640002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9a400004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4180014, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9580ffff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd840002f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc40c0021, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x14dc0011, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x95c0fffe, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xccc00037, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8c000190, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd800006d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc41d3246, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4193245, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x51dc0020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7d9d801a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400028, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400029, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc420000b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x32200002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9a0000ad, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04200032, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd9000010, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xde030000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400033, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04080000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc43c0009, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x27fc0002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x97c0fffe, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc42c0015, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x96c0ffff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd800002e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc42d3249, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1af4003e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9740004d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc428000d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4080060, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7ca88005, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x24880001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7f4b4009, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x97400046, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4313274, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4100057, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7d33400c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x97400009, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x28240100, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7e6a4004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce400079, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1eecffdd, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcec13249, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf013273, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf013275, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x800003c3, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc429326f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1aa80030, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x96800006, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x28240001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc428000d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x06a80008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7e6a8004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce800035, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc41d3272, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x25cc0001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x10cc0004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x19e80042, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x25dc0006, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x11dc0001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7e8e800a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7de9c00a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc40d3271, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4293270, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x50cc0020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7ce8c01a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7cd30011, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x11e80007, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x2aa80000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce80001c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd300001e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc428000f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9a80ffff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4300011, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1b30003f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x33300000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4240059, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1660001f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7e320009, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc0328000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7e72400a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0430000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9a000002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04300008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc02ac000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7d310002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x17300002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x2aa87600, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7cd0c011, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcdc00024, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd0c00025, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce800026, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04280222, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce800026, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x96000002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce400026, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400027, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4280058, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x22ec003d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcec13249, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd013273, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce813275, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd800007b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc8380018, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x57b00020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04343108, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc429325d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x040c3000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x13740008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x2374007e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x32a80003, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xccc13267, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc40d3267, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x18ec0057, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x18e40213, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x18cc0199, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7cecc00a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7ce4c00a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x94800003, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd4400078, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x800003e7, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04200022, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xde030000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xccc00024, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd1800025, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf400026, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd4400026, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400027, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04200010, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xde030000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xccc00024, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x45980104, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd1800025, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd4400026, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf800026, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf000026, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400027, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x49980104, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9a80000a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc81c001f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x45980168, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x55e00020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xccc00024, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd1800025, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcdc00026, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce000026, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400027, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x800003f2, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8c000448, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x040c2000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xccc13267, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc40d3267, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x94c00001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc40d3249, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x18cc003e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400030, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc42c0016, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x96c0ffff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8000030, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc42c0016, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9ac0ffff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd800002f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc42c0015, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9ac0ffff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400034, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4300025, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4340024, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4380081, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf813279, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf41326e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf01326d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x94c0000d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x254c0700, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc424001e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x10cc0010, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1a641fe8, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x28cc0726, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x2a640200, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xccc1237b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x2264003f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8813260, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce41325b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4240033, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4280034, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd9000036, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8000010, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8c001427, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x96400006, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xde430000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce40000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc40c005e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x94c01755, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd4400078, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9680000a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce80000a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x06a80002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400010, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xde830000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce80000d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc40c005e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x94c0174c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd4400078, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8000010, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8c00142b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4393265, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x2bb80040, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400032, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf813265, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4200012, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9a00ffff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4100044, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x19180024, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc8100072, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x551c003f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x99c00003, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x95800010, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8000043d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc00c8000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd840006c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x28200000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8000043f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc00c4000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x282000f0, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4113255, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd01324f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd88130b8, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xccc130b5, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce000053, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x195c00e8, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4100004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x2555fff0, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc0360001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x042c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x29540001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04240000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04280004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc420000b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x32200002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9a000009, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcec1c200, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc5e124dc, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0aa80001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7ef6c001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7e624001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x96000001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9a80fff9, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc02ee000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x2555fff0, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcec1c200, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x29540008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc81c001f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x55e00020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc42d3255, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4353259, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8013260, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x45980158, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xccc00024, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd1800025, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcdc00026, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce000026, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400027, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x49980158, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x45980170, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4200012, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x16200010, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9a00fffe, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xccc00024, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd1800025, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc429324f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce400026, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce800026, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcec00026, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf400026, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400027, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd000008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc40d325b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7d43c001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x195400e8, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1154000a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x18dc00e8, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x05e80488, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x18d0006c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x18f807f0, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x18e40077, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x18ec0199, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7e6e400a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x86800000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8000048e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000494, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x800004de, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000685, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000686, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x800006ac, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1ccc001f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xccc1325b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc411325d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x251001ef, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd01325d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4293254, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1264000a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4300004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7d79400a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7e7a400a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x52a8001e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x15180001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7d69401a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x202c007d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcec1325b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x95000008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x95800028, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc42d3267, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4193246, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc41d3245, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1aec0028, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc40d325c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x800004cc, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc42d3256, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc419324e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x26e8003f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1aec003e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x12f4000e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc41d324d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc40d324f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7d75401a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04100002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7d290004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7f8f4001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7f52800f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x51980020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7d9d801a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x50e00002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x51980008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9a800002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x800004d1, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7d0dc002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x6665fc00, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7e5e401a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcec00008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7da1c011, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd140000b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd1c00002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x2a644000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce400002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7f534002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x6665fc00, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7e76401a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd1800002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce400002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x800004d7, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc42d325a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4193258, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1aec003e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc41d3257, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4213259, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x12f4000e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7d75401a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x51980020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x52200002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7d9d801a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcec00008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7da1c011, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd140000b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd1c00002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x2a644000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce400002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x202c003d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf000008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcfc00013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcec1325b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc42d325b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x96c00001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4193260, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x259c0007, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x15980004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x05e804e3, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x86800000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x800004e7, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x800004f0, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000505, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8000016a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4380004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcfc00013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc435325d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd801325b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x277401ef, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf41325d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf800008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4380004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8c000671, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9640fff4, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x17e00008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc418000d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce000009, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd84131db, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf800008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd800009, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc430001e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcfc00013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc42d325b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1b301ff8, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x2b300400, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x2330003f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x26edf000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7ef2c00a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8413260, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcec1325b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x05a80507, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x86800000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8000050c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000528, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8000057d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x800005c2, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x800005f3, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4380004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8c000671, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcfc00013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9a400012, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1bd400e8, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc42c004a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd40005e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc41c004d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcec0005e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x99c0000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4100019, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7d150005, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x25100001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x99000008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8c00063b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcfc00013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4113277, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x2511fffd, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd013277, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd801326f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000624, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04240012, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1be00fe4, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce413260, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce000066, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf800008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400068, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4380004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8c000671, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcfc00013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9a400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1bd400e8, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc42c004a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd40005e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc41c004d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcec0005e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x99c0000d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4100019, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7d150005, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x25100001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x99000009, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400067, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8c00063b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcfc00013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4113277, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x2511fffd, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd013277, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd801326f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000624, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1bd400e8, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc42c0060, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7ed6c005, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x26ec0001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4113271, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4153270, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4193272, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc41d3273, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04280022, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x51100020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7d51401a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4113274, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4213275, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4253276, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4313248, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd1400061, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x2730000f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x13300010, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7db1800a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd800060, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x96c00002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x05dc0008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcdc00062, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x042c3000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd000063, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce000064, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce400065, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcec13267, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc42d3246, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4313245, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4353267, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce813260, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x52ec0020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7ef2c01a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc820001f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1b700057, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1b680213, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1b740199, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x46ec0188, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7f73400a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7f6b400a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x56240020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf400024, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd2c00025, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce000026, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce400026, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x042c2000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400027, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc418000d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x17e00008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce000009, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcec13267, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc42d3267, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x26e01000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9a00fffe, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd9c131fc, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd800009, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf800008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x96c00001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4380004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4113277, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc41c000b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc420000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x11dc0002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7de1c001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x11dc0008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x29dc0001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x25140001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x191807e4, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x192007ec, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x95400004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcdc1334a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcfc00013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9580000e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x09980001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x041c0001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x95800005, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x09980001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x51dc0001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x69dc0001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9980fffd, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7de20014, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x561c0020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce013344, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcdc13345, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcfc00013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x95400022, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x042c3000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcec13267, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc42d3246, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4313245, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4353267, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc425334d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x26640001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9640fffe, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc419334e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc41d334f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4213350, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4253351, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x52ec0020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1b680057, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7ef2c01a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1b700213, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1b740199, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x46ec01b0, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7f6b400a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7f73400a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcfc00013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf400024, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd2c00025, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd800026, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcdc00026, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce000026, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce400026, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x042c2000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400027, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcec13267, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc42d3267, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x96c00001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04280032, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce813260, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8800068, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf800008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4380004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x2010007d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd01325b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc411325b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1910003e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9500fffe, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04100040, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd00001b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc410000f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9900ffff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04100060, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd00001b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc410000f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9900ffff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcfc00013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x2010003d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd01325b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4113277, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x25140001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x191807e4, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9540000b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x2511fffd, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd013277, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc41c000b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc420000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x11dc0002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7de1c001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x11dc0008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcdc1334a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcfc00013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x95800005, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8013344, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8013345, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcfc00013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4180050, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc41c0052, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04280042, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd813273, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcdc13275, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce813260, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd9000068, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400067, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf800008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x07d40000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8c00120d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8c00124f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8c001232, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x057c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x042c3000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4380004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcfc00013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcec13267, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc42d3246, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4313245, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4353267, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x52ec0020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7ef2c01a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1b680057, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1b700213, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1b740199, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc820001f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x46ec0190, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7f6b400a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7f73400a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x56240020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf400024, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd2c00025, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce000026, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce400026, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x042c2000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400027, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcfc00013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcec13267, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4153249, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x2154003d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc41c0019, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1bd800e8, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7dd9c005, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x25dc0001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc42c004a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd80005e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc420004d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcec0005e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x11dc0010, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7e1e000a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd413249, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce01326f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x28340001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x05980008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7f598004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd800035, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1be800e8, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc42c004a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce80005e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd801327a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd800005f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8000075, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd800007f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc424004c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce41326e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcec0005e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x28240100, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7e6a4004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce400079, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc435325d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x277401ef, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04240020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce41325e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd801325b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8013260, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf41325d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xda000068, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf800008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4113277, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc41c000b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc420000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x11dc0002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7de1c001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x11dc0008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x29dc0001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x25140001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9540002d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcdc1334a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcfc00013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x042c3000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcec13267, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc42d3246, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4313245, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4353267, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc425334d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x26640001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9640fffe, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc419334e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc41d334f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4213350, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4253351, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x52ec0020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1b680057, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7ef2c01a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1b700213, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1b740199, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x46ec01b0, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7f6b400a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7f73400a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcfc00013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf400024, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd2c00025, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd800026, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcdc00026, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce000026, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce400026, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x042c2000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400027, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcec13267, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc42d3267, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x96c00001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc41c000b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc420000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x11dc0002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7de1c001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x11dc0008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcdc1334a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcfc00013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc430000b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x33300002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04240000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9b000010, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1be000e8, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x042c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc0360001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04280004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcec1c200, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc63124dc, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0aa80001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7ef6c001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7e724001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x97000001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9a80fff9, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc02ee000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcec1c200, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4253260, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7fc14001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc40d3249, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x18cc003e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x98c00005, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x194c1c03, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xccc0003b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc40c002d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000697, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc420004a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x194c00e8, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xccc0005e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc40c004c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc431326d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x27301fff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce00005e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7cf0c00d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x98c00003, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8c0007e0, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x95c00008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc430001e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1b301ff8, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x2b300400, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x2330003f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf01325b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd801325b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc411325d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x251001ef, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd01325d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x25100007, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x31100005, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9900008e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc40c0007, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd9000010, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8000075e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x202c007d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcec1325b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4293265, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4353254, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x26a9feff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4380004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1374000b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc40c000d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8000009, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1774000d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc41d30b8, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcfc00013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x95c00008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc411325d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd801325b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xccc00009, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf800008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x251001ef, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd01325d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce813265, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf400100, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc00ac006, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc00e0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x28880700, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x28cc0014, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8c0006de, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x14cc0010, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x30d4000f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04cc0001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x10cc0010, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x28cc0014, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x99400009, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc41530b8, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcfc00013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4193265, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x19980028, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x99400003, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x99800002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x800006c8, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcfc00013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc411325d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd801325b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf800008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x251001ef, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd01325d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x15600008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce000009, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc8380023, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4180081, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x11a00002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7fa38011, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4100026, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x05980008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7d1a0002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x282c2002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x3e280008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcec00013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4300027, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x042c0008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd3800025, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf000024, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x202400d0, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7ca48001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcc800026, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xccc00026, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x28240006, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcc000026, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a640001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9a40fffe, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9a800004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x32280000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9a800002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9a000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400027, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x24d8003f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd840003c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcec0003a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8800013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd81a2a4, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc41d325d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x25dc0007, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc40d3249, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x18cc003e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x94c0000a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc420004a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x194c00e8, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xccc0005e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc40c004c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc431326d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x27301fff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce00005e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7cf0c00d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000712, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x194c1c03, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xccc0003b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc40c002d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x05e80714, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x86800000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8000071c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000720, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000747, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8000071d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x800007c4, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000732, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000745, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000744, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x98c00006, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8000072e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x98c00003, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8c0007e0, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x95c0000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4253265, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x2a64008c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce413265, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc430001e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1b301fe8, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x2b300400, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x2330003f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8013260, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf01325b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc40c0007, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd9000010, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04240000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8000075e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x98c0fff1, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8c0007e0, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x95c00002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000723, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc41f02f1, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x95c00004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8013247, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd801325d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000743, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8813247, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd801325d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4100004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd88130b8, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd000008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04100001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x98c0ffde, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8000072e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x98c00003, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8c0007e0, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x95c00012, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4340004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x15600008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc418000d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce000009, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd84131db, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf400008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd800009, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc430001e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1b301ff8, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x2b300400, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x2330003f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8413260, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf01325b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc40c0007, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd9000010, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04240000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x041c3000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcdc13267, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc41d3267, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc41d3265, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x25dc8000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x95c00007, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc41c004a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x195800e8, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd80005e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc418004c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd81326e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcdc0005e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc41d3265, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x25dd7fff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcdc13265, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc41d3246, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4193245, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc42d3267, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x51e00020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7e1a001a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x46200200, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04283247, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04300033, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1af80057, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1af40213, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x042c000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7f7b400a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7f6f400a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf400024, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd2000025, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd800026, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcdc00026, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc6990000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x329c325d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x99c00008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x329c3269, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x99c00006, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x329c3267, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x95c00005, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc01defff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7d9d8009, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8000078a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x25980000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0b300001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x06a80001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd800026, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9b00fff2, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400027, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc43c0012, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9bc0ffff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd801325b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc431325a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc03e7ff0, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7f3f0009, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf01325a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4313249, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1f30001f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf013249, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc03e4000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcfc13254, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8013254, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc431325d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd801324f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8013255, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8013247, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd801325d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1b300028, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8c00120d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8c001219, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8c001232, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4380004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9900000d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd88130b8, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9700000b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc43d30b5, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1bf0003a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9b000b80, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x203c003a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc430000e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x27300700, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x13300014, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x2b300001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf0130b7, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcfc130b5, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x46200008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf400024, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd2000025, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8000026, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400027, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x043c2000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcfc13267, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc43d3267, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9bc00001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xccc00010, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf800008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4080007, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd9000010, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4193260, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x259c0003, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x31dc0003, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x95c00014, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x040c3000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xccc13267, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc40d3267, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x18ec0057, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x18e40213, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x18cc0199, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7cecc00a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7ce4c00a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4193246, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc41d3245, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x51980020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7d9d801a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8c000448, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x040c2000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xccc13267, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc40d3267, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x94c00001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcc800010, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd801325d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc418000b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x31980002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x041c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9980001c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x19580066, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x15600008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x040c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc0120001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x11980003, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04240004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7da18001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4200007, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4340004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd9000010, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xccc1c200, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc41d24db, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7cd0c001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a640001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7dd9c005, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x25dc0001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x99c00002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9a40fff8, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc418005e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9580137b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc00ee000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xccc1c200, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce000010, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf400008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd840004f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4113269, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x19080070, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x190c00e8, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x2510003f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x2518000f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd813268, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x05a80809, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x86800000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8000080e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8000080f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000898, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000946, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x800009e1, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000a5a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04a80811, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x86800000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000815, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000834, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8000085e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8000085e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04341001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4380004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc42d3045, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcec1c091, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x31300021, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9700000b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd84002f1, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc43130b8, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x27300001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4293059, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x56a8001f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7f2b000a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf800008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9b000241, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8000084a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc43130b6, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9b000003, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc02f0001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcec130b6, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4252087, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x5668001a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x26a80005, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9a80fffd, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd80130b6, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8000084a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4380004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04341001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc431ecaa, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x27300080, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9b000010, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc02e0001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcec130b6, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd80130b6, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x31300021, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9700000a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd84002f1, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc43130b8, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x27300001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4293059, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x56a8001f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7f2b000a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf800008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9b00021d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xdd410000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x040c0005, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd84802e9, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8c001a41, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc43b02f1, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9b800006, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4380004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd88130b8, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf800008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcec80278, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x56f00020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf080280, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8c001608, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xdc140000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8813247, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd80802e9, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8000085e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x31100011, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x950001fa, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc02e0001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x2aec0008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc01c0020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc0180001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc00c0007, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x11a40006, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7de6000a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x10e40008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7e26000a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7e2e000a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce000013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4113254, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1d10ffdf, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x2110003e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd013254, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd801324f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8013255, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1d10ff9e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd013254, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8013247, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd801325d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd801325e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc0245301, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce413249, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd801325f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc425326c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc0121fff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x29108eff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7e524009, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce41326c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc425325a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc0127ff0, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7e524009, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce41325a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc425325b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc0131fff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7e524009, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce41325b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd801326d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd801326e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8013279, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x94c00003, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x08cc0001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000866, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc00c0007, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x95800003, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x09980001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000866, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc0100010, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7dd2400c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9a400004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc0180003, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7dd1c002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000866, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000a5a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04a8089a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x86800000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8000089e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x800008fa, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000945, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000945, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x31300022, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x97000007, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4380004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc43130b8, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x27300001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf800008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04183000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd813267, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4113246, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4193245, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x51100020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7d91801a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x459801e0, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4313267, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x2738000f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1b342010, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x172c000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x26ec0800, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1b30c012, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7ef7400a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7f37000a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x2b300000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf00001c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd180001e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc42c000f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9ac0ffff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc8300011, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x97000036, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x45980008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd180001e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc42c000f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9ac0ffff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc8340011, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9740002f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc43c0004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x13b80001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc79d3300, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc7a13301, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x96000001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8393300, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc0260001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce793301, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc424005e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x964012a4, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c028009, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9740001c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x27580001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x99800004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x57740001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x06a80400, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x800008d2, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4180006, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9980ffff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x29640001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce40001a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x242c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x06ec0400, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x57740001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x27580001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9980fffd, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc02620c0, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce41c078, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce81c080, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcc01c081, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf01c082, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x57240020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce41c083, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc0260400, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7e6e400a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce41c084, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7eae8001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7f2f0011, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x800008d2, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4180006, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9980ffff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcdf93300, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce393301, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcfc00008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc43c0004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04182000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd813267, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcfc00008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000903, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x31240022, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x96400008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04100001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4380004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc43130b8, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x27300001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf800008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4af0280, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4b30278, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x52ec0020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7ef2c01a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7ec30011, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x32f80000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9b800011, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x043c0020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04280000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x67180001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0bfc0001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x57300001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x95800006, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8c001628, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9a400003, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd981325d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000915, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd9c1325d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x06a80001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9bc0fff6, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7f818001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8c001606, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7d838001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x94800010, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc41d3259, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc421325a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x16240014, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x12640014, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1a2801f0, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x12a80010, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x2620ffff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7e2a000a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7de1c001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7e5e400a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9b800002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x2264003f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce41325a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8013259, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc40c0007, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd9000010, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8c00075e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4af0228, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x043c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x66d80001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x95800010, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04300002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1330000d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x13f40014, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7f73400a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04380040, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf80001b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc438000f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9b80ffff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04380060, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf80001b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc438000f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9b80ffff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x07fc0001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x56ec0001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x33e80010, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9680ffec, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000a5a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000a5a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04a80948, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x86800000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8000094c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8000099b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x800009e0, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x800009e0, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc43c0004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04183000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd813267, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4113246, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4193245, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x51100020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7d91801a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x459801e0, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4313267, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x2738000f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1b342010, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x172c000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x26ec0800, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1b30c012, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7ef7400a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7f37000a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x2b300000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf00001c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd180001e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc42c000f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9ac0ffff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc8300011, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x97000033, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x45980008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd180001e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc42c000f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9ac0ffff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc8340011, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9740002c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x13b80001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc79d3300, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc7a13301, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x96000001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8393300, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc0260001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce793301, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc424005e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x964011fe, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c028009, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9740001c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x27580001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x99800004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x57740001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x06a80400, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000978, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4180006, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9980ffff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x29640001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce40001a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x242c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x06ec0400, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x57740001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x27580001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9980fffd, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc0260010, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce41c078, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf01c080, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x57240020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce41c081, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce81c082, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcc01c083, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc0260800, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7e6e400a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce41c084, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7eae8001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7f2f0011, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000978, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4180006, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9980ffff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcdf93300, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce393301, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04182000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd813267, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcfc00008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4193246, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc41d3245, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x51980020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7dda801a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7d41c001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7e838011, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd84802e9, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8c001802, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x469c0390, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4313267, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04183000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd813267, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1b342010, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x172c000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x26ec0800, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1b30c012, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7ef7400a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7f37000a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x2b300000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf00001c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x45dc0004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd1c0001e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc418000f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9980ffff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4200011, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x45dc0004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd1c0001e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc418000f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9980ffff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4240011, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x45dc0004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd1c0001e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc418000f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9980ffff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4280011, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x45dc0004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd1c0001e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc418000f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9980ffff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc42c0011, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x45dc0004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd1c0001e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc418000f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9980ffff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4300011, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x45dc0004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd1c0001e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc418000f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9980ffff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4340011, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x45dc0004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd1c0001e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc418000f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9980ffff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4380011, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04182000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd813267, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x043c0001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8c0014df, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000a5a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000a5a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x31280014, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce8802ef, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9a800062, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x31280034, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9a800060, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04a809e8, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x86800000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x800009ec, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000a45, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000a59, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000a59, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4113246, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4193245, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x51100020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7d91801a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x45980400, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4b30258, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4a70250, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x53300020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7e72401a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4313267, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1b342010, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x172c000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x26ec0800, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1b30c012, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7ef7400a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7f37000a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x2b300000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf00001c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x042c0020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x66740001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x97400041, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04383000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf813267, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4393267, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9b800001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd180001e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc438000f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9b80ffff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4300011, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1b38007e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x33b40003, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9b400003, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x4598001c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9740002f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x45980004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd180001e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc438000f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9b80ffff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc40c0011, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x45980004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd180001e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc438000f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9b80ffff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4100011, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x45980004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd180001e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc438000f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9b80ffff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4340011, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf4002eb, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x45980004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd180001e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc438000f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9b80ffff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4340011, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf4002ec, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x45980004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd180001e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc438000f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9b80ffff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4340011, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf4002ed, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x45980004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd180001e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc438000f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9b80ffff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4340011, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf4002ee, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x45980004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04382000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf813267, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd84802e9, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8c001715, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04382000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf813267, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x56640001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0aec0001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9ac0ffbc, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4380004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04341001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x94800005, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc431ecaa, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x27300080, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x97000002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000a55, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc43130b6, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x233c0032, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcfc130b6, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf0130b6, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc49302ef, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x99000003, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8413247, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf800008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000a5a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000a5a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04180001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x5198001f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd813268, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4193269, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x2598000f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9980fffe, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd80002f1, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8013268, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd800004f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04380001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x53b8001f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7db9801a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd813268, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000a5e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400029, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc40c005e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x94c01106, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8800013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcc412e01, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcc412e02, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcc412e03, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcc412e00, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000aa7, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400029, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc40c005e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x94c010fd, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c40c001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x50640020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7ce4c01a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd0c00072, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc80c0072, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x58e801fc, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x12a80009, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x2aa80000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd0c0001e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce80001c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc424000f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9a40ffff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04240010, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x18dc01e2, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7e5e4002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x3e5c0003, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x3e540002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x95c00006, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc8180011, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc8100011, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc8100011, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x55140020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000aa2, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9540000a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc8180011, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x44cc0008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x55900020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd0c0001e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc424000f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9a40ffff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4140011, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000aa2, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x44cc0004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4180011, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd0c0001e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc424000f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9a40ffff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc8100011, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x55140020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8800013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd812e01, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd012e02, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd412e03, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcc412e00, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc428000e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x2aa80008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce800013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4253249, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x2264003f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce413249, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce800013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4253249, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x96400001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd800002a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc410001a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc40c0021, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4140028, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x95000005, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1e64001f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce800013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce413249, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80001b70, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x14d00010, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4180030, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc41c0007, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x99000004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x99400009, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9980000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000ab1, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xccc00037, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8c000190, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc420001c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8000032, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9a0010ac, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000aa7, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd880003f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x95c00002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8c0003f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80001082, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8800040, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x95c00002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8c00040, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x800010de, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc010ffff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x18d403f7, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7d0cc009, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc41b0367, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7d958004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7d85800a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xdc1e0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc424000b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x32640002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c40c001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x18d001fc, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x05280adc, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x86800000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000af1, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000adf, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000ae7, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8c000ace, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8c00013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x96400002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd8d2000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x99c00010, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c408001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x88000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x18d803f7, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc010ffff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7d0cc009, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04140000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x11940014, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x29544001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9a400002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x29544003, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000af4, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8c00013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x96400002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd44d2000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c408001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x88000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc424000b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x32640002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c40c001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8c00013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x96400002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd44dc000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c408001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x88000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c40c001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x18d0003c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x95000006, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8c000ace, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8800013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd8d2c00, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x99c00003, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000b0a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8800013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd44d2c00, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c408001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x88000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c40c001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x28148004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x24d800ff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xccc00019, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd4593240, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c408001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x88000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400029, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc40c005e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x94c0105e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c410001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x50540020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c418001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x2198003f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x199c0034, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc40c0007, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x95c00028, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc428000e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x2aa80008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce800013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc42d324f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4313255, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7ef3400c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9b400021, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd800002a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80001b70, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc40c0007, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x14e80001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9a8000af, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd9000010, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x041c0002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x042c01c8, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8c000d61, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xccc00010, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400029, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc40c005e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x94c01043, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c410001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x50540020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c418001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x18a01fe8, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x3620005c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9a00000e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x2464003f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc6290ce7, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x16ac001f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x96c00004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x26ac003f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7ee6c00d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x96c00005, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x06200001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x2620000f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9a00fff8, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8000016a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce000367, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc424005e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9640102e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc428000e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x199c0037, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x19a00035, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x2aa80008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce800013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x95c0005d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd800002a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc42d3256, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc431325a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x2330003f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x16f8001f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9780000d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4253248, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc035f0ff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7e764009, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x19b401f8, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x13740008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7e76400a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce800013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce413248, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf01325a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce800013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc431325a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x97000001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7d15001a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd1000072, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc8100072, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x55140020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x199c0034, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400010, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400029, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9b800004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1ae4003e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce400008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000b7c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4353254, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x16a80008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1aec003c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x19a4003f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x12a80015, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x12ec001f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1374000b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7eae800a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc02e4000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1774000d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7eae800a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce400008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7f6b400a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x95c00005, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc43d3248, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1bfc01e8, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x13fc0018, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7dbd800a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1d98ff15, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x592c00fc, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd80000a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x12e00016, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7da1800a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x592c007e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x12e00015, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7da1800a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd1000001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd800001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x11a0000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1264001e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1620000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7e26000a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7e32000a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x12e4001b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7e26000a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x5924007e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x12640017, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7e26000a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x19a4003c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x12640018, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7e26000a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd800002a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce01325a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd013257, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd413258, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc429325a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc40c005e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x94c00fdb, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x96800001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x95c00003, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c40c001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c410001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9780f5ca, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf400100, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc40c0007, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd9000010, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8c00120d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8c001219, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8c001232, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xccc00010, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8c001b6d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c408001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x88000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc42d324e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc431324d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x52ec0020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7ef2c01a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc435324f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4293256, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x52ec0008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x07740003, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04240002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x269c003f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7e5e4004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7f67000f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x97000003, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7f674002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0b740001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x53740002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7ef6c011, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1ab42010, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1ab8c006, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x16a8000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x26a80800, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x2b740000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7f7b400a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7f6b400a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf40001c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd2c0001e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc438000f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9b80ffff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4180011, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9a000003, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8c000bec, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000b47, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc42c001d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4313256, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1b34060b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1b300077, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7f37000a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x13300017, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04340100, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x26ec00ff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc03a8004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7ef6c00a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7f3b000a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7ef2c00a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcec1325b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000c16, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc40c0032, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc410001d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x28cc0008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xccc00013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc415325b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c418001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c418001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x18580037, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x251000ff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc421325d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x262001ef, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce01325d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x99800004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7d15400a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd41325b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000168, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1d54001f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd41325b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c408001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x88000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc428000b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc42c000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x12a80001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x26a80004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7eae800a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc40c0021, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4340028, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x14f00010, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4380030, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc43c0007, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd280200, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd680208, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcda80210, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9b00000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9b400014, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9b800017, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc428000b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc42c000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x12a80001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x26a80004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7eae800a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc6930200, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc6970208, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc69b0210, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x17300001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9b000005, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xccc00037, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8c000190, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8000032, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8000028, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd800002b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000168, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd900003f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x97c00002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd940003f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80001082, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd9000040, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x97c00002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd9400040, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x800010de, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc40c0021, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x14fc0011, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x24f800ff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x33b80001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x97c0fffc, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9b800007, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xccc00037, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8c000190, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8000032, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8000028, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd800002b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80001b70, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4380004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd88130b8, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04100000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04140000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc418000e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x29980008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7d83c001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd800013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4093249, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1888003e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x94800020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400074, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8c000671, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9a400009, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc418000e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x29980008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd800013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc419324c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x259c0001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1598001f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x95c00016, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x95800015, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x99000003, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400036, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04100001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc40c0021, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x14d80011, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x24e000ff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x321c0002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x32200001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9580ffee, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x99c00014, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x96000004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xccc00037, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04140001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000c30, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9480000a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8000074, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc418005e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x95800f29, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf800008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000c16, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x94800004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8000074, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc418005e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x95800f23, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd9c00036, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x99400002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xccc00037, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf800008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000c16, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x94800004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8000074, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc418005e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x95800f1a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xccc00037, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8800036, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80001b70, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x041c0003, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x042c01c8, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8c000d61, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4200007, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc40c0077, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x94c00001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c418001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc428000e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9600f502, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a200001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x98c0f500, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x2aa80008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce000010, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9a000f05, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce800013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc431325a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc42d3256, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1f30001f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x16e4001f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf01325a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc431325a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x97000001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9640f4f4, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc434000b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x33740002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9b40f4f1, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4353254, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x16a80008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1aec003c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x12a80015, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x12ec001f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1374000b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7eae800a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc02e4000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1774000d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7eae800a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7f6b400a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf400100, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x12780001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x2bb80001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc00ac005, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc00e0002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x28cc8000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x28884900, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x28cc0014, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000ff3, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc43c0007, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c40c001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x17fc0001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9bc00004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400029, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc424005e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x96400ee1, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcc41c40a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcc41c40c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcc41c40d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c414001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x24d0007f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x15580010, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x255400ff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd01c411, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd81c40f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd41c40e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcc41c410, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c414001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c418001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04200000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x18e80033, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x18ec0034, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcc41c414, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcc41c415, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd81c413, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd41c412, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x18dc0032, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c030011, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c038011, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x95c00027, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x96c00002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc431c417, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc435c416, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x96800004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x96c00002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc439c419, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc43dc418, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc41c000e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x29dc0008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcdc00013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf413261, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x96c00002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf013262, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x96800004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcfc13263, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x96c00002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf813264, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x18dc0030, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc43c0007, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x95c00017, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x17fc0001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9ac00005, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7d77000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9bc00015, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9700000a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000cd6, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x51b80020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x53300020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7f97801a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7f37001a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7f3b000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9bc0000d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x97800002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000cd6, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9a000018, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x28200001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000ca7, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x18dc0031, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x95c00003, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc435c40b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9740fffd, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd800002a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80001b70, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4280032, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x2aa80008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce800013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc40d325b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x97000002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x800012c2, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc438001d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1bb81ff0, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7f8cc00a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xccc1325b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc411325d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x251001ef, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd01325d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80001b70, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc428000e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc43c0007, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x2aa80008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc438001d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce800013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x13f4000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9bc00006, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc43d3256, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1bf0060b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1bfc0077, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7ff3c00a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000cf4, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc43d325a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1bfc0677, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x13fc0017, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04300100, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1bb81fe8, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7f73400a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc032800b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7fb7800a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7ff3c00a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7ffbc00a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcfc1325b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000c16, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc43c0007, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c40c001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x18d42011, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x17fc0001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x18d001e8, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x24cc007f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7cd4c00a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9bc00004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400029, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc428005e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x96800e6c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c414001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x50580020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7d59401a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd1400072, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc8140072, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x596001fc, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x12200009, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7ce0c00a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c418001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x505c0020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7d9d801a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c41c001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x50600020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7de1c01a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c420001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xccc0001b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd140001d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd180001f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd1c00020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x95000010, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04300000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc428000f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9a80ffff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc8240010, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7e5e800c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9bc00015, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9a80000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9b000024, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x28300001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x122c0004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x06ec0001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0aec0001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9ac0ffff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000d1f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc428000f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9a80ffff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc8240010, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x566c0020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc428000e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x2aa80008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce800013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce413261, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcec13262, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd800002a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80001b70, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4340032, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x2b740008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc40d325b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x96800005, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x566c0020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce413261, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcec13262, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x800012c2, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc438001d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1bb81fe8, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7f8cc00a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xccc1325b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc411325d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x251001ef, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd01325d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80001b70, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc43c0007, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc438001d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc428000e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x2aa80008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce800013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x13f4000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9bc00006, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc43d3256, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1bf0060b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1bfc0077, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7ff3c00a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000d57, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc43d325a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1bfc0677, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x13fc0017, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04300100, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1bb81fe8, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7f73400a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc0328009, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7fb7800a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7ff3c00a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7ffbc00a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcfc1325b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000c16, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc43c000e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x2bfc0008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcfc00013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4253246, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4113245, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04143000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd413267, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x52640020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7e51001a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4153267, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7d2d0011, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x19640057, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x19580213, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x19600199, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7da6400a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7e26400a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd1000025, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce400024, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcdc00026, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400027, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04142000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcfc00013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd413267, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4153267, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x99400001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c40c001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x18d001e8, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x18d40030, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x18d80034, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x05280d83, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c420001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c424001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x86800000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000d8a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8000016a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000d95, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000db1, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8000016a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000d95, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000dbc, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x11540010, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7e010001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8c00187c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7d75400a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd4610000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9580f3d8, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc439c040, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x97800001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c408001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x88000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8000016, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x526c0020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x18e80058, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7e2ec01a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd2c00072, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc82c0072, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x5ae0073a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7ea2800a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9940000a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce800024, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd2c00025, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd4400026, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400027, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9580f3c6, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4380012, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9b80ffff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c408001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x88000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xdc3a0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0bb80001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce800024, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd2c00025, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcc400026, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400027, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9b80fffb, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9980fff5, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c408001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x88000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc02a0001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x2aa80001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x16200002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce800013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce01c405, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd441c406, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9580f3b1, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc439c409, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x97800001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c408001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x88000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc424000b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x32640002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9a40000b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x11540010, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x29540002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd4610000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9580f3a5, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc439c040, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x97800001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c408001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x88000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd4400078, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000168, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400029, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc40c005e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x94c00da7, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c40c001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x50500020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7cd0c01a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd0c00072, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc8280072, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x5aac007e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x12d80017, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c41c001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7d9d800a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x56a00020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x2620ffff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7da1800a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x51980020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7e82400a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7e58c01a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x19d4003d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x28182002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x99400030, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8c00104f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc430000d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4340035, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd800002a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd800013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc8140023, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4180081, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x13300005, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc011000f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4240004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x11a00002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c908009, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x12640004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7d614011, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4100026, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x05980008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7ca4800a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7d1a0002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7cb0800a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x3e280008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x20880188, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x54ec0020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7cb4800a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4300027, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04380008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd1400025, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf000024, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x20240090, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7ca48001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcc800026, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xccc00026, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcec00026, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcec00026, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x28240004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcc000026, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a640001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9a40fffe, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9a800005, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x32280000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9a800002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9a000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c018001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400027, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8000016, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf80003a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd901a2a4, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80001037, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc418000e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x29980008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd800013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc421326c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1624001f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9a40fffe, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd841325f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8800033, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc43c0009, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x27fc0004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x97c0fffe, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8000039, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd0c00038, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc43c0022, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9bc0ffff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8800034, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc429325f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x26ac0001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9ac0fffe, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x26ac0002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x96c00003, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd800002a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80001b70, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc43c0007, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc430001e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8800033, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x13f4000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1b301ff0, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x2b300300, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x2330003f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7f37000a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9680000b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc43c0009, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x27fc0004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x97c0fffe, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400039, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd0c00038, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc43c0022, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9bc0ffff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf01325b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8800034, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000c16, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8800034, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8c0001a2, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80001b70, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcc80003b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x24b00008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc418000e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1330000a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x18ac0024, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x2b304000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c40c001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcec00008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x18a800e5, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1d980008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x12a80008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7da9800a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x29980008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd800013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4113249, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1910003e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x99000002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd840003d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c410001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd4400078, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x51100020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf01326c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7cd0c01a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc421326c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x12a80014, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x2220003f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7e2a000a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd800013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce01326c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8800033, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc43c0009, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x27fc0004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x97c0fffe, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8000039, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd0c00038, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc43c0022, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9bc0ffff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8800034, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80001190, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c40c001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x18dc003d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x95c00004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x041c0001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x042c01c8, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8c000d61, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x18d40030, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x18d001e8, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x18fc0034, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x24e8000f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x06a80e71, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c418001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c41c001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x86800000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000edd, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000e91, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000e91, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000ea1, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000eaa, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000e7c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000e7f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000e7f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000e87, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000e8f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8000016a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x51dc0020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7d9e001a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000ee6, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc420000e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x2a200008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce000013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4213262, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4253261, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x52200020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7e26001a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000ee6, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc420000e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x2a200008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce000013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4213264, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4253263, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x52200020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7e26001a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000ee6, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc820001f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000ee6, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x18e82005, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x51e00020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x2aa80000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7da1801a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd1800072, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc8180072, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x59a001fc, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x12200009, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7ea2800a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce80001c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd180001e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc428000f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9a80ffff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc8200011, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000ee6, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x15980002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd81c400, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc421c401, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x95400041, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc425c401, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x52640020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7e26001a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000ee6, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x31ac2580, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9ac00011, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x31ac260c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9ac0000f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x31ac0800, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9ac0000d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x31ac0828, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9ac0000b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x31ac2440, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9ac00009, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x31ac2390, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9ac00007, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x31ac0093, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9ac00005, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x31ac31dc, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9ac00003, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x31ac31e6, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x96c00004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4340004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000ede, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x39ac7c06, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x3db07c00, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9ac00003, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x97000002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000ebc, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x39acc337, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x3db0c330, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9ac00003, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x97000002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000ebc, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x39acc335, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x3db0c336, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9ac00003, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x97000002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000ebc, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x39ac9002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x3db09001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9ac00003, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x97000002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000ebc, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x39ac9012, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x3db09011, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9ac00003, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x97000002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000ebc, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x39acec70, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x3db0ec6f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9ac00003, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x97000002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000ebc, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4340004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc5a10000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x95400005, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x05980001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc5a50000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x52640020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7e26001a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf400008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x05280eea, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c418001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c41c001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x86800000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000ef1, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8000016a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000efe, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000f11, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000f2e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000efe, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000f1f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4340004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce190000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x95400005, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x05980001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x56200020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce190000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf400008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x97c0f26f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc439c040, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x97800001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c408001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x88000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x51ec0020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x18e80058, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7daec01a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd2c00072, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc82c0072, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x5af8073a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7eba800a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd2c00025, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce800024, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce000026, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x95400003, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x56240020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce400026, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400027, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x97c0f25c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4380012, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9b80ffff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c408001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x88000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc02a0001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x2aa80001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x15980002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce800013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd81c405, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce01c406, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x95400003, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x56240020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce41c406, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x97c0f24e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc439c409, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x97800001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c408001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x88000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc424000b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x32640002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9a40f247, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8800013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce190000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x95400004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x05980001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x56200020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce190000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x97c0f240, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc439c040, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x97800001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c408001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x88000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x31ac2580, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9ac00011, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x31ac260c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9ac0000f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x31ac0800, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9ac0000d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x31ac0828, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9ac0000b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x31ac2440, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9ac00009, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x31ac2390, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9ac00007, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x31ac0093, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9ac00005, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x31ac31dc, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9ac00003, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x31ac31e6, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x96c00004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4340004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000ef2, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x39ac7c06, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x3db07c00, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9ac00003, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x97000002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000f40, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x39acc337, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x3db0c330, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9ac00003, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x97000002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000f40, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x39acc335, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x3db0c336, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9ac00003, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x97000002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000f40, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x39acec70, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x3db0ec6f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9ac00003, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x97000002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000f40, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x39ac9002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x3db09002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9ac00003, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x97000002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000f40, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x39ac9012, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x3db09012, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9ac00003, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x97000002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000f40, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000ef1, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc40c0006, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x98c0ffff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c40c001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c410001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c414001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c418001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c41c001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c43c001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x95c00001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc434000e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x2b740008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x2b780001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8c1325e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf80001a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c034001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c038001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x18e0007d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x32240003, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9a400006, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x32240000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9a400004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd01c080, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd41c081, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000f88, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x51640020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7e52401a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd2400072, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc8280072, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce81c080, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x56ac0020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x26f0ffff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf01c081, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1af000fc, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1334000a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x24e02000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7f63400a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x18e00074, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x32240003, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9a400006, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x32240000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9a400004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd81c082, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcdc1c083, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000f9d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x51e40020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7e5a401a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd2400072, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc8280072, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce81c082, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x56ac0020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x26f0ffff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf01c083, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1af000fc, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x13380016, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x18e00039, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x12200019, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7fa3800a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7fb7800a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x18e0007d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1220001d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7fa3800a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x18e00074, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x12200014, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7fa3800a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf81c078, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcfc1c084, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000c16, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c40c001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x18dc003d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x95c00004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x041c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x042c01c8, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8c000d61, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x18d001e8, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x31140005, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x99400003, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x31140006, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x95400002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8c00104f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x05280fb7, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x28140002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x86800000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000fbe, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000fbe, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000fc2, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000fbe, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000fd1, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000ff2, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000ff2, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x24cc003f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xccc1a2a4, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c408001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x88000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c414001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x18e80039, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x52a8003b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x50580020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x24cc003f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7d59401a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd1400072, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc8140072, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7d69401a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc41c0017, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x99c0ffff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd140004b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xccc1a2a4, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c408001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x88000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc414000d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04180001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x24cc003f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7d958004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd800035, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xccc1a2a4, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc43c000e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x2bfc0008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcfc00013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc43d3249, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1bfc003e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x97c00002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400074, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4100019, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7d150005, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x25100001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9500000b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x97c0fffc, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4180021, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x159c0011, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x259800ff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x31a00003, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x31a40001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7e25800a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x95c0fff5, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9580fff4, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000fef, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc411326f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1d100010, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd01326f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x97c00002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8000074, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80001b70, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04380000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc430000d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc8140023, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4180081, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x13300005, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc011000f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4240004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x33b40003, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x97400003, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc0340008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000ffe, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4340035, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x11a00002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c908009, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x12640004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7d614011, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4100026, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x05980008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7ca4800a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7d1a0002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7cb0800a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x282c2002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x208801a8, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x3e280008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7cb4800a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcec00013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4300027, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x042c0008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd1400025, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf000024, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x20240030, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7ca48001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcc800026, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xccc00026, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9b800013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcc400026, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c414001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x28340000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x507c0020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7d7d401a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd1400072, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc8140072, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x557c0020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x28342002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd400026, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcfc00026, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd4400026, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9a80000e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x32280000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9a80000b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8000102f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcc000026, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcc000026, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcc000026, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcc000026, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcc000026, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9a800005, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x32280000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9a800002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9a000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c018001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcc000026, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400027, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1cccfe08, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8800013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcec0003a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xccc1a2a4, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc43c000e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x2bfc0008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcfc00013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc43d3249, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1bfc003e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9bc00007, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc428000e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x16a80008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce800009, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc42c005e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x96c00b33, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd840003c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4200025, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7da2400f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7da28002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7e1ac002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0aec0001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x96400002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7d2ac002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x3ef40010, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9b40f11d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04380030, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf81325e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000c16, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xde410000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xdcc10000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xdd010000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xdd410000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xdd810000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xddc10000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xde010000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc40c000e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c024001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x28cc0008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xccc00013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc8100086, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x5510003f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc40d3249, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x18cc003e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x98c00003, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x99000011, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80001075, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9900000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc40c0026, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4100081, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4140025, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7d15800f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7d15c002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7d520002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a200001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x95800002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7cde0002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x3e20001a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9a000009, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x040c0030, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xccc1325e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80001071, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd9c00036, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400029, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc40c005e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x94c00b01, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04240001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xdc200000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xdc1c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xdc180000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xdc140000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xdc100000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xdc0c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x96400004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xdc240000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xdc0c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000c16, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xdc240000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcc40003f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8c00010, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4080029, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcc80003b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc418000e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x18a800e5, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1d980008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x12a80008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7da9800a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x29980008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd800013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x18a400e5, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x12500009, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x248c0008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x94c00006, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x200c006d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7cd0c00a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xccc1326c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc421326c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x96000001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd800013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x200c0228, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7cd0c00a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xccc1326c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc421326c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x96000001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc40c002a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc410002b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x18881fe8, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x18d4072c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x18cc00d1, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7cd4c00a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x3094000d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x38d80000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x311c0003, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x99400006, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x30940007, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1620001f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9940001d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9a000023, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x800010c4, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9580001a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x99c00019, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xccc00041, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x25140001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc418002c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9940000d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x259c007f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x95c00013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x19a00030, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcdc0001b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400022, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc430000f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x17300001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9b00fffe, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9a000012, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400023, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x800010cb, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x199c0fe8, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcdc0001b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400023, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc430000f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x17300001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9b00fffe, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x800010cb, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8c00010, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8000022, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8000023, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc430005e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x97000aac, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c408001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x88000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc43c000e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc434002e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x2bfc0008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x2020002c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcfc00013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce01326c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x17780001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x27740001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x07a810d8, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf400010, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc421326c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x96000001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x86800000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000168, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000aa7, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000bfc, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x800012e9, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8000104c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcc400040, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8800010, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4180032, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x29980008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd800013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x200c007d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xccc1325b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc411325b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x95000001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c408001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x88000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x28240007, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xde430000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd4400078, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80001190, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcc80003b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x24b00008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc418000e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1330000a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x18a800e5, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1d980008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x12a80008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7da9800a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x29980008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd800013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc40d3249, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x18cc003e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x98c00002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd840003d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x2b304000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf01326c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc431326c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c40c001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c410001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c414001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x192400fd, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x50580020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7d59401a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c41c001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x06681110, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c420001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcc400078, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x18ac0024, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x19180070, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x19100078, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcec00008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x18f40058, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x5978073a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7f7b400a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x97000001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x86800000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80001117, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80001118, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80001122, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8000112d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80001130, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80001133, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8000016a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8000117b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x24ec0f00, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x32ec0600, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x96c00003, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4300006, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9b00ffff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd1400025, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf400024, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcdc00026, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400027, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8000117b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x24ec0f00, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x32ec0600, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x96c00003, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4300006, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9b00ffff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd1400025, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf400024, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcdc00026, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce000026, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400027, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8000117b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc81c001f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x55e00020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80001122, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc81c0020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x55e00020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80001122, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8c00116b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc02a0200, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7e8e8009, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x22a8003d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x22a80074, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x2774001c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x13740014, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7eb6800a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x25ecffff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x55700020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x15f40010, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x13740002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x275c001f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x95c00027, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c018001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7f41c001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x15dc0002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x39e00008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x25dc0007, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7dc1c01e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x05dc0001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x96000004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x05e40008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8c00116e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80001168, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7dc2001e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x06200001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x05e40008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7e62000e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9a000004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7da58001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8c00116e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80001165, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7dc2001e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x06200001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7e1a0001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x05cc0008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7e0d000e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x95000007, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7e02401e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x06640001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x06640008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x05d80008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8c00116e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80001168, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7dc2401e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x06640001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7da58001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8c00116e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x05e00008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7da2000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9600ffe6, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x17640002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8c00116e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80001190, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4200006, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9a00ffff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8c00116b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc420000e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x2a200001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce00001a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce81c078, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcec1c080, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcc01c081, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd41c082, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf01c083, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x12640002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x22640435, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce41c084, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0528117e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x312c0003, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x86800000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80001190, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80001185, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80001182, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80001182, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4300012, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9b00ffff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9ac0000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc03a0400, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4340004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc418000e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x15980008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1198001c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7d81c00a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcdc130b7, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf8130b5, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf400008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04240008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc418000e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc41c0049, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x19a000e8, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x29a80008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7de2c00c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce800013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc421325e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x26200010, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc415326d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9a000006, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc420007d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x96000004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x96c00003, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce40003e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x800011a3, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7d654001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd41326d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c020001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x96000005, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4100026, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4240081, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4140025, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x800011b6, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4253279, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc415326d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc431326c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x2730003f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x3b380006, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x97800004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x3f38000b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9b800004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x800011b4, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04300006, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x800011b4, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0430000b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04380002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7fb10004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7e57000f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7e578002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7d67c002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0be40001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x97000002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7d3a4002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x202c002c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc421325e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04280020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcec1326c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x26200010, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x3e640010, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x96000003, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x96400002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce81325e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4300028, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc434002e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x17780001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x27740001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x07a811cf, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9b00feb8, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf400010, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc414005e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x954009a7, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x86800000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000168, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000aa7, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000bfc, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x800012e9, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000168, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8c00120d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c40c001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xccc1c07c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcc41c07d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcc41c08c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c410001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcc41c079, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd01c07e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c414001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x18f0012f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x18f40612, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x18cc00c1, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7f73400a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7cf7400a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x39600004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9a000002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc0140004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x11600001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x18fc003e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9740001c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf400041, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc425c07f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x97c00003, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x166c001f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x800011ee, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1a6c003e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x96c00006, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04200002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a200001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9a00ffff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x800011e8, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc428002c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x96800010, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x26ac007f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcec0001b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1ab00030, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1aac0fe8, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc434000f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9b40ffff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x97000008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcec0001b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc434000f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9b40ffff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80001205, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a200001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9a00ffff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc425c07f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x166c001f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x11600001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9ac0fffa, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8c001232, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c408001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x88000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8000033, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc438000b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc43c0009, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x27fc0001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x97c0fffe, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd841c07f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc43dc07f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1bfc0078, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7ffbc00c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x97c0fffd, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc03a2800, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf81c07c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcc01c07d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcc01c08c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcc01c079, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcc01c07e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04380040, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf80001b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc438000f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9b80ffff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04380060, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf80001b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc438000f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9b80ffff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04380002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0bb80001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9b80ffff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc43dc07f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x17fc001f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04380010, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9bc0fffa, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd801c07f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc43dc07f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcfc00078, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8000034, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc03ae000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf81c200, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc03a0800, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf81c07c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcc01c07d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcc01c08c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcc01c079, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcc01c07e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04380040, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf80001b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc438000f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9b80ffff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04380002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0bb80001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9b80ffff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc43dc07f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x17fc001f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04380010, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9bc0fffa, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc03ae000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf81c200, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc03a4000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf81c07c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcc01c07d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcc01c08c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcc01c079, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcc01c07e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04380002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0bb80001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9b80ffff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc43dc07f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x17fc001f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04380010, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9bc0fffa, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc40c0007, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x30d00002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x99000052, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400029, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc424005e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9640090f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c410001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc428000e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1514001f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x19180038, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x2aa80008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x99400030, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x30dc0001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce800013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x99c0000a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc42d324e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc431324d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x52ec0020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7ef2c01a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc435324f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4293256, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1ab0c006, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x52ec0008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8000127f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc42d3258, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4313257, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x52ec0020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7ef2c01a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4353259, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc429325a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1ab0c012, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x07740001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04240002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x26a0003f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7e624004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7f67800f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x97800002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04340000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x53740002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7ef6c011, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1ab42010, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x16a8000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x26a80800, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x2b740000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7f73400a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7f6b400a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf40001c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd2c0001e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc438000f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9b80ffff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4100011, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1514001f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x99400006, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9980000a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8c0012e1, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc40c0007, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04100000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80001267, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd800002a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc424005e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x964008d7, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd9800036, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000c16, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc42c001d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x95c00005, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc431325a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1b300677, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x11dc000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x800012aa, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4313256, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1b34060b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1b300077, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7f37000a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x13300017, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04340100, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x26ec00ff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc03a8002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7ef6c00a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7edec00a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7f3b000a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7ef2c00a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcec1325b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000c16, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4140032, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc410001d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x29540008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc40d325b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1858003f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x251000ff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x99800007, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7d0cc00a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xccc1325b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc411325d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x251001ef, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd01325d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000168, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x18d0006c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x18d407f0, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9900000e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04100002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4193256, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc41d324f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x2598003f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7d190004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7d5d4001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7d52000f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9a000003, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd41324f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x800012d8, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7d514002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd41324f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x800012d8, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4193259, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc41d325a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7d958001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7dd5c002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd813259, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcdc1325a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc411325d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x251001ef, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd01325d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1ccc001e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xccc1325b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc40d325b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x94c00001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c408001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x88000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc40c0021, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4340028, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x14f00010, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4380030, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc43c0007, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9b000004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9b40000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9b80000f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x17300001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9b000005, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xccc00037, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8c000190, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8000032, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8000028, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd800002b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000168, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd980003f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x97c00002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd9c0003f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80001082, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd9800040, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x97c00002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd9c00040, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x800010de, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc43c0007, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x33f80003, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x97800051, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcc80003b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x24b00008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc418000e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1330000a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x18a800e5, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1d980008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x12a80008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7da9800a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x29980008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd800013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4353249, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1b74003e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9b400002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd840003d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x2b304000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf01326c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc431326c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x97000001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c434001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1b4c00f8, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c410001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c414001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x50700020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04e81324, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x18ac0024, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c41c001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x50600020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcc400078, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x30e40004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9a400007, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7d71401a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x596401fc, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x12640009, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1b74008d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7e76400a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x2a640000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcec00008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x86800000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8000016a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8000016a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8000016a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8000016a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8000132c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8000133b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80001344, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8000016a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4340004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc42530b5, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1a68003a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9a80fffe, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x2024003a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc418000e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x25980700, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x11980014, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7d19000a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd0130b7, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce4130b5, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf400008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80001190, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce40001c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd140001e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc428000f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9a80ffff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4240011, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7de6800f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9a80ffea, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80001190, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce40001c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd140001e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc428000f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9a80ffff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc8240011, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7de1c01a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7de6800f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9a80ffe0, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80001190, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8c00104f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x28182002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc430000d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4340035, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd800013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc8140023, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4180081, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x13300005, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4240004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x11a00002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x12640004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7d614011, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4100026, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x05980008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7ca4800a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7d1a0002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7cb0800a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x3e280008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7cb4800a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4300027, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x042c0008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd1400025, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf000024, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x20240030, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7ca48001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcc800026, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c434001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1b4c00f8, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf400026, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcc400026, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x28340000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c414001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x507c0020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x30e40004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9a400005, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7d7d401a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd1400072, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc8140072, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x557c0020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x28342002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd400026, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcfc00026, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd4400026, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcc000026, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9a800005, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x32280000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9a800002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9a000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c018001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400027, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8800013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04380028, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcec0003a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf81a2a4, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80001037, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400029, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc40c005e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x94c007eb, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c40c001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x50500020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7d0d001a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd1000072, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc8100072, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x591c01fc, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x11dc0009, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x45140210, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x595801fc, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x11980009, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x29dc0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcdc0001c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd140001e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc418000f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9980ffff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4200011, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1624001f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x96400069, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc40c000e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x28cc0008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xccc00013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce013249, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1a307fe8, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf00000a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x23304076, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd1000001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf000001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc41d3254, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4253256, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x18cc00e8, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x10cc0015, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x4514020c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd140001e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc418000f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9980ffff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4200011, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce013248, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1a2001e8, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x12200014, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x2a204001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce000013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1a64003c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1264001f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x11dc0009, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x15dc000b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7dcdc00a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7e5dc00a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcdc00100, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8800013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400010, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd800002a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf00000d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf00000a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8c001427, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04340022, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x07740001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04300010, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xdf430000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c434001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c408001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd4412e01, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0434001e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xdf430000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd4400078, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xdf030000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd4412e40, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcc41c030, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcc41c031, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x248dfffe, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xccc12e00, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8800013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcc812e00, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c434001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c434001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8c00142b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8000010, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc40c000e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x28cc0008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xccc00013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x45140248, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd140001e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc418000f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9980ffff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc8200011, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce013257, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x56200020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce013258, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0434000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xdb000024, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd1400025, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8000026, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8000026, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400027, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x45540008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd140001e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc418000f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9980ffff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc8200011, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce013259, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x56200020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc0337fff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7f220009, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce01325a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x55300020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7d01c001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x042c01d0, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8c000d61, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x06ec0004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7f01c001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8c000d61, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x041c0002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x042c01c8, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8c000d61, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4380012, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9b80ffff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd800002a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000aa7, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd800002a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c408001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x88000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400029, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c40c001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x50500020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8c001427, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7cd0c01a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4200007, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd0c00072, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc8240072, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd240001e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c414001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x19682011, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x5a6c01fc, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x12ec0009, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7eeac00a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x2aec0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcec0001c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc430000f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9b00ffff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4180011, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c438001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x99800007, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xdf830000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcfa0000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8c00142b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd4400078, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd800002a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80001b70, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8c00142b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd800002a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80001b70, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8000012, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc43c0008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9bc0ffff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400012, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc43c0008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x97c0ffff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4380007, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c40c001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x17b80001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x18d40038, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c410001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9b800004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400029, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc414005e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9540073d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x18c80066, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c414001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x30880001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c418001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x94800008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8c00187c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc42c0004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd910000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcec00008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7d410001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x043c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c41c001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c420001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04240001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x06200001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x4220000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a640001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcc000078, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9a40fffe, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x24e80007, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x24ec0010, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9ac00006, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc42c0004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc5310000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcec00008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80001465, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x51540020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7d15001a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd1000072, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc82c0072, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd2c0001e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x18f02011, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x5aec01fc, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x12ec0009, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7ef2c00a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x2aec0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcec0001c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc42c000f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9ac0ffff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4300011, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x96800012, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x12a80001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0aa80001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x06a8146a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7f1f0009, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x86800000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7f1b400f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80001478, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7f1b400e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80001478, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7f1b400c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8000147a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7f1b400d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8000147a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7f1b400f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8000147a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7f1b400e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8000147a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7f334002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x97400014, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8000147b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9b400012, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9b800005, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9bc0001f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7e024001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x043c0001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8000144a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc40c0032, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc438001d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x28cc0008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xccc00013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc43d325b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1bb81ff0, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7fbfc00a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcfc1325b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc411325d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x251001ef, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd01325d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80001b70, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x94800007, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8c00187c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc42c0004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd910000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcec00008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9b800003, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd800002a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80001b70, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc40c0032, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x28cc0008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xccc00013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc40d325b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x800012c2, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc40c000e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc43c0007, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc438001d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x28cc0008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xccc00013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x13f4000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9bc00006, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc43d3256, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1bf0060b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1bfc0077, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7ff3c00a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x800014a9, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc43d325a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1bfc0677, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04300100, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1bb81ff0, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7f73400a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc0328007, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7fb7800a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x13fc0017, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7ff3c00a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7ffbc00a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcfc1325b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc03a0002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4340004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf8130b5, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf400008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000c16, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x043c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc414000e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x29540008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4193246, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc41d3245, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x51980020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7dd9c01a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x45dc0390, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4313267, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04183000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd813267, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1b380057, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1b340213, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1b300199, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7f7b400a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7f73400a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf400024, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd1c00025, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcc800026, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c420001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce000026, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c424001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce400026, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c428001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce800026, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c42c001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcec00026, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c430001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf000026, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c434001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf400026, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c438001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf800026, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400027, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04182000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd813267, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd840004f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1a0800fd, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x109c000a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4193265, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7dd9c00a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcdc13265, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x2620ffff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce080228, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9880000e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce480250, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce880258, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8080230, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8080238, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8080240, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8080248, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8080268, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8080270, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8080278, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8080280, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd800004f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x97c0ec75, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x040c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x041c0010, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x26180001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x09dc0001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x16200001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x95800002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04cc0001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x99c0fffb, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xccc80230, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8080238, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8080240, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8080248, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x040c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce480250, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce880258, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x52a80020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7e6a401a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x041c0020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x66580001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x09dc0001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x56640001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x95800002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04cc0001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x99c0fffb, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xccc80260, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8080268, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8080270, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8080278, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8080280, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x040c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcec80288, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf080290, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcec80298, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf0802a0, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x040c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x041c0010, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf4802a8, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x27580001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x09dc0001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x17740001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x95800002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04cc0001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x99c0fffb, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xccc802b0, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd80802b8, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x178c000b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x27b8003f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7cf8c001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf8802c0, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xccc802c8, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf8802d0, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf8802d8, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd800004f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x97c00002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c408001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x88000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc40c000e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x28cc0008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xccc00013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc43d3265, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1bc800ea, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c418001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x25b8ffff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4930240, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc48f0238, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04cc0001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x24cc000f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7cd2800c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9a80000b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc5230309, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x2620ffff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7e3a400c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9a400004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x05100001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x2510000f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80001539, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd08034b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd4400078, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000168, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc48f0230, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4930240, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x98c00004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd880353, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8c00163f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc49b0353, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4930238, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc48f0228, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x05100001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x2510000f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7cd14005, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x25540001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x99400004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x05100001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x2510000f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8000154f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc48f0230, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c41c001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd080238, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd08034b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x08cc0001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x2598ffff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x3d200008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xccc80230, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd900309, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8100319, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04340801, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x2198003f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd910ce7, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4190ce6, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7d918005, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x25980001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9580fffd, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7d918004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd810ce6, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9a000003, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcdd1054f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8000156e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x090c0008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcdcd050e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x040c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x110c0014, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x28cc4001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xccc00013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcc41230a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcc41230b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcc41230c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcc41230d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcc480329, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcc48032a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcc4802e0, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8000055, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc48f02e0, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x24d8003f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x09940001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x44100001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9580002c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x95400005, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x09540001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x51100001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x69100001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8000157f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x24cc003f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4970290, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc49b0288, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x51540020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7d59401a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc49b02a0, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc49f0298, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x51980020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7d9d801a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x041c0040, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04200000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7dcdc002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7d924019, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7d26400c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x09dc0001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9a400008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x51100001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x06200001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x99c0fffa, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc48f0230, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4930240, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8c00163f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80001579, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7d010021, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7d914019, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4930238, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x55580020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd480298, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd8802a0, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x10d40010, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x12180016, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc51f0309, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7d95800a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7d62000a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7dd9c00a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcdd00309, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce113320, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc48f02e0, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc49b02b0, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x18dc01e8, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7dd9400e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc48f0230, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4930240, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x95c0001d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x95400003, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8c00163f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x800015aa, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc48f0238, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4a302b8, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x12240004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7e5e400a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4ab02a8, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04100000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce4c0319, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7d9d8002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7ea14005, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x25540001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x99400004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x06200001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x2620000f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x800015bc, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x09dc0001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04240001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7e624004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x06200001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7d25000a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x2620000f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x99c0fff4, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd0d3330, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce0802b8, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd8802b0, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4ab02e0, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1aa807f0, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc48f02d0, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc49702d8, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc49b02c8, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc49f02c0, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x96800028, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7d4e000f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9600000b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7d964002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7e6a000f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x96000003, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7d694001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x800015e9, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7cde4002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7e6a000f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x96000008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7de94001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x800015e9, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7cd64002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7e6a000e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x96000003, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7d694001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x800015e9, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc48f0230, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4930240, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8c00163f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x800015cd, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4930238, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7d698002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd4802d8, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x129c0008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc50f0319, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x11a0000e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x11140001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4340004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7e1e000a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1198000a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd953300, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7e0e000a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x12a8000a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce953301, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce100319, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf400008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4b70280, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4b30278, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7f73800a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x536c0020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7ef2c01a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9780eb68, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8c001608, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8080278, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8080280, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c408001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x88000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x043c0003, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80001609, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x043c0001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x30b40000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9b400011, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4b70258, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4b30250, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x53780020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7fb3801a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7faf8019, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04300020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04280000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x67b40001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0b300001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x57b80001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x97400002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x06a80001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9b00fffb, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4bb0260, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7fab8001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf880260, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04300020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04280000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x66f40001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0b300001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x56ec0001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x97400005, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8c001628, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4353247, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7f7f4009, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9b40fffe, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x06a80001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9b00fff7, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x269c0007, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x11dc0008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x29dc0008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x26a00018, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x12200003, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7de1c00a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x26a00060, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x06200020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x16200001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7de1c00a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcdc00013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x269c0018, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x26a00007, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x26a40060, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x11dc0006, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x12200006, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x16640001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x29dc0008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7de1c00a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7de5c00a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcdc00013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4b70228, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x05100001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04cc0001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x2510000f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xccc80230, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7f514005, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x25540001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x99400004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x05100001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x2510000f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80001644, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4b30248, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd080240, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7f130005, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x27300001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9b000002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8c001688, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8c00120d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8c001219, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8c001232, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04300001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04340801, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7f130004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf01051e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc42d051f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7ed2c005, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x26ec0001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x96c0fffd, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf01051f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8000055, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc5170309, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x195c07f0, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x196007f6, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04340000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x95c00008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x09dc0001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04340001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x95c00005, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x09dc0001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x53740001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x6b740001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80001665, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4a702a0, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4ab0298, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x52640020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7e6a401a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7f634014, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7e76401a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4300004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x56680020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8113320, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce480298, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce8802a0, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc5170319, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4b702b0, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x255c000f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7f5f4001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8113330, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf4802b0, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x11340001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x195c07e8, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x196007ee, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8353300, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7e1e4001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8353301, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce4802d0, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8100309, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8100319, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf000008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4970258, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc48f0250, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x51540020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7cd4c01a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4af0280, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4b30278, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x52ec0020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7ef2c01a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04140020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04280000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x64d80001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x09540001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x54cc0001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x95800060, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8c001628, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4193247, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x25980001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9580005c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7dc24001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc41d3248, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x25dc000f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7dd2000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x96000057, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc41d3255, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc435324f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7df5c00c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x99c00004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4193265, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x25980040, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9580fffe, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc439325b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1bb0003f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x97000049, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1bb000e8, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x33380003, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9b800046, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x33300002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9700000a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4393260, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1bb000e4, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x33300004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x97000040, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc431325d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x27300010, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9b00fffe, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x800016f1, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc033ffff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x2f3000ff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc439325b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7f3b0009, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf01325b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc439325b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x27b800ff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9b80fffe, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8c00033, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4300009, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x27300008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9700fffe, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1a7003e6, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x27380003, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x13b80004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x27300003, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x13300003, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7fb38001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1a7000e8, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7fb38001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x13300001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7fb38001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x07b80002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1a700064, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x33300002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x97000009, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x17b00005, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x07300003, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf012082, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcc01203f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcc01203f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0b300003, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x800016df, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x17b00005, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf012082, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcc01203f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcc01203f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x13300005, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7fb30002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4392083, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7fb38005, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x27b80001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9b80ffdf, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8c00034, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc431325d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x27300010, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9b00fffe, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc439325b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x27b000ff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9b00ffca, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd841325d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x2030007b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf01325b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x800016f2, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd841325d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04300001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7f2b0014, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7ef2c01a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x06a80001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9940ff9c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8c001608, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8080278, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8080280, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd840004f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc414000e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x29540008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc43d3265, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1bc800ea, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd80802e9, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c40c001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x18fc0064, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9bc00042, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4193246, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc41d3245, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x51980020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7dd9801a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x45980400, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4313267, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x043c3000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcfc13267, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc43d3267, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9bc00001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1b380057, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1b340213, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1b300199, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7f7b400a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7f73400a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf400024, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x14f4001d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4bf02e9, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9bc0001c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c410001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x192807fa, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4bf0258, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4a70250, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x53fc0020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7e7e401a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x042c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04300000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x667c0001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x56640001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x06ec0001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x97c0fffd, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x07300001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0aec0001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7eebc00c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x06ec0001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x97c0fff8, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0b300001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x43300007, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x53300002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7db30011, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd3000025, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc03ec005, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x2bfca200, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcfc00026, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xccc00026, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd000026, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x192807fa, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc01f007f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7d1d0009, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x2110007d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8c001628, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x203c003f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcfc13256, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8c0017f5, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd013254, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x18fc01e8, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcfc13248, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8c00185b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8413247, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0b740001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9b40ffd5, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd800004f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4bf02e9, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x97c0ea24, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x14d4001d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4930260, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7d52400e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc49f0258, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4a30250, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x51dc0020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7de1801a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x96400017, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7d534002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4af0270, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7dae4005, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x26640001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x32e0001f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9a400006, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x06ec0001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x96000002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x042c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcec80270, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8000174f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0b740001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8c00178a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x05100001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9b40fff3, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4af0280, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4b30278, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x52ec0020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7ef2c01a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8c001608, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8080278, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8080280, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4ab0268, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7daa4005, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x26640001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x32a0001f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9a400005, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x06a80001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x96000002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x24280000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80001765, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c410001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc01f007f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x09540001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7d1d0009, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x2110007d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8c001628, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8013256, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8c0017f2, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd013254, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4113248, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x15100004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x11100004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4b3034b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7f13000a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf013248, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4930260, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8c001855, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x32a4001f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8413247, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd800004f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x09100001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x06a80001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x96400002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x24280000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd080260, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce880268, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9940ffc0, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c408001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x88000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7ec28001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8c001628, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x32e0001f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4253247, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x26640001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9640005e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4293265, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4253255, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc431324f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7e72400c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x26a80040, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9a400002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9680fff7, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc429325b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1aa4003f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x96400049, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1aa400e8, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x32680003, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9a800046, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x32640002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9640000a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4293260, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1aa400e4, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x32640004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x96400040, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc425325d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x26640010, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9a40fffe, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x800017e2, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcdc00013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc027ffff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x2e6400ff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc429325b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7e6a4009, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce41325b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc429325b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x26a800ff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9a80fffe, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8c00033, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4240009, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x26640008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9640fffe, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x19e403e6, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x26680003, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x12a80004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x26640003, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x12640003, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7ea68001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x19e400e8, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7ea68001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x12640001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7ea68001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x06a80002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x19e40064, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x32640002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x96400009, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x16a40005, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x06640003, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce412082, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcc01203f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcc01203f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a640003, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x800017d0, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x16a40005, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce412082, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcc01203f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcc01203f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x12640005, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7ea64002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4292083, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7ea68005, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x26a80001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9a80ffdf, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8c00034, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcdc00013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc425325d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x26640010, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9a40fffe, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc429325b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x26a400ff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9a40ffca, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd841325d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x2024007b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce41325b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x800017e3, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd841325d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4a70280, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4ab0278, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x52640020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7e6a401a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04280001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7eae8014, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7e6a401a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x56680020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce480278, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce880280, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x06ec0001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x96000002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x042c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcec80270, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c438001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c420001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x800017fe, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4bf02e9, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9bc00006, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c438001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c420001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf800026, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce000026, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x800017fe, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc43b02eb, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc42302ec, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf813245, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce013246, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x52200020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7fa3801a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x47b8020c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x15e00008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1220000a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x2a206032, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x513c001e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7e3e001a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4bf02e9, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9bc00005, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc43c000e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x2bfc0008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcfc00013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8000180f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4313267, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1b3c0077, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1b300199, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7ff3000a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1330000a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x2b300032, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x043c3000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcfc13267, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc43d3267, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd200000b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4200007, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd3800002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf000002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8000040, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x96000002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400040, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400018, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x043c2000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcfc13267, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8000018, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8800010, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcdc00013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7dc30001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xdc1e0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04380032, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf80000e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8c001427, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcc413248, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc43d3269, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x27fc000f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x33fc0003, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x97c00011, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x043c001f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xdfc30000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd4413249, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c43c001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c43c001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x043c0024, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0bfc0021, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xdfc30000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd441326a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x173c0008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1b300303, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7f3f0001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x043c0001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7ff3c004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcfc13084, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80001842, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x043c0024, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xdfc30000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd4413249, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c43c001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x23fc003f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcfc1326d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0bb80026, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xdf830000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd441326e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c438001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c438001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4393265, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1fb8ffc6, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xddc30000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf813265, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9a000003, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcdc0000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80001852, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcdc0000d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce000010, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8c00142b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c41c001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c420001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcdc13252, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce013253, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8c001628, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80001878, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc49f02e9, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x99c00018, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c41c001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c420001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcdc13252, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce013253, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc43c000e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x2bfc0008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcfc00013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x043c3000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcfc13267, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc43d3267, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x97c0ffff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcdc00026, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce000026, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400027, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc41c0012, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x99c0ffff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc43c000e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x2bfc0008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcfc00013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x043c2000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcfc13267, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8c001628, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80001878, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc41f02ed, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc42302ee, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcdc13252, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce013253, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04200001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7e2a0004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce013084, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x28340001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x313c0bcc, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9bc00010, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x393c051f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9bc00004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x3d3c050e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9bc0000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x97c0000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x393c0560, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9bc00004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x3d3c054f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9bc00007, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x97c00007, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x393c1538, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9bc00005, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x3d3c1537, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9bc00002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x97c00002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x2b740800, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc40c000e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x28cc0008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xccc00013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc43d3265, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1bc800ea, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c40c001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x18e8007c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c42c001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x06a8189a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x86800000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8000189e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x800018c5, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x800018f2, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8000016a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c414001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x18d0007e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x50580020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x09200001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7d59401a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd1400072, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc8140072, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x09240002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c418001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c41c001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x99000011, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4340004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc42130b5, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1a24002c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9a40fffe, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x2020002c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc418000d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1198001c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x10cc0004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x14cc0004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7cd8c00a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xccc130b7, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce0130b5, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf400008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000168, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd1400025, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x5978073a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x2bb80002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf800024, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd800026, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcdc00026, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400027, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9600e8a8, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4300012, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9b00ffff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9640e8a5, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x800018a9, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04140000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc55b0309, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x3d5c0010, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x05540001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x2598ffff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x09780001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7dad800c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x99c0ffd2, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9580fff9, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4970258, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4930250, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x51540020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7d15001a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04140020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04280000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x442c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x65180001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x09540001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x55100001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9580000b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8c001628, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc41d3248, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04300001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7f2b0014, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x25dc000f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7df9c00c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x95c00004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7ef2c01a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8c13260, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd901325d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x06a80001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9940fff1, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04140020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04280000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x66d80001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x09540001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x56ec0001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x95800005, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8c001628, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc421325d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x26240007, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9a40fffe, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x06a80001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9940fff7, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8000189e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04140020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04280000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x09540001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8c001628, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc41d3254, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc023007f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x19e4003e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7de1c009, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7dee000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x96400008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x96000007, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8c13260, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd901325d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc421325d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x261c0007, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x99c0fffe, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8000189e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x06a80001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9940fff0, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8000189e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc40c000e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x28cc0008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xccc00013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc43d3265, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1bc800ea, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c40c001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x18e00064, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x06281911, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x14f4001d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x24cc0003, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x86800000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80001915, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x800019af, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80001a2b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8000016a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcc48032b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcc480333, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcc48033b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcc480343, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x98800011, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4213246, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4253245, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x52200020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7e26401a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x46640400, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4313267, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04203000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce013267, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4213267, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9a000001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1b3c0057, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1b200213, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1b300199, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7e3e000a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7e32000a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce000024, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4970258, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4930250, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x51540020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7d15001a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4af0280, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4b30278, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x52ec0020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7ef2c01a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04180000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04140020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04280000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7f438001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8c001628, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc41d3247, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x25dc0001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x95c00068, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4213254, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1a1c003e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x95c00065, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc01f007f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7e1e0009, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x97800062, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0bb80001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x43bc0008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7fcbc001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc7df032b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7e1fc00c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x97c0fffa, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x043c0101, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x94c00002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x043c0102, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc439325b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1bb0003f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x97000049, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1bb000e8, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x33380003, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9b800046, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x33300002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x97000009, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4393260, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1bb000e4, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x33300004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x97000040, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc431325d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x27300010, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9b00fffe, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80001994, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8c001628, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc033ffff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x2f3000ff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc439325b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7f3b0009, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf01325b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc439325b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x27b800ff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9b80fffe, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8c00033, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4300009, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x27300008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9700fffe, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x19f003e6, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x27380003, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x13b80004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x27300003, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x13300003, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7fb38001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x19f000e8, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7fb38001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x13300001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7fb38001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x07b80002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x19f00064, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x33300002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x97000009, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x17b00005, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x07300003, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf012082, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcc01203f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcc01203f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0b300003, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80001982, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x17b00005, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf012082, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcc01203f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcc01203f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x13300005, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7fb30002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4392083, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7fb38005, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x27b80001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9b80ffdf, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8c00034, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcdc00013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc431325d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x27300010, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9b00fffe, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc439325b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x27b000ff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9b00ffcb, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcfc1325d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x2030007b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf01325b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80001995, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcfc1325d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04300001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7f2b0014, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7ef2c01a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x98800009, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x41bc0007, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x53fc0002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7e7fc011, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd3c00025, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8000026, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400027, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc43c0012, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9bc0ffff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x653c0001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7dbd8001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x06a80001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x09540001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x55100001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9940ff8f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc43c000e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x2bfc0008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcfc00013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x043c2000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcfc13267, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8080278, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8080280, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000168, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c410001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04140000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc55b0309, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x3d5c0010, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x2598ffff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x05540001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7d91800c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x95c00003, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd4400078, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000168, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9580fff8, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x09780001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4970258, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4930250, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x51540020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7d15001a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4af0280, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4b30278, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x52ec0020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7ef2c01a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04140020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04280000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x65180001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x09540001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x55100001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9580005d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8c001628, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4253247, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x26640001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04200101, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x96400058, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7dc24001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc41d3248, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x25dc000f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7df9c00c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x95c00053, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x94c00002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04200102, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7e41c001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc425325b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1a70003f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x97000049, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1a7000e8, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x33240003, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9a400046, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x33300002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9700000a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4253260, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1a7000e4, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x33300004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x97000040, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc431325d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x27300010, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9b00fffe, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80001a21, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcdc00013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc033ffff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x2f3000ff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc425325b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7f270009, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf01325b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc425325b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x266400ff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9a40fffe, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8c00033, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4300009, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x27300008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9700fffe, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x19f003e6, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x27240003, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x12640004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x27300003, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x13300003, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7e724001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x19f000e8, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7e724001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x13300001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7e724001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x06640002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x19f00064, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x33300002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x97000009, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x16700005, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x07300003, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf012082, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcc01203f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcc01203f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0b300003, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80001a0f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x16700005, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf012082, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcc01203f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcc01203f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x13300005, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7e730002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4252083, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7e724005, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x26640001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9a40ffdf, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8c00034, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcdc00013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc431325d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x27300010, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9b00fffe, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc425325b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x267000ff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9b00ffca, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce01325d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x2030007b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf01325b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80001a22, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce01325d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04300001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7f2b0014, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7ef2c01a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x06a80001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9940ff9f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd4400078, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8080278, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8080280, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000168, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8c001a31, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd4400078, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8080278, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8080280, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c408001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x88000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4213246, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4253245, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x52200020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7e26401a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x46640400, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4313267, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04203000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce013267, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4213267, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9a000001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1b180057, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1b200213, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1b300199, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7e1a000a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7e32000a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce000024, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4970258, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4930250, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x51540020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7d15001a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4af0280, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4b30278, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x52ec0020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7ef2c01a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04140020, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04280000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x65180001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x95800060, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x8c001628, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4193247, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x25980001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04200101, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x94c00005, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x30f00005, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04200005, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9b000002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04200102, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x95800056, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc439325b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1bb0003f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x97000049, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1bb000e8, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x33380003, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9b800046, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x33300002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9700000a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4393260, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1bb000e4, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x33300004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x97000040, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc431325d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x27300010, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9b00fffe, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80001aa2, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcdc00013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc033ffff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x2f3000ff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc439325b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7f3b0009, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf01325b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc439325b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x27b800ff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9b80fffe, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8c00033, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4300009, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x27300008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9700fffe, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x19f003e6, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x27380003, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x13b80004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x27300003, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x13300003, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7fb38001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x19f000e8, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7fb38001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x13300001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7fb38001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x07b80002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x19f00064, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x33300002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x97000009, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x17b00005, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x07300003, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf012082, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcc01203f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcc01203f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0b300003, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80001a90, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x17b00005, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf012082, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcc01203f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcc01203f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x13300005, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7fb30002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4392083, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7fb38005, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x27b80001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9b80ffdf, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8c00034, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcdc00013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc431325d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x27300010, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9b00fffe, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc439325b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x27b000ff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9b00ffca, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce01325d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x2030007b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf00325b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80001aa3, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce01325d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04300001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7f2b0014, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7ef2c01a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc49b02e9, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x99800005, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd2400025, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x4664001c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8000026, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400027, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x06a80001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x09540001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x55100001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9940ff9c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc49b02e9, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x99800008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc430000e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x2b300008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf000013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04302000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcf013267, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc4313267, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x97000001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x244c00ff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcc4c0200, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c408001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x88000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc44f0200, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc410000b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc414000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7d158010, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x059cc000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xccdd0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c408001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x88000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc40c0037, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x94c0ffff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcc000049, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc40c003a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x94c0ffff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c40c001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x24d00001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9500e69a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x18d0003b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x18d40021, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x99400006, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd840004a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc40c003c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x94c0ffff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x14cc0001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x94c00028, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8000033, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc438000b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc43c0009, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x27fc0001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x97c0fffe, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd841c07f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc43dc07f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1bfc0078, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7ffbc00c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x97c0fffd, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x99000004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc0120840, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x282c0040, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80001ae8, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc0121841, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x282c001a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd01c07c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcc01c07d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcc01c08c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcc01c079, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcc01c07e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04200004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcec0001b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a200001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9a00ffff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc425c07f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x166c001f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04200004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9ac0fffb, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc434000f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9b40ffff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd801c07f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc425c07f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce400078, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8000034, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9940e66b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd800004a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c408001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x88000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc40c0036, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x24d00001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9900fffe, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x18cc0021, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xccc00047, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcc000046, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc40c0039, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x94c0ffff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc40c003d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x98c0ffff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c40c001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x24d003ff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x18d47fea, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x18d87ff4, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd00004c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd40004e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd80004d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd41c405, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc02a0001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x2aa80001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce800013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd01c406, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcc01c406, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcc01c406, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc40c0006, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x98c0ffff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc414000e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x29540008, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x295c0001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8c1325e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcdc0001a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x11980002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x4110000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc0160800, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7d15000a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc0164010, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd41c078, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcc01c080, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcc01c081, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd81c082, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcc01c083, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd01c084, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc40c0006, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x98c0ffff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400048, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc40c003b, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x94c0ffff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000c16, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd801c40a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd901c40d, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd801c410, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd801c40e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd801c40f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc40c0040, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04140001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x09540001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9940ffff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04140096, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xccc1c400, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc411c401, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9500fffa, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc424003e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04d00001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x11100002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd01c40c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc0180034, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd81c411, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd841c414, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0a540001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcd41c412, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x2468000f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc419c416, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x41980003, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc41c003f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7dda0001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x12200002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x10cc0002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xccc1c40c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd901c411, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce41c412, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd8800013, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xce292e40, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcc412e01, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcc412e02, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcc412e03, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcc412e00, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000aa7, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc43c0007, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xdc120000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x31144000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x95400005, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xdc030000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd800002a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xcc3c000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80001b70, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x33f80003, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd4400078, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x9780e601, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x188cfff0, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x04e40002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80001190, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c408001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x88000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc424005e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x96400006, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc424005e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x96400003, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7c408001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x88000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80001b74, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000168, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xbf810000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000004, mmCP_DFY_CNTL                              },
+    { PwrCmdWrite, 0x000000b4, mmCP_DFY_ADDR_HI                           },
+    { PwrCmdWrite, 0x54106500, mmCP_DFY_ADDR_LO                           },
+    { PwrCmdWrite, 0x7e000200, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7e020204, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc00a0505, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xbf8c007f, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xb8900904, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xb8911a04, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xb8920304, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xb8930b44, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x921c0d0c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x921c1c13, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x921d0c12, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x811c1d1c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x811c111c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x921cff1c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000400, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x921dff10, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000100, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x81181d1c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7e040218, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xe0701000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80050002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xe0701000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80050102, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xe0701000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80050002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xe0701000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80050102, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xe0701000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80050002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xe0701000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80050102, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xbf810000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000004, mmCP_DFY_CNTL                              },
+    { PwrCmdWrite, 0x000000b4, mmCP_DFY_ADDR_HI                           },
+    { PwrCmdWrite, 0x54106900, mmCP_DFY_ADDR_LO                           },
+    { PwrCmdWrite, 0x7e080200, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x7e100204, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xbefc00ff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00010000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x24200087, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x262200ff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x000001f0, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x20222282, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x28182111, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd81a0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0000040c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd81a0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0000080c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd81a0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0000040c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd81a0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0000080c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd81a0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0000040c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd81a0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0000080c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd81a0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0000040c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd81a0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0000080c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd81a0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0000040c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd81a0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0000080c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd81a0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0000040c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd81a0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0000080c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd81a0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0000040c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd81a0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0000080c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd81a0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0000040c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd81a0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0000080c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd81a0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0000040c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd81a0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0000080c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd81a0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0000040c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd81a0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0000080c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xbf810000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x80000004, mmCP_DFY_CNTL                              },
+    { PwrCmdWrite, 0x000000b4, mmCP_DFY_ADDR_HI                           },
+    { PwrCmdWrite, 0x54116f00, mmCP_DFY_ADDR_LO                           },
+    { PwrCmdWrite, 0xc0310800, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000040, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xb4540fe8, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000041, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0000000c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x07808000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xffffffff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xffffffff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xffffffff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xffffffff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xaaaaaaaa, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xaaaaaaaa, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xaaaaaaaa, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xaaaaaaaa, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x55555555, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x55555555, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x55555555, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x55555555, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x540fee40, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x000000b4, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000010, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x54116f00, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x000000b4, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00005301, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xb4540fef, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x540fee20, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x000000b4, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x08000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc0310800, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000040, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xb454105e, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x000000c0, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000010, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x07808000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xffffffff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xffffffff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xffffffff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xffffffff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xaaaaaaaa, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xaaaaaaaa, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xaaaaaaaa, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xaaaaaaaa, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x55555555, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x55555555, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x55555555, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x55555555, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x540fee40, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x000000b4, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000010, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x54117300, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x000000b4, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00005301, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xb4540fef, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x540fee20, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x000000b4, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x08000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc0310800, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000040, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xb4541065, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000500, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0000001c, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x07808000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xffffffff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xffffffff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xffffffff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xffffffff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xaaaaaaaa, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xaaaaaaaa, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xaaaaaaaa, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xaaaaaaaa, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x55555555, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x55555555, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x55555555, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x55555555, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x540fee40, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x000000b4, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000010, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x54117700, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x000000b4, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00005301, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xb4540fef, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x540fee20, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x000000b4, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x08000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xc0310800, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000040, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xb4541069, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000444, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x0000008a, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x07808000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xffffffff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xffffffff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xffffffff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xffffffff, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000002, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xaaaaaaaa, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xaaaaaaaa, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xaaaaaaaa, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xaaaaaaaa, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x55555555, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x55555555, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x55555555, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x55555555, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x540fee40, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x000000b4, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000010, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000001, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000004, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x54117b00, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x000000b4, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00005301, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0xb4540fef, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x540fee20, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x000000b4, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x08000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0                            },
+    { PwrCmdWrite, 0x00000000, mmCP_MEC_CNTL                              },
+    { PwrCmdWrite, 0x00000000, mmCP_MEC_CNTL                              },
+    { PwrCmdWrite, 0x00000004, mmSRBM_GFX_CNTL                            },
+    { PwrCmdWrite, 0x54116f00, mmCP_MQD_BASE_ADDR                         },
+    { PwrCmdWrite, 0x000000b4, mmCP_MQD_BASE_ADDR_HI                      },
+    { PwrCmdWrite, 0xb4540fef, mmCP_HQD_PQ_BASE                           },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_BASE_HI                        },
+    { PwrCmdWrite, 0x540fee20, mmCP_HQD_PQ_WPTR_POLL_ADDR                 },
+    { PwrCmdWrite, 0x000000b4, mmCP_HQD_PQ_WPTR_POLL_ADDR_HI              },
+    { PwrCmdWrite, 0x00005301, mmCP_HQD_PERSISTENT_STATE                  },
+    { PwrCmdWrite, 0x00010000, mmCP_HQD_VMID                              },
+    { PwrCmdWrite, 0xc8318509, mmCP_HQD_PQ_CONTROL                        },
+    { PwrCmdWrite, 0x00000005, mmSRBM_GFX_CNTL                            },
+    { PwrCmdWrite, 0x54117300, mmCP_MQD_BASE_ADDR                         },
+    { PwrCmdWrite, 0x000000b4, mmCP_MQD_BASE_ADDR_HI                      },
+    { PwrCmdWrite, 0xb4540fef, mmCP_HQD_PQ_BASE                           },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_BASE_HI                        },
+    { PwrCmdWrite, 0x540fee20, mmCP_HQD_PQ_WPTR_POLL_ADDR                 },
+    { PwrCmdWrite, 0x000000b4, mmCP_HQD_PQ_WPTR_POLL_ADDR_HI              },
+    { PwrCmdWrite, 0x00005301, mmCP_HQD_PERSISTENT_STATE                  },
+    { PwrCmdWrite, 0x00010000, mmCP_HQD_VMID                              },
+    { PwrCmdWrite, 0xc8318509, mmCP_HQD_PQ_CONTROL                        },
+    { PwrCmdWrite, 0x00000006, mmSRBM_GFX_CNTL                            },
+    { PwrCmdWrite, 0x54117700, mmCP_MQD_BASE_ADDR                         },
+    { PwrCmdWrite, 0x000000b4, mmCP_MQD_BASE_ADDR_HI                      },
+    { PwrCmdWrite, 0xb4540fef, mmCP_HQD_PQ_BASE                           },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_BASE_HI                        },
+    { PwrCmdWrite, 0x540fee20, mmCP_HQD_PQ_WPTR_POLL_ADDR                 },
+    { PwrCmdWrite, 0x000000b4, mmCP_HQD_PQ_WPTR_POLL_ADDR_HI              },
+    { PwrCmdWrite, 0x00005301, mmCP_HQD_PERSISTENT_STATE                  },
+    { PwrCmdWrite, 0x00010000, mmCP_HQD_VMID                              },
+    { PwrCmdWrite, 0xc8318509, mmCP_HQD_PQ_CONTROL                        },
+    { PwrCmdWrite, 0x00000007, mmSRBM_GFX_CNTL                            },
+    { PwrCmdWrite, 0x54117b00, mmCP_MQD_BASE_ADDR                         },
+    { PwrCmdWrite, 0x000000b4, mmCP_MQD_BASE_ADDR_HI                      },
+    { PwrCmdWrite, 0xb4540fef, mmCP_HQD_PQ_BASE                           },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_BASE_HI                        },
+    { PwrCmdWrite, 0x540fee20, mmCP_HQD_PQ_WPTR_POLL_ADDR                 },
+    { PwrCmdWrite, 0x000000b4, mmCP_HQD_PQ_WPTR_POLL_ADDR_HI              },
+    { PwrCmdWrite, 0x00005301, mmCP_HQD_PERSISTENT_STATE                  },
+    { PwrCmdWrite, 0x00010000, mmCP_HQD_VMID                              },
+    { PwrCmdWrite, 0xc8318509, mmCP_HQD_PQ_CONTROL                        },
+    { PwrCmdWrite, 0x00000004, mmSRBM_GFX_CNTL                            },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE                            },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR                           },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR                           },
+    { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE                            },
+    { PwrCmdWrite, 0x00000104, mmSRBM_GFX_CNTL                            },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE                            },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR                           },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR                           },
+    { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE                            },
+    { PwrCmdWrite, 0x00000204, mmSRBM_GFX_CNTL                            },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE                            },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR                           },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR                           },
+    { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE                            },
+    { PwrCmdWrite, 0x00000304, mmSRBM_GFX_CNTL                            },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE                            },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR                           },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR                           },
+    { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE                            },
+    { PwrCmdWrite, 0x00000404, mmSRBM_GFX_CNTL                            },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE                            },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR                           },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR                           },
+    { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE                            },
+    { PwrCmdWrite, 0x00000504, mmSRBM_GFX_CNTL                            },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE                            },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR                           },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR                           },
+    { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE                            },
+    { PwrCmdWrite, 0x00000604, mmSRBM_GFX_CNTL                            },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE                            },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR                           },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR                           },
+    { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE                            },
+    { PwrCmdWrite, 0x00000704, mmSRBM_GFX_CNTL                            },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE                            },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR                           },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR                           },
+    { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE                            },
+    { PwrCmdWrite, 0x00000005, mmSRBM_GFX_CNTL                            },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE                            },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR                           },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR                           },
+    { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE                            },
+    { PwrCmdWrite, 0x00000105, mmSRBM_GFX_CNTL                            },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE                            },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR                           },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR                           },
+    { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE                            },
+    { PwrCmdWrite, 0x00000205, mmSRBM_GFX_CNTL                            },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE                            },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR                           },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR                           },
+    { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE                            },
+    { PwrCmdWrite, 0x00000305, mmSRBM_GFX_CNTL                            },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE                            },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR                           },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR                           },
+    { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE                            },
+    { PwrCmdWrite, 0x00000405, mmSRBM_GFX_CNTL                            },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE                            },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR                           },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR                           },
+    { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE                            },
+    { PwrCmdWrite, 0x00000505, mmSRBM_GFX_CNTL                            },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE                            },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR                           },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR                           },
+    { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE                            },
+    { PwrCmdWrite, 0x00000605, mmSRBM_GFX_CNTL                            },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE                            },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR                           },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR                           },
+    { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE                            },
+    { PwrCmdWrite, 0x00000705, mmSRBM_GFX_CNTL                            },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE                            },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR                           },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR                           },
+    { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE                            },
+    { PwrCmdWrite, 0x00000006, mmSRBM_GFX_CNTL                            },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE                            },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR                           },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR                           },
+    { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE                            },
+    { PwrCmdWrite, 0x00000106, mmSRBM_GFX_CNTL                            },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE                            },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR                           },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR                           },
+    { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE                            },
+    { PwrCmdWrite, 0x00000206, mmSRBM_GFX_CNTL                            },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE                            },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR                           },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR                           },
+    { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE                            },
+    { PwrCmdWrite, 0x00000306, mmSRBM_GFX_CNTL                            },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE                            },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR                           },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR                           },
+    { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE                            },
+    { PwrCmdWrite, 0x00000406, mmSRBM_GFX_CNTL                            },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE                            },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR                           },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR                           },
+    { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE                            },
+    { PwrCmdWrite, 0x00000506, mmSRBM_GFX_CNTL                            },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE                            },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR                           },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR                           },
+    { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE                            },
+    { PwrCmdWrite, 0x00000606, mmSRBM_GFX_CNTL                            },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE                            },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR                           },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR                           },
+    { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE                            },
+    { PwrCmdWrite, 0x00000706, mmSRBM_GFX_CNTL                            },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE                            },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR                           },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR                           },
+    { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE                            },
+    { PwrCmdWrite, 0x00000007, mmSRBM_GFX_CNTL                            },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE                            },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR                           },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR                           },
+    { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE                            },
+    { PwrCmdWrite, 0x00000107, mmSRBM_GFX_CNTL                            },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE                            },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR                           },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR                           },
+    { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE                            },
+    { PwrCmdWrite, 0x00000207, mmSRBM_GFX_CNTL                            },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE                            },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR                           },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR                           },
+    { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE                            },
+    { PwrCmdWrite, 0x00000307, mmSRBM_GFX_CNTL                            },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE                            },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR                           },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR                           },
+    { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE                            },
+    { PwrCmdWrite, 0x00000407, mmSRBM_GFX_CNTL                            },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE                            },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR                           },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR                           },
+    { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE                            },
+    { PwrCmdWrite, 0x00000507, mmSRBM_GFX_CNTL                            },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE                            },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR                           },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR                           },
+    { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE                            },
+    { PwrCmdWrite, 0x00000607, mmSRBM_GFX_CNTL                            },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE                            },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR                           },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR                           },
+    { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE                            },
+    { PwrCmdWrite, 0x00000707, mmSRBM_GFX_CNTL                            },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE                            },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR                           },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR                           },
+    { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE                            },
+    { PwrCmdWrite, 0x00000008, mmSRBM_GFX_CNTL                            },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE                            },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR                           },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR                           },
+    { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE                            },
+    { PwrCmdWrite, 0x00000108, mmSRBM_GFX_CNTL                            },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE                            },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR                           },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR                           },
+    { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE                            },
+    { PwrCmdWrite, 0x00000208, mmSRBM_GFX_CNTL                            },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE                            },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR                           },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR                           },
+    { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE                            },
+    { PwrCmdWrite, 0x00000308, mmSRBM_GFX_CNTL                            },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE                            },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR                           },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR                           },
+    { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE                            },
+    { PwrCmdWrite, 0x00000408, mmSRBM_GFX_CNTL                            },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE                            },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR                           },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR                           },
+    { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE                            },
+    { PwrCmdWrite, 0x00000508, mmSRBM_GFX_CNTL                            },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE                            },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR                           },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR                           },
+    { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE                            },
+    { PwrCmdWrite, 0x00000608, mmSRBM_GFX_CNTL                            },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE                            },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR                           },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR                           },
+    { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE                            },
+    { PwrCmdWrite, 0x00000708, mmSRBM_GFX_CNTL                            },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE                            },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR                           },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR                           },
+    { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE                            },
+    { PwrCmdWrite, 0x00000009, mmSRBM_GFX_CNTL                            },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE                            },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR                           },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR                           },
+    { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE                            },
+    { PwrCmdWrite, 0x00000109, mmSRBM_GFX_CNTL                            },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE                            },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR                           },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR                           },
+    { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE                            },
+    { PwrCmdWrite, 0x00000209, mmSRBM_GFX_CNTL                            },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE                            },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR                           },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR                           },
+    { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE                            },
+    { PwrCmdWrite, 0x00000309, mmSRBM_GFX_CNTL                            },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE                            },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR                           },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR                           },
+    { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE                            },
+    { PwrCmdWrite, 0x00000409, mmSRBM_GFX_CNTL                            },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE                            },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR                           },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR                           },
+    { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE                            },
+    { PwrCmdWrite, 0x00000509, mmSRBM_GFX_CNTL                            },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE                            },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR                           },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR                           },
+    { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE                            },
+    { PwrCmdWrite, 0x00000609, mmSRBM_GFX_CNTL                            },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE                            },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR                           },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR                           },
+    { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE                            },
+    { PwrCmdWrite, 0x00000709, mmSRBM_GFX_CNTL                            },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE                            },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR                           },
+    { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR                           },
+    { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE                            },
+    { PwrCmdWrite, 0x00000004, mmSRBM_GFX_CNTL                            },
+    { PwrCmdWrite, 0x01010101, mmCP_PQ_WPTR_POLL_CNTL1                    },
+    { PwrCmdWrite, 0x00000000, mmGRBM_STATUS                              },
+    { PwrCmdWrite, 0x00000000, mmGRBM_STATUS                              },
+    { PwrCmdWrite, 0x00000000, mmGRBM_STATUS                              },
+    { PwrCmdEnd,   0x00000000, 0x00000000                                 },
+};
+
+#endif
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/powerplay/inc/hardwaremanager.h
@@ -0,0 +1,385 @@
+/*
+ * Copyright 2015 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+#ifndef _HARDWARE_MANAGER_H_
+#define _HARDWARE_MANAGER_H_
+
+
+
+struct pp_hwmgr;
+struct pp_hw_power_state;
+struct pp_power_state;
+enum amd_dpm_forced_level;
+struct PP_TemperatureRange;
+
+struct phm_fan_speed_info {
+	uint32_t min_percent;
+	uint32_t max_percent;
+	uint32_t min_rpm;
+	uint32_t max_rpm;
+	bool supports_percent_read;
+	bool supports_percent_write;
+	bool supports_rpm_read;
+	bool supports_rpm_write;
+};
+
+/* Automatic Power State Throttling */
+enum PHM_AutoThrottleSource
+{
+    PHM_AutoThrottleSource_Thermal,
+    PHM_AutoThrottleSource_External
+};
+
+typedef enum PHM_AutoThrottleSource PHM_AutoThrottleSource;
+
+enum phm_platform_caps {
+	PHM_PlatformCaps_AtomBiosPpV1 = 0,
+	PHM_PlatformCaps_PowerPlaySupport,
+	PHM_PlatformCaps_ACOverdriveSupport,
+	PHM_PlatformCaps_BacklightSupport,
+	PHM_PlatformCaps_ThermalController,
+	PHM_PlatformCaps_BiosPowerSourceControl,
+	PHM_PlatformCaps_DisableVoltageTransition,
+	PHM_PlatformCaps_DisableEngineTransition,
+	PHM_PlatformCaps_DisableMemoryTransition,
+	PHM_PlatformCaps_DynamicPowerManagement,
+	PHM_PlatformCaps_EnableASPML0s,
+	PHM_PlatformCaps_EnableASPML1,
+	PHM_PlatformCaps_OD5inACSupport,
+	PHM_PlatformCaps_OD5inDCSupport,
+	PHM_PlatformCaps_SoftStateOD5,
+	PHM_PlatformCaps_NoOD5Support,
+	PHM_PlatformCaps_ContinuousHardwarePerformanceRange,
+	PHM_PlatformCaps_ActivityReporting,
+	PHM_PlatformCaps_EnableBackbias,
+	PHM_PlatformCaps_OverdriveDisabledByPowerBudget,
+	PHM_PlatformCaps_ShowPowerBudgetWarning,
+	PHM_PlatformCaps_PowerBudgetWaiverAvailable,
+	PHM_PlatformCaps_GFXClockGatingSupport,
+	PHM_PlatformCaps_MMClockGatingSupport,
+	PHM_PlatformCaps_AutomaticDCTransition,
+	PHM_PlatformCaps_GeminiPrimary,
+	PHM_PlatformCaps_MemorySpreadSpectrumSupport,
+	PHM_PlatformCaps_EngineSpreadSpectrumSupport,
+	PHM_PlatformCaps_StepVddc,
+	PHM_PlatformCaps_DynamicPCIEGen2Support,
+	PHM_PlatformCaps_SMC,
+	PHM_PlatformCaps_FaultyInternalThermalReading,          /* Internal thermal controller reports faulty temperature value when DAC2 is active */
+	PHM_PlatformCaps_EnableVoltageControl,                  /* indicates voltage can be controlled */
+	PHM_PlatformCaps_EnableSideportControl,                 /* indicates Sideport can be controlled */
+	PHM_PlatformCaps_VideoPlaybackEEUNotification,          /* indicates EEU notification of video start/stop is required */
+	PHM_PlatformCaps_TurnOffPll_ASPML1,                     /* PCIE Turn Off PLL in ASPM L1 */
+	PHM_PlatformCaps_EnableHTLinkControl,                   /* indicates HT Link can be controlled by ACPI or CLMC overrided/automated mode. */
+	PHM_PlatformCaps_PerformanceStateOnly,                  /* indicates only performance power state to be used on current system. */
+	PHM_PlatformCaps_ExclusiveModeAlwaysHigh,               /* In Exclusive (3D) mode always stay in High state. */
+	PHM_PlatformCaps_DisableMGClockGating,                  /* to disable Medium Grain Clock Gating or not */
+	PHM_PlatformCaps_DisableMGCGTSSM,                       /* TO disable Medium Grain Clock Gating Shader Complex control */
+	PHM_PlatformCaps_UVDAlwaysHigh,                         /* In UVD mode always stay in High state */
+	PHM_PlatformCaps_DisablePowerGating,                    /* to disable power gating */
+	PHM_PlatformCaps_CustomThermalPolicy,                   /* indicates only performance power state to be used on current system. */
+	PHM_PlatformCaps_StayInBootState,                       /* Stay in Boot State, do not do clock/voltage or PCIe Lane and Gen switching (RV7xx and up). */
+	PHM_PlatformCaps_SMCAllowSeparateSWThermalState,        /* SMC use separate SW thermal state, instead of the default SMC thermal policy. */
+	PHM_PlatformCaps_MultiUVDStateSupport,                  /* Powerplay state table supports multi UVD states. */
+	PHM_PlatformCaps_EnableSCLKDeepSleepForUVD,             /* With HW ECOs, we don't need to disable SCLK Deep Sleep for UVD state. */
+	PHM_PlatformCaps_EnableMCUHTLinkControl,                /* Enable HT link control by MCU */
+	PHM_PlatformCaps_ABM,                                   /* ABM support.*/
+	PHM_PlatformCaps_KongThermalPolicy,                     /* A thermal policy specific for Kong */
+	PHM_PlatformCaps_SwitchVDDNB,                           /* if the users want to switch VDDNB */
+	PHM_PlatformCaps_ULPS,                                  /* support ULPS mode either through ACPI state or ULPS state */
+	PHM_PlatformCaps_NativeULPS,                            /* hardware capable of ULPS state (other than through the ACPI state) */
+	PHM_PlatformCaps_EnableMVDDControl,                     /* indicates that memory voltage can be controlled */
+	PHM_PlatformCaps_ControlVDDCI,                          /* Control VDDCI separately from VDDC. */
+	PHM_PlatformCaps_DisableDCODT,                          /* indicates if DC ODT apply or not */
+	PHM_PlatformCaps_DynamicACTiming,                       /* if the SMC dynamically re-programs MC SEQ register values */
+	PHM_PlatformCaps_EnableThermalIntByGPIO,                /* enable throttle control through GPIO */
+	PHM_PlatformCaps_BootStateOnAlert,                      /* Go to boot state on alerts, e.g. on an AC->DC transition. */
+	PHM_PlatformCaps_DontWaitForVBlankOnAlert,              /* Do NOT wait for VBLANK during an alert (e.g. AC->DC transition). */
+	PHM_PlatformCaps_Force3DClockSupport,                   /* indicates if the platform supports force 3D clock. */
+	PHM_PlatformCaps_MicrocodeFanControl,                   /* Fan is controlled by the SMC microcode. */
+	PHM_PlatformCaps_AdjustUVDPriorityForSP,
+	PHM_PlatformCaps_DisableLightSleep,                     /* Light sleep for evergreen family. */
+	PHM_PlatformCaps_DisableMCLS,                           /* MC Light sleep */
+	PHM_PlatformCaps_RegulatorHot,                          /* Enable throttling on 'regulator hot' events. */
+	PHM_PlatformCaps_BACO,                                  /* Support Bus Alive Chip Off mode */
+	PHM_PlatformCaps_DisableDPM,                            /* Disable DPM, supported from Llano */
+	PHM_PlatformCaps_DynamicM3Arbiter,                      /* support dynamically change m3 arbitor parameters */
+	PHM_PlatformCaps_SclkDeepSleep,                         /* support sclk deep sleep */
+	PHM_PlatformCaps_DynamicPatchPowerState,                /* this ASIC supports to patch power state dynamically */
+	PHM_PlatformCaps_ThermalAutoThrottling,                 /* enabling auto thermal throttling, */
+	PHM_PlatformCaps_SumoThermalPolicy,                     /* A thermal policy specific for Sumo */
+	PHM_PlatformCaps_PCIEPerformanceRequest,                /* support to change RC voltage */
+	PHM_PlatformCaps_BLControlledByGPU,                     /* support varibright */
+	PHM_PlatformCaps_PowerContainment,                      /* support DPM2 power containment (AKA TDP clamping) */
+	PHM_PlatformCaps_SQRamping,                             /* support DPM2 SQ power throttle */
+	PHM_PlatformCaps_CAC,                                   /* support Capacitance * Activity power estimation */
+	PHM_PlatformCaps_NIChipsets,                            /* Northern Island and beyond chipsets */
+	PHM_PlatformCaps_TrinityChipsets,                       /* Trinity chipset */
+	PHM_PlatformCaps_EvergreenChipsets,                     /* Evergreen family chipset */
+	PHM_PlatformCaps_PowerControl,                          /* Cayman and beyond chipsets */
+	PHM_PlatformCaps_DisableLSClockGating,                  /* to disable Light Sleep control for HDP memories */
+	PHM_PlatformCaps_BoostState,                            /* this ASIC supports boost state */
+	PHM_PlatformCaps_UserMaxClockForMultiDisplays,          /* indicates if max memory clock is used for all status when multiple displays are connected */
+	PHM_PlatformCaps_RegWriteDelay,                         /* indicates if back to back reg write delay is required */
+	PHM_PlatformCaps_NonABMSupportInPPLib,                  /* ABM is not supported in PPLIB, (moved from PPLIB to DAL) */
+	PHM_PlatformCaps_GFXDynamicMGPowerGating,               /* Enable Dynamic MG PowerGating on Trinity */
+	PHM_PlatformCaps_DisableSMUUVDHandshake,                /* Disable SMU UVD Handshake */
+	PHM_PlatformCaps_DTE,                                   /* Support Digital Temperature Estimation */
+	PHM_PlatformCaps_W5100Specifc_SmuSkipMsgDTE,            /* This is for the feature requested by David B., and Tonny W.*/
+	PHM_PlatformCaps_UVDPowerGating,                        /* enable UVD power gating, supported from Llano */
+	PHM_PlatformCaps_UVDDynamicPowerGating,                 /* enable UVD Dynamic power gating, supported from UVD5 */
+	PHM_PlatformCaps_VCEPowerGating,                        /* Enable VCE power gating, supported for TN and later ASICs */
+	PHM_PlatformCaps_SamuPowerGating,                       /* Enable SAMU power gating, supported for KV and later ASICs */
+	PHM_PlatformCaps_UVDDPM,                                /* UVD clock DPM */
+	PHM_PlatformCaps_VCEDPM,                                /* VCE clock DPM */
+	PHM_PlatformCaps_SamuDPM,                               /* SAMU clock DPM */
+	PHM_PlatformCaps_AcpDPM,                                /* ACP clock DPM */
+	PHM_PlatformCaps_SclkDeepSleepAboveLow,                 /* Enable SCLK Deep Sleep on all DPM states */
+	PHM_PlatformCaps_DynamicUVDState,                       /* Dynamic UVD State */
+	PHM_PlatformCaps_WantSAMClkWithDummyBackEnd,            /* Set SAM Clk With Dummy Back End */
+	PHM_PlatformCaps_WantUVDClkWithDummyBackEnd,            /* Set UVD Clk With Dummy Back End */
+	PHM_PlatformCaps_WantVCEClkWithDummyBackEnd,            /* Set VCE Clk With Dummy Back End */
+	PHM_PlatformCaps_WantACPClkWithDummyBackEnd,            /* Set SAM Clk With Dummy Back End */
+	PHM_PlatformCaps_OD6inACSupport,                        /* indicates that the ASIC/back end supports OD6 */
+	PHM_PlatformCaps_OD6inDCSupport,                        /* indicates that the ASIC/back end supports OD6 in DC */
+	PHM_PlatformCaps_EnablePlatformPowerManagement,         /* indicates that Platform Power Management feature is supported */
+	PHM_PlatformCaps_SurpriseRemoval,                       /* indicates that surprise removal feature is requested */
+	PHM_PlatformCaps_NewCACVoltage,                         /* indicates new CAC voltage table support */
+	PHM_PlatformCaps_DBRamping,                             /* for dI/dT feature */
+	PHM_PlatformCaps_TDRamping,                             /* for dI/dT feature */
+	PHM_PlatformCaps_TCPRamping,                            /* for dI/dT feature */
+	PHM_PlatformCaps_EnableSMU7ThermalManagement,           /* SMC will manage thermal events */
+	PHM_PlatformCaps_FPS,                                   /* FPS support */
+	PHM_PlatformCaps_ACP,                                   /* ACP support */
+	PHM_PlatformCaps_SclkThrottleLowNotification,           /* SCLK Throttle Low Notification */
+	PHM_PlatformCaps_XDMAEnabled,                           /* XDMA engine is enabled */
+	PHM_PlatformCaps_UseDummyBackEnd,                       /* use dummy back end */
+	PHM_PlatformCaps_EnableDFSBypass,                       /* Enable DFS bypass */
+	PHM_PlatformCaps_VddNBDirectRequest,
+	PHM_PlatformCaps_PauseMMSessions,
+	PHM_PlatformCaps_UnTabledHardwareInterface,             /* Tableless/direct call hardware interface for CI and newer ASICs */
+	PHM_PlatformCaps_SMU7,                                  /* indicates that vpuRecoveryBegin without SMU shutdown */
+	PHM_PlatformCaps_RevertGPIO5Polarity,                   /* indicates revert GPIO5 plarity table support */
+	PHM_PlatformCaps_Thermal2GPIO17,                        /* indicates thermal2GPIO17 table support */
+	PHM_PlatformCaps_ThermalOutGPIO,                        /* indicates ThermalOutGPIO support, pin number is assigned by VBIOS */
+	PHM_PlatformCaps_DisableMclkSwitchingForFrameLock,      /* Disable memory clock switch during Framelock */
+	PHM_PlatformCaps_VRHotGPIOConfigurable,                 /* indicates VR_HOT GPIO configurable */
+	PHM_PlatformCaps_TempInversion,                         /* enable Temp Inversion feature */
+	PHM_PlatformCaps_IOIC3,
+	PHM_PlatformCaps_ConnectedStandby,
+	PHM_PlatformCaps_EVV,
+	PHM_PlatformCaps_EnableLongIdleBACOSupport,
+	PHM_PlatformCaps_CombinePCCWithThermalSignal,
+	PHM_PlatformCaps_DisableUsingActualTemperatureForPowerCalc,
+	PHM_PlatformCaps_StablePState,
+	PHM_PlatformCaps_OD6PlusinACSupport,
+	PHM_PlatformCaps_OD6PlusinDCSupport,
+	PHM_PlatformCaps_ODThermalLimitUnlock,
+	PHM_PlatformCaps_ReducePowerLimit,
+	PHM_PlatformCaps_ODFuzzyFanControlSupport,
+	PHM_PlatformCaps_GeminiRegulatorFanControlSupport,
+	PHM_PlatformCaps_ControlVDDGFX,
+	PHM_PlatformCaps_BBBSupported,
+	PHM_PlatformCaps_DisableVoltageIsland,
+	PHM_PlatformCaps_FanSpeedInTableIsRPM,
+	PHM_PlatformCaps_GFXClockGatingManagedInCAIL,
+	PHM_PlatformCaps_IcelandULPSSWWorkAround,
+	PHM_PlatformCaps_FPSEnhancement,
+	PHM_PlatformCaps_LoadPostProductionFirmware,
+	PHM_PlatformCaps_VpuRecoveryInProgress,
+	PHM_PlatformCaps_Falcon_QuickTransition,
+	PHM_PlatformCaps_AVFS,
+	PHM_PlatformCaps_ClockStretcher,
+	PHM_PlatformCaps_TablelessHardwareInterface,
+	PHM_PlatformCaps_EnableDriverEVV,
+	PHM_PlatformCaps_Max
+};
+
+#define PHM_MAX_NUM_CAPS_BITS_PER_FIELD (sizeof(uint32_t)*8)
+
+/* Number of uint32_t entries used by CAPS table */
+#define PHM_MAX_NUM_CAPS_ULONG_ENTRIES \
+	((PHM_PlatformCaps_Max + ((PHM_MAX_NUM_CAPS_BITS_PER_FIELD) - 1)) / (PHM_MAX_NUM_CAPS_BITS_PER_FIELD))
+
+struct pp_hw_descriptor {
+	uint32_t hw_caps[PHM_MAX_NUM_CAPS_ULONG_ENTRIES];
+};
+
+enum PHM_PerformanceLevelDesignation {
+	PHM_PerformanceLevelDesignation_Activity,
+	PHM_PerformanceLevelDesignation_PowerContainment
+};
+
+typedef enum PHM_PerformanceLevelDesignation PHM_PerformanceLevelDesignation;
+
+struct PHM_PerformanceLevel {
+    uint32_t    coreClock;
+    uint32_t    memory_clock;
+    uint32_t  vddc;
+    uint32_t  vddci;
+    uint32_t    nonLocalMemoryFreq;
+    uint32_t nonLocalMemoryWidth;
+};
+
+typedef struct PHM_PerformanceLevel PHM_PerformanceLevel;
+
+/* Function for setting a platform cap */
+static inline void phm_cap_set(uint32_t *caps,
+			enum phm_platform_caps c)
+{
+	caps[c / PHM_MAX_NUM_CAPS_BITS_PER_FIELD] |= (1UL <<
+			     (c & (PHM_MAX_NUM_CAPS_BITS_PER_FIELD - 1)));
+}
+
+static inline void phm_cap_unset(uint32_t *caps,
+			enum phm_platform_caps c)
+{
+	caps[c / PHM_MAX_NUM_CAPS_BITS_PER_FIELD] &= ~(1UL << (c & (PHM_MAX_NUM_CAPS_BITS_PER_FIELD - 1)));
+}
+
+static inline bool phm_cap_enabled(const uint32_t *caps, enum phm_platform_caps c)
+{
+	return (0 != (caps[c / PHM_MAX_NUM_CAPS_BITS_PER_FIELD] &
+		  (1UL << (c & (PHM_MAX_NUM_CAPS_BITS_PER_FIELD - 1)))));
+}
+
+#define PP_PCIEGenInvalid  0xffff
+enum PP_PCIEGen {
+    PP_PCIEGen1 = 0,                /* PCIE 1.0 - Transfer rate of 2.5 GT/s */
+    PP_PCIEGen2,                    /*PCIE 2.0 - Transfer rate of 5.0 GT/s */
+    PP_PCIEGen3                     /*PCIE 3.0 - Transfer rate of 8.0 GT/s */
+};
+
+typedef enum PP_PCIEGen PP_PCIEGen;
+
+#define PP_Min_PCIEGen     PP_PCIEGen1
+#define PP_Max_PCIEGen     PP_PCIEGen3
+#define PP_Min_PCIELane    1
+#define PP_Max_PCIELane    32
+
+enum phm_clock_Type {
+	PHM_DispClock = 1,
+	PHM_SClock,
+	PHM_MemClock
+};
+
+#define MAX_NUM_CLOCKS 16
+
+struct PP_Clocks {
+	uint32_t engineClock;
+	uint32_t memoryClock;
+	uint32_t BusBandwidth;
+	uint32_t engineClockInSR;
+};
+
+struct phm_platform_descriptor {
+	uint32_t platformCaps[PHM_MAX_NUM_CAPS_ULONG_ENTRIES];
+	uint32_t vbiosInterruptId;
+	struct PP_Clocks overdriveLimit;
+	struct PP_Clocks clockStep;
+	uint32_t hardwareActivityPerformanceLevels;
+	uint32_t minimumClocksReductionPercentage;
+	uint32_t minOverdriveVDDC;
+	uint32_t maxOverdriveVDDC;
+	uint32_t overdriveVDDCStep;
+	uint32_t hardwarePerformanceLevels;
+	uint16_t powerBudget;
+	uint32_t TDPLimit;
+	uint32_t nearTDPLimit;
+	uint32_t nearTDPLimitAdjusted;
+	uint32_t SQRampingThreshold;
+	uint32_t CACLeakage;
+	uint16_t TDPODLimit;
+	uint32_t TDPAdjustment;
+	bool TDPAdjustmentPolarity;
+	uint16_t LoadLineSlope;
+	uint32_t  VidMinLimit;
+	uint32_t  VidMaxLimit;
+	uint32_t  VidStep;
+	uint32_t  VidAdjustment;
+	bool VidAdjustmentPolarity;
+};
+
+struct phm_clocks {
+	uint32_t num_of_entries;
+	uint32_t clock[MAX_NUM_CLOCKS];
+};
+
+enum PP_DAL_POWERLEVEL {
+	PP_DAL_POWERLEVEL_INVALID = 0,
+	PP_DAL_POWERLEVEL_ULTRALOW,
+	PP_DAL_POWERLEVEL_LOW,
+	PP_DAL_POWERLEVEL_NOMINAL,
+	PP_DAL_POWERLEVEL_PERFORMANCE,
+
+	PP_DAL_POWERLEVEL_0 = PP_DAL_POWERLEVEL_ULTRALOW,
+	PP_DAL_POWERLEVEL_1 = PP_DAL_POWERLEVEL_LOW,
+	PP_DAL_POWERLEVEL_2 = PP_DAL_POWERLEVEL_NOMINAL,
+	PP_DAL_POWERLEVEL_3 = PP_DAL_POWERLEVEL_PERFORMANCE,
+	PP_DAL_POWERLEVEL_4 = PP_DAL_POWERLEVEL_3+1,
+	PP_DAL_POWERLEVEL_5 = PP_DAL_POWERLEVEL_4+1,
+	PP_DAL_POWERLEVEL_6 = PP_DAL_POWERLEVEL_5+1,
+	PP_DAL_POWERLEVEL_7 = PP_DAL_POWERLEVEL_6+1,
+};
+
+
+extern int phm_enable_clock_power_gatings(struct pp_hwmgr *hwmgr);
+extern int phm_powergate_uvd(struct pp_hwmgr *hwmgr, bool gate);
+extern int phm_powergate_vce(struct pp_hwmgr *hwmgr, bool gate);
+extern int phm_powerdown_uvd(struct pp_hwmgr *hwmgr);
+extern int phm_setup_asic(struct pp_hwmgr *hwmgr);
+extern int phm_enable_dynamic_state_management(struct pp_hwmgr *hwmgr);
+extern void phm_init_dynamic_caps(struct pp_hwmgr *hwmgr);
+extern bool phm_is_hw_access_blocked(struct pp_hwmgr *hwmgr);
+extern int phm_block_hw_access(struct pp_hwmgr *hwmgr, bool block);
+extern int phm_set_power_state(struct pp_hwmgr *hwmgr,
+		    const struct pp_hw_power_state *pcurrent_state,
+		 const struct pp_hw_power_state *pnew_power_state);
+
+extern int phm_apply_state_adjust_rules(struct pp_hwmgr *hwmgr,
+				   struct pp_power_state *adjusted_ps,
+			     const struct pp_power_state *current_ps);
+
+extern int phm_force_dpm_levels(struct pp_hwmgr *hwmgr, enum amd_dpm_forced_level level);
+extern int phm_display_configuration_changed(struct pp_hwmgr *hwmgr);
+extern int phm_notify_smc_display_config_after_ps_adjustment(struct pp_hwmgr *hwmgr);
+extern int phm_register_thermal_interrupt(struct pp_hwmgr *hwmgr, const void *info);
+extern int phm_start_thermal_controller(struct pp_hwmgr *hwmgr, struct PP_TemperatureRange *temperature_range);
+extern int phm_stop_thermal_controller(struct pp_hwmgr *hwmgr);
+extern bool phm_check_smc_update_required_for_display_configuration(struct pp_hwmgr *hwmgr);
+
+extern int phm_check_states_equal(struct pp_hwmgr *hwmgr,
+				 const struct pp_hw_power_state *pstate1,
+				 const struct pp_hw_power_state *pstate2,
+				 bool *equal);
+
+extern int phm_store_dal_configuration_data(struct pp_hwmgr *hwmgr,
+		const struct amd_pp_display_configuration *display_config);
+
+extern int phm_get_dal_power_level(struct pp_hwmgr *hwmgr,
+		struct amd_pp_dal_clock_info*info);
+
+extern int phm_set_cpu_power_state(struct pp_hwmgr *hwmgr);
+
+extern int phm_power_down_asic(struct pp_hwmgr *hwmgr);
+
+#endif /* _HARDWARE_MANAGER_H_ */
+
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h
@@ -0,0 +1,802 @@
+/*
+ * Copyright 2015 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+#ifndef _HWMGR_H_
+#define _HWMGR_H_
+
+#include <linux/errno.h>
+#include <linux/seq_file.h>
+#include "amd_powerplay.h"
+#include "pp_instance.h"
+#include "hardwaremanager.h"
+#include "pp_power_source.h"
+#include "hwmgr_ppt.h"
+#include "ppatomctrl.h"
+#include "hwmgr_ppt.h"
+
+struct pp_instance;
+struct pp_hwmgr;
+struct pp_hw_power_state;
+struct pp_power_state;
+struct PP_VCEState;
+struct phm_fan_speed_info;
+struct pp_atomctrl_voltage_table;
+
+
+enum DISPLAY_GAP {
+	DISPLAY_GAP_VBLANK_OR_WM = 0,   /* Wait for vblank or MCHG watermark. */
+	DISPLAY_GAP_VBLANK       = 1,   /* Wait for vblank. */
+	DISPLAY_GAP_WATERMARK    = 2,   /* Wait for MCHG watermark. (Note that HW may deassert WM in VBI depending on DC_STUTTER_CNTL.) */
+	DISPLAY_GAP_IGNORE       = 3    /* Do not wait. */
+};
+typedef enum DISPLAY_GAP DISPLAY_GAP;
+
+
+struct vi_dpm_level {
+	bool enabled;
+	uint32_t value;
+	uint32_t param1;
+};
+
+struct vi_dpm_table {
+	uint32_t count;
+	struct vi_dpm_level dpm_level[1];
+};
+
+enum PP_Result {
+	PP_Result_TableImmediateExit = 0x13,
+};
+
+#define PCIE_PERF_REQ_REMOVE_REGISTRY   0
+#define PCIE_PERF_REQ_FORCE_LOWPOWER    1
+#define PCIE_PERF_REQ_GEN1         2
+#define PCIE_PERF_REQ_GEN2         3
+#define PCIE_PERF_REQ_GEN3         4
+
+enum PHM_BackEnd_Magic {
+	PHM_Dummy_Magic       = 0xAA5555AA,
+	PHM_RV770_Magic       = 0xDCBAABCD,
+	PHM_Kong_Magic        = 0x239478DF,
+	PHM_NIslands_Magic    = 0x736C494E,
+	PHM_Sumo_Magic        = 0x8339FA11,
+	PHM_SIslands_Magic    = 0x369431AC,
+	PHM_Trinity_Magic     = 0x96751873,
+	PHM_CIslands_Magic    = 0x38AC78B0,
+	PHM_Kv_Magic          = 0xDCBBABC0,
+	PHM_VIslands_Magic    = 0x20130307,
+	PHM_Cz_Magic          = 0x67DCBA25
+};
+
+
+#define PHM_PCIE_POWERGATING_TARGET_GFX            0
+#define PHM_PCIE_POWERGATING_TARGET_DDI            1
+#define PHM_PCIE_POWERGATING_TARGET_PLLCASCADE     2
+#define PHM_PCIE_POWERGATING_TARGET_PHY            3
+
+typedef int (*phm_table_function)(struct pp_hwmgr *hwmgr, void *input,
+				  void *output, void *storage, int result);
+
+typedef bool (*phm_check_function)(struct pp_hwmgr *hwmgr);
+
+struct phm_set_power_state_input {
+	const struct pp_hw_power_state *pcurrent_state;
+	const struct pp_hw_power_state *pnew_state;
+};
+
+struct phm_acp_arbiter {
+	uint32_t acpclk;
+};
+
+struct phm_uvd_arbiter {
+	uint32_t vclk;
+	uint32_t dclk;
+	uint32_t vclk_ceiling;
+	uint32_t dclk_ceiling;
+};
+
+struct phm_vce_arbiter {
+	uint32_t   evclk;
+	uint32_t   ecclk;
+};
+
+struct phm_gfx_arbiter {
+	uint32_t sclk;
+	uint32_t mclk;
+	uint32_t sclk_over_drive;
+	uint32_t mclk_over_drive;
+	uint32_t sclk_threshold;
+	uint32_t num_cus;
+};
+
+/* Entries in the master tables */
+struct phm_master_table_item {
+	phm_check_function isFunctionNeededInRuntimeTable;
+	phm_table_function tableFunction;
+};
+
+enum phm_master_table_flag {
+	PHM_MasterTableFlag_None         = 0,
+	PHM_MasterTableFlag_ExitOnError  = 1,
+};
+
+/* The header of the master tables */
+struct phm_master_table_header {
+	uint32_t storage_size;
+	uint32_t flags;
+	struct phm_master_table_item *master_list;
+};
+
+struct phm_runtime_table_header {
+	uint32_t storage_size;
+	bool exit_error;
+	phm_table_function *function_list;
+};
+
+struct phm_clock_array {
+	uint32_t count;
+	uint32_t values[1];
+};
+
+struct phm_clock_voltage_dependency_record {
+	uint32_t clk;
+	uint32_t v;
+};
+
+struct phm_vceclock_voltage_dependency_record {
+	uint32_t ecclk;
+	uint32_t evclk;
+	uint32_t v;
+};
+
+struct phm_uvdclock_voltage_dependency_record {
+	uint32_t vclk;
+	uint32_t dclk;
+	uint32_t v;
+};
+
+struct phm_samuclock_voltage_dependency_record {
+	uint32_t samclk;
+	uint32_t v;
+};
+
+struct phm_acpclock_voltage_dependency_record {
+	uint32_t acpclk;
+	uint32_t v;
+};
+
+struct phm_clock_voltage_dependency_table {
+	uint32_t count;										/* Number of entries. */
+	struct phm_clock_voltage_dependency_record entries[1];		/* Dynamically allocate count entries. */
+};
+
+struct phm_phase_shedding_limits_record {
+	uint32_t  Voltage;
+	uint32_t    Sclk;
+	uint32_t    Mclk;
+};
+
+
+extern int phm_dispatch_table(struct pp_hwmgr *hwmgr,
+			      struct phm_runtime_table_header *rt_table,
+			      void *input, void *output);
+
+extern int phm_construct_table(struct pp_hwmgr *hwmgr,
+			       struct phm_master_table_header *master_table,
+			       struct phm_runtime_table_header *rt_table);
+
+extern int phm_destroy_table(struct pp_hwmgr *hwmgr,
+			     struct phm_runtime_table_header *rt_table);
+
+
+struct phm_uvd_clock_voltage_dependency_record {
+	uint32_t vclk;
+	uint32_t dclk;
+	uint32_t v;
+};
+
+struct phm_uvd_clock_voltage_dependency_table {
+	uint8_t count;
+	struct phm_uvd_clock_voltage_dependency_record entries[1];
+};
+
+struct phm_acp_clock_voltage_dependency_record {
+	uint32_t acpclk;
+	uint32_t v;
+};
+
+struct phm_acp_clock_voltage_dependency_table {
+	uint32_t count;
+	struct phm_acp_clock_voltage_dependency_record entries[1];
+};
+
+struct phm_vce_clock_voltage_dependency_record {
+	uint32_t ecclk;
+	uint32_t evclk;
+	uint32_t v;
+};
+
+struct phm_phase_shedding_limits_table {
+	uint32_t                           count;
+	struct phm_phase_shedding_limits_record  entries[1];
+};
+
+struct phm_vceclock_voltage_dependency_table {
+	uint8_t count;                                    /* Number of entries. */
+	struct phm_vceclock_voltage_dependency_record entries[1]; /* Dynamically allocate count entries. */
+};
+
+struct phm_uvdclock_voltage_dependency_table {
+	uint8_t count;                                    /* Number of entries. */
+	struct phm_uvdclock_voltage_dependency_record entries[1]; /* Dynamically allocate count entries. */
+};
+
+struct phm_samuclock_voltage_dependency_table {
+	uint8_t count;                                    /* Number of entries. */
+	struct phm_samuclock_voltage_dependency_record entries[1]; /* Dynamically allocate count entries. */
+};
+
+struct phm_acpclock_voltage_dependency_table {
+	uint32_t count;                                    /* Number of entries. */
+	struct phm_acpclock_voltage_dependency_record entries[1]; /* Dynamically allocate count entries. */
+};
+
+struct phm_vce_clock_voltage_dependency_table {
+	uint8_t count;
+	struct phm_vce_clock_voltage_dependency_record entries[1];
+};
+
+struct pp_hwmgr_func {
+	int (*backend_init)(struct pp_hwmgr *hw_mgr);
+	int (*backend_fini)(struct pp_hwmgr *hw_mgr);
+	int (*asic_setup)(struct pp_hwmgr *hw_mgr);
+	int (*get_power_state_size)(struct pp_hwmgr *hw_mgr);
+
+	int (*apply_state_adjust_rules)(struct pp_hwmgr *hwmgr,
+				struct pp_power_state  *prequest_ps,
+			const struct pp_power_state *pcurrent_ps);
+
+	int (*force_dpm_level)(struct pp_hwmgr *hw_mgr,
+					enum amd_dpm_forced_level level);
+
+	int (*dynamic_state_management_enable)(
+						struct pp_hwmgr *hw_mgr);
+
+	int (*patch_boot_state)(struct pp_hwmgr *hwmgr,
+				     struct pp_hw_power_state *hw_ps);
+
+	int (*get_pp_table_entry)(struct pp_hwmgr *hwmgr,
+			    unsigned long, struct pp_power_state *);
+	int (*get_num_of_pp_table_entries)(struct pp_hwmgr *hwmgr);
+	int (*powerdown_uvd)(struct pp_hwmgr *hwmgr);
+	int (*powergate_vce)(struct pp_hwmgr *hwmgr, bool bgate);
+	int (*powergate_uvd)(struct pp_hwmgr *hwmgr, bool bgate);
+	int (*get_mclk)(struct pp_hwmgr *hwmgr, bool low);
+	int (*get_sclk)(struct pp_hwmgr *hwmgr, bool low);
+	int (*power_state_set)(struct pp_hwmgr *hwmgr,
+						const void *state);
+	void (*print_current_perforce_level)(struct pp_hwmgr *hwmgr,
+							struct seq_file *m);
+	int (*enable_clock_power_gating)(struct pp_hwmgr *hwmgr);
+	int (*notify_smc_display_config_after_ps_adjustment)(struct pp_hwmgr *hwmgr);
+	int (*display_config_changed)(struct pp_hwmgr *hwmgr);
+	int (*disable_clock_power_gating)(struct pp_hwmgr *hwmgr);
+	int (*update_clock_gatings)(struct pp_hwmgr *hwmgr,
+						const uint32_t *msg_id);
+	int (*set_max_fan_rpm_output)(struct pp_hwmgr *hwmgr, uint16_t us_max_fan_pwm);
+	int (*set_max_fan_pwm_output)(struct pp_hwmgr *hwmgr, uint16_t us_max_fan_pwm);
+	int (*get_temperature)(struct pp_hwmgr *hwmgr);
+	int (*stop_thermal_controller)(struct pp_hwmgr *hwmgr);
+	int (*get_fan_speed_info)(struct pp_hwmgr *hwmgr, struct phm_fan_speed_info *fan_speed_info);
+	int (*set_fan_control_mode)(struct pp_hwmgr *hwmgr, uint32_t mode);
+	int (*get_fan_control_mode)(struct pp_hwmgr *hwmgr);
+	int (*set_fan_speed_percent)(struct pp_hwmgr *hwmgr, uint32_t percent);
+	int (*get_fan_speed_percent)(struct pp_hwmgr *hwmgr, uint32_t *speed);
+	int (*set_fan_speed_rpm)(struct pp_hwmgr *hwmgr, uint32_t percent);
+	int (*get_fan_speed_rpm)(struct pp_hwmgr *hwmgr, uint32_t *speed);
+	int (*reset_fan_speed_to_default)(struct pp_hwmgr *hwmgr);
+	int (*uninitialize_thermal_controller)(struct pp_hwmgr *hwmgr);
+	int (*register_internal_thermal_interrupt)(struct pp_hwmgr *hwmgr,
+					const void *thermal_interrupt_info);
+	bool (*check_smc_update_required_for_display_configuration)(struct pp_hwmgr *hwmgr);
+	int (*check_states_equal)(struct pp_hwmgr *hwmgr,
+					const struct pp_hw_power_state *pstate1,
+					const struct pp_hw_power_state *pstate2,
+					bool *equal);
+	int (*set_cpu_power_state)(struct pp_hwmgr *hwmgr);
+	int (*store_cc6_data)(struct pp_hwmgr *hwmgr, uint32_t separation_time,
+				bool cc6_disable, bool pstate_disable,
+				bool pstate_switch_disable);
+	int (*get_dal_power_level)(struct pp_hwmgr *hwmgr,
+				   struct amd_pp_dal_clock_info *info);
+	int (*power_off_asic)(struct pp_hwmgr *hwmgr);
+};
+
+struct pp_table_func {
+	int (*pptable_init)(struct pp_hwmgr *hw_mgr);
+	int (*pptable_fini)(struct pp_hwmgr *hw_mgr);
+	int (*pptable_get_number_of_vce_state_table_entries)(struct pp_hwmgr *hw_mgr);
+	int (*pptable_get_vce_state_table_entry)(
+						struct pp_hwmgr *hwmgr,
+						unsigned long i,
+						struct PP_VCEState *vce_state,
+						void **clock_info,
+						unsigned long *flag);
+};
+
+union phm_cac_leakage_record {
+	struct {
+		uint16_t Vddc;          /* in CI, we use it for StdVoltageHiSidd */
+		uint32_t Leakage;       /* in CI, we use it for StdVoltageLoSidd */
+	};
+	struct {
+		uint16_t Vddc1;
+		uint16_t Vddc2;
+		uint16_t Vddc3;
+	};
+};
+
+struct phm_cac_leakage_table {
+	uint32_t count;
+	union phm_cac_leakage_record entries[1];
+};
+
+struct phm_samu_clock_voltage_dependency_record {
+	uint32_t samclk;
+	uint32_t v;
+};
+
+
+struct phm_samu_clock_voltage_dependency_table {
+	uint8_t count;
+	struct phm_samu_clock_voltage_dependency_record entries[1];
+};
+
+struct phm_cac_tdp_table {
+	uint16_t usTDP;
+	uint16_t usConfigurableTDP;
+	uint16_t usTDC;
+	uint16_t usBatteryPowerLimit;
+	uint16_t usSmallPowerLimit;
+	uint16_t usLowCACLeakage;
+	uint16_t usHighCACLeakage;
+	uint16_t usMaximumPowerDeliveryLimit;
+	uint16_t usOperatingTempMinLimit;
+	uint16_t usOperatingTempMaxLimit;
+	uint16_t usOperatingTempStep;
+	uint16_t usOperatingTempHyst;
+	uint16_t usDefaultTargetOperatingTemp;
+	uint16_t usTargetOperatingTemp;
+	uint16_t usPowerTuneDataSetID;
+	uint16_t usSoftwareShutdownTemp;
+	uint16_t usClockStretchAmount;
+	uint16_t usTemperatureLimitHotspot;
+	uint16_t usTemperatureLimitLiquid1;
+	uint16_t usTemperatureLimitLiquid2;
+	uint16_t usTemperatureLimitVrVddc;
+	uint16_t usTemperatureLimitVrMvdd;
+	uint16_t usTemperatureLimitPlx;
+	uint8_t  ucLiquid1_I2C_address;
+	uint8_t  ucLiquid2_I2C_address;
+	uint8_t  ucLiquid_I2C_Line;
+	uint8_t  ucVr_I2C_address;
+	uint8_t  ucVr_I2C_Line;
+	uint8_t  ucPlx_I2C_address;
+	uint8_t  ucPlx_I2C_Line;
+};
+
+struct phm_ppm_table {
+	uint8_t   ppm_design;
+	uint16_t  cpu_core_number;
+	uint32_t  platform_tdp;
+	uint32_t  small_ac_platform_tdp;
+	uint32_t  platform_tdc;
+	uint32_t  small_ac_platform_tdc;
+	uint32_t  apu_tdp;
+	uint32_t  dgpu_tdp;
+	uint32_t  dgpu_ulv_power;
+	uint32_t  tj_max;
+};
+
+struct phm_vq_budgeting_record {
+	uint32_t ulCUs;
+	uint32_t ulSustainableSOCPowerLimitLow;
+	uint32_t ulSustainableSOCPowerLimitHigh;
+	uint32_t ulMinSclkLow;
+	uint32_t ulMinSclkHigh;
+	uint8_t  ucDispConfig;
+	uint32_t ulDClk;
+	uint32_t ulEClk;
+	uint32_t ulSustainableSclk;
+	uint32_t ulSustainableCUs;
+};
+
+struct phm_vq_budgeting_table {
+	uint8_t numEntries;
+	struct phm_vq_budgeting_record entries[1];
+};
+
+struct phm_clock_and_voltage_limits {
+	uint32_t sclk;
+	uint32_t mclk;
+	uint16_t vddc;
+	uint16_t vddci;
+	uint16_t vddgfx;
+};
+
+/* Structure to hold PPTable information */
+
+struct phm_ppt_v1_information {
+	struct phm_ppt_v1_clock_voltage_dependency_table *vdd_dep_on_sclk;
+	struct phm_ppt_v1_clock_voltage_dependency_table *vdd_dep_on_mclk;
+	struct phm_clock_array *valid_sclk_values;
+	struct phm_clock_array *valid_mclk_values;
+	struct phm_clock_and_voltage_limits max_clock_voltage_on_dc;
+	struct phm_clock_and_voltage_limits max_clock_voltage_on_ac;
+	struct phm_clock_voltage_dependency_table *vddc_dep_on_dal_pwrl;
+	struct phm_ppm_table *ppm_parameter_table;
+	struct phm_cac_tdp_table *cac_dtp_table;
+	struct phm_ppt_v1_mm_clock_voltage_dependency_table *mm_dep_table;
+	struct phm_ppt_v1_voltage_lookup_table *vddc_lookup_table;
+	struct phm_ppt_v1_voltage_lookup_table *vddgfx_lookup_table;
+	struct phm_ppt_v1_pcie_table *pcie_table;
+	uint16_t us_ulv_voltage_offset;
+};
+
+struct phm_dynamic_state_info {
+	struct phm_clock_voltage_dependency_table *vddc_dependency_on_sclk;
+	struct phm_clock_voltage_dependency_table *vddci_dependency_on_mclk;
+	struct phm_clock_voltage_dependency_table *vddc_dependency_on_mclk;
+	struct phm_clock_voltage_dependency_table *mvdd_dependency_on_mclk;
+	struct phm_clock_voltage_dependency_table *vddc_dep_on_dal_pwrl;
+	struct phm_clock_array                    *valid_sclk_values;
+	struct phm_clock_array                    *valid_mclk_values;
+	struct phm_clock_and_voltage_limits       max_clock_voltage_on_dc;
+	struct phm_clock_and_voltage_limits       max_clock_voltage_on_ac;
+	uint32_t                                  mclk_sclk_ratio;
+	uint32_t                                  sclk_mclk_delta;
+	uint32_t                                  vddc_vddci_delta;
+	uint32_t                                  min_vddc_for_pcie_gen2;
+	struct phm_cac_leakage_table              *cac_leakage_table;
+	struct phm_phase_shedding_limits_table	  *vddc_phase_shed_limits_table;
+
+	struct phm_vce_clock_voltage_dependency_table
+					    *vce_clock_voltage_dependency_table;
+	struct phm_uvd_clock_voltage_dependency_table
+					    *uvd_clock_voltage_dependency_table;
+	struct phm_acp_clock_voltage_dependency_table
+					    *acp_clock_voltage_dependency_table;
+	struct phm_samu_clock_voltage_dependency_table
+					   *samu_clock_voltage_dependency_table;
+
+	struct phm_ppm_table                          *ppm_parameter_table;
+	struct phm_cac_tdp_table                      *cac_dtp_table;
+	struct phm_clock_voltage_dependency_table	  *vdd_gfx_dependency_on_sclk;
+	struct phm_vq_budgeting_table		  		  *vq_budgeting_table;
+};
+
+struct pp_fan_info {
+	bool bNoFan;
+	uint8_t   ucTachometerPulsesPerRevolution;
+	uint32_t   ulMinRPM;
+	uint32_t   ulMaxRPM;
+};
+
+struct pp_advance_fan_control_parameters {
+	uint16_t  usTMin;                          /* The temperature, in 0.01 centigrades, below which we just run at a minimal PWM. */
+	uint16_t  usTMed;                          /* The middle temperature where we change slopes. */
+	uint16_t  usTHigh;                         /* The high temperature for setting the second slope. */
+	uint16_t  usPWMMin;                        /* The minimum PWM value in percent (0.01% increments). */
+	uint16_t  usPWMMed;                        /* The PWM value (in percent) at TMed. */
+	uint16_t  usPWMHigh;                       /* The PWM value at THigh. */
+	uint8_t   ucTHyst;                         /* Temperature hysteresis. Integer. */
+	uint32_t   ulCycleDelay;                   /* The time between two invocations of the fan control routine in microseconds. */
+	uint16_t  usTMax;                          /* The max temperature */
+	uint8_t   ucFanControlMode;
+	uint16_t  usFanPWMMinLimit;
+	uint16_t  usFanPWMMaxLimit;
+	uint16_t  usFanPWMStep;
+	uint16_t  usDefaultMaxFanPWM;
+	uint16_t  usFanOutputSensitivity;
+	uint16_t  usDefaultFanOutputSensitivity;
+	uint16_t  usMaxFanPWM;                     /* The max Fan PWM value for Fuzzy Fan Control feature */
+	uint16_t  usFanRPMMinLimit;                /* Minimum limit range in percentage, need to calculate based on minRPM/MaxRpm */
+	uint16_t  usFanRPMMaxLimit;                /* Maximum limit range in percentage, usually set to 100% by default */
+	uint16_t  usFanRPMStep;                    /* Step increments/decerements, in percent */
+	uint16_t  usDefaultMaxFanRPM;              /* The max Fan RPM value for Fuzzy Fan Control feature, default from PPTable */
+	uint16_t  usMaxFanRPM;                     /* The max Fan RPM value for Fuzzy Fan Control feature, user defined */
+	uint16_t  usFanCurrentLow;                 /* Low current */
+	uint16_t  usFanCurrentHigh;                /* High current */
+	uint16_t  usFanRPMLow;                     /* Low RPM */
+	uint16_t  usFanRPMHigh;                    /* High RPM */
+	uint32_t   ulMinFanSCLKAcousticLimit;      /* Minimum Fan Controller SCLK Frequency Acoustic Limit. */
+	uint8_t   ucTargetTemperature;             /* Advanced fan controller target temperature. */
+	uint8_t   ucMinimumPWMLimit;               /* The minimum PWM that the advanced fan controller can set.  This should be set to the highest PWM that will run the fan at its lowest RPM. */
+	uint16_t  usFanGainEdge;                   /* The following is added for Fiji */
+	uint16_t  usFanGainHotspot;
+	uint16_t  usFanGainLiquid;
+	uint16_t  usFanGainVrVddc;
+	uint16_t  usFanGainVrMvdd;
+	uint16_t  usFanGainPlx;
+	uint16_t  usFanGainHbm;
+};
+
+struct pp_thermal_controller_info {
+	uint8_t ucType;
+	uint8_t ucI2cLine;
+	uint8_t ucI2cAddress;
+	struct pp_fan_info fanInfo;
+	struct pp_advance_fan_control_parameters advanceFanControlParameters;
+};
+
+struct phm_microcode_version_info {
+	uint32_t SMC;
+	uint32_t DMCU;
+	uint32_t MC;
+	uint32_t NB;
+};
+
+/**
+ * The main hardware manager structure.
+ */
+struct pp_hwmgr {
+	uint32_t chip_family;
+	uint32_t chip_id;
+	uint32_t hw_revision;
+	uint32_t sub_sys_id;
+	uint32_t sub_vendor_id;
+
+	void *device;
+	struct pp_smumgr *smumgr;
+	const void *soft_pp_table;
+	bool need_pp_table_upload;
+	enum amd_dpm_forced_level dpm_level;
+	bool block_hw_access;
+	struct phm_gfx_arbiter gfx_arbiter;
+	struct phm_acp_arbiter acp_arbiter;
+	struct phm_uvd_arbiter uvd_arbiter;
+	struct phm_vce_arbiter vce_arbiter;
+	uint32_t usec_timeout;
+	void *pptable;
+	struct phm_platform_descriptor platform_descriptor;
+	void *backend;
+	enum PP_DAL_POWERLEVEL dal_power_level;
+	struct phm_dynamic_state_info dyn_state;
+	struct phm_runtime_table_header setup_asic;
+	struct phm_runtime_table_header power_down_asic;
+	struct phm_runtime_table_header disable_dynamic_state_management;
+	struct phm_runtime_table_header enable_dynamic_state_management;
+	struct phm_runtime_table_header set_power_state;
+	struct phm_runtime_table_header enable_clock_power_gatings;
+	struct phm_runtime_table_header display_configuration_changed;
+	struct phm_runtime_table_header start_thermal_controller;
+	struct phm_runtime_table_header set_temperature_range;
+	const struct pp_hwmgr_func *hwmgr_func;
+	const struct pp_table_func *pptable_func;
+	struct pp_power_state    *ps;
+	enum pp_power_source  power_source;
+	uint32_t num_ps;
+	struct pp_thermal_controller_info thermal_controller;
+	bool fan_ctrl_is_in_default_mode;
+	uint32_t fan_ctrl_default_mode;
+	uint32_t tmin;
+	struct phm_microcode_version_info microcode_version_info;
+	uint32_t ps_size;
+	struct pp_power_state    *current_ps;
+	struct pp_power_state    *request_ps;
+	struct pp_power_state    *boot_ps;
+	struct pp_power_state    *uvd_ps;
+	struct amd_pp_display_configuration display_config;
+};
+
+
+extern int hwmgr_init(struct amd_pp_init *pp_init,
+		      struct pp_instance *handle);
+
+extern int hwmgr_fini(struct pp_hwmgr *hwmgr);
+
+extern int hw_init_power_state_table(struct pp_hwmgr *hwmgr);
+
+extern int phm_wait_on_register(struct pp_hwmgr *hwmgr, uint32_t index,
+				uint32_t value, uint32_t mask);
+
+extern int phm_wait_for_register_unequal(struct pp_hwmgr *hwmgr,
+				uint32_t index, uint32_t value, uint32_t mask);
+
+extern uint32_t phm_read_indirect_register(struct pp_hwmgr *hwmgr,
+		uint32_t indirect_port, uint32_t index);
+
+extern void phm_write_indirect_register(struct pp_hwmgr *hwmgr,
+		uint32_t indirect_port,
+		uint32_t index,
+		uint32_t value);
+
+extern void phm_wait_on_indirect_register(struct pp_hwmgr *hwmgr,
+				uint32_t indirect_port,
+				uint32_t index,
+				uint32_t value,
+				uint32_t mask);
+
+extern void phm_wait_for_indirect_register_unequal(
+				struct pp_hwmgr *hwmgr,
+				uint32_t indirect_port,
+				uint32_t index,
+				uint32_t value,
+				uint32_t mask);
+
+extern bool phm_cf_want_uvd_power_gating(struct pp_hwmgr *hwmgr);
+extern bool phm_cf_want_vce_power_gating(struct pp_hwmgr *hwmgr);
+extern bool phm_cf_want_microcode_fan_ctrl(struct pp_hwmgr *hwmgr);
+
+extern int phm_trim_voltage_table(struct pp_atomctrl_voltage_table *vol_table);
+extern int phm_get_svi2_mvdd_voltage_table(struct pp_atomctrl_voltage_table *vol_table, phm_ppt_v1_clock_voltage_dependency_table *dep_table);
+extern int phm_get_svi2_vddci_voltage_table(struct pp_atomctrl_voltage_table *vol_table, phm_ppt_v1_clock_voltage_dependency_table *dep_table);
+extern int phm_get_svi2_vdd_voltage_table(struct pp_atomctrl_voltage_table *vol_table, phm_ppt_v1_voltage_lookup_table *lookup_table);
+extern void phm_trim_voltage_table_to_fit_state_table(uint32_t max_vol_steps, struct pp_atomctrl_voltage_table *vol_table);
+extern int phm_reset_single_dpm_table(void *table, uint32_t count, int max);
+extern void phm_setup_pcie_table_entry(void *table, uint32_t index, uint32_t pcie_gen, uint32_t pcie_lanes);
+extern int32_t phm_get_dpm_level_enable_mask_value(void *table);
+extern uint8_t phm_get_voltage_index(struct phm_ppt_v1_voltage_lookup_table *lookup_table, uint16_t voltage);
+extern uint16_t phm_find_closest_vddci(struct pp_atomctrl_voltage_table *vddci_table, uint16_t vddci);
+extern int phm_find_boot_level(void *table, uint32_t value, uint32_t *boot_level);
+extern int phm_get_sclk_for_voltage_evv(struct pp_hwmgr *hwmgr, phm_ppt_v1_voltage_lookup_table *lookup_table,
+								uint16_t virtual_voltage_id, int32_t *sclk);
+extern int phm_initializa_dynamic_state_adjustment_rule_settings(struct pp_hwmgr *hwmgr);
+extern int phm_hwmgr_backend_fini(struct pp_hwmgr *hwmgr);
+extern uint32_t phm_get_lowest_enabled_level(struct pp_hwmgr *hwmgr, uint32_t mask);
+
+
+#define PHM_ENTIRE_REGISTER_MASK 0xFFFFFFFFU
+
+#define PHM_FIELD_SHIFT(reg, field) reg##__##field##__SHIFT
+#define PHM_FIELD_MASK(reg, field) reg##__##field##_MASK
+
+#define PHM_SET_FIELD(origval, reg, field, fieldval)	\
+	(((origval) & ~PHM_FIELD_MASK(reg, field)) |	\
+	 (PHM_FIELD_MASK(reg, field) & ((fieldval) << PHM_FIELD_SHIFT(reg, field))))
+
+#define PHM_GET_FIELD(value, reg, field)	\
+	(((value) & PHM_FIELD_MASK(reg, field)) >>	\
+	 PHM_FIELD_SHIFT(reg, field))
+
+
+#define PHM_WAIT_REGISTER_GIVEN_INDEX(hwmgr, index, value, mask)	\
+	phm_wait_on_register(hwmgr, index, value, mask)
+
+#define PHM_WAIT_REGISTER_UNEQUAL_GIVEN_INDEX(hwmgr, index, value, mask)	\
+	phm_wait_for_register_unequal(hwmgr, index, value, mask)
+
+#define PHM_WAIT_INDIRECT_REGISTER_GIVEN_INDEX(hwmgr, port, index, value, mask)	\
+	phm_wait_on_indirect_register(hwmgr, mm##port##_INDEX, index, value, mask)
+
+#define PHM_WAIT_INDIRECT_REGISTER_UNEQUAL_GIVEN_INDEX(hwmgr, port, index, value, mask)	\
+	phm_wait_for_indirect_register_unequal(hwmgr, mm##port##_INDEX, index, value, mask)
+
+#define PHM_WAIT_VFPF_INDIRECT_REGISTER_GIVEN_INDEX(hwmgr, port, index, value, mask)	\
+	phm_wait_on_indirect_register(hwmgr, mm##port##_INDEX_0, index, value, mask)
+
+#define PHM_WAIT_VFPF_INDIRECT_REGISTER_UNEQUAL_GIVEN_INDEX(hwmgr, port, index, value, mask)	\
+	phm_wait_for_indirect_register_unequal(hwmgr, mm##port##_INDEX_0, index, value, mask)
+
+/* Operations on named registers. */
+
+#define PHM_WAIT_REGISTER(hwmgr, reg, value, mask)	\
+	PHM_WAIT_REGISTER_GIVEN_INDEX(hwmgr, mm##reg, value, mask)
+
+#define PHM_WAIT_REGISTER_UNEQUAL(hwmgr, reg, value, mask)	\
+	PHM_WAIT_REGISTER_UNEQUAL_GIVEN_INDEX(hwmgr, mm##reg, value, mask)
+
+#define PHM_WAIT_INDIRECT_REGISTER(hwmgr, port, reg, value, mask)	\
+	PHM_WAIT_INDIRECT_REGISTER_GIVEN_INDEX(hwmgr, port, ix##reg, value, mask)
+
+#define PHM_WAIT_INDIRECT_REGISTER_UNEQUAL(hwmgr, port, reg, value, mask)	\
+	PHM_WAIT_INDIRECT_REGISTER_UNEQUAL_GIVEN_INDEX(hwmgr, port, ix##reg, value, mask)
+
+#define PHM_WAIT_VFPF_INDIRECT_REGISTER(hwmgr, port, reg, value, mask)	\
+	PHM_WAIT_VFPF_INDIRECT_REGISTER_GIVEN_INDEX(hwmgr, port, ix##reg, value, mask)
+
+#define PHM_WAIT_VFPF_INDIRECT_REGISTER_UNEQUAL(hwmgr, port, reg, value, mask)	\
+	PHM_WAIT_VFPF_INDIRECT_REGISTER_UNEQUAL_GIVEN_INDEX(hwmgr, port, ix##reg, value, mask)
+
+/* Operations on named fields. */
+
+#define PHM_READ_FIELD(device, reg, field)	\
+	PHM_GET_FIELD(cgs_read_register(device, mm##reg), reg, field)
+
+#define PHM_READ_INDIRECT_FIELD(device, port, reg, field)	\
+	PHM_GET_FIELD(cgs_read_ind_register(device, port, ix##reg),	\
+			reg, field)
+
+#define PHM_READ_VFPF_INDIRECT_FIELD(device, port, reg, field)	\
+	PHM_GET_FIELD(cgs_read_ind_register(device, port, ix##reg),	\
+			reg, field)
+
+#define PHM_WRITE_FIELD(device, reg, field, fieldval)	\
+	cgs_write_register(device, mm##reg, PHM_SET_FIELD(	\
+				cgs_read_register(device, mm##reg), reg, field, fieldval))
+
+#define PHM_WRITE_INDIRECT_FIELD(device, port, reg, field, fieldval)	\
+	cgs_write_ind_register(device, port, ix##reg,	\
+			PHM_SET_FIELD(cgs_read_ind_register(device, port, ix##reg),	\
+				reg, field, fieldval))
+
+#define PHM_WRITE_VFPF_INDIRECT_FIELD(device, port, reg, field, fieldval)	\
+	cgs_write_ind_register(device, port, ix##reg,	\
+			PHM_SET_FIELD(cgs_read_ind_register(device, port, ix##reg),	\
+				reg, field, fieldval))
+
+#define PHM_WAIT_FIELD(hwmgr, reg, field, fieldval)	\
+	PHM_WAIT_REGISTER(hwmgr, reg, (fieldval)	\
+			<< PHM_FIELD_SHIFT(reg, field), PHM_FIELD_MASK(reg, field))
+
+#define PHM_WAIT_INDIRECT_FIELD(hwmgr, port, reg, field, fieldval)	\
+	PHM_WAIT_INDIRECT_REGISTER(hwmgr, port, reg, (fieldval)	\
+			<< PHM_FIELD_SHIFT(reg, field), PHM_FIELD_MASK(reg, field))
+
+#define PHM_WAIT_VFPF_INDIRECT_FIELD(hwmgr, port, reg, field, fieldval)	\
+	PHM_WAIT_VFPF_INDIRECT_REGISTER(hwmgr, port, reg, (fieldval)	\
+			<< PHM_FIELD_SHIFT(reg, field), PHM_FIELD_MASK(reg, field))
+
+#define PHM_WAIT_FIELD_UNEQUAL(hwmgr, reg, field, fieldval)	\
+	PHM_WAIT_REGISTER_UNEQUAL(hwmgr, reg, (fieldval)	\
+			<< PHM_FIELD_SHIFT(reg, field), PHM_FIELD_MASK(reg, field))
+
+#define PHM_WAIT_INDIRECT_FIELD_UNEQUAL(hwmgr, port, reg, field, fieldval)	\
+	PHM_WAIT_INDIRECT_REGISTER_UNEQUAL(hwmgr, port, reg, (fieldval)	\
+			<< PHM_FIELD_SHIFT(reg, field), PHM_FIELD_MASK(reg, field))
+
+#define PHM_WAIT_VFPF_INDIRECT_FIELD_UNEQUAL(hwmgr, port, reg, field, fieldval)	\
+	PHM_WAIT_VFPF_INDIRECT_REGISTER_UNEQUAL(hwmgr, port, reg, (fieldval)	\
+			<< PHM_FIELD_SHIFT(reg, field), PHM_FIELD_MASK(reg, field))
+
+/* Operations on arrays of registers & fields. */
+
+#define PHM_READ_ARRAY_REGISTER(device, reg, offset)	\
+	cgs_read_register(device, mm##reg + (offset))
+
+#define PHM_WRITE_ARRAY_REGISTER(device, reg, offset, value)	\
+	cgs_write_register(device, mm##reg + (offset), value)
+
+#define PHM_WAIT_ARRAY_REGISTER(hwmgr, reg, offset, value, mask)	\
+	PHM_WAIT_REGISTER_GIVEN_INDEX(hwmgr, mm##reg + (offset), value, mask)
+
+#define PHM_WAIT_ARRAY_REGISTER_UNEQUAL(hwmgr, reg, offset, value, mask)	\
+	PHM_WAIT_REGISTER_UNEQUAL_GIVEN_INDEX(hwmgr, mm##reg + (offset), value, mask)
+
+#define PHM_READ_ARRAY_FIELD(hwmgr, reg, offset, field) \
+	PHM_GET_FIELD(PHM_READ_ARRAY_REGISTER(hwmgr->device, reg, offset), reg, field)
+
+#define PHM_WRITE_ARRAY_FIELD(hwmgr, reg, offset, field, fieldvalue)	\
+	PHM_WRITE_ARRAY_REGISTER(hwmgr->device, reg, offset,	\
+			PHM_SET_FIELD(PHM_READ_ARRAY_REGISTER(hwmgr->device, reg, offset),	\
+				reg, field, fieldvalue))
+
+#define PHM_WAIT_ARRAY_FIELD(hwmgr, reg, offset, field, fieldvalue)	\
+	PHM_WAIT_REGISTER_GIVEN_INDEX(hwmgr, mm##reg + (offset),	\
+			(fieldvalue) << PHM_FIELD_SHIFT(reg, field),	\
+			PHM_FIELD_MASK(reg, field))
+
+#define PHM_WAIT_ARRAY_FIELD_UNEQUAL(hwmgr, reg, offset, field, fieldvalue)	\
+	PHM_WAIT_REGISTER_UNEQUAL_GIVEN_INDEX(hwmgr, mm##reg + (offset),	\
+			(fieldvalue) << PHM_FIELD_SHIFT(reg, field),	\
+			PHM_FIELD_MASK(reg, field))
+
+#endif /* _HWMGR_H_ */
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/powerplay/inc/power_state.h
@@ -0,0 +1,200 @@
+/*
+ * Copyright 2015 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+#ifndef PP_POWERSTATE_H
+#define PP_POWERSTATE_H
+
+struct pp_hw_power_state {
+	unsigned int magic;
+};
+
+struct pp_power_state;
+
+
+#define PP_INVALID_POWER_STATE_ID (0)
+
+
+/*
+ * An item of a list containing Power States.
+ */
+
+struct PP_StateLinkedList {
+	struct pp_power_state *next;
+	struct pp_power_state *prev;
+};
+
+
+enum PP_StateUILabel {
+	PP_StateUILabel_None,
+	PP_StateUILabel_Battery,
+	PP_StateUILabel_MiddleLow,
+	PP_StateUILabel_Balanced,
+	PP_StateUILabel_MiddleHigh,
+	PP_StateUILabel_Performance,
+	PP_StateUILabel_BACO
+};
+
+enum PP_StateClassificationFlag {
+	PP_StateClassificationFlag_Boot                = 0x0001,
+	PP_StateClassificationFlag_Thermal             = 0x0002,
+	PP_StateClassificationFlag_LimitedPowerSource  = 0x0004,
+	PP_StateClassificationFlag_Rest                = 0x0008,
+	PP_StateClassificationFlag_Forced              = 0x0010,
+	PP_StateClassificationFlag_User3DPerformance   = 0x0020,
+	PP_StateClassificationFlag_User2DPerformance   = 0x0040,
+	PP_StateClassificationFlag_3DPerformance       = 0x0080,
+	PP_StateClassificationFlag_ACOverdriveTemplate   = 0x0100,
+	PP_StateClassificationFlag_Uvd                 = 0x0200,
+	PP_StateClassificationFlag_3DPerformanceLow    = 0x0400,
+	PP_StateClassificationFlag_ACPI                = 0x0800,
+	PP_StateClassificationFlag_HD2                 = 0x1000,
+	PP_StateClassificationFlag_UvdHD               = 0x2000,
+	PP_StateClassificationFlag_UvdSD               = 0x4000,
+	PP_StateClassificationFlag_UserDCPerformance    = 0x8000,
+	PP_StateClassificationFlag_DCOverdriveTemplate   = 0x10000,
+	PP_StateClassificationFlag_BACO                  = 0x20000,
+	PP_StateClassificationFlag_LimitedPowerSource_2  = 0x40000,
+	PP_StateClassificationFlag_ULV                   = 0x80000,
+	PP_StateClassificationFlag_UvdMVC               = 0x100000,
+};
+
+typedef unsigned int PP_StateClassificationFlags;
+
+struct PP_StateClassificationBlock {
+	enum PP_StateUILabel         ui_label;
+	enum PP_StateClassificationFlag  flags;
+	int                          bios_index;
+	bool                      temporary_state;
+	bool                      to_be_deleted;
+};
+
+struct PP_StatePcieBlock {
+	unsigned int lanes;
+};
+
+enum PP_RefreshrateSource {
+	PP_RefreshrateSource_EDID,
+	PP_RefreshrateSource_Explicit
+};
+
+struct PP_StateDisplayBlock {
+	bool              disableFrameModulation;
+	bool              limitRefreshrate;
+	enum PP_RefreshrateSource refreshrateSource;
+	int                  explicitRefreshrate;
+	int                  edidRefreshrateIndex;
+	bool              enableVariBright;
+};
+
+struct PP_StateMemroyBlock {
+	bool              dllOff;
+	uint8_t                 m3arb;
+	uint8_t                 unused[3];
+};
+
+struct PP_StateSoftwareAlgorithmBlock {
+	bool disableLoadBalancing;
+	bool enableSleepForTimestamps;
+};
+
+#define PP_TEMPERATURE_UNITS_PER_CENTIGRADES 1000
+
+/**
+ * Type to hold a temperature range.
+ */
+struct PP_TemperatureRange {
+	uint32_t min;
+	uint32_t max;
+};
+
+struct PP_StateValidationBlock {
+	bool singleDisplayOnly;
+	bool disallowOnDC;
+	uint8_t supportedPowerLevels;
+};
+
+struct PP_UVD_CLOCKS {
+	uint32_t VCLK;
+	uint32_t DCLK;
+};
+
+/**
+* Structure to hold a PowerPlay Power State.
+*/
+struct pp_power_state {
+	uint32_t                            id;
+	struct PP_StateLinkedList                  orderedList;
+	struct PP_StateLinkedList                  allStatesList;
+
+	struct PP_StateClassificationBlock         classification;
+	struct PP_StateValidationBlock             validation;
+	struct PP_StatePcieBlock                   pcie;
+	struct PP_StateDisplayBlock                display;
+	struct PP_StateMemroyBlock                 memory;
+	struct PP_TemperatureRange                 temperatures;
+	struct PP_StateSoftwareAlgorithmBlock      software;
+	struct PP_UVD_CLOCKS                       uvd_clocks;
+	struct pp_hw_power_state  hardware;
+};
+
+
+/*Structure to hold a VCE state entry*/
+struct PP_VCEState {
+	uint32_t evclk;
+	uint32_t ecclk;
+	uint32_t sclk;
+	uint32_t mclk;
+};
+
+enum PP_MMProfilingState {
+	PP_MMProfilingState_NA = 0,
+	PP_MMProfilingState_Started,
+	PP_MMProfilingState_Stopped
+};
+
+struct PP_Clock_Engine_Request {
+	unsigned long clientType;
+	unsigned long ctxid;
+	uint64_t  context_handle;
+	unsigned long sclk;
+	unsigned long sclkHardMin;
+	unsigned long mclk;
+	unsigned long iclk;
+	unsigned long evclk;
+	unsigned long ecclk;
+	unsigned long ecclkHardMin;
+	unsigned long vclk;
+	unsigned long dclk;
+	unsigned long samclk;
+	unsigned long acpclk;
+	unsigned long sclkOverdrive;
+	unsigned long mclkOverdrive;
+	unsigned long sclk_threshold;
+	unsigned long flag;
+	unsigned long vclk_ceiling;
+	unsigned long dclk_ceiling;
+	unsigned long num_cus;
+	unsigned long pmflag;
+	enum PP_MMProfilingState MMProfilingState;
+};
+
+#endif
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/powerplay/inc/pp_acpi.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2015 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+extern bool acpi_atcs_functions_supported(void *device,
+							uint32_t index);
+extern int acpi_pcie_perf_request(void *device,
+						uint8_t perf_req,
+						bool advertise);
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/powerplay/inc/pp_asicblocks.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2015 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+#ifndef PP_ASICBLOCKS_H
+#define PP_ASICBLOCKS_H
+
+
+enum PHM_AsicBlock {
+	PHM_AsicBlock_GFX,
+	PHM_AsicBlock_UVD_MVC,
+	PHM_AsicBlock_UVD,
+	PHM_AsicBlock_UVD_HD,
+	PHM_AsicBlock_UVD_SD,
+	PHM_AsicBlock_Count
+};
+
+enum PHM_ClockGateSetting {
+	PHM_ClockGateSetting_StaticOn,
+	PHM_ClockGateSetting_StaticOff,
+	PHM_ClockGateSetting_Dynamic
+};
+
+struct phm_asic_blocks {
+	bool gfx : 1;
+	bool uvd : 1;
+};
+
+#endif
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/powerplay/inc/pp_debug.h
@@ -0,0 +1,47 @@
+
+/*
+ * Copyright 2015 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+#ifndef PP_DEBUG_H
+#define PP_DEBUG_H
+
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+
+#define PP_ASSERT_WITH_CODE(cond, msg, code)	\
+	do {					\
+		if (!(cond)) {			\
+			printk("%s\n", msg);	\
+			code;			\
+		}				\
+	} while (0)
+
+
+#define PP_DBG_LOG(fmt, ...) \
+	do { \
+		if(0)printk(KERN_INFO "[ pp_dbg ] " fmt, ##__VA_ARGS__); \
+	} while (0)
+
+
+#endif /* PP_DEBUG_H */
+
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/powerplay/inc/pp_feature.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2015 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#ifndef _PP_FEATURE_H_
+#define _PP_FEATURE_H_
+
+/**
+ * PowerPlay feature ids.
+ */
+enum pp_feature {
+	PP_Feature_PowerPlay = 0,
+	PP_Feature_User2DPerformance,
+	PP_Feature_User3DPerformance,
+	PP_Feature_VariBright,
+	PP_Feature_VariBrightOnPowerXpress,
+	PP_Feature_ReducedRefreshRate,
+	PP_Feature_GFXClockGating,
+	PP_Feature_OverdriveTest,
+	PP_Feature_OverDrive,
+	PP_Feature_PowerBudgetWaiver,
+	PP_Feature_PowerControl,
+	PP_Feature_PowerControl_2,
+	PP_Feature_MultiUVDState,
+	PP_Feature_Force3DClock,
+	PP_Feature_BACO,
+	PP_Feature_PowerDown,
+	PP_Feature_DynamicUVDState,
+	PP_Feature_VCEDPM,
+	PP_Feature_PPM,
+	PP_Feature_ACP_POWERGATING,
+	PP_Feature_FFC,
+	PP_Feature_FPS,
+	PP_Feature_ViPG,
+	PP_Feature_Max
+};
+
+/**
+ * Struct for PowerPlay feature info.
+ */
+struct pp_feature_info {
+	bool supported;               /* feature supported by PowerPlay */
+	bool enabled;                 /* feature enabled in PowerPlay */
+	bool enabled_default;        /* default enable status of the feature */
+	uint32_t version;             /* feature version */
+};
+
+#endif /* _PP_FEATURE_H_ */
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/powerplay/inc/pp_instance.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2015 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+#ifndef _PP_INSTANCE_H_
+#define _PP_INSTANCE_H_
+
+#include "smumgr.h"
+#include "hwmgr.h"
+#include "eventmgr.h"
+
+#define PP_VALID  0x1F1F1F1F
+
+struct pp_instance {
+	uint32_t pp_valid;
+	struct pp_smumgr *smu_mgr;
+	struct pp_hwmgr *hwmgr;
+	struct pp_eventmgr *eventmgr;
+};
+
+#endif
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/powerplay/inc/pp_power_source.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2015 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#ifndef PP_POWERSOURCE_H
+#define PP_POWERSOURCE_H
+
+enum pp_power_source {
+	PP_PowerSource_AC = 0,
+	PP_PowerSource_DC,
+	PP_PowerSource_LimitedPower,
+	PP_PowerSource_LimitedPower_2,
+	PP_PowerSource_Max
+};
+
+
+#endif
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/powerplay/inc/ppinterrupt.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2015 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#ifndef _PP_INTERRUPT_H_
+#define _PP_INTERRUPT_H_
+
+enum amd_thermal_irq {
+	AMD_THERMAL_IRQ_LOW_TO_HIGH = 0,
+	AMD_THERMAL_IRQ_HIGH_TO_LOW,
+
+	AMD_THERMAL_IRQ_LAST
+};
+
+/* The type of the interrupt callback functions in PowerPlay */
+typedef int (*irq_handler_func_t)(void *private_data,
+				unsigned src_id, const uint32_t *iv_entry);
+
+/* Event Manager action chain list information */
+struct pp_interrupt_registration_info {
+	irq_handler_func_t call_back; /* Pointer to callback function */
+	void *context;                   /* Pointer to callback function context */
+	uint32_t src_id;               /* Registered interrupt id */
+	const uint32_t *iv_entry;
+};
+
+#endif /* _PP_INTERRUPT_H_ */
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/powerplay/inc/smu7.h
@@ -0,0 +1,170 @@
+/*
+ * Copyright 2013 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#ifndef SMU7_H
+#define SMU7_H
+
+#pragma pack(push, 1)
+
+#define SMU7_CONTEXT_ID_SMC        1
+#define SMU7_CONTEXT_ID_VBIOS      2
+
+
+#define SMU7_CONTEXT_ID_SMC        1
+#define SMU7_CONTEXT_ID_VBIOS      2
+
+#define SMU7_MAX_LEVELS_VDDC            8
+#define SMU7_MAX_LEVELS_VDDCI           4
+#define SMU7_MAX_LEVELS_MVDD            4
+#define SMU7_MAX_LEVELS_VDDNB           8
+
+#define SMU7_MAX_LEVELS_GRAPHICS        SMU__NUM_SCLK_DPM_STATE   // SCLK + SQ DPM + ULV
+#define SMU7_MAX_LEVELS_MEMORY          SMU__NUM_MCLK_DPM_LEVELS   // MCLK Levels DPM
+#define SMU7_MAX_LEVELS_GIO             SMU__NUM_LCLK_DPM_LEVELS  // LCLK Levels
+#define SMU7_MAX_LEVELS_LINK            SMU__NUM_PCIE_DPM_LEVELS  // PCIe speed and number of lanes.
+#define SMU7_MAX_LEVELS_UVD             8   // VCLK/DCLK levels for UVD.
+#define SMU7_MAX_LEVELS_VCE             8   // ECLK levels for VCE.
+#define SMU7_MAX_LEVELS_ACP             8   // ACLK levels for ACP.
+#define SMU7_MAX_LEVELS_SAMU            8   // SAMCLK levels for SAMU.
+#define SMU7_MAX_ENTRIES_SMIO           32  // Number of entries in SMIO table.
+
+#define DPM_NO_LIMIT 0
+#define DPM_NO_UP 1
+#define DPM_GO_DOWN 2
+#define DPM_GO_UP 3
+
+#define SMU7_FIRST_DPM_GRAPHICS_LEVEL    0
+#define SMU7_FIRST_DPM_MEMORY_LEVEL      0
+
+#define GPIO_CLAMP_MODE_VRHOT      1
+#define GPIO_CLAMP_MODE_THERM      2
+#define GPIO_CLAMP_MODE_DC         4
+
+#define SCRATCH_B_TARG_PCIE_INDEX_SHIFT 0
+#define SCRATCH_B_TARG_PCIE_INDEX_MASK  (0x7<<SCRATCH_B_TARG_PCIE_INDEX_SHIFT)
+#define SCRATCH_B_CURR_PCIE_INDEX_SHIFT 3
+#define SCRATCH_B_CURR_PCIE_INDEX_MASK  (0x7<<SCRATCH_B_CURR_PCIE_INDEX_SHIFT)
+#define SCRATCH_B_TARG_UVD_INDEX_SHIFT  6
+#define SCRATCH_B_TARG_UVD_INDEX_MASK   (0x7<<SCRATCH_B_TARG_UVD_INDEX_SHIFT)
+#define SCRATCH_B_CURR_UVD_INDEX_SHIFT  9
+#define SCRATCH_B_CURR_UVD_INDEX_MASK   (0x7<<SCRATCH_B_CURR_UVD_INDEX_SHIFT)
+#define SCRATCH_B_TARG_VCE_INDEX_SHIFT  12
+#define SCRATCH_B_TARG_VCE_INDEX_MASK   (0x7<<SCRATCH_B_TARG_VCE_INDEX_SHIFT)
+#define SCRATCH_B_CURR_VCE_INDEX_SHIFT  15
+#define SCRATCH_B_CURR_VCE_INDEX_MASK   (0x7<<SCRATCH_B_CURR_VCE_INDEX_SHIFT)
+#define SCRATCH_B_TARG_ACP_INDEX_SHIFT  18
+#define SCRATCH_B_TARG_ACP_INDEX_MASK   (0x7<<SCRATCH_B_TARG_ACP_INDEX_SHIFT)
+#define SCRATCH_B_CURR_ACP_INDEX_SHIFT  21
+#define SCRATCH_B_CURR_ACP_INDEX_MASK   (0x7<<SCRATCH_B_CURR_ACP_INDEX_SHIFT)
+#define SCRATCH_B_TARG_SAMU_INDEX_SHIFT 24
+#define SCRATCH_B_TARG_SAMU_INDEX_MASK  (0x7<<SCRATCH_B_TARG_SAMU_INDEX_SHIFT)
+#define SCRATCH_B_CURR_SAMU_INDEX_SHIFT 27
+#define SCRATCH_B_CURR_SAMU_INDEX_MASK  (0x7<<SCRATCH_B_CURR_SAMU_INDEX_SHIFT)
+
+
+struct SMU7_PIDController
+{
+    uint32_t Ki;
+    int32_t LFWindupUL;
+    int32_t LFWindupLL;
+    uint32_t StatePrecision;
+    uint32_t LfPrecision;
+    uint32_t LfOffset;
+    uint32_t MaxState;
+    uint32_t MaxLfFraction;
+    uint32_t StateShift;
+};
+
+typedef struct SMU7_PIDController SMU7_PIDController;
+
+// -------------------------------------------------------------------------------------------------------------------------
+#define SMU7_MAX_PCIE_LINK_SPEEDS 3 /* 0:Gen1 1:Gen2 2:Gen3 */
+
+#define SMU7_SCLK_DPM_CONFIG_MASK                        0x01
+#define SMU7_VOLTAGE_CONTROLLER_CONFIG_MASK              0x02
+#define SMU7_THERMAL_CONTROLLER_CONFIG_MASK              0x04
+#define SMU7_MCLK_DPM_CONFIG_MASK                        0x08
+#define SMU7_UVD_DPM_CONFIG_MASK                         0x10
+#define SMU7_VCE_DPM_CONFIG_MASK                         0x20
+#define SMU7_ACP_DPM_CONFIG_MASK                         0x40
+#define SMU7_SAMU_DPM_CONFIG_MASK                        0x80
+#define SMU7_PCIEGEN_DPM_CONFIG_MASK                    0x100
+
+#define SMU7_ACP_MCLK_HANDSHAKE_DISABLE                  0x00000001
+#define SMU7_ACP_SCLK_HANDSHAKE_DISABLE                  0x00000002
+#define SMU7_UVD_MCLK_HANDSHAKE_DISABLE                  0x00000100
+#define SMU7_UVD_SCLK_HANDSHAKE_DISABLE                  0x00000200
+#define SMU7_VCE_MCLK_HANDSHAKE_DISABLE                  0x00010000
+#define SMU7_VCE_SCLK_HANDSHAKE_DISABLE                  0x00020000
+
+struct SMU7_Firmware_Header
+{
+    uint32_t Digest[5];
+    uint32_t Version;
+    uint32_t HeaderSize;
+    uint32_t Flags;
+    uint32_t EntryPoint;
+    uint32_t CodeSize;
+    uint32_t ImageSize;
+
+    uint32_t Rtos;
+    uint32_t SoftRegisters;
+    uint32_t DpmTable;
+    uint32_t FanTable;
+    uint32_t CacConfigTable;
+    uint32_t CacStatusTable;
+
+    uint32_t mcRegisterTable;
+
+    uint32_t mcArbDramTimingTable;
+
+    uint32_t PmFuseTable;
+    uint32_t Globals;
+    uint32_t Reserved[42];
+    uint32_t Signature;
+};
+
+typedef struct SMU7_Firmware_Header SMU7_Firmware_Header;
+
+#define SMU7_FIRMWARE_HEADER_LOCATION 0x20000
+
+enum  DisplayConfig {
+    PowerDown = 1,
+    DP54x4,
+    DP54x2,
+    DP54x1,
+    DP27x4,
+    DP27x2,
+    DP27x1,
+    HDMI297,
+    HDMI162,
+    LVDS,
+    DP324x4,
+    DP324x2,
+    DP324x1
+};
+
+#pragma pack(pop)
+
+#endif
+
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/powerplay/inc/smu72.h
@@ -0,0 +1,664 @@
+#ifndef SMU72_H
+#define SMU72_H
+
+#if !defined(SMC_MICROCODE)
+#pragma pack(push, 1)
+#endif
+
+#define SMU__NUM_SCLK_DPM_STATE  8
+#define SMU__NUM_MCLK_DPM_LEVELS 4
+#define SMU__NUM_LCLK_DPM_LEVELS 8
+#define SMU__NUM_PCIE_DPM_LEVELS 8
+
+enum SID_OPTION {
+	SID_OPTION_HI,
+	SID_OPTION_LO,
+	SID_OPTION_COUNT
+};
+
+enum Poly3rdOrderCoeff {
+	LEAKAGE_TEMPERATURE_SCALAR,
+	LEAKAGE_VOLTAGE_SCALAR,
+	DYNAMIC_VOLTAGE_SCALAR,
+	POLY_3RD_ORDER_COUNT
+};
+
+struct SMU7_Poly3rdOrder_Data {
+	int32_t a;
+	int32_t b;
+	int32_t c;
+	int32_t d;
+	uint8_t a_shift;
+	uint8_t b_shift;
+	uint8_t c_shift;
+	uint8_t x_shift;
+};
+
+typedef struct SMU7_Poly3rdOrder_Data SMU7_Poly3rdOrder_Data;
+
+struct Power_Calculator_Data {
+	uint16_t NoLoadVoltage;
+	uint16_t LoadVoltage;
+	uint16_t Resistance;
+	uint16_t Temperature;
+	uint16_t BaseLeakage;
+	uint16_t LkgTempScalar;
+	uint16_t LkgVoltScalar;
+	uint16_t LkgAreaScalar;
+	uint16_t LkgPower;
+	uint16_t DynVoltScalar;
+	uint32_t Cac;
+	uint32_t DynPower;
+	uint32_t TotalCurrent;
+	uint32_t TotalPower;
+};
+
+typedef struct Power_Calculator_Data PowerCalculatorData_t;
+
+struct Gc_Cac_Weight_Data {
+	uint8_t index;
+	uint32_t value;
+};
+
+typedef struct Gc_Cac_Weight_Data GcCacWeight_Data;
+
+
+typedef struct {
+	uint32_t high;
+	uint32_t low;
+} data_64_t;
+
+typedef struct {
+	data_64_t high;
+	data_64_t low;
+} data_128_t;
+
+#define SMU7_CONTEXT_ID_SMC        1
+#define SMU7_CONTEXT_ID_VBIOS      2
+
+#define SMU72_MAX_LEVELS_VDDC            16
+#define SMU72_MAX_LEVELS_VDDGFX          16
+#define SMU72_MAX_LEVELS_VDDCI           8
+#define SMU72_MAX_LEVELS_MVDD            4
+
+#define SMU_MAX_SMIO_LEVELS              4
+
+#define SMU72_MAX_LEVELS_GRAPHICS        SMU__NUM_SCLK_DPM_STATE   /* SCLK + SQ DPM + ULV */
+#define SMU72_MAX_LEVELS_MEMORY          SMU__NUM_MCLK_DPM_LEVELS   /* MCLK Levels DPM */
+#define SMU72_MAX_LEVELS_GIO             SMU__NUM_LCLK_DPM_LEVELS  /* LCLK Levels */
+#define SMU72_MAX_LEVELS_LINK            SMU__NUM_PCIE_DPM_LEVELS  /* PCIe speed and number of lanes. */
+#define SMU72_MAX_LEVELS_UVD             8   /* VCLK/DCLK levels for UVD. */
+#define SMU72_MAX_LEVELS_VCE             8   /* ECLK levels for VCE. */
+#define SMU72_MAX_LEVELS_ACP             8   /* ACLK levels for ACP. */
+#define SMU72_MAX_LEVELS_SAMU            8   /* SAMCLK levels for SAMU. */
+#define SMU72_MAX_ENTRIES_SMIO           32  /* Number of entries in SMIO table. */
+
+#define DPM_NO_LIMIT 0
+#define DPM_NO_UP 1
+#define DPM_GO_DOWN 2
+#define DPM_GO_UP 3
+
+#define SMU7_FIRST_DPM_GRAPHICS_LEVEL    0
+#define SMU7_FIRST_DPM_MEMORY_LEVEL      0
+
+#define GPIO_CLAMP_MODE_VRHOT      1
+#define GPIO_CLAMP_MODE_THERM      2
+#define GPIO_CLAMP_MODE_DC         4
+
+#define SCRATCH_B_TARG_PCIE_INDEX_SHIFT 0
+#define SCRATCH_B_TARG_PCIE_INDEX_MASK  (0x7<<SCRATCH_B_TARG_PCIE_INDEX_SHIFT)
+#define SCRATCH_B_CURR_PCIE_INDEX_SHIFT 3
+#define SCRATCH_B_CURR_PCIE_INDEX_MASK  (0x7<<SCRATCH_B_CURR_PCIE_INDEX_SHIFT)
+#define SCRATCH_B_TARG_UVD_INDEX_SHIFT  6
+#define SCRATCH_B_TARG_UVD_INDEX_MASK   (0x7<<SCRATCH_B_TARG_UVD_INDEX_SHIFT)
+#define SCRATCH_B_CURR_UVD_INDEX_SHIFT  9
+#define SCRATCH_B_CURR_UVD_INDEX_MASK   (0x7<<SCRATCH_B_CURR_UVD_INDEX_SHIFT)
+#define SCRATCH_B_TARG_VCE_INDEX_SHIFT  12
+#define SCRATCH_B_TARG_VCE_INDEX_MASK   (0x7<<SCRATCH_B_TARG_VCE_INDEX_SHIFT)
+#define SCRATCH_B_CURR_VCE_INDEX_SHIFT  15
+#define SCRATCH_B_CURR_VCE_INDEX_MASK   (0x7<<SCRATCH_B_CURR_VCE_INDEX_SHIFT)
+#define SCRATCH_B_TARG_ACP_INDEX_SHIFT  18
+#define SCRATCH_B_TARG_ACP_INDEX_MASK   (0x7<<SCRATCH_B_TARG_ACP_INDEX_SHIFT)
+#define SCRATCH_B_CURR_ACP_INDEX_SHIFT  21
+#define SCRATCH_B_CURR_ACP_INDEX_MASK   (0x7<<SCRATCH_B_CURR_ACP_INDEX_SHIFT)
+#define SCRATCH_B_TARG_SAMU_INDEX_SHIFT 24
+#define SCRATCH_B_TARG_SAMU_INDEX_MASK  (0x7<<SCRATCH_B_TARG_SAMU_INDEX_SHIFT)
+#define SCRATCH_B_CURR_SAMU_INDEX_SHIFT 27
+#define SCRATCH_B_CURR_SAMU_INDEX_MASK  (0x7<<SCRATCH_B_CURR_SAMU_INDEX_SHIFT)
+
+/* Virtualization Defines */
+#define CG_XDMA_MASK  0x1
+#define CG_XDMA_SHIFT 0
+#define CG_UVD_MASK   0x2
+#define CG_UVD_SHIFT  1
+#define CG_VCE_MASK   0x4
+#define CG_VCE_SHIFT  2
+#define CG_SAMU_MASK  0x8
+#define CG_SAMU_SHIFT 3
+#define CG_GFX_MASK   0x10
+#define CG_GFX_SHIFT  4
+#define CG_SDMA_MASK  0x20
+#define CG_SDMA_SHIFT 5
+#define CG_HDP_MASK   0x40
+#define CG_HDP_SHIFT  6
+#define CG_MC_MASK    0x80
+#define CG_MC_SHIFT   7
+#define CG_DRM_MASK   0x100
+#define CG_DRM_SHIFT  8
+#define CG_ROM_MASK   0x200
+#define CG_ROM_SHIFT  9
+#define CG_BIF_MASK   0x400
+#define CG_BIF_SHIFT  10
+
+#define SMU72_DTE_ITERATIONS 5
+#define SMU72_DTE_SOURCES 3
+#define SMU72_DTE_SINKS 1
+#define SMU72_NUM_CPU_TES 0
+#define SMU72_NUM_GPU_TES 1
+#define SMU72_NUM_NON_TES 2
+#define SMU72_DTE_FAN_SCALAR_MIN 0x100
+#define SMU72_DTE_FAN_SCALAR_MAX 0x166
+#define SMU72_DTE_FAN_TEMP_MAX 93
+#define SMU72_DTE_FAN_TEMP_MIN 83
+
+#if defined SMU__FUSION_ONLY
+#define SMU7_DTE_ITERATIONS 5
+#define SMU7_DTE_SOURCES 5
+#define SMU7_DTE_SINKS 3
+#define SMU7_NUM_CPU_TES 2
+#define SMU7_NUM_GPU_TES 1
+#define SMU7_NUM_NON_TES 2
+#endif
+
+struct SMU7_HystController_Data {
+	uint8_t waterfall_up;
+	uint8_t waterfall_down;
+	uint8_t waterfall_limit;
+	uint8_t spare;
+	uint16_t release_cnt;
+	uint16_t release_limit;
+};
+
+typedef struct SMU7_HystController_Data SMU7_HystController_Data;
+
+struct SMU72_PIDController {
+	uint32_t Ki;
+	int32_t LFWindupUpperLim;
+	int32_t LFWindupLowerLim;
+	uint32_t StatePrecision;
+	uint32_t LfPrecision;
+	uint32_t LfOffset;
+	uint32_t MaxState;
+	uint32_t MaxLfFraction;
+	uint32_t StateShift;
+};
+
+typedef struct SMU72_PIDController SMU72_PIDController;
+
+struct SMU7_LocalDpmScoreboard {
+	uint32_t PercentageBusy;
+
+	int32_t  PIDError;
+	int32_t  PIDIntegral;
+	int32_t  PIDOutput;
+
+	uint32_t SigmaDeltaAccum;
+	uint32_t SigmaDeltaOutput;
+	uint32_t SigmaDeltaLevel;
+
+	uint32_t UtilizationSetpoint;
+
+	uint8_t  TdpClampMode;
+	uint8_t  TdcClampMode;
+	uint8_t  ThermClampMode;
+	uint8_t  VoltageBusy;
+
+	int8_t   CurrLevel;
+	int8_t   TargLevel;
+	uint8_t  LevelChangeInProgress;
+	uint8_t  UpHyst;
+
+	uint8_t  DownHyst;
+	uint8_t  VoltageDownHyst;
+	uint8_t  DpmEnable;
+	uint8_t  DpmRunning;
+
+	uint8_t  DpmForce;
+	uint8_t  DpmForceLevel;
+	uint8_t  DisplayWatermark;
+	uint8_t  McArbIndex;
+
+	uint32_t MinimumPerfSclk;
+
+	uint8_t  AcpiReq;
+	uint8_t  AcpiAck;
+	uint8_t  GfxClkSlow;
+	uint8_t  GpioClampMode; /* bit0 = VRHOT: bit1 = THERM: bit2 = DC */
+
+	uint8_t  FpsFilterWeight;
+	uint8_t  EnabledLevelsChange;
+	uint8_t  DteClampMode;
+	uint8_t  FpsClampMode;
+
+	uint16_t LevelResidencyCounters[SMU72_MAX_LEVELS_GRAPHICS];
+	uint16_t LevelSwitchCounters[SMU72_MAX_LEVELS_GRAPHICS];
+
+	void     (*TargetStateCalculator)(uint8_t);
+	void     (*SavedTargetStateCalculator)(uint8_t);
+
+	uint16_t AutoDpmInterval;
+	uint16_t AutoDpmRange;
+
+	uint8_t  FpsEnabled;
+	uint8_t  MaxPerfLevel;
+	uint8_t  AllowLowClkInterruptToHost;
+	uint8_t  FpsRunning;
+
+	uint32_t MaxAllowedFrequency;
+
+	uint32_t FilteredSclkFrequency;
+	uint32_t LastSclkFrequency;
+	uint32_t FilteredSclkFrequencyCnt;
+};
+
+typedef struct SMU7_LocalDpmScoreboard SMU7_LocalDpmScoreboard;
+
+#define SMU7_MAX_VOLTAGE_CLIENTS 12
+
+typedef uint8_t (*VoltageChangeHandler_t)(uint16_t, uint8_t);
+
+struct SMU_VoltageLevel {
+	uint8_t Vddc;
+	uint8_t Vddci;
+	uint8_t VddGfx;
+	uint8_t Phases;
+};
+
+typedef struct SMU_VoltageLevel SMU_VoltageLevel;
+
+struct SMU7_VoltageScoreboard {
+	SMU_VoltageLevel CurrentVoltage;
+	SMU_VoltageLevel TargetVoltage;
+	uint16_t MaxVid;
+	uint8_t  HighestVidOffset;
+	uint8_t  CurrentVidOffset;
+
+	uint8_t  ControllerBusy;
+	uint8_t  CurrentVid;
+	uint8_t  CurrentVddciVid;
+	uint8_t  VddGfxShutdown; /* 0 = normal mode, 1 = shut down */
+
+	SMU_VoltageLevel RequestedVoltage[SMU7_MAX_VOLTAGE_CLIENTS];
+	uint8_t  EnabledRequest[SMU7_MAX_VOLTAGE_CLIENTS];
+
+	uint8_t  TargetIndex;
+	uint8_t  Delay;
+	uint8_t  ControllerEnable;
+	uint8_t  ControllerRunning;
+	uint16_t CurrentStdVoltageHiSidd;
+	uint16_t CurrentStdVoltageLoSidd;
+	uint8_t  OverrideVoltage;
+	uint8_t  VddcUseUlvOffset;
+	uint8_t  VddGfxUseUlvOffset;
+	uint8_t  padding;
+
+	VoltageChangeHandler_t ChangeVddc;
+	VoltageChangeHandler_t ChangeVddGfx;
+	VoltageChangeHandler_t ChangeVddci;
+	VoltageChangeHandler_t ChangePhase;
+	VoltageChangeHandler_t ChangeMvdd;
+
+	VoltageChangeHandler_t functionLinks[6];
+
+	uint8_t *VddcFollower1;
+	uint8_t *VddcFollower2;
+	int16_t  Driver_OD_RequestedVidOffset1;
+	int16_t  Driver_OD_RequestedVidOffset2;
+
+};
+
+typedef struct SMU7_VoltageScoreboard SMU7_VoltageScoreboard;
+
+#define SMU7_MAX_PCIE_LINK_SPEEDS 3 /* 0:Gen1 1:Gen2 2:Gen3 */
+
+struct SMU7_PCIeLinkSpeedScoreboard {
+	uint8_t     DpmEnable;
+	uint8_t     DpmRunning;
+	uint8_t     DpmForce;
+	uint8_t     DpmForceLevel;
+
+	uint8_t     CurrentLinkSpeed;
+	uint8_t     EnabledLevelsChange;
+	uint16_t    AutoDpmInterval;
+
+	uint16_t    AutoDpmRange;
+	uint16_t    AutoDpmCount;
+
+	uint8_t     DpmMode;
+	uint8_t     AcpiReq;
+	uint8_t     AcpiAck;
+	uint8_t     CurrentLinkLevel;
+
+};
+
+typedef struct SMU7_PCIeLinkSpeedScoreboard SMU7_PCIeLinkSpeedScoreboard;
+
+/* -------------------------------------------------------- CAC table ------------------------------------------------------ */
+#define SMU7_LKGE_LUT_NUM_OF_TEMP_ENTRIES 16
+#define SMU7_LKGE_LUT_NUM_OF_VOLT_ENTRIES 16
+#define SMU7_SCALE_I  7
+#define SMU7_SCALE_R 12
+
+struct SMU7_PowerScoreboard {
+	PowerCalculatorData_t VddGfxPowerData[SID_OPTION_COUNT];
+	PowerCalculatorData_t VddcPowerData[SID_OPTION_COUNT];
+
+	uint32_t TotalGpuPower;
+	uint32_t TdcCurrent;
+
+	uint16_t   VddciTotalPower;
+	uint16_t   sparesasfsdfd;
+	uint16_t   Vddr1Power;
+	uint16_t   RocPower;
+
+	uint16_t   CalcMeasPowerBlend;
+	uint8_t    SidOptionPower;
+	uint8_t    SidOptionCurrent;
+
+	uint32_t   WinTime;
+
+	uint16_t Telemetry_1_slope;
+	uint16_t Telemetry_2_slope;
+	int32_t Telemetry_1_offset;
+	int32_t Telemetry_2_offset;
+
+	uint32_t VddcCurrentTelemetry;
+	uint32_t VddGfxCurrentTelemetry;
+	uint32_t VddcPowerTelemetry;
+	uint32_t VddGfxPowerTelemetry;
+	uint32_t VddciPowerTelemetry;
+
+	uint32_t VddcPower;
+	uint32_t VddGfxPower;
+	uint32_t VddciPower;
+
+	uint32_t TelemetryCurrent[2];
+	uint32_t TelemetryVoltage[2];
+	uint32_t TelemetryPower[2];
+};
+
+typedef struct SMU7_PowerScoreboard SMU7_PowerScoreboard;
+
+struct SMU7_ThermalScoreboard {
+	int16_t  GpuLimit;
+	int16_t  GpuHyst;
+	uint16_t CurrGnbTemp;
+	uint16_t FilteredGnbTemp;
+
+	uint8_t  ControllerEnable;
+	uint8_t  ControllerRunning;
+	uint8_t  AutoTmonCalInterval;
+	uint8_t  AutoTmonCalEnable;
+
+	uint8_t  ThermalDpmEnabled;
+	uint8_t  SclkEnabledMask;
+	uint8_t  spare[2];
+	int32_t  temperature_gradient;
+
+	SMU7_HystController_Data HystControllerData;
+	int32_t  WeightedSensorTemperature;
+	uint16_t TemperatureLimit[SMU72_MAX_LEVELS_GRAPHICS];
+	uint32_t Alpha;
+};
+
+typedef struct SMU7_ThermalScoreboard SMU7_ThermalScoreboard;
+
+/* For FeatureEnables: */
+#define SMU7_SCLK_DPM_CONFIG_MASK                        0x01
+#define SMU7_VOLTAGE_CONTROLLER_CONFIG_MASK              0x02
+#define SMU7_THERMAL_CONTROLLER_CONFIG_MASK              0x04
+#define SMU7_MCLK_DPM_CONFIG_MASK                        0x08
+#define SMU7_UVD_DPM_CONFIG_MASK                         0x10
+#define SMU7_VCE_DPM_CONFIG_MASK                         0x20
+#define SMU7_ACP_DPM_CONFIG_MASK                         0x40
+#define SMU7_SAMU_DPM_CONFIG_MASK                        0x80
+#define SMU7_PCIEGEN_DPM_CONFIG_MASK                    0x100
+
+#define SMU7_ACP_MCLK_HANDSHAKE_DISABLE                  0x00000001
+#define SMU7_ACP_SCLK_HANDSHAKE_DISABLE                  0x00000002
+#define SMU7_UVD_MCLK_HANDSHAKE_DISABLE                  0x00000100
+#define SMU7_UVD_SCLK_HANDSHAKE_DISABLE                  0x00000200
+#define SMU7_VCE_MCLK_HANDSHAKE_DISABLE                  0x00010000
+#define SMU7_VCE_SCLK_HANDSHAKE_DISABLE                  0x00020000
+
+/* All 'soft registers' should be uint32_t. */
+struct SMU72_SoftRegisters {
+	uint32_t        RefClockFrequency;
+	uint32_t        PmTimerPeriod;
+	uint32_t        FeatureEnables;
+
+	uint32_t        PreVBlankGap;
+	uint32_t        VBlankTimeout;
+	uint32_t        TrainTimeGap;
+
+	uint32_t        MvddSwitchTime;
+	uint32_t        LongestAcpiTrainTime;
+	uint32_t        AcpiDelay;
+	uint32_t        G5TrainTime;
+	uint32_t        DelayMpllPwron;
+	uint32_t        VoltageChangeTimeout;
+
+	uint32_t        HandshakeDisables;
+
+	uint8_t         DisplayPhy1Config;
+	uint8_t         DisplayPhy2Config;
+	uint8_t         DisplayPhy3Config;
+	uint8_t         DisplayPhy4Config;
+
+	uint8_t         DisplayPhy5Config;
+	uint8_t         DisplayPhy6Config;
+	uint8_t         DisplayPhy7Config;
+	uint8_t         DisplayPhy8Config;
+
+	uint32_t        AverageGraphicsActivity;
+	uint32_t        AverageMemoryActivity;
+	uint32_t        AverageGioActivity;
+
+	uint8_t         SClkDpmEnabledLevels;
+	uint8_t         MClkDpmEnabledLevels;
+	uint8_t         LClkDpmEnabledLevels;
+	uint8_t         PCIeDpmEnabledLevels;
+
+	uint8_t         UVDDpmEnabledLevels;
+	uint8_t         SAMUDpmEnabledLevels;
+	uint8_t         ACPDpmEnabledLevels;
+	uint8_t         VCEDpmEnabledLevels;
+
+	uint32_t        DRAM_LOG_ADDR_H;
+	uint32_t        DRAM_LOG_ADDR_L;
+	uint32_t        DRAM_LOG_PHY_ADDR_H;
+	uint32_t        DRAM_LOG_PHY_ADDR_L;
+	uint32_t        DRAM_LOG_BUFF_SIZE;
+	uint32_t        UlvEnterCount;
+	uint32_t        UlvTime;
+	uint32_t        UcodeLoadStatus;
+	uint32_t        Reserved[2];
+
+};
+
+typedef struct SMU72_SoftRegisters SMU72_SoftRegisters;
+
+struct SMU72_Firmware_Header {
+	uint32_t Digest[5];
+	uint32_t Version;
+	uint32_t HeaderSize;
+	uint32_t Flags;
+	uint32_t EntryPoint;
+	uint32_t CodeSize;
+	uint32_t ImageSize;
+
+	uint32_t Rtos;
+	uint32_t SoftRegisters;
+	uint32_t DpmTable;
+	uint32_t FanTable;
+	uint32_t CacConfigTable;
+	uint32_t CacStatusTable;
+	uint32_t mcRegisterTable;
+	uint32_t mcArbDramTimingTable;
+	uint32_t PmFuseTable;
+	uint32_t Globals;
+	uint32_t ClockStretcherTable;
+	uint32_t Reserved[41];
+	uint32_t Signature;
+};
+
+typedef struct SMU72_Firmware_Header SMU72_Firmware_Header;
+
+#define SMU72_FIRMWARE_HEADER_LOCATION 0x20000
+
+enum  DisplayConfig {
+	PowerDown = 1,
+	DP54x4,
+	DP54x2,
+	DP54x1,
+	DP27x4,
+	DP27x2,
+	DP27x1,
+	HDMI297,
+	HDMI162,
+	LVDS,
+	DP324x4,
+	DP324x2,
+	DP324x1
+};
+
+#define MC_BLOCK_COUNT 1
+#define CPL_BLOCK_COUNT 5
+#define SE_BLOCK_COUNT 15
+#define GC_BLOCK_COUNT 24
+
+struct SMU7_Local_Cac {
+	uint8_t BlockId;
+	uint8_t SignalId;
+	uint8_t Threshold;
+	uint8_t Padding;
+};
+
+typedef struct SMU7_Local_Cac SMU7_Local_Cac;
+
+struct SMU7_Local_Cac_Table {
+	SMU7_Local_Cac CplLocalCac[CPL_BLOCK_COUNT];
+	SMU7_Local_Cac McLocalCac[MC_BLOCK_COUNT];
+	SMU7_Local_Cac SeLocalCac[SE_BLOCK_COUNT];
+	SMU7_Local_Cac GcLocalCac[GC_BLOCK_COUNT];
+};
+
+typedef struct SMU7_Local_Cac_Table SMU7_Local_Cac_Table;
+
+#if !defined(SMC_MICROCODE)
+#pragma pack(pop)
+#endif
+
+/* Description of Clock Gating bitmask for Tonga: */
+/* System Clock Gating */
+#define CG_SYS_BITMASK_FIRST_BIT      0  /* First bit of Sys CG bitmask */
+#define CG_SYS_BITMASK_LAST_BIT       9  /* Last bit of Sys CG bitmask */
+#define CG_SYS_BIF_MGLS_SHIFT         0
+#define CG_SYS_ROM_SHIFT              1
+#define CG_SYS_MC_MGCG_SHIFT          2
+#define CG_SYS_MC_MGLS_SHIFT          3
+#define CG_SYS_SDMA_MGCG_SHIFT        4
+#define CG_SYS_SDMA_MGLS_SHIFT        5
+#define CG_SYS_DRM_MGCG_SHIFT         6
+#define CG_SYS_HDP_MGCG_SHIFT         7
+#define CG_SYS_HDP_MGLS_SHIFT         8
+#define CG_SYS_DRM_MGLS_SHIFT         9
+
+#define CG_SYS_BIF_MGLS_MASK          0x1
+#define CG_SYS_ROM_MASK               0x2
+#define CG_SYS_MC_MGCG_MASK           0x4
+#define CG_SYS_MC_MGLS_MASK           0x8
+#define CG_SYS_SDMA_MGCG_MASK         0x10
+#define CG_SYS_SDMA_MGLS_MASK         0x20
+#define CG_SYS_DRM_MGCG_MASK          0x40
+#define CG_SYS_HDP_MGCG_MASK          0x80
+#define CG_SYS_HDP_MGLS_MASK          0x100
+#define CG_SYS_DRM_MGLS_MASK          0x200
+
+/* Graphics Clock Gating */
+#define CG_GFX_BITMASK_FIRST_BIT      16 /* First bit of Gfx CG bitmask */
+#define CG_GFX_BITMASK_LAST_BIT       20 /* Last bit of Gfx CG bitmask */
+#define CG_GFX_CGCG_SHIFT             16
+#define CG_GFX_CGLS_SHIFT             17
+#define CG_CPF_MGCG_SHIFT             18
+#define CG_RLC_MGCG_SHIFT             19
+#define CG_GFX_OTHERS_MGCG_SHIFT      20
+
+#define CG_GFX_CGCG_MASK              0x00010000
+#define CG_GFX_CGLS_MASK              0x00020000
+#define CG_CPF_MGCG_MASK              0x00040000
+#define CG_RLC_MGCG_MASK              0x00080000
+#define CG_GFX_OTHERS_MGCG_MASK       0x00100000
+
+/* Voltage Regulator Configuration */
+/* VR Config info is contained in dpmTable.VRConfig */
+
+#define VRCONF_VDDC_MASK         0x000000FF
+#define VRCONF_VDDC_SHIFT        0
+#define VRCONF_VDDGFX_MASK       0x0000FF00
+#define VRCONF_VDDGFX_SHIFT      8
+#define VRCONF_VDDCI_MASK        0x00FF0000
+#define VRCONF_VDDCI_SHIFT       16
+#define VRCONF_MVDD_MASK         0xFF000000
+#define VRCONF_MVDD_SHIFT        24
+
+#define VR_MERGED_WITH_VDDC      0
+#define VR_SVI2_PLANE_1          1
+#define VR_SVI2_PLANE_2          2
+#define VR_SMIO_PATTERN_1        3
+#define VR_SMIO_PATTERN_2        4
+#define VR_STATIC_VOLTAGE        5
+
+/* Clock Stretcher Configuration */
+
+#define CLOCK_STRETCHER_MAX_ENTRIES 0x4
+#define CKS_LOOKUPTable_MAX_ENTRIES 0x4
+
+/* The 'settings' field is subdivided in the following way: */
+#define CLOCK_STRETCHER_SETTING_DDT_MASK             0x01
+#define CLOCK_STRETCHER_SETTING_DDT_SHIFT            0x0
+#define CLOCK_STRETCHER_SETTING_STRETCH_AMOUNT_MASK  0x1E
+#define CLOCK_STRETCHER_SETTING_STRETCH_AMOUNT_SHIFT 0x1
+#define CLOCK_STRETCHER_SETTING_ENABLE_MASK          0x80
+#define CLOCK_STRETCHER_SETTING_ENABLE_SHIFT         0x7
+
+struct SMU_ClockStretcherDataTableEntry {
+	uint8_t minVID;
+	uint8_t maxVID;
+
+	uint16_t setting;
+};
+typedef struct SMU_ClockStretcherDataTableEntry SMU_ClockStretcherDataTableEntry;
+
+struct SMU_ClockStretcherDataTable {
+	SMU_ClockStretcherDataTableEntry ClockStretcherDataTableEntry[CLOCK_STRETCHER_MAX_ENTRIES];
+};
+typedef struct SMU_ClockStretcherDataTable SMU_ClockStretcherDataTable;
+
+struct SMU_CKS_LOOKUPTableEntry {
+	uint16_t minFreq;
+	uint16_t maxFreq;
+
+	uint8_t setting;
+	uint8_t padding[3];
+};
+typedef struct SMU_CKS_LOOKUPTableEntry SMU_CKS_LOOKUPTableEntry;
+
+struct SMU_CKS_LOOKUPTable {
+	SMU_CKS_LOOKUPTableEntry CKS_LOOKUPTableEntry[CKS_LOOKUPTable_MAX_ENTRIES];
+};
+typedef struct SMU_CKS_LOOKUPTable SMU_CKS_LOOKUPTable;
+
+#endif
+
+
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/powerplay/inc/smu72_discrete.h
@@ -0,0 +1,760 @@
+#ifndef SMU72_DISCRETE_H
+#define SMU72_DISCRETE_H
+
+#include "smu72.h"
+
+#if !defined(SMC_MICROCODE)
+#pragma pack(push, 1)
+#endif
+
+struct SMIO_Pattern {
+	uint16_t Voltage;
+	uint8_t  Smio;
+	uint8_t  padding;
+};
+
+typedef struct SMIO_Pattern SMIO_Pattern;
+
+struct SMIO_Table {
+	SMIO_Pattern Pattern[SMU_MAX_SMIO_LEVELS];
+};
+
+typedef struct SMIO_Table SMIO_Table;
+
+struct SMU72_Discrete_GraphicsLevel {
+	SMU_VoltageLevel MinVoltage;
+
+	uint32_t    SclkFrequency;
+
+	uint8_t     pcieDpmLevel;
+	uint8_t     DeepSleepDivId;
+	uint16_t    ActivityLevel;
+
+	uint32_t    CgSpllFuncCntl3;
+	uint32_t    CgSpllFuncCntl4;
+	uint32_t    SpllSpreadSpectrum;
+	uint32_t    SpllSpreadSpectrum2;
+	uint32_t    CcPwrDynRm;
+	uint32_t    CcPwrDynRm1;
+	uint8_t     SclkDid;
+	uint8_t     DisplayWatermark;
+	uint8_t     EnabledForActivity;
+	uint8_t     EnabledForThrottle;
+	uint8_t     UpHyst;
+	uint8_t     DownHyst;
+	uint8_t     VoltageDownHyst;
+	uint8_t     PowerThrottle;
+};
+
+typedef struct SMU72_Discrete_GraphicsLevel SMU72_Discrete_GraphicsLevel;
+
+struct SMU72_Discrete_ACPILevel {
+	uint32_t    Flags;
+	SMU_VoltageLevel MinVoltage;
+	uint32_t    SclkFrequency;
+	uint8_t     SclkDid;
+	uint8_t     DisplayWatermark;
+	uint8_t     DeepSleepDivId;
+	uint8_t     padding;
+	uint32_t    CgSpllFuncCntl;
+	uint32_t    CgSpllFuncCntl2;
+	uint32_t    CgSpllFuncCntl3;
+	uint32_t    CgSpllFuncCntl4;
+	uint32_t    SpllSpreadSpectrum;
+	uint32_t    SpllSpreadSpectrum2;
+	uint32_t    CcPwrDynRm;
+	uint32_t    CcPwrDynRm1;
+};
+
+typedef struct SMU72_Discrete_ACPILevel SMU72_Discrete_ACPILevel;
+
+struct SMU72_Discrete_Ulv {
+	uint32_t    CcPwrDynRm;
+	uint32_t    CcPwrDynRm1;
+	uint16_t    VddcOffset;
+	uint8_t     VddcOffsetVid;
+	uint8_t     VddcPhase;
+	uint32_t    Reserved;
+};
+
+typedef struct SMU72_Discrete_Ulv SMU72_Discrete_Ulv;
+
+struct SMU72_Discrete_MemoryLevel {
+	SMU_VoltageLevel MinVoltage;
+	uint32_t    MinMvdd;
+
+	uint32_t    MclkFrequency;
+
+	uint8_t     EdcReadEnable;
+	uint8_t     EdcWriteEnable;
+	uint8_t     RttEnable;
+	uint8_t     StutterEnable;
+
+	uint8_t     StrobeEnable;
+	uint8_t     StrobeRatio;
+	uint8_t     EnabledForThrottle;
+	uint8_t     EnabledForActivity;
+
+	uint8_t     UpHyst;
+	uint8_t     DownHyst;
+	uint8_t     VoltageDownHyst;
+	uint8_t     padding;
+
+	uint16_t    ActivityLevel;
+	uint8_t     DisplayWatermark;
+	uint8_t     padding1;
+
+	uint32_t    MpllFuncCntl;
+	uint32_t    MpllFuncCntl_1;
+	uint32_t    MpllFuncCntl_2;
+	uint32_t    MpllAdFuncCntl;
+	uint32_t    MpllDqFuncCntl;
+	uint32_t    MclkPwrmgtCntl;
+	uint32_t    DllCntl;
+	uint32_t    MpllSs1;
+	uint32_t    MpllSs2;
+};
+
+typedef struct SMU72_Discrete_MemoryLevel SMU72_Discrete_MemoryLevel;
+
+struct SMU72_Discrete_LinkLevel {
+	uint8_t     PcieGenSpeed;           /*< 0:PciE-gen1 1:PciE-gen2 2:PciE-gen3 */
+	uint8_t     PcieLaneCount;          /*< 1=x1, 2=x2, 3=x4, 4=x8, 5=x12, 6=x16 */
+	uint8_t     EnabledForActivity;
+	uint8_t     SPC;
+	uint32_t    DownThreshold;
+	uint32_t    UpThreshold;
+	uint32_t    Reserved;
+};
+
+typedef struct SMU72_Discrete_LinkLevel SMU72_Discrete_LinkLevel;
+
+/* MC ARB DRAM Timing registers. */
+struct SMU72_Discrete_MCArbDramTimingTableEntry {
+	uint32_t McArbDramTiming;
+	uint32_t McArbDramTiming2;
+	uint8_t  McArbBurstTime;
+	uint8_t  padding[3];
+};
+
+typedef struct SMU72_Discrete_MCArbDramTimingTableEntry SMU72_Discrete_MCArbDramTimingTableEntry;
+
+struct SMU72_Discrete_MCArbDramTimingTable {
+	SMU72_Discrete_MCArbDramTimingTableEntry entries[SMU__NUM_SCLK_DPM_STATE][SMU__NUM_MCLK_DPM_LEVELS];
+};
+
+typedef struct SMU72_Discrete_MCArbDramTimingTable SMU72_Discrete_MCArbDramTimingTable;
+
+/* UVD VCLK/DCLK state (level) definition. */
+struct SMU72_Discrete_UvdLevel {
+	uint32_t VclkFrequency;
+	uint32_t DclkFrequency;
+	SMU_VoltageLevel MinVoltage;
+	uint8_t  VclkDivider;
+	uint8_t  DclkDivider;
+	uint8_t  padding[2];
+};
+
+typedef struct SMU72_Discrete_UvdLevel SMU72_Discrete_UvdLevel;
+
+/* Clocks for other external blocks (VCE, ACP, SAMU). */
+struct SMU72_Discrete_ExtClkLevel {
+	uint32_t Frequency;
+	SMU_VoltageLevel MinVoltage;
+	uint8_t  Divider;
+	uint8_t  padding[3];
+};
+
+typedef struct SMU72_Discrete_ExtClkLevel SMU72_Discrete_ExtClkLevel;
+
+struct SMU72_Discrete_StateInfo {
+	uint32_t SclkFrequency;
+	uint32_t MclkFrequency;
+	uint32_t VclkFrequency;
+	uint32_t DclkFrequency;
+	uint32_t SamclkFrequency;
+	uint32_t AclkFrequency;
+	uint32_t EclkFrequency;
+	uint16_t MvddVoltage;
+	uint16_t padding16;
+	uint8_t  DisplayWatermark;
+	uint8_t  McArbIndex;
+	uint8_t  McRegIndex;
+	uint8_t  SeqIndex;
+	uint8_t  SclkDid;
+	int8_t   SclkIndex;
+	int8_t   MclkIndex;
+	uint8_t  PCIeGen;
+
+};
+
+typedef struct SMU72_Discrete_StateInfo SMU72_Discrete_StateInfo;
+
+struct SMU72_Discrete_DpmTable {
+	/* Multi-DPM controller settings */
+	SMU72_PIDController                  GraphicsPIDController;
+	SMU72_PIDController                  MemoryPIDController;
+	SMU72_PIDController                  LinkPIDController;
+
+	uint32_t                            SystemFlags;
+
+	/* SMIO masks for voltage and phase controls */
+	uint32_t                            VRConfig;
+	uint32_t                            SmioMask1;
+	uint32_t                            SmioMask2;
+	SMIO_Table                          SmioTable1;
+	SMIO_Table                          SmioTable2;
+
+	uint32_t                            VddcLevelCount;
+	uint32_t                            VddciLevelCount;
+	uint32_t                            VddGfxLevelCount;
+	uint32_t                            MvddLevelCount;
+
+	uint16_t                            VddcTable[SMU72_MAX_LEVELS_VDDC];
+	uint16_t                            VddGfxTable[SMU72_MAX_LEVELS_VDDGFX];
+	uint16_t                            VddciTable[SMU72_MAX_LEVELS_VDDCI];
+
+	uint8_t                             BapmVddGfxVidHiSidd[SMU72_MAX_LEVELS_VDDGFX];
+	uint8_t                             BapmVddGfxVidLoSidd[SMU72_MAX_LEVELS_VDDGFX];
+	uint8_t                             BapmVddGfxVidHiSidd2[SMU72_MAX_LEVELS_VDDGFX];
+
+	uint8_t                             BapmVddcVidHiSidd[SMU72_MAX_LEVELS_VDDC];
+	uint8_t                             BapmVddcVidLoSidd[SMU72_MAX_LEVELS_VDDC];
+	uint8_t                             BapmVddcVidHiSidd2[SMU72_MAX_LEVELS_VDDC];
+
+	uint8_t                             GraphicsDpmLevelCount;
+	uint8_t                             MemoryDpmLevelCount;
+	uint8_t                             LinkLevelCount;
+	uint8_t                             MasterDeepSleepControl;
+
+	uint8_t                             UvdLevelCount;
+	uint8_t                             VceLevelCount;
+	uint8_t                             AcpLevelCount;
+	uint8_t                             SamuLevelCount;
+
+	uint8_t                             ThermOutGpio;
+	uint8_t                             ThermOutPolarity;
+	uint8_t                             ThermOutMode;
+	uint8_t                             DPMFreezeAndForced;
+	uint32_t                            Reserved[4];
+
+	/* State table entries for each DPM state */
+	SMU72_Discrete_GraphicsLevel        GraphicsLevel[SMU72_MAX_LEVELS_GRAPHICS];
+	SMU72_Discrete_MemoryLevel          MemoryACPILevel;
+	SMU72_Discrete_MemoryLevel          MemoryLevel[SMU72_MAX_LEVELS_MEMORY];
+	SMU72_Discrete_LinkLevel            LinkLevel[SMU72_MAX_LEVELS_LINK];
+	SMU72_Discrete_ACPILevel            ACPILevel;
+	SMU72_Discrete_UvdLevel             UvdLevel[SMU72_MAX_LEVELS_UVD];
+	SMU72_Discrete_ExtClkLevel          VceLevel[SMU72_MAX_LEVELS_VCE];
+	SMU72_Discrete_ExtClkLevel          AcpLevel[SMU72_MAX_LEVELS_ACP];
+	SMU72_Discrete_ExtClkLevel          SamuLevel[SMU72_MAX_LEVELS_SAMU];
+	SMU72_Discrete_Ulv                  Ulv;
+
+	uint32_t                            SclkStepSize;
+	uint32_t                            Smio[SMU72_MAX_ENTRIES_SMIO];
+
+	uint8_t                             UvdBootLevel;
+	uint8_t                             VceBootLevel;
+	uint8_t                             AcpBootLevel;
+	uint8_t                             SamuBootLevel;
+
+	uint8_t                             GraphicsBootLevel;
+	uint8_t                             GraphicsVoltageChangeEnable;
+	uint8_t                             GraphicsThermThrottleEnable;
+	uint8_t                             GraphicsInterval;
+
+	uint8_t                             VoltageInterval;
+	uint8_t                             ThermalInterval;
+	uint16_t                            TemperatureLimitHigh;
+
+	uint16_t                            TemperatureLimitLow;
+	uint8_t                             MemoryBootLevel;
+	uint8_t                             MemoryVoltageChangeEnable;
+
+	uint16_t                            BootMVdd;
+	uint8_t                             MemoryInterval;
+	uint8_t                             MemoryThermThrottleEnable;
+
+	uint16_t                            VoltageResponseTime;
+	uint16_t                            PhaseResponseTime;
+
+	uint8_t                             PCIeBootLinkLevel;
+	uint8_t                             PCIeGenInterval;
+	uint8_t                             DTEInterval;
+	uint8_t                             DTEMode;
+
+	uint8_t                             SVI2Enable;
+	uint8_t                             VRHotGpio;
+	uint8_t                             AcDcGpio;
+	uint8_t                             ThermGpio;
+
+	uint16_t                            PPM_PkgPwrLimit;
+	uint16_t                            PPM_TemperatureLimit;
+
+	uint16_t                            DefaultTdp;
+	uint16_t                            TargetTdp;
+
+	uint16_t                            FpsHighThreshold;
+	uint16_t                            FpsLowThreshold;
+
+	uint16_t                            BAPMTI_R[SMU72_DTE_ITERATIONS][SMU72_DTE_SOURCES][SMU72_DTE_SINKS];
+	uint16_t                            BAPMTI_RC[SMU72_DTE_ITERATIONS][SMU72_DTE_SOURCES][SMU72_DTE_SINKS];
+
+	uint8_t                             DTEAmbientTempBase;
+	uint8_t                             DTETjOffset;
+	uint8_t                             GpuTjMax;
+	uint8_t                             GpuTjHyst;
+
+	SMU_VoltageLevel                    BootVoltage;
+
+	uint32_t                            BAPM_TEMP_GRADIENT;
+
+	uint32_t                            LowSclkInterruptThreshold;
+	uint32_t                            VddGfxReChkWait;
+
+	uint8_t                             ClockStretcherAmount;
+
+	uint8_t                             Sclk_CKS_masterEn0_7;
+	uint8_t                             Sclk_CKS_masterEn8_15;
+	uint8_t                             padding[1];
+
+	uint8_t                             Sclk_voltageOffset[8];
+
+	SMU_ClockStretcherDataTable         ClockStretcherDataTable;
+	SMU_CKS_LOOKUPTable                 CKS_LOOKUPTable;
+};
+
+typedef struct SMU72_Discrete_DpmTable SMU72_Discrete_DpmTable;
+
+/* --------------------------------------------------- AC Timing Parameters ------------------------------------------------ */
+#define SMU72_DISCRETE_MC_REGISTER_ARRAY_SIZE 16
+#define SMU72_DISCRETE_MC_REGISTER_ARRAY_SET_COUNT SMU72_MAX_LEVELS_MEMORY /* DPM */
+
+struct SMU72_Discrete_MCRegisterAddress {
+	uint16_t s0;
+	uint16_t s1;
+};
+
+typedef struct SMU72_Discrete_MCRegisterAddress SMU72_Discrete_MCRegisterAddress;
+
+struct SMU72_Discrete_MCRegisterSet {
+	uint32_t value[SMU72_DISCRETE_MC_REGISTER_ARRAY_SIZE];
+};
+
+typedef struct SMU72_Discrete_MCRegisterSet SMU72_Discrete_MCRegisterSet;
+
+struct SMU72_Discrete_MCRegisters {
+	uint8_t                             last;
+	uint8_t                             reserved[3];
+	SMU72_Discrete_MCRegisterAddress     address[SMU72_DISCRETE_MC_REGISTER_ARRAY_SIZE];
+	SMU72_Discrete_MCRegisterSet         data[SMU72_DISCRETE_MC_REGISTER_ARRAY_SET_COUNT];
+};
+
+typedef struct SMU72_Discrete_MCRegisters SMU72_Discrete_MCRegisters;
+
+
+/* --------------------------------------------------- Fan Table ----------------------------------------------------------- */
+
+struct SMU72_Discrete_FanTable {
+	uint16_t FdoMode;
+	int16_t  TempMin;
+	int16_t  TempMed;
+	int16_t  TempMax;
+	int16_t  Slope1;
+	int16_t  Slope2;
+	int16_t  FdoMin;
+	int16_t  HystUp;
+	int16_t  HystDown;
+	int16_t  HystSlope;
+	int16_t  TempRespLim;
+	int16_t  TempCurr;
+	int16_t  SlopeCurr;
+	int16_t  PwmCurr;
+	uint32_t RefreshPeriod;
+	int16_t  FdoMax;
+	uint8_t  TempSrc;
+	int8_t   FanControl_GL_Flag;
+};
+
+typedef struct SMU72_Discrete_FanTable SMU72_Discrete_FanTable;
+
+#define SMU7_DISCRETE_GPIO_SCLK_DEBUG             4
+#define SMU7_DISCRETE_GPIO_SCLK_DEBUG_BIT         (0x1 << SMU7_DISCRETE_GPIO_SCLK_DEBUG)
+
+struct SMU7_MclkDpmScoreboard {
+
+	uint32_t PercentageBusy;
+
+	int32_t  PIDError;
+	int32_t  PIDIntegral;
+	int32_t  PIDOutput;
+
+	uint32_t SigmaDeltaAccum;
+	uint32_t SigmaDeltaOutput;
+	uint32_t SigmaDeltaLevel;
+
+	uint32_t UtilizationSetpoint;
+
+	uint8_t  TdpClampMode;
+	uint8_t  TdcClampMode;
+	uint8_t  ThermClampMode;
+	uint8_t  VoltageBusy;
+
+	int8_t   CurrLevel;
+	int8_t   TargLevel;
+	uint8_t  LevelChangeInProgress;
+	uint8_t  UpHyst;
+
+	uint8_t  DownHyst;
+	uint8_t  VoltageDownHyst;
+	uint8_t  DpmEnable;
+	uint8_t  DpmRunning;
+
+	uint8_t  DpmForce;
+	uint8_t  DpmForceLevel;
+	uint8_t  DisplayWatermark;
+	uint8_t  McArbIndex;
+
+	uint32_t MinimumPerfMclk;
+
+	uint8_t  AcpiReq;
+	uint8_t  AcpiAck;
+	uint8_t  MclkSwitchInProgress;
+	uint8_t  MclkSwitchCritical;
+
+	uint8_t  IgnoreVBlank;
+	uint8_t  TargetMclkIndex;
+	uint8_t  TargetMvddIndex;
+	uint8_t  MclkSwitchResult;
+
+	uint16_t VbiFailureCount;
+	uint8_t  VbiWaitCounter;
+	uint8_t  EnabledLevelsChange;
+
+	uint16_t LevelResidencyCountersN[SMU72_MAX_LEVELS_MEMORY];
+	uint16_t LevelSwitchCounters[SMU72_MAX_LEVELS_MEMORY];
+
+	void     (*TargetStateCalculator)(uint8_t);
+	void     (*SavedTargetStateCalculator)(uint8_t);
+
+	uint16_t AutoDpmInterval;
+	uint16_t AutoDpmRange;
+
+	uint16_t VbiTimeoutCount;
+	uint16_t MclkSwitchingTime;
+
+	uint8_t  fastSwitch;
+	uint8_t  Save_PIC_VDDGFX_EXIT;
+	uint8_t  Save_PIC_VDDGFX_ENTER;
+	uint8_t  padding;
+
+};
+
+typedef struct SMU7_MclkDpmScoreboard SMU7_MclkDpmScoreboard;
+
+struct SMU7_UlvScoreboard {
+	uint8_t     EnterUlv;
+	uint8_t     ExitUlv;
+	uint8_t     UlvActive;
+	uint8_t     WaitingForUlv;
+	uint8_t     UlvEnable;
+	uint8_t     UlvRunning;
+	uint8_t     UlvMasterEnable;
+	uint8_t     padding;
+	uint32_t    UlvAbortedCount;
+	uint32_t    UlvTimeStamp;
+};
+
+typedef struct SMU7_UlvScoreboard SMU7_UlvScoreboard;
+
+struct VddgfxSavedRegisters {
+	uint32_t GPU_DBG[3];
+	uint32_t MEC_BaseAddress_Hi;
+	uint32_t MEC_BaseAddress_Lo;
+	uint32_t THM_TMON0_CTRL2__RDIR_PRESENT;
+	uint32_t THM_TMON1_CTRL2__RDIR_PRESENT;
+	uint32_t CP_INT_CNTL;
+};
+
+typedef struct VddgfxSavedRegisters VddgfxSavedRegisters;
+
+struct SMU7_VddGfxScoreboard {
+	uint8_t     VddGfxEnable;
+	uint8_t     VddGfxActive;
+	uint8_t     VPUResetOccured;
+	uint8_t     padding;
+
+	uint32_t    VddGfxEnteredCount;
+	uint32_t    VddGfxAbortedCount;
+
+	uint32_t    VddGfxVid;
+
+	VddgfxSavedRegisters SavedRegisters;
+};
+
+typedef struct SMU7_VddGfxScoreboard SMU7_VddGfxScoreboard;
+
+struct SMU7_TdcLimitScoreboard {
+	uint8_t  Enable;
+	uint8_t  Running;
+	uint16_t Alpha;
+	uint32_t FilteredIddc;
+	uint32_t IddcLimit;
+	uint32_t IddcHyst;
+	SMU7_HystController_Data HystControllerData;
+};
+
+typedef struct SMU7_TdcLimitScoreboard SMU7_TdcLimitScoreboard;
+
+struct SMU7_PkgPwrLimitScoreboard {
+	uint8_t  Enable;
+	uint8_t  Running;
+	uint16_t Alpha;
+	uint32_t FilteredPkgPwr;
+	uint32_t Limit;
+	uint32_t Hyst;
+	uint32_t LimitFromDriver;
+	SMU7_HystController_Data HystControllerData;
+};
+
+typedef struct SMU7_PkgPwrLimitScoreboard SMU7_PkgPwrLimitScoreboard;
+
+struct SMU7_BapmScoreboard {
+	uint32_t source_powers[SMU72_DTE_SOURCES];
+	uint32_t source_powers_last[SMU72_DTE_SOURCES];
+	int32_t entity_temperatures[SMU72_NUM_GPU_TES];
+	int32_t initial_entity_temperatures[SMU72_NUM_GPU_TES];
+	int32_t Limit;
+	int32_t Hyst;
+	int32_t therm_influence_coeff_table[SMU72_DTE_ITERATIONS * SMU72_DTE_SOURCES * SMU72_DTE_SINKS * 2];
+	int32_t therm_node_table[SMU72_DTE_ITERATIONS * SMU72_DTE_SOURCES * SMU72_DTE_SINKS];
+	uint16_t ConfigTDPPowerScalar;
+	uint16_t FanSpeedPowerScalar;
+	uint16_t OverDrivePowerScalar;
+	uint16_t OverDriveLimitScalar;
+	uint16_t FinalPowerScalar;
+	uint8_t VariantID;
+	uint8_t spare997;
+
+	SMU7_HystController_Data HystControllerData;
+
+	int32_t temperature_gradient_slope;
+	int32_t temperature_gradient;
+	uint32_t measured_temperature;
+};
+
+
+typedef struct SMU7_BapmScoreboard SMU7_BapmScoreboard;
+
+struct SMU7_AcpiScoreboard {
+	uint32_t SavedInterruptMask[2];
+	uint8_t LastACPIRequest;
+	uint8_t CgBifResp;
+	uint8_t RequestType;
+	uint8_t Padding;
+	SMU72_Discrete_ACPILevel D0Level;
+};
+
+typedef struct SMU7_AcpiScoreboard SMU7_AcpiScoreboard;
+
+struct SMU72_Discrete_PmFuses {
+	/* dw1  */
+	uint8_t SviLoadLineEn;
+	uint8_t SviLoadLineVddC;
+	uint8_t SviLoadLineTrimVddC;
+	uint8_t SviLoadLineOffsetVddC;
+
+	/* dw2 */
+	uint16_t TDC_VDDC_PkgLimit;
+	uint8_t TDC_VDDC_ThrottleReleaseLimitPerc;
+	uint8_t TDC_MAWt;
+
+	/* dw3 */
+	uint8_t TdcWaterfallCtl;
+	uint8_t LPMLTemperatureMin;
+	uint8_t LPMLTemperatureMax;
+	uint8_t Reserved;
+
+	/* dw4-dw7  */
+	uint8_t LPMLTemperatureScaler[16];
+
+	/* dw8-dw9  */
+	int16_t FuzzyFan_ErrorSetDelta;
+	int16_t FuzzyFan_ErrorRateSetDelta;
+	int16_t FuzzyFan_PwmSetDelta;
+	uint16_t Reserved6;
+
+	/* dw10-dw14  */
+	uint8_t GnbLPML[16];
+
+	/* dw15 */
+	uint8_t GnbLPMLMaxVid;
+	uint8_t GnbLPMLMinVid;
+	uint8_t Reserved1[2];
+
+	/* dw16 */
+	uint16_t BapmVddCBaseLeakageHiSidd;
+	uint16_t BapmVddCBaseLeakageLoSidd;
+};
+
+typedef struct SMU72_Discrete_PmFuses SMU72_Discrete_PmFuses;
+
+struct SMU7_Discrete_Log_Header_Table {
+	uint32_t    version;
+	uint32_t    asic_id;
+	uint16_t    flags;
+	uint16_t    entry_size;
+	uint32_t    total_size;
+	uint32_t    num_of_entries;
+	uint8_t     type;
+	uint8_t     mode;
+	uint8_t     filler_0[2];
+	uint32_t    filler_1[2];
+};
+
+typedef struct SMU7_Discrete_Log_Header_Table SMU7_Discrete_Log_Header_Table;
+
+struct SMU7_Discrete_Log_Cntl {
+	uint8_t             Enabled;
+	uint8_t             Type;
+	uint8_t             padding[2];
+	uint32_t            BufferSize;
+	uint32_t            SamplesLogged;
+	uint32_t            SampleSize;
+	uint32_t            AddrL;
+	uint32_t            AddrH;
+};
+
+typedef struct SMU7_Discrete_Log_Cntl SMU7_Discrete_Log_Cntl;
+
+#define CAC_ACC_NW_NUM_OF_SIGNALS 87
+
+struct SMU7_Discrete_Cac_Collection_Table {
+	uint32_t temperature;
+	uint32_t cac_acc_nw[CAC_ACC_NW_NUM_OF_SIGNALS];
+};
+
+typedef struct SMU7_Discrete_Cac_Collection_Table SMU7_Discrete_Cac_Collection_Table;
+
+struct SMU7_Discrete_Cac_Verification_Table {
+	uint32_t VddcTotalPower;
+	uint32_t VddcLeakagePower;
+	uint32_t VddcConstantPower;
+	uint32_t VddcGfxDynamicPower;
+	uint32_t VddcUvdDynamicPower;
+	uint32_t VddcVceDynamicPower;
+	uint32_t VddcAcpDynamicPower;
+	uint32_t VddcPcieDynamicPower;
+	uint32_t VddcDceDynamicPower;
+	uint32_t VddcCurrent;
+	uint32_t VddcVoltage;
+	uint32_t VddciTotalPower;
+	uint32_t VddciLeakagePower;
+	uint32_t VddciConstantPower;
+	uint32_t VddciDynamicPower;
+	uint32_t Vddr1TotalPower;
+	uint32_t Vddr1LeakagePower;
+	uint32_t Vddr1ConstantPower;
+	uint32_t Vddr1DynamicPower;
+	uint32_t spare[4];
+	uint32_t temperature;
+};
+
+typedef struct SMU7_Discrete_Cac_Verification_Table SMU7_Discrete_Cac_Verification_Table;
+
+struct SMU7_Discrete_Pm_Status_Table {
+	/* Thermal entities */
+	int32_t T_meas_max;
+	int32_t T_meas_acc;
+	int32_t T_calc_max;
+	int32_t T_calc_acc;
+	uint32_t P_scalar_acc;
+	uint32_t P_calc_max;
+	uint32_t P_calc_acc;
+
+	/*Voltage domains */
+	uint32_t I_calc_max;
+	uint32_t I_calc_acc;
+	uint32_t I_calc_acc_vddci;
+	uint32_t V_calc_noload_acc;
+	uint32_t V_calc_load_acc;
+	uint32_t V_calc_noload_acc_vddci;
+	uint32_t P_meas_acc;
+	uint32_t V_meas_noload_acc;
+	uint32_t V_meas_load_acc;
+	uint32_t I_meas_acc;
+	uint32_t P_meas_acc_vddci;
+	uint32_t V_meas_noload_acc_vddci;
+	uint32_t V_meas_load_acc_vddci;
+	uint32_t I_meas_acc_vddci;
+
+	/*Frequency */
+	uint16_t Sclk_dpm_residency[8];
+	uint16_t Uvd_dpm_residency[8];
+	uint16_t Vce_dpm_residency[8];
+	uint16_t Mclk_dpm_residency[4];
+
+	/*Chip */
+	uint32_t P_vddci_acc;
+	uint32_t P_vddr1_acc;
+	uint32_t P_nte1_acc;
+	uint32_t PkgPwr_max;
+	uint32_t PkgPwr_acc;
+	uint32_t MclkSwitchingTime_max;
+	uint32_t MclkSwitchingTime_acc;
+	uint32_t FanPwm_acc;
+	uint32_t FanRpm_acc;
+
+	uint32_t AccCnt;
+};
+
+typedef struct SMU7_Discrete_Pm_Status_Table SMU7_Discrete_Pm_Status_Table;
+
+/*FIXME THESE NEED TO BE UPDATED */
+#define SMU7_SCLK_CAC 0x561
+#define SMU7_MCLK_CAC 0xF9
+#define SMU7_VCLK_CAC 0x2DE
+#define SMU7_DCLK_CAC 0x2DE
+#define SMU7_ECLK_CAC 0x25E
+#define SMU7_ACLK_CAC 0x25E
+#define SMU7_SAMCLK_CAC 0x25E
+#define SMU7_DISPCLK_CAC 0x100
+#define SMU7_CAC_CONSTANT 0x2EE3430
+#define SMU7_CAC_CONSTANT_SHIFT 18
+
+#define SMU7_VDDCI_MCLK_CONST        1765
+#define SMU7_VDDCI_MCLK_CONST_SHIFT  16
+#define SMU7_VDDCI_VDDCI_CONST       50958
+#define SMU7_VDDCI_VDDCI_CONST_SHIFT 14
+#define SMU7_VDDCI_CONST             11781
+
+#define SMU7_12C_VDDCI_MCLK_CONST        1623
+#define SMU7_12C_VDDCI_MCLK_CONST_SHIFT  15
+#define SMU7_12C_VDDCI_VDDCI_CONST       40088
+#define SMU7_12C_VDDCI_VDDCI_CONST_SHIFT 13
+#define SMU7_12C_VDDCI_CONST             20856
+
+#define SMU7_VDDCI_STROBE_PWR        1331
+
+#define SMU7_VDDR1_CONST            693
+#define SMU7_VDDR1_CAC_WEIGHT       20
+#define SMU7_VDDR1_CAC_WEIGHT_SHIFT 19
+#define SMU7_VDDR1_STROBE_PWR       512
+
+#define SMU7_AREA_COEFF_UVD 0xA78
+#define SMU7_AREA_COEFF_VCE 0x190A
+#define SMU7_AREA_COEFF_ACP 0x22D1
+#define SMU7_AREA_COEFF_SAMU 0x534
+
+/*ThermOutMode values */
+#define SMU7_THERM_OUT_MODE_DISABLE       0x0
+#define SMU7_THERM_OUT_MODE_THERM_ONLY    0x1
+#define SMU7_THERM_OUT_MODE_THERM_VRHOT   0x2
+
+#if !defined(SMC_MICROCODE)
+#pragma pack(pop)
+#endif
+
+
+#endif
+
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/powerplay/inc/smu73.h
@@ -0,0 +1,720 @@
+/*
+ * Copyright 2015 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+#ifndef _SMU73_H_
+#define _SMU73_H_
+
+#pragma pack(push, 1)
+enum SID_OPTION {
+  SID_OPTION_HI,
+  SID_OPTION_LO,
+  SID_OPTION_COUNT
+};
+
+enum Poly3rdOrderCoeff {
+    LEAKAGE_TEMPERATURE_SCALAR,
+    LEAKAGE_VOLTAGE_SCALAR,
+    DYNAMIC_VOLTAGE_SCALAR,
+    POLY_3RD_ORDER_COUNT
+};
+
+struct SMU7_Poly3rdOrder_Data
+{
+    int32_t a;
+    int32_t b;
+    int32_t c;
+    int32_t d;
+    uint8_t a_shift;
+    uint8_t b_shift;
+    uint8_t c_shift;
+    uint8_t x_shift;
+};
+
+typedef struct SMU7_Poly3rdOrder_Data SMU7_Poly3rdOrder_Data;
+
+struct Power_Calculator_Data
+{
+  uint16_t NoLoadVoltage;
+  uint16_t LoadVoltage;
+  uint16_t Resistance;
+  uint16_t Temperature;
+  uint16_t BaseLeakage;
+  uint16_t LkgTempScalar;
+  uint16_t LkgVoltScalar;
+  uint16_t LkgAreaScalar;
+  uint16_t LkgPower;
+  uint16_t DynVoltScalar;
+  uint32_t Cac;
+  uint32_t DynPower;
+  uint32_t TotalCurrent;
+  uint32_t TotalPower;
+};
+
+typedef struct Power_Calculator_Data PowerCalculatorData_t;
+
+struct Gc_Cac_Weight_Data
+{
+  uint8_t index;
+  uint32_t value;
+};
+
+typedef struct Gc_Cac_Weight_Data GcCacWeight_Data;
+
+
+typedef struct {
+  uint32_t high;
+  uint32_t low;
+} data_64_t;
+
+typedef struct {
+  data_64_t high;
+  data_64_t low;
+} data_128_t;
+
+#define SMU__NUM_SCLK_DPM_STATE  8
+#define SMU__NUM_MCLK_DPM_LEVELS 4
+#define SMU__NUM_LCLK_DPM_LEVELS 8
+#define SMU__NUM_PCIE_DPM_LEVELS 8
+
+#define SMU7_CONTEXT_ID_SMC        1
+#define SMU7_CONTEXT_ID_VBIOS      2
+
+#define SMU73_MAX_LEVELS_VDDC            16
+#define SMU73_MAX_LEVELS_VDDGFX          16
+#define SMU73_MAX_LEVELS_VDDCI           8
+#define SMU73_MAX_LEVELS_MVDD            4
+
+#define SMU_MAX_SMIO_LEVELS              4
+
+#define SMU73_MAX_LEVELS_GRAPHICS        SMU__NUM_SCLK_DPM_STATE   // SCLK + SQ DPM + ULV
+#define SMU73_MAX_LEVELS_MEMORY          SMU__NUM_MCLK_DPM_LEVELS   // MCLK Levels DPM
+#define SMU73_MAX_LEVELS_GIO             SMU__NUM_LCLK_DPM_LEVELS  // LCLK Levels
+#define SMU73_MAX_LEVELS_LINK            SMU__NUM_PCIE_DPM_LEVELS  // PCIe speed and number of lanes.
+#define SMU73_MAX_LEVELS_UVD             8   // VCLK/DCLK levels for UVD.
+#define SMU73_MAX_LEVELS_VCE             8   // ECLK levels for VCE.
+#define SMU73_MAX_LEVELS_ACP             8   // ACLK levels for ACP.
+#define SMU73_MAX_LEVELS_SAMU            8   // SAMCLK levels for SAMU.
+#define SMU73_MAX_ENTRIES_SMIO           32  // Number of entries in SMIO table.
+
+#define DPM_NO_LIMIT 0
+#define DPM_NO_UP 1
+#define DPM_GO_DOWN 2
+#define DPM_GO_UP 3
+
+#define SMU7_FIRST_DPM_GRAPHICS_LEVEL    0
+#define SMU7_FIRST_DPM_MEMORY_LEVEL      0
+
+#define GPIO_CLAMP_MODE_VRHOT      1
+#define GPIO_CLAMP_MODE_THERM      2
+#define GPIO_CLAMP_MODE_DC         4
+
+#define SCRATCH_B_TARG_PCIE_INDEX_SHIFT 0
+#define SCRATCH_B_TARG_PCIE_INDEX_MASK  (0x7<<SCRATCH_B_TARG_PCIE_INDEX_SHIFT)
+#define SCRATCH_B_CURR_PCIE_INDEX_SHIFT 3
+#define SCRATCH_B_CURR_PCIE_INDEX_MASK  (0x7<<SCRATCH_B_CURR_PCIE_INDEX_SHIFT)
+#define SCRATCH_B_TARG_UVD_INDEX_SHIFT  6
+#define SCRATCH_B_TARG_UVD_INDEX_MASK   (0x7<<SCRATCH_B_TARG_UVD_INDEX_SHIFT)
+#define SCRATCH_B_CURR_UVD_INDEX_SHIFT  9
+#define SCRATCH_B_CURR_UVD_INDEX_MASK   (0x7<<SCRATCH_B_CURR_UVD_INDEX_SHIFT)
+#define SCRATCH_B_TARG_VCE_INDEX_SHIFT  12
+#define SCRATCH_B_TARG_VCE_INDEX_MASK   (0x7<<SCRATCH_B_TARG_VCE_INDEX_SHIFT)
+#define SCRATCH_B_CURR_VCE_INDEX_SHIFT  15
+#define SCRATCH_B_CURR_VCE_INDEX_MASK   (0x7<<SCRATCH_B_CURR_VCE_INDEX_SHIFT)
+#define SCRATCH_B_TARG_ACP_INDEX_SHIFT  18
+#define SCRATCH_B_TARG_ACP_INDEX_MASK   (0x7<<SCRATCH_B_TARG_ACP_INDEX_SHIFT)
+#define SCRATCH_B_CURR_ACP_INDEX_SHIFT  21
+#define SCRATCH_B_CURR_ACP_INDEX_MASK   (0x7<<SCRATCH_B_CURR_ACP_INDEX_SHIFT)
+#define SCRATCH_B_TARG_SAMU_INDEX_SHIFT 24
+#define SCRATCH_B_TARG_SAMU_INDEX_MASK  (0x7<<SCRATCH_B_TARG_SAMU_INDEX_SHIFT)
+#define SCRATCH_B_CURR_SAMU_INDEX_SHIFT 27
+#define SCRATCH_B_CURR_SAMU_INDEX_MASK  (0x7<<SCRATCH_B_CURR_SAMU_INDEX_SHIFT)
+
+// Virtualization Defines
+#define CG_XDMA_MASK  0x1
+#define CG_XDMA_SHIFT 0
+#define CG_UVD_MASK   0x2
+#define CG_UVD_SHIFT  1
+#define CG_VCE_MASK   0x4
+#define CG_VCE_SHIFT  2
+#define CG_SAMU_MASK  0x8
+#define CG_SAMU_SHIFT 3
+#define CG_GFX_MASK   0x10
+#define CG_GFX_SHIFT  4
+#define CG_SDMA_MASK  0x20
+#define CG_SDMA_SHIFT 5
+#define CG_HDP_MASK   0x40
+#define CG_HDP_SHIFT  6
+#define CG_MC_MASK    0x80
+#define CG_MC_SHIFT   7
+#define CG_DRM_MASK   0x100
+#define CG_DRM_SHIFT  8
+#define CG_ROM_MASK   0x200
+#define CG_ROM_SHIFT  9
+#define CG_BIF_MASK   0x400
+#define CG_BIF_SHIFT  10
+
+#define SMU73_DTE_ITERATIONS 5
+#define SMU73_DTE_SOURCES 3
+#define SMU73_DTE_SINKS 1
+#define SMU73_NUM_CPU_TES 0
+#define SMU73_NUM_GPU_TES 1
+#define SMU73_NUM_NON_TES 2
+#define SMU73_DTE_FAN_SCALAR_MIN 0x100
+#define SMU73_DTE_FAN_SCALAR_MAX 0x166
+#define SMU73_DTE_FAN_TEMP_MAX 93
+#define SMU73_DTE_FAN_TEMP_MIN 83
+
+#define SMU73_THERMAL_INPUT_LOOP_COUNT 6
+#define SMU73_THERMAL_CLAMP_MODE_COUNT 8
+
+
+struct SMU7_HystController_Data
+{
+    uint16_t waterfall_up;
+    uint16_t waterfall_down;
+    uint16_t waterfall_limit;
+    uint16_t release_cnt;
+    uint16_t release_limit;
+    uint16_t spare;
+};
+
+typedef struct SMU7_HystController_Data SMU7_HystController_Data;
+
+struct SMU73_PIDController
+{
+    uint32_t Ki;
+    int32_t LFWindupUpperLim;
+    int32_t LFWindupLowerLim;
+    uint32_t StatePrecision;
+
+    uint32_t LfPrecision;
+    uint32_t LfOffset;
+    uint32_t MaxState;
+    uint32_t MaxLfFraction;
+    uint32_t StateShift;
+};
+
+typedef struct SMU73_PIDController SMU73_PIDController;
+
+struct SMU7_LocalDpmScoreboard
+{
+    uint32_t PercentageBusy;
+
+    int32_t  PIDError;
+    int32_t  PIDIntegral;
+    int32_t  PIDOutput;
+
+    uint32_t SigmaDeltaAccum;
+    uint32_t SigmaDeltaOutput;
+    uint32_t SigmaDeltaLevel;
+
+    uint32_t UtilizationSetpoint;
+
+    uint8_t  TdpClampMode;
+    uint8_t  TdcClampMode;
+    uint8_t  ThermClampMode;
+    uint8_t  VoltageBusy;
+
+    int8_t   CurrLevel;
+    int8_t   TargLevel;
+    uint8_t  LevelChangeInProgress;
+    uint8_t  UpHyst;
+
+    uint8_t  DownHyst;
+    uint8_t  VoltageDownHyst;
+    uint8_t  DpmEnable;
+    uint8_t  DpmRunning;
+
+    uint8_t  DpmForce;
+    uint8_t  DpmForceLevel;
+    uint8_t  DisplayWatermark;
+    uint8_t  McArbIndex;
+
+    uint32_t MinimumPerfSclk;
+
+    uint8_t  AcpiReq;
+    uint8_t  AcpiAck;
+    uint8_t  GfxClkSlow;
+    uint8_t  GpioClampMode;
+
+    uint8_t  spare2;
+    uint8_t  EnabledLevelsChange;
+    uint8_t  DteClampMode;
+    uint8_t  FpsClampMode;
+
+    uint16_t LevelResidencyCounters [SMU73_MAX_LEVELS_GRAPHICS];
+    uint16_t LevelSwitchCounters [SMU73_MAX_LEVELS_GRAPHICS];
+
+    void     (*TargetStateCalculator)(uint8_t);
+    void     (*SavedTargetStateCalculator)(uint8_t);
+
+    uint16_t AutoDpmInterval;
+    uint16_t AutoDpmRange;
+
+    uint8_t  FpsEnabled;
+    uint8_t  MaxPerfLevel;
+    uint8_t  AllowLowClkInterruptToHost;
+    uint8_t  FpsRunning;
+
+    uint32_t MaxAllowedFrequency;
+
+    uint32_t FilteredSclkFrequency;
+    uint32_t LastSclkFrequency;
+    uint32_t FilteredSclkFrequencyCnt;
+
+    uint8_t  LedEnable;
+    uint8_t  LedPin0;
+    uint8_t  LedPin1;
+    uint8_t  LedPin2;
+    uint32_t LedAndMask;
+
+    uint16_t FpsAlpha;
+    uint16_t DeltaTime;
+    uint32_t CurrentFps;
+    uint32_t FilteredFps;
+    uint32_t FrameCount;
+    uint32_t FrameCountLast;
+    uint16_t FpsTargetScalar;
+    uint16_t FpsWaterfallLimitScalar;
+    uint16_t FpsAlphaScalar;
+    uint16_t spare8;
+    SMU7_HystController_Data HystControllerData;
+};
+
+typedef struct SMU7_LocalDpmScoreboard SMU7_LocalDpmScoreboard;
+
+#define SMU7_MAX_VOLTAGE_CLIENTS 12
+
+typedef uint8_t (*VoltageChangeHandler_t)(uint16_t, uint8_t);
+
+#define VDDC_MASK    0x00007FFF
+#define VDDC_SHIFT   0
+#define VDDCI_MASK   0x3FFF8000
+#define VDDCI_SHIFT  15
+#define PHASES_MASK  0xC0000000
+#define PHASES_SHIFT 30
+
+typedef uint32_t SMU_VoltageLevel;
+
+struct SMU7_VoltageScoreboard
+{
+    SMU_VoltageLevel TargetVoltage;
+    uint16_t MaxVid;
+    uint8_t  HighestVidOffset;
+    uint8_t  CurrentVidOffset;
+
+    uint16_t CurrentVddc;
+    uint16_t CurrentVddci;
+
+
+    uint8_t  ControllerBusy;
+    uint8_t  CurrentVid;
+    uint8_t  CurrentVddciVid;
+    uint8_t  padding;
+
+    SMU_VoltageLevel RequestedVoltage[SMU7_MAX_VOLTAGE_CLIENTS];
+    SMU_VoltageLevel TargetVoltageState;
+    uint8_t  EnabledRequest[SMU7_MAX_VOLTAGE_CLIENTS];
+
+    uint8_t  padding2;
+    uint8_t  padding3;
+    uint8_t  ControllerEnable;
+    uint8_t  ControllerRunning;
+    uint16_t CurrentStdVoltageHiSidd;
+    uint16_t CurrentStdVoltageLoSidd;
+    uint8_t  OverrideVoltage;
+    uint8_t  padding4;
+    uint8_t  padding5;
+    uint8_t  CurrentPhases;
+
+    VoltageChangeHandler_t ChangeVddc;
+
+    VoltageChangeHandler_t ChangeVddci;
+    VoltageChangeHandler_t ChangePhase;
+    VoltageChangeHandler_t ChangeMvdd;
+
+    VoltageChangeHandler_t functionLinks[6];
+
+    uint16_t * VddcFollower1;
+
+    int16_t  Driver_OD_RequestedVidOffset1;
+    int16_t  Driver_OD_RequestedVidOffset2;
+
+};
+
+typedef struct SMU7_VoltageScoreboard SMU7_VoltageScoreboard;
+
+// -------------------------------------------------------------------------------------------------------------------------
+#define SMU7_MAX_PCIE_LINK_SPEEDS 3 /* 0:Gen1 1:Gen2 2:Gen3 */
+
+struct SMU7_PCIeLinkSpeedScoreboard
+{
+    uint8_t     DpmEnable;
+    uint8_t     DpmRunning;
+    uint8_t     DpmForce;
+    uint8_t     DpmForceLevel;
+
+    uint8_t     CurrentLinkSpeed;
+    uint8_t     EnabledLevelsChange;
+    uint16_t    AutoDpmInterval;
+
+    uint16_t    AutoDpmRange;
+    uint16_t    AutoDpmCount;
+
+    uint8_t     DpmMode;
+    uint8_t     AcpiReq;
+    uint8_t     AcpiAck;
+    uint8_t     CurrentLinkLevel;
+
+};
+
+typedef struct SMU7_PCIeLinkSpeedScoreboard SMU7_PCIeLinkSpeedScoreboard;
+
+// -------------------------------------------------------- CAC table ------------------------------------------------------
+#define SMU7_LKGE_LUT_NUM_OF_TEMP_ENTRIES 16
+#define SMU7_LKGE_LUT_NUM_OF_VOLT_ENTRIES 16
+
+#define SMU7_SCALE_I  7
+#define SMU7_SCALE_R 12
+
+struct SMU7_PowerScoreboard
+{
+    uint32_t GpuPower;
+
+    uint32_t VddcPower;
+    uint32_t VddcVoltage;
+    uint32_t VddcCurrent;
+
+    uint32_t MvddPower;
+    uint32_t MvddVoltage;
+    uint32_t MvddCurrent;
+
+    uint32_t RocPower;
+
+    uint16_t Telemetry_1_slope;
+    uint16_t Telemetry_2_slope;
+    int32_t  Telemetry_1_offset;
+    int32_t  Telemetry_2_offset;
+};
+typedef struct SMU7_PowerScoreboard SMU7_PowerScoreboard;
+
+// For FeatureEnables:
+#define SMU7_SCLK_DPM_CONFIG_MASK                        0x01
+#define SMU7_VOLTAGE_CONTROLLER_CONFIG_MASK              0x02
+#define SMU7_THERMAL_CONTROLLER_CONFIG_MASK              0x04
+#define SMU7_MCLK_DPM_CONFIG_MASK                        0x08
+#define SMU7_UVD_DPM_CONFIG_MASK                         0x10
+#define SMU7_VCE_DPM_CONFIG_MASK                         0x20
+#define SMU7_ACP_DPM_CONFIG_MASK                         0x40
+#define SMU7_SAMU_DPM_CONFIG_MASK                        0x80
+#define SMU7_PCIEGEN_DPM_CONFIG_MASK                    0x100
+
+#define SMU7_ACP_MCLK_HANDSHAKE_DISABLE                  0x00000001
+#define SMU7_ACP_SCLK_HANDSHAKE_DISABLE                  0x00000002
+#define SMU7_UVD_MCLK_HANDSHAKE_DISABLE                  0x00000100
+#define SMU7_UVD_SCLK_HANDSHAKE_DISABLE                  0x00000200
+#define SMU7_VCE_MCLK_HANDSHAKE_DISABLE                  0x00010000
+#define SMU7_VCE_SCLK_HANDSHAKE_DISABLE                  0x00020000
+
+// All 'soft registers' should be uint32_t.
+struct SMU73_SoftRegisters
+{
+    uint32_t        RefClockFrequency;
+    uint32_t        PmTimerPeriod;
+    uint32_t        FeatureEnables;
+
+    uint32_t        PreVBlankGap;
+    uint32_t        VBlankTimeout;
+    uint32_t        TrainTimeGap;
+
+    uint32_t        MvddSwitchTime;
+    uint32_t        LongestAcpiTrainTime;
+    uint32_t        AcpiDelay;
+    uint32_t        G5TrainTime;
+    uint32_t        DelayMpllPwron;
+    uint32_t        VoltageChangeTimeout;
+
+    uint32_t        HandshakeDisables;
+
+    uint8_t         DisplayPhy1Config;
+    uint8_t         DisplayPhy2Config;
+    uint8_t         DisplayPhy3Config;
+    uint8_t         DisplayPhy4Config;
+
+    uint8_t         DisplayPhy5Config;
+    uint8_t         DisplayPhy6Config;
+    uint8_t         DisplayPhy7Config;
+    uint8_t         DisplayPhy8Config;
+
+    uint32_t        AverageGraphicsActivity;
+    uint32_t        AverageMemoryActivity;
+    uint32_t        AverageGioActivity;
+
+    uint8_t         SClkDpmEnabledLevels;
+    uint8_t         MClkDpmEnabledLevels;
+    uint8_t         LClkDpmEnabledLevels;
+    uint8_t         PCIeDpmEnabledLevels;
+
+    uint8_t         UVDDpmEnabledLevels;
+    uint8_t         SAMUDpmEnabledLevels;
+    uint8_t         ACPDpmEnabledLevels;
+    uint8_t         VCEDpmEnabledLevels;
+
+    uint32_t        DRAM_LOG_ADDR_H;
+    uint32_t        DRAM_LOG_ADDR_L;
+    uint32_t        DRAM_LOG_PHY_ADDR_H;
+    uint32_t        DRAM_LOG_PHY_ADDR_L;
+    uint32_t        DRAM_LOG_BUFF_SIZE;
+    uint32_t        UlvEnterCount;
+    uint32_t        UlvTime;
+    uint32_t        UcodeLoadStatus;
+    uint32_t        Reserved[2];
+
+};
+
+typedef struct SMU73_SoftRegisters SMU73_SoftRegisters;
+
+struct SMU73_Firmware_Header
+{
+    uint32_t Digest[5];
+    uint32_t Version;
+    uint32_t HeaderSize;
+    uint32_t Flags;
+    uint32_t EntryPoint;
+    uint32_t CodeSize;
+    uint32_t ImageSize;
+
+    uint32_t Rtos;
+    uint32_t SoftRegisters;
+    uint32_t DpmTable;
+    uint32_t FanTable;
+    uint32_t CacConfigTable;
+    uint32_t CacStatusTable;
+
+
+    uint32_t mcRegisterTable;
+
+
+    uint32_t mcArbDramTimingTable;
+
+
+
+
+    uint32_t PmFuseTable;
+    uint32_t Globals;
+    uint32_t ClockStretcherTable;
+    uint32_t Reserved[41];
+    uint32_t Signature;
+};
+
+typedef struct SMU73_Firmware_Header SMU73_Firmware_Header;
+
+#define SMU7_FIRMWARE_HEADER_LOCATION 0x20000
+
+enum  DisplayConfig {
+    PowerDown = 1,
+    DP54x4,
+    DP54x2,
+    DP54x1,
+    DP27x4,
+    DP27x2,
+    DP27x1,
+    HDMI297,
+    HDMI162,
+    LVDS,
+    DP324x4,
+    DP324x2,
+    DP324x1
+};
+
+
+#define MC_BLOCK_COUNT 1
+#define CPL_BLOCK_COUNT 5
+#define SE_BLOCK_COUNT 15
+#define GC_BLOCK_COUNT 24
+
+struct SMU7_Local_Cac {
+  uint8_t BlockId;
+  uint8_t SignalId;
+  uint8_t Threshold;
+  uint8_t Padding;
+};
+
+typedef struct SMU7_Local_Cac SMU7_Local_Cac;
+
+struct SMU7_Local_Cac_Table {
+
+  SMU7_Local_Cac CplLocalCac[CPL_BLOCK_COUNT];
+  SMU7_Local_Cac McLocalCac[MC_BLOCK_COUNT];
+  SMU7_Local_Cac SeLocalCac[SE_BLOCK_COUNT];
+  SMU7_Local_Cac GcLocalCac[GC_BLOCK_COUNT];
+};
+
+typedef struct SMU7_Local_Cac_Table SMU7_Local_Cac_Table;
+
+#if !defined(SMC_MICROCODE)
+#pragma pack(pop)
+#endif
+
+// Description of Clock Gating bitmask for Tonga:
+// System Clock Gating
+#define CG_SYS_BITMASK_FIRST_BIT      0  // First bit of Sys CG bitmask
+#define CG_SYS_BITMASK_LAST_BIT       9  // Last bit of Sys CG bitmask
+#define CG_SYS_BIF_MGLS_SHIFT         0
+#define CG_SYS_ROM_SHIFT              1
+#define CG_SYS_MC_MGCG_SHIFT          2
+#define CG_SYS_MC_MGLS_SHIFT          3
+#define CG_SYS_SDMA_MGCG_SHIFT        4
+#define CG_SYS_SDMA_MGLS_SHIFT        5
+#define CG_SYS_DRM_MGCG_SHIFT         6
+#define CG_SYS_HDP_MGCG_SHIFT         7
+#define CG_SYS_HDP_MGLS_SHIFT         8
+#define CG_SYS_DRM_MGLS_SHIFT         9
+
+#define CG_SYS_BIF_MGLS_MASK          0x1
+#define CG_SYS_ROM_MASK               0x2
+#define CG_SYS_MC_MGCG_MASK           0x4
+#define CG_SYS_MC_MGLS_MASK           0x8
+#define CG_SYS_SDMA_MGCG_MASK         0x10
+#define CG_SYS_SDMA_MGLS_MASK         0x20
+#define CG_SYS_DRM_MGCG_MASK          0x40
+#define CG_SYS_HDP_MGCG_MASK          0x80
+#define CG_SYS_HDP_MGLS_MASK          0x100
+#define CG_SYS_DRM_MGLS_MASK          0x200
+
+// Graphics Clock Gating
+#define CG_GFX_BITMASK_FIRST_BIT      16 // First bit of Gfx CG bitmask
+#define CG_GFX_BITMASK_LAST_BIT       20 // Last bit of Gfx CG bitmask
+#define CG_GFX_CGCG_SHIFT             16
+#define CG_GFX_CGLS_SHIFT             17
+#define CG_CPF_MGCG_SHIFT             18
+#define CG_RLC_MGCG_SHIFT             19
+#define CG_GFX_OTHERS_MGCG_SHIFT      20
+
+#define CG_GFX_CGCG_MASK              0x00010000
+#define CG_GFX_CGLS_MASK              0x00020000
+#define CG_CPF_MGCG_MASK              0x00040000
+#define CG_RLC_MGCG_MASK              0x00080000
+#define CG_GFX_OTHERS_MGCG_MASK       0x00100000
+
+
+
+// Voltage Regulator Configuration
+// VR Config info is contained in dpmTable.VRConfig
+
+#define VRCONF_VDDC_MASK         0x000000FF
+#define VRCONF_VDDC_SHIFT        0
+#define VRCONF_VDDGFX_MASK       0x0000FF00
+#define VRCONF_VDDGFX_SHIFT      8
+#define VRCONF_VDDCI_MASK        0x00FF0000
+#define VRCONF_VDDCI_SHIFT       16
+#define VRCONF_MVDD_MASK         0xFF000000
+#define VRCONF_MVDD_SHIFT        24
+
+#define VR_MERGED_WITH_VDDC      0
+#define VR_SVI2_PLANE_1          1
+#define VR_SVI2_PLANE_2          2
+#define VR_SMIO_PATTERN_1        3
+#define VR_SMIO_PATTERN_2        4
+#define VR_STATIC_VOLTAGE        5
+
+// Clock Stretcher Configuration
+
+#define CLOCK_STRETCHER_MAX_ENTRIES 0x4
+#define CKS_LOOKUPTable_MAX_ENTRIES 0x4
+
+// The 'settings' field is subdivided in the following way:
+#define CLOCK_STRETCHER_SETTING_DDT_MASK             0x01
+#define CLOCK_STRETCHER_SETTING_DDT_SHIFT            0x0
+#define CLOCK_STRETCHER_SETTING_STRETCH_AMOUNT_MASK  0x1E
+#define CLOCK_STRETCHER_SETTING_STRETCH_AMOUNT_SHIFT 0x1
+#define CLOCK_STRETCHER_SETTING_ENABLE_MASK          0x80
+#define CLOCK_STRETCHER_SETTING_ENABLE_SHIFT         0x7
+
+struct SMU_ClockStretcherDataTableEntry {
+  uint8_t minVID;
+  uint8_t maxVID;
+
+
+  uint16_t setting;
+};
+typedef struct SMU_ClockStretcherDataTableEntry SMU_ClockStretcherDataTableEntry;
+
+struct SMU_ClockStretcherDataTable {
+  SMU_ClockStretcherDataTableEntry ClockStretcherDataTableEntry[CLOCK_STRETCHER_MAX_ENTRIES];
+};
+typedef struct SMU_ClockStretcherDataTable SMU_ClockStretcherDataTable;
+
+struct SMU_CKS_LOOKUPTableEntry {
+  uint16_t minFreq;
+  uint16_t maxFreq;
+
+  uint8_t setting;
+  uint8_t padding[3];
+};
+typedef struct SMU_CKS_LOOKUPTableEntry SMU_CKS_LOOKUPTableEntry;
+
+struct SMU_CKS_LOOKUPTable {
+  SMU_CKS_LOOKUPTableEntry CKS_LOOKUPTableEntry[CKS_LOOKUPTable_MAX_ENTRIES];
+};
+typedef struct SMU_CKS_LOOKUPTable SMU_CKS_LOOKUPTable;
+
+struct AgmAvfsData_t {
+  uint16_t avgPsmCount[28];
+  uint16_t minPsmCount[28];
+};
+typedef struct AgmAvfsData_t AgmAvfsData_t;
+
+// AVFS DEFINES
+
+enum VFT_COLUMNS {
+  SCLK0,
+  SCLK1,
+  SCLK2,
+  SCLK3,
+  SCLK4,
+  SCLK5,
+  SCLK6,
+  SCLK7,
+
+  NUM_VFT_COLUMNS
+};
+
+#define TEMP_RANGE_MAXSTEPS 12
+struct VFT_CELL_t {
+  uint16_t Voltage;
+};
+
+typedef struct VFT_CELL_t VFT_CELL_t;
+
+struct VFT_TABLE_t {
+  VFT_CELL_t    Cell[TEMP_RANGE_MAXSTEPS][NUM_VFT_COLUMNS];
+  uint16_t      AvfsGbv [NUM_VFT_COLUMNS];
+  uint16_t      BtcGbv  [NUM_VFT_COLUMNS];
+  uint16_t      Temperature [TEMP_RANGE_MAXSTEPS];
+
+  uint8_t       NumTemperatureSteps;
+  uint8_t       padding[3];
+};
+typedef struct VFT_TABLE_t VFT_TABLE_t;
+
+#endif
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/powerplay/inc/smu73_discrete.h
@@ -0,0 +1,799 @@
+/*
+ * Copyright 2015 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+#ifndef _SMU73_DISCRETE_H_
+#define _SMU73_DISCRETE_H_
+
+#include "smu73.h"
+
+#pragma pack(push, 1)
+
+struct SMIO_Pattern
+{
+  uint16_t Voltage;
+  uint8_t  Smio;
+  uint8_t  padding;
+};
+
+typedef struct SMIO_Pattern SMIO_Pattern;
+
+struct SMIO_Table
+{
+  SMIO_Pattern Pattern[SMU_MAX_SMIO_LEVELS];
+};
+
+typedef struct SMIO_Table SMIO_Table;
+
+struct SMU73_Discrete_GraphicsLevel {
+	uint32_t    MinVoltage;
+
+	uint32_t    SclkFrequency;
+
+	uint8_t     pcieDpmLevel;
+	uint8_t     DeepSleepDivId;
+	uint16_t    ActivityLevel;
+	uint32_t    CgSpllFuncCntl3;
+	uint32_t    CgSpllFuncCntl4;
+	uint32_t    SpllSpreadSpectrum;
+	uint32_t    SpllSpreadSpectrum2;
+	uint32_t    CcPwrDynRm;
+	uint32_t    CcPwrDynRm1;
+	uint8_t     SclkDid;
+	uint8_t     DisplayWatermark;
+	uint8_t     EnabledForActivity;
+	uint8_t     EnabledForThrottle;
+	uint8_t     UpHyst;
+	uint8_t     DownHyst;
+	uint8_t     VoltageDownHyst;
+	uint8_t     PowerThrottle;
+};
+
+typedef struct SMU73_Discrete_GraphicsLevel SMU73_Discrete_GraphicsLevel;
+
+struct SMU73_Discrete_ACPILevel {
+    uint32_t    Flags;
+    uint32_t MinVoltage;
+    uint32_t    SclkFrequency;
+    uint8_t     SclkDid;
+    uint8_t     DisplayWatermark;
+    uint8_t     DeepSleepDivId;
+    uint8_t     padding;
+    uint32_t    CgSpllFuncCntl;
+    uint32_t    CgSpllFuncCntl2;
+    uint32_t    CgSpllFuncCntl3;
+    uint32_t    CgSpllFuncCntl4;
+    uint32_t    SpllSpreadSpectrum;
+    uint32_t    SpllSpreadSpectrum2;
+    uint32_t    CcPwrDynRm;
+    uint32_t    CcPwrDynRm1;
+};
+
+typedef struct SMU73_Discrete_ACPILevel SMU73_Discrete_ACPILevel;
+
+struct SMU73_Discrete_Ulv {
+	uint32_t    CcPwrDynRm;
+	uint32_t    CcPwrDynRm1;
+	uint16_t    VddcOffset;
+	uint8_t     VddcOffsetVid;
+	uint8_t     VddcPhase;
+	uint32_t    Reserved;
+};
+
+typedef struct SMU73_Discrete_Ulv SMU73_Discrete_Ulv;
+
+struct SMU73_Discrete_MemoryLevel
+{
+    uint32_t MinVoltage;
+    uint32_t    MinMvdd;
+
+    uint32_t    MclkFrequency;
+
+    uint8_t     StutterEnable;
+    uint8_t     FreqRange;
+    uint8_t     EnabledForThrottle;
+    uint8_t     EnabledForActivity;
+
+    uint8_t     UpHyst;
+    uint8_t     DownHyst;
+    uint8_t     VoltageDownHyst;
+    uint8_t     padding;
+
+    uint16_t    ActivityLevel;
+    uint8_t     DisplayWatermark;
+    uint8_t     MclkDivider;
+};
+
+typedef struct SMU73_Discrete_MemoryLevel SMU73_Discrete_MemoryLevel;
+
+struct SMU73_Discrete_LinkLevel
+{
+    uint8_t     PcieGenSpeed;           ///< 0:PciE-gen1 1:PciE-gen2 2:PciE-gen3
+    uint8_t     PcieLaneCount;          ///< 1=x1, 2=x2, 3=x4, 4=x8, 5=x12, 6=x16 
+    uint8_t     EnabledForActivity;
+    uint8_t     SPC;
+    uint32_t    DownThreshold;
+    uint32_t    UpThreshold;
+    uint32_t    Reserved;
+};
+
+typedef struct SMU73_Discrete_LinkLevel SMU73_Discrete_LinkLevel;
+
+
+// MC ARB DRAM Timing registers.
+struct SMU73_Discrete_MCArbDramTimingTableEntry
+{
+    uint32_t McArbDramTiming;
+    uint32_t McArbDramTiming2;
+    uint8_t  McArbBurstTime;
+    uint8_t  TRRDS;
+    uint8_t  TRRDL;
+    uint8_t  padding;
+};
+
+typedef struct SMU73_Discrete_MCArbDramTimingTableEntry SMU73_Discrete_MCArbDramTimingTableEntry;
+
+struct SMU73_Discrete_MCArbDramTimingTable
+{
+    SMU73_Discrete_MCArbDramTimingTableEntry entries[SMU__NUM_SCLK_DPM_STATE][SMU__NUM_MCLK_DPM_LEVELS];
+};
+
+typedef struct SMU73_Discrete_MCArbDramTimingTable SMU73_Discrete_MCArbDramTimingTable;
+
+// UVD VCLK/DCLK state (level) definition.
+struct SMU73_Discrete_UvdLevel
+{
+    uint32_t VclkFrequency;
+    uint32_t DclkFrequency;
+    uint32_t MinVoltage;
+    uint8_t  VclkDivider;
+    uint8_t  DclkDivider;
+    uint8_t  padding[2];
+};
+
+typedef struct SMU73_Discrete_UvdLevel SMU73_Discrete_UvdLevel;
+
+// Clocks for other external blocks (VCE, ACP, SAMU).
+struct SMU73_Discrete_ExtClkLevel
+{
+    uint32_t Frequency;
+    uint32_t MinVoltage;
+    uint8_t  Divider;
+    uint8_t  padding[3];
+};
+
+typedef struct SMU73_Discrete_ExtClkLevel SMU73_Discrete_ExtClkLevel;
+
+struct SMU73_Discrete_StateInfo
+{
+    uint32_t SclkFrequency;
+    uint32_t MclkFrequency;
+    uint32_t VclkFrequency;
+    uint32_t DclkFrequency;
+    uint32_t SamclkFrequency;
+    uint32_t AclkFrequency;
+    uint32_t EclkFrequency;
+    uint16_t MvddVoltage;
+    uint16_t padding16;
+    uint8_t  DisplayWatermark;
+    uint8_t  McArbIndex;
+    uint8_t  McRegIndex;
+    uint8_t  SeqIndex;
+    uint8_t  SclkDid;
+    int8_t   SclkIndex;
+    int8_t   MclkIndex;
+    uint8_t  PCIeGen;
+
+};
+
+typedef struct SMU73_Discrete_StateInfo SMU73_Discrete_StateInfo;
+
+struct SMU73_Discrete_DpmTable
+{
+    // Multi-DPM controller settings
+    SMU73_PIDController                  GraphicsPIDController;
+    SMU73_PIDController                  MemoryPIDController;
+    SMU73_PIDController                  LinkPIDController;
+
+    uint32_t                            SystemFlags;
+
+    // SMIO masks for voltage and phase controls
+    uint32_t                            VRConfig;
+    uint32_t                            SmioMask1;
+    uint32_t                            SmioMask2;
+    SMIO_Table                          SmioTable1;
+    SMIO_Table                          SmioTable2;
+
+    uint32_t                            MvddLevelCount;
+
+
+    uint8_t                             BapmVddcVidHiSidd        [SMU73_MAX_LEVELS_VDDC];
+    uint8_t                             BapmVddcVidLoSidd        [SMU73_MAX_LEVELS_VDDC];
+    uint8_t                             BapmVddcVidHiSidd2       [SMU73_MAX_LEVELS_VDDC];
+
+    uint8_t                             GraphicsDpmLevelCount;
+    uint8_t                             MemoryDpmLevelCount;
+    uint8_t                             LinkLevelCount;
+    uint8_t                             MasterDeepSleepControl;
+
+    uint8_t                             UvdLevelCount;
+    uint8_t                             VceLevelCount;
+    uint8_t                             AcpLevelCount;
+    uint8_t                             SamuLevelCount;
+
+    uint8_t                             ThermOutGpio;
+    uint8_t                             ThermOutPolarity;
+    uint8_t                             ThermOutMode;
+    uint8_t                             BootPhases;
+    uint32_t                            Reserved[4];
+
+    // State table entries for each DPM state
+    SMU73_Discrete_GraphicsLevel        GraphicsLevel           [SMU73_MAX_LEVELS_GRAPHICS];
+    SMU73_Discrete_MemoryLevel          MemoryACPILevel;
+    SMU73_Discrete_MemoryLevel          MemoryLevel             [SMU73_MAX_LEVELS_MEMORY];
+    SMU73_Discrete_LinkLevel            LinkLevel               [SMU73_MAX_LEVELS_LINK];
+    SMU73_Discrete_ACPILevel            ACPILevel;
+    SMU73_Discrete_UvdLevel             UvdLevel                [SMU73_MAX_LEVELS_UVD];
+    SMU73_Discrete_ExtClkLevel          VceLevel                [SMU73_MAX_LEVELS_VCE];
+    SMU73_Discrete_ExtClkLevel          AcpLevel                [SMU73_MAX_LEVELS_ACP];
+    SMU73_Discrete_ExtClkLevel          SamuLevel               [SMU73_MAX_LEVELS_SAMU];
+    SMU73_Discrete_Ulv                  Ulv;
+
+    uint32_t                            SclkStepSize;
+    uint32_t                            Smio                    [SMU73_MAX_ENTRIES_SMIO];
+
+    uint8_t                             UvdBootLevel;
+    uint8_t                             VceBootLevel;
+    uint8_t                             AcpBootLevel;
+    uint8_t                             SamuBootLevel;
+
+    uint8_t                             GraphicsBootLevel;
+    uint8_t                             GraphicsVoltageChangeEnable;
+    uint8_t                             GraphicsThermThrottleEnable;
+    uint8_t                             GraphicsInterval;
+
+    uint8_t                             VoltageInterval;
+    uint8_t                             ThermalInterval;
+    uint16_t                            TemperatureLimitHigh;
+
+    uint16_t                            TemperatureLimitLow;
+    uint8_t                             MemoryBootLevel;
+    uint8_t                             MemoryVoltageChangeEnable;
+
+    uint16_t                            BootMVdd;
+    uint8_t                             MemoryInterval;
+    uint8_t                             MemoryThermThrottleEnable;
+
+    uint16_t                            VoltageResponseTime;
+    uint16_t                            PhaseResponseTime;
+
+    uint8_t                             PCIeBootLinkLevel;
+    uint8_t                             PCIeGenInterval;
+    uint8_t                             DTEInterval;
+    uint8_t                             DTEMode;
+
+    uint8_t                             SVI2Enable;
+    uint8_t                             VRHotGpio;
+    uint8_t                             AcDcGpio;
+    uint8_t                             ThermGpio;
+
+    uint16_t                            PPM_PkgPwrLimit;
+    uint16_t                            PPM_TemperatureLimit;
+
+    uint16_t                            DefaultTdp;
+    uint16_t                            TargetTdp;
+
+    uint16_t                            FpsHighThreshold;
+    uint16_t                            FpsLowThreshold;
+
+    uint16_t                            TemperatureLimitEdge;
+    uint16_t                            TemperatureLimitHotspot;
+    uint16_t                            TemperatureLimitLiquid1;
+    uint16_t                            TemperatureLimitLiquid2;
+    uint16_t                            TemperatureLimitVrVddc;
+    uint16_t                            TemperatureLimitVrMvdd;
+    uint16_t                            TemperatureLimitPlx;
+
+    uint16_t                            FanGainEdge;
+    uint16_t                            FanGainHotspot;
+    uint16_t                            FanGainLiquid;
+    uint16_t                            FanGainVrVddc;
+    uint16_t                            FanGainVrMvdd;
+    uint16_t                            FanGainPlx;
+    uint16_t                            FanGainHbm;
+
+    uint8_t                             Liquid1_I2C_address;
+    uint8_t                             Liquid2_I2C_address;
+    uint8_t                             Vr_I2C_address;
+    uint8_t                             Plx_I2C_address;
+
+    uint8_t                             GeminiMode;
+    uint8_t                             spare17[3];
+    uint32_t                            GeminiApertureHigh;
+    uint32_t                            GeminiApertureLow;
+
+    uint8_t                             Liquid_I2C_LineSCL;
+    uint8_t                             Liquid_I2C_LineSDA;
+    uint8_t                             Vr_I2C_LineSCL;
+    uint8_t                             Vr_I2C_LineSDA;
+    uint8_t                             Plx_I2C_LineSCL;
+    uint8_t                             Plx_I2C_LineSDA;
+
+    uint8_t                             spare1253[2];
+    uint32_t                            spare123[2];
+
+    uint8_t                             DTEAmbientTempBase;
+    uint8_t                             DTETjOffset;
+    uint8_t                             GpuTjMax;
+    uint8_t                             GpuTjHyst;
+
+    uint16_t                            BootVddc;
+    uint16_t                            BootVddci;
+
+    uint32_t                            BAPM_TEMP_GRADIENT;
+
+    uint32_t                            LowSclkInterruptThreshold;
+    uint32_t                            VddGfxReChkWait;
+
+    uint8_t                             ClockStretcherAmount;
+    uint8_t                             Sclk_CKS_masterEn0_7;
+    uint8_t                             Sclk_CKS_masterEn8_15;
+    uint8_t                             DPMFreezeAndForced;
+
+    uint8_t                             Sclk_voltageOffset[8];
+
+    SMU_ClockStretcherDataTable         ClockStretcherDataTable;
+    SMU_CKS_LOOKUPTable                 CKS_LOOKUPTable;
+};
+
+typedef struct SMU73_Discrete_DpmTable SMU73_Discrete_DpmTable;
+
+
+// --------------------------------------------------- Fan Table -----------------------------------------------------------
+struct SMU73_Discrete_FanTable
+{
+    uint16_t FdoMode;
+    int16_t  TempMin;
+    int16_t  TempMed;
+    int16_t  TempMax;
+    int16_t  Slope1;
+    int16_t  Slope2;
+    int16_t  FdoMin;
+    int16_t  HystUp;
+    int16_t  HystDown;
+    int16_t  HystSlope;
+    int16_t  TempRespLim;
+    int16_t  TempCurr;
+    int16_t  SlopeCurr;
+    int16_t  PwmCurr;
+    uint32_t RefreshPeriod;
+    int16_t  FdoMax;
+    uint8_t  TempSrc;
+    int8_t   Padding;
+};
+
+typedef struct SMU73_Discrete_FanTable SMU73_Discrete_FanTable;
+
+#define SMU7_DISCRETE_GPIO_SCLK_DEBUG             4
+#define SMU7_DISCRETE_GPIO_SCLK_DEBUG_BIT         (0x1 << SMU7_DISCRETE_GPIO_SCLK_DEBUG)
+
+
+
+struct SMU7_MclkDpmScoreboard
+{
+
+    uint32_t PercentageBusy;
+
+    int32_t  PIDError;
+    int32_t  PIDIntegral;
+    int32_t  PIDOutput;
+
+    uint32_t SigmaDeltaAccum;
+    uint32_t SigmaDeltaOutput;
+    uint32_t SigmaDeltaLevel;
+
+    uint32_t UtilizationSetpoint;
+
+    uint8_t  TdpClampMode;
+    uint8_t  TdcClampMode;
+    uint8_t  ThermClampMode;
+    uint8_t  VoltageBusy;
+
+    int8_t   CurrLevel;
+    int8_t   TargLevel;
+    uint8_t  LevelChangeInProgress;
+    uint8_t  UpHyst;
+
+    uint8_t  DownHyst;
+    uint8_t  VoltageDownHyst;
+    uint8_t  DpmEnable;
+    uint8_t  DpmRunning;
+
+    uint8_t  DpmForce;
+    uint8_t  DpmForceLevel;
+    uint8_t  DisplayWatermark;
+    uint8_t  McArbIndex;
+
+    uint32_t MinimumPerfMclk;
+
+    uint8_t  AcpiReq;
+    uint8_t  AcpiAck;
+    uint8_t  MclkSwitchInProgress;
+    uint8_t  MclkSwitchCritical;
+
+    uint8_t  IgnoreVBlank;
+    uint8_t  TargetMclkIndex;
+    uint8_t  TargetMvddIndex;
+    uint8_t  MclkSwitchResult;
+
+    uint16_t VbiFailureCount;
+    uint8_t  VbiWaitCounter;
+    uint8_t  EnabledLevelsChange;
+
+    uint16_t LevelResidencyCounters [SMU73_MAX_LEVELS_MEMORY];
+    uint16_t LevelSwitchCounters [SMU73_MAX_LEVELS_MEMORY];
+
+    void     (*TargetStateCalculator)(uint8_t);
+    void     (*SavedTargetStateCalculator)(uint8_t);
+
+    uint16_t AutoDpmInterval;
+    uint16_t AutoDpmRange;
+
+    uint16_t VbiTimeoutCount;
+    uint16_t MclkSwitchingTime;
+
+    uint8_t  fastSwitch;
+    uint8_t  Save_PIC_VDDGFX_EXIT;
+    uint8_t  Save_PIC_VDDGFX_ENTER;
+    uint8_t  padding;
+
+};
+
+typedef struct SMU7_MclkDpmScoreboard SMU7_MclkDpmScoreboard;
+
+struct SMU7_UlvScoreboard
+{
+    uint8_t     EnterUlv;
+    uint8_t     ExitUlv;
+    uint8_t     UlvActive;
+    uint8_t     WaitingForUlv;
+    uint8_t     UlvEnable;
+    uint8_t     UlvRunning;
+    uint8_t     UlvMasterEnable;
+    uint8_t     padding;
+    uint32_t    UlvAbortedCount;
+    uint32_t    UlvTimeStamp;
+};
+
+typedef struct SMU7_UlvScoreboard SMU7_UlvScoreboard;
+
+struct VddgfxSavedRegisters
+{
+  uint32_t GPU_DBG[3];
+  uint32_t MEC_BaseAddress_Hi;
+  uint32_t MEC_BaseAddress_Lo;
+  uint32_t THM_TMON0_CTRL2__RDIR_PRESENT;
+  uint32_t THM_TMON1_CTRL2__RDIR_PRESENT;
+  uint32_t CP_INT_CNTL;
+};
+
+typedef struct VddgfxSavedRegisters VddgfxSavedRegisters;
+
+struct SMU7_VddGfxScoreboard
+{
+    uint8_t     VddGfxEnable;
+    uint8_t     VddGfxActive;
+    uint8_t     VPUResetOccured;
+    uint8_t     padding;
+
+    uint32_t    VddGfxEnteredCount;
+    uint32_t    VddGfxAbortedCount;
+
+    uint32_t    VddGfxVid;
+
+    VddgfxSavedRegisters SavedRegisters;
+};
+
+typedef struct SMU7_VddGfxScoreboard SMU7_VddGfxScoreboard;
+
+struct SMU7_TdcLimitScoreboard {
+  uint8_t  Enable;
+  uint8_t  Running;
+  uint16_t Alpha;
+  uint32_t FilteredIddc;
+  uint32_t IddcLimit;
+  uint32_t IddcHyst;
+  SMU7_HystController_Data HystControllerData;
+};
+
+typedef struct SMU7_TdcLimitScoreboard SMU7_TdcLimitScoreboard;
+
+struct SMU7_PkgPwrLimitScoreboard {
+  uint8_t  Enable;
+  uint8_t  Running;
+  uint16_t Alpha;
+  uint32_t FilteredPkgPwr;
+  uint32_t Limit;
+  uint32_t Hyst;
+  uint32_t LimitFromDriver;
+  SMU7_HystController_Data HystControllerData;
+};
+
+typedef struct SMU7_PkgPwrLimitScoreboard SMU7_PkgPwrLimitScoreboard;
+
+struct SMU7_BapmScoreboard {
+  uint32_t source_powers[SMU73_DTE_SOURCES];
+  uint32_t source_powers_last[SMU73_DTE_SOURCES];
+  int32_t entity_temperatures[SMU73_NUM_GPU_TES];
+  int32_t initial_entity_temperatures[SMU73_NUM_GPU_TES];
+  int32_t Limit;
+  int32_t Hyst;
+  int32_t therm_influence_coeff_table[SMU73_DTE_ITERATIONS * SMU73_DTE_SOURCES * SMU73_DTE_SINKS * 2];
+  int32_t therm_node_table[SMU73_DTE_ITERATIONS * SMU73_DTE_SOURCES * SMU73_DTE_SINKS];
+  uint16_t ConfigTDPPowerScalar;
+  uint16_t FanSpeedPowerScalar;
+  uint16_t OverDrivePowerScalar;
+  uint16_t OverDriveLimitScalar;
+  uint16_t FinalPowerScalar;
+  uint8_t VariantID;
+  uint8_t spare997;
+
+  SMU7_HystController_Data HystControllerData;
+
+  int32_t temperature_gradient_slope;
+  int32_t temperature_gradient;
+  uint32_t measured_temperature;
+};
+
+
+typedef struct SMU7_BapmScoreboard SMU7_BapmScoreboard;
+
+struct SMU7_AcpiScoreboard {
+  uint32_t SavedInterruptMask[2];
+  uint8_t LastACPIRequest;
+  uint8_t CgBifResp;
+  uint8_t RequestType;
+  uint8_t Padding;
+  SMU73_Discrete_ACPILevel D0Level;
+};
+
+typedef struct SMU7_AcpiScoreboard SMU7_AcpiScoreboard;
+
+struct SMU_QuadraticCoeffs {
+  int32_t m1;
+  uint32_t b;
+
+  int16_t m2;
+  uint8_t m1_shift;
+  uint8_t m2_shift;
+};
+
+typedef struct SMU_QuadraticCoeffs SMU_QuadraticCoeffs;
+
+struct SMU73_Discrete_PmFuses {
+  /* dw0-dw1 */
+  uint8_t BapmVddCVidHiSidd[8];
+
+  /* dw2-dw3 */
+  uint8_t BapmVddCVidLoSidd[8];
+
+  /* dw4-dw5 */
+  uint8_t VddCVid[8];
+
+  /* dw1*/
+  uint8_t SviLoadLineEn;
+  uint8_t SviLoadLineVddC;
+  uint8_t SviLoadLineTrimVddC;
+  uint8_t SviLoadLineOffsetVddC;
+
+  /* dw2 */
+  uint16_t TDC_VDDC_PkgLimit;
+  uint8_t TDC_VDDC_ThrottleReleaseLimitPerc;
+  uint8_t TDC_MAWt;
+
+  /* dw3 */
+  uint8_t TdcWaterfallCtl;
+  uint8_t LPMLTemperatureMin;
+  uint8_t LPMLTemperatureMax;
+  uint8_t Reserved;
+
+  /* dw4-dw7 */
+  uint8_t LPMLTemperatureScaler[16];
+
+  /* dw8-dw9 */
+  int16_t FuzzyFan_ErrorSetDelta;
+  int16_t FuzzyFan_ErrorRateSetDelta;
+  int16_t FuzzyFan_PwmSetDelta;
+  uint16_t Reserved6;
+
+  /* dw10-dw14 */
+  uint8_t GnbLPML[16];
+
+  /* dw15 */
+  uint8_t GnbLPMLMaxVid;
+  uint8_t GnbLPMLMinVid;
+  uint8_t Reserved1[2];
+
+  /* dw16 */
+  uint16_t BapmVddCBaseLeakageHiSidd;
+  uint16_t BapmVddCBaseLeakageLoSidd;
+
+  /* AVFS */
+  uint16_t  VFT_Temp[3];
+  uint16_t  padding;
+
+  SMU_QuadraticCoeffs VFT_ATE[3];
+
+  SMU_QuadraticCoeffs AVFS_GB;
+  SMU_QuadraticCoeffs ATE_ACBTC_GB;
+
+  SMU_QuadraticCoeffs P2V;
+
+  uint32_t PsmCharzFreq;
+
+  uint16_t InversionVoltage;
+  uint16_t PsmCharzTemp;
+
+  uint32_t EnabledAvfsModules;
+};
+
+typedef struct SMU73_Discrete_PmFuses SMU73_Discrete_PmFuses;
+
+struct SMU7_Discrete_Log_Header_Table {
+  uint32_t    version;
+  uint32_t    asic_id;
+  uint16_t    flags;
+  uint16_t    entry_size;
+  uint32_t    total_size;
+  uint32_t    num_of_entries;
+  uint8_t     type;
+  uint8_t     mode;
+  uint8_t     filler_0[2];
+  uint32_t    filler_1[2];
+};
+
+typedef struct SMU7_Discrete_Log_Header_Table SMU7_Discrete_Log_Header_Table;
+
+struct SMU7_Discrete_Log_Cntl {
+    uint8_t             Enabled;
+    uint8_t             Type;
+    uint8_t             padding[2];
+    uint32_t            BufferSize;
+    uint32_t            SamplesLogged;
+    uint32_t            SampleSize;
+    uint32_t            AddrL;
+    uint32_t            AddrH;
+};
+
+typedef struct SMU7_Discrete_Log_Cntl SMU7_Discrete_Log_Cntl;
+
+#define CAC_ACC_NW_NUM_OF_SIGNALS 87
+
+struct SMU7_Discrete_Cac_Collection_Table {
+  uint32_t temperature;
+  uint32_t cac_acc_nw[CAC_ACC_NW_NUM_OF_SIGNALS];
+};
+
+typedef struct SMU7_Discrete_Cac_Collection_Table SMU7_Discrete_Cac_Collection_Table;
+
+struct SMU7_Discrete_Cac_Verification_Table {
+  uint32_t VddcTotalPower;
+  uint32_t VddcLeakagePower;
+  uint32_t VddcConstantPower;
+  uint32_t VddcGfxDynamicPower;
+  uint32_t VddcUvdDynamicPower;
+  uint32_t VddcVceDynamicPower;
+  uint32_t VddcAcpDynamicPower;
+  uint32_t VddcPcieDynamicPower;
+  uint32_t VddcDceDynamicPower;
+  uint32_t VddcCurrent;
+  uint32_t VddcVoltage;
+  uint32_t VddciTotalPower;
+  uint32_t VddciLeakagePower;
+  uint32_t VddciConstantPower;
+  uint32_t VddciDynamicPower;
+  uint32_t Vddr1TotalPower;
+  uint32_t Vddr1LeakagePower;
+  uint32_t Vddr1ConstantPower;
+  uint32_t Vddr1DynamicPower;
+  uint32_t spare[4];
+  uint32_t temperature;
+};
+
+typedef struct SMU7_Discrete_Cac_Verification_Table SMU7_Discrete_Cac_Verification_Table;
+
+struct SMU7_Discrete_Pm_Status_Table {
+  //Thermal entities
+  int32_t  T_meas_max[SMU73_THERMAL_INPUT_LOOP_COUNT];
+  int32_t  T_meas_acc[SMU73_THERMAL_INPUT_LOOP_COUNT];
+  int32_t  T_meas_acc_cnt[SMU73_THERMAL_INPUT_LOOP_COUNT];
+  uint32_t T_hbm_acc;
+
+  //Voltage domains
+  uint32_t I_calc_max;
+  uint32_t I_calc_acc;
+  uint32_t P_meas_acc;
+  uint32_t V_meas_load_acc;
+  uint32_t I_meas_acc;
+  uint32_t P_meas_acc_vddci;
+  uint32_t V_meas_load_acc_vddci;
+  uint32_t I_meas_acc_vddci;
+
+  //Frequency
+  uint16_t Sclk_dpm_residency[8];
+  uint16_t Uvd_dpm_residency[8];
+  uint16_t Vce_dpm_residency[8];
+
+  //Chip
+  uint32_t P_roc_acc;
+  uint32_t PkgPwr_max;
+  uint32_t PkgPwr_acc;
+  uint32_t MclkSwitchingTime_max;
+  uint32_t MclkSwitchingTime_acc;
+  uint32_t FanPwm_acc;
+  uint32_t FanRpm_acc;
+  uint32_t Gfx_busy_acc;
+  uint32_t Mc_busy_acc;
+  uint32_t Fps_acc;
+
+  uint32_t AccCnt;
+};
+
+typedef struct SMU7_Discrete_Pm_Status_Table SMU7_Discrete_Pm_Status_Table;
+
+//FIXME THESE NEED TO BE UPDATED
+#define SMU7_SCLK_CAC 0x561
+#define SMU7_MCLK_CAC 0xF9
+#define SMU7_VCLK_CAC 0x2DE
+#define SMU7_DCLK_CAC 0x2DE
+#define SMU7_ECLK_CAC 0x25E
+#define SMU7_ACLK_CAC 0x25E
+#define SMU7_SAMCLK_CAC 0x25E
+#define SMU7_DISPCLK_CAC 0x100
+#define SMU7_CAC_CONSTANT 0x2EE3430
+#define SMU7_CAC_CONSTANT_SHIFT 18
+
+#define SMU7_VDDCI_MCLK_CONST        1765
+#define SMU7_VDDCI_MCLK_CONST_SHIFT  16
+#define SMU7_VDDCI_VDDCI_CONST       50958
+#define SMU7_VDDCI_VDDCI_CONST_SHIFT 14
+#define SMU7_VDDCI_CONST             11781
+#define SMU7_VDDCI_STROBE_PWR        1331
+
+#define SMU7_VDDR1_CONST            693
+#define SMU7_VDDR1_CAC_WEIGHT       20
+#define SMU7_VDDR1_CAC_WEIGHT_SHIFT 19
+#define SMU7_VDDR1_STROBE_PWR       512
+
+#define SMU7_AREA_COEFF_UVD 0xA78
+#define SMU7_AREA_COEFF_VCE 0x190A
+#define SMU7_AREA_COEFF_ACP 0x22D1
+#define SMU7_AREA_COEFF_SAMU 0x534
+
+//ThermOutMode values
+#define SMU7_THERM_OUT_MODE_DISABLE       0x0
+#define SMU7_THERM_OUT_MODE_THERM_ONLY    0x1
+#define SMU7_THERM_OUT_MODE_THERM_VRHOT   0x2
+
+#pragma pack(pop)
+
+#endif
+
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/powerplay/inc/smu7_discrete.h
@@ -0,0 +1,514 @@
+/*
+ * Copyright 2013 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#ifndef SMU7_DISCRETE_H
+#define SMU7_DISCRETE_H
+
+#include "smu7.h"
+
+#pragma pack(push, 1)
+
+#define SMU7_DTE_ITERATIONS 5
+#define SMU7_DTE_SOURCES 3
+#define SMU7_DTE_SINKS 1
+#define SMU7_NUM_CPU_TES 0
+#define SMU7_NUM_GPU_TES 1
+#define SMU7_NUM_NON_TES 2
+
+struct SMU7_SoftRegisters
+{
+    uint32_t        RefClockFrequency;
+    uint32_t        PmTimerP;
+    uint32_t        FeatureEnables;
+    uint32_t        PreVBlankGap;
+    uint32_t        VBlankTimeout;
+    uint32_t        TrainTimeGap;
+
+    uint32_t        MvddSwitchTime;
+    uint32_t        LongestAcpiTrainTime;
+    uint32_t        AcpiDelay;
+    uint32_t        G5TrainTime;
+    uint32_t        DelayMpllPwron;
+    uint32_t        VoltageChangeTimeout;
+    uint32_t        HandshakeDisables;
+
+    uint8_t         DisplayPhy1Config;
+    uint8_t         DisplayPhy2Config;
+    uint8_t         DisplayPhy3Config;
+    uint8_t         DisplayPhy4Config;
+
+    uint8_t         DisplayPhy5Config;
+    uint8_t         DisplayPhy6Config;
+    uint8_t         DisplayPhy7Config;
+    uint8_t         DisplayPhy8Config;
+
+    uint32_t        AverageGraphicsA;
+    uint32_t        AverageMemoryA;
+    uint32_t        AverageGioA;
+
+    uint8_t         SClkDpmEnabledLevels;
+    uint8_t         MClkDpmEnabledLevels;
+    uint8_t         LClkDpmEnabledLevels;
+    uint8_t         PCIeDpmEnabledLevels;
+
+    uint8_t         UVDDpmEnabledLevels;
+    uint8_t         SAMUDpmEnabledLevels;
+    uint8_t         ACPDpmEnabledLevels;
+    uint8_t         VCEDpmEnabledLevels;
+
+    uint32_t        DRAM_LOG_ADDR_H;
+    uint32_t        DRAM_LOG_ADDR_L;
+    uint32_t        DRAM_LOG_PHY_ADDR_H;
+    uint32_t        DRAM_LOG_PHY_ADDR_L;
+    uint32_t        DRAM_LOG_BUFF_SIZE;
+    uint32_t        UlvEnterC;
+    uint32_t        UlvTime;
+    uint32_t        Reserved[3];
+
+};
+
+typedef struct SMU7_SoftRegisters SMU7_SoftRegisters;
+
+struct SMU7_Discrete_VoltageLevel
+{
+    uint16_t    Voltage;
+    uint16_t    StdVoltageHiSidd;
+    uint16_t    StdVoltageLoSidd;
+    uint8_t     Smio;
+    uint8_t     padding;
+};
+
+typedef struct SMU7_Discrete_VoltageLevel SMU7_Discrete_VoltageLevel;
+
+struct SMU7_Discrete_GraphicsLevel
+{
+    uint32_t    Flags;
+    uint32_t    MinVddc;
+    uint32_t    MinVddcPhases;
+
+    uint32_t    SclkFrequency;
+
+    uint8_t     padding1[2];
+    uint16_t    ActivityLevel;
+
+    uint32_t    CgSpllFuncCntl3;
+    uint32_t    CgSpllFuncCntl4;
+    uint32_t    SpllSpreadSpectrum;
+    uint32_t    SpllSpreadSpectrum2;
+    uint32_t    CcPwrDynRm;
+    uint32_t    CcPwrDynRm1;
+    uint8_t     SclkDid;
+    uint8_t     DisplayWatermark;
+    uint8_t     EnabledForActivity;
+    uint8_t     EnabledForThrottle;
+    uint8_t     UpH;
+    uint8_t     DownH;
+    uint8_t     VoltageDownH;
+    uint8_t     PowerThrottle;
+    uint8_t     DeepSleepDivId;
+    uint8_t     padding[3];
+};
+
+typedef struct SMU7_Discrete_GraphicsLevel SMU7_Discrete_GraphicsLevel;
+
+struct SMU7_Discrete_ACPILevel
+{
+    uint32_t    Flags;
+    uint32_t    MinVddc;
+    uint32_t    MinVddcPhases;
+    uint32_t    SclkFrequency;
+    uint8_t     SclkDid;
+    uint8_t     DisplayWatermark;
+    uint8_t     DeepSleepDivId;
+    uint8_t     padding;
+    uint32_t    CgSpllFuncCntl;
+    uint32_t    CgSpllFuncCntl2;
+    uint32_t    CgSpllFuncCntl3;
+    uint32_t    CgSpllFuncCntl4;
+    uint32_t    SpllSpreadSpectrum;
+    uint32_t    SpllSpreadSpectrum2;
+    uint32_t    CcPwrDynRm;
+    uint32_t    CcPwrDynRm1;
+};
+
+typedef struct SMU7_Discrete_ACPILevel SMU7_Discrete_ACPILevel;
+
+struct SMU7_Discrete_Ulv
+{
+    uint32_t    CcPwrDynRm;
+    uint32_t    CcPwrDynRm1;
+    uint16_t    VddcOffset;
+    uint8_t     VddcOffsetVid;
+    uint8_t     VddcPhase;
+    uint32_t    Reserved;
+};
+
+typedef struct SMU7_Discrete_Ulv SMU7_Discrete_Ulv;
+
+struct SMU7_Discrete_MemoryLevel
+{
+    uint32_t    MinVddc;
+    uint32_t    MinVddcPhases;
+    uint32_t    MinVddci;
+    uint32_t    MinMvdd;
+
+    uint32_t    MclkFrequency;
+
+    uint8_t     EdcReadEnable;
+    uint8_t     EdcWriteEnable;
+    uint8_t     RttEnable;
+    uint8_t     StutterEnable;
+
+    uint8_t     StrobeEnable;
+    uint8_t     StrobeRatio;
+    uint8_t     EnabledForThrottle;
+    uint8_t     EnabledForActivity;
+
+    uint8_t     UpH;
+    uint8_t     DownH;
+    uint8_t     VoltageDownH;
+    uint8_t     padding;
+
+    uint16_t    ActivityLevel;
+    uint8_t     DisplayWatermark;
+    uint8_t     padding1;
+
+    uint32_t    MpllFuncCntl;
+    uint32_t    MpllFuncCntl_1;
+    uint32_t    MpllFuncCntl_2;
+    uint32_t    MpllAdFuncCntl;
+    uint32_t    MpllDqFuncCntl;
+    uint32_t    MclkPwrmgtCntl;
+    uint32_t    DllCntl;
+    uint32_t    MpllSs1;
+    uint32_t    MpllSs2;
+};
+
+typedef struct SMU7_Discrete_MemoryLevel SMU7_Discrete_MemoryLevel;
+
+struct SMU7_Discrete_LinkLevel
+{
+    uint8_t     PcieGenSpeed;
+    uint8_t     PcieLaneCount;
+    uint8_t     EnabledForActivity;
+    uint8_t     Padding;
+    uint32_t    DownT;
+    uint32_t    UpT;
+    uint32_t    Reserved;
+};
+
+typedef struct SMU7_Discrete_LinkLevel SMU7_Discrete_LinkLevel;
+
+
+struct SMU7_Discrete_MCArbDramTimingTableEntry
+{
+    uint32_t McArbDramTiming;
+    uint32_t McArbDramTiming2;
+    uint8_t  McArbBurstTime;
+    uint8_t  padding[3];
+};
+
+typedef struct SMU7_Discrete_MCArbDramTimingTableEntry SMU7_Discrete_MCArbDramTimingTableEntry;
+
+struct SMU7_Discrete_MCArbDramTimingTable
+{
+    SMU7_Discrete_MCArbDramTimingTableEntry entries[SMU__NUM_SCLK_DPM_STATE][SMU__NUM_MCLK_DPM_LEVELS];
+};
+
+typedef struct SMU7_Discrete_MCArbDramTimingTable SMU7_Discrete_MCArbDramTimingTable;
+
+struct SMU7_Discrete_UvdLevel
+{
+    uint32_t VclkFrequency;
+    uint32_t DclkFrequency;
+    uint16_t MinVddc;
+    uint8_t  MinVddcPhases;
+    uint8_t  VclkDivider;
+    uint8_t  DclkDivider;
+    uint8_t  padding[3];
+};
+
+typedef struct SMU7_Discrete_UvdLevel SMU7_Discrete_UvdLevel;
+
+struct SMU7_Discrete_ExtClkLevel
+{
+    uint32_t Frequency;
+    uint16_t MinVoltage;
+    uint8_t  MinPhases;
+    uint8_t  Divider;
+};
+
+typedef struct SMU7_Discrete_ExtClkLevel SMU7_Discrete_ExtClkLevel;
+
+struct SMU7_Discrete_StateInfo
+{
+    uint32_t SclkFrequency;
+    uint32_t MclkFrequency;
+    uint32_t VclkFrequency;
+    uint32_t DclkFrequency;
+    uint32_t SamclkFrequency;
+    uint32_t AclkFrequency;
+    uint32_t EclkFrequency;
+    uint16_t MvddVoltage;
+    uint16_t padding16;
+    uint8_t  DisplayWatermark;
+    uint8_t  McArbIndex;
+    uint8_t  McRegIndex;
+    uint8_t  SeqIndex;
+    uint8_t  SclkDid;
+    int8_t   SclkIndex;
+    int8_t   MclkIndex;
+    uint8_t  PCIeGen;
+
+};
+
+typedef struct SMU7_Discrete_StateInfo SMU7_Discrete_StateInfo;
+
+
+struct SMU7_Discrete_DpmTable
+{
+    SMU7_PIDController                  GraphicsPIDController;
+    SMU7_PIDController                  MemoryPIDController;
+    SMU7_PIDController                  LinkPIDController;
+
+    uint32_t                            SystemFlags;
+
+
+    uint32_t                            SmioMaskVddcVid;
+    uint32_t                            SmioMaskVddcPhase;
+    uint32_t                            SmioMaskVddciVid;
+    uint32_t                            SmioMaskMvddVid;
+
+    uint32_t                            VddcLevelCount;
+    uint32_t                            VddciLevelCount;
+    uint32_t                            MvddLevelCount;
+
+    SMU7_Discrete_VoltageLevel          VddcLevel               [SMU7_MAX_LEVELS_VDDC];
+//    SMU7_Discrete_VoltageLevel          VddcStandardReference   [SMU7_MAX_LEVELS_VDDC];
+    SMU7_Discrete_VoltageLevel          VddciLevel              [SMU7_MAX_LEVELS_VDDCI];
+    SMU7_Discrete_VoltageLevel          MvddLevel               [SMU7_MAX_LEVELS_MVDD];
+
+    uint8_t                             GraphicsDpmLevelCount;
+    uint8_t                             MemoryDpmLevelCount;
+    uint8_t                             LinkLevelCount;
+    uint8_t                             UvdLevelCount;
+    uint8_t                             VceLevelCount;
+    uint8_t                             AcpLevelCount;
+    uint8_t                             SamuLevelCount;
+    uint8_t                             MasterDeepSleepControl;
+    uint32_t                            Reserved[5];
+//    uint32_t                            SamuDefaultLevel;
+
+    SMU7_Discrete_GraphicsLevel         GraphicsLevel           [SMU7_MAX_LEVELS_GRAPHICS];
+    SMU7_Discrete_MemoryLevel           MemoryACPILevel;
+    SMU7_Discrete_MemoryLevel           MemoryLevel             [SMU7_MAX_LEVELS_MEMORY];
+    SMU7_Discrete_LinkLevel             LinkLevel               [SMU7_MAX_LEVELS_LINK];
+    SMU7_Discrete_ACPILevel             ACPILevel;
+    SMU7_Discrete_UvdLevel              UvdLevel                [SMU7_MAX_LEVELS_UVD];
+    SMU7_Discrete_ExtClkLevel           VceLevel                [SMU7_MAX_LEVELS_VCE];
+    SMU7_Discrete_ExtClkLevel           AcpLevel                [SMU7_MAX_LEVELS_ACP];
+    SMU7_Discrete_ExtClkLevel           SamuLevel               [SMU7_MAX_LEVELS_SAMU];
+    SMU7_Discrete_Ulv                   Ulv;
+
+    uint32_t                            SclkStepSize;
+    uint32_t                            Smio                    [SMU7_MAX_ENTRIES_SMIO];
+
+    uint8_t                             UvdBootLevel;
+    uint8_t                             VceBootLevel;
+    uint8_t                             AcpBootLevel;
+    uint8_t                             SamuBootLevel;
+
+    uint8_t                             UVDInterval;
+    uint8_t                             VCEInterval;
+    uint8_t                             ACPInterval;
+    uint8_t                             SAMUInterval;
+
+    uint8_t                             GraphicsBootLevel;
+    uint8_t                             GraphicsVoltageChangeEnable;
+    uint8_t                             GraphicsThermThrottleEnable;
+    uint8_t                             GraphicsInterval;
+
+    uint8_t                             VoltageInterval;
+    uint8_t                             ThermalInterval;
+    uint16_t                            TemperatureLimitHigh;
+
+    uint16_t                            TemperatureLimitLow;
+    uint8_t                             MemoryBootLevel;
+    uint8_t                             MemoryVoltageChangeEnable;
+
+    uint8_t                             MemoryInterval;
+    uint8_t                             MemoryThermThrottleEnable;
+    uint16_t                            VddcVddciDelta;
+
+    uint16_t                            VoltageResponseTime;
+    uint16_t                            PhaseResponseTime;
+
+    uint8_t                             PCIeBootLinkLevel;
+    uint8_t                             PCIeGenInterval;
+    uint8_t                             DTEInterval;
+    uint8_t                             DTEMode;
+
+    uint8_t                             SVI2Enable;
+    uint8_t                             VRHotGpio;
+    uint8_t                             AcDcGpio;
+    uint8_t                             ThermGpio;
+
+    uint16_t                            PPM_PkgPwrLimit;
+    uint16_t                            PPM_TemperatureLimit;
+
+    uint16_t                            DefaultTdp;
+    uint16_t                            TargetTdp;
+
+    uint16_t                            FpsHighT;
+    uint16_t                            FpsLowT;
+
+    uint16_t                            BAPMTI_R  [SMU7_DTE_ITERATIONS][SMU7_DTE_SOURCES][SMU7_DTE_SINKS];
+    uint16_t                            BAPMTI_RC [SMU7_DTE_ITERATIONS][SMU7_DTE_SOURCES][SMU7_DTE_SINKS];
+
+    uint8_t                             DTEAmbientTempBase;
+    uint8_t                             DTETjOffset;
+    uint8_t                             GpuTjMax;
+    uint8_t                             GpuTjHyst;
+
+    uint16_t                            BootVddc;
+    uint16_t                            BootVddci;
+
+    uint16_t                            BootMVdd;
+    uint16_t                            padding;
+
+    uint32_t                            BAPM_TEMP_GRADIENT;
+
+    uint32_t                            LowSclkInterruptT;
+};
+
+typedef struct SMU7_Discrete_DpmTable SMU7_Discrete_DpmTable;
+
+#define SMU7_DISCRETE_MC_REGISTER_ARRAY_SIZE 16
+#define SMU7_DISCRETE_MC_REGISTER_ARRAY_SET_COUNT SMU7_MAX_LEVELS_MEMORY
+
+struct SMU7_Discrete_MCRegisterAddress
+{
+    uint16_t s0;
+    uint16_t s1;
+};
+
+typedef struct SMU7_Discrete_MCRegisterAddress SMU7_Discrete_MCRegisterAddress;
+
+struct SMU7_Discrete_MCRegisterSet
+{
+    uint32_t value[SMU7_DISCRETE_MC_REGISTER_ARRAY_SIZE];
+};
+
+typedef struct SMU7_Discrete_MCRegisterSet SMU7_Discrete_MCRegisterSet;
+
+struct SMU7_Discrete_MCRegisters
+{
+    uint8_t                             last;
+    uint8_t                             reserved[3];
+    SMU7_Discrete_MCRegisterAddress     address[SMU7_DISCRETE_MC_REGISTER_ARRAY_SIZE];
+    SMU7_Discrete_MCRegisterSet         data[SMU7_DISCRETE_MC_REGISTER_ARRAY_SET_COUNT];
+};
+
+typedef struct SMU7_Discrete_MCRegisters SMU7_Discrete_MCRegisters;
+
+struct SMU7_Discrete_FanTable
+{
+	uint16_t FdoMode;
+	int16_t  TempMin;
+	int16_t  TempMed;
+	int16_t  TempMax;
+	int16_t  Slope1;
+	int16_t  Slope2;
+	int16_t  FdoMin;
+	int16_t  HystUp;
+	int16_t  HystDown;
+	int16_t  HystSlope;
+	int16_t  TempRespLim;
+	int16_t  TempCurr;
+	int16_t  SlopeCurr;
+	int16_t  PwmCurr;
+	uint32_t RefreshPeriod;
+	int16_t  FdoMax;
+	uint8_t  TempSrc;
+	int8_t   Padding;
+};
+
+typedef struct SMU7_Discrete_FanTable SMU7_Discrete_FanTable;
+
+
+struct SMU7_Discrete_PmFuses {
+  // dw0-dw1
+  uint8_t BapmVddCVidHiSidd[8];
+
+  // dw2-dw3
+  uint8_t BapmVddCVidLoSidd[8];
+
+  // dw4-dw5
+  uint8_t VddCVid[8];
+
+  // dw6
+  uint8_t SviLoadLineEn;
+  uint8_t SviLoadLineVddC;
+  uint8_t SviLoadLineTrimVddC;
+  uint8_t SviLoadLineOffsetVddC;
+
+  // dw7
+  uint16_t TDC_VDDC_PkgLimit;
+  uint8_t TDC_VDDC_ThrottleReleaseLimitPerc;
+  uint8_t TDC_MAWt;
+
+  // dw8
+  uint8_t TdcWaterfallCtl;
+  uint8_t LPMLTemperatureMin;
+  uint8_t LPMLTemperatureMax;
+  uint8_t Reserved;
+
+  // dw9-dw10
+  uint8_t BapmVddCVidHiSidd2[8];
+
+  // dw11-dw12
+  int16_t FuzzyFan_ErrorSetDelta;
+  int16_t FuzzyFan_ErrorRateSetDelta;
+  int16_t FuzzyFan_PwmSetDelta;
+  uint16_t CalcMeasPowerBlend;
+
+  // dw13-dw16
+  uint8_t GnbLPML[16];
+
+  // dw17
+  uint8_t GnbLPMLMaxVid;
+  uint8_t GnbLPMLMinVid;
+  uint8_t Reserved1[2];
+
+  // dw18
+  uint16_t BapmVddCBaseLeakageHiSidd;
+  uint16_t BapmVddCBaseLeakageLoSidd;
+};
+
+typedef struct SMU7_Discrete_PmFuses SMU7_Discrete_PmFuses;
+
+
+#pragma pack(pop)
+
+#endif
+
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/powerplay/inc/smu7_fusion.h
@@ -0,0 +1,300 @@
+/*
+ * Copyright 2013 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#ifndef SMU7_FUSION_H
+#define SMU7_FUSION_H
+
+#include "smu7.h"
+
+#pragma pack(push, 1)
+
+#define SMU7_DTE_ITERATIONS 5
+#define SMU7_DTE_SOURCES 5
+#define SMU7_DTE_SINKS 3
+#define SMU7_NUM_CPU_TES 2
+#define SMU7_NUM_GPU_TES 1
+#define SMU7_NUM_NON_TES 2
+
+// All 'soft registers' should be uint32_t.
+struct SMU7_SoftRegisters
+{
+    uint32_t        RefClockFrequency;
+    uint32_t        PmTimerP;
+    uint32_t        FeatureEnables;
+    uint32_t        HandshakeDisables;
+
+    uint8_t         DisplayPhy1Config;
+    uint8_t         DisplayPhy2Config;
+    uint8_t         DisplayPhy3Config;
+    uint8_t         DisplayPhy4Config;
+
+    uint8_t         DisplayPhy5Config;
+    uint8_t         DisplayPhy6Config;
+    uint8_t         DisplayPhy7Config;
+    uint8_t         DisplayPhy8Config;
+
+    uint32_t        AverageGraphicsA;
+    uint32_t        AverageMemoryA;
+    uint32_t        AverageGioA;
+
+    uint8_t         SClkDpmEnabledLevels;
+    uint8_t         MClkDpmEnabledLevels;
+    uint8_t         LClkDpmEnabledLevels;
+    uint8_t         PCIeDpmEnabledLevels;
+
+    uint8_t         UVDDpmEnabledLevels;
+    uint8_t         SAMUDpmEnabledLevels;
+    uint8_t         ACPDpmEnabledLevels;
+    uint8_t         VCEDpmEnabledLevels;
+
+    uint32_t        DRAM_LOG_ADDR_H;
+    uint32_t        DRAM_LOG_ADDR_L;
+    uint32_t        DRAM_LOG_PHY_ADDR_H;
+    uint32_t        DRAM_LOG_PHY_ADDR_L;
+    uint32_t        DRAM_LOG_BUFF_SIZE;
+    uint32_t        UlvEnterC;
+    uint32_t        UlvTime;
+    uint32_t        Reserved[3];
+
+};
+
+typedef struct SMU7_SoftRegisters SMU7_SoftRegisters;
+
+struct SMU7_Fusion_GraphicsLevel
+{
+    uint32_t    MinVddNb;
+
+    uint32_t    SclkFrequency;
+
+    uint8_t     Vid;
+    uint8_t     VidOffset;
+    uint16_t    AT;
+
+    uint8_t     PowerThrottle;
+    uint8_t     GnbSlow;
+    uint8_t     ForceNbPs1;
+    uint8_t     SclkDid;
+
+    uint8_t     DisplayWatermark;
+    uint8_t     EnabledForActivity;
+    uint8_t     EnabledForThrottle;
+    uint8_t     UpH;
+
+    uint8_t     DownH;
+    uint8_t     VoltageDownH;
+    uint8_t     DeepSleepDivId;
+
+    uint8_t     ClkBypassCntl;
+
+    uint32_t    reserved;
+};
+
+typedef struct SMU7_Fusion_GraphicsLevel SMU7_Fusion_GraphicsLevel;
+
+struct SMU7_Fusion_GIOLevel
+{
+    uint8_t     EnabledForActivity;
+    uint8_t     LclkDid;
+    uint8_t     Vid;
+    uint8_t     VoltageDownH;
+
+    uint32_t    MinVddNb;
+
+    uint16_t    ResidencyCounter;
+    uint8_t     UpH;
+    uint8_t     DownH;
+
+    uint32_t    LclkFrequency;
+
+    uint8_t     ActivityLevel;
+    uint8_t     EnabledForThrottle;
+
+    uint8_t     ClkBypassCntl;
+
+    uint8_t     padding;
+};
+
+typedef struct SMU7_Fusion_GIOLevel SMU7_Fusion_GIOLevel;
+
+// UVD VCLK/DCLK state (level) definition.
+struct SMU7_Fusion_UvdLevel
+{
+    uint32_t VclkFrequency;
+    uint32_t DclkFrequency;
+    uint16_t MinVddNb;
+    uint8_t  VclkDivider;
+    uint8_t  DclkDivider;
+
+    uint8_t     VClkBypassCntl;
+    uint8_t     DClkBypassCntl;
+
+    uint8_t     padding[2];
+
+};
+
+typedef struct SMU7_Fusion_UvdLevel SMU7_Fusion_UvdLevel;
+
+// Clocks for other external blocks (VCE, ACP, SAMU).
+struct SMU7_Fusion_ExtClkLevel
+{
+    uint32_t Frequency;
+    uint16_t MinVoltage;
+    uint8_t  Divider;
+    uint8_t  ClkBypassCntl;
+
+    uint32_t Reserved;
+};
+typedef struct SMU7_Fusion_ExtClkLevel SMU7_Fusion_ExtClkLevel;
+
+struct SMU7_Fusion_ACPILevel
+{
+    uint32_t    Flags;
+    uint32_t    MinVddNb;
+    uint32_t    SclkFrequency;
+    uint8_t     SclkDid;
+    uint8_t     GnbSlow;
+    uint8_t     ForceNbPs1;
+    uint8_t     DisplayWatermark;
+    uint8_t     DeepSleepDivId;
+    uint8_t     padding[3];
+};
+
+typedef struct SMU7_Fusion_ACPILevel SMU7_Fusion_ACPILevel;
+
+struct SMU7_Fusion_NbDpm
+{
+    uint8_t DpmXNbPsHi;
+    uint8_t DpmXNbPsLo;
+    uint8_t Dpm0PgNbPsHi;
+    uint8_t Dpm0PgNbPsLo;
+    uint8_t EnablePsi1;
+    uint8_t SkipDPM0;
+    uint8_t SkipPG;
+    uint8_t Hysteresis;
+    uint8_t EnableDpmPstatePoll;
+    uint8_t padding[3];
+};
+
+typedef struct SMU7_Fusion_NbDpm SMU7_Fusion_NbDpm;
+
+struct SMU7_Fusion_StateInfo
+{
+    uint32_t SclkFrequency;
+    uint32_t LclkFrequency;
+    uint32_t VclkFrequency;
+    uint32_t DclkFrequency;
+    uint32_t SamclkFrequency;
+    uint32_t AclkFrequency;
+    uint32_t EclkFrequency;
+    uint8_t  DisplayWatermark;
+    uint8_t  McArbIndex;
+    int8_t   SclkIndex;
+    int8_t   MclkIndex;
+};
+
+typedef struct SMU7_Fusion_StateInfo SMU7_Fusion_StateInfo;
+
+struct SMU7_Fusion_DpmTable
+{
+    uint32_t                            SystemFlags;
+
+    SMU7_PIDController                  GraphicsPIDController;
+    SMU7_PIDController                  GioPIDController;
+
+    uint8_t                            GraphicsDpmLevelCount;
+    uint8_t                            GIOLevelCount;
+    uint8_t                            UvdLevelCount;
+    uint8_t                            VceLevelCount;
+
+    uint8_t                            AcpLevelCount;
+    uint8_t                            SamuLevelCount;
+    uint16_t                           FpsHighT;
+
+    SMU7_Fusion_GraphicsLevel         GraphicsLevel           [SMU__NUM_SCLK_DPM_STATE];
+    SMU7_Fusion_ACPILevel             ACPILevel;
+    SMU7_Fusion_UvdLevel              UvdLevel                [SMU7_MAX_LEVELS_UVD];
+    SMU7_Fusion_ExtClkLevel           VceLevel                [SMU7_MAX_LEVELS_VCE];
+    SMU7_Fusion_ExtClkLevel           AcpLevel                [SMU7_MAX_LEVELS_ACP];
+    SMU7_Fusion_ExtClkLevel           SamuLevel               [SMU7_MAX_LEVELS_SAMU];
+
+    uint8_t                           UvdBootLevel;
+    uint8_t                           VceBootLevel;
+    uint8_t                           AcpBootLevel;
+    uint8_t                           SamuBootLevel;
+    uint8_t                           UVDInterval;
+    uint8_t                           VCEInterval;
+    uint8_t                           ACPInterval;
+    uint8_t                           SAMUInterval;
+
+    uint8_t                           GraphicsBootLevel;
+    uint8_t                           GraphicsInterval;
+    uint8_t                           GraphicsThermThrottleEnable;
+    uint8_t                           GraphicsVoltageChangeEnable;
+
+    uint8_t                           GraphicsClkSlowEnable;
+    uint8_t                           GraphicsClkSlowDivider;
+    uint16_t                          FpsLowT;
+
+    uint32_t                          DisplayCac;
+    uint32_t                          LowSclkInterruptT;
+
+    uint32_t                          DRAM_LOG_ADDR_H;
+    uint32_t                          DRAM_LOG_ADDR_L;
+    uint32_t                          DRAM_LOG_PHY_ADDR_H;
+    uint32_t                          DRAM_LOG_PHY_ADDR_L;
+    uint32_t                          DRAM_LOG_BUFF_SIZE;
+
+};
+
+struct SMU7_Fusion_GIODpmTable
+{
+
+    SMU7_Fusion_GIOLevel              GIOLevel                [SMU7_MAX_LEVELS_GIO];
+
+    SMU7_PIDController                GioPIDController;
+
+    uint32_t                          GIOLevelCount;
+
+    uint8_t                           Enable;
+    uint8_t                           GIOVoltageChangeEnable;
+    uint8_t                           GIOBootLevel;
+    uint8_t                           padding;
+    uint8_t                           padding1[2];
+    uint8_t                           TargetState;
+    uint8_t                           CurrenttState;
+    uint8_t                           ThrottleOnHtc;
+    uint8_t                           ThermThrottleStatus;
+    uint8_t                           ThermThrottleTempSelect;
+    uint8_t                           ThermThrottleEnable;
+    uint16_t                          TemperatureLimitHigh;
+    uint16_t                          TemperatureLimitLow;
+
+};
+
+typedef struct SMU7_Fusion_DpmTable SMU7_Fusion_DpmTable;
+typedef struct SMU7_Fusion_GIODpmTable SMU7_Fusion_GIODpmTable;
+
+#pragma pack(pop)
+
+#endif
+
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/powerplay/inc/smu8.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2014 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#ifndef SMU8_H
+#define SMU8_H
+
+#pragma pack(push, 1)
+
+#define ENABLE_DEBUG_FEATURES
+
+struct SMU8_Firmware_Header {
+	uint32_t Version;
+	uint32_t ImageSize;
+	uint32_t CodeSize;
+	uint32_t HeaderSize;
+	uint32_t EntryPoint;
+	uint32_t Rtos;
+	uint32_t UcodeLoadStatus;
+	uint32_t DpmTable;
+	uint32_t FanTable;
+	uint32_t PmFuseTable;
+	uint32_t Globals;
+	uint32_t Reserved[20];
+	uint32_t Signature;
+};
+
+struct SMU8_MultimediaPowerLogData {
+	uint32_t avgTotalPower;
+	uint32_t avgGpuPower;
+	uint32_t avgUvdPower;
+	uint32_t avgVcePower;
+
+	uint32_t avgSclk;
+	uint32_t avgDclk;
+	uint32_t avgVclk;
+	uint32_t avgEclk;
+
+	uint32_t startTimeHi;
+	uint32_t startTimeLo;
+
+	uint32_t endTimeHi;
+	uint32_t endTimeLo;
+};
+
+#define SMU8_FIRMWARE_HEADER_LOCATION 0x1FF80
+#define SMU8_UNBCSR_START_ADDR 0xC0100000
+
+#define SMN_MP1_SRAM_START_ADDR 0x10000000
+
+#pragma pack(pop)
+
+#endif
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/powerplay/inc/smu8_fusion.h
@@ -0,0 +1,135 @@
+/*
+ * Copyright 2014 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#ifndef SMU8_FUSION_H
+#define SMU8_FUSION_H
+
+#include "smu8.h"
+
+#pragma pack(push, 1)
+
+#define SMU8_MAX_CUS 2
+#define SMU8_PSMS_PER_CU 4
+#define SMU8_CACS_PER_CU 4
+
+struct SMU8_GfxCuPgScoreboard {
+    uint8_t Enabled;
+    uint8_t spare[3];
+};
+
+struct SMU8_Port80MonitorTable {
+	uint32_t MmioAddress;
+	uint32_t MemoryBaseHi;
+	uint32_t MemoryBaseLo;
+	uint16_t MemoryBufferSize;
+	uint16_t MemoryPosition;
+	uint16_t PollingInterval;
+	uint8_t  EnableCsrShadow;
+	uint8_t  EnableDramShadow;
+};
+
+/*  Display specific power management parameters */
+#define PWRMGT_SEPARATION_TIME_SHIFT            0
+#define PWRMGT_SEPARATION_TIME_MASK             0xFFFF
+#define PWRMGT_DISABLE_CPU_CSTATES_SHIFT        16
+#define PWRMGT_DISABLE_CPU_CSTATES_MASK         0x1
+#define PWRMGT_DISABLE_CPU_PSTATES_SHIFT        24
+#define PWRMGT_DISABLE_CPU_PSTATES_MASK         0x1
+
+/* Clock Table Definitions */
+#define NUM_SCLK_LEVELS     8
+#define NUM_LCLK_LEVELS     8
+#define NUM_UVD_LEVELS      8
+#define NUM_ECLK_LEVELS     8
+#define NUM_ACLK_LEVELS     8
+
+struct SMU8_Fusion_ClkLevel {
+	uint8_t		GnbVid;
+	uint8_t		GfxVid;
+	uint8_t		DfsDid;
+	uint8_t		DeepSleepDid;
+	uint32_t	DfsBypass;
+	uint32_t	Frequency;
+};
+
+struct SMU8_Fusion_SclkBreakdownTable {
+	struct SMU8_Fusion_ClkLevel ClkLevel[NUM_SCLK_LEVELS];
+	struct SMU8_Fusion_ClkLevel DpmOffLevel;
+	/* SMU8_Fusion_ClkLevel PwrOffLevel; */
+	uint32_t    SclkValidMask;
+	uint32_t    MaxSclkIndex;
+};
+
+struct SMU8_Fusion_LclkBreakdownTable {
+	struct SMU8_Fusion_ClkLevel ClkLevel[NUM_LCLK_LEVELS];
+	struct SMU8_Fusion_ClkLevel DpmOffLevel;
+    /* SMU8_Fusion_ClkLevel PwrOffLevel; */
+	uint32_t    LclkValidMask;
+	uint32_t    MaxLclkIndex;
+};
+
+struct SMU8_Fusion_EclkBreakdownTable {
+	struct SMU8_Fusion_ClkLevel ClkLevel[NUM_ECLK_LEVELS];
+	struct SMU8_Fusion_ClkLevel DpmOffLevel;
+	struct SMU8_Fusion_ClkLevel PwrOffLevel;
+	uint32_t    EclkValidMask;
+	uint32_t    MaxEclkIndex;
+};
+
+struct SMU8_Fusion_VclkBreakdownTable {
+	struct SMU8_Fusion_ClkLevel ClkLevel[NUM_UVD_LEVELS];
+	struct SMU8_Fusion_ClkLevel DpmOffLevel;
+	struct SMU8_Fusion_ClkLevel PwrOffLevel;
+	uint32_t    VclkValidMask;
+	uint32_t    MaxVclkIndex;
+};
+
+struct SMU8_Fusion_DclkBreakdownTable {
+	struct SMU8_Fusion_ClkLevel ClkLevel[NUM_UVD_LEVELS];
+	struct SMU8_Fusion_ClkLevel DpmOffLevel;
+	struct SMU8_Fusion_ClkLevel PwrOffLevel;
+	uint32_t    DclkValidMask;
+	uint32_t    MaxDclkIndex;
+};
+
+struct SMU8_Fusion_AclkBreakdownTable {
+	struct SMU8_Fusion_ClkLevel ClkLevel[NUM_ACLK_LEVELS];
+	struct SMU8_Fusion_ClkLevel DpmOffLevel;
+	struct SMU8_Fusion_ClkLevel PwrOffLevel;
+	uint32_t    AclkValidMask;
+	uint32_t    MaxAclkIndex;
+};
+
+
+struct SMU8_Fusion_ClkTable {
+	struct SMU8_Fusion_SclkBreakdownTable SclkBreakdownTable;
+	struct SMU8_Fusion_LclkBreakdownTable LclkBreakdownTable;
+	struct SMU8_Fusion_EclkBreakdownTable EclkBreakdownTable;
+	struct SMU8_Fusion_VclkBreakdownTable VclkBreakdownTable;
+	struct SMU8_Fusion_DclkBreakdownTable DclkBreakdownTable;
+	struct SMU8_Fusion_AclkBreakdownTable AclkBreakdownTable;
+};
+
+#pragma pack(pop)
+
+#endif
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/powerplay/inc/smu_ucode_xfer_cz.h
@@ -0,0 +1,147 @@
+// CZ Ucode Loading Definitions
+#ifndef SMU_UCODE_XFER_CZ_H
+#define SMU_UCODE_XFER_CZ_H
+
+#define NUM_JOBLIST_ENTRIES      32
+
+#define TASK_TYPE_NO_ACTION      0
+#define TASK_TYPE_UCODE_LOAD     1
+#define TASK_TYPE_UCODE_SAVE     2
+#define TASK_TYPE_REG_LOAD       3
+#define TASK_TYPE_REG_SAVE       4
+#define TASK_TYPE_INITIALIZE     5
+
+#define TASK_ARG_REG_SMCIND      0
+#define TASK_ARG_REG_MMIO        1
+#define TASK_ARG_REG_FCH         2
+#define TASK_ARG_REG_UNB         3
+
+#define TASK_ARG_INIT_MM_PWR_LOG 0
+#define TASK_ARG_INIT_CLK_TABLE  1
+
+#define JOB_GFX_SAVE             0
+#define JOB_GFX_RESTORE          1
+#define JOB_FCH_SAVE             2
+#define JOB_FCH_RESTORE          3
+#define JOB_UNB_SAVE             4
+#define JOB_UNB_RESTORE          5
+#define JOB_GMC_SAVE             6
+#define JOB_GMC_RESTORE          7
+#define JOB_GNB_SAVE             8
+#define JOB_GNB_RESTORE          9
+
+#define IGNORE_JOB               0xff
+#define END_OF_TASK_LIST     (uint16_t)0xffff
+
+// Size of DRAM regions (in bytes) requested by SMU:
+#define SMU_DRAM_REQ_MM_PWR_LOG 48 
+
+#define UCODE_ID_SDMA0           0
+#define UCODE_ID_SDMA1           1
+#define UCODE_ID_CP_CE           2
+#define UCODE_ID_CP_PFP          3
+#define UCODE_ID_CP_ME           4
+#define UCODE_ID_CP_MEC_JT1      5
+#define UCODE_ID_CP_MEC_JT2      6
+#define UCODE_ID_GMCON_RENG      7
+#define UCODE_ID_RLC_G           8
+#define UCODE_ID_RLC_SCRATCH     9
+#define UCODE_ID_RLC_SRM_ARAM    10
+#define UCODE_ID_RLC_SRM_DRAM    11
+#define UCODE_ID_DMCU_ERAM       12
+#define UCODE_ID_DMCU_IRAM       13
+
+#define UCODE_ID_SDMA0_MASK           0x00000001       
+#define UCODE_ID_SDMA1_MASK           0x00000002        
+#define UCODE_ID_CP_CE_MASK           0x00000004      
+#define UCODE_ID_CP_PFP_MASK          0x00000008         
+#define UCODE_ID_CP_ME_MASK           0x00000010          
+#define UCODE_ID_CP_MEC_JT1_MASK      0x00000020             
+#define UCODE_ID_CP_MEC_JT2_MASK      0x00000040          
+#define UCODE_ID_GMCON_RENG_MASK      0x00000080            
+#define UCODE_ID_RLC_G_MASK           0x00000100           
+#define UCODE_ID_RLC_SCRATCH_MASK     0x00000200         
+#define UCODE_ID_RLC_SRM_ARAM_MASK    0x00000400                
+#define UCODE_ID_RLC_SRM_DRAM_MASK    0x00000800                 
+#define UCODE_ID_DMCU_ERAM_MASK       0x00001000             
+#define UCODE_ID_DMCU_IRAM_MASK       0x00002000              
+
+#define UCODE_ID_SDMA0_SIZE_BYTE           10368        
+#define UCODE_ID_SDMA1_SIZE_BYTE           10368          
+#define UCODE_ID_CP_CE_SIZE_BYTE           8576        
+#define UCODE_ID_CP_PFP_SIZE_BYTE          16768           
+#define UCODE_ID_CP_ME_SIZE_BYTE           16768            
+#define UCODE_ID_CP_MEC_JT1_SIZE_BYTE      384               
+#define UCODE_ID_CP_MEC_JT2_SIZE_BYTE      384            
+#define UCODE_ID_GMCON_RENG_SIZE_BYTE      4096              
+#define UCODE_ID_RLC_G_SIZE_BYTE           2048             
+#define UCODE_ID_RLC_SCRATCH_SIZE_BYTE     132           
+#define UCODE_ID_RLC_SRM_ARAM_SIZE_BYTE    8192                  
+#define UCODE_ID_RLC_SRM_DRAM_SIZE_BYTE    4096                   
+#define UCODE_ID_DMCU_ERAM_SIZE_BYTE       24576               
+#define UCODE_ID_DMCU_IRAM_SIZE_BYTE       1024                 
+
+#define NUM_UCODES               14
+
+typedef struct {
+	uint32_t high;
+	uint32_t low;
+} data_64_t;
+
+struct SMU_Task {
+    uint8_t type;
+    uint8_t arg;
+    uint16_t next;
+    data_64_t addr;
+    uint32_t size_bytes;
+};
+typedef struct SMU_Task SMU_Task;
+
+struct TOC {
+    uint8_t JobList[NUM_JOBLIST_ENTRIES];
+    SMU_Task tasks[1];
+};
+
+// META DATA COMMAND Definitions
+#define METADATA_CMD_MODE0         0x00000103 
+#define METADATA_CMD_MODE1         0x00000113 
+#define METADATA_CMD_MODE2         0x00000123 
+#define METADATA_CMD_MODE3         0x00000133
+#define METADATA_CMD_DELAY         0x00000203
+#define METADATA_CMD_CHNG_REGSPACE 0x00000303
+#define METADATA_PERFORM_ON_SAVE   0x00001000
+#define METADATA_PERFORM_ON_LOAD   0x00002000
+#define METADATA_CMD_ARG_MASK      0xFFFF0000
+#define METADATA_CMD_ARG_SHIFT     16
+
+// Simple register addr/data fields
+struct SMU_MetaData_Mode0 {
+    uint32_t register_address;
+    uint32_t register_data;
+};
+typedef struct SMU_MetaData_Mode0 SMU_MetaData_Mode0;
+
+// Register addr/data with mask
+struct SMU_MetaData_Mode1 {
+    uint32_t register_address;
+    uint32_t register_mask;
+    uint32_t register_data;
+};
+typedef struct SMU_MetaData_Mode1 SMU_MetaData_Mode1;
+
+struct SMU_MetaData_Mode2 {
+    uint32_t register_address;
+    uint32_t register_mask;
+    uint32_t target_value;
+};
+typedef struct SMU_MetaData_Mode2 SMU_MetaData_Mode2;
+
+// Always write data (even on a save operation)
+struct SMU_MetaData_Mode3 {
+    uint32_t register_address;
+    uint32_t register_mask;
+    uint32_t register_data;
+};
+typedef struct SMU_MetaData_Mode3 SMU_MetaData_Mode3;
+
+#endif
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/powerplay/inc/smu_ucode_xfer_vi.h
@@ -0,0 +1,100 @@
+/*
+ * Copyright 2014 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#ifndef SMU_UCODE_XFER_VI_H
+#define SMU_UCODE_XFER_VI_H
+
+#define SMU_DRAMData_TOC_VERSION  1
+#define MAX_IH_REGISTER_COUNT     65535
+#define SMU_DIGEST_SIZE_BYTES     20
+#define SMU_FB_SIZE_BYTES         1048576
+#define SMU_MAX_ENTRIES           12
+
+#define UCODE_ID_SMU              0
+#define UCODE_ID_SDMA0            1
+#define UCODE_ID_SDMA1            2
+#define UCODE_ID_CP_CE            3
+#define UCODE_ID_CP_PFP           4
+#define UCODE_ID_CP_ME            5
+#define UCODE_ID_CP_MEC           6
+#define UCODE_ID_CP_MEC_JT1       7
+#define UCODE_ID_CP_MEC_JT2       8
+#define UCODE_ID_GMCON_RENG       9
+#define UCODE_ID_RLC_G            10
+#define UCODE_ID_IH_REG_RESTORE   11
+#define UCODE_ID_VBIOS            12
+#define UCODE_ID_MISC_METADATA    13
+#define UCODE_ID_RLC_SCRATCH      32
+#define UCODE_ID_RLC_SRM_ARAM     33
+#define UCODE_ID_RLC_SRM_DRAM     34
+#define UCODE_ID_MEC_STORAGE      35
+#define UCODE_ID_VBIOS_PARAMETERS 36
+#define UCODE_META_DATA           0xFF
+
+#define UCODE_ID_SMU_MASK             0x00000001
+#define UCODE_ID_SDMA0_MASK           0x00000002
+#define UCODE_ID_SDMA1_MASK           0x00000004
+#define UCODE_ID_CP_CE_MASK           0x00000008
+#define UCODE_ID_CP_PFP_MASK          0x00000010
+#define UCODE_ID_CP_ME_MASK           0x00000020
+#define UCODE_ID_CP_MEC_MASK          0x00000040
+#define UCODE_ID_CP_MEC_JT1_MASK      0x00000080
+#define UCODE_ID_CP_MEC_JT2_MASK      0x00000100
+#define UCODE_ID_GMCON_RENG_MASK      0x00000200
+#define UCODE_ID_RLC_G_MASK           0x00000400
+#define UCODE_ID_IH_REG_RESTORE_MASK  0x00000800
+#define UCODE_ID_VBIOS_MASK           0x00001000
+
+#define UCODE_FLAG_UNHALT_MASK   0x1
+
+struct SMU_Entry {
+#ifndef __BIG_ENDIAN
+	uint16_t id;
+	uint16_t version;
+	uint32_t image_addr_high;
+	uint32_t image_addr_low;
+	uint32_t meta_data_addr_high;
+	uint32_t meta_data_addr_low;
+	uint32_t data_size_byte;
+	uint16_t flags;
+	uint16_t num_register_entries;
+#else
+	uint16_t version;
+	uint16_t id;
+	uint32_t image_addr_high;
+	uint32_t image_addr_low;
+	uint32_t meta_data_addr_high;
+	uint32_t meta_data_addr_low;
+	uint32_t data_size_byte;
+	uint16_t num_register_entries;
+	uint16_t flags;
+#endif
+};
+
+struct SMU_DRAMData_TOC {
+	uint32_t structure_version;
+	uint32_t num_entries;
+	struct SMU_Entry entry[SMU_MAX_ENTRIES];
+};
+
+#endif
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/powerplay/inc/smumgr.h
@@ -0,0 +1,182 @@
+/*
+ * Copyright 2015 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+#ifndef _SMUMGR_H_
+#define _SMUMGR_H_
+#include <linux/types.h>
+#include "pp_instance.h"
+#include "amd_powerplay.h"
+
+struct pp_smumgr;
+struct pp_instance;
+
+#define smu_lower_32_bits(n) ((uint32_t)(n))
+#define smu_upper_32_bits(n) ((uint32_t)(((n)>>16)>>16))
+
+struct pp_smumgr_func {
+	int (*smu_init)(struct pp_smumgr *smumgr);
+	int (*smu_fini)(struct pp_smumgr *smumgr);
+	int (*start_smu)(struct pp_smumgr *smumgr);
+	int (*check_fw_load_finish)(struct pp_smumgr *smumgr,
+				    uint32_t firmware);
+	int (*request_smu_load_fw)(struct pp_smumgr *smumgr);
+	int (*request_smu_load_specific_fw)(struct pp_smumgr *smumgr,
+					    uint32_t firmware);
+	int (*get_argument)(struct pp_smumgr *smumgr);
+	int (*send_msg_to_smc)(struct pp_smumgr *smumgr, uint16_t msg);
+	int (*send_msg_to_smc_with_parameter)(struct pp_smumgr *smumgr,
+					  uint16_t msg, uint32_t parameter);
+	int (*download_pptable_settings)(struct pp_smumgr *smumgr,
+					 void **table);
+	int (*upload_pptable_settings)(struct pp_smumgr *smumgr);
+};
+
+struct pp_smumgr {
+	uint32_t chip_family;
+	uint32_t chip_id;
+	uint32_t hw_revision;
+	void *device;
+	void *backend;
+	uint32_t usec_timeout;
+	bool reload_fw;
+	const struct pp_smumgr_func *smumgr_funcs;
+};
+
+
+extern int smum_init(struct amd_pp_init *pp_init,
+		     struct pp_instance *handle);
+
+extern int smum_fini(struct pp_smumgr *smumgr);
+
+extern int smum_get_argument(struct pp_smumgr *smumgr);
+
+extern int smum_download_powerplay_table(struct pp_smumgr *smumgr, void **table);
+
+extern int smum_upload_powerplay_table(struct pp_smumgr *smumgr);
+
+extern int smum_send_msg_to_smc(struct pp_smumgr *smumgr, uint16_t msg);
+
+extern int smum_send_msg_to_smc_with_parameter(struct pp_smumgr *smumgr,
+					uint16_t msg, uint32_t parameter);
+
+extern int smum_wait_on_register(struct pp_smumgr *smumgr,
+				uint32_t index, uint32_t value, uint32_t mask);
+
+extern int smum_wait_for_register_unequal(struct pp_smumgr *smumgr,
+				uint32_t index, uint32_t value, uint32_t mask);
+
+extern int smum_wait_on_indirect_register(struct pp_smumgr *smumgr,
+				uint32_t indirect_port, uint32_t index,
+				uint32_t value, uint32_t mask);
+
+
+extern void smum_wait_for_indirect_register_unequal(
+				struct pp_smumgr *smumgr,
+				uint32_t indirect_port, uint32_t index,
+				uint32_t value, uint32_t mask);
+
+extern int smu_allocate_memory(void *device, uint32_t size,
+			 enum cgs_gpu_mem_type type,
+			 uint32_t byte_align, uint64_t *mc_addr,
+			 void **kptr, void *handle);
+
+extern int smu_free_memory(void *device, void *handle);
+
+#define SMUM_FIELD_SHIFT(reg, field) reg##__##field##__SHIFT
+
+#define SMUM_FIELD_MASK(reg, field) reg##__##field##_MASK
+
+#define SMUM_WAIT_INDIRECT_REGISTER_GIVEN_INDEX(smumgr,			\
+					port, index, value, mask)	\
+	smum_wait_on_indirect_register(smumgr,				\
+				mm##port##_INDEX, index, value, mask)
+
+
+#define SMUM_WAIT_REGISTER_UNEQUAL_GIVEN_INDEX(smumgr,         \
+							index, value, mask) \
+		smum_wait_for_register_unequal(smumgr,            \
+					index, value, mask)
+
+#define SMUM_WAIT_REGISTER_UNEQUAL(smumgr, reg, value, mask)		\
+	SMUM_WAIT_REGISTER_UNEQUAL_GIVEN_INDEX(smumgr,			\
+				mm##reg, value, mask)
+
+#define SMUM_WAIT_FIELD_UNEQUAL(smumgr, reg, field, fieldval)		\
+	SMUM_WAIT_REGISTER_UNEQUAL(smumgr, reg,				\
+		(fieldval) << SMUM_FIELD_SHIFT(reg, field),		\
+		SMUM_FIELD_MASK(reg, field))
+
+#define SMUM_GET_FIELD(value, reg, field)				\
+		(((value) & SMUM_FIELD_MASK(reg, field))		\
+		>> SMUM_FIELD_SHIFT(reg, field))
+
+#define SMUM_READ_FIELD(device, reg, field)                           \
+		SMUM_GET_FIELD(cgs_read_register(device, mm##reg), reg, field)
+
+#define SMUM_SET_FIELD(value, reg, field, field_val)                  \
+		(((value) & ~SMUM_FIELD_MASK(reg, field)) |                    \
+		(SMUM_FIELD_MASK(reg, field) & ((field_val) <<                 \
+			SMUM_FIELD_SHIFT(reg, field))))
+
+#define SMUM_WAIT_VFPF_INDIRECT_REGISTER_GIVEN_INDEX(smumgr,		\
+				port, index, value, mask)		\
+	smum_wait_on_indirect_register(smumgr,				\
+		mm##port##_INDEX_0, index, value, mask)
+
+#define SMUM_WAIT_VFPF_INDIRECT_REGISTER_UNEQUAL_GIVEN_INDEX(smumgr,	\
+				port, index, value, mask)		\
+	smum_wait_for_indirect_register_unequal(smumgr,			\
+		mm##port##_INDEX_0, index, value, mask)
+
+
+#define SMUM_WAIT_VFPF_INDIRECT_REGISTER(smumgr, port, reg, value, mask) \
+	SMUM_WAIT_VFPF_INDIRECT_REGISTER_GIVEN_INDEX(smumgr, port, ix##reg, value, mask)
+
+#define SMUM_WAIT_VFPF_INDIRECT_REGISTER_UNEQUAL(smumgr, port, reg, value, mask)     \
+		SMUM_WAIT_VFPF_INDIRECT_REGISTER_UNEQUAL_GIVEN_INDEX(smumgr, port, ix##reg, value, mask)
+
+
+/*Operations on named fields.*/
+
+#define SMUM_READ_VFPF_INDIRECT_FIELD(device, port, reg, field) \
+		SMUM_GET_FIELD(cgs_read_ind_register(device, port, ix##reg), \
+			reg, field)
+
+#define SMUM_WRITE_FIELD(device, reg, field, fieldval)            \
+		cgs_write_register(device, mm##reg, \
+		SMUM_SET_FIELD(cgs_read_register(device, mm##reg), reg, field, fieldval))
+
+#define SMUM_WRITE_VFPF_INDIRECT_FIELD(device, port, reg, field, fieldval)    \
+		cgs_write_ind_register(device, port, ix##reg, \
+			SMUM_SET_FIELD(cgs_read_ind_register(device, port, ix##reg), \
+			reg, field, fieldval))
+
+#define SMUM_WAIT_VFPF_INDIRECT_FIELD(smumgr, port, reg, field, fieldval) \
+	SMUM_WAIT_VFPF_INDIRECT_REGISTER(smumgr, port, reg,		\
+		(fieldval) << SMUM_FIELD_SHIFT(reg, field),		\
+		SMUM_FIELD_MASK(reg, field))
+
+#define SMUM_WAIT_VFPF_INDIRECT_FIELD_UNEQUAL(smumgr, port, reg, field, fieldval) \
+	SMUM_WAIT_VFPF_INDIRECT_REGISTER_UNEQUAL(smumgr, port, reg,	\
+		(fieldval) << SMUM_FIELD_SHIFT(reg, field),		\
+		SMUM_FIELD_MASK(reg, field))
+#endif
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/powerplay/inc/tonga_ppsmc.h
@@ -0,0 +1,420 @@
+/*
+ * Copyright 2015 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#ifndef TONGA_PP_SMC_H
+#define TONGA_PP_SMC_H
+
+#pragma pack(push, 1)
+
+#define PPSMC_SWSTATE_FLAG_DC				0x01
+#define PPSMC_SWSTATE_FLAG_UVD				0x02
+#define PPSMC_SWSTATE_FLAG_VCE				0x04
+#define PPSMC_SWSTATE_FLAG_PCIE_X1			0x08
+
+#define PPSMC_THERMAL_PROTECT_TYPE_INTERNAL             0x00
+#define PPSMC_THERMAL_PROTECT_TYPE_EXTERNAL             0x01
+#define PPSMC_THERMAL_PROTECT_TYPE_NONE                 0xff
+
+#define PPSMC_SYSTEMFLAG_GPIO_DC                        0x01
+#define PPSMC_SYSTEMFLAG_STEPVDDC                       0x02
+#define PPSMC_SYSTEMFLAG_GDDR5                          0x04
+
+#define PPSMC_SYSTEMFLAG_DISABLE_BABYSTEP               0x08
+
+#define PPSMC_SYSTEMFLAG_REGULATOR_HOT                  0x10
+#define PPSMC_SYSTEMFLAG_REGULATOR_HOT_ANALOG           0x20
+#define PPSMC_SYSTEMFLAG_12CHANNEL                      0x40
+
+
+#define PPSMC_EXTRAFLAGS_AC2DC_ACTION_MASK              0x07
+#define PPSMC_EXTRAFLAGS_AC2DC_DONT_WAIT_FOR_VBLANK     0x08
+
+#define PPSMC_EXTRAFLAGS_AC2DC_ACTION_GOTODPMLOWSTATE   0x00
+#define PPSMC_EXTRAFLAGS_AC2DC_ACTION_GOTOINITIALSTATE  0x01
+
+#define PPSMC_EXTRAFLAGS_AC2DC_GPIO5_POLARITY_HIGH      0x10
+#define PPSMC_EXTRAFLAGS_DRIVER_TO_GPIO17               0x20
+#define PPSMC_EXTRAFLAGS_PCC_TO_GPIO17                  0x40
+
+/* Defines for DPM 2.0 */
+#define PPSMC_DPM2FLAGS_TDPCLMP                         0x01
+#define PPSMC_DPM2FLAGS_PWRSHFT                         0x02
+#define PPSMC_DPM2FLAGS_OCP                             0x04
+
+/* Defines for display watermark level */
+
+#define PPSMC_DISPLAY_WATERMARK_LOW                     0
+#define PPSMC_DISPLAY_WATERMARK_HIGH                    1
+
+/* In the HW performance level's state flags:*/
+#define PPSMC_STATEFLAG_AUTO_PULSE_SKIP    0x01
+#define PPSMC_STATEFLAG_POWERBOOST         0x02
+#define PPSMC_STATEFLAG_PSKIP_ON_TDP_FAULT 0x04
+#define PPSMC_STATEFLAG_POWERSHIFT         0x08
+#define PPSMC_STATEFLAG_SLOW_READ_MARGIN   0x10
+#define PPSMC_STATEFLAG_DEEPSLEEP_THROTTLE 0x20
+#define PPSMC_STATEFLAG_DEEPSLEEP_BYPASS   0x40
+
+/* Fan control algorithm:*/
+#define FDO_MODE_HARDWARE 0
+#define FDO_MODE_PIECE_WISE_LINEAR 1
+
+enum FAN_CONTROL {
+	FAN_CONTROL_FUZZY,
+	FAN_CONTROL_TABLE
+};
+
+/* Return codes for driver to SMC communication.*/
+
+#define PPSMC_Result_OK             ((uint16_t)0x01)
+#define PPSMC_Result_NoMore         ((uint16_t)0x02)
+#define PPSMC_Result_NotNow         ((uint16_t)0x03)
+
+#define PPSMC_Result_Failed         ((uint16_t)0xFF)
+#define PPSMC_Result_UnknownCmd     ((uint16_t)0xFE)
+#define PPSMC_Result_UnknownVT      ((uint16_t)0xFD)
+
+typedef uint16_t PPSMC_Result;
+
+#define PPSMC_isERROR(x) ((uint16_t)0x80 & (x))
+
+
+#define PPSMC_MSG_Halt                      ((uint16_t)0x10)
+#define PPSMC_MSG_Resume                    ((uint16_t)0x11)
+#define PPSMC_MSG_EnableDPMLevel            ((uint16_t)0x12)
+#define PPSMC_MSG_ZeroLevelsDisabled        ((uint16_t)0x13)
+#define PPSMC_MSG_OneLevelsDisabled         ((uint16_t)0x14)
+#define PPSMC_MSG_TwoLevelsDisabled         ((uint16_t)0x15)
+#define PPSMC_MSG_EnableThermalInterrupt    ((uint16_t)0x16)
+#define PPSMC_MSG_RunningOnAC               ((uint16_t)0x17)
+#define PPSMC_MSG_LevelUp                   ((uint16_t)0x18)
+#define PPSMC_MSG_LevelDown                 ((uint16_t)0x19)
+#define PPSMC_MSG_ResetDPMCounters          ((uint16_t)0x1a)
+#define PPSMC_MSG_SwitchToSwState           ((uint16_t)0x20)
+
+#define PPSMC_MSG_SwitchToSwStateLast       ((uint16_t)0x3f)
+#define PPSMC_MSG_SwitchToInitialState      ((uint16_t)0x40)
+#define PPSMC_MSG_NoForcedLevel             ((uint16_t)0x41)
+#define PPSMC_MSG_ForceHigh                 ((uint16_t)0x42)
+#define PPSMC_MSG_ForceMediumOrHigh         ((uint16_t)0x43)
+
+#define PPSMC_MSG_SwitchToMinimumPower      ((uint16_t)0x51)
+#define PPSMC_MSG_ResumeFromMinimumPower    ((uint16_t)0x52)
+#define PPSMC_MSG_EnableCac                 ((uint16_t)0x53)
+#define PPSMC_MSG_DisableCac                ((uint16_t)0x54)
+#define PPSMC_DPMStateHistoryStart          ((uint16_t)0x55)
+#define PPSMC_DPMStateHistoryStop           ((uint16_t)0x56)
+#define PPSMC_CACHistoryStart               ((uint16_t)0x57)
+#define PPSMC_CACHistoryStop                ((uint16_t)0x58)
+#define PPSMC_TDPClampingActive             ((uint16_t)0x59)
+#define PPSMC_TDPClampingInactive           ((uint16_t)0x5A)
+#define PPSMC_StartFanControl               ((uint16_t)0x5B)
+#define PPSMC_StopFanControl                ((uint16_t)0x5C)
+#define PPSMC_NoDisplay                     ((uint16_t)0x5D)
+#define PPSMC_HasDisplay                    ((uint16_t)0x5E)
+#define PPSMC_MSG_UVDPowerOFF               ((uint16_t)0x60)
+#define PPSMC_MSG_UVDPowerON                ((uint16_t)0x61)
+#define PPSMC_MSG_EnableULV                 ((uint16_t)0x62)
+#define PPSMC_MSG_DisableULV                ((uint16_t)0x63)
+#define PPSMC_MSG_EnterULV                  ((uint16_t)0x64)
+#define PPSMC_MSG_ExitULV                   ((uint16_t)0x65)
+#define PPSMC_PowerShiftActive              ((uint16_t)0x6A)
+#define PPSMC_PowerShiftInactive            ((uint16_t)0x6B)
+#define PPSMC_OCPActive                     ((uint16_t)0x6C)
+#define PPSMC_OCPInactive                   ((uint16_t)0x6D)
+#define PPSMC_CACLongTermAvgEnable          ((uint16_t)0x6E)
+#define PPSMC_CACLongTermAvgDisable         ((uint16_t)0x6F)
+#define PPSMC_MSG_InferredStateSweep_Start  ((uint16_t)0x70)
+#define PPSMC_MSG_InferredStateSweep_Stop   ((uint16_t)0x71)
+#define PPSMC_MSG_SwitchToLowestInfState    ((uint16_t)0x72)
+#define PPSMC_MSG_SwitchToNonInfState       ((uint16_t)0x73)
+#define PPSMC_MSG_AllStateSweep_Start       ((uint16_t)0x74)
+#define PPSMC_MSG_AllStateSweep_Stop        ((uint16_t)0x75)
+#define PPSMC_MSG_SwitchNextLowerInfState   ((uint16_t)0x76)
+#define PPSMC_MSG_SwitchNextHigherInfState  ((uint16_t)0x77)
+#define PPSMC_MSG_MclkRetrainingTest        ((uint16_t)0x78)
+#define PPSMC_MSG_ForceTDPClamping          ((uint16_t)0x79)
+#define PPSMC_MSG_CollectCAC_PowerCorreln   ((uint16_t)0x7A)
+#define PPSMC_MSG_CollectCAC_WeightCalib    ((uint16_t)0x7B)
+#define PPSMC_MSG_CollectCAC_SQonly         ((uint16_t)0x7C)
+#define PPSMC_MSG_CollectCAC_TemperaturePwr ((uint16_t)0x7D)
+
+#define PPSMC_MSG_ExtremitiesTest_Start     ((uint16_t)0x7E)
+#define PPSMC_MSG_ExtremitiesTest_Stop      ((uint16_t)0x7F)
+#define PPSMC_FlushDataCache                ((uint16_t)0x80)
+#define PPSMC_FlushInstrCache               ((uint16_t)0x81)
+
+#define PPSMC_MSG_SetEnabledLevels          ((uint16_t)0x82)
+#define PPSMC_MSG_SetForcedLevels           ((uint16_t)0x83)
+
+#define PPSMC_MSG_ResetToDefaults           ((uint16_t)0x84)
+
+#define PPSMC_MSG_SetForcedLevelsAndJump    ((uint16_t)0x85)
+#define PPSMC_MSG_SetCACHistoryMode         ((uint16_t)0x86)
+#define PPSMC_MSG_EnableDTE                 ((uint16_t)0x87)
+#define PPSMC_MSG_DisableDTE                ((uint16_t)0x88)
+
+#define PPSMC_MSG_SmcSpaceSetAddress        ((uint16_t)0x89)
+#define PPSMC_MSG_ChangeNearTDPLimit        ((uint16_t)0x90)
+#define PPSMC_MSG_ChangeSafePowerLimit      ((uint16_t)0x91)
+
+#define PPSMC_MSG_DPMStateSweepStart        ((uint16_t)0x92)
+#define PPSMC_MSG_DPMStateSweepStop         ((uint16_t)0x93)
+
+#define PPSMC_MSG_OVRDDisableSCLKDS         ((uint16_t)0x94)
+#define PPSMC_MSG_CancelDisableOVRDSCLKDS   ((uint16_t)0x95)
+#define PPSMC_MSG_ThrottleOVRDSCLKDS        ((uint16_t)0x96)
+#define PPSMC_MSG_CancelThrottleOVRDSCLKDS  ((uint16_t)0x97)
+#define PPSMC_MSG_GPIO17					((uint16_t)0x98)
+
+#define PPSMC_MSG_API_SetSvi2Volt_Vddc      ((uint16_t)0x99)
+#define PPSMC_MSG_API_SetSvi2Volt_Vddci     ((uint16_t)0x9A)
+#define PPSMC_MSG_API_SetSvi2Volt_Mvdd      ((uint16_t)0x9B)
+#define PPSMC_MSG_API_GetSvi2Volt_Vddc      ((uint16_t)0x9C)
+#define PPSMC_MSG_API_GetSvi2Volt_Vddci     ((uint16_t)0x9D)
+#define PPSMC_MSG_API_GetSvi2Volt_Mvdd      ((uint16_t)0x9E)
+
+#define PPSMC_MSG_BREAK                     ((uint16_t)0xF8)
+
+/* Trinity Specific Messages*/
+#define PPSMC_MSG_Test                      ((uint16_t) 0x100)
+#define PPSMC_MSG_DPM_Voltage_Pwrmgt        ((uint16_t) 0x101)
+#define PPSMC_MSG_DPM_Config                ((uint16_t) 0x102)
+#define PPSMC_MSG_PM_Controller_Start       ((uint16_t) 0x103)
+#define PPSMC_MSG_DPM_ForceState            ((uint16_t) 0x104)
+#define PPSMC_MSG_PG_PowerDownSIMD          ((uint16_t) 0x105)
+#define PPSMC_MSG_PG_PowerUpSIMD            ((uint16_t) 0x106)
+#define PPSMC_MSG_PM_Controller_Stop        ((uint16_t) 0x107)
+#define PPSMC_MSG_PG_SIMD_Config            ((uint16_t) 0x108)
+#define PPSMC_MSG_Voltage_Cntl_Enable       ((uint16_t) 0x109)
+#define PPSMC_MSG_Thermal_Cntl_Enable       ((uint16_t) 0x10a)
+#define PPSMC_MSG_Reset_Service             ((uint16_t) 0x10b)
+#define PPSMC_MSG_VCEPowerOFF               ((uint16_t) 0x10e)
+#define PPSMC_MSG_VCEPowerON                ((uint16_t) 0x10f)
+#define PPSMC_MSG_DPM_Disable_VCE_HS        ((uint16_t) 0x110)
+#define PPSMC_MSG_DPM_Enable_VCE_HS         ((uint16_t) 0x111)
+#define PPSMC_MSG_DPM_N_LevelsDisabled      ((uint16_t) 0x112)
+#define PPSMC_MSG_DCEPowerOFF               ((uint16_t) 0x113)
+#define PPSMC_MSG_DCEPowerON                ((uint16_t) 0x114)
+#define PPSMC_MSG_PCIE_DDIPowerDown         ((uint16_t) 0x117)
+#define PPSMC_MSG_PCIE_DDIPowerUp           ((uint16_t) 0x118)
+#define PPSMC_MSG_PCIE_CascadePLLPowerDown  ((uint16_t) 0x119)
+#define PPSMC_MSG_PCIE_CascadePLLPowerUp    ((uint16_t) 0x11a)
+#define PPSMC_MSG_SYSPLLPowerOff            ((uint16_t) 0x11b)
+#define PPSMC_MSG_SYSPLLPowerOn             ((uint16_t) 0x11c)
+#define PPSMC_MSG_DCE_RemoveVoltageAdjustment   ((uint16_t) 0x11d)
+#define PPSMC_MSG_DCE_AllowVoltageAdjustment    ((uint16_t) 0x11e)
+#define PPSMC_MSG_DISPLAYPHYStatusNotify    ((uint16_t) 0x11f)
+#define PPSMC_MSG_EnableBAPM                ((uint16_t) 0x120)
+#define PPSMC_MSG_DisableBAPM               ((uint16_t) 0x121)
+#define PPSMC_MSG_PCIE_PHYPowerDown         ((uint16_t) 0x122)
+#define PPSMC_MSG_PCIE_PHYPowerUp           ((uint16_t) 0x123)
+#define PPSMC_MSG_UVD_DPM_Config            ((uint16_t) 0x124)
+#define PPSMC_MSG_Spmi_Enable               ((uint16_t) 0x122)
+#define PPSMC_MSG_Spmi_Timer                ((uint16_t) 0x123)
+#define PPSMC_MSG_LCLK_DPM_Config           ((uint16_t) 0x124)
+#define PPSMC_MSG_NBDPM_Config             ((uint16_t) 0x125)
+#define PPSMC_MSG_PCIE_DDIPhyPowerDown           ((uint16_t) 0x126)
+#define PPSMC_MSG_PCIE_DDIPhyPowerUp             ((uint16_t) 0x127)
+#define PPSMC_MSG_MCLKDPM_Config                ((uint16_t) 0x128)
+
+#define PPSMC_MSG_UVDDPM_Config               ((uint16_t) 0x129)
+#define PPSMC_MSG_VCEDPM_Config               ((uint16_t) 0x12A)
+#define PPSMC_MSG_ACPDPM_Config               ((uint16_t) 0x12B)
+#define PPSMC_MSG_SAMUDPM_Config              ((uint16_t) 0x12C)
+#define PPSMC_MSG_UVDDPM_SetEnabledMask       ((uint16_t) 0x12D)
+#define PPSMC_MSG_VCEDPM_SetEnabledMask       ((uint16_t) 0x12E)
+#define PPSMC_MSG_ACPDPM_SetEnabledMask       ((uint16_t) 0x12F)
+#define PPSMC_MSG_SAMUDPM_SetEnabledMask      ((uint16_t) 0x130)
+#define PPSMC_MSG_MCLKDPM_ForceState          ((uint16_t) 0x131)
+#define PPSMC_MSG_MCLKDPM_NoForcedLevel       ((uint16_t) 0x132)
+#define PPSMC_MSG_Thermal_Cntl_Disable        ((uint16_t) 0x133)
+#define PPSMC_MSG_SetTDPLimit                 ((uint16_t) 0x134)
+#define PPSMC_MSG_Voltage_Cntl_Disable        ((uint16_t) 0x135)
+#define PPSMC_MSG_PCIeDPM_Enable              ((uint16_t) 0x136)
+#define PPSMC_MSG_ACPPowerOFF                 ((uint16_t) 0x137)
+#define PPSMC_MSG_ACPPowerON                  ((uint16_t) 0x138)
+#define PPSMC_MSG_SAMPowerOFF                 ((uint16_t) 0x139)
+#define PPSMC_MSG_SAMPowerON                  ((uint16_t) 0x13a)
+#define PPSMC_MSG_SDMAPowerOFF                ((uint16_t) 0x13b)
+#define PPSMC_MSG_SDMAPowerON                 ((uint16_t) 0x13c)
+#define PPSMC_MSG_PCIeDPM_Disable             ((uint16_t) 0x13d)
+#define PPSMC_MSG_IOMMUPowerOFF               ((uint16_t) 0x13e)
+#define PPSMC_MSG_IOMMUPowerON                ((uint16_t) 0x13f)
+#define PPSMC_MSG_NBDPM_Enable                ((uint16_t) 0x140)
+#define PPSMC_MSG_NBDPM_Disable               ((uint16_t) 0x141)
+#define PPSMC_MSG_NBDPM_ForceNominal          ((uint16_t) 0x142)
+#define PPSMC_MSG_NBDPM_ForcePerformance      ((uint16_t) 0x143)
+#define PPSMC_MSG_NBDPM_UnForce               ((uint16_t) 0x144)
+#define PPSMC_MSG_SCLKDPM_SetEnabledMask      ((uint16_t) 0x145)
+#define PPSMC_MSG_MCLKDPM_SetEnabledMask      ((uint16_t) 0x146)
+#define PPSMC_MSG_PCIeDPM_ForceLevel          ((uint16_t) 0x147)
+#define PPSMC_MSG_PCIeDPM_UnForceLevel        ((uint16_t) 0x148)
+#define PPSMC_MSG_EnableACDCGPIOInterrupt     ((uint16_t) 0x149)
+#define PPSMC_MSG_EnableVRHotGPIOInterrupt    ((uint16_t) 0x14a)
+#define PPSMC_MSG_SwitchToAC                  ((uint16_t) 0x14b)
+
+#define PPSMC_MSG_XDMAPowerOFF                ((uint16_t) 0x14c)
+#define PPSMC_MSG_XDMAPowerON                 ((uint16_t) 0x14d)
+
+#define PPSMC_MSG_DPM_Enable                  ((uint16_t)0x14e)
+#define PPSMC_MSG_DPM_Disable                 ((uint16_t)0x14f)
+#define PPSMC_MSG_MCLKDPM_Enable              ((uint16_t)0x150)
+#define PPSMC_MSG_MCLKDPM_Disable             ((uint16_t)0x151)
+#define PPSMC_MSG_LCLKDPM_Enable              ((uint16_t)0x152)
+#define PPSMC_MSG_LCLKDPM_Disable             ((uint16_t)0x153)
+#define PPSMC_MSG_UVDDPM_Enable               ((uint16_t)0x154)
+#define PPSMC_MSG_UVDDPM_Disable              ((uint16_t)0x155)
+#define PPSMC_MSG_SAMUDPM_Enable              ((uint16_t)0x156)
+#define PPSMC_MSG_SAMUDPM_Disable             ((uint16_t)0x157)
+#define PPSMC_MSG_ACPDPM_Enable               ((uint16_t)0x158)
+#define PPSMC_MSG_ACPDPM_Disable              ((uint16_t)0x159)
+#define PPSMC_MSG_VCEDPM_Enable               ((uint16_t)0x15a)
+#define PPSMC_MSG_VCEDPM_Disable              ((uint16_t)0x15b)
+#define PPSMC_MSG_LCLKDPM_SetEnabledMask      ((uint16_t)0x15c)
+
+#define PPSMC_MSG_DPM_FPS_Mode                ((uint16_t) 0x15d)
+#define PPSMC_MSG_DPM_Activity_Mode           ((uint16_t) 0x15e)
+#define PPSMC_MSG_VddC_Request                ((uint16_t) 0x15f)
+#define PPSMC_MSG_MCLKDPM_GetEnabledMask      ((uint16_t) 0x160)
+#define PPSMC_MSG_LCLKDPM_GetEnabledMask      ((uint16_t) 0x161)
+#define PPSMC_MSG_SCLKDPM_GetEnabledMask      ((uint16_t) 0x162)
+#define PPSMC_MSG_UVDDPM_GetEnabledMask       ((uint16_t) 0x163)
+#define PPSMC_MSG_SAMUDPM_GetEnabledMask      ((uint16_t) 0x164)
+#define PPSMC_MSG_ACPDPM_GetEnabledMask       ((uint16_t) 0x165)
+#define PPSMC_MSG_VCEDPM_GetEnabledMask       ((uint16_t) 0x166)
+#define PPSMC_MSG_PCIeDPM_SetEnabledMask      ((uint16_t) 0x167)
+#define PPSMC_MSG_PCIeDPM_GetEnabledMask      ((uint16_t) 0x168)
+#define PPSMC_MSG_TDCLimitEnable              ((uint16_t) 0x169)
+#define PPSMC_MSG_TDCLimitDisable             ((uint16_t) 0x16a)
+#define PPSMC_MSG_DPM_AutoRotate_Mode         ((uint16_t) 0x16b)
+#define PPSMC_MSG_DISPCLK_FROM_FCH            ((uint16_t)0x16c)
+#define PPSMC_MSG_DISPCLK_FROM_DFS            ((uint16_t)0x16d)
+#define PPSMC_MSG_DPREFCLK_FROM_FCH           ((uint16_t)0x16e)
+#define PPSMC_MSG_DPREFCLK_FROM_DFS           ((uint16_t)0x16f)
+#define PPSMC_MSG_PmStatusLogStart            ((uint16_t)0x170)
+#define PPSMC_MSG_PmStatusLogSample           ((uint16_t)0x171)
+#define PPSMC_MSG_SCLK_AutoDPM_ON             ((uint16_t) 0x172)
+#define PPSMC_MSG_MCLK_AutoDPM_ON             ((uint16_t) 0x173)
+#define PPSMC_MSG_LCLK_AutoDPM_ON             ((uint16_t) 0x174)
+#define PPSMC_MSG_UVD_AutoDPM_ON              ((uint16_t) 0x175)
+#define PPSMC_MSG_SAMU_AutoDPM_ON             ((uint16_t) 0x176)
+#define PPSMC_MSG_ACP_AutoDPM_ON              ((uint16_t) 0x177)
+#define PPSMC_MSG_VCE_AutoDPM_ON              ((uint16_t) 0x178)
+#define PPSMC_MSG_PCIe_AutoDPM_ON             ((uint16_t) 0x179)
+#define PPSMC_MSG_MASTER_AutoDPM_ON           ((uint16_t) 0x17a)
+#define PPSMC_MSG_MASTER_AutoDPM_OFF          ((uint16_t) 0x17b)
+#define PPSMC_MSG_DYNAMICDISPPHYPOWER         ((uint16_t) 0x17c)
+#define PPSMC_MSG_CAC_COLLECTION_ON           ((uint16_t) 0x17d)
+#define PPSMC_MSG_CAC_COLLECTION_OFF          ((uint16_t) 0x17e)
+#define PPSMC_MSG_CAC_CORRELATION_ON          ((uint16_t) 0x17f)
+#define PPSMC_MSG_CAC_CORRELATION_OFF         ((uint16_t) 0x180)
+#define PPSMC_MSG_PM_STATUS_TO_DRAM_ON        ((uint16_t) 0x181)
+#define PPSMC_MSG_PM_STATUS_TO_DRAM_OFF       ((uint16_t) 0x182)
+#define PPSMC_MSG_UVD_HANDSHAKE_OFF           ((uint16_t) 0x183)
+#define PPSMC_MSG_ALLOW_LOWSCLK_INTERRUPT     ((uint16_t) 0x184)
+#define PPSMC_MSG_PkgPwrLimitEnable           ((uint16_t) 0x185)
+#define PPSMC_MSG_PkgPwrLimitDisable          ((uint16_t) 0x186)
+#define PPSMC_MSG_PkgPwrSetLimit              ((uint16_t) 0x187)
+#define PPSMC_MSG_OverDriveSetTargetTdp       ((uint16_t) 0x188)
+#define PPSMC_MSG_SCLKDPM_FreezeLevel         ((uint16_t) 0x189)
+#define PPSMC_MSG_SCLKDPM_UnfreezeLevel       ((uint16_t) 0x18A)
+#define PPSMC_MSG_MCLKDPM_FreezeLevel         ((uint16_t) 0x18B)
+#define PPSMC_MSG_MCLKDPM_UnfreezeLevel       ((uint16_t) 0x18C)
+#define PPSMC_MSG_START_DRAM_LOGGING          ((uint16_t) 0x18D)
+#define PPSMC_MSG_STOP_DRAM_LOGGING           ((uint16_t) 0x18E)
+#define PPSMC_MSG_MASTER_DeepSleep_ON         ((uint16_t) 0x18F)
+#define PPSMC_MSG_MASTER_DeepSleep_OFF        ((uint16_t) 0x190)
+#define PPSMC_MSG_Remove_DC_Clamp             ((uint16_t) 0x191)
+#define PPSMC_MSG_DisableACDCGPIOInterrupt    ((uint16_t) 0x192)
+#define PPSMC_MSG_OverrideVoltageControl_SetVddc       ((uint16_t) 0x193)
+#define PPSMC_MSG_OverrideVoltageControl_SetVddci      ((uint16_t) 0x194)
+#define PPSMC_MSG_SetVidOffset_1              ((uint16_t) 0x195)
+#define PPSMC_MSG_SetVidOffset_2              ((uint16_t) 0x207)
+#define PPSMC_MSG_GetVidOffset_1              ((uint16_t) 0x196)
+#define PPSMC_MSG_GetVidOffset_2              ((uint16_t) 0x208)
+#define PPSMC_MSG_THERMAL_OVERDRIVE_Enable    ((uint16_t) 0x197)
+#define PPSMC_MSG_THERMAL_OVERDRIVE_Disable	  ((uint16_t) 0x198)
+#define PPSMC_MSG_SetTjMax                    ((uint16_t) 0x199)
+#define PPSMC_MSG_SetFanPwmMax                ((uint16_t) 0x19A)
+
+#define PPSMC_MSG_WaitForMclkSwitchFinish	  ((uint16_t) 0x19B)
+#define PPSMC_MSG_ENABLE_THERMAL_DPM          ((uint16_t) 0x19C)
+#define PPSMC_MSG_DISABLE_THERMAL_DPM         ((uint16_t) 0x19D)
+#define PPSMC_MSG_Enable_PCC                  ((uint16_t) 0x19E)
+#define PPSMC_MSG_Disable_PCC                 ((uint16_t) 0x19F)
+
+#define PPSMC_MSG_API_GetSclkFrequency        ((uint16_t) 0x200)
+#define PPSMC_MSG_API_GetMclkFrequency        ((uint16_t) 0x201)
+#define PPSMC_MSG_API_GetSclkBusy             ((uint16_t) 0x202)
+#define PPSMC_MSG_API_GetMclkBusy             ((uint16_t) 0x203)
+#define PPSMC_MSG_API_GetAsicPower            ((uint16_t) 0x204)
+#define PPSMC_MSG_SetFanRpmMax                ((uint16_t) 0x205)
+#define PPSMC_MSG_SetFanSclkTarget            ((uint16_t) 0x206)
+#define PPSMC_MSG_SetFanMinPwm                ((uint16_t) 0x209)
+#define PPSMC_MSG_SetFanTemperatureTarget     ((uint16_t) 0x20A)
+
+#define PPSMC_MSG_BACO_StartMonitor           ((uint16_t) 0x240)
+#define PPSMC_MSG_BACO_Cancel                 ((uint16_t) 0x241)
+#define PPSMC_MSG_EnableVddGfx                ((uint16_t) 0x242)
+#define PPSMC_MSG_DisableVddGfx               ((uint16_t) 0x243)
+#define PPSMC_MSG_UcodeAddressLow             ((uint16_t) 0x244)
+#define PPSMC_MSG_UcodeAddressHigh            ((uint16_t) 0x245)
+#define PPSMC_MSG_UcodeLoadStatus             ((uint16_t) 0x246)
+
+#define PPSMC_MSG_DRV_DRAM_ADDR_HI			  ((uint16_t) 0x250)
+#define PPSMC_MSG_DRV_DRAM_ADDR_LO            ((uint16_t) 0x251)
+#define PPSMC_MSG_SMU_DRAM_ADDR_HI            ((uint16_t) 0x252)
+#define PPSMC_MSG_SMU_DRAM_ADDR_LO            ((uint16_t) 0x253)
+#define PPSMC_MSG_LoadUcodes                  ((uint16_t) 0x254)
+#define PPSMC_MSG_PowerStateNotify            ((uint16_t) 0x255)
+#define PPSMC_MSG_COND_EXEC_DRAM_ADDR_HI      ((uint16_t) 0x256)
+#define PPSMC_MSG_COND_EXEC_DRAM_ADDR_LO      ((uint16_t) 0x257)
+#define PPSMC_MSG_VBIOS_DRAM_ADDR_HI          ((uint16_t) 0x258)
+#define PPSMC_MSG_VBIOS_DRAM_ADDR_LO          ((uint16_t) 0x259)
+#define PPSMC_MSG_LoadVBios                   ((uint16_t) 0x25A)
+#define PPSMC_MSG_GetUcodeVersion             ((uint16_t) 0x25B)
+#define DMCUSMC_MSG_PSREntry                  ((uint16_t) 0x25C)
+#define DMCUSMC_MSG_PSRExit                   ((uint16_t) 0x25D)
+#define PPSMC_MSG_EnableClockGatingFeature    ((uint16_t) 0x260)
+#define PPSMC_MSG_DisableClockGatingFeature   ((uint16_t) 0x261)
+#define PPSMC_MSG_IsDeviceRunning             ((uint16_t) 0x262)
+#define PPSMC_MSG_LoadMetaData                ((uint16_t) 0x263)
+#define PPSMC_MSG_TMON_AutoCaliberate_Enable  ((uint16_t) 0x264)
+#define PPSMC_MSG_TMON_AutoCaliberate_Disable ((uint16_t) 0x265)
+#define PPSMC_MSG_GetTelemetry1Slope          ((uint16_t) 0x266)
+#define PPSMC_MSG_GetTelemetry1Offset         ((uint16_t) 0x267)
+#define PPSMC_MSG_GetTelemetry2Slope          ((uint16_t) 0x268)
+#define PPSMC_MSG_GetTelemetry2Offset         ((uint16_t) 0x269)
+
+typedef uint16_t PPSMC_Msg;
+
+/* If the SMC firmware has an event status soft register this is what the individual bits mean.*/
+#define PPSMC_EVENT_STATUS_THERMAL          0x00000001
+#define PPSMC_EVENT_STATUS_REGULATORHOT     0x00000002
+#define PPSMC_EVENT_STATUS_DC               0x00000004
+#define PPSMC_EVENT_STATUS_GPIO17           0x00000008
+
+
+#pragma pack(pop)
+#endif
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/powerplay/smumgr/Makefile
@@ -0,0 +1,9 @@
+#
+# Makefile for the 'smu manager' sub-component of powerplay.
+# It provides the smu management services for the driver.
+
+SMU_MGR = smumgr.o cz_smumgr.o tonga_smumgr.o fiji_smumgr.o
+
+AMD_PP_SMUMGR = $(addprefix $(AMD_PP_PATH)/smumgr/,$(SMU_MGR))
+
+AMD_POWERPLAY_FILES += $(AMD_PP_SMUMGR)
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/powerplay/smumgr/cz_smumgr.c
@@ -0,0 +1,881 @@
+/*
+ * Copyright 2015 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/gfp.h>
+#include "linux/delay.h"
+#include "cgs_common.h"
+#include "smu/smu_8_0_d.h"
+#include "smu/smu_8_0_sh_mask.h"
+#include "smu8.h"
+#include "smu8_fusion.h"
+#include "cz_smumgr.h"
+#include "cz_ppsmc.h"
+#include "smu_ucode_xfer_cz.h"
+#include "gca/gfx_8_0_d.h"
+#include "gca/gfx_8_0_sh_mask.h"
+#include "smumgr.h"
+
+#define SIZE_ALIGN_32(x)    (((x) + 31) / 32 * 32)
+
+static enum cz_scratch_entry firmware_list[] = {
+	CZ_SCRATCH_ENTRY_UCODE_ID_SDMA0,
+	CZ_SCRATCH_ENTRY_UCODE_ID_SDMA1,
+	CZ_SCRATCH_ENTRY_UCODE_ID_CP_CE,
+	CZ_SCRATCH_ENTRY_UCODE_ID_CP_PFP,
+	CZ_SCRATCH_ENTRY_UCODE_ID_CP_ME,
+	CZ_SCRATCH_ENTRY_UCODE_ID_CP_MEC_JT1,
+	CZ_SCRATCH_ENTRY_UCODE_ID_CP_MEC_JT2,
+	CZ_SCRATCH_ENTRY_UCODE_ID_RLC_G,
+};
+
+static int cz_smum_get_argument(struct pp_smumgr *smumgr)
+{
+	if (smumgr == NULL || smumgr->device == NULL)
+		return -EINVAL;
+
+	return cgs_read_register(smumgr->device,
+					mmSMU_MP1_SRBM2P_ARG_0);
+}
+
+static int cz_send_msg_to_smc_async(struct pp_smumgr *smumgr,
+								uint16_t msg)
+{
+	int result = 0;
+
+	if (smumgr == NULL || smumgr->device == NULL)
+		return -EINVAL;
+
+	result = SMUM_WAIT_FIELD_UNEQUAL(smumgr,
+					SMU_MP1_SRBM2P_RESP_0, CONTENT, 0);
+	if (result != 0) {
+		printk(KERN_ERR "[ powerplay ] cz_send_msg_to_smc_async failed\n");
+		return result;
+	}
+
+	cgs_write_register(smumgr->device, mmSMU_MP1_SRBM2P_RESP_0, 0);
+	cgs_write_register(smumgr->device, mmSMU_MP1_SRBM2P_MSG_0, msg);
+
+	return 0;
+}
+
+/* Send a message to the SMC, and wait for its response.*/
+static int cz_send_msg_to_smc(struct pp_smumgr *smumgr, uint16_t msg)
+{
+	int result = 0;
+
+	result = cz_send_msg_to_smc_async(smumgr, msg);
+	if (result != 0)
+		return result;
+
+	result = SMUM_WAIT_FIELD_UNEQUAL(smumgr,
+					SMU_MP1_SRBM2P_RESP_0, CONTENT, 0);
+
+	if (result != 0)
+		return result;
+
+	return 0;
+}
+
+static int cz_set_smc_sram_address(struct pp_smumgr *smumgr,
+				     uint32_t smc_address, uint32_t limit)
+{
+	if (smumgr == NULL || smumgr->device == NULL)
+		return -EINVAL;
+
+	if (0 != (3 & smc_address)) {
+		printk(KERN_ERR "[ powerplay ] SMC address must be 4 byte aligned\n");
+		return -1;
+	}
+
+	if (limit <= (smc_address + 3)) {
+		printk(KERN_ERR "[ powerplay ] SMC address beyond the SMC RAM area\n");
+		return -1;
+	}
+
+	cgs_write_register(smumgr->device, mmMP0PUB_IND_INDEX_0,
+				SMN_MP1_SRAM_START_ADDR + smc_address);
+
+	return 0;
+}
+
+static int cz_write_smc_sram_dword(struct pp_smumgr *smumgr,
+		uint32_t smc_address, uint32_t value, uint32_t limit)
+{
+	int result;
+
+	if (smumgr == NULL || smumgr->device == NULL)
+		return -EINVAL;
+
+	result = cz_set_smc_sram_address(smumgr, smc_address, limit);
+	cgs_write_register(smumgr->device, mmMP0PUB_IND_DATA_0, value);
+
+	return 0;
+}
+
+static int cz_send_msg_to_smc_with_parameter(struct pp_smumgr *smumgr,
+					  uint16_t msg, uint32_t parameter)
+{
+	if (smumgr == NULL || smumgr->device == NULL)
+		return -EINVAL;
+
+	cgs_write_register(smumgr->device, mmSMU_MP1_SRBM2P_ARG_0, parameter);
+
+	return cz_send_msg_to_smc(smumgr, msg);
+}
+
+static int cz_request_smu_load_fw(struct pp_smumgr *smumgr)
+{
+	struct cz_smumgr *cz_smu = (struct cz_smumgr *)(smumgr->backend);
+	int result = 0;
+	uint32_t smc_address;
+
+	if (!smumgr->reload_fw) {
+		printk(KERN_INFO "[ powerplay ] skip reloading...\n");
+		return 0;
+	}
+
+	smc_address = SMU8_FIRMWARE_HEADER_LOCATION +
+		offsetof(struct SMU8_Firmware_Header, UcodeLoadStatus);
+
+	cz_write_smc_sram_dword(smumgr, smc_address, 0, smc_address+4);
+
+	cz_send_msg_to_smc_with_parameter(smumgr,
+					PPSMC_MSG_DriverDramAddrHi,
+					cz_smu->toc_buffer.mc_addr_high);
+
+	cz_send_msg_to_smc_with_parameter(smumgr,
+					PPSMC_MSG_DriverDramAddrLo,
+					cz_smu->toc_buffer.mc_addr_low);
+
+	cz_send_msg_to_smc(smumgr, PPSMC_MSG_InitJobs);
+
+	cz_send_msg_to_smc_with_parameter(smumgr,
+					PPSMC_MSG_ExecuteJob,
+					cz_smu->toc_entry_aram);
+	cz_send_msg_to_smc_with_parameter(smumgr, PPSMC_MSG_ExecuteJob,
+				cz_smu->toc_entry_power_profiling_index);
+
+	result = cz_send_msg_to_smc_with_parameter(smumgr,
+					PPSMC_MSG_ExecuteJob,
+					cz_smu->toc_entry_initialize_index);
+
+	return result;
+}
+
+static int cz_check_fw_load_finish(struct pp_smumgr *smumgr,
+				   uint32_t firmware)
+{
+	int i;
+	uint32_t index = SMN_MP1_SRAM_START_ADDR +
+			 SMU8_FIRMWARE_HEADER_LOCATION +
+			 offsetof(struct SMU8_Firmware_Header, UcodeLoadStatus);
+
+	if (smumgr == NULL || smumgr->device == NULL)
+		return -EINVAL;
+
+	return cgs_read_register(smumgr->device,
+					mmSMU_MP1_SRBM2P_ARG_0);
+
+	cgs_write_register(smumgr->device, mmMP0PUB_IND_INDEX, index);
+
+	for (i = 0; i < smumgr->usec_timeout; i++) {
+		if (firmware ==
+			(cgs_read_register(smumgr->device, mmMP0PUB_IND_DATA) & firmware))
+			break;
+		udelay(1);
+	}
+
+	if (i >= smumgr->usec_timeout) {
+		printk(KERN_ERR "[ powerplay ] SMU check loaded firmware failed.\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int cz_load_mec_firmware(struct pp_smumgr *smumgr)
+{
+	uint32_t reg_data;
+	uint32_t tmp;
+	int ret = 0;
+	struct cgs_firmware_info info = {0};
+	struct cz_smumgr *cz_smu;
+
+	if (smumgr == NULL || smumgr->device == NULL)
+		return -EINVAL;
+
+	cz_smu = (struct cz_smumgr *)smumgr->backend;
+	ret = cgs_get_firmware_info(smumgr->device,
+						CGS_UCODE_ID_CP_MEC, &info);
+
+	if (ret)
+		return -EINVAL;
+
+	/* Disable MEC parsing/prefetching */
+	tmp = cgs_read_register(smumgr->device,
+					mmCP_MEC_CNTL);
+	tmp = SMUM_SET_FIELD(tmp, CP_MEC_CNTL, MEC_ME1_HALT, 1);
+	tmp = SMUM_SET_FIELD(tmp, CP_MEC_CNTL, MEC_ME2_HALT, 1);
+	cgs_write_register(smumgr->device, mmCP_MEC_CNTL, tmp);
+
+	tmp = cgs_read_register(smumgr->device,
+					mmCP_CPC_IC_BASE_CNTL);
+
+	tmp = SMUM_SET_FIELD(tmp, CP_CPC_IC_BASE_CNTL, VMID, 0);
+	tmp = SMUM_SET_FIELD(tmp, CP_CPC_IC_BASE_CNTL, ATC, 0);
+	tmp = SMUM_SET_FIELD(tmp, CP_CPC_IC_BASE_CNTL, CACHE_POLICY, 0);
+	tmp = SMUM_SET_FIELD(tmp, CP_CPC_IC_BASE_CNTL, MTYPE, 1);
+	cgs_write_register(smumgr->device, mmCP_CPC_IC_BASE_CNTL, tmp);
+
+	reg_data = smu_lower_32_bits(info.mc_addr) &
+			SMUM_FIELD_MASK(CP_CPC_IC_BASE_LO, IC_BASE_LO);
+	cgs_write_register(smumgr->device, mmCP_CPC_IC_BASE_LO, reg_data);
+
+	reg_data = smu_upper_32_bits(info.mc_addr) &
+			SMUM_FIELD_MASK(CP_CPC_IC_BASE_HI, IC_BASE_HI);
+	cgs_write_register(smumgr->device, mmCP_CPC_IC_BASE_HI, reg_data);
+
+	return 0;
+}
+
+static int cz_start_smu(struct pp_smumgr *smumgr)
+{
+	int ret = 0;
+	uint32_t fw_to_check = UCODE_ID_RLC_G_MASK |
+				UCODE_ID_SDMA0_MASK |
+				UCODE_ID_SDMA1_MASK |
+				UCODE_ID_CP_CE_MASK |
+				UCODE_ID_CP_ME_MASK |
+				UCODE_ID_CP_PFP_MASK |
+				UCODE_ID_CP_MEC_JT1_MASK |
+				UCODE_ID_CP_MEC_JT2_MASK;
+
+	if (smumgr->chip_id == CHIP_STONEY)
+		fw_to_check &= ~(UCODE_ID_SDMA1_MASK | UCODE_ID_CP_MEC_JT2_MASK);
+
+	cz_request_smu_load_fw(smumgr);
+	cz_check_fw_load_finish(smumgr, fw_to_check);
+
+	ret = cz_load_mec_firmware(smumgr);
+	if (ret)
+		printk(KERN_ERR "[ powerplay ] Mec Firmware load failed\n");
+
+	return ret;
+}
+
+static uint8_t cz_translate_firmware_enum_to_arg(struct pp_smumgr *smumgr,
+			enum cz_scratch_entry firmware_enum)
+{
+	uint8_t ret = 0;
+
+	switch (firmware_enum) {
+	case CZ_SCRATCH_ENTRY_UCODE_ID_SDMA0:
+		ret = UCODE_ID_SDMA0;
+		break;
+	case CZ_SCRATCH_ENTRY_UCODE_ID_SDMA1:
+		if (smumgr->chip_id == CHIP_STONEY)
+			ret = UCODE_ID_SDMA0;
+		else
+			ret = UCODE_ID_SDMA1;
+		break;
+	case CZ_SCRATCH_ENTRY_UCODE_ID_CP_CE:
+		ret = UCODE_ID_CP_CE;
+		break;
+	case CZ_SCRATCH_ENTRY_UCODE_ID_CP_PFP:
+		ret = UCODE_ID_CP_PFP;
+		break;
+	case CZ_SCRATCH_ENTRY_UCODE_ID_CP_ME:
+		ret = UCODE_ID_CP_ME;
+		break;
+	case CZ_SCRATCH_ENTRY_UCODE_ID_CP_MEC_JT1:
+		ret = UCODE_ID_CP_MEC_JT1;
+		break;
+	case CZ_SCRATCH_ENTRY_UCODE_ID_CP_MEC_JT2:
+		if (smumgr->chip_id == CHIP_STONEY)
+			ret = UCODE_ID_CP_MEC_JT1;
+		else
+			ret = UCODE_ID_CP_MEC_JT2;
+		break;
+	case CZ_SCRATCH_ENTRY_UCODE_ID_GMCON_RENG:
+		ret = UCODE_ID_GMCON_RENG;
+		break;
+	case CZ_SCRATCH_ENTRY_UCODE_ID_RLC_G:
+		ret = UCODE_ID_RLC_G;
+		break;
+	case CZ_SCRATCH_ENTRY_UCODE_ID_RLC_SCRATCH:
+		ret = UCODE_ID_RLC_SCRATCH;
+		break;
+	case CZ_SCRATCH_ENTRY_UCODE_ID_RLC_SRM_ARAM:
+		ret = UCODE_ID_RLC_SRM_ARAM;
+		break;
+	case CZ_SCRATCH_ENTRY_UCODE_ID_RLC_SRM_DRAM:
+		ret = UCODE_ID_RLC_SRM_DRAM;
+		break;
+	case CZ_SCRATCH_ENTRY_UCODE_ID_DMCU_ERAM:
+		ret = UCODE_ID_DMCU_ERAM;
+		break;
+	case CZ_SCRATCH_ENTRY_UCODE_ID_DMCU_IRAM:
+		ret = UCODE_ID_DMCU_IRAM;
+		break;
+	case CZ_SCRATCH_ENTRY_UCODE_ID_POWER_PROFILING:
+		ret = TASK_ARG_INIT_MM_PWR_LOG;
+		break;
+	case CZ_SCRATCH_ENTRY_DATA_ID_SDMA_HALT:
+	case CZ_SCRATCH_ENTRY_DATA_ID_SYS_CLOCKGATING:
+	case CZ_SCRATCH_ENTRY_DATA_ID_SDMA_RING_REGS:
+	case CZ_SCRATCH_ENTRY_DATA_ID_NONGFX_REINIT:
+	case CZ_SCRATCH_ENTRY_DATA_ID_SDMA_START:
+	case CZ_SCRATCH_ENTRY_DATA_ID_IH_REGISTERS:
+		ret = TASK_ARG_REG_MMIO;
+		break;
+	case CZ_SCRATCH_ENTRY_SMU8_FUSION_CLKTABLE:
+		ret = TASK_ARG_INIT_CLK_TABLE;
+		break;
+	}
+
+	return ret;
+}
+
+static enum cgs_ucode_id cz_convert_fw_type_to_cgs(uint32_t fw_type)
+{
+	enum cgs_ucode_id result = CGS_UCODE_ID_MAXIMUM;
+
+	switch (fw_type) {
+	case UCODE_ID_SDMA0:
+		result = CGS_UCODE_ID_SDMA0;
+		break;
+	case UCODE_ID_SDMA1:
+		result = CGS_UCODE_ID_SDMA1;
+		break;
+	case UCODE_ID_CP_CE:
+		result = CGS_UCODE_ID_CP_CE;
+		break;
+	case UCODE_ID_CP_PFP:
+		result = CGS_UCODE_ID_CP_PFP;
+		break;
+	case UCODE_ID_CP_ME:
+		result = CGS_UCODE_ID_CP_ME;
+		break;
+	case UCODE_ID_CP_MEC_JT1:
+		result = CGS_UCODE_ID_CP_MEC_JT1;
+		break;
+	case UCODE_ID_CP_MEC_JT2:
+		result = CGS_UCODE_ID_CP_MEC_JT2;
+		break;
+	case UCODE_ID_RLC_G:
+		result = CGS_UCODE_ID_RLC_G;
+		break;
+	default:
+		break;
+	}
+
+	return result;
+}
+
+static int cz_smu_populate_single_scratch_task(
+			struct pp_smumgr *smumgr,
+			enum cz_scratch_entry fw_enum,
+			uint8_t type, bool is_last)
+{
+	uint8_t i;
+	struct cz_smumgr *cz_smu = (struct cz_smumgr *)smumgr->backend;
+	struct TOC *toc = (struct TOC *)cz_smu->toc_buffer.kaddr;
+	struct SMU_Task *task = &toc->tasks[cz_smu->toc_entry_used_count++];
+
+	task->type = type;
+	task->arg = cz_translate_firmware_enum_to_arg(smumgr, fw_enum);
+	task->next = is_last ? END_OF_TASK_LIST : cz_smu->toc_entry_used_count;
+
+	for (i = 0; i < cz_smu->scratch_buffer_length; i++)
+		if (cz_smu->scratch_buffer[i].firmware_ID == fw_enum)
+			break;
+
+	if (i >= cz_smu->scratch_buffer_length) {
+		printk(KERN_ERR "[ powerplay ] Invalid Firmware Type\n");
+		return -EINVAL;
+	}
+
+	task->addr.low = cz_smu->scratch_buffer[i].mc_addr_low;
+	task->addr.high = cz_smu->scratch_buffer[i].mc_addr_high;
+	task->size_bytes = cz_smu->scratch_buffer[i].data_size;
+
+	if (CZ_SCRATCH_ENTRY_DATA_ID_IH_REGISTERS == fw_enum) {
+		struct cz_ih_meta_data *pIHReg_restore =
+		     (struct cz_ih_meta_data *)cz_smu->scratch_buffer[i].kaddr;
+		pIHReg_restore->command =
+			METADATA_CMD_MODE0 | METADATA_PERFORM_ON_LOAD;
+	}
+
+	return 0;
+}
+
+static int cz_smu_populate_single_ucode_load_task(
+					struct pp_smumgr *smumgr,
+					enum cz_scratch_entry fw_enum,
+					bool is_last)
+{
+	uint8_t i;
+	struct cz_smumgr *cz_smu = (struct cz_smumgr *)smumgr->backend;
+	struct TOC *toc = (struct TOC *)cz_smu->toc_buffer.kaddr;
+	struct SMU_Task *task = &toc->tasks[cz_smu->toc_entry_used_count++];
+
+	task->type = TASK_TYPE_UCODE_LOAD;
+	task->arg = cz_translate_firmware_enum_to_arg(smumgr, fw_enum);
+	task->next = is_last ? END_OF_TASK_LIST : cz_smu->toc_entry_used_count;
+
+	for (i = 0; i < cz_smu->driver_buffer_length; i++)
+		if (cz_smu->driver_buffer[i].firmware_ID == fw_enum)
+			break;
+
+	if (i >= cz_smu->driver_buffer_length) {
+		printk(KERN_ERR "[ powerplay ] Invalid Firmware Type\n");
+		return -EINVAL;
+	}
+
+	task->addr.low = cz_smu->driver_buffer[i].mc_addr_low;
+	task->addr.high = cz_smu->driver_buffer[i].mc_addr_high;
+	task->size_bytes = cz_smu->driver_buffer[i].data_size;
+
+	return 0;
+}
+
+static int cz_smu_construct_toc_for_rlc_aram_save(struct pp_smumgr *smumgr)
+{
+	struct cz_smumgr *cz_smu = (struct cz_smumgr *)smumgr->backend;
+
+	cz_smu->toc_entry_aram = cz_smu->toc_entry_used_count;
+	cz_smu_populate_single_scratch_task(smumgr,
+				CZ_SCRATCH_ENTRY_UCODE_ID_RLC_SRM_ARAM,
+				TASK_TYPE_UCODE_SAVE, true);
+
+	return 0;
+}
+
+static int cz_smu_initialize_toc_empty_job_list(struct pp_smumgr *smumgr)
+{
+	int i;
+	struct cz_smumgr *cz_smu = (struct cz_smumgr *)smumgr->backend;
+	struct TOC *toc = (struct TOC *)cz_smu->toc_buffer.kaddr;
+
+	for (i = 0; i < NUM_JOBLIST_ENTRIES; i++)
+		toc->JobList[i] = (uint8_t)IGNORE_JOB;
+
+	return 0;
+}
+
+static int cz_smu_construct_toc_for_vddgfx_enter(struct pp_smumgr *smumgr)
+{
+	struct cz_smumgr *cz_smu = (struct cz_smumgr *)smumgr->backend;
+	struct TOC *toc = (struct TOC *)cz_smu->toc_buffer.kaddr;
+
+	toc->JobList[JOB_GFX_SAVE] = (uint8_t)cz_smu->toc_entry_used_count;
+	cz_smu_populate_single_scratch_task(smumgr,
+				    CZ_SCRATCH_ENTRY_UCODE_ID_RLC_SCRATCH,
+				    TASK_TYPE_UCODE_SAVE, false);
+
+	cz_smu_populate_single_scratch_task(smumgr,
+				    CZ_SCRATCH_ENTRY_UCODE_ID_RLC_SRM_DRAM,
+				    TASK_TYPE_UCODE_SAVE, true);
+
+	return 0;
+}
+
+
+static int cz_smu_construct_toc_for_vddgfx_exit(struct pp_smumgr *smumgr)
+{
+	struct cz_smumgr *cz_smu = (struct cz_smumgr *)smumgr->backend;
+	struct TOC *toc = (struct TOC *)cz_smu->toc_buffer.kaddr;
+
+	toc->JobList[JOB_GFX_RESTORE] = (uint8_t)cz_smu->toc_entry_used_count;
+
+	cz_smu_populate_single_ucode_load_task(smumgr,
+				CZ_SCRATCH_ENTRY_UCODE_ID_CP_CE, false);
+	cz_smu_populate_single_ucode_load_task(smumgr,
+				CZ_SCRATCH_ENTRY_UCODE_ID_CP_PFP, false);
+	cz_smu_populate_single_ucode_load_task(smumgr,
+				CZ_SCRATCH_ENTRY_UCODE_ID_CP_ME, false);
+	cz_smu_populate_single_ucode_load_task(smumgr,
+				CZ_SCRATCH_ENTRY_UCODE_ID_CP_MEC_JT1, false);
+
+	if (smumgr->chip_id == CHIP_STONEY)
+		cz_smu_populate_single_ucode_load_task(smumgr,
+				CZ_SCRATCH_ENTRY_UCODE_ID_CP_MEC_JT1, false);
+	else
+		cz_smu_populate_single_ucode_load_task(smumgr,
+				CZ_SCRATCH_ENTRY_UCODE_ID_CP_MEC_JT2, false);
+
+	cz_smu_populate_single_ucode_load_task(smumgr,
+				CZ_SCRATCH_ENTRY_UCODE_ID_RLC_G, false);
+
+	/* populate scratch */
+	cz_smu_populate_single_scratch_task(smumgr,
+				CZ_SCRATCH_ENTRY_UCODE_ID_RLC_SCRATCH,
+				TASK_TYPE_UCODE_LOAD, false);
+
+	cz_smu_populate_single_scratch_task(smumgr,
+				CZ_SCRATCH_ENTRY_UCODE_ID_RLC_SRM_ARAM,
+				TASK_TYPE_UCODE_LOAD, false);
+
+	cz_smu_populate_single_scratch_task(smumgr,
+				CZ_SCRATCH_ENTRY_UCODE_ID_RLC_SRM_DRAM,
+				TASK_TYPE_UCODE_LOAD, true);
+
+	return 0;
+}
+
+static int cz_smu_construct_toc_for_power_profiling(
+						 struct pp_smumgr *smumgr)
+{
+	struct cz_smumgr *cz_smu = (struct cz_smumgr *)smumgr->backend;
+
+	cz_smu->toc_entry_power_profiling_index = cz_smu->toc_entry_used_count;
+
+	cz_smu_populate_single_scratch_task(smumgr,
+				CZ_SCRATCH_ENTRY_UCODE_ID_POWER_PROFILING,
+				TASK_TYPE_INITIALIZE, true);
+	return 0;
+}
+
+static int cz_smu_construct_toc_for_bootup(struct pp_smumgr *smumgr)
+{
+	struct cz_smumgr *cz_smu = (struct cz_smumgr *)smumgr->backend;
+
+	cz_smu->toc_entry_initialize_index = cz_smu->toc_entry_used_count;
+
+	cz_smu_populate_single_ucode_load_task(smumgr,
+				CZ_SCRATCH_ENTRY_UCODE_ID_SDMA0, false);
+	if (smumgr->chip_id == CHIP_STONEY)
+		cz_smu_populate_single_ucode_load_task(smumgr,
+				CZ_SCRATCH_ENTRY_UCODE_ID_SDMA0, false);
+	else
+		cz_smu_populate_single_ucode_load_task(smumgr,
+				CZ_SCRATCH_ENTRY_UCODE_ID_SDMA1, false);
+	cz_smu_populate_single_ucode_load_task(smumgr,
+				CZ_SCRATCH_ENTRY_UCODE_ID_CP_CE, false);
+	cz_smu_populate_single_ucode_load_task(smumgr,
+				CZ_SCRATCH_ENTRY_UCODE_ID_CP_PFP, false);
+	cz_smu_populate_single_ucode_load_task(smumgr,
+				CZ_SCRATCH_ENTRY_UCODE_ID_CP_ME, false);
+	cz_smu_populate_single_ucode_load_task(smumgr,
+				CZ_SCRATCH_ENTRY_UCODE_ID_CP_MEC_JT1, false);
+	if (smumgr->chip_id == CHIP_STONEY)
+		cz_smu_populate_single_ucode_load_task(smumgr,
+				CZ_SCRATCH_ENTRY_UCODE_ID_CP_MEC_JT1, false);
+	else
+		cz_smu_populate_single_ucode_load_task(smumgr,
+				CZ_SCRATCH_ENTRY_UCODE_ID_CP_MEC_JT2, false);
+	cz_smu_populate_single_ucode_load_task(smumgr,
+				CZ_SCRATCH_ENTRY_UCODE_ID_RLC_G, true);
+
+	return 0;
+}
+
+static int cz_smu_construct_toc_for_clock_table(struct pp_smumgr *smumgr)
+{
+	struct cz_smumgr *cz_smu = (struct cz_smumgr *)smumgr->backend;
+
+	cz_smu->toc_entry_clock_table = cz_smu->toc_entry_used_count;
+
+	cz_smu_populate_single_scratch_task(smumgr,
+				CZ_SCRATCH_ENTRY_SMU8_FUSION_CLKTABLE,
+				TASK_TYPE_INITIALIZE, true);
+
+	return 0;
+}
+
+static int cz_smu_construct_toc(struct pp_smumgr *smumgr)
+{
+	struct cz_smumgr *cz_smu = (struct cz_smumgr *)smumgr->backend;
+
+	cz_smu->toc_entry_used_count = 0;
+
+	cz_smu_initialize_toc_empty_job_list(smumgr);
+
+	cz_smu_construct_toc_for_rlc_aram_save(smumgr);
+
+	cz_smu_construct_toc_for_vddgfx_enter(smumgr);
+
+	cz_smu_construct_toc_for_vddgfx_exit(smumgr);
+
+	cz_smu_construct_toc_for_power_profiling(smumgr);
+
+	cz_smu_construct_toc_for_bootup(smumgr);
+
+	cz_smu_construct_toc_for_clock_table(smumgr);
+
+	return 0;
+}
+
+static int cz_smu_populate_firmware_entries(struct pp_smumgr *smumgr)
+{
+	struct cz_smumgr *cz_smu = (struct cz_smumgr *)smumgr->backend;
+	uint32_t firmware_type;
+	uint32_t i;
+	int ret;
+	enum cgs_ucode_id ucode_id;
+	struct cgs_firmware_info info = {0};
+
+	cz_smu->driver_buffer_length = 0;
+
+	for (i = 0; i < sizeof(firmware_list)/sizeof(*firmware_list); i++) {
+
+		firmware_type = cz_translate_firmware_enum_to_arg(smumgr,
+					firmware_list[i]);
+
+		ucode_id = cz_convert_fw_type_to_cgs(firmware_type);
+
+		ret = cgs_get_firmware_info(smumgr->device,
+							ucode_id, &info);
+
+		if (ret == 0) {
+			cz_smu->driver_buffer[i].mc_addr_high =
+					smu_upper_32_bits(info.mc_addr);
+
+			cz_smu->driver_buffer[i].mc_addr_low =
+					smu_lower_32_bits(info.mc_addr);
+
+			cz_smu->driver_buffer[i].data_size = info.image_size;
+
+			cz_smu->driver_buffer[i].firmware_ID = firmware_list[i];
+			cz_smu->driver_buffer_length++;
+		}
+	}
+
+	return 0;
+}
+
+static int cz_smu_populate_single_scratch_entry(
+				struct pp_smumgr *smumgr,
+				enum cz_scratch_entry scratch_type,
+				uint32_t ulsize_byte,
+				struct cz_buffer_entry *entry)
+{
+	struct cz_smumgr *cz_smu = (struct cz_smumgr *)smumgr->backend;
+	long long mc_addr =
+			((long long)(cz_smu->smu_buffer.mc_addr_high) << 32)
+			| cz_smu->smu_buffer.mc_addr_low;
+
+	uint32_t ulsize_aligned = SIZE_ALIGN_32(ulsize_byte);
+
+	mc_addr += cz_smu->smu_buffer_used_bytes;
+
+	entry->data_size = ulsize_byte;
+	entry->kaddr = (char *) cz_smu->smu_buffer.kaddr +
+				cz_smu->smu_buffer_used_bytes;
+	entry->mc_addr_low = smu_lower_32_bits(mc_addr);
+	entry->mc_addr_high = smu_upper_32_bits(mc_addr);
+	entry->firmware_ID = scratch_type;
+
+	cz_smu->smu_buffer_used_bytes += ulsize_aligned;
+
+	return 0;
+}
+
+static int cz_download_pptable_settings(struct pp_smumgr *smumgr, void **table)
+{
+	struct cz_smumgr *cz_smu = (struct cz_smumgr *)smumgr->backend;
+	unsigned long i;
+
+	for (i = 0; i < cz_smu->scratch_buffer_length; i++) {
+		if (cz_smu->scratch_buffer[i].firmware_ID
+			== CZ_SCRATCH_ENTRY_SMU8_FUSION_CLKTABLE)
+			break;
+	}
+
+	*table = (struct SMU8_Fusion_ClkTable *)cz_smu->scratch_buffer[i].kaddr;
+
+	cz_send_msg_to_smc_with_parameter(smumgr,
+				PPSMC_MSG_SetClkTableAddrHi,
+				cz_smu->scratch_buffer[i].mc_addr_high);
+
+	cz_send_msg_to_smc_with_parameter(smumgr,
+				PPSMC_MSG_SetClkTableAddrLo,
+				cz_smu->scratch_buffer[i].mc_addr_low);
+
+	cz_send_msg_to_smc_with_parameter(smumgr, PPSMC_MSG_ExecuteJob,
+				cz_smu->toc_entry_clock_table);
+
+	cz_send_msg_to_smc(smumgr, PPSMC_MSG_ClkTableXferToDram);
+
+	return 0;
+}
+
+static int cz_upload_pptable_settings(struct pp_smumgr *smumgr)
+{
+	struct cz_smumgr *cz_smu = (struct cz_smumgr *)smumgr->backend;
+	unsigned long i;
+
+	for (i = 0; i < cz_smu->scratch_buffer_length; i++) {
+		if (cz_smu->scratch_buffer[i].firmware_ID
+				== CZ_SCRATCH_ENTRY_SMU8_FUSION_CLKTABLE)
+			break;
+	}
+
+	cz_send_msg_to_smc_with_parameter(smumgr,
+				PPSMC_MSG_SetClkTableAddrHi,
+				cz_smu->scratch_buffer[i].mc_addr_high);
+
+	cz_send_msg_to_smc_with_parameter(smumgr,
+				PPSMC_MSG_SetClkTableAddrLo,
+				cz_smu->scratch_buffer[i].mc_addr_low);
+
+	cz_send_msg_to_smc_with_parameter(smumgr, PPSMC_MSG_ExecuteJob,
+				cz_smu->toc_entry_clock_table);
+
+	cz_send_msg_to_smc(smumgr, PPSMC_MSG_ClkTableXferToSmu);
+
+	return 0;
+}
+
+static int cz_smu_init(struct pp_smumgr *smumgr)
+{
+	struct cz_smumgr *cz_smu = (struct cz_smumgr *)smumgr->backend;
+	uint64_t mc_addr = 0;
+	int ret = 0;
+
+	cz_smu->toc_buffer.data_size = 4096;
+	cz_smu->smu_buffer.data_size =
+		ALIGN(UCODE_ID_RLC_SCRATCH_SIZE_BYTE, 32) +
+		ALIGN(UCODE_ID_RLC_SRM_ARAM_SIZE_BYTE, 32) +
+		ALIGN(UCODE_ID_RLC_SRM_DRAM_SIZE_BYTE, 32) +
+		ALIGN(sizeof(struct SMU8_MultimediaPowerLogData), 32) +
+		ALIGN(sizeof(struct SMU8_Fusion_ClkTable), 32);
+
+	ret = smu_allocate_memory(smumgr->device,
+				cz_smu->toc_buffer.data_size,
+				CGS_GPU_MEM_TYPE__GART_CACHEABLE,
+				PAGE_SIZE,
+				&mc_addr,
+				&cz_smu->toc_buffer.kaddr,
+				&cz_smu->toc_buffer.handle);
+	if (ret != 0)
+		return -1;
+
+	cz_smu->toc_buffer.mc_addr_high = smu_upper_32_bits(mc_addr);
+	cz_smu->toc_buffer.mc_addr_low = smu_lower_32_bits(mc_addr);
+
+	ret = smu_allocate_memory(smumgr->device,
+				cz_smu->smu_buffer.data_size,
+				CGS_GPU_MEM_TYPE__GART_CACHEABLE,
+				PAGE_SIZE,
+				&mc_addr,
+				&cz_smu->smu_buffer.kaddr,
+				&cz_smu->smu_buffer.handle);
+	if (ret != 0)
+		return -1;
+
+	cz_smu->smu_buffer.mc_addr_high = smu_upper_32_bits(mc_addr);
+	cz_smu->smu_buffer.mc_addr_low = smu_lower_32_bits(mc_addr);
+
+	cz_smu_populate_firmware_entries(smumgr);
+	if (0 != cz_smu_populate_single_scratch_entry(smumgr,
+		CZ_SCRATCH_ENTRY_UCODE_ID_RLC_SCRATCH,
+		UCODE_ID_RLC_SCRATCH_SIZE_BYTE,
+		&cz_smu->scratch_buffer[cz_smu->scratch_buffer_length++])) {
+		printk(KERN_ERR "[ powerplay ] Error when Populate Firmware Entry.\n");
+		return -1;
+	}
+
+	if (0 != cz_smu_populate_single_scratch_entry(smumgr,
+		CZ_SCRATCH_ENTRY_UCODE_ID_RLC_SRM_ARAM,
+		UCODE_ID_RLC_SRM_ARAM_SIZE_BYTE,
+		&cz_smu->scratch_buffer[cz_smu->scratch_buffer_length++])) {
+		printk(KERN_ERR "[ powerplay ] Error when Populate Firmware Entry.\n");
+		return -1;
+	}
+	if (0 != cz_smu_populate_single_scratch_entry(smumgr,
+		CZ_SCRATCH_ENTRY_UCODE_ID_RLC_SRM_DRAM,
+		UCODE_ID_RLC_SRM_DRAM_SIZE_BYTE,
+		&cz_smu->scratch_buffer[cz_smu->scratch_buffer_length++])) {
+		printk(KERN_ERR "[ powerplay ] Error when Populate Firmware Entry.\n");
+		return -1;
+	}
+
+	if (0 != cz_smu_populate_single_scratch_entry(smumgr,
+		CZ_SCRATCH_ENTRY_UCODE_ID_POWER_PROFILING,
+		sizeof(struct SMU8_MultimediaPowerLogData),
+		&cz_smu->scratch_buffer[cz_smu->scratch_buffer_length++])) {
+		printk(KERN_ERR "[ powerplay ] Error when Populate Firmware Entry.\n");
+		return -1;
+	}
+
+	if (0 != cz_smu_populate_single_scratch_entry(smumgr,
+		CZ_SCRATCH_ENTRY_SMU8_FUSION_CLKTABLE,
+		sizeof(struct SMU8_Fusion_ClkTable),
+		&cz_smu->scratch_buffer[cz_smu->scratch_buffer_length++])) {
+		printk(KERN_ERR "[ powerplay ] Error when Populate Firmware Entry.\n");
+		return -1;
+	}
+	cz_smu_construct_toc(smumgr);
+
+	return 0;
+}
+
+static int cz_smu_fini(struct pp_smumgr *smumgr)
+{
+	struct cz_smumgr *cz_smu;
+
+	if (smumgr == NULL || smumgr->device == NULL)
+		return -EINVAL;
+
+	cz_smu = (struct cz_smumgr *)smumgr->backend;
+	if (cz_smu) {
+		cgs_free_gpu_mem(smumgr->device,
+				cz_smu->toc_buffer.handle);
+		cgs_free_gpu_mem(smumgr->device,
+				cz_smu->smu_buffer.handle);
+		kfree(cz_smu);
+		kfree(smumgr);
+	}
+
+	return 0;
+}
+
+static const struct pp_smumgr_func cz_smu_funcs = {
+	.smu_init = cz_smu_init,
+	.smu_fini = cz_smu_fini,
+	.start_smu = cz_start_smu,
+	.check_fw_load_finish = cz_check_fw_load_finish,
+	.request_smu_load_fw = NULL,
+	.request_smu_load_specific_fw = NULL,
+	.get_argument = cz_smum_get_argument,
+	.send_msg_to_smc = cz_send_msg_to_smc,
+	.send_msg_to_smc_with_parameter = cz_send_msg_to_smc_with_parameter,
+	.download_pptable_settings = cz_download_pptable_settings,
+	.upload_pptable_settings = cz_upload_pptable_settings,
+};
+
+int cz_smum_init(struct pp_smumgr *smumgr)
+{
+	struct cz_smumgr *cz_smu;
+
+	cz_smu = kzalloc(sizeof(struct cz_smumgr), GFP_KERNEL);
+	if (cz_smu == NULL)
+		return -ENOMEM;
+
+	smumgr->backend = cz_smu;
+	smumgr->smumgr_funcs = &cz_smu_funcs;
+	return 0;
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/powerplay/smumgr/cz_smumgr.h
@@ -0,0 +1,102 @@
+/*
+ * Copyright 2015 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+#ifndef _CZ_SMUMGR_H_
+#define _CZ_SMUMGR_H_
+
+
+#define MAX_NUM_FIRMWARE                        8
+#define MAX_NUM_SCRATCH                         11
+#define CZ_SCRATCH_SIZE_NONGFX_CLOCKGATING      1024
+#define CZ_SCRATCH_SIZE_NONGFX_GOLDENSETTING    2048
+#define CZ_SCRATCH_SIZE_SDMA_METADATA           1024
+#define CZ_SCRATCH_SIZE_IH                      ((2*256+1)*4)
+
+enum cz_scratch_entry {
+	CZ_SCRATCH_ENTRY_UCODE_ID_SDMA0 = 0,
+	CZ_SCRATCH_ENTRY_UCODE_ID_SDMA1,
+	CZ_SCRATCH_ENTRY_UCODE_ID_CP_CE,
+	CZ_SCRATCH_ENTRY_UCODE_ID_CP_PFP,
+	CZ_SCRATCH_ENTRY_UCODE_ID_CP_ME,
+	CZ_SCRATCH_ENTRY_UCODE_ID_CP_MEC_JT1,
+	CZ_SCRATCH_ENTRY_UCODE_ID_CP_MEC_JT2,
+	CZ_SCRATCH_ENTRY_UCODE_ID_GMCON_RENG,
+	CZ_SCRATCH_ENTRY_UCODE_ID_RLC_G,
+	CZ_SCRATCH_ENTRY_UCODE_ID_RLC_SCRATCH,
+	CZ_SCRATCH_ENTRY_UCODE_ID_RLC_SRM_ARAM,
+	CZ_SCRATCH_ENTRY_UCODE_ID_RLC_SRM_DRAM,
+	CZ_SCRATCH_ENTRY_UCODE_ID_DMCU_ERAM,
+	CZ_SCRATCH_ENTRY_UCODE_ID_DMCU_IRAM,
+	CZ_SCRATCH_ENTRY_UCODE_ID_POWER_PROFILING,
+	CZ_SCRATCH_ENTRY_DATA_ID_SDMA_HALT,
+	CZ_SCRATCH_ENTRY_DATA_ID_SYS_CLOCKGATING,
+	CZ_SCRATCH_ENTRY_DATA_ID_SDMA_RING_REGS,
+	CZ_SCRATCH_ENTRY_DATA_ID_NONGFX_REINIT,
+	CZ_SCRATCH_ENTRY_DATA_ID_SDMA_START,
+	CZ_SCRATCH_ENTRY_DATA_ID_IH_REGISTERS,
+	CZ_SCRATCH_ENTRY_SMU8_FUSION_CLKTABLE
+};
+
+struct cz_buffer_entry {
+	uint32_t data_size;
+	uint32_t mc_addr_low;
+	uint32_t mc_addr_high;
+	void *kaddr;
+	enum cz_scratch_entry firmware_ID;
+	unsigned long handle; /* as bo handle used when release bo */
+};
+
+struct cz_register_index_data_pair {
+	uint32_t offset;
+	uint32_t value;
+};
+
+struct cz_ih_meta_data {
+	uint32_t command;
+	struct cz_register_index_data_pair register_index_value_pair[1];
+};
+
+struct cz_smumgr {
+	uint8_t driver_buffer_length;
+	uint8_t scratch_buffer_length;
+	uint16_t toc_entry_used_count;
+	uint16_t toc_entry_initialize_index;
+	uint16_t toc_entry_power_profiling_index;
+	uint16_t toc_entry_aram;
+	uint16_t toc_entry_ih_register_restore_task_index;
+	uint16_t toc_entry_clock_table;
+	uint16_t ih_register_restore_task_size;
+	uint16_t smu_buffer_used_bytes;
+
+	struct cz_buffer_entry toc_buffer;
+	struct cz_buffer_entry smu_buffer;
+	struct cz_buffer_entry firmware_buffer;
+	struct cz_buffer_entry driver_buffer[MAX_NUM_FIRMWARE];
+	struct cz_buffer_entry meta_data_buffer[MAX_NUM_FIRMWARE];
+	struct cz_buffer_entry scratch_buffer[MAX_NUM_SCRATCH];
+};
+
+struct pp_smumgr;
+
+extern int cz_smum_init(struct pp_smumgr *smumgr);
+
+#endif
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/powerplay/smumgr/fiji_smumgr.c
@@ -0,0 +1,1042 @@
+/*
+ * Copyright 2015 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#include "smumgr.h"
+#include "smu73.h"
+#include "smu_ucode_xfer_vi.h"
+#include "fiji_smumgr.h"
+#include "fiji_ppsmc.h"
+#include "smu73_discrete.h"
+#include "ppatomctrl.h"
+#include "smu/smu_7_1_3_d.h"
+#include "smu/smu_7_1_3_sh_mask.h"
+#include "gmc/gmc_8_1_d.h"
+#include "gmc/gmc_8_1_sh_mask.h"
+#include "oss/oss_3_0_d.h"
+#include "gca/gfx_8_0_d.h"
+#include "bif/bif_5_0_d.h"
+#include "bif/bif_5_0_sh_mask.h"
+#include "pp_debug.h"
+#include "fiji_pwrvirus.h"
+
+#define AVFS_EN_MSB                                        1568
+#define AVFS_EN_LSB                                        1568
+
+#define FIJI_SMC_SIZE 0x20000
+
+struct SMU73_Discrete_GraphicsLevel avfs_graphics_level[8] = {
+		/*  Min        Sclk       pcie     DeepSleep Activity  CgSpll      CgSpll    spllSpread  SpllSpread   CcPwr  CcPwr  Sclk   Display     Enabled     Enabled                       Voltage    Power */
+		/* Voltage,  Frequency,  DpmLevel,  DivId,    Level,  FuncCntl3,  FuncCntl4,  Spectrum,   Spectrum2,  DynRm, DynRm1  Did, Watermark, ForActivity, ForThrottle, UpHyst, DownHyst, DownHyst, Throttle */
+		{ 0x3c0fd047, 0x30750000,   0x00,     0x03,   0x1e00, 0x00200410, 0x87020000, 0x21680000, 0x0c000000,   0,      0,   0x16,   0x00,       0x01,        0x01,      0x00,   0x00,      0x00,     0x00 },
+		{ 0xa00fd047, 0x409c0000,   0x01,     0x04,   0x1e00, 0x00800510, 0x87020000, 0x21680000, 0x11000000,   0,      0,   0x16,   0x00,       0x01,        0x01,      0x00,   0x00,      0x00,     0x00 },
+		{ 0x0410d047, 0x50c30000,   0x01,     0x00,   0x1e00, 0x00600410, 0x87020000, 0x21680000, 0x0d000000,   0,      0,   0x0e,   0x00,       0x01,        0x01,      0x00,   0x00,      0x00,     0x00 },
+		{ 0x6810d047, 0x60ea0000,   0x01,     0x00,   0x1e00, 0x00800410, 0x87020000, 0x21680000, 0x0e000000,   0,      0,   0x0c,   0x00,       0x01,        0x01,      0x00,   0x00,      0x00,     0x00 },
+		{ 0xcc10d047, 0xe8fd0000,   0x01,     0x00,   0x1e00, 0x00e00410, 0x87020000, 0x21680000, 0x0f000000,   0,      0,   0x0c,   0x00,       0x01,        0x01,      0x00,   0x00,      0x00,     0x00 },
+		{ 0x3011d047, 0x70110100,   0x01,     0x00,   0x1e00, 0x00400510, 0x87020000, 0x21680000, 0x10000000,   0,      0,   0x0c,   0x00,       0x01,        0x01,      0x00,   0x00,      0x00,     0x00 },
+		{ 0x9411d047, 0xf8240100,   0x01,     0x00,   0x1e00, 0x00a00510, 0x87020000, 0x21680000, 0x11000000,   0,      0,   0x0c,   0x00,       0x01,        0x01,      0x00,   0x00,      0x00,     0x00 },
+		{ 0xf811d047, 0x80380100,   0x01,     0x00,   0x1e00, 0x00000610, 0x87020000, 0x21680000, 0x12000000,   0,      0,   0x0c,   0x01,       0x01,        0x01,      0x00,   0x00,      0x00,     0x00 }
+};
+
+static enum cgs_ucode_id fiji_convert_fw_type_to_cgs(uint32_t fw_type)
+{
+	enum cgs_ucode_id result = CGS_UCODE_ID_MAXIMUM;
+
+	switch (fw_type) {
+	case UCODE_ID_SMU:
+		result = CGS_UCODE_ID_SMU;
+		break;
+	case UCODE_ID_SDMA0:
+		result = CGS_UCODE_ID_SDMA0;
+		break;
+	case UCODE_ID_SDMA1:
+		result = CGS_UCODE_ID_SDMA1;
+		break;
+	case UCODE_ID_CP_CE:
+		result = CGS_UCODE_ID_CP_CE;
+		break;
+	case UCODE_ID_CP_PFP:
+		result = CGS_UCODE_ID_CP_PFP;
+		break;
+	case UCODE_ID_CP_ME:
+		result = CGS_UCODE_ID_CP_ME;
+		break;
+	case UCODE_ID_CP_MEC:
+		result = CGS_UCODE_ID_CP_MEC;
+		break;
+	case UCODE_ID_CP_MEC_JT1:
+		result = CGS_UCODE_ID_CP_MEC_JT1;
+		break;
+	case UCODE_ID_CP_MEC_JT2:
+		result = CGS_UCODE_ID_CP_MEC_JT2;
+		break;
+	case UCODE_ID_RLC_G:
+		result = CGS_UCODE_ID_RLC_G;
+		break;
+	default:
+		break;
+	}
+
+	return result;
+}
+/**
+* Set the address for reading/writing the SMC SRAM space.
+* @param    smumgr  the address of the powerplay hardware manager.
+* @param    smc_addr the address in the SMC RAM to access.
+*/
+static int fiji_set_smc_sram_address(struct pp_smumgr *smumgr,
+		uint32_t smc_addr, uint32_t limit)
+{
+	PP_ASSERT_WITH_CODE((0 == (3 & smc_addr)),
+			"SMC address must be 4 byte aligned.", return -EINVAL;);
+	PP_ASSERT_WITH_CODE((limit > (smc_addr + 3)),
+			"SMC address is beyond the SMC RAM area.", return -EINVAL;);
+
+	cgs_write_register(smumgr->device, mmSMC_IND_INDEX_0, smc_addr);
+	SMUM_WRITE_FIELD(smumgr->device, SMC_IND_ACCESS_CNTL, AUTO_INCREMENT_IND_0, 0);
+
+	return 0;
+}
+
+/**
+* Copy bytes from an array into the SMC RAM space.
+*
+* @param    smumgr  the address of the powerplay SMU manager.
+* @param    smcStartAddress the start address in the SMC RAM to copy bytes to.
+* @param    src the byte array to copy the bytes from.
+* @param    byteCount the number of bytes to copy.
+*/
+int fiji_copy_bytes_to_smc(struct pp_smumgr *smumgr,
+		uint32_t smcStartAddress, const uint8_t *src,
+		uint32_t byteCount, uint32_t limit)
+{
+	int result;
+	uint32_t data, originalData;
+	uint32_t addr, extraShift;
+
+	PP_ASSERT_WITH_CODE((0 == (3 & smcStartAddress)),
+			"SMC address must be 4 byte aligned.", return -EINVAL;);
+	PP_ASSERT_WITH_CODE((limit > (smcStartAddress + byteCount)),
+			"SMC address is beyond the SMC RAM area.", return -EINVAL;);
+
+	addr = smcStartAddress;
+
+	while (byteCount >= 4) {
+		/* Bytes are written into the SMC addres space with the MSB first. */
+		data = src[0] * 0x1000000 + src[1] * 0x10000 + src[2] * 0x100 + src[3];
+
+		result = fiji_set_smc_sram_address(smumgr, addr, limit);
+		if (result)
+			return result;
+
+		cgs_write_register(smumgr->device, mmSMC_IND_DATA_0, data);
+
+		src += 4;
+		byteCount -= 4;
+		addr += 4;
+	}
+
+	if (byteCount) {
+		/* Now write the odd bytes left.
+		 * Do a read modify write cycle.
+		 */
+		data = 0;
+
+		result = fiji_set_smc_sram_address(smumgr, addr, limit);
+		if (result)
+			return result;
+
+		originalData = cgs_read_register(smumgr->device, mmSMC_IND_DATA_0);
+		extraShift = 8 * (4 - byteCount);
+
+		while (byteCount > 0) {
+			/* Bytes are written into the SMC addres
+			 * space with the MSB first.
+			 */
+			data = (0x100 * data) + *src++;
+			byteCount--;
+		}
+		data <<= extraShift;
+		data |= (originalData & ~((~0UL) << extraShift));
+
+		result = fiji_set_smc_sram_address(smumgr, addr, limit);
+		if (!result)
+			return result;
+
+		cgs_write_register(smumgr->device, mmSMC_IND_DATA_0, data);
+	}
+	return 0;
+}
+
+int fiji_program_jump_on_start(struct pp_smumgr *smumgr)
+{
+	static unsigned char data[] = { 0xE0, 0x00, 0x80, 0x40 };
+
+	fiji_copy_bytes_to_smc(smumgr, 0x0, data, 4, sizeof(data) + 1);
+
+	return 0;
+}
+
+/**
+* Return if the SMC is currently running.
+*
+* @param    smumgr  the address of the powerplay hardware manager.
+*/
+bool fiji_is_smc_ram_running(struct pp_smumgr *smumgr)
+{
+	return ((0 == SMUM_READ_VFPF_INDIRECT_FIELD(smumgr->device,
+			CGS_IND_REG__SMC,
+			SMC_SYSCON_CLOCK_CNTL_0, ck_disable))
+			&& (0x20100 <= cgs_read_ind_register(smumgr->device,
+					CGS_IND_REG__SMC, ixSMC_PC_C)));
+}
+
+/**
+* Send a message to the SMC, and wait for its response.
+*
+* @param    smumgr  the address of the powerplay hardware manager.
+* @param    msg the message to send.
+* @return   The response that came from the SMC.
+*/
+int fiji_send_msg_to_smc(struct pp_smumgr *smumgr, uint16_t msg)
+{
+	if (!fiji_is_smc_ram_running(smumgr))
+		return -1;
+
+	if (1 != SMUM_READ_FIELD(smumgr->device, SMC_RESP_0, SMC_RESP)) {
+		printk(KERN_ERR "Failed to send Previous Message.");
+		SMUM_WAIT_FIELD_UNEQUAL(smumgr, SMC_RESP_0, SMC_RESP, 0);
+	}
+
+	cgs_write_register(smumgr->device, mmSMC_MESSAGE_0, msg);
+	SMUM_WAIT_FIELD_UNEQUAL(smumgr, SMC_RESP_0, SMC_RESP, 0);
+
+	return 0;
+}
+
+/**
+ * Send a message to the SMC with parameter
+ * @param    smumgr:  the address of the powerplay hardware manager.
+ * @param    msg: the message to send.
+ * @param    parameter: the parameter to send
+ * @return   The response that came from the SMC.
+ */
+int fiji_send_msg_to_smc_with_parameter(struct pp_smumgr *smumgr,
+		uint16_t msg, uint32_t parameter)
+{
+	if (!fiji_is_smc_ram_running(smumgr))
+		return -1;
+
+	if (1 != SMUM_READ_FIELD(smumgr->device, SMC_RESP_0, SMC_RESP)) {
+		printk(KERN_ERR "Failed to send Previous Message.");
+		SMUM_WAIT_FIELD_UNEQUAL(smumgr, SMC_RESP_0, SMC_RESP, 0);
+	}
+
+	cgs_write_register(smumgr->device, mmSMC_MSG_ARG_0, parameter);
+	cgs_write_register(smumgr->device, mmSMC_MESSAGE_0, msg);
+	SMUM_WAIT_FIELD_UNEQUAL(smumgr, SMC_RESP_0, SMC_RESP, 0);
+
+	return 0;
+}
+
+
+/**
+* Send a message to the SMC with parameter, do not wait for response
+*
+* @param    smumgr:  the address of the powerplay hardware manager.
+* @param    msg: the message to send.
+* @param    parameter: the parameter to send
+* @return   The response that came from the SMC.
+*/
+int fiji_send_msg_to_smc_with_parameter_without_waiting(
+		struct pp_smumgr *smumgr, uint16_t msg, uint32_t parameter)
+{
+	if (1 != SMUM_READ_FIELD(smumgr->device, SMC_RESP_0, SMC_RESP)) {
+		printk(KERN_ERR "Failed to send Previous Message.");
+		SMUM_WAIT_FIELD_UNEQUAL(smumgr, SMC_RESP_0, SMC_RESP, 0);
+	}
+	cgs_write_register(smumgr->device, mmSMC_MSG_ARG_0, parameter);
+	cgs_write_register(smumgr->device, mmSMC_MESSAGE_0, msg);
+
+	return 0;
+}
+
+/**
+* Uploads the SMU firmware from .hex file
+*
+* @param    smumgr  the address of the powerplay SMU manager.
+* @return   0 or -1.
+*/
+
+static int fiji_upload_smu_firmware_image(struct pp_smumgr *smumgr)
+{
+	const uint8_t *src;
+	uint32_t byte_count;
+	uint32_t *data;
+	struct cgs_firmware_info info = {0};
+
+	cgs_get_firmware_info(smumgr->device,
+			fiji_convert_fw_type_to_cgs(UCODE_ID_SMU), &info);
+
+	if (info.image_size & 3) {
+		printk(KERN_ERR "SMC ucode is not 4 bytes aligned\n");
+		return -EINVAL;
+	}
+
+	if (info.image_size > FIJI_SMC_SIZE) {
+		printk(KERN_ERR "SMC address is beyond the SMC RAM area\n");
+		return -EINVAL;
+	}
+
+	cgs_write_register(smumgr->device, mmSMC_IND_INDEX_0, 0x20000);
+	SMUM_WRITE_FIELD(smumgr->device, SMC_IND_ACCESS_CNTL, AUTO_INCREMENT_IND_0, 1);
+
+	byte_count = info.image_size;
+	src = (const uint8_t *)info.kptr;
+
+	data = (uint32_t *)src;
+	for (; byte_count >= 4; data++, byte_count -= 4)
+		cgs_write_register(smumgr->device, mmSMC_IND_DATA_0, data[0]);
+
+	SMUM_WRITE_FIELD(smumgr->device, SMC_IND_ACCESS_CNTL, AUTO_INCREMENT_IND_0, 0);
+	return 0;
+}
+
+/**
+* Read a 32bit value from the SMC SRAM space.
+* ALL PARAMETERS ARE IN HOST BYTE ORDER.
+* @param    smumgr  the address of the powerplay hardware manager.
+* @param    smc_addr the address in the SMC RAM to access.
+* @param    value and output parameter for the data read from the SMC SRAM.
+*/
+int fiji_read_smc_sram_dword(struct pp_smumgr *smumgr, uint32_t smc_addr,
+		uint32_t *value, uint32_t limit)
+{
+	int	result = fiji_set_smc_sram_address(smumgr, smc_addr, limit);
+
+	if (result)
+		return result;
+
+	*value = cgs_read_register(smumgr->device, mmSMC_IND_DATA_0);
+	return 0;
+}
+
+/**
+* Write a 32bit value to the SMC SRAM space.
+* ALL PARAMETERS ARE IN HOST BYTE ORDER.
+* @param    smumgr  the address of the powerplay hardware manager.
+* @param    smc_addr the address in the SMC RAM to access.
+* @param    value to write to the SMC SRAM.
+*/
+int fiji_write_smc_sram_dword(struct pp_smumgr *smumgr, uint32_t smc_addr,
+		uint32_t value, uint32_t limit)
+{
+	int result;
+
+	result = fiji_set_smc_sram_address(smumgr, smc_addr, limit);
+
+	if (result)
+		return result;
+
+	cgs_write_register(smumgr->device, mmSMC_IND_DATA_0, value);
+	return 0;
+}
+
+static uint32_t fiji_get_mask_for_firmware_type(uint32_t fw_type)
+{
+	uint32_t result = 0;
+
+	switch (fw_type) {
+	case UCODE_ID_SDMA0:
+		result = UCODE_ID_SDMA0_MASK;
+		break;
+	case UCODE_ID_SDMA1:
+		result = UCODE_ID_SDMA1_MASK;
+		break;
+	case UCODE_ID_CP_CE:
+		result = UCODE_ID_CP_CE_MASK;
+		break;
+	case UCODE_ID_CP_PFP:
+		result = UCODE_ID_CP_PFP_MASK;
+		break;
+	case UCODE_ID_CP_ME:
+		result = UCODE_ID_CP_ME_MASK;
+		break;
+	case UCODE_ID_CP_MEC_JT1:
+		result = UCODE_ID_CP_MEC_MASK | UCODE_ID_CP_MEC_JT1_MASK;
+		break;
+	case UCODE_ID_CP_MEC_JT2:
+		result = UCODE_ID_CP_MEC_MASK | UCODE_ID_CP_MEC_JT2_MASK;
+		break;
+	case UCODE_ID_RLC_G:
+		result = UCODE_ID_RLC_G_MASK;
+		break;
+	default:
+		printk(KERN_ERR "UCode type is out of range!");
+		result = 0;
+	}
+
+	return result;
+}
+
+/* Populate one firmware image to the data structure */
+static int fiji_populate_single_firmware_entry(struct pp_smumgr *smumgr,
+		uint32_t fw_type, struct SMU_Entry *entry)
+{
+	int result;
+	struct cgs_firmware_info info = {0};
+
+	result = cgs_get_firmware_info(
+			smumgr->device,
+			fiji_convert_fw_type_to_cgs(fw_type),
+			&info);
+
+	if (!result) {
+		entry->version = 0;
+		entry->id = (uint16_t)fw_type;
+		entry->image_addr_high = smu_upper_32_bits(info.mc_addr);
+		entry->image_addr_low = smu_lower_32_bits(info.mc_addr);
+		entry->meta_data_addr_high = 0;
+		entry->meta_data_addr_low = 0;
+		entry->data_size_byte = info.image_size;
+		entry->num_register_entries = 0;
+
+		if (fw_type == UCODE_ID_RLC_G)
+			entry->flags = 1;
+		else
+			entry->flags = 0;
+	}
+
+	return result;
+}
+
+static int fiji_request_smu_load_fw(struct pp_smumgr *smumgr)
+{
+	struct fiji_smumgr *priv = (struct fiji_smumgr *)(smumgr->backend);
+	uint32_t fw_to_load;
+	struct SMU_DRAMData_TOC *toc;
+
+	if (priv->soft_regs_start)
+		cgs_write_ind_register(smumgr->device, CGS_IND_REG__SMC,
+				priv->soft_regs_start +
+				offsetof(SMU73_SoftRegisters, UcodeLoadStatus),
+				0x0);
+
+	toc = (struct SMU_DRAMData_TOC *)priv->header;
+	toc->num_entries = 0;
+	toc->structure_version = 1;
+
+	PP_ASSERT_WITH_CODE(
+			0 == fiji_populate_single_firmware_entry(smumgr,
+					UCODE_ID_RLC_G, &toc->entry[toc->num_entries++]),
+			"Failed to Get Firmware Entry.\n" , return -1 );
+	PP_ASSERT_WITH_CODE(
+			0 == fiji_populate_single_firmware_entry(smumgr,
+					UCODE_ID_CP_CE, &toc->entry[toc->num_entries++]),
+			"Failed to Get Firmware Entry.\n" , return -1 );
+	PP_ASSERT_WITH_CODE(
+			0 == fiji_populate_single_firmware_entry(smumgr,
+					UCODE_ID_CP_PFP, &toc->entry[toc->num_entries++]),
+			"Failed to Get Firmware Entry.\n" , return -1 );
+	PP_ASSERT_WITH_CODE(
+			0 == fiji_populate_single_firmware_entry(smumgr,
+					UCODE_ID_CP_ME, &toc->entry[toc->num_entries++]),
+			"Failed to Get Firmware Entry.\n" , return -1 );
+	PP_ASSERT_WITH_CODE(
+			0 == fiji_populate_single_firmware_entry(smumgr,
+					UCODE_ID_CP_MEC, &toc->entry[toc->num_entries++]),
+			"Failed to Get Firmware Entry.\n" , return -1 );
+	PP_ASSERT_WITH_CODE(
+			0 == fiji_populate_single_firmware_entry(smumgr,
+					UCODE_ID_CP_MEC_JT1, &toc->entry[toc->num_entries++]),
+					"Failed to Get Firmware Entry.\n" , return -1 );
+	PP_ASSERT_WITH_CODE(
+			0 == fiji_populate_single_firmware_entry(smumgr,
+					UCODE_ID_CP_MEC_JT2, &toc->entry[toc->num_entries++]),
+					"Failed to Get Firmware Entry.\n" , return -1 );
+	PP_ASSERT_WITH_CODE(
+			0 == fiji_populate_single_firmware_entry(smumgr,
+					UCODE_ID_SDMA0, &toc->entry[toc->num_entries++]),
+					"Failed to Get Firmware Entry.\n" , return -1 );
+	PP_ASSERT_WITH_CODE(
+			0 == fiji_populate_single_firmware_entry(smumgr,
+					UCODE_ID_SDMA1, &toc->entry[toc->num_entries++]),
+					"Failed to Get Firmware Entry.\n" , return -1 );
+
+	fiji_send_msg_to_smc_with_parameter(smumgr, PPSMC_MSG_DRV_DRAM_ADDR_HI,
+			priv->header_buffer.mc_addr_high);
+	fiji_send_msg_to_smc_with_parameter(smumgr,PPSMC_MSG_DRV_DRAM_ADDR_LO,
+			priv->header_buffer.mc_addr_low);
+
+	fw_to_load = UCODE_ID_RLC_G_MASK
+			+ UCODE_ID_SDMA0_MASK
+			+ UCODE_ID_SDMA1_MASK
+			+ UCODE_ID_CP_CE_MASK
+			+ UCODE_ID_CP_ME_MASK
+			+ UCODE_ID_CP_PFP_MASK
+			+ UCODE_ID_CP_MEC_MASK
+			+ UCODE_ID_CP_MEC_JT1_MASK
+			+ UCODE_ID_CP_MEC_JT2_MASK;
+
+	if (fiji_send_msg_to_smc_with_parameter(smumgr,
+			PPSMC_MSG_LoadUcodes, fw_to_load))
+		printk(KERN_ERR "Fail to Request SMU Load uCode");
+
+	return 0;
+}
+
+
+/* Check if the FW has been loaded, SMU will not return
+ * if loading has not finished.
+ */
+static int fiji_check_fw_load_finish(struct pp_smumgr *smumgr,
+		uint32_t fw_type)
+{
+	struct fiji_smumgr *priv = (struct fiji_smumgr *)(smumgr->backend);
+	uint32_t mask = fiji_get_mask_for_firmware_type(fw_type);
+
+	/* Check SOFT_REGISTERS_TABLE_28.UcodeLoadStatus */
+	if (smum_wait_on_indirect_register(smumgr, mmSMC_IND_INDEX,
+			priv->soft_regs_start +
+			offsetof(SMU73_SoftRegisters, UcodeLoadStatus),
+			mask, mask)) {
+		printk(KERN_ERR "check firmware loading failed\n");
+		return -EINVAL;
+	}
+	return 0;
+}
+
+
+static int fiji_reload_firmware(struct pp_smumgr *smumgr)
+{
+	return smumgr->smumgr_funcs->start_smu(smumgr);
+}
+
+static bool fiji_is_hw_virtualization_enabled(struct pp_smumgr *smumgr)
+{
+	uint32_t value;
+
+	value = cgs_read_register(smumgr->device, mmBIF_IOV_FUNC_IDENTIFIER);
+	if (value & BIF_IOV_FUNC_IDENTIFIER__IOV_ENABLE_MASK) {
+		/* driver reads on SR-IOV enabled PF: 0x80000000
+		 * driver reads on SR-IOV enabled VF: 0x80000001
+		 * driver reads on SR-IOV disabled:   0x00000000
+		 */
+		return true;
+	}
+	return false;
+}
+
+static int fiji_request_smu_specific_fw_load(struct pp_smumgr *smumgr, uint32_t fw_type)
+{
+	if (fiji_is_hw_virtualization_enabled(smumgr)) {
+		uint32_t masks = fiji_get_mask_for_firmware_type(fw_type);
+		if (fiji_send_msg_to_smc_with_parameter_without_waiting(smumgr,
+				PPSMC_MSG_LoadUcodes, masks))
+			printk(KERN_ERR "Fail to Request SMU Load uCode");
+	}
+	/* For non-virtualization cases,
+	 * SMU loads all FWs at once in fiji_request_smu_load_fw.
+	 */
+	return 0;
+}
+
+static int fiji_start_smu_in_protection_mode(struct pp_smumgr *smumgr)
+{
+	int result = 0;
+
+	/* Wait for smc boot up */
+	/* SMUM_WAIT_INDIRECT_FIELD_UNEQUAL(smumgr, SMC_IND,
+		RCU_UC_EVENTS, boot_seq_done, 0); */
+
+	SMUM_WRITE_VFPF_INDIRECT_FIELD(smumgr->device, CGS_IND_REG__SMC,
+			SMC_SYSCON_RESET_CNTL, rst_reg, 1);
+
+	result = fiji_upload_smu_firmware_image(smumgr);
+	if (result)
+		return result;
+
+	/* Clear status */
+	cgs_write_ind_register(smumgr->device, CGS_IND_REG__SMC,
+			ixSMU_STATUS, 0);
+
+	SMUM_WRITE_VFPF_INDIRECT_FIELD(smumgr->device, CGS_IND_REG__SMC,
+			SMC_SYSCON_CLOCK_CNTL_0, ck_disable, 0);
+
+	/* De-assert reset */
+	SMUM_WRITE_VFPF_INDIRECT_FIELD(smumgr->device, CGS_IND_REG__SMC,
+			SMC_SYSCON_RESET_CNTL, rst_reg, 0);
+
+	/* Wait for ROM firmware to initialize interrupt hendler */
+	/*SMUM_WAIT_VFPF_INDIRECT_REGISTER(smumgr, SMC_IND,
+			SMC_INTR_CNTL_MASK_0, 0x10040, 0xFFFFFFFF); */
+
+	/* Set SMU Auto Start */
+	SMUM_WRITE_VFPF_INDIRECT_FIELD(smumgr->device, CGS_IND_REG__SMC,
+			SMU_INPUT_DATA, AUTO_START, 1);
+
+	/* Clear firmware interrupt enable flag */
+	cgs_write_ind_register(smumgr->device, CGS_IND_REG__SMC,
+			ixFIRMWARE_FLAGS, 0);
+
+	SMUM_WAIT_VFPF_INDIRECT_FIELD(smumgr, SMC_IND, RCU_UC_EVENTS,
+			INTERRUPTS_ENABLED, 1);
+
+	cgs_write_register(smumgr->device, mmSMC_MSG_ARG_0, 0x20000);
+	cgs_write_register(smumgr->device, mmSMC_MESSAGE_0, PPSMC_MSG_Test);
+	SMUM_WAIT_FIELD_UNEQUAL(smumgr, SMC_RESP_0, SMC_RESP, 0);
+
+	/* Wait for done bit to be set */
+	SMUM_WAIT_VFPF_INDIRECT_FIELD_UNEQUAL(smumgr, SMC_IND,
+			SMU_STATUS, SMU_DONE, 0);
+
+	/* Check pass/failed indicator */
+	if (1 != SMUM_READ_VFPF_INDIRECT_FIELD(smumgr->device, CGS_IND_REG__SMC,
+			SMU_STATUS, SMU_PASS)) {
+		PP_ASSERT_WITH_CODE(false,
+				"SMU Firmware start failed!", return -1);
+	}
+
+	/* Wait for firmware to initialize */
+	SMUM_WAIT_VFPF_INDIRECT_FIELD(smumgr, SMC_IND,
+			FIRMWARE_FLAGS, INTERRUPTS_ENABLED, 1);
+
+	return result;
+}
+
+static int fiji_start_smu_in_non_protection_mode(struct pp_smumgr *smumgr)
+{
+	int result = 0;
+
+	/* wait for smc boot up */
+	SMUM_WAIT_VFPF_INDIRECT_FIELD_UNEQUAL(smumgr, SMC_IND,
+			RCU_UC_EVENTS, boot_seq_done, 0);
+
+	/* Clear firmware interrupt enable flag */
+	cgs_write_ind_register(smumgr->device, CGS_IND_REG__SMC,
+			ixFIRMWARE_FLAGS, 0);
+
+	/* Assert reset */
+	SMUM_WRITE_VFPF_INDIRECT_FIELD(smumgr->device, CGS_IND_REG__SMC,
+			SMC_SYSCON_RESET_CNTL, rst_reg, 1);
+
+	result = fiji_upload_smu_firmware_image(smumgr);
+	if (result)
+		return result;
+
+	/* Set smc instruct start point at 0x0 */
+	fiji_program_jump_on_start(smumgr);
+
+	/* Enable clock */
+	SMUM_WRITE_VFPF_INDIRECT_FIELD(smumgr->device, CGS_IND_REG__SMC,
+			SMC_SYSCON_CLOCK_CNTL_0, ck_disable, 0);
+
+	/* De-assert reset */
+	SMUM_WRITE_VFPF_INDIRECT_FIELD(smumgr->device, CGS_IND_REG__SMC,
+			SMC_SYSCON_RESET_CNTL, rst_reg, 0);
+
+	/* Wait for firmware to initialize */
+	SMUM_WAIT_VFPF_INDIRECT_FIELD(smumgr, SMC_IND,
+			FIRMWARE_FLAGS, INTERRUPTS_ENABLED, 1);
+
+	return result;
+}
+
+int fiji_setup_pwr_virus(struct pp_smumgr *smumgr)
+{
+	int i, result = -1;
+	uint32_t reg, data;
+	PWR_Command_Table *virus = PwrVirusTable;
+	struct fiji_smumgr *priv = (struct fiji_smumgr *)(smumgr->backend);
+
+	priv->avfs.AvfsBtcStatus = AVFS_LOAD_VIRUS;
+	for (i = 0; (i < PWR_VIRUS_TABLE_SIZE); i++) {
+		switch (virus->command) {
+		case PwrCmdWrite:
+			reg  = virus->reg;
+			data = virus->data;
+			cgs_write_register(smumgr->device, reg, data);
+			break;
+		case PwrCmdEnd:
+			priv->avfs.AvfsBtcStatus = AVFS_BTC_VIRUS_LOADED;
+			result = 0;
+			break;
+		default:
+			printk(KERN_ERR "Table Exit with Invalid Command!");
+			priv->avfs.AvfsBtcStatus = AVFS_BTC_VIRUS_FAIL;
+			result = -1;
+			break;
+		}
+		virus++;
+	}
+	return result;
+}
+
+static int fiji_start_avfs_btc(struct pp_smumgr *smumgr)
+{
+	int result = 0;
+	struct fiji_smumgr *priv = (struct fiji_smumgr *)(smumgr->backend);
+
+	priv->avfs.AvfsBtcStatus = AVFS_BTC_STARTED;
+	if (priv->avfs.AvfsBtcParam) {
+		if (!fiji_send_msg_to_smc_with_parameter(smumgr,
+				PPSMC_MSG_PerformBtc, priv->avfs.AvfsBtcParam)) {
+			if (!fiji_send_msg_to_smc(smumgr, PPSMC_MSG_EnableAvfs)) {
+				priv->avfs.AvfsBtcStatus = AVFS_BTC_COMPLETED_UNSAVED;
+				result = 0;
+			} else {
+				printk(KERN_ERR "[AVFS][fiji_start_avfs_btc] Attempt"
+						" to Enable AVFS Failed!");
+				fiji_send_msg_to_smc(smumgr, PPSMC_MSG_DisableAvfs);
+				result = -1;
+			}
+		} else {
+			printk(KERN_ERR "[AVFS][fiji_start_avfs_btc] "
+					"PerformBTC SMU msg failed");
+			result = -1;
+		}
+	}
+	/* Soft-Reset to reset the engine before loading uCode */
+	 /* halt */
+	cgs_write_register(smumgr->device, mmCP_MEC_CNTL, 0x50000000);
+	/* reset everything */
+	cgs_write_register(smumgr->device, mmGRBM_SOFT_RESET, 0xffffffff);
+	/* clear reset */
+	cgs_write_register(smumgr->device, mmGRBM_SOFT_RESET, 0);
+
+	return result;
+}
+
+int fiji_setup_pm_fuse_for_avfs(struct pp_smumgr *smumgr)
+{
+	int result = 0;
+	uint32_t table_start;
+	uint32_t charz_freq_addr, inversion_voltage_addr, charz_freq;
+	uint16_t inversion_voltage;
+
+	charz_freq = 0x30750000; /* In 10KHz units 0x00007530 Actual value */
+	inversion_voltage = 0x1A04; /* mV Q14.2 0x41A Actual value */
+
+	PP_ASSERT_WITH_CODE(0 == fiji_read_smc_sram_dword(smumgr,
+			SMU7_FIRMWARE_HEADER_LOCATION + offsetof(SMU73_Firmware_Header,
+					PmFuseTable), &table_start, 0x40000),
+			"[AVFS][Fiji_SetupGfxLvlStruct] SMU could not communicate "
+			"starting address of PmFuse structure",
+			return -1;);
+
+	charz_freq_addr = table_start +
+			offsetof(struct SMU73_Discrete_PmFuses, PsmCharzFreq);
+	inversion_voltage_addr = table_start +
+			offsetof(struct SMU73_Discrete_PmFuses, InversionVoltage);
+
+	result = fiji_copy_bytes_to_smc(smumgr, charz_freq_addr,
+			(uint8_t *)(&charz_freq), sizeof(charz_freq), 0x40000);
+	PP_ASSERT_WITH_CODE(0 == result,
+			"[AVFS][fiji_setup_pm_fuse_for_avfs] charz_freq could not "
+			"be populated.", return -1;);
+
+	result = fiji_copy_bytes_to_smc(smumgr, inversion_voltage_addr,
+			(uint8_t *)(&inversion_voltage), sizeof(inversion_voltage), 0x40000);
+	PP_ASSERT_WITH_CODE(0 == result, "[AVFS][fiji_setup_pm_fuse_for_avfs] "
+			"charz_freq could not be populated.", return -1;);
+
+	return result;
+}
+
+int fiji_setup_graphics_level_structure(struct pp_smumgr *smumgr)
+{
+	int32_t vr_config;
+	uint32_t table_start;
+	uint32_t level_addr, vr_config_addr;
+	uint32_t level_size = sizeof(avfs_graphics_level);
+
+	PP_ASSERT_WITH_CODE(0 == fiji_read_smc_sram_dword(smumgr,
+			SMU7_FIRMWARE_HEADER_LOCATION +
+			offsetof(SMU73_Firmware_Header, DpmTable),
+			&table_start, 0x40000),
+			"[AVFS][Fiji_SetupGfxLvlStruct] SMU could not "
+			"communicate starting address of DPM table",
+			return -1;);
+
+	/* Default value for vr_config =
+	 * VR_MERGED_WITH_VDDC + VR_STATIC_VOLTAGE(VDDCI) */
+	vr_config = 0x01000500;   /* Real value:0x50001 */
+
+	vr_config_addr = table_start +
+			offsetof(SMU73_Discrete_DpmTable, VRConfig);
+
+	PP_ASSERT_WITH_CODE(0 == fiji_copy_bytes_to_smc(smumgr, vr_config_addr,
+			(uint8_t *)&vr_config, sizeof(int32_t), 0x40000),
+			"[AVFS][Fiji_SetupGfxLvlStruct] Problems copying "
+			"vr_config value over to SMC",
+			return -1;);
+
+	level_addr = table_start + offsetof(SMU73_Discrete_DpmTable, GraphicsLevel);
+
+	PP_ASSERT_WITH_CODE(0 == fiji_copy_bytes_to_smc(smumgr, level_addr,
+			(uint8_t *)(&avfs_graphics_level), level_size, 0x40000),
+			"[AVFS][Fiji_SetupGfxLvlStruct] Copying of DPM table failed!",
+			return -1;);
+
+	return 0;
+}
+
+/* Work in Progress */
+int fiji_restore_vft_table(struct pp_smumgr *smumgr)
+{
+	struct fiji_smumgr *priv = (struct fiji_smumgr *)(smumgr->backend);
+
+	if (AVFS_BTC_COMPLETED_SAVED == priv->avfs.AvfsBtcStatus) {
+		priv->avfs.AvfsBtcStatus = AVFS_BTC_COMPLETED_RESTORED;
+		return 0;
+	} else
+		return -EINVAL;
+}
+
+/* Work in Progress */
+int fiji_save_vft_table(struct pp_smumgr *smumgr)
+{
+	struct fiji_smumgr *priv = (struct fiji_smumgr *)(smumgr->backend);
+
+	if (AVFS_BTC_COMPLETED_SAVED == priv->avfs.AvfsBtcStatus) {
+		priv->avfs.AvfsBtcStatus = AVFS_BTC_COMPLETED_RESTORED;
+		return 0;
+	} else
+		return -EINVAL;
+}
+
+int fiji_avfs_event_mgr(struct pp_smumgr *smumgr, bool smu_started)
+{
+	struct fiji_smumgr *priv = (struct fiji_smumgr *)(smumgr->backend);
+
+	switch (priv->avfs.AvfsBtcStatus) {
+	case AVFS_BTC_COMPLETED_SAVED: /*S3 State - Pre SMU Start */
+		priv->avfs.AvfsBtcStatus = AVFS_BTC_RESTOREVFT_FAILED;
+		PP_ASSERT_WITH_CODE(0 == fiji_restore_vft_table(smumgr),
+				"[AVFS][fiji_avfs_event_mgr] Could not Copy Graphics "
+				"Level table over to SMU",
+				return -1;);
+		priv->avfs.AvfsBtcStatus = AVFS_BTC_COMPLETED_RESTORED;
+		break;
+	case AVFS_BTC_COMPLETED_RESTORED: /*S3 State - Post SMU Start*/
+		priv->avfs.AvfsBtcStatus = AVFS_BTC_SMUMSG_ERROR;
+		PP_ASSERT_WITH_CODE(0 == fiji_send_msg_to_smc(smumgr,
+				PPSMC_MSG_VftTableIsValid),
+				"[AVFS][fiji_avfs_event_mgr] SMU did not respond "
+				"correctly to VftTableIsValid Msg",
+				return -1;);
+		priv->avfs.AvfsBtcStatus = AVFS_BTC_SMUMSG_ERROR;
+		PP_ASSERT_WITH_CODE(0 == fiji_send_msg_to_smc(smumgr,
+				PPSMC_MSG_EnableAvfs),
+				"[AVFS][fiji_avfs_event_mgr] SMU did not respond "
+				"correctly to EnableAvfs Message Msg",
+				return -1;);
+		priv->avfs.AvfsBtcStatus = AVFS_BTC_COMPLETED_SAVED;
+		break;
+	case AVFS_BTC_BOOT: /*Cold Boot State - Post SMU Start*/
+		if (!smu_started)
+			break;
+		priv->avfs.AvfsBtcStatus = AVFS_BTC_FAILED;
+		PP_ASSERT_WITH_CODE(0 == fiji_setup_pm_fuse_for_avfs(smumgr),
+				"[AVFS][fiji_avfs_event_mgr] Failure at "
+				"fiji_setup_pm_fuse_for_avfs",
+				return -1;);
+		priv->avfs.AvfsBtcStatus = AVFS_BTC_DPMTABLESETUP_FAILED;
+		PP_ASSERT_WITH_CODE(0 == fiji_setup_graphics_level_structure(smumgr),
+				"[AVFS][fiji_avfs_event_mgr] Could not Copy Graphics Level"
+				" table over to SMU",
+				return -1;);
+		priv->avfs.AvfsBtcStatus = AVFS_BTC_VIRUS_FAIL;
+		PP_ASSERT_WITH_CODE(0 == fiji_setup_pwr_virus(smumgr),
+				"[AVFS][fiji_avfs_event_mgr] Could not setup "
+				"Pwr Virus for AVFS ",
+				return -1;);
+		priv->avfs.AvfsBtcStatus = AVFS_BTC_FAILED;
+		PP_ASSERT_WITH_CODE(0 == fiji_start_avfs_btc(smumgr),
+				"[AVFS][fiji_avfs_event_mgr] Failure at "
+				"fiji_start_avfs_btc. AVFS Disabled",
+				return -1;);
+		priv->avfs.AvfsBtcStatus = AVFS_BTC_SAVEVFT_FAILED;
+		PP_ASSERT_WITH_CODE(0 == fiji_save_vft_table(smumgr),
+				"[AVFS][fiji_avfs_event_mgr] Could not save VFT Table",
+				return -1;);
+		priv->avfs.AvfsBtcStatus = AVFS_BTC_COMPLETED_SAVED;
+		break;
+	case AVFS_BTC_DISABLED: /* Do nothing */
+		break;
+	case AVFS_BTC_NOTSUPPORTED: /* Do nothing */
+		break;
+	default:
+		printk(KERN_ERR "[AVFS] Something is broken. See log!");
+		break;
+	}
+	return 0;
+}
+
+static int fiji_start_smu(struct pp_smumgr *smumgr)
+{
+	int result = 0;
+	struct fiji_smumgr *priv = (struct fiji_smumgr *)(smumgr->backend);
+
+	/* Only start SMC if SMC RAM is not running */
+	if (!fiji_is_smc_ram_running(smumgr)) {
+		fiji_avfs_event_mgr(smumgr, false);
+
+		/* Check if SMU is running in protected mode */
+		if (0 == SMUM_READ_VFPF_INDIRECT_FIELD(smumgr->device,
+				CGS_IND_REG__SMC,
+				SMU_FIRMWARE, SMU_MODE)) {
+			result = fiji_start_smu_in_non_protection_mode(smumgr);
+			if (result)
+				return result;
+		} else {
+			result = fiji_start_smu_in_protection_mode(smumgr);
+			if (result)
+				return result;
+		}
+		fiji_avfs_event_mgr(smumgr, true);
+	}
+
+	/* To initialize all clock gating before RLC loaded and running.*/
+	cgs_set_clockgating_state(smumgr->device,
+			AMD_IP_BLOCK_TYPE_GFX, AMD_CG_STATE_GATE);
+	cgs_set_clockgating_state(smumgr->device,
+			AMD_IP_BLOCK_TYPE_GMC, AMD_CG_STATE_GATE);
+	cgs_set_clockgating_state(smumgr->device,
+			AMD_IP_BLOCK_TYPE_SDMA, AMD_CG_STATE_GATE);
+	cgs_set_clockgating_state(smumgr->device,
+			AMD_IP_BLOCK_TYPE_COMMON, AMD_CG_STATE_GATE);
+
+	/* Setup SoftRegsStart here for register lookup in case
+	 * DummyBackEnd is used and ProcessFirmwareHeader is not executed
+	 */
+	fiji_read_smc_sram_dword(smumgr,
+			SMU7_FIRMWARE_HEADER_LOCATION +
+			offsetof(SMU73_Firmware_Header, SoftRegisters),
+			&(priv->soft_regs_start), 0x40000);
+
+	result = fiji_request_smu_load_fw(smumgr);
+
+	return result;
+}
+
+static bool fiji_is_hw_avfs_present(struct pp_smumgr *smumgr)
+{
+
+	uint32_t efuse = 0;
+	uint32_t mask = (1 << ((AVFS_EN_MSB - AVFS_EN_LSB) + 1)) - 1;
+
+	if (!atomctrl_read_efuse(smumgr->device, AVFS_EN_LSB, AVFS_EN_MSB,
+			mask, &efuse)) {
+		if (efuse)
+			return true;
+	}
+	return false;
+}
+
+/**
+* Write a 32bit value to the SMC SRAM space.
+* ALL PARAMETERS ARE IN HOST BYTE ORDER.
+* @param    smumgr  the address of the powerplay hardware manager.
+* @param    smc_addr the address in the SMC RAM to access.
+* @param    value to write to the SMC SRAM.
+*/
+static int fiji_smu_init(struct pp_smumgr *smumgr)
+{
+	struct fiji_smumgr *priv = (struct fiji_smumgr *)(smumgr->backend);
+	uint64_t mc_addr;
+
+	priv->header_buffer.data_size =
+			((sizeof(struct SMU_DRAMData_TOC) / 4096) + 1) * 4096;
+	smu_allocate_memory(smumgr->device,
+			priv->header_buffer.data_size,
+			CGS_GPU_MEM_TYPE__VISIBLE_CONTIG_FB,
+			PAGE_SIZE,
+			&mc_addr,
+			&priv->header_buffer.kaddr,
+			&priv->header_buffer.handle);
+
+	priv->header = priv->header_buffer.kaddr;
+	priv->header_buffer.mc_addr_high = smu_upper_32_bits(mc_addr);
+	priv->header_buffer.mc_addr_low = smu_lower_32_bits(mc_addr);
+
+	PP_ASSERT_WITH_CODE((NULL != priv->header),
+			"Out of memory.",
+			kfree(smumgr->backend);
+			cgs_free_gpu_mem(smumgr->device,
+			(cgs_handle_t)priv->header_buffer.handle);
+			return -1);
+
+	priv->avfs.AvfsBtcStatus = AVFS_BTC_BOOT;
+	if (fiji_is_hw_avfs_present(smumgr))
+		/* AVFS Parameter
+		 * 0 - BTC DC disabled, BTC AC disabled
+		 * 1 - BTC DC enabled,  BTC AC disabled
+		 * 2 - BTC DC disabled, BTC AC enabled
+		 * 3 - BTC DC enabled,  BTC AC enabled
+		 * Default is 0 - BTC DC disabled, BTC AC disabled
+		 */
+		priv->avfs.AvfsBtcParam = 0;
+	else
+		priv->avfs.AvfsBtcStatus = AVFS_BTC_NOTSUPPORTED;
+
+	priv->acpi_optimization = 1;
+
+	return 0;
+}
+
+static int fiji_smu_fini(struct pp_smumgr *smumgr)
+{
+	if (smumgr->backend) {
+		kfree(smumgr->backend);
+		smumgr->backend = NULL;
+	}
+	return 0;
+}
+
+static const struct pp_smumgr_func fiji_smu_funcs = {
+	.smu_init = &fiji_smu_init,
+	.smu_fini = &fiji_smu_fini,
+	.start_smu = &fiji_start_smu,
+	.check_fw_load_finish = &fiji_check_fw_load_finish,
+	.request_smu_load_fw = &fiji_reload_firmware,
+	.request_smu_load_specific_fw = &fiji_request_smu_specific_fw_load,
+	.send_msg_to_smc = &fiji_send_msg_to_smc,
+	.send_msg_to_smc_with_parameter = &fiji_send_msg_to_smc_with_parameter,
+	.download_pptable_settings = NULL,
+	.upload_pptable_settings = NULL,
+};
+
+int fiji_smum_init(struct pp_smumgr *smumgr)
+{
+	struct fiji_smumgr *fiji_smu = NULL;
+
+	fiji_smu = kzalloc(sizeof(struct fiji_smumgr), GFP_KERNEL);
+
+	if (fiji_smu == NULL)
+		return -ENOMEM;
+
+	smumgr->backend = fiji_smu;
+	smumgr->smumgr_funcs = &fiji_smu_funcs;
+
+	return 0;
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/powerplay/smumgr/fiji_smumgr.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2015 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+#ifndef _FIJI_SMUMANAGER_H_
+#define _FIJI_SMUMANAGER_H_
+
+enum AVFS_BTC_STATUS {
+	AVFS_BTC_BOOT = 0,
+	AVFS_BTC_BOOT_STARTEDSMU,
+	AVFS_LOAD_VIRUS,
+	AVFS_BTC_VIRUS_LOADED,
+	AVFS_BTC_VIRUS_FAIL,
+	AVFS_BTC_STARTED,
+	AVFS_BTC_FAILED,
+	AVFS_BTC_RESTOREVFT_FAILED,
+	AVFS_BTC_SAVEVFT_FAILED,
+	AVFS_BTC_DPMTABLESETUP_FAILED,
+	AVFS_BTC_COMPLETED_UNSAVED,
+	AVFS_BTC_COMPLETED_SAVED,
+	AVFS_BTC_COMPLETED_RESTORED,
+	AVFS_BTC_DISABLED,
+	AVFS_BTC_NOTSUPPORTED,
+	AVFS_BTC_SMUMSG_ERROR
+};
+
+struct fiji_smu_avfs {
+	enum AVFS_BTC_STATUS AvfsBtcStatus;
+	uint32_t           AvfsBtcParam;
+};
+
+struct fiji_buffer_entry {
+	uint32_t data_size;
+	uint32_t mc_addr_low;
+	uint32_t mc_addr_high;
+	void *kaddr;
+	unsigned long  handle;
+};
+
+struct fiji_smumgr {
+	uint8_t        *header;
+	uint8_t        *mec_image;
+	uint32_t        soft_regs_start;
+	struct fiji_smu_avfs avfs;
+	uint32_t        acpi_optimization;
+
+	struct fiji_buffer_entry header_buffer;
+};
+
+int fiji_smum_init(struct pp_smumgr *smumgr);
+int fiji_read_smc_sram_dword(struct pp_smumgr *smumgr, uint32_t smcAddress,
+		uint32_t *value, uint32_t limit);
+int fiji_write_smc_sram_dword(struct pp_smumgr *smumgr, uint32_t smc_addr,
+		uint32_t value, uint32_t limit);
+int fiji_copy_bytes_to_smc(struct pp_smumgr *smumgr, uint32_t smcStartAddress,
+		const uint8_t *src,	uint32_t byteCount, uint32_t limit);
+
+#endif
+
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/powerplay/smumgr/smumgr.c
@@ -0,0 +1,263 @@
+/*
+ * Copyright 2015 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include "pp_instance.h"
+#include "smumgr.h"
+#include "cgs_common.h"
+#include "linux/delay.h"
+#include "cz_smumgr.h"
+#include "tonga_smumgr.h"
+#include "fiji_smumgr.h"
+
+int smum_init(struct amd_pp_init *pp_init, struct pp_instance *handle)
+{
+	struct pp_smumgr *smumgr;
+
+	if ((handle == NULL) || (pp_init == NULL))
+		return -EINVAL;
+
+	smumgr = kzalloc(sizeof(struct pp_smumgr), GFP_KERNEL);
+	if (smumgr == NULL)
+		return -ENOMEM;
+
+	smumgr->device = pp_init->device;
+	smumgr->chip_family = pp_init->chip_family;
+	smumgr->chip_id = pp_init->chip_id;
+	smumgr->hw_revision = pp_init->rev_id;
+	smumgr->usec_timeout = AMD_MAX_USEC_TIMEOUT;
+	smumgr->reload_fw = 1;
+	handle->smu_mgr = smumgr;
+
+	switch (smumgr->chip_family) {
+	case AMD_FAMILY_CZ:
+		cz_smum_init(smumgr);
+		break;
+	case AMD_FAMILY_VI:
+		switch (smumgr->chip_id) {
+		case CHIP_TONGA:
+			tonga_smum_init(smumgr);
+			break;
+		case CHIP_FIJI:
+			fiji_smum_init(smumgr);
+			break;
+		default:
+			return -EINVAL;
+		}
+		break;
+	default:
+		kfree(smumgr);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+int smum_fini(struct pp_smumgr *smumgr)
+{
+	kfree(smumgr);
+	return 0;
+}
+
+int smum_get_argument(struct pp_smumgr *smumgr)
+{
+	if (NULL != smumgr->smumgr_funcs->get_argument)
+		return smumgr->smumgr_funcs->get_argument(smumgr);
+
+	return 0;
+}
+
+int smum_download_powerplay_table(struct pp_smumgr *smumgr,
+								void **table)
+{
+	if (NULL != smumgr->smumgr_funcs->download_pptable_settings)
+		return smumgr->smumgr_funcs->download_pptable_settings(smumgr,
+									table);
+
+	return 0;
+}
+
+int smum_upload_powerplay_table(struct pp_smumgr *smumgr)
+{
+	if (NULL != smumgr->smumgr_funcs->upload_pptable_settings)
+		return smumgr->smumgr_funcs->upload_pptable_settings(smumgr);
+
+	return 0;
+}
+
+int smum_send_msg_to_smc(struct pp_smumgr *smumgr, uint16_t msg)
+{
+	if (smumgr == NULL || smumgr->smumgr_funcs->send_msg_to_smc == NULL)
+		return -EINVAL;
+
+	return smumgr->smumgr_funcs->send_msg_to_smc(smumgr, msg);
+}
+
+int smum_send_msg_to_smc_with_parameter(struct pp_smumgr *smumgr,
+					uint16_t msg, uint32_t parameter)
+{
+	if (smumgr == NULL ||
+		smumgr->smumgr_funcs->send_msg_to_smc_with_parameter == NULL)
+		return -EINVAL;
+	return smumgr->smumgr_funcs->send_msg_to_smc_with_parameter(
+						smumgr, msg, parameter);
+}
+
+/*
+ * Returns once the part of the register indicated by the mask has
+ * reached the given value.
+ */
+int smum_wait_on_register(struct pp_smumgr *smumgr,
+				uint32_t index,
+				uint32_t value, uint32_t mask)
+{
+	uint32_t i;
+	uint32_t cur_value;
+
+	if (smumgr == NULL || smumgr->device == NULL)
+		return -EINVAL;
+
+	for (i = 0; i < smumgr->usec_timeout; i++) {
+		cur_value = cgs_read_register(smumgr->device, index);
+		if ((cur_value & mask) == (value & mask))
+			break;
+		udelay(1);
+	}
+
+	/* timeout means wrong logic*/
+	if (i == smumgr->usec_timeout)
+		return -1;
+
+	return 0;
+}
+
+int smum_wait_for_register_unequal(struct pp_smumgr *smumgr,
+					uint32_t index,
+					uint32_t value, uint32_t mask)
+{
+	uint32_t i;
+	uint32_t cur_value;
+
+	if (smumgr == NULL)
+		return -EINVAL;
+
+	for (i = 0; i < smumgr->usec_timeout; i++) {
+		cur_value = cgs_read_register(smumgr->device,
+									index);
+		if ((cur_value & mask) != (value & mask))
+			break;
+		udelay(1);
+	}
+
+	/* timeout means wrong logic */
+	if (i == smumgr->usec_timeout)
+		return -1;
+
+	return 0;
+}
+
+
+/*
+ * Returns once the part of the register indicated by the mask
+ * has reached the given value.The indirect space is described by
+ * giving the memory-mapped index of the indirect index register.
+ */
+int smum_wait_on_indirect_register(struct pp_smumgr *smumgr,
+					uint32_t indirect_port,
+					uint32_t index,
+					uint32_t value,
+					uint32_t mask)
+{
+	if (smumgr == NULL || smumgr->device == NULL)
+		return -EINVAL;
+
+	cgs_write_register(smumgr->device, indirect_port, index);
+	return smum_wait_on_register(smumgr, indirect_port + 1,
+						mask, value);
+}
+
+void smum_wait_for_indirect_register_unequal(
+						struct pp_smumgr *smumgr,
+						uint32_t indirect_port,
+						uint32_t index,
+						uint32_t value,
+						uint32_t mask)
+{
+	if (smumgr == NULL || smumgr->device == NULL)
+		return;
+	cgs_write_register(smumgr->device, indirect_port, index);
+	smum_wait_for_register_unequal(smumgr, indirect_port + 1,
+						value, mask);
+}
+
+int smu_allocate_memory(void *device, uint32_t size,
+			 enum cgs_gpu_mem_type type,
+			 uint32_t byte_align, uint64_t *mc_addr,
+			 void **kptr, void *handle)
+{
+	int ret = 0;
+	cgs_handle_t cgs_handle;
+
+	if (device == NULL || handle == NULL ||
+	    mc_addr == NULL || kptr == NULL)
+		return -EINVAL;
+
+	ret = cgs_alloc_gpu_mem(device, type, size, byte_align,
+				0, 0, (cgs_handle_t *)handle);
+	if (ret)
+		return -ENOMEM;
+
+	cgs_handle = *(cgs_handle_t *)handle;
+
+	ret = cgs_gmap_gpu_mem(device, cgs_handle, mc_addr);
+	if (ret)
+		goto error_gmap;
+
+	ret = cgs_kmap_gpu_mem(device, cgs_handle, kptr);
+	if (ret)
+		goto error_kmap;
+
+	return 0;
+
+error_kmap:
+	cgs_gunmap_gpu_mem(device, cgs_handle);
+
+error_gmap:
+	cgs_free_gpu_mem(device, cgs_handle);
+	return ret;
+}
+
+int smu_free_memory(void *device, void *handle)
+{
+	cgs_handle_t cgs_handle = (cgs_handle_t)handle;
+
+	if (device == NULL || handle == NULL)
+		return -EINVAL;
+
+	cgs_kunmap_gpu_mem(device, cgs_handle);
+	cgs_gunmap_gpu_mem(device, cgs_handle);
+	cgs_free_gpu_mem(device, cgs_handle);
+
+	return 0;
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/powerplay/smumgr/tonga_smumgr.c
@@ -0,0 +1,819 @@
+/*
+ * Copyright 2015 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/gfp.h>
+
+#include "smumgr.h"
+#include "tonga_smumgr.h"
+#include "pp_debug.h"
+#include "smu_ucode_xfer_vi.h"
+#include "tonga_ppsmc.h"
+#include "smu/smu_7_1_2_d.h"
+#include "smu/smu_7_1_2_sh_mask.h"
+#include "cgs_common.h"
+
+#define TONGA_SMC_SIZE			0x20000
+#define BUFFER_SIZE			80000
+#define MAX_STRING_SIZE			15
+#define BUFFER_SIZETWO              131072 /*128 *1024*/
+
+/**
+* Set the address for reading/writing the SMC SRAM space.
+* @param    smumgr  the address of the powerplay hardware manager.
+* @param    smcAddress the address in the SMC RAM to access.
+*/
+static int tonga_set_smc_sram_address(struct pp_smumgr *smumgr,
+				uint32_t smcAddress, uint32_t limit)
+{
+	if (smumgr == NULL || smumgr->device == NULL)
+		return -EINVAL;
+	PP_ASSERT_WITH_CODE((0 == (3 & smcAddress)),
+		"SMC address must be 4 byte aligned.",
+		return -1;);
+
+	PP_ASSERT_WITH_CODE((limit > (smcAddress + 3)),
+		"SMC address is beyond the SMC RAM area.",
+		return -1;);
+
+	cgs_write_register(smumgr->device, mmSMC_IND_INDEX_0, smcAddress);
+	SMUM_WRITE_FIELD(smumgr->device, SMC_IND_ACCESS_CNTL, AUTO_INCREMENT_IND_11, 0);
+
+	return 0;
+}
+
+/**
+* Copy bytes from an array into the SMC RAM space.
+*
+* @param    smumgr  the address of the powerplay SMU manager.
+* @param    smcStartAddress the start address in the SMC RAM to copy bytes to.
+* @param    src the byte array to copy the bytes from.
+* @param    byteCount the number of bytes to copy.
+*/
+int tonga_copy_bytes_to_smc(struct pp_smumgr *smumgr,
+		uint32_t smcStartAddress, const uint8_t *src,
+		uint32_t byteCount, uint32_t limit)
+{
+	uint32_t addr;
+	uint32_t data, orig_data;
+	int result = 0;
+	uint32_t extra_shift;
+
+	if (smumgr == NULL || smumgr->device == NULL)
+		return -EINVAL;
+	PP_ASSERT_WITH_CODE((0 == (3 & smcStartAddress)),
+		"SMC address must be 4 byte aligned.",
+		return 0;);
+
+	PP_ASSERT_WITH_CODE((limit > (smcStartAddress + byteCount)),
+		"SMC address is beyond the SMC RAM area.",
+		return 0;);
+
+	addr = smcStartAddress;
+
+	while (byteCount >= 4) {
+		/*
+		 * Bytes are written into the
+		 * SMC address space with the MSB first
+		 */
+		data = (src[0] << 24) + (src[1] << 16) + (src[2] << 8) + src[3];
+
+		result = tonga_set_smc_sram_address(smumgr, addr, limit);
+
+		if (result)
+			goto out;
+
+		cgs_write_register(smumgr->device, mmSMC_IND_DATA_0, data);
+
+		src += 4;
+		byteCount -= 4;
+		addr += 4;
+	}
+
+	if (0 != byteCount) {
+		/* Now write odd bytes left, do a read modify write cycle */
+		data = 0;
+
+		result = tonga_set_smc_sram_address(smumgr, addr, limit);
+		if (result)
+			goto out;
+
+		orig_data = cgs_read_register(smumgr->device,
+							mmSMC_IND_DATA_0);
+		extra_shift = 8 * (4 - byteCount);
+
+		while (byteCount > 0) {
+			data = (data << 8) + *src++;
+			byteCount--;
+		}
+
+		data <<= extra_shift;
+		data |= (orig_data & ~((~0UL) << extra_shift));
+
+		result = tonga_set_smc_sram_address(smumgr, addr, limit);
+		if (result)
+			goto out;
+
+		cgs_write_register(smumgr->device, mmSMC_IND_DATA_0, data);
+	}
+
+out:
+	return result;
+}
+
+
+int tonga_program_jump_on_start(struct pp_smumgr *smumgr)
+{
+	static unsigned char pData[] = { 0xE0, 0x00, 0x80, 0x40 };
+
+	tonga_copy_bytes_to_smc(smumgr, 0x0, pData, 4, sizeof(pData)+1);
+
+	return 0;
+}
+
+/**
+* Return if the SMC is currently running.
+*
+* @param    smumgr  the address of the powerplay hardware manager.
+*/
+static int tonga_is_smc_ram_running(struct pp_smumgr *smumgr)
+{
+	return ((0 == SMUM_READ_VFPF_INDIRECT_FIELD(smumgr->device, CGS_IND_REG__SMC,
+					SMC_SYSCON_CLOCK_CNTL_0, ck_disable))
+			&& (0x20100 <= cgs_read_ind_register(smumgr->device,
+					CGS_IND_REG__SMC, ixSMC_PC_C)));
+}
+
+static int tonga_send_msg_to_smc_offset(struct pp_smumgr *smumgr)
+{
+	if (smumgr == NULL || smumgr->device == NULL)
+		return -EINVAL;
+
+	SMUM_WAIT_FIELD_UNEQUAL(smumgr, SMC_RESP_0, SMC_RESP, 0);
+
+	cgs_write_register(smumgr->device, mmSMC_MSG_ARG_0, 0x20000);
+	cgs_write_register(smumgr->device, mmSMC_MESSAGE_0, PPSMC_MSG_Test);
+
+	SMUM_WAIT_FIELD_UNEQUAL(smumgr, SMC_RESP_0, SMC_RESP, 0);
+
+	return 0;
+}
+
+/**
+* Send a message to the SMC, and wait for its response.
+*
+* @param    smumgr  the address of the powerplay hardware manager.
+* @param    msg the message to send.
+* @return   The response that came from the SMC.
+*/
+static int tonga_send_msg_to_smc(struct pp_smumgr *smumgr, uint16_t msg)
+{
+	if (smumgr == NULL || smumgr->device == NULL)
+		return -EINVAL;
+
+	if (!tonga_is_smc_ram_running(smumgr))
+		return -1;
+
+	SMUM_WAIT_FIELD_UNEQUAL(smumgr, SMC_RESP_0, SMC_RESP, 0);
+	PP_ASSERT_WITH_CODE(
+		1 == SMUM_READ_FIELD(smumgr->device, SMC_RESP_0, SMC_RESP),
+		"Failed to send Previous Message.",
+		);
+
+	cgs_write_register(smumgr->device, mmSMC_MESSAGE_0, msg);
+
+	SMUM_WAIT_FIELD_UNEQUAL(smumgr, SMC_RESP_0, SMC_RESP, 0);
+	PP_ASSERT_WITH_CODE(
+		1 == SMUM_READ_FIELD(smumgr->device, SMC_RESP_0, SMC_RESP),
+		"Failed to send Message.",
+		);
+
+	return 0;
+}
+
+/*
+* Send a message to the SMC, and do not wait for its response.
+*
+* @param    smumgr  the address of the powerplay hardware manager.
+* @param    msg the message to send.
+* @return   The response that came from the SMC.
+*/
+static int tonga_send_msg_to_smc_without_waiting
+				(struct pp_smumgr *smumgr, uint16_t msg)
+{
+	if (smumgr == NULL || smumgr->device == NULL)
+		return -EINVAL;
+
+	SMUM_WAIT_FIELD_UNEQUAL(smumgr, SMC_RESP_0, SMC_RESP, 0);
+	PP_ASSERT_WITH_CODE(
+		1 == SMUM_READ_FIELD(smumgr->device, SMC_RESP_0, SMC_RESP),
+		"Failed to send Previous Message.",
+		);
+	cgs_write_register(smumgr->device, mmSMC_MESSAGE_0, msg);
+
+	return 0;
+}
+
+/*
+* Send a message to the SMC with parameter
+*
+* @param    smumgr:  the address of the powerplay hardware manager.
+* @param    msg: the message to send.
+* @param    parameter: the parameter to send
+* @return   The response that came from the SMC.
+*/
+static int tonga_send_msg_to_smc_with_parameter(struct pp_smumgr *smumgr,
+				uint16_t msg, uint32_t parameter)
+{
+	if (smumgr == NULL || smumgr->device == NULL)
+		return -EINVAL;
+
+	if (!tonga_is_smc_ram_running(smumgr))
+		return PPSMC_Result_Failed;
+
+	SMUM_WAIT_FIELD_UNEQUAL(smumgr, SMC_RESP_0, SMC_RESP, 0);
+	cgs_write_register(smumgr->device, mmSMC_MSG_ARG_0, parameter);
+
+	return tonga_send_msg_to_smc(smumgr, msg);
+}
+
+/*
+* Send a message to the SMC with parameter, do not wait for response
+*
+* @param    smumgr:  the address of the powerplay hardware manager.
+* @param    msg: the message to send.
+* @param    parameter: the parameter to send
+* @return   The response that came from the SMC.
+*/
+static int tonga_send_msg_to_smc_with_parameter_without_waiting(
+			struct pp_smumgr *smumgr,
+			uint16_t msg, uint32_t parameter)
+{
+	if (smumgr == NULL || smumgr->device == NULL)
+		return -EINVAL;
+
+	SMUM_WAIT_FIELD_UNEQUAL(smumgr, SMC_RESP_0, SMC_RESP, 0);
+
+	cgs_write_register(smumgr->device, mmSMC_MSG_ARG_0, parameter);
+
+	return tonga_send_msg_to_smc_without_waiting(smumgr, msg);
+}
+
+/*
+ * Read a 32bit value from the SMC SRAM space.
+ * ALL PARAMETERS ARE IN HOST BYTE ORDER.
+ * @param    smumgr  the address of the powerplay hardware manager.
+ * @param    smcAddress the address in the SMC RAM to access.
+ * @param    value and output parameter for the data read from the SMC SRAM.
+ */
+int tonga_read_smc_sram_dword(struct pp_smumgr *smumgr,
+					uint32_t smcAddress, uint32_t *value,
+					uint32_t limit)
+{
+	int result;
+
+	result = tonga_set_smc_sram_address(smumgr, smcAddress, limit);
+
+	if (0 != result)
+		return result;
+
+	*value = cgs_read_register(smumgr->device, mmSMC_IND_DATA_0);
+
+	return 0;
+}
+
+/*
+ * Write a 32bit value to the SMC SRAM space.
+ * ALL PARAMETERS ARE IN HOST BYTE ORDER.
+ * @param    smumgr  the address of the powerplay hardware manager.
+ * @param    smcAddress the address in the SMC RAM to access.
+ * @param    value to write to the SMC SRAM.
+ */
+int tonga_write_smc_sram_dword(struct pp_smumgr *smumgr,
+					uint32_t smcAddress, uint32_t value,
+					uint32_t limit)
+{
+	int result;
+
+	result = tonga_set_smc_sram_address(smumgr, smcAddress, limit);
+
+	if (0 != result)
+		return result;
+
+	cgs_write_register(smumgr->device, mmSMC_IND_DATA_0, value);
+
+	return 0;
+}
+
+static int tonga_smu_fini(struct pp_smumgr *smumgr)
+{
+	if (smumgr->backend != NULL) {
+		kfree(smumgr->backend);
+		smumgr->backend = NULL;
+	}
+	return 0;
+}
+
+static enum cgs_ucode_id tonga_convert_fw_type_to_cgs(uint32_t fw_type)
+{
+	enum cgs_ucode_id result = CGS_UCODE_ID_MAXIMUM;
+
+	switch (fw_type) {
+	case UCODE_ID_SMU:
+		result = CGS_UCODE_ID_SMU;
+		break;
+	case UCODE_ID_SDMA0:
+		result = CGS_UCODE_ID_SDMA0;
+		break;
+	case UCODE_ID_SDMA1:
+		result = CGS_UCODE_ID_SDMA1;
+		break;
+	case UCODE_ID_CP_CE:
+		result = CGS_UCODE_ID_CP_CE;
+		break;
+	case UCODE_ID_CP_PFP:
+		result = CGS_UCODE_ID_CP_PFP;
+		break;
+	case UCODE_ID_CP_ME:
+		result = CGS_UCODE_ID_CP_ME;
+		break;
+	case UCODE_ID_CP_MEC:
+		result = CGS_UCODE_ID_CP_MEC;
+		break;
+	case UCODE_ID_CP_MEC_JT1:
+		result = CGS_UCODE_ID_CP_MEC_JT1;
+		break;
+	case UCODE_ID_CP_MEC_JT2:
+		result = CGS_UCODE_ID_CP_MEC_JT2;
+		break;
+	case UCODE_ID_RLC_G:
+		result = CGS_UCODE_ID_RLC_G;
+		break;
+	default:
+		break;
+	}
+
+	return result;
+}
+
+/**
+ * Convert the PPIRI firmware type to SMU type mask.
+ * For MEC, we need to check all MEC related type
+*/
+static uint16_t tonga_get_mask_for_firmware_type(uint16_t firmwareType)
+{
+	uint16_t result = 0;
+
+	switch (firmwareType) {
+	case UCODE_ID_SDMA0:
+		result = UCODE_ID_SDMA0_MASK;
+		break;
+	case UCODE_ID_SDMA1:
+		result = UCODE_ID_SDMA1_MASK;
+		break;
+	case UCODE_ID_CP_CE:
+		result = UCODE_ID_CP_CE_MASK;
+		break;
+	case UCODE_ID_CP_PFP:
+		result = UCODE_ID_CP_PFP_MASK;
+		break;
+	case UCODE_ID_CP_ME:
+		result = UCODE_ID_CP_ME_MASK;
+		break;
+	case UCODE_ID_CP_MEC:
+	case UCODE_ID_CP_MEC_JT1:
+	case UCODE_ID_CP_MEC_JT2:
+		result = UCODE_ID_CP_MEC_MASK;
+		break;
+	case UCODE_ID_RLC_G:
+		result = UCODE_ID_RLC_G_MASK;
+		break;
+	default:
+		break;
+	}
+
+	return result;
+}
+
+/**
+ * Check if the FW has been loaded,
+ * SMU will not return if loading has not finished.
+*/
+static int tonga_check_fw_load_finish(struct pp_smumgr *smumgr, uint32_t fwType)
+{
+	uint16_t fwMask = tonga_get_mask_for_firmware_type(fwType);
+
+	if (0 != SMUM_WAIT_VFPF_INDIRECT_REGISTER(smumgr, SMC_IND,
+				SOFT_REGISTERS_TABLE_28, fwMask, fwMask)) {
+		printk(KERN_ERR "[ powerplay ] check firmware loading failed\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+/* Populate one firmware image to the data structure */
+static int tonga_populate_single_firmware_entry(struct pp_smumgr *smumgr,
+				uint16_t firmware_type,
+				struct SMU_Entry *pentry)
+{
+	int result;
+	struct cgs_firmware_info info = {0};
+
+	result = cgs_get_firmware_info(
+				smumgr->device,
+				tonga_convert_fw_type_to_cgs(firmware_type),
+				&info);
+
+	if (result == 0) {
+		pentry->version = 0;
+		pentry->id = (uint16_t)firmware_type;
+		pentry->image_addr_high = smu_upper_32_bits(info.mc_addr);
+		pentry->image_addr_low = smu_lower_32_bits(info.mc_addr);
+		pentry->meta_data_addr_high = 0;
+		pentry->meta_data_addr_low = 0;
+		pentry->data_size_byte = info.image_size;
+		pentry->num_register_entries = 0;
+
+		if (firmware_type == UCODE_ID_RLC_G)
+			pentry->flags = 1;
+		else
+			pentry->flags = 0;
+	} else {
+		return result;
+	}
+
+	return result;
+}
+
+static int tonga_request_smu_reload_fw(struct pp_smumgr *smumgr)
+{
+	struct tonga_smumgr *tonga_smu =
+		(struct tonga_smumgr *)(smumgr->backend);
+	uint16_t fw_to_load;
+	int result = 0;
+	struct SMU_DRAMData_TOC *toc;
+	/**
+	 * First time this gets called during SmuMgr init,
+	 * we haven't processed SMU header file yet,
+	 * so Soft Register Start offset is unknown.
+	 * However, for this case, UcodeLoadStatus is already 0,
+	 * so we can skip this if the Soft Registers Start offset is 0.
+	 */
+	cgs_write_ind_register(smumgr->device,
+		CGS_IND_REG__SMC, ixSOFT_REGISTERS_TABLE_28, 0);
+
+	tonga_send_msg_to_smc_with_parameter(smumgr,
+		PPSMC_MSG_SMU_DRAM_ADDR_HI,
+		tonga_smu->smu_buffer.mc_addr_high);
+	tonga_send_msg_to_smc_with_parameter(smumgr,
+		PPSMC_MSG_SMU_DRAM_ADDR_LO,
+		tonga_smu->smu_buffer.mc_addr_low);
+
+	toc = (struct SMU_DRAMData_TOC *)tonga_smu->pHeader;
+	toc->num_entries = 0;
+	toc->structure_version = 1;
+
+	PP_ASSERT_WITH_CODE(
+		0 == tonga_populate_single_firmware_entry(smumgr,
+		UCODE_ID_RLC_G,
+		&toc->entry[toc->num_entries++]),
+		"Failed to Get Firmware Entry.\n",
+		return -1);
+	PP_ASSERT_WITH_CODE(
+		0 == tonga_populate_single_firmware_entry(smumgr,
+		UCODE_ID_CP_CE,
+		&toc->entry[toc->num_entries++]),
+		"Failed to Get Firmware Entry.\n",
+		return -1);
+	PP_ASSERT_WITH_CODE(
+		0 == tonga_populate_single_firmware_entry
+		(smumgr, UCODE_ID_CP_PFP, &toc->entry[toc->num_entries++]),
+		"Failed to Get Firmware Entry.\n", return -1);
+	PP_ASSERT_WITH_CODE(
+		0 == tonga_populate_single_firmware_entry
+		(smumgr, UCODE_ID_CP_ME, &toc->entry[toc->num_entries++]),
+		"Failed to Get Firmware Entry.\n", return -1);
+	PP_ASSERT_WITH_CODE(
+		0 == tonga_populate_single_firmware_entry
+		(smumgr, UCODE_ID_CP_MEC, &toc->entry[toc->num_entries++]),
+		"Failed to Get Firmware Entry.\n", return -1);
+	PP_ASSERT_WITH_CODE(
+		0 == tonga_populate_single_firmware_entry
+		(smumgr, UCODE_ID_CP_MEC_JT1, &toc->entry[toc->num_entries++]),
+		"Failed to Get Firmware Entry.\n", return -1);
+	PP_ASSERT_WITH_CODE(
+		0 == tonga_populate_single_firmware_entry
+		(smumgr, UCODE_ID_CP_MEC_JT2, &toc->entry[toc->num_entries++]),
+		"Failed to Get Firmware Entry.\n", return -1);
+	PP_ASSERT_WITH_CODE(
+		0 == tonga_populate_single_firmware_entry
+		(smumgr, UCODE_ID_SDMA0, &toc->entry[toc->num_entries++]),
+		"Failed to Get Firmware Entry.\n", return -1);
+	PP_ASSERT_WITH_CODE(
+		0 == tonga_populate_single_firmware_entry
+		(smumgr, UCODE_ID_SDMA1, &toc->entry[toc->num_entries++]),
+		"Failed to Get Firmware Entry.\n", return -1);
+
+	tonga_send_msg_to_smc_with_parameter(smumgr,
+		PPSMC_MSG_DRV_DRAM_ADDR_HI,
+		tonga_smu->header_buffer.mc_addr_high);
+	tonga_send_msg_to_smc_with_parameter(smumgr,
+		PPSMC_MSG_DRV_DRAM_ADDR_LO,
+		tonga_smu->header_buffer.mc_addr_low);
+
+	fw_to_load = UCODE_ID_RLC_G_MASK
+			+ UCODE_ID_SDMA0_MASK
+			+ UCODE_ID_SDMA1_MASK
+			+ UCODE_ID_CP_CE_MASK
+			+ UCODE_ID_CP_ME_MASK
+			+ UCODE_ID_CP_PFP_MASK
+			+ UCODE_ID_CP_MEC_MASK;
+
+	PP_ASSERT_WITH_CODE(
+		0 == tonga_send_msg_to_smc_with_parameter_without_waiting(
+		smumgr, PPSMC_MSG_LoadUcodes, fw_to_load),
+		"Fail to Request SMU Load uCode", return 0);
+
+	return result;
+}
+
+static int tonga_request_smu_load_specific_fw(struct pp_smumgr *smumgr,
+				uint32_t firmwareType)
+{
+	return 0;
+}
+
+/**
+ * Upload the SMC firmware to the SMC microcontroller.
+ *
+ * @param    smumgr  the address of the powerplay hardware manager.
+ * @param    pFirmware the data structure containing the various sections of the firmware.
+ */
+static int tonga_smu_upload_firmware_image(struct pp_smumgr *smumgr)
+{
+	const uint8_t *src;
+	uint32_t byte_count;
+	uint32_t *data;
+	struct cgs_firmware_info info = {0};
+
+	if (smumgr == NULL || smumgr->device == NULL)
+		return -EINVAL;
+
+	cgs_get_firmware_info(smumgr->device,
+		tonga_convert_fw_type_to_cgs(UCODE_ID_SMU), &info);
+
+	if (info.image_size & 3) {
+		printk(KERN_ERR "[ powerplay ] SMC ucode is not 4 bytes aligned\n");
+		return -EINVAL;
+	}
+
+	if (info.image_size > TONGA_SMC_SIZE) {
+		printk(KERN_ERR "[ powerplay ] SMC address is beyond the SMC RAM area\n");
+		return -EINVAL;
+	}
+
+	cgs_write_register(smumgr->device, mmSMC_IND_INDEX_0, 0x20000);
+	SMUM_WRITE_FIELD(smumgr->device, SMC_IND_ACCESS_CNTL, AUTO_INCREMENT_IND_0, 1);
+
+	byte_count = info.image_size;
+	src = (const uint8_t *)info.kptr;
+
+	data = (uint32_t *)src;
+	for (; byte_count >= 4; data++, byte_count -= 4)
+		cgs_write_register(smumgr->device, mmSMC_IND_DATA_0, data[0]);
+
+	SMUM_WRITE_FIELD(smumgr->device, SMC_IND_ACCESS_CNTL, AUTO_INCREMENT_IND_0, 0);
+
+	return 0;
+}
+
+static int tonga_start_in_protection_mode(struct pp_smumgr *smumgr)
+{
+	int result;
+
+	/* Assert reset */
+	SMUM_WRITE_VFPF_INDIRECT_FIELD(smumgr->device, CGS_IND_REG__SMC,
+		SMC_SYSCON_RESET_CNTL, rst_reg, 1);
+
+	result = tonga_smu_upload_firmware_image(smumgr);
+	if (result)
+		return result;
+
+	/* Clear status */
+	cgs_write_ind_register(smumgr->device, CGS_IND_REG__SMC,
+		ixSMU_STATUS, 0);
+
+	/* Enable clock */
+	SMUM_WRITE_VFPF_INDIRECT_FIELD(smumgr->device, CGS_IND_REG__SMC,
+		SMC_SYSCON_CLOCK_CNTL_0, ck_disable, 0);
+
+	/* De-assert reset */
+	SMUM_WRITE_VFPF_INDIRECT_FIELD(smumgr->device, CGS_IND_REG__SMC,
+		SMC_SYSCON_RESET_CNTL, rst_reg, 0);
+
+	/* Set SMU Auto Start */
+	SMUM_WRITE_VFPF_INDIRECT_FIELD(smumgr->device, CGS_IND_REG__SMC,
+		SMU_INPUT_DATA, AUTO_START, 1);
+
+	/* Clear firmware interrupt enable flag */
+	cgs_write_ind_register(smumgr->device, CGS_IND_REG__SMC,
+		ixFIRMWARE_FLAGS, 0);
+
+	SMUM_WAIT_VFPF_INDIRECT_FIELD(smumgr, SMC_IND,
+		RCU_UC_EVENTS, INTERRUPTS_ENABLED, 1);
+
+	/**
+	 * Call Test SMU message with 0x20000 offset to trigger SMU start
+	 */
+	tonga_send_msg_to_smc_offset(smumgr);
+
+	/* Wait for done bit to be set */
+	SMUM_WAIT_VFPF_INDIRECT_FIELD_UNEQUAL(smumgr, SMC_IND,
+		SMU_STATUS, SMU_DONE, 0);
+
+	/* Check pass/failed indicator */
+	if (1 != SMUM_READ_VFPF_INDIRECT_FIELD(smumgr->device,
+				CGS_IND_REG__SMC, SMU_STATUS, SMU_PASS)) {
+		printk(KERN_ERR "[ powerplay ] SMU Firmware start failed\n");
+		return -EINVAL;
+	}
+
+	/* Wait for firmware to initialize */
+	SMUM_WAIT_VFPF_INDIRECT_FIELD(smumgr, SMC_IND,
+		FIRMWARE_FLAGS, INTERRUPTS_ENABLED, 1);
+
+	return 0;
+}
+
+
+static int tonga_start_in_non_protection_mode(struct pp_smumgr *smumgr)
+{
+	int result = 0;
+
+	/* wait for smc boot up */
+	SMUM_WAIT_VFPF_INDIRECT_FIELD_UNEQUAL(smumgr, SMC_IND,
+		RCU_UC_EVENTS, boot_seq_done, 0);
+
+	/*Clear firmware interrupt enable flag*/
+	cgs_write_ind_register(smumgr->device, CGS_IND_REG__SMC,
+		ixFIRMWARE_FLAGS, 0);
+
+
+	SMUM_WRITE_VFPF_INDIRECT_FIELD(smumgr->device, CGS_IND_REG__SMC,
+		SMC_SYSCON_RESET_CNTL, rst_reg, 1);
+
+	result = tonga_smu_upload_firmware_image(smumgr);
+
+	if (result != 0)
+		return result;
+
+	/* Set smc instruct start point at 0x0 */
+	tonga_program_jump_on_start(smumgr);
+
+
+	SMUM_WRITE_VFPF_INDIRECT_FIELD(smumgr->device, CGS_IND_REG__SMC,
+		SMC_SYSCON_CLOCK_CNTL_0, ck_disable, 0);
+
+	/*De-assert reset*/
+	SMUM_WRITE_VFPF_INDIRECT_FIELD(smumgr->device, CGS_IND_REG__SMC,
+		SMC_SYSCON_RESET_CNTL, rst_reg, 0);
+
+	/* Wait for firmware to initialize */
+	SMUM_WAIT_VFPF_INDIRECT_FIELD(smumgr, SMC_IND,
+		FIRMWARE_FLAGS, INTERRUPTS_ENABLED, 1);
+
+	return result;
+}
+
+static int tonga_start_smu(struct pp_smumgr *smumgr)
+{
+	int result;
+
+	/* Only start SMC if SMC RAM is not running */
+	if (!tonga_is_smc_ram_running(smumgr)) {
+		/*Check if SMU is running in protected mode*/
+		if (0 == SMUM_READ_VFPF_INDIRECT_FIELD(smumgr->device, CGS_IND_REG__SMC,
+					SMU_FIRMWARE, SMU_MODE)) {
+			result = tonga_start_in_non_protection_mode(smumgr);
+			if (result)
+				return result;
+		} else {
+			result = tonga_start_in_protection_mode(smumgr);
+			if (result)
+				return result;
+		}
+	}
+
+	result = tonga_request_smu_reload_fw(smumgr);
+
+	return result;
+}
+
+/**
+ * Write a 32bit value to the SMC SRAM space.
+ * ALL PARAMETERS ARE IN HOST BYTE ORDER.
+ * @param    smumgr  the address of the powerplay hardware manager.
+ * @param    smcAddress the address in the SMC RAM to access.
+ * @param    value to write to the SMC SRAM.
+ */
+static int tonga_smu_init(struct pp_smumgr *smumgr)
+{
+	struct tonga_smumgr *tonga_smu;
+	uint8_t *internal_buf;
+	uint64_t mc_addr = 0;
+	/* Allocate memory for backend private data */
+	tonga_smu = (struct tonga_smumgr *)(smumgr->backend);
+	tonga_smu->header_buffer.data_size =
+		((sizeof(struct SMU_DRAMData_TOC) / 4096) + 1) * 4096;
+	tonga_smu->smu_buffer.data_size = 200*4096;
+
+	smu_allocate_memory(smumgr->device,
+		tonga_smu->header_buffer.data_size,
+		CGS_GPU_MEM_TYPE__VISIBLE_CONTIG_FB,
+		PAGE_SIZE,
+		&mc_addr,
+		&tonga_smu->header_buffer.kaddr,
+		&tonga_smu->header_buffer.handle);
+
+	tonga_smu->pHeader = tonga_smu->header_buffer.kaddr;
+	tonga_smu->header_buffer.mc_addr_high = smu_upper_32_bits(mc_addr);
+	tonga_smu->header_buffer.mc_addr_low = smu_lower_32_bits(mc_addr);
+
+	PP_ASSERT_WITH_CODE((NULL != tonga_smu->pHeader),
+		"Out of memory.",
+		kfree(smumgr->backend);
+		cgs_free_gpu_mem(smumgr->device,
+		(cgs_handle_t)tonga_smu->header_buffer.handle);
+		return -1);
+
+	smu_allocate_memory(smumgr->device,
+		tonga_smu->smu_buffer.data_size,
+		CGS_GPU_MEM_TYPE__VISIBLE_CONTIG_FB,
+		PAGE_SIZE,
+		&mc_addr,
+		&tonga_smu->smu_buffer.kaddr,
+		&tonga_smu->smu_buffer.handle);
+
+	internal_buf = tonga_smu->smu_buffer.kaddr;
+	tonga_smu->smu_buffer.mc_addr_high = smu_upper_32_bits(mc_addr);
+	tonga_smu->smu_buffer.mc_addr_low = smu_lower_32_bits(mc_addr);
+
+	PP_ASSERT_WITH_CODE((NULL != internal_buf),
+		"Out of memory.",
+		kfree(smumgr->backend);
+		cgs_free_gpu_mem(smumgr->device,
+		(cgs_handle_t)tonga_smu->smu_buffer.handle);
+		return -1;);
+
+	return 0;
+}
+
+static const struct pp_smumgr_func tonga_smu_funcs = {
+	.smu_init = &tonga_smu_init,
+	.smu_fini = &tonga_smu_fini,
+	.start_smu = &tonga_start_smu,
+	.check_fw_load_finish = &tonga_check_fw_load_finish,
+	.request_smu_load_fw = &tonga_request_smu_reload_fw,
+	.request_smu_load_specific_fw = &tonga_request_smu_load_specific_fw,
+	.send_msg_to_smc = &tonga_send_msg_to_smc,
+	.send_msg_to_smc_with_parameter = &tonga_send_msg_to_smc_with_parameter,
+	.download_pptable_settings = NULL,
+	.upload_pptable_settings = NULL,
+};
+
+int tonga_smum_init(struct pp_smumgr *smumgr)
+{
+	struct tonga_smumgr *tonga_smu = NULL;
+
+	tonga_smu = kzalloc(sizeof(struct tonga_smumgr), GFP_KERNEL);
+
+	if (tonga_smu == NULL)
+		return -ENOMEM;
+
+	smumgr->backend = tonga_smu;
+	smumgr->smumgr_funcs = &tonga_smu_funcs;
+
+	return 0;
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/powerplay/smumgr/tonga_smumgr.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2015 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#ifndef _TONGA_SMUMGR_H_
+#define _TONGA_SMUMGR_H_
+
+struct tonga_buffer_entry {
+	uint32_t data_size;
+	uint32_t mc_addr_low;
+	uint32_t mc_addr_high;
+	void *kaddr;
+	unsigned long  handle;
+};
+
+struct tonga_smumgr {
+	uint8_t *pHeader;
+	uint8_t *pMecImage;
+	uint32_t ulSoftRegsStart;
+
+	struct tonga_buffer_entry header_buffer;
+	struct tonga_buffer_entry smu_buffer;
+};
+
+extern int tonga_smum_init(struct pp_smumgr *smumgr);
+extern int tonga_copy_bytes_to_smc(struct pp_smumgr *smumgr,
+		uint32_t smcStartAddress, const uint8_t *src,
+		uint32_t byteCount, uint32_t limit);
+extern int tonga_read_smc_sram_dword(struct pp_smumgr *smumgr, uint32_t smcAddress,
+		uint32_t *value, uint32_t limit);
+extern int tonga_write_smc_sram_dword(struct pp_smumgr *smumgr, uint32_t smcAddress,
+		uint32_t value, uint32_t limit);
+
+#endif
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/amd/scheduler/gpu_scheduler.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/scheduler/gpu_scheduler.c
@@ -47,6 +47,8 @@ static void amd_sched_rq_init(struct amd
 static void amd_sched_rq_add_entity(struct amd_sched_rq *rq,
 				    struct amd_sched_entity *entity)
 {
+	if (!list_empty(&entity->list))
+		return;
 	spin_lock(&rq->lock);
 	list_add_tail(&entity->list, &rq->entities);
 	spin_unlock(&rq->lock);
@@ -55,6 +57,8 @@ static void amd_sched_rq_add_entity(stru
 static void amd_sched_rq_remove_entity(struct amd_sched_rq *rq,
 				       struct amd_sched_entity *entity)
 {
+	if (list_empty(&entity->list))
+		return;
 	spin_lock(&rq->lock);
 	list_del_init(&entity->list);
 	if (rq->current_entity == entity)
@@ -138,9 +142,6 @@ int amd_sched_entity_init(struct amd_gpu
 	atomic_set(&entity->fence_seq, 0);
 	entity->fence_context = fence_context_alloc(1);
 
-	/* Add the entity to the run queue */
-	amd_sched_rq_add_entity(rq, entity);
-
 	return 0;
 }
 
@@ -302,9 +303,11 @@ static bool amd_sched_entity_in(struct a
 	spin_unlock(&entity->queue_lock);
 
 	/* first job wakes up scheduler */
-	if (first)
+	if (first) {
+		/* Add the entity to the run queue */
+		amd_sched_rq_add_entity(entity->rq, entity);
 		amd_sched_wakeup(sched);
-
+	}
 	return added;
 }
 
@@ -349,14 +352,17 @@ static struct amd_sched_entity *
 amd_sched_select_entity(struct amd_gpu_scheduler *sched)
 {
 	struct amd_sched_entity *entity;
+	int i;
 
 	if (!amd_sched_ready(sched))
 		return NULL;
 
 	/* Kernel run queue has higher priority than normal run queue*/
-	entity = amd_sched_rq_select_entity(&sched->kernel_rq);
-	if (entity == NULL)
-		entity = amd_sched_rq_select_entity(&sched->sched_rq);
+	for (i = 0; i < AMD_SCHED_MAX_PRIORITY; i++) {
+		entity = amd_sched_rq_select_entity(&sched->sched_rq[i]);
+		if (entity)
+			break;
+	}
 
 	return entity;
 }
@@ -478,12 +484,13 @@ int amd_sched_init(struct amd_gpu_schedu
 		   struct amd_sched_backend_ops *ops,
 		   unsigned hw_submission, long timeout, const char *name)
 {
+	int i;
 	sched->ops = ops;
 	sched->hw_submission_limit = hw_submission;
 	sched->name = name;
 	sched->timeout = timeout;
-	amd_sched_rq_init(&sched->sched_rq);
-	amd_sched_rq_init(&sched->kernel_rq);
+	for (i = 0; i < AMD_SCHED_MAX_PRIORITY; i++)
+		amd_sched_rq_init(&sched->sched_rq[i]);
 
 	init_waitqueue_head(&sched->wake_up_worker);
 	init_waitqueue_head(&sched->job_scheduled);
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/amd/scheduler/gpu_scheduler.h
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/amd/scheduler/gpu_scheduler.h
@@ -104,6 +104,12 @@ struct amd_sched_backend_ops {
 	struct fence *(*run_job)(struct amd_sched_job *sched_job);
 };
 
+enum amd_sched_priority {
+	AMD_SCHED_PRIORITY_KERNEL = 0,
+	AMD_SCHED_PRIORITY_NORMAL,
+	AMD_SCHED_MAX_PRIORITY
+};
+
 /**
  * One scheduler is implemented for each hardware ring
 */
@@ -112,8 +118,7 @@ struct amd_gpu_scheduler {
 	uint32_t			hw_submission_limit;
 	long				timeout;
 	const char			*name;
-	struct amd_sched_rq		sched_rq;
-	struct amd_sched_rq		kernel_rq;
+	struct amd_sched_rq		sched_rq[AMD_SCHED_MAX_PRIORITY];
 	wait_queue_head_t		wake_up_worker;
 	wait_queue_head_t		job_scheduled;
 	atomic_t			hw_rq_count;
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/ast/ast_main.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/ast/ast_main.c
@@ -227,7 +227,7 @@ static int ast_get_dram_info(struct drm_
 	} while (ast_read32(ast, 0x10000) != 0x01);
 	data = ast_read32(ast, 0x10004);
 
-	if (data & 0x400)
+	if (data & 0x40)
 		ast->dram_bus_width = 16;
 	else
 		ast->dram_bus_width = 32;
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c
@@ -316,25 +316,27 @@ atmel_hlcdc_plane_update_pos_and_size(st
 			u32 *coeff_tab = heo_upscaling_ycoef;
 			u32 max_memsize;
 
-			if (state->crtc_w < state->src_w)
+			if (state->crtc_h < state->src_h)
 				coeff_tab = heo_downscaling_ycoef;
 			for (i = 0; i < ARRAY_SIZE(heo_upscaling_ycoef); i++)
 				atmel_hlcdc_layer_update_cfg(&plane->layer,
 							     33 + i,
 							     0xffffffff,
 							     coeff_tab[i]);
-			factor = ((8 * 256 * state->src_w) - (256 * 4)) /
-				 state->crtc_w;
+			factor = ((8 * 256 * state->src_h) - (256 * 4)) /
+				 state->crtc_h;
 			factor++;
-			max_memsize = ((factor * state->crtc_w) + (256 * 4)) /
+			max_memsize = ((factor * state->crtc_h) + (256 * 4)) /
 				      2048;
-			if (max_memsize > state->src_w)
+			if (max_memsize > state->src_h)
 				factor--;
 			factor_reg |= (factor << 16) | 0x80000000;
 		}
 
 		atmel_hlcdc_layer_update_cfg(&plane->layer, 13, 0xffffffff,
 					     factor_reg);
+	} else {
+		atmel_hlcdc_layer_update_cfg(&plane->layer, 13, 0xffffffff, 0);
 	}
 }
 
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/drm_atomic.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/drm_atomic.c
@@ -28,6 +28,7 @@
 
 #include <drm/drmP.h>
 #include <drm/drm_atomic.h>
+#include <drm/drm_mode.h>
 #include <drm/drm_plane_helper.h>
 
 /**
@@ -150,7 +151,7 @@ void drm_atomic_state_default_clear(stru
 	for (i = 0; i < state->num_connector; i++) {
 		struct drm_connector *connector = state->connectors[i];
 
-		if (!connector)
+		if (!connector || !connector->funcs)
 			continue;
 
 		/*
@@ -316,8 +317,7 @@ int drm_atomic_set_mode_for_crtc(struct
 	if (mode && memcmp(&state->mode, mode, sizeof(*mode)) == 0)
 		return 0;
 
-	if (state->mode_blob)
-		drm_property_unreference_blob(state->mode_blob);
+	drm_property_unreference_blob(state->mode_blob);
 	state->mode_blob = NULL;
 
 	if (mode) {
@@ -363,10 +363,11 @@ int drm_atomic_set_mode_prop_for_crtc(st
 	if (blob == state->mode_blob)
 		return 0;
 
-	if (state->mode_blob)
-		drm_property_unreference_blob(state->mode_blob);
+	drm_property_unreference_blob(state->mode_blob);
 	state->mode_blob = NULL;
 
+	memset(&state->mode, 0, sizeof(state->mode));
+
 	if (blob) {
 		if (blob->length != sizeof(struct drm_mode_modeinfo) ||
 		    drm_mode_convert_umode(&state->mode,
@@ -379,7 +380,6 @@ int drm_atomic_set_mode_prop_for_crtc(st
 		DRM_DEBUG_ATOMIC("Set [MODE:%s] for CRTC state %p\n",
 				 state->mode.name, state);
 	} else {
-		memset(&state->mode, 0, sizeof(state->mode));
 		state->enable = false;
 		DRM_DEBUG_ATOMIC("Set [NOMODE] for CRTC state %p\n",
 				 state);
@@ -390,6 +390,59 @@ int drm_atomic_set_mode_prop_for_crtc(st
 EXPORT_SYMBOL(drm_atomic_set_mode_prop_for_crtc);
 
 /**
+ * drm_atomic_replace_property_blob - replace a blob property
+ * @blob: a pointer to the member blob to be replaced
+ * @new_blob: the new blob to replace with
+ * @expected_size: the expected size of the new blob
+ * @replaced: whether the blob has been replaced
+ *
+ * RETURNS:
+ * Zero on success, error code on failure
+ */
+static void
+drm_atomic_replace_property_blob(struct drm_property_blob **blob,
+				 struct drm_property_blob *new_blob,
+				 bool *replaced)
+{
+	struct drm_property_blob *old_blob = *blob;
+
+	if (old_blob == new_blob)
+		return;
+
+	if (old_blob)
+		drm_property_unreference_blob(old_blob);
+	if (new_blob)
+		drm_property_reference_blob(new_blob);
+	*blob = new_blob;
+	*replaced = true;
+
+	return;
+}
+
+static int
+drm_atomic_replace_property_blob_from_id(struct drm_crtc *crtc,
+					 struct drm_property_blob **blob,
+					 uint64_t blob_id,
+					 ssize_t expected_size,
+					 bool *replaced)
+{
+	struct drm_device *dev = crtc->dev;
+	struct drm_property_blob *new_blob = NULL;
+
+	if (blob_id != 0) {
+		new_blob = drm_property_lookup_blob(dev, blob_id);
+		if (new_blob == NULL)
+			return -EINVAL;
+		if (expected_size > 0 && expected_size != new_blob->length)
+			return -EINVAL;
+	}
+
+	drm_atomic_replace_property_blob(blob, new_blob, replaced);
+
+	return 0;
+}
+
+/**
  * drm_atomic_crtc_set_property - set property on CRTC
  * @crtc: the drm CRTC to set a property on
  * @state: the state object to update with the new property value
@@ -411,6 +464,7 @@ int drm_atomic_crtc_set_property(struct
 {
 	struct drm_device *dev = crtc->dev;
 	struct drm_mode_config *config = &dev->mode_config;
+	bool replaced = false;
 	int ret;
 
 	if (property == config->prop_active)
@@ -419,11 +473,33 @@ int drm_atomic_crtc_set_property(struct
 		struct drm_property_blob *mode =
 			drm_property_lookup_blob(dev, val);
 		ret = drm_atomic_set_mode_prop_for_crtc(state, mode);
-		if (mode)
-			drm_property_unreference_blob(mode);
+		drm_property_unreference_blob(mode);
 		return ret;
-	}
-	else if (crtc->funcs->atomic_set_property)
+	} else if (property == config->degamma_lut_property) {
+		ret = drm_atomic_replace_property_blob_from_id(crtc,
+					&state->degamma_lut,
+					val,
+					-1,
+					&replaced);
+		state->color_mgmt_changed = replaced;
+		return ret;
+	} else if (property == config->ctm_property) {
+		ret = drm_atomic_replace_property_blob_from_id(crtc,
+					&state->ctm,
+					val,
+					sizeof(struct drm_color_ctm),
+					&replaced);
+		state->color_mgmt_changed = replaced;
+		return ret;
+	} else if (property == config->gamma_lut_property) {
+		ret = drm_atomic_replace_property_blob_from_id(crtc,
+					&state->gamma_lut,
+					val,
+					-1,
+					&replaced);
+		state->color_mgmt_changed = replaced;
+		return ret;
+	} else if (crtc->funcs->atomic_set_property)
 		return crtc->funcs->atomic_set_property(crtc, state, property, val);
 	else
 		return -EINVAL;
@@ -450,6 +526,12 @@ drm_atomic_crtc_get_property(struct drm_
 		*val = state->active;
 	else if (property == config->prop_mode_id)
 		*val = (state->mode_blob) ? state->mode_blob->base.id : 0;
+	else if (property == config->degamma_lut_property)
+		*val = (state->degamma_lut) ? state->degamma_lut->base.id : 0;
+	else if (property == config->ctm_property)
+		*val = (state->ctm) ? state->ctm->base.id : 0;
+	else if (property == config->gamma_lut_property)
+		*val = (state->gamma_lut) ? state->gamma_lut->base.id : 0;
 	else if (crtc->funcs->atomic_get_property)
 		return crtc->funcs->atomic_get_property(crtc, state, property, val);
 	else
@@ -1039,10 +1121,21 @@ drm_atomic_set_crtc_for_connector(struct
 {
 	struct drm_crtc_state *crtc_state;
 
+	if (conn_state->crtc && conn_state->crtc != crtc) {
+		crtc_state = drm_atomic_get_existing_crtc_state(conn_state->state,
+								conn_state->crtc);
+
+		crtc_state->connector_mask &=
+			~(1 << drm_connector_index(conn_state->connector));
+	}
+
 	if (crtc) {
 		crtc_state = drm_atomic_get_crtc_state(conn_state->state, crtc);
 		if (IS_ERR(crtc_state))
 			return PTR_ERR(crtc_state);
+
+		crtc_state->connector_mask |=
+			1 << drm_connector_index(conn_state->connector);
 	}
 
 	conn_state->crtc = crtc;
@@ -1148,35 +1241,6 @@ drm_atomic_add_affected_planes(struct dr
 EXPORT_SYMBOL(drm_atomic_add_affected_planes);
 
 /**
- * drm_atomic_connectors_for_crtc - count number of connected outputs
- * @state: atomic state
- * @crtc: DRM crtc
- *
- * This function counts all connectors which will be connected to @crtc
- * according to @state. Useful to recompute the enable state for @crtc.
- */
-int
-drm_atomic_connectors_for_crtc(struct drm_atomic_state *state,
-			       struct drm_crtc *crtc)
-{
-	struct drm_connector *connector;
-	struct drm_connector_state *conn_state;
-
-	int i, num_connected_connectors = 0;
-
-	for_each_connector_in_state(state, connector, conn_state, i) {
-		if (conn_state->crtc == crtc)
-			num_connected_connectors++;
-	}
-
-	DRM_DEBUG_ATOMIC("State %p has %i connectors for [CRTC:%d]\n",
-			 state, num_connected_connectors, crtc->base.id);
-
-	return num_connected_connectors;
-}
-EXPORT_SYMBOL(drm_atomic_connectors_for_crtc);
-
-/**
  * drm_atomic_legacy_backoff - locking backoff for legacy ioctls
  * @state: atomic state
  *
@@ -1191,12 +1255,7 @@ void drm_atomic_legacy_backoff(struct dr
 retry:
 	drm_modeset_backoff(state->acquire_ctx);
 
-	ret = drm_modeset_lock(&state->dev->mode_config.connection_mutex,
-			       state->acquire_ctx);
-	if (ret)
-		goto retry;
-	ret = drm_modeset_lock_all_crtcs(state->dev,
-					 state->acquire_ctx);
+	ret = drm_modeset_lock_all_ctx(state->dev, state->acquire_ctx);
 	if (ret)
 		goto retry;
 }
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/drm_atomic_helper.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/drm_atomic_helper.c
@@ -99,6 +99,47 @@ get_current_crtc_for_encoder(struct drm_
 	return NULL;
 }
 
+static void
+set_best_encoder(struct drm_atomic_state *state,
+		 struct drm_connector_state *conn_state,
+		 struct drm_encoder *encoder)
+{
+	struct drm_crtc_state *crtc_state;
+	struct drm_crtc *crtc;
+
+	if (conn_state->best_encoder) {
+		/* Unset the encoder_mask in the old crtc state. */
+		crtc = conn_state->connector->state->crtc;
+
+		/* A NULL crtc is an error here because we should have
+		 *  duplicated a NULL best_encoder when crtc was NULL.
+		 * As an exception restoring duplicated atomic state
+		 * during resume is allowed, so don't warn when
+		 * best_encoder is equal to encoder we intend to set.
+		 */
+		WARN_ON(!crtc && encoder != conn_state->best_encoder);
+		if (crtc) {
+			crtc_state = drm_atomic_get_existing_crtc_state(state, crtc);
+
+			crtc_state->encoder_mask &=
+				~(1 << drm_encoder_index(conn_state->best_encoder));
+		}
+	}
+
+	if (encoder) {
+		crtc = conn_state->crtc;
+		WARN_ON(!crtc);
+		if (crtc) {
+			crtc_state = drm_atomic_get_existing_crtc_state(state, crtc);
+
+			crtc_state->encoder_mask |=
+				1 << drm_encoder_index(encoder);
+		}
+	}
+
+	conn_state->best_encoder = encoder;
+}
+
 static int
 steal_encoder(struct drm_atomic_state *state,
 	      struct drm_encoder *encoder,
@@ -108,7 +149,6 @@ steal_encoder(struct drm_atomic_state *s
 	struct drm_crtc_state *crtc_state;
 	struct drm_connector *connector;
 	struct drm_connector_state *connector_state;
-	int ret;
 
 	/*
 	 * We can only steal an encoder coming from a connector, which means we
@@ -139,10 +179,10 @@ steal_encoder(struct drm_atomic_state *s
 		if (IS_ERR(connector_state))
 			return PTR_ERR(connector_state);
 
-		ret = drm_atomic_set_crtc_for_connector(connector_state, NULL);
-		if (ret)
-			return ret;
-		connector_state->best_encoder = NULL;
+		if (connector_state->best_encoder != encoder)
+			continue;
+
+		set_best_encoder(state, connector_state, NULL);
 	}
 
 	return 0;
@@ -190,7 +230,7 @@ update_connector_routing(struct drm_atom
 				connector->base.id,
 				connector->name);
 
-		connector_state->best_encoder = NULL;
+		set_best_encoder(state, connector_state, NULL);
 
 		return 0;
 	}
@@ -219,6 +259,8 @@ update_connector_routing(struct drm_atom
 	}
 
 	if (new_encoder == connector_state->best_encoder) {
+		set_best_encoder(state, connector_state, new_encoder);
+
 		DRM_DEBUG_ATOMIC("[CONNECTOR:%d:%s] keeps [ENCODER:%d:%s], now on [CRTC:%d]\n",
 				 connector->base.id,
 				 connector->name,
@@ -245,7 +287,8 @@ update_connector_routing(struct drm_atom
 	if (WARN_ON(!connector_state->crtc))
 		return -EINVAL;
 
-	connector_state->best_encoder = new_encoder;
+	set_best_encoder(state, connector_state, new_encoder);
+
 	idx = drm_crtc_index(connector_state->crtc);
 
 	crtc_state = state->crtc_states[idx];
@@ -428,7 +471,8 @@ drm_atomic_helper_check_modeset(struct d
 	 * crtc only changed its mode but has the same set of connectors.
 	 */
 	for_each_crtc_in_state(state, crtc, crtc_state, i) {
-		int num_connectors;
+		bool has_connectors =
+			!!crtc_state->connector_mask;
 
 		/*
 		 * We must set ->active_changed after walking connectors for
@@ -457,10 +501,7 @@ drm_atomic_helper_check_modeset(struct d
 		if (ret != 0)
 			return ret;
 
-		num_connectors = drm_atomic_connectors_for_crtc(state,
-								crtc);
-
-		if (crtc_state->enable != !!num_connectors) {
+		if (crtc_state->enable != has_connectors) {
 			DRM_DEBUG_ATOMIC("[CRTC:%d] enabled/connectors mismatch\n",
 					 crtc->base.id);
 
@@ -913,9 +954,23 @@ static void wait_for_fences(struct drm_d
 	}
 }
 
-static bool framebuffer_changed(struct drm_device *dev,
-				struct drm_atomic_state *old_state,
-				struct drm_crtc *crtc)
+/**
+ * drm_atomic_helper_framebuffer_changed - check if framebuffer has changed
+ * @dev: DRM device
+ * @old_state: atomic state object with old state structures
+ * @crtc: DRM crtc
+ *
+ * Checks whether the framebuffer used for this CRTC changes as a result of
+ * the atomic update.  This is useful for drivers which cannot use
+ * drm_atomic_helper_wait_for_vblanks() and need to reimplement its
+ * functionality.
+ *
+ * Returns:
+ * true if the framebuffer changed.
+ */
+bool drm_atomic_helper_framebuffer_changed(struct drm_device *dev,
+					   struct drm_atomic_state *old_state,
+					   struct drm_crtc *crtc)
 {
 	struct drm_plane *plane;
 	struct drm_plane_state *old_plane_state;
@@ -932,6 +987,7 @@ static bool framebuffer_changed(struct d
 
 	return false;
 }
+EXPORT_SYMBOL(drm_atomic_helper_framebuffer_changed);
 
 /**
  * drm_atomic_helper_wait_for_vblanks - wait for vblank on crtcs
@@ -966,7 +1022,8 @@ drm_atomic_helper_wait_for_vblanks(struc
 		if (old_state->legacy_cursor_update)
 			continue;
 
-		if (!framebuffer_changed(dev, old_state, crtc))
+		if (!drm_atomic_helper_framebuffer_changed(dev,
+				old_state, crtc))
 			continue;
 
 		ret = drm_crtc_vblank_get(crtc);
@@ -1676,7 +1733,7 @@ static int update_output_state(struct dr
 		if (crtc == set->crtc)
 			continue;
 
-		if (!drm_atomic_connectors_for_crtc(state, crtc)) {
+		if (!crtc_state->connector_mask) {
 			ret = drm_atomic_set_mode_prop_for_crtc(crtc_state,
 								NULL);
 			if (ret < 0)
@@ -1818,6 +1875,161 @@ commit:
 }
 
 /**
+ * drm_atomic_helper_disable_all - disable all currently active outputs
+ * @dev: DRM device
+ * @ctx: lock acquisition context
+ *
+ * Loops through all connectors, finding those that aren't turned off and then
+ * turns them off by setting their DPMS mode to OFF and deactivating the CRTC
+ * that they are connected to.
+ *
+ * This is used for example in suspend/resume to disable all currently active
+ * functions when suspending.
+ *
+ * Note that if callers haven't already acquired all modeset locks this might
+ * return -EDEADLK, which must be handled by calling drm_modeset_backoff().
+ *
+ * Returns:
+ * 0 on success or a negative error code on failure.
+ *
+ * See also:
+ * drm_atomic_helper_suspend(), drm_atomic_helper_resume()
+ */
+int drm_atomic_helper_disable_all(struct drm_device *dev,
+				  struct drm_modeset_acquire_ctx *ctx)
+{
+	struct drm_atomic_state *state;
+	struct drm_connector *conn;
+	int err;
+
+	state = drm_atomic_state_alloc(dev);
+	if (!state)
+		return -ENOMEM;
+
+	state->acquire_ctx = ctx;
+
+	drm_for_each_connector(conn, dev) {
+		struct drm_crtc *crtc = conn->state->crtc;
+		struct drm_crtc_state *crtc_state;
+
+		if (!crtc || conn->dpms != DRM_MODE_DPMS_ON)
+			continue;
+
+		crtc_state = drm_atomic_get_crtc_state(state, crtc);
+		if (IS_ERR(crtc_state)) {
+			err = PTR_ERR(crtc_state);
+			goto free;
+		}
+
+		crtc_state->active = false;
+	}
+
+	err = drm_atomic_commit(state);
+
+free:
+	if (err < 0)
+		drm_atomic_state_free(state);
+
+	return err;
+}
+EXPORT_SYMBOL(drm_atomic_helper_disable_all);
+
+/**
+ * drm_atomic_helper_suspend - subsystem-level suspend helper
+ * @dev: DRM device
+ *
+ * Duplicates the current atomic state, disables all active outputs and then
+ * returns a pointer to the original atomic state to the caller. Drivers can
+ * pass this pointer to the drm_atomic_helper_resume() helper upon resume to
+ * restore the output configuration that was active at the time the system
+ * entered suspend.
+ *
+ * Note that it is potentially unsafe to use this. The atomic state object
+ * returned by this function is assumed to be persistent. Drivers must ensure
+ * that this holds true. Before calling this function, drivers must make sure
+ * to suspend fbdev emulation so that nothing can be using the device.
+ *
+ * Returns:
+ * A pointer to a copy of the state before suspend on success or an ERR_PTR()-
+ * encoded error code on failure. Drivers should store the returned atomic
+ * state object and pass it to the drm_atomic_helper_resume() helper upon
+ * resume.
+ *
+ * See also:
+ * drm_atomic_helper_duplicate_state(), drm_atomic_helper_disable_all(),
+ * drm_atomic_helper_resume()
+ */
+struct drm_atomic_state *drm_atomic_helper_suspend(struct drm_device *dev)
+{
+	struct drm_modeset_acquire_ctx ctx;
+	struct drm_atomic_state *state;
+	int err;
+
+	drm_modeset_acquire_init(&ctx, 0);
+
+retry:
+	err = drm_modeset_lock_all_ctx(dev, &ctx);
+	if (err < 0) {
+		state = ERR_PTR(err);
+		goto unlock;
+	}
+
+	state = drm_atomic_helper_duplicate_state(dev, &ctx);
+	if (IS_ERR(state))
+		goto unlock;
+
+	err = drm_atomic_helper_disable_all(dev, &ctx);
+	if (err < 0) {
+		drm_atomic_state_free(state);
+		state = ERR_PTR(err);
+		goto unlock;
+	}
+
+unlock:
+	if (PTR_ERR(state) == -EDEADLK) {
+		drm_modeset_backoff(&ctx);
+		goto retry;
+	}
+
+	drm_modeset_drop_locks(&ctx);
+	drm_modeset_acquire_fini(&ctx);
+	return state;
+}
+EXPORT_SYMBOL(drm_atomic_helper_suspend);
+
+/**
+ * drm_atomic_helper_resume - subsystem-level resume helper
+ * @dev: DRM device
+ * @state: atomic state to resume to
+ *
+ * Calls drm_mode_config_reset() to synchronize hardware and software states,
+ * grabs all modeset locks and commits the atomic state object. This can be
+ * used in conjunction with the drm_atomic_helper_suspend() helper to
+ * implement suspend/resume for drivers that support atomic mode-setting.
+ *
+ * Returns:
+ * 0 on success or a negative error code on failure.
+ *
+ * See also:
+ * drm_atomic_helper_suspend()
+ */
+int drm_atomic_helper_resume(struct drm_device *dev,
+			     struct drm_atomic_state *state)
+{
+	struct drm_mode_config *config = &dev->mode_config;
+	int err;
+
+	drm_mode_config_reset(dev);
+	drm_modeset_lock_all(dev);
+	state->acquire_ctx = config->acquire_ctx;
+	err = drm_atomic_commit(state);
+	drm_modeset_unlock_all(dev);
+
+	return err;
+}
+EXPORT_SYMBOL(drm_atomic_helper_resume);
+
+/**
  * drm_atomic_helper_crtc_set_property - helper for crtc properties
  * @crtc: DRM crtc
  * @property: DRM property
@@ -2184,8 +2396,12 @@ EXPORT_SYMBOL(drm_atomic_helper_connecto
  */
 void drm_atomic_helper_crtc_reset(struct drm_crtc *crtc)
 {
-	if (crtc->state && crtc->state->mode_blob)
+	if (crtc->state) {
 		drm_property_unreference_blob(crtc->state->mode_blob);
+		drm_property_unreference_blob(crtc->state->degamma_lut);
+		drm_property_unreference_blob(crtc->state->ctm);
+		drm_property_unreference_blob(crtc->state->gamma_lut);
+	}
 	kfree(crtc->state);
 	crtc->state = kzalloc(sizeof(*crtc->state), GFP_KERNEL);
 
@@ -2209,10 +2425,17 @@ void __drm_atomic_helper_crtc_duplicate_
 
 	if (state->mode_blob)
 		drm_property_reference_blob(state->mode_blob);
+	if (state->degamma_lut)
+		drm_property_reference_blob(state->degamma_lut);
+	if (state->ctm)
+		drm_property_reference_blob(state->ctm);
+	if (state->gamma_lut)
+		drm_property_reference_blob(state->gamma_lut);
 	state->mode_changed = false;
 	state->active_changed = false;
 	state->planes_changed = false;
 	state->connectors_changed = false;
+	state->color_mgmt_changed = false;
 	state->event = NULL;
 }
 EXPORT_SYMBOL(__drm_atomic_helper_crtc_duplicate_state);
@@ -2252,8 +2475,10 @@ EXPORT_SYMBOL(drm_atomic_helper_crtc_dup
 void __drm_atomic_helper_crtc_destroy_state(struct drm_crtc *crtc,
 					    struct drm_crtc_state *state)
 {
-	if (state->mode_blob)
-		drm_property_unreference_blob(state->mode_blob);
+	drm_property_unreference_blob(state->mode_blob);
+	drm_property_unreference_blob(state->degamma_lut);
+	drm_property_unreference_blob(state->ctm);
+	drm_property_unreference_blob(state->gamma_lut);
 }
 EXPORT_SYMBOL(__drm_atomic_helper_crtc_destroy_state);
 
@@ -2368,6 +2593,28 @@ void drm_atomic_helper_plane_destroy_sta
 EXPORT_SYMBOL(drm_atomic_helper_plane_destroy_state);
 
 /**
+ * __drm_atomic_helper_connector_reset - reset state on connector
+ * @connector: drm connector
+ * @conn_state: connector state to assign
+ *
+ * Initializes the newly allocated @conn_state and assigns it to
+ * #connector ->state, usually required when initializing the drivers
+ * or when called from the ->reset hook.
+ *
+ * This is useful for drivers that subclass the connector state.
+ */
+void
+__drm_atomic_helper_connector_reset(struct drm_connector *connector,
+				    struct drm_connector_state *conn_state)
+{
+	if (conn_state)
+		conn_state->connector = connector;
+
+	connector->state = conn_state;
+}
+EXPORT_SYMBOL(__drm_atomic_helper_connector_reset);
+
+/**
  * drm_atomic_helper_connector_reset - default ->reset hook for connectors
  * @connector: drm connector
  *
@@ -2377,11 +2624,11 @@ EXPORT_SYMBOL(drm_atomic_helper_plane_de
  */
 void drm_atomic_helper_connector_reset(struct drm_connector *connector)
 {
-	kfree(connector->state);
-	connector->state = kzalloc(sizeof(*connector->state), GFP_KERNEL);
+	struct drm_connector_state *conn_state =
+		kzalloc(sizeof(*conn_state), GFP_KERNEL);
 
-	if (connector->state)
-		connector->state->connector = connector;
+	kfree(connector->state);
+	__drm_atomic_helper_connector_reset(connector, conn_state);
 }
 EXPORT_SYMBOL(drm_atomic_helper_connector_reset);
 
@@ -2430,7 +2677,9 @@ EXPORT_SYMBOL(drm_atomic_helper_connecto
  * @ctx: lock acquisition context
  *
  * Makes a copy of the current atomic state by looping over all objects and
- * duplicating their respective states.
+ * duplicating their respective states. This is used for example by suspend/
+ * resume support code to save the state prior to suspend such that it can
+ * be restored upon resume.
  *
  * Note that this treats atomic state as persistent between save and restore.
  * Drivers must make sure that this is possible and won't result in confusion
@@ -2442,6 +2691,9 @@ EXPORT_SYMBOL(drm_atomic_helper_connecto
  * Returns:
  * A pointer to the copy of the atomic state object on success or an
  * ERR_PTR()-encoded error code on failure.
+ *
+ * See also:
+ * drm_atomic_helper_suspend(), drm_atomic_helper_resume()
  */
 struct drm_atomic_state *
 drm_atomic_helper_duplicate_state(struct drm_device *dev,
@@ -2538,3 +2790,98 @@ void drm_atomic_helper_connector_destroy
 	kfree(state);
 }
 EXPORT_SYMBOL(drm_atomic_helper_connector_destroy_state);
+
+/**
+ * drm_atomic_helper_legacy_gamma_set - set the legacy gamma correction table
+ * @crtc: CRTC object
+ * @red: red correction table
+ * @green: green correction table
+ * @blue: green correction table
+ * @start:
+ * @size: size of the tables
+ *
+ * Implements support for legacy gamma correction table for drivers
+ * that support color management through the DEGAMMA_LUT/GAMMA_LUT
+ * properties.
+ */
+void drm_atomic_helper_legacy_gamma_set(struct drm_crtc *crtc,
+					u16 *red, u16 *green, u16 *blue,
+					uint32_t start, uint32_t size)
+{
+	struct drm_device *dev = crtc->dev;
+	struct drm_mode_config *config = &dev->mode_config;
+	struct drm_atomic_state *state;
+	struct drm_crtc_state *crtc_state;
+	struct drm_property_blob *blob = NULL;
+	struct drm_color_lut *blob_data;
+	int i, ret = 0;
+
+	state = drm_atomic_state_alloc(crtc->dev);
+	if (!state)
+		return;
+
+	blob = drm_property_create_blob(dev,
+					sizeof(struct drm_color_lut) * size,
+					NULL);
+	if (IS_ERR(blob)) {
+		ret = PTR_ERR(blob);
+		blob = NULL;
+		goto fail;
+	}
+
+	/* Prepare GAMMA_LUT with the legacy values. */
+	blob_data = (struct drm_color_lut *) blob->data;
+	for (i = 0; i < size; i++) {
+		blob_data[i].red = red[i];
+		blob_data[i].green = green[i];
+		blob_data[i].blue = blue[i];
+	}
+
+	state->acquire_ctx = crtc->dev->mode_config.acquire_ctx;
+retry:
+	crtc_state = drm_atomic_get_crtc_state(state, crtc);
+	if (IS_ERR(crtc_state)) {
+		ret = PTR_ERR(crtc_state);
+		goto fail;
+	}
+
+	/* Reset DEGAMMA_LUT and CTM properties. */
+	ret = drm_atomic_crtc_set_property(crtc, crtc_state,
+			config->degamma_lut_property, 0);
+	if (ret)
+		goto fail;
+
+	ret = drm_atomic_crtc_set_property(crtc, crtc_state,
+			config->ctm_property, 0);
+	if (ret)
+		goto fail;
+
+	ret = drm_atomic_crtc_set_property(crtc, crtc_state,
+			config->gamma_lut_property, blob->base.id);
+	if (ret)
+		goto fail;
+
+	ret = drm_atomic_commit(state);
+	if (ret)
+		goto fail;
+
+	/* Driver takes ownership of state on successful commit. */
+
+	drm_property_unreference_blob(blob);
+
+	return;
+fail:
+	if (ret == -EDEADLK)
+		goto backoff;
+
+	drm_atomic_state_free(state);
+	drm_property_unreference_blob(blob);
+
+	return;
+backoff:
+	drm_atomic_state_clear(state);
+	drm_atomic_legacy_backoff(state);
+
+	goto retry;
+}
+EXPORT_SYMBOL(drm_atomic_helper_legacy_gamma_set);
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/drm_cache.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/drm_cache.c
@@ -136,6 +136,7 @@ drm_clflush_virt_range(void *addr, unsig
 		mb();
 		for (; addr < end; addr += size)
 			clflushopt(addr);
+		clflushopt(end - 1); /* force serialisation */
 		mb();
 		return;
 	}
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/drm_crtc.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/drm_crtc.c
@@ -1121,6 +1121,29 @@ out_unlock:
 EXPORT_SYMBOL(drm_encoder_init);
 
 /**
+ * drm_encoder_index - find the index of a registered encoder
+ * @encoder: encoder to find index for
+ *
+ * Given a registered encoder, return the index of that encoder within a DRM
+ * device's list of encoders.
+ */
+unsigned int drm_encoder_index(struct drm_encoder *encoder)
+{
+	unsigned int index = 0;
+	struct drm_encoder *tmp;
+
+	drm_for_each_encoder(tmp, encoder->dev) {
+		if (tmp == encoder)
+			return index;
+
+		index++;
+	}
+
+	BUG();
+}
+EXPORT_SYMBOL(drm_encoder_index);
+
+/**
  * drm_encoder_cleanup - cleans up an initialised encoder
  * @encoder: encoder to cleanup
  *
@@ -1470,6 +1493,41 @@ static int drm_mode_create_standard_prop
 		return -ENOMEM;
 	dev->mode_config.prop_mode_id = prop;
 
+	prop = drm_property_create(dev,
+			DRM_MODE_PROP_BLOB,
+			"DEGAMMA_LUT", 0);
+	if (!prop)
+		return -ENOMEM;
+	dev->mode_config.degamma_lut_property = prop;
+
+	prop = drm_property_create_range(dev,
+			DRM_MODE_PROP_IMMUTABLE,
+			"DEGAMMA_LUT_SIZE", 0, UINT_MAX);
+	if (!prop)
+		return -ENOMEM;
+	dev->mode_config.degamma_lut_size_property = prop;
+
+	prop = drm_property_create(dev,
+			DRM_MODE_PROP_BLOB,
+			"CTM", 0);
+	if (!prop)
+		return -ENOMEM;
+	dev->mode_config.ctm_property = prop;
+
+	prop = drm_property_create(dev,
+			DRM_MODE_PROP_BLOB,
+			"GAMMA_LUT", 0);
+	if (!prop)
+		return -ENOMEM;
+	dev->mode_config.gamma_lut_property = prop;
+
+	prop = drm_property_create_range(dev,
+			DRM_MODE_PROP_IMMUTABLE,
+			"GAMMA_LUT_SIZE", 0, UINT_MAX);
+	if (!prop)
+		return -ENOMEM;
+	dev->mode_config.gamma_lut_size_property = prop;
+
 	return 0;
 }
 
@@ -2682,8 +2740,6 @@ int drm_mode_setcrtc(struct drm_device *
 			goto out;
 		}
 
-		drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V);
-
 		/*
 		 * Check whether the primary plane supports the fb pixel format.
 		 * Drivers not implementing the universal planes API use a
@@ -3316,6 +3372,24 @@ int drm_mode_addfb2(struct drm_device *d
 	return 0;
 }
 
+struct drm_mode_rmfb_work {
+	struct work_struct work;
+	struct list_head fbs;
+};
+
+static void drm_mode_rmfb_work_fn(struct work_struct *w)
+{
+	struct drm_mode_rmfb_work *arg = container_of(w, typeof(*arg), work);
+
+	while (!list_empty(&arg->fbs)) {
+		struct drm_framebuffer *fb =
+			list_first_entry(&arg->fbs, typeof(*fb), filp_head);
+
+		list_del_init(&fb->filp_head);
+		drm_framebuffer_remove(fb);
+	}
+}
+
 /**
  * drm_mode_rmfb - remove an FB from the configuration
  * @dev: drm device for the ioctl
@@ -3356,7 +3430,25 @@ int drm_mode_rmfb(struct drm_device *dev
 	mutex_unlock(&dev->mode_config.fb_lock);
 	mutex_unlock(&file_priv->fbs_lock);
 
-	drm_framebuffer_unreference(fb);
+	/*
+	 * we now own the reference that was stored in the fbs list
+	 *
+	 * drm_framebuffer_remove may fail with -EINTR on pending signals,
+	 * so run this in a separate stack as there's no way to correctly
+	 * handle this after the fb is already removed from the lookup table.
+	 */
+	if (atomic_read(&fb->refcount.refcount) > 1) {
+		struct drm_mode_rmfb_work arg;
+
+		INIT_WORK_ONSTACK(&arg.work, drm_mode_rmfb_work_fn);
+		INIT_LIST_HEAD(&arg.fbs);
+		list_add_tail(&fb->filp_head, &arg.fbs);
+
+		schedule_work(&arg.work);
+		flush_work(&arg.work);
+		destroy_work_on_stack(&arg.work);
+	} else
+		drm_framebuffer_unreference(fb);
 
 	return 0;
 
@@ -3509,7 +3601,6 @@ out_err1:
 	return ret;
 }
 
-
 /**
  * drm_fb_release - remove and free the FBs on this file
  * @priv: drm file for the ioctl
@@ -3524,6 +3615,9 @@ out_err1:
 void drm_fb_release(struct drm_file *priv)
 {
 	struct drm_framebuffer *fb, *tfb;
+	struct drm_mode_rmfb_work arg;
+
+	INIT_LIST_HEAD(&arg.fbs);
 
 	/*
 	 * When the file gets released that means no one else can access the fb
@@ -3536,10 +3630,22 @@ void drm_fb_release(struct drm_file *pri
 	 * at it any more.
 	 */
 	list_for_each_entry_safe(fb, tfb, &priv->fbs, filp_head) {
-		list_del_init(&fb->filp_head);
+		if (atomic_read(&fb->refcount.refcount) > 1) {
+			list_move_tail(&fb->filp_head, &arg.fbs);
+		} else {
+			list_del_init(&fb->filp_head);
 
-		/* This drops the fpriv->fbs reference. */
-		drm_framebuffer_unreference(fb);
+			/* This drops the fpriv->fbs reference. */
+			drm_framebuffer_unreference(fb);
+		}
+	}
+
+	if (!list_empty(&arg.fbs)) {
+		INIT_WORK_ONSTACK(&arg.work, drm_mode_rmfb_work_fn);
+
+		schedule_work(&arg.work);
+		flush_work(&arg.work);
+		destroy_work_on_stack(&arg.work);
 	}
 }
 
@@ -5183,6 +5289,9 @@ int drm_mode_page_flip_ioctl(struct drm_
 	unsigned long flags;
 	int ret = -EINVAL;
 
+	if (!drm_core_check_feature(dev, DRIVER_MODESET))
+		return -EINVAL;
+
 	if (page_flip->flags & ~DRM_MODE_PAGE_FLIP_FLAGS ||
 	    page_flip->reserved != 0)
 		return -EINVAL;
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/drm_crtc_helper.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/drm_crtc_helper.c
@@ -63,9 +63,6 @@
  * but need to implement the atomic interface instead, potentially using the
  * atomic helpers for that.
  */
-MODULE_AUTHOR("David Airlie, Jesse Barnes");
-MODULE_DESCRIPTION("DRM KMS helper");
-MODULE_LICENSE("GPL and additional rights");
 
 /**
  * drm_helper_move_panel_connectors_to_head() - move panels to the front in the
@@ -855,6 +852,12 @@ EXPORT_SYMBOL(drm_helper_mode_fill_fb_st
  * due to slight differences in allocating shared resources when the
  * configuration is restored in a different order than when userspace set it up)
  * need to use their own restore logic.
+ *
+ * This function is deprecated. New drivers should implement atomic mode-
+ * setting and use the atomic suspend/resume helpers.
+ *
+ * See also:
+ * drm_atomic_helper_suspend(), drm_atomic_helper_resume()
  */
 void drm_helper_resume_force_mode(struct drm_device *dev)
 {
@@ -1015,3 +1018,36 @@ int drm_helper_crtc_mode_set_base(struct
 	return drm_plane_helper_commit(plane, plane_state, old_fb);
 }
 EXPORT_SYMBOL(drm_helper_crtc_mode_set_base);
+
+/**
+ * drm_helper_crtc_enable_color_mgmt - enable color management properties
+ * @crtc: DRM CRTC
+ * @degamma_lut_size: the size of the degamma lut (before CSC)
+ * @gamma_lut_size: the size of the gamma lut (after CSC)
+ *
+ * This function lets the driver enable the color correction properties on a
+ * CRTC. This includes 3 degamma, csc and gamma properties that userspace can
+ * set and 2 size properties to inform the userspace of the lut sizes.
+ */
+void drm_helper_crtc_enable_color_mgmt(struct drm_crtc *crtc,
+				       int degamma_lut_size,
+				       int gamma_lut_size)
+{
+	struct drm_device *dev = crtc->dev;
+	struct drm_mode_config *config = &dev->mode_config;
+
+	drm_object_attach_property(&crtc->base,
+				   config->degamma_lut_property, 0);
+	drm_object_attach_property(&crtc->base,
+				   config->ctm_property, 0);
+	drm_object_attach_property(&crtc->base,
+				   config->gamma_lut_property, 0);
+
+	drm_object_attach_property(&crtc->base,
+				   config->degamma_lut_size_property,
+				   degamma_lut_size);
+	drm_object_attach_property(&crtc->base,
+				   config->gamma_lut_size_property,
+				   gamma_lut_size);
+}
+EXPORT_SYMBOL(drm_helper_crtc_enable_color_mgmt);
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/drm_dp_aux_dev.c
@@ -0,0 +1,380 @@
+/*
+ * Copyright © 2015 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Rafael Antognolli <rafael.antognolli@intel.com>
+ *
+ */
+
+#include <linux/device.h>
+#include <linux/fs.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/uaccess.h>
+#include <drm/drm_dp_helper.h>
+#include <drm/drm_crtc.h>
+#include <drm/drmP.h>
+
+struct drm_dp_aux_dev {
+	unsigned index;
+	struct drm_dp_aux *aux;
+	struct device *dev;
+	struct kref refcount;
+	atomic_t usecount;
+};
+
+#define DRM_AUX_MINORS	256
+#define AUX_MAX_OFFSET	(1 << 20)
+static DEFINE_IDR(aux_idr);
+static DEFINE_MUTEX(aux_idr_mutex);
+static struct class *drm_dp_aux_dev_class;
+static int drm_dev_major = -1;
+
+static struct drm_dp_aux_dev *drm_dp_aux_dev_get_by_minor(unsigned index)
+{
+	struct drm_dp_aux_dev *aux_dev = NULL;
+
+	mutex_lock(&aux_idr_mutex);
+	aux_dev = idr_find(&aux_idr, index);
+	if (!kref_get_unless_zero(&aux_dev->refcount))
+		aux_dev = NULL;
+	mutex_unlock(&aux_idr_mutex);
+
+	return aux_dev;
+}
+
+static struct drm_dp_aux_dev *alloc_drm_dp_aux_dev(struct drm_dp_aux *aux)
+{
+	struct drm_dp_aux_dev *aux_dev;
+	int index;
+
+	aux_dev = kzalloc(sizeof(*aux_dev), GFP_KERNEL);
+	if (!aux_dev)
+		return ERR_PTR(-ENOMEM);
+	aux_dev->aux = aux;
+	atomic_set(&aux_dev->usecount, 1);
+	kref_init(&aux_dev->refcount);
+
+	mutex_lock(&aux_idr_mutex);
+	index = idr_alloc_cyclic(&aux_idr, aux_dev, 0, DRM_AUX_MINORS,
+				 GFP_KERNEL);
+	mutex_unlock(&aux_idr_mutex);
+	if (index < 0) {
+		kfree(aux_dev);
+		return ERR_PTR(index);
+	}
+	aux_dev->index = index;
+
+	return aux_dev;
+}
+
+static void release_drm_dp_aux_dev(struct kref *ref)
+{
+	struct drm_dp_aux_dev *aux_dev =
+		container_of(ref, struct drm_dp_aux_dev, refcount);
+
+	kfree(aux_dev);
+}
+
+static ssize_t name_show(struct device *dev,
+			 struct device_attribute *attr, char *buf)
+{
+	ssize_t res;
+	struct drm_dp_aux_dev *aux_dev =
+		drm_dp_aux_dev_get_by_minor(MINOR(dev->devt));
+
+	if (!aux_dev)
+		return -ENODEV;
+
+	res = sprintf(buf, "%s\n", aux_dev->aux->name);
+	kref_put(&aux_dev->refcount, release_drm_dp_aux_dev);
+
+	return res;
+}
+static DEVICE_ATTR_RO(name);
+
+static struct attribute *drm_dp_aux_attrs[] = {
+	&dev_attr_name.attr,
+	NULL,
+};
+ATTRIBUTE_GROUPS(drm_dp_aux);
+
+static int auxdev_open(struct inode *inode, struct file *file)
+{
+	unsigned int minor = iminor(inode);
+	struct drm_dp_aux_dev *aux_dev;
+
+	aux_dev = drm_dp_aux_dev_get_by_minor(minor);
+	if (!aux_dev)
+		return -ENODEV;
+
+	file->private_data = aux_dev;
+	return 0;
+}
+
+static loff_t auxdev_llseek(struct file *file, loff_t offset, int whence)
+{
+	return fixed_size_llseek(file, offset, whence, AUX_MAX_OFFSET);
+}
+
+static ssize_t auxdev_read(struct file *file, char __user *buf, size_t count,
+			   loff_t *offset)
+{
+	size_t bytes_pending, num_bytes_processed = 0;
+	struct drm_dp_aux_dev *aux_dev = file->private_data;
+	ssize_t res = 0;
+
+	if (!atomic_inc_not_zero(&aux_dev->usecount))
+		return -ENODEV;
+
+	bytes_pending = min((loff_t)count, AUX_MAX_OFFSET - (*offset));
+
+	if (!access_ok(VERIFY_WRITE, buf, bytes_pending)) {
+		res = -EFAULT;
+		goto out;
+	}
+
+	while (bytes_pending > 0) {
+		uint8_t localbuf[DP_AUX_MAX_PAYLOAD_BYTES];
+		ssize_t todo = min_t(size_t, bytes_pending, sizeof(localbuf));
+
+		if (signal_pending(current)) {
+			res = num_bytes_processed ?
+				num_bytes_processed : -ERESTARTSYS;
+			goto out;
+		}
+
+		res = drm_dp_dpcd_read(aux_dev->aux, *offset, localbuf, todo);
+		if (res <= 0) {
+			res = num_bytes_processed ? num_bytes_processed : res;
+			goto out;
+		}
+		if (__copy_to_user(buf + num_bytes_processed, localbuf, res)) {
+			res = num_bytes_processed ?
+				num_bytes_processed : -EFAULT;
+			goto out;
+		}
+		bytes_pending -= res;
+		*offset += res;
+		num_bytes_processed += res;
+		res = num_bytes_processed;
+	}
+
+out:
+	atomic_dec(&aux_dev->usecount);
+	wake_up_atomic_t(&aux_dev->usecount);
+	return res;
+}
+
+static ssize_t auxdev_write(struct file *file, const char __user *buf,
+			    size_t count, loff_t *offset)
+{
+	size_t bytes_pending, num_bytes_processed = 0;
+	struct drm_dp_aux_dev *aux_dev = file->private_data;
+	ssize_t res = 0;
+
+	if (!atomic_inc_not_zero(&aux_dev->usecount))
+		return -ENODEV;
+
+	bytes_pending = min((loff_t)count, AUX_MAX_OFFSET - *offset);
+
+	if (!access_ok(VERIFY_READ, buf, bytes_pending)) {
+		res = -EFAULT;
+		goto out;
+	}
+
+	while (bytes_pending > 0) {
+		uint8_t localbuf[DP_AUX_MAX_PAYLOAD_BYTES];
+		ssize_t todo = min_t(size_t, bytes_pending, sizeof(localbuf));
+
+		if (signal_pending(current)) {
+			res = num_bytes_processed ?
+				num_bytes_processed : -ERESTARTSYS;
+			goto out;
+		}
+
+		if (__copy_from_user(localbuf,
+				     buf + num_bytes_processed, todo)) {
+			res = num_bytes_processed ?
+				num_bytes_processed : -EFAULT;
+			goto out;
+		}
+
+		res = drm_dp_dpcd_write(aux_dev->aux, *offset, localbuf, todo);
+		if (res <= 0) {
+			res = num_bytes_processed ? num_bytes_processed : res;
+			goto out;
+		}
+		bytes_pending -= res;
+		*offset += res;
+		num_bytes_processed += res;
+		res = num_bytes_processed;
+	}
+
+out:
+	atomic_dec(&aux_dev->usecount);
+	wake_up_atomic_t(&aux_dev->usecount);
+	return res;
+}
+
+static int auxdev_release(struct inode *inode, struct file *file)
+{
+	struct drm_dp_aux_dev *aux_dev = file->private_data;
+
+	kref_put(&aux_dev->refcount, release_drm_dp_aux_dev);
+	return 0;
+}
+
+static const struct file_operations auxdev_fops = {
+	.owner		= THIS_MODULE,
+	.llseek		= auxdev_llseek,
+	.read		= auxdev_read,
+	.write		= auxdev_write,
+	.open		= auxdev_open,
+	.release	= auxdev_release,
+};
+
+#define to_auxdev(d) container_of(d, struct drm_dp_aux_dev, aux)
+
+static struct drm_dp_aux_dev *drm_dp_aux_dev_get_by_aux(struct drm_dp_aux *aux)
+{
+	struct drm_dp_aux_dev *iter, *aux_dev = NULL;
+	int id;
+
+	/* don't increase kref count here because this function should only be
+	 * used by drm_dp_aux_unregister_devnode. Thus, it will always have at
+	 * least one reference - the one that drm_dp_aux_register_devnode
+	 * created
+	 */
+	mutex_lock(&aux_idr_mutex);
+	idr_for_each_entry(&aux_idr, iter, id) {
+		if (iter->aux == aux) {
+			aux_dev = iter;
+			break;
+		}
+	}
+	mutex_unlock(&aux_idr_mutex);
+	return aux_dev;
+}
+
+static int auxdev_wait_atomic_t(atomic_t *p)
+{
+	schedule();
+	return 0;
+}
+/**
+ * drm_dp_aux_unregister_devnode() - unregister a devnode for this aux channel
+ * @aux: DisplayPort AUX channel
+ *
+ * Returns 0 on success or a negative error code on failure.
+ */
+void drm_dp_aux_unregister_devnode(struct drm_dp_aux *aux)
+{
+	struct drm_dp_aux_dev *aux_dev;
+	unsigned int minor;
+
+	aux_dev = drm_dp_aux_dev_get_by_aux(aux);
+	if (!aux_dev) /* attach must have failed */
+		return;
+
+	mutex_lock(&aux_idr_mutex);
+	idr_remove(&aux_idr, aux_dev->index);
+	mutex_unlock(&aux_idr_mutex);
+
+	atomic_dec(&aux_dev->usecount);
+	wait_on_atomic_t(&aux_dev->usecount, auxdev_wait_atomic_t,
+			 TASK_UNINTERRUPTIBLE);
+
+	minor = aux_dev->index;
+	if (aux_dev->dev)
+		device_destroy(drm_dp_aux_dev_class,
+			       MKDEV(drm_dev_major, minor));
+
+	DRM_DEBUG("drm_dp_aux_dev: aux [%s] unregistering\n", aux->name);
+	kref_put(&aux_dev->refcount, release_drm_dp_aux_dev);
+}
+EXPORT_SYMBOL(drm_dp_aux_unregister_devnode);
+
+/**
+ * drm_dp_aux_register_devnode() - register a devnode for this aux channel
+ * @aux: DisplayPort AUX channel
+ *
+ * Returns 0 on success or a negative error code on failure.
+ */
+int drm_dp_aux_register_devnode(struct drm_dp_aux *aux)
+{
+	struct drm_dp_aux_dev *aux_dev;
+	int res;
+
+	aux_dev = alloc_drm_dp_aux_dev(aux);
+	if (IS_ERR(aux_dev))
+		return PTR_ERR(aux_dev);
+
+	aux_dev->dev = device_create(drm_dp_aux_dev_class, aux->dev,
+				     MKDEV(drm_dev_major, aux_dev->index), NULL,
+				     "drm_dp_aux%d", aux_dev->index);
+	if (IS_ERR(aux_dev->dev)) {
+		res = PTR_ERR(aux_dev->dev);
+		aux_dev->dev = NULL;
+		goto error;
+	}
+
+	DRM_DEBUG("drm_dp_aux_dev: aux [%s] registered as minor %d\n",
+		  aux->name, aux_dev->index);
+	return 0;
+error:
+	drm_dp_aux_unregister_devnode(aux);
+	return res;
+}
+EXPORT_SYMBOL(drm_dp_aux_register_devnode);
+
+int drm_dp_aux_dev_init(void)
+{
+	int res;
+
+	drm_dp_aux_dev_class = class_create(THIS_MODULE, "drm_dp_aux_dev");
+	if (IS_ERR(drm_dp_aux_dev_class)) {
+		res = PTR_ERR(drm_dp_aux_dev_class);
+		goto out;
+	}
+	drm_dp_aux_dev_class->dev_groups = drm_dp_aux_groups;
+
+	res = register_chrdev(0, "aux", &auxdev_fops);
+	if (res < 0)
+		goto out;
+	drm_dev_major = res;
+
+	return 0;
+out:
+	class_destroy(drm_dp_aux_dev_class);
+	return res;
+}
+EXPORT_SYMBOL(drm_dp_aux_dev_init);
+
+void drm_dp_aux_dev_exit(void)
+{
+	unregister_chrdev(drm_dev_major, "aux");
+	class_destroy(drm_dp_aux_dev_class);
+}
+EXPORT_SYMBOL(drm_dp_aux_dev_exit);
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/drm_dp_dual_mode_helper.c
@@ -0,0 +1,366 @@
+/*
+ * Copyright © 2016 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include <linux/errno.h>
+#include <linux/export.h>
+#include <linux/i2c.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <drm/drm_dp_dual_mode_helper.h>
+#include <drm/drmP.h>
+
+/**
+ * DOC: dp dual mode helpers
+ *
+ * Helper functions to deal with DP dual mode (aka. DP++) adaptors.
+ *
+ * Type 1:
+ * Adaptor registers (if any) and the sink DDC bus may be accessed via I2C.
+ *
+ * Type 2:
+ * Adaptor registers and sink DDC bus can be accessed either via I2C or
+ * I2C-over-AUX. Source devices may choose to implement either of these
+ * access methods.
+ */
+
+#define DP_DUAL_MODE_SLAVE_ADDRESS 0x40
+
+/**
+ * drm_dp_dual_mode_read - Read from the DP dual mode adaptor register(s)
+ * @adapter: I2C adapter for the DDC bus
+ * @offset: register offset
+ * @buffer: buffer for return data
+ * @size: sizo of the buffer
+ *
+ * Reads @size bytes from the DP dual mode adaptor registers
+ * starting at @offset.
+ *
+ * Returns:
+ * 0 on success, negative error code on failure
+ */
+ssize_t drm_dp_dual_mode_read(struct i2c_adapter *adapter,
+			      u8 offset, void *buffer, size_t size)
+{
+	struct i2c_msg msgs[] = {
+		{
+			.addr = DP_DUAL_MODE_SLAVE_ADDRESS,
+			.flags = 0,
+			.len = 1,
+			.buf = &offset,
+		},
+		{
+			.addr = DP_DUAL_MODE_SLAVE_ADDRESS,
+			.flags = I2C_M_RD,
+			.len = size,
+			.buf = buffer,
+		},
+	};
+	int ret;
+
+	ret = i2c_transfer(adapter, msgs, ARRAY_SIZE(msgs));
+	if (ret < 0)
+		return ret;
+	if (ret != ARRAY_SIZE(msgs))
+		return -EPROTO;
+
+	return 0;
+}
+EXPORT_SYMBOL(drm_dp_dual_mode_read);
+
+/**
+ * drm_dp_dual_mode_write - Write to the DP dual mode adaptor register(s)
+ * @adapter: I2C adapter for the DDC bus
+ * @offset: register offset
+ * @buffer: buffer for write data
+ * @size: sizo of the buffer
+ *
+ * Writes @size bytes to the DP dual mode adaptor registers
+ * starting at @offset.
+ *
+ * Returns:
+ * 0 on success, negative error code on failure
+ */
+ssize_t drm_dp_dual_mode_write(struct i2c_adapter *adapter,
+			       u8 offset, const void *buffer, size_t size)
+{
+	struct i2c_msg msg = {
+		.addr = DP_DUAL_MODE_SLAVE_ADDRESS,
+		.flags = 0,
+		.len = 1 + size,
+		.buf = NULL,
+	};
+	void *data;
+	int ret;
+
+	data = kmalloc(msg.len, GFP_TEMPORARY);
+	if (!data)
+		return -ENOMEM;
+
+	msg.buf = data;
+
+	memcpy(data, &offset, 1);
+	memcpy(data + 1, buffer, size);
+
+	ret = i2c_transfer(adapter, &msg, 1);
+
+	kfree(data);
+
+	if (ret < 0)
+		return ret;
+	if (ret != 1)
+		return -EPROTO;
+
+	return 0;
+}
+EXPORT_SYMBOL(drm_dp_dual_mode_write);
+
+static bool is_hdmi_adaptor(const char hdmi_id[DP_DUAL_MODE_HDMI_ID_LEN])
+{
+	static const char dp_dual_mode_hdmi_id[DP_DUAL_MODE_HDMI_ID_LEN] =
+		"DP-HDMI ADAPTOR\x04";
+
+	return memcmp(hdmi_id, dp_dual_mode_hdmi_id,
+		      sizeof(dp_dual_mode_hdmi_id)) == 0;
+}
+
+static bool is_type2_adaptor(uint8_t adaptor_id)
+{
+	return adaptor_id == (DP_DUAL_MODE_TYPE_TYPE2 |
+			      DP_DUAL_MODE_REV_TYPE2);
+}
+
+/**
+ * drm_dp_dual_mode_detect - Identify the DP dual mode adaptor
+ * @adapter: I2C adapter for the DDC bus
+ *
+ * Attempt to identify the type of the DP dual mode adaptor used.
+ *
+ * Note that when the answer is @DRM_DP_DUAL_MODE_UNKNOWN it's not
+ * certain whether we're dealing with a native HDMI port or
+ * a type 1 DVI dual mode adaptor. The driver will have to use
+ * some other hardware/driver specific mechanism to make that
+ * distinction.
+ *
+ * Returns:
+ * The type of the DP dual mode adaptor used
+ */
+enum drm_dp_dual_mode_type drm_dp_dual_mode_detect(struct i2c_adapter *adapter)
+{
+	char hdmi_id[DP_DUAL_MODE_HDMI_ID_LEN] = {};
+	uint8_t adaptor_id = 0x00;
+	ssize_t ret;
+
+	/*
+	 * Let's see if the adaptor is there the by reading the
+	 * HDMI ID registers.
+	 *
+	 * Note that type 1 DVI adaptors are not required to implemnt
+	 * any registers, and that presents a problem for detection.
+	 * If the i2c transfer is nacked, we may or may not be dealing
+	 * with a type 1 DVI adaptor. Some other mechanism of detecting
+	 * the presence of the adaptor is required. One way would be
+	 * to check the state of the CONFIG1 pin, Another method would
+	 * simply require the driver to know whether the port is a DP++
+	 * port or a native HDMI port. Both of these methods are entirely
+	 * hardware/driver specific so we can't deal with them here.
+	 */
+	ret = drm_dp_dual_mode_read(adapter, DP_DUAL_MODE_HDMI_ID,
+				    hdmi_id, sizeof(hdmi_id));
+	if (ret)
+		return DRM_DP_DUAL_MODE_UNKNOWN;
+
+	/*
+	 * Sigh. Some (maybe all?) type 1 adaptors are broken and ack
+	 * the offset but ignore it, and instead they just always return
+	 * data from the start of the HDMI ID buffer. So for a broken
+	 * type 1 HDMI adaptor a single byte read will always give us
+	 * 0x44, and for a type 1 DVI adaptor it should give 0x00
+	 * (assuming it implements any registers). Fortunately neither
+	 * of those values will match the type 2 signature of the
+	 * DP_DUAL_MODE_ADAPTOR_ID register so we can proceed with
+	 * the type 2 adaptor detection safely even in the presence
+	 * of broken type 1 adaptors.
+	 */
+	ret = drm_dp_dual_mode_read(adapter, DP_DUAL_MODE_ADAPTOR_ID,
+				    &adaptor_id, sizeof(adaptor_id));
+	if (ret == 0) {
+		if (is_type2_adaptor(adaptor_id)) {
+			if (is_hdmi_adaptor(hdmi_id))
+				return DRM_DP_DUAL_MODE_TYPE2_HDMI;
+			else
+				return DRM_DP_DUAL_MODE_TYPE2_DVI;
+		}
+	}
+
+	if (is_hdmi_adaptor(hdmi_id))
+		return DRM_DP_DUAL_MODE_TYPE1_HDMI;
+	else
+		return DRM_DP_DUAL_MODE_TYPE1_DVI;
+}
+EXPORT_SYMBOL(drm_dp_dual_mode_detect);
+
+/**
+ * drm_dp_dual_mode_max_tmds_clock - Max TMDS clock for DP dual mode adaptor
+ * @type: DP dual mode adaptor type
+ * @adapter: I2C adapter for the DDC bus
+ *
+ * Determine the max TMDS clock the adaptor supports based on the
+ * type of the dual mode adaptor and the DP_DUAL_MODE_MAX_TMDS_CLOCK
+ * register (on type2 adaptors). As some type 1 adaptors have
+ * problems with registers (see comments in drm_dp_dual_mode_detect())
+ * we don't read the register on those, instead we simply assume
+ * a 165 MHz limit based on the specification.
+ *
+ * Returns:
+ * Maximum supported TMDS clock rate for the DP dual mode adaptor in kHz.
+ */
+int drm_dp_dual_mode_max_tmds_clock(enum drm_dp_dual_mode_type type,
+				    struct i2c_adapter *adapter)
+{
+	uint8_t max_tmds_clock;
+	ssize_t ret;
+
+	/* native HDMI so no limit */
+	if (type == DRM_DP_DUAL_MODE_NONE)
+		return 0;
+
+	/*
+	 * Type 1 adaptors are limited to 165MHz
+	 * Type 2 adaptors can tells us their limit
+	 */
+	if (type < DRM_DP_DUAL_MODE_TYPE2_DVI)
+		return 165000;
+
+	ret = drm_dp_dual_mode_read(adapter, DP_DUAL_MODE_MAX_TMDS_CLOCK,
+				    &max_tmds_clock, sizeof(max_tmds_clock));
+	if (ret || max_tmds_clock == 0x00 || max_tmds_clock == 0xff) {
+		DRM_DEBUG_KMS("Failed to query max TMDS clock\n");
+		return 165000;
+	}
+
+	return max_tmds_clock * 5000 / 2;
+}
+EXPORT_SYMBOL(drm_dp_dual_mode_max_tmds_clock);
+
+/**
+ * drm_dp_dual_mode_get_tmds_output - Get the state of the TMDS output buffers in the DP dual mode adaptor
+ * @type: DP dual mode adaptor type
+ * @adapter: I2C adapter for the DDC bus
+ * @enabled: current state of the TMDS output buffers
+ *
+ * Get the state of the TMDS output buffers in the adaptor. For
+ * type2 adaptors this is queried from the DP_DUAL_MODE_TMDS_OEN
+ * register. As some type 1 adaptors have problems with registers
+ * (see comments in drm_dp_dual_mode_detect()) we don't read the
+ * register on those, instead we simply assume that the buffers
+ * are always enabled.
+ *
+ * Returns:
+ * 0 on success, negative error code on failure
+ */
+int drm_dp_dual_mode_get_tmds_output(enum drm_dp_dual_mode_type type,
+				     struct i2c_adapter *adapter,
+				     bool *enabled)
+{
+	uint8_t tmds_oen;
+	ssize_t ret;
+
+	if (type < DRM_DP_DUAL_MODE_TYPE2_DVI) {
+		*enabled = true;
+		return 0;
+	}
+
+	ret = drm_dp_dual_mode_read(adapter, DP_DUAL_MODE_TMDS_OEN,
+				    &tmds_oen, sizeof(tmds_oen));
+	if (ret) {
+		DRM_DEBUG_KMS("Failed to query state of TMDS output buffers\n");
+		return ret;
+	}
+
+	*enabled = !(tmds_oen & DP_DUAL_MODE_TMDS_DISABLE);
+
+	return 0;
+}
+EXPORT_SYMBOL(drm_dp_dual_mode_get_tmds_output);
+
+/**
+ * drm_dp_dual_mode_set_tmds_output - Enable/disable TMDS output buffers in the DP dual mode adaptor
+ * @type: DP dual mode adaptor type
+ * @adapter: I2C adapter for the DDC bus
+ * @enable: enable (as opposed to disable) the TMDS output buffers
+ *
+ * Set the state of the TMDS output buffers in the adaptor. For
+ * type2 this is set via the DP_DUAL_MODE_TMDS_OEN register. As
+ * some type 1 adaptors have problems with registers (see comments
+ * in drm_dp_dual_mode_detect()) we avoid touching the register,
+ * making this function a no-op on type 1 adaptors.
+ *
+ * Returns:
+ * 0 on success, negative error code on failure
+ */
+int drm_dp_dual_mode_set_tmds_output(enum drm_dp_dual_mode_type type,
+				     struct i2c_adapter *adapter, bool enable)
+{
+	uint8_t tmds_oen = enable ? 0 : DP_DUAL_MODE_TMDS_DISABLE;
+	ssize_t ret;
+
+	if (type < DRM_DP_DUAL_MODE_TYPE2_DVI)
+		return 0;
+
+	ret = drm_dp_dual_mode_write(adapter, DP_DUAL_MODE_TMDS_OEN,
+				     &tmds_oen, sizeof(tmds_oen));
+	if (ret) {
+		DRM_DEBUG_KMS("Failed to %s TMDS output buffers\n",
+			      enable ? "enable" : "disable");
+		return ret;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL(drm_dp_dual_mode_set_tmds_output);
+
+/**
+ * drm_dp_get_dual_mode_type_name - Get the name of the DP dual mode adaptor type as a string
+ * @type: DP dual mode adaptor type
+ *
+ * Returns:
+ * String representation of the DP dual mode adaptor type
+ */
+const char *drm_dp_get_dual_mode_type_name(enum drm_dp_dual_mode_type type)
+{
+	switch (type) {
+	case DRM_DP_DUAL_MODE_NONE:
+		return "none";
+	case DRM_DP_DUAL_MODE_TYPE1_DVI:
+		return "type 1 DVI";
+	case DRM_DP_DUAL_MODE_TYPE1_HDMI:
+		return "type 1 HDMI";
+	case DRM_DP_DUAL_MODE_TYPE2_DVI:
+		return "type 2 DVI";
+	case DRM_DP_DUAL_MODE_TYPE2_HDMI:
+		return "type 2 HDMI";
+	default:
+		WARN_ON(type != DRM_DP_DUAL_MODE_UNKNOWN);
+		return "unknown";
+	}
+}
+EXPORT_SYMBOL(drm_dp_get_dual_mode_type_name);
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/drm_dp_helper.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/drm_dp_helper.c
@@ -28,6 +28,7 @@
 #include <linux/sched.h>
 #include <linux/i2c.h>
 #include <drm/drm_dp_helper.h>
+#include <drm/drm_dp_aux_dev.h>
 #include <drm/drmP.h>
 
 /**
@@ -178,7 +179,7 @@ static int drm_dp_dpcd_access(struct drm
 {
 	struct drm_dp_aux_msg msg;
 	unsigned int retry;
-	int err;
+	int err = 0;
 
 	memset(&msg, 0, sizeof(msg));
 	msg.address = offset;
@@ -186,6 +187,8 @@ static int drm_dp_dpcd_access(struct drm
 	msg.buffer = buffer;
 	msg.size = size;
 
+	mutex_lock(&aux->hw_mutex);
+
 	/*
 	 * The specification doesn't give any recommendation on how often to
 	 * retry native transactions. We used to retry 7 times like for
@@ -194,25 +197,24 @@ static int drm_dp_dpcd_access(struct drm
 	 */
 	for (retry = 0; retry < 32; retry++) {
 
-		mutex_lock(&aux->hw_mutex);
 		err = aux->transfer(aux, &msg);
-		mutex_unlock(&aux->hw_mutex);
 		if (err < 0) {
 			if (err == -EBUSY)
 				continue;
 
-			return err;
+			goto unlock;
 		}
 
 
 		switch (msg.reply & DP_AUX_NATIVE_REPLY_MASK) {
 		case DP_AUX_NATIVE_REPLY_ACK:
 			if (err < size)
-				return -EPROTO;
-			return err;
+				err = -EPROTO;
+			goto unlock;
 
 		case DP_AUX_NATIVE_REPLY_NACK:
-			return -EIO;
+			err = -EIO;
+			goto unlock;
 
 		case DP_AUX_NATIVE_REPLY_DEFER:
 			usleep_range(AUX_RETRY_INTERVAL, AUX_RETRY_INTERVAL + 100);
@@ -221,7 +223,11 @@ static int drm_dp_dpcd_access(struct drm
 	}
 
 	DRM_DEBUG_KMS("too many retries, giving up\n");
-	return -EIO;
+	err = -EIO;
+
+unlock:
+	mutex_unlock(&aux->hw_mutex);
+	return err;
 }
 
 /**
@@ -543,9 +549,7 @@ static int drm_dp_i2c_do_msg(struct drm_
 	int max_retries = max(7, drm_dp_i2c_retry_count(msg, dp_aux_i2c_speed_khz));
 
 	for (retry = 0, defer_i2c = 0; retry < (max_retries + defer_i2c); retry++) {
-		mutex_lock(&aux->hw_mutex);
 		ret = aux->transfer(aux, msg);
-		mutex_unlock(&aux->hw_mutex);
 		if (ret < 0) {
 			if (ret == -EBUSY)
 				continue;
@@ -684,6 +688,8 @@ static int drm_dp_i2c_xfer(struct i2c_ad
 
 	memset(&msg, 0, sizeof(msg));
 
+	mutex_lock(&aux->hw_mutex);
+
 	for (i = 0; i < num; i++) {
 		msg.address = msgs[i].addr;
 		drm_dp_i2c_msg_set_request(&msg, &msgs[i]);
@@ -738,6 +744,8 @@ static int drm_dp_i2c_xfer(struct i2c_ad
 	msg.size = 0;
 	(void)drm_dp_i2c_do_msg(aux, &msg);
 
+	mutex_unlock(&aux->hw_mutex);
+
 	return err;
 }
 
@@ -754,6 +762,8 @@ static const struct i2c_algorithm drm_dp
  */
 int drm_dp_aux_register(struct drm_dp_aux *aux)
 {
+	int ret;
+
 	mutex_init(&aux->hw_mutex);
 
 	aux->ddc.algo = &drm_dp_i2c_algo;
@@ -768,7 +778,17 @@ int drm_dp_aux_register(struct drm_dp_au
 	strlcpy(aux->ddc.name, aux->name ? aux->name : dev_name(aux->dev),
 		sizeof(aux->ddc.name));
 
-	return i2c_add_adapter(&aux->ddc);
+	ret = drm_dp_aux_register_devnode(aux);
+	if (ret)
+		return ret;
+
+	ret = i2c_add_adapter(&aux->ddc);
+	if (ret) {
+		drm_dp_aux_unregister_devnode(aux);
+		return ret;
+	}
+
+	return 0;
 }
 EXPORT_SYMBOL(drm_dp_aux_register);
 
@@ -778,6 +798,7 @@ EXPORT_SYMBOL(drm_dp_aux_register);
  */
 void drm_dp_aux_unregister(struct drm_dp_aux *aux)
 {
+	drm_dp_aux_unregister_devnode(aux);
 	i2c_del_adapter(&aux->ddc);
 }
 EXPORT_SYMBOL(drm_dp_aux_unregister);
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/drm_dp_mst_topology.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/drm_dp_mst_topology.c
@@ -666,7 +666,9 @@ static int build_enum_path_resources(str
 }
 
 static int build_allocate_payload(struct drm_dp_sideband_msg_tx *msg, int port_num,
-				  u8 vcpi, uint16_t pbn)
+				  u8 vcpi, uint16_t pbn,
+				  u8 number_sdp_streams,
+				  u8 *sdp_stream_sink)
 {
 	struct drm_dp_sideband_msg_req_body req;
 	memset(&req, 0, sizeof(req));
@@ -674,6 +676,9 @@ static int build_allocate_payload(struct
 	req.u.allocate_payload.port_number = port_num;
 	req.u.allocate_payload.vcpi = vcpi;
 	req.u.allocate_payload.pbn = pbn;
+	req.u.allocate_payload.number_sdp_streams = number_sdp_streams;
+	memcpy(req.u.allocate_payload.sdp_stream_sink, sdp_stream_sink,
+		   number_sdp_streams);
 	drm_dp_encode_sideband_req(&req, msg);
 	msg->path_msg = true;
 	return 0;
@@ -798,6 +803,18 @@ static struct drm_dp_mst_branch *drm_dp_
 	return mstb;
 }
 
+static void drm_dp_free_mst_port(struct kref *kref);
+
+static void drm_dp_free_mst_branch_device(struct kref *kref)
+{
+	struct drm_dp_mst_branch *mstb = container_of(kref, struct drm_dp_mst_branch, kref);
+	if (mstb->port_parent) {
+		if (list_empty(&mstb->port_parent->next))
+			kref_put(&mstb->port_parent->kref, drm_dp_free_mst_port);
+	}
+	kfree(mstb);
+}
+
 static void drm_dp_destroy_mst_branch_device(struct kref *kref)
 {
 	struct drm_dp_mst_branch *mstb = container_of(kref, struct drm_dp_mst_branch, kref);
@@ -805,6 +822,15 @@ static void drm_dp_destroy_mst_branch_de
 	bool wake_tx = false;
 
 	/*
+	 * init kref again to be used by ports to remove mst branch when it is
+	 * not needed anymore
+	 */
+	kref_init(kref);
+
+	if (mstb->port_parent && list_empty(&mstb->port_parent->next))
+		kref_get(&mstb->port_parent->kref);
+
+	/*
 	 * destroy all ports - don't need lock
 	 * as there are no more references to the mst branch
 	 * device at this point.
@@ -830,7 +856,8 @@ static void drm_dp_destroy_mst_branch_de
 
 	if (wake_tx)
 		wake_up(&mstb->mgr->tx_waitq);
-	kfree(mstb);
+
+	kref_put(kref, drm_dp_free_mst_branch_device);
 }
 
 static void drm_dp_put_mst_branch_device(struct drm_dp_mst_branch *mstb)
@@ -878,6 +905,7 @@ static void drm_dp_destroy_port(struct k
 			 * from an EDID retrieval */
 
 			mutex_lock(&mgr->destroy_connector_lock);
+			kref_get(&port->parent->kref);
 			list_add(&port->next, &mgr->destroy_connector_list);
 			mutex_unlock(&mgr->destroy_connector_lock);
 			schedule_work(&mgr->destroy_connector_work);
@@ -973,17 +1001,17 @@ static struct drm_dp_mst_port *drm_dp_ge
 static u8 drm_dp_calculate_rad(struct drm_dp_mst_port *port,
 				 u8 *rad)
 {
-	int lct = port->parent->lct;
+	int parent_lct = port->parent->lct;
 	int shift = 4;
-	int idx = lct / 2;
-	if (lct > 1) {
-		memcpy(rad, port->parent->rad, idx);
-		shift = (lct % 2) ? 4 : 0;
+	int idx = (parent_lct - 1) / 2;
+	if (parent_lct > 1) {
+		memcpy(rad, port->parent->rad, idx + 1);
+		shift = (parent_lct % 2) ? 4 : 0;
 	} else
 		rad[0] = 0;
 
 	rad[idx] |= port->port_num << shift;
-	return lct + 1;
+	return parent_lct + 1;
 }
 
 /*
@@ -1013,18 +1041,27 @@ static bool drm_dp_port_setup_pdt(struct
 	return send_link;
 }
 
-static void drm_dp_check_port_guid(struct drm_dp_mst_branch *mstb,
-				   struct drm_dp_mst_port *port)
+static void drm_dp_check_mstb_guid(struct drm_dp_mst_branch *mstb, u8 *guid)
 {
 	int ret;
-	if (port->dpcd_rev >= 0x12) {
-		port->guid_valid = drm_dp_validate_guid(mstb->mgr, port->guid);
-		if (!port->guid_valid) {
-			ret = drm_dp_send_dpcd_write(mstb->mgr,
-						     port,
-						     DP_GUID,
-						     16, port->guid);
-			port->guid_valid = true;
+
+	memcpy(mstb->guid, guid, 16);
+
+	if (!drm_dp_validate_guid(mstb->mgr, mstb->guid)) {
+		if (mstb->port_parent) {
+			ret = drm_dp_send_dpcd_write(
+					mstb->mgr,
+					mstb->port_parent,
+					DP_GUID,
+					16,
+					mstb->guid);
+		} else {
+
+			ret = drm_dp_dpcd_write(
+					mstb->mgr->aux,
+					DP_GUID,
+					mstb->guid,
+					16);
 		}
 	}
 }
@@ -1039,7 +1076,7 @@ static void build_mst_prop_path(const st
 	snprintf(proppath, proppath_size, "mst:%d", mstb->mgr->conn_base_id);
 	for (i = 0; i < (mstb->lct - 1); i++) {
 		int shift = (i % 2) ? 0 : 4;
-		int port_num = mstb->rad[i / 2] >> shift;
+		int port_num = (mstb->rad[i / 2] >> shift) & 0xf;
 		snprintf(temp, sizeof(temp), "-%d", port_num);
 		strlcat(proppath, temp, proppath_size);
 	}
@@ -1081,7 +1118,6 @@ static void drm_dp_add_port(struct drm_d
 	port->dpcd_rev = port_msg->dpcd_revision;
 	port->num_sdp_streams = port_msg->num_sdp_streams;
 	port->num_sdp_stream_sinks = port_msg->num_sdp_stream_sinks;
-	memcpy(port->guid, port_msg->peer_guid, 16);
 
 	/* manage mstb port lists with mgr lock - take a reference
 	   for this list */
@@ -1094,11 +1130,9 @@ static void drm_dp_add_port(struct drm_d
 
 	if (old_ddps != port->ddps) {
 		if (port->ddps) {
-			drm_dp_check_port_guid(mstb, port);
 			if (!port->input)
 				drm_dp_send_enum_path_resources(mstb->mgr, mstb, port);
 		} else {
-			port->guid_valid = false;
 			port->available_pbn = 0;
 			}
 	}
@@ -1157,10 +1191,8 @@ static void drm_dp_update_port(struct dr
 
 	if (old_ddps != port->ddps) {
 		if (port->ddps) {
-			drm_dp_check_port_guid(mstb, port);
 			dowork = true;
 		} else {
-			port->guid_valid = false;
 			port->available_pbn = 0;
 		}
 	}
@@ -1190,7 +1222,7 @@ static struct drm_dp_mst_branch *drm_dp_
 
 	for (i = 0; i < lct - 1; i++) {
 		int shift = (i % 2) ? 0 : 4;
-		int port_num = rad[i / 2] >> shift;
+		int port_num = (rad[i / 2] >> shift) & 0xf;
 
 		list_for_each_entry(port, &mstb->ports, next) {
 			if (port->port_num == port_num) {
@@ -1210,6 +1242,48 @@ out:
 	return mstb;
 }
 
+static struct drm_dp_mst_branch *get_mst_branch_device_by_guid_helper(
+	struct drm_dp_mst_branch *mstb,
+	uint8_t *guid)
+{
+	struct drm_dp_mst_branch *found_mstb;
+	struct drm_dp_mst_port *port;
+
+	if (memcmp(mstb->guid, guid, 16) == 0)
+		return mstb;
+
+
+	list_for_each_entry(port, &mstb->ports, next) {
+		if (!port->mstb)
+			continue;
+
+		found_mstb = get_mst_branch_device_by_guid_helper(port->mstb, guid);
+
+		if (found_mstb)
+			return found_mstb;
+	}
+
+	return NULL;
+}
+
+static struct drm_dp_mst_branch *drm_dp_get_mst_branch_device_by_guid(
+	struct drm_dp_mst_topology_mgr *mgr,
+	uint8_t *guid)
+{
+	struct drm_dp_mst_branch *mstb;
+
+	/* find the port by iterating down */
+	mutex_lock(&mgr->lock);
+
+	mstb = get_mst_branch_device_by_guid_helper(mgr->mst_primary, guid);
+
+	if (mstb)
+		kref_get(&mstb->kref);
+
+	mutex_unlock(&mgr->lock);
+	return mstb;
+}
+
 static void drm_dp_check_and_send_link_address(struct drm_dp_mst_topology_mgr *mgr,
 					       struct drm_dp_mst_branch *mstb)
 {
@@ -1320,6 +1394,7 @@ static int set_hdr_from_dst_qlock(struct
 				  struct drm_dp_sideband_msg_tx *txmsg)
 {
 	struct drm_dp_mst_branch *mstb = txmsg->dst;
+	u8 req_type;
 
 	/* both msg slots are full */
 	if (txmsg->seqno == -1) {
@@ -1336,7 +1411,13 @@ static int set_hdr_from_dst_qlock(struct
 			txmsg->seqno = 1;
 		mstb->tx_slots[txmsg->seqno] = txmsg;
 	}
-	hdr->broadcast = 0;
+
+	req_type = txmsg->msg[0] & 0x7f;
+	if (req_type == DP_CONNECTION_STATUS_NOTIFY ||
+		req_type == DP_RESOURCE_STATUS_NOTIFY)
+		hdr->broadcast = 1;
+	else
+		hdr->broadcast = 0;
 	hdr->path_msg = txmsg->path_msg;
 	hdr->lct = mstb->lct;
 	hdr->lcr = mstb->lct - 1;
@@ -1438,26 +1519,18 @@ static void process_single_down_tx_qlock
 }
 
 /* called holding qlock */
-static void process_single_up_tx_qlock(struct drm_dp_mst_topology_mgr *mgr)
+static void process_single_up_tx_qlock(struct drm_dp_mst_topology_mgr *mgr,
+				       struct drm_dp_sideband_msg_tx *txmsg)
 {
-	struct drm_dp_sideband_msg_tx *txmsg;
 	int ret;
 
 	/* construct a chunk from the first msg in the tx_msg queue */
-	if (list_empty(&mgr->tx_msg_upq)) {
-		mgr->tx_up_in_progress = false;
-		return;
-	}
-
-	txmsg = list_first_entry(&mgr->tx_msg_upq, struct drm_dp_sideband_msg_tx, next);
 	ret = process_single_tx_qlock(mgr, txmsg, true);
-	if (ret == 1) {
-		/* up txmsgs aren't put in slots - so free after we send it */
-		list_del(&txmsg->next);
-		kfree(txmsg);
-	} else if (ret)
+
+	if (ret != 1)
 		DRM_DEBUG_KMS("failed to send msg in q %d\n", ret);
-	mgr->tx_up_in_progress = true;
+
+	txmsg->dst->tx_slots[txmsg->seqno] = NULL;
 }
 
 static void drm_dp_queue_down_tx(struct drm_dp_mst_topology_mgr *mgr,
@@ -1507,6 +1580,9 @@ static void drm_dp_send_link_address(str
 				       txmsg->reply.u.link_addr.ports[i].num_sdp_streams,
 				       txmsg->reply.u.link_addr.ports[i].num_sdp_stream_sinks);
 			}
+
+			drm_dp_check_mstb_guid(mstb, txmsg->reply.u.link_addr.guid);
+
 			for (i = 0; i < txmsg->reply.u.link_addr.nports; i++) {
 				drm_dp_add_port(mstb, mgr->dev, &txmsg->reply.u.link_addr.ports[i]);
 			}
@@ -1554,6 +1630,37 @@ static int drm_dp_send_enum_path_resourc
 	return 0;
 }
 
+static struct drm_dp_mst_port *drm_dp_get_last_connected_port_to_mstb(struct drm_dp_mst_branch *mstb)
+{
+	if (!mstb->port_parent)
+		return NULL;
+
+	if (mstb->port_parent->mstb != mstb)
+		return mstb->port_parent;
+
+	return drm_dp_get_last_connected_port_to_mstb(mstb->port_parent->parent);
+}
+
+static struct drm_dp_mst_branch *drm_dp_get_last_connected_port_and_mstb(struct drm_dp_mst_topology_mgr *mgr,
+									 struct drm_dp_mst_branch *mstb,
+									 int *port_num)
+{
+	struct drm_dp_mst_branch *rmstb = NULL;
+	struct drm_dp_mst_port *found_port;
+	mutex_lock(&mgr->lock);
+	if (mgr->mst_primary) {
+		found_port = drm_dp_get_last_connected_port_to_mstb(mstb);
+
+		if (found_port) {
+			rmstb = found_port->parent;
+			kref_get(&rmstb->kref);
+			*port_num = found_port->port_num;
+		}
+	}
+	mutex_unlock(&mgr->lock);
+	return rmstb;
+}
+
 static int drm_dp_payload_send_msg(struct drm_dp_mst_topology_mgr *mgr,
 				   struct drm_dp_mst_port *port,
 				   int id,
@@ -1561,22 +1668,38 @@ static int drm_dp_payload_send_msg(struc
 {
 	struct drm_dp_sideband_msg_tx *txmsg;
 	struct drm_dp_mst_branch *mstb;
-	int len, ret;
+	int len, ret, port_num;
+	u8 sinks[DRM_DP_MAX_SDP_STREAMS];
+	int i;
 
-	mstb = drm_dp_get_validated_mstb_ref(mgr, port->parent);
-	if (!mstb)
+	port = drm_dp_get_validated_port_ref(mgr, port);
+	if (!port)
 		return -EINVAL;
 
+	port_num = port->port_num;
+	mstb = drm_dp_get_validated_mstb_ref(mgr, port->parent);
+	if (!mstb) {
+		mstb = drm_dp_get_last_connected_port_and_mstb(mgr, port->parent, &port_num);
+
+		if (!mstb) {
+			drm_dp_put_port(port);
+			return -EINVAL;
+		}
+	}
+
 	txmsg = kzalloc(sizeof(*txmsg), GFP_KERNEL);
 	if (!txmsg) {
 		ret = -ENOMEM;
 		goto fail_put;
 	}
 
+	for (i = 0; i < port->num_sdp_streams; i++)
+		sinks[i] = i;
+
 	txmsg->dst = mstb;
-	len = build_allocate_payload(txmsg, port->port_num,
+	len = build_allocate_payload(txmsg, port_num,
 				     id,
-				     pbn);
+				     pbn, port->num_sdp_streams, sinks);
 
 	drm_dp_queue_down_tx(mgr, txmsg);
 
@@ -1590,6 +1713,7 @@ static int drm_dp_payload_send_msg(struc
 	kfree(txmsg);
 fail_put:
 	drm_dp_put_mst_branch_device(mstb);
+	drm_dp_put_port(port);
 	return ret;
 }
 
@@ -1672,6 +1796,11 @@ int drm_dp_update_payload_part1(struct d
 		req_payload.start_slot = cur_slots;
 		if (mgr->proposed_vcpis[i]) {
 			port = container_of(mgr->proposed_vcpis[i], struct drm_dp_mst_port, vcpi);
+			port = drm_dp_get_validated_port_ref(mgr, port);
+			if (!port) {
+				mutex_unlock(&mgr->payload_lock);
+				return -EINVAL;
+			}
 			req_payload.num_slots = mgr->proposed_vcpis[i]->num_slots;
 		} else {
 			port = NULL;
@@ -1697,6 +1826,9 @@ int drm_dp_update_payload_part1(struct d
 			mgr->payloads[i].payload_state = req_payload.payload_state;
 		}
 		cur_slots += req_payload.num_slots;
+
+		if (port)
+			drm_dp_put_port(port);
 	}
 
 	for (i = 0; i < mgr->max_payloads; i++) {
@@ -1844,11 +1976,12 @@ static int drm_dp_send_up_ack_reply(stru
 	drm_dp_encode_up_ack_reply(txmsg, req_type);
 
 	mutex_lock(&mgr->qlock);
-	list_add_tail(&txmsg->next, &mgr->tx_msg_upq);
-	if (!mgr->tx_up_in_progress) {
-		process_single_up_tx_qlock(mgr);
-	}
+
+	process_single_up_tx_qlock(mgr, txmsg);
+
 	mutex_unlock(&mgr->qlock);
+
+	kfree(txmsg);
 	return 0;
 }
 
@@ -1927,31 +2060,17 @@ int drm_dp_mst_topology_mgr_set_mst(stru
 		mgr->mst_primary = mstb;
 		kref_get(&mgr->mst_primary->kref);
 
-		{
-			struct drm_dp_payload reset_pay;
-			reset_pay.start_slot = 0;
-			reset_pay.num_slots = 0x3f;
-			drm_dp_dpcd_write_payload(mgr, 0, &reset_pay);
-		}
-
 		ret = drm_dp_dpcd_writeb(mgr->aux, DP_MSTM_CTRL,
-					 DP_MST_EN | DP_UP_REQ_EN | DP_UPSTREAM_IS_SRC);
+							 DP_MST_EN | DP_UP_REQ_EN | DP_UPSTREAM_IS_SRC);
 		if (ret < 0) {
 			goto out_unlock;
 		}
 
-
-		/* sort out guid */
-		ret = drm_dp_dpcd_read(mgr->aux, DP_GUID, mgr->guid, 16);
-		if (ret != 16) {
-			DRM_DEBUG_KMS("failed to read DP GUID %d\n", ret);
-			goto out_unlock;
-		}
-
-		mgr->guid_valid = drm_dp_validate_guid(mgr, mgr->guid);
-		if (!mgr->guid_valid) {
-			ret = drm_dp_dpcd_write(mgr->aux, DP_GUID, mgr->guid, 16);
-			mgr->guid_valid = true;
+		{
+			struct drm_dp_payload reset_pay;
+			reset_pay.start_slot = 0;
+			reset_pay.num_slots = 0x3f;
+			drm_dp_dpcd_write_payload(mgr, 0, &reset_pay);
 		}
 
 		queue_work(system_long_wq, &mgr->work);
@@ -2015,6 +2134,8 @@ int drm_dp_mst_topology_mgr_resume(struc
 
 	if (mgr->mst_primary) {
 		int sret;
+		u8 guid[16];
+
 		sret = drm_dp_dpcd_read(mgr->aux, DP_DPCD_REV, mgr->dpcd, DP_RECEIVER_CAP_SIZE);
 		if (sret != DP_RECEIVER_CAP_SIZE) {
 			DRM_DEBUG_KMS("dpcd read failed - undocked during suspend?\n");
@@ -2029,6 +2150,16 @@ int drm_dp_mst_topology_mgr_resume(struc
 			ret = -1;
 			goto out_unlock;
 		}
+
+		/* Some hubs forget their guids after they resume */
+		sret = drm_dp_dpcd_read(mgr->aux, DP_GUID, guid, 16);
+		if (sret != 16) {
+			DRM_DEBUG_KMS("dpcd read failed - undocked during suspend?\n");
+			ret = -1;
+			goto out_unlock;
+		}
+		drm_dp_check_mstb_guid(mgr->mst_primary, guid);
+
 		ret = 0;
 	} else
 		ret = -1;
@@ -2145,28 +2276,51 @@ static int drm_dp_mst_handle_up_req(stru
 
 	if (mgr->up_req_recv.have_eomt) {
 		struct drm_dp_sideband_msg_req_body msg;
-		struct drm_dp_mst_branch *mstb;
+		struct drm_dp_mst_branch *mstb = NULL;
 		bool seqno;
-		mstb = drm_dp_get_mst_branch_device(mgr,
-						    mgr->up_req_recv.initial_hdr.lct,
-						    mgr->up_req_recv.initial_hdr.rad);
-		if (!mstb) {
-			DRM_DEBUG_KMS("Got MST reply from unknown device %d\n", mgr->up_req_recv.initial_hdr.lct);
-			memset(&mgr->up_req_recv, 0, sizeof(struct drm_dp_sideband_msg_rx));
-			return 0;
+
+		if (!mgr->up_req_recv.initial_hdr.broadcast) {
+			mstb = drm_dp_get_mst_branch_device(mgr,
+							    mgr->up_req_recv.initial_hdr.lct,
+							    mgr->up_req_recv.initial_hdr.rad);
+			if (!mstb) {
+				DRM_DEBUG_KMS("Got MST reply from unknown device %d\n", mgr->up_req_recv.initial_hdr.lct);
+				memset(&mgr->up_req_recv, 0, sizeof(struct drm_dp_sideband_msg_rx));
+				return 0;
+			}
 		}
 
 		seqno = mgr->up_req_recv.initial_hdr.seqno;
 		drm_dp_sideband_parse_req(&mgr->up_req_recv, &msg);
 
 		if (msg.req_type == DP_CONNECTION_STATUS_NOTIFY) {
-			drm_dp_send_up_ack_reply(mgr, mstb, msg.req_type, seqno, false);
+			drm_dp_send_up_ack_reply(mgr, mgr->mst_primary, msg.req_type, seqno, false);
+
+			if (!mstb)
+				mstb = drm_dp_get_mst_branch_device_by_guid(mgr, msg.u.conn_stat.guid);
+
+			if (!mstb) {
+				DRM_DEBUG_KMS("Got MST reply from unknown device %d\n", mgr->up_req_recv.initial_hdr.lct);
+				memset(&mgr->up_req_recv, 0, sizeof(struct drm_dp_sideband_msg_rx));
+				return 0;
+			}
+
 			drm_dp_update_port(mstb, &msg.u.conn_stat);
+
 			DRM_DEBUG_KMS("Got CSN: pn: %d ldps:%d ddps: %d mcs: %d ip: %d pdt: %d\n", msg.u.conn_stat.port_number, msg.u.conn_stat.legacy_device_plug_status, msg.u.conn_stat.displayport_device_plug_status, msg.u.conn_stat.message_capability_status, msg.u.conn_stat.input_port, msg.u.conn_stat.peer_device_type);
 			(*mgr->cbs->hotplug)(mgr);
 
 		} else if (msg.req_type == DP_RESOURCE_STATUS_NOTIFY) {
-			drm_dp_send_up_ack_reply(mgr, mstb, msg.req_type, seqno, false);
+			drm_dp_send_up_ack_reply(mgr, mgr->mst_primary, msg.req_type, seqno, false);
+			if (!mstb)
+				mstb = drm_dp_get_mst_branch_device_by_guid(mgr, msg.u.resource_stat.guid);
+
+			if (!mstb) {
+				DRM_DEBUG_KMS("Got MST reply from unknown device %d\n", mgr->up_req_recv.initial_hdr.lct);
+				memset(&mgr->up_req_recv, 0, sizeof(struct drm_dp_sideband_msg_rx));
+				return 0;
+			}
+
 			DRM_DEBUG_KMS("Got RSN: pn: %d avail_pbn %d\n", msg.u.resource_stat.port_number, msg.u.resource_stat.available_pbn);
 		}
 
@@ -2259,6 +2413,27 @@ out:
 EXPORT_SYMBOL(drm_dp_mst_detect_port);
 
 /**
+ * drm_dp_mst_port_has_audio() - Check whether port has audio capability or not
+ * @mgr: manager for this port
+ * @port: unverified pointer to a port.
+ *
+ * This returns whether the port supports audio or not.
+ */
+bool drm_dp_mst_port_has_audio(struct drm_dp_mst_topology_mgr *mgr,
+					struct drm_dp_mst_port *port)
+{
+	bool ret = false;
+
+	port = drm_dp_get_validated_port_ref(mgr, port);
+	if (!port)
+		return ret;
+	ret = port->has_audio;
+	drm_dp_put_port(port);
+	return ret;
+}
+EXPORT_SYMBOL(drm_dp_mst_port_has_audio);
+
+/**
  * drm_dp_mst_get_edid() - get EDID for an MST port
  * @connector: toplevel connector to get EDID for
  * @mgr: manager for this port
@@ -2283,6 +2458,7 @@ struct edid *drm_dp_mst_get_edid(struct
 		edid = drm_get_edid(connector, &port->aux.ddc);
 		drm_mode_connector_set_tile_property(connector);
 	}
+	port->has_audio = drm_detect_monitor_audio(edid);
 	drm_dp_put_port(port);
 	return edid;
 }
@@ -2346,6 +2522,7 @@ bool drm_dp_mst_allocate_vcpi(struct drm
 		DRM_DEBUG_KMS("payload: vcpi %d already allocated for pbn %d - requested pbn %d\n", port->vcpi.vcpi, port->vcpi.pbn, pbn);
 		if (pbn == port->vcpi.pbn) {
 			*slots = port->vcpi.num_slots;
+			drm_dp_put_port(port);
 			return true;
 		}
 	}
@@ -2505,32 +2682,31 @@ EXPORT_SYMBOL(drm_dp_check_act_status);
  */
 int drm_dp_calc_pbn_mode(int clock, int bpp)
 {
-	fixed20_12 pix_bw;
-	fixed20_12 fbpp;
-	fixed20_12 result;
-	fixed20_12 margin, tmp;
-	u32 res;
-
-	pix_bw.full = dfixed_const(clock);
-	fbpp.full = dfixed_const(bpp);
-	tmp.full = dfixed_const(8);
-	fbpp.full = dfixed_div(fbpp, tmp);
-
-	result.full = dfixed_mul(pix_bw, fbpp);
-	margin.full = dfixed_const(54);
-	tmp.full = dfixed_const(64);
-	margin.full = dfixed_div(margin, tmp);
-	result.full = dfixed_div(result, margin);
-
-	margin.full = dfixed_const(1006);
-	tmp.full = dfixed_const(1000);
-	margin.full = dfixed_div(margin, tmp);
-	result.full = dfixed_mul(result, margin);
-
-	result.full = dfixed_div(result, tmp);
-	result.full = dfixed_ceil(result);
-	res = dfixed_trunc(result);
-	return res;
+	u64 kbps;
+	s64 peak_kbps;
+	u32 numerator;
+	u32 denominator;
+
+	kbps = clock * bpp;
+
+	/*
+	 * margin 5300ppm + 300ppm ~ 0.6% as per spec, factor is 1.006
+	 * The unit of 54/64Mbytes/sec is an arbitrary unit chosen based on
+	 * common multiplier to render an integer PBN for all link rate/lane
+	 * counts combinations
+	 * calculate
+	 * peak_kbps *= (1006/1000)
+	 * peak_kbps *= (64/54)
+	 * peak_kbps *= 8    convert to bytes
+	 */
+
+	numerator = 64 * 1006;
+	denominator = 54 * 8 * 1000 * 1000;
+
+	kbps *= numerator;
+	peak_kbps = drm_fixp_from_fraction(kbps, denominator);
+
+	return drm_fixp2int_ceil(peak_kbps);
 }
 EXPORT_SYMBOL(drm_dp_calc_pbn_mode);
 
@@ -2538,11 +2714,23 @@ static int test_calc_pbn_mode(void)
 {
 	int ret;
 	ret = drm_dp_calc_pbn_mode(154000, 30);
-	if (ret != 689)
+	if (ret != 689) {
+		DRM_ERROR("PBN calculation test failed - clock %d, bpp %d, expected PBN %d, actual PBN %d.\n",
+				154000, 30, 689, ret);
 		return -EINVAL;
+	}
 	ret = drm_dp_calc_pbn_mode(234000, 30);
-	if (ret != 1047)
+	if (ret != 1047) {
+		DRM_ERROR("PBN calculation test failed - clock %d, bpp %d, expected PBN %d, actual PBN %d.\n",
+				234000, 30, 1047, ret);
+		return -EINVAL;
+	}
+	ret = drm_dp_calc_pbn_mode(297000, 24);
+	if (ret != 1063) {
+		DRM_ERROR("PBN calculation test failed - clock %d, bpp %d, expected PBN %d, actual PBN %d.\n",
+				297000, 24, 1063, ret);
 		return -EINVAL;
+	}
 	return 0;
 }
 
@@ -2566,7 +2754,7 @@ static void drm_dp_mst_dump_mstb(struct
 
 	seq_printf(m, "%smst: %p, %d\n", prefix, mstb, mstb->num_ports);
 	list_for_each_entry(port, &mstb->ports, next) {
-		seq_printf(m, "%sport: %d: ddps: %d ldps: %d, %p, conn: %p\n", prefix, port->port_num, port->ddps, port->ldps, port, port->connector);
+		seq_printf(m, "%sport: %d: ddps: %d ldps: %d, sdp: %d/%d, %p, conn: %p\n", prefix, port->port_num, port->ddps, port->ldps, port->num_sdp_streams, port->num_sdp_stream_sinks, port, port->connector);
 		if (port->mstb)
 			drm_dp_mst_dump_mstb(m, port->mstb);
 	}
@@ -2683,6 +2871,13 @@ static void drm_dp_tx_work(struct work_s
 	mutex_unlock(&mgr->qlock);
 }
 
+static void drm_dp_free_mst_port(struct kref *kref)
+{
+	struct drm_dp_mst_port *port = container_of(kref, struct drm_dp_mst_port, kref);
+	kref_put(&port->parent->kref, drm_dp_free_mst_branch_device);
+	kfree(port);
+}
+
 static void drm_dp_destroy_connector_work(struct work_struct *work)
 {
 	struct drm_dp_mst_topology_mgr *mgr = container_of(work, struct drm_dp_mst_topology_mgr, destroy_connector_work);
@@ -2703,13 +2898,20 @@ static void drm_dp_destroy_connector_wor
 		list_del(&port->next);
 		mutex_unlock(&mgr->destroy_connector_lock);
 
+		kref_init(&port->kref);
+		INIT_LIST_HEAD(&port->next);
+
 		mgr->cbs->destroy_connector(mgr, port->connector);
 
 		drm_dp_port_teardown_pdt(port, port->pdt);
 
-		if (!port->input && port->vcpi.vcpi > 0)
+		if (!port->input && port->vcpi.vcpi > 0) {
+			drm_dp_mst_reset_vcpi_slots(mgr, port);
+			drm_dp_update_payload_part1(mgr);
 			drm_dp_mst_put_payload_id(mgr, port->vcpi.vcpi);
-		kfree(port);
+		}
+
+		kref_put(&port->kref, drm_dp_free_mst_port);
 		send_hotplug = true;
 	}
 	if (send_hotplug)
@@ -2736,7 +2938,6 @@ int drm_dp_mst_topology_mgr_init(struct
 	mutex_init(&mgr->qlock);
 	mutex_init(&mgr->payload_lock);
 	mutex_init(&mgr->destroy_connector_lock);
-	INIT_LIST_HEAD(&mgr->tx_msg_upq);
 	INIT_LIST_HEAD(&mgr->tx_msg_downq);
 	INIT_LIST_HEAD(&mgr->destroy_connector_list);
 	INIT_WORK(&mgr->work, drm_dp_mst_link_probe_work);
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/drm_edid.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/drm_edid.c
@@ -73,6 +73,8 @@
 #define EDID_QUIRK_FORCE_8BPC			(1 << 8)
 /* Force 12bpc */
 #define EDID_QUIRK_FORCE_12BPC			(1 << 9)
+/* Force 6bpc */
+#define EDID_QUIRK_FORCE_6BPC			(1 << 10)
 
 struct detailed_mode_closure {
 	struct drm_connector *connector;
@@ -99,6 +101,9 @@ static struct edid_quirk {
 	/* Unknown Acer */
 	{ "ACR", 2423, EDID_QUIRK_FIRST_DETAILED_PREFERRED },
 
+	/* AEO model 0 reports 8 bpc, but is a 6 bpc panel */
+	{ "AEO", 0, EDID_QUIRK_FORCE_6BPC },
+
 	/* Belinea 10 15 55 */
 	{ "MAX", 1516, EDID_QUIRK_PREFER_LARGE_60 },
 	{ "MAX", 0x77e, EDID_QUIRK_PREFER_LARGE_60 },
@@ -3820,6 +3825,9 @@ int drm_add_edid_modes(struct drm_connec
 
 	drm_add_display_info(edid, &connector->display_info, connector);
 
+	if (quirks & EDID_QUIRK_FORCE_6BPC)
+		connector->display_info.bpc = 6;
+
 	if (quirks & EDID_QUIRK_FORCE_8BPC)
 		connector->display_info.bpc = 8;
 
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/drm_fb_cma_helper.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/drm_fb_cma_helper.c
@@ -348,9 +348,6 @@ struct drm_fbdev_cma *drm_fbdev_cma_init
 
 	}
 
-	/* disable all the possible outputs/crtcs before entering KMS mode */
-	drm_helper_disable_unused_functions(dev);
-
 	ret = drm_fb_helper_initial_config(helper, preferred_bpp);
 	if (ret < 0) {
 		dev_err(dev->dev, "Failed to set initial hw configuration.\n");
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/drm_fb_helper.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/drm_fb_helper.c
@@ -1251,7 +1251,7 @@ retry:
 			goto fail;
 
 		plane = mode_set->crtc->primary;
-		plane_mask |= drm_plane_index(plane);
+		plane_mask |= (1 << drm_plane_index(plane));
 		plane->old_fb = plane->fb;
 	}
 
@@ -1899,7 +1899,6 @@ static int drm_pick_crtcs(struct drm_fb_
 			  int n, int width, int height)
 {
 	int c, o;
-	struct drm_device *dev = fb_helper->dev;
 	struct drm_connector *connector;
 	const struct drm_connector_helper_funcs *connector_funcs;
 	struct drm_encoder *encoder;
@@ -1918,7 +1917,7 @@ static int drm_pick_crtcs(struct drm_fb_
 	if (modes[n] == NULL)
 		return best_score;
 
-	crtcs = kzalloc(dev->mode_config.num_connector *
+	crtcs = kzalloc(fb_helper->connector_count *
 			sizeof(struct drm_fb_helper_crtc *), GFP_KERNEL);
 	if (!crtcs)
 		return best_score;
@@ -1964,7 +1963,7 @@ static int drm_pick_crtcs(struct drm_fb_
 		if (score > best_score) {
 			best_score = score;
 			memcpy(best_crtcs, crtcs,
-			       dev->mode_config.num_connector *
+			       fb_helper->connector_count *
 			       sizeof(struct drm_fb_helper_crtc *));
 		}
 	}
@@ -2175,9 +2174,9 @@ EXPORT_SYMBOL(drm_fb_helper_hotplug_even
  * but the module doesn't depend on any fb console symbols.  At least
  * attempt to load fbcon to avoid leaving the system without a usable console.
  */
-#if defined(CONFIG_FRAMEBUFFER_CONSOLE_MODULE) && !defined(CONFIG_EXPERT)
-static int __init drm_fb_helper_modinit(void)
+int __init drm_fb_helper_modinit(void)
 {
+#if defined(CONFIG_FRAMEBUFFER_CONSOLE_MODULE) && !defined(CONFIG_EXPERT)
 	const char *name = "fbcon";
 	struct module *fbcon;
 
@@ -2187,8 +2186,7 @@ static int __init drm_fb_helper_modinit(
 
 	if (!fbcon)
 		request_module_nowait(name);
+#endif
 	return 0;
 }
-
-module_init(drm_fb_helper_modinit);
-#endif
+EXPORT_SYMBOL(drm_fb_helper_modinit);
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/drm_gem.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/drm_gem.c
@@ -338,27 +338,32 @@ drm_gem_handle_create_tail(struct drm_fi
 	spin_unlock(&file_priv->table_lock);
 	idr_preload_end();
 	mutex_unlock(&dev->object_name_lock);
-	if (ret < 0) {
-		drm_gem_object_handle_unreference_unlocked(obj);
-		return ret;
-	}
+	if (ret < 0)
+		goto err_unref;
+
 	*handlep = ret;
 
 	ret = drm_vma_node_allow(&obj->vma_node, file_priv->filp);
-	if (ret) {
-		drm_gem_handle_delete(file_priv, *handlep);
-		return ret;
-	}
+	if (ret)
+		goto err_remove;
 
 	if (dev->driver->gem_open_object) {
 		ret = dev->driver->gem_open_object(obj, file_priv);
-		if (ret) {
-			drm_gem_handle_delete(file_priv, *handlep);
-			return ret;
-		}
+		if (ret)
+			goto err_revoke;
 	}
 
 	return 0;
+
+err_revoke:
+	drm_vma_node_revoke(&obj->vma_node, file_priv->filp);
+err_remove:
+	spin_lock(&file_priv->table_lock);
+	idr_remove(&file_priv->object_idr, *handlep);
+	spin_unlock(&file_priv->table_lock);
+err_unref:
+	drm_gem_object_handle_unreference_unlocked(obj);
+	return ret;
 }
 
 /**
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/drm_ioc32.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/drm_ioc32.c
@@ -1015,6 +1015,7 @@ static int compat_drm_wait_vblank(struct
 	return 0;
 }
 
+#if defined(CONFIG_X86) || defined(CONFIG_IA64)
 typedef struct drm_mode_fb_cmd232 {
 	u32 fb_id;
 	u32 width;
@@ -1071,6 +1072,7 @@ static int compat_drm_mode_addfb2(struct
 
 	return 0;
 }
+#endif
 
 static drm_ioctl_compat_t *drm_compat_ioctls[] = {
 	[DRM_IOCTL_NR(DRM_IOCTL_VERSION32)] = compat_drm_version,
@@ -1104,7 +1106,9 @@ static drm_ioctl_compat_t *drm_compat_io
 	[DRM_IOCTL_NR(DRM_IOCTL_UPDATE_DRAW32)] = compat_drm_update_draw,
 #endif
 	[DRM_IOCTL_NR(DRM_IOCTL_WAIT_VBLANK32)] = compat_drm_wait_vblank,
+#if defined(CONFIG_X86) || defined(CONFIG_IA64)
 	[DRM_IOCTL_NR(DRM_IOCTL_MODE_ADDFB232)] = compat_drm_mode_addfb2,
+#endif
 };
 
 /**
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/drm_irq.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/drm_irq.c
@@ -221,6 +221,64 @@ static void drm_update_vblank_count(stru
 		diff = (flags & DRM_CALLED_FROM_VBLIRQ) != 0;
 	}
 
+	/*
+	 * Within a drm_vblank_pre_modeset - drm_vblank_post_modeset
+	 * interval? If so then vblank irqs keep running and it will likely
+	 * happen that the hardware vblank counter is not trustworthy as it
+	 * might reset at some point in that interval and vblank timestamps
+	 * are not trustworthy either in that interval. Iow. this can result
+	 * in a bogus diff >> 1 which must be avoided as it would cause
+	 * random large forward jumps of the software vblank counter.
+	 */
+	if (diff > 1 && (vblank->inmodeset & 0x2)) {
+		DRM_DEBUG_VBL("clamping vblank bump to 1 on crtc %u: diffr=%u"
+			      " due to pre-modeset.\n", pipe, diff);
+		diff = 1;
+	}
+
+	/*
+	 * FIMXE: Need to replace this hack with proper seqlocks.
+	 *
+	 * Restrict the bump of the software vblank counter to a safe maximum
+	 * value of +1 whenever there is the possibility that concurrent readers
+	 * of vblank timestamps could be active at the moment, as the current
+	 * implementation of the timestamp caching and updating is not safe
+	 * against concurrent readers for calls to store_vblank() with a bump
+	 * of anything but +1. A bump != 1 would very likely return corrupted
+	 * timestamps to userspace, because the same slot in the cache could
+	 * be concurrently written by store_vblank() and read by one of those
+	 * readers without the read-retry logic detecting the collision.
+	 *
+	 * Concurrent readers can exist when we are called from the
+	 * drm_vblank_off() or drm_vblank_on() functions and other non-vblank-
+	 * irq callers. However, all those calls to us are happening with the
+	 * vbl_lock locked to prevent drm_vblank_get(), so the vblank refcount
+	 * can't increase while we are executing. Therefore a zero refcount at
+	 * this point is safe for arbitrary counter bumps if we are called
+	 * outside vblank irq, a non-zero count is not 100% safe. Unfortunately
+	 * we must also accept a refcount of 1, as whenever we are called from
+	 * drm_vblank_get() -> drm_vblank_enable() the refcount will be 1 and
+	 * we must let that one pass through in order to not lose vblank counts
+	 * during vblank irq off - which would completely defeat the whole
+	 * point of this routine.
+	 *
+	 * Whenever we are called from vblank irq, we have to assume concurrent
+	 * readers exist or can show up any time during our execution, even if
+	 * the refcount is currently zero, as vblank irqs are usually only
+	 * enabled due to the presence of readers, and because when we are called
+	 * from vblank irq we can't hold the vbl_lock to protect us from sudden
+	 * bumps in vblank refcount. Therefore also restrict bumps to +1 when
+	 * called from vblank irq.
+	 */
+	if ((diff > 1) && (atomic_read(&vblank->refcount) > 1 ||
+	    (flags & DRM_CALLED_FROM_VBLIRQ))) {
+		DRM_DEBUG_VBL("clamping vblank bump to 1 on crtc %u: diffr=%u "
+			      "refcount %u, vblirq %u\n", pipe, diff,
+			      atomic_read(&vblank->refcount),
+			      (flags & DRM_CALLED_FROM_VBLIRQ) != 0);
+		diff = 1;
+	}
+
 	DRM_DEBUG_VBL("updating vblank count on crtc %u:"
 		      " current=%u, diff=%u, hw=%u hw_last=%u\n",
 		      pipe, vblank->count, diff, cur_vblank, vblank->last);
@@ -1313,7 +1371,13 @@ void drm_vblank_off(struct drm_device *d
 	spin_lock_irqsave(&dev->event_lock, irqflags);
 
 	spin_lock(&dev->vbl_lock);
-	vblank_disable_and_save(dev, pipe);
+	DRM_DEBUG_VBL("crtc %d, vblank enabled %d, inmodeset %d\n",
+		      pipe, vblank->enabled, vblank->inmodeset);
+
+	/* Avoid redundant vblank disables without previous drm_vblank_on(). */
+	if (drm_core_check_feature(dev, DRIVER_ATOMIC) || !vblank->inmodeset)
+		vblank_disable_and_save(dev, pipe);
+
 	wake_up(&vblank->queue);
 
 	/*
@@ -1415,6 +1479,9 @@ void drm_vblank_on(struct drm_device *de
 		return;
 
 	spin_lock_irqsave(&dev->vbl_lock, irqflags);
+	DRM_DEBUG_VBL("crtc %d, vblank enabled %d, inmodeset %d\n",
+		      pipe, vblank->enabled, vblank->inmodeset);
+
 	/* Drop our private "prevent drm_vblank_get" refcount */
 	if (vblank->inmodeset) {
 		atomic_dec(&vblank->refcount);
@@ -1427,8 +1494,7 @@ void drm_vblank_on(struct drm_device *de
 	 * re-enable interrupts if there are users left, or the
 	 * user wishes vblank interrupts to be enabled all the time.
 	 */
-	if (atomic_read(&vblank->refcount) != 0 ||
-	    (!dev->vblank_disable_immediate && drm_vblank_offdelay == 0))
+	if (atomic_read(&vblank->refcount) != 0 || drm_vblank_offdelay == 0)
 		WARN_ON(drm_vblank_enable(dev, pipe));
 	spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
 }
@@ -1523,6 +1589,7 @@ void drm_vblank_post_modeset(struct drm_
 	if (vblank->inmodeset) {
 		spin_lock_irqsave(&dev->vbl_lock, irqflags);
 		dev->vblank_disable_allowed = true;
+		drm_reset_vblank_timestamp(dev, pipe);
 		spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
 
 		if (vblank->inmodeset & 0x2)
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/drm_kms_helper_common.c
@@ -0,0 +1,60 @@
+/*
+ * Copyright © 2015 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Rafael Antognolli <rafael.antognolli@intel.com>
+ *
+ */
+
+#include <drm/drmP.h>
+#include <drm/drm_fb_helper.h>
+#include <drm/drm_dp_aux_dev.h>
+
+MODULE_AUTHOR("David Airlie, Jesse Barnes");
+MODULE_DESCRIPTION("DRM KMS helper");
+MODULE_LICENSE("GPL and additional rights");
+
+static int __init drm_kms_helper_init(void)
+{
+	int ret;
+
+	/* Call init functions from specific kms helpers here */
+	ret = drm_fb_helper_modinit();
+	if (ret < 0)
+		goto out;
+
+	ret = drm_dp_aux_dev_init();
+	if (ret < 0)
+		goto out;
+
+out:
+	return ret;
+}
+
+static void __exit drm_kms_helper_exit(void)
+{
+	/* Call exit functions from specific kms helpers here */
+	drm_dp_aux_dev_exit();
+}
+
+module_init(drm_kms_helper_init);
+module_exit(drm_kms_helper_exit);
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/drm_modes.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/drm_modes.c
@@ -1487,6 +1487,8 @@ int drm_mode_convert_umode(struct drm_di
 	if (out->status != MODE_OK)
 		goto out;
 
+	drm_mode_set_crtcinfo(out, CRTC_INTERLACE_HALVE_V);
+
 	ret = 0;
 
 out:
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/drm_modeset_lock.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/drm_modeset_lock.c
@@ -57,11 +57,18 @@
 
 /**
  * drm_modeset_lock_all - take all modeset locks
- * @dev: drm device
+ * @dev: DRM device
  *
  * This function takes all modeset locks, suitable where a more fine-grained
- * scheme isn't (yet) implemented. Locks must be dropped with
- * drm_modeset_unlock_all.
+ * scheme isn't (yet) implemented. Locks must be dropped by calling the
+ * drm_modeset_unlock_all() function.
+ *
+ * This function is deprecated. It allocates a lock acquisition context and
+ * stores it in the DRM device's ->mode_config. This facilitate conversion of
+ * existing code because it removes the need to manually deal with the
+ * acquisition context, but it is also brittle because the context is global
+ * and care must be taken not to nest calls. New code should use the
+ * drm_modeset_lock_all_ctx() function and pass in the context explicitly.
  */
 void drm_modeset_lock_all(struct drm_device *dev)
 {
@@ -78,39 +85,43 @@ void drm_modeset_lock_all(struct drm_dev
 	drm_modeset_acquire_init(ctx, 0);
 
 retry:
-	ret = drm_modeset_lock(&config->connection_mutex, ctx);
-	if (ret)
-		goto fail;
-	ret = drm_modeset_lock_all_crtcs(dev, ctx);
-	if (ret)
-		goto fail;
+	ret = drm_modeset_lock_all_ctx(dev, ctx);
+	if (ret < 0) {
+		if (ret == -EDEADLK) {
+			drm_modeset_backoff(ctx);
+			goto retry;
+		}
+
+		drm_modeset_acquire_fini(ctx);
+		kfree(ctx);
+		return;
+	}
 
 	WARN_ON(config->acquire_ctx);
 
-	/* now we hold the locks, so now that it is safe, stash the
-	 * ctx for drm_modeset_unlock_all():
+	/*
+	 * We hold the locks now, so it is safe to stash the acquisition
+	 * context for drm_modeset_unlock_all().
 	 */
 	config->acquire_ctx = ctx;
 
 	drm_warn_on_modeset_not_all_locked(dev);
-
-	return;
-
-fail:
-	if (ret == -EDEADLK) {
-		drm_modeset_backoff(ctx);
-		goto retry;
-	}
-
-	kfree(ctx);
 }
 EXPORT_SYMBOL(drm_modeset_lock_all);
 
 /**
  * drm_modeset_unlock_all - drop all modeset locks
- * @dev: device
+ * @dev: DRM device
  *
- * This function drop all modeset locks taken by drm_modeset_lock_all.
+ * This function drops all modeset locks taken by a previous call to the
+ * drm_modeset_lock_all() function.
+ *
+ * This function is deprecated. It uses the lock acquisition context stored
+ * in the DRM device's ->mode_config. This facilitates conversion of existing
+ * code because it removes the need to manually deal with the acquisition
+ * context, but it is also brittle because the context is global and care must
+ * be taken not to nest calls. New code should pass the acquisition context
+ * directly to the drm_modeset_drop_locks() function.
  */
 void drm_modeset_unlock_all(struct drm_device *dev)
 {
@@ -431,14 +442,34 @@ void drm_modeset_unlock(struct drm_modes
 }
 EXPORT_SYMBOL(drm_modeset_unlock);
 
-/* In some legacy codepaths it's convenient to just grab all the crtc and plane
- * related locks. */
-int drm_modeset_lock_all_crtcs(struct drm_device *dev,
-		struct drm_modeset_acquire_ctx *ctx)
+/**
+ * drm_modeset_lock_all_ctx - take all modeset locks
+ * @dev: DRM device
+ * @ctx: lock acquisition context
+ *
+ * This function takes all modeset locks, suitable where a more fine-grained
+ * scheme isn't (yet) implemented.
+ *
+ * Unlike drm_modeset_lock_all(), it doesn't take the dev->mode_config.mutex
+ * since that lock isn't required for modeset state changes. Callers which
+ * need to grab that lock too need to do so outside of the acquire context
+ * @ctx.
+ *
+ * Locks acquired with this function should be released by calling the
+ * drm_modeset_drop_locks() function on @ctx.
+ *
+ * Returns: 0 on success or a negative error-code on failure.
+ */
+int drm_modeset_lock_all_ctx(struct drm_device *dev,
+			     struct drm_modeset_acquire_ctx *ctx)
 {
 	struct drm_crtc *crtc;
 	struct drm_plane *plane;
-	int ret = 0;
+	int ret;
+
+	ret = drm_modeset_lock(&dev->mode_config.connection_mutex, ctx);
+	if (ret)
+		return ret;
 
 	drm_for_each_crtc(crtc, dev) {
 		ret = drm_modeset_lock(&crtc->mutex, ctx);
@@ -454,4 +485,4 @@ int drm_modeset_lock_all_crtcs(struct dr
 
 	return 0;
 }
-EXPORT_SYMBOL(drm_modeset_lock_all_crtcs);
+EXPORT_SYMBOL(drm_modeset_lock_all_ctx);
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/drm_pci.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/drm_pci.c
@@ -410,6 +410,26 @@ int drm_pcie_get_speed_cap_mask(struct d
 }
 EXPORT_SYMBOL(drm_pcie_get_speed_cap_mask);
 
+int drm_pcie_get_max_link_width(struct drm_device *dev, u32 *mlw)
+{
+	struct pci_dev *root;
+	u32 lnkcap;
+
+	*mlw = 0;
+	if (!dev->pdev)
+		return -EINVAL;
+
+	root = dev->pdev->bus->self;
+
+	pcie_capability_read_dword(root, PCI_EXP_LNKCAP, &lnkcap);
+
+	*mlw = (lnkcap & PCI_EXP_LNKCAP_MLW) >> 4;
+
+	DRM_INFO("probing mlw for device %x:%x = %x\n", root->vendor, root->device, lnkcap);
+	return 0;
+}
+EXPORT_SYMBOL(drm_pcie_get_max_link_width);
+
 #else
 
 int drm_pci_init(struct drm_driver *driver, struct pci_driver *pdriver)
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/drm_rect.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/drm_rect.c
@@ -275,22 +275,23 @@ EXPORT_SYMBOL(drm_rect_calc_vscale_relax
 
 /**
  * drm_rect_debug_print - print the rectangle information
+ * @prefix: prefix string
  * @r: rectangle to print
  * @fixed_point: rectangle is in 16.16 fixed point format
  */
-void drm_rect_debug_print(const struct drm_rect *r, bool fixed_point)
+void drm_rect_debug_print(const char *prefix, const struct drm_rect *r, bool fixed_point)
 {
 	int w = drm_rect_width(r);
 	int h = drm_rect_height(r);
 
 	if (fixed_point)
-		DRM_DEBUG_KMS("%d.%06ux%d.%06u%+d.%06u%+d.%06u\n",
+		DRM_DEBUG_KMS("%s%d.%06ux%d.%06u%+d.%06u%+d.%06u\n", prefix,
 			      w >> 16, ((w & 0xffff) * 15625) >> 10,
 			      h >> 16, ((h & 0xffff) * 15625) >> 10,
 			      r->x1 >> 16, ((r->x1 & 0xffff) * 15625) >> 10,
 			      r->y1 >> 16, ((r->y1 & 0xffff) * 15625) >> 10);
 	else
-		DRM_DEBUG_KMS("%dx%d%+d%+d\n", w, h, r->x1, r->y1);
+		DRM_DEBUG_KMS("%s%dx%d%+d%+d\n", prefix, w, h, r->x1, r->y1);
 }
 EXPORT_SYMBOL(drm_rect_debug_print);
 
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/drm_sysfs.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/drm_sysfs.c
@@ -252,7 +252,7 @@ static ssize_t edid_show(struct file *fi
 			 struct bin_attribute *attr, char *buf, loff_t off,
 			 size_t count)
 {
-	struct device *connector_dev = container_of(kobj, struct device, kobj);
+	struct device *connector_dev = kobj_to_dev(kobj);
 	struct drm_connector *connector = to_drm_connector(connector_dev);
 	unsigned char *edid;
 	size_t size;
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/gma500/cdv_intel_dp.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/gma500/cdv_intel_dp.c
@@ -220,7 +220,7 @@ i2c_dp_aux_prepare_bus(struct i2c_adapte
  * FIXME: This is the old dp aux helper, gma500 is the last driver that needs to
  * be ported over to the new helper code in drm_dp_helper.c like i915 or radeon.
  */
-static int __deprecated
+static int
 i2c_dp_aux_add_bus(struct i2c_adapter *adapter)
 {
 	int error;
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/gma500/gem.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/gma500/gem.c
@@ -130,7 +130,7 @@ int psb_gem_create(struct drm_file *file
 		return ret;
 	}
 	/* We have the initial and handle reference but need only one now */
-	drm_gem_object_unreference(&r->gem);
+	drm_gem_object_unreference_unlocked(&r->gem);
 	*handlep = handle;
 	return 0;
 }
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/gma500/mdfld_dsi_pkg_sender.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/gma500/mdfld_dsi_pkg_sender.c
@@ -72,7 +72,7 @@ static const char *const dsi_errors[] =
 	"RX Prot Violation",
 	"HS Generic Write FIFO Full",
 	"LP Generic Write FIFO Full",
-	"Generic Read Data Avail"
+	"Generic Read Data Avail",
 	"Special Packet Sent",
 	"Tearing Effect",
 };
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/i915/i915_dma.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/i915/i915_dma.c
@@ -402,6 +402,8 @@ static int i915_load_modeset_init(struct
 	if (ret)
 		goto cleanup_gem_stolen;
 
+	intel_setup_gmbus(dev);
+
 	/* Important: The output setup functions called by modeset_init need
 	 * working irqs for e.g. gmbus and dp aux transfers. */
 	intel_modeset_init(dev);
@@ -451,6 +453,7 @@ cleanup_gem:
 cleanup_irq:
 	intel_guc_ucode_fini(dev);
 	drm_irq_uninstall(dev);
+	intel_teardown_gmbus(dev);
 cleanup_gem_stolen:
 	i915_gem_cleanup_stolen(dev);
 cleanup_vga_switcheroo:
@@ -1028,7 +1031,6 @@ int i915_driver_load(struct drm_device *
 
 	/* Try to make sure MCHBAR is enabled before poking at it */
 	intel_setup_mchbar(dev);
-	intel_setup_gmbus(dev);
 	intel_opregion_setup(dev);
 
 	i915_gem_load(dev);
@@ -1099,7 +1101,6 @@ out_gem_unload:
 	if (dev->pdev->msi_enabled)
 		pci_disable_msi(dev->pdev);
 
-	intel_teardown_gmbus(dev);
 	intel_teardown_mchbar(dev);
 	pm_qos_remove_request(&dev_priv->pm_qos);
 	destroy_workqueue(dev_priv->gpu_error.hangcheck_wq);
@@ -1198,7 +1199,6 @@ int i915_driver_unload(struct drm_device
 
 	intel_csr_ucode_fini(dev);
 
-	intel_teardown_gmbus(dev);
 	intel_teardown_mchbar(dev);
 
 	destroy_workqueue(dev_priv->hotplug.dp_wq);
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/i915/i915_drv.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/i915/i915_drv.c
@@ -400,44 +400,37 @@ static const struct intel_device_info in
  * and subvendor IDs, we need it to come before the more general IVB
  * PCI ID matches, otherwise we'll use the wrong info struct above.
  */
-#define INTEL_PCI_IDS \
-	INTEL_I830_IDS(&intel_i830_info),	\
-	INTEL_I845G_IDS(&intel_845g_info),	\
-	INTEL_I85X_IDS(&intel_i85x_info),	\
-	INTEL_I865G_IDS(&intel_i865g_info),	\
-	INTEL_I915G_IDS(&intel_i915g_info),	\
-	INTEL_I915GM_IDS(&intel_i915gm_info),	\
-	INTEL_I945G_IDS(&intel_i945g_info),	\
-	INTEL_I945GM_IDS(&intel_i945gm_info),	\
-	INTEL_I965G_IDS(&intel_i965g_info),	\
-	INTEL_G33_IDS(&intel_g33_info),		\
-	INTEL_I965GM_IDS(&intel_i965gm_info),	\
-	INTEL_GM45_IDS(&intel_gm45_info), 	\
-	INTEL_G45_IDS(&intel_g45_info), 	\
-	INTEL_PINEVIEW_IDS(&intel_pineview_info),	\
-	INTEL_IRONLAKE_D_IDS(&intel_ironlake_d_info),	\
-	INTEL_IRONLAKE_M_IDS(&intel_ironlake_m_info),	\
-	INTEL_SNB_D_IDS(&intel_sandybridge_d_info),	\
-	INTEL_SNB_M_IDS(&intel_sandybridge_m_info),	\
-	INTEL_IVB_Q_IDS(&intel_ivybridge_q_info), /* must be first IVB */ \
-	INTEL_IVB_M_IDS(&intel_ivybridge_m_info),	\
-	INTEL_IVB_D_IDS(&intel_ivybridge_d_info),	\
-	INTEL_HSW_D_IDS(&intel_haswell_d_info), \
-	INTEL_HSW_M_IDS(&intel_haswell_m_info), \
-	INTEL_VLV_M_IDS(&intel_valleyview_m_info),	\
-	INTEL_VLV_D_IDS(&intel_valleyview_d_info),	\
-	INTEL_BDW_GT12M_IDS(&intel_broadwell_m_info),	\
-	INTEL_BDW_GT12D_IDS(&intel_broadwell_d_info),	\
-	INTEL_BDW_GT3M_IDS(&intel_broadwell_gt3m_info),	\
-	INTEL_BDW_GT3D_IDS(&intel_broadwell_gt3d_info), \
-	INTEL_CHV_IDS(&intel_cherryview_info),	\
-	INTEL_SKL_GT1_IDS(&intel_skylake_info),	\
-	INTEL_SKL_GT2_IDS(&intel_skylake_info),	\
-	INTEL_SKL_GT3_IDS(&intel_skylake_gt3_info),	\
-	INTEL_BXT_IDS(&intel_broxton_info)
-
-static const struct pci_device_id pciidlist[] = {		/* aka */
-	INTEL_PCI_IDS,
+static const struct pci_device_id pciidlist[] = {
+	INTEL_I830_IDS(&intel_i830_info),
+	INTEL_I845G_IDS(&intel_845g_info),
+	INTEL_I85X_IDS(&intel_i85x_info),
+	INTEL_I865G_IDS(&intel_i865g_info),
+	INTEL_I915G_IDS(&intel_i915g_info),
+	INTEL_I915GM_IDS(&intel_i915gm_info),
+	INTEL_I945G_IDS(&intel_i945g_info),
+	INTEL_I945GM_IDS(&intel_i945gm_info),
+	INTEL_I965G_IDS(&intel_i965g_info),
+	INTEL_G33_IDS(&intel_g33_info),
+	INTEL_I965GM_IDS(&intel_i965gm_info),
+	INTEL_GM45_IDS(&intel_gm45_info),
+	INTEL_G45_IDS(&intel_g45_info),
+	INTEL_PINEVIEW_IDS(&intel_pineview_info),
+	INTEL_IRONLAKE_D_IDS(&intel_ironlake_d_info),
+	INTEL_IRONLAKE_M_IDS(&intel_ironlake_m_info),
+	INTEL_SNB_D_IDS(&intel_sandybridge_d_info),
+	INTEL_SNB_M_IDS(&intel_sandybridge_m_info),
+	INTEL_IVB_Q_IDS(&intel_ivybridge_q_info), /* must be first IVB */
+	INTEL_IVB_M_IDS(&intel_ivybridge_m_info),
+	INTEL_IVB_D_IDS(&intel_ivybridge_d_info),
+	INTEL_HSW_D_IDS(&intel_haswell_d_info),
+	INTEL_HSW_M_IDS(&intel_haswell_m_info),
+	INTEL_VLV_M_IDS(&intel_valleyview_m_info),
+	INTEL_VLV_D_IDS(&intel_valleyview_d_info),
+	INTEL_BDW_GT12M_IDS(&intel_broadwell_m_info),
+	INTEL_BDW_GT12D_IDS(&intel_broadwell_d_info),
+	INTEL_BDW_GT3M_IDS(&intel_broadwell_gt3m_info),
+	INTEL_BDW_GT3D_IDS(&intel_broadwell_gt3d_info),
+	INTEL_CHV_IDS(&intel_cherryview_info),
 	{0, 0, 0}
 };
 
@@ -531,7 +524,10 @@ void intel_detect_pch(struct drm_device
 				dev_priv->pch_type = PCH_SPT;
 				DRM_DEBUG_KMS("Found SunrisePoint LP PCH\n");
 				WARN_ON(!IS_SKYLAKE(dev));
-			} else if (id == INTEL_PCH_P2X_DEVICE_ID_TYPE) {
+			} else if ((id == INTEL_PCH_P2X_DEVICE_ID_TYPE) ||
+				   ((id == INTEL_PCH_QEMU_DEVICE_ID_TYPE) &&
+				    pch->subsystem_vendor == 0x1af4 &&
+				    pch->subsystem_device == 0x1100)) {
 				dev_priv->pch_type = intel_virt_detect_pch(dev);
 			} else
 				continue;
@@ -1546,6 +1542,9 @@ static int intel_runtime_suspend(struct
 
 	assert_forcewakes_inactive(dev_priv);
 
+	if (!IS_VALLEYVIEW(dev_priv) || !IS_CHERRYVIEW(dev_priv))
+		intel_hpd_poll_init(dev_priv);
+
 	DRM_DEBUG_KMS("Device suspended\n");
 	return 0;
 }
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/i915/i915_drv.h
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/i915/i915_drv.h
@@ -249,6 +249,9 @@ struct i915_hotplug {
 	u32 short_port_mask;
 	struct work_struct dig_port_work;
 
+	struct work_struct poll_init_work;
+	bool poll_enabled;
+
 	/*
 	 * if we get a HPD irq from DP and a HPD irq from non-DP
 	 * the non-DP HPD could block the workqueue on a mode config
@@ -2614,6 +2617,7 @@ struct drm_i915_cmd_table {
 #define INTEL_PCH_SPT_DEVICE_ID_TYPE		0xA100
 #define INTEL_PCH_SPT_LP_DEVICE_ID_TYPE		0x9D00
 #define INTEL_PCH_P2X_DEVICE_ID_TYPE		0x7100
+#define INTEL_PCH_QEMU_DEVICE_ID_TYPE		0x2900 /* qemu q35 has 2918 */
 
 #define INTEL_PCH_TYPE(dev) (__I915__(dev)->pch_type)
 #define HAS_PCH_SPT(dev) (INTEL_PCH_TYPE(dev) == PCH_SPT)
@@ -2706,6 +2710,8 @@ void intel_hpd_init(struct drm_i915_priv
 void intel_hpd_init_work(struct drm_i915_private *dev_priv);
 void intel_hpd_cancel_work(struct drm_i915_private *dev_priv);
 bool intel_hpd_pin_to_port(enum hpd_pin pin, enum port *port);
+bool intel_hpd_disable(struct drm_i915_private *dev_priv, enum hpd_pin pin);
+void intel_hpd_enable(struct drm_i915_private *dev_priv, enum hpd_pin pin);
 
 /* i915_irq.c */
 void i915_queue_hangcheck(struct drm_device *dev);
@@ -3312,6 +3318,9 @@ static inline bool intel_gmbus_is_forced
 }
 extern void intel_i2c_reset(struct drm_device *dev);
 
+/* intel_bios.c */
+bool intel_bios_is_port_present(struct drm_i915_private *dev_priv, enum port port);
+
 /* intel_opregion.c */
 #ifdef CONFIG_ACPI
 extern int intel_opregion_setup(struct drm_device *dev);
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/i915/i915_gem_context.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/i915/i915_gem_context.c
@@ -340,6 +340,10 @@ void i915_gem_context_reset(struct drm_d
 			i915_gem_context_unreference(lctx);
 			ring->last_context = NULL;
 		}
+
+		/* Force the GPU state to be reinitialised on enabling */
+		if (ring->default_context)
+			ring->default_context->legacy_hw_ctx.initialized = false;
 	}
 }
 
@@ -708,7 +712,7 @@ static int do_switch(struct drm_i915_gem
 	if (ret)
 		goto unpin_out;
 
-	if (!to->legacy_hw_ctx.initialized) {
+	if (!to->legacy_hw_ctx.initialized || i915_gem_context_is_default(to)) {
 		hw_flags |= MI_RESTORE_INHIBIT;
 		/* NB: If we inhibit the restore, the context is not allowed to
 		 * die because future work may end up depending on valid address
@@ -923,6 +927,14 @@ int i915_gem_context_getparam_ioctl(stru
 	case I915_CONTEXT_PARAM_NO_ZEROMAP:
 		args->value = ctx->flags & CONTEXT_NO_ZEROMAP;
 		break;
+	case I915_CONTEXT_PARAM_GTT_SIZE:
+		if (ctx->ppgtt)
+			args->value = ctx->ppgtt->base.total;
+		else if (to_i915(dev)->mm.aliasing_ppgtt)
+			args->value = to_i915(dev)->mm.aliasing_ppgtt->base.total;
+		else
+			args->value = to_i915(dev)->gtt.base.total;
+		break;
 	default:
 		ret = -EINVAL;
 		break;
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -2747,6 +2747,7 @@ void i915_global_gtt_cleanup(struct drm_
 		struct i915_hw_ppgtt *ppgtt = dev_priv->mm.aliasing_ppgtt;
 
 		ppgtt->base.cleanup(&ppgtt->base);
+		kfree(ppgtt);
 	}
 
 	if (drm_mm_initialized(&vm->mm)) {
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/i915/i915_gem_shrinker.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/i915/i915_gem_shrinker.c
@@ -39,7 +39,7 @@ static bool mutex_is_locked_by(struct mu
 	if (!mutex_is_locked(mutex))
 		return false;
 
-#if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_MUTEXES)
+#if defined(CONFIG_DEBUG_MUTEXES) || defined(CONFIG_MUTEX_SPIN_ON_OWNER)
 	return mutex->owner == task;
 #else
 	/* Since UP may be pre-empted, we cannot assume that we own the lock */
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/i915/i915_irq.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/i915/i915_irq.c
@@ -2354,9 +2354,13 @@ static irqreturn_t gen8_irq_handler(int
 				spt_irq_handler(dev, pch_iir);
 			else
 				cpt_irq_handler(dev, pch_iir);
-		} else
-			DRM_ERROR("The master control interrupt lied (SDE)!\n");
-
+		} else {
+			/*
+			 * Like on previous PCH there seems to be something
+			 * fishy going on with forwarding PCH interrupts.
+			 */
+			DRM_DEBUG_DRIVER("The master control interrupt lied (SDE)!\n");
+		}
 	}
 
 	I915_WRITE_FW(GEN8_MASTER_IRQ, GEN8_MASTER_IRQ_CONTROL);
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/i915/i915_reg.h
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/i915/i915_reg.h
@@ -2838,7 +2838,14 @@ enum skl_disp_power_wells {
 #define GEN6_RP_STATE_CAP	(MCHBAR_MIRROR_BASE_SNB + 0x5998)
 #define BXT_RP_STATE_CAP        0x138170
 
-#define INTERVAL_1_28_US(us)	(((us) * 100) >> 7)
+/*
+ * Make these a multiple of magic 25 to avoid SNB (eg. Dell XPS
+ * 8300) freezing up around GPU hangs. Looks as if even
+ * scheduling/timer interrupts start misbehaving if the RPS
+ * EI/thresholds are "bad", leading to a very sluggish or even
+ * frozen machine.
+ */
+#define INTERVAL_1_28_US(us)	roundup(((us) * 100) >> 7, 25)
 #define INTERVAL_1_33_US(us)	(((us) * 3)   >> 2)
 #define INTERVAL_0_833_US(us)	(((us) * 6) / 5)
 #define GT_INTERVAL_FROM_US(dev_priv, us) (IS_GEN9(dev_priv) ? \
@@ -3233,19 +3240,20 @@ enum skl_disp_power_wells {
 
 #define PORT_HOTPLUG_STAT	(dev_priv->info.display_mmio_offset + 0x61114)
 /*
- * HDMI/DP bits are gen4+
+ * HDMI/DP bits are g4x+
  *
  * WARNING: Bspec for hpd status bits on gen4 seems to be completely confused.
  * Please check the detailed lore in the commit message for for experimental
  * evidence.
  */
-#define   PORTD_HOTPLUG_LIVE_STATUS_G4X		(1 << 29)
+/* Bspec says GM45 should match G4X/VLV/CHV, but reality disagrees */
+#define   PORTD_HOTPLUG_LIVE_STATUS_GM45	(1 << 29)
+#define   PORTC_HOTPLUG_LIVE_STATUS_GM45	(1 << 28)
+#define   PORTB_HOTPLUG_LIVE_STATUS_GM45	(1 << 27)
+/* G4X/VLV/CHV DP/HDMI bits again match Bspec */
+#define   PORTD_HOTPLUG_LIVE_STATUS_G4X		(1 << 27)
 #define   PORTC_HOTPLUG_LIVE_STATUS_G4X		(1 << 28)
-#define   PORTB_HOTPLUG_LIVE_STATUS_G4X		(1 << 27)
-/* VLV DP/HDMI bits again match Bspec */
-#define   PORTD_HOTPLUG_LIVE_STATUS_VLV		(1 << 27)
-#define   PORTC_HOTPLUG_LIVE_STATUS_VLV		(1 << 28)
-#define   PORTB_HOTPLUG_LIVE_STATUS_VLV		(1 << 29)
+#define   PORTB_HOTPLUG_LIVE_STATUS_G4X		(1 << 29)
 #define   PORTD_HOTPLUG_INT_STATUS		(3 << 21)
 #define   PORTD_HOTPLUG_INT_LONG_PULSE		(2 << 21)
 #define   PORTD_HOTPLUG_INT_SHORT_PULSE		(1 << 21)
@@ -7350,6 +7358,8 @@ enum skl_disp_power_wells {
 #define  TRANS_CLK_SEL_DISABLED		(0x0<<29)
 #define  TRANS_CLK_SEL_PORT(x)		(((x)+1)<<29)
 
+#define CDCLK_FREQ			0x46200
+
 #define TRANSA_MSA_MISC			0x60410
 #define TRANSB_MSA_MISC			0x61410
 #define TRANSC_MSA_MISC			0x62410
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/i915/intel_audio.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/i915/intel_audio.c
@@ -525,6 +525,10 @@ void intel_audio_codec_enable(struct int
 		dev_priv->display.audio_codec_enable(connector, intel_encoder,
 						     adjusted_mode);
 
+	mutex_lock(&dev_priv->av_mutex);
+	intel_dig_port->audio_connector = connector;
+	mutex_unlock(&dev_priv->av_mutex);
+
 	if (acomp && acomp->audio_ops && acomp->audio_ops->pin_eld_notify)
 		acomp->audio_ops->pin_eld_notify(acomp->audio_ops->audio_ptr, (int) port);
 }
@@ -548,6 +552,10 @@ void intel_audio_codec_disable(struct in
 	if (dev_priv->display.audio_codec_disable)
 		dev_priv->display.audio_codec_disable(intel_encoder);
 
+	mutex_lock(&dev_priv->av_mutex);
+	intel_dig_port->audio_connector = NULL;
+	mutex_unlock(&dev_priv->av_mutex);
+
 	if (acomp && acomp->audio_ops && acomp->audio_ops->pin_eld_notify)
 		acomp->audio_ops->pin_eld_notify(acomp->audio_ops->audio_ptr, (int) port);
 }
@@ -706,6 +714,39 @@ static int i915_audio_component_sync_aud
 	return 0;
 }
 
+static int i915_audio_component_get_eld(struct device *dev, int port,
+					bool *enabled,
+					unsigned char *buf, int max_bytes)
+{
+	struct drm_i915_private *dev_priv = dev_to_i915(dev);
+	struct drm_device *drm_dev = dev_priv->dev;
+	struct intel_encoder *intel_encoder;
+	struct intel_digital_port *intel_dig_port;
+	const u8 *eld;
+	int ret = -EINVAL;
+
+	mutex_lock(&dev_priv->av_mutex);
+	for_each_intel_encoder(drm_dev, intel_encoder) {
+		if (intel_encoder->type != INTEL_OUTPUT_DISPLAYPORT &&
+		    intel_encoder->type != INTEL_OUTPUT_HDMI)
+			continue;
+		intel_dig_port = enc_to_dig_port(&intel_encoder->base);
+		if (port == intel_dig_port->port) {
+			ret = 0;
+			*enabled = intel_dig_port->audio_connector != NULL;
+			if (!*enabled)
+				break;
+			eld = intel_dig_port->audio_connector->eld;
+			ret = drm_eld_size(eld);
+			memcpy(buf, eld, min(max_bytes, ret));
+			break;
+		}
+	}
+
+	mutex_unlock(&dev_priv->av_mutex);
+	return ret;
+}
+
 static const struct i915_audio_component_ops i915_audio_component_ops = {
 	.owner		= THIS_MODULE,
 	.get_power	= i915_audio_component_get_power,
@@ -713,6 +754,7 @@ static const struct i915_audio_component
 	.codec_wake_override = i915_audio_component_codec_wake_override,
 	.get_cdclk_freq	= i915_audio_component_get_cdclk_freq,
 	.sync_audio_rate = i915_audio_component_sync_audio_rate,
+	.get_eld	= i915_audio_component_get_eld,
 };
 
 static int i915_audio_component_bind(struct device *i915_dev,
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/i915/intel_bios.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/i915/intel_bios.c
@@ -1351,3 +1351,42 @@ intel_parse_bios(struct drm_device *dev)
 
 	return 0;
 }
+
+/**
+ * intel_bios_is_port_present - is the specified digital port present
+ * @dev_priv:	i915 device instance
+ * @port:	port to check
+ *
+ * Return true if the device in %port is present.
+ */
+bool intel_bios_is_port_present(struct drm_i915_private *dev_priv, enum port port)
+{
+	static const struct {
+		u16 dp, hdmi;
+	} port_mapping[] = {
+		[PORT_B] = { DVO_PORT_DPB, DVO_PORT_HDMIB, },
+		[PORT_C] = { DVO_PORT_DPC, DVO_PORT_HDMIC, },
+		[PORT_D] = { DVO_PORT_DPD, DVO_PORT_HDMID, },
+		[PORT_E] = { DVO_PORT_DPE, DVO_PORT_HDMIE, },
+	};
+	int i;
+
+	/* FIXME maybe deal with port A as well? */
+	if (WARN_ON(port == PORT_A) || port >= ARRAY_SIZE(port_mapping))
+		return false;
+
+	if (!dev_priv->vbt.child_dev_num)
+		return false;
+
+	for (i = 0; i < dev_priv->vbt.child_dev_num; i++) {
+		const union child_device_config *p_child =
+			&dev_priv->vbt.child_dev[i];
+		if ((p_child->common.dvo_port == port_mapping[port].dp ||
+		     p_child->common.dvo_port == port_mapping[port].hdmi) &&
+		    (p_child->common.device_type & (DEVICE_TYPE_TMDS_DVI_SIGNALING |
+						    DEVICE_TYPE_DISPLAYPORT_OUTPUT)))
+			return true;
+	}
+
+	return false;
+}
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/i915/intel_crt.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/i915/intel_crt.c
@@ -248,8 +248,14 @@ static bool intel_crt_compute_config(str
 		pipe_config->has_pch_encoder = true;
 
 	/* LPT FDI RX only supports 8bpc. */
-	if (HAS_PCH_LPT(dev))
+	if (HAS_PCH_LPT(dev)) {
+		if (pipe_config->bw_constrained && pipe_config->pipe_bpp < 24) {
+			DRM_DEBUG_KMS("LPT only supports 24bpp\n");
+			return false;
+		}
+
 		pipe_config->pipe_bpp = 24;
+	}
 
 	/* FDI must always be 2.7 GHz */
 	if (HAS_DDI(dev)) {
@@ -314,10 +320,25 @@ static bool valleyview_crt_detect_hotplu
 	struct drm_device *dev = connector->dev;
 	struct intel_crt *crt = intel_attached_crt(connector);
 	struct drm_i915_private *dev_priv = dev->dev_private;
+	bool reenable_hpd;
 	u32 adpa;
 	bool ret;
 	u32 save_adpa;
 
+	/*
+	 * Doing a force trigger causes a hpd interrupt to get sent, which can
+	 * get us stuck in a loop if we're polling:
+	 *  - We enable power wells and reset the ADPA
+	 *  - output_poll_exec does force probe on VGA, triggering a hpd
+	 *  - HPD handler waits for poll to unlock dev->mode_config.mutex
+	 *  - output_poll_exec shuts off the ADPA, unlocks
+	 *    dev->mode_config.mutex
+	 *  - HPD handler runs, resets ADPA and brings us back to the start
+	 *
+	 * Just disable HPD interrupts here to prevent this
+	 */
+	reenable_hpd = intel_hpd_disable(dev_priv, crt->base.hpd_pin);
+
 	save_adpa = adpa = I915_READ(crt->adpa_reg);
 	DRM_DEBUG_KMS("trigger hotplug detect cycle: adpa=0x%x\n", adpa);
 
@@ -340,6 +361,9 @@ static bool valleyview_crt_detect_hotplu
 
 	DRM_DEBUG_KMS("valleyview hotplug adpa=0x%x, result %d\n", adpa, ret);
 
+	if (reenable_hpd)
+		intel_hpd_enable(dev_priv, crt->base.hpd_pin);
+
 	return ret;
 }
 
@@ -702,11 +726,11 @@ static int intel_crt_set_property(struct
 	return 0;
 }
 
-static void intel_crt_reset(struct drm_connector *connector)
+void intel_crt_reset(struct drm_encoder *encoder)
 {
-	struct drm_device *dev = connector->dev;
+	struct drm_device *dev = encoder->dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
-	struct intel_crt *crt = intel_attached_crt(connector);
+	struct intel_crt *crt = intel_encoder_to_crt(to_intel_encoder(encoder));
 
 	if (INTEL_INFO(dev)->gen >= 5) {
 		u32 adpa;
@@ -728,7 +752,6 @@ static void intel_crt_reset(struct drm_c
  */
 
 static const struct drm_connector_funcs intel_crt_connector_funcs = {
-	.reset = intel_crt_reset,
 	.dpms = drm_atomic_helper_connector_dpms,
 	.detect = intel_crt_detect,
 	.fill_modes = drm_helper_probe_single_connector_modes,
@@ -746,6 +769,7 @@ static const struct drm_connector_helper
 };
 
 static const struct drm_encoder_funcs intel_crt_enc_funcs = {
+	.reset = intel_crt_reset,
 	.destroy = intel_encoder_destroy,
 };
 
@@ -870,5 +894,5 @@ void intel_crt_init(struct drm_device *d
 		dev_priv->fdi_rx_config = I915_READ(FDI_RX_CTL(PIPE_A)) & fdi_config;
 	}
 
-	intel_crt_reset(connector);
+	intel_crt_reset(&crt->base.base);
 }
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/i915/intel_csr.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/i915/intel_csr.c
@@ -180,7 +180,8 @@ struct stepping_info {
 static const struct stepping_info skl_stepping_info[] = {
 		{'A', '0'}, {'B', '0'}, {'C', '0'},
 		{'D', '0'}, {'E', '0'}, {'F', '0'},
-		{'G', '0'}, {'H', '0'}, {'I', '0'}
+		{'G', '0'}, {'H', '0'}, {'I', '0'},
+		{'J', '0'}, {'K', '0'}
 };
 
 static struct stepping_info bxt_stepping_info[] = {
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/i915/intel_ddi.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/i915/intel_ddi.c
@@ -464,9 +464,17 @@ static void intel_prepare_ddi_buffers(st
 	} else if (IS_BROADWELL(dev)) {
 		ddi_translations_fdi = bdw_ddi_translations_fdi;
 		ddi_translations_dp = bdw_ddi_translations_dp;
-		ddi_translations_edp = bdw_ddi_translations_edp;
+
+		if (dev_priv->edp_low_vswing) {
+			ddi_translations_edp = bdw_ddi_translations_edp;
+			n_edp_entries = ARRAY_SIZE(bdw_ddi_translations_edp);
+		} else {
+			ddi_translations_edp = bdw_ddi_translations_dp;
+			n_edp_entries = ARRAY_SIZE(bdw_ddi_translations_dp);
+		}
+
 		ddi_translations_hdmi = bdw_ddi_translations_hdmi;
-		n_edp_entries = ARRAY_SIZE(bdw_ddi_translations_edp);
+
 		n_dp_entries = ARRAY_SIZE(bdw_ddi_translations_dp);
 		n_hdmi_entries = ARRAY_SIZE(bdw_ddi_translations_hdmi);
 		hdmi_default_entry = 7;
@@ -1582,7 +1590,8 @@ skl_ddi_pll_select(struct intel_crtc *in
 			 DPLL_CFGCR2_KDIV(wrpll_params.kdiv) |
 			 DPLL_CFGCR2_PDIV(wrpll_params.pdiv) |
 			 wrpll_params.central_freq;
-	} else if (intel_encoder->type == INTEL_OUTPUT_DISPLAYPORT) {
+	} else if (intel_encoder->type == INTEL_OUTPUT_DISPLAYPORT ||
+		   intel_encoder->type == INTEL_OUTPUT_DP_MST) {
 		switch (crtc_state->port_clock / 2) {
 		case 81000:
 			ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_810, 0);
@@ -3187,12 +3196,6 @@ void intel_ddi_get_config(struct intel_e
 	intel_ddi_clock_get(encoder, pipe_config);
 }
 
-static void intel_ddi_destroy(struct drm_encoder *encoder)
-{
-	/* HDMI has nothing special to destroy, so we can go with this. */
-	intel_dp_encoder_destroy(encoder);
-}
-
 static bool intel_ddi_compute_config(struct intel_encoder *encoder,
 				     struct intel_crtc_state *pipe_config)
 {
@@ -3211,7 +3214,8 @@ static bool intel_ddi_compute_config(str
 }
 
 static const struct drm_encoder_funcs intel_ddi_funcs = {
-	.destroy = intel_ddi_destroy,
+	.reset = intel_dp_encoder_reset,
+	.destroy = intel_dp_encoder_destroy,
 };
 
 static struct intel_connector *
@@ -3283,6 +3287,7 @@ void intel_ddi_init(struct drm_device *d
 	intel_encoder->post_disable = intel_ddi_post_disable;
 	intel_encoder->get_hw_state = intel_ddi_get_hw_state;
 	intel_encoder->get_config = intel_ddi_get_config;
+	intel_encoder->suspend = intel_dp_encoder_suspend;
 
 	intel_dig_port->port = port;
 	intel_dig_port->saved_port_bits = I915_READ(DDI_BUF_CTL(port)) &
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/i915/intel_display.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/i915/intel_display.c
@@ -2950,13 +2950,13 @@ u32 intel_fb_stride_alignment(struct drm
 	}
 }
 
-unsigned long intel_plane_obj_offset(struct intel_plane *intel_plane,
-				     struct drm_i915_gem_object *obj,
-				     unsigned int plane)
+u32 intel_plane_obj_offset(struct intel_plane *intel_plane,
+			   struct drm_i915_gem_object *obj,
+			   unsigned int plane)
 {
 	const struct i915_ggtt_view *view = &i915_ggtt_view_normal;
 	struct i915_vma *vma;
-	unsigned char *offset;
+	u64 offset;
 
 	if (intel_rotation_90_or_270(intel_plane->base.state->rotation))
 		view = &i915_ggtt_view_rotated;
@@ -2966,14 +2966,16 @@ unsigned long intel_plane_obj_offset(str
 		view->type))
 		return -1;
 
-	offset = (unsigned char *)vma->node.start;
+	offset = vma->node.start;
 
 	if (plane == 1) {
 		offset += vma->ggtt_view.rotation_info.uv_start_page *
 			  PAGE_SIZE;
 	}
 
-	return (unsigned long)offset;
+	WARN_ON(upper_32_bits(offset));
+
+	return lower_32_bits(offset);
 }
 
 static void skl_detach_scaler(struct intel_crtc *intel_crtc, int id)
@@ -3099,7 +3101,7 @@ static void skylake_update_primary_plane
 	u32 tile_height, plane_offset, plane_size;
 	unsigned int rotation;
 	int x_offset, y_offset;
-	unsigned long surf_addr;
+	u32 surf_addr;
 	struct intel_crtc_state *crtc_state = intel_crtc->config;
 	struct intel_plane_state *plane_state;
 	int src_x = 0, src_y = 0, src_w = 0, src_h = 0;
@@ -4447,7 +4449,7 @@ int skl_update_scaler_crtc(struct intel_
 		      intel_crtc->base.base.id, intel_crtc->pipe, SKL_CRTC_INDEX);
 
 	return skl_update_scaler(state, !state->base.active, SKL_CRTC_INDEX,
-		&state->scaler_state.scaler_id, DRM_ROTATE_0,
+		&state->scaler_state.scaler_id, BIT(DRM_ROTATE_0),
 		state->pipe_src_w, state->pipe_src_h,
 		adjusted_mode->crtc_hdisplay, adjusted_mode->crtc_vdisplay);
 }
@@ -6447,13 +6449,11 @@ static void intel_connector_check_state(
 
 int intel_connector_init(struct intel_connector *connector)
 {
-	struct drm_connector_state *connector_state;
+	drm_atomic_helper_connector_reset(&connector->base);
 
-	connector_state = kzalloc(sizeof *connector_state, GFP_KERNEL);
-	if (!connector_state)
+	if (!connector->base.state)
 		return -ENOMEM;
 
-	connector->base.state = connector_state;
 	return 0;
 }
 
@@ -8228,12 +8228,14 @@ static void ironlake_init_pch_refclk(str
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct intel_encoder *encoder;
+	int i;
 	u32 val, final;
 	bool has_lvds = false;
 	bool has_cpu_edp = false;
 	bool has_panel = false;
 	bool has_ck505 = false;
 	bool can_ssc = false;
+	bool using_ssc_source = false;
 
 	/* We need to take the global config into account */
 	for_each_intel_encoder(dev, encoder) {
@@ -8260,8 +8262,22 @@ static void ironlake_init_pch_refclk(str
 		can_ssc = true;
 	}
 
-	DRM_DEBUG_KMS("has_panel %d has_lvds %d has_ck505 %d\n",
-		      has_panel, has_lvds, has_ck505);
+	/* Check if any DPLLs are using the SSC source */
+	for (i = 0; i < dev_priv->num_shared_dpll; i++) {
+		u32 temp = I915_READ(PCH_DPLL(i));
+
+		if (!(temp & DPLL_VCO_ENABLE))
+			continue;
+
+		if ((temp & PLL_REF_INPUT_MASK) ==
+		    PLLB_REF_INPUT_SPREADSPECTRUMIN) {
+			using_ssc_source = true;
+			break;
+		}
+	}
+
+	DRM_DEBUG_KMS("has_panel %d has_lvds %d has_ck505 %d using_ssc_source %d\n",
+		      has_panel, has_lvds, has_ck505, using_ssc_source);
 
 	/* Ironlake: try to setup display ref clock before DPLL
 	 * enabling. This is only under driver's control after
@@ -8298,9 +8314,9 @@ static void ironlake_init_pch_refclk(str
 				final |= DREF_CPU_SOURCE_OUTPUT_NONSPREAD;
 		} else
 			final |= DREF_CPU_SOURCE_OUTPUT_DISABLE;
-	} else {
-		final |= DREF_SSC_SOURCE_DISABLE;
-		final |= DREF_CPU_SOURCE_OUTPUT_DISABLE;
+	} else if (using_ssc_source) {
+		final |= DREF_SSC_SOURCE_ENABLE;
+		final |= DREF_SSC1_ENABLE;
 	}
 
 	if (final == val)
@@ -8346,7 +8362,7 @@ static void ironlake_init_pch_refclk(str
 		POSTING_READ(PCH_DREF_CONTROL);
 		udelay(200);
 	} else {
-		DRM_DEBUG_KMS("Disabling SSC entirely\n");
+		DRM_DEBUG_KMS("Disabling CPU source output\n");
 
 		val &= ~DREF_CPU_SOURCE_OUTPUT_MASK;
 
@@ -8357,16 +8373,20 @@ static void ironlake_init_pch_refclk(str
 		POSTING_READ(PCH_DREF_CONTROL);
 		udelay(200);
 
-		/* Turn off the SSC source */
-		val &= ~DREF_SSC_SOURCE_MASK;
-		val |= DREF_SSC_SOURCE_DISABLE;
+		if (!using_ssc_source) {
+			DRM_DEBUG_KMS("Disabling SSC source\n");
 
-		/* Turn off SSC1 */
-		val &= ~DREF_SSC1_ENABLE;
+			/* Turn off the SSC source */
+			val &= ~DREF_SSC_SOURCE_MASK;
+			val |= DREF_SSC_SOURCE_DISABLE;
 
-		I915_WRITE(PCH_DREF_CONTROL, val);
-		POSTING_READ(PCH_DREF_CONTROL);
-		udelay(200);
+			/* Turn off SSC1 */
+			val &= ~DREF_SSC1_ENABLE;
+
+			I915_WRITE(PCH_DREF_CONTROL, val);
+			POSTING_READ(PCH_DREF_CONTROL);
+			udelay(200);
+		}
 	}
 
 	BUG_ON(val != final);
@@ -9669,6 +9689,8 @@ static void broadwell_set_cdclk(struct d
 	sandybridge_pcode_write(dev_priv, HSW_PCODE_DE_WRITE_FREQ_REQ, data);
 	mutex_unlock(&dev_priv->rps.hw_lock);
 
+	I915_WRITE(CDCLK_FREQ, DIV_ROUND_CLOSEST(cdclk, 1000) - 1);
+
 	intel_update_cdclk(dev);
 
 	WARN(cdclk != dev_priv->cdclk_freq,
@@ -13537,11 +13559,12 @@ intel_check_primary_plane(struct drm_pla
 	int max_scale = DRM_PLANE_HELPER_NO_SCALING;
 	bool can_position = false;
 
-	/* use scaler when colorkey is not required */
-	if (INTEL_INFO(plane->dev)->gen >= 9 &&
-	    state->ckey.flags == I915_SET_COLORKEY_NONE) {
-		min_scale = 1;
-		max_scale = skl_max_scale(to_intel_crtc(crtc), crtc_state);
+	if (INTEL_INFO(plane->dev)->gen >= 9) {
+		/* use scaler when colorkey is not required */
+		if (state->ckey.flags == I915_SET_COLORKEY_NONE) {
+			min_scale = 1;
+			max_scale = skl_max_scale(to_intel_crtc(crtc), crtc_state);
+		}
 		can_position = true;
 	}
 
@@ -14137,6 +14160,8 @@ static void intel_setup_outputs(struct d
 		if (I915_READ(PCH_DP_D) & DP_DETECTED)
 			intel_dp_init(dev, PCH_DP_D, PORT_D);
 	} else if (IS_VALLEYVIEW(dev)) {
+		bool has_edp, has_port;
+
 		/*
 		 * The DP_DETECTED bit is the latched state of the DDC
 		 * SDA pin at boot. However since eDP doesn't require DDC
@@ -14145,27 +14170,37 @@ static void intel_setup_outputs(struct d
 		 * Thus we can't rely on the DP_DETECTED bit alone to detect
 		 * eDP ports. Consult the VBT as well as DP_DETECTED to
 		 * detect eDP ports.
+		 *
+		 * Sadly the straps seem to be missing sometimes even for HDMI
+		 * ports (eg. on Voyo V3 - CHT x7-Z8700), so check both strap
+		 * and VBT for the presence of the port. Additionally we can't
+		 * trust the port type the VBT declares as we've seen at least
+		 * HDMI ports that the VBT claim are DP or eDP.
 		 */
-		if (I915_READ(VLV_HDMIB) & SDVO_DETECTED &&
-		    !intel_dp_is_edp(dev, PORT_B))
+		has_edp = intel_dp_is_edp(dev, PORT_B);
+		has_port = intel_bios_is_port_present(dev_priv, PORT_B);
+		if (I915_READ(VLV_DP_B) & DP_DETECTED || has_port)
+			has_edp &= intel_dp_init(dev, VLV_DP_B, PORT_B);
+		if ((I915_READ(VLV_HDMIB) & SDVO_DETECTED || has_port) && !has_edp)
 			intel_hdmi_init(dev, VLV_HDMIB, PORT_B);
-		if (I915_READ(VLV_DP_B) & DP_DETECTED ||
-		    intel_dp_is_edp(dev, PORT_B))
-			intel_dp_init(dev, VLV_DP_B, PORT_B);
 
-		if (I915_READ(VLV_HDMIC) & SDVO_DETECTED &&
-		    !intel_dp_is_edp(dev, PORT_C))
+		has_edp = intel_dp_is_edp(dev, PORT_C);
+		has_port = intel_bios_is_port_present(dev_priv, PORT_C);
+		if (I915_READ(VLV_DP_C) & DP_DETECTED || has_port)
+			has_edp &= intel_dp_init(dev, VLV_DP_C, PORT_C);
+		if ((I915_READ(VLV_HDMIC) & SDVO_DETECTED || has_port) && !has_edp)
 			intel_hdmi_init(dev, VLV_HDMIC, PORT_C);
-		if (I915_READ(VLV_DP_C) & DP_DETECTED ||
-		    intel_dp_is_edp(dev, PORT_C))
-			intel_dp_init(dev, VLV_DP_C, PORT_C);
 
 		if (IS_CHERRYVIEW(dev)) {
-			/* eDP not supported on port D, so don't check VBT */
-			if (I915_READ(CHV_HDMID) & SDVO_DETECTED)
-				intel_hdmi_init(dev, CHV_HDMID, PORT_D);
-			if (I915_READ(CHV_DP_D) & DP_DETECTED)
+			/*
+			 * eDP not supported on port D,
+			 * so no need to worry about it
+			 */
+			has_port = intel_bios_is_port_present(dev_priv, PORT_D);
+			if (I915_READ(CHV_DP_D) & DP_DETECTED || has_port)
 				intel_dp_init(dev, CHV_DP_D, PORT_D);
+			if (I915_READ(CHV_HDMID) & SDVO_DETECTED || has_port)
+				intel_hdmi_init(dev, CHV_HDMID, PORT_D);
 		}
 
 		intel_dsi_init(dev);
@@ -15113,6 +15148,8 @@ static void intel_sanitize_crtc(struct i
 		WARN_ON(drm_atomic_set_mode_for_crtc(crtc->base.state, NULL) < 0);
 		crtc->base.state->active = crtc->active;
 		crtc->base.enabled = crtc->active;
+		crtc->base.state->connector_mask = 0;
+		crtc->base.state->encoder_mask = 0;
 
 		/* Because we only establish the connector -> encoder ->
 		 * crtc links if something is active, this means the
@@ -15315,7 +15352,23 @@ static void intel_modeset_readout_hw_sta
 	for_each_intel_connector(dev, connector) {
 		if (connector->get_hw_state(connector)) {
 			connector->base.dpms = DRM_MODE_DPMS_ON;
-			connector->base.encoder = &connector->encoder->base;
+
+			encoder = connector->encoder;
+			connector->base.encoder = &encoder->base;
+
+			if (encoder->base.crtc &&
+			    encoder->base.crtc->state->active) {
+				/*
+				 * This has to be done during hardware readout
+				 * because anything calling .crtc_disable may
+				 * rely on the connector_mask being accurate.
+				 */
+				encoder->base.crtc->state->connector_mask |=
+					1 << drm_connector_index(&connector->base);
+				encoder->base.crtc->state->encoder_mask |=
+					1 << drm_encoder_index(&encoder->base);
+			}
+
 		} else {
 			connector->base.dpms = DRM_MODE_DPMS_OFF;
 			connector->base.encoder = NULL;
@@ -15565,6 +15618,8 @@ void intel_modeset_cleanup(struct drm_de
 	mutex_lock(&dev->struct_mutex);
 	intel_cleanup_gt_powersave(dev);
 	mutex_unlock(&dev->struct_mutex);
+
+	intel_teardown_gmbus(dev);
 }
 
 /*
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/i915/intel_dp.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/i915/intel_dp.c
@@ -3628,8 +3628,7 @@ static bool
 intel_dp_reset_link_train(struct intel_dp *intel_dp, uint32_t *DP,
 			uint8_t dp_train_pat)
 {
-	if (!intel_dp->train_set_valid)
-		memset(intel_dp->train_set, 0, sizeof(intel_dp->train_set));
+	memset(intel_dp->train_set, 0, sizeof(intel_dp->train_set));
 	intel_dp_set_signal_levels(intel_dp, DP);
 	return intel_dp_set_link_train(intel_dp, DP, dp_train_pat);
 }
@@ -3746,22 +3745,6 @@ intel_dp_link_training_clock_recovery(st
 			break;
 		}
 
-		/*
-		 * if we used previously trained voltage and pre-emphasis values
-		 * and we don't get clock recovery, reset link training values
-		 */
-		if (intel_dp->train_set_valid) {
-			DRM_DEBUG_KMS("clock recovery not ok, reset");
-			/* clear the flag as we are not reusing train set */
-			intel_dp->train_set_valid = false;
-			if (!intel_dp_reset_link_train(intel_dp, &DP,
-						       DP_TRAINING_PATTERN_1 |
-						       DP_LINK_SCRAMBLING_DISABLE)) {
-				DRM_ERROR("failed to enable link training\n");
-				return;
-			}
-			continue;
-		}
 
 		/* Check to see if we've tried the max voltage */
 		for (i = 0; i < intel_dp->lane_count; i++)
@@ -3854,7 +3837,6 @@ intel_dp_link_training_channel_equalizat
 		/* Make sure clock is still ok */
 		if (!drm_dp_clock_recovery_ok(link_status,
 					      intel_dp->lane_count)) {
-			intel_dp->train_set_valid = false;
 			intel_dp_link_training_clock_recovery(intel_dp);
 			intel_dp_set_link_train(intel_dp, &DP,
 						training_pattern |
@@ -3871,7 +3853,6 @@ intel_dp_link_training_channel_equalizat
 
 		/* Try 5 times, then try clock recovery if that fails */
 		if (tries > 5) {
-			intel_dp->train_set_valid = false;
 			intel_dp_link_training_clock_recovery(intel_dp);
 			intel_dp_set_link_train(intel_dp, &DP,
 						training_pattern |
@@ -3893,10 +3874,8 @@ intel_dp_link_training_channel_equalizat
 
 	intel_dp->DP = DP;
 
-	if (channel_eq) {
-		intel_dp->train_set_valid = true;
+	if (channel_eq)
 		DRM_DEBUG_KMS("Channel EQ done. DP Training successful\n");
-	}
 }
 
 void intel_dp_stop_link_train(struct intel_dp *intel_dp)
@@ -4613,20 +4592,20 @@ static bool g4x_digital_port_connected(s
 	return I915_READ(PORT_HOTPLUG_STAT) & bit;
 }
 
-static bool vlv_digital_port_connected(struct drm_i915_private *dev_priv,
-				       struct intel_digital_port *port)
+static bool gm45_digital_port_connected(struct drm_i915_private *dev_priv,
+					struct intel_digital_port *port)
 {
 	u32 bit;
 
 	switch (port->port) {
 	case PORT_B:
-		bit = PORTB_HOTPLUG_LIVE_STATUS_VLV;
+		bit = PORTB_HOTPLUG_LIVE_STATUS_GM45;
 		break;
 	case PORT_C:
-		bit = PORTC_HOTPLUG_LIVE_STATUS_VLV;
+		bit = PORTC_HOTPLUG_LIVE_STATUS_GM45;
 		break;
 	case PORT_D:
-		bit = PORTD_HOTPLUG_LIVE_STATUS_VLV;
+		bit = PORTD_HOTPLUG_LIVE_STATUS_GM45;
 		break;
 	default:
 		MISSING_CASE(port->port);
@@ -4678,8 +4657,8 @@ bool intel_digital_port_connected(struct
 		return cpt_digital_port_connected(dev_priv, port);
 	else if (IS_BROXTON(dev_priv))
 		return bxt_digital_port_connected(dev_priv, port);
-	else if (IS_VALLEYVIEW(dev_priv))
-		return vlv_digital_port_connected(dev_priv, port);
+	else if (IS_GM45(dev_priv))
+		return gm45_digital_port_connected(dev_priv, port);
 	else
 		return g4x_digital_port_connected(dev_priv, port);
 }
@@ -5035,7 +5014,7 @@ void intel_dp_encoder_destroy(struct drm
 	kfree(intel_dig_port);
 }
 
-static void intel_dp_encoder_suspend(struct intel_encoder *intel_encoder)
+void intel_dp_encoder_suspend(struct intel_encoder *intel_encoder)
 {
 	struct intel_dp *intel_dp = enc_to_intel_dp(&intel_encoder->base);
 
@@ -5077,15 +5056,17 @@ static void intel_edp_panel_vdd_sanitize
 	edp_panel_vdd_schedule_off(intel_dp);
 }
 
-static void intel_dp_encoder_reset(struct drm_encoder *encoder)
+void intel_dp_encoder_reset(struct drm_encoder *encoder)
 {
-	struct intel_dp *intel_dp;
+	struct drm_i915_private *dev_priv = to_i915(encoder->dev);
+	struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
+
+	if (!HAS_DDI(dev_priv))
+		intel_dp->DP = I915_READ(intel_dp->output_reg);
 
 	if (to_intel_encoder(encoder)->type != INTEL_OUTPUT_EDP)
 		return;
 
-	intel_dp = enc_to_intel_dp(encoder);
-
 	pps_lock(intel_dp);
 
 	/*
@@ -5157,9 +5138,6 @@ intel_dp_hpd_pulse(struct intel_digital_
 	intel_display_power_get(dev_priv, power_domain);
 
 	if (long_hpd) {
-		/* indicate that we need to restart link training */
-		intel_dp->train_set_valid = false;
-
 		if (!intel_digital_port_connected(dev_priv, intel_dig_port))
 			goto mst_fail;
 
@@ -6135,8 +6113,9 @@ intel_dp_init_connector(struct intel_dig
 	return true;
 }
 
-void
-intel_dp_init(struct drm_device *dev, int output_reg, enum port port)
+bool intel_dp_init(struct drm_device *dev,
+		   int output_reg,
+		   enum port port)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct intel_digital_port *intel_dig_port;
@@ -6146,7 +6125,7 @@ intel_dp_init(struct drm_device *dev, in
 
 	intel_dig_port = kzalloc(sizeof(*intel_dig_port), GFP_KERNEL);
 	if (!intel_dig_port)
-		return;
+		return false;
 
 	intel_connector = intel_connector_alloc();
 	if (!intel_connector)
@@ -6201,15 +6180,14 @@ intel_dp_init(struct drm_device *dev, in
 	if (!intel_dp_init_connector(intel_dig_port, intel_connector))
 		goto err_init_connector;
 
-	return;
+	return true;
 
 err_init_connector:
 	drm_encoder_cleanup(encoder);
 	kfree(intel_connector);
 err_connector_alloc:
 	kfree(intel_dig_port);
-
-	return;
+	return false;
 }
 
 void intel_dp_mst_suspend(struct drm_device *dev)
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/i915/intel_dp_mst.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/i915/intel_dp_mst.c
@@ -477,6 +477,8 @@ static void intel_dp_destroy_mst_connect
 	struct intel_connector *intel_connector = to_intel_connector(connector);
 	struct drm_device *dev = connector->dev;
 
+	intel_connector->unregister(intel_connector);
+
 	/* need to nuke the connector */
 	drm_modeset_lock_all(dev);
 	if (connector->state->crtc) {
@@ -490,11 +492,7 @@ static void intel_dp_destroy_mst_connect
 
 		WARN(ret, "Disabling mst crtc failed with %i\n", ret);
 	}
-	drm_modeset_unlock_all(dev);
 
-	intel_connector->unregister(intel_connector);
-
-	drm_modeset_lock_all(dev);
 	intel_connector_remove_from_fbdev(intel_connector);
 	drm_connector_cleanup(connector);
 	drm_modeset_unlock_all(dev);
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/i915/intel_drv.h
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/i915/intel_drv.h
@@ -783,7 +783,6 @@ struct intel_dp {
 				     bool has_aux_irq,
 				     int send_bytes,
 				     uint32_t aux_clock_divider);
-	bool train_set_valid;
 
 	/* Displayport compliance testing */
 	unsigned long compliance_test_type;
@@ -799,6 +798,8 @@ struct intel_digital_port {
 	struct intel_hdmi hdmi;
 	enum irqreturn (*hpd_pulse)(struct intel_digital_port *, bool);
 	bool release_cl2_override;
+	/* for communication with audio component; protected by av_mutex */
+	const struct drm_connector *audio_connector;
 };
 
 struct intel_dp_mst_encoder {
@@ -970,7 +971,7 @@ void gen8_irq_power_well_post_enable(str
 
 /* intel_crt.c */
 void intel_crt_init(struct drm_device *dev);
-
+void intel_crt_reset(struct drm_encoder *encoder);
 
 /* intel_ddi.c */
 void intel_prepare_ddi(struct drm_device *dev);
@@ -1178,9 +1179,9 @@ void intel_modeset_preclose(struct drm_d
 int skl_update_scaler_crtc(struct intel_crtc_state *crtc_state);
 int skl_max_scale(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state);
 
-unsigned long intel_plane_obj_offset(struct intel_plane *intel_plane,
-				     struct drm_i915_gem_object *obj,
-				     unsigned int plane);
+u32 intel_plane_obj_offset(struct intel_plane *intel_plane,
+			   struct drm_i915_gem_object *obj,
+			   unsigned int plane);
 
 u32 skl_plane_ctl_format(uint32_t pixel_format);
 u32 skl_plane_ctl_tiling(uint64_t fb_modifier);
@@ -1196,7 +1197,7 @@ void intel_csr_ucode_fini(struct drm_dev
 void assert_csr_loaded(struct drm_i915_private *dev_priv);
 
 /* intel_dp.c */
-void intel_dp_init(struct drm_device *dev, int output_reg, enum port port);
+bool intel_dp_init(struct drm_device *dev, int output_reg, enum port port);
 bool intel_dp_init_connector(struct intel_digital_port *intel_dig_port,
 			     struct intel_connector *intel_connector);
 void intel_dp_set_link_params(struct intel_dp *intel_dp,
@@ -1204,6 +1205,8 @@ void intel_dp_set_link_params(struct int
 void intel_dp_start_link_train(struct intel_dp *intel_dp);
 void intel_dp_stop_link_train(struct intel_dp *intel_dp);
 void intel_dp_sink_dpms(struct intel_dp *intel_dp, int mode);
+void intel_dp_encoder_reset(struct drm_encoder *encoder);
+void intel_dp_encoder_suspend(struct intel_encoder *intel_encoder);
 void intel_dp_encoder_destroy(struct drm_encoder *encoder);
 int intel_dp_sink_crc(struct intel_dp *intel_dp, u8 *crc);
 bool intel_dp_compute_config(struct intel_encoder *encoder,
@@ -1243,6 +1246,8 @@ void intel_dsi_init(struct drm_device *d
 
 /* intel_dvo.c */
 void intel_dvo_init(struct drm_device *dev);
+/* intel_hotplug.c */
+void intel_hpd_poll_init(struct drm_i915_private *dev_priv);
 
 
 /* legacy fbdev emulation in intel_fbdev.c */
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c
@@ -207,7 +207,12 @@ static const u8 *mipi_exec_gpio(struct i
 	gpio = *data++;
 
 	/* pull up/down */
-	action = *data++;
+	action = *data++ & 1;
+
+	if (gpio >= ARRAY_SIZE(gtable)) {
+		DRM_DEBUG_KMS("unknown gpio %u\n", gpio);
+		goto out;
+	}
 
 	function = gtable[gpio].function_reg;
 	pad = gtable[gpio].pad_reg;
@@ -226,6 +231,7 @@ static const u8 *mipi_exec_gpio(struct i
 	vlv_gpio_nc_write(dev_priv, pad, val);
 	mutex_unlock(&dev_priv->sb_lock);
 
+out:
 	return data;
 }
 
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/i915/intel_fbdev.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/i915/intel_fbdev.c
@@ -362,12 +362,12 @@ static bool intel_fb_initial_config(stru
 	uint64_t conn_configured = 0, mask;
 	int pass = 0;
 
-	save_enabled = kcalloc(dev->mode_config.num_connector, sizeof(bool),
+	save_enabled = kcalloc(fb_helper->connector_count, sizeof(bool),
 			       GFP_KERNEL);
 	if (!save_enabled)
 		return false;
 
-	memcpy(save_enabled, enabled, dev->mode_config.num_connector);
+	memcpy(save_enabled, enabled, fb_helper->connector_count);
 	mask = (1 << fb_helper->connector_count) - 1;
 retry:
 	for (i = 0; i < fb_helper->connector_count; i++) {
@@ -501,7 +501,7 @@ retry:
 	if (fallback) {
 bail:
 		DRM_DEBUG_KMS("Not using firmware configuration\n");
-		memcpy(enabled, save_enabled, dev->mode_config.num_connector);
+		memcpy(enabled, save_enabled, fb_helper->connector_count);
 		kfree(save_enabled);
 		return false;
 	}
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/i915/intel_hdmi.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/i915/intel_hdmi.c
@@ -1388,8 +1388,16 @@ intel_hdmi_detect(struct drm_connector *
 				hdmi_to_dig_port(intel_hdmi));
 	}
 
-	if (!live_status)
-		DRM_DEBUG_KMS("Live status not up!");
+	if (!live_status) {
+		DRM_DEBUG_KMS("HDMI live status down\n");
+		/*
+		 * Live status register is not reliable on all intel platforms.
+		 * So consider live_status only for certain platforms, for
+		 * others, read EDID to determine presence of sink.
+		 */
+		if (INTEL_INFO(dev_priv)->gen < 7 || IS_IVYBRIDGE(dev_priv))
+			live_status = true;
+	}
 
 	intel_hdmi_unset_edid(connector);
 
@@ -2022,6 +2030,9 @@ void intel_hdmi_init_connector(struct in
 	enum port port = intel_dig_port->port;
 	uint8_t alternate_ddc_pin;
 
+	DRM_DEBUG_KMS("Adding HDMI connector on port %c\n",
+		      port_name(port));
+
 	drm_connector_init(dev, connector, &intel_hdmi_connector_funcs,
 			   DRM_MODE_CONNECTOR_HDMIA);
 	drm_connector_helper_add(connector, &intel_hdmi_connector_helper_funcs);
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/i915/intel_hotplug.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/i915/intel_hotplug.c
@@ -453,26 +453,20 @@ void intel_hpd_irq_handler(struct drm_de
  *
  * This is a separate step from interrupt enabling to simplify the locking rules
  * in the driver load and resume code.
+ *
+ * Also see: intel_hpd_poll_init(), which enables connector polling
  */
 void intel_hpd_init(struct drm_i915_private *dev_priv)
 {
-	struct drm_device *dev = dev_priv->dev;
-	struct drm_mode_config *mode_config = &dev->mode_config;
-	struct drm_connector *connector;
 	int i;
 
 	for_each_hpd_pin(i) {
 		dev_priv->hotplug.stats[i].count = 0;
 		dev_priv->hotplug.stats[i].state = HPD_ENABLED;
 	}
-	list_for_each_entry(connector, &mode_config->connector_list, head) {
-		struct intel_connector *intel_connector = to_intel_connector(connector);
-		connector->polled = intel_connector->polled;
-		if (connector->encoder && !connector->polled && I915_HAS_HOTPLUG(dev) && intel_connector->encoder->hpd_pin > HPD_NONE)
-			connector->polled = DRM_CONNECTOR_POLL_HPD;
-		if (intel_connector->mst_port)
-			connector->polled = DRM_CONNECTOR_POLL_HPD;
-	}
+
+	WRITE_ONCE(dev_priv->hotplug.poll_enabled, false);
+	schedule_work(&dev_priv->hotplug.poll_init_work);
 
 	/*
 	 * Interrupt setup is already guaranteed to be single-threaded, this is
@@ -480,14 +474,90 @@ void intel_hpd_init(struct drm_i915_priv
 	 */
 	spin_lock_irq(&dev_priv->irq_lock);
 	if (dev_priv->display.hpd_irq_setup)
-		dev_priv->display.hpd_irq_setup(dev);
+		dev_priv->display.hpd_irq_setup(dev_priv->dev);
 	spin_unlock_irq(&dev_priv->irq_lock);
 }
 
+void i915_hpd_poll_init_work(struct work_struct *work) {
+	struct drm_i915_private *dev_priv =
+		container_of(work, struct drm_i915_private,
+			     hotplug.poll_init_work);
+	struct drm_device *dev = dev_priv->dev;
+	struct drm_mode_config *mode_config = &dev->mode_config;
+	struct drm_connector *connector;
+	bool enabled;
+
+	mutex_lock(&dev->mode_config.mutex);
+
+	enabled = READ_ONCE(dev_priv->hotplug.poll_enabled);
+
+	list_for_each_entry(connector, &mode_config->connector_list, head) {
+		struct intel_connector *intel_connector =
+			to_intel_connector(connector);
+		connector->polled = intel_connector->polled;
+
+		/* MST has a dynamic intel_connector->encoder and it's reprobing
+		 * is all handled by the MST helpers. */
+		if (intel_connector->mst_port)
+			continue;
+
+		if (!connector->polled && I915_HAS_HOTPLUG(dev) &&
+		    intel_connector->encoder->hpd_pin > HPD_NONE) {
+			connector->polled = enabled ?
+				DRM_CONNECTOR_POLL_CONNECT |
+				DRM_CONNECTOR_POLL_DISCONNECT :
+				DRM_CONNECTOR_POLL_HPD;
+		}
+	}
+
+	if (enabled)
+		drm_kms_helper_poll_enable_locked(dev);
+
+	mutex_unlock(&dev->mode_config.mutex);
+
+	/*
+	 * We might have missed any hotplugs that happened while we were
+	 * in the middle of disabling polling
+	 */
+	if (!enabled)
+		drm_helper_hpd_irq_event(dev);
+}
+
+/**
+ * intel_hpd_poll_init - enables/disables polling for connectors with hpd
+ * @dev_priv: i915 device instance
+ * @enabled: Whether to enable or disable polling
+ *
+ * This function enables polling for all connectors, regardless of whether or
+ * not they support hotplug detection. Under certain conditions HPD may not be
+ * functional. On most Intel GPUs, this happens when we enter runtime suspend.
+ * On Valleyview and Cherryview systems, this also happens when we shut off all
+ * of the powerwells.
+ *
+ * Since this function can get called in contexts where we're already holding
+ * dev->mode_config.mutex, we do the actual hotplug enabling in a seperate
+ * worker.
+ *
+ * Also see: intel_hpd_init(), which restores hpd handling.
+ */
+void intel_hpd_poll_init(struct drm_i915_private *dev_priv)
+{
+	WRITE_ONCE(dev_priv->hotplug.poll_enabled, true);
+
+	/*
+	 * We might already be holding dev->mode_config.mutex, so do this in a
+	 * seperate worker
+	 * As well, there's no issue if we race here since we always reschedule
+	 * this worker anyway
+	 */
+	schedule_work(&dev_priv->hotplug.poll_init_work);
+}
+
 void intel_hpd_init_work(struct drm_i915_private *dev_priv)
 {
 	INIT_WORK(&dev_priv->hotplug.hotplug_work, i915_hotplug_work_func);
 	INIT_WORK(&dev_priv->hotplug.dig_port_work, i915_digport_work_func);
+	INIT_WORK(&dev_priv->hotplug.poll_init_work, i915_hpd_poll_init_work);
 	INIT_DELAYED_WORK(&dev_priv->hotplug.reenable_work,
 			  intel_hpd_irq_storm_reenable_work);
 }
@@ -504,5 +574,33 @@ void intel_hpd_cancel_work(struct drm_i9
 
 	cancel_work_sync(&dev_priv->hotplug.dig_port_work);
 	cancel_work_sync(&dev_priv->hotplug.hotplug_work);
+	cancel_work_sync(&dev_priv->hotplug.poll_init_work);
 	cancel_delayed_work_sync(&dev_priv->hotplug.reenable_work);
 }
+
+bool intel_hpd_disable(struct drm_i915_private *dev_priv, enum hpd_pin pin)
+{
+	bool ret = false;
+
+	if (pin == HPD_NONE)
+		return false;
+
+	spin_lock_irq(&dev_priv->irq_lock);
+	if (dev_priv->hotplug.stats[pin].state == HPD_ENABLED) {
+		dev_priv->hotplug.stats[pin].state = HPD_DISABLED;
+		ret = true;
+	}
+	spin_unlock_irq(&dev_priv->irq_lock);
+
+	return ret;
+}
+
+void intel_hpd_enable(struct drm_i915_private *dev_priv, enum hpd_pin pin)
+{
+	if (pin == HPD_NONE)
+		return;
+
+	spin_lock_irq(&dev_priv->irq_lock);
+	dev_priv->hotplug.stats[pin].state = HPD_ENABLED;
+	spin_unlock_irq(&dev_priv->irq_lock);
+}
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/i915/intel_i2c.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/i915/intel_i2c.c
@@ -675,7 +675,7 @@ int intel_setup_gmbus(struct drm_device
 	return 0;
 
 err:
-	while (--pin) {
+	while (pin--) {
 		if (!intel_gmbus_is_valid_pin(dev_priv, pin))
 			continue;
 
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/i915/intel_lrc.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/i915/intel_lrc.c
@@ -776,11 +776,11 @@ static int logical_ring_prepare(struct d
 		if (unlikely(total_bytes > remain_usable)) {
 			/*
 			 * The base request will fit but the reserved space
-			 * falls off the end. So only need to to wait for the
-			 * reserved size after flushing out the remainder.
+			 * falls off the end. So don't need an immediate wrap
+			 * and only need to effectively wait for the reserved
+			 * size space from the start of ringbuffer.
 			 */
 			wait_bytes = remain_actual + ringbuf->reserved_size;
-			need_wrap = true;
 		} else if (total_bytes > ringbuf->space) {
 			/* No wrapping required, just waiting. */
 			wait_bytes = total_bytes;
@@ -1706,6 +1706,7 @@ static int gen8_emit_flush_render(struct
 	if (flush_domains) {
 		flags |= PIPE_CONTROL_RENDER_TARGET_CACHE_FLUSH;
 		flags |= PIPE_CONTROL_DEPTH_CACHE_FLUSH;
+		flags |= PIPE_CONTROL_DC_FLUSH_ENABLE;
 		flags |= PIPE_CONTROL_FLUSH_ENABLE;
 	}
 
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/i915/intel_opregion.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/i915/intel_opregion.c
@@ -682,7 +682,7 @@ static void intel_didl_outputs(struct dr
 	}
 
 	if (!acpi_video_bus) {
-		DRM_ERROR("No ACPI video bus found\n");
+		DRM_DEBUG_KMS("No ACPI video bus found\n");
 		return;
 	}
 
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/i915/intel_pm.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/i915/intel_pm.c
@@ -1789,16 +1789,20 @@ static uint32_t ilk_compute_cur_wm(const
 				   const struct intel_plane_state *pstate,
 				   uint32_t mem_value)
 {
-	int bpp = pstate->base.fb ? pstate->base.fb->bits_per_pixel / 8 : 0;
+	/*
+	 * We treat the cursor plane as always-on for the purposes of watermark
+	 * calculation.  Until we have two-stage watermark programming merged,
+	 * this is necessary to avoid flickering.
+	 */
+	int cpp = 4;
+	int width = pstate->visible ? pstate->base.crtc_w : 64;
 
-	if (!cstate->base.active || !pstate->visible)
+	if (!cstate->base.active)
 		return 0;
 
 	return ilk_wm_method2(ilk_pipe_pixel_rate(cstate),
 			      cstate->base.adjusted_mode.crtc_htotal,
-			      drm_rect_width(&pstate->dst),
-			      bpp,
-			      mem_value);
+			      width, cpp, mem_value);
 }
 
 /* Only for WM_LP. */
@@ -3880,6 +3884,8 @@ static void ilk_pipe_wm_get_hw_state(str
 	if (IS_HASWELL(dev) || IS_BROADWELL(dev))
 		hw->wm_linetime[pipe] = I915_READ(PIPE_WM_LINETIME(pipe));
 
+	memset(active, 0, sizeof(*active));
+
 	active->pipe_enabled = intel_crtc->active;
 
 	if (active->pipe_enabled) {
@@ -4520,7 +4526,8 @@ void gen6_rps_idle(struct drm_i915_priva
 		else
 			gen6_set_rps(dev_priv->dev, dev_priv->rps.idle_freq);
 		dev_priv->rps.last_adj = 0;
-		I915_WRITE(GEN6_PMINTRMSK, 0xffffffff);
+		I915_WRITE(GEN6_PMINTRMSK,
+			   gen6_sanitize_rps_pm_mask(dev_priv, ~0));
 	}
 	mutex_unlock(&dev_priv->rps.hw_lock);
 
@@ -6620,6 +6627,12 @@ static void broadwell_init_clock_gating(
 	misccpctl = I915_READ(GEN7_MISCCPCTL);
 	I915_WRITE(GEN7_MISCCPCTL, misccpctl & ~GEN7_DOP_CLOCK_GATE_ENABLE);
 	I915_WRITE(GEN8_L3SQCREG1, BDW_WA_L3SQCREG1_DEFAULT);
+	/*
+	 * Wait at least 100 clocks before re-enabling clock gating. See
+	 * the definition of L3SQCREG1 in BSpec.
+	 */
+	POSTING_READ(GEN8_L3SQCREG1);
+	udelay(1);
 	I915_WRITE(GEN7_MISCCPCTL, misccpctl);
 
 	/*
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/i915/intel_ringbuffer.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/i915/intel_ringbuffer.c
@@ -347,6 +347,7 @@ gen7_render_ring_flush(struct drm_i915_g
 	if (flush_domains) {
 		flags |= PIPE_CONTROL_RENDER_TARGET_CACHE_FLUSH;
 		flags |= PIPE_CONTROL_DEPTH_CACHE_FLUSH;
+		flags |= PIPE_CONTROL_DC_FLUSH_ENABLE;
 		flags |= PIPE_CONTROL_FLUSH_ENABLE;
 	}
 	if (invalidate_domains) {
@@ -419,6 +420,7 @@ gen8_render_ring_flush(struct drm_i915_g
 	if (flush_domains) {
 		flags |= PIPE_CONTROL_RENDER_TARGET_CACHE_FLUSH;
 		flags |= PIPE_CONTROL_DEPTH_CACHE_FLUSH;
+		flags |= PIPE_CONTROL_DC_FLUSH_ENABLE;
 		flags |= PIPE_CONTROL_FLUSH_ENABLE;
 	}
 	if (invalidate_domains) {
@@ -1920,6 +1922,17 @@ i915_dispatch_execbuffer(struct drm_i915
 	return 0;
 }
 
+static void cleanup_phys_status_page(struct intel_engine_cs *ring)
+{
+	struct drm_i915_private *dev_priv = to_i915(ring->dev);
+
+	if (!dev_priv->status_page_dmah)
+		return;
+
+	drm_pci_free(ring->dev, dev_priv->status_page_dmah);
+	ring->status_page.page_addr = NULL;
+}
+
 static void cleanup_status_page(struct intel_engine_cs *ring)
 {
 	struct drm_i915_gem_object *obj;
@@ -1936,9 +1949,9 @@ static void cleanup_status_page(struct i
 
 static int init_status_page(struct intel_engine_cs *ring)
 {
-	struct drm_i915_gem_object *obj;
+	struct drm_i915_gem_object *obj = ring->status_page.obj;
 
-	if ((obj = ring->status_page.obj) == NULL) {
+	if (obj == NULL) {
 		unsigned flags;
 		int ret;
 
@@ -2132,7 +2145,7 @@ static int intel_init_ring_buffer(struct
 		if (ret)
 			goto error;
 	} else {
-		BUG_ON(ring->id != RCS);
+		WARN_ON(ring->id != RCS);
 		ret = init_phys_status_page(ring);
 		if (ret)
 			goto error;
@@ -2177,7 +2190,12 @@ void intel_cleanup_ring_buffer(struct in
 	if (ring->cleanup)
 		ring->cleanup(ring);
 
-	cleanup_status_page(ring);
+	if (I915_NEED_GFX_HWS(ring->dev)) {
+		cleanup_status_page(ring);
+	} else {
+		WARN_ON(ring->id != RCS);
+		cleanup_phys_status_page(ring);
+	}
 
 	i915_cmd_parser_fini_ring(ring);
 	i915_gem_batch_pool_fini(&ring->batch_pool);
@@ -2339,11 +2357,11 @@ static int __intel_ring_prepare(struct i
 		if (unlikely(total_bytes > remain_usable)) {
 			/*
 			 * The base request will fit but the reserved space
-			 * falls off the end. So only need to to wait for the
-			 * reserved size after flushing out the remainder.
+			 * falls off the end. So don't need an immediate wrap
+			 * and only need to effectively wait for the reserved
+			 * size space from the start of ringbuffer.
 			 */
 			wait_bytes = remain_actual + ringbuf->reserved_size;
-			need_wrap = true;
 		} else if (total_bytes > ringbuf->space) {
 			/* No wrapping required, just waiting. */
 			wait_bytes = total_bytes;
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/i915/intel_runtime_pm.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/i915/intel_runtime_pm.c
@@ -863,6 +863,7 @@ static bool vlv_power_well_enabled(struc
 
 static void vlv_display_power_well_init(struct drm_i915_private *dev_priv)
 {
+	struct intel_encoder *encoder;
 	enum pipe pipe;
 
 	/*
@@ -896,6 +897,12 @@ static void vlv_display_power_well_init(
 
 	intel_hpd_init(dev_priv);
 
+	/* Re-enable the ADPA, if we have one */
+	for_each_intel_encoder(dev_priv->dev, encoder) {
+		if (encoder->type == INTEL_OUTPUT_ANALOG)
+			intel_crt_reset(&encoder->base);
+	}
+
 	i915_redisable_vga_power_on(dev_priv->dev);
 }
 
@@ -906,6 +913,8 @@ static void vlv_display_power_well_deini
 	spin_unlock_irq(&dev_priv->irq_lock);
 
 	vlv_power_sequencer_reset(dev_priv);
+
+	intel_hpd_poll_init(dev_priv);
 }
 
 static void vlv_display_power_well_enable(struct drm_i915_private *dev_priv,
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/i915/intel_sprite.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/i915/intel_sprite.c
@@ -195,7 +195,7 @@ skl_update_plane(struct drm_plane *drm_p
 	int pixel_size = drm_format_plane_cpp(fb->pixel_format, 0);
 	const struct drm_intel_sprite_colorkey *key =
 		&to_intel_plane_state(drm_plane->state)->ckey;
-	unsigned long surf_addr;
+	u32 surf_addr;
 	u32 tile_height, plane_offset, plane_size;
 	unsigned int rotation;
 	int x_offset, y_offset;
@@ -832,8 +832,8 @@ intel_check_sprite_plane(struct drm_plan
 		hscale = drm_rect_calc_hscale(src, dst, min_scale, max_scale);
 		if (hscale < 0) {
 			DRM_DEBUG_KMS("Horizontal scaling factor out of limits\n");
-			drm_rect_debug_print(src, true);
-			drm_rect_debug_print(dst, false);
+			drm_rect_debug_print("src: ", src, true);
+			drm_rect_debug_print("dst: ", dst, false);
 
 			return hscale;
 		}
@@ -841,8 +841,8 @@ intel_check_sprite_plane(struct drm_plan
 		vscale = drm_rect_calc_vscale(src, dst, min_scale, max_scale);
 		if (vscale < 0) {
 			DRM_DEBUG_KMS("Vertical scaling factor out of limits\n");
-			drm_rect_debug_print(src, true);
-			drm_rect_debug_print(dst, false);
+			drm_rect_debug_print("src: ", src, true);
+			drm_rect_debug_print("dst: ", dst, false);
 
 			return vscale;
 		}
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/i915/intel_uncore.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/i915/intel_uncore.c
@@ -1132,7 +1132,11 @@ static void intel_uncore_fw_domains_init
 	} else if (IS_HASWELL(dev) || IS_BROADWELL(dev)) {
 		dev_priv->uncore.funcs.force_wake_get =
 			fw_domains_get_with_thread_status;
-		dev_priv->uncore.funcs.force_wake_put = fw_domains_put;
+		if (IS_HASWELL(dev))
+			dev_priv->uncore.funcs.force_wake_put =
+				fw_domains_put_with_fifo;
+		else
+			dev_priv->uncore.funcs.force_wake_put = fw_domains_put;
 		fw_domain_init(dev_priv, FW_DOMAIN_ID_RENDER,
 			       FORCEWAKE_MT, FORCEWAKE_ACK_HSW);
 	} else if (IS_IVYBRIDGE(dev)) {
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/imx/imx-drm-core.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/imx/imx-drm-core.c
@@ -26,6 +26,7 @@
 #include <drm/drm_fb_cma_helper.h>
 #include <drm/drm_plane_helper.h>
 #include <drm/drm_of.h>
+#include <video/imx-ipu-v3.h>
 
 #include "imx-drm.h"
 
@@ -312,6 +313,7 @@ static int imx_drm_driver_load(struct dr
 		dev_warn(drm->dev, "Invalid legacyfb_depth.  Defaulting to 16bpp\n");
 		legacyfb_depth = 16;
 	}
+	drm_helper_disable_unused_functions(drm);
 	imxdrm->fbhelper = drm_fbdev_cma_init(drm, legacyfb_depth,
 				drm->mode_config.num_crtc, MAX_CRTC);
 	if (IS_ERR(imxdrm->fbhelper)) {
@@ -504,6 +506,13 @@ static int compare_of(struct device *dev
 {
 	struct device_node *np = data;
 
+	/* Special case for DI, dev->of_node may not be set yet */
+	if (strcmp(dev->driver->name, "imx-ipuv3-crtc") == 0) {
+		struct ipu_client_platformdata *pdata = dev->platform_data;
+
+		return pdata->of_node == np;
+	}
+
 	/* Special case for LDB, one device for two channels */
 	if (of_node_cmp(np->name, "lvds-channel") == 0) {
 		np = of_get_parent(np);
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/imx/ipuv3-crtc.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/imx/ipuv3-crtc.c
@@ -369,7 +369,7 @@ static int ipu_crtc_init(struct ipu_crtc
 
 	ret = imx_drm_add_crtc(drm, &ipu_crtc->base, &ipu_crtc->imx_crtc,
 			&ipu_crtc->plane[0]->base, &ipu_crtc_helper_funcs,
-			ipu_crtc->dev->of_node);
+			pdata->of_node);
 	if (ret) {
 		dev_err(ipu_crtc->dev, "adding crtc failed with %d.\n", ret);
 		goto err_put_resources;
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/mgag200/mgag200_mode.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/mgag200/mgag200_mode.c
@@ -194,7 +194,7 @@ static int mga_g200se_set_plls(struct mg
 			}
 		}
 
-		fvv = pllreffreq * testn / testm;
+		fvv = pllreffreq * (n + 1) / (m + 1);
 		fvv = (fvv - 800000) / 50000;
 
 		if (fvv > 15)
@@ -214,6 +214,14 @@ static int mga_g200se_set_plls(struct mg
 	WREG_DAC(MGA1064_PIX_PLLC_M, m);
 	WREG_DAC(MGA1064_PIX_PLLC_N, n);
 	WREG_DAC(MGA1064_PIX_PLLC_P, p);
+
+	if (mdev->unique_rev_id >= 0x04) {
+		WREG_DAC(0x1a, 0x09);
+		msleep(20);
+		WREG_DAC(0x1a, 0x01);
+
+	}
+
 	return 0;
 }
 
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/msm/msm_gem_submit.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/msm/msm_gem_submit.c
@@ -55,6 +55,14 @@ static struct msm_gem_submit *submit_cre
 	return submit;
 }
 
+static inline unsigned long __must_check
+copy_from_user_inatomic(void *to, const void __user *from, unsigned long n)
+{
+	if (access_ok(VERIFY_READ, from, n))
+		return __copy_from_user_inatomic(to, from, n);
+	return -EFAULT;
+}
+
 static int submit_lookup_objects(struct msm_gem_submit *submit,
 		struct drm_msm_gem_submit *args, struct drm_file *file)
 {
@@ -62,6 +70,7 @@ static int submit_lookup_objects(struct
 	int ret = 0;
 
 	spin_lock(&file->table_lock);
+	pagefault_disable();
 
 	for (i = 0; i < args->nr_bos; i++) {
 		struct drm_msm_gem_submit_bo submit_bo;
@@ -70,10 +79,15 @@ static int submit_lookup_objects(struct
 		void __user *userptr =
 			to_user_ptr(args->bos + (i * sizeof(submit_bo)));
 
-		ret = copy_from_user(&submit_bo, userptr, sizeof(submit_bo));
-		if (ret) {
-			ret = -EFAULT;
-			goto out_unlock;
+		ret = copy_from_user_inatomic(&submit_bo, userptr, sizeof(submit_bo));
+		if (unlikely(ret)) {
+			pagefault_enable();
+			spin_unlock(&file->table_lock);
+			ret = copy_from_user(&submit_bo, userptr, sizeof(submit_bo));
+			if (ret)
+				goto out;
+			spin_lock(&file->table_lock);
+			pagefault_disable();
 		}
 
 		if (submit_bo.flags & ~MSM_SUBMIT_BO_FLAGS) {
@@ -113,9 +127,12 @@ static int submit_lookup_objects(struct
 	}
 
 out_unlock:
-	submit->nr_bos = i;
+	pagefault_enable();
 	spin_unlock(&file->table_lock);
 
+out:
+	submit->nr_bos = i;
+
 	return ret;
 }
 
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/nouveau/nouveau_bios.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/nouveau/nouveau_bios.c
@@ -351,7 +351,7 @@ static int parse_fp_mode_table(struct dr
 		/* Apple cards don't have the fp table; the laptops use DDC */
 		/* The table is also missing on some x86 IGPs */
 #ifndef __powerpc__
-		NV_ERROR(drm, "Pointer to flat panel table invalid\n");
+		NV_WARN(drm, "Pointer to flat panel table invalid\n");
 #endif
 		bios->digital_min_front_porch = 0x4b;
 		return 0;
@@ -935,7 +935,7 @@ static int parse_bit_tmds_tbl_entry(stru
 
 	tmdstableptr = ROM16(bios->data[bitentry->offset]);
 	if (!tmdstableptr) {
-		NV_ERROR(drm, "Pointer to TMDS table invalid\n");
+		NV_WARN(drm, "Pointer to TMDS table invalid\n");
 		return -EINVAL;
 	}
 
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/nouveau/nouveau_connector.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/nouveau/nouveau_connector.c
@@ -969,10 +969,13 @@ nouveau_connector_hotplug(struct nvif_no
 
 		NV_DEBUG(drm, "%splugged %s\n", plugged ? "" : "un", name);
 
+		mutex_lock(&drm->dev->mode_config.mutex);
 		if (plugged)
 			drm_helper_connector_dpms(connector, DRM_MODE_DPMS_ON);
 		else
 			drm_helper_connector_dpms(connector, DRM_MODE_DPMS_OFF);
+		mutex_unlock(&drm->dev->mode_config.mutex);
+
 		drm_helper_hpd_irq_event(connector->dev);
 	}
 
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/nouveau/nouveau_display.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/nouveau/nouveau_display.c
@@ -634,10 +634,6 @@ nouveau_display_resume(struct drm_device
 		nv_crtc->lut.depth = 0;
 	}
 
-	/* Make sure that drm and hw vblank irqs get resumed if needed. */
-	for (head = 0; head < dev->mode_config.num_crtc; head++)
-		drm_vblank_on(dev, head);
-
 	/* This should ensure we don't hit a locking problem when someone
 	 * wakes us up via a connector.  We should never go into suspend
 	 * while the display is on anyways.
@@ -647,6 +643,10 @@ nouveau_display_resume(struct drm_device
 
 	drm_helper_resume_force_mode(dev);
 
+	/* Make sure that drm and hw vblank irqs get resumed if needed. */
+	for (head = 0; head < dev->mode_config.num_crtc; head++)
+		drm_vblank_on(dev, head);
+
 	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
 		struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
 
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/nouveau/nouveau_drm.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/nouveau/nouveau_drm.c
@@ -308,7 +308,16 @@ static int nouveau_drm_probe(struct pci_
 	bool boot = false;
 	int ret;
 
-	/* remove conflicting drivers (vesafb, efifb etc) */
+	/* We need to check that the chipset is supported before booting
+	 * fbdev off the hardware, as there's no way to put it back.
+	 */
+	ret = nvkm_device_pci_new(pdev, NULL, "error", true, false, 0, &device);
+	if (ret)
+		return ret;
+
+	nvkm_device_del(&device);
+
+	/* Remove conflicting drivers (vesafb, efifb etc). */
 	aper = alloc_apertures(3);
 	if (!aper)
 		return -ENOMEM;
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/nouveau/nouveau_fbcon.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/nouveau/nouveau_fbcon.c
@@ -557,6 +557,8 @@ nouveau_fbcon_init(struct drm_device *de
 	if (ret)
 		goto fini;
 
+	if (fbcon->helper.fbdev)
+		fbcon->helper.fbdev->pixmap.buf_align = 4;
 	return 0;
 
 fini:
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/nouveau/nouveau_platform.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/nouveau/nouveau_platform.c
@@ -24,7 +24,7 @@
 static int nouveau_platform_probe(struct platform_device *pdev)
 {
 	const struct nvkm_device_tegra_func *func;
-	struct nvkm_device *device;
+	struct nvkm_device *device = NULL;
 	struct drm_device *drm;
 	int ret;
 
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/nouveau/nv04_fbcon.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/nouveau/nv04_fbcon.c
@@ -82,7 +82,6 @@ nv04_fbcon_imageblit(struct fb_info *inf
 	uint32_t fg;
 	uint32_t bg;
 	uint32_t dsize;
-	uint32_t width;
 	uint32_t *data = (uint32_t *)image->data;
 	int ret;
 
@@ -93,9 +92,6 @@ nv04_fbcon_imageblit(struct fb_info *inf
 	if (ret)
 		return ret;
 
-	width = ALIGN(image->width, 8);
-	dsize = ALIGN(width * image->height, 32) >> 5;
-
 	if (info->fix.visual == FB_VISUAL_TRUECOLOR ||
 	    info->fix.visual == FB_VISUAL_DIRECTCOLOR) {
 		fg = ((uint32_t *) info->pseudo_palette)[image->fg_color];
@@ -111,10 +107,11 @@ nv04_fbcon_imageblit(struct fb_info *inf
 			 ((image->dx + image->width) & 0xffff));
 	OUT_RING(chan, bg);
 	OUT_RING(chan, fg);
-	OUT_RING(chan, (image->height << 16) | width);
+	OUT_RING(chan, (image->height << 16) | ALIGN(image->width, 8));
 	OUT_RING(chan, (image->height << 16) | image->width);
 	OUT_RING(chan, (image->dy << 16) | (image->dx & 0xffff));
 
+	dsize = ALIGN(ALIGN(image->width, 8) * image->height, 32) >> 5;
 	while (dsize) {
 		int iter_len = dsize > 128 ? 128 : dsize;
 
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/nouveau/nv50_fbcon.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/nouveau/nv50_fbcon.c
@@ -95,7 +95,7 @@ nv50_fbcon_imageblit(struct fb_info *inf
 	struct nouveau_fbdev *nfbdev = info->par;
 	struct nouveau_drm *drm = nouveau_drm(nfbdev->dev);
 	struct nouveau_channel *chan = drm->channel;
-	uint32_t width, dwords, *data = (uint32_t *)image->data;
+	uint32_t dwords, *data = (uint32_t *)image->data;
 	uint32_t mask = ~(~0 >> (32 - info->var.bits_per_pixel));
 	uint32_t *palette = info->pseudo_palette;
 	int ret;
@@ -107,9 +107,6 @@ nv50_fbcon_imageblit(struct fb_info *inf
 	if (ret)
 		return ret;
 
-	width = ALIGN(image->width, 32);
-	dwords = (width * image->height) >> 5;
-
 	BEGIN_NV04(chan, NvSub2D, 0x0814, 2);
 	if (info->fix.visual == FB_VISUAL_TRUECOLOR ||
 	    info->fix.visual == FB_VISUAL_DIRECTCOLOR) {
@@ -128,6 +125,7 @@ nv50_fbcon_imageblit(struct fb_info *inf
 	OUT_RING(chan, 0);
 	OUT_RING(chan, image->dy);
 
+	dwords = ALIGN(ALIGN(image->width, 8) * image->height, 32) >> 5;
 	while (dwords) {
 		int push = dwords > 2047 ? 2047 : dwords;
 
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/nouveau/nvc0_fbcon.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/nouveau/nvc0_fbcon.c
@@ -95,7 +95,7 @@ nvc0_fbcon_imageblit(struct fb_info *inf
 	struct nouveau_fbdev *nfbdev = info->par;
 	struct nouveau_drm *drm = nouveau_drm(nfbdev->dev);
 	struct nouveau_channel *chan = drm->channel;
-	uint32_t width, dwords, *data = (uint32_t *)image->data;
+	uint32_t dwords, *data = (uint32_t *)image->data;
 	uint32_t mask = ~(~0 >> (32 - info->var.bits_per_pixel));
 	uint32_t *palette = info->pseudo_palette;
 	int ret;
@@ -107,9 +107,6 @@ nvc0_fbcon_imageblit(struct fb_info *inf
 	if (ret)
 		return ret;
 
-	width = ALIGN(image->width, 32);
-	dwords = (width * image->height) >> 5;
-
 	BEGIN_NVC0(chan, NvSub2D, 0x0814, 2);
 	if (info->fix.visual == FB_VISUAL_TRUECOLOR ||
 	    info->fix.visual == FB_VISUAL_DIRECTCOLOR) {
@@ -128,6 +125,7 @@ nvc0_fbcon_imageblit(struct fb_info *inf
 	OUT_RING  (chan, 0);
 	OUT_RING  (chan, image->dy);
 
+	dwords = ALIGN(ALIGN(image->width, 8) * image->height, 32) >> 5;
 	while (dwords) {
 		int push = dwords > 2047 ? 2047 : dwords;
 
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/nouveau/nvkm/core/ramht.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/nouveau/nvkm/core/ramht.c
@@ -131,7 +131,7 @@ nvkm_ramht_del(struct nvkm_ramht **pramh
 	struct nvkm_ramht *ramht = *pramht;
 	if (ramht) {
 		nvkm_gpuobj_del(&ramht->gpuobj);
-		kfree(*pramht);
+		vfree(*pramht);
 		*pramht = NULL;
 	}
 }
@@ -143,8 +143,8 @@ nvkm_ramht_new(struct nvkm_device *devic
 	struct nvkm_ramht *ramht;
 	int ret, i;
 
-	if (!(ramht = *pramht = kzalloc(sizeof(*ramht) + (size >> 3) *
-					sizeof(*ramht->data), GFP_KERNEL)))
+	if (!(ramht = *pramht = vzalloc(sizeof(*ramht) +
+					(size >> 3) * sizeof(*ramht->data))))
 		return -ENOMEM;
 
 	ramht->device = device;
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c
@@ -252,32 +252,40 @@ nvkm_device_tegra_new(const struct nvkm_
 
 	if (!(tdev = kzalloc(sizeof(*tdev), GFP_KERNEL)))
 		return -ENOMEM;
-	*pdevice = &tdev->device;
+
 	tdev->func = func;
 	tdev->pdev = pdev;
 	tdev->irq = -1;
 
 	tdev->vdd = devm_regulator_get(&pdev->dev, "vdd");
-	if (IS_ERR(tdev->vdd))
-		return PTR_ERR(tdev->vdd);
+	if (IS_ERR(tdev->vdd)) {
+		ret = PTR_ERR(tdev->vdd);
+		goto free;
+	}
 
 	tdev->rst = devm_reset_control_get(&pdev->dev, "gpu");
-	if (IS_ERR(tdev->rst))
-		return PTR_ERR(tdev->rst);
+	if (IS_ERR(tdev->rst)) {
+		ret = PTR_ERR(tdev->rst);
+		goto free;
+	}
 
 	tdev->clk = devm_clk_get(&pdev->dev, "gpu");
-	if (IS_ERR(tdev->clk))
-		return PTR_ERR(tdev->clk);
+	if (IS_ERR(tdev->clk)) {
+		ret = PTR_ERR(tdev->clk);
+		goto free;
+	}
 
 	tdev->clk_pwr = devm_clk_get(&pdev->dev, "pwr");
-	if (IS_ERR(tdev->clk_pwr))
-		return PTR_ERR(tdev->clk_pwr);
+	if (IS_ERR(tdev->clk_pwr)) {
+		ret = PTR_ERR(tdev->clk_pwr);
+		goto free;
+	}
 
 	nvkm_device_tegra_probe_iommu(tdev);
 
 	ret = nvkm_device_tegra_power_up(tdev);
 	if (ret)
-		return ret;
+		goto remove;
 
 	tdev->gpu_speedo = tegra_sku_info.gpu_speedo_value;
 	ret = nvkm_device_ctor(&nvkm_device_tegra_func, NULL, &pdev->dev,
@@ -285,9 +293,19 @@ nvkm_device_tegra_new(const struct nvkm_
 			       cfg, dbg, detect, mmio, subdev_mask,
 			       &tdev->device);
 	if (ret)
-		return ret;
+		goto powerdown;
+
+	*pdevice = &tdev->device;
 
 	return 0;
+
+powerdown:
+	nvkm_device_tegra_power_down(tdev);
+remove:
+	nvkm_device_tegra_remove_iommu(tdev);
+free:
+	kfree(tdev);
+	return ret;
 }
 #else
 int
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/nouveau/nvkm/engine/disp/dport.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/nouveau/nvkm/engine/disp/dport.c
@@ -328,6 +328,7 @@ nvkm_dp_train(struct work_struct *w)
 		.outp = outp,
 	}, *dp = &_dp;
 	u32 datarate = 0;
+	u8  pwr;
 	int ret;
 
 	if (!outp->base.info.location && disp->func->sor.magic)
@@ -355,6 +356,15 @@ nvkm_dp_train(struct work_struct *w)
 	/* disable link interrupt handling during link training */
 	nvkm_notify_put(&outp->irq);
 
+	/* ensure sink is not in a low-power state */
+	if (!nvkm_rdaux(outp->aux, DPCD_SC00, &pwr, 1)) {
+		if ((pwr & DPCD_SC00_SET_POWER) != DPCD_SC00_SET_POWER_D0) {
+			pwr &= ~DPCD_SC00_SET_POWER;
+			pwr |=  DPCD_SC00_SET_POWER_D0;
+			nvkm_wraux(outp->aux, DPCD_SC00, &pwr, 1);
+		}
+	}
+
 	/* enable down-spreading and execute pre-train script from vbios */
 	dp_link_train_init(dp, outp->dpcd[3] & 0x01);
 
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/nouveau/nvkm/engine/disp/dport.h
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/nouveau/nvkm/engine/disp/dport.h
@@ -71,5 +71,11 @@
 #define DPCD_LS0C_LANE1_POST_CURSOR2                                       0x0c
 #define DPCD_LS0C_LANE0_POST_CURSOR2                                       0x03
 
+/* DPCD Sink Control */
+#define DPCD_SC00                                                       0x00600
+#define DPCD_SC00_SET_POWER                                                0x03
+#define DPCD_SC00_SET_POWER_D0                                             0x01
+#define DPCD_SC00_SET_POWER_D3                                             0x03
+
 void nvkm_dp_train(struct work_struct *);
 #endif
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgf119.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgf119.c
@@ -40,8 +40,8 @@ static int
 gf119_sor_dp_pattern(struct nvkm_output_dp *outp, int pattern)
 {
 	struct nvkm_device *device = outp->base.disp->engine.subdev.device;
-	const u32 loff = gf119_sor_loff(outp);
-	nvkm_mask(device, 0x61c110 + loff, 0x0f0f0f0f, 0x01010101 * pattern);
+	const u32 soff = gf119_sor_soff(outp);
+	nvkm_mask(device, 0x61c110 + soff, 0x0f0f0f0f, 0x01010101 * pattern);
 	return 0;
 }
 
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/nouveau/nvkm/engine/fifo/dmanv04.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/nouveau/nvkm/engine/fifo/dmanv04.c
@@ -36,7 +36,10 @@ nv04_fifo_dma_object_dtor(struct nvkm_fi
 {
 	struct nv04_fifo_chan *chan = nv04_fifo_chan(base);
 	struct nvkm_instmem *imem = chan->fifo->base.engine.subdev.device->imem;
+
+	mutex_lock(&chan->fifo->base.engine.subdev.mutex);
 	nvkm_ramht_remove(imem->ramht, cookie);
+	mutex_unlock(&chan->fifo->base.engine.subdev.mutex);
 }
 
 static int
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c
@@ -874,22 +874,41 @@ gf100_gr_trap_gpc_rop(struct gf100_gr *g
 }
 
 static const struct nvkm_enum gf100_mp_warp_error[] = {
-	{ 0x00, "NO_ERROR" },
-	{ 0x01, "STACK_MISMATCH" },
+	{ 0x01, "STACK_ERROR" },
+	{ 0x02, "API_STACK_ERROR" },
+	{ 0x03, "RET_EMPTY_STACK_ERROR" },
+	{ 0x04, "PC_WRAP" },
 	{ 0x05, "MISALIGNED_PC" },
-	{ 0x08, "MISALIGNED_GPR" },
-	{ 0x09, "INVALID_OPCODE" },
-	{ 0x0d, "GPR_OUT_OF_BOUNDS" },
-	{ 0x0e, "MEM_OUT_OF_BOUNDS" },
-	{ 0x0f, "UNALIGNED_MEM_ACCESS" },
+	{ 0x06, "PC_OVERFLOW" },
+	{ 0x07, "MISALIGNED_IMMC_ADDR" },
+	{ 0x08, "MISALIGNED_REG" },
+	{ 0x09, "ILLEGAL_INSTR_ENCODING" },
+	{ 0x0a, "ILLEGAL_SPH_INSTR_COMBO" },
+	{ 0x0b, "ILLEGAL_INSTR_PARAM" },
+	{ 0x0c, "INVALID_CONST_ADDR" },
+	{ 0x0d, "OOR_REG" },
+	{ 0x0e, "OOR_ADDR" },
+	{ 0x0f, "MISALIGNED_ADDR" },
 	{ 0x10, "INVALID_ADDR_SPACE" },
-	{ 0x11, "INVALID_PARAM" },
+	{ 0x11, "ILLEGAL_INSTR_PARAM2" },
+	{ 0x12, "INVALID_CONST_ADDR_LDC" },
+	{ 0x13, "GEOMETRY_SM_ERROR" },
+	{ 0x14, "DIVERGENT" },
+	{ 0x15, "WARP_EXIT" },
 	{}
 };
 
 static const struct nvkm_bitfield gf100_mp_global_error[] = {
+	{ 0x00000001, "SM_TO_SM_FAULT" },
+	{ 0x00000002, "L1_ERROR" },
 	{ 0x00000004, "MULTIPLE_WARP_ERRORS" },
-	{ 0x00000008, "OUT_OF_STACK_SPACE" },
+	{ 0x00000008, "PHYSICAL_STACK_OVERFLOW" },
+	{ 0x00000010, "BPT_INT" },
+	{ 0x00000020, "BPT_PAUSE" },
+	{ 0x00000040, "SINGLE_STEP_COMPLETE" },
+	{ 0x20000000, "ECC_SEC_ERROR" },
+	{ 0x40000000, "ECC_DED_ERROR" },
+	{ 0x80000000, "TIMEOUT" },
 	{}
 };
 
@@ -1717,6 +1736,8 @@ gf100_gr_init(struct gf100_gr *gr)
 
 	gf100_gr_mmio(gr, gr->func->mmio);
 
+	nvkm_mask(device, TPC_UNIT(0, 0, 0x05c), 0x00000001, 0x00000001);
+
 	memcpy(tpcnr, gr->tpc_nr, sizeof(gr->tpc_nr));
 	for (i = 0, gpc = -1; i < gr->tpc_total; i++) {
 		do {
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv30.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv30.c
@@ -76,8 +76,8 @@ nv30_gr_chan_new(struct nvkm_gr *base, s
 		nvkm_wo32(chan->inst, i, 0x00040004);
 	for (i = 0x1f18; i <= 0x3088 ; i += 16) {
 		nvkm_wo32(chan->inst, i + 0, 0x10700ff9);
-		nvkm_wo32(chan->inst, i + 1, 0x0436086c);
-		nvkm_wo32(chan->inst, i + 2, 0x000c001b);
+		nvkm_wo32(chan->inst, i + 4, 0x0436086c);
+		nvkm_wo32(chan->inst, i + 8, 0x000c001b);
 	}
 	for (i = 0x30b8; i < 0x30c8; i += 4)
 		nvkm_wo32(chan->inst, i, 0x0000ffff);
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv34.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv34.c
@@ -75,8 +75,8 @@ nv34_gr_chan_new(struct nvkm_gr *base, s
 		nvkm_wo32(chan->inst, i, 0x00040004);
 	for (i = 0x15ac; i <= 0x271c ; i += 16) {
 		nvkm_wo32(chan->inst, i + 0, 0x10700ff9);
-		nvkm_wo32(chan->inst, i + 1, 0x0436086c);
-		nvkm_wo32(chan->inst, i + 2, 0x000c001b);
+		nvkm_wo32(chan->inst, i + 4, 0x0436086c);
+		nvkm_wo32(chan->inst, i + 8, 0x000c001b);
 	}
 	for (i = 0x274c; i < 0x275c; i += 4)
 		nvkm_wo32(chan->inst, i, 0x0000ffff);
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/nouveau/nvkm/engine/pm/nv40.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/nouveau/nvkm/engine/pm/nv40.c
@@ -59,9 +59,11 @@ static void
 nv40_perfctr_next(struct nvkm_pm *pm, struct nvkm_perfdom *dom)
 {
 	struct nvkm_device *device = pm->engine.subdev.device;
-	if (pm->sequence != pm->sequence) {
+	struct nv40_pm *nv40pm = container_of(pm, struct nv40_pm, base);
+
+	if (nv40pm->sequence != pm->sequence) {
 		nvkm_wr32(device, 0x400084, 0x00000020);
-		pm->sequence = pm->sequence;
+		nv40pm->sequence = pm->sequence;
 	}
 }
 
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/qxl/qxl_display.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/qxl/qxl_display.c
@@ -375,10 +375,15 @@ static int qxl_crtc_cursor_set2(struct d
 
 	qxl_bo_kunmap(user_bo);
 
+	qcrtc->cur_x += qcrtc->hot_spot_x - hot_x;
+	qcrtc->cur_y += qcrtc->hot_spot_y - hot_y;
+	qcrtc->hot_spot_x = hot_x;
+	qcrtc->hot_spot_y = hot_y;
+
 	cmd = (struct qxl_cursor_cmd *)qxl_release_map(qdev, release);
 	cmd->type = QXL_CURSOR_SET;
-	cmd->u.set.position.x = qcrtc->cur_x;
-	cmd->u.set.position.y = qcrtc->cur_y;
+	cmd->u.set.position.x = qcrtc->cur_x + qcrtc->hot_spot_x;
+	cmd->u.set.position.y = qcrtc->cur_y + qcrtc->hot_spot_y;
 
 	cmd->u.set.shape = qxl_bo_physical_address(qdev, cursor_bo, 0);
 
@@ -441,8 +446,8 @@ static int qxl_crtc_cursor_move(struct d
 
 	cmd = (struct qxl_cursor_cmd *)qxl_release_map(qdev, release);
 	cmd->type = QXL_CURSOR_MOVE;
-	cmd->u.position.x = qcrtc->cur_x;
-	cmd->u.position.y = qcrtc->cur_y;
+	cmd->u.position.x = qcrtc->cur_x + qcrtc->hot_spot_x;
+	cmd->u.position.y = qcrtc->cur_y + qcrtc->hot_spot_y;
 	qxl_release_unmap(qdev, release, &cmd->release_info);
 
 	qxl_push_cursor_ring_release(qdev, release, QXL_CMD_CURSOR, false);
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/qxl/qxl_draw.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/qxl/qxl_draw.c
@@ -136,6 +136,8 @@ static int qxl_palette_create_1bit(struc
 				 * correctly globaly, since that would require
 				 * tracking all of our palettes. */
 	ret = qxl_bo_kmap(palette_bo, (void **)&pal);
+	if (ret)
+		return ret;
 	pal->num_ents = 2;
 	pal->unique = unique++;
 	if (visual == FB_VISUAL_TRUECOLOR || visual == FB_VISUAL_DIRECTCOLOR) {
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/qxl/qxl_drv.h
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/qxl/qxl_drv.h
@@ -135,6 +135,8 @@ struct qxl_crtc {
 	int index;
 	int cur_x;
 	int cur_y;
+	int hot_spot_x;
+	int hot_spot_y;
 };
 
 struct qxl_output {
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/qxl/qxl_ioctl.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/qxl/qxl_ioctl.c
@@ -168,7 +168,8 @@ static int qxl_process_single_command(st
 		       cmd->command_size))
 		return -EFAULT;
 
-	reloc_info = kmalloc(sizeof(struct qxl_reloc_info) * cmd->relocs_num, GFP_KERNEL);
+	reloc_info = kmalloc_array(cmd->relocs_num,
+				   sizeof(struct qxl_reloc_info), GFP_KERNEL);
 	if (!reloc_info)
 		return -ENOMEM;
 
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/radeon/atombios_crtc.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/radeon/atombios_crtc.c
@@ -1739,6 +1739,7 @@ static u32 radeon_get_pll_use_mask(struc
 static int radeon_get_shared_dp_ppll(struct drm_crtc *crtc)
 {
 	struct drm_device *dev = crtc->dev;
+	struct radeon_device *rdev = dev->dev_private;
 	struct drm_crtc *test_crtc;
 	struct radeon_crtc *test_radeon_crtc;
 
@@ -1748,6 +1749,10 @@ static int radeon_get_shared_dp_ppll(str
 		test_radeon_crtc = to_radeon_crtc(test_crtc);
 		if (test_radeon_crtc->encoder &&
 		    ENCODER_MODE_IS_DP(atombios_get_encoder_mode(test_radeon_crtc->encoder))) {
+			/* PPLL2 is exclusive to UNIPHYA on DCE61 */
+			if (ASIC_IS_DCE61(rdev) && !ASIC_IS_DCE8(rdev) &&
+			    test_radeon_crtc->pll_id == ATOM_PPLL2)
+				continue;
 			/* for DP use the same PLL for all */
 			if (test_radeon_crtc->pll_id != ATOM_PPLL_INVALID)
 				return test_radeon_crtc->pll_id;
@@ -1769,6 +1774,7 @@ static int radeon_get_shared_nondp_ppll(
 {
 	struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
 	struct drm_device *dev = crtc->dev;
+	struct radeon_device *rdev = dev->dev_private;
 	struct drm_crtc *test_crtc;
 	struct radeon_crtc *test_radeon_crtc;
 	u32 adjusted_clock, test_adjusted_clock;
@@ -1784,6 +1790,10 @@ static int radeon_get_shared_nondp_ppll(
 		test_radeon_crtc = to_radeon_crtc(test_crtc);
 		if (test_radeon_crtc->encoder &&
 		    !ENCODER_MODE_IS_DP(atombios_get_encoder_mode(test_radeon_crtc->encoder))) {
+			/* PPLL2 is exclusive to UNIPHYA on DCE61 */
+			if (ASIC_IS_DCE61(rdev) && !ASIC_IS_DCE8(rdev) &&
+			    test_radeon_crtc->pll_id == ATOM_PPLL2)
+				continue;
 			/* check if we are already driving this connector with another crtc */
 			if (test_radeon_crtc->connector == radeon_crtc->connector) {
 				/* if we are, return that pll */
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/radeon/atombios_dp.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/radeon/atombios_dp.c
@@ -302,77 +302,43 @@ static int convert_bpc_to_bpp(int bpc)
 		return bpc * 3;
 }
 
-/* get the max pix clock supported by the link rate and lane num */
-static int dp_get_max_dp_pix_clock(int link_rate,
-				   int lane_num,
-				   int bpp)
-{
-	return (link_rate * lane_num * 8) / bpp;
-}
-
 /***** radeon specific DP functions *****/
 
-int radeon_dp_get_max_link_rate(struct drm_connector *connector,
-				const u8 dpcd[DP_DPCD_SIZE])
-{
-	int max_link_rate;
-
-	if (radeon_connector_is_dp12_capable(connector))
-		max_link_rate = min(drm_dp_max_link_rate(dpcd), 540000);
-	else
-		max_link_rate = min(drm_dp_max_link_rate(dpcd), 270000);
-
-	return max_link_rate;
-}
-
-/* First get the min lane# when low rate is used according to pixel clock
- * (prefer low rate), second check max lane# supported by DP panel,
- * if the max lane# < low rate lane# then use max lane# instead.
- */
-static int radeon_dp_get_dp_lane_number(struct drm_connector *connector,
-					const u8 dpcd[DP_DPCD_SIZE],
-					int pix_clock)
-{
-	int bpp = convert_bpc_to_bpp(radeon_get_monitor_bpc(connector));
-	int max_link_rate = radeon_dp_get_max_link_rate(connector, dpcd);
-	int max_lane_num = drm_dp_max_lane_count(dpcd);
-	int lane_num;
-	int max_dp_pix_clock;
-
-	for (lane_num = 1; lane_num < max_lane_num; lane_num <<= 1) {
-		max_dp_pix_clock = dp_get_max_dp_pix_clock(max_link_rate, lane_num, bpp);
-		if (pix_clock <= max_dp_pix_clock)
-			break;
-	}
-
-	return lane_num;
-}
-
-static int radeon_dp_get_dp_link_clock(struct drm_connector *connector,
-				       const u8 dpcd[DP_DPCD_SIZE],
-				       int pix_clock)
+int radeon_dp_get_dp_link_config(struct drm_connector *connector,
+				 const u8 dpcd[DP_DPCD_SIZE],
+				 unsigned pix_clock,
+				 unsigned *dp_lanes, unsigned *dp_rate)
 {
 	int bpp = convert_bpc_to_bpp(radeon_get_monitor_bpc(connector));
-	int lane_num, max_pix_clock;
+	static const unsigned link_rates[3] = { 162000, 270000, 540000 };
+	unsigned max_link_rate = drm_dp_max_link_rate(dpcd);
+	unsigned max_lane_num = drm_dp_max_lane_count(dpcd);
+	unsigned lane_num, i, max_pix_clock;
 
 	if (radeon_connector_encoder_get_dp_bridge_encoder_id(connector) ==
-	    ENCODER_OBJECT_ID_NUTMEG)
-		return 270000;
-
-	lane_num = radeon_dp_get_dp_lane_number(connector, dpcd, pix_clock);
-	max_pix_clock = dp_get_max_dp_pix_clock(162000, lane_num, bpp);
-	if (pix_clock <= max_pix_clock)
-		return 162000;
-	max_pix_clock = dp_get_max_dp_pix_clock(270000, lane_num, bpp);
-	if (pix_clock <= max_pix_clock)
-		return 270000;
-	if (radeon_connector_is_dp12_capable(connector)) {
-		max_pix_clock = dp_get_max_dp_pix_clock(540000, lane_num, bpp);
-		if (pix_clock <= max_pix_clock)
-			return 540000;
+	    ENCODER_OBJECT_ID_NUTMEG) {
+		for (lane_num = 1; lane_num <= max_lane_num; lane_num <<= 1) {
+			max_pix_clock = (lane_num * 270000 * 8) / bpp;
+			if (max_pix_clock >= pix_clock) {
+				*dp_lanes = lane_num;
+				*dp_rate = 270000;
+				return 0;
+			}
+		}
+	} else {
+		for (lane_num = 1; lane_num <= max_lane_num; lane_num <<= 1) {
+			for (i = 0; i < ARRAY_SIZE(link_rates) && link_rates[i] <= max_link_rate; i++) {
+				max_pix_clock = (lane_num * link_rates[i] * 8) / bpp;
+				if (max_pix_clock >= pix_clock) {
+					*dp_lanes = lane_num;
+					*dp_rate = link_rates[i];
+					return 0;
+				}
+			}
+		}
 	}
 
-	return radeon_dp_get_max_link_rate(connector, dpcd);
+	return -EINVAL;
 }
 
 static u8 radeon_dp_encoder_service(struct radeon_device *rdev,
@@ -491,6 +457,7 @@ void radeon_dp_set_link_config(struct dr
 {
 	struct radeon_connector *radeon_connector = to_radeon_connector(connector);
 	struct radeon_connector_atom_dig *dig_connector;
+	int ret;
 
 	if (!radeon_connector->con_priv)
 		return;
@@ -498,10 +465,14 @@ void radeon_dp_set_link_config(struct dr
 
 	if ((dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) ||
 	    (dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP)) {
-		dig_connector->dp_clock =
-			radeon_dp_get_dp_link_clock(connector, dig_connector->dpcd, mode->clock);
-		dig_connector->dp_lane_count =
-			radeon_dp_get_dp_lane_number(connector, dig_connector->dpcd, mode->clock);
+		ret = radeon_dp_get_dp_link_config(connector, dig_connector->dpcd,
+						   mode->clock,
+						   &dig_connector->dp_lane_count,
+						   &dig_connector->dp_clock);
+		if (ret) {
+			dig_connector->dp_clock = 0;
+			dig_connector->dp_lane_count = 0;
+		}
 	}
 }
 
@@ -510,7 +481,8 @@ int radeon_dp_mode_valid_helper(struct d
 {
 	struct radeon_connector *radeon_connector = to_radeon_connector(connector);
 	struct radeon_connector_atom_dig *dig_connector;
-	int dp_clock;
+	unsigned dp_clock, dp_lanes;
+	int ret;
 
 	if ((mode->clock > 340000) &&
 	    (!radeon_connector_is_dp12_capable(connector)))
@@ -520,8 +492,12 @@ int radeon_dp_mode_valid_helper(struct d
 		return MODE_CLOCK_HIGH;
 	dig_connector = radeon_connector->con_priv;
 
-	dp_clock =
-		radeon_dp_get_dp_link_clock(connector, dig_connector->dpcd, mode->clock);
+	ret = radeon_dp_get_dp_link_config(connector, dig_connector->dpcd,
+					   mode->clock,
+					   &dp_lanes,
+					   &dp_clock);
+	if (ret)
+		return MODE_CLOCK_HIGH;
 
 	if ((dp_clock == 540000) &&
 	    (!radeon_connector_is_dp12_capable(connector)))
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/radeon/atombios_encoders.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/radeon/atombios_encoders.c
@@ -120,6 +120,7 @@ atombios_set_backlight_level(struct rade
 		case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
 		case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
 		case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
+		case ENCODER_OBJECT_ID_INTERNAL_UNIPHY3:
 			if (dig->backlight_level == 0)
 				atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_LCD_BLOFF, 0, 0);
 			else {
@@ -310,6 +311,10 @@ static bool radeon_atom_mode_fixup(struc
 	    && (mode->crtc_vsync_start < (mode->crtc_vdisplay + 2)))
 		adjusted_mode->crtc_vsync_start = adjusted_mode->crtc_vdisplay + 2;
 
+	/* vertical FP must be at least 1 */
+	if (mode->crtc_vsync_start == mode->crtc_vdisplay)
+		adjusted_mode->crtc_vsync_start++;
+
 	/* get the native mode for scaling */
 	if (radeon_encoder->active_device & (ATOM_DEVICE_LCD_SUPPORT)) {
 		radeon_panel_mode_fixup(encoder, adjusted_mode);
@@ -892,8 +897,6 @@ atombios_dig_encoder_setup2(struct drm_e
 			else
 				args.v1.ucLaneNum = 4;
 
-			if (ENCODER_MODE_IS_DP(args.v1.ucEncoderMode) && (dp_clock == 270000))
-				args.v1.ucConfig |= ATOM_ENCODER_CONFIG_DPLINKRATE_2_70GHZ;
 			switch (radeon_encoder->encoder_id) {
 			case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
 				args.v1.ucConfig = ATOM_ENCODER_CONFIG_V2_TRANSMITTER1;
@@ -910,6 +913,10 @@ atombios_dig_encoder_setup2(struct drm_e
 				args.v1.ucConfig |= ATOM_ENCODER_CONFIG_LINKB;
 			else
 				args.v1.ucConfig |= ATOM_ENCODER_CONFIG_LINKA;
+
+			if (ENCODER_MODE_IS_DP(args.v1.ucEncoderMode) && (dp_clock == 270000))
+				args.v1.ucConfig |= ATOM_ENCODER_CONFIG_DPLINKRATE_2_70GHZ;
+
 			break;
 		case 2:
 		case 3:
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/radeon/dce6_afmt.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/radeon/dce6_afmt.c
@@ -301,6 +301,14 @@ void dce6_dp_audio_set_dto(struct radeon
 	 * is the numerator, DCCG_AUDIO_DTOx_MODULE is the denominator
 	 */
 	if (ASIC_IS_DCE8(rdev)) {
+		unsigned int div = (RREG32(DENTIST_DISPCLK_CNTL) &
+			DENTIST_DPREFCLK_WDIVIDER_MASK) >>
+			DENTIST_DPREFCLK_WDIVIDER_SHIFT;
+		div = radeon_audio_decode_dfs_div(div);
+
+		if (div)
+			clock = clock * 100 / div;
+
 		WREG32(DCE8_DCCG_AUDIO_DTO1_PHASE, 24000);
 		WREG32(DCE8_DCCG_AUDIO_DTO1_MODULE, clock);
 	} else {
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/radeon/evergreen.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/radeon/evergreen.c
@@ -2608,10 +2608,152 @@ static void evergreen_agp_enable(struct
 	WREG32(VM_CONTEXT1_CNTL, 0);
 }
 
+static const unsigned ni_dig_offsets[] =
+{
+	NI_DIG0_REGISTER_OFFSET,
+	NI_DIG1_REGISTER_OFFSET,
+	NI_DIG2_REGISTER_OFFSET,
+	NI_DIG3_REGISTER_OFFSET,
+	NI_DIG4_REGISTER_OFFSET,
+	NI_DIG5_REGISTER_OFFSET
+};
+
+static const unsigned ni_tx_offsets[] =
+{
+	NI_DCIO_UNIPHY0_UNIPHY_TX_CONTROL1,
+	NI_DCIO_UNIPHY1_UNIPHY_TX_CONTROL1,
+	NI_DCIO_UNIPHY2_UNIPHY_TX_CONTROL1,
+	NI_DCIO_UNIPHY3_UNIPHY_TX_CONTROL1,
+	NI_DCIO_UNIPHY4_UNIPHY_TX_CONTROL1,
+	NI_DCIO_UNIPHY5_UNIPHY_TX_CONTROL1
+};
+
+static const unsigned evergreen_dp_offsets[] =
+{
+	EVERGREEN_DP0_REGISTER_OFFSET,
+	EVERGREEN_DP1_REGISTER_OFFSET,
+	EVERGREEN_DP2_REGISTER_OFFSET,
+	EVERGREEN_DP3_REGISTER_OFFSET,
+	EVERGREEN_DP4_REGISTER_OFFSET,
+	EVERGREEN_DP5_REGISTER_OFFSET
+};
+
+
+/*
+ * Assumption is that EVERGREEN_CRTC_MASTER_EN enable for requested crtc
+ * We go from crtc to connector and it is not relible  since it
+ * should be an opposite direction .If crtc is enable then
+ * find the dig_fe which selects this crtc and insure that it enable.
+ * if such dig_fe is found then find dig_be which selects found dig_be and
+ * insure that it enable and in DP_SST mode.
+ * if UNIPHY_PLL_CONTROL1.enable then we should disconnect timing
+ * from dp symbols clocks .
+ */
+static bool evergreen_is_dp_sst_stream_enabled(struct radeon_device *rdev,
+					       unsigned crtc_id, unsigned *ret_dig_fe)
+{
+	unsigned i;
+	unsigned dig_fe;
+	unsigned dig_be;
+	unsigned dig_en_be;
+	unsigned uniphy_pll;
+	unsigned digs_fe_selected;
+	unsigned dig_be_mode;
+	unsigned dig_fe_mask;
+	bool is_enabled = false;
+	bool found_crtc = false;
+
+	/* loop through all running dig_fe to find selected crtc */
+	for (i = 0; i < ARRAY_SIZE(ni_dig_offsets); i++) {
+		dig_fe = RREG32(NI_DIG_FE_CNTL + ni_dig_offsets[i]);
+		if (dig_fe & NI_DIG_FE_CNTL_SYMCLK_FE_ON &&
+		    crtc_id == NI_DIG_FE_CNTL_SOURCE_SELECT(dig_fe)) {
+			/* found running pipe */
+			found_crtc = true;
+			dig_fe_mask = 1 << i;
+			dig_fe = i;
+			break;
+		}
+	}
+
+	if (found_crtc) {
+		/* loop through all running dig_be to find selected dig_fe */
+		for (i = 0; i < ARRAY_SIZE(ni_dig_offsets); i++) {
+			dig_be = RREG32(NI_DIG_BE_CNTL + ni_dig_offsets[i]);
+			/* if dig_fe_selected by dig_be? */
+			digs_fe_selected = NI_DIG_BE_CNTL_FE_SOURCE_SELECT(dig_be);
+			dig_be_mode = NI_DIG_FE_CNTL_MODE(dig_be);
+			if (dig_fe_mask &  digs_fe_selected &&
+			    /* if dig_be in sst mode? */
+			    dig_be_mode == NI_DIG_BE_DPSST) {
+				dig_en_be = RREG32(NI_DIG_BE_EN_CNTL +
+						   ni_dig_offsets[i]);
+				uniphy_pll = RREG32(NI_DCIO_UNIPHY0_PLL_CONTROL1 +
+						    ni_tx_offsets[i]);
+				/* dig_be enable and tx is running */
+				if (dig_en_be & NI_DIG_BE_EN_CNTL_ENABLE &&
+				    dig_en_be & NI_DIG_BE_EN_CNTL_SYMBCLK_ON &&
+				    uniphy_pll & NI_DCIO_UNIPHY0_PLL_CONTROL1_ENABLE) {
+					is_enabled = true;
+					*ret_dig_fe = dig_fe;
+					break;
+				}
+			}
+		}
+	}
+
+	return is_enabled;
+}
+
+/*
+ * Blank dig when in dp sst mode
+ * Dig ignores crtc timing
+ */
+static void evergreen_blank_dp_output(struct radeon_device *rdev,
+				      unsigned dig_fe)
+{
+	unsigned stream_ctrl;
+	unsigned fifo_ctrl;
+	unsigned counter = 0;
+
+	if (dig_fe >= ARRAY_SIZE(evergreen_dp_offsets)) {
+		DRM_ERROR("invalid dig_fe %d\n", dig_fe);
+		return;
+	}
+
+	stream_ctrl = RREG32(EVERGREEN_DP_VID_STREAM_CNTL +
+			     evergreen_dp_offsets[dig_fe]);
+	if (!(stream_ctrl & EVERGREEN_DP_VID_STREAM_CNTL_ENABLE)) {
+		DRM_ERROR("dig %d , should be enable\n", dig_fe);
+		return;
+	}
+
+	stream_ctrl &=~EVERGREEN_DP_VID_STREAM_CNTL_ENABLE;
+	WREG32(EVERGREEN_DP_VID_STREAM_CNTL +
+	       evergreen_dp_offsets[dig_fe], stream_ctrl);
+
+	stream_ctrl = RREG32(EVERGREEN_DP_VID_STREAM_CNTL +
+			     evergreen_dp_offsets[dig_fe]);
+	while (counter < 32 && stream_ctrl & EVERGREEN_DP_VID_STREAM_STATUS) {
+		msleep(1);
+		counter++;
+		stream_ctrl = RREG32(EVERGREEN_DP_VID_STREAM_CNTL +
+				     evergreen_dp_offsets[dig_fe]);
+	}
+	if (counter >= 32 )
+		DRM_ERROR("counter exceeds %d\n", counter);
+
+	fifo_ctrl = RREG32(EVERGREEN_DP_STEER_FIFO + evergreen_dp_offsets[dig_fe]);
+	fifo_ctrl |= EVERGREEN_DP_STEER_FIFO_RESET;
+	WREG32(EVERGREEN_DP_STEER_FIFO + evergreen_dp_offsets[dig_fe], fifo_ctrl);
+
+}
+
 void evergreen_mc_stop(struct radeon_device *rdev, struct evergreen_mc_save *save)
 {
 	u32 crtc_enabled, tmp, frame_count, blackout;
 	int i, j;
+	unsigned dig_fe;
 
 	if (!ASIC_IS_NODCE(rdev)) {
 		save->vga_render_control = RREG32(VGA_RENDER_CONTROL);
@@ -2651,7 +2793,17 @@ void evergreen_mc_stop(struct radeon_dev
 					break;
 				udelay(1);
 			}
-
+			/*we should disable dig if it drives dp sst*/
+			/*but we are in radeon_device_init and the topology is unknown*/
+			/*and it is available after radeon_modeset_init*/
+			/*the following method radeon_atom_encoder_dpms_dig*/
+			/*does the job if we initialize it properly*/
+			/*for now we do it this manually*/
+			/**/
+			if (ASIC_IS_DCE5(rdev) &&
+			    evergreen_is_dp_sst_stream_enabled(rdev, i ,&dig_fe))
+				evergreen_blank_dp_output(rdev, dig_fe);
+			/*we could remove 6 lines below*/
 			/* XXX this is a hack to avoid strange behavior with EFI on certain systems */
 			WREG32(EVERGREEN_CRTC_UPDATE_LOCK + crtc_offsets[i], 1);
 			tmp = RREG32(EVERGREEN_CRTC_CONTROL + crtc_offsets[i]);
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/radeon/evergreen_hdmi.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/radeon/evergreen_hdmi.c
@@ -289,6 +289,16 @@ void dce4_dp_audio_set_dto(struct radeon
 	 * number (coefficient of two integer numbers.  DCCG_AUDIO_DTOx_PHASE
 	 * is the numerator, DCCG_AUDIO_DTOx_MODULE is the denominator
 	 */
+	if (ASIC_IS_DCE41(rdev)) {
+		unsigned int div = (RREG32(DCE41_DENTIST_DISPCLK_CNTL) &
+			DENTIST_DPREFCLK_WDIVIDER_MASK) >>
+			DENTIST_DPREFCLK_WDIVIDER_SHIFT;
+		div = radeon_audio_decode_dfs_div(div);
+
+		if (div)
+			clock = 100 * clock / div;
+	}
+
 	WREG32(DCCG_AUDIO_DTO1_PHASE, 24000);
 	WREG32(DCCG_AUDIO_DTO1_MODULE, clock);
 }
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/radeon/evergreen_reg.h
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/radeon/evergreen_reg.h
@@ -250,8 +250,43 @@
 
 /* HDMI blocks at 0x7030, 0x7c30, 0x10830, 0x11430, 0x12030, 0x12c30 */
 #define EVERGREEN_HDMI_BASE				0x7030
+/*DIG block*/
+#define NI_DIG0_REGISTER_OFFSET                 (0x7000  - 0x7000)
+#define NI_DIG1_REGISTER_OFFSET                 (0x7C00  - 0x7000)
+#define NI_DIG2_REGISTER_OFFSET                 (0x10800 - 0x7000)
+#define NI_DIG3_REGISTER_OFFSET                 (0x11400 - 0x7000)
+#define NI_DIG4_REGISTER_OFFSET                 (0x12000 - 0x7000)
+#define NI_DIG5_REGISTER_OFFSET                 (0x12C00 - 0x7000)
+
+
+#define NI_DIG_FE_CNTL                               0x7000
+#       define NI_DIG_FE_CNTL_SOURCE_SELECT(x)        ((x) & 0x3)
+#       define NI_DIG_FE_CNTL_SYMCLK_FE_ON            (1<<24)
+
+
+#define NI_DIG_BE_CNTL                    0x7140
+#       define NI_DIG_BE_CNTL_FE_SOURCE_SELECT(x)     (((x) >> 8 ) & 0x3F)
+#       define NI_DIG_FE_CNTL_MODE(x)                 (((x) >> 16) & 0x7 )
+
+#define NI_DIG_BE_EN_CNTL                              0x7144
+#       define NI_DIG_BE_EN_CNTL_ENABLE               (1 << 0)
+#       define NI_DIG_BE_EN_CNTL_SYMBCLK_ON           (1 << 8)
+#       define NI_DIG_BE_DPSST 0
 
 /* Display Port block */
+#define EVERGREEN_DP0_REGISTER_OFFSET                 (0x730C  - 0x730C)
+#define EVERGREEN_DP1_REGISTER_OFFSET                 (0x7F0C  - 0x730C)
+#define EVERGREEN_DP2_REGISTER_OFFSET                 (0x10B0C - 0x730C)
+#define EVERGREEN_DP3_REGISTER_OFFSET                 (0x1170C - 0x730C)
+#define EVERGREEN_DP4_REGISTER_OFFSET                 (0x1230C - 0x730C)
+#define EVERGREEN_DP5_REGISTER_OFFSET                 (0x12F0C - 0x730C)
+
+
+#define EVERGREEN_DP_VID_STREAM_CNTL                    0x730C
+#       define EVERGREEN_DP_VID_STREAM_CNTL_ENABLE     (1 << 0)
+#       define EVERGREEN_DP_VID_STREAM_STATUS          (1 <<16)
+#define EVERGREEN_DP_STEER_FIFO                         0x7310
+#       define EVERGREEN_DP_STEER_FIFO_RESET           (1 << 0)
 #define EVERGREEN_DP_SEC_CNTL                           0x7280
 #       define EVERGREEN_DP_SEC_STREAM_ENABLE           (1 << 0)
 #       define EVERGREEN_DP_SEC_ASP_ENABLE              (1 << 4)
@@ -266,4 +301,15 @@
 #       define EVERGREEN_DP_SEC_N_BASE_MULTIPLE(x)      (((x) & 0xf) << 24)
 #       define EVERGREEN_DP_SEC_SS_EN                   (1 << 28)
 
+/*DCIO_UNIPHY block*/
+#define NI_DCIO_UNIPHY0_UNIPHY_TX_CONTROL1            (0x6600  -0x6600)
+#define NI_DCIO_UNIPHY1_UNIPHY_TX_CONTROL1            (0x6640  -0x6600)
+#define NI_DCIO_UNIPHY2_UNIPHY_TX_CONTROL1            (0x6680 - 0x6600)
+#define NI_DCIO_UNIPHY3_UNIPHY_TX_CONTROL1            (0x66C0 - 0x6600)
+#define NI_DCIO_UNIPHY4_UNIPHY_TX_CONTROL1            (0x6700 - 0x6600)
+#define NI_DCIO_UNIPHY5_UNIPHY_TX_CONTROL1            (0x6740 - 0x6600)
+
+#define NI_DCIO_UNIPHY0_PLL_CONTROL1                   0x6618
+#       define NI_DCIO_UNIPHY0_PLL_CONTROL1_ENABLE     (1 << 0)
+
 #endif
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/radeon/evergreend.h
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/radeon/evergreend.h
@@ -511,6 +511,11 @@
 #define DCCG_AUDIO_DTO1_CNTL              0x05cc
 #       define DCCG_AUDIO_DTO1_USE_512FBR_DTO (1 << 3)
 
+#define DCE41_DENTIST_DISPCLK_CNTL			0x049c
+#       define DENTIST_DPREFCLK_WDIVIDER(x)		(((x) & 0x7f) << 24)
+#       define DENTIST_DPREFCLK_WDIVIDER_MASK		(0x7f << 24)
+#       define DENTIST_DPREFCLK_WDIVIDER_SHIFT		24
+
 /* DCE 4.0 AFMT */
 #define HDMI_CONTROL                         0x7030
 #       define HDMI_KEEPOUT_MODE             (1 << 0)
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/radeon/r100.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/radeon/r100.c
@@ -3150,7 +3150,8 @@ void r100_bandwidth_update(struct radeon
 {
 	fixed20_12 trcd_ff, trp_ff, tras_ff, trbs_ff, tcas_ff;
 	fixed20_12 sclk_ff, mclk_ff, sclk_eff_ff, sclk_delay_ff;
-	fixed20_12 peak_disp_bw, mem_bw, pix_clk, pix_clk2, temp_ff, crit_point_ff;
+	fixed20_12 peak_disp_bw, mem_bw, pix_clk, pix_clk2, temp_ff;
+	fixed20_12 crit_point_ff = {0};
 	uint32_t temp, data, mem_trcd, mem_trp, mem_tras;
 	fixed20_12 memtcas_ff[8] = {
 		dfixed_init(1),
@@ -3204,7 +3205,7 @@ void r100_bandwidth_update(struct radeon
 	fixed20_12 min_mem_eff;
 	fixed20_12 mc_latency_sclk, mc_latency_mclk, k1;
 	fixed20_12 cur_latency_mclk, cur_latency_sclk;
-	fixed20_12 disp_latency, disp_latency_overhead, disp_drain_rate,
+	fixed20_12 disp_latency, disp_latency_overhead, disp_drain_rate = {0},
 		disp_drain_rate2, read_return_rate;
 	fixed20_12 time_disp1_drop_priority;
 	int c;
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/radeon/radeon.h
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/radeon/radeon.h
@@ -268,6 +268,7 @@ struct radeon_clock {
 	uint32_t current_dispclk;
 	uint32_t dp_extclk;
 	uint32_t max_pixel_clock;
+	uint32_t vco_freq;
 };
 
 /*
@@ -1889,7 +1890,7 @@ struct radeon_asic {
 		void (*pad_ib)(struct radeon_ib *ib);
 	} vm;
 	/* ring specific callbacks */
-	struct radeon_asic_ring *ring[RADEON_NUM_RINGS];
+	const struct radeon_asic_ring *ring[RADEON_NUM_RINGS];
 	/* irqs */
 	struct {
 		int (*set)(struct radeon_device *rdev);
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/radeon/radeon_asic.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/radeon/radeon_asic.c
@@ -179,7 +179,7 @@ void radeon_agp_disable(struct radeon_de
  * ASIC
  */
 
-static struct radeon_asic_ring r100_gfx_ring = {
+static const struct radeon_asic_ring r100_gfx_ring = {
 	.ib_execute = &r100_ring_ib_execute,
 	.emit_fence = &r100_fence_ring_emit,
 	.emit_semaphore = &r100_semaphore_ring_emit,
@@ -329,7 +329,7 @@ static struct radeon_asic r200_asic = {
 	},
 };
 
-static struct radeon_asic_ring r300_gfx_ring = {
+static const struct radeon_asic_ring r300_gfx_ring = {
 	.ib_execute = &r100_ring_ib_execute,
 	.emit_fence = &r300_fence_ring_emit,
 	.emit_semaphore = &r100_semaphore_ring_emit,
@@ -343,7 +343,7 @@ static struct radeon_asic_ring r300_gfx_
 	.set_wptr = &r100_gfx_set_wptr,
 };
 
-static struct radeon_asic_ring rv515_gfx_ring = {
+static const struct radeon_asic_ring rv515_gfx_ring = {
 	.ib_execute = &r100_ring_ib_execute,
 	.emit_fence = &r300_fence_ring_emit,
 	.emit_semaphore = &r100_semaphore_ring_emit,
@@ -901,7 +901,7 @@ static struct radeon_asic r520_asic = {
 	},
 };
 
-static struct radeon_asic_ring r600_gfx_ring = {
+static const struct radeon_asic_ring r600_gfx_ring = {
 	.ib_execute = &r600_ring_ib_execute,
 	.emit_fence = &r600_fence_ring_emit,
 	.emit_semaphore = &r600_semaphore_ring_emit,
@@ -914,7 +914,7 @@ static struct radeon_asic_ring r600_gfx_
 	.set_wptr = &r600_gfx_set_wptr,
 };
 
-static struct radeon_asic_ring r600_dma_ring = {
+static const struct radeon_asic_ring r600_dma_ring = {
 	.ib_execute = &r600_dma_ring_ib_execute,
 	.emit_fence = &r600_dma_fence_ring_emit,
 	.emit_semaphore = &r600_dma_semaphore_ring_emit,
@@ -999,7 +999,7 @@ static struct radeon_asic r600_asic = {
 	},
 };
 
-static struct radeon_asic_ring rv6xx_uvd_ring = {
+static const struct radeon_asic_ring rv6xx_uvd_ring = {
 	.ib_execute = &uvd_v1_0_ib_execute,
 	.emit_fence = &uvd_v1_0_fence_emit,
 	.emit_semaphore = &uvd_v1_0_semaphore_emit,
@@ -1198,7 +1198,7 @@ static struct radeon_asic rs780_asic = {
 	},
 };
 
-static struct radeon_asic_ring rv770_uvd_ring = {
+static const struct radeon_asic_ring rv770_uvd_ring = {
 	.ib_execute = &uvd_v1_0_ib_execute,
 	.emit_fence = &uvd_v2_2_fence_emit,
 	.emit_semaphore = &uvd_v2_2_semaphore_emit,
@@ -1305,7 +1305,7 @@ static struct radeon_asic rv770_asic = {
 	},
 };
 
-static struct radeon_asic_ring evergreen_gfx_ring = {
+static const struct radeon_asic_ring evergreen_gfx_ring = {
 	.ib_execute = &evergreen_ring_ib_execute,
 	.emit_fence = &r600_fence_ring_emit,
 	.emit_semaphore = &r600_semaphore_ring_emit,
@@ -1318,7 +1318,7 @@ static struct radeon_asic_ring evergreen
 	.set_wptr = &r600_gfx_set_wptr,
 };
 
-static struct radeon_asic_ring evergreen_dma_ring = {
+static const struct radeon_asic_ring evergreen_dma_ring = {
 	.ib_execute = &evergreen_dma_ring_ib_execute,
 	.emit_fence = &evergreen_dma_fence_ring_emit,
 	.emit_semaphore = &r600_dma_semaphore_ring_emit,
@@ -1612,7 +1612,7 @@ static struct radeon_asic btc_asic = {
 	},
 };
 
-static struct radeon_asic_ring cayman_gfx_ring = {
+static const struct radeon_asic_ring cayman_gfx_ring = {
 	.ib_execute = &cayman_ring_ib_execute,
 	.ib_parse = &evergreen_ib_parse,
 	.emit_fence = &cayman_fence_ring_emit,
@@ -1627,7 +1627,7 @@ static struct radeon_asic_ring cayman_gf
 	.set_wptr = &cayman_gfx_set_wptr,
 };
 
-static struct radeon_asic_ring cayman_dma_ring = {
+static const struct radeon_asic_ring cayman_dma_ring = {
 	.ib_execute = &cayman_dma_ring_ib_execute,
 	.ib_parse = &evergreen_dma_ib_parse,
 	.emit_fence = &evergreen_dma_fence_ring_emit,
@@ -1642,7 +1642,7 @@ static struct radeon_asic_ring cayman_dm
 	.set_wptr = &cayman_dma_set_wptr
 };
 
-static struct radeon_asic_ring cayman_uvd_ring = {
+static const struct radeon_asic_ring cayman_uvd_ring = {
 	.ib_execute = &uvd_v1_0_ib_execute,
 	.emit_fence = &uvd_v2_2_fence_emit,
 	.emit_semaphore = &uvd_v3_1_semaphore_emit,
@@ -1760,7 +1760,7 @@ static struct radeon_asic cayman_asic =
 	},
 };
 
-static struct radeon_asic_ring trinity_vce_ring = {
+static const struct radeon_asic_ring trinity_vce_ring = {
 	.ib_execute = &radeon_vce_ib_execute,
 	.emit_fence = &radeon_vce_fence_emit,
 	.emit_semaphore = &radeon_vce_semaphore_emit,
@@ -1881,7 +1881,7 @@ static struct radeon_asic trinity_asic =
 	},
 };
 
-static struct radeon_asic_ring si_gfx_ring = {
+static const struct radeon_asic_ring si_gfx_ring = {
 	.ib_execute = &si_ring_ib_execute,
 	.ib_parse = &si_ib_parse,
 	.emit_fence = &si_fence_ring_emit,
@@ -1896,7 +1896,7 @@ static struct radeon_asic_ring si_gfx_ri
 	.set_wptr = &cayman_gfx_set_wptr,
 };
 
-static struct radeon_asic_ring si_dma_ring = {
+static const struct radeon_asic_ring si_dma_ring = {
 	.ib_execute = &cayman_dma_ring_ib_execute,
 	.ib_parse = &evergreen_dma_ib_parse,
 	.emit_fence = &evergreen_dma_fence_ring_emit,
@@ -2023,7 +2023,7 @@ static struct radeon_asic si_asic = {
 	},
 };
 
-static struct radeon_asic_ring ci_gfx_ring = {
+static const struct radeon_asic_ring ci_gfx_ring = {
 	.ib_execute = &cik_ring_ib_execute,
 	.ib_parse = &cik_ib_parse,
 	.emit_fence = &cik_fence_gfx_ring_emit,
@@ -2038,7 +2038,7 @@ static struct radeon_asic_ring ci_gfx_ri
 	.set_wptr = &cik_gfx_set_wptr,
 };
 
-static struct radeon_asic_ring ci_cp_ring = {
+static const struct radeon_asic_ring ci_cp_ring = {
 	.ib_execute = &cik_ring_ib_execute,
 	.ib_parse = &cik_ib_parse,
 	.emit_fence = &cik_fence_compute_ring_emit,
@@ -2053,7 +2053,7 @@ static struct radeon_asic_ring ci_cp_rin
 	.set_wptr = &cik_compute_set_wptr,
 };
 
-static struct radeon_asic_ring ci_dma_ring = {
+static const struct radeon_asic_ring ci_dma_ring = {
 	.ib_execute = &cik_sdma_ring_ib_execute,
 	.ib_parse = &cik_ib_parse,
 	.emit_fence = &cik_sdma_fence_ring_emit,
@@ -2068,7 +2068,7 @@ static struct radeon_asic_ring ci_dma_ri
 	.set_wptr = &cik_sdma_set_wptr,
 };
 
-static struct radeon_asic_ring ci_vce_ring = {
+static const struct radeon_asic_ring ci_vce_ring = {
 	.ib_execute = &radeon_vce_ib_execute,
 	.emit_fence = &radeon_vce_fence_emit,
 	.emit_semaphore = &radeon_vce_semaphore_emit,
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/radeon/radeon_atombios.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/radeon/radeon_atombios.c
@@ -437,7 +437,9 @@ static bool radeon_atom_apply_quirks(str
 	}
 
 	/* Fujitsu D3003-S2 board lists DVI-I as DVI-D and VGA */
-	if (((dev->pdev->device == 0x9802) || (dev->pdev->device == 0x9806)) &&
+	if (((dev->pdev->device == 0x9802) ||
+	     (dev->pdev->device == 0x9805) ||
+	     (dev->pdev->device == 0x9806)) &&
 	    (dev->pdev->subsystem_vendor == 0x1734) &&
 	    (dev->pdev->subsystem_device == 0x11bd)) {
 		if (*connector_type == DRM_MODE_CONNECTOR_VGA) {
@@ -448,14 +450,6 @@ static bool radeon_atom_apply_quirks(str
 		}
 	}
 
-	/* Fujitsu D3003-S2 board lists DVI-I as DVI-I and VGA */
-	if ((dev->pdev->device == 0x9805) &&
-	    (dev->pdev->subsystem_vendor == 0x1734) &&
-	    (dev->pdev->subsystem_device == 0x11bd)) {
-		if (*connector_type == DRM_MODE_CONNECTOR_VGA)
-			return false;
-	}
-
 	return true;
 }
 
@@ -1112,6 +1106,31 @@ union firmware_info {
 	ATOM_FIRMWARE_INFO_V2_2 info_22;
 };
 
+union igp_info {
+	struct _ATOM_INTEGRATED_SYSTEM_INFO info;
+	struct _ATOM_INTEGRATED_SYSTEM_INFO_V2 info_2;
+	struct _ATOM_INTEGRATED_SYSTEM_INFO_V6 info_6;
+	struct _ATOM_INTEGRATED_SYSTEM_INFO_V1_7 info_7;
+	struct _ATOM_INTEGRATED_SYSTEM_INFO_V1_8 info_8;
+};
+
+static void radeon_atombios_get_dentist_vco_freq(struct radeon_device *rdev)
+{
+	struct radeon_mode_info *mode_info = &rdev->mode_info;
+	int index = GetIndexIntoMasterTable(DATA, IntegratedSystemInfo);
+	union igp_info *igp_info;
+	u8 frev, crev;
+	u16 data_offset;
+
+	if (atom_parse_data_header(mode_info->atom_context, index, NULL,
+			&frev, &crev, &data_offset)) {
+		igp_info = (union igp_info *)(mode_info->atom_context->bios +
+			data_offset);
+		rdev->clock.vco_freq =
+			le32_to_cpu(igp_info->info_6.ulDentistVCOFreq);
+	}
+}
+
 bool radeon_atom_get_clock_info(struct drm_device *dev)
 {
 	struct radeon_device *rdev = dev->dev_private;
@@ -1136,7 +1155,7 @@ bool radeon_atom_get_clock_info(struct d
 		    le16_to_cpu(firmware_info->info.usReferenceClock);
 		p1pll->reference_div = 0;
 
-		if (crev < 2)
+		if ((frev < 2) && (crev < 2))
 			p1pll->pll_out_min =
 				le16_to_cpu(firmware_info->info.usMinPixelClockPLL_Output);
 		else
@@ -1145,7 +1164,7 @@ bool radeon_atom_get_clock_info(struct d
 		p1pll->pll_out_max =
 		    le32_to_cpu(firmware_info->info.ulMaxPixelClockPLL_Output);
 
-		if (crev >= 4) {
+		if (((frev < 2) && (crev >= 4)) || (frev >= 2)) {
 			p1pll->lcd_pll_out_min =
 				le16_to_cpu(firmware_info->info_14.usLcdMinPixelClockPLL_Output) * 100;
 			if (p1pll->lcd_pll_out_min == 0)
@@ -1263,20 +1282,25 @@ bool radeon_atom_get_clock_info(struct d
 		rdev->mode_info.firmware_flags =
 			le16_to_cpu(firmware_info->info.usFirmwareCapability.susAccess);
 
+		if (ASIC_IS_DCE8(rdev))
+			rdev->clock.vco_freq =
+				le32_to_cpu(firmware_info->info_22.ulGPUPLL_OutputFreq);
+		else if (ASIC_IS_DCE5(rdev))
+			rdev->clock.vco_freq = rdev->clock.current_dispclk;
+		else if (ASIC_IS_DCE41(rdev))
+			radeon_atombios_get_dentist_vco_freq(rdev);
+		else
+			rdev->clock.vco_freq = rdev->clock.current_dispclk;
+
+		if (rdev->clock.vco_freq == 0)
+			rdev->clock.vco_freq = 360000;	/* 3.6 GHz */
+
 		return true;
 	}
 
 	return false;
 }
 
-union igp_info {
-	struct _ATOM_INTEGRATED_SYSTEM_INFO info;
-	struct _ATOM_INTEGRATED_SYSTEM_INFO_V2 info_2;
-	struct _ATOM_INTEGRATED_SYSTEM_INFO_V6 info_6;
-	struct _ATOM_INTEGRATED_SYSTEM_INFO_V1_7 info_7;
-	struct _ATOM_INTEGRATED_SYSTEM_INFO_V1_8 info_8;
-};
-
 bool radeon_atombios_sideport_present(struct radeon_device *rdev)
 {
 	struct radeon_mode_info *mode_info = &rdev->mode_info;
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/radeon/radeon_atpx_handler.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/radeon/radeon_atpx_handler.c
@@ -10,6 +10,7 @@
 #include <linux/slab.h>
 #include <linux/acpi.h>
 #include <linux/pci.h>
+#include <linux/delay.h>
 
 #include "radeon_acpi.h"
 
@@ -255,6 +256,10 @@ static int radeon_atpx_set_discrete_stat
 		if (!info)
 			return -EIO;
 		kfree(info);
+
+		/* 200ms delay is required after off */
+		if (state == 0)
+			msleep(200);
 	}
 	return 0;
 }
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/radeon/radeon_audio.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/radeon/radeon_audio.c
@@ -739,9 +739,6 @@ static void radeon_audio_dp_mode_set(str
 	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
 	struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
 	struct drm_connector *connector = radeon_get_connector_for_encoder(encoder);
-	struct radeon_connector *radeon_connector = to_radeon_connector(connector);
-	struct radeon_connector_atom_dig *dig_connector =
-		radeon_connector->con_priv;
 
 	if (!dig || !dig->afmt)
 		return;
@@ -753,10 +750,7 @@ static void radeon_audio_dp_mode_set(str
 		radeon_audio_write_speaker_allocation(encoder);
 		radeon_audio_write_sad_regs(encoder);
 		radeon_audio_write_latency_fields(encoder, mode);
-		if (rdev->clock.dp_extclk || ASIC_IS_DCE5(rdev))
-			radeon_audio_set_dto(encoder, rdev->clock.default_dispclk * 10);
-		else
-			radeon_audio_set_dto(encoder, dig_connector->dp_clock);
+		radeon_audio_set_dto(encoder, rdev->clock.vco_freq * 10);
 		radeon_audio_set_audio_packet(encoder);
 		radeon_audio_select_pin(encoder);
 
@@ -781,3 +775,15 @@ void radeon_audio_dpms(struct drm_encode
 	if (radeon_encoder->audio && radeon_encoder->audio->dpms)
 		radeon_encoder->audio->dpms(encoder, mode == DRM_MODE_DPMS_ON);
 }
+
+unsigned int radeon_audio_decode_dfs_div(unsigned int div)
+{
+	if (div >= 8 && div < 64)
+		return (div - 8) * 25 + 200;
+	else if (div >= 64 && div < 96)
+		return (div - 64) * 50 + 1600;
+	else if (div >= 96 && div < 128)
+		return (div - 96) * 100 + 3200;
+	else
+		return 0;
+}
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/radeon/radeon_audio.h
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/radeon/radeon_audio.h
@@ -79,5 +79,6 @@ void radeon_audio_fini(struct radeon_dev
 void radeon_audio_mode_set(struct drm_encoder *encoder,
 	struct drm_display_mode *mode);
 void radeon_audio_dpms(struct drm_encoder *encoder, int mode);
+unsigned int radeon_audio_decode_dfs_div(unsigned int div);
 
 #endif
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/radeon/radeon_connectors.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/radeon/radeon_connectors.c
@@ -1996,10 +1996,12 @@ radeon_add_atom_connector(struct drm_dev
 						   rdev->mode_info.dither_property,
 						   RADEON_FMT_DITHER_DISABLE);
 
-			if (radeon_audio != 0)
+			if (radeon_audio != 0) {
 				drm_object_attach_property(&radeon_connector->base.base,
 							   rdev->mode_info.audio_property,
 							   RADEON_AUDIO_AUTO);
+				radeon_connector->audio = RADEON_AUDIO_AUTO;
+			}
 			if (ASIC_IS_DCE5(rdev))
 				drm_object_attach_property(&radeon_connector->base.base,
 							   rdev->mode_info.output_csc_property,
@@ -2056,7 +2058,6 @@ radeon_add_atom_connector(struct drm_dev
 							   RADEON_OUTPUT_CSC_BYPASS);
 			/* no HPD on analog connectors */
 			radeon_connector->hpd.hpd = RADEON_HPD_NONE;
-			connector->polled = DRM_CONNECTOR_POLL_CONNECT;
 			connector->interlace_allowed = true;
 			connector->doublescan_allowed = true;
 			break;
@@ -2124,6 +2125,7 @@ radeon_add_atom_connector(struct drm_dev
 				drm_object_attach_property(&radeon_connector->base.base,
 							   rdev->mode_info.audio_property,
 							   RADEON_AUDIO_AUTO);
+				radeon_connector->audio = RADEON_AUDIO_AUTO;
 			}
 			if (connector_type == DRM_MODE_CONNECTOR_DVII) {
 				radeon_connector->dac_load_detect = true;
@@ -2179,6 +2181,7 @@ radeon_add_atom_connector(struct drm_dev
 				drm_object_attach_property(&radeon_connector->base.base,
 							   rdev->mode_info.audio_property,
 							   RADEON_AUDIO_AUTO);
+				radeon_connector->audio = RADEON_AUDIO_AUTO;
 			}
 			if (ASIC_IS_DCE5(rdev))
 				drm_object_attach_property(&radeon_connector->base.base,
@@ -2231,6 +2234,7 @@ radeon_add_atom_connector(struct drm_dev
 				drm_object_attach_property(&radeon_connector->base.base,
 							   rdev->mode_info.audio_property,
 							   RADEON_AUDIO_AUTO);
+				radeon_connector->audio = RADEON_AUDIO_AUTO;
 			}
 			if (ASIC_IS_DCE5(rdev))
 				drm_object_attach_property(&radeon_connector->base.base,
@@ -2303,8 +2307,10 @@ radeon_add_atom_connector(struct drm_dev
 	}
 
 	if (radeon_connector->hpd.hpd == RADEON_HPD_NONE) {
-		if (i2c_bus->valid)
-			connector->polled = DRM_CONNECTOR_POLL_CONNECT;
+		if (i2c_bus->valid) {
+			connector->polled = DRM_CONNECTOR_POLL_CONNECT |
+			                    DRM_CONNECTOR_POLL_DISCONNECT;
+		}
 	} else
 		connector->polled = DRM_CONNECTOR_POLL_HPD;
 
@@ -2380,7 +2386,6 @@ radeon_add_legacy_connector(struct drm_d
 					      1);
 		/* no HPD on analog connectors */
 		radeon_connector->hpd.hpd = RADEON_HPD_NONE;
-		connector->polled = DRM_CONNECTOR_POLL_CONNECT;
 		connector->interlace_allowed = true;
 		connector->doublescan_allowed = true;
 		break;
@@ -2465,10 +2470,13 @@ radeon_add_legacy_connector(struct drm_d
 	}
 
 	if (radeon_connector->hpd.hpd == RADEON_HPD_NONE) {
-		if (i2c_bus->valid)
-			connector->polled = DRM_CONNECTOR_POLL_CONNECT;
+		if (i2c_bus->valid) {
+			connector->polled = DRM_CONNECTOR_POLL_CONNECT |
+			                    DRM_CONNECTOR_POLL_DISCONNECT;
+		}
 	} else
 		connector->polled = DRM_CONNECTOR_POLL_HPD;
+
 	connector->display_info.subpixel_order = subpixel_order;
 	drm_connector_register(connector);
 }
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/radeon/radeon_device.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/radeon/radeon_device.c
@@ -630,6 +630,23 @@ void radeon_gtt_location(struct radeon_d
 /*
  * GPU helpers function.
  */
+
+/**
+ * radeon_device_is_virtual - check if we are running is a virtual environment
+ *
+ * Check if the asic has been passed through to a VM (all asics).
+ * Used at driver startup.
+ * Returns true if virtual or false if not.
+ */
+static bool radeon_device_is_virtual(void)
+{
+#ifdef CONFIG_X86
+	return boot_cpu_has(X86_FEATURE_HYPERVISOR);
+#else
+	return false;
+#endif
+}
+
 /**
  * radeon_card_posted - check if the hw has already been initialized
  *
@@ -643,6 +660,10 @@ bool radeon_card_posted(struct radeon_de
 {
 	uint32_t reg;
 
+	/* for pass through, always force asic_init */
+	if (radeon_device_is_virtual())
+		return false;
+
 	/* required for EFI mode on macbook2,1 which uses an r5xx asic */
 	if (efi_enabled(EFI_BOOT) &&
 	    (rdev->pdev->subsystem_vendor == PCI_VENDOR_ID_APPLE) &&
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/radeon/radeon_display.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/radeon/radeon_display.c
@@ -403,7 +403,8 @@ static void radeon_flip_work_func(struct
 	struct drm_crtc *crtc = &radeon_crtc->base;
 	unsigned long flags;
 	int r;
-	int vpos, hpos, stat, min_udelay;
+	int vpos, hpos, stat, min_udelay = 0;
+	unsigned repcnt = 4;
 	struct drm_vblank_crtc *vblank = &crtc->dev->vblank[work->crtc_id];
 
         down_read(&rdev->exclusive_lock);
@@ -454,7 +455,7 @@ static void radeon_flip_work_func(struct
 	 * In practice this won't execute very often unless on very fast
 	 * machines because the time window for this to happen is very small.
 	 */
-	for (;;) {
+	while (radeon_crtc->enabled && --repcnt) {
 		/* GET_DISTANCE_TO_VBLANKSTART returns distance to real vblank
 		 * start in hpos, and to the "fudged earlier" vblank start in
 		 * vpos.
@@ -470,12 +471,24 @@ static void radeon_flip_work_func(struct
 			break;
 
 		/* Sleep at least until estimated real start of hw vblank */
-		spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
 		min_udelay = (-hpos + 1) * max(vblank->linedur_ns / 1000, 5);
+		if (min_udelay > vblank->framedur_ns / 2000) {
+			/* Don't wait ridiculously long - something is wrong */
+			repcnt = 0;
+			break;
+		}
+		spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
 		usleep_range(min_udelay, 2 * min_udelay);
 		spin_lock_irqsave(&crtc->dev->event_lock, flags);
 	};
 
+	if (!repcnt)
+		DRM_DEBUG_DRIVER("Delay problem on crtc %d: min_udelay %d, "
+				 "framedur %d, linedur %d, stat %d, vpos %d, "
+				 "hpos %d\n", work->crtc_id, min_udelay,
+				 vblank->framedur_ns / 1000,
+				 vblank->linedur_ns / 1000, stat, vpos, hpos);
+
 	/* do the flip (mmio) */
 	radeon_page_flip(rdev, radeon_crtc->crtc_id, work->base);
 
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/radeon/radeon_dp_auxch.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/radeon/radeon_dp_auxch.c
@@ -105,7 +105,7 @@ radeon_dp_aux_transfer_native(struct drm
 
 	tmp &= AUX_HPD_SEL(0x7);
 	tmp |= AUX_HPD_SEL(chan->rec.hpd);
-	tmp |= AUX_EN | AUX_LS_READ_EN;
+	tmp |= AUX_EN | AUX_LS_READ_EN | AUX_HPD_DISCON(0x1);
 
 	WREG32(AUX_CONTROL + aux_offset[instance], tmp);
 
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/radeon/radeon_dp_mst.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/radeon/radeon_dp_mst.c
@@ -525,11 +525,9 @@ static bool radeon_mst_mode_fixup(struct
 	drm_mode_set_crtcinfo(adjusted_mode, 0);
 	{
 	  struct radeon_connector_atom_dig *dig_connector;
-
 	  dig_connector = mst_enc->connector->con_priv;
 	  dig_connector->dp_lane_count = drm_dp_max_lane_count(dig_connector->dpcd);
-	  dig_connector->dp_clock = radeon_dp_get_max_link_rate(&mst_enc->connector->base,
-								dig_connector->dpcd);
+	  dig_connector->dp_clock = drm_dp_max_link_rate(dig_connector->dpcd);
 	  DRM_DEBUG_KMS("dig clock %p %d %d\n", dig_connector,
 			dig_connector->dp_lane_count, dig_connector->dp_clock);
 	}
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/radeon/radeon_fb.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/radeon/radeon_fb.c
@@ -283,7 +283,7 @@ out_unref:
 
 	}
 	if (fb && ret) {
-		drm_gem_object_unreference(gobj);
+		drm_gem_object_unreference_unlocked(gobj);
 		drm_framebuffer_unregister_private(fb);
 		drm_framebuffer_cleanup(fb);
 		kfree(fb);
@@ -293,7 +293,8 @@ out_unref:
 
 void radeon_fb_output_poll_changed(struct radeon_device *rdev)
 {
-	drm_fb_helper_hotplug_event(&rdev->mode_info.rfbdev->helper);
+	if (rdev->mode_info.rfbdev)
+		drm_fb_helper_hotplug_event(&rdev->mode_info.rfbdev->helper);
 }
 
 static int radeon_fbdev_destroy(struct drm_device *dev, struct radeon_fbdev *rfbdev)
@@ -326,6 +327,10 @@ int radeon_fbdev_init(struct radeon_devi
 	int bpp_sel = 32;
 	int ret;
 
+	/* don't enable fbdev if no connectors */
+	if (list_empty(&rdev->ddev->mode_config.connector_list))
+		return 0;
+
 	/* select 8 bpp console on RN50 or 16MB cards */
 	if (ASIC_IS_RN50(rdev) || rdev->mc.real_vram_size <= (32*1024*1024))
 		bpp_sel = 8;
@@ -378,11 +383,15 @@ void radeon_fbdev_fini(struct radeon_dev
 
 void radeon_fbdev_set_suspend(struct radeon_device *rdev, int state)
 {
-	fb_set_suspend(rdev->mode_info.rfbdev->helper.fbdev, state);
+	if (rdev->mode_info.rfbdev)
+		fb_set_suspend(rdev->mode_info.rfbdev->helper.fbdev, state);
 }
 
 bool radeon_fbdev_robj_is_fb(struct radeon_device *rdev, struct radeon_bo *robj)
 {
+	if (!rdev->mode_info.rfbdev)
+		return false;
+
 	if (robj == gem_to_radeon_bo(rdev->mode_info.rfbdev->rfb.obj))
 		return true;
 	return false;
@@ -390,12 +399,14 @@ bool radeon_fbdev_robj_is_fb(struct rade
 
 void radeon_fb_add_connector(struct radeon_device *rdev, struct drm_connector *connector)
 {
-	drm_fb_helper_add_one_connector(&rdev->mode_info.rfbdev->helper, connector);
+	if (rdev->mode_info.rfbdev)
+		drm_fb_helper_add_one_connector(&rdev->mode_info.rfbdev->helper, connector);
 }
 
 void radeon_fb_remove_connector(struct radeon_device *rdev, struct drm_connector *connector)
 {
-	drm_fb_helper_remove_one_connector(&rdev->mode_info.rfbdev->helper, connector);
+	if (rdev->mode_info.rfbdev)
+		drm_fb_helper_remove_one_connector(&rdev->mode_info.rfbdev->helper, connector);
 }
 
 void radeon_fbdev_restore_mode(struct radeon_device *rdev)
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/radeon/radeon_fence.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/radeon/radeon_fence.c
@@ -130,7 +130,7 @@ int radeon_fence_emit(struct radeon_devi
 		      struct radeon_fence **fence,
 		      int ring)
 {
-	u64 seq = ++rdev->fence_drv[ring].sync_seq[ring];
+	u64 seq;
 
 	/* we are protected by the ring emission mutex */
 	*fence = kmalloc(sizeof(struct radeon_fence), GFP_KERNEL);
@@ -138,7 +138,7 @@ int radeon_fence_emit(struct radeon_devi
 		return -ENOMEM;
 	}
 	(*fence)->rdev = rdev;
-	(*fence)->seq = seq;
+	(*fence)->seq = seq = ++rdev->fence_drv[ring].sync_seq[ring];
 	(*fence)->ring = ring;
 	(*fence)->is_vm_update = false;
 	fence_init(&(*fence)->base, &radeon_fence_ops,
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/radeon/radeon_gem.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/radeon/radeon_gem.c
@@ -663,6 +663,7 @@ int radeon_gem_va_ioctl(struct drm_devic
 	bo_va = radeon_vm_bo_find(&fpriv->vm, rbo);
 	if (!bo_va) {
 		args->operation = RADEON_VA_RESULT_ERROR;
+		radeon_bo_unreserve(rbo);
 		drm_gem_object_unreference_unlocked(gobj);
 		return -ENOENT;
 	}
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/radeon/radeon_kms.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/radeon/radeon_kms.c
@@ -748,19 +748,19 @@ void radeon_driver_preclose_kms(struct d
  * radeon_get_vblank_counter_kms - get frame count
  *
  * @dev: drm dev pointer
- * @crtc: crtc to get the frame count from
+ * @pipe: crtc to get the frame count from
  *
  * Gets the frame count on the requested crtc (all asics).
  * Returns frame count on success, -EINVAL on failure.
  */
-u32 radeon_get_vblank_counter_kms(struct drm_device *dev, int crtc)
+u32 radeon_get_vblank_counter_kms(struct drm_device *dev, unsigned int pipe)
 {
 	int vpos, hpos, stat;
 	u32 count;
 	struct radeon_device *rdev = dev->dev_private;
 
-	if (crtc < 0 || crtc >= rdev->num_crtc) {
-		DRM_ERROR("Invalid crtc %d\n", crtc);
+	if (pipe < 0 || pipe >= rdev->num_crtc) {
+		DRM_ERROR("Invalid crtc %u\n", pipe);
 		return -EINVAL;
 	}
 
@@ -772,29 +772,29 @@ u32 radeon_get_vblank_counter_kms(struct
 	 * and start of vsync, so vpos >= 0 means to bump the hw frame counter
 	 * result by 1 to give the proper appearance to caller.
 	 */
-	if (rdev->mode_info.crtcs[crtc]) {
+	if (rdev->mode_info.crtcs[pipe]) {
 		/* Repeat readout if needed to provide stable result if
 		 * we cross start of vsync during the queries.
 		 */
 		do {
-			count = radeon_get_vblank_counter(rdev, crtc);
+			count = radeon_get_vblank_counter(rdev, pipe);
 			/* Ask radeon_get_crtc_scanoutpos to return vpos as
 			 * distance to start of vblank, instead of regular
 			 * vertical scanout pos.
 			 */
 			stat = radeon_get_crtc_scanoutpos(
-				dev, crtc, GET_DISTANCE_TO_VBLANKSTART,
+				dev, pipe, GET_DISTANCE_TO_VBLANKSTART,
 				&vpos, &hpos, NULL, NULL,
-				&rdev->mode_info.crtcs[crtc]->base.hwmode);
-		} while (count != radeon_get_vblank_counter(rdev, crtc));
+				&rdev->mode_info.crtcs[pipe]->base.hwmode);
+		} while (count != radeon_get_vblank_counter(rdev, pipe));
 
 		if (((stat & (DRM_SCANOUTPOS_VALID | DRM_SCANOUTPOS_ACCURATE)) !=
 		    (DRM_SCANOUTPOS_VALID | DRM_SCANOUTPOS_ACCURATE))) {
 			DRM_DEBUG_VBL("Query failed! stat %d\n", stat);
 		}
 		else {
-			DRM_DEBUG_VBL("crtc %d: dist from vblank start %d\n",
-				      crtc, vpos);
+			DRM_DEBUG_VBL("crtc %u: dist from vblank start %d\n",
+				      pipe, vpos);
 
 			/* Bump counter if we are at >= leading edge of vblank,
 			 * but before vsync where vpos would turn negative and
@@ -806,7 +806,7 @@ u32 radeon_get_vblank_counter_kms(struct
 	}
 	else {
 	    /* Fallback to use value as is. */
-	    count = radeon_get_vblank_counter(rdev, crtc);
+	    count = radeon_get_vblank_counter(rdev, pipe);
 	    DRM_DEBUG_VBL("NULL mode info! Returned count may be wrong.\n");
 	}
 
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/radeon/radeon_mode.h
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/radeon/radeon_mode.h
@@ -757,8 +757,10 @@ extern u8 radeon_dp_getsinktype(struct r
 extern bool radeon_dp_getdpcd(struct radeon_connector *radeon_connector);
 extern int radeon_dp_get_panel_mode(struct drm_encoder *encoder,
 				    struct drm_connector *connector);
-int radeon_dp_get_max_link_rate(struct drm_connector *connector,
-				const u8 *dpcd);
+extern int radeon_dp_get_dp_link_config(struct drm_connector *connector,
+					const u8 *dpcd,
+					unsigned pix_clock,
+					unsigned *dp_lanes, unsigned *dp_rate);
 extern void radeon_dp_set_rx_power_state(struct drm_connector *connector,
 					 u8 power_state);
 extern void radeon_dp_aux_init(struct radeon_connector *radeon_connector);
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/radeon/radeon_object.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/radeon/radeon_object.c
@@ -33,6 +33,7 @@
 #include <linux/slab.h>
 #include <drm/drmP.h>
 #include <drm/radeon_drm.h>
+#include <drm/drm_cache.h>
 #include "radeon.h"
 #include "radeon_trace.h"
 
@@ -245,6 +246,12 @@ int radeon_bo_create(struct radeon_devic
 		DRM_INFO_ONCE("Please enable CONFIG_MTRR and CONFIG_X86_PAT for "
 			      "better performance thanks to write-combining\n");
 	bo->flags &= ~(RADEON_GEM_GTT_WC | RADEON_GEM_GTT_UC);
+#else
+	/* For architectures that don't support WC memory,
+	 * mask out the WC flag from the BO
+	 */
+	if (!drm_arch_can_wc_memory())
+		bo->flags &= ~RADEON_GEM_GTT_WC;
 #endif
 
 	radeon_ttm_placement_from_domain(bo, domain);
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/radeon/radeon_pm.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/radeon/radeon_pm.c
@@ -713,7 +713,7 @@ static struct attribute *hwmon_attribute
 static umode_t hwmon_attributes_visible(struct kobject *kobj,
 					struct attribute *attr, int index)
 {
-	struct device *dev = container_of(kobj, struct device, kobj);
+	struct device *dev = kobj_to_dev(kobj);
 	struct radeon_device *rdev = dev_get_drvdata(dev);
 	umode_t effective_mode = attr->mode;
 
@@ -1078,10 +1078,6 @@ force:
 	/* update displays */
 	radeon_dpm_display_configuration_changed(rdev);
 
-	rdev->pm.dpm.current_active_crtcs = rdev->pm.dpm.new_active_crtcs;
-	rdev->pm.dpm.current_active_crtc_count = rdev->pm.dpm.new_active_crtc_count;
-	rdev->pm.dpm.single_display = single_display;
-
 	/* wait for the rings to drain */
 	for (i = 0; i < RADEON_NUM_RINGS; i++) {
 		struct radeon_ring *ring = &rdev->ring[i];
@@ -1097,6 +1093,10 @@ force:
 
 	radeon_dpm_post_set_power_state(rdev);
 
+	rdev->pm.dpm.current_active_crtcs = rdev->pm.dpm.new_active_crtcs;
+	rdev->pm.dpm.current_active_crtc_count = rdev->pm.dpm.new_active_crtc_count;
+	rdev->pm.dpm.single_display = single_display;
+
 	if (rdev->asic->dpm.force_performance_level) {
 		if (rdev->pm.dpm.thermal_active) {
 			enum radeon_dpm_forced_level level = rdev->pm.dpm.forced_level;
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/radeon/radeon_sa.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/radeon/radeon_sa.c
@@ -349,8 +349,13 @@ int radeon_sa_bo_new(struct radeon_devic
 			/* see if we can skip over some allocations */
 		} while (radeon_sa_bo_next_hole(sa_manager, fences, tries));
 
+		for (i = 0; i < RADEON_NUM_RINGS; ++i)
+			radeon_fence_ref(fences[i]);
+
 		spin_unlock(&sa_manager->wq.lock);
 		r = radeon_fence_wait_any(rdev, fences, false);
+		for (i = 0; i < RADEON_NUM_RINGS; ++i)
+			radeon_fence_unref(&fences[i]);
 		spin_lock(&sa_manager->wq.lock);
 		/* if we have nothing to wait for block */
 		if (r == -ENOENT) {
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/radeon/radeon_ttm.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/radeon/radeon_ttm.c
@@ -235,6 +235,8 @@ static int radeon_verify_access(struct t
 {
 	struct radeon_bo *rbo = container_of(bo, struct radeon_bo, tbo);
 
+	if (radeon_ttm_tt_has_userptr(bo->ttm))
+		return -EPERM;
 	return drm_vma_node_verify_access(&rbo->gem_base.vma_node, filp);
 }
 
@@ -261,8 +263,8 @@ static int radeon_move_blit(struct ttm_b
 
 	rdev = radeon_get_rdev(bo->bdev);
 	ridx = radeon_copy_ring_index(rdev);
-	old_start = old_mem->start << PAGE_SHIFT;
-	new_start = new_mem->start << PAGE_SHIFT;
+	old_start = (u64)old_mem->start << PAGE_SHIFT;
+	new_start = (u64)new_mem->start << PAGE_SHIFT;
 
 	switch (old_mem->mem_type) {
 	case TTM_PL_VRAM:
@@ -758,7 +760,7 @@ static int radeon_ttm_tt_populate(struct
 						       0, PAGE_SIZE,
 						       PCI_DMA_BIDIRECTIONAL);
 		if (pci_dma_mapping_error(rdev->pdev, gtt->ttm.dma_address[i])) {
-			while (--i) {
+			while (i--) {
 				pci_unmap_page(rdev->pdev, gtt->ttm.dma_address[i],
 					       PAGE_SIZE, PCI_DMA_BIDIRECTIONAL);
 				gtt->ttm.dma_address[i] = 0;
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/radeon/radeon_vm.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/radeon/radeon_vm.c
@@ -455,15 +455,15 @@ int radeon_vm_bo_set_addr(struct radeon_
 
 	if (soffset) {
 		/* make sure object fit at this offset */
-		eoffset = soffset + size;
+		eoffset = soffset + size - 1;
 		if (soffset >= eoffset) {
 			r = -EINVAL;
 			goto error_unreserve;
 		}
 
 		last_pfn = eoffset / RADEON_GPU_PAGE_SIZE;
-		if (last_pfn > rdev->vm_manager.max_pfn) {
-			dev_err(rdev->dev, "va above limit (0x%08X > 0x%08X)\n",
+		if (last_pfn >= rdev->vm_manager.max_pfn) {
+			dev_err(rdev->dev, "va above limit (0x%08X >= 0x%08X)\n",
 				last_pfn, rdev->vm_manager.max_pfn);
 			r = -EINVAL;
 			goto error_unreserve;
@@ -478,7 +478,7 @@ int radeon_vm_bo_set_addr(struct radeon_
 	eoffset /= RADEON_GPU_PAGE_SIZE;
 	if (soffset || eoffset) {
 		struct interval_tree_node *it;
-		it = interval_tree_iter_first(&vm->va, soffset, eoffset - 1);
+		it = interval_tree_iter_first(&vm->va, soffset, eoffset);
 		if (it && it != &bo_va->it) {
 			struct radeon_bo_va *tmp;
 			tmp = container_of(it, struct radeon_bo_va, it);
@@ -518,7 +518,7 @@ int radeon_vm_bo_set_addr(struct radeon_
 	if (soffset || eoffset) {
 		spin_lock(&vm->status_lock);
 		bo_va->it.start = soffset;
-		bo_va->it.last = eoffset - 1;
+		bo_va->it.last = eoffset;
 		list_add(&bo_va->vm_status, &vm->cleared);
 		spin_unlock(&vm->status_lock);
 		interval_tree_insert(&bo_va->it, &vm->va);
@@ -888,7 +888,7 @@ static void radeon_vm_fence_pts(struct r
 	unsigned i;
 
 	start >>= radeon_vm_block_size;
-	end >>= radeon_vm_block_size;
+	end = (end - 1) >> radeon_vm_block_size;
 
 	for (i = start; i <= end; ++i)
 		radeon_bo_fence(vm->page_tables[i].bo, fence, true);
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/radeon/si_dpm.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/radeon/si_dpm.c
@@ -2926,9 +2926,12 @@ static struct si_dpm_quirk si_dpm_quirk_
 	/* PITCAIRN - https://bugs.freedesktop.org/show_bug.cgi?id=76490 */
 	{ PCI_VENDOR_ID_ATI, 0x6810, 0x1462, 0x3036, 0, 120000 },
 	{ PCI_VENDOR_ID_ATI, 0x6811, 0x174b, 0xe271, 0, 120000 },
+	{ PCI_VENDOR_ID_ATI, 0x6811, 0x174b, 0x2015, 0, 120000 },
 	{ PCI_VENDOR_ID_ATI, 0x6810, 0x174b, 0xe271, 85000, 90000 },
 	{ PCI_VENDOR_ID_ATI, 0x6811, 0x1462, 0x2015, 0, 120000 },
 	{ PCI_VENDOR_ID_ATI, 0x6811, 0x1043, 0x2015, 0, 120000 },
+	{ PCI_VENDOR_ID_ATI, 0x6811, 0x148c, 0x2015, 0, 120000 },
+	{ PCI_VENDOR_ID_ATI, 0x6810, 0x1682, 0x9275, 0, 120000 },
 	{ 0, 0, 0, 0 },
 };
 
@@ -3008,6 +3011,16 @@ static void si_apply_state_adjust_rules(
 		}
 		++p;
 	}
+	/* limit mclk on all R7 370 parts for stability */
+	if (rdev->pdev->device == 0x6811 &&
+	    rdev->pdev->revision == 0x81)
+		max_mclk = 120000;
+	/* limit sclk/mclk on Jet parts for stability */
+	if (rdev->pdev->device == 0x6665 &&
+	    rdev->pdev->revision == 0xc3) {
+		max_sclk = 75000;
+		max_mclk = 80000;
+	}
 
 	if (rps->vce_active) {
 		rps->evclk = rdev->pm.dpm.vce_states[rdev->pm.dpm.vce_level].evclk;
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/radeon/sid.h
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/radeon/sid.h
@@ -915,6 +915,11 @@
 #define DCCG_AUDIO_DTO1_PHASE                           0x05c0
 #define DCCG_AUDIO_DTO1_MODULE                          0x05c4
 
+#define DENTIST_DISPCLK_CNTL				0x0490
+#	define DENTIST_DPREFCLK_WDIVIDER(x)		(((x) & 0x7f) << 24)
+#	define DENTIST_DPREFCLK_WDIVIDER_MASK		(0x7f << 24)
+#	define DENTIST_DPREFCLK_WDIVIDER_SHIFT		24
+
 #define AFMT_AUDIO_SRC_CONTROL                          0x713c
 #define		AFMT_AUDIO_SRC_SELECT(x)		(((x) & 7) << 0)
 /* AFMT_AUDIO_SRC_SELECT
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/radeon/vce_v1_0.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/radeon/vce_v1_0.c
@@ -178,12 +178,12 @@ int vce_v1_0_load_fw(struct radeon_devic
 		return -EINVAL;
 	}
 
-	for (i = 0; i < sign->num; ++i) {
-		if (sign->val[i].chip_id == chip_id)
+	for (i = 0; i < le32_to_cpu(sign->num); ++i) {
+		if (le32_to_cpu(sign->val[i].chip_id) == chip_id)
 			break;
 	}
 
-	if (i == sign->num)
+	if (i == le32_to_cpu(sign->num))
 		return -EINVAL;
 
 	data += (256 - 64) / 4;
@@ -191,18 +191,18 @@ int vce_v1_0_load_fw(struct radeon_devic
 	data[1] = sign->val[i].nonce[1];
 	data[2] = sign->val[i].nonce[2];
 	data[3] = sign->val[i].nonce[3];
-	data[4] = sign->len + 64;
+	data[4] = cpu_to_le32(le32_to_cpu(sign->len) + 64);
 
 	memset(&data[5], 0, 44);
 	memcpy(&data[16], &sign[1], rdev->vce_fw->size - sizeof(*sign));
 
-	data += data[4] / 4;
+	data += le32_to_cpu(data[4]) / 4;
 	data[0] = sign->val[i].sigval[0];
 	data[1] = sign->val[i].sigval[1];
 	data[2] = sign->val[i].sigval[2];
 	data[3] = sign->val[i].sigval[3];
 
-	rdev->vce.keyselect = sign->val[i].keyselect;
+	rdev->vce.keyselect = le32_to_cpu(sign->val[i].keyselect);
 
 	return 0;
 }
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/sti/sti_drv.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/sti/sti_drv.c
@@ -160,6 +160,7 @@ static int sti_load(struct drm_device *d
 
 	drm_mode_config_reset(dev);
 
+	drm_helper_disable_unused_functions(dev);
 	drm_fbdev_cma_init(dev, 32,
 			   dev->mode_config.num_crtc,
 			   dev->mode_config.num_connector);
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/tilcdc/tilcdc_drv.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/tilcdc/tilcdc_drv.c
@@ -294,6 +294,7 @@ static int tilcdc_load(struct drm_device
 			break;
 	}
 
+	drm_helper_disable_unused_functions(dev);
 	priv->fbdev = drm_fbdev_cma_init(dev, bpp,
 			dev->mode_config.num_crtc,
 			dev->mode_config.num_connector);
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/ttm/ttm_bo.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/ttm/ttm_bo.c
@@ -176,7 +176,7 @@ void ttm_bo_add_to_lru(struct ttm_buffer
 		list_add_tail(&bo->lru, &man->lru);
 		kref_get(&bo->list_kref);
 
-		if (bo->ttm != NULL) {
+		if (bo->ttm && !(bo->ttm->page_flags & TTM_PAGE_FLAG_SG)) {
 			list_add_tail(&bo->swap, &bo->glob->swap_lru);
 			kref_get(&bo->list_kref);
 		}
@@ -228,6 +228,18 @@ void ttm_bo_del_sub_from_lru(struct ttm_
 }
 EXPORT_SYMBOL(ttm_bo_del_sub_from_lru);
 
+void ttm_bo_move_to_lru_tail(struct ttm_buffer_object *bo)
+{
+	int put_count = 0;
+
+	lockdep_assert_held(&bo->resv->lock.base);
+
+	put_count = ttm_bo_del_from_lru(bo);
+	ttm_bo_list_ref_sub(bo, put_count, true);
+	ttm_bo_add_to_lru(bo);
+}
+EXPORT_SYMBOL(ttm_bo_move_to_lru_tail);
+
 /*
  * Call bo->mutex locked.
  */
@@ -1004,9 +1016,9 @@ out_unlock:
 	return ret;
 }
 
-static bool ttm_bo_mem_compat(struct ttm_placement *placement,
-			      struct ttm_mem_reg *mem,
-			      uint32_t *new_flags)
+bool ttm_bo_mem_compat(struct ttm_placement *placement,
+		       struct ttm_mem_reg *mem,
+		       uint32_t *new_flags)
 {
 	int i;
 
@@ -1038,6 +1050,7 @@ static bool ttm_bo_mem_compat(struct ttm
 
 	return false;
 }
+EXPORT_SYMBOL(ttm_bo_mem_compat);
 
 int ttm_bo_validate(struct ttm_buffer_object *bo,
 			struct ttm_placement *placement,
@@ -1170,9 +1183,15 @@ int ttm_bo_init(struct ttm_bo_device *bd
 	if (likely(!ret))
 		ret = ttm_bo_validate(bo, placement, interruptible, false);
 
-	if (!resv)
+	if (!resv) {
 		ttm_bo_unreserve(bo);
 
+	} else if (!(bo->mem.placement & TTM_PL_FLAG_NO_EVICT)) {
+		spin_lock(&bo->glob->lru_lock);
+		ttm_bo_add_to_lru(bo);
+		spin_unlock(&bo->glob->lru_lock);
+	}
+
 	if (unlikely(ret))
 		ttm_bo_unref(&bo);
 
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/udl/udl_fb.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/udl/udl_fb.c
@@ -539,7 +539,7 @@ static int udlfb_create(struct drm_fb_he
 out_destroy_fbi:
 	drm_fb_helper_release_fbi(helper);
 out_gfree:
-	drm_gem_object_unreference(&ufbdev->ufb.obj->base);
+	drm_gem_object_unreference_unlocked(&ufbdev->ufb.obj->base);
 out:
 	return ret;
 }
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/udl/udl_gem.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/udl/udl_gem.c
@@ -52,7 +52,7 @@ udl_gem_create(struct drm_file *file,
 		return ret;
 	}
 
-	drm_gem_object_unreference(&obj->base);
+	drm_gem_object_unreference_unlocked(&obj->base);
 	*handle_p = handle;
 	return 0;
 }
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/vc4/vc4_crtc.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/vc4/vc4_crtc.c
@@ -327,7 +327,7 @@ static int vc4_crtc_atomic_check(struct
 	/* The pixelvalve can only feed one encoder (and encoders are
 	 * 1:1 with connectors.)
 	 */
-	if (drm_atomic_connectors_for_crtc(state->state, crtc) > 1)
+	if (hweight32(state->connector_mask) > 1)
 		return -EINVAL;
 
 	drm_atomic_crtc_state_for_each_plane(plane, state) {
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf.c
@@ -247,7 +247,7 @@ static void __vmw_cmdbuf_header_free(str
 {
 	struct vmw_cmdbuf_man *man = header->man;
 
-	BUG_ON(!spin_is_locked(&man->lock));
+	lockdep_assert_held_once(&man->lock);
 
 	if (header->inline_space) {
 		vmw_cmdbuf_header_inline_free(header);
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/vmwgfx/vmwgfx_dmabuf.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/vmwgfx/vmwgfx_dmabuf.c
@@ -49,6 +49,7 @@ int vmw_dmabuf_pin_in_placement(struct v
 {
 	struct ttm_buffer_object *bo = &buf->base;
 	int ret;
+	uint32_t new_flags;
 
 	ret = ttm_write_lock(&dev_priv->reservation_sem, interruptible);
 	if (unlikely(ret != 0))
@@ -60,7 +61,12 @@ int vmw_dmabuf_pin_in_placement(struct v
 	if (unlikely(ret != 0))
 		goto err;
 
-	ret = ttm_bo_validate(bo, placement, interruptible, false);
+	if (buf->pin_count > 0)
+		ret = ttm_bo_mem_compat(placement, &bo->mem,
+					&new_flags) == true ? 0 : -EINVAL;
+	else
+		ret = ttm_bo_validate(bo, placement, interruptible, false);
+
 	if (!ret)
 		vmw_bo_pin_reserved(buf, true);
 
@@ -91,6 +97,7 @@ int vmw_dmabuf_pin_in_vram_or_gmr(struct
 {
 	struct ttm_buffer_object *bo = &buf->base;
 	int ret;
+	uint32_t new_flags;
 
 	ret = ttm_write_lock(&dev_priv->reservation_sem, interruptible);
 	if (unlikely(ret != 0))
@@ -102,6 +109,12 @@ int vmw_dmabuf_pin_in_vram_or_gmr(struct
 	if (unlikely(ret != 0))
 		goto err;
 
+	if (buf->pin_count > 0) {
+		ret = ttm_bo_mem_compat(&vmw_vram_gmr_placement, &bo->mem,
+					&new_flags) == true ? 0 : -EINVAL;
+		goto out_unreserve;
+	}
+
 	ret = ttm_bo_validate(bo, &vmw_vram_gmr_placement, interruptible,
 			      false);
 	if (likely(ret == 0) || ret == -ERESTARTSYS)
@@ -161,6 +174,7 @@ int vmw_dmabuf_pin_in_start_of_vram(stru
 	struct ttm_placement placement;
 	struct ttm_place place;
 	int ret = 0;
+	uint32_t new_flags;
 
 	place = vmw_vram_placement.placement[0];
 	place.lpfn = bo->num_pages;
@@ -185,10 +199,15 @@ int vmw_dmabuf_pin_in_start_of_vram(stru
 	 */
 	if (bo->mem.mem_type == TTM_PL_VRAM &&
 	    bo->mem.start < bo->num_pages &&
-	    bo->mem.start > 0)
+	    bo->mem.start > 0 &&
+	    buf->pin_count == 0)
 		(void) ttm_bo_validate(bo, &vmw_sys_placement, false, false);
 
-	ret = ttm_bo_validate(bo, &placement, interruptible, false);
+	if (buf->pin_count > 0)
+		ret = ttm_bo_mem_compat(&placement, &bo->mem,
+					&new_flags) == true ? 0 : -EINVAL;
+	else
+		ret = ttm_bo_validate(bo, &placement, interruptible, false);
 
 	/* For some reason we didn't end up at the start of vram */
 	WARN_ON(ret == 0 && bo->offset != 0);
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
@@ -25,6 +25,7 @@
  *
  **************************************************************************/
 #include <linux/module.h>
+#include <linux/console.h>
 
 #include <drm/drmP.h>
 #include "vmwgfx_drv.h"
@@ -226,6 +227,7 @@ static int vmw_force_iommu;
 static int vmw_restrict_iommu;
 static int vmw_force_coherent;
 static int vmw_restrict_dma_mask;
+static int vmw_assume_16bpp;
 
 static int vmw_probe(struct pci_dev *, const struct pci_device_id *);
 static void vmw_master_init(struct vmw_master *);
@@ -242,6 +244,8 @@ MODULE_PARM_DESC(force_coherent, "Force
 module_param_named(force_coherent, vmw_force_coherent, int, 0600);
 MODULE_PARM_DESC(restrict_dma_mask, "Restrict DMA mask to 44 bits with IOMMU");
 module_param_named(restrict_dma_mask, vmw_restrict_dma_mask, int, 0600);
+MODULE_PARM_DESC(assume_16bpp, "Assume 16-bpp when filtering modes");
+module_param_named(assume_16bpp, vmw_assume_16bpp, int, 0600);
 
 
 static void vmw_print_capabilities(uint32_t capabilities)
@@ -651,6 +655,8 @@ static int vmw_driver_load(struct drm_de
 	dev_priv->vram_start = pci_resource_start(dev->pdev, 1);
 	dev_priv->mmio_start = pci_resource_start(dev->pdev, 2);
 
+	dev_priv->assume_16bpp = !!vmw_assume_16bpp;
+
 	dev_priv->enable_fb = enable_fbdev;
 
 	vmw_write(dev_priv, SVGA_REG_ID, SVGA_ID_2);
@@ -697,6 +703,13 @@ static int vmw_driver_load(struct drm_de
 			vmw_read(dev_priv,
 				 SVGA_REG_SUGGESTED_GBOBJECT_MEM_SIZE_KB);
 
+		/*
+		 * Workaround for low memory 2D VMs to compensate for the
+		 * allocation taken by fbdev
+		 */
+		if (!(dev_priv->capabilities & SVGA_CAP_3D))
+			mem_size *= 2;
+
 		dev_priv->max_mob_pages = mem_size * 1024 / PAGE_SIZE;
 		dev_priv->prim_bb_mem =
 			vmw_read(dev_priv,
@@ -1538,6 +1551,12 @@ static int vmw_probe(struct pci_dev *pde
 static int __init vmwgfx_init(void)
 {
 	int ret;
+
+#ifdef CONFIG_VGA_CONSOLE
+	if (vgacon_text_force())
+		return -EINVAL;
+#endif
+
 	ret = drm_pci_init(&driver, &vmw_pci_driver);
 	if (ret)
 		DRM_ERROR("Failed initializing DRM.\n");
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
@@ -387,6 +387,7 @@ struct vmw_private {
 	spinlock_t hw_lock;
 	spinlock_t cap_lock;
 	bool has_dx;
+	bool assume_16bpp;
 
 	/*
 	 * VGA registers.
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c
@@ -3273,19 +3273,19 @@ static const struct vmw_cmd_entry vmw_cm
 		    &vmw_cmd_dx_cid_check, true, false, true),
 	VMW_CMD_DEF(SVGA_3D_CMD_DX_DEFINE_QUERY, &vmw_cmd_dx_define_query,
 		    true, false, true),
-	VMW_CMD_DEF(SVGA_3D_CMD_DX_DESTROY_QUERY, &vmw_cmd_ok,
+	VMW_CMD_DEF(SVGA_3D_CMD_DX_DESTROY_QUERY, &vmw_cmd_dx_cid_check,
 		    true, false, true),
 	VMW_CMD_DEF(SVGA_3D_CMD_DX_BIND_QUERY, &vmw_cmd_dx_bind_query,
 		    true, false, true),
 	VMW_CMD_DEF(SVGA_3D_CMD_DX_SET_QUERY_OFFSET,
-		    &vmw_cmd_ok, true, false, true),
-	VMW_CMD_DEF(SVGA_3D_CMD_DX_BEGIN_QUERY, &vmw_cmd_ok,
+		    &vmw_cmd_dx_cid_check, true, false, true),
+	VMW_CMD_DEF(SVGA_3D_CMD_DX_BEGIN_QUERY, &vmw_cmd_dx_cid_check,
 		    true, false, true),
-	VMW_CMD_DEF(SVGA_3D_CMD_DX_END_QUERY, &vmw_cmd_ok,
+	VMW_CMD_DEF(SVGA_3D_CMD_DX_END_QUERY, &vmw_cmd_dx_cid_check,
 		    true, false, true),
 	VMW_CMD_DEF(SVGA_3D_CMD_DX_READBACK_QUERY, &vmw_cmd_invalid,
 		    true, false, true),
-	VMW_CMD_DEF(SVGA_3D_CMD_DX_SET_PREDICATION, &vmw_cmd_invalid,
+	VMW_CMD_DEF(SVGA_3D_CMD_DX_SET_PREDICATION, &vmw_cmd_dx_cid_check,
 		    true, false, true),
 	VMW_CMD_DEF(SVGA_3D_CMD_DX_SET_VIEWPORTS, &vmw_cmd_dx_cid_check,
 		    true, false, true),
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c
@@ -517,28 +517,6 @@ static int vmw_fb_kms_framebuffer(struct
 
 	par->set_fb = &vfb->base;
 
-	if (!par->bo_ptr) {
-		/*
-		 * Pin before mapping. Since we don't know in what placement
-		 * to pin, call into KMS to do it for us.
-		 */
-		ret = vfb->pin(vfb);
-		if (ret) {
-			DRM_ERROR("Could not pin the fbdev framebuffer.\n");
-			return ret;
-		}
-
-		ret = ttm_bo_kmap(&par->vmw_bo->base, 0,
-				  par->vmw_bo->base.num_pages, &par->map);
-		if (ret) {
-			vfb->unpin(vfb);
-			DRM_ERROR("Could not map the fbdev framebuffer.\n");
-			return ret;
-		}
-
-		par->bo_ptr = ttm_kmap_obj_virtual(&par->map, &par->bo_iowrite);
-	}
-
 	return 0;
 }
 
@@ -573,9 +551,9 @@ static int vmw_fb_set_par(struct fb_info
 		mode = old_mode;
 		old_mode = NULL;
 	} else if (!vmw_kms_validate_mode_vram(vmw_priv,
-					       mode->hdisplay *
-					       (var->bits_per_pixel + 7) / 8,
-					       mode->vdisplay)) {
+					mode->hdisplay *
+					DIV_ROUND_UP(var->bits_per_pixel, 8),
+					mode->vdisplay)) {
 		drm_mode_destroy(vmw_priv->dev, mode);
 		return -EINVAL;
 	}
@@ -601,6 +579,31 @@ static int vmw_fb_set_par(struct fb_info
 	if (ret)
 		goto out_unlock;
 
+	if (!par->bo_ptr) {
+		struct vmw_framebuffer *vfb = vmw_framebuffer_to_vfb(set.fb);
+
+		/*
+		 * Pin before mapping. Since we don't know in what placement
+		 * to pin, call into KMS to do it for us.
+		 */
+		ret = vfb->pin(vfb);
+		if (ret) {
+			DRM_ERROR("Could not pin the fbdev framebuffer.\n");
+			goto out_unlock;
+		}
+
+		ret = ttm_bo_kmap(&par->vmw_bo->base, 0,
+				  par->vmw_bo->base.num_pages, &par->map);
+		if (ret) {
+			vfb->unpin(vfb);
+			DRM_ERROR("Could not map the fbdev framebuffer.\n");
+			goto out_unlock;
+		}
+
+		par->bo_ptr = ttm_kmap_obj_virtual(&par->map, &par->bo_iowrite);
+	}
+
+
 	vmw_fb_dirty_mark(par, par->fb_x, par->fb_y,
 			  par->set_fb->width, par->set_fb->height);
 
--- zfcpdump-kernel-4.4.orig/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
+++ zfcpdump-kernel-4.4/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
@@ -763,21 +763,25 @@ static int vmw_create_dmabuf_proxy(struc
 	uint32_t format;
 	struct drm_vmw_size content_base_size;
 	struct vmw_resource *res;
+	unsigned int bytes_pp;
 	int ret;
 
 	switch (mode_cmd->depth) {
 	case 32:
 	case 24:
 		format = SVGA3D_X8R8G8B8;
+		bytes_pp = 4;
 		break;
 
 	case 16:
 	case 15:
 		format = SVGA3D_R5G6B5;
+		bytes_pp = 2;
 		break;
 
 	case 8:
 		format = SVGA3D_P8;
+		bytes_pp = 1;
 		break;
 
 	default:
@@ -785,7 +789,7 @@ static int vmw_create_dmabuf_proxy(struc
 		return -EINVAL;
 	}
 
-	content_base_size.width  = mode_cmd->width;
+	content_base_size.width  = mode_cmd->pitch / bytes_pp;
 	content_base_size.height = mode_cmd->height;
 	content_base_size.depth  = 1;
 
@@ -1534,14 +1538,10 @@ int vmw_du_connector_fill_modes(struct d
 		DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC)
 	};
 	int i;
-	u32 assumed_bpp = 2;
+	u32 assumed_bpp = 4;
 
-	/*
-	 * If using screen objects, then assume 32-bpp because that's what the
-	 * SVGA device is assuming
-	 */
-	if (dev_priv->active_display_unit == vmw_du_screen_object)
-		assumed_bpp = 4;
+	if (dev_priv->assume_16bpp)
+		assumed_bpp = 2;
 
 	if (dev_priv->active_display_unit == vmw_du_screen_target) {
 		max_width  = min(max_width,  dev_priv->stdu_max_width);
--- zfcpdump-kernel-4.4.orig/drivers/gpu/ipu-v3/ipu-common.c
+++ zfcpdump-kernel-4.4/drivers/gpu/ipu-v3/ipu-common.c
@@ -997,7 +997,7 @@ struct ipu_platform_reg {
 };
 
 /* These must be in the order of the corresponding device tree port nodes */
-static const struct ipu_platform_reg client_reg[] = {
+static struct ipu_platform_reg client_reg[] = {
 	{
 		.pdata = {
 			.csi = 0,
@@ -1048,8 +1048,19 @@ static int ipu_add_client_devices(struct
 	mutex_unlock(&ipu_client_id_mutex);
 
 	for (i = 0; i < ARRAY_SIZE(client_reg); i++) {
-		const struct ipu_platform_reg *reg = &client_reg[i];
+		struct ipu_platform_reg *reg = &client_reg[i];
 		struct platform_device *pdev;
+		struct device_node *of_node;
+
+		/* Associate subdevice with the corresponding port node */
+		of_node = of_graph_get_port_by_id(dev->of_node, i);
+		if (!of_node) {
+			dev_info(dev,
+				 "no port@%d node in %s, not using %s%d\n",
+				 i, dev->of_node->full_name,
+				 (i / 2) ? "DI" : "CSI", i % 2);
+			continue;
+		}
 
 		pdev = platform_device_alloc(reg->name, id++);
 		if (!pdev) {
@@ -1059,15 +1070,7 @@ static int ipu_add_client_devices(struct
 
 		pdev->dev.parent = dev;
 
-		/* Associate subdevice with the corresponding port node */
-		pdev->dev.of_node = of_graph_get_port_by_id(dev->of_node, i);
-		if (!pdev->dev.of_node) {
-			dev_err(dev, "missing port@%d node in %s\n", i,
-				dev->of_node->full_name);
-			ret = -ENODEV;
-			goto err_register;
-		}
-
+		reg->pdata.of_node = of_node;
 		ret = platform_device_add_data(pdev, &reg->pdata,
 					       sizeof(reg->pdata));
 		if (!ret)
@@ -1076,6 +1079,12 @@ static int ipu_add_client_devices(struct
 			platform_device_put(pdev);
 			goto err_register;
 		}
+
+		/*
+		 * Set of_node only after calling platform_device_add. Otherwise
+		 * the platform:imx-ipuv3-crtc modalias won't be used.
+		 */
+		pdev->dev.of_node = of_node;
 	}
 
 	return 0;
--- zfcpdump-kernel-4.4.orig/drivers/hid/Kconfig
+++ zfcpdump-kernel-4.4/drivers/hid/Kconfig
@@ -920,6 +920,14 @@ config HID_SENSOR_CUSTOM_SENSOR
 	  standard sensors.
 	  Select this config option for custom/generic sensor support.
 
+config HID_ALPS
+	tristate "Alps HID device support"
+	depends on HID
+	---help---
+	Support for Alps I2C HID touchpads and StickPointer.
+	Say Y here if you have a Alps touchpads over i2c-hid or usbhid
+	and want support for its special functionalities.
+
 endmenu
 
 endif # HID
--- zfcpdump-kernel-4.4.orig/drivers/hid/Makefile
+++ zfcpdump-kernel-4.4/drivers/hid/Makefile
@@ -21,6 +21,7 @@ hid-wiimote-y		:= hid-wiimote-core.o hid
 hid-wiimote-$(CONFIG_DEBUG_FS)	+= hid-wiimote-debug.o
 
 obj-$(CONFIG_HID_A4TECH)	+= hid-a4tech.o
+obj-$(CONFIG_HID_ALPS)		+= hid-alps.o
 obj-$(CONFIG_HID_ACRUX)		+= hid-axff.o
 obj-$(CONFIG_HID_APPLE)		+= hid-apple.o
 obj-$(CONFIG_HID_APPLEIR)	+= hid-appleir.o
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/hid/hid-alps.c
@@ -0,0 +1,506 @@
+/*
+ *  Copyright (c) 2016 Masaki Ota <masaki.ota@jp.alps.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/hid.h>
+#include <linux/input.h>
+#include <linux/input/mt.h>
+#include <linux/module.h>
+#include <asm/unaligned.h>
+#include "hid-ids.h"
+
+/* ALPS Device Product ID */
+#define HID_PRODUCT_ID_T3_BTNLESS	0xD0C0
+#define HID_PRODUCT_ID_COSMO		0x1202
+#define HID_PRODUCT_ID_U1_PTP_1		0x1207
+#define HID_PRODUCT_ID_U1			0x1209
+#define HID_PRODUCT_ID_U1_PTP_2		0x120A
+#define HID_PRODUCT_ID_U1_DUAL		0x120B
+#define HID_PRODUCT_ID_T4_BTNLESS	0x120C
+
+#define DEV_SINGLEPOINT				0x01
+#define DEV_DUALPOINT				0x02
+
+#define U1_MOUSE_REPORT_ID			0x01 /* Mouse data ReportID */
+#define U1_ABSOLUTE_REPORT_ID		0x03 /* Absolute data ReportID */
+#define U1_FEATURE_REPORT_ID		0x05 /* Feature ReportID */
+#define U1_SP_ABSOLUTE_REPORT_ID	0x06 /* Feature ReportID */
+
+#define U1_FEATURE_REPORT_LEN		0x08 /* Feature Report Length */
+#define U1_FEATURE_REPORT_LEN_ALL	0x0A
+#define U1_CMD_REGISTER_READ		0xD1
+#define U1_CMD_REGISTER_WRITE		0xD2
+
+#define	U1_DEVTYPE_SP_SUPPORT		0x10 /* SP Support */
+#define	U1_DISABLE_DEV				0x01
+#define U1_TP_ABS_MODE				0x02
+#define	U1_SP_ABS_MODE				0x80
+
+#define ADDRESS_U1_DEV_CTRL_1	0x00800040
+#define ADDRESS_U1_DEVICE_TYP	0x00800043
+#define ADDRESS_U1_NUM_SENS_X	0x00800047
+#define ADDRESS_U1_NUM_SENS_Y	0x00800048
+#define ADDRESS_U1_PITCH_SENS_X	0x00800049
+#define ADDRESS_U1_PITCH_SENS_Y	0x0080004A
+#define ADDRESS_U1_RESO_DWN_ABS 0x0080004E
+#define ADDRESS_U1_PAD_BTN		0x00800052
+#define ADDRESS_U1_SP_BTN		0x0080009F
+
+#define MAX_TOUCHES	5
+
+/**
+ * struct u1_data
+ *
+ * @input: pointer to the kernel input device
+ * @input2: pointer to the kernel input2 device
+ * @hdev: pointer to the struct hid_device
+ *
+ * @dev_ctrl: device control parameter
+ * @dev_type: device type
+ * @sen_line_num_x: number of sensor line of X
+ * @sen_line_num_y: number of sensor line of Y
+ * @pitch_x: sensor pitch of X
+ * @pitch_y: sensor pitch of Y
+ * @resolution: resolution
+ * @btn_info: button information
+ * @x_active_len_mm: active area length of X (mm)
+ * @y_active_len_mm: active area length of Y (mm)
+ * @x_max: maximum x coordinate value
+ * @y_max: maximum y coordinate value
+ * @btn_cnt: number of buttons
+ * @sp_btn_cnt: number of stick buttons
+ */
+struct u1_dev {
+	struct input_dev *input;
+	struct input_dev *input2;
+	struct hid_device *hdev;
+
+	u8	dev_ctrl;
+	u8	dev_type;
+	u8	sen_line_num_x;
+	u8	sen_line_num_y;
+	u8	pitch_x;
+	u8	pitch_y;
+	u8	resolution;
+	u8	btn_info;
+	u8	sp_btn_info;
+	u32	x_active_len_mm;
+	u32	y_active_len_mm;
+	u32	x_max;
+	u32	y_max;
+	u32	btn_cnt;
+	u32	sp_btn_cnt;
+};
+
+static int u1_read_write_register(struct hid_device *hdev, u32 address,
+	u8 *read_val, u8 write_val, bool read_flag)
+{
+	int ret, i;
+	u8 check_sum;
+	u8 *input;
+	u8 *readbuf;
+
+	input = kzalloc(U1_FEATURE_REPORT_LEN, GFP_KERNEL);
+	if (!input)
+		return -ENOMEM;
+
+	input[0] = U1_FEATURE_REPORT_ID;
+	if (read_flag) {
+		input[1] = U1_CMD_REGISTER_READ;
+		input[6] = 0x00;
+	} else {
+		input[1] = U1_CMD_REGISTER_WRITE;
+		input[6] = write_val;
+	}
+
+	put_unaligned_le32(address, input + 2);
+
+	/* Calculate the checksum */
+	check_sum = U1_FEATURE_REPORT_LEN_ALL;
+	for (i = 0; i < U1_FEATURE_REPORT_LEN - 1; i++)
+		check_sum += input[i];
+
+	input[7] = check_sum;
+	ret = hid_hw_raw_request(hdev, U1_FEATURE_REPORT_ID, input,
+			U1_FEATURE_REPORT_LEN,
+			HID_FEATURE_REPORT, HID_REQ_SET_REPORT);
+
+	if (ret < 0) {
+		dev_err(&hdev->dev, "failed to read command (%d)\n", ret);
+		goto exit;
+	}
+
+	if (read_flag) {
+		readbuf = kzalloc(U1_FEATURE_REPORT_LEN, GFP_KERNEL);
+		if (!readbuf) {
+			kfree(input);
+			return -ENOMEM;
+		}
+
+		ret = hid_hw_raw_request(hdev, U1_FEATURE_REPORT_ID, readbuf,
+				U1_FEATURE_REPORT_LEN,
+				HID_FEATURE_REPORT, HID_REQ_GET_REPORT);
+
+		if (ret < 0) {
+			dev_err(&hdev->dev, "failed read register (%d)\n", ret);
+			goto exit;
+		}
+
+		*read_val = readbuf[6];
+
+		kfree(readbuf);
+	}
+
+	ret = 0;
+
+exit:
+	kfree(input);
+	return ret;
+}
+
+static int alps_raw_event(struct hid_device *hdev,
+		struct hid_report *report, u8 *data, int size)
+{
+	unsigned int x, y, z;
+	int i;
+	short sp_x, sp_y;
+	struct u1_dev *hdata = hid_get_drvdata(hdev);
+
+	switch (data[0]) {
+	case U1_MOUSE_REPORT_ID:
+		break;
+	case U1_FEATURE_REPORT_ID:
+		break;
+	case U1_ABSOLUTE_REPORT_ID:
+		for (i = 0; i < MAX_TOUCHES; i++) {
+			u8 *contact = &data[i * 5];
+
+			x = get_unaligned_le16(contact + 3);
+			y = get_unaligned_le16(contact + 5);
+			z = contact[7] & 0x7F;
+
+			input_mt_slot(hdata->input, i);
+
+			if (z != 0) {
+				input_mt_report_slot_state(hdata->input,
+					MT_TOOL_FINGER, 1);
+			} else {
+				input_mt_report_slot_state(hdata->input,
+					MT_TOOL_FINGER, 0);
+				break;
+			}
+
+			input_report_abs(hdata->input, ABS_MT_POSITION_X, x);
+			input_report_abs(hdata->input, ABS_MT_POSITION_Y, y);
+			input_report_abs(hdata->input, ABS_MT_PRESSURE, z);
+
+		}
+
+		input_mt_sync_frame(hdata->input);
+
+		input_report_key(hdata->input, BTN_LEFT,
+			data[1] & 0x1);
+		input_report_key(hdata->input, BTN_RIGHT,
+			(data[1] & 0x2));
+		input_report_key(hdata->input, BTN_MIDDLE,
+			(data[1] & 0x4));
+
+		input_sync(hdata->input);
+
+		return 1;
+
+	case U1_SP_ABSOLUTE_REPORT_ID:
+		sp_x = get_unaligned_le16(data+2);
+		sp_y = get_unaligned_le16(data+4);
+
+		sp_x = sp_x / 8;
+		sp_y = sp_y / 8;
+
+		input_report_rel(hdata->input2, REL_X, sp_x);
+		input_report_rel(hdata->input2, REL_Y, sp_y);
+
+		input_report_key(hdata->input2, BTN_LEFT,
+			data[1] & 0x1);
+		input_report_key(hdata->input2, BTN_RIGHT,
+			(data[1] & 0x2));
+		input_report_key(hdata->input2, BTN_MIDDLE,
+			(data[1] & 0x4));
+
+		input_sync(hdata->input2);
+
+		return 1;
+	}
+
+	return 0;
+}
+
+#ifdef CONFIG_PM
+static int alps_post_reset(struct hid_device *hdev)
+{
+	return u1_read_write_register(hdev, ADDRESS_U1_DEV_CTRL_1,
+				NULL, U1_TP_ABS_MODE | U1_SP_ABS_MODE, false);
+}
+
+static int alps_post_resume(struct hid_device *hdev)
+{
+	return u1_read_write_register(hdev, ADDRESS_U1_DEV_CTRL_1,
+				NULL, U1_TP_ABS_MODE | U1_SP_ABS_MODE, false);
+}
+#endif /* CONFIG_PM */
+
+static int alps_input_configured(struct hid_device *hdev, struct hid_input *hi)
+{
+	struct u1_dev *data = hid_get_drvdata(hdev);
+	struct input_dev *input = hi->input, *input2;
+	struct u1_dev devInfo;
+	int ret;
+	int res_x, res_y, i;
+
+	data->input = input;
+
+	hid_dbg(hdev, "Opening low level driver\n");
+	ret = hid_hw_open(hdev);
+	if (ret)
+		return ret;
+
+	/* Allow incoming hid reports */
+	hid_device_io_start(hdev);
+
+	/* Device initialization */
+	ret = u1_read_write_register(hdev, ADDRESS_U1_DEV_CTRL_1,
+			&devInfo.dev_ctrl, 0, true);
+	if (ret < 0) {
+		dev_err(&hdev->dev, "failed U1_DEV_CTRL_1 (%d)\n", ret);
+		goto exit;
+	}
+
+	devInfo.dev_ctrl &= ~U1_DISABLE_DEV;
+	devInfo.dev_ctrl |= U1_TP_ABS_MODE;
+	ret = u1_read_write_register(hdev, ADDRESS_U1_DEV_CTRL_1,
+			NULL, devInfo.dev_ctrl, false);
+	if (ret < 0) {
+		dev_err(&hdev->dev, "failed to change TP mode (%d)\n", ret);
+		goto exit;
+	}
+
+	ret = u1_read_write_register(hdev, ADDRESS_U1_NUM_SENS_X,
+			&devInfo.sen_line_num_x, 0, true);
+	if (ret < 0) {
+		dev_err(&hdev->dev, "failed U1_NUM_SENS_X (%d)\n", ret);
+		goto exit;
+	}
+
+	ret = u1_read_write_register(hdev, ADDRESS_U1_NUM_SENS_Y,
+			&devInfo.sen_line_num_y, 0, true);
+		if (ret < 0) {
+		dev_err(&hdev->dev, "failed U1_NUM_SENS_Y (%d)\n", ret);
+		goto exit;
+	}
+
+	ret = u1_read_write_register(hdev, ADDRESS_U1_PITCH_SENS_X,
+			&devInfo.pitch_x, 0, true);
+	if (ret < 0) {
+		dev_err(&hdev->dev, "failed U1_PITCH_SENS_X (%d)\n", ret);
+		goto exit;
+	}
+
+	ret = u1_read_write_register(hdev, ADDRESS_U1_PITCH_SENS_Y,
+			&devInfo.pitch_y, 0, true);
+	if (ret < 0) {
+		dev_err(&hdev->dev, "failed U1_PITCH_SENS_Y (%d)\n", ret);
+		goto exit;
+	}
+
+	ret = u1_read_write_register(hdev, ADDRESS_U1_RESO_DWN_ABS,
+		&devInfo.resolution, 0, true);
+	if (ret < 0) {
+		dev_err(&hdev->dev, "failed U1_RESO_DWN_ABS (%d)\n", ret);
+		goto exit;
+	}
+
+	ret = u1_read_write_register(hdev, ADDRESS_U1_PAD_BTN,
+			&devInfo.btn_info, 0, true);
+	if (ret < 0) {
+		dev_err(&hdev->dev, "failed U1_PAD_BTN (%d)\n", ret);
+		goto exit;
+	}
+
+	/* Check StickPointer device */
+	ret = u1_read_write_register(hdev, ADDRESS_U1_DEVICE_TYP,
+			&devInfo.dev_type, 0, true);
+	if (ret < 0) {
+		dev_err(&hdev->dev, "failed U1_DEVICE_TYP (%d)\n", ret);
+		goto exit;
+	}
+
+	devInfo.x_active_len_mm =
+		(devInfo.pitch_x * (devInfo.sen_line_num_x - 1)) / 10;
+	devInfo.y_active_len_mm =
+		(devInfo.pitch_y * (devInfo.sen_line_num_y - 1)) / 10;
+
+	devInfo.x_max =
+		(devInfo.resolution << 2) * (devInfo.sen_line_num_x - 1);
+	devInfo.y_max =
+		(devInfo.resolution << 2) * (devInfo.sen_line_num_y - 1);
+
+	__set_bit(EV_ABS, input->evbit);
+	input_set_abs_params(input, ABS_MT_POSITION_X, 1, devInfo.x_max, 0, 0);
+	input_set_abs_params(input, ABS_MT_POSITION_Y, 1, devInfo.y_max, 0, 0);
+
+	if (devInfo.x_active_len_mm && devInfo.y_active_len_mm) {
+		res_x = (devInfo.x_max - 1) / devInfo.x_active_len_mm;
+		res_y = (devInfo.y_max - 1) / devInfo.y_active_len_mm;
+
+		input_abs_set_res(input, ABS_MT_POSITION_X, res_x);
+		input_abs_set_res(input, ABS_MT_POSITION_Y, res_y);
+	}
+
+	input_set_abs_params(input, ABS_MT_PRESSURE, 0, 64, 0, 0);
+
+	input_mt_init_slots(input, MAX_TOUCHES, INPUT_MT_POINTER);
+
+	__set_bit(EV_KEY, input->evbit);
+	if ((devInfo.btn_info & 0x0F) == (devInfo.btn_info & 0xF0) >> 4) {
+		devInfo.btn_cnt = (devInfo.btn_info & 0x0F);
+	} else {
+		/* Button pad */
+		devInfo.btn_cnt = 1;
+		__set_bit(INPUT_PROP_BUTTONPAD, input->propbit);
+	}
+
+	for (i = 0; i < devInfo.btn_cnt; i++)
+		__set_bit(BTN_LEFT + i, input->keybit);
+
+
+	/* Stick device initialization */
+	if (devInfo.dev_type & U1_DEVTYPE_SP_SUPPORT) {
+
+		input2 = input_allocate_device();
+		if (!input2) {
+			input_free_device(input2);
+			goto exit;
+		}
+
+		data->input2 = input2;
+
+		devInfo.dev_ctrl |= U1_SP_ABS_MODE;
+		ret = u1_read_write_register(hdev, ADDRESS_U1_DEV_CTRL_1,
+			NULL, devInfo.dev_ctrl, false);
+		if (ret < 0) {
+			dev_err(&hdev->dev, "failed SP mode (%d)\n", ret);
+			input_free_device(input2);
+			goto exit;
+		}
+
+		ret = u1_read_write_register(hdev, ADDRESS_U1_SP_BTN,
+			&devInfo.sp_btn_info, 0, true);
+		if (ret < 0) {
+			dev_err(&hdev->dev, "failed U1_SP_BTN (%d)\n", ret);
+			input_free_device(input2);
+			goto exit;
+		}
+
+		input2->phys = input->phys;
+		input2->name = "DualPoint Stick";
+		input2->id.bustype = BUS_I2C;
+		input2->id.vendor  = input->id.vendor;
+		input2->id.product = input->id.product;
+		input2->id.version = input->id.version;
+		input2->dev.parent = input->dev.parent;
+
+		__set_bit(EV_KEY, input2->evbit);
+		devInfo.sp_btn_cnt = (devInfo.sp_btn_info & 0x0F);
+		for (i = 0; i < devInfo.sp_btn_cnt; i++)
+			__set_bit(BTN_LEFT + i, input2->keybit);
+
+		__set_bit(EV_REL, input2->evbit);
+		__set_bit(REL_X, input2->relbit);
+		__set_bit(REL_Y, input2->relbit);
+		__set_bit(INPUT_PROP_POINTER, input2->propbit);
+		__set_bit(INPUT_PROP_POINTING_STICK, input2->propbit);
+
+		if (input_register_device(data->input2)) {
+			input_free_device(input2);
+			goto exit;
+		}
+	}
+
+exit:
+	hid_device_io_stop(hdev);
+	hid_hw_close(hdev);
+	return ret;
+}
+
+static int alps_input_mapping(struct hid_device *hdev,
+		struct hid_input *hi, struct hid_field *field,
+		struct hid_usage *usage, unsigned long **bit, int *max)
+{
+	return -1;
+}
+
+static int alps_probe(struct hid_device *hdev, const struct hid_device_id *id)
+{
+	struct u1_dev *data = NULL;
+	int ret;
+
+	data = devm_kzalloc(&hdev->dev, sizeof(struct u1_dev), GFP_KERNEL);
+	if (!data)
+		return -ENOMEM;
+
+	data->hdev = hdev;
+	hid_set_drvdata(hdev, data);
+
+	hdev->quirks |= HID_QUIRK_NO_INIT_REPORTS;
+
+	ret = hid_parse(hdev);
+	if (ret) {
+		hid_err(hdev, "parse failed\n");
+		return ret;
+	}
+
+	ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
+	if (ret) {
+		hid_err(hdev, "hw start failed\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+static void alps_remove(struct hid_device *hdev)
+{
+	hid_hw_stop(hdev);
+}
+
+static const struct hid_device_id alps_id[] = {
+	{ HID_DEVICE(HID_BUS_ANY, HID_GROUP_ANY,
+		USB_VENDOR_ID_ALPS_JP, HID_DEVICE_ID_ALPS_U1_DUAL) },
+	{ }
+};
+MODULE_DEVICE_TABLE(hid, alps_id);
+
+static struct hid_driver alps_driver = {
+	.name = "hid-alps",
+	.id_table		= alps_id,
+	.probe			= alps_probe,
+	.remove			= alps_remove,
+	.raw_event		= alps_raw_event,
+	.input_mapping		= alps_input_mapping,
+	.input_configured	= alps_input_configured,
+#ifdef CONFIG_PM
+	.resume			= alps_post_resume,
+	.reset_resume		= alps_post_reset,
+#endif
+};
+
+module_hid_driver(alps_driver);
+
+MODULE_AUTHOR("Masaki Ota <masaki.ota@jp.alps.com>");
+MODULE_DESCRIPTION("ALPS HID driver");
+MODULE_LICENSE("GPL");
--- zfcpdump-kernel-4.4.orig/drivers/hid/hid-core.c
+++ zfcpdump-kernel-4.4/drivers/hid/hid-core.c
@@ -1251,6 +1251,7 @@ static void hid_input_field(struct hid_d
 		/* Ignore report if ErrorRollOver */
 		if (!(field->flags & HID_MAIN_ITEM_VARIABLE) &&
 		    value[n] >= min && value[n] <= max &&
+		    value[n] - min < field->maxusage &&
 		    field->usage[value[n] - min].hid == HID_UP_KEYBOARD + 1)
 			goto exit;
 	}
@@ -1263,11 +1264,13 @@ static void hid_input_field(struct hid_d
 		}
 
 		if (field->value[n] >= min && field->value[n] <= max
+			&& field->value[n] - min < field->maxusage
 			&& field->usage[field->value[n] - min].hid
 			&& search(value, field->value[n], count))
 				hid_process_event(hid, field, &field->usage[field->value[n] - min], 0, interrupt);
 
 		if (value[n] >= min && value[n] <= max
+			&& value[n] - min < field->maxusage
 			&& field->usage[value[n] - min].hid
 			&& search(field->value, value[n], count))
 				hid_process_event(hid, field, &field->usage[value[n] - min], 1, interrupt);
@@ -1736,6 +1739,7 @@ static const struct hid_device_id hid_ha
 	{ HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_RP_649) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_ACRUX, 0x0802) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_ACRUX, 0xf705) },
+	{ HID_DEVICE(HID_BUS_ANY, HID_GROUP_ANY, USB_VENDOR_ID_ALPS_JP, HID_DEVICE_ID_ALPS_U1_DUAL) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MIGHTYMOUSE) },
 	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGICMOUSE) },
 	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGICTRACKPAD) },
@@ -1897,6 +1901,7 @@ static const struct hid_device_id hid_ha
 	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_ELITE_KBD) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_CORDLESS_DESKTOP_LX500) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_EXTREME_3D) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_DUAL_ACTION) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WHEEL) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD_CORD) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD) },
@@ -2615,9 +2620,10 @@ int hid_add_device(struct hid_device *hd
 	/*
 	 * Scan generic devices for group information
 	 */
-	if (hid_ignore_special_drivers ||
-	    (!hdev->group &&
-	     !hid_match_id(hdev, hid_have_special_driver))) {
+	if (hid_ignore_special_drivers) {
+		hdev->group = HID_GROUP_GENERIC;
+	} else if (!hdev->group &&
+		   !hid_match_id(hdev, hid_have_special_driver)) {
 		ret = hid_scan_report(hdev);
 		if (ret)
 			hid_warn(hdev, "bad device descriptor (%d)\n", ret);
--- zfcpdump-kernel-4.4.orig/drivers/hid/hid-elo.c
+++ zfcpdump-kernel-4.4/drivers/hid/hid-elo.c
@@ -261,7 +261,7 @@ static void elo_remove(struct hid_device
 	struct elo_priv *priv = hid_get_drvdata(hdev);
 
 	hid_hw_stop(hdev);
-	flush_workqueue(wq);
+	cancel_delayed_work_sync(&priv->work);
 	kfree(priv);
 }
 
--- zfcpdump-kernel-4.4.orig/drivers/hid/hid-ids.h
+++ zfcpdump-kernel-4.4/drivers/hid/hid-ids.h
@@ -67,6 +67,9 @@
 #define USB_VENDOR_ID_ALPS		0x0433
 #define USB_DEVICE_ID_IBM_GAMEPAD	0x1101
 
+#define USB_VENDOR_ID_ALPS_JP		0x044E
+#define HID_DEVICE_ID_ALPS_U1_DUAL	0x120B
+
 #define USB_VENDOR_ID_ANTON		0x1130
 #define USB_DEVICE_ID_ANTON_TOUCH_PAD	0x3101
 
@@ -255,6 +258,7 @@
 #define USB_DEVICE_ID_CORSAIR_K90	0x1b02
 
 #define USB_VENDOR_ID_CREATIVELABS	0x041e
+#define USB_DEVICE_ID_CREATIVE_SB_OMNI_SURROUND_51	0x322c
 #define USB_DEVICE_ID_PRODIKEYS_PCMIDI	0x2801
 
 #define USB_VENDOR_ID_CVTOUCH		0x1ff7
--- zfcpdump-kernel-4.4.orig/drivers/hid/hid-input.c
+++ zfcpdump-kernel-4.4/drivers/hid/hid-input.c
@@ -946,6 +946,7 @@ static void hidinput_configure_usage(str
 	case HID_UP_HPVENDOR2:
 		set_bit(EV_REP, input->evbit);
 		switch (usage->hid & HID_USAGE) {
+		case 0x001: map_key_clear(KEY_MICMUTE);		break;
 		case 0x003: map_key_clear(KEY_BRIGHTNESSDOWN);	break;
 		case 0x004: map_key_clear(KEY_BRIGHTNESSUP);	break;
 		default:    goto ignore;
--- zfcpdump-kernel-4.4.orig/drivers/hid/hid-multitouch.c
+++ zfcpdump-kernel-4.4/drivers/hid/hid-multitouch.c
@@ -61,6 +61,7 @@ MODULE_LICENSE("GPL");
 #define MT_QUIRK_ALWAYS_VALID		(1 << 4)
 #define MT_QUIRK_VALID_IS_INRANGE	(1 << 5)
 #define MT_QUIRK_VALID_IS_CONFIDENCE	(1 << 6)
+#define MT_QUIRK_CONFIDENCE		(1 << 7)
 #define MT_QUIRK_SLOT_IS_CONTACTID_MINUS_ONE	(1 << 8)
 #define MT_QUIRK_NO_AREA		(1 << 9)
 #define MT_QUIRK_IGNORE_DUPLICATES	(1 << 10)
@@ -78,6 +79,7 @@ struct mt_slot {
 	__s32 contactid;	/* the device ContactID assigned to this slot */
 	bool touch_state;	/* is the touch valid? */
 	bool inrange_state;	/* is the finger in proximity of the sensor? */
+	bool confidence_state;  /* is the touch made by a finger? */
 };
 
 struct mt_class {
@@ -357,8 +359,19 @@ static void mt_feature_mapping(struct hi
 			break;
 		}
 
-		td->inputmode = field->report->id;
-		td->inputmode_index = usage->usage_index;
+		if (td->inputmode < 0) {
+			td->inputmode = field->report->id;
+			td->inputmode_index = usage->usage_index;
+		} else {
+			/*
+			 * Some elan panels wrongly declare 2 input mode
+			 * features, and silently ignore when we set the
+			 * value in the second field. Skip the second feature
+			 * and hope for the best.
+			 */
+			dev_info(&hdev->dev,
+				 "Ignoring the extra HID_DG_INPUTMODE\n");
+		}
 
 		break;
 	case HID_DG_CONTACTMAX:
@@ -385,6 +398,11 @@ static void mt_feature_mapping(struct hi
 			td->is_buttonpad = true;
 
 		break;
+	case 0xff0000c5:
+		/* Retrieve the Win8 blob once to enable some devices */
+		if (usage->usage_index == 0)
+			mt_get_feature(hdev, field->report);
+		break;
 	}
 }
 
@@ -486,6 +504,9 @@ static int mt_touch_input_mapping(struct
 			mt_store_field(usage, td, hi);
 			return 1;
 		case HID_DG_CONFIDENCE:
+			if (cls->name == MT_CLS_WIN_8 &&
+				field->application == HID_DG_TOUCHPAD)
+				cls->quirks |= MT_QUIRK_CONFIDENCE;
 			mt_store_field(usage, td, hi);
 			return 1;
 		case HID_DG_TIPSWITCH:
@@ -598,6 +619,7 @@ static void mt_complete_slot(struct mt_d
 		return;
 
 	if (td->curvalid || (td->mtclass.quirks & MT_QUIRK_ALWAYS_VALID)) {
+		int active;
 		int slotnum = mt_compute_slot(td, input);
 		struct mt_slot *s = &td->curdata;
 		struct input_mt *mt = input->mt;
@@ -612,10 +634,14 @@ static void mt_complete_slot(struct mt_d
 				return;
 		}
 
+		if (!(td->mtclass.quirks & MT_QUIRK_CONFIDENCE))
+			s->confidence_state = 1;
+		active = (s->touch_state || s->inrange_state) &&
+							s->confidence_state;
+
 		input_mt_slot(input, slotnum);
-		input_mt_report_slot_state(input, MT_TOOL_FINGER,
-			s->touch_state || s->inrange_state);
-		if (s->touch_state || s->inrange_state) {
+		input_mt_report_slot_state(input, MT_TOOL_FINGER, active);
+		if (active) {
 			/* this finger is in proximity of the sensor */
 			int wide = (s->w > s->h);
 			/* divided by two to match visual scale of touch */
@@ -680,6 +706,8 @@ static void mt_process_mt_event(struct h
 			td->curdata.touch_state = value;
 			break;
 		case HID_DG_CONFIDENCE:
+			if (quirks & MT_QUIRK_CONFIDENCE)
+				td->curdata.confidence_state = value;
 			if (quirks & MT_QUIRK_VALID_IS_CONFIDENCE)
 				td->curvalid = value;
 			break;
--- zfcpdump-kernel-4.4.orig/drivers/hid/hid-sony.c
+++ zfcpdump-kernel-4.4/drivers/hid/hid-sony.c
@@ -1418,8 +1418,10 @@ static int sixaxis_set_operational_usb(s
 	}
 
 	ret = hid_hw_output_report(hdev, buf, 1);
-	if (ret < 0)
-		hid_err(hdev, "can't set operational mode: step 3\n");
+	if (ret < 0) {
+		hid_info(hdev, "can't set operational mode: step 3, ignoring\n");
+		ret = 0;
+	}
 
 out:
 	kfree(buf);
--- zfcpdump-kernel-4.4.orig/drivers/hid/i2c-hid/i2c-hid.c
+++ zfcpdump-kernel-4.4/drivers/hid/i2c-hid/i2c-hid.c
@@ -282,17 +282,21 @@ static int i2c_hid_set_or_send_report(st
 	u16 dataRegister = le16_to_cpu(ihid->hdesc.wDataRegister);
 	u16 outputRegister = le16_to_cpu(ihid->hdesc.wOutputRegister);
 	u16 maxOutputLength = le16_to_cpu(ihid->hdesc.wMaxOutputLength);
+	u16 size;
+	int args_len;
+	int index = 0;
+
+	i2c_hid_dbg(ihid, "%s\n", __func__);
+
+	if (data_len > ihid->bufsize)
+		return -EINVAL;
 
-	/* hid_hw_* already checked that data_len < HID_MAX_BUFFER_SIZE */
-	u16 size =	2			/* size */ +
+	size =		2			/* size */ +
 			(reportID ? 1 : 0)	/* reportID */ +
 			data_len		/* buf */;
-	int args_len =	(reportID >= 0x0F ? 1 : 0) /* optional third byte */ +
+	args_len =	(reportID >= 0x0F ? 1 : 0) /* optional third byte */ +
 			2			/* dataRegister */ +
 			size			/* args */;
-	int index = 0;
-
-	i2c_hid_dbg(ihid, "%s\n", __func__);
 
 	if (!use_data && maxOutputLength == 0)
 		return -ENOSYS;
--- zfcpdump-kernel-4.4.orig/drivers/hid/uhid.c
+++ zfcpdump-kernel-4.4/drivers/hid/uhid.c
@@ -51,10 +51,26 @@ struct uhid_device {
 	u32 report_id;
 	u32 report_type;
 	struct uhid_event report_buf;
+	struct work_struct worker;
 };
 
 static struct miscdevice uhid_misc;
 
+static void uhid_device_add_worker(struct work_struct *work)
+{
+	struct uhid_device *uhid = container_of(work, struct uhid_device, worker);
+	int ret;
+
+	ret = hid_add_device(uhid->hid);
+	if (ret) {
+		hid_err(uhid->hid, "Cannot register HID device: error %d\n", ret);
+
+		hid_destroy_device(uhid->hid);
+		uhid->hid = NULL;
+		uhid->running = false;
+	}
+}
+
 static void uhid_queue(struct uhid_device *uhid, struct uhid_event *ev)
 {
 	__u8 newhead;
@@ -498,18 +514,14 @@ static int uhid_dev_create2(struct uhid_
 	uhid->hid = hid;
 	uhid->running = true;
 
-	ret = hid_add_device(hid);
-	if (ret) {
-		hid_err(hid, "Cannot register HID device\n");
-		goto err_hid;
-	}
+	/* Adding of a HID device is done through a worker, to allow HID drivers
+	 * which use feature requests during .probe to work, without they would
+	 * be blocked on devlock, which is held by uhid_char_write.
+	 */
+	schedule_work(&uhid->worker);
 
 	return 0;
 
-err_hid:
-	hid_destroy_device(hid);
-	uhid->hid = NULL;
-	uhid->running = false;
 err_free:
 	kfree(uhid->rd_data);
 	uhid->rd_data = NULL;
@@ -550,6 +562,8 @@ static int uhid_dev_destroy(struct uhid_
 	uhid->running = false;
 	wake_up_interruptible(&uhid->report_wait);
 
+	cancel_work_sync(&uhid->worker);
+
 	hid_destroy_device(uhid->hid);
 	kfree(uhid->rd_data);
 
@@ -612,6 +626,7 @@ static int uhid_char_open(struct inode *
 	init_waitqueue_head(&uhid->waitq);
 	init_waitqueue_head(&uhid->report_wait);
 	uhid->running = false;
+	INIT_WORK(&uhid->worker, uhid_device_add_worker);
 
 	file->private_data = uhid;
 	nonseekable_open(inode, file);
--- zfcpdump-kernel-4.4.orig/drivers/hid/usbhid/hid-core.c
+++ zfcpdump-kernel-4.4/drivers/hid/usbhid/hid-core.c
@@ -477,8 +477,6 @@ static void hid_ctrl(struct urb *urb)
 	struct usbhid_device *usbhid = hid->driver_data;
 	int unplug = 0, status = urb->status;
 
-	spin_lock(&usbhid->lock);
-
 	switch (status) {
 	case 0:			/* success */
 		if (usbhid->ctrl[usbhid->ctrltail].dir == USB_DIR_IN)
@@ -498,6 +496,8 @@ static void hid_ctrl(struct urb *urb)
 		hid_warn(urb->dev, "ctrl urb status %d received\n", status);
 	}
 
+	spin_lock(&usbhid->lock);
+
 	if (unplug) {
 		usbhid->ctrltail = usbhid->ctrlhead;
 	} else {
@@ -951,14 +951,6 @@ static int usbhid_output_report(struct h
 	return ret;
 }
 
-static void usbhid_restart_queues(struct usbhid_device *usbhid)
-{
-	if (usbhid->urbout && !test_bit(HID_OUT_RUNNING, &usbhid->iofl))
-		usbhid_restart_out_queue(usbhid);
-	if (!test_bit(HID_CTRL_RUNNING, &usbhid->iofl))
-		usbhid_restart_ctrl_queue(usbhid);
-}
-
 static void hid_free_buffers(struct usb_device *dev, struct hid_device *hid)
 {
 	struct usbhid_device *usbhid = hid->driver_data;
@@ -1404,6 +1396,37 @@ static void hid_cease_io(struct usbhid_d
 	usb_kill_urb(usbhid->urbout);
 }
 
+static void hid_restart_io(struct hid_device *hid)
+{
+	struct usbhid_device *usbhid = hid->driver_data;
+	int clear_halt = test_bit(HID_CLEAR_HALT, &usbhid->iofl);
+	int reset_pending = test_bit(HID_RESET_PENDING, &usbhid->iofl);
+
+	spin_lock_irq(&usbhid->lock);
+	clear_bit(HID_SUSPENDED, &usbhid->iofl);
+	usbhid_mark_busy(usbhid);
+
+	if (clear_halt || reset_pending)
+		schedule_work(&usbhid->reset_work);
+	usbhid->retry_delay = 0;
+	spin_unlock_irq(&usbhid->lock);
+
+	if (reset_pending || !test_bit(HID_STARTED, &usbhid->iofl))
+		return;
+
+	if (!clear_halt) {
+		if (hid_start_in(hid) < 0)
+			hid_io_error(hid);
+	}
+
+	spin_lock_irq(&usbhid->lock);
+	if (usbhid->urbout && !test_bit(HID_OUT_RUNNING, &usbhid->iofl))
+		usbhid_restart_out_queue(usbhid);
+	if (!test_bit(HID_CTRL_RUNNING, &usbhid->iofl))
+		usbhid_restart_ctrl_queue(usbhid);
+	spin_unlock_irq(&usbhid->lock);
+}
+
 /* Treat USB reset pretty much the same as suspend/resume */
 static int hid_pre_reset(struct usb_interface *intf)
 {
@@ -1453,14 +1476,14 @@ static int hid_post_reset(struct usb_int
 		return 1;
 	}
 
+	/* No need to do another reset or clear a halted endpoint */
 	spin_lock_irq(&usbhid->lock);
 	clear_bit(HID_RESET_PENDING, &usbhid->iofl);
+	clear_bit(HID_CLEAR_HALT, &usbhid->iofl);
 	spin_unlock_irq(&usbhid->lock);
 	hid_set_idle(dev, intf->cur_altsetting->desc.bInterfaceNumber, 0, 0);
-	status = hid_start_in(hid);
-	if (status < 0)
-		hid_io_error(hid);
-	usbhid_restart_queues(usbhid);
+
+	hid_restart_io(hid);
 
 	return 0;
 }
@@ -1483,25 +1506,9 @@ void usbhid_put_power(struct hid_device
 #ifdef CONFIG_PM
 static int hid_resume_common(struct hid_device *hid, bool driver_suspended)
 {
-	struct usbhid_device *usbhid = hid->driver_data;
-	int status;
-
-	spin_lock_irq(&usbhid->lock);
-	clear_bit(HID_SUSPENDED, &usbhid->iofl);
-	usbhid_mark_busy(usbhid);
-
-	if (test_bit(HID_CLEAR_HALT, &usbhid->iofl) ||
-			test_bit(HID_RESET_PENDING, &usbhid->iofl))
-		schedule_work(&usbhid->reset_work);
-	usbhid->retry_delay = 0;
-
-	usbhid_restart_queues(usbhid);
-	spin_unlock_irq(&usbhid->lock);
-
-	status = hid_start_in(hid);
-	if (status < 0)
-		hid_io_error(hid);
+	int status = 0;
 
+	hid_restart_io(hid);
 	if (driver_suspended && hid->driver && hid->driver->resume)
 		status = hid->driver->resume(hid);
 	return status;
@@ -1570,12 +1577,8 @@ static int hid_suspend(struct usb_interf
 static int hid_resume(struct usb_interface *intf)
 {
 	struct hid_device *hid = usb_get_intfdata (intf);
-	struct usbhid_device *usbhid = hid->driver_data;
 	int status;
 
-	if (!test_bit(HID_STARTED, &usbhid->iofl))
-		return 0;
-
 	status = hid_resume_common(hid, true);
 	dev_dbg(&intf->dev, "resume status %d\n", status);
 	return 0;
@@ -1584,10 +1587,8 @@ static int hid_resume(struct usb_interfa
 static int hid_reset_resume(struct usb_interface *intf)
 {
 	struct hid_device *hid = usb_get_intfdata(intf);
-	struct usbhid_device *usbhid = hid->driver_data;
 	int status;
 
-	clear_bit(HID_SUSPENDED, &usbhid->iofl);
 	status = hid_post_reset(intf);
 	if (status >= 0 && hid->driver && hid->driver->reset_resume) {
 		int ret = hid->driver->reset_resume(hid);
--- zfcpdump-kernel-4.4.orig/drivers/hid/usbhid/hid-quirks.c
+++ zfcpdump-kernel-4.4/drivers/hid/usbhid/hid-quirks.c
@@ -70,6 +70,7 @@ static const struct hid_blacklist {
 	{ USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_3AXIS_5BUTTON_STICK, HID_QUIRK_NOGET },
 	{ USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_AXIS_295, HID_QUIRK_NOGET },
 	{ USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_PIXART_USB_OPTICAL_MOUSE, HID_QUIRK_ALWAYS_POLL },
+	{ USB_VENDOR_ID_CREATIVELABS, USB_DEVICE_ID_CREATIVE_SB_OMNI_SURROUND_51, HID_QUIRK_NOGET },
 	{ USB_VENDOR_ID_DMI, USB_DEVICE_ID_DMI_ENC, HID_QUIRK_NOGET },
 	{ USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_WIIU, HID_QUIRK_MULTI_INPUT },
 	{ USB_VENDOR_ID_ELAN, HID_ANY_ID, HID_QUIRK_ALWAYS_POLL },
--- zfcpdump-kernel-4.4.orig/drivers/hid/usbhid/hiddev.c
+++ zfcpdump-kernel-4.4/drivers/hid/usbhid/hiddev.c
@@ -516,13 +516,13 @@ static noinline int hiddev_ioctl_usage(s
 					goto inval;
 			} else if (uref->usage_index >= field->report_count)
 				goto inval;
-
-			else if ((cmd == HIDIOCGUSAGES || cmd == HIDIOCSUSAGES) &&
-				 (uref_multi->num_values > HID_MAX_MULTI_USAGES ||
-				  uref->usage_index + uref_multi->num_values > field->report_count))
-				goto inval;
 		}
 
+		if ((cmd == HIDIOCGUSAGES || cmd == HIDIOCSUSAGES) &&
+		    (uref_multi->num_values > HID_MAX_MULTI_USAGES ||
+		     uref->usage_index + uref_multi->num_values > field->report_count))
+			goto inval;
+
 		switch (cmd) {
 		case HIDIOCGUSAGE:
 			uref->value = field->value[uref->usage_index];
--- zfcpdump-kernel-4.4.orig/drivers/hid/wacom_sys.c
+++ zfcpdump-kernel-4.4/drivers/hid/wacom_sys.c
@@ -152,6 +152,25 @@ static void wacom_feature_mapping(struct
 		hid_data->inputmode = field->report->id;
 		hid_data->inputmode_index = usage->usage_index;
 		break;
+
+	case HID_UP_DIGITIZER:
+		if (field->report->id == 0x0B &&
+		    (field->application == WACOM_G9_DIGITIZER ||
+		     field->application == WACOM_G11_DIGITIZER)) {
+			wacom->wacom_wac.mode_report = field->report->id;
+			wacom->wacom_wac.mode_value = 0;
+		}
+		break;
+
+	case WACOM_G9_PAGE:
+	case WACOM_G11_PAGE:
+		if (field->report->id == 0x03 &&
+		    (field->application == WACOM_G9_TOUCHSCREEN ||
+		     field->application == WACOM_G11_TOUCHSCREEN)) {
+			wacom->wacom_wac.mode_report = field->report->id;
+			wacom->wacom_wac.mode_value = 0;
+		}
+		break;
 	}
 }
 
@@ -322,26 +341,41 @@ static int wacom_hid_set_device_mode(str
 	return 0;
 }
 
-static int wacom_set_device_mode(struct hid_device *hdev, int report_id,
-		int length, int mode)
+static int wacom_set_device_mode(struct hid_device *hdev,
+				 struct wacom_wac *wacom_wac)
 {
-	unsigned char *rep_data;
+	u8 *rep_data;
+	struct hid_report *r;
+	struct hid_report_enum *re;
+	int length;
 	int error = -ENOMEM, limit = 0;
 
-	rep_data = kzalloc(length, GFP_KERNEL);
+	if (wacom_wac->mode_report < 0)
+		return 0;
+
+	re = &(hdev->report_enum[HID_FEATURE_REPORT]);
+	r = re->report_id_hash[wacom_wac->mode_report];
+	if (!r)
+		return -EINVAL;
+
+	rep_data = hid_alloc_report_buf(r, GFP_KERNEL);
 	if (!rep_data)
-		return error;
+		return -ENOMEM;
+
+	length = hid_report_len(r);
 
 	do {
-		rep_data[0] = report_id;
-		rep_data[1] = mode;
+		rep_data[0] = wacom_wac->mode_report;
+		rep_data[1] = wacom_wac->mode_value;
 
 		error = wacom_set_report(hdev, HID_FEATURE_REPORT, rep_data,
 					 length, 1);
 		if (error >= 0)
 			error = wacom_get_report(hdev, HID_FEATURE_REPORT,
 			                         rep_data, length, 1);
-	} while (error >= 0 && rep_data[1] != mode && limit++ < WAC_MSG_RETRIES);
+	} while (error >= 0 &&
+		 rep_data[1] != wacom_wac->mode_report &&
+		 limit++ < WAC_MSG_RETRIES);
 
 	kfree(rep_data);
 
@@ -411,32 +445,41 @@ static int wacom_bt_query_tablet_data(st
 static int wacom_query_tablet_data(struct hid_device *hdev,
 		struct wacom_features *features)
 {
+	struct wacom *wacom = hid_get_drvdata(hdev);
+	struct wacom_wac *wacom_wac = &wacom->wacom_wac;
+
 	if (hdev->bus == BUS_BLUETOOTH)
 		return wacom_bt_query_tablet_data(hdev, 1, features);
 
-	if (features->type == HID_GENERIC)
-		return wacom_hid_set_device_mode(hdev);
-
-	if (features->device_type & WACOM_DEVICETYPE_TOUCH) {
-		if (features->type > TABLETPC) {
-			/* MT Tablet PC touch */
-			return wacom_set_device_mode(hdev, 3, 4, 4);
-		}
-		else if (features->type == WACOM_24HDT) {
-			return wacom_set_device_mode(hdev, 18, 3, 2);
-		}
-		else if (features->type == WACOM_27QHDT) {
-			return wacom_set_device_mode(hdev, 131, 3, 2);
-		}
-		else if (features->type == BAMBOO_PAD) {
-			return wacom_set_device_mode(hdev, 2, 2, 2);
-		}
-	} else if (features->device_type & WACOM_DEVICETYPE_PEN) {
-		if (features->type <= BAMBOO_PT) {
-			return wacom_set_device_mode(hdev, 2, 2, 2);
+	if (features->type != HID_GENERIC) {
+		if (features->device_type & WACOM_DEVICETYPE_TOUCH) {
+			if (features->type > TABLETPC) {
+				/* MT Tablet PC touch */
+				wacom_wac->mode_report = 3;
+				wacom_wac->mode_value = 4;
+			} else if (features->type == WACOM_24HDT) {
+				wacom_wac->mode_report = 18;
+				wacom_wac->mode_value = 2;
+			} else if (features->type == WACOM_27QHDT) {
+				wacom_wac->mode_report = 131;
+				wacom_wac->mode_value = 2;
+			} else if (features->type == BAMBOO_PAD) {
+				wacom_wac->mode_report = 2;
+				wacom_wac->mode_value = 2;
+			}
+		} else if (features->device_type & WACOM_DEVICETYPE_PEN) {
+			if (features->type <= BAMBOO_PT) {
+				wacom_wac->mode_report = 2;
+				wacom_wac->mode_value = 2;
+			}
 		}
 	}
 
+	wacom_set_device_mode(hdev, wacom_wac);
+
+	if (features->type == HID_GENERIC)
+		return wacom_hid_set_device_mode(hdev);
+
 	return 0;
 }
 
@@ -1686,61 +1729,21 @@ static void wacom_update_name(struct wac
 		"%s Pad", name);
 }
 
-static int wacom_probe(struct hid_device *hdev,
-		const struct hid_device_id *id)
+static int wacom_parse_and_register(struct wacom *wacom)
 {
-	struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
-	struct usb_device *dev = interface_to_usbdev(intf);
-	struct wacom *wacom;
-	struct wacom_wac *wacom_wac;
-	struct wacom_features *features;
+	struct wacom_wac *wacom_wac = &wacom->wacom_wac;
+	struct wacom_features *features = &wacom_wac->features;
+	struct hid_device *hdev = wacom->hdev;
 	int error;
 	unsigned int connect_mask = HID_CONNECT_HIDRAW;
 
-	if (!id->driver_data)
-		return -EINVAL;
-
-	hdev->quirks |= HID_QUIRK_NO_INIT_REPORTS;
-
-	/* hid-core sets this quirk for the boot interface */
-	hdev->quirks &= ~HID_QUIRK_NOGET;
-
-	wacom = kzalloc(sizeof(struct wacom), GFP_KERNEL);
-	if (!wacom)
-		return -ENOMEM;
-
-	hid_set_drvdata(hdev, wacom);
-	wacom->hdev = hdev;
-
-	/* ask for the report descriptor to be loaded by HID */
-	error = hid_parse(hdev);
-	if (error) {
-		hid_err(hdev, "parse failed\n");
-		goto fail_parse;
-	}
-
-	wacom_wac = &wacom->wacom_wac;
-	wacom_wac->features = *((struct wacom_features *)id->driver_data);
-	features = &wacom_wac->features;
 	features->pktlen = wacom_compute_pktlen(hdev);
-	if (features->pktlen > WACOM_PKGLEN_MAX) {
-		error = -EINVAL;
-		goto fail_pktlen;
-	}
-
-	if (features->check_for_hid_type && features->hid_type != hdev->type) {
-		error = -ENODEV;
-		goto fail_type;
-	}
-
-	wacom->usbdev = dev;
-	wacom->intf = intf;
-	mutex_init(&wacom->lock);
-	INIT_WORK(&wacom->work, wacom_wireless_work);
+	if (features->pktlen > WACOM_PKGLEN_MAX)
+		return -EINVAL;
 
 	error = wacom_allocate_inputs(wacom);
 	if (error)
-		goto fail_allocate_inputs;
+		return error;
 
 	/*
 	 * Bamboo Pad has a generic hid handling for the Pen, and we switch it
@@ -1753,7 +1756,7 @@ static int wacom_probe(struct hid_device
 		} else if ((features->pktlen != WACOM_PKGLEN_BPAD_TOUCH) &&
 			   (features->pktlen != WACOM_PKGLEN_BPAD_TOUCH_USB)) {
 			error = -ENODEV;
-			goto fail_shared_data;
+			goto fail_allocate_inputs;
 		}
 	}
 
@@ -1773,7 +1776,7 @@ static int wacom_probe(struct hid_device
 			 error ? "Ignoring" : "Assuming pen");
 
 		if (error)
-			goto fail_shared_data;
+			goto fail_parsed;
 
 		features->device_type |= WACOM_DEVICETYPE_PEN;
 	}
@@ -1797,14 +1800,6 @@ static int wacom_probe(struct hid_device
 	if (error)
 		goto fail_register_inputs;
 
-	if (hdev->bus == BUS_BLUETOOTH) {
-		error = device_create_file(&hdev->dev, &dev_attr_speed);
-		if (error)
-			hid_warn(hdev,
-				 "can't create sysfs speed attribute err: %d\n",
-				 error);
-	}
-
 	if (features->type == HID_GENERIC)
 		connect_mask |= HID_CONNECT_DRIVER;
 
@@ -1845,18 +1840,83 @@ static int wacom_probe(struct hid_device
 	return 0;
 
 fail_hw_start:
-	if (hdev->bus == BUS_BLUETOOTH)
-		device_remove_file(&hdev->dev, &dev_attr_speed);
+	hid_hw_stop(hdev);
 fail_register_inputs:
 	wacom_clean_inputs(wacom);
 	wacom_destroy_battery(wacom);
 fail_battery:
 	wacom_remove_shared_data(wacom);
 fail_shared_data:
-	wacom_clean_inputs(wacom);
+fail_parsed:
 fail_allocate_inputs:
+	wacom_clean_inputs(wacom);
+	return error;
+}
+
+static int wacom_probe(struct hid_device *hdev,
+		const struct hid_device_id *id)
+{
+	struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
+	struct usb_device *dev = interface_to_usbdev(intf);
+	struct wacom *wacom;
+	struct wacom_wac *wacom_wac;
+	struct wacom_features *features;
+	int error;
+
+	if (!id->driver_data)
+		return -EINVAL;
+
+	hdev->quirks |= HID_QUIRK_NO_INIT_REPORTS;
+
+	/* hid-core sets this quirk for the boot interface */
+	hdev->quirks &= ~HID_QUIRK_NOGET;
+
+	wacom = kzalloc(sizeof(struct wacom), GFP_KERNEL);
+	if (!wacom)
+		return -ENOMEM;
+
+	hid_set_drvdata(hdev, wacom);
+	wacom->hdev = hdev;
+
+	wacom_wac = &wacom->wacom_wac;
+	wacom_wac->features = *((struct wacom_features *)id->driver_data);
+	features = &wacom_wac->features;
+
+	if (features->check_for_hid_type && features->hid_type != hdev->type) {
+		error = -ENODEV;
+		goto fail_type;
+	}
+
+	wacom_wac->hid_data.inputmode = -1;
+	wacom_wac->mode_report = -1;
+
+	wacom->usbdev = dev;
+	wacom->intf = intf;
+	mutex_init(&wacom->lock);
+	INIT_WORK(&wacom->work, wacom_wireless_work);
+
+	/* ask for the report descriptor to be loaded by HID */
+	error = hid_parse(hdev);
+	if (error) {
+		hid_err(hdev, "parse failed\n");
+		goto fail_parse;
+	}
+
+	error = wacom_parse_and_register(wacom);
+	if (error)
+		goto fail_parse;
+
+	if (hdev->bus == BUS_BLUETOOTH) {
+		error = device_create_file(&hdev->dev, &dev_attr_speed);
+		if (error)
+			hid_warn(hdev,
+				 "can't create sysfs speed attribute err: %d\n",
+				 error);
+	}
+
+	return 0;
+
 fail_type:
-fail_pktlen:
 fail_parse:
 	kfree(wacom);
 	hid_set_drvdata(hdev, NULL);
--- zfcpdump-kernel-4.4.orig/drivers/hid/wacom_wac.c
+++ zfcpdump-kernel-4.4/drivers/hid/wacom_wac.c
@@ -2493,6 +2493,17 @@ void wacom_setup_device_quirks(struct wa
 	}
 
 	/*
+	 * Hack for the Bamboo One:
+	 * the device presents a PAD/Touch interface as most Bamboos and even
+	 * sends ghosts PAD data on it. However, later, we must disable this
+	 * ghost interface, and we can not detect it unless we set it here
+	 * to WACOM_DEVICETYPE_PAD or WACOM_DEVICETYPE_TOUCH.
+	 */
+	if (features->type == BAMBOO_PEN &&
+	    features->pktlen == WACOM_PKGLEN_BBTOUCH3)
+		features->device_type |= WACOM_DEVICETYPE_PAD;
+
+	/*
 	 * Raw Wacom-mode pen and touch events both come from interface
 	 * 0, whose HID descriptor has an application usage of 0xFF0D
 	 * (i.e., WACOM_VENDORDEFINED_PEN). We route pen packets back
@@ -3438,6 +3449,10 @@ static const struct wacom_features wacom
 	{ "Wacom Intuos PT M 2", 21600, 13500, 2047, 63,
 	  INTUOSHT2, WACOM_INTUOS_RES, WACOM_INTUOS_RES, .touch_max = 16,
 	  .check_for_hid_type = true, .hid_type = HID_TYPE_USBNONE };
+static const struct wacom_features wacom_features_0x343 =
+	{ "Wacom DTK1651", 34616, 19559, 1023, 0,
+	  DTUS, WACOM_INTUOS_RES, WACOM_INTUOS_RES, 4,
+	  WACOM_DTU_OFFSET, WACOM_DTU_OFFSET };
 
 static const struct wacom_features wacom_features_HID_ANY_ID =
 	{ "Wacom HID", .type = HID_GENERIC };
@@ -3603,6 +3618,7 @@ const struct hid_device_id wacom_ids[] =
 	{ USB_DEVICE_WACOM(0x33C) },
 	{ USB_DEVICE_WACOM(0x33D) },
 	{ USB_DEVICE_WACOM(0x33E) },
+	{ USB_DEVICE_WACOM(0x343) },
 	{ USB_DEVICE_WACOM(0x4001) },
 	{ USB_DEVICE_WACOM(0x4004) },
 	{ USB_DEVICE_WACOM(0x5000) },
--- zfcpdump-kernel-4.4.orig/drivers/hid/wacom_wac.h
+++ zfcpdump-kernel-4.4/drivers/hid/wacom_wac.h
@@ -83,6 +83,12 @@
 #define WACOM_DEVICETYPE_WL_MONITOR     0x0008
 
 #define WACOM_VENDORDEFINED_PEN		0xff0d0001
+#define WACOM_G9_PAGE			0xff090000
+#define WACOM_G9_DIGITIZER		(WACOM_G9_PAGE | 0x02)
+#define WACOM_G9_TOUCHSCREEN		(WACOM_G9_PAGE | 0x11)
+#define WACOM_G11_PAGE			0xff110000
+#define WACOM_G11_DIGITIZER		(WACOM_G11_PAGE | 0x02)
+#define WACOM_G11_TOUCHSCREEN		(WACOM_G11_PAGE | 0x11)
 
 #define WACOM_PEN_FIELD(f)	(((f)->logical == HID_DG_STYLUS) || \
 				 ((f)->physical == HID_DG_STYLUS) || \
@@ -237,6 +243,8 @@ struct wacom_wac {
 	int ps_connected;
 	u8 bt_features;
 	u8 bt_high_speed;
+	int mode_report;
+	int mode_value;
 	struct hid_data hid_data;
 };
 
--- zfcpdump-kernel-4.4.orig/drivers/hv/channel.c
+++ zfcpdump-kernel-4.4/drivers/hv/channel.c
@@ -28,6 +28,7 @@
 #include <linux/module.h>
 #include <linux/hyperv.h>
 #include <linux/uio.h>
+#include <linux/interrupt.h>
 
 #include "hyperv_vmbus.h"
 
@@ -218,6 +219,21 @@ error0:
 }
 EXPORT_SYMBOL_GPL(vmbus_open);
 
+/* Used for Hyper-V Socket: a guest client's connect() to the host */
+int vmbus_send_tl_connect_request(const uuid_le *shv_guest_servie_id,
+				  const uuid_le *shv_host_servie_id)
+{
+	struct vmbus_channel_tl_connect_request conn_msg;
+
+	memset(&conn_msg, 0, sizeof(conn_msg));
+	conn_msg.header.msgtype = CHANNELMSG_TL_CONNECT_REQUEST;
+	conn_msg.guest_endpoint_id = *shv_guest_servie_id;
+	conn_msg.host_service_id = *shv_host_servie_id;
+
+	return vmbus_post_msg(&conn_msg, sizeof(conn_msg));
+}
+EXPORT_SYMBOL_GPL(vmbus_send_tl_connect_request);
+
 /*
  * create_gpadl_header - Creates a gpadl for the specified buffer
  */
@@ -496,8 +512,33 @@ static void reset_channel_cb(void *arg)
 static int vmbus_close_internal(struct vmbus_channel *channel)
 {
 	struct vmbus_channel_close_channel *msg;
+	struct tasklet_struct *tasklet;
 	int ret;
 
+	/*
+	 * process_chn_event(), running in the tasklet, can race
+	 * with vmbus_close_internal() in the case of SMP guest, e.g., when
+	 * the former is accessing channel->inbound.ring_buffer, the latter
+	 * could be freeing the ring_buffer pages.
+	 *
+	 * To resolve the race, we can serialize them by disabling the
+	 * tasklet when the latter is running here.
+	 */
+	tasklet = hv_context.event_dpc[channel->target_cpu];
+	tasklet_disable(tasklet);
+
+	/*
+	 * In case a device driver's probe() fails (e.g.,
+	 * util_probe() -> vmbus_open() returns -ENOMEM) and the device is
+	 * rescinded later (e.g., we dynamically disble an Integrated Service
+	 * in Hyper-V Manager), the driver's remove() invokes vmbus_close():
+	 * here we should skip most of the below cleanup work.
+	 */
+	if (channel->state != CHANNEL_OPENED_STATE) {
+		ret = -EINVAL;
+		goto out;
+	}
+
 	channel->state = CHANNEL_OPEN_STATE;
 	channel->sc_creation_callback = NULL;
 	/* Stop callback and cancel the timer asap */
@@ -525,7 +566,7 @@ static int vmbus_close_internal(struct v
 		 * If we failed to post the close msg,
 		 * it is perhaps better to leak memory.
 		 */
-		return ret;
+		goto out;
 	}
 
 	/* Tear down the gpadl for the channel's ring buffer */
@@ -538,7 +579,7 @@ static int vmbus_close_internal(struct v
 			 * If we failed to teardown gpadl,
 			 * it is perhaps better to leak memory.
 			 */
-			return ret;
+			goto out;
 		}
 	}
 
@@ -549,12 +590,9 @@ static int vmbus_close_internal(struct v
 	free_pages((unsigned long)channel->ringbuffer_pages,
 		get_order(channel->ringbuffer_pagecount * PAGE_SIZE));
 
-	/*
-	 * If the channel has been rescinded; process device removal.
-	 */
-	if (channel->rescind)
-		hv_process_channel_removal(channel,
-					   channel->offermsg.child_relid);
+out:
+	tasklet_enable(tasklet);
+
 	return ret;
 }
 
@@ -601,6 +639,7 @@ int vmbus_sendpacket_ctl(struct vmbus_ch
 	u64 aligned_data = 0;
 	int ret;
 	bool signal = false;
+	bool lock = channel->acquire_ring_lock;
 	int num_vecs = ((bufferlen != 0) ? 3 : 1);
 
 
@@ -620,7 +659,7 @@ int vmbus_sendpacket_ctl(struct vmbus_ch
 	bufferlist[2].iov_len = (packetlen_aligned - packetlen);
 
 	ret = hv_ringbuffer_write(&channel->outbound, bufferlist, num_vecs,
-				  &signal);
+				  &signal, lock);
 
 	/*
 	 * Signalling the host is conditional on many factors:
@@ -630,11 +669,24 @@ int vmbus_sendpacket_ctl(struct vmbus_ch
 	 *    on the ring. We will not signal if more data is
 	 *    to be placed.
 	 *
+	 * Based on the channel signal state, we will decide
+	 * which signaling policy will be applied.
+	 *
 	 * If we cannot write to the ring-buffer; signal the host
 	 * even if we may not have written anything. This is a rare
 	 * enough condition that it should not matter.
+	 * NOTE: in this case, the hvsock channel is an exception, because
+	 * it looks the host side's hvsock implementation has a throttling
+	 * mechanism which can hurt the performance otherwise.
 	 */
-	if (((ret == 0) && kick_q && signal) || (ret))
+
+	if (channel->signal_policy)
+		signal = true;
+	else
+		kick_q = true;
+
+	if (((ret == 0) && kick_q && signal) ||
+	    (ret && !is_hvsock_channel(channel)))
 		vmbus_setevent(channel);
 
 	return ret;
@@ -687,6 +739,7 @@ int vmbus_sendpacket_pagebuffer_ctl(stru
 	struct kvec bufferlist[3];
 	u64 aligned_data = 0;
 	bool signal = false;
+	bool lock = channel->acquire_ring_lock;
 
 	if (pagecount > MAX_PAGE_BUFFER_COUNT)
 		return -EINVAL;
@@ -723,7 +776,8 @@ int vmbus_sendpacket_pagebuffer_ctl(stru
 	bufferlist[2].iov_base = &aligned_data;
 	bufferlist[2].iov_len = (packetlen_aligned - packetlen);
 
-	ret = hv_ringbuffer_write(&channel->outbound, bufferlist, 3, &signal);
+	ret = hv_ringbuffer_write(&channel->outbound, bufferlist, 3,
+				  &signal, lock);
 
 	/*
 	 * Signalling the host is conditional on many factors:
@@ -733,10 +787,19 @@ int vmbus_sendpacket_pagebuffer_ctl(stru
 	 *    on the ring. We will not signal if more data is
 	 *    to be placed.
 	 *
+	 * Based on the channel signal state, we will decide
+	 * which signaling policy will be applied.
+	 *
 	 * If we cannot write to the ring-buffer; signal the host
 	 * even if we may not have written anything. This is a rare
 	 * enough condition that it should not matter.
 	 */
+
+	if (channel->signal_policy)
+		signal = true;
+	else
+		kick_q = true;
+
 	if (((ret == 0) && kick_q && signal) || (ret))
 		vmbus_setevent(channel);
 
@@ -777,6 +840,7 @@ int vmbus_sendpacket_mpb_desc(struct vmb
 	struct kvec bufferlist[3];
 	u64 aligned_data = 0;
 	bool signal = false;
+	bool lock = channel->acquire_ring_lock;
 
 	packetlen = desc_size + bufferlen;
 	packetlen_aligned = ALIGN(packetlen, sizeof(u64));
@@ -796,7 +860,8 @@ int vmbus_sendpacket_mpb_desc(struct vmb
 	bufferlist[2].iov_base = &aligned_data;
 	bufferlist[2].iov_len = (packetlen_aligned - packetlen);
 
-	ret = hv_ringbuffer_write(&channel->outbound, bufferlist, 3, &signal);
+	ret = hv_ringbuffer_write(&channel->outbound, bufferlist, 3,
+				  &signal, lock);
 
 	if (ret == 0 && signal)
 		vmbus_setevent(channel);
@@ -821,6 +886,7 @@ int vmbus_sendpacket_multipagebuffer(str
 	struct kvec bufferlist[3];
 	u64 aligned_data = 0;
 	bool signal = false;
+	bool lock = channel->acquire_ring_lock;
 	u32 pfncount = NUM_PAGES_SPANNED(multi_pagebuffer->offset,
 					 multi_pagebuffer->len);
 
@@ -859,7 +925,8 @@ int vmbus_sendpacket_multipagebuffer(str
 	bufferlist[2].iov_base = &aligned_data;
 	bufferlist[2].iov_len = (packetlen_aligned - packetlen);
 
-	ret = hv_ringbuffer_write(&channel->outbound, bufferlist, 3, &signal);
+	ret = hv_ringbuffer_write(&channel->outbound, bufferlist, 3,
+				  &signal, lock);
 
 	if (ret == 0 && signal)
 		vmbus_setevent(channel);
@@ -881,46 +948,29 @@ EXPORT_SYMBOL_GPL(vmbus_sendpacket_multi
  *
  * Mainly used by Hyper-V drivers.
  */
-int vmbus_recvpacket(struct vmbus_channel *channel, void *buffer,
-			u32 bufferlen, u32 *buffer_actual_len, u64 *requestid)
+static inline int
+__vmbus_recvpacket(struct vmbus_channel *channel, void *buffer,
+		   u32 bufferlen, u32 *buffer_actual_len, u64 *requestid,
+		   bool raw)
 {
-	struct vmpacket_descriptor desc;
-	u32 packetlen;
-	u32 userlen;
 	int ret;
 	bool signal = false;
 
-	*buffer_actual_len = 0;
-	*requestid = 0;
-
-
-	ret = hv_ringbuffer_peek(&channel->inbound, &desc,
-			     sizeof(struct vmpacket_descriptor));
-	if (ret != 0)
-		return 0;
-
-	packetlen = desc.len8 << 3;
-	userlen = packetlen - (desc.offset8 << 3);
-
-	*buffer_actual_len = userlen;
-
-	if (userlen > bufferlen) {
-
-		pr_err("Buffer too small - got %d needs %d\n",
-			   bufferlen, userlen);
-		return -ETOOSMALL;
-	}
-
-	*requestid = desc.trans_id;
-
-	/* Copy over the packet to the user buffer */
-	ret = hv_ringbuffer_read(&channel->inbound, buffer, userlen,
-			     (desc.offset8 << 3), &signal);
+	ret = hv_ringbuffer_read(&channel->inbound, buffer, bufferlen,
+				 buffer_actual_len, requestid, &signal, raw);
 
 	if (signal)
 		vmbus_setevent(channel);
 
-	return 0;
+	return ret;
+}
+
+int vmbus_recvpacket(struct vmbus_channel *channel, void *buffer,
+		     u32 bufferlen, u32 *buffer_actual_len,
+		     u64 *requestid)
+{
+	return __vmbus_recvpacket(channel, buffer, bufferlen,
+				  buffer_actual_len, requestid, false);
 }
 EXPORT_SYMBOL(vmbus_recvpacket);
 
@@ -931,37 +981,7 @@ int vmbus_recvpacket_raw(struct vmbus_ch
 			      u32 bufferlen, u32 *buffer_actual_len,
 			      u64 *requestid)
 {
-	struct vmpacket_descriptor desc;
-	u32 packetlen;
-	int ret;
-	bool signal = false;
-
-	*buffer_actual_len = 0;
-	*requestid = 0;
-
-
-	ret = hv_ringbuffer_peek(&channel->inbound, &desc,
-			     sizeof(struct vmpacket_descriptor));
-	if (ret != 0)
-		return 0;
-
-
-	packetlen = desc.len8 << 3;
-
-	*buffer_actual_len = packetlen;
-
-	if (packetlen > bufferlen)
-		return -ENOBUFS;
-
-	*requestid = desc.trans_id;
-
-	/* Copy over the entire packet to the user buffer */
-	ret = hv_ringbuffer_read(&channel->inbound, buffer, packetlen, 0,
-				 &signal);
-
-	if (signal)
-		vmbus_setevent(channel);
-
-	return ret;
+	return __vmbus_recvpacket(channel, buffer, bufferlen,
+				  buffer_actual_len, requestid, true);
 }
 EXPORT_SYMBOL_GPL(vmbus_recvpacket_raw);
--- zfcpdump-kernel-4.4.orig/drivers/hv/channel_mgmt.c
+++ zfcpdump-kernel-4.4/drivers/hv/channel_mgmt.c
@@ -28,12 +28,127 @@
 #include <linux/list.h>
 #include <linux/module.h>
 #include <linux/completion.h>
+#include <linux/delay.h>
 #include <linux/hyperv.h>
 
 #include "hyperv_vmbus.h"
 
-static void init_vp_index(struct vmbus_channel *channel,
-			  const uuid_le *type_guid);
+static void init_vp_index(struct vmbus_channel *channel, u16 dev_type);
+
+static const struct vmbus_device vmbus_devs[] = {
+	/* IDE */
+	{ .dev_type = HV_IDE,
+	  HV_IDE_GUID,
+	  .perf_device = true,
+	},
+
+	/* SCSI */
+	{ .dev_type = HV_SCSI,
+	  HV_SCSI_GUID,
+	  .perf_device = true,
+	},
+
+	/* Fibre Channel */
+	{ .dev_type = HV_FC,
+	  HV_SYNTHFC_GUID,
+	  .perf_device = true,
+	},
+
+	/* Synthetic NIC */
+	{ .dev_type = HV_NIC,
+	  HV_NIC_GUID,
+	  .perf_device = true,
+	},
+
+	/* Network Direct */
+	{ .dev_type = HV_ND,
+	  HV_ND_GUID,
+	  .perf_device = true,
+	},
+
+	/* PCIE */
+	{ .dev_type = HV_PCIE,
+	  HV_PCIE_GUID,
+	  .perf_device = true,
+	},
+
+	/* Synthetic Frame Buffer */
+	{ .dev_type = HV_FB,
+	  HV_SYNTHVID_GUID,
+	  .perf_device = false,
+	},
+
+	/* Synthetic Keyboard */
+	{ .dev_type = HV_KBD,
+	  HV_KBD_GUID,
+	  .perf_device = false,
+	},
+
+	/* Synthetic MOUSE */
+	{ .dev_type = HV_MOUSE,
+	  HV_MOUSE_GUID,
+	  .perf_device = false,
+	},
+
+	/* KVP */
+	{ .dev_type = HV_KVP,
+	  HV_KVP_GUID,
+	  .perf_device = false,
+	},
+
+	/* Time Synch */
+	{ .dev_type = HV_TS,
+	  HV_TS_GUID,
+	  .perf_device = false,
+	},
+
+	/* Heartbeat */
+	{ .dev_type = HV_HB,
+	  HV_HEART_BEAT_GUID,
+	  .perf_device = false,
+	},
+
+	/* Shutdown */
+	{ .dev_type = HV_SHUTDOWN,
+	  HV_SHUTDOWN_GUID,
+	  .perf_device = false,
+	},
+
+	/* File copy */
+	{ .dev_type = HV_FCOPY,
+	  HV_FCOPY_GUID,
+	  .perf_device = false,
+	},
+
+	/* Backup */
+	{ .dev_type = HV_BACKUP,
+	  HV_VSS_GUID,
+	  .perf_device = false,
+	},
+
+	/* Dynamic Memory */
+	{ .dev_type = HV_DM,
+	  HV_DM_GUID,
+	  .perf_device = false,
+	},
+
+	/* Unknown GUID */
+	{ .dev_type = HV_UNKOWN,
+	  .perf_device = false,
+	},
+};
+
+static u16 hv_get_dev_type(const uuid_le *guid)
+{
+	u16 i;
+
+	for (i = HV_IDE; i < HV_UNKOWN; i++) {
+		if (!uuid_le_cmp(*guid, vmbus_devs[i].guid))
+			return i;
+	}
+	pr_info("Unknown GUID: %pUl\n", guid);
+	return i;
+}
 
 /**
  * vmbus_prep_negotiate_resp() - Create default response for Hyper-V Negotiate message
@@ -144,6 +259,7 @@ static struct vmbus_channel *alloc_chann
 		return NULL;
 
 	channel->id = atomic_inc_return(&chan_num);
+	channel->acquire_ring_lock = true;
 	spin_lock_init(&channel->inbound_lock);
 	spin_lock_init(&channel->lock);
 
@@ -177,19 +293,25 @@ static void percpu_channel_deq(void *arg
 }
 
 
-void hv_process_channel_removal(struct vmbus_channel *channel, u32 relid)
+static void vmbus_release_relid(u32 relid)
 {
 	struct vmbus_channel_relid_released msg;
-	unsigned long flags;
-	struct vmbus_channel *primary_channel;
 
 	memset(&msg, 0, sizeof(struct vmbus_channel_relid_released));
 	msg.child_relid = relid;
 	msg.header.msgtype = CHANNELMSG_RELID_RELEASED;
 	vmbus_post_msg(&msg, sizeof(struct vmbus_channel_relid_released));
+}
 
-	if (channel == NULL)
-		return;
+void hv_process_channel_removal(struct vmbus_channel *channel, u32 relid)
+{
+	unsigned long flags;
+	struct vmbus_channel *primary_channel;
+
+	vmbus_release_relid(relid);
+
+	BUG_ON(!channel->rescind);
+	BUG_ON(!mutex_is_locked(&vmbus_connection.channel_mutex));
 
 	if (channel->target_cpu != get_cpu()) {
 		put_cpu();
@@ -201,9 +323,7 @@ void hv_process_channel_removal(struct v
 	}
 
 	if (channel->primary_channel == NULL) {
-		spin_lock_irqsave(&vmbus_connection.channel_lock, flags);
 		list_del(&channel->listentry);
-		spin_unlock_irqrestore(&vmbus_connection.channel_lock, flags);
 
 		primary_channel = channel;
 	} else {
@@ -230,9 +350,7 @@ void vmbus_free_channels(void)
 
 	list_for_each_entry_safe(channel, tmp, &vmbus_connection.chn_list,
 		listentry) {
-		/* if we don't set rescind to true, vmbus_close_internal()
-		 * won't invoke hv_process_channel_removal().
-		 */
+		/* hv_process_channel_removal() needs this */
 		channel->rescind = true;
 
 		vmbus_device_unregister(channel->device_obj);
@@ -248,9 +366,11 @@ static void vmbus_process_offer(struct v
 	struct vmbus_channel *channel;
 	bool fnew = true;
 	unsigned long flags;
+	u16 dev_type;
+	int ret;
 
 	/* Make sure this is a new offer */
-	spin_lock_irqsave(&vmbus_connection.channel_lock, flags);
+	mutex_lock(&vmbus_connection.channel_mutex);
 
 	list_for_each_entry(channel, &vmbus_connection.chn_list, listentry) {
 		if (!uuid_le_cmp(channel->offermsg.offer.if_type,
@@ -266,7 +386,7 @@ static void vmbus_process_offer(struct v
 		list_add_tail(&newchannel->listentry,
 			      &vmbus_connection.chn_list);
 
-	spin_unlock_irqrestore(&vmbus_connection.channel_lock, flags);
+	mutex_unlock(&vmbus_connection.channel_mutex);
 
 	if (!fnew) {
 		/*
@@ -285,7 +405,9 @@ static void vmbus_process_offer(struct v
 			goto err_free_chan;
 	}
 
-	init_vp_index(newchannel, &newchannel->offermsg.offer.if_type);
+	dev_type = hv_get_dev_type(&newchannel->offermsg.offer.if_type);
+
+	init_vp_index(newchannel, dev_type);
 
 	if (newchannel->target_cpu != get_cpu()) {
 		put_cpu();
@@ -322,12 +444,17 @@ static void vmbus_process_offer(struct v
 	if (!newchannel->device_obj)
 		goto err_deq_chan;
 
+	newchannel->device_obj->device_id = dev_type;
 	/*
 	 * Add the new device to the bus. This will kick off device-driver
 	 * binding which eventually invokes the device driver's AddDevice()
 	 * method.
 	 */
-	if (vmbus_device_register(newchannel->device_obj) != 0) {
+	mutex_lock(&vmbus_connection.channel_mutex);
+	ret = vmbus_device_register(newchannel->device_obj);
+	mutex_unlock(&vmbus_connection.channel_mutex);
+
+	if (ret != 0) {
 		pr_err("unable to add child device object (relid %d)\n",
 			newchannel->offermsg.child_relid);
 		kfree(newchannel->device_obj);
@@ -336,9 +463,11 @@ static void vmbus_process_offer(struct v
 	return;
 
 err_deq_chan:
-	spin_lock_irqsave(&vmbus_connection.channel_lock, flags);
+	vmbus_release_relid(newchannel->offermsg.child_relid);
+
+	mutex_lock(&vmbus_connection.channel_mutex);
 	list_del(&newchannel->listentry);
-	spin_unlock_irqrestore(&vmbus_connection.channel_lock, flags);
+	mutex_unlock(&vmbus_connection.channel_mutex);
 
 	if (newchannel->target_cpu != get_cpu()) {
 		put_cpu();
@@ -353,31 +482,6 @@ err_free_chan:
 	free_channel(newchannel);
 }
 
-enum {
-	IDE = 0,
-	SCSI,
-	NIC,
-	ND_NIC,
-	MAX_PERF_CHN,
-};
-
-/*
- * This is an array of device_ids (device types) that are performance critical.
- * We attempt to distribute the interrupt load for these devices across
- * all available CPUs.
- */
-static const struct hv_vmbus_device_id hp_devs[] = {
-	/* IDE */
-	{ HV_IDE_GUID, },
-	/* Storage - SCSI */
-	{ HV_SCSI_GUID, },
-	/* Network */
-	{ HV_NIC_GUID, },
-	/* NetworkDirect Guest RDMA */
-	{ HV_ND_GUID, },
-};
-
-
 /*
  * We use this state to statically distribute the channel interrupt load.
  */
@@ -394,23 +498,15 @@ static int next_numa_node_id;
  * For pre-win8 hosts or non-performance critical channels we assign the
  * first CPU in the first NUMA node.
  */
-static void init_vp_index(struct vmbus_channel *channel, const uuid_le *type_guid)
+static void init_vp_index(struct vmbus_channel *channel, u16 dev_type)
 {
 	u32 cur_cpu;
-	int i;
-	bool perf_chn = false;
+	bool perf_chn = vmbus_devs[dev_type].perf_device;
 	struct vmbus_channel *primary = channel->primary_channel;
 	int next_node;
 	struct cpumask available_mask;
 	struct cpumask *alloced_mask;
 
-	for (i = IDE; i < MAX_PERF_CHN; i++) {
-		if (!memcmp(type_guid->b, hp_devs[i].guid,
-				 sizeof(uuid_le))) {
-			perf_chn = true;
-			break;
-		}
-	}
 	if ((vmbus_proto_version == VERSION_WS2008) ||
 	    (vmbus_proto_version == VERSION_WIN7) || (!perf_chn)) {
 		/*
@@ -459,6 +555,17 @@ static void init_vp_index(struct vmbus_c
 		    cpumask_of_node(primary->numa_node));
 
 	cur_cpu = -1;
+
+	/*
+	 * Normally Hyper-V host doesn't create more subchannels than there
+	 * are VCPUs on the node but it is possible when not all present VCPUs
+	 * on the node are initialized by guest. Clear the alloced_cpus_in_node
+	 * to start over.
+	 */
+	if (cpumask_equal(&primary->alloced_cpus_in_node,
+			  cpumask_of_node(primary->numa_node)))
+		cpumask_clear(&primary->alloced_cpus_in_node);
+
 	while (true) {
 		cur_cpu = cpumask_next(cur_cpu, &available_mask);
 		if (cur_cpu >= nr_cpu_ids) {
@@ -488,6 +595,60 @@ static void init_vp_index(struct vmbus_c
 	channel->target_vp = hv_context.vp_index[cur_cpu];
 }
 
+static void vmbus_wait_for_unload(void)
+{
+	int cpu;
+	void *page_addr;
+	struct hv_message *msg;
+	struct vmbus_channel_message_header *hdr;
+	u32 message_type;
+
+	/*
+	 * CHANNELMSG_UNLOAD_RESPONSE is always delivered to the CPU which was
+	 * used for initial contact or to CPU0 depending on host version. When
+	 * we're crashing on a different CPU let's hope that IRQ handler on
+	 * the cpu which receives CHANNELMSG_UNLOAD_RESPONSE is still
+	 * functional and vmbus_unload_response() will complete
+	 * vmbus_connection.unload_event. If not, the last thing we can do is
+	 * read message pages for all CPUs directly.
+	 */
+	while (1) {
+		if (completion_done(&vmbus_connection.unload_event))
+			break;
+
+		for_each_online_cpu(cpu) {
+			page_addr = hv_context.synic_message_page[cpu];
+			msg = (struct hv_message *)page_addr +
+				VMBUS_MESSAGE_SINT;
+
+			message_type = READ_ONCE(msg->header.message_type);
+			if (message_type == HVMSG_NONE)
+				continue;
+
+			hdr = (struct vmbus_channel_message_header *)
+				msg->u.payload;
+
+			if (hdr->msgtype == CHANNELMSG_UNLOAD_RESPONSE)
+				complete(&vmbus_connection.unload_event);
+
+			vmbus_signal_eom(msg, message_type);
+		}
+
+		mdelay(10);
+	}
+
+	/*
+	 * We're crashing and already got the UNLOAD_RESPONSE, cleanup all
+	 * maybe-pending messages on all CPUs to be able to receive new
+	 * messages after we reconnect.
+	 */
+	for_each_online_cpu(cpu) {
+		page_addr = hv_context.synic_message_page[cpu];
+		msg = (struct hv_message *)page_addr + VMBUS_MESSAGE_SINT;
+		msg->header.message_type = HVMSG_NONE;
+	}
+}
+
 /*
  * vmbus_unload_response - Handler for the unload response.
  */
@@ -500,7 +661,7 @@ static void vmbus_unload_response(struct
 	complete(&vmbus_connection.unload_event);
 }
 
-void vmbus_initiate_unload(void)
+void vmbus_initiate_unload(bool crash)
 {
 	struct vmbus_channel_message_header hdr;
 
@@ -513,7 +674,14 @@ void vmbus_initiate_unload(void)
 	hdr.msgtype = CHANNELMSG_UNLOAD;
 	vmbus_post_msg(&hdr, sizeof(struct vmbus_channel_message_header));
 
-	wait_for_completion(&vmbus_connection.unload_event);
+	/*
+	 * vmbus_initiate_unload() is also called on crash and the crash can be
+	 * happening in an interrupt context, where scheduling is impossible.
+	 */
+	if (!crash)
+		wait_for_completion(&vmbus_connection.unload_event);
+	else
+		vmbus_wait_for_unload();
 }
 
 /*
@@ -582,11 +750,17 @@ static void vmbus_onoffer_rescind(struct
 	struct device *dev;
 
 	rescind = (struct vmbus_channel_rescind_offer *)hdr;
+
+	mutex_lock(&vmbus_connection.channel_mutex);
 	channel = relid2channel(rescind->child_relid);
 
 	if (channel == NULL) {
-		hv_process_channel_removal(NULL, rescind->child_relid);
-		return;
+		/*
+		 * This is very impossible, because in
+		 * vmbus_process_offer(), we have already invoked
+		 * vmbus_release_relid() on error.
+		 */
+		goto out;
 	}
 
 	spin_lock_irqsave(&channel->lock, flags);
@@ -594,6 +768,10 @@ static void vmbus_onoffer_rescind(struct
 	spin_unlock_irqrestore(&channel->lock, flags);
 
 	if (channel->device_obj) {
+		if (channel->chn_rescind_callback) {
+			channel->chn_rescind_callback(channel);
+			goto out;
+		}
 		/*
 		 * We will have to unregister this device from the
 		 * driver core.
@@ -607,7 +785,24 @@ static void vmbus_onoffer_rescind(struct
 		hv_process_channel_removal(channel,
 			channel->offermsg.child_relid);
 	}
+
+out:
+	mutex_unlock(&vmbus_connection.channel_mutex);
+}
+
+void vmbus_hvsock_device_unregister(struct vmbus_channel *channel)
+{
+	mutex_lock(&vmbus_connection.channel_mutex);
+
+	BUG_ON(!is_hvsock_channel(channel));
+
+	channel->rescind = true;
+	vmbus_device_unregister(channel->device_obj);
+
+	mutex_unlock(&vmbus_connection.channel_mutex);
 }
+EXPORT_SYMBOL_GPL(vmbus_hvsock_device_unregister);
+
 
 /*
  * vmbus_onoffers_delivered -
@@ -811,6 +1006,10 @@ struct vmbus_channel_message_table_entry
 	{CHANNELMSG_VERSION_RESPONSE,		1, vmbus_onversion_response},
 	{CHANNELMSG_UNLOAD,			0, NULL},
 	{CHANNELMSG_UNLOAD_RESPONSE,		1, vmbus_unload_response},
+	{CHANNELMSG_18,				0, NULL},
+	{CHANNELMSG_19,				0, NULL},
+	{CHANNELMSG_20,				0, NULL},
+	{CHANNELMSG_TL_CONNECT_REQUEST,		0, NULL},
 };
 
 /*
@@ -959,3 +1158,10 @@ bool vmbus_are_subchannels_present(struc
 	return ret;
 }
 EXPORT_SYMBOL_GPL(vmbus_are_subchannels_present);
+
+void vmbus_set_chn_rescind_callback(struct vmbus_channel *channel,
+		void (*chn_rescind_cb)(struct vmbus_channel *))
+{
+	channel->chn_rescind_callback = chn_rescind_cb;
+}
+EXPORT_SYMBOL_GPL(vmbus_set_chn_rescind_callback);
--- zfcpdump-kernel-4.4.orig/drivers/hv/connection.c
+++ zfcpdump-kernel-4.4/drivers/hv/connection.c
@@ -83,9 +83,20 @@ static int vmbus_negotiate_version(struc
 	msg->interrupt_page = virt_to_phys(vmbus_connection.int_page);
 	msg->monitor_page1 = virt_to_phys(vmbus_connection.monitor_pages[0]);
 	msg->monitor_page2 = virt_to_phys(vmbus_connection.monitor_pages[1]);
+	/*
+	 * We want all channel messages to be delivered on CPU 0.
+	 * This has been the behavior pre-win8. This is not
+	 * perf issue and having all channel messages delivered on CPU 0
+	 * would be ok.
+	 * For post win8 hosts, we support receiving channel messagges on
+	 * all the CPUs. This is needed for kexec to work correctly where
+	 * the CPU attempting to connect may not be CPU 0.
+	 */
 	if (version >= VERSION_WIN8_1) {
 		msg->target_vcpu = hv_context.vp_index[get_cpu()];
 		put_cpu();
+	} else {
+		msg->target_vcpu = 0;
 	}
 
 	/*
@@ -146,7 +157,7 @@ int vmbus_connect(void)
 	spin_lock_init(&vmbus_connection.channelmsg_lock);
 
 	INIT_LIST_HEAD(&vmbus_connection.chn_list);
-	spin_lock_init(&vmbus_connection.channel_lock);
+	mutex_init(&vmbus_connection.channel_mutex);
 
 	/*
 	 * Setup the vmbus event connection for channel interrupt
@@ -233,7 +244,7 @@ void vmbus_disconnect(void)
 	/*
 	 * First send the unload request to the host.
 	 */
-	vmbus_initiate_unload();
+	vmbus_initiate_unload(false);
 
 	if (vmbus_connection.work_queue) {
 		drain_workqueue(vmbus_connection.work_queue);
@@ -282,11 +293,11 @@ struct vmbus_channel *relid2channel(u32
 {
 	struct vmbus_channel *channel;
 	struct vmbus_channel *found_channel  = NULL;
-	unsigned long flags;
 	struct list_head *cur, *tmp;
 	struct vmbus_channel *cur_sc;
 
-	spin_lock_irqsave(&vmbus_connection.channel_lock, flags);
+	BUG_ON(!mutex_is_locked(&vmbus_connection.channel_mutex));
+
 	list_for_each_entry(channel, &vmbus_connection.chn_list, listentry) {
 		if (channel->offermsg.child_relid == relid) {
 			found_channel = channel;
@@ -305,7 +316,6 @@ struct vmbus_channel *relid2channel(u32
 			}
 		}
 	}
-	spin_unlock_irqrestore(&vmbus_connection.channel_lock, flags);
 
 	return found_channel;
 }
@@ -472,7 +482,7 @@ int vmbus_post_msg(void *buffer, size_t
 /*
  * vmbus_set_event - Send an event notification to the parent
  */
-int vmbus_set_event(struct vmbus_channel *channel)
+void vmbus_set_event(struct vmbus_channel *channel)
 {
 	u32 child_relid = channel->offermsg.child_relid;
 
@@ -483,5 +493,6 @@ int vmbus_set_event(struct vmbus_channel
 			(child_relid >> 5));
 	}
 
-	return hv_signal_event(channel->sig_event);
+	hv_do_hypercall(HVCALL_SIGNAL_EVENT, channel->sig_event, NULL);
 }
+EXPORT_SYMBOL_GPL(vmbus_set_event);
--- zfcpdump-kernel-4.4.orig/drivers/hv/hv.c
+++ zfcpdump-kernel-4.4/drivers/hv/hv.c
@@ -33,6 +33,14 @@
 #include <asm/mshyperv.h>
 #include "hyperv_vmbus.h"
 
+#ifndef PKG_ABI
+/*
+ * Preserve the ability to 'make deb-pkg' since PKG_ABI is provided
+ * by the Ubuntu build rules.
+ */
+#define PKG_ABI 0
+#endif
+
 /* The one and only */
 struct hv_context hv_context = {
 	.synic_initialized	= false,
@@ -89,9 +97,9 @@ static int query_hypervisor_info(void)
 }
 
 /*
- * do_hypercall- Invoke the specified hypercall
+ * hv_do_hypercall- Invoke the specified hypercall
  */
-static u64 do_hypercall(u64 control, void *input, void *output)
+u64 hv_do_hypercall(u64 control, void *input, void *output)
 {
 	u64 input_address = (input) ? virt_to_phys(input) : 0;
 	u64 output_address = (output) ? virt_to_phys(output) : 0;
@@ -132,6 +140,7 @@ static u64 do_hypercall(u64 control, voi
 	return hv_status_lo | ((u64)hv_status_hi << 32);
 #endif /* !x86_64 */
 }
+EXPORT_SYMBOL_GPL(hv_do_hypercall);
 
 #ifdef CONFIG_X86_64
 static cycle_t read_hv_clock_tsc(struct clocksource *arg)
@@ -139,7 +148,7 @@ static cycle_t read_hv_clock_tsc(struct
 	cycle_t current_tick;
 	struct ms_hyperv_tsc_page *tsc_pg = hv_context.tsc_page;
 
-	if (tsc_pg->tsc_sequence != -1) {
+	if (tsc_pg->tsc_sequence != 0) {
 		/*
 		 * Use the tsc page to compute the value.
 		 */
@@ -161,7 +170,7 @@ static cycle_t read_hv_clock_tsc(struct
 			if (tsc_pg->tsc_sequence == sequence)
 				return current_tick;
 
-			if (tsc_pg->tsc_sequence != -1)
+			if (tsc_pg->tsc_sequence != 0)
 				continue;
 			/*
 			 * Fallback using MSR method.
@@ -192,9 +201,7 @@ int hv_init(void)
 {
 	int max_leaf;
 	union hv_x64_msr_hypercall_contents hypercall_msr;
-	union hv_x64_msr_hypercall_contents tsc_msr;
 	void *virtaddr = NULL;
-	void *va_tsc = NULL;
 
 	memset(hv_context.synic_event_page, 0, sizeof(void *) * NR_CPUS);
 	memset(hv_context.synic_message_page, 0,
@@ -205,6 +212,8 @@ int hv_init(void)
 	       sizeof(int) * NR_CPUS);
 	memset(hv_context.event_dpc, 0,
 	       sizeof(void *) * NR_CPUS);
+	memset(hv_context.msg_dpc, 0,
+	       sizeof(void *) * NR_CPUS);
 	memset(hv_context.clk_evt, 0,
 	       sizeof(void *) * NR_CPUS);
 
@@ -213,7 +222,7 @@ int hv_init(void)
 	/*
 	 * Write our OS ID.
 	 */
-	hv_context.guestid = generate_guest_id(0, LINUX_VERSION_CODE, 0);
+	hv_context.guestid = generate_guest_id(0x80 /*Canonical*/, LINUX_VERSION_CODE, PKG_ABI);
 	wrmsrl(HV_X64_MSR_GUEST_OS_ID, hv_context.guestid);
 
 	/* See if the hypercall page is already set */
@@ -240,6 +249,9 @@ int hv_init(void)
 
 #ifdef CONFIG_X86_64
 	if (ms_hyperv.features & HV_X64_MSR_REFERENCE_TSC_AVAILABLE) {
+		union hv_x64_msr_hypercall_contents tsc_msr;
+		void *va_tsc;
+
 		va_tsc = __vmalloc(PAGE_SIZE, GFP_KERNEL, PAGE_KERNEL);
 		if (!va_tsc)
 			goto cleanup;
@@ -293,8 +305,14 @@ void hv_cleanup(void)
 	 * Cleanup the TSC page based CS.
 	 */
 	if (ms_hyperv.features & HV_X64_MSR_REFERENCE_TSC_AVAILABLE) {
-		clocksource_change_rating(&hyperv_cs_tsc, 10);
-		clocksource_unregister(&hyperv_cs_tsc);
+		/*
+		 * Crash can happen in an interrupt context and unregistering
+		 * a clocksource is impossible and redundant in this case.
+		 */
+		if (!oops_in_progress) {
+			clocksource_change_rating(&hyperv_cs_tsc, 10);
+			clocksource_unregister(&hyperv_cs_tsc);
+		}
 
 		hypercall_msr.as_uint64 = 0;
 		wrmsrl(HV_X64_MSR_REFERENCE_TSC, hypercall_msr.as_uint64);
@@ -315,7 +333,7 @@ int hv_post_message(union hv_connection_
 {
 
 	struct hv_input_post_message *aligned_msg;
-	u16 status;
+	u64 status;
 
 	if (payload_size > HV_MESSAGE_PAYLOAD_BYTE_COUNT)
 		return -EMSGSIZE;
@@ -329,27 +347,10 @@ int hv_post_message(union hv_connection_
 	aligned_msg->payload_size = payload_size;
 	memcpy((void *)aligned_msg->payload, payload, payload_size);
 
-	status = do_hypercall(HVCALL_POST_MESSAGE, aligned_msg, NULL)
-		& 0xFFFF;
+	status = hv_do_hypercall(HVCALL_POST_MESSAGE, aligned_msg, NULL);
 
 	put_cpu();
-	return status;
-}
-
-
-/*
- * hv_signal_event -
- * Signal an event on the specified connection using the hypervisor event IPC.
- *
- * This involves a hypercall.
- */
-u16 hv_signal_event(void *con_id)
-{
-	u16 status;
-
-	status = (do_hypercall(HVCALL_SIGNAL_EVENT, con_id, NULL) & 0xFFFF);
-
-	return status;
+	return status & 0xFFFF;
 }
 
 static int hv_ce_set_next_event(unsigned long delta,
@@ -424,6 +425,13 @@ int hv_synic_alloc(void)
 		}
 		tasklet_init(hv_context.event_dpc[cpu], vmbus_on_event, cpu);
 
+		hv_context.msg_dpc[cpu] = kmalloc(size, GFP_ATOMIC);
+		if (hv_context.msg_dpc[cpu] == NULL) {
+			pr_err("Unable to allocate event dpc\n");
+			goto err;
+		}
+		tasklet_init(hv_context.msg_dpc[cpu], vmbus_on_msg_dpc, cpu);
+
 		hv_context.clk_evt[cpu] = kzalloc(ced_size, GFP_ATOMIC);
 		if (hv_context.clk_evt[cpu] == NULL) {
 			pr_err("Unable to allocate clock event device\n");
@@ -465,6 +473,7 @@ err:
 static void hv_synic_free_cpu(int cpu)
 {
 	kfree(hv_context.event_dpc[cpu]);
+	kfree(hv_context.msg_dpc[cpu]);
 	kfree(hv_context.clk_evt[cpu]);
 	if (hv_context.synic_event_page[cpu])
 		free_page((unsigned long)hv_context.synic_event_page[cpu]);
--- zfcpdump-kernel-4.4.orig/drivers/hv/hv_balloon.c
+++ zfcpdump-kernel-4.4/drivers/hv/hv_balloon.c
@@ -714,7 +714,7 @@ static bool pfn_covered(unsigned long st
 		 * If the pfn range we are dealing with is not in the current
 		 * "hot add block", move on.
 		 */
-		if ((start_pfn >= has->end_pfn))
+		if (start_pfn < has->start_pfn || start_pfn >= has->end_pfn)
 			continue;
 		/*
 		 * If the current hot add-request extends beyond
@@ -768,7 +768,7 @@ static unsigned long handle_pg_range(uns
 		 * If the pfn range we are dealing with is not in the current
 		 * "hot add block", move on.
 		 */
-		if ((start_pfn >= has->end_pfn))
+		if (start_pfn < has->start_pfn || start_pfn >= has->end_pfn)
 			continue;
 
 		old_covered_state = has->covered_end_pfn;
@@ -1400,6 +1400,7 @@ static void balloon_onchannelcallback(vo
 				 * This is a normal hot-add request specifying
 				 * hot-add memory.
 				 */
+				dm->host_specified_ha_region = false;
 				ha_pg_range = &ha_msg->range;
 				dm->ha_wrk.ha_page_range = *ha_pg_range;
 				dm->ha_wrk.ha_region_range.page_range = 0;
--- zfcpdump-kernel-4.4.orig/drivers/hv/hv_fcopy.c
+++ zfcpdump-kernel-4.4/drivers/hv/hv_fcopy.c
@@ -51,7 +51,6 @@ static struct {
 	struct hv_fcopy_hdr  *fcopy_msg; /* current message */
 	struct vmbus_channel *recv_channel; /* chn we got the request */
 	u64 recv_req_id; /* request ID. */
-	void *fcopy_context; /* for the channel callback */
 } fcopy_transaction;
 
 static void fcopy_respond_to_host(int error);
@@ -67,6 +66,13 @@ static struct hvutil_transport *hvt;
  */
 static int dm_reg_value;
 
+static void fcopy_poll_wrapper(void *channel)
+{
+	/* Transaction is finished, reset the state here to avoid races. */
+	fcopy_transaction.state = HVUTIL_READY;
+	hv_fcopy_onchannelcallback(channel);
+}
+
 static void fcopy_timeout_func(struct work_struct *dummy)
 {
 	/*
@@ -74,13 +80,7 @@ static void fcopy_timeout_func(struct wo
 	 * process the pending transaction.
 	 */
 	fcopy_respond_to_host(HV_E_FAIL);
-
-	/* Transaction is finished, reset the state. */
-	if (fcopy_transaction.state > HVUTIL_READY)
-		fcopy_transaction.state = HVUTIL_READY;
-
-	hv_poll_channel(fcopy_transaction.fcopy_context,
-			hv_fcopy_onchannelcallback);
+	hv_poll_channel(fcopy_transaction.recv_channel, fcopy_poll_wrapper);
 }
 
 static int fcopy_handle_handshake(u32 version)
@@ -108,9 +108,7 @@ static int fcopy_handle_handshake(u32 ve
 		return -EINVAL;
 	}
 	pr_debug("FCP: userspace daemon ver. %d registered\n", version);
-	fcopy_transaction.state = HVUTIL_READY;
-	hv_poll_channel(fcopy_transaction.fcopy_context,
-			hv_fcopy_onchannelcallback);
+	hv_poll_channel(fcopy_transaction.recv_channel, fcopy_poll_wrapper);
 	return 0;
 }
 
@@ -227,15 +225,8 @@ void hv_fcopy_onchannelcallback(void *co
 	int util_fw_version;
 	int fcopy_srv_version;
 
-	if (fcopy_transaction.state > HVUTIL_READY) {
-		/*
-		 * We will defer processing this callback once
-		 * the current transaction is complete.
-		 */
-		fcopy_transaction.fcopy_context = context;
+	if (fcopy_transaction.state > HVUTIL_READY)
 		return;
-	}
-	fcopy_transaction.fcopy_context = NULL;
 
 	vmbus_recvpacket(channel, recv_buffer, PAGE_SIZE * 2, &recvlen,
 			 &requestid);
@@ -260,7 +251,6 @@ void hv_fcopy_onchannelcallback(void *co
 		 */
 
 		fcopy_transaction.recv_len = recvlen;
-		fcopy_transaction.recv_channel = channel;
 		fcopy_transaction.recv_req_id = requestid;
 		fcopy_transaction.fcopy_msg = fcopy_msg;
 
@@ -275,7 +265,8 @@ void hv_fcopy_onchannelcallback(void *co
 		 * Send the information to the user-level daemon.
 		 */
 		schedule_work(&fcopy_send_work);
-		schedule_delayed_work(&fcopy_timeout_work, 5*HZ);
+		schedule_delayed_work(&fcopy_timeout_work,
+				      HV_UTIL_TIMEOUT * HZ);
 		return;
 	}
 	icmsghdr->icflags = ICMSGHDRFLAG_TRANSACTION | ICMSGHDRFLAG_RESPONSE;
@@ -304,9 +295,8 @@ static int fcopy_on_msg(void *msg, int l
 	if (cancel_delayed_work_sync(&fcopy_timeout_work)) {
 		fcopy_transaction.state = HVUTIL_USERSPACE_RECV;
 		fcopy_respond_to_host(*val);
-		fcopy_transaction.state = HVUTIL_READY;
-		hv_poll_channel(fcopy_transaction.fcopy_context,
-				hv_fcopy_onchannelcallback);
+		hv_poll_channel(fcopy_transaction.recv_channel,
+				fcopy_poll_wrapper);
 	}
 
 	return 0;
@@ -326,6 +316,7 @@ static void fcopy_on_reset(void)
 int hv_fcopy_init(struct hv_util_service *srv)
 {
 	recv_buffer = srv->recv_buffer;
+	fcopy_transaction.recv_channel = srv->channel;
 
 	/*
 	 * When this driver loads, the user level daemon that
--- zfcpdump-kernel-4.4.orig/drivers/hv/hv_kvp.c
+++ zfcpdump-kernel-4.4/drivers/hv/hv_kvp.c
@@ -66,7 +66,6 @@ static struct {
 	struct hv_kvp_msg  *kvp_msg; /* current message */
 	struct vmbus_channel *recv_channel; /* chn we got the request */
 	u64 recv_req_id; /* request ID. */
-	void *kvp_context; /* for the channel callback */
 } kvp_transaction;
 
 /*
@@ -79,9 +78,11 @@ static void kvp_send_key(struct work_str
 
 static void kvp_respond_to_host(struct hv_kvp_msg *msg, int error);
 static void kvp_timeout_func(struct work_struct *dummy);
+static void kvp_host_handshake_func(struct work_struct *dummy);
 static void kvp_register(int);
 
 static DECLARE_DELAYED_WORK(kvp_timeout_work, kvp_timeout_func);
+static DECLARE_DELAYED_WORK(kvp_host_handshake_work, kvp_host_handshake_func);
 static DECLARE_WORK(kvp_sendkey_work, kvp_send_key);
 
 static const char kvp_devname[] = "vmbus/hv_kvp";
@@ -94,6 +95,13 @@ static struct hvutil_transport *hvt;
  */
 #define HV_DRV_VERSION           "3.1"
 
+static void kvp_poll_wrapper(void *channel)
+{
+	/* Transaction is finished, reset the state here to avoid races. */
+	kvp_transaction.state = HVUTIL_READY;
+	hv_kvp_onchannelcallback(channel);
+}
+
 static void
 kvp_register(int reg_value)
 {
@@ -121,12 +129,12 @@ static void kvp_timeout_func(struct work
 	 */
 	kvp_respond_to_host(NULL, HV_E_FAIL);
 
-	/* Transaction is finished, reset the state. */
-	if (kvp_transaction.state > HVUTIL_READY)
-		kvp_transaction.state = HVUTIL_READY;
+	hv_poll_channel(kvp_transaction.recv_channel, kvp_poll_wrapper);
+}
 
-	hv_poll_channel(kvp_transaction.kvp_context,
-			hv_kvp_onchannelcallback);
+static void kvp_host_handshake_func(struct work_struct *dummy)
+{
+	hv_poll_channel(kvp_transaction.recv_channel, hv_kvp_onchannelcallback);
 }
 
 static int kvp_handle_handshake(struct hv_kvp_msg *msg)
@@ -153,7 +161,13 @@ static int kvp_handle_handshake(struct h
 	pr_debug("KVP: userspace daemon ver. %d registered\n",
 		 KVP_OP_REGISTER);
 	kvp_register(dm_reg_value);
-	kvp_transaction.state = HVUTIL_READY;
+
+	/*
+	 * If we're still negotiating with the host cancel the timeout
+	 * work to not poll the channel twice.
+	 */
+	cancel_delayed_work_sync(&kvp_host_handshake_work);
+	hv_poll_channel(kvp_transaction.recv_channel, kvp_poll_wrapper);
 
 	return 0;
 }
@@ -218,9 +232,7 @@ static int kvp_on_msg(void *msg, int len
 	 */
 	if (cancel_delayed_work_sync(&kvp_timeout_work)) {
 		kvp_respond_to_host(message, error);
-		kvp_transaction.state = HVUTIL_READY;
-		hv_poll_channel(kvp_transaction.kvp_context,
-				hv_kvp_onchannelcallback);
+		hv_poll_channel(kvp_transaction.recv_channel, kvp_poll_wrapper);
 	}
 
 	return 0;
@@ -595,16 +607,24 @@ void hv_kvp_onchannelcallback(void *cont
 	struct icmsg_negotiate *negop = NULL;
 	int util_fw_version;
 	int kvp_srv_version;
+	static enum {NEGO_NOT_STARTED,
+		     NEGO_IN_PROGRESS,
+		     NEGO_FINISHED} host_negotiatied = NEGO_NOT_STARTED;
 
-	if (kvp_transaction.state > HVUTIL_READY) {
+	if (host_negotiatied == NEGO_NOT_STARTED &&
+	    kvp_transaction.state < HVUTIL_READY) {
 		/*
-		 * We will defer processing this callback once
-		 * the current transaction is complete.
+		 * If userspace daemon is not connected and host is asking
+		 * us to negotiate we need to delay to not lose messages.
+		 * This is important for Failover IP setting.
 		 */
-		kvp_transaction.kvp_context = context;
+		host_negotiatied = NEGO_IN_PROGRESS;
+		schedule_delayed_work(&kvp_host_handshake_work,
+				      HV_UTIL_NEGO_TIMEOUT * HZ);
 		return;
 	}
-	kvp_transaction.kvp_context = NULL;
+	if (kvp_transaction.state > HVUTIL_READY)
+		return;
 
 	vmbus_recvpacket(channel, recv_buffer, PAGE_SIZE * 4, &recvlen,
 			 &requestid);
@@ -647,7 +667,6 @@ void hv_kvp_onchannelcallback(void *cont
 			 */
 
 			kvp_transaction.recv_len = recvlen;
-			kvp_transaction.recv_channel = channel;
 			kvp_transaction.recv_req_id = requestid;
 			kvp_transaction.kvp_msg = kvp_msg;
 
@@ -668,7 +687,8 @@ void hv_kvp_onchannelcallback(void *cont
 			 * user-mode not responding.
 			 */
 			schedule_work(&kvp_sendkey_work);
-			schedule_delayed_work(&kvp_timeout_work, 5*HZ);
+			schedule_delayed_work(&kvp_timeout_work,
+					      HV_UTIL_TIMEOUT * HZ);
 
 			return;
 
@@ -680,6 +700,8 @@ void hv_kvp_onchannelcallback(void *cont
 		vmbus_sendpacket(channel, recv_buffer,
 				       recvlen, requestid,
 				       VM_PKT_DATA_INBAND, 0);
+
+		host_negotiatied = NEGO_FINISHED;
 	}
 
 }
@@ -695,6 +717,7 @@ int
 hv_kvp_init(struct hv_util_service *srv)
 {
 	recv_buffer = srv->recv_buffer;
+	kvp_transaction.recv_channel = srv->channel;
 
 	/*
 	 * When this driver loads, the user level daemon that
@@ -715,6 +738,7 @@ hv_kvp_init(struct hv_util_service *srv)
 void hv_kvp_deinit(void)
 {
 	kvp_transaction.state = HVUTIL_DEVICE_DYING;
+	cancel_delayed_work_sync(&kvp_host_handshake_work);
 	cancel_delayed_work_sync(&kvp_timeout_work);
 	cancel_work_sync(&kvp_sendkey_work);
 	hvutil_transport_destroy(hvt);
--- zfcpdump-kernel-4.4.orig/drivers/hv/hv_snapshot.c
+++ zfcpdump-kernel-4.4/drivers/hv/hv_snapshot.c
@@ -53,7 +53,6 @@ static struct {
 	struct vmbus_channel *recv_channel; /* chn we got the request */
 	u64 recv_req_id; /* request ID. */
 	struct hv_vss_msg  *msg; /* current message */
-	void *vss_context; /* for the channel callback */
 } vss_transaction;
 
 
@@ -74,6 +73,13 @@ static void vss_timeout_func(struct work
 static DECLARE_DELAYED_WORK(vss_timeout_work, vss_timeout_func);
 static DECLARE_WORK(vss_send_op_work, vss_send_op);
 
+static void vss_poll_wrapper(void *channel)
+{
+	/* Transaction is finished, reset the state here to avoid races. */
+	vss_transaction.state = HVUTIL_READY;
+	hv_vss_onchannelcallback(channel);
+}
+
 /*
  * Callback when data is received from user mode.
  */
@@ -86,12 +92,7 @@ static void vss_timeout_func(struct work
 	pr_warn("VSS: timeout waiting for daemon to reply\n");
 	vss_respond_to_host(HV_E_FAIL);
 
-	/* Transaction is finished, reset the state. */
-	if (vss_transaction.state > HVUTIL_READY)
-		vss_transaction.state = HVUTIL_READY;
-
-	hv_poll_channel(vss_transaction.vss_context,
-			hv_vss_onchannelcallback);
+	hv_poll_channel(vss_transaction.recv_channel, vss_poll_wrapper);
 }
 
 static int vss_handle_handshake(struct hv_vss_msg *vss_msg)
@@ -112,7 +113,7 @@ static int vss_handle_handshake(struct h
 	default:
 		return -EINVAL;
 	}
-	vss_transaction.state = HVUTIL_READY;
+	hv_poll_channel(vss_transaction.recv_channel, vss_poll_wrapper);
 	pr_debug("VSS: userspace daemon ver. %d registered\n", dm_reg_value);
 	return 0;
 }
@@ -138,9 +139,8 @@ static int vss_on_msg(void *msg, int len
 		if (cancel_delayed_work_sync(&vss_timeout_work)) {
 			vss_respond_to_host(vss_msg->error);
 			/* Transaction is finished, reset the state. */
-			vss_transaction.state = HVUTIL_READY;
-			hv_poll_channel(vss_transaction.vss_context,
-					hv_vss_onchannelcallback);
+			hv_poll_channel(vss_transaction.recv_channel,
+					vss_poll_wrapper);
 		}
 	} else {
 		/* This is a spurious call! */
@@ -238,15 +238,8 @@ void hv_vss_onchannelcallback(void *cont
 	struct icmsg_hdr *icmsghdrp;
 	struct icmsg_negotiate *negop = NULL;
 
-	if (vss_transaction.state > HVUTIL_READY) {
-		/*
-		 * We will defer processing this callback once
-		 * the current transaction is complete.
-		 */
-		vss_transaction.vss_context = context;
+	if (vss_transaction.state > HVUTIL_READY)
 		return;
-	}
-	vss_transaction.vss_context = NULL;
 
 	vmbus_recvpacket(channel, recv_buffer, PAGE_SIZE * 2, &recvlen,
 			 &requestid);
@@ -270,7 +263,6 @@ void hv_vss_onchannelcallback(void *cont
 			 */
 
 			vss_transaction.recv_len = recvlen;
-			vss_transaction.recv_channel = channel;
 			vss_transaction.recv_req_id = requestid;
 			vss_transaction.msg = (struct hv_vss_msg *)vss_msg;
 
@@ -338,7 +330,13 @@ static void vss_on_reset(void)
 int
 hv_vss_init(struct hv_util_service *srv)
 {
+	if (vmbus_proto_version < VERSION_WIN8_1) {
+		pr_warn("Integration service 'Backup (volume snapshot)'"
+			" not supported on this host version.\n");
+		return -ENOTSUPP;
+	}
 	recv_buffer = srv->recv_buffer;
+	vss_transaction.recv_channel = srv->channel;
 
 	/*
 	 * When this driver loads, the user level daemon that
--- zfcpdump-kernel-4.4.orig/drivers/hv/hv_util.c
+++ zfcpdump-kernel-4.4/drivers/hv/hv_util.c
@@ -322,6 +322,7 @@ static int util_probe(struct hv_device *
 	srv->recv_buffer = kmalloc(PAGE_SIZE * 4, GFP_KERNEL);
 	if (!srv->recv_buffer)
 		return -ENOMEM;
+	srv->channel = dev->channel;
 	if (srv->util_init) {
 		ret = srv->util_init(srv);
 		if (ret) {
--- zfcpdump-kernel-4.4.orig/drivers/hv/hv_utils_transport.c
+++ zfcpdump-kernel-4.4/drivers/hv/hv_utils_transport.c
@@ -27,11 +27,9 @@ static struct list_head hvt_list = LIST_
 
 static void hvt_reset(struct hvutil_transport *hvt)
 {
-	mutex_lock(&hvt->outmsg_lock);
 	kfree(hvt->outmsg);
 	hvt->outmsg = NULL;
 	hvt->outmsg_len = 0;
-	mutex_unlock(&hvt->outmsg_lock);
 	if (hvt->on_reset)
 		hvt->on_reset();
 }
@@ -44,10 +42,17 @@ static ssize_t hvt_op_read(struct file *
 
 	hvt = container_of(file->f_op, struct hvutil_transport, fops);
 
-	if (wait_event_interruptible(hvt->outmsg_q, hvt->outmsg_len > 0))
+	if (wait_event_interruptible(hvt->outmsg_q, hvt->outmsg_len > 0 ||
+				     hvt->mode != HVUTIL_TRANSPORT_CHARDEV))
 		return -EINTR;
 
-	mutex_lock(&hvt->outmsg_lock);
+	mutex_lock(&hvt->lock);
+
+	if (hvt->mode == HVUTIL_TRANSPORT_DESTROY) {
+		ret = -EBADF;
+		goto out_unlock;
+	}
+
 	if (!hvt->outmsg) {
 		ret = -EAGAIN;
 		goto out_unlock;
@@ -68,7 +73,7 @@ static ssize_t hvt_op_read(struct file *
 	hvt->outmsg_len = 0;
 
 out_unlock:
-	mutex_unlock(&hvt->outmsg_lock);
+	mutex_unlock(&hvt->lock);
 	return ret;
 }
 
@@ -77,19 +82,22 @@ static ssize_t hvt_op_write(struct file
 {
 	struct hvutil_transport *hvt;
 	u8 *inmsg;
+	int ret;
 
 	hvt = container_of(file->f_op, struct hvutil_transport, fops);
 
-	inmsg = kzalloc(count, GFP_KERNEL);
-	if (copy_from_user(inmsg, buf, count)) {
-		kfree(inmsg);
-		return -EFAULT;
-	}
-	if (hvt->on_msg(inmsg, count))
-		return -EFAULT;
+	inmsg = memdup_user(buf, count);
+	if (IS_ERR(inmsg))
+		return PTR_ERR(inmsg);
+
+	if (hvt->mode == HVUTIL_TRANSPORT_DESTROY)
+		ret = -EBADF;
+	else
+		ret = hvt->on_msg(inmsg, count);
+
 	kfree(inmsg);
 
-	return count;
+	return ret ? ret : count;
 }
 
 static unsigned int hvt_op_poll(struct file *file, poll_table *wait)
@@ -99,6 +107,10 @@ static unsigned int hvt_op_poll(struct f
 	hvt = container_of(file->f_op, struct hvutil_transport, fops);
 
 	poll_wait(file, &hvt->outmsg_q, wait);
+
+	if (hvt->mode == HVUTIL_TRANSPORT_DESTROY)
+		return POLLERR | POLLHUP;
+
 	if (hvt->outmsg_len > 0)
 		return POLLIN | POLLRDNORM;
 
@@ -108,40 +120,68 @@ static unsigned int hvt_op_poll(struct f
 static int hvt_op_open(struct inode *inode, struct file *file)
 {
 	struct hvutil_transport *hvt;
+	int ret = 0;
+	bool issue_reset = false;
 
 	hvt = container_of(file->f_op, struct hvutil_transport, fops);
 
-	/*
-	 * Switching to CHARDEV mode. We switch bach to INIT when device
-	 * gets released.
-	 */
-	if (hvt->mode == HVUTIL_TRANSPORT_INIT)
+	mutex_lock(&hvt->lock);
+
+	if (hvt->mode == HVUTIL_TRANSPORT_DESTROY) {
+		ret = -EBADF;
+	} else if (hvt->mode == HVUTIL_TRANSPORT_INIT) {
+		/*
+		 * Switching to CHARDEV mode. We switch bach to INIT when
+		 * device gets released.
+		 */
 		hvt->mode = HVUTIL_TRANSPORT_CHARDEV;
+	}
 	else if (hvt->mode == HVUTIL_TRANSPORT_NETLINK) {
 		/*
 		 * We're switching from netlink communication to using char
 		 * device. Issue the reset first.
 		 */
-		hvt_reset(hvt);
+		issue_reset = true;
 		hvt->mode = HVUTIL_TRANSPORT_CHARDEV;
-	} else
-		return -EBUSY;
+	} else {
+		ret = -EBUSY;
+	}
 
-	return 0;
+	if (issue_reset)
+		hvt_reset(hvt);
+
+	mutex_unlock(&hvt->lock);
+
+	return ret;
+}
+
+static void hvt_transport_free(struct hvutil_transport *hvt)
+{
+	misc_deregister(&hvt->mdev);
+	kfree(hvt->outmsg);
+	kfree(hvt);
 }
 
 static int hvt_op_release(struct inode *inode, struct file *file)
 {
 	struct hvutil_transport *hvt;
+	int mode_old;
 
 	hvt = container_of(file->f_op, struct hvutil_transport, fops);
 
-	hvt->mode = HVUTIL_TRANSPORT_INIT;
+	mutex_lock(&hvt->lock);
+	mode_old = hvt->mode;
+	if (hvt->mode != HVUTIL_TRANSPORT_DESTROY)
+		hvt->mode = HVUTIL_TRANSPORT_INIT;
 	/*
 	 * Cleanup message buffers to avoid spurious messages when the daemon
 	 * connects back.
 	 */
 	hvt_reset(hvt);
+	mutex_unlock(&hvt->lock);
+
+	if (mode_old == HVUTIL_TRANSPORT_DESTROY)
+		hvt_transport_free(hvt);
 
 	return 0;
 }
@@ -168,6 +208,7 @@ static void hvt_cn_callback(struct cn_ms
 	 * Switching to NETLINK mode. Switching to CHARDEV happens when someone
 	 * opens the device.
 	 */
+	mutex_lock(&hvt->lock);
 	if (hvt->mode == HVUTIL_TRANSPORT_INIT)
 		hvt->mode = HVUTIL_TRANSPORT_NETLINK;
 
@@ -175,6 +216,7 @@ static void hvt_cn_callback(struct cn_ms
 		hvt_found->on_msg(msg->data, msg->len);
 	else
 		pr_warn("hvt_cn_callback: unexpected netlink message!\n");
+	mutex_unlock(&hvt->lock);
 }
 
 int hvutil_transport_send(struct hvutil_transport *hvt, void *msg, int len)
@@ -182,7 +224,8 @@ int hvutil_transport_send(struct hvutil_
 	struct cn_msg *cn_msg;
 	int ret = 0;
 
-	if (hvt->mode == HVUTIL_TRANSPORT_INIT) {
+	if (hvt->mode == HVUTIL_TRANSPORT_INIT ||
+	    hvt->mode == HVUTIL_TRANSPORT_DESTROY) {
 		return -EINVAL;
 	} else if (hvt->mode == HVUTIL_TRANSPORT_NETLINK) {
 		cn_msg = kzalloc(sizeof(*cn_msg) + len, GFP_ATOMIC);
@@ -197,18 +240,26 @@ int hvutil_transport_send(struct hvutil_
 		return ret;
 	}
 	/* HVUTIL_TRANSPORT_CHARDEV */
-	mutex_lock(&hvt->outmsg_lock);
+	mutex_lock(&hvt->lock);
+	if (hvt->mode != HVUTIL_TRANSPORT_CHARDEV) {
+		ret = -EINVAL;
+		goto out_unlock;
+	}
+
 	if (hvt->outmsg) {
 		/* Previous message wasn't received */
 		ret = -EFAULT;
 		goto out_unlock;
 	}
 	hvt->outmsg = kzalloc(len, GFP_KERNEL);
-	memcpy(hvt->outmsg, msg, len);
-	hvt->outmsg_len = len;
-	wake_up_interruptible(&hvt->outmsg_q);
+	if (hvt->outmsg) {
+		memcpy(hvt->outmsg, msg, len);
+		hvt->outmsg_len = len;
+		wake_up_interruptible(&hvt->outmsg_q);
+	} else
+		ret = -ENOMEM;
 out_unlock:
-	mutex_unlock(&hvt->outmsg_lock);
+	mutex_unlock(&hvt->lock);
 	return ret;
 }
 
@@ -239,7 +290,7 @@ struct hvutil_transport *hvutil_transpor
 	hvt->mdev.fops = &hvt->fops;
 
 	init_waitqueue_head(&hvt->outmsg_q);
-	mutex_init(&hvt->outmsg_lock);
+	mutex_init(&hvt->lock);
 
 	spin_lock(&hvt_list_lock);
 	list_add(&hvt->list, &hvt_list);
@@ -259,18 +310,34 @@ struct hvutil_transport *hvutil_transpor
 	return hvt;
 
 err_free_hvt:
+	spin_lock(&hvt_list_lock);
+	list_del(&hvt->list);
+	spin_unlock(&hvt_list_lock);
 	kfree(hvt);
 	return NULL;
 }
 
 void hvutil_transport_destroy(struct hvutil_transport *hvt)
 {
+	int mode_old;
+
+	mutex_lock(&hvt->lock);
+	mode_old = hvt->mode;
+	hvt->mode = HVUTIL_TRANSPORT_DESTROY;
+	wake_up_interruptible(&hvt->outmsg_q);
+	mutex_unlock(&hvt->lock);
+
+	/*
+	 * In case we were in 'chardev' mode we still have an open fd so we
+	 * have to defer freeing the device. Netlink interface can be freed
+	 * now.
+	 */
 	spin_lock(&hvt_list_lock);
 	list_del(&hvt->list);
 	spin_unlock(&hvt_list_lock);
 	if (hvt->cn_id.idx > 0 && hvt->cn_id.val > 0)
 		cn_del_callback(&hvt->cn_id);
-	misc_deregister(&hvt->mdev);
-	kfree(hvt->outmsg);
-	kfree(hvt);
+
+	if (mode_old != HVUTIL_TRANSPORT_CHARDEV)
+		hvt_transport_free(hvt);
 }
--- zfcpdump-kernel-4.4.orig/drivers/hv/hv_utils_transport.h
+++ zfcpdump-kernel-4.4/drivers/hv/hv_utils_transport.h
@@ -25,6 +25,7 @@ enum hvutil_transport_mode {
 	HVUTIL_TRANSPORT_INIT = 0,
 	HVUTIL_TRANSPORT_NETLINK,
 	HVUTIL_TRANSPORT_CHARDEV,
+	HVUTIL_TRANSPORT_DESTROY,
 };
 
 struct hvutil_transport {
@@ -38,7 +39,7 @@ struct hvutil_transport {
 	u8 *outmsg;                         /* message to the userspace */
 	int outmsg_len;                     /* its length */
 	wait_queue_head_t outmsg_q;         /* poll/read wait queue */
-	struct mutex outmsg_lock;           /* protects outmsg */
+	struct mutex lock;                  /* protects struct members */
 };
 
 struct hvutil_transport *hvutil_transport_init(const char *name,
--- zfcpdump-kernel-4.4.orig/drivers/hv/hyperv_vmbus.h
+++ zfcpdump-kernel-4.4/drivers/hv/hyperv_vmbus.h
@@ -31,6 +31,16 @@
 #include <linux/hyperv.h>
 
 /*
+ * Timeout for services such as KVP and fcopy.
+ */
+#define HV_UTIL_TIMEOUT 30
+
+/*
+ * Timeout for guest-host handshake for services.
+ */
+#define HV_UTIL_NEGO_TIMEOUT 60
+
+/*
  * The below CPUID leaves are present if VersionAndFeatures.HypervisorPresent
  * is set by CPUID(HVCPUID_VERSION_FEATURES).
  */
@@ -63,10 +73,6 @@ enum hv_cpuid_function {
 /* Define version of the synthetic interrupt controller. */
 #define HV_SYNIC_VERSION		(1)
 
-/* Define synthetic interrupt controller message constants. */
-#define HV_MESSAGE_SIZE			(256)
-#define HV_MESSAGE_PAYLOAD_BYTE_COUNT	(240)
-#define HV_MESSAGE_PAYLOAD_QWORD_COUNT	(30)
 #define HV_ANY_VP			(0xFFFFFFFF)
 
 /* Define synthetic interrupt controller flag constants. */
@@ -74,48 +80,9 @@ enum hv_cpuid_function {
 #define HV_EVENT_FLAGS_BYTE_COUNT	(256)
 #define HV_EVENT_FLAGS_DWORD_COUNT	(256 / sizeof(u32))
 
-/* Define hypervisor message types. */
-enum hv_message_type {
-	HVMSG_NONE			= 0x00000000,
-
-	/* Memory access messages. */
-	HVMSG_UNMAPPED_GPA		= 0x80000000,
-	HVMSG_GPA_INTERCEPT		= 0x80000001,
-
-	/* Timer notification messages. */
-	HVMSG_TIMER_EXPIRED			= 0x80000010,
-
-	/* Error messages. */
-	HVMSG_INVALID_VP_REGISTER_VALUE	= 0x80000020,
-	HVMSG_UNRECOVERABLE_EXCEPTION	= 0x80000021,
-	HVMSG_UNSUPPORTED_FEATURE		= 0x80000022,
-
-	/* Trace buffer complete messages. */
-	HVMSG_EVENTLOG_BUFFERCOMPLETE	= 0x80000040,
-
-	/* Platform-specific processor intercept messages. */
-	HVMSG_X64_IOPORT_INTERCEPT		= 0x80010000,
-	HVMSG_X64_MSR_INTERCEPT		= 0x80010001,
-	HVMSG_X64_CPUID_INTERCEPT		= 0x80010002,
-	HVMSG_X64_EXCEPTION_INTERCEPT	= 0x80010003,
-	HVMSG_X64_APIC_EOI			= 0x80010004,
-	HVMSG_X64_LEGACY_FP_ERROR		= 0x80010005
-};
-
-#define HV_SYNIC_STIMER_COUNT		(4)
-
 /* Define invalid partition identifier. */
 #define HV_PARTITION_ID_INVALID		((u64)0x0)
 
-/* Define port identifier type. */
-union hv_port_id {
-	u32 asu32;
-	struct {
-		u32 id:24;
-		u32 reserved:8;
-	} u ;
-};
-
 /* Define port type. */
 enum hv_port_type {
 	HVPORT_MSG	= 1,
@@ -163,27 +130,6 @@ struct hv_connection_info {
 	};
 };
 
-/* Define synthetic interrupt controller message flags. */
-union hv_message_flags {
-	u8 asu8;
-	struct {
-		u8 msg_pending:1;
-		u8 reserved:7;
-	};
-};
-
-/* Define synthetic interrupt controller message header. */
-struct hv_message_header {
-	enum hv_message_type message_type;
-	u8 payload_size;
-	union hv_message_flags message_flags;
-	u8 reserved[2];
-	union {
-		u64 sender;
-		union hv_port_id port;
-	};
-};
-
 /*
  * Timer configuration register.
  */
@@ -200,31 +146,9 @@ union hv_timer_config {
 	};
 };
 
-
-/* Define timer message payload structure. */
-struct hv_timer_message_payload {
-	u32 timer_index;
-	u32 reserved;
-	u64 expiration_time;	/* When the timer expired */
-	u64 delivery_time;	/* When the message was delivered */
-};
-
-/* Define synthetic interrupt controller message format. */
-struct hv_message {
-	struct hv_message_header header;
-	union {
-		u64 payload[HV_MESSAGE_PAYLOAD_QWORD_COUNT];
-	} u ;
-};
-
 /* Define the number of message buffers associated with each port. */
 #define HV_PORT_MESSAGE_BUFFER_COUNT	(16)
 
-/* Define the synthetic interrupt message page layout. */
-struct hv_message_page {
-	struct hv_message sint_message[HV_SYNIC_SINT_COUNT];
-};
-
 /* Define the synthetic interrupt controller event flags format. */
 union hv_synic_event_flags {
 	u8 flags8[HV_EVENT_FLAGS_BYTE_COUNT];
@@ -337,17 +261,11 @@ struct hv_monitor_page {
 	u8 rsvdz4[1984];
 };
 
-/* Declare the various hypercall operations. */
-enum hv_call_code {
-	HVCALL_POST_MESSAGE	= 0x005c,
-	HVCALL_SIGNAL_EVENT	= 0x005d,
-};
-
 /* Definition of the hv_post_message hypercall input structure. */
 struct hv_input_post_message {
 	union hv_connection_id connectionid;
 	u32 reserved;
-	enum hv_message_type message_type;
+	u32 message_type;
 	u32 payload_size;
 	u64 payload[HV_MESSAGE_PAYLOAD_QWORD_COUNT];
 };
@@ -530,10 +448,11 @@ struct hv_context {
 	u32 vp_index[NR_CPUS];
 	/*
 	 * Starting with win8, we can take channel interrupts on any CPU;
-	 * we will manage the tasklet that handles events on a per CPU
+	 * we will manage the tasklet that handles events messages on a per CPU
 	 * basis.
 	 */
 	struct tasklet_struct *event_dpc[NR_CPUS];
+	struct tasklet_struct *msg_dpc[NR_CPUS];
 	/*
 	 * To optimize the mapping of relid to channel, maintain
 	 * per-cpu list of the channels based on their CPU affinity.
@@ -582,8 +501,6 @@ extern int hv_post_message(union hv_conn
 			 enum hv_message_type message_type,
 			 void *payload, size_t payload_size);
 
-extern u16 hv_signal_event(void *con_id);
-
 extern int hv_synic_alloc(void);
 
 extern void hv_synic_free(void);
@@ -612,16 +529,11 @@ void hv_ringbuffer_cleanup(struct hv_rin
 
 int hv_ringbuffer_write(struct hv_ring_buffer_info *ring_info,
 		    struct kvec *kv_list,
-		    u32 kv_count, bool *signal);
-
-int hv_ringbuffer_peek(struct hv_ring_buffer_info *ring_info, void *buffer,
-		   u32 buflen);
-
-int hv_ringbuffer_read(struct hv_ring_buffer_info *ring_info,
-		   void *buffer,
-		   u32 buflen,
-		   u32 offset, bool *signal);
+		    u32 kv_count, bool *signal, bool lock);
 
+int hv_ringbuffer_read(struct hv_ring_buffer_info *inring_info,
+		       void *buffer, u32 buflen, u32 *buffer_actual_len,
+		       u64 *requestid, bool *signal, bool raw);
 
 void hv_ringbuffer_get_debuginfo(struct hv_ring_buffer_info *ring_info,
 			    struct hv_ring_buffer_debug_info *debug_info);
@@ -678,7 +590,7 @@ struct vmbus_connection {
 
 	/* List of channels */
 	struct list_head chn_list;
-	spinlock_t channel_lock;
+	struct mutex channel_mutex;
 
 	struct workqueue_struct *work_queue;
 };
@@ -712,6 +624,42 @@ struct vmbus_channel_message_table_entry
 extern struct vmbus_channel_message_table_entry
 	channel_message_table[CHANNELMSG_COUNT];
 
+/* Free the message slot and signal end-of-message if required */
+static inline void vmbus_signal_eom(struct hv_message *msg, u32 old_msg_type)
+{
+	/*
+	 * On crash we're reading some other CPU's message page and we need
+	 * to be careful: this other CPU may already had cleared the header
+	 * and the host may already had delivered some other message there.
+	 * In case we blindly write msg->header.message_type we're going
+	 * to lose it. We can still lose a message of the same type but
+	 * we count on the fact that there can only be one
+	 * CHANNELMSG_UNLOAD_RESPONSE and we don't care about other messages
+	 * on crash.
+	 */
+	if (cmpxchg(&msg->header.message_type, old_msg_type,
+		    HVMSG_NONE) != old_msg_type)
+		return;
+
+	/*
+	 * Make sure the write to MessageType (ie set to
+	 * HVMSG_NONE) happens before we read the
+	 * MessagePending and EOMing. Otherwise, the EOMing
+	 * will not deliver any more messages since there is
+	 * no empty slot
+	 */
+	mb();
+
+	if (msg->header.message_flags.msg_pending) {
+		/*
+		 * This will cause message queue rescan to
+		 * possibly deliver another msg from the
+		 * hypervisor
+		 */
+		wrmsrl(HV_X64_MSR_EOM, 0);
+	}
+}
+
 /* General vmbus interface */
 
 struct hv_device *vmbus_device_create(const uuid_le *type,
@@ -736,9 +684,8 @@ void vmbus_disconnect(void);
 
 int vmbus_post_msg(void *buffer, size_t buflen);
 
-int vmbus_set_event(struct vmbus_channel *channel);
-
 void vmbus_on_event(unsigned long data);
+void vmbus_on_msg_dpc(unsigned long data);
 
 int hv_kvp_init(struct hv_util_service *);
 void hv_kvp_deinit(void);
@@ -751,7 +698,7 @@ void hv_vss_onchannelcallback(void *);
 int hv_fcopy_init(struct hv_util_service *);
 void hv_fcopy_deinit(void);
 void hv_fcopy_onchannelcallback(void *);
-void vmbus_initiate_unload(void);
+void vmbus_initiate_unload(bool crash);
 
 static inline void hv_poll_channel(struct vmbus_channel *channel,
 				   void (*cb)(void *))
@@ -759,11 +706,7 @@ static inline void hv_poll_channel(struc
 	if (!channel)
 		return;
 
-	if (channel->target_cpu != smp_processor_id())
-		smp_call_function_single(channel->target_cpu,
-					 cb, channel, true);
-	else
-		cb(channel);
+	smp_call_function_single(channel->target_cpu, cb, channel, true);
 }
 
 enum hvutil_device_state {
--- zfcpdump-kernel-4.4.orig/drivers/hv/ring_buffer.c
+++ zfcpdump-kernel-4.4/drivers/hv/ring_buffer.c
@@ -33,25 +33,21 @@
 void hv_begin_read(struct hv_ring_buffer_info *rbi)
 {
 	rbi->ring_buffer->interrupt_mask = 1;
-	mb();
+	virt_mb();
 }
 
 u32 hv_end_read(struct hv_ring_buffer_info *rbi)
 {
-	u32 read;
-	u32 write;
 
 	rbi->ring_buffer->interrupt_mask = 0;
-	mb();
+	virt_mb();
 
 	/*
 	 * Now check to see if the ring buffer is still empty.
 	 * If it is not, we raced and we need to process new
 	 * incoming messages.
 	 */
-	hv_get_ringbuffer_availbytes(rbi, &read, &write);
-
-	return read;
+	return hv_get_bytes_to_read(rbi);
 }
 
 /*
@@ -72,68 +68,23 @@ u32 hv_end_read(struct hv_ring_buffer_in
 
 static bool hv_need_to_signal(u32 old_write, struct hv_ring_buffer_info *rbi)
 {
-	mb();
-	if (rbi->ring_buffer->interrupt_mask)
+	virt_mb();
+	if (READ_ONCE(rbi->ring_buffer->interrupt_mask))
 		return false;
 
 	/* check interrupt_mask before read_index */
-	rmb();
+	virt_rmb();
 	/*
 	 * This is the only case we need to signal when the
 	 * ring transitions from being empty to non-empty.
 	 */
-	if (old_write == rbi->ring_buffer->read_index)
-		return true;
-
-	return false;
-}
-
-/*
- * To optimize the flow management on the send-side,
- * when the sender is blocked because of lack of
- * sufficient space in the ring buffer, potential the
- * consumer of the ring buffer can signal the producer.
- * This is controlled by the following parameters:
- *
- * 1. pending_send_sz: This is the size in bytes that the
- *    producer is trying to send.
- * 2. The feature bit feat_pending_send_sz set to indicate if
- *    the consumer of the ring will signal when the ring
- *    state transitions from being full to a state where
- *    there is room for the producer to send the pending packet.
- */
-
-static bool hv_need_to_signal_on_read(u32 prev_write_sz,
-				      struct hv_ring_buffer_info *rbi)
-{
-	u32 cur_write_sz;
-	u32 r_size;
-	u32 write_loc = rbi->ring_buffer->write_index;
-	u32 read_loc = rbi->ring_buffer->read_index;
-	u32 pending_sz = rbi->ring_buffer->pending_send_sz;
-
-	/*
-	 * If the other end is not blocked on write don't bother.
-	 */
-	if (pending_sz == 0)
-		return false;
-
-	r_size = rbi->ring_datasize;
-	cur_write_sz = write_loc >= read_loc ? r_size - (write_loc - read_loc) :
-			read_loc - write_loc;
-
-	if ((prev_write_sz < pending_sz) && (cur_write_sz >= pending_sz))
+	if (old_write == READ_ONCE(rbi->ring_buffer->read_index))
 		return true;
 
 	return false;
 }
 
-/*
- * hv_get_next_write_location()
- *
- * Get the next write location for the specified ring buffer
- *
- */
+/* Get the next write location for the specified ring buffer. */
 static inline u32
 hv_get_next_write_location(struct hv_ring_buffer_info *ring_info)
 {
@@ -142,12 +93,7 @@ hv_get_next_write_location(struct hv_rin
 	return next;
 }
 
-/*
- * hv_set_next_write_location()
- *
- * Set the next write location for the specified ring buffer
- *
- */
+/* Set the next write location for the specified ring buffer. */
 static inline void
 hv_set_next_write_location(struct hv_ring_buffer_info *ring_info,
 		     u32 next_write_location)
@@ -155,11 +101,7 @@ hv_set_next_write_location(struct hv_rin
 	ring_info->ring_buffer->write_index = next_write_location;
 }
 
-/*
- * hv_get_next_read_location()
- *
- * Get the next read location for the specified ring buffer
- */
+/* Get the next read location for the specified ring buffer. */
 static inline u32
 hv_get_next_read_location(struct hv_ring_buffer_info *ring_info)
 {
@@ -169,10 +111,8 @@ hv_get_next_read_location(struct hv_ring
 }
 
 /*
- * hv_get_next_readlocation_withoffset()
- *
  * Get the next read location + offset for the specified ring buffer.
- * This allows the caller to skip
+ * This allows the caller to skip.
  */
 static inline u32
 hv_get_next_readlocation_withoffset(struct hv_ring_buffer_info *ring_info,
@@ -186,53 +126,23 @@ hv_get_next_readlocation_withoffset(stru
 	return next;
 }
 
-/*
- *
- * hv_set_next_read_location()
- *
- * Set the next read location for the specified ring buffer
- *
- */
+/* Set the next read location for the specified ring buffer. */
 static inline void
 hv_set_next_read_location(struct hv_ring_buffer_info *ring_info,
 		    u32 next_read_location)
 {
 	ring_info->ring_buffer->read_index = next_read_location;
+	ring_info->priv_read_index = next_read_location;
 }
 
-
-/*
- *
- * hv_get_ring_buffer()
- *
- * Get the start of the ring buffer
- */
-static inline void *
-hv_get_ring_buffer(struct hv_ring_buffer_info *ring_info)
-{
-	return (void *)ring_info->ring_buffer->buffer;
-}
-
-
-/*
- *
- * hv_get_ring_buffersize()
- *
- * Get the size of the ring buffer
- */
+/* Get the size of the ring buffer. */
 static inline u32
 hv_get_ring_buffersize(struct hv_ring_buffer_info *ring_info)
 {
 	return ring_info->ring_datasize;
 }
 
-/*
- *
- * hv_get_ring_bufferindices()
- *
- * Get the read and write indices as u64 of the specified ring buffer
- *
- */
+/* Get the read and write indices as u64 of the specified ring buffer. */
 static inline u64
 hv_get_ring_bufferindices(struct hv_ring_buffer_info *ring_info)
 {
@@ -240,12 +150,8 @@ hv_get_ring_bufferindices(struct hv_ring
 }
 
 /*
- *
- * hv_copyfrom_ringbuffer()
- *
  * Helper routine to copy to source from ring buffer.
  * Assume there is enough room. Handles wrap-around in src case only!!
- *
  */
 static u32 hv_copyfrom_ringbuffer(
 	struct hv_ring_buffer_info	*ring_info,
@@ -277,12 +183,8 @@ static u32 hv_copyfrom_ringbuffer(
 
 
 /*
- *
- * hv_copyto_ringbuffer()
- *
  * Helper routine to copy from source to ring buffer.
  * Assume there is enough room. Handles wrap-around in dest case only!!
- *
  */
 static u32 hv_copyto_ringbuffer(
 	struct hv_ring_buffer_info	*ring_info,
@@ -308,13 +210,7 @@ static u32 hv_copyto_ringbuffer(
 	return start_write_offset;
 }
 
-/*
- *
- * hv_ringbuffer_get_debuginfo()
- *
- * Get various debug metrics for the specified ring buffer
- *
- */
+/* Get various debug metrics for the specified ring buffer. */
 void hv_ringbuffer_get_debuginfo(struct hv_ring_buffer_info *ring_info,
 			    struct hv_ring_buffer_debug_info *debug_info)
 {
@@ -337,13 +233,7 @@ void hv_ringbuffer_get_debuginfo(struct
 	}
 }
 
-/*
- *
- * hv_ringbuffer_init()
- *
- *Initialize the ring buffer
- *
- */
+/* Initialize the ring buffer. */
 int hv_ringbuffer_init(struct hv_ring_buffer_info *ring_info,
 		   void *buffer, u32 buflen)
 {
@@ -356,9 +246,7 @@ int hv_ringbuffer_init(struct hv_ring_bu
 	ring_info->ring_buffer->read_index =
 		ring_info->ring_buffer->write_index = 0;
 
-	/*
-	 * Set the feature bit for enabling flow control.
-	 */
+	/* Set the feature bit for enabling flow control. */
 	ring_info->ring_buffer->feature_bits.value = 1;
 
 	ring_info->ring_size = buflen;
@@ -369,54 +257,42 @@ int hv_ringbuffer_init(struct hv_ring_bu
 	return 0;
 }
 
-/*
- *
- * hv_ringbuffer_cleanup()
- *
- * Cleanup the ring buffer
- *
- */
+/* Cleanup the ring buffer. */
 void hv_ringbuffer_cleanup(struct hv_ring_buffer_info *ring_info)
 {
 }
 
-/*
- *
- * hv_ringbuffer_write()
- *
- * Write to the ring buffer
- *
- */
+/* Write to the ring buffer. */
 int hv_ringbuffer_write(struct hv_ring_buffer_info *outring_info,
-		    struct kvec *kv_list, u32 kv_count, bool *signal)
+		    struct kvec *kv_list, u32 kv_count, bool *signal, bool lock)
 {
 	int i = 0;
 	u32 bytes_avail_towrite;
-	u32 bytes_avail_toread;
 	u32 totalbytes_towrite = 0;
 
 	u32 next_write_location;
 	u32 old_write;
 	u64 prev_indices = 0;
-	unsigned long flags;
+	unsigned long flags = 0;
 
 	for (i = 0; i < kv_count; i++)
 		totalbytes_towrite += kv_list[i].iov_len;
 
 	totalbytes_towrite += sizeof(u64);
 
-	spin_lock_irqsave(&outring_info->ring_lock, flags);
-
-	hv_get_ringbuffer_availbytes(outring_info,
-				&bytes_avail_toread,
-				&bytes_avail_towrite);
+	if (lock)
+		spin_lock_irqsave(&outring_info->ring_lock, flags);
 
+	bytes_avail_towrite = hv_get_bytes_to_write(outring_info);
 
-	/* If there is only room for the packet, assume it is full. */
-	/* Otherwise, the next time around, we think the ring buffer */
-	/* is empty since the read index == write index */
+	/*
+	 * If there is only room for the packet, assume it is full.
+	 * Otherwise, the next time around, we think the ring buffer
+	 * is empty since the read index == write index.
+	 */
 	if (bytes_avail_towrite <= totalbytes_towrite) {
-		spin_unlock_irqrestore(&outring_info->ring_lock, flags);
+		if (lock)
+			spin_unlock_irqrestore(&outring_info->ring_lock, flags);
 		return -EAGAIN;
 	}
 
@@ -441,100 +317,70 @@ int hv_ringbuffer_write(struct hv_ring_b
 					     sizeof(u64));
 
 	/* Issue a full memory barrier before updating the write index */
-	mb();
+	virt_mb();
 
 	/* Now, update the write location */
 	hv_set_next_write_location(outring_info, next_write_location);
 
 
-	spin_unlock_irqrestore(&outring_info->ring_lock, flags);
+	if (lock)
+		spin_unlock_irqrestore(&outring_info->ring_lock, flags);
 
 	*signal = hv_need_to_signal(old_write, outring_info);
 	return 0;
 }
 
-
-/*
- *
- * hv_ringbuffer_peek()
- *
- * Read without advancing the read index
- *
- */
-int hv_ringbuffer_peek(struct hv_ring_buffer_info *Inring_info,
-		   void *Buffer, u32 buflen)
+int hv_ringbuffer_read(struct hv_ring_buffer_info *inring_info,
+		       void *buffer, u32 buflen, u32 *buffer_actual_len,
+		       u64 *requestid, bool *signal, bool raw)
 {
-	u32 bytes_avail_towrite;
-	u32 bytes_avail_toread;
-	u32 next_read_location = 0;
-	unsigned long flags;
-
-	spin_lock_irqsave(&Inring_info->ring_lock, flags);
-
-	hv_get_ringbuffer_availbytes(Inring_info,
-				&bytes_avail_toread,
-				&bytes_avail_towrite);
-
-	/* Make sure there is something to read */
-	if (bytes_avail_toread < buflen) {
-
-		spin_unlock_irqrestore(&Inring_info->ring_lock, flags);
-
-		return -EAGAIN;
-	}
-
-	/* Convert to byte offset */
-	next_read_location = hv_get_next_read_location(Inring_info);
-
-	next_read_location = hv_copyfrom_ringbuffer(Inring_info,
-						Buffer,
-						buflen,
-						next_read_location);
-
-	spin_unlock_irqrestore(&Inring_info->ring_lock, flags);
-
-	return 0;
-}
-
-
-/*
- *
- * hv_ringbuffer_read()
- *
- * Read and advance the read index
- *
- */
-int hv_ringbuffer_read(struct hv_ring_buffer_info *inring_info, void *buffer,
-		   u32 buflen, u32 offset, bool *signal)
-{
-	u32 bytes_avail_towrite;
 	u32 bytes_avail_toread;
 	u32 next_read_location = 0;
 	u64 prev_indices = 0;
-	unsigned long flags;
+	struct vmpacket_descriptor desc;
+	u32 offset;
+	u32 packetlen;
+	int ret = 0;
 
 	if (buflen <= 0)
 		return -EINVAL;
 
-	spin_lock_irqsave(&inring_info->ring_lock, flags);
 
-	hv_get_ringbuffer_availbytes(inring_info,
-				&bytes_avail_toread,
-				&bytes_avail_towrite);
+	*buffer_actual_len = 0;
+	*requestid = 0;
 
+	bytes_avail_toread = hv_get_bytes_to_read(inring_info);
 	/* Make sure there is something to read */
-	if (bytes_avail_toread < buflen) {
-		spin_unlock_irqrestore(&inring_info->ring_lock, flags);
+	if (bytes_avail_toread < sizeof(desc)) {
+		/*
+		 * No error is set when there is even no header, drivers are
+		 * supposed to analyze buffer_actual_len.
+		 */
+		return ret;
+	}
 
+	next_read_location = hv_get_next_read_location(inring_info);
+	next_read_location = hv_copyfrom_ringbuffer(inring_info, &desc,
+						    sizeof(desc),
+						    next_read_location);
+
+	offset = raw ? 0 : (desc.offset8 << 3);
+	packetlen = (desc.len8 << 3) - offset;
+	*buffer_actual_len = packetlen;
+	*requestid = desc.trans_id;
+
+	if (bytes_avail_toread < packetlen + offset)
 		return -EAGAIN;
-	}
+
+	if (packetlen > buflen)
+		return -ENOBUFS;
 
 	next_read_location =
 		hv_get_next_readlocation_withoffset(inring_info, offset);
 
 	next_read_location = hv_copyfrom_ringbuffer(inring_info,
 						buffer,
-						buflen,
+						packetlen,
 						next_read_location);
 
 	next_read_location = hv_copyfrom_ringbuffer(inring_info,
@@ -542,17 +388,17 @@ int hv_ringbuffer_read(struct hv_ring_bu
 						sizeof(u64),
 						next_read_location);
 
-	/* Make sure all reads are done before we update the read index since */
-	/* the writer may start writing to the read area once the read index */
-	/*is updated */
-	mb();
+	/*
+	 * Make sure all reads are done before we update the read index since
+	 * the writer may start writing to the read area once the read index
+	 * is updated.
+	 */
+	virt_mb();
 
 	/* Update the read index */
 	hv_set_next_read_location(inring_info, next_read_location);
 
-	spin_unlock_irqrestore(&inring_info->ring_lock, flags);
-
-	*signal = hv_need_to_signal_on_read(bytes_avail_towrite, inring_info);
+	*signal = hv_need_to_signal_on_read(inring_info);
 
-	return 0;
+	return ret;
 }
--- zfcpdump-kernel-4.4.orig/drivers/hv/vmbus_drv.c
+++ zfcpdump-kernel-4.4/drivers/hv/vmbus_drv.c
@@ -41,13 +41,13 @@
 #include <linux/ptrace.h>
 #include <linux/screen_info.h>
 #include <linux/kdebug.h>
+#include <linux/efi.h>
+#include <linux/random.h>
 #include "hyperv_vmbus.h"
 
 static struct acpi_device  *hv_acpi_dev;
 
-static struct tasklet_struct msg_dpc;
 static struct completion probe_event;
-static int irq;
 
 
 static void hyperv_report_panic(struct pt_regs *regs)
@@ -103,7 +103,10 @@ static struct notifier_block hyperv_pani
 	.notifier_call = hyperv_panic_event,
 };
 
+static const char *fb_mmio_name = "fb_range";
+static struct resource *fb_mmio;
 struct resource *hyperv_mmio;
+DEFINE_SEMAPHORE(hyperv_mmio_lock);
 
 static int vmbus_exists(void)
 {
@@ -478,6 +481,24 @@ static ssize_t channel_vp_mapping_show(s
 }
 static DEVICE_ATTR_RO(channel_vp_mapping);
 
+static ssize_t vendor_show(struct device *dev,
+			   struct device_attribute *dev_attr,
+			   char *buf)
+{
+	struct hv_device *hv_dev = device_to_hv_device(dev);
+	return sprintf(buf, "0x%x\n", hv_dev->vendor_id);
+}
+static DEVICE_ATTR_RO(vendor);
+
+static ssize_t device_show(struct device *dev,
+			   struct device_attribute *dev_attr,
+			   char *buf)
+{
+	struct hv_device *hv_dev = device_to_hv_device(dev);
+	return sprintf(buf, "0x%x\n", hv_dev->device_id);
+}
+static DEVICE_ATTR_RO(device);
+
 /* Set up per device attributes in /sys/bus/vmbus/devices/<bus device> */
 static struct attribute *vmbus_attrs[] = {
 	&dev_attr_id.attr,
@@ -503,6 +524,8 @@ static struct attribute *vmbus_attrs[] =
 	&dev_attr_in_read_bytes_avail.attr,
 	&dev_attr_in_write_bytes_avail.attr,
 	&dev_attr_channel_vp_mapping.attr,
+	&dev_attr_vendor.attr,
+	&dev_attr_device.attr,
 	NULL,
 };
 ATTRIBUTE_GROUPS(vmbus);
@@ -531,9 +554,9 @@ static int vmbus_uevent(struct device *d
 
 static const uuid_le null_guid;
 
-static inline bool is_null_guid(const __u8 *guid)
+static inline bool is_null_guid(const uuid_le *guid)
 {
-	if (memcmp(guid, &null_guid, sizeof(uuid_le)))
+	if (uuid_le_cmp(*guid, null_guid))
 		return false;
 	return true;
 }
@@ -544,10 +567,10 @@ static inline bool is_null_guid(const __
  */
 static const struct hv_vmbus_device_id *hv_vmbus_get_id(
 					const struct hv_vmbus_device_id *id,
-					const __u8 *guid)
+					const uuid_le *guid)
 {
-	for (; !is_null_guid(id->guid); id++)
-		if (!memcmp(&id->guid, guid, sizeof(uuid_le)))
+	for (; !is_null_guid(&id->guid); id++)
+		if (!uuid_le_cmp(id->guid, *guid))
 			return id;
 
 	return NULL;
@@ -563,7 +586,11 @@ static int vmbus_match(struct device *de
 	struct hv_driver *drv = drv_to_hv_drv(driver);
 	struct hv_device *hv_dev = device_to_hv_device(device);
 
-	if (hv_vmbus_get_id(drv->id_table, hv_dev->dev_type.b))
+	/* The hv_sock driver handles all hv_sock offers. */
+	if (is_hvsock_channel(hv_dev->channel))
+		return drv->hvsock;
+
+	if (hv_vmbus_get_id(drv->id_table, &hv_dev->dev_type))
 		return 1;
 
 	return 0;
@@ -580,7 +607,7 @@ static int vmbus_probe(struct device *ch
 	struct hv_device *dev = device_to_hv_device(child_device);
 	const struct hv_vmbus_device_id *dev_id;
 
-	dev_id = hv_vmbus_get_id(drv->id_table, dev->dev_type.b);
+	dev_id = hv_vmbus_get_id(drv->id_table, &dev->dev_type);
 	if (drv->probe) {
 		ret = drv->probe(dev, dev_id);
 		if (ret != 0)
@@ -602,23 +629,11 @@ static int vmbus_remove(struct device *c
 {
 	struct hv_driver *drv;
 	struct hv_device *dev = device_to_hv_device(child_device);
-	u32 relid = dev->channel->offermsg.child_relid;
 
 	if (child_device->driver) {
 		drv = drv_to_hv_drv(child_device->driver);
 		if (drv->remove)
 			drv->remove(dev);
-		else {
-			hv_process_channel_removal(dev->channel, relid);
-			pr_err("remove not set for driver %s\n",
-				dev_name(child_device));
-		}
-	} else {
-		/*
-		 * We don't have a driver for this device; deal with the
-		 * rescind message by removing the channel.
-		 */
-		hv_process_channel_removal(dev->channel, relid);
 	}
 
 	return 0;
@@ -653,7 +668,10 @@ static void vmbus_shutdown(struct device
 static void vmbus_device_release(struct device *device)
 {
 	struct hv_device *hv_dev = device_to_hv_device(device);
+	struct vmbus_channel *channel = hv_dev->channel;
 
+	hv_process_channel_removal(channel,
+				   channel->offermsg.child_relid);
 	kfree(hv_dev);
 
 }
@@ -695,28 +713,10 @@ static void hv_process_timer_expiration(
 	if (dev->event_handler)
 		dev->event_handler(dev);
 
-	msg->header.message_type = HVMSG_NONE;
-
-	/*
-	 * Make sure the write to MessageType (ie set to
-	 * HVMSG_NONE) happens before we read the
-	 * MessagePending and EOMing. Otherwise, the EOMing
-	 * will not deliver any more messages since there is
-	 * no empty slot
-	 */
-	mb();
-
-	if (msg->header.message_flags.msg_pending) {
-		/*
-		 * This will cause message queue rescan to
-		 * possibly deliver another msg from the
-		 * hypervisor
-		 */
-		wrmsrl(HV_X64_MSR_EOM, 0);
-	}
+	vmbus_signal_eom(msg, HVMSG_TIMER_EXPIRED);
 }
 
-static void vmbus_on_msg_dpc(unsigned long data)
+void vmbus_on_msg_dpc(unsigned long data)
 {
 	int cpu = smp_processor_id();
 	void *page_addr = hv_context.synic_message_page[cpu];
@@ -725,53 +725,34 @@ static void vmbus_on_msg_dpc(unsigned lo
 	struct vmbus_channel_message_header *hdr;
 	struct vmbus_channel_message_table_entry *entry;
 	struct onmessage_work_context *ctx;
+	u32 message_type = msg->header.message_type;
 
-	while (1) {
-		if (msg->header.message_type == HVMSG_NONE)
-			/* no msg */
-			break;
-
-		hdr = (struct vmbus_channel_message_header *)msg->u.payload;
-
-		if (hdr->msgtype >= CHANNELMSG_COUNT) {
-			WARN_ONCE(1, "unknown msgtype=%d\n", hdr->msgtype);
-			goto msg_handled;
-		}
+	if (message_type == HVMSG_NONE)
+		/* no msg */
+		return;
 
-		entry = &channel_message_table[hdr->msgtype];
-		if (entry->handler_type	== VMHT_BLOCKING) {
-			ctx = kmalloc(sizeof(*ctx), GFP_ATOMIC);
-			if (ctx == NULL)
-				continue;
+	hdr = (struct vmbus_channel_message_header *)msg->u.payload;
 
-			INIT_WORK(&ctx->work, vmbus_onmessage_work);
-			memcpy(&ctx->msg, msg, sizeof(*msg));
+	if (hdr->msgtype >= CHANNELMSG_COUNT) {
+		WARN_ONCE(1, "unknown msgtype=%d\n", hdr->msgtype);
+		goto msg_handled;
+	}
 
-			queue_work(vmbus_connection.work_queue, &ctx->work);
-		} else
-			entry->message_handler(hdr);
+	entry = &channel_message_table[hdr->msgtype];
+	if (entry->handler_type	== VMHT_BLOCKING) {
+		ctx = kmalloc(sizeof(*ctx), GFP_ATOMIC);
+		if (ctx == NULL)
+			return;
+
+		INIT_WORK(&ctx->work, vmbus_onmessage_work);
+		memcpy(&ctx->msg, msg, sizeof(*msg));
+
+		queue_work(vmbus_connection.work_queue, &ctx->work);
+	} else
+		entry->message_handler(hdr);
 
 msg_handled:
-		msg->header.message_type = HVMSG_NONE;
-
-		/*
-		 * Make sure the write to MessageType (ie set to
-		 * HVMSG_NONE) happens before we read the
-		 * MessagePending and EOMing. Otherwise, the EOMing
-		 * will not deliver any more messages since there is
-		 * no empty slot
-		 */
-		mb();
-
-		if (msg->header.message_flags.msg_pending) {
-			/*
-			 * This will cause message queue rescan to
-			 * possibly deliver another msg from the
-			 * hypervisor
-			 */
-			wrmsrl(HV_X64_MSR_EOM, 0);
-		}
-	}
+	vmbus_signal_eom(msg, message_type);
 }
 
 static void vmbus_isr(void)
@@ -824,8 +805,10 @@ static void vmbus_isr(void)
 		if (msg->header.message_type == HVMSG_TIMER_EXPIRED)
 			hv_process_timer_expiration(msg, cpu);
 		else
-			tasklet_schedule(&msg_dpc);
+			tasklet_schedule(hv_context.msg_dpc[cpu]);
 	}
+
+	add_interrupt_randomness(HYPERVISOR_CALLBACK_VECTOR, 0);
 }
 
 
@@ -835,10 +818,9 @@ static void vmbus_isr(void)
  * Here, we
  *	- initialize the vmbus driver context
  *	- invoke the vmbus hv main init routine
- *	- get the irq resource
  *	- retrieve the channel offers
  */
-static int vmbus_bus_init(int irq)
+static int vmbus_bus_init(void)
 {
 	int ret;
 
@@ -849,8 +831,6 @@ static int vmbus_bus_init(int irq)
 		return ret;
 	}
 
-	tasklet_init(&msg_dpc, vmbus_on_msg_dpc, 0);
-
 	ret = bus_register(&hv_bus);
 	if (ret)
 		goto err_cleanup;
@@ -867,7 +847,7 @@ static int vmbus_bus_init(int irq)
 	on_each_cpu(hv_synic_init, NULL, 1);
 	ret = vmbus_connect();
 	if (ret)
-		goto err_alloc;
+		goto err_connect;
 
 	if (vmbus_proto_version > VERSION_WIN7)
 		cpu_hotplug_disable();
@@ -885,6 +865,8 @@ static int vmbus_bus_init(int irq)
 
 	return 0;
 
+err_connect:
+	on_each_cpu(hv_synic_cleanup, NULL, 1);
 err_alloc:
 	hv_synic_free();
 	hv_remove_vmbus_irq();
@@ -966,6 +948,7 @@ struct hv_device *vmbus_device_create(co
 	memcpy(&child_device_obj->dev_type, type, sizeof(uuid_le));
 	memcpy(&child_device_obj->dev_instance, instance,
 	       sizeof(uuid_le));
+	child_device_obj->vendor_id = 0x1414; /* MSFT vendor ID */
 
 
 	return child_device_obj;
@@ -1031,9 +1014,6 @@ static acpi_status vmbus_walk_resources(
 	struct resource **prev_res = NULL;
 
 	switch (res->type) {
-	case ACPI_RESOURCE_TYPE_IRQ:
-		irq = res->data.irq.interrupts[0];
-		return AE_OK;
 
 	/*
 	 * "Address" descriptors are for bus windows. Ignore
@@ -1075,13 +1055,28 @@ static acpi_status vmbus_walk_resources(
 	new_res->start = start;
 	new_res->end = end;
 
+	/*
+	 * If two ranges are adjacent, merge them.
+	 */
 	do {
 		if (!*old_res) {
 			*old_res = new_res;
 			break;
 		}
 
-		if ((*old_res)->end < new_res->start) {
+		if (((*old_res)->end + 1) == new_res->start) {
+			(*old_res)->end = new_res->end;
+			kfree(new_res);
+			break;
+		}
+
+		if ((*old_res)->start == new_res->end + 1) {
+			(*old_res)->start = new_res->start;
+			kfree(new_res);
+			break;
+		}
+
+		if ((*old_res)->start > new_res->end) {
 			new_res->sibling = *old_res;
 			if (prev_res)
 				(*prev_res)->sibling = new_res;
@@ -1103,6 +1098,12 @@ static int vmbus_acpi_remove(struct acpi
 	struct resource *next_res;
 
 	if (hyperv_mmio) {
+		if (fb_mmio) {
+			__release_region(hyperv_mmio, fb_mmio->start,
+					 resource_size(fb_mmio));
+			fb_mmio = NULL;
+		}
+
 		for (cur_res = hyperv_mmio; cur_res; cur_res = next_res) {
 			next_res = cur_res->sibling;
 			kfree(cur_res);
@@ -1112,6 +1113,30 @@ static int vmbus_acpi_remove(struct acpi
 	return 0;
 }
 
+static void vmbus_reserve_fb(void)
+{
+	int size;
+	/*
+	 * Make a claim for the frame buffer in the resource tree under the
+	 * first node, which will be the one below 4GB.  The length seems to
+	 * be underreported, particularly in a Generation 1 VM.  So start out
+	 * reserving a larger area and make it smaller until it succeeds.
+	 */
+
+	if (screen_info.lfb_base) {
+		if (efi_enabled(EFI_BOOT))
+			size = max_t(__u32, screen_info.lfb_size, 0x800000);
+		else
+			size = max_t(__u32, screen_info.lfb_size, 0x4000000);
+
+		for (; !fb_mmio && (size >= 0x100000); size >>= 1) {
+			fb_mmio = __request_region(hyperv_mmio,
+						   screen_info.lfb_base, size,
+						   fb_mmio_name, 0);
+		}
+	}
+}
+
 /**
  * vmbus_allocate_mmio() - Pick a memory-mapped I/O range.
  * @new:		If successful, supplied a pointer to the
@@ -1140,11 +1165,33 @@ int vmbus_allocate_mmio(struct resource
 			resource_size_t size, resource_size_t align,
 			bool fb_overlap_ok)
 {
-	struct resource *iter;
-	resource_size_t range_min, range_max, start, local_min, local_max;
+	struct resource *iter, *shadow;
+	resource_size_t range_min, range_max, start;
 	const char *dev_n = dev_name(&device_obj->device);
-	u32 fb_end = screen_info.lfb_base + (screen_info.lfb_size << 1);
-	int i;
+	int retval;
+
+	retval = -ENXIO;
+	down(&hyperv_mmio_lock);
+
+	/*
+	 * If overlaps with frame buffers are allowed, then first attempt to
+	 * make the allocation from within the reserved region.  Because it
+	 * is already reserved, no shadow allocation is necessary.
+	 */
+	if (fb_overlap_ok && fb_mmio && !(min > fb_mmio->end) &&
+	    !(max < fb_mmio->start)) {
+
+		range_min = fb_mmio->start;
+		range_max = fb_mmio->end;
+		start = (range_min + align - 1) & ~(align - 1);
+		for (; start + size - 1 <= range_max; start += align) {
+			*new = request_mem_region_exclusive(start, size, dev_n);
+			if (*new) {
+				retval = 0;
+				goto exit;
+			}
+		}
+	}
 
 	for (iter = hyperv_mmio; iter; iter = iter->sibling) {
 		if ((iter->start >= max) || (iter->end <= min))
@@ -1152,45 +1199,72 @@ int vmbus_allocate_mmio(struct resource
 
 		range_min = iter->start;
 		range_max = iter->end;
+		start = (range_min + align - 1) & ~(align - 1);
+		for (; start + size - 1 <= range_max; start += align) {
+			shadow = __request_region(iter, start, size, NULL,
+						  IORESOURCE_BUSY);
+			if (!shadow)
+				continue;
 
-		/* If this range overlaps the frame buffer, split it into
-		   two tries. */
-		for (i = 0; i < 2; i++) {
-			local_min = range_min;
-			local_max = range_max;
-			if (fb_overlap_ok || (range_min >= fb_end) ||
-			    (range_max <= screen_info.lfb_base)) {
-				i++;
-			} else {
-				if ((range_min <= screen_info.lfb_base) &&
-				    (range_max >= screen_info.lfb_base)) {
-					/*
-					 * The frame buffer is in this window,
-					 * so trim this into the part that
-					 * preceeds the frame buffer.
-					 */
-					local_max = screen_info.lfb_base - 1;
-					range_min = fb_end;
-				} else {
-					range_min = fb_end;
-					continue;
-				}
+			*new = request_mem_region_exclusive(start, size, dev_n);
+			if (*new) {
+				shadow->name = (char *)*new;
+				retval = 0;
+				goto exit;
 			}
 
-			start = (local_min + align - 1) & ~(align - 1);
-			for (; start + size - 1 <= local_max; start += align) {
-				*new = request_mem_region_exclusive(start, size,
-								    dev_n);
-				if (*new)
-					return 0;
-			}
+			__release_region(iter, start, size);
 		}
 	}
 
-	return -ENXIO;
+exit:
+	up(&hyperv_mmio_lock);
+	return retval;
 }
 EXPORT_SYMBOL_GPL(vmbus_allocate_mmio);
 
+/**
+ * vmbus_free_mmio() - Free a memory-mapped I/O range.
+ * @start:		Base address of region to release.
+ * @size:		Size of the range to be allocated
+ *
+ * This function releases anything requested by
+ * vmbus_mmio_allocate().
+ */
+void vmbus_free_mmio(resource_size_t start, resource_size_t size)
+{
+	struct resource *iter;
+
+	down(&hyperv_mmio_lock);
+	for (iter = hyperv_mmio; iter; iter = iter->sibling) {
+		if ((iter->start >= start + size) || (iter->end <= start))
+			continue;
+
+		__release_region(iter, start, size);
+	}
+	release_mem_region(start, size);
+	up(&hyperv_mmio_lock);
+
+}
+EXPORT_SYMBOL_GPL(vmbus_free_mmio);
+
+/**
+ * vmbus_cpu_number_to_vp_number() - Map CPU to VP.
+ * @cpu_number: CPU number in Linux terms
+ *
+ * This function returns the mapping between the Linux processor
+ * number and the hypervisor's virtual processor number, useful
+ * in making hypercalls and such that talk about specific
+ * processors.
+ *
+ * Return: Virtual processor number in Hyper-V terms
+ */
+int vmbus_cpu_number_to_vp_number(int cpu_number)
+{
+	return hv_context.vp_index[cpu_number];
+}
+EXPORT_SYMBOL_GPL(vmbus_cpu_number_to_vp_number);
+
 static int vmbus_acpi_add(struct acpi_device *device)
 {
 	acpi_status result;
@@ -1214,8 +1288,10 @@ static int vmbus_acpi_add(struct acpi_de
 
 		if (ACPI_FAILURE(result))
 			continue;
-		if (hyperv_mmio)
+		if (hyperv_mmio) {
+			vmbus_reserve_fb();
 			break;
+		}
 	}
 	ret_val = 0;
 
@@ -1247,7 +1323,7 @@ static void hv_kexec_handler(void)
 	int cpu;
 
 	hv_synic_clockevents_cleanup();
-	vmbus_initiate_unload();
+	vmbus_initiate_unload(false);
 	for_each_online_cpu(cpu)
 		smp_call_function_single(cpu, hv_synic_cleanup, NULL, 1);
 	hv_cleanup();
@@ -1255,7 +1331,7 @@ static void hv_kexec_handler(void)
 
 static void hv_crash_handler(struct pt_regs *regs)
 {
-	vmbus_initiate_unload();
+	vmbus_initiate_unload(true);
 	/*
 	 * In crash handler we can't schedule synic cleanup for all CPUs,
 	 * doing the cleanup for current CPU only. This should be sufficient
@@ -1275,7 +1351,7 @@ static int __init hv_acpi_init(void)
 	init_completion(&probe_event);
 
 	/*
-	 * Get irq resources first.
+	 * Get ACPI resources first.
 	 */
 	ret = acpi_bus_register_driver(&vmbus_acpi_driver);
 
@@ -1288,12 +1364,7 @@ static int __init hv_acpi_init(void)
 		goto cleanup;
 	}
 
-	if (irq <= 0) {
-		ret = -ENODEV;
-		goto cleanup;
-	}
-
-	ret = vmbus_bus_init(irq);
+	ret = vmbus_bus_init();
 	if (ret)
 		goto cleanup;
 
@@ -1318,7 +1389,8 @@ static void __exit vmbus_exit(void)
 	hv_synic_clockevents_cleanup();
 	vmbus_disconnect();
 	hv_remove_vmbus_irq();
-	tasklet_kill(&msg_dpc);
+	for_each_online_cpu(cpu)
+		tasklet_kill(hv_context.msg_dpc[cpu]);
 	vmbus_free_channels();
 	if (ms_hyperv.misc_features & HV_FEATURE_GUEST_CRASH_MSR_AVAILABLE) {
 		unregister_die_notifier(&hyperv_die_block);
--- zfcpdump-kernel-4.4.orig/drivers/hwmon/ads1015.c
+++ zfcpdump-kernel-4.4/drivers/hwmon/ads1015.c
@@ -126,7 +126,7 @@ static int ads1015_reg_to_mv(struct i2c_
 	struct ads1015_data *data = i2c_get_clientdata(client);
 	unsigned int pga = data->channel_data[channel].pga;
 	int fullscale = fullscale_table[pga];
-	const unsigned mask = data->id == ads1115 ? 0x7fff : 0x7ff0;
+	const int mask = data->id == ads1115 ? 0x7fff : 0x7ff0;
 
 	return DIV_ROUND_CLOSEST(reg * fullscale, mask);
 }
--- zfcpdump-kernel-4.4.orig/drivers/hwmon/ads7828.c
+++ zfcpdump-kernel-4.4/drivers/hwmon/ads7828.c
@@ -120,6 +120,7 @@ static int ads7828_probe(struct i2c_clie
 	unsigned int vref_mv = ADS7828_INT_VREF_MV;
 	bool diff_input = false;
 	bool ext_vref = false;
+	unsigned int regval;
 
 	data = devm_kzalloc(dev, sizeof(struct ads7828_data), GFP_KERNEL);
 	if (!data)
@@ -154,6 +155,15 @@ static int ads7828_probe(struct i2c_clie
 	if (!diff_input)
 		data->cmd_byte |= ADS7828_CMD_SD_SE;
 
+	/*
+	 * Datasheet specifies internal reference voltage is disabled by
+	 * default. The internal reference voltage needs to be enabled and
+	 * voltage needs to settle before getting valid ADC data. So perform a
+	 * dummy read to enable the internal reference voltage.
+	 */
+	if (!ext_vref)
+		regmap_read(data->regmap, data->cmd_byte, &regval);
+
 	hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name,
 							   data,
 							   ads7828_groups);
--- zfcpdump-kernel-4.4.orig/drivers/hwmon/adt7411.c
+++ zfcpdump-kernel-4.4/drivers/hwmon/adt7411.c
@@ -30,6 +30,7 @@
 
 #define ADT7411_REG_CFG1			0x18
 #define ADT7411_CFG1_START_MONITOR		(1 << 0)
+#define ADT7411_CFG1_RESERVED_BIT3		(1 << 3)
 
 #define ADT7411_REG_CFG2			0x19
 #define ADT7411_CFG2_DISABLE_AVG		(1 << 5)
@@ -296,8 +297,10 @@ static int adt7411_probe(struct i2c_clie
 	mutex_init(&data->device_lock);
 	mutex_init(&data->update_lock);
 
+	/* According to the datasheet, we must only write 1 to bit 3 */
 	ret = adt7411_modify_bit(client, ADT7411_REG_CFG1,
-				 ADT7411_CFG1_START_MONITOR, 1);
+				 ADT7411_CFG1_RESERVED_BIT3
+				 | ADT7411_CFG1_START_MONITOR, 1);
 	if (ret < 0)
 		return ret;
 
--- zfcpdump-kernel-4.4.orig/drivers/hwmon/dell-smm-hwmon.c
+++ zfcpdump-kernel-4.4/drivers/hwmon/dell-smm-hwmon.c
@@ -66,11 +66,13 @@
 
 static DEFINE_MUTEX(i8k_mutex);
 static char bios_version[4];
+static char bios_machineid[16];
 static struct device *i8k_hwmon_dev;
 static u32 i8k_hwmon_flags;
 static uint i8k_fan_mult = I8K_FAN_MULT;
 static uint i8k_pwm_mult;
 static uint i8k_fan_max = I8K_FAN_HIGH;
+static bool disallow_fan_type_call;
 
 #define I8K_HWMON_HAVE_TEMP1	(1 << 0)
 #define I8K_HWMON_HAVE_TEMP2	(1 << 1)
@@ -94,13 +96,13 @@ module_param(ignore_dmi, bool, 0);
 MODULE_PARM_DESC(ignore_dmi, "Continue probing hardware even if DMI data does not match");
 
 #if IS_ENABLED(CONFIG_I8K)
-static bool restricted;
+static bool restricted = true;
 module_param(restricted, bool, 0);
-MODULE_PARM_DESC(restricted, "Allow fan control if SYS_ADMIN capability set");
+MODULE_PARM_DESC(restricted, "Restrict fan control and serial number to CAP_SYS_ADMIN (default: 1)");
 
 static bool power_status;
 module_param(power_status, bool, 0600);
-MODULE_PARM_DESC(power_status, "Report power status in /proc/i8k");
+MODULE_PARM_DESC(power_status, "Report power status in /proc/i8k (default: 0)");
 #endif
 
 static uint fan_mult;
@@ -235,14 +237,28 @@ static int i8k_get_fan_speed(int fan)
 /*
  * Read the fan type.
  */
-static int i8k_get_fan_type(int fan)
+static int _i8k_get_fan_type(int fan)
 {
 	struct smm_regs regs = { .eax = I8K_SMM_GET_FAN_TYPE, };
 
+	if (disallow_fan_type_call)
+		return -EINVAL;
+
 	regs.ebx = fan & 0xff;
 	return i8k_smm(&regs) ? : regs.eax & 0xff;
 }
 
+static int i8k_get_fan_type(int fan)
+{
+	/* I8K_SMM_GET_FAN_TYPE SMM call is expensive, so cache values */
+	static int types[2] = { INT_MIN, INT_MIN };
+
+	if (types[fan] == INT_MIN)
+		types[fan] = _i8k_get_fan_type(fan);
+
+	return types[fan];
+}
+
 /*
  * Read the fan nominal rpm for specific fan speed.
  */
@@ -392,9 +408,11 @@ i8k_ioctl_unlocked(struct file *fp, unsi
 		break;
 
 	case I8K_MACHINE_ID:
-		memset(buff, 0, 16);
-		strlcpy(buff, i8k_get_dmi_data(DMI_PRODUCT_SERIAL),
-			sizeof(buff));
+		if (restricted && !capable(CAP_SYS_ADMIN))
+			return -EPERM;
+
+		memset(buff, 0, sizeof(buff));
+		strlcpy(buff, bios_machineid, sizeof(buff));
 		break;
 
 	case I8K_FN_STATUS:
@@ -511,7 +529,7 @@ static int i8k_proc_show(struct seq_file
 	seq_printf(seq, "%s %s %s %d %d %d %d %d %d %d\n",
 		   I8K_PROC_FMT,
 		   bios_version,
-		   i8k_get_dmi_data(DMI_PRODUCT_SERIAL),
+		   (restricted && !capable(CAP_SYS_ADMIN)) ? "-1" : bios_machineid,
 		   cpu_temp,
 		   left_fan, right_fan, left_speed, right_speed,
 		   ac_power, fn_key);
@@ -718,6 +736,9 @@ static struct attribute *i8k_attrs[] = {
 static umode_t i8k_is_visible(struct kobject *kobj, struct attribute *attr,
 			      int index)
 {
+	if (disallow_fan_type_call &&
+	    (index == 9 || index == 12))
+		return 0;
 	if (index >= 0 && index <= 1 &&
 	    !(i8k_hwmon_flags & I8K_HWMON_HAVE_TEMP1))
 		return 0;
@@ -767,13 +788,17 @@ static int __init i8k_init_hwmon(void)
 	if (err >= 0)
 		i8k_hwmon_flags |= I8K_HWMON_HAVE_TEMP4;
 
-	/* First fan attributes, if fan type is OK */
-	err = i8k_get_fan_type(0);
+	/* First fan attributes, if fan status or type is OK */
+	err = i8k_get_fan_status(0);
+	if (err < 0)
+		err = i8k_get_fan_type(0);
 	if (err >= 0)
 		i8k_hwmon_flags |= I8K_HWMON_HAVE_FAN1;
 
-	/* Second fan attributes, if fan type is OK */
-	err = i8k_get_fan_type(1);
+	/* Second fan attributes, if fan status or type is OK */
+	err = i8k_get_fan_status(1);
+	if (err < 0)
+		err = i8k_get_fan_type(1);
 	if (err >= 0)
 		i8k_hwmon_flags |= I8K_HWMON_HAVE_FAN2;
 
@@ -929,18 +954,34 @@ static struct dmi_system_id i8k_dmi_tabl
 
 MODULE_DEVICE_TABLE(dmi, i8k_dmi_table);
 
-static struct dmi_system_id i8k_blacklist_dmi_table[] __initdata = {
+/*
+ * On some machines once I8K_SMM_GET_FAN_TYPE is issued then CPU fan speed
+ * randomly going up and down due to bug in Dell SMM or BIOS. Here is blacklist
+ * of affected Dell machines for which we disallow I8K_SMM_GET_FAN_TYPE call.
+ * See bug: https://bugzilla.kernel.org/show_bug.cgi?id=100121
+ */
+static struct dmi_system_id i8k_blacklist_fan_type_dmi_table[] __initdata = {
+	{
+		.ident = "Dell Studio XPS 8000",
+		.matches = {
+			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+			DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Studio XPS 8000"),
+		},
+	},
 	{
-		/*
-		 * CPU fan speed going up and down on Dell Studio XPS 8100
-		 * for unknown reasons.
-		 */
 		.ident = "Dell Studio XPS 8100",
 		.matches = {
 			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
 			DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Studio XPS 8100"),
 		},
 	},
+	{
+		.ident = "Dell Inspiron 580",
+		.matches = {
+			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+			DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Inspiron 580 "),
+		},
+	},
 	{ }
 };
 
@@ -955,8 +996,7 @@ static int __init i8k_probe(void)
 	/*
 	 * Get DMI information
 	 */
-	if (!dmi_check_system(i8k_dmi_table) ||
-	    dmi_check_system(i8k_blacklist_dmi_table)) {
+	if (!dmi_check_system(i8k_dmi_table)) {
 		if (!ignore_dmi && !force)
 			return -ENODEV;
 
@@ -967,8 +1007,13 @@ static int __init i8k_probe(void)
 			i8k_get_dmi_data(DMI_BIOS_VERSION));
 	}
 
+	if (dmi_check_system(i8k_blacklist_fan_type_dmi_table))
+		disallow_fan_type_call = true;
+
 	strlcpy(bios_version, i8k_get_dmi_data(DMI_BIOS_VERSION),
 		sizeof(bios_version));
+	strlcpy(bios_machineid, i8k_get_dmi_data(DMI_PRODUCT_SERIAL),
+		sizeof(bios_machineid));
 
 	/*
 	 * Get SMM Dell signature
--- zfcpdump-kernel-4.4.orig/drivers/hwmon/gpio-fan.c
+++ zfcpdump-kernel-4.4/drivers/hwmon/gpio-fan.c
@@ -406,16 +406,11 @@ static int gpio_fan_get_cur_state(struct
 				  unsigned long *state)
 {
 	struct gpio_fan_data *fan_data = cdev->devdata;
-	int r;
 
 	if (!fan_data)
 		return -EINVAL;
 
-	r = get_fan_speed_index(fan_data);
-	if (r < 0)
-		return r;
-
-	*state = r;
+	*state = fan_data->speed_index;
 	return 0;
 }
 
--- zfcpdump-kernel-4.4.orig/drivers/hwmon/iio_hwmon.c
+++ zfcpdump-kernel-4.4/drivers/hwmon/iio_hwmon.c
@@ -109,24 +109,24 @@ static int iio_hwmon_probe(struct platfo
 
 		switch (type) {
 		case IIO_VOLTAGE:
-			a->dev_attr.attr.name = kasprintf(GFP_KERNEL,
-							  "in%d_input",
-							  in_i++);
+			a->dev_attr.attr.name = devm_kasprintf(dev, GFP_KERNEL,
+							       "in%d_input",
+							       in_i++);
 			break;
 		case IIO_TEMP:
-			a->dev_attr.attr.name = kasprintf(GFP_KERNEL,
-							  "temp%d_input",
-							  temp_i++);
+			a->dev_attr.attr.name = devm_kasprintf(dev, GFP_KERNEL,
+							       "temp%d_input",
+							       temp_i++);
 			break;
 		case IIO_CURRENT:
-			a->dev_attr.attr.name = kasprintf(GFP_KERNEL,
-							  "curr%d_input",
-							  curr_i++);
+			a->dev_attr.attr.name = devm_kasprintf(dev, GFP_KERNEL,
+							       "curr%d_input",
+							       curr_i++);
 			break;
 		case IIO_HUMIDITYRELATIVE:
-			a->dev_attr.attr.name = kasprintf(GFP_KERNEL,
-							  "humidity%d_input",
-							  humidity_i++);
+			a->dev_attr.attr.name = devm_kasprintf(dev, GFP_KERNEL,
+							       "humidity%d_input",
+							       humidity_i++);
 			break;
 		default:
 			ret = -EINVAL;
--- zfcpdump-kernel-4.4.orig/drivers/hwmon/max1111.c
+++ zfcpdump-kernel-4.4/drivers/hwmon/max1111.c
@@ -85,6 +85,9 @@ static struct max1111_data *the_max1111;
 
 int max1111_read_channel(int channel)
 {
+	if (!the_max1111 || !the_max1111->spi)
+		return -ENODEV;
+
 	return max1111_read(&the_max1111->spi->dev, channel);
 }
 EXPORT_SYMBOL(max1111_read_channel);
@@ -258,6 +261,9 @@ static int max1111_remove(struct spi_dev
 {
 	struct max1111_data *data = spi_get_drvdata(spi);
 
+#ifdef CONFIG_SHARPSL_PM
+	the_max1111 = NULL;
+#endif
 	hwmon_device_unregister(data->hwmon_dev);
 	sysfs_remove_group(&spi->dev.kobj, &max1110_attr_group);
 	sysfs_remove_group(&spi->dev.kobj, &max1111_attr_group);
--- zfcpdump-kernel-4.4.orig/drivers/hwspinlock/hwspinlock_core.c
+++ zfcpdump-kernel-4.4/drivers/hwspinlock/hwspinlock_core.c
@@ -313,6 +313,10 @@ int of_hwspin_lock_get_id(struct device_
 		hwlock = radix_tree_deref_slot(slot);
 		if (unlikely(!hwlock))
 			continue;
+		if (radix_tree_is_indirect_ptr(hwlock)) {
+			slot = radix_tree_iter_retry(&iter);
+			continue;
+		}
 
 		if (hwlock->bank->dev->of_node == args.np) {
 			ret = 0;
--- zfcpdump-kernel-4.4.orig/drivers/hwtracing/coresight/coresight.c
+++ zfcpdump-kernel-4.4/drivers/hwtracing/coresight/coresight.c
@@ -548,7 +548,7 @@ static int coresight_name_match(struct d
 	to_match = data;
 	i_csdev = to_coresight_device(dev);
 
-	if (!strcmp(to_match, dev_name(&i_csdev->dev)))
+	if (to_match && !strcmp(to_match, dev_name(&i_csdev->dev)))
 		return 1;
 
 	return 0;
--- zfcpdump-kernel-4.4.orig/drivers/hwtracing/intel_th/core.c
+++ zfcpdump-kernel-4.4/drivers/hwtracing/intel_th/core.c
@@ -419,6 +419,38 @@ static struct intel_th_subdevice {
 	},
 };
 
+#ifdef CONFIG_MODULES
+static void __intel_th_request_hub_module(struct work_struct *work)
+{
+	struct intel_th *th = container_of(work, struct intel_th,
+					   request_module_work);
+
+	request_module("intel_th_%s", th->hub->name);
+}
+
+static int intel_th_request_hub_module(struct intel_th *th)
+{
+	INIT_WORK(&th->request_module_work, __intel_th_request_hub_module);
+	schedule_work(&th->request_module_work);
+
+	return 0;
+}
+
+static void intel_th_request_hub_module_flush(struct intel_th *th)
+{
+	flush_work(&th->request_module_work);
+}
+#else
+static inline int intel_th_request_hub_module(struct intel_th *th)
+{
+	return -EINVAL;
+}
+
+static inline void intel_th_request_hub_module_flush(struct intel_th *th)
+{
+}
+#endif /* CONFIG_MODULES */
+
 static int intel_th_populate(struct intel_th *th, struct resource *devres,
 			     unsigned int ndevres, int irq)
 {
@@ -488,7 +520,7 @@ static int intel_th_populate(struct inte
 		/* need switch driver to be loaded to enumerate the rest */
 		if (subdev->type == INTEL_TH_SWITCH && !req) {
 			th->hub = thdev;
-			err = request_module("intel_th_%s", subdev->name);
+			err = intel_th_request_hub_module(th);
 			if (!err)
 				req++;
 		}
@@ -603,6 +635,7 @@ void intel_th_free(struct intel_th *th)
 {
 	int i;
 
+	intel_th_request_hub_module_flush(th);
 	for (i = 0; i < TH_SUBDEVICE_MAX; i++)
 		if (th->thdev[i] != th->hub)
 			intel_th_device_remove(th->thdev[i]);
--- zfcpdump-kernel-4.4.orig/drivers/hwtracing/intel_th/intel_th.h
+++ zfcpdump-kernel-4.4/drivers/hwtracing/intel_th/intel_th.h
@@ -197,6 +197,9 @@ struct intel_th {
 
 	int			id;
 	int			major;
+#ifdef CONFIG_MODULES
+	struct work_struct	request_module_work;
+#endif /* CONFIG_MODULES */
 #ifdef CONFIG_INTEL_TH_DEBUG
 	struct dentry		*dbg;
 #endif
--- zfcpdump-kernel-4.4.orig/drivers/hwtracing/intel_th/pci.c
+++ zfcpdump-kernel-4.4/drivers/hwtracing/intel_th/pci.c
@@ -67,6 +67,11 @@ static const struct pci_device_id intel_
 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xa126),
 		.driver_data = (kernel_ulong_t)0,
 	},
+	{
+		/* Kaby Lake PCH-H */
+		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xa2a6),
+		.driver_data = (kernel_ulong_t)0,
+	},
 	{ 0 },
 };
 
--- zfcpdump-kernel-4.4.orig/drivers/hwtracing/stm/Kconfig
+++ zfcpdump-kernel-4.4/drivers/hwtracing/stm/Kconfig
@@ -1,6 +1,7 @@
 config STM
 	tristate "System Trace Module devices"
 	select CONFIGFS_FS
+	select SRCU
 	help
 	  A System Trace Module (STM) is a device exporting data in System
 	  Trace Protocol (STP) format as defined by MIPI STP standards.
--- zfcpdump-kernel-4.4.orig/drivers/i2c/busses/i2c-brcmstb.c
+++ zfcpdump-kernel-4.4/drivers/i2c/busses/i2c-brcmstb.c
@@ -562,8 +562,7 @@ static int brcmstb_i2c_probe(struct plat
 	if (!dev)
 		return -ENOMEM;
 
-	dev->bsc_regmap = devm_kzalloc(&pdev->dev, sizeof(struct bsc_regs *),
-				       GFP_KERNEL);
+	dev->bsc_regmap = devm_kzalloc(&pdev->dev, sizeof(*dev->bsc_regmap), GFP_KERNEL);
 	if (!dev->bsc_regmap)
 		return -ENOMEM;
 
--- zfcpdump-kernel-4.4.orig/drivers/i2c/busses/i2c-cpm.c
+++ zfcpdump-kernel-4.4/drivers/i2c/busses/i2c-cpm.c
@@ -116,8 +116,8 @@ struct cpm_i2c {
 	cbd_t __iomem *rbase;
 	u_char *txbuf[CPM_MAXBD];
 	u_char *rxbuf[CPM_MAXBD];
-	u32 txdma[CPM_MAXBD];
-	u32 rxdma[CPM_MAXBD];
+	dma_addr_t txdma[CPM_MAXBD];
+	dma_addr_t rxdma[CPM_MAXBD];
 };
 
 static irqreturn_t cpm_i2c_interrupt(int irq, void *dev_id)
--- zfcpdump-kernel-4.4.orig/drivers/i2c/busses/i2c-cros-ec-tunnel.c
+++ zfcpdump-kernel-4.4/drivers/i2c/busses/i2c-cros-ec-tunnel.c
@@ -215,7 +215,7 @@ static int ec_i2c_xfer(struct i2c_adapte
 	msg->outsize = request_len;
 	msg->insize = response_len;
 
-	result = cros_ec_cmd_xfer(bus->ec, msg);
+	result = cros_ec_cmd_xfer_status(bus->ec, msg);
 	if (result < 0) {
 		dev_err(dev, "Error transferring EC i2c message %d\n", result);
 		goto exit;
--- zfcpdump-kernel-4.4.orig/drivers/i2c/busses/i2c-designware-core.c
+++ zfcpdump-kernel-4.4/drivers/i2c/busses/i2c-designware-core.c
@@ -271,6 +271,17 @@ static void __i2c_dw_enable(struct dw_i2
 		 enable ? "en" : "dis");
 }
 
+static unsigned long i2c_dw_clk_rate(struct dw_i2c_dev *dev)
+{
+	/*
+	 * Clock is not necessary if we got LCNT/HCNT values directly from
+	 * the platform code.
+	 */
+	if (WARN_ON_ONCE(!dev->get_clk_rate_khz))
+		return 0;
+	return dev->get_clk_rate_khz(dev);
+}
+
 /**
  * i2c_dw_init() - initialize the designware i2c master hardware
  * @dev: device private data
@@ -281,7 +292,6 @@ static void __i2c_dw_enable(struct dw_i2
  */
 int i2c_dw_init(struct dw_i2c_dev *dev)
 {
-	u32 input_clock_khz;
 	u32 hcnt, lcnt;
 	u32 reg;
 	u32 sda_falling_time, scl_falling_time;
@@ -295,8 +305,6 @@ int i2c_dw_init(struct dw_i2c_dev *dev)
 		}
 	}
 
-	input_clock_khz = dev->get_clk_rate_khz(dev);
-
 	reg = dw_readl(dev, DW_IC_COMP_TYPE);
 	if (reg == ___constant_swab32(DW_IC_COMP_TYPE_VALUE)) {
 		/* Configure register endianess access */
@@ -325,12 +333,12 @@ int i2c_dw_init(struct dw_i2c_dev *dev)
 		hcnt = dev->ss_hcnt;
 		lcnt = dev->ss_lcnt;
 	} else {
-		hcnt = i2c_dw_scl_hcnt(input_clock_khz,
+		hcnt = i2c_dw_scl_hcnt(i2c_dw_clk_rate(dev),
 					4000,	/* tHD;STA = tHIGH = 4.0 us */
 					sda_falling_time,
 					0,	/* 0: DW default, 1: Ideal */
 					0);	/* No offset */
-		lcnt = i2c_dw_scl_lcnt(input_clock_khz,
+		lcnt = i2c_dw_scl_lcnt(i2c_dw_clk_rate(dev),
 					4700,	/* tLOW = 4.7 us */
 					scl_falling_time,
 					0);	/* No offset */
@@ -344,12 +352,12 @@ int i2c_dw_init(struct dw_i2c_dev *dev)
 		hcnt = dev->fs_hcnt;
 		lcnt = dev->fs_lcnt;
 	} else {
-		hcnt = i2c_dw_scl_hcnt(input_clock_khz,
+		hcnt = i2c_dw_scl_hcnt(i2c_dw_clk_rate(dev),
 					600,	/* tHD;STA = tHIGH = 0.6 us */
 					sda_falling_time,
 					0,	/* 0: DW default, 1: Ideal */
 					0);	/* No offset */
-		lcnt = i2c_dw_scl_lcnt(input_clock_khz,
+		lcnt = i2c_dw_scl_lcnt(i2c_dw_clk_rate(dev),
 					1300,	/* tLOW = 1.3 us */
 					scl_falling_time,
 					0);	/* No offset */
--- zfcpdump-kernel-4.4.orig/drivers/i2c/busses/i2c-designware-platdrv.c
+++ zfcpdump-kernel-4.4/drivers/i2c/busses/i2c-designware-platdrv.c
@@ -36,6 +36,7 @@
 #include <linux/platform_device.h>
 #include <linux/pm.h>
 #include <linux/pm_runtime.h>
+#include <linux/property.h>
 #include <linux/io.h>
 #include <linux/slab.h>
 #include <linux/acpi.h>
@@ -132,12 +133,24 @@ static inline int dw_i2c_acpi_configure(
 }
 #endif
 
+static int i2c_dw_plat_prepare_clk(struct dw_i2c_dev *i_dev, bool prepare)
+{
+	if (IS_ERR(i_dev->clk))
+		return PTR_ERR(i_dev->clk);
+
+	if (prepare)
+		return clk_prepare_enable(i_dev->clk);
+
+	clk_disable_unprepare(i_dev->clk);
+	return 0;
+}
+
 static int dw_i2c_plat_probe(struct platform_device *pdev)
 {
+	struct dw_i2c_platform_data *pdata = dev_get_platdata(&pdev->dev);
 	struct dw_i2c_dev *dev;
 	struct i2c_adapter *adap;
 	struct resource *mem;
-	struct dw_i2c_platform_data *pdata;
 	int irq, r;
 	u32 clk_freq, ht = 0;
 
@@ -161,33 +174,28 @@ static int dw_i2c_plat_probe(struct plat
 	/* fast mode by default because of legacy reasons */
 	clk_freq = 400000;
 
-	if (has_acpi_companion(&pdev->dev)) {
-		dw_i2c_acpi_configure(pdev);
-	} else if (pdev->dev.of_node) {
-		of_property_read_u32(pdev->dev.of_node,
-					"i2c-sda-hold-time-ns", &ht);
-
-		of_property_read_u32(pdev->dev.of_node,
-				     "i2c-sda-falling-time-ns",
-				     &dev->sda_falling_time);
-		of_property_read_u32(pdev->dev.of_node,
-				     "i2c-scl-falling-time-ns",
-				     &dev->scl_falling_time);
-
-		of_property_read_u32(pdev->dev.of_node, "clock-frequency",
-				     &clk_freq);
-
-		/* Only standard mode at 100kHz and fast mode at 400kHz
-		 * are supported.
-		 */
-		if (clk_freq != 100000 && clk_freq != 400000) {
-			dev_err(&pdev->dev, "Only 100kHz and 400kHz supported");
-			return -EINVAL;
-		}
+	if (pdata) {
+		clk_freq = pdata->i2c_scl_freq;
 	} else {
-		pdata = dev_get_platdata(&pdev->dev);
-		if (pdata)
-			clk_freq = pdata->i2c_scl_freq;
+		device_property_read_u32(&pdev->dev, "i2c-sda-hold-time-ns",
+					 &ht);
+		device_property_read_u32(&pdev->dev, "i2c-sda-falling-time-ns",
+					 &dev->sda_falling_time);
+		device_property_read_u32(&pdev->dev, "i2c-scl-falling-time-ns",
+					 &dev->scl_falling_time);
+		device_property_read_u32(&pdev->dev, "clock-frequency",
+					 &clk_freq);
+	}
+
+	if (has_acpi_companion(&pdev->dev))
+		dw_i2c_acpi_configure(pdev);
+
+	/*
+	 * Only standard mode at 100kHz and fast mode at 400kHz are supported.
+	 */
+	if (clk_freq != 100000 && clk_freq != 400000) {
+		dev_err(&pdev->dev, "Only 100kHz and 400kHz supported");
+		return -EINVAL;
 	}
 
 	r = i2c_dw_eval_lock_support(dev);
@@ -209,16 +217,13 @@ static int dw_i2c_plat_probe(struct plat
 			DW_IC_CON_RESTART_EN | DW_IC_CON_SPEED_FAST;
 
 	dev->clk = devm_clk_get(&pdev->dev, NULL);
-	dev->get_clk_rate_khz = i2c_dw_get_clk_rate_khz;
-	if (IS_ERR(dev->clk))
-		return PTR_ERR(dev->clk);
-	clk_prepare_enable(dev->clk);
+	if (!i2c_dw_plat_prepare_clk(dev, true)) {
+		dev->get_clk_rate_khz = i2c_dw_get_clk_rate_khz;
 
-	if (!dev->sda_hold_time && ht) {
-		u32 ic_clk = dev->get_clk_rate_khz(dev);
-
-		dev->sda_hold_time = div_u64((u64)ic_clk * ht + 500000,
-					     1000000);
+		if (!dev->sda_hold_time && ht)
+			dev->sda_hold_time = div_u64(
+				(u64)dev->get_clk_rate_khz(dev) * ht + 500000,
+				1000000);
 	}
 
 	if (!dev->tx_fifo_depth) {
@@ -300,7 +305,7 @@ static int dw_i2c_plat_suspend(struct de
 	struct dw_i2c_dev *i_dev = platform_get_drvdata(pdev);
 
 	i2c_dw_disable(i_dev);
-	clk_disable_unprepare(i_dev->clk);
+	i2c_dw_plat_prepare_clk(i_dev, false);
 
 	return 0;
 }
@@ -310,7 +315,7 @@ static int dw_i2c_plat_resume(struct dev
 	struct platform_device *pdev = to_platform_device(dev);
 	struct dw_i2c_dev *i_dev = platform_get_drvdata(pdev);
 
-	clk_prepare_enable(i_dev->clk);
+	i2c_dw_plat_prepare_clk(i_dev, true);
 
 	if (!i_dev->pm_runtime_disabled)
 		i2c_dw_init(i_dev);
--- zfcpdump-kernel-4.4.orig/drivers/i2c/busses/i2c-efm32.c
+++ zfcpdump-kernel-4.4/drivers/i2c/busses/i2c-efm32.c
@@ -433,7 +433,7 @@ static int efm32_i2c_probe(struct platfo
 	ret = request_irq(ddata->irq, efm32_i2c_irq, 0, DRIVER_NAME, ddata);
 	if (ret < 0) {
 		dev_err(&pdev->dev, "failed to request irq (%d)\n", ret);
-		return ret;
+		goto err_disable_clk;
 	}
 
 	ret = i2c_add_adapter(&ddata->adapter);
--- zfcpdump-kernel-4.4.orig/drivers/i2c/busses/i2c-eg20t.c
+++ zfcpdump-kernel-4.4/drivers/i2c/busses/i2c-eg20t.c
@@ -773,13 +773,6 @@ static int pch_i2c_probe(struct pci_dev
 	/* Set the number of I2C channel instance */
 	adap_info->ch_num = id->driver_data;
 
-	ret = request_irq(pdev->irq, pch_i2c_handler, IRQF_SHARED,
-		  KBUILD_MODNAME, adap_info);
-	if (ret) {
-		pch_pci_err(pdev, "request_irq FAILED\n");
-		goto err_request_irq;
-	}
-
 	for (i = 0; i < adap_info->ch_num; i++) {
 		pch_adap = &adap_info->pch_data[i].pch_adapter;
 		adap_info->pch_i2c_suspended = false;
@@ -796,6 +789,17 @@ static int pch_i2c_probe(struct pci_dev
 		adap_info->pch_data[i].pch_base_address = base_addr + 0x100 * i;
 
 		pch_adap->dev.parent = &pdev->dev;
+	}
+
+	ret = request_irq(pdev->irq, pch_i2c_handler, IRQF_SHARED,
+		  KBUILD_MODNAME, adap_info);
+	if (ret) {
+		pch_pci_err(pdev, "request_irq FAILED\n");
+		goto err_request_irq;
+	}
+
+	for (i = 0; i < adap_info->ch_num; i++) {
+		pch_adap = &adap_info->pch_data[i].pch_adapter;
 
 		pch_i2c_init(&adap_info->pch_data[i]);
 
--- zfcpdump-kernel-4.4.orig/drivers/i2c/busses/i2c-exynos5.c
+++ zfcpdump-kernel-4.4/drivers/i2c/busses/i2c-exynos5.c
@@ -671,7 +671,9 @@ static int exynos5_i2c_xfer(struct i2c_a
 		return -EIO;
 	}
 
-	clk_prepare_enable(i2c->clk);
+	ret = clk_enable(i2c->clk);
+	if (ret)
+		return ret;
 
 	for (i = 0; i < num; i++, msgs++) {
 		stop = (i == num - 1);
@@ -695,7 +697,7 @@ static int exynos5_i2c_xfer(struct i2c_a
 	}
 
  out:
-	clk_disable_unprepare(i2c->clk);
+	clk_disable(i2c->clk);
 	return ret;
 }
 
@@ -747,7 +749,9 @@ static int exynos5_i2c_probe(struct plat
 		return -ENOENT;
 	}
 
-	clk_prepare_enable(i2c->clk);
+	ret = clk_prepare_enable(i2c->clk);
+	if (ret)
+		return ret;
 
 	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	i2c->regs = devm_ioremap_resource(&pdev->dev, mem);
@@ -799,6 +803,10 @@ static int exynos5_i2c_probe(struct plat
 
 	platform_set_drvdata(pdev, i2c);
 
+	clk_disable(i2c->clk);
+
+	return 0;
+
  err_clk:
 	clk_disable_unprepare(i2c->clk);
 	return ret;
@@ -810,6 +818,8 @@ static int exynos5_i2c_remove(struct pla
 
 	i2c_del_adapter(&i2c->adap);
 
+	clk_unprepare(i2c->clk);
+
 	return 0;
 }
 
@@ -821,6 +831,8 @@ static int exynos5_i2c_suspend_noirq(str
 
 	i2c->suspended = 1;
 
+	clk_unprepare(i2c->clk);
+
 	return 0;
 }
 
@@ -830,7 +842,9 @@ static int exynos5_i2c_resume_noirq(stru
 	struct exynos5_i2c *i2c = platform_get_drvdata(pdev);
 	int ret = 0;
 
-	clk_prepare_enable(i2c->clk);
+	ret = clk_prepare_enable(i2c->clk);
+	if (ret)
+		return ret;
 
 	ret = exynos5_hsi2c_clock_setup(i2c);
 	if (ret) {
@@ -839,7 +853,7 @@ static int exynos5_i2c_resume_noirq(stru
 	}
 
 	exynos5_i2c_init(i2c);
-	clk_disable_unprepare(i2c->clk);
+	clk_disable(i2c->clk);
 	i2c->suspended = 0;
 
 	return 0;
--- zfcpdump-kernel-4.4.orig/drivers/i2c/busses/i2c-i801.c
+++ zfcpdump-kernel-4.4/drivers/i2c/busses/i2c-i801.c
@@ -210,6 +210,7 @@
 #define PCI_DEVICE_ID_INTEL_BROXTON_SMBUS		0x5ad4
 #define PCI_DEVICE_ID_INTEL_LEWISBURG_SMBUS		0xa1a3
 #define PCI_DEVICE_ID_INTEL_LEWISBURG_SSKU_SMBUS	0xa223
+#define PCI_DEVICE_ID_INTEL_KABYPOINT_H_SMBUS		0xa2a3
 
 struct i801_mux_config {
 	char *gpio_chip;
@@ -244,6 +245,13 @@ struct i801_priv {
 	struct platform_device *mux_pdev;
 #endif
 	struct platform_device *tco_pdev;
+
+	/*
+	 * If set to true the host controller registers are reserved for
+	 * ACPI AML use. Protected by acpi_lock.
+	 */
+	bool acpi_reserved;
+	struct mutex acpi_lock;
 };
 
 #define FEATURE_SMBUS_PEC	(1 << 0)
@@ -714,9 +722,15 @@ static s32 i801_access(struct i2c_adapte
 {
 	int hwpec;
 	int block = 0;
-	int ret, xact = 0;
+	int ret = 0, xact = 0;
 	struct i801_priv *priv = i2c_get_adapdata(adap);
 
+	mutex_lock(&priv->acpi_lock);
+	if (priv->acpi_reserved) {
+		mutex_unlock(&priv->acpi_lock);
+		return -EBUSY;
+	}
+
 	hwpec = (priv->features & FEATURE_SMBUS_PEC) && (flags & I2C_CLIENT_PEC)
 		&& size != I2C_SMBUS_QUICK
 		&& size != I2C_SMBUS_I2C_BLOCK_DATA;
@@ -773,7 +787,8 @@ static s32 i801_access(struct i2c_adapte
 	default:
 		dev_err(&priv->pci_dev->dev, "Unsupported transaction %d\n",
 			size);
-		return -EOPNOTSUPP;
+		ret = -EOPNOTSUPP;
+		goto out;
 	}
 
 	if (hwpec)	/* enable/disable hardware PEC */
@@ -796,11 +811,11 @@ static s32 i801_access(struct i2c_adapte
 		       ~(SMBAUXCTL_CRC | SMBAUXCTL_E32B), SMBAUXCTL(priv));
 
 	if (block)
-		return ret;
+		goto out;
 	if (ret)
-		return ret;
+		goto out;
 	if ((read_write == I2C_SMBUS_WRITE) || (xact == I801_QUICK))
-		return 0;
+		goto out;
 
 	switch (xact & 0x7f) {
 	case I801_BYTE:	/* Result put in SMBHSTDAT0 */
@@ -812,7 +827,10 @@ static s32 i801_access(struct i2c_adapte
 			     (inb_p(SMBHSTDAT1(priv)) << 8);
 		break;
 	}
-	return 0;
+
+out:
+	mutex_unlock(&priv->acpi_lock);
+	return ret;
 }
 
 
@@ -875,6 +893,7 @@ static const struct pci_device_id i801_i
 	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BROXTON_SMBUS) },
 	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_LEWISBURG_SMBUS) },
 	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_LEWISBURG_SSKU_SMBUS) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_KABYPOINT_H_SMBUS) },
 	{ 0, }
 };
 
@@ -1249,6 +1268,72 @@ static void i801_add_tco(struct i801_pri
 	priv->tco_pdev = pdev;
 }
 
+#ifdef CONFIG_ACPI
+static acpi_status
+i801_acpi_io_handler(u32 function, acpi_physical_address address, u32 bits,
+		     u64 *value, void *handler_context, void *region_context)
+{
+	struct i801_priv *priv = handler_context;
+	struct pci_dev *pdev = priv->pci_dev;
+	acpi_status status;
+
+	/*
+	 * Once BIOS AML code touches the OpRegion we warn and inhibit any
+	 * further access from the driver itself. This device is now owned
+	 * by the system firmware.
+	 */
+	mutex_lock(&priv->acpi_lock);
+
+	if (!priv->acpi_reserved) {
+		priv->acpi_reserved = true;
+
+		dev_warn(&pdev->dev, "BIOS is accessing SMBus registers\n");
+		dev_warn(&pdev->dev, "Driver SMBus register access inhibited\n");
+	}
+
+	if ((function & ACPI_IO_MASK) == ACPI_READ)
+		status = acpi_os_read_port(address, (u32 *)value, bits);
+	else
+		status = acpi_os_write_port(address, (u32)*value, bits);
+
+	mutex_unlock(&priv->acpi_lock);
+
+	return status;
+}
+
+static int i801_acpi_probe(struct i801_priv *priv)
+{
+	struct acpi_device *adev;
+	acpi_status status;
+
+	adev = ACPI_COMPANION(&priv->pci_dev->dev);
+	if (adev) {
+		status = acpi_install_address_space_handler(adev->handle,
+				ACPI_ADR_SPACE_SYSTEM_IO, i801_acpi_io_handler,
+				NULL, priv);
+		if (ACPI_SUCCESS(status))
+			return 0;
+	}
+
+	return acpi_check_resource_conflict(&priv->pci_dev->resource[SMBBAR]);
+}
+
+static void i801_acpi_remove(struct i801_priv *priv)
+{
+	struct acpi_device *adev;
+
+	adev = ACPI_COMPANION(&priv->pci_dev->dev);
+	if (!adev)
+		return;
+
+	acpi_remove_address_space_handler(adev->handle,
+		ACPI_ADR_SPACE_SYSTEM_IO, i801_acpi_io_handler);
+}
+#else
+static inline int i801_acpi_probe(struct i801_priv *priv) { return 0; }
+static inline void i801_acpi_remove(struct i801_priv *priv) { }
+#endif
+
 static int i801_probe(struct pci_dev *dev, const struct pci_device_id *id)
 {
 	unsigned char temp;
@@ -1266,12 +1351,16 @@ static int i801_probe(struct pci_dev *de
 	priv->adapter.dev.parent = &dev->dev;
 	ACPI_COMPANION_SET(&priv->adapter.dev, ACPI_COMPANION(&dev->dev));
 	priv->adapter.retries = 3;
+	mutex_init(&priv->acpi_lock);
 
 	priv->pci_dev = dev;
 	switch (dev->device) {
 	case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_H_SMBUS:
 	case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_SMBUS:
+	case PCI_DEVICE_ID_INTEL_LEWISBURG_SMBUS:
+	case PCI_DEVICE_ID_INTEL_LEWISBURG_SSKU_SMBUS:
 	case PCI_DEVICE_ID_INTEL_DNV_SMBUS:
+	case PCI_DEVICE_ID_INTEL_KABYPOINT_H_SMBUS:
 		priv->features |= FEATURE_I2C_BLOCK_READ;
 		priv->features |= FEATURE_IRQ;
 		priv->features |= FEATURE_SMBUS_PEC;
@@ -1326,10 +1415,8 @@ static int i801_probe(struct pci_dev *de
 		return -ENODEV;
 	}
 
-	err = acpi_check_resource_conflict(&dev->resource[SMBBAR]);
-	if (err) {
+	if (i801_acpi_probe(priv))
 		return -ENODEV;
-	}
 
 	err = pcim_iomap_regions(dev, 1 << SMBBAR,
 				 dev_driver_string(&dev->dev));
@@ -1338,6 +1425,7 @@ static int i801_probe(struct pci_dev *de
 			"Failed to request SMBus region 0x%lx-0x%Lx\n",
 			priv->smba,
 			(unsigned long long)pci_resource_end(dev, SMBBAR));
+		i801_acpi_remove(priv);
 		return err;
 	}
 
@@ -1402,6 +1490,7 @@ static int i801_probe(struct pci_dev *de
 	err = i2c_add_adapter(&priv->adapter);
 	if (err) {
 		dev_err(&dev->dev, "Failed to add SMBus adapter\n");
+		i801_acpi_remove(priv);
 		return err;
 	}
 
@@ -1420,6 +1509,7 @@ static void i801_remove(struct pci_dev *
 
 	i801_del_mux(priv);
 	i2c_del_adapter(&priv->adapter);
+	i801_acpi_remove(priv);
 	pci_write_config_byte(dev, SMBHSTCFG, priv->original_hstcfg);
 
 	platform_device_unregister(priv->tco_pdev);
--- zfcpdump-kernel-4.4.orig/drivers/i2c/busses/i2c-qup.c
+++ zfcpdump-kernel-4.4/drivers/i2c/busses/i2c-qup.c
@@ -727,7 +727,8 @@ static int qup_i2c_pm_resume_runtime(str
 #ifdef CONFIG_PM_SLEEP
 static int qup_i2c_suspend(struct device *device)
 {
-	qup_i2c_pm_suspend_runtime(device);
+	if (!pm_runtime_suspended(device))
+		return qup_i2c_pm_suspend_runtime(device);
 	return 0;
 }
 
--- zfcpdump-kernel-4.4.orig/drivers/i2c/muxes/i2c-mux-reg.c
+++ zfcpdump-kernel-4.4/drivers/i2c/muxes/i2c-mux-reg.c
@@ -150,7 +150,7 @@ static int i2c_mux_reg_probe_dt(struct r
 		mux->data.idle_in_use = true;
 
 	/* map address from "reg" if exists */
-	if (of_address_to_resource(np, 0, &res)) {
+	if (of_address_to_resource(np, 0, &res) == 0) {
 		mux->data.reg_size = resource_size(&res);
 		mux->data.reg = devm_ioremap_resource(&pdev->dev, &res);
 		if (IS_ERR(mux->data.reg))
--- zfcpdump-kernel-4.4.orig/drivers/idle/intel_idle.c
+++ zfcpdump-kernel-4.4/drivers/idle/intel_idle.c
@@ -65,7 +65,7 @@
 #include <asm/mwait.h>
 #include <asm/msr.h>
 
-#define INTEL_IDLE_VERSION "0.4"
+#define INTEL_IDLE_VERSION "0.4.1"
 #define PREFIX "intel_idle: "
 
 static struct cpuidle_driver intel_idle_driver = {
@@ -716,6 +716,87 @@ static struct cpuidle_state avn_cstates[
 	{
 		.enter = NULL }
 };
+static struct cpuidle_state knl_cstates[] = {
+	{
+		.name = "C1-KNL",
+		.desc = "MWAIT 0x00",
+		.flags = MWAIT2flg(0x00),
+		.exit_latency = 1,
+		.target_residency = 2,
+		.enter = &intel_idle,
+		.enter_freeze = intel_idle_freeze },
+	{
+		.name = "C6-KNL",
+		.desc = "MWAIT 0x10",
+		.flags = MWAIT2flg(0x10) | CPUIDLE_FLAG_TLB_FLUSHED,
+		.exit_latency = 120,
+		.target_residency = 500,
+		.enter = &intel_idle,
+		.enter_freeze = intel_idle_freeze },
+	{
+		.enter = NULL }
+};
+
+static struct cpuidle_state bxt_cstates[] = {
+	{
+		.name = "C1-BXT",
+		.desc = "MWAIT 0x00",
+		.flags = MWAIT2flg(0x00),
+		.exit_latency = 2,
+		.target_residency = 2,
+		.enter = &intel_idle,
+		.enter_freeze = intel_idle_freeze, },
+	{
+		.name = "C1E-BXT",
+		.desc = "MWAIT 0x01",
+		.flags = MWAIT2flg(0x01),
+		.exit_latency = 10,
+		.target_residency = 20,
+		.enter = &intel_idle,
+		.enter_freeze = intel_idle_freeze, },
+	{
+		.name = "C6-BXT",
+		.desc = "MWAIT 0x20",
+		.flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TLB_FLUSHED,
+		.exit_latency = 133,
+		.target_residency = 133,
+		.enter = &intel_idle,
+		.enter_freeze = intel_idle_freeze, },
+	{
+		.name = "C7s-BXT",
+		.desc = "MWAIT 0x31",
+		.flags = MWAIT2flg(0x31) | CPUIDLE_FLAG_TLB_FLUSHED,
+		.exit_latency = 155,
+		.target_residency = 155,
+		.enter = &intel_idle,
+		.enter_freeze = intel_idle_freeze, },
+	{
+		.name = "C8-BXT",
+		.desc = "MWAIT 0x40",
+		.flags = MWAIT2flg(0x40) | CPUIDLE_FLAG_TLB_FLUSHED,
+		.exit_latency = 1000,
+		.target_residency = 1000,
+		.enter = &intel_idle,
+		.enter_freeze = intel_idle_freeze, },
+	{
+		.name = "C9-BXT",
+		.desc = "MWAIT 0x50",
+		.flags = MWAIT2flg(0x50) | CPUIDLE_FLAG_TLB_FLUSHED,
+		.exit_latency = 2000,
+		.target_residency = 2000,
+		.enter = &intel_idle,
+		.enter_freeze = intel_idle_freeze, },
+	{
+		.name = "C10-BXT",
+		.desc = "MWAIT 0x60",
+		.flags = MWAIT2flg(0x60) | CPUIDLE_FLAG_TLB_FLUSHED,
+		.exit_latency = 10000,
+		.target_residency = 10000,
+		.enter = &intel_idle,
+		.enter_freeze = intel_idle_freeze, },
+	{
+		.enter = NULL }
+};
 
 /**
  * intel_idle
@@ -890,6 +971,15 @@ static const struct idle_cpu idle_cpu_av
 	.disable_promotion_to_c1e = true,
 };
 
+static const struct idle_cpu idle_cpu_knl = {
+	.state_table = knl_cstates,
+};
+
+static const struct idle_cpu idle_cpu_bxt = {
+	.state_table = bxt_cstates,
+	.disable_promotion_to_c1e = true,
+};
+
 #define ICPU(model, cpu) \
 	{ X86_VENDOR_INTEL, 6, model, X86_FEATURE_MWAIT, (unsigned long)&cpu }
 
@@ -921,6 +1011,8 @@ static const struct x86_cpu_id intel_idl
 	ICPU(0x56, idle_cpu_bdw),
 	ICPU(0x4e, idle_cpu_skl),
 	ICPU(0x5e, idle_cpu_skl),
+	ICPU(0x57, idle_cpu_knl),
+	ICPU(0x5c, idle_cpu_bxt),
 	{}
 };
 MODULE_DEVICE_TABLE(x86cpu, intel_idle_ids);
@@ -994,36 +1086,162 @@ static void intel_idle_cpuidle_devices_u
 }
 
 /*
- * intel_idle_state_table_update()
- *
- * Update the default state_table for this CPU-id
+ * ivt_idle_state_table_update(void)
  *
- * Currently used to access tuned IVT multi-socket targets
+ * Tune IVT multi-socket targets
  * Assumption: num_sockets == (max_package_num + 1)
  */
-void intel_idle_state_table_update(void)
+static void ivt_idle_state_table_update(void)
 {
 	/* IVT uses a different table for 1-2, 3-4, and > 4 sockets */
-	if (boot_cpu_data.x86_model == 0x3e) { /* IVT */
-		int cpu, package_num, num_sockets = 1;
+	int cpu, package_num, num_sockets = 1;
 
-		for_each_online_cpu(cpu) {
-			package_num = topology_physical_package_id(cpu);
-			if (package_num + 1 > num_sockets) {
-				num_sockets = package_num + 1;
-
-				if (num_sockets > 4) {
-					cpuidle_state_table = ivt_cstates_8s;
-					return;
-				}
+	for_each_online_cpu(cpu) {
+		package_num = topology_physical_package_id(cpu);
+		if (package_num + 1 > num_sockets) {
+			num_sockets = package_num + 1;
+
+			if (num_sockets > 4) {
+				cpuidle_state_table = ivt_cstates_8s;
+				return;
 			}
 		}
+	}
+
+	if (num_sockets > 2)
+		cpuidle_state_table = ivt_cstates_4s;
+
+	/* else, 1 and 2 socket systems use default ivt_cstates */
+}
+
+/*
+ * Translate IRTL (Interrupt Response Time Limit) MSR to usec
+ */
+
+static unsigned int irtl_ns_units[] = {
+	1, 32, 1024, 32768, 1048576, 33554432, 0, 0 };
+
+static unsigned long long irtl_2_usec(unsigned long long irtl)
+{
+	unsigned long long ns;
+
+	ns = irtl_ns_units[(irtl >> 10) & 0x3];
+
+	return div64_u64((irtl & 0x3FF) * ns, 1000);
+}
+/*
+ * bxt_idle_state_table_update(void)
+ *
+ * On BXT, we trust the IRTL to show the definitive maximum latency
+ * We use the same value for target_residency.
+ */
+static void bxt_idle_state_table_update(void)
+{
+	unsigned long long msr;
 
-		if (num_sockets > 2)
-			cpuidle_state_table = ivt_cstates_4s;
-		/* else, 1 and 2 socket systems use default ivt_cstates */
+	rdmsrl(MSR_PKGC6_IRTL, msr);
+	if (msr) {
+		unsigned int usec = irtl_2_usec(msr);
+
+		bxt_cstates[2].exit_latency = usec;
+		bxt_cstates[2].target_residency = usec;
+	}
+
+	rdmsrl(MSR_PKGC7_IRTL, msr);
+	if (msr) {
+		unsigned int usec = irtl_2_usec(msr);
+
+		bxt_cstates[3].exit_latency = usec;
+		bxt_cstates[3].target_residency = usec;
+	}
+
+	rdmsrl(MSR_PKGC8_IRTL, msr);
+	if (msr) {
+		unsigned int usec = irtl_2_usec(msr);
+
+		bxt_cstates[4].exit_latency = usec;
+		bxt_cstates[4].target_residency = usec;
+	}
+
+	rdmsrl(MSR_PKGC9_IRTL, msr);
+	if (msr) {
+		unsigned int usec = irtl_2_usec(msr);
+
+		bxt_cstates[5].exit_latency = usec;
+		bxt_cstates[5].target_residency = usec;
+	}
+
+	rdmsrl(MSR_PKGC10_IRTL, msr);
+	if (msr) {
+		unsigned int usec = irtl_2_usec(msr);
+
+		bxt_cstates[6].exit_latency = usec;
+		bxt_cstates[6].target_residency = usec;
+	}
+
+}
+/*
+ * sklh_idle_state_table_update(void)
+ *
+ * On SKL-H (model 0x5e) disable C8 and C9 if:
+ * C10 is enabled and SGX disabled
+ */
+static void sklh_idle_state_table_update(void)
+{
+	unsigned long long msr;
+	unsigned int eax, ebx, ecx, edx;
+
+
+	/* if PC10 disabled via cmdline intel_idle.max_cstate=7 or shallower */
+	if (max_cstate <= 7)
+		return;
+
+	/* if PC10 not present in CPUID.MWAIT.EDX */
+	if ((mwait_substates & (0xF << 28)) == 0)
+		return;
+
+	rdmsrl(MSR_NHM_SNB_PKG_CST_CFG_CTL, msr);
+
+	/* PC10 is not enabled in PKG C-state limit */
+	if ((msr & 0xF) != 8)
+		return;
+
+	ecx = 0;
+	cpuid(7, &eax, &ebx, &ecx, &edx);
+
+	/* if SGX is present */
+	if (ebx & (1 << 2)) {
+
+		rdmsrl(MSR_IA32_FEATURE_CONTROL, msr);
+
+		/* if SGX is enabled */
+		if (msr & (1 << 18))
+			return;
+	}
+
+	skl_cstates[5].disabled = 1;	/* C8-SKL */
+	skl_cstates[6].disabled = 1;	/* C9-SKL */
+}
+/*
+ * intel_idle_state_table_update()
+ *
+ * Update the default state_table for this CPU-id
+ */
+
+static void intel_idle_state_table_update(void)
+{
+	switch (boot_cpu_data.x86_model) {
+
+	case 0x3e: /* IVT */
+		ivt_idle_state_table_update();
+		break;
+	case 0x5c: /* BXT */
+		bxt_idle_state_table_update();
+		break;
+	case 0x5e: /* SKL-H */
+		sklh_idle_state_table_update();
+		break;
 	}
-	return;
 }
 
 /*
@@ -1063,6 +1281,14 @@ static int __init intel_idle_cpuidle_dri
 		if (num_substates == 0)
 			continue;
 
+		/* if state marked as disabled, skip it */
+		if (cpuidle_state_table[cstate].disabled != 0) {
+			pr_debug(PREFIX "state %s is disabled",
+				cpuidle_state_table[cstate].name);
+			continue;
+		}
+
+
 		if (((mwait_cstate + 1) > 2) &&
 			!boot_cpu_has(X86_FEATURE_NONSTOP_TSC))
 			mark_tsc_unstable("TSC halts in idle"
--- zfcpdump-kernel-4.4.orig/drivers/iio/accel/Kconfig
+++ zfcpdump-kernel-4.4/drivers/iio/accel/Kconfig
@@ -173,6 +173,7 @@ config STK8312
 config STK8BA50
 	tristate "Sensortek STK8BA50 3-Axis Accelerometer Driver"
 	depends on I2C
+	depends on IIO_TRIGGER
 	help
 	  Say yes here to get support for the Sensortek STK8BA50 3-axis
 	  accelerometer.
--- zfcpdump-kernel-4.4.orig/drivers/iio/accel/bmc150-accel-core.c
+++ zfcpdump-kernel-4.4/drivers/iio/accel/bmc150-accel-core.c
@@ -68,6 +68,9 @@
 #define BMC150_ACCEL_REG_PMU_BW		0x10
 #define BMC150_ACCEL_DEF_BW			125
 
+#define BMC150_ACCEL_REG_RESET			0x14
+#define BMC150_ACCEL_RESET_VAL			0xB6
+
 #define BMC150_ACCEL_REG_INT_MAP_0		0x19
 #define BMC150_ACCEL_INT_MAP_0_BIT_SLOPE	BIT(2)
 
@@ -547,7 +550,7 @@ static int bmc150_accel_get_axis(struct
 {
 	int ret;
 	int axis = chan->scan_index;
-	unsigned int raw_val;
+	__le16 raw_val;
 
 	mutex_lock(&data->mutex);
 	ret = bmc150_accel_set_power_state(data, true);
@@ -557,14 +560,14 @@ static int bmc150_accel_get_axis(struct
 	}
 
 	ret = regmap_bulk_read(data->regmap, BMC150_ACCEL_AXIS_TO_REG(axis),
-			       &raw_val, 2);
+			       &raw_val, sizeof(raw_val));
 	if (ret < 0) {
 		dev_err(data->dev, "Error reading axis %d\n", axis);
 		bmc150_accel_set_power_state(data, false);
 		mutex_unlock(&data->mutex);
 		return ret;
 	}
-	*val = sign_extend32(raw_val >> chan->scan_type.shift,
+	*val = sign_extend32(le16_to_cpu(raw_val) >> chan->scan_type.shift,
 			     chan->scan_type.realbits - 1);
 	ret = bmc150_accel_set_power_state(data, false);
 	mutex_unlock(&data->mutex);
@@ -988,6 +991,7 @@ static const struct iio_event_spec bmc15
 		.realbits = (bits),					\
 		.storagebits = 16,					\
 		.shift = 16 - (bits),					\
+		.endianness = IIO_LE,					\
 	},								\
 	.event_spec = &bmc150_accel_event,				\
 	.num_event_specs = 1						\
@@ -1486,6 +1490,14 @@ static int bmc150_accel_chip_init(struct
 	int ret, i;
 	unsigned int val;
 
+	/*
+	 * Reset chip to get it in a known good state. A delay of 1.8ms after
+	 * reset is required according to the data sheets of supported chips.
+	 */
+	regmap_write(data->regmap, BMC150_ACCEL_REG_RESET,
+		     BMC150_ACCEL_RESET_VAL);
+	usleep_range(1800, 2500);
+
 	ret = regmap_read(data->regmap, BMC150_ACCEL_REG_CHIP_ID, &val);
 	if (ret < 0) {
 		dev_err(data->dev,
--- zfcpdump-kernel-4.4.orig/drivers/iio/accel/kxsd9.c
+++ zfcpdump-kernel-4.4/drivers/iio/accel/kxsd9.c
@@ -81,7 +81,7 @@ static int kxsd9_write_scale(struct iio_
 
 	mutex_lock(&st->buf_lock);
 	ret = spi_w8r8(st->us, KXSD9_READ(KXSD9_REG_CTRL_C));
-	if (ret)
+	if (ret < 0)
 		goto error_ret;
 	st->tx[0] = KXSD9_WRITE(KXSD9_REG_CTRL_C);
 	st->tx[1] = (ret & ~KXSD9_FS_MASK) | i;
@@ -160,11 +160,13 @@ static int kxsd9_read_raw(struct iio_dev
 		if (ret < 0)
 			goto error_ret;
 		*val = ret;
+		ret = IIO_VAL_INT;
 		break;
 	case IIO_CHAN_INFO_SCALE:
 		ret = spi_w8r8(st->us, KXSD9_READ(KXSD9_REG_CTRL_C));
-		if (ret)
+		if (ret < 0)
 			goto error_ret;
+		*val = 0;
 		*val2 = kxsd9_micro_scales[ret & KXSD9_FS_MASK];
 		ret = IIO_VAL_INT_PLUS_MICRO;
 		break;
--- zfcpdump-kernel-4.4.orig/drivers/iio/adc/Kconfig
+++ zfcpdump-kernel-4.4/drivers/iio/adc/Kconfig
@@ -306,6 +306,7 @@ config QCOM_SPMI_VADC
 config ROCKCHIP_SARADC
 	tristate "Rockchip SARADC driver"
 	depends on ARCH_ROCKCHIP || (ARM && COMPILE_TEST)
+	depends on RESET_CONTROLLER
 	help
 	  Say yes here to build support for the SARADC found in SoCs from
 	  Rockchip.
@@ -372,6 +373,7 @@ config TWL6030_GPADC
 config VF610_ADC
 	tristate "Freescale vf610 ADC driver"
 	depends on OF
+	depends on HAS_IOMEM
 	select IIO_BUFFER
 	select IIO_TRIGGERED_BUFFER
 	help
--- zfcpdump-kernel-4.4.orig/drivers/iio/adc/ad7266.c
+++ zfcpdump-kernel-4.4/drivers/iio/adc/ad7266.c
@@ -396,8 +396,8 @@ static int ad7266_probe(struct spi_devic
 
 	st = iio_priv(indio_dev);
 
-	st->reg = devm_regulator_get(&spi->dev, "vref");
-	if (!IS_ERR_OR_NULL(st->reg)) {
+	st->reg = devm_regulator_get_optional(&spi->dev, "vref");
+	if (!IS_ERR(st->reg)) {
 		ret = regulator_enable(st->reg);
 		if (ret)
 			return ret;
@@ -408,6 +408,9 @@ static int ad7266_probe(struct spi_devic
 
 		st->vref_mv = ret / 1000;
 	} else {
+		/* Any other error indicates that the regulator does exist */
+		if (PTR_ERR(st->reg) != -ENODEV)
+			return PTR_ERR(st->reg);
 		/* Use internal reference */
 		st->vref_mv = 2500;
 	}
--- zfcpdump-kernel-4.4.orig/drivers/iio/adc/ad799x.c
+++ zfcpdump-kernel-4.4/drivers/iio/adc/ad799x.c
@@ -533,6 +533,7 @@ static struct attribute_group ad799x_eve
 static const struct iio_info ad7991_info = {
 	.read_raw = &ad799x_read_raw,
 	.driver_module = THIS_MODULE,
+	.update_scan_mode = ad799x_update_scan_mode,
 };
 
 static const struct iio_info ad7993_4_7_8_noirq_info = {
--- zfcpdump-kernel-4.4.orig/drivers/iio/adc/at91_adc.c
+++ zfcpdump-kernel-4.4/drivers/iio/adc/at91_adc.c
@@ -381,8 +381,8 @@ static irqreturn_t at91_adc_rl_interrupt
 		st->ts_bufferedmeasure = false;
 		input_report_key(st->ts_input, BTN_TOUCH, 0);
 		input_sync(st->ts_input);
-	} else if (status & AT91_ADC_EOC(3)) {
-		/* Conversion finished */
+	} else if (status & AT91_ADC_EOC(3) && st->ts_input) {
+		/* Conversion finished and we've a touchscreen */
 		if (st->ts_bufferedmeasure) {
 			/*
 			 * Last measurement is always discarded, since it can
--- zfcpdump-kernel-4.4.orig/drivers/iio/adc/rockchip_saradc.c
+++ zfcpdump-kernel-4.4/drivers/iio/adc/rockchip_saradc.c
@@ -21,6 +21,8 @@
 #include <linux/of_device.h>
 #include <linux/clk.h>
 #include <linux/completion.h>
+#include <linux/delay.h>
+#include <linux/reset.h>
 #include <linux/regulator/consumer.h>
 #include <linux/iio/iio.h>
 
@@ -53,6 +55,7 @@ struct rockchip_saradc {
 	struct clk		*clk;
 	struct completion	completion;
 	struct regulator	*vref;
+	struct reset_control	*reset;
 	const struct rockchip_saradc_data *data;
 	u16			last_val;
 };
@@ -171,6 +174,16 @@ static const struct of_device_id rockchi
 };
 MODULE_DEVICE_TABLE(of, rockchip_saradc_match);
 
+/**
+ * Reset SARADC Controller.
+ */
+static void rockchip_saradc_reset_controller(struct reset_control *reset)
+{
+	reset_control_assert(reset);
+	usleep_range(10, 20);
+	reset_control_deassert(reset);
+}
+
 static int rockchip_saradc_probe(struct platform_device *pdev)
 {
 	struct rockchip_saradc *info = NULL;
@@ -199,6 +212,20 @@ static int rockchip_saradc_probe(struct
 	if (IS_ERR(info->regs))
 		return PTR_ERR(info->regs);
 
+	/*
+	 * The reset should be an optional property, as it should work
+	 * with old devicetrees as well
+	 */
+	info->reset = devm_reset_control_get(&pdev->dev, "saradc-apb");
+	if (IS_ERR(info->reset)) {
+		ret = PTR_ERR(info->reset);
+		if (ret != -ENOENT)
+			return ret;
+
+		dev_dbg(&pdev->dev, "no reset control found\n");
+		info->reset = NULL;
+	}
+
 	init_completion(&info->completion);
 
 	irq = platform_get_irq(pdev, 0);
@@ -233,6 +260,9 @@ static int rockchip_saradc_probe(struct
 		return PTR_ERR(info->vref);
 	}
 
+	if (info->reset)
+		rockchip_saradc_reset_controller(info->reset);
+
 	/*
 	 * Use a default value for the converter clock.
 	 * This may become user-configurable in the future.
--- zfcpdump-kernel-4.4.orig/drivers/iio/adc/ti_am335x_adc.c
+++ zfcpdump-kernel-4.4/drivers/iio/adc/ti_am335x_adc.c
@@ -32,6 +32,7 @@
 
 struct tiadc_device {
 	struct ti_tscadc_dev *mfd_tscadc;
+	struct mutex fifo1_lock; /* to protect fifo access */
 	int channels;
 	u8 channel_line[8];
 	u8 channel_step[8];
@@ -289,7 +290,7 @@ static int tiadc_iio_buffered_hardware_s
 		goto error_kfifo_free;
 
 	indio_dev->setup_ops = setup_ops;
-	indio_dev->modes |= INDIO_BUFFER_HARDWARE;
+	indio_dev->modes |= INDIO_BUFFER_SOFTWARE;
 
 	return 0;
 
@@ -360,6 +361,7 @@ static int tiadc_read_raw(struct iio_dev
 		int *val, int *val2, long mask)
 {
 	struct tiadc_device *adc_dev = iio_priv(indio_dev);
+	int ret = IIO_VAL_INT;
 	int i, map_val;
 	unsigned int fifo1count, read, stepid;
 	bool found = false;
@@ -373,13 +375,14 @@ static int tiadc_read_raw(struct iio_dev
 	if (!step_en)
 		return -EINVAL;
 
+	mutex_lock(&adc_dev->fifo1_lock);
 	fifo1count = tiadc_readl(adc_dev, REG_FIFO1CNT);
 	while (fifo1count--)
 		tiadc_readl(adc_dev, REG_FIFO1);
 
 	am335x_tsc_se_set_once(adc_dev->mfd_tscadc, step_en);
 
-	timeout = jiffies + usecs_to_jiffies
+	timeout = jiffies + msecs_to_jiffies
 				(IDLE_TIMEOUT * adc_dev->channels);
 	/* Wait for Fifo threshold interrupt */
 	while (1) {
@@ -389,7 +392,8 @@ static int tiadc_read_raw(struct iio_dev
 
 		if (time_after(jiffies, timeout)) {
 			am335x_tsc_se_adc_done(adc_dev->mfd_tscadc);
-			return -EAGAIN;
+			ret = -EAGAIN;
+			goto err_unlock;
 		}
 	}
 	map_val = adc_dev->channel_step[chan->scan_index];
@@ -415,8 +419,11 @@ static int tiadc_read_raw(struct iio_dev
 	am335x_tsc_se_adc_done(adc_dev->mfd_tscadc);
 
 	if (found == false)
-		return -EBUSY;
-	return IIO_VAL_INT;
+		ret =  -EBUSY;
+
+err_unlock:
+	mutex_unlock(&adc_dev->fifo1_lock);
+	return ret;
 }
 
 static const struct iio_info tiadc_info = {
@@ -485,6 +492,7 @@ static int tiadc_probe(struct platform_d
 
 	tiadc_step_config(indio_dev);
 	tiadc_writel(adc_dev, REG_FIFO1THR, FIFO1_THRESHOLD);
+	mutex_init(&adc_dev->fifo1_lock);
 
 	err = tiadc_channel_init(indio_dev, adc_dev->channels);
 	if (err < 0)
--- zfcpdump-kernel-4.4.orig/drivers/iio/common/hid-sensors/hid-sensor-attributes.c
+++ zfcpdump-kernel-4.4/drivers/iio/common/hid-sensors/hid-sensor-attributes.c
@@ -56,8 +56,8 @@ static struct {
 	{HID_USAGE_SENSOR_ALS, 0, 1, 0},
 	{HID_USAGE_SENSOR_ALS, HID_USAGE_SENSOR_UNITS_LUX, 1, 0},
 
-	{HID_USAGE_SENSOR_PRESSURE, 0, 100000, 0},
-	{HID_USAGE_SENSOR_PRESSURE, HID_USAGE_SENSOR_UNITS_PASCAL, 1, 0},
+	{HID_USAGE_SENSOR_PRESSURE, 0, 100, 0},
+	{HID_USAGE_SENSOR_PRESSURE, HID_USAGE_SENSOR_UNITS_PASCAL, 0, 1000},
 };
 
 static int pow_10(unsigned power)
--- zfcpdump-kernel-4.4.orig/drivers/iio/dac/mcp4725.c
+++ zfcpdump-kernel-4.4/drivers/iio/dac/mcp4725.c
@@ -300,6 +300,7 @@ static int mcp4725_probe(struct i2c_clie
 	data->client = client;
 
 	indio_dev->dev.parent = &client->dev;
+	indio_dev->name = id->name;
 	indio_dev->info = &mcp4725_info;
 	indio_dev->channels = &mcp4725_channel;
 	indio_dev->num_channels = 1;
--- zfcpdump-kernel-4.4.orig/drivers/iio/gyro/bmg160_core.c
+++ zfcpdump-kernel-4.4/drivers/iio/gyro/bmg160_core.c
@@ -452,7 +452,7 @@ static int bmg160_get_temp(struct bmg160
 static int bmg160_get_axis(struct bmg160_data *data, int axis, int *val)
 {
 	int ret;
-	unsigned int raw_val;
+	__le16 raw_val;
 
 	mutex_lock(&data->mutex);
 	ret = bmg160_set_power_state(data, true);
@@ -462,7 +462,7 @@ static int bmg160_get_axis(struct bmg160
 	}
 
 	ret = regmap_bulk_read(data->regmap, BMG160_AXIS_TO_REG(axis), &raw_val,
-			       2);
+			       sizeof(raw_val));
 	if (ret < 0) {
 		dev_err(data->dev, "Error reading axis %d\n", axis);
 		bmg160_set_power_state(data, false);
@@ -470,7 +470,7 @@ static int bmg160_get_axis(struct bmg160
 		return ret;
 	}
 
-	*val = sign_extend32(raw_val, 15);
+	*val = sign_extend32(le16_to_cpu(raw_val), 15);
 	ret = bmg160_set_power_state(data, false);
 	mutex_unlock(&data->mutex);
 	if (ret < 0)
@@ -733,6 +733,7 @@ static const struct iio_event_spec bmg16
 		.sign = 's',						\
 		.realbits = 16,					\
 		.storagebits = 16,					\
+		.endianness = IIO_LE,					\
 	},								\
 	.event_spec = &bmg160_event,					\
 	.num_event_specs = 1						\
@@ -780,7 +781,7 @@ static irqreturn_t bmg160_trigger_handle
 			mutex_unlock(&data->mutex);
 			goto err;
 		}
-		data->buffer[i++] = ret;
+		data->buffer[i++] = val;
 	}
 	mutex_unlock(&data->mutex);
 
--- zfcpdump-kernel-4.4.orig/drivers/iio/humidity/hdc100x.c
+++ zfcpdump-kernel-4.4/drivers/iio/humidity/hdc100x.c
@@ -55,7 +55,7 @@ static const struct {
 	},
 	{ /* IIO_HUMIDITYRELATIVE channel */
 		.shift = 8,
-		.mask = 2,
+		.mask = 3,
 	},
 };
 
@@ -164,14 +164,14 @@ static int hdc100x_get_measurement(struc
 		dev_err(&client->dev, "cannot read high byte measurement");
 		return ret;
 	}
-	val = ret << 6;
+	val = ret << 8;
 
 	ret = i2c_smbus_read_byte(client);
 	if (ret < 0) {
 		dev_err(&client->dev, "cannot read low byte measurement");
 		return ret;
 	}
-	val |= ret >> 2;
+	val |= ret;
 
 	return val;
 }
@@ -211,18 +211,18 @@ static int hdc100x_read_raw(struct iio_d
 		return IIO_VAL_INT_PLUS_MICRO;
 	case IIO_CHAN_INFO_SCALE:
 		if (chan->type == IIO_TEMP) {
-			*val = 165;
-			*val2 = 65536 >> 2;
+			*val = 165000;
+			*val2 = 65536;
 			return IIO_VAL_FRACTIONAL;
 		} else {
-			*val = 0;
-			*val2 = 10000;
-			return IIO_VAL_INT_PLUS_MICRO;
+			*val = 100;
+			*val2 = 65536;
+			return IIO_VAL_FRACTIONAL;
 		}
 		break;
 	case IIO_CHAN_INFO_OFFSET:
-		*val = -3971;
-		*val2 = 879096;
+		*val = -15887;
+		*val2 = 515151;
 		return IIO_VAL_INT_PLUS_MICRO;
 	default:
 		return -EINVAL;
--- zfcpdump-kernel-4.4.orig/drivers/iio/imu/adis_buffer.c
+++ zfcpdump-kernel-4.4/drivers/iio/imu/adis_buffer.c
@@ -43,7 +43,7 @@ int adis_update_scan_mode(struct iio_dev
 		return -ENOMEM;
 
 	rx = adis->buffer;
-	tx = rx + indio_dev->scan_bytes;
+	tx = rx + scan_count;
 
 	spi_message_init(&adis->msg);
 
--- zfcpdump-kernel-4.4.orig/drivers/iio/industrialio-buffer.c
+++ zfcpdump-kernel-4.4/drivers/iio/industrialio-buffer.c
@@ -107,9 +107,10 @@ ssize_t iio_buffer_read_first_n_outer(st
 {
 	struct iio_dev *indio_dev = filp->private_data;
 	struct iio_buffer *rb = indio_dev->buffer;
+	DEFINE_WAIT_FUNC(wait, woken_wake_function);
 	size_t datum_size;
 	size_t to_wait;
-	int ret;
+	int ret = 0;
 
 	if (!indio_dev->info)
 		return -ENODEV;
@@ -131,19 +132,29 @@ ssize_t iio_buffer_read_first_n_outer(st
 	else
 		to_wait = min_t(size_t, n / datum_size, rb->watermark);
 
+	add_wait_queue(&rb->pollq, &wait);
 	do {
-		ret = wait_event_interruptible(rb->pollq,
-		      iio_buffer_ready(indio_dev, rb, to_wait, n / datum_size));
-		if (ret)
-			return ret;
-
-		if (!indio_dev->info)
-			return -ENODEV;
+		if (!indio_dev->info) {
+			ret = -ENODEV;
+			break;
+		}
+
+		if (!iio_buffer_ready(indio_dev, rb, to_wait, n / datum_size)) {
+			if (signal_pending(current)) {
+				ret = -ERESTARTSYS;
+				break;
+			}
+
+			wait_woken(&wait, TASK_INTERRUPTIBLE,
+				   MAX_SCHEDULE_TIMEOUT);
+			continue;
+		}
 
 		ret = rb->access->read_first_n(rb, n, buf);
 		if (ret == 0 && (filp->f_flags & O_NONBLOCK))
 			ret = -EAGAIN;
-	 } while (ret == 0);
+	} while (ret == 0);
+	remove_wait_queue(&rb->pollq, &wait);
 
 	return ret;
 }
--- zfcpdump-kernel-4.4.orig/drivers/iio/industrialio-core.c
+++ zfcpdump-kernel-4.4/drivers/iio/industrialio-core.c
@@ -433,23 +433,21 @@ ssize_t iio_format_value(char *buf, unsi
 		scale_db = true;
 	case IIO_VAL_INT_PLUS_MICRO:
 		if (vals[1] < 0)
-			return sprintf(buf, "-%ld.%06u%s\n", abs(vals[0]),
-					-vals[1],
-				scale_db ? " dB" : "");
+			return sprintf(buf, "-%d.%06u%s\n", abs(vals[0]),
+				       -vals[1], scale_db ? " dB" : "");
 		else
 			return sprintf(buf, "%d.%06u%s\n", vals[0], vals[1],
 				scale_db ? " dB" : "");
 	case IIO_VAL_INT_PLUS_NANO:
 		if (vals[1] < 0)
-			return sprintf(buf, "-%ld.%09u\n", abs(vals[0]),
-					-vals[1]);
+			return sprintf(buf, "-%d.%09u\n", abs(vals[0]),
+				       -vals[1]);
 		else
 			return sprintf(buf, "%d.%09u\n", vals[0], vals[1]);
 	case IIO_VAL_FRACTIONAL:
 		tmp = div_s64((s64)vals[0] * 1000000000LL, vals[1]);
-		vals[1] = do_div(tmp, 1000000000LL);
-		vals[0] = tmp;
-		return sprintf(buf, "%d.%09u\n", vals[0], vals[1]);
+		vals[0] = (int)div_s64_rem(tmp, 1000000000, &vals[1]);
+		return sprintf(buf, "%d.%09u\n", vals[0], abs(vals[1]));
 	case IIO_VAL_FRACTIONAL_LOG2:
 		tmp = (s64)vals[0] * 1000000000LL >> vals[1];
 		vals[1] = do_div(tmp, 1000000000LL);
--- zfcpdump-kernel-4.4.orig/drivers/iio/industrialio-trigger.c
+++ zfcpdump-kernel-4.4/drivers/iio/industrialio-trigger.c
@@ -210,22 +210,35 @@ static int iio_trigger_attach_poll_func(
 
 	/* Prevent the module from being removed whilst attached to a trigger */
 	__module_get(pf->indio_dev->info->driver_module);
+
+	/* Get irq number */
 	pf->irq = iio_trigger_get_irq(trig);
+	if (pf->irq < 0)
+		goto out_put_module;
+
+	/* Request irq */
 	ret = request_threaded_irq(pf->irq, pf->h, pf->thread,
 				   pf->type, pf->name,
 				   pf);
-	if (ret < 0) {
-		module_put(pf->indio_dev->info->driver_module);
-		return ret;
-	}
+	if (ret < 0)
+		goto out_put_irq;
 
+	/* Enable trigger in driver */
 	if (trig->ops && trig->ops->set_trigger_state && notinuse) {
 		ret = trig->ops->set_trigger_state(trig, true);
 		if (ret < 0)
-			module_put(pf->indio_dev->info->driver_module);
+			goto out_free_irq;
 	}
 
 	return ret;
+
+out_free_irq:
+	free_irq(pf->irq, pf);
+out_put_irq:
+	iio_trigger_put_irq(trig, pf->irq);
+out_put_module:
+	module_put(pf->indio_dev->info->driver_module);
+	return ret;
 }
 
 static int iio_trigger_detach_poll_func(struct iio_trigger *trig,
--- zfcpdump-kernel-4.4.orig/drivers/iio/inkern.c
+++ zfcpdump-kernel-4.4/drivers/iio/inkern.c
@@ -351,6 +351,8 @@ EXPORT_SYMBOL_GPL(iio_channel_get);
 
 void iio_channel_release(struct iio_channel *channel)
 {
+	if (!channel)
+		return;
 	iio_device_put(channel->indio_dev);
 	kfree(channel);
 }
--- zfcpdump-kernel-4.4.orig/drivers/iio/light/acpi-als.c
+++ zfcpdump-kernel-4.4/drivers/iio/light/acpi-als.c
@@ -54,7 +54,9 @@ static const struct iio_chan_spec acpi_a
 			.realbits	= 32,
 			.storagebits	= 32,
 		},
-		.info_mask_separate	= BIT(IIO_CHAN_INFO_RAW),
+		/* _RAW is here for backward ABI compatibility */
+		.info_mask_separate	= BIT(IIO_CHAN_INFO_RAW) |
+					  BIT(IIO_CHAN_INFO_PROCESSED),
 	},
 };
 
@@ -152,7 +154,7 @@ static int acpi_als_read_raw(struct iio_
 	s32 temp_val;
 	int ret;
 
-	if (mask != IIO_CHAN_INFO_RAW)
+	if ((mask != IIO_CHAN_INFO_PROCESSED) && (mask != IIO_CHAN_INFO_RAW))
 		return -EINVAL;
 
 	/* we support only illumination (_ALI) so far. */
--- zfcpdump-kernel-4.4.orig/drivers/iio/light/apds9960.c
+++ zfcpdump-kernel-4.4/drivers/iio/light/apds9960.c
@@ -1005,6 +1005,7 @@ static int apds9960_probe(struct i2c_cli
 
 	iio_device_attach_buffer(indio_dev, buffer);
 
+	indio_dev->dev.parent = &client->dev;
 	indio_dev->info = &apds9960_info;
 	indio_dev->name = APDS9960_DRV_NAME;
 	indio_dev->channels = apds9960_channels;
--- zfcpdump-kernel-4.4.orig/drivers/iio/light/ltr501.c
+++ zfcpdump-kernel-4.4/drivers/iio/light/ltr501.c
@@ -180,7 +180,7 @@ static const struct ltr501_samp_table lt
 			{500000, 2000000}
 };
 
-static unsigned int ltr501_match_samp_freq(const struct ltr501_samp_table *tab,
+static int ltr501_match_samp_freq(const struct ltr501_samp_table *tab,
 					   int len, int val, int val2)
 {
 	int i, freq;
--- zfcpdump-kernel-4.4.orig/drivers/iio/magnetometer/ak8975.c
+++ zfcpdump-kernel-4.4/drivers/iio/magnetometer/ak8975.c
@@ -462,6 +462,8 @@ static int ak8975_setup_irq(struct ak897
 	int rc;
 	int irq;
 
+	init_waitqueue_head(&data->data_ready_queue);
+	clear_bit(0, &data->flags);
 	if (client->irq)
 		irq = client->irq;
 	else
@@ -477,8 +479,6 @@ static int ak8975_setup_irq(struct ak897
 		return rc;
 	}
 
-	init_waitqueue_head(&data->data_ready_queue);
-	clear_bit(0, &data->flags);
 	data->eoc_irq = irq;
 
 	return rc;
@@ -732,7 +732,7 @@ static int ak8975_probe(struct i2c_clien
 	int eoc_gpio;
 	int err;
 	const char *name = NULL;
-	enum asahi_compass_chipset chipset;
+	enum asahi_compass_chipset chipset = AK_MAX_TYPE;
 
 	/* Grab and set up the supplied GPIO. */
 	if (client->dev.platform_data)
--- zfcpdump-kernel-4.4.orig/drivers/iio/magnetometer/st_magn.h
+++ zfcpdump-kernel-4.4/drivers/iio/magnetometer/st_magn.h
@@ -44,6 +44,7 @@ static inline int st_magn_allocate_ring(
 static inline void st_magn_deallocate_ring(struct iio_dev *indio_dev)
 {
 }
+#define ST_MAGN_TRIGGER_SET_STATE NULL
 #endif /* CONFIG_IIO_BUFFER */
 
 #endif /* ST_MAGN_H */
--- zfcpdump-kernel-4.4.orig/drivers/iio/pressure/mpl115.c
+++ zfcpdump-kernel-4.4/drivers/iio/pressure/mpl115.c
@@ -117,7 +117,7 @@ static int mpl115_read_raw(struct iio_de
 		*val = ret >> 6;
 		return IIO_VAL_INT;
 	case IIO_CHAN_INFO_OFFSET:
-		*val = 605;
+		*val = -605;
 		*val2 = 750000;
 		return IIO_VAL_INT_PLUS_MICRO;
 	case IIO_CHAN_INFO_SCALE:
--- zfcpdump-kernel-4.4.orig/drivers/iio/pressure/st_pressure_core.c
+++ zfcpdump-kernel-4.4/drivers/iio/pressure/st_pressure_core.c
@@ -28,15 +28,21 @@
 #include <linux/iio/common/st_sensors.h>
 #include "st_pressure.h"
 
+#define MCELSIUS_PER_CELSIUS			1000
+
+/* Default pressure sensitivity */
 #define ST_PRESS_LSB_PER_MBAR			4096UL
 #define ST_PRESS_KPASCAL_NANO_SCALE		(100000000UL / \
 						 ST_PRESS_LSB_PER_MBAR)
+
+/* Default temperature sensitivity */
 #define ST_PRESS_LSB_PER_CELSIUS		480UL
-#define ST_PRESS_CELSIUS_NANO_SCALE		(1000000000UL / \
-						 ST_PRESS_LSB_PER_CELSIUS)
+#define ST_PRESS_MILLI_CELSIUS_OFFSET		42500UL
+
 #define ST_PRESS_NUMBER_DATA_CHANNELS		1
 
 /* FULLSCALE */
+#define ST_PRESS_FS_AVL_1100MB			1100
 #define ST_PRESS_FS_AVL_1260MB			1260
 
 #define ST_PRESS_1_OUT_XL_ADDR			0x28
@@ -54,18 +60,20 @@
 #define ST_PRESS_LPS331AP_PW_MASK		0x80
 #define ST_PRESS_LPS331AP_FS_ADDR		0x23
 #define ST_PRESS_LPS331AP_FS_MASK		0x30
-#define ST_PRESS_LPS331AP_FS_AVL_1260_VAL	0x00
-#define ST_PRESS_LPS331AP_FS_AVL_1260_GAIN	ST_PRESS_KPASCAL_NANO_SCALE
-#define ST_PRESS_LPS331AP_FS_AVL_TEMP_GAIN	ST_PRESS_CELSIUS_NANO_SCALE
 #define ST_PRESS_LPS331AP_BDU_ADDR		0x20
 #define ST_PRESS_LPS331AP_BDU_MASK		0x04
 #define ST_PRESS_LPS331AP_DRDY_IRQ_ADDR		0x22
 #define ST_PRESS_LPS331AP_DRDY_IRQ_INT1_MASK	0x04
 #define ST_PRESS_LPS331AP_DRDY_IRQ_INT2_MASK	0x20
 #define ST_PRESS_LPS331AP_MULTIREAD_BIT		true
-#define ST_PRESS_LPS331AP_TEMP_OFFSET		42500
 
 /* CUSTOM VALUES FOR LPS001WP SENSOR */
+
+/* LPS001WP pressure resolution */
+#define ST_PRESS_LPS001WP_LSB_PER_MBAR		16UL
+/* LPS001WP temperature resolution */
+#define ST_PRESS_LPS001WP_LSB_PER_CELSIUS	64UL
+
 #define ST_PRESS_LPS001WP_WAI_EXP		0xba
 #define ST_PRESS_LPS001WP_ODR_ADDR		0x20
 #define ST_PRESS_LPS001WP_ODR_MASK		0x30
@@ -74,6 +82,8 @@
 #define ST_PRESS_LPS001WP_ODR_AVL_13HZ_VAL	0x03
 #define ST_PRESS_LPS001WP_PW_ADDR		0x20
 #define ST_PRESS_LPS001WP_PW_MASK		0x40
+#define ST_PRESS_LPS001WP_FS_AVL_PRESS_GAIN \
+	(100000000UL / ST_PRESS_LPS001WP_LSB_PER_MBAR)
 #define ST_PRESS_LPS001WP_BDU_ADDR		0x20
 #define ST_PRESS_LPS001WP_BDU_MASK		0x04
 #define ST_PRESS_LPS001WP_MULTIREAD_BIT		true
@@ -90,18 +100,12 @@
 #define ST_PRESS_LPS25H_ODR_AVL_25HZ_VAL	0x04
 #define ST_PRESS_LPS25H_PW_ADDR			0x20
 #define ST_PRESS_LPS25H_PW_MASK			0x80
-#define ST_PRESS_LPS25H_FS_ADDR			0x00
-#define ST_PRESS_LPS25H_FS_MASK			0x00
-#define ST_PRESS_LPS25H_FS_AVL_1260_VAL		0x00
-#define ST_PRESS_LPS25H_FS_AVL_1260_GAIN	ST_PRESS_KPASCAL_NANO_SCALE
-#define ST_PRESS_LPS25H_FS_AVL_TEMP_GAIN	ST_PRESS_CELSIUS_NANO_SCALE
 #define ST_PRESS_LPS25H_BDU_ADDR		0x20
 #define ST_PRESS_LPS25H_BDU_MASK		0x04
 #define ST_PRESS_LPS25H_DRDY_IRQ_ADDR		0x23
 #define ST_PRESS_LPS25H_DRDY_IRQ_INT1_MASK	0x01
 #define ST_PRESS_LPS25H_DRDY_IRQ_INT2_MASK	0x10
 #define ST_PRESS_LPS25H_MULTIREAD_BIT		true
-#define ST_PRESS_LPS25H_TEMP_OFFSET		42500
 #define ST_PRESS_LPS25H_OUT_XL_ADDR		0x28
 #define ST_TEMP_LPS25H_OUT_L_ADDR		0x2b
 
@@ -153,7 +157,9 @@ static const struct iio_chan_spec st_pre
 			.storagebits = 16,
 			.endianness = IIO_LE,
 		},
-		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
+		.info_mask_separate =
+			BIT(IIO_CHAN_INFO_RAW) |
+			BIT(IIO_CHAN_INFO_SCALE),
 		.modified = 0,
 	},
 	{
@@ -169,7 +175,7 @@ static const struct iio_chan_spec st_pre
 		},
 		.info_mask_separate =
 			BIT(IIO_CHAN_INFO_RAW) |
-			BIT(IIO_CHAN_INFO_OFFSET),
+			BIT(IIO_CHAN_INFO_SCALE),
 		.modified = 0,
 	},
 	IIO_CHAN_SOFT_TIMESTAMP(1)
@@ -204,11 +210,14 @@ static const struct st_sensor_settings s
 			.addr = ST_PRESS_LPS331AP_FS_ADDR,
 			.mask = ST_PRESS_LPS331AP_FS_MASK,
 			.fs_avl = {
+				/*
+				 * Pressure and temperature sensitivity values
+				 * as defined in table 3 of LPS331AP datasheet.
+				 */
 				[0] = {
 					.num = ST_PRESS_FS_AVL_1260MB,
-					.value = ST_PRESS_LPS331AP_FS_AVL_1260_VAL,
-					.gain = ST_PRESS_LPS331AP_FS_AVL_1260_GAIN,
-					.gain2 = ST_PRESS_LPS331AP_FS_AVL_TEMP_GAIN,
+					.gain = ST_PRESS_KPASCAL_NANO_SCALE,
+					.gain2 = ST_PRESS_LSB_PER_CELSIUS,
 				},
 			},
 		},
@@ -248,7 +257,17 @@ static const struct st_sensor_settings s
 			.value_off = ST_SENSORS_DEFAULT_POWER_OFF_VALUE,
 		},
 		.fs = {
-			.addr = 0,
+			.fs_avl = {
+				/*
+				 * Pressure and temperature resolution values
+				 * as defined in table 3 of LPS001WP datasheet.
+				 */
+				[0] = {
+					.num = ST_PRESS_FS_AVL_1100MB,
+					.gain = ST_PRESS_LPS001WP_FS_AVL_PRESS_GAIN,
+					.gain2 = ST_PRESS_LPS001WP_LSB_PER_CELSIUS,
+				},
+			},
 		},
 		.bdu = {
 			.addr = ST_PRESS_LPS001WP_BDU_ADDR,
@@ -285,14 +304,15 @@ static const struct st_sensor_settings s
 			.value_off = ST_SENSORS_DEFAULT_POWER_OFF_VALUE,
 		},
 		.fs = {
-			.addr = ST_PRESS_LPS25H_FS_ADDR,
-			.mask = ST_PRESS_LPS25H_FS_MASK,
 			.fs_avl = {
+				/*
+				 * Pressure and temperature sensitivity values
+				 * as defined in table 3 of LPS25H datasheet.
+				 */
 				[0] = {
 					.num = ST_PRESS_FS_AVL_1260MB,
-					.value = ST_PRESS_LPS25H_FS_AVL_1260_VAL,
-					.gain = ST_PRESS_LPS25H_FS_AVL_1260_GAIN,
-					.gain2 = ST_PRESS_LPS25H_FS_AVL_TEMP_GAIN,
+					.gain = ST_PRESS_KPASCAL_NANO_SCALE,
+					.gain2 = ST_PRESS_LSB_PER_CELSIUS,
 				},
 			},
 		},
@@ -346,26 +366,26 @@ static int st_press_read_raw(struct iio_
 
 		return IIO_VAL_INT;
 	case IIO_CHAN_INFO_SCALE:
-		*val = 0;
-
 		switch (ch->type) {
 		case IIO_PRESSURE:
+			*val = 0;
 			*val2 = press_data->current_fullscale->gain;
-			break;
+			return IIO_VAL_INT_PLUS_NANO;
 		case IIO_TEMP:
+			*val = MCELSIUS_PER_CELSIUS;
 			*val2 = press_data->current_fullscale->gain2;
-			break;
+			return IIO_VAL_FRACTIONAL;
 		default:
 			err = -EINVAL;
 			goto read_error;
 		}
 
-		return IIO_VAL_INT_PLUS_NANO;
 	case IIO_CHAN_INFO_OFFSET:
 		switch (ch->type) {
 		case IIO_TEMP:
-			*val = 425;
-			*val2 = 10;
+			*val = ST_PRESS_MILLI_CELSIUS_OFFSET *
+			       press_data->current_fullscale->gain2;
+			*val2 = MCELSIUS_PER_CELSIUS;
 			break;
 		default:
 			err = -EINVAL;
--- zfcpdump-kernel-4.4.orig/drivers/iio/proximity/as3935.c
+++ zfcpdump-kernel-4.4/drivers/iio/proximity/as3935.c
@@ -64,6 +64,7 @@ struct as3935_state {
 	struct delayed_work work;
 
 	u32 tune_cap;
+	u8 buffer[16]; /* 8-bit data + 56-bit padding + 64-bit timestamp */
 	u8 buf[2] ____cacheline_aligned;
 };
 
@@ -72,7 +73,8 @@ static const struct iio_chan_spec as3935
 		.type           = IIO_PROXIMITY,
 		.info_mask_separate =
 			BIT(IIO_CHAN_INFO_RAW) |
-			BIT(IIO_CHAN_INFO_PROCESSED),
+			BIT(IIO_CHAN_INFO_PROCESSED) |
+			BIT(IIO_CHAN_INFO_SCALE),
 		.scan_index     = 0,
 		.scan_type = {
 			.sign           = 'u',
@@ -181,7 +183,12 @@ static int as3935_read_raw(struct iio_de
 		/* storm out of range */
 		if (*val == AS3935_DATA_MASK)
 			return -EINVAL;
-		*val *= 1000;
+
+		if (m == IIO_CHAN_INFO_PROCESSED)
+			*val *= 1000;
+		break;
+	case IIO_CHAN_INFO_SCALE:
+		*val = 1000;
 		break;
 	default:
 		return -EINVAL;
@@ -206,10 +213,10 @@ static irqreturn_t as3935_trigger_handle
 	ret = as3935_read(st, AS3935_DATA, &val);
 	if (ret)
 		goto err_read;
-	val &= AS3935_DATA_MASK;
-	val *= 1000;
 
-	iio_push_to_buffers_with_timestamp(indio_dev, &val, pf->timestamp);
+	st->buffer[0] = val & AS3935_DATA_MASK;
+	iio_push_to_buffers_with_timestamp(indio_dev, &st->buffer,
+					   pf->timestamp);
 err_read:
 	iio_trigger_notify_done(indio_dev->trig);
 
@@ -385,7 +392,7 @@ static int as3935_probe(struct spi_devic
 		return ret;
 	}
 
-	ret = iio_triggered_buffer_setup(indio_dev, NULL,
+	ret = iio_triggered_buffer_setup(indio_dev, iio_pollfunc_store_time,
 		&as3935_trigger_handler, NULL);
 
 	if (ret) {
--- zfcpdump-kernel-4.4.orig/drivers/infiniband/core/cm.c
+++ zfcpdump-kernel-4.4/drivers/infiniband/core/cm.c
@@ -782,11 +782,11 @@ static void cm_enter_timewait(struct cm_
 	wait_time = cm_convert_to_ms(cm_id_priv->av.timeout);
 
 	/* Check if the device started its remove_one */
-	spin_lock_irq(&cm.lock);
+	spin_lock_irqsave(&cm.lock, flags);
 	if (!cm_dev->going_down)
 		queue_delayed_work(cm.wq, &cm_id_priv->timewait_info->work.work,
 				   msecs_to_jiffies(wait_time));
-	spin_unlock_irq(&cm.lock);
+	spin_unlock_irqrestore(&cm.lock, flags);
 
 	cm_id_priv->timewait_info = NULL;
 }
@@ -3430,14 +3430,14 @@ static int cm_establish(struct ib_cm_id
 	work->cm_event.event = IB_CM_USER_ESTABLISHED;
 
 	/* Check if the device started its remove_one */
-	spin_lock_irq(&cm.lock);
+	spin_lock_irqsave(&cm.lock, flags);
 	if (!cm_dev->going_down) {
 		queue_delayed_work(cm.wq, &work->work, 0);
 	} else {
 		kfree(work);
 		ret = -ENODEV;
 	}
-	spin_unlock_irq(&cm.lock);
+	spin_unlock_irqrestore(&cm.lock, flags);
 
 out:
 	return ret;
--- zfcpdump-kernel-4.4.orig/drivers/infiniband/core/cma.c
+++ zfcpdump-kernel-4.4/drivers/infiniband/core/cma.c
@@ -453,7 +453,7 @@ static inline int cma_validate_port(stru
 	if ((dev_type != ARPHRD_INFINIBAND) && rdma_protocol_ib(device, port))
 		return ret;
 
-	if (dev_type == ARPHRD_ETHER)
+	if (dev_type == ARPHRD_ETHER && rdma_protocol_roce(device, port))
 		ndev = dev_get_by_index(&init_net, bound_if_index);
 
 	ret = ib_find_cached_gid_by_port(device, gid, port, ndev, NULL);
--- zfcpdump-kernel-4.4.orig/drivers/infiniband/core/iwpm_util.c
+++ zfcpdump-kernel-4.4/drivers/infiniband/core/iwpm_util.c
@@ -634,6 +634,7 @@ static int send_nlmsg_done(struct sk_buf
 	if (!(ibnl_put_msg(skb, &nlh, 0, 0, nl_client,
 			   RDMA_NL_IWPM_MAPINFO, NLM_F_MULTI))) {
 		pr_warn("%s Unable to put NLMSG_DONE\n", __func__);
+		dev_kfree_skb(skb);
 		return -ENOMEM;
 	}
 	nlh->nlmsg_type = NLMSG_DONE;
--- zfcpdump-kernel-4.4.orig/drivers/infiniband/core/multicast.c
+++ zfcpdump-kernel-4.4/drivers/infiniband/core/multicast.c
@@ -106,7 +106,6 @@ struct mcast_group {
 	atomic_t		refcount;
 	enum mcast_group_state	state;
 	struct ib_sa_query	*query;
-	int			query_id;
 	u16			pkey_index;
 	u8			leave_state;
 	int			retries;
@@ -339,11 +338,7 @@ static int send_join(struct mcast_group
 				       member->multicast.comp_mask,
 				       3000, GFP_KERNEL, join_handler, group,
 				       &group->query);
-	if (ret >= 0) {
-		group->query_id = ret;
-		ret = 0;
-	}
-	return ret;
+	return (ret > 0) ? 0 : ret;
 }
 
 static int send_leave(struct mcast_group *group, u8 leave_state)
@@ -363,11 +358,7 @@ static int send_leave(struct mcast_group
 				       IB_SA_MCMEMBER_REC_JOIN_STATE,
 				       3000, GFP_KERNEL, leave_handler,
 				       group, &group->query);
-	if (ret >= 0) {
-		group->query_id = ret;
-		ret = 0;
-	}
-	return ret;
+	return (ret > 0) ? 0 : ret;
 }
 
 static void join_group(struct mcast_group *group, struct mcast_member *member,
--- zfcpdump-kernel-4.4.orig/drivers/infiniband/core/sa_query.c
+++ zfcpdump-kernel-4.4/drivers/infiniband/core/sa_query.c
@@ -534,7 +534,7 @@ static int ib_nl_send_msg(struct ib_sa_q
 	data = ibnl_put_msg(skb, &nlh, query->seq, 0, RDMA_NL_LS,
 			    RDMA_NL_LS_OP_RESOLVE, NLM_F_REQUEST);
 	if (!data) {
-		kfree_skb(skb);
+		nlmsg_free(skb);
 		return -EMSGSIZE;
 	}
 
--- zfcpdump-kernel-4.4.orig/drivers/infiniband/core/ucm.c
+++ zfcpdump-kernel-4.4/drivers/infiniband/core/ucm.c
@@ -48,6 +48,7 @@
 
 #include <asm/uaccess.h>
 
+#include <rdma/ib.h>
 #include <rdma/ib_cm.h>
 #include <rdma/ib_user_cm.h>
 #include <rdma/ib_marshall.h>
@@ -1103,6 +1104,9 @@ static ssize_t ib_ucm_write(struct file
 	struct ib_ucm_cmd_hdr hdr;
 	ssize_t result;
 
+	if (WARN_ON_ONCE(!ib_safe_file_access(filp)))
+		return -EACCES;
+
 	if (len < sizeof(hdr))
 		return -EINVAL;
 
--- zfcpdump-kernel-4.4.orig/drivers/infiniband/core/ucma.c
+++ zfcpdump-kernel-4.4/drivers/infiniband/core/ucma.c
@@ -1574,6 +1574,9 @@ static ssize_t ucma_write(struct file *f
 	struct rdma_ucm_cmd_hdr hdr;
 	ssize_t ret;
 
+	if (WARN_ON_ONCE(!ib_safe_file_access(filp)))
+		return -EACCES;
+
 	if (len < sizeof(hdr))
 		return -EINVAL;
 
--- zfcpdump-kernel-4.4.orig/drivers/infiniband/core/uverbs.h
+++ zfcpdump-kernel-4.4/drivers/infiniband/core/uverbs.h
@@ -116,6 +116,7 @@ struct ib_uverbs_event_file {
 struct ib_uverbs_file {
 	struct kref				ref;
 	struct mutex				mutex;
+	struct mutex                            cleanup_mutex; /* protect cleanup */
 	struct ib_uverbs_device		       *device;
 	struct ib_ucontext		       *ucontext;
 	struct ib_event_handler			event_handler;
--- zfcpdump-kernel-4.4.orig/drivers/infiniband/core/uverbs_main.c
+++ zfcpdump-kernel-4.4/drivers/infiniband/core/uverbs_main.c
@@ -48,6 +48,8 @@
 
 #include <asm/uaccess.h>
 
+#include <rdma/ib.h>
+
 #include "uverbs.h"
 
 MODULE_AUTHOR("Roland Dreier");
@@ -682,6 +684,9 @@ static ssize_t ib_uverbs_write(struct fi
 	int srcu_key;
 	ssize_t ret;
 
+	if (WARN_ON_ONCE(!ib_safe_file_access(filp)))
+		return -EACCES;
+
 	if (count < sizeof hdr)
 		return -EINVAL;
 
@@ -917,6 +922,7 @@ static int ib_uverbs_open(struct inode *
 	file->async_file = NULL;
 	kref_init(&file->ref);
 	mutex_init(&file->mutex);
+	mutex_init(&file->cleanup_mutex);
 
 	filp->private_data = file;
 	kobject_get(&dev->kobj);
@@ -942,18 +948,20 @@ static int ib_uverbs_close(struct inode
 {
 	struct ib_uverbs_file *file = filp->private_data;
 	struct ib_uverbs_device *dev = file->device;
-	struct ib_ucontext *ucontext = NULL;
+
+	mutex_lock(&file->cleanup_mutex);
+	if (file->ucontext) {
+		ib_uverbs_cleanup_ucontext(file, file->ucontext);
+		file->ucontext = NULL;
+	}
+	mutex_unlock(&file->cleanup_mutex);
 
 	mutex_lock(&file->device->lists_mutex);
-	ucontext = file->ucontext;
-	file->ucontext = NULL;
 	if (!file->is_closed) {
 		list_del(&file->list);
 		file->is_closed = 1;
 	}
 	mutex_unlock(&file->device->lists_mutex);
-	if (ucontext)
-		ib_uverbs_cleanup_ucontext(file, ucontext);
 
 	if (file->async_file)
 		kref_put(&file->async_file->ref, ib_uverbs_release_event_file);
@@ -1167,22 +1175,30 @@ static void ib_uverbs_free_hw_resources(
 	mutex_lock(&uverbs_dev->lists_mutex);
 	while (!list_empty(&uverbs_dev->uverbs_file_list)) {
 		struct ib_ucontext *ucontext;
-
 		file = list_first_entry(&uverbs_dev->uverbs_file_list,
 					struct ib_uverbs_file, list);
 		file->is_closed = 1;
-		ucontext = file->ucontext;
 		list_del(&file->list);
-		file->ucontext = NULL;
 		kref_get(&file->ref);
 		mutex_unlock(&uverbs_dev->lists_mutex);
-		/* We must release the mutex before going ahead and calling
-		 * disassociate_ucontext. disassociate_ucontext might end up
-		 * indirectly calling uverbs_close, for example due to freeing
-		 * the resources (e.g mmput).
-		 */
+
 		ib_uverbs_event_handler(&file->event_handler, &event);
+
+		mutex_lock(&file->cleanup_mutex);
+		ucontext = file->ucontext;
+		file->ucontext = NULL;
+		mutex_unlock(&file->cleanup_mutex);
+
+		/* At this point ib_uverbs_close cannot be running
+		 * ib_uverbs_cleanup_ucontext
+		 */
 		if (ucontext) {
+			/* We must release the mutex before going ahead and
+			 * calling disassociate_ucontext. disassociate_ucontext
+			 * might end up indirectly calling uverbs_close,
+			 * for example due to freeing the resources
+			 * (e.g mmput).
+			 */
 			ib_dev->disassociate_ucontext(ucontext);
 			ib_uverbs_cleanup_ucontext(file, ucontext);
 		}
--- zfcpdump-kernel-4.4.orig/drivers/infiniband/hw/cxgb3/iwch_cm.c
+++ zfcpdump-kernel-4.4/drivers/infiniband/hw/cxgb3/iwch_cm.c
@@ -149,7 +149,7 @@ static int iwch_l2t_send(struct t3cdev *
 	error = l2t_send(tdev, skb, l2e);
 	if (error < 0)
 		kfree_skb(skb);
-	return error;
+	return error < 0 ? error : 0;
 }
 
 int iwch_cxgb3_ofld_send(struct t3cdev *tdev, struct sk_buff *skb)
@@ -165,7 +165,7 @@ int iwch_cxgb3_ofld_send(struct t3cdev *
 	error = cxgb3_ofld_send(tdev, skb);
 	if (error < 0)
 		kfree_skb(skb);
-	return error;
+	return error < 0 ? error : 0;
 }
 
 static void release_tid(struct t3cdev *tdev, u32 hwtid, struct sk_buff *skb)
--- zfcpdump-kernel-4.4.orig/drivers/infiniband/hw/cxgb4/cq.c
+++ zfcpdump-kernel-4.4/drivers/infiniband/hw/cxgb4/cq.c
@@ -162,7 +162,7 @@ static int create_cq(struct c4iw_rdev *r
 	cq->bar2_va = c4iw_bar2_addrs(rdev, cq->cqid, T4_BAR2_QTYPE_INGRESS,
 				      &cq->bar2_qid,
 				      user ? &cq->bar2_pa : NULL);
-	if (user && !cq->bar2_va) {
+	if (user && !cq->bar2_pa) {
 		pr_warn(MOD "%s: cqid %u not in BAR2 range.\n",
 			pci_name(rdev->lldi.pdev), cq->cqid);
 		ret = -EINVAL;
--- zfcpdump-kernel-4.4.orig/drivers/infiniband/hw/cxgb4/qp.c
+++ zfcpdump-kernel-4.4/drivers/infiniband/hw/cxgb4/qp.c
@@ -185,6 +185,10 @@ void __iomem *c4iw_bar2_addrs(struct c4i
 
 	if (pbar2_pa)
 		*pbar2_pa = (rdev->bar2_pa + bar2_qoffset) & PAGE_MASK;
+
+	if (is_t4(rdev->lldi.adapter_type))
+		return NULL;
+
 	return rdev->bar2_kva + bar2_qoffset;
 }
 
@@ -270,7 +274,7 @@ static int create_qp(struct c4iw_rdev *r
 	/*
 	 * User mode must have bar2 access.
 	 */
-	if (user && (!wq->sq.bar2_va || !wq->rq.bar2_va)) {
+	if (user && (!wq->sq.bar2_pa || !wq->rq.bar2_pa)) {
 		pr_warn(MOD "%s: sqid %u or rqid %u not in BAR2 range.\n",
 			pci_name(rdev->lldi.pdev), wq->sq.qid, wq->rq.qid);
 		goto free_dma;
--- zfcpdump-kernel-4.4.orig/drivers/infiniband/hw/mlx4/ah.c
+++ zfcpdump-kernel-4.4/drivers/infiniband/hw/mlx4/ah.c
@@ -47,6 +47,7 @@ static struct ib_ah *create_ib_ah(struct
 
 	ah->av.ib.port_pd = cpu_to_be32(to_mpd(pd)->pdn | (ah_attr->port_num << 24));
 	ah->av.ib.g_slid  = ah_attr->src_path_bits;
+	ah->av.ib.sl_tclass_flowlabel = cpu_to_be32(ah_attr->sl << 28);
 	if (ah_attr->ah_flags & IB_AH_GRH) {
 		ah->av.ib.g_slid   |= 0x80;
 		ah->av.ib.gid_index = ah_attr->grh.sgid_index;
@@ -64,7 +65,6 @@ static struct ib_ah *create_ib_ah(struct
 		       !(1 << ah->av.ib.stat_rate & dev->caps.stat_rate_support))
 			--ah->av.ib.stat_rate;
 	}
-	ah->av.ib.sl_tclass_flowlabel = cpu_to_be32(ah_attr->sl << 28);
 
 	return &ah->ibah;
 }
--- zfcpdump-kernel-4.4.orig/drivers/infiniband/hw/mlx4/mad.c
+++ zfcpdump-kernel-4.4/drivers/infiniband/hw/mlx4/mad.c
@@ -526,7 +526,7 @@ int mlx4_ib_send_to_slave(struct mlx4_ib
 		tun_tx_ix = (++tun_qp->tx_ix_head) & (MLX4_NUM_TUNNEL_BUFS - 1);
 	spin_unlock(&tun_qp->tx_lock);
 	if (ret)
-		goto out;
+		goto end;
 
 	tun_mad = (struct mlx4_rcv_tunnel_mad *) (tun_qp->tx_ring[tun_tx_ix].buf.addr);
 	if (tun_qp->tx_ring[tun_tx_ix].ah)
@@ -595,9 +595,15 @@ int mlx4_ib_send_to_slave(struct mlx4_ib
 	wr.wr.send_flags = IB_SEND_SIGNALED;
 
 	ret = ib_post_send(src_qp, &wr.wr, &bad_wr);
-out:
-	if (ret)
-		ib_destroy_ah(ah);
+	if (!ret)
+		return 0;
+ out:
+	spin_lock(&tun_qp->tx_lock);
+	tun_qp->tx_ix_tail++;
+	spin_unlock(&tun_qp->tx_lock);
+	tun_qp->tx_ring[tun_tx_ix].ah = NULL;
+end:
+	ib_destroy_ah(ah);
 	return ret;
 }
 
@@ -1074,6 +1080,27 @@ void handle_port_mgmt_change_event(struc
 
 		/* Generate GUID changed event */
 		if (changed_attr & MLX4_EQ_PORT_INFO_GID_PFX_CHANGE_MASK) {
+			if (mlx4_is_master(dev->dev)) {
+				union ib_gid gid;
+				int err = 0;
+
+				if (!eqe->event.port_mgmt_change.params.port_info.gid_prefix)
+					err = __mlx4_ib_query_gid(&dev->ib_dev, port, 0, &gid, 1);
+				else
+					gid.global.subnet_prefix =
+						eqe->event.port_mgmt_change.params.port_info.gid_prefix;
+				if (err) {
+					pr_warn("Could not change QP1 subnet prefix for port %d: query_gid error (%d)\n",
+						port, err);
+				} else {
+					pr_debug("Changing QP1 subnet prefix for port %d. old=0x%llx. new=0x%llx\n",
+						 port,
+						 (u64)atomic64_read(&dev->sriov.demux[port - 1].subnet_prefix),
+						 be64_to_cpu(gid.global.subnet_prefix));
+					atomic64_set(&dev->sriov.demux[port - 1].subnet_prefix,
+						     be64_to_cpu(gid.global.subnet_prefix));
+				}
+			}
 			mlx4_ib_dispatch_event(dev, port, IB_EVENT_GID_CHANGE);
 			/*if master, notify all slaves*/
 			if (mlx4_is_master(dev->dev))
@@ -1278,9 +1305,15 @@ int mlx4_ib_send_to_wire(struct mlx4_ib_
 
 
 	ret = ib_post_send(send_qp, &wr.wr, &bad_wr);
+	if (!ret)
+		return 0;
+
+	spin_lock(&sqp->tx_lock);
+	sqp->tx_ix_tail++;
+	spin_unlock(&sqp->tx_lock);
+	sqp->tx_ring[wire_tx_ix].ah = NULL;
 out:
-	if (ret)
-		ib_destroy_ah(ah);
+	ib_destroy_ah(ah);
 	return ret;
 }
 
@@ -2142,6 +2175,8 @@ int mlx4_ib_init_sriov(struct mlx4_ib_de
 		if (err)
 			goto demux_err;
 		dev->sriov.demux[i].guid_cache[0] = gid.global.interface_id;
+		atomic64_set(&dev->sriov.demux[i].subnet_prefix,
+			     be64_to_cpu(gid.global.subnet_prefix));
 		err = alloc_pv_object(dev, mlx4_master_func_num(dev->dev), i + 1,
 				      &dev->sriov.sqps[i]);
 		if (err)
--- zfcpdump-kernel-4.4.orig/drivers/infiniband/hw/mlx4/mcg.c
+++ zfcpdump-kernel-4.4/drivers/infiniband/hw/mlx4/mcg.c
@@ -489,7 +489,7 @@ static u8 get_leave_state(struct mcast_g
 		if (!group->members[i])
 			leave_state |= (1 << i);
 
-	return leave_state & (group->rec.scope_join_state & 7);
+	return leave_state & (group->rec.scope_join_state & 0xf);
 }
 
 static int join_group(struct mcast_group *group, int slave, u8 join_mask)
@@ -564,8 +564,8 @@ static void mlx4_ib_mcg_timeout_handler(
 		} else
 			mcg_warn_group(group, "DRIVER BUG\n");
 	} else if (group->state == MCAST_LEAVE_SENT) {
-		if (group->rec.scope_join_state & 7)
-			group->rec.scope_join_state &= 0xf8;
+		if (group->rec.scope_join_state & 0xf)
+			group->rec.scope_join_state &= 0xf0;
 		group->state = MCAST_IDLE;
 		mutex_unlock(&group->lock);
 		if (release_group(group, 1))
@@ -605,7 +605,7 @@ static int handle_leave_req(struct mcast
 static int handle_join_req(struct mcast_group *group, u8 join_mask,
 			   struct mcast_req *req)
 {
-	u8 group_join_state = group->rec.scope_join_state & 7;
+	u8 group_join_state = group->rec.scope_join_state & 0xf;
 	int ref = 0;
 	u16 status;
 	struct ib_sa_mcmember_data *sa_data = (struct ib_sa_mcmember_data *)req->sa_mad.data;
@@ -690,8 +690,8 @@ static void mlx4_ib_mcg_work_handler(str
 			u8 cur_join_state;
 
 			resp_join_state = ((struct ib_sa_mcmember_data *)
-						group->response_sa_mad.data)->scope_join_state & 7;
-			cur_join_state = group->rec.scope_join_state & 7;
+						group->response_sa_mad.data)->scope_join_state & 0xf;
+			cur_join_state = group->rec.scope_join_state & 0xf;
 
 			if (method == IB_MGMT_METHOD_GET_RESP) {
 				/* successfull join */
@@ -710,7 +710,7 @@ process_requests:
 		req = list_first_entry(&group->pending_list, struct mcast_req,
 				       group_list);
 		sa_data = (struct ib_sa_mcmember_data *)req->sa_mad.data;
-		req_join_state = sa_data->scope_join_state & 0x7;
+		req_join_state = sa_data->scope_join_state & 0xf;
 
 		/* For a leave request, we will immediately answer the VF, and
 		 * update our internal counters. The actual leave will be sent
--- zfcpdump-kernel-4.4.orig/drivers/infiniband/hw/mlx4/mlx4_ib.h
+++ zfcpdump-kernel-4.4/drivers/infiniband/hw/mlx4/mlx4_ib.h
@@ -441,7 +441,7 @@ struct mlx4_ib_demux_ctx {
 	struct workqueue_struct *wq;
 	struct workqueue_struct *ud_wq;
 	spinlock_t ud_lock;
-	__be64 subnet_prefix;
+	atomic64_t subnet_prefix;
 	__be64 guid_cache[128];
 	struct mlx4_ib_dev *dev;
 	/* the following lock protects both mcg_table and mcg_mgid0_list */
--- zfcpdump-kernel-4.4.orig/drivers/infiniband/hw/mlx4/qp.c
+++ zfcpdump-kernel-4.4/drivers/infiniband/hw/mlx4/qp.c
@@ -357,7 +357,7 @@ static int send_wqe_overhead(enum mlx4_i
 			sizeof (struct mlx4_wqe_raddr_seg);
 	case MLX4_IB_QPT_RC:
 		return sizeof (struct mlx4_wqe_ctrl_seg) +
-			sizeof (struct mlx4_wqe_atomic_seg) +
+			sizeof (struct mlx4_wqe_masked_atomic_seg) +
 			sizeof (struct mlx4_wqe_raddr_seg);
 	case MLX4_IB_QPT_SMI:
 	case MLX4_IB_QPT_GSI:
@@ -1162,8 +1162,10 @@ struct ib_qp *mlx4_ib_create_qp(struct i
 	{
 		err = create_qp_common(to_mdev(pd->device), pd, init_attr,
 				       udata, 0, &qp, gfp);
-		if (err)
+		if (err) {
+			kfree(qp);
 			return ERR_PTR(err);
+		}
 
 		qp->ibqp.qp_num = qp->mqp.qpn;
 		qp->xrcdn = xrcdn;
@@ -1591,9 +1593,12 @@ static int __mlx4_ib_modify_qp(struct ib
 	}
 
 	if (qp->ibqp.uobject)
-		context->usr_page = cpu_to_be32(to_mucontext(ibqp->uobject->context)->uar.index);
+		context->usr_page = cpu_to_be32(
+			mlx4_to_hw_uar_index(dev->dev,
+					     to_mucontext(ibqp->uobject->context)->uar.index));
 	else
-		context->usr_page = cpu_to_be32(dev->priv_uar.index);
+		context->usr_page = cpu_to_be32(
+			mlx4_to_hw_uar_index(dev->dev, dev->priv_uar.index));
 
 	if (attr_mask & IB_QP_DEST_QPN)
 		context->remote_qpn = cpu_to_be32(attr->dest_qp_num);
@@ -2329,24 +2334,27 @@ static int build_mlx_header(struct mlx4_
 		sqp->ud_header.grh.flow_label    =
 			ah->av.ib.sl_tclass_flowlabel & cpu_to_be32(0xfffff);
 		sqp->ud_header.grh.hop_limit     = ah->av.ib.hop_limit;
-		if (is_eth)
+		if (is_eth) {
 			memcpy(sqp->ud_header.grh.source_gid.raw, sgid.raw, 16);
-		else {
-		if (mlx4_is_mfunc(to_mdev(ib_dev)->dev)) {
-			/* When multi-function is enabled, the ib_core gid
-			 * indexes don't necessarily match the hw ones, so
-			 * we must use our own cache */
-			sqp->ud_header.grh.source_gid.global.subnet_prefix =
-				to_mdev(ib_dev)->sriov.demux[sqp->qp.port - 1].
-						       subnet_prefix;
-			sqp->ud_header.grh.source_gid.global.interface_id =
-				to_mdev(ib_dev)->sriov.demux[sqp->qp.port - 1].
-					       guid_cache[ah->av.ib.gid_index];
-		} else
-			ib_get_cached_gid(ib_dev,
-					  be32_to_cpu(ah->av.ib.port_pd) >> 24,
-					  ah->av.ib.gid_index,
-					  &sqp->ud_header.grh.source_gid, NULL);
+		} else {
+			if (mlx4_is_mfunc(to_mdev(ib_dev)->dev)) {
+				/* When multi-function is enabled, the ib_core gid
+				 * indexes don't necessarily match the hw ones, so
+				 * we must use our own cache
+				 */
+				sqp->ud_header.grh.source_gid.global.subnet_prefix =
+					cpu_to_be64(atomic64_read(&(to_mdev(ib_dev)->sriov.
+								    demux[sqp->qp.port - 1].
+								    subnet_prefix)));
+				sqp->ud_header.grh.source_gid.global.interface_id =
+					to_mdev(ib_dev)->sriov.demux[sqp->qp.port - 1].
+						       guid_cache[ah->av.ib.gid_index];
+			} else {
+				ib_get_cached_gid(ib_dev,
+						  be32_to_cpu(ah->av.ib.port_pd) >> 24,
+						  ah->av.ib.gid_index,
+						  &sqp->ud_header.grh.source_gid, NULL);
+			}
 		}
 		memcpy(sqp->ud_header.grh.destination_gid.raw,
 		       ah->av.ib.dgid, 16);
--- zfcpdump-kernel-4.4.orig/drivers/infiniband/hw/mlx5/cq.c
+++ zfcpdump-kernel-4.4/drivers/infiniband/hw/mlx5/cq.c
@@ -756,14 +756,15 @@ struct ib_cq *mlx5_ib_create_cq(struct i
 	int uninitialized_var(index);
 	int uninitialized_var(inlen);
 	int cqe_size;
-	int irqn;
+	unsigned int irqn;
 	int eqn;
 	int err;
 
 	if (attr->flags)
 		return ERR_PTR(-EINVAL);
 
-	if (entries < 0)
+	if (entries < 0 ||
+	    (entries > (1 << MLX5_CAP_GEN(dev->mdev, log_max_cq_sz))))
 		return ERR_PTR(-EINVAL);
 
 	entries = roundup_pow_of_two(entries + 1);
@@ -1094,11 +1095,16 @@ int mlx5_ib_resize_cq(struct ib_cq *ibcq
 		return -ENOSYS;
 	}
 
-	if (entries < 1)
+	if (entries < 1 ||
+	    entries > (1 << MLX5_CAP_GEN(dev->mdev, log_max_cq_sz))) {
+		mlx5_ib_warn(dev, "wrong entries number %d, max %d\n",
+			     entries,
+			     1 << MLX5_CAP_GEN(dev->mdev, log_max_cq_sz));
 		return -EINVAL;
+	}
 
 	entries = roundup_pow_of_two(entries + 1);
-	if (entries >  (1 << MLX5_CAP_GEN(dev->mdev, log_max_cq_sz)) + 1)
+	if (entries > (1 << MLX5_CAP_GEN(dev->mdev, log_max_cq_sz)) + 1)
 		return -EINVAL;
 
 	if (entries == ibcq->cqe + 1)
--- zfcpdump-kernel-4.4.orig/drivers/infiniband/hw/mlx5/main.c
+++ zfcpdump-kernel-4.4/drivers/infiniband/hw/mlx5/main.c
@@ -40,6 +40,7 @@
 #include <linux/io-mapping.h>
 #include <linux/sched.h>
 #include <rdma/ib_user_verbs.h>
+#include <linux/mlx5/port.h>
 #include <linux/mlx5/vport.h>
 #include <rdma/ib_smi.h>
 #include <rdma/ib_umem.h>
@@ -273,9 +274,9 @@ static int mlx5_ib_query_device(struct i
 		     sizeof(struct mlx5_wqe_ctrl_seg)) /
 		     sizeof(struct mlx5_wqe_data_seg);
 	props->max_sge = min(max_rq_sg, max_sq_sg);
-	props->max_sge_rd = props->max_sge;
+	props->max_sge_rd	   = MLX5_MAX_SGE_RD;
 	props->max_cq		   = 1 << MLX5_CAP_GEN(mdev, log_max_cq);
-	props->max_cqe = (1 << MLX5_CAP_GEN(mdev, log_max_eq_sz)) - 1;
+	props->max_cqe = (1 << MLX5_CAP_GEN(mdev, log_max_cq_sz)) - 1;
 	props->max_mr		   = 1 << MLX5_CAP_GEN(mdev, log_max_mkey);
 	props->max_pd		   = 1 << MLX5_CAP_GEN(mdev, log_max_pd);
 	props->max_qp_rd_atom	   = 1 << MLX5_CAP_GEN(mdev, log_max_ra_req_qp);
@@ -405,8 +406,8 @@ static int mlx5_query_hca_port(struct ib
 	struct mlx5_ib_dev *dev = to_mdev(ibdev);
 	struct mlx5_core_dev *mdev = dev->mdev;
 	struct mlx5_hca_vport_context *rep;
-	int max_mtu;
-	int oper_mtu;
+	u16 max_mtu;
+	u16 oper_mtu;
 	int err;
 	u8 ib_link_width_oper;
 	u8 vl_hw_cap;
@@ -962,14 +963,11 @@ static void mlx5_ib_event(struct mlx5_co
 		break;
 
 	case MLX5_DEV_EVENT_PORT_DOWN:
+	case MLX5_DEV_EVENT_PORT_INITIALIZED:
 		ibev.event = IB_EVENT_PORT_ERR;
 		port = (u8)param;
 		break;
 
-	case MLX5_DEV_EVENT_PORT_INITIALIZED:
-		/* not used by ULPs */
-		return;
-
 	case MLX5_DEV_EVENT_LID_CHANGE:
 		ibev.event = IB_EVENT_LID_CHANGE;
 		port = (u8)param;
--- zfcpdump-kernel-4.4.orig/drivers/infiniband/hw/mlx5/qp.c
+++ zfcpdump-kernel-4.4/drivers/infiniband/hw/mlx5/qp.c
@@ -226,6 +226,8 @@ static int set_rq_size(struct mlx5_ib_de
 		qp->rq.max_gs = 0;
 		qp->rq.wqe_cnt = 0;
 		qp->rq.wqe_shift = 0;
+		cap->max_recv_wr = 0;
+		cap->max_recv_sge = 0;
 	} else {
 		if (ucmd) {
 			qp->rq.wqe_cnt = ucmd->rq_wqe_count;
@@ -2525,10 +2527,11 @@ static u8 get_fence(u8 fence, struct ib_
 			return MLX5_FENCE_MODE_SMALL_AND_FENCE;
 		else
 			return fence;
-
-	} else {
-		return 0;
+	} else if (unlikely(wr->send_flags & IB_SEND_FENCE)) {
+		return MLX5_FENCE_MODE_FENCE;
 	}
+
+	return 0;
 }
 
 static int begin_wqe(struct mlx5_ib_qp *qp, void **seg,
@@ -3092,17 +3095,19 @@ int mlx5_ib_query_qp(struct ib_qp *ibqp,
 	qp_attr->cap.max_recv_sge    = qp->rq.max_gs;
 
 	if (!ibqp->uobject) {
-		qp_attr->cap.max_send_wr  = qp->sq.wqe_cnt;
+		qp_attr->cap.max_send_wr  = qp->sq.max_post;
 		qp_attr->cap.max_send_sge = qp->sq.max_gs;
+		qp_init_attr->qp_context = ibqp->qp_context;
 	} else {
 		qp_attr->cap.max_send_wr  = 0;
 		qp_attr->cap.max_send_sge = 0;
 	}
 
-	/* We don't support inline sends for kernel QPs (yet), and we
-	 * don't know what userspace's value should be.
-	 */
-	qp_attr->cap.max_inline_data = 0;
+	qp_init_attr->qp_type = ibqp->qp_type;
+	qp_init_attr->recv_cq = ibqp->recv_cq;
+	qp_init_attr->send_cq = ibqp->send_cq;
+	qp_init_attr->srq = ibqp->srq;
+	qp_attr->cap.max_inline_data = qp->max_inline_data;
 
 	qp_init_attr->cap	     = qp_attr->cap;
 
--- zfcpdump-kernel-4.4.orig/drivers/infiniband/hw/qib/qib_file_ops.c
+++ zfcpdump-kernel-4.4/drivers/infiniband/hw/qib/qib_file_ops.c
@@ -45,6 +45,8 @@
 #include <linux/export.h>
 #include <linux/uio.h>
 
+#include <rdma/ib.h>
+
 #include "qib.h"
 #include "qib_common.h"
 #include "qib_user_sdma.h"
@@ -2067,6 +2069,9 @@ static ssize_t qib_write(struct file *fp
 	ssize_t ret = 0;
 	void *dest;
 
+	if (WARN_ON_ONCE(!ib_safe_file_access(fp)))
+		return -EACCES;
+
 	if (count < sizeof(cmd.type)) {
 		ret = -EINVAL;
 		goto bail;
--- zfcpdump-kernel-4.4.orig/drivers/infiniband/hw/qib/qib_qp.c
+++ zfcpdump-kernel-4.4/drivers/infiniband/hw/qib/qib_qp.c
@@ -100,9 +100,10 @@ static u32 credit_table[31] = {
 	32768                   /* 1E */
 };
 
-static void get_map_page(struct qib_qpn_table *qpt, struct qpn_map *map)
+static void get_map_page(struct qib_qpn_table *qpt, struct qpn_map *map,
+			 gfp_t gfp)
 {
-	unsigned long page = get_zeroed_page(GFP_KERNEL);
+	unsigned long page = get_zeroed_page(gfp);
 
 	/*
 	 * Free the page if someone raced with us installing it.
@@ -121,7 +122,7 @@ static void get_map_page(struct qib_qpn_
  * zero/one for QP type IB_QPT_SMI/IB_QPT_GSI.
  */
 static int alloc_qpn(struct qib_devdata *dd, struct qib_qpn_table *qpt,
-		     enum ib_qp_type type, u8 port)
+		     enum ib_qp_type type, u8 port, gfp_t gfp)
 {
 	u32 i, offset, max_scan, qpn;
 	struct qpn_map *map;
@@ -151,7 +152,7 @@ static int alloc_qpn(struct qib_devdata
 	max_scan = qpt->nmaps - !offset;
 	for (i = 0;;) {
 		if (unlikely(!map->page)) {
-			get_map_page(qpt, map);
+			get_map_page(qpt, map, gfp);
 			if (unlikely(!map->page))
 				break;
 		}
@@ -983,13 +984,21 @@ struct ib_qp *qib_create_qp(struct ib_pd
 	size_t sz;
 	size_t sg_list_sz;
 	struct ib_qp *ret;
+	gfp_t gfp;
+
 
 	if (init_attr->cap.max_send_sge > ib_qib_max_sges ||
 	    init_attr->cap.max_send_wr > ib_qib_max_qp_wrs ||
-	    init_attr->create_flags) {
-		ret = ERR_PTR(-EINVAL);
-		goto bail;
-	}
+	    init_attr->create_flags & ~(IB_QP_CREATE_USE_GFP_NOIO))
+		return ERR_PTR(-EINVAL);
+
+	/* GFP_NOIO is applicable in RC QPs only */
+	if (init_attr->create_flags & IB_QP_CREATE_USE_GFP_NOIO &&
+	    init_attr->qp_type != IB_QPT_RC)
+		return ERR_PTR(-EINVAL);
+
+	gfp = init_attr->create_flags & IB_QP_CREATE_USE_GFP_NOIO ?
+			GFP_NOIO : GFP_KERNEL;
 
 	/* Check receive queue parameters if no SRQ is specified. */
 	if (!init_attr->srq) {
@@ -1021,7 +1030,8 @@ struct ib_qp *qib_create_qp(struct ib_pd
 		sz = sizeof(struct qib_sge) *
 			init_attr->cap.max_send_sge +
 			sizeof(struct qib_swqe);
-		swq = vmalloc((init_attr->cap.max_send_wr + 1) * sz);
+		swq = __vmalloc((init_attr->cap.max_send_wr + 1) * sz,
+				gfp, PAGE_KERNEL);
 		if (swq == NULL) {
 			ret = ERR_PTR(-ENOMEM);
 			goto bail;
@@ -1037,13 +1047,13 @@ struct ib_qp *qib_create_qp(struct ib_pd
 		} else if (init_attr->cap.max_recv_sge > 1)
 			sg_list_sz = sizeof(*qp->r_sg_list) *
 				(init_attr->cap.max_recv_sge - 1);
-		qp = kzalloc(sz + sg_list_sz, GFP_KERNEL);
+		qp = kzalloc(sz + sg_list_sz, gfp);
 		if (!qp) {
 			ret = ERR_PTR(-ENOMEM);
 			goto bail_swq;
 		}
 		RCU_INIT_POINTER(qp->next, NULL);
-		qp->s_hdr = kzalloc(sizeof(*qp->s_hdr), GFP_KERNEL);
+		qp->s_hdr = kzalloc(sizeof(*qp->s_hdr), gfp);
 		if (!qp->s_hdr) {
 			ret = ERR_PTR(-ENOMEM);
 			goto bail_qp;
@@ -1058,8 +1068,16 @@ struct ib_qp *qib_create_qp(struct ib_pd
 			qp->r_rq.max_sge = init_attr->cap.max_recv_sge;
 			sz = (sizeof(struct ib_sge) * qp->r_rq.max_sge) +
 				sizeof(struct qib_rwqe);
-			qp->r_rq.wq = vmalloc_user(sizeof(struct qib_rwq) +
-						   qp->r_rq.size * sz);
+			if (gfp != GFP_NOIO)
+				qp->r_rq.wq = vmalloc_user(
+						sizeof(struct qib_rwq) +
+						qp->r_rq.size * sz);
+			else
+				qp->r_rq.wq = __vmalloc(
+						sizeof(struct qib_rwq) +
+						qp->r_rq.size * sz,
+						gfp, PAGE_KERNEL);
+
 			if (!qp->r_rq.wq) {
 				ret = ERR_PTR(-ENOMEM);
 				goto bail_qp;
@@ -1090,7 +1108,7 @@ struct ib_qp *qib_create_qp(struct ib_pd
 		dev = to_idev(ibpd->device);
 		dd = dd_from_dev(dev);
 		err = alloc_qpn(dd, &dev->qpn_table, init_attr->qp_type,
-				init_attr->port_num);
+				init_attr->port_num, gfp);
 		if (err < 0) {
 			ret = ERR_PTR(err);
 			vfree(qp->r_rq.wq);
--- zfcpdump-kernel-4.4.orig/drivers/infiniband/hw/qib/qib_verbs_mcast.c
+++ zfcpdump-kernel-4.4/drivers/infiniband/hw/qib/qib_verbs_mcast.c
@@ -286,15 +286,13 @@ int qib_multicast_detach(struct ib_qp *i
 	struct qib_ibdev *dev = to_idev(ibqp->device);
 	struct qib_ibport *ibp = to_iport(ibqp->device, qp->port_num);
 	struct qib_mcast *mcast = NULL;
-	struct qib_mcast_qp *p, *tmp;
+	struct qib_mcast_qp *p, *tmp, *delp = NULL;
 	struct rb_node *n;
 	int last = 0;
 	int ret;
 
-	if (ibqp->qp_num <= 1 || qp->state == IB_QPS_RESET) {
-		ret = -EINVAL;
-		goto bail;
-	}
+	if (ibqp->qp_num <= 1 || qp->state == IB_QPS_RESET)
+		return -EINVAL;
 
 	spin_lock_irq(&ibp->lock);
 
@@ -303,8 +301,7 @@ int qib_multicast_detach(struct ib_qp *i
 	while (1) {
 		if (n == NULL) {
 			spin_unlock_irq(&ibp->lock);
-			ret = -EINVAL;
-			goto bail;
+			return -EINVAL;
 		}
 
 		mcast = rb_entry(n, struct qib_mcast, rb_node);
@@ -328,6 +325,7 @@ int qib_multicast_detach(struct ib_qp *i
 		 */
 		list_del_rcu(&p->list);
 		mcast->n_attached--;
+		delp = p;
 
 		/* If this was the last attached QP, remove the GID too. */
 		if (list_empty(&mcast->qp_list)) {
@@ -338,15 +336,16 @@ int qib_multicast_detach(struct ib_qp *i
 	}
 
 	spin_unlock_irq(&ibp->lock);
+	/* QP not attached */
+	if (!delp)
+		return -EINVAL;
+	/*
+	 * Wait for any list walkers to finish before freeing the
+	 * list element.
+	 */
+	wait_event(mcast->wait, atomic_read(&mcast->refcount) <= 1);
+	qib_mcast_qp_free(delp);
 
-	if (p) {
-		/*
-		 * Wait for any list walkers to finish before freeing the
-		 * list element.
-		 */
-		wait_event(mcast->wait, atomic_read(&mcast->refcount) <= 1);
-		qib_mcast_qp_free(p);
-	}
 	if (last) {
 		atomic_dec(&mcast->refcount);
 		wait_event(mcast->wait, !atomic_read(&mcast->refcount));
@@ -355,11 +354,7 @@ int qib_multicast_detach(struct ib_qp *i
 		dev->n_mcast_grps_allocated--;
 		spin_unlock_irq(&dev->n_mcast_grps_lock);
 	}
-
-	ret = 0;
-
-bail:
-	return ret;
+	return 0;
 }
 
 int qib_mcast_tree_empty(struct qib_ibport *ibp)
--- zfcpdump-kernel-4.4.orig/drivers/infiniband/ulp/ipoib/ipoib.h
+++ zfcpdump-kernel-4.4/drivers/infiniband/ulp/ipoib/ipoib.h
@@ -472,6 +472,7 @@ void ipoib_send(struct net_device *dev,
 		struct ipoib_ah *address, u32 qpn);
 void ipoib_reap_ah(struct work_struct *work);
 
+struct ipoib_path *__path_find(struct net_device *dev, void *gid);
 void ipoib_mark_paths_invalid(struct net_device *dev);
 void ipoib_flush_paths(struct net_device *dev);
 struct ipoib_dev_priv *ipoib_intf_alloc(const char *format);
--- zfcpdump-kernel-4.4.orig/drivers/infiniband/ulp/ipoib/ipoib_cm.c
+++ zfcpdump-kernel-4.4/drivers/infiniband/ulp/ipoib/ipoib_cm.c
@@ -1299,6 +1299,8 @@ void ipoib_cm_destroy_tx(struct ipoib_cm
 	}
 }
 
+#define QPN_AND_OPTIONS_OFFSET	4
+
 static void ipoib_cm_tx_start(struct work_struct *work)
 {
 	struct ipoib_dev_priv *priv = container_of(work, struct ipoib_dev_priv,
@@ -1307,6 +1309,7 @@ static void ipoib_cm_tx_start(struct wor
 	struct ipoib_neigh *neigh;
 	struct ipoib_cm_tx *p;
 	unsigned long flags;
+	struct ipoib_path *path;
 	int ret;
 
 	struct ib_sa_path_rec pathrec;
@@ -1319,7 +1322,19 @@ static void ipoib_cm_tx_start(struct wor
 		p = list_entry(priv->cm.start_list.next, typeof(*p), list);
 		list_del_init(&p->list);
 		neigh = p->neigh;
+
 		qpn = IPOIB_QPN(neigh->daddr);
+		/*
+		 * As long as the search is with these 2 locks,
+		 * path existence indicates its validity.
+		 */
+		path = __path_find(dev, neigh->daddr + QPN_AND_OPTIONS_OFFSET);
+		if (!path) {
+			pr_info("%s ignore not valid path %pI6\n",
+				__func__,
+				neigh->daddr + QPN_AND_OPTIONS_OFFSET);
+			goto free_neigh;
+		}
 		memcpy(&pathrec, &p->path->pathrec, sizeof pathrec);
 
 		spin_unlock_irqrestore(&priv->lock, flags);
@@ -1331,6 +1346,7 @@ static void ipoib_cm_tx_start(struct wor
 		spin_lock_irqsave(&priv->lock, flags);
 
 		if (ret) {
+free_neigh:
 			neigh = p->neigh;
 			if (neigh) {
 				neigh->cm = NULL;
--- zfcpdump-kernel-4.4.orig/drivers/infiniband/ulp/ipoib/ipoib_ib.c
+++ zfcpdump-kernel-4.4/drivers/infiniband/ulp/ipoib/ipoib_ib.c
@@ -245,8 +245,6 @@ static void ipoib_ib_handle_rx_wc(struct
 	skb_reset_mac_header(skb);
 	skb_pull(skb, IPOIB_ENCAP_LEN);
 
-	skb->truesize = SKB_TRUESIZE(skb->len);
-
 	++dev->stats.rx_packets;
 	dev->stats.rx_bytes += skb->len;
 
@@ -1030,8 +1028,17 @@ static void __ipoib_ib_dev_flush(struct
 	}
 
 	if (level == IPOIB_FLUSH_LIGHT) {
+		int oper_up;
 		ipoib_mark_paths_invalid(dev);
+		/* Set IPoIB operation as down to prevent races between:
+		 * the flush flow which leaves MCG and on the fly joins
+		 * which can happen during that time. mcast restart task
+		 * should deal with join requests we missed.
+		 */
+		oper_up = test_and_clear_bit(IPOIB_FLAG_OPER_UP, &priv->flags);
 		ipoib_mcast_dev_flush(dev);
+		if (oper_up)
+			set_bit(IPOIB_FLAG_OPER_UP, &priv->flags);
 		ipoib_flush_ah(dev);
 	}
 
--- zfcpdump-kernel-4.4.orig/drivers/infiniband/ulp/ipoib/ipoib_main.c
+++ zfcpdump-kernel-4.4/drivers/infiniband/ulp/ipoib/ipoib_main.c
@@ -481,7 +481,7 @@ int ipoib_set_mode(struct net_device *de
 	return -EINVAL;
 }
 
-static struct ipoib_path *__path_find(struct net_device *dev, void *gid)
+struct ipoib_path *__path_find(struct net_device *dev, void *gid)
 {
 	struct ipoib_dev_priv *priv = netdev_priv(dev);
 	struct rb_node *n = priv->path_tree.rb_node;
@@ -1131,7 +1131,9 @@ struct ipoib_neigh *ipoib_neigh_get(stru
 				neigh = NULL;
 				goto out_unlock;
 			}
-			neigh->alive = jiffies;
+
+			if (likely(skb_queue_len(&neigh->queue) < IPOIB_MAX_PATH_REC_QUEUE))
+				neigh->alive = jiffies;
 			goto out_unlock;
 		}
 	}
--- zfcpdump-kernel-4.4.orig/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
+++ zfcpdump-kernel-4.4/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
@@ -456,7 +456,10 @@ out_locked:
 	return status;
 }
 
-static void ipoib_mcast_join(struct net_device *dev, struct ipoib_mcast *mcast)
+/*
+ * Caller must hold 'priv->lock'
+ */
+static int ipoib_mcast_join(struct net_device *dev, struct ipoib_mcast *mcast)
 {
 	struct ipoib_dev_priv *priv = netdev_priv(dev);
 	struct ib_sa_multicast *multicast;
@@ -466,6 +469,10 @@ static void ipoib_mcast_join(struct net_
 	ib_sa_comp_mask comp_mask;
 	int ret = 0;
 
+	if (!priv->broadcast ||
+	    !test_bit(IPOIB_FLAG_OPER_UP, &priv->flags))
+		return -EINVAL;
+
 	ipoib_dbg_mcast(priv, "joining MGID %pI6\n", mcast->mcmember.mgid.raw);
 
 	rec.mgid     = mcast->mcmember.mgid;
@@ -525,20 +532,23 @@ static void ipoib_mcast_join(struct net_
 			rec.join_state = 4;
 #endif
 	}
+	spin_unlock_irq(&priv->lock);
 
 	multicast = ib_sa_join_multicast(&ipoib_sa_client, priv->ca, priv->port,
 					 &rec, comp_mask, GFP_KERNEL,
 					 ipoib_mcast_join_complete, mcast);
+	spin_lock_irq(&priv->lock);
 	if (IS_ERR(multicast)) {
 		ret = PTR_ERR(multicast);
 		ipoib_warn(priv, "ib_sa_join_multicast failed, status %d\n", ret);
-		spin_lock_irq(&priv->lock);
 		/* Requeue this join task with a backoff delay */
 		__ipoib_mcast_schedule_join_thread(priv, mcast, 1);
 		clear_bit(IPOIB_MCAST_FLAG_BUSY, &mcast->flags);
 		spin_unlock_irq(&priv->lock);
 		complete(&mcast->done);
+		spin_lock_irq(&priv->lock);
 	}
+	return 0;
 }
 
 void ipoib_mcast_join_task(struct work_struct *work)
@@ -620,9 +630,10 @@ void ipoib_mcast_join_task(struct work_s
 				/* Found the next unjoined group */
 				init_completion(&mcast->done);
 				set_bit(IPOIB_MCAST_FLAG_BUSY, &mcast->flags);
-				spin_unlock_irq(&priv->lock);
-				ipoib_mcast_join(dev, mcast);
-				spin_lock_irq(&priv->lock);
+				if (ipoib_mcast_join(dev, mcast)) {
+					spin_unlock_irq(&priv->lock);
+					return;
+				}
 			} else if (!delay_until ||
 				 time_before(mcast->delay_until, delay_until))
 				delay_until = mcast->delay_until;
@@ -641,10 +652,9 @@ out:
 	if (mcast) {
 		init_completion(&mcast->done);
 		set_bit(IPOIB_MCAST_FLAG_BUSY, &mcast->flags);
+		ipoib_mcast_join(dev, mcast);
 	}
 	spin_unlock_irq(&priv->lock);
-	if (mcast)
-		ipoib_mcast_join(dev, mcast);
 }
 
 int ipoib_mcast_start_thread(struct net_device *dev)
--- zfcpdump-kernel-4.4.orig/drivers/infiniband/ulp/isert/ib_isert.c
+++ zfcpdump-kernel-4.4/drivers/infiniband/ulp/isert/ib_isert.c
@@ -66,6 +66,7 @@ isert_rdma_accept(struct isert_conn *ise
 struct rdma_cm_id *isert_setup_id(struct isert_np *isert_np);
 
 static void isert_release_work(struct work_struct *work);
+static void isert_wait4flush(struct isert_conn *isert_conn);
 
 static inline bool
 isert_prot_cmd(struct isert_conn *conn, struct se_cmd *cmd)
@@ -815,12 +816,31 @@ isert_put_conn(struct isert_conn *isert_
 	kref_put(&isert_conn->kref, isert_release_kref);
 }
 
+static void
+isert_handle_unbound_conn(struct isert_conn *isert_conn)
+{
+	struct isert_np *isert_np = isert_conn->cm_id->context;
+
+	mutex_lock(&isert_np->mutex);
+	if (!list_empty(&isert_conn->node)) {
+		/*
+		 * This means iscsi doesn't know this connection
+		 * so schedule a cleanup ourselves
+		 */
+		list_del_init(&isert_conn->node);
+		isert_put_conn(isert_conn);
+		complete(&isert_conn->wait);
+		queue_work(isert_release_wq, &isert_conn->release_work);
+	}
+	mutex_unlock(&isert_np->mutex);
+}
+
 /**
  * isert_conn_terminate() - Initiate connection termination
  * @isert_conn: isert connection struct
  *
  * Notes:
- * In case the connection state is FULL_FEATURE, move state
+ * In case the connection state is BOUND, move state
  * to TEMINATING and start teardown sequence (rdma_disconnect).
  * In case the connection state is UP, complete flush as well.
  *
@@ -832,23 +852,19 @@ isert_conn_terminate(struct isert_conn *
 {
 	int err;
 
-	switch (isert_conn->state) {
-	case ISER_CONN_TERMINATING:
-		break;
-	case ISER_CONN_UP:
-	case ISER_CONN_FULL_FEATURE: /* FALLTHRU */
-		isert_info("Terminating conn %p state %d\n",
-			   isert_conn, isert_conn->state);
-		isert_conn->state = ISER_CONN_TERMINATING;
-		err = rdma_disconnect(isert_conn->cm_id);
-		if (err)
-			isert_warn("Failed rdma_disconnect isert_conn %p\n",
-				   isert_conn);
-		break;
-	default:
-		isert_warn("conn %p teminating in state %d\n",
-			   isert_conn, isert_conn->state);
-	}
+	if (isert_conn->state >= ISER_CONN_TERMINATING)
+		return;
+
+	isert_info("Terminating conn %p state %d\n",
+		   isert_conn, isert_conn->state);
+	isert_conn->state = ISER_CONN_TERMINATING;
+	err = rdma_disconnect(isert_conn->cm_id);
+	if (err)
+		isert_warn("Failed rdma_disconnect isert_conn %p\n",
+			   isert_conn);
+
+	isert_info("conn %p completing wait\n", isert_conn);
+	complete(&isert_conn->wait);
 }
 
 static int
@@ -882,35 +898,27 @@ static int
 isert_disconnected_handler(struct rdma_cm_id *cma_id,
 			   enum rdma_cm_event_type event)
 {
-	struct isert_np *isert_np = cma_id->context;
-	struct isert_conn *isert_conn;
-	bool terminating = false;
-
-	if (isert_np->cm_id == cma_id)
-		return isert_np_cma_handler(cma_id->context, event);
-
-	isert_conn = cma_id->qp->qp_context;
+	struct isert_conn *isert_conn = cma_id->qp->qp_context;
 
 	mutex_lock(&isert_conn->mutex);
-	terminating = (isert_conn->state == ISER_CONN_TERMINATING);
-	isert_conn_terminate(isert_conn);
-	mutex_unlock(&isert_conn->mutex);
-
-	isert_info("conn %p completing wait\n", isert_conn);
-	complete(&isert_conn->wait);
-
-	if (terminating)
-		goto out;
-
-	mutex_lock(&isert_np->mutex);
-	if (!list_empty(&isert_conn->node)) {
-		list_del_init(&isert_conn->node);
-		isert_put_conn(isert_conn);
-		queue_work(isert_release_wq, &isert_conn->release_work);
+	switch (isert_conn->state) {
+	case ISER_CONN_TERMINATING:
+		break;
+	case ISER_CONN_UP:
+		isert_conn_terminate(isert_conn);
+		isert_wait4flush(isert_conn);
+		isert_handle_unbound_conn(isert_conn);
+		break;
+	case ISER_CONN_BOUND:
+	case ISER_CONN_FULL_FEATURE: /* FALLTHRU */
+		iscsit_cause_connection_reinstatement(isert_conn->conn, 0);
+		break;
+	default:
+		isert_warn("conn %p teminating in state %d\n",
+			   isert_conn, isert_conn->state);
 	}
-	mutex_unlock(&isert_np->mutex);
+	mutex_unlock(&isert_conn->mutex);
 
-out:
 	return 0;
 }
 
@@ -929,12 +937,16 @@ isert_connect_error(struct rdma_cm_id *c
 static int
 isert_cma_handler(struct rdma_cm_id *cma_id, struct rdma_cm_event *event)
 {
+	struct isert_np *isert_np = cma_id->context;
 	int ret = 0;
 
 	isert_info("%s (%d): status %d id %p np %p\n",
 		   rdma_event_msg(event->event), event->event,
 		   event->status, cma_id, cma_id->context);
 
+	if (isert_np->cm_id == cma_id)
+		return isert_np_cma_handler(cma_id->context, event->event);
+
 	switch (event->event) {
 	case RDMA_CM_EVENT_CONNECT_REQUEST:
 		ret = isert_connect_request(cma_id, event);
@@ -980,13 +992,10 @@ isert_post_recvm(struct isert_conn *iser
 	rx_wr--;
 	rx_wr->next = NULL; /* mark end of work requests list */
 
-	isert_conn->post_recv_buf_count += count;
 	ret = ib_post_recv(isert_conn->qp, isert_conn->rx_wr,
 			   &rx_wr_failed);
-	if (ret) {
+	if (ret)
 		isert_err("ib_post_recv() failed with ret: %d\n", ret);
-		isert_conn->post_recv_buf_count -= count;
-	}
 
 	return ret;
 }
@@ -1002,12 +1011,9 @@ isert_post_recv(struct isert_conn *isert
 	rx_wr.num_sge = 1;
 	rx_wr.next = NULL;
 
-	isert_conn->post_recv_buf_count++;
 	ret = ib_post_recv(isert_conn->qp, &rx_wr, &rx_wr_failed);
-	if (ret) {
+	if (ret)
 		isert_err("ib_post_recv() failed with ret: %d\n", ret);
-		isert_conn->post_recv_buf_count--;
-	}
 
 	return ret;
 }
@@ -1120,12 +1126,9 @@ isert_rdma_post_recvl(struct isert_conn
 	rx_wr.sg_list = &sge;
 	rx_wr.num_sge = 1;
 
-	isert_conn->post_recv_buf_count++;
 	ret = ib_post_recv(isert_conn->qp, &rx_wr, &rx_wr_fail);
-	if (ret) {
+	if (ret)
 		isert_err("ib_post_recv() failed: %d\n", ret);
-		isert_conn->post_recv_buf_count--;
-	}
 
 	return ret;
 }
@@ -1620,7 +1623,6 @@ isert_rcv_completion(struct iser_rx_desc
 	ib_dma_sync_single_for_device(ib_dev, rx_dma, rx_buflen,
 				      DMA_FROM_DEVICE);
 
-	isert_conn->post_recv_buf_count--;
 }
 
 static int
@@ -2035,7 +2037,8 @@ is_isert_tx_desc(struct isert_conn *iser
 	void *start = isert_conn->rx_descs;
 	int len = ISERT_QP_MAX_RECV_DTOS * sizeof(*isert_conn->rx_descs);
 
-	if (wr_id >= start && wr_id < start + len)
+	if ((wr_id >= start && wr_id < start + len) ||
+	    (wr_id == isert_conn->login_req_buf))
 		return false;
 
 	return true;
@@ -2059,10 +2062,6 @@ isert_cq_comp_err(struct isert_conn *ise
 			isert_unmap_tx_desc(desc, ib_dev);
 		else
 			isert_completion_put(desc, isert_cmd, ib_dev, true);
-	} else {
-		isert_conn->post_recv_buf_count--;
-		if (!isert_conn->post_recv_buf_count)
-			iscsit_cause_connection_reinstatement(isert_conn->conn, 0);
 	}
 }
 
@@ -3193,6 +3192,7 @@ accept_wait:
 
 	conn->context = isert_conn;
 	isert_conn->conn = conn;
+	isert_conn->state = ISER_CONN_BOUND;
 
 	isert_set_conn_info(np, conn, isert_conn);
 
--- zfcpdump-kernel-4.4.orig/drivers/infiniband/ulp/isert/ib_isert.h
+++ zfcpdump-kernel-4.4/drivers/infiniband/ulp/isert/ib_isert.h
@@ -50,6 +50,7 @@ enum iser_ib_op_code {
 enum iser_conn_state {
 	ISER_CONN_INIT,
 	ISER_CONN_UP,
+	ISER_CONN_BOUND,
 	ISER_CONN_FULL_FEATURE,
 	ISER_CONN_TERMINATING,
 	ISER_CONN_DOWN,
@@ -144,7 +145,6 @@ struct isert_device;
 
 struct isert_conn {
 	enum iser_conn_state	state;
-	int			post_recv_buf_count;
 	u32			responder_resources;
 	u32			initiator_depth;
 	bool			pi_support;
--- zfcpdump-kernel-4.4.orig/drivers/infiniband/ulp/srp/ib_srp.c
+++ zfcpdump-kernel-4.4/drivers/infiniband/ulp/srp/ib_srp.c
@@ -1519,7 +1519,7 @@ static int srp_map_idb(struct srp_rdma_c
 
 	if (dev->use_fast_reg) {
 		state.sg = idb_sg;
-		sg_set_buf(idb_sg, req->indirect_desc, idb_len);
+		sg_init_one(idb_sg, req->indirect_desc, idb_len);
 		idb_sg->dma_address = req->indirect_dma_addr; /* hack! */
 #ifdef CONFIG_NEED_SG_DMA_LENGTH
 		idb_sg->dma_length = idb_sg->length;	      /* hack^2 */
--- zfcpdump-kernel-4.4.orig/drivers/infiniband/ulp/srpt/ib_srpt.c
+++ zfcpdump-kernel-4.4/drivers/infiniband/ulp/srpt/ib_srpt.c
@@ -1737,47 +1737,6 @@ send_sense:
 	return -1;
 }
 
-/**
- * srpt_rx_mgmt_fn_tag() - Process a task management function by tag.
- * @ch: RDMA channel of the task management request.
- * @fn: Task management function to perform.
- * @req_tag: Tag of the SRP task management request.
- * @mgmt_ioctx: I/O context of the task management request.
- *
- * Returns zero if the target core will process the task management
- * request asynchronously.
- *
- * Note: It is assumed that the initiator serializes tag-based task management
- * requests.
- */
-static int srpt_rx_mgmt_fn_tag(struct srpt_send_ioctx *ioctx, u64 tag)
-{
-	struct srpt_device *sdev;
-	struct srpt_rdma_ch *ch;
-	struct srpt_send_ioctx *target;
-	int ret, i;
-
-	ret = -EINVAL;
-	ch = ioctx->ch;
-	BUG_ON(!ch);
-	BUG_ON(!ch->sport);
-	sdev = ch->sport->sdev;
-	BUG_ON(!sdev);
-	spin_lock_irq(&sdev->spinlock);
-	for (i = 0; i < ch->rq_size; ++i) {
-		target = ch->ioctx_ring[i];
-		if (target->cmd.se_lun == ioctx->cmd.se_lun &&
-		    target->cmd.tag == tag &&
-		    srpt_get_cmd_state(target) != SRPT_STATE_DONE) {
-			ret = 0;
-			/* now let the target core abort &target->cmd; */
-			break;
-		}
-	}
-	spin_unlock_irq(&sdev->spinlock);
-	return ret;
-}
-
 static int srp_tmr_to_tcm(int fn)
 {
 	switch (fn) {
@@ -1812,7 +1771,6 @@ static void srpt_handle_tsk_mgmt(struct
 	struct se_cmd *cmd;
 	struct se_session *sess = ch->sess;
 	uint64_t unpacked_lun;
-	uint32_t tag = 0;
 	int tcm_tmr;
 	int rc;
 
@@ -1828,25 +1786,10 @@ static void srpt_handle_tsk_mgmt(struct
 	srpt_set_cmd_state(send_ioctx, SRPT_STATE_MGMT);
 	send_ioctx->cmd.tag = srp_tsk->tag;
 	tcm_tmr = srp_tmr_to_tcm(srp_tsk->tsk_mgmt_func);
-	if (tcm_tmr < 0) {
-		send_ioctx->cmd.se_tmr_req->response =
-			TMR_TASK_MGMT_FUNCTION_NOT_SUPPORTED;
-		goto fail;
-	}
 	unpacked_lun = srpt_unpack_lun((uint8_t *)&srp_tsk->lun,
 				       sizeof(srp_tsk->lun));
-
-	if (srp_tsk->tsk_mgmt_func == SRP_TSK_ABORT_TASK) {
-		rc = srpt_rx_mgmt_fn_tag(send_ioctx, srp_tsk->task_tag);
-		if (rc < 0) {
-			send_ioctx->cmd.se_tmr_req->response =
-					TMR_TASK_DOES_NOT_EXIST;
-			goto fail;
-		}
-		tag = srp_tsk->task_tag;
-	}
 	rc = target_submit_tmr(&send_ioctx->cmd, sess, NULL, unpacked_lun,
-				srp_tsk, tcm_tmr, GFP_KERNEL, tag,
+				srp_tsk, tcm_tmr, GFP_KERNEL, srp_tsk->task_tag,
 				TARGET_SCF_ACK_KREF);
 	if (rc != 0) {
 		send_ioctx->cmd.se_tmr_req->response = TMR_FUNCTION_REJECTED;
--- zfcpdump-kernel-4.4.orig/drivers/input/joystick/xpad.c
+++ zfcpdump-kernel-4.4/drivers/input/joystick/xpad.c
@@ -317,6 +317,19 @@ static struct usb_device_id xpad_table[]
 
 MODULE_DEVICE_TABLE(usb, xpad_table);
 
+struct xpad_output_packet {
+	u8 data[XPAD_PKT_LEN];
+	u8 len;
+	bool pending;
+};
+
+#define XPAD_OUT_CMD_IDX	0
+#define XPAD_OUT_FF_IDX		1
+#define XPAD_OUT_LED_IDX	(1 + IS_ENABLED(CONFIG_JOYSTICK_XPAD_FF))
+#define XPAD_NUM_OUT_PACKETS	(1 + \
+				 IS_ENABLED(CONFIG_JOYSTICK_XPAD_FF) + \
+				 IS_ENABLED(CONFIG_JOYSTICK_XPAD_LEDS))
+
 struct usb_xpad {
 	struct input_dev *dev;		/* input device interface */
 	struct usb_device *udev;	/* usb device */
@@ -329,9 +342,13 @@ struct usb_xpad {
 	dma_addr_t idata_dma;
 
 	struct urb *irq_out;		/* urb for interrupt out report */
+	bool irq_out_active;		/* we must not use an active URB */
 	unsigned char *odata;		/* output data */
 	dma_addr_t odata_dma;
-	struct mutex odata_mutex;
+	spinlock_t odata_lock;
+
+	struct xpad_output_packet out_packets[XPAD_NUM_OUT_PACKETS];
+	int last_out_packet;
 
 #if defined(CONFIG_JOYSTICK_XPAD_LEDS)
 	struct xpad_led *led;
@@ -678,18 +695,71 @@ exit:
 			__func__, retval);
 }
 
+/* Callers must hold xpad->odata_lock spinlock */
+static bool xpad_prepare_next_out_packet(struct usb_xpad *xpad)
+{
+	struct xpad_output_packet *pkt, *packet = NULL;
+	int i;
+
+	for (i = 0; i < XPAD_NUM_OUT_PACKETS; i++) {
+		if (++xpad->last_out_packet >= XPAD_NUM_OUT_PACKETS)
+			xpad->last_out_packet = 0;
+
+		pkt = &xpad->out_packets[xpad->last_out_packet];
+		if (pkt->pending) {
+			dev_dbg(&xpad->intf->dev,
+				"%s - found pending output packet %d\n",
+				__func__, xpad->last_out_packet);
+			packet = pkt;
+			break;
+		}
+	}
+
+	if (packet) {
+		memcpy(xpad->odata, packet->data, packet->len);
+		xpad->irq_out->transfer_buffer_length = packet->len;
+		packet->pending = false;
+		return true;
+	}
+
+	return false;
+}
+
+/* Callers must hold xpad->odata_lock spinlock */
+static int xpad_try_sending_next_out_packet(struct usb_xpad *xpad)
+{
+	int error;
+
+	if (!xpad->irq_out_active && xpad_prepare_next_out_packet(xpad)) {
+		error = usb_submit_urb(xpad->irq_out, GFP_ATOMIC);
+		if (error) {
+			dev_err(&xpad->intf->dev,
+				"%s - usb_submit_urb failed with result %d\n",
+				__func__, error);
+			return -EIO;
+		}
+
+		xpad->irq_out_active = true;
+	}
+
+	return 0;
+}
+
 static void xpad_irq_out(struct urb *urb)
 {
 	struct usb_xpad *xpad = urb->context;
 	struct device *dev = &xpad->intf->dev;
-	int retval, status;
+	int status = urb->status;
+	int error;
+	unsigned long flags;
 
-	status = urb->status;
+	spin_lock_irqsave(&xpad->odata_lock, flags);
 
 	switch (status) {
 	case 0:
 		/* success */
-		return;
+		xpad->irq_out_active = xpad_prepare_next_out_packet(xpad);
+		break;
 
 	case -ECONNRESET:
 	case -ENOENT:
@@ -697,19 +767,26 @@ static void xpad_irq_out(struct urb *urb
 		/* this urb is terminated, clean up */
 		dev_dbg(dev, "%s - urb shutting down with status: %d\n",
 			__func__, status);
-		return;
+		xpad->irq_out_active = false;
+		break;
 
 	default:
 		dev_dbg(dev, "%s - nonzero urb status received: %d\n",
 			__func__, status);
-		goto exit;
+		break;
 	}
 
-exit:
-	retval = usb_submit_urb(urb, GFP_ATOMIC);
-	if (retval)
-		dev_err(dev, "%s - usb_submit_urb failed with result %d\n",
-			__func__, retval);
+	if (xpad->irq_out_active) {
+		error = usb_submit_urb(urb, GFP_ATOMIC);
+		if (error) {
+			dev_err(dev,
+				"%s - usb_submit_urb failed with result %d\n",
+				__func__, error);
+			xpad->irq_out_active = false;
+		}
+	}
+
+	spin_unlock_irqrestore(&xpad->odata_lock, flags);
 }
 
 static int xpad_init_output(struct usb_interface *intf, struct usb_xpad *xpad)
@@ -728,7 +805,7 @@ static int xpad_init_output(struct usb_i
 		goto fail1;
 	}
 
-	mutex_init(&xpad->odata_mutex);
+	spin_lock_init(&xpad->odata_lock);
 
 	xpad->irq_out = usb_alloc_urb(0, GFP_KERNEL);
 	if (!xpad->irq_out) {
@@ -770,27 +847,57 @@ static void xpad_deinit_output(struct us
 
 static int xpad_inquiry_pad_presence(struct usb_xpad *xpad)
 {
+	struct xpad_output_packet *packet =
+			&xpad->out_packets[XPAD_OUT_CMD_IDX];
+	unsigned long flags;
 	int retval;
 
-	mutex_lock(&xpad->odata_mutex);
+	spin_lock_irqsave(&xpad->odata_lock, flags);
+
+	packet->data[0] = 0x08;
+	packet->data[1] = 0x00;
+	packet->data[2] = 0x0F;
+	packet->data[3] = 0xC0;
+	packet->data[4] = 0x00;
+	packet->data[5] = 0x00;
+	packet->data[6] = 0x00;
+	packet->data[7] = 0x00;
+	packet->data[8] = 0x00;
+	packet->data[9] = 0x00;
+	packet->data[10] = 0x00;
+	packet->data[11] = 0x00;
+	packet->len = 12;
+	packet->pending = true;
+
+	/* Reset the sequence so we send out presence first */
+	xpad->last_out_packet = -1;
+	retval = xpad_try_sending_next_out_packet(xpad);
+
+	spin_unlock_irqrestore(&xpad->odata_lock, flags);
 
-	xpad->odata[0] = 0x08;
-	xpad->odata[1] = 0x00;
-	xpad->odata[2] = 0x0F;
-	xpad->odata[3] = 0xC0;
-	xpad->odata[4] = 0x00;
-	xpad->odata[5] = 0x00;
-	xpad->odata[6] = 0x00;
-	xpad->odata[7] = 0x00;
-	xpad->odata[8] = 0x00;
-	xpad->odata[9] = 0x00;
-	xpad->odata[10] = 0x00;
-	xpad->odata[11] = 0x00;
-	xpad->irq_out->transfer_buffer_length = 12;
+	return retval;
+}
+
+static int xpad_start_xbox_one(struct usb_xpad *xpad)
+{
+	struct xpad_output_packet *packet =
+			&xpad->out_packets[XPAD_OUT_CMD_IDX];
+	unsigned long flags;
+	int retval;
 
-	retval = usb_submit_urb(xpad->irq_out, GFP_KERNEL);
+	spin_lock_irqsave(&xpad->odata_lock, flags);
 
-	mutex_unlock(&xpad->odata_mutex);
+	/* Xbox one controller needs to be initialized. */
+	packet->data[0] = 0x05;
+	packet->data[1] = 0x20;
+	packet->len = 2;
+	packet->pending = true;
+
+	/* Reset the sequence so we send out start packet first */
+	xpad->last_out_packet = -1;
+	retval = xpad_try_sending_next_out_packet(xpad);
+
+	spin_unlock_irqrestore(&xpad->odata_lock, flags);
 
 	return retval;
 }
@@ -799,8 +906,11 @@ static int xpad_inquiry_pad_presence(str
 static int xpad_play_effect(struct input_dev *dev, void *data, struct ff_effect *effect)
 {
 	struct usb_xpad *xpad = input_get_drvdata(dev);
+	struct xpad_output_packet *packet = &xpad->out_packets[XPAD_OUT_FF_IDX];
 	__u16 strong;
 	__u16 weak;
+	int retval;
+	unsigned long flags;
 
 	if (effect->type != FF_RUMBLE)
 		return 0;
@@ -808,69 +918,80 @@ static int xpad_play_effect(struct input
 	strong = effect->u.rumble.strong_magnitude;
 	weak = effect->u.rumble.weak_magnitude;
 
+	spin_lock_irqsave(&xpad->odata_lock, flags);
+
 	switch (xpad->xtype) {
 	case XTYPE_XBOX:
-		xpad->odata[0] = 0x00;
-		xpad->odata[1] = 0x06;
-		xpad->odata[2] = 0x00;
-		xpad->odata[3] = strong / 256;	/* left actuator */
-		xpad->odata[4] = 0x00;
-		xpad->odata[5] = weak / 256;	/* right actuator */
-		xpad->irq_out->transfer_buffer_length = 6;
+		packet->data[0] = 0x00;
+		packet->data[1] = 0x06;
+		packet->data[2] = 0x00;
+		packet->data[3] = strong / 256;	/* left actuator */
+		packet->data[4] = 0x00;
+		packet->data[5] = weak / 256;	/* right actuator */
+		packet->len = 6;
+		packet->pending = true;
 		break;
 
 	case XTYPE_XBOX360:
-		xpad->odata[0] = 0x00;
-		xpad->odata[1] = 0x08;
-		xpad->odata[2] = 0x00;
-		xpad->odata[3] = strong / 256;  /* left actuator? */
-		xpad->odata[4] = weak / 256;	/* right actuator? */
-		xpad->odata[5] = 0x00;
-		xpad->odata[6] = 0x00;
-		xpad->odata[7] = 0x00;
-		xpad->irq_out->transfer_buffer_length = 8;
+		packet->data[0] = 0x00;
+		packet->data[1] = 0x08;
+		packet->data[2] = 0x00;
+		packet->data[3] = strong / 256;  /* left actuator? */
+		packet->data[4] = weak / 256;	/* right actuator? */
+		packet->data[5] = 0x00;
+		packet->data[6] = 0x00;
+		packet->data[7] = 0x00;
+		packet->len = 8;
+		packet->pending = true;
 		break;
 
 	case XTYPE_XBOX360W:
-		xpad->odata[0] = 0x00;
-		xpad->odata[1] = 0x01;
-		xpad->odata[2] = 0x0F;
-		xpad->odata[3] = 0xC0;
-		xpad->odata[4] = 0x00;
-		xpad->odata[5] = strong / 256;
-		xpad->odata[6] = weak / 256;
-		xpad->odata[7] = 0x00;
-		xpad->odata[8] = 0x00;
-		xpad->odata[9] = 0x00;
-		xpad->odata[10] = 0x00;
-		xpad->odata[11] = 0x00;
-		xpad->irq_out->transfer_buffer_length = 12;
+		packet->data[0] = 0x00;
+		packet->data[1] = 0x01;
+		packet->data[2] = 0x0F;
+		packet->data[3] = 0xC0;
+		packet->data[4] = 0x00;
+		packet->data[5] = strong / 256;
+		packet->data[6] = weak / 256;
+		packet->data[7] = 0x00;
+		packet->data[8] = 0x00;
+		packet->data[9] = 0x00;
+		packet->data[10] = 0x00;
+		packet->data[11] = 0x00;
+		packet->len = 12;
+		packet->pending = true;
 		break;
 
 	case XTYPE_XBOXONE:
-		xpad->odata[0] = 0x09; /* activate rumble */
-		xpad->odata[1] = 0x08;
-		xpad->odata[2] = 0x00;
-		xpad->odata[3] = 0x08; /* continuous effect */
-		xpad->odata[4] = 0x00; /* simple rumble mode */
-		xpad->odata[5] = 0x03; /* L and R actuator only */
-		xpad->odata[6] = 0x00; /* TODO: LT actuator */
-		xpad->odata[7] = 0x00; /* TODO: RT actuator */
-		xpad->odata[8] = strong / 256;	/* left actuator */
-		xpad->odata[9] = weak / 256;	/* right actuator */
-		xpad->odata[10] = 0x80;	/* length of pulse */
-		xpad->odata[11] = 0x00;	/* stop period of pulse */
-		xpad->irq_out->transfer_buffer_length = 12;
+		packet->data[0] = 0x09; /* activate rumble */
+		packet->data[1] = 0x08;
+		packet->data[2] = 0x00;
+		packet->data[3] = 0x08; /* continuous effect */
+		packet->data[4] = 0x00; /* simple rumble mode */
+		packet->data[5] = 0x03; /* L and R actuator only */
+		packet->data[6] = 0x00; /* TODO: LT actuator */
+		packet->data[7] = 0x00; /* TODO: RT actuator */
+		packet->data[8] = strong / 256;	/* left actuator */
+		packet->data[9] = weak / 256;	/* right actuator */
+		packet->data[10] = 0x80;	/* length of pulse */
+		packet->data[11] = 0x00;	/* stop period of pulse */
+		packet->len = 12;
+		packet->pending = true;
 		break;
 
 	default:
 		dev_dbg(&xpad->dev->dev,
 			"%s - rumble command sent to unsupported xpad type: %d\n",
 			__func__, xpad->xtype);
-		return -EINVAL;
+		retval = -EINVAL;
+		goto out;
 	}
 
-	return usb_submit_urb(xpad->irq_out, GFP_ATOMIC);
+	retval = xpad_try_sending_next_out_packet(xpad);
+
+out:
+	spin_unlock_irqrestore(&xpad->odata_lock, flags);
+	return retval;
 }
 
 static int xpad_init_ff(struct usb_xpad *xpad)
@@ -921,36 +1042,44 @@ struct xpad_led {
  */
 static void xpad_send_led_command(struct usb_xpad *xpad, int command)
 {
+	struct xpad_output_packet *packet =
+			&xpad->out_packets[XPAD_OUT_LED_IDX];
+	unsigned long flags;
+
 	command %= 16;
 
-	mutex_lock(&xpad->odata_mutex);
+	spin_lock_irqsave(&xpad->odata_lock, flags);
 
 	switch (xpad->xtype) {
 	case XTYPE_XBOX360:
-		xpad->odata[0] = 0x01;
-		xpad->odata[1] = 0x03;
-		xpad->odata[2] = command;
-		xpad->irq_out->transfer_buffer_length = 3;
+		packet->data[0] = 0x01;
+		packet->data[1] = 0x03;
+		packet->data[2] = command;
+		packet->len = 3;
+		packet->pending = true;
 		break;
+
 	case XTYPE_XBOX360W:
-		xpad->odata[0] = 0x00;
-		xpad->odata[1] = 0x00;
-		xpad->odata[2] = 0x08;
-		xpad->odata[3] = 0x40 + command;
-		xpad->odata[4] = 0x00;
-		xpad->odata[5] = 0x00;
-		xpad->odata[6] = 0x00;
-		xpad->odata[7] = 0x00;
-		xpad->odata[8] = 0x00;
-		xpad->odata[9] = 0x00;
-		xpad->odata[10] = 0x00;
-		xpad->odata[11] = 0x00;
-		xpad->irq_out->transfer_buffer_length = 12;
+		packet->data[0] = 0x00;
+		packet->data[1] = 0x00;
+		packet->data[2] = 0x08;
+		packet->data[3] = 0x40 + command;
+		packet->data[4] = 0x00;
+		packet->data[5] = 0x00;
+		packet->data[6] = 0x00;
+		packet->data[7] = 0x00;
+		packet->data[8] = 0x00;
+		packet->data[9] = 0x00;
+		packet->data[10] = 0x00;
+		packet->data[11] = 0x00;
+		packet->len = 12;
+		packet->pending = true;
 		break;
 	}
 
-	usb_submit_urb(xpad->irq_out, GFP_KERNEL);
-	mutex_unlock(&xpad->odata_mutex);
+	xpad_try_sending_next_out_packet(xpad);
+
+	spin_unlock_irqrestore(&xpad->odata_lock, flags);
 }
 
 /*
@@ -1048,13 +1177,8 @@ static int xpad_open(struct input_dev *d
 	if (usb_submit_urb(xpad->irq_in, GFP_KERNEL))
 		return -EIO;
 
-	if (xpad->xtype == XTYPE_XBOXONE) {
-		/* Xbox one controller needs to be initialized. */
-		xpad->odata[0] = 0x05;
-		xpad->odata[1] = 0x20;
-		xpad->irq_out->transfer_buffer_length = 2;
-		return usb_submit_urb(xpad->irq_out, GFP_KERNEL);
-	}
+	if (xpad->xtype == XTYPE_XBOXONE)
+		return xpad_start_xbox_one(xpad);
 
 	return 0;
 }
@@ -1200,22 +1324,15 @@ static int xpad_probe(struct usb_interfa
 	int ep_irq_in_idx;
 	int i, error;
 
+	if (intf->cur_altsetting->desc.bNumEndpoints != 2)
+		return -ENODEV;
+
 	for (i = 0; xpad_device[i].idVendor; i++) {
 		if ((le16_to_cpu(udev->descriptor.idVendor) == xpad_device[i].idVendor) &&
 		    (le16_to_cpu(udev->descriptor.idProduct) == xpad_device[i].idProduct))
 			break;
 	}
 
-	if (xpad_device[i].xtype == XTYPE_XBOXONE &&
-	    intf->cur_altsetting->desc.bInterfaceNumber != 0) {
-		/*
-		 * The Xbox One controller lists three interfaces all with the
-		 * same interface class, subclass and protocol. Differentiate by
-		 * interface number.
-		 */
-		return -ENODEV;
-	}
-
 	xpad = kzalloc(sizeof(struct usb_xpad), GFP_KERNEL);
 	if (!xpad)
 		return -ENOMEM;
@@ -1246,6 +1363,8 @@ static int xpad_probe(struct usb_interfa
 		if (intf->cur_altsetting->desc.bInterfaceClass == USB_CLASS_VENDOR_SPEC) {
 			if (intf->cur_altsetting->desc.bInterfaceProtocol == 129)
 				xpad->xtype = XTYPE_XBOX360W;
+			else if (intf->cur_altsetting->desc.bInterfaceProtocol == 208)
+				xpad->xtype = XTYPE_XBOXONE;
 			else
 				xpad->xtype = XTYPE_XBOX360;
 		} else {
@@ -1260,6 +1379,17 @@ static int xpad_probe(struct usb_interfa
 			xpad->mapping |= MAP_STICKS_TO_NULL;
 	}
 
+	if (xpad->xtype == XTYPE_XBOXONE &&
+	    intf->cur_altsetting->desc.bInterfaceNumber != 0) {
+		/*
+		 * The Xbox One controller lists three interfaces all with the
+		 * same interface class, subclass and protocol. Differentiate by
+		 * interface number.
+		 */
+		error = -ENODEV;
+		goto err_free_in_urb;
+	}
+
 	error = xpad_init_output(intf, xpad);
 	if (error)
 		goto err_free_in_urb;
--- zfcpdump-kernel-4.4.orig/drivers/input/keyboard/tegra-kbc.c
+++ zfcpdump-kernel-4.4/drivers/input/keyboard/tegra-kbc.c
@@ -376,7 +376,7 @@ static int tegra_kbc_start(struct tegra_
 	/* Reset the KBC controller to clear all previous status.*/
 	reset_control_assert(kbc->rst);
 	udelay(100);
-	reset_control_assert(kbc->rst);
+	reset_control_deassert(kbc->rst);
 	udelay(100);
 
 	tegra_kbc_config_pins(kbc);
--- zfcpdump-kernel-4.4.orig/drivers/input/misc/ati_remote2.c
+++ zfcpdump-kernel-4.4/drivers/input/misc/ati_remote2.c
@@ -817,26 +817,49 @@ static int ati_remote2_probe(struct usb_
 
 	ar2->udev = udev;
 
+	/* Sanity check, first interface must have an endpoint */
+	if (alt->desc.bNumEndpoints < 1 || !alt->endpoint) {
+		dev_err(&interface->dev,
+			"%s(): interface 0 must have an endpoint\n", __func__);
+		r = -ENODEV;
+		goto fail1;
+	}
 	ar2->intf[0] = interface;
 	ar2->ep[0] = &alt->endpoint[0].desc;
 
+	/* Sanity check, the device must have two interfaces */
 	ar2->intf[1] = usb_ifnum_to_if(udev, 1);
+	if ((udev->actconfig->desc.bNumInterfaces < 2) || !ar2->intf[1]) {
+		dev_err(&interface->dev, "%s(): need 2 interfaces, found %d\n",
+			__func__, udev->actconfig->desc.bNumInterfaces);
+		r = -ENODEV;
+		goto fail1;
+	}
+
 	r = usb_driver_claim_interface(&ati_remote2_driver, ar2->intf[1], ar2);
 	if (r)
 		goto fail1;
+
+	/* Sanity check, second interface must have an endpoint */
 	alt = ar2->intf[1]->cur_altsetting;
+	if (alt->desc.bNumEndpoints < 1 || !alt->endpoint) {
+		dev_err(&interface->dev,
+			"%s(): interface 1 must have an endpoint\n", __func__);
+		r = -ENODEV;
+		goto fail2;
+	}
 	ar2->ep[1] = &alt->endpoint[0].desc;
 
 	r = ati_remote2_urb_init(ar2);
 	if (r)
-		goto fail2;
+		goto fail3;
 
 	ar2->channel_mask = channel_mask;
 	ar2->mode_mask = mode_mask;
 
 	r = ati_remote2_setup(ar2, ar2->channel_mask);
 	if (r)
-		goto fail2;
+		goto fail3;
 
 	usb_make_path(udev, ar2->phys, sizeof(ar2->phys));
 	strlcat(ar2->phys, "/input0", sizeof(ar2->phys));
@@ -845,11 +868,11 @@ static int ati_remote2_probe(struct usb_
 
 	r = sysfs_create_group(&udev->dev.kobj, &ati_remote2_attr_group);
 	if (r)
-		goto fail2;
+		goto fail3;
 
 	r = ati_remote2_input_init(ar2);
 	if (r)
-		goto fail3;
+		goto fail4;
 
 	usb_set_intfdata(interface, ar2);
 
@@ -857,10 +880,11 @@ static int ati_remote2_probe(struct usb_
 
 	return 0;
 
- fail3:
+ fail4:
 	sysfs_remove_group(&udev->dev.kobj, &ati_remote2_attr_group);
- fail2:
+ fail3:
 	ati_remote2_urb_cleanup(ar2);
+ fail2:
 	usb_driver_release_interface(&ati_remote2_driver, ar2->intf[1]);
  fail1:
 	kfree(ar2);
--- zfcpdump-kernel-4.4.orig/drivers/input/misc/ims-pcu.c
+++ zfcpdump-kernel-4.4/drivers/input/misc/ims-pcu.c
@@ -1663,6 +1663,8 @@ static int ims_pcu_parse_cdc_data(struct
 
 	pcu->ctrl_intf = usb_ifnum_to_if(pcu->udev,
 					 union_desc->bMasterInterface0);
+	if (!pcu->ctrl_intf)
+		return -EINVAL;
 
 	alt = pcu->ctrl_intf->cur_altsetting;
 	pcu->ep_ctrl = &alt->endpoint[0].desc;
@@ -1670,6 +1672,8 @@ static int ims_pcu_parse_cdc_data(struct
 
 	pcu->data_intf = usb_ifnum_to_if(pcu->udev,
 					 union_desc->bSlaveInterface0);
+	if (!pcu->data_intf)
+		return -EINVAL;
 
 	alt = pcu->data_intf->cur_altsetting;
 	if (alt->desc.bNumEndpoints != 2) {
--- zfcpdump-kernel-4.4.orig/drivers/input/misc/max8997_haptic.c
+++ zfcpdump-kernel-4.4/drivers/input/misc/max8997_haptic.c
@@ -255,12 +255,14 @@ static int max8997_haptic_probe(struct p
 	struct max8997_dev *iodev = dev_get_drvdata(pdev->dev.parent);
 	const struct max8997_platform_data *pdata =
 					dev_get_platdata(iodev->dev);
-	const struct max8997_haptic_platform_data *haptic_pdata =
-					pdata->haptic_pdata;
+	const struct max8997_haptic_platform_data *haptic_pdata = NULL;
 	struct max8997_haptic *chip;
 	struct input_dev *input_dev;
 	int error;
 
+	if (pdata)
+		haptic_pdata = pdata->haptic_pdata;
+
 	if (!haptic_pdata) {
 		dev_err(&pdev->dev, "no haptic platform data\n");
 		return -EINVAL;
--- zfcpdump-kernel-4.4.orig/drivers/input/misc/pmic8xxx-pwrkey.c
+++ zfcpdump-kernel-4.4/drivers/input/misc/pmic8xxx-pwrkey.c
@@ -353,7 +353,8 @@ static int pmic8xxx_pwrkey_probe(struct
 	if (of_property_read_u32(pdev->dev.of_node, "debounce", &kpd_delay))
 		kpd_delay = 15625;
 
-	if (kpd_delay > 62500 || kpd_delay == 0) {
+	/* Valid range of pwr key trigger delay is 1/64 sec to 2 seconds. */
+	if (kpd_delay > USEC_PER_SEC * 2 || kpd_delay < USEC_PER_SEC / 64) {
 		dev_err(&pdev->dev, "invalid power key trigger delay\n");
 		return -EINVAL;
 	}
@@ -385,8 +386,8 @@ static int pmic8xxx_pwrkey_probe(struct
 	pwr->name = "pmic8xxx_pwrkey";
 	pwr->phys = "pmic8xxx_pwrkey/input0";
 
-	delay = (kpd_delay << 10) / USEC_PER_SEC;
-	delay = 1 + ilog2(delay);
+	delay = (kpd_delay << 6) / USEC_PER_SEC;
+	delay = ilog2(delay);
 
 	err = regmap_read(regmap, PON_CNTL_1, &pon_cntl);
 	if (err < 0) {
--- zfcpdump-kernel-4.4.orig/drivers/input/misc/powermate.c
+++ zfcpdump-kernel-4.4/drivers/input/misc/powermate.c
@@ -307,6 +307,9 @@ static int powermate_probe(struct usb_in
 	int error = -ENOMEM;
 
 	interface = intf->cur_altsetting;
+	if (interface->desc.bNumEndpoints < 1)
+		return -EINVAL;
+
 	endpoint = &interface->endpoint[0].desc;
 	if (!usb_endpoint_is_int_in(endpoint))
 		return -EIO;
--- zfcpdump-kernel-4.4.orig/drivers/input/misc/pwm-beeper.c
+++ zfcpdump-kernel-4.4/drivers/input/misc/pwm-beeper.c
@@ -20,21 +20,40 @@
 #include <linux/platform_device.h>
 #include <linux/pwm.h>
 #include <linux/slab.h>
+#include <linux/workqueue.h>
 
 struct pwm_beeper {
 	struct input_dev *input;
 	struct pwm_device *pwm;
+	struct work_struct work;
 	unsigned long period;
 };
 
 #define HZ_TO_NANOSECONDS(x) (1000000000UL/(x))
 
+static void __pwm_beeper_set(struct pwm_beeper *beeper)
+{
+	unsigned long period = beeper->period;
+
+	if (period) {
+		pwm_config(beeper->pwm, period / 2, period);
+		pwm_enable(beeper->pwm);
+	} else
+		pwm_disable(beeper->pwm);
+}
+
+static void pwm_beeper_work(struct work_struct *work)
+{
+	struct pwm_beeper *beeper =
+		container_of(work, struct pwm_beeper, work);
+
+	__pwm_beeper_set(beeper);
+}
+
 static int pwm_beeper_event(struct input_dev *input,
 			    unsigned int type, unsigned int code, int value)
 {
-	int ret = 0;
 	struct pwm_beeper *beeper = input_get_drvdata(input);
-	unsigned long period;
 
 	if (type != EV_SND || value < 0)
 		return -EINVAL;
@@ -49,22 +68,31 @@ static int pwm_beeper_event(struct input
 		return -EINVAL;
 	}
 
-	if (value == 0) {
-		pwm_disable(beeper->pwm);
-	} else {
-		period = HZ_TO_NANOSECONDS(value);
-		ret = pwm_config(beeper->pwm, period / 2, period);
-		if (ret)
-			return ret;
-		ret = pwm_enable(beeper->pwm);
-		if (ret)
-			return ret;
-		beeper->period = period;
-	}
+	if (value == 0)
+		beeper->period = 0;
+	else
+		beeper->period = HZ_TO_NANOSECONDS(value);
+
+	schedule_work(&beeper->work);
 
 	return 0;
 }
 
+static void pwm_beeper_stop(struct pwm_beeper *beeper)
+{
+	cancel_work_sync(&beeper->work);
+
+	if (beeper->period)
+		pwm_disable(beeper->pwm);
+}
+
+static void pwm_beeper_close(struct input_dev *input)
+{
+	struct pwm_beeper *beeper = input_get_drvdata(input);
+
+	pwm_beeper_stop(beeper);
+}
+
 static int pwm_beeper_probe(struct platform_device *pdev)
 {
 	unsigned long pwm_id = (unsigned long)dev_get_platdata(&pdev->dev);
@@ -87,6 +115,8 @@ static int pwm_beeper_probe(struct platf
 		goto err_free;
 	}
 
+	INIT_WORK(&beeper->work, pwm_beeper_work);
+
 	beeper->input = input_allocate_device();
 	if (!beeper->input) {
 		dev_err(&pdev->dev, "Failed to allocate input device\n");
@@ -106,6 +136,7 @@ static int pwm_beeper_probe(struct platf
 	beeper->input->sndbit[0] = BIT(SND_TONE) | BIT(SND_BELL);
 
 	beeper->input->event = pwm_beeper_event;
+	beeper->input->close = pwm_beeper_close;
 
 	input_set_drvdata(beeper->input, beeper);
 
@@ -135,7 +166,6 @@ static int pwm_beeper_remove(struct plat
 
 	input_unregister_device(beeper->input);
 
-	pwm_disable(beeper->pwm);
 	pwm_free(beeper->pwm);
 
 	kfree(beeper);
@@ -147,8 +177,7 @@ static int __maybe_unused pwm_beeper_sus
 {
 	struct pwm_beeper *beeper = dev_get_drvdata(dev);
 
-	if (beeper->period)
-		pwm_disable(beeper->pwm);
+	pwm_beeper_stop(beeper);
 
 	return 0;
 }
@@ -157,10 +186,8 @@ static int __maybe_unused pwm_beeper_res
 {
 	struct pwm_beeper *beeper = dev_get_drvdata(dev);
 
-	if (beeper->period) {
-		pwm_config(beeper->pwm, beeper->period / 2, beeper->period);
-		pwm_enable(beeper->pwm);
-	}
+	if (beeper->period)
+		__pwm_beeper_set(beeper);
 
 	return 0;
 }
--- zfcpdump-kernel-4.4.orig/drivers/input/misc/uinput.c
+++ zfcpdump-kernel-4.4/drivers/input/misc/uinput.c
@@ -893,9 +893,15 @@ static long uinput_ioctl(struct file *fi
 }
 
 #ifdef CONFIG_COMPAT
+
+#define UI_SET_PHYS_COMPAT	_IOW(UINPUT_IOCTL_BASE, 108, compat_uptr_t)
+
 static long uinput_compat_ioctl(struct file *file,
 				unsigned int cmd, unsigned long arg)
 {
+	if (cmd == UI_SET_PHYS_COMPAT)
+		cmd = UI_SET_PHYS;
+
 	return uinput_ioctl_handler(file, cmd, arg, compat_ptr(arg));
 }
 #endif
--- zfcpdump-kernel-4.4.orig/drivers/input/mouse/cypress_ps2.c
+++ zfcpdump-kernel-4.4/drivers/input/mouse/cypress_ps2.c
@@ -390,7 +390,9 @@ static int cypress_set_input_params(stru
 	if (ret < 0)
 		return ret;
 
+#if ( CYPRESS_SIMULATED_MT != 1 )
 	__set_bit(INPUT_PROP_SEMI_MT, input->propbit);
+#endif
 
 	input_abs_set_res(input, ABS_X, cytp->tp_res_x);
 	input_abs_set_res(input, ABS_Y, cytp->tp_res_y);
@@ -478,6 +480,22 @@ static int cypress_parse_packet(struct p
 			((packet[5] & 0x0f) << 8) | packet[7];
 		if (cytp->mode & CYTP_BIT_ABS_PRESSURE)
 			report_data->contacts[1].z = report_data->contacts[0].z;
+#if ( CYPRESS_SIMULATED_MT == 1 )
+		/* simulate contact positions for >2 fingers */
+		if ( report_data->contact_cnt >= 3 ) {
+			int i;
+			for ( i=1; i<report_data->contact_cnt; i++ ) {
+			    report_data->contacts[i].x =
+					    report_data->contacts[0].x
+					    + 100*(i)*((i%2)?-1:1);
+			    report_data->contacts[i].y =
+					    report_data->contacts[0].y;
+			    if (cytp->mode & CYTP_BIT_ABS_PRESSURE)
+				    report_data->contacts[i].z =
+					    report_data->contacts[0].z;
+			}
+		}
+#endif
 	}
 
 	report_data->left = (header_byte & BTN_LEFT_BIT) ? 1 : 0;
--- zfcpdump-kernel-4.4.orig/drivers/input/mouse/cypress_ps2.h
+++ zfcpdump-kernel-4.4/drivers/input/mouse/cypress_ps2.h
@@ -130,7 +130,18 @@
 #define RESP_REMOTE_BIT     0x40
 #define RESP_SMBUS_BIT      0x80
 
-#define CYTP_MAX_MT_SLOTS 2
+/*
+ * CYPRESS_SIMULATED_MT
+ *   set to 1 for simulated multitouch (up to 5 contact points)
+ *   set to 0 for SEMI_MT (only 2 corner points, and count of fingers)
+ */
+#define CYPRESS_SIMULATED_MT 1
+
+#if ( CYPRESS_SIMULATED_MT == 1 )
+# define CYTP_MAX_MT_SLOTS 5
+#else
+# define CYTP_MAX_MT_SLOTS 2
+#endif
 
 struct cytp_contact {
 	int x;
--- zfcpdump-kernel-4.4.orig/drivers/input/mouse/elan_i2c_core.c
+++ zfcpdump-kernel-4.4/drivers/input/mouse/elan_i2c_core.c
@@ -4,7 +4,8 @@
  * Copyright (c) 2013 ELAN Microelectronics Corp.
  *
  * Author: 林政維 (Duson Lin) <dusonlin@emc.com.tw>
- * Version: 1.6.0
+ * Author: KT Liao <kt.liao@emc.com.tw>
+ * Version: 1.6.2
  *
  * Based on cyapa driver:
  * copyright (c) 2011-2012 Cypress Semiconductor, Inc.
@@ -40,7 +41,7 @@
 #include "elan_i2c.h"
 
 #define DRIVER_NAME		"elan_i2c"
-#define ELAN_DRIVER_VERSION	"1.6.1"
+#define ELAN_DRIVER_VERSION	"1.6.2"
 #define ELAN_VENDOR_ID		0x04f3
 #define ETP_MAX_PRESSURE	255
 #define ETP_FWIDTH_REDUCE	90
@@ -199,9 +200,41 @@ static int elan_sleep(struct elan_tp_dat
 	return error;
 }
 
+static int elan_query_product(struct elan_tp_data *data)
+{
+	int error;
+
+	error = data->ops->get_product_id(data->client, &data->product_id);
+	if (error)
+		return error;
+
+	error = data->ops->get_sm_version(data->client, &data->ic_type,
+					  &data->sm_version);
+	if (error)
+		return error;
+
+	return 0;
+}
+
+static int elan_check_ASUS_special_fw(struct elan_tp_data *data)
+{
+	if (data->ic_type != 0x0E)
+		return false;
+
+	switch (data->product_id) {
+	case 0x05 ... 0x07:
+	case 0x09:
+	case 0x13:
+		return true;
+	default:
+		return false;
+	}
+}
+
 static int __elan_initialize(struct elan_tp_data *data)
 {
 	struct i2c_client *client = data->client;
+	bool woken_up = false;
 	int error;
 
 	error = data->ops->initialize(client);
@@ -210,6 +243,27 @@ static int __elan_initialize(struct elan
 		return error;
 	}
 
+	error = elan_query_product(data);
+	if (error)
+		return error;
+
+	/*
+	 * Some ASUS devices were shipped with firmware that requires
+	 * touchpads to be woken up first, before attempting to switch
+	 * them into absolute reporting mode.
+	 */
+	if (elan_check_ASUS_special_fw(data)) {
+		error = data->ops->sleep_control(client, false);
+		if (error) {
+			dev_err(&client->dev,
+				"failed to wake device up: %d\n", error);
+			return error;
+		}
+
+		msleep(200);
+		woken_up = true;
+	}
+
 	data->mode |= ETP_ENABLE_ABS;
 	error = data->ops->set_mode(client, data->mode);
 	if (error) {
@@ -218,11 +272,13 @@ static int __elan_initialize(struct elan
 		return error;
 	}
 
-	error = data->ops->sleep_control(client, false);
-	if (error) {
-		dev_err(&client->dev,
-			"failed to wake device up: %d\n", error);
-		return error;
+	if (!woken_up) {
+		error = data->ops->sleep_control(client, false);
+		if (error) {
+			dev_err(&client->dev,
+				"failed to wake device up: %d\n", error);
+			return error;
+		}
 	}
 
 	return 0;
@@ -248,10 +304,6 @@ static int elan_query_device_info(struct
 {
 	int error;
 
-	error = data->ops->get_product_id(data->client, &data->product_id);
-	if (error)
-		return error;
-
 	error = data->ops->get_version(data->client, false, &data->fw_version);
 	if (error)
 		return error;
@@ -261,11 +313,6 @@ static int elan_query_device_info(struct
 	if (error)
 		return error;
 
-	error = data->ops->get_sm_version(data->client, &data->ic_type,
-					  &data->sm_version);
-	if (error)
-		return error;
-
 	error = data->ops->get_version(data->client, true, &data->iap_version);
 	if (error)
 		return error;
--- zfcpdump-kernel-4.4.orig/drivers/input/mouse/elantech.c
+++ zfcpdump-kernel-4.4/drivers/input/mouse/elantech.c
@@ -1222,7 +1222,7 @@ static int elantech_set_input_params(str
 			input_set_abs_params(dev, ABS_TOOL_WIDTH, ETP_WMIN_V2,
 					     ETP_WMAX_V2, 0, 0);
 		}
-		input_mt_init_slots(dev, 2, 0);
+		input_mt_init_slots(dev, 2, INPUT_MT_SEMI_MT);
 		input_set_abs_params(dev, ABS_MT_POSITION_X, x_min, x_max, 0, 0);
 		input_set_abs_params(dev, ABS_MT_POSITION_Y, y_min, y_max, 0, 0);
 		break;
@@ -1568,13 +1568,7 @@ static int elantech_set_properties(struc
 		case 5:
 			etd->hw_version = 3;
 			break;
-		case 6:
-		case 7:
-		case 8:
-		case 9:
-		case 10:
-		case 13:
-		case 14:
+		case 6 ... 14:
 			etd->hw_version = 4;
 			break;
 		default:
--- zfcpdump-kernel-4.4.orig/drivers/input/mouse/synaptics.c
+++ zfcpdump-kernel-4.4/drivers/input/mouse/synaptics.c
@@ -862,8 +862,9 @@ static void synaptics_report_ext_buttons
 	if (!SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap))
 		return;
 
-	/* Bug in FW 8.1, buttons are reported only when ExtBit is 1 */
-	if (SYN_ID_FULL(priv->identity) == 0x801 &&
+	/* Bug in FW 8.1 & 8.2, buttons are reported only when ExtBit is 1 */
+	if ((SYN_ID_FULL(priv->identity) == 0x801 ||
+	     SYN_ID_FULL(priv->identity) == 0x802) &&
 	    !((psmouse->packet[0] ^ psmouse->packet[3]) & 0x02))
 		return;
 
@@ -1250,7 +1251,9 @@ static void set_input_params(struct psmo
 		/* Clickpads report only left button */
 		__clear_bit(BTN_RIGHT, dev->keybit);
 		__clear_bit(BTN_MIDDLE, dev->keybit);
-	}
+	} else if (SYN_CAP_CLICKPAD2BTN(priv->ext_cap_0c) ||
+		   SYN_CAP_CLICKPAD2BTN2(priv->ext_cap_0c))
+		__set_bit(INPUT_PROP_BUTTONPAD, dev->propbit);
 }
 
 static ssize_t synaptics_show_disable_gesture(struct psmouse *psmouse,
--- zfcpdump-kernel-4.4.orig/drivers/input/mouse/synaptics.h
+++ zfcpdump-kernel-4.4/drivers/input/mouse/synaptics.h
@@ -85,6 +85,7 @@
  */
 #define SYN_CAP_CLICKPAD(ex0c)		((ex0c) & 0x100000) /* 1-button ClickPad */
 #define SYN_CAP_CLICKPAD2BTN(ex0c)	((ex0c) & 0x000100) /* 2-button ClickPad */
+#define SYN_CAP_CLICKPAD2BTN2(ex0c)	((ex0c) & 0x200000) /* 2-button ClickPad */
 #define SYN_CAP_MAX_DIMENSIONS(ex0c)	((ex0c) & 0x020000)
 #define SYN_CAP_MIN_DIMENSIONS(ex0c)	((ex0c) & 0x002000)
 #define SYN_CAP_ADV_GESTURE(ex0c)	((ex0c) & 0x080000)
--- zfcpdump-kernel-4.4.orig/drivers/input/mouse/vmmouse.c
+++ zfcpdump-kernel-4.4/drivers/input/mouse/vmmouse.c
@@ -355,18 +355,11 @@ int vmmouse_detect(struct psmouse *psmou
 		return -ENXIO;
 	}
 
-	if (!request_region(VMMOUSE_PROTO_PORT, 4, "vmmouse")) {
-		psmouse_dbg(psmouse, "VMMouse port in use.\n");
-		return -EBUSY;
-	}
-
 	/* Check if the device is present */
 	response = ~VMMOUSE_PROTO_MAGIC;
 	VMMOUSE_CMD(GETVERSION, 0, version, response, dummy1, dummy2);
-	if (response != VMMOUSE_PROTO_MAGIC || version == 0xffffffffU) {
-		release_region(VMMOUSE_PROTO_PORT, 4);
+	if (response != VMMOUSE_PROTO_MAGIC || version == 0xffffffffU)
 		return -ENXIO;
-	}
 
 	if (set_properties) {
 		psmouse->vendor = VMMOUSE_VENDOR;
@@ -374,8 +367,6 @@ int vmmouse_detect(struct psmouse *psmou
 		psmouse->model = version;
 	}
 
-	release_region(VMMOUSE_PROTO_PORT, 4);
-
 	return 0;
 }
 
@@ -394,7 +385,6 @@ static void vmmouse_disconnect(struct ps
 	psmouse_reset(psmouse);
 	input_unregister_device(priv->abs_dev);
 	kfree(priv);
-	release_region(VMMOUSE_PROTO_PORT, 4);
 }
 
 /**
@@ -438,15 +428,10 @@ int vmmouse_init(struct psmouse *psmouse
 	struct input_dev *rel_dev = psmouse->dev, *abs_dev;
 	int error;
 
-	if (!request_region(VMMOUSE_PROTO_PORT, 4, "vmmouse")) {
-		psmouse_dbg(psmouse, "VMMouse port in use.\n");
-		return -EBUSY;
-	}
-
 	psmouse_reset(psmouse);
 	error = vmmouse_enable(psmouse);
 	if (error)
-		goto release_region;
+		return error;
 
 	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
 	abs_dev = input_allocate_device();
@@ -458,8 +443,6 @@ int vmmouse_init(struct psmouse *psmouse
 	priv->abs_dev = abs_dev;
 	psmouse->private = priv;
 
-	input_set_capability(rel_dev, EV_REL, REL_WHEEL);
-
 	/* Set up and register absolute device */
 	snprintf(priv->phys, sizeof(priv->phys), "%s/input1",
 		 psmouse->ps2dev.serio->phys);
@@ -475,10 +458,6 @@ int vmmouse_init(struct psmouse *psmouse
 	abs_dev->id.version = psmouse->model;
 	abs_dev->dev.parent = &psmouse->ps2dev.serio->dev;
 
-	error = input_register_device(priv->abs_dev);
-	if (error)
-		goto init_fail;
-
 	/* Set absolute device capabilities */
 	input_set_capability(abs_dev, EV_KEY, BTN_LEFT);
 	input_set_capability(abs_dev, EV_KEY, BTN_RIGHT);
@@ -488,6 +467,13 @@ int vmmouse_init(struct psmouse *psmouse
 	input_set_abs_params(abs_dev, ABS_X, 0, VMMOUSE_MAX_X, 0, 0);
 	input_set_abs_params(abs_dev, ABS_Y, 0, VMMOUSE_MAX_Y, 0, 0);
 
+	error = input_register_device(priv->abs_dev);
+	if (error)
+		goto init_fail;
+
+	/* Add wheel capability to the relative device */
+	input_set_capability(rel_dev, EV_REL, REL_WHEEL);
+
 	psmouse->protocol_handler = vmmouse_process_byte;
 	psmouse->disconnect = vmmouse_disconnect;
 	psmouse->reconnect = vmmouse_reconnect;
@@ -501,8 +487,5 @@ init_fail:
 	kfree(priv);
 	psmouse->private = NULL;
 
-release_region:
-	release_region(VMMOUSE_PROTO_PORT, 4);
-
 	return error;
 }
--- zfcpdump-kernel-4.4.orig/drivers/input/serio/hyperv-keyboard.c
+++ zfcpdump-kernel-4.4/drivers/input/serio/hyperv-keyboard.c
@@ -412,16 +412,6 @@ static int hv_kbd_remove(struct hv_devic
 	return 0;
 }
 
-/*
- * Keyboard GUID
- * {f912ad6d-2b17-48ea-bd65-f927a61c7684}
- */
-#define HV_KBD_GUID \
-	.guid = { \
-			0x6d, 0xad, 0x12, 0xf9, 0x17, 0x2b, 0xea, 0x48, \
-			0xbd, 0x65, 0xf9, 0x27, 0xa6, 0x1c, 0x76, 0x84 \
-	}
-
 static const struct hv_vmbus_device_id id_table[] = {
 	/* Keyboard guid */
 	{ HV_KBD_GUID, },
--- zfcpdump-kernel-4.4.orig/drivers/input/serio/i8042-x86ia64io.h
+++ zfcpdump-kernel-4.4/drivers/input/serio/i8042-x86ia64io.h
@@ -258,6 +258,13 @@ static const struct dmi_system_id __init
 		},
 	},
 	{
+		/* Fujitsu Lifebook U745 */
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK U745"),
+		},
+	},
+	{
 		/* Fujitsu T70H */
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
--- zfcpdump-kernel-4.4.orig/drivers/input/serio/i8042.c
+++ zfcpdump-kernel-4.4/drivers/input/serio/i8042.c
@@ -1277,6 +1277,7 @@ static int __init i8042_create_kbd_port(
 	serio->start		= i8042_start;
 	serio->stop		= i8042_stop;
 	serio->close		= i8042_port_close;
+	serio->ps2_cmd_mutex	= &i8042_mutex;
 	serio->port_data	= port;
 	serio->dev.parent	= &i8042_platform_device->dev;
 	strlcpy(serio->name, "i8042 KBD port", sizeof(serio->name));
@@ -1304,6 +1305,7 @@ static int __init i8042_create_aux_port(
 	serio->write		= i8042_aux_write;
 	serio->start		= i8042_start;
 	serio->stop		= i8042_stop;
+	serio->ps2_cmd_mutex	= &i8042_mutex;
 	serio->port_data	= port;
 	serio->dev.parent	= &i8042_platform_device->dev;
 	if (idx < 0) {
@@ -1373,21 +1375,6 @@ static void i8042_unregister_ports(void)
 	}
 }
 
-/*
- * Checks whether port belongs to i8042 controller.
- */
-bool i8042_check_port_owner(const struct serio *port)
-{
-	int i;
-
-	for (i = 0; i < I8042_NUM_PORTS; i++)
-		if (i8042_ports[i].serio == port)
-			return true;
-
-	return false;
-}
-EXPORT_SYMBOL(i8042_check_port_owner);
-
 static void i8042_free_irqs(void)
 {
 	if (i8042_aux_irq_registered)
--- zfcpdump-kernel-4.4.orig/drivers/input/serio/libps2.c
+++ zfcpdump-kernel-4.4/drivers/input/serio/libps2.c
@@ -56,19 +56,17 @@ EXPORT_SYMBOL(ps2_sendbyte);
 
 void ps2_begin_command(struct ps2dev *ps2dev)
 {
-	mutex_lock(&ps2dev->cmd_mutex);
+	struct mutex *m = ps2dev->serio->ps2_cmd_mutex ?: &ps2dev->cmd_mutex;
 
-	if (i8042_check_port_owner(ps2dev->serio))
-		i8042_lock_chip();
+	mutex_lock(m);
 }
 EXPORT_SYMBOL(ps2_begin_command);
 
 void ps2_end_command(struct ps2dev *ps2dev)
 {
-	if (i8042_check_port_owner(ps2dev->serio))
-		i8042_unlock_chip();
+	struct mutex *m = ps2dev->serio->ps2_cmd_mutex ?: &ps2dev->cmd_mutex;
 
-	mutex_unlock(&ps2dev->cmd_mutex);
+	mutex_unlock(m);
 }
 EXPORT_SYMBOL(ps2_end_command);
 
--- zfcpdump-kernel-4.4.orig/drivers/input/tablet/gtco.c
+++ zfcpdump-kernel-4.4/drivers/input/tablet/gtco.c
@@ -858,6 +858,14 @@ static int gtco_probe(struct usb_interfa
 		goto err_free_buf;
 	}
 
+	/* Sanity check that a device has an endpoint */
+	if (usbinterface->altsetting[0].desc.bNumEndpoints < 1) {
+		dev_err(&usbinterface->dev,
+			"Invalid number of endpoints\n");
+		error = -EINVAL;
+		goto err_free_urb;
+	}
+
 	/*
 	 * The endpoint is always altsetting 0, we know this since we know
 	 * this device only has one interrupt endpoint
@@ -879,7 +887,7 @@ static int gtco_probe(struct usb_interfa
 	 * HID report descriptor
 	 */
 	if (usb_get_extra_descriptor(usbinterface->cur_altsetting,
-				     HID_DEVICE_TYPE, &hid_desc) != 0){
+				     HID_DEVICE_TYPE, &hid_desc) != 0) {
 		dev_err(&usbinterface->dev,
 			"Can't retrieve exta USB descriptor to get hid report descriptor length\n");
 		error = -EIO;
--- zfcpdump-kernel-4.4.orig/drivers/input/touchscreen/sur40.c
+++ zfcpdump-kernel-4.4/drivers/input/touchscreen/sur40.c
@@ -126,7 +126,7 @@ struct sur40_image_header {
 #define VIDEO_PACKET_SIZE  16384
 
 /* polling interval (ms) */
-#define POLL_INTERVAL 4
+#define POLL_INTERVAL 1
 
 /* maximum number of contacts FIXME: this is a guess? */
 #define MAX_CONTACTS 64
@@ -441,7 +441,7 @@ static void sur40_process_video(struct s
 
 	/* return error if streaming was stopped in the meantime */
 	if (sur40->sequence == -1)
-		goto err_poll;
+		return;
 
 	/* mark as finished */
 	v4l2_get_timestamp(&new_buf->vb.timestamp);
@@ -730,6 +730,7 @@ static int sur40_start_streaming(struct
 static void sur40_stop_streaming(struct vb2_queue *vq)
 {
 	struct sur40_state *sur40 = vb2_get_drv_priv(vq);
+	vb2_wait_for_all_buffers(vq);
 	sur40->sequence = -1;
 
 	/* Release all active buffers */
--- zfcpdump-kernel-4.4.orig/drivers/input/touchscreen/tsc2004.c
+++ zfcpdump-kernel-4.4/drivers/input/touchscreen/tsc2004.c
@@ -22,6 +22,11 @@
 #include <linux/regmap.h>
 #include "tsc200x-core.h"
 
+static const struct input_id tsc2004_input_id = {
+	.bustype = BUS_I2C,
+	.product = 2004,
+};
+
 static int tsc2004_cmd(struct device *dev, u8 cmd)
 {
 	u8 tx = TSC200X_CMD | TSC200X_CMD_12BIT | cmd;
@@ -42,7 +47,7 @@ static int tsc2004_probe(struct i2c_clie
 			 const struct i2c_device_id *id)
 
 {
-	return tsc200x_probe(&i2c->dev, i2c->irq, BUS_I2C,
+	return tsc200x_probe(&i2c->dev, i2c->irq, &tsc2004_input_id,
 			     devm_regmap_init_i2c(i2c, &tsc200x_regmap_config),
 			     tsc2004_cmd);
 }
--- zfcpdump-kernel-4.4.orig/drivers/input/touchscreen/tsc2005.c
+++ zfcpdump-kernel-4.4/drivers/input/touchscreen/tsc2005.c
@@ -24,6 +24,11 @@
 #include <linux/regmap.h>
 #include "tsc200x-core.h"
 
+static const struct input_id tsc2005_input_id = {
+	.bustype = BUS_SPI,
+	.product = 2005,
+};
+
 static int tsc2005_cmd(struct device *dev, u8 cmd)
 {
 	u8 tx = TSC200X_CMD | TSC200X_CMD_12BIT | cmd;
@@ -62,7 +67,7 @@ static int tsc2005_probe(struct spi_devi
 	if (error)
 		return error;
 
-	return tsc200x_probe(&spi->dev, spi->irq, BUS_SPI,
+	return tsc200x_probe(&spi->dev, spi->irq, &tsc2005_input_id,
 			     devm_regmap_init_spi(spi, &tsc200x_regmap_config),
 			     tsc2005_cmd);
 }
--- zfcpdump-kernel-4.4.orig/drivers/input/touchscreen/tsc200x-core.c
+++ zfcpdump-kernel-4.4/drivers/input/touchscreen/tsc200x-core.c
@@ -450,7 +450,7 @@ static void tsc200x_close(struct input_d
 	mutex_unlock(&ts->mutex);
 }
 
-int tsc200x_probe(struct device *dev, int irq, __u16 bustype,
+int tsc200x_probe(struct device *dev, int irq, const struct input_id *tsc_id,
 		  struct regmap *regmap,
 		  int (*tsc200x_cmd)(struct device *dev, u8 cmd))
 {
@@ -547,9 +547,18 @@ int tsc200x_probe(struct device *dev, in
 	snprintf(ts->phys, sizeof(ts->phys),
 		 "%s/input-ts", dev_name(dev));
 
-	input_dev->name = "TSC200X touchscreen";
+	if (tsc_id->product == 2004) {
+		input_dev->name = "TSC200X touchscreen";
+	} else {
+		input_dev->name = devm_kasprintf(dev, GFP_KERNEL,
+						 "TSC%04d touchscreen",
+						 tsc_id->product);
+		if (!input_dev->name)
+			return -ENOMEM;
+	}
+
 	input_dev->phys = ts->phys;
-	input_dev->id.bustype = bustype;
+	input_dev->id = *tsc_id;
 	input_dev->dev.parent = dev;
 	input_dev->evbit[0] = BIT(EV_ABS) | BIT(EV_KEY);
 	input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
--- zfcpdump-kernel-4.4.orig/drivers/input/touchscreen/tsc200x-core.h
+++ zfcpdump-kernel-4.4/drivers/input/touchscreen/tsc200x-core.h
@@ -70,7 +70,7 @@
 extern const struct regmap_config tsc200x_regmap_config;
 extern const struct dev_pm_ops tsc200x_pm_ops;
 
-int tsc200x_probe(struct device *dev, int irq, __u16 bustype,
+int tsc200x_probe(struct device *dev, int irq, const struct input_id *tsc_id,
 		  struct regmap *regmap,
 		  int (*tsc200x_cmd)(struct device *dev, u8 cmd));
 int tsc200x_remove(struct device *dev);
--- zfcpdump-kernel-4.4.orig/drivers/input/touchscreen/wacom_w8001.c
+++ zfcpdump-kernel-4.4/drivers/input/touchscreen/wacom_w8001.c
@@ -27,7 +27,7 @@ MODULE_AUTHOR("Jaya Kumar <jayakumar.lkm
 MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_LICENSE("GPL");
 
-#define W8001_MAX_LENGTH	11
+#define W8001_MAX_LENGTH	13
 #define W8001_LEAD_MASK		0x80
 #define W8001_LEAD_BYTE		0x80
 #define W8001_TAB_MASK		0x40
@@ -80,7 +80,8 @@ struct w8001_touch_query {
  */
 
 struct w8001 {
-	struct input_dev *dev;
+	struct input_dev *pen_dev;
+	struct input_dev *touch_dev;
 	struct serio *serio;
 	struct completion cmd_done;
 	int id;
@@ -95,7 +96,10 @@ struct w8001 {
 	u16 max_touch_y;
 	u16 max_pen_x;
 	u16 max_pen_y;
-	char name[64];
+	char pen_name[64];
+	char touch_name[64];
+	int open_count;
+	struct mutex mutex;
 };
 
 static void parse_pen_data(u8 *data, struct w8001_coord *coord)
@@ -141,7 +145,7 @@ static void scale_touch_coordinates(stru
 
 static void parse_multi_touch(struct w8001 *w8001)
 {
-	struct input_dev *dev = w8001->dev;
+	struct input_dev *dev = w8001->touch_dev;
 	unsigned char *data = w8001->data;
 	unsigned int x, y;
 	int i;
@@ -151,7 +155,6 @@ static void parse_multi_touch(struct w80
 		bool touch = data[0] & (1 << i);
 
 		input_mt_slot(dev, i);
-		input_mt_report_slot_state(dev, MT_TOOL_FINGER, touch);
 		if (touch) {
 			x = (data[6 * i + 1] << 7) | data[6 * i + 2];
 			y = (data[6 * i + 3] << 7) | data[6 * i + 4];
@@ -207,7 +210,7 @@ static void parse_touchquery(u8 *data, s
 
 static void report_pen_events(struct w8001 *w8001, struct w8001_coord *coord)
 {
-	struct input_dev *dev = w8001->dev;
+	struct input_dev *dev = w8001->pen_dev;
 
 	/*
 	 * We have 1 bit for proximity (rdy) and 3 bits for tip, side,
@@ -233,11 +236,6 @@ static void report_pen_events(struct w80
 		break;
 
 	case BTN_TOOL_FINGER:
-		input_report_key(dev, BTN_TOUCH, 0);
-		input_report_key(dev, BTN_TOOL_FINGER, 0);
-		input_sync(dev);
-		/* fall through */
-
 	case KEY_RESERVED:
 		w8001->type = coord->f2 ? BTN_TOOL_RUBBER : BTN_TOOL_PEN;
 		break;
@@ -261,7 +259,7 @@ static void report_pen_events(struct w80
 
 static void report_single_touch(struct w8001 *w8001, struct w8001_coord *coord)
 {
-	struct input_dev *dev = w8001->dev;
+	struct input_dev *dev = w8001->touch_dev;
 	unsigned int x = coord->x;
 	unsigned int y = coord->y;
 
@@ -271,7 +269,6 @@ static void report_single_touch(struct w
 	input_report_abs(dev, ABS_X, x);
 	input_report_abs(dev, ABS_Y, y);
 	input_report_key(dev, BTN_TOUCH, coord->tsw);
-	input_report_key(dev, BTN_TOOL_FINGER, coord->tsw);
 
 	input_sync(dev);
 
@@ -369,22 +366,36 @@ static int w8001_command(struct w8001 *w
 static int w8001_open(struct input_dev *dev)
 {
 	struct w8001 *w8001 = input_get_drvdata(dev);
+	int err;
+
+	err = mutex_lock_interruptible(&w8001->mutex);
+	if (err)
+		return err;
 
-	return w8001_command(w8001, W8001_CMD_START, false);
+	if (w8001->open_count++ == 0) {
+		err = w8001_command(w8001, W8001_CMD_START, false);
+		if (err)
+			w8001->open_count--;
+	}
+
+	mutex_unlock(&w8001->mutex);
+	return err;
 }
 
 static void w8001_close(struct input_dev *dev)
 {
 	struct w8001 *w8001 = input_get_drvdata(dev);
 
-	w8001_command(w8001, W8001_CMD_STOP, false);
+	mutex_lock(&w8001->mutex);
+
+	if (--w8001->open_count == 0)
+		w8001_command(w8001, W8001_CMD_STOP, false);
+
+	mutex_unlock(&w8001->mutex);
 }
 
-static int w8001_setup(struct w8001 *w8001)
+static int w8001_detect(struct w8001 *w8001)
 {
-	struct input_dev *dev = w8001->dev;
-	struct w8001_coord coord;
-	struct w8001_touch_query touch;
 	int error;
 
 	error = w8001_command(w8001, W8001_CMD_STOP, false);
@@ -393,105 +404,145 @@ static int w8001_setup(struct w8001 *w80
 
 	msleep(250);	/* wait 250ms before querying the device */
 
-	dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
-	strlcat(w8001->name, "Wacom Serial", sizeof(w8001->name));
+	return 0;
+}
 
-	__set_bit(INPUT_PROP_DIRECT, dev->propbit);
+static int w8001_setup_pen(struct w8001 *w8001, char *basename,
+			   size_t basename_sz)
+{
+	struct input_dev *dev = w8001->pen_dev;
+	struct w8001_coord coord;
+	int error;
 
 	/* penabled? */
 	error = w8001_command(w8001, W8001_CMD_QUERY, true);
-	if (!error) {
-		__set_bit(BTN_TOUCH, dev->keybit);
-		__set_bit(BTN_TOOL_PEN, dev->keybit);
-		__set_bit(BTN_TOOL_RUBBER, dev->keybit);
-		__set_bit(BTN_STYLUS, dev->keybit);
-		__set_bit(BTN_STYLUS2, dev->keybit);
-
-		parse_pen_data(w8001->response, &coord);
-		w8001->max_pen_x = coord.x;
-		w8001->max_pen_y = coord.y;
-
-		input_set_abs_params(dev, ABS_X, 0, coord.x, 0, 0);
-		input_set_abs_params(dev, ABS_Y, 0, coord.y, 0, 0);
-		input_abs_set_res(dev, ABS_X, W8001_PEN_RESOLUTION);
-		input_abs_set_res(dev, ABS_Y, W8001_PEN_RESOLUTION);
-		input_set_abs_params(dev, ABS_PRESSURE, 0, coord.pen_pressure, 0, 0);
-		if (coord.tilt_x && coord.tilt_y) {
-			input_set_abs_params(dev, ABS_TILT_X, 0, coord.tilt_x, 0, 0);
-			input_set_abs_params(dev, ABS_TILT_Y, 0, coord.tilt_y, 0, 0);
-		}
-		w8001->id = 0x90;
-		strlcat(w8001->name, " Penabled", sizeof(w8001->name));
+	if (error)
+		return error;
+
+	__set_bit(EV_KEY, dev->evbit);
+	__set_bit(EV_ABS, dev->evbit);
+	__set_bit(BTN_TOUCH, dev->keybit);
+	__set_bit(BTN_TOOL_PEN, dev->keybit);
+	__set_bit(BTN_TOOL_RUBBER, dev->keybit);
+	__set_bit(BTN_STYLUS, dev->keybit);
+	__set_bit(BTN_STYLUS2, dev->keybit);
+	__set_bit(INPUT_PROP_DIRECT, dev->propbit);
+
+	parse_pen_data(w8001->response, &coord);
+	w8001->max_pen_x = coord.x;
+	w8001->max_pen_y = coord.y;
+
+	input_set_abs_params(dev, ABS_X, 0, coord.x, 0, 0);
+	input_set_abs_params(dev, ABS_Y, 0, coord.y, 0, 0);
+	input_abs_set_res(dev, ABS_X, W8001_PEN_RESOLUTION);
+	input_abs_set_res(dev, ABS_Y, W8001_PEN_RESOLUTION);
+	input_set_abs_params(dev, ABS_PRESSURE, 0, coord.pen_pressure, 0, 0);
+	if (coord.tilt_x && coord.tilt_y) {
+		input_set_abs_params(dev, ABS_TILT_X, 0, coord.tilt_x, 0, 0);
+		input_set_abs_params(dev, ABS_TILT_Y, 0, coord.tilt_y, 0, 0);
 	}
 
+	w8001->id = 0x90;
+	strlcat(basename, " Penabled", basename_sz);
+
+	return 0;
+}
+
+static int w8001_setup_touch(struct w8001 *w8001, char *basename,
+			     size_t basename_sz)
+{
+	struct input_dev *dev = w8001->touch_dev;
+	struct w8001_touch_query touch;
+	int error;
+
+
 	/* Touch enabled? */
 	error = w8001_command(w8001, W8001_CMD_TOUCHQUERY, true);
-
+	if (error)
+		return error;
 	/*
 	 * Some non-touch devices may reply to the touch query. But their
 	 * second byte is empty, which indicates touch is not supported.
 	 */
-	if (!error && w8001->response[1]) {
-		__set_bit(BTN_TOUCH, dev->keybit);
-		__set_bit(BTN_TOOL_FINGER, dev->keybit);
-
-		parse_touchquery(w8001->response, &touch);
-		w8001->max_touch_x = touch.x;
-		w8001->max_touch_y = touch.y;
-
-		if (w8001->max_pen_x && w8001->max_pen_y) {
-			/* if pen is supported scale to pen maximum */
-			touch.x = w8001->max_pen_x;
-			touch.y = w8001->max_pen_y;
-			touch.panel_res = W8001_PEN_RESOLUTION;
-		}
+	if (!w8001->response[1])
+		return -ENXIO;
 
-		input_set_abs_params(dev, ABS_X, 0, touch.x, 0, 0);
-		input_set_abs_params(dev, ABS_Y, 0, touch.y, 0, 0);
-		input_abs_set_res(dev, ABS_X, touch.panel_res);
-		input_abs_set_res(dev, ABS_Y, touch.panel_res);
-
-		switch (touch.sensor_id) {
-		case 0:
-		case 2:
-			w8001->pktlen = W8001_PKTLEN_TOUCH93;
-			w8001->id = 0x93;
-			strlcat(w8001->name, " 1FG", sizeof(w8001->name));
-			break;
+	__set_bit(EV_KEY, dev->evbit);
+	__set_bit(EV_ABS, dev->evbit);
+	__set_bit(BTN_TOUCH, dev->keybit);
+	__set_bit(INPUT_PROP_DIRECT, dev->propbit);
 
-		case 1:
-		case 3:
-		case 4:
-			w8001->pktlen = W8001_PKTLEN_TOUCH9A;
-			strlcat(w8001->name, " 1FG", sizeof(w8001->name));
-			w8001->id = 0x9a;
-			break;
+	parse_touchquery(w8001->response, &touch);
+	w8001->max_touch_x = touch.x;
+	w8001->max_touch_y = touch.y;
+
+	if (w8001->max_pen_x && w8001->max_pen_y) {
+		/* if pen is supported scale to pen maximum */
+		touch.x = w8001->max_pen_x;
+		touch.y = w8001->max_pen_y;
+		touch.panel_res = W8001_PEN_RESOLUTION;
+	}
 
-		case 5:
-			w8001->pktlen = W8001_PKTLEN_TOUCH2FG;
+	input_set_abs_params(dev, ABS_X, 0, touch.x, 0, 0);
+	input_set_abs_params(dev, ABS_Y, 0, touch.y, 0, 0);
+	input_abs_set_res(dev, ABS_X, touch.panel_res);
+	input_abs_set_res(dev, ABS_Y, touch.panel_res);
 
-			input_mt_init_slots(dev, 2, 0);
-			input_set_abs_params(dev, ABS_MT_POSITION_X,
-						0, touch.x, 0, 0);
-			input_set_abs_params(dev, ABS_MT_POSITION_Y,
-						0, touch.y, 0, 0);
-			input_set_abs_params(dev, ABS_MT_TOOL_TYPE,
-						0, MT_TOOL_MAX, 0, 0);
-
-			strlcat(w8001->name, " 2FG", sizeof(w8001->name));
-			if (w8001->max_pen_x && w8001->max_pen_y)
-				w8001->id = 0xE3;
-			else
-				w8001->id = 0xE2;
-			break;
-		}
+	switch (touch.sensor_id) {
+	case 0:
+	case 2:
+		w8001->pktlen = W8001_PKTLEN_TOUCH93;
+		w8001->id = 0x93;
+		strlcat(basename, " 1FG", basename_sz);
+		break;
+
+	case 1:
+	case 3:
+	case 4:
+		w8001->pktlen = W8001_PKTLEN_TOUCH9A;
+		strlcat(basename, " 1FG", basename_sz);
+		w8001->id = 0x9a;
+		break;
+
+	case 5:
+		w8001->pktlen = W8001_PKTLEN_TOUCH2FG;
+
+		__set_bit(BTN_TOOL_DOUBLETAP, dev->keybit);
+		input_mt_init_slots(dev, 2, 0);
+		input_set_abs_params(dev, ABS_MT_POSITION_X,
+					0, touch.x, 0, 0);
+		input_set_abs_params(dev, ABS_MT_POSITION_Y,
+					0, touch.y, 0, 0);
+
+		strlcat(basename, " 2FG", basename_sz);
+		if (w8001->max_pen_x && w8001->max_pen_y)
+			w8001->id = 0xE3;
+		else
+			w8001->id = 0xE2;
+		break;
 	}
 
-	strlcat(w8001->name, " Touchscreen", sizeof(w8001->name));
+	strlcat(basename, " Touchscreen", basename_sz);
 
 	return 0;
 }
 
+static void w8001_set_devdata(struct input_dev *dev, struct w8001 *w8001,
+			      struct serio *serio)
+{
+	dev->phys = w8001->phys;
+	dev->id.bustype = BUS_RS232;
+	dev->id.product = w8001->id;
+	dev->id.vendor = 0x056a;
+	dev->id.version = 0x0100;
+	dev->open = w8001_open;
+	dev->close = w8001_close;
+
+	dev->dev.parent = &serio->dev;
+
+	input_set_drvdata(dev, w8001);
+}
+
 /*
  * w8001_disconnect() is the opposite of w8001_connect()
  */
@@ -502,7 +553,10 @@ static void w8001_disconnect(struct seri
 
 	serio_close(serio);
 
-	input_unregister_device(w8001->dev);
+	if (w8001->pen_dev)
+		input_unregister_device(w8001->pen_dev);
+	if (w8001->touch_dev)
+		input_unregister_device(w8001->touch_dev);
 	kfree(w8001);
 
 	serio_set_drvdata(serio, NULL);
@@ -517,18 +571,23 @@ static void w8001_disconnect(struct seri
 static int w8001_connect(struct serio *serio, struct serio_driver *drv)
 {
 	struct w8001 *w8001;
-	struct input_dev *input_dev;
-	int err;
+	struct input_dev *input_dev_pen;
+	struct input_dev *input_dev_touch;
+	char basename[64];
+	int err, err_pen, err_touch;
 
 	w8001 = kzalloc(sizeof(struct w8001), GFP_KERNEL);
-	input_dev = input_allocate_device();
-	if (!w8001 || !input_dev) {
+	input_dev_pen = input_allocate_device();
+	input_dev_touch = input_allocate_device();
+	if (!w8001 || !input_dev_pen || !input_dev_touch) {
 		err = -ENOMEM;
 		goto fail1;
 	}
 
 	w8001->serio = serio;
-	w8001->dev = input_dev;
+	w8001->pen_dev = input_dev_pen;
+	w8001->touch_dev = input_dev_touch;
+	mutex_init(&w8001->mutex);
 	init_completion(&w8001->cmd_done);
 	snprintf(w8001->phys, sizeof(w8001->phys), "%s/input0", serio->phys);
 
@@ -537,35 +596,67 @@ static int w8001_connect(struct serio *s
 	if (err)
 		goto fail2;
 
-	err = w8001_setup(w8001);
+	err = w8001_detect(w8001);
 	if (err)
 		goto fail3;
 
-	input_dev->name = w8001->name;
-	input_dev->phys = w8001->phys;
-	input_dev->id.product = w8001->id;
-	input_dev->id.bustype = BUS_RS232;
-	input_dev->id.vendor = 0x056a;
-	input_dev->id.version = 0x0100;
-	input_dev->dev.parent = &serio->dev;
+	/* For backwards-compatibility we compose the basename based on
+	 * capabilities and then just append the tool type
+	 */
+	strlcpy(basename, "Wacom Serial", sizeof(basename));
 
-	input_dev->open = w8001_open;
-	input_dev->close = w8001_close;
+	err_pen = w8001_setup_pen(w8001, basename, sizeof(basename));
+	err_touch = w8001_setup_touch(w8001, basename, sizeof(basename));
+	if (err_pen && err_touch) {
+		err = -ENXIO;
+		goto fail3;
+	}
 
-	input_set_drvdata(input_dev, w8001);
+	if (!err_pen) {
+		strlcpy(w8001->pen_name, basename, sizeof(w8001->pen_name));
+		strlcat(w8001->pen_name, " Pen", sizeof(w8001->pen_name));
+		input_dev_pen->name = w8001->pen_name;
+
+		w8001_set_devdata(input_dev_pen, w8001, serio);
+
+		err = input_register_device(w8001->pen_dev);
+		if (err)
+			goto fail3;
+	} else {
+		input_free_device(input_dev_pen);
+		input_dev_pen = NULL;
+		w8001->pen_dev = NULL;
+	}
 
-	err = input_register_device(w8001->dev);
-	if (err)
-		goto fail3;
+	if (!err_touch) {
+		strlcpy(w8001->touch_name, basename, sizeof(w8001->touch_name));
+		strlcat(w8001->touch_name, " Finger",
+			sizeof(w8001->touch_name));
+		input_dev_touch->name = w8001->touch_name;
+
+		w8001_set_devdata(input_dev_touch, w8001, serio);
+
+		err = input_register_device(w8001->touch_dev);
+		if (err)
+			goto fail4;
+	} else {
+		input_free_device(input_dev_touch);
+		input_dev_touch = NULL;
+		w8001->touch_dev = NULL;
+	}
 
 	return 0;
 
+fail4:
+	if (w8001->pen_dev)
+		input_unregister_device(w8001->pen_dev);
 fail3:
 	serio_close(serio);
 fail2:
 	serio_set_drvdata(serio, NULL);
 fail1:
-	input_free_device(input_dev);
+	input_free_device(input_dev_pen);
+	input_free_device(input_dev_touch);
 	kfree(w8001);
 	return err;
 }
--- zfcpdump-kernel-4.4.orig/drivers/input/touchscreen/zforce_ts.c
+++ zfcpdump-kernel-4.4/drivers/input/touchscreen/zforce_ts.c
@@ -370,8 +370,8 @@ static int zforce_touch_event(struct zfo
 			point.coord_x = point.coord_y = 0;
 		}
 
-		point.state = payload[9 * i + 5] & 0x03;
-		point.id = (payload[9 * i + 5] & 0xfc) >> 2;
+		point.state = payload[9 * i + 5] & 0x0f;
+		point.id = (payload[9 * i + 5] & 0xf0) >> 4;
 
 		/* determine touch major, minor and orientation */
 		point.area_major = max(payload[9 * i + 6],
--- zfcpdump-kernel-4.4.orig/drivers/iommu/amd_iommu.c
+++ zfcpdump-kernel-4.4/drivers/iommu/amd_iommu.c
@@ -91,6 +91,7 @@ struct iommu_dev_data {
 	struct list_head dev_data_list;	  /* For global dev_data_list */
 	struct protection_domain *domain; /* Domain the device is bound to */
 	u16 devid;			  /* PCI Device ID */
+	u16 alias;			  /* Alias Device ID */
 	bool iommu_v2;			  /* Device can make use of IOMMUv2 */
 	bool passthrough;		  /* Device is identity mapped */
 	struct {
@@ -125,6 +126,13 @@ static struct protection_domain *to_pdom
 	return container_of(dom, struct protection_domain, domain);
 }
 
+static inline u16 get_device_id(struct device *dev)
+{
+	struct pci_dev *pdev = to_pci_dev(dev);
+
+	return PCI_DEVID(pdev->bus->number, pdev->devfn);
+}
+
 static struct iommu_dev_data *alloc_dev_data(u16 devid)
 {
 	struct iommu_dev_data *dev_data;
@@ -162,6 +170,68 @@ out_unlock:
 	return dev_data;
 }
 
+static int __last_alias(struct pci_dev *pdev, u16 alias, void *data)
+{
+	*(u16 *)data = alias;
+	return 0;
+}
+
+static u16 get_alias(struct device *dev)
+{
+	struct pci_dev *pdev = to_pci_dev(dev);
+	u16 devid, ivrs_alias, pci_alias;
+
+	devid = get_device_id(dev);
+	ivrs_alias = amd_iommu_alias_table[devid];
+	pci_for_each_dma_alias(pdev, __last_alias, &pci_alias);
+
+	if (ivrs_alias == pci_alias)
+		return ivrs_alias;
+
+	/*
+	 * DMA alias showdown
+	 *
+	 * The IVRS is fairly reliable in telling us about aliases, but it
+	 * can't know about every screwy device.  If we don't have an IVRS
+	 * reported alias, use the PCI reported alias.  In that case we may
+	 * still need to initialize the rlookup and dev_table entries if the
+	 * alias is to a non-existent device.
+	 */
+	if (ivrs_alias == devid) {
+		if (!amd_iommu_rlookup_table[pci_alias]) {
+			amd_iommu_rlookup_table[pci_alias] =
+				amd_iommu_rlookup_table[devid];
+			memcpy(amd_iommu_dev_table[pci_alias].data,
+			       amd_iommu_dev_table[devid].data,
+			       sizeof(amd_iommu_dev_table[pci_alias].data));
+		}
+
+		return pci_alias;
+	}
+
+	pr_info("AMD-Vi: Using IVRS reported alias %02x:%02x.%d "
+		"for device %s[%04x:%04x], kernel reported alias "
+		"%02x:%02x.%d\n", PCI_BUS_NUM(ivrs_alias), PCI_SLOT(ivrs_alias),
+		PCI_FUNC(ivrs_alias), dev_name(dev), pdev->vendor, pdev->device,
+		PCI_BUS_NUM(pci_alias), PCI_SLOT(pci_alias),
+		PCI_FUNC(pci_alias));
+
+	/*
+	 * If we don't have a PCI DMA alias and the IVRS alias is on the same
+	 * bus, then the IVRS table may know about a quirk that we don't.
+	 */
+	if (pci_alias == devid &&
+	    PCI_BUS_NUM(ivrs_alias) == pdev->bus->number) {
+		pdev->dev_flags |= PCI_DEV_FLAGS_DMA_ALIAS_DEVFN;
+		pdev->dma_alias_devfn = ivrs_alias & 0xff;
+		pr_info("AMD-Vi: Added PCI DMA alias %02x.%d for %s\n",
+			PCI_SLOT(ivrs_alias), PCI_FUNC(ivrs_alias),
+			dev_name(dev));
+	}
+
+	return ivrs_alias;
+}
+
 static struct iommu_dev_data *find_dev_data(u16 devid)
 {
 	struct iommu_dev_data *dev_data;
@@ -174,13 +244,6 @@ static struct iommu_dev_data *find_dev_d
 	return dev_data;
 }
 
-static inline u16 get_device_id(struct device *dev)
-{
-	struct pci_dev *pdev = to_pci_dev(dev);
-
-	return PCI_DEVID(pdev->bus->number, pdev->devfn);
-}
-
 static struct iommu_dev_data *get_dev_data(struct device *dev)
 {
 	return dev->archdata.iommu;
@@ -289,9 +352,11 @@ static void init_iommu_group(struct devi
 	if (!domain)
 		goto out;
 
-	dma_domain = to_pdomain(domain)->priv;
+	if (to_pdomain(domain)->flags == PD_DMA_OPS_MASK) {
+		dma_domain = to_pdomain(domain)->priv;
+		init_unity_mappings_for_device(dev, dma_domain);
+	}
 
-	init_unity_mappings_for_device(dev, dma_domain);
 out:
 	iommu_group_put(group);
 }
@@ -308,6 +373,8 @@ static int iommu_init_device(struct devi
 	if (!dev_data)
 		return -ENOMEM;
 
+	dev_data->alias = get_alias(dev);
+
 	if (pci_iommuv2_capable(pdev)) {
 		struct amd_iommu *iommu;
 
@@ -328,7 +395,7 @@ static void iommu_ignore_device(struct d
 	u16 devid, alias;
 
 	devid = get_device_id(dev);
-	alias = amd_iommu_alias_table[devid];
+	alias = get_alias(dev);
 
 	memset(&amd_iommu_dev_table[devid], 0, sizeof(struct dev_table_entry));
 	memset(&amd_iommu_dev_table[alias], 0, sizeof(struct dev_table_entry));
@@ -1017,7 +1084,7 @@ static int device_flush_dte(struct iommu
 	int ret;
 
 	iommu = amd_iommu_rlookup_table[dev_data->devid];
-	alias = amd_iommu_alias_table[dev_data->devid];
+	alias = dev_data->alias;
 
 	ret = iommu_flush_dte(iommu, dev_data->devid);
 	if (!ret && alias != dev_data->devid)
@@ -1891,7 +1958,7 @@ static void do_attach(struct iommu_dev_d
 	bool ats;
 
 	iommu = amd_iommu_rlookup_table[dev_data->devid];
-	alias = amd_iommu_alias_table[dev_data->devid];
+	alias = dev_data->alias;
 	ats   = dev_data->ats.enabled;
 
 	/* Update data structures */
@@ -1905,7 +1972,7 @@ static void do_attach(struct iommu_dev_d
 	/* Update device table */
 	set_dte_entry(dev_data->devid, domain, ats);
 	if (alias != dev_data->devid)
-		set_dte_entry(dev_data->devid, domain, ats);
+		set_dte_entry(alias, domain, ats);
 
 	device_flush_dte(dev_data);
 }
@@ -1925,7 +1992,7 @@ static void do_detach(struct iommu_dev_d
 		return;
 
 	iommu = amd_iommu_rlookup_table[dev_data->devid];
-	alias = amd_iommu_alias_table[dev_data->devid];
+	alias = dev_data->alias;
 
 	/* decrease reference counters */
 	dev_data->domain->dev_iommu[iommu->index] -= 1;
@@ -2257,8 +2324,15 @@ static void update_device_table(struct p
 {
 	struct iommu_dev_data *dev_data;
 
-	list_for_each_entry(dev_data, &domain->dev_list, list)
+	list_for_each_entry(dev_data, &domain->dev_list, list) {
 		set_dte_entry(dev_data->devid, domain, dev_data->ats.enabled);
+
+		if (dev_data->devid == dev_data->alias)
+			continue;
+
+		/* There is an alias, update device table entry for it */
+		set_dte_entry(dev_data->alias, domain, dev_data->ats.enabled);
+	}
 }
 
 static void update_domain(struct protection_domain *domain)
@@ -2905,9 +2979,7 @@ static struct iommu_domain *amd_iommu_do
 static void amd_iommu_domain_free(struct iommu_domain *dom)
 {
 	struct protection_domain *domain;
-
-	if (!dom)
-		return;
+	struct dma_ops_domain *dma_dom;
 
 	domain = to_pdomain(dom);
 
@@ -2916,13 +2988,24 @@ static void amd_iommu_domain_free(struct
 
 	BUG_ON(domain->dev_cnt != 0);
 
-	if (domain->mode != PAGE_MODE_NONE)
-		free_pagetable(domain);
+	if (!dom)
+		return;
 
-	if (domain->flags & PD_IOMMUV2_MASK)
-		free_gcr3_table(domain);
+	switch (dom->type) {
+	case IOMMU_DOMAIN_DMA:
+		dma_dom = domain->priv;
+		dma_ops_domain_free(dma_dom);
+		break;
+	default:
+		if (domain->mode != PAGE_MODE_NONE)
+			free_pagetable(domain);
 
-	protection_domain_free(domain);
+		if (domain->flags & PD_IOMMUV2_MASK)
+			free_gcr3_table(domain);
+
+		protection_domain_free(domain);
+		break;
+	}
 }
 
 static void amd_iommu_detach_device(struct iommu_domain *dom,
--- zfcpdump-kernel-4.4.orig/drivers/iommu/amd_iommu_init.c
+++ zfcpdump-kernel-4.4/drivers/iommu/amd_iommu_init.c
@@ -228,6 +228,10 @@ static int amd_iommu_enable_interrupts(v
 static int __init iommu_go_to_state(enum iommu_init_state state);
 static void init_device_table_dma(void);
 
+static int iommu_pc_get_set_reg_val(struct amd_iommu *iommu,
+				    u8 bank, u8 cntr, u8 fxn,
+				    u64 *value, bool is_write);
+
 static inline void update_last_devid(u16 devid)
 {
 	if (devid > amd_iommu_last_bdf)
@@ -1016,6 +1020,34 @@ static void amd_iommu_erratum_746_workar
 }
 
 /*
+ * Family15h Model 30h-3fh (IOMMU Mishandles ATS Write Permission)
+ * Workaround:
+ *     BIOS should enable ATS write permission check by setting
+ *     L2_DEBUG_3[AtsIgnoreIWDis](D0F2xF4_x47[0]) = 1b
+ */
+static void amd_iommu_ats_write_check_workaround(struct amd_iommu *iommu)
+{
+	u32 value;
+
+	if ((boot_cpu_data.x86 != 0x15) ||
+	    (boot_cpu_data.x86_model < 0x30) ||
+	    (boot_cpu_data.x86_model > 0x3f))
+		return;
+
+	/* Test L2_DEBUG_3[AtsIgnoreIWDis] == 1 */
+	value = iommu_read_l2(iommu, 0x47);
+
+	if (value & BIT(0))
+		return;
+
+	/* Set L2_DEBUG_3[AtsIgnoreIWDis] = 1 */
+	iommu_write_l2(iommu, 0x47, value | BIT(0));
+
+	pr_info("AMD-Vi: Applying ATS write check workaround for IOMMU at %s\n",
+		dev_name(&iommu->dev->dev));
+}
+
+/*
  * This function clues the initialization function for one IOMMU
  * together and also allocates the command buffer and programs the
  * hardware. It does NOT enable the IOMMU. This is done afterwards.
@@ -1142,8 +1174,8 @@ static void init_iommu_perf_ctr(struct a
 	amd_iommu_pc_present = true;
 
 	/* Check if the performance counters can be written to */
-	if ((0 != amd_iommu_pc_get_set_reg_val(0, 0, 0, 0, &val, true)) ||
-	    (0 != amd_iommu_pc_get_set_reg_val(0, 0, 0, 0, &val2, false)) ||
+	if ((0 != iommu_pc_get_set_reg_val(iommu, 0, 0, 0, &val, true)) ||
+	    (0 != iommu_pc_get_set_reg_val(iommu, 0, 0, 0, &val2, false)) ||
 	    (val != val2)) {
 		pr_err("AMD-Vi: Unable to write to IOMMU perf counter.\n");
 		amd_iommu_pc_present = false;
@@ -1284,6 +1316,7 @@ static int iommu_init_pci(struct amd_iom
 	}
 
 	amd_iommu_erratum_746_workaround(iommu);
+	amd_iommu_ats_write_check_workaround(iommu);
 
 	iommu->iommu_dev = iommu_device_create(&iommu->dev->dev, iommu,
 					       amd_iommu_groups, "ivhd%d",
@@ -1330,13 +1363,23 @@ static int __init amd_iommu_init_pci(voi
 			break;
 	}
 
+	/*
+	 * Order is important here to make sure any unity map requirements are
+	 * fulfilled. The unity mappings are created and written to the device
+	 * table during the amd_iommu_init_api() call.
+	 *
+	 * After that we call init_device_table_dma() to make sure any
+	 * uninitialized DTE will block DMA, and in the end we flush the caches
+	 * of all IOMMUs to make sure the changes to the device table are
+	 * active.
+	 */
+	ret = amd_iommu_init_api();
+
 	init_device_table_dma();
 
 	for_each_iommu(iommu)
 		iommu_flush_all_caches(iommu);
 
-	ret = amd_iommu_init_api();
-
 	if (!ret)
 		print_iommu_info();
 
@@ -2283,22 +2326,15 @@ u8 amd_iommu_pc_get_max_counters(u16 dev
 }
 EXPORT_SYMBOL(amd_iommu_pc_get_max_counters);
 
-int amd_iommu_pc_get_set_reg_val(u16 devid, u8 bank, u8 cntr, u8 fxn,
+static int iommu_pc_get_set_reg_val(struct amd_iommu *iommu,
+				    u8 bank, u8 cntr, u8 fxn,
 				    u64 *value, bool is_write)
 {
-	struct amd_iommu *iommu;
 	u32 offset;
 	u32 max_offset_lim;
 
-	/* Make sure the IOMMU PC resource is available */
-	if (!amd_iommu_pc_present)
-		return -ENODEV;
-
-	/* Locate the iommu associated with the device ID */
-	iommu = amd_iommu_rlookup_table[devid];
-
 	/* Check for valid iommu and pc register indexing */
-	if (WARN_ON((iommu == NULL) || (fxn > 0x28) || (fxn & 7)))
+	if (WARN_ON((fxn > 0x28) || (fxn & 7)))
 		return -ENODEV;
 
 	offset = (u32)(((0x40|bank) << 12) | (cntr << 8) | fxn);
@@ -2322,3 +2358,16 @@ int amd_iommu_pc_get_set_reg_val(u16 dev
 	return 0;
 }
 EXPORT_SYMBOL(amd_iommu_pc_get_set_reg_val);
+
+int amd_iommu_pc_get_set_reg_val(u16 devid, u8 bank, u8 cntr, u8 fxn,
+				    u64 *value, bool is_write)
+{
+	struct amd_iommu *iommu = amd_iommu_rlookup_table[devid];
+
+	/* Make sure the IOMMU PC resource is available */
+	if (!amd_iommu_pc_present || iommu == NULL)
+		return -ENODEV;
+
+	return iommu_pc_get_set_reg_val(iommu, bank, cntr, fxn,
+					value, is_write);
+}
--- zfcpdump-kernel-4.4.orig/drivers/iommu/arm-smmu-v3.c
+++ zfcpdump-kernel-4.4/drivers/iommu/arm-smmu-v3.c
@@ -870,7 +870,7 @@ static void arm_smmu_cmdq_skip_err(struc
 	 * We may have concurrent producers, so we need to be careful
 	 * not to touch any of the shadow cmdq state.
 	 */
-	queue_read(cmd, Q_ENT(q, idx), q->ent_dwords);
+	queue_read(cmd, Q_ENT(q, cons), q->ent_dwords);
 	dev_err(smmu->dev, "skipping command in error state:\n");
 	for (i = 0; i < ARRAY_SIZE(cmd); ++i)
 		dev_err(smmu->dev, "\t0x%016llx\n", (unsigned long long)cmd[i]);
@@ -881,7 +881,7 @@ static void arm_smmu_cmdq_skip_err(struc
 		return;
 	}
 
-	queue_write(cmd, Q_ENT(q, idx), q->ent_dwords);
+	queue_write(Q_ENT(q, cons), cmd, q->ent_dwords);
 }
 
 static void arm_smmu_cmdq_issue_cmd(struct arm_smmu_device *smmu,
@@ -1025,6 +1025,9 @@ static void arm_smmu_write_strtab_ent(st
 		case STRTAB_STE_0_CFG_S2_TRANS:
 			ste_live = true;
 			break;
+		case STRTAB_STE_0_CFG_ABORT:
+			if (disable_bypass)
+				break;
 		default:
 			BUG(); /* STE corruption */
 		}
@@ -1919,6 +1922,7 @@ static struct iommu_ops arm_smmu_ops = {
 	.detach_dev		= arm_smmu_detach_dev,
 	.map			= arm_smmu_map,
 	.unmap			= arm_smmu_unmap,
+	.map_sg			= default_iommu_map_sg,
 	.iova_to_phys		= arm_smmu_iova_to_phys,
 	.add_device		= arm_smmu_add_device,
 	.remove_device		= arm_smmu_remove_device,
--- zfcpdump-kernel-4.4.orig/drivers/iommu/dma-iommu.c
+++ zfcpdump-kernel-4.4/drivers/iommu/dma-iommu.c
@@ -68,7 +68,8 @@ void iommu_put_dma_cookie(struct iommu_d
 	if (!iovad)
 		return;
 
-	put_iova_domain(iovad);
+	if (iovad->granule)
+		put_iova_domain(iovad);
 	kfree(iovad);
 	domain->iova_cookie = NULL;
 }
@@ -403,7 +404,7 @@ static int __finalise_sg(struct device *
 		unsigned int s_length = sg_dma_len(s);
 		unsigned int s_dma_len = s->length;
 
-		s->offset = s_offset;
+		s->offset += s_offset;
 		s->length = s_length;
 		sg_dma_address(s) = dma_addr + s_offset;
 		dma_addr += s_dma_len;
@@ -422,7 +423,7 @@ static void __invalidate_sg(struct scatt
 
 	for_each_sg(sg, s, nents, i) {
 		if (sg_dma_address(s) != DMA_ERROR_CODE)
-			s->offset = sg_dma_address(s);
+			s->offset += sg_dma_address(s);
 		if (sg_dma_len(s))
 			s->length = sg_dma_len(s);
 		sg_dma_address(s) = DMA_ERROR_CODE;
--- zfcpdump-kernel-4.4.orig/drivers/iommu/dmar.c
+++ zfcpdump-kernel-4.4/drivers/iommu/dmar.c
@@ -329,7 +329,8 @@ static int dmar_pci_bus_notifier(struct
 	/* Only care about add/remove events for physical functions */
 	if (pdev->is_virtfn)
 		return NOTIFY_DONE;
-	if (action != BUS_NOTIFY_ADD_DEVICE && action != BUS_NOTIFY_DEL_DEVICE)
+	if (action != BUS_NOTIFY_ADD_DEVICE &&
+	    action != BUS_NOTIFY_REMOVED_DEVICE)
 		return NOTIFY_DONE;
 
 	info = dmar_alloc_pci_notify_info(pdev, action);
@@ -339,7 +340,7 @@ static int dmar_pci_bus_notifier(struct
 	down_write(&dmar_global_lock);
 	if (action == BUS_NOTIFY_ADD_DEVICE)
 		dmar_pci_bus_add_dev(info);
-	else if (action == BUS_NOTIFY_DEL_DEVICE)
+	else if (action == BUS_NOTIFY_REMOVED_DEVICE)
 		dmar_pci_bus_del_dev(info);
 	up_write(&dmar_global_lock);
 
@@ -1347,7 +1348,7 @@ void dmar_disable_qi(struct intel_iommu
 
 	raw_spin_lock_irqsave(&iommu->register_lock, flags);
 
-	sts =  dmar_readq(iommu->reg + DMAR_GSTS_REG);
+	sts =  readl(iommu->reg + DMAR_GSTS_REG);
 	if (!(sts & DMA_GSTS_QIES))
 		goto end;
 
@@ -1857,10 +1858,11 @@ static int dmar_hp_remove_drhd(struct ac
 	/*
 	 * All PCI devices managed by this unit should have been destroyed.
 	 */
-	if (!dmaru->include_all && dmaru->devices && dmaru->devices_cnt)
+	if (!dmaru->include_all && dmaru->devices && dmaru->devices_cnt) {
 		for_each_active_dev_scope(dmaru->devices,
 					  dmaru->devices_cnt, i, dev)
 			return -EBUSY;
+	}
 
 	ret = dmar_ir_hotplug(dmaru, false);
 	if (ret == 0)
--- zfcpdump-kernel-4.4.orig/drivers/iommu/exynos-iommu.c
+++ zfcpdump-kernel-4.4/drivers/iommu/exynos-iommu.c
@@ -647,6 +647,7 @@ static struct platform_driver exynos_sys
 		.name		= "exynos-sysmmu",
 		.of_match_table	= sysmmu_of_match,
 		.pm		= &sysmmu_pm_ops,
+		.suppress_bind_attrs = true,
 	}
 };
 
--- zfcpdump-kernel-4.4.orig/drivers/iommu/intel-iommu.c
+++ zfcpdump-kernel-4.4/drivers/iommu/intel-iommu.c
@@ -1489,7 +1489,7 @@ static void iommu_disable_dev_iotlb(stru
 {
 	struct pci_dev *pdev;
 
-	if (dev_is_pci(info->dev))
+	if (!dev_is_pci(info->dev))
 		return;
 
 	pdev = to_pci_dev(info->dev);
@@ -2032,7 +2032,7 @@ out_unlock:
 	spin_unlock(&iommu->lock);
 	spin_unlock_irqrestore(&device_domain_lock, flags);
 
-	return 0;
+	return ret;
 }
 
 struct domain_context_mapping_data {
@@ -3169,11 +3169,6 @@ static int __init init_dmars(void)
 			}
 		}
 
-		iommu_flush_write_buffer(iommu);
-		iommu_set_root_entry(iommu);
-		iommu->flush.flush_context(iommu, 0, 0, 0, DMA_CCMD_GLOBAL_INVL);
-		iommu->flush.flush_iotlb(iommu, 0, 0, 0, DMA_TLB_GLOBAL_FLUSH);
-
 		if (!ecap_pass_through(iommu->ecap))
 			hw_pass_through = 0;
 #ifdef CONFIG_INTEL_IOMMU_SVM
@@ -3182,6 +3177,18 @@ static int __init init_dmars(void)
 #endif
 	}
 
+	/*
+	 * Now that qi is enabled on all iommus, set the root entry and flush
+	 * caches. This is required on some Intel X58 chipsets, otherwise the
+	 * flush_context function will loop forever and the boot hangs.
+	 */
+	for_each_active_iommu(iommu, drhd) {
+		iommu_flush_write_buffer(iommu);
+		iommu_set_root_entry(iommu);
+		iommu->flush.flush_context(iommu, 0, 0, 0, DMA_CCMD_GLOBAL_INVL);
+		iommu->flush.flush_iotlb(iommu, 0, 0, 0, DMA_TLB_GLOBAL_FLUSH);
+	}
+
 	if (iommu_pass_through)
 		iommu_identity_mapping |= IDENTMAP_ALL;
 
@@ -4175,10 +4182,11 @@ int dmar_check_one_atsr(struct acpi_dmar
 	if (!atsru)
 		return 0;
 
-	if (!atsru->include_all && atsru->devices && atsru->devices_cnt)
+	if (!atsru->include_all && atsru->devices && atsru->devices_cnt) {
 		for_each_active_dev_scope(atsru->devices, atsru->devices_cnt,
 					  i, dev)
 			return -EBUSY;
+	}
 
 	return 0;
 }
@@ -4367,7 +4375,7 @@ int dmar_iommu_notify_scope_dev(struct d
 				rmrru->devices_cnt);
 			if(ret < 0)
 				return ret;
-		} else if (info->event == BUS_NOTIFY_DEL_DEVICE) {
+		} else if (info->event == BUS_NOTIFY_REMOVED_DEVICE) {
 			dmar_remove_dev_scope(info, rmrr->segment,
 				rmrru->devices, rmrru->devices_cnt);
 		}
@@ -4387,7 +4395,7 @@ int dmar_iommu_notify_scope_dev(struct d
 				break;
 			else if(ret < 0)
 				return ret;
-		} else if (info->event == BUS_NOTIFY_DEL_DEVICE) {
+		} else if (info->event == BUS_NOTIFY_REMOVED_DEVICE) {
 			if (dmar_remove_dev_scope(info, atsr->segment,
 					atsru->devices, atsru->devices_cnt))
 				break;
--- zfcpdump-kernel-4.4.orig/drivers/iommu/intel-svm.c
+++ zfcpdump-kernel-4.4/drivers/iommu/intel-svm.c
@@ -249,12 +249,30 @@ static void intel_flush_pasid_dev(struct
 static void intel_mm_release(struct mmu_notifier *mn, struct mm_struct *mm)
 {
 	struct intel_svm *svm = container_of(mn, struct intel_svm, notifier);
+	struct intel_svm_dev *sdev;
 
+	/* This might end up being called from exit_mmap(), *before* the page
+	 * tables are cleared. And __mmu_notifier_release() will delete us from
+	 * the list of notifiers so that our invalidate_range() callback doesn't
+	 * get called when the page tables are cleared. So we need to protect
+	 * against hardware accessing those page tables.
+	 *
+	 * We do it by clearing the entry in the PASID table and then flushing
+	 * the IOTLB and the PASID table caches. This might upset hardware;
+	 * perhaps we'll want to point the PASID to a dummy PGD (like the zero
+	 * page) so that we end up taking a fault that the hardware really
+	 * *has* to handle gracefully without affecting other processes.
+	 */
 	svm->iommu->pasid_table[svm->pasid].val = 0;
+	wmb();
+
+	rcu_read_lock();
+	list_for_each_entry_rcu(sdev, &svm->devs, list) {
+		intel_flush_pasid_dev(svm, sdev, svm->pasid);
+		intel_flush_svm_range_dev(svm, sdev, 0, -1, 0, !svm->mm);
+	}
+	rcu_read_unlock();
 
-	/* There's no need to do any flush because we can't get here if there
-	 * are any devices left anyway. */
-	WARN_ON(!list_empty(&svm->devs));
 }
 
 static const struct mmu_notifier_ops intel_mmuops = {
@@ -379,7 +397,6 @@ int intel_svm_bind_mm(struct device *dev
 				goto out;
 			}
 			iommu->pasid_table[svm->pasid].val = (u64)__pa(mm->pgd) | 1;
-			mm = NULL;
 		} else
 			iommu->pasid_table[svm->pasid].val = (u64)__pa(init_mm.pgd) | 1 | (1ULL << 11);
 		wmb();
@@ -442,11 +459,11 @@ int intel_svm_unbind_mm(struct device *d
 				kfree_rcu(sdev, rcu);
 
 				if (list_empty(&svm->devs)) {
-					mmu_notifier_unregister(&svm->notifier, svm->mm);
 
 					idr_remove(&svm->iommu->pasid_idr, svm->pasid);
 					if (svm->mm)
-						mmput(svm->mm);
+						mmu_notifier_unregister(&svm->notifier, svm->mm);
+
 					/* We mandate that no page faults may be outstanding
 					 * for the PASID when intel_svm_unbind_mm() is called.
 					 * If that is not obeyed, subtle errors will happen.
@@ -507,6 +524,10 @@ static irqreturn_t prq_event_thread(int
 	struct intel_svm *svm = NULL;
 	int head, tail, handled = 0;
 
+	/* Clear PPR bit before reading head/tail registers, to
+	 * ensure that we get a new interrupt if needed. */
+	writel(DMA_PRS_PPR, iommu->reg + DMAR_PRS_REG);
+
 	tail = dmar_readq(iommu->reg + DMAR_PQT_REG) & PRQ_RING_MASK;
 	head = dmar_readq(iommu->reg + DMAR_PQH_REG) & PRQ_RING_MASK;
 	while (head != tail) {
@@ -551,6 +572,9 @@ static irqreturn_t prq_event_thread(int
 		 * any faults on kernel addresses. */
 		if (!svm->mm)
 			goto bad_req;
+		/* If the mm is already defunct, don't handle faults. */
+		if (!atomic_inc_not_zero(&svm->mm->mm_users))
+			goto bad_req;
 		down_read(&svm->mm->mmap_sem);
 		vma = find_extend_vma(svm->mm, address);
 		if (!vma || address < vma->vm_start)
@@ -567,6 +591,7 @@ static irqreturn_t prq_event_thread(int
 		result = QI_RESP_SUCCESS;
 	invalid:
 		up_read(&svm->mm->mmap_sem);
+		mmput(svm->mm);
 	bad_req:
 		/* Accounting for major/minor faults? */
 		rcu_read_lock();
--- zfcpdump-kernel-4.4.orig/drivers/iommu/intel_irq_remapping.c
+++ zfcpdump-kernel-4.4/drivers/iommu/intel_irq_remapping.c
@@ -629,7 +629,7 @@ static void iommu_disable_irq_remapping(
 
 	raw_spin_lock_irqsave(&iommu->register_lock, flags);
 
-	sts = dmar_readq(iommu->reg + DMAR_GSTS_REG);
+	sts = readl(iommu->reg + DMAR_GSTS_REG);
 	if (!(sts & DMA_GSTS_IRES))
 		goto end;
 
--- zfcpdump-kernel-4.4.orig/drivers/iommu/io-pgtable-arm.c
+++ zfcpdump-kernel-4.4/drivers/iommu/io-pgtable-arm.c
@@ -405,17 +405,18 @@ static void __arm_lpae_free_pgtable(stru
 	arm_lpae_iopte *start, *end;
 	unsigned long table_size;
 
-	/* Only leaf entries at the last level */
-	if (lvl == ARM_LPAE_MAX_LEVELS - 1)
-		return;
-
 	if (lvl == ARM_LPAE_START_LVL(data))
 		table_size = data->pgd_size;
 	else
 		table_size = 1UL << data->pg_shift;
 
 	start = ptep;
-	end = (void *)ptep + table_size;
+
+	/* Only leaf entries at the last level */
+	if (lvl == ARM_LPAE_MAX_LEVELS - 1)
+		end = ptep;
+	else
+		end = (void *)ptep + table_size;
 
 	while (ptep != end) {
 		arm_lpae_iopte pte = *ptep++;
--- zfcpdump-kernel-4.4.orig/drivers/iommu/iommu.c
+++ zfcpdump-kernel-4.4/drivers/iommu/iommu.c
@@ -848,7 +848,8 @@ struct iommu_group *iommu_group_get_for_
 	if (!group->default_domain) {
 		group->default_domain = __iommu_domain_alloc(dev->bus,
 							     IOMMU_DOMAIN_DMA);
-		group->domain = group->default_domain;
+		if (!group->domain)
+			group->domain = group->default_domain;
 	}
 
 	ret = iommu_group_add_device(group, dev);
--- zfcpdump-kernel-4.4.orig/drivers/irqchip/irq-atmel-aic-common.c
+++ zfcpdump-kernel-4.4/drivers/irqchip/irq-atmel-aic-common.c
@@ -86,7 +86,7 @@ int aic_common_set_priority(int priority
 	    priority > AT91_AIC_IRQ_MAX_PRIORITY)
 		return -EINVAL;
 
-	*val &= AT91_AIC_PRIOR;
+	*val &= ~AT91_AIC_PRIOR;
 	*val |= priority;
 
 	return 0;
--- zfcpdump-kernel-4.4.orig/drivers/irqchip/irq-atmel-aic.c
+++ zfcpdump-kernel-4.4/drivers/irqchip/irq-atmel-aic.c
@@ -176,6 +176,7 @@ static int aic_irq_domain_xlate(struct i
 {
 	struct irq_domain_chip_generic *dgc = d->gc;
 	struct irq_chip_generic *gc;
+	unsigned long flags;
 	unsigned smr;
 	int idx;
 	int ret;
@@ -194,12 +195,12 @@ static int aic_irq_domain_xlate(struct i
 
 	gc = dgc->gc[idx];
 
-	irq_gc_lock(gc);
+	irq_gc_lock_irqsave(gc, flags);
 	smr = irq_reg_readl(gc, AT91_AIC_SMR(*out_hwirq));
 	ret = aic_common_set_priority(intspec[2], &smr);
 	if (!ret)
 		irq_reg_writel(gc, smr, AT91_AIC_SMR(*out_hwirq));
-	irq_gc_unlock(gc);
+	irq_gc_unlock_irqrestore(gc, flags);
 
 	return ret;
 }
--- zfcpdump-kernel-4.4.orig/drivers/irqchip/irq-atmel-aic5.c
+++ zfcpdump-kernel-4.4/drivers/irqchip/irq-atmel-aic5.c
@@ -258,6 +258,7 @@ static int aic5_irq_domain_xlate(struct
 				 unsigned int *out_type)
 {
 	struct irq_chip_generic *bgc = irq_get_domain_generic_chip(d, 0);
+	unsigned long flags;
 	unsigned smr;
 	int ret;
 
@@ -269,13 +270,13 @@ static int aic5_irq_domain_xlate(struct
 	if (ret)
 		return ret;
 
-	irq_gc_lock(bgc);
+	irq_gc_lock_irqsave(bgc, flags);
 	irq_reg_writel(bgc, *out_hwirq, AT91_AIC5_SSR);
 	smr = irq_reg_readl(bgc, AT91_AIC5_SMR);
 	ret = aic_common_set_priority(intspec[2], &smr);
 	if (!ret)
 		irq_reg_writel(bgc, intspec[2] | smr, AT91_AIC5_SMR);
-	irq_gc_unlock(bgc);
+	irq_gc_unlock_irqrestore(bgc, flags);
 
 	return ret;
 }
--- zfcpdump-kernel-4.4.orig/drivers/irqchip/irq-gic-v2m.c
+++ zfcpdump-kernel-4.4/drivers/irqchip/irq-gic-v2m.c
@@ -15,9 +15,11 @@
 
 #define pr_fmt(fmt) "GICv2m: " fmt
 
+#include <linux/acpi.h>
 #include <linux/irq.h>
 #include <linux/irqdomain.h>
 #include <linux/kernel.h>
+#include <linux/msi.h>
 #include <linux/of_address.h>
 #include <linux/of_pci.h>
 #include <linux/slab.h>
@@ -55,7 +57,7 @@ static DEFINE_SPINLOCK(v2m_lock);
 
 struct v2m_data {
 	struct list_head entry;
-	struct device_node *node;
+	struct fwnode_handle *fwnode;
 	struct resource res;	/* GICv2m resource */
 	void __iomem *base;	/* GICv2m virt address */
 	u32 spi_start;		/* The SPI number that MSIs start */
@@ -138,6 +140,11 @@ static int gicv2m_irq_gic_domain_alloc(s
 		fwspec.param[0] = 0;
 		fwspec.param[1] = hwirq - 32;
 		fwspec.param[2] = IRQ_TYPE_EDGE_RISING;
+	} else if (is_fwnode_irqchip(domain->parent->fwnode)) {
+		fwspec.fwnode = domain->parent->fwnode;
+		fwspec.param_count = 2;
+		fwspec.param[0] = hwirq;
+		fwspec.param[1] = IRQ_TYPE_EDGE_RISING;
 	} else {
 		return -EINVAL;
 	}
@@ -254,7 +261,9 @@ static void gicv2m_teardown(void)
 		list_del(&v2m->entry);
 		kfree(v2m->bm);
 		iounmap(v2m->base);
-		of_node_put(v2m->node);
+		of_node_put(to_of_node(v2m->fwnode));
+		if (is_fwnode_irqchip(v2m->fwnode))
+			irq_domain_free_fwnode(v2m->fwnode);
 		kfree(v2m);
 	}
 }
@@ -268,7 +277,7 @@ static int gicv2m_allocate_domains(struc
 	if (!v2m)
 		return 0;
 
-	inner_domain = irq_domain_create_tree(of_node_to_fwnode(v2m->node),
+	inner_domain = irq_domain_create_tree(v2m->fwnode,
 					      &gicv2m_domain_ops, v2m);
 	if (!inner_domain) {
 		pr_err("Failed to create GICv2m domain\n");
@@ -277,10 +286,10 @@ static int gicv2m_allocate_domains(struc
 
 	inner_domain->bus_token = DOMAIN_BUS_NEXUS;
 	inner_domain->parent = parent;
-	pci_domain = pci_msi_create_irq_domain(of_node_to_fwnode(v2m->node),
+	pci_domain = pci_msi_create_irq_domain(v2m->fwnode,
 					       &gicv2m_msi_domain_info,
 					       inner_domain);
-	plat_domain = platform_msi_create_irq_domain(of_node_to_fwnode(v2m->node),
+	plat_domain = platform_msi_create_irq_domain(v2m->fwnode,
 						     &gicv2m_pmsi_domain_info,
 						     inner_domain);
 	if (!pci_domain || !plat_domain) {
@@ -296,8 +305,9 @@ static int gicv2m_allocate_domains(struc
 	return 0;
 }
 
-static int __init gicv2m_init_one(struct device_node *node,
-				  struct irq_domain *parent)
+static int __init gicv2m_init_one(struct fwnode_handle *fwnode,
+				  u32 spi_start, u32 nr_spis,
+				  struct resource *res)
 {
 	int ret;
 	struct v2m_data *v2m;
@@ -309,13 +319,9 @@ static int __init gicv2m_init_one(struct
 	}
 
 	INIT_LIST_HEAD(&v2m->entry);
-	v2m->node = node;
+	v2m->fwnode = fwnode;
 
-	ret = of_address_to_resource(node, 0, &v2m->res);
-	if (ret) {
-		pr_err("Failed to allocate v2m resource.\n");
-		goto err_free_v2m;
-	}
+	memcpy(&v2m->res, res, sizeof(struct resource));
 
 	v2m->base = ioremap(v2m->res.start, resource_size(&v2m->res));
 	if (!v2m->base) {
@@ -324,10 +330,9 @@ static int __init gicv2m_init_one(struct
 		goto err_free_v2m;
 	}
 
-	if (!of_property_read_u32(node, "arm,msi-base-spi", &v2m->spi_start) &&
-	    !of_property_read_u32(node, "arm,msi-num-spis", &v2m->nr_spis)) {
-		pr_info("Overriding V2M MSI_TYPER (base:%u, num:%u)\n",
-			v2m->spi_start, v2m->nr_spis);
+	if (spi_start && nr_spis) {
+		v2m->spi_start = spi_start;
+		v2m->nr_spis = nr_spis;
 	} else {
 		u32 typer = readl_relaxed(v2m->base + V2M_MSI_TYPER);
 
@@ -359,10 +364,10 @@ static int __init gicv2m_init_one(struct
 	}
 
 	list_add_tail(&v2m->entry, &v2m_nodes);
-	pr_info("Node %s: range[%#lx:%#lx], SPI[%d:%d]\n", node->name,
-		(unsigned long)v2m->res.start, (unsigned long)v2m->res.end,
-		v2m->spi_start, (v2m->spi_start + v2m->nr_spis));
 
+	pr_info("range[%#lx:%#lx], SPI[%d:%d]\n",
+		(unsigned long)res->start, (unsigned long)res->end,
+		v2m->spi_start, (v2m->spi_start + v2m->nr_spis));
 	return 0;
 
 err_iounmap:
@@ -377,17 +382,34 @@ static struct of_device_id gicv2m_device
 	{},
 };
 
-int __init gicv2m_of_init(struct device_node *node, struct irq_domain *parent)
+static int __init gicv2m_of_init(struct fwnode_handle *parent_handle,
+				 struct irq_domain *parent)
 {
 	int ret = 0;
+	struct device_node *node = to_of_node(parent_handle);
 	struct device_node *child;
 
 	for (child = of_find_matching_node(node, gicv2m_device_id); child;
 	     child = of_find_matching_node(child, gicv2m_device_id)) {
+		u32 spi_start = 0, nr_spis = 0;
+		struct resource res;
+
 		if (!of_find_property(child, "msi-controller", NULL))
 			continue;
 
-		ret = gicv2m_init_one(child, parent);
+		ret = of_address_to_resource(child, 0, &res);
+		if (ret) {
+			pr_err("Failed to allocate v2m resource.\n");
+			break;
+		}
+
+		if (!of_property_read_u32(child, "arm,msi-base-spi",
+					  &spi_start) &&
+		    !of_property_read_u32(child, "arm,msi-num-spis", &nr_spis))
+			pr_info("DT overriding V2M MSI_TYPER (base:%u, num:%u)\n",
+				spi_start, nr_spis);
+
+		ret = gicv2m_init_one(&child->fwnode, spi_start, nr_spis, &res);
 		if (ret) {
 			of_node_put(node);
 			break;
@@ -400,3 +422,100 @@ int __init gicv2m_of_init(struct device_
 		gicv2m_teardown();
 	return ret;
 }
+
+#ifdef CONFIG_ACPI
+static int acpi_num_msi;
+
+static struct fwnode_handle *gicv2m_get_fwnode(struct device *dev)
+{
+	struct v2m_data *data;
+
+	if (WARN_ON(acpi_num_msi <= 0))
+		return NULL;
+
+	/* We only return the fwnode of the first MSI frame. */
+	data = list_first_entry_or_null(&v2m_nodes, struct v2m_data, entry);
+	if (!data)
+		return NULL;
+
+	return data->fwnode;
+}
+
+static int __init
+acpi_parse_madt_msi(struct acpi_subtable_header *header,
+		    const unsigned long end)
+{
+	int ret;
+	struct resource res;
+	u32 spi_start = 0, nr_spis = 0;
+	struct acpi_madt_generic_msi_frame *m;
+	struct fwnode_handle *fwnode;
+
+	m = (struct acpi_madt_generic_msi_frame *)header;
+	if (BAD_MADT_ENTRY(m, end))
+		return -EINVAL;
+
+	res.start = m->base_address;
+	res.end = m->base_address + SZ_4K;
+
+	if (m->flags & ACPI_MADT_OVERRIDE_SPI_VALUES) {
+		spi_start = m->spi_base;
+		nr_spis = m->spi_count;
+
+		pr_info("ACPI overriding V2M MSI_TYPER (base:%u, num:%u)\n",
+			spi_start, nr_spis);
+	}
+
+	fwnode = irq_domain_alloc_fwnode((void *)m->base_address);
+	if (!fwnode) {
+		pr_err("Unable to allocate GICv2m domain token\n");
+		return -EINVAL;
+	}
+
+	ret = gicv2m_init_one(fwnode, spi_start, nr_spis, &res);
+	if (ret)
+		irq_domain_free_fwnode(fwnode);
+
+	return ret;
+}
+
+static int __init gicv2m_acpi_init(struct irq_domain *parent)
+{
+	int ret;
+
+	if (acpi_num_msi > 0)
+		return 0;
+
+	acpi_num_msi = acpi_table_parse_madt(ACPI_MADT_TYPE_GENERIC_MSI_FRAME,
+				      acpi_parse_madt_msi, 0);
+
+	if (acpi_num_msi <= 0)
+		goto err_out;
+
+	ret = gicv2m_allocate_domains(parent);
+	if (ret)
+		goto err_out;
+
+	pci_msi_register_fwnode_provider(&gicv2m_get_fwnode);
+
+	return 0;
+
+err_out:
+	gicv2m_teardown();
+	return -EINVAL;
+}
+#else /* CONFIG_ACPI */
+static int __init gicv2m_acpi_init(struct irq_domain *parent)
+{
+	return -EINVAL;
+}
+#endif /* CONFIG_ACPI */
+
+int __init gicv2m_init(struct fwnode_handle *parent_handle,
+		       struct irq_domain *parent)
+{
+	if (is_of_node(parent_handle))
+		return gicv2m_of_init(parent_handle, parent);
+
+	return gicv2m_acpi_init(parent);
+}
--- zfcpdump-kernel-4.4.orig/drivers/irqchip/irq-gic-v3-its.c
+++ zfcpdump-kernel-4.4/drivers/irqchip/irq-gic-v3-its.c
@@ -41,6 +41,7 @@
 
 #define ITS_FLAGS_CMDQ_NEEDS_FLUSHING		(1ULL << 0)
 #define ITS_FLAGS_WORKAROUND_CAVIUM_22375	(1ULL << 1)
+#define ITS_FLAGS_WORKAROUND_CAVIUM_23144	(1ULL << 2)
 
 #define RDIST_FLAGS_PROPBASE_NEEDS_FLUSHING	(1 << 0)
 
@@ -71,6 +72,7 @@ struct its_node {
 	struct list_head	its_device_list;
 	u64			flags;
 	u32			ite_size;
+	int			numa_node;
 };
 
 #define ITS_ITT_ALIGN		SZ_256
@@ -597,19 +599,26 @@ static void its_unmask_irq(struct irq_da
 	lpi_set_config(d, true);
 }
 
-static void its_eoi_irq(struct irq_data *d)
-{
-	gic_write_eoir(d->hwirq);
-}
-
 static int its_set_affinity(struct irq_data *d, const struct cpumask *mask_val,
 			    bool force)
 {
-	unsigned int cpu = cpumask_any_and(mask_val, cpu_online_mask);
+	unsigned int cpu;
+	const struct cpumask *cpu_mask = cpu_online_mask;
 	struct its_device *its_dev = irq_data_get_irq_chip_data(d);
 	struct its_collection *target_col;
 	u32 id = its_get_event_id(d);
 
+       /* lpi cannot be routed to a redistributor that is on a foreign node */
+	if (its_dev->its->flags & ITS_FLAGS_WORKAROUND_CAVIUM_23144) {
+		if (its_dev->its->numa_node >= 0) {
+			cpu_mask = cpumask_of_node(its_dev->its->numa_node);
+			if (!cpumask_intersects(mask_val, cpu_mask))
+				return -EINVAL;
+		}
+	}
+
+	cpu = cpumask_any_and(mask_val, cpu_mask);
+
 	if (cpu >= nr_cpu_ids)
 		return -EINVAL;
 
@@ -638,7 +647,7 @@ static struct irq_chip its_irq_chip = {
 	.name			= "ITS",
 	.irq_mask		= its_mask_irq,
 	.irq_unmask		= its_unmask_irq,
-	.irq_eoi		= its_eoi_irq,
+	.irq_eoi		= irq_chip_eoi_parent,
 	.irq_set_affinity	= its_set_affinity,
 	.irq_compose_msi_msg	= its_irq_compose_msi_msg,
 };
@@ -1086,6 +1095,16 @@ static void its_cpu_init_collection(void
 	list_for_each_entry(its, &its_nodes, entry) {
 		u64 target;
 
+		/* avoid cross node collections and its mapping */
+		if (its->flags & ITS_FLAGS_WORKAROUND_CAVIUM_23144) {
+			struct device_node *cpu_node;
+
+			cpu_node = of_get_cpu_node(cpu, NULL);
+			if (its->numa_node != NUMA_NO_NODE &&
+				its->numa_node != of_node_to_nid(cpu_node))
+				continue;
+		}
+
 		/*
 		 * We now have to bind each collection to its target
 		 * redistributor.
@@ -1313,9 +1332,14 @@ static void its_irq_domain_activate(stru
 {
 	struct its_device *its_dev = irq_data_get_irq_chip_data(d);
 	u32 event = its_get_event_id(d);
+	const struct cpumask *cpu_mask = cpu_online_mask;
+
+	/* get the cpu_mask of local node */
+	if (its_dev->its->numa_node >= 0)
+		cpu_mask = cpumask_of_node(its_dev->its->numa_node);
 
 	/* Bind the LPI to the first possible CPU */
-	its_dev->event_map.col_map[event] = cpumask_first(cpu_online_mask);
+	its_dev->event_map.col_map[event] = cpumask_first(cpu_mask);
 
 	/* Map the GIC IRQ and event to the device */
 	its_send_mapvi(its_dev, d->hwirq, event);
@@ -1405,6 +1429,13 @@ static void __maybe_unused its_enable_qu
 	its->flags |= ITS_FLAGS_WORKAROUND_CAVIUM_22375;
 }
 
+static void __maybe_unused its_enable_quirk_cavium_23144(void *data)
+{
+	struct its_node *its = data;
+
+	its->flags |= ITS_FLAGS_WORKAROUND_CAVIUM_23144;
+}
+
 static const struct gic_quirk its_quirks[] = {
 #ifdef CONFIG_CAVIUM_ERRATUM_22375
 	{
@@ -1414,6 +1445,14 @@ static const struct gic_quirk its_quirks
 		.init	= its_enable_quirk_cavium_22375,
 	},
 #endif
+#ifdef CONFIG_CAVIUM_ERRATUM_23144
+	{
+		.desc	= "ITS: Cavium erratum 23144",
+		.iidr	= 0xa100034c,	/* ThunderX pass 1.x */
+		.mask	= 0xffff0fff,
+		.init	= its_enable_quirk_cavium_23144,
+	},
+#endif
 	{
 	}
 };
@@ -1475,6 +1514,7 @@ static int its_probe(struct device_node
 	its->base = its_base;
 	its->phys_base = res.start;
 	its->ite_size = ((readl_relaxed(its_base + GITS_TYPER) >> 4) & 0xf) + 1;
+	its->numa_node = of_node_to_nid(node);
 
 	its->cmd_base = kzalloc(ITS_CMD_QUEUE_SZ, GFP_KERNEL);
 	if (!its->cmd_base) {
--- zfcpdump-kernel-4.4.orig/drivers/irqchip/irq-gic-v3.c
+++ zfcpdump-kernel-4.4/drivers/irqchip/irq-gic-v3.c
@@ -361,6 +361,13 @@ static asmlinkage void __exception_irq_e
 			if (static_key_true(&supports_deactivate))
 				gic_write_dir(irqnr);
 #ifdef CONFIG_SMP
+			/*
+			 * Unlike GICv2, we don't need an smp_rmb() here.
+			 * The control dependency from gic_read_iar to
+			 * the ISB in gic_write_eoir is enough to ensure
+			 * that any shared data read by handle_IPI will
+			 * be read after the ACK.
+			 */
 			handle_IPI(irqnr, regs);
 #else
 			WARN_ONCE(true, "Unexpected SGI received!\n");
@@ -380,6 +387,15 @@ static void __init gic_dist_init(void)
 	writel_relaxed(0, base + GICD_CTLR);
 	gic_dist_wait_for_rwp();
 
+	/*
+	 * Configure SPIs as non-secure Group-1. This will only matter
+	 * if the GIC only has a single security state. This will not
+	 * do the right thing if the kernel is running in secure mode,
+	 * but that's not the intended use case anyway.
+	 */
+	for (i = 32; i < gic_data.irq_nr; i += 32)
+		writel_relaxed(~0, base + GICD_IGROUPR + i / 8);
+
 	gic_dist_config(base, gic_data.irq_nr, gic_dist_wait_for_rwp);
 
 	/* Enable distributor with ARE, Group1 */
@@ -494,6 +510,9 @@ static void gic_cpu_init(void)
 
 	rbase = gic_data_rdist_sgi_base();
 
+	/* Configure SGIs/PPIs as non-secure Group-1 */
+	writel_relaxed(~0, rbase + GICR_IGROUPR0);
+
 	gic_cpu_config(rbase, gic_redist_wait_for_rwp);
 
 	/* Give LPIs a spin */
@@ -525,7 +544,7 @@ static struct notifier_block gic_cpu_not
 static u16 gic_compute_target_list(int *base_cpu, const struct cpumask *mask,
 				   unsigned long cluster_id)
 {
-	int cpu = *base_cpu;
+	int next_cpu, cpu = *base_cpu;
 	unsigned long mpidr = cpu_logical_map(cpu);
 	u16 tlist = 0;
 
@@ -539,9 +558,10 @@ static u16 gic_compute_target_list(int *
 
 		tlist |= 1 << (mpidr & 0xf);
 
-		cpu = cpumask_next(cpu, mask);
-		if (cpu >= nr_cpu_ids)
+		next_cpu = cpumask_next(cpu, mask);
+		if (next_cpu >= nr_cpu_ids)
 			goto out;
+		cpu = next_cpu;
 
 		mpidr = cpu_logical_map(cpu);
 
--- zfcpdump-kernel-4.4.orig/drivers/irqchip/irq-gic.c
+++ zfcpdump-kernel-4.4/drivers/irqchip/irq-gic.c
@@ -347,6 +347,14 @@ static void __exception_irq_entry gic_ha
 			if (static_key_true(&supports_deactivate))
 				writel_relaxed(irqstat, cpu_base + GIC_CPU_DEACTIVATE);
 #ifdef CONFIG_SMP
+			/*
+			 * Ensure any shared data written by the CPU sending
+			 * the IPI is read after we've read the ACK register
+			 * on the GIC.
+			 *
+			 * Pairs with the write barrier in gic_raise_softirq
+			 */
+			smp_rmb();
 			handle_IPI(irqnr, regs);
 #endif
 			continue;
@@ -972,7 +980,7 @@ static int gic_irq_domain_translate(stru
 		return 0;
 	}
 
-	if (fwspec->fwnode->type == FWNODE_IRQCHIP) {
+	if (is_fwnode_irqchip(fwspec->fwnode)) {
 		if(fwspec->param_count != 2)
 			return -EINVAL;
 
@@ -1234,7 +1242,7 @@ gic_of_init(struct device_node *node, st
 	}
 
 	if (IS_ENABLED(CONFIG_ARM_GIC_V2M))
-		gicv2m_of_init(node, gic_data[gic_cnt].domain);
+		gicv2m_init(&node->fwnode, gic_data[gic_cnt].domain);
 
 	gic_cnt++;
 	return 0;
@@ -1359,6 +1367,10 @@ static int __init gic_v2_acpi_init(struc
 	__gic_init_bases(0, -1, dist_base, cpu_base, 0, domain_handle);
 
 	acpi_set_irq_model(ACPI_IRQ_MODEL_GIC, domain_handle);
+
+	if (IS_ENABLED(CONFIG_ARM_GIC_V2M))
+		gicv2m_init(NULL, gic_data[0].domain);
+
 	return 0;
 }
 IRQCHIP_ACPI_DECLARE(gic_v2, ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR,
--- zfcpdump-kernel-4.4.orig/drivers/irqchip/irq-mxs.c
+++ zfcpdump-kernel-4.4/drivers/irqchip/irq-mxs.c
@@ -183,7 +183,7 @@ static void __iomem * __init icoll_init_
 	void __iomem *icoll_base;
 
 	icoll_base = of_io_request_and_map(np, 0, np->name);
-	if (!icoll_base)
+	if (IS_ERR(icoll_base))
 		panic("%s: unable to map resource", np->full_name);
 	return icoll_base;
 }
@@ -241,6 +241,7 @@ static int __init asm9260_of_init(struct
 		writel(0, icoll_priv.intr + i);
 
 	icoll_add_domain(np, ASM9260_NUM_IRQS);
+	set_handle_irq(icoll_handle_irq);
 
 	return 0;
 }
--- zfcpdump-kernel-4.4.orig/drivers/irqchip/irq-omap-intc.c
+++ zfcpdump-kernel-4.4/drivers/irqchip/irq-omap-intc.c
@@ -47,6 +47,7 @@
 #define INTC_ILR0		0x0100
 
 #define ACTIVEIRQ_MASK		0x7f	/* omap2/3 active interrupt bits */
+#define SPURIOUSIRQ_MASK	(0x1ffffff << 7)
 #define INTCPS_NR_ILR_REGS	128
 #define INTCPS_NR_MIR_REGS	4
 
@@ -330,11 +331,35 @@ static int __init omap_init_irq(u32 base
 static asmlinkage void __exception_irq_entry
 omap_intc_handle_irq(struct pt_regs *regs)
 {
+	extern unsigned long irq_err_count;
 	u32 irqnr;
 
 	irqnr = intc_readl(INTC_SIR);
+
+	/*
+	 * A spurious IRQ can result if interrupt that triggered the
+	 * sorting is no longer active during the sorting (10 INTC
+	 * functional clock cycles after interrupt assertion). Or a
+	 * change in interrupt mask affected the result during sorting
+	 * time. There is no special handling required except ignoring
+	 * the SIR register value just read and retrying.
+	 * See section 6.2.5 of AM335x TRM Literature Number: SPRUH73K
+	 *
+	 * Many a times, a spurious interrupt situation has been fixed
+	 * by adding a flush for the posted write acking the IRQ in
+	 * the device driver. Typically, this is going be the device
+	 * driver whose interrupt was handled just before the spurious
+	 * IRQ occurred. Pay attention to those device drivers if you
+	 * run into hitting the spurious IRQ condition below.
+	 */
+	if (unlikely((irqnr & SPURIOUSIRQ_MASK) == SPURIOUSIRQ_MASK)) {
+		pr_err_once("%s: spurious irq!\n", __func__);
+		irq_err_count++;
+		omap_ack_irq(NULL);
+		return;
+	}
+
 	irqnr &= ACTIVEIRQ_MASK;
-	WARN_ONCE(!irqnr, "Spurious IRQ ?\n");
 	handle_domain_irq(domain, irqnr, regs);
 }
 
--- zfcpdump-kernel-4.4.orig/drivers/irqchip/irq-sunxi-nmi.c
+++ zfcpdump-kernel-4.4/drivers/irqchip/irq-sunxi-nmi.c
@@ -154,9 +154,9 @@ static int __init sunxi_sc_nmi_irq_init(
 
 	gc = irq_get_domain_generic_chip(domain, 0);
 	gc->reg_base = of_io_request_and_map(node, 0, of_node_full_name(node));
-	if (!gc->reg_base) {
+	if (IS_ERR(gc->reg_base)) {
 		pr_err("unable to map resource\n");
-		ret = -ENOMEM;
+		ret = PTR_ERR(gc->reg_base);
 		goto fail_irqd_remove;
 	}
 
--- zfcpdump-kernel-4.4.orig/drivers/leds/Kconfig
+++ zfcpdump-kernel-4.4/drivers/leds/Kconfig
@@ -230,7 +230,6 @@ config LEDS_LP55XX_COMMON
 	tristate "Common Driver for TI/National LP5521/5523/55231/5562/8501"
 	depends on LEDS_LP5521 || LEDS_LP5523 || LEDS_LP5562 || LEDS_LP8501
 	select FW_LOADER
-	select FW_LOADER_USER_HELPER
 	help
 	  This option supports common operations for LP5521/5523/55231/5562/8501
 	  devices.
--- zfcpdump-kernel-4.4.orig/drivers/lightnvm/Makefile
+++ zfcpdump-kernel-4.4/drivers/lightnvm/Makefile
@@ -2,6 +2,6 @@
 # Makefile for Open-Channel SSDs.
 #
 
-obj-$(CONFIG_NVM)		:= core.o
+obj-$(CONFIG_NVM)		:= core.o sysblk.o
 obj-$(CONFIG_NVM_GENNVM) 	+= gennvm.o
 obj-$(CONFIG_NVM_RRPC)		+= rrpc.o
--- zfcpdump-kernel-4.4.orig/drivers/lightnvm/core.c
+++ zfcpdump-kernel-4.4/drivers/lightnvm/core.c
@@ -27,6 +27,7 @@
 #include <linux/module.h>
 #include <linux/miscdevice.h>
 #include <linux/lightnvm.h>
+#include <linux/sched/sysctl.h>
 #include <uapi/linux/lightnvm.h>
 
 static LIST_HEAD(nvm_targets);
@@ -105,6 +106,9 @@ struct nvmm_type *nvm_init_mgr(struct nv
 	lockdep_assert_held(&nvm_lock);
 
 	list_for_each_entry(mt, &nvm_mgrs, list) {
+		if (strncmp(dev->sb.mmtype, mt->name, NVM_MMTYPE_LEN))
+			continue;
+
 		ret = mt->register_mgr(dev);
 		if (ret < 0) {
 			pr_err("nvm: media mgr failed to init (%d) on dev %s\n",
@@ -166,6 +170,20 @@ static struct nvm_dev *nvm_find_nvm_dev(
 	return NULL;
 }
 
+struct nvm_block *nvm_get_blk_unlocked(struct nvm_dev *dev, struct nvm_lun *lun,
+							unsigned long flags)
+{
+	return dev->mt->get_blk_unlocked(dev, lun, flags);
+}
+EXPORT_SYMBOL(nvm_get_blk_unlocked);
+
+/* Assumes that all valid pages have already been moved on release to bm */
+void nvm_put_blk_unlocked(struct nvm_dev *dev, struct nvm_block *blk)
+{
+	return dev->mt->put_blk_unlocked(dev, blk);
+}
+EXPORT_SYMBOL(nvm_put_blk_unlocked);
+
 struct nvm_block *nvm_get_blk(struct nvm_dev *dev, struct nvm_lun *lun,
 							unsigned long flags)
 {
@@ -192,6 +210,206 @@ int nvm_erase_blk(struct nvm_dev *dev, s
 }
 EXPORT_SYMBOL(nvm_erase_blk);
 
+void nvm_addr_to_generic_mode(struct nvm_dev *dev, struct nvm_rq *rqd)
+{
+	int i;
+
+	if (rqd->nr_pages > 1) {
+		for (i = 0; i < rqd->nr_pages; i++)
+			rqd->ppa_list[i] = dev_to_generic_addr(dev,
+							rqd->ppa_list[i]);
+	} else {
+		rqd->ppa_addr = dev_to_generic_addr(dev, rqd->ppa_addr);
+	}
+}
+EXPORT_SYMBOL(nvm_addr_to_generic_mode);
+
+void nvm_generic_to_addr_mode(struct nvm_dev *dev, struct nvm_rq *rqd)
+{
+	int i;
+
+	if (rqd->nr_pages > 1) {
+		for (i = 0; i < rqd->nr_pages; i++)
+			rqd->ppa_list[i] = generic_to_dev_addr(dev,
+							rqd->ppa_list[i]);
+	} else {
+		rqd->ppa_addr = generic_to_dev_addr(dev, rqd->ppa_addr);
+	}
+}
+EXPORT_SYMBOL(nvm_generic_to_addr_mode);
+
+int nvm_set_rqd_ppalist(struct nvm_dev *dev, struct nvm_rq *rqd,
+					struct ppa_addr *ppas, int nr_ppas)
+{
+	int i, plane_cnt, pl_idx;
+
+	if (dev->plane_mode == NVM_PLANE_SINGLE && nr_ppas == 1) {
+		rqd->nr_pages = 1;
+		rqd->ppa_addr = ppas[0];
+
+		return 0;
+	}
+
+	plane_cnt = (1 << dev->plane_mode);
+	rqd->nr_pages = plane_cnt * nr_ppas;
+
+	if (dev->ops->max_phys_sect < rqd->nr_pages)
+		return -EINVAL;
+
+	rqd->ppa_list = nvm_dev_dma_alloc(dev, GFP_KERNEL, &rqd->dma_ppa_list);
+	if (!rqd->ppa_list) {
+		pr_err("nvm: failed to allocate dma memory\n");
+		return -ENOMEM;
+	}
+
+	for (pl_idx = 0; pl_idx < plane_cnt; pl_idx++) {
+		for (i = 0; i < nr_ppas; i++) {
+			ppas[i].g.pl = pl_idx;
+			rqd->ppa_list[(pl_idx * nr_ppas) + i] = ppas[i];
+		}
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL(nvm_set_rqd_ppalist);
+
+void nvm_free_rqd_ppalist(struct nvm_dev *dev, struct nvm_rq *rqd)
+{
+	if (!rqd->ppa_list)
+		return;
+
+	nvm_dev_dma_free(dev, rqd->ppa_list, rqd->dma_ppa_list);
+}
+EXPORT_SYMBOL(nvm_free_rqd_ppalist);
+
+int nvm_erase_ppa(struct nvm_dev *dev, struct ppa_addr *ppas, int nr_ppas)
+{
+	struct nvm_rq rqd;
+	int ret;
+
+	if (!dev->ops->erase_block)
+		return 0;
+
+	memset(&rqd, 0, sizeof(struct nvm_rq));
+
+	ret = nvm_set_rqd_ppalist(dev, &rqd, ppas, nr_ppas);
+	if (ret)
+		return ret;
+
+	nvm_generic_to_addr_mode(dev, &rqd);
+
+	ret = dev->ops->erase_block(dev, &rqd);
+
+	nvm_free_rqd_ppalist(dev, &rqd);
+
+	return ret;
+}
+EXPORT_SYMBOL(nvm_erase_ppa);
+
+void nvm_end_io(struct nvm_rq *rqd, int error)
+{
+	rqd->error = error;
+	rqd->end_io(rqd);
+}
+EXPORT_SYMBOL(nvm_end_io);
+
+static void nvm_end_io_sync(struct nvm_rq *rqd)
+{
+	struct completion *waiting = rqd->wait;
+
+	rqd->wait = NULL;
+
+	complete(waiting);
+}
+
+int nvm_submit_ppa(struct nvm_dev *dev, struct ppa_addr *ppa, int nr_ppas,
+				int opcode, int flags, void *buf, int len)
+{
+	DECLARE_COMPLETION_ONSTACK(wait);
+	struct nvm_rq rqd;
+	struct bio *bio;
+	int ret;
+	unsigned long hang_check;
+
+	bio = bio_map_kern(dev->q, buf, len, GFP_KERNEL);
+	if (IS_ERR_OR_NULL(bio))
+		return -ENOMEM;
+
+	memset(&rqd, 0, sizeof(struct nvm_rq));
+	ret = nvm_set_rqd_ppalist(dev, &rqd, ppa, nr_ppas);
+	if (ret) {
+		bio_put(bio);
+		return ret;
+	}
+
+	rqd.opcode = opcode;
+	rqd.bio = bio;
+	rqd.wait = &wait;
+	rqd.dev = dev;
+	rqd.end_io = nvm_end_io_sync;
+	rqd.flags = flags;
+	nvm_generic_to_addr_mode(dev, &rqd);
+
+	ret = dev->ops->submit_io(dev, &rqd);
+
+	/* Prevent hang_check timer from firing at us during very long I/O */
+	hang_check = sysctl_hung_task_timeout_secs;
+	if (hang_check)
+		while (!wait_for_completion_io_timeout(&wait, hang_check * (HZ/2)));
+	else
+		wait_for_completion_io(&wait);
+
+	nvm_free_rqd_ppalist(dev, &rqd);
+
+	return rqd.error;
+}
+EXPORT_SYMBOL(nvm_submit_ppa);
+
+static int nvm_init_slc_tbl(struct nvm_dev *dev, struct nvm_id_group *grp)
+{
+	int i;
+
+	dev->lps_per_blk = dev->pgs_per_blk;
+	dev->lptbl = kcalloc(dev->lps_per_blk, sizeof(int), GFP_KERNEL);
+	if (!dev->lptbl)
+		return -ENOMEM;
+
+	/* Just a linear array */
+	for (i = 0; i < dev->lps_per_blk; i++)
+		dev->lptbl[i] = i;
+
+	return 0;
+}
+
+static int nvm_init_mlc_tbl(struct nvm_dev *dev, struct nvm_id_group *grp)
+{
+	int i, p;
+	struct nvm_id_lp_mlc *mlc = &grp->lptbl.mlc;
+
+	if (!mlc->num_pairs)
+		return 0;
+
+	dev->lps_per_blk = mlc->num_pairs;
+	dev->lptbl = kcalloc(dev->lps_per_blk, sizeof(int), GFP_KERNEL);
+	if (!dev->lptbl)
+		return -ENOMEM;
+
+	/* The lower page table encoding consists of a list of bytes, where each
+	 * has a lower and an upper half. The first half byte maintains the
+	 * increment value and every value after is an offset added to the
+	 * previous incrementation value */
+	dev->lptbl[0] = mlc->pairs[0] & 0xF;
+	for (i = 1; i < dev->lps_per_blk; i++) {
+		p = mlc->pairs[i >> 1];
+		if (i & 0x1) /* upper */
+			dev->lptbl[i] = dev->lptbl[i - 1] + ((p & 0xF0) >> 4);
+		else /* lower */
+			dev->lptbl[i] = dev->lptbl[i - 1] + (p & 0xF);
+	}
+
+	return 0;
+}
+
 static int nvm_core_init(struct nvm_dev *dev)
 {
 	struct nvm_id *id = &dev->identity;
@@ -206,6 +424,7 @@ static int nvm_core_init(struct nvm_dev
 	dev->sec_size = grp->csecs;
 	dev->oob_size = grp->sos;
 	dev->sec_per_pg = grp->fpg_sz / grp->csecs;
+	dev->mccap = grp->mccap;
 	memcpy(&dev->ppaf, &id->ppaf, sizeof(struct nvm_addr_format));
 
 	dev->plane_mode = NVM_PLANE_SINGLE;
@@ -216,11 +435,23 @@ static int nvm_core_init(struct nvm_dev
 		return -EINVAL;
 	}
 
-	if (grp->fmtype != 0 && grp->fmtype != 1) {
+	switch (grp->fmtype) {
+	case NVM_ID_FMTYPE_SLC:
+		if (nvm_init_slc_tbl(dev, grp))
+			return -ENOMEM;
+		break;
+	case NVM_ID_FMTYPE_MLC:
+		if (nvm_init_mlc_tbl(dev, grp))
+			return -ENOMEM;
+		break;
+	default:
 		pr_err("nvm: flash type not supported\n");
 		return -EINVAL;
 	}
 
+	if (!dev->lps_per_blk)
+		pr_info("nvm: lower page programming table missing\n");
+
 	if (grp->mpos & 0x020202)
 		dev->plane_mode = NVM_PLANE_DOUBLE;
 	if (grp->mpos & 0x040404)
@@ -238,6 +469,7 @@ static int nvm_core_init(struct nvm_dev
 				dev->nr_chnls;
 	dev->total_pages = dev->total_blocks * dev->pgs_per_blk;
 	INIT_LIST_HEAD(&dev->online_targets);
+	mutex_init(&dev->mlock);
 
 	return 0;
 }
@@ -249,6 +481,8 @@ static void nvm_free(struct nvm_dev *dev
 
 	if (dev->mt)
 		dev->mt->unregister_mgr(dev);
+
+	kfree(dev->lptbl);
 }
 
 static int nvm_init(struct nvm_dev *dev)
@@ -338,9 +572,16 @@ int nvm_register(struct request_queue *q
 		}
 	}
 
+	ret = nvm_get_sysblock(dev, &dev->sb);
+	if (!ret)
+		pr_err("nvm: device not initialized.\n");
+	else if (ret < 0)
+		pr_err("nvm: err (%d) on device initialization\n", ret);
+
 	/* register device with a supported media manager */
 	down_write(&nvm_lock);
-	dev->mt = nvm_init_mgr(dev);
+	if (ret > 0)
+		dev->mt = nvm_init_mgr(dev);
 	list_add(&dev->devices, &nvm_devices);
 	up_write(&nvm_lock);
 
@@ -788,6 +1029,97 @@ static long nvm_ioctl_dev_remove(struct
 	return __nvm_configure_remove(&remove);
 }
 
+static void nvm_setup_nvm_sb_info(struct nvm_sb_info *info)
+{
+	info->seqnr = 1;
+	info->erase_cnt = 0;
+	info->version = 1;
+}
+
+static long __nvm_ioctl_dev_init(struct nvm_ioctl_dev_init *init)
+{
+	struct nvm_dev *dev;
+	struct nvm_sb_info info;
+	int ret;
+
+	down_write(&nvm_lock);
+	dev = nvm_find_nvm_dev(init->dev);
+	up_write(&nvm_lock);
+	if (!dev) {
+		pr_err("nvm: device not found\n");
+		return -EINVAL;
+	}
+
+	nvm_setup_nvm_sb_info(&info);
+
+	strncpy(info.mmtype, init->mmtype, NVM_MMTYPE_LEN);
+	info.fs_ppa.ppa = -1;
+
+	ret = nvm_init_sysblock(dev, &info);
+	if (ret)
+		return ret;
+
+	memcpy(&dev->sb, &info, sizeof(struct nvm_sb_info));
+
+	down_write(&nvm_lock);
+	dev->mt = nvm_init_mgr(dev);
+	up_write(&nvm_lock);
+
+	return 0;
+}
+
+static long nvm_ioctl_dev_init(struct file *file, void __user *arg)
+{
+	struct nvm_ioctl_dev_init init;
+
+	if (!capable(CAP_SYS_ADMIN))
+		return -EPERM;
+
+	if (copy_from_user(&init, arg, sizeof(struct nvm_ioctl_dev_init)))
+		return -EFAULT;
+
+	if (init.flags != 0) {
+		pr_err("nvm: no flags supported\n");
+		return -EINVAL;
+	}
+
+	init.dev[DISK_NAME_LEN - 1] = '\0';
+
+	return __nvm_ioctl_dev_init(&init);
+}
+
+static long nvm_ioctl_dev_factory(struct file *file, void __user *arg)
+{
+	struct nvm_ioctl_dev_factory fact;
+	struct nvm_dev *dev;
+
+	if (!capable(CAP_SYS_ADMIN))
+		return -EPERM;
+
+	if (copy_from_user(&fact, arg, sizeof(struct nvm_ioctl_dev_factory)))
+		return -EFAULT;
+
+	fact.dev[DISK_NAME_LEN - 1] = '\0';
+
+	if (fact.flags & ~(NVM_FACTORY_NR_BITS - 1))
+		return -EINVAL;
+
+	down_write(&nvm_lock);
+	dev = nvm_find_nvm_dev(fact.dev);
+	up_write(&nvm_lock);
+	if (!dev) {
+		pr_err("nvm: device not found\n");
+		return -EINVAL;
+	}
+
+	if (dev->mt) {
+		dev->mt->unregister_mgr(dev);
+		dev->mt = NULL;
+	}
+
+	return nvm_dev_factory(dev, fact.flags);
+}
+
 static long nvm_ctl_ioctl(struct file *file, uint cmd, unsigned long arg)
 {
 	void __user *argp = (void __user *)arg;
@@ -801,6 +1133,10 @@ static long nvm_ctl_ioctl(struct file *f
 		return nvm_ioctl_dev_create(file, argp);
 	case NVM_DEV_REMOVE:
 		return nvm_ioctl_dev_remove(file, argp);
+	case NVM_DEV_INIT:
+		return nvm_ioctl_dev_init(file, argp);
+	case NVM_DEV_FACTORY:
+		return nvm_ioctl_dev_factory(file, argp);
 	}
 	return 0;
 }
--- zfcpdump-kernel-4.4.orig/drivers/lightnvm/gennvm.c
+++ zfcpdump-kernel-4.4/drivers/lightnvm/gennvm.c
@@ -60,7 +60,8 @@ static int gennvm_luns_init(struct nvm_d
 		lun->vlun.lun_id = i % dev->luns_per_chnl;
 		lun->vlun.chnl_id = i / dev->luns_per_chnl;
 		lun->vlun.nr_free_blocks = dev->blks_per_lun;
-		lun->vlun.nr_inuse_blocks = 0;
+		lun->vlun.nr_open_blocks = 0;
+		lun->vlun.nr_closed_blocks = 0;
 		lun->vlun.nr_bad_blocks = 0;
 	}
 	return 0;
@@ -89,6 +90,7 @@ static int gennvm_block_bb(struct ppa_ad
 
 		list_move_tail(&blk->list, &lun->bb_list);
 		lun->vlun.nr_bad_blocks++;
+		lun->vlun.nr_free_blocks--;
 	}
 
 	return 0;
@@ -133,15 +135,15 @@ static int gennvm_block_map(u64 slba, u3
 		pba = pba - (dev->sec_per_lun * lun_id);
 		blk = &lun->vlun.blocks[div_u64(pba, dev->sec_per_blk)];
 
-		if (!blk->type) {
+		if (!blk->state) {
 			/* at this point, we don't know anything about the
 			 * block. It's up to the FTL on top to re-etablish the
-			 * block state
+			 * block state. The block is assumed to be open.
 			 */
 			list_move_tail(&blk->list, &lun->used_list);
-			blk->type = 1;
+			blk->state = NVM_BLK_ST_OPEN;
 			lun->vlun.nr_free_blocks--;
-			lun->vlun.nr_inuse_blocks++;
+			lun->vlun.nr_open_blocks++;
 		}
 	}
 
@@ -255,14 +257,14 @@ static void gennvm_unregister(struct nvm
 	module_put(THIS_MODULE);
 }
 
-static struct nvm_block *gennvm_get_blk(struct nvm_dev *dev,
+static struct nvm_block *gennvm_get_blk_unlocked(struct nvm_dev *dev,
 				struct nvm_lun *vlun, unsigned long flags)
 {
 	struct gen_lun *lun = container_of(vlun, struct gen_lun, vlun);
 	struct nvm_block *blk = NULL;
 	int is_gc = flags & NVM_IOTYPE_GC;
 
-	spin_lock(&vlun->lock);
+	assert_spin_locked(&vlun->lock);
 
 	if (list_empty(&lun->free_list)) {
 		pr_err_ratelimited("gennvm: lun %u have no free pages available",
@@ -275,83 +277,64 @@ static struct nvm_block *gennvm_get_blk(
 
 	blk = list_first_entry(&lun->free_list, struct nvm_block, list);
 	list_move_tail(&blk->list, &lun->used_list);
-	blk->type = 1;
+	blk->state = NVM_BLK_ST_OPEN;
 
 	lun->vlun.nr_free_blocks--;
-	lun->vlun.nr_inuse_blocks++;
+	lun->vlun.nr_open_blocks++;
 
 out:
+	return blk;
+}
+
+static struct nvm_block *gennvm_get_blk(struct nvm_dev *dev,
+				struct nvm_lun *vlun, unsigned long flags)
+{
+	struct nvm_block *blk;
+
+	spin_lock(&vlun->lock);
+	blk = gennvm_get_blk_unlocked(dev, vlun, flags);
 	spin_unlock(&vlun->lock);
 	return blk;
 }
 
-static void gennvm_put_blk(struct nvm_dev *dev, struct nvm_block *blk)
+static void gennvm_put_blk_unlocked(struct nvm_dev *dev, struct nvm_block *blk)
 {
 	struct nvm_lun *vlun = blk->lun;
 	struct gen_lun *lun = container_of(vlun, struct gen_lun, vlun);
 
-	spin_lock(&vlun->lock);
+	assert_spin_locked(&vlun->lock);
 
-	switch (blk->type) {
-	case 1:
+	if (blk->state & NVM_BLK_ST_OPEN) {
 		list_move_tail(&blk->list, &lun->free_list);
+		lun->vlun.nr_open_blocks--;
 		lun->vlun.nr_free_blocks++;
-		lun->vlun.nr_inuse_blocks--;
-		blk->type = 0;
-		break;
-	case 2:
+		blk->state = NVM_BLK_ST_FREE;
+	} else if (blk->state & NVM_BLK_ST_CLOSED) {
+		list_move_tail(&blk->list, &lun->free_list);
+		lun->vlun.nr_closed_blocks--;
+		lun->vlun.nr_free_blocks++;
+		blk->state = NVM_BLK_ST_FREE;
+	} else if (blk->state & NVM_BLK_ST_BAD) {
 		list_move_tail(&blk->list, &lun->bb_list);
 		lun->vlun.nr_bad_blocks++;
-		lun->vlun.nr_inuse_blocks--;
-		break;
-	default:
+		blk->state = NVM_BLK_ST_BAD;
+	} else {
 		WARN_ON_ONCE(1);
 		pr_err("gennvm: erroneous block type (%lu -> %u)\n",
-							blk->id, blk->type);
+							blk->id, blk->state);
 		list_move_tail(&blk->list, &lun->bb_list);
 		lun->vlun.nr_bad_blocks++;
-		lun->vlun.nr_inuse_blocks--;
-	}
-
-	spin_unlock(&vlun->lock);
-}
-
-static void gennvm_addr_to_generic_mode(struct nvm_dev *dev, struct nvm_rq *rqd)
-{
-	int i;
-
-	if (rqd->nr_pages > 1) {
-		for (i = 0; i < rqd->nr_pages; i++)
-			rqd->ppa_list[i] = dev_to_generic_addr(dev,
-							rqd->ppa_list[i]);
-	} else {
-		rqd->ppa_addr = dev_to_generic_addr(dev, rqd->ppa_addr);
-	}
-}
-
-static void gennvm_generic_to_addr_mode(struct nvm_dev *dev, struct nvm_rq *rqd)
-{
-	int i;
-
-	if (rqd->nr_pages > 1) {
-		for (i = 0; i < rqd->nr_pages; i++)
-			rqd->ppa_list[i] = generic_to_dev_addr(dev,
-							rqd->ppa_list[i]);
-	} else {
-		rqd->ppa_addr = generic_to_dev_addr(dev, rqd->ppa_addr);
+		blk->state = NVM_BLK_ST_BAD;
 	}
 }
 
-static int gennvm_submit_io(struct nvm_dev *dev, struct nvm_rq *rqd)
+static void gennvm_put_blk(struct nvm_dev *dev, struct nvm_block *blk)
 {
-	if (!dev->ops->submit_io)
-		return 0;
-
-	/* Convert address space */
-	gennvm_generic_to_addr_mode(dev, rqd);
+	struct nvm_lun *vlun = blk->lun;
 
-	rqd->dev = dev;
-	return dev->ops->submit_io(dev, rqd);
+	spin_lock(&vlun->lock);
+	gennvm_put_blk_unlocked(dev, blk);
+	spin_unlock(&vlun->lock);
 }
 
 static void gennvm_blk_set_type(struct nvm_dev *dev, struct ppa_addr *ppa,
@@ -376,7 +359,7 @@ static void gennvm_blk_set_type(struct n
 	blk = &lun->vlun.blocks[ppa->g.blk];
 
 	/* will be moved to bb list on put_blk from target */
-	blk->type = type;
+	blk->state = type;
 }
 
 /* mark block bad. It is expected the target recover from the error. */
@@ -390,77 +373,51 @@ static void gennvm_mark_blk_bad(struct n
 	if (dev->ops->set_bb_tbl(dev, rqd, 1))
 		return;
 
-	gennvm_addr_to_generic_mode(dev, rqd);
+	nvm_addr_to_generic_mode(dev, rqd);
 
 	/* look up blocks and mark them as bad */
 	if (rqd->nr_pages > 1)
 		for (i = 0; i < rqd->nr_pages; i++)
-			gennvm_blk_set_type(dev, &rqd->ppa_list[i], 2);
+			gennvm_blk_set_type(dev, &rqd->ppa_list[i],
+						NVM_BLK_ST_BAD);
 	else
-		gennvm_blk_set_type(dev, &rqd->ppa_addr, 2);
+		gennvm_blk_set_type(dev, &rqd->ppa_addr, NVM_BLK_ST_BAD);
 }
 
-static int gennvm_end_io(struct nvm_rq *rqd, int error)
+static void gennvm_end_io(struct nvm_rq *rqd)
 {
 	struct nvm_tgt_instance *ins = rqd->ins;
-	int ret = 0;
 
-	switch (error) {
+	switch (rqd->error) {
 	case NVM_RSP_SUCCESS:
-		break;
 	case NVM_RSP_ERR_EMPTYPAGE:
 		break;
 	case NVM_RSP_ERR_FAILWRITE:
 		gennvm_mark_blk_bad(rqd->dev, rqd);
-	default:
-		ret++;
 	}
 
-	ret += ins->tt->end_io(rqd, error);
-
-	return ret;
+	ins->tt->end_io(rqd);
 }
 
-static int gennvm_erase_blk(struct nvm_dev *dev, struct nvm_block *blk,
-							unsigned long flags)
+static int gennvm_submit_io(struct nvm_dev *dev, struct nvm_rq *rqd)
 {
-	int plane_cnt = 0, pl_idx, ret;
-	struct ppa_addr addr;
-	struct nvm_rq rqd;
-
-	if (!dev->ops->erase_block)
-		return 0;
-
-	addr = block_to_ppa(dev, blk);
-
-	if (dev->plane_mode == NVM_PLANE_SINGLE) {
-		rqd.nr_pages = 1;
-		rqd.ppa_addr = addr;
-	} else {
-		plane_cnt = (1 << dev->plane_mode);
-		rqd.nr_pages = plane_cnt;
-
-		rqd.ppa_list = nvm_dev_dma_alloc(dev, GFP_KERNEL,
-							&rqd.dma_ppa_list);
-		if (!rqd.ppa_list) {
-			pr_err("gennvm: failed to allocate dma memory\n");
-			return -ENOMEM;
-		}
-
-		for (pl_idx = 0; pl_idx < plane_cnt; pl_idx++) {
-			addr.g.pl = pl_idx;
-			rqd.ppa_list[pl_idx] = addr;
-		}
-	}
+	if (!dev->ops->submit_io)
+		return -ENODEV;
 
-	gennvm_generic_to_addr_mode(dev, &rqd);
+	/* Convert address space */
+	nvm_generic_to_addr_mode(dev, rqd);
 
-	ret = dev->ops->erase_block(dev, &rqd);
+	rqd->dev = dev;
+	rqd->end_io = gennvm_end_io;
+	return dev->ops->submit_io(dev, rqd);
+}
 
-	if (plane_cnt)
-		nvm_dev_dma_free(dev, rqd.ppa_list, rqd.dma_ppa_list);
+static int gennvm_erase_blk(struct nvm_dev *dev, struct nvm_block *blk,
+							unsigned long flags)
+{
+	struct ppa_addr addr = block_to_ppa(dev, blk);
 
-	return ret;
+	return nvm_erase_ppa(dev, &addr, 1);
 }
 
 static struct nvm_lun *gennvm_get_lun(struct nvm_dev *dev, int lunid)
@@ -480,10 +437,11 @@ static void gennvm_lun_info_print(struct
 	gennvm_for_each_lun(gn, lun, i) {
 		spin_lock(&lun->vlun.lock);
 
-		pr_info("%s: lun%8u\t%u\t%u\t%u\n",
+		pr_info("%s: lun%8u\t%u\t%u\t%u\t%u\n",
 				dev->name, i,
 				lun->vlun.nr_free_blocks,
-				lun->vlun.nr_inuse_blocks,
+				lun->vlun.nr_open_blocks,
+				lun->vlun.nr_closed_blocks,
 				lun->vlun.nr_bad_blocks);
 
 		spin_unlock(&lun->vlun.lock);
@@ -491,21 +449,23 @@ static void gennvm_lun_info_print(struct
 }
 
 static struct nvmm_type gennvm = {
-	.name		= "gennvm",
-	.version	= {0, 1, 0},
+	.name			= "gennvm",
+	.version		= {0, 1, 0},
+
+	.register_mgr		= gennvm_register,
+	.unregister_mgr		= gennvm_unregister,
 
-	.register_mgr	= gennvm_register,
-	.unregister_mgr	= gennvm_unregister,
+	.get_blk_unlocked	= gennvm_get_blk_unlocked,
+	.put_blk_unlocked	= gennvm_put_blk_unlocked,
 
-	.get_blk	= gennvm_get_blk,
-	.put_blk	= gennvm_put_blk,
+	.get_blk		= gennvm_get_blk,
+	.put_blk		= gennvm_put_blk,
 
-	.submit_io	= gennvm_submit_io,
-	.end_io		= gennvm_end_io,
-	.erase_blk	= gennvm_erase_blk,
+	.submit_io		= gennvm_submit_io,
+	.erase_blk		= gennvm_erase_blk,
 
-	.get_lun	= gennvm_get_lun,
-	.lun_info_print = gennvm_lun_info_print,
+	.get_lun		= gennvm_get_lun,
+	.lun_info_print		= gennvm_lun_info_print,
 };
 
 static int __init gennvm_module_init(void)
--- zfcpdump-kernel-4.4.orig/drivers/lightnvm/rrpc.c
+++ zfcpdump-kernel-4.4/drivers/lightnvm/rrpc.c
@@ -179,16 +179,23 @@ static void rrpc_set_lun_cur(struct rrpc
 static struct rrpc_block *rrpc_get_blk(struct rrpc *rrpc, struct rrpc_lun *rlun,
 							unsigned long flags)
 {
+	struct nvm_lun *lun = rlun->parent;
 	struct nvm_block *blk;
 	struct rrpc_block *rblk;
 
-	blk = nvm_get_blk(rrpc->dev, rlun->parent, flags);
-	if (!blk)
+	spin_lock(&lun->lock);
+	blk = nvm_get_blk_unlocked(rrpc->dev, rlun->parent, flags);
+	if (!blk) {
+		pr_err("nvm: rrpc: cannot get new block from media manager\n");
+		spin_unlock(&lun->lock);
 		return NULL;
+	}
 
 	rblk = &rlun->blocks[blk->id];
-	blk->priv = rblk;
+	list_add_tail(&rblk->list, &rlun->open_list);
+	spin_unlock(&lun->lock);
 
+	blk->priv = rblk;
 	bitmap_zero(rblk->invalid_pages, rrpc->dev->pgs_per_blk);
 	rblk->next_page = 0;
 	rblk->nr_invalid_pages = 0;
@@ -199,7 +206,13 @@ static struct rrpc_block *rrpc_get_blk(s
 
 static void rrpc_put_blk(struct rrpc *rrpc, struct rrpc_block *rblk)
 {
-	nvm_put_blk(rrpc->dev, rblk->parent);
+	struct rrpc_lun *rlun = rblk->rlun;
+	struct nvm_lun *lun = rlun->parent;
+
+	spin_lock(&lun->lock);
+	nvm_put_blk_unlocked(rrpc->dev, rblk->parent);
+	list_del(&rblk->list);
+	spin_unlock(&lun->lock);
 }
 
 static void rrpc_put_blks(struct rrpc *rrpc)
@@ -287,6 +300,10 @@ static int rrpc_move_valid_pages(struct
 	}
 
 	page = mempool_alloc(rrpc->page_pool, GFP_NOIO);
+	if (!page) {
+		bio_put(bio);
+		return -ENOMEM;
+	}
 
 	while ((slot = find_first_zero_bit(rblk->invalid_pages,
 					    nr_pgs_per_blk)) < nr_pgs_per_blk) {
@@ -328,6 +345,10 @@ try:
 			goto finished;
 		}
 		wait_for_completion_io(&wait);
+		if (bio->bi_error) {
+			rrpc_inflight_laddr_release(rrpc, rqd);
+			goto finished;
+		}
 
 		bio_reset(bio);
 		reinit_completion(&wait);
@@ -350,6 +371,8 @@ try:
 		wait_for_completion_io(&wait);
 
 		rrpc_inflight_laddr_release(rrpc, rqd);
+		if (bio->bi_error)
+			goto finished;
 
 		bio_reset(bio);
 	}
@@ -373,16 +396,26 @@ static void rrpc_block_gc(struct work_st
 	struct rrpc *rrpc = gcb->rrpc;
 	struct rrpc_block *rblk = gcb->rblk;
 	struct nvm_dev *dev = rrpc->dev;
+	struct nvm_lun *lun = rblk->parent->lun;
+	struct rrpc_lun *rlun = &rrpc->luns[lun->id - rrpc->lun_offset];
 
+	mempool_free(gcb, rrpc->gcb_pool);
 	pr_debug("nvm: block '%lu' being reclaimed\n", rblk->parent->id);
 
 	if (rrpc_move_valid_pages(rrpc, rblk))
-		goto done;
+		goto put_back;
+
+	if (nvm_erase_blk(dev, rblk->parent))
+		goto put_back;
 
-	nvm_erase_blk(dev, rblk->parent);
 	rrpc_put_blk(rrpc, rblk);
-done:
-	mempool_free(gcb, rrpc->gcb_pool);
+
+	return;
+
+put_back:
+	spin_lock(&rlun->lock);
+	list_add_tail(&rblk->prio, &rlun->prio_list);
+	spin_unlock(&rlun->lock);
 }
 
 /* the block with highest number of invalid pages, will be in the beginning
@@ -427,7 +460,7 @@ static void rrpc_lun_gc(struct work_stru
 	if (nr_blocks_need < rrpc->nr_luns)
 		nr_blocks_need = rrpc->nr_luns;
 
-	spin_lock(&lun->lock);
+	spin_lock(&rlun->lock);
 	while (nr_blocks_need > lun->nr_free_blocks &&
 					!list_empty(&rlun->prio_list)) {
 		struct rrpc_block *rblock = block_prio_find_max(rlun);
@@ -436,16 +469,16 @@ static void rrpc_lun_gc(struct work_stru
 		if (!rblock->nr_invalid_pages)
 			break;
 
+		gcb = mempool_alloc(rrpc->gcb_pool, GFP_ATOMIC);
+		if (!gcb)
+			break;
+
 		list_del_init(&rblock->prio);
 
 		BUG_ON(!block_is_full(rrpc, rblock));
 
 		pr_debug("rrpc: selected block '%lu' for GC\n", block->id);
 
-		gcb = mempool_alloc(rrpc->gcb_pool, GFP_ATOMIC);
-		if (!gcb)
-			break;
-
 		gcb->rrpc = rrpc;
 		gcb->rblk = rblock;
 		INIT_WORK(&gcb->ws_gc, rrpc_block_gc);
@@ -454,7 +487,7 @@ static void rrpc_lun_gc(struct work_stru
 
 		nr_blocks_need--;
 	}
-	spin_unlock(&lun->lock);
+	spin_unlock(&rlun->lock);
 
 	/* TODO: Hint that request queue can be started again */
 }
@@ -635,12 +668,24 @@ static void rrpc_end_io_write(struct rrp
 		lun = rblk->parent->lun;
 
 		cmnt_size = atomic_inc_return(&rblk->data_cmnt_size);
-		if (unlikely(cmnt_size == rrpc->dev->pgs_per_blk))
+		if (unlikely(cmnt_size == rrpc->dev->pgs_per_blk)) {
+			struct nvm_block *blk = rblk->parent;
+			struct rrpc_lun *rlun = rblk->rlun;
+
+			spin_lock(&lun->lock);
+			lun->nr_open_blocks--;
+			lun->nr_closed_blocks++;
+			blk->state &= ~NVM_BLK_ST_OPEN;
+			blk->state |= NVM_BLK_ST_CLOSED;
+			list_move_tail(&rblk->list, &rlun->closed_list);
+			spin_unlock(&lun->lock);
+
 			rrpc_run_gc(rrpc, rblk);
+		}
 	}
 }
 
-static int rrpc_end_io(struct nvm_rq *rqd, int error)
+static void rrpc_end_io(struct nvm_rq *rqd)
 {
 	struct rrpc *rrpc = container_of(rqd->ins, struct rrpc, instance);
 	struct rrpc_rq *rrqd = nvm_rq_to_pdu(rqd);
@@ -650,11 +695,12 @@ static int rrpc_end_io(struct nvm_rq *rq
 	if (bio_data_dir(rqd->bio) == WRITE)
 		rrpc_end_io_write(rrpc, rrqd, laddr, npages);
 
+	bio_put(rqd->bio);
+
 	if (rrqd->flags & NVM_IOTYPE_GC)
-		return 0;
+		return;
 
 	rrpc_unlock_rq(rrpc, rqd);
-	bio_put(rqd->bio);
 
 	if (npages > 1)
 		nvm_dev_dma_free(rrpc->dev, rqd->ppa_list, rqd->dma_ppa_list);
@@ -662,8 +708,6 @@ static int rrpc_end_io(struct nvm_rq *rq
 		nvm_dev_dma_free(rrpc->dev, rqd->metadata, rqd->dma_metadata);
 
 	mempool_free(rqd, rrpc->rq_pool);
-
-	return 0;
 }
 
 static int rrpc_read_ppalist_rq(struct rrpc *rrpc, struct bio *bio,
@@ -841,6 +885,13 @@ static int rrpc_submit_io(struct rrpc *r
 	err = nvm_submit_io(rrpc->dev, rqd);
 	if (err) {
 		pr_err("rrpc: I/O submission failed: %d\n", err);
+		bio_put(bio);
+		if (!(flags & NVM_IOTYPE_GC)) {
+			rrpc_unlock_rq(rrpc, rqd);
+			if (rqd->nr_pages > 1)
+				nvm_dev_dma_free(rrpc->dev,
+			rqd->ppa_list, rqd->dma_ppa_list);
+		}
 		return NVM_IO_ERR;
 	}
 
@@ -1090,6 +1141,11 @@ static int rrpc_luns_init(struct rrpc *r
 	struct rrpc_lun *rlun;
 	int i, j;
 
+	if (dev->pgs_per_blk > MAX_INVALID_PAGES_STORAGE * BITS_PER_LONG) {
+		pr_err("rrpc: number of pages per block too high.");
+		return -EINVAL;
+	}
+
 	spin_lock_init(&rrpc->rev_lock);
 
 	rrpc->luns = kcalloc(rrpc->nr_luns, sizeof(struct rrpc_lun),
@@ -1101,16 +1157,13 @@ static int rrpc_luns_init(struct rrpc *r
 	for (i = 0; i < rrpc->nr_luns; i++) {
 		struct nvm_lun *lun = dev->mt->get_lun(dev, lun_begin + i);
 
-		if (dev->pgs_per_blk >
-				MAX_INVALID_PAGES_STORAGE * BITS_PER_LONG) {
-			pr_err("rrpc: number of pages per block too high.");
-			goto err;
-		}
-
 		rlun = &rrpc->luns[i];
 		rlun->rrpc = rrpc;
 		rlun->parent = lun;
 		INIT_LIST_HEAD(&rlun->prio_list);
+		INIT_LIST_HEAD(&rlun->open_list);
+		INIT_LIST_HEAD(&rlun->closed_list);
+
 		INIT_WORK(&rlun->ws_gc, rrpc_lun_gc);
 		spin_lock_init(&rlun->lock);
 
@@ -1127,6 +1180,7 @@ static int rrpc_luns_init(struct rrpc *r
 			struct nvm_block *blk = &lun->blocks[j];
 
 			rblk->parent = blk;
+			rblk->rlun = rlun;
 			INIT_LIST_HEAD(&rblk->prio);
 			spin_lock_init(&rblk->lock);
 		}
--- zfcpdump-kernel-4.4.orig/drivers/lightnvm/rrpc.h
+++ zfcpdump-kernel-4.4/drivers/lightnvm/rrpc.h
@@ -54,7 +54,9 @@ struct rrpc_rq {
 
 struct rrpc_block {
 	struct nvm_block *parent;
+	struct rrpc_lun *rlun;
 	struct list_head prio;
+	struct list_head list;
 
 #define MAX_INVALID_PAGES_STORAGE 8
 	/* Bitmap for invalid page intries */
@@ -73,7 +75,16 @@ struct rrpc_lun {
 	struct nvm_lun *parent;
 	struct rrpc_block *cur, *gc_cur;
 	struct rrpc_block *blocks;	/* Reference to block allocation */
-	struct list_head prio_list;		/* Blocks that may be GC'ed */
+
+	struct list_head prio_list;	/* Blocks that may be GC'ed */
+	struct list_head open_list;	/* In-use open blocks. These are blocks
+					 * that can be both written to and read
+					 * from
+					 */
+	struct list_head closed_list;	/* In-use closed blocks. These are
+					 * blocks that can _only_ be read from
+					 */
+
 	struct work_struct ws_gc;
 
 	spinlock_t lock;
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/lightnvm/sysblk.c
@@ -0,0 +1,741 @@
+/*
+ * Copyright (C) 2015 Matias Bjorling. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.  If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139,
+ * USA.
+ *
+ */
+
+#include <linux/lightnvm.h>
+
+#define MAX_SYSBLKS 3	/* remember to update mapping scheme on change */
+#define MAX_BLKS_PR_SYSBLK 2 /* 2 blks with 256 pages and 3000 erases
+			      * enables ~1.5M updates per sysblk unit
+			      */
+
+struct sysblk_scan {
+	/* A row is a collection of flash blocks for a system block. */
+	int nr_rows;
+	int row;
+	int act_blk[MAX_SYSBLKS];
+
+	int nr_ppas;
+	struct ppa_addr ppas[MAX_SYSBLKS * MAX_BLKS_PR_SYSBLK];/* all sysblks */
+};
+
+static inline int scan_ppa_idx(int row, int blkid)
+{
+	return (row * MAX_BLKS_PR_SYSBLK) + blkid;
+}
+
+void nvm_sysblk_to_cpu(struct nvm_sb_info *info, struct nvm_system_block *sb)
+{
+	info->seqnr = be32_to_cpu(sb->seqnr);
+	info->erase_cnt = be32_to_cpu(sb->erase_cnt);
+	info->version = be16_to_cpu(sb->version);
+	strncpy(info->mmtype, sb->mmtype, NVM_MMTYPE_LEN);
+	info->fs_ppa.ppa = be64_to_cpu(sb->fs_ppa);
+}
+
+void nvm_cpu_to_sysblk(struct nvm_system_block *sb, struct nvm_sb_info *info)
+{
+	sb->magic = cpu_to_be32(NVM_SYSBLK_MAGIC);
+	sb->seqnr = cpu_to_be32(info->seqnr);
+	sb->erase_cnt = cpu_to_be32(info->erase_cnt);
+	sb->version = cpu_to_be16(info->version);
+	strncpy(sb->mmtype, info->mmtype, NVM_MMTYPE_LEN);
+	sb->fs_ppa = cpu_to_be64(info->fs_ppa.ppa);
+}
+
+static int nvm_setup_sysblks(struct nvm_dev *dev, struct ppa_addr *sysblk_ppas)
+{
+	int nr_rows = min_t(int, MAX_SYSBLKS, dev->nr_chnls);
+	int i;
+
+	for (i = 0; i < nr_rows; i++)
+		sysblk_ppas[i].ppa = 0;
+
+	/* if possible, place sysblk at first channel, middle channel and last
+	 * channel of the device. If not, create only one or two sys blocks
+	 */
+	switch (dev->nr_chnls) {
+	case 2:
+		sysblk_ppas[1].g.ch = 1;
+		/* fall-through */
+	case 1:
+		sysblk_ppas[0].g.ch = 0;
+		break;
+	default:
+		sysblk_ppas[0].g.ch = 0;
+		sysblk_ppas[1].g.ch = dev->nr_chnls / 2;
+		sysblk_ppas[2].g.ch = dev->nr_chnls - 1;
+		break;
+	}
+
+	return nr_rows;
+}
+
+void nvm_setup_sysblk_scan(struct nvm_dev *dev, struct sysblk_scan *s,
+						struct ppa_addr *sysblk_ppas)
+{
+	memset(s, 0, sizeof(struct sysblk_scan));
+	s->nr_rows = nvm_setup_sysblks(dev, sysblk_ppas);
+}
+
+static int sysblk_get_host_blks(struct ppa_addr ppa, int nr_blks, u8 *blks,
+								void *private)
+{
+	struct sysblk_scan *s = private;
+	int i, nr_sysblk = 0;
+
+	for (i = 0; i < nr_blks; i++) {
+		if (blks[i] != NVM_BLK_T_HOST)
+			continue;
+
+		if (s->nr_ppas == MAX_BLKS_PR_SYSBLK * MAX_SYSBLKS) {
+			pr_err("nvm: too many host blks\n");
+			return -EINVAL;
+		}
+
+		ppa.g.blk = i;
+
+		s->ppas[scan_ppa_idx(s->row, nr_sysblk)] = ppa;
+		s->nr_ppas++;
+		nr_sysblk++;
+	}
+
+	return 0;
+}
+
+static int nvm_get_all_sysblks(struct nvm_dev *dev, struct sysblk_scan *s,
+				struct ppa_addr *ppas, nvm_bb_update_fn *fn)
+{
+	struct ppa_addr dppa;
+	int i, ret;
+
+	s->nr_ppas = 0;
+
+	for (i = 0; i < s->nr_rows; i++) {
+		dppa = generic_to_dev_addr(dev, ppas[i]);
+		s->row = i;
+
+		ret = dev->ops->get_bb_tbl(dev, dppa, dev->blks_per_lun, fn, s);
+		if (ret) {
+			pr_err("nvm: failed bb tbl for ppa (%u %u)\n",
+							ppas[i].g.ch,
+							ppas[i].g.blk);
+			return ret;
+		}
+	}
+
+	return ret;
+}
+
+/*
+ * scans a block for latest sysblk.
+ * Returns:
+ *	0 - newer sysblk not found. PPA is updated to latest page.
+ *	1 - newer sysblk found and stored in *cur. PPA is updated to
+ *	    next valid page.
+ *	<0- error.
+ */
+static int nvm_scan_block(struct nvm_dev *dev, struct ppa_addr *ppa,
+						struct nvm_system_block *sblk)
+{
+	struct nvm_system_block *cur;
+	int pg, cursz, ret, found = 0;
+
+	/* the full buffer for a flash page is allocated. Only the first of it
+	 * contains the system block information
+	 */
+	cursz = dev->sec_size * dev->sec_per_pg * dev->nr_planes;
+	cur = kmalloc(cursz, GFP_KERNEL);
+	if (!cur)
+		return -ENOMEM;
+
+	/* perform linear scan through the block */
+	for (pg = 0; pg < dev->lps_per_blk; pg++) {
+		ppa->g.pg = ppa_to_slc(dev, pg);
+
+		ret = nvm_submit_ppa(dev, ppa, 1, NVM_OP_PREAD, NVM_IO_SLC_MODE,
+								cur, cursz);
+		if (ret) {
+			if (ret == NVM_RSP_ERR_EMPTYPAGE) {
+				pr_debug("nvm: sysblk scan empty ppa (%u %u %u %u)\n",
+							ppa->g.ch,
+							ppa->g.lun,
+							ppa->g.blk,
+							ppa->g.pg);
+				break;
+			}
+			pr_err("nvm: read failed (%x) for ppa (%u %u %u %u)",
+							ret,
+							ppa->g.ch,
+							ppa->g.lun,
+							ppa->g.blk,
+							ppa->g.pg);
+			break; /* if we can't read a page, continue to the
+				* next blk
+				*/
+		}
+
+		if (be32_to_cpu(cur->magic) != NVM_SYSBLK_MAGIC) {
+			pr_debug("nvm: scan break for ppa (%u %u %u %u)\n",
+							ppa->g.ch,
+							ppa->g.lun,
+							ppa->g.blk,
+							ppa->g.pg);
+			break; /* last valid page already found */
+		}
+
+		if (be32_to_cpu(cur->seqnr) < be32_to_cpu(sblk->seqnr))
+			continue;
+
+		memcpy(sblk, cur, sizeof(struct nvm_system_block));
+		found = 1;
+	}
+
+	kfree(cur);
+
+	return found;
+}
+
+static int nvm_set_bb_tbl(struct nvm_dev *dev, struct sysblk_scan *s, int type)
+{
+	struct nvm_rq rqd;
+	int ret;
+
+	if (s->nr_ppas > dev->ops->max_phys_sect) {
+		pr_err("nvm: unable to update all sysblocks atomically\n");
+		return -EINVAL;
+	}
+
+	memset(&rqd, 0, sizeof(struct nvm_rq));
+
+	nvm_set_rqd_ppalist(dev, &rqd, s->ppas, s->nr_ppas);
+	nvm_generic_to_addr_mode(dev, &rqd);
+
+	ret = dev->ops->set_bb_tbl(dev, &rqd, type);
+	nvm_free_rqd_ppalist(dev, &rqd);
+	if (ret) {
+		pr_err("nvm: sysblk failed bb mark\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int sysblk_get_free_blks(struct ppa_addr ppa, int nr_blks, u8 *blks,
+								void *private)
+{
+	struct sysblk_scan *s = private;
+	struct ppa_addr *sppa;
+	int i, blkid = 0;
+
+	for (i = 0; i < nr_blks; i++) {
+		if (blks[i] == NVM_BLK_T_HOST)
+			return -EEXIST;
+
+		if (blks[i] != NVM_BLK_T_FREE)
+			continue;
+
+		sppa = &s->ppas[scan_ppa_idx(s->row, blkid)];
+		sppa->g.ch = ppa.g.ch;
+		sppa->g.lun = ppa.g.lun;
+		sppa->g.blk = i;
+		s->nr_ppas++;
+		blkid++;
+
+		pr_debug("nvm: use (%u %u %u) as sysblk\n",
+					sppa->g.ch, sppa->g.lun, sppa->g.blk);
+		if (blkid > MAX_BLKS_PR_SYSBLK - 1)
+			return 0;
+	}
+
+	pr_err("nvm: sysblk failed get sysblk\n");
+	return -EINVAL;
+}
+
+static int nvm_write_and_verify(struct nvm_dev *dev, struct nvm_sb_info *info,
+							struct sysblk_scan *s)
+{
+	struct nvm_system_block nvmsb;
+	void *buf;
+	int i, sect, ret, bufsz;
+	struct ppa_addr *ppas;
+
+	nvm_cpu_to_sysblk(&nvmsb, info);
+
+	/* buffer for flash page */
+	bufsz = dev->sec_size * dev->sec_per_pg * dev->nr_planes;
+	buf = kzalloc(bufsz, GFP_KERNEL);
+	if (!buf)
+		return -ENOMEM;
+	memcpy(buf, &nvmsb, sizeof(struct nvm_system_block));
+
+	ppas = kcalloc(dev->sec_per_pg, sizeof(struct ppa_addr), GFP_KERNEL);
+	if (!ppas) {
+		ret = -ENOMEM;
+		goto err;
+	}
+
+	/* Write and verify */
+	for (i = 0; i < s->nr_rows; i++) {
+		ppas[0] = s->ppas[scan_ppa_idx(i, s->act_blk[i])];
+
+		pr_debug("nvm: writing sysblk to ppa (%u %u %u %u)\n",
+							ppas[0].g.ch,
+							ppas[0].g.lun,
+							ppas[0].g.blk,
+							ppas[0].g.pg);
+
+		/* Expand to all sectors within a flash page */
+		if (dev->sec_per_pg > 1) {
+			for (sect = 1; sect < dev->sec_per_pg; sect++) {
+				ppas[sect].ppa = ppas[0].ppa;
+				ppas[sect].g.sec = sect;
+			}
+		}
+
+		ret = nvm_submit_ppa(dev, ppas, dev->sec_per_pg, NVM_OP_PWRITE,
+						NVM_IO_SLC_MODE, buf, bufsz);
+		if (ret) {
+			pr_err("nvm: sysblk failed program (%u %u %u)\n",
+							ppas[0].g.ch,
+							ppas[0].g.lun,
+							ppas[0].g.blk);
+			break;
+		}
+
+		ret = nvm_submit_ppa(dev, ppas, dev->sec_per_pg, NVM_OP_PREAD,
+						NVM_IO_SLC_MODE, buf, bufsz);
+		if (ret) {
+			pr_err("nvm: sysblk failed read (%u %u %u)\n",
+							ppas[0].g.ch,
+							ppas[0].g.lun,
+							ppas[0].g.blk);
+			break;
+		}
+
+		if (memcmp(buf, &nvmsb, sizeof(struct nvm_system_block))) {
+			pr_err("nvm: sysblk failed verify (%u %u %u)\n",
+							ppas[0].g.ch,
+							ppas[0].g.lun,
+							ppas[0].g.blk);
+			ret = -EINVAL;
+			break;
+		}
+	}
+
+	kfree(ppas);
+err:
+	kfree(buf);
+
+	return ret;
+}
+
+static int nvm_prepare_new_sysblks(struct nvm_dev *dev, struct sysblk_scan *s)
+{
+	int i, ret;
+	unsigned long nxt_blk;
+	struct ppa_addr *ppa;
+
+	for (i = 0; i < s->nr_rows; i++) {
+		nxt_blk = (s->act_blk[i] + 1) % MAX_BLKS_PR_SYSBLK;
+		ppa = &s->ppas[scan_ppa_idx(i, nxt_blk)];
+		ppa->g.pg = ppa_to_slc(dev, 0);
+
+		ret = nvm_erase_ppa(dev, ppa, 1);
+		if (ret)
+			return ret;
+
+		s->act_blk[i] = nxt_blk;
+	}
+
+	return 0;
+}
+
+int nvm_get_sysblock(struct nvm_dev *dev, struct nvm_sb_info *info)
+{
+	struct ppa_addr sysblk_ppas[MAX_SYSBLKS];
+	struct sysblk_scan s;
+	struct nvm_system_block *cur;
+	int i, j, found = 0;
+	int ret = -ENOMEM;
+
+	/*
+	 * 1. setup sysblk locations
+	 * 2. get bad block list
+	 * 3. filter on host-specific (type 3)
+	 * 4. iterate through all and find the highest seq nr.
+	 * 5. return superblock information
+	 */
+
+	if (!dev->ops->get_bb_tbl)
+		return -EINVAL;
+
+	nvm_setup_sysblk_scan(dev, &s, sysblk_ppas);
+
+	mutex_lock(&dev->mlock);
+	ret = nvm_get_all_sysblks(dev, &s, sysblk_ppas, sysblk_get_host_blks);
+	if (ret)
+		goto err_sysblk;
+
+	/* no sysblocks initialized */
+	if (!s.nr_ppas)
+		goto err_sysblk;
+
+	cur = kzalloc(sizeof(struct nvm_system_block), GFP_KERNEL);
+	if (!cur)
+		goto err_sysblk;
+
+	/* find the latest block across all sysblocks */
+	for (i = 0; i < s.nr_rows; i++) {
+		for (j = 0; j < MAX_BLKS_PR_SYSBLK; j++) {
+			struct ppa_addr ppa = s.ppas[scan_ppa_idx(i, j)];
+
+			ret = nvm_scan_block(dev, &ppa, cur);
+			if (ret > 0)
+				found = 1;
+			else if (ret < 0)
+				break;
+		}
+	}
+
+	nvm_sysblk_to_cpu(info, cur);
+
+	kfree(cur);
+err_sysblk:
+	mutex_unlock(&dev->mlock);
+
+	if (found)
+		return 1;
+	return ret;
+}
+
+int nvm_update_sysblock(struct nvm_dev *dev, struct nvm_sb_info *new)
+{
+	/* 1. for each latest superblock
+	 * 2. if room
+	 *    a. write new flash page entry with the updated information
+	 * 3. if no room
+	 *    a. find next available block on lun (linear search)
+	 *       if none, continue to next lun
+	 *       if none at all, report error. also report that it wasn't
+	 *       possible to write to all superblocks.
+	 *    c. write data to block.
+	 */
+	struct ppa_addr sysblk_ppas[MAX_SYSBLKS];
+	struct sysblk_scan s;
+	struct nvm_system_block *cur;
+	int i, j, ppaidx, found = 0;
+	int ret = -ENOMEM;
+
+	if (!dev->ops->get_bb_tbl)
+		return -EINVAL;
+
+	nvm_setup_sysblk_scan(dev, &s, sysblk_ppas);
+
+	mutex_lock(&dev->mlock);
+	ret = nvm_get_all_sysblks(dev, &s, sysblk_ppas, sysblk_get_host_blks);
+	if (ret)
+		goto err_sysblk;
+
+	cur = kzalloc(sizeof(struct nvm_system_block), GFP_KERNEL);
+	if (!cur)
+		goto err_sysblk;
+
+	/* Get the latest sysblk for each sysblk row */
+	for (i = 0; i < s.nr_rows; i++) {
+		found = 0;
+		for (j = 0; j < MAX_BLKS_PR_SYSBLK; j++) {
+			ppaidx = scan_ppa_idx(i, j);
+			ret = nvm_scan_block(dev, &s.ppas[ppaidx], cur);
+			if (ret > 0) {
+				s.act_blk[i] = j;
+				found = 1;
+			} else if (ret < 0)
+				break;
+		}
+	}
+
+	if (!found) {
+		pr_err("nvm: no valid sysblks found to update\n");
+		ret = -EINVAL;
+		goto err_cur;
+	}
+
+	/*
+	 * All sysblocks found. Check that they have same page id in their flash
+	 * blocks
+	 */
+	for (i = 1; i < s.nr_rows; i++) {
+		struct ppa_addr l = s.ppas[scan_ppa_idx(0, s.act_blk[0])];
+		struct ppa_addr r = s.ppas[scan_ppa_idx(i, s.act_blk[i])];
+
+		if (l.g.pg != r.g.pg) {
+			pr_err("nvm: sysblks not on same page. Previous update failed.\n");
+			ret = -EINVAL;
+			goto err_cur;
+		}
+	}
+
+	/*
+	 * Check that there haven't been another update to the seqnr since we
+	 * began
+	 */
+	if ((new->seqnr - 1) != be32_to_cpu(cur->seqnr)) {
+		pr_err("nvm: seq is not sequential\n");
+		ret = -EINVAL;
+		goto err_cur;
+	}
+
+	/*
+	 * When all pages in a block has been written, a new block is selected
+	 * and writing is performed on the new block.
+	 */
+	if (s.ppas[scan_ppa_idx(0, s.act_blk[0])].g.pg ==
+						dev->lps_per_blk - 1) {
+		ret = nvm_prepare_new_sysblks(dev, &s);
+		if (ret)
+			goto err_cur;
+	}
+
+	ret = nvm_write_and_verify(dev, new, &s);
+err_cur:
+	kfree(cur);
+err_sysblk:
+	mutex_unlock(&dev->mlock);
+
+	return ret;
+}
+
+int nvm_init_sysblock(struct nvm_dev *dev, struct nvm_sb_info *info)
+{
+	struct ppa_addr sysblk_ppas[MAX_SYSBLKS];
+	struct sysblk_scan s;
+	int ret;
+
+	/*
+	 * 1. select master blocks and select first available blks
+	 * 2. get bad block list
+	 * 3. mark MAX_SYSBLKS block as host-based device allocated.
+	 * 4. write and verify data to block
+	 */
+
+	if (!dev->ops->get_bb_tbl || !dev->ops->set_bb_tbl)
+		return -EINVAL;
+
+	if (!(dev->mccap & NVM_ID_CAP_SLC) || !dev->lps_per_blk) {
+		pr_err("nvm: memory does not support SLC access\n");
+		return -EINVAL;
+	}
+
+	/* Index all sysblocks and mark them as host-driven */
+	nvm_setup_sysblk_scan(dev, &s, sysblk_ppas);
+
+	mutex_lock(&dev->mlock);
+	ret = nvm_get_all_sysblks(dev, &s, sysblk_ppas, sysblk_get_free_blks);
+	if (ret)
+		goto err_mark;
+
+	ret = nvm_set_bb_tbl(dev, &s, NVM_BLK_T_HOST);
+	if (ret)
+		goto err_mark;
+
+	/* Write to the first block of each row */
+	ret = nvm_write_and_verify(dev, info, &s);
+err_mark:
+	mutex_unlock(&dev->mlock);
+	return ret;
+}
+
+struct factory_blks {
+	struct nvm_dev *dev;
+	int flags;
+	unsigned long *blks;
+};
+
+static int factory_nblks(int nblks)
+{
+	/* Round up to nearest BITS_PER_LONG */
+	return (nblks + (BITS_PER_LONG - 1)) & ~(BITS_PER_LONG - 1);
+}
+
+static unsigned int factory_blk_offset(struct nvm_dev *dev, int ch, int lun)
+{
+	int nblks = factory_nblks(dev->blks_per_lun);
+
+	return ((ch * dev->luns_per_chnl * nblks) + (lun * nblks)) /
+								BITS_PER_LONG;
+}
+
+static int nvm_factory_blks(struct ppa_addr ppa, int nr_blks, u8 *blks,
+								void *private)
+{
+	struct factory_blks *f = private;
+	struct nvm_dev *dev = f->dev;
+	int i, lunoff;
+
+	lunoff = factory_blk_offset(dev, ppa.g.ch, ppa.g.lun);
+
+	/* non-set bits correspond to the block must be erased */
+	for (i = 0; i < nr_blks; i++) {
+		switch (blks[i]) {
+		case NVM_BLK_T_FREE:
+			if (f->flags & NVM_FACTORY_ERASE_ONLY_USER)
+				set_bit(i, &f->blks[lunoff]);
+			break;
+		case NVM_BLK_T_HOST:
+			if (!(f->flags & NVM_FACTORY_RESET_HOST_BLKS))
+				set_bit(i, &f->blks[lunoff]);
+			break;
+		case NVM_BLK_T_GRWN_BAD:
+			if (!(f->flags & NVM_FACTORY_RESET_GRWN_BBLKS))
+				set_bit(i, &f->blks[lunoff]);
+			break;
+		default:
+			set_bit(i, &f->blks[lunoff]);
+			break;
+		}
+	}
+
+	return 0;
+}
+
+static int nvm_fact_get_blks(struct nvm_dev *dev, struct ppa_addr *erase_list,
+					int max_ppas, struct factory_blks *f)
+{
+	struct ppa_addr ppa;
+	int ch, lun, blkid, idx, done = 0, ppa_cnt = 0;
+	unsigned long *offset;
+
+	while (!done) {
+		done = 1;
+		for (ch = 0; ch < dev->nr_chnls; ch++) {
+			for (lun = 0; lun < dev->luns_per_chnl; lun++) {
+				idx = factory_blk_offset(dev, ch, lun);
+				offset = &f->blks[idx];
+
+				blkid = find_first_zero_bit(offset,
+							dev->blks_per_lun);
+				if (blkid >= dev->blks_per_lun)
+					continue;
+				set_bit(blkid, offset);
+
+				ppa.ppa = 0;
+				ppa.g.ch = ch;
+				ppa.g.lun = lun;
+				ppa.g.blk = blkid;
+				pr_debug("nvm: erase ppa (%u %u %u)\n",
+								ppa.g.ch,
+								ppa.g.lun,
+								ppa.g.blk);
+
+				erase_list[ppa_cnt] = ppa;
+				ppa_cnt++;
+				done = 0;
+
+				if (ppa_cnt == max_ppas)
+					return ppa_cnt;
+			}
+		}
+	}
+
+	return ppa_cnt;
+}
+
+static int nvm_fact_get_bb_tbl(struct nvm_dev *dev, struct ppa_addr ppa,
+					nvm_bb_update_fn *fn, void *priv)
+{
+	struct ppa_addr dev_ppa;
+	int ret;
+
+	dev_ppa = generic_to_dev_addr(dev, ppa);
+
+	ret = dev->ops->get_bb_tbl(dev, dev_ppa, dev->blks_per_lun, fn, priv);
+	if (ret)
+		pr_err("nvm: failed bb tbl for ch%u lun%u\n",
+							ppa.g.ch, ppa.g.blk);
+	return ret;
+}
+
+static int nvm_fact_select_blks(struct nvm_dev *dev, struct factory_blks *f)
+{
+	int ch, lun, ret;
+	struct ppa_addr ppa;
+
+	ppa.ppa = 0;
+	for (ch = 0; ch < dev->nr_chnls; ch++) {
+		for (lun = 0; lun < dev->luns_per_chnl; lun++) {
+			ppa.g.ch = ch;
+			ppa.g.lun = lun;
+
+			ret = nvm_fact_get_bb_tbl(dev, ppa, nvm_factory_blks,
+									f);
+			if (ret)
+				return ret;
+		}
+	}
+
+	return 0;
+}
+
+int nvm_dev_factory(struct nvm_dev *dev, int flags)
+{
+	struct factory_blks f;
+	struct ppa_addr *ppas;
+	int ppa_cnt, ret = -ENOMEM;
+	int max_ppas = dev->ops->max_phys_sect / dev->nr_planes;
+	struct ppa_addr sysblk_ppas[MAX_SYSBLKS];
+	struct sysblk_scan s;
+
+	f.blks = kzalloc(factory_nblks(dev->blks_per_lun) * dev->nr_luns,
+								GFP_KERNEL);
+	if (!f.blks)
+		return ret;
+
+	ppas = kcalloc(max_ppas, sizeof(struct ppa_addr), GFP_KERNEL);
+	if (!ppas)
+		goto err_blks;
+
+	f.dev = dev;
+	f.flags = flags;
+
+	/* create list of blks to be erased */
+	ret = nvm_fact_select_blks(dev, &f);
+	if (ret)
+		goto err_ppas;
+
+	/* continue to erase until list of blks until empty */
+	while ((ppa_cnt = nvm_fact_get_blks(dev, ppas, max_ppas, &f)) > 0)
+		nvm_erase_ppa(dev, ppas, ppa_cnt);
+
+	/* mark host reserved blocks free */
+	if (flags & NVM_FACTORY_RESET_HOST_BLKS) {
+		nvm_setup_sysblk_scan(dev, &s, sysblk_ppas);
+		mutex_lock(&dev->mlock);
+		ret = nvm_get_all_sysblks(dev, &s, sysblk_ppas,
+							sysblk_get_host_blks);
+		if (!ret)
+			ret = nvm_set_bb_tbl(dev, &s, NVM_BLK_T_FREE);
+		mutex_unlock(&dev->mlock);
+	}
+err_ppas:
+	kfree(ppas);
+err_blks:
+	kfree(f.blks);
+	return ret;
+}
+EXPORT_SYMBOL(nvm_dev_factory);
--- zfcpdump-kernel-4.4.orig/drivers/mcb/mcb-parse.c
+++ zfcpdump-kernel-4.4/drivers/mcb/mcb-parse.c
@@ -57,7 +57,7 @@ static int chameleon_parse_gdd(struct mc
 	mdev->id = GDD_DEV(reg1);
 	mdev->rev = GDD_REV(reg1);
 	mdev->var = GDD_VAR(reg1);
-	mdev->bar = GDD_BAR(reg1);
+	mdev->bar = GDD_BAR(reg2);
 	mdev->group = GDD_GRP(reg2);
 	mdev->inst = GDD_INS(reg2);
 
--- zfcpdump-kernel-4.4.orig/drivers/md/bcache/btree.c
+++ zfcpdump-kernel-4.4/drivers/md/bcache/btree.c
@@ -1741,6 +1741,7 @@ static void bch_btree_gc(struct cache_se
 	do {
 		ret = btree_root(gc_root, c, &op, &writes, &stats);
 		closure_sync(&writes);
+		cond_resched();
 
 		if (ret && ret != -EAGAIN)
 			pr_warn("gc failed!");
@@ -2162,8 +2163,10 @@ int bch_btree_insert_check_key(struct bt
 		rw_lock(true, b, b->level);
 
 		if (b->key.ptr[0] != btree_ptr ||
-		    b->seq != seq + 1)
+                   b->seq != seq + 1) {
+                       op->lock = b->level;
 			goto out;
+               }
 	}
 
 	SET_KEY_PTRS(check_key, 1);
--- zfcpdump-kernel-4.4.orig/drivers/md/bcache/super.c
+++ zfcpdump-kernel-4.4/drivers/md/bcache/super.c
@@ -685,6 +685,8 @@ static void bcache_device_link(struct bc
 	WARN(sysfs_create_link(&d->kobj, &c->kobj, "cache") ||
 	     sysfs_create_link(&c->kobj, &d->kobj, d->name),
 	     "Couldn't create device <-> cache set symlinks");
+
+	clear_bit(BCACHE_DEV_UNLINK_DONE, &d->flags);
 }
 
 static void bcache_device_detach(struct bcache_device *d)
@@ -847,8 +849,11 @@ void bch_cached_dev_run(struct cached_de
 	buf[SB_LABEL_SIZE] = '\0';
 	env[2] = kasprintf(GFP_KERNEL, "CACHED_LABEL=%s", buf);
 
-	if (atomic_xchg(&dc->running, 1))
+	if (atomic_xchg(&dc->running, 1)) {
+		kfree(env[1]);
+		kfree(env[2]);
 		return;
+	}
 
 	if (!d->c &&
 	    BDEV_STATE(&dc->sb) != BDEV_STATE_NONE) {
@@ -1010,8 +1015,12 @@ int bch_cached_dev_attach(struct cached_
 	 */
 	atomic_set(&dc->count, 1);
 
-	if (bch_cached_dev_writeback_start(dc))
+	/* Block writeback thread, but spawn it */
+	down_write(&dc->writeback_lock);
+	if (bch_cached_dev_writeback_start(dc)) {
+		up_write(&dc->writeback_lock);
 		return -ENOMEM;
+	}
 
 	if (BDEV_STATE(&dc->sb) == BDEV_STATE_DIRTY) {
 		bch_sectors_dirty_init(dc);
@@ -1023,6 +1032,9 @@ int bch_cached_dev_attach(struct cached_
 	bch_cached_dev_run(dc);
 	bcache_device_link(&dc->disk, c, "bdev");
 
+	/* Allow the writeback thread to proceed */
+	up_write(&dc->writeback_lock);
+
 	pr_info("Caching %s as %s on set %pU",
 		bdevname(dc->bdev, buf), dc->disk.disk->disk_name,
 		dc->disk.c->sb.set_uuid);
@@ -1361,6 +1373,9 @@ static void cache_set_flush(struct closu
 	struct btree *b;
 	unsigned i;
 
+	if (!c)
+		closure_return(cl);
+
 	bch_cache_accounting_destroy(&c->accounting);
 
 	kobject_put(&c->internal);
@@ -1803,7 +1818,7 @@ static int cache_alloc(struct cache_sb *
 	free = roundup_pow_of_two(ca->sb.nbuckets) >> 10;
 
 	if (!init_fifo(&ca->free[RESERVE_BTREE], 8, GFP_KERNEL) ||
-	    !init_fifo(&ca->free[RESERVE_PRIO], prio_buckets(ca), GFP_KERNEL) ||
+	    !init_fifo_exact(&ca->free[RESERVE_PRIO], prio_buckets(ca), GFP_KERNEL) ||
 	    !init_fifo(&ca->free[RESERVE_MOVINGGC], free, GFP_KERNEL) ||
 	    !init_fifo(&ca->free[RESERVE_NONE], free, GFP_KERNEL) ||
 	    !init_fifo(&ca->free_inc,	free << 2, GFP_KERNEL) ||
@@ -1823,11 +1838,12 @@ static int cache_alloc(struct cache_sb *
 	return 0;
 }
 
-static void register_cache(struct cache_sb *sb, struct page *sb_page,
+static int register_cache(struct cache_sb *sb, struct page *sb_page,
 				struct block_device *bdev, struct cache *ca)
 {
 	char name[BDEVNAME_SIZE];
-	const char *err = "cannot allocate memory";
+	const char *err = NULL;
+	int ret = 0;
 
 	memcpy(&ca->sb, sb, sizeof(struct cache_sb));
 	ca->bdev = bdev;
@@ -1842,27 +1858,35 @@ static void register_cache(struct cache_
 	if (blk_queue_discard(bdev_get_queue(ca->bdev)))
 		ca->discard = CACHE_DISCARD(&ca->sb);
 
-	if (cache_alloc(sb, ca) != 0)
+	ret = cache_alloc(sb, ca);
+	if (ret != 0)
 		goto err;
 
-	err = "error creating kobject";
-	if (kobject_add(&ca->kobj, &part_to_dev(bdev->bd_part)->kobj, "bcache"))
-		goto err;
+	if (kobject_add(&ca->kobj, &part_to_dev(bdev->bd_part)->kobj, "bcache")) {
+		err = "error calling kobject_add";
+		ret = -ENOMEM;
+		goto out;
+	}
 
 	mutex_lock(&bch_register_lock);
 	err = register_cache_set(ca);
 	mutex_unlock(&bch_register_lock);
 
-	if (err)
-		goto err;
+	if (err) {
+		ret = -ENODEV;
+		goto out;
+	}
 
 	pr_info("registered cache device %s", bdevname(bdev, name));
+
 out:
 	kobject_put(&ca->kobj);
-	return;
+
 err:
-	pr_notice("error opening %s: %s", bdevname(bdev, name), err);
-	goto out;
+	if (err)
+		pr_notice("error opening %s: %s", bdevname(bdev, name), err);
+
+	return ret;
 }
 
 /* Global interfaces/init */
@@ -1926,13 +1950,15 @@ static ssize_t register_bcache(struct ko
 				  sb);
 	if (IS_ERR(bdev)) {
 		if (bdev == ERR_PTR(-EBUSY)) {
-			bdev = lookup_bdev(strim(path));
+			bdev = lookup_bdev(strim(path), 0);
 			mutex_lock(&bch_register_lock);
 			if (!IS_ERR(bdev) && bch_is_open(bdev))
 				err = "device already registered";
 			else
 				err = "device busy";
 			mutex_unlock(&bch_register_lock);
+			if (attr == &ksysfs_register_quiet)
+				goto out;
 		}
 		goto err;
 	}
@@ -1958,7 +1984,8 @@ static ssize_t register_bcache(struct ko
 		if (!ca)
 			goto err_close;
 
-		register_cache(sb, sb_page, bdev, ca);
+		if (register_cache(sb, sb_page, bdev, ca) != 0)
+			goto err_close;
 	}
 out:
 	if (sb_page)
@@ -1971,8 +1998,7 @@ out:
 err_close:
 	blkdev_put(bdev, FMODE_READ|FMODE_WRITE|FMODE_EXCL);
 err:
-	if (attr != &ksysfs_register_quiet)
-		pr_info("error opening %s: %s", path, err);
+	pr_info("error opening %s: %s", path, err);
 	ret = -EINVAL;
 	goto out;
 }
@@ -2066,8 +2092,10 @@ static int __init bcache_init(void)
 	closure_debug_init();
 
 	bcache_major = register_blkdev(0, "bcache");
-	if (bcache_major < 0)
+	if (bcache_major < 0) {
+		unregister_reboot_notifier(&reboot);
 		return bcache_major;
+	}
 
 	if (!(bcache_wq = create_workqueue("bcache")) ||
 	    !(bcache_kobj = kobject_create_and_add("bcache", fs_kobj)) ||
--- zfcpdump-kernel-4.4.orig/drivers/md/bcache/writeback.c
+++ zfcpdump-kernel-4.4/drivers/md/bcache/writeback.c
@@ -323,6 +323,10 @@ void bcache_dev_sectors_dirty_add(struct
 
 static bool dirty_pred(struct keybuf *buf, struct bkey *k)
 {
+	struct cached_dev *dc = container_of(buf, struct cached_dev, writeback_keys);
+
+	BUG_ON(KEY_INODE(k) != dc->disk.id);
+
 	return KEY_DIRTY(k);
 }
 
@@ -372,11 +376,24 @@ next:
 	}
 }
 
+/*
+ * Returns true if we scanned the entire disk
+ */
 static bool refill_dirty(struct cached_dev *dc)
 {
 	struct keybuf *buf = &dc->writeback_keys;
+	struct bkey start = KEY(dc->disk.id, 0, 0);
 	struct bkey end = KEY(dc->disk.id, MAX_KEY_OFFSET, 0);
-	bool searched_from_start = false;
+	struct bkey start_pos;
+
+	/*
+	 * make sure keybuf pos is inside the range for this disk - at bringup
+	 * we might not be attached yet so this disk's inode nr isn't
+	 * initialized then
+	 */
+	if (bkey_cmp(&buf->last_scanned, &start) < 0 ||
+	    bkey_cmp(&buf->last_scanned, &end) > 0)
+		buf->last_scanned = start;
 
 	if (dc->partial_stripes_expensive) {
 		refill_full_stripes(dc);
@@ -384,14 +401,20 @@ static bool refill_dirty(struct cached_d
 			return false;
 	}
 
-	if (bkey_cmp(&buf->last_scanned, &end) >= 0) {
-		buf->last_scanned = KEY(dc->disk.id, 0, 0);
-		searched_from_start = true;
-	}
-
+	start_pos = buf->last_scanned;
 	bch_refill_keybuf(dc->disk.c, buf, &end, dirty_pred);
 
-	return bkey_cmp(&buf->last_scanned, &end) >= 0 && searched_from_start;
+	if (bkey_cmp(&buf->last_scanned, &end) < 0)
+		return false;
+
+	/*
+	 * If we get to the end start scanning again from the beginning, and
+	 * only scan up to where we initially started scanning from:
+	 */
+	buf->last_scanned = start;
+	bch_refill_keybuf(dc->disk.c, buf, &start_pos, dirty_pred);
+
+	return bkey_cmp(&buf->last_scanned, &start_pos) >= 0;
 }
 
 static int bch_writeback_thread(void *arg)
--- zfcpdump-kernel-4.4.orig/drivers/md/bcache/writeback.h
+++ zfcpdump-kernel-4.4/drivers/md/bcache/writeback.h
@@ -63,7 +63,8 @@ static inline bool should_writeback(stru
 
 static inline void bch_writeback_queue(struct cached_dev *dc)
 {
-	wake_up_process(dc->writeback_thread);
+	if (!IS_ERR_OR_NULL(dc->writeback_thread))
+		wake_up_process(dc->writeback_thread);
 }
 
 static inline void bch_writeback_add(struct cached_dev *dc)
--- zfcpdump-kernel-4.4.orig/drivers/md/dm-cache-metadata.c
+++ zfcpdump-kernel-4.4/drivers/md/dm-cache-metadata.c
@@ -867,18 +867,55 @@ static int blocks_are_unmapped_or_clean(
 	return 0;
 }
 
-#define WRITE_LOCK(cmd) \
-	if (cmd->fail_io || dm_bm_is_read_only(cmd->bm)) \
-		return -EINVAL; \
-	down_write(&cmd->root_lock)
-
-#define WRITE_LOCK_VOID(cmd) \
-	if (cmd->fail_io || dm_bm_is_read_only(cmd->bm)) \
-		return; \
-	down_write(&cmd->root_lock)
+static bool cmd_write_lock(struct dm_cache_metadata *cmd)
+{
+	down_write(&cmd->root_lock);
+	if (cmd->fail_io || dm_bm_is_read_only(cmd->bm)) {
+		up_write(&cmd->root_lock);
+		return false;
+	}
+	return true;
+}
+
+#define WRITE_LOCK(cmd)				\
+	do {					\
+		if (!cmd_write_lock((cmd)))	\
+			return -EINVAL;		\
+	} while(0)
+
+#define WRITE_LOCK_VOID(cmd)			\
+	do {					\
+		if (!cmd_write_lock((cmd)))	\
+			return;			\
+	} while(0)
 
 #define WRITE_UNLOCK(cmd) \
-	up_write(&cmd->root_lock)
+	up_write(&(cmd)->root_lock)
+
+static bool cmd_read_lock(struct dm_cache_metadata *cmd)
+{
+	down_read(&cmd->root_lock);
+	if (cmd->fail_io) {
+		up_read(&cmd->root_lock);
+		return false;
+	}
+	return true;
+}
+
+#define READ_LOCK(cmd)				\
+	do {					\
+		if (!cmd_read_lock((cmd)))	\
+			return -EINVAL;		\
+	} while(0)
+
+#define READ_LOCK_VOID(cmd)			\
+	do {					\
+		if (!cmd_read_lock((cmd)))	\
+			return;			\
+	} while(0)
+
+#define READ_UNLOCK(cmd) \
+	up_read(&(cmd)->root_lock)
 
 int dm_cache_resize(struct dm_cache_metadata *cmd, dm_cblock_t new_cache_size)
 {
@@ -1015,22 +1052,20 @@ int dm_cache_load_discards(struct dm_cac
 {
 	int r;
 
-	down_read(&cmd->root_lock);
+	READ_LOCK(cmd);
 	r = __load_discards(cmd, fn, context);
-	up_read(&cmd->root_lock);
+	READ_UNLOCK(cmd);
 
 	return r;
 }
 
-dm_cblock_t dm_cache_size(struct dm_cache_metadata *cmd)
+int dm_cache_size(struct dm_cache_metadata *cmd, dm_cblock_t *result)
 {
-	dm_cblock_t r;
+	READ_LOCK(cmd);
+	*result = cmd->cache_blocks;
+	READ_UNLOCK(cmd);
 
-	down_read(&cmd->root_lock);
-	r = cmd->cache_blocks;
-	up_read(&cmd->root_lock);
-
-	return r;
+	return 0;
 }
 
 static int __remove(struct dm_cache_metadata *cmd, dm_cblock_t cblock)
@@ -1188,9 +1223,9 @@ int dm_cache_load_mappings(struct dm_cac
 {
 	int r;
 
-	down_read(&cmd->root_lock);
+	READ_LOCK(cmd);
 	r = __load_mappings(cmd, policy, fn, context);
-	up_read(&cmd->root_lock);
+	READ_UNLOCK(cmd);
 
 	return r;
 }
@@ -1215,18 +1250,18 @@ static int __dump_mappings(struct dm_cac
 
 void dm_cache_dump(struct dm_cache_metadata *cmd)
 {
-	down_read(&cmd->root_lock);
+	READ_LOCK_VOID(cmd);
 	__dump_mappings(cmd);
-	up_read(&cmd->root_lock);
+	READ_UNLOCK(cmd);
 }
 
 int dm_cache_changed_this_transaction(struct dm_cache_metadata *cmd)
 {
 	int r;
 
-	down_read(&cmd->root_lock);
+	READ_LOCK(cmd);
 	r = cmd->changed;
-	up_read(&cmd->root_lock);
+	READ_UNLOCK(cmd);
 
 	return r;
 }
@@ -1276,9 +1311,9 @@ int dm_cache_set_dirty(struct dm_cache_m
 void dm_cache_metadata_get_stats(struct dm_cache_metadata *cmd,
 				 struct dm_cache_statistics *stats)
 {
-	down_read(&cmd->root_lock);
+	READ_LOCK_VOID(cmd);
 	*stats = cmd->stats;
-	up_read(&cmd->root_lock);
+	READ_UNLOCK(cmd);
 }
 
 void dm_cache_metadata_set_stats(struct dm_cache_metadata *cmd,
@@ -1312,9 +1347,9 @@ int dm_cache_get_free_metadata_block_cou
 {
 	int r = -EINVAL;
 
-	down_read(&cmd->root_lock);
+	READ_LOCK(cmd);
 	r = dm_sm_get_nr_free(cmd->metadata_sm, result);
-	up_read(&cmd->root_lock);
+	READ_UNLOCK(cmd);
 
 	return r;
 }
@@ -1324,9 +1359,9 @@ int dm_cache_get_metadata_dev_size(struc
 {
 	int r = -EINVAL;
 
-	down_read(&cmd->root_lock);
+	READ_LOCK(cmd);
 	r = dm_sm_get_nr_blocks(cmd->metadata_sm, result);
-	up_read(&cmd->root_lock);
+	READ_UNLOCK(cmd);
 
 	return r;
 }
@@ -1417,7 +1452,13 @@ int dm_cache_write_hints(struct dm_cache
 
 int dm_cache_metadata_all_clean(struct dm_cache_metadata *cmd, bool *result)
 {
-	return blocks_are_unmapped_or_clean(cmd, 0, cmd->cache_blocks, result);
+	int r;
+
+	READ_LOCK(cmd);
+	r = blocks_are_unmapped_or_clean(cmd, 0, cmd->cache_blocks, result);
+	READ_UNLOCK(cmd);
+
+	return r;
 }
 
 void dm_cache_metadata_set_read_only(struct dm_cache_metadata *cmd)
@@ -1440,10 +1481,7 @@ int dm_cache_metadata_set_needs_check(st
 	struct dm_block *sblock;
 	struct cache_disk_superblock *disk_super;
 
-	/*
-	 * We ignore fail_io for this function.
-	 */
-	down_write(&cmd->root_lock);
+	WRITE_LOCK(cmd);
 	set_bit(NEEDS_CHECK, &cmd->flags);
 
 	r = superblock_lock(cmd, &sblock);
@@ -1458,19 +1496,17 @@ int dm_cache_metadata_set_needs_check(st
 	dm_bm_unlock(sblock);
 
 out:
-	up_write(&cmd->root_lock);
+	WRITE_UNLOCK(cmd);
 	return r;
 }
 
-bool dm_cache_metadata_needs_check(struct dm_cache_metadata *cmd)
+int dm_cache_metadata_needs_check(struct dm_cache_metadata *cmd, bool *result)
 {
-	bool needs_check;
-
-	down_read(&cmd->root_lock);
-	needs_check = !!test_bit(NEEDS_CHECK, &cmd->flags);
-	up_read(&cmd->root_lock);
+	READ_LOCK(cmd);
+	*result = !!test_bit(NEEDS_CHECK, &cmd->flags);
+	READ_UNLOCK(cmd);
 
-	return needs_check;
+	return 0;
 }
 
 int dm_cache_metadata_abort(struct dm_cache_metadata *cmd)
--- zfcpdump-kernel-4.4.orig/drivers/md/dm-cache-metadata.h
+++ zfcpdump-kernel-4.4/drivers/md/dm-cache-metadata.h
@@ -66,7 +66,7 @@ void dm_cache_metadata_close(struct dm_c
  * origin blocks to map to.
  */
 int dm_cache_resize(struct dm_cache_metadata *cmd, dm_cblock_t new_cache_size);
-dm_cblock_t dm_cache_size(struct dm_cache_metadata *cmd);
+int dm_cache_size(struct dm_cache_metadata *cmd, dm_cblock_t *result);
 
 int dm_cache_discard_bitset_resize(struct dm_cache_metadata *cmd,
 				   sector_t discard_block_size,
@@ -137,7 +137,7 @@ int dm_cache_write_hints(struct dm_cache
  */
 int dm_cache_metadata_all_clean(struct dm_cache_metadata *cmd, bool *result);
 
-bool dm_cache_metadata_needs_check(struct dm_cache_metadata *cmd);
+int dm_cache_metadata_needs_check(struct dm_cache_metadata *cmd, bool *result);
 int dm_cache_metadata_set_needs_check(struct dm_cache_metadata *cmd);
 void dm_cache_metadata_set_read_only(struct dm_cache_metadata *cmd);
 void dm_cache_metadata_set_read_write(struct dm_cache_metadata *cmd);
--- zfcpdump-kernel-4.4.orig/drivers/md/dm-cache-target.c
+++ zfcpdump-kernel-4.4/drivers/md/dm-cache-target.c
@@ -987,9 +987,14 @@ static void notify_mode_switch(struct ca
 
 static void set_cache_mode(struct cache *cache, enum cache_metadata_mode new_mode)
 {
-	bool needs_check = dm_cache_metadata_needs_check(cache->cmd);
+	bool needs_check;
 	enum cache_metadata_mode old_mode = get_cache_mode(cache);
 
+	if (dm_cache_metadata_needs_check(cache->cmd, &needs_check)) {
+		DMERR("unable to read needs_check flag, setting failure mode");
+		new_mode = CM_FAIL;
+	}
+
 	if (new_mode == CM_WRITE && needs_check) {
 		DMERR("%s: unable to switch cache to write mode until repaired.",
 		      cache_device_name(cache));
@@ -3513,6 +3518,7 @@ static void cache_status(struct dm_targe
 	char buf[BDEVNAME_SIZE];
 	struct cache *cache = ti->private;
 	dm_cblock_t residency;
+	bool needs_check;
 
 	switch (type) {
 	case STATUSTYPE_INFO:
@@ -3586,7 +3592,9 @@ static void cache_status(struct dm_targe
 		else
 			DMEMIT("rw ");
 
-		if (dm_cache_metadata_needs_check(cache->cmd))
+		r = dm_cache_metadata_needs_check(cache->cmd, &needs_check);
+
+		if (r || needs_check)
 			DMEMIT("needs_check ");
 		else
 			DMEMIT("- ");
--- zfcpdump-kernel-4.4.orig/drivers/md/dm-crypt.c
+++ zfcpdump-kernel-4.4/drivers/md/dm-crypt.c
@@ -1920,6 +1920,13 @@ static int crypt_map(struct dm_target *t
 		return DM_MAPIO_REMAPPED;
 	}
 
+	/*
+	 * Check if bio is too large, split as needed.
+	 */
+	if (unlikely(bio->bi_iter.bi_size > (BIO_MAX_PAGES << PAGE_SHIFT)) &&
+	    bio_data_dir(bio) == WRITE)
+		dm_accept_partial_bio(bio, ((BIO_MAX_PAGES << PAGE_SHIFT) >> SECTOR_SHIFT));
+
 	io = dm_per_bio_data(bio, cc->per_bio_data_size);
 	crypt_io_init(io, cc, bio, dm_target_offset(ti, bio->bi_iter.bi_sector));
 	io->ctx.req = (struct ablkcipher_request *)(io + 1);
--- zfcpdump-kernel-4.4.orig/drivers/md/dm-exception-store.h
+++ zfcpdump-kernel-4.4/drivers/md/dm-exception-store.h
@@ -69,7 +69,7 @@ struct dm_exception_store_type {
 	 * Update the metadata with this exception.
 	 */
 	void (*commit_exception) (struct dm_exception_store *store,
-				  struct dm_exception *e,
+				  struct dm_exception *e, int valid,
 				  void (*callback) (void *, int success),
 				  void *callback_context);
 
--- zfcpdump-kernel-4.4.orig/drivers/md/dm-flakey.c
+++ zfcpdump-kernel-4.4/drivers/md/dm-flakey.c
@@ -289,10 +289,14 @@ static int flakey_map(struct dm_target *
 		pb->bio_submitted = true;
 
 		/*
-		 * Map reads as normal.
+		 * Error reads if neither corrupt_bio_byte or drop_writes are set.
+		 * Otherwise, flakey_end_io() will decide if the reads should be modified.
 		 */
-		if (bio_data_dir(bio) == READ)
+		if (bio_data_dir(bio) == READ) {
+			if (!fc->corrupt_bio_byte && !test_bit(DROP_WRITES, &fc->flags))
+				return -EIO;
 			goto map_bio;
+		}
 
 		/*
 		 * Drop writes?
@@ -328,14 +332,22 @@ static int flakey_end_io(struct dm_targe
 	struct flakey_c *fc = ti->private;
 	struct per_bio_data *pb = dm_per_bio_data(bio, sizeof(struct per_bio_data));
 
-	/*
-	 * Corrupt successful READs while in down state.
-	 * If flags were specified, only corrupt those that match.
-	 */
-	if (fc->corrupt_bio_byte && !error && pb->bio_submitted &&
-	    (bio_data_dir(bio) == READ) && (fc->corrupt_bio_rw == READ) &&
-	    all_corrupt_bio_flags_match(bio, fc))
-		corrupt_bio_data(bio, fc);
+	if (!error && pb->bio_submitted && (bio_data_dir(bio) == READ)) {
+		if (fc->corrupt_bio_byte && (fc->corrupt_bio_rw == READ) &&
+		    all_corrupt_bio_flags_match(bio, fc)) {
+			/*
+			 * Corrupt successful matching READs while in down state.
+			 */
+			corrupt_bio_data(bio, fc);
+
+		} else if (!test_bit(DROP_WRITES, &fc->flags)) {
+			/*
+			 * Error read during the down_interval if drop_writes
+			 * wasn't configured.
+			 */
+			return -EIO;
+		}
+	}
 
 	return error;
 }
--- zfcpdump-kernel-4.4.orig/drivers/md/dm-log-writes.c
+++ zfcpdump-kernel-4.4/drivers/md/dm-log-writes.c
@@ -258,12 +258,12 @@ static int log_one_block(struct log_writ
 		goto out;
 	sector++;
 
-	bio = bio_alloc(GFP_KERNEL, block->vec_cnt);
+	atomic_inc(&lc->io_blocks);
+	bio = bio_alloc(GFP_KERNEL, min(block->vec_cnt, BIO_MAX_PAGES));
 	if (!bio) {
 		DMERR("Couldn't alloc log bio");
 		goto error;
 	}
-	atomic_inc(&lc->io_blocks);
 	bio->bi_iter.bi_size = 0;
 	bio->bi_iter.bi_sector = sector;
 	bio->bi_bdev = lc->logdev->bdev;
@@ -280,7 +280,7 @@ static int log_one_block(struct log_writ
 		if (ret != block->vecs[i].bv_len) {
 			atomic_inc(&lc->io_blocks);
 			submit_bio(WRITE, bio);
-			bio = bio_alloc(GFP_KERNEL, block->vec_cnt - i);
+			bio = bio_alloc(GFP_KERNEL, min(block->vec_cnt - i, BIO_MAX_PAGES));
 			if (!bio) {
 				DMERR("Couldn't alloc log bio");
 				goto error;
@@ -456,9 +456,9 @@ static int log_writes_ctr(struct dm_targ
 		goto bad;
 	}
 
-	ret = -EINVAL;
 	lc->log_kthread = kthread_run(log_writes_kthread, lc, "log-write");
-	if (!lc->log_kthread) {
+	if (IS_ERR(lc->log_kthread)) {
+		ret = PTR_ERR(lc->log_kthread);
 		ti->error = "Couldn't alloc kthread";
 		dm_put_device(ti, lc->dev);
 		dm_put_device(ti, lc->logdev);
--- zfcpdump-kernel-4.4.orig/drivers/md/dm-snap-persistent.c
+++ zfcpdump-kernel-4.4/drivers/md/dm-snap-persistent.c
@@ -695,7 +695,7 @@ static int persistent_prepare_exception(
 }
 
 static void persistent_commit_exception(struct dm_exception_store *store,
-					struct dm_exception *e,
+					struct dm_exception *e, int valid,
 					void (*callback) (void *, int success),
 					void *callback_context)
 {
@@ -704,6 +704,9 @@ static void persistent_commit_exception(
 	struct core_exception ce;
 	struct commit_callback *cb;
 
+	if (!valid)
+		ps->valid = 0;
+
 	ce.old_chunk = e->old_chunk;
 	ce.new_chunk = e->new_chunk;
 	write_exception(ps, ps->current_committed++, &ce);
--- zfcpdump-kernel-4.4.orig/drivers/md/dm-snap-transient.c
+++ zfcpdump-kernel-4.4/drivers/md/dm-snap-transient.c
@@ -52,12 +52,12 @@ static int transient_prepare_exception(s
 }
 
 static void transient_commit_exception(struct dm_exception_store *store,
-				       struct dm_exception *e,
+				       struct dm_exception *e, int valid,
 				       void (*callback) (void *, int success),
 				       void *callback_context)
 {
 	/* Just succeed */
-	callback(callback_context, 1);
+	callback(callback_context, valid);
 }
 
 static void transient_usage(struct dm_exception_store *store,
--- zfcpdump-kernel-4.4.orig/drivers/md/dm-snap.c
+++ zfcpdump-kernel-4.4/drivers/md/dm-snap.c
@@ -1106,6 +1106,7 @@ static int snapshot_ctr(struct dm_target
 	int i;
 	int r = -EINVAL;
 	char *origin_path, *cow_path;
+	dev_t origin_dev, cow_dev;
 	unsigned args_used, num_flush_bios = 1;
 	fmode_t origin_mode = FMODE_READ;
 
@@ -1136,11 +1137,19 @@ static int snapshot_ctr(struct dm_target
 		ti->error = "Cannot get origin device";
 		goto bad_origin;
 	}
+	origin_dev = s->origin->bdev->bd_dev;
 
 	cow_path = argv[0];
 	argv++;
 	argc--;
 
+	cow_dev = dm_get_dev_t(cow_path);
+	if (cow_dev && cow_dev == origin_dev) {
+		ti->error = "COW device cannot be the same as origin device";
+		r = -EINVAL;
+		goto bad_cow;
+	}
+
 	r = dm_get_device(ti, cow_path, dm_table_get_mode(ti->table), &s->cow);
 	if (r) {
 		ti->error = "Cannot get COW device";
@@ -1438,8 +1447,9 @@ static void __invalidate_snapshot(struct
 	dm_table_event(s->ti->table);
 }
 
-static void pending_complete(struct dm_snap_pending_exception *pe, int success)
+static void pending_complete(void *context, int success)
 {
+	struct dm_snap_pending_exception *pe = context;
 	struct dm_exception *e;
 	struct dm_snapshot *s = pe->snap;
 	struct bio *origin_bios = NULL;
@@ -1509,24 +1519,13 @@ out:
 	free_pending_exception(pe);
 }
 
-static void commit_callback(void *context, int success)
-{
-	struct dm_snap_pending_exception *pe = context;
-
-	pending_complete(pe, success);
-}
-
 static void complete_exception(struct dm_snap_pending_exception *pe)
 {
 	struct dm_snapshot *s = pe->snap;
 
-	if (unlikely(pe->copy_error))
-		pending_complete(pe, 0);
-
-	else
-		/* Update the metadata if we are persistent */
-		s->store->type->commit_exception(s->store, &pe->e,
-						 commit_callback, pe);
+	/* Update the metadata if we are persistent */
+	s->store->type->commit_exception(s->store, &pe->e, !pe->copy_error,
+					 pending_complete, pe);
 }
 
 /*
--- zfcpdump-kernel-4.4.orig/drivers/md/dm-table.c
+++ zfcpdump-kernel-4.4/drivers/md/dm-table.c
@@ -365,6 +365,26 @@ static int upgrade_mode(struct dm_dev_in
 }
 
 /*
+ * Convert the path to a device
+ */
+dev_t dm_get_dev_t(const char *path)
+{
+	dev_t uninitialized_var(dev);
+	struct block_device *bdev;
+
+	bdev = lookup_bdev(path, 0);
+	if (IS_ERR(bdev))
+		dev = name_to_dev_t(path);
+	else {
+		dev = bdev->bd_dev;
+		bdput(bdev);
+	}
+
+	return dev;
+}
+EXPORT_SYMBOL_GPL(dm_get_dev_t);
+
+/*
  * Add a device to the list, or just increment the usage count if
  * it's already present.
  */
@@ -372,23 +392,15 @@ int dm_get_device(struct dm_target *ti,
 		  struct dm_dev **result)
 {
 	int r;
-	dev_t uninitialized_var(dev);
+	dev_t dev;
 	struct dm_dev_internal *dd;
 	struct dm_table *t = ti->table;
-	struct block_device *bdev;
 
 	BUG_ON(!t);
 
-	/* convert the path to a device */
-	bdev = lookup_bdev(path);
-	if (IS_ERR(bdev)) {
-		dev = name_to_dev_t(path);
-		if (!dev)
-			return -ENODEV;
-	} else {
-		dev = bdev->bd_dev;
-		bdput(bdev);
-	}
+	dev = dm_get_dev_t(path);
+	if (!dev)
+		return -ENODEV;
 
 	dd = find_device(&t->devices, dev);
 	if (!dd) {
--- zfcpdump-kernel-4.4.orig/drivers/md/dm-thin-metadata.c
+++ zfcpdump-kernel-4.4/drivers/md/dm-thin-metadata.c
@@ -1943,5 +1943,8 @@ bool dm_pool_metadata_needs_check(struct
 
 void dm_pool_issue_prefetches(struct dm_pool_metadata *pmd)
 {
-	dm_tm_issue_prefetches(pmd->tm);
+	down_read(&pmd->root_lock);
+	if (!pmd->fail_io)
+		dm_tm_issue_prefetches(pmd->tm);
+	up_read(&pmd->root_lock);
 }
--- zfcpdump-kernel-4.4.orig/drivers/md/dm-thin.c
+++ zfcpdump-kernel-4.4/drivers/md/dm-thin.c
@@ -3453,8 +3453,8 @@ static void pool_postsuspend(struct dm_t
 	struct pool_c *pt = ti->private;
 	struct pool *pool = pt->pool;
 
-	cancel_delayed_work(&pool->waker);
-	cancel_delayed_work(&pool->no_space_timeout);
+	cancel_delayed_work_sync(&pool->waker);
+	cancel_delayed_work_sync(&pool->no_space_timeout);
 	flush_workqueue(pool->wq);
 	(void) commit(pool);
 }
--- zfcpdump-kernel-4.4.orig/drivers/md/dm.c
+++ zfcpdump-kernel-4.4/drivers/md/dm.c
@@ -1109,12 +1109,8 @@ static void rq_completed(struct mapped_d
 	 * back into ->request_fn() could deadlock attempting to grab the
 	 * queue lock again.
 	 */
-	if (run_queue) {
-		if (md->queue->mq_ops)
-			blk_mq_run_hw_queues(md->queue, true);
-		else
-			blk_run_queue_async(md->queue);
-	}
+	if (!md->queue->mq_ops && run_queue)
+		blk_run_queue_async(md->queue);
 
 	/*
 	 * dm_put() must be at the end of this function. See the comment above
@@ -1191,6 +1187,8 @@ static void dm_unprep_request(struct req
 
 	if (clone)
 		free_rq_clone(clone);
+	else if (!tio->md->queue->mq_ops)
+		free_rq_tio(tio);
 }
 
 /*
@@ -1212,9 +1210,9 @@ static void dm_requeue_original_request(
 {
 	int rw = rq_data_dir(rq);
 
+	rq_end_stats(md, rq);
 	dm_unprep_request(rq);
 
-	rq_end_stats(md, rq);
 	if (!rq->q->mq_ops)
 		old_requeue_request(rq);
 	else {
@@ -1334,7 +1332,10 @@ static void dm_complete_request(struct r
 	struct dm_rq_target_io *tio = tio_from_request(rq);
 
 	tio->error = error;
-	blk_complete_request(rq);
+	if (!rq->q->mq_ops)
+		blk_complete_request(rq);
+	else
+		blk_mq_complete_request(rq, error);
 }
 
 /*
@@ -3077,7 +3078,8 @@ static void unlock_fs(struct mapped_devi
  * Caller must hold md->suspend_lock
  */
 static int __dm_suspend(struct mapped_device *md, struct dm_table *map,
-			unsigned suspend_flags, int interruptible)
+			unsigned suspend_flags, int interruptible,
+			int dmf_suspended_flag)
 {
 	bool do_lockfs = suspend_flags & DM_SUSPEND_LOCKFS_FLAG;
 	bool noflush = suspend_flags & DM_SUSPEND_NOFLUSH_FLAG;
@@ -3144,6 +3146,8 @@ static int __dm_suspend(struct mapped_de
 	 * to finish.
 	 */
 	r = dm_wait_for_completion(md, interruptible);
+	if (!r)
+		set_bit(dmf_suspended_flag, &md->flags);
 
 	if (noflush)
 		clear_bit(DMF_NOFLUSH_SUSPENDING, &md->flags);
@@ -3205,12 +3209,10 @@ retry:
 
 	map = rcu_dereference_protected(md->map, lockdep_is_held(&md->suspend_lock));
 
-	r = __dm_suspend(md, map, suspend_flags, TASK_INTERRUPTIBLE);
+	r = __dm_suspend(md, map, suspend_flags, TASK_INTERRUPTIBLE, DMF_SUSPENDED);
 	if (r)
 		goto out_unlock;
 
-	set_bit(DMF_SUSPENDED, &md->flags);
-
 	dm_table_postsuspend_targets(map);
 
 out_unlock:
@@ -3304,9 +3306,8 @@ static void __dm_internal_suspend(struct
 	 * would require changing .presuspend to return an error -- avoid this
 	 * until there is a need for more elaborate variants of internal suspend.
 	 */
-	(void) __dm_suspend(md, map, suspend_flags, TASK_UNINTERRUPTIBLE);
-
-	set_bit(DMF_SUSPENDED_INTERNALLY, &md->flags);
+	(void) __dm_suspend(md, map, suspend_flags, TASK_UNINTERRUPTIBLE,
+			    DMF_SUSPENDED_INTERNALLY);
 
 	dm_table_postsuspend_targets(map);
 }
--- zfcpdump-kernel-4.4.orig/drivers/md/md.c
+++ zfcpdump-kernel-4.4/drivers/md/md.c
@@ -293,6 +293,8 @@ static blk_qc_t md_make_request(struct r
 	 * go away inside make_request
 	 */
 	sectors = bio_sectors(bio);
+	/* bio could be mergeable after passing to underlayer */
+	bio->bi_rw &= ~REQ_NOMERGE;
 	mddev->pers->make_request(mddev, bio);
 
 	cpu = part_stat_lock();
@@ -2017,28 +2019,32 @@ int md_integrity_register(struct mddev *
 }
 EXPORT_SYMBOL(md_integrity_register);
 
-/* Disable data integrity if non-capable/non-matching disk is being added */
-void md_integrity_add_rdev(struct md_rdev *rdev, struct mddev *mddev)
+/*
+ * Attempt to add an rdev, but only if it is consistent with the current
+ * integrity profile
+ */
+int md_integrity_add_rdev(struct md_rdev *rdev, struct mddev *mddev)
 {
 	struct blk_integrity *bi_rdev;
 	struct blk_integrity *bi_mddev;
+	char name[BDEVNAME_SIZE];
 
 	if (!mddev->gendisk)
-		return;
+		return 0;
 
 	bi_rdev = bdev_get_integrity(rdev->bdev);
 	bi_mddev = blk_get_integrity(mddev->gendisk);
 
 	if (!bi_mddev) /* nothing to do */
-		return;
-	if (rdev->raid_disk < 0) /* skip spares */
-		return;
-	if (bi_rdev && blk_integrity_compare(mddev->gendisk,
-					     rdev->bdev->bd_disk) >= 0)
-		return;
-	WARN_ON_ONCE(!mddev->suspended);
-	printk(KERN_NOTICE "disabling data integrity on %s\n", mdname(mddev));
-	blk_integrity_unregister(mddev->gendisk);
+		return 0;
+
+	if (blk_integrity_compare(mddev->gendisk, rdev->bdev->bd_disk) != 0) {
+		printk(KERN_NOTICE "%s: incompatible integrity profile for %s\n",
+				mdname(mddev), bdevname(rdev->bdev, name));
+		return -ENXIO;
+	}
+
+	return 0;
 }
 EXPORT_SYMBOL(md_integrity_add_rdev);
 
@@ -7566,16 +7572,12 @@ EXPORT_SYMBOL(unregister_md_cluster_oper
 
 int md_setup_cluster(struct mddev *mddev, int nodes)
 {
-	int err;
-
-	err = request_module("md-cluster");
-	if (err) {
-		pr_err("md-cluster module not found.\n");
-		return -ENOENT;
-	}
-
+	if (!md_cluster_ops)
+		request_module("md-cluster");
 	spin_lock(&pers_lock);
+	/* ensure module won't be unloaded */
 	if (!md_cluster_ops || !try_module_get(md_cluster_mod)) {
+		pr_err("can't find md-cluster module or get it's reference.\n");
 		spin_unlock(&pers_lock);
 		return -ENOENT;
 	}
--- zfcpdump-kernel-4.4.orig/drivers/md/md.h
+++ zfcpdump-kernel-4.4/drivers/md/md.h
@@ -657,7 +657,7 @@ extern void md_wait_for_blocked_rdev(str
 extern void md_set_array_sectors(struct mddev *mddev, sector_t array_sectors);
 extern int md_check_no_bitmap(struct mddev *mddev);
 extern int md_integrity_register(struct mddev *mddev);
-extern void md_integrity_add_rdev(struct md_rdev *rdev, struct mddev *mddev);
+extern int md_integrity_add_rdev(struct md_rdev *rdev, struct mddev *mddev);
 extern int strict_strtoul_scaled(const char *cp, unsigned long *res, int scale);
 
 extern void mddev_init(struct mddev *mddev);
--- zfcpdump-kernel-4.4.orig/drivers/md/multipath.c
+++ zfcpdump-kernel-4.4/drivers/md/multipath.c
@@ -129,7 +129,9 @@ static void multipath_make_request(struc
 	}
 	multipath = conf->multipaths + mp_bh->path;
 
-	mp_bh->bio = *bio;
+	bio_init(&mp_bh->bio);
+	__bio_clone_fast(&mp_bh->bio, bio);
+
 	mp_bh->bio.bi_iter.bi_sector += multipath->rdev->data_offset;
 	mp_bh->bio.bi_bdev = multipath->rdev->bdev;
 	mp_bh->bio.bi_rw |= REQ_FAILFAST_TRANSPORT;
@@ -257,6 +259,9 @@ static int multipath_add_disk(struct mdd
 			disk_stack_limits(mddev->gendisk, rdev->bdev,
 					  rdev->data_offset << 9);
 
+			err = md_integrity_add_rdev(rdev, mddev);
+			if (err)
+				break;
 			spin_lock_irq(&conf->device_lock);
 			mddev->degraded--;
 			rdev->raid_disk = path;
@@ -264,9 +269,6 @@ static int multipath_add_disk(struct mdd
 			spin_unlock_irq(&conf->device_lock);
 			rcu_assign_pointer(p->rdev, rdev);
 			err = 0;
-			mddev_suspend(mddev);
-			md_integrity_add_rdev(rdev, mddev);
-			mddev_resume(mddev);
 			break;
 		}
 
--- zfcpdump-kernel-4.4.orig/drivers/md/persistent-data/dm-space-map-metadata.c
+++ zfcpdump-kernel-4.4/drivers/md/persistent-data/dm-space-map-metadata.c
@@ -152,12 +152,9 @@ static int brb_peek(struct bop_ring_buff
 
 static int brb_pop(struct bop_ring_buffer *brb)
 {
-	struct block_op *bop;
-
 	if (brb_empty(brb))
 		return -ENODATA;
 
-	bop = brb->bops + brb->begin;
 	brb->begin = brb_next(brb, brb->begin);
 
 	return 0;
--- zfcpdump-kernel-4.4.orig/drivers/md/raid1.c
+++ zfcpdump-kernel-4.4/drivers/md/raid1.c
@@ -1589,6 +1589,9 @@ static int raid1_add_disk(struct mddev *
 	if (mddev->recovery_disabled == conf->recovery_disabled)
 		return -EBUSY;
 
+	if (md_integrity_add_rdev(rdev, mddev))
+		return -ENXIO;
+
 	if (rdev->raid_disk >= 0)
 		first = last = rdev->raid_disk;
 
@@ -1632,9 +1635,6 @@ static int raid1_add_disk(struct mddev *
 			break;
 		}
 	}
-	mddev_suspend(mddev);
-	md_integrity_add_rdev(rdev, mddev);
-	mddev_resume(mddev);
 	if (mddev->queue && blk_queue_discard(bdev_get_queue(rdev->bdev)))
 		queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, mddev->queue);
 	print_conf(conf);
@@ -2274,6 +2274,7 @@ static void handle_write_finished(struct
 	if (fail) {
 		spin_lock_irq(&conf->device_lock);
 		list_add(&r1_bio->retry_list, &conf->bio_end_io_list);
+		conf->nr_queued++;
 		spin_unlock_irq(&conf->device_lock);
 		md_wakeup_thread(conf->mddev->thread);
 	} else {
@@ -2391,8 +2392,10 @@ static void raid1d(struct md_thread *thr
 		LIST_HEAD(tmp);
 		spin_lock_irqsave(&conf->device_lock, flags);
 		if (!test_bit(MD_CHANGE_PENDING, &mddev->flags)) {
-			list_add(&tmp, &conf->bio_end_io_list);
-			list_del_init(&conf->bio_end_io_list);
+			while (!list_empty(&conf->bio_end_io_list)) {
+				list_move(conf->bio_end_io_list.prev, &tmp);
+				conf->nr_queued--;
+			}
 		}
 		spin_unlock_irqrestore(&conf->device_lock, flags);
 		while (!list_empty(&tmp)) {
--- zfcpdump-kernel-4.4.orig/drivers/md/raid10.c
+++ zfcpdump-kernel-4.4/drivers/md/raid10.c
@@ -1698,6 +1698,9 @@ static int raid10_add_disk(struct mddev
 	if (rdev->saved_raid_disk < 0 && !_enough(conf, 1, -1))
 		return -EINVAL;
 
+	if (md_integrity_add_rdev(rdev, mddev))
+		return -ENXIO;
+
 	if (rdev->raid_disk >= 0)
 		first = last = rdev->raid_disk;
 
@@ -1739,9 +1742,6 @@ static int raid10_add_disk(struct mddev
 		rcu_assign_pointer(p->rdev, rdev);
 		break;
 	}
-	mddev_suspend(mddev);
-	md_integrity_add_rdev(rdev, mddev);
-	mddev_resume(mddev);
 	if (mddev->queue && blk_queue_discard(bdev_get_queue(rdev->bdev)))
 		queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, mddev->queue);
 
@@ -2664,6 +2664,7 @@ static void handle_write_completed(struc
 		if (fail) {
 			spin_lock_irq(&conf->device_lock);
 			list_add(&r10_bio->retry_list, &conf->bio_end_io_list);
+			conf->nr_queued++;
 			spin_unlock_irq(&conf->device_lock);
 			md_wakeup_thread(conf->mddev->thread);
 		} else {
@@ -2691,8 +2692,10 @@ static void raid10d(struct md_thread *th
 		LIST_HEAD(tmp);
 		spin_lock_irqsave(&conf->device_lock, flags);
 		if (!test_bit(MD_CHANGE_PENDING, &mddev->flags)) {
-			list_add(&tmp, &conf->bio_end_io_list);
-			list_del_init(&conf->bio_end_io_list);
+			while (!list_empty(&conf->bio_end_io_list)) {
+				list_move(conf->bio_end_io_list.prev, &tmp);
+				conf->nr_queued--;
+			}
 		}
 		spin_unlock_irqrestore(&conf->device_lock, flags);
 		while (!list_empty(&tmp)) {
--- zfcpdump-kernel-4.4.orig/drivers/md/raid5.c
+++ zfcpdump-kernel-4.4/drivers/md/raid5.c
@@ -340,8 +340,7 @@ static void release_inactive_stripe_list
 					 int hash)
 {
 	int size;
-	unsigned long do_wakeup = 0;
-	int i = 0;
+	bool do_wakeup = false;
 	unsigned long flags;
 
 	if (hash == NR_STRIPE_HASH_LOCKS) {
@@ -362,19 +361,15 @@ static void release_inactive_stripe_list
 			    !list_empty(list))
 				atomic_dec(&conf->empty_inactive_list_nr);
 			list_splice_tail_init(list, conf->inactive_list + hash);
-			do_wakeup |= 1 << hash;
+			do_wakeup = true;
 			spin_unlock_irqrestore(conf->hash_locks + hash, flags);
 		}
 		size--;
 		hash--;
 	}
 
-	for (i = 0; i < NR_STRIPE_HASH_LOCKS; i++) {
-		if (do_wakeup & (1 << i))
-			wake_up(&conf->wait_for_stripe[i]);
-	}
-
 	if (do_wakeup) {
+		wake_up(&conf->wait_for_stripe);
 		if (atomic_read(&conf->active_stripes) == 0)
 			wake_up(&conf->wait_for_quiescent);
 		if (conf->retry_read_aligned)
@@ -687,15 +682,14 @@ raid5_get_active_stripe(struct r5conf *c
 			if (!sh) {
 				set_bit(R5_INACTIVE_BLOCKED,
 					&conf->cache_state);
-				wait_event_exclusive_cmd(
-					conf->wait_for_stripe[hash],
+				wait_event_lock_irq(
+					conf->wait_for_stripe,
 					!list_empty(conf->inactive_list + hash) &&
 					(atomic_read(&conf->active_stripes)
 					 < (conf->max_nr_stripes * 3 / 4)
 					 || !test_bit(R5_INACTIVE_BLOCKED,
 						      &conf->cache_state)),
-					spin_unlock_irq(conf->hash_locks + hash),
-					spin_lock_irq(conf->hash_locks + hash));
+					*(conf->hash_locks + hash));
 				clear_bit(R5_INACTIVE_BLOCKED,
 					  &conf->cache_state);
 			} else {
@@ -720,9 +714,6 @@ raid5_get_active_stripe(struct r5conf *c
 		}
 	} while (sh == NULL);
 
-	if (!list_empty(conf->inactive_list + hash))
-		wake_up(&conf->wait_for_stripe[hash]);
-
 	spin_unlock_irq(conf->hash_locks + hash);
 	return sh;
 }
@@ -2091,6 +2082,14 @@ static int resize_chunks(struct r5conf *
 	unsigned long cpu;
 	int err = 0;
 
+	/*
+	 * Never shrink. And mddev_suspend() could deadlock if this is called
+	 * from raid5d. In that case, scribble_disks and scribble_sectors
+	 * should equal to new_disks and new_sectors
+	 */
+	if (conf->scribble_disks >= new_disks &&
+	    conf->scribble_sectors >= new_sectors)
+		return 0;
 	mddev_suspend(conf->mddev);
 	get_online_cpus();
 	for_each_present_cpu(cpu) {
@@ -2112,6 +2111,10 @@ static int resize_chunks(struct r5conf *
 	}
 	put_online_cpus();
 	mddev_resume(conf->mddev);
+	if (!err) {
+		conf->scribble_disks = new_disks;
+		conf->scribble_sectors = new_sectors;
+	}
 	return err;
 }
 
@@ -2192,7 +2195,7 @@ static int resize_stripes(struct r5conf
 	cnt = 0;
 	list_for_each_entry(nsh, &newstripes, lru) {
 		lock_device_hash_lock(conf, hash);
-		wait_event_exclusive_cmd(conf->wait_for_stripe[hash],
+		wait_event_cmd(conf->wait_for_stripe,
 				    !list_empty(conf->inactive_list + hash),
 				    unlock_device_hash_lock(conf, hash),
 				    lock_device_hash_lock(conf, hash));
@@ -4238,7 +4241,6 @@ static void break_stripe_batch_list(stru
 		WARN_ON_ONCE(sh->state & ((1 << STRIPE_ACTIVE) |
 					  (1 << STRIPE_SYNCING) |
 					  (1 << STRIPE_REPLACED) |
-					  (1 << STRIPE_PREREAD_ACTIVE) |
 					  (1 << STRIPE_DELAYED) |
 					  (1 << STRIPE_BIT_DELAY) |
 					  (1 << STRIPE_FULL_WRITE) |
@@ -4253,6 +4255,7 @@ static void break_stripe_batch_list(stru
 					      (1 << STRIPE_REPLACED)));
 
 		set_mask_bits(&sh->state, ~(STRIPE_EXPAND_SYNC_FLAGS |
+					    (1 << STRIPE_PREREAD_ACTIVE) |
 					    (1 << STRIPE_DEGRADED)),
 			      head_sh->state & (1 << STRIPE_INSYNC));
 
@@ -6414,6 +6417,12 @@ static int raid5_alloc_percpu(struct r5c
 	}
 	put_online_cpus();
 
+	if (!err) {
+		conf->scribble_disks = max(conf->raid_disks,
+			conf->previous_raid_disks);
+		conf->scribble_sectors = max(conf->chunk_sectors,
+			conf->prev_chunk_sectors);
+	}
 	return err;
 }
 
@@ -6504,9 +6513,7 @@ static struct r5conf *setup_conf(struct
 	seqcount_init(&conf->gen_lock);
 	mutex_init(&conf->cache_size_mutex);
 	init_waitqueue_head(&conf->wait_for_quiescent);
-	for (i = 0; i < NR_STRIPE_HASH_LOCKS; i++) {
-		init_waitqueue_head(&conf->wait_for_stripe[i]);
-	}
+	init_waitqueue_head(&conf->wait_for_stripe);
 	init_waitqueue_head(&conf->wait_for_overlap);
 	INIT_LIST_HEAD(&conf->handle_list);
 	INIT_LIST_HEAD(&conf->hold_list);
@@ -7015,8 +7022,8 @@ static int run(struct mddev *mddev)
 		}
 
 		if (discard_supported &&
-		   mddev->queue->limits.max_discard_sectors >= stripe &&
-		   mddev->queue->limits.discard_granularity >= stripe)
+		    mddev->queue->limits.max_discard_sectors >= (stripe >> 9) &&
+		    mddev->queue->limits.discard_granularity >= stripe)
 			queue_flag_set_unlocked(QUEUE_FLAG_DISCARD,
 						mddev->queue);
 		else
--- zfcpdump-kernel-4.4.orig/drivers/md/raid5.h
+++ zfcpdump-kernel-4.4/drivers/md/raid5.h
@@ -510,6 +510,8 @@ struct r5conf {
 					      * conversions
 					      */
 	} __percpu *percpu;
+	int scribble_disks;
+	int scribble_sectors;
 #ifdef CONFIG_HOTPLUG_CPU
 	struct notifier_block	cpu_notify;
 #endif
@@ -522,7 +524,7 @@ struct r5conf {
 	atomic_t		empty_inactive_list_nr;
 	struct llist_head	released_stripes;
 	wait_queue_head_t	wait_for_quiescent;
-	wait_queue_head_t	wait_for_stripe[NR_STRIPE_HASH_LOCKS];
+	wait_queue_head_t	wait_for_stripe;
 	wait_queue_head_t	wait_for_overlap;
 	unsigned long		cache_state;
 #define R5_INACTIVE_BLOCKED	1	/* release of inactive stripes blocked,
--- zfcpdump-kernel-4.4.orig/drivers/media/dvb-core/dvb_frontend.c
+++ zfcpdump-kernel-4.4/drivers/media/dvb-core/dvb_frontend.c
@@ -2313,9 +2313,9 @@ static int dvb_frontend_ioctl_legacy(str
 		dev_dbg(fe->dvb->device, "%s: current delivery system on cache: %d, V3 type: %d\n",
 				 __func__, c->delivery_system, fe->ops.info.type);
 
-		/* Force the CAN_INVERSION_AUTO bit on. If the frontend doesn't
-		 * do it, it is done for it. */
-		info->caps |= FE_CAN_INVERSION_AUTO;
+		/* Set CAN_INVERSION_AUTO bit on in other than oneshot mode */
+		if (!(fepriv->tune_mode_flags & FE_TUNE_MODE_ONESHOT))
+			info->caps |= FE_CAN_INVERSION_AUTO;
 		err = 0;
 		break;
 	}
--- zfcpdump-kernel-4.4.orig/drivers/media/dvb-core/dvb_ringbuffer.c
+++ zfcpdump-kernel-4.4/drivers/media/dvb-core/dvb_ringbuffer.c
@@ -55,7 +55,13 @@ void dvb_ringbuffer_init(struct dvb_ring
 
 int dvb_ringbuffer_empty(struct dvb_ringbuffer *rbuf)
 {
-	return (rbuf->pread==rbuf->pwrite);
+	/* smp_load_acquire() to load write pointer on reader side
+	 * this pairs with smp_store_release() in dvb_ringbuffer_write(),
+	 * dvb_ringbuffer_write_user(), or dvb_ringbuffer_reset()
+	 *
+	 * for memory barriers also see Documentation/circular-buffers.txt
+	 */
+	return (rbuf->pread == smp_load_acquire(&rbuf->pwrite));
 }
 
 
@@ -64,7 +70,12 @@ ssize_t dvb_ringbuffer_free(struct dvb_r
 {
 	ssize_t free;
 
-	free = rbuf->pread - rbuf->pwrite;
+	/* ACCESS_ONCE() to load read pointer on writer side
+	 * this pairs with smp_store_release() in dvb_ringbuffer_read(),
+	 * dvb_ringbuffer_read_user(), dvb_ringbuffer_flush(),
+	 * or dvb_ringbuffer_reset()
+	 */
+	free = ACCESS_ONCE(rbuf->pread) - rbuf->pwrite;
 	if (free <= 0)
 		free += rbuf->size;
 	return free-1;
@@ -76,7 +87,11 @@ ssize_t dvb_ringbuffer_avail(struct dvb_
 {
 	ssize_t avail;
 
-	avail = rbuf->pwrite - rbuf->pread;
+	/* smp_load_acquire() to load write pointer on reader side
+	 * this pairs with smp_store_release() in dvb_ringbuffer_write(),
+	 * dvb_ringbuffer_write_user(), or dvb_ringbuffer_reset()
+	 */
+	avail = smp_load_acquire(&rbuf->pwrite) - rbuf->pread;
 	if (avail < 0)
 		avail += rbuf->size;
 	return avail;
@@ -86,14 +101,25 @@ ssize_t dvb_ringbuffer_avail(struct dvb_
 
 void dvb_ringbuffer_flush(struct dvb_ringbuffer *rbuf)
 {
-	rbuf->pread = rbuf->pwrite;
+	/* dvb_ringbuffer_flush() counts as read operation
+	 * smp_load_acquire() to load write pointer
+	 * smp_store_release() to update read pointer, this ensures that the
+	 * correct pointer is visible for subsequent dvb_ringbuffer_free()
+	 * calls on other cpu cores
+	 */
+	smp_store_release(&rbuf->pread, smp_load_acquire(&rbuf->pwrite));
 	rbuf->error = 0;
 }
 EXPORT_SYMBOL(dvb_ringbuffer_flush);
 
 void dvb_ringbuffer_reset(struct dvb_ringbuffer *rbuf)
 {
-	rbuf->pread = rbuf->pwrite = 0;
+	/* dvb_ringbuffer_reset() counts as read and write operation
+	 * smp_store_release() to update read pointer
+	 */
+	smp_store_release(&rbuf->pread, 0);
+	/* smp_store_release() to update write pointer */
+	smp_store_release(&rbuf->pwrite, 0);
 	rbuf->error = 0;
 }
 
@@ -119,12 +145,17 @@ ssize_t dvb_ringbuffer_read_user(struct
 			return -EFAULT;
 		buf += split;
 		todo -= split;
-		rbuf->pread = 0;
+		/* smp_store_release() for read pointer update to ensure
+		 * that buf is not overwritten until read is complete,
+		 * this pairs with ACCESS_ONCE() in dvb_ringbuffer_free()
+		 */
+		smp_store_release(&rbuf->pread, 0);
 	}
 	if (copy_to_user(buf, rbuf->data+rbuf->pread, todo))
 		return -EFAULT;
 
-	rbuf->pread = (rbuf->pread + todo) % rbuf->size;
+	/* smp_store_release() to update read pointer, see above */
+	smp_store_release(&rbuf->pread, (rbuf->pread + todo) % rbuf->size);
 
 	return len;
 }
@@ -139,11 +170,16 @@ void dvb_ringbuffer_read(struct dvb_ring
 		memcpy(buf, rbuf->data+rbuf->pread, split);
 		buf += split;
 		todo -= split;
-		rbuf->pread = 0;
+		/* smp_store_release() for read pointer update to ensure
+		 * that buf is not overwritten until read is complete,
+		 * this pairs with ACCESS_ONCE() in dvb_ringbuffer_free()
+		 */
+		smp_store_release(&rbuf->pread, 0);
 	}
 	memcpy(buf, rbuf->data+rbuf->pread, todo);
 
-	rbuf->pread = (rbuf->pread + todo) % rbuf->size;
+	/* smp_store_release() to update read pointer, see above */
+	smp_store_release(&rbuf->pread, (rbuf->pread + todo) % rbuf->size);
 }
 
 
@@ -158,10 +194,16 @@ ssize_t dvb_ringbuffer_write(struct dvb_
 		memcpy(rbuf->data+rbuf->pwrite, buf, split);
 		buf += split;
 		todo -= split;
-		rbuf->pwrite = 0;
+		/* smp_store_release() for write pointer update to ensure that
+		 * written data is visible on other cpu cores before the pointer
+		 * update, this pairs with smp_load_acquire() in
+		 * dvb_ringbuffer_empty() or dvb_ringbuffer_avail()
+		 */
+		smp_store_release(&rbuf->pwrite, 0);
 	}
 	memcpy(rbuf->data+rbuf->pwrite, buf, todo);
-	rbuf->pwrite = (rbuf->pwrite + todo) % rbuf->size;
+	/* smp_store_release() for write pointer update, see above */
+	smp_store_release(&rbuf->pwrite, (rbuf->pwrite + todo) % rbuf->size);
 
 	return len;
 }
@@ -181,12 +223,18 @@ ssize_t dvb_ringbuffer_write_user(struct
 			return len - todo;
 		buf += split;
 		todo -= split;
-		rbuf->pwrite = 0;
+		/* smp_store_release() for write pointer update to ensure that
+		 * written data is visible on other cpu cores before the pointer
+		 * update, this pairs with smp_load_acquire() in
+		 * dvb_ringbuffer_empty() or dvb_ringbuffer_avail()
+		 */
+		smp_store_release(&rbuf->pwrite, 0);
 	}
 	status = copy_from_user(rbuf->data+rbuf->pwrite, buf, todo);
 	if (status)
 		return len - todo;
-	rbuf->pwrite = (rbuf->pwrite + todo) % rbuf->size;
+	/* smp_store_release() for write pointer update, see above */
+	smp_store_release(&rbuf->pwrite, (rbuf->pwrite + todo) % rbuf->size);
 
 	return len;
 }
--- zfcpdump-kernel-4.4.orig/drivers/media/dvb-frontends/Kconfig
+++ zfcpdump-kernel-4.4/drivers/media/dvb-frontends/Kconfig
@@ -264,7 +264,7 @@ config DVB_MB86A16
 config DVB_TDA10071
 	tristate "NXP TDA10071"
 	depends on DVB_CORE && I2C
-	select REGMAP
+	select REGMAP_I2C
 	default m if !MEDIA_SUBDRV_AUTOSELECT
 	help
 	  Say Y when you want to support this frontend.
--- zfcpdump-kernel-4.4.orig/drivers/media/dvb-frontends/tda1004x.c
+++ zfcpdump-kernel-4.4/drivers/media/dvb-frontends/tda1004x.c
@@ -903,9 +903,18 @@ static int tda1004x_get_fe(struct dvb_fr
 {
 	struct dtv_frontend_properties *fe_params = &fe->dtv_property_cache;
 	struct tda1004x_state* state = fe->demodulator_priv;
+	int status;
 
 	dprintk("%s\n", __func__);
 
+	status = tda1004x_read_byte(state, TDA1004X_STATUS_CD);
+	if (status == -1)
+		return -EIO;
+
+	/* Only update the properties cache if device is locked */
+	if (!(status & 8))
+		return 0;
+
 	// inversion status
 	fe_params->inversion = INVERSION_OFF;
 	if (tda1004x_read_byte(state, TDA1004X_CONFC1) & 0x20)
--- zfcpdump-kernel-4.4.orig/drivers/media/i2c/adv7511.c
+++ zfcpdump-kernel-4.4/drivers/media/i2c/adv7511.c
@@ -1161,12 +1161,23 @@ static void adv7511_dbg_dump_edid(int lv
 	}
 }
 
+static void adv7511_notify_no_edid(struct v4l2_subdev *sd)
+{
+	struct adv7511_state *state = get_adv7511_state(sd);
+	struct adv7511_edid_detect ed;
+
+	/* We failed to read the EDID, so send an event for this. */
+	ed.present = false;
+	ed.segment = adv7511_rd(sd, 0xc4);
+	v4l2_subdev_notify(sd, ADV7511_EDID_DETECT, (void *)&ed);
+	v4l2_ctrl_s_ctrl(state->have_edid0_ctrl, 0x0);
+}
+
 static void adv7511_edid_handler(struct work_struct *work)
 {
 	struct delayed_work *dwork = to_delayed_work(work);
 	struct adv7511_state *state = container_of(dwork, struct adv7511_state, edid_handler);
 	struct v4l2_subdev *sd = &state->sd;
-	struct adv7511_edid_detect ed;
 
 	v4l2_dbg(1, debug, sd, "%s:\n", __func__);
 
@@ -1191,9 +1202,7 @@ static void adv7511_edid_handler(struct
 	}
 
 	/* We failed to read the EDID, so send an event for this. */
-	ed.present = false;
-	ed.segment = adv7511_rd(sd, 0xc4);
-	v4l2_subdev_notify(sd, ADV7511_EDID_DETECT, (void *)&ed);
+	adv7511_notify_no_edid(sd);
 	v4l2_dbg(1, debug, sd, "%s: no edid found\n", __func__);
 }
 
@@ -1264,7 +1273,6 @@ static void adv7511_check_monitor_presen
 	/* update read only ctrls */
 	v4l2_ctrl_s_ctrl(state->hotplug_ctrl, adv7511_have_hotplug(sd) ? 0x1 : 0x0);
 	v4l2_ctrl_s_ctrl(state->rx_sense_ctrl, adv7511_have_rx_sense(sd) ? 0x1 : 0x0);
-	v4l2_ctrl_s_ctrl(state->have_edid0_ctrl, state->edid.segments ? 0x1 : 0x0);
 
 	if ((status & MASK_ADV7511_HPD_DETECT) && ((status & MASK_ADV7511_MSEN_DETECT) || state->edid.segments)) {
 		v4l2_dbg(1, debug, sd, "%s: hotplug and (rx-sense or edid)\n", __func__);
@@ -1294,6 +1302,7 @@ static void adv7511_check_monitor_presen
 		}
 		adv7511_s_power(sd, false);
 		memset(&state->edid, 0, sizeof(struct adv7511_state_edid));
+		adv7511_notify_no_edid(sd);
 	}
 }
 
@@ -1370,6 +1379,7 @@ static bool adv7511_check_edid_status(st
 		}
 		/* one more segment read ok */
 		state->edid.segments = segment + 1;
+		v4l2_ctrl_s_ctrl(state->have_edid0_ctrl, 0x1);
 		if (((state->edid.data[0x7e] >> 1) + 1) > state->edid.segments) {
 			/* Request next EDID segment */
 			v4l2_dbg(1, debug, sd, "%s: request segment %d\n", __func__, state->edid.segments);
@@ -1389,7 +1399,6 @@ static bool adv7511_check_edid_status(st
 		ed.present = true;
 		ed.segment = 0;
 		state->edid_detect_counter++;
-		v4l2_ctrl_s_ctrl(state->have_edid0_ctrl, state->edid.segments ? 0x1 : 0x0);
 		v4l2_subdev_notify(sd, ADV7511_EDID_DETECT, (void *)&ed);
 		return ed.present;
 	}
--- zfcpdump-kernel-4.4.orig/drivers/media/i2c/adv7604.c
+++ zfcpdump-kernel-4.4/drivers/media/i2c/adv7604.c
@@ -1960,10 +1960,9 @@ static int adv76xx_isr(struct v4l2_subde
 	}
 
 	/* tx 5v detect */
-	tx_5v = io_read(sd, 0x70) & info->cable_det_mask;
+	tx_5v = irq_reg_0x70 & info->cable_det_mask;
 	if (tx_5v) {
 		v4l2_dbg(1, debug, sd, "%s: tx_5v: 0x%x\n", __func__, tx_5v);
-		io_write(sd, 0x71, tx_5v);
 		adv76xx_s_detect_tx_5v_ctrl(sd);
 		if (handled)
 			*handled = true;
--- zfcpdump-kernel-4.4.orig/drivers/media/i2c/ir-kbd-i2c.c
+++ zfcpdump-kernel-4.4/drivers/media/i2c/ir-kbd-i2c.c
@@ -478,7 +478,6 @@ static const struct i2c_device_id ir_kbd
 	{ "ir_rx_z8f0811_hdpvr", 0 },
 	{ }
 };
-MODULE_DEVICE_TABLE(i2c, ir_kbd_id);
 
 static struct i2c_driver ir_kbd_driver = {
 	.driver = {
--- zfcpdump-kernel-4.4.orig/drivers/media/pci/bt8xx/bttv-driver.c
+++ zfcpdump-kernel-4.4/drivers/media/pci/bt8xx/bttv-driver.c
@@ -2334,6 +2334,19 @@ static int bttv_g_fmt_vid_overlay(struct
 	return 0;
 }
 
+static void bttv_get_width_mask_vid_cap(const struct bttv_format *fmt,
+					unsigned int *width_mask,
+					unsigned int *width_bias)
+{
+	if (fmt->flags & FORMAT_FLAGS_PLANAR) {
+		*width_mask = ~15; /* width must be a multiple of 16 pixels */
+		*width_bias = 8;   /* nearest */
+	} else {
+		*width_mask = ~3; /* width must be a multiple of 4 pixels */
+		*width_bias = 2;  /* nearest */
+	}
+}
+
 static int bttv_try_fmt_vid_cap(struct file *file, void *priv,
 						struct v4l2_format *f)
 {
@@ -2343,6 +2356,7 @@ static int bttv_try_fmt_vid_cap(struct f
 	enum v4l2_field field;
 	__s32 width, height;
 	__s32 height2;
+	unsigned int width_mask, width_bias;
 	int rc;
 
 	fmt = format_by_fourcc(f->fmt.pix.pixelformat);
@@ -2375,9 +2389,9 @@ static int bttv_try_fmt_vid_cap(struct f
 	width = f->fmt.pix.width;
 	height = f->fmt.pix.height;
 
+	bttv_get_width_mask_vid_cap(fmt, &width_mask, &width_bias);
 	rc = limit_scaled_size_lock(fh, &width, &height, field,
-			       /* width_mask: 4 pixels */ ~3,
-			       /* width_bias: nearest */ 2,
+			       width_mask, width_bias,
 			       /* adjust_size */ 1,
 			       /* adjust_crop */ 0);
 	if (0 != rc)
@@ -2410,6 +2424,7 @@ static int bttv_s_fmt_vid_cap(struct fil
 	struct bttv_fh *fh = priv;
 	struct bttv *btv = fh->btv;
 	__s32 width, height;
+	unsigned int width_mask, width_bias;
 	enum v4l2_field field;
 
 	retval = bttv_switch_type(fh, f->type);
@@ -2424,9 +2439,10 @@ static int bttv_s_fmt_vid_cap(struct fil
 	height = f->fmt.pix.height;
 	field = f->fmt.pix.field;
 
+	fmt = format_by_fourcc(f->fmt.pix.pixelformat);
+	bttv_get_width_mask_vid_cap(fmt, &width_mask, &width_bias);
 	retval = limit_scaled_size_lock(fh, &width, &height, f->fmt.pix.field,
-			       /* width_mask: 4 pixels */ ~3,
-			       /* width_bias: nearest */ 2,
+			       width_mask, width_bias,
 			       /* adjust_size */ 1,
 			       /* adjust_crop */ 1);
 	if (0 != retval)
@@ -2434,8 +2450,6 @@ static int bttv_s_fmt_vid_cap(struct fil
 
 	f->fmt.pix.field = field;
 
-	fmt = format_by_fourcc(f->fmt.pix.pixelformat);
-
 	/* update our state informations */
 	fh->fmt              = fmt;
 	fh->cap.field        = f->fmt.pix.field;
--- zfcpdump-kernel-4.4.orig/drivers/media/pci/saa7134/saa7134-alsa.c
+++ zfcpdump-kernel-4.4/drivers/media/pci/saa7134/saa7134-alsa.c
@@ -1211,6 +1211,8 @@ static int alsa_device_init(struct saa71
 
 static int alsa_device_exit(struct saa7134_dev *dev)
 {
+	if (!snd_saa7134_cards[dev->nr])
+		return 1;
 
 	snd_card_free(snd_saa7134_cards[dev->nr]);
 	snd_saa7134_cards[dev->nr] = NULL;
@@ -1260,7 +1262,8 @@ static void saa7134_alsa_exit(void)
 	int idx;
 
 	for (idx = 0; idx < SNDRV_CARDS; idx++) {
-		snd_card_free(snd_saa7134_cards[idx]);
+		if (snd_saa7134_cards[idx])
+			snd_card_free(snd_saa7134_cards[idx]);
 	}
 
 	saa7134_dmasound_init = NULL;
--- zfcpdump-kernel-4.4.orig/drivers/media/pci/saa7134/saa7134-video.c
+++ zfcpdump-kernel-4.4/drivers/media/pci/saa7134/saa7134-video.c
@@ -1219,10 +1219,13 @@ static int saa7134_g_fmt_vid_cap(struct
 	f->fmt.pix.height       = dev->height;
 	f->fmt.pix.field        = dev->field;
 	f->fmt.pix.pixelformat  = dev->fmt->fourcc;
-	f->fmt.pix.bytesperline =
-		(f->fmt.pix.width * dev->fmt->depth) >> 3;
+	if (dev->fmt->planar)
+		f->fmt.pix.bytesperline = f->fmt.pix.width;
+	else
+		f->fmt.pix.bytesperline =
+			(f->fmt.pix.width * dev->fmt->depth) / 8;
 	f->fmt.pix.sizeimage =
-		f->fmt.pix.height * f->fmt.pix.bytesperline;
+		(f->fmt.pix.height * f->fmt.pix.width * dev->fmt->depth) / 8;
 	f->fmt.pix.colorspace   = V4L2_COLORSPACE_SMPTE170M;
 	return 0;
 }
@@ -1298,10 +1301,13 @@ static int saa7134_try_fmt_vid_cap(struc
 	if (f->fmt.pix.height > maxh)
 		f->fmt.pix.height = maxh;
 	f->fmt.pix.width &= ~0x03;
-	f->fmt.pix.bytesperline =
-		(f->fmt.pix.width * fmt->depth) >> 3;
+	if (fmt->planar)
+		f->fmt.pix.bytesperline = f->fmt.pix.width;
+	else
+		f->fmt.pix.bytesperline =
+			(f->fmt.pix.width * fmt->depth) / 8;
 	f->fmt.pix.sizeimage =
-		f->fmt.pix.height * f->fmt.pix.bytesperline;
+		(f->fmt.pix.height * f->fmt.pix.width * fmt->depth) / 8;
 	f->fmt.pix.colorspace   = V4L2_COLORSPACE_SMPTE170M;
 
 	return 0;
--- zfcpdump-kernel-4.4.orig/drivers/media/platform/am437x/am437x-vpfe.c
+++ zfcpdump-kernel-4.4/drivers/media/platform/am437x/am437x-vpfe.c
@@ -1706,7 +1706,7 @@ static int vpfe_get_app_input_index(stru
 		sdinfo = &cfg->sub_devs[i];
 		client = v4l2_get_subdevdata(sdinfo->sd);
 		if (client->addr == curr_client->addr &&
-		    client->adapter->nr == client->adapter->nr) {
+		    client->adapter->nr == curr_client->adapter->nr) {
 			if (vpfe->current_input >= 1)
 				return -1;
 			*app_input_index = j + vpfe->current_input;
--- zfcpdump-kernel-4.4.orig/drivers/media/platform/coda/coda-bit.c
+++ zfcpdump-kernel-4.4/drivers/media/platform/coda/coda-bit.c
@@ -1342,7 +1342,7 @@ static void coda_finish_encode(struct co
 
 	/* Calculate bytesused field */
 	if (dst_buf->sequence == 0) {
-		vb2_set_plane_payload(&dst_buf->vb2_buf, 0,
+		vb2_set_plane_payload(&dst_buf->vb2_buf, 0, wr_ptr - start_ptr +
 					ctx->vpu_header_size[0] +
 					ctx->vpu_header_size[1] +
 					ctx->vpu_header_size[2]);
--- zfcpdump-kernel-4.4.orig/drivers/media/platform/coda/coda-common.c
+++ zfcpdump-kernel-4.4/drivers/media/platform/coda/coda-common.c
@@ -2119,14 +2119,12 @@ static int coda_probe(struct platform_de
 
 	pdev_id = of_id ? of_id->data : platform_get_device_id(pdev);
 
-	if (of_id) {
+	if (of_id)
 		dev->devtype = of_id->data;
-	} else if (pdev_id) {
+	else if (pdev_id)
 		dev->devtype = &coda_devdata[pdev_id->driver_data];
-	} else {
-		ret = -EINVAL;
-		goto err_v4l2_register;
-	}
+	else
+		return -EINVAL;
 
 	spin_lock_init(&dev->irqlock);
 	INIT_LIST_HEAD(&dev->instances);
--- zfcpdump-kernel-4.4.orig/drivers/media/platform/s5p-mfc/s5p_mfc.c
+++ zfcpdump-kernel-4.4/drivers/media/platform/s5p-mfc/s5p_mfc.c
@@ -1029,6 +1029,11 @@ static int match_child(struct device *de
 	return !strcmp(dev_name(dev), (char *)data);
 }
 
+static void s5p_mfc_memdev_release(struct device *dev)
+{
+	dma_release_declared_memory(dev);
+}
+
 static void *mfc_get_drv_data(struct platform_device *pdev);
 
 static int s5p_mfc_alloc_memdevs(struct s5p_mfc_dev *dev)
@@ -1041,6 +1046,9 @@ static int s5p_mfc_alloc_memdevs(struct
 		mfc_err("Not enough memory\n");
 		return -ENOMEM;
 	}
+
+	dev_set_name(dev->mem_dev_l, "%s", "s5p-mfc-l");
+	dev->mem_dev_l->release = s5p_mfc_memdev_release;
 	device_initialize(dev->mem_dev_l);
 	of_property_read_u32_array(dev->plat_dev->dev.of_node,
 			"samsung,mfc-l", mem_info, 2);
@@ -1058,6 +1066,9 @@ static int s5p_mfc_alloc_memdevs(struct
 		mfc_err("Not enough memory\n");
 		return -ENOMEM;
 	}
+
+	dev_set_name(dev->mem_dev_r, "%s", "s5p-mfc-r");
+	dev->mem_dev_r->release = s5p_mfc_memdev_release;
 	device_initialize(dev->mem_dev_r);
 	of_property_read_u32_array(dev->plat_dev->dev.of_node,
 			"samsung,mfc-r", mem_info, 2);
--- zfcpdump-kernel-4.4.orig/drivers/media/platform/vsp1/vsp1_sru.c
+++ zfcpdump-kernel-4.4/drivers/media/platform/vsp1/vsp1_sru.c
@@ -154,6 +154,7 @@ static int sru_s_stream(struct v4l2_subd
 	mutex_lock(sru->ctrls.lock);
 	ctrl0 |= vsp1_sru_read(sru, VI6_SRU_CTRL0)
 	       & (VI6_SRU_CTRL0_PARAM0_MASK | VI6_SRU_CTRL0_PARAM1_MASK);
+	vsp1_sru_write(sru, VI6_SRU_CTRL0, ctrl0);
 	mutex_unlock(sru->ctrls.lock);
 
 	vsp1_sru_write(sru, VI6_SRU_CTRL1, VI6_SRU_CTRL1_PARAM5);
--- zfcpdump-kernel-4.4.orig/drivers/media/rc/ir-rc5-decoder.c
+++ zfcpdump-kernel-4.4/drivers/media/rc/ir-rc5-decoder.c
@@ -29,7 +29,7 @@
 #define RC5_BIT_START		(1 * RC5_UNIT)
 #define RC5_BIT_END		(1 * RC5_UNIT)
 #define RC5X_SPACE		(4 * RC5_UNIT)
-#define RC5_TRAILER		(10 * RC5_UNIT) /* In reality, approx 100 */
+#define RC5_TRAILER		(6 * RC5_UNIT) /* In reality, approx 100 */
 
 enum rc5_state {
 	STATE_INACTIVE,
--- zfcpdump-kernel-4.4.orig/drivers/media/rc/sunxi-cir.c
+++ zfcpdump-kernel-4.4/drivers/media/rc/sunxi-cir.c
@@ -153,6 +153,8 @@ static int sunxi_ir_probe(struct platfor
 	if (!ir)
 		return -ENOMEM;
 
+	spin_lock_init(&ir->ir_lock);
+
 	if (of_device_is_compatible(dn, "allwinner,sun5i-a13-ir"))
 		ir->fifo_size = 64;
 	else
--- zfcpdump-kernel-4.4.orig/drivers/media/tuners/si2157.c
+++ zfcpdump-kernel-4.4/drivers/media/tuners/si2157.c
@@ -168,6 +168,7 @@ static int si2157_init(struct dvb_fronte
 		len = fw->data[fw->size - remaining];
 		if (len > SI2157_ARGLEN) {
 			dev_err(&client->dev, "Bad firmware length\n");
+			ret = -EINVAL;
 			goto err_release_firmware;
 		}
 		memcpy(cmd.args, &fw->data[(fw->size - remaining) + 1], len);
--- zfcpdump-kernel-4.4.orig/drivers/media/usb/airspy/airspy.c
+++ zfcpdump-kernel-4.4/drivers/media/usb/airspy/airspy.c
@@ -1073,7 +1073,7 @@ static int airspy_probe(struct usb_inter
 	if (ret) {
 		dev_err(s->dev, "Failed to register as video device (%d)\n",
 				ret);
-		goto err_unregister_v4l2_dev;
+		goto err_free_controls;
 	}
 	dev_info(s->dev, "Registered as %s\n",
 			video_device_node_name(&s->vdev));
@@ -1082,7 +1082,6 @@ static int airspy_probe(struct usb_inter
 
 err_free_controls:
 	v4l2_ctrl_handler_free(&s->hdl);
-err_unregister_v4l2_dev:
 	v4l2_device_unregister(&s->v4l2_dev);
 err_free_mem:
 	kfree(s);
--- zfcpdump-kernel-4.4.orig/drivers/media/usb/au0828/au0828-core.c
+++ zfcpdump-kernel-4.4/drivers/media/usb/au0828/au0828-core.c
@@ -159,7 +159,7 @@ static void au0828_usb_disconnect(struct
 	   Set the status so poll routines can check and avoid
 	   access after disconnect.
 	*/
-	dev->dev_state = DEV_DISCONNECTED;
+	set_bit(DEV_DISCONNECTED, &dev->dev_state);
 
 	au0828_rc_unregister(dev);
 	/* Digital TV */
--- zfcpdump-kernel-4.4.orig/drivers/media/usb/au0828/au0828-input.c
+++ zfcpdump-kernel-4.4/drivers/media/usb/au0828/au0828-input.c
@@ -130,7 +130,7 @@ static int au0828_get_key_au8522(struct
 	bool first = true;
 
 	/* do nothing if device is disconnected */
-	if (ir->dev->dev_state == DEV_DISCONNECTED)
+	if (test_bit(DEV_DISCONNECTED, &ir->dev->dev_state))
 		return 0;
 
 	/* Check IR int */
@@ -260,7 +260,7 @@ static void au0828_rc_stop(struct rc_dev
 	cancel_delayed_work_sync(&ir->work);
 
 	/* do nothing if device is disconnected */
-	if (ir->dev->dev_state != DEV_DISCONNECTED) {
+	if (!test_bit(DEV_DISCONNECTED, &ir->dev->dev_state)) {
 		/* Disable IR */
 		au8522_rc_clear(ir, 0xe0, 1 << 4);
 	}
--- zfcpdump-kernel-4.4.orig/drivers/media/usb/au0828/au0828-video.c
+++ zfcpdump-kernel-4.4/drivers/media/usb/au0828/au0828-video.c
@@ -104,14 +104,13 @@ static inline void print_err_status(stru
 
 static int check_dev(struct au0828_dev *dev)
 {
-	if (dev->dev_state & DEV_DISCONNECTED) {
+	if (test_bit(DEV_DISCONNECTED, &dev->dev_state)) {
 		pr_info("v4l2 ioctl: device not present\n");
 		return -ENODEV;
 	}
 
-	if (dev->dev_state & DEV_MISCONFIGURED) {
-		pr_info("v4l2 ioctl: device is misconfigured; "
-		       "close and open it again\n");
+	if (test_bit(DEV_MISCONFIGURED, &dev->dev_state)) {
+		pr_info("v4l2 ioctl: device is misconfigured; close and open it again\n");
 		return -EIO;
 	}
 	return 0;
@@ -519,8 +518,8 @@ static inline int au0828_isoc_copy(struc
 	if (!dev)
 		return 0;
 
-	if ((dev->dev_state & DEV_DISCONNECTED) ||
-	    (dev->dev_state & DEV_MISCONFIGURED))
+	if (test_bit(DEV_DISCONNECTED, &dev->dev_state) ||
+	    test_bit(DEV_MISCONFIGURED, &dev->dev_state))
 		return 0;
 
 	if (urb->status < 0) {
@@ -766,10 +765,10 @@ static int au0828_stream_interrupt(struc
 	int ret = 0;
 
 	dev->stream_state = STREAM_INTERRUPT;
-	if (dev->dev_state == DEV_DISCONNECTED)
+	if (test_bit(DEV_DISCONNECTED, &dev->dev_state))
 		return -ENODEV;
 	else if (ret) {
-		dev->dev_state = DEV_MISCONFIGURED;
+		set_bit(DEV_MISCONFIGURED, &dev->dev_state);
 		dprintk(1, "%s device is misconfigured!\n", __func__);
 		return ret;
 	}
@@ -958,7 +957,7 @@ static int au0828_v4l2_open(struct file
 	int ret;
 
 	dprintk(1,
-		"%s called std_set %d dev_state %d stream users %d users %d\n",
+		"%s called std_set %d dev_state %ld stream users %d users %d\n",
 		__func__, dev->std_set_in_tuner_core, dev->dev_state,
 		dev->streaming_users, dev->users);
 
@@ -977,7 +976,7 @@ static int au0828_v4l2_open(struct file
 		au0828_analog_stream_enable(dev);
 		au0828_analog_stream_reset(dev);
 		dev->stream_state = STREAM_OFF;
-		dev->dev_state |= DEV_INITIALIZED;
+		set_bit(DEV_INITIALIZED, &dev->dev_state);
 	}
 	dev->users++;
 	mutex_unlock(&dev->lock);
@@ -991,7 +990,7 @@ static int au0828_v4l2_close(struct file
 	struct video_device *vdev = video_devdata(filp);
 
 	dprintk(1,
-		"%s called std_set %d dev_state %d stream users %d users %d\n",
+		"%s called std_set %d dev_state %ld stream users %d users %d\n",
 		__func__, dev->std_set_in_tuner_core, dev->dev_state,
 		dev->streaming_users, dev->users);
 
@@ -1007,7 +1006,7 @@ static int au0828_v4l2_close(struct file
 		del_timer_sync(&dev->vbi_timeout);
 	}
 
-	if (dev->dev_state == DEV_DISCONNECTED)
+	if (test_bit(DEV_DISCONNECTED, &dev->dev_state))
 		goto end;
 
 	if (dev->users == 1) {
@@ -1036,7 +1035,7 @@ static void au0828_init_tuner(struct au0
 		.type = V4L2_TUNER_ANALOG_TV,
 	};
 
-	dprintk(1, "%s called std_set %d dev_state %d\n", __func__,
+	dprintk(1, "%s called std_set %d dev_state %ld\n", __func__,
 		dev->std_set_in_tuner_core, dev->dev_state);
 
 	if (dev->std_set_in_tuner_core)
@@ -1108,7 +1107,7 @@ static int vidioc_querycap(struct file *
 	struct video_device *vdev = video_devdata(file);
 	struct au0828_dev *dev = video_drvdata(file);
 
-	dprintk(1, "%s called std_set %d dev_state %d\n", __func__,
+	dprintk(1, "%s called std_set %d dev_state %ld\n", __func__,
 		dev->std_set_in_tuner_core, dev->dev_state);
 
 	strlcpy(cap->driver, "au0828", sizeof(cap->driver));
@@ -1151,7 +1150,7 @@ static int vidioc_g_fmt_vid_cap(struct f
 {
 	struct au0828_dev *dev = video_drvdata(file);
 
-	dprintk(1, "%s called std_set %d dev_state %d\n", __func__,
+	dprintk(1, "%s called std_set %d dev_state %ld\n", __func__,
 		dev->std_set_in_tuner_core, dev->dev_state);
 
 	f->fmt.pix.width = dev->width;
@@ -1170,7 +1169,7 @@ static int vidioc_try_fmt_vid_cap(struct
 {
 	struct au0828_dev *dev = video_drvdata(file);
 
-	dprintk(1, "%s called std_set %d dev_state %d\n", __func__,
+	dprintk(1, "%s called std_set %d dev_state %ld\n", __func__,
 		dev->std_set_in_tuner_core, dev->dev_state);
 
 	return au0828_set_format(dev, VIDIOC_TRY_FMT, f);
@@ -1182,7 +1181,7 @@ static int vidioc_s_fmt_vid_cap(struct f
 	struct au0828_dev *dev = video_drvdata(file);
 	int rc;
 
-	dprintk(1, "%s called std_set %d dev_state %d\n", __func__,
+	dprintk(1, "%s called std_set %d dev_state %ld\n", __func__,
 		dev->std_set_in_tuner_core, dev->dev_state);
 
 	rc = check_dev(dev);
@@ -1204,7 +1203,7 @@ static int vidioc_s_std(struct file *fil
 {
 	struct au0828_dev *dev = video_drvdata(file);
 
-	dprintk(1, "%s called std_set %d dev_state %d\n", __func__,
+	dprintk(1, "%s called std_set %d dev_state %ld\n", __func__,
 		dev->std_set_in_tuner_core, dev->dev_state);
 
 	if (norm == dev->std)
@@ -1236,7 +1235,7 @@ static int vidioc_g_std(struct file *fil
 {
 	struct au0828_dev *dev = video_drvdata(file);
 
-	dprintk(1, "%s called std_set %d dev_state %d\n", __func__,
+	dprintk(1, "%s called std_set %d dev_state %ld\n", __func__,
 		dev->std_set_in_tuner_core, dev->dev_state);
 
 	*norm = dev->std;
@@ -1259,7 +1258,7 @@ static int vidioc_enum_input(struct file
 		[AU0828_VMUX_DEBUG] = "tv debug"
 	};
 
-	dprintk(1, "%s called std_set %d dev_state %d\n", __func__,
+	dprintk(1, "%s called std_set %d dev_state %ld\n", __func__,
 		dev->std_set_in_tuner_core, dev->dev_state);
 
 	tmp = input->index;
@@ -1289,7 +1288,7 @@ static int vidioc_g_input(struct file *f
 {
 	struct au0828_dev *dev = video_drvdata(file);
 
-	dprintk(1, "%s called std_set %d dev_state %d\n", __func__,
+	dprintk(1, "%s called std_set %d dev_state %ld\n", __func__,
 		dev->std_set_in_tuner_core, dev->dev_state);
 
 	*i = dev->ctrl_input;
@@ -1300,7 +1299,7 @@ static void au0828_s_input(struct au0828
 {
 	int i;
 
-	dprintk(1, "%s called std_set %d dev_state %d\n", __func__,
+	dprintk(1, "%s called std_set %d dev_state %ld\n", __func__,
 		dev->std_set_in_tuner_core, dev->dev_state);
 
 	switch (AUVI_INPUT(index).type) {
@@ -1385,7 +1384,7 @@ static int vidioc_g_audio(struct file *f
 {
 	struct au0828_dev *dev = video_drvdata(file);
 
-	dprintk(1, "%s called std_set %d dev_state %d\n", __func__,
+	dprintk(1, "%s called std_set %d dev_state %ld\n", __func__,
 		dev->std_set_in_tuner_core, dev->dev_state);
 
 	a->index = dev->ctrl_ainput;
@@ -1405,7 +1404,7 @@ static int vidioc_s_audio(struct file *f
 	if (a->index != dev->ctrl_ainput)
 		return -EINVAL;
 
-	dprintk(1, "%s called std_set %d dev_state %d\n", __func__,
+	dprintk(1, "%s called std_set %d dev_state %ld\n", __func__,
 		dev->std_set_in_tuner_core, dev->dev_state);
 	return 0;
 }
@@ -1417,7 +1416,7 @@ static int vidioc_g_tuner(struct file *f
 	if (t->index != 0)
 		return -EINVAL;
 
-	dprintk(1, "%s called std_set %d dev_state %d\n", __func__,
+	dprintk(1, "%s called std_set %d dev_state %ld\n", __func__,
 		dev->std_set_in_tuner_core, dev->dev_state);
 
 	strcpy(t->name, "Auvitek tuner");
@@ -1437,7 +1436,7 @@ static int vidioc_s_tuner(struct file *f
 	if (t->index != 0)
 		return -EINVAL;
 
-	dprintk(1, "%s called std_set %d dev_state %d\n", __func__,
+	dprintk(1, "%s called std_set %d dev_state %ld\n", __func__,
 		dev->std_set_in_tuner_core, dev->dev_state);
 
 	au0828_init_tuner(dev);
@@ -1459,7 +1458,7 @@ static int vidioc_g_frequency(struct fil
 
 	if (freq->tuner != 0)
 		return -EINVAL;
-	dprintk(1, "%s called std_set %d dev_state %d\n", __func__,
+	dprintk(1, "%s called std_set %d dev_state %ld\n", __func__,
 		dev->std_set_in_tuner_core, dev->dev_state);
 	freq->frequency = dev->ctrl_freq;
 	return 0;
@@ -1474,7 +1473,7 @@ static int vidioc_s_frequency(struct fil
 	if (freq->tuner != 0)
 		return -EINVAL;
 
-	dprintk(1, "%s called std_set %d dev_state %d\n", __func__,
+	dprintk(1, "%s called std_set %d dev_state %ld\n", __func__,
 		dev->std_set_in_tuner_core, dev->dev_state);
 
 	au0828_init_tuner(dev);
@@ -1500,7 +1499,7 @@ static int vidioc_g_fmt_vbi_cap(struct f
 {
 	struct au0828_dev *dev = video_drvdata(file);
 
-	dprintk(1, "%s called std_set %d dev_state %d\n", __func__,
+	dprintk(1, "%s called std_set %d dev_state %ld\n", __func__,
 		dev->std_set_in_tuner_core, dev->dev_state);
 
 	format->fmt.vbi.samples_per_line = dev->vbi_width;
@@ -1526,7 +1525,7 @@ static int vidioc_cropcap(struct file *f
 	if (cc->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
 		return -EINVAL;
 
-	dprintk(1, "%s called std_set %d dev_state %d\n", __func__,
+	dprintk(1, "%s called std_set %d dev_state %ld\n", __func__,
 		dev->std_set_in_tuner_core, dev->dev_state);
 
 	cc->bounds.left = 0;
@@ -1548,7 +1547,7 @@ static int vidioc_g_register(struct file
 {
 	struct au0828_dev *dev = video_drvdata(file);
 
-	dprintk(1, "%s called std_set %d dev_state %d\n", __func__,
+	dprintk(1, "%s called std_set %d dev_state %ld\n", __func__,
 		dev->std_set_in_tuner_core, dev->dev_state);
 
 	reg->val = au0828_read(dev, reg->reg);
@@ -1561,7 +1560,7 @@ static int vidioc_s_register(struct file
 {
 	struct au0828_dev *dev = video_drvdata(file);
 
-	dprintk(1, "%s called std_set %d dev_state %d\n", __func__,
+	dprintk(1, "%s called std_set %d dev_state %ld\n", __func__,
 		dev->std_set_in_tuner_core, dev->dev_state);
 
 	return au0828_writereg(dev, reg->reg, reg->val);
--- zfcpdump-kernel-4.4.orig/drivers/media/usb/au0828/au0828.h
+++ zfcpdump-kernel-4.4/drivers/media/usb/au0828/au0828.h
@@ -21,6 +21,7 @@
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
+#include <linux/bitops.h>
 #include <linux/usb.h>
 #include <linux/i2c.h>
 #include <linux/i2c-algo-bit.h>
@@ -122,9 +123,9 @@ enum au0828_stream_state {
 
 /* device state */
 enum au0828_dev_state {
-	DEV_INITIALIZED = 0x01,
-	DEV_DISCONNECTED = 0x02,
-	DEV_MISCONFIGURED = 0x04
+	DEV_INITIALIZED = 0,
+	DEV_DISCONNECTED = 1,
+	DEV_MISCONFIGURED = 2
 };
 
 struct au0828_dev;
@@ -248,7 +249,7 @@ struct au0828_dev {
 	int input_type;
 	int std_set_in_tuner_core;
 	unsigned int ctrl_input;
-	enum au0828_dev_state dev_state;
+	long unsigned int dev_state; /* defined at enum au0828_dev_state */;
 	enum au0828_stream_state stream_state;
 	wait_queue_head_t open;
 
--- zfcpdump-kernel-4.4.orig/drivers/media/usb/em28xx/em28xx-i2c.c
+++ zfcpdump-kernel-4.4/drivers/media/usb/em28xx/em28xx-i2c.c
@@ -507,9 +507,8 @@ static int em28xx_i2c_xfer(struct i2c_ad
 	if (dev->disconnected)
 		return -ENODEV;
 
-	rc = rt_mutex_trylock(&dev->i2c_bus_lock);
-	if (rc < 0)
-		return rc;
+	if (!rt_mutex_trylock(&dev->i2c_bus_lock))
+		return -EAGAIN;
 
 	/* Switch I2C bus if needed */
 	if (bus != dev->cur_i2c_bus &&
--- zfcpdump-kernel-4.4.orig/drivers/media/usb/gspca/cpia1.c
+++ zfcpdump-kernel-4.4/drivers/media/usb/gspca/cpia1.c
@@ -1624,7 +1624,7 @@ static int sd_start(struct gspca_dev *gs
 
 static void sd_stopN(struct gspca_dev *gspca_dev)
 {
-	struct sd *sd = (struct sd *) gspca_dev;
+	struct sd *sd __maybe_unused = (struct sd *) gspca_dev;
 
 	command_pause(gspca_dev);
 
--- zfcpdump-kernel-4.4.orig/drivers/media/usb/gspca/konica.c
+++ zfcpdump-kernel-4.4/drivers/media/usb/gspca/konica.c
@@ -243,7 +243,7 @@ static int sd_start(struct gspca_dev *gs
 
 static void sd_stopN(struct gspca_dev *gspca_dev)
 {
-	struct sd *sd = (struct sd *) gspca_dev;
+	struct sd *sd __maybe_unused = (struct sd *) gspca_dev;
 
 	konica_stream_off(gspca_dev);
 #if IS_ENABLED(CONFIG_INPUT)
--- zfcpdump-kernel-4.4.orig/drivers/media/usb/gspca/ov534.c
+++ zfcpdump-kernel-4.4/drivers/media/usb/gspca/ov534.c
@@ -1491,8 +1491,13 @@ static void sd_set_streamparm(struct gsp
 	struct v4l2_fract *tpf = &cp->timeperframe;
 	struct sd *sd = (struct sd *) gspca_dev;
 
-	/* Set requested framerate */
-	sd->frame_rate = tpf->denominator / tpf->numerator;
+	if (tpf->numerator == 0 || tpf->denominator == 0)
+		/* Set default framerate */
+		sd->frame_rate = 30;
+	else
+		/* Set requested framerate */
+		sd->frame_rate = tpf->denominator / tpf->numerator;
+
 	if (gspca_dev->streaming)
 		set_frame_rate(gspca_dev);
 
--- zfcpdump-kernel-4.4.orig/drivers/media/usb/gspca/t613.c
+++ zfcpdump-kernel-4.4/drivers/media/usb/gspca/t613.c
@@ -837,7 +837,7 @@ static void sd_pkt_scan(struct gspca_dev
 			u8 *data,			/* isoc packet */
 			int len)			/* iso packet length */
 {
-	struct sd *sd = (struct sd *) gspca_dev;
+	struct sd *sd __maybe_unused = (struct sd *) gspca_dev;
 	int pkt_type;
 
 	if (data[0] == 0x5a) {
--- zfcpdump-kernel-4.4.orig/drivers/media/usb/gspca/topro.c
+++ zfcpdump-kernel-4.4/drivers/media/usb/gspca/topro.c
@@ -4802,7 +4802,11 @@ static void sd_set_streamparm(struct gsp
 	struct v4l2_fract *tpf = &cp->timeperframe;
 	int fr, i;
 
-	sd->framerate = tpf->denominator / tpf->numerator;
+	if (tpf->numerator == 0 || tpf->denominator == 0)
+		sd->framerate = 30;
+	else
+		sd->framerate = tpf->denominator / tpf->numerator;
+
 	if (gspca_dev->streaming)
 		setframerate(gspca_dev, v4l2_ctrl_g_ctrl(gspca_dev->exposure));
 
--- zfcpdump-kernel-4.4.orig/drivers/media/usb/pwc/pwc-if.c
+++ zfcpdump-kernel-4.4/drivers/media/usb/pwc/pwc-if.c
@@ -91,6 +91,7 @@ static const struct usb_device_id pwc_de
 	{ USB_DEVICE(0x0471, 0x0312) },
 	{ USB_DEVICE(0x0471, 0x0313) }, /* the 'new' 720K */
 	{ USB_DEVICE(0x0471, 0x0329) }, /* Philips SPC 900NC PC Camera */
+	{ USB_DEVICE(0x0471, 0x032C) }, /* Philips SPC 880NC PC Camera */
 	{ USB_DEVICE(0x069A, 0x0001) }, /* Askey */
 	{ USB_DEVICE(0x046D, 0x08B0) }, /* Logitech QuickCam Pro 3000 */
 	{ USB_DEVICE(0x046D, 0x08B1) }, /* Logitech QuickCam Notebook Pro */
@@ -811,6 +812,11 @@ static int usb_pwc_probe(struct usb_inte
 			name = "Philips SPC 900NC webcam";
 			type_id = 740;
 			break;
+		case 0x032C:
+			PWC_INFO("Philips SPC 880NC USB webcam detected.\n");
+			name = "Philips SPC 880NC webcam";
+			type_id = 740;
+			break;
 		default:
 			return -ENODEV;
 			break;
--- zfcpdump-kernel-4.4.orig/drivers/media/usb/usbtv/usbtv-audio.c
+++ zfcpdump-kernel-4.4/drivers/media/usb/usbtv/usbtv-audio.c
@@ -278,6 +278,9 @@ static void snd_usbtv_trigger(struct wor
 {
 	struct usbtv *chip = container_of(work, struct usbtv, snd_trigger);
 
+	if (!chip->snd)
+		return;
+
 	if (atomic_read(&chip->snd_stream))
 		usbtv_audio_start(chip);
 	else
@@ -378,6 +381,8 @@ err:
 
 void usbtv_audio_free(struct usbtv *usbtv)
 {
+	cancel_work_sync(&usbtv->snd_trigger);
+
 	if (usbtv->snd && usbtv->udev) {
 		snd_card_free(usbtv->snd);
 		usbtv->snd = NULL;
--- zfcpdump-kernel-4.4.orig/drivers/media/usb/usbvision/usbvision-video.c
+++ zfcpdump-kernel-4.4/drivers/media/usb/usbvision/usbvision-video.c
@@ -1463,9 +1463,23 @@ static int usbvision_probe(struct usb_in
 
 	if (usbvision_device_data[model].interface >= 0)
 		interface = &dev->actconfig->interface[usbvision_device_data[model].interface]->altsetting[0];
-	else
+	else if (ifnum < dev->actconfig->desc.bNumInterfaces)
 		interface = &dev->actconfig->interface[ifnum]->altsetting[0];
+	else {
+		dev_err(&intf->dev, "interface %d is invalid, max is %d\n",
+		    ifnum, dev->actconfig->desc.bNumInterfaces - 1);
+		ret = -ENODEV;
+		goto err_usb;
+	}
+
+	if (interface->desc.bNumEndpoints < 2) {
+		dev_err(&intf->dev, "interface %d has %d endpoints, but must"
+		    " have minimum 2\n", ifnum, interface->desc.bNumEndpoints);
+		ret = -ENODEV;
+		goto err_usb;
+	}
 	endpoint = &interface->endpoint[1].desc;
+
 	if (!usb_endpoint_xfer_isoc(endpoint)) {
 		dev_err(&intf->dev, "%s: interface %d. has non-ISO endpoint!\n",
 		    __func__, ifnum);
--- zfcpdump-kernel-4.4.orig/drivers/media/usb/uvc/uvc_driver.c
+++ zfcpdump-kernel-4.4/drivers/media/usb/uvc/uvc_driver.c
@@ -148,6 +148,26 @@ static struct uvc_format_desc uvc_fmts[]
 		.guid		= UVC_GUID_FORMAT_H264,
 		.fcc		= V4L2_PIX_FMT_H264,
 	},
+	{
+		.name		= "Greyscale 8 L/R (Y8I)",
+		.guid		= UVC_GUID_FORMAT_Y8I,
+		.fcc		= V4L2_PIX_FMT_Y8I,
+	},
+	{
+		.name		= "Greyscale 12 L/R (Y12I)",
+		.guid		= UVC_GUID_FORMAT_Y12I,
+		.fcc		= V4L2_PIX_FMT_Y12I,
+	},
+	{
+		.name		= "Depth data 16-bit (Z16)",
+		.guid		= UVC_GUID_FORMAT_Z16,
+		.fcc		= V4L2_PIX_FMT_Z16,
+	},
+	{
+		.name		= "Bayer 10-bit (SRGGB10P)",
+		.guid		= UVC_GUID_FORMAT_RW10,
+		.fcc		= V4L2_PIX_FMT_SRGGB10P,
+	},
 };
 
 /* ------------------------------------------------------------------------
@@ -2265,6 +2285,15 @@ static struct usb_device_id uvc_ids[] =
 	  .bInterfaceSubClass	= 1,
 	  .bInterfaceProtocol	= 0,
 	  .driver_info		= UVC_QUIRK_PROBE_DEF },
+	/* Alienware X51*/
+	{ .match_flags          = USB_DEVICE_ID_MATCH_DEVICE
+				  | USB_DEVICE_ID_MATCH_INT_INFO,
+	  .idVendor             = 0x05a9,
+	  .idProduct            = 0x2643,
+	  .bInterfaceClass      = USB_CLASS_VIDEO,
+	  .bInterfaceSubClass   = 1,
+	  .bInterfaceProtocol   = 0,
+	  .driver_info          = UVC_QUIRK_PROBE_DEF },
 	/* Apple Built-In iSight */
 	{ .match_flags		= USB_DEVICE_ID_MATCH_DEVICE
 				| USB_DEVICE_ID_MATCH_INT_INFO,
--- zfcpdump-kernel-4.4.orig/drivers/media/usb/uvc/uvc_v4l2.c
+++ zfcpdump-kernel-4.4/drivers/media/usb/uvc/uvc_v4l2.c
@@ -1388,47 +1388,44 @@ static int uvc_v4l2_put_xu_query(const s
 static long uvc_v4l2_compat_ioctl32(struct file *file,
 		     unsigned int cmd, unsigned long arg)
 {
+	struct uvc_fh *handle = file->private_data;
 	union {
 		struct uvc_xu_control_mapping xmap;
 		struct uvc_xu_control_query xqry;
 	} karg;
 	void __user *up = compat_ptr(arg);
-	mm_segment_t old_fs;
 	long ret;
 
 	switch (cmd) {
 	case UVCIOC_CTRL_MAP32:
-		cmd = UVCIOC_CTRL_MAP;
 		ret = uvc_v4l2_get_xu_mapping(&karg.xmap, up);
+		if (ret)
+			return ret;
+		ret = uvc_ioctl_ctrl_map(handle->chain, &karg.xmap);
+		if (ret)
+			return ret;
+		ret = uvc_v4l2_put_xu_mapping(&karg.xmap, up);
+		if (ret)
+			return ret;
+
 		break;
 
 	case UVCIOC_CTRL_QUERY32:
-		cmd = UVCIOC_CTRL_QUERY;
 		ret = uvc_v4l2_get_xu_query(&karg.xqry, up);
+		if (ret)
+			return ret;
+		ret = uvc_xu_ctrl_query(handle->chain, &karg.xqry);
+		if (ret)
+			return ret;
+		ret = uvc_v4l2_put_xu_query(&karg.xqry, up);
+		if (ret)
+			return ret;
 		break;
 
 	default:
 		return -ENOIOCTLCMD;
 	}
 
-	old_fs = get_fs();
-	set_fs(KERNEL_DS);
-	ret = video_ioctl2(file, cmd, (unsigned long)&karg);
-	set_fs(old_fs);
-
-	if (ret < 0)
-		return ret;
-
-	switch (cmd) {
-	case UVCIOC_CTRL_MAP:
-		ret = uvc_v4l2_put_xu_mapping(&karg.xmap, up);
-		break;
-
-	case UVCIOC_CTRL_QUERY:
-		ret = uvc_v4l2_put_xu_query(&karg.xqry, up);
-		break;
-	}
-
 	return ret;
 }
 #endif
--- zfcpdump-kernel-4.4.orig/drivers/media/usb/uvc/uvcvideo.h
+++ zfcpdump-kernel-4.4/drivers/media/usb/uvc/uvcvideo.h
@@ -119,6 +119,18 @@
 #define UVC_GUID_FORMAT_H264 \
 	{ 'H',  '2',  '6',  '4', 0x00, 0x00, 0x10, 0x00, \
 	 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
+#define UVC_GUID_FORMAT_Y8I \
+	{ 'Y',  '8',  'I',  ' ', 0x00, 0x00, 0x10, 0x00, \
+	 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
+#define UVC_GUID_FORMAT_Y12I \
+	{ 'Y',  '1',  '2',  'I', 0x00, 0x00, 0x10, 0x00, \
+	 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
+#define UVC_GUID_FORMAT_Z16 \
+	{ 'Z',  '1',  '6',  ' ', 0x00, 0x00, 0x10, 0x00, \
+	 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
+#define UVC_GUID_FORMAT_RW10 \
+	{ 'R',  'W',  '1',  '0', 0x00, 0x00, 0x10, 0x00, \
+	 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
 
 /* ------------------------------------------------------------------------
  * Driver specific constants.
--- zfcpdump-kernel-4.4.orig/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
+++ zfcpdump-kernel-4.4/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
@@ -280,7 +280,8 @@ static int put_v4l2_format32(struct v4l2
 static int put_v4l2_create32(struct v4l2_create_buffers *kp, struct v4l2_create_buffers32 __user *up)
 {
 	if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_create_buffers32)) ||
-	    copy_to_user(up, kp, offsetof(struct v4l2_create_buffers32, format)))
+	    copy_to_user(up, kp, offsetof(struct v4l2_create_buffers32, format)) ||
+	    copy_to_user(up->reserved, kp->reserved, sizeof(kp->reserved)))
 		return -EFAULT;
 	return __put_v4l2_format32(&kp->format, &up->format);
 }
@@ -415,7 +416,8 @@ static int get_v4l2_buffer32(struct v4l2
 		get_user(kp->index, &up->index) ||
 		get_user(kp->type, &up->type) ||
 		get_user(kp->flags, &up->flags) ||
-		get_user(kp->memory, &up->memory))
+		get_user(kp->memory, &up->memory) ||
+		get_user(kp->length, &up->length))
 			return -EFAULT;
 
 	if (V4L2_TYPE_IS_OUTPUT(kp->type))
@@ -427,9 +429,6 @@ static int get_v4l2_buffer32(struct v4l2
 			return -EFAULT;
 
 	if (V4L2_TYPE_IS_MULTIPLANAR(kp->type)) {
-		if (get_user(kp->length, &up->length))
-			return -EFAULT;
-
 		num_planes = kp->length;
 		if (num_planes == 0) {
 			kp->m.planes = NULL;
@@ -462,16 +461,14 @@ static int get_v4l2_buffer32(struct v4l2
 	} else {
 		switch (kp->memory) {
 		case V4L2_MEMORY_MMAP:
-			if (get_user(kp->length, &up->length) ||
-				get_user(kp->m.offset, &up->m.offset))
+			if (get_user(kp->m.offset, &up->m.offset))
 				return -EFAULT;
 			break;
 		case V4L2_MEMORY_USERPTR:
 			{
 			compat_long_t tmp;
 
-			if (get_user(kp->length, &up->length) ||
-			    get_user(tmp, &up->m.userptr))
+			if (get_user(tmp, &up->m.userptr))
 				return -EFAULT;
 
 			kp->m.userptr = (unsigned long)compat_ptr(tmp);
@@ -513,7 +510,8 @@ static int put_v4l2_buffer32(struct v4l2
 		copy_to_user(&up->timecode, &kp->timecode, sizeof(struct v4l2_timecode)) ||
 		put_user(kp->sequence, &up->sequence) ||
 		put_user(kp->reserved2, &up->reserved2) ||
-		put_user(kp->reserved, &up->reserved))
+		put_user(kp->reserved, &up->reserved) ||
+		put_user(kp->length, &up->length))
 			return -EFAULT;
 
 	if (V4L2_TYPE_IS_MULTIPLANAR(kp->type)) {
@@ -536,13 +534,11 @@ static int put_v4l2_buffer32(struct v4l2
 	} else {
 		switch (kp->memory) {
 		case V4L2_MEMORY_MMAP:
-			if (put_user(kp->length, &up->length) ||
-				put_user(kp->m.offset, &up->m.offset))
+			if (put_user(kp->m.offset, &up->m.offset))
 				return -EFAULT;
 			break;
 		case V4L2_MEMORY_USERPTR:
-			if (put_user(kp->length, &up->length) ||
-				put_user(kp->m.userptr, &up->m.userptr))
+			if (put_user(kp->m.userptr, &up->m.userptr))
 				return -EFAULT;
 			break;
 		case V4L2_MEMORY_OVERLAY:
--- zfcpdump-kernel-4.4.orig/drivers/media/v4l2-core/videobuf2-core.c
+++ zfcpdump-kernel-4.4/drivers/media/v4l2-core/videobuf2-core.c
@@ -1502,10 +1502,10 @@ static int __vb2_wait_for_done_vb(struct
  * Will sleep if required for nonblocking == false.
  */
 static int __vb2_get_done_vb(struct vb2_queue *q, struct vb2_buffer **vb,
-				int nonblocking)
+			     void *pb, int nonblocking)
 {
 	unsigned long flags;
-	int ret;
+	int ret = 0;
 
 	/*
 	 * Wait for at least one buffer to become available on the done_list.
@@ -1521,12 +1521,14 @@ static int __vb2_get_done_vb(struct vb2_
 	spin_lock_irqsave(&q->done_lock, flags);
 	*vb = list_first_entry(&q->done_list, struct vb2_buffer, done_entry);
 	/*
-	 * Only remove the buffer from done_list if v4l2_buffer can handle all
-	 * the planes.
-	 * Verifying planes is NOT necessary since it already has been checked
-	 * before the buffer is queued/prepared. So it can never fail.
+	 * Only remove the buffer from done_list if all planes can be
+	 * handled. Some cases such as V4L2 file I/O and DVB have pb
+	 * == NULL; skip the check then as there's nothing to verify.
 	 */
-	list_del(&(*vb)->done_entry);
+	if (pb)
+		ret = call_bufop(q, verify_planes_array, *vb, pb);
+	if (!ret)
+		list_del(&(*vb)->done_entry);
 	spin_unlock_irqrestore(&q->done_lock, flags);
 
 	return ret;
@@ -1604,7 +1606,7 @@ int vb2_core_dqbuf(struct vb2_queue *q,
 	struct vb2_buffer *vb = NULL;
 	int ret;
 
-	ret = __vb2_get_done_vb(q, &vb, nonblocking);
+	ret = __vb2_get_done_vb(q, &vb, pb, nonblocking);
 	if (ret < 0)
 		return ret;
 
--- zfcpdump-kernel-4.4.orig/drivers/media/v4l2-core/videobuf2-memops.c
+++ zfcpdump-kernel-4.4/drivers/media/v4l2-core/videobuf2-memops.c
@@ -49,7 +49,7 @@ struct frame_vector *vb2_create_framevec
 	vec = frame_vector_create(nr);
 	if (!vec)
 		return ERR_PTR(-ENOMEM);
-	ret = get_vaddr_frames(start, nr, write, 1, vec);
+	ret = get_vaddr_frames(start & PAGE_MASK, nr, write, true, vec);
 	if (ret < 0)
 		goto out_destroy;
 	/* We accept only complete set of PFNs */
--- zfcpdump-kernel-4.4.orig/drivers/media/v4l2-core/videobuf2-v4l2.c
+++ zfcpdump-kernel-4.4/drivers/media/v4l2-core/videobuf2-v4l2.c
@@ -822,10 +822,10 @@ unsigned int vb2_poll(struct vb2_queue *
 		return res | POLLERR;
 
 	/*
-	 * For output streams you can write as long as there are fewer buffers
-	 * queued than there are buffers available.
+	 * For output streams you can call write() as long as there are fewer
+	 * buffers queued than there are buffers available.
 	 */
-	if (q->is_output && q->queued_count < q->num_buffers)
+	if (q->is_output && q->fileio && q->queued_count < q->num_buffers)
 		return res | POLLOUT | POLLWRNORM;
 
 	if (list_empty(&q->done_list)) {
--- zfcpdump-kernel-4.4.orig/drivers/memory/omap-gpmc.c
+++ zfcpdump-kernel-4.4/drivers/memory/omap-gpmc.c
@@ -394,7 +394,7 @@ static void gpmc_cs_bool_timings(int cs,
 	gpmc_cs_modify_reg(cs, GPMC_CS_CONFIG4,
 			   GPMC_CONFIG4_OEEXTRADELAY, p->oe_extra_delay);
 	gpmc_cs_modify_reg(cs, GPMC_CS_CONFIG4,
-			   GPMC_CONFIG4_OEEXTRADELAY, p->we_extra_delay);
+			   GPMC_CONFIG4_WEEXTRADELAY, p->we_extra_delay);
 	gpmc_cs_modify_reg(cs, GPMC_CS_CONFIG6,
 			   GPMC_CONFIG6_CYCLE2CYCLESAMECSEN,
 			   p->cycle2cyclesamecsen);
--- zfcpdump-kernel-4.4.orig/drivers/memstick/host/rtsx_usb_ms.c
+++ zfcpdump-kernel-4.4/drivers/memstick/host/rtsx_usb_ms.c
@@ -706,7 +706,8 @@ poll_again:
 		if (host->eject)
 			break;
 
-		msleep(1000);
+		if (msleep_interruptible(1000))
+			flush_signals(current);
 	}
 
 	complete(&host->detect_ms_exit);
--- zfcpdump-kernel-4.4.orig/drivers/mfd/intel-lpss-acpi.c
+++ zfcpdump-kernel-4.4/drivers/mfd/intel-lpss-acpi.c
@@ -18,6 +18,7 @@
 #include <linux/pm.h>
 #include <linux/pm_runtime.h>
 #include <linux/platform_device.h>
+#include <linux/property.h>
 
 #include "intel-lpss.h"
 
@@ -25,18 +26,44 @@ static const struct intel_lpss_platform_
 	.clk_rate = 120000000,
 };
 
+static struct property_entry spt_i2c_properties[] = {
+	PROPERTY_ENTRY_U32("i2c-sda-hold-time-ns", 230),
+	{ },
+};
+
+static struct property_set spt_i2c_pset = {
+	.properties = spt_i2c_properties,
+};
+
+static const struct intel_lpss_platform_info spt_i2c_info = {
+	.clk_rate = 120000000,
+	.pset = &spt_i2c_pset,
+};
+
 static const struct intel_lpss_platform_info bxt_info = {
 	.clk_rate = 100000000,
 };
 
+static struct property_entry bxt_i2c_properties[] = {
+	PROPERTY_ENTRY_U32("i2c-sda-hold-time-ns", 42),
+	PROPERTY_ENTRY_U32("i2c-sda-falling-time-ns", 171),
+	PROPERTY_ENTRY_U32("i2c-scl-falling-time-ns", 208),
+	{ },
+};
+
+static struct property_set bxt_i2c_pset = {
+	.properties = bxt_i2c_properties,
+};
+
 static const struct intel_lpss_platform_info bxt_i2c_info = {
 	.clk_rate = 133000000,
+	.pset = &bxt_i2c_pset,
 };
 
 static const struct acpi_device_id intel_lpss_acpi_ids[] = {
 	/* SPT */
-	{ "INT3446", (kernel_ulong_t)&spt_info },
-	{ "INT3447", (kernel_ulong_t)&spt_info },
+	{ "INT3446", (kernel_ulong_t)&spt_i2c_info },
+	{ "INT3447", (kernel_ulong_t)&spt_i2c_info },
 	/* BXT */
 	{ "80860AAC", (kernel_ulong_t)&bxt_i2c_info },
 	{ "80860ABC", (kernel_ulong_t)&bxt_info },
--- zfcpdump-kernel-4.4.orig/drivers/mfd/intel-lpss-pci.c
+++ zfcpdump-kernel-4.4/drivers/mfd/intel-lpss-pci.c
@@ -17,6 +17,7 @@
 #include <linux/pci.h>
 #include <linux/pm.h>
 #include <linux/pm_runtime.h>
+#include <linux/property.h>
 
 #include "intel-lpss.h"
 
@@ -65,9 +66,35 @@ static const struct intel_lpss_platform_
 	.clk_rate = 120000000,
 };
 
+static struct property_entry spt_i2c_properties[] = {
+	PROPERTY_ENTRY_U32("i2c-sda-hold-time-ns", 230),
+	{ },
+};
+
+static struct property_set spt_i2c_pset = {
+	.properties = spt_i2c_properties,
+};
+
+static const struct intel_lpss_platform_info spt_i2c_info = {
+	.clk_rate = 120000000,
+	.pset = &spt_i2c_pset,
+};
+
+static struct property_entry uart_properties[] = {
+	PROPERTY_ENTRY_U32("reg-io-width", 4),
+	PROPERTY_ENTRY_U32("reg-shift", 2),
+	PROPERTY_ENTRY_BOOL("snps,uart-16550-compatible"),
+	{ },
+};
+
+static struct property_set uart_pset = {
+	.properties = uart_properties,
+};
+
 static const struct intel_lpss_platform_info spt_uart_info = {
 	.clk_rate = 120000000,
 	.clk_con_id = "baudclk",
+	.pset = &uart_pset,
 };
 
 static const struct intel_lpss_platform_info bxt_info = {
@@ -77,10 +104,36 @@ static const struct intel_lpss_platform_
 static const struct intel_lpss_platform_info bxt_uart_info = {
 	.clk_rate = 100000000,
 	.clk_con_id = "baudclk",
+	.pset = &uart_pset,
+};
+
+static struct property_entry bxt_i2c_properties[] = {
+	PROPERTY_ENTRY_U32("i2c-sda-hold-time-ns", 42),
+	PROPERTY_ENTRY_U32("i2c-sda-falling-time-ns", 171),
+	PROPERTY_ENTRY_U32("i2c-scl-falling-time-ns", 208),
+	{ },
+};
+
+static struct property_set bxt_i2c_pset = {
+	.properties = bxt_i2c_properties,
 };
 
 static const struct intel_lpss_platform_info bxt_i2c_info = {
 	.clk_rate = 133000000,
+	.pset = &bxt_i2c_pset,
+};
+
+static const struct intel_lpss_platform_info kbl_info = {
+	.clk_rate = 120000000,
+};
+
+static const struct intel_lpss_platform_info kbl_uart_info = {
+	.clk_rate = 120000000,
+	.clk_con_id = "baudclk",
+};
+
+static const struct intel_lpss_platform_info kbl_i2c_info = {
+	.clk_rate = 133000000,
 };
 
 static const struct pci_device_id intel_lpss_pci_ids[] = {
@@ -121,21 +174,31 @@ static const struct pci_device_id intel_
 	{ PCI_VDEVICE(INTEL, 0x9d28), (kernel_ulong_t)&spt_uart_info },
 	{ PCI_VDEVICE(INTEL, 0x9d29), (kernel_ulong_t)&spt_info },
 	{ PCI_VDEVICE(INTEL, 0x9d2a), (kernel_ulong_t)&spt_info },
-	{ PCI_VDEVICE(INTEL, 0x9d60), (kernel_ulong_t)&spt_info },
-	{ PCI_VDEVICE(INTEL, 0x9d61), (kernel_ulong_t)&spt_info },
-	{ PCI_VDEVICE(INTEL, 0x9d62), (kernel_ulong_t)&spt_info },
-	{ PCI_VDEVICE(INTEL, 0x9d63), (kernel_ulong_t)&spt_info },
-	{ PCI_VDEVICE(INTEL, 0x9d64), (kernel_ulong_t)&spt_info },
-	{ PCI_VDEVICE(INTEL, 0x9d65), (kernel_ulong_t)&spt_info },
+	{ PCI_VDEVICE(INTEL, 0x9d60), (kernel_ulong_t)&spt_i2c_info },
+	{ PCI_VDEVICE(INTEL, 0x9d61), (kernel_ulong_t)&spt_i2c_info },
+	{ PCI_VDEVICE(INTEL, 0x9d62), (kernel_ulong_t)&spt_i2c_info },
+	{ PCI_VDEVICE(INTEL, 0x9d63), (kernel_ulong_t)&spt_i2c_info },
+	{ PCI_VDEVICE(INTEL, 0x9d64), (kernel_ulong_t)&spt_i2c_info },
+	{ PCI_VDEVICE(INTEL, 0x9d65), (kernel_ulong_t)&spt_i2c_info },
 	{ PCI_VDEVICE(INTEL, 0x9d66), (kernel_ulong_t)&spt_uart_info },
 	/* SPT-H */
 	{ PCI_VDEVICE(INTEL, 0xa127), (kernel_ulong_t)&spt_uart_info },
 	{ PCI_VDEVICE(INTEL, 0xa128), (kernel_ulong_t)&spt_uart_info },
 	{ PCI_VDEVICE(INTEL, 0xa129), (kernel_ulong_t)&spt_info },
 	{ PCI_VDEVICE(INTEL, 0xa12a), (kernel_ulong_t)&spt_info },
-	{ PCI_VDEVICE(INTEL, 0xa160), (kernel_ulong_t)&spt_info },
-	{ PCI_VDEVICE(INTEL, 0xa161), (kernel_ulong_t)&spt_info },
+	{ PCI_VDEVICE(INTEL, 0xa160), (kernel_ulong_t)&spt_i2c_info },
+	{ PCI_VDEVICE(INTEL, 0xa161), (kernel_ulong_t)&spt_i2c_info },
 	{ PCI_VDEVICE(INTEL, 0xa166), (kernel_ulong_t)&spt_uart_info },
+	/* KBL-H */
+	{ PCI_VDEVICE(INTEL, 0xa2a7), (kernel_ulong_t)&kbl_uart_info },
+	{ PCI_VDEVICE(INTEL, 0xa2a8), (kernel_ulong_t)&kbl_uart_info },
+	{ PCI_VDEVICE(INTEL, 0xa2a9), (kernel_ulong_t)&kbl_info },
+	{ PCI_VDEVICE(INTEL, 0xa2aa), (kernel_ulong_t)&kbl_info },
+	{ PCI_VDEVICE(INTEL, 0xa2e0), (kernel_ulong_t)&kbl_i2c_info },
+	{ PCI_VDEVICE(INTEL, 0xa2e1), (kernel_ulong_t)&kbl_i2c_info },
+	{ PCI_VDEVICE(INTEL, 0xa2e2), (kernel_ulong_t)&kbl_i2c_info },
+	{ PCI_VDEVICE(INTEL, 0xa2e3), (kernel_ulong_t)&kbl_i2c_info },
+	{ PCI_VDEVICE(INTEL, 0xa2e6), (kernel_ulong_t)&kbl_uart_info },
 	{ }
 };
 MODULE_DEVICE_TABLE(pci, intel_lpss_pci_ids);
--- zfcpdump-kernel-4.4.orig/drivers/mfd/intel-lpss.c
+++ zfcpdump-kernel-4.4/drivers/mfd/intel-lpss.c
@@ -24,6 +24,7 @@
 #include <linux/mfd/core.h>
 #include <linux/pm_qos.h>
 #include <linux/pm_runtime.h>
+#include <linux/property.h>
 #include <linux/seq_file.h>
 #include <linux/io-64-nonatomic-lo-hi.h>
 
@@ -33,6 +34,7 @@
 #define LPSS_DEV_SIZE		0x200
 #define LPSS_PRIV_OFFSET	0x200
 #define LPSS_PRIV_SIZE		0x100
+#define LPSS_PRIV_REG_COUNT	(LPSS_PRIV_SIZE / 4)
 #define LPSS_IDMA64_OFFSET	0x800
 #define LPSS_IDMA64_SIZE	0x800
 
@@ -72,9 +74,10 @@ struct intel_lpss {
 	enum intel_lpss_dev_type type;
 	struct clk *clk;
 	struct clk_lookup *clock;
-	const struct mfd_cell *cell;
+	struct mfd_cell *cell;
 	struct device *dev;
 	void __iomem *priv;
+	u32 priv_ctx[LPSS_PRIV_REG_COUNT];
 	int devid;
 	u32 caps;
 	u32 active_ltr;
@@ -217,6 +220,7 @@ static void intel_lpss_ltr_hide(struct i
 
 static int intel_lpss_assign_devs(struct intel_lpss *lpss)
 {
+	const struct mfd_cell *cell;
 	unsigned int type;
 
 	type = lpss->caps & LPSS_PRIV_CAPS_TYPE_MASK;
@@ -224,18 +228,22 @@ static int intel_lpss_assign_devs(struct
 
 	switch (type) {
 	case LPSS_DEV_I2C:
-		lpss->cell = &intel_lpss_i2c_cell;
+		cell = &intel_lpss_i2c_cell;
 		break;
 	case LPSS_DEV_UART:
-		lpss->cell = &intel_lpss_uart_cell;
+		cell = &intel_lpss_uart_cell;
 		break;
 	case LPSS_DEV_SPI:
-		lpss->cell = &intel_lpss_spi_cell;
+		cell = &intel_lpss_spi_cell;
 		break;
 	default:
 		return -ENODEV;
 	}
 
+	lpss->cell = devm_kmemdup(lpss->dev, cell, sizeof(*cell), GFP_KERNEL);
+	if (!lpss->cell)
+		return -ENOMEM;
+
 	lpss->type = type;
 
 	return 0;
@@ -401,6 +409,8 @@ int intel_lpss_probe(struct device *dev,
 	if (ret)
 		return ret;
 
+	lpss->cell->pset = info->pset;
+
 	intel_lpss_init_dev(lpss);
 
 	lpss->devid = ida_simple_get(&intel_lpss_devid_ida, 0, 0, GFP_KERNEL);
@@ -445,6 +455,7 @@ int intel_lpss_probe(struct device *dev,
 err_remove_ltr:
 	intel_lpss_debugfs_remove(lpss);
 	intel_lpss_ltr_hide(lpss);
+	intel_lpss_unregister_clock(lpss);
 
 err_clk_register:
 	ida_simple_remove(&intel_lpss_devid_ida, lpss->devid);
@@ -484,6 +495,16 @@ EXPORT_SYMBOL_GPL(intel_lpss_prepare);
 
 int intel_lpss_suspend(struct device *dev)
 {
+	struct intel_lpss *lpss = dev_get_drvdata(dev);
+	unsigned int i;
+
+	/* Save device context */
+	for (i = 0; i < LPSS_PRIV_REG_COUNT; i++)
+		lpss->priv_ctx[i] = readl(lpss->priv + i * 4);
+
+	/* Put the device into reset state */
+	writel(0, lpss->priv + LPSS_PRIV_RESETS);
+
 	return 0;
 }
 EXPORT_SYMBOL_GPL(intel_lpss_suspend);
@@ -491,8 +512,13 @@ EXPORT_SYMBOL_GPL(intel_lpss_suspend);
 int intel_lpss_resume(struct device *dev)
 {
 	struct intel_lpss *lpss = dev_get_drvdata(dev);
+	unsigned int i;
 
-	intel_lpss_init_dev(lpss);
+	intel_lpss_deassert_reset(lpss);
+
+	/* Restore device context */
+	for (i = 0; i < LPSS_PRIV_REG_COUNT; i++)
+		writel(lpss->priv_ctx[i], lpss->priv + i * 4);
 
 	return 0;
 }
--- zfcpdump-kernel-4.4.orig/drivers/mfd/intel-lpss.h
+++ zfcpdump-kernel-4.4/drivers/mfd/intel-lpss.h
@@ -16,12 +16,14 @@
 
 struct device;
 struct resource;
+struct property_set;
 
 struct intel_lpss_platform_info {
 	struct resource *mem;
 	int irq;
 	unsigned long clk_rate;
 	const char *clk_con_id;
+	struct property_set *pset;
 };
 
 int intel_lpss_probe(struct device *dev,
--- zfcpdump-kernel-4.4.orig/drivers/mfd/intel_soc_pmic_core.c
+++ zfcpdump-kernel-4.4/drivers/mfd/intel_soc_pmic_core.c
@@ -35,6 +35,7 @@ static struct gpiod_lookup_table panel_g
 	.table = {
 		/* Panel EN/DISABLE */
 		GPIO_LOOKUP("gpio_crystalcove", 94, "panel", GPIO_ACTIVE_HIGH),
+		{ },
 	},
 };
 
--- zfcpdump-kernel-4.4.orig/drivers/mfd/mfd-core.c
+++ zfcpdump-kernel-4.4/drivers/mfd/mfd-core.c
@@ -14,6 +14,7 @@
 #include <linux/kernel.h>
 #include <linux/platform_device.h>
 #include <linux/acpi.h>
+#include <linux/property.h>
 #include <linux/mfd/core.h>
 #include <linux/pm_runtime.h>
 #include <linux/slab.h>
@@ -191,6 +192,12 @@ static int mfd_add_device(struct device
 		if (ret)
 			goto fail_alias;
 	}
+
+	if (cell->pset) {
+		ret = platform_device_add_properties(pdev, cell->pset);
+		if (ret)
+			goto fail_alias;
+	}
 
 	ret = mfd_platform_add_cell(pdev, cell, usage_count);
 	if (ret)
--- zfcpdump-kernel-4.4.orig/drivers/mfd/omap-usb-tll.c
+++ zfcpdump-kernel-4.4/drivers/mfd/omap-usb-tll.c
@@ -269,6 +269,8 @@ static int usbtll_omap_probe(struct plat
 
 		if (IS_ERR(tll->ch_clk[i]))
 			dev_dbg(dev, "can't get clock : %s\n", clkname);
+		else
+			clk_prepare(tll->ch_clk[i]);
 	}
 
 	pm_runtime_put_sync(dev);
@@ -301,9 +303,12 @@ static int usbtll_omap_remove(struct pla
 	tll_dev = NULL;
 	spin_unlock(&tll_lock);
 
-	for (i = 0; i < tll->nch; i++)
-		if (!IS_ERR(tll->ch_clk[i]))
+	for (i = 0; i < tll->nch; i++) {
+		if (!IS_ERR(tll->ch_clk[i])) {
+			clk_unprepare(tll->ch_clk[i]);
 			clk_put(tll->ch_clk[i]);
+		}
+	}
 
 	pm_runtime_disable(&pdev->dev);
 	return 0;
@@ -420,7 +425,7 @@ int omap_tll_enable(struct usbhs_omap_pl
 			if (IS_ERR(tll->ch_clk[i]))
 				continue;
 
-			r = clk_prepare_enable(tll->ch_clk[i]);
+			r = clk_enable(tll->ch_clk[i]);
 			if (r) {
 				dev_err(tll_dev,
 				 "Error enabling ch %d clock: %d\n", i, r);
@@ -448,7 +453,7 @@ int omap_tll_disable(struct usbhs_omap_p
 	for (i = 0; i < tll->nch; i++) {
 		if (omap_usb_mode_needs_tll(pdata->port_mode[i])) {
 			if (!IS_ERR(tll->ch_clk[i]))
-				clk_disable_unprepare(tll->ch_clk[i]);
+				clk_disable(tll->ch_clk[i]);
 		}
 	}
 
--- zfcpdump-kernel-4.4.orig/drivers/mfd/qcom_rpm.c
+++ zfcpdump-kernel-4.4/drivers/mfd/qcom_rpm.c
@@ -34,7 +34,13 @@ struct qcom_rpm_resource {
 struct qcom_rpm_data {
 	u32 version;
 	const struct qcom_rpm_resource *resource_table;
-	unsigned n_resources;
+	unsigned int n_resources;
+	unsigned int req_ctx_off;
+	unsigned int req_sel_off;
+	unsigned int ack_ctx_off;
+	unsigned int ack_sel_off;
+	unsigned int req_sel_size;
+	unsigned int ack_sel_size;
 };
 
 struct qcom_rpm {
@@ -61,11 +67,7 @@ struct qcom_rpm {
 
 #define RPM_REQUEST_TIMEOUT	(5 * HZ)
 
-#define RPM_REQUEST_CONTEXT	3
-#define RPM_REQ_SELECT		11
-#define RPM_ACK_CONTEXT		15
-#define RPM_ACK_SELECTOR	23
-#define RPM_SELECT_SIZE		7
+#define RPM_MAX_SEL_SIZE	7
 
 #define RPM_NOTIFICATION	BIT(30)
 #define RPM_REJECTED		BIT(31)
@@ -157,6 +159,12 @@ static const struct qcom_rpm_data apq806
 	.version = 3,
 	.resource_table = apq8064_rpm_resource_table,
 	.n_resources = ARRAY_SIZE(apq8064_rpm_resource_table),
+	.req_ctx_off = 3,
+	.req_sel_off = 11,
+	.ack_ctx_off = 15,
+	.ack_sel_off = 23,
+	.req_sel_size = 4,
+	.ack_sel_size = 7,
 };
 
 static const struct qcom_rpm_resource msm8660_rpm_resource_table[] = {
@@ -240,6 +248,12 @@ static const struct qcom_rpm_data msm866
 	.version = 2,
 	.resource_table = msm8660_rpm_resource_table,
 	.n_resources = ARRAY_SIZE(msm8660_rpm_resource_table),
+	.req_ctx_off = 3,
+	.req_sel_off = 11,
+	.ack_ctx_off = 19,
+	.ack_sel_off = 27,
+	.req_sel_size = 7,
+	.ack_sel_size = 7,
 };
 
 static const struct qcom_rpm_resource msm8960_rpm_resource_table[] = {
@@ -322,6 +336,12 @@ static const struct qcom_rpm_data msm896
 	.version = 3,
 	.resource_table = msm8960_rpm_resource_table,
 	.n_resources = ARRAY_SIZE(msm8960_rpm_resource_table),
+	.req_ctx_off = 3,
+	.req_sel_off = 11,
+	.ack_ctx_off = 15,
+	.ack_sel_off = 23,
+	.req_sel_size = 4,
+	.ack_sel_size = 7,
 };
 
 static const struct qcom_rpm_resource ipq806x_rpm_resource_table[] = {
@@ -362,6 +382,12 @@ static const struct qcom_rpm_data ipq806
 	.version = 3,
 	.resource_table = ipq806x_rpm_resource_table,
 	.n_resources = ARRAY_SIZE(ipq806x_rpm_resource_table),
+	.req_ctx_off = 3,
+	.req_sel_off = 11,
+	.ack_ctx_off = 15,
+	.ack_sel_off = 23,
+	.req_sel_size = 4,
+	.ack_sel_size = 7,
 };
 
 static const struct of_device_id qcom_rpm_of_match[] = {
@@ -380,7 +406,7 @@ int qcom_rpm_write(struct qcom_rpm *rpm,
 {
 	const struct qcom_rpm_resource *res;
 	const struct qcom_rpm_data *data = rpm->data;
-	u32 sel_mask[RPM_SELECT_SIZE] = { 0 };
+	u32 sel_mask[RPM_MAX_SEL_SIZE] = { 0 };
 	int left;
 	int ret = 0;
 	int i;
@@ -398,12 +424,12 @@ int qcom_rpm_write(struct qcom_rpm *rpm,
 		writel_relaxed(buf[i], RPM_REQ_REG(rpm, res->target_id + i));
 
 	bitmap_set((unsigned long *)sel_mask, res->select_id, 1);
-	for (i = 0; i < ARRAY_SIZE(sel_mask); i++) {
+	for (i = 0; i < rpm->data->req_sel_size; i++) {
 		writel_relaxed(sel_mask[i],
-			       RPM_CTRL_REG(rpm, RPM_REQ_SELECT + i));
+			       RPM_CTRL_REG(rpm, rpm->data->req_sel_off + i));
 	}
 
-	writel_relaxed(BIT(state), RPM_CTRL_REG(rpm, RPM_REQUEST_CONTEXT));
+	writel_relaxed(BIT(state), RPM_CTRL_REG(rpm, rpm->data->req_ctx_off));
 
 	reinit_completion(&rpm->ack);
 	regmap_write(rpm->ipc_regmap, rpm->ipc_offset, BIT(rpm->ipc_bit));
@@ -426,10 +452,11 @@ static irqreturn_t qcom_rpm_ack_interrup
 	u32 ack;
 	int i;
 
-	ack = readl_relaxed(RPM_CTRL_REG(rpm, RPM_ACK_CONTEXT));
-	for (i = 0; i < RPM_SELECT_SIZE; i++)
-		writel_relaxed(0, RPM_CTRL_REG(rpm, RPM_ACK_SELECTOR + i));
-	writel(0, RPM_CTRL_REG(rpm, RPM_ACK_CONTEXT));
+	ack = readl_relaxed(RPM_CTRL_REG(rpm, rpm->data->ack_ctx_off));
+	for (i = 0; i < rpm->data->ack_sel_size; i++)
+		writel_relaxed(0,
+			RPM_CTRL_REG(rpm, rpm->data->ack_sel_off + i));
+	writel(0, RPM_CTRL_REG(rpm, rpm->data->ack_ctx_off));
 
 	if (ack & RPM_NOTIFICATION) {
 		dev_warn(rpm->dev, "ignoring notification!\n");
--- zfcpdump-kernel-4.4.orig/drivers/misc/Kconfig
+++ zfcpdump-kernel-4.4/drivers/misc/Kconfig
@@ -439,7 +439,7 @@ config ARM_CHARLCD
 	  still useful.
 
 config BMP085
-	bool
+	tristate
 	depends on SYSFS
 
 config BMP085_I2C
--- zfcpdump-kernel-4.4.orig/drivers/misc/ad525x_dpot.c
+++ zfcpdump-kernel-4.4/drivers/misc/ad525x_dpot.c
@@ -216,7 +216,7 @@ static s32 dpot_read_i2c(struct dpot_dat
 			 */
 			value = swab16(value);
 
-			if (dpot->uid == DPOT_UID(AD5271_ID))
+			if (dpot->uid == DPOT_UID(AD5274_ID))
 				value = value >> 2;
 		return value;
 	default:
--- zfcpdump-kernel-4.4.orig/drivers/misc/cxl/Makefile
+++ zfcpdump-kernel-4.4/drivers/misc/cxl/Makefile
@@ -1,8 +1,10 @@
-ccflags-y := -Werror -Wno-unused-const-variable
+ccflags-y			:= $(call cc-disable-warning, unused-const-variable)
+ccflags-$(CONFIG_PPC_WERROR)	+= -Werror
 
 cxl-y				+= main.o file.o irq.o fault.o native.o
 cxl-y				+= context.o sysfs.o debugfs.o pci.o trace.o
 cxl-y				+= vphb.o api.o
+cxl-$(CONFIG_PPC_PSERIES)	+= flash.o guest.o of.o hcalls.o
 obj-$(CONFIG_CXL)		+= cxl.o
 obj-$(CONFIG_CXL_BASE)		+= base.o
 
--- zfcpdump-kernel-4.4.orig/drivers/misc/cxl/api.c
+++ zfcpdump-kernel-4.4/drivers/misc/cxl/api.c
@@ -25,7 +25,6 @@ struct cxl_context *cxl_dev_context_init
 
 	afu = cxl_pci_to_afu(dev);
 
-	get_device(&afu->dev);
 	ctx = cxl_context_alloc();
 	if (IS_ERR(ctx)) {
 		rc = PTR_ERR(ctx);
@@ -52,8 +51,6 @@ struct cxl_context *cxl_dev_context_init
 	if (rc)
 		goto err_mapping;
 
-	cxl_assign_psn_space(ctx);
-
 	return ctx;
 
 err_mapping:
@@ -61,7 +58,6 @@ err_mapping:
 err_ctx:
 	kfree(ctx);
 err_dev:
-	put_device(&afu->dev);
 	return ERR_PTR(rc);
 }
 EXPORT_SYMBOL_GPL(cxl_dev_context_init);
@@ -80,43 +76,23 @@ struct device *cxl_get_phys_dev(struct p
 
 	return afu->adapter->dev.parent;
 }
-EXPORT_SYMBOL_GPL(cxl_get_phys_dev);
 
 int cxl_release_context(struct cxl_context *ctx)
 {
 	if (ctx->status >= STARTED)
 		return -EBUSY;
 
-	put_device(&ctx->afu->dev);
-
 	cxl_context_free(ctx);
 
 	return 0;
 }
 EXPORT_SYMBOL_GPL(cxl_release_context);
 
-int cxl_allocate_afu_irqs(struct cxl_context *ctx, int num)
-{
-	if (num == 0)
-		num = ctx->afu->pp_irqs;
-	return afu_allocate_irqs(ctx, num);
-}
-EXPORT_SYMBOL_GPL(cxl_allocate_afu_irqs);
-
-void cxl_free_afu_irqs(struct cxl_context *ctx)
-{
-	afu_irq_name_free(ctx);
-	cxl_release_irq_ranges(&ctx->irqs, ctx->afu->adapter);
-}
-EXPORT_SYMBOL_GPL(cxl_free_afu_irqs);
-
 static irq_hw_number_t cxl_find_afu_irq(struct cxl_context *ctx, int num)
 {
 	__u16 range;
 	int r;
 
-	WARN_ON(num == 0);
-
 	for (r = 0; r < CXL_IRQ_RANGES; r++) {
 		range = ctx->irqs.range[r];
 		if (num < range) {
@@ -127,6 +103,44 @@ static irq_hw_number_t cxl_find_afu_irq(
 	return 0;
 }
 
+int cxl_allocate_afu_irqs(struct cxl_context *ctx, int num)
+{
+	int res;
+	irq_hw_number_t hwirq;
+
+	if (num == 0)
+		num = ctx->afu->pp_irqs;
+	res = afu_allocate_irqs(ctx, num);
+	if (!res && !cpu_has_feature(CPU_FTR_HVMODE)) {
+		/* In a guest, the PSL interrupt is not multiplexed. It was
+		 * allocated above, and we need to set its handler
+		 */
+		hwirq = cxl_find_afu_irq(ctx, 0);
+		if (hwirq)
+			cxl_map_irq(ctx->afu->adapter, hwirq, cxl_ops->psl_interrupt, ctx, "psl");
+	}
+	return res;
+}
+EXPORT_SYMBOL_GPL(cxl_allocate_afu_irqs);
+
+void cxl_free_afu_irqs(struct cxl_context *ctx)
+{
+	irq_hw_number_t hwirq;
+	unsigned int virq;
+
+	if (!cpu_has_feature(CPU_FTR_HVMODE)) {
+		hwirq = cxl_find_afu_irq(ctx, 0);
+		if (hwirq) {
+			virq = irq_find_mapping(NULL, hwirq);
+			if (virq)
+				cxl_unmap_irq(virq, ctx);
+		}
+	}
+	afu_irq_name_free(ctx);
+	cxl_ops->release_irq_ranges(&ctx->irqs, ctx->afu->adapter);
+}
+EXPORT_SYMBOL_GPL(cxl_free_afu_irqs);
+
 int cxl_map_afu_irq(struct cxl_context *ctx, int num,
 		    irq_handler_t handler, void *cookie, char *name)
 {
@@ -176,13 +190,13 @@ int cxl_start_context(struct cxl_context
 
 	if (task) {
 		ctx->pid = get_task_pid(task, PIDTYPE_PID);
-		get_pid(ctx->pid);
+		ctx->glpid = get_task_pid(task->group_leader, PIDTYPE_PID);
 		kernel = false;
 	}
 
 	cxl_ctx_get();
 
-	if ((rc = cxl_attach_process(ctx, kernel, wed , 0))) {
+	if ((rc = cxl_ops->attach_process(ctx, kernel, wed, 0))) {
 		put_pid(ctx->pid);
 		cxl_ctx_put();
 		goto out;
@@ -197,7 +211,7 @@ EXPORT_SYMBOL_GPL(cxl_start_context);
 
 int cxl_process_element(struct cxl_context *ctx)
 {
-	return ctx->pe;
+	return ctx->external_pe;
 }
 EXPORT_SYMBOL_GPL(cxl_process_element);
 
@@ -211,7 +225,6 @@ EXPORT_SYMBOL_GPL(cxl_stop_context);
 void cxl_set_master(struct cxl_context *ctx)
 {
 	ctx->master = true;
-	cxl_assign_psn_space(ctx);
 }
 EXPORT_SYMBOL_GPL(cxl_set_master);
 
@@ -329,15 +342,11 @@ EXPORT_SYMBOL_GPL(cxl_start_work);
 
 void __iomem *cxl_psa_map(struct cxl_context *ctx)
 {
-	struct cxl_afu *afu = ctx->afu;
-	int rc;
-
-	rc = cxl_afu_check_and_enable(afu);
-	if (rc)
+	if (ctx->status != STARTED)
 		return NULL;
 
 	pr_devel("%s: psn_phys%llx size:%llx\n",
-		 __func__, afu->psn_phys, afu->adapter->ps_size);
+		__func__, ctx->psn_phys, ctx->psn_size);
 	return ioremap(ctx->psn_phys, ctx->psn_size);
 }
 EXPORT_SYMBOL_GPL(cxl_psa_map);
@@ -353,11 +362,11 @@ int cxl_afu_reset(struct cxl_context *ct
 	struct cxl_afu *afu = ctx->afu;
 	int rc;
 
-	rc = __cxl_afu_reset(afu);
+	rc = cxl_ops->afu_reset(afu);
 	if (rc)
 		return rc;
 
-	return cxl_afu_check_and_enable(afu);
+	return cxl_ops->afu_check_and_enable(afu);
 }
 EXPORT_SYMBOL_GPL(cxl_afu_reset);
 
@@ -367,3 +376,11 @@ void cxl_perst_reloads_same_image(struct
 	afu->adapter->perst_same_image = perst_reloads_same_image;
 }
 EXPORT_SYMBOL_GPL(cxl_perst_reloads_same_image);
+
+ssize_t cxl_read_adapter_vpd(struct pci_dev *dev, void *buf, size_t count)
+{
+	struct cxl_afu *afu = cxl_pci_to_afu(dev);
+
+	return cxl_ops->read_adapter_vpd(afu->adapter, buf, count);
+}
+EXPORT_SYMBOL_GPL(cxl_read_adapter_vpd);
--- zfcpdump-kernel-4.4.orig/drivers/misc/cxl/base.c
+++ zfcpdump-kernel-4.4/drivers/misc/cxl/base.c
@@ -11,6 +11,7 @@
 #include <linux/rcupdate.h>
 #include <asm/errno.h>
 #include <misc/cxl-base.h>
+#include <linux/of_platform.h>
 #include "cxl.h"
 
 /* protected by rcu */
@@ -84,3 +85,34 @@ void unregister_cxl_calls(struct cxl_cal
 	synchronize_rcu();
 }
 EXPORT_SYMBOL_GPL(unregister_cxl_calls);
+
+int cxl_update_properties(struct device_node *dn,
+			  struct property *new_prop)
+{
+	return of_update_property(dn, new_prop);
+}
+EXPORT_SYMBOL_GPL(cxl_update_properties);
+
+static int __init cxl_base_init(void)
+{
+	struct device_node *np = NULL;
+	struct platform_device *dev;
+	int count = 0;
+
+	/*
+	 * Scan for compatible devices in guest only
+	 */
+	if (cpu_has_feature(CPU_FTR_HVMODE))
+		return 0;
+
+	while ((np = of_find_compatible_node(np, NULL,
+				     "ibm,coherent-platform-facility"))) {
+		dev = of_platform_device_create(np, NULL, NULL);
+		if (dev)
+			count++;
+	}
+	pr_devel("Found %d cxl device(s)\n", count);
+	return 0;
+}
+
+module_init(cxl_base_init);
--- zfcpdump-kernel-4.4.orig/drivers/misc/cxl/context.c
+++ zfcpdump-kernel-4.4/drivers/misc/cxl/context.c
@@ -42,7 +42,7 @@ int cxl_context_init(struct cxl_context
 	spin_lock_init(&ctx->sste_lock);
 	ctx->afu = afu;
 	ctx->master = master;
-	ctx->pid = NULL; /* Set in start work ioctl */
+	ctx->pid = ctx->glpid = NULL; /* Set in start work ioctl */
 	mutex_init(&ctx->mapping_lock);
 	ctx->mapping = mapping;
 
@@ -95,8 +95,19 @@ int cxl_context_init(struct cxl_context
 		return i;
 
 	ctx->pe = i;
-	ctx->elem = &ctx->afu->spa[i];
+	if (cpu_has_feature(CPU_FTR_HVMODE)) {
+		ctx->elem = &ctx->afu->native->spa[i];
+		ctx->external_pe = ctx->pe;
+	} else {
+		ctx->external_pe = -1; /* assigned when attaching */
+	}
 	ctx->pe_inserted = false;
+
+	/*
+	 * take a ref on the afu so that it stays alive at-least till
+	 * this context is reclaimed inside reclaim_ctx.
+	 */
+	cxl_afu_get(afu);
 	return 0;
 }
 
@@ -208,10 +219,21 @@ int __detach_context(struct cxl_context
 	/* Only warn if we detached while the link was OK.
 	 * If detach fails when hw is down, we don't care.
 	 */
-	WARN_ON(cxl_detach_process(ctx) &&
-		cxl_adapter_link_ok(ctx->afu->adapter));
+	WARN_ON(cxl_ops->detach_process(ctx) &&
+		cxl_ops->link_ok(ctx->afu->adapter, ctx->afu));
 	flush_work(&ctx->fault_work); /* Only needed for dedicated process */
+
+	/*
+	 * Wait until no further interrupts are presented by the PSL
+	 * for this context.
+	 */
+	if (cxl_ops->irq_wait)
+		cxl_ops->irq_wait(ctx);
+
+	/* release the reference to the group leader and mm handling pid */
 	put_pid(ctx->pid);
+	put_pid(ctx->glpid);
+
 	cxl_ctx_put();
 	return 0;
 }
@@ -278,6 +300,9 @@ static void reclaim_ctx(struct rcu_head
 	if (ctx->irq_bitmap)
 		kfree(ctx->irq_bitmap);
 
+	/* Drop ref to the afu device taken during cxl_context_init */
+	cxl_afu_put(ctx->afu);
+
 	kfree(ctx);
 }
 
--- zfcpdump-kernel-4.4.orig/drivers/misc/cxl/cxl.h
+++ zfcpdump-kernel-4.4/drivers/misc/cxl/cxl.h
@@ -155,7 +155,10 @@ static const cxl_p2n_reg_t CXL_PSL_WED_A
 #define CXL_PSL_SPAP_V    0x0000000000000001ULL
 
 /****** CXL_PSL_Control ****************************************************/
-#define CXL_PSL_Control_tb 0x0000000000000001ULL
+#define CXL_PSL_Control_tb              (0x1ull << (63-63))
+#define CXL_PSL_Control_Fr              (0x1ull << (63-31))
+#define CXL_PSL_Control_Fs_MASK         (0x3ull << (63-29))
+#define CXL_PSL_Control_Fs_Complete     (0x3ull << (63-29))
 
 /****** CXL_PSL_DLCNTL *****************************************************/
 #define CXL_PSL_DLCNTL_D (0x1ull << (63-28))
@@ -274,6 +277,7 @@ static const cxl_p2n_reg_t CXL_PSL_WED_A
 #define CXL_PSL_DSISR_An_PE (1ull << (63-4))  /* PSL Error (implementation specific) */
 #define CXL_PSL_DSISR_An_AE (1ull << (63-5))  /* AFU Error */
 #define CXL_PSL_DSISR_An_OC (1ull << (63-6))  /* OS Context Warning */
+#define CXL_PSL_DSISR_PENDING (CXL_PSL_DSISR_TRANS | CXL_PSL_DSISR_An_PE | CXL_PSL_DSISR_An_AE | CXL_PSL_DSISR_An_OC)
 /* NOTE: Bits 32:63 are undefined if DSISR[DS] = 1 */
 #define CXL_PSL_DSISR_An_M  DSISR_NOHPTE      /* PTE not found */
 #define CXL_PSL_DSISR_An_P  DSISR_PROTFAULT   /* Storage protection violation */
@@ -324,6 +328,10 @@ static const cxl_p2n_reg_t CXL_PSL_WED_A
 #define CXL_MODE_TIME_SLICED 0x4
 #define CXL_SUPPORTED_MODES (CXL_MODE_DEDICATED | CXL_MODE_DIRECTED)
 
+#define CXL_DEV_MINORS 13   /* 1 control + 4 AFUs * 3 (dedicated/master/shared) */
+#define CXL_CARD_MINOR(adapter) (adapter->adapter_num * CXL_DEV_MINORS)
+#define CXL_DEVT_ADAPTER(dev) (MINOR(dev) / CXL_DEV_MINORS)
+
 enum cxl_context_status {
 	CLOSED,
 	OPENED,
@@ -336,6 +344,12 @@ enum prefault_modes {
 	CXL_PREFAULT_ALL,
 };
 
+enum cxl_attrs {
+	CXL_ADAPTER_ATTRS,
+	CXL_AFU_MASTER_ATTRS,
+	CXL_AFU_ATTRS,
+};
+
 struct cxl_sste {
 	__be64 esid_data;
 	__be64 vsid_data;
@@ -344,18 +358,46 @@ struct cxl_sste {
 #define to_cxl_adapter(d) container_of(d, struct cxl, dev)
 #define to_cxl_afu(d) container_of(d, struct cxl_afu, dev)
 
-struct cxl_afu {
+struct cxl_afu_native {
+	void __iomem *p1n_mmio;
+	void __iomem *afu_desc_mmio;
 	irq_hw_number_t psl_hwirq;
+	unsigned int psl_virq;
+	struct mutex spa_mutex;
+	/*
+	 * Only the first part of the SPA is used for the process element
+	 * linked list. The only other part that software needs to worry about
+	 * is sw_command_status, which we store a separate pointer to.
+	 * Everything else in the SPA is only used by hardware
+	 */
+	struct cxl_process_element *spa;
+	__be64 *sw_command_status;
+	unsigned int spa_size;
+	int spa_order;
+	int spa_max_procs;
+	u64 pp_offset;
+};
+
+struct cxl_afu_guest {
+	u64 handle;
+	phys_addr_t p2n_phys;
+	u64 p2n_size;
+	int max_ints;
+	struct mutex recovery_lock;
+	int previous_state;
+};
+
+struct cxl_afu {
+	struct cxl_afu_native *native;
+	struct cxl_afu_guest *guest;
 	irq_hw_number_t serr_hwirq;
-	char *err_irq_name;
-	char *psl_irq_name;
 	unsigned int serr_virq;
-	void __iomem *p1n_mmio;
+	char *psl_irq_name;
+	char *err_irq_name;
 	void __iomem *p2n_mmio;
 	phys_addr_t psn_phys;
-	u64 pp_offset;
 	u64 pp_size;
-	void __iomem *afu_desc_mmio;
+
 	struct cxl *adapter;
 	struct device dev;
 	struct cdev afu_cdev_s, afu_cdev_m, afu_cdev_d;
@@ -363,26 +405,12 @@ struct cxl_afu {
 	struct idr contexts_idr;
 	struct dentry *debugfs;
 	struct mutex contexts_lock;
-	struct mutex spa_mutex;
 	spinlock_t afu_cntl_lock;
 
 	/* AFU error buffer fields and bin attribute for sysfs */
 	u64 eb_len, eb_offset;
 	struct bin_attribute attr_eb;
 
-	/*
-	 * Only the first part of the SPA is used for the process element
-	 * linked list. The only other part that software needs to worry about
-	 * is sw_command_status, which we store a separate pointer to.
-	 * Everything else in the SPA is only used by hardware
-	 */
-	struct cxl_process_element *spa;
-	__be64 *sw_command_status;
-	unsigned int spa_size;
-	int spa_order;
-	int spa_max_procs;
-	unsigned int psl_virq;
-
 	/* pointer to the vphb */
 	struct pci_controller *phb;
 
@@ -403,12 +431,30 @@ struct cxl_afu {
 	bool enabled;
 };
 
+/* AFU refcount management */
+static inline struct cxl_afu *cxl_afu_get(struct cxl_afu *afu)
+{
+
+	return (get_device(&afu->dev) == NULL) ? NULL : afu;
+}
+
+static inline void  cxl_afu_put(struct cxl_afu *afu)
+{
+	put_device(&afu->dev);
+}
+
 
 struct cxl_irq_name {
 	struct list_head list;
 	char *name;
 };
 
+struct irq_avail {
+	irq_hw_number_t offset;
+	irq_hw_number_t range;
+	unsigned long   *bitmap;
+};
+
 /*
  * This is a cxl context.  If the PSL is in dedicated mode, there will be one
  * of these per AFU.  If in AFU directed there can be lots of these.
@@ -433,6 +479,9 @@ struct cxl_context {
 	unsigned int sst_size, sst_lru;
 
 	wait_queue_head_t wq;
+	/* pid of the group leader associated with the pid */
+	struct pid *glpid;
+	/* use mm context associated with this pid for ds faults */
 	struct pid *pid;
 	spinlock_t lock; /* Protects pending_irq_mask, pending_fault and fault_addr */
 	/* Only used in PR mode */
@@ -461,7 +510,19 @@ struct cxl_context {
 
 	struct cxl_process_element *elem;
 
-	int pe; /* process element handle */
+	/*
+	 * pe is the process element handle, assigned by this driver when the
+	 * context is initialized.
+	 *
+	 * external_pe is the PE shown outside of cxl.
+	 * On bare-metal, pe=external_pe, because we decide what the handle is.
+	 * In a guest, we only find out about the pe used by pHyp when the
+	 * context is attached, and that's the value we want to report outside
+	 * of cxl.
+	 */
+	int pe;
+	int external_pe;
+
 	u32 irq_count;
 	bool pe_inserted;
 	bool master;
@@ -473,11 +534,34 @@ struct cxl_context {
 	struct rcu_head rcu;
 };
 
-struct cxl {
+struct cxl_native {
+	u64 afu_desc_off;
+	u64 afu_desc_size;
 	void __iomem *p1_mmio;
 	void __iomem *p2_mmio;
 	irq_hw_number_t err_hwirq;
 	unsigned int err_virq;
+	u64 ps_off;
+};
+
+struct cxl_guest {
+	struct platform_device *pdev;
+	int irq_nranges;
+	struct cdev cdev;
+	irq_hw_number_t irq_base_offset;
+	struct irq_avail *irq_avail;
+	spinlock_t irq_alloc_lock;
+	u64 handle;
+	char *status;
+	u16 vendor;
+	u16 device;
+	u16 subsystem_vendor;
+	u16 subsystem;
+};
+
+struct cxl {
+	struct cxl_native *native;
+	struct cxl_guest *guest;
 	spinlock_t afu_list_lock;
 	struct cxl_afu *afu[CXL_MAX_SLICES];
 	struct device dev;
@@ -488,9 +572,6 @@ struct cxl {
 	struct bin_attribute cxl_attr;
 	int adapter_num;
 	int user_irqs;
-	u64 afu_desc_off;
-	u64 afu_desc_size;
-	u64 ps_off;
 	u64 ps_size;
 	u16 psl_rev;
 	u16 base_image;
@@ -502,15 +583,18 @@ struct cxl {
 	bool perst_loads_image;
 	bool perst_select_user;
 	bool perst_same_image;
+	bool psl_timebase_synced;
 };
 
-int cxl_alloc_one_irq(struct cxl *adapter);
-void cxl_release_one_irq(struct cxl *adapter, int hwirq);
-int cxl_alloc_irq_ranges(struct cxl_irq_ranges *irqs, struct cxl *adapter, unsigned int num);
-void cxl_release_irq_ranges(struct cxl_irq_ranges *irqs, struct cxl *adapter);
-int cxl_setup_irq(struct cxl *adapter, unsigned int hwirq, unsigned int virq);
+int cxl_pci_alloc_one_irq(struct cxl *adapter);
+void cxl_pci_release_one_irq(struct cxl *adapter, int hwirq);
+int cxl_pci_alloc_irq_ranges(struct cxl_irq_ranges *irqs, struct cxl *adapter, unsigned int num);
+void cxl_pci_release_irq_ranges(struct cxl_irq_ranges *irqs, struct cxl *adapter);
+int cxl_pci_setup_irq(struct cxl *adapter, unsigned int hwirq, unsigned int virq);
 int cxl_update_image_control(struct cxl *adapter);
-int cxl_reset(struct cxl *adapter);
+int cxl_pci_reset(struct cxl *adapter);
+void cxl_pci_release_afu(struct device *dev);
+ssize_t cxl_pci_read_adapter_vpd(struct cxl *adapter, void *buf, size_t len);
 
 /* common == phyp + powernv */
 struct cxl_process_element_common {
@@ -540,29 +624,32 @@ struct cxl_process_element {
 	__be32 software_state;
 } __packed;
 
-static inline bool cxl_adapter_link_ok(struct cxl *cxl)
+static inline bool cxl_adapter_link_ok(struct cxl *cxl, struct cxl_afu *afu)
 {
 	struct pci_dev *pdev;
 
-	pdev = to_pci_dev(cxl->dev.parent);
-	return !pci_channel_offline(pdev);
+	if (cpu_has_feature(CPU_FTR_HVMODE)) {
+		pdev = to_pci_dev(cxl->dev.parent);
+		return !pci_channel_offline(pdev);
+	}
+	return true;
 }
 
 static inline void __iomem *_cxl_p1_addr(struct cxl *cxl, cxl_p1_reg_t reg)
 {
 	WARN_ON(!cpu_has_feature(CPU_FTR_HVMODE));
-	return cxl->p1_mmio + cxl_reg_off(reg);
+	return cxl->native->p1_mmio + cxl_reg_off(reg);
 }
 
 static inline void cxl_p1_write(struct cxl *cxl, cxl_p1_reg_t reg, u64 val)
 {
-	if (likely(cxl_adapter_link_ok(cxl)))
+	if (likely(cxl_adapter_link_ok(cxl, NULL)))
 		out_be64(_cxl_p1_addr(cxl, reg), val);
 }
 
 static inline u64 cxl_p1_read(struct cxl *cxl, cxl_p1_reg_t reg)
 {
-	if (likely(cxl_adapter_link_ok(cxl)))
+	if (likely(cxl_adapter_link_ok(cxl, NULL)))
 		return in_be64(_cxl_p1_addr(cxl, reg));
 	else
 		return ~0ULL;
@@ -571,18 +658,18 @@ static inline u64 cxl_p1_read(struct cxl
 static inline void __iomem *_cxl_p1n_addr(struct cxl_afu *afu, cxl_p1n_reg_t reg)
 {
 	WARN_ON(!cpu_has_feature(CPU_FTR_HVMODE));
-	return afu->p1n_mmio + cxl_reg_off(reg);
+	return afu->native->p1n_mmio + cxl_reg_off(reg);
 }
 
 static inline void cxl_p1n_write(struct cxl_afu *afu, cxl_p1n_reg_t reg, u64 val)
 {
-	if (likely(cxl_adapter_link_ok(afu->adapter)))
+	if (likely(cxl_adapter_link_ok(afu->adapter, afu)))
 		out_be64(_cxl_p1n_addr(afu, reg), val);
 }
 
 static inline u64 cxl_p1n_read(struct cxl_afu *afu, cxl_p1n_reg_t reg)
 {
-	if (likely(cxl_adapter_link_ok(afu->adapter)))
+	if (likely(cxl_adapter_link_ok(afu->adapter, afu)))
 		return in_be64(_cxl_p1n_addr(afu, reg));
 	else
 		return ~0ULL;
@@ -595,39 +682,19 @@ static inline void __iomem *_cxl_p2n_add
 
 static inline void cxl_p2n_write(struct cxl_afu *afu, cxl_p2n_reg_t reg, u64 val)
 {
-	if (likely(cxl_adapter_link_ok(afu->adapter)))
+	if (likely(cxl_adapter_link_ok(afu->adapter, afu)))
 		out_be64(_cxl_p2n_addr(afu, reg), val);
 }
 
 static inline u64 cxl_p2n_read(struct cxl_afu *afu, cxl_p2n_reg_t reg)
 {
-	if (likely(cxl_adapter_link_ok(afu->adapter)))
+	if (likely(cxl_adapter_link_ok(afu->adapter, afu)))
 		return in_be64(_cxl_p2n_addr(afu, reg));
 	else
 		return ~0ULL;
 }
 
-static inline u64 cxl_afu_cr_read64(struct cxl_afu *afu, int cr, u64 off)
-{
-	if (likely(cxl_adapter_link_ok(afu->adapter)))
-		return in_le64((afu)->afu_desc_mmio + (afu)->crs_offset +
-			       ((cr) * (afu)->crs_len) + (off));
-	else
-		return ~0ULL;
-}
-
-static inline u32 cxl_afu_cr_read32(struct cxl_afu *afu, int cr, u64 off)
-{
-	if (likely(cxl_adapter_link_ok(afu->adapter)))
-		return in_le32((afu)->afu_desc_mmio + (afu)->crs_offset +
-			       ((cr) * (afu)->crs_len) + (off));
-	else
-		return 0xffffffff;
-}
-u16 cxl_afu_cr_read16(struct cxl_afu *afu, int cr, u64 off);
-u8 cxl_afu_cr_read8(struct cxl_afu *afu, int cr, u64 off);
-
-ssize_t cxl_afu_read_err_buffer(struct cxl_afu *afu, char *buf,
+ssize_t cxl_pci_afu_read_err_buffer(struct cxl_afu *afu, char *buf,
 				loff_t off, size_t count);
 
 
@@ -637,13 +704,14 @@ struct cxl_calls {
 };
 int register_cxl_calls(struct cxl_calls *calls);
 void unregister_cxl_calls(struct cxl_calls *calls);
+int cxl_update_properties(struct device_node *dn, struct property *new_prop);
 
-int cxl_alloc_adapter_nr(struct cxl *adapter);
 void cxl_remove_adapter_nr(struct cxl *adapter);
 
 int cxl_alloc_spa(struct cxl_afu *afu);
 void cxl_release_spa(struct cxl_afu *afu);
 
+dev_t cxl_get_dev(void);
 int cxl_file_init(void);
 void cxl_file_exit(void);
 int cxl_register_adapter(struct cxl *adapter);
@@ -664,21 +732,19 @@ void cxl_sysfs_afu_remove(struct cxl_afu
 int cxl_sysfs_afu_m_add(struct cxl_afu *afu);
 void cxl_sysfs_afu_m_remove(struct cxl_afu *afu);
 
-int cxl_afu_activate_mode(struct cxl_afu *afu, int mode);
-int _cxl_afu_deactivate_mode(struct cxl_afu *afu, int mode);
-int cxl_afu_deactivate_mode(struct cxl_afu *afu);
+struct cxl *cxl_alloc_adapter(void);
+struct cxl_afu *cxl_alloc_afu(struct cxl *adapter, int slice);
 int cxl_afu_select_best_mode(struct cxl_afu *afu);
 
-int cxl_register_psl_irq(struct cxl_afu *afu);
-void cxl_release_psl_irq(struct cxl_afu *afu);
-int cxl_register_psl_err_irq(struct cxl *adapter);
-void cxl_release_psl_err_irq(struct cxl *adapter);
-int cxl_register_serr_irq(struct cxl_afu *afu);
-void cxl_release_serr_irq(struct cxl_afu *afu);
+int cxl_native_register_psl_irq(struct cxl_afu *afu);
+void cxl_native_release_psl_irq(struct cxl_afu *afu);
+int cxl_native_register_psl_err_irq(struct cxl *adapter);
+void cxl_native_release_psl_err_irq(struct cxl *adapter);
+int cxl_native_register_serr_irq(struct cxl_afu *afu);
+void cxl_native_release_serr_irq(struct cxl_afu *afu);
 int afu_register_irqs(struct cxl_context *ctx, u32 count);
 void afu_release_irqs(struct cxl_context *ctx, void *cookie);
 void afu_irq_name_free(struct cxl_context *ctx);
-irqreturn_t cxl_slice_irq_err(int irq, void *data);
 
 int cxl_debugfs_init(void);
 void cxl_debugfs_exit(void);
@@ -692,6 +758,7 @@ void cxl_prefault(struct cxl_context *ct
 
 struct cxl *get_cxl_adapter(int num);
 int cxl_alloc_sst(struct cxl_context *ctx);
+void cxl_dump_debug_buffer(void *addr, size_t size);
 
 void init_cxl_native(void);
 
@@ -705,40 +772,55 @@ unsigned int cxl_map_irq(struct cxl *ada
 void cxl_unmap_irq(unsigned int virq, void *cookie);
 int __detach_context(struct cxl_context *ctx);
 
-/* This matches the layout of the H_COLLECT_CA_INT_INFO retbuf */
+/*
+ * This must match the layout of the H_COLLECT_CA_INT_INFO retbuf defined
+ * in PAPR.
+ * A word about endianness: a pointer to this structure is passed when
+ * calling the hcall. However, it is not a block of memory filled up by
+ * the hypervisor. The return values are found in registers, and copied
+ * one by one when returning from the hcall. See the end of the call to
+ * plpar_hcall9() in hvCall.S
+ * As a consequence:
+ * - we don't need to do any endianness conversion
+ * - the pid and tid are an exception. They are 32-bit values returned in
+ *   the same 64-bit register. So we do need to worry about byte ordering.
+ */
 struct cxl_irq_info {
 	u64 dsisr;
 	u64 dar;
 	u64 dsr;
+#ifndef CONFIG_CPU_LITTLE_ENDIAN
 	u32 pid;
 	u32 tid;
+#else
+	u32 tid;
+	u32 pid;
+#endif
 	u64 afu_err;
 	u64 errstat;
-	u64 padding[3]; /* to match the expected retbuf size for plpar_hcall9 */
+	u64 proc_handle;
+	u64 padding[2]; /* to match the expected retbuf size for plpar_hcall9 */
 };
 
 void cxl_assign_psn_space(struct cxl_context *ctx);
-int cxl_attach_process(struct cxl_context *ctx, bool kernel, u64 wed,
-			    u64 amr);
-int cxl_detach_process(struct cxl_context *ctx);
-
-int cxl_get_irq(struct cxl_afu *afu, struct cxl_irq_info *info);
-int cxl_ack_irq(struct cxl_context *ctx, u64 tfc, u64 psl_reset_mask);
+irqreturn_t cxl_irq(int irq, struct cxl_context *ctx, struct cxl_irq_info *irq_info);
+int cxl_register_one_irq(struct cxl *adapter, irq_handler_t handler,
+			void *cookie, irq_hw_number_t *dest_hwirq,
+			unsigned int *dest_virq, const char *name);
 
 int cxl_check_error(struct cxl_afu *afu);
 int cxl_afu_slbia(struct cxl_afu *afu);
 int cxl_tlb_slb_invalidate(struct cxl *adapter);
+int cxl_data_cache_flush(struct cxl *adapter);
 int cxl_afu_disable(struct cxl_afu *afu);
-int __cxl_afu_reset(struct cxl_afu *afu);
-int cxl_afu_check_and_enable(struct cxl_afu *afu);
 int cxl_psl_purge(struct cxl_afu *afu);
 
 void cxl_stop_trace(struct cxl *cxl);
 int cxl_pci_vphb_add(struct cxl_afu *afu);
-void cxl_pci_vphb_reconfigure(struct cxl_afu *afu);
 void cxl_pci_vphb_remove(struct cxl_afu *afu);
 
 extern struct pci_driver cxl_pci_driver;
+extern struct platform_driver cxl_of_driver;
 int afu_allocate_irqs(struct cxl_context *ctx, u32 count);
 
 int afu_open(struct inode *inode, struct file *file);
@@ -749,4 +831,62 @@ unsigned int afu_poll(struct file *file,
 ssize_t afu_read(struct file *file, char __user *buf, size_t count, loff_t *off);
 extern const struct file_operations afu_fops;
 
+struct cxl *cxl_guest_init_adapter(struct device_node *np, struct platform_device *dev);
+void cxl_guest_remove_adapter(struct cxl *adapter);
+int cxl_of_read_adapter_handle(struct cxl *adapter, struct device_node *np);
+int cxl_of_read_adapter_properties(struct cxl *adapter, struct device_node *np);
+ssize_t cxl_guest_read_adapter_vpd(struct cxl *adapter, void *buf, size_t len);
+ssize_t cxl_guest_read_afu_vpd(struct cxl_afu *afu, void *buf, size_t len);
+int cxl_guest_init_afu(struct cxl *adapter, int slice, struct device_node *afu_np);
+void cxl_guest_remove_afu(struct cxl_afu *afu);
+int cxl_of_read_afu_handle(struct cxl_afu *afu, struct device_node *afu_np);
+int cxl_of_read_afu_properties(struct cxl_afu *afu, struct device_node *afu_np);
+int cxl_guest_add_chardev(struct cxl *adapter);
+void cxl_guest_remove_chardev(struct cxl *adapter);
+void cxl_guest_reload_module(struct cxl *adapter);
+int cxl_of_probe(struct platform_device *pdev);
+
+struct cxl_backend_ops {
+	struct module *module;
+	int (*adapter_reset)(struct cxl *adapter);
+	int (*alloc_one_irq)(struct cxl *adapter);
+	void (*release_one_irq)(struct cxl *adapter, int hwirq);
+	int (*alloc_irq_ranges)(struct cxl_irq_ranges *irqs,
+				struct cxl *adapter, unsigned int num);
+	void (*release_irq_ranges)(struct cxl_irq_ranges *irqs,
+				struct cxl *adapter);
+	int (*setup_irq)(struct cxl *adapter, unsigned int hwirq,
+			unsigned int virq);
+	irqreturn_t (*handle_psl_slice_error)(struct cxl_context *ctx,
+					u64 dsisr, u64 errstat);
+	irqreturn_t (*psl_interrupt)(int irq, void *data);
+	int (*ack_irq)(struct cxl_context *ctx, u64 tfc, u64 psl_reset_mask);
+	void (*irq_wait)(struct cxl_context *ctx);
+	int (*attach_process)(struct cxl_context *ctx, bool kernel,
+			u64 wed, u64 amr);
+	int (*detach_process)(struct cxl_context *ctx);
+	bool (*support_attributes)(const char *attr_name, enum cxl_attrs type);
+	bool (*link_ok)(struct cxl *cxl, struct cxl_afu *afu);
+	void (*release_afu)(struct device *dev);
+	ssize_t (*afu_read_err_buffer)(struct cxl_afu *afu, char *buf,
+				loff_t off, size_t count);
+	int (*afu_check_and_enable)(struct cxl_afu *afu);
+	int (*afu_activate_mode)(struct cxl_afu *afu, int mode);
+	int (*afu_deactivate_mode)(struct cxl_afu *afu, int mode);
+	int (*afu_reset)(struct cxl_afu *afu);
+	int (*afu_cr_read8)(struct cxl_afu *afu, int cr_idx, u64 offset, u8 *val);
+	int (*afu_cr_read16)(struct cxl_afu *afu, int cr_idx, u64 offset, u16 *val);
+	int (*afu_cr_read32)(struct cxl_afu *afu, int cr_idx, u64 offset, u32 *val);
+	int (*afu_cr_read64)(struct cxl_afu *afu, int cr_idx, u64 offset, u64 *val);
+	int (*afu_cr_write8)(struct cxl_afu *afu, int cr_idx, u64 offset, u8 val);
+	int (*afu_cr_write16)(struct cxl_afu *afu, int cr_idx, u64 offset, u16 val);
+	int (*afu_cr_write32)(struct cxl_afu *afu, int cr_idx, u64 offset, u32 val);
+	ssize_t (*read_adapter_vpd)(struct cxl *adapter, void *buf, size_t count);
+};
+extern const struct cxl_backend_ops cxl_native_ops;
+extern const struct cxl_backend_ops cxl_guest_ops;
+extern const struct cxl_backend_ops *cxl_ops;
+
+/* check if the given pci_dev is on the the cxl vphb bus */
+bool cxl_pci_is_vphb_device(struct pci_dev *dev);
 #endif
--- zfcpdump-kernel-4.4.orig/drivers/misc/cxl/debugfs.c
+++ zfcpdump-kernel-4.4/drivers/misc/cxl/debugfs.c
@@ -118,6 +118,10 @@ void cxl_debugfs_afu_remove(struct cxl_a
 int __init cxl_debugfs_init(void)
 {
 	struct dentry *ent;
+
+	if (!cpu_has_feature(CPU_FTR_HVMODE))
+		return 0;
+
 	ent = debugfs_create_dir("cxl", NULL);
 	if (IS_ERR(ent))
 		return PTR_ERR(ent);
--- zfcpdump-kernel-4.4.orig/drivers/misc/cxl/fault.c
+++ zfcpdump-kernel-4.4/drivers/misc/cxl/fault.c
@@ -101,7 +101,7 @@ static void cxl_ack_ae(struct cxl_contex
 {
 	unsigned long flags;
 
-	cxl_ack_irq(ctx, CXL_PSL_TFC_An_AE, 0);
+	cxl_ops->ack_irq(ctx, CXL_PSL_TFC_An_AE, 0);
 
 	spin_lock_irqsave(&ctx->lock, flags);
 	ctx->pending_fault = true;
@@ -125,7 +125,7 @@ static int cxl_handle_segment_miss(struc
 	else {
 
 		mb(); /* Order seg table write to TFC MMIO write */
-		cxl_ack_irq(ctx, CXL_PSL_TFC_An_R, 0);
+		cxl_ops->ack_irq(ctx, CXL_PSL_TFC_An_R, 0);
 	}
 
 	return IRQ_HANDLED;
@@ -163,26 +163,108 @@ static void cxl_handle_page_fault(struct
 	local_irq_restore(flags);
 
 	pr_devel("Page fault successfully handled for pe: %i!\n", ctx->pe);
-	cxl_ack_irq(ctx, CXL_PSL_TFC_An_R, 0);
+	cxl_ops->ack_irq(ctx, CXL_PSL_TFC_An_R, 0);
 }
 
+/*
+ * Returns the mm_struct corresponding to the context ctx via ctx->pid
+ * In case the task has exited we use the task group leader accessible
+ * via ctx->glpid to find the next task in the thread group that has a
+ * valid  mm_struct associated with it. If a task with valid mm_struct
+ * is found the ctx->pid is updated to use the task struct for subsequent
+ * translations. In case no valid mm_struct is found in the task group to
+ * service the fault a NULL is returned.
+ */
+static struct mm_struct *get_mem_context(struct cxl_context *ctx)
+{
+	struct task_struct *task = NULL;
+	struct mm_struct *mm = NULL;
+	struct pid *old_pid = ctx->pid;
+
+	if (old_pid == NULL) {
+		pr_warn("%s: Invalid context for pe=%d\n",
+			 __func__, ctx->pe);
+		return NULL;
+	}
+
+	task = get_pid_task(old_pid, PIDTYPE_PID);
+
+	/*
+	 * pid_alive may look racy but this saves us from costly
+	 * get_task_mm when the task is a zombie. In worst case
+	 * we may think a task is alive, which is about to die
+	 * but get_task_mm will return NULL.
+	 */
+	if (task != NULL && pid_alive(task))
+		mm = get_task_mm(task);
+
+	/* release the task struct that was taken earlier */
+	if (task)
+		put_task_struct(task);
+	else
+		pr_devel("%s: Context owning pid=%i for pe=%i dead\n",
+			__func__, pid_nr(old_pid), ctx->pe);
+
+	/*
+	 * If we couldn't find the mm context then use the group
+	 * leader to iterate over the task group and find a task
+	 * that gives us mm_struct.
+	 */
+	if (unlikely(mm == NULL && ctx->glpid != NULL)) {
+
+		rcu_read_lock();
+		task = pid_task(ctx->glpid, PIDTYPE_PID);
+		if (task)
+			do {
+				mm = get_task_mm(task);
+				if (mm) {
+					ctx->pid = get_task_pid(task,
+								PIDTYPE_PID);
+					break;
+				}
+				task = next_thread(task);
+			} while (task && !thread_group_leader(task));
+		rcu_read_unlock();
+
+		/* check if we switched pid */
+		if (ctx->pid != old_pid) {
+			if (mm)
+				pr_devel("%s:pe=%i switch pid %i->%i\n",
+					 __func__, ctx->pe, pid_nr(old_pid),
+					 pid_nr(ctx->pid));
+			else
+				pr_devel("%s:Cannot find mm for pid=%i\n",
+					 __func__, pid_nr(old_pid));
+
+			/* drop the reference to older pid */
+			put_pid(old_pid);
+		}
+	}
+
+	return mm;
+}
+
+
+
 void cxl_handle_fault(struct work_struct *fault_work)
 {
 	struct cxl_context *ctx =
 		container_of(fault_work, struct cxl_context, fault_work);
 	u64 dsisr = ctx->dsisr;
 	u64 dar = ctx->dar;
-	struct task_struct *task = NULL;
 	struct mm_struct *mm = NULL;
 
-	if (cxl_p2n_read(ctx->afu, CXL_PSL_DSISR_An) != dsisr ||
-	    cxl_p2n_read(ctx->afu, CXL_PSL_DAR_An) != dar ||
-	    cxl_p2n_read(ctx->afu, CXL_PSL_PEHandle_An) != ctx->pe) {
-		/* Most likely explanation is harmless - a dedicated process
-		 * has detached and these were cleared by the PSL purge, but
-		 * warn about it just in case */
-		dev_notice(&ctx->afu->dev, "cxl_handle_fault: Translation fault regs changed\n");
-		return;
+	if (cpu_has_feature(CPU_FTR_HVMODE)) {
+		if (cxl_p2n_read(ctx->afu, CXL_PSL_DSISR_An) != dsisr ||
+		    cxl_p2n_read(ctx->afu, CXL_PSL_DAR_An) != dar ||
+		    cxl_p2n_read(ctx->afu, CXL_PSL_PEHandle_An) != ctx->pe) {
+			/* Most likely explanation is harmless - a dedicated
+			 * process has detached and these were cleared by the
+			 * PSL purge, but warn about it just in case
+			 */
+			dev_notice(&ctx->afu->dev, "cxl_handle_fault: Translation fault regs changed\n");
+			return;
+		}
 	}
 
 	/* Early return if the context is being / has been detached */
@@ -195,17 +277,17 @@ void cxl_handle_fault(struct work_struct
 		"DSISR: %#llx DAR: %#llx\n", ctx->pe, dsisr, dar);
 
 	if (!ctx->kernel) {
-		if (!(task = get_pid_task(ctx->pid, PIDTYPE_PID))) {
-			pr_devel("cxl_handle_fault unable to get task %i\n",
-				 pid_nr(ctx->pid));
+
+		mm = get_mem_context(ctx);
+		/* indicates all the thread in task group have exited */
+		if (mm == NULL) {
+			pr_devel("%s: unable to get mm for pe=%d pid=%i\n",
+				 __func__, ctx->pe, pid_nr(ctx->pid));
 			cxl_ack_ae(ctx);
 			return;
-		}
-		if (!(mm = get_task_mm(task))) {
-			pr_devel("cxl_handle_fault unable to get mm %i\n",
-				 pid_nr(ctx->pid));
-			cxl_ack_ae(ctx);
-			goto out;
+		} else {
+			pr_devel("Handling page fault for pe=%d pid=%i\n",
+				 ctx->pe, pid_nr(ctx->pid));
 		}
 	}
 
@@ -218,33 +300,22 @@ void cxl_handle_fault(struct work_struct
 
 	if (mm)
 		mmput(mm);
-out:
-	if (task)
-		put_task_struct(task);
 }
 
 static void cxl_prefault_one(struct cxl_context *ctx, u64 ea)
 {
-	int rc;
-	struct task_struct *task;
 	struct mm_struct *mm;
 
-	if (!(task = get_pid_task(ctx->pid, PIDTYPE_PID))) {
-		pr_devel("cxl_prefault_one unable to get task %i\n",
-			 pid_nr(ctx->pid));
-		return;
-	}
-	if (!(mm = get_task_mm(task))) {
+	mm = get_mem_context(ctx);
+	if (mm == NULL) {
 		pr_devel("cxl_prefault_one unable to get mm %i\n",
 			 pid_nr(ctx->pid));
-		put_task_struct(task);
 		return;
 	}
 
-	rc = cxl_fault_segment(ctx, mm, ea);
+	cxl_fault_segment(ctx, mm, ea);
 
 	mmput(mm);
-	put_task_struct(task);
 }
 
 static u64 next_segment(u64 ea, u64 vsid)
@@ -263,18 +334,13 @@ static void cxl_prefault_vma(struct cxl_
 	struct copro_slb slb;
 	struct vm_area_struct *vma;
 	int rc;
-	struct task_struct *task;
 	struct mm_struct *mm;
 
-	if (!(task = get_pid_task(ctx->pid, PIDTYPE_PID))) {
-		pr_devel("cxl_prefault_vma unable to get task %i\n",
-			 pid_nr(ctx->pid));
-		return;
-	}
-	if (!(mm = get_task_mm(task))) {
+	mm = get_mem_context(ctx);
+	if (mm == NULL) {
 		pr_devel("cxl_prefault_vm unable to get mm %i\n",
 			 pid_nr(ctx->pid));
-		goto out1;
+		return;
 	}
 
 	down_read(&mm->mmap_sem);
@@ -295,8 +361,6 @@ static void cxl_prefault_vma(struct cxl_
 	up_read(&mm->mmap_sem);
 
 	mmput(mm);
-out1:
-	put_task_struct(task);
 }
 
 void cxl_prefault(struct cxl_context *ctx, u64 wed)
--- zfcpdump-kernel-4.4.orig/drivers/misc/cxl/file.c
+++ zfcpdump-kernel-4.4/drivers/misc/cxl/file.c
@@ -26,9 +26,7 @@
 #include "trace.h"
 
 #define CXL_NUM_MINORS 256 /* Total to reserve */
-#define CXL_DEV_MINORS 13   /* 1 control + 4 AFUs * 3 (dedicated/master/shared) */
 
-#define CXL_CARD_MINOR(adapter) (adapter->adapter_num * CXL_DEV_MINORS)
 #define CXL_AFU_MINOR_D(afu) (CXL_CARD_MINOR(afu->adapter) + 1 + (3 * afu->slice))
 #define CXL_AFU_MINOR_M(afu) (CXL_AFU_MINOR_D(afu) + 1)
 #define CXL_AFU_MINOR_S(afu) (CXL_AFU_MINOR_D(afu) + 2)
@@ -36,7 +34,6 @@
 #define CXL_AFU_MKDEV_M(afu) MKDEV(MAJOR(cxl_dev), CXL_AFU_MINOR_M(afu))
 #define CXL_AFU_MKDEV_S(afu) MKDEV(MAJOR(cxl_dev), CXL_AFU_MINOR_S(afu))
 
-#define CXL_DEVT_ADAPTER(dev) (MINOR(dev) / CXL_DEV_MINORS)
 #define CXL_DEVT_AFU(dev) ((MINOR(dev) % CXL_DEV_MINORS - 1) / 3)
 
 #define CXL_DEVT_IS_CARD(dev) (MINOR(dev) % CXL_DEV_MINORS == 0)
@@ -67,13 +64,19 @@ static int __afu_open(struct inode *inod
 		spin_unlock(&adapter->afu_list_lock);
 		goto err_put_adapter;
 	}
-	get_device(&afu->dev);
+
+	/*
+	 * taking a ref to the afu so that it doesn't go away
+	 * for rest of the function. This ref is released before
+	 * we return.
+	 */
+	cxl_afu_get(afu);
 	spin_unlock(&adapter->afu_list_lock);
 
 	if (!afu->current_mode)
 		goto err_put_afu;
 
-	if (!cxl_adapter_link_ok(adapter)) {
+	if (!cxl_ops->link_ok(adapter, afu)) {
 		rc = -EIO;
 		goto err_put_afu;
 	}
@@ -90,13 +93,12 @@ static int __afu_open(struct inode *inod
 	file->private_data = ctx;
 	cxl_ctx_get();
 
-	/* Our ref on the AFU will now hold the adapter */
-	put_device(&adapter->dev);
-
-	return 0;
+	/* indicate success */
+	rc = 0;
 
 err_put_afu:
-	put_device(&afu->dev);
+	/* release the ref taken earlier */
+	cxl_afu_put(afu);
 err_put_adapter:
 	put_device(&adapter->dev);
 	return rc;
@@ -131,8 +133,6 @@ int afu_release(struct inode *inode, str
 		mutex_unlock(&ctx->mapping_lock);
 	}
 
-	put_device(&ctx->afu->dev);
-
 	/*
 	 * At this this point all bottom halfs have finished and we should be
 	 * getting no more IRQs from the hardware for this context.  Once it's
@@ -198,13 +198,17 @@ static long afu_ioctl_start_work(struct
 	 * where a process (master, some daemon, etc) has opened the chardev on
 	 * behalf of another process, so the AFU's mm gets bound to the process
 	 * that performs this ioctl and not the process that opened the file.
+	 * Also we grab the PID of the group leader so that if the task that
+	 * has performed the attach operation exits the mm context of the
+	 * process is still accessible.
 	 */
-	ctx->pid = get_pid(get_task_pid(current, PIDTYPE_PID));
+	ctx->pid = get_task_pid(current, PIDTYPE_PID);
+	ctx->glpid = get_task_pid(current->group_leader, PIDTYPE_PID);
 
 	trace_cxl_attach(ctx, work.work_element_descriptor, work.num_interrupts, amr);
 
-	if ((rc = cxl_attach_process(ctx, false, work.work_element_descriptor,
-				     amr))) {
+	if ((rc = cxl_ops->attach_process(ctx, false, work.work_element_descriptor,
+							amr))) {
 		afu_release_irqs(ctx, ctx);
 		goto out;
 	}
@@ -215,12 +219,13 @@ out:
 	mutex_unlock(&ctx->status_mutex);
 	return rc;
 }
+
 static long afu_ioctl_process_element(struct cxl_context *ctx,
 				      int __user *upe)
 {
 	pr_devel("%s: pe: %i\n", __func__, ctx->pe);
 
-	if (copy_to_user(upe, &ctx->pe, sizeof(__u32)))
+	if (copy_to_user(upe, &ctx->external_pe, sizeof(__u32)))
 		return -EFAULT;
 
 	return 0;
@@ -252,7 +257,7 @@ long afu_ioctl(struct file *file, unsign
 	if (ctx->status == CLOSED)
 		return -EIO;
 
-	if (!cxl_adapter_link_ok(ctx->afu->adapter))
+	if (!cxl_ops->link_ok(ctx->afu->adapter, ctx->afu))
 		return -EIO;
 
 	pr_devel("afu_ioctl\n");
@@ -282,7 +287,7 @@ int afu_mmap(struct file *file, struct v
 	if (ctx->status != STARTED)
 		return -EIO;
 
-	if (!cxl_adapter_link_ok(ctx->afu->adapter))
+	if (!cxl_ops->link_ok(ctx->afu->adapter, ctx->afu))
 		return -EIO;
 
 	return cxl_context_iomap(ctx, vm);
@@ -329,7 +334,7 @@ ssize_t afu_read(struct file *file, char
 	int rc;
 	DEFINE_WAIT(wait);
 
-	if (!cxl_adapter_link_ok(ctx->afu->adapter))
+	if (!cxl_ops->link_ok(ctx->afu->adapter, ctx->afu))
 		return -EIO;
 
 	if (count < CXL_READ_MIN_SIZE)
@@ -342,7 +347,7 @@ ssize_t afu_read(struct file *file, char
 		if (ctx_event_pending(ctx))
 			break;
 
-		if (!cxl_adapter_link_ok(ctx->afu->adapter)) {
+		if (!cxl_ops->link_ok(ctx->afu->adapter, ctx->afu)) {
 			rc = -EIO;
 			goto out;
 		}
@@ -438,7 +443,8 @@ static const struct file_operations afu_
 
 static char *cxl_devnode(struct device *dev, umode_t *mode)
 {
-	if (CXL_DEVT_IS_CARD(dev->devt)) {
+	if (cpu_has_feature(CPU_FTR_HVMODE) &&
+	    CXL_DEVT_IS_CARD(dev->devt)) {
 		/*
 		 * These minor numbers will eventually be used to program the
 		 * PSL and AFUs once we have dynamic reprogramming support
@@ -539,6 +545,11 @@ int cxl_register_adapter(struct cxl *ada
 	return device_register(&adapter->dev);
 }
 
+dev_t cxl_get_dev(void)
+{
+	return cxl_dev;
+}
+
 int __init cxl_file_init(void)
 {
 	int rc;
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/misc/cxl/flash.c
@@ -0,0 +1,538 @@
+#include <linux/kernel.h>
+#include <linux/fs.h>
+#include <linux/semaphore.h>
+#include <linux/slab.h>
+#include <linux/uaccess.h>
+#include <asm/rtas.h>
+
+#include "cxl.h"
+#include "hcalls.h"
+
+#define DOWNLOAD_IMAGE 1
+#define VALIDATE_IMAGE 2
+
+struct ai_header {
+	u16 version;
+	u8  reserved0[6];
+	u16 vendor;
+	u16 device;
+	u16 subsystem_vendor;
+	u16 subsystem;
+	u64 image_offset;
+	u64 image_length;
+	u8  reserved1[96];
+};
+
+static struct semaphore sem;
+unsigned long *buffer[CXL_AI_MAX_ENTRIES];
+struct sg_list *le;
+static u64 continue_token;
+static unsigned int transfer;
+
+struct update_props_workarea {
+	__be32 phandle;
+	__be32 state;
+	__be64 reserved;
+	__be32 nprops;
+} __packed;
+
+struct update_nodes_workarea {
+	__be32 state;
+	__be64 unit_address;
+	__be32 reserved;
+} __packed;
+
+#define DEVICE_SCOPE 3
+#define NODE_ACTION_MASK	0xff000000
+#define NODE_COUNT_MASK		0x00ffffff
+#define OPCODE_DELETE	0x01000000
+#define OPCODE_UPDATE	0x02000000
+#define OPCODE_ADD	0x03000000
+
+static int rcall(int token, char *buf, s32 scope)
+{
+	int rc;
+
+	spin_lock(&rtas_data_buf_lock);
+
+	memcpy(rtas_data_buf, buf, RTAS_DATA_BUF_SIZE);
+	rc = rtas_call(token, 2, 1, NULL, rtas_data_buf, scope);
+	memcpy(buf, rtas_data_buf, RTAS_DATA_BUF_SIZE);
+
+	spin_unlock(&rtas_data_buf_lock);
+	return rc;
+}
+
+static int update_property(struct device_node *dn, const char *name,
+			   u32 vd, char *value)
+{
+	struct property *new_prop;
+	u32 *val;
+	int rc;
+
+	new_prop = kzalloc(sizeof(*new_prop), GFP_KERNEL);
+	if (!new_prop)
+		return -ENOMEM;
+
+	new_prop->name = kstrdup(name, GFP_KERNEL);
+	if (!new_prop->name) {
+		kfree(new_prop);
+		return -ENOMEM;
+	}
+
+	new_prop->length = vd;
+	new_prop->value = kzalloc(new_prop->length, GFP_KERNEL);
+	if (!new_prop->value) {
+		kfree(new_prop->name);
+		kfree(new_prop);
+		return -ENOMEM;
+	}
+	memcpy(new_prop->value, value, vd);
+
+	val = (u32 *)new_prop->value;
+	rc = cxl_update_properties(dn, new_prop);
+	pr_devel("%s: update property (%s, length: %i, value: %#x)\n",
+		  dn->name, name, vd, be32_to_cpu(*val));
+
+	if (rc) {
+		kfree(new_prop->name);
+		kfree(new_prop->value);
+		kfree(new_prop);
+	}
+	return rc;
+}
+
+static int update_node(__be32 phandle, s32 scope)
+{
+	struct update_props_workarea *upwa;
+	struct device_node *dn;
+	int i, rc, ret;
+	char *prop_data;
+	char *buf;
+	int token;
+	u32 nprops;
+	u32 vd;
+
+	token = rtas_token("ibm,update-properties");
+	if (token == RTAS_UNKNOWN_SERVICE)
+		return -EINVAL;
+
+	buf = kzalloc(RTAS_DATA_BUF_SIZE, GFP_KERNEL);
+	if (!buf)
+		return -ENOMEM;
+
+	dn = of_find_node_by_phandle(be32_to_cpu(phandle));
+	if (!dn) {
+		kfree(buf);
+		return -ENOENT;
+	}
+
+	upwa = (struct update_props_workarea *)&buf[0];
+	upwa->phandle = phandle;
+	do {
+		rc = rcall(token, buf, scope);
+		if (rc < 0)
+			break;
+
+		prop_data = buf + sizeof(*upwa);
+		nprops = be32_to_cpu(upwa->nprops);
+
+		if (*prop_data == 0) {
+			prop_data++;
+			vd = be32_to_cpu(*(__be32 *)prop_data);
+			prop_data += vd + sizeof(vd);
+			nprops--;
+		}
+
+		for (i = 0; i < nprops; i++) {
+			char *prop_name;
+
+			prop_name = prop_data;
+			prop_data += strlen(prop_name) + 1;
+			vd = be32_to_cpu(*(__be32 *)prop_data);
+			prop_data += sizeof(vd);
+
+			if ((vd != 0x00000000) && (vd != 0x80000000)) {
+				ret = update_property(dn, prop_name, vd,
+						prop_data);
+				if (ret)
+					pr_err("cxl: Could not update property %s - %i\n",
+					       prop_name, ret);
+
+				prop_data += vd;
+			}
+		}
+	} while (rc == 1);
+
+	of_node_put(dn);
+	kfree(buf);
+	return rc;
+}
+
+static int update_devicetree(struct cxl *adapter, s32 scope)
+{
+	struct update_nodes_workarea *unwa;
+	u32 action, node_count;
+	int token, rc, i;
+	__be32 *data, drc_index, phandle;
+	char *buf;
+
+	token = rtas_token("ibm,update-nodes");
+	if (token == RTAS_UNKNOWN_SERVICE)
+		return -EINVAL;
+
+	buf = kzalloc(RTAS_DATA_BUF_SIZE, GFP_KERNEL);
+	if (!buf)
+		return -ENOMEM;
+
+	unwa = (struct update_nodes_workarea *)&buf[0];
+	unwa->unit_address = cpu_to_be64(adapter->guest->handle);
+	do {
+		rc = rcall(token, buf, scope);
+		if (rc && rc != 1)
+			break;
+
+		data = (__be32 *)buf + 4;
+		while (be32_to_cpu(*data) & NODE_ACTION_MASK) {
+			action = be32_to_cpu(*data) & NODE_ACTION_MASK;
+			node_count = be32_to_cpu(*data) & NODE_COUNT_MASK;
+			pr_devel("device reconfiguration - action: %#x, nodes: %#x\n",
+				 action, node_count);
+			data++;
+
+			for (i = 0; i < node_count; i++) {
+				phandle = *data++;
+
+				switch (action) {
+				case OPCODE_DELETE:
+					/* nothing to do */
+					break;
+				case OPCODE_UPDATE:
+					update_node(phandle, scope);
+					break;
+				case OPCODE_ADD:
+					/* nothing to do, just move pointer */
+					drc_index = *data++;
+					break;
+				}
+			}
+		}
+	} while (rc == 1);
+
+	kfree(buf);
+	return 0;
+}
+
+static int handle_image(struct cxl *adapter, int operation,
+			long (*fct)(u64, u64, u64, u64 *),
+			struct cxl_adapter_image *ai)
+{
+	size_t mod, s_copy, len_chunk = 0;
+	struct ai_header *header = NULL;
+	unsigned int entries = 0, i;
+	void *dest, *from;
+	int rc = 0, need_header;
+
+	/* base adapter image header */
+	need_header = (ai->flags & CXL_AI_NEED_HEADER);
+	if (need_header) {
+		header = kzalloc(sizeof(struct ai_header), GFP_KERNEL);
+		if (!header)
+			return -ENOMEM;
+		header->version = cpu_to_be16(1);
+		header->vendor = cpu_to_be16(adapter->guest->vendor);
+		header->device = cpu_to_be16(adapter->guest->device);
+		header->subsystem_vendor = cpu_to_be16(adapter->guest->subsystem_vendor);
+		header->subsystem = cpu_to_be16(adapter->guest->subsystem);
+		header->image_offset = cpu_to_be64(CXL_AI_HEADER_SIZE);
+		header->image_length = cpu_to_be64(ai->len_image);
+	}
+
+	/* number of entries in the list */
+	len_chunk = ai->len_data;
+	if (need_header)
+		len_chunk += CXL_AI_HEADER_SIZE;
+
+	entries = len_chunk / CXL_AI_BUFFER_SIZE;
+	mod = len_chunk % CXL_AI_BUFFER_SIZE;
+	if (mod)
+		entries++;
+
+	if (entries > CXL_AI_MAX_ENTRIES) {
+		rc = -EINVAL;
+		goto err;
+	}
+
+	/*          < -- MAX_CHUNK_SIZE = 4096 * 256 = 1048576 bytes -->
+	 * chunk 0  ----------------------------------------------------
+	 *          | header   |  data                                 |
+	 *          ----------------------------------------------------
+	 * chunk 1  ----------------------------------------------------
+	 *          | data                                             |
+	 *          ----------------------------------------------------
+	 * ....
+	 * chunk n  ----------------------------------------------------
+	 *          | data                                             |
+	 *          ----------------------------------------------------
+	 */
+	from = (void *) ai->data;
+	for (i = 0; i < entries; i++) {
+		dest = buffer[i];
+		s_copy = CXL_AI_BUFFER_SIZE;
+
+		if ((need_header) && (i == 0)) {
+			/* add adapter image header */
+			memcpy(buffer[i], header, sizeof(struct ai_header));
+			s_copy = CXL_AI_BUFFER_SIZE - CXL_AI_HEADER_SIZE;
+			dest += CXL_AI_HEADER_SIZE; /* image offset */
+		}
+		if ((i == (entries - 1)) && mod)
+			s_copy = mod;
+
+		/* copy data */
+		if (copy_from_user(dest, from, s_copy))
+			goto err;
+
+		/* fill in the list */
+		le[i].phys_addr = cpu_to_be64(virt_to_phys(buffer[i]));
+		le[i].len = cpu_to_be64(CXL_AI_BUFFER_SIZE);
+		if ((i == (entries - 1)) && mod)
+			le[i].len = cpu_to_be64(mod);
+		from += s_copy;
+	}
+	pr_devel("%s (op: %i, need header: %i, entries: %i, token: %#llx)\n",
+		 __func__, operation, need_header, entries, continue_token);
+
+	/*
+	 * download/validate the adapter image to the coherent
+	 * platform facility
+	 */
+	rc = fct(adapter->guest->handle, virt_to_phys(le), entries,
+		&continue_token);
+	if (rc == 0) /* success of download/validation operation */
+		continue_token = 0;
+
+err:
+	kfree(header);
+
+	return rc;
+}
+
+static int transfer_image(struct cxl *adapter, int operation,
+			struct cxl_adapter_image *ai)
+{
+	int rc = 0;
+	int afu;
+
+	switch (operation) {
+	case DOWNLOAD_IMAGE:
+		rc = handle_image(adapter, operation,
+				&cxl_h_download_adapter_image, ai);
+		if (rc < 0) {
+			pr_devel("resetting adapter\n");
+			cxl_h_reset_adapter(adapter->guest->handle);
+		}
+		return rc;
+
+	case VALIDATE_IMAGE:
+		rc = handle_image(adapter, operation,
+				&cxl_h_validate_adapter_image, ai);
+		if (rc < 0) {
+			pr_devel("resetting adapter\n");
+			cxl_h_reset_adapter(adapter->guest->handle);
+			return rc;
+		}
+		if (rc == 0) {
+			pr_devel("remove curent afu\n");
+			for (afu = 0; afu < adapter->slices; afu++)
+				cxl_guest_remove_afu(adapter->afu[afu]);
+
+			pr_devel("resetting adapter\n");
+			cxl_h_reset_adapter(adapter->guest->handle);
+
+			/* The entire image has now been
+			 * downloaded and the validation has
+			 * been successfully performed.
+			 * After that, the partition should call
+			 * ibm,update-nodes and
+			 * ibm,update-properties to receive the
+			 * current configuration
+			 */
+			rc = update_devicetree(adapter, DEVICE_SCOPE);
+			transfer = 1;
+		}
+		return rc;
+	}
+
+	return -EINVAL;
+}
+
+static long ioctl_transfer_image(struct cxl *adapter, int operation,
+				struct cxl_adapter_image __user *uai)
+{
+	struct cxl_adapter_image ai;
+
+	pr_devel("%s\n", __func__);
+
+	if (copy_from_user(&ai, uai, sizeof(struct cxl_adapter_image)))
+		return -EFAULT;
+
+	/*
+	 * Make sure reserved fields and bits are set to 0
+	 */
+	if (ai.reserved1 || ai.reserved2 || ai.reserved3 || ai.reserved4 ||
+		(ai.flags & ~CXL_AI_ALL))
+		return -EINVAL;
+
+	return transfer_image(adapter, operation, &ai);
+}
+
+static int device_open(struct inode *inode, struct file *file)
+{
+	int adapter_num = CXL_DEVT_ADAPTER(inode->i_rdev);
+	struct cxl *adapter;
+	int rc = 0, i;
+
+	pr_devel("in %s\n", __func__);
+
+	BUG_ON(sizeof(struct ai_header) != CXL_AI_HEADER_SIZE);
+
+	/* Allows one process to open the device by using a semaphore */
+	if (down_interruptible(&sem) != 0)
+		return -EPERM;
+
+	if (!(adapter = get_cxl_adapter(adapter_num)))
+		return -ENODEV;
+
+	file->private_data = adapter;
+	continue_token = 0;
+	transfer = 0;
+
+	for (i = 0; i < CXL_AI_MAX_ENTRIES; i++)
+		buffer[i] = NULL;
+
+	/* aligned buffer containing list entries which describes up to
+	 * 1 megabyte of data (256 entries of 4096 bytes each)
+	 *  Logical real address of buffer 0  -  Buffer 0 length in bytes
+	 *  Logical real address of buffer 1  -  Buffer 1 length in bytes
+	 *  Logical real address of buffer 2  -  Buffer 2 length in bytes
+	 *  ....
+	 *  ....
+	 *  Logical real address of buffer N  -  Buffer N length in bytes
+	 */
+	le = (struct sg_list *)get_zeroed_page(GFP_KERNEL);
+	if (!le) {
+		rc = -ENOMEM;
+		goto err;
+	}
+
+	for (i = 0; i < CXL_AI_MAX_ENTRIES; i++) {
+		buffer[i] = (unsigned long *)get_zeroed_page(GFP_KERNEL);
+		if (!buffer[i]) {
+			rc = -ENOMEM;
+			goto err1;
+		}
+	}
+
+	return 0;
+
+err1:
+	for (i = 0; i < CXL_AI_MAX_ENTRIES; i++) {
+		if (buffer[i])
+			free_page((unsigned long) buffer[i]);
+	}
+
+	if (le)
+		free_page((unsigned long) le);
+err:
+	put_device(&adapter->dev);
+
+	return rc;
+}
+
+static long device_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+	struct cxl *adapter = file->private_data;
+
+	pr_devel("in %s\n", __func__);
+
+	if (cmd == CXL_IOCTL_DOWNLOAD_IMAGE)
+		return ioctl_transfer_image(adapter,
+					DOWNLOAD_IMAGE,
+					(struct cxl_adapter_image __user *)arg);
+	else if (cmd == CXL_IOCTL_VALIDATE_IMAGE)
+		return ioctl_transfer_image(adapter,
+					VALIDATE_IMAGE,
+					(struct cxl_adapter_image __user *)arg);
+	else
+		return -EINVAL;
+}
+
+static long device_compat_ioctl(struct file *file, unsigned int cmd,
+				unsigned long arg)
+{
+	return device_ioctl(file, cmd, arg);
+}
+
+static int device_close(struct inode *inode, struct file *file)
+{
+	struct cxl *adapter = file->private_data;
+	int i;
+
+	pr_devel("in %s\n", __func__);
+
+	for (i = 0; i < CXL_AI_MAX_ENTRIES; i++) {
+		if (buffer[i])
+			free_page((unsigned long) buffer[i]);
+	}
+
+	if (le)
+		free_page((unsigned long) le);
+
+	up(&sem);
+	put_device(&adapter->dev);
+	continue_token = 0;
+
+	/* reload the module */
+	if (transfer)
+		cxl_guest_reload_module(adapter);
+	else {
+		pr_devel("resetting adapter\n");
+		cxl_h_reset_adapter(adapter->guest->handle);
+	}
+
+	transfer = 0;
+	return 0;
+}
+
+static const struct file_operations fops = {
+	.owner		= THIS_MODULE,
+	.open		= device_open,
+	.unlocked_ioctl	= device_ioctl,
+	.compat_ioctl	= device_compat_ioctl,
+	.release	= device_close,
+};
+
+void cxl_guest_remove_chardev(struct cxl *adapter)
+{
+	cdev_del(&adapter->guest->cdev);
+}
+
+int cxl_guest_add_chardev(struct cxl *adapter)
+{
+	dev_t devt;
+	int rc;
+
+	devt = MKDEV(MAJOR(cxl_get_dev()), CXL_CARD_MINOR(adapter));
+	cdev_init(&adapter->guest->cdev, &fops);
+	if ((rc = cdev_add(&adapter->guest->cdev, devt, 1))) {
+		dev_err(&adapter->dev,
+			"Unable to add chardev on adapter (card%i): %i\n",
+			adapter->adapter_num, rc);
+		goto err;
+	}
+	adapter->dev.devt = devt;
+	sema_init(&sem, 1);
+err:
+	return rc;
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/misc/cxl/guest.c
@@ -0,0 +1,1177 @@
+/*
+ * Copyright 2015 IBM Corp.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/spinlock.h>
+#include <linux/uaccess.h>
+#include <linux/delay.h>
+
+#include "cxl.h"
+#include "hcalls.h"
+#include "trace.h"
+
+#define CXL_ERROR_DETECTED_EVENT	1
+#define CXL_SLOT_RESET_EVENT		2
+#define CXL_RESUME_EVENT		3
+
+static void pci_error_handlers(struct cxl_afu *afu,
+				int bus_error_event,
+				pci_channel_state_t state)
+{
+	struct pci_dev *afu_dev;
+
+	if (afu->phb == NULL)
+		return;
+
+	list_for_each_entry(afu_dev, &afu->phb->bus->devices, bus_list) {
+		if (!afu_dev->driver)
+			continue;
+
+		switch (bus_error_event) {
+		case CXL_ERROR_DETECTED_EVENT:
+			afu_dev->error_state = state;
+
+			if (afu_dev->driver->err_handler &&
+			    afu_dev->driver->err_handler->error_detected)
+				afu_dev->driver->err_handler->error_detected(afu_dev, state);
+		break;
+		case CXL_SLOT_RESET_EVENT:
+			afu_dev->error_state = state;
+
+			if (afu_dev->driver->err_handler &&
+			    afu_dev->driver->err_handler->slot_reset)
+				afu_dev->driver->err_handler->slot_reset(afu_dev);
+		break;
+		case CXL_RESUME_EVENT:
+			if (afu_dev->driver->err_handler &&
+			    afu_dev->driver->err_handler->resume)
+				afu_dev->driver->err_handler->resume(afu_dev);
+		break;
+		}
+	}
+}
+
+static irqreturn_t guest_handle_psl_slice_error(struct cxl_context *ctx, u64 dsisr,
+					u64 errstat)
+{
+	pr_devel("in %s\n", __func__);
+	dev_crit(&ctx->afu->dev, "PSL ERROR STATUS: 0x%.16llx\n", errstat);
+
+	return cxl_ops->ack_irq(ctx, 0, errstat);
+}
+
+static ssize_t guest_collect_vpd(struct cxl *adapter, struct cxl_afu *afu,
+			void *buf, size_t len)
+{
+	unsigned int entries, mod;
+	unsigned long **vpd_buf = NULL;
+	struct sg_list *le;
+	int rc = 0, i, tocopy;
+	u64 out = 0;
+
+	if (buf == NULL)
+		return -EINVAL;
+
+	/* number of entries in the list */
+	entries = len / SG_BUFFER_SIZE;
+	mod = len % SG_BUFFER_SIZE;
+	if (mod)
+		entries++;
+
+	if (entries > SG_MAX_ENTRIES) {
+		entries = SG_MAX_ENTRIES;
+		len = SG_MAX_ENTRIES * SG_BUFFER_SIZE;
+		mod = 0;
+	}
+
+	vpd_buf = kzalloc(entries * sizeof(unsigned long *), GFP_KERNEL);
+	if (!vpd_buf)
+		return -ENOMEM;
+
+	le = (struct sg_list *)get_zeroed_page(GFP_KERNEL);
+	if (!le) {
+		rc = -ENOMEM;
+		goto err1;
+	}
+
+	for (i = 0; i < entries; i++) {
+		vpd_buf[i] = (unsigned long *)get_zeroed_page(GFP_KERNEL);
+		if (!vpd_buf[i]) {
+			rc = -ENOMEM;
+			goto err2;
+		}
+		le[i].phys_addr = cpu_to_be64(virt_to_phys(vpd_buf[i]));
+		le[i].len = cpu_to_be64(SG_BUFFER_SIZE);
+		if ((i == (entries - 1)) && mod)
+			le[i].len = cpu_to_be64(mod);
+	}
+
+	if (adapter)
+		rc = cxl_h_collect_vpd_adapter(adapter->guest->handle,
+					virt_to_phys(le), entries, &out);
+	else
+		rc = cxl_h_collect_vpd(afu->guest->handle, 0,
+				virt_to_phys(le), entries, &out);
+	pr_devel("length of available (entries: %i), vpd: %#llx\n",
+		entries, out);
+
+	if (!rc) {
+		/*
+		 * hcall returns in 'out' the size of available VPDs.
+		 * It fills the buffer with as much data as possible.
+		 */
+		if (out < len)
+			len = out;
+		rc = len;
+		if (out) {
+			for (i = 0; i < entries; i++) {
+				if (len < SG_BUFFER_SIZE)
+					tocopy = len;
+				else
+					tocopy = SG_BUFFER_SIZE;
+				memcpy(buf, vpd_buf[i], tocopy);
+				buf += tocopy;
+				len -= tocopy;
+			}
+		}
+	}
+err2:
+	for (i = 0; i < entries; i++) {
+		if (vpd_buf[i])
+			free_page((unsigned long) vpd_buf[i]);
+	}
+	free_page((unsigned long) le);
+err1:
+	kfree(vpd_buf);
+	return rc;
+}
+
+static int guest_get_irq_info(struct cxl_context *ctx, struct cxl_irq_info *info)
+{
+	return cxl_h_collect_int_info(ctx->afu->guest->handle, ctx->process_token, info);
+}
+
+static irqreturn_t guest_psl_irq(int irq, void *data)
+{
+	struct cxl_context *ctx = data;
+	struct cxl_irq_info irq_info;
+	int rc;
+
+	pr_devel("%d: received PSL interrupt %i\n", ctx->pe, irq);
+	rc = guest_get_irq_info(ctx, &irq_info);
+	if (rc) {
+		WARN(1, "Unable to get IRQ info: %i\n", rc);
+		return IRQ_HANDLED;
+	}
+
+	rc = cxl_irq(irq, ctx, &irq_info);
+	return rc;
+}
+
+static int afu_read_error_state(struct cxl_afu *afu, int *state_out)
+{
+	u64 state;
+	int rc = 0;
+
+	rc = cxl_h_read_error_state(afu->guest->handle, &state);
+	if (!rc) {
+		WARN_ON(state != H_STATE_NORMAL &&
+			state != H_STATE_DISABLE &&
+			state != H_STATE_TEMP_UNAVAILABLE &&
+			state != H_STATE_PERM_UNAVAILABLE);
+		*state_out = state & 0xffffffff;
+	}
+	return rc;
+}
+
+static irqreturn_t guest_slice_irq_err(int irq, void *data)
+{
+	struct cxl_afu *afu = data;
+	int rc;
+	u64 serr;
+
+	WARN(irq, "CXL SLICE ERROR interrupt %i\n", irq);
+	rc = cxl_h_get_fn_error_interrupt(afu->guest->handle, &serr);
+	if (rc) {
+		dev_crit(&afu->dev, "Couldn't read PSL_SERR_An: %d\n", rc);
+		return IRQ_HANDLED;
+	}
+	dev_crit(&afu->dev, "PSL_SERR_An: 0x%.16llx\n", serr);
+
+	rc = cxl_h_ack_fn_error_interrupt(afu->guest->handle, serr);
+	if (rc)
+		dev_crit(&afu->dev, "Couldn't ack slice error interrupt: %d\n",
+			rc);
+
+	return IRQ_HANDLED;
+}
+
+
+static int irq_alloc_range(struct cxl *adapter, int len, int *irq)
+{
+	int i, n;
+	struct irq_avail *cur;
+
+	for (i = 0; i < adapter->guest->irq_nranges; i++) {
+		cur = &adapter->guest->irq_avail[i];
+		n = bitmap_find_next_zero_area(cur->bitmap, cur->range,
+					0, len, 0);
+		if (n < cur->range) {
+			bitmap_set(cur->bitmap, n, len);
+			*irq = cur->offset + n;
+			pr_devel("guest: allocate IRQs %#x->%#x\n",
+				*irq, *irq + len - 1);
+
+			return 0;
+		}
+	}
+	return -ENOSPC;
+}
+
+static int irq_free_range(struct cxl *adapter, int irq, int len)
+{
+	int i, n;
+	struct irq_avail *cur;
+
+	if (len == 0)
+		return -ENOENT;
+
+	for (i = 0; i < adapter->guest->irq_nranges; i++) {
+		cur = &adapter->guest->irq_avail[i];
+		if (irq >= cur->offset &&
+			(irq + len) <= (cur->offset + cur->range)) {
+			n = irq - cur->offset;
+			bitmap_clear(cur->bitmap, n, len);
+			pr_devel("guest: release IRQs %#x->%#x\n",
+				irq, irq + len - 1);
+			return 0;
+		}
+	}
+	return -ENOENT;
+}
+
+static int guest_reset(struct cxl *adapter)
+{
+	struct cxl_afu *afu = NULL;
+	int i, rc;
+
+	pr_devel("Adapter reset request\n");
+	for (i = 0; i < adapter->slices; i++) {
+		if ((afu = adapter->afu[i])) {
+			pci_error_handlers(afu, CXL_ERROR_DETECTED_EVENT,
+					pci_channel_io_frozen);
+			cxl_context_detach_all(afu);
+		}
+	}
+
+	rc = cxl_h_reset_adapter(adapter->guest->handle);
+	for (i = 0; i < adapter->slices; i++) {
+		if (!rc && (afu = adapter->afu[i])) {
+			pci_error_handlers(afu, CXL_SLOT_RESET_EVENT,
+					pci_channel_io_normal);
+			pci_error_handlers(afu, CXL_RESUME_EVENT, 0);
+		}
+	}
+	return rc;
+}
+
+static int guest_alloc_one_irq(struct cxl *adapter)
+{
+	int irq;
+
+	spin_lock(&adapter->guest->irq_alloc_lock);
+	if (irq_alloc_range(adapter, 1, &irq))
+		irq = -ENOSPC;
+	spin_unlock(&adapter->guest->irq_alloc_lock);
+	return irq;
+}
+
+static void guest_release_one_irq(struct cxl *adapter, int irq)
+{
+	spin_lock(&adapter->guest->irq_alloc_lock);
+	irq_free_range(adapter, irq, 1);
+	spin_unlock(&adapter->guest->irq_alloc_lock);
+}
+
+static int guest_alloc_irq_ranges(struct cxl_irq_ranges *irqs,
+				struct cxl *adapter, unsigned int num)
+{
+	int i, try, irq;
+
+	memset(irqs, 0, sizeof(struct cxl_irq_ranges));
+
+	spin_lock(&adapter->guest->irq_alloc_lock);
+	for (i = 0; i < CXL_IRQ_RANGES && num; i++) {
+		try = num;
+		while (try) {
+			if (irq_alloc_range(adapter, try, &irq) == 0)
+				break;
+			try /= 2;
+		}
+		if (!try)
+			goto error;
+		irqs->offset[i] = irq;
+		irqs->range[i] = try;
+		num -= try;
+	}
+	if (num)
+		goto error;
+	spin_unlock(&adapter->guest->irq_alloc_lock);
+	return 0;
+
+error:
+	for (i = 0; i < CXL_IRQ_RANGES; i++)
+		irq_free_range(adapter, irqs->offset[i], irqs->range[i]);
+	spin_unlock(&adapter->guest->irq_alloc_lock);
+	return -ENOSPC;
+}
+
+static void guest_release_irq_ranges(struct cxl_irq_ranges *irqs,
+				struct cxl *adapter)
+{
+	int i;
+
+	spin_lock(&adapter->guest->irq_alloc_lock);
+	for (i = 0; i < CXL_IRQ_RANGES; i++)
+		irq_free_range(adapter, irqs->offset[i], irqs->range[i]);
+	spin_unlock(&adapter->guest->irq_alloc_lock);
+}
+
+static int guest_register_serr_irq(struct cxl_afu *afu)
+{
+	afu->err_irq_name = kasprintf(GFP_KERNEL, "cxl-%s-err",
+				      dev_name(&afu->dev));
+	if (!afu->err_irq_name)
+		return -ENOMEM;
+
+	if (!(afu->serr_virq = cxl_map_irq(afu->adapter, afu->serr_hwirq,
+				 guest_slice_irq_err, afu, afu->err_irq_name))) {
+		kfree(afu->err_irq_name);
+		afu->err_irq_name = NULL;
+		return -ENOMEM;
+	}
+
+	return 0;
+}
+
+static void guest_release_serr_irq(struct cxl_afu *afu)
+{
+	cxl_unmap_irq(afu->serr_virq, afu);
+	cxl_ops->release_one_irq(afu->adapter, afu->serr_hwirq);
+	kfree(afu->err_irq_name);
+}
+
+static int guest_ack_irq(struct cxl_context *ctx, u64 tfc, u64 psl_reset_mask)
+{
+	return cxl_h_control_faults(ctx->afu->guest->handle, ctx->process_token,
+				tfc >> 32, (psl_reset_mask != 0));
+}
+
+static void disable_afu_irqs(struct cxl_context *ctx)
+{
+	irq_hw_number_t hwirq;
+	unsigned int virq;
+	int r, i;
+
+	pr_devel("Disabling AFU(%d) interrupts\n", ctx->afu->slice);
+	for (r = 0; r < CXL_IRQ_RANGES; r++) {
+		hwirq = ctx->irqs.offset[r];
+		for (i = 0; i < ctx->irqs.range[r]; hwirq++, i++) {
+			virq = irq_find_mapping(NULL, hwirq);
+			disable_irq(virq);
+		}
+	}
+}
+
+static void enable_afu_irqs(struct cxl_context *ctx)
+{
+	irq_hw_number_t hwirq;
+	unsigned int virq;
+	int r, i;
+
+	pr_devel("Enabling AFU(%d) interrupts\n", ctx->afu->slice);
+	for (r = 0; r < CXL_IRQ_RANGES; r++) {
+		hwirq = ctx->irqs.offset[r];
+		for (i = 0; i < ctx->irqs.range[r]; hwirq++, i++) {
+			virq = irq_find_mapping(NULL, hwirq);
+			enable_irq(virq);
+		}
+	}
+}
+
+static int _guest_afu_cr_readXX(int sz, struct cxl_afu *afu, int cr_idx,
+			u64 offset, u64 *val)
+{
+	unsigned long cr;
+	char c;
+	int rc = 0;
+
+	if (afu->crs_len < sz)
+		return -ENOENT;
+
+	if (unlikely(offset >= afu->crs_len))
+		return -ERANGE;
+
+	cr = get_zeroed_page(GFP_KERNEL);
+	if (!cr)
+		return -ENOMEM;
+
+	rc = cxl_h_get_config(afu->guest->handle, cr_idx, offset,
+			virt_to_phys((void *)cr), sz);
+	if (rc)
+		goto err;
+
+	switch (sz) {
+	case 1:
+		c = *((char *) cr);
+		*val = c;
+		break;
+	case 2:
+		*val = in_le16((u16 *)cr);
+		break;
+	case 4:
+		*val = in_le32((unsigned *)cr);
+		break;
+	case 8:
+		*val = in_le64((u64 *)cr);
+		break;
+	default:
+		WARN_ON(1);
+	}
+err:
+	free_page(cr);
+	return rc;
+}
+
+static int guest_afu_cr_read32(struct cxl_afu *afu, int cr_idx, u64 offset,
+			u32 *out)
+{
+	int rc;
+	u64 val;
+
+	rc = _guest_afu_cr_readXX(4, afu, cr_idx, offset, &val);
+	if (!rc)
+		*out = (u32) val;
+	return rc;
+}
+
+static int guest_afu_cr_read16(struct cxl_afu *afu, int cr_idx, u64 offset,
+			u16 *out)
+{
+	int rc;
+	u64 val;
+
+	rc = _guest_afu_cr_readXX(2, afu, cr_idx, offset, &val);
+	if (!rc)
+		*out = (u16) val;
+	return rc;
+}
+
+static int guest_afu_cr_read8(struct cxl_afu *afu, int cr_idx, u64 offset,
+			u8 *out)
+{
+	int rc;
+	u64 val;
+
+	rc = _guest_afu_cr_readXX(1, afu, cr_idx, offset, &val);
+	if (!rc)
+		*out = (u8) val;
+	return rc;
+}
+
+static int guest_afu_cr_read64(struct cxl_afu *afu, int cr_idx, u64 offset,
+			u64 *out)
+{
+	return _guest_afu_cr_readXX(8, afu, cr_idx, offset, out);
+}
+
+static int guest_afu_cr_write32(struct cxl_afu *afu, int cr, u64 off, u32 in)
+{
+	/* config record is not writable from guest */
+	return -EPERM;
+}
+
+static int guest_afu_cr_write16(struct cxl_afu *afu, int cr, u64 off, u16 in)
+{
+	/* config record is not writable from guest */
+	return -EPERM;
+}
+
+static int guest_afu_cr_write8(struct cxl_afu *afu, int cr, u64 off, u8 in)
+{
+	/* config record is not writable from guest */
+	return -EPERM;
+}
+
+static int attach_afu_directed(struct cxl_context *ctx, u64 wed, u64 amr)
+{
+	struct cxl_process_element_hcall *elem;
+	struct cxl *adapter = ctx->afu->adapter;
+	const struct cred *cred;
+	u32 pid, idx;
+	int rc, r, i;
+	u64 mmio_addr, mmio_size;
+	__be64 flags = 0;
+
+	/* Must be 8 byte aligned and cannot cross a 4096 byte boundary */
+	if (!(elem = (struct cxl_process_element_hcall *)
+			get_zeroed_page(GFP_KERNEL)))
+		return -ENOMEM;
+
+	elem->version = cpu_to_be64(CXL_PROCESS_ELEMENT_VERSION);
+	if (ctx->kernel) {
+		pid = 0;
+		flags |= CXL_PE_TRANSLATION_ENABLED;
+		flags |= CXL_PE_PRIVILEGED_PROCESS;
+		if (mfmsr() & MSR_SF)
+			flags |= CXL_PE_64_BIT;
+	} else {
+		pid = current->pid;
+		flags |= CXL_PE_PROBLEM_STATE;
+		flags |= CXL_PE_TRANSLATION_ENABLED;
+		if (!test_tsk_thread_flag(current, TIF_32BIT))
+			flags |= CXL_PE_64_BIT;
+		cred = get_current_cred();
+		if (uid_eq(cred->euid, GLOBAL_ROOT_UID))
+			flags |= CXL_PE_PRIVILEGED_PROCESS;
+		put_cred(cred);
+	}
+	elem->flags         = cpu_to_be64(flags);
+	elem->common.tid    = cpu_to_be32(0); /* Unused */
+	elem->common.pid    = cpu_to_be32(pid);
+	elem->common.csrp   = cpu_to_be64(0); /* disable */
+	elem->common.aurp0  = cpu_to_be64(0); /* disable */
+	elem->common.aurp1  = cpu_to_be64(0); /* disable */
+
+	cxl_prefault(ctx, wed);
+
+	elem->common.sstp0  = cpu_to_be64(ctx->sstp0);
+	elem->common.sstp1  = cpu_to_be64(ctx->sstp1);
+	for (r = 0; r < CXL_IRQ_RANGES; r++) {
+		for (i = 0; i < ctx->irqs.range[r]; i++) {
+			if (r == 0 && i == 0) {
+				elem->pslVirtualIsn = cpu_to_be32(ctx->irqs.offset[0]);
+			} else {
+				idx = ctx->irqs.offset[r] + i - adapter->guest->irq_base_offset;
+				elem->applicationVirtualIsnBitmap[idx / 8] |= 0x80 >> (idx % 8);
+			}
+		}
+	}
+	elem->common.amr = cpu_to_be64(amr);
+	elem->common.wed = cpu_to_be64(wed);
+
+	disable_afu_irqs(ctx);
+
+	rc = cxl_h_attach_process(ctx->afu->guest->handle, elem,
+				&ctx->process_token, &mmio_addr, &mmio_size);
+	if (rc == H_SUCCESS) {
+		if (ctx->master || !ctx->afu->pp_psa) {
+			ctx->psn_phys = ctx->afu->psn_phys;
+			ctx->psn_size = ctx->afu->adapter->ps_size;
+		} else {
+			ctx->psn_phys = mmio_addr;
+			ctx->psn_size = mmio_size;
+		}
+		if (ctx->afu->pp_psa && mmio_size &&
+			ctx->afu->pp_size == 0) {
+			/*
+			 * There's no property in the device tree to read the
+			 * pp_size. We only find out at the 1st attach.
+			 * Compared to bare-metal, it is too late and we
+			 * should really lock here. However, on powerVM,
+			 * pp_size is really only used to display in /sys.
+			 * Being discussed with pHyp for their next release.
+			 */
+			ctx->afu->pp_size = mmio_size;
+		}
+		/* from PAPR: process element is bytes 4-7 of process token */
+		ctx->external_pe = ctx->process_token & 0xFFFFFFFF;
+		pr_devel("CXL pe=%i is known as %i for pHyp, mmio_size=%#llx",
+			ctx->pe, ctx->external_pe, ctx->psn_size);
+		ctx->pe_inserted = true;
+		enable_afu_irqs(ctx);
+	}
+
+	free_page((u64)elem);
+	return rc;
+}
+
+static int guest_attach_process(struct cxl_context *ctx, bool kernel, u64 wed, u64 amr)
+{
+	pr_devel("in %s\n", __func__);
+
+	ctx->kernel = kernel;
+	if (ctx->afu->current_mode == CXL_MODE_DIRECTED)
+		return attach_afu_directed(ctx, wed, amr);
+
+	/* dedicated mode not supported on FW840 */
+
+	return -EINVAL;
+}
+
+static int detach_afu_directed(struct cxl_context *ctx)
+{
+	if (!ctx->pe_inserted)
+		return 0;
+	if (cxl_h_detach_process(ctx->afu->guest->handle, ctx->process_token))
+		return -1;
+	return 0;
+}
+
+static int guest_detach_process(struct cxl_context *ctx)
+{
+	pr_devel("in %s\n", __func__);
+	trace_cxl_detach(ctx);
+
+	if (!cxl_ops->link_ok(ctx->afu->adapter, ctx->afu))
+		return -EIO;
+
+	if (ctx->afu->current_mode == CXL_MODE_DIRECTED)
+		return detach_afu_directed(ctx);
+
+	return -EINVAL;
+}
+
+static void guest_release_afu(struct device *dev)
+{
+	struct cxl_afu *afu = to_cxl_afu(dev);
+
+	pr_devel("%s\n", __func__);
+
+	idr_destroy(&afu->contexts_idr);
+
+	kfree(afu->guest);
+	kfree(afu);
+}
+
+ssize_t cxl_guest_read_afu_vpd(struct cxl_afu *afu, void *buf, size_t len)
+{
+	return guest_collect_vpd(NULL, afu, buf, len);
+}
+
+#define ERR_BUFF_MAX_COPY_SIZE PAGE_SIZE
+static ssize_t guest_afu_read_err_buffer(struct cxl_afu *afu, char *buf,
+					loff_t off, size_t count)
+{
+	void *tbuf = NULL;
+	int rc = 0;
+
+	tbuf = (void *) get_zeroed_page(GFP_KERNEL);
+	if (!tbuf)
+		return -ENOMEM;
+
+	rc = cxl_h_get_afu_err(afu->guest->handle,
+			       off & 0x7,
+			       virt_to_phys(tbuf),
+			       count);
+	if (rc)
+		goto err;
+
+	if (count > ERR_BUFF_MAX_COPY_SIZE)
+		count = ERR_BUFF_MAX_COPY_SIZE - (off & 0x7);
+	memcpy(buf, tbuf, count);
+err:
+	free_page((u64)tbuf);
+
+	return rc;
+}
+
+static int guest_afu_check_and_enable(struct cxl_afu *afu)
+{
+	return 0;
+}
+
+static bool guest_support_attributes(const char *attr_name,
+				     enum cxl_attrs type)
+{
+	switch (type) {
+	case CXL_ADAPTER_ATTRS:
+		if ((strcmp(attr_name, "base_image") == 0) ||
+			(strcmp(attr_name, "load_image_on_perst") == 0) ||
+			(strcmp(attr_name, "perst_reloads_same_image") == 0) ||
+			(strcmp(attr_name, "image_loaded") == 0))
+			return false;
+		break;
+	case CXL_AFU_MASTER_ATTRS:
+		if ((strcmp(attr_name, "pp_mmio_off") == 0))
+			return false;
+		break;
+	case CXL_AFU_ATTRS:
+		break;
+	default:
+		break;
+	}
+
+	return true;
+}
+
+static int activate_afu_directed(struct cxl_afu *afu)
+{
+	int rc;
+
+	dev_info(&afu->dev, "Activating AFU(%d) directed mode\n", afu->slice);
+
+	afu->current_mode = CXL_MODE_DIRECTED;
+
+	afu->num_procs = afu->max_procs_virtualised;
+
+	if ((rc = cxl_chardev_m_afu_add(afu)))
+		return rc;
+
+	if ((rc = cxl_sysfs_afu_m_add(afu)))
+		goto err;
+
+	if ((rc = cxl_chardev_s_afu_add(afu)))
+		goto err1;
+
+	return 0;
+err1:
+	cxl_sysfs_afu_m_remove(afu);
+err:
+	cxl_chardev_afu_remove(afu);
+	return rc;
+}
+
+static int guest_afu_activate_mode(struct cxl_afu *afu, int mode)
+{
+	if (!mode)
+		return 0;
+	if (!(mode & afu->modes_supported))
+		return -EINVAL;
+
+	if (mode == CXL_MODE_DIRECTED)
+		return activate_afu_directed(afu);
+
+	if (mode == CXL_MODE_DEDICATED)
+		dev_err(&afu->dev, "Dedicated mode not supported\n");
+
+	return -EINVAL;
+}
+
+static int deactivate_afu_directed(struct cxl_afu *afu)
+{
+	dev_info(&afu->dev, "Deactivating AFU(%d) directed mode\n", afu->slice);
+
+	afu->current_mode = 0;
+	afu->num_procs = 0;
+
+	cxl_sysfs_afu_m_remove(afu);
+	cxl_chardev_afu_remove(afu);
+
+	cxl_ops->afu_reset(afu);
+
+	return 0;
+}
+
+static int guest_afu_deactivate_mode(struct cxl_afu *afu, int mode)
+{
+	if (!mode)
+		return 0;
+	if (!(mode & afu->modes_supported))
+		return -EINVAL;
+
+	if (mode == CXL_MODE_DIRECTED)
+		return deactivate_afu_directed(afu);
+	return 0;
+}
+
+static int guest_afu_reset(struct cxl_afu *afu)
+{
+	pr_devel("AFU(%d) reset request\n", afu->slice);
+	return cxl_h_reset_afu(afu->guest->handle);
+}
+
+static int guest_map_slice_regs(struct cxl_afu *afu)
+{
+	if (!(afu->p2n_mmio = ioremap(afu->guest->p2n_phys, afu->guest->p2n_size))) {
+		dev_err(&afu->dev, "Error mapping AFU(%d) MMIO regions\n",
+			afu->slice);
+		return -ENOMEM;
+	}
+	return 0;
+}
+
+static void guest_unmap_slice_regs(struct cxl_afu *afu)
+{
+	if (afu->p2n_mmio)
+		iounmap(afu->p2n_mmio);
+}
+
+static int afu_update_state(struct cxl_afu *afu)
+{
+	int rc, cur_state;
+
+	rc = afu_read_error_state(afu, &cur_state);
+	if (rc)
+		return rc;
+
+	if (afu->guest->previous_state == cur_state)
+		return 0;
+
+	pr_devel("AFU(%d) update state to %#x\n", afu->slice, cur_state);
+
+	switch (cur_state) {
+	case H_STATE_NORMAL:
+		afu->guest->previous_state = cur_state;
+		rc = 1;
+		break;
+
+	case H_STATE_DISABLE:
+		pci_error_handlers(afu, CXL_ERROR_DETECTED_EVENT,
+				pci_channel_io_frozen);
+
+		cxl_context_detach_all(afu);
+		if ((rc = cxl_ops->afu_reset(afu)))
+			pr_devel("reset hcall failed %d\n", rc);
+
+		rc = afu_read_error_state(afu, &cur_state);
+		if (!rc && cur_state == H_STATE_NORMAL) {
+			pci_error_handlers(afu, CXL_SLOT_RESET_EVENT,
+					pci_channel_io_normal);
+			pci_error_handlers(afu, CXL_RESUME_EVENT, 0);
+			rc = 1;
+		}
+		afu->guest->previous_state = 0;
+		break;
+
+	case H_STATE_TEMP_UNAVAILABLE:
+		afu->guest->previous_state = cur_state;
+		break;
+
+	case H_STATE_PERM_UNAVAILABLE:
+		dev_err(&afu->dev, "AFU is in permanent error state\n");
+		pci_error_handlers(afu, CXL_ERROR_DETECTED_EVENT,
+				pci_channel_io_perm_failure);
+		afu->guest->previous_state = cur_state;
+		break;
+
+	default:
+		pr_err("Unexpected AFU(%d) error state: %#x\n",
+		       afu->slice, cur_state);
+		return -EINVAL;
+	}
+
+	return rc;
+}
+
+static int afu_do_recovery(struct cxl_afu *afu)
+{
+	int rc;
+
+	/* many threads can arrive here, in case of detach_all for example.
+	 * Only one needs to drive the recovery
+	 */
+	if (mutex_trylock(&afu->guest->recovery_lock)) {
+		rc = afu_update_state(afu);
+		mutex_unlock(&afu->guest->recovery_lock);
+		return rc;
+	}
+	return 0;
+}
+
+static bool guest_link_ok(struct cxl *cxl, struct cxl_afu *afu)
+{
+	int state;
+
+	if (afu) {
+		if (afu_read_error_state(afu, &state) ||
+			state != H_STATE_NORMAL) {
+			if (afu_do_recovery(afu) > 0) {
+				/* check again in case we've just fixed it */
+				if (!afu_read_error_state(afu, &state) &&
+					state == H_STATE_NORMAL)
+					return true;
+			}
+			return false;
+		}
+	}
+
+	return true;
+}
+
+static int afu_properties_look_ok(struct cxl_afu *afu)
+{
+	if (afu->pp_irqs < 0) {
+		dev_err(&afu->dev, "Unexpected per-process minimum interrupt value\n");
+		return -EINVAL;
+	}
+
+	if (afu->max_procs_virtualised < 1) {
+		dev_err(&afu->dev, "Unexpected max number of processes virtualised value\n");
+		return -EINVAL;
+	}
+
+	if (afu->crs_len < 0) {
+		dev_err(&afu->dev, "Unexpected configuration record size value\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+int cxl_guest_init_afu(struct cxl *adapter, int slice, struct device_node *afu_np)
+{
+	struct cxl_afu *afu;
+	bool free = true;
+	int rc;
+
+	pr_devel("in %s - AFU(%d)\n", __func__, slice);
+	if (!(afu = cxl_alloc_afu(adapter, slice)))
+		return -ENOMEM;
+
+	if (!(afu->guest = kzalloc(sizeof(struct cxl_afu_guest), GFP_KERNEL))) {
+		kfree(afu);
+		return -ENOMEM;
+	}
+
+	mutex_init(&afu->guest->recovery_lock);
+
+	if ((rc = dev_set_name(&afu->dev, "afu%i.%i",
+					  adapter->adapter_num,
+					  slice)))
+		goto err1;
+
+	adapter->slices++;
+
+	if ((rc = cxl_of_read_afu_handle(afu, afu_np)))
+		goto err1;
+
+	if ((rc = cxl_ops->afu_reset(afu)))
+		goto err1;
+
+	if ((rc = cxl_of_read_afu_properties(afu, afu_np)))
+		goto err1;
+
+	if ((rc = afu_properties_look_ok(afu)))
+		goto err1;
+
+	if ((rc = guest_map_slice_regs(afu)))
+		goto err1;
+
+	if ((rc = guest_register_serr_irq(afu)))
+		goto err2;
+
+	/*
+	 * After we call this function we must not free the afu directly, even
+	 * if it returns an error!
+	 */
+	if ((rc = cxl_register_afu(afu)))
+		goto err_put1;
+
+	if ((rc = cxl_sysfs_afu_add(afu)))
+		goto err_put1;
+
+	/*
+	 * pHyp doesn't expose the programming models supported by the
+	 * AFU. pHyp currently only supports directed mode. If it adds
+	 * dedicated mode later, this version of cxl has no way to
+	 * detect it. So we'll initialize the driver, but the first
+	 * attach will fail.
+	 * Being discussed with pHyp to do better (likely new property)
+	 */
+	if (afu->max_procs_virtualised == 1)
+		afu->modes_supported = CXL_MODE_DEDICATED;
+	else
+		afu->modes_supported = CXL_MODE_DIRECTED;
+
+	if ((rc = cxl_afu_select_best_mode(afu)))
+		goto err_put2;
+
+	adapter->afu[afu->slice] = afu;
+
+	afu->enabled = true;
+
+	if ((rc = cxl_pci_vphb_add(afu)))
+		dev_info(&afu->dev, "Can't register vPHB\n");
+
+	return 0;
+
+err_put2:
+	cxl_sysfs_afu_remove(afu);
+err_put1:
+	device_unregister(&afu->dev);
+	free = false;
+	guest_release_serr_irq(afu);
+err2:
+	guest_unmap_slice_regs(afu);
+err1:
+	if (free) {
+		kfree(afu->guest);
+		kfree(afu);
+	}
+	return rc;
+}
+
+void cxl_guest_remove_afu(struct cxl_afu *afu)
+{
+	pr_devel("in %s - AFU(%d)\n", __func__, afu->slice);
+
+	if (!afu)
+		return;
+
+	cxl_pci_vphb_remove(afu);
+	cxl_sysfs_afu_remove(afu);
+
+	spin_lock(&afu->adapter->afu_list_lock);
+	afu->adapter->afu[afu->slice] = NULL;
+	spin_unlock(&afu->adapter->afu_list_lock);
+
+	cxl_context_detach_all(afu);
+	cxl_ops->afu_deactivate_mode(afu, afu->current_mode);
+	guest_release_serr_irq(afu);
+	guest_unmap_slice_regs(afu);
+
+	device_unregister(&afu->dev);
+}
+
+static void free_adapter(struct cxl *adapter)
+{
+	struct irq_avail *cur;
+	int i;
+
+	if (adapter->guest->irq_avail) {
+		for (i = 0; i < adapter->guest->irq_nranges; i++) {
+			cur = &adapter->guest->irq_avail[i];
+			kfree(cur->bitmap);
+		}
+		kfree(adapter->guest->irq_avail);
+	}
+	kfree(adapter->guest->status);
+	cxl_remove_adapter_nr(adapter);
+	kfree(adapter->guest);
+	kfree(adapter);
+}
+
+static int properties_look_ok(struct cxl *adapter)
+{
+	/* The absence of this property means that the operational
+	 * status is unknown or okay
+	 */
+	if (strlen(adapter->guest->status) &&
+	    strcmp(adapter->guest->status, "okay")) {
+		pr_err("ABORTING:Bad operational status of the device\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+ssize_t cxl_guest_read_adapter_vpd(struct cxl *adapter, void *buf, size_t len)
+{
+	return guest_collect_vpd(adapter, NULL, buf, len);
+}
+
+void cxl_guest_remove_adapter(struct cxl *adapter)
+{
+	pr_devel("in %s\n", __func__);
+
+	cxl_sysfs_adapter_remove(adapter);
+
+	cxl_guest_remove_chardev(adapter);
+	device_unregister(&adapter->dev);
+}
+
+static void release_adapter(struct device *dev)
+{
+	free_adapter(to_cxl_adapter(dev));
+}
+
+struct cxl *cxl_guest_init_adapter(struct device_node *np, struct platform_device *pdev)
+{
+	struct cxl *adapter;
+	bool free = true;
+	int rc;
+
+	if (!(adapter = cxl_alloc_adapter()))
+		return ERR_PTR(-ENOMEM);
+
+	if (!(adapter->guest = kzalloc(sizeof(struct cxl_guest), GFP_KERNEL))) {
+		free_adapter(adapter);
+		return ERR_PTR(-ENOMEM);
+	}
+
+	adapter->slices = 0;
+	adapter->guest->pdev = pdev;
+	adapter->dev.parent = &pdev->dev;
+	adapter->dev.release = release_adapter;
+	dev_set_drvdata(&pdev->dev, adapter);
+
+	if ((rc = cxl_of_read_adapter_handle(adapter, np)))
+		goto err1;
+
+	if ((rc = cxl_of_read_adapter_properties(adapter, np)))
+		goto err1;
+
+	if ((rc = properties_look_ok(adapter)))
+		goto err1;
+
+	if ((rc = cxl_guest_add_chardev(adapter)))
+		goto err1;
+
+	/*
+	 * After we call this function we must not free the adapter directly,
+	 * even if it returns an error!
+	 */
+	if ((rc = cxl_register_adapter(adapter)))
+		goto err_put1;
+
+	if ((rc = cxl_sysfs_adapter_add(adapter)))
+		goto err_put1;
+
+	return adapter;
+
+err_put1:
+	device_unregister(&adapter->dev);
+	free = false;
+	cxl_guest_remove_chardev(adapter);
+err1:
+	if (free)
+		free_adapter(adapter);
+	return ERR_PTR(rc);
+}
+
+void cxl_guest_reload_module(struct cxl *adapter)
+{
+	struct platform_device *pdev;
+
+	pdev = adapter->guest->pdev;
+	cxl_guest_remove_adapter(adapter);
+
+	cxl_of_probe(pdev);
+}
+
+const struct cxl_backend_ops cxl_guest_ops = {
+	.module = THIS_MODULE,
+	.adapter_reset = guest_reset,
+	.alloc_one_irq = guest_alloc_one_irq,
+	.release_one_irq = guest_release_one_irq,
+	.alloc_irq_ranges = guest_alloc_irq_ranges,
+	.release_irq_ranges = guest_release_irq_ranges,
+	.setup_irq = NULL,
+	.handle_psl_slice_error = guest_handle_psl_slice_error,
+	.psl_interrupt = guest_psl_irq,
+	.ack_irq = guest_ack_irq,
+	.attach_process = guest_attach_process,
+	.detach_process = guest_detach_process,
+	.support_attributes = guest_support_attributes,
+	.link_ok = guest_link_ok,
+	.release_afu = guest_release_afu,
+	.afu_read_err_buffer = guest_afu_read_err_buffer,
+	.afu_check_and_enable = guest_afu_check_and_enable,
+	.afu_activate_mode = guest_afu_activate_mode,
+	.afu_deactivate_mode = guest_afu_deactivate_mode,
+	.afu_reset = guest_afu_reset,
+	.afu_cr_read8 = guest_afu_cr_read8,
+	.afu_cr_read16 = guest_afu_cr_read16,
+	.afu_cr_read32 = guest_afu_cr_read32,
+	.afu_cr_read64 = guest_afu_cr_read64,
+	.afu_cr_write8 = guest_afu_cr_write8,
+	.afu_cr_write16 = guest_afu_cr_write16,
+	.afu_cr_write32 = guest_afu_cr_write32,
+	.read_adapter_vpd = cxl_guest_read_adapter_vpd,
+};
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/misc/cxl/hcalls.c
@@ -0,0 +1,647 @@
+/*
+ * Copyright 2015 IBM Corp.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+
+#include <linux/compiler.h>
+#include <linux/types.h>
+#include <linux/delay.h>
+#include <asm/byteorder.h>
+#include "hcalls.h"
+#include "trace.h"
+
+#define CXL_HCALL_TIMEOUT 60000
+#define CXL_HCALL_TIMEOUT_DOWNLOAD 120000
+
+#define H_ATTACH_CA_PROCESS    0x344
+#define H_CONTROL_CA_FUNCTION  0x348
+#define H_DETACH_CA_PROCESS    0x34C
+#define H_COLLECT_CA_INT_INFO  0x350
+#define H_CONTROL_CA_FAULTS    0x354
+#define H_DOWNLOAD_CA_FUNCTION 0x35C
+#define H_DOWNLOAD_CA_FACILITY 0x364
+#define H_CONTROL_CA_FACILITY  0x368
+
+#define H_CONTROL_CA_FUNCTION_RESET                   1 /* perform a reset */
+#define H_CONTROL_CA_FUNCTION_SUSPEND_PROCESS         2 /* suspend a process from being executed */
+#define H_CONTROL_CA_FUNCTION_RESUME_PROCESS          3 /* resume a process to be executed */
+#define H_CONTROL_CA_FUNCTION_READ_ERR_STATE          4 /* read the error state */
+#define H_CONTROL_CA_FUNCTION_GET_AFU_ERR             5 /* collect the AFU error buffer */
+#define H_CONTROL_CA_FUNCTION_GET_CONFIG              6 /* collect configuration record */
+#define H_CONTROL_CA_FUNCTION_GET_DOWNLOAD_STATE      7 /* query to return download status */
+#define H_CONTROL_CA_FUNCTION_TERMINATE_PROCESS       8 /* terminate the process before completion */
+#define H_CONTROL_CA_FUNCTION_COLLECT_VPD             9 /* collect VPD */
+#define H_CONTROL_CA_FUNCTION_GET_FUNCTION_ERR_INT   11 /* read the function-wide error data based on an interrupt */
+#define H_CONTROL_CA_FUNCTION_ACK_FUNCTION_ERR_INT   12 /* acknowledge function-wide error data based on an interrupt */
+#define H_CONTROL_CA_FUNCTION_GET_ERROR_LOG          13 /* retrieve the Platform Log ID (PLID) of an error log */
+
+#define H_CONTROL_CA_FAULTS_RESPOND_PSL         1
+#define H_CONTROL_CA_FAULTS_RESPOND_AFU         2
+
+#define H_CONTROL_CA_FACILITY_RESET             1 /* perform a reset */
+#define H_CONTROL_CA_FACILITY_COLLECT_VPD       2 /* collect VPD */
+
+#define H_DOWNLOAD_CA_FACILITY_DOWNLOAD         1 /* download adapter image */
+#define H_DOWNLOAD_CA_FACILITY_VALIDATE         2 /* validate adapter image */
+
+
+#define _CXL_LOOP_HCALL(call, rc, retbuf, fn, ...)			\
+	{								\
+		unsigned int delay, total_delay = 0;			\
+		u64 token = 0;						\
+									\
+		memset(retbuf, 0, sizeof(retbuf));			\
+		while (1) {						\
+			rc = call(fn, retbuf, __VA_ARGS__, token);	\
+			token = retbuf[0];				\
+			if (rc != H_BUSY && !H_IS_LONG_BUSY(rc))	\
+				break;					\
+									\
+			if (rc == H_BUSY)				\
+				delay = 10;				\
+			else						\
+				delay = get_longbusy_msecs(rc);		\
+									\
+			total_delay += delay;				\
+			if (total_delay > CXL_HCALL_TIMEOUT) {		\
+				WARN(1, "Warning: Giving up waiting for CXL hcall " \
+					"%#x after %u msec\n", fn, total_delay); \
+				rc = H_BUSY;				\
+				break;					\
+			}						\
+			msleep(delay);					\
+		}							\
+	}
+#define CXL_H_WAIT_UNTIL_DONE(...)  _CXL_LOOP_HCALL(plpar_hcall, __VA_ARGS__)
+#define CXL_H9_WAIT_UNTIL_DONE(...) _CXL_LOOP_HCALL(plpar_hcall9, __VA_ARGS__)
+
+#define _PRINT_MSG(rc, format, ...)					\
+	{								\
+		if ((rc != H_SUCCESS) && (rc != H_CONTINUE))		\
+			pr_err(format, __VA_ARGS__);			\
+		else							\
+			pr_devel(format, __VA_ARGS__);			\
+	}								\
+
+
+static char *afu_op_names[] = {
+	"UNKNOWN_OP",		/* 0 undefined */
+	"RESET",		/* 1 */
+	"SUSPEND_PROCESS",	/* 2 */
+	"RESUME_PROCESS",	/* 3 */
+	"READ_ERR_STATE",	/* 4 */
+	"GET_AFU_ERR",		/* 5 */
+	"GET_CONFIG",		/* 6 */
+	"GET_DOWNLOAD_STATE",	/* 7 */
+	"TERMINATE_PROCESS",	/* 8 */
+	"COLLECT_VPD",		/* 9 */
+	"UNKNOWN_OP",		/* 10 undefined */
+	"GET_FUNCTION_ERR_INT",	/* 11 */
+	"ACK_FUNCTION_ERR_INT",	/* 12 */
+	"GET_ERROR_LOG",	/* 13 */
+};
+
+static char *control_adapter_op_names[] = {
+	"UNKNOWN_OP",		/* 0 undefined */
+	"RESET",		/* 1 */
+	"COLLECT_VPD",		/* 2 */
+};
+
+static char *download_op_names[] = {
+	"UNKNOWN_OP",		/* 0 undefined */
+	"DOWNLOAD",		/* 1 */
+	"VALIDATE",		/* 2 */
+};
+
+static char *op_str(unsigned int op, char *name_array[], int array_len)
+{
+	if (op >= array_len)
+		return "UNKNOWN_OP";
+	return name_array[op];
+}
+
+#define OP_STR(op, name_array)      op_str(op, name_array, ARRAY_SIZE(name_array))
+
+#define OP_STR_AFU(op)              OP_STR(op, afu_op_names)
+#define OP_STR_CONTROL_ADAPTER(op)  OP_STR(op, control_adapter_op_names)
+#define OP_STR_DOWNLOAD_ADAPTER(op) OP_STR(op, download_op_names)
+
+
+long cxl_h_attach_process(u64 unit_address,
+			struct cxl_process_element_hcall *element,
+			u64 *process_token, u64 *mmio_addr, u64 *mmio_size)
+{
+	unsigned long retbuf[PLPAR_HCALL_BUFSIZE];
+	long rc;
+
+	CXL_H_WAIT_UNTIL_DONE(rc, retbuf, H_ATTACH_CA_PROCESS, unit_address, virt_to_phys(element));
+	_PRINT_MSG(rc, "cxl_h_attach_process(%#.16llx, %#.16lx): %li\n",
+		unit_address, virt_to_phys(element), rc);
+	trace_cxl_hcall_attach(unit_address, virt_to_phys(element), retbuf[0], retbuf[1], retbuf[2], rc);
+
+	pr_devel("token: 0x%.8lx mmio_addr: 0x%lx mmio_size: 0x%lx\nProcess Element Structure:\n",
+		retbuf[0], retbuf[1], retbuf[2]);
+	cxl_dump_debug_buffer(element, sizeof(*element));
+
+	switch (rc) {
+	case H_SUCCESS:       /* The process info is attached to the coherent platform function */
+		*process_token = retbuf[0];
+		if (mmio_addr)
+			*mmio_addr = retbuf[1];
+		if (mmio_size)
+			*mmio_size = retbuf[2];
+		return 0;
+	case H_PARAMETER:     /* An incorrect parameter was supplied. */
+	case H_FUNCTION:      /* The function is not supported. */
+		return -EINVAL;
+	case H_AUTHORITY:     /* The partition does not have authority to perform this hcall */
+	case H_RESOURCE:      /* The coherent platform function does not have enough additional resource to attach the process */
+	case H_HARDWARE:      /* A hardware event prevented the attach operation */
+	case H_STATE:         /* The coherent platform function is not in a valid state */
+	case H_BUSY:
+		return -EBUSY;
+	default:
+		WARN(1, "Unexpected return code: %lx", rc);
+		return -EINVAL;
+	}
+}
+
+/**
+ * cxl_h_detach_process - Detach a process element from a coherent
+ *                        platform function.
+ */
+long cxl_h_detach_process(u64 unit_address, u64 process_token)
+{
+	unsigned long retbuf[PLPAR_HCALL_BUFSIZE];
+	long rc;
+
+	CXL_H_WAIT_UNTIL_DONE(rc, retbuf, H_DETACH_CA_PROCESS, unit_address, process_token);
+	_PRINT_MSG(rc, "cxl_h_detach_process(%#.16llx, 0x%.8llx): %li\n", unit_address, process_token, rc);
+	trace_cxl_hcall_detach(unit_address, process_token, rc);
+
+	switch (rc) {
+	case H_SUCCESS:       /* The process was detached from the coherent platform function */
+		return 0;
+	case H_PARAMETER:     /* An incorrect parameter was supplied. */
+		return -EINVAL;
+	case H_AUTHORITY:     /* The partition does not have authority to perform this hcall */
+	case H_RESOURCE:      /* The function has page table mappings for MMIO */
+	case H_HARDWARE:      /* A hardware event prevented the detach operation */
+	case H_STATE:         /* The coherent platform function is not in a valid state */
+	case H_BUSY:
+		return -EBUSY;
+	default:
+		WARN(1, "Unexpected return code: %lx", rc);
+		return -EINVAL;
+	}
+}
+
+/**
+ * cxl_h_control_function - This H_CONTROL_CA_FUNCTION hypervisor call allows
+ *                          the partition to manipulate or query
+ *                          certain coherent platform function behaviors.
+ */
+static long cxl_h_control_function(u64 unit_address, u64 op,
+				   u64 p1, u64 p2, u64 p3, u64 p4, u64 *out)
+{
+	unsigned long retbuf[PLPAR_HCALL9_BUFSIZE];
+	long rc;
+
+	CXL_H9_WAIT_UNTIL_DONE(rc, retbuf, H_CONTROL_CA_FUNCTION, unit_address, op, p1, p2, p3, p4);
+	_PRINT_MSG(rc, "cxl_h_control_function(%#.16llx, %s(%#llx, %#llx, %#llx, %#llx, R4: %#lx)): %li\n",
+		unit_address, OP_STR_AFU(op), p1, p2, p3, p4, retbuf[0], rc);
+	trace_cxl_hcall_control_function(unit_address, OP_STR_AFU(op), p1, p2, p3, p4, retbuf[0], rc);
+
+	switch (rc) {
+	case H_SUCCESS:       /* The operation is completed for the coherent platform function */
+		if ((op == H_CONTROL_CA_FUNCTION_GET_FUNCTION_ERR_INT ||
+		     op == H_CONTROL_CA_FUNCTION_READ_ERR_STATE ||
+		     op == H_CONTROL_CA_FUNCTION_COLLECT_VPD))
+			*out = retbuf[0];
+		return 0;
+	case H_PARAMETER:     /* An incorrect parameter was supplied. */
+	case H_FUNCTION:      /* The function is not supported. */
+	case H_NOT_FOUND:     /* The operation supplied was not valid */
+	case H_NOT_AVAILABLE: /* The operation cannot be performed because the AFU has not been downloaded */
+	case H_SG_LIST:       /* An block list entry was invalid */
+		return -EINVAL;
+	case H_AUTHORITY:     /* The partition does not have authority to perform this hcall */
+	case H_RESOURCE:      /* The function has page table mappings for MMIO */
+	case H_HARDWARE:      /* A hardware event prevented the attach operation */
+	case H_STATE:         /* The coherent platform function is not in a valid state */
+	case H_BUSY:
+		return -EBUSY;
+	default:
+		WARN(1, "Unexpected return code: %lx", rc);
+		return -EINVAL;
+	}
+}
+
+/**
+ * cxl_h_reset_afu - Perform a reset to the coherent platform function.
+ */
+long cxl_h_reset_afu(u64 unit_address)
+{
+	return cxl_h_control_function(unit_address,
+				H_CONTROL_CA_FUNCTION_RESET,
+				0, 0, 0, 0,
+				NULL);
+}
+
+/**
+ * cxl_h_suspend_process - Suspend a process from being executed
+ * Parameter1 = process-token as returned from H_ATTACH_CA_PROCESS when
+ *              process was attached.
+ */
+long cxl_h_suspend_process(u64 unit_address, u64 process_token)
+{
+	return cxl_h_control_function(unit_address,
+				H_CONTROL_CA_FUNCTION_SUSPEND_PROCESS,
+				process_token, 0, 0, 0,
+				NULL);
+}
+
+/**
+ * cxl_h_resume_process - Resume a process to be executed
+ * Parameter1 = process-token as returned from H_ATTACH_CA_PROCESS when
+ *              process was attached.
+ */
+long cxl_h_resume_process(u64 unit_address, u64 process_token)
+{
+	return cxl_h_control_function(unit_address,
+				H_CONTROL_CA_FUNCTION_RESUME_PROCESS,
+				process_token, 0, 0, 0,
+				NULL);
+}
+
+/**
+ * cxl_h_read_error_state - Checks the error state of the coherent
+ *                          platform function.
+ * R4 contains the error state
+ */
+long cxl_h_read_error_state(u64 unit_address, u64 *state)
+{
+	return cxl_h_control_function(unit_address,
+				H_CONTROL_CA_FUNCTION_READ_ERR_STATE,
+				0, 0, 0, 0,
+				state);
+}
+
+/**
+ * cxl_h_get_afu_err - collect the AFU error buffer
+ * Parameter1 = byte offset into error buffer to retrieve, valid values
+ *              are between 0 and (ibm,error-buffer-size - 1)
+ * Parameter2 = 4K aligned real address of error buffer, to be filled in
+ * Parameter3 = length of error buffer, valid values are 4K or less
+ */
+long cxl_h_get_afu_err(u64 unit_address, u64 offset,
+		u64 buf_address, u64 len)
+{
+	return cxl_h_control_function(unit_address,
+				H_CONTROL_CA_FUNCTION_GET_AFU_ERR,
+				offset, buf_address, len, 0,
+				NULL);
+}
+
+/**
+ * cxl_h_get_config - collect configuration record for the
+ *                    coherent platform function
+ * Parameter1 = # of configuration record to retrieve, valid values are
+ *              between 0 and (ibm,#config-records - 1)
+ * Parameter2 = byte offset into configuration record to retrieve,
+ *              valid values are between 0 and (ibm,config-record-size - 1)
+ * Parameter3 = 4K aligned real address of configuration record buffer,
+ *              to be filled in
+ * Parameter4 = length of configuration buffer, valid values are 4K or less
+ */
+long cxl_h_get_config(u64 unit_address, u64 cr_num, u64 offset,
+		u64 buf_address, u64 len)
+{
+	return cxl_h_control_function(unit_address,
+				H_CONTROL_CA_FUNCTION_GET_CONFIG,
+				cr_num, offset, buf_address, len,
+				NULL);
+}
+
+/**
+ * cxl_h_terminate_process - Terminate the process before completion
+ * Parameter1 = process-token as returned from H_ATTACH_CA_PROCESS when
+ *              process was attached.
+ */
+long cxl_h_terminate_process(u64 unit_address, u64 process_token)
+{
+	return cxl_h_control_function(unit_address,
+				H_CONTROL_CA_FUNCTION_TERMINATE_PROCESS,
+				process_token, 0, 0, 0,
+				NULL);
+}
+
+/**
+ * cxl_h_collect_vpd - Collect VPD for the coherent platform function.
+ * Parameter1 = # of VPD record to retrieve, valid values are between 0
+ *              and (ibm,#config-records - 1).
+ * Parameter2 = 4K naturally aligned real buffer containing block
+ *              list entries
+ * Parameter3 = number of block list entries in the block list, valid
+ *              values are between 0 and 256
+ */
+long cxl_h_collect_vpd(u64 unit_address, u64 record, u64 list_address,
+		       u64 num, u64 *out)
+{
+	return cxl_h_control_function(unit_address,
+				H_CONTROL_CA_FUNCTION_COLLECT_VPD,
+				record, list_address, num, 0,
+				out);
+}
+
+/**
+ * cxl_h_get_fn_error_interrupt - Read the function-wide error data based on an interrupt
+ */
+long cxl_h_get_fn_error_interrupt(u64 unit_address, u64 *reg)
+{
+	return cxl_h_control_function(unit_address,
+				H_CONTROL_CA_FUNCTION_GET_FUNCTION_ERR_INT,
+				0, 0, 0, 0, reg);
+}
+
+/**
+ * cxl_h_ack_fn_error_interrupt - Acknowledge function-wide error data
+ *                                based on an interrupt
+ * Parameter1 = value to write to the function-wide error interrupt register
+ */
+long cxl_h_ack_fn_error_interrupt(u64 unit_address, u64 value)
+{
+	return cxl_h_control_function(unit_address,
+				H_CONTROL_CA_FUNCTION_ACK_FUNCTION_ERR_INT,
+				value, 0, 0, 0,
+				NULL);
+}
+
+/**
+ * cxl_h_get_error_log - Retrieve the Platform Log ID (PLID) of
+ *                       an error log
+ */
+long cxl_h_get_error_log(u64 unit_address, u64 value)
+{
+	return cxl_h_control_function(unit_address,
+				H_CONTROL_CA_FUNCTION_GET_ERROR_LOG,
+				0, 0, 0, 0,
+				NULL);
+}
+
+/**
+ * cxl_h_collect_int_info - Collect interrupt info about a coherent
+ *                          platform function after an interrupt occurred.
+ */
+long cxl_h_collect_int_info(u64 unit_address, u64 process_token,
+			    struct cxl_irq_info *info)
+{
+	long rc;
+
+	BUG_ON(sizeof(*info) != sizeof(unsigned long[PLPAR_HCALL9_BUFSIZE]));
+
+	rc = plpar_hcall9(H_COLLECT_CA_INT_INFO, (unsigned long *) info,
+			unit_address, process_token);
+	_PRINT_MSG(rc, "cxl_h_collect_int_info(%#.16llx, 0x%llx): %li\n",
+		unit_address, process_token, rc);
+	trace_cxl_hcall_collect_int_info(unit_address, process_token, rc);
+
+	switch (rc) {
+	case H_SUCCESS:     /* The interrupt info is returned in return registers. */
+		pr_devel("dsisr:%#llx, dar:%#llx, dsr:%#llx, pid:%u, tid:%u, afu_err:%#llx, errstat:%#llx\n",
+			info->dsisr, info->dar, info->dsr, info->pid,
+			info->tid, info->afu_err, info->errstat);
+		return 0;
+	case H_PARAMETER:   /* An incorrect parameter was supplied. */
+		return -EINVAL;
+	case H_AUTHORITY:   /* The partition does not have authority to perform this hcall. */
+	case H_HARDWARE:    /* A hardware event prevented the collection of the interrupt info.*/
+	case H_STATE:       /* The coherent platform function is not in a valid state to collect interrupt info. */
+		return -EBUSY;
+	default:
+		WARN(1, "Unexpected return code: %lx", rc);
+		return -EINVAL;
+	}
+}
+
+/**
+ * cxl_h_control_faults - Control the operation of a coherent platform
+ *                        function after a fault occurs.
+ *
+ * Parameters
+ *    control-mask: value to control the faults
+ *                  looks like PSL_TFC_An shifted >> 32
+ *    reset-mask: mask to control reset of function faults
+ *                Set reset_mask = 1 to reset PSL errors
+ */
+long cxl_h_control_faults(u64 unit_address, u64 process_token,
+			  u64 control_mask, u64 reset_mask)
+{
+	unsigned long retbuf[PLPAR_HCALL_BUFSIZE];
+	long rc;
+
+	memset(retbuf, 0, sizeof(retbuf));
+
+	rc = plpar_hcall(H_CONTROL_CA_FAULTS, retbuf, unit_address,
+			H_CONTROL_CA_FAULTS_RESPOND_PSL, process_token,
+			control_mask, reset_mask);
+	_PRINT_MSG(rc, "cxl_h_control_faults(%#.16llx, 0x%llx, %#llx, %#llx): %li (%#lx)\n",
+		unit_address, process_token, control_mask, reset_mask,
+		rc, retbuf[0]);
+	trace_cxl_hcall_control_faults(unit_address, process_token,
+				control_mask, reset_mask, retbuf[0], rc);
+
+	switch (rc) {
+	case H_SUCCESS:    /* Faults were successfully controlled for the function. */
+		return 0;
+	case H_PARAMETER:  /* An incorrect parameter was supplied. */
+		return -EINVAL;
+	case H_HARDWARE:   /* A hardware event prevented the control of faults. */
+	case H_STATE:      /* The function was in an invalid state. */
+	case H_AUTHORITY:  /* The partition does not have authority to perform this hcall; the coherent platform facilities may need to be licensed. */
+		return -EBUSY;
+	case H_FUNCTION:   /* The function is not supported */
+	case H_NOT_FOUND:  /* The operation supplied was not valid */
+		return -EINVAL;
+	default:
+		WARN(1, "Unexpected return code: %lx", rc);
+		return -EINVAL;
+	}
+}
+
+/**
+ * cxl_h_control_facility - This H_CONTROL_CA_FACILITY hypervisor call
+ *                          allows the partition to manipulate or query
+ *                          certain coherent platform facility behaviors.
+ */
+static long cxl_h_control_facility(u64 unit_address, u64 op,
+				   u64 p1, u64 p2, u64 p3, u64 p4, u64 *out)
+{
+	unsigned long retbuf[PLPAR_HCALL9_BUFSIZE];
+	long rc;
+
+	CXL_H9_WAIT_UNTIL_DONE(rc, retbuf, H_CONTROL_CA_FACILITY, unit_address, op, p1, p2, p3, p4);
+	_PRINT_MSG(rc, "cxl_h_control_facility(%#.16llx, %s(%#llx, %#llx, %#llx, %#llx, R4: %#lx)): %li\n",
+		unit_address, OP_STR_CONTROL_ADAPTER(op), p1, p2, p3, p4, retbuf[0], rc);
+	trace_cxl_hcall_control_facility(unit_address, OP_STR_CONTROL_ADAPTER(op), p1, p2, p3, p4, retbuf[0], rc);
+
+	switch (rc) {
+	case H_SUCCESS:       /* The operation is completed for the coherent platform facility */
+		if (op == H_CONTROL_CA_FACILITY_COLLECT_VPD)
+			*out = retbuf[0];
+		return 0;
+	case H_PARAMETER:     /* An incorrect parameter was supplied. */
+	case H_FUNCTION:      /* The function is not supported. */
+	case H_NOT_FOUND:     /* The operation supplied was not valid */
+	case H_NOT_AVAILABLE: /* The operation cannot be performed because the AFU has not been downloaded */
+	case H_SG_LIST:       /* An block list entry was invalid */
+		return -EINVAL;
+	case H_AUTHORITY:     /* The partition does not have authority to perform this hcall */
+	case H_RESOURCE:      /* The function has page table mappings for MMIO */
+	case H_HARDWARE:      /* A hardware event prevented the attach operation */
+	case H_STATE:         /* The coherent platform facility is not in a valid state */
+	case H_BUSY:
+		return -EBUSY;
+	default:
+		WARN(1, "Unexpected return code: %lx", rc);
+		return -EINVAL;
+	}
+}
+
+/**
+ * cxl_h_reset_adapter - Perform a reset to the coherent platform facility.
+ */
+long cxl_h_reset_adapter(u64 unit_address)
+{
+	return cxl_h_control_facility(unit_address,
+				H_CONTROL_CA_FACILITY_RESET,
+				0, 0, 0, 0,
+				NULL);
+}
+
+/**
+ * cxl_h_collect_vpd - Collect VPD for the coherent platform function.
+ * Parameter1 = 4K naturally aligned real buffer containing block
+ *              list entries
+ * Parameter2 = number of block list entries in the block list, valid
+ *              values are between 0 and 256
+ */
+long cxl_h_collect_vpd_adapter(u64 unit_address, u64 list_address,
+			       u64 num, u64 *out)
+{
+	return cxl_h_control_facility(unit_address,
+				H_CONTROL_CA_FACILITY_COLLECT_VPD,
+				list_address, num, 0, 0,
+				out);
+}
+
+/**
+ * cxl_h_download_facility - This H_DOWNLOAD_CA_FACILITY
+ *                    hypervisor call provide platform support for
+ *                    downloading a base adapter image to the coherent
+ *                    platform facility, and for validating the entire
+ *                    image after the download.
+ * Parameters
+ *    op: operation to perform to the coherent platform function
+ *      Download: operation = 1, the base image in the coherent platform
+ *                               facility is first erased, and then
+ *                               programmed using the image supplied
+ *                               in the scatter/gather list.
+ *      Validate: operation = 2, the base image in the coherent platform
+ *                               facility is compared with the image
+ *                               supplied in the scatter/gather list.
+ *    list_address: 4K naturally aligned real buffer containing
+ *                  scatter/gather list entries.
+ *    num: number of block list entries in the scatter/gather list.
+ */
+static long cxl_h_download_facility(u64 unit_address, u64 op,
+				    u64 list_address, u64 num,
+				    u64 *out)
+{
+	unsigned long retbuf[PLPAR_HCALL_BUFSIZE];
+	unsigned int delay, total_delay = 0;
+	u64 token = 0;
+	long rc;
+
+	if (*out != 0)
+		token = *out;
+
+	memset(retbuf, 0, sizeof(retbuf));
+	while (1) {
+		rc = plpar_hcall(H_DOWNLOAD_CA_FACILITY, retbuf,
+				 unit_address, op, list_address, num,
+				 token);
+		token = retbuf[0];
+		if (rc != H_BUSY && !H_IS_LONG_BUSY(rc))
+			break;
+
+		if (rc != H_BUSY) {
+			delay = get_longbusy_msecs(rc);
+			total_delay += delay;
+			if (total_delay > CXL_HCALL_TIMEOUT_DOWNLOAD) {
+				WARN(1, "Warning: Giving up waiting for CXL hcall "
+					"%#x after %u msec\n",
+					H_DOWNLOAD_CA_FACILITY, total_delay);
+				rc = H_BUSY;
+				break;
+			}
+			msleep(delay);
+		}
+	}
+	_PRINT_MSG(rc, "cxl_h_download_facility(%#.16llx, %s(%#llx, %#llx), %#lx): %li\n",
+		 unit_address, OP_STR_DOWNLOAD_ADAPTER(op), list_address, num, retbuf[0], rc);
+	trace_cxl_hcall_download_facility(unit_address, OP_STR_DOWNLOAD_ADAPTER(op), list_address, num, retbuf[0], rc);
+
+	switch (rc) {
+	case H_SUCCESS:       /* The operation is completed for the coherent platform facility */
+		return 0;
+	case H_PARAMETER:     /* An incorrect parameter was supplied */
+	case H_FUNCTION:      /* The function is not supported. */
+	case H_SG_LIST:       /* An block list entry was invalid */
+	case H_BAD_DATA:      /* Image verification failed */
+		return -EINVAL;
+	case H_AUTHORITY:     /* The partition does not have authority to perform this hcall */
+	case H_RESOURCE:      /* The function has page table mappings for MMIO */
+	case H_HARDWARE:      /* A hardware event prevented the attach operation */
+	case H_STATE:         /* The coherent platform facility is not in a valid state */
+	case H_BUSY:
+		return -EBUSY;
+	case H_CONTINUE:
+		*out = retbuf[0];
+		return 1;  /* More data is needed for the complete image */
+	default:
+		WARN(1, "Unexpected return code: %lx", rc);
+		return -EINVAL;
+	}
+}
+
+/**
+ * cxl_h_download_adapter_image - Download the base image to the coherent
+ *                                platform facility.
+ */
+long cxl_h_download_adapter_image(u64 unit_address,
+				  u64 list_address, u64 num,
+				  u64 *out)
+{
+	return cxl_h_download_facility(unit_address,
+				       H_DOWNLOAD_CA_FACILITY_DOWNLOAD,
+				       list_address, num, out);
+}
+
+/**
+ * cxl_h_validate_adapter_image - Validate the base image in the coherent
+ *                                platform facility.
+ */
+long cxl_h_validate_adapter_image(u64 unit_address,
+				  u64 list_address, u64 num,
+				  u64 *out)
+{
+	return cxl_h_download_facility(unit_address,
+				       H_DOWNLOAD_CA_FACILITY_VALIDATE,
+				       list_address, num, out);
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/misc/cxl/hcalls.h
@@ -0,0 +1,204 @@
+/*
+ * Copyright 2015 IBM Corp.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _HCALLS_H
+#define _HCALLS_H
+
+#include <linux/types.h>
+#include <asm/byteorder.h>
+#include <asm/hvcall.h>
+#include "cxl.h"
+
+#define SG_BUFFER_SIZE 4096
+#define SG_MAX_ENTRIES 256
+
+struct sg_list {
+	u64 phys_addr;
+	u64 len;
+};
+
+/*
+ * This is straight out of PAPR, but replacing some of the compound fields with
+ * a single field, where they were identical to the register layout.
+ *
+ * The 'flags' parameter regroups the various bit-fields
+ */
+#define CXL_PE_CSRP_VALID			(1ULL << 63)
+#define CXL_PE_PROBLEM_STATE			(1ULL << 62)
+#define CXL_PE_SECONDARY_SEGMENT_TBL_SRCH	(1ULL << 61)
+#define CXL_PE_TAGS_ACTIVE			(1ULL << 60)
+#define CXL_PE_USER_STATE			(1ULL << 59)
+#define CXL_PE_TRANSLATION_ENABLED		(1ULL << 58)
+#define CXL_PE_64_BIT				(1ULL << 57)
+#define CXL_PE_PRIVILEGED_PROCESS		(1ULL << 56)
+
+#define CXL_PROCESS_ELEMENT_VERSION 1
+struct cxl_process_element_hcall {
+	__be64 version;
+	__be64 flags;
+	u8     reserved0[12];
+	__be32 pslVirtualIsn;
+	u8     applicationVirtualIsnBitmap[256];
+	u8     reserved1[144];
+	struct cxl_process_element_common common;
+	u8     reserved4[12];
+} __packed;
+
+#define H_STATE_NORMAL              1
+#define H_STATE_DISABLE             2
+#define H_STATE_TEMP_UNAVAILABLE    3
+#define H_STATE_PERM_UNAVAILABLE    4
+
+/* NOTE: element must be a logical real address, and must be pinned */
+long cxl_h_attach_process(u64 unit_address, struct cxl_process_element_hcall *element,
+			u64 *process_token, u64 *mmio_addr, u64 *mmio_size);
+
+/**
+ * cxl_h_detach_process - Detach a process element from a coherent
+ *                        platform function.
+ */
+long cxl_h_detach_process(u64 unit_address, u64 process_token);
+
+/**
+ * cxl_h_reset_afu - Perform a reset to the coherent platform function.
+ */
+long cxl_h_reset_afu(u64 unit_address);
+
+/**
+ * cxl_h_suspend_process - Suspend a process from being executed
+ * Parameter1 = process-token as returned from H_ATTACH_CA_PROCESS when
+ *              process was attached.
+ */
+long cxl_h_suspend_process(u64 unit_address, u64 process_token);
+
+/**
+ * cxl_h_resume_process - Resume a process to be executed
+ * Parameter1 = process-token as returned from H_ATTACH_CA_PROCESS when
+ *              process was attached.
+ */
+long cxl_h_resume_process(u64 unit_address, u64 process_token);
+
+/**
+ * cxl_h_read_error_state - Reads the error state of the coherent
+ *                          platform function.
+ * R4 contains the error state
+ */
+long cxl_h_read_error_state(u64 unit_address, u64 *state);
+
+/**
+ * cxl_h_get_afu_err - collect the AFU error buffer
+ * Parameter1 = byte offset into error buffer to retrieve, valid values
+ *              are between 0 and (ibm,error-buffer-size - 1)
+ * Parameter2 = 4K aligned real address of error buffer, to be filled in
+ * Parameter3 = length of error buffer, valid values are 4K or less
+ */
+long cxl_h_get_afu_err(u64 unit_address, u64 offset, u64 buf_address, u64 len);
+
+/**
+ * cxl_h_get_config - collect configuration record for the
+ *                    coherent platform function
+ * Parameter1 = # of configuration record to retrieve, valid values are
+ *              between 0 and (ibm,#config-records - 1)
+ * Parameter2 = byte offset into configuration record to retrieve,
+ *              valid values are between 0 and (ibm,config-record-size - 1)
+ * Parameter3 = 4K aligned real address of configuration record buffer,
+ *              to be filled in
+ * Parameter4 = length of configuration buffer, valid values are 4K or less
+ */
+long cxl_h_get_config(u64 unit_address, u64 cr_num, u64 offset,
+		u64 buf_address, u64 len);
+
+/**
+ * cxl_h_terminate_process - Terminate the process before completion
+ * Parameter1 = process-token as returned from H_ATTACH_CA_PROCESS when
+ *              process was attached.
+ */
+long cxl_h_terminate_process(u64 unit_address, u64 process_token);
+
+/**
+ * cxl_h_collect_vpd - Collect VPD for the coherent platform function.
+ * Parameter1 = # of VPD record to retrieve, valid values are between 0
+ *              and (ibm,#config-records - 1).
+ * Parameter2 = 4K naturally aligned real buffer containing block
+ *              list entries
+ * Parameter3 = number of block list entries in the block list, valid
+ *              values are between 0 and 256
+ */
+long cxl_h_collect_vpd(u64 unit_address, u64 record, u64 list_address,
+		       u64 num, u64 *out);
+
+/**
+ * cxl_h_get_fn_error_interrupt - Read the function-wide error data based on an interrupt
+ */
+long cxl_h_get_fn_error_interrupt(u64 unit_address, u64 *reg);
+
+/**
+ * cxl_h_ack_fn_error_interrupt - Acknowledge function-wide error data
+ *                                based on an interrupt
+ * Parameter1 = value to write to the function-wide error interrupt register
+ */
+long cxl_h_ack_fn_error_interrupt(u64 unit_address, u64 value);
+
+/**
+ * cxl_h_get_error_log - Retrieve the Platform Log ID (PLID) of
+ *                       an error log
+ */
+long cxl_h_get_error_log(u64 unit_address, u64 value);
+
+/**
+ * cxl_h_collect_int_info - Collect interrupt info about a coherent
+ *                          platform function after an interrupt occurred.
+ */
+long cxl_h_collect_int_info(u64 unit_address, u64 process_token,
+			struct cxl_irq_info *info);
+
+/**
+ * cxl_h_control_faults - Control the operation of a coherent platform
+ *                        function after a fault occurs.
+ *
+ * Parameters
+ *    control-mask: value to control the faults
+ *                  looks like PSL_TFC_An shifted >> 32
+ *    reset-mask: mask to control reset of function faults
+ *                Set reset_mask = 1 to reset PSL errors
+ */
+long cxl_h_control_faults(u64 unit_address, u64 process_token,
+			u64 control_mask, u64 reset_mask);
+
+/**
+ * cxl_h_reset_adapter - Perform a reset to the coherent platform facility.
+ */
+long cxl_h_reset_adapter(u64 unit_address);
+
+/**
+ * cxl_h_collect_vpd - Collect VPD for the coherent platform function.
+ * Parameter1 = 4K naturally aligned real buffer containing block
+ *              list entries
+ * Parameter2 = number of block list entries in the block list, valid
+ *              values are between 0 and 256
+ */
+long cxl_h_collect_vpd_adapter(u64 unit_address, u64 list_address,
+			       u64 num, u64 *out);
+
+/**
+ * cxl_h_download_adapter_image - Download the base image to the coherent
+ *                                platform facility.
+ */
+long cxl_h_download_adapter_image(u64 unit_address,
+				  u64 list_address, u64 num,
+				  u64 *out);
+
+/**
+ * cxl_h_validate_adapter_image - Validate the base image in the coherent
+ *                                platform facility.
+ */
+long cxl_h_validate_adapter_image(u64 unit_address,
+				  u64 list_address, u64 num,
+				  u64 *out);
+#endif /* _HCALLS_H */
--- zfcpdump-kernel-4.4.orig/drivers/misc/cxl/irq.c
+++ zfcpdump-kernel-4.4/drivers/misc/cxl/irq.c
@@ -19,70 +19,11 @@
 #include "cxl.h"
 #include "trace.h"
 
-/* XXX: This is implementation specific */
-static irqreturn_t handle_psl_slice_error(struct cxl_context *ctx, u64 dsisr, u64 errstat)
+static int afu_irq_range_start(void)
 {
-	u64 fir1, fir2, fir_slice, serr, afu_debug;
-
-	fir1 = cxl_p1_read(ctx->afu->adapter, CXL_PSL_FIR1);
-	fir2 = cxl_p1_read(ctx->afu->adapter, CXL_PSL_FIR2);
-	fir_slice = cxl_p1n_read(ctx->afu, CXL_PSL_FIR_SLICE_An);
-	serr = cxl_p1n_read(ctx->afu, CXL_PSL_SERR_An);
-	afu_debug = cxl_p1n_read(ctx->afu, CXL_AFU_DEBUG_An);
-
-	dev_crit(&ctx->afu->dev, "PSL ERROR STATUS: 0x%016llx\n", errstat);
-	dev_crit(&ctx->afu->dev, "PSL_FIR1: 0x%016llx\n", fir1);
-	dev_crit(&ctx->afu->dev, "PSL_FIR2: 0x%016llx\n", fir2);
-	dev_crit(&ctx->afu->dev, "PSL_SERR_An: 0x%016llx\n", serr);
-	dev_crit(&ctx->afu->dev, "PSL_FIR_SLICE_An: 0x%016llx\n", fir_slice);
-	dev_crit(&ctx->afu->dev, "CXL_PSL_AFU_DEBUG_An: 0x%016llx\n", afu_debug);
-
-	dev_crit(&ctx->afu->dev, "STOPPING CXL TRACE\n");
-	cxl_stop_trace(ctx->afu->adapter);
-
-	return cxl_ack_irq(ctx, 0, errstat);
-}
-
-irqreturn_t cxl_slice_irq_err(int irq, void *data)
-{
-	struct cxl_afu *afu = data;
-	u64 fir_slice, errstat, serr, afu_debug;
-
-	WARN(irq, "CXL SLICE ERROR interrupt %i\n", irq);
-
-	serr = cxl_p1n_read(afu, CXL_PSL_SERR_An);
-	fir_slice = cxl_p1n_read(afu, CXL_PSL_FIR_SLICE_An);
-	errstat = cxl_p2n_read(afu, CXL_PSL_ErrStat_An);
-	afu_debug = cxl_p1n_read(afu, CXL_AFU_DEBUG_An);
-	dev_crit(&afu->dev, "PSL_SERR_An: 0x%016llx\n", serr);
-	dev_crit(&afu->dev, "PSL_FIR_SLICE_An: 0x%016llx\n", fir_slice);
-	dev_crit(&afu->dev, "CXL_PSL_ErrStat_An: 0x%016llx\n", errstat);
-	dev_crit(&afu->dev, "CXL_PSL_AFU_DEBUG_An: 0x%016llx\n", afu_debug);
-
-	cxl_p1n_write(afu, CXL_PSL_SERR_An, serr);
-
-	return IRQ_HANDLED;
-}
-
-static irqreturn_t cxl_irq_err(int irq, void *data)
-{
-	struct cxl *adapter = data;
-	u64 fir1, fir2, err_ivte;
-
-	WARN(1, "CXL ERROR interrupt %i\n", irq);
-
-	err_ivte = cxl_p1_read(adapter, CXL_PSL_ErrIVTE);
-	dev_crit(&adapter->dev, "PSL_ErrIVTE: 0x%016llx\n", err_ivte);
-
-	dev_crit(&adapter->dev, "STOPPING CXL TRACE\n");
-	cxl_stop_trace(adapter);
-
-	fir1 = cxl_p1_read(adapter, CXL_PSL_FIR1);
-	fir2 = cxl_p1_read(adapter, CXL_PSL_FIR2);
-
-	dev_crit(&adapter->dev, "PSL_FIR1: 0x%016llx\nPSL_FIR2: 0x%016llx\n", fir1, fir2);
-
-	return IRQ_HANDLED;
+	if (cpu_has_feature(CPU_FTR_HVMODE))
+		return 1;
+	return 0;
 }
 
 static irqreturn_t schedule_cxl_fault(struct cxl_context *ctx, u64 dsisr, u64 dar)
@@ -93,9 +34,8 @@ static irqreturn_t schedule_cxl_fault(st
 	return IRQ_HANDLED;
 }
 
-static irqreturn_t cxl_irq(int irq, void *data, struct cxl_irq_info *irq_info)
+irqreturn_t cxl_irq(int irq, struct cxl_context *ctx, struct cxl_irq_info *irq_info)
 {
-	struct cxl_context *ctx = data;
 	u64 dsisr, dar;
 
 	dsisr = irq_info->dsisr;
@@ -145,7 +85,8 @@ static irqreturn_t cxl_irq(int irq, void
 	if (dsisr & CXL_PSL_DSISR_An_UR)
 		pr_devel("CXL interrupt: AURP PTE not found\n");
 	if (dsisr & CXL_PSL_DSISR_An_PE)
-		return handle_psl_slice_error(ctx, dsisr, irq_info->errstat);
+		return cxl_ops->handle_psl_slice_error(ctx, dsisr,
+						irq_info->errstat);
 	if (dsisr & CXL_PSL_DSISR_An_AE) {
 		pr_devel("CXL interrupt: AFU Error 0x%016llx\n", irq_info->afu_err);
 
@@ -169,7 +110,7 @@ static irqreturn_t cxl_irq(int irq, void
 			wake_up_all(&ctx->wq);
 		}
 
-		cxl_ack_irq(ctx, CXL_PSL_TFC_An_A, 0);
+		cxl_ops->ack_irq(ctx, CXL_PSL_TFC_An_A, 0);
 		return IRQ_HANDLED;
 	}
 	if (dsisr & CXL_PSL_DSISR_An_OC)
@@ -179,54 +120,27 @@ static irqreturn_t cxl_irq(int irq, void
 	return IRQ_HANDLED;
 }
 
-static irqreturn_t fail_psl_irq(struct cxl_afu *afu, struct cxl_irq_info *irq_info)
-{
-	if (irq_info->dsisr & CXL_PSL_DSISR_TRANS)
-		cxl_p2n_write(afu, CXL_PSL_TFC_An, CXL_PSL_TFC_An_AE);
-	else
-		cxl_p2n_write(afu, CXL_PSL_TFC_An, CXL_PSL_TFC_An_A);
-
-	return IRQ_HANDLED;
-}
-
-static irqreturn_t cxl_irq_multiplexed(int irq, void *data)
-{
-	struct cxl_afu *afu = data;
-	struct cxl_context *ctx;
-	struct cxl_irq_info irq_info;
-	int ph = cxl_p2n_read(afu, CXL_PSL_PEHandle_An) & 0xffff;
-	int ret;
-
-	if ((ret = cxl_get_irq(afu, &irq_info))) {
-		WARN(1, "Unable to get CXL IRQ Info: %i\n", ret);
-		return fail_psl_irq(afu, &irq_info);
-	}
-
-	rcu_read_lock();
-	ctx = idr_find(&afu->contexts_idr, ph);
-	if (ctx) {
-		ret = cxl_irq(irq, ctx, &irq_info);
-		rcu_read_unlock();
-		return ret;
-	}
-	rcu_read_unlock();
-
-	WARN(1, "Unable to demultiplex CXL PSL IRQ for PE %i DSISR %016llx DAR"
-		" %016llx\n(Possible AFU HW issue - was a term/remove acked"
-		" with outstanding transactions?)\n", ph, irq_info.dsisr,
-		irq_info.dar);
-	return fail_psl_irq(afu, &irq_info);
-}
-
 static irqreturn_t cxl_irq_afu(int irq, void *data)
 {
 	struct cxl_context *ctx = data;
 	irq_hw_number_t hwirq = irqd_to_hwirq(irq_get_irq_data(irq));
-	int irq_off, afu_irq = 1;
+	int irq_off, afu_irq = 0;
 	__u16 range;
 	int r;
 
-	for (r = 1; r < CXL_IRQ_RANGES; r++) {
+	/*
+	 * Look for the interrupt number.
+	 * On bare-metal, we know range 0 only contains the PSL
+	 * interrupt so we could start counting at range 1 and initialize
+	 * afu_irq at 1.
+	 * In a guest, range 0 also contains AFU interrupts, so it must
+	 * be counted for. Therefore we initialize afu_irq at 0 to take into
+	 * account the PSL interrupt.
+	 *
+	 * For code-readability, it just seems easier to go over all
+	 * the ranges on bare-metal and guest. The end result is the same.
+	 */
+	for (r = 0; r < CXL_IRQ_RANGES; r++) {
 		irq_off = hwirq - ctx->irqs.offset[r];
 		range = ctx->irqs.range[r];
 		if (irq_off >= 0 && irq_off < range) {
@@ -236,7 +150,7 @@ static irqreturn_t cxl_irq_afu(int irq,
 		afu_irq += range;
 	}
 	if (unlikely(r >= CXL_IRQ_RANGES)) {
-		WARN(1, "Recieved AFU IRQ out of range for pe %i (virq %i hwirq %lx)\n",
+		WARN(1, "Received AFU IRQ out of range for pe %i (virq %i hwirq %lx)\n",
 		     ctx->pe, irq, hwirq);
 		return IRQ_HANDLED;
 	}
@@ -246,7 +160,7 @@ static irqreturn_t cxl_irq_afu(int irq,
 	       afu_irq, ctx->pe, irq, hwirq);
 
 	if (unlikely(!ctx->irq_bitmap)) {
-		WARN(1, "Recieved AFU IRQ for context with no IRQ bitmap\n");
+		WARN(1, "Received AFU IRQ for context with no IRQ bitmap\n");
 		return IRQ_HANDLED;
 	}
 	spin_lock(&ctx->lock);
@@ -272,7 +186,8 @@ unsigned int cxl_map_irq(struct cxl *ada
 		return 0;
 	}
 
-	cxl_setup_irq(adapter, hwirq, virq);
+	if (cxl_ops->setup_irq)
+		cxl_ops->setup_irq(adapter, hwirq, virq);
 
 	pr_devel("hwirq %#lx mapped to virq %u\n", hwirq, virq);
 
@@ -288,19 +203,18 @@ unsigned int cxl_map_irq(struct cxl *ada
 void cxl_unmap_irq(unsigned int virq, void *cookie)
 {
 	free_irq(virq, cookie);
-	irq_dispose_mapping(virq);
 }
 
-static int cxl_register_one_irq(struct cxl *adapter,
-				irq_handler_t handler,
-				void *cookie,
-				irq_hw_number_t *dest_hwirq,
-				unsigned int *dest_virq,
-				const char *name)
+int cxl_register_one_irq(struct cxl *adapter,
+			irq_handler_t handler,
+			void *cookie,
+			irq_hw_number_t *dest_hwirq,
+			unsigned int *dest_virq,
+			const char *name)
 {
 	int hwirq, virq;
 
-	if ((hwirq = cxl_alloc_one_irq(adapter)) < 0)
+	if ((hwirq = cxl_ops->alloc_one_irq(adapter)) < 0)
 		return hwirq;
 
 	if (!(virq = cxl_map_irq(adapter, hwirq, handler, cookie, name)))
@@ -312,108 +226,10 @@ static int cxl_register_one_irq(struct c
 	return 0;
 
 err:
-	cxl_release_one_irq(adapter, hwirq);
+	cxl_ops->release_one_irq(adapter, hwirq);
 	return -ENOMEM;
 }
 
-int cxl_register_psl_err_irq(struct cxl *adapter)
-{
-	int rc;
-
-	adapter->irq_name = kasprintf(GFP_KERNEL, "cxl-%s-err",
-				      dev_name(&adapter->dev));
-	if (!adapter->irq_name)
-		return -ENOMEM;
-
-	if ((rc = cxl_register_one_irq(adapter, cxl_irq_err, adapter,
-				       &adapter->err_hwirq,
-				       &adapter->err_virq,
-				       adapter->irq_name))) {
-		kfree(adapter->irq_name);
-		adapter->irq_name = NULL;
-		return rc;
-	}
-
-	cxl_p1_write(adapter, CXL_PSL_ErrIVTE, adapter->err_hwirq & 0xffff);
-
-	return 0;
-}
-
-void cxl_release_psl_err_irq(struct cxl *adapter)
-{
-	if (adapter->err_virq != irq_find_mapping(NULL, adapter->err_hwirq))
-		return;
-
-	cxl_p1_write(adapter, CXL_PSL_ErrIVTE, 0x0000000000000000);
-	cxl_unmap_irq(adapter->err_virq, adapter);
-	cxl_release_one_irq(adapter, adapter->err_hwirq);
-	kfree(adapter->irq_name);
-}
-
-int cxl_register_serr_irq(struct cxl_afu *afu)
-{
-	u64 serr;
-	int rc;
-
-	afu->err_irq_name = kasprintf(GFP_KERNEL, "cxl-%s-err",
-				      dev_name(&afu->dev));
-	if (!afu->err_irq_name)
-		return -ENOMEM;
-
-	if ((rc = cxl_register_one_irq(afu->adapter, cxl_slice_irq_err, afu,
-				       &afu->serr_hwirq,
-				       &afu->serr_virq, afu->err_irq_name))) {
-		kfree(afu->err_irq_name);
-		afu->err_irq_name = NULL;
-		return rc;
-	}
-
-	serr = cxl_p1n_read(afu, CXL_PSL_SERR_An);
-	serr = (serr & 0x00ffffffffff0000ULL) | (afu->serr_hwirq & 0xffff);
-	cxl_p1n_write(afu, CXL_PSL_SERR_An, serr);
-
-	return 0;
-}
-
-void cxl_release_serr_irq(struct cxl_afu *afu)
-{
-	if (afu->serr_virq != irq_find_mapping(NULL, afu->serr_hwirq))
-		return;
-
-	cxl_p1n_write(afu, CXL_PSL_SERR_An, 0x0000000000000000);
-	cxl_unmap_irq(afu->serr_virq, afu);
-	cxl_release_one_irq(afu->adapter, afu->serr_hwirq);
-	kfree(afu->err_irq_name);
-}
-
-int cxl_register_psl_irq(struct cxl_afu *afu)
-{
-	int rc;
-
-	afu->psl_irq_name = kasprintf(GFP_KERNEL, "cxl-%s",
-				      dev_name(&afu->dev));
-	if (!afu->psl_irq_name)
-		return -ENOMEM;
-
-	if ((rc = cxl_register_one_irq(afu->adapter, cxl_irq_multiplexed, afu,
-				    &afu->psl_hwirq, &afu->psl_virq,
-				    afu->psl_irq_name))) {
-		kfree(afu->psl_irq_name);
-		afu->psl_irq_name = NULL;
-	}
-	return rc;
-}
-
-void cxl_release_psl_irq(struct cxl_afu *afu)
-{
-	if (afu->psl_virq != irq_find_mapping(NULL, afu->psl_hwirq))
-		return;
-
-	cxl_unmap_irq(afu->psl_virq, afu);
-	cxl_release_one_irq(afu->adapter, afu->psl_hwirq);
-	kfree(afu->psl_irq_name);
-}
-
 void afu_irq_name_free(struct cxl_context *ctx)
 {
 	struct cxl_irq_name *irq_name, *tmp;
@@ -429,16 +245,33 @@ int afu_allocate_irqs(struct cxl_context
 {
 	int rc, r, i, j = 1;
 	struct cxl_irq_name *irq_name;
+	int alloc_count;
+
+	/*
+	 * In native mode, range 0 is reserved for the multiplexed
+	 * PSL interrupt. It has been allocated when the AFU was initialized.
+	 *
+	 * In a guest, the PSL interrupt is not mutliplexed, but per-context,
+	 * and is the first interrupt from range 0. It still needs to be
+	 * allocated, so bump the count by one.
+	 */
+	if (cpu_has_feature(CPU_FTR_HVMODE))
+		alloc_count = count;
+	else
+		alloc_count = count + 1;
 
 	/* Initialize the list head to hold irq names */
 	INIT_LIST_HEAD(&ctx->irq_names);
 
-	if ((rc = cxl_alloc_irq_ranges(&ctx->irqs, ctx->afu->adapter, count)))
+	if ((rc = cxl_ops->alloc_irq_ranges(&ctx->irqs, ctx->afu->adapter,
+							alloc_count)))
 		return rc;
 
-	/* Multiplexed PSL Interrupt */
-	ctx->irqs.offset[0] = ctx->afu->psl_hwirq;
-	ctx->irqs.range[0] = 1;
+	if (cpu_has_feature(CPU_FTR_HVMODE)) {
+		/* Multiplexed PSL Interrupt */
+		ctx->irqs.offset[0] = ctx->afu->native->psl_hwirq;
+		ctx->irqs.range[0] = 1;
+	}
 
 	ctx->irq_count = count;
 	ctx->irq_bitmap = kcalloc(BITS_TO_LONGS(count),
@@ -450,7 +283,7 @@ int afu_allocate_irqs(struct cxl_context
 	 * Allocate names first.  If any fail, bail out before allocating
 	 * actual hardware IRQs.
 	 */
-	for (r = 1; r < CXL_IRQ_RANGES; r++) {
+	for (r = afu_irq_range_start(); r < CXL_IRQ_RANGES; r++) {
 		for (i = 0; i < ctx->irqs.range[r]; i++) {
 			irq_name = kmalloc(sizeof(struct cxl_irq_name),
 					   GFP_KERNEL);
@@ -471,7 +304,7 @@ int afu_allocate_irqs(struct cxl_context
 	return 0;
 
 out:
-	cxl_release_irq_ranges(&ctx->irqs, ctx->afu->adapter);
+	cxl_ops->release_irq_ranges(&ctx->irqs, ctx->afu->adapter);
 	afu_irq_name_free(ctx);
 	return -ENOMEM;
 }
@@ -480,15 +313,30 @@ static void afu_register_hwirqs(struct c
 {
 	irq_hw_number_t hwirq;
 	struct cxl_irq_name *irq_name;
-	int r,i;
+	int r, i;
+	irqreturn_t (*handler)(int irq, void *data);
 
 	/* We've allocated all memory now, so let's do the irq allocations */
 	irq_name = list_first_entry(&ctx->irq_names, struct cxl_irq_name, list);
-	for (r = 1; r < CXL_IRQ_RANGES; r++) {
+	for (r = afu_irq_range_start(); r < CXL_IRQ_RANGES; r++) {
 		hwirq = ctx->irqs.offset[r];
 		for (i = 0; i < ctx->irqs.range[r]; hwirq++, i++) {
-			cxl_map_irq(ctx->afu->adapter, hwirq,
-				    cxl_irq_afu, ctx, irq_name->name);
+			if (r == 0 && i == 0)
+				/*
+				 * The very first interrupt of range 0 is
+				 * always the PSL interrupt, but we only
+				 * need to connect a handler for guests,
+				 * because there's one PSL interrupt per
+				 * context.
+				 * On bare-metal, the PSL interrupt is
+				 * multiplexed and was setup when the AFU
+				 * was configured.
+				 */
+				handler = cxl_ops->psl_interrupt;
+			else
+				handler = cxl_irq_afu;
+			cxl_map_irq(ctx->afu->adapter, hwirq, handler, ctx,
+				irq_name->name);
 			irq_name = list_next_entry(irq_name, list);
 		}
 	}
@@ -504,7 +352,7 @@ int afu_register_irqs(struct cxl_context
 
 	afu_register_hwirqs(ctx);
 	return 0;
- }
+}
 
 void afu_release_irqs(struct cxl_context *ctx, void *cookie)
 {
@@ -512,7 +360,7 @@ void afu_release_irqs(struct cxl_context
 	unsigned int virq;
 	int r, i;
 
-	for (r = 1; r < CXL_IRQ_RANGES; r++) {
+	for (r = afu_irq_range_start(); r < CXL_IRQ_RANGES; r++) {
 		hwirq = ctx->irqs.offset[r];
 		for (i = 0; i < ctx->irqs.range[r]; hwirq++, i++) {
 			virq = irq_find_mapping(NULL, hwirq);
@@ -522,7 +370,7 @@ void afu_release_irqs(struct cxl_context
 	}
 
 	afu_irq_name_free(ctx);
-	cxl_release_irq_ranges(&ctx->irqs, ctx->afu->adapter);
+	cxl_ops->release_irq_ranges(&ctx->irqs, ctx->afu->adapter);
 
 	ctx->irq_count = 0;
 }
--- zfcpdump-kernel-4.4.orig/drivers/misc/cxl/main.c
+++ zfcpdump-kernel-4.4/drivers/misc/cxl/main.c
@@ -32,6 +32,29 @@ uint cxl_verbose;
 module_param_named(verbose, cxl_verbose, uint, 0600);
 MODULE_PARM_DESC(verbose, "Enable verbose dmesg output");
 
+const struct cxl_backend_ops *cxl_ops;
+
+int cxl_afu_slbia(struct cxl_afu *afu)
+{
+	unsigned long timeout = jiffies + (HZ * CXL_TIMEOUT);
+
+	pr_devel("cxl_afu_slbia issuing SLBIA command\n");
+	cxl_p2n_write(afu, CXL_SLBIA_An, CXL_TLB_SLB_IQ_ALL);
+	while (cxl_p2n_read(afu, CXL_SLBIA_An) & CXL_TLB_SLB_P) {
+		if (time_after_eq(jiffies, timeout)) {
+			dev_warn(&afu->dev, "WARNING: CXL AFU SLBIA timed out!\n");
+			return -EBUSY;
+		}
+		/* If the adapter has gone down, we can assume that we
+		 * will PERST it and that will invalidate everything.
+		 */
+		if (!cxl_ops->link_ok(afu->adapter, afu))
+			return -EIO;
+		cpu_relax();
+	}
+	return 0;
+}
+
 static inline void _cxl_slbia(struct cxl_context *ctx, struct mm_struct *mm)
 {
 	struct task_struct *task;
@@ -139,6 +162,32 @@ int cxl_alloc_sst(struct cxl_context *ct
 	return 0;
 }
 
+/* print buffer content as integers when debugging */
+void cxl_dump_debug_buffer(void *buf, size_t buf_len)
+{
+#ifdef DEBUG
+	int i, *ptr;
+
+	/*
+	 * We want to regroup up to 4 integers per line, which means they
+	 * need to be in the same pr_devel() statement
+	 */
+	ptr = (int *) buf;
+	for (i = 0; i * 4 < buf_len; i += 4) {
+		if ((i + 3) * 4 < buf_len)
+			pr_devel("%.8x %.8x %.8x %.8x\n", ptr[i], ptr[i + 1],
+				ptr[i + 2], ptr[i + 3]);
+		else if ((i + 2) * 4 < buf_len)
+			pr_devel("%.8x %.8x %.8x\n", ptr[i], ptr[i + 1],
+				ptr[i + 2]);
+		else if ((i + 1) * 4 < buf_len)
+			pr_devel("%.8x %.8x\n", ptr[i], ptr[i + 1]);
+		else
+			pr_devel("%.8x\n", ptr[i]);
+	}
+#endif /* DEBUG */
+}
+
 /* Find a CXL adapter by it's number and increase it's refcount */
 struct cxl *get_cxl_adapter(int num)
 {
@@ -152,7 +201,7 @@ struct cxl *get_cxl_adapter(int num)
 	return adapter;
 }
 
-int cxl_alloc_adapter_nr(struct cxl *adapter)
+static int cxl_alloc_adapter_nr(struct cxl *adapter)
 {
 	int i;
 
@@ -174,13 +223,58 @@ void cxl_remove_adapter_nr(struct cxl *a
 	idr_remove(&cxl_adapter_idr, adapter->adapter_num);
 }
 
+struct cxl *cxl_alloc_adapter(void)
+{
+	struct cxl *adapter;
+
+	if (!(adapter = kzalloc(sizeof(struct cxl), GFP_KERNEL)))
+		return NULL;
+
+	spin_lock_init(&adapter->afu_list_lock);
+
+	if (cxl_alloc_adapter_nr(adapter))
+		goto err1;
+
+	if (dev_set_name(&adapter->dev, "card%i", adapter->adapter_num))
+		goto err2;
+
+	return adapter;
+
+err2:
+	cxl_remove_adapter_nr(adapter);
+err1:
+	kfree(adapter);
+	return NULL;
+}
+
+struct cxl_afu *cxl_alloc_afu(struct cxl *adapter, int slice)
+{
+	struct cxl_afu *afu;
+
+	if (!(afu = kzalloc(sizeof(struct cxl_afu), GFP_KERNEL)))
+		return NULL;
+
+	afu->adapter = adapter;
+	afu->dev.parent = &adapter->dev;
+	afu->dev.release = cxl_ops->release_afu;
+	afu->slice = slice;
+	idr_init(&afu->contexts_idr);
+	mutex_init(&afu->contexts_lock);
+	spin_lock_init(&afu->afu_cntl_lock);
+
+	afu->prefault_mode = CXL_PREFAULT_NONE;
+	afu->irqs_max = afu->adapter->user_irqs;
+
+	return afu;
+}
+
 int cxl_afu_select_best_mode(struct cxl_afu *afu)
 {
 	if (afu->modes_supported & CXL_MODE_DIRECTED)
-		return cxl_afu_activate_mode(afu, CXL_MODE_DIRECTED);
+		return cxl_ops->afu_activate_mode(afu, CXL_MODE_DIRECTED);
 
 	if (afu->modes_supported & CXL_MODE_DEDICATED)
-		return cxl_afu_activate_mode(afu, CXL_MODE_DEDICATED);
+		return cxl_ops->afu_activate_mode(afu, CXL_MODE_DEDICATED);
 
 	dev_warn(&afu->dev, "No supported programming modes available\n");
 	/* We don't fail this so the user can inspect sysfs */
@@ -191,9 +285,6 @@ static int __init init_cxl(void)
 {
 	int rc = 0;
 
-	if (!cpu_has_feature(CPU_FTR_HVMODE))
-		return -EPERM;
-
 	if ((rc = cxl_file_init()))
 		return rc;
 
@@ -202,7 +293,17 @@ static int __init init_cxl(void)
 	if ((rc = register_cxl_calls(&cxl_calls)))
 		goto err;
 
-	if ((rc = pci_register_driver(&cxl_pci_driver)))
+	if (cpu_has_feature(CPU_FTR_HVMODE)) {
+		cxl_ops = &cxl_native_ops;
+		rc = pci_register_driver(&cxl_pci_driver);
+	}
+#ifdef CONFIG_PPC_PSERIES
+	else {
+		cxl_ops = &cxl_guest_ops;
+		rc = platform_driver_register(&cxl_of_driver);
+	}
+#endif
+	if (rc)
 		goto err1;
 
 	return 0;
@@ -217,7 +318,12 @@ err:
 
 static void exit_cxl(void)
 {
-	pci_unregister_driver(&cxl_pci_driver);
+	if (cpu_has_feature(CPU_FTR_HVMODE))
+		pci_unregister_driver(&cxl_pci_driver);
+#ifdef CONFIG_PPC_PSERIES
+	else
+		platform_driver_unregister(&cxl_of_driver);
+#endif
 
 	cxl_debugfs_exit();
 	cxl_file_exit();
--- zfcpdump-kernel-4.4.orig/drivers/misc/cxl/native.c
+++ zfcpdump-kernel-4.4/drivers/misc/cxl/native.c
@@ -14,6 +14,7 @@
 #include <linux/mutex.h>
 #include <linux/mm.h>
 #include <linux/uaccess.h>
+#include <linux/delay.h>
 #include <asm/synch.h>
 #include <misc/cxl-base.h>
 
@@ -42,7 +43,7 @@ static int afu_control(struct cxl_afu *a
 			goto out;
 		}
 
-		if (!cxl_adapter_link_ok(afu->adapter)) {
+		if (!cxl_ops->link_ok(afu->adapter, afu)) {
 			afu->enabled = enabled;
 			rc = -EIO;
 			goto out;
@@ -80,7 +81,7 @@ int cxl_afu_disable(struct cxl_afu *afu)
 }
 
 /* This will disable as well as reset */
-int __cxl_afu_reset(struct cxl_afu *afu)
+static int native_afu_reset(struct cxl_afu *afu)
 {
 	pr_devel("AFU reset request\n");
 
@@ -90,9 +91,9 @@ int __cxl_afu_reset(struct cxl_afu *afu)
 			   false);
 }
 
-int cxl_afu_check_and_enable(struct cxl_afu *afu)
+static int native_afu_check_and_enable(struct cxl_afu *afu)
 {
-	if (!cxl_adapter_link_ok(afu->adapter)) {
+	if (!cxl_ops->link_ok(afu->adapter, afu)) {
 		WARN(1, "Refusing to enable afu while link down!\n");
 		return -EIO;
 	}
@@ -114,7 +115,7 @@ int cxl_psl_purge(struct cxl_afu *afu)
 
 	pr_devel("PSL purge request\n");
 
-	if (!cxl_adapter_link_ok(afu->adapter)) {
+	if (!cxl_ops->link_ok(afu->adapter, afu)) {
 		dev_warn(&afu->dev, "PSL Purge called with link down, ignoring\n");
 		rc = -EIO;
 		goto out;
@@ -136,7 +137,7 @@ int cxl_psl_purge(struct cxl_afu *afu)
 			rc = -EBUSY;
 			goto out;
 		}
-		if (!cxl_adapter_link_ok(afu->adapter)) {
+		if (!cxl_ops->link_ok(afu->adapter, afu)) {
 			rc = -EIO;
 			goto out;
 		}
@@ -186,22 +187,22 @@ static int spa_max_procs(int spa_size)
 int cxl_alloc_spa(struct cxl_afu *afu)
 {
 	/* Work out how many pages to allocate */
-	afu->spa_order = 0;
+	afu->native->spa_order = 0;
 	do {
-		afu->spa_order++;
-		afu->spa_size = (1 << afu->spa_order) * PAGE_SIZE;
-		afu->spa_max_procs = spa_max_procs(afu->spa_size);
-	} while (afu->spa_max_procs < afu->num_procs);
+		afu->native->spa_order++;
+		afu->native->spa_size = (1 << afu->native->spa_order) * PAGE_SIZE;
+		afu->native->spa_max_procs = spa_max_procs(afu->native->spa_size);
+	} while (afu->native->spa_max_procs < afu->num_procs);
 
-	WARN_ON(afu->spa_size > 0x100000); /* Max size supported by the hardware */
+	WARN_ON(afu->native->spa_size > 0x100000); /* Max size supported by the hardware */
 
-	if (!(afu->spa = (struct cxl_process_element *)
-	      __get_free_pages(GFP_KERNEL | __GFP_ZERO, afu->spa_order))) {
+	if (!(afu->native->spa = (struct cxl_process_element *)
+	      __get_free_pages(GFP_KERNEL | __GFP_ZERO, afu->native->spa_order))) {
 		pr_err("cxl_alloc_spa: Unable to allocate scheduled process area\n");
 		return -ENOMEM;
 	}
 	pr_devel("spa pages: %i afu->spa_max_procs: %i   afu->num_procs: %i\n",
-		 1<<afu->spa_order, afu->spa_max_procs, afu->num_procs);
+		 1<<afu->native->spa_order, afu->native->spa_max_procs, afu->num_procs);
 
 	return 0;
 }
@@ -210,13 +211,15 @@ static void attach_spa(struct cxl_afu *a
 {
 	u64 spap;
 
-	afu->sw_command_status = (__be64 *)((char *)afu->spa +
-					    ((afu->spa_max_procs + 3) * 128));
+	afu->native->sw_command_status = (__be64 *)((char *)afu->native->spa +
+					    ((afu->native->spa_max_procs + 3) * 128));
 
-	spap = virt_to_phys(afu->spa) & CXL_PSL_SPAP_Addr;
-	spap |= ((afu->spa_size >> (12 - CXL_PSL_SPAP_Size_Shift)) - 1) & CXL_PSL_SPAP_Size;
+	spap = virt_to_phys(afu->native->spa) & CXL_PSL_SPAP_Addr;
+	spap |= ((afu->native->spa_size >> (12 - CXL_PSL_SPAP_Size_Shift)) - 1) & CXL_PSL_SPAP_Size;
 	spap |= CXL_PSL_SPAP_V;
-	pr_devel("cxl: SPA allocated at 0x%p. Max processes: %i, sw_command_status: 0x%p CXL_PSL_SPAP_An=0x%016llx\n", afu->spa, afu->spa_max_procs, afu->sw_command_status, spap);
+	pr_devel("cxl: SPA allocated at 0x%p. Max processes: %i, sw_command_status: 0x%p CXL_PSL_SPAP_An=0x%016llx\n",
+		afu->native->spa, afu->native->spa_max_procs,
+		afu->native->sw_command_status, spap);
 	cxl_p1n_write(afu, CXL_PSL_SPAP_An, spap);
 }
 
@@ -227,9 +230,10 @@ static inline void detach_spa(struct cxl
 
 void cxl_release_spa(struct cxl_afu *afu)
 {
-	if (afu->spa) {
-		free_pages((unsigned long) afu->spa, afu->spa_order);
-		afu->spa = NULL;
+	if (afu->native->spa) {
+		free_pages((unsigned long) afu->native->spa,
+			afu->native->spa_order);
+		afu->native->spa = NULL;
 	}
 }
 
@@ -247,7 +251,7 @@ int cxl_tlb_slb_invalidate(struct cxl *a
 			dev_warn(&adapter->dev, "WARNING: CXL adapter wide TLBIA timed out!\n");
 			return -EBUSY;
 		}
-		if (!cxl_adapter_link_ok(adapter))
+		if (!cxl_ops->link_ok(adapter, NULL))
 			return -EIO;
 		cpu_relax();
 	}
@@ -258,31 +262,41 @@ int cxl_tlb_slb_invalidate(struct cxl *a
 			dev_warn(&adapter->dev, "WARNING: CXL adapter wide SLBIA timed out!\n");
 			return -EBUSY;
 		}
-		if (!cxl_adapter_link_ok(adapter))
+		if (!cxl_ops->link_ok(adapter, NULL))
 			return -EIO;
 		cpu_relax();
 	}
 	return 0;
 }
 
-int cxl_afu_slbia(struct cxl_afu *afu)
+int cxl_data_cache_flush(struct cxl *adapter)
 {
+	u64 reg;
 	unsigned long timeout = jiffies + (HZ * CXL_TIMEOUT);
 
-	pr_devel("cxl_afu_slbia issuing SLBIA command\n");
-	cxl_p2n_write(afu, CXL_SLBIA_An, CXL_TLB_SLB_IQ_ALL);
-	while (cxl_p2n_read(afu, CXL_SLBIA_An) & CXL_TLB_SLB_P) {
+	pr_devel("Flushing data cache\n");
+
+	reg = cxl_p1_read(adapter, CXL_PSL_Control);
+	reg |= CXL_PSL_Control_Fr;
+	cxl_p1_write(adapter, CXL_PSL_Control, reg);
+
+	reg = cxl_p1_read(adapter, CXL_PSL_Control);
+	while ((reg & CXL_PSL_Control_Fs_MASK) != CXL_PSL_Control_Fs_Complete) {
 		if (time_after_eq(jiffies, timeout)) {
-			dev_warn(&afu->dev, "WARNING: CXL AFU SLBIA timed out!\n");
+			dev_warn(&adapter->dev, "WARNING: cache flush timed out!\n");
 			return -EBUSY;
 		}
-		/* If the adapter has gone down, we can assume that we
-		 * will PERST it and that will invalidate everything.
-		 */
-		if (!cxl_adapter_link_ok(afu->adapter))
+
+		if (!cxl_ops->link_ok(adapter, NULL)) {
+			dev_warn(&adapter->dev, "WARNING: link down when flushing cache\n");
 			return -EIO;
+		}
 		cpu_relax();
+		reg = cxl_p1_read(adapter, CXL_PSL_Control);
 	}
+
+	reg &= ~CXL_PSL_Control_Fr;
+	cxl_p1_write(adapter, CXL_PSL_Control, reg);
 	return 0;
 }
 
@@ -312,7 +326,7 @@ static void slb_invalid(struct cxl_conte
 	struct cxl *adapter = ctx->afu->adapter;
 	u64 slbia;
 
-	WARN_ON(!mutex_is_locked(&ctx->afu->spa_mutex));
+	WARN_ON(!mutex_is_locked(&ctx->afu->native->spa_mutex));
 
 	cxl_p1_write(adapter, CXL_PSL_LBISEL,
 			((u64)be32_to_cpu(ctx->elem->common.pid) << 32) |
@@ -320,7 +334,7 @@ static void slb_invalid(struct cxl_conte
 	cxl_p1_write(adapter, CXL_PSL_SLBIA, CXL_TLB_SLB_IQ_LPIDPID);
 
 	while (1) {
-		if (!cxl_adapter_link_ok(adapter))
+		if (!cxl_ops->link_ok(adapter, NULL))
 			break;
 		slbia = cxl_p1_read(adapter, CXL_PSL_SLBIA);
 		if (!(slbia & CXL_TLB_SLB_P))
@@ -342,7 +356,7 @@ static int do_process_element_cmd(struct
 
 	ctx->elem->software_state = cpu_to_be32(pe_state);
 	smp_wmb();
-	*(ctx->afu->sw_command_status) = cpu_to_be64(cmd | 0 | ctx->pe);
+	*(ctx->afu->native->sw_command_status) = cpu_to_be64(cmd | 0 | ctx->pe);
 	smp_mb();
 	cxl_p1n_write(ctx->afu, CXL_PSL_LLCMD_An, cmd | ctx->pe);
 	while (1) {
@@ -351,12 +365,12 @@ static int do_process_element_cmd(struct
 			rc = -EBUSY;
 			goto out;
 		}
-		if (!cxl_adapter_link_ok(ctx->afu->adapter)) {
+		if (!cxl_ops->link_ok(ctx->afu->adapter, ctx->afu)) {
 			dev_warn(&ctx->afu->dev, "WARNING: Device link down, aborting Process Element Command!\n");
 			rc = -EIO;
 			goto out;
 		}
-		state = be64_to_cpup(ctx->afu->sw_command_status);
+		state = be64_to_cpup(ctx->afu->native->sw_command_status);
 		if (state == ~0ULL) {
 			pr_err("cxl: Error adding process element to AFU\n");
 			rc = -1;
@@ -384,12 +398,12 @@ static int add_process_element(struct cx
 {
 	int rc = 0;
 
-	mutex_lock(&ctx->afu->spa_mutex);
+	mutex_lock(&ctx->afu->native->spa_mutex);
 	pr_devel("%s Adding pe: %i started\n", __func__, ctx->pe);
 	if (!(rc = do_process_element_cmd(ctx, CXL_SPA_SW_CMD_ADD, CXL_PE_SOFTWARE_STATE_V)))
 		ctx->pe_inserted = true;
 	pr_devel("%s Adding pe: %i finished\n", __func__, ctx->pe);
-	mutex_unlock(&ctx->afu->spa_mutex);
+	mutex_unlock(&ctx->afu->native->spa_mutex);
 	return rc;
 }
 
@@ -401,18 +415,18 @@ static int terminate_process_element(str
 	if (!(ctx->elem->software_state & cpu_to_be32(CXL_PE_SOFTWARE_STATE_V)))
 		return rc;
 
-	mutex_lock(&ctx->afu->spa_mutex);
+	mutex_lock(&ctx->afu->native->spa_mutex);
 	pr_devel("%s Terminate pe: %i started\n", __func__, ctx->pe);
 	/* We could be asked to terminate when the hw is down. That
 	 * should always succeed: it's not running if the hw has gone
 	 * away and is being reset.
 	 */
-	if (cxl_adapter_link_ok(ctx->afu->adapter))
+	if (cxl_ops->link_ok(ctx->afu->adapter, ctx->afu))
 		rc = do_process_element_cmd(ctx, CXL_SPA_SW_CMD_TERMINATE,
 					    CXL_PE_SOFTWARE_STATE_V | CXL_PE_SOFTWARE_STATE_T);
 	ctx->elem->software_state = 0;	/* Remove Valid bit */
 	pr_devel("%s Terminate pe: %i finished\n", __func__, ctx->pe);
-	mutex_unlock(&ctx->afu->spa_mutex);
+	mutex_unlock(&ctx->afu->native->spa_mutex);
 	return rc;
 }
 
@@ -420,20 +434,20 @@ static int remove_process_element(struct
 {
 	int rc = 0;
 
-	mutex_lock(&ctx->afu->spa_mutex);
+	mutex_lock(&ctx->afu->native->spa_mutex);
 	pr_devel("%s Remove pe: %i started\n", __func__, ctx->pe);
 
 	/* We could be asked to remove when the hw is down. Again, if
 	 * the hw is down, the PE is gone, so we succeed.
 	 */
-	if (cxl_adapter_link_ok(ctx->afu->adapter))
+	if (cxl_ops->link_ok(ctx->afu->adapter, ctx->afu))
 		rc = do_process_element_cmd(ctx, CXL_SPA_SW_CMD_REMOVE, 0);
 
 	if (!rc)
 		ctx->pe_inserted = false;
 	slb_invalid(ctx);
 	pr_devel("%s Remove pe: %i finished\n", __func__, ctx->pe);
-	mutex_unlock(&ctx->afu->spa_mutex);
+	mutex_unlock(&ctx->afu->native->spa_mutex);
 
 	return rc;
 }
@@ -446,7 +460,7 @@ void cxl_assign_psn_space(struct cxl_con
 		ctx->psn_size = ctx->afu->adapter->ps_size;
 	} else {
 		ctx->psn_phys = ctx->afu->psn_phys +
-			(ctx->afu->pp_offset + ctx->afu->pp_size * ctx->pe);
+			(ctx->afu->native->pp_offset + ctx->afu->pp_size * ctx->pe);
 		ctx->psn_size = ctx->afu->pp_size;
 	}
 }
@@ -458,7 +472,7 @@ static int activate_afu_directed(struct
 	dev_info(&afu->dev, "Activating AFU directed mode\n");
 
 	afu->num_procs = afu->max_procs_virtualised;
-	if (afu->spa == NULL) {
+	if (afu->native->spa == NULL) {
 		if (cxl_alloc_spa(afu))
 			return -ENOMEM;
 	}
@@ -552,7 +566,7 @@ static int attach_afu_directed(struct cx
 	ctx->elem->common.wed = cpu_to_be64(wed);
 
 	/* first guy needs to enable */
-	if ((result = cxl_afu_check_and_enable(ctx->afu)))
+	if ((result = cxl_ops->afu_check_and_enable(ctx->afu)))
 		return result;
 
 	return add_process_element(ctx);
@@ -568,7 +582,7 @@ static int deactivate_afu_directed(struc
 	cxl_sysfs_afu_m_remove(afu);
 	cxl_chardev_afu_remove(afu);
 
-	__cxl_afu_reset(afu);
+	cxl_ops->afu_reset(afu);
 	cxl_afu_disable(afu);
 	cxl_psl_purge(afu);
 
@@ -632,7 +646,7 @@ static int attach_dedicated(struct cxl_c
 	/* master only context for dedicated */
 	cxl_assign_psn_space(ctx);
 
-	if ((rc = __cxl_afu_reset(afu)))
+	if ((rc = cxl_ops->afu_reset(afu)))
 		return rc;
 
 	cxl_p2n_write(afu, CXL_PSL_WED_An, wed);
@@ -652,7 +666,7 @@ static int deactivate_dedicated_process(
 	return 0;
 }
 
-int _cxl_afu_deactivate_mode(struct cxl_afu *afu, int mode)
+static int native_afu_deactivate_mode(struct cxl_afu *afu, int mode)
 {
 	if (mode == CXL_MODE_DIRECTED)
 		return deactivate_afu_directed(afu);
@@ -661,19 +675,14 @@ int _cxl_afu_deactivate_mode(struct cxl_
 	return 0;
 }
 
-int cxl_afu_deactivate_mode(struct cxl_afu *afu)
-{
-	return _cxl_afu_deactivate_mode(afu, afu->current_mode);
-}
-
-int cxl_afu_activate_mode(struct cxl_afu *afu, int mode)
+static int native_afu_activate_mode(struct cxl_afu *afu, int mode)
 {
 	if (!mode)
 		return 0;
 	if (!(mode & afu->modes_supported))
 		return -EINVAL;
 
-	if (!cxl_adapter_link_ok(afu->adapter)) {
+	if (!cxl_ops->link_ok(afu->adapter, afu)) {
 		WARN(1, "Device link is down, refusing to activate!\n");
 		return -EIO;
 	}
@@ -686,9 +695,10 @@ int cxl_afu_activate_mode(struct cxl_afu
 	return -EINVAL;
 }
 
-int cxl_attach_process(struct cxl_context *ctx, bool kernel, u64 wed, u64 amr)
+static int native_attach_process(struct cxl_context *ctx, bool kernel,
+				u64 wed, u64 amr)
 {
-	if (!cxl_adapter_link_ok(ctx->afu->adapter)) {
+	if (!cxl_ops->link_ok(ctx->afu->adapter, ctx->afu)) {
 		WARN(1, "Device link is down, refusing to attach process!\n");
 		return -EIO;
 	}
@@ -705,7 +715,7 @@ int cxl_attach_process(struct cxl_contex
 
 static inline int detach_process_native_dedicated(struct cxl_context *ctx)
 {
-	__cxl_afu_reset(ctx->afu);
+	cxl_ops->afu_reset(ctx->afu);
 	cxl_afu_disable(ctx->afu);
 	cxl_psl_purge(ctx->afu);
 	return 0;
@@ -723,7 +733,7 @@ static inline int detach_process_native_
 	return 0;
 }
 
-int cxl_detach_process(struct cxl_context *ctx)
+static int native_detach_process(struct cxl_context *ctx)
 {
 	trace_cxl_detach(ctx);
 
@@ -733,14 +743,14 @@ int cxl_detach_process(struct cxl_contex
 	return detach_process_native_afu_directed(ctx);
 }
 
-int cxl_get_irq(struct cxl_afu *afu, struct cxl_irq_info *info)
+static int native_get_irq_info(struct cxl_afu *afu, struct cxl_irq_info *info)
 {
 	u64 pidtid;
 
 	/* If the adapter has gone away, we can't get any meaningful
 	 * information.
 	 */
-	if (!cxl_adapter_link_ok(afu->adapter))
+	if (!cxl_ops->link_ok(afu->adapter, afu))
 		return -EIO;
 
 	info->dsisr = cxl_p2n_read(afu, CXL_PSL_DSISR_An);
@@ -751,10 +761,243 @@ int cxl_get_irq(struct cxl_afu *afu, str
 	info->tid = pidtid & 0xffffffff;
 	info->afu_err = cxl_p2n_read(afu, CXL_AFU_ERR_An);
 	info->errstat = cxl_p2n_read(afu, CXL_PSL_ErrStat_An);
+	info->proc_handle = 0;
 
 	return 0;
 }
 
+static irqreturn_t native_handle_psl_slice_error(struct cxl_context *ctx,
+						u64 dsisr, u64 errstat)
+{
+	u64 fir1, fir2, fir_slice, serr, afu_debug;
+
+	fir1 = cxl_p1_read(ctx->afu->adapter, CXL_PSL_FIR1);
+	fir2 = cxl_p1_read(ctx->afu->adapter, CXL_PSL_FIR2);
+	fir_slice = cxl_p1n_read(ctx->afu, CXL_PSL_FIR_SLICE_An);
+	serr = cxl_p1n_read(ctx->afu, CXL_PSL_SERR_An);
+	afu_debug = cxl_p1n_read(ctx->afu, CXL_AFU_DEBUG_An);
+
+	dev_crit(&ctx->afu->dev, "PSL ERROR STATUS: 0x%016llx\n", errstat);
+	dev_crit(&ctx->afu->dev, "PSL_FIR1: 0x%016llx\n", fir1);
+	dev_crit(&ctx->afu->dev, "PSL_FIR2: 0x%016llx\n", fir2);
+	dev_crit(&ctx->afu->dev, "PSL_SERR_An: 0x%016llx\n", serr);
+	dev_crit(&ctx->afu->dev, "PSL_FIR_SLICE_An: 0x%016llx\n", fir_slice);
+	dev_crit(&ctx->afu->dev, "CXL_PSL_AFU_DEBUG_An: 0x%016llx\n", afu_debug);
+
+	dev_crit(&ctx->afu->dev, "STOPPING CXL TRACE\n");
+	cxl_stop_trace(ctx->afu->adapter);
+
+	return cxl_ops->ack_irq(ctx, 0, errstat);
+}
+
+static irqreturn_t fail_psl_irq(struct cxl_afu *afu, struct cxl_irq_info *irq_info)
+{
+	if (irq_info->dsisr & CXL_PSL_DSISR_TRANS)
+		cxl_p2n_write(afu, CXL_PSL_TFC_An, CXL_PSL_TFC_An_AE);
+	else
+		cxl_p2n_write(afu, CXL_PSL_TFC_An, CXL_PSL_TFC_An_A);
+
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t native_irq_multiplexed(int irq, void *data)
+{
+	struct cxl_afu *afu = data;
+	struct cxl_context *ctx;
+	struct cxl_irq_info irq_info;
+	int ph = cxl_p2n_read(afu, CXL_PSL_PEHandle_An) & 0xffff;
+	int ret;
+
+	if ((ret = native_get_irq_info(afu, &irq_info))) {
+		WARN(1, "Unable to get CXL IRQ Info: %i\n", ret);
+		return fail_psl_irq(afu, &irq_info);
+	}
+
+	rcu_read_lock();
+	ctx = idr_find(&afu->contexts_idr, ph);
+	if (ctx) {
+		ret = cxl_irq(irq, ctx, &irq_info);
+		rcu_read_unlock();
+		return ret;
+	}
+	rcu_read_unlock();
+
+	WARN(1, "Unable to demultiplex CXL PSL IRQ for PE %i DSISR %016llx DAR"
+		" %016llx\n(Possible AFU HW issue - was a term/remove acked"
+		" with outstanding transactions?)\n", ph, irq_info.dsisr,
+		irq_info.dar);
+	return fail_psl_irq(afu, &irq_info);
+}
+
+void native_irq_wait(struct cxl_context *ctx)
+{
+	u64 dsisr;
+	int timeout = 1000;
+	int ph;
+
+	/*
+	 * Wait until no further interrupts are presented by the PSL
+	 * for this context.
+	 */
+	while (timeout--) {
+		ph = cxl_p2n_read(ctx->afu, CXL_PSL_PEHandle_An) & 0xffff;
+		if (ph != ctx->pe)
+			return;
+		dsisr = cxl_p2n_read(ctx->afu, CXL_PSL_DSISR_An);
+		if ((dsisr & CXL_PSL_DSISR_PENDING) == 0)
+			return;
+		/*
+		 * We are waiting for the workqueue to process our
+		 * irq, so need to let that run here.
+		 */
+		msleep(1);
+	}
+
+	dev_warn(&ctx->afu->dev, "WARNING: waiting on DSI for PE %i"
+		 " DSISR %016llx!\n", ph, dsisr);
+	return;
+}
+
+static irqreturn_t native_slice_irq_err(int irq, void *data)
+{
+	struct cxl_afu *afu = data;
+	u64 fir_slice, errstat, serr, afu_debug;
+
+	WARN(irq, "CXL SLICE ERROR interrupt %i\n", irq);
+
+	serr = cxl_p1n_read(afu, CXL_PSL_SERR_An);
+	fir_slice = cxl_p1n_read(afu, CXL_PSL_FIR_SLICE_An);
+	errstat = cxl_p2n_read(afu, CXL_PSL_ErrStat_An);
+	afu_debug = cxl_p1n_read(afu, CXL_AFU_DEBUG_An);
+	dev_crit(&afu->dev, "PSL_SERR_An: 0x%016llx\n", serr);
+	dev_crit(&afu->dev, "PSL_FIR_SLICE_An: 0x%016llx\n", fir_slice);
+	dev_crit(&afu->dev, "CXL_PSL_ErrStat_An: 0x%016llx\n", errstat);
+	dev_crit(&afu->dev, "CXL_PSL_AFU_DEBUG_An: 0x%016llx\n", afu_debug);
+
+	cxl_p1n_write(afu, CXL_PSL_SERR_An, serr);
+
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t native_irq_err(int irq, void *data)
+{
+	struct cxl *adapter = data;
+	u64 fir1, fir2, err_ivte;
+
+	WARN(1, "CXL ERROR interrupt %i\n", irq);
+
+	err_ivte = cxl_p1_read(adapter, CXL_PSL_ErrIVTE);
+	dev_crit(&adapter->dev, "PSL_ErrIVTE: 0x%016llx\n", err_ivte);
+
+	dev_crit(&adapter->dev, "STOPPING CXL TRACE\n");
+	cxl_stop_trace(adapter);
+
+	fir1 = cxl_p1_read(adapter, CXL_PSL_FIR1);
+	fir2 = cxl_p1_read(adapter, CXL_PSL_FIR2);
+
+	dev_crit(&adapter->dev, "PSL_FIR1: 0x%016llx\nPSL_FIR2: 0x%016llx\n", fir1, fir2);
+
+	return IRQ_HANDLED;
+}
+
+int cxl_native_register_psl_err_irq(struct cxl *adapter)
+{
+	int rc;
+
+	adapter->irq_name = kasprintf(GFP_KERNEL, "cxl-%s-err",
+				      dev_name(&adapter->dev));
+	if (!adapter->irq_name)
+		return -ENOMEM;
+
+	if ((rc = cxl_register_one_irq(adapter, native_irq_err, adapter,
+				       &adapter->native->err_hwirq,
+				       &adapter->native->err_virq,
+				       adapter->irq_name))) {
+		kfree(adapter->irq_name);
+		adapter->irq_name = NULL;
+		return rc;
+	}
+
+	cxl_p1_write(adapter, CXL_PSL_ErrIVTE, adapter->native->err_hwirq & 0xffff);
+
+	return 0;
+}
+
+void cxl_native_release_psl_err_irq(struct cxl *adapter)
+{
+	if (adapter->native->err_virq != irq_find_mapping(NULL, adapter->native->err_hwirq))
+		return;
+
+	cxl_p1_write(adapter, CXL_PSL_ErrIVTE, 0x0000000000000000);
+	cxl_unmap_irq(adapter->native->err_virq, adapter);
+	cxl_ops->release_one_irq(adapter, adapter->native->err_hwirq);
+	kfree(adapter->irq_name);
+}
+
+int cxl_native_register_serr_irq(struct cxl_afu *afu)
+{
+	u64 serr;
+	int rc;
+
+	afu->err_irq_name = kasprintf(GFP_KERNEL, "cxl-%s-err",
+				      dev_name(&afu->dev));
+	if (!afu->err_irq_name)
+		return -ENOMEM;
+
+	if ((rc = cxl_register_one_irq(afu->adapter, native_slice_irq_err, afu,
+				       &afu->serr_hwirq,
+				       &afu->serr_virq, afu->err_irq_name))) {
+		kfree(afu->err_irq_name);
+		afu->err_irq_name = NULL;
+		return rc;
+	}
+
+	serr = cxl_p1n_read(afu, CXL_PSL_SERR_An);
+	serr = (serr & 0x00ffffffffff0000ULL) | (afu->serr_hwirq & 0xffff);
+	cxl_p1n_write(afu, CXL_PSL_SERR_An, serr);
+
+	return 0;
+}
+
+void cxl_native_release_serr_irq(struct cxl_afu *afu)
+{
+	if (afu->serr_virq != irq_find_mapping(NULL, afu->serr_hwirq))
+		return;
+
+	cxl_p1n_write(afu, CXL_PSL_SERR_An, 0x0000000000000000);
+	cxl_unmap_irq(afu->serr_virq, afu);
+	cxl_ops->release_one_irq(afu->adapter, afu->serr_hwirq);
+	kfree(afu->err_irq_name);
+}
+
+int cxl_native_register_psl_irq(struct cxl_afu *afu)
+{
+	int rc;
+
+	afu->psl_irq_name = kasprintf(GFP_KERNEL, "cxl-%s",
+				      dev_name(&afu->dev));
+	if (!afu->psl_irq_name)
+		return -ENOMEM;
+
+	if ((rc = cxl_register_one_irq(afu->adapter, native_irq_multiplexed,
+				    afu, &afu->native->psl_hwirq, &afu->native->psl_virq,
+				    afu->psl_irq_name))) {
+		kfree(afu->psl_irq_name);
+		afu->psl_irq_name = NULL;
+	}
+	return rc;
+}
+
+void cxl_native_release_psl_irq(struct cxl_afu *afu)
+{
+	if (afu->native->psl_virq != irq_find_mapping(NULL, afu->native->psl_hwirq))
+		return;
+
+	cxl_unmap_irq(afu->native->psl_virq, afu);
+	cxl_ops->release_one_irq(afu->adapter, afu->native->psl_hwirq);
+	kfree(afu->psl_irq_name);
+}
+
 static void recover_psl_err(struct cxl_afu *afu, u64 errstat)
 {
 	u64 dsisr;
@@ -769,7 +1012,7 @@ static void recover_psl_err(struct cxl_a
 	cxl_p2n_write(afu, CXL_PSL_ErrStat_An, errstat);
 }
 
-int cxl_ack_irq(struct cxl_context *ctx, u64 tfc, u64 psl_reset_mask)
+static int native_ack_irq(struct cxl_context *ctx, u64 tfc, u64 psl_reset_mask)
 {
 	trace_cxl_psl_irq_ack(ctx, tfc);
 	if (tfc)
@@ -784,3 +1027,133 @@ int cxl_check_error(struct cxl_afu *afu)
 {
 	return (cxl_p1n_read(afu, CXL_PSL_SCNTL_An) == ~0ULL);
 }
+
+static bool native_support_attributes(const char *attr_name,
+				      enum cxl_attrs type)
+{
+	return true;
+}
+
+static int native_afu_cr_read64(struct cxl_afu *afu, int cr, u64 off, u64 *out)
+{
+	if (unlikely(!cxl_ops->link_ok(afu->adapter, afu)))
+		return -EIO;
+	if (unlikely(off >= afu->crs_len))
+		return -ERANGE;
+	*out = in_le64(afu->native->afu_desc_mmio + afu->crs_offset +
+		(cr * afu->crs_len) + off);
+	return 0;
+}
+
+static int native_afu_cr_read32(struct cxl_afu *afu, int cr, u64 off, u32 *out)
+{
+	if (unlikely(!cxl_ops->link_ok(afu->adapter, afu)))
+		return -EIO;
+	if (unlikely(off >= afu->crs_len))
+		return -ERANGE;
+	*out = in_le32(afu->native->afu_desc_mmio + afu->crs_offset +
+		(cr * afu->crs_len) + off);
+	return 0;
+}
+
+static int native_afu_cr_read16(struct cxl_afu *afu, int cr, u64 off, u16 *out)
+{
+	u64 aligned_off = off & ~0x3L;
+	u32 val;
+	int rc;
+
+	rc = native_afu_cr_read32(afu, cr, aligned_off, &val);
+	if (!rc)
+		*out = (val >> ((off & 0x3) * 8)) & 0xffff;
+	return rc;
+}
+
+static int native_afu_cr_read8(struct cxl_afu *afu, int cr, u64 off, u8 *out)
+{
+	u64 aligned_off = off & ~0x3L;
+	u32 val;
+	int rc;
+
+	rc = native_afu_cr_read32(afu, cr, aligned_off, &val);
+	if (!rc)
+		*out = (val >> ((off & 0x3) * 8)) & 0xff;
+	return rc;
+}
+
+static int native_afu_cr_write32(struct cxl_afu *afu, int cr, u64 off, u32 in)
+{
+	if (unlikely(!cxl_ops->link_ok(afu->adapter, afu)))
+		return -EIO;
+	if (unlikely(off >= afu->crs_len))
+		return -ERANGE;
+	out_le32(afu->native->afu_desc_mmio + afu->crs_offset +
+		(cr * afu->crs_len) + off, in);
+	return 0;
+}
+
+static int native_afu_cr_write16(struct cxl_afu *afu, int cr, u64 off, u16 in)
+{
+	u64 aligned_off = off & ~0x3L;
+	u32 val32, mask, shift;
+	int rc;
+
+	rc = native_afu_cr_read32(afu, cr, aligned_off, &val32);
+	if (rc)
+		return rc;
+	shift = (off & 0x3) * 8;
+	WARN_ON(shift == 24);
+	mask = 0xffff << shift;
+	val32 = (val32 & ~mask) | (in << shift);
+
+	rc = native_afu_cr_write32(afu, cr, aligned_off, val32);
+	return rc;
+}
+
+static int native_afu_cr_write8(struct cxl_afu *afu, int cr, u64 off, u8 in)
+{
+	u64 aligned_off = off & ~0x3L;
+	u32 val32, mask, shift;
+	int rc;
+
+	rc = native_afu_cr_read32(afu, cr, aligned_off, &val32);
+	if (rc)
+		return rc;
+	shift = (off & 0x3) * 8;
+	mask = 0xff << shift;
+	val32 = (val32 & ~mask) | (in << shift);
+
+	rc = native_afu_cr_write32(afu, cr, aligned_off, val32);
+	return rc;
+}
+
+const struct cxl_backend_ops cxl_native_ops = {
+	.module = THIS_MODULE,
+	.adapter_reset = cxl_pci_reset,
+	.alloc_one_irq = cxl_pci_alloc_one_irq,
+	.release_one_irq = cxl_pci_release_one_irq,
+	.alloc_irq_ranges = cxl_pci_alloc_irq_ranges,
+	.release_irq_ranges = cxl_pci_release_irq_ranges,
+	.setup_irq = cxl_pci_setup_irq,
+	.handle_psl_slice_error = native_handle_psl_slice_error,
+	.psl_interrupt = NULL,
+	.ack_irq = native_ack_irq,
+	.irq_wait = native_irq_wait,
+	.attach_process = native_attach_process,
+	.detach_process = native_detach_process,
+	.support_attributes = native_support_attributes,
+	.link_ok = cxl_adapter_link_ok,
+	.release_afu = cxl_pci_release_afu,
+	.afu_read_err_buffer = cxl_pci_afu_read_err_buffer,
+	.afu_check_and_enable = native_afu_check_and_enable,
+	.afu_activate_mode = native_afu_activate_mode,
+	.afu_deactivate_mode = native_afu_deactivate_mode,
+	.afu_reset = native_afu_reset,
+	.afu_cr_read8 = native_afu_cr_read8,
+	.afu_cr_read16 = native_afu_cr_read16,
+	.afu_cr_read32 = native_afu_cr_read32,
+	.afu_cr_read64 = native_afu_cr_read64,
+	.afu_cr_write8 = native_afu_cr_write8,
+	.afu_cr_write16 = native_afu_cr_write16,
+	.afu_cr_write32 = native_afu_cr_write32,
+	.read_adapter_vpd = cxl_pci_read_adapter_vpd,
+};
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/misc/cxl/of.c
@@ -0,0 +1,513 @@
+/*
+ * Copyright 2015 IBM Corp.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/of_address.h>
+#include <linux/of_platform.h>
+
+#include "cxl.h"
+
+
+static const __be32 *read_prop_string(const struct device_node *np,
+				const char *prop_name)
+{
+	const __be32 *prop;
+
+	prop = of_get_property(np, prop_name, NULL);
+	if (cxl_verbose && prop)
+		pr_info("%s: %s\n", prop_name, (char *) prop);
+	return prop;
+}
+
+static const __be32 *read_prop_dword(const struct device_node *np,
+				const char *prop_name, u32 *val)
+{
+	const __be32 *prop;
+
+	prop = of_get_property(np, prop_name, NULL);
+	if (prop)
+		*val = be32_to_cpu(prop[0]);
+	if (cxl_verbose && prop)
+		pr_info("%s: %#x (%u)\n", prop_name, *val, *val);
+	return prop;
+}
+
+static const __be64 *read_prop64_dword(const struct device_node *np,
+				const char *prop_name, u64 *val)
+{
+	const __be64 *prop;
+
+	prop = of_get_property(np, prop_name, NULL);
+	if (prop)
+		*val = be64_to_cpu(prop[0]);
+	if (cxl_verbose && prop)
+		pr_info("%s: %#llx (%llu)\n", prop_name, *val, *val);
+	return prop;
+}
+
+
+static int read_handle(struct device_node *np, u64 *handle)
+{
+	const __be32 *prop;
+	u64 size;
+
+	/* Get address and size of the node */
+	prop = of_get_address(np, 0, &size, NULL);
+	if (size)
+		return -EINVAL;
+
+	/* Helper to read a big number; size is in cells (not bytes) */
+	*handle = of_read_number(prop, of_n_addr_cells(np));
+	return 0;
+}
+
+static int read_phys_addr(struct device_node *np, char *prop_name,
+			struct cxl_afu *afu)
+{
+	int i, len, entry_size, naddr, nsize, type;
+	u64 addr, size;
+	const __be32 *prop;
+
+	naddr = of_n_addr_cells(np);
+	nsize = of_n_size_cells(np);
+
+	prop = of_get_property(np, prop_name, &len);
+	if (prop) {
+		entry_size = naddr + nsize;
+		for (i = 0; i < (len / 4); i += entry_size, prop += entry_size) {
+			type = be32_to_cpu(prop[0]);
+			addr = of_read_number(prop, naddr);
+			size = of_read_number(&prop[naddr], nsize);
+			switch (type) {
+			case 0: /* unit address */
+				afu->guest->handle = addr;
+				break;
+			case 1: /* p2 area */
+				afu->guest->p2n_phys += addr;
+				afu->guest->p2n_size = size;
+				break;
+			case 2: /* problem state area */
+				afu->psn_phys += addr;
+				afu->adapter->ps_size = size;
+				break;
+			default:
+				pr_err("Invalid address type %d found in %s property of AFU\n",
+					type, prop_name);
+				return -EINVAL;
+			}
+			if (cxl_verbose)
+				pr_info("%s: %#x %#llx (size %#llx)\n",
+					prop_name, type, addr, size);
+		}
+	}
+	return 0;
+}
+
+static int read_vpd(struct cxl *adapter, struct cxl_afu *afu)
+{
+	char vpd[256];
+	int rc;
+	size_t len = sizeof(vpd);
+
+	memset(vpd, 0, len);
+
+	if (adapter)
+		rc = cxl_guest_read_adapter_vpd(adapter, vpd, len);
+	else
+		rc = cxl_guest_read_afu_vpd(afu, vpd, len);
+
+	if (rc > 0) {
+		cxl_dump_debug_buffer(vpd, rc);
+		rc = 0;
+	}
+	return rc;
+}
+
+int cxl_of_read_afu_handle(struct cxl_afu *afu, struct device_node *afu_np)
+{
+	if (read_handle(afu_np, &afu->guest->handle))
+		return -EINVAL;
+	pr_devel("AFU handle: 0x%.16llx\n", afu->guest->handle);
+
+	return 0;
+}
+
+int cxl_of_read_afu_properties(struct cxl_afu *afu, struct device_node *np)
+{
+	int i, len, rc;
+	char *p;
+	const __be32 *prop;
+	u16 device_id, vendor_id;
+	u32 val = 0, class_code;
+
+	/* Properties are read in the same order as listed in PAPR */
+
+	if (cxl_verbose) {
+		pr_info("Dump of the 'ibm,coherent-platform-function' node properties:\n");
+
+		prop = of_get_property(np, "compatible", &len);
+		i = 0;
+		while (i < len) {
+			p = (char *) prop + i;
+			pr_info("compatible: %s\n", p);
+			i += strlen(p) + 1;
+		}
+		read_prop_string(np, "name");
+	}
+
+	rc = read_phys_addr(np, "reg", afu);
+	if (rc)
+		return rc;
+
+	rc = read_phys_addr(np, "assigned-addresses", afu);
+	if (rc)
+		return rc;
+
+	if (afu->psn_phys == 0)
+		afu->psa = false;
+	else
+		afu->psa = true;
+
+	if (cxl_verbose) {
+		read_prop_string(np, "ibm,loc-code");
+		read_prop_string(np, "device_type");
+	}
+
+	read_prop_dword(np, "ibm,#processes", &afu->max_procs_virtualised);
+
+	if (cxl_verbose) {
+		read_prop_dword(np, "ibm,scratchpad-size", &val);
+		read_prop_dword(np, "ibm,programmable", &val);
+		read_prop_string(np, "ibm,phandle");
+		read_vpd(NULL, afu);
+	}
+
+	read_prop_dword(np, "ibm,max-ints-per-process", &afu->guest->max_ints);
+	afu->irqs_max = afu->guest->max_ints;
+
+	prop = read_prop_dword(np, "ibm,min-ints-per-process", &afu->pp_irqs);
+	if (prop) {
+		/* One extra interrupt for the PSL interrupt is already
+		 * included. Remove it now to keep only AFU interrupts and
+		 * match the native case.
+		 */
+		afu->pp_irqs--;
+	}
+
+	if (cxl_verbose) {
+		read_prop_dword(np, "ibm,max-ints", &val);
+		read_prop_dword(np, "ibm,vpd-size", &val);
+	}
+
+	read_prop64_dword(np, "ibm,error-buffer-size", &afu->eb_len);
+	afu->eb_offset = 0;
+
+	if (cxl_verbose)
+		read_prop_dword(np, "ibm,config-record-type", &val);
+
+	read_prop64_dword(np, "ibm,config-record-size", &afu->crs_len);
+	afu->crs_offset = 0;
+
+	read_prop_dword(np, "ibm,#config-records", &afu->crs_num);
+
+	if (cxl_verbose) {
+		for (i = 0; i < afu->crs_num; i++) {
+			rc = cxl_ops->afu_cr_read16(afu, i, PCI_DEVICE_ID,
+						&device_id);
+			if (!rc)
+				pr_info("record %d - device-id: %#x\n",
+					i, device_id);
+			rc = cxl_ops->afu_cr_read16(afu, i, PCI_VENDOR_ID,
+						&vendor_id);
+			if (!rc)
+				pr_info("record %d - vendor-id: %#x\n",
+					i, vendor_id);
+			rc = cxl_ops->afu_cr_read32(afu, i, PCI_CLASS_REVISION,
+						&class_code);
+			if (!rc) {
+				class_code >>= 8;
+				pr_info("record %d - class-code: %#x\n",
+					i, class_code);
+			}
+		}
+
+		read_prop_dword(np, "ibm,function-number", &val);
+		read_prop_dword(np, "ibm,privileged-function", &val);
+		read_prop_dword(np, "vendor-id", &val);
+		read_prop_dword(np, "device-id", &val);
+		read_prop_dword(np, "revision-id", &val);
+		read_prop_dword(np, "class-code", &val);
+		read_prop_dword(np, "subsystem-vendor-id", &val);
+		read_prop_dword(np, "subsystem-id", &val);
+	}
+	/*
+	 * if "ibm,process-mmio" doesn't exist then per-process mmio is
+	 * not supported
+	 */
+	val = 0;
+	prop = read_prop_dword(np, "ibm,process-mmio", &val);
+	if (prop && val == 1)
+		afu->pp_psa = true;
+	else
+		afu->pp_psa = false;
+
+	if (cxl_verbose) {
+		read_prop_dword(np, "ibm,supports-aur", &val);
+		read_prop_dword(np, "ibm,supports-csrp", &val);
+		read_prop_dword(np, "ibm,supports-prr", &val);
+	}
+
+	prop = read_prop_dword(np, "ibm,function-error-interrupt", &val);
+	if (prop)
+		afu->serr_hwirq = val;
+
+	pr_devel("AFU handle: %#llx\n", afu->guest->handle);
+	pr_devel("p2n_phys: %#llx (size %#llx)\n",
+		afu->guest->p2n_phys, afu->guest->p2n_size);
+	pr_devel("psn_phys: %#llx (size %#llx)\n",
+		afu->psn_phys, afu->adapter->ps_size);
+	pr_devel("Max number of processes virtualised=%i\n",
+		afu->max_procs_virtualised);
+	pr_devel("Per-process irqs min=%i, max=%i\n", afu->pp_irqs,
+		 afu->irqs_max);
+	pr_devel("Slice error interrupt=%#lx\n", afu->serr_hwirq);
+
+	return 0;
+}
+
+static int read_adapter_irq_config(struct cxl *adapter, struct device_node *np)
+{
+	const __be32 *ranges;
+	int len, nranges, i;
+	struct irq_avail *cur;
+
+	ranges = of_get_property(np, "interrupt-ranges", &len);
+	if (ranges == NULL || len < (2 * sizeof(int)))
+		return -EINVAL;
+
+	/*
+	 * encoded array of two cells per entry, each cell encoded as
+	 * with encode-int
+	 */
+	nranges = len / (2 * sizeof(int));
+	if (nranges == 0 || (nranges * 2 * sizeof(int)) != len)
+		return -EINVAL;
+
+	adapter->guest->irq_avail = kzalloc(nranges * sizeof(struct irq_avail),
+					    GFP_KERNEL);
+	if (adapter->guest->irq_avail == NULL)
+		return -ENOMEM;
+
+	adapter->guest->irq_base_offset = be32_to_cpu(ranges[0]);
+	for (i = 0; i < nranges; i++) {
+		cur = &adapter->guest->irq_avail[i];
+		cur->offset = be32_to_cpu(ranges[i * 2]);
+		cur->range  = be32_to_cpu(ranges[i * 2 + 1]);
+		cur->bitmap = kcalloc(BITS_TO_LONGS(cur->range),
+				sizeof(*cur->bitmap), GFP_KERNEL);
+		if (cur->bitmap == NULL)
+			goto err;
+		if (cur->offset < adapter->guest->irq_base_offset)
+			adapter->guest->irq_base_offset = cur->offset;
+		if (cxl_verbose)
+			pr_info("available IRQ range: %#lx-%#lx (%lu)\n",
+				cur->offset, cur->offset + cur->range - 1,
+				cur->range);
+	}
+	adapter->guest->irq_nranges = nranges;
+	spin_lock_init(&adapter->guest->irq_alloc_lock);
+
+	return 0;
+err:
+	for (i--; i >= 0; i--) {
+		cur = &adapter->guest->irq_avail[i];
+		kfree(cur->bitmap);
+	}
+	kfree(adapter->guest->irq_avail);
+	adapter->guest->irq_avail = NULL;
+	return -ENOMEM;
+}
+
+int cxl_of_read_adapter_handle(struct cxl *adapter, struct device_node *np)
+{
+	if (read_handle(np, &adapter->guest->handle))
+		return -EINVAL;
+	pr_devel("Adapter handle: 0x%.16llx\n", adapter->guest->handle);
+
+	return 0;
+}
+
+int cxl_of_read_adapter_properties(struct cxl *adapter, struct device_node *np)
+{
+	int rc, len, naddr, i;
+	char *p;
+	const __be32 *prop;
+	u32 val = 0;
+
+	/* Properties are read in the same order as listed in PAPR */
+
+	naddr = of_n_addr_cells(np);
+
+	if (cxl_verbose) {
+		pr_info("Dump of the 'ibm,coherent-platform-facility' node properties:\n");
+
+		read_prop_dword(np, "#address-cells", &val);
+		read_prop_dword(np, "#size-cells", &val);
+
+		prop = of_get_property(np, "compatible", &len);
+		i = 0;
+		while (i < len) {
+			p = (char *) prop + i;
+			pr_info("compatible: %s\n", p);
+			i += strlen(p) + 1;
+		}
+		read_prop_string(np, "name");
+		read_prop_string(np, "model");
+
+		prop = of_get_property(np, "reg", NULL);
+		if (prop) {
+			pr_info("reg: addr:%#llx size:%#x\n",
+				of_read_number(prop, naddr),
+				be32_to_cpu(prop[naddr]));
+		}
+
+		read_prop_string(np, "ibm,loc-code");
+	}
+
+	if ((rc = read_adapter_irq_config(adapter, np)))
+		return rc;
+
+	if (cxl_verbose) {
+		read_prop_string(np, "device_type");
+		read_prop_string(np, "ibm,phandle");
+	}
+
+	prop = read_prop_dword(np, "ibm,caia-version", &val);
+	if (prop) {
+		adapter->caia_major = (val & 0xFF00) >> 8;
+		adapter->caia_minor = val & 0xFF;
+	}
+
+	prop = read_prop_dword(np, "ibm,psl-revision", &val);
+	if (prop)
+		adapter->psl_rev = val;
+
+	prop = read_prop_string(np, "status");
+	if (prop) {
+		adapter->guest->status = kasprintf(GFP_KERNEL, "%s", (char *) prop);
+		if (adapter->guest->status == NULL)
+			return -ENOMEM;
+	}
+
+	prop = read_prop_dword(np, "vendor-id", &val);
+	if (prop)
+		adapter->guest->vendor = val;
+
+	prop = read_prop_dword(np, "device-id", &val);
+	if (prop)
+		adapter->guest->device = val;
+
+	if (cxl_verbose) {
+		read_prop_dword(np, "ibm,privileged-facility", &val);
+		read_prop_dword(np, "revision-id", &val);
+		read_prop_dword(np, "class-code", &val);
+	}
+
+	prop = read_prop_dword(np, "subsystem-vendor-id", &val);
+	if (prop)
+		adapter->guest->subsystem_vendor = val;
+
+	prop = read_prop_dword(np, "subsystem-id", &val);
+	if (prop)
+		adapter->guest->subsystem = val;
+
+	if (cxl_verbose)
+		read_vpd(adapter, NULL);
+
+	return 0;
+}
+
+static int cxl_of_remove(struct platform_device *pdev)
+{
+	struct cxl *adapter;
+	int afu;
+
+	adapter = dev_get_drvdata(&pdev->dev);
+	for (afu = 0; afu < adapter->slices; afu++)
+		cxl_guest_remove_afu(adapter->afu[afu]);
+
+	cxl_guest_remove_adapter(adapter);
+	return 0;
+}
+
+static void cxl_of_shutdown(struct platform_device *pdev)
+{
+	cxl_of_remove(pdev);
+}
+
+int cxl_of_probe(struct platform_device *pdev)
+{
+	struct device_node *np = NULL;
+	struct device_node *afu_np = NULL;
+	struct cxl *adapter = NULL;
+	int ret;
+	int slice, slice_ok;
+
+	pr_devel("in %s\n", __func__);
+
+	np = pdev->dev.of_node;
+	if (np == NULL)
+		return -ENODEV;
+
+	/* init adapter */
+	adapter = cxl_guest_init_adapter(np, pdev);
+	if (IS_ERR(adapter)) {
+		dev_err(&pdev->dev, "guest_init_adapter failed: %li\n", PTR_ERR(adapter));
+		return PTR_ERR(adapter);
+	}
+
+	/* init afu */
+	slice_ok = 0;
+	for (afu_np = NULL, slice = 0; (afu_np = of_get_next_child(np, afu_np)); slice++) {
+		if ((ret = cxl_guest_init_afu(adapter, slice, afu_np)))
+			dev_err(&pdev->dev, "AFU %i failed to initialise: %i\n",
+				slice, ret);
+		else
+			slice_ok++;
+	}
+
+	if (slice_ok == 0) {
+		dev_info(&pdev->dev, "No active AFU");
+		adapter->slices = 0;
+	}
+
+	if (afu_np)
+		of_node_put(afu_np);
+	return 0;
+}
+
+static const struct of_device_id cxl_of_match[] = {
+	{ .compatible = "ibm,coherent-platform-facility",},
+	{},
+};
+MODULE_DEVICE_TABLE(of, cxl_of_match);
+
+struct platform_driver cxl_of_driver = {
+	.driver = {
+		.name = "cxl_of",
+		.of_match_table = cxl_of_match,
+		.owner = THIS_MODULE
+	},
+	.probe = cxl_of_probe,
+	.remove = cxl_of_remove,
+	.shutdown = cxl_of_shutdown,
+};
--- zfcpdump-kernel-4.4.orig/drivers/misc/cxl/pci.c
+++ zfcpdump-kernel-4.4/drivers/misc/cxl/pci.c
@@ -22,6 +22,7 @@
 #include <asm/pci-bridge.h> /* for struct pci_controller */
 #include <asm/pnv-pci.h>
 #include <asm/io.h>
+#include <asm/reg.h>
 
 #include "cxl.h"
 #include <misc/cxl.h>
@@ -90,8 +91,8 @@
 
 /* This works a little different than the p1/p2 register accesses to make it
  * easier to pull out individual fields */
-#define AFUD_READ(afu, off)		in_be64(afu->afu_desc_mmio + off)
-#define AFUD_READ_LE(afu, off)		in_le64(afu->afu_desc_mmio + off)
+#define AFUD_READ(afu, off)		in_be64(afu->native->afu_desc_mmio + off)
+#define AFUD_READ_LE(afu, off)		in_le64(afu->native->afu_desc_mmio + off)
 #define EXTRACT_PPC_BIT(val, bit)	(!!(val & PPC_BIT(bit)))
 #define EXTRACT_PPC_BITS(val, bs, be)	((val & PPC_BITMASK(bs, be)) >> PPC_BITLSHIFT(be))
 
@@ -116,28 +117,11 @@
 #define   AFUD_EB_LEN(val)		EXTRACT_PPC_BITS(val, 8, 63)
 #define AFUD_READ_EB_OFF(afu)		AFUD_READ(afu, 0x48)
 
-u16 cxl_afu_cr_read16(struct cxl_afu *afu, int cr, u64 off)
-{
-	u64 aligned_off = off & ~0x3L;
-	u32 val;
-
-	val = cxl_afu_cr_read32(afu, cr, aligned_off);
-	return (val >> ((off & 0x2) * 8)) & 0xffff;
-}
-
-u8 cxl_afu_cr_read8(struct cxl_afu *afu, int cr, u64 off)
-{
-	u64 aligned_off = off & ~0x3L;
-	u32 val;
-
-	val = cxl_afu_cr_read32(afu, cr, aligned_off);
-	return (val >> ((off & 0x3) * 8)) & 0xff;
-}
-
 static const struct pci_device_id cxl_pci_tbl[] = {
 	{ PCI_DEVICE(PCI_VENDOR_ID_IBM, 0x0477), },
 	{ PCI_DEVICE(PCI_VENDOR_ID_IBM, 0x044b), },
 	{ PCI_DEVICE(PCI_VENDOR_ID_IBM, 0x04cf), },
+	{ PCI_DEVICE(PCI_VENDOR_ID_IBM, 0x0601), },
 	{ PCI_DEVICE_CLASS(0x120000, ~0), },
 
 	{ }
@@ -339,12 +323,43 @@ static void dump_afu_descriptor(struct c
 #undef show_reg
 }
 
+#define CAPP_UNIT0_ID 0xBA
+#define CAPP_UNIT1_ID 0XBE
+
+static u64 get_capp_unit_id(struct device_node *np)
+{
+	u32 phb_index;
+
+	/*
+	 * For chips other than POWER8NVL, we only have CAPP 0,
+	 * irrespective of which PHB is used.
+	 */
+	if (!pvr_version_is(PVR_POWER8NVL))
+		return CAPP_UNIT0_ID;
+
+	/*
+	 * For POWER8NVL, assume CAPP 0 is attached to PHB0 and
+	 * CAPP 1 is attached to PHB1.
+	 */
+	if (of_property_read_u32(np, "ibm,phb-index", &phb_index))
+		return 0;
+
+	if (phb_index == 0)
+		return CAPP_UNIT0_ID;
+
+	if (phb_index == 1)
+		return CAPP_UNIT1_ID;
+
+	return 0;
+}
+
 static int init_implementation_adapter_regs(struct cxl *adapter, struct pci_dev *dev)
 {
 	struct device_node *np;
 	const __be32 *prop;
-	u64 psl_dsnctl;
+	u64 psl_dsnctl, psl_fircntl;
 	u64 chipid;
+	u64 capp_unit_id;
 
 	if (!(np = pnv_pci_get_phb_node(dev)))
 		return -ENODEV;
@@ -354,16 +369,28 @@ static int init_implementation_adapter_r
 	if (!np)
 		return -ENODEV;
 	chipid = be32_to_cpup(prop);
+	capp_unit_id = get_capp_unit_id(np);
 	of_node_put(np);
+	if (!capp_unit_id) {
+		pr_err("cxl: invalid capp unit id\n");
+		return -ENODEV;
+	}
 
+	psl_dsnctl = 0x0000900000000000ULL; /* pteupd ttype, scdone */
+	psl_dsnctl |= (0x2ULL << (63-38)); /* MMIO hang pulse: 256 us */
 	/* Tell PSL where to route data to */
-	psl_dsnctl = 0x02E8900002000000ULL | (chipid << (63-5));
+	psl_dsnctl |= (chipid << (63-5));
+	psl_dsnctl |= (capp_unit_id << (63-13));
+
 	cxl_p1_write(adapter, CXL_PSL_DSNDCTL, psl_dsnctl);
 	cxl_p1_write(adapter, CXL_PSL_RESLCKTO, 0x20000000200ULL);
 	/* snoop write mask */
 	cxl_p1_write(adapter, CXL_PSL_SNWRALLOC, 0x00000000FFFFFFFFULL);
-	/* set fir_accum */
-	cxl_p1_write(adapter, CXL_PSL_FIR_CNTL, 0x0800000000000000ULL);
+	/* set fir_cntl to recommended value for production env */
+	psl_fircntl = (0x2ULL << (63-3)); /* ce_report */
+	psl_fircntl |= (0x1ULL << (63-6)); /* FIR_report */
+	psl_fircntl |= 0x1ULL; /* ce_thresh */
+	cxl_p1_write(adapter, CXL_PSL_FIR_CNTL, psl_fircntl);
 	/* for debugging with trace arrays */
 	cxl_p1_write(adapter, CXL_PSL_TRACE, 0x0000FF7C00000000ULL);
 
@@ -373,22 +400,24 @@ static int init_implementation_adapter_r
 #define TBSYNC_CNT(n) (((u64)n & 0x7) << (63-6))
 #define _2048_250MHZ_CYCLES 1
 
-static int cxl_setup_psl_timebase(struct cxl *adapter, struct pci_dev *dev)
+static void cxl_setup_psl_timebase(struct cxl *adapter, struct pci_dev *dev)
 {
 	u64 psl_tb;
 	int delta;
 	unsigned int retry = 0;
 	struct device_node *np;
 
+	adapter->psl_timebase_synced = false;
+
 	if (!(np = pnv_pci_get_phb_node(dev)))
-		return -ENODEV;
+		return;
 
 	/* Do not fail when CAPP timebase sync is not supported by OPAL */
 	of_node_get(np);
 	if (! of_get_property(np, "ibm,capp-timebase-sync", NULL)) {
 		of_node_put(np);
-		pr_err("PSL: Timebase sync: OPAL support missing\n");
-		return 0;
+		dev_info(&dev->dev, "PSL timebase inactive: OPAL support missing\n");
+		return;
 	}
 	of_node_put(np);
 
@@ -407,16 +436,17 @@ static int cxl_setup_psl_timebase(struct
 	do {
 		msleep(1);
 		if (retry++ > 5) {
-			pr_err("PSL: Timebase sync: giving up!\n");
-			return -EIO;
+			dev_info(&dev->dev, "PSL timebase can't synchronize\n");
+			return;
 		}
 		psl_tb = cxl_p1_read(adapter, CXL_PSL_Timebase);
 		delta = mftb() - psl_tb;
 		if (delta < 0)
 			delta = -delta;
-	} while (cputime_to_usecs(delta) > 16);
+	} while (tb_to_ns(delta) > 16000);
 
-	return 0;
+	adapter->psl_timebase_synced = true;
+	return;
 }
 
 static int init_implementation_afu_regs(struct cxl_afu *afu)
@@ -432,8 +462,8 @@ static int init_implementation_afu_regs(
 	return 0;
 }
 
-int cxl_setup_irq(struct cxl *adapter, unsigned int hwirq,
-			 unsigned int virq)
+int cxl_pci_setup_irq(struct cxl *adapter, unsigned int hwirq,
+		unsigned int virq)
 {
 	struct pci_dev *dev = to_pci_dev(adapter->dev.parent);
 
@@ -475,28 +505,30 @@ int cxl_update_image_control(struct cxl
 	return 0;
 }
 
-int cxl_alloc_one_irq(struct cxl *adapter)
+int cxl_pci_alloc_one_irq(struct cxl *adapter)
 {
 	struct pci_dev *dev = to_pci_dev(adapter->dev.parent);
 
 	return pnv_cxl_alloc_hwirqs(dev, 1);
 }
 
-void cxl_release_one_irq(struct cxl *adapter, int hwirq)
+void cxl_pci_release_one_irq(struct cxl *adapter, int hwirq)
 {
 	struct pci_dev *dev = to_pci_dev(adapter->dev.parent);
 
 	return pnv_cxl_release_hwirqs(dev, hwirq, 1);
 }
 
-int cxl_alloc_irq_ranges(struct cxl_irq_ranges *irqs, struct cxl *adapter, unsigned int num)
+int cxl_pci_alloc_irq_ranges(struct cxl_irq_ranges *irqs,
+			struct cxl *adapter, unsigned int num)
 {
 	struct pci_dev *dev = to_pci_dev(adapter->dev.parent);
 
 	return pnv_cxl_alloc_hwirq_ranges(irqs, dev, num);
 }
 
-void cxl_release_irq_ranges(struct cxl_irq_ranges *irqs, struct cxl *adapter)
+void cxl_pci_release_irq_ranges(struct cxl_irq_ranges *irqs,
+				struct cxl *adapter)
 {
 	struct pci_dev *dev = to_pci_dev(adapter->dev.parent);
 
@@ -557,7 +589,7 @@ static int switch_card_to_cxl(struct pci
 	return 0;
 }
 
-static int cxl_map_slice_regs(struct cxl_afu *afu, struct cxl *adapter, struct pci_dev *dev)
+static int pci_map_slice_regs(struct cxl_afu *afu, struct cxl *adapter, struct pci_dev *dev)
 {
 	u64 p1n_base, p2n_base, afu_desc;
 	const u64 p1n_size = 0x100;
@@ -565,15 +597,15 @@ static int cxl_map_slice_regs(struct cxl
 
 	p1n_base = p1_base(dev) + 0x10000 + (afu->slice * p1n_size);
 	p2n_base = p2_base(dev) + (afu->slice * p2n_size);
-	afu->psn_phys = p2_base(dev) + (adapter->ps_off + (afu->slice * adapter->ps_size));
-	afu_desc = p2_base(dev) + adapter->afu_desc_off + (afu->slice * adapter->afu_desc_size);
+	afu->psn_phys = p2_base(dev) + (adapter->native->ps_off + (afu->slice * adapter->ps_size));
+	afu_desc = p2_base(dev) + adapter->native->afu_desc_off + (afu->slice * adapter->native->afu_desc_size);
 
-	if (!(afu->p1n_mmio = ioremap(p1n_base, p1n_size)))
+	if (!(afu->native->p1n_mmio = ioremap(p1n_base, p1n_size)))
 		goto err;
 	if (!(afu->p2n_mmio = ioremap(p2n_base, p2n_size)))
 		goto err1;
 	if (afu_desc) {
-		if (!(afu->afu_desc_mmio = ioremap(afu_desc, adapter->afu_desc_size)))
+		if (!(afu->native->afu_desc_mmio = ioremap(afu_desc, adapter->native->afu_desc_size)))
 			goto err2;
 	}
 
@@ -581,62 +613,41 @@ static int cxl_map_slice_regs(struct cxl
 err2:
 	iounmap(afu->p2n_mmio);
 err1:
-	iounmap(afu->p1n_mmio);
+	iounmap(afu->native->p1n_mmio);
 err:
 	dev_err(&afu->dev, "Error mapping AFU MMIO regions\n");
 	return -ENOMEM;
 }
 
-static void cxl_unmap_slice_regs(struct cxl_afu *afu)
+static void pci_unmap_slice_regs(struct cxl_afu *afu)
 {
 	if (afu->p2n_mmio) {
 		iounmap(afu->p2n_mmio);
 		afu->p2n_mmio = NULL;
 	}
-	if (afu->p1n_mmio) {
-		iounmap(afu->p1n_mmio);
-		afu->p1n_mmio = NULL;
+	if (afu->native->p1n_mmio) {
+		iounmap(afu->native->p1n_mmio);
+		afu->native->p1n_mmio = NULL;
 	}
-	if (afu->afu_desc_mmio) {
-		iounmap(afu->afu_desc_mmio);
-		afu->afu_desc_mmio = NULL;
+	if (afu->native->afu_desc_mmio) {
+		iounmap(afu->native->afu_desc_mmio);
+		afu->native->afu_desc_mmio = NULL;
 	}
 }
 
-static void cxl_release_afu(struct device *dev)
+void cxl_pci_release_afu(struct device *dev)
 {
 	struct cxl_afu *afu = to_cxl_afu(dev);
 
-	pr_devel("cxl_release_afu\n");
+	pr_devel("%s\n", __func__);
 
 	idr_destroy(&afu->contexts_idr);
 	cxl_release_spa(afu);
 
+	kfree(afu->native);
 	kfree(afu);
 }
 
-static struct cxl_afu *cxl_alloc_afu(struct cxl *adapter, int slice)
-{
-	struct cxl_afu *afu;
-
-	if (!(afu = kzalloc(sizeof(struct cxl_afu), GFP_KERNEL)))
-		return NULL;
-
-	afu->adapter = adapter;
-	afu->dev.parent = &adapter->dev;
-	afu->dev.release = cxl_release_afu;
-	afu->slice = slice;
-	idr_init(&afu->contexts_idr);
-	mutex_init(&afu->contexts_lock);
-	spin_lock_init(&afu->afu_cntl_lock);
-	mutex_init(&afu->spa_mutex);
-
-	afu->prefault_mode = CXL_PREFAULT_NONE;
-	afu->irqs_max = afu->adapter->user_irqs;
-
-	return afu;
-}
-
 /* Expects AFU struct to have recently been zeroed out */
 static int cxl_read_afu_descriptor(struct cxl_afu *afu)
 {
@@ -658,7 +669,7 @@ static int cxl_read_afu_descriptor(struc
 	afu->pp_size = AFUD_PPPSA_LEN(val) * 4096;
 	afu->psa = AFUD_PPPSA_PSA(val);
 	if ((afu->pp_psa = AFUD_PPPSA_PP(val)))
-		afu->pp_offset = AFUD_READ_PPPSA_OFF(afu);
+		afu->native->pp_offset = AFUD_READ_PPPSA_OFF(afu);
 
 	val = AFUD_READ_CR(afu);
 	afu->crs_len = AFUD_CR_LEN(val) * 256;
@@ -685,10 +696,11 @@ static int cxl_read_afu_descriptor(struc
 
 static int cxl_afu_descriptor_looks_ok(struct cxl_afu *afu)
 {
-	int i;
+	int i, rc;
+	u32 val;
 
 	if (afu->psa && afu->adapter->ps_size <
-			(afu->pp_offset + afu->pp_size*afu->max_procs_virtualised)) {
+			(afu->native->pp_offset + afu->pp_size*afu->max_procs_virtualised)) {
 		dev_err(&afu->dev, "per-process PSA can't fit inside the PSA!\n");
 		return -ENODEV;
 	}
@@ -697,7 +709,8 @@ static int cxl_afu_descriptor_looks_ok(s
 		dev_warn(&afu->dev, "AFU uses < PAGE_SIZE per-process PSA!");
 
 	for (i = 0; i < afu->crs_num; i++) {
-		if ((cxl_afu_cr_read32(afu, i, 0) == 0)) {
+		rc = cxl_ops->afu_cr_read32(afu, i, 0, &val);
+		if (rc || val == 0) {
 			dev_err(&afu->dev, "ABORTING: AFU configuration record %i is invalid\n", i);
 			return -EINVAL;
 		}
@@ -718,7 +731,7 @@ static int sanitise_afu_regs(struct cxl_
 	reg = cxl_p2n_read(afu, CXL_AFU_Cntl_An);
 	if ((reg & CXL_AFU_Cntl_An_ES_MASK) != CXL_AFU_Cntl_An_ES_Disabled) {
 		dev_warn(&afu->dev, "WARNING: AFU was not disabled: %#016llx\n", reg);
-		if (__cxl_afu_reset(afu))
+		if (cxl_ops->afu_reset(afu))
 			return -EIO;
 		if (cxl_afu_disable(afu))
 			return -EIO;
@@ -766,13 +779,13 @@ static int sanitise_afu_regs(struct cxl_
  * 4/8 bytes aligned access. So in case the requested offset/count arent 8 byte
  * aligned the function uses a bounce buffer which can be max PAGE_SIZE.
  */
-ssize_t cxl_afu_read_err_buffer(struct cxl_afu *afu, char *buf,
+ssize_t cxl_pci_afu_read_err_buffer(struct cxl_afu *afu, char *buf,
 				loff_t off, size_t count)
 {
 	loff_t aligned_start, aligned_end;
 	size_t aligned_length;
 	void *tbuf;
-	const void __iomem *ebuf = afu->afu_desc_mmio + afu->eb_offset;
+	const void __iomem *ebuf = afu->native->afu_desc_mmio + afu->eb_offset;
 
 	if (count == 0 || off < 0 || (size_t)off >= afu->eb_len)
 		return 0;
@@ -803,18 +816,18 @@ ssize_t cxl_afu_read_err_buffer(struct c
 	return count;
 }
 
-static int cxl_configure_afu(struct cxl_afu *afu, struct cxl *adapter, struct pci_dev *dev)
+static int pci_configure_afu(struct cxl_afu *afu, struct cxl *adapter, struct pci_dev *dev)
 {
 	int rc;
 
-	if ((rc = cxl_map_slice_regs(afu, adapter, dev)))
+	if ((rc = pci_map_slice_regs(afu, adapter, dev)))
 		return rc;
 
 	if ((rc = sanitise_afu_regs(afu)))
 		goto err1;
 
 	/* We need to reset the AFU before we can read the AFU descriptor */
-	if ((rc = __cxl_afu_reset(afu)))
+	if ((rc = cxl_ops->afu_reset(afu)))
 		goto err1;
 
 	if (cxl_verbose)
@@ -829,44 +842,50 @@ static int cxl_configure_afu(struct cxl_
 	if ((rc = init_implementation_afu_regs(afu)))
 		goto err1;
 
-	if ((rc = cxl_register_serr_irq(afu)))
+	if ((rc = cxl_native_register_serr_irq(afu)))
 		goto err1;
 
-	if ((rc = cxl_register_psl_irq(afu)))
+	if ((rc = cxl_native_register_psl_irq(afu)))
 		goto err2;
 
 	return 0;
 
 err2:
-	cxl_release_serr_irq(afu);
+	cxl_native_release_serr_irq(afu);
 err1:
-	cxl_unmap_slice_regs(afu);
+	pci_unmap_slice_regs(afu);
 	return rc;
 }
 
-static void cxl_deconfigure_afu(struct cxl_afu *afu)
+static void pci_deconfigure_afu(struct cxl_afu *afu)
 {
-	cxl_release_psl_irq(afu);
-	cxl_release_serr_irq(afu);
-	cxl_unmap_slice_regs(afu);
+	cxl_native_release_psl_irq(afu);
+	cxl_native_release_serr_irq(afu);
+	pci_unmap_slice_regs(afu);
 }
 
-static int cxl_init_afu(struct cxl *adapter, int slice, struct pci_dev *dev)
+static int pci_init_afu(struct cxl *adapter, int slice, struct pci_dev *dev)
 {
 	struct cxl_afu *afu;
-	int rc;
+	int rc = -ENOMEM;
 
 	afu = cxl_alloc_afu(adapter, slice);
 	if (!afu)
 		return -ENOMEM;
 
+	afu->native = kzalloc(sizeof(struct cxl_afu_native), GFP_KERNEL);
+	if (!afu->native)
+		goto err_free_afu;
+
+	mutex_init(&afu->native->spa_mutex);
+
 	rc = dev_set_name(&afu->dev, "afu%i.%i", adapter->adapter_num, slice);
 	if (rc)
-		goto err_free;
+		goto err_free_native;
 
-	rc = cxl_configure_afu(afu, adapter, dev);
+	rc = pci_configure_afu(afu, adapter, dev);
 	if (rc)
-		goto err_free;
+		goto err_free_native;
 
 	/* Don't care if this fails */
 	cxl_debugfs_afu_add(afu);
@@ -889,24 +908,27 @@ static int cxl_init_afu(struct cxl *adap
 	return 0;
 
 err_put1:
-	cxl_deconfigure_afu(afu);
+	pci_deconfigure_afu(afu);
 	cxl_debugfs_afu_remove(afu);
 	device_unregister(&afu->dev);
 	return rc;
 
-err_free:
+err_free_native:
+	kfree(afu->native);
+err_free_afu:
 	kfree(afu);
 	return rc;
 
 }
 
-static void cxl_remove_afu(struct cxl_afu *afu)
+static void cxl_pci_remove_afu(struct cxl_afu *afu)
 {
-	pr_devel("cxl_remove_afu\n");
+	pr_devel("%s\n", __func__);
 
 	if (!afu)
 		return;
 
+	cxl_pci_vphb_remove(afu);
 	cxl_sysfs_afu_remove(afu);
 	cxl_debugfs_afu_remove(afu);
 
@@ -915,13 +937,13 @@ static void cxl_remove_afu(struct cxl_af
 	spin_unlock(&afu->adapter->afu_list_lock);
 
 	cxl_context_detach_all(afu);
-	cxl_afu_deactivate_mode(afu);
+	cxl_ops->afu_deactivate_mode(afu, afu->current_mode);
 
-	cxl_deconfigure_afu(afu);
+	pci_deconfigure_afu(afu);
 	device_unregister(&afu->dev);
 }
 
-int cxl_reset(struct cxl *adapter)
+int cxl_pci_reset(struct cxl *adapter)
 {
 	struct pci_dev *dev = to_pci_dev(adapter->dev.parent);
 	int rc;
@@ -934,6 +956,9 @@ int cxl_reset(struct cxl *adapter)
 
 	dev_info(&dev->dev, "CXL reset\n");
 
+	/* the adapter is about to be reset, so ignore errors */
+	cxl_data_cache_flush(adapter);
+
 	/* pcie_warm_reset requests a fundamental pci reset which includes a
 	 * PERST assert/deassert.  PERST triggers a loading of the image
 	 * if "user" or "factory" is selected in sysfs */
@@ -955,17 +980,17 @@ static int cxl_map_adapter_regs(struct c
 	pr_devel("cxl_map_adapter_regs: p1: %#016llx %#llx, p2: %#016llx %#llx",
 			p1_base(dev), p1_size(dev), p2_base(dev), p2_size(dev));
 
-	if (!(adapter->p1_mmio = ioremap(p1_base(dev), p1_size(dev))))
+	if (!(adapter->native->p1_mmio = ioremap(p1_base(dev), p1_size(dev))))
 		goto err3;
 
-	if (!(adapter->p2_mmio = ioremap(p2_base(dev), p2_size(dev))))
+	if (!(adapter->native->p2_mmio = ioremap(p2_base(dev), p2_size(dev))))
 		goto err4;
 
 	return 0;
 
 err4:
-	iounmap(adapter->p1_mmio);
-	adapter->p1_mmio = NULL;
+	iounmap(adapter->native->p1_mmio);
+	adapter->native->p1_mmio = NULL;
 err3:
 	pci_release_region(dev, 0);
 err2:
@@ -976,14 +1001,14 @@ err1:
 
 static void cxl_unmap_adapter_regs(struct cxl *adapter)
 {
-	if (adapter->p1_mmio) {
-		iounmap(adapter->p1_mmio);
-		adapter->p1_mmio = NULL;
+	if (adapter->native->p1_mmio) {
+		iounmap(adapter->native->p1_mmio);
+		adapter->native->p1_mmio = NULL;
 		pci_release_region(to_pci_dev(adapter->dev.parent), 2);
 	}
-	if (adapter->p2_mmio) {
-		iounmap(adapter->p2_mmio);
-		adapter->p2_mmio = NULL;
+	if (adapter->native->p2_mmio) {
+		iounmap(adapter->native->p2_mmio);
+		adapter->native->p2_mmio = NULL;
 		pci_release_region(to_pci_dev(adapter->dev.parent), 0);
 	}
 }
@@ -1024,10 +1049,10 @@ static int cxl_read_vsec(struct cxl *ada
 
 	/* Convert everything to bytes, because there is NO WAY I'd look at the
 	 * code a month later and forget what units these are in ;-) */
-	adapter->ps_off = ps_off * 64 * 1024;
+	adapter->native->ps_off = ps_off * 64 * 1024;
 	adapter->ps_size = ps_size * 64 * 1024;
-	adapter->afu_desc_off = afu_desc_off * 64 * 1024;
-	adapter->afu_desc_size = afu_desc_size *64 * 1024;
+	adapter->native->afu_desc_off = afu_desc_off * 64 * 1024;
+	adapter->native->afu_desc_size = afu_desc_size * 64 * 1024;
 
 	/* Total IRQs - 1 PSL ERROR - #AFU*(1 slice error + 1 DSI) */
 	adapter->user_irqs = pnv_cxl_get_irq_count(dev) - 1 - 2*adapter->slices;
@@ -1078,21 +1103,26 @@ static int cxl_vsec_looks_ok(struct cxl
 		return -EINVAL;
 	}
 
-	if (!adapter->afu_desc_off || !adapter->afu_desc_size) {
+	if (!adapter->native->afu_desc_off || !adapter->native->afu_desc_size) {
 		dev_err(&dev->dev, "ABORTING: VSEC shows no AFU descriptors\n");
 		return -EINVAL;
 	}
 
-	if (adapter->ps_size > p2_size(dev) - adapter->ps_off) {
+	if (adapter->ps_size > p2_size(dev) - adapter->native->ps_off) {
 		dev_err(&dev->dev, "ABORTING: Problem state size larger than "
 				   "available in BAR2: 0x%llx > 0x%llx\n",
-			 adapter->ps_size, p2_size(dev) - adapter->ps_off);
+			 adapter->ps_size, p2_size(dev) - adapter->native->ps_off);
 		return -EINVAL;
 	}
 
 	return 0;
 }
 
+ssize_t cxl_pci_read_adapter_vpd(struct cxl *adapter, void *buf, size_t len)
+{
+	return pci_read_vpd(to_pci_dev(adapter->dev.parent), 0, len, buf);
+}
+
 static void cxl_release_adapter(struct device *dev)
 {
 	struct cxl *adapter = to_cxl_adapter(dev);
@@ -1101,33 +1131,10 @@ static void cxl_release_adapter(struct d
 
 	cxl_remove_adapter_nr(adapter);
 
+	kfree(adapter->native);
 	kfree(adapter);
 }
 
-static struct cxl *cxl_alloc_adapter(void)
-{
-	struct cxl *adapter;
-
-	if (!(adapter = kzalloc(sizeof(struct cxl), GFP_KERNEL)))
-		return NULL;
-
-	spin_lock_init(&adapter->afu_list_lock);
-
-	if (cxl_alloc_adapter_nr(adapter))
-		goto err1;
-
-	if (dev_set_name(&adapter->dev, "card%i", adapter->adapter_num))
-		goto err2;
-
-	return adapter;
-
-err2:
-	cxl_remove_adapter_nr(adapter);
-err1:
-	kfree(adapter);
-	return NULL;
-}
-
 #define CXL_PSL_ErrIVTE_tberror (0x1ull << (63-31))
 
 static int sanitise_adapter_regs(struct cxl *adapter)
@@ -1188,10 +1195,10 @@ static int cxl_configure_adapter(struct
 	if ((rc = pnv_phb_to_cxl_mode(dev, OPAL_PHB_CAPI_MODE_SNOOP_ON)))
 		goto err;
 
-	if ((rc = cxl_setup_psl_timebase(adapter, dev)))
-		goto err;
+	/* Ignore error, adapter init is not dependant on timebase sync */
+	cxl_setup_psl_timebase(adapter, dev);
 
-	if ((rc = cxl_register_psl_err_irq(adapter)))
+	if ((rc = cxl_native_register_psl_err_irq(adapter)))
 		goto err;
 
 	return 0;
@@ -1206,13 +1213,13 @@ static void cxl_deconfigure_adapter(stru
 {
 	struct pci_dev *pdev = to_pci_dev(adapter->dev.parent);
 
-	cxl_release_psl_err_irq(adapter);
+	cxl_native_release_psl_err_irq(adapter);
 	cxl_unmap_adapter_regs(adapter);
 
 	pci_disable_device(pdev);
 }
 
-static struct cxl *cxl_init_adapter(struct pci_dev *dev)
+static struct cxl *cxl_pci_init_adapter(struct pci_dev *dev)
 {
 	struct cxl *adapter;
 	int rc;
@@ -1221,6 +1228,12 @@ static struct cxl *cxl_init_adapter(stru
 	if (!adapter)
 		return ERR_PTR(-ENOMEM);
 
+	adapter->native = kzalloc(sizeof(struct cxl_native), GFP_KERNEL);
+	if (!adapter->native) {
+		rc = -ENOMEM;
+		goto err_release;
+	}
+
 	/* Set defaults for parameters which need to persist over
 	 * configure/reconfigure
 	 */
@@ -1230,8 +1243,7 @@ static struct cxl *cxl_init_adapter(stru
 	rc = cxl_configure_adapter(adapter, dev);
 	if (rc) {
 		pci_disable_device(dev);
-		cxl_release_adapter(&adapter->dev);
-		return ERR_PTR(rc);
+		goto err_release;
 	}
 
 	/* Don't care if this one fails: */
@@ -1257,9 +1269,13 @@ err_put1:
 	cxl_deconfigure_adapter(adapter);
 	device_unregister(&adapter->dev);
 	return ERR_PTR(rc);
+
+err_release:
+	cxl_release_adapter(&adapter->dev);
+	return ERR_PTR(rc);
 }
 
-static void cxl_remove_adapter(struct cxl *adapter)
+static void cxl_pci_remove_adapter(struct cxl *adapter)
 {
 	pr_devel("cxl_remove_adapter\n");
 
@@ -1271,23 +1287,57 @@ static void cxl_remove_adapter(struct cx
 	device_unregister(&adapter->dev);
 }
 
+#define CXL_MAX_PCIEX_PARENT 2
+
+static int cxl_slot_is_switched(struct pci_dev *dev)
+{
+	struct device_node *np;
+	int depth = 0;
+	const __be32 *prop;
+
+	if (!(np = pci_device_to_OF_node(dev))) {
+		pr_err("cxl: np = NULL\n");
+		return -ENODEV;
+	}
+	of_node_get(np);
+	while (np) {
+		np = of_get_next_parent(np);
+		prop = of_get_property(np, "device_type", NULL);
+		if (!prop || strcmp((char *)prop, "pciex"))
+			break;
+		depth++;
+	}
+	of_node_put(np);
+	return (depth > CXL_MAX_PCIEX_PARENT);
+}
+
 static int cxl_probe(struct pci_dev *dev, const struct pci_device_id *id)
 {
 	struct cxl *adapter;
 	int slice;
 	int rc;
 
+	if (cxl_pci_is_vphb_device(dev)) {
+		dev_dbg(&dev->dev, "cxl_init_adapter: Ignoring cxl vphb device\n");
+		return -ENODEV;
+	}
+
+	if (cxl_slot_is_switched(dev)) {
+		dev_info(&dev->dev, "Ignoring card on incompatible PCI slot\n");
+		return -ENODEV;
+	}
+
 	if (cxl_verbose)
 		dump_cxl_config_space(dev);
 
-	adapter = cxl_init_adapter(dev);
+	adapter = cxl_pci_init_adapter(dev);
 	if (IS_ERR(adapter)) {
 		dev_err(&dev->dev, "cxl_init_adapter failed: %li\n", PTR_ERR(adapter));
 		return PTR_ERR(adapter);
 	}
 
 	for (slice = 0; slice < adapter->slices; slice++) {
-		if ((rc = cxl_init_afu(adapter, slice, dev))) {
+		if ((rc = pci_init_afu(adapter, slice, dev))) {
 			dev_err(&dev->dev, "AFU %i failed to initialise: %i\n", slice, rc);
 			continue;
 		}
@@ -1312,10 +1362,9 @@ static void cxl_remove(struct pci_dev *d
 	 */
 	for (i = 0; i < adapter->slices; i++) {
 		afu = adapter->afu[i];
-		cxl_pci_vphb_remove(afu);
-		cxl_remove_afu(afu);
+		cxl_pci_remove_afu(afu);
 	}
-	cxl_remove_adapter(adapter);
+	cxl_pci_remove_adapter(adapter);
 }
 
 static pci_ers_result_t cxl_vphb_error_detected(struct cxl_afu *afu,
@@ -1461,8 +1510,8 @@ static pci_ers_result_t cxl_pci_error_de
 			return result;
 
 		cxl_context_detach_all(afu);
-		cxl_afu_deactivate_mode(afu);
-		cxl_deconfigure_afu(afu);
+		cxl_ops->afu_deactivate_mode(afu, afu->current_mode);
+		pci_deconfigure_afu(afu);
 	}
 	cxl_deconfigure_adapter(adapter);
 
@@ -1485,14 +1534,12 @@ static pci_ers_result_t cxl_pci_slot_res
 	for (i = 0; i < adapter->slices; i++) {
 		afu = adapter->afu[i];
 
-		if (cxl_configure_afu(afu, adapter, pdev))
+		if (pci_configure_afu(afu, adapter, pdev))
 			goto err;
 
 		if (cxl_afu_select_best_mode(afu))
 			goto err;
 
-		cxl_pci_vphb_reconfigure(afu);
-
 		list_for_each_entry(afu_dev, &afu->phb->bus->devices, bus_list) {
 			/* Reset the device context.
 			 * TODO: make this less disruptive
@@ -1508,7 +1555,7 @@ static pci_ers_result_t cxl_pci_slot_res
 
 			afu_dev->dev.archdata.cxl_ctx = ctx;
 
-			if (cxl_afu_check_and_enable(afu))
+			if (cxl_ops->afu_check_and_enable(afu))
 				goto err;
 
 			afu_dev->error_state = pci_channel_io_normal;
--- zfcpdump-kernel-4.4.orig/drivers/misc/cxl/sysfs.c
+++ zfcpdump-kernel-4.4/drivers/misc/cxl/sysfs.c
@@ -57,6 +57,15 @@ static ssize_t image_loaded_show(struct
 	return scnprintf(buf, PAGE_SIZE, "factory\n");
 }
 
+static ssize_t psl_timebase_synced_show(struct device *device,
+					struct device_attribute *attr,
+					char *buf)
+{
+	struct cxl *adapter = to_cxl_adapter(device);
+
+	return scnprintf(buf, PAGE_SIZE, "%i\n", adapter->psl_timebase_synced);
+}
+
 static ssize_t reset_adapter_store(struct device *device,
 				   struct device_attribute *attr,
 				   const char *buf, size_t count)
@@ -69,7 +78,7 @@ static ssize_t reset_adapter_store(struc
 	if ((rc != 1) || (val != 1))
 		return -EINVAL;
 
-	if ((rc = cxl_reset(adapter)))
+	if ((rc = cxl_ops->adapter_reset(adapter)))
 		return rc;
 	return count;
 }
@@ -142,6 +151,7 @@ static struct device_attribute adapter_a
 	__ATTR_RO(psl_revision),
 	__ATTR_RO(base_image),
 	__ATTR_RO(image_loaded),
+	__ATTR_RO(psl_timebase_synced),
 	__ATTR_RW(load_image_on_perst),
 	__ATTR_RW(perst_reloads_same_image),
 	__ATTR(reset, S_IWUSR, NULL, reset_adapter_store),
@@ -165,7 +175,7 @@ static ssize_t pp_mmio_off_show(struct d
 {
 	struct cxl_afu *afu = to_afu_chardev_m(device);
 
-	return scnprintf(buf, PAGE_SIZE, "%llu\n", afu->pp_offset);
+	return scnprintf(buf, PAGE_SIZE, "%llu\n", afu->native->pp_offset);
 }
 
 static ssize_t pp_mmio_len_show(struct device *device,
@@ -211,7 +221,7 @@ static ssize_t reset_store_afu(struct de
 		goto err;
 	}
 
-	if ((rc = __cxl_afu_reset(afu)))
+	if ((rc = cxl_ops->afu_reset(afu)))
 		goto err;
 
 	rc = count;
@@ -253,8 +263,14 @@ static ssize_t irqs_max_store(struct dev
 	if (irqs_max < afu->pp_irqs)
 		return -EINVAL;
 
-	if (irqs_max > afu->adapter->user_irqs)
-		return -EINVAL;
+	if (cpu_has_feature(CPU_FTR_HVMODE)) {
+		if (irqs_max > afu->adapter->user_irqs)
+			return -EINVAL;
+	} else {
+		/* pHyp sets a per-AFU limit */
+		if (irqs_max > afu->guest->max_ints)
+			return -EINVAL;
+	}
 
 	afu->irqs_max = irqs_max;
 	return count;
@@ -348,7 +364,7 @@ static ssize_t mode_store(struct device
 	}
 
 	/*
-	 * cxl_afu_deactivate_mode needs to be done outside the lock, prevent
+	 * afu_deactivate_mode needs to be done outside the lock, prevent
 	 * other contexts coming in before we are ready:
 	 */
 	old_mode = afu->current_mode;
@@ -357,9 +373,9 @@ static ssize_t mode_store(struct device
 
 	mutex_unlock(&afu->contexts_lock);
 
-	if ((rc = _cxl_afu_deactivate_mode(afu, old_mode)))
+	if ((rc = cxl_ops->afu_deactivate_mode(afu, old_mode)))
 		return rc;
-	if ((rc = cxl_afu_activate_mode(afu, mode)))
+	if ((rc = cxl_ops->afu_activate_mode(afu, mode)))
 		return rc;
 
 	return count;
@@ -386,10 +402,9 @@ static ssize_t afu_eb_read(struct file *
 			       struct bin_attribute *bin_attr, char *buf,
 			       loff_t off, size_t count)
 {
-	struct cxl_afu *afu = to_cxl_afu(container_of(kobj,
-						      struct device, kobj));
+	struct cxl_afu *afu = to_cxl_afu(kobj_to_dev(kobj));
 
-	return cxl_afu_read_err_buffer(afu, buf, off, count);
+	return cxl_ops->afu_read_err_buffer(afu, buf, off, count);
 }
 
 static struct device_attribute afu_attrs[] = {
@@ -406,24 +421,39 @@ static struct device_attribute afu_attrs
 
 int cxl_sysfs_adapter_add(struct cxl *adapter)
 {
+	struct device_attribute *dev_attr;
 	int i, rc;
 
 	for (i = 0; i < ARRAY_SIZE(adapter_attrs); i++) {
-		if ((rc = device_create_file(&adapter->dev, &adapter_attrs[i])))
-			goto err;
+		dev_attr = &adapter_attrs[i];
+		if (cxl_ops->support_attributes(dev_attr->attr.name,
+						CXL_ADAPTER_ATTRS)) {
+			if ((rc = device_create_file(&adapter->dev, dev_attr)))
+				goto err;
+		}
 	}
 	return 0;
 err:
-	for (i--; i >= 0; i--)
-		device_remove_file(&adapter->dev, &adapter_attrs[i]);
+	for (i--; i >= 0; i--) {
+		dev_attr = &adapter_attrs[i];
+		if (cxl_ops->support_attributes(dev_attr->attr.name,
+						CXL_ADAPTER_ATTRS))
+			device_remove_file(&adapter->dev, dev_attr);
+	}
 	return rc;
 }
+
 void cxl_sysfs_adapter_remove(struct cxl *adapter)
 {
+	struct device_attribute *dev_attr;
 	int i;
 
-	for (i = 0; i < ARRAY_SIZE(adapter_attrs); i++)
-		device_remove_file(&adapter->dev, &adapter_attrs[i]);
+	for (i = 0; i < ARRAY_SIZE(adapter_attrs); i++) {
+		dev_attr = &adapter_attrs[i];
+		if (cxl_ops->support_attributes(dev_attr->attr.name,
+						CXL_ADAPTER_ATTRS))
+			device_remove_file(&adapter->dev, dev_attr);
+	}
 }
 
 struct afu_config_record {
@@ -467,12 +497,14 @@ static ssize_t afu_read_config(struct fi
 			       loff_t off, size_t count)
 {
 	struct afu_config_record *cr = to_cr(kobj);
-	struct cxl_afu *afu = to_cxl_afu(container_of(kobj->parent, struct device, kobj));
+	struct cxl_afu *afu = to_cxl_afu(kobj_to_dev(kobj->parent));
 
-	u64 i, j, val;
+	u64 i, j, val, rc;
 
 	for (i = 0; i < count;) {
-		val = cxl_afu_cr_read64(afu, cr->cr, off & ~0x7);
+		rc = cxl_ops->afu_cr_read64(afu, cr->cr, off & ~0x7, &val);
+		if (rc)
+			val = ~0ULL;
 		for (j = off & 0x7; j < 8 && i < count; i++, j++, off++)
 			buf[i] = (val >> (j * 8)) & 0xff;
 	}
@@ -517,14 +549,22 @@ static struct afu_config_record *cxl_sys
 		return ERR_PTR(-ENOMEM);
 
 	cr->cr = cr_idx;
-	cr->device = cxl_afu_cr_read16(afu, cr_idx, PCI_DEVICE_ID);
-	cr->vendor = cxl_afu_cr_read16(afu, cr_idx, PCI_VENDOR_ID);
-	cr->class = cxl_afu_cr_read32(afu, cr_idx, PCI_CLASS_REVISION) >> 8;
+
+	rc = cxl_ops->afu_cr_read16(afu, cr_idx, PCI_DEVICE_ID, &cr->device);
+	if (rc)
+		goto err;
+	rc = cxl_ops->afu_cr_read16(afu, cr_idx, PCI_VENDOR_ID, &cr->vendor);
+	if (rc)
+		goto err;
+	rc = cxl_ops->afu_cr_read32(afu, cr_idx, PCI_CLASS_REVISION, &cr->class);
+	if (rc)
+		goto err;
+	cr->class >>= 8;
 
 	/*
 	 * Export raw AFU PCIe like config record. For now this is read only by
 	 * root - we can expand that later to be readable by non-root and maybe
-	 * even writable provided we have a good use-case. Once we suport
+	 * even writable provided we have a good use-case. Once we support
 	 * exposing AFUs through a virtual PHB they will get that for free from
 	 * Linux' PCI infrastructure, but until then it's not clear that we
 	 * need it for anything since the main use case is just identifying
@@ -562,6 +602,7 @@ err:
 
 void cxl_sysfs_afu_remove(struct cxl_afu *afu)
 {
+	struct device_attribute *dev_attr;
 	struct afu_config_record *cr, *tmp;
 	int i;
 
@@ -569,8 +610,12 @@ void cxl_sysfs_afu_remove(struct cxl_afu
 	if (afu->eb_len)
 		device_remove_bin_file(&afu->dev, &afu->attr_eb);
 
-	for (i = 0; i < ARRAY_SIZE(afu_attrs); i++)
-		device_remove_file(&afu->dev, &afu_attrs[i]);
+	for (i = 0; i < ARRAY_SIZE(afu_attrs); i++) {
+		dev_attr = &afu_attrs[i];
+		if (cxl_ops->support_attributes(dev_attr->attr.name,
+						CXL_AFU_ATTRS))
+			device_remove_file(&afu->dev, &afu_attrs[i]);
+	}
 
 	list_for_each_entry_safe(cr, tmp, &afu->crs, list) {
 		sysfs_remove_bin_file(&cr->kobj, &cr->config_attr);
@@ -580,14 +625,19 @@ void cxl_sysfs_afu_remove(struct cxl_afu
 
 int cxl_sysfs_afu_add(struct cxl_afu *afu)
 {
+	struct device_attribute *dev_attr;
 	struct afu_config_record *cr;
 	int i, rc;
 
 	INIT_LIST_HEAD(&afu->crs);
 
 	for (i = 0; i < ARRAY_SIZE(afu_attrs); i++) {
-		if ((rc = device_create_file(&afu->dev, &afu_attrs[i])))
-			goto err;
+		dev_attr = &afu_attrs[i];
+		if (cxl_ops->support_attributes(dev_attr->attr.name,
+						CXL_AFU_ATTRS)) {
+			if ((rc = device_create_file(&afu->dev, &afu_attrs[i])))
+				goto err;
+		}
 	}
 
 	/* conditionally create the add the binary file for error info buffer */
@@ -626,32 +676,50 @@ err:
 	/* reset the eb_len as we havent created the bin attr */
 	afu->eb_len = 0;
 
-	for (i--; i >= 0; i--)
+	for (i--; i >= 0; i--) {
+		dev_attr = &afu_attrs[i];
+		if (cxl_ops->support_attributes(dev_attr->attr.name,
+						CXL_AFU_ATTRS))
 		device_remove_file(&afu->dev, &afu_attrs[i]);
+	}
 	return rc;
 }
 
 int cxl_sysfs_afu_m_add(struct cxl_afu *afu)
 {
+	struct device_attribute *dev_attr;
 	int i, rc;
 
 	for (i = 0; i < ARRAY_SIZE(afu_master_attrs); i++) {
-		if ((rc = device_create_file(afu->chardev_m, &afu_master_attrs[i])))
-			goto err;
+		dev_attr = &afu_master_attrs[i];
+		if (cxl_ops->support_attributes(dev_attr->attr.name,
+						CXL_AFU_MASTER_ATTRS)) {
+			if ((rc = device_create_file(afu->chardev_m, &afu_master_attrs[i])))
+				goto err;
+		}
 	}
 
 	return 0;
 
 err:
-	for (i--; i >= 0; i--)
-		device_remove_file(afu->chardev_m, &afu_master_attrs[i]);
+	for (i--; i >= 0; i--) {
+		dev_attr = &afu_master_attrs[i];
+		if (cxl_ops->support_attributes(dev_attr->attr.name,
+						CXL_AFU_MASTER_ATTRS))
+			device_remove_file(afu->chardev_m, &afu_master_attrs[i]);
+	}
 	return rc;
 }
 
 void cxl_sysfs_afu_m_remove(struct cxl_afu *afu)
 {
+	struct device_attribute *dev_attr;
 	int i;
 
-	for (i = 0; i < ARRAY_SIZE(afu_master_attrs); i++)
-		device_remove_file(afu->chardev_m, &afu_master_attrs[i]);
+	for (i = 0; i < ARRAY_SIZE(afu_master_attrs); i++) {
+		dev_attr = &afu_master_attrs[i];
+		if (cxl_ops->support_attributes(dev_attr->attr.name,
+						CXL_AFU_MASTER_ATTRS))
+			device_remove_file(afu->chardev_m, &afu_master_attrs[i]);
+	}
 }
--- zfcpdump-kernel-4.4.orig/drivers/misc/cxl/trace.h
+++ zfcpdump-kernel-4.4/drivers/misc/cxl/trace.h
@@ -450,6 +450,199 @@ DEFINE_EVENT(cxl_pe_class, cxl_slbia,
 	TP_ARGS(ctx)
 );
 
+TRACE_EVENT(cxl_hcall,
+	TP_PROTO(u64 unit_address, u64 process_token, long rc),
+
+	TP_ARGS(unit_address, process_token, rc),
+
+	TP_STRUCT__entry(
+		__field(u64, unit_address)
+		__field(u64, process_token)
+		__field(long, rc)
+	),
+
+	TP_fast_assign(
+		__entry->unit_address = unit_address;
+		__entry->process_token = process_token;
+		__entry->rc = rc;
+	),
+
+	TP_printk("unit_address=0x%016llx process_token=0x%016llx rc=%li",
+		__entry->unit_address,
+		__entry->process_token,
+		__entry->rc
+	)
+);
+
+TRACE_EVENT(cxl_hcall_control,
+	TP_PROTO(u64 unit_address, char *fct, u64 p1, u64 p2, u64 p3,
+	u64 p4, unsigned long r4, long rc),
+
+	TP_ARGS(unit_address, fct, p1, p2, p3, p4, r4, rc),
+
+	TP_STRUCT__entry(
+		__field(u64, unit_address)
+		__field(char *, fct)
+		__field(u64, p1)
+		__field(u64, p2)
+		__field(u64, p3)
+		__field(u64, p4)
+		__field(unsigned long, r4)
+		__field(long, rc)
+	),
+
+	TP_fast_assign(
+		__entry->unit_address = unit_address;
+		__entry->fct = fct;
+		__entry->p1 = p1;
+		__entry->p2 = p2;
+		__entry->p3 = p3;
+		__entry->p4 = p4;
+		__entry->r4 = r4;
+		__entry->rc = rc;
+	),
+
+	TP_printk("unit_address=%#.16llx %s(%#llx, %#llx, %#llx, %#llx, R4: %#lx)): %li",
+		__entry->unit_address,
+		__entry->fct,
+		__entry->p1,
+		__entry->p2,
+		__entry->p3,
+		__entry->p4,
+		__entry->r4,
+		__entry->rc
+	)
+);
+
+TRACE_EVENT(cxl_hcall_attach,
+	TP_PROTO(u64 unit_address, u64 phys_addr, unsigned long process_token,
+		unsigned long mmio_addr, unsigned long mmio_size, long rc),
+
+	TP_ARGS(unit_address, phys_addr, process_token,
+		mmio_addr, mmio_size, rc),
+
+	TP_STRUCT__entry(
+		__field(u64, unit_address)
+		__field(u64, phys_addr)
+		__field(unsigned long, process_token)
+		__field(unsigned long, mmio_addr)
+		__field(unsigned long, mmio_size)
+		__field(long, rc)
+	),
+
+	TP_fast_assign(
+		__entry->unit_address = unit_address;
+		__entry->phys_addr = phys_addr;
+		__entry->process_token = process_token;
+		__entry->mmio_addr = mmio_addr;
+		__entry->mmio_size = mmio_size;
+		__entry->rc = rc;
+	),
+
+	TP_printk("unit_address=0x%016llx phys_addr=0x%016llx "
+		"token=0x%.8lx mmio_addr=0x%lx mmio_size=0x%lx rc=%li",
+		__entry->unit_address,
+		__entry->phys_addr,
+		__entry->process_token,
+		__entry->mmio_addr,
+		__entry->mmio_size,
+		__entry->rc
+	)
+);
+
+DEFINE_EVENT(cxl_hcall, cxl_hcall_detach,
+	TP_PROTO(u64 unit_address, u64 process_token, long rc),
+	TP_ARGS(unit_address, process_token, rc)
+);
+
+DEFINE_EVENT(cxl_hcall_control, cxl_hcall_control_function,
+	TP_PROTO(u64 unit_address, char *fct, u64 p1, u64 p2, u64 p3,
+	u64 p4, unsigned long r4, long rc),
+	TP_ARGS(unit_address, fct, p1, p2, p3, p4, r4, rc)
+);
+
+DEFINE_EVENT(cxl_hcall, cxl_hcall_collect_int_info,
+	TP_PROTO(u64 unit_address, u64 process_token, long rc),
+	TP_ARGS(unit_address, process_token, rc)
+);
+
+TRACE_EVENT(cxl_hcall_control_faults,
+	TP_PROTO(u64 unit_address, u64 process_token,
+		u64 control_mask, u64 reset_mask, unsigned long r4,
+		long rc),
+
+	TP_ARGS(unit_address, process_token,
+		control_mask, reset_mask, r4, rc),
+
+	TP_STRUCT__entry(
+		__field(u64, unit_address)
+		__field(u64, process_token)
+		__field(u64, control_mask)
+		__field(u64, reset_mask)
+		__field(unsigned long, r4)
+		__field(long, rc)
+	),
+
+	TP_fast_assign(
+		__entry->unit_address = unit_address;
+		__entry->process_token = process_token;
+		__entry->control_mask = control_mask;
+		__entry->reset_mask = reset_mask;
+		__entry->r4 = r4;
+		__entry->rc = rc;
+	),
+
+	TP_printk("unit_address=0x%016llx process_token=0x%llx "
+		"control_mask=%#llx reset_mask=%#llx r4=%#lx rc=%li",
+		__entry->unit_address,
+		__entry->process_token,
+		__entry->control_mask,
+		__entry->reset_mask,
+		__entry->r4,
+		__entry->rc
+	)
+);
+
+DEFINE_EVENT(cxl_hcall_control, cxl_hcall_control_facility,
+	TP_PROTO(u64 unit_address, char *fct, u64 p1, u64 p2, u64 p3,
+	u64 p4, unsigned long r4, long rc),
+	TP_ARGS(unit_address, fct, p1, p2, p3, p4, r4, rc)
+);
+
+TRACE_EVENT(cxl_hcall_download_facility,
+	TP_PROTO(u64 unit_address, char *fct, u64 list_address, u64 num,
+	unsigned long r4, long rc),
+
+	TP_ARGS(unit_address, fct, list_address, num, r4, rc),
+
+	TP_STRUCT__entry(
+		__field(u64, unit_address)
+		__field(char *, fct)
+		__field(u64, list_address)
+		__field(u64, num)
+		__field(unsigned long, r4)
+		__field(long, rc)
+	),
+
+	TP_fast_assign(
+		__entry->unit_address = unit_address;
+		__entry->fct = fct;
+		__entry->list_address = list_address;
+		__entry->num = num;
+		__entry->r4 = r4;
+		__entry->rc = rc;
+	),
+
+	TP_printk("%#.16llx, %s(%#llx, %#llx), %#lx): %li",
+		__entry->unit_address,
+		__entry->fct,
+		__entry->list_address,
+		__entry->num,
+		__entry->r4,
+		__entry->rc
+	)
+);
+
 #endif /* _CXL_TRACE_H */
 
 /* This part must be outside protection */
--- zfcpdump-kernel-4.4.orig/drivers/misc/cxl/vphb.c
+++ zfcpdump-kernel-4.4/drivers/misc/cxl/vphb.c
@@ -49,7 +49,7 @@ static bool cxl_pci_enable_device_hook(s
 	phb = pci_bus_to_host(dev->bus);
 	afu = (struct cxl_afu *)phb->private_data;
 
-	if (!cxl_adapter_link_ok(afu->adapter)) {
+	if (!cxl_ops->link_ok(afu->adapter, afu)) {
 		dev_warn(&dev->dev, "%s: Device link is down, refusing to enable AFU\n", __func__);
 		return false;
 	}
@@ -66,7 +66,7 @@ static bool cxl_pci_enable_device_hook(s
 		return false;
 	dev->dev.archdata.cxl_ctx = ctx;
 
-	return (cxl_afu_check_and_enable(afu) == 0);
+	return (cxl_ops->afu_check_and_enable(afu) == 0);
 }
 
 static void cxl_pci_disable_device(struct pci_dev *dev)
@@ -99,113 +99,90 @@ static int cxl_pcie_cfg_record(u8 bus, u
 	return (bus << 8) + devfn;
 }
 
-static unsigned long cxl_pcie_cfg_addr(struct pci_controller* phb,
-				       u8 bus, u8 devfn, int offset)
-{
-	int record = cxl_pcie_cfg_record(bus, devfn);
-
-	return (unsigned long)phb->cfg_addr + ((unsigned long)phb->cfg_data * record) + offset;
-}
-
-
 static int cxl_pcie_config_info(struct pci_bus *bus, unsigned int devfn,
-				int offset, int len,
-				volatile void __iomem **ioaddr,
-				u32 *mask, int *shift)
+				struct cxl_afu **_afu, int *_record)
 {
 	struct pci_controller *phb;
 	struct cxl_afu *afu;
-	unsigned long addr;
+	int record;
 
 	phb = pci_bus_to_host(bus);
 	if (phb == NULL)
 		return PCIBIOS_DEVICE_NOT_FOUND;
-	afu = (struct cxl_afu *)phb->private_data;
 
-	if (cxl_pcie_cfg_record(bus->number, devfn) > afu->crs_num)
+	afu = (struct cxl_afu *)phb->private_data;
+	record = cxl_pcie_cfg_record(bus->number, devfn);
+	if (record > afu->crs_num)
 		return PCIBIOS_DEVICE_NOT_FOUND;
-	if (offset >= (unsigned long)phb->cfg_data)
-		return PCIBIOS_BAD_REGISTER_NUMBER;
-	addr = cxl_pcie_cfg_addr(phb, bus->number, devfn, offset);
 
-	*ioaddr = (void *)(addr & ~0x3ULL);
-	*shift = ((addr & 0x3) * 8);
-	switch (len) {
-	case 1:
-		*mask = 0xff;
-		break;
-	case 2:
-		*mask = 0xffff;
-		break;
-	default:
-		*mask = 0xffffffff;
-		break;
-	}
+	*_afu = afu;
+	*_record = record;
 	return 0;
 }
 
-
-static inline bool cxl_config_link_ok(struct pci_bus *bus)
-{
-	struct pci_controller *phb;
-	struct cxl_afu *afu;
-
-	/* Config space IO is based on phb->cfg_addr, which is based on
-	 * afu_desc_mmio. This isn't safe to read/write when the link
-	 * goes down, as EEH tears down MMIO space.
-	 *
-	 * Check if the link is OK before proceeding.
-	 */
-
-	phb = pci_bus_to_host(bus);
-	if (phb == NULL)
-		return false;
-	afu = (struct cxl_afu *)phb->private_data;
-	return cxl_adapter_link_ok(afu->adapter);
-}
-
 static int cxl_pcie_read_config(struct pci_bus *bus, unsigned int devfn,
 				int offset, int len, u32 *val)
 {
-	volatile void __iomem *ioaddr;
-	int shift, rc;
-	u32 mask;
+	int rc, record;
+	struct cxl_afu *afu;
+	u8 val8;
+	u16 val16;
+	u32 val32;
 
-	rc = cxl_pcie_config_info(bus, devfn, offset, len, &ioaddr,
-				  &mask, &shift);
+	rc = cxl_pcie_config_info(bus, devfn, &afu, &record);
 	if (rc)
 		return rc;
 
-	if (!cxl_config_link_ok(bus))
+	switch (len) {
+	case 1:
+		rc = cxl_ops->afu_cr_read8(afu, record, offset,	&val8);
+		*val = val8;
+		break;
+	case 2:
+		rc = cxl_ops->afu_cr_read16(afu, record, offset, &val16);
+		*val = val16;
+		break;
+	case 4:
+		rc = cxl_ops->afu_cr_read32(afu, record, offset, &val32);
+		*val = val32;
+		break;
+	default:
+		WARN_ON(1);
+	}
+
+	if (rc)
 		return PCIBIOS_DEVICE_NOT_FOUND;
 
-	/* Can only read 32 bits */
-	*val = (in_le32(ioaddr) >> shift) & mask;
 	return PCIBIOS_SUCCESSFUL;
 }
 
 static int cxl_pcie_write_config(struct pci_bus *bus, unsigned int devfn,
 				 int offset, int len, u32 val)
 {
-	volatile void __iomem *ioaddr;
-	u32 v, mask;
-	int shift, rc;
+	int rc, record;
+	struct cxl_afu *afu;
 
-	rc = cxl_pcie_config_info(bus, devfn, offset, len, &ioaddr,
-				  &mask, &shift);
+	rc = cxl_pcie_config_info(bus, devfn, &afu, &record);
 	if (rc)
 		return rc;
 
-	if (!cxl_config_link_ok(bus))
-		return PCIBIOS_DEVICE_NOT_FOUND;
-
-	/* Can only write 32 bits so do read-modify-write */
-	mask <<= shift;
-	val <<= shift;
+	switch (len) {
+	case 1:
+		rc = cxl_ops->afu_cr_write8(afu, record, offset, val & 0xff);
+		break;
+	case 2:
+		rc = cxl_ops->afu_cr_write16(afu, record, offset, val & 0xffff);
+		break;
+	case 4:
+		rc = cxl_ops->afu_cr_write32(afu, record, offset, val);
+		break;
+	default:
+		WARN_ON(1);
+	}
 
-	v = (in_le32(ioaddr) & ~mask) || (val & mask);
+	if (rc)
+		return PCIBIOS_SET_FAILED;
 
-	out_le32(ioaddr, v);
 	return PCIBIOS_SUCCESSFUL;
 }
 
@@ -231,25 +208,32 @@ static struct pci_controller_ops cxl_pci
 
 int cxl_pci_vphb_add(struct cxl_afu *afu)
 {
-	struct pci_dev *phys_dev;
-	struct pci_controller *phb, *phys_phb;
+	struct pci_controller *phb;
+	struct device_node *vphb_dn;
+	struct device *parent;
 
-	phys_dev = to_pci_dev(afu->adapter->dev.parent);
-	phys_phb = pci_bus_to_host(phys_dev->bus);
+	/* The parent device is the adapter. Reuse the device node of
+	 * the adapter.
+	 * We don't seem to care what device node is used for the vPHB,
+	 * but tools such as lsvpd walk up the device parents looking
+	 * for a valid location code, so we might as well show devices
+	 * attached to the adapter as being located on that adapter.
+	 */
+	parent = afu->adapter->dev.parent;
+	vphb_dn = parent->of_node;
 
 	/* Alloc and setup PHB data structure */
-	phb = pcibios_alloc_controller(phys_phb->dn);
-
+	phb = pcibios_alloc_controller(vphb_dn);
 	if (!phb)
 		return -ENODEV;
 
 	/* Setup parent in sysfs */
-	phb->parent = &phys_dev->dev;
+	phb->parent = parent;
 
 	/* Setup the PHB using arch provided callback */
 	phb->ops = &cxl_pcie_pci_ops;
-	phb->cfg_addr = afu->afu_desc_mmio + afu->crs_offset;
-	phb->cfg_data = (void *)(u64)afu->crs_len;
+	phb->cfg_addr = NULL;
+	phb->cfg_data = 0;
 	phb->private_data = afu;
 	phb->controller_ops = cxl_pci_controller_ops;
 
@@ -272,15 +256,6 @@ int cxl_pci_vphb_add(struct cxl_afu *afu
 	return 0;
 }
 
-void cxl_pci_vphb_reconfigure(struct cxl_afu *afu)
-{
-	/* When we are reconfigured, the AFU's MMIO space is unmapped
-	 * and remapped. We need to reflect this in the PHB's view of
-	 * the world.
-	 */
-	afu->phb->cfg_addr = afu->afu_desc_mmio + afu->crs_offset;
-}
-
 void cxl_pci_vphb_remove(struct cxl_afu *afu)
 {
 	struct pci_controller *phb;
@@ -296,6 +271,15 @@ void cxl_pci_vphb_remove(struct cxl_afu
 	pcibios_free_controller(phb);
 }
 
+bool cxl_pci_is_vphb_device(struct pci_dev *dev)
+{
+	struct pci_controller *phb;
+
+	phb = pci_bus_to_host(dev->bus);
+
+	return (phb->ops == &cxl_pcie_pci_ops);
+}
+
 struct cxl_afu *cxl_pci_to_afu(struct pci_dev *dev)
 {
 	struct pci_controller *phb;
--- zfcpdump-kernel-4.4.orig/drivers/misc/mei/amthif.c
+++ zfcpdump-kernel-4.4/drivers/misc/mei/amthif.c
@@ -417,8 +417,10 @@ int mei_amthif_irq_read_msg(struct mei_c
 
 	dev = cl->dev;
 
-	if (dev->iamthif_state != MEI_IAMTHIF_READING)
+	if (dev->iamthif_state != MEI_IAMTHIF_READING) {
+		mei_irq_discard_msg(dev, mei_hdr);
 		return 0;
+	}
 
 	ret = mei_cl_irq_read_msg(cl, mei_hdr, cmpl_list);
 	if (ret)
--- zfcpdump-kernel-4.4.orig/drivers/misc/mei/bus.c
+++ zfcpdump-kernel-4.4/drivers/misc/mei/bus.c
@@ -53,6 +53,11 @@ ssize_t __mei_cl_send(struct mei_cl *cl,
 	bus = cl->dev;
 
 	mutex_lock(&bus->device_lock);
+	if (bus->dev_state != MEI_DEV_ENABLED) {
+		rets = -ENODEV;
+		goto out;
+	}
+
 	if (!mei_cl_is_connected(cl)) {
 		rets = -ENODEV;
 		goto out;
@@ -109,6 +114,10 @@ ssize_t __mei_cl_recv(struct mei_cl *cl,
 	bus = cl->dev;
 
 	mutex_lock(&bus->device_lock);
+	if (bus->dev_state != MEI_DEV_ENABLED) {
+		rets = -ENODEV;
+		goto out;
+	}
 
 	cb = mei_cl_read_cb(cl, NULL);
 	if (cb)
@@ -213,17 +222,23 @@ EXPORT_SYMBOL_GPL(mei_cldev_recv);
 static void mei_cl_bus_event_work(struct work_struct *work)
 {
 	struct mei_cl_device *cldev;
+	struct mei_device *bus;
 
 	cldev = container_of(work, struct mei_cl_device, event_work);
 
+	bus = cldev->bus;
+
 	if (cldev->event_cb)
 		cldev->event_cb(cldev, cldev->events, cldev->event_context);
 
 	cldev->events = 0;
 
 	/* Prepare for the next read */
-	if (cldev->events_mask & BIT(MEI_CL_EVENT_RX))
+	if (cldev->events_mask & BIT(MEI_CL_EVENT_RX)) {
+		mutex_lock(&bus->device_lock);
 		mei_cl_read_start(cldev->cl, 0, NULL);
+		mutex_unlock(&bus->device_lock);
+	}
 }
 
 /**
@@ -287,6 +302,7 @@ int mei_cldev_register_event_cb(struct m
 				unsigned long events_mask,
 				mei_cldev_event_cb_t event_cb, void *context)
 {
+	struct mei_device *bus = cldev->bus;
 	int ret;
 
 	if (cldev->event_cb)
@@ -299,15 +315,17 @@ int mei_cldev_register_event_cb(struct m
 	INIT_WORK(&cldev->event_work, mei_cl_bus_event_work);
 
 	if (cldev->events_mask & BIT(MEI_CL_EVENT_RX)) {
+		mutex_lock(&bus->device_lock);
 		ret = mei_cl_read_start(cldev->cl, 0, NULL);
+		mutex_unlock(&bus->device_lock);
 		if (ret && ret != -EBUSY)
 			return ret;
 	}
 
 	if (cldev->events_mask & BIT(MEI_CL_EVENT_NOTIF)) {
-		mutex_lock(&cldev->cl->dev->device_lock);
+		mutex_lock(&bus->device_lock);
 		ret = mei_cl_notify_request(cldev->cl, NULL, event_cb ? 1 : 0);
-		mutex_unlock(&cldev->cl->dev->device_lock);
+		mutex_unlock(&bus->device_lock);
 		if (ret)
 			return ret;
 	}
--- zfcpdump-kernel-4.4.orig/drivers/misc/mei/client.c
+++ zfcpdump-kernel-4.4/drivers/misc/mei/client.c
@@ -1735,6 +1735,10 @@ void mei_cl_complete(struct mei_cl *cl,
 			wake_up(&cl->wait);
 
 		break;
+	case MEI_FOP_DISCONNECT_RSP:
+		mei_io_cb_free(cb);
+		mei_cl_set_disconnected(cl);
+		break;
 	default:
 		BUG_ON(0);
 	}
--- zfcpdump-kernel-4.4.orig/drivers/misc/mei/hbm.c
+++ zfcpdump-kernel-4.4/drivers/misc/mei/hbm.c
@@ -873,8 +873,7 @@ static int mei_hbm_fw_disconnect_req(str
 		cb = mei_io_cb_init(cl, MEI_FOP_DISCONNECT_RSP, NULL);
 		if (!cb)
 			return -ENOMEM;
-		cl_dbg(dev, cl, "add disconnect response as first\n");
-		list_add(&cb->list, &dev->ctrl_wr_list.list);
+		list_add_tail(&cb->list, &dev->ctrl_wr_list.list);
 	}
 	return 0;
 }
--- zfcpdump-kernel-4.4.orig/drivers/misc/mei/interrupt.c
+++ zfcpdump-kernel-4.4/drivers/misc/mei/interrupt.c
@@ -76,7 +76,6 @@ static inline int mei_cl_hbm_equal(struc
  * @dev: mei device
  * @hdr: message header
  */
-static inline
 void mei_irq_discard_msg(struct mei_device *dev, struct mei_msg_hdr *hdr)
 {
 	/*
@@ -184,10 +183,7 @@ static int mei_cl_irq_disconnect_rsp(str
 		return -EMSGSIZE;
 
 	ret = mei_hbm_cl_disconnect_rsp(dev, cl);
-	mei_cl_set_disconnected(cl);
-	mei_io_cb_free(cb);
-	mei_me_cl_put(cl->me_cl);
-	cl->me_cl = NULL;
+	list_move_tail(&cb->list, &cmpl_list->list);
 
 	return ret;
 }
--- zfcpdump-kernel-4.4.orig/drivers/misc/mei/main.c
+++ zfcpdump-kernel-4.4/drivers/misc/mei/main.c
@@ -458,7 +458,11 @@ static int mei_ioctl_client_notify_reque
 {
 	struct mei_cl *cl = file->private_data;
 
-	return mei_cl_notify_request(cl, file, request);
+	if (request != MEI_HBM_NOTIFICATION_START &&
+	    request != MEI_HBM_NOTIFICATION_STOP)
+		return -EINVAL;
+
+	return mei_cl_notify_request(cl, file, (u8)request);
 }
 
 /**
@@ -657,7 +661,9 @@ out:
  * @file: pointer to file structure
  * @band: band bitmap
  *
- * Return: poll mask
+ * Return: negative on error,
+ *         0 if it did no changes,
+ *         and positive a process was added or deleted
  */
 static int mei_fasync(int fd, struct file *file, int band)
 {
@@ -665,7 +671,7 @@ static int mei_fasync(int fd, struct fil
 	struct mei_cl *cl = file->private_data;
 
 	if (!mei_cl_is_connected(cl))
-		return POLLERR;
+		return -ENODEV;
 
 	return fasync_helper(fd, file, band, &cl->ev_async);
 }
--- zfcpdump-kernel-4.4.orig/drivers/misc/mei/mei_dev.h
+++ zfcpdump-kernel-4.4/drivers/misc/mei/mei_dev.h
@@ -782,6 +782,8 @@ bool mei_hbuf_acquire(struct mei_device
 
 bool mei_write_is_idle(struct mei_device *dev);
 
+void mei_irq_discard_msg(struct mei_device *dev, struct mei_msg_hdr *hdr);
+
 #if IS_ENABLED(CONFIG_DEBUG_FS)
 int mei_dbgfs_register(struct mei_device *dev, const char *name);
 void mei_dbgfs_deregister(struct mei_device *dev);
--- zfcpdump-kernel-4.4.orig/drivers/misc/mei/pci-me.c
+++ zfcpdump-kernel-4.4/drivers/misc/mei/pci-me.c
@@ -40,6 +40,9 @@
 #include "hw-me-regs.h"
 #include "hw-me.h"
 
+static bool disable_msi;
+module_param(disable_msi, bool, 0);
+
 /* mei_pci_tbl - PCI Device ID Table */
 static const struct pci_device_id mei_me_pci_tbl[] = {
 	{MEI_PCI_DEVICE(MEI_DEV_ID_82946GZ, mei_me_legacy_cfg)},
@@ -183,7 +186,8 @@ static int mei_me_probe(struct pci_dev *
 		err = -ENOMEM;
 		goto free_device;
 	}
-	pci_enable_msi(pdev);
+	if (!disable_msi)
+		pci_enable_msi(pdev);
 
 	 /* request and enable interrupt */
 	irqflags = pci_dev_msi_enabled(pdev) ? IRQF_ONESHOT : IRQF_SHARED;
--- zfcpdump-kernel-4.4.orig/drivers/misc/mic/host/mic_virtio.c
+++ zfcpdump-kernel-4.4/drivers/misc/mic/host/mic_virtio.c
@@ -556,6 +556,12 @@ static int mic_copy_dp_entry(struct mic_
 		goto exit;
 	}
 
+	/* Ensure desc has not changed between the two reads */
+	if (memcmp(&dd, dd_config, sizeof(dd))) {
+		ret = -EINVAL;
+		goto exit;
+	}
+
 	vqconfig = mic_vq_config(dd_config);
 	for (i = 0; i < dd.num_vq; i++) {
 		if (le16_to_cpu(vqconfig[i].num) > MIC_MAX_VRING_ENTRIES) {
--- zfcpdump-kernel-4.4.orig/drivers/misc/mic/scif/scif_rma.c
+++ zfcpdump-kernel-4.4/drivers/misc/mic/scif/scif_rma.c
@@ -1511,7 +1511,7 @@ off_t scif_register_pinned_pages(scif_ep
 	if ((map_flags & SCIF_MAP_FIXED) &&
 	    ((ALIGN(offset, PAGE_SIZE) != offset) ||
 	    (offset < 0) ||
-	    (offset + (off_t)len < offset)))
+	    (len > LONG_MAX - offset)))
 		return -EINVAL;
 
 	might_sleep();
@@ -1614,7 +1614,7 @@ off_t scif_register(scif_epd_t epd, void
 	if ((map_flags & SCIF_MAP_FIXED) &&
 	    ((ALIGN(offset, PAGE_SIZE) != offset) ||
 	    (offset < 0) ||
-	    (offset + (off_t)len < offset)))
+	    (len > LONG_MAX - offset)))
 		return -EINVAL;
 
 	/* Unsupported protection requested */
@@ -1732,7 +1732,8 @@ scif_unregister(scif_epd_t epd, off_t of
 
 	/* Offset is not page aligned or offset+len wraps around */
 	if ((ALIGN(offset, PAGE_SIZE) != offset) ||
-	    (offset + (off_t)len < offset))
+	    (offset < 0) ||
+	    (len > LONG_MAX - offset))
 		return -EINVAL;
 
 	err = scif_verify_epd(ep);
--- zfcpdump-kernel-4.4.orig/drivers/mmc/card/block.c
+++ zfcpdump-kernel-4.4/drivers/mmc/card/block.c
@@ -596,6 +596,14 @@ static int mmc_blk_ioctl_cmd(struct bloc
 	struct mmc_card *card;
 	int err = 0, ioc_err = 0;
 
+	/*
+	 * The caller must have CAP_SYS_RAWIO, and must be calling this on the
+	 * whole block device, not on a partition.  This prevents overspray
+	 * between sibling partitions.
+	 */
+	if ((!capable(CAP_SYS_RAWIO)) || (bdev != bdev->bd_contains))
+		return -EPERM;
+
 	idata = mmc_blk_ioctl_copy_from_user(ic_ptr);
 	if (IS_ERR(idata))
 		return PTR_ERR(idata);
@@ -638,6 +646,14 @@ static int mmc_blk_ioctl_multi_cmd(struc
 	int i, err = 0, ioc_err = 0;
 	__u64 num_of_cmds;
 
+	/*
+	 * The caller must have CAP_SYS_RAWIO, and must be calling this on the
+	 * whole block device, not on a partition.  This prevents overspray
+	 * between sibling partitions.
+	 */
+	if ((!capable(CAP_SYS_RAWIO)) || (bdev != bdev->bd_contains))
+		return -EPERM;
+
 	if (copy_from_user(&num_of_cmds, &user->num_of_cmds,
 			   sizeof(num_of_cmds)))
 		return -EFAULT;
@@ -693,14 +709,6 @@ cmd_err:
 static int mmc_blk_ioctl(struct block_device *bdev, fmode_t mode,
 	unsigned int cmd, unsigned long arg)
 {
-	/*
-	 * The caller must have CAP_SYS_RAWIO, and must be calling this on the
-	 * whole block device, not on a partition.  This prevents overspray
-	 * between sibling partitions.
-	 */
-	if ((!capable(CAP_SYS_RAWIO)) || (bdev != bdev->bd_contains))
-		return -EPERM;
-
 	switch (cmd) {
 	case MMC_IOC_CMD:
 		return mmc_blk_ioctl_cmd(bdev,
@@ -1759,8 +1767,8 @@ static void mmc_blk_packed_hdr_wrq_prep(
 
 	packed_cmd_hdr = packed->cmd_hdr;
 	memset(packed_cmd_hdr, 0, sizeof(packed->cmd_hdr));
-	packed_cmd_hdr[0] = (packed->nr_entries << 16) |
-		(PACKED_CMD_WR << 8) | PACKED_CMD_VER;
+	packed_cmd_hdr[0] = cpu_to_le32((packed->nr_entries << 16) |
+		(PACKED_CMD_WR << 8) | PACKED_CMD_VER);
 	hdr_blocks = mmc_large_sector(card) ? 8 : 1;
 
 	/*
@@ -1774,14 +1782,14 @@ static void mmc_blk_packed_hdr_wrq_prep(
 			((brq->data.blocks * brq->data.blksz) >=
 			 card->ext_csd.data_tag_unit_size);
 		/* Argument of CMD23 */
-		packed_cmd_hdr[(i * 2)] =
+		packed_cmd_hdr[(i * 2)] = cpu_to_le32(
 			(do_rel_wr ? MMC_CMD23_ARG_REL_WR : 0) |
 			(do_data_tag ? MMC_CMD23_ARG_TAG_REQ : 0) |
-			blk_rq_sectors(prq);
+			blk_rq_sectors(prq));
 		/* Argument of CMD18 or CMD25 */
-		packed_cmd_hdr[((i * 2)) + 1] =
+		packed_cmd_hdr[((i * 2)) + 1] = cpu_to_le32(
 			mmc_card_blockaddr(card) ?
-			blk_rq_pos(prq) : blk_rq_pos(prq) << 9;
+			blk_rq_pos(prq) : blk_rq_pos(prq) << 9);
 		packed->blocks += blk_rq_sectors(prq);
 		i++;
 	}
@@ -2506,11 +2514,12 @@ static const struct mmc_fixup blk_fixups
 		  MMC_QUIRK_BLK_NO_CMD23),
 
 	/*
-	 * Some Micron MMC cards needs longer data read timeout than
-	 * indicated in CSD.
+	 * Some MMC cards need longer data read timeout than indicated in CSD.
 	 */
 	MMC_FIXUP(CID_NAME_ANY, CID_MANFID_MICRON, 0x200, add_quirk_mmc,
 		  MMC_QUIRK_LONG_READ_TIME),
+	MMC_FIXUP("008GE0", CID_MANFID_TOSHIBA, CID_OEMID_ANY, add_quirk_mmc,
+		  MMC_QUIRK_LONG_READ_TIME),
 
 	/*
 	 * On these Samsung MoviNAND parts, performing secure erase or
--- zfcpdump-kernel-4.4.orig/drivers/mmc/core/bus.c
+++ zfcpdump-kernel-4.4/drivers/mmc/core/bus.c
@@ -349,6 +349,8 @@ int mmc_add_card(struct mmc_card *card)
 
 	card->dev.of_node = mmc_of_find_child_device(card->host, 0);
 
+	device_enable_async_suspend(&card->dev);
+
 	ret = device_add(&card->dev);
 	if (ret)
 		return ret;
--- zfcpdump-kernel-4.4.orig/drivers/mmc/core/core.c
+++ zfcpdump-kernel-4.4/drivers/mmc/core/core.c
@@ -874,11 +874,11 @@ void mmc_set_data_timeout(struct mmc_dat
 	/*
 	 * Some cards require longer data read timeout than indicated in CSD.
 	 * Address this by setting the read timeout to a "reasonably high"
-	 * value. For the cards tested, 300ms has proven enough. If necessary,
+	 * value. For the cards tested, 600ms has proven enough. If necessary,
 	 * this value can be increased if other problematic cards require this.
 	 */
 	if (mmc_card_long_read_time(card) && data->flags & MMC_DATA_READ) {
-		data->timeout_ns = 300000000;
+		data->timeout_ns = 600000000;
 		data->timeout_clks = 0;
 	}
 
--- zfcpdump-kernel-4.4.orig/drivers/mmc/core/mmc.c
+++ zfcpdump-kernel-4.4/drivers/mmc/core/mmc.c
@@ -333,6 +333,9 @@ static void mmc_manage_gp_partitions(str
 	}
 }
 
+/* Minimum partition switch timeout in milliseconds */
+#define MMC_MIN_PART_SWITCH_TIME	300
+
 /*
  * Decode extended CSD.
  */
@@ -397,6 +400,10 @@ static int mmc_decode_ext_csd(struct mmc
 
 		/* EXT_CSD value is in units of 10ms, but we store in ms */
 		card->ext_csd.part_time = 10 * ext_csd[EXT_CSD_PART_SWITCH_TIME];
+		/* Some eMMC set the value too low so set a minimum */
+		if (card->ext_csd.part_time &&
+		    card->ext_csd.part_time < MMC_MIN_PART_SWITCH_TIME)
+			card->ext_csd.part_time = MMC_MIN_PART_SWITCH_TIME;
 
 		/* Sleep / awake timeout in 100ns units */
 		if (sa_shift > 0 && sa_shift <= 0x17)
@@ -1076,8 +1083,7 @@ static int mmc_select_hs400(struct mmc_c
 	mmc_set_clock(host, max_dtr);
 
 	/* Switch card to HS mode */
-	val = EXT_CSD_TIMING_HS |
-	      card->drive_strength << EXT_CSD_DRV_STR_SHIFT;
+	val = EXT_CSD_TIMING_HS;
 	err = __mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
 			   EXT_CSD_HS_TIMING, val,
 			   card->ext_csd.generic_cmd6_time,
@@ -1160,8 +1166,7 @@ int mmc_hs400_to_hs200(struct mmc_card *
 	mmc_set_clock(host, max_dtr);
 
 	/* Switch HS400 to HS DDR */
-	val = EXT_CSD_TIMING_HS |
-	      card->drive_strength << EXT_CSD_DRV_STR_SHIFT;
+	val = EXT_CSD_TIMING_HS;
 	err = __mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_HS_TIMING,
 			   val, card->ext_csd.generic_cmd6_time,
 			   true, send_status, true);
@@ -1948,8 +1953,8 @@ static int mmc_runtime_resume(struct mmc
 		return 0;
 
 	err = _mmc_resume(host);
-	if (err)
-		pr_err("%s: error %d doing aggressive resume\n",
+	if (err && err != -ENOMEDIUM)
+		pr_err("%s: error %d doing runtime resume\n",
 			mmc_hostname(host), err);
 
 	return 0;
--- zfcpdump-kernel-4.4.orig/drivers/mmc/core/sd.c
+++ zfcpdump-kernel-4.4/drivers/mmc/core/sd.c
@@ -626,9 +626,9 @@ static int mmc_sd_init_uhs_card(struct m
 	 * SDR104 mode SD-cards. Note that tuning is mandatory for SDR104.
 	 */
 	if (!mmc_host_is_spi(card->host) &&
-		(card->sd_bus_speed == UHS_SDR50_BUS_SPEED ||
-		 card->sd_bus_speed == UHS_DDR50_BUS_SPEED ||
-		 card->sd_bus_speed == UHS_SDR104_BUS_SPEED)) {
+		(card->host->ios.timing == MMC_TIMING_UHS_SDR50 ||
+		 card->host->ios.timing == MMC_TIMING_UHS_DDR50 ||
+		 card->host->ios.timing == MMC_TIMING_UHS_SDR104)) {
 		err = mmc_execute_tuning(card);
 
 		/*
@@ -638,7 +638,7 @@ static int mmc_sd_init_uhs_card(struct m
 		 * difference between v3.00 and 3.01 spec means that CMD19
 		 * tuning is also available for DDR50 mode.
 		 */
-		if (err && card->sd_bus_speed == UHS_DDR50_BUS_SPEED) {
+		if (err && card->host->ios.timing == MMC_TIMING_UHS_DDR50) {
 			pr_warn("%s: ddr50 tuning failed\n",
 				mmc_hostname(card->host));
 			err = 0;
@@ -1169,8 +1169,8 @@ static int mmc_sd_runtime_resume(struct
 		return 0;
 
 	err = _mmc_sd_resume(host);
-	if (err)
-		pr_err("%s: error %d doing aggressive resume\n",
+	if (err && err != -ENOMEDIUM)
+		pr_err("%s: error %d doing runtime resume\n",
 			mmc_hostname(host), err);
 
 	return 0;
--- zfcpdump-kernel-4.4.orig/drivers/mmc/core/sdio.c
+++ zfcpdump-kernel-4.4/drivers/mmc/core/sdio.c
@@ -535,8 +535,8 @@ static int mmc_sdio_init_uhs_card(struct
 	 * SDR104 mode SD-cards. Note that tuning is mandatory for SDR104.
 	 */
 	if (!mmc_host_is_spi(card->host) &&
-	    ((card->sw_caps.sd3_bus_mode & SD_MODE_UHS_SDR50) ||
-	     (card->sw_caps.sd3_bus_mode & SD_MODE_UHS_SDR104)))
+	    ((card->host->ios.timing == MMC_TIMING_UHS_SDR50) ||
+	      (card->host->ios.timing == MMC_TIMING_UHS_SDR104)))
 		err = mmc_execute_tuning(card);
 out:
 	return err;
@@ -630,7 +630,7 @@ try_again:
 	 */
 	if (!powered_resume && (rocr & ocr & R4_18V_PRESENT)) {
 		err = mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_180,
-					ocr);
+					ocr_card);
 		if (err == -EAGAIN) {
 			sdio_reset(host);
 			mmc_go_idle(host);
--- zfcpdump-kernel-4.4.orig/drivers/mmc/core/sdio_bus.c
+++ zfcpdump-kernel-4.4/drivers/mmc/core/sdio_bus.c
@@ -322,6 +322,7 @@ int sdio_add_func(struct sdio_func *func
 
 	sdio_set_of_node(func);
 	sdio_acpi_set_handle(func);
+	device_enable_async_suspend(&func->dev);
 	ret = device_add(&func->dev);
 	if (ret == 0)
 		sdio_func_set_present(func);
--- zfcpdump-kernel-4.4.orig/drivers/mmc/host/Kconfig
+++ zfcpdump-kernel-4.4/drivers/mmc/host/Kconfig
@@ -97,6 +97,7 @@ config MMC_RICOH_MMC
 config MMC_SDHCI_ACPI
 	tristate "SDHCI support for ACPI enumerated SDHCI controllers"
 	depends on MMC_SDHCI && ACPI
+	select IOSF_MBI if X86
 	help
 	  This selects support for ACPI enumerated SDHCI controllers,
 	  identified by ACPI Compatibility ID PNP0D40 or specific
--- zfcpdump-kernel-4.4.orig/drivers/mmc/host/dw_mmc-pltfm.c
+++ zfcpdump-kernel-4.4/drivers/mmc/host/dw_mmc-pltfm.c
@@ -60,7 +60,7 @@ int dw_mci_pltfm_register(struct platfor
 
 	regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	/* Get registers' physical base address */
-	host->phy_regs = (void *)(regs->start);
+	host->phy_regs = regs->start;
 	host->regs = devm_ioremap_resource(&pdev->dev, regs);
 	if (IS_ERR(host->regs))
 		return PTR_ERR(host->regs);
--- zfcpdump-kernel-4.4.orig/drivers/mmc/host/dw_mmc.c
+++ zfcpdump-kernel-4.4/drivers/mmc/host/dw_mmc.c
@@ -699,7 +699,7 @@ static int dw_mci_edmac_start_dma(struct
 	int ret = 0;
 
 	/* Set external dma config: burst size, burst width */
-	cfg.dst_addr = (dma_addr_t)(host->phy_regs + fifo_offset);
+	cfg.dst_addr = host->phy_regs + fifo_offset;
 	cfg.src_addr = cfg.dst_addr;
 	cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
 	cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
--- zfcpdump-kernel-4.4.orig/drivers/mmc/host/mmc_spi.c
+++ zfcpdump-kernel-4.4/drivers/mmc/host/mmc_spi.c
@@ -1436,6 +1436,12 @@ static int mmc_spi_probe(struct spi_devi
 					     host->pdata->cd_debounce);
 		if (status != 0)
 			goto fail_add_host;
+
+		/* The platform has a CD GPIO signal that may support
+		 * interrupts, so let mmc_gpiod_request_cd_irq() decide
+		 * if polling is needed or not.
+		 */
+		mmc->caps &= ~MMC_CAP_NEEDS_POLL;
 		mmc_gpiod_request_cd_irq(mmc);
 	}
 
--- zfcpdump-kernel-4.4.orig/drivers/mmc/host/mmci.c
+++ zfcpdump-kernel-4.4/drivers/mmc/host/mmci.c
@@ -1886,7 +1886,7 @@ static struct amba_id mmci_ids[] = {
 	{
 		.id     = 0x00280180,
 		.mask   = 0x00ffffff,
-		.data	= &variant_u300,
+		.data	= &variant_nomadik,
 	},
 	{
 		.id     = 0x00480180,
--- zfcpdump-kernel-4.4.orig/drivers/mmc/host/pxamci.c
+++ zfcpdump-kernel-4.4/drivers/mmc/host/pxamci.c
@@ -798,14 +798,16 @@ static int pxamci_probe(struct platform_
 		gpio_direction_output(gpio_power,
 				      host->pdata->gpio_power_invert);
 	}
-	if (gpio_is_valid(gpio_ro))
+	if (gpio_is_valid(gpio_ro)) {
 		ret = mmc_gpio_request_ro(mmc, gpio_ro);
-	if (ret) {
-		dev_err(&pdev->dev, "Failed requesting gpio_ro %d\n", gpio_ro);
-		goto out;
-	} else {
-		mmc->caps |= host->pdata->gpio_card_ro_invert ?
-			0 : MMC_CAP2_RO_ACTIVE_HIGH;
+		if (ret) {
+			dev_err(&pdev->dev, "Failed requesting gpio_ro %d\n",
+				gpio_ro);
+			goto out;
+		} else {
+			mmc->caps2 |= host->pdata->gpio_card_ro_invert ?
+				0 : MMC_CAP2_RO_ACTIVE_HIGH;
+		}
 	}
 
 	if (gpio_is_valid(gpio_cd))
--- zfcpdump-kernel-4.4.orig/drivers/mmc/host/sdhci-acpi.c
+++ zfcpdump-kernel-4.4/drivers/mmc/host/sdhci-acpi.c
@@ -41,6 +41,11 @@
 #include <linux/mmc/pm.h>
 #include <linux/mmc/slot-gpio.h>
 
+#ifdef CONFIG_X86
+#include <asm/cpu_device_id.h>
+#include <asm/iosf_mbi.h>
+#endif
+
 #include "sdhci.h"
 
 enum {
@@ -146,6 +151,102 @@ static const struct sdhci_acpi_chip sdhc
 	.ops = &sdhci_acpi_ops_int,
 };
 
+#ifdef CONFIG_X86
+
+static bool sdhci_acpi_byt(void)
+{
+	static const struct x86_cpu_id byt[] = {
+		{ X86_VENDOR_INTEL, 6, 0x37 },
+		{}
+	};
+
+	return x86_match_cpu(byt);
+}
+
+#define BYT_IOSF_SCCEP			0x63
+#define BYT_IOSF_OCP_NETCTRL0		0x1078
+#define BYT_IOSF_OCP_TIMEOUT_BASE	GENMASK(10, 8)
+
+static void sdhci_acpi_byt_setting(struct device *dev)
+{
+	u32 val = 0;
+
+	if (!sdhci_acpi_byt())
+		return;
+
+	if (iosf_mbi_read(BYT_IOSF_SCCEP, 0x06, BYT_IOSF_OCP_NETCTRL0,
+			  &val)) {
+		dev_err(dev, "%s read error\n", __func__);
+		return;
+	}
+
+	if (!(val & BYT_IOSF_OCP_TIMEOUT_BASE))
+		return;
+
+	val &= ~BYT_IOSF_OCP_TIMEOUT_BASE;
+
+	if (iosf_mbi_write(BYT_IOSF_SCCEP, 0x07, BYT_IOSF_OCP_NETCTRL0,
+			   val)) {
+		dev_err(dev, "%s write error\n", __func__);
+		return;
+	}
+
+	dev_dbg(dev, "%s completed\n", __func__);
+}
+
+static bool sdhci_acpi_byt_defer(struct device *dev)
+{
+	if (!sdhci_acpi_byt())
+		return false;
+
+	if (!iosf_mbi_available())
+		return true;
+
+	sdhci_acpi_byt_setting(dev);
+
+	return false;
+}
+
+#else
+
+static inline void sdhci_acpi_byt_setting(struct device *dev)
+{
+}
+
+static inline bool sdhci_acpi_byt_defer(struct device *dev)
+{
+	return false;
+}
+
+#endif
+
+static int bxt_get_cd(struct mmc_host *mmc)
+{
+	int gpio_cd = mmc_gpio_get_cd(mmc);
+	struct sdhci_host *host = mmc_priv(mmc);
+	unsigned long flags;
+	int ret = 0;
+
+	if (!gpio_cd)
+		return 0;
+
+	pm_runtime_get_sync(mmc->parent);
+
+	spin_lock_irqsave(&host->lock, flags);
+
+	if (host->flags & SDHCI_DEVICE_DEAD)
+		goto out;
+
+	ret = !!(sdhci_readl(host, SDHCI_PRESENT_STATE) & SDHCI_CARD_PRESENT);
+out:
+	spin_unlock_irqrestore(&host->lock, flags);
+
+	pm_runtime_mark_last_busy(mmc->parent);
+	pm_runtime_put_autosuspend(mmc->parent);
+
+	return ret;
+}
+
 static int sdhci_acpi_emmc_probe_slot(struct platform_device *pdev,
 				      const char *hid, const char *uid)
 {
@@ -196,6 +297,9 @@ static int sdhci_acpi_sd_probe_slot(stru
 
 	/* Platform specific code during sd probe slot goes here */
 
+	if (hid && !strcmp(hid, "80865ACA"))
+		host->mmc_host_ops.get_cd = bxt_get_cd;
+
 	return 0;
 }
 
@@ -203,7 +307,7 @@ static const struct sdhci_acpi_slot sdhc
 	.chip    = &sdhci_acpi_chip_int,
 	.caps    = MMC_CAP_8_BIT_DATA | MMC_CAP_NONREMOVABLE |
 		   MMC_CAP_HW_RESET | MMC_CAP_1_8V_DDR |
-		   MMC_CAP_BUS_WIDTH_TEST | MMC_CAP_WAIT_WHILE_BUSY,
+		   MMC_CAP_WAIT_WHILE_BUSY,
 	.caps2   = MMC_CAP2_HC_ERASE_SZ,
 	.flags   = SDHCI_ACPI_RUNTIME_PM,
 	.quirks  = SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC,
@@ -218,7 +322,7 @@ static const struct sdhci_acpi_slot sdhc
 		   SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC,
 	.quirks2 = SDHCI_QUIRK2_HOST_OFF_CARD_ON,
 	.caps    = MMC_CAP_NONREMOVABLE | MMC_CAP_POWER_OFF_CARD |
-		   MMC_CAP_BUS_WIDTH_TEST | MMC_CAP_WAIT_WHILE_BUSY,
+		   MMC_CAP_WAIT_WHILE_BUSY,
 	.flags   = SDHCI_ACPI_RUNTIME_PM,
 	.pm_caps = MMC_PM_KEEP_POWER,
 	.probe_slot	= sdhci_acpi_sdio_probe_slot,
@@ -230,7 +334,7 @@ static const struct sdhci_acpi_slot sdhc
 	.quirks  = SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC,
 	.quirks2 = SDHCI_QUIRK2_CARD_ON_NEEDS_BUS_ON |
 		   SDHCI_QUIRK2_STOP_WITH_TC,
-	.caps    = MMC_CAP_BUS_WIDTH_TEST | MMC_CAP_WAIT_WHILE_BUSY,
+	.caps    = MMC_CAP_WAIT_WHILE_BUSY,
 	.probe_slot	= sdhci_acpi_sd_probe_slot,
 };
 
@@ -307,6 +411,9 @@ static int sdhci_acpi_probe(struct platf
 	if (acpi_bus_get_status(device) || !device->status.present)
 		return -ENODEV;
 
+	if (sdhci_acpi_byt_defer(dev))
+		return -EPROBE_DEFER;
+
 	hid = acpi_device_hid(device);
 	uid = device->pnp.unique_id;
 
@@ -430,6 +537,8 @@ static int sdhci_acpi_resume(struct devi
 {
 	struct sdhci_acpi_host *c = dev_get_drvdata(dev);
 
+	sdhci_acpi_byt_setting(&c->pdev->dev);
+
 	return sdhci_resume_host(c->host);
 }
 
@@ -453,6 +562,8 @@ static int sdhci_acpi_runtime_resume(str
 {
 	struct sdhci_acpi_host *c = dev_get_drvdata(dev);
 
+	sdhci_acpi_byt_setting(&c->pdev->dev);
+
 	return sdhci_runtime_resume_host(c->host);
 }
 
--- zfcpdump-kernel-4.4.orig/drivers/mmc/host/sdhci-pci-core.c
+++ zfcpdump-kernel-4.4/drivers/mmc/host/sdhci-pci-core.c
@@ -277,7 +277,7 @@ static int spt_select_drive_strength(str
 	if (sdhci_pci_spt_drive_strength > 0)
 		drive_strength = sdhci_pci_spt_drive_strength & 0xf;
 	else
-		drive_strength = 1; /* 33-ohm */
+		drive_strength = 0; /* Default 50-ohm */
 
 	if ((mmc_driver_type_mask(drive_strength) & card_drv) == 0)
 		drive_strength = 0; /* Default 50-ohm */
@@ -330,11 +330,37 @@ static void spt_read_drive_strength(stru
 	sdhci_pci_spt_drive_strength = 0x10 | ((val >> 12) & 0xf);
 }
 
+static int bxt_get_cd(struct mmc_host *mmc)
+{
+	int gpio_cd = mmc_gpio_get_cd(mmc);
+	struct sdhci_host *host = mmc_priv(mmc);
+	unsigned long flags;
+	int ret = 0;
+
+	if (!gpio_cd)
+		return 0;
+
+	pm_runtime_get_sync(mmc->parent);
+
+	spin_lock_irqsave(&host->lock, flags);
+
+	if (host->flags & SDHCI_DEVICE_DEAD)
+		goto out;
+
+	ret = !!(sdhci_readl(host, SDHCI_PRESENT_STATE) & SDHCI_CARD_PRESENT);
+out:
+	spin_unlock_irqrestore(&host->lock, flags);
+
+	pm_runtime_mark_last_busy(mmc->parent);
+	pm_runtime_put_autosuspend(mmc->parent);
+
+	return ret;
+}
+
 static int byt_emmc_probe_slot(struct sdhci_pci_slot *slot)
 {
 	slot->host->mmc->caps |= MMC_CAP_8_BIT_DATA | MMC_CAP_NONREMOVABLE |
 				 MMC_CAP_HW_RESET | MMC_CAP_1_8V_DDR |
-				 MMC_CAP_BUS_WIDTH_TEST |
 				 MMC_CAP_WAIT_WHILE_BUSY;
 	slot->host->mmc->caps2 |= MMC_CAP2_HC_ERASE_SZ;
 	slot->hw_reset = sdhci_pci_int_hw_reset;
@@ -350,18 +376,21 @@ static int byt_emmc_probe_slot(struct sd
 static int byt_sdio_probe_slot(struct sdhci_pci_slot *slot)
 {
 	slot->host->mmc->caps |= MMC_CAP_POWER_OFF_CARD | MMC_CAP_NONREMOVABLE |
-				 MMC_CAP_BUS_WIDTH_TEST |
 				 MMC_CAP_WAIT_WHILE_BUSY;
 	return 0;
 }
 
 static int byt_sd_probe_slot(struct sdhci_pci_slot *slot)
 {
-	slot->host->mmc->caps |= MMC_CAP_BUS_WIDTH_TEST |
-				 MMC_CAP_WAIT_WHILE_BUSY;
+	slot->host->mmc->caps |= MMC_CAP_WAIT_WHILE_BUSY;
 	slot->cd_con_id = NULL;
 	slot->cd_idx = 0;
 	slot->cd_override_level = true;
+	if (slot->chip->pdev->device == PCI_DEVICE_ID_INTEL_BXT_SD ||
+	    slot->chip->pdev->device == PCI_DEVICE_ID_INTEL_BXTM_SD ||
+	    slot->chip->pdev->device == PCI_DEVICE_ID_INTEL_APL_SD)
+		slot->host->mmc_host_ops.get_cd = bxt_get_cd;
+
 	return 0;
 }
 
@@ -1138,6 +1167,30 @@ static const struct pci_device_id pci_id
 		.subvendor	= PCI_ANY_ID,
 		.subdevice	= PCI_ANY_ID,
 		.driver_data	= (kernel_ulong_t)&sdhci_intel_byt_sd,
+	},
+
+	{
+		.vendor		= PCI_VENDOR_ID_INTEL,
+		.device		= PCI_DEVICE_ID_INTEL_BXTM_EMMC,
+		.subvendor	= PCI_ANY_ID,
+		.subdevice	= PCI_ANY_ID,
+		.driver_data	= (kernel_ulong_t)&sdhci_intel_byt_emmc,
+	},
+
+	{
+		.vendor		= PCI_VENDOR_ID_INTEL,
+		.device		= PCI_DEVICE_ID_INTEL_BXTM_SDIO,
+		.subvendor	= PCI_ANY_ID,
+		.subdevice	= PCI_ANY_ID,
+		.driver_data	= (kernel_ulong_t)&sdhci_intel_byt_sdio,
+	},
+
+	{
+		.vendor		= PCI_VENDOR_ID_INTEL,
+		.device		= PCI_DEVICE_ID_INTEL_BXTM_SD,
+		.subvendor	= PCI_ANY_ID,
+		.subdevice	= PCI_ANY_ID,
+		.driver_data	= (kernel_ulong_t)&sdhci_intel_byt_sd,
 	},
 
 	{
--- zfcpdump-kernel-4.4.orig/drivers/mmc/host/sdhci-pci.h
+++ zfcpdump-kernel-4.4/drivers/mmc/host/sdhci-pci.h
@@ -28,6 +28,9 @@
 #define PCI_DEVICE_ID_INTEL_BXT_SD	0x0aca
 #define PCI_DEVICE_ID_INTEL_BXT_EMMC	0x0acc
 #define PCI_DEVICE_ID_INTEL_BXT_SDIO	0x0ad0
+#define PCI_DEVICE_ID_INTEL_BXTM_SD	0x1aca
+#define PCI_DEVICE_ID_INTEL_BXTM_EMMC	0x1acc
+#define PCI_DEVICE_ID_INTEL_BXTM_SDIO	0x1ad0
 #define PCI_DEVICE_ID_INTEL_APL_SD	0x5aca
 #define PCI_DEVICE_ID_INTEL_APL_EMMC	0x5acc
 #define PCI_DEVICE_ID_INTEL_APL_SDIO	0x5ad0
--- zfcpdump-kernel-4.4.orig/drivers/mmc/host/sdhci.c
+++ zfcpdump-kernel-4.4/drivers/mmc/host/sdhci.c
@@ -492,7 +492,7 @@ static int sdhci_adma_table_pre(struct s
 		host->align_buffer, host->align_buffer_sz, direction);
 	if (dma_mapping_error(mmc_dev(host->mmc), host->align_addr))
 		goto fail;
-	BUG_ON(host->align_addr & host->align_mask);
+	BUG_ON(host->align_addr & SDHCI_ADMA2_MASK);
 
 	host->sg_count = sdhci_pre_dma_transfer(host, data);
 	if (host->sg_count < 0)
@@ -514,8 +514,8 @@ static int sdhci_adma_table_pre(struct s
 		 * the (up to three) bytes that screw up the
 		 * alignment.
 		 */
-		offset = (host->align_sz - (addr & host->align_mask)) &
-			 host->align_mask;
+		offset = (SDHCI_ADMA2_ALIGN - (addr & SDHCI_ADMA2_MASK)) &
+			 SDHCI_ADMA2_MASK;
 		if (offset) {
 			if (data->flags & MMC_DATA_WRITE) {
 				buffer = sdhci_kmap_atomic(sg, &flags);
@@ -529,8 +529,8 @@ static int sdhci_adma_table_pre(struct s
 
 			BUG_ON(offset > 65536);
 
-			align += host->align_sz;
-			align_addr += host->align_sz;
+			align += SDHCI_ADMA2_ALIGN;
+			align_addr += SDHCI_ADMA2_ALIGN;
 
 			desc += host->desc_sz;
 
@@ -540,9 +540,12 @@ static int sdhci_adma_table_pre(struct s
 
 		BUG_ON(len > 65536);
 
-		/* tran, valid */
-		sdhci_adma_write_desc(host, desc, addr, len, ADMA2_TRAN_VALID);
-		desc += host->desc_sz;
+		if (len) {
+			/* tran, valid */
+			sdhci_adma_write_desc(host, desc, addr, len,
+					      ADMA2_TRAN_VALID);
+			desc += host->desc_sz;
+		}
 
 		/*
 		 * If this triggers then we have a calculation bug
@@ -608,7 +611,7 @@ static void sdhci_adma_table_post(struct
 	/* Do a quick scan of the SG list for any unaligned mappings */
 	has_unaligned = false;
 	for_each_sg(data->sg, sg, host->sg_count, i)
-		if (sg_dma_address(sg) & host->align_mask) {
+		if (sg_dma_address(sg) & SDHCI_ADMA2_MASK) {
 			has_unaligned = true;
 			break;
 		}
@@ -620,15 +623,15 @@ static void sdhci_adma_table_post(struct
 		align = host->align_buffer;
 
 		for_each_sg(data->sg, sg, host->sg_count, i) {
-			if (sg_dma_address(sg) & host->align_mask) {
-				size = host->align_sz -
-				       (sg_dma_address(sg) & host->align_mask);
+			if (sg_dma_address(sg) & SDHCI_ADMA2_MASK) {
+				size = SDHCI_ADMA2_ALIGN -
+				       (sg_dma_address(sg) & SDHCI_ADMA2_MASK);
 
 				buffer = sdhci_kmap_atomic(sg, &flags);
 				memcpy(buffer, align, size);
 				sdhci_kunmap_atomic(buffer, &flags);
 
-				align += host->align_sz;
+				align += SDHCI_ADMA2_ALIGN;
 			}
 		}
 	}
@@ -663,9 +666,20 @@ static u8 sdhci_calc_timeout(struct sdhc
 	if (!data)
 		target_timeout = cmd->busy_timeout * 1000;
 	else {
-		target_timeout = data->timeout_ns / 1000;
-		if (host->clock)
-			target_timeout += data->timeout_clks / host->clock;
+		target_timeout = DIV_ROUND_UP(data->timeout_ns, 1000);
+		if (host->clock && data->timeout_clks) {
+			unsigned long long val;
+
+			/*
+			 * data->timeout_clks is in units of clock cycles.
+			 * host->clock is in Hz.  target_timeout is in us.
+			 * Hence, us = 1000000 * cycles / Hz.  Round up.
+			 */
+			val = 1000000 * data->timeout_clks;
+			if (do_div(val, host->clock))
+				target_timeout++;
+			target_timeout += val;
+		}
 	}
 
 	/*
@@ -1301,7 +1315,9 @@ static void sdhci_set_power(struct sdhci
 			pwr = SDHCI_POWER_330;
 			break;
 		default:
-			BUG();
+			WARN(1, "%s: Invalid vdd %#x\n",
+			     mmc_hostname(host->mmc), vdd);
+			break;
 		}
 	}
 
@@ -1364,7 +1380,7 @@ static void sdhci_request(struct mmc_hos
 	sdhci_runtime_pm_get(host);
 
 	/* Firstly check card presence */
-	present = sdhci_do_get_cd(host);
+	present = mmc->ops->get_cd(mmc);
 
 	spin_lock_irqsave(&host->lock, flags);
 
@@ -2760,7 +2776,7 @@ static int sdhci_runtime_pm_put(struct s
 
 static void sdhci_runtime_pm_bus_on(struct sdhci_host *host)
 {
-	if (host->runtime_suspended || host->bus_on)
+	if (host->bus_on)
 		return;
 	host->bus_on = true;
 	pm_runtime_get_noresume(host->mmc->parent);
@@ -2768,7 +2784,7 @@ static void sdhci_runtime_pm_bus_on(stru
 
 static void sdhci_runtime_pm_bus_off(struct sdhci_host *host)
 {
-	if (host->runtime_suspended || !host->bus_on)
+	if (!host->bus_on)
 		return;
 	host->bus_on = false;
 	pm_runtime_put_noidle(host->mmc->parent);
@@ -2861,6 +2877,8 @@ struct sdhci_host *sdhci_alloc_host(stru
 
 	host = mmc_priv(mmc);
 	host->mmc = mmc;
+	host->mmc_host_ops = sdhci_ops;
+	mmc->ops = &host->mmc_host_ops;
 
 	return host;
 }
@@ -2967,24 +2985,17 @@ int sdhci_add_host(struct sdhci_host *ho
 		if (host->flags & SDHCI_USE_64_BIT_DMA) {
 			host->adma_table_sz = (SDHCI_MAX_SEGS * 2 + 1) *
 					      SDHCI_ADMA2_64_DESC_SZ;
-			host->align_buffer_sz = SDHCI_MAX_SEGS *
-						SDHCI_ADMA2_64_ALIGN;
 			host->desc_sz = SDHCI_ADMA2_64_DESC_SZ;
-			host->align_sz = SDHCI_ADMA2_64_ALIGN;
-			host->align_mask = SDHCI_ADMA2_64_ALIGN - 1;
 		} else {
 			host->adma_table_sz = (SDHCI_MAX_SEGS * 2 + 1) *
 					      SDHCI_ADMA2_32_DESC_SZ;
-			host->align_buffer_sz = SDHCI_MAX_SEGS *
-						SDHCI_ADMA2_32_ALIGN;
 			host->desc_sz = SDHCI_ADMA2_32_DESC_SZ;
-			host->align_sz = SDHCI_ADMA2_32_ALIGN;
-			host->align_mask = SDHCI_ADMA2_32_ALIGN - 1;
 		}
 		host->adma_table = dma_alloc_coherent(mmc_dev(mmc),
 						      host->adma_table_sz,
 						      &host->adma_addr,
 						      GFP_KERNEL);
+		host->align_buffer_sz = SDHCI_MAX_SEGS * SDHCI_ADMA2_ALIGN;
 		host->align_buffer = kmalloc(host->align_buffer_sz, GFP_KERNEL);
 		if (!host->adma_table || !host->align_buffer) {
 			if (host->adma_table)
@@ -2998,7 +3009,7 @@ int sdhci_add_host(struct sdhci_host *ho
 			host->flags &= ~SDHCI_USE_ADMA;
 			host->adma_table = NULL;
 			host->align_buffer = NULL;
-		} else if (host->adma_addr & host->align_mask) {
+		} else if (host->adma_addr & (SDHCI_ADMA2_DESC_ALIGN - 1)) {
 			pr_warn("%s: unable to allocate aligned ADMA descriptor\n",
 				mmc_hostname(mmc));
 			host->flags &= ~SDHCI_USE_ADMA;
@@ -3057,7 +3068,6 @@ int sdhci_add_host(struct sdhci_host *ho
 	/*
 	 * Set host parameters.
 	 */
-	mmc->ops = &sdhci_ops;
 	max_clk = host->max_clk;
 
 	if (host->ops->get_min_clock)
@@ -3091,14 +3101,14 @@ int sdhci_add_host(struct sdhci_host *ho
 		if (caps[0] & SDHCI_TIMEOUT_CLK_UNIT)
 			host->timeout_clk *= 1000;
 
+		if (override_timeout_clk)
+			host->timeout_clk = override_timeout_clk;
+
 		mmc->max_busy_timeout = host->ops->get_max_timeout_count ?
 			host->ops->get_max_timeout_count(host) : 1 << 27;
 		mmc->max_busy_timeout /= host->timeout_clk;
 	}
 
-	if (override_timeout_clk)
-		host->timeout_clk = override_timeout_clk;
-
 	mmc->caps |= MMC_CAP_SDIO_IRQ | MMC_CAP_ERASE | MMC_CAP_CMD23;
 	mmc->caps2 |= MMC_CAP2_SDIO_IRQ_NOTHREAD;
 
--- zfcpdump-kernel-4.4.orig/drivers/mmc/host/sdhci.h
+++ zfcpdump-kernel-4.4/drivers/mmc/host/sdhci.h
@@ -272,22 +272,27 @@
 /* ADMA2 32-bit DMA descriptor size */
 #define SDHCI_ADMA2_32_DESC_SZ	8
 
-/* ADMA2 32-bit DMA alignment */
-#define SDHCI_ADMA2_32_ALIGN	4
-
 /* ADMA2 32-bit descriptor */
 struct sdhci_adma2_32_desc {
 	__le16	cmd;
 	__le16	len;
 	__le32	addr;
-}  __packed __aligned(SDHCI_ADMA2_32_ALIGN);
+}  __packed __aligned(4);
+
+/* ADMA2 data alignment */
+#define SDHCI_ADMA2_ALIGN	4
+#define SDHCI_ADMA2_MASK	(SDHCI_ADMA2_ALIGN - 1)
+
+/*
+ * ADMA2 descriptor alignment.  Some controllers (e.g. Intel) require 8 byte
+ * alignment for the descriptor table even in 32-bit DMA mode.  Memory
+ * allocation is at least 8 byte aligned anyway, so just stipulate 8 always.
+ */
+#define SDHCI_ADMA2_DESC_ALIGN	8
 
 /* ADMA2 64-bit DMA descriptor size */
 #define SDHCI_ADMA2_64_DESC_SZ	12
 
-/* ADMA2 64-bit DMA alignment */
-#define SDHCI_ADMA2_64_ALIGN	8
-
 /*
  * ADMA2 64-bit descriptor. Note 12-byte descriptor can't always be 8-byte
  * aligned.
@@ -425,6 +430,7 @@ struct sdhci_host {
 
 	/* Internal data */
 	struct mmc_host *mmc;	/* MMC structure */
+	struct mmc_host_ops mmc_host_ops;	/* MMC host ops */
 	u64 dma_mask;		/* custom DMA mask */
 
 #if defined(CONFIG_LEDS_CLASS) || defined(CONFIG_LEDS_CLASS_MODULE)
@@ -482,8 +488,6 @@ struct sdhci_host {
 	dma_addr_t align_addr;	/* Mapped bounce buffer */
 
 	unsigned int desc_sz;	/* ADMA descriptor size */
-	unsigned int align_sz;	/* ADMA alignment */
-	unsigned int align_mask;	/* ADMA alignment mask */
 
 	struct tasklet_struct finish_tasklet;	/* Tasklet structures */
 
--- zfcpdump-kernel-4.4.orig/drivers/mmc/host/sh_mmcif.c
+++ zfcpdump-kernel-4.4/drivers/mmc/host/sh_mmcif.c
@@ -397,38 +397,26 @@ static void sh_mmcif_start_dma_tx(struct
 }
 
 static struct dma_chan *
-sh_mmcif_request_dma_one(struct sh_mmcif_host *host,
-			 struct sh_mmcif_plat_data *pdata,
-			 enum dma_transfer_direction direction)
+sh_mmcif_request_dma_pdata(struct sh_mmcif_host *host, uintptr_t slave_id)
 {
-	struct dma_slave_config cfg = { 0, };
-	struct dma_chan *chan;
-	void *slave_data = NULL;
-	struct resource *res;
-	struct device *dev = sh_mmcif_host_to_dev(host);
 	dma_cap_mask_t mask;
-	int ret;
 
 	dma_cap_zero(mask);
 	dma_cap_set(DMA_SLAVE, mask);
+	if (slave_id <= 0)
+		return NULL;
 
-	if (pdata)
-		slave_data = direction == DMA_MEM_TO_DEV ?
-			(void *)pdata->slave_id_tx :
-			(void *)pdata->slave_id_rx;
-
-	chan = dma_request_slave_channel_compat(mask, shdma_chan_filter,
-				slave_data, dev,
-				direction == DMA_MEM_TO_DEV ? "tx" : "rx");
-
-	dev_dbg(dev, "%s: %s: got channel %p\n", __func__,
-		direction == DMA_MEM_TO_DEV ? "TX" : "RX", chan);
+	return dma_request_channel(mask, shdma_chan_filter, (void *)slave_id);
+}
 
-	if (!chan)
-		return NULL;
+static int sh_mmcif_dma_slave_config(struct sh_mmcif_host *host,
+				     struct dma_chan *chan,
+				     enum dma_transfer_direction direction)
+{
+	struct resource *res;
+	struct dma_slave_config cfg = { 0, };
 
 	res = platform_get_resource(host->pd, IORESOURCE_MEM, 0);
-
 	cfg.direction = direction;
 
 	if (direction == DMA_DEV_TO_MEM) {
@@ -439,38 +427,42 @@ sh_mmcif_request_dma_one(struct sh_mmcif
 		cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
 	}
 
-	ret = dmaengine_slave_config(chan, &cfg);
-	if (ret < 0) {
-		dma_release_channel(chan);
-		return NULL;
-	}
-
-	return chan;
+	return dmaengine_slave_config(chan, &cfg);
 }
 
-static void sh_mmcif_request_dma(struct sh_mmcif_host *host,
-				 struct sh_mmcif_plat_data *pdata)
+static void sh_mmcif_request_dma(struct sh_mmcif_host *host)
 {
 	struct device *dev = sh_mmcif_host_to_dev(host);
 	host->dma_active = false;
 
-	if (pdata) {
-		if (pdata->slave_id_tx <= 0 || pdata->slave_id_rx <= 0)
-			return;
-	} else if (!dev->of_node) {
-		return;
+	/* We can only either use DMA for both Tx and Rx or not use it at all */
+	if (IS_ENABLED(CONFIG_SUPERH) && dev->platform_data) {
+		struct sh_mmcif_plat_data *pdata = dev->platform_data;
+
+		host->chan_tx = sh_mmcif_request_dma_pdata(host,
+							pdata->slave_id_tx);
+		host->chan_rx = sh_mmcif_request_dma_pdata(host,
+							pdata->slave_id_rx);
+	} else {
+		host->chan_tx = dma_request_slave_channel(dev, "tx");
+		host->chan_rx = dma_request_slave_channel(dev, "rx");
 	}
+	dev_dbg(dev, "%s: got channel TX %p RX %p\n", __func__, host->chan_tx,
+		host->chan_rx);
 
-	/* We can only either use DMA for both Tx and Rx or not use it at all */
-	host->chan_tx = sh_mmcif_request_dma_one(host, pdata, DMA_MEM_TO_DEV);
-	if (!host->chan_tx)
-		return;
+	if (!host->chan_tx || !host->chan_rx ||
+	    sh_mmcif_dma_slave_config(host, host->chan_tx, DMA_MEM_TO_DEV) ||
+	    sh_mmcif_dma_slave_config(host, host->chan_rx, DMA_DEV_TO_MEM))
+		goto error;
 
-	host->chan_rx = sh_mmcif_request_dma_one(host, pdata, DMA_DEV_TO_MEM);
-	if (!host->chan_rx) {
+	return;
+
+error:
+	if (host->chan_tx)
 		dma_release_channel(host->chan_tx);
-		host->chan_tx = NULL;
-	}
+	if (host->chan_rx)
+		dma_release_channel(host->chan_rx);
+	host->chan_tx = host->chan_rx = NULL;
 }
 
 static void sh_mmcif_release_dma(struct sh_mmcif_host *host)
@@ -1102,7 +1094,7 @@ static void sh_mmcif_set_ios(struct mmc_
 	if (ios->power_mode == MMC_POWER_UP) {
 		if (!host->card_present) {
 			/* See if we also get DMA */
-			sh_mmcif_request_dma(host, dev->platform_data);
+			sh_mmcif_request_dma(host);
 			host->card_present = true;
 		}
 		sh_mmcif_set_power(host, ios);
--- zfcpdump-kernel-4.4.orig/drivers/mmc/host/usdhi6rol0.c
+++ zfcpdump-kernel-4.4/drivers/mmc/host/usdhi6rol0.c
@@ -1634,7 +1634,7 @@ static void usdhi6_timeout_work(struct w
 	struct usdhi6_host *host = container_of(d, struct usdhi6_host, timeout_work);
 	struct mmc_request *mrq = host->mrq;
 	struct mmc_data *data = mrq ? mrq->data : NULL;
-	struct scatterlist *sg = host->sg ?: data->sg;
+	struct scatterlist *sg;
 
 	dev_warn(mmc_dev(host->mmc),
 		 "%s timeout wait %u CMD%d: IRQ 0x%08x:0x%08x, last IRQ 0x%08x\n",
@@ -1666,6 +1666,7 @@ static void usdhi6_timeout_work(struct w
 	case USDHI6_WAIT_FOR_MWRITE:
 	case USDHI6_WAIT_FOR_READ:
 	case USDHI6_WAIT_FOR_WRITE:
+		sg = host->sg ?: data->sg;
 		dev_dbg(mmc_dev(host->mmc),
 			"%c: page #%u @ +0x%zx %ux%u in SG%u. Current SG %u bytes @ %u\n",
 			data->flags & MMC_DATA_READ ? 'R' : 'W', host->page_idx,
--- zfcpdump-kernel-4.4.orig/drivers/mtd/maps/pmcmsp-flash.c
+++ zfcpdump-kernel-4.4/drivers/mtd/maps/pmcmsp-flash.c
@@ -75,15 +75,15 @@ static int __init init_msp_flash(void)
 
 	printk(KERN_NOTICE "Found %d PMC flash devices\n", fcnt);
 
-	msp_flash = kmalloc(fcnt * sizeof(struct map_info *), GFP_KERNEL);
+	msp_flash = kcalloc(fcnt, sizeof(*msp_flash), GFP_KERNEL);
 	if (!msp_flash)
 		return -ENOMEM;
 
-	msp_parts = kmalloc(fcnt * sizeof(struct mtd_partition *), GFP_KERNEL);
+	msp_parts = kcalloc(fcnt, sizeof(*msp_parts), GFP_KERNEL);
 	if (!msp_parts)
 		goto free_msp_flash;
 
-	msp_maps = kcalloc(fcnt, sizeof(struct mtd_info), GFP_KERNEL);
+	msp_maps = kcalloc(fcnt, sizeof(*msp_maps), GFP_KERNEL);
 	if (!msp_maps)
 		goto free_msp_parts;
 
--- zfcpdump-kernel-4.4.orig/drivers/mtd/maps/sa1100-flash.c
+++ zfcpdump-kernel-4.4/drivers/mtd/maps/sa1100-flash.c
@@ -230,8 +230,10 @@ static struct sa_info *sa1100_setup_mtd(
 
 		info->mtd = mtd_concat_create(cdev, info->num_subdev,
 					      plat->name);
-		if (info->mtd == NULL)
+		if (info->mtd == NULL) {
 			ret = -ENXIO;
+			goto err;
+		}
 	}
 	info->mtd->dev.parent = &pdev->dev;
 
--- zfcpdump-kernel-4.4.orig/drivers/mtd/mtdsuper.c
+++ zfcpdump-kernel-4.4/drivers/mtd/mtdsuper.c
@@ -125,6 +125,7 @@ struct dentry *mount_mtd(struct file_sys
 #ifdef CONFIG_BLOCK
 	struct block_device *bdev;
 	int ret, major;
+	int perm;
 #endif
 	int mtdnr;
 
@@ -176,7 +177,10 @@ struct dentry *mount_mtd(struct file_sys
 	/* try the old way - the hack where we allowed users to mount
 	 * /dev/mtdblock$(n) but didn't actually _use_ the blockdev
 	 */
-	bdev = lookup_bdev(dev_name);
+	perm = MAY_READ;
+	if (!(flags & MS_RDONLY))
+		perm |= MAY_WRITE;
+	bdev = lookup_bdev(dev_name, perm);
 	if (IS_ERR(bdev)) {
 		ret = PTR_ERR(bdev);
 		pr_debug("MTDSB: lookup_bdev() returned %d\n", ret);
--- zfcpdump-kernel-4.4.orig/drivers/mtd/nand/brcmnand/brcmnand.c
+++ zfcpdump-kernel-4.4/drivers/mtd/nand/brcmnand/brcmnand.c
@@ -309,6 +309,36 @@ static const u16 brcmnand_regs_v60[] = {
 	[BRCMNAND_FC_BASE]		= 0x400,
 };
 
+/* BRCMNAND v7.1 */
+static const u16 brcmnand_regs_v71[] = {
+	[BRCMNAND_CMD_START]		=  0x04,
+	[BRCMNAND_CMD_EXT_ADDRESS]	=  0x08,
+	[BRCMNAND_CMD_ADDRESS]		=  0x0c,
+	[BRCMNAND_INTFC_STATUS]		=  0x14,
+	[BRCMNAND_CS_SELECT]		=  0x18,
+	[BRCMNAND_CS_XOR]		=  0x1c,
+	[BRCMNAND_LL_OP]		=  0x20,
+	[BRCMNAND_CS0_BASE]		=  0x50,
+	[BRCMNAND_CS1_BASE]		=     0,
+	[BRCMNAND_CORR_THRESHOLD]	=  0xdc,
+	[BRCMNAND_CORR_THRESHOLD_EXT]	=  0xe0,
+	[BRCMNAND_UNCORR_COUNT]		=  0xfc,
+	[BRCMNAND_CORR_COUNT]		= 0x100,
+	[BRCMNAND_CORR_EXT_ADDR]	= 0x10c,
+	[BRCMNAND_CORR_ADDR]		= 0x110,
+	[BRCMNAND_UNCORR_EXT_ADDR]	= 0x114,
+	[BRCMNAND_UNCORR_ADDR]		= 0x118,
+	[BRCMNAND_SEMAPHORE]		= 0x150,
+	[BRCMNAND_ID]			= 0x194,
+	[BRCMNAND_ID_EXT]		= 0x198,
+	[BRCMNAND_LL_RDATA]		= 0x19c,
+	[BRCMNAND_OOB_READ_BASE]	= 0x200,
+	[BRCMNAND_OOB_READ_10_BASE]	=     0,
+	[BRCMNAND_OOB_WRITE_BASE]	= 0x280,
+	[BRCMNAND_OOB_WRITE_10_BASE]	=     0,
+	[BRCMNAND_FC_BASE]		= 0x400,
+};
+
 enum brcmnand_cs_reg {
 	BRCMNAND_CS_CFG_EXT = 0,
 	BRCMNAND_CS_CFG,
@@ -404,7 +434,9 @@ static int brcmnand_revision_init(struct
 	}
 
 	/* Register offsets */
-	if (ctrl->nand_version >= 0x0600)
+	if (ctrl->nand_version >= 0x0701)
+		ctrl->reg_offsets = brcmnand_regs_v71;
+	else if (ctrl->nand_version >= 0x0600)
 		ctrl->reg_offsets = brcmnand_regs_v60;
 	else if (ctrl->nand_version >= 0x0500)
 		ctrl->reg_offsets = brcmnand_regs_v50;
--- zfcpdump-kernel-4.4.orig/drivers/mtd/nand/davinci_nand.c
+++ zfcpdump-kernel-4.4/drivers/mtd/nand/davinci_nand.c
@@ -241,6 +241,9 @@ static void nand_davinci_hwctl_4bit(stru
 	unsigned long flags;
 	u32 val;
 
+	/* Reset ECC hardware */
+	davinci_nand_readl(info, NAND_4BIT_ECC1_OFFSET);
+
 	spin_lock_irqsave(&davinci_nand_lock, flags);
 
 	/* Start 4-bit ECC calculation for read/write */
--- zfcpdump-kernel-4.4.orig/drivers/mtd/nand/nand_base.c
+++ zfcpdump-kernel-4.4/drivers/mtd/nand/nand_base.c
@@ -2586,7 +2586,7 @@ static int nand_do_write_ops(struct mtd_
 		int cached = writelen > bytes && page != blockmask;
 		uint8_t *wbuf = buf;
 		int use_bufpoi;
-		int part_pagewr = (column || writelen < (mtd->writesize - 1));
+		int part_pagewr = (column || writelen < mtd->writesize);
 
 		if (part_pagewr)
 			use_bufpoi = 1;
@@ -3979,7 +3979,6 @@ static int nand_dt_init(struct mtd_info
  * This is the first phase of the normal nand_scan() function. It reads the
  * flash ID and sets up MTD fields accordingly.
  *
- * The mtd->owner field must be set to the module of the caller.
  */
 int nand_scan_ident(struct mtd_info *mtd, int maxchips,
 		    struct nand_flash_dev *table)
@@ -3995,6 +3994,9 @@ int nand_scan_ident(struct mtd_info *mtd
 			return ret;
 	}
 
+	if (!mtd->name && mtd->dev.parent)
+		mtd->name = dev_name(mtd->dev.parent);
+
 	/* Set the default functions */
 	nand_set_defaults(chip, chip->options & NAND_BUSWIDTH_16);
 
@@ -4400,19 +4402,12 @@ EXPORT_SYMBOL(nand_scan_tail);
  *
  * This fills out all the uninitialized function pointers with the defaults.
  * The flash ID is read and the mtd/chip structures are filled with the
- * appropriate values. The mtd->owner field must be set to the module of the
- * caller.
+ * appropriate values.
  */
 int nand_scan(struct mtd_info *mtd, int maxchips)
 {
 	int ret;
 
-	/* Many callers got this wrong, so check for it for a while... */
-	if (!mtd->owner && caller_is_module()) {
-		pr_crit("%s called with NULL mtd->owner!\n", __func__);
-		BUG();
-	}
-
 	ret = nand_scan_ident(mtd, maxchips, NULL);
 	if (!ret)
 		ret = nand_scan_tail(mtd);
--- zfcpdump-kernel-4.4.orig/drivers/mtd/onenand/onenand_base.c
+++ zfcpdump-kernel-4.4/drivers/mtd/onenand/onenand_base.c
@@ -2599,6 +2599,7 @@ static int onenand_default_block_markbad
  */
 static int onenand_block_markbad(struct mtd_info *mtd, loff_t ofs)
 {
+	struct onenand_chip *this = mtd->priv;
 	int ret;
 
 	ret = onenand_block_isbad(mtd, ofs);
@@ -2610,7 +2611,7 @@ static int onenand_block_markbad(struct
 	}
 
 	onenand_get_device(mtd, FL_WRITING);
-	ret = mtd_block_markbad(mtd, ofs);
+	ret = this->block_markbad(mtd, ofs);
 	onenand_release_device(mtd);
 	return ret;
 }
--- zfcpdump-kernel-4.4.orig/drivers/mtd/spi-nor/spi-nor.c
+++ zfcpdump-kernel-4.4/drivers/mtd/spi-nor/spi-nor.c
@@ -1067,45 +1067,6 @@ static int spansion_quad_enable(struct s
 	return 0;
 }
 
-static int micron_quad_enable(struct spi_nor *nor)
-{
-	int ret;
-	u8 val;
-
-	ret = nor->read_reg(nor, SPINOR_OP_RD_EVCR, &val, 1);
-	if (ret < 0) {
-		dev_err(nor->dev, "error %d reading EVCR\n", ret);
-		return ret;
-	}
-
-	write_enable(nor);
-
-	/* set EVCR, enable quad I/O */
-	nor->cmd_buf[0] = val & ~EVCR_QUAD_EN_MICRON;
-	ret = nor->write_reg(nor, SPINOR_OP_WD_EVCR, nor->cmd_buf, 1);
-	if (ret < 0) {
-		dev_err(nor->dev, "error while writing EVCR register\n");
-		return ret;
-	}
-
-	ret = spi_nor_wait_till_ready(nor);
-	if (ret)
-		return ret;
-
-	/* read EVCR and check it */
-	ret = nor->read_reg(nor, SPINOR_OP_RD_EVCR, &val, 1);
-	if (ret < 0) {
-		dev_err(nor->dev, "error %d reading EVCR\n", ret);
-		return ret;
-	}
-	if (val & EVCR_QUAD_EN_MICRON) {
-		dev_err(nor->dev, "Micron EVCR Quad bit not clear\n");
-		return -EINVAL;
-	}
-
-	return 0;
-}
-
 static int set_quad_mode(struct spi_nor *nor, const struct flash_info *info)
 {
 	int status;
@@ -1119,12 +1080,7 @@ static int set_quad_mode(struct spi_nor
 		}
 		return status;
 	case SNOR_MFR_MICRON:
-		status = micron_quad_enable(nor);
-		if (status) {
-			dev_err(nor->dev, "Micron quad-read not enabled\n");
-			return -EINVAL;
-		}
-		return status;
+		return 0;
 	default:
 		status = spansion_quad_enable(nor);
 		if (status) {
--- zfcpdump-kernel-4.4.orig/drivers/mtd/ubi/build.c
+++ zfcpdump-kernel-4.4/drivers/mtd/ubi/build.c
@@ -869,7 +869,7 @@ int ubi_attach_mtd_dev(struct mtd_info *
 	for (i = 0; i < UBI_MAX_DEVICES; i++) {
 		ubi = ubi_devices[i];
 		if (ubi && mtd->index == ubi->mtd->index) {
-			ubi_err(ubi, "mtd%d is already attached to ubi%d",
+			pr_err("ubi: mtd%d is already attached to ubi%d",
 				mtd->index, i);
 			return -EEXIST;
 		}
@@ -884,7 +884,7 @@ int ubi_attach_mtd_dev(struct mtd_info *
 	 * no sense to attach emulated MTD devices, so we prohibit this.
 	 */
 	if (mtd->type == MTD_UBIVOLUME) {
-		ubi_err(ubi, "refuse attaching mtd%d - it is already emulated on top of UBI",
+		pr_err("ubi: refuse attaching mtd%d - it is already emulated on top of UBI",
 			mtd->index);
 		return -EINVAL;
 	}
@@ -895,7 +895,7 @@ int ubi_attach_mtd_dev(struct mtd_info *
 			if (!ubi_devices[ubi_num])
 				break;
 		if (ubi_num == UBI_MAX_DEVICES) {
-			ubi_err(ubi, "only %d UBI devices may be created",
+			pr_err("ubi: only %d UBI devices may be created",
 				UBI_MAX_DEVICES);
 			return -ENFILE;
 		}
@@ -905,7 +905,7 @@ int ubi_attach_mtd_dev(struct mtd_info *
 
 		/* Make sure ubi_num is not busy */
 		if (ubi_devices[ubi_num]) {
-			ubi_err(ubi, "already exists");
+			pr_err("ubi: ubi%i already exists", ubi_num);
 			return -EEXIST;
 		}
 	}
@@ -987,6 +987,9 @@ int ubi_attach_mtd_dev(struct mtd_info *
 			goto out_detach;
 	}
 
+	/* Make device "available" before it becomes accessible via sysfs */
+	ubi_devices[ubi_num] = ubi;
+
 	err = uif_init(ubi, &ref);
 	if (err)
 		goto out_detach;
@@ -1031,7 +1034,6 @@ int ubi_attach_mtd_dev(struct mtd_info *
 	wake_up_process(ubi->bgt_thread);
 	spin_unlock(&ubi->wl_lock);
 
-	ubi_devices[ubi_num] = ubi;
 	ubi_notify_all(ubi, UBI_VOLUME_ADDED, NULL);
 	return ubi_num;
 
@@ -1042,6 +1044,7 @@ out_uif:
 	ubi_assert(ref);
 	uif_close(ubi);
 out_detach:
+	ubi_devices[ubi_num] = NULL;
 	ubi_wl_close(ubi);
 	ubi_free_internal_volumes(ubi);
 	vfree(ubi->vtbl);
--- zfcpdump-kernel-4.4.orig/drivers/mtd/ubi/eba.c
+++ zfcpdump-kernel-4.4/drivers/mtd/ubi/eba.c
@@ -426,8 +426,25 @@ retry:
 						 pnum, vol_id, lnum);
 					err = -EBADMSG;
 				} else {
-					err = -EINVAL;
-					ubi_ro_mode(ubi);
+					/*
+					 * Ending up here in the non-Fastmap case
+					 * is a clear bug as the VID header had to
+					 * be present at scan time to have it referenced.
+					 * With fastmap the story is more complicated.
+					 * Fastmap has the mapping info without the need
+					 * of a full scan. So the LEB could have been
+					 * unmapped, Fastmap cannot know this and keeps
+					 * the LEB referenced.
+					 * This is valid and works as the layer above UBI
+					 * has to do bookkeeping about used/referenced
+					 * LEBs in any case.
+					 */
+					if (ubi->fast_attach) {
+						err = -EBADMSG;
+					} else {
+						err = -EINVAL;
+						ubi_ro_mode(ubi);
+					}
 				}
 			}
 			goto out_free;
@@ -558,6 +575,7 @@ static int recover_peb(struct ubi_device
 	int err, idx = vol_id2idx(ubi, vol_id), new_pnum, data_size, tries = 0;
 	struct ubi_volume *vol = ubi->volumes[idx];
 	struct ubi_vid_hdr *vid_hdr;
+	uint32_t crc;
 
 	vid_hdr = ubi_zalloc_vid_hdr(ubi, GFP_NOFS);
 	if (!vid_hdr)
@@ -582,14 +600,8 @@ retry:
 		goto out_put;
 	}
 
-	vid_hdr->sqnum = cpu_to_be64(ubi_next_sqnum(ubi));
-	err = ubi_io_write_vid_hdr(ubi, new_pnum, vid_hdr);
-	if (err) {
-		up_read(&ubi->fm_eba_sem);
-		goto write_error;
-	}
+	ubi_assert(vid_hdr->vol_type == UBI_VID_DYNAMIC);
 
-	data_size = offset + len;
 	mutex_lock(&ubi->buf_mutex);
 	memset(ubi->peb_buf + offset, 0xFF, len);
 
@@ -604,6 +616,19 @@ retry:
 
 	memcpy(ubi->peb_buf + offset, buf, len);
 
+	data_size = offset + len;
+	crc = crc32(UBI_CRC32_INIT, ubi->peb_buf, data_size);
+	vid_hdr->sqnum = cpu_to_be64(ubi_next_sqnum(ubi));
+	vid_hdr->copy_flag = 1;
+	vid_hdr->data_size = cpu_to_be32(data_size);
+	vid_hdr->data_crc = cpu_to_be32(crc);
+	err = ubi_io_write_vid_hdr(ubi, new_pnum, vid_hdr);
+	if (err) {
+		mutex_unlock(&ubi->buf_mutex);
+		up_read(&ubi->fm_eba_sem);
+		goto write_error;
+	}
+
 	err = ubi_io_write_data(ubi, ubi->peb_buf, new_pnum, 0, data_size);
 	if (err) {
 		mutex_unlock(&ubi->buf_mutex);
--- zfcpdump-kernel-4.4.orig/drivers/mtd/ubi/fastmap.c
+++ zfcpdump-kernel-4.4/drivers/mtd/ubi/fastmap.c
@@ -1058,6 +1058,7 @@ int ubi_scan_fastmap(struct ubi_device *
 	ubi_msg(ubi, "fastmap WL pool size: %d",
 		ubi->fm_wl_pool.max_size);
 	ubi->fm_disabled = 0;
+	ubi->fast_attach = 1;
 
 	ubi_free_vid_hdr(ubi, vh);
 	kfree(ech);
--- zfcpdump-kernel-4.4.orig/drivers/mtd/ubi/ubi.h
+++ zfcpdump-kernel-4.4/drivers/mtd/ubi/ubi.h
@@ -462,6 +462,7 @@ struct ubi_debug_info {
  * @fm_eba_sem: allows ubi_update_fastmap() to block EBA table changes
  * @fm_work: fastmap work queue
  * @fm_work_scheduled: non-zero if fastmap work was scheduled
+ * @fast_attach: non-zero if UBI was attached by fastmap
  *
  * @used: RB-tree of used physical eraseblocks
  * @erroneous: RB-tree of erroneous used physical eraseblocks
@@ -570,6 +571,7 @@ struct ubi_device {
 	size_t fm_size;
 	struct work_struct fm_work;
 	int fm_work_scheduled;
+	int fast_attach;
 
 	/* Wear-leveling sub-system's stuff */
 	struct rb_root used;
--- zfcpdump-kernel-4.4.orig/drivers/mtd/ubi/upd.c
+++ zfcpdump-kernel-4.4/drivers/mtd/ubi/upd.c
@@ -193,7 +193,7 @@ int ubi_start_leb_change(struct ubi_devi
 	vol->changing_leb = 1;
 	vol->ch_lnum = req->lnum;
 
-	vol->upd_buf = vmalloc(req->bytes);
+	vol->upd_buf = vmalloc(ALIGN((int)req->bytes, ubi->min_io_size));
 	if (!vol->upd_buf)
 		return -ENOMEM;
 
--- zfcpdump-kernel-4.4.orig/drivers/mtd/ubi/vmt.c
+++ zfcpdump-kernel-4.4/drivers/mtd/ubi/vmt.c
@@ -488,13 +488,6 @@ int ubi_resize_volume(struct ubi_volume_
 		spin_unlock(&ubi->volumes_lock);
 	}
 
-	/* Change volume table record */
-	vtbl_rec = ubi->vtbl[vol_id];
-	vtbl_rec.reserved_pebs = cpu_to_be32(reserved_pebs);
-	err = ubi_change_vtbl_record(ubi, vol_id, &vtbl_rec);
-	if (err)
-		goto out_acc;
-
 	if (pebs < 0) {
 		for (i = 0; i < -pebs; i++) {
 			err = ubi_eba_unmap_leb(ubi, vol, reserved_pebs + i);
@@ -512,6 +505,24 @@ int ubi_resize_volume(struct ubi_volume_
 		spin_unlock(&ubi->volumes_lock);
 	}
 
+	/*
+	 * When we shrink a volume we have to flush all pending (erase) work.
+	 * Otherwise it can happen that upon next attach UBI finds a LEB with
+	 * lnum > highest_lnum and refuses to attach.
+	 */
+	if (pebs < 0) {
+		err = ubi_wl_flush(ubi, vol_id, UBI_ALL);
+		if (err)
+			goto out_acc;
+	}
+
+	/* Change volume table record */
+	vtbl_rec = ubi->vtbl[vol_id];
+	vtbl_rec.reserved_pebs = cpu_to_be32(reserved_pebs);
+	err = ubi_change_vtbl_record(ubi, vol_id, &vtbl_rec);
+	if (err)
+		goto out_acc;
+
 	vol->reserved_pebs = reserved_pebs;
 	if (vol->vol_type == UBI_DYNAMIC_VOLUME) {
 		vol->used_ebs = reserved_pebs;
--- zfcpdump-kernel-4.4.orig/drivers/net/bonding/bond_main.c
+++ zfcpdump-kernel-4.4/drivers/net/bonding/bond_main.c
@@ -214,6 +214,8 @@ static void bond_uninit(struct net_devic
 static struct rtnl_link_stats64 *bond_get_stats(struct net_device *bond_dev,
 						struct rtnl_link_stats64 *stats);
 static void bond_slave_arr_handler(struct work_struct *work);
+static bool bond_time_in_interval(struct bonding *bond, unsigned long last_act,
+				  int mod);
 
 /*---------------------------- General routines -----------------------------*/
 
@@ -1207,7 +1209,6 @@ static int bond_master_upper_dev_link(st
 	err = netdev_master_upper_dev_link_private(slave_dev, bond_dev, slave);
 	if (err)
 		return err;
-	slave_dev->flags |= IFF_SLAVE;
 	rtmsg_ifinfo(RTM_NEWLINK, slave_dev, IFF_SLAVE, GFP_KERNEL);
 	return 0;
 }
@@ -1316,9 +1317,10 @@ int bond_enslave(struct net_device *bond
 			    slave_dev->name);
 	}
 
-	/* already enslaved */
-	if (slave_dev->flags & IFF_SLAVE) {
-		netdev_dbg(bond_dev, "Error: Device was already enslaved\n");
+	/* already in-use? */
+	if (netdev_is_rx_handler_busy(slave_dev)) {
+		netdev_err(bond_dev,
+			   "Error: Device is in use and cannot be enslaved\n");
 		return -EBUSY;
 	}
 
@@ -1465,6 +1467,9 @@ int bond_enslave(struct net_device *bond
 		}
 	}
 
+	/* set slave flag before open to prevent IPv6 addrconf */
+	slave_dev->flags |= IFF_SLAVE;
+
 	/* open the slave since the application closed it */
 	res = dev_open(slave_dev);
 	if (res) {
@@ -1725,6 +1730,7 @@ err_close:
 	dev_close(slave_dev);
 
 err_restore_mac:
+	slave_dev->flags &= ~IFF_SLAVE;
 	if (!bond->params.fail_over_mac ||
 	    BOND_MODE(bond) != BOND_MODE_ACTIVEBACKUP) {
 		/* XXX TODO - fom follow mode needs to change master's
@@ -2415,7 +2421,7 @@ int bond_arp_rcv(const struct sk_buff *s
 		 struct slave *slave)
 {
 	struct arphdr *arp = (struct arphdr *)skb->data;
-	struct slave *curr_active_slave;
+	struct slave *curr_active_slave, *curr_arp_slave;
 	unsigned char *arp_ptr;
 	__be32 sip, tip;
 	int alen, is_arp = skb->protocol == __cpu_to_be16(ETH_P_ARP);
@@ -2462,26 +2468,41 @@ int bond_arp_rcv(const struct sk_buff *s
 		     &sip, &tip);
 
 	curr_active_slave = rcu_dereference(bond->curr_active_slave);
+	curr_arp_slave = rcu_dereference(bond->current_arp_slave);
 
-	/* Backup slaves won't see the ARP reply, but do come through
-	 * here for each ARP probe (so we swap the sip/tip to validate
-	 * the probe).  In a "redundant switch, common router" type of
-	 * configuration, the ARP probe will (hopefully) travel from
-	 * the active, through one switch, the router, then the other
-	 * switch before reaching the backup.
+	/* We 'trust' the received ARP enough to validate it if:
+	 *
+	 * (a) the slave receiving the ARP is active (which includes the
+	 * current ARP slave, if any), or
 	 *
-	 * We 'trust' the arp requests if there is an active slave and
-	 * it received valid arp reply(s) after it became active. This
-	 * is done to avoid endless looping when we can't reach the
+	 * (b) the receiving slave isn't active, but there is a currently
+	 * active slave and it received valid arp reply(s) after it became
+	 * the currently active slave, or
+	 *
+	 * (c) there is an ARP slave that sent an ARP during the prior ARP
+	 * interval, and we receive an ARP reply on any slave.  We accept
+	 * these because switch FDB update delays may deliver the ARP
+	 * reply to a slave other than the sender of the ARP request.
+	 *
+	 * Note: for (b), backup slaves are receiving the broadcast ARP
+	 * request, not a reply.  This request passes from the sending
+	 * slave through the L2 switch(es) to the receiving slave.  Since
+	 * this is checking the request, sip/tip are swapped for
+	 * validation.
+	 *
+	 * This is done to avoid endless looping when we can't reach the
 	 * arp_ip_target and fool ourselves with our own arp requests.
 	 */
-
 	if (bond_is_active_slave(slave))
 		bond_validate_arp(bond, slave, sip, tip);
 	else if (curr_active_slave &&
 		 time_after(slave_last_rx(bond, curr_active_slave),
 			    curr_active_slave->last_link_up))
 		bond_validate_arp(bond, slave, tip, sip);
+	else if (curr_arp_slave && (arp->ar_op == htons(ARPOP_REPLY)) &&
+		 bond_time_in_interval(bond,
+				       dev_trans_start(curr_arp_slave->dev), 1))
+		bond_validate_arp(bond, slave, sip, tip);
 
 out_unlock:
 	if (arp != (struct arphdr *)skb->data)
@@ -3240,6 +3261,30 @@ static int bond_close(struct net_device
 	return 0;
 }
 
+/* fold stats, assuming all rtnl_link_stats64 fields are u64, but
+ * that some drivers can provide 32bit values only.
+ */
+static void bond_fold_stats(struct rtnl_link_stats64 *_res,
+			    const struct rtnl_link_stats64 *_new,
+			    const struct rtnl_link_stats64 *_old)
+{
+	const u64 *new = (const u64 *)_new;
+	const u64 *old = (const u64 *)_old;
+	u64 *res = (u64 *)_res;
+	int i;
+
+	for (i = 0; i < sizeof(*_res) / sizeof(u64); i++) {
+		u64 nv = new[i];
+		u64 ov = old[i];
+
+		/* detects if this particular field is 32bit only */
+		if (((nv | ov) >> 32) == 0)
+			res[i] += (u32)nv - (u32)ov;
+		else
+			res[i] += nv - ov;
+	}
+}
+
 static struct rtnl_link_stats64 *bond_get_stats(struct net_device *bond_dev,
 						struct rtnl_link_stats64 *stats)
 {
@@ -3248,43 +3293,23 @@ static struct rtnl_link_stats64 *bond_ge
 	struct list_head *iter;
 	struct slave *slave;
 
+	spin_lock(&bond->stats_lock);
 	memcpy(stats, &bond->bond_stats, sizeof(*stats));
 
-	bond_for_each_slave(bond, slave, iter) {
-		const struct rtnl_link_stats64 *sstats =
+	rcu_read_lock();
+	bond_for_each_slave_rcu(bond, slave, iter) {
+		const struct rtnl_link_stats64 *new =
 			dev_get_stats(slave->dev, &temp);
-		struct rtnl_link_stats64 *pstats = &slave->slave_stats;
 
-		stats->rx_packets +=  sstats->rx_packets - pstats->rx_packets;
-		stats->rx_bytes += sstats->rx_bytes - pstats->rx_bytes;
-		stats->rx_errors += sstats->rx_errors - pstats->rx_errors;
-		stats->rx_dropped += sstats->rx_dropped - pstats->rx_dropped;
-
-		stats->tx_packets += sstats->tx_packets - pstats->tx_packets;;
-		stats->tx_bytes += sstats->tx_bytes - pstats->tx_bytes;
-		stats->tx_errors += sstats->tx_errors - pstats->tx_errors;
-		stats->tx_dropped += sstats->tx_dropped - pstats->tx_dropped;
-
-		stats->multicast += sstats->multicast - pstats->multicast;
-		stats->collisions += sstats->collisions - pstats->collisions;
-
-		stats->rx_length_errors += sstats->rx_length_errors - pstats->rx_length_errors;
-		stats->rx_over_errors += sstats->rx_over_errors - pstats->rx_over_errors;
-		stats->rx_crc_errors += sstats->rx_crc_errors - pstats->rx_crc_errors;
-		stats->rx_frame_errors += sstats->rx_frame_errors - pstats->rx_frame_errors;
-		stats->rx_fifo_errors += sstats->rx_fifo_errors - pstats->rx_fifo_errors;
-		stats->rx_missed_errors += sstats->rx_missed_errors - pstats->rx_missed_errors;
-
-		stats->tx_aborted_errors += sstats->tx_aborted_errors - pstats->tx_aborted_errors;
-		stats->tx_carrier_errors += sstats->tx_carrier_errors - pstats->tx_carrier_errors;
-		stats->tx_fifo_errors += sstats->tx_fifo_errors - pstats->tx_fifo_errors;
-		stats->tx_heartbeat_errors += sstats->tx_heartbeat_errors - pstats->tx_heartbeat_errors;
-		stats->tx_window_errors += sstats->tx_window_errors - pstats->tx_window_errors;
+		bond_fold_stats(stats, new, &slave->slave_stats);
 
 		/* save off the slave stats for the next run */
-		memcpy(pstats, sstats, sizeof(*sstats));
+		memcpy(&slave->slave_stats, new, sizeof(*new));
 	}
+	rcu_read_unlock();
+
 	memcpy(&bond->bond_stats, stats, sizeof(*stats));
+	spin_unlock(&bond->stats_lock);
 
 	return stats;
 }
@@ -4098,6 +4123,7 @@ void bond_setup(struct net_device *bond_
 	struct bonding *bond = netdev_priv(bond_dev);
 
 	spin_lock_init(&bond->mode_lock);
+	spin_lock_init(&bond->stats_lock);
 	bond->params = bonding_defaults;
 
 	/* Initialize pointers */
--- zfcpdump-kernel-4.4.orig/drivers/net/bonding/bond_netlink.c
+++ zfcpdump-kernel-4.4/drivers/net/bonding/bond_netlink.c
@@ -446,7 +446,11 @@ static int bond_newlink(struct net *src_
 	if (err < 0)
 		return err;
 
-	return register_netdevice(bond_dev);
+	err = register_netdevice(bond_dev);
+
+	netif_carrier_off(bond_dev);
+
+	return err;
 }
 
 static size_t bond_get_size(const struct net_device *bond_dev)
--- zfcpdump-kernel-4.4.orig/drivers/net/can/at91_can.c
+++ zfcpdump-kernel-4.4/drivers/net/can/at91_can.c
@@ -712,9 +712,10 @@ static int at91_poll_rx(struct net_devic
 
 	/* upper group completed, look again in lower */
 	if (priv->rx_next > get_mb_rx_low_last(priv) &&
-	    quota > 0 && mb > get_mb_rx_last(priv)) {
+	    mb > get_mb_rx_last(priv)) {
 		priv->rx_next = get_mb_rx_first(priv);
-		goto again;
+		if (quota > 0)
+			goto again;
 	}
 
 	return received;
--- zfcpdump-kernel-4.4.orig/drivers/net/can/c_can/c_can.c
+++ zfcpdump-kernel-4.4/drivers/net/can/c_can/c_can.c
@@ -332,9 +332,23 @@ static void c_can_setup_tx_object(struct
 
 	priv->write_reg(priv, C_CAN_IFACE(MSGCTRL_REG, iface), ctrl);
 
-	for (i = 0; i < frame->can_dlc; i += 2) {
-		priv->write_reg(priv, C_CAN_IFACE(DATA1_REG, iface) + i / 2,
-				frame->data[i] | (frame->data[i + 1] << 8));
+	if (priv->type == BOSCH_D_CAN) {
+		u32 data = 0, dreg = C_CAN_IFACE(DATA1_REG, iface);
+
+		for (i = 0; i < frame->can_dlc; i += 4, dreg += 2) {
+			data = (u32)frame->data[i];
+			data |= (u32)frame->data[i + 1] << 8;
+			data |= (u32)frame->data[i + 2] << 16;
+			data |= (u32)frame->data[i + 3] << 24;
+			priv->write_reg32(priv, dreg, data);
+		}
+	} else {
+		for (i = 0; i < frame->can_dlc; i += 2) {
+			priv->write_reg(priv,
+					C_CAN_IFACE(DATA1_REG, iface) + i / 2,
+					frame->data[i] |
+					(frame->data[i + 1] << 8));
+		}
 	}
 }
 
@@ -402,10 +416,20 @@ static int c_can_read_msg_object(struct
 	} else {
 		int i, dreg = C_CAN_IFACE(DATA1_REG, iface);
 
-		for (i = 0; i < frame->can_dlc; i += 2, dreg ++) {
-			data = priv->read_reg(priv, dreg);
-			frame->data[i] = data;
-			frame->data[i + 1] = data >> 8;
+		if (priv->type == BOSCH_D_CAN) {
+			for (i = 0; i < frame->can_dlc; i += 4, dreg += 2) {
+				data = priv->read_reg32(priv, dreg);
+				frame->data[i] = data;
+				frame->data[i + 1] = data >> 8;
+				frame->data[i + 2] = data >> 16;
+				frame->data[i + 3] = data >> 24;
+			}
+		} else {
+			for (i = 0; i < frame->can_dlc; i += 2, dreg++) {
+				data = priv->read_reg(priv, dreg);
+				frame->data[i] = data;
+				frame->data[i + 1] = data >> 8;
+			}
 		}
 	}
 
--- zfcpdump-kernel-4.4.orig/drivers/net/can/dev.c
+++ zfcpdump-kernel-4.4/drivers/net/can/dev.c
@@ -21,6 +21,7 @@
 #include <linux/slab.h>
 #include <linux/netdevice.h>
 #include <linux/if_arp.h>
+#include <linux/workqueue.h>
 #include <linux/can.h>
 #include <linux/can/dev.h>
 #include <linux/can/skb.h>
@@ -471,9 +472,8 @@ EXPORT_SYMBOL_GPL(can_free_echo_skb);
 /*
  * CAN device restart for bus-off recovery
  */
-static void can_restart(unsigned long data)
+static void can_restart(struct net_device *dev)
 {
-	struct net_device *dev = (struct net_device *)data;
 	struct can_priv *priv = netdev_priv(dev);
 	struct net_device_stats *stats = &dev->stats;
 	struct sk_buff *skb;
@@ -513,6 +513,14 @@ restart:
 		netdev_err(dev, "Error %d during restart", err);
 }
 
+static void can_restart_work(struct work_struct *work)
+{
+	struct delayed_work *dwork = to_delayed_work(work);
+	struct can_priv *priv = container_of(dwork, struct can_priv, restart_work);
+
+	can_restart(priv->dev);
+}
+
 int can_restart_now(struct net_device *dev)
 {
 	struct can_priv *priv = netdev_priv(dev);
@@ -526,8 +534,8 @@ int can_restart_now(struct net_device *d
 	if (priv->state != CAN_STATE_BUS_OFF)
 		return -EBUSY;
 
-	/* Runs as soon as possible in the timer context */
-	mod_timer(&priv->restart_timer, jiffies);
+	cancel_delayed_work_sync(&priv->restart_work);
+	can_restart(dev);
 
 	return 0;
 }
@@ -548,8 +556,8 @@ void can_bus_off(struct net_device *dev)
 	netif_carrier_off(dev);
 
 	if (priv->restart_ms)
-		mod_timer(&priv->restart_timer,
-			  jiffies + (priv->restart_ms * HZ) / 1000);
+		schedule_delayed_work(&priv->restart_work,
+				      msecs_to_jiffies(priv->restart_ms));
 }
 EXPORT_SYMBOL_GPL(can_bus_off);
 
@@ -658,6 +666,7 @@ struct net_device *alloc_candev(int size
 		return NULL;
 
 	priv = netdev_priv(dev);
+	priv->dev = dev;
 
 	if (echo_skb_max) {
 		priv->echo_skb_max = echo_skb_max;
@@ -667,7 +676,7 @@ struct net_device *alloc_candev(int size
 
 	priv->state = CAN_STATE_STOPPED;
 
-	init_timer(&priv->restart_timer);
+	INIT_DELAYED_WORK(&priv->restart_work, can_restart_work);
 
 	return dev;
 }
@@ -696,11 +705,17 @@ int can_change_mtu(struct net_device *de
 	/* allow change of MTU according to the CANFD ability of the device */
 	switch (new_mtu) {
 	case CAN_MTU:
+		/* 'CANFD-only' controllers can not switch to CAN_MTU */
+		if (priv->ctrlmode_static & CAN_CTRLMODE_FD)
+			return -EINVAL;
+
 		priv->ctrlmode &= ~CAN_CTRLMODE_FD;
 		break;
 
 	case CANFD_MTU:
-		if (!(priv->ctrlmode_supported & CAN_CTRLMODE_FD))
+		/* check for potential CANFD ability */
+		if (!(priv->ctrlmode_supported & CAN_CTRLMODE_FD) &&
+		    !(priv->ctrlmode_static & CAN_CTRLMODE_FD))
 			return -EINVAL;
 
 		priv->ctrlmode |= CAN_CTRLMODE_FD;
@@ -742,8 +757,6 @@ int open_candev(struct net_device *dev)
 	if (!netif_carrier_ok(dev))
 		netif_carrier_on(dev);
 
-	setup_timer(&priv->restart_timer, can_restart, (unsigned long)dev);
-
 	return 0;
 }
 EXPORT_SYMBOL_GPL(open_candev);
@@ -758,7 +771,7 @@ void close_candev(struct net_device *dev
 {
 	struct can_priv *priv = netdev_priv(dev);
 
-	del_timer_sync(&priv->restart_timer);
+	cancel_delayed_work_sync(&priv->restart_work);
 	can_flush_echo_skb(dev);
 }
 EXPORT_SYMBOL_GPL(close_candev);
@@ -782,6 +795,38 @@ static const struct nla_policy can_polic
 				= { .len = sizeof(struct can_bittiming_const) },
 };
 
+static int can_validate(struct nlattr *tb[], struct nlattr *data[])
+{
+	bool is_can_fd = false;
+
+	/* Make sure that valid CAN FD configurations always consist of
+	 * - nominal/arbitration bittiming
+	 * - data bittiming
+	 * - control mode with CAN_CTRLMODE_FD set
+	 */
+
+	if (!data)
+		return 0;
+
+	if (data[IFLA_CAN_CTRLMODE]) {
+		struct can_ctrlmode *cm = nla_data(data[IFLA_CAN_CTRLMODE]);
+
+		is_can_fd = cm->flags & cm->mask & CAN_CTRLMODE_FD;
+	}
+
+	if (is_can_fd) {
+		if (!data[IFLA_CAN_BITTIMING] || !data[IFLA_CAN_DATA_BITTIMING])
+			return -EOPNOTSUPP;
+	}
+
+	if (data[IFLA_CAN_DATA_BITTIMING]) {
+		if (!is_can_fd || !data[IFLA_CAN_BITTIMING])
+			return -EOPNOTSUPP;
+	}
+
+	return 0;
+}
+
 static int can_changelink(struct net_device *dev,
 			  struct nlattr *tb[], struct nlattr *data[])
 {
@@ -813,19 +858,31 @@ static int can_changelink(struct net_dev
 
 	if (data[IFLA_CAN_CTRLMODE]) {
 		struct can_ctrlmode *cm;
+		u32 ctrlstatic;
+		u32 maskedflags;
 
 		/* Do not allow changing controller mode while running */
 		if (dev->flags & IFF_UP)
 			return -EBUSY;
 		cm = nla_data(data[IFLA_CAN_CTRLMODE]);
+		ctrlstatic = priv->ctrlmode_static;
+		maskedflags = cm->flags & cm->mask;
+
+		/* check whether provided bits are allowed to be passed */
+		if (cm->mask & ~(priv->ctrlmode_supported | ctrlstatic))
+			return -EOPNOTSUPP;
 
-		/* check whether changed bits are allowed to be modified */
-		if (cm->mask & ~priv->ctrlmode_supported)
+		/* do not check for static fd-non-iso if 'fd' is disabled */
+		if (!(maskedflags & CAN_CTRLMODE_FD))
+			ctrlstatic &= ~CAN_CTRLMODE_FD_NON_ISO;
+
+		/* make sure static options are provided by configuration */
+		if ((maskedflags & ctrlstatic) != ctrlstatic)
 			return -EOPNOTSUPP;
 
 		/* clear bits to be modified and copy the flag values */
 		priv->ctrlmode &= ~cm->mask;
-		priv->ctrlmode |= (cm->flags & cm->mask);
+		priv->ctrlmode |= maskedflags;
 
 		/* CAN_CTRLMODE_FD can only be set when driver supports FD */
 		if (priv->ctrlmode & CAN_CTRLMODE_FD)
@@ -961,13 +1018,20 @@ static int can_newlink(struct net *src_n
 	return -EOPNOTSUPP;
 }
 
+static void can_dellink(struct net_device *dev, struct list_head *head)
+{
+	return;
+}
+
 static struct rtnl_link_ops can_link_ops __read_mostly = {
 	.kind		= "can",
 	.maxtype	= IFLA_CAN_MAX,
 	.policy		= can_policy,
 	.setup		= can_setup,
+	.validate	= can_validate,
 	.newlink	= can_newlink,
 	.changelink	= can_changelink,
+	.dellink	= can_dellink,
 	.get_size	= can_get_size,
 	.fill_info	= can_fill_info,
 	.get_xstats_size = can_get_xstats_size,
--- zfcpdump-kernel-4.4.orig/drivers/net/can/flexcan.c
+++ zfcpdump-kernel-4.4/drivers/net/can/flexcan.c
@@ -1268,11 +1268,10 @@ static int __maybe_unused flexcan_suspen
 	struct flexcan_priv *priv = netdev_priv(dev);
 	int err;
 
-	err = flexcan_chip_disable(priv);
-	if (err)
-		return err;
-
 	if (netif_running(dev)) {
+		err = flexcan_chip_disable(priv);
+		if (err)
+			return err;
 		netif_stop_queue(dev);
 		netif_device_detach(dev);
 	}
@@ -1285,13 +1284,17 @@ static int __maybe_unused flexcan_resume
 {
 	struct net_device *dev = dev_get_drvdata(device);
 	struct flexcan_priv *priv = netdev_priv(dev);
+	int err;
 
 	priv->can.state = CAN_STATE_ERROR_ACTIVE;
 	if (netif_running(dev)) {
 		netif_device_attach(dev);
 		netif_start_queue(dev);
+		err = flexcan_chip_enable(priv);
+		if (err)
+			return err;
 	}
-	return flexcan_chip_enable(priv);
+	return 0;
 }
 
 static SIMPLE_DEV_PM_OPS(flexcan_pm_ops, flexcan_suspend, flexcan_resume);
--- zfcpdump-kernel-4.4.orig/drivers/net/can/m_can/m_can.c
+++ zfcpdump-kernel-4.4/drivers/net/can/m_can/m_can.c
@@ -955,7 +955,7 @@ static struct net_device *alloc_m_can_de
 	priv->can.do_get_berr_counter = m_can_get_berr_counter;
 
 	/* CAN_CTRLMODE_FD_NON_ISO is fixed with M_CAN IP v3.0.1 */
-	priv->can.ctrlmode = CAN_CTRLMODE_FD_NON_ISO;
+	can_set_static_ctrlmode(dev, CAN_CTRLMODE_FD_NON_ISO);
 
 	/* CAN_CTRLMODE_FD_NON_ISO can not be changed with M_CAN IP v3.0.1 */
 	priv->can.ctrlmode_supported = CAN_CTRLMODE_LOOPBACK |
--- zfcpdump-kernel-4.4.orig/drivers/net/can/usb/ems_usb.c
+++ zfcpdump-kernel-4.4/drivers/net/can/usb/ems_usb.c
@@ -117,6 +117,9 @@ MODULE_LICENSE("GPL v2");
  */
 #define EMS_USB_ARM7_CLOCK 8000000
 
+#define CPC_TX_QUEUE_TRIGGER_LOW	25
+#define CPC_TX_QUEUE_TRIGGER_HIGH	35
+
 /*
  * CAN-Message representation in a CPC_MSG. Message object type is
  * CPC_MSG_TYPE_CAN_FRAME or CPC_MSG_TYPE_RTR_FRAME or
@@ -278,6 +281,11 @@ static void ems_usb_read_interrupt_callb
 	switch (urb->status) {
 	case 0:
 		dev->free_slots = dev->intr_in_buffer[1];
+		if(dev->free_slots > CPC_TX_QUEUE_TRIGGER_HIGH){
+			if (netif_queue_stopped(netdev)){
+				netif_wake_queue(netdev);
+			}
+		}
 		break;
 
 	case -ECONNRESET: /* unlink */
@@ -526,8 +534,6 @@ static void ems_usb_write_bulk_callback(
 	/* Release context */
 	context->echo_index = MAX_TX_URBS;
 
-	if (netif_queue_stopped(netdev))
-		netif_wake_queue(netdev);
 }
 
 /*
@@ -587,7 +593,7 @@ static int ems_usb_start(struct ems_usb
 	int err, i;
 
 	dev->intr_in_buffer[0] = 0;
-	dev->free_slots = 15; /* initial size */
+	dev->free_slots = 50; /* initial size */
 
 	for (i = 0; i < MAX_RX_URBS; i++) {
 		struct urb *urb = NULL;
@@ -835,7 +841,7 @@ static netdev_tx_t ems_usb_start_xmit(st
 
 		/* Slow down tx path */
 		if (atomic_read(&dev->active_tx_urbs) >= MAX_TX_URBS ||
-		    dev->free_slots < 5) {
+		    dev->free_slots < CPC_TX_QUEUE_TRIGGER_LOW) {
 			netif_stop_queue(netdev);
 		}
 	}
--- zfcpdump-kernel-4.4.orig/drivers/net/can/usb/gs_usb.c
+++ zfcpdump-kernel-4.4/drivers/net/can/usb/gs_usb.c
@@ -826,9 +826,8 @@ static struct gs_can *gs_make_candev(uns
 static void gs_destroy_candev(struct gs_can *dev)
 {
 	unregister_candev(dev->netdev);
-	free_candev(dev->netdev);
 	usb_kill_anchored_urbs(&dev->tx_submitted);
-	kfree(dev);
+	free_candev(dev->netdev);
 }
 
 static int gs_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
@@ -913,12 +912,15 @@ static int gs_usb_probe(struct usb_inter
 	for (i = 0; i < icount; i++) {
 		dev->canch[i] = gs_make_candev(i, intf);
 		if (IS_ERR_OR_NULL(dev->canch[i])) {
+			/* save error code to return later */
+			rc = PTR_ERR(dev->canch[i]);
+
 			/* on failure destroy previously created candevs */
 			icount = i;
-			for (i = 0; i < icount; i++) {
+			for (i = 0; i < icount; i++)
 				gs_destroy_candev(dev->canch[i]);
-				dev->canch[i] = NULL;
-			}
+
+			usb_kill_anchored_urbs(&dev->rx_submitted);
 			kfree(dev);
 			return rc;
 		}
@@ -939,16 +941,12 @@ static void gs_usb_disconnect(struct usb
 		return;
 	}
 
-	for (i = 0; i < GS_MAX_INTF; i++) {
-		struct gs_can *can = dev->canch[i];
-
-		if (!can)
-			continue;
-
-		gs_destroy_candev(can);
-	}
+	for (i = 0; i < GS_MAX_INTF; i++)
+		if (dev->canch[i])
+			gs_destroy_candev(dev->canch[i]);
 
 	usb_kill_anchored_urbs(&dev->rx_submitted);
+	kfree(dev);
 }
 
 static const struct usb_device_id gs_usb_table[] = {
--- zfcpdump-kernel-4.4.orig/drivers/net/dsa/bcm_sf2.h
+++ zfcpdump-kernel-4.4/drivers/net/dsa/bcm_sf2.h
@@ -187,8 +187,8 @@ static inline void name##_writeq(struct
 static inline void intrl2_##which##_mask_clear(struct bcm_sf2_priv *priv, \
 						u32 mask)		\
 {									\
-	intrl2_##which##_writel(priv, mask, INTRL2_CPU_MASK_CLEAR);	\
 	priv->irq##which##_mask &= ~(mask);				\
+	intrl2_##which##_writel(priv, mask, INTRL2_CPU_MASK_CLEAR);	\
 }									\
 static inline void intrl2_##which##_mask_set(struct bcm_sf2_priv *priv, \
 						u32 mask)		\
--- zfcpdump-kernel-4.4.orig/drivers/net/dsa/mv88e6xxx.c
+++ zfcpdump-kernel-4.4/drivers/net/dsa/mv88e6xxx.c
@@ -1519,7 +1519,7 @@ int mv88e6xxx_port_vlan_add(struct dsa_s
 
 	/* no PVID with ranges, otherwise it's a bug */
 	if (pvid)
-		err = _mv88e6xxx_port_pvid_set(ds, port, vid);
+		err = _mv88e6xxx_port_pvid_set(ds, port, vlan->vid_end);
 unlock:
 	mutex_unlock(&ps->smi_mutex);
 
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/Kconfig
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/Kconfig
@@ -24,6 +24,7 @@ source "drivers/net/ethernet/agere/Kconf
 source "drivers/net/ethernet/allwinner/Kconfig"
 source "drivers/net/ethernet/alteon/Kconfig"
 source "drivers/net/ethernet/altera/Kconfig"
+source "drivers/net/ethernet/amazon/Kconfig"
 source "drivers/net/ethernet/amd/Kconfig"
 source "drivers/net/ethernet/apm/Kconfig"
 source "drivers/net/ethernet/apple/Kconfig"
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/Makefile
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/Makefile
@@ -10,6 +10,7 @@ obj-$(CONFIG_NET_VENDOR_AGERE) += agere/
 obj-$(CONFIG_NET_VENDOR_ALLWINNER) += allwinner/
 obj-$(CONFIG_NET_VENDOR_ALTEON) += alteon/
 obj-$(CONFIG_ALTERA_TSE) += altera/
+obj-$(CONFIG_NET_VENDOR_AMAZON) += amazon/
 obj-$(CONFIG_NET_VENDOR_AMD) += amd/
 obj-$(CONFIG_NET_XGENE) += apm/
 obj-$(CONFIG_NET_VENDOR_APPLE) += apple/
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/amazon/Kconfig
@@ -0,0 +1,27 @@
+#
+# Amazon network device configuration
+#
+
+config NET_VENDOR_AMAZON
+	bool "Amazon Devices"
+	default y
+	---help---
+	  If you have a network (Ethernet) device belonging to this class, say Y.
+
+	  Note that the answer to this question doesn't directly affect the
+	  kernel: saying N will just cause the configurator to skip all
+	  the questions about Amazon devices. If you say Y, you will be asked
+	  for your specific device in the following questions.
+
+if NET_VENDOR_AMAZON
+
+config ENA_ETHERNET
+	tristate "Elastic Network Adapter (ENA) support"
+	depends on (PCI_MSI && X86)
+	---help---
+	  This driver supports Elastic Network Adapter (ENA)"
+
+	  To compile this driver as a module, choose M here.
+	  The module will be called ena.
+
+endif #NET_VENDOR_AMAZON
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/amazon/Makefile
@@ -0,0 +1,5 @@
+#
+# Makefile for the Amazon network device drivers.
+#
+
+obj-$(CONFIG_ENA_ETHERNET) += ena/
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/amazon/ena/Makefile
@@ -0,0 +1,7 @@
+#
+# Makefile for the Elastic Network Adapter (ENA) device drivers.
+#
+
+obj-$(CONFIG_ENA_ETHERNET) += ena.o
+
+ena-y := ena_netdev.o ena_com.o ena_eth_com.o ena_ethtool.o
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/amazon/ena/ena_admin_defs.h
@@ -0,0 +1,973 @@
+/*
+ * Copyright 2015 - 2016 Amazon.com, Inc. or its affiliates.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+#ifndef _ENA_ADMIN_H_
+#define _ENA_ADMIN_H_
+
+enum ena_admin_aq_opcode {
+	ENA_ADMIN_CREATE_SQ	= 1,
+
+	ENA_ADMIN_DESTROY_SQ	= 2,
+
+	ENA_ADMIN_CREATE_CQ	= 3,
+
+	ENA_ADMIN_DESTROY_CQ	= 4,
+
+	ENA_ADMIN_GET_FEATURE	= 8,
+
+	ENA_ADMIN_SET_FEATURE	= 9,
+
+	ENA_ADMIN_GET_STATS	= 11,
+};
+
+enum ena_admin_aq_completion_status {
+	ENA_ADMIN_SUCCESS			= 0,
+
+	ENA_ADMIN_RESOURCE_ALLOCATION_FAILURE	= 1,
+
+	ENA_ADMIN_BAD_OPCODE			= 2,
+
+	ENA_ADMIN_UNSUPPORTED_OPCODE		= 3,
+
+	ENA_ADMIN_MALFORMED_REQUEST		= 4,
+
+	/* Additional status is provided in ACQ entry extended_status */
+	ENA_ADMIN_ILLEGAL_PARAMETER		= 5,
+
+	ENA_ADMIN_UNKNOWN_ERROR			= 6,
+};
+
+enum ena_admin_aq_feature_id {
+	ENA_ADMIN_DEVICE_ATTRIBUTES		= 1,
+
+	ENA_ADMIN_MAX_QUEUES_NUM		= 2,
+
+	ENA_ADMIN_RSS_HASH_FUNCTION		= 10,
+
+	ENA_ADMIN_STATELESS_OFFLOAD_CONFIG	= 11,
+
+	ENA_ADMIN_RSS_REDIRECTION_TABLE_CONFIG	= 12,
+
+	ENA_ADMIN_MTU				= 14,
+
+	ENA_ADMIN_RSS_HASH_INPUT		= 18,
+
+	ENA_ADMIN_INTERRUPT_MODERATION		= 20,
+
+	ENA_ADMIN_AENQ_CONFIG			= 26,
+
+	ENA_ADMIN_LINK_CONFIG			= 27,
+
+	ENA_ADMIN_HOST_ATTR_CONFIG		= 28,
+
+	ENA_ADMIN_FEATURES_OPCODE_NUM		= 32,
+};
+
+enum ena_admin_placement_policy_type {
+	/* descriptors and headers are in host memory */
+	ENA_ADMIN_PLACEMENT_POLICY_HOST	= 1,
+
+	/* descriptors and headers are in device memory (a.k.a Low Latency
+	 * Queue)
+	 */
+	ENA_ADMIN_PLACEMENT_POLICY_DEV	= 3,
+};
+
+enum ena_admin_link_types {
+	ENA_ADMIN_LINK_SPEED_1G		= 0x1,
+
+	ENA_ADMIN_LINK_SPEED_2_HALF_G	= 0x2,
+
+	ENA_ADMIN_LINK_SPEED_5G		= 0x4,
+
+	ENA_ADMIN_LINK_SPEED_10G	= 0x8,
+
+	ENA_ADMIN_LINK_SPEED_25G	= 0x10,
+
+	ENA_ADMIN_LINK_SPEED_40G	= 0x20,
+
+	ENA_ADMIN_LINK_SPEED_50G	= 0x40,
+
+	ENA_ADMIN_LINK_SPEED_100G	= 0x80,
+
+	ENA_ADMIN_LINK_SPEED_200G	= 0x100,
+
+	ENA_ADMIN_LINK_SPEED_400G	= 0x200,
+};
+
+enum ena_admin_completion_policy_type {
+	/* completion queue entry for each sq descriptor */
+	ENA_ADMIN_COMPLETION_POLICY_DESC		= 0,
+
+	/* completion queue entry upon request in sq descriptor */
+	ENA_ADMIN_COMPLETION_POLICY_DESC_ON_DEMAND	= 1,
+
+	/* current queue head pointer is updated in OS memory upon sq
+	 * descriptor request
+	 */
+	ENA_ADMIN_COMPLETION_POLICY_HEAD_ON_DEMAND	= 2,
+
+	/* current queue head pointer is updated in OS memory for each sq
+	 * descriptor
+	 */
+	ENA_ADMIN_COMPLETION_POLICY_HEAD		= 3,
+};
+
+/* basic stats return ena_admin_basic_stats while extanded stats return a
+ * buffer (string format) with additional statistics per queue and per
+ * device id
+ */
+enum ena_admin_get_stats_type {
+	ENA_ADMIN_GET_STATS_TYPE_BASIC		= 0,
+
+	ENA_ADMIN_GET_STATS_TYPE_EXTENDED	= 1,
+};
+
+enum ena_admin_get_stats_scope {
+	ENA_ADMIN_SPECIFIC_QUEUE	= 0,
+
+	ENA_ADMIN_ETH_TRAFFIC		= 1,
+};
+
+struct ena_admin_aq_common_desc {
+	/* 11:0 : command_id
+	 * 15:12 : reserved12
+	 */
+	u16 command_id;
+
+	/* as appears in ena_admin_aq_opcode */
+	u8 opcode;
+
+	/* 0 : phase
+	 * 1 : ctrl_data - control buffer address valid
+	 * 2 : ctrl_data_indirect - control buffer address
+	 *    points to list of pages with addresses of control
+	 *    buffers
+	 * 7:3 : reserved3
+	 */
+	u8 flags;
+};
+
+/* used in ena_admin_aq_entry. Can point directly to control data, or to a
+ * page list chunk. Used also at the end of indirect mode page list chunks,
+ * for chaining.
+ */
+struct ena_admin_ctrl_buff_info {
+	u32 length;
+
+	struct ena_common_mem_addr address;
+};
+
+struct ena_admin_sq {
+	u16 sq_idx;
+
+	/* 4:0 : reserved
+	 * 7:5 : sq_direction - 0x1 - Tx; 0x2 - Rx
+	 */
+	u8 sq_identity;
+
+	u8 reserved1;
+};
+
+struct ena_admin_aq_entry {
+	struct ena_admin_aq_common_desc aq_common_descriptor;
+
+	union {
+		u32 inline_data_w1[3];
+
+		struct ena_admin_ctrl_buff_info control_buffer;
+	} u;
+
+	u32 inline_data_w4[12];
+};
+
+struct ena_admin_acq_common_desc {
+	/* command identifier to associate it with the aq descriptor
+	 * 11:0 : command_id
+	 * 15:12 : reserved12
+	 */
+	u16 command;
+
+	u8 status;
+
+	/* 0 : phase
+	 * 7:1 : reserved1
+	 */
+	u8 flags;
+
+	u16 extended_status;
+
+	/* serves as a hint what AQ entries can be revoked */
+	u16 sq_head_indx;
+};
+
+struct ena_admin_acq_entry {
+	struct ena_admin_acq_common_desc acq_common_descriptor;
+
+	u32 response_specific_data[14];
+};
+
+struct ena_admin_aq_create_sq_cmd {
+	struct ena_admin_aq_common_desc aq_common_descriptor;
+
+	/* 4:0 : reserved0_w1
+	 * 7:5 : sq_direction - 0x1 - Tx, 0x2 - Rx
+	 */
+	u8 sq_identity;
+
+	u8 reserved8_w1;
+
+	/* 3:0 : placement_policy - Describing where the SQ
+	 *    descriptor ring and the SQ packet headers reside:
+	 *    0x1 - descriptors and headers are in OS memory,
+	 *    0x3 - descriptors and headers in device memory
+	 *    (a.k.a Low Latency Queue)
+	 * 6:4 : completion_policy - Describing what policy
+	 *    to use for generation completion entry (cqe) in
+	 *    the CQ associated with this SQ: 0x0 - cqe for each
+	 *    sq descriptor, 0x1 - cqe upon request in sq
+	 *    descriptor, 0x2 - current queue head pointer is
+	 *    updated in OS memory upon sq descriptor request
+	 *    0x3 - current queue head pointer is updated in OS
+	 *    memory for each sq descriptor
+	 * 7 : reserved15_w1
+	 */
+	u8 sq_caps_2;
+
+	/* 0 : is_physically_contiguous - Described if the
+	 *    queue ring memory is allocated in physical
+	 *    contiguous pages or split.
+	 * 7:1 : reserved17_w1
+	 */
+	u8 sq_caps_3;
+
+	/* associated completion queue id. This CQ must be created prior to
+	 *    SQ creation
+	 */
+	u16 cq_idx;
+
+	/* submission queue depth in entries */
+	u16 sq_depth;
+
+	/* SQ physical base address in OS memory. This field should not be
+	 * used for Low Latency queues. Has to be page aligned.
+	 */
+	struct ena_common_mem_addr sq_ba;
+
+	/* specifies queue head writeback location in OS memory. Valid if
+	 * completion_policy is set to completion_policy_head_on_demand or
+	 * completion_policy_head. Has to be cache aligned
+	 */
+	struct ena_common_mem_addr sq_head_writeback;
+
+	u32 reserved0_w7;
+
+	u32 reserved0_w8;
+};
+
+enum ena_admin_sq_direction {
+	ENA_ADMIN_SQ_DIRECTION_TX	= 1,
+
+	ENA_ADMIN_SQ_DIRECTION_RX	= 2,
+};
+
+struct ena_admin_acq_create_sq_resp_desc {
+	struct ena_admin_acq_common_desc acq_common_desc;
+
+	u16 sq_idx;
+
+	u16 reserved;
+
+	/* queue doorbell address as an offset to PCIe MMIO REG BAR */
+	u32 sq_doorbell_offset;
+
+	/* low latency queue ring base address as an offset to PCIe MMIO
+	 * LLQ_MEM BAR
+	 */
+	u32 llq_descriptors_offset;
+
+	/* low latency queue headers' memory as an offset to PCIe MMIO
+	 * LLQ_MEM BAR
+	 */
+	u32 llq_headers_offset;
+};
+
+struct ena_admin_aq_destroy_sq_cmd {
+	struct ena_admin_aq_common_desc aq_common_descriptor;
+
+	struct ena_admin_sq sq;
+};
+
+struct ena_admin_acq_destroy_sq_resp_desc {
+	struct ena_admin_acq_common_desc acq_common_desc;
+};
+
+struct ena_admin_aq_create_cq_cmd {
+	struct ena_admin_aq_common_desc aq_common_descriptor;
+
+	/* 4:0 : reserved5
+	 * 5 : interrupt_mode_enabled - if set, cq operates
+	 *    in interrupt mode, otherwise - polling
+	 * 7:6 : reserved6
+	 */
+	u8 cq_caps_1;
+
+	/* 4:0 : cq_entry_size_words - size of CQ entry in
+	 *    32-bit words, valid values: 4, 8.
+	 * 7:5 : reserved7
+	 */
+	u8 cq_caps_2;
+
+	/* completion queue depth in # of entries. must be power of 2 */
+	u16 cq_depth;
+
+	/* msix vector assigned to this cq */
+	u32 msix_vector;
+
+	/* cq physical base address in OS memory. CQ must be physically
+	 * contiguous
+	 */
+	struct ena_common_mem_addr cq_ba;
+};
+
+struct ena_admin_acq_create_cq_resp_desc {
+	struct ena_admin_acq_common_desc acq_common_desc;
+
+	u16 cq_idx;
+
+	/* actual cq depth in number of entries */
+	u16 cq_actual_depth;
+
+	u32 numa_node_register_offset;
+
+	u32 cq_head_db_register_offset;
+
+	u32 cq_interrupt_unmask_register_offset;
+};
+
+struct ena_admin_aq_destroy_cq_cmd {
+	struct ena_admin_aq_common_desc aq_common_descriptor;
+
+	u16 cq_idx;
+
+	u16 reserved1;
+};
+
+struct ena_admin_acq_destroy_cq_resp_desc {
+	struct ena_admin_acq_common_desc acq_common_desc;
+};
+
+/* ENA AQ Get Statistics command. Extended statistics are placed in control
+ * buffer pointed by AQ entry
+ */
+struct ena_admin_aq_get_stats_cmd {
+	struct ena_admin_aq_common_desc aq_common_descriptor;
+
+	union {
+		/* command specific inline data */
+		u32 inline_data_w1[3];
+
+		struct ena_admin_ctrl_buff_info control_buffer;
+	} u;
+
+	/* stats type as defined in enum ena_admin_get_stats_type */
+	u8 type;
+
+	/* stats scope defined in enum ena_admin_get_stats_scope */
+	u8 scope;
+
+	u16 reserved3;
+
+	/* queue id. used when scope is specific_queue */
+	u16 queue_idx;
+
+	/* device id, value 0xFFFF means mine. only privileged device can get
+	 *    stats of other device
+	 */
+	u16 device_id;
+};
+
+/* Basic Statistics Command. */
+struct ena_admin_basic_stats {
+	u32 tx_bytes_low;
+
+	u32 tx_bytes_high;
+
+	u32 tx_pkts_low;
+
+	u32 tx_pkts_high;
+
+	u32 rx_bytes_low;
+
+	u32 rx_bytes_high;
+
+	u32 rx_pkts_low;
+
+	u32 rx_pkts_high;
+
+	u32 rx_drops_low;
+
+	u32 rx_drops_high;
+};
+
+struct ena_admin_acq_get_stats_resp {
+	struct ena_admin_acq_common_desc acq_common_desc;
+
+	struct ena_admin_basic_stats basic_stats;
+};
+
+struct ena_admin_get_set_feature_common_desc {
+	/* 1:0 : select - 0x1 - current value; 0x3 - default
+	 *    value
+	 * 7:3 : reserved3
+	 */
+	u8 flags;
+
+	/* as appears in ena_admin_aq_feature_id */
+	u8 feature_id;
+
+	u16 reserved16;
+};
+
+struct ena_admin_device_attr_feature_desc {
+	u32 impl_id;
+
+	u32 device_version;
+
+	/* bitmap of ena_admin_aq_feature_id */
+	u32 supported_features;
+
+	u32 reserved3;
+
+	/* Indicates how many bits are used physical address access. */
+	u32 phys_addr_width;
+
+	/* Indicates how many bits are used virtual address access. */
+	u32 virt_addr_width;
+
+	/* unicast MAC address (in Network byte order) */
+	u8 mac_addr[6];
+
+	u8 reserved7[2];
+
+	u32 max_mtu;
+};
+
+struct ena_admin_queue_feature_desc {
+	/* including LLQs */
+	u32 max_sq_num;
+
+	u32 max_sq_depth;
+
+	u32 max_cq_num;
+
+	u32 max_cq_depth;
+
+	u32 max_llq_num;
+
+	u32 max_llq_depth;
+
+	u32 max_header_size;
+
+	/* Maximum Descriptors number, including meta descriptor, allowed for
+	 *    a single Tx packet
+	 */
+	u16 max_packet_tx_descs;
+
+	/* Maximum Descriptors number allowed for a single Rx packet */
+	u16 max_packet_rx_descs;
+};
+
+struct ena_admin_set_feature_mtu_desc {
+	/* exclude L2 */
+	u32 mtu;
+};
+
+struct ena_admin_set_feature_host_attr_desc {
+	/* host OS info base address in OS memory. host info is 4KB of
+	 * physically contiguous
+	 */
+	struct ena_common_mem_addr os_info_ba;
+
+	/* host debug area base address in OS memory. debug area must be
+	 * physically contiguous
+	 */
+	struct ena_common_mem_addr debug_ba;
+
+	/* debug area size */
+	u32 debug_area_size;
+};
+
+struct ena_admin_feature_intr_moder_desc {
+	/* interrupt delay granularity in usec */
+	u16 intr_delay_resolution;
+
+	u16 reserved;
+};
+
+struct ena_admin_get_feature_link_desc {
+	/* Link speed in Mb */
+	u32 speed;
+
+	/* bit field of enum ena_admin_link types */
+	u32 supported;
+
+	/* 0 : autoneg
+	 * 1 : duplex - Full Duplex
+	 * 31:2 : reserved2
+	 */
+	u32 flags;
+};
+
+struct ena_admin_feature_aenq_desc {
+	/* bitmask for AENQ groups the device can report */
+	u32 supported_groups;
+
+	/* bitmask for AENQ groups to report */
+	u32 enabled_groups;
+};
+
+struct ena_admin_feature_offload_desc {
+	/* 0 : TX_L3_csum_ipv4
+	 * 1 : TX_L4_ipv4_csum_part - The checksum field
+	 *    should be initialized with pseudo header checksum
+	 * 2 : TX_L4_ipv4_csum_full
+	 * 3 : TX_L4_ipv6_csum_part - The checksum field
+	 *    should be initialized with pseudo header checksum
+	 * 4 : TX_L4_ipv6_csum_full
+	 * 5 : tso_ipv4
+	 * 6 : tso_ipv6
+	 * 7 : tso_ecn
+	 */
+	u32 tx;
+
+	/* Receive side supported stateless offload
+	 * 0 : RX_L3_csum_ipv4 - IPv4 checksum
+	 * 1 : RX_L4_ipv4_csum - TCP/UDP/IPv4 checksum
+	 * 2 : RX_L4_ipv6_csum - TCP/UDP/IPv6 checksum
+	 * 3 : RX_hash - Hash calculation
+	 */
+	u32 rx_supported;
+
+	u32 rx_enabled;
+};
+
+enum ena_admin_hash_functions {
+	ENA_ADMIN_TOEPLITZ	= 1,
+
+	ENA_ADMIN_CRC32		= 2,
+};
+
+struct ena_admin_feature_rss_flow_hash_control {
+	u32 keys_num;
+
+	u32 reserved;
+
+	u32 key[10];
+};
+
+struct ena_admin_feature_rss_flow_hash_function {
+	/* 7:0 : funcs - bitmask of ena_admin_hash_functions */
+	u32 supported_func;
+
+	/* 7:0 : selected_func - bitmask of
+	 *    ena_admin_hash_functions
+	 */
+	u32 selected_func;
+
+	/* initial value */
+	u32 init_val;
+};
+
+/* RSS flow hash protocols */
+enum ena_admin_flow_hash_proto {
+	ENA_ADMIN_RSS_TCP4	= 0,
+
+	ENA_ADMIN_RSS_UDP4	= 1,
+
+	ENA_ADMIN_RSS_TCP6	= 2,
+
+	ENA_ADMIN_RSS_UDP6	= 3,
+
+	ENA_ADMIN_RSS_IP4	= 4,
+
+	ENA_ADMIN_RSS_IP6	= 5,
+
+	ENA_ADMIN_RSS_IP4_FRAG	= 6,
+
+	ENA_ADMIN_RSS_NOT_IP	= 7,
+
+	ENA_ADMIN_RSS_PROTO_NUM	= 16,
+};
+
+/* RSS flow hash fields */
+enum ena_admin_flow_hash_fields {
+	/* Ethernet Dest Addr */
+	ENA_ADMIN_RSS_L2_DA	= 0,
+
+	/* Ethernet Src Addr */
+	ENA_ADMIN_RSS_L2_SA	= 1,
+
+	/* ipv4/6 Dest Addr */
+	ENA_ADMIN_RSS_L3_DA	= 2,
+
+	/* ipv4/6 Src Addr */
+	ENA_ADMIN_RSS_L3_SA	= 5,
+
+	/* tcp/udp Dest Port */
+	ENA_ADMIN_RSS_L4_DP	= 6,
+
+	/* tcp/udp Src Port */
+	ENA_ADMIN_RSS_L4_SP	= 7,
+};
+
+struct ena_admin_proto_input {
+	/* flow hash fields (bitwise according to ena_admin_flow_hash_fields) */
+	u16 fields;
+
+	u16 reserved2;
+};
+
+struct ena_admin_feature_rss_hash_control {
+	struct ena_admin_proto_input supported_fields[ENA_ADMIN_RSS_PROTO_NUM];
+
+	struct ena_admin_proto_input selected_fields[ENA_ADMIN_RSS_PROTO_NUM];
+
+	struct ena_admin_proto_input reserved2[ENA_ADMIN_RSS_PROTO_NUM];
+
+	struct ena_admin_proto_input reserved3[ENA_ADMIN_RSS_PROTO_NUM];
+};
+
+struct ena_admin_feature_rss_flow_hash_input {
+	/* supported hash input sorting
+	 * 1 : L3_sort - support swap L3 addresses if DA is
+	 *    smaller than SA
+	 * 2 : L4_sort - support swap L4 ports if DP smaller
+	 *    SP
+	 */
+	u16 supported_input_sort;
+
+	/* enabled hash input sorting
+	 * 1 : enable_L3_sort - enable swap L3 addresses if
+	 *    DA smaller than SA
+	 * 2 : enable_L4_sort - enable swap L4 ports if DP
+	 *    smaller than SP
+	 */
+	u16 enabled_input_sort;
+};
+
+enum ena_admin_os_type {
+	ENA_ADMIN_OS_LINUX	= 1,
+
+	ENA_ADMIN_OS_WIN	= 2,
+
+	ENA_ADMIN_OS_DPDK	= 3,
+
+	ENA_ADMIN_OS_FREEBSD	= 4,
+
+	ENA_ADMIN_OS_IPXE	= 5,
+};
+
+struct ena_admin_host_info {
+	/* defined in enum ena_admin_os_type */
+	u32 os_type;
+
+	/* os distribution string format */
+	u8 os_dist_str[128];
+
+	/* OS distribution numeric format */
+	u32 os_dist;
+
+	/* kernel version string format */
+	u8 kernel_ver_str[32];
+
+	/* Kernel version numeric format */
+	u32 kernel_ver;
+
+	/* 7:0 : major
+	 * 15:8 : minor
+	 * 23:16 : sub_minor
+	 */
+	u32 driver_version;
+
+	/* features bitmap */
+	u32 supported_network_features[4];
+};
+
+struct ena_admin_rss_ind_table_entry {
+	u16 cq_idx;
+
+	u16 reserved;
+};
+
+struct ena_admin_feature_rss_ind_table {
+	/* min supported table size (2^min_size) */
+	u16 min_size;
+
+	/* max supported table size (2^max_size) */
+	u16 max_size;
+
+	/* table size (2^size) */
+	u16 size;
+
+	u16 reserved;
+
+	/* index of the inline entry. 0xFFFFFFFF means invalid */
+	u32 inline_index;
+
+	/* used for updating single entry, ignored when setting the entire
+	 * table through the control buffer.
+	 */
+	struct ena_admin_rss_ind_table_entry inline_entry;
+};
+
+struct ena_admin_get_feat_cmd {
+	struct ena_admin_aq_common_desc aq_common_descriptor;
+
+	struct ena_admin_ctrl_buff_info control_buffer;
+
+	struct ena_admin_get_set_feature_common_desc feat_common;
+
+	u32 raw[11];
+};
+
+struct ena_admin_get_feat_resp {
+	struct ena_admin_acq_common_desc acq_common_desc;
+
+	union {
+		u32 raw[14];
+
+		struct ena_admin_device_attr_feature_desc dev_attr;
+
+		struct ena_admin_queue_feature_desc max_queue;
+
+		struct ena_admin_feature_aenq_desc aenq;
+
+		struct ena_admin_get_feature_link_desc link;
+
+		struct ena_admin_feature_offload_desc offload;
+
+		struct ena_admin_feature_rss_flow_hash_function flow_hash_func;
+
+		struct ena_admin_feature_rss_flow_hash_input flow_hash_input;
+
+		struct ena_admin_feature_rss_ind_table ind_table;
+
+		struct ena_admin_feature_intr_moder_desc intr_moderation;
+	} u;
+};
+
+struct ena_admin_set_feat_cmd {
+	struct ena_admin_aq_common_desc aq_common_descriptor;
+
+	struct ena_admin_ctrl_buff_info control_buffer;
+
+	struct ena_admin_get_set_feature_common_desc feat_common;
+
+	union {
+		u32 raw[11];
+
+		/* mtu size */
+		struct ena_admin_set_feature_mtu_desc mtu;
+
+		/* host attributes */
+		struct ena_admin_set_feature_host_attr_desc host_attr;
+
+		/* AENQ configuration */
+		struct ena_admin_feature_aenq_desc aenq;
+
+		/* rss flow hash function */
+		struct ena_admin_feature_rss_flow_hash_function flow_hash_func;
+
+		/* rss flow hash input */
+		struct ena_admin_feature_rss_flow_hash_input flow_hash_input;
+
+		/* rss indirection table */
+		struct ena_admin_feature_rss_ind_table ind_table;
+	} u;
+};
+
+struct ena_admin_set_feat_resp {
+	struct ena_admin_acq_common_desc acq_common_desc;
+
+	union {
+		u32 raw[14];
+	} u;
+};
+
+struct ena_admin_aenq_common_desc {
+	u16 group;
+
+	u16 syndrom;
+
+	/* 0 : phase */
+	u8 flags;
+
+	u8 reserved1[3];
+
+	u32 timestamp_low;
+
+	u32 timestamp_high;
+};
+
+/* asynchronous event notification groups */
+enum ena_admin_aenq_group {
+	ENA_ADMIN_LINK_CHANGE		= 0,
+
+	ENA_ADMIN_FATAL_ERROR		= 1,
+
+	ENA_ADMIN_WARNING		= 2,
+
+	ENA_ADMIN_NOTIFICATION		= 3,
+
+	ENA_ADMIN_KEEP_ALIVE		= 4,
+
+	ENA_ADMIN_AENQ_GROUPS_NUM	= 5,
+};
+
+enum ena_admin_aenq_notification_syndrom {
+	ENA_ADMIN_SUSPEND	= 0,
+
+	ENA_ADMIN_RESUME	= 1,
+};
+
+struct ena_admin_aenq_entry {
+	struct ena_admin_aenq_common_desc aenq_common_desc;
+
+	/* command specific inline data */
+	u32 inline_data_w4[12];
+};
+
+struct ena_admin_aenq_link_change_desc {
+	struct ena_admin_aenq_common_desc aenq_common_desc;
+
+	/* 0 : link_status */
+	u32 flags;
+};
+
+struct ena_admin_ena_mmio_req_read_less_resp {
+	u16 req_id;
+
+	u16 reg_off;
+
+	/* value is valid when poll is cleared */
+	u32 reg_val;
+};
+
+/* aq_common_desc */
+#define ENA_ADMIN_AQ_COMMON_DESC_COMMAND_ID_MASK GENMASK(11, 0)
+#define ENA_ADMIN_AQ_COMMON_DESC_PHASE_MASK BIT(0)
+#define ENA_ADMIN_AQ_COMMON_DESC_CTRL_DATA_SHIFT 1
+#define ENA_ADMIN_AQ_COMMON_DESC_CTRL_DATA_MASK BIT(1)
+#define ENA_ADMIN_AQ_COMMON_DESC_CTRL_DATA_INDIRECT_SHIFT 2
+#define ENA_ADMIN_AQ_COMMON_DESC_CTRL_DATA_INDIRECT_MASK BIT(2)
+
+/* sq */
+#define ENA_ADMIN_SQ_SQ_DIRECTION_SHIFT 5
+#define ENA_ADMIN_SQ_SQ_DIRECTION_MASK GENMASK(7, 5)
+
+/* acq_common_desc */
+#define ENA_ADMIN_ACQ_COMMON_DESC_COMMAND_ID_MASK GENMASK(11, 0)
+#define ENA_ADMIN_ACQ_COMMON_DESC_PHASE_MASK BIT(0)
+
+/* aq_create_sq_cmd */
+#define ENA_ADMIN_AQ_CREATE_SQ_CMD_SQ_DIRECTION_SHIFT 5
+#define ENA_ADMIN_AQ_CREATE_SQ_CMD_SQ_DIRECTION_MASK GENMASK(7, 5)
+#define ENA_ADMIN_AQ_CREATE_SQ_CMD_PLACEMENT_POLICY_MASK GENMASK(3, 0)
+#define ENA_ADMIN_AQ_CREATE_SQ_CMD_COMPLETION_POLICY_SHIFT 4
+#define ENA_ADMIN_AQ_CREATE_SQ_CMD_COMPLETION_POLICY_MASK GENMASK(6, 4)
+#define ENA_ADMIN_AQ_CREATE_SQ_CMD_IS_PHYSICALLY_CONTIGUOUS_MASK BIT(0)
+
+/* aq_create_cq_cmd */
+#define ENA_ADMIN_AQ_CREATE_CQ_CMD_INTERRUPT_MODE_ENABLED_SHIFT 5
+#define ENA_ADMIN_AQ_CREATE_CQ_CMD_INTERRUPT_MODE_ENABLED_MASK BIT(5)
+#define ENA_ADMIN_AQ_CREATE_CQ_CMD_CQ_ENTRY_SIZE_WORDS_MASK GENMASK(4, 0)
+
+/* get_set_feature_common_desc */
+#define ENA_ADMIN_GET_SET_FEATURE_COMMON_DESC_SELECT_MASK GENMASK(1, 0)
+
+/* get_feature_link_desc */
+#define ENA_ADMIN_GET_FEATURE_LINK_DESC_AUTONEG_MASK BIT(0)
+#define ENA_ADMIN_GET_FEATURE_LINK_DESC_DUPLEX_SHIFT 1
+#define ENA_ADMIN_GET_FEATURE_LINK_DESC_DUPLEX_MASK BIT(1)
+
+/* feature_offload_desc */
+#define ENA_ADMIN_FEATURE_OFFLOAD_DESC_TX_L3_CSUM_IPV4_MASK BIT(0)
+#define ENA_ADMIN_FEATURE_OFFLOAD_DESC_TX_L4_IPV4_CSUM_PART_SHIFT 1
+#define ENA_ADMIN_FEATURE_OFFLOAD_DESC_TX_L4_IPV4_CSUM_PART_MASK BIT(1)
+#define ENA_ADMIN_FEATURE_OFFLOAD_DESC_TX_L4_IPV4_CSUM_FULL_SHIFT 2
+#define ENA_ADMIN_FEATURE_OFFLOAD_DESC_TX_L4_IPV4_CSUM_FULL_MASK BIT(2)
+#define ENA_ADMIN_FEATURE_OFFLOAD_DESC_TX_L4_IPV6_CSUM_PART_SHIFT 3
+#define ENA_ADMIN_FEATURE_OFFLOAD_DESC_TX_L4_IPV6_CSUM_PART_MASK BIT(3)
+#define ENA_ADMIN_FEATURE_OFFLOAD_DESC_TX_L4_IPV6_CSUM_FULL_SHIFT 4
+#define ENA_ADMIN_FEATURE_OFFLOAD_DESC_TX_L4_IPV6_CSUM_FULL_MASK BIT(4)
+#define ENA_ADMIN_FEATURE_OFFLOAD_DESC_TSO_IPV4_SHIFT 5
+#define ENA_ADMIN_FEATURE_OFFLOAD_DESC_TSO_IPV4_MASK BIT(5)
+#define ENA_ADMIN_FEATURE_OFFLOAD_DESC_TSO_IPV6_SHIFT 6
+#define ENA_ADMIN_FEATURE_OFFLOAD_DESC_TSO_IPV6_MASK BIT(6)
+#define ENA_ADMIN_FEATURE_OFFLOAD_DESC_TSO_ECN_SHIFT 7
+#define ENA_ADMIN_FEATURE_OFFLOAD_DESC_TSO_ECN_MASK BIT(7)
+#define ENA_ADMIN_FEATURE_OFFLOAD_DESC_RX_L3_CSUM_IPV4_MASK BIT(0)
+#define ENA_ADMIN_FEATURE_OFFLOAD_DESC_RX_L4_IPV4_CSUM_SHIFT 1
+#define ENA_ADMIN_FEATURE_OFFLOAD_DESC_RX_L4_IPV4_CSUM_MASK BIT(1)
+#define ENA_ADMIN_FEATURE_OFFLOAD_DESC_RX_L4_IPV6_CSUM_SHIFT 2
+#define ENA_ADMIN_FEATURE_OFFLOAD_DESC_RX_L4_IPV6_CSUM_MASK BIT(2)
+#define ENA_ADMIN_FEATURE_OFFLOAD_DESC_RX_HASH_SHIFT 3
+#define ENA_ADMIN_FEATURE_OFFLOAD_DESC_RX_HASH_MASK BIT(3)
+
+/* feature_rss_flow_hash_function */
+#define ENA_ADMIN_FEATURE_RSS_FLOW_HASH_FUNCTION_FUNCS_MASK GENMASK(7, 0)
+#define ENA_ADMIN_FEATURE_RSS_FLOW_HASH_FUNCTION_SELECTED_FUNC_MASK GENMASK(7, 0)
+
+/* feature_rss_flow_hash_input */
+#define ENA_ADMIN_FEATURE_RSS_FLOW_HASH_INPUT_L3_SORT_SHIFT 1
+#define ENA_ADMIN_FEATURE_RSS_FLOW_HASH_INPUT_L3_SORT_MASK BIT(1)
+#define ENA_ADMIN_FEATURE_RSS_FLOW_HASH_INPUT_L4_SORT_SHIFT 2
+#define ENA_ADMIN_FEATURE_RSS_FLOW_HASH_INPUT_L4_SORT_MASK BIT(2)
+#define ENA_ADMIN_FEATURE_RSS_FLOW_HASH_INPUT_ENABLE_L3_SORT_SHIFT 1
+#define ENA_ADMIN_FEATURE_RSS_FLOW_HASH_INPUT_ENABLE_L3_SORT_MASK BIT(1)
+#define ENA_ADMIN_FEATURE_RSS_FLOW_HASH_INPUT_ENABLE_L4_SORT_SHIFT 2
+#define ENA_ADMIN_FEATURE_RSS_FLOW_HASH_INPUT_ENABLE_L4_SORT_MASK BIT(2)
+
+/* host_info */
+#define ENA_ADMIN_HOST_INFO_MAJOR_MASK GENMASK(7, 0)
+#define ENA_ADMIN_HOST_INFO_MINOR_SHIFT 8
+#define ENA_ADMIN_HOST_INFO_MINOR_MASK GENMASK(15, 8)
+#define ENA_ADMIN_HOST_INFO_SUB_MINOR_SHIFT 16
+#define ENA_ADMIN_HOST_INFO_SUB_MINOR_MASK GENMASK(23, 16)
+
+/* aenq_common_desc */
+#define ENA_ADMIN_AENQ_COMMON_DESC_PHASE_MASK BIT(0)
+
+/* aenq_link_change_desc */
+#define ENA_ADMIN_AENQ_LINK_CHANGE_DESC_LINK_STATUS_MASK BIT(0)
+
+#endif /*_ENA_ADMIN_H_ */
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/amazon/ena/ena_com.c
@@ -0,0 +1,2666 @@
+/*
+ * Copyright 2015 Amazon.com, Inc. or its affiliates.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include "ena_com.h"
+
+/*****************************************************************************/
+/*****************************************************************************/
+
+/* Timeout in micro-sec */
+#define ADMIN_CMD_TIMEOUT_US (1000000)
+
+#define ENA_ASYNC_QUEUE_DEPTH 4
+#define ENA_ADMIN_QUEUE_DEPTH 32
+
+#define MIN_ENA_VER (((ENA_COMMON_SPEC_VERSION_MAJOR) << \
+		ENA_REGS_VERSION_MAJOR_VERSION_SHIFT) \
+		| (ENA_COMMON_SPEC_VERSION_MINOR))
+
+#define ENA_CTRL_MAJOR		0
+#define ENA_CTRL_MINOR		0
+#define ENA_CTRL_SUB_MINOR	1
+
+#define MIN_ENA_CTRL_VER \
+	(((ENA_CTRL_MAJOR) << \
+	(ENA_REGS_CONTROLLER_VERSION_MAJOR_VERSION_SHIFT)) | \
+	((ENA_CTRL_MINOR) << \
+	(ENA_REGS_CONTROLLER_VERSION_MINOR_VERSION_SHIFT)) | \
+	(ENA_CTRL_SUB_MINOR))
+
+#define ENA_DMA_ADDR_TO_UINT32_LOW(x)	((u32)((u64)(x)))
+#define ENA_DMA_ADDR_TO_UINT32_HIGH(x)	((u32)(((u64)(x)) >> 32))
+
+#define ENA_MMIO_READ_TIMEOUT 0xFFFFFFFF
+
+/*****************************************************************************/
+/*****************************************************************************/
+/*****************************************************************************/
+
+enum ena_cmd_status {
+	ENA_CMD_SUBMITTED,
+	ENA_CMD_COMPLETED,
+	/* Abort - canceled by the driver */
+	ENA_CMD_ABORTED,
+};
+
+struct ena_comp_ctx {
+	struct completion wait_event;
+	struct ena_admin_acq_entry *user_cqe;
+	u32 comp_size;
+	enum ena_cmd_status status;
+	/* status from the device */
+	u8 comp_status;
+	u8 cmd_opcode;
+	bool occupied;
+};
+
+struct ena_com_stats_ctx {
+	struct ena_admin_aq_get_stats_cmd get_cmd;
+	struct ena_admin_acq_get_stats_resp get_resp;
+};
+
+static inline int ena_com_mem_addr_set(struct ena_com_dev *ena_dev,
+				       struct ena_common_mem_addr *ena_addr,
+				       dma_addr_t addr)
+{
+	if ((addr & GENMASK_ULL(ena_dev->dma_addr_bits - 1, 0)) != addr) {
+		pr_err("dma address has more bits that the device supports\n");
+		return -EINVAL;
+	}
+
+	ena_addr->mem_addr_low = (u32)addr;
+	ena_addr->mem_addr_high = (u64)addr >> 32;
+
+	return 0;
+}
+
+static int ena_com_admin_init_sq(struct ena_com_admin_queue *queue)
+{
+	struct ena_com_admin_sq *sq = &queue->sq;
+	u16 size = ADMIN_SQ_SIZE(queue->q_depth);
+
+	sq->entries = dma_zalloc_coherent(queue->q_dmadev, size, &sq->dma_addr,
+					  GFP_KERNEL);
+
+	if (!sq->entries) {
+		pr_err("memory allocation failed");
+		return -ENOMEM;
+	}
+
+	sq->head = 0;
+	sq->tail = 0;
+	sq->phase = 1;
+
+	sq->db_addr = NULL;
+
+	return 0;
+}
+
+static int ena_com_admin_init_cq(struct ena_com_admin_queue *queue)
+{
+	struct ena_com_admin_cq *cq = &queue->cq;
+	u16 size = ADMIN_CQ_SIZE(queue->q_depth);
+
+	cq->entries = dma_zalloc_coherent(queue->q_dmadev, size, &cq->dma_addr,
+					  GFP_KERNEL);
+
+	if (!cq->entries) {
+		pr_err("memory allocation failed");
+		return -ENOMEM;
+	}
+
+	cq->head = 0;
+	cq->phase = 1;
+
+	return 0;
+}
+
+static int ena_com_admin_init_aenq(struct ena_com_dev *dev,
+				   struct ena_aenq_handlers *aenq_handlers)
+{
+	struct ena_com_aenq *aenq = &dev->aenq;
+	u32 addr_low, addr_high, aenq_caps;
+	u16 size;
+
+	dev->aenq.q_depth = ENA_ASYNC_QUEUE_DEPTH;
+	size = ADMIN_AENQ_SIZE(ENA_ASYNC_QUEUE_DEPTH);
+	aenq->entries = dma_zalloc_coherent(dev->dmadev, size, &aenq->dma_addr,
+					    GFP_KERNEL);
+
+	if (!aenq->entries) {
+		pr_err("memory allocation failed");
+		return -ENOMEM;
+	}
+
+	aenq->head = aenq->q_depth;
+	aenq->phase = 1;
+
+	addr_low = ENA_DMA_ADDR_TO_UINT32_LOW(aenq->dma_addr);
+	addr_high = ENA_DMA_ADDR_TO_UINT32_HIGH(aenq->dma_addr);
+
+	writel(addr_low, dev->reg_bar + ENA_REGS_AENQ_BASE_LO_OFF);
+	writel(addr_high, dev->reg_bar + ENA_REGS_AENQ_BASE_HI_OFF);
+
+	aenq_caps = 0;
+	aenq_caps |= dev->aenq.q_depth & ENA_REGS_AENQ_CAPS_AENQ_DEPTH_MASK;
+	aenq_caps |= (sizeof(struct ena_admin_aenq_entry)
+		      << ENA_REGS_AENQ_CAPS_AENQ_ENTRY_SIZE_SHIFT) &
+		     ENA_REGS_AENQ_CAPS_AENQ_ENTRY_SIZE_MASK;
+	writel(aenq_caps, dev->reg_bar + ENA_REGS_AENQ_CAPS_OFF);
+
+	if (unlikely(!aenq_handlers)) {
+		pr_err("aenq handlers pointer is NULL\n");
+		return -EINVAL;
+	}
+
+	aenq->aenq_handlers = aenq_handlers;
+
+	return 0;
+}
+
+static inline void comp_ctxt_release(struct ena_com_admin_queue *queue,
+				     struct ena_comp_ctx *comp_ctx)
+{
+	comp_ctx->occupied = false;
+	atomic_dec(&queue->outstanding_cmds);
+}
+
+static struct ena_comp_ctx *get_comp_ctxt(struct ena_com_admin_queue *queue,
+					  u16 command_id, bool capture)
+{
+	if (unlikely(command_id >= queue->q_depth)) {
+		pr_err("command id is larger than the queue size. cmd_id: %u queue size %d\n",
+		       command_id, queue->q_depth);
+		return NULL;
+	}
+
+	if (unlikely(queue->comp_ctx[command_id].occupied && capture)) {
+		pr_err("Completion context is occupied\n");
+		return NULL;
+	}
+
+	if (capture) {
+		atomic_inc(&queue->outstanding_cmds);
+		queue->comp_ctx[command_id].occupied = true;
+	}
+
+	return &queue->comp_ctx[command_id];
+}
+
+static struct ena_comp_ctx *__ena_com_submit_admin_cmd(struct ena_com_admin_queue *admin_queue,
+						       struct ena_admin_aq_entry *cmd,
+						       size_t cmd_size_in_bytes,
+						       struct ena_admin_acq_entry *comp,
+						       size_t comp_size_in_bytes)
+{
+	struct ena_comp_ctx *comp_ctx;
+	u16 tail_masked, cmd_id;
+	u16 queue_size_mask;
+	u16 cnt;
+
+	queue_size_mask = admin_queue->q_depth - 1;
+
+	tail_masked = admin_queue->sq.tail & queue_size_mask;
+
+	/* In case of queue FULL */
+	cnt = admin_queue->sq.tail - admin_queue->sq.head;
+	if (cnt >= admin_queue->q_depth) {
+		pr_debug("admin queue is FULL (tail %d head %d depth: %d)\n",
+			 admin_queue->sq.tail, admin_queue->sq.head,
+			 admin_queue->q_depth);
+		admin_queue->stats.out_of_space++;
+		return ERR_PTR(-ENOSPC);
+	}
+
+	cmd_id = admin_queue->curr_cmd_id;
+
+	cmd->aq_common_descriptor.flags |= admin_queue->sq.phase &
+		ENA_ADMIN_AQ_COMMON_DESC_PHASE_MASK;
+
+	cmd->aq_common_descriptor.command_id |= cmd_id &
+		ENA_ADMIN_AQ_COMMON_DESC_COMMAND_ID_MASK;
+
+	comp_ctx = get_comp_ctxt(admin_queue, cmd_id, true);
+	if (unlikely(!comp_ctx))
+		return ERR_PTR(-EINVAL);
+
+	comp_ctx->status = ENA_CMD_SUBMITTED;
+	comp_ctx->comp_size = (u32)comp_size_in_bytes;
+	comp_ctx->user_cqe = comp;
+	comp_ctx->cmd_opcode = cmd->aq_common_descriptor.opcode;
+
+	reinit_completion(&comp_ctx->wait_event);
+
+	memcpy(&admin_queue->sq.entries[tail_masked], cmd, cmd_size_in_bytes);
+
+	admin_queue->curr_cmd_id = (admin_queue->curr_cmd_id + 1) &
+		queue_size_mask;
+
+	admin_queue->sq.tail++;
+	admin_queue->stats.submitted_cmd++;
+
+	if (unlikely((admin_queue->sq.tail & queue_size_mask) == 0))
+		admin_queue->sq.phase = !admin_queue->sq.phase;
+
+	writel(admin_queue->sq.tail, admin_queue->sq.db_addr);
+
+	return comp_ctx;
+}
+
+static inline int ena_com_init_comp_ctxt(struct ena_com_admin_queue *queue)
+{
+	size_t size = queue->q_depth * sizeof(struct ena_comp_ctx);
+	struct ena_comp_ctx *comp_ctx;
+	u16 i;
+
+	queue->comp_ctx = devm_kzalloc(queue->q_dmadev, size, GFP_KERNEL);
+	if (unlikely(!queue->comp_ctx)) {
+		pr_err("memory allocation failed");
+		return -ENOMEM;
+	}
+
+	for (i = 0; i < queue->q_depth; i++) {
+		comp_ctx = get_comp_ctxt(queue, i, false);
+		if (comp_ctx)
+			init_completion(&comp_ctx->wait_event);
+	}
+
+	return 0;
+}
+
+static struct ena_comp_ctx *ena_com_submit_admin_cmd(struct ena_com_admin_queue *admin_queue,
+						     struct ena_admin_aq_entry *cmd,
+						     size_t cmd_size_in_bytes,
+						     struct ena_admin_acq_entry *comp,
+						     size_t comp_size_in_bytes)
+{
+	unsigned long flags;
+	struct ena_comp_ctx *comp_ctx;
+
+	spin_lock_irqsave(&admin_queue->q_lock, flags);
+	if (unlikely(!admin_queue->running_state)) {
+		spin_unlock_irqrestore(&admin_queue->q_lock, flags);
+		return ERR_PTR(-ENODEV);
+	}
+	comp_ctx = __ena_com_submit_admin_cmd(admin_queue, cmd,
+					      cmd_size_in_bytes,
+					      comp,
+					      comp_size_in_bytes);
+	if (unlikely(IS_ERR(comp_ctx)))
+		admin_queue->running_state = false;
+	spin_unlock_irqrestore(&admin_queue->q_lock, flags);
+
+	return comp_ctx;
+}
+
+static int ena_com_init_io_sq(struct ena_com_dev *ena_dev,
+			      struct ena_com_create_io_ctx *ctx,
+			      struct ena_com_io_sq *io_sq)
+{
+	size_t size;
+	int dev_node = 0;
+
+	memset(&io_sq->desc_addr, 0x0, sizeof(struct ena_com_io_desc_addr));
+
+	io_sq->desc_entry_size =
+		(io_sq->direction == ENA_COM_IO_QUEUE_DIRECTION_TX) ?
+		sizeof(struct ena_eth_io_tx_desc) :
+		sizeof(struct ena_eth_io_rx_desc);
+
+	size = io_sq->desc_entry_size * io_sq->q_depth;
+
+	if (io_sq->mem_queue_type == ENA_ADMIN_PLACEMENT_POLICY_HOST) {
+		dev_node = dev_to_node(ena_dev->dmadev);
+		set_dev_node(ena_dev->dmadev, ctx->numa_node);
+		io_sq->desc_addr.virt_addr =
+			dma_zalloc_coherent(ena_dev->dmadev, size,
+					    &io_sq->desc_addr.phys_addr,
+					    GFP_KERNEL);
+		set_dev_node(ena_dev->dmadev, dev_node);
+		if (!io_sq->desc_addr.virt_addr) {
+			io_sq->desc_addr.virt_addr =
+				dma_zalloc_coherent(ena_dev->dmadev, size,
+						    &io_sq->desc_addr.phys_addr,
+						    GFP_KERNEL);
+		}
+	} else {
+		dev_node = dev_to_node(ena_dev->dmadev);
+		set_dev_node(ena_dev->dmadev, ctx->numa_node);
+		io_sq->desc_addr.virt_addr =
+			devm_kzalloc(ena_dev->dmadev, size, GFP_KERNEL);
+		set_dev_node(ena_dev->dmadev, dev_node);
+		if (!io_sq->desc_addr.virt_addr) {
+			io_sq->desc_addr.virt_addr =
+				devm_kzalloc(ena_dev->dmadev, size, GFP_KERNEL);
+		}
+	}
+
+	if (!io_sq->desc_addr.virt_addr) {
+		pr_err("memory allocation failed");
+		return -ENOMEM;
+	}
+
+	io_sq->tail = 0;
+	io_sq->next_to_comp = 0;
+	io_sq->phase = 1;
+
+	return 0;
+}
+
+static int ena_com_init_io_cq(struct ena_com_dev *ena_dev,
+			      struct ena_com_create_io_ctx *ctx,
+			      struct ena_com_io_cq *io_cq)
+{
+	size_t size;
+	int prev_node = 0;
+
+	memset(&io_cq->cdesc_addr, 0x0, sizeof(struct ena_com_io_desc_addr));
+
+	/* Use the basic completion descriptor for Rx */
+	io_cq->cdesc_entry_size_in_bytes =
+		(io_cq->direction == ENA_COM_IO_QUEUE_DIRECTION_TX) ?
+		sizeof(struct ena_eth_io_tx_cdesc) :
+		sizeof(struct ena_eth_io_rx_cdesc_base);
+
+	size = io_cq->cdesc_entry_size_in_bytes * io_cq->q_depth;
+
+	prev_node = dev_to_node(ena_dev->dmadev);
+	set_dev_node(ena_dev->dmadev, ctx->numa_node);
+	io_cq->cdesc_addr.virt_addr =
+		dma_zalloc_coherent(ena_dev->dmadev, size,
+				    &io_cq->cdesc_addr.phys_addr, GFP_KERNEL);
+	set_dev_node(ena_dev->dmadev, prev_node);
+	if (!io_cq->cdesc_addr.virt_addr) {
+		io_cq->cdesc_addr.virt_addr =
+			dma_zalloc_coherent(ena_dev->dmadev, size,
+					    &io_cq->cdesc_addr.phys_addr,
+					    GFP_KERNEL);
+	}
+
+	if (!io_cq->cdesc_addr.virt_addr) {
+		pr_err("memory allocation failed");
+		return -ENOMEM;
+	}
+
+	io_cq->phase = 1;
+	io_cq->head = 0;
+
+	return 0;
+}
+
+static void ena_com_handle_single_admin_completion(struct ena_com_admin_queue *admin_queue,
+						   struct ena_admin_acq_entry *cqe)
+{
+	struct ena_comp_ctx *comp_ctx;
+	u16 cmd_id;
+
+	cmd_id = cqe->acq_common_descriptor.command &
+		ENA_ADMIN_ACQ_COMMON_DESC_COMMAND_ID_MASK;
+
+	comp_ctx = get_comp_ctxt(admin_queue, cmd_id, false);
+	if (unlikely(!comp_ctx)) {
+		pr_err("comp_ctx is NULL. Changing the admin queue running state\n");
+		admin_queue->running_state = false;
+		return;
+	}
+
+	comp_ctx->status = ENA_CMD_COMPLETED;
+	comp_ctx->comp_status = cqe->acq_common_descriptor.status;
+
+	if (comp_ctx->user_cqe)
+		memcpy(comp_ctx->user_cqe, (void *)cqe, comp_ctx->comp_size);
+
+	if (!admin_queue->polling)
+		complete(&comp_ctx->wait_event);
+}
+
+static void ena_com_handle_admin_completion(struct ena_com_admin_queue *admin_queue)
+{
+	struct ena_admin_acq_entry *cqe = NULL;
+	u16 comp_num = 0;
+	u16 head_masked;
+	u8 phase;
+
+	head_masked = admin_queue->cq.head & (admin_queue->q_depth - 1);
+	phase = admin_queue->cq.phase;
+
+	cqe = &admin_queue->cq.entries[head_masked];
+
+	/* Go over all the completions */
+	while ((cqe->acq_common_descriptor.flags &
+			ENA_ADMIN_ACQ_COMMON_DESC_PHASE_MASK) == phase) {
+		/* Do not read the rest of the completion entry before the
+		 * phase bit was validated
+		 */
+		rmb();
+		ena_com_handle_single_admin_completion(admin_queue, cqe);
+
+		head_masked++;
+		comp_num++;
+		if (unlikely(head_masked == admin_queue->q_depth)) {
+			head_masked = 0;
+			phase = !phase;
+		}
+
+		cqe = &admin_queue->cq.entries[head_masked];
+	}
+
+	admin_queue->cq.head += comp_num;
+	admin_queue->cq.phase = phase;
+	admin_queue->sq.head += comp_num;
+	admin_queue->stats.completed_cmd += comp_num;
+}
+
+static int ena_com_comp_status_to_errno(u8 comp_status)
+{
+	if (unlikely(comp_status != 0))
+		pr_err("admin command failed[%u]\n", comp_status);
+
+	if (unlikely(comp_status > ENA_ADMIN_UNKNOWN_ERROR))
+		return -EINVAL;
+
+	switch (comp_status) {
+	case ENA_ADMIN_SUCCESS:
+		return 0;
+	case ENA_ADMIN_RESOURCE_ALLOCATION_FAILURE:
+		return -ENOMEM;
+	case ENA_ADMIN_UNSUPPORTED_OPCODE:
+		return -EPERM;
+	case ENA_ADMIN_BAD_OPCODE:
+	case ENA_ADMIN_MALFORMED_REQUEST:
+	case ENA_ADMIN_ILLEGAL_PARAMETER:
+	case ENA_ADMIN_UNKNOWN_ERROR:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int ena_com_wait_and_process_admin_cq_polling(struct ena_comp_ctx *comp_ctx,
+						     struct ena_com_admin_queue *admin_queue)
+{
+	unsigned long flags;
+	u32 start_time;
+	int ret;
+
+	start_time = ((u32)jiffies_to_usecs(jiffies));
+
+	while (comp_ctx->status == ENA_CMD_SUBMITTED) {
+		if ((((u32)jiffies_to_usecs(jiffies)) - start_time) >
+		    ADMIN_CMD_TIMEOUT_US) {
+			pr_err("Wait for completion (polling) timeout\n");
+			/* ENA didn't have any completion */
+			spin_lock_irqsave(&admin_queue->q_lock, flags);
+			admin_queue->stats.no_completion++;
+			admin_queue->running_state = false;
+			spin_unlock_irqrestore(&admin_queue->q_lock, flags);
+
+			ret = -ETIME;
+			goto err;
+		}
+
+		spin_lock_irqsave(&admin_queue->q_lock, flags);
+		ena_com_handle_admin_completion(admin_queue);
+		spin_unlock_irqrestore(&admin_queue->q_lock, flags);
+
+		msleep(100);
+	}
+
+	if (unlikely(comp_ctx->status == ENA_CMD_ABORTED)) {
+		pr_err("Command was aborted\n");
+		spin_lock_irqsave(&admin_queue->q_lock, flags);
+		admin_queue->stats.aborted_cmd++;
+		spin_unlock_irqrestore(&admin_queue->q_lock, flags);
+		ret = -ENODEV;
+		goto err;
+	}
+
+	WARN(comp_ctx->status != ENA_CMD_COMPLETED, "Invalid comp status %d\n",
+	     comp_ctx->status);
+
+	ret = ena_com_comp_status_to_errno(comp_ctx->comp_status);
+err:
+	comp_ctxt_release(admin_queue, comp_ctx);
+	return ret;
+}
+
+static int ena_com_wait_and_process_admin_cq_interrupts(struct ena_comp_ctx *comp_ctx,
+							struct ena_com_admin_queue *admin_queue)
+{
+	unsigned long flags;
+	int ret;
+
+	wait_for_completion_timeout(&comp_ctx->wait_event,
+				    usecs_to_jiffies(ADMIN_CMD_TIMEOUT_US));
+
+	/* In case the command wasn't completed find out the root cause.
+	 * There might be 2 kinds of errors
+	 * 1) No completion (timeout reached)
+	 * 2) There is completion but the device didn't get any msi-x interrupt.
+	 */
+	if (unlikely(comp_ctx->status == ENA_CMD_SUBMITTED)) {
+		spin_lock_irqsave(&admin_queue->q_lock, flags);
+		ena_com_handle_admin_completion(admin_queue);
+		admin_queue->stats.no_completion++;
+		spin_unlock_irqrestore(&admin_queue->q_lock, flags);
+
+		if (comp_ctx->status == ENA_CMD_COMPLETED)
+			pr_err("The ena device have completion but the driver didn't receive any MSI-X interrupt (cmd %d)\n",
+			       comp_ctx->cmd_opcode);
+		else
+			pr_err("The ena device doesn't send any completion for the admin cmd %d status %d\n",
+			       comp_ctx->cmd_opcode, comp_ctx->status);
+
+		admin_queue->running_state = false;
+		ret = -ETIME;
+		goto err;
+	}
+
+	ret = ena_com_comp_status_to_errno(comp_ctx->comp_status);
+err:
+	comp_ctxt_release(admin_queue, comp_ctx);
+	return ret;
+}
+
+/* This method read the hardware device register through posting writes
+ * and waiting for response
+ * On timeout the function will return ENA_MMIO_READ_TIMEOUT
+ */
+static u32 ena_com_reg_bar_read32(struct ena_com_dev *ena_dev, u16 offset)
+{
+	struct ena_com_mmio_read *mmio_read = &ena_dev->mmio_read;
+	volatile struct ena_admin_ena_mmio_req_read_less_resp *read_resp =
+		mmio_read->read_resp;
+	u32 mmio_read_reg, ret;
+	unsigned long flags;
+	int i;
+
+	might_sleep();
+
+	/* If readless is disabled, perform regular read */
+	if (!mmio_read->readless_supported)
+		return readl(ena_dev->reg_bar + offset);
+
+	spin_lock_irqsave(&mmio_read->lock, flags);
+	mmio_read->seq_num++;
+
+	read_resp->req_id = mmio_read->seq_num + 0xDEAD;
+	mmio_read_reg = (offset << ENA_REGS_MMIO_REG_READ_REG_OFF_SHIFT) &
+			ENA_REGS_MMIO_REG_READ_REG_OFF_MASK;
+	mmio_read_reg |= mmio_read->seq_num &
+			ENA_REGS_MMIO_REG_READ_REQ_ID_MASK;
+
+	/* make sure read_resp->req_id get updated before the hw can write
+	 * there
+	 */
+	wmb();
+
+	writel(mmio_read_reg, ena_dev->reg_bar + ENA_REGS_MMIO_REG_READ_OFF);
+
+	for (i = 0; i < ENA_REG_READ_TIMEOUT; i++) {
+		if (read_resp->req_id == mmio_read->seq_num)
+			break;
+
+		udelay(1);
+	}
+
+	if (unlikely(i == ENA_REG_READ_TIMEOUT)) {
+		pr_err("reading reg failed for timeout. expected: req id[%hu] offset[%hu] actual: req id[%hu] offset[%hu]\n",
+		       mmio_read->seq_num, offset, read_resp->req_id,
+		       read_resp->reg_off);
+		ret = ENA_MMIO_READ_TIMEOUT;
+		goto err;
+	}
+
+	if (read_resp->reg_off != offset) {
+		pr_err("Read failure: wrong offset provided");
+		ret = ENA_MMIO_READ_TIMEOUT;
+	} else {
+		ret = read_resp->reg_val;
+	}
+err:
+	spin_unlock_irqrestore(&mmio_read->lock, flags);
+
+	return ret;
+}
+
+/* There are two types to wait for completion.
+ * Polling mode - wait until the completion is available.
+ * Async mode - wait on wait queue until the completion is ready
+ * (or the timeout expired).
+ * It is expected that the IRQ called ena_com_handle_admin_completion
+ * to mark the completions.
+ */
+static int ena_com_wait_and_process_admin_cq(struct ena_comp_ctx *comp_ctx,
+					     struct ena_com_admin_queue *admin_queue)
+{
+	if (admin_queue->polling)
+		return ena_com_wait_and_process_admin_cq_polling(comp_ctx,
+								 admin_queue);
+
+	return ena_com_wait_and_process_admin_cq_interrupts(comp_ctx,
+							    admin_queue);
+}
+
+static int ena_com_destroy_io_sq(struct ena_com_dev *ena_dev,
+				 struct ena_com_io_sq *io_sq)
+{
+	struct ena_com_admin_queue *admin_queue = &ena_dev->admin_queue;
+	struct ena_admin_aq_destroy_sq_cmd destroy_cmd;
+	struct ena_admin_acq_destroy_sq_resp_desc destroy_resp;
+	u8 direction;
+	int ret;
+
+	memset(&destroy_cmd, 0x0, sizeof(struct ena_admin_aq_destroy_sq_cmd));
+
+	if (io_sq->direction == ENA_COM_IO_QUEUE_DIRECTION_TX)
+		direction = ENA_ADMIN_SQ_DIRECTION_TX;
+	else
+		direction = ENA_ADMIN_SQ_DIRECTION_RX;
+
+	destroy_cmd.sq.sq_identity |= (direction <<
+		ENA_ADMIN_SQ_SQ_DIRECTION_SHIFT) &
+		ENA_ADMIN_SQ_SQ_DIRECTION_MASK;
+
+	destroy_cmd.sq.sq_idx = io_sq->idx;
+	destroy_cmd.aq_common_descriptor.opcode = ENA_ADMIN_DESTROY_SQ;
+
+	ret = ena_com_execute_admin_command(admin_queue,
+					    (struct ena_admin_aq_entry *)&destroy_cmd,
+					    sizeof(destroy_cmd),
+					    (struct ena_admin_acq_entry *)&destroy_resp,
+					    sizeof(destroy_resp));
+
+	if (unlikely(ret && (ret != -ENODEV)))
+		pr_err("failed to destroy io sq error: %d\n", ret);
+
+	return ret;
+}
+
+static void ena_com_io_queue_free(struct ena_com_dev *ena_dev,
+				  struct ena_com_io_sq *io_sq,
+				  struct ena_com_io_cq *io_cq)
+{
+	size_t size;
+
+	if (io_cq->cdesc_addr.virt_addr) {
+		size = io_cq->cdesc_entry_size_in_bytes * io_cq->q_depth;
+
+		dma_free_coherent(ena_dev->dmadev, size,
+				  io_cq->cdesc_addr.virt_addr,
+				  io_cq->cdesc_addr.phys_addr);
+
+		io_cq->cdesc_addr.virt_addr = NULL;
+	}
+
+	if (io_sq->desc_addr.virt_addr) {
+		size = io_sq->desc_entry_size * io_sq->q_depth;
+
+		if (io_sq->mem_queue_type == ENA_ADMIN_PLACEMENT_POLICY_HOST)
+			dma_free_coherent(ena_dev->dmadev, size,
+					  io_sq->desc_addr.virt_addr,
+					  io_sq->desc_addr.phys_addr);
+		else
+			devm_kfree(ena_dev->dmadev, io_sq->desc_addr.virt_addr);
+
+		io_sq->desc_addr.virt_addr = NULL;
+	}
+}
+
+static int wait_for_reset_state(struct ena_com_dev *ena_dev, u32 timeout,
+				u16 exp_state)
+{
+	u32 val, i;
+
+	for (i = 0; i < timeout; i++) {
+		val = ena_com_reg_bar_read32(ena_dev, ENA_REGS_DEV_STS_OFF);
+
+		if (unlikely(val == ENA_MMIO_READ_TIMEOUT)) {
+			pr_err("Reg read timeout occurred\n");
+			return -ETIME;
+		}
+
+		if ((val & ENA_REGS_DEV_STS_RESET_IN_PROGRESS_MASK) ==
+			exp_state)
+			return 0;
+
+		/* The resolution of the timeout is 100ms */
+		msleep(100);
+	}
+
+	return -ETIME;
+}
+
+static bool ena_com_check_supported_feature_id(struct ena_com_dev *ena_dev,
+					       enum ena_admin_aq_feature_id feature_id)
+{
+	u32 feature_mask = 1 << feature_id;
+
+	/* Device attributes is always supported */
+	if ((feature_id != ENA_ADMIN_DEVICE_ATTRIBUTES) &&
+	    !(ena_dev->supported_features & feature_mask))
+		return false;
+
+	return true;
+}
+
+static int ena_com_get_feature_ex(struct ena_com_dev *ena_dev,
+				  struct ena_admin_get_feat_resp *get_resp,
+				  enum ena_admin_aq_feature_id feature_id,
+				  dma_addr_t control_buf_dma_addr,
+				  u32 control_buff_size)
+{
+	struct ena_com_admin_queue *admin_queue;
+	struct ena_admin_get_feat_cmd get_cmd;
+	int ret;
+
+	if (!ena_com_check_supported_feature_id(ena_dev, feature_id)) {
+		pr_info("Feature %d isn't supported\n", feature_id);
+		return -EPERM;
+	}
+
+	memset(&get_cmd, 0x0, sizeof(get_cmd));
+	admin_queue = &ena_dev->admin_queue;
+
+	get_cmd.aq_common_descriptor.opcode = ENA_ADMIN_GET_FEATURE;
+
+	if (control_buff_size)
+		get_cmd.aq_common_descriptor.flags =
+			ENA_ADMIN_AQ_COMMON_DESC_CTRL_DATA_INDIRECT_MASK;
+	else
+		get_cmd.aq_common_descriptor.flags = 0;
+
+	ret = ena_com_mem_addr_set(ena_dev,
+				   &get_cmd.control_buffer.address,
+				   control_buf_dma_addr);
+	if (unlikely(ret)) {
+		pr_err("memory address set failed\n");
+		return ret;
+	}
+
+	get_cmd.control_buffer.length = control_buff_size;
+
+	get_cmd.feat_common.feature_id = feature_id;
+
+	ret = ena_com_execute_admin_command(admin_queue,
+					    (struct ena_admin_aq_entry *)
+					    &get_cmd,
+					    sizeof(get_cmd),
+					    (struct ena_admin_acq_entry *)
+					    get_resp,
+					    sizeof(*get_resp));
+
+	if (unlikely(ret))
+		pr_err("Failed to submit get_feature command %d error: %d\n",
+		       feature_id, ret);
+
+	return ret;
+}
+
+static int ena_com_get_feature(struct ena_com_dev *ena_dev,
+			       struct ena_admin_get_feat_resp *get_resp,
+			       enum ena_admin_aq_feature_id feature_id)
+{
+	return ena_com_get_feature_ex(ena_dev,
+				      get_resp,
+				      feature_id,
+				      0,
+				      0);
+}
+
+static int ena_com_hash_key_allocate(struct ena_com_dev *ena_dev)
+{
+	struct ena_rss *rss = &ena_dev->rss;
+
+	rss->hash_key =
+		dma_zalloc_coherent(ena_dev->dmadev, sizeof(*rss->hash_key),
+				    &rss->hash_key_dma_addr, GFP_KERNEL);
+
+	if (unlikely(!rss->hash_key))
+		return -ENOMEM;
+
+	return 0;
+}
+
+static void ena_com_hash_key_destroy(struct ena_com_dev *ena_dev)
+{
+	struct ena_rss *rss = &ena_dev->rss;
+
+	if (rss->hash_key)
+		dma_free_coherent(ena_dev->dmadev, sizeof(*rss->hash_key),
+				  rss->hash_key, rss->hash_key_dma_addr);
+	rss->hash_key = NULL;
+}
+
+static int ena_com_hash_ctrl_init(struct ena_com_dev *ena_dev)
+{
+	struct ena_rss *rss = &ena_dev->rss;
+
+	rss->hash_ctrl =
+		dma_zalloc_coherent(ena_dev->dmadev, sizeof(*rss->hash_ctrl),
+				    &rss->hash_ctrl_dma_addr, GFP_KERNEL);
+
+	if (unlikely(!rss->hash_ctrl))
+		return -ENOMEM;
+
+	return 0;
+}
+
+static void ena_com_hash_ctrl_destroy(struct ena_com_dev *ena_dev)
+{
+	struct ena_rss *rss = &ena_dev->rss;
+
+	if (rss->hash_ctrl)
+		dma_free_coherent(ena_dev->dmadev, sizeof(*rss->hash_ctrl),
+				  rss->hash_ctrl, rss->hash_ctrl_dma_addr);
+	rss->hash_ctrl = NULL;
+}
+
+static int ena_com_indirect_table_allocate(struct ena_com_dev *ena_dev,
+					   u16 log_size)
+{
+	struct ena_rss *rss = &ena_dev->rss;
+	struct ena_admin_get_feat_resp get_resp;
+	size_t tbl_size;
+	int ret;
+
+	ret = ena_com_get_feature(ena_dev, &get_resp,
+				  ENA_ADMIN_RSS_REDIRECTION_TABLE_CONFIG);
+	if (unlikely(ret))
+		return ret;
+
+	if ((get_resp.u.ind_table.min_size > log_size) ||
+	    (get_resp.u.ind_table.max_size < log_size)) {
+		pr_err("indirect table size doesn't fit. requested size: %d while min is:%d and max %d\n",
+		       1 << log_size, 1 << get_resp.u.ind_table.min_size,
+		       1 << get_resp.u.ind_table.max_size);
+		return -EINVAL;
+	}
+
+	tbl_size = (1ULL << log_size) *
+		sizeof(struct ena_admin_rss_ind_table_entry);
+
+	rss->rss_ind_tbl =
+		dma_zalloc_coherent(ena_dev->dmadev, tbl_size,
+				    &rss->rss_ind_tbl_dma_addr, GFP_KERNEL);
+	if (unlikely(!rss->rss_ind_tbl))
+		goto mem_err1;
+
+	tbl_size = (1ULL << log_size) * sizeof(u16);
+	rss->host_rss_ind_tbl =
+		devm_kzalloc(ena_dev->dmadev, tbl_size, GFP_KERNEL);
+	if (unlikely(!rss->host_rss_ind_tbl))
+		goto mem_err2;
+
+	rss->tbl_log_size = log_size;
+
+	return 0;
+
+mem_err2:
+	tbl_size = (1ULL << log_size) *
+		sizeof(struct ena_admin_rss_ind_table_entry);
+
+	dma_free_coherent(ena_dev->dmadev, tbl_size, rss->rss_ind_tbl,
+			  rss->rss_ind_tbl_dma_addr);
+	rss->rss_ind_tbl = NULL;
+mem_err1:
+	rss->tbl_log_size = 0;
+	return -ENOMEM;
+}
+
+static void ena_com_indirect_table_destroy(struct ena_com_dev *ena_dev)
+{
+	struct ena_rss *rss = &ena_dev->rss;
+	size_t tbl_size = (1ULL << rss->tbl_log_size) *
+		sizeof(struct ena_admin_rss_ind_table_entry);
+
+	if (rss->rss_ind_tbl)
+		dma_free_coherent(ena_dev->dmadev, tbl_size, rss->rss_ind_tbl,
+				  rss->rss_ind_tbl_dma_addr);
+	rss->rss_ind_tbl = NULL;
+
+	if (rss->host_rss_ind_tbl)
+		devm_kfree(ena_dev->dmadev, rss->host_rss_ind_tbl);
+	rss->host_rss_ind_tbl = NULL;
+}
+
+static int ena_com_create_io_sq(struct ena_com_dev *ena_dev,
+				struct ena_com_io_sq *io_sq, u16 cq_idx)
+{
+	struct ena_com_admin_queue *admin_queue = &ena_dev->admin_queue;
+	struct ena_admin_aq_create_sq_cmd create_cmd;
+	struct ena_admin_acq_create_sq_resp_desc cmd_completion;
+	u8 direction;
+	int ret;
+
+	memset(&create_cmd, 0x0, sizeof(struct ena_admin_aq_create_sq_cmd));
+
+	create_cmd.aq_common_descriptor.opcode = ENA_ADMIN_CREATE_SQ;
+
+	if (io_sq->direction == ENA_COM_IO_QUEUE_DIRECTION_TX)
+		direction = ENA_ADMIN_SQ_DIRECTION_TX;
+	else
+		direction = ENA_ADMIN_SQ_DIRECTION_RX;
+
+	create_cmd.sq_identity |= (direction <<
+		ENA_ADMIN_AQ_CREATE_SQ_CMD_SQ_DIRECTION_SHIFT) &
+		ENA_ADMIN_AQ_CREATE_SQ_CMD_SQ_DIRECTION_MASK;
+
+	create_cmd.sq_caps_2 |= io_sq->mem_queue_type &
+		ENA_ADMIN_AQ_CREATE_SQ_CMD_PLACEMENT_POLICY_MASK;
+
+	create_cmd.sq_caps_2 |= (ENA_ADMIN_COMPLETION_POLICY_DESC <<
+		ENA_ADMIN_AQ_CREATE_SQ_CMD_COMPLETION_POLICY_SHIFT) &
+		ENA_ADMIN_AQ_CREATE_SQ_CMD_COMPLETION_POLICY_MASK;
+
+	create_cmd.sq_caps_3 |=
+		ENA_ADMIN_AQ_CREATE_SQ_CMD_IS_PHYSICALLY_CONTIGUOUS_MASK;
+
+	create_cmd.cq_idx = cq_idx;
+	create_cmd.sq_depth = io_sq->q_depth;
+
+	if (io_sq->mem_queue_type == ENA_ADMIN_PLACEMENT_POLICY_HOST) {
+		ret = ena_com_mem_addr_set(ena_dev,
+					   &create_cmd.sq_ba,
+					   io_sq->desc_addr.phys_addr);
+		if (unlikely(ret)) {
+			pr_err("memory address set failed\n");
+			return ret;
+		}
+	}
+
+	ret = ena_com_execute_admin_command(admin_queue,
+					    (struct ena_admin_aq_entry *)&create_cmd,
+					    sizeof(create_cmd),
+					    (struct ena_admin_acq_entry *)&cmd_completion,
+					    sizeof(cmd_completion));
+	if (unlikely(ret)) {
+		pr_err("Failed to create IO SQ. error: %d\n", ret);
+		return ret;
+	}
+
+	io_sq->idx = cmd_completion.sq_idx;
+
+	io_sq->db_addr = (u32 __iomem *)((uintptr_t)ena_dev->reg_bar +
+		(uintptr_t)cmd_completion.sq_doorbell_offset);
+
+	if (io_sq->mem_queue_type == ENA_ADMIN_PLACEMENT_POLICY_DEV) {
+		io_sq->header_addr = (u8 __iomem *)((uintptr_t)ena_dev->mem_bar
+				+ cmd_completion.llq_headers_offset);
+
+		io_sq->desc_addr.pbuf_dev_addr =
+			(u8 __iomem *)((uintptr_t)ena_dev->mem_bar +
+			cmd_completion.llq_descriptors_offset);
+	}
+
+	pr_debug("created sq[%u], depth[%u]\n", io_sq->idx, io_sq->q_depth);
+
+	return ret;
+}
+
+static int ena_com_ind_tbl_convert_to_device(struct ena_com_dev *ena_dev)
+{
+	struct ena_rss *rss = &ena_dev->rss;
+	struct ena_com_io_sq *io_sq;
+	u16 qid;
+	int i;
+
+	for (i = 0; i < 1 << rss->tbl_log_size; i++) {
+		qid = rss->host_rss_ind_tbl[i];
+		if (qid >= ENA_TOTAL_NUM_QUEUES)
+			return -EINVAL;
+
+		io_sq = &ena_dev->io_sq_queues[qid];
+
+		if (io_sq->direction != ENA_COM_IO_QUEUE_DIRECTION_RX)
+			return -EINVAL;
+
+		rss->rss_ind_tbl[i].cq_idx = io_sq->idx;
+	}
+
+	return 0;
+}
+
+static int ena_com_ind_tbl_convert_from_device(struct ena_com_dev *ena_dev)
+{
+	u16 dev_idx_to_host_tbl[ENA_TOTAL_NUM_QUEUES] = { (u16)-1 };
+	struct ena_rss *rss = &ena_dev->rss;
+	u8 idx;
+	u16 i;
+
+	for (i = 0; i < ENA_TOTAL_NUM_QUEUES; i++)
+		dev_idx_to_host_tbl[ena_dev->io_sq_queues[i].idx] = i;
+
+	for (i = 0; i < 1 << rss->tbl_log_size; i++) {
+		if (rss->rss_ind_tbl[i].cq_idx > ENA_TOTAL_NUM_QUEUES)
+			return -EINVAL;
+		idx = (u8)rss->rss_ind_tbl[i].cq_idx;
+
+		if (dev_idx_to_host_tbl[idx] > ENA_TOTAL_NUM_QUEUES)
+			return -EINVAL;
+
+		rss->host_rss_ind_tbl[i] = dev_idx_to_host_tbl[idx];
+	}
+
+	return 0;
+}
+
+static int ena_com_init_interrupt_moderation_table(struct ena_com_dev *ena_dev)
+{
+	size_t size;
+
+	size = sizeof(struct ena_intr_moder_entry) * ENA_INTR_MAX_NUM_OF_LEVELS;
+
+	ena_dev->intr_moder_tbl =
+		devm_kzalloc(ena_dev->dmadev, size, GFP_KERNEL);
+	if (!ena_dev->intr_moder_tbl)
+		return -ENOMEM;
+
+	ena_com_config_default_interrupt_moderation_table(ena_dev);
+
+	return 0;
+}
+
+static void ena_com_update_intr_delay_resolution(struct ena_com_dev *ena_dev,
+						 u16 intr_delay_resolution)
+{
+	struct ena_intr_moder_entry *intr_moder_tbl = ena_dev->intr_moder_tbl;
+	unsigned int i;
+
+	if (!intr_delay_resolution) {
+		pr_err("Illegal intr_delay_resolution provided. Going to use default 1 usec resolution\n");
+		intr_delay_resolution = 1;
+	}
+	ena_dev->intr_delay_resolution = intr_delay_resolution;
+
+	/* update Rx */
+	for (i = 0; i < ENA_INTR_MAX_NUM_OF_LEVELS; i++)
+		intr_moder_tbl[i].intr_moder_interval /= intr_delay_resolution;
+
+	/* update Tx */
+	ena_dev->intr_moder_tx_interval /= intr_delay_resolution;
+}
+
+/*****************************************************************************/
+/*******************************      API       ******************************/
+/*****************************************************************************/
+
+int ena_com_execute_admin_command(struct ena_com_admin_queue *admin_queue,
+				  struct ena_admin_aq_entry *cmd,
+				  size_t cmd_size,
+				  struct ena_admin_acq_entry *comp,
+				  size_t comp_size)
+{
+	struct ena_comp_ctx *comp_ctx;
+	int ret;
+
+	comp_ctx = ena_com_submit_admin_cmd(admin_queue, cmd, cmd_size,
+					    comp, comp_size);
+	if (unlikely(IS_ERR(comp_ctx))) {
+		pr_err("Failed to submit command [%ld]\n", PTR_ERR(comp_ctx));
+		return PTR_ERR(comp_ctx);
+	}
+
+	ret = ena_com_wait_and_process_admin_cq(comp_ctx, admin_queue);
+	if (unlikely(ret)) {
+		if (admin_queue->running_state)
+			pr_err("Failed to process command. ret = %d\n", ret);
+		else
+			pr_debug("Failed to process command. ret = %d\n", ret);
+	}
+	return ret;
+}
+
+int ena_com_create_io_cq(struct ena_com_dev *ena_dev,
+			 struct ena_com_io_cq *io_cq)
+{
+	struct ena_com_admin_queue *admin_queue = &ena_dev->admin_queue;
+	struct ena_admin_aq_create_cq_cmd create_cmd;
+	struct ena_admin_acq_create_cq_resp_desc cmd_completion;
+	int ret;
+
+	memset(&create_cmd, 0x0, sizeof(struct ena_admin_aq_create_cq_cmd));
+
+	create_cmd.aq_common_descriptor.opcode = ENA_ADMIN_CREATE_CQ;
+
+	create_cmd.cq_caps_2 |= (io_cq->cdesc_entry_size_in_bytes / 4) &
+		ENA_ADMIN_AQ_CREATE_CQ_CMD_CQ_ENTRY_SIZE_WORDS_MASK;
+	create_cmd.cq_caps_1 |=
+		ENA_ADMIN_AQ_CREATE_CQ_CMD_INTERRUPT_MODE_ENABLED_MASK;
+
+	create_cmd.msix_vector = io_cq->msix_vector;
+	create_cmd.cq_depth = io_cq->q_depth;
+
+	ret = ena_com_mem_addr_set(ena_dev,
+				   &create_cmd.cq_ba,
+				   io_cq->cdesc_addr.phys_addr);
+	if (unlikely(ret)) {
+		pr_err("memory address set failed\n");
+		return ret;
+	}
+
+	ret = ena_com_execute_admin_command(admin_queue,
+					    (struct ena_admin_aq_entry *)&create_cmd,
+					    sizeof(create_cmd),
+					    (struct ena_admin_acq_entry *)&cmd_completion,
+					    sizeof(cmd_completion));
+	if (unlikely(ret)) {
+		pr_err("Failed to create IO CQ. error: %d\n", ret);
+		return ret;
+	}
+
+	io_cq->idx = cmd_completion.cq_idx;
+
+	io_cq->unmask_reg = (u32 __iomem *)((uintptr_t)ena_dev->reg_bar +
+		cmd_completion.cq_interrupt_unmask_register_offset);
+
+	if (cmd_completion.cq_head_db_register_offset)
+		io_cq->cq_head_db_reg =
+			(u32 __iomem *)((uintptr_t)ena_dev->reg_bar +
+			cmd_completion.cq_head_db_register_offset);
+
+	if (cmd_completion.numa_node_register_offset)
+		io_cq->numa_node_cfg_reg =
+			(u32 __iomem *)((uintptr_t)ena_dev->reg_bar +
+			cmd_completion.numa_node_register_offset);
+
+	pr_debug("created cq[%u], depth[%u]\n", io_cq->idx, io_cq->q_depth);
+
+	return ret;
+}
+
+int ena_com_get_io_handlers(struct ena_com_dev *ena_dev, u16 qid,
+			    struct ena_com_io_sq **io_sq,
+			    struct ena_com_io_cq **io_cq)
+{
+	if (qid >= ENA_TOTAL_NUM_QUEUES) {
+		pr_err("Invalid queue number %d but the max is %d\n", qid,
+		       ENA_TOTAL_NUM_QUEUES);
+		return -EINVAL;
+	}
+
+	*io_sq = &ena_dev->io_sq_queues[qid];
+	*io_cq = &ena_dev->io_cq_queues[qid];
+
+	return 0;
+}
+
+void ena_com_abort_admin_commands(struct ena_com_dev *ena_dev)
+{
+	struct ena_com_admin_queue *admin_queue = &ena_dev->admin_queue;
+	struct ena_comp_ctx *comp_ctx;
+	u16 i;
+
+	if (!admin_queue->comp_ctx)
+		return;
+
+	for (i = 0; i < admin_queue->q_depth; i++) {
+		comp_ctx = get_comp_ctxt(admin_queue, i, false);
+		if (unlikely(!comp_ctx))
+			break;
+
+		comp_ctx->status = ENA_CMD_ABORTED;
+
+		complete(&comp_ctx->wait_event);
+	}
+}
+
+void ena_com_wait_for_abort_completion(struct ena_com_dev *ena_dev)
+{
+	struct ena_com_admin_queue *admin_queue = &ena_dev->admin_queue;
+	unsigned long flags;
+
+	spin_lock_irqsave(&admin_queue->q_lock, flags);
+	while (atomic_read(&admin_queue->outstanding_cmds) != 0) {
+		spin_unlock_irqrestore(&admin_queue->q_lock, flags);
+		msleep(20);
+		spin_lock_irqsave(&admin_queue->q_lock, flags);
+	}
+	spin_unlock_irqrestore(&admin_queue->q_lock, flags);
+}
+
+int ena_com_destroy_io_cq(struct ena_com_dev *ena_dev,
+			  struct ena_com_io_cq *io_cq)
+{
+	struct ena_com_admin_queue *admin_queue = &ena_dev->admin_queue;
+	struct ena_admin_aq_destroy_cq_cmd destroy_cmd;
+	struct ena_admin_acq_destroy_cq_resp_desc destroy_resp;
+	int ret;
+
+	memset(&destroy_cmd, 0x0, sizeof(struct ena_admin_aq_destroy_sq_cmd));
+
+	destroy_cmd.cq_idx = io_cq->idx;
+	destroy_cmd.aq_common_descriptor.opcode = ENA_ADMIN_DESTROY_CQ;
+
+	ret = ena_com_execute_admin_command(admin_queue,
+					    (struct ena_admin_aq_entry *)&destroy_cmd,
+					    sizeof(destroy_cmd),
+					    (struct ena_admin_acq_entry *)&destroy_resp,
+					    sizeof(destroy_resp));
+
+	if (unlikely(ret && (ret != -ENODEV)))
+		pr_err("Failed to destroy IO CQ. error: %d\n", ret);
+
+	return ret;
+}
+
+bool ena_com_get_admin_running_state(struct ena_com_dev *ena_dev)
+{
+	return ena_dev->admin_queue.running_state;
+}
+
+void ena_com_set_admin_running_state(struct ena_com_dev *ena_dev, bool state)
+{
+	struct ena_com_admin_queue *admin_queue = &ena_dev->admin_queue;
+	unsigned long flags;
+
+	spin_lock_irqsave(&admin_queue->q_lock, flags);
+	ena_dev->admin_queue.running_state = state;
+	spin_unlock_irqrestore(&admin_queue->q_lock, flags);
+}
+
+void ena_com_admin_aenq_enable(struct ena_com_dev *ena_dev)
+{
+	u16 depth = ena_dev->aenq.q_depth;
+
+	WARN(ena_dev->aenq.head != depth, "Invalid AENQ state\n");
+
+	/* Init head_db to mark that all entries in the queue
+	 * are initially available
+	 */
+	writel(depth, ena_dev->reg_bar + ENA_REGS_AENQ_HEAD_DB_OFF);
+}
+
+int ena_com_set_aenq_config(struct ena_com_dev *ena_dev, u32 groups_flag)
+{
+	struct ena_com_admin_queue *admin_queue;
+	struct ena_admin_set_feat_cmd cmd;
+	struct ena_admin_set_feat_resp resp;
+	struct ena_admin_get_feat_resp get_resp;
+	int ret;
+
+	ret = ena_com_get_feature(ena_dev, &get_resp, ENA_ADMIN_AENQ_CONFIG);
+	if (ret) {
+		pr_info("Can't get aenq configuration\n");
+		return ret;
+	}
+
+	if ((get_resp.u.aenq.supported_groups & groups_flag) != groups_flag) {
+		pr_warn("Trying to set unsupported aenq events. supported flag: %x asked flag: %x\n",
+			get_resp.u.aenq.supported_groups, groups_flag);
+		return -EPERM;
+	}
+
+	memset(&cmd, 0x0, sizeof(cmd));
+	admin_queue = &ena_dev->admin_queue;
+
+	cmd.aq_common_descriptor.opcode = ENA_ADMIN_SET_FEATURE;
+	cmd.aq_common_descriptor.flags = 0;
+	cmd.feat_common.feature_id = ENA_ADMIN_AENQ_CONFIG;
+	cmd.u.aenq.enabled_groups = groups_flag;
+
+	ret = ena_com_execute_admin_command(admin_queue,
+					    (struct ena_admin_aq_entry *)&cmd,
+					    sizeof(cmd),
+					    (struct ena_admin_acq_entry *)&resp,
+					    sizeof(resp));
+
+	if (unlikely(ret))
+		pr_err("Failed to config AENQ ret: %d\n", ret);
+
+	return ret;
+}
+
+int ena_com_get_dma_width(struct ena_com_dev *ena_dev)
+{
+	u32 caps = ena_com_reg_bar_read32(ena_dev, ENA_REGS_CAPS_OFF);
+	int width;
+
+	if (unlikely(caps == ENA_MMIO_READ_TIMEOUT)) {
+		pr_err("Reg read timeout occurred\n");
+		return -ETIME;
+	}
+
+	width = (caps & ENA_REGS_CAPS_DMA_ADDR_WIDTH_MASK) >>
+		ENA_REGS_CAPS_DMA_ADDR_WIDTH_SHIFT;
+
+	pr_debug("ENA dma width: %d\n", width);
+
+	if ((width < 32) || width > ENA_MAX_PHYS_ADDR_SIZE_BITS) {
+		pr_err("DMA width illegal value: %d\n", width);
+		return -EINVAL;
+	}
+
+	ena_dev->dma_addr_bits = width;
+
+	return width;
+}
+
+int ena_com_validate_version(struct ena_com_dev *ena_dev)
+{
+	u32 ver;
+	u32 ctrl_ver;
+	u32 ctrl_ver_masked;
+
+	/* Make sure the ENA version and the controller version are at least
+	 * as the driver expects
+	 */
+	ver = ena_com_reg_bar_read32(ena_dev, ENA_REGS_VERSION_OFF);
+	ctrl_ver = ena_com_reg_bar_read32(ena_dev,
+					  ENA_REGS_CONTROLLER_VERSION_OFF);
+
+	if (unlikely((ver == ENA_MMIO_READ_TIMEOUT) ||
+		     (ctrl_ver == ENA_MMIO_READ_TIMEOUT))) {
+		pr_err("Reg read timeout occurred\n");
+		return -ETIME;
+	}
+
+	pr_info("ena device version: %d.%d\n",
+		(ver & ENA_REGS_VERSION_MAJOR_VERSION_MASK) >>
+			ENA_REGS_VERSION_MAJOR_VERSION_SHIFT,
+		ver & ENA_REGS_VERSION_MINOR_VERSION_MASK);
+
+	if (ver < MIN_ENA_VER) {
+		pr_err("ENA version is lower than the minimal version the driver supports\n");
+		return -1;
+	}
+
+	pr_info("ena controller version: %d.%d.%d implementation version %d\n",
+		(ctrl_ver & ENA_REGS_CONTROLLER_VERSION_MAJOR_VERSION_MASK) >>
+			ENA_REGS_CONTROLLER_VERSION_MAJOR_VERSION_SHIFT,
+		(ctrl_ver & ENA_REGS_CONTROLLER_VERSION_MINOR_VERSION_MASK) >>
+			ENA_REGS_CONTROLLER_VERSION_MINOR_VERSION_SHIFT,
+		(ctrl_ver & ENA_REGS_CONTROLLER_VERSION_SUBMINOR_VERSION_MASK),
+		(ctrl_ver & ENA_REGS_CONTROLLER_VERSION_IMPL_ID_MASK) >>
+			ENA_REGS_CONTROLLER_VERSION_IMPL_ID_SHIFT);
+
+	ctrl_ver_masked =
+		(ctrl_ver & ENA_REGS_CONTROLLER_VERSION_MAJOR_VERSION_MASK) |
+		(ctrl_ver & ENA_REGS_CONTROLLER_VERSION_MINOR_VERSION_MASK) |
+		(ctrl_ver & ENA_REGS_CONTROLLER_VERSION_SUBMINOR_VERSION_MASK);
+
+	/* Validate the ctrl version without the implementation ID */
+	if (ctrl_ver_masked < MIN_ENA_CTRL_VER) {
+		pr_err("ENA ctrl version is lower than the minimal ctrl version the driver supports\n");
+		return -1;
+	}
+
+	return 0;
+}
+
+void ena_com_admin_destroy(struct ena_com_dev *ena_dev)
+{
+	struct ena_com_admin_queue *admin_queue = &ena_dev->admin_queue;
+	struct ena_com_admin_cq *cq = &admin_queue->cq;
+	struct ena_com_admin_sq *sq = &admin_queue->sq;
+	struct ena_com_aenq *aenq = &ena_dev->aenq;
+	u16 size;
+
+	if (admin_queue->comp_ctx)
+		devm_kfree(ena_dev->dmadev, admin_queue->comp_ctx);
+	admin_queue->comp_ctx = NULL;
+	size = ADMIN_SQ_SIZE(admin_queue->q_depth);
+	if (sq->entries)
+		dma_free_coherent(ena_dev->dmadev, size, sq->entries,
+				  sq->dma_addr);
+	sq->entries = NULL;
+
+	size = ADMIN_CQ_SIZE(admin_queue->q_depth);
+	if (cq->entries)
+		dma_free_coherent(ena_dev->dmadev, size, cq->entries,
+				  cq->dma_addr);
+	cq->entries = NULL;
+
+	size = ADMIN_AENQ_SIZE(aenq->q_depth);
+	if (ena_dev->aenq.entries)
+		dma_free_coherent(ena_dev->dmadev, size, aenq->entries,
+				  aenq->dma_addr);
+	aenq->entries = NULL;
+}
+
+void ena_com_set_admin_polling_mode(struct ena_com_dev *ena_dev, bool polling)
+{
+	ena_dev->admin_queue.polling = polling;
+}
+
+int ena_com_mmio_reg_read_request_init(struct ena_com_dev *ena_dev)
+{
+	struct ena_com_mmio_read *mmio_read = &ena_dev->mmio_read;
+
+	spin_lock_init(&mmio_read->lock);
+	mmio_read->read_resp =
+		dma_zalloc_coherent(ena_dev->dmadev,
+				    sizeof(*mmio_read->read_resp),
+				    &mmio_read->read_resp_dma_addr, GFP_KERNEL);
+	if (unlikely(!mmio_read->read_resp))
+		return -ENOMEM;
+
+	ena_com_mmio_reg_read_request_write_dev_addr(ena_dev);
+
+	mmio_read->read_resp->req_id = 0x0;
+	mmio_read->seq_num = 0x0;
+	mmio_read->readless_supported = true;
+
+	return 0;
+}
+
+void ena_com_set_mmio_read_mode(struct ena_com_dev *ena_dev, bool readless_supported)
+{
+	struct ena_com_mmio_read *mmio_read = &ena_dev->mmio_read;
+
+	mmio_read->readless_supported = readless_supported;
+}
+
+void ena_com_mmio_reg_read_request_destroy(struct ena_com_dev *ena_dev)
+{
+	struct ena_com_mmio_read *mmio_read = &ena_dev->mmio_read;
+
+	writel(0x0, ena_dev->reg_bar + ENA_REGS_MMIO_RESP_LO_OFF);
+	writel(0x0, ena_dev->reg_bar + ENA_REGS_MMIO_RESP_HI_OFF);
+
+	dma_free_coherent(ena_dev->dmadev, sizeof(*mmio_read->read_resp),
+			  mmio_read->read_resp, mmio_read->read_resp_dma_addr);
+
+	mmio_read->read_resp = NULL;
+}
+
+void ena_com_mmio_reg_read_request_write_dev_addr(struct ena_com_dev *ena_dev)
+{
+	struct ena_com_mmio_read *mmio_read = &ena_dev->mmio_read;
+	u32 addr_low, addr_high;
+
+	addr_low = ENA_DMA_ADDR_TO_UINT32_LOW(mmio_read->read_resp_dma_addr);
+	addr_high = ENA_DMA_ADDR_TO_UINT32_HIGH(mmio_read->read_resp_dma_addr);
+
+	writel(addr_low, ena_dev->reg_bar + ENA_REGS_MMIO_RESP_LO_OFF);
+	writel(addr_high, ena_dev->reg_bar + ENA_REGS_MMIO_RESP_HI_OFF);
+}
+
+int ena_com_admin_init(struct ena_com_dev *ena_dev,
+		       struct ena_aenq_handlers *aenq_handlers,
+		       bool init_spinlock)
+{
+	struct ena_com_admin_queue *admin_queue = &ena_dev->admin_queue;
+	u32 aq_caps, acq_caps, dev_sts, addr_low, addr_high;
+	int ret;
+
+	dev_sts = ena_com_reg_bar_read32(ena_dev, ENA_REGS_DEV_STS_OFF);
+
+	if (unlikely(dev_sts == ENA_MMIO_READ_TIMEOUT)) {
+		pr_err("Reg read timeout occurred\n");
+		return -ETIME;
+	}
+
+	if (!(dev_sts & ENA_REGS_DEV_STS_READY_MASK)) {
+		pr_err("Device isn't ready, abort com init\n");
+		return -ENODEV;
+	}
+
+	admin_queue->q_depth = ENA_ADMIN_QUEUE_DEPTH;
+
+	admin_queue->q_dmadev = ena_dev->dmadev;
+	admin_queue->polling = false;
+	admin_queue->curr_cmd_id = 0;
+
+	atomic_set(&admin_queue->outstanding_cmds, 0);
+
+	if (init_spinlock)
+		spin_lock_init(&admin_queue->q_lock);
+
+	ret = ena_com_init_comp_ctxt(admin_queue);
+	if (ret)
+		goto error;
+
+	ret = ena_com_admin_init_sq(admin_queue);
+	if (ret)
+		goto error;
+
+	ret = ena_com_admin_init_cq(admin_queue);
+	if (ret)
+		goto error;
+
+	admin_queue->sq.db_addr = (u32 __iomem *)((uintptr_t)ena_dev->reg_bar +
+		ENA_REGS_AQ_DB_OFF);
+
+	addr_low = ENA_DMA_ADDR_TO_UINT32_LOW(admin_queue->sq.dma_addr);
+	addr_high = ENA_DMA_ADDR_TO_UINT32_HIGH(admin_queue->sq.dma_addr);
+
+	writel(addr_low, ena_dev->reg_bar + ENA_REGS_AQ_BASE_LO_OFF);
+	writel(addr_high, ena_dev->reg_bar + ENA_REGS_AQ_BASE_HI_OFF);
+
+	addr_low = ENA_DMA_ADDR_TO_UINT32_LOW(admin_queue->cq.dma_addr);
+	addr_high = ENA_DMA_ADDR_TO_UINT32_HIGH(admin_queue->cq.dma_addr);
+
+	writel(addr_low, ena_dev->reg_bar + ENA_REGS_ACQ_BASE_LO_OFF);
+	writel(addr_high, ena_dev->reg_bar + ENA_REGS_ACQ_BASE_HI_OFF);
+
+	aq_caps = 0;
+	aq_caps |= admin_queue->q_depth & ENA_REGS_AQ_CAPS_AQ_DEPTH_MASK;
+	aq_caps |= (sizeof(struct ena_admin_aq_entry) <<
+			ENA_REGS_AQ_CAPS_AQ_ENTRY_SIZE_SHIFT) &
+			ENA_REGS_AQ_CAPS_AQ_ENTRY_SIZE_MASK;
+
+	acq_caps = 0;
+	acq_caps |= admin_queue->q_depth & ENA_REGS_ACQ_CAPS_ACQ_DEPTH_MASK;
+	acq_caps |= (sizeof(struct ena_admin_acq_entry) <<
+		ENA_REGS_ACQ_CAPS_ACQ_ENTRY_SIZE_SHIFT) &
+		ENA_REGS_ACQ_CAPS_ACQ_ENTRY_SIZE_MASK;
+
+	writel(aq_caps, ena_dev->reg_bar + ENA_REGS_AQ_CAPS_OFF);
+	writel(acq_caps, ena_dev->reg_bar + ENA_REGS_ACQ_CAPS_OFF);
+	ret = ena_com_admin_init_aenq(ena_dev, aenq_handlers);
+	if (ret)
+		goto error;
+
+	admin_queue->running_state = true;
+
+	return 0;
+error:
+	ena_com_admin_destroy(ena_dev);
+
+	return ret;
+}
+
+int ena_com_create_io_queue(struct ena_com_dev *ena_dev,
+			    struct ena_com_create_io_ctx *ctx)
+{
+	struct ena_com_io_sq *io_sq;
+	struct ena_com_io_cq *io_cq;
+	int ret;
+
+	if (ctx->qid >= ENA_TOTAL_NUM_QUEUES) {
+		pr_err("Qid (%d) is bigger than max num of queues (%d)\n",
+		       ctx->qid, ENA_TOTAL_NUM_QUEUES);
+		return -EINVAL;
+	}
+
+	io_sq = &ena_dev->io_sq_queues[ctx->qid];
+	io_cq = &ena_dev->io_cq_queues[ctx->qid];
+
+	memset(io_sq, 0x0, sizeof(struct ena_com_io_sq));
+	memset(io_cq, 0x0, sizeof(struct ena_com_io_cq));
+
+	/* Init CQ */
+	io_cq->q_depth = ctx->queue_size;
+	io_cq->direction = ctx->direction;
+	io_cq->qid = ctx->qid;
+
+	io_cq->msix_vector = ctx->msix_vector;
+
+	io_sq->q_depth = ctx->queue_size;
+	io_sq->direction = ctx->direction;
+	io_sq->qid = ctx->qid;
+
+	io_sq->mem_queue_type = ctx->mem_queue_type;
+
+	if (ctx->direction == ENA_COM_IO_QUEUE_DIRECTION_TX)
+		/* header length is limited to 8 bits */
+		io_sq->tx_max_header_size =
+			min_t(u32, ena_dev->tx_max_header_size, SZ_256);
+
+	ret = ena_com_init_io_sq(ena_dev, ctx, io_sq);
+	if (ret)
+		goto error;
+	ret = ena_com_init_io_cq(ena_dev, ctx, io_cq);
+	if (ret)
+		goto error;
+
+	ret = ena_com_create_io_cq(ena_dev, io_cq);
+	if (ret)
+		goto error;
+
+	ret = ena_com_create_io_sq(ena_dev, io_sq, io_cq->idx);
+	if (ret)
+		goto destroy_io_cq;
+
+	return 0;
+
+destroy_io_cq:
+	ena_com_destroy_io_cq(ena_dev, io_cq);
+error:
+	ena_com_io_queue_free(ena_dev, io_sq, io_cq);
+	return ret;
+}
+
+void ena_com_destroy_io_queue(struct ena_com_dev *ena_dev, u16 qid)
+{
+	struct ena_com_io_sq *io_sq;
+	struct ena_com_io_cq *io_cq;
+
+	if (qid >= ENA_TOTAL_NUM_QUEUES) {
+		pr_err("Qid (%d) is bigger than max num of queues (%d)\n", qid,
+		       ENA_TOTAL_NUM_QUEUES);
+		return;
+	}
+
+	io_sq = &ena_dev->io_sq_queues[qid];
+	io_cq = &ena_dev->io_cq_queues[qid];
+
+	ena_com_destroy_io_sq(ena_dev, io_sq);
+	ena_com_destroy_io_cq(ena_dev, io_cq);
+
+	ena_com_io_queue_free(ena_dev, io_sq, io_cq);
+}
+
+int ena_com_get_link_params(struct ena_com_dev *ena_dev,
+			    struct ena_admin_get_feat_resp *resp)
+{
+	return ena_com_get_feature(ena_dev, resp, ENA_ADMIN_LINK_CONFIG);
+}
+
+int ena_com_get_dev_attr_feat(struct ena_com_dev *ena_dev,
+			      struct ena_com_dev_get_features_ctx *get_feat_ctx)
+{
+	struct ena_admin_get_feat_resp get_resp;
+	int rc;
+
+	rc = ena_com_get_feature(ena_dev, &get_resp,
+				 ENA_ADMIN_DEVICE_ATTRIBUTES);
+	if (rc)
+		return rc;
+
+	memcpy(&get_feat_ctx->dev_attr, &get_resp.u.dev_attr,
+	       sizeof(get_resp.u.dev_attr));
+	ena_dev->supported_features = get_resp.u.dev_attr.supported_features;
+
+	rc = ena_com_get_feature(ena_dev, &get_resp,
+				 ENA_ADMIN_MAX_QUEUES_NUM);
+	if (rc)
+		return rc;
+
+	memcpy(&get_feat_ctx->max_queues, &get_resp.u.max_queue,
+	       sizeof(get_resp.u.max_queue));
+	ena_dev->tx_max_header_size = get_resp.u.max_queue.max_header_size;
+
+	rc = ena_com_get_feature(ena_dev, &get_resp,
+				 ENA_ADMIN_AENQ_CONFIG);
+	if (rc)
+		return rc;
+
+	memcpy(&get_feat_ctx->aenq, &get_resp.u.aenq,
+	       sizeof(get_resp.u.aenq));
+
+	rc = ena_com_get_feature(ena_dev, &get_resp,
+				 ENA_ADMIN_STATELESS_OFFLOAD_CONFIG);
+	if (rc)
+		return rc;
+
+	memcpy(&get_feat_ctx->offload, &get_resp.u.offload,
+	       sizeof(get_resp.u.offload));
+
+	return 0;
+}
+
+void ena_com_admin_q_comp_intr_handler(struct ena_com_dev *ena_dev)
+{
+	ena_com_handle_admin_completion(&ena_dev->admin_queue);
+}
+
+/* ena_handle_specific_aenq_event:
+ * return the handler that is relevant to the specific event group
+ */
+static ena_aenq_handler ena_com_get_specific_aenq_cb(struct ena_com_dev *dev,
+						     u16 group)
+{
+	struct ena_aenq_handlers *aenq_handlers = dev->aenq.aenq_handlers;
+
+	if ((group < ENA_MAX_HANDLERS) && aenq_handlers->handlers[group])
+		return aenq_handlers->handlers[group];
+
+	return aenq_handlers->unimplemented_handler;
+}
+
+/* ena_aenq_intr_handler:
+ * handles the aenq incoming events.
+ * pop events from the queue and apply the specific handler
+ */
+void ena_com_aenq_intr_handler(struct ena_com_dev *dev, void *data)
+{
+	struct ena_admin_aenq_entry *aenq_e;
+	struct ena_admin_aenq_common_desc *aenq_common;
+	struct ena_com_aenq *aenq  = &dev->aenq;
+	ena_aenq_handler handler_cb;
+	u16 masked_head, processed = 0;
+	u8 phase;
+
+	masked_head = aenq->head & (aenq->q_depth - 1);
+	phase = aenq->phase;
+	aenq_e = &aenq->entries[masked_head]; /* Get first entry */
+	aenq_common = &aenq_e->aenq_common_desc;
+
+	/* Go over all the events */
+	while ((aenq_common->flags & ENA_ADMIN_AENQ_COMMON_DESC_PHASE_MASK) ==
+	       phase) {
+		pr_debug("AENQ! Group[%x] Syndrom[%x] timestamp: [%llus]\n",
+			 aenq_common->group, aenq_common->syndrom,
+			 (u64)aenq_common->timestamp_low +
+				 ((u64)aenq_common->timestamp_high << 32));
+
+		/* Handle specific event*/
+		handler_cb = ena_com_get_specific_aenq_cb(dev,
+							  aenq_common->group);
+		handler_cb(data, aenq_e); /* call the actual event handler*/
+
+		/* Get next event entry */
+		masked_head++;
+		processed++;
+
+		if (unlikely(masked_head == aenq->q_depth)) {
+			masked_head = 0;
+			phase = !phase;
+		}
+		aenq_e = &aenq->entries[masked_head];
+		aenq_common = &aenq_e->aenq_common_desc;
+	}
+
+	aenq->head += processed;
+	aenq->phase = phase;
+
+	/* Don't update aenq doorbell if there weren't any processed events */
+	if (!processed)
+		return;
+
+	/* write the aenq doorbell after all AENQ descriptors were read */
+	mb();
+	writel((u32)aenq->head, dev->reg_bar + ENA_REGS_AENQ_HEAD_DB_OFF);
+}
+
+int ena_com_dev_reset(struct ena_com_dev *ena_dev)
+{
+	u32 stat, timeout, cap, reset_val;
+	int rc;
+
+	stat = ena_com_reg_bar_read32(ena_dev, ENA_REGS_DEV_STS_OFF);
+	cap = ena_com_reg_bar_read32(ena_dev, ENA_REGS_CAPS_OFF);
+
+	if (unlikely((stat == ENA_MMIO_READ_TIMEOUT) ||
+		     (cap == ENA_MMIO_READ_TIMEOUT))) {
+		pr_err("Reg read32 timeout occurred\n");
+		return -ETIME;
+	}
+
+	if ((stat & ENA_REGS_DEV_STS_READY_MASK) == 0) {
+		pr_err("Device isn't ready, can't reset device\n");
+		return -EINVAL;
+	}
+
+	timeout = (cap & ENA_REGS_CAPS_RESET_TIMEOUT_MASK) >>
+			ENA_REGS_CAPS_RESET_TIMEOUT_SHIFT;
+	if (timeout == 0) {
+		pr_err("Invalid timeout value\n");
+		return -EINVAL;
+	}
+
+	/* start reset */
+	reset_val = ENA_REGS_DEV_CTL_DEV_RESET_MASK;
+	writel(reset_val, ena_dev->reg_bar + ENA_REGS_DEV_CTL_OFF);
+
+	/* Write again the MMIO read request address */
+	ena_com_mmio_reg_read_request_write_dev_addr(ena_dev);
+
+	rc = wait_for_reset_state(ena_dev, timeout,
+				  ENA_REGS_DEV_STS_RESET_IN_PROGRESS_MASK);
+	if (rc != 0) {
+		pr_err("Reset indication didn't turn on\n");
+		return rc;
+	}
+
+	/* reset done */
+	writel(0, ena_dev->reg_bar + ENA_REGS_DEV_CTL_OFF);
+	rc = wait_for_reset_state(ena_dev, timeout, 0);
+	if (rc != 0) {
+		pr_err("Reset indication didn't turn off\n");
+		return rc;
+	}
+
+	return 0;
+}
+
+static int ena_get_dev_stats(struct ena_com_dev *ena_dev,
+			     struct ena_com_stats_ctx *ctx,
+			     enum ena_admin_get_stats_type type)
+{
+	struct ena_admin_aq_get_stats_cmd *get_cmd = &ctx->get_cmd;
+	struct ena_admin_acq_get_stats_resp *get_resp = &ctx->get_resp;
+	struct ena_com_admin_queue *admin_queue;
+	int ret;
+
+	admin_queue = &ena_dev->admin_queue;
+
+	get_cmd->aq_common_descriptor.opcode = ENA_ADMIN_GET_STATS;
+	get_cmd->aq_common_descriptor.flags = 0;
+	get_cmd->type = type;
+
+	ret =  ena_com_execute_admin_command(admin_queue,
+					     (struct ena_admin_aq_entry *)get_cmd,
+					     sizeof(*get_cmd),
+					     (struct ena_admin_acq_entry *)get_resp,
+					     sizeof(*get_resp));
+
+	if (unlikely(ret))
+		pr_err("Failed to get stats. error: %d\n", ret);
+
+	return ret;
+}
+
+int ena_com_get_dev_basic_stats(struct ena_com_dev *ena_dev,
+				struct ena_admin_basic_stats *stats)
+{
+	struct ena_com_stats_ctx ctx;
+	int ret;
+
+	memset(&ctx, 0x0, sizeof(ctx));
+	ret = ena_get_dev_stats(ena_dev, &ctx, ENA_ADMIN_GET_STATS_TYPE_BASIC);
+	if (likely(ret == 0))
+		memcpy(stats, &ctx.get_resp.basic_stats,
+		       sizeof(ctx.get_resp.basic_stats));
+
+	return ret;
+}
+
+int ena_com_set_dev_mtu(struct ena_com_dev *ena_dev, int mtu)
+{
+	struct ena_com_admin_queue *admin_queue;
+	struct ena_admin_set_feat_cmd cmd;
+	struct ena_admin_set_feat_resp resp;
+	int ret;
+
+	if (!ena_com_check_supported_feature_id(ena_dev, ENA_ADMIN_MTU)) {
+		pr_info("Feature %d isn't supported\n", ENA_ADMIN_MTU);
+		return -EPERM;
+	}
+
+	memset(&cmd, 0x0, sizeof(cmd));
+	admin_queue = &ena_dev->admin_queue;
+
+	cmd.aq_common_descriptor.opcode = ENA_ADMIN_SET_FEATURE;
+	cmd.aq_common_descriptor.flags = 0;
+	cmd.feat_common.feature_id = ENA_ADMIN_MTU;
+	cmd.u.mtu.mtu = mtu;
+
+	ret = ena_com_execute_admin_command(admin_queue,
+					    (struct ena_admin_aq_entry *)&cmd,
+					    sizeof(cmd),
+					    (struct ena_admin_acq_entry *)&resp,
+					    sizeof(resp));
+
+	if (unlikely(ret))
+		pr_err("Failed to set mtu %d. error: %d\n", mtu, ret);
+
+	return ret;
+}
+
+int ena_com_get_offload_settings(struct ena_com_dev *ena_dev,
+				 struct ena_admin_feature_offload_desc *offload)
+{
+	int ret;
+	struct ena_admin_get_feat_resp resp;
+
+	ret = ena_com_get_feature(ena_dev, &resp,
+				  ENA_ADMIN_STATELESS_OFFLOAD_CONFIG);
+	if (unlikely(ret)) {
+		pr_err("Failed to get offload capabilities %d\n", ret);
+		return ret;
+	}
+
+	memcpy(offload, &resp.u.offload, sizeof(resp.u.offload));
+
+	return 0;
+}
+
+int ena_com_set_hash_function(struct ena_com_dev *ena_dev)
+{
+	struct ena_com_admin_queue *admin_queue = &ena_dev->admin_queue;
+	struct ena_rss *rss = &ena_dev->rss;
+	struct ena_admin_set_feat_cmd cmd;
+	struct ena_admin_set_feat_resp resp;
+	struct ena_admin_get_feat_resp get_resp;
+	int ret;
+
+	if (!ena_com_check_supported_feature_id(ena_dev,
+						ENA_ADMIN_RSS_HASH_FUNCTION)) {
+		pr_info("Feature %d isn't supported\n",
+			ENA_ADMIN_RSS_HASH_FUNCTION);
+		return -EPERM;
+	}
+
+	/* Validate hash function is supported */
+	ret = ena_com_get_feature(ena_dev, &get_resp,
+				  ENA_ADMIN_RSS_HASH_FUNCTION);
+	if (unlikely(ret))
+		return ret;
+
+	if (get_resp.u.flow_hash_func.supported_func & (1 << rss->hash_func)) {
+		pr_err("Func hash %d isn't supported by device, abort\n",
+		       rss->hash_func);
+		return -EPERM;
+	}
+
+	memset(&cmd, 0x0, sizeof(cmd));
+
+	cmd.aq_common_descriptor.opcode = ENA_ADMIN_SET_FEATURE;
+	cmd.aq_common_descriptor.flags =
+		ENA_ADMIN_AQ_COMMON_DESC_CTRL_DATA_INDIRECT_MASK;
+	cmd.feat_common.feature_id = ENA_ADMIN_RSS_HASH_FUNCTION;
+	cmd.u.flow_hash_func.init_val = rss->hash_init_val;
+	cmd.u.flow_hash_func.selected_func = 1 << rss->hash_func;
+
+	ret = ena_com_mem_addr_set(ena_dev,
+				   &cmd.control_buffer.address,
+				   rss->hash_key_dma_addr);
+	if (unlikely(ret)) {
+		pr_err("memory address set failed\n");
+		return ret;
+	}
+
+	cmd.control_buffer.length = sizeof(*rss->hash_key);
+
+	ret = ena_com_execute_admin_command(admin_queue,
+					    (struct ena_admin_aq_entry *)&cmd,
+					    sizeof(cmd),
+					    (struct ena_admin_acq_entry *)&resp,
+					    sizeof(resp));
+	if (unlikely(ret)) {
+		pr_err("Failed to set hash function %d. error: %d\n",
+		       rss->hash_func, ret);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+int ena_com_fill_hash_function(struct ena_com_dev *ena_dev,
+			       enum ena_admin_hash_functions func,
+			       const u8 *key, u16 key_len, u32 init_val)
+{
+	struct ena_rss *rss = &ena_dev->rss;
+	struct ena_admin_get_feat_resp get_resp;
+	struct ena_admin_feature_rss_flow_hash_control *hash_key =
+		rss->hash_key;
+	int rc;
+
+	/* Make sure size is a mult of DWs */
+	if (unlikely(key_len & 0x3))
+		return -EINVAL;
+
+	rc = ena_com_get_feature_ex(ena_dev, &get_resp,
+				    ENA_ADMIN_RSS_HASH_FUNCTION,
+				    rss->hash_key_dma_addr,
+				    sizeof(*rss->hash_key));
+	if (unlikely(rc))
+		return rc;
+
+	if (!((1 << func) & get_resp.u.flow_hash_func.supported_func)) {
+		pr_err("Flow hash function %d isn't supported\n", func);
+		return -EPERM;
+	}
+
+	switch (func) {
+	case ENA_ADMIN_TOEPLITZ:
+		if (key_len > sizeof(hash_key->key)) {
+			pr_err("key len (%hu) is bigger than the max supported (%zu)\n",
+			       key_len, sizeof(hash_key->key));
+			return -EINVAL;
+		}
+
+		memcpy(hash_key->key, key, key_len);
+		rss->hash_init_val = init_val;
+		hash_key->keys_num = key_len >> 2;
+		break;
+	case ENA_ADMIN_CRC32:
+		rss->hash_init_val = init_val;
+		break;
+	default:
+		pr_err("Invalid hash function (%d)\n", func);
+		return -EINVAL;
+	}
+
+	rc = ena_com_set_hash_function(ena_dev);
+
+	/* Restore the old function */
+	if (unlikely(rc))
+		ena_com_get_hash_function(ena_dev, NULL, NULL);
+
+	return rc;
+}
+
+int ena_com_get_hash_function(struct ena_com_dev *ena_dev,
+			      enum ena_admin_hash_functions *func,
+			      u8 *key)
+{
+	struct ena_rss *rss = &ena_dev->rss;
+	struct ena_admin_get_feat_resp get_resp;
+	struct ena_admin_feature_rss_flow_hash_control *hash_key =
+		rss->hash_key;
+	int rc;
+
+	rc = ena_com_get_feature_ex(ena_dev, &get_resp,
+				    ENA_ADMIN_RSS_HASH_FUNCTION,
+				    rss->hash_key_dma_addr,
+				    sizeof(*rss->hash_key));
+	if (unlikely(rc))
+		return rc;
+
+	rss->hash_func = get_resp.u.flow_hash_func.selected_func;
+	if (func)
+		*func = rss->hash_func;
+
+	if (key)
+		memcpy(key, hash_key->key, (size_t)(hash_key->keys_num) << 2);
+
+	return 0;
+}
+
+int ena_com_get_hash_ctrl(struct ena_com_dev *ena_dev,
+			  enum ena_admin_flow_hash_proto proto,
+			  u16 *fields)
+{
+	struct ena_rss *rss = &ena_dev->rss;
+	struct ena_admin_get_feat_resp get_resp;
+	int rc;
+
+	rc = ena_com_get_feature_ex(ena_dev, &get_resp,
+				    ENA_ADMIN_RSS_HASH_INPUT,
+				    rss->hash_ctrl_dma_addr,
+				    sizeof(*rss->hash_ctrl));
+	if (unlikely(rc))
+		return rc;
+
+	if (fields)
+		*fields = rss->hash_ctrl->selected_fields[proto].fields;
+
+	return 0;
+}
+
+int ena_com_set_hash_ctrl(struct ena_com_dev *ena_dev)
+{
+	struct ena_com_admin_queue *admin_queue = &ena_dev->admin_queue;
+	struct ena_rss *rss = &ena_dev->rss;
+	struct ena_admin_feature_rss_hash_control *hash_ctrl = rss->hash_ctrl;
+	struct ena_admin_set_feat_cmd cmd;
+	struct ena_admin_set_feat_resp resp;
+	int ret;
+
+	if (!ena_com_check_supported_feature_id(ena_dev,
+						ENA_ADMIN_RSS_HASH_INPUT)) {
+		pr_info("Feature %d isn't supported\n", ENA_ADMIN_RSS_HASH_INPUT);
+		return -EPERM;
+	}
+
+	memset(&cmd, 0x0, sizeof(cmd));
+
+	cmd.aq_common_descriptor.opcode = ENA_ADMIN_SET_FEATURE;
+	cmd.aq_common_descriptor.flags =
+		ENA_ADMIN_AQ_COMMON_DESC_CTRL_DATA_INDIRECT_MASK;
+	cmd.feat_common.feature_id = ENA_ADMIN_RSS_HASH_INPUT;
+	cmd.u.flow_hash_input.enabled_input_sort =
+		ENA_ADMIN_FEATURE_RSS_FLOW_HASH_INPUT_L3_SORT_MASK |
+		ENA_ADMIN_FEATURE_RSS_FLOW_HASH_INPUT_L4_SORT_MASK;
+
+	ret = ena_com_mem_addr_set(ena_dev,
+				   &cmd.control_buffer.address,
+				   rss->hash_ctrl_dma_addr);
+	if (unlikely(ret)) {
+		pr_err("memory address set failed\n");
+		return ret;
+	}
+	cmd.control_buffer.length = sizeof(*hash_ctrl);
+
+	ret = ena_com_execute_admin_command(admin_queue,
+					    (struct ena_admin_aq_entry *)&cmd,
+					    sizeof(cmd),
+					    (struct ena_admin_acq_entry *)&resp,
+					    sizeof(resp));
+	if (unlikely(ret))
+		pr_err("Failed to set hash input. error: %d\n", ret);
+
+	return ret;
+}
+
+int ena_com_set_default_hash_ctrl(struct ena_com_dev *ena_dev)
+{
+	struct ena_rss *rss = &ena_dev->rss;
+	struct ena_admin_feature_rss_hash_control *hash_ctrl =
+		rss->hash_ctrl;
+	u16 available_fields = 0;
+	int rc, i;
+
+	/* Get the supported hash input */
+	rc = ena_com_get_hash_ctrl(ena_dev, 0, NULL);
+	if (unlikely(rc))
+		return rc;
+
+	hash_ctrl->selected_fields[ENA_ADMIN_RSS_TCP4].fields =
+		ENA_ADMIN_RSS_L3_SA | ENA_ADMIN_RSS_L3_DA |
+		ENA_ADMIN_RSS_L4_DP | ENA_ADMIN_RSS_L4_SP;
+
+	hash_ctrl->selected_fields[ENA_ADMIN_RSS_UDP4].fields =
+		ENA_ADMIN_RSS_L3_SA | ENA_ADMIN_RSS_L3_DA |
+		ENA_ADMIN_RSS_L4_DP | ENA_ADMIN_RSS_L4_SP;
+
+	hash_ctrl->selected_fields[ENA_ADMIN_RSS_TCP6].fields =
+		ENA_ADMIN_RSS_L3_SA | ENA_ADMIN_RSS_L3_DA |
+		ENA_ADMIN_RSS_L4_DP | ENA_ADMIN_RSS_L4_SP;
+
+	hash_ctrl->selected_fields[ENA_ADMIN_RSS_UDP6].fields =
+		ENA_ADMIN_RSS_L3_SA | ENA_ADMIN_RSS_L3_DA |
+		ENA_ADMIN_RSS_L4_DP | ENA_ADMIN_RSS_L4_SP;
+
+	hash_ctrl->selected_fields[ENA_ADMIN_RSS_IP4].fields =
+		ENA_ADMIN_RSS_L3_SA | ENA_ADMIN_RSS_L3_DA;
+
+	hash_ctrl->selected_fields[ENA_ADMIN_RSS_IP6].fields =
+		ENA_ADMIN_RSS_L3_SA | ENA_ADMIN_RSS_L3_DA;
+
+	hash_ctrl->selected_fields[ENA_ADMIN_RSS_IP4_FRAG].fields =
+		ENA_ADMIN_RSS_L3_SA | ENA_ADMIN_RSS_L3_DA;
+
+	hash_ctrl->selected_fields[ENA_ADMIN_RSS_IP4_FRAG].fields =
+		ENA_ADMIN_RSS_L2_DA | ENA_ADMIN_RSS_L2_SA;
+
+	for (i = 0; i < ENA_ADMIN_RSS_PROTO_NUM; i++) {
+		available_fields = hash_ctrl->selected_fields[i].fields &
+				hash_ctrl->supported_fields[i].fields;
+		if (available_fields != hash_ctrl->selected_fields[i].fields) {
+			pr_err("hash control doesn't support all the desire configuration. proto %x supported %x selected %x\n",
+			       i, hash_ctrl->supported_fields[i].fields,
+			       hash_ctrl->selected_fields[i].fields);
+			return -EPERM;
+		}
+	}
+
+	rc = ena_com_set_hash_ctrl(ena_dev);
+
+	/* In case of failure, restore the old hash ctrl */
+	if (unlikely(rc))
+		ena_com_get_hash_ctrl(ena_dev, 0, NULL);
+
+	return rc;
+}
+
+int ena_com_fill_hash_ctrl(struct ena_com_dev *ena_dev,
+			   enum ena_admin_flow_hash_proto proto,
+			   u16 hash_fields)
+{
+	struct ena_rss *rss = &ena_dev->rss;
+	struct ena_admin_feature_rss_hash_control *hash_ctrl = rss->hash_ctrl;
+	u16 supported_fields;
+	int rc;
+
+	if (proto >= ENA_ADMIN_RSS_PROTO_NUM) {
+		pr_err("Invalid proto num (%u)\n", proto);
+		return -EINVAL;
+	}
+
+	/* Get the ctrl table */
+	rc = ena_com_get_hash_ctrl(ena_dev, proto, NULL);
+	if (unlikely(rc))
+		return rc;
+
+	/* Make sure all the fields are supported */
+	supported_fields = hash_ctrl->supported_fields[proto].fields;
+	if ((hash_fields & supported_fields) != hash_fields) {
+		pr_err("proto %d doesn't support the required fields %x. supports only: %x\n",
+		       proto, hash_fields, supported_fields);
+	}
+
+	hash_ctrl->selected_fields[proto].fields = hash_fields;
+
+	rc = ena_com_set_hash_ctrl(ena_dev);
+
+	/* In case of failure, restore the old hash ctrl */
+	if (unlikely(rc))
+		ena_com_get_hash_ctrl(ena_dev, 0, NULL);
+
+	return 0;
+}
+
+int ena_com_indirect_table_fill_entry(struct ena_com_dev *ena_dev,
+				      u16 entry_idx, u16 entry_value)
+{
+	struct ena_rss *rss = &ena_dev->rss;
+
+	if (unlikely(entry_idx >= (1 << rss->tbl_log_size)))
+		return -EINVAL;
+
+	if (unlikely((entry_value > ENA_TOTAL_NUM_QUEUES)))
+		return -EINVAL;
+
+	rss->host_rss_ind_tbl[entry_idx] = entry_value;
+
+	return 0;
+}
+
+int ena_com_indirect_table_set(struct ena_com_dev *ena_dev)
+{
+	struct ena_com_admin_queue *admin_queue = &ena_dev->admin_queue;
+	struct ena_rss *rss = &ena_dev->rss;
+	struct ena_admin_set_feat_cmd cmd;
+	struct ena_admin_set_feat_resp resp;
+	int ret;
+
+	if (!ena_com_check_supported_feature_id(
+		    ena_dev, ENA_ADMIN_RSS_REDIRECTION_TABLE_CONFIG)) {
+		pr_info("Feature %d isn't supported\n",
+			ENA_ADMIN_RSS_REDIRECTION_TABLE_CONFIG);
+		return -EPERM;
+	}
+
+	ret = ena_com_ind_tbl_convert_to_device(ena_dev);
+	if (ret) {
+		pr_err("Failed to convert host indirection table to device table\n");
+		return ret;
+	}
+
+	memset(&cmd, 0x0, sizeof(cmd));
+
+	cmd.aq_common_descriptor.opcode = ENA_ADMIN_SET_FEATURE;
+	cmd.aq_common_descriptor.flags =
+		ENA_ADMIN_AQ_COMMON_DESC_CTRL_DATA_INDIRECT_MASK;
+	cmd.feat_common.feature_id = ENA_ADMIN_RSS_REDIRECTION_TABLE_CONFIG;
+	cmd.u.ind_table.size = rss->tbl_log_size;
+	cmd.u.ind_table.inline_index = 0xFFFFFFFF;
+
+	ret = ena_com_mem_addr_set(ena_dev,
+				   &cmd.control_buffer.address,
+				   rss->rss_ind_tbl_dma_addr);
+	if (unlikely(ret)) {
+		pr_err("memory address set failed\n");
+		return ret;
+	}
+
+	cmd.control_buffer.length = (1ULL << rss->tbl_log_size) *
+		sizeof(struct ena_admin_rss_ind_table_entry);
+
+	ret = ena_com_execute_admin_command(admin_queue,
+					    (struct ena_admin_aq_entry *)&cmd,
+					    sizeof(cmd),
+					    (struct ena_admin_acq_entry *)&resp,
+					    sizeof(resp));
+
+	if (unlikely(ret))
+		pr_err("Failed to set indirect table. error: %d\n", ret);
+
+	return ret;
+}
+
+int ena_com_indirect_table_get(struct ena_com_dev *ena_dev, u32 *ind_tbl)
+{
+	struct ena_rss *rss = &ena_dev->rss;
+	struct ena_admin_get_feat_resp get_resp;
+	u32 tbl_size;
+	int i, rc;
+
+	tbl_size = (1ULL << rss->tbl_log_size) *
+		sizeof(struct ena_admin_rss_ind_table_entry);
+
+	rc = ena_com_get_feature_ex(ena_dev, &get_resp,
+				    ENA_ADMIN_RSS_REDIRECTION_TABLE_CONFIG,
+				    rss->rss_ind_tbl_dma_addr,
+				    tbl_size);
+	if (unlikely(rc))
+		return rc;
+
+	if (!ind_tbl)
+		return 0;
+
+	rc = ena_com_ind_tbl_convert_from_device(ena_dev);
+	if (unlikely(rc))
+		return rc;
+
+	for (i = 0; i < (1 << rss->tbl_log_size); i++)
+		ind_tbl[i] = rss->host_rss_ind_tbl[i];
+
+	return 0;
+}
+
+int ena_com_rss_init(struct ena_com_dev *ena_dev, u16 indr_tbl_log_size)
+{
+	int rc;
+
+	memset(&ena_dev->rss, 0x0, sizeof(ena_dev->rss));
+
+	rc = ena_com_indirect_table_allocate(ena_dev, indr_tbl_log_size);
+	if (unlikely(rc))
+		goto err_indr_tbl;
+
+	rc = ena_com_hash_key_allocate(ena_dev);
+	if (unlikely(rc))
+		goto err_hash_key;
+
+	rc = ena_com_hash_ctrl_init(ena_dev);
+	if (unlikely(rc))
+		goto err_hash_ctrl;
+
+	return 0;
+
+err_hash_ctrl:
+	ena_com_hash_key_destroy(ena_dev);
+err_hash_key:
+	ena_com_indirect_table_destroy(ena_dev);
+err_indr_tbl:
+
+	return rc;
+}
+
+void ena_com_rss_destroy(struct ena_com_dev *ena_dev)
+{
+	ena_com_indirect_table_destroy(ena_dev);
+	ena_com_hash_key_destroy(ena_dev);
+	ena_com_hash_ctrl_destroy(ena_dev);
+
+	memset(&ena_dev->rss, 0x0, sizeof(ena_dev->rss));
+}
+
+int ena_com_allocate_host_info(struct ena_com_dev *ena_dev)
+{
+	struct ena_host_attribute *host_attr = &ena_dev->host_attr;
+
+	host_attr->host_info =
+		dma_zalloc_coherent(ena_dev->dmadev, SZ_4K,
+				    &host_attr->host_info_dma_addr, GFP_KERNEL);
+	if (unlikely(!host_attr->host_info))
+		return -ENOMEM;
+
+	return 0;
+}
+
+int ena_com_allocate_debug_area(struct ena_com_dev *ena_dev,
+				u32 debug_area_size)
+{
+	struct ena_host_attribute *host_attr = &ena_dev->host_attr;
+
+	host_attr->debug_area_virt_addr =
+		dma_zalloc_coherent(ena_dev->dmadev, debug_area_size,
+				    &host_attr->debug_area_dma_addr, GFP_KERNEL);
+	if (unlikely(!host_attr->debug_area_virt_addr)) {
+		host_attr->debug_area_size = 0;
+		return -ENOMEM;
+	}
+
+	host_attr->debug_area_size = debug_area_size;
+
+	return 0;
+}
+
+void ena_com_delete_host_info(struct ena_com_dev *ena_dev)
+{
+	struct ena_host_attribute *host_attr = &ena_dev->host_attr;
+
+	if (host_attr->host_info) {
+		dma_free_coherent(ena_dev->dmadev, SZ_4K, host_attr->host_info,
+				  host_attr->host_info_dma_addr);
+		host_attr->host_info = NULL;
+	}
+}
+
+void ena_com_delete_debug_area(struct ena_com_dev *ena_dev)
+{
+	struct ena_host_attribute *host_attr = &ena_dev->host_attr;
+
+	if (host_attr->debug_area_virt_addr) {
+		dma_free_coherent(ena_dev->dmadev, host_attr->debug_area_size,
+				  host_attr->debug_area_virt_addr,
+				  host_attr->debug_area_dma_addr);
+		host_attr->debug_area_virt_addr = NULL;
+	}
+}
+
+int ena_com_set_host_attributes(struct ena_com_dev *ena_dev)
+{
+	struct ena_host_attribute *host_attr = &ena_dev->host_attr;
+	struct ena_com_admin_queue *admin_queue;
+	struct ena_admin_set_feat_cmd cmd;
+	struct ena_admin_set_feat_resp resp;
+
+	int ret;
+
+	if (!ena_com_check_supported_feature_id(ena_dev,
+						ENA_ADMIN_HOST_ATTR_CONFIG)) {
+		pr_warn("Set host attribute isn't supported\n");
+		return -EPERM;
+	}
+
+	memset(&cmd, 0x0, sizeof(cmd));
+	admin_queue = &ena_dev->admin_queue;
+
+	cmd.aq_common_descriptor.opcode = ENA_ADMIN_SET_FEATURE;
+	cmd.feat_common.feature_id = ENA_ADMIN_HOST_ATTR_CONFIG;
+
+	ret = ena_com_mem_addr_set(ena_dev,
+				   &cmd.u.host_attr.debug_ba,
+				   host_attr->debug_area_dma_addr);
+	if (unlikely(ret)) {
+		pr_err("memory address set failed\n");
+		return ret;
+	}
+
+	ret = ena_com_mem_addr_set(ena_dev,
+				   &cmd.u.host_attr.os_info_ba,
+				   host_attr->host_info_dma_addr);
+	if (unlikely(ret)) {
+		pr_err("memory address set failed\n");
+		return ret;
+	}
+
+	cmd.u.host_attr.debug_area_size = host_attr->debug_area_size;
+
+	ret = ena_com_execute_admin_command(admin_queue,
+					    (struct ena_admin_aq_entry *)&cmd,
+					    sizeof(cmd),
+					    (struct ena_admin_acq_entry *)&resp,
+					    sizeof(resp));
+
+	if (unlikely(ret))
+		pr_err("Failed to set host attributes: %d\n", ret);
+
+	return ret;
+}
+
+/* Interrupt moderation */
+bool ena_com_interrupt_moderation_supported(struct ena_com_dev *ena_dev)
+{
+	return ena_com_check_supported_feature_id(ena_dev,
+						  ENA_ADMIN_INTERRUPT_MODERATION);
+}
+
+int ena_com_update_nonadaptive_moderation_interval_tx(struct ena_com_dev *ena_dev,
+						      u32 tx_coalesce_usecs)
+{
+	if (!ena_dev->intr_delay_resolution) {
+		pr_err("Illegal interrupt delay granularity value\n");
+		return -EFAULT;
+	}
+
+	ena_dev->intr_moder_tx_interval = tx_coalesce_usecs /
+		ena_dev->intr_delay_resolution;
+
+	return 0;
+}
+
+int ena_com_update_nonadaptive_moderation_interval_rx(struct ena_com_dev *ena_dev,
+						      u32 rx_coalesce_usecs)
+{
+	if (!ena_dev->intr_delay_resolution) {
+		pr_err("Illegal interrupt delay granularity value\n");
+		return -EFAULT;
+	}
+
+	/* We use LOWEST entry of moderation table for storing
+	 * nonadaptive interrupt coalescing values
+	 */
+	ena_dev->intr_moder_tbl[ENA_INTR_MODER_LOWEST].intr_moder_interval =
+		rx_coalesce_usecs / ena_dev->intr_delay_resolution;
+
+	return 0;
+}
+
+void ena_com_destroy_interrupt_moderation(struct ena_com_dev *ena_dev)
+{
+	if (ena_dev->intr_moder_tbl)
+		devm_kfree(ena_dev->dmadev, ena_dev->intr_moder_tbl);
+	ena_dev->intr_moder_tbl = NULL;
+}
+
+int ena_com_init_interrupt_moderation(struct ena_com_dev *ena_dev)
+{
+	struct ena_admin_get_feat_resp get_resp;
+	u16 delay_resolution;
+	int rc;
+
+	rc = ena_com_get_feature(ena_dev, &get_resp,
+				 ENA_ADMIN_INTERRUPT_MODERATION);
+
+	if (rc) {
+		if (rc == -EPERM) {
+			pr_info("Feature %d isn't supported\n",
+				ENA_ADMIN_INTERRUPT_MODERATION);
+			rc = 0;
+		} else {
+			pr_err("Failed to get interrupt moderation admin cmd. rc: %d\n",
+			       rc);
+		}
+
+		/* no moderation supported, disable adaptive support */
+		ena_com_disable_adaptive_moderation(ena_dev);
+		return rc;
+	}
+
+	rc = ena_com_init_interrupt_moderation_table(ena_dev);
+	if (rc)
+		goto err;
+
+	/* if moderation is supported by device we set adaptive moderation */
+	delay_resolution = get_resp.u.intr_moderation.intr_delay_resolution;
+	ena_com_update_intr_delay_resolution(ena_dev, delay_resolution);
+	ena_com_enable_adaptive_moderation(ena_dev);
+
+	return 0;
+err:
+	ena_com_destroy_interrupt_moderation(ena_dev);
+	return rc;
+}
+
+void ena_com_config_default_interrupt_moderation_table(struct ena_com_dev *ena_dev)
+{
+	struct ena_intr_moder_entry *intr_moder_tbl = ena_dev->intr_moder_tbl;
+
+	if (!intr_moder_tbl)
+		return;
+
+	intr_moder_tbl[ENA_INTR_MODER_LOWEST].intr_moder_interval =
+		ENA_INTR_LOWEST_USECS;
+	intr_moder_tbl[ENA_INTR_MODER_LOWEST].pkts_per_interval =
+		ENA_INTR_LOWEST_PKTS;
+	intr_moder_tbl[ENA_INTR_MODER_LOWEST].bytes_per_interval =
+		ENA_INTR_LOWEST_BYTES;
+
+	intr_moder_tbl[ENA_INTR_MODER_LOW].intr_moder_interval =
+		ENA_INTR_LOW_USECS;
+	intr_moder_tbl[ENA_INTR_MODER_LOW].pkts_per_interval =
+		ENA_INTR_LOW_PKTS;
+	intr_moder_tbl[ENA_INTR_MODER_LOW].bytes_per_interval =
+		ENA_INTR_LOW_BYTES;
+
+	intr_moder_tbl[ENA_INTR_MODER_MID].intr_moder_interval =
+		ENA_INTR_MID_USECS;
+	intr_moder_tbl[ENA_INTR_MODER_MID].pkts_per_interval =
+		ENA_INTR_MID_PKTS;
+	intr_moder_tbl[ENA_INTR_MODER_MID].bytes_per_interval =
+		ENA_INTR_MID_BYTES;
+
+	intr_moder_tbl[ENA_INTR_MODER_HIGH].intr_moder_interval =
+		ENA_INTR_HIGH_USECS;
+	intr_moder_tbl[ENA_INTR_MODER_HIGH].pkts_per_interval =
+		ENA_INTR_HIGH_PKTS;
+	intr_moder_tbl[ENA_INTR_MODER_HIGH].bytes_per_interval =
+		ENA_INTR_HIGH_BYTES;
+
+	intr_moder_tbl[ENA_INTR_MODER_HIGHEST].intr_moder_interval =
+		ENA_INTR_HIGHEST_USECS;
+	intr_moder_tbl[ENA_INTR_MODER_HIGHEST].pkts_per_interval =
+		ENA_INTR_HIGHEST_PKTS;
+	intr_moder_tbl[ENA_INTR_MODER_HIGHEST].bytes_per_interval =
+		ENA_INTR_HIGHEST_BYTES;
+}
+
+unsigned int ena_com_get_nonadaptive_moderation_interval_tx(struct ena_com_dev *ena_dev)
+{
+	return ena_dev->intr_moder_tx_interval;
+}
+
+unsigned int ena_com_get_nonadaptive_moderation_interval_rx(struct ena_com_dev *ena_dev)
+{
+	struct ena_intr_moder_entry *intr_moder_tbl = ena_dev->intr_moder_tbl;
+
+	if (intr_moder_tbl)
+		return intr_moder_tbl[ENA_INTR_MODER_LOWEST].intr_moder_interval;
+
+	return 0;
+}
+
+void ena_com_init_intr_moderation_entry(struct ena_com_dev *ena_dev,
+					enum ena_intr_moder_level level,
+					struct ena_intr_moder_entry *entry)
+{
+	struct ena_intr_moder_entry *intr_moder_tbl = ena_dev->intr_moder_tbl;
+
+	if (level >= ENA_INTR_MAX_NUM_OF_LEVELS)
+		return;
+
+	intr_moder_tbl[level].intr_moder_interval = entry->intr_moder_interval;
+	if (ena_dev->intr_delay_resolution)
+		intr_moder_tbl[level].intr_moder_interval /=
+			ena_dev->intr_delay_resolution;
+	intr_moder_tbl[level].pkts_per_interval = entry->pkts_per_interval;
+
+	/* use hardcoded value until ethtool supports bytecount parameter */
+	if (entry->bytes_per_interval != ENA_INTR_BYTE_COUNT_NOT_SUPPORTED)
+		intr_moder_tbl[level].bytes_per_interval = entry->bytes_per_interval;
+}
+
+void ena_com_get_intr_moderation_entry(struct ena_com_dev *ena_dev,
+				       enum ena_intr_moder_level level,
+				       struct ena_intr_moder_entry *entry)
+{
+	struct ena_intr_moder_entry *intr_moder_tbl = ena_dev->intr_moder_tbl;
+
+	if (level >= ENA_INTR_MAX_NUM_OF_LEVELS)
+		return;
+
+	entry->intr_moder_interval = intr_moder_tbl[level].intr_moder_interval;
+	if (ena_dev->intr_delay_resolution)
+		entry->intr_moder_interval *= ena_dev->intr_delay_resolution;
+	entry->pkts_per_interval =
+	intr_moder_tbl[level].pkts_per_interval;
+	entry->bytes_per_interval = intr_moder_tbl[level].bytes_per_interval;
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/amazon/ena/ena_com.h
@@ -0,0 +1,1038 @@
+/*
+ * Copyright 2015 Amazon.com, Inc. or its affiliates.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef ENA_COM
+#define ENA_COM
+
+#include <linux/delay.h>
+#include <linux/dma-mapping.h>
+#include <linux/gfp.h>
+#include <linux/sched.h>
+#include <linux/sizes.h>
+#include <linux/spinlock.h>
+#include <linux/types.h>
+#include <linux/wait.h>
+
+#include "ena_common_defs.h"
+#include "ena_admin_defs.h"
+#include "ena_eth_io_defs.h"
+#include "ena_regs_defs.h"
+
+#undef pr_fmt
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#define ENA_MAX_NUM_IO_QUEUES		128U
+/* We need to queues for each IO (on for Tx and one for Rx) */
+#define ENA_TOTAL_NUM_QUEUES		(2 * (ENA_MAX_NUM_IO_QUEUES))
+
+#define ENA_MAX_HANDLERS 256
+
+#define ENA_MAX_PHYS_ADDR_SIZE_BITS 48
+
+/* Unit in usec */
+#define ENA_REG_READ_TIMEOUT 200000
+
+#define ADMIN_SQ_SIZE(depth)	((depth) * sizeof(struct ena_admin_aq_entry))
+#define ADMIN_CQ_SIZE(depth)	((depth) * sizeof(struct ena_admin_acq_entry))
+#define ADMIN_AENQ_SIZE(depth)	((depth) * sizeof(struct ena_admin_aenq_entry))
+
+/*****************************************************************************/
+/*****************************************************************************/
+/* ENA adaptive interrupt moderation settings */
+
+#define ENA_INTR_LOWEST_USECS           (0)
+#define ENA_INTR_LOWEST_PKTS            (3)
+#define ENA_INTR_LOWEST_BYTES           (2 * 1524)
+
+#define ENA_INTR_LOW_USECS              (32)
+#define ENA_INTR_LOW_PKTS               (12)
+#define ENA_INTR_LOW_BYTES              (16 * 1024)
+
+#define ENA_INTR_MID_USECS              (80)
+#define ENA_INTR_MID_PKTS               (48)
+#define ENA_INTR_MID_BYTES              (64 * 1024)
+
+#define ENA_INTR_HIGH_USECS             (128)
+#define ENA_INTR_HIGH_PKTS              (96)
+#define ENA_INTR_HIGH_BYTES             (128 * 1024)
+
+#define ENA_INTR_HIGHEST_USECS          (192)
+#define ENA_INTR_HIGHEST_PKTS           (128)
+#define ENA_INTR_HIGHEST_BYTES          (192 * 1024)
+
+#define ENA_INTR_INITIAL_TX_INTERVAL_USECS		196
+#define ENA_INTR_INITIAL_RX_INTERVAL_USECS		4
+#define ENA_INTR_DELAY_OLD_VALUE_WEIGHT			6
+#define ENA_INTR_DELAY_NEW_VALUE_WEIGHT			4
+#define ENA_INTR_MODER_LEVEL_STRIDE			2
+#define ENA_INTR_BYTE_COUNT_NOT_SUPPORTED		0xFFFFFF
+
+enum ena_intr_moder_level {
+	ENA_INTR_MODER_LOWEST = 0,
+	ENA_INTR_MODER_LOW,
+	ENA_INTR_MODER_MID,
+	ENA_INTR_MODER_HIGH,
+	ENA_INTR_MODER_HIGHEST,
+	ENA_INTR_MAX_NUM_OF_LEVELS,
+};
+
+struct ena_intr_moder_entry {
+	unsigned int intr_moder_interval;
+	unsigned int pkts_per_interval;
+	unsigned int bytes_per_interval;
+};
+
+enum queue_direction {
+	ENA_COM_IO_QUEUE_DIRECTION_TX,
+	ENA_COM_IO_QUEUE_DIRECTION_RX
+};
+
+struct ena_com_buf {
+	dma_addr_t paddr; /**< Buffer physical address */
+	u16 len; /**< Buffer length in bytes */
+};
+
+struct ena_com_rx_buf_info {
+	u16 len;
+	u16 req_id;
+};
+
+struct ena_com_io_desc_addr {
+	u8 __iomem *pbuf_dev_addr; /* LLQ address */
+	u8 *virt_addr;
+	dma_addr_t phys_addr;
+};
+
+struct ena_com_tx_meta {
+	u16 mss;
+	u16 l3_hdr_len;
+	u16 l3_hdr_offset;
+	u16 l4_hdr_len; /* In words */
+};
+
+struct ena_com_io_cq {
+	struct ena_com_io_desc_addr cdesc_addr;
+
+	/* Interrupt unmask register */
+	u32 __iomem *unmask_reg;
+
+	/* The completion queue head doorbell register */
+	u32 __iomem *cq_head_db_reg;
+
+	/* numa configuration register (for TPH) */
+	u32 __iomem *numa_node_cfg_reg;
+
+	/* The value to write to the above register to unmask
+	 * the interrupt of this queue
+	 */
+	u32 msix_vector;
+
+	enum queue_direction direction;
+
+	/* holds the number of cdesc of the current packet */
+	u16 cur_rx_pkt_cdesc_count;
+	/* save the firt cdesc idx of the current packet */
+	u16 cur_rx_pkt_cdesc_start_idx;
+
+	u16 q_depth;
+	/* Caller qid */
+	u16 qid;
+
+	/* Device queue index */
+	u16 idx;
+	u16 head;
+	u16 last_head_update;
+	u8 phase;
+	u8 cdesc_entry_size_in_bytes;
+
+} ____cacheline_aligned;
+
+struct ena_com_io_sq {
+	struct ena_com_io_desc_addr desc_addr;
+
+	u32 __iomem *db_addr;
+	u8 __iomem *header_addr;
+
+	enum queue_direction direction;
+	enum ena_admin_placement_policy_type mem_queue_type;
+
+	u32 msix_vector;
+	struct ena_com_tx_meta cached_tx_meta;
+
+	u16 q_depth;
+	u16 qid;
+
+	u16 idx;
+	u16 tail;
+	u16 next_to_comp;
+	u32 tx_max_header_size;
+	u8 phase;
+	u8 desc_entry_size;
+	u8 dma_addr_bits;
+} ____cacheline_aligned;
+
+struct ena_com_admin_cq {
+	struct ena_admin_acq_entry *entries;
+	dma_addr_t dma_addr;
+
+	u16 head;
+	u8 phase;
+};
+
+struct ena_com_admin_sq {
+	struct ena_admin_aq_entry *entries;
+	dma_addr_t dma_addr;
+
+	u32 __iomem *db_addr;
+
+	u16 head;
+	u16 tail;
+	u8 phase;
+
+};
+
+struct ena_com_stats_admin {
+	u32 aborted_cmd;
+	u32 submitted_cmd;
+	u32 completed_cmd;
+	u32 out_of_space;
+	u32 no_completion;
+};
+
+struct ena_com_admin_queue {
+	void *q_dmadev;
+	spinlock_t q_lock; /* spinlock for the admin queue */
+	struct ena_comp_ctx *comp_ctx;
+	u16 q_depth;
+	struct ena_com_admin_cq cq;
+	struct ena_com_admin_sq sq;
+
+	/* Indicate if the admin queue should poll for completion */
+	bool polling;
+
+	u16 curr_cmd_id;
+
+	/* Indicate that the ena was initialized and can
+	 * process new admin commands
+	 */
+	bool running_state;
+
+	/* Count the number of outstanding admin commands */
+	atomic_t outstanding_cmds;
+
+	struct ena_com_stats_admin stats;
+};
+
+struct ena_aenq_handlers;
+
+struct ena_com_aenq {
+	u16 head;
+	u8 phase;
+	struct ena_admin_aenq_entry *entries;
+	dma_addr_t dma_addr;
+	u16 q_depth;
+	struct ena_aenq_handlers *aenq_handlers;
+};
+
+struct ena_com_mmio_read {
+	struct ena_admin_ena_mmio_req_read_less_resp *read_resp;
+	dma_addr_t read_resp_dma_addr;
+	u16 seq_num;
+	bool readless_supported;
+	/* spin lock to ensure a single outstanding read */
+	spinlock_t lock;
+};
+
+struct ena_rss {
+	/* Indirect table */
+	u16 *host_rss_ind_tbl;
+	struct ena_admin_rss_ind_table_entry *rss_ind_tbl;
+	dma_addr_t rss_ind_tbl_dma_addr;
+	u16 tbl_log_size;
+
+	/* Hash key */
+	enum ena_admin_hash_functions hash_func;
+	struct ena_admin_feature_rss_flow_hash_control *hash_key;
+	dma_addr_t hash_key_dma_addr;
+	u32 hash_init_val;
+
+	/* Flow Control */
+	struct ena_admin_feature_rss_hash_control *hash_ctrl;
+	dma_addr_t hash_ctrl_dma_addr;
+
+};
+
+struct ena_host_attribute {
+	/* Debug area */
+	u8 *debug_area_virt_addr;
+	dma_addr_t debug_area_dma_addr;
+	u32 debug_area_size;
+
+	/* Host information */
+	struct ena_admin_host_info *host_info;
+	dma_addr_t host_info_dma_addr;
+};
+
+/* Each ena_dev is a PCI function. */
+struct ena_com_dev {
+	struct ena_com_admin_queue admin_queue;
+	struct ena_com_aenq aenq;
+	struct ena_com_io_cq io_cq_queues[ENA_TOTAL_NUM_QUEUES];
+	struct ena_com_io_sq io_sq_queues[ENA_TOTAL_NUM_QUEUES];
+	u8 __iomem *reg_bar;
+	void __iomem *mem_bar;
+	void *dmadev;
+
+	enum ena_admin_placement_policy_type tx_mem_queue_type;
+	u32 tx_max_header_size;
+	u16 stats_func; /* Selected function for extended statistic dump */
+	u16 stats_queue; /* Selected queue for extended statistic dump */
+
+	struct ena_com_mmio_read mmio_read;
+
+	struct ena_rss rss;
+	u32 supported_features;
+	u32 dma_addr_bits;
+
+	struct ena_host_attribute host_attr;
+	bool adaptive_coalescing;
+	u16 intr_delay_resolution;
+	u32 intr_moder_tx_interval;
+	struct ena_intr_moder_entry *intr_moder_tbl;
+};
+
+struct ena_com_dev_get_features_ctx {
+	struct ena_admin_queue_feature_desc max_queues;
+	struct ena_admin_device_attr_feature_desc dev_attr;
+	struct ena_admin_feature_aenq_desc aenq;
+	struct ena_admin_feature_offload_desc offload;
+};
+
+struct ena_com_create_io_ctx {
+	enum ena_admin_placement_policy_type mem_queue_type;
+	enum queue_direction direction;
+	int numa_node;
+	u32 msix_vector;
+	u16 queue_size;
+	u16 qid;
+};
+
+typedef void (*ena_aenq_handler)(void *data,
+	struct ena_admin_aenq_entry *aenq_e);
+
+/* Holds aenq handlers. Indexed by AENQ event group */
+struct ena_aenq_handlers {
+	ena_aenq_handler handlers[ENA_MAX_HANDLERS];
+	ena_aenq_handler unimplemented_handler;
+};
+
+/*****************************************************************************/
+/*****************************************************************************/
+
+/* ena_com_mmio_reg_read_request_init - Init the mmio reg read mechanism
+ * @ena_dev: ENA communication layer struct
+ *
+ * Initialize the register read mechanism.
+ *
+ * @note: This method must be the first stage in the initialization sequence.
+ *
+ * @return - 0 on success, negative value on failure.
+ */
+int ena_com_mmio_reg_read_request_init(struct ena_com_dev *ena_dev);
+
+/* ena_com_set_mmio_read_mode - Enable/disable the mmio reg read mechanism
+ * @ena_dev: ENA communication layer struct
+ * @readless_supported: readless mode (enable/disable)
+ */
+void ena_com_set_mmio_read_mode(struct ena_com_dev *ena_dev,
+				bool readless_supported);
+
+/* ena_com_mmio_reg_read_request_write_dev_addr - Write the mmio reg read return
+ * value physical address.
+ * @ena_dev: ENA communication layer struct
+ */
+void ena_com_mmio_reg_read_request_write_dev_addr(struct ena_com_dev *ena_dev);
+
+/* ena_com_mmio_reg_read_request_destroy - Destroy the mmio reg read mechanism
+ * @ena_dev: ENA communication layer struct
+ */
+void ena_com_mmio_reg_read_request_destroy(struct ena_com_dev *ena_dev);
+
+/* ena_com_admin_init - Init the admin and the async queues
+ * @ena_dev: ENA communication layer struct
+ * @aenq_handlers: Those handlers to be called upon event.
+ * @init_spinlock: Indicate if this method should init the admin spinlock or
+ * the spinlock was init before (for example, in a case of FLR).
+ *
+ * Initialize the admin submission and completion queues.
+ * Initialize the asynchronous events notification queues.
+ *
+ * @return - 0 on success, negative value on failure.
+ */
+int ena_com_admin_init(struct ena_com_dev *ena_dev,
+		       struct ena_aenq_handlers *aenq_handlers,
+		       bool init_spinlock);
+
+/* ena_com_admin_destroy - Destroy the admin and the async events queues.
+ * @ena_dev: ENA communication layer struct
+ *
+ * @note: Before calling this method, the caller must validate that the device
+ * won't send any additional admin completions/aenq.
+ * To achieve that, a FLR is recommended.
+ */
+void ena_com_admin_destroy(struct ena_com_dev *ena_dev);
+
+/* ena_com_dev_reset - Perform device FLR to the device.
+ * @ena_dev: ENA communication layer struct
+ *
+ * @return - 0 on success, negative value on failure.
+ */
+int ena_com_dev_reset(struct ena_com_dev *ena_dev);
+
+/* ena_com_create_io_queue - Create io queue.
+ * @ena_dev: ENA communication layer struct
+ * @ctx - create context structure
+ *
+ * Create the submission and the completion queues.
+ *
+ * @return - 0 on success, negative value on failure.
+ */
+int ena_com_create_io_queue(struct ena_com_dev *ena_dev,
+			    struct ena_com_create_io_ctx *ctx);
+
+/* ena_com_destroy_io_queue - Destroy IO queue with the queue id - qid.
+ * @ena_dev: ENA communication layer struct
+ * @qid - the caller virtual queue id.
+ */
+void ena_com_destroy_io_queue(struct ena_com_dev *ena_dev, u16 qid);
+
+/* ena_com_get_io_handlers - Return the io queue handlers
+ * @ena_dev: ENA communication layer struct
+ * @qid - the caller virtual queue id.
+ * @io_sq - IO submission queue handler
+ * @io_cq - IO completion queue handler.
+ *
+ * @return - 0 on success, negative value on failure.
+ */
+int ena_com_get_io_handlers(struct ena_com_dev *ena_dev, u16 qid,
+			    struct ena_com_io_sq **io_sq,
+			    struct ena_com_io_cq **io_cq);
+
+/* ena_com_admin_aenq_enable - ENAble asynchronous event notifications
+ * @ena_dev: ENA communication layer struct
+ *
+ * After this method, aenq event can be received via AENQ.
+ */
+void ena_com_admin_aenq_enable(struct ena_com_dev *ena_dev);
+
+/* ena_com_set_admin_running_state - Set the state of the admin queue
+ * @ena_dev: ENA communication layer struct
+ *
+ * Change the state of the admin queue (enable/disable)
+ */
+void ena_com_set_admin_running_state(struct ena_com_dev *ena_dev, bool state);
+
+/* ena_com_get_admin_running_state - Get the admin queue state
+ * @ena_dev: ENA communication layer struct
+ *
+ * Retrieve the state of the admin queue (enable/disable)
+ *
+ * @return - current polling mode (enable/disable)
+ */
+bool ena_com_get_admin_running_state(struct ena_com_dev *ena_dev);
+
+/* ena_com_set_admin_polling_mode - Set the admin completion queue polling mode
+ * @ena_dev: ENA communication layer struct
+ * @polling: ENAble/Disable polling mode
+ *
+ * Set the admin completion mode.
+ */
+void ena_com_set_admin_polling_mode(struct ena_com_dev *ena_dev, bool polling);
+
+/* ena_com_set_admin_polling_mode - Get the admin completion queue polling mode
+ * @ena_dev: ENA communication layer struct
+ *
+ * Get the admin completion mode.
+ * If polling mode is on, ena_com_execute_admin_command will perform a
+ * polling on the admin completion queue for the commands completion,
+ * otherwise it will wait on wait event.
+ *
+ * @return state
+ */
+bool ena_com_get_ena_admin_polling_mode(struct ena_com_dev *ena_dev);
+
+/* ena_com_admin_q_comp_intr_handler - admin queue interrupt handler
+ * @ena_dev: ENA communication layer struct
+ *
+ * This method go over the admin completion queue and wake up all the pending
+ * threads that wait on the commands wait event.
+ *
+ * @note: Should be called after MSI-X interrupt.
+ */
+void ena_com_admin_q_comp_intr_handler(struct ena_com_dev *ena_dev);
+
+/* ena_com_aenq_intr_handler - AENQ interrupt handler
+ * @ena_dev: ENA communication layer struct
+ *
+ * This method go over the async event notification queue and call the proper
+ * aenq handler.
+ */
+void ena_com_aenq_intr_handler(struct ena_com_dev *dev, void *data);
+
+/* ena_com_abort_admin_commands - Abort all the outstanding admin commands.
+ * @ena_dev: ENA communication layer struct
+ *
+ * This method aborts all the outstanding admin commands.
+ * The caller should then call ena_com_wait_for_abort_completion to make sure
+ * all the commands were completed.
+ */
+void ena_com_abort_admin_commands(struct ena_com_dev *ena_dev);
+
+/* ena_com_wait_for_abort_completion - Wait for admin commands abort.
+ * @ena_dev: ENA communication layer struct
+ *
+ * This method wait until all the outstanding admin commands will be completed.
+ */
+void ena_com_wait_for_abort_completion(struct ena_com_dev *ena_dev);
+
+/* ena_com_validate_version - Validate the device parameters
+ * @ena_dev: ENA communication layer struct
+ *
+ * This method validate the device parameters are the same as the saved
+ * parameters in ena_dev.
+ * This method is useful after device reset, to validate the device mac address
+ * and the device offloads are the same as before the reset.
+ *
+ * @return - 0 on success negative value otherwise.
+ */
+int ena_com_validate_version(struct ena_com_dev *ena_dev);
+
+/* ena_com_get_link_params - Retrieve physical link parameters.
+ * @ena_dev: ENA communication layer struct
+ * @resp: Link parameters
+ *
+ * Retrieve the physical link parameters,
+ * like speed, auto-negotiation and full duplex support.
+ *
+ * @return - 0 on Success negative value otherwise.
+ */
+int ena_com_get_link_params(struct ena_com_dev *ena_dev,
+			    struct ena_admin_get_feat_resp *resp);
+
+/* ena_com_get_dma_width - Retrieve physical dma address width the device
+ * supports.
+ * @ena_dev: ENA communication layer struct
+ *
+ * Retrieve the maximum physical address bits the device can handle.
+ *
+ * @return: > 0 on Success and negative value otherwise.
+ */
+int ena_com_get_dma_width(struct ena_com_dev *ena_dev);
+
+/* ena_com_set_aenq_config - Set aenq groups configurations
+ * @ena_dev: ENA communication layer struct
+ * @groups flag: bit fields flags of enum ena_admin_aenq_group.
+ *
+ * Configure which aenq event group the driver would like to receive.
+ *
+ * @return: 0 on Success and negative value otherwise.
+ */
+int ena_com_set_aenq_config(struct ena_com_dev *ena_dev, u32 groups_flag);
+
+/* ena_com_get_dev_attr_feat - Get device features
+ * @ena_dev: ENA communication layer struct
+ * @get_feat_ctx: returned context that contain the get features.
+ *
+ * @return: 0 on Success and negative value otherwise.
+ */
+int ena_com_get_dev_attr_feat(struct ena_com_dev *ena_dev,
+			      struct ena_com_dev_get_features_ctx *get_feat_ctx);
+
+/* ena_com_get_dev_basic_stats - Get device basic statistics
+ * @ena_dev: ENA communication layer struct
+ * @stats: stats return value
+ *
+ * @return: 0 on Success and negative value otherwise.
+ */
+int ena_com_get_dev_basic_stats(struct ena_com_dev *ena_dev,
+				struct ena_admin_basic_stats *stats);
+
+/* ena_com_set_dev_mtu - Configure the device mtu.
+ * @ena_dev: ENA communication layer struct
+ * @mtu: mtu value
+ *
+ * @return: 0 on Success and negative value otherwise.
+ */
+int ena_com_set_dev_mtu(struct ena_com_dev *ena_dev, int mtu);
+
+/* ena_com_get_offload_settings - Retrieve the device offloads capabilities
+ * @ena_dev: ENA communication layer struct
+ * @offlad: offload return value
+ *
+ * @return: 0 on Success and negative value otherwise.
+ */
+int ena_com_get_offload_settings(struct ena_com_dev *ena_dev,
+				 struct ena_admin_feature_offload_desc *offload);
+
+/* ena_com_rss_init - Init RSS
+ * @ena_dev: ENA communication layer struct
+ * @log_size: indirection log size
+ *
+ * Allocate RSS/RFS resources.
+ * The caller then can configure rss using ena_com_set_hash_function,
+ * ena_com_set_hash_ctrl and ena_com_indirect_table_set.
+ *
+ * @return: 0 on Success and negative value otherwise.
+ */
+int ena_com_rss_init(struct ena_com_dev *ena_dev, u16 log_size);
+
+/* ena_com_rss_destroy - Destroy rss
+ * @ena_dev: ENA communication layer struct
+ *
+ * Free all the RSS/RFS resources.
+ */
+void ena_com_rss_destroy(struct ena_com_dev *ena_dev);
+
+/* ena_com_fill_hash_function - Fill RSS hash function
+ * @ena_dev: ENA communication layer struct
+ * @func: The hash function (Toeplitz or crc)
+ * @key: Hash key (for toeplitz hash)
+ * @key_len: key length (max length 10 DW)
+ * @init_val: initial value for the hash function
+ *
+ * Fill the ena_dev resources with the desire hash function, hash key, key_len
+ * and key initial value (if needed by the hash function).
+ * To flush the key into the device the caller should call
+ * ena_com_set_hash_function.
+ *
+ * @return: 0 on Success and negative value otherwise.
+ */
+int ena_com_fill_hash_function(struct ena_com_dev *ena_dev,
+			       enum ena_admin_hash_functions func,
+			       const u8 *key, u16 key_len, u32 init_val);
+
+/* ena_com_set_hash_function - Flush the hash function and it dependencies to
+ * the device.
+ * @ena_dev: ENA communication layer struct
+ *
+ * Flush the hash function and it dependencies (key, key length and
+ * initial value) if needed.
+ *
+ * @note: Prior to this method the caller should call ena_com_fill_hash_function
+ *
+ * @return: 0 on Success and negative value otherwise.
+ */
+int ena_com_set_hash_function(struct ena_com_dev *ena_dev);
+
+/* ena_com_get_hash_function - Retrieve the hash function and the hash key
+ * from the device.
+ * @ena_dev: ENA communication layer struct
+ * @func: hash function
+ * @key: hash key
+ *
+ * Retrieve the hash function and the hash key from the device.
+ *
+ * @note: If the caller called ena_com_fill_hash_function but didn't flash
+ * it to the device, the new configuration will be lost.
+ *
+ * @return: 0 on Success and negative value otherwise.
+ */
+int ena_com_get_hash_function(struct ena_com_dev *ena_dev,
+			      enum ena_admin_hash_functions *func,
+			      u8 *key);
+
+/* ena_com_fill_hash_ctrl - Fill RSS hash control
+ * @ena_dev: ENA communication layer struct.
+ * @proto: The protocol to configure.
+ * @hash_fields: bit mask of ena_admin_flow_hash_fields
+ *
+ * Fill the ena_dev resources with the desire hash control (the ethernet
+ * fields that take part of the hash) for a specific protocol.
+ * To flush the hash control to the device, the caller should call
+ * ena_com_set_hash_ctrl.
+ *
+ * @return: 0 on Success and negative value otherwise.
+ */
+int ena_com_fill_hash_ctrl(struct ena_com_dev *ena_dev,
+			   enum ena_admin_flow_hash_proto proto,
+			   u16 hash_fields);
+
+/* ena_com_set_hash_ctrl - Flush the hash control resources to the device.
+ * @ena_dev: ENA communication layer struct
+ *
+ * Flush the hash control (the ethernet fields that take part of the hash)
+ *
+ * @note: Prior to this method the caller should call ena_com_fill_hash_ctrl.
+ *
+ * @return: 0 on Success and negative value otherwise.
+ */
+int ena_com_set_hash_ctrl(struct ena_com_dev *ena_dev);
+
+/* ena_com_get_hash_ctrl - Retrieve the hash control from the device.
+ * @ena_dev: ENA communication layer struct
+ * @proto: The protocol to retrieve.
+ * @fields: bit mask of ena_admin_flow_hash_fields.
+ *
+ * Retrieve the hash control from the device.
+ *
+ * @note, If the caller called ena_com_fill_hash_ctrl but didn't flash
+ * it to the device, the new configuration will be lost.
+ *
+ * @return: 0 on Success and negative value otherwise.
+ */
+int ena_com_get_hash_ctrl(struct ena_com_dev *ena_dev,
+			  enum ena_admin_flow_hash_proto proto,
+			  u16 *fields);
+
+/* ena_com_set_default_hash_ctrl - Set the hash control to a default
+ * configuration.
+ * @ena_dev: ENA communication layer struct
+ *
+ * Fill the ena_dev resources with the default hash control configuration.
+ * To flush the hash control to the device, the caller should call
+ * ena_com_set_hash_ctrl.
+ *
+ * @return: 0 on Success and negative value otherwise.
+ */
+int ena_com_set_default_hash_ctrl(struct ena_com_dev *ena_dev);
+
+/* ena_com_indirect_table_fill_entry - Fill a single entry in the RSS
+ * indirection table
+ * @ena_dev: ENA communication layer struct.
+ * @entry_idx - indirection table entry.
+ * @entry_value - redirection value
+ *
+ * Fill a single entry of the RSS indirection table in the ena_dev resources.
+ * To flush the indirection table to the device, the called should call
+ * ena_com_indirect_table_set.
+ *
+ * @return: 0 on Success and negative value otherwise.
+ */
+int ena_com_indirect_table_fill_entry(struct ena_com_dev *ena_dev,
+				      u16 entry_idx, u16 entry_value);
+
+/* ena_com_indirect_table_set - Flush the indirection table to the device.
+ * @ena_dev: ENA communication layer struct
+ *
+ * Flush the indirection hash control to the device.
+ * Prior to this method the caller should call ena_com_indirect_table_fill_entry
+ *
+ * @return: 0 on Success and negative value otherwise.
+ */
+int ena_com_indirect_table_set(struct ena_com_dev *ena_dev);
+
+/* ena_com_indirect_table_get - Retrieve the indirection table from the device.
+ * @ena_dev: ENA communication layer struct
+ * @ind_tbl: indirection table
+ *
+ * Retrieve the RSS indirection table from the device.
+ *
+ * @note: If the caller called ena_com_indirect_table_fill_entry but didn't flash
+ * it to the device, the new configuration will be lost.
+ *
+ * @return: 0 on Success and negative value otherwise.
+ */
+int ena_com_indirect_table_get(struct ena_com_dev *ena_dev, u32 *ind_tbl);
+
+/* ena_com_allocate_host_info - Allocate host info resources.
+ * @ena_dev: ENA communication layer struct
+ *
+ * @return: 0 on Success and negative value otherwise.
+ */
+int ena_com_allocate_host_info(struct ena_com_dev *ena_dev);
+
+/* ena_com_allocate_debug_area - Allocate debug area.
+ * @ena_dev: ENA communication layer struct
+ * @debug_area_size - debug area size.
+ *
+ * @return: 0 on Success and negative value otherwise.
+ */
+int ena_com_allocate_debug_area(struct ena_com_dev *ena_dev,
+				u32 debug_area_size);
+
+/* ena_com_delete_debug_area - Free the debug area resources.
+ * @ena_dev: ENA communication layer struct
+ *
+ * Free the allocate debug area.
+ */
+void ena_com_delete_debug_area(struct ena_com_dev *ena_dev);
+
+/* ena_com_delete_host_info - Free the host info resources.
+ * @ena_dev: ENA communication layer struct
+ *
+ * Free the allocate host info.
+ */
+void ena_com_delete_host_info(struct ena_com_dev *ena_dev);
+
+/* ena_com_set_host_attributes - Update the device with the host
+ * attributes (debug area and host info) base address.
+ * @ena_dev: ENA communication layer struct
+ *
+ * @return: 0 on Success and negative value otherwise.
+ */
+int ena_com_set_host_attributes(struct ena_com_dev *ena_dev);
+
+/* ena_com_create_io_cq - Create io completion queue.
+ * @ena_dev: ENA communication layer struct
+ * @io_cq - io completion queue handler
+
+ * Create IO completion queue.
+ *
+ * @return - 0 on success, negative value on failure.
+ */
+int ena_com_create_io_cq(struct ena_com_dev *ena_dev,
+			 struct ena_com_io_cq *io_cq);
+
+/* ena_com_destroy_io_cq - Destroy io completion queue.
+ * @ena_dev: ENA communication layer struct
+ * @io_cq - io completion queue handler
+
+ * Destroy IO completion queue.
+ *
+ * @return - 0 on success, negative value on failure.
+ */
+int ena_com_destroy_io_cq(struct ena_com_dev *ena_dev,
+			  struct ena_com_io_cq *io_cq);
+
+/* ena_com_execute_admin_command - Execute admin command
+ * @admin_queue: admin queue.
+ * @cmd: the admin command to execute.
+ * @cmd_size: the command size.
+ * @cmd_completion: command completion return value.
+ * @cmd_comp_size: command completion size.
+
+ * Submit an admin command and then wait until the device will return a
+ * completion.
+ * The completion will be copyed into cmd_comp.
+ *
+ * @return - 0 on success, negative value on failure.
+ */
+int ena_com_execute_admin_command(struct ena_com_admin_queue *admin_queue,
+				  struct ena_admin_aq_entry *cmd,
+				  size_t cmd_size,
+				  struct ena_admin_acq_entry *cmd_comp,
+				  size_t cmd_comp_size);
+
+/* ena_com_init_interrupt_moderation - Init interrupt moderation
+ * @ena_dev: ENA communication layer struct
+ *
+ * @return - 0 on success, negative value on failure.
+ */
+int ena_com_init_interrupt_moderation(struct ena_com_dev *ena_dev);
+
+/* ena_com_destroy_interrupt_moderation - Destroy interrupt moderation resources
+ * @ena_dev: ENA communication layer struct
+ */
+void ena_com_destroy_interrupt_moderation(struct ena_com_dev *ena_dev);
+
+/* ena_com_interrupt_moderation_supported - Return if interrupt moderation
+ * capability is supported by the device.
+ *
+ * @return - supported or not.
+ */
+bool ena_com_interrupt_moderation_supported(struct ena_com_dev *ena_dev);
+
+/* ena_com_config_default_interrupt_moderation_table - Restore the interrupt
+ * moderation table back to the default parameters.
+ * @ena_dev: ENA communication layer struct
+ */
+void ena_com_config_default_interrupt_moderation_table(struct ena_com_dev *ena_dev);
+
+/* ena_com_update_nonadaptive_moderation_interval_tx - Update the
+ * non-adaptive interval in Tx direction.
+ * @ena_dev: ENA communication layer struct
+ * @tx_coalesce_usecs: Interval in usec.
+ *
+ * @return - 0 on success, negative value on failure.
+ */
+int ena_com_update_nonadaptive_moderation_interval_tx(struct ena_com_dev *ena_dev,
+						      u32 tx_coalesce_usecs);
+
+/* ena_com_update_nonadaptive_moderation_interval_rx - Update the
+ * non-adaptive interval in Rx direction.
+ * @ena_dev: ENA communication layer struct
+ * @rx_coalesce_usecs: Interval in usec.
+ *
+ * @return - 0 on success, negative value on failure.
+ */
+int ena_com_update_nonadaptive_moderation_interval_rx(struct ena_com_dev *ena_dev,
+						      u32 rx_coalesce_usecs);
+
+/* ena_com_get_nonadaptive_moderation_interval_tx - Retrieve the
+ * non-adaptive interval in Tx direction.
+ * @ena_dev: ENA communication layer struct
+ *
+ * @return - interval in usec
+ */
+unsigned int ena_com_get_nonadaptive_moderation_interval_tx(struct ena_com_dev *ena_dev);
+
+/* ena_com_get_nonadaptive_moderation_interval_rx - Retrieve the
+ * non-adaptive interval in Rx direction.
+ * @ena_dev: ENA communication layer struct
+ *
+ * @return - interval in usec
+ */
+unsigned int ena_com_get_nonadaptive_moderation_interval_rx(struct ena_com_dev *ena_dev);
+
+/* ena_com_init_intr_moderation_entry - Update a single entry in the interrupt
+ * moderation table.
+ * @ena_dev: ENA communication layer struct
+ * @level: Interrupt moderation table level
+ * @entry: Entry value
+ *
+ * Update a single entry in the interrupt moderation table.
+ */
+void ena_com_init_intr_moderation_entry(struct ena_com_dev *ena_dev,
+					enum ena_intr_moder_level level,
+					struct ena_intr_moder_entry *entry);
+
+/* ena_com_get_intr_moderation_entry - Init ena_intr_moder_entry.
+ * @ena_dev: ENA communication layer struct
+ * @level: Interrupt moderation table level
+ * @entry: Entry to fill.
+ *
+ * Initialize the entry according to the adaptive interrupt moderation table.
+ */
+void ena_com_get_intr_moderation_entry(struct ena_com_dev *ena_dev,
+				       enum ena_intr_moder_level level,
+				       struct ena_intr_moder_entry *entry);
+
+static inline bool ena_com_get_adaptive_moderation_enabled(struct ena_com_dev *ena_dev)
+{
+	return ena_dev->adaptive_coalescing;
+}
+
+static inline void ena_com_enable_adaptive_moderation(struct ena_com_dev *ena_dev)
+{
+	ena_dev->adaptive_coalescing = true;
+}
+
+static inline void ena_com_disable_adaptive_moderation(struct ena_com_dev *ena_dev)
+{
+	ena_dev->adaptive_coalescing = false;
+}
+
+/* ena_com_calculate_interrupt_delay - Calculate new interrupt delay
+ * @ena_dev: ENA communication layer struct
+ * @pkts: Number of packets since the last update
+ * @bytes: Number of bytes received since the last update.
+ * @smoothed_interval: Returned interval
+ * @moder_tbl_idx: Current table level as input update new level as return
+ * value.
+ */
+static inline void ena_com_calculate_interrupt_delay(struct ena_com_dev *ena_dev,
+						     unsigned int pkts,
+						     unsigned int bytes,
+						     unsigned int *smoothed_interval,
+						     unsigned int *moder_tbl_idx)
+{
+	enum ena_intr_moder_level curr_moder_idx, new_moder_idx;
+	struct ena_intr_moder_entry *curr_moder_entry;
+	struct ena_intr_moder_entry *pred_moder_entry;
+	struct ena_intr_moder_entry *new_moder_entry;
+	struct ena_intr_moder_entry *intr_moder_tbl = ena_dev->intr_moder_tbl;
+	unsigned int interval;
+
+	/* We apply adaptive moderation on Rx path only.
+	 * Tx uses static interrupt moderation.
+	 */
+	if (!pkts || !bytes)
+		/* Tx interrupt, or spurious interrupt,
+		 * in both cases we just use same delay values
+		 */
+		return;
+
+	curr_moder_idx = (enum ena_intr_moder_level)(*moder_tbl_idx);
+	if (unlikely(curr_moder_idx >= ENA_INTR_MAX_NUM_OF_LEVELS)) {
+		pr_err("Wrong moderation index %u\n", curr_moder_idx);
+		return;
+	}
+
+	curr_moder_entry = &intr_moder_tbl[curr_moder_idx];
+	new_moder_idx = curr_moder_idx;
+
+	if (curr_moder_idx == ENA_INTR_MODER_LOWEST) {
+		if ((pkts > curr_moder_entry->pkts_per_interval) ||
+		    (bytes > curr_moder_entry->bytes_per_interval))
+			new_moder_idx =
+				(enum ena_intr_moder_level)(curr_moder_idx + ENA_INTR_MODER_LEVEL_STRIDE);
+	} else {
+		pred_moder_entry = &intr_moder_tbl[curr_moder_idx - ENA_INTR_MODER_LEVEL_STRIDE];
+
+		if ((pkts <= pred_moder_entry->pkts_per_interval) ||
+		    (bytes <= pred_moder_entry->bytes_per_interval))
+			new_moder_idx =
+				(enum ena_intr_moder_level)(curr_moder_idx - ENA_INTR_MODER_LEVEL_STRIDE);
+		else if ((pkts > curr_moder_entry->pkts_per_interval) ||
+			 (bytes > curr_moder_entry->bytes_per_interval)) {
+			if (curr_moder_idx != ENA_INTR_MODER_HIGHEST)
+				new_moder_idx =
+					(enum ena_intr_moder_level)(curr_moder_idx + ENA_INTR_MODER_LEVEL_STRIDE);
+		}
+	}
+	new_moder_entry = &intr_moder_tbl[new_moder_idx];
+
+	interval = new_moder_entry->intr_moder_interval;
+	*smoothed_interval = (
+		(interval * ENA_INTR_DELAY_NEW_VALUE_WEIGHT +
+		ENA_INTR_DELAY_OLD_VALUE_WEIGHT * (*smoothed_interval)) + 5) /
+		10;
+
+	*moder_tbl_idx = new_moder_idx;
+}
+
+/* ena_com_update_intr_reg - Prepare interrupt register
+ * @intr_reg: interrupt register to update.
+ * @rx_delay_interval: Rx interval in usecs
+ * @tx_delay_interval: Tx interval in usecs
+ * @unmask: unask enable/disable
+ *
+ * Prepare interrupt update register with the supplied parameters.
+ */
+static inline void ena_com_update_intr_reg(struct ena_eth_io_intr_reg *intr_reg,
+					   u32 rx_delay_interval,
+					   u32 tx_delay_interval,
+					   bool unmask)
+{
+	intr_reg->intr_control = 0;
+	intr_reg->intr_control |= rx_delay_interval &
+		ENA_ETH_IO_INTR_REG_RX_INTR_DELAY_MASK;
+
+	intr_reg->intr_control |=
+		(tx_delay_interval << ENA_ETH_IO_INTR_REG_TX_INTR_DELAY_SHIFT)
+		& ENA_ETH_IO_INTR_REG_TX_INTR_DELAY_MASK;
+
+	if (unmask)
+		intr_reg->intr_control |= ENA_ETH_IO_INTR_REG_INTR_UNMASK_MASK;
+}
+
+#endif /* !(ENA_COM) */
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/amazon/ena/ena_common_defs.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2015 - 2016 Amazon.com, Inc. or its affiliates.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+#ifndef _ENA_COMMON_H_
+#define _ENA_COMMON_H_
+
+#define ENA_COMMON_SPEC_VERSION_MAJOR	0 /*  */
+#define ENA_COMMON_SPEC_VERSION_MINOR	10 /*  */
+
+/* ENA operates with 48-bit memory addresses. ena_mem_addr_t */
+struct ena_common_mem_addr {
+	u32 mem_addr_low;
+
+	u16 mem_addr_high;
+
+	/* MBZ */
+	u16 reserved16;
+};
+
+#endif /*_ENA_COMMON_H_ */
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/amazon/ena/ena_eth_com.c
@@ -0,0 +1,501 @@
+/*
+ * Copyright 2015 Amazon.com, Inc. or its affiliates.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include "ena_eth_com.h"
+
+static inline struct ena_eth_io_rx_cdesc_base *ena_com_get_next_rx_cdesc(
+	struct ena_com_io_cq *io_cq)
+{
+	struct ena_eth_io_rx_cdesc_base *cdesc;
+	u16 expected_phase, head_masked;
+	u16 desc_phase;
+
+	head_masked = io_cq->head & (io_cq->q_depth - 1);
+	expected_phase = io_cq->phase;
+
+	cdesc = (struct ena_eth_io_rx_cdesc_base *)(io_cq->cdesc_addr.virt_addr
+			+ (head_masked * io_cq->cdesc_entry_size_in_bytes));
+
+	desc_phase = (cdesc->status & ENA_ETH_IO_RX_CDESC_BASE_PHASE_MASK) >>
+			ENA_ETH_IO_RX_CDESC_BASE_PHASE_SHIFT;
+
+	if (desc_phase != expected_phase)
+		return NULL;
+
+	return cdesc;
+}
+
+static inline void ena_com_cq_inc_head(struct ena_com_io_cq *io_cq)
+{
+	io_cq->head++;
+
+	/* Switch phase bit in case of wrap around */
+	if (unlikely((io_cq->head & (io_cq->q_depth - 1)) == 0))
+		io_cq->phase ^= 1;
+}
+
+static inline void *get_sq_desc(struct ena_com_io_sq *io_sq)
+{
+	u16 tail_masked;
+	u32 offset;
+
+	tail_masked = io_sq->tail & (io_sq->q_depth - 1);
+
+	offset = tail_masked * io_sq->desc_entry_size;
+
+	return (void *)((uintptr_t)io_sq->desc_addr.virt_addr + offset);
+}
+
+static inline void ena_com_copy_curr_sq_desc_to_dev(struct ena_com_io_sq *io_sq)
+{
+	u16 tail_masked = io_sq->tail & (io_sq->q_depth - 1);
+	u32 offset = tail_masked * io_sq->desc_entry_size;
+
+	/* In case this queue isn't a LLQ */
+	if (io_sq->mem_queue_type == ENA_ADMIN_PLACEMENT_POLICY_HOST)
+		return;
+
+	memcpy_toio(io_sq->desc_addr.pbuf_dev_addr + offset,
+		    io_sq->desc_addr.virt_addr + offset,
+		    io_sq->desc_entry_size);
+}
+
+static inline void ena_com_sq_update_tail(struct ena_com_io_sq *io_sq)
+{
+	io_sq->tail++;
+
+	/* Switch phase bit in case of wrap around */
+	if (unlikely((io_sq->tail & (io_sq->q_depth - 1)) == 0))
+		io_sq->phase ^= 1;
+}
+
+static inline int ena_com_write_header(struct ena_com_io_sq *io_sq,
+				       u8 *head_src, u16 header_len)
+{
+	u16 tail_masked = io_sq->tail & (io_sq->q_depth - 1);
+	u8 __iomem *dev_head_addr =
+		io_sq->header_addr + (tail_masked * io_sq->tx_max_header_size);
+
+	if (io_sq->mem_queue_type == ENA_ADMIN_PLACEMENT_POLICY_HOST)
+		return 0;
+
+	if (unlikely(!io_sq->header_addr)) {
+		pr_err("Push buffer header ptr is NULL\n");
+		return -EINVAL;
+	}
+
+	memcpy_toio(dev_head_addr, head_src, header_len);
+
+	return 0;
+}
+
+static inline struct ena_eth_io_rx_cdesc_base *
+	ena_com_rx_cdesc_idx_to_ptr(struct ena_com_io_cq *io_cq, u16 idx)
+{
+	idx &= (io_cq->q_depth - 1);
+	return (struct ena_eth_io_rx_cdesc_base *)
+		((uintptr_t)io_cq->cdesc_addr.virt_addr +
+		idx * io_cq->cdesc_entry_size_in_bytes);
+}
+
+static inline u16 ena_com_cdesc_rx_pkt_get(struct ena_com_io_cq *io_cq,
+					   u16 *first_cdesc_idx)
+{
+	struct ena_eth_io_rx_cdesc_base *cdesc;
+	u16 count = 0, head_masked;
+	u32 last = 0;
+
+	do {
+		cdesc = ena_com_get_next_rx_cdesc(io_cq);
+		if (!cdesc)
+			break;
+
+		ena_com_cq_inc_head(io_cq);
+		count++;
+		last = (cdesc->status & ENA_ETH_IO_RX_CDESC_BASE_LAST_MASK) >>
+			ENA_ETH_IO_RX_CDESC_BASE_LAST_SHIFT;
+	} while (!last);
+
+	if (last) {
+		*first_cdesc_idx = io_cq->cur_rx_pkt_cdesc_start_idx;
+		count += io_cq->cur_rx_pkt_cdesc_count;
+
+		head_masked = io_cq->head & (io_cq->q_depth - 1);
+
+		io_cq->cur_rx_pkt_cdesc_count = 0;
+		io_cq->cur_rx_pkt_cdesc_start_idx = head_masked;
+
+		pr_debug("ena q_id: %d packets were completed. first desc idx %u descs# %d\n",
+			 io_cq->qid, *first_cdesc_idx, count);
+	} else {
+		io_cq->cur_rx_pkt_cdesc_count += count;
+		count = 0;
+	}
+
+	return count;
+}
+
+static inline bool ena_com_meta_desc_changed(struct ena_com_io_sq *io_sq,
+					     struct ena_com_tx_ctx *ena_tx_ctx)
+{
+	int rc;
+
+	if (ena_tx_ctx->meta_valid) {
+		rc = memcmp(&io_sq->cached_tx_meta,
+			    &ena_tx_ctx->ena_meta,
+			    sizeof(struct ena_com_tx_meta));
+
+		if (unlikely(rc != 0))
+			return true;
+	}
+
+	return false;
+}
+
+static inline void ena_com_create_and_store_tx_meta_desc(struct ena_com_io_sq *io_sq,
+							 struct ena_com_tx_ctx *ena_tx_ctx)
+{
+	struct ena_eth_io_tx_meta_desc *meta_desc = NULL;
+	struct ena_com_tx_meta *ena_meta = &ena_tx_ctx->ena_meta;
+
+	meta_desc = get_sq_desc(io_sq);
+	memset(meta_desc, 0x0, sizeof(struct ena_eth_io_tx_meta_desc));
+
+	meta_desc->len_ctrl |= ENA_ETH_IO_TX_META_DESC_META_DESC_MASK;
+
+	meta_desc->len_ctrl |= ENA_ETH_IO_TX_META_DESC_EXT_VALID_MASK;
+
+	/* bits 0-9 of the mss */
+	meta_desc->word2 |= (ena_meta->mss <<
+		ENA_ETH_IO_TX_META_DESC_MSS_LO_SHIFT) &
+		ENA_ETH_IO_TX_META_DESC_MSS_LO_MASK;
+	/* bits 10-13 of the mss */
+	meta_desc->len_ctrl |= ((ena_meta->mss >> 10) <<
+		ENA_ETH_IO_TX_META_DESC_MSS_HI_SHIFT) &
+		ENA_ETH_IO_TX_META_DESC_MSS_HI_MASK;
+
+	/* Extended meta desc */
+	meta_desc->len_ctrl |= ENA_ETH_IO_TX_META_DESC_ETH_META_TYPE_MASK;
+	meta_desc->len_ctrl |= ENA_ETH_IO_TX_META_DESC_META_STORE_MASK;
+	meta_desc->len_ctrl |= (io_sq->phase <<
+		ENA_ETH_IO_TX_META_DESC_PHASE_SHIFT) &
+		ENA_ETH_IO_TX_META_DESC_PHASE_MASK;
+
+	meta_desc->len_ctrl |= ENA_ETH_IO_TX_META_DESC_FIRST_MASK;
+	meta_desc->word2 |= ena_meta->l3_hdr_len &
+		ENA_ETH_IO_TX_META_DESC_L3_HDR_LEN_MASK;
+	meta_desc->word2 |= (ena_meta->l3_hdr_offset <<
+		ENA_ETH_IO_TX_META_DESC_L3_HDR_OFF_SHIFT) &
+		ENA_ETH_IO_TX_META_DESC_L3_HDR_OFF_MASK;
+
+	meta_desc->word2 |= (ena_meta->l4_hdr_len <<
+		ENA_ETH_IO_TX_META_DESC_L4_HDR_LEN_IN_WORDS_SHIFT) &
+		ENA_ETH_IO_TX_META_DESC_L4_HDR_LEN_IN_WORDS_MASK;
+
+	meta_desc->len_ctrl |= ENA_ETH_IO_TX_META_DESC_META_STORE_MASK;
+
+	/* Cached the meta desc */
+	memcpy(&io_sq->cached_tx_meta, ena_meta,
+	       sizeof(struct ena_com_tx_meta));
+
+	ena_com_copy_curr_sq_desc_to_dev(io_sq);
+	ena_com_sq_update_tail(io_sq);
+}
+
+static inline void ena_com_rx_set_flags(struct ena_com_rx_ctx *ena_rx_ctx,
+					struct ena_eth_io_rx_cdesc_base *cdesc)
+{
+	ena_rx_ctx->l3_proto = cdesc->status &
+		ENA_ETH_IO_RX_CDESC_BASE_L3_PROTO_IDX_MASK;
+	ena_rx_ctx->l4_proto =
+		(cdesc->status & ENA_ETH_IO_RX_CDESC_BASE_L4_PROTO_IDX_MASK) >>
+		ENA_ETH_IO_RX_CDESC_BASE_L4_PROTO_IDX_SHIFT;
+	ena_rx_ctx->l3_csum_err =
+		(cdesc->status & ENA_ETH_IO_RX_CDESC_BASE_L3_CSUM_ERR_MASK) >>
+		ENA_ETH_IO_RX_CDESC_BASE_L3_CSUM_ERR_SHIFT;
+	ena_rx_ctx->l4_csum_err =
+		(cdesc->status & ENA_ETH_IO_RX_CDESC_BASE_L4_CSUM_ERR_MASK) >>
+		ENA_ETH_IO_RX_CDESC_BASE_L4_CSUM_ERR_SHIFT;
+	ena_rx_ctx->hash = cdesc->hash;
+	ena_rx_ctx->frag =
+		(cdesc->status & ENA_ETH_IO_RX_CDESC_BASE_IPV4_FRAG_MASK) >>
+		ENA_ETH_IO_RX_CDESC_BASE_IPV4_FRAG_SHIFT;
+
+	pr_debug("ena_rx_ctx->l3_proto %d ena_rx_ctx->l4_proto %d\nena_rx_ctx->l3_csum_err %d ena_rx_ctx->l4_csum_err %d\nhash frag %d frag: %d cdesc_status: %x\n",
+		 ena_rx_ctx->l3_proto, ena_rx_ctx->l4_proto,
+		 ena_rx_ctx->l3_csum_err, ena_rx_ctx->l4_csum_err,
+		 ena_rx_ctx->hash, ena_rx_ctx->frag, cdesc->status);
+}
+
+/*****************************************************************************/
+/*****************************     API      **********************************/
+/*****************************************************************************/
+
+int ena_com_prepare_tx(struct ena_com_io_sq *io_sq,
+		       struct ena_com_tx_ctx *ena_tx_ctx,
+		       int *nb_hw_desc)
+{
+	struct ena_eth_io_tx_desc *desc = NULL;
+	struct ena_com_buf *ena_bufs = ena_tx_ctx->ena_bufs;
+	void *push_header = ena_tx_ctx->push_header;
+	u16 header_len = ena_tx_ctx->header_len;
+	u16 num_bufs = ena_tx_ctx->num_bufs;
+	int total_desc, i, rc;
+	bool have_meta;
+	u64 addr_hi;
+
+	WARN(io_sq->direction != ENA_COM_IO_QUEUE_DIRECTION_TX, "wrong Q type");
+
+	/* num_bufs +1 for potential meta desc */
+	if (ena_com_sq_empty_space(io_sq) < (num_bufs + 1)) {
+		pr_err("Not enough space in the tx queue\n");
+		return -ENOMEM;
+	}
+
+	if (unlikely(header_len > io_sq->tx_max_header_size)) {
+		pr_err("header size is too large %d max header: %d\n",
+		       header_len, io_sq->tx_max_header_size);
+		return -EINVAL;
+	}
+
+	/* start with pushing the header (if needed) */
+	rc = ena_com_write_header(io_sq, push_header, header_len);
+	if (unlikely(rc))
+		return rc;
+
+	have_meta = ena_tx_ctx->meta_valid && ena_com_meta_desc_changed(io_sq,
+			ena_tx_ctx);
+	if (have_meta)
+		ena_com_create_and_store_tx_meta_desc(io_sq, ena_tx_ctx);
+
+	/* If the caller doesn't want send packets */
+	if (unlikely(!num_bufs && !header_len)) {
+		*nb_hw_desc = have_meta ? 0 : 1;
+		return 0;
+	}
+
+	desc = get_sq_desc(io_sq);
+	memset(desc, 0x0, sizeof(struct ena_eth_io_tx_desc));
+
+	/* Set first desc when we don't have meta descriptor */
+	if (!have_meta)
+		desc->len_ctrl |= ENA_ETH_IO_TX_DESC_FIRST_MASK;
+
+	desc->buff_addr_hi_hdr_sz |= (header_len <<
+		ENA_ETH_IO_TX_DESC_HEADER_LENGTH_SHIFT) &
+		ENA_ETH_IO_TX_DESC_HEADER_LENGTH_MASK;
+	desc->len_ctrl |= (io_sq->phase << ENA_ETH_IO_TX_DESC_PHASE_SHIFT) &
+		ENA_ETH_IO_TX_DESC_PHASE_MASK;
+
+	desc->len_ctrl |= ENA_ETH_IO_TX_DESC_COMP_REQ_MASK;
+
+	/* Bits 0-9 */
+	desc->meta_ctrl |= (ena_tx_ctx->req_id <<
+		ENA_ETH_IO_TX_DESC_REQ_ID_LO_SHIFT) &
+		ENA_ETH_IO_TX_DESC_REQ_ID_LO_MASK;
+
+	desc->meta_ctrl |= (ena_tx_ctx->df <<
+		ENA_ETH_IO_TX_DESC_DF_SHIFT) &
+		ENA_ETH_IO_TX_DESC_DF_MASK;
+
+	/* Bits 10-15 */
+	desc->len_ctrl |= ((ena_tx_ctx->req_id >> 10) <<
+		ENA_ETH_IO_TX_DESC_REQ_ID_HI_SHIFT) &
+		ENA_ETH_IO_TX_DESC_REQ_ID_HI_MASK;
+
+	if (ena_tx_ctx->meta_valid) {
+		desc->meta_ctrl |= (ena_tx_ctx->tso_enable <<
+			ENA_ETH_IO_TX_DESC_TSO_EN_SHIFT) &
+			ENA_ETH_IO_TX_DESC_TSO_EN_MASK;
+		desc->meta_ctrl |= ena_tx_ctx->l3_proto &
+			ENA_ETH_IO_TX_DESC_L3_PROTO_IDX_MASK;
+		desc->meta_ctrl |= (ena_tx_ctx->l4_proto <<
+			ENA_ETH_IO_TX_DESC_L4_PROTO_IDX_SHIFT) &
+			ENA_ETH_IO_TX_DESC_L4_PROTO_IDX_MASK;
+		desc->meta_ctrl |= (ena_tx_ctx->l3_csum_enable <<
+			ENA_ETH_IO_TX_DESC_L3_CSUM_EN_SHIFT) &
+			ENA_ETH_IO_TX_DESC_L3_CSUM_EN_MASK;
+		desc->meta_ctrl |= (ena_tx_ctx->l4_csum_enable <<
+			ENA_ETH_IO_TX_DESC_L4_CSUM_EN_SHIFT) &
+			ENA_ETH_IO_TX_DESC_L4_CSUM_EN_MASK;
+		desc->meta_ctrl |= (ena_tx_ctx->l4_csum_partial <<
+			ENA_ETH_IO_TX_DESC_L4_CSUM_PARTIAL_SHIFT) &
+			ENA_ETH_IO_TX_DESC_L4_CSUM_PARTIAL_MASK;
+	}
+
+	for (i = 0; i < num_bufs; i++) {
+		/* The first desc share the same desc as the header */
+		if (likely(i != 0)) {
+			ena_com_copy_curr_sq_desc_to_dev(io_sq);
+			ena_com_sq_update_tail(io_sq);
+
+			desc = get_sq_desc(io_sq);
+			memset(desc, 0x0, sizeof(struct ena_eth_io_tx_desc));
+
+			desc->len_ctrl |= (io_sq->phase <<
+				ENA_ETH_IO_TX_DESC_PHASE_SHIFT) &
+				ENA_ETH_IO_TX_DESC_PHASE_MASK;
+		}
+
+		desc->len_ctrl |= ena_bufs->len &
+			ENA_ETH_IO_TX_DESC_LENGTH_MASK;
+
+		addr_hi = ((ena_bufs->paddr &
+			GENMASK_ULL(io_sq->dma_addr_bits - 1, 32)) >> 32);
+
+		desc->buff_addr_lo = (u32)ena_bufs->paddr;
+		desc->buff_addr_hi_hdr_sz |= addr_hi &
+			ENA_ETH_IO_TX_DESC_ADDR_HI_MASK;
+		ena_bufs++;
+	}
+
+	/* set the last desc indicator */
+	desc->len_ctrl |= ENA_ETH_IO_TX_DESC_LAST_MASK;
+
+	ena_com_copy_curr_sq_desc_to_dev(io_sq);
+
+	ena_com_sq_update_tail(io_sq);
+
+	total_desc = max_t(u16, num_bufs, 1);
+	total_desc += have_meta ? 1 : 0;
+
+	*nb_hw_desc = total_desc;
+	return 0;
+}
+
+int ena_com_rx_pkt(struct ena_com_io_cq *io_cq,
+		   struct ena_com_io_sq *io_sq,
+		   struct ena_com_rx_ctx *ena_rx_ctx)
+{
+	struct ena_com_rx_buf_info *ena_buf = &ena_rx_ctx->ena_bufs[0];
+	struct ena_eth_io_rx_cdesc_base *cdesc = NULL;
+	u16 cdesc_idx = 0;
+	u16 nb_hw_desc;
+	u16 i;
+
+	WARN(io_cq->direction != ENA_COM_IO_QUEUE_DIRECTION_RX, "wrong Q type");
+
+	nb_hw_desc = ena_com_cdesc_rx_pkt_get(io_cq, &cdesc_idx);
+	if (nb_hw_desc == 0) {
+		ena_rx_ctx->descs = nb_hw_desc;
+		return 0;
+	}
+
+	pr_debug("fetch rx packet: queue %d completed desc: %d\n", io_cq->qid,
+		 nb_hw_desc);
+
+	if (unlikely(nb_hw_desc > ena_rx_ctx->max_bufs)) {
+		pr_err("Too many RX cdescs (%d) > MAX(%d)\n", nb_hw_desc,
+		       ena_rx_ctx->max_bufs);
+		return -ENOSPC;
+	}
+
+	for (i = 0; i < nb_hw_desc; i++) {
+		cdesc = ena_com_rx_cdesc_idx_to_ptr(io_cq, cdesc_idx + i);
+
+		ena_buf->len = cdesc->length;
+		ena_buf->req_id = cdesc->req_id;
+		ena_buf++;
+	}
+
+	/* Update SQ head ptr */
+	io_sq->next_to_comp += nb_hw_desc;
+
+	pr_debug("[%s][QID#%d] Updating SQ head to: %d\n", __func__, io_sq->qid,
+		 io_sq->next_to_comp);
+
+	/* Get rx flags from the last pkt */
+	ena_com_rx_set_flags(ena_rx_ctx, cdesc);
+
+	ena_rx_ctx->descs = nb_hw_desc;
+	return 0;
+}
+
+int ena_com_add_single_rx_desc(struct ena_com_io_sq *io_sq,
+			       struct ena_com_buf *ena_buf,
+			       u16 req_id)
+{
+	struct ena_eth_io_rx_desc *desc;
+
+	WARN(io_sq->direction != ENA_COM_IO_QUEUE_DIRECTION_RX, "wrong Q type");
+
+	if (unlikely(ena_com_sq_empty_space(io_sq) == 0))
+		return -ENOSPC;
+
+	desc = get_sq_desc(io_sq);
+	memset(desc, 0x0, sizeof(struct ena_eth_io_rx_desc));
+
+	desc->length = ena_buf->len;
+
+	desc->ctrl |= ENA_ETH_IO_RX_DESC_FIRST_MASK;
+	desc->ctrl |= ENA_ETH_IO_RX_DESC_LAST_MASK;
+	desc->ctrl |= io_sq->phase & ENA_ETH_IO_RX_DESC_PHASE_MASK;
+	desc->ctrl |= ENA_ETH_IO_RX_DESC_COMP_REQ_MASK;
+
+	desc->req_id = req_id;
+
+	desc->buff_addr_lo = (u32)ena_buf->paddr;
+	desc->buff_addr_hi =
+		((ena_buf->paddr & GENMASK_ULL(io_sq->dma_addr_bits - 1, 32)) >> 32);
+
+	ena_com_sq_update_tail(io_sq);
+
+	return 0;
+}
+
+int ena_com_tx_comp_req_id_get(struct ena_com_io_cq *io_cq, u16 *req_id)
+{
+	u8 expected_phase, cdesc_phase;
+	struct ena_eth_io_tx_cdesc *cdesc;
+	u16 masked_head;
+
+	masked_head = io_cq->head & (io_cq->q_depth - 1);
+	expected_phase = io_cq->phase;
+
+	cdesc = (struct ena_eth_io_tx_cdesc *)
+		((uintptr_t)io_cq->cdesc_addr.virt_addr +
+		(masked_head * io_cq->cdesc_entry_size_in_bytes));
+
+	/* When the current completion descriptor phase isn't the same as the
+	 * expected, it mean that the device still didn't update
+	 * this completion.
+	 */
+	cdesc_phase = cdesc->flags & ENA_ETH_IO_TX_CDESC_PHASE_MASK;
+	if (cdesc_phase != expected_phase)
+		return -EAGAIN;
+
+	ena_com_cq_inc_head(io_cq);
+
+	*req_id = cdesc->req_id;
+
+	return 0;
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/amazon/ena/ena_eth_com.h
@@ -0,0 +1,160 @@
+/*
+ * Copyright 2015 Amazon.com, Inc. or its affiliates.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef ENA_ETH_COM_H_
+#define ENA_ETH_COM_H_
+
+#include "ena_com.h"
+
+/* head update threshold in units of (queue size / ENA_COMP_HEAD_THRESH) */
+#define ENA_COMP_HEAD_THRESH 4
+
+struct ena_com_tx_ctx {
+	struct ena_com_tx_meta ena_meta;
+	struct ena_com_buf *ena_bufs;
+	/* For LLQ, header buffer - pushed to the device mem space */
+	void *push_header;
+
+	enum ena_eth_io_l3_proto_index l3_proto;
+	enum ena_eth_io_l4_proto_index l4_proto;
+	u16 num_bufs;
+	u16 req_id;
+	/* For regular queue, indicate the size of the header
+	 * For LLQ, indicate the size of the pushed buffer
+	 */
+	u16 header_len;
+
+	u8 meta_valid;
+	u8 tso_enable;
+	u8 l3_csum_enable;
+	u8 l4_csum_enable;
+	u8 l4_csum_partial;
+	u8 df; /* Don't fragment */
+};
+
+struct ena_com_rx_ctx {
+	struct ena_com_rx_buf_info *ena_bufs;
+	enum ena_eth_io_l3_proto_index l3_proto;
+	enum ena_eth_io_l4_proto_index l4_proto;
+	bool l3_csum_err;
+	bool l4_csum_err;
+	/* fragmented packet */
+	bool frag;
+	u32 hash;
+	u16 descs;
+	int max_bufs;
+};
+
+int ena_com_prepare_tx(struct ena_com_io_sq *io_sq,
+		       struct ena_com_tx_ctx *ena_tx_ctx,
+		       int *nb_hw_desc);
+
+int ena_com_rx_pkt(struct ena_com_io_cq *io_cq,
+		   struct ena_com_io_sq *io_sq,
+		   struct ena_com_rx_ctx *ena_rx_ctx);
+
+int ena_com_add_single_rx_desc(struct ena_com_io_sq *io_sq,
+			       struct ena_com_buf *ena_buf,
+			       u16 req_id);
+
+int ena_com_tx_comp_req_id_get(struct ena_com_io_cq *io_cq, u16 *req_id);
+
+static inline void ena_com_unmask_intr(struct ena_com_io_cq *io_cq,
+				       struct ena_eth_io_intr_reg *intr_reg)
+{
+	writel(intr_reg->intr_control, io_cq->unmask_reg);
+}
+
+static inline int ena_com_sq_empty_space(struct ena_com_io_sq *io_sq)
+{
+	u16 tail, next_to_comp, cnt;
+
+	next_to_comp = io_sq->next_to_comp;
+	tail = io_sq->tail;
+	cnt = tail - next_to_comp;
+
+	return io_sq->q_depth - 1 - cnt;
+}
+
+static inline int ena_com_write_sq_doorbell(struct ena_com_io_sq *io_sq)
+{
+	u16 tail;
+
+	tail = io_sq->tail;
+
+	pr_debug("write submission queue doorbell for queue: %d tail: %d\n",
+		 io_sq->qid, tail);
+
+	writel(tail, io_sq->db_addr);
+
+	return 0;
+}
+
+static inline int ena_com_update_dev_comp_head(struct ena_com_io_cq *io_cq)
+{
+	u16 unreported_comp, head;
+	bool need_update;
+
+	head = io_cq->head;
+	unreported_comp = head - io_cq->last_head_update;
+	need_update = unreported_comp > (io_cq->q_depth / ENA_COMP_HEAD_THRESH);
+
+	if (io_cq->cq_head_db_reg && need_update) {
+		pr_debug("Write completion queue doorbell for queue %d: head: %d\n",
+			 io_cq->qid, head);
+		writel(head, io_cq->cq_head_db_reg);
+		io_cq->last_head_update = head;
+	}
+
+	return 0;
+}
+
+static inline void ena_com_update_numa_node(struct ena_com_io_cq *io_cq,
+					    u8 numa_node)
+{
+	struct ena_eth_io_numa_node_cfg_reg numa_cfg;
+
+	if (!io_cq->numa_node_cfg_reg)
+		return;
+
+	numa_cfg.numa_cfg = (numa_node & ENA_ETH_IO_NUMA_NODE_CFG_REG_NUMA_MASK)
+		| ENA_ETH_IO_NUMA_NODE_CFG_REG_ENABLED_MASK;
+
+	writel(numa_cfg.numa_cfg, io_cq->numa_node_cfg_reg);
+}
+
+static inline void ena_com_comp_ack(struct ena_com_io_sq *io_sq, u16 elem)
+{
+	io_sq->next_to_comp += elem;
+}
+
+#endif /* ENA_ETH_COM_H_ */
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/amazon/ena/ena_eth_io_defs.h
@@ -0,0 +1,416 @@
+/*
+ * Copyright 2015 - 2016 Amazon.com, Inc. or its affiliates.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+#ifndef _ENA_ETH_IO_H_
+#define _ENA_ETH_IO_H_
+
+enum ena_eth_io_l3_proto_index {
+	ENA_ETH_IO_L3_PROTO_UNKNOWN	= 0,
+
+	ENA_ETH_IO_L3_PROTO_IPV4	= 8,
+
+	ENA_ETH_IO_L3_PROTO_IPV6	= 11,
+
+	ENA_ETH_IO_L3_PROTO_FCOE	= 21,
+
+	ENA_ETH_IO_L3_PROTO_ROCE	= 22,
+};
+
+enum ena_eth_io_l4_proto_index {
+	ENA_ETH_IO_L4_PROTO_UNKNOWN		= 0,
+
+	ENA_ETH_IO_L4_PROTO_TCP			= 12,
+
+	ENA_ETH_IO_L4_PROTO_UDP			= 13,
+
+	ENA_ETH_IO_L4_PROTO_ROUTEABLE_ROCE	= 23,
+};
+
+struct ena_eth_io_tx_desc {
+	/* 15:0 : length - Buffer length in bytes, must
+	 *    include any packet trailers that the ENA supposed
+	 *    to update like End-to-End CRC, Authentication GMAC
+	 *    etc. This length must not include the
+	 *    'Push_Buffer' length. This length must not include
+	 *    the 4-byte added in the end for 802.3 Ethernet FCS
+	 * 21:16 : req_id_hi - Request ID[15:10]
+	 * 22 : reserved22 - MBZ
+	 * 23 : meta_desc - MBZ
+	 * 24 : phase
+	 * 25 : reserved1 - MBZ
+	 * 26 : first - Indicates first descriptor in
+	 *    transaction
+	 * 27 : last - Indicates last descriptor in
+	 *    transaction
+	 * 28 : comp_req - Indicates whether completion
+	 *    should be posted, after packet is transmitted.
+	 *    Valid only for first descriptor
+	 * 30:29 : reserved29 - MBZ
+	 * 31 : reserved31 - MBZ
+	 */
+	u32 len_ctrl;
+
+	/* 3:0 : l3_proto_idx - L3 protocol. This field
+	 *    required when l3_csum_en,l3_csum or tso_en are set.
+	 * 4 : DF - IPv4 DF, must be 0 if packet is IPv4 and
+	 *    DF flags of the IPv4 header is 0. Otherwise must
+	 *    be set to 1
+	 * 6:5 : reserved5
+	 * 7 : tso_en - Enable TSO, For TCP only.
+	 * 12:8 : l4_proto_idx - L4 protocol. This field need
+	 *    to be set when l4_csum_en or tso_en are set.
+	 * 13 : l3_csum_en - enable IPv4 header checksum.
+	 * 14 : l4_csum_en - enable TCP/UDP checksum.
+	 * 15 : ethernet_fcs_dis - when set, the controller
+	 *    will not append the 802.3 Ethernet Frame Check
+	 *    Sequence to the packet
+	 * 16 : reserved16
+	 * 17 : l4_csum_partial - L4 partial checksum. when
+	 *    set to 0, the ENA calculates the L4 checksum,
+	 *    where the Destination Address required for the
+	 *    TCP/UDP pseudo-header is taken from the actual
+	 *    packet L3 header. when set to 1, the ENA doesn't
+	 *    calculate the sum of the pseudo-header, instead,
+	 *    the checksum field of the L4 is used instead. When
+	 *    TSO enabled, the checksum of the pseudo-header
+	 *    must not include the tcp length field. L4 partial
+	 *    checksum should be used for IPv6 packet that
+	 *    contains Routing Headers.
+	 * 20:18 : reserved18 - MBZ
+	 * 21 : reserved21 - MBZ
+	 * 31:22 : req_id_lo - Request ID[9:0]
+	 */
+	u32 meta_ctrl;
+
+	u32 buff_addr_lo;
+
+	/* address high and header size
+	 * 15:0 : addr_hi - Buffer Pointer[47:32]
+	 * 23:16 : reserved16_w2
+	 * 31:24 : header_length - Header length. For Low
+	 *    Latency Queues, this fields indicates the number
+	 *    of bytes written to the headers' memory. For
+	 *    normal queues, if packet is TCP or UDP, and longer
+	 *    than max_header_size, then this field should be
+	 *    set to the sum of L4 header offset and L4 header
+	 *    size(without options), otherwise, this field
+	 *    should be set to 0. For both modes, this field
+	 *    must not exceed the max_header_size.
+	 *    max_header_size value is reported by the Max
+	 *    Queues Feature descriptor
+	 */
+	u32 buff_addr_hi_hdr_sz;
+};
+
+struct ena_eth_io_tx_meta_desc {
+	/* 9:0 : req_id_lo - Request ID[9:0]
+	 * 11:10 : reserved10 - MBZ
+	 * 12 : reserved12 - MBZ
+	 * 13 : reserved13 - MBZ
+	 * 14 : ext_valid - if set, offset fields in Word2
+	 *    are valid Also MSS High in Word 0 and bits [31:24]
+	 *    in Word 3
+	 * 15 : reserved15
+	 * 19:16 : mss_hi
+	 * 20 : eth_meta_type - 0: Tx Metadata Descriptor, 1:
+	 *    Extended Metadata Descriptor
+	 * 21 : meta_store - Store extended metadata in queue
+	 *    cache
+	 * 22 : reserved22 - MBZ
+	 * 23 : meta_desc - MBO
+	 * 24 : phase
+	 * 25 : reserved25 - MBZ
+	 * 26 : first - Indicates first descriptor in
+	 *    transaction
+	 * 27 : last - Indicates last descriptor in
+	 *    transaction
+	 * 28 : comp_req - Indicates whether completion
+	 *    should be posted, after packet is transmitted.
+	 *    Valid only for first descriptor
+	 * 30:29 : reserved29 - MBZ
+	 * 31 : reserved31 - MBZ
+	 */
+	u32 len_ctrl;
+
+	/* 5:0 : req_id_hi
+	 * 31:6 : reserved6 - MBZ
+	 */
+	u32 word1;
+
+	/* 7:0 : l3_hdr_len
+	 * 15:8 : l3_hdr_off
+	 * 21:16 : l4_hdr_len_in_words - counts the L4 header
+	 *    length in words. there is an explicit assumption
+	 *    that L4 header appears right after L3 header and
+	 *    L4 offset is based on l3_hdr_off+l3_hdr_len
+	 * 31:22 : mss_lo
+	 */
+	u32 word2;
+
+	u32 reserved;
+};
+
+struct ena_eth_io_tx_cdesc {
+	/* Request ID[15:0] */
+	u16 req_id;
+
+	u8 status;
+
+	/* flags
+	 * 0 : phase
+	 * 7:1 : reserved1
+	 */
+	u8 flags;
+
+	u16 sub_qid;
+
+	u16 sq_head_idx;
+};
+
+struct ena_eth_io_rx_desc {
+	/* In bytes. 0 means 64KB */
+	u16 length;
+
+	/* MBZ */
+	u8 reserved2;
+
+	/* 0 : phase
+	 * 1 : reserved1 - MBZ
+	 * 2 : first - Indicates first descriptor in
+	 *    transaction
+	 * 3 : last - Indicates last descriptor in transaction
+	 * 4 : comp_req
+	 * 5 : reserved5 - MBO
+	 * 7:6 : reserved6 - MBZ
+	 */
+	u8 ctrl;
+
+	u16 req_id;
+
+	/* MBZ */
+	u16 reserved6;
+
+	u32 buff_addr_lo;
+
+	u16 buff_addr_hi;
+
+	/* MBZ */
+	u16 reserved16_w3;
+};
+
+/* 4-word format Note: all ethernet parsing information are valid only when
+ * last=1
+ */
+struct ena_eth_io_rx_cdesc_base {
+	/* 4:0 : l3_proto_idx
+	 * 6:5 : src_vlan_cnt
+	 * 7 : reserved7 - MBZ
+	 * 12:8 : l4_proto_idx
+	 * 13 : l3_csum_err - when set, either the L3
+	 *    checksum error detected, or, the controller didn't
+	 *    validate the checksum. This bit is valid only when
+	 *    l3_proto_idx indicates IPv4 packet
+	 * 14 : l4_csum_err - when set, either the L4
+	 *    checksum error detected, or, the controller didn't
+	 *    validate the checksum. This bit is valid only when
+	 *    l4_proto_idx indicates TCP/UDP packet, and,
+	 *    ipv4_frag is not set
+	 * 15 : ipv4_frag - Indicates IPv4 fragmented packet
+	 * 23:16 : reserved16
+	 * 24 : phase
+	 * 25 : l3_csum2 - second checksum engine result
+	 * 26 : first - Indicates first descriptor in
+	 *    transaction
+	 * 27 : last - Indicates last descriptor in
+	 *    transaction
+	 * 29:28 : reserved28
+	 * 30 : buffer - 0: Metadata descriptor. 1: Buffer
+	 *    Descriptor was used
+	 * 31 : reserved31
+	 */
+	u32 status;
+
+	u16 length;
+
+	u16 req_id;
+
+	/* 32-bit hash result */
+	u32 hash;
+
+	u16 sub_qid;
+
+	u16 reserved;
+};
+
+/* 8-word format */
+struct ena_eth_io_rx_cdesc_ext {
+	struct ena_eth_io_rx_cdesc_base base;
+
+	u32 buff_addr_lo;
+
+	u16 buff_addr_hi;
+
+	u16 reserved16;
+
+	u32 reserved_w6;
+
+	u32 reserved_w7;
+};
+
+struct ena_eth_io_intr_reg {
+	/* 14:0 : rx_intr_delay
+	 * 29:15 : tx_intr_delay
+	 * 30 : intr_unmask
+	 * 31 : reserved
+	 */
+	u32 intr_control;
+};
+
+struct ena_eth_io_numa_node_cfg_reg {
+	/* 7:0 : numa
+	 * 30:8 : reserved
+	 * 31 : enabled
+	 */
+	u32 numa_cfg;
+};
+
+/* tx_desc */
+#define ENA_ETH_IO_TX_DESC_LENGTH_MASK GENMASK(15, 0)
+#define ENA_ETH_IO_TX_DESC_REQ_ID_HI_SHIFT 16
+#define ENA_ETH_IO_TX_DESC_REQ_ID_HI_MASK GENMASK(21, 16)
+#define ENA_ETH_IO_TX_DESC_META_DESC_SHIFT 23
+#define ENA_ETH_IO_TX_DESC_META_DESC_MASK BIT(23)
+#define ENA_ETH_IO_TX_DESC_PHASE_SHIFT 24
+#define ENA_ETH_IO_TX_DESC_PHASE_MASK BIT(24)
+#define ENA_ETH_IO_TX_DESC_FIRST_SHIFT 26
+#define ENA_ETH_IO_TX_DESC_FIRST_MASK BIT(26)
+#define ENA_ETH_IO_TX_DESC_LAST_SHIFT 27
+#define ENA_ETH_IO_TX_DESC_LAST_MASK BIT(27)
+#define ENA_ETH_IO_TX_DESC_COMP_REQ_SHIFT 28
+#define ENA_ETH_IO_TX_DESC_COMP_REQ_MASK BIT(28)
+#define ENA_ETH_IO_TX_DESC_L3_PROTO_IDX_MASK GENMASK(3, 0)
+#define ENA_ETH_IO_TX_DESC_DF_SHIFT 4
+#define ENA_ETH_IO_TX_DESC_DF_MASK BIT(4)
+#define ENA_ETH_IO_TX_DESC_TSO_EN_SHIFT 7
+#define ENA_ETH_IO_TX_DESC_TSO_EN_MASK BIT(7)
+#define ENA_ETH_IO_TX_DESC_L4_PROTO_IDX_SHIFT 8
+#define ENA_ETH_IO_TX_DESC_L4_PROTO_IDX_MASK GENMASK(12, 8)
+#define ENA_ETH_IO_TX_DESC_L3_CSUM_EN_SHIFT 13
+#define ENA_ETH_IO_TX_DESC_L3_CSUM_EN_MASK BIT(13)
+#define ENA_ETH_IO_TX_DESC_L4_CSUM_EN_SHIFT 14
+#define ENA_ETH_IO_TX_DESC_L4_CSUM_EN_MASK BIT(14)
+#define ENA_ETH_IO_TX_DESC_ETHERNET_FCS_DIS_SHIFT 15
+#define ENA_ETH_IO_TX_DESC_ETHERNET_FCS_DIS_MASK BIT(15)
+#define ENA_ETH_IO_TX_DESC_L4_CSUM_PARTIAL_SHIFT 17
+#define ENA_ETH_IO_TX_DESC_L4_CSUM_PARTIAL_MASK BIT(17)
+#define ENA_ETH_IO_TX_DESC_REQ_ID_LO_SHIFT 22
+#define ENA_ETH_IO_TX_DESC_REQ_ID_LO_MASK GENMASK(31, 22)
+#define ENA_ETH_IO_TX_DESC_ADDR_HI_MASK GENMASK(15, 0)
+#define ENA_ETH_IO_TX_DESC_HEADER_LENGTH_SHIFT 24
+#define ENA_ETH_IO_TX_DESC_HEADER_LENGTH_MASK GENMASK(31, 24)
+
+/* tx_meta_desc */
+#define ENA_ETH_IO_TX_META_DESC_REQ_ID_LO_MASK GENMASK(9, 0)
+#define ENA_ETH_IO_TX_META_DESC_EXT_VALID_SHIFT 14
+#define ENA_ETH_IO_TX_META_DESC_EXT_VALID_MASK BIT(14)
+#define ENA_ETH_IO_TX_META_DESC_MSS_HI_SHIFT 16
+#define ENA_ETH_IO_TX_META_DESC_MSS_HI_MASK GENMASK(19, 16)
+#define ENA_ETH_IO_TX_META_DESC_ETH_META_TYPE_SHIFT 20
+#define ENA_ETH_IO_TX_META_DESC_ETH_META_TYPE_MASK BIT(20)
+#define ENA_ETH_IO_TX_META_DESC_META_STORE_SHIFT 21
+#define ENA_ETH_IO_TX_META_DESC_META_STORE_MASK BIT(21)
+#define ENA_ETH_IO_TX_META_DESC_META_DESC_SHIFT 23
+#define ENA_ETH_IO_TX_META_DESC_META_DESC_MASK BIT(23)
+#define ENA_ETH_IO_TX_META_DESC_PHASE_SHIFT 24
+#define ENA_ETH_IO_TX_META_DESC_PHASE_MASK BIT(24)
+#define ENA_ETH_IO_TX_META_DESC_FIRST_SHIFT 26
+#define ENA_ETH_IO_TX_META_DESC_FIRST_MASK BIT(26)
+#define ENA_ETH_IO_TX_META_DESC_LAST_SHIFT 27
+#define ENA_ETH_IO_TX_META_DESC_LAST_MASK BIT(27)
+#define ENA_ETH_IO_TX_META_DESC_COMP_REQ_SHIFT 28
+#define ENA_ETH_IO_TX_META_DESC_COMP_REQ_MASK BIT(28)
+#define ENA_ETH_IO_TX_META_DESC_REQ_ID_HI_MASK GENMASK(5, 0)
+#define ENA_ETH_IO_TX_META_DESC_L3_HDR_LEN_MASK GENMASK(7, 0)
+#define ENA_ETH_IO_TX_META_DESC_L3_HDR_OFF_SHIFT 8
+#define ENA_ETH_IO_TX_META_DESC_L3_HDR_OFF_MASK GENMASK(15, 8)
+#define ENA_ETH_IO_TX_META_DESC_L4_HDR_LEN_IN_WORDS_SHIFT 16
+#define ENA_ETH_IO_TX_META_DESC_L4_HDR_LEN_IN_WORDS_MASK GENMASK(21, 16)
+#define ENA_ETH_IO_TX_META_DESC_MSS_LO_SHIFT 22
+#define ENA_ETH_IO_TX_META_DESC_MSS_LO_MASK GENMASK(31, 22)
+
+/* tx_cdesc */
+#define ENA_ETH_IO_TX_CDESC_PHASE_MASK BIT(0)
+
+/* rx_desc */
+#define ENA_ETH_IO_RX_DESC_PHASE_MASK BIT(0)
+#define ENA_ETH_IO_RX_DESC_FIRST_SHIFT 2
+#define ENA_ETH_IO_RX_DESC_FIRST_MASK BIT(2)
+#define ENA_ETH_IO_RX_DESC_LAST_SHIFT 3
+#define ENA_ETH_IO_RX_DESC_LAST_MASK BIT(3)
+#define ENA_ETH_IO_RX_DESC_COMP_REQ_SHIFT 4
+#define ENA_ETH_IO_RX_DESC_COMP_REQ_MASK BIT(4)
+
+/* rx_cdesc_base */
+#define ENA_ETH_IO_RX_CDESC_BASE_L3_PROTO_IDX_MASK GENMASK(4, 0)
+#define ENA_ETH_IO_RX_CDESC_BASE_SRC_VLAN_CNT_SHIFT 5
+#define ENA_ETH_IO_RX_CDESC_BASE_SRC_VLAN_CNT_MASK GENMASK(6, 5)
+#define ENA_ETH_IO_RX_CDESC_BASE_L4_PROTO_IDX_SHIFT 8
+#define ENA_ETH_IO_RX_CDESC_BASE_L4_PROTO_IDX_MASK GENMASK(12, 8)
+#define ENA_ETH_IO_RX_CDESC_BASE_L3_CSUM_ERR_SHIFT 13
+#define ENA_ETH_IO_RX_CDESC_BASE_L3_CSUM_ERR_MASK BIT(13)
+#define ENA_ETH_IO_RX_CDESC_BASE_L4_CSUM_ERR_SHIFT 14
+#define ENA_ETH_IO_RX_CDESC_BASE_L4_CSUM_ERR_MASK BIT(14)
+#define ENA_ETH_IO_RX_CDESC_BASE_IPV4_FRAG_SHIFT 15
+#define ENA_ETH_IO_RX_CDESC_BASE_IPV4_FRAG_MASK BIT(15)
+#define ENA_ETH_IO_RX_CDESC_BASE_PHASE_SHIFT 24
+#define ENA_ETH_IO_RX_CDESC_BASE_PHASE_MASK BIT(24)
+#define ENA_ETH_IO_RX_CDESC_BASE_L3_CSUM2_SHIFT 25
+#define ENA_ETH_IO_RX_CDESC_BASE_L3_CSUM2_MASK BIT(25)
+#define ENA_ETH_IO_RX_CDESC_BASE_FIRST_SHIFT 26
+#define ENA_ETH_IO_RX_CDESC_BASE_FIRST_MASK BIT(26)
+#define ENA_ETH_IO_RX_CDESC_BASE_LAST_SHIFT 27
+#define ENA_ETH_IO_RX_CDESC_BASE_LAST_MASK BIT(27)
+#define ENA_ETH_IO_RX_CDESC_BASE_BUFFER_SHIFT 30
+#define ENA_ETH_IO_RX_CDESC_BASE_BUFFER_MASK BIT(30)
+
+/* intr_reg */
+#define ENA_ETH_IO_INTR_REG_RX_INTR_DELAY_MASK GENMASK(14, 0)
+#define ENA_ETH_IO_INTR_REG_TX_INTR_DELAY_SHIFT 15
+#define ENA_ETH_IO_INTR_REG_TX_INTR_DELAY_MASK GENMASK(29, 15)
+#define ENA_ETH_IO_INTR_REG_INTR_UNMASK_SHIFT 30
+#define ENA_ETH_IO_INTR_REG_INTR_UNMASK_MASK BIT(30)
+
+/* numa_node_cfg_reg */
+#define ENA_ETH_IO_NUMA_NODE_CFG_REG_NUMA_MASK GENMASK(7, 0)
+#define ENA_ETH_IO_NUMA_NODE_CFG_REG_ENABLED_SHIFT 31
+#define ENA_ETH_IO_NUMA_NODE_CFG_REG_ENABLED_MASK BIT(31)
+
+#endif /*_ENA_ETH_IO_H_ */
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/amazon/ena/ena_ethtool.c
@@ -0,0 +1,895 @@
+/*
+ * Copyright 2015 Amazon.com, Inc. or its affiliates.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include <linux/pci.h>
+
+#include "ena_netdev.h"
+
+struct ena_stats {
+	char name[ETH_GSTRING_LEN];
+	int stat_offset;
+};
+
+#define ENA_STAT_ENA_COM_ENTRY(stat) { \
+	.name = #stat, \
+	.stat_offset = offsetof(struct ena_com_stats_admin, stat) \
+}
+
+#define ENA_STAT_ENTRY(stat, stat_type) { \
+	.name = #stat, \
+	.stat_offset = offsetof(struct ena_stats_##stat_type, stat) \
+}
+
+#define ENA_STAT_RX_ENTRY(stat) \
+	ENA_STAT_ENTRY(stat, rx)
+
+#define ENA_STAT_TX_ENTRY(stat) \
+	ENA_STAT_ENTRY(stat, tx)
+
+#define ENA_STAT_GLOBAL_ENTRY(stat) \
+	ENA_STAT_ENTRY(stat, dev)
+
+static const struct ena_stats ena_stats_global_strings[] = {
+	ENA_STAT_GLOBAL_ENTRY(tx_timeout),
+	ENA_STAT_GLOBAL_ENTRY(io_suspend),
+	ENA_STAT_GLOBAL_ENTRY(io_resume),
+	ENA_STAT_GLOBAL_ENTRY(wd_expired),
+	ENA_STAT_GLOBAL_ENTRY(interface_up),
+	ENA_STAT_GLOBAL_ENTRY(interface_down),
+	ENA_STAT_GLOBAL_ENTRY(admin_q_pause),
+};
+
+static const struct ena_stats ena_stats_tx_strings[] = {
+	ENA_STAT_TX_ENTRY(cnt),
+	ENA_STAT_TX_ENTRY(bytes),
+	ENA_STAT_TX_ENTRY(queue_stop),
+	ENA_STAT_TX_ENTRY(queue_wakeup),
+	ENA_STAT_TX_ENTRY(dma_mapping_err),
+	ENA_STAT_TX_ENTRY(linearize),
+	ENA_STAT_TX_ENTRY(linearize_failed),
+	ENA_STAT_TX_ENTRY(napi_comp),
+	ENA_STAT_TX_ENTRY(tx_poll),
+	ENA_STAT_TX_ENTRY(doorbells),
+	ENA_STAT_TX_ENTRY(prepare_ctx_err),
+	ENA_STAT_TX_ENTRY(missing_tx_comp),
+	ENA_STAT_TX_ENTRY(bad_req_id),
+};
+
+static const struct ena_stats ena_stats_rx_strings[] = {
+	ENA_STAT_RX_ENTRY(cnt),
+	ENA_STAT_RX_ENTRY(bytes),
+	ENA_STAT_RX_ENTRY(refil_partial),
+	ENA_STAT_RX_ENTRY(bad_csum),
+	ENA_STAT_RX_ENTRY(page_alloc_fail),
+	ENA_STAT_RX_ENTRY(skb_alloc_fail),
+	ENA_STAT_RX_ENTRY(dma_mapping_err),
+	ENA_STAT_RX_ENTRY(bad_desc_num),
+	ENA_STAT_RX_ENTRY(rx_copybreak_pkt),
+};
+
+static const struct ena_stats ena_stats_ena_com_strings[] = {
+	ENA_STAT_ENA_COM_ENTRY(aborted_cmd),
+	ENA_STAT_ENA_COM_ENTRY(submitted_cmd),
+	ENA_STAT_ENA_COM_ENTRY(completed_cmd),
+	ENA_STAT_ENA_COM_ENTRY(out_of_space),
+	ENA_STAT_ENA_COM_ENTRY(no_completion),
+};
+
+#define ENA_STATS_ARRAY_GLOBAL	ARRAY_SIZE(ena_stats_global_strings)
+#define ENA_STATS_ARRAY_TX	ARRAY_SIZE(ena_stats_tx_strings)
+#define ENA_STATS_ARRAY_RX	ARRAY_SIZE(ena_stats_rx_strings)
+#define ENA_STATS_ARRAY_ENA_COM	ARRAY_SIZE(ena_stats_ena_com_strings)
+
+static void ena_safe_update_stat(u64 *src, u64 *dst,
+				 struct u64_stats_sync *syncp)
+{
+	unsigned int start;
+
+	do {
+		start = u64_stats_fetch_begin_irq(syncp);
+		*(dst) = *src;
+	} while (u64_stats_fetch_retry_irq(syncp, start));
+}
+
+static void ena_queue_stats(struct ena_adapter *adapter, u64 **data)
+{
+	const struct ena_stats *ena_stats;
+	struct ena_ring *ring;
+
+	u64 *ptr;
+	int i, j;
+
+	for (i = 0; i < adapter->num_queues; i++) {
+		/* Tx stats */
+		ring = &adapter->tx_ring[i];
+
+		for (j = 0; j < ENA_STATS_ARRAY_TX; j++) {
+			ena_stats = &ena_stats_tx_strings[j];
+
+			ptr = (u64 *)((uintptr_t)&ring->tx_stats +
+				(uintptr_t)ena_stats->stat_offset);
+
+			ena_safe_update_stat(ptr, (*data)++, &ring->syncp);
+		}
+
+		/* Rx stats */
+		ring = &adapter->rx_ring[i];
+
+		for (j = 0; j < ENA_STATS_ARRAY_RX; j++) {
+			ena_stats = &ena_stats_rx_strings[j];
+
+			ptr = (u64 *)((uintptr_t)&ring->rx_stats +
+				(uintptr_t)ena_stats->stat_offset);
+
+			ena_safe_update_stat(ptr, (*data)++, &ring->syncp);
+		}
+	}
+}
+
+static void ena_dev_admin_queue_stats(struct ena_adapter *adapter, u64 **data)
+{
+	const struct ena_stats *ena_stats;
+	u32 *ptr;
+	int i;
+
+	for (i = 0; i < ENA_STATS_ARRAY_ENA_COM; i++) {
+		ena_stats = &ena_stats_ena_com_strings[i];
+
+		ptr = (u32 *)((uintptr_t)&adapter->ena_dev->admin_queue.stats +
+			(uintptr_t)ena_stats->stat_offset);
+
+		*(*data)++ = *ptr;
+	}
+}
+
+static void ena_get_ethtool_stats(struct net_device *netdev,
+				  struct ethtool_stats *stats,
+				  u64 *data)
+{
+	struct ena_adapter *adapter = netdev_priv(netdev);
+	const struct ena_stats *ena_stats;
+	u64 *ptr;
+	int i;
+
+	for (i = 0; i < ENA_STATS_ARRAY_GLOBAL; i++) {
+		ena_stats = &ena_stats_global_strings[i];
+
+		ptr = (u64 *)((uintptr_t)&adapter->dev_stats +
+			(uintptr_t)ena_stats->stat_offset);
+
+		ena_safe_update_stat(ptr, data++, &adapter->syncp);
+	}
+
+	ena_queue_stats(adapter, &data);
+	ena_dev_admin_queue_stats(adapter, &data);
+}
+
+int ena_get_sset_count(struct net_device *netdev, int sset)
+{
+	struct ena_adapter *adapter = netdev_priv(netdev);
+
+	if (sset != ETH_SS_STATS)
+		return -EOPNOTSUPP;
+
+	return  adapter->num_queues * (ENA_STATS_ARRAY_TX + ENA_STATS_ARRAY_RX)
+		+ ENA_STATS_ARRAY_GLOBAL + ENA_STATS_ARRAY_ENA_COM;
+}
+
+static void ena_queue_strings(struct ena_adapter *adapter, u8 **data)
+{
+	const struct ena_stats *ena_stats;
+	int i, j;
+
+	for (i = 0; i < adapter->num_queues; i++) {
+		/* Tx stats */
+		for (j = 0; j < ENA_STATS_ARRAY_TX; j++) {
+			ena_stats = &ena_stats_tx_strings[j];
+
+			snprintf(*data, ETH_GSTRING_LEN,
+				 "queue_%u_tx_%s", i, ena_stats->name);
+			 (*data) += ETH_GSTRING_LEN;
+		}
+		/* Rx stats */
+		for (j = 0; j < ENA_STATS_ARRAY_RX; j++) {
+			ena_stats = &ena_stats_rx_strings[j];
+
+			snprintf(*data, ETH_GSTRING_LEN,
+				 "queue_%u_rx_%s", i, ena_stats->name);
+			(*data) += ETH_GSTRING_LEN;
+		}
+	}
+}
+
+static void ena_com_dev_strings(u8 **data)
+{
+	const struct ena_stats *ena_stats;
+	int i;
+
+	for (i = 0; i < ENA_STATS_ARRAY_ENA_COM; i++) {
+		ena_stats = &ena_stats_ena_com_strings[i];
+
+		snprintf(*data, ETH_GSTRING_LEN,
+			 "ena_admin_q_%s", ena_stats->name);
+		(*data) += ETH_GSTRING_LEN;
+	}
+}
+
+static void ena_get_strings(struct net_device *netdev, u32 sset, u8 *data)
+{
+	struct ena_adapter *adapter = netdev_priv(netdev);
+	const struct ena_stats *ena_stats;
+	int i;
+
+	if (sset != ETH_SS_STATS)
+		return;
+
+	for (i = 0; i < ENA_STATS_ARRAY_GLOBAL; i++) {
+		ena_stats = &ena_stats_global_strings[i];
+
+		memcpy(data, ena_stats->name, ETH_GSTRING_LEN);
+		data += ETH_GSTRING_LEN;
+	}
+
+	ena_queue_strings(adapter, &data);
+	ena_com_dev_strings(&data);
+}
+
+static int ena_get_link_ksettings(struct net_device *netdev,
+				  struct ethtool_link_ksettings *link_ksettings)
+{
+	struct ena_adapter *adapter = netdev_priv(netdev);
+	struct ena_com_dev *ena_dev = adapter->ena_dev;
+	struct ena_admin_get_feature_link_desc *link;
+	struct ena_admin_get_feat_resp feat_resp;
+	int rc;
+
+	rc = ena_com_get_link_params(ena_dev, &feat_resp);
+	if (rc)
+		return rc;
+
+	link = &feat_resp.u.link;
+	link_ksettings->base.speed = link->speed;
+
+	if (link->flags & ENA_ADMIN_GET_FEATURE_LINK_DESC_AUTONEG_MASK) {
+		ethtool_link_ksettings_add_link_mode(link_ksettings,
+						     supported, Autoneg);
+		ethtool_link_ksettings_add_link_mode(link_ksettings,
+						     supported, Autoneg);
+	}
+
+	link_ksettings->base.autoneg =
+		(link->flags & ENA_ADMIN_GET_FEATURE_LINK_DESC_AUTONEG_MASK) ?
+		AUTONEG_ENABLE : AUTONEG_DISABLE;
+
+	link_ksettings->base.duplex = DUPLEX_FULL;
+
+	return 0;
+}
+
+static int ena_get_coalesce(struct net_device *net_dev,
+			    struct ethtool_coalesce *coalesce)
+{
+	struct ena_adapter *adapter = netdev_priv(net_dev);
+	struct ena_com_dev *ena_dev = adapter->ena_dev;
+	struct ena_intr_moder_entry intr_moder_entry;
+
+	if (!ena_com_interrupt_moderation_supported(ena_dev)) {
+		/* the devie doesn't support interrupt moderation */
+		return -EOPNOTSUPP;
+	}
+	coalesce->tx_coalesce_usecs =
+		ena_com_get_nonadaptive_moderation_interval_tx(ena_dev) /
+			ena_dev->intr_delay_resolution;
+	if (!ena_com_get_adaptive_moderation_enabled(ena_dev)) {
+		coalesce->rx_coalesce_usecs =
+			ena_com_get_nonadaptive_moderation_interval_rx(ena_dev)
+			/ ena_dev->intr_delay_resolution;
+	} else {
+		ena_com_get_intr_moderation_entry(adapter->ena_dev, ENA_INTR_MODER_LOWEST, &intr_moder_entry);
+		coalesce->rx_coalesce_usecs_low = intr_moder_entry.intr_moder_interval;
+		coalesce->rx_max_coalesced_frames_low = intr_moder_entry.pkts_per_interval;
+
+		ena_com_get_intr_moderation_entry(adapter->ena_dev, ENA_INTR_MODER_MID, &intr_moder_entry);
+		coalesce->rx_coalesce_usecs = intr_moder_entry.intr_moder_interval;
+		coalesce->rx_max_coalesced_frames = intr_moder_entry.pkts_per_interval;
+
+		ena_com_get_intr_moderation_entry(adapter->ena_dev, ENA_INTR_MODER_HIGHEST, &intr_moder_entry);
+		coalesce->rx_coalesce_usecs_high = intr_moder_entry.intr_moder_interval;
+		coalesce->rx_max_coalesced_frames_high = intr_moder_entry.pkts_per_interval;
+	}
+	coalesce->use_adaptive_rx_coalesce =
+		ena_com_get_adaptive_moderation_enabled(ena_dev);
+
+	return 0;
+}
+
+static void ena_update_tx_rings_intr_moderation(struct ena_adapter *adapter)
+{
+	unsigned int val;
+	int i;
+
+	val = ena_com_get_nonadaptive_moderation_interval_tx(adapter->ena_dev);
+
+	for (i = 0; i < adapter->num_queues; i++)
+		adapter->tx_ring[i].smoothed_interval = val;
+}
+
+static int ena_set_coalesce(struct net_device *net_dev,
+			    struct ethtool_coalesce *coalesce)
+{
+	struct ena_adapter *adapter = netdev_priv(net_dev);
+	struct ena_com_dev *ena_dev = adapter->ena_dev;
+	struct ena_intr_moder_entry intr_moder_entry;
+	int rc;
+
+	if (!ena_com_interrupt_moderation_supported(ena_dev)) {
+		/* the devie doesn't support interrupt moderation */
+		return -EOPNOTSUPP;
+	}
+
+	if (coalesce->rx_coalesce_usecs_irq ||
+	    coalesce->rx_max_coalesced_frames_irq ||
+	    coalesce->tx_coalesce_usecs_irq ||
+	    coalesce->tx_max_coalesced_frames ||
+	    coalesce->tx_max_coalesced_frames_irq ||
+	    coalesce->stats_block_coalesce_usecs ||
+	    coalesce->use_adaptive_tx_coalesce ||
+	    coalesce->pkt_rate_low ||
+	    coalesce->tx_coalesce_usecs_low ||
+	    coalesce->tx_max_coalesced_frames_low ||
+	    coalesce->pkt_rate_high ||
+	    coalesce->tx_coalesce_usecs_high ||
+	    coalesce->tx_max_coalesced_frames_high ||
+	    coalesce->rate_sample_interval)
+		return -EINVAL;
+
+	rc = ena_com_update_nonadaptive_moderation_interval_tx(ena_dev,
+							       coalesce->tx_coalesce_usecs);
+	if (rc)
+		return rc;
+
+	ena_update_tx_rings_intr_moderation(adapter);
+
+	if (ena_com_get_adaptive_moderation_enabled(ena_dev)) {
+		if (!coalesce->use_adaptive_rx_coalesce) {
+			ena_com_disable_adaptive_moderation(ena_dev);
+			rc = ena_com_update_nonadaptive_moderation_interval_rx(ena_dev,
+									       coalesce->rx_coalesce_usecs);
+			return rc;
+		}
+	} else { /* was in non-adaptive mode */
+		if (coalesce->use_adaptive_rx_coalesce) {
+			ena_com_enable_adaptive_moderation(ena_dev);
+		} else {
+			rc = ena_com_update_nonadaptive_moderation_interval_rx(ena_dev,
+									       coalesce->rx_coalesce_usecs);
+			return rc;
+		}
+	}
+
+	intr_moder_entry.intr_moder_interval = coalesce->rx_coalesce_usecs_low;
+	intr_moder_entry.pkts_per_interval = coalesce->rx_max_coalesced_frames_low;
+	intr_moder_entry.bytes_per_interval = ENA_INTR_BYTE_COUNT_NOT_SUPPORTED;
+	ena_com_init_intr_moderation_entry(adapter->ena_dev, ENA_INTR_MODER_LOWEST, &intr_moder_entry);
+
+	intr_moder_entry.intr_moder_interval = coalesce->rx_coalesce_usecs;
+	intr_moder_entry.pkts_per_interval = coalesce->rx_max_coalesced_frames;
+	intr_moder_entry.bytes_per_interval = ENA_INTR_BYTE_COUNT_NOT_SUPPORTED;
+	ena_com_init_intr_moderation_entry(adapter->ena_dev, ENA_INTR_MODER_MID, &intr_moder_entry);
+
+	intr_moder_entry.intr_moder_interval = coalesce->rx_coalesce_usecs_high;
+	intr_moder_entry.pkts_per_interval = coalesce->rx_max_coalesced_frames_high;
+	intr_moder_entry.bytes_per_interval = ENA_INTR_BYTE_COUNT_NOT_SUPPORTED;
+	ena_com_init_intr_moderation_entry(adapter->ena_dev, ENA_INTR_MODER_HIGHEST, &intr_moder_entry);
+
+	return 0;
+}
+
+static u32 ena_get_msglevel(struct net_device *netdev)
+{
+	struct ena_adapter *adapter = netdev_priv(netdev);
+
+	return adapter->msg_enable;
+}
+
+static void ena_set_msglevel(struct net_device *netdev, u32 value)
+{
+	struct ena_adapter *adapter = netdev_priv(netdev);
+
+	adapter->msg_enable = value;
+}
+
+static void ena_get_drvinfo(struct net_device *dev,
+			    struct ethtool_drvinfo *info)
+{
+	struct ena_adapter *adapter = netdev_priv(dev);
+
+	strlcpy(info->driver, DRV_MODULE_NAME, sizeof(info->driver));
+	strlcpy(info->version, DRV_MODULE_VERSION, sizeof(info->version));
+	strlcpy(info->bus_info, pci_name(adapter->pdev),
+		sizeof(info->bus_info));
+}
+
+static void ena_get_ringparam(struct net_device *netdev,
+			      struct ethtool_ringparam *ring)
+{
+	struct ena_adapter *adapter = netdev_priv(netdev);
+	struct ena_ring *tx_ring = &adapter->tx_ring[0];
+	struct ena_ring *rx_ring = &adapter->rx_ring[0];
+
+	ring->rx_max_pending = rx_ring->ring_size;
+	ring->tx_max_pending = tx_ring->ring_size;
+	ring->rx_pending = rx_ring->ring_size;
+	ring->tx_pending = tx_ring->ring_size;
+}
+
+static u32 ena_flow_hash_to_flow_type(u16 hash_fields)
+{
+	u32 data = 0;
+
+	if (hash_fields & ENA_ADMIN_RSS_L2_DA)
+		data |= RXH_L2DA;
+
+	if (hash_fields & ENA_ADMIN_RSS_L3_DA)
+		data |= RXH_IP_DST;
+
+	if (hash_fields & ENA_ADMIN_RSS_L3_SA)
+		data |= RXH_IP_SRC;
+
+	if (hash_fields & ENA_ADMIN_RSS_L4_DP)
+		data |= RXH_L4_B_2_3;
+
+	if (hash_fields & ENA_ADMIN_RSS_L4_SP)
+		data |= RXH_L4_B_0_1;
+
+	return data;
+}
+
+static u16 ena_flow_data_to_flow_hash(u32 hash_fields)
+{
+	u16 data = 0;
+
+	if (hash_fields & RXH_L2DA)
+		data |= ENA_ADMIN_RSS_L2_DA;
+
+	if (hash_fields & RXH_IP_DST)
+		data |= ENA_ADMIN_RSS_L3_DA;
+
+	if (hash_fields & RXH_IP_SRC)
+		data |= ENA_ADMIN_RSS_L3_SA;
+
+	if (hash_fields & RXH_L4_B_2_3)
+		data |= ENA_ADMIN_RSS_L4_DP;
+
+	if (hash_fields & RXH_L4_B_0_1)
+		data |= ENA_ADMIN_RSS_L4_SP;
+
+	return data;
+}
+
+static int ena_get_rss_hash(struct ena_com_dev *ena_dev,
+			    struct ethtool_rxnfc *cmd)
+{
+	enum ena_admin_flow_hash_proto proto;
+	u16 hash_fields;
+	int rc;
+
+	cmd->data = 0;
+
+	switch (cmd->flow_type) {
+	case TCP_V4_FLOW:
+		proto = ENA_ADMIN_RSS_TCP4;
+		break;
+	case UDP_V4_FLOW:
+		proto = ENA_ADMIN_RSS_UDP4;
+		break;
+	case TCP_V6_FLOW:
+		proto = ENA_ADMIN_RSS_TCP6;
+		break;
+	case UDP_V6_FLOW:
+		proto = ENA_ADMIN_RSS_UDP6;
+		break;
+	case IPV4_FLOW:
+		proto = ENA_ADMIN_RSS_IP4;
+		break;
+	case IPV6_FLOW:
+		proto = ENA_ADMIN_RSS_IP6;
+		break;
+	case ETHER_FLOW:
+		proto = ENA_ADMIN_RSS_NOT_IP;
+		break;
+	case AH_V4_FLOW:
+	case ESP_V4_FLOW:
+	case AH_V6_FLOW:
+	case ESP_V6_FLOW:
+	case SCTP_V4_FLOW:
+	case AH_ESP_V4_FLOW:
+		return -EOPNOTSUPP;
+	default:
+		return -EINVAL;
+	}
+
+	rc = ena_com_get_hash_ctrl(ena_dev, proto, &hash_fields);
+	if (rc) {
+		/* If device don't have permission, return unsupported */
+		if (rc == -EPERM)
+			rc = -EOPNOTSUPP;
+		return rc;
+	}
+
+	cmd->data = ena_flow_hash_to_flow_type(hash_fields);
+
+	return 0;
+}
+
+static int ena_set_rss_hash(struct ena_com_dev *ena_dev,
+			    struct ethtool_rxnfc *cmd)
+{
+	enum ena_admin_flow_hash_proto proto;
+	u16 hash_fields;
+
+	switch (cmd->flow_type) {
+	case TCP_V4_FLOW:
+		proto = ENA_ADMIN_RSS_TCP4;
+		break;
+	case UDP_V4_FLOW:
+		proto = ENA_ADMIN_RSS_UDP4;
+		break;
+	case TCP_V6_FLOW:
+		proto = ENA_ADMIN_RSS_TCP6;
+		break;
+	case UDP_V6_FLOW:
+		proto = ENA_ADMIN_RSS_UDP6;
+		break;
+	case IPV4_FLOW:
+		proto = ENA_ADMIN_RSS_IP4;
+		break;
+	case IPV6_FLOW:
+		proto = ENA_ADMIN_RSS_IP6;
+		break;
+	case ETHER_FLOW:
+		proto = ENA_ADMIN_RSS_NOT_IP;
+		break;
+	case AH_V4_FLOW:
+	case ESP_V4_FLOW:
+	case AH_V6_FLOW:
+	case ESP_V6_FLOW:
+	case SCTP_V4_FLOW:
+	case AH_ESP_V4_FLOW:
+		return -EOPNOTSUPP;
+	default:
+		return -EINVAL;
+	}
+
+	hash_fields = ena_flow_data_to_flow_hash(cmd->data);
+
+	return ena_com_fill_hash_ctrl(ena_dev, proto, hash_fields);
+}
+
+static int ena_set_rxnfc(struct net_device *netdev, struct ethtool_rxnfc *info)
+{
+	struct ena_adapter *adapter = netdev_priv(netdev);
+	int rc = 0;
+
+	switch (info->cmd) {
+	case ETHTOOL_SRXFH:
+		rc = ena_set_rss_hash(adapter->ena_dev, info);
+		break;
+	case ETHTOOL_SRXCLSRLDEL:
+	case ETHTOOL_SRXCLSRLINS:
+	default:
+		netif_err(adapter, drv, netdev,
+			  "Command parameter %d is not supported\n", info->cmd);
+		rc = -EOPNOTSUPP;
+	}
+
+	return (rc == -EPERM) ? -EOPNOTSUPP : rc;
+}
+
+static int ena_get_rxnfc(struct net_device *netdev, struct ethtool_rxnfc *info,
+			 u32 *rules)
+{
+	struct ena_adapter *adapter = netdev_priv(netdev);
+	int rc = 0;
+
+	switch (info->cmd) {
+	case ETHTOOL_GRXRINGS:
+		info->data = adapter->num_queues;
+		rc = 0;
+		break;
+	case ETHTOOL_GRXFH:
+		rc = ena_get_rss_hash(adapter->ena_dev, info);
+		break;
+	case ETHTOOL_GRXCLSRLCNT:
+	case ETHTOOL_GRXCLSRULE:
+	case ETHTOOL_GRXCLSRLALL:
+	default:
+		netif_err(adapter, drv, netdev,
+			  "Command parameter %d is not supported\n", info->cmd);
+		rc = -EOPNOTSUPP;
+	}
+
+	return (rc == -EPERM) ? -EOPNOTSUPP : rc;
+}
+
+static u32 ena_get_rxfh_indir_size(struct net_device *netdev)
+{
+	return ENA_RX_RSS_TABLE_SIZE;
+}
+
+static u32 ena_get_rxfh_key_size(struct net_device *netdev)
+{
+	return ENA_HASH_KEY_SIZE;
+}
+
+static int ena_get_rxfh(struct net_device *netdev, u32 *indir, u8 *key,
+			u8 *hfunc)
+{
+	struct ena_adapter *adapter = netdev_priv(netdev);
+	enum ena_admin_hash_functions ena_func;
+	u8 func;
+	int rc;
+
+	rc = ena_com_indirect_table_get(adapter->ena_dev, indir);
+	if (rc)
+		return rc;
+
+	rc = ena_com_get_hash_function(adapter->ena_dev, &ena_func, key);
+	if (rc)
+		return rc;
+
+	switch (ena_func) {
+	case ENA_ADMIN_TOEPLITZ:
+		func = ETH_RSS_HASH_TOP;
+		break;
+	case ENA_ADMIN_CRC32:
+		func = ETH_RSS_HASH_XOR;
+		break;
+	default:
+		netif_err(adapter, drv, netdev,
+			  "Command parameter is not supported\n");
+		return -EOPNOTSUPP;
+	}
+
+	if (hfunc)
+		*hfunc = func;
+
+	return rc;
+}
+
+static int ena_set_rxfh(struct net_device *netdev, const u32 *indir,
+			const u8 *key, const u8 hfunc)
+{
+	struct ena_adapter *adapter = netdev_priv(netdev);
+	struct ena_com_dev *ena_dev = adapter->ena_dev;
+	enum ena_admin_hash_functions func;
+	int rc, i;
+
+	if (indir) {
+		for (i = 0; i < ENA_RX_RSS_TABLE_SIZE; i++) {
+			rc = ena_com_indirect_table_fill_entry(ena_dev,
+							       ENA_IO_RXQ_IDX(indir[i]),
+							       i);
+			if (unlikely(rc)) {
+				netif_err(adapter, drv, netdev,
+					  "Cannot fill indirect table (index is too large)\n");
+				return rc;
+			}
+		}
+
+		rc = ena_com_indirect_table_set(ena_dev);
+		if (rc) {
+			netif_err(adapter, drv, netdev,
+				  "Cannot set indirect table\n");
+			return rc == -EPERM ? -EOPNOTSUPP : rc;
+		}
+	}
+
+	switch (hfunc) {
+	case ETH_RSS_HASH_TOP:
+		func = ENA_ADMIN_TOEPLITZ;
+		break;
+	case ETH_RSS_HASH_XOR:
+		func = ENA_ADMIN_CRC32;
+		break;
+	default:
+		netif_err(adapter, drv, netdev, "Unsupported hfunc %d\n",
+			  hfunc);
+		return -EOPNOTSUPP;
+	}
+
+	if (key) {
+		rc = ena_com_fill_hash_function(ena_dev, func, key,
+						ENA_HASH_KEY_SIZE,
+						0xFFFFFFFF);
+		if (unlikely(rc)) {
+			netif_err(adapter, drv, netdev, "Cannot fill key\n");
+			return rc == -EPERM ? -EOPNOTSUPP : rc;
+		}
+	}
+
+	return 0;
+}
+
+static void ena_get_channels(struct net_device *netdev,
+			     struct ethtool_channels *channels)
+{
+	struct ena_adapter *adapter = netdev_priv(netdev);
+
+	channels->max_rx = ENA_MAX_NUM_IO_QUEUES;
+	channels->max_tx = ENA_MAX_NUM_IO_QUEUES;
+	channels->max_other = 0;
+	channels->max_combined = 0;
+	channels->rx_count = adapter->num_queues;
+	channels->tx_count = adapter->num_queues;
+	channels->other_count = 0;
+	channels->combined_count = 0;
+}
+
+static int ena_get_tunable(struct net_device *netdev,
+			   const struct ethtool_tunable *tuna, void *data)
+{
+	struct ena_adapter *adapter = netdev_priv(netdev);
+	int ret = 0;
+
+	switch (tuna->id) {
+	case ETHTOOL_RX_COPYBREAK:
+		*(u32 *)data = adapter->rx_copybreak;
+		break;
+	default:
+		ret = -EINVAL;
+		break;
+	}
+
+	return ret;
+}
+
+static int ena_set_tunable(struct net_device *netdev,
+			   const struct ethtool_tunable *tuna,
+			   const void *data)
+{
+	struct ena_adapter *adapter = netdev_priv(netdev);
+	int ret = 0;
+	u32 len;
+
+	switch (tuna->id) {
+	case ETHTOOL_RX_COPYBREAK:
+		len = *(u32 *)data;
+		if (len > adapter->netdev->mtu) {
+			ret = -EINVAL;
+			break;
+		}
+		adapter->rx_copybreak = len;
+		break;
+	default:
+		ret = -EINVAL;
+		break;
+	}
+
+	return ret;
+}
+
+static const struct ethtool_ops ena_ethtool_ops = {
+	.get_link_ksettings	= ena_get_link_ksettings,
+	.get_drvinfo		= ena_get_drvinfo,
+	.get_msglevel		= ena_get_msglevel,
+	.set_msglevel		= ena_set_msglevel,
+	.get_link		= ethtool_op_get_link,
+	.get_coalesce		= ena_get_coalesce,
+	.set_coalesce		= ena_set_coalesce,
+	.get_ringparam		= ena_get_ringparam,
+	.get_sset_count         = ena_get_sset_count,
+	.get_strings		= ena_get_strings,
+	.get_ethtool_stats      = ena_get_ethtool_stats,
+	.get_rxnfc		= ena_get_rxnfc,
+	.set_rxnfc		= ena_set_rxnfc,
+	.get_rxfh_indir_size    = ena_get_rxfh_indir_size,
+	.get_rxfh_key_size	= ena_get_rxfh_key_size,
+	.get_rxfh		= ena_get_rxfh,
+	.set_rxfh		= ena_set_rxfh,
+	.get_channels		= ena_get_channels,
+	.get_tunable		= ena_get_tunable,
+	.set_tunable		= ena_set_tunable,
+};
+
+void ena_set_ethtool_ops(struct net_device *netdev)
+{
+	netdev->ethtool_ops = &ena_ethtool_ops;
+}
+
+static void ena_dump_stats_ex(struct ena_adapter *adapter, u8 *buf)
+{
+	struct net_device *netdev = adapter->netdev;
+	u8 *strings_buf;
+	u64 *data_buf;
+	int strings_num;
+	int i, rc;
+
+	strings_num = ena_get_sset_count(netdev, ETH_SS_STATS);
+	if (strings_num <= 0) {
+		netif_err(adapter, drv, netdev, "Can't get stats num\n");
+		return;
+	}
+
+	strings_buf = devm_kzalloc(&adapter->pdev->dev,
+				   strings_num * ETH_GSTRING_LEN,
+				   GFP_ATOMIC);
+	if (!strings_buf) {
+		netif_err(adapter, drv, netdev,
+			  "failed to alloc strings_buf\n");
+		return;
+	}
+
+	data_buf = devm_kzalloc(&adapter->pdev->dev,
+				strings_num * sizeof(u64),
+				GFP_ATOMIC);
+	if (!data_buf) {
+		netif_err(adapter, drv, netdev,
+			  "failed to allocate data buf\n");
+		devm_kfree(&adapter->pdev->dev, strings_buf);
+		return;
+	}
+
+	ena_get_strings(netdev, ETH_SS_STATS, strings_buf);
+	ena_get_ethtool_stats(netdev, NULL, data_buf);
+
+	/* If there is a buffer, dump stats, otherwise print them to dmesg */
+	if (buf)
+		for (i = 0; i < strings_num; i++) {
+			rc = snprintf(buf, ETH_GSTRING_LEN + sizeof(u64),
+				      "%s %llu\n",
+				      strings_buf + i * ETH_GSTRING_LEN,
+				      data_buf[i]);
+			buf += rc;
+		}
+	else
+		for (i = 0; i < strings_num; i++)
+			netif_err(adapter, drv, netdev, "%s: %llu\n",
+				  strings_buf + i * ETH_GSTRING_LEN,
+				  data_buf[i]);
+
+	devm_kfree(&adapter->pdev->dev, strings_buf);
+	devm_kfree(&adapter->pdev->dev, data_buf);
+}
+
+void ena_dump_stats_to_buf(struct ena_adapter *adapter, u8 *buf)
+{
+	if (!buf)
+		return;
+
+	ena_dump_stats_ex(adapter, buf);
+}
+
+void ena_dump_stats_to_dmesg(struct ena_adapter *adapter)
+{
+	ena_dump_stats_ex(adapter, NULL);
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/amazon/ena/ena_netdev.c
@@ -0,0 +1,3280 @@
+/*
+ * Copyright 2015 Amazon.com, Inc. or its affiliates.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#ifdef CONFIG_RFS_ACCEL
+#include <linux/cpu_rmap.h>
+#endif /* CONFIG_RFS_ACCEL */
+#include <linux/ethtool.h>
+#include <linux/if_vlan.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/numa.h>
+#include <linux/pci.h>
+#include <linux/utsname.h>
+#include <linux/version.h>
+#include <linux/vmalloc.h>
+#include <net/ip.h>
+
+#include "ena_netdev.h"
+#include "ena_pci_id_tbl.h"
+
+static char version[] = DEVICE_NAME " v" DRV_MODULE_VERSION "\n";
+
+MODULE_AUTHOR("Amazon.com, Inc. or its affiliates");
+MODULE_DESCRIPTION(DEVICE_NAME);
+MODULE_LICENSE("GPL");
+MODULE_VERSION(DRV_MODULE_VERSION);
+
+/* Time in jiffies before concluding the transmitter is hung. */
+#define TX_TIMEOUT  (5 * HZ)
+
+#define ENA_NAPI_BUDGET 64
+
+#define DEFAULT_MSG_ENABLE (NETIF_MSG_DRV | NETIF_MSG_PROBE | NETIF_MSG_IFUP | \
+		NETIF_MSG_TX_DONE | NETIF_MSG_TX_ERR | NETIF_MSG_RX_ERR)
+static int debug = -1;
+module_param(debug, int, 0);
+MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)");
+
+static struct ena_aenq_handlers aenq_handlers;
+
+static struct workqueue_struct *ena_wq;
+
+MODULE_DEVICE_TABLE(pci, ena_pci_tbl);
+
+static int ena_rss_init_default(struct ena_adapter *adapter);
+
+static void ena_tx_timeout(struct net_device *dev)
+{
+	struct ena_adapter *adapter = netdev_priv(dev);
+
+	u64_stats_update_begin(&adapter->syncp);
+	adapter->dev_stats.tx_timeout++;
+	u64_stats_update_end(&adapter->syncp);
+
+	netif_err(adapter, tx_err, dev, "Transmit time out\n");
+
+	/* Change the state of the device to trigger reset */
+	set_bit(ENA_FLAG_TRIGGER_RESET, &adapter->flags);
+}
+
+static void update_rx_ring_mtu(struct ena_adapter *adapter, int mtu)
+{
+	int i;
+
+	for (i = 0; i < adapter->num_queues; i++)
+		adapter->rx_ring[i].mtu = mtu;
+}
+
+static int ena_change_mtu(struct net_device *dev, int new_mtu)
+{
+	struct ena_adapter *adapter = netdev_priv(dev);
+	int ret;
+
+	if ((new_mtu > adapter->max_mtu) || (new_mtu < ENA_MIN_MTU)) {
+		netif_err(adapter, drv, dev,
+			  "Invalid MTU setting. new_mtu: %d\n", new_mtu);
+
+		return -EINVAL;
+	}
+
+	ret = ena_com_set_dev_mtu(adapter->ena_dev, new_mtu);
+	if (!ret) {
+		netif_dbg(adapter, drv, dev, "set MTU to %d\n", new_mtu);
+		update_rx_ring_mtu(adapter, new_mtu);
+		dev->mtu = new_mtu;
+	} else {
+		netif_err(adapter, drv, dev, "Failed to set MTU to %d\n",
+			  new_mtu);
+	}
+
+	return ret;
+}
+
+static int ena_init_rx_cpu_rmap(struct ena_adapter *adapter)
+{
+#ifdef CONFIG_RFS_ACCEL
+	u32 i;
+	int rc;
+
+	adapter->netdev->rx_cpu_rmap = alloc_irq_cpu_rmap(adapter->num_queues);
+	if (!adapter->netdev->rx_cpu_rmap)
+		return -ENOMEM;
+	for (i = 0; i < adapter->num_queues; i++) {
+		int irq_idx = ENA_IO_IRQ_IDX(i);
+
+		rc = irq_cpu_rmap_add(adapter->netdev->rx_cpu_rmap,
+				      adapter->msix_entries[irq_idx].vector);
+		if (rc) {
+			free_irq_cpu_rmap(adapter->netdev->rx_cpu_rmap);
+			adapter->netdev->rx_cpu_rmap = NULL;
+			return rc;
+		}
+	}
+#endif /* CONFIG_RFS_ACCEL */
+	return 0;
+}
+
+static void ena_init_io_rings_common(struct ena_adapter *adapter,
+				     struct ena_ring *ring, u16 qid)
+{
+	ring->qid = qid;
+	ring->pdev = adapter->pdev;
+	ring->dev = &adapter->pdev->dev;
+	ring->netdev = adapter->netdev;
+	ring->napi = &adapter->ena_napi[qid].napi;
+	ring->adapter = adapter;
+	ring->ena_dev = adapter->ena_dev;
+	ring->per_napi_packets = 0;
+	ring->per_napi_bytes = 0;
+	ring->cpu = 0;
+	u64_stats_init(&ring->syncp);
+}
+
+static void ena_init_io_rings(struct ena_adapter *adapter)
+{
+	struct ena_com_dev *ena_dev;
+	struct ena_ring *txr, *rxr;
+	int i;
+
+	ena_dev = adapter->ena_dev;
+
+	for (i = 0; i < adapter->num_queues; i++) {
+		txr = &adapter->tx_ring[i];
+		rxr = &adapter->rx_ring[i];
+
+		/* TX/RX common ring state */
+		ena_init_io_rings_common(adapter, txr, i);
+		ena_init_io_rings_common(adapter, rxr, i);
+
+		/* TX specific ring state */
+		txr->ring_size = adapter->tx_ring_size;
+		txr->tx_max_header_size = ena_dev->tx_max_header_size;
+		txr->tx_mem_queue_type = ena_dev->tx_mem_queue_type;
+		txr->sgl_size = adapter->max_tx_sgl_size;
+		txr->smoothed_interval =
+			ena_com_get_nonadaptive_moderation_interval_tx(ena_dev);
+
+		/* RX specific ring state */
+		rxr->ring_size = adapter->rx_ring_size;
+		rxr->rx_copybreak = adapter->rx_copybreak;
+		rxr->sgl_size = adapter->max_rx_sgl_size;
+		rxr->smoothed_interval =
+			ena_com_get_nonadaptive_moderation_interval_rx(ena_dev);
+	}
+}
+
+/* ena_setup_tx_resources - allocate I/O Tx resources (Descriptors)
+ * @adapter: network interface device structure
+ * @qid: queue index
+ *
+ * Return 0 on success, negative on failure
+ */
+static int ena_setup_tx_resources(struct ena_adapter *adapter, int qid)
+{
+	struct ena_ring *tx_ring = &adapter->tx_ring[qid];
+	struct ena_irq *ena_irq = &adapter->irq_tbl[ENA_IO_IRQ_IDX(qid)];
+	int size, i, node;
+
+	if (tx_ring->tx_buffer_info) {
+		netif_err(adapter, ifup,
+			  adapter->netdev, "tx_buffer_info info is not NULL");
+		return -EEXIST;
+	}
+
+	size = sizeof(struct ena_tx_buffer) * tx_ring->ring_size;
+	node = cpu_to_node(ena_irq->cpu);
+
+	tx_ring->tx_buffer_info = vzalloc_node(size, node);
+	if (!tx_ring->tx_buffer_info) {
+		tx_ring->tx_buffer_info = vzalloc(size);
+		if (!tx_ring->tx_buffer_info)
+			return -ENOMEM;
+	}
+
+	size = sizeof(u16) * tx_ring->ring_size;
+	tx_ring->free_tx_ids = vzalloc_node(size, node);
+	if (!tx_ring->free_tx_ids) {
+		tx_ring->free_tx_ids = vzalloc(size);
+		if (!tx_ring->free_tx_ids) {
+			vfree(tx_ring->tx_buffer_info);
+			return -ENOMEM;
+		}
+	}
+
+	/* Req id ring for TX out of order completions */
+	for (i = 0; i < tx_ring->ring_size; i++)
+		tx_ring->free_tx_ids[i] = i;
+
+	/* Reset tx statistics */
+	memset(&tx_ring->tx_stats, 0x0, sizeof(tx_ring->tx_stats));
+
+	tx_ring->next_to_use = 0;
+	tx_ring->next_to_clean = 0;
+	tx_ring->cpu = ena_irq->cpu;
+	return 0;
+}
+
+/* ena_free_tx_resources - Free I/O Tx Resources per Queue
+ * @adapter: network interface device structure
+ * @qid: queue index
+ *
+ * Free all transmit software resources
+ */
+static void ena_free_tx_resources(struct ena_adapter *adapter, int qid)
+{
+	struct ena_ring *tx_ring = &adapter->tx_ring[qid];
+
+	vfree(tx_ring->tx_buffer_info);
+	tx_ring->tx_buffer_info = NULL;
+
+	vfree(tx_ring->free_tx_ids);
+	tx_ring->free_tx_ids = NULL;
+}
+
+/* ena_setup_all_tx_resources - allocate I/O Tx queues resources for All queues
+ * @adapter: private structure
+ *
+ * Return 0 on success, negative on failure
+ */
+static int ena_setup_all_tx_resources(struct ena_adapter *adapter)
+{
+	int i, rc = 0;
+
+	for (i = 0; i < adapter->num_queues; i++) {
+		rc = ena_setup_tx_resources(adapter, i);
+		if (rc)
+			goto err_setup_tx;
+	}
+
+	return 0;
+
+err_setup_tx:
+
+	netif_err(adapter, ifup, adapter->netdev,
+		  "Tx queue %d: allocation failed\n", i);
+
+	/* rewind the index freeing the rings as we go */
+	while (i--)
+		ena_free_tx_resources(adapter, i);
+	return rc;
+}
+
+/* ena_free_all_io_tx_resources - Free I/O Tx Resources for All Queues
+ * @adapter: board private structure
+ *
+ * Free all transmit software resources
+ */
+static void ena_free_all_io_tx_resources(struct ena_adapter *adapter)
+{
+	int i;
+
+	for (i = 0; i < adapter->num_queues; i++)
+		ena_free_tx_resources(adapter, i);
+}
+
+/* ena_setup_rx_resources - allocate I/O Rx resources (Descriptors)
+ * @adapter: network interface device structure
+ * @qid: queue index
+ *
+ * Returns 0 on success, negative on failure
+ */
+static int ena_setup_rx_resources(struct ena_adapter *adapter,
+				  u32 qid)
+{
+	struct ena_ring *rx_ring = &adapter->rx_ring[qid];
+	struct ena_irq *ena_irq = &adapter->irq_tbl[ENA_IO_IRQ_IDX(qid)];
+	int size, node;
+
+	if (rx_ring->rx_buffer_info) {
+		netif_err(adapter, ifup, adapter->netdev,
+			  "rx_buffer_info is not NULL");
+		return -EEXIST;
+	}
+
+	/* alloc extra element so in rx path
+	 * we can always prefetch rx_info + 1
+	 */
+	size = sizeof(struct ena_rx_buffer) * (rx_ring->ring_size + 1);
+	node = cpu_to_node(ena_irq->cpu);
+
+	rx_ring->rx_buffer_info = vzalloc_node(size, node);
+	if (!rx_ring->rx_buffer_info) {
+		rx_ring->rx_buffer_info = vzalloc(size);
+		if (!rx_ring->rx_buffer_info)
+			return -ENOMEM;
+	}
+
+	/* Reset rx statistics */
+	memset(&rx_ring->rx_stats, 0x0, sizeof(rx_ring->rx_stats));
+
+	rx_ring->next_to_clean = 0;
+	rx_ring->next_to_use = 0;
+	rx_ring->cpu = ena_irq->cpu;
+
+	return 0;
+}
+
+/* ena_free_rx_resources - Free I/O Rx Resources
+ * @adapter: network interface device structure
+ * @qid: queue index
+ *
+ * Free all receive software resources
+ */
+static void ena_free_rx_resources(struct ena_adapter *adapter,
+				  u32 qid)
+{
+	struct ena_ring *rx_ring = &adapter->rx_ring[qid];
+
+	vfree(rx_ring->rx_buffer_info);
+	rx_ring->rx_buffer_info = NULL;
+}
+
+/* ena_setup_all_rx_resources - allocate I/O Rx queues resources for all queues
+ * @adapter: board private structure
+ *
+ * Return 0 on success, negative on failure
+ */
+static int ena_setup_all_rx_resources(struct ena_adapter *adapter)
+{
+	int i, rc = 0;
+
+	for (i = 0; i < adapter->num_queues; i++) {
+		rc = ena_setup_rx_resources(adapter, i);
+		if (rc)
+			goto err_setup_rx;
+	}
+
+	return 0;
+
+err_setup_rx:
+
+	netif_err(adapter, ifup, adapter->netdev,
+		  "Rx queue %d: allocation failed\n", i);
+
+	/* rewind the index freeing the rings as we go */
+	while (i--)
+		ena_free_rx_resources(adapter, i);
+	return rc;
+}
+
+/* ena_free_all_io_rx_resources - Free I/O Rx Resources for All Queues
+ * @adapter: board private structure
+ *
+ * Free all receive software resources
+ */
+static void ena_free_all_io_rx_resources(struct ena_adapter *adapter)
+{
+	int i;
+
+	for (i = 0; i < adapter->num_queues; i++)
+		ena_free_rx_resources(adapter, i);
+}
+
+static inline int ena_alloc_rx_page(struct ena_ring *rx_ring,
+				    struct ena_rx_buffer *rx_info, gfp_t gfp)
+{
+	struct ena_com_buf *ena_buf;
+	struct page *page;
+	dma_addr_t dma;
+
+	/* if previous allocated page is not used */
+	if (unlikely(rx_info->page))
+		return 0;
+
+	page = alloc_page(gfp);
+	if (unlikely(!page)) {
+		u64_stats_update_begin(&rx_ring->syncp);
+		rx_ring->rx_stats.page_alloc_fail++;
+		u64_stats_update_end(&rx_ring->syncp);
+		return -ENOMEM;
+	}
+
+	dma = dma_map_page(rx_ring->dev, page, 0, PAGE_SIZE,
+			   DMA_FROM_DEVICE);
+	if (unlikely(dma_mapping_error(rx_ring->dev, dma))) {
+		u64_stats_update_begin(&rx_ring->syncp);
+		rx_ring->rx_stats.dma_mapping_err++;
+		u64_stats_update_end(&rx_ring->syncp);
+
+		__free_page(page);
+		return -EIO;
+	}
+	netif_dbg(rx_ring->adapter, rx_status, rx_ring->netdev,
+		  "alloc page %p, rx_info %p\n", page, rx_info);
+
+	rx_info->page = page;
+	rx_info->page_offset = 0;
+	ena_buf = &rx_info->ena_buf;
+	ena_buf->paddr = dma;
+	ena_buf->len = PAGE_SIZE;
+
+	return 0;
+}
+
+static void ena_free_rx_page(struct ena_ring *rx_ring,
+			     struct ena_rx_buffer *rx_info)
+{
+	struct page *page = rx_info->page;
+	struct ena_com_buf *ena_buf = &rx_info->ena_buf;
+
+	if (unlikely(!page)) {
+		netif_warn(rx_ring->adapter, rx_err, rx_ring->netdev,
+			   "Trying to free unallocated buffer\n");
+		return;
+	}
+
+	dma_unmap_page(rx_ring->dev, ena_buf->paddr, PAGE_SIZE,
+		       DMA_FROM_DEVICE);
+
+	__free_page(page);
+	rx_info->page = NULL;
+}
+
+static int ena_refill_rx_bufs(struct ena_ring *rx_ring, u32 num)
+{
+	u16 next_to_use;
+	u32 i;
+	int rc;
+
+	next_to_use = rx_ring->next_to_use;
+
+	for (i = 0; i < num; i++) {
+		struct ena_rx_buffer *rx_info =
+			&rx_ring->rx_buffer_info[next_to_use];
+
+		rc = ena_alloc_rx_page(rx_ring, rx_info,
+				       __GFP_COLD | GFP_ATOMIC | __GFP_COMP);
+		if (unlikely(rc < 0)) {
+			netif_warn(rx_ring->adapter, rx_err, rx_ring->netdev,
+				   "failed to alloc buffer for rx queue %d\n",
+				   rx_ring->qid);
+			break;
+		}
+		rc = ena_com_add_single_rx_desc(rx_ring->ena_com_io_sq,
+						&rx_info->ena_buf,
+						next_to_use);
+		if (unlikely(rc)) {
+			netif_warn(rx_ring->adapter, rx_status, rx_ring->netdev,
+				   "failed to add buffer for rx queue %d\n",
+				   rx_ring->qid);
+			break;
+		}
+		next_to_use = ENA_RX_RING_IDX_NEXT(next_to_use,
+						   rx_ring->ring_size);
+	}
+
+	if (unlikely(i < num)) {
+		u64_stats_update_begin(&rx_ring->syncp);
+		rx_ring->rx_stats.refil_partial++;
+		u64_stats_update_end(&rx_ring->syncp);
+		netdev_warn(rx_ring->netdev,
+			    "refilled rx qid %d with only %d buffers (from %d)\n",
+			    rx_ring->qid, i, num);
+	}
+
+	if (likely(i)) {
+		/* Add memory barrier to make sure the desc were written before
+		 * issue a doorbell
+		 */
+		wmb();
+		ena_com_write_sq_doorbell(rx_ring->ena_com_io_sq);
+	}
+
+	rx_ring->next_to_use = next_to_use;
+
+	return i;
+}
+
+static void ena_free_rx_bufs(struct ena_adapter *adapter,
+			     u32 qid)
+{
+	struct ena_ring *rx_ring = &adapter->rx_ring[qid];
+	u32 i;
+
+	for (i = 0; i < rx_ring->ring_size; i++) {
+		struct ena_rx_buffer *rx_info = &rx_ring->rx_buffer_info[i];
+
+		if (rx_info->page)
+			ena_free_rx_page(rx_ring, rx_info);
+	}
+}
+
+/* ena_refill_all_rx_bufs - allocate all queues Rx buffers
+ * @adapter: board private structure
+ *
+ */
+static void ena_refill_all_rx_bufs(struct ena_adapter *adapter)
+{
+	struct ena_ring *rx_ring;
+	int i, rc, bufs_num;
+
+	for (i = 0; i < adapter->num_queues; i++) {
+		rx_ring = &adapter->rx_ring[i];
+		bufs_num = rx_ring->ring_size - 1;
+		rc = ena_refill_rx_bufs(rx_ring, bufs_num);
+
+		if (unlikely(rc != bufs_num))
+			netif_warn(rx_ring->adapter, rx_status, rx_ring->netdev,
+				   "refilling Queue %d failed. allocated %d buffers from: %d\n",
+				   i, rc, bufs_num);
+	}
+}
+
+static void ena_free_all_rx_bufs(struct ena_adapter *adapter)
+{
+	int i;
+
+	for (i = 0; i < adapter->num_queues; i++)
+		ena_free_rx_bufs(adapter, i);
+}
+
+/* ena_free_tx_bufs - Free Tx Buffers per Queue
+ * @tx_ring: TX ring for which buffers be freed
+ */
+static void ena_free_tx_bufs(struct ena_ring *tx_ring)
+{
+	u32 i;
+
+	for (i = 0; i < tx_ring->ring_size; i++) {
+		struct ena_tx_buffer *tx_info = &tx_ring->tx_buffer_info[i];
+		struct ena_com_buf *ena_buf;
+		int nr_frags;
+		int j;
+
+		if (!tx_info->skb)
+			continue;
+
+		netdev_notice(tx_ring->netdev,
+			      "free uncompleted tx skb qid %d idx 0x%x\n",
+			      tx_ring->qid, i);
+
+		ena_buf = tx_info->bufs;
+		dma_unmap_single(tx_ring->dev,
+				 ena_buf->paddr,
+				 ena_buf->len,
+				 DMA_TO_DEVICE);
+
+		/* unmap remaining mapped pages */
+		nr_frags = tx_info->num_of_bufs - 1;
+		for (j = 0; j < nr_frags; j++) {
+			ena_buf++;
+			dma_unmap_page(tx_ring->dev,
+				       ena_buf->paddr,
+				       ena_buf->len,
+				       DMA_TO_DEVICE);
+		}
+
+		dev_kfree_skb_any(tx_info->skb);
+	}
+	netdev_tx_reset_queue(netdev_get_tx_queue(tx_ring->netdev,
+						  tx_ring->qid));
+}
+
+static void ena_free_all_tx_bufs(struct ena_adapter *adapter)
+{
+	struct ena_ring *tx_ring;
+	int i;
+
+	for (i = 0; i < adapter->num_queues; i++) {
+		tx_ring = &adapter->tx_ring[i];
+		ena_free_tx_bufs(tx_ring);
+	}
+}
+
+static void ena_destroy_all_tx_queues(struct ena_adapter *adapter)
+{
+	u16 ena_qid;
+	int i;
+
+	for (i = 0; i < adapter->num_queues; i++) {
+		ena_qid = ENA_IO_TXQ_IDX(i);
+		ena_com_destroy_io_queue(adapter->ena_dev, ena_qid);
+	}
+}
+
+static void ena_destroy_all_rx_queues(struct ena_adapter *adapter)
+{
+	u16 ena_qid;
+	int i;
+
+	for (i = 0; i < adapter->num_queues; i++) {
+		ena_qid = ENA_IO_RXQ_IDX(i);
+		ena_com_destroy_io_queue(adapter->ena_dev, ena_qid);
+	}
+}
+
+static void ena_destroy_all_io_queues(struct ena_adapter *adapter)
+{
+	ena_destroy_all_tx_queues(adapter);
+	ena_destroy_all_rx_queues(adapter);
+}
+
+static int validate_tx_req_id(struct ena_ring *tx_ring, u16 req_id)
+{
+	struct ena_tx_buffer *tx_info = NULL;
+
+	if (likely(req_id < tx_ring->ring_size)) {
+		tx_info = &tx_ring->tx_buffer_info[req_id];
+		if (likely(tx_info->skb))
+			return 0;
+	}
+
+	if (tx_info)
+		netif_err(tx_ring->adapter, tx_done, tx_ring->netdev,
+			  "tx_info doesn't have valid skb\n");
+	else
+		netif_err(tx_ring->adapter, tx_done, tx_ring->netdev,
+			  "Invalid req_id: %hu\n", req_id);
+
+	u64_stats_update_begin(&tx_ring->syncp);
+	tx_ring->tx_stats.bad_req_id++;
+	u64_stats_update_end(&tx_ring->syncp);
+
+	/* Trigger device reset */
+	set_bit(ENA_FLAG_TRIGGER_RESET, &tx_ring->adapter->flags);
+	return -EFAULT;
+}
+
+static int ena_clean_tx_irq(struct ena_ring *tx_ring, u32 budget)
+{
+	struct netdev_queue *txq;
+	bool above_thresh;
+	u32 tx_bytes = 0;
+	u32 total_done = 0;
+	u16 next_to_clean;
+	u16 req_id;
+	int tx_pkts = 0;
+	int rc;
+
+	next_to_clean = tx_ring->next_to_clean;
+	txq = netdev_get_tx_queue(tx_ring->netdev, tx_ring->qid);
+
+	while (tx_pkts < budget) {
+		struct ena_tx_buffer *tx_info;
+		struct sk_buff *skb;
+		struct ena_com_buf *ena_buf;
+		int i, nr_frags;
+
+		rc = ena_com_tx_comp_req_id_get(tx_ring->ena_com_io_cq,
+						&req_id);
+		if (rc)
+			break;
+
+		rc = validate_tx_req_id(tx_ring, req_id);
+		if (rc)
+			break;
+
+		tx_info = &tx_ring->tx_buffer_info[req_id];
+		skb = tx_info->skb;
+
+		/* prefetch skb_end_pointer() to speedup skb_shinfo(skb) */
+		prefetch(&skb->end);
+
+		tx_info->skb = NULL;
+		tx_info->last_jiffies = 0;
+
+		if (likely(tx_info->num_of_bufs != 0)) {
+			ena_buf = tx_info->bufs;
+
+			dma_unmap_single(tx_ring->dev,
+					 dma_unmap_addr(ena_buf, paddr),
+					 dma_unmap_len(ena_buf, len),
+					 DMA_TO_DEVICE);
+
+			/* unmap remaining mapped pages */
+			nr_frags = tx_info->num_of_bufs - 1;
+			for (i = 0; i < nr_frags; i++) {
+				ena_buf++;
+				dma_unmap_page(tx_ring->dev,
+					       dma_unmap_addr(ena_buf, paddr),
+					       dma_unmap_len(ena_buf, len),
+					       DMA_TO_DEVICE);
+			}
+		}
+
+		netif_dbg(tx_ring->adapter, tx_done, tx_ring->netdev,
+			  "tx_poll: q %d skb %p completed\n", tx_ring->qid,
+			  skb);
+
+		tx_bytes += skb->len;
+		dev_kfree_skb(skb);
+		tx_pkts++;
+		total_done += tx_info->tx_descs;
+
+		tx_ring->free_tx_ids[next_to_clean] = req_id;
+		next_to_clean = ENA_TX_RING_IDX_NEXT(next_to_clean,
+						     tx_ring->ring_size);
+	}
+
+	tx_ring->next_to_clean = next_to_clean;
+	ena_com_comp_ack(tx_ring->ena_com_io_sq, total_done);
+	ena_com_update_dev_comp_head(tx_ring->ena_com_io_cq);
+
+	netdev_tx_completed_queue(txq, tx_pkts, tx_bytes);
+
+	netif_dbg(tx_ring->adapter, tx_done, tx_ring->netdev,
+		  "tx_poll: q %d done. total pkts: %d\n",
+		  tx_ring->qid, tx_pkts);
+
+	/* need to make the rings circular update visible to
+	 * ena_start_xmit() before checking for netif_queue_stopped().
+	 */
+	smp_mb();
+
+	above_thresh = ena_com_sq_empty_space(tx_ring->ena_com_io_sq) >
+		ENA_TX_WAKEUP_THRESH;
+	if (unlikely(netif_tx_queue_stopped(txq) && above_thresh)) {
+		__netif_tx_lock(txq, smp_processor_id());
+		above_thresh = ena_com_sq_empty_space(tx_ring->ena_com_io_sq) >
+			ENA_TX_WAKEUP_THRESH;
+		if (netif_tx_queue_stopped(txq) && above_thresh) {
+			netif_tx_wake_queue(txq);
+			u64_stats_update_begin(&tx_ring->syncp);
+			tx_ring->tx_stats.queue_wakeup++;
+			u64_stats_update_end(&tx_ring->syncp);
+		}
+		__netif_tx_unlock(txq);
+	}
+
+	tx_ring->per_napi_bytes += tx_bytes;
+	tx_ring->per_napi_packets += tx_pkts;
+
+	return tx_pkts;
+}
+
+static struct sk_buff *ena_rx_skb(struct ena_ring *rx_ring,
+				  struct ena_com_rx_buf_info *ena_bufs,
+				  u32 descs,
+				  u16 *next_to_clean)
+{
+	struct sk_buff *skb;
+	struct ena_rx_buffer *rx_info =
+		&rx_ring->rx_buffer_info[*next_to_clean];
+	u32 len;
+	u32 buf = 0;
+	void *va;
+
+	len = ena_bufs[0].len;
+	if (unlikely(!rx_info->page)) {
+		netif_err(rx_ring->adapter, rx_err, rx_ring->netdev,
+			  "Page is NULL\n");
+		return NULL;
+	}
+
+	netif_dbg(rx_ring->adapter, rx_status, rx_ring->netdev,
+		  "rx_info %p page %p\n",
+		  rx_info, rx_info->page);
+
+	/* save virt address of first buffer */
+	va = page_address(rx_info->page) + rx_info->page_offset;
+	prefetch(va + NET_IP_ALIGN);
+
+	if (len <= rx_ring->rx_copybreak) {
+		skb = netdev_alloc_skb_ip_align(rx_ring->netdev,
+						rx_ring->rx_copybreak);
+		if (unlikely(!skb)) {
+			u64_stats_update_begin(&rx_ring->syncp);
+			rx_ring->rx_stats.skb_alloc_fail++;
+			u64_stats_update_end(&rx_ring->syncp);
+			netif_err(rx_ring->adapter, rx_err, rx_ring->netdev,
+				  "Failed to allocate skb\n");
+			return NULL;
+		}
+
+		netif_dbg(rx_ring->adapter, rx_status, rx_ring->netdev,
+			  "rx allocated small packet. len %d. data_len %d\n",
+			  skb->len, skb->data_len);
+
+		/* sync this buffer for CPU use */
+		dma_sync_single_for_cpu(rx_ring->dev,
+					dma_unmap_addr(&rx_info->ena_buf, paddr),
+					len,
+					DMA_FROM_DEVICE);
+		skb_copy_to_linear_data(skb, va, len);
+		dma_sync_single_for_device(rx_ring->dev,
+					   dma_unmap_addr(&rx_info->ena_buf, paddr),
+					   len,
+					   DMA_FROM_DEVICE);
+
+		skb_put(skb, len);
+		skb->protocol = eth_type_trans(skb, rx_ring->netdev);
+		*next_to_clean = ENA_RX_RING_IDX_ADD(*next_to_clean, descs,
+						     rx_ring->ring_size);
+		return skb;
+	}
+
+	skb = napi_get_frags(rx_ring->napi);
+	if (unlikely(!skb)) {
+		netif_dbg(rx_ring->adapter, rx_status, rx_ring->netdev,
+			  "Failed allocating skb\n");
+		u64_stats_update_begin(&rx_ring->syncp);
+		rx_ring->rx_stats.skb_alloc_fail++;
+		u64_stats_update_end(&rx_ring->syncp);
+		return NULL;
+	}
+
+	do {
+		dma_unmap_page(rx_ring->dev,
+			       dma_unmap_addr(&rx_info->ena_buf, paddr),
+			       PAGE_SIZE, DMA_FROM_DEVICE);
+
+		skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, rx_info->page,
+				rx_info->page_offset, len, PAGE_SIZE);
+
+		netif_dbg(rx_ring->adapter, rx_status, rx_ring->netdev,
+			  "rx skb updated. len %d. data_len %d\n",
+			  skb->len, skb->data_len);
+
+		rx_info->page = NULL;
+		*next_to_clean =
+			ENA_RX_RING_IDX_NEXT(*next_to_clean,
+					     rx_ring->ring_size);
+		if (likely(--descs == 0))
+			break;
+		rx_info = &rx_ring->rx_buffer_info[*next_to_clean];
+		len = ena_bufs[++buf].len;
+	} while (1);
+
+	return skb;
+}
+
+/* ena_rx_checksum - indicate in skb if hw indicated a good cksum
+ * @adapter: structure containing adapter specific data
+ * @ena_rx_ctx: received packet context/metadata
+ * @skb: skb currently being received and modified
+ */
+static inline void ena_rx_checksum(struct ena_ring *rx_ring,
+				   struct ena_com_rx_ctx *ena_rx_ctx,
+				   struct sk_buff *skb)
+{
+	/* Rx csum disabled */
+	if (unlikely(!(rx_ring->netdev->features & NETIF_F_RXCSUM))) {
+		skb->ip_summed = CHECKSUM_NONE;
+		return;
+	}
+
+	/* For fragmented packets the checksum isn't valid */
+	if (ena_rx_ctx->frag) {
+		skb->ip_summed = CHECKSUM_NONE;
+		return;
+	}
+
+	/* if IP and error */
+	if (unlikely((ena_rx_ctx->l3_proto == ENA_ETH_IO_L3_PROTO_IPV4) &&
+		     (ena_rx_ctx->l3_csum_err))) {
+		/* ipv4 checksum error */
+		skb->ip_summed = CHECKSUM_NONE;
+		u64_stats_update_begin(&rx_ring->syncp);
+		rx_ring->rx_stats.bad_csum++;
+		u64_stats_update_end(&rx_ring->syncp);
+		netif_err(rx_ring->adapter, rx_err, rx_ring->netdev,
+			  "RX IPv4 header checksum error\n");
+		return;
+	}
+
+	/* if TCP/UDP */
+	if (likely((ena_rx_ctx->l4_proto == ENA_ETH_IO_L4_PROTO_TCP) ||
+		   (ena_rx_ctx->l4_proto == ENA_ETH_IO_L4_PROTO_UDP))) {
+		if (unlikely(ena_rx_ctx->l4_csum_err)) {
+			/* TCP/UDP checksum error */
+			u64_stats_update_begin(&rx_ring->syncp);
+			rx_ring->rx_stats.bad_csum++;
+			u64_stats_update_end(&rx_ring->syncp);
+			netif_err(rx_ring->adapter, rx_err, rx_ring->netdev,
+				  "RX L4 checksum error\n");
+			skb->ip_summed = CHECKSUM_NONE;
+			return;
+		}
+
+		skb->ip_summed = CHECKSUM_UNNECESSARY;
+	}
+}
+
+static void ena_set_rx_hash(struct ena_ring *rx_ring,
+			    struct ena_com_rx_ctx *ena_rx_ctx,
+			    struct sk_buff *skb)
+{
+	enum pkt_hash_types hash_type;
+
+	if (likely(rx_ring->netdev->features & NETIF_F_RXHASH)) {
+		if (likely((ena_rx_ctx->l4_proto == ENA_ETH_IO_L4_PROTO_TCP) ||
+			   (ena_rx_ctx->l4_proto == ENA_ETH_IO_L4_PROTO_UDP)))
+
+			hash_type = PKT_HASH_TYPE_L4;
+		else
+			hash_type = PKT_HASH_TYPE_NONE;
+
+		/* Override hash type if the packet is fragmented */
+		if (ena_rx_ctx->frag)
+			hash_type = PKT_HASH_TYPE_NONE;
+
+		skb_set_hash(skb, ena_rx_ctx->hash, hash_type);
+	}
+}
+
+/* ena_clean_rx_irq - Cleanup RX irq
+ * @rx_ring: RX ring to clean
+ * @napi: napi handler
+ * @budget: how many packets driver is allowed to clean
+ *
+ * Returns the number of cleaned buffers.
+ */
+static int ena_clean_rx_irq(struct ena_ring *rx_ring, struct napi_struct *napi,
+			    u32 budget)
+{
+	u16 next_to_clean = rx_ring->next_to_clean;
+	u32 res_budget, work_done;
+
+	struct ena_com_rx_ctx ena_rx_ctx;
+	struct ena_adapter *adapter;
+	struct sk_buff *skb;
+	int refill_required;
+	int refill_threshold;
+	int rc = 0;
+	int total_len = 0;
+	int rx_copybreak_pkt = 0;
+
+	netif_dbg(rx_ring->adapter, rx_status, rx_ring->netdev,
+		  "%s qid %d\n", __func__, rx_ring->qid);
+	res_budget = budget;
+
+	do {
+		ena_rx_ctx.ena_bufs = rx_ring->ena_bufs;
+		ena_rx_ctx.max_bufs = rx_ring->sgl_size;
+		ena_rx_ctx.descs = 0;
+		rc = ena_com_rx_pkt(rx_ring->ena_com_io_cq,
+				    rx_ring->ena_com_io_sq,
+				    &ena_rx_ctx);
+		if (unlikely(rc))
+			goto error;
+
+		if (unlikely(ena_rx_ctx.descs == 0))
+			break;
+
+		netif_dbg(rx_ring->adapter, rx_status, rx_ring->netdev,
+			  "rx_poll: q %d got packet from ena. descs #: %d l3 proto %d l4 proto %d hash: %x\n",
+			  rx_ring->qid, ena_rx_ctx.descs, ena_rx_ctx.l3_proto,
+			  ena_rx_ctx.l4_proto, ena_rx_ctx.hash);
+
+		/* allocate skb and fill it */
+		skb = ena_rx_skb(rx_ring, rx_ring->ena_bufs, ena_rx_ctx.descs,
+				 &next_to_clean);
+
+		/* exit if we failed to retrieve a buffer */
+		if (unlikely(!skb)) {
+			next_to_clean = ENA_RX_RING_IDX_ADD(next_to_clean,
+							    ena_rx_ctx.descs,
+							    rx_ring->ring_size);
+			break;
+		}
+
+		ena_rx_checksum(rx_ring, &ena_rx_ctx, skb);
+
+		ena_set_rx_hash(rx_ring, &ena_rx_ctx, skb);
+
+		skb_record_rx_queue(skb, rx_ring->qid);
+
+		if (rx_ring->ena_bufs[0].len <= rx_ring->rx_copybreak) {
+			total_len += rx_ring->ena_bufs[0].len;
+			rx_copybreak_pkt++;
+			napi_gro_receive(napi, skb);
+		} else {
+			total_len += skb->len;
+			napi_gro_frags(napi);
+		}
+
+		res_budget--;
+	} while (likely(res_budget));
+
+	work_done = budget - res_budget;
+	rx_ring->per_napi_bytes += total_len;
+	rx_ring->per_napi_packets += work_done;
+	u64_stats_update_begin(&rx_ring->syncp);
+	rx_ring->rx_stats.bytes += total_len;
+	rx_ring->rx_stats.cnt += work_done;
+	rx_ring->rx_stats.rx_copybreak_pkt += rx_copybreak_pkt;
+	u64_stats_update_end(&rx_ring->syncp);
+
+	rx_ring->next_to_clean = next_to_clean;
+
+	refill_required = ena_com_sq_empty_space(rx_ring->ena_com_io_sq);
+	refill_threshold = rx_ring->ring_size / ENA_RX_REFILL_THRESH_DIVIDER;
+
+	/* Optimization, try to batch new rx buffers */
+	if (refill_required > refill_threshold) {
+		ena_com_update_dev_comp_head(rx_ring->ena_com_io_cq);
+		ena_refill_rx_bufs(rx_ring, refill_required);
+	}
+
+	return work_done;
+
+error:
+	adapter = netdev_priv(rx_ring->netdev);
+
+	u64_stats_update_begin(&rx_ring->syncp);
+	rx_ring->rx_stats.bad_desc_num++;
+	u64_stats_update_end(&rx_ring->syncp);
+
+	/* Too many desc from the device. Trigger reset */
+	set_bit(ENA_FLAG_TRIGGER_RESET, &adapter->flags);
+
+	return 0;
+}
+
+inline void ena_adjust_intr_moderation(struct ena_ring *rx_ring,
+				       struct ena_ring *tx_ring)
+{
+	/* We apply adaptive moderation on Rx path only.
+	 * Tx uses static interrupt moderation.
+	 */
+	ena_com_calculate_interrupt_delay(rx_ring->ena_dev,
+					  rx_ring->per_napi_packets,
+					  rx_ring->per_napi_bytes,
+					  &rx_ring->smoothed_interval,
+					  &rx_ring->moder_tbl_idx);
+
+	/* Reset per napi packets/bytes */
+	tx_ring->per_napi_packets = 0;
+	tx_ring->per_napi_bytes = 0;
+	rx_ring->per_napi_packets = 0;
+	rx_ring->per_napi_bytes = 0;
+}
+
+static inline void ena_update_ring_numa_node(struct ena_ring *tx_ring,
+					     struct ena_ring *rx_ring)
+{
+	int cpu = get_cpu();
+	int numa_node;
+
+	/* Check only one ring since the 2 rings are running on the same cpu */
+	if (likely(tx_ring->cpu == cpu))
+		goto out;
+
+	numa_node = cpu_to_node(cpu);
+	put_cpu();
+
+	if (numa_node != NUMA_NO_NODE) {
+		ena_com_update_numa_node(tx_ring->ena_com_io_cq, numa_node);
+		ena_com_update_numa_node(rx_ring->ena_com_io_cq, numa_node);
+	}
+
+	tx_ring->cpu = cpu;
+	rx_ring->cpu = cpu;
+
+	return;
+out:
+	put_cpu();
+}
+
+static int ena_io_poll(struct napi_struct *napi, int budget)
+{
+	struct ena_napi *ena_napi = container_of(napi, struct ena_napi, napi);
+	struct ena_ring *tx_ring, *rx_ring;
+	struct ena_eth_io_intr_reg intr_reg;
+
+	u32 tx_work_done;
+	u32 rx_work_done;
+	int tx_budget;
+	int napi_comp_call = 0;
+	int ret;
+
+	tx_ring = ena_napi->tx_ring;
+	rx_ring = ena_napi->rx_ring;
+
+	tx_budget = tx_ring->ring_size / ENA_TX_POLL_BUDGET_DIVIDER;
+
+	if (!test_bit(ENA_FLAG_DEV_UP, &tx_ring->adapter->flags)) {
+		napi_complete_done(napi, 0);
+		return 0;
+	}
+
+	tx_work_done = ena_clean_tx_irq(tx_ring, tx_budget);
+	rx_work_done = ena_clean_rx_irq(rx_ring, napi, budget);
+
+	if ((budget > rx_work_done) && (tx_budget > tx_work_done)) {
+		napi_complete_done(napi, rx_work_done);
+
+		napi_comp_call = 1;
+		/* Tx and Rx share the same interrupt vector */
+		if (ena_com_get_adaptive_moderation_enabled(rx_ring->ena_dev))
+			ena_adjust_intr_moderation(rx_ring, tx_ring);
+
+		/* Update intr register: rx intr delay, tx intr delay and
+		 * interrupt unmask
+		 */
+		ena_com_update_intr_reg(&intr_reg,
+					rx_ring->smoothed_interval,
+					tx_ring->smoothed_interval,
+					true);
+
+		/* It is a shared MSI-X. Tx and Rx CQ have pointer to it.
+		 * So we use one of them to reach the intr reg
+		 */
+		ena_com_unmask_intr(rx_ring->ena_com_io_cq, &intr_reg);
+
+		ena_update_ring_numa_node(tx_ring, rx_ring);
+
+		ret = rx_work_done;
+	} else {
+		ret = budget;
+	}
+
+	u64_stats_update_begin(&tx_ring->syncp);
+	tx_ring->tx_stats.napi_comp += napi_comp_call;
+	tx_ring->tx_stats.tx_poll++;
+	u64_stats_update_end(&tx_ring->syncp);
+
+	return ret;
+}
+
+static irqreturn_t ena_intr_msix_mgmnt(int irq, void *data)
+{
+	struct ena_adapter *adapter = (struct ena_adapter *)data;
+
+	ena_com_admin_q_comp_intr_handler(adapter->ena_dev);
+
+	/* Don't call the aenq handler before probe is done */
+	if (likely(test_bit(ENA_FLAG_DEVICE_RUNNING, &adapter->flags)))
+		ena_com_aenq_intr_handler(adapter->ena_dev, data);
+
+	return IRQ_HANDLED;
+}
+
+/* ena_intr_msix_io - MSI-X Interrupt Handler for Tx/Rx
+ * @irq: interrupt number
+ * @data: pointer to a network interface private napi device structure
+ */
+static irqreturn_t ena_intr_msix_io(int irq, void *data)
+{
+	struct ena_napi *ena_napi = data;
+
+	napi_schedule(&ena_napi->napi);
+
+	return IRQ_HANDLED;
+}
+
+static int ena_enable_msix(struct ena_adapter *adapter, int num_queues)
+{
+	int i, msix_vecs, rc;
+
+	if (test_bit(ENA_FLAG_MSIX_ENABLED, &adapter->flags)) {
+		netif_err(adapter, probe, adapter->netdev,
+			  "Error, MSI-X is already enabled\n");
+		return -EPERM;
+	}
+
+	/* Reserved the max msix vectors we might need */
+	msix_vecs = ENA_MAX_MSIX_VEC(num_queues);
+
+	netif_dbg(adapter, probe, adapter->netdev,
+		  "trying to enable MSI-X, vectors %d\n", msix_vecs);
+
+	adapter->msix_entries = vzalloc(msix_vecs * sizeof(struct msix_entry));
+
+	if (!adapter->msix_entries)
+		return -ENOMEM;
+
+	for (i = 0; i < msix_vecs; i++)
+		adapter->msix_entries[i].entry = i;
+
+	rc = pci_enable_msix(adapter->pdev, adapter->msix_entries, msix_vecs);
+	if (rc != 0) {
+		netif_err(adapter, probe, adapter->netdev,
+			  "Failed to enable MSI-X, vectors %d rc %d\n",
+			  msix_vecs, rc);
+		return -ENOSPC;
+	}
+
+	netif_dbg(adapter, probe, adapter->netdev, "enable MSI-X, vectors %d\n",
+		  msix_vecs);
+
+	if (msix_vecs >= 1) {
+		if (ena_init_rx_cpu_rmap(adapter))
+			netif_warn(adapter, probe, adapter->netdev,
+				   "Failed to map IRQs to CPUs\n");
+	}
+
+	adapter->msix_vecs = msix_vecs;
+	set_bit(ENA_FLAG_MSIX_ENABLED, &adapter->flags);
+
+	return 0;
+}
+
+static void ena_setup_mgmnt_intr(struct ena_adapter *adapter)
+{
+	u32 cpu;
+
+	snprintf(adapter->irq_tbl[ENA_MGMNT_IRQ_IDX].name,
+		 ENA_IRQNAME_SIZE, "ena-mgmnt@pci:%s",
+		 pci_name(adapter->pdev));
+	adapter->irq_tbl[ENA_MGMNT_IRQ_IDX].handler =
+		ena_intr_msix_mgmnt;
+	adapter->irq_tbl[ENA_MGMNT_IRQ_IDX].data = adapter;
+	adapter->irq_tbl[ENA_MGMNT_IRQ_IDX].vector =
+		adapter->msix_entries[ENA_MGMNT_IRQ_IDX].vector;
+	cpu = cpumask_first(cpu_online_mask);
+	adapter->irq_tbl[ENA_MGMNT_IRQ_IDX].cpu = cpu;
+	cpumask_set_cpu(cpu,
+			&adapter->irq_tbl[ENA_MGMNT_IRQ_IDX].affinity_hint_mask);
+}
+
+static void ena_setup_io_intr(struct ena_adapter *adapter)
+{
+	struct net_device *netdev;
+	int irq_idx, i, cpu;
+
+	netdev = adapter->netdev;
+
+	for (i = 0; i < adapter->num_queues; i++) {
+		irq_idx = ENA_IO_IRQ_IDX(i);
+		cpu = i % num_online_cpus();
+
+		snprintf(adapter->irq_tbl[irq_idx].name, ENA_IRQNAME_SIZE,
+			 "%s-Tx-Rx-%d", netdev->name, i);
+		adapter->irq_tbl[irq_idx].handler = ena_intr_msix_io;
+		adapter->irq_tbl[irq_idx].data = &adapter->ena_napi[i];
+		adapter->irq_tbl[irq_idx].vector =
+			adapter->msix_entries[irq_idx].vector;
+		adapter->irq_tbl[irq_idx].cpu = cpu;
+
+		cpumask_set_cpu(cpu,
+				&adapter->irq_tbl[irq_idx].affinity_hint_mask);
+	}
+}
+
+static int ena_request_mgmnt_irq(struct ena_adapter *adapter)
+{
+	unsigned long flags = 0;
+	struct ena_irq *irq;
+	int rc;
+
+	irq = &adapter->irq_tbl[ENA_MGMNT_IRQ_IDX];
+	rc = request_irq(irq->vector, irq->handler, flags, irq->name,
+			 irq->data);
+	if (rc) {
+		netif_err(adapter, probe, adapter->netdev,
+			  "failed to request admin irq\n");
+		return rc;
+	}
+
+	netif_dbg(adapter, probe, adapter->netdev,
+		  "set affinity hint of mgmnt irq.to 0x%lx (irq vector: %d)\n",
+		  irq->affinity_hint_mask.bits[0], irq->vector);
+
+	irq_set_affinity_hint(irq->vector, &irq->affinity_hint_mask);
+
+	return rc;
+}
+
+static int ena_request_io_irq(struct ena_adapter *adapter)
+{
+	unsigned long flags = 0;
+	struct ena_irq *irq;
+	int rc = 0, i, k;
+
+	if (!test_bit(ENA_FLAG_MSIX_ENABLED, &adapter->flags)) {
+		netif_err(adapter, ifup, adapter->netdev,
+			  "Failed to request I/O IRQ: MSI-X is not enabled\n");
+		return -EINVAL;
+	}
+
+	for (i = ENA_IO_IRQ_FIRST_IDX; i < adapter->msix_vecs; i++) {
+		irq = &adapter->irq_tbl[i];
+		rc = request_irq(irq->vector, irq->handler, flags, irq->name,
+				 irq->data);
+		if (rc) {
+			netif_err(adapter, ifup, adapter->netdev,
+				  "Failed to request I/O IRQ. index %d rc %d\n",
+				   i, rc);
+			goto err;
+		}
+
+		netif_dbg(adapter, ifup, adapter->netdev,
+			  "set affinity hint of irq. index %d to 0x%lx (irq vector: %d)\n",
+			  i, irq->affinity_hint_mask.bits[0], irq->vector);
+
+		irq_set_affinity_hint(irq->vector, &irq->affinity_hint_mask);
+	}
+
+	return rc;
+
+err:
+	for (k = ENA_IO_IRQ_FIRST_IDX; k < i; k++) {
+		irq = &adapter->irq_tbl[k];
+		free_irq(irq->vector, irq->data);
+	}
+
+	return rc;
+}
+
+static void ena_free_mgmnt_irq(struct ena_adapter *adapter)
+{
+	struct ena_irq *irq;
+
+	irq = &adapter->irq_tbl[ENA_MGMNT_IRQ_IDX];
+	synchronize_irq(irq->vector);
+	irq_set_affinity_hint(irq->vector, NULL);
+	free_irq(irq->vector, irq->data);
+}
+
+static void ena_free_io_irq(struct ena_adapter *adapter)
+{
+	struct ena_irq *irq;
+	int i;
+
+#ifdef CONFIG_RFS_ACCEL
+	if (adapter->msix_vecs >= 1) {
+		free_irq_cpu_rmap(adapter->netdev->rx_cpu_rmap);
+		adapter->netdev->rx_cpu_rmap = NULL;
+	}
+#endif /* CONFIG_RFS_ACCEL */
+
+	for (i = ENA_IO_IRQ_FIRST_IDX; i < adapter->msix_vecs; i++) {
+		irq = &adapter->irq_tbl[i];
+		irq_set_affinity_hint(irq->vector, NULL);
+		free_irq(irq->vector, irq->data);
+	}
+}
+
+static void ena_disable_msix(struct ena_adapter *adapter)
+{
+	if (test_and_clear_bit(ENA_FLAG_MSIX_ENABLED, &adapter->flags))
+		pci_disable_msix(adapter->pdev);
+
+	if (adapter->msix_entries)
+		vfree(adapter->msix_entries);
+	adapter->msix_entries = NULL;
+}
+
+static void ena_disable_io_intr_sync(struct ena_adapter *adapter)
+{
+	int i;
+
+	if (!netif_running(adapter->netdev))
+		return;
+
+	for (i = ENA_IO_IRQ_FIRST_IDX; i < adapter->msix_vecs; i++)
+		synchronize_irq(adapter->irq_tbl[i].vector);
+}
+
+static void ena_del_napi(struct ena_adapter *adapter)
+{
+	int i;
+
+	for (i = 0; i < adapter->num_queues; i++)
+		netif_napi_del(&adapter->ena_napi[i].napi);
+}
+
+static void ena_init_napi(struct ena_adapter *adapter)
+{
+	struct ena_napi *napi;
+	int i;
+
+	for (i = 0; i < adapter->num_queues; i++) {
+		napi = &adapter->ena_napi[i];
+
+		netif_napi_add(adapter->netdev,
+			       &adapter->ena_napi[i].napi,
+			       ena_io_poll,
+			       ENA_NAPI_BUDGET);
+		napi->rx_ring = &adapter->rx_ring[i];
+		napi->tx_ring = &adapter->tx_ring[i];
+		napi->qid = i;
+	}
+}
+
+static void ena_napi_disable_all(struct ena_adapter *adapter)
+{
+	int i;
+
+	for (i = 0; i < adapter->num_queues; i++)
+		napi_disable(&adapter->ena_napi[i].napi);
+}
+
+static void ena_napi_enable_all(struct ena_adapter *adapter)
+{
+	int i;
+
+	for (i = 0; i < adapter->num_queues; i++)
+		napi_enable(&adapter->ena_napi[i].napi);
+}
+
+static void ena_restore_ethtool_params(struct ena_adapter *adapter)
+{
+	adapter->tx_usecs = 0;
+	adapter->rx_usecs = 0;
+	adapter->tx_frames = 1;
+	adapter->rx_frames = 1;
+}
+
+/* Configure the Rx forwarding */
+static int ena_rss_configure(struct ena_adapter *adapter)
+{
+	struct ena_com_dev *ena_dev = adapter->ena_dev;
+	int rc;
+
+	/* In case the RSS table wasn't initialized by probe */
+	if (!ena_dev->rss.tbl_log_size) {
+		rc = ena_rss_init_default(adapter);
+		if (rc && (rc != -EPERM)) {
+			netif_err(adapter, ifup, adapter->netdev,
+				  "Failed to init RSS rc: %d\n", rc);
+			return rc;
+		}
+	}
+
+	/* Set indirect table */
+	rc = ena_com_indirect_table_set(ena_dev);
+	if (unlikely(rc && rc != -EPERM))
+		return rc;
+
+	/* Configure hash function (if supported) */
+	rc = ena_com_set_hash_function(ena_dev);
+	if (unlikely(rc && (rc != -EPERM)))
+		return rc;
+
+	/* Configure hash inputs (if supported) */
+	rc = ena_com_set_hash_ctrl(ena_dev);
+	if (unlikely(rc && (rc != -EPERM)))
+		return rc;
+
+	return 0;
+}
+
+static int ena_up_complete(struct ena_adapter *adapter)
+{
+	int rc, i;
+
+	rc = ena_rss_configure(adapter);
+	if (rc)
+		return rc;
+
+	ena_init_napi(adapter);
+
+	ena_change_mtu(adapter->netdev, adapter->netdev->mtu);
+
+	ena_refill_all_rx_bufs(adapter);
+
+	/* enable transmits */
+	netif_tx_start_all_queues(adapter->netdev);
+
+	ena_restore_ethtool_params(adapter);
+
+	ena_napi_enable_all(adapter);
+
+	/* schedule napi in case we had pending packets
+	 * from the last time we disable napi
+	 */
+	for (i = 0; i < adapter->num_queues; i++)
+		napi_schedule(&adapter->ena_napi[i].napi);
+
+	return 0;
+}
+
+static int ena_create_io_tx_queue(struct ena_adapter *adapter, int qid)
+{
+	struct ena_com_create_io_ctx ctx = { 0 };
+	struct ena_com_dev *ena_dev;
+	struct ena_ring *tx_ring;
+	u32 msix_vector;
+	u16 ena_qid;
+	int rc;
+
+	ena_dev = adapter->ena_dev;
+
+	tx_ring = &adapter->tx_ring[qid];
+	msix_vector = ENA_IO_IRQ_IDX(qid);
+	ena_qid = ENA_IO_TXQ_IDX(qid);
+
+	ctx.direction = ENA_COM_IO_QUEUE_DIRECTION_TX;
+	ctx.qid = ena_qid;
+	ctx.mem_queue_type = ena_dev->tx_mem_queue_type;
+	ctx.msix_vector = msix_vector;
+	ctx.queue_size = adapter->tx_ring_size;
+	ctx.numa_node = cpu_to_node(tx_ring->cpu);
+
+	rc = ena_com_create_io_queue(ena_dev, &ctx);
+	if (rc) {
+		netif_err(adapter, ifup, adapter->netdev,
+			  "Failed to create I/O TX queue num %d rc: %d\n",
+			  qid, rc);
+		return rc;
+	}
+
+	rc = ena_com_get_io_handlers(ena_dev, ena_qid,
+				     &tx_ring->ena_com_io_sq,
+				     &tx_ring->ena_com_io_cq);
+	if (rc) {
+		netif_err(adapter, ifup, adapter->netdev,
+			  "Failed to get TX queue handlers. TX queue num %d rc: %d\n",
+			  qid, rc);
+		ena_com_destroy_io_queue(ena_dev, ena_qid);
+	}
+
+	ena_com_update_numa_node(tx_ring->ena_com_io_cq, ctx.numa_node);
+	return rc;
+}
+
+static int ena_create_all_io_tx_queues(struct ena_adapter *adapter)
+{
+	struct ena_com_dev *ena_dev = adapter->ena_dev;
+	int rc, i;
+
+	for (i = 0; i < adapter->num_queues; i++) {
+		rc = ena_create_io_tx_queue(adapter, i);
+		if (rc)
+			goto create_err;
+	}
+
+	return 0;
+
+create_err:
+	while (i--)
+		ena_com_destroy_io_queue(ena_dev, ENA_IO_TXQ_IDX(i));
+
+	return rc;
+}
+
+static int ena_create_io_rx_queue(struct ena_adapter *adapter, int qid)
+{
+	struct ena_com_dev *ena_dev;
+	struct ena_com_create_io_ctx ctx = { 0 };
+	struct ena_ring *rx_ring;
+	u32 msix_vector;
+	u16 ena_qid;
+	int rc;
+
+	ena_dev = adapter->ena_dev;
+
+	rx_ring = &adapter->rx_ring[qid];
+	msix_vector = ENA_IO_IRQ_IDX(qid);
+	ena_qid = ENA_IO_RXQ_IDX(qid);
+
+	ctx.qid = ena_qid;
+	ctx.direction = ENA_COM_IO_QUEUE_DIRECTION_RX;
+	ctx.mem_queue_type = ENA_ADMIN_PLACEMENT_POLICY_HOST;
+	ctx.msix_vector = msix_vector;
+	ctx.queue_size = adapter->rx_ring_size;
+	ctx.numa_node = cpu_to_node(rx_ring->cpu);
+
+	rc = ena_com_create_io_queue(ena_dev, &ctx);
+	if (rc) {
+		netif_err(adapter, ifup, adapter->netdev,
+			  "Failed to create I/O RX queue num %d rc: %d\n",
+			  qid, rc);
+		return rc;
+	}
+
+	rc = ena_com_get_io_handlers(ena_dev, ena_qid,
+				     &rx_ring->ena_com_io_sq,
+				     &rx_ring->ena_com_io_cq);
+	if (rc) {
+		netif_err(adapter, ifup, adapter->netdev,
+			  "Failed to get RX queue handlers. RX queue num %d rc: %d\n",
+			  qid, rc);
+		ena_com_destroy_io_queue(ena_dev, ena_qid);
+	}
+
+	ena_com_update_numa_node(rx_ring->ena_com_io_cq, ctx.numa_node);
+
+	return rc;
+}
+
+static int ena_create_all_io_rx_queues(struct ena_adapter *adapter)
+{
+	struct ena_com_dev *ena_dev = adapter->ena_dev;
+	int rc, i;
+
+	for (i = 0; i < adapter->num_queues; i++) {
+		rc = ena_create_io_rx_queue(adapter, i);
+		if (rc)
+			goto create_err;
+	}
+
+	return 0;
+
+create_err:
+	while (i--)
+		ena_com_destroy_io_queue(ena_dev, ENA_IO_RXQ_IDX(i));
+
+	return rc;
+}
+
+static int ena_up(struct ena_adapter *adapter)
+{
+	int rc;
+
+	netdev_dbg(adapter->netdev, "%s\n", __func__);
+
+	ena_setup_io_intr(adapter);
+
+	rc = ena_request_io_irq(adapter);
+	if (rc)
+		goto err_req_irq;
+
+	/* allocate transmit descriptors */
+	rc = ena_setup_all_tx_resources(adapter);
+	if (rc)
+		goto err_setup_tx;
+
+	/* allocate receive descriptors */
+	rc = ena_setup_all_rx_resources(adapter);
+	if (rc)
+		goto err_setup_rx;
+
+	/* Create TX queues */
+	rc = ena_create_all_io_tx_queues(adapter);
+	if (rc)
+		goto err_create_tx_queues;
+
+	/* Create RX queues */
+	rc = ena_create_all_io_rx_queues(adapter);
+	if (rc)
+		goto err_create_rx_queues;
+
+	rc = ena_up_complete(adapter);
+	if (rc)
+		goto err_up;
+
+	if (test_bit(ENA_FLAG_LINK_UP, &adapter->flags))
+		netif_carrier_on(adapter->netdev);
+
+	u64_stats_update_begin(&adapter->syncp);
+	adapter->dev_stats.interface_up++;
+	u64_stats_update_end(&adapter->syncp);
+
+	set_bit(ENA_FLAG_DEV_UP, &adapter->flags);
+
+	return rc;
+
+err_up:
+	ena_destroy_all_rx_queues(adapter);
+err_create_rx_queues:
+	ena_destroy_all_tx_queues(adapter);
+err_create_tx_queues:
+	ena_free_all_io_rx_resources(adapter);
+err_setup_rx:
+	ena_free_all_io_tx_resources(adapter);
+err_setup_tx:
+	ena_free_io_irq(adapter);
+err_req_irq:
+
+	return rc;
+}
+
+static void ena_down(struct ena_adapter *adapter)
+{
+	netif_info(adapter, ifdown, adapter->netdev, "%s\n", __func__);
+
+	clear_bit(ENA_FLAG_DEV_UP, &adapter->flags);
+
+	u64_stats_update_begin(&adapter->syncp);
+	adapter->dev_stats.interface_down++;
+	u64_stats_update_end(&adapter->syncp);
+
+	/* After this point the napi handler won't enable the tx queue */
+	ena_napi_disable_all(adapter);
+	netif_carrier_off(adapter->netdev);
+	netif_tx_disable(adapter->netdev);
+
+	/* After destroy the queue there won't be any new interrupts */
+	ena_destroy_all_io_queues(adapter);
+
+	ena_disable_io_intr_sync(adapter);
+	ena_free_io_irq(adapter);
+	ena_del_napi(adapter);
+
+	ena_free_all_tx_bufs(adapter);
+	ena_free_all_rx_bufs(adapter);
+	ena_free_all_io_tx_resources(adapter);
+	ena_free_all_io_rx_resources(adapter);
+}
+
+/* ena_open - Called when a network interface is made active
+ * @netdev: network interface device structure
+ *
+ * Returns 0 on success, negative value on failure
+ *
+ * The open entry point is called when a network interface is made
+ * active by the system (IFF_UP).  At this point all resources needed
+ * for transmit and receive operations are allocated, the interrupt
+ * handler is registered with the OS, the watchdog timer is started,
+ * and the stack is notified that the interface is ready.
+ */
+static int ena_open(struct net_device *netdev)
+{
+	struct ena_adapter *adapter = netdev_priv(netdev);
+	int rc;
+
+	/* Notify the stack of the actual queue counts. */
+	rc = netif_set_real_num_tx_queues(netdev, adapter->num_queues);
+	if (rc) {
+		netif_err(adapter, ifup, netdev, "Can't set num tx queues\n");
+		return rc;
+	}
+
+	rc = netif_set_real_num_rx_queues(netdev, adapter->num_queues);
+	if (rc) {
+		netif_err(adapter, ifup, netdev, "Can't set num rx queues\n");
+		return rc;
+	}
+
+	rc = ena_up(adapter);
+	if (rc)
+		return rc;
+
+	return rc;
+}
+
+/* ena_close - Disables a network interface
+ * @netdev: network interface device structure
+ *
+ * Returns 0, this is not allowed to fail
+ *
+ * The close entry point is called when an interface is de-activated
+ * by the OS.  The hardware is still under the drivers control, but
+ * needs to be disabled.  A global MAC reset is issued to stop the
+ * hardware, and all transmit and receive resources are freed.
+ */
+static int ena_close(struct net_device *netdev)
+{
+	struct ena_adapter *adapter = netdev_priv(netdev);
+
+	netif_dbg(adapter, ifdown, netdev, "%s\n", __func__);
+
+	if (test_bit(ENA_FLAG_DEV_UP, &adapter->flags))
+		ena_down(adapter);
+
+	return 0;
+}
+
+static void ena_tx_csum(struct ena_com_tx_ctx *ena_tx_ctx, struct sk_buff *skb)
+{
+	u32 mss = skb_shinfo(skb)->gso_size;
+	struct ena_com_tx_meta *ena_meta = &ena_tx_ctx->ena_meta;
+	u8 l4_protocol = 0;
+
+	if ((skb->ip_summed == CHECKSUM_PARTIAL) || mss) {
+		ena_tx_ctx->l4_csum_enable = 1;
+		if (mss) {
+			ena_tx_ctx->tso_enable = 1;
+			ena_meta->l4_hdr_len = tcp_hdr(skb)->doff;
+			ena_tx_ctx->l4_csum_partial = 0;
+		} else {
+			ena_tx_ctx->tso_enable = 0;
+			ena_meta->l4_hdr_len = 0;
+			ena_tx_ctx->l4_csum_partial = 1;
+		}
+
+		switch (ip_hdr(skb)->version) {
+		case IPVERSION:
+			ena_tx_ctx->l3_proto = ENA_ETH_IO_L3_PROTO_IPV4;
+			if (ip_hdr(skb)->frag_off & htons(IP_DF))
+				ena_tx_ctx->df = 1;
+			if (mss)
+				ena_tx_ctx->l3_csum_enable = 1;
+			l4_protocol = ip_hdr(skb)->protocol;
+			break;
+		case 6:
+			ena_tx_ctx->l3_proto = ENA_ETH_IO_L3_PROTO_IPV6;
+			l4_protocol = ipv6_hdr(skb)->nexthdr;
+			break;
+		default:
+			break;
+		}
+
+		if (l4_protocol == IPPROTO_TCP)
+			ena_tx_ctx->l4_proto = ENA_ETH_IO_L4_PROTO_TCP;
+		else
+			ena_tx_ctx->l4_proto = ENA_ETH_IO_L4_PROTO_UDP;
+
+		ena_meta->mss = mss;
+		ena_meta->l3_hdr_len = skb_network_header_len(skb);
+		ena_meta->l3_hdr_offset = skb_network_offset(skb);
+		ena_tx_ctx->meta_valid = 1;
+
+	} else {
+		ena_tx_ctx->meta_valid = 0;
+	}
+}
+
+static int ena_check_and_linearize_skb(struct ena_ring *tx_ring,
+				       struct sk_buff *skb)
+{
+	int num_frags, header_len, rc;
+
+	num_frags = skb_shinfo(skb)->nr_frags;
+	header_len = skb_headlen(skb);
+
+	if (num_frags < tx_ring->sgl_size)
+		return 0;
+
+	if ((num_frags == tx_ring->sgl_size) &&
+	    (header_len < tx_ring->tx_max_header_size))
+		return 0;
+
+	u64_stats_update_begin(&tx_ring->syncp);
+	tx_ring->tx_stats.linearize++;
+	u64_stats_update_end(&tx_ring->syncp);
+
+	rc = skb_linearize(skb);
+	if (unlikely(rc)) {
+		u64_stats_update_begin(&tx_ring->syncp);
+		tx_ring->tx_stats.linearize_failed++;
+		u64_stats_update_end(&tx_ring->syncp);
+	}
+
+	return rc;
+}
+
+/* Called with netif_tx_lock. */
+static netdev_tx_t ena_start_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+	struct ena_adapter *adapter = netdev_priv(dev);
+	struct ena_tx_buffer *tx_info;
+	struct ena_com_tx_ctx ena_tx_ctx;
+	struct ena_ring *tx_ring;
+	struct netdev_queue *txq;
+	struct ena_com_buf *ena_buf;
+	void *push_hdr;
+	u32 len, last_frag;
+	u16 next_to_use;
+	u16 req_id;
+	u16 push_len;
+	u16 header_len;
+	dma_addr_t dma;
+	int qid, rc, nb_hw_desc;
+	int i = -1;
+
+	netif_dbg(adapter, tx_queued, dev, "%s skb %p\n", __func__, skb);
+	/*  Determine which tx ring we will be placed on */
+	qid = skb_get_queue_mapping(skb);
+	tx_ring = &adapter->tx_ring[qid];
+	txq = netdev_get_tx_queue(dev, qid);
+
+	rc = ena_check_and_linearize_skb(tx_ring, skb);
+	if (unlikely(rc))
+		goto error_drop_packet;
+
+	skb_tx_timestamp(skb);
+	len = skb_headlen(skb);
+
+	next_to_use = tx_ring->next_to_use;
+	req_id = tx_ring->free_tx_ids[next_to_use];
+	tx_info = &tx_ring->tx_buffer_info[req_id];
+	tx_info->num_of_bufs = 0;
+
+	WARN(tx_info->skb, "SKB isn't NULL req_id %d\n", req_id);
+	ena_buf = tx_info->bufs;
+	tx_info->skb = skb;
+
+	if (tx_ring->tx_mem_queue_type == ENA_ADMIN_PLACEMENT_POLICY_DEV) {
+		/* prepared the push buffer */
+		push_len = min_t(u32, len, tx_ring->tx_max_header_size);
+		header_len = push_len;
+		push_hdr = skb->data;
+	} else {
+		push_len = 0;
+		header_len = min_t(u32, len, tx_ring->tx_max_header_size);
+		push_hdr = NULL;
+	}
+
+	netif_dbg(adapter, tx_queued, dev,
+		  "skb: %p header_buf->vaddr: %p push_len: %d\n", skb,
+		  push_hdr, push_len);
+
+	if (len > push_len) {
+		dma = dma_map_single(tx_ring->dev, skb->data + push_len,
+				     len - push_len, DMA_TO_DEVICE);
+		if (dma_mapping_error(tx_ring->dev, dma))
+			goto error_report_dma_error;
+
+		ena_buf->paddr = dma;
+		ena_buf->len = len - push_len;
+
+		ena_buf++;
+		tx_info->num_of_bufs++;
+	}
+
+	last_frag = skb_shinfo(skb)->nr_frags;
+
+	for (i = 0; i < last_frag; i++) {
+		const skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
+
+		len = skb_frag_size(frag);
+		dma = skb_frag_dma_map(tx_ring->dev, frag, 0, len,
+				       DMA_TO_DEVICE);
+		if (dma_mapping_error(tx_ring->dev, dma))
+			goto error_report_dma_error;
+
+		ena_buf->paddr = dma;
+		ena_buf->len = len;
+		ena_buf++;
+	}
+
+	tx_info->num_of_bufs += last_frag;
+
+	memset(&ena_tx_ctx, 0x0, sizeof(struct ena_com_tx_ctx));
+	ena_tx_ctx.ena_bufs = tx_info->bufs;
+	ena_tx_ctx.push_header = push_hdr;
+	ena_tx_ctx.num_bufs = tx_info->num_of_bufs;
+	ena_tx_ctx.req_id = req_id;
+	ena_tx_ctx.header_len = header_len;
+
+	/* set flags and meta data */
+	ena_tx_csum(&ena_tx_ctx, skb);
+
+	/* prepare the packet's descriptors to dma engine */
+	rc = ena_com_prepare_tx(tx_ring->ena_com_io_sq, &ena_tx_ctx,
+				&nb_hw_desc);
+
+	if (unlikely(rc)) {
+		netif_err(adapter, tx_queued, dev,
+			  "failed to prepare tx bufs\n");
+		u64_stats_update_begin(&tx_ring->syncp);
+		tx_ring->tx_stats.queue_stop++;
+		tx_ring->tx_stats.prepare_ctx_err++;
+		u64_stats_update_end(&tx_ring->syncp);
+		netif_tx_stop_queue(txq);
+		goto error_unmap_dma;
+	}
+
+	netdev_tx_sent_queue(txq, skb->len);
+
+	u64_stats_update_begin(&tx_ring->syncp);
+	tx_ring->tx_stats.cnt++;
+	tx_ring->tx_stats.bytes += skb->len;
+	u64_stats_update_end(&tx_ring->syncp);
+
+	tx_info->tx_descs = nb_hw_desc;
+	tx_info->last_jiffies = jiffies;
+
+	tx_ring->next_to_use = ENA_TX_RING_IDX_NEXT(next_to_use,
+		tx_ring->ring_size);
+
+	/* This WMB is aimed to:
+	 * 1 - perform smp barrier before reading next_to_completion
+	 * 2 - make sure the desc were written before trigger DB
+	 */
+	wmb();
+
+	/* stop the queue when no more space available, the packet can have up
+	 * to sgl_size + 2. one for the meta descriptor and one for header
+	 * (if the header is larger than tx_max_header_size).
+	 */
+	if (unlikely(ena_com_sq_empty_space(tx_ring->ena_com_io_sq) <
+		     (tx_ring->sgl_size + 2))) {
+		netif_dbg(adapter, tx_queued, dev, "%s stop queue %d\n",
+			  __func__, qid);
+
+		netif_tx_stop_queue(txq);
+		u64_stats_update_begin(&tx_ring->syncp);
+		tx_ring->tx_stats.queue_stop++;
+		u64_stats_update_end(&tx_ring->syncp);
+
+		/* There is a rare condition where this function decide to
+		 * stop the queue but meanwhile clean_tx_irq updates
+		 * next_to_completion and terminates.
+		 * The queue will remain stopped forever.
+		 * To solve this issue this function perform rmb, check
+		 * the wakeup condition and wake up the queue if needed.
+		 */
+		smp_rmb();
+
+		if (ena_com_sq_empty_space(tx_ring->ena_com_io_sq)
+				> ENA_TX_WAKEUP_THRESH) {
+			netif_tx_wake_queue(txq);
+			u64_stats_update_begin(&tx_ring->syncp);
+			tx_ring->tx_stats.queue_wakeup++;
+			u64_stats_update_end(&tx_ring->syncp);
+		}
+	}
+
+	if (netif_xmit_stopped(txq) || !skb->xmit_more) {
+		/* trigger the dma engine */
+		ena_com_write_sq_doorbell(tx_ring->ena_com_io_sq);
+		u64_stats_update_begin(&tx_ring->syncp);
+		tx_ring->tx_stats.doorbells++;
+		u64_stats_update_end(&tx_ring->syncp);
+	}
+
+	return NETDEV_TX_OK;
+
+error_report_dma_error:
+	u64_stats_update_begin(&tx_ring->syncp);
+	tx_ring->tx_stats.dma_mapping_err++;
+	u64_stats_update_end(&tx_ring->syncp);
+	netdev_warn(adapter->netdev, "failed to map skb\n");
+
+	tx_info->skb = NULL;
+
+error_unmap_dma:
+	if (i >= 0) {
+		/* save value of frag that failed */
+		last_frag = i;
+
+		/* start back at beginning and unmap skb */
+		tx_info->skb = NULL;
+		ena_buf = tx_info->bufs;
+		dma_unmap_single(tx_ring->dev, dma_unmap_addr(ena_buf, paddr),
+				 dma_unmap_len(ena_buf, len), DMA_TO_DEVICE);
+
+		/* unmap remaining mapped pages */
+		for (i = 0; i < last_frag; i++) {
+			ena_buf++;
+			dma_unmap_page(tx_ring->dev, dma_unmap_addr(ena_buf, paddr),
+				       dma_unmap_len(ena_buf, len), DMA_TO_DEVICE);
+		}
+	}
+
+error_drop_packet:
+
+	dev_kfree_skb(skb);
+	return NETDEV_TX_OK;
+}
+
+#ifdef CONFIG_NET_POLL_CONTROLLER
+static void ena_netpoll(struct net_device *netdev)
+{
+	struct ena_adapter *adapter = netdev_priv(netdev);
+	int i;
+
+	for (i = 0; i < adapter->num_queues; i++)
+		napi_schedule(&adapter->ena_napi[i].napi);
+}
+#endif /* CONFIG_NET_POLL_CONTROLLER */
+
+static u16 ena_select_queue(struct net_device *dev, struct sk_buff *skb,
+			    void *accel_priv, select_queue_fallback_t fallback)
+{
+	u16 qid;
+	/* we suspect that this is good for in--kernel network services that
+	 * want to loop incoming skb rx to tx in normal user generated traffic,
+	 * most probably we will not get to this
+	 */
+	if (skb_rx_queue_recorded(skb))
+		qid = skb_get_rx_queue(skb);
+	else
+		qid = fallback(dev, skb);
+
+	return qid;
+}
+
+static void ena_config_host_info(struct ena_com_dev *ena_dev)
+{
+	struct ena_admin_host_info *host_info;
+	int rc;
+
+	/* Allocate only the host info */
+	rc = ena_com_allocate_host_info(ena_dev);
+	if (rc) {
+		pr_err("Cannot allocate host info\n");
+		return;
+	}
+
+	host_info = ena_dev->host_attr.host_info;
+
+	host_info->os_type = ENA_ADMIN_OS_LINUX;
+	host_info->kernel_ver = LINUX_VERSION_CODE;
+	strncpy(host_info->kernel_ver_str, utsname()->version,
+		sizeof(host_info->kernel_ver_str) - 1);
+	host_info->os_dist = 0;
+	strncpy(host_info->os_dist_str, utsname()->release,
+		sizeof(host_info->os_dist_str) - 1);
+	host_info->driver_version =
+		(DRV_MODULE_VER_MAJOR) |
+		(DRV_MODULE_VER_MINOR << ENA_ADMIN_HOST_INFO_MINOR_SHIFT) |
+		(DRV_MODULE_VER_SUBMINOR << ENA_ADMIN_HOST_INFO_SUB_MINOR_SHIFT);
+
+	rc = ena_com_set_host_attributes(ena_dev);
+	if (rc) {
+		if (rc == -EPERM)
+			pr_warn("Cannot set host attributes\n");
+		else
+			pr_err("Cannot set host attributes\n");
+
+		goto err;
+	}
+
+	return;
+
+err:
+	ena_com_delete_host_info(ena_dev);
+}
+
+static void ena_config_debug_area(struct ena_adapter *adapter)
+{
+	u32 debug_area_size;
+	int rc, ss_count;
+
+	ss_count = ena_get_sset_count(adapter->netdev, ETH_SS_STATS);
+	if (ss_count <= 0) {
+		netif_err(adapter, drv, adapter->netdev,
+			  "SS count is negative\n");
+		return;
+	}
+
+	/* allocate 32 bytes for each string and 64bit for the value */
+	debug_area_size = ss_count * ETH_GSTRING_LEN + sizeof(u64) * ss_count;
+
+	rc = ena_com_allocate_debug_area(adapter->ena_dev, debug_area_size);
+	if (rc) {
+		pr_err("Cannot allocate debug area\n");
+		return;
+	}
+
+	rc = ena_com_set_host_attributes(adapter->ena_dev);
+	if (rc) {
+		if (rc == -EPERM)
+			netif_warn(adapter, drv, adapter->netdev,
+				   "Cannot set host attributes\n");
+		else
+			netif_err(adapter, drv, adapter->netdev,
+				  "Cannot set host attributes\n");
+		goto err;
+	}
+
+	return;
+err:
+	ena_com_delete_debug_area(adapter->ena_dev);
+}
+
+static struct rtnl_link_stats64 *ena_get_stats64(struct net_device *netdev,
+						 struct rtnl_link_stats64 *stats)
+{
+	struct ena_adapter *adapter = netdev_priv(netdev);
+	struct ena_admin_basic_stats ena_stats;
+	int rc;
+
+	if (!test_bit(ENA_FLAG_DEV_UP, &adapter->flags))
+		return NULL;
+
+	rc = ena_com_get_dev_basic_stats(adapter->ena_dev, &ena_stats);
+	if (rc)
+		return NULL;
+
+	stats->tx_bytes = ((u64)ena_stats.tx_bytes_high << 32) |
+		ena_stats.tx_bytes_low;
+	stats->rx_bytes = ((u64)ena_stats.rx_bytes_high << 32) |
+		ena_stats.rx_bytes_low;
+
+	stats->rx_packets = ((u64)ena_stats.rx_pkts_high << 32) |
+		ena_stats.rx_pkts_low;
+	stats->tx_packets = ((u64)ena_stats.tx_pkts_high << 32) |
+		ena_stats.tx_pkts_low;
+
+	stats->rx_dropped = ((u64)ena_stats.rx_drops_high << 32) |
+		ena_stats.rx_drops_low;
+
+	stats->multicast = 0;
+	stats->collisions = 0;
+
+	stats->rx_length_errors = 0;
+	stats->rx_crc_errors = 0;
+	stats->rx_frame_errors = 0;
+	stats->rx_fifo_errors = 0;
+	stats->rx_missed_errors = 0;
+	stats->tx_window_errors = 0;
+
+	stats->rx_errors = 0;
+	stats->tx_errors = 0;
+
+	return stats;
+}
+
+static const struct net_device_ops ena_netdev_ops = {
+	.ndo_open		= ena_open,
+	.ndo_stop		= ena_close,
+	.ndo_start_xmit		= ena_start_xmit,
+	.ndo_select_queue	= ena_select_queue,
+	.ndo_get_stats64	= ena_get_stats64,
+	.ndo_tx_timeout		= ena_tx_timeout,
+	.ndo_change_mtu		= ena_change_mtu,
+	.ndo_set_mac_address	= NULL,
+	.ndo_validate_addr	= eth_validate_addr,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+	.ndo_poll_controller	= ena_netpoll,
+#endif /* CONFIG_NET_POLL_CONTROLLER */
+};
+
+static void ena_device_io_suspend(struct work_struct *work)
+{
+	struct ena_adapter *adapter =
+		container_of(work, struct ena_adapter, suspend_io_task);
+	struct net_device *netdev = adapter->netdev;
+
+	/* ena_napi_disable_all disables only the IO handling.
+	 * We are still subject to AENQ keep alive watchdog.
+	 */
+	u64_stats_update_begin(&adapter->syncp);
+	adapter->dev_stats.io_suspend++;
+	u64_stats_update_begin(&adapter->syncp);
+	ena_napi_disable_all(adapter);
+	netif_tx_lock(netdev);
+	netif_device_detach(netdev);
+	netif_tx_unlock(netdev);
+}
+
+static void ena_device_io_resume(struct work_struct *work)
+{
+	struct ena_adapter *adapter =
+		container_of(work, struct ena_adapter, resume_io_task);
+	struct net_device *netdev = adapter->netdev;
+
+	u64_stats_update_begin(&adapter->syncp);
+	adapter->dev_stats.io_resume++;
+	u64_stats_update_end(&adapter->syncp);
+
+	netif_device_attach(netdev);
+	ena_napi_enable_all(adapter);
+}
+
+static int ena_device_validate_params(struct ena_adapter *adapter,
+				      struct ena_com_dev_get_features_ctx *get_feat_ctx)
+{
+	struct net_device *netdev = adapter->netdev;
+	int rc;
+
+	rc = ether_addr_equal(get_feat_ctx->dev_attr.mac_addr,
+			      adapter->mac_addr);
+	if (!rc) {
+		netif_err(adapter, drv, netdev,
+			  "Error, mac address are different\n");
+		return -EINVAL;
+	}
+
+	if ((get_feat_ctx->max_queues.max_cq_num < adapter->num_queues) ||
+	    (get_feat_ctx->max_queues.max_sq_num < adapter->num_queues)) {
+		netif_err(adapter, drv, netdev,
+			  "Error, device doesn't support enough queues\n");
+		return -EINVAL;
+	}
+
+	if (get_feat_ctx->dev_attr.max_mtu < netdev->mtu) {
+		netif_err(adapter, drv, netdev,
+			  "Error, device max mtu is smaller than netdev MTU\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int ena_device_init(struct ena_com_dev *ena_dev, struct pci_dev *pdev,
+			   struct ena_com_dev_get_features_ctx *get_feat_ctx,
+			   bool *wd_state)
+{
+	struct device *dev = &pdev->dev;
+	bool readless_supported;
+	u32 aenq_groups;
+	int dma_width;
+	int rc;
+
+	rc = ena_com_mmio_reg_read_request_init(ena_dev);
+	if (rc) {
+		dev_err(dev, "failed to init mmio read less\n");
+		return rc;
+	}
+
+	/* The PCIe configuration space revision id indicate if mmio reg
+	 * read is disabled
+	 */
+	readless_supported = !(pdev->revision & ENA_MMIO_DISABLE_REG_READ);
+	ena_com_set_mmio_read_mode(ena_dev, readless_supported);
+
+	rc = ena_com_dev_reset(ena_dev);
+	if (rc) {
+		dev_err(dev, "Can not reset device\n");
+		goto err_mmio_read_less;
+	}
+
+	rc = ena_com_validate_version(ena_dev);
+	if (rc) {
+		dev_err(dev, "device version is too low\n");
+		goto err_mmio_read_less;
+	}
+
+	dma_width = ena_com_get_dma_width(ena_dev);
+	if (dma_width < 0) {
+		dev_err(dev, "Invalid dma width value %d", dma_width);
+		goto err_mmio_read_less;
+	}
+
+	rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(dma_width));
+	if (rc) {
+		dev_err(dev, "pci_set_dma_mask failed 0x%x\n", rc);
+		goto err_mmio_read_less;
+	}
+
+	rc = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(dma_width));
+	if (rc) {
+		dev_err(dev, "err_pci_set_consistent_dma_mask failed 0x%x\n",
+			rc);
+		goto err_mmio_read_less;
+	}
+
+	/* ENA admin level init */
+	rc = ena_com_admin_init(ena_dev, &aenq_handlers, true);
+	if (rc) {
+		dev_err(dev,
+			"Can not initialize ena admin queue with device\n");
+		goto err_mmio_read_less;
+	}
+
+	/* To enable the msix interrupts the driver needs to know the number
+	 * of queues. So the driver uses polling mode to retrieve this
+	 * information
+	 */
+	ena_com_set_admin_polling_mode(ena_dev, true);
+
+	/* Get Device Attributes*/
+	rc = ena_com_get_dev_attr_feat(ena_dev, get_feat_ctx);
+	if (rc) {
+		dev_err(dev, "Cannot get attribute for ena device rc=%d\n", rc);
+		goto err_admin_init;
+	}
+
+	/* Try to turn all the available aenq groups */
+	aenq_groups = BIT(ENA_ADMIN_LINK_CHANGE) |
+		BIT(ENA_ADMIN_FATAL_ERROR) |
+		BIT(ENA_ADMIN_WARNING) |
+		BIT(ENA_ADMIN_NOTIFICATION) |
+		BIT(ENA_ADMIN_KEEP_ALIVE);
+
+	aenq_groups &= get_feat_ctx->aenq.supported_groups;
+
+	rc = ena_com_set_aenq_config(ena_dev, aenq_groups);
+	if (rc) {
+		dev_err(dev, "Cannot configure aenq groups rc= %d\n", rc);
+		goto err_admin_init;
+	}
+
+	*wd_state = !!(aenq_groups & BIT(ENA_ADMIN_KEEP_ALIVE));
+
+	ena_config_host_info(ena_dev);
+
+	return 0;
+
+err_admin_init:
+	ena_com_admin_destroy(ena_dev);
+err_mmio_read_less:
+	ena_com_mmio_reg_read_request_destroy(ena_dev);
+
+	return rc;
+}
+
+static int ena_enable_msix_and_set_admin_interrupts(struct ena_adapter *adapter,
+						    int io_vectors)
+{
+	struct ena_com_dev *ena_dev = adapter->ena_dev;
+	struct device *dev = &adapter->pdev->dev;
+	int rc;
+
+	rc = ena_enable_msix(adapter, io_vectors);
+	if (rc) {
+		dev_err(dev, "Can not reserve msix vectors\n");
+		return rc;
+	}
+
+	ena_setup_mgmnt_intr(adapter);
+
+	rc = ena_request_mgmnt_irq(adapter);
+	if (rc) {
+		dev_err(dev, "Can not setup management interrupts\n");
+		goto err_disable_msix;
+	}
+
+	ena_com_set_admin_polling_mode(ena_dev, false);
+
+	ena_com_admin_aenq_enable(ena_dev);
+
+	return 0;
+
+err_disable_msix:
+	ena_disable_msix(adapter);
+
+	return rc;
+}
+
+static void ena_fw_reset_device(struct work_struct *work)
+{
+	struct ena_com_dev_get_features_ctx get_feat_ctx;
+	struct ena_adapter *adapter =
+		container_of(work, struct ena_adapter, reset_task);
+	struct net_device *netdev = adapter->netdev;
+	struct ena_com_dev *ena_dev = adapter->ena_dev;
+	struct pci_dev *pdev = adapter->pdev;
+	bool dev_up, wd_state;
+	int rc;
+
+	del_timer_sync(&adapter->timer_service);
+
+	rtnl_lock();
+
+	dev_up = test_bit(ENA_FLAG_DEV_UP, &adapter->flags);
+	ena_com_set_admin_running_state(ena_dev, false);
+
+	/* After calling ena_close the tx queues and the napi
+	 * are disabled so no one can interfere or touch the
+	 * data structures
+	 */
+	ena_close(netdev);
+
+	rc = ena_com_dev_reset(ena_dev);
+	if (rc) {
+		dev_err(&pdev->dev, "Device reset failed\n");
+		goto err;
+	}
+
+	ena_free_mgmnt_irq(adapter);
+
+	ena_disable_msix(adapter);
+
+	ena_com_abort_admin_commands(ena_dev);
+
+	ena_com_wait_for_abort_completion(ena_dev);
+
+	ena_com_admin_destroy(ena_dev);
+
+	ena_com_mmio_reg_read_request_destroy(ena_dev);
+
+	/* Finish with the destroy part. Start the init part */
+
+	rc = ena_device_init(ena_dev, adapter->pdev, &get_feat_ctx, &wd_state);
+	if (rc) {
+		dev_err(&pdev->dev, "Can not initialize device\n");
+		goto err;
+	}
+	adapter->wd_state = wd_state;
+
+	rc = ena_device_validate_params(adapter, &get_feat_ctx);
+	if (rc) {
+		dev_err(&pdev->dev, "Validation of device parameters failed\n");
+		goto err_device_destroy;
+	}
+
+	rc = ena_enable_msix_and_set_admin_interrupts(adapter,
+						      adapter->num_queues);
+	if (rc) {
+		dev_err(&pdev->dev, "Enable MSI-X failed\n");
+		goto err_device_destroy;
+	}
+	/* If the interface was up before the reset bring it up */
+	if (dev_up) {
+		rc = ena_up(adapter);
+		if (rc) {
+			dev_err(&pdev->dev, "Failed to create I/O queues\n");
+			goto err_disable_msix;
+		}
+	}
+
+	mod_timer(&adapter->timer_service, round_jiffies(jiffies + HZ));
+
+	rtnl_unlock();
+
+	dev_err(&pdev->dev, "Device reset completed successfully\n");
+
+	return;
+err_disable_msix:
+	ena_free_mgmnt_irq(adapter);
+	ena_disable_msix(adapter);
+err_device_destroy:
+	ena_com_admin_destroy(ena_dev);
+err:
+	rtnl_unlock();
+
+	dev_err(&pdev->dev,
+		"Reset attempt failed. Can not reset the device\n");
+}
+
+static void check_for_missing_tx_completions(struct ena_adapter *adapter)
+{
+	struct ena_tx_buffer *tx_buf;
+	unsigned long last_jiffies;
+	struct ena_ring *tx_ring;
+	int i, j, budget;
+	u32 missed_tx;
+
+	/* Make sure the driver doesn't turn the device in other process */
+	smp_rmb();
+
+	if (!test_bit(ENA_FLAG_DEV_UP, &adapter->flags))
+		return;
+
+	budget = ENA_MONITORED_TX_QUEUES;
+
+	for (i = adapter->last_monitored_tx_qid; i < adapter->num_queues; i++) {
+		tx_ring = &adapter->tx_ring[i];
+
+		for (j = 0; j < tx_ring->ring_size; j++) {
+			tx_buf = &tx_ring->tx_buffer_info[j];
+			last_jiffies = tx_buf->last_jiffies;
+			if (unlikely(last_jiffies && time_is_before_jiffies(last_jiffies + TX_TIMEOUT))) {
+				netif_notice(adapter, tx_err, adapter->netdev,
+					     "Found a Tx that wasn't completed on time, qid %d, index %d.\n",
+					     tx_ring->qid, j);
+
+				u64_stats_update_begin(&tx_ring->syncp);
+				missed_tx = tx_ring->tx_stats.missing_tx_comp++;
+				u64_stats_update_end(&tx_ring->syncp);
+
+				/* Clear last jiffies so the lost buffer won't
+				 * be counted twice.
+				 */
+				tx_buf->last_jiffies = 0;
+
+				if (unlikely(missed_tx > MAX_NUM_OF_TIMEOUTED_PACKETS)) {
+					netif_err(adapter, tx_err, adapter->netdev,
+						  "The number of lost tx completion is above the threshold (%d > %d). Reset the device\n",
+						  missed_tx, MAX_NUM_OF_TIMEOUTED_PACKETS);
+					set_bit(ENA_FLAG_TRIGGER_RESET, &adapter->flags);
+				}
+			}
+		}
+
+		budget--;
+		if (!budget)
+			break;
+	}
+
+	adapter->last_monitored_tx_qid = i % adapter->num_queues;
+}
+
+/* Check for keep alive expiration */
+static void check_for_missing_keep_alive(struct ena_adapter *adapter)
+{
+	unsigned long keep_alive_expired;
+
+	if (!adapter->wd_state)
+		return;
+
+	keep_alive_expired = round_jiffies(adapter->last_keep_alive_jiffies
+					   + ENA_DEVICE_KALIVE_TIMEOUT);
+	if (unlikely(time_is_before_jiffies(keep_alive_expired))) {
+		netif_err(adapter, drv, adapter->netdev,
+			  "Keep alive watchdog timeout.\n");
+		u64_stats_update_begin(&adapter->syncp);
+		adapter->dev_stats.wd_expired++;
+		u64_stats_update_end(&adapter->syncp);
+		set_bit(ENA_FLAG_TRIGGER_RESET, &adapter->flags);
+	}
+}
+
+static void check_for_admin_com_state(struct ena_adapter *adapter)
+{
+	if (unlikely(!ena_com_get_admin_running_state(adapter->ena_dev))) {
+		netif_err(adapter, drv, adapter->netdev,
+			  "ENA admin queue is not in running state!\n");
+		u64_stats_update_begin(&adapter->syncp);
+		adapter->dev_stats.admin_q_pause++;
+		u64_stats_update_end(&adapter->syncp);
+		set_bit(ENA_FLAG_TRIGGER_RESET, &adapter->flags);
+	}
+}
+
+static void ena_update_host_info(struct ena_admin_host_info *host_info,
+				 struct net_device *netdev)
+{
+	host_info->supported_network_features[0] =
+		netdev->features & GENMASK_ULL(31, 0);
+	host_info->supported_network_features[1] =
+		(netdev->features & GENMASK_ULL(63, 32)) >> 32;
+}
+
+static void ena_timer_service(unsigned long data)
+{
+	struct ena_adapter *adapter = (struct ena_adapter *)data;
+	u8 *debug_area = adapter->ena_dev->host_attr.debug_area_virt_addr;
+	struct ena_admin_host_info *host_info =
+		adapter->ena_dev->host_attr.host_info;
+
+	check_for_missing_keep_alive(adapter);
+
+	check_for_admin_com_state(adapter);
+
+	check_for_missing_tx_completions(adapter);
+
+	if (debug_area)
+		ena_dump_stats_to_buf(adapter, debug_area);
+
+	if (host_info)
+		ena_update_host_info(host_info, adapter->netdev);
+
+	if (unlikely(test_and_clear_bit(ENA_FLAG_TRIGGER_RESET, &adapter->flags))) {
+		netif_err(adapter, drv, adapter->netdev,
+			  "Trigger reset is on\n");
+		ena_dump_stats_to_dmesg(adapter);
+		queue_work(ena_wq, &adapter->reset_task);
+		return;
+	}
+
+	/* Reset the timer */
+	mod_timer(&adapter->timer_service, jiffies + HZ);
+}
+
+static int ena_calc_io_queue_num(struct pci_dev *pdev,
+				 struct ena_com_dev *ena_dev,
+				 struct ena_com_dev_get_features_ctx *get_feat_ctx)
+{
+	int io_sq_num, io_queue_num;
+
+	/* In case of LLQ use the llq number in the get feature cmd */
+	if (ena_dev->tx_mem_queue_type == ENA_ADMIN_PLACEMENT_POLICY_DEV) {
+		io_sq_num = get_feat_ctx->max_queues.max_llq_num;
+
+		if (io_sq_num == 0) {
+			dev_err(&pdev->dev,
+				"Trying to use LLQ but llq_num is 0. Fall back into regular queues\n");
+
+			ena_dev->tx_mem_queue_type =
+				ENA_ADMIN_PLACEMENT_POLICY_HOST;
+			io_sq_num = get_feat_ctx->max_queues.max_sq_num;
+		}
+	} else {
+		io_sq_num = get_feat_ctx->max_queues.max_sq_num;
+	}
+
+	io_queue_num = min_t(int, num_possible_cpus(), ENA_MAX_NUM_IO_QUEUES);
+	io_queue_num = min_t(int, io_queue_num, io_sq_num);
+	io_queue_num = min_t(int, io_queue_num,
+			     get_feat_ctx->max_queues.max_cq_num);
+	/* 1 IRQ for for mgmnt and 1 IRQs for each IO direction */
+	io_queue_num = min_t(int, io_queue_num, pci_msix_vec_count(pdev) - 1);
+	if (unlikely(!io_queue_num)) {
+		dev_err(&pdev->dev, "The device doesn't have io queues\n");
+		return -EFAULT;
+	}
+
+	return io_queue_num;
+}
+
+static int ena_set_push_mode(struct pci_dev *pdev, struct ena_com_dev *ena_dev,
+			     struct ena_com_dev_get_features_ctx *get_feat_ctx)
+{
+	bool has_mem_bar;
+
+	has_mem_bar = pci_select_bars(pdev, IORESOURCE_MEM) & BIT(ENA_MEM_BAR);
+
+	/* Enable push mode if device supports LLQ */
+	if (has_mem_bar && (get_feat_ctx->max_queues.max_llq_num > 0))
+		ena_dev->tx_mem_queue_type = ENA_ADMIN_PLACEMENT_POLICY_DEV;
+	else
+		ena_dev->tx_mem_queue_type = ENA_ADMIN_PLACEMENT_POLICY_HOST;
+
+	return 0;
+}
+
+static void ena_set_dev_offloads(struct ena_com_dev_get_features_ctx *feat,
+				 struct net_device *netdev)
+{
+	netdev_features_t dev_features = 0;
+
+	/* Set offload features */
+	if (feat->offload.tx &
+		ENA_ADMIN_FEATURE_OFFLOAD_DESC_TX_L4_IPV4_CSUM_PART_MASK)
+		dev_features |= NETIF_F_IP_CSUM;
+
+	if (feat->offload.tx &
+		ENA_ADMIN_FEATURE_OFFLOAD_DESC_TX_L4_IPV6_CSUM_PART_MASK)
+		dev_features |= NETIF_F_IPV6_CSUM;
+
+	if (feat->offload.tx & ENA_ADMIN_FEATURE_OFFLOAD_DESC_TSO_IPV4_MASK)
+		dev_features |= NETIF_F_TSO;
+
+	if (feat->offload.tx & ENA_ADMIN_FEATURE_OFFLOAD_DESC_TSO_IPV6_MASK)
+		dev_features |= NETIF_F_TSO6;
+
+	if (feat->offload.tx & ENA_ADMIN_FEATURE_OFFLOAD_DESC_TSO_ECN_MASK)
+		dev_features |= NETIF_F_TSO_ECN;
+
+	if (feat->offload.rx_supported &
+		ENA_ADMIN_FEATURE_OFFLOAD_DESC_RX_L4_IPV4_CSUM_MASK)
+		dev_features |= NETIF_F_RXCSUM;
+
+	if (feat->offload.rx_supported &
+		ENA_ADMIN_FEATURE_OFFLOAD_DESC_RX_L4_IPV6_CSUM_MASK)
+		dev_features |= NETIF_F_RXCSUM;
+
+	netdev->features =
+		dev_features |
+		NETIF_F_SG |
+		NETIF_F_NTUPLE |
+		NETIF_F_RXHASH |
+		NETIF_F_HIGHDMA;
+
+	netdev->hw_features |= netdev->features;
+	netdev->vlan_features |= netdev->features;
+}
+
+static void ena_set_conf_feat_params(struct ena_adapter *adapter,
+				     struct ena_com_dev_get_features_ctx *feat)
+{
+	struct net_device *netdev = adapter->netdev;
+
+	/* Copy mac address */
+	if (!is_valid_ether_addr(feat->dev_attr.mac_addr)) {
+		eth_hw_addr_random(netdev);
+		ether_addr_copy(adapter->mac_addr, netdev->dev_addr);
+	} else {
+		ether_addr_copy(adapter->mac_addr, feat->dev_attr.mac_addr);
+		ether_addr_copy(netdev->dev_addr, adapter->mac_addr);
+	}
+
+	/* Set offload features */
+	ena_set_dev_offloads(feat, netdev);
+
+	adapter->max_mtu = feat->dev_attr.max_mtu;
+}
+
+static int ena_rss_init_default(struct ena_adapter *adapter)
+{
+	struct ena_com_dev *ena_dev = adapter->ena_dev;
+	struct device *dev = &adapter->pdev->dev;
+	int rc, i;
+	u32 val;
+
+	rc = ena_com_rss_init(ena_dev, ENA_RX_RSS_TABLE_LOG_SIZE);
+	if (unlikely(rc)) {
+		dev_err(dev, "Cannot init indirect table\n");
+		goto err_rss_init;
+	}
+
+	for (i = 0; i < ENA_RX_RSS_TABLE_SIZE; i++) {
+		val = ethtool_rxfh_indir_default(i, adapter->num_queues);
+		rc = ena_com_indirect_table_fill_entry(ena_dev, i,
+						       ENA_IO_RXQ_IDX(val));
+		if (unlikely(rc && (rc != -EPERM))) {
+			dev_err(dev, "Cannot fill indirect table\n");
+			goto err_fill_indir;
+		}
+	}
+
+	rc = ena_com_fill_hash_function(ena_dev, ENA_ADMIN_CRC32, NULL,
+					ENA_HASH_KEY_SIZE, 0xFFFFFFFF);
+	if (unlikely(rc && (rc != -EPERM))) {
+		dev_err(dev, "Cannot fill hash function\n");
+		goto err_fill_indir;
+	}
+
+	rc = ena_com_set_default_hash_ctrl(ena_dev);
+	if (unlikely(rc && (rc != -EPERM))) {
+		dev_err(dev, "Cannot fill hash control\n");
+		goto err_fill_indir;
+	}
+
+	return 0;
+
+err_fill_indir:
+	ena_com_rss_destroy(ena_dev);
+err_rss_init:
+
+	return rc;
+}
+
+static void ena_release_bars(struct ena_com_dev *ena_dev, struct pci_dev *pdev)
+{
+	int release_bars;
+
+	release_bars = pci_select_bars(pdev, IORESOURCE_MEM) & ENA_BAR_MASK;
+	pci_release_selected_regions(pdev, release_bars);
+}
+
+static int ena_calc_queue_size(struct pci_dev *pdev,
+			       struct ena_com_dev *ena_dev,
+			       u16 *max_tx_sgl_size,
+			       u16 *max_rx_sgl_size,
+			       struct ena_com_dev_get_features_ctx *get_feat_ctx)
+{
+	u32 queue_size = ENA_DEFAULT_RING_SIZE;
+
+	queue_size = min_t(u32, queue_size,
+			   get_feat_ctx->max_queues.max_cq_depth);
+	queue_size = min_t(u32, queue_size,
+			   get_feat_ctx->max_queues.max_sq_depth);
+
+	if (ena_dev->tx_mem_queue_type == ENA_ADMIN_PLACEMENT_POLICY_DEV)
+		queue_size = min_t(u32, queue_size,
+				   get_feat_ctx->max_queues.max_llq_depth);
+
+	queue_size = rounddown_pow_of_two(queue_size);
+
+	if (unlikely(!queue_size)) {
+		dev_err(&pdev->dev, "Invalid queue size\n");
+		return -EFAULT;
+	}
+
+	*max_tx_sgl_size = min_t(u16, ENA_PKT_MAX_BUFS,
+				 get_feat_ctx->max_queues.max_packet_tx_descs);
+	*max_rx_sgl_size = min_t(u16, ENA_PKT_MAX_BUFS,
+				 get_feat_ctx->max_queues.max_packet_rx_descs);
+
+	return queue_size;
+}
+
+/* ena_probe - Device Initialization Routine
+ * @pdev: PCI device information struct
+ * @ent: entry in ena_pci_tbl
+ *
+ * Returns 0 on success, negative on failure
+ *
+ * ena_probe initializes an adapter identified by a pci_dev structure.
+ * The OS initialization, configuring of the adapter private structure,
+ * and a hardware reset occur.
+ */
+static int ena_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+{
+	struct ena_com_dev_get_features_ctx get_feat_ctx;
+	static int version_printed;
+	struct net_device *netdev;
+	struct ena_adapter *adapter;
+	struct ena_com_dev *ena_dev = NULL;
+	static int adapters_found;
+	int io_queue_num, bars, rc;
+	int queue_size;
+	u16 tx_sgl_size = 0;
+	u16 rx_sgl_size = 0;
+	bool wd_state;
+
+	dev_dbg(&pdev->dev, "%s\n", __func__);
+
+	if (version_printed++ == 0)
+		dev_info(&pdev->dev, "%s", version);
+
+	rc = pci_enable_device_mem(pdev);
+	if (rc) {
+		dev_err(&pdev->dev, "pci_enable_device_mem() failed!\n");
+		return rc;
+	}
+
+	pci_set_master(pdev);
+
+	ena_dev = vzalloc(sizeof(*ena_dev));
+	if (!ena_dev) {
+		rc = -ENOMEM;
+		goto err_disable_device;
+	}
+
+	bars = pci_select_bars(pdev, IORESOURCE_MEM) & ENA_BAR_MASK;
+	rc = pci_request_selected_regions(pdev, bars, DRV_MODULE_NAME);
+	if (rc) {
+		dev_err(&pdev->dev, "pci_request_selected_regions failed %d\n",
+			rc);
+		goto err_free_ena_dev;
+	}
+
+	ena_dev->reg_bar = ioremap(pci_resource_start(pdev, ENA_REG_BAR),
+				   pci_resource_len(pdev, ENA_REG_BAR));
+	if (!ena_dev->reg_bar) {
+		dev_err(&pdev->dev, "failed to remap regs bar\n");
+		rc = -EFAULT;
+		goto err_free_region;
+	}
+
+	ena_dev->dmadev = &pdev->dev;
+
+	rc = ena_device_init(ena_dev, pdev, &get_feat_ctx, &wd_state);
+	if (rc) {
+		dev_err(&pdev->dev, "ena device init failed\n");
+		if (rc == -ETIME)
+			rc = -EPROBE_DEFER;
+		goto err_free_region;
+	}
+
+	rc = ena_set_push_mode(pdev, ena_dev, &get_feat_ctx);
+	if (rc) {
+		dev_err(&pdev->dev, "Invalid module param(push_mode)\n");
+		goto err_device_destroy;
+	}
+
+	if (ena_dev->tx_mem_queue_type == ENA_ADMIN_PLACEMENT_POLICY_DEV) {
+		ena_dev->mem_bar = ioremap_wc(pci_resource_start(pdev, ENA_MEM_BAR),
+					      pci_resource_len(pdev, ENA_MEM_BAR));
+		if (!ena_dev->mem_bar) {
+			rc = -EFAULT;
+			goto err_device_destroy;
+		}
+	}
+
+	/* initial Tx interrupt delay, Assumes 1 usec granularity.
+	* Updated during device initialization with the real granularity
+	*/
+	ena_dev->intr_moder_tx_interval = ENA_INTR_INITIAL_TX_INTERVAL_USECS;
+	io_queue_num = ena_calc_io_queue_num(pdev, ena_dev, &get_feat_ctx);
+	queue_size = ena_calc_queue_size(pdev, ena_dev, &tx_sgl_size,
+					 &rx_sgl_size, &get_feat_ctx);
+	if ((queue_size <= 0) || (io_queue_num <= 0)) {
+		rc = -EFAULT;
+		goto err_device_destroy;
+	}
+
+	dev_info(&pdev->dev, "creating %d io queues. queue size: %d\n",
+		 io_queue_num, queue_size);
+
+	/* dev zeroed in init_etherdev */
+	netdev = alloc_etherdev_mq(sizeof(struct ena_adapter), io_queue_num);
+	if (!netdev) {
+		dev_err(&pdev->dev, "alloc_etherdev_mq failed\n");
+		rc = -ENOMEM;
+		goto err_device_destroy;
+	}
+
+	SET_NETDEV_DEV(netdev, &pdev->dev);
+
+	adapter = netdev_priv(netdev);
+	pci_set_drvdata(pdev, adapter);
+
+	adapter->ena_dev = ena_dev;
+	adapter->netdev = netdev;
+	adapter->pdev = pdev;
+
+	ena_set_conf_feat_params(adapter, &get_feat_ctx);
+
+	adapter->msg_enable = netif_msg_init(debug, DEFAULT_MSG_ENABLE);
+
+	adapter->tx_ring_size = queue_size;
+	adapter->rx_ring_size = queue_size;
+
+	adapter->max_tx_sgl_size = tx_sgl_size;
+	adapter->max_rx_sgl_size = rx_sgl_size;
+
+	adapter->num_queues = io_queue_num;
+	adapter->last_monitored_tx_qid = 0;
+
+	adapter->rx_copybreak = ENA_DEFAULT_RX_COPYBREAK;
+	adapter->wd_state = wd_state;
+
+	snprintf(adapter->name, ENA_NAME_MAX_LEN, "ena_%d", adapters_found);
+
+	rc = ena_com_init_interrupt_moderation(adapter->ena_dev);
+	if (rc) {
+		dev_err(&pdev->dev,
+			"Failed to query interrupt moderation feature\n");
+		goto err_netdev_destroy;
+	}
+	ena_init_io_rings(adapter);
+
+	netdev->netdev_ops = &ena_netdev_ops;
+	netdev->watchdog_timeo = TX_TIMEOUT;
+	ena_set_ethtool_ops(netdev);
+
+	netdev->priv_flags |= IFF_UNICAST_FLT;
+
+	u64_stats_init(&adapter->syncp);
+
+	rc = ena_enable_msix_and_set_admin_interrupts(adapter, io_queue_num);
+	if (rc) {
+		dev_err(&pdev->dev,
+			"Failed to enable and set the admin interrupts\n");
+		goto err_worker_destroy;
+	}
+	rc = ena_rss_init_default(adapter);
+	if (rc && (rc != -EPERM)) {
+		dev_err(&pdev->dev, "Cannot init RSS rc: %d\n", rc);
+		goto err_free_msix;
+	}
+
+	ena_config_debug_area(adapter);
+
+	memcpy(adapter->netdev->perm_addr, adapter->mac_addr, netdev->addr_len);
+
+	netif_carrier_off(netdev);
+
+	rc = register_netdev(netdev);
+	if (rc) {
+		dev_err(&pdev->dev, "Cannot register net device\n");
+		goto err_rss;
+	}
+
+	INIT_WORK(&adapter->suspend_io_task, ena_device_io_suspend);
+	INIT_WORK(&adapter->resume_io_task, ena_device_io_resume);
+	INIT_WORK(&adapter->reset_task, ena_fw_reset_device);
+
+	adapter->last_keep_alive_jiffies = jiffies;
+
+	init_timer(&adapter->timer_service);
+	adapter->timer_service.expires = round_jiffies(jiffies + HZ);
+	adapter->timer_service.function = ena_timer_service;
+	adapter->timer_service.data = (unsigned long)adapter;
+
+	add_timer(&adapter->timer_service);
+
+	dev_info(&pdev->dev, "%s found at mem %lx, mac addr %pM Queues %d\n",
+		 DEVICE_NAME, (long)pci_resource_start(pdev, 0),
+		 netdev->dev_addr, io_queue_num);
+
+	set_bit(ENA_FLAG_DEVICE_RUNNING, &adapter->flags);
+
+	adapters_found++;
+
+	return 0;
+
+err_rss:
+	ena_com_delete_debug_area(ena_dev);
+	ena_com_rss_destroy(ena_dev);
+err_free_msix:
+	ena_com_dev_reset(ena_dev);
+	ena_free_mgmnt_irq(adapter);
+	ena_disable_msix(adapter);
+err_worker_destroy:
+	ena_com_destroy_interrupt_moderation(ena_dev);
+	del_timer(&adapter->timer_service);
+	cancel_work_sync(&adapter->suspend_io_task);
+	cancel_work_sync(&adapter->resume_io_task);
+err_netdev_destroy:
+	free_netdev(netdev);
+err_device_destroy:
+	ena_com_delete_host_info(ena_dev);
+	ena_com_admin_destroy(ena_dev);
+err_free_region:
+	ena_release_bars(ena_dev, pdev);
+err_free_ena_dev:
+	pci_set_drvdata(pdev, NULL);
+	vfree(ena_dev);
+err_disable_device:
+	pci_disable_device(pdev);
+	return rc;
+}
+
+/*****************************************************************************/
+static int ena_sriov_configure(struct pci_dev *dev, int numvfs)
+{
+	int rc;
+
+	if (numvfs > 0) {
+		rc = pci_enable_sriov(dev, numvfs);
+		if (rc != 0) {
+			dev_err(&dev->dev,
+				"pci_enable_sriov failed to enable: %d vfs with the error: %d\n",
+				numvfs, rc);
+			return rc;
+		}
+
+		return numvfs;
+	}
+
+	if (numvfs == 0) {
+		pci_disable_sriov(dev);
+		return 0;
+	}
+
+	return -EINVAL;
+}
+
+/*****************************************************************************/
+/*****************************************************************************/
+
+/* ena_remove - Device Removal Routine
+ * @pdev: PCI device information struct
+ *
+ * ena_remove is called by the PCI subsystem to alert the driver
+ * that it should release a PCI device.
+ */
+static void ena_remove(struct pci_dev *pdev)
+{
+	struct ena_adapter *adapter = pci_get_drvdata(pdev);
+	struct ena_com_dev *ena_dev;
+	struct net_device *netdev;
+
+	if (!adapter)
+		/* This device didn't load properly and it's resources
+		 * already released, nothing to do
+		 */
+		return;
+
+	ena_dev = adapter->ena_dev;
+	netdev = adapter->netdev;
+
+#ifdef CONFIG_RFS_ACCEL
+	if ((adapter->msix_vecs >= 1) && (netdev->rx_cpu_rmap)) {
+		free_irq_cpu_rmap(netdev->rx_cpu_rmap);
+		netdev->rx_cpu_rmap = NULL;
+	}
+#endif /* CONFIG_RFS_ACCEL */
+
+	unregister_netdev(netdev);
+	del_timer_sync(&adapter->timer_service);
+
+	cancel_work_sync(&adapter->reset_task);
+
+	cancel_work_sync(&adapter->suspend_io_task);
+
+	cancel_work_sync(&adapter->resume_io_task);
+
+	ena_com_dev_reset(ena_dev);
+
+	ena_free_mgmnt_irq(adapter);
+
+	ena_disable_msix(adapter);
+
+	free_netdev(netdev);
+
+	ena_com_mmio_reg_read_request_destroy(ena_dev);
+
+	ena_com_abort_admin_commands(ena_dev);
+
+	ena_com_wait_for_abort_completion(ena_dev);
+
+	ena_com_admin_destroy(ena_dev);
+
+	ena_com_rss_destroy(ena_dev);
+
+	ena_com_delete_debug_area(ena_dev);
+
+	ena_com_delete_host_info(ena_dev);
+
+	ena_release_bars(ena_dev, pdev);
+
+	pci_set_drvdata(pdev, NULL);
+
+	pci_disable_device(pdev);
+
+	ena_com_destroy_interrupt_moderation(ena_dev);
+
+	vfree(ena_dev);
+}
+
+static struct pci_driver ena_pci_driver = {
+	.name		= DRV_MODULE_NAME,
+	.id_table	= ena_pci_tbl,
+	.probe		= ena_probe,
+	.remove		= ena_remove,
+	.sriov_configure = ena_sriov_configure,
+};
+
+static int __init ena_init(void)
+{
+	pr_info("%s", version);
+
+	ena_wq = create_singlethread_workqueue(DRV_MODULE_NAME);
+	if (!ena_wq) {
+		pr_err("Failed to create workqueue\n");
+		return -ENOMEM;
+	}
+
+	return pci_register_driver(&ena_pci_driver);
+}
+
+static void __exit ena_cleanup(void)
+{
+	pci_unregister_driver(&ena_pci_driver);
+
+	if (ena_wq) {
+		destroy_workqueue(ena_wq);
+		ena_wq = NULL;
+	}
+}
+
+/******************************************************************************
+ ******************************** AENQ Handlers *******************************
+ *****************************************************************************/
+/* ena_update_on_link_change:
+ * Notify the network interface about the change in link status
+ */
+static void ena_update_on_link_change(void *adapter_data,
+				      struct ena_admin_aenq_entry *aenq_e)
+{
+	struct ena_adapter *adapter = (struct ena_adapter *)adapter_data;
+	struct ena_admin_aenq_link_change_desc *aenq_desc =
+		(struct ena_admin_aenq_link_change_desc *)aenq_e;
+	int status = aenq_desc->flags &
+		ENA_ADMIN_AENQ_LINK_CHANGE_DESC_LINK_STATUS_MASK;
+
+	if (status) {
+		netdev_dbg(adapter->netdev, "%s\n", __func__);
+		set_bit(ENA_FLAG_LINK_UP, &adapter->flags);
+		netif_carrier_on(adapter->netdev);
+	} else {
+		clear_bit(ENA_FLAG_LINK_UP, &adapter->flags);
+		netif_carrier_off(adapter->netdev);
+	}
+}
+
+static void ena_keep_alive_wd(void *adapter_data,
+			      struct ena_admin_aenq_entry *aenq_e)
+{
+	struct ena_adapter *adapter = (struct ena_adapter *)adapter_data;
+
+	adapter->last_keep_alive_jiffies = jiffies;
+}
+
+static void ena_notification(void *adapter_data,
+			     struct ena_admin_aenq_entry *aenq_e)
+{
+	struct ena_adapter *adapter = (struct ena_adapter *)adapter_data;
+
+	WARN(aenq_e->aenq_common_desc.group != ENA_ADMIN_NOTIFICATION,
+	     "Invalid group(%x) expected %x\n",
+	     aenq_e->aenq_common_desc.group,
+	     ENA_ADMIN_NOTIFICATION);
+
+	switch (aenq_e->aenq_common_desc.syndrom) {
+	case ENA_ADMIN_SUSPEND:
+		/* Suspend just the IO queues.
+		 * We deliberately don't suspend admin so the timer and
+		 * the keep_alive events should remain.
+		 */
+		queue_work(ena_wq, &adapter->suspend_io_task);
+		break;
+	case ENA_ADMIN_RESUME:
+		queue_work(ena_wq, &adapter->resume_io_task);
+		break;
+	default:
+		netif_err(adapter, drv, adapter->netdev,
+			  "Invalid aenq notification link state %d\n",
+			  aenq_e->aenq_common_desc.syndrom);
+	}
+}
+
+/* This handler will called for unknown event group or unimplemented handlers*/
+static void unimplemented_aenq_handler(void *data,
+				       struct ena_admin_aenq_entry *aenq_e)
+{
+	struct ena_adapter *adapter = (struct ena_adapter *)data;
+
+	netif_err(adapter, drv, adapter->netdev,
+		  "Unknown event was received or event with unimplemented handler\n");
+}
+
+static struct ena_aenq_handlers aenq_handlers = {
+	.handlers = {
+		[ENA_ADMIN_LINK_CHANGE] = ena_update_on_link_change,
+		[ENA_ADMIN_NOTIFICATION] = ena_notification,
+		[ENA_ADMIN_KEEP_ALIVE] = ena_keep_alive_wd,
+	},
+	.unimplemented_handler = unimplemented_aenq_handler
+};
+
+module_init(ena_init);
+module_exit(ena_cleanup);
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/amazon/ena/ena_netdev.h
@@ -0,0 +1,324 @@
+/*
+ * Copyright 2015 Amazon.com, Inc. or its affiliates.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef ENA_H
+#define ENA_H
+
+#include <linux/bitops.h>
+#include <linux/etherdevice.h>
+#include <linux/inetdevice.h>
+#include <linux/interrupt.h>
+#include <linux/netdevice.h>
+#include <linux/skbuff.h>
+
+#include "ena_com.h"
+#include "ena_eth_com.h"
+
+#define DRV_MODULE_VER_MAJOR	1
+#define DRV_MODULE_VER_MINOR	0
+#define DRV_MODULE_VER_SUBMINOR 2
+
+#define DRV_MODULE_NAME		"ena"
+#ifndef DRV_MODULE_VERSION
+#define DRV_MODULE_VERSION \
+	__stringify(DRV_MODULE_VER_MAJOR) "."	\
+	__stringify(DRV_MODULE_VER_MINOR) "."	\
+	__stringify(DRV_MODULE_VER_SUBMINOR)
+#endif
+
+#define DEVICE_NAME	"Elastic Network Adapter (ENA)"
+
+/* 1 for AENQ + ADMIN */
+#define ENA_MAX_MSIX_VEC(io_queues)	(1 + (io_queues))
+
+#define ENA_REG_BAR			0
+#define ENA_MEM_BAR			2
+#define ENA_BAR_MASK (BIT(ENA_REG_BAR) | BIT(ENA_MEM_BAR))
+
+#define ENA_DEFAULT_RING_SIZE	(1024)
+
+#define ENA_TX_WAKEUP_THRESH		(MAX_SKB_FRAGS + 2)
+#define ENA_DEFAULT_RX_COPYBREAK	(128 - NET_IP_ALIGN)
+
+/* limit the buffer size to 600 bytes to handle MTU changes from very
+ * small to very large, in which case the number of buffers per packet
+ * could exceed ENA_PKT_MAX_BUFS
+ */
+#define ENA_DEFAULT_MIN_RX_BUFF_ALLOC_SIZE 600
+
+#define ENA_MIN_MTU		128
+
+#define ENA_NAME_MAX_LEN	20
+#define ENA_IRQNAME_SIZE	40
+
+#define ENA_PKT_MAX_BUFS	19
+
+#define ENA_RX_RSS_TABLE_LOG_SIZE  7
+#define ENA_RX_RSS_TABLE_SIZE	(1 << ENA_RX_RSS_TABLE_LOG_SIZE)
+
+#define ENA_HASH_KEY_SIZE	40
+
+/* The number of tx packet completions that will be handled each NAPI poll
+ * cycle is ring_size / ENA_TX_POLL_BUDGET_DIVIDER.
+ */
+#define ENA_TX_POLL_BUDGET_DIVIDER	4
+
+/* Refill Rx queue when number of available descriptors is below
+ * QUEUE_SIZE / ENA_RX_REFILL_THRESH_DIVIDER
+ */
+#define ENA_RX_REFILL_THRESH_DIVIDER	8
+
+/* Number of queues to check for missing queues per timer service */
+#define ENA_MONITORED_TX_QUEUES	4
+/* Max timeout packets before device reset */
+#define MAX_NUM_OF_TIMEOUTED_PACKETS 32
+
+#define ENA_TX_RING_IDX_NEXT(idx, ring_size) (((idx) + 1) & ((ring_size) - 1))
+
+#define ENA_RX_RING_IDX_NEXT(idx, ring_size) (((idx) + 1) & ((ring_size) - 1))
+#define ENA_RX_RING_IDX_ADD(idx, n, ring_size) \
+	(((idx) + (n)) & ((ring_size) - 1))
+
+#define ENA_IO_TXQ_IDX(q)	(2 * (q))
+#define ENA_IO_RXQ_IDX(q)	(2 * (q) + 1)
+
+#define ENA_MGMNT_IRQ_IDX		0
+#define ENA_IO_IRQ_FIRST_IDX		1
+#define ENA_IO_IRQ_IDX(q)		(ENA_IO_IRQ_FIRST_IDX + (q))
+
+/* ENA device should send keep alive msg every 1 sec.
+ * We wait for 3 sec just to be on the safe side.
+ */
+#define ENA_DEVICE_KALIVE_TIMEOUT	(3 * HZ)
+
+#define ENA_MMIO_DISABLE_REG_READ	BIT(0)
+
+struct ena_irq {
+	irq_handler_t handler;
+	void *data;
+	int cpu;
+	u32 vector;
+	cpumask_t affinity_hint_mask;
+	char name[ENA_IRQNAME_SIZE];
+};
+
+struct ena_napi {
+	struct napi_struct napi ____cacheline_aligned;
+	struct ena_ring *tx_ring;
+	struct ena_ring *rx_ring;
+	u32 qid;
+};
+
+struct ena_tx_buffer {
+	struct sk_buff *skb;
+	/* num of ena desc for this specific skb
+	 * (includes data desc and metadata desc)
+	 */
+	u32 tx_descs;
+	/* num of buffers used by this skb */
+	u32 num_of_bufs;
+	/* Save the last jiffies to detect missing tx packets */
+	unsigned long last_jiffies;
+	struct ena_com_buf bufs[ENA_PKT_MAX_BUFS];
+} ____cacheline_aligned;
+
+struct ena_rx_buffer {
+	struct sk_buff *skb;
+	struct page *page;
+	u32 page_offset;
+	struct ena_com_buf ena_buf;
+} ____cacheline_aligned;
+
+struct ena_stats_tx {
+	u64 cnt;
+	u64 bytes;
+	u64 queue_stop;
+	u64 prepare_ctx_err;
+	u64 queue_wakeup;
+	u64 dma_mapping_err;
+	u64 linearize;
+	u64 linearize_failed;
+	u64 napi_comp;
+	u64 tx_poll;
+	u64 doorbells;
+	u64 missing_tx_comp;
+	u64 bad_req_id;
+};
+
+struct ena_stats_rx {
+	u64 cnt;
+	u64 bytes;
+	u64 refil_partial;
+	u64 bad_csum;
+	u64 page_alloc_fail;
+	u64 skb_alloc_fail;
+	u64 dma_mapping_err;
+	u64 bad_desc_num;
+	u64 rx_copybreak_pkt;
+};
+
+struct ena_ring {
+	/* Holds the empty requests for TX out of order completions */
+	u16 *free_tx_ids;
+	union {
+		struct ena_tx_buffer *tx_buffer_info;
+		struct ena_rx_buffer *rx_buffer_info;
+	};
+
+	/* cache ptr to avoid using the adapter */
+	struct device *dev;
+	struct pci_dev *pdev;
+	struct napi_struct *napi;
+	struct net_device *netdev;
+	struct ena_com_dev *ena_dev;
+	struct ena_adapter *adapter;
+	struct ena_com_io_cq *ena_com_io_cq;
+	struct ena_com_io_sq *ena_com_io_sq;
+
+	u16 next_to_use;
+	u16 next_to_clean;
+	u16 rx_copybreak;
+	u16 qid;
+	u16 mtu;
+	u16 sgl_size;
+
+	/* The maximum header length the device can handle */
+	u8 tx_max_header_size;
+
+	/* cpu for TPH */
+	int cpu;
+	 /* number of tx/rx_buffer_info's entries */
+	int ring_size;
+
+	enum ena_admin_placement_policy_type tx_mem_queue_type;
+
+	struct ena_com_rx_buf_info ena_bufs[ENA_PKT_MAX_BUFS];
+	u32  smoothed_interval;
+	u32  per_napi_packets;
+	u32  per_napi_bytes;
+	enum ena_intr_moder_level moder_tbl_idx;
+	struct u64_stats_sync syncp;
+	union {
+		struct ena_stats_tx tx_stats;
+		struct ena_stats_rx rx_stats;
+	};
+} ____cacheline_aligned;
+
+struct ena_stats_dev {
+	u64 tx_timeout;
+	u64 io_suspend;
+	u64 io_resume;
+	u64 wd_expired;
+	u64 interface_up;
+	u64 interface_down;
+	u64 admin_q_pause;
+};
+
+enum ena_flags_t {
+	ENA_FLAG_DEVICE_RUNNING,
+	ENA_FLAG_DEV_UP,
+	ENA_FLAG_LINK_UP,
+	ENA_FLAG_MSIX_ENABLED,
+	ENA_FLAG_TRIGGER_RESET
+};
+
+/* adapter specific private data structure */
+struct ena_adapter {
+	struct ena_com_dev *ena_dev;
+	/* OS defined structs */
+	struct net_device *netdev;
+	struct pci_dev *pdev;
+
+	/* rx packets that shorter that this len will be copied to the skb
+	 * header
+	 */
+	u32 rx_copybreak;
+	u32 max_mtu;
+
+	int num_queues;
+
+	struct msix_entry *msix_entries;
+	int msix_vecs;
+
+	u32 tx_usecs, rx_usecs; /* interrupt moderation */
+	u32 tx_frames, rx_frames; /* interrupt moderation */
+
+	u32 tx_ring_size;
+	u32 rx_ring_size;
+
+	u32 msg_enable;
+
+	u16 max_tx_sgl_size;
+	u16 max_rx_sgl_size;
+
+	u8 mac_addr[ETH_ALEN];
+
+	char name[ENA_NAME_MAX_LEN];
+
+	unsigned long flags;
+	/* TX */
+	struct ena_ring tx_ring[ENA_MAX_NUM_IO_QUEUES]
+		____cacheline_aligned_in_smp;
+
+	/* RX */
+	struct ena_ring rx_ring[ENA_MAX_NUM_IO_QUEUES]
+		____cacheline_aligned_in_smp;
+
+	struct ena_napi ena_napi[ENA_MAX_NUM_IO_QUEUES];
+
+	struct ena_irq irq_tbl[ENA_MAX_MSIX_VEC(ENA_MAX_NUM_IO_QUEUES)];
+
+	/* timer service */
+	struct work_struct reset_task;
+	struct work_struct suspend_io_task;
+	struct work_struct resume_io_task;
+	struct timer_list timer_service;
+
+	bool wd_state;
+	unsigned long last_keep_alive_jiffies;
+
+	struct u64_stats_sync syncp;
+	struct ena_stats_dev dev_stats;
+
+	/* last queue index that was checked for uncompleted tx packets */
+	u32 last_monitored_tx_qid;
+};
+
+void ena_set_ethtool_ops(struct net_device *netdev);
+
+void ena_dump_stats_to_dmesg(struct ena_adapter *adapter);
+
+void ena_dump_stats_to_buf(struct ena_adapter *adapter, u8 *buf);
+
+int ena_get_sset_count(struct net_device *netdev, int sset);
+
+#endif /* !(ENA_H) */
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/amazon/ena/ena_pci_id_tbl.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2015 Amazon.com, Inc. or its affiliates.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef ENA_PCI_ID_TBL_H_
+#define ENA_PCI_ID_TBL_H_
+
+#ifndef PCI_VENDOR_ID_AMAZON
+#define PCI_VENDOR_ID_AMAZON 0x1d0f
+#endif
+
+#ifndef PCI_DEV_ID_ENA_PF
+#define PCI_DEV_ID_ENA_PF	0x0ec2
+#endif
+
+#ifndef PCI_DEV_ID_ENA_LLQ_PF
+#define PCI_DEV_ID_ENA_LLQ_PF	0x1ec2
+#endif
+
+#ifndef PCI_DEV_ID_ENA_VF
+#define PCI_DEV_ID_ENA_VF	0xec20
+#endif
+
+#ifndef PCI_DEV_ID_ENA_LLQ_VF
+#define PCI_DEV_ID_ENA_LLQ_VF	0xec21
+#endif
+
+#define ENA_PCI_ID_TABLE_ENTRY(devid) \
+	{PCI_DEVICE(PCI_VENDOR_ID_AMAZON, devid)},
+
+static const struct pci_device_id ena_pci_tbl[] = {
+	ENA_PCI_ID_TABLE_ENTRY(PCI_DEV_ID_ENA_PF)
+	ENA_PCI_ID_TABLE_ENTRY(PCI_DEV_ID_ENA_LLQ_PF)
+	ENA_PCI_ID_TABLE_ENTRY(PCI_DEV_ID_ENA_VF)
+	ENA_PCI_ID_TABLE_ENTRY(PCI_DEV_ID_ENA_LLQ_VF)
+	{ }
+};
+
+#endif /* ENA_PCI_ID_TBL_H_ */
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/amazon/ena/ena_regs_defs.h
@@ -0,0 +1,133 @@
+/*
+ * Copyright 2015 - 2016 Amazon.com, Inc. or its affiliates.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+#ifndef _ENA_REGS_H_
+#define _ENA_REGS_H_
+
+/* ena_registers offsets */
+#define ENA_REGS_VERSION_OFF		0x0
+#define ENA_REGS_CONTROLLER_VERSION_OFF		0x4
+#define ENA_REGS_CAPS_OFF		0x8
+#define ENA_REGS_CAPS_EXT_OFF		0xc
+#define ENA_REGS_AQ_BASE_LO_OFF		0x10
+#define ENA_REGS_AQ_BASE_HI_OFF		0x14
+#define ENA_REGS_AQ_CAPS_OFF		0x18
+#define ENA_REGS_ACQ_BASE_LO_OFF		0x20
+#define ENA_REGS_ACQ_BASE_HI_OFF		0x24
+#define ENA_REGS_ACQ_CAPS_OFF		0x28
+#define ENA_REGS_AQ_DB_OFF		0x2c
+#define ENA_REGS_ACQ_TAIL_OFF		0x30
+#define ENA_REGS_AENQ_CAPS_OFF		0x34
+#define ENA_REGS_AENQ_BASE_LO_OFF		0x38
+#define ENA_REGS_AENQ_BASE_HI_OFF		0x3c
+#define ENA_REGS_AENQ_HEAD_DB_OFF		0x40
+#define ENA_REGS_AENQ_TAIL_OFF		0x44
+#define ENA_REGS_INTR_MASK_OFF		0x4c
+#define ENA_REGS_DEV_CTL_OFF		0x54
+#define ENA_REGS_DEV_STS_OFF		0x58
+#define ENA_REGS_MMIO_REG_READ_OFF		0x5c
+#define ENA_REGS_MMIO_RESP_LO_OFF		0x60
+#define ENA_REGS_MMIO_RESP_HI_OFF		0x64
+#define ENA_REGS_RSS_IND_ENTRY_UPDATE_OFF		0x68
+
+/* version register */
+#define ENA_REGS_VERSION_MINOR_VERSION_MASK		0xff
+#define ENA_REGS_VERSION_MAJOR_VERSION_SHIFT		8
+#define ENA_REGS_VERSION_MAJOR_VERSION_MASK		0xff00
+
+/* controller_version register */
+#define ENA_REGS_CONTROLLER_VERSION_SUBMINOR_VERSION_MASK		0xff
+#define ENA_REGS_CONTROLLER_VERSION_MINOR_VERSION_SHIFT		8
+#define ENA_REGS_CONTROLLER_VERSION_MINOR_VERSION_MASK		0xff00
+#define ENA_REGS_CONTROLLER_VERSION_MAJOR_VERSION_SHIFT		16
+#define ENA_REGS_CONTROLLER_VERSION_MAJOR_VERSION_MASK		0xff0000
+#define ENA_REGS_CONTROLLER_VERSION_IMPL_ID_SHIFT		24
+#define ENA_REGS_CONTROLLER_VERSION_IMPL_ID_MASK		0xff000000
+
+/* caps register */
+#define ENA_REGS_CAPS_CONTIGUOUS_QUEUE_REQUIRED_MASK		0x1
+#define ENA_REGS_CAPS_RESET_TIMEOUT_SHIFT		1
+#define ENA_REGS_CAPS_RESET_TIMEOUT_MASK		0x3e
+#define ENA_REGS_CAPS_DMA_ADDR_WIDTH_SHIFT		8
+#define ENA_REGS_CAPS_DMA_ADDR_WIDTH_MASK		0xff00
+
+/* aq_caps register */
+#define ENA_REGS_AQ_CAPS_AQ_DEPTH_MASK		0xffff
+#define ENA_REGS_AQ_CAPS_AQ_ENTRY_SIZE_SHIFT		16
+#define ENA_REGS_AQ_CAPS_AQ_ENTRY_SIZE_MASK		0xffff0000
+
+/* acq_caps register */
+#define ENA_REGS_ACQ_CAPS_ACQ_DEPTH_MASK		0xffff
+#define ENA_REGS_ACQ_CAPS_ACQ_ENTRY_SIZE_SHIFT		16
+#define ENA_REGS_ACQ_CAPS_ACQ_ENTRY_SIZE_MASK		0xffff0000
+
+/* aenq_caps register */
+#define ENA_REGS_AENQ_CAPS_AENQ_DEPTH_MASK		0xffff
+#define ENA_REGS_AENQ_CAPS_AENQ_ENTRY_SIZE_SHIFT		16
+#define ENA_REGS_AENQ_CAPS_AENQ_ENTRY_SIZE_MASK		0xffff0000
+
+/* dev_ctl register */
+#define ENA_REGS_DEV_CTL_DEV_RESET_MASK		0x1
+#define ENA_REGS_DEV_CTL_AQ_RESTART_SHIFT		1
+#define ENA_REGS_DEV_CTL_AQ_RESTART_MASK		0x2
+#define ENA_REGS_DEV_CTL_QUIESCENT_SHIFT		2
+#define ENA_REGS_DEV_CTL_QUIESCENT_MASK		0x4
+#define ENA_REGS_DEV_CTL_IO_RESUME_SHIFT		3
+#define ENA_REGS_DEV_CTL_IO_RESUME_MASK		0x8
+
+/* dev_sts register */
+#define ENA_REGS_DEV_STS_READY_MASK		0x1
+#define ENA_REGS_DEV_STS_AQ_RESTART_IN_PROGRESS_SHIFT		1
+#define ENA_REGS_DEV_STS_AQ_RESTART_IN_PROGRESS_MASK		0x2
+#define ENA_REGS_DEV_STS_AQ_RESTART_FINISHED_SHIFT		2
+#define ENA_REGS_DEV_STS_AQ_RESTART_FINISHED_MASK		0x4
+#define ENA_REGS_DEV_STS_RESET_IN_PROGRESS_SHIFT		3
+#define ENA_REGS_DEV_STS_RESET_IN_PROGRESS_MASK		0x8
+#define ENA_REGS_DEV_STS_RESET_FINISHED_SHIFT		4
+#define ENA_REGS_DEV_STS_RESET_FINISHED_MASK		0x10
+#define ENA_REGS_DEV_STS_FATAL_ERROR_SHIFT		5
+#define ENA_REGS_DEV_STS_FATAL_ERROR_MASK		0x20
+#define ENA_REGS_DEV_STS_QUIESCENT_STATE_IN_PROGRESS_SHIFT		6
+#define ENA_REGS_DEV_STS_QUIESCENT_STATE_IN_PROGRESS_MASK		0x40
+#define ENA_REGS_DEV_STS_QUIESCENT_STATE_ACHIEVED_SHIFT		7
+#define ENA_REGS_DEV_STS_QUIESCENT_STATE_ACHIEVED_MASK		0x80
+
+/* mmio_reg_read register */
+#define ENA_REGS_MMIO_REG_READ_REQ_ID_MASK		0xffff
+#define ENA_REGS_MMIO_REG_READ_REG_OFF_SHIFT		16
+#define ENA_REGS_MMIO_REG_READ_REG_OFF_MASK		0xffff0000
+
+/* rss_ind_entry_update register */
+#define ENA_REGS_RSS_IND_ENTRY_UPDATE_INDEX_MASK		0xffff
+#define ENA_REGS_RSS_IND_ENTRY_UPDATE_CQ_IDX_SHIFT		16
+#define ENA_REGS_RSS_IND_ENTRY_UPDATE_CQ_IDX_MASK		0xffff0000
+
+#endif /*_ENA_REGS_H_ */
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/amd/xgbe/xgbe-drv.c
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/amd/xgbe/xgbe-drv.c
@@ -1626,11 +1626,17 @@ static void xgbe_poll_controller(struct
 }
 #endif /* End CONFIG_NET_POLL_CONTROLLER */
 
-static int xgbe_setup_tc(struct net_device *netdev, u8 tc)
+static int xgbe_setup_tc(struct net_device *netdev, u32 handle, __be16 proto,
+			 struct tc_to_netdev *tc_to_netdev)
 {
 	struct xgbe_prv_data *pdata = netdev_priv(netdev);
 	unsigned int offset, queue;
-	u8 i;
+	u8 i, tc;
+
+	if (handle != TC_H_ROOT || tc_to_netdev->type != TC_SETUP_MQPRIO)
+		return -EINVAL;
+
+	tc = tc_to_netdev->tc;
 
 	if (tc && (tc != pdata->hw_feat.tc_cnt))
 		return -EINVAL;
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/apm/xgene/Makefile
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/apm/xgene/Makefile
@@ -3,5 +3,6 @@
 #
 
 xgene-enet-objs := xgene_enet_hw.o xgene_enet_sgmac.o xgene_enet_xgmac.o \
-		   xgene_enet_main.o xgene_enet_ring2.o xgene_enet_ethtool.o
+		   xgene_enet_main.o xgene_enet_ring2.o xgene_enet_ethtool.o \
+		   xgene_enet_cle.o
 obj-$(CONFIG_NET_XGENE) += xgene-enet.o
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/apm/xgene/xgene_enet_cle.c
@@ -0,0 +1,734 @@
+/* Applied Micro X-Gene SoC Ethernet Classifier structures
+ *
+ * Copyright (c) 2016, Applied Micro Circuits Corporation
+ * Authors: Khuong Dinh <kdinh@apm.com>
+ *          Tanmay Inamdar <tinamdar@apm.com>
+ *          Iyappan Subramanian <isubramanian@apm.com>
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "xgene_enet_main.h"
+
+/* interfaces to convert structures to HW recognized bit formats */
+static void xgene_cle_sband_to_hw(u8 frag, enum xgene_cle_prot_version ver,
+				  enum xgene_cle_prot_type type, u32 len,
+				  u32 *reg)
+{
+	*reg =  SET_VAL(SB_IPFRAG, frag) |
+		SET_VAL(SB_IPPROT, type) |
+		SET_VAL(SB_IPVER, ver) |
+		SET_VAL(SB_HDRLEN, len);
+}
+
+static void xgene_cle_idt_to_hw(u32 dstqid, u32 fpsel,
+				u32 nfpsel, u32 *idt_reg)
+{
+	*idt_reg =  SET_VAL(IDT_DSTQID, dstqid) |
+		    SET_VAL(IDT_FPSEL, fpsel) |
+		    SET_VAL(IDT_NFPSEL, nfpsel);
+}
+
+static void xgene_cle_dbptr_to_hw(struct xgene_enet_pdata *pdata,
+				  struct xgene_cle_dbptr *dbptr, u32 *buf)
+{
+	buf[4] = SET_VAL(CLE_FPSEL, dbptr->fpsel) |
+		 SET_VAL(CLE_DSTQIDL, dbptr->dstqid);
+
+	buf[5] = SET_VAL(CLE_DSTQIDH, (u32)dbptr->dstqid >> CLE_DSTQIDL_LEN) |
+		 SET_VAL(CLE_PRIORITY, dbptr->cle_priority);
+}
+
+static void xgene_cle_kn_to_hw(struct xgene_cle_ptree_kn *kn, u32 *buf)
+{
+	u32 i, j = 0;
+	u32 data;
+
+	buf[j++] = SET_VAL(CLE_TYPE, kn->node_type);
+	for (i = 0; i < kn->num_keys; i++) {
+		struct xgene_cle_ptree_key *key = &kn->key[i];
+
+		if (!(i % 2)) {
+			buf[j] = SET_VAL(CLE_KN_PRIO, key->priority) |
+				 SET_VAL(CLE_KN_RPTR, key->result_pointer);
+		} else {
+			data = SET_VAL(CLE_KN_PRIO, key->priority) |
+			       SET_VAL(CLE_KN_RPTR, key->result_pointer);
+			buf[j++] |= (data << 16);
+		}
+	}
+}
+
+static void xgene_cle_dn_to_hw(struct xgene_cle_ptree_ewdn *dn,
+			       u32 *buf, u32 jb)
+{
+	struct xgene_cle_ptree_branch *br;
+	u32 i, j = 0;
+	u32 npp;
+
+	buf[j++] = SET_VAL(CLE_DN_TYPE, dn->node_type) |
+		   SET_VAL(CLE_DN_LASTN, dn->last_node) |
+		   SET_VAL(CLE_DN_HLS, dn->hdr_len_store) |
+		   SET_VAL(CLE_DN_EXT, dn->hdr_extn) |
+		   SET_VAL(CLE_DN_BSTOR, dn->byte_store) |
+		   SET_VAL(CLE_DN_SBSTOR, dn->search_byte_store) |
+		   SET_VAL(CLE_DN_RPTR, dn->result_pointer);
+
+	for (i = 0; i < dn->num_branches; i++) {
+		br = &dn->branch[i];
+		npp = br->next_packet_pointer;
+
+		if ((br->jump_rel == JMP_ABS) && (npp < CLE_PKTRAM_SIZE))
+			npp += jb;
+
+		buf[j++] = SET_VAL(CLE_BR_VALID, br->valid) |
+			   SET_VAL(CLE_BR_NPPTR, npp) |
+			   SET_VAL(CLE_BR_JB, br->jump_bw) |
+			   SET_VAL(CLE_BR_JR, br->jump_rel) |
+			   SET_VAL(CLE_BR_OP, br->operation) |
+			   SET_VAL(CLE_BR_NNODE, br->next_node) |
+			   SET_VAL(CLE_BR_NBR, br->next_branch);
+
+		buf[j++] = SET_VAL(CLE_BR_DATA, br->data) |
+			   SET_VAL(CLE_BR_MASK, br->mask);
+	}
+}
+
+static int xgene_cle_poll_cmd_done(void __iomem *base,
+				   enum xgene_cle_cmd_type cmd)
+{
+	u32 status, loop = 10;
+	int ret = -EBUSY;
+
+	while (loop--) {
+		status = ioread32(base + INDCMD_STATUS);
+		if (status & cmd) {
+			ret = 0;
+			break;
+		}
+		usleep_range(1000, 2000);
+	}
+
+	return ret;
+}
+
+static int xgene_cle_dram_wr(struct xgene_enet_cle *cle, u32 *data, u8 nregs,
+			     u32 index, enum xgene_cle_dram_type type,
+			     enum xgene_cle_cmd_type cmd)
+{
+	enum xgene_cle_parser parser = cle->active_parser;
+	void __iomem *base = cle->base;
+	u32 i, j, ind_addr;
+	u8 port, nparsers;
+	int ret = 0;
+
+	/* PTREE_RAM onwards, DRAM regions are common for all parsers */
+	nparsers = (type >= PTREE_RAM) ? 1 : cle->parsers;
+
+	for (i = 0; i < nparsers; i++) {
+		port = i;
+		if ((type < PTREE_RAM) && (parser != PARSER_ALL))
+			port = parser;
+
+		ind_addr = XGENE_CLE_DRAM(type + (port * 4)) | index;
+		iowrite32(ind_addr, base + INDADDR);
+		for (j = 0; j < nregs; j++)
+			iowrite32(data[j], base + DATA_RAM0 + (j * 4));
+		iowrite32(cmd, base + INDCMD);
+
+		ret = xgene_cle_poll_cmd_done(base, cmd);
+		if (ret)
+			break;
+	}
+
+	return ret;
+}
+
+static void xgene_cle_enable_ptree(struct xgene_enet_pdata *pdata,
+				   struct xgene_enet_cle *cle)
+{
+	struct xgene_cle_ptree *ptree = &cle->ptree;
+	void __iomem *addr, *base = cle->base;
+	u32 offset = CLE_PORT_OFFSET;
+	u32 i;
+
+	/* 1G port has to advance 4 bytes and 10G has to advance 8 bytes */
+	ptree->start_pkt += cle->jump_bytes;
+	for (i = 0; i < cle->parsers; i++) {
+		if (cle->active_parser != PARSER_ALL)
+			addr = base + cle->active_parser * offset;
+		else
+			addr = base + (i * offset);
+
+		iowrite32(ptree->start_node & 0x3fff, addr + SNPTR0);
+		iowrite32(ptree->start_pkt & 0x1ff, addr + SPPTR0);
+	}
+}
+
+static int xgene_cle_setup_dbptr(struct xgene_enet_pdata *pdata,
+				 struct xgene_enet_cle *cle)
+{
+	struct xgene_cle_ptree *ptree = &cle->ptree;
+	u32 buf[CLE_DRAM_REGS];
+	u32 i;
+	int ret;
+
+	memset(buf, 0, sizeof(buf));
+	for (i = 0; i < ptree->num_dbptr; i++) {
+		xgene_cle_dbptr_to_hw(pdata, &ptree->dbptr[i], buf);
+		ret = xgene_cle_dram_wr(cle, buf, 6, i + ptree->start_dbptr,
+					DB_RAM,	CLE_CMD_WR);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
+static int xgene_cle_setup_node(struct xgene_enet_pdata *pdata,
+				struct xgene_enet_cle *cle)
+{
+	struct xgene_cle_ptree *ptree = &cle->ptree;
+	struct xgene_cle_ptree_ewdn *dn = ptree->dn;
+	struct xgene_cle_ptree_kn *kn = ptree->kn;
+	u32 buf[CLE_DRAM_REGS];
+	int i, j, ret;
+
+	memset(buf, 0, sizeof(buf));
+	for (i = 0; i < ptree->num_dn; i++) {
+		xgene_cle_dn_to_hw(&dn[i], buf, cle->jump_bytes);
+		ret = xgene_cle_dram_wr(cle, buf, 17, i + ptree->start_node,
+					PTREE_RAM, CLE_CMD_WR);
+		if (ret)
+			return ret;
+	}
+
+	/* continue node index for key node */
+	memset(buf, 0, sizeof(buf));
+	for (j = i; j < (ptree->num_kn + ptree->num_dn); j++) {
+		xgene_cle_kn_to_hw(&kn[j - ptree->num_dn], buf);
+		ret = xgene_cle_dram_wr(cle, buf, 17, j + ptree->start_node,
+					PTREE_RAM, CLE_CMD_WR);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
+static int xgene_cle_setup_ptree(struct xgene_enet_pdata *pdata,
+				 struct xgene_enet_cle *cle)
+{
+	int ret;
+
+	ret = xgene_cle_setup_node(pdata, cle);
+	if (ret)
+		return ret;
+
+	ret = xgene_cle_setup_dbptr(pdata, cle);
+	if (ret)
+		return ret;
+
+	xgene_cle_enable_ptree(pdata, cle);
+
+	return 0;
+}
+
+static void xgene_cle_setup_def_dbptr(struct xgene_enet_pdata *pdata,
+				      struct xgene_enet_cle *enet_cle,
+				      struct xgene_cle_dbptr *dbptr,
+				      u32 index, u8 priority)
+{
+	void __iomem *base = enet_cle->base;
+	void __iomem *base_addr;
+	u32 buf[CLE_DRAM_REGS];
+	u32 def_cls, offset;
+	u32 i, j;
+
+	memset(buf, 0, sizeof(buf));
+	xgene_cle_dbptr_to_hw(pdata, dbptr, buf);
+
+	for (i = 0; i < enet_cle->parsers; i++) {
+		if (enet_cle->active_parser != PARSER_ALL) {
+			offset = enet_cle->active_parser *
+				CLE_PORT_OFFSET;
+		} else {
+			offset = i * CLE_PORT_OFFSET;
+		}
+
+		base_addr = base + DFCLSRESDB00 + offset;
+		for (j = 0; j < 6; j++)
+			iowrite32(buf[j], base_addr + (j * 4));
+
+		def_cls = ((priority & 0x7) << 10) | (index & 0x3ff);
+		iowrite32(def_cls, base + DFCLSRESDBPTR0 + offset);
+	}
+}
+
+static int xgene_cle_set_rss_sband(struct xgene_enet_cle *cle)
+{
+	u32 idx = CLE_PKTRAM_SIZE / sizeof(u32);
+	u32 mac_hdr_len = ETH_HLEN;
+	u32 sband, reg = 0;
+	u32 ipv4_ihl = 5;
+	u32 hdr_len;
+	int ret;
+
+	/* Sideband: IPV4/TCP packets */
+	hdr_len = (mac_hdr_len << 5) | ipv4_ihl;
+	xgene_cle_sband_to_hw(0, XGENE_CLE_IPV4, XGENE_CLE_TCP, hdr_len, &reg);
+	sband = reg;
+
+	/* Sideband: IPv4/UDP packets */
+	hdr_len = (mac_hdr_len << 5) | ipv4_ihl;
+	xgene_cle_sband_to_hw(1, XGENE_CLE_IPV4, XGENE_CLE_UDP, hdr_len, &reg);
+	sband |= (reg << 16);
+
+	ret = xgene_cle_dram_wr(cle, &sband, 1, idx, PKT_RAM, CLE_CMD_WR);
+	if (ret)
+		return ret;
+
+	/* Sideband: IPv4/RAW packets */
+	hdr_len = (mac_hdr_len << 5) | ipv4_ihl;
+	xgene_cle_sband_to_hw(0, XGENE_CLE_IPV4, XGENE_CLE_OTHER,
+			      hdr_len, &reg);
+	sband = reg;
+
+	/* Sideband: Ethernet II/RAW packets */
+	hdr_len = (mac_hdr_len << 5);
+	xgene_cle_sband_to_hw(0, XGENE_CLE_IPV4, XGENE_CLE_OTHER,
+			      hdr_len, &reg);
+	sband |= (reg << 16);
+
+	ret = xgene_cle_dram_wr(cle, &sband, 1, idx + 1, PKT_RAM, CLE_CMD_WR);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static int xgene_cle_set_rss_skeys(struct xgene_enet_cle *cle)
+{
+	u32 secret_key_ipv4[4];  /* 16 Bytes*/
+	int ret = 0;
+
+	get_random_bytes(secret_key_ipv4, 16);
+	ret = xgene_cle_dram_wr(cle, secret_key_ipv4, 4, 0,
+				RSS_IPV4_HASH_SKEY, CLE_CMD_WR);
+	return ret;
+}
+
+static int xgene_cle_set_rss_idt(struct xgene_enet_pdata *pdata)
+{
+	u32 fpsel, dstqid, nfpsel, idt_reg, idx;
+	int i, ret = 0;
+	u16 pool_id;
+
+	for (i = 0; i < XGENE_CLE_IDT_ENTRIES; i++) {
+		idx = i % pdata->rxq_cnt;
+		pool_id = pdata->rx_ring[idx]->buf_pool->id;
+		fpsel = xgene_enet_ring_bufnum(pool_id) - 0x20;
+		dstqid = xgene_enet_dst_ring_num(pdata->rx_ring[idx]);
+		nfpsel = 0;
+		idt_reg = 0;
+
+		xgene_cle_idt_to_hw(dstqid, fpsel, nfpsel, &idt_reg);
+		ret = xgene_cle_dram_wr(&pdata->cle, &idt_reg, 1, i,
+					RSS_IDT, CLE_CMD_WR);
+		if (ret)
+			return ret;
+	}
+
+	ret = xgene_cle_set_rss_skeys(&pdata->cle);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static int xgene_cle_setup_rss(struct xgene_enet_pdata *pdata)
+{
+	struct xgene_enet_cle *cle = &pdata->cle;
+	void __iomem *base = cle->base;
+	u32 offset, val = 0;
+	int i, ret = 0;
+
+	offset = CLE_PORT_OFFSET;
+	for (i = 0; i < cle->parsers; i++) {
+		if (cle->active_parser != PARSER_ALL)
+			offset = cle->active_parser * CLE_PORT_OFFSET;
+		else
+			offset = i * CLE_PORT_OFFSET;
+
+		/* enable RSS */
+		val = (RSS_IPV4_12B << 1) | 0x1;
+		writel(val, base + RSS_CTRL0 + offset);
+	}
+
+	/* setup sideband data */
+	ret = xgene_cle_set_rss_sband(cle);
+	if (ret)
+		return ret;
+
+	/* setup indirection table */
+	ret = xgene_cle_set_rss_idt(pdata);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static int xgene_enet_cle_init(struct xgene_enet_pdata *pdata)
+{
+	struct xgene_enet_cle *enet_cle = &pdata->cle;
+	struct xgene_cle_dbptr dbptr[DB_MAX_PTRS];
+	struct xgene_cle_ptree_branch *br;
+	u32 def_qid, def_fpsel, pool_id;
+	struct xgene_cle_ptree *ptree;
+	struct xgene_cle_ptree_kn kn;
+	int ret;
+	struct xgene_cle_ptree_ewdn ptree_dn[] = {
+		{
+			/* PKT_TYPE_NODE */
+			.node_type = EWDN,
+			.last_node = 0,
+			.hdr_len_store = 1,
+			.hdr_extn = NO_BYTE,
+			.byte_store = NO_BYTE,
+			.search_byte_store = NO_BYTE,
+			.result_pointer = DB_RES_DROP,
+			.num_branches = 2,
+			.branch = {
+				{
+					/* IPV4 */
+					.valid = 0,
+					.next_packet_pointer = 22,
+					.jump_bw = JMP_FW,
+					.jump_rel = JMP_ABS,
+					.operation = EQT,
+					.next_node = PKT_PROT_NODE,
+					.next_branch = 0,
+					.data = 0x8,
+					.mask = 0xffff
+				},
+				{
+					.valid = 0,
+					.next_packet_pointer = 262,
+					.jump_bw = JMP_FW,
+					.jump_rel = JMP_ABS,
+					.operation = EQT,
+					.next_node = LAST_NODE,
+					.next_branch = 0,
+					.data = 0x0,
+					.mask = 0xffff
+				}
+			},
+		},
+		{
+			/* PKT_PROT_NODE */
+			.node_type = EWDN,
+			.last_node = 0,
+			.hdr_len_store = 1,
+			.hdr_extn = NO_BYTE,
+			.byte_store = NO_BYTE,
+			.search_byte_store = NO_BYTE,
+			.result_pointer = DB_RES_DROP,
+			.num_branches = 3,
+			.branch = {
+				{
+					/* TCP */
+					.valid = 1,
+					.next_packet_pointer = 26,
+					.jump_bw = JMP_FW,
+					.jump_rel = JMP_ABS,
+					.operation = EQT,
+					.next_node = RSS_IPV4_TCP_NODE,
+					.next_branch = 0,
+					.data = 0x0600,
+					.mask = 0xffff
+				},
+				{
+					/* UDP */
+					.valid = 1,
+					.next_packet_pointer = 26,
+					.jump_bw = JMP_FW,
+					.jump_rel = JMP_ABS,
+					.operation = EQT,
+					.next_node = RSS_IPV4_UDP_NODE,
+					.next_branch = 0,
+					.data = 0x1100,
+					.mask = 0xffff
+				},
+				{
+					.valid = 0,
+					.next_packet_pointer = 260,
+					.jump_bw = JMP_FW,
+					.jump_rel = JMP_ABS,
+					.operation = EQT,
+					.next_node = LAST_NODE,
+					.next_branch = 0,
+					.data = 0x0,
+					.mask = 0xffff
+				}
+			}
+		},
+		{
+			/* RSS_IPV4_TCP_NODE */
+			.node_type = EWDN,
+			.last_node = 0,
+			.hdr_len_store = 1,
+			.hdr_extn = NO_BYTE,
+			.byte_store = NO_BYTE,
+			.search_byte_store = BOTH_BYTES,
+			.result_pointer = DB_RES_DROP,
+			.num_branches = 6,
+			.branch = {
+				{
+					/* SRC IPV4 B01 */
+					.valid = 0,
+					.next_packet_pointer = 28,
+					.jump_bw = JMP_FW,
+					.jump_rel = JMP_ABS,
+					.operation = EQT,
+					.next_node = RSS_IPV4_TCP_NODE,
+					.next_branch = 1,
+					.data = 0x0,
+					.mask = 0xffff
+				},
+				{
+					/* SRC IPV4 B23 */
+					.valid = 0,
+					.next_packet_pointer = 30,
+					.jump_bw = JMP_FW,
+					.jump_rel = JMP_ABS,
+					.operation = EQT,
+					.next_node = RSS_IPV4_TCP_NODE,
+					.next_branch = 2,
+					.data = 0x0,
+					.mask = 0xffff
+				},
+				{
+					/* DST IPV4 B01 */
+					.valid = 0,
+					.next_packet_pointer = 32,
+					.jump_bw = JMP_FW,
+					.jump_rel = JMP_ABS,
+					.operation = EQT,
+					.next_node = RSS_IPV4_TCP_NODE,
+					.next_branch = 3,
+					.data = 0x0,
+					.mask = 0xffff
+				},
+				{
+					/* DST IPV4 B23 */
+					.valid = 0,
+					.next_packet_pointer = 34,
+					.jump_bw = JMP_FW,
+					.jump_rel = JMP_ABS,
+					.operation = EQT,
+					.next_node = RSS_IPV4_TCP_NODE,
+					.next_branch = 4,
+					.data = 0x0,
+					.mask = 0xffff
+				},
+				{
+					/* TCP SRC Port */
+					.valid = 0,
+					.next_packet_pointer = 36,
+					.jump_bw = JMP_FW,
+					.jump_rel = JMP_ABS,
+					.operation = EQT,
+					.next_node = RSS_IPV4_TCP_NODE,
+					.next_branch = 5,
+					.data = 0x0,
+					.mask = 0xffff
+				},
+				{
+					/* TCP DST Port */
+					.valid = 0,
+					.next_packet_pointer = 256,
+					.jump_bw = JMP_FW,
+					.jump_rel = JMP_ABS,
+					.operation = EQT,
+					.next_node = LAST_NODE,
+					.next_branch = 0,
+					.data = 0x0,
+					.mask = 0xffff
+				}
+			}
+		},
+		{
+			/* RSS_IPV4_UDP_NODE */
+			.node_type = EWDN,
+			.last_node = 0,
+			.hdr_len_store = 1,
+			.hdr_extn = NO_BYTE,
+			.byte_store = NO_BYTE,
+			.search_byte_store = BOTH_BYTES,
+			.result_pointer = DB_RES_DROP,
+			.num_branches = 6,
+			.branch = {
+				{
+					/* SRC IPV4 B01 */
+					.valid = 0,
+					.next_packet_pointer = 28,
+					.jump_bw = JMP_FW,
+					.jump_rel = JMP_ABS,
+					.operation = EQT,
+					.next_node = RSS_IPV4_UDP_NODE,
+					.next_branch = 1,
+					.data = 0x0,
+					.mask = 0xffff
+				},
+				{
+					/* SRC IPV4 B23 */
+					.valid = 0,
+					.next_packet_pointer = 30,
+					.jump_bw = JMP_FW,
+					.jump_rel = JMP_ABS,
+					.operation = EQT,
+					.next_node = RSS_IPV4_UDP_NODE,
+					.next_branch = 2,
+					.data = 0x0,
+					.mask = 0xffff
+				},
+				{
+					/* DST IPV4 B01 */
+					.valid = 0,
+					.next_packet_pointer = 32,
+					.jump_bw = JMP_FW,
+					.jump_rel = JMP_ABS,
+					.operation = EQT,
+					.next_node = RSS_IPV4_UDP_NODE,
+					.next_branch = 3,
+					.data = 0x0,
+					.mask = 0xffff
+				},
+				{
+					/* DST IPV4 B23 */
+					.valid = 0,
+					.next_packet_pointer = 34,
+					.jump_bw = JMP_FW,
+					.jump_rel = JMP_ABS,
+					.operation = EQT,
+					.next_node = RSS_IPV4_UDP_NODE,
+					.next_branch = 4,
+					.data = 0x0,
+					.mask = 0xffff
+				},
+				{
+					/* TCP SRC Port */
+					.valid = 0,
+					.next_packet_pointer = 36,
+					.jump_bw = JMP_FW,
+					.jump_rel = JMP_ABS,
+					.operation = EQT,
+					.next_node = RSS_IPV4_UDP_NODE,
+					.next_branch = 5,
+					.data = 0x0,
+					.mask = 0xffff
+				},
+				{
+					/* TCP DST Port */
+					.valid = 0,
+					.next_packet_pointer = 256,
+					.jump_bw = JMP_FW,
+					.jump_rel = JMP_ABS,
+					.operation = EQT,
+					.next_node = LAST_NODE,
+					.next_branch = 0,
+					.data = 0x0,
+					.mask = 0xffff
+				}
+			}
+		},
+		{
+			/* LAST NODE */
+			.node_type = EWDN,
+			.last_node = 1,
+			.hdr_len_store = 1,
+			.hdr_extn = NO_BYTE,
+			.byte_store = NO_BYTE,
+			.search_byte_store = NO_BYTE,
+			.result_pointer = DB_RES_DROP,
+			.num_branches = 1,
+			.branch = {
+				{
+					.valid = 0,
+					.next_packet_pointer = 0,
+					.jump_bw = JMP_FW,
+					.jump_rel = JMP_ABS,
+					.operation = EQT,
+					.next_node = MAX_NODES,
+					.next_branch = 0,
+					.data = 0,
+					.mask = 0xffff
+				}
+			}
+		}
+	};
+
+	ptree = &enet_cle->ptree;
+	ptree->start_pkt = 12; /* Ethertype */
+	if (pdata->phy_mode == PHY_INTERFACE_MODE_XGMII) {
+		ret = xgene_cle_setup_rss(pdata);
+		if (ret) {
+			netdev_err(pdata->ndev, "RSS initialization failed\n");
+			return ret;
+		}
+	} else {
+		br = &ptree_dn[PKT_PROT_NODE].branch[0];
+		br->valid = 0;
+		br->next_packet_pointer = 260;
+		br->next_node = LAST_NODE;
+		br->data = 0x0000;
+		br->mask = 0xffff;
+	}
+
+	def_qid = xgene_enet_dst_ring_num(pdata->rx_ring[0]);
+	pool_id = pdata->rx_ring[0]->buf_pool->id;
+	def_fpsel = xgene_enet_ring_bufnum(pool_id) - 0x20;
+
+	memset(dbptr, 0, sizeof(struct xgene_cle_dbptr) * DB_MAX_PTRS);
+	dbptr[DB_RES_ACCEPT].fpsel =  def_fpsel;
+	dbptr[DB_RES_ACCEPT].dstqid = def_qid;
+	dbptr[DB_RES_ACCEPT].cle_priority = 1;
+
+	dbptr[DB_RES_DEF].fpsel = def_fpsel;
+	dbptr[DB_RES_DEF].dstqid = def_qid;
+	dbptr[DB_RES_DEF].cle_priority = 7;
+	xgene_cle_setup_def_dbptr(pdata, enet_cle, &dbptr[DB_RES_DEF],
+				  DB_RES_ACCEPT, 7);
+
+	dbptr[DB_RES_DROP].drop = 1;
+
+	memset(&kn, 0, sizeof(kn));
+	kn.node_type = KN;
+	kn.num_keys = 1;
+	kn.key[0].priority = 0;
+	kn.key[0].result_pointer = DB_RES_ACCEPT;
+
+	ptree->dn = ptree_dn;
+	ptree->kn = &kn;
+	ptree->dbptr = dbptr;
+	ptree->num_dn = MAX_NODES;
+	ptree->num_kn = 1;
+	ptree->num_dbptr = DB_MAX_PTRS;
+
+	return xgene_cle_setup_ptree(pdata, enet_cle);
+}
+
+struct xgene_cle_ops xgene_cle3in_ops = {
+	.cle_init = xgene_enet_cle_init,
+};
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/apm/xgene/xgene_enet_cle.h
@@ -0,0 +1,295 @@
+/* Applied Micro X-Gene SoC Ethernet Classifier structures
+ *
+ * Copyright (c) 2016, Applied Micro Circuits Corporation
+ * Authors: Khuong Dinh <kdinh@apm.com>
+ *          Tanmay Inamdar <tinamdar@apm.com>
+ *          Iyappan Subramanian <isubramanian@apm.com>
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __XGENE_ENET_CLE_H__
+#define __XGENE_ENET_CLE_H__
+
+#include <linux/io.h>
+#include <linux/random.h>
+
+/* Register offsets */
+#define INDADDR			0x04
+#define INDCMD			0x08
+#define INDCMD_STATUS		0x0c
+#define DATA_RAM0		0x10
+#define SNPTR0			0x0100
+#define SPPTR0			0x0104
+#define DFCLSRESDBPTR0		0x0108
+#define DFCLSRESDB00		0x010c
+#define RSS_CTRL0		0x0000013c
+
+#define CLE_CMD_TO		10	/* ms */
+#define CLE_PKTRAM_SIZE		256	/* bytes */
+#define CLE_PORT_OFFSET		0x200
+#define CLE_DRAM_REGS		17
+
+#define CLE_DN_TYPE_LEN		2
+#define CLE_DN_TYPE_POS		0
+#define CLE_DN_LASTN_LEN	1
+#define CLE_DN_LASTN_POS	2
+#define CLE_DN_HLS_LEN		1
+#define CLE_DN_HLS_POS		3
+#define CLE_DN_EXT_LEN		2
+#define	CLE_DN_EXT_POS		4
+#define CLE_DN_BSTOR_LEN	2
+#define CLE_DN_BSTOR_POS	6
+#define CLE_DN_SBSTOR_LEN	2
+#define CLE_DN_SBSTOR_POS	8
+#define CLE_DN_RPTR_LEN		12
+#define CLE_DN_RPTR_POS		12
+
+#define CLE_BR_VALID_LEN	1
+#define CLE_BR_VALID_POS	0
+#define CLE_BR_NPPTR_LEN	9
+#define CLE_BR_NPPTR_POS	1
+#define CLE_BR_JB_LEN		1
+#define CLE_BR_JB_POS		10
+#define CLE_BR_JR_LEN		1
+#define CLE_BR_JR_POS		11
+#define CLE_BR_OP_LEN		3
+#define CLE_BR_OP_POS		12
+#define CLE_BR_NNODE_LEN	9
+#define CLE_BR_NNODE_POS	15
+#define CLE_BR_NBR_LEN		5
+#define CLE_BR_NBR_POS		24
+
+#define CLE_BR_DATA_LEN		16
+#define CLE_BR_DATA_POS		0
+#define CLE_BR_MASK_LEN		16
+#define CLE_BR_MASK_POS		16
+
+#define CLE_KN_PRIO_POS		0
+#define CLE_KN_PRIO_LEN		3
+#define CLE_KN_RPTR_POS		3
+#define CLE_KN_RPTR_LEN		10
+#define CLE_TYPE_POS		0
+#define CLE_TYPE_LEN		2
+
+#define CLE_DSTQIDL_POS		25
+#define CLE_DSTQIDL_LEN		7
+#define CLE_DSTQIDH_POS		0
+#define CLE_DSTQIDH_LEN		5
+#define CLE_FPSEL_POS		21
+#define CLE_FPSEL_LEN		4
+#define CLE_PRIORITY_POS	5
+#define CLE_PRIORITY_LEN	3
+
+#define JMP_ABS			0
+#define JMP_REL			1
+#define JMP_FW			0
+#define JMP_BW			1
+
+enum xgene_cle_ptree_nodes {
+	PKT_TYPE_NODE,
+	PKT_PROT_NODE,
+	RSS_IPV4_TCP_NODE,
+	RSS_IPV4_UDP_NODE,
+	LAST_NODE,
+	MAX_NODES
+};
+
+enum xgene_cle_byte_store {
+	NO_BYTE,
+	FIRST_BYTE,
+	SECOND_BYTE,
+	BOTH_BYTES
+};
+
+/* Preclassification operation types */
+enum xgene_cle_node_type {
+	INV,
+	KN,
+	EWDN,
+	RES_NODE
+};
+
+/* Preclassification operation types */
+enum xgene_cle_op_type {
+	EQT,
+	NEQT,
+	LTEQT,
+	GTEQT,
+	AND,
+	NAND
+};
+
+enum xgene_cle_parser {
+	PARSER0,
+	PARSER1,
+	PARSER2,
+	PARSER_ALL
+};
+
+#define XGENE_CLE_DRAM(type)	(((type) & 0xf) << 28)
+enum xgene_cle_dram_type {
+	PKT_RAM,
+	RSS_IDT,
+	RSS_IPV4_HASH_SKEY,
+	PTREE_RAM = 0xc,
+	AVL_RAM,
+	DB_RAM
+};
+
+enum xgene_cle_cmd_type {
+	CLE_CMD_WR = 1,
+	CLE_CMD_RD = 2,
+	CLE_CMD_AVL_ADD = 8,
+	CLE_CMD_AVL_DEL = 16,
+	CLE_CMD_AVL_SRCH = 32
+};
+
+enum xgene_cle_ipv4_rss_hashtype {
+	RSS_IPV4_8B,
+	RSS_IPV4_12B,
+};
+
+enum xgene_cle_prot_type {
+	XGENE_CLE_TCP,
+	XGENE_CLE_UDP,
+	XGENE_CLE_ESP,
+	XGENE_CLE_OTHER
+};
+
+enum xgene_cle_prot_version {
+	XGENE_CLE_IPV4,
+};
+
+enum xgene_cle_ptree_dbptrs {
+	DB_RES_DROP,
+	DB_RES_DEF,
+	DB_RES_ACCEPT,
+	DB_MAX_PTRS
+};
+
+/* RSS sideband signal info */
+#define SB_IPFRAG_POS	0
+#define SB_IPFRAG_LEN	1
+#define SB_IPPROT_POS	1
+#define SB_IPPROT_LEN	2
+#define SB_IPVER_POS	3
+#define SB_IPVER_LEN	1
+#define SB_HDRLEN_POS	4
+#define SB_HDRLEN_LEN	12
+
+/* RSS indirection table */
+#define XGENE_CLE_IDT_ENTRIES	128
+#define IDT_DSTQID_POS		0
+#define IDT_DSTQID_LEN		12
+#define IDT_FPSEL_POS		12
+#define IDT_FPSEL_LEN		4
+#define IDT_NFPSEL_POS		16
+#define IDT_NFPSEL_LEN		4
+
+struct xgene_cle_ptree_branch {
+	bool valid;
+	u16 next_packet_pointer;
+	bool jump_bw;
+	bool jump_rel;
+	u8 operation;
+	u16 next_node;
+	u8 next_branch;
+	u16 data;
+	u16 mask;
+};
+
+struct xgene_cle_ptree_ewdn {
+	u8 node_type;
+	bool last_node;
+	bool hdr_len_store;
+	u8 hdr_extn;
+	u8 byte_store;
+	u8 search_byte_store;
+	u16 result_pointer;
+	u8 num_branches;
+	struct xgene_cle_ptree_branch branch[6];
+};
+
+struct xgene_cle_ptree_key {
+	u8 priority;
+	u16 result_pointer;
+};
+
+struct xgene_cle_ptree_kn {
+	u8 node_type;
+	u8 num_keys;
+	struct xgene_cle_ptree_key key[32];
+};
+
+struct xgene_cle_dbptr {
+	u8 split_boundary;
+	u8 mirror_nxtfpsel;
+	u8 mirror_fpsel;
+	u16 mirror_dstqid;
+	u8 drop;
+	u8 mirror;
+	u8 hdr_data_split;
+	u64 hopinfomsbs;
+	u8 DR;
+	u8 HR;
+	u64 hopinfomlsbs;
+	u16 h0enq_num;
+	u8 h0fpsel;
+	u8 nxtfpsel;
+	u8 fpsel;
+	u16 dstqid;
+	u8 cle_priority;
+	u8 cle_flowgroup;
+	u8 cle_perflow;
+	u8 cle_insert_timestamp;
+	u8 stash;
+	u8 in;
+	u8 perprioen;
+	u8 perflowgroupen;
+	u8 perflowen;
+	u8 selhash;
+	u8 selhdrext;
+	u8 mirror_nxtfpsel_msb;
+	u8 mirror_fpsel_msb;
+	u8 hfpsel_msb;
+	u8 nxtfpsel_msb;
+	u8 fpsel_msb;
+};
+
+struct xgene_cle_ptree {
+	struct xgene_cle_ptree_ewdn *dn;
+	struct xgene_cle_ptree_kn *kn;
+	struct xgene_cle_dbptr *dbptr;
+	u32 num_dn;
+	u32 num_kn;
+	u32 num_dbptr;
+	u32 start_node;
+	u32 start_pkt;
+	u32 start_dbptr;
+};
+
+struct xgene_enet_cle {
+	void __iomem *base;
+	struct xgene_cle_ptree ptree;
+	enum xgene_cle_parser active_parser;
+	u32 parsers;
+	u32 max_nodes;
+	u32 max_dbptrs;
+	u32 jump_bytes;
+};
+
+extern struct xgene_cle_ops xgene_cle3in_ops;
+
+#endif /* __XGENE_ENET_CLE_H__ */
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/apm/xgene/xgene_enet_hw.c
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/apm/xgene/xgene_enet_hw.c
@@ -204,6 +204,17 @@ static u32 xgene_enet_ring_len(struct xg
 	return num_msgs;
 }
 
+static void xgene_enet_setup_coalescing(struct xgene_enet_desc_ring *ring)
+{
+	u32 data = 0x7777;
+
+	xgene_enet_ring_wr32(ring, CSR_PBM_COAL, 0x8e);
+	xgene_enet_ring_wr32(ring, CSR_PBM_CTICK1, data);
+	xgene_enet_ring_wr32(ring, CSR_PBM_CTICK2, data << 16);
+	xgene_enet_ring_wr32(ring, CSR_THRESHOLD0_SET1, 0x40);
+	xgene_enet_ring_wr32(ring, CSR_THRESHOLD1_SET1, 0x80);
+}
+
 void xgene_enet_parse_error(struct xgene_enet_desc_ring *ring,
 			    struct xgene_enet_pdata *pdata,
 			    enum xgene_enet_err_code status)
@@ -892,4 +903,5 @@ struct xgene_ring_ops xgene_ring1_ops =
 	.clear = xgene_enet_clear_ring,
 	.wr_cmd = xgene_enet_wr_cmd,
 	.len = xgene_enet_ring_len,
+	.coalesce = xgene_enet_setup_coalescing,
 };
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/apm/xgene/xgene_enet_hw.h
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/apm/xgene/xgene_enet_hw.h
@@ -54,6 +54,11 @@ enum xgene_enet_rm {
 #define IS_BUFFER_POOL		BIT(20)
 #define PREFETCH_BUF_EN		BIT(21)
 #define CSR_RING_ID_BUF		0x000c
+#define CSR_PBM_COAL		0x0014
+#define CSR_PBM_CTICK1		0x001c
+#define CSR_PBM_CTICK2		0x0020
+#define CSR_THRESHOLD0_SET1	0x0030
+#define CSR_THRESHOLD1_SET1	0x0034
 #define CSR_RING_NE_INT_MODE	0x017c
 #define CSR_RING_CONFIG		0x006c
 #define CSR_RING_WR_BASE	0x0070
@@ -101,6 +106,7 @@ enum xgene_enet_rm {
 #define MAC_OFFSET			0x30
 
 #define BLOCK_ETH_CSR_OFFSET		0x2000
+#define BLOCK_ETH_CLE_CSR_OFFSET	0x6000
 #define BLOCK_ETH_RING_IF_OFFSET	0x9000
 #define BLOCK_ETH_CLKRST_CSR_OFFSET	0xc000
 #define BLOCK_ETH_DIAG_CSR_OFFSET	0xD000
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/apm/xgene/xgene_enet_main.c
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/apm/xgene/xgene_enet_main.c
@@ -93,13 +93,6 @@ static int xgene_enet_refill_bufpool(str
 	return 0;
 }
 
-static u16 xgene_enet_dst_ring_num(struct xgene_enet_desc_ring *ring)
-{
-	struct xgene_enet_pdata *pdata = netdev_priv(ring->ndev);
-
-	return ((u16)pdata->rm << 10) | ring->num;
-}
-
 static u8 xgene_enet_hdr_len(const void *data)
 {
 	const struct ethhdr *eth = data;
@@ -189,7 +182,6 @@ static int xgene_enet_tx_completion(stru
 static u64 xgene_enet_work_msg(struct sk_buff *skb)
 {
 	struct net_device *ndev = skb->dev;
-	struct xgene_enet_pdata *pdata = netdev_priv(ndev);
 	struct iphdr *iph;
 	u8 l3hlen = 0, l4hlen = 0;
 	u8 ethhdr, proto = 0, csum_enable = 0;
@@ -235,10 +227,6 @@ static u64 xgene_enet_work_msg(struct sk
 			if (!mss || ((skb->len - hdr_len) <= mss))
 				goto out;
 
-			if (mss != pdata->mss) {
-				pdata->mss = mss;
-				pdata->mac_ops->set_mss(pdata);
-			}
 			hopinfo |= SET_BIT(ET);
 		}
 	} else if (iph->protocol == IPPROTO_UDP) {
@@ -420,7 +408,7 @@ out:
 	raw_desc->m0 = cpu_to_le64(SET_VAL(LL, ll) | SET_VAL(NV, nv) |
 				   SET_VAL(USERINFO, tx_ring->tail));
 	tx_ring->cp_ring->cp_skb[tx_ring->tail] = skb;
-	pdata->tx_level += count;
+	pdata->tx_level[tx_ring->cp_ring->index] += count;
 	tx_ring->tail = tail;
 
 	return count;
@@ -430,15 +418,17 @@ static netdev_tx_t xgene_enet_start_xmit
 					 struct net_device *ndev)
 {
 	struct xgene_enet_pdata *pdata = netdev_priv(ndev);
-	struct xgene_enet_desc_ring *tx_ring = pdata->tx_ring;
-	u32 tx_level = pdata->tx_level;
+	struct xgene_enet_desc_ring *tx_ring;
+	int index = skb->queue_mapping;
+	u32 tx_level = pdata->tx_level[index];
 	int count;
 
-	if (tx_level < pdata->txc_level)
-		tx_level += ((typeof(pdata->tx_level))~0U);
+	tx_ring = pdata->tx_ring[index];
+	if (tx_level < pdata->txc_level[index])
+		tx_level += ((typeof(pdata->tx_level[index]))~0U);
 
-	if ((tx_level - pdata->txc_level) > pdata->tx_qcnt_hi) {
-		netif_stop_queue(ndev);
+	if ((tx_level - pdata->txc_level[index]) > pdata->tx_qcnt_hi) {
+		netif_stop_subqueue(ndev, index);
 		return NETDEV_TX_BUSY;
 	}
 
@@ -536,7 +526,8 @@ static bool is_rx_desc(struct xgene_enet
 static int xgene_enet_process_ring(struct xgene_enet_desc_ring *ring,
 				   int budget)
 {
-	struct xgene_enet_pdata *pdata = netdev_priv(ring->ndev);
+	struct net_device *ndev = ring->ndev;
+	struct xgene_enet_pdata *pdata = netdev_priv(ndev);
 	struct xgene_enet_raw_desc *raw_desc, *exp_desc;
 	u16 head = ring->head;
 	u16 slots = ring->slots - 1;
@@ -580,7 +571,7 @@ static int xgene_enet_process_ring(struc
 		desc_count++;
 		processed++;
 		if (is_completion)
-			pdata->txc_level += desc_count;
+			pdata->txc_level[ring->index] += desc_count;
 
 		if (ret)
 			break;
@@ -590,8 +581,8 @@ static int xgene_enet_process_ring(struc
 		pdata->ring_ops->wr_cmd(ring, -count);
 		ring->head = head;
 
-		if (netif_queue_stopped(ring->ndev))
-			netif_start_queue(ring->ndev);
+		if (__netif_subqueue_stopped(ndev, ring->index))
+			netif_start_subqueue(ndev, ring->index);
 	}
 
 	return processed;
@@ -616,8 +607,16 @@ static int xgene_enet_napi(struct napi_s
 static void xgene_enet_timeout(struct net_device *ndev)
 {
 	struct xgene_enet_pdata *pdata = netdev_priv(ndev);
+	struct netdev_queue *txq;
+	int i;
 
 	pdata->mac_ops->reset(pdata);
+
+	for (i = 0; i < pdata->txq_cnt; i++) {
+		txq = netdev_get_tx_queue(ndev, i);
+		txq->trans_start = jiffies;
+		netif_tx_start_queue(txq);
+	}
 }
 
 static int xgene_enet_register_irq(struct net_device *ndev)
@@ -625,16 +624,22 @@ static int xgene_enet_register_irq(struc
 	struct xgene_enet_pdata *pdata = netdev_priv(ndev);
 	struct device *dev = ndev_to_dev(ndev);
 	struct xgene_enet_desc_ring *ring;
-	int ret;
+	int ret = 0, i;
 
-	ring = pdata->rx_ring;
-	ret = devm_request_irq(dev, ring->irq, xgene_enet_rx_irq,
-			       IRQF_SHARED, ring->irq_name, ring);
-	if (ret)
-		netdev_err(ndev, "Failed to request irq %s\n", ring->irq_name);
+	for (i = 0; i < pdata->rxq_cnt; i++) {
+		ring = pdata->rx_ring[i];
+		irq_set_status_flags(ring->irq, IRQ_DISABLE_UNLAZY);
+		ret = devm_request_irq(dev, ring->irq, xgene_enet_rx_irq,
+				       IRQF_SHARED, ring->irq_name, ring);
+		if (ret) {
+			netdev_err(ndev, "Failed to request irq %s\n",
+				   ring->irq_name);
+		}
+	}
 
-	if (pdata->cq_cnt) {
-		ring = pdata->tx_ring->cp_ring;
+	for (i = 0; i < pdata->cq_cnt; i++) {
+		ring = pdata->tx_ring[i]->cp_ring;
+		irq_set_status_flags(ring->irq, IRQ_DISABLE_UNLAZY);
 		ret = devm_request_irq(dev, ring->irq, xgene_enet_rx_irq,
 				       IRQF_SHARED, ring->irq_name, ring);
 		if (ret) {
@@ -649,27 +654,38 @@ static int xgene_enet_register_irq(struc
 static void xgene_enet_free_irq(struct net_device *ndev)
 {
 	struct xgene_enet_pdata *pdata;
+	struct xgene_enet_desc_ring *ring;
 	struct device *dev;
+	int i;
 
 	pdata = netdev_priv(ndev);
 	dev = ndev_to_dev(ndev);
-	devm_free_irq(dev, pdata->rx_ring->irq, pdata->rx_ring);
 
-	if (pdata->cq_cnt) {
-		devm_free_irq(dev, pdata->tx_ring->cp_ring->irq,
-			      pdata->tx_ring->cp_ring);
+	for (i = 0; i < pdata->rxq_cnt; i++) {
+		ring = pdata->rx_ring[i];
+		irq_clear_status_flags(ring->irq, IRQ_DISABLE_UNLAZY);
+		devm_free_irq(dev, ring->irq, ring);
+	}
+
+	for (i = 0; i < pdata->cq_cnt; i++) {
+		ring = pdata->tx_ring[i]->cp_ring;
+		irq_clear_status_flags(ring->irq, IRQ_DISABLE_UNLAZY);
+		devm_free_irq(dev, ring->irq, ring);
 	}
 }
 
 static void xgene_enet_napi_enable(struct xgene_enet_pdata *pdata)
 {
 	struct napi_struct *napi;
+	int i;
 
-	napi = &pdata->rx_ring->napi;
-	napi_enable(napi);
+	for (i = 0; i < pdata->rxq_cnt; i++) {
+		napi = &pdata->rx_ring[i]->napi;
+		napi_enable(napi);
+	}
 
-	if (pdata->cq_cnt) {
-		napi = &pdata->tx_ring->cp_ring->napi;
+	for (i = 0; i < pdata->cq_cnt; i++) {
+		napi = &pdata->tx_ring[i]->cp_ring->napi;
 		napi_enable(napi);
 	}
 }
@@ -677,12 +693,15 @@ static void xgene_enet_napi_enable(struc
 static void xgene_enet_napi_disable(struct xgene_enet_pdata *pdata)
 {
 	struct napi_struct *napi;
+	int i;
 
-	napi = &pdata->rx_ring->napi;
-	napi_disable(napi);
+	for (i = 0; i < pdata->rxq_cnt; i++) {
+		napi = &pdata->rx_ring[i]->napi;
+		napi_disable(napi);
+	}
 
-	if (pdata->cq_cnt) {
-		napi = &pdata->tx_ring->cp_ring->napi;
+	for (i = 0; i < pdata->cq_cnt; i++) {
+		napi = &pdata->tx_ring[i]->cp_ring->napi;
 		napi_disable(napi);
 	}
 }
@@ -693,6 +712,14 @@ static int xgene_enet_open(struct net_de
 	struct xgene_mac_ops *mac_ops = pdata->mac_ops;
 	int ret;
 
+	ret = netif_set_real_num_tx_queues(ndev, pdata->txq_cnt);
+	if (ret)
+		return ret;
+
+	ret = netif_set_real_num_rx_queues(ndev, pdata->rxq_cnt);
+	if (ret)
+		return ret;
+
 	mac_ops->tx_enable(pdata);
 	mac_ops->rx_enable(pdata);
 
@@ -715,6 +742,7 @@ static int xgene_enet_close(struct net_d
 {
 	struct xgene_enet_pdata *pdata = netdev_priv(ndev);
 	struct xgene_mac_ops *mac_ops = pdata->mac_ops;
+	int i;
 
 	netif_stop_queue(ndev);
 
@@ -728,7 +756,8 @@ static int xgene_enet_close(struct net_d
 
 	xgene_enet_free_irq(ndev);
 	xgene_enet_napi_disable(pdata);
-	xgene_enet_process_ring(pdata->rx_ring, -1);
+	for (i = 0; i < pdata->rxq_cnt; i++)
+		xgene_enet_process_ring(pdata->rx_ring[i], -1);
 
 	return 0;
 }
@@ -748,18 +777,26 @@ static void xgene_enet_delete_ring(struc
 static void xgene_enet_delete_desc_rings(struct xgene_enet_pdata *pdata)
 {
 	struct xgene_enet_desc_ring *buf_pool;
+	struct xgene_enet_desc_ring *ring;
+	int i;
 
-	if (pdata->tx_ring) {
-		xgene_enet_delete_ring(pdata->tx_ring);
-		pdata->tx_ring = NULL;
+	for (i = 0; i < pdata->txq_cnt; i++) {
+		ring = pdata->tx_ring[i];
+		if (ring) {
+			xgene_enet_delete_ring(ring);
+			pdata->tx_ring[i] = NULL;
+		}
 	}
 
-	if (pdata->rx_ring) {
-		buf_pool = pdata->rx_ring->buf_pool;
-		xgene_enet_delete_bufpool(buf_pool);
-		xgene_enet_delete_ring(buf_pool);
-		xgene_enet_delete_ring(pdata->rx_ring);
-		pdata->rx_ring = NULL;
+	for (i = 0; i < pdata->rxq_cnt; i++) {
+		ring = pdata->rx_ring[i];
+		if (ring) {
+			buf_pool = ring->buf_pool;
+			xgene_enet_delete_bufpool(buf_pool);
+			xgene_enet_delete_ring(buf_pool);
+			xgene_enet_delete_ring(ring);
+			pdata->rx_ring[i] = NULL;
+		}
 	}
 }
 
@@ -814,24 +851,29 @@ static void xgene_enet_free_desc_rings(s
 {
 	struct device *dev = &pdata->pdev->dev;
 	struct xgene_enet_desc_ring *ring;
+	int i;
 
-	ring = pdata->tx_ring;
-	if (ring) {
-		if (ring->cp_ring && ring->cp_ring->cp_skb)
-			devm_kfree(dev, ring->cp_ring->cp_skb);
-		if (ring->cp_ring && pdata->cq_cnt)
-			xgene_enet_free_desc_ring(ring->cp_ring);
-		xgene_enet_free_desc_ring(ring);
-	}
-
-	ring = pdata->rx_ring;
-	if (ring) {
-		if (ring->buf_pool) {
-			if (ring->buf_pool->rx_skb)
-				devm_kfree(dev, ring->buf_pool->rx_skb);
-			xgene_enet_free_desc_ring(ring->buf_pool);
+	for (i = 0; i < pdata->txq_cnt; i++) {
+		ring = pdata->tx_ring[i];
+		if (ring) {
+			if (ring->cp_ring && ring->cp_ring->cp_skb)
+				devm_kfree(dev, ring->cp_ring->cp_skb);
+			if (ring->cp_ring && pdata->cq_cnt)
+				xgene_enet_free_desc_ring(ring->cp_ring);
+			xgene_enet_free_desc_ring(ring);
+		}
+	}
+
+	for (i = 0; i < pdata->rxq_cnt; i++) {
+		ring = pdata->rx_ring[i];
+		if (ring) {
+			if (ring->buf_pool) {
+				if (ring->buf_pool->rx_skb)
+					devm_kfree(dev, ring->buf_pool->rx_skb);
+				xgene_enet_free_desc_ring(ring->buf_pool);
+			}
+			xgene_enet_free_desc_ring(ring);
 		}
-		xgene_enet_free_desc_ring(ring);
 	}
 }
 
@@ -944,104 +986,120 @@ static int xgene_enet_create_desc_rings(
 	u8 bp_bufnum = pdata->bp_bufnum;
 	u16 ring_num = pdata->ring_num;
 	u16 ring_id;
-	int ret, size;
+	int i, ret, size;
 
-	/* allocate rx descriptor ring */
-	owner = xgene_derive_ring_owner(pdata);
-	ring_id = xgene_enet_get_ring_id(RING_OWNER_CPU, cpu_bufnum++);
-	rx_ring = xgene_enet_create_desc_ring(ndev, ring_num++,
-					      RING_CFGSIZE_16KB, ring_id);
-	if (!rx_ring) {
-		ret = -ENOMEM;
-		goto err;
-	}
-
-	/* allocate buffer pool for receiving packets */
-	owner = xgene_derive_ring_owner(pdata);
-	ring_id = xgene_enet_get_ring_id(owner, bp_bufnum++);
-	buf_pool = xgene_enet_create_desc_ring(ndev, ring_num++,
-					       RING_CFGSIZE_2KB, ring_id);
-	if (!buf_pool) {
-		ret = -ENOMEM;
-		goto err;
-	}
-
-	rx_ring->nbufpool = NUM_BUFPOOL;
-	rx_ring->buf_pool = buf_pool;
-	rx_ring->irq = pdata->rx_irq;
-	if (!pdata->cq_cnt) {
-		snprintf(rx_ring->irq_name, IRQ_ID_SIZE, "%s-rx-txc",
-			 ndev->name);
-	} else {
-		snprintf(rx_ring->irq_name, IRQ_ID_SIZE, "%s-rx", ndev->name);
-	}
-	buf_pool->rx_skb = devm_kcalloc(dev, buf_pool->slots,
-					sizeof(struct sk_buff *), GFP_KERNEL);
-	if (!buf_pool->rx_skb) {
-		ret = -ENOMEM;
-		goto err;
-	}
-
-	buf_pool->dst_ring_num = xgene_enet_dst_ring_num(buf_pool);
-	rx_ring->buf_pool = buf_pool;
-	pdata->rx_ring = rx_ring;
-
-	/* allocate tx descriptor ring */
-	owner = xgene_derive_ring_owner(pdata);
-	ring_id = xgene_enet_get_ring_id(owner, eth_bufnum++);
-	tx_ring = xgene_enet_create_desc_ring(ndev, ring_num++,
-					      RING_CFGSIZE_16KB, ring_id);
-	if (!tx_ring) {
-		ret = -ENOMEM;
-		goto err;
-	}
+	for (i = 0; i < pdata->rxq_cnt; i++) {
+		/* allocate rx descriptor ring */
+		owner = xgene_derive_ring_owner(pdata);
+		ring_id = xgene_enet_get_ring_id(RING_OWNER_CPU, cpu_bufnum++);
+		rx_ring = xgene_enet_create_desc_ring(ndev, ring_num++,
+						      RING_CFGSIZE_16KB,
+						      ring_id);
+		if (!rx_ring) {
+			ret = -ENOMEM;
+			goto err;
+		}
+
+		/* allocate buffer pool for receiving packets */
+		owner = xgene_derive_ring_owner(pdata);
+		ring_id = xgene_enet_get_ring_id(owner, bp_bufnum++);
+		buf_pool = xgene_enet_create_desc_ring(ndev, ring_num++,
+						       RING_CFGSIZE_2KB,
+						       ring_id);
+		if (!buf_pool) {
+			ret = -ENOMEM;
+			goto err;
+		}
 
-	size = (tx_ring->slots / 2) * sizeof(__le64) * MAX_EXP_BUFFS;
-	tx_ring->exp_bufs = dma_zalloc_coherent(dev, size, &dma_exp_bufs,
+		rx_ring->nbufpool = NUM_BUFPOOL;
+		rx_ring->buf_pool = buf_pool;
+		rx_ring->irq = pdata->irqs[i];
+		if (!pdata->cq_cnt) {
+			snprintf(rx_ring->irq_name, IRQ_ID_SIZE, "%s-rx-txc",
+				 ndev->name);
+		} else {
+			snprintf(rx_ring->irq_name, IRQ_ID_SIZE, "%s-rx%d",
+				 ndev->name, i);
+		}
+		buf_pool->rx_skb = devm_kcalloc(dev, buf_pool->slots,
+						sizeof(struct sk_buff *),
 						GFP_KERNEL);
-	if (!tx_ring->exp_bufs) {
-		ret = -ENOMEM;
-		goto err;
-	}
+		if (!buf_pool->rx_skb) {
+			ret = -ENOMEM;
+			goto err;
+		}
 
-	pdata->tx_ring = tx_ring;
+		buf_pool->dst_ring_num = xgene_enet_dst_ring_num(buf_pool);
+		rx_ring->buf_pool = buf_pool;
+		pdata->rx_ring[i] = rx_ring;
+	}
 
-	if (!pdata->cq_cnt) {
-		cp_ring = pdata->rx_ring;
-	} else {
-		/* allocate tx completion descriptor ring */
-		ring_id = xgene_enet_get_ring_id(RING_OWNER_CPU, cpu_bufnum++);
-		cp_ring = xgene_enet_create_desc_ring(ndev, ring_num++,
+	for (i = 0; i < pdata->txq_cnt; i++) {
+		/* allocate tx descriptor ring */
+		owner = xgene_derive_ring_owner(pdata);
+		ring_id = xgene_enet_get_ring_id(owner, eth_bufnum++);
+		tx_ring = xgene_enet_create_desc_ring(ndev, ring_num++,
 						      RING_CFGSIZE_16KB,
 						      ring_id);
-		if (!cp_ring) {
+		if (!tx_ring) {
 			ret = -ENOMEM;
 			goto err;
 		}
-		cp_ring->irq = pdata->txc_irq;
-		snprintf(cp_ring->irq_name, IRQ_ID_SIZE, "%s-txc", ndev->name);
-	}
 
-	cp_ring->cp_skb = devm_kcalloc(dev, tx_ring->slots,
-				       sizeof(struct sk_buff *), GFP_KERNEL);
-	if (!cp_ring->cp_skb) {
-		ret = -ENOMEM;
-		goto err;
-	}
+		size = (tx_ring->slots / 2) * sizeof(__le64) * MAX_EXP_BUFFS;
+		tx_ring->exp_bufs = dma_zalloc_coherent(dev, size,
+							&dma_exp_bufs,
+							GFP_KERNEL);
+		if (!tx_ring->exp_bufs) {
+			ret = -ENOMEM;
+			goto err;
+		}
 
-	size = sizeof(dma_addr_t) * MAX_SKB_FRAGS;
-	cp_ring->frag_dma_addr = devm_kcalloc(dev, tx_ring->slots,
-					      size, GFP_KERNEL);
-	if (!cp_ring->frag_dma_addr) {
-		devm_kfree(dev, cp_ring->cp_skb);
-		ret = -ENOMEM;
-		goto err;
-	}
+		pdata->tx_ring[i] = tx_ring;
 
-	pdata->tx_ring->cp_ring = cp_ring;
-	pdata->tx_ring->dst_ring_num = xgene_enet_dst_ring_num(cp_ring);
+		if (!pdata->cq_cnt) {
+			cp_ring = pdata->rx_ring[i];
+		} else {
+			/* allocate tx completion descriptor ring */
+			ring_id = xgene_enet_get_ring_id(RING_OWNER_CPU,
+							 cpu_bufnum++);
+			cp_ring = xgene_enet_create_desc_ring(ndev, ring_num++,
+							      RING_CFGSIZE_16KB,
+							      ring_id);
+			if (!cp_ring) {
+				ret = -ENOMEM;
+				goto err;
+			}
 
-	pdata->tx_qcnt_hi = pdata->tx_ring->slots - 128;
+			cp_ring->irq = pdata->irqs[pdata->rxq_cnt + i];
+			cp_ring->index = i;
+			snprintf(cp_ring->irq_name, IRQ_ID_SIZE, "%s-txc%d",
+				 ndev->name, i);
+		}
+
+		cp_ring->cp_skb = devm_kcalloc(dev, tx_ring->slots,
+					       sizeof(struct sk_buff *),
+					       GFP_KERNEL);
+		if (!cp_ring->cp_skb) {
+			ret = -ENOMEM;
+			goto err;
+		}
+
+		size = sizeof(dma_addr_t) * MAX_SKB_FRAGS;
+		cp_ring->frag_dma_addr = devm_kcalloc(dev, tx_ring->slots,
+						      size, GFP_KERNEL);
+		if (!cp_ring->frag_dma_addr) {
+			devm_kfree(dev, cp_ring->cp_skb);
+			ret = -ENOMEM;
+			goto err;
+		}
+
+		tx_ring->cp_ring = cp_ring;
+		tx_ring->dst_ring_num = xgene_enet_dst_ring_num(cp_ring);
+	}
+
+	pdata->ring_ops->coalesce(pdata->tx_ring[0]);
+	pdata->tx_qcnt_hi = pdata->tx_ring[0]->slots - 128;
 
 	return 0;
 
@@ -1165,6 +1223,32 @@ static int xgene_get_rx_delay(struct xge
 	return 0;
 }
 
+static int xgene_enet_get_irqs(struct xgene_enet_pdata *pdata)
+{
+	struct platform_device *pdev = pdata->pdev;
+	struct device *dev = &pdev->dev;
+	int i, ret, max_irqs;
+
+	if (pdata->phy_mode == PHY_INTERFACE_MODE_RGMII)
+		max_irqs = 1;
+	else if (pdata->phy_mode == PHY_INTERFACE_MODE_SGMII)
+		max_irqs = 2;
+	else
+		max_irqs = XGENE_MAX_ENET_IRQ;
+
+	for (i = 0; i < max_irqs; i++) {
+		ret = platform_get_irq(pdev, i);
+		if (ret <= 0) {
+			dev_err(dev, "Unable to get ENET IRQ\n");
+			ret = ret ? : -ENXIO;
+			return ret;
+		}
+		pdata->irqs[i] = ret;
+	}
+
+	return 0;
+}
+
 static int xgene_enet_get_resources(struct xgene_enet_pdata *pdata)
 {
 	struct platform_device *pdev;
@@ -1248,25 +1332,9 @@ static int xgene_enet_get_resources(stru
 	if (ret)
 		return ret;
 
-	ret = platform_get_irq(pdev, 0);
-	if (ret <= 0) {
-		dev_err(dev, "Unable to get ENET Rx IRQ\n");
-		ret = ret ? : -ENXIO;
+	ret = xgene_enet_get_irqs(pdata);
+	if (ret)
 		return ret;
-	}
-	pdata->rx_irq = ret;
-
-	if (pdata->phy_mode != PHY_INTERFACE_MODE_RGMII) {
-		ret = platform_get_irq(pdev, 1);
-		if (ret <= 0) {
-			pdata->cq_cnt = 0;
-			dev_info(dev, "Unable to get Tx completion IRQ,"
-				 "using Rx IRQ instead\n");
-		} else {
-			pdata->cq_cnt = XGENE_MAX_TXC_RINGS;
-			pdata->txc_irq = ret;
-		}
-	}
 
 	pdata->clk = devm_clk_get(&pdev->dev, NULL);
 	if (IS_ERR(pdata->clk)) {
@@ -1279,6 +1347,7 @@ static int xgene_enet_get_resources(stru
 	else
 		base_addr = pdata->base_addr;
 	pdata->eth_csr_addr = base_addr + BLOCK_ETH_CSR_OFFSET;
+	pdata->cle.base = base_addr + BLOCK_ETH_CLE_CSR_OFFSET;
 	pdata->eth_ring_if_addr = base_addr + BLOCK_ETH_RING_IF_OFFSET;
 	pdata->eth_diag_csr_addr = base_addr + BLOCK_ETH_DIAG_CSR_OFFSET;
 	if (pdata->phy_mode == PHY_INTERFACE_MODE_RGMII ||
@@ -1299,10 +1368,11 @@ static int xgene_enet_get_resources(stru
 
 static int xgene_enet_init_hw(struct xgene_enet_pdata *pdata)
 {
+	struct xgene_enet_cle *enet_cle = &pdata->cle;
 	struct net_device *ndev = pdata->ndev;
 	struct xgene_enet_desc_ring *buf_pool;
 	u16 dst_ring_num;
-	int ret;
+	int i, ret;
 
 	ret = pdata->port_ops->reset(pdata);
 	if (ret)
@@ -1315,16 +1385,36 @@ static int xgene_enet_init_hw(struct xge
 	}
 
 	/* setup buffer pool */
-	buf_pool = pdata->rx_ring->buf_pool;
-	xgene_enet_init_bufpool(buf_pool);
-	ret = xgene_enet_refill_bufpool(buf_pool, pdata->rx_buff_cnt);
-	if (ret) {
-		xgene_enet_delete_desc_rings(pdata);
-		return ret;
+	for (i = 0; i < pdata->rxq_cnt; i++) {
+		buf_pool = pdata->rx_ring[i]->buf_pool;
+		xgene_enet_init_bufpool(buf_pool);
+		ret = xgene_enet_refill_bufpool(buf_pool, pdata->rx_buff_cnt);
+		if (ret) {
+			xgene_enet_delete_desc_rings(pdata);
+			return ret;
+		}
+	}
+
+	dst_ring_num = xgene_enet_dst_ring_num(pdata->rx_ring[0]);
+	buf_pool = pdata->rx_ring[0]->buf_pool;
+	if (pdata->phy_mode == PHY_INTERFACE_MODE_XGMII) {
+		/* Initialize and Enable  PreClassifier Tree */
+		enet_cle->max_nodes = 512;
+		enet_cle->max_dbptrs = 1024;
+		enet_cle->parsers = 3;
+		enet_cle->active_parser = PARSER_ALL;
+		enet_cle->ptree.start_node = 0;
+		enet_cle->ptree.start_dbptr = 0;
+		enet_cle->jump_bytes = 8;
+		ret = pdata->cle_ops->cle_init(pdata);
+		if (ret) {
+			netdev_err(ndev, "Preclass Tree init error\n");
+			return ret;
+		}
+	} else {
+		pdata->port_ops->cle_bypass(pdata, dst_ring_num, buf_pool->id);
 	}
 
-	dst_ring_num = xgene_enet_dst_ring_num(pdata->rx_ring);
-	pdata->port_ops->cle_bypass(pdata, dst_ring_num, buf_pool->id);
 	pdata->mac_ops->init(pdata);
 
 	return ret;
@@ -1337,16 +1427,26 @@ static void xgene_enet_setup_ops(struct
 		pdata->mac_ops = &xgene_gmac_ops;
 		pdata->port_ops = &xgene_gport_ops;
 		pdata->rm = RM3;
+		pdata->rxq_cnt = 1;
+		pdata->txq_cnt = 1;
+		pdata->cq_cnt = 0;
 		break;
 	case PHY_INTERFACE_MODE_SGMII:
 		pdata->mac_ops = &xgene_sgmac_ops;
 		pdata->port_ops = &xgene_sgport_ops;
 		pdata->rm = RM1;
+		pdata->rxq_cnt = 1;
+		pdata->txq_cnt = 1;
+		pdata->cq_cnt = 1;
 		break;
 	default:
 		pdata->mac_ops = &xgene_xgmac_ops;
 		pdata->port_ops = &xgene_xgport_ops;
+		pdata->cle_ops = &xgene_cle3in_ops;
 		pdata->rm = RM0;
+		pdata->rxq_cnt = XGENE_NUM_RX_RING;
+		pdata->txq_cnt = XGENE_NUM_TX_RING;
+		pdata->cq_cnt = XGENE_NUM_TXC_RING;
 		break;
 	}
 
@@ -1400,12 +1500,16 @@ static void xgene_enet_setup_ops(struct
 static void xgene_enet_napi_add(struct xgene_enet_pdata *pdata)
 {
 	struct napi_struct *napi;
+	int i;
 
-	napi = &pdata->rx_ring->napi;
-	netif_napi_add(pdata->ndev, napi, xgene_enet_napi, NAPI_POLL_WEIGHT);
+	for (i = 0; i < pdata->rxq_cnt; i++) {
+		napi = &pdata->rx_ring[i]->napi;
+		netif_napi_add(pdata->ndev, napi, xgene_enet_napi,
+			       NAPI_POLL_WEIGHT);
+	}
 
-	if (pdata->cq_cnt) {
-		napi = &pdata->tx_ring->cp_ring->napi;
+	for (i = 0; i < pdata->cq_cnt; i++) {
+		napi = &pdata->tx_ring[i]->cp_ring->napi;
 		netif_napi_add(pdata->ndev, napi, xgene_enet_napi,
 			       NAPI_POLL_WEIGHT);
 	}
@@ -1414,12 +1518,15 @@ static void xgene_enet_napi_add(struct x
 static void xgene_enet_napi_del(struct xgene_enet_pdata *pdata)
 {
 	struct napi_struct *napi;
+	int i;
 
-	napi = &pdata->rx_ring->napi;
-	netif_napi_del(napi);
+	for (i = 0; i < pdata->rxq_cnt; i++) {
+		napi = &pdata->rx_ring[i]->napi;
+		netif_napi_del(napi);
+	}
 
-	if (pdata->cq_cnt) {
-		napi = &pdata->tx_ring->cp_ring->napi;
+	for (i = 0; i < pdata->cq_cnt; i++) {
+		napi = &pdata->tx_ring[i]->cp_ring->napi;
 		netif_napi_del(napi);
 	}
 }
@@ -1433,7 +1540,8 @@ static int xgene_enet_probe(struct platf
 	const struct of_device_id *of_id;
 	int ret;
 
-	ndev = alloc_etherdev(sizeof(struct xgene_enet_pdata));
+	ndev = alloc_etherdev_mqs(sizeof(struct xgene_enet_pdata),
+				  XGENE_NUM_RX_RING, XGENE_NUM_TX_RING);
 	if (!ndev)
 		return -ENOMEM;
 
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/apm/xgene/xgene_enet_main.h
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/apm/xgene/xgene_enet_main.h
@@ -25,6 +25,7 @@
 #include <linux/acpi.h>
 #include <linux/clk.h>
 #include <linux/efi.h>
+#include <linux/irq.h>
 #include <linux/io.h>
 #include <linux/of_platform.h>
 #include <linux/of_net.h>
@@ -35,6 +36,7 @@
 #include <linux/if_vlan.h>
 #include <linux/phy.h>
 #include "xgene_enet_hw.h"
+#include "xgene_enet_cle.h"
 #include "xgene_enet_ring2.h"
 
 #define XGENE_DRV_VERSION	"v1.0"
@@ -47,6 +49,11 @@
 #define XGENE_ENET_MSS	1448
 #define XGENE_MIN_ENET_FRAME_SIZE	60
 
+#define XGENE_MAX_ENET_IRQ	8
+#define XGENE_NUM_RX_RING	4
+#define XGENE_NUM_TX_RING	4
+#define XGENE_NUM_TXC_RING	4
+
 #define START_CPU_BUFNUM_0	0
 #define START_ETH_BUFNUM_0	2
 #define START_BP_BUFNUM_0	0x22
@@ -71,7 +78,6 @@
 #define X2_START_RING_NUM_1	256
 
 #define IRQ_ID_SIZE		16
-#define XGENE_MAX_TXC_RINGS	1
 
 #define PHY_POLL_LINK_ON	(10 * HZ)
 #define PHY_POLL_LINK_OFF	(PHY_POLL_LINK_ON / 5)
@@ -101,6 +107,7 @@ struct xgene_enet_desc_ring {
 	void *irq_mbox_addr;
 	u16 dst_ring_num;
 	u8 nbufpool;
+	u8 index;
 	struct sk_buff *(*rx_skb);
 	struct sk_buff *(*cp_skb);
 	dma_addr_t *frag_dma_addr;
@@ -142,6 +149,11 @@ struct xgene_ring_ops {
 	void (*clear)(struct xgene_enet_desc_ring *);
 	void (*wr_cmd)(struct xgene_enet_desc_ring *, int);
 	u32 (*len)(struct xgene_enet_desc_ring *);
+	void (*coalesce)(struct xgene_enet_desc_ring *);
+};
+
+struct xgene_cle_ops {
+	int (*cle_init)(struct xgene_enet_pdata *pdata);
 };
 
 /* ethernet private data */
@@ -153,15 +165,16 @@ struct xgene_enet_pdata {
 	struct clk *clk;
 	struct platform_device *pdev;
 	enum xgene_enet_id enet_id;
-	struct xgene_enet_desc_ring *tx_ring;
-	struct xgene_enet_desc_ring *rx_ring;
-	u16 tx_level;
-	u16 txc_level;
+	struct xgene_enet_desc_ring *tx_ring[XGENE_NUM_TX_RING];
+	struct xgene_enet_desc_ring *rx_ring[XGENE_NUM_RX_RING];
+	u16 tx_level[XGENE_NUM_TX_RING];
+	u16 txc_level[XGENE_NUM_TX_RING];
 	char *dev_name;
 	u32 rx_buff_cnt;
 	u32 tx_qcnt_hi;
-	u32 rx_irq;
-	u32 txc_irq;
+	u32 irqs[XGENE_MAX_ENET_IRQ];
+	u8 rxq_cnt;
+	u8 txq_cnt;
 	u8 cq_cnt;
 	void __iomem *eth_csr_addr;
 	void __iomem *eth_ring_if_addr;
@@ -173,10 +186,12 @@ struct xgene_enet_pdata {
 	void __iomem *ring_cmd_addr;
 	int phy_mode;
 	enum xgene_enet_rm rm;
+	struct xgene_enet_cle cle;
 	struct rtnl_link_stats64 stats;
 	struct xgene_mac_ops *mac_ops;
 	struct xgene_port_ops *port_ops;
 	struct xgene_ring_ops *ring_ops;
+	struct xgene_cle_ops *cle_ops;
 	struct delayed_work link_work;
 	u32 port_id;
 	u8 cpu_bufnum;
@@ -228,6 +243,13 @@ static inline struct device *ndev_to_dev
 	return ndev->dev.parent;
 }
 
+static inline u16 xgene_enet_dst_ring_num(struct xgene_enet_desc_ring *ring)
+{
+	struct xgene_enet_pdata *pdata = netdev_priv(ring->ndev);
+
+	return ((u16)pdata->rm << 10) | ring->num;
+}
+
 void xgene_enet_set_ethtool_ops(struct net_device *netdev);
 
 #endif /* __XGENE_ENET_MAIN_H__ */
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/apm/xgene/xgene_enet_ring2.c
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/apm/xgene/xgene_enet_ring2.c
@@ -190,6 +190,17 @@ static u32 xgene_enet_ring_len(struct xg
 	return num_msgs;
 }
 
+static void xgene_enet_setup_coalescing(struct xgene_enet_desc_ring *ring)
+{
+	u32 data = 0x7777;
+
+	xgene_enet_ring_wr32(ring, CSR_PBM_COAL, 0x8e);
+	xgene_enet_ring_wr32(ring, CSR_PBM_CTICK1, data);
+	xgene_enet_ring_wr32(ring, CSR_PBM_CTICK2, data << 16);
+	xgene_enet_ring_wr32(ring, CSR_THRESHOLD0_SET1, 0x40);
+	xgene_enet_ring_wr32(ring, CSR_THRESHOLD1_SET1, 0x80);
+}
+
 struct xgene_ring_ops xgene_ring2_ops = {
 	.num_ring_config = X2_NUM_RING_CONFIG,
 	.num_ring_id_shift = 13,
@@ -197,4 +208,5 @@ struct xgene_ring_ops xgene_ring2_ops =
 	.clear = xgene_enet_clear_ring,
 	.wr_cmd = xgene_enet_wr_cmd,
 	.len = xgene_enet_ring_len,
+	.coalesce = xgene_enet_setup_coalescing,
 };
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/atheros/alx/main.c
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/atheros/alx/main.c
@@ -86,9 +86,14 @@ static int alx_refill_rx_ring(struct alx
 	while (!cur_buf->skb && next != rxq->read_idx) {
 		struct alx_rfd *rfd = &rxq->rfd[cur];
 
-		skb = __netdev_alloc_skb(alx->dev, alx->rxbuf_size, gfp);
+		skb = __netdev_alloc_skb(alx->dev, alx->rxbuf_size + 64, gfp);
 		if (!skb)
 			break;
+
+		/* Workround for the HW RX DMA overflow issue */
+		if (((unsigned long)skb->data & 0xfff) == 0xfc0)
+			skb_reserve(skb, 64);
+
 		dma = dma_map_single(&alx->hw.pdev->dev,
 				     skb->data, alx->rxbuf_size,
 				     DMA_FROM_DEVICE);
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/atheros/atlx/atl2.c
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/atheros/atlx/atl2.c
@@ -1412,7 +1412,7 @@ static int atl2_probe(struct pci_dev *pd
 
 	err = -EIO;
 
-	netdev->hw_features = NETIF_F_SG | NETIF_F_HW_VLAN_CTAG_RX;
+	netdev->hw_features = NETIF_F_HW_VLAN_CTAG_RX;
 	netdev->features |= (NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_CTAG_RX);
 
 	/* Init PHY as early as possible due to power saving issue  */
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/broadcom/bgmac.c
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/broadcom/bgmac.c
@@ -219,7 +219,7 @@ err_dma:
 	dma_unmap_single(dma_dev, slot->dma_addr, skb_headlen(skb),
 			 DMA_TO_DEVICE);
 
-	while (i > 0) {
+	while (i-- > 0) {
 		int index = (ring->end + i) % BGMAC_TX_RING_SLOTS;
 		struct bgmac_slot_info *slot = &ring->slots[index];
 		u32 ctl1 = le32_to_cpu(ring->cpu_base[index].ctl1);
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
@@ -4332,6 +4332,14 @@ int bnx2x_setup_tc(struct net_device *de
 	return 0;
 }
 
+int __bnx2x_setup_tc(struct net_device *dev, u32 handle, __be16 proto,
+		     struct tc_to_netdev *tc)
+{
+	if (handle != TC_H_ROOT || tc->type != TC_SETUP_MQPRIO)
+		return -EINVAL;
+	return bnx2x_setup_tc(dev, tc->tc);
+}
+
 /* called with rtnl_lock */
 int bnx2x_change_mac_addr(struct net_device *dev, void *p)
 {
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h
@@ -486,6 +486,8 @@ netdev_tx_t bnx2x_start_xmit(struct sk_b
 
 /* setup_tc callback */
 int bnx2x_setup_tc(struct net_device *dev, u8 num_tc);
+int __bnx2x_setup_tc(struct net_device *dev, u32 handle, __be16 proto,
+		     struct tc_to_netdev *tc);
 
 int bnx2x_get_vf_config(struct net_device *dev, int vf,
 			struct ifla_vf_info *ivi);
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
@@ -12994,7 +12994,7 @@ static const struct net_device_ops bnx2x
 #ifdef CONFIG_NET_POLL_CONTROLLER
 	.ndo_poll_controller	= poll_bnx2x,
 #endif
-	.ndo_setup_tc		= bnx2x_setup_tc,
+	.ndo_setup_tc		= __bnx2x_setup_tc,
 #ifdef CONFIG_BNX2X_SRIOV
 	.ndo_set_vf_mac		= bnx2x_set_vf_mac,
 	.ndo_set_vf_vlan	= bnx2x_set_vf_vlan,
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/broadcom/bnxt/bnxt.c
@@ -5280,9 +5280,16 @@ static int bnxt_change_mtu(struct net_de
 	return 0;
 }
 
-static int bnxt_setup_tc(struct net_device *dev, u8 tc)
+static int bnxt_setup_tc(struct net_device *dev, u32 handle, __be16 proto,
+			 struct tc_to_netdev *ntc)
 {
 	struct bnxt *bp = netdev_priv(dev);
+	u8 tc;
+
+	if (handle != TC_H_ROOT || ntc->type != TC_SETUP_MQPRIO)
+		return -EINVAL;
+
+	tc = ntc->tc;
 
 	if (tc > bp->max_tc) {
 		netdev_err(dev, "too many traffic classes requested: %d Max supported is %d\n",
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/broadcom/genet/bcmgenet.c
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/broadcom/genet/bcmgenet.c
@@ -1197,7 +1197,7 @@ static unsigned int __bcmgenet_tx_reclai
 			dev->stats.tx_bytes += tx_cb_ptr->skb->len;
 			dma_unmap_single(&dev->dev,
 					 dma_unmap_addr(tx_cb_ptr, dma_addr),
-					 tx_cb_ptr->skb->len,
+					 dma_unmap_len(tx_cb_ptr, dma_len),
 					 DMA_TO_DEVICE);
 			bcmgenet_free_cb(tx_cb_ptr);
 		} else if (dma_unmap_addr(tx_cb_ptr, dma_addr)) {
@@ -1308,7 +1308,7 @@ static int bcmgenet_xmit_single(struct n
 	}
 
 	dma_unmap_addr_set(tx_cb_ptr, dma_addr, mapping);
-	dma_unmap_len_set(tx_cb_ptr, dma_len, skb->len);
+	dma_unmap_len_set(tx_cb_ptr, dma_len, skb_len);
 	length_status = (skb_len << DMA_BUFLENGTH_SHIFT) | dma_desc_flags |
 			(priv->hw_params->qtag_mask << DMA_TX_QTAG_SHIFT) |
 			DMA_TX_APPEND_CRC;
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/broadcom/tg3.c
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/broadcom/tg3.c
@@ -329,6 +329,7 @@ static const struct pci_device_id tg3_pc
 	{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57785)},
 	{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57761)},
 	{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57765)},
+	{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57786)},
 	{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57791),
 	 .driver_data = TG3_DRV_DATA_FLAG_10_100_ONLY},
 	{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57795),
@@ -7833,6 +7834,14 @@ static int tigon3_dma_hwbug_workaround(s
 	return ret;
 }
 
+static bool tg3_tso_bug_gso_check(struct tg3_napi *tnapi, struct sk_buff *skb)
+{
+	/* Check if we will never have enough descriptors,
+	 * as gso_segs can be more than current ring size
+	 */
+	return skb_shinfo(skb)->gso_segs < tnapi->tx_pending / 3;
+}
+
 static netdev_tx_t tg3_start_xmit(struct sk_buff *, struct net_device *);
 
 /* Use GSO to workaround all TSO packets that meet HW bug conditions
@@ -7936,14 +7945,19 @@ static netdev_tx_t tg3_start_xmit(struct
 		 * vlan encapsulated.
 		 */
 		if (skb->protocol == htons(ETH_P_8021Q) ||
-		    skb->protocol == htons(ETH_P_8021AD))
-			return tg3_tso_bug(tp, tnapi, txq, skb);
+		    skb->protocol == htons(ETH_P_8021AD)) {
+			if (tg3_tso_bug_gso_check(tnapi, skb))
+				return tg3_tso_bug(tp, tnapi, txq, skb);
+			goto drop;
+		}
 
 		if (!skb_is_gso_v6(skb)) {
 			if (unlikely((ETH_HLEN + hdr_len) > 80) &&
-			    tg3_flag(tp, TSO_BUG))
-				return tg3_tso_bug(tp, tnapi, txq, skb);
-
+			    tg3_flag(tp, TSO_BUG)) {
+				if (tg3_tso_bug_gso_check(tnapi, skb))
+					return tg3_tso_bug(tp, tnapi, txq, skb);
+				goto drop;
+			}
 			ip_csum = iph->check;
 			ip_tot_len = iph->tot_len;
 			iph->check = 0;
@@ -8075,7 +8089,7 @@ static netdev_tx_t tg3_start_xmit(struct
 	if (would_hit_hwbug) {
 		tg3_tx_skb_unmap(tnapi, tnapi->tx_prod, i);
 
-		if (mss) {
+		if (mss && tg3_tso_bug_gso_check(tnapi, skb)) {
 			/* If it's a TSO packet, do GSO instead of
 			 * allocating and copying to a large linear SKB
 			 */
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/cadence/macb.c
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/cadence/macb.c
@@ -2405,9 +2405,9 @@ static int macb_init(struct platform_dev
 	if (bp->phy_interface == PHY_INTERFACE_MODE_RGMII)
 		val = GEM_BIT(RGMII);
 	else if (bp->phy_interface == PHY_INTERFACE_MODE_RMII &&
-		 (bp->caps & MACB_CAPS_USRIO_DEFAULT_IS_MII))
+		 (bp->caps & MACB_CAPS_USRIO_DEFAULT_IS_MII_GMII))
 		val = MACB_BIT(RMII);
-	else if (!(bp->caps & MACB_CAPS_USRIO_DEFAULT_IS_MII))
+	else if (!(bp->caps & MACB_CAPS_USRIO_DEFAULT_IS_MII_GMII))
 		val = MACB_BIT(MII);
 
 	if (bp->caps & MACB_CAPS_USRIO_HAS_CLKEN)
@@ -2738,7 +2738,7 @@ static int at91ether_init(struct platfor
 }
 
 static const struct macb_config at91sam9260_config = {
-	.caps = MACB_CAPS_USRIO_HAS_CLKEN | MACB_CAPS_USRIO_DEFAULT_IS_MII,
+	.caps = MACB_CAPS_USRIO_HAS_CLKEN | MACB_CAPS_USRIO_DEFAULT_IS_MII_GMII,
 	.clk_init = macb_clk_init,
 	.init = macb_init,
 };
@@ -2751,21 +2751,22 @@ static const struct macb_config pc302gem
 };
 
 static const struct macb_config sama5d2_config = {
-	.caps = 0,
+	.caps = MACB_CAPS_USRIO_DEFAULT_IS_MII_GMII,
 	.dma_burst_length = 16,
 	.clk_init = macb_clk_init,
 	.init = macb_init,
 };
 
 static const struct macb_config sama5d3_config = {
-	.caps = MACB_CAPS_SG_DISABLED | MACB_CAPS_GIGABIT_MODE_AVAILABLE,
+	.caps = MACB_CAPS_SG_DISABLED | MACB_CAPS_GIGABIT_MODE_AVAILABLE
+	      | MACB_CAPS_USRIO_DEFAULT_IS_MII_GMII,
 	.dma_burst_length = 16,
 	.clk_init = macb_clk_init,
 	.init = macb_init,
 };
 
 static const struct macb_config sama5d4_config = {
-	.caps = 0,
+	.caps = MACB_CAPS_USRIO_DEFAULT_IS_MII_GMII,
 	.dma_burst_length = 4,
 	.clk_init = macb_clk_init,
 	.init = macb_init,
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/cadence/macb.h
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/cadence/macb.h
@@ -398,7 +398,7 @@
 /* Capability mask bits */
 #define MACB_CAPS_ISR_CLEAR_ON_WRITE		0x00000001
 #define MACB_CAPS_USRIO_HAS_CLKEN		0x00000002
-#define MACB_CAPS_USRIO_DEFAULT_IS_MII		0x00000004
+#define MACB_CAPS_USRIO_DEFAULT_IS_MII_GMII	0x00000004
 #define MACB_CAPS_NO_GIGABIT_HALF		0x00000008
 #define MACB_CAPS_FIFO_MODE			0x10000000
 #define MACB_CAPS_GIGABIT_MODE_AVAILABLE	0x20000000
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/cavium/Kconfig
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/cavium/Kconfig
@@ -35,7 +35,7 @@ config	THUNDER_NIC_BGX
 	tristate "Thunder MAC interface driver (BGX)"
 	depends on 64BIT
 	select PHYLIB
-	select MDIO_OCTEON
+	select MDIO_THUNDER
 	---help---
 	  This driver supports programming and controlling of MAC
 	  interface from NIC physical function driver.
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/cavium/liquidio/lio_main.c
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/cavium/liquidio/lio_main.c
@@ -1526,7 +1526,6 @@ static int liquidio_ptp_gettime(struct p
 				struct timespec64 *ts)
 {
 	u64 ns;
-	u32 remainder;
 	unsigned long flags;
 	struct lio *lio = container_of(ptp, struct lio, ptp_info);
 	struct octeon_device *oct = (struct octeon_device *)lio->oct_dev;
@@ -1536,8 +1535,7 @@ static int liquidio_ptp_gettime(struct p
 	ns += lio->ptp_adjust;
 	spin_unlock_irqrestore(&lio->ptp_lock, flags);
 
-	ts->tv_sec = div_u64_rem(ns, 1000000000ULL, &remainder);
-	ts->tv_nsec = remainder;
+	*ts = ns_to_timespec64(ns);
 
 	return 0;
 }
@@ -1685,7 +1683,7 @@ static int octeon_setup_droq(struct octe
 	dev_dbg(&oct->pci_dev->dev, "Creating Droq: %d\n", q_no);
 	/* droq creation and local register settings. */
 	ret_val = octeon_create_droq(oct, q_no, num_descs, desc_size, app_ctx);
-	if (ret_val == -1)
+	if (ret_val < 0)
 		return ret_val;
 
 	if (ret_val == 1) {
@@ -2526,7 +2524,7 @@ static void handle_timestamp(struct octe
 
 	octeon_swap_8B_data(&resp->timestamp, 1);
 
-	if (unlikely((skb_shinfo(skb)->tx_flags | SKBTX_IN_PROGRESS) != 0)) {
+	if (unlikely((skb_shinfo(skb)->tx_flags & SKBTX_IN_PROGRESS) != 0)) {
 		struct skb_shared_hwtstamps ts;
 		u64 ns = resp->timestamp;
 
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/cavium/liquidio/octeon_droq.c
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/cavium/liquidio/octeon_droq.c
@@ -983,5 +983,5 @@ int octeon_create_droq(struct octeon_dev
 
 create_droq_fail:
 	octeon_delete_droq(oct, q_no);
-	return -1;
+	return -ENOMEM;
 }
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/cavium/thunder/nic.h
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/cavium/thunder/nic.h
@@ -116,6 +116,15 @@
 #define NIC_PF_INTR_ID_MBOX0		8
 #define NIC_PF_INTR_ID_MBOX1		9
 
+/* Minimum FIFO level before all packets for the CQ are dropped
+ *
+ * This value ensures that once a packet has been "accepted"
+ * for reception it will not get dropped due to non-availability
+ * of CQ descriptor. An errata in HW mandates this value to be
+ * atleast 0x100.
+ */
+#define NICPF_CQM_MIN_DROP_LEVEL       0x100
+
 /* Global timer for CQ timer thresh interrupts
  * Calculated for SCLK of 700Mhz
  * value written should be a 1/16th of what is expected
@@ -248,10 +257,13 @@ struct nicvf_drv_stats {
 	u64 rx_frames_jumbo;
 	u64 rx_drops;
 
+	u64 rcv_buffer_alloc_failures;
+
 	/* Tx */
 	u64 tx_frames_ok;
 	u64 tx_drops;
 	u64 tx_tso;
+	u64 tx_timeout;
 	u64 txq_stop;
 	u64 txq_wake;
 };
@@ -260,44 +272,55 @@ struct nicvf {
 	struct nicvf		*pnicvf;
 	struct net_device	*netdev;
 	struct pci_dev		*pdev;
-	u8			vf_id;
-	u8			node;
-	u8			tns_mode:1;
-	u8			sqs_mode:1;
-	u8			loopback_supported:1;
-	u16			mtu;
+	void __iomem		*reg_base;
 	struct queue_set	*qs;
+	struct nicvf_cq_poll	*napi[8];
+	u8			vf_id;
+	u8			sqs_id;
+	bool                    sqs_mode;
+	bool			hw_tso;
+	bool			t88;
+
+	/* Receive buffer alloc */
+	u32			rb_page_offset;
+	u16			rb_pageref;
+	bool			rb_alloc_fail;
+	bool			rb_work_scheduled;
+	struct page		*rb_page;
+	struct delayed_work	rbdr_work;
+	struct tasklet_struct	rbdr_task;
+
+	/* Secondary Qset */
+	u8			sqs_count;
 #define	MAX_SQS_PER_VF_SINGLE_NODE		5
 #define	MAX_SQS_PER_VF				11
-	u8			sqs_id;
-	u8			sqs_count; /* Secondary Qset count */
 	struct nicvf		*snicvf[MAX_SQS_PER_VF];
+
+	/* Queue count */
 	u8			rx_queues;
 	u8			tx_queues;
 	u8			max_queues;
-	void __iomem		*reg_base;
+
+	u8			node;
+	u8			cpi_alg;
+	u16			mtu;
 	bool			link_up;
 	u8			duplex;
 	u32			speed;
-	struct page		*rb_page;
-	u32			rb_page_offset;
-	bool			rb_alloc_fail;
-	bool			rb_work_scheduled;
-	struct delayed_work	rbdr_work;
-	struct tasklet_struct	rbdr_task;
-	struct tasklet_struct	qs_err_task;
-	struct tasklet_struct	cq_task;
-	struct nicvf_cq_poll	*napi[8];
+	bool			tns_mode;
+	bool			loopback_supported;
 	struct nicvf_rss_info	rss_info;
-	u8			cpi_alg;
+	struct tasklet_struct	qs_err_task;
+	struct work_struct	reset_task;
+
 	/* Interrupt coalescing settings */
 	u32			cq_coalesce_usecs;
-
 	u32			msg_enable;
+
+	/* Stats */
 	struct nicvf_hw_stats   hw_stats;
 	struct nicvf_drv_stats  drv_stats;
 	struct bgx_stats	bgx_stats;
-	struct work_struct	reset_task;
 
 	/* MSI-X  */
 	bool			msix_enabled;
@@ -305,6 +328,7 @@ struct nicvf {
 	struct msix_entry	msix_entries[NIC_VF_MSIX_VECTORS];
 	char			irq_name[NIC_VF_MSIX_VECTORS][20];
 	bool			irq_allocated[NIC_VF_MSIX_VECTORS];
+	cpumask_var_t		affinity_mask[NIC_VF_MSIX_VECTORS];
 
 	/* VF <-> PF mailbox communication */
 	bool			pf_acked;
@@ -489,6 +513,11 @@ static inline int nic_get_node_id(struct
 	return ((addr >> NIC_NODE_ID_SHIFT) & NIC_NODE_ID_MASK);
 }
 
+static inline bool pass1_silicon(struct pci_dev *pdev)
+{
+	return pdev->revision < 8;
+}
+
 int nicvf_set_real_num_queues(struct net_device *netdev,
 			      int tx_queues, int rx_queues);
 int nicvf_open(struct net_device *netdev);
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/cavium/thunder/nic_main.c
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/cavium/thunder/nic_main.c
@@ -54,11 +54,6 @@ struct nicpf {
 	bool			irq_allocated[NIC_PF_MSIX_VECTORS];
 };
 
-static inline bool pass1_silicon(struct nicpf *nic)
-{
-	return nic->pdev->revision < 8;
-}
-
 /* Supported devices */
 static const struct pci_device_id nic_id_table[] = {
 	{ PCI_DEVICE(PCI_VENDOR_ID_CAVIUM, PCI_DEVICE_ID_THUNDER_NIC_PF) },
@@ -122,7 +117,7 @@ static void nic_send_msg_to_vf(struct ni
 	 * when PF writes to MBOX(1), in next revisions when
 	 * PF writes to MBOX(0)
 	 */
-	if (pass1_silicon(nic)) {
+	if (pass1_silicon(nic->pdev)) {
 		/* see the comment for nic_reg_write()/nic_reg_read()
 		 * functions above
 		 */
@@ -256,9 +251,14 @@ static void nic_set_tx_pkt_pad(struct ni
 	int lmac;
 	u64 lmac_cfg;
 
-	/* Max value that can be set is 60 */
-	if (size > 60)
-		size = 60;
+	/* There is a issue in HW where-in while sending GSO sized
+	 * pkts as part of TSO, if pkt len falls below this size
+	 * NIC will zero PAD packet and also updates IP total length.
+	 * Hence set this value to lessthan min pkt size of MAC+IP+TCP
+	 * headers, BGX will do the padding to transmit 64 byte pkt.
+	 */
+	if (size > 52)
+		size = 52;
 
 	for (lmac = 0; lmac < (MAX_BGX_PER_CN88XX * MAX_LMAC_PER_BGX); lmac++) {
 		lmac_cfg = nic_reg_read(nic, NIC_PF_LMAC_0_7_CFG | (lmac << 3));
@@ -309,6 +309,7 @@ static void nic_set_lmac_vf_mapping(stru
 static void nic_init_hw(struct nicpf *nic)
 {
 	int i;
+	u64 cqm_cfg;
 
 	/* Enable NIC HW block */
 	nic_reg_write(nic, NIC_PF_CFG, 0x3);
@@ -345,6 +346,11 @@ static void nic_init_hw(struct nicpf *ni
 	/* Enable VLAN ethertype matching and stripping */
 	nic_reg_write(nic, NIC_PF_RX_ETYPE_0_7,
 		      (2 << 19) | (ETYPE_ALG_VLAN_STRIP << 16) | ETH_P_8021Q);
+
+	/* Check if HW expected value is higher (could be in future chips) */
+	cqm_cfg = nic_reg_read(nic, NIC_PF_CQM_CFG);
+	if (cqm_cfg < NICPF_CQM_MIN_DROP_LEVEL)
+		nic_reg_write(nic, NIC_PF_CQM_CFG, NICPF_CQM_MIN_DROP_LEVEL);
 }
 
 /* Channel parse index configuration */
@@ -397,7 +403,7 @@ static void nic_config_cpi(struct nicpf
 			padd = cpi % 8; /* 3 bits CS out of 6bits DSCP */
 
 		/* Leave RSS_SIZE as '0' to disable RSS */
-		if (pass1_silicon(nic)) {
+		if (pass1_silicon(nic->pdev)) {
 			nic_reg_write(nic, NIC_PF_CPI_0_2047_CFG | (cpi << 3),
 				      (vnic << 24) | (padd << 16) |
 				      (rssi_base + rssi));
@@ -467,7 +473,7 @@ static void nic_config_rss(struct nicpf
 	}
 
 	cpi_base = nic->cpi_base[cfg->vf_id];
-	if (pass1_silicon(nic))
+	if (pass1_silicon(nic->pdev))
 		idx_addr = NIC_PF_CPI_0_2047_CFG;
 	else
 		idx_addr = NIC_PF_MPI_0_2047_CFG;
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/cavium/thunder/nic_reg.h
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/cavium/thunder/nic_reg.h
@@ -21,7 +21,7 @@
 #define   NIC_PF_TCP_TIMER			(0x0060)
 #define   NIC_PF_BP_CFG				(0x0080)
 #define   NIC_PF_RRM_CFG			(0x0088)
-#define   NIC_PF_CQM_CF				(0x00A0)
+#define   NIC_PF_CQM_CFG			(0x00A0)
 #define   NIC_PF_CNM_CF				(0x00A8)
 #define   NIC_PF_CNM_STATUS			(0x00B0)
 #define   NIC_PF_CQ_AVG_CFG			(0x00C0)
@@ -170,7 +170,6 @@
 #define   NIC_QSET_SQ_0_7_DOOR			(0x010838)
 #define   NIC_QSET_SQ_0_7_STATUS		(0x010840)
 #define   NIC_QSET_SQ_0_7_DEBUG			(0x010848)
-#define   NIC_QSET_SQ_0_7_CNM_CHG		(0x010860)
 #define   NIC_QSET_SQ_0_7_STAT_0_1		(0x010900)
 
 #define   NIC_QSET_RBDR_0_1_CFG			(0x010C00)
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/cavium/thunder/nicvf_ethtool.c
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/cavium/thunder/nicvf_ethtool.c
@@ -89,9 +89,11 @@ static const struct nicvf_stat nicvf_drv
 	NICVF_DRV_STAT(rx_frames_1518),
 	NICVF_DRV_STAT(rx_frames_jumbo),
 	NICVF_DRV_STAT(rx_drops),
+	NICVF_DRV_STAT(rcv_buffer_alloc_failures),
 	NICVF_DRV_STAT(tx_frames_ok),
 	NICVF_DRV_STAT(tx_tso),
 	NICVF_DRV_STAT(tx_drops),
+	NICVF_DRV_STAT(tx_timeout),
 	NICVF_DRV_STAT(txq_stop),
 	NICVF_DRV_STAT(txq_wake),
 };
@@ -380,7 +382,10 @@ static void nicvf_get_regs(struct net_de
 		p[i++] = nicvf_queue_reg_read(nic, NIC_QSET_SQ_0_7_DOOR, q);
 		p[i++] = nicvf_queue_reg_read(nic, NIC_QSET_SQ_0_7_STATUS, q);
 		p[i++] = nicvf_queue_reg_read(nic, NIC_QSET_SQ_0_7_DEBUG, q);
-		p[i++] = nicvf_queue_reg_read(nic, NIC_QSET_SQ_0_7_CNM_CHG, q);
+		/* Padding, was NIC_QSET_SQ_0_7_CNM_CHG, which
+		 * produces bus errors when read
+		 */
+		p[i++] = 0;
 		p[i++] = nicvf_queue_reg_read(nic, NIC_QSET_SQ_0_7_STAT_0_1, q);
 		reg_offset = NIC_QSET_SQ_0_7_STAT_0_1 | (1 << 3);
 		p[i++] = nicvf_queue_reg_read(nic, reg_offset, q);
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/cavium/thunder/nicvf_main.c
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/cavium/thunder/nicvf_main.c
@@ -513,6 +513,7 @@ static void nicvf_snd_pkt_handler(struct
 	struct nicvf *nic = netdev_priv(netdev);
 	struct snd_queue *sq;
 	struct sq_hdr_subdesc *hdr;
+	struct sq_hdr_subdesc *tso_sqe;
 
 	sq = &nic->qs->sq[cqe_tx->sq_idx];
 
@@ -525,14 +526,26 @@ static void nicvf_snd_pkt_handler(struct
 		   __func__, cqe_tx->sq_qs, cqe_tx->sq_idx,
 		   cqe_tx->sqe_ptr, hdr->subdesc_cnt);
 
-	nicvf_put_sq_desc(sq, hdr->subdesc_cnt + 1);
 	nicvf_check_cqe_tx_errs(nic, cq, cqe_tx);
 	skb = (struct sk_buff *)sq->skbuff[cqe_tx->sqe_ptr];
-	/* For TSO offloaded packets only one head SKB needs to be freed */
 	if (skb) {
+		/* Check for dummy descriptor used for HW TSO offload on 88xx */
+		if (hdr->dont_send) {
+			/* Get actual TSO descriptors and free them */
+			tso_sqe =
+			 (struct sq_hdr_subdesc *)GET_SQ_DESC(sq, hdr->rsvd2);
+			nicvf_put_sq_desc(sq, tso_sqe->subdesc_cnt + 1);
+		}
+		nicvf_put_sq_desc(sq, hdr->subdesc_cnt + 1);
 		prefetch(skb);
 		dev_consume_skb_any(skb);
 		sq->skbuff[cqe_tx->sqe_ptr] = (u64)NULL;
+	} else {
+		/* In case of SW TSO on 88xx, only last segment will have
+		 * a SKB attached, so just free SQEs here.
+		 */
+		if (!nic->hw_tso)
+			nicvf_put_sq_desc(sq, hdr->subdesc_cnt + 1);
 	}
 }
 
@@ -566,8 +579,7 @@ static inline void nicvf_set_rxhash(stru
 
 static void nicvf_rcv_pkt_handler(struct net_device *netdev,
 				  struct napi_struct *napi,
-				  struct cmp_queue *cq,
-				  struct cqe_rx_t *cqe_rx, int cqe_type)
+				  struct cqe_rx_t *cqe_rx)
 {
 	struct sk_buff *skb;
 	struct nicvf *nic = netdev_priv(netdev);
@@ -583,7 +595,7 @@ static void nicvf_rcv_pkt_handler(struct
 	}
 
 	/* Check for errors */
-	err = nicvf_check_cqe_rx_errs(nic, cq, cqe_rx);
+	err = nicvf_check_cqe_rx_errs(nic, cqe_rx);
 	if (err && !cqe_rx->rb_cnt)
 		return;
 
@@ -674,8 +686,7 @@ loop:
 			   cq_idx, cq_desc->cqe_type);
 		switch (cq_desc->cqe_type) {
 		case CQE_TYPE_RX:
-			nicvf_rcv_pkt_handler(netdev, napi, cq,
-					      cq_desc, CQE_TYPE_RX);
+			nicvf_rcv_pkt_handler(netdev, napi, cq_desc);
 			work_done++;
 		break;
 		case CQE_TYPE_SEND:
@@ -820,7 +831,7 @@ static irqreturn_t nicvf_intr_handler(in
 	nicvf_disable_intr(nic, NICVF_INTR_CQ, qidx);
 
 	/* Schedule NAPI */
-	napi_schedule(&cq_poll->napi);
+	napi_schedule_irqoff(&cq_poll->napi);
 
 	/* Clear interrupt */
 	nicvf_clear_intr(nic, NICVF_INTR_CQ, qidx);
@@ -891,6 +902,31 @@ static void nicvf_disable_msix(struct ni
 	}
 }
 
+static void nicvf_set_irq_affinity(struct nicvf *nic)
+{
+	int vec, cpu;
+	int irqnum;
+
+	for (vec = 0; vec < nic->num_vec; vec++) {
+		if (!nic->irq_allocated[vec])
+			continue;
+
+		if (!zalloc_cpumask_var(&nic->affinity_mask[vec], GFP_KERNEL))
+			return;
+		 /* CQ interrupts */
+		if (vec < NICVF_INTR_ID_SQ)
+			/* Leave CPU0 for RBDR and other interrupts */
+			cpu = nicvf_netdev_qidx(nic, vec) + 1;
+		else
+			cpu = 0;
+
+		cpumask_set_cpu(cpumask_local_spread(cpu, nic->node),
+				nic->affinity_mask[vec]);
+		irqnum = nic->msix_entries[vec].vector;
+		irq_set_affinity_hint(irqnum, nic->affinity_mask[vec]);
+	}
+}
+
 static int nicvf_register_interrupts(struct nicvf *nic)
 {
 	int irq, ret = 0;
@@ -936,8 +972,13 @@ static int nicvf_register_interrupts(str
 	ret = request_irq(nic->msix_entries[irq].vector,
 			  nicvf_qs_err_intr_handler,
 			  0, nic->irq_name[irq], nic);
-	if (!ret)
-		nic->irq_allocated[irq] = true;
+	if (ret)
+		goto err;
+
+	nic->irq_allocated[irq] = true;
+
+	/* Set IRQ affinities */
+	nicvf_set_irq_affinity(nic);
 
 err:
 	if (ret)
@@ -955,6 +996,9 @@ static void nicvf_unregister_interrupts(
 		if (!nic->irq_allocated[irq])
 			continue;
 
+		irq_set_affinity_hint(nic->msix_entries[irq].vector, NULL);
+		free_cpumask_var(nic->affinity_mask[irq]);
+
 		if (irq < NICVF_INTR_ID_SQ)
 			free_irq(nic->msix_entries[irq].vector, nic->napi[irq]);
 		else
@@ -1117,7 +1161,6 @@ int nicvf_stop(struct net_device *netdev
 
 	/* Clear multiqset info */
 	nic->pnicvf = nic;
-	nic->sqs_count = 0;
 
 	return 0;
 }
@@ -1346,6 +1389,9 @@ void nicvf_update_stats(struct nicvf *ni
 	drv_stats->tx_frames_ok = stats->tx_ucast_frames_ok +
 				  stats->tx_bcast_frames_ok +
 				  stats->tx_mcast_frames_ok;
+	drv_stats->rx_frames_ok = stats->rx_ucast_frames +
+				  stats->rx_bcast_frames +
+				  stats->rx_mcast_frames;
 	drv_stats->rx_drops = stats->rx_drop_red +
 			      stats->rx_drop_overrun;
 	drv_stats->tx_drops = stats->tx_drops;
@@ -1386,6 +1432,7 @@ static void nicvf_tx_timeout(struct net_
 		netdev_warn(dev, "%s: Transmit timed out, resetting\n",
 			    dev->name);
 
+	nic->drv_stats.tx_timeout++;
 	schedule_work(&nic->reset_task);
 }
 
@@ -1460,6 +1507,7 @@ static int nicvf_probe(struct pci_dev *p
 	struct net_device *netdev;
 	struct nicvf *nic;
 	int    err, qcount;
+	u16    sdevid;
 
 	err = pci_enable_device(pdev);
 	if (err) {
@@ -1530,6 +1578,13 @@ static int nicvf_probe(struct pci_dev *p
 
 	nicvf_send_vf_struct(nic);
 
+	if (!pass1_silicon(nic->pdev))
+		nic->hw_tso = true;
+
+	pci_read_config_word(nic->pdev, PCI_SUBSYSTEM_ID, &sdevid);
+	if (sdevid == 0xA134)
+		nic->t88 = true;
+
 	/* Check if this VF is in QS only mode */
 	if (nic->sqs_mode)
 		return 0;
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/cavium/thunder/nicvf_queues.c
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/cavium/thunder/nicvf_queues.c
@@ -18,13 +18,14 @@
 #include "q_struct.h"
 #include "nicvf_queues.h"
 
-struct rbuf_info {
-	struct page *page;
-	void	*data;
-	u64	offset;
-};
+static void nicvf_get_page(struct nicvf *nic)
+{
+	if (!nic->rb_pageref || !nic->rb_page)
+		return;
 
-#define GET_RBUF_INFO(x) ((struct rbuf_info *)(x - NICVF_RCV_BUF_ALIGN_BYTES))
+	atomic_add(nic->rb_pageref, &nic->rb_page->_count);
+	nic->rb_pageref = 0;
+}
 
 /* Poll a register for a specific value */
 static int nicvf_poll_reg(struct nicvf *nic, int qidx,
@@ -86,73 +87,53 @@ static void nicvf_free_q_desc_mem(struct
 static inline int nicvf_alloc_rcv_buffer(struct nicvf *nic, gfp_t gfp,
 					 u32 buf_len, u64 **rbuf)
 {
-	u64 data;
-	struct rbuf_info *rinfo;
-	int order = get_order(buf_len);
+	int order = (PAGE_SIZE <= 4096) ?  PAGE_ALLOC_COSTLY_ORDER : 0;
 
 	/* Check if request can be accomodated in previous allocated page */
-	if (nic->rb_page) {
-		if ((nic->rb_page_offset + buf_len + buf_len) >
-		    (PAGE_SIZE << order)) {
-			nic->rb_page = NULL;
-		} else {
-			nic->rb_page_offset += buf_len;
-			get_page(nic->rb_page);
-		}
+	if (nic->rb_page &&
+	    ((nic->rb_page_offset + buf_len) < (PAGE_SIZE << order))) {
+		nic->rb_pageref++;
+		goto ret;
 	}
 
+	nicvf_get_page(nic);
+	nic->rb_page = NULL;
+
 	/* Allocate a new page */
 	if (!nic->rb_page) {
 		nic->rb_page = alloc_pages(gfp | __GFP_COMP | __GFP_NOWARN,
 					   order);
 		if (!nic->rb_page) {
-			netdev_err(nic->netdev,
-				   "Failed to allocate new rcv buffer\n");
+			nic->drv_stats.rcv_buffer_alloc_failures++;
 			return -ENOMEM;
 		}
 		nic->rb_page_offset = 0;
 	}
 
-	data = (u64)page_address(nic->rb_page) + nic->rb_page_offset;
-
-	/* Align buffer addr to cache line i.e 128 bytes */
-	rinfo = (struct rbuf_info *)(data + NICVF_RCV_BUF_ALIGN_LEN(data));
-	/* Save page address for reference updation */
-	rinfo->page = nic->rb_page;
-	/* Store start address for later retrieval */
-	rinfo->data = (void *)data;
-	/* Store alignment offset */
-	rinfo->offset = NICVF_RCV_BUF_ALIGN_LEN(data);
+ret:
+	*rbuf = (u64 *)((u64)page_address(nic->rb_page) + nic->rb_page_offset);
+	nic->rb_page_offset += buf_len;
 
-	data += rinfo->offset;
-
-	/* Give next aligned address to hw for DMA */
-	*rbuf = (u64 *)(data + NICVF_RCV_BUF_ALIGN_BYTES);
 	return 0;
 }
 
-/* Retrieve actual buffer start address and build skb for received packet */
+/* Build skb around receive buffer */
 static struct sk_buff *nicvf_rb_ptr_to_skb(struct nicvf *nic,
 					   u64 rb_ptr, int len)
 {
+	void *data;
 	struct sk_buff *skb;
-	struct rbuf_info *rinfo;
 
-	rb_ptr = (u64)phys_to_virt(rb_ptr);
-	/* Get buffer start address and alignment offset */
-	rinfo = GET_RBUF_INFO(rb_ptr);
+	data = phys_to_virt(rb_ptr);
 
 	/* Now build an skb to give to stack */
-	skb = build_skb(rinfo->data, RCV_FRAG_LEN);
+	skb = build_skb(data, RCV_FRAG_LEN);
 	if (!skb) {
-		put_page(rinfo->page);
+		put_page(virt_to_page(data));
 		return NULL;
 	}
 
-	/* Set correct skb->data */
-	skb_reserve(skb, rinfo->offset + NICVF_RCV_BUF_ALIGN_BYTES);
-
-	prefetch((void *)rb_ptr);
+	prefetch(skb->data);
 	return skb;
 }
 
@@ -187,6 +168,9 @@ static int  nicvf_init_rbdr(struct nicvf
 		desc = GET_RBDR_DESC(rbdr, idx);
 		desc->buf_addr = virt_to_phys(rbuf) >> NICVF_RCV_BUF_ALIGN;
 	}
+
+	nicvf_get_page(nic);
+
 	return 0;
 }
 
@@ -196,7 +180,6 @@ static void nicvf_free_rbdr(struct nicvf
 	int head, tail;
 	u64 buf_addr;
 	struct rbdr_entry_t *desc;
-	struct rbuf_info *rinfo;
 
 	if (!rbdr)
 		return;
@@ -212,16 +195,14 @@ static void nicvf_free_rbdr(struct nicvf
 	while (head != tail) {
 		desc = GET_RBDR_DESC(rbdr, head);
 		buf_addr = desc->buf_addr << NICVF_RCV_BUF_ALIGN;
-		rinfo = GET_RBUF_INFO((u64)phys_to_virt(buf_addr));
-		put_page(rinfo->page);
+		put_page(virt_to_page(phys_to_virt(buf_addr)));
 		head++;
 		head &= (rbdr->dmem.q_len - 1);
 	}
 	/* Free SKB of tail desc */
 	desc = GET_RBDR_DESC(rbdr, tail);
 	buf_addr = desc->buf_addr << NICVF_RCV_BUF_ALIGN;
-	rinfo = GET_RBUF_INFO((u64)phys_to_virt(buf_addr));
-	put_page(rinfo->page);
+	put_page(virt_to_page(phys_to_virt(buf_addr)));
 
 	/* Free RBDR ring */
 	nicvf_free_q_desc_mem(nic, &rbdr->dmem);
@@ -273,6 +254,8 @@ refill:
 		new_rb++;
 	}
 
+	nicvf_get_page(nic);
+
 	/* make sure all memory stores are done before ringing doorbell */
 	smp_wmb();
 
@@ -330,7 +313,7 @@ static int nicvf_init_cmp_queue(struct n
 		return err;
 
 	cq->desc = cq->dmem.base;
-	cq->thresh = CMP_QUEUE_CQE_THRESH;
+	cq->thresh = pass1_silicon(nic->pdev) ? 0 : CMP_QUEUE_CQE_THRESH;
 	nic->cq_coalesce_usecs = (CMP_QUEUE_TIMER_THRESH * 0.05) - 1;
 
 	return 0;
@@ -550,6 +533,7 @@ static void nicvf_rcv_queue_config(struc
 		nicvf_config_vlan_stripping(nic, nic->netdev->features);
 
 	/* Enable Receive queue */
+	memset(&rq_cfg, 0, sizeof(struct rq_cfg));
 	rq_cfg.ena = 1;
 	rq_cfg.tcp_ena = 0;
 	nicvf_queue_reg_write(nic, NIC_QSET_RQ_0_7_CFG, qidx, *(u64 *)&rq_cfg);
@@ -582,6 +566,7 @@ void nicvf_cmp_queue_config(struct nicvf
 			      qidx, (u64)(cq->dmem.phys_base));
 
 	/* Enable Completion queue */
+	memset(&cq_cfg, 0, sizeof(struct cq_cfg));
 	cq_cfg.ena = 1;
 	cq_cfg.reset = 0;
 	cq_cfg.caching = 0;
@@ -630,6 +615,7 @@ static void nicvf_snd_queue_config(struc
 			      qidx, (u64)(sq->dmem.phys_base));
 
 	/* Enable send queue  & set queue size */
+	memset(&sq_cfg, 0, sizeof(struct sq_cfg));
 	sq_cfg.ena = 1;
 	sq_cfg.reset = 0;
 	sq_cfg.ldwb = 0;
@@ -666,6 +652,7 @@ static void nicvf_rbdr_config(struct nic
 
 	/* Enable RBDR  & set queue size */
 	/* Buffer size should be in multiples of 128 bytes */
+	memset(&rbdr_cfg, 0, sizeof(struct rbdr_cfg));
 	rbdr_cfg.ena = 1;
 	rbdr_cfg.reset = 0;
 	rbdr_cfg.ldwb = 0;
@@ -951,16 +938,22 @@ static int nicvf_tso_count_subdescs(stru
 	return num_edescs + sh->gso_segs;
 }
 
+#define POST_CQE_DESC_COUNT 2
+
 /* Get the number of SQ descriptors needed to xmit this skb */
 static int nicvf_sq_subdesc_required(struct nicvf *nic, struct sk_buff *skb)
 {
 	int subdesc_cnt = MIN_SQ_DESC_PER_PKT_XMIT;
 
-	if (skb_shinfo(skb)->gso_size) {
+	if (skb_shinfo(skb)->gso_size && !nic->hw_tso) {
 		subdesc_cnt = nicvf_tso_count_subdescs(skb);
 		return subdesc_cnt;
 	}
 
+	/* Dummy descriptors to get TSO pkt completion notification */
+	if (nic->t88 && nic->hw_tso && skb_shinfo(skb)->gso_size)
+		subdesc_cnt += POST_CQE_DESC_COUNT;
+
 	if (skb_shinfo(skb)->nr_frags)
 		subdesc_cnt += skb_shinfo(skb)->nr_frags;
 
@@ -971,21 +964,28 @@ static int nicvf_sq_subdesc_required(str
  * First subdescriptor for every send descriptor.
  */
 static inline void
-nicvf_sq_add_hdr_subdesc(struct snd_queue *sq, int qentry,
+nicvf_sq_add_hdr_subdesc(struct nicvf *nic, struct snd_queue *sq, int qentry,
 			 int subdesc_cnt, struct sk_buff *skb, int len)
 {
 	int proto;
 	struct sq_hdr_subdesc *hdr;
 
 	hdr = (struct sq_hdr_subdesc *)GET_SQ_DESC(sq, qentry);
-	sq->skbuff[qentry] = (u64)skb;
-
 	memset(hdr, 0, SND_QUEUE_DESC_SIZE);
 	hdr->subdesc_type = SQ_DESC_TYPE_HEADER;
-	/* Enable notification via CQE after processing SQE */
-	hdr->post_cqe = 1;
-	/* No of subdescriptors following this */
-	hdr->subdesc_cnt = subdesc_cnt;
+
+	if (nic->t88 && nic->hw_tso && skb_shinfo(skb)->gso_size) {
+		/* post_cqe = 0, to avoid HW posting a CQE for every TSO
+		 * segment transmitted on 88xx.
+		 */
+		hdr->subdesc_cnt = subdesc_cnt - POST_CQE_DESC_COUNT;
+	} else {
+		sq->skbuff[qentry] = (u64)skb;
+		/* Enable notification via CQE after processing SQE */
+		hdr->post_cqe = 1;
+		/* No of subdescriptors following this */
+		hdr->subdesc_cnt = subdesc_cnt;
+	}
 	hdr->tot_len = len;
 
 	/* Offload checksum calculation to HW */
@@ -1007,6 +1007,15 @@ nicvf_sq_add_hdr_subdesc(struct snd_queu
 			break;
 		}
 	}
+
+	if (nic->hw_tso && skb_shinfo(skb)->gso_size) {
+		hdr->tso = 1;
+		hdr->tso_start = skb_transport_offset(skb) + tcp_hdrlen(skb);
+		hdr->tso_max_paysize = skb_shinfo(skb)->gso_size;
+		/* For non-tunneled pkts, point this to L2 ethertype */
+		hdr->inner_l3_offset = skb_network_offset(skb) - 2;
+		nic->drv_stats.tx_tso++;
+	}
 }
 
 /* SQ GATHER subdescriptor
@@ -1027,6 +1036,37 @@ static inline void nicvf_sq_add_gather_s
 	gather->addr = data;
 }
 
+/* Add HDR + IMMEDIATE subdescriptors right after descriptors of a TSO
+ * packet so that a CQE is posted as a notifation for transmission of
+ * TSO packet.
+ */
+static inline void nicvf_sq_add_cqe_subdesc(struct snd_queue *sq, int qentry,
+					    int tso_sqe, struct sk_buff *skb)
+{
+	struct sq_imm_subdesc *imm;
+	struct sq_hdr_subdesc *hdr;
+
+	sq->skbuff[qentry] = (u64)skb;
+
+	hdr = (struct sq_hdr_subdesc *)GET_SQ_DESC(sq, qentry);
+	memset(hdr, 0, SND_QUEUE_DESC_SIZE);
+	hdr->subdesc_type = SQ_DESC_TYPE_HEADER;
+	/* Enable notification via CQE after processing SQE */
+	hdr->post_cqe = 1;
+	/* There is no packet to transmit here */
+	hdr->dont_send = 1;
+	hdr->subdesc_cnt = POST_CQE_DESC_COUNT - 1;
+	hdr->tot_len = 1;
+	/* Actual TSO header SQE index, needed for cleanup */
+	hdr->rsvd2 = tso_sqe;
+
+	qentry = nicvf_get_nxt_sqentry(sq, qentry);
+	imm = (struct sq_imm_subdesc *)GET_SQ_DESC(sq, qentry);
+	memset(imm, 0, SND_QUEUE_DESC_SIZE);
+	imm->subdesc_type = SQ_DESC_TYPE_IMMEDIATE;
+	imm->len = 1;
+}
+
 /* Segment a TSO packet into 'gso_size' segments and append
  * them to SQ for transfer
  */
@@ -1076,7 +1116,7 @@ static int nicvf_sq_append_tso(struct ni
 			data_left -= size;
 			tso_build_data(skb, &tso, size);
 		}
-		nicvf_sq_add_hdr_subdesc(sq, hdr_qentry,
+		nicvf_sq_add_hdr_subdesc(nic, sq, hdr_qentry,
 					 seg_subdescs - 1, skb, seg_len);
 		sq->skbuff[hdr_qentry] = (u64)NULL;
 		qentry = nicvf_get_nxt_sqentry(sq, qentry);
@@ -1100,7 +1140,7 @@ static int nicvf_sq_append_tso(struct ni
 int nicvf_sq_append_skb(struct nicvf *nic, struct sk_buff *skb)
 {
 	int i, size;
-	int subdesc_cnt;
+	int subdesc_cnt, tso_sqe = 0;
 	int sq_num, qentry;
 	struct queue_set *qs;
 	struct snd_queue *sq;
@@ -1129,11 +1169,13 @@ int nicvf_sq_append_skb(struct nicvf *ni
 	qentry = nicvf_get_sq_desc(sq, subdesc_cnt);
 
 	/* Check if its a TSO packet */
-	if (skb_shinfo(skb)->gso_size)
+	if (skb_shinfo(skb)->gso_size && !nic->hw_tso)
 		return nicvf_sq_append_tso(nic, sq, sq_num, qentry, skb);
 
 	/* Add SQ header subdesc */
-	nicvf_sq_add_hdr_subdesc(sq, qentry, subdesc_cnt - 1, skb, skb->len);
+	nicvf_sq_add_hdr_subdesc(nic, sq, qentry, subdesc_cnt - 1,
+				 skb, skb->len);
+	tso_sqe = qentry;
 
 	/* Add SQ gather subdescs */
 	qentry = nicvf_get_nxt_sqentry(sq, qentry);
@@ -1157,6 +1199,11 @@ int nicvf_sq_append_skb(struct nicvf *ni
 	}
 
 doorbell:
+	if (nic->t88 && skb_shinfo(skb)->gso_size) {
+		qentry = nicvf_get_nxt_sqentry(sq, qentry);
+		nicvf_sq_add_cqe_subdesc(sq, qentry, tso_sqe, skb);
+	}
+
 	/* make sure all memory stores are done before ringing doorbell */
 	smp_wmb();
 
@@ -1234,153 +1281,93 @@ struct sk_buff *nicvf_get_rcv_skb(struct
 	return skb;
 }
 
-/* Enable interrupt */
-void nicvf_enable_intr(struct nicvf *nic, int int_type, int q_idx)
+static u64 nicvf_int_type_to_mask(int int_type, int q_idx)
 {
 	u64 reg_val;
 
-	reg_val = nicvf_reg_read(nic, NIC_VF_ENA_W1S);
-
 	switch (int_type) {
 	case NICVF_INTR_CQ:
-		reg_val |= ((1ULL << q_idx) << NICVF_INTR_CQ_SHIFT);
+		reg_val = ((1ULL << q_idx) << NICVF_INTR_CQ_SHIFT);
 		break;
 	case NICVF_INTR_SQ:
-		reg_val |= ((1ULL << q_idx) << NICVF_INTR_SQ_SHIFT);
+		reg_val = ((1ULL << q_idx) << NICVF_INTR_SQ_SHIFT);
 		break;
 	case NICVF_INTR_RBDR:
-		reg_val |= ((1ULL << q_idx) << NICVF_INTR_RBDR_SHIFT);
+		reg_val = ((1ULL << q_idx) << NICVF_INTR_RBDR_SHIFT);
 		break;
 	case NICVF_INTR_PKT_DROP:
-		reg_val |= (1ULL << NICVF_INTR_PKT_DROP_SHIFT);
+		reg_val = (1ULL << NICVF_INTR_PKT_DROP_SHIFT);
 		break;
 	case NICVF_INTR_TCP_TIMER:
-		reg_val |= (1ULL << NICVF_INTR_TCP_TIMER_SHIFT);
+		reg_val = (1ULL << NICVF_INTR_TCP_TIMER_SHIFT);
 		break;
 	case NICVF_INTR_MBOX:
-		reg_val |= (1ULL << NICVF_INTR_MBOX_SHIFT);
+		reg_val = (1ULL << NICVF_INTR_MBOX_SHIFT);
 		break;
 	case NICVF_INTR_QS_ERR:
-		reg_val |= (1ULL << NICVF_INTR_QS_ERR_SHIFT);
+		reg_val = (1ULL << NICVF_INTR_QS_ERR_SHIFT);
 		break;
 	default:
-		netdev_err(nic->netdev,
-			   "Failed to enable interrupt: unknown type\n");
-		break;
+		reg_val = 0;
 	}
 
-	nicvf_reg_write(nic, NIC_VF_ENA_W1S, reg_val);
+	return reg_val;
+}
+
+/* Enable interrupt */
+void nicvf_enable_intr(struct nicvf *nic, int int_type, int q_idx)
+{
+	u64 mask = nicvf_int_type_to_mask(int_type, q_idx);
+
+	if (!mask) {
+		netdev_dbg(nic->netdev,
+			   "Failed to enable interrupt: unknown type\n");
+		return;
+	}
+	nicvf_reg_write(nic, NIC_VF_ENA_W1S,
+			nicvf_reg_read(nic, NIC_VF_ENA_W1S) | mask);
 }
 
 /* Disable interrupt */
 void nicvf_disable_intr(struct nicvf *nic, int int_type, int q_idx)
 {
-	u64 reg_val = 0;
+	u64 mask = nicvf_int_type_to_mask(int_type, q_idx);
 
-	switch (int_type) {
-	case NICVF_INTR_CQ:
-		reg_val |= ((1ULL << q_idx) << NICVF_INTR_CQ_SHIFT);
-		break;
-	case NICVF_INTR_SQ:
-		reg_val |= ((1ULL << q_idx) << NICVF_INTR_SQ_SHIFT);
-		break;
-	case NICVF_INTR_RBDR:
-		reg_val |= ((1ULL << q_idx) << NICVF_INTR_RBDR_SHIFT);
-		break;
-	case NICVF_INTR_PKT_DROP:
-		reg_val |= (1ULL << NICVF_INTR_PKT_DROP_SHIFT);
-		break;
-	case NICVF_INTR_TCP_TIMER:
-		reg_val |= (1ULL << NICVF_INTR_TCP_TIMER_SHIFT);
-		break;
-	case NICVF_INTR_MBOX:
-		reg_val |= (1ULL << NICVF_INTR_MBOX_SHIFT);
-		break;
-	case NICVF_INTR_QS_ERR:
-		reg_val |= (1ULL << NICVF_INTR_QS_ERR_SHIFT);
-		break;
-	default:
-		netdev_err(nic->netdev,
+	if (!mask) {
+		netdev_dbg(nic->netdev,
 			   "Failed to disable interrupt: unknown type\n");
-		break;
+		return;
 	}
 
-	nicvf_reg_write(nic, NIC_VF_ENA_W1C, reg_val);
+	nicvf_reg_write(nic, NIC_VF_ENA_W1C, mask);
 }
 
 /* Clear interrupt */
 void nicvf_clear_intr(struct nicvf *nic, int int_type, int q_idx)
 {
-	u64 reg_val = 0;
+	u64 mask = nicvf_int_type_to_mask(int_type, q_idx);
 
-	switch (int_type) {
-	case NICVF_INTR_CQ:
-		reg_val = ((1ULL << q_idx) << NICVF_INTR_CQ_SHIFT);
-		break;
-	case NICVF_INTR_SQ:
-		reg_val = ((1ULL << q_idx) << NICVF_INTR_SQ_SHIFT);
-		break;
-	case NICVF_INTR_RBDR:
-		reg_val = ((1ULL << q_idx) << NICVF_INTR_RBDR_SHIFT);
-		break;
-	case NICVF_INTR_PKT_DROP:
-		reg_val = (1ULL << NICVF_INTR_PKT_DROP_SHIFT);
-		break;
-	case NICVF_INTR_TCP_TIMER:
-		reg_val = (1ULL << NICVF_INTR_TCP_TIMER_SHIFT);
-		break;
-	case NICVF_INTR_MBOX:
-		reg_val = (1ULL << NICVF_INTR_MBOX_SHIFT);
-		break;
-	case NICVF_INTR_QS_ERR:
-		reg_val |= (1ULL << NICVF_INTR_QS_ERR_SHIFT);
-		break;
-	default:
-		netdev_err(nic->netdev,
+	if (!mask) {
+		netdev_dbg(nic->netdev,
 			   "Failed to clear interrupt: unknown type\n");
-		break;
+		return;
 	}
 
-	nicvf_reg_write(nic, NIC_VF_INT, reg_val);
+	nicvf_reg_write(nic, NIC_VF_INT, mask);
 }
 
 /* Check if interrupt is enabled */
 int nicvf_is_intr_enabled(struct nicvf *nic, int int_type, int q_idx)
 {
-	u64 reg_val;
-	u64 mask = 0xff;
-
-	reg_val = nicvf_reg_read(nic, NIC_VF_ENA_W1S);
-
-	switch (int_type) {
-	case NICVF_INTR_CQ:
-		mask = ((1ULL << q_idx) << NICVF_INTR_CQ_SHIFT);
-		break;
-	case NICVF_INTR_SQ:
-		mask = ((1ULL << q_idx) << NICVF_INTR_SQ_SHIFT);
-		break;
-	case NICVF_INTR_RBDR:
-		mask = ((1ULL << q_idx) << NICVF_INTR_RBDR_SHIFT);
-		break;
-	case NICVF_INTR_PKT_DROP:
-		mask = NICVF_INTR_PKT_DROP_MASK;
-		break;
-	case NICVF_INTR_TCP_TIMER:
-		mask = NICVF_INTR_TCP_TIMER_MASK;
-		break;
-	case NICVF_INTR_MBOX:
-		mask = NICVF_INTR_MBOX_MASK;
-		break;
-	case NICVF_INTR_QS_ERR:
-		mask = NICVF_INTR_QS_ERR_MASK;
-		break;
-	default:
-		netdev_err(nic->netdev,
+	u64 mask = nicvf_int_type_to_mask(int_type, q_idx);
+	/* If interrupt type is unknown, we treat it disabled. */
+	if (!mask) {
+		netdev_dbg(nic->netdev,
 			   "Failed to check interrupt enable: unknown type\n");
-		break;
+		return 0;
 	}
 
-	return (reg_val & mask);
+	return mask & nicvf_reg_read(nic, NIC_VF_ENA_W1S);
 }
 
 void nicvf_update_rq_stats(struct nicvf *nic, int rq_idx)
@@ -1410,16 +1397,12 @@ void nicvf_update_sq_stats(struct nicvf
 }
 
 /* Check for errors in the receive cmp.queue entry */
-int nicvf_check_cqe_rx_errs(struct nicvf *nic,
-			    struct cmp_queue *cq, struct cqe_rx_t *cqe_rx)
+int nicvf_check_cqe_rx_errs(struct nicvf *nic, struct cqe_rx_t *cqe_rx)
 {
 	struct nicvf_hw_stats *stats = &nic->hw_stats;
-	struct nicvf_drv_stats *drv_stats = &nic->drv_stats;
 
-	if (!cqe_rx->err_level && !cqe_rx->err_opcode) {
-		drv_stats->rx_frames_ok++;
+	if (!cqe_rx->err_level && !cqe_rx->err_opcode)
 		return 0;
-	}
 
 	if (netif_msg_rx_err(nic))
 		netdev_err(nic->netdev,
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/cavium/thunder/nicvf_queues.h
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/cavium/thunder/nicvf_queues.h
@@ -75,7 +75,7 @@
  */
 #define CMP_QSIZE		CMP_QUEUE_SIZE2
 #define CMP_QUEUE_LEN		(1ULL << (CMP_QSIZE + 10))
-#define CMP_QUEUE_CQE_THRESH	0
+#define CMP_QUEUE_CQE_THRESH	(NAPI_POLL_WEIGHT / 2)
 #define CMP_QUEUE_TIMER_THRESH	80 /* ~2usec */
 
 #define RBDR_SIZE		RBDR_SIZE0
@@ -83,10 +83,8 @@
 #define MAX_RCV_BUF_COUNT	(1ULL << (RBDR_SIZE6 + 13))
 #define RBDR_THRESH		(RCV_BUF_COUNT / 2)
 #define DMA_BUFFER_LEN		2048 /* In multiples of 128bytes */
-#define RCV_FRAG_LEN	(SKB_DATA_ALIGN(DMA_BUFFER_LEN + NET_SKB_PAD) + \
-			 SKB_DATA_ALIGN(sizeof(struct skb_shared_info)) + \
-			 (NICVF_RCV_BUF_ALIGN_BYTES * 2))
-#define RCV_DATA_OFFSET		NICVF_RCV_BUF_ALIGN_BYTES
+#define RCV_FRAG_LEN	 (SKB_DATA_ALIGN(DMA_BUFFER_LEN + NET_SKB_PAD) + \
+			 SKB_DATA_ALIGN(sizeof(struct skb_shared_info)))
 
 #define MAX_CQES_FOR_TX		((SND_QUEUE_LEN / MIN_SQ_DESC_PER_PKT_XMIT) * \
 				 MAX_CQE_PER_PKT_XMIT)
@@ -108,10 +106,6 @@
 #define NICVF_SQ_BASE_ALIGN_BYTES	128  /* 7 bits */
 
 #define NICVF_ALIGNED_ADDR(ADDR, ALIGN_BYTES)	ALIGN(ADDR, ALIGN_BYTES)
-#define NICVF_ADDR_ALIGN_LEN(ADDR, BYTES)\
-	(NICVF_ALIGNED_ADDR(ADDR, BYTES) - BYTES)
-#define NICVF_RCV_BUF_ALIGN_LEN(X)\
-	(NICVF_ALIGNED_ADDR(X, NICVF_RCV_BUF_ALIGN_BYTES) - X)
 
 /* Queue enable/disable */
 #define NICVF_SQ_EN		BIT_ULL(19)
@@ -344,8 +338,7 @@ u64  nicvf_queue_reg_read(struct nicvf *
 /* Stats */
 void nicvf_update_rq_stats(struct nicvf *nic, int rq_idx);
 void nicvf_update_sq_stats(struct nicvf *nic, int sq_idx);
-int nicvf_check_cqe_rx_errs(struct nicvf *nic,
-			    struct cmp_queue *cq, struct cqe_rx_t *cqe_rx);
+int nicvf_check_cqe_rx_errs(struct nicvf *nic, struct cqe_rx_t *cqe_rx);
 int nicvf_check_cqe_tx_errs(struct nicvf *nic,
 			    struct cmp_queue *cq, struct cqe_send_t *cqe_tx);
 #endif /* NICVF_QUEUES_H */
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/cavium/thunder/q_struct.h
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/cavium/thunder/q_struct.h
@@ -545,25 +545,28 @@ struct sq_hdr_subdesc {
 	u64    subdesc_cnt:8;
 	u64    csum_l4:2;
 	u64    csum_l3:1;
-	u64    rsvd0:5;
+	u64    csum_inner_l4:2;
+	u64    csum_inner_l3:1;
+	u64    rsvd0:2;
 	u64    l4_offset:8;
 	u64    l3_offset:8;
 	u64    rsvd1:4;
 	u64    tot_len:20; /* W0 */
 
-	u64    tso_sdc_cont:8;
-	u64    tso_sdc_first:8;
-	u64    tso_l4_offset:8;
-	u64    tso_flags_last:12;
-	u64    tso_flags_first:12;
-	u64    rsvd2:2;
+	u64    rsvd2:24;
+	u64    inner_l4_offset:8;
+	u64    inner_l3_offset:8;
+	u64    tso_start:8;
+	u64    rsvd3:2;
 	u64    tso_max_paysize:14; /* W1 */
 #elif defined(__LITTLE_ENDIAN_BITFIELD)
 	u64    tot_len:20;
 	u64    rsvd1:4;
 	u64    l3_offset:8;
 	u64    l4_offset:8;
-	u64    rsvd0:5;
+	u64    rsvd0:2;
+	u64    csum_inner_l3:1;
+	u64    csum_inner_l4:2;
 	u64    csum_l3:1;
 	u64    csum_l4:2;
 	u64    subdesc_cnt:8;
@@ -574,12 +577,11 @@ struct sq_hdr_subdesc {
 	u64    subdesc_type:4; /* W0 */
 
 	u64    tso_max_paysize:14;
-	u64    rsvd2:2;
-	u64    tso_flags_first:12;
-	u64    tso_flags_last:12;
-	u64    tso_l4_offset:8;
-	u64    tso_sdc_first:8;
-	u64    tso_sdc_cont:8; /* W1 */
+	u64    rsvd3:2;
+	u64    tso_start:8;
+	u64    inner_l3_offset:8;
+	u64    inner_l4_offset:8;
+	u64    rsvd2:24; /* W1 */
 #endif
 };
 
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/cavium/thunder/thunder_bgx.c
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/cavium/thunder/thunder_bgx.c
@@ -434,12 +434,14 @@ static int bgx_lmac_xaui_init(struct bgx
 
 	bgx_reg_modify(bgx, lmacid, BGX_SPUX_CONTROL1, SPU_CTL_LOW_POWER);
 	/* Set interleaved running disparity for RXAUI */
-	if (bgx->lmac_type != BGX_MODE_RXAUI)
-		bgx_reg_modify(bgx, lmacid,
-			       BGX_SPUX_MISC_CONTROL, SPU_MISC_CTL_RX_DIS);
-	else
+	if (bgx->lmac_type == BGX_MODE_RXAUI)
 		bgx_reg_modify(bgx, lmacid, BGX_SPUX_MISC_CONTROL,
-			       SPU_MISC_CTL_RX_DIS | SPU_MISC_CTL_INTLV_RDISP);
+			       SPU_MISC_CTL_INTLV_RDISP);
+
+	/* Clear receive packet disable */
+	cfg = bgx_reg_read(bgx, lmacid, BGX_SPUX_MISC_CONTROL);
+	cfg &= ~SPU_MISC_CTL_RX_DIS;
+	bgx_reg_write(bgx, lmacid, BGX_SPUX_MISC_CONTROL, cfg);
 
 	/* clear all interrupts */
 	cfg = bgx_reg_read(bgx, lmacid, BGX_SMUX_RX_INT);
@@ -512,7 +514,6 @@ static int bgx_xaui_check_link(struct lm
 	int lmac_type = bgx->lmac_type;
 	u64 cfg;
 
-	bgx_reg_modify(bgx, lmacid, BGX_SPUX_MISC_CONTROL, SPU_MISC_CTL_RX_DIS);
 	if (bgx->use_training) {
 		cfg = bgx_reg_read(bgx, lmacid, BGX_SPUX_INT);
 		if (!(cfg & (1ull << 13))) {
@@ -549,7 +550,9 @@ static int bgx_xaui_check_link(struct lm
 	}
 
 	/* Clear rcvflt bit (latching high) and read it back */
-	bgx_reg_modify(bgx, lmacid, BGX_SPUX_STATUS2, SPU_STATUS2_RCVFLT);
+	if (bgx_reg_read(bgx, lmacid, BGX_SPUX_STATUS2) & SPU_STATUS2_RCVFLT)
+		bgx_reg_modify(bgx, lmacid,
+			       BGX_SPUX_STATUS2, SPU_STATUS2_RCVFLT);
 	if (bgx_reg_read(bgx, lmacid, BGX_SPUX_STATUS2) & SPU_STATUS2_RCVFLT) {
 		dev_err(&bgx->pdev->dev, "Receive fault, retry training\n");
 		if (bgx->use_training) {
@@ -568,13 +571,6 @@ static int bgx_xaui_check_link(struct lm
 		return -1;
 	}
 
-	/* Wait for MAC RX to be ready */
-	if (bgx_poll_reg(bgx, lmacid, BGX_SMUX_RX_CTL,
-			 SMU_RX_CTL_STATUS, true)) {
-		dev_err(&bgx->pdev->dev, "SMU RX link not okay\n");
-		return -1;
-	}
-
 	/* Wait for BGX RX to be idle */
 	if (bgx_poll_reg(bgx, lmacid, BGX_SMUX_CTL, SMU_CTL_RX_IDLE, false)) {
 		dev_err(&bgx->pdev->dev, "SMU RX not idle\n");
@@ -587,29 +583,25 @@ static int bgx_xaui_check_link(struct lm
 		return -1;
 	}
 
-	if (bgx_reg_read(bgx, lmacid, BGX_SPUX_STATUS2) & SPU_STATUS2_RCVFLT) {
-		dev_err(&bgx->pdev->dev, "Receive fault\n");
-		return -1;
-	}
+	/* Check for MAC RX faults */
+	cfg = bgx_reg_read(bgx, lmacid, BGX_SMUX_RX_CTL);
+	/* 0 - Link is okay, 1 - Local fault, 2 - Remote fault */
+	cfg &= SMU_RX_CTL_STATUS;
+	if (!cfg)
+		return 0;
 
-	/* Receive link is latching low. Force it high and verify it */
-	bgx_reg_modify(bgx, lmacid, BGX_SPUX_STATUS1, SPU_STATUS1_RCV_LNK);
-	if (bgx_poll_reg(bgx, lmacid, BGX_SPUX_STATUS1,
-			 SPU_STATUS1_RCV_LNK, false)) {
-		dev_err(&bgx->pdev->dev, "SPU receive link down\n");
-		return -1;
-	}
+	/* Rx local/remote fault seen.
+	 * Do lmac reinit to see if condition recovers
+	 */
+	bgx_lmac_xaui_init(bgx, lmacid, bgx->lmac_type);
 
-	cfg = bgx_reg_read(bgx, lmacid, BGX_SPUX_MISC_CONTROL);
-	cfg &= ~SPU_MISC_CTL_RX_DIS;
-	bgx_reg_write(bgx, lmacid, BGX_SPUX_MISC_CONTROL, cfg);
-	return 0;
+	return -1;
 }
 
 static void bgx_poll_for_link(struct work_struct *work)
 {
 	struct lmac *lmac;
-	u64 link;
+	u64 spu_link, smu_link;
 
 	lmac = container_of(work, struct lmac, dwork.work);
 
@@ -619,8 +611,11 @@ static void bgx_poll_for_link(struct wor
 	bgx_poll_reg(lmac->bgx, lmac->lmacid, BGX_SPUX_STATUS1,
 		     SPU_STATUS1_RCV_LNK, false);
 
-	link = bgx_reg_read(lmac->bgx, lmac->lmacid, BGX_SPUX_STATUS1);
-	if (link & SPU_STATUS1_RCV_LNK) {
+	spu_link = bgx_reg_read(lmac->bgx, lmac->lmacid, BGX_SPUX_STATUS1);
+	smu_link = bgx_reg_read(lmac->bgx, lmac->lmacid, BGX_SMUX_RX_CTL);
+
+	if ((spu_link & SPU_STATUS1_RCV_LNK) &&
+	    !(smu_link & SMU_RX_CTL_STATUS)) {
 		lmac->link_up = 1;
 		if (lmac->bgx->lmac_type == BGX_MODE_XLAUI)
 			lmac->last_speed = 40000;
@@ -634,9 +629,15 @@ static void bgx_poll_for_link(struct wor
 	}
 
 	if (lmac->last_link != lmac->link_up) {
+		if (lmac->link_up) {
+			if (bgx_xaui_check_link(lmac)) {
+				/* Errors, clear link_up state */
+				lmac->link_up = 0;
+				lmac->last_speed = SPEED_UNKNOWN;
+				lmac->last_duplex = DUPLEX_UNKNOWN;
+			}
+		}
 		lmac->last_link = lmac->link_up;
-		if (lmac->link_up)
-			bgx_xaui_check_link(lmac);
 	}
 
 	queue_delayed_work(lmac->check_link, &lmac->dwork, HZ * 2);
@@ -708,7 +709,7 @@ static int bgx_lmac_enable(struct bgx *b
 static void bgx_lmac_disable(struct bgx *bgx, u8 lmacid)
 {
 	struct lmac *lmac;
-	u64 cmrx_cfg;
+	u64 cfg;
 
 	lmac = &bgx->lmac[lmacid];
 	if (lmac->check_link) {
@@ -717,9 +718,33 @@ static void bgx_lmac_disable(struct bgx
 		destroy_workqueue(lmac->check_link);
 	}
 
-	cmrx_cfg = bgx_reg_read(bgx, lmacid, BGX_CMRX_CFG);
-	cmrx_cfg &= ~(1 << 15);
-	bgx_reg_write(bgx, lmacid, BGX_CMRX_CFG, cmrx_cfg);
+	/* Disable packet reception */
+	cfg = bgx_reg_read(bgx, lmacid, BGX_CMRX_CFG);
+	cfg &= ~CMR_PKT_RX_EN;
+	bgx_reg_write(bgx, lmacid, BGX_CMRX_CFG, cfg);
+
+	/* Give chance for Rx/Tx FIFO to get drained */
+	bgx_poll_reg(bgx, lmacid, BGX_CMRX_RX_FIFO_LEN, (u64)0x1FFF, true);
+	bgx_poll_reg(bgx, lmacid, BGX_CMRX_TX_FIFO_LEN, (u64)0x3FFF, true);
+
+	/* Disable packet transmission */
+	cfg = bgx_reg_read(bgx, lmacid, BGX_CMRX_CFG);
+	cfg &= ~CMR_PKT_TX_EN;
+	bgx_reg_write(bgx, lmacid, BGX_CMRX_CFG, cfg);
+
+	/* Disable serdes lanes */
+        if (!lmac->is_sgmii)
+                bgx_reg_modify(bgx, lmacid,
+                               BGX_SPUX_CONTROL1, SPU_CTL_LOW_POWER);
+        else
+                bgx_reg_modify(bgx, lmacid,
+                               BGX_GMP_PCS_MRX_CTL, PCS_MRX_CTL_PWR_DN);
+
+	/* Disable LMAC */
+	cfg = bgx_reg_read(bgx, lmacid, BGX_CMRX_CFG);
+	cfg &= ~CMR_EN;
+	bgx_reg_write(bgx, lmacid, BGX_CMRX_CFG, cfg);
+
 	bgx_flush_dmac_addrs(bgx, lmacid);
 
 	if ((bgx->lmac_type != BGX_MODE_XFI) &&
@@ -886,7 +911,8 @@ static void bgx_get_qlm_mode(struct bgx
 
 #ifdef CONFIG_ACPI
 
-static int acpi_get_mac_address(struct acpi_device *adev, u8 *dst)
+static int acpi_get_mac_address(struct device *dev, struct acpi_device *adev,
+				u8 *dst)
 {
 	u8 mac[ETH_ALEN];
 	int ret;
@@ -897,10 +923,13 @@ static int acpi_get_mac_address(struct a
 		goto out;
 
 	if (!is_valid_ether_addr(mac)) {
+		dev_err(dev, "MAC address invalid: %pM\n", mac);
 		ret = -EINVAL;
 		goto out;
 	}
 
+	dev_info(dev, "MAC address set to: %pM\n", mac);
+
 	memcpy(dst, mac, ETH_ALEN);
 out:
 	return ret;
@@ -911,14 +940,15 @@ static acpi_status bgx_acpi_register_phy
 					 u32 lvl, void *context, void **rv)
 {
 	struct bgx *bgx = context;
+	struct device *dev = &bgx->pdev->dev;
 	struct acpi_device *adev;
 
 	if (acpi_bus_get_device(handle, &adev))
 		goto out;
 
-	acpi_get_mac_address(adev, bgx->lmac[bgx->lmac_count].mac);
+	acpi_get_mac_address(dev, adev, bgx->lmac[bgx->lmac_count].mac);
 
-	SET_NETDEV_DEV(&bgx->lmac[bgx->lmac_count].netdev, &bgx->pdev->dev);
+	SET_NETDEV_DEV(&bgx->lmac[bgx->lmac_count].netdev, dev);
 
 	bgx->lmac[bgx->lmac_count].lmacid = bgx->lmac_count;
 out:
@@ -968,34 +998,45 @@ static int bgx_init_acpi_phy(struct bgx
 
 static int bgx_init_of_phy(struct bgx *bgx)
 {
-	struct device_node *np;
-	struct device_node *np_child;
+	struct fwnode_handle *fwn;
 	u8 lmac = 0;
-	char bgx_sel[5];
 	const char *mac;
 
-	/* Get BGX node from DT */
-	snprintf(bgx_sel, 5, "bgx%d", bgx->bgx_id);
-	np = of_find_node_by_name(NULL, bgx_sel);
-	if (!np)
-		return -ENODEV;
-
-	for_each_child_of_node(np, np_child) {
-		struct device_node *phy_np = of_parse_phandle(np_child,
-							      "phy-handle", 0);
-		if (!phy_np)
-			continue;
-		bgx->lmac[lmac].phydev = of_phy_find_device(phy_np);
+	device_for_each_child_node(&bgx->pdev->dev, fwn) {
+		struct phy_device *pd;
+		struct device_node *phy_np;
+		struct device_node *node = to_of_node(fwn);
+
+		/* Should always be an OF node.  But if it is not, we
+		 * cannot handle it, so exit the loop.
+		 */
+		if (!node)
+			break;
 
-		mac = of_get_mac_address(np_child);
+		mac = of_get_mac_address(node);
 		if (mac)
 			ether_addr_copy(bgx->lmac[lmac].mac, mac);
 
 		SET_NETDEV_DEV(&bgx->lmac[lmac].netdev, &bgx->pdev->dev);
 		bgx->lmac[lmac].lmacid = lmac;
+
+		phy_np = of_parse_phandle(node, "phy-handle", 0);
+		/* If there is no phy or defective firmware presents
+		 * this cortina phy, for which there is no driver
+		 * support, ignore it.
+		 */
+		if (phy_np &&
+		    !of_device_is_compatible(phy_np, "cortina,cs4223-slice")) {
+			/* Wait until the phy drivers are available */
+			pd = of_phy_find_device(phy_np);
+			if (!pd)
+				return -EPROBE_DEFER;
+			bgx->lmac[lmac].phydev = pd;
+		}
+
 		lmac++;
 		if (lmac == MAX_LMAC_PER_BGX) {
-			of_node_put(np_child);
+			of_node_put(node);
 			break;
 		}
 	}
@@ -1026,9 +1067,6 @@ static int bgx_probe(struct pci_dev *pde
 	struct bgx *bgx = NULL;
 	u8 lmac;
 
-	/* Load octeon mdio driver */
-	octeon_mdiobus_force_mod_depencency();
-
 	bgx = devm_kzalloc(dev, sizeof(*bgx), GFP_KERNEL);
 	if (!bgx)
 		return -ENOMEM;
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/cavium/thunder/thunder_bgx.h
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/cavium/thunder/thunder_bgx.h
@@ -41,6 +41,7 @@
 #define BGX_CMRX_RX_STAT10		0xC0
 #define BGX_CMRX_RX_BP_DROP		0xC8
 #define BGX_CMRX_RX_DMAC_CTL		0x0E8
+#define BGX_CMRX_RX_FIFO_LEN		0x108
 #define BGX_CMR_RX_DMACX_CAM		0x200
 #define  RX_DMACX_CAM_EN			BIT_ULL(48)
 #define  RX_DMACX_CAM_LMACID(x)			(x << 49)
@@ -50,6 +51,7 @@
 #define BGX_CMR_CHAN_MSK_AND		0x450
 #define BGX_CMR_BIST_STATUS		0x460
 #define BGX_CMR_RX_LMACS		0x468
+#define BGX_CMRX_TX_FIFO_LEN		0x518
 #define BGX_CMRX_TX_STAT0		0x600
 #define BGX_CMRX_TX_STAT1		0x608
 #define BGX_CMRX_TX_STAT2		0x610
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/cisco/enic/enic.h
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/cisco/enic/enic.h
@@ -33,7 +33,7 @@
 
 #define DRV_NAME		"enic"
 #define DRV_DESCRIPTION		"Cisco VIC Ethernet NIC Driver"
-#define DRV_VERSION		"2.3.0.12"
+#define DRV_VERSION		"2.3.0.20"
 #define DRV_COPYRIGHT		"Copyright 2008-2013 Cisco Systems, Inc"
 
 #define ENIC_BARS_MAX		6
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/cisco/enic/vnic_dev.c
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/cisco/enic/vnic_dev.c
@@ -298,7 +298,8 @@ static int _vnic_dev_cmd2(struct vnic_de
 			  int wait)
 {
 	struct devcmd2_controller *dc2c = vdev->devcmd2;
-	struct devcmd2_result *result = dc2c->result + dc2c->next_result;
+	struct devcmd2_result *result;
+	u8 color;
 	unsigned int i;
 	int delay, err;
 	u32 fetch_index, new_posted;
@@ -336,13 +337,17 @@ static int _vnic_dev_cmd2(struct vnic_de
 	if (dc2c->cmd_ring[posted].flags & DEVCMD2_FNORESULT)
 		return 0;
 
+	result = dc2c->result + dc2c->next_result;
+	color = dc2c->color;
+
+	dc2c->next_result++;
+	if (dc2c->next_result == dc2c->result_size) {
+		dc2c->next_result = 0;
+		dc2c->color = dc2c->color ? 0 : 1;
+	}
+
 	for (delay = 0; delay < wait; delay++) {
-		if (result->color == dc2c->color) {
-			dc2c->next_result++;
-			if (dc2c->next_result == dc2c->result_size) {
-				dc2c->next_result = 0;
-				dc2c->color = dc2c->color ? 0 : 1;
-			}
+		if (result->color == color) {
 			if (result->error) {
 				err = result->error;
 				if (err != ERR_ECMDUNKNOWN ||
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/emulex/benet/be_main.c
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/emulex/benet/be_main.c
@@ -5472,6 +5472,10 @@ static void be_worker(struct work_struct
 	struct be_rx_obj *rxo;
 	int i;
 
+	if (be_physfn(adapter) &&
+	    MODULO(adapter->work_counter, adapter->be_get_temp_freq) == 0)
+		be_cmd_get_die_temperature(adapter);
+
 	/* when interrupts are not yet enabled, just reap any pending
 	 * mcc completions
 	 */
@@ -5490,10 +5494,6 @@ static void be_worker(struct work_struct
 			be_cmd_get_stats(adapter, &adapter->stats_cmd);
 	}
 
-	if (be_physfn(adapter) &&
-	    MODULO(adapter->work_counter, adapter->be_get_temp_freq) == 0)
-		be_cmd_get_die_temperature(adapter);
-
 	for_all_rx_queues(adapter, rxo, i) {
 		/* Replenish RX-queues starved due to memory
 		 * allocation failures.
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/freescale/fec_main.c
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/freescale/fec_main.c
@@ -1557,9 +1557,15 @@ fec_enet_rx(struct net_device *ndev, int
 	struct fec_enet_private *fep = netdev_priv(ndev);
 
 	for_each_set_bit(queue_id, &fep->work_rx, FEC_ENET_MAX_RX_QS) {
-		clear_bit(queue_id, &fep->work_rx);
-		pkt_received += fec_enet_rx_queue(ndev,
+		int ret;
+
+		ret = fec_enet_rx_queue(ndev,
 					budget - pkt_received, queue_id);
+
+		if (ret < budget - pkt_received)
+			clear_bit(queue_id, &fep->work_rx);
+
+		pkt_received += ret;
 	}
 	return pkt_received;
 }
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/ibm/Kconfig
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/ibm/Kconfig
@@ -37,4 +37,14 @@ config EHEA
 	  To compile the driver as a module, choose M here. The module
 	  will be called ehea.
 
+config IBMVNIC
+	tristate "IBM Virtual NIC support"
+	depends on PPC_PSERIES
+	---help---
+	  This driver supports Virtual NIC adapters on IBM i and IBM System p
+	  systems.
+
+	  To compile this driver as a module, choose M here. The module will
+	  be called ibmvnic.
+
 endif # NET_VENDOR_IBM
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/ibm/Makefile
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/ibm/Makefile
@@ -3,5 +3,6 @@
 #
 
 obj-$(CONFIG_IBMVETH) += ibmveth.o
+obj-$(CONFIG_IBMVNIC) += ibmvnic.o
 obj-$(CONFIG_IBM_EMAC) += emac/
 obj-$(CONFIG_EHEA) += ehea/
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/ibm/ibmvnic.c
@@ -0,0 +1,3585 @@
+/**************************************************************************/
+/*                                                                        */
+/*  IBM System i and System p Virtual NIC Device Driver                   */
+/*  Copyright (C) 2014 IBM Corp.                                          */
+/*  Santiago Leon (santi_leon@yahoo.com)                                  */
+/*  Thomas Falcon (tlfalcon@linux.vnet.ibm.com)                           */
+/*  John Allen (jallen@linux.vnet.ibm.com)                                */
+/*                                                                        */
+/*  This program is free software; you can redistribute it and/or modify  */
+/*  it under the terms of the GNU General Public License as published by  */
+/*  the Free Software Foundation; either version 2 of the License, or     */
+/*  (at your option) any later version.                                   */
+/*                                                                        */
+/*  This program is distributed in the hope that it will be useful,       */
+/*  but WITHOUT ANY WARRANTY; without even the implied warranty of        */
+/*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         */
+/*  GNU General Public License for more details.                          */
+/*                                                                        */
+/*  You should have received a copy of the GNU General Public License     */
+/*  along with this program.                                              */
+/*                                                                        */
+/* This module contains the implementation of a virtual ethernet device   */
+/* for use with IBM i/p Series LPAR Linux. It utilizes the logical LAN    */
+/* option of the RS/6000 Platform Architecture to interface with virtual  */
+/* ethernet NICs that are presented to the partition by the hypervisor.   */
+/*									   */
+/* Messages are passed between the VNIC driver and the VNIC server using  */
+/* Command/Response Queues (CRQs) and sub CRQs (sCRQs). CRQs are used to  */
+/* issue and receive commands that initiate communication with the server */
+/* on driver initialization. Sub CRQs (sCRQs) are similar to CRQs, but    */
+/* are used by the driver to notify the server that a packet is           */
+/* ready for transmission or that a buffer has been added to receive a    */
+/* packet. Subsequently, sCRQs are used by the server to notify the       */
+/* driver that a packet transmission has been completed or that a packet  */
+/* has been received and placed in a waiting buffer.                      */
+/*                                                                        */
+/* In lieu of a more conventional "on-the-fly" DMA mapping strategy in    */
+/* which skbs are DMA mapped and immediately unmapped when the transmit   */
+/* or receive has been completed, the VNIC driver is required to use      */
+/* "long term mapping". This entails that large, continuous DMA mapped    */
+/* buffers are allocated on driver initialization and these buffers are   */
+/* then continuously reused to pass skbs to and from the VNIC server.     */
+/*                                                                        */
+/**************************************************************************/
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/completion.h>
+#include <linux/ioport.h>
+#include <linux/dma-mapping.h>
+#include <linux/kernel.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/mm.h>
+#include <linux/ethtool.h>
+#include <linux/proc_fs.h>
+#include <linux/in.h>
+#include <linux/ip.h>
+#include <linux/irq.h>
+#include <linux/kthread.h>
+#include <linux/seq_file.h>
+#include <linux/debugfs.h>
+#include <linux/interrupt.h>
+#include <net/net_namespace.h>
+#include <asm/hvcall.h>
+#include <linux/atomic.h>
+#include <asm/vio.h>
+#include <asm/iommu.h>
+#include <linux/uaccess.h>
+#include <asm/firmware.h>
+#include <linux/seq_file.h>
+
+#include "ibmvnic.h"
+
+static const char ibmvnic_driver_name[] = "ibmvnic";
+static const char ibmvnic_driver_string[] = "IBM System i/p Virtual NIC Driver";
+
+MODULE_AUTHOR("Santiago Leon <santi_leon@yahoo.com>");
+MODULE_DESCRIPTION("IBM System i/p Virtual NIC Driver");
+MODULE_LICENSE("GPL");
+MODULE_VERSION(IBMVNIC_DRIVER_VERSION);
+
+static int ibmvnic_version = IBMVNIC_INITIAL_VERSION;
+static int ibmvnic_remove(struct vio_dev *);
+static void release_sub_crqs(struct ibmvnic_adapter *);
+static int ibmvnic_reset_crq(struct ibmvnic_adapter *);
+static int ibmvnic_send_crq_init(struct ibmvnic_adapter *);
+static int ibmvnic_reenable_crq_queue(struct ibmvnic_adapter *);
+static int ibmvnic_send_crq(struct ibmvnic_adapter *, union ibmvnic_crq *);
+static int send_subcrq(struct ibmvnic_adapter *adapter, u64 remote_handle,
+		       union sub_crq *sub_crq);
+static irqreturn_t ibmvnic_interrupt_rx(int irq, void *instance);
+static int enable_scrq_irq(struct ibmvnic_adapter *,
+			   struct ibmvnic_sub_crq_queue *);
+static int disable_scrq_irq(struct ibmvnic_adapter *,
+			    struct ibmvnic_sub_crq_queue *);
+static int pending_scrq(struct ibmvnic_adapter *,
+			struct ibmvnic_sub_crq_queue *);
+static union sub_crq *ibmvnic_next_scrq(struct ibmvnic_adapter *,
+					struct ibmvnic_sub_crq_queue *);
+static int ibmvnic_poll(struct napi_struct *napi, int data);
+static void send_map_query(struct ibmvnic_adapter *adapter);
+static void send_request_map(struct ibmvnic_adapter *, dma_addr_t, __be32, u8);
+static void send_request_unmap(struct ibmvnic_adapter *, u8);
+
+struct ibmvnic_stat {
+	char name[ETH_GSTRING_LEN];
+	int offset;
+};
+
+#define IBMVNIC_STAT_OFF(stat) (offsetof(struct ibmvnic_adapter, stats) + \
+			     offsetof(struct ibmvnic_statistics, stat))
+#define IBMVNIC_GET_STAT(a, off) (*((u64 *)(((unsigned long)(a)) + off)))
+
+static const struct ibmvnic_stat ibmvnic_stats[] = {
+	{"rx_packets", IBMVNIC_STAT_OFF(rx_packets)},
+	{"rx_bytes", IBMVNIC_STAT_OFF(rx_bytes)},
+	{"tx_packets", IBMVNIC_STAT_OFF(tx_packets)},
+	{"tx_bytes", IBMVNIC_STAT_OFF(tx_bytes)},
+	{"ucast_tx_packets", IBMVNIC_STAT_OFF(ucast_tx_packets)},
+	{"ucast_rx_packets", IBMVNIC_STAT_OFF(ucast_rx_packets)},
+	{"mcast_tx_packets", IBMVNIC_STAT_OFF(mcast_tx_packets)},
+	{"mcast_rx_packets", IBMVNIC_STAT_OFF(mcast_rx_packets)},
+	{"bcast_tx_packets", IBMVNIC_STAT_OFF(bcast_tx_packets)},
+	{"bcast_rx_packets", IBMVNIC_STAT_OFF(bcast_rx_packets)},
+	{"align_errors", IBMVNIC_STAT_OFF(align_errors)},
+	{"fcs_errors", IBMVNIC_STAT_OFF(fcs_errors)},
+	{"single_collision_frames", IBMVNIC_STAT_OFF(single_collision_frames)},
+	{"multi_collision_frames", IBMVNIC_STAT_OFF(multi_collision_frames)},
+	{"sqe_test_errors", IBMVNIC_STAT_OFF(sqe_test_errors)},
+	{"deferred_tx", IBMVNIC_STAT_OFF(deferred_tx)},
+	{"late_collisions", IBMVNIC_STAT_OFF(late_collisions)},
+	{"excess_collisions", IBMVNIC_STAT_OFF(excess_collisions)},
+	{"internal_mac_tx_errors", IBMVNIC_STAT_OFF(internal_mac_tx_errors)},
+	{"carrier_sense", IBMVNIC_STAT_OFF(carrier_sense)},
+	{"too_long_frames", IBMVNIC_STAT_OFF(too_long_frames)},
+	{"internal_mac_rx_errors", IBMVNIC_STAT_OFF(internal_mac_rx_errors)},
+};
+
+static long h_reg_sub_crq(unsigned long unit_address, unsigned long token,
+			  unsigned long length, unsigned long *number,
+			  unsigned long *irq)
+{
+	unsigned long retbuf[PLPAR_HCALL_BUFSIZE];
+	long rc;
+
+	rc = plpar_hcall(H_REG_SUB_CRQ, retbuf, unit_address, token, length);
+	*number = retbuf[0];
+	*irq = retbuf[1];
+
+	return rc;
+}
+
+/* net_device_ops functions */
+
+static void init_rx_pool(struct ibmvnic_adapter *adapter,
+			 struct ibmvnic_rx_pool *rx_pool, int num, int index,
+			 int buff_size, int active)
+{
+	netdev_dbg(adapter->netdev,
+		   "Initializing rx_pool %d, %d buffs, %d bytes each\n",
+		   index, num, buff_size);
+	rx_pool->size = num;
+	rx_pool->index = index;
+	rx_pool->buff_size = buff_size;
+	rx_pool->active = active;
+}
+
+static int alloc_long_term_buff(struct ibmvnic_adapter *adapter,
+				struct ibmvnic_long_term_buff *ltb, int size)
+{
+	struct device *dev = &adapter->vdev->dev;
+
+	ltb->size = size;
+	ltb->buff = dma_alloc_coherent(dev, ltb->size, &ltb->addr,
+				       GFP_KERNEL);
+
+	if (!ltb->buff) {
+		dev_err(dev, "Couldn't alloc long term buffer\n");
+		return -ENOMEM;
+	}
+	ltb->map_id = adapter->map_id;
+	adapter->map_id++;
+	send_request_map(adapter, ltb->addr,
+			 ltb->size, ltb->map_id);
+	init_completion(&adapter->fw_done);
+	wait_for_completion(&adapter->fw_done);
+	return 0;
+}
+
+static void free_long_term_buff(struct ibmvnic_adapter *adapter,
+				struct ibmvnic_long_term_buff *ltb)
+{
+	struct device *dev = &adapter->vdev->dev;
+
+	dma_free_coherent(dev, ltb->size, ltb->buff, ltb->addr);
+	send_request_unmap(adapter, ltb->map_id);
+}
+
+static int alloc_rx_pool(struct ibmvnic_adapter *adapter,
+			 struct ibmvnic_rx_pool *pool)
+{
+	struct device *dev = &adapter->vdev->dev;
+	int i;
+
+	pool->free_map = kcalloc(pool->size, sizeof(int), GFP_KERNEL);
+	if (!pool->free_map)
+		return -ENOMEM;
+
+	pool->rx_buff = kcalloc(pool->size, sizeof(struct ibmvnic_rx_buff),
+				GFP_KERNEL);
+
+	if (!pool->rx_buff) {
+		dev_err(dev, "Couldn't alloc rx buffers\n");
+		kfree(pool->free_map);
+		return -ENOMEM;
+	}
+
+	if (alloc_long_term_buff(adapter, &pool->long_term_buff,
+				 pool->size * pool->buff_size)) {
+		kfree(pool->free_map);
+		kfree(pool->rx_buff);
+		return -ENOMEM;
+	}
+
+	for (i = 0; i < pool->size; ++i)
+		pool->free_map[i] = i;
+
+	atomic_set(&pool->available, 0);
+	pool->next_alloc = 0;
+	pool->next_free = 0;
+
+	return 0;
+}
+
+static void replenish_rx_pool(struct ibmvnic_adapter *adapter,
+			      struct ibmvnic_rx_pool *pool)
+{
+	int count = pool->size - atomic_read(&pool->available);
+	struct device *dev = &adapter->vdev->dev;
+	int buffers_added = 0;
+	unsigned long lpar_rc;
+	union sub_crq sub_crq;
+	struct sk_buff *skb;
+	unsigned int offset;
+	dma_addr_t dma_addr;
+	unsigned char *dst;
+	u64 *handle_array;
+	int shift = 0;
+	int index;
+	int i;
+
+	handle_array = (u64 *)((u8 *)(adapter->login_rsp_buf) +
+				      be32_to_cpu(adapter->login_rsp_buf->
+				      off_rxadd_subcrqs));
+
+	for (i = 0; i < count; ++i) {
+		skb = alloc_skb(pool->buff_size, GFP_ATOMIC);
+		if (!skb) {
+			dev_err(dev, "Couldn't replenish rx buff\n");
+			adapter->replenish_no_mem++;
+			break;
+		}
+
+		index = pool->free_map[pool->next_free];
+
+		if (pool->rx_buff[index].skb)
+			dev_err(dev, "Inconsistent free_map!\n");
+
+		/* Copy the skb to the long term mapped DMA buffer */
+		offset = index * pool->buff_size;
+		dst = pool->long_term_buff.buff + offset;
+		memset(dst, 0, pool->buff_size);
+		dma_addr = pool->long_term_buff.addr + offset;
+		pool->rx_buff[index].data = dst;
+
+		pool->free_map[pool->next_free] = IBMVNIC_INVALID_MAP;
+		pool->rx_buff[index].dma = dma_addr;
+		pool->rx_buff[index].skb = skb;
+		pool->rx_buff[index].pool_index = pool->index;
+		pool->rx_buff[index].size = pool->buff_size;
+
+		memset(&sub_crq, 0, sizeof(sub_crq));
+		sub_crq.rx_add.first = IBMVNIC_CRQ_CMD;
+		sub_crq.rx_add.correlator =
+		    cpu_to_be64((u64)&pool->rx_buff[index]);
+		sub_crq.rx_add.ioba = cpu_to_be32(dma_addr);
+		sub_crq.rx_add.map_id = pool->long_term_buff.map_id;
+
+		/* The length field of the sCRQ is defined to be 24 bits so the
+		 * buffer size needs to be left shifted by a byte before it is
+		 * converted to big endian to prevent the last byte from being
+		 * truncated.
+		 */
+#ifdef __LITTLE_ENDIAN__
+		shift = 8;
+#endif
+		sub_crq.rx_add.len = cpu_to_be32(pool->buff_size << shift);
+
+		lpar_rc = send_subcrq(adapter, handle_array[pool->index],
+				      &sub_crq);
+		if (lpar_rc != H_SUCCESS)
+			goto failure;
+
+		buffers_added++;
+		adapter->replenish_add_buff_success++;
+		pool->next_free = (pool->next_free + 1) % pool->size;
+	}
+	atomic_add(buffers_added, &pool->available);
+	return;
+
+failure:
+	dev_info(dev, "replenish pools failure\n");
+	pool->free_map[pool->next_free] = index;
+	pool->rx_buff[index].skb = NULL;
+	if (!dma_mapping_error(dev, dma_addr))
+		dma_unmap_single(dev, dma_addr, pool->buff_size,
+				 DMA_FROM_DEVICE);
+
+	dev_kfree_skb_any(skb);
+	adapter->replenish_add_buff_failure++;
+	atomic_add(buffers_added, &pool->available);
+}
+
+static void replenish_pools(struct ibmvnic_adapter *adapter)
+{
+	int i;
+
+	if (adapter->migrated)
+		return;
+
+	adapter->replenish_task_cycles++;
+	for (i = 0; i < be32_to_cpu(adapter->login_rsp_buf->num_rxadd_subcrqs);
+	     i++) {
+		if (adapter->rx_pool[i].active)
+			replenish_rx_pool(adapter, &adapter->rx_pool[i]);
+	}
+}
+
+static void free_rx_pool(struct ibmvnic_adapter *adapter,
+			 struct ibmvnic_rx_pool *pool)
+{
+	int i;
+
+	kfree(pool->free_map);
+	pool->free_map = NULL;
+
+	if (!pool->rx_buff)
+		return;
+
+	for (i = 0; i < pool->size; i++) {
+		if (pool->rx_buff[i].skb) {
+			dev_kfree_skb_any(pool->rx_buff[i].skb);
+			pool->rx_buff[i].skb = NULL;
+		}
+	}
+	kfree(pool->rx_buff);
+	pool->rx_buff = NULL;
+}
+
+static int ibmvnic_open(struct net_device *netdev)
+{
+	struct ibmvnic_adapter *adapter = netdev_priv(netdev);
+	struct device *dev = &adapter->vdev->dev;
+	struct ibmvnic_tx_pool *tx_pool;
+	union ibmvnic_crq crq;
+	int rxadd_subcrqs;
+	u64 *size_array;
+	int tx_subcrqs;
+	int i, j;
+
+	rxadd_subcrqs =
+	    be32_to_cpu(adapter->login_rsp_buf->num_rxadd_subcrqs);
+	tx_subcrqs =
+	    be32_to_cpu(adapter->login_rsp_buf->num_txsubm_subcrqs);
+	size_array = (u64 *)((u8 *)(adapter->login_rsp_buf) +
+				  be32_to_cpu(adapter->login_rsp_buf->
+					      off_rxadd_buff_size));
+	adapter->map_id = 1;
+	adapter->napi = kcalloc(adapter->req_rx_queues,
+				sizeof(struct napi_struct), GFP_KERNEL);
+	if (!adapter->napi)
+		goto alloc_napi_failed;
+	for (i = 0; i < adapter->req_rx_queues; i++) {
+		netif_napi_add(netdev, &adapter->napi[i], ibmvnic_poll,
+			       NAPI_POLL_WEIGHT);
+		napi_enable(&adapter->napi[i]);
+	}
+	adapter->rx_pool =
+	    kcalloc(rxadd_subcrqs, sizeof(struct ibmvnic_rx_pool), GFP_KERNEL);
+
+	if (!adapter->rx_pool)
+		goto rx_pool_arr_alloc_failed;
+	send_map_query(adapter);
+	for (i = 0; i < rxadd_subcrqs; i++) {
+		init_rx_pool(adapter, &adapter->rx_pool[i],
+			     IBMVNIC_BUFFS_PER_POOL, i,
+			     be64_to_cpu(size_array[i]), 1);
+		if (alloc_rx_pool(adapter, &adapter->rx_pool[i])) {
+			dev_err(dev, "Couldn't alloc rx pool\n");
+			goto rx_pool_alloc_failed;
+		}
+	}
+	adapter->tx_pool =
+	    kcalloc(tx_subcrqs, sizeof(struct ibmvnic_tx_pool), GFP_KERNEL);
+
+	if (!adapter->tx_pool)
+		goto tx_pool_arr_alloc_failed;
+	for (i = 0; i < tx_subcrqs; i++) {
+		tx_pool = &adapter->tx_pool[i];
+		tx_pool->tx_buff =
+		    kcalloc(adapter->max_tx_entries_per_subcrq,
+			    sizeof(struct ibmvnic_tx_buff), GFP_KERNEL);
+		if (!tx_pool->tx_buff)
+			goto tx_pool_alloc_failed;
+
+		if (alloc_long_term_buff(adapter, &tx_pool->long_term_buff,
+					 adapter->max_tx_entries_per_subcrq *
+					 adapter->req_mtu))
+			goto tx_ltb_alloc_failed;
+
+		tx_pool->free_map =
+		    kcalloc(adapter->max_tx_entries_per_subcrq,
+			    sizeof(int), GFP_KERNEL);
+		if (!tx_pool->free_map)
+			goto tx_fm_alloc_failed;
+
+		for (j = 0; j < adapter->max_tx_entries_per_subcrq; j++)
+			tx_pool->free_map[j] = j;
+
+		tx_pool->consumer_index = 0;
+		tx_pool->producer_index = 0;
+	}
+	adapter->bounce_buffer_size =
+	    (netdev->mtu + ETH_HLEN - 1) / PAGE_SIZE + 1;
+	adapter->bounce_buffer = kmalloc(adapter->bounce_buffer_size,
+					 GFP_KERNEL);
+	if (!adapter->bounce_buffer)
+		goto bounce_alloc_failed;
+
+	adapter->bounce_buffer_dma = dma_map_single(dev, adapter->bounce_buffer,
+						    adapter->bounce_buffer_size,
+						    DMA_TO_DEVICE);
+	if (dma_mapping_error(dev, adapter->bounce_buffer_dma)) {
+		dev_err(dev, "Couldn't map tx bounce buffer\n");
+		goto bounce_map_failed;
+	}
+	replenish_pools(adapter);
+
+	/* We're ready to receive frames, enable the sub-crq interrupts and
+	 * set the logical link state to up
+	 */
+	for (i = 0; i < adapter->req_rx_queues; i++)
+		enable_scrq_irq(adapter, adapter->rx_scrq[i]);
+
+	for (i = 0; i < adapter->req_tx_queues; i++)
+		enable_scrq_irq(adapter, adapter->tx_scrq[i]);
+
+	memset(&crq, 0, sizeof(crq));
+	crq.logical_link_state.first = IBMVNIC_CRQ_CMD;
+	crq.logical_link_state.cmd = LOGICAL_LINK_STATE;
+	crq.logical_link_state.link_state = IBMVNIC_LOGICAL_LNK_UP;
+	ibmvnic_send_crq(adapter, &crq);
+
+	netif_start_queue(netdev);
+	return 0;
+
+bounce_map_failed:
+	kfree(adapter->bounce_buffer);
+bounce_alloc_failed:
+	i = tx_subcrqs - 1;
+	kfree(adapter->tx_pool[i].free_map);
+tx_fm_alloc_failed:
+	free_long_term_buff(adapter, &adapter->tx_pool[i].long_term_buff);
+tx_ltb_alloc_failed:
+	kfree(adapter->tx_pool[i].tx_buff);
+tx_pool_alloc_failed:
+	for (j = 0; j < i; j++) {
+		kfree(adapter->tx_pool[j].tx_buff);
+		free_long_term_buff(adapter,
+				    &adapter->tx_pool[j].long_term_buff);
+		kfree(adapter->tx_pool[j].free_map);
+	}
+	kfree(adapter->tx_pool);
+	adapter->tx_pool = NULL;
+tx_pool_arr_alloc_failed:
+	i = rxadd_subcrqs;
+rx_pool_alloc_failed:
+	for (j = 0; j < i; j++) {
+		free_rx_pool(adapter, &adapter->rx_pool[j]);
+		free_long_term_buff(adapter,
+				    &adapter->rx_pool[j].long_term_buff);
+	}
+	kfree(adapter->rx_pool);
+	adapter->rx_pool = NULL;
+rx_pool_arr_alloc_failed:
+	for (i = 0; i < adapter->req_rx_queues; i++)
+		napi_enable(&adapter->napi[i]);
+alloc_napi_failed:
+	return -ENOMEM;
+}
+
+static int ibmvnic_close(struct net_device *netdev)
+{
+	struct ibmvnic_adapter *adapter = netdev_priv(netdev);
+	struct device *dev = &adapter->vdev->dev;
+	union ibmvnic_crq crq;
+	int i;
+
+	adapter->closing = true;
+
+	for (i = 0; i < adapter->req_rx_queues; i++)
+		napi_disable(&adapter->napi[i]);
+
+	netif_stop_queue(netdev);
+
+	if (adapter->bounce_buffer) {
+		if (!dma_mapping_error(dev, adapter->bounce_buffer_dma)) {
+			dma_unmap_single(&adapter->vdev->dev,
+					 adapter->bounce_buffer_dma,
+					 adapter->bounce_buffer_size,
+					 DMA_BIDIRECTIONAL);
+			adapter->bounce_buffer_dma = DMA_ERROR_CODE;
+		}
+		kfree(adapter->bounce_buffer);
+		adapter->bounce_buffer = NULL;
+	}
+
+	memset(&crq, 0, sizeof(crq));
+	crq.logical_link_state.first = IBMVNIC_CRQ_CMD;
+	crq.logical_link_state.cmd = LOGICAL_LINK_STATE;
+	crq.logical_link_state.link_state = IBMVNIC_LOGICAL_LNK_DN;
+	ibmvnic_send_crq(adapter, &crq);
+
+	for (i = 0; i < be32_to_cpu(adapter->login_rsp_buf->num_txsubm_subcrqs);
+	     i++) {
+		kfree(adapter->tx_pool[i].tx_buff);
+		free_long_term_buff(adapter,
+				    &adapter->tx_pool[i].long_term_buff);
+		kfree(adapter->tx_pool[i].free_map);
+	}
+	kfree(adapter->tx_pool);
+	adapter->tx_pool = NULL;
+
+	for (i = 0; i < be32_to_cpu(adapter->login_rsp_buf->num_rxadd_subcrqs);
+	     i++) {
+		free_rx_pool(adapter, &adapter->rx_pool[i]);
+		free_long_term_buff(adapter,
+				    &adapter->rx_pool[i].long_term_buff);
+	}
+	kfree(adapter->rx_pool);
+	adapter->rx_pool = NULL;
+
+	adapter->closing = false;
+
+	return 0;
+}
+
+static int ibmvnic_xmit(struct sk_buff *skb, struct net_device *netdev)
+{
+	struct ibmvnic_adapter *adapter = netdev_priv(netdev);
+	int queue_num = skb_get_queue_mapping(skb);
+	struct device *dev = &adapter->vdev->dev;
+	struct ibmvnic_tx_buff *tx_buff = NULL;
+	struct ibmvnic_tx_pool *tx_pool;
+	unsigned int tx_send_failed = 0;
+	unsigned int tx_map_failed = 0;
+	unsigned int tx_dropped = 0;
+	unsigned int tx_packets = 0;
+	unsigned int tx_bytes = 0;
+	dma_addr_t data_dma_addr;
+	struct netdev_queue *txq;
+	bool used_bounce = false;
+	unsigned long lpar_rc;
+	union sub_crq tx_crq;
+	unsigned int offset;
+	unsigned char *dst;
+	u64 *handle_array;
+	int index = 0;
+	int ret = 0;
+
+	tx_pool = &adapter->tx_pool[queue_num];
+	txq = netdev_get_tx_queue(netdev, skb_get_queue_mapping(skb));
+	handle_array = (u64 *)((u8 *)(adapter->login_rsp_buf) +
+				   be32_to_cpu(adapter->login_rsp_buf->
+					       off_txsubm_subcrqs));
+	if (adapter->migrated) {
+		tx_send_failed++;
+		tx_dropped++;
+		ret = NETDEV_TX_BUSY;
+		goto out;
+	}
+
+	index = tx_pool->free_map[tx_pool->consumer_index];
+	offset = index * adapter->req_mtu;
+	dst = tx_pool->long_term_buff.buff + offset;
+	memset(dst, 0, adapter->req_mtu);
+	skb_copy_from_linear_data(skb, dst, skb->len);
+	data_dma_addr = tx_pool->long_term_buff.addr + offset;
+
+	tx_pool->consumer_index =
+	    (tx_pool->consumer_index + 1) %
+		adapter->max_tx_entries_per_subcrq;
+
+	tx_buff = &tx_pool->tx_buff[index];
+	tx_buff->skb = skb;
+	tx_buff->data_dma[0] = data_dma_addr;
+	tx_buff->data_len[0] = skb->len;
+	tx_buff->index = index;
+	tx_buff->pool_index = queue_num;
+	tx_buff->last_frag = true;
+	tx_buff->used_bounce = used_bounce;
+
+	memset(&tx_crq, 0, sizeof(tx_crq));
+	tx_crq.v1.first = IBMVNIC_CRQ_CMD;
+	tx_crq.v1.type = IBMVNIC_TX_DESC;
+	tx_crq.v1.n_crq_elem = 1;
+	tx_crq.v1.n_sge = 1;
+	tx_crq.v1.flags1 = IBMVNIC_TX_COMP_NEEDED;
+	tx_crq.v1.correlator = cpu_to_be32(index);
+	tx_crq.v1.dma_reg = cpu_to_be16(tx_pool->long_term_buff.map_id);
+	tx_crq.v1.sge_len = cpu_to_be32(skb->len);
+	tx_crq.v1.ioba = cpu_to_be64(data_dma_addr);
+
+	if (adapter->vlan_header_insertion) {
+		tx_crq.v1.flags2 |= IBMVNIC_TX_VLAN_INSERT;
+		tx_crq.v1.vlan_id = cpu_to_be16(skb->vlan_tci);
+	}
+
+	if (skb->protocol == htons(ETH_P_IP)) {
+		if (ip_hdr(skb)->version == 4)
+			tx_crq.v1.flags1 |= IBMVNIC_TX_PROT_IPV4;
+		else if (ip_hdr(skb)->version == 6)
+			tx_crq.v1.flags1 |= IBMVNIC_TX_PROT_IPV6;
+
+		if (ip_hdr(skb)->protocol == IPPROTO_TCP)
+			tx_crq.v1.flags1 |= IBMVNIC_TX_PROT_TCP;
+		else if (ip_hdr(skb)->protocol != IPPROTO_TCP)
+			tx_crq.v1.flags1 |= IBMVNIC_TX_PROT_UDP;
+	}
+
+	if (skb->ip_summed == CHECKSUM_PARTIAL)
+		tx_crq.v1.flags1 |= IBMVNIC_TX_CHKSUM_OFFLOAD;
+
+	lpar_rc = send_subcrq(adapter, handle_array[0], &tx_crq);
+
+	if (lpar_rc != H_SUCCESS) {
+		dev_err(dev, "tx failed with code %ld\n", lpar_rc);
+
+		if (tx_pool->consumer_index == 0)
+			tx_pool->consumer_index =
+				adapter->max_tx_entries_per_subcrq - 1;
+		else
+			tx_pool->consumer_index--;
+
+		tx_send_failed++;
+		tx_dropped++;
+		ret = NETDEV_TX_BUSY;
+		goto out;
+	}
+	tx_packets++;
+	tx_bytes += skb->len;
+	txq->trans_start = jiffies;
+	ret = NETDEV_TX_OK;
+
+out:
+	netdev->stats.tx_dropped += tx_dropped;
+	netdev->stats.tx_bytes += tx_bytes;
+	netdev->stats.tx_packets += tx_packets;
+	adapter->tx_send_failed += tx_send_failed;
+	adapter->tx_map_failed += tx_map_failed;
+
+	return ret;
+}
+
+static void ibmvnic_set_multi(struct net_device *netdev)
+{
+	struct ibmvnic_adapter *adapter = netdev_priv(netdev);
+	struct netdev_hw_addr *ha;
+	union ibmvnic_crq crq;
+
+	memset(&crq, 0, sizeof(crq));
+	crq.request_capability.first = IBMVNIC_CRQ_CMD;
+	crq.request_capability.cmd = REQUEST_CAPABILITY;
+
+	if (netdev->flags & IFF_PROMISC) {
+		if (!adapter->promisc_supported)
+			return;
+	} else {
+		if (netdev->flags & IFF_ALLMULTI) {
+			/* Accept all multicast */
+			memset(&crq, 0, sizeof(crq));
+			crq.multicast_ctrl.first = IBMVNIC_CRQ_CMD;
+			crq.multicast_ctrl.cmd = MULTICAST_CTRL;
+			crq.multicast_ctrl.flags = IBMVNIC_ENABLE_ALL;
+			ibmvnic_send_crq(adapter, &crq);
+		} else if (netdev_mc_empty(netdev)) {
+			/* Reject all multicast */
+			memset(&crq, 0, sizeof(crq));
+			crq.multicast_ctrl.first = IBMVNIC_CRQ_CMD;
+			crq.multicast_ctrl.cmd = MULTICAST_CTRL;
+			crq.multicast_ctrl.flags = IBMVNIC_DISABLE_ALL;
+			ibmvnic_send_crq(adapter, &crq);
+		} else {
+			/* Accept one or more multicast(s) */
+			netdev_for_each_mc_addr(ha, netdev) {
+				memset(&crq, 0, sizeof(crq));
+				crq.multicast_ctrl.first = IBMVNIC_CRQ_CMD;
+				crq.multicast_ctrl.cmd = MULTICAST_CTRL;
+				crq.multicast_ctrl.flags = IBMVNIC_ENABLE_MC;
+				ether_addr_copy(&crq.multicast_ctrl.mac_addr[0],
+						ha->addr);
+				ibmvnic_send_crq(adapter, &crq);
+			}
+		}
+	}
+}
+
+static int ibmvnic_set_mac(struct net_device *netdev, void *p)
+{
+	struct ibmvnic_adapter *adapter = netdev_priv(netdev);
+	struct sockaddr *addr = p;
+	union ibmvnic_crq crq;
+
+	if (!is_valid_ether_addr(addr->sa_data))
+		return -EADDRNOTAVAIL;
+
+	memset(&crq, 0, sizeof(crq));
+	crq.change_mac_addr.first = IBMVNIC_CRQ_CMD;
+	crq.change_mac_addr.cmd = CHANGE_MAC_ADDR;
+	ether_addr_copy(&crq.change_mac_addr.mac_addr[0], addr->sa_data);
+	ibmvnic_send_crq(adapter, &crq);
+	/* netdev->dev_addr is changed in handle_change_mac_rsp function */
+	return 0;
+}
+
+static int ibmvnic_change_mtu(struct net_device *netdev, int new_mtu)
+{
+	struct ibmvnic_adapter *adapter = netdev_priv(netdev);
+
+	if (new_mtu > adapter->req_mtu || new_mtu < adapter->min_mtu)
+		return -EINVAL;
+
+	netdev->mtu = new_mtu;
+	return 0;
+}
+
+static void ibmvnic_tx_timeout(struct net_device *dev)
+{
+	struct ibmvnic_adapter *adapter = netdev_priv(dev);
+	int rc;
+
+	/* Adapter timed out, resetting it */
+	release_sub_crqs(adapter);
+	rc = ibmvnic_reset_crq(adapter);
+	if (rc)
+		dev_err(&adapter->vdev->dev, "Adapter timeout, reset failed\n");
+	else
+		ibmvnic_send_crq_init(adapter);
+}
+
+static void remove_buff_from_pool(struct ibmvnic_adapter *adapter,
+				  struct ibmvnic_rx_buff *rx_buff)
+{
+	struct ibmvnic_rx_pool *pool = &adapter->rx_pool[rx_buff->pool_index];
+
+	rx_buff->skb = NULL;
+
+	pool->free_map[pool->next_alloc] = (int)(rx_buff - pool->rx_buff);
+	pool->next_alloc = (pool->next_alloc + 1) % pool->size;
+
+	atomic_dec(&pool->available);
+}
+
+static int ibmvnic_poll(struct napi_struct *napi, int budget)
+{
+	struct net_device *netdev = napi->dev;
+	struct ibmvnic_adapter *adapter = netdev_priv(netdev);
+	int scrq_num = (int)(napi - adapter->napi);
+	int frames_processed = 0;
+restart_poll:
+	while (frames_processed < budget) {
+		struct sk_buff *skb;
+		struct ibmvnic_rx_buff *rx_buff;
+		union sub_crq *next;
+		u32 length;
+		u16 offset;
+		u8 flags = 0;
+
+		if (!pending_scrq(adapter, adapter->rx_scrq[scrq_num]))
+			break;
+		next = ibmvnic_next_scrq(adapter, adapter->rx_scrq[scrq_num]);
+		rx_buff =
+		    (struct ibmvnic_rx_buff *)be64_to_cpu(next->
+							  rx_comp.correlator);
+		/* do error checking */
+		if (next->rx_comp.rc) {
+			netdev_err(netdev, "rx error %x\n", next->rx_comp.rc);
+			/* free the entry */
+			next->rx_comp.first = 0;
+			remove_buff_from_pool(adapter, rx_buff);
+			break;
+		}
+
+		length = be32_to_cpu(next->rx_comp.len);
+		offset = be16_to_cpu(next->rx_comp.off_frame_data);
+		flags = next->rx_comp.flags;
+		skb = rx_buff->skb;
+		skb_copy_to_linear_data(skb, rx_buff->data + offset,
+					length);
+		skb->vlan_tci = be16_to_cpu(next->rx_comp.vlan_tci);
+		/* free the entry */
+		next->rx_comp.first = 0;
+		remove_buff_from_pool(adapter, rx_buff);
+
+		skb_put(skb, length);
+		skb->protocol = eth_type_trans(skb, netdev);
+
+		if (flags & IBMVNIC_IP_CHKSUM_GOOD &&
+		    flags & IBMVNIC_TCP_UDP_CHKSUM_GOOD) {
+			skb->ip_summed = CHECKSUM_UNNECESSARY;
+		}
+
+		length = skb->len;
+		napi_gro_receive(napi, skb); /* send it up */
+		netdev->stats.rx_packets++;
+		netdev->stats.rx_bytes += length;
+		frames_processed++;
+	}
+	replenish_pools(adapter);
+
+	if (frames_processed < budget) {
+		enable_scrq_irq(adapter, adapter->rx_scrq[scrq_num]);
+		napi_complete(napi);
+		if (pending_scrq(adapter, adapter->rx_scrq[scrq_num]) &&
+		    napi_reschedule(napi)) {
+			disable_scrq_irq(adapter, adapter->rx_scrq[scrq_num]);
+			goto restart_poll;
+		}
+	}
+	return frames_processed;
+}
+
+#ifdef CONFIG_NET_POLL_CONTROLLER
+static void ibmvnic_netpoll_controller(struct net_device *dev)
+{
+	struct ibmvnic_adapter *adapter = netdev_priv(dev);
+	int i;
+
+	replenish_pools(netdev_priv(dev));
+	for (i = 0; i < adapter->req_rx_queues; i++)
+		ibmvnic_interrupt_rx(adapter->rx_scrq[i]->irq,
+				     adapter->rx_scrq[i]);
+}
+#endif
+
+static const struct net_device_ops ibmvnic_netdev_ops = {
+	.ndo_open		= ibmvnic_open,
+	.ndo_stop		= ibmvnic_close,
+	.ndo_start_xmit		= ibmvnic_xmit,
+	.ndo_set_rx_mode	= ibmvnic_set_multi,
+	.ndo_set_mac_address	= ibmvnic_set_mac,
+	.ndo_validate_addr	= eth_validate_addr,
+	.ndo_change_mtu		= ibmvnic_change_mtu,
+	.ndo_tx_timeout		= ibmvnic_tx_timeout,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+	.ndo_poll_controller	= ibmvnic_netpoll_controller,
+#endif
+};
+
+/* ethtool functions */
+
+static int ibmvnic_get_settings(struct net_device *netdev,
+				struct ethtool_cmd *cmd)
+{
+	cmd->supported = (SUPPORTED_1000baseT_Full | SUPPORTED_Autoneg |
+			  SUPPORTED_FIBRE);
+	cmd->advertising = (ADVERTISED_1000baseT_Full | ADVERTISED_Autoneg |
+			    ADVERTISED_FIBRE);
+	ethtool_cmd_speed_set(cmd, SPEED_1000);
+	cmd->duplex = DUPLEX_FULL;
+	cmd->port = PORT_FIBRE;
+	cmd->phy_address = 0;
+	cmd->transceiver = XCVR_INTERNAL;
+	cmd->autoneg = AUTONEG_ENABLE;
+	cmd->maxtxpkt = 0;
+	cmd->maxrxpkt = 1;
+	return 0;
+}
+
+static void ibmvnic_get_drvinfo(struct net_device *dev,
+				struct ethtool_drvinfo *info)
+{
+	strlcpy(info->driver, ibmvnic_driver_name, sizeof(info->driver));
+	strlcpy(info->version, IBMVNIC_DRIVER_VERSION, sizeof(info->version));
+}
+
+static u32 ibmvnic_get_msglevel(struct net_device *netdev)
+{
+	struct ibmvnic_adapter *adapter = netdev_priv(netdev);
+
+	return adapter->msg_enable;
+}
+
+static void ibmvnic_set_msglevel(struct net_device *netdev, u32 data)
+{
+	struct ibmvnic_adapter *adapter = netdev_priv(netdev);
+
+	adapter->msg_enable = data;
+}
+
+static u32 ibmvnic_get_link(struct net_device *netdev)
+{
+	struct ibmvnic_adapter *adapter = netdev_priv(netdev);
+
+	/* Don't need to send a query because we request a logical link up at
+	 * init and then we wait for link state indications
+	 */
+	return adapter->logical_link_state;
+}
+
+static void ibmvnic_get_ringparam(struct net_device *netdev,
+				  struct ethtool_ringparam *ring)
+{
+	ring->rx_max_pending = 0;
+	ring->tx_max_pending = 0;
+	ring->rx_mini_max_pending = 0;
+	ring->rx_jumbo_max_pending = 0;
+	ring->rx_pending = 0;
+	ring->tx_pending = 0;
+	ring->rx_mini_pending = 0;
+	ring->rx_jumbo_pending = 0;
+}
+
+static void ibmvnic_get_strings(struct net_device *dev, u32 stringset, u8 *data)
+{
+	int i;
+
+	if (stringset != ETH_SS_STATS)
+		return;
+
+	for (i = 0; i < ARRAY_SIZE(ibmvnic_stats); i++, data += ETH_GSTRING_LEN)
+		memcpy(data, ibmvnic_stats[i].name, ETH_GSTRING_LEN);
+}
+
+static int ibmvnic_get_sset_count(struct net_device *dev, int sset)
+{
+	switch (sset) {
+	case ETH_SS_STATS:
+		return ARRAY_SIZE(ibmvnic_stats);
+	default:
+		return -EOPNOTSUPP;
+	}
+}
+
+static void ibmvnic_get_ethtool_stats(struct net_device *dev,
+				      struct ethtool_stats *stats, u64 *data)
+{
+	struct ibmvnic_adapter *adapter = netdev_priv(dev);
+	union ibmvnic_crq crq;
+	int i;
+
+	memset(&crq, 0, sizeof(crq));
+	crq.request_statistics.first = IBMVNIC_CRQ_CMD;
+	crq.request_statistics.cmd = REQUEST_STATISTICS;
+	crq.request_statistics.ioba = cpu_to_be32(adapter->stats_token);
+	crq.request_statistics.len =
+	    cpu_to_be32(sizeof(struct ibmvnic_statistics));
+	ibmvnic_send_crq(adapter, &crq);
+
+	/* Wait for data to be written */
+	init_completion(&adapter->stats_done);
+	wait_for_completion(&adapter->stats_done);
+
+	for (i = 0; i < ARRAY_SIZE(ibmvnic_stats); i++)
+		data[i] = IBMVNIC_GET_STAT(adapter, ibmvnic_stats[i].offset);
+}
+
+static const struct ethtool_ops ibmvnic_ethtool_ops = {
+	.get_settings		= ibmvnic_get_settings,
+	.get_drvinfo		= ibmvnic_get_drvinfo,
+	.get_msglevel		= ibmvnic_get_msglevel,
+	.set_msglevel		= ibmvnic_set_msglevel,
+	.get_link		= ibmvnic_get_link,
+	.get_ringparam		= ibmvnic_get_ringparam,
+	.get_strings            = ibmvnic_get_strings,
+	.get_sset_count         = ibmvnic_get_sset_count,
+	.get_ethtool_stats	= ibmvnic_get_ethtool_stats,
+};
+
+/* Routines for managing CRQs/sCRQs  */
+
+static void release_sub_crq_queue(struct ibmvnic_adapter *adapter,
+				  struct ibmvnic_sub_crq_queue *scrq)
+{
+	struct device *dev = &adapter->vdev->dev;
+	long rc;
+
+	netdev_dbg(adapter->netdev, "Releasing sub-CRQ\n");
+
+	/* Close the sub-crqs */
+	do {
+		rc = plpar_hcall_norets(H_FREE_SUB_CRQ,
+					adapter->vdev->unit_address,
+					scrq->crq_num);
+	} while (rc == H_BUSY || H_IS_LONG_BUSY(rc));
+
+	dma_unmap_single(dev, scrq->msg_token, 4 * PAGE_SIZE,
+			 DMA_BIDIRECTIONAL);
+	free_pages((unsigned long)scrq->msgs, 2);
+	kfree(scrq);
+}
+
+static struct ibmvnic_sub_crq_queue *init_sub_crq_queue(struct ibmvnic_adapter
+							*adapter)
+{
+	struct device *dev = &adapter->vdev->dev;
+	struct ibmvnic_sub_crq_queue *scrq;
+	int rc;
+
+	scrq = kmalloc(sizeof(*scrq), GFP_ATOMIC);
+	if (!scrq)
+		return NULL;
+
+	scrq->msgs = (union sub_crq *)__get_free_pages(GFP_KERNEL, 2);
+	memset(scrq->msgs, 0, 4 * PAGE_SIZE);
+	if (!scrq->msgs) {
+		dev_warn(dev, "Couldn't allocate crq queue messages page\n");
+		goto zero_page_failed;
+	}
+
+	scrq->msg_token = dma_map_single(dev, scrq->msgs, 4 * PAGE_SIZE,
+					 DMA_BIDIRECTIONAL);
+	if (dma_mapping_error(dev, scrq->msg_token)) {
+		dev_warn(dev, "Couldn't map crq queue messages page\n");
+		goto map_failed;
+	}
+
+	rc = h_reg_sub_crq(adapter->vdev->unit_address, scrq->msg_token,
+			   4 * PAGE_SIZE, &scrq->crq_num, &scrq->hw_irq);
+
+	if (rc == H_RESOURCE)
+		rc = ibmvnic_reset_crq(adapter);
+
+	if (rc == H_CLOSED) {
+		dev_warn(dev, "Partner adapter not ready, waiting.\n");
+	} else if (rc) {
+		dev_warn(dev, "Error %d registering sub-crq\n", rc);
+		goto reg_failed;
+	}
+
+	scrq->irq = irq_create_mapping(NULL, scrq->hw_irq);
+	if (scrq->irq == NO_IRQ) {
+		dev_err(dev, "Error mapping irq\n");
+		goto map_irq_failed;
+	}
+
+	scrq->adapter = adapter;
+	scrq->size = 4 * PAGE_SIZE / sizeof(*scrq->msgs);
+	scrq->cur = 0;
+	scrq->rx_skb_top = NULL;
+	spin_lock_init(&scrq->lock);
+
+	netdev_dbg(adapter->netdev,
+		   "sub-crq initialized, num %lx, hw_irq=%lx, irq=%x\n",
+		   scrq->crq_num, scrq->hw_irq, scrq->irq);
+
+	return scrq;
+
+map_irq_failed:
+	do {
+		rc = plpar_hcall_norets(H_FREE_SUB_CRQ,
+					adapter->vdev->unit_address,
+					scrq->crq_num);
+	} while (rc == H_BUSY || H_IS_LONG_BUSY(rc));
+reg_failed:
+	dma_unmap_single(dev, scrq->msg_token, 4 * PAGE_SIZE,
+			 DMA_BIDIRECTIONAL);
+map_failed:
+	free_pages((unsigned long)scrq->msgs, 2);
+zero_page_failed:
+	kfree(scrq);
+
+	return NULL;
+}
+
+static void release_sub_crqs(struct ibmvnic_adapter *adapter)
+{
+	int i;
+
+	if (adapter->tx_scrq) {
+		for (i = 0; i < adapter->req_tx_queues; i++)
+			if (adapter->tx_scrq[i]) {
+				free_irq(adapter->tx_scrq[i]->irq,
+					 adapter->tx_scrq[i]);
+				release_sub_crq_queue(adapter,
+						      adapter->tx_scrq[i]);
+			}
+		adapter->tx_scrq = NULL;
+	}
+
+	if (adapter->rx_scrq) {
+		for (i = 0; i < adapter->req_rx_queues; i++)
+			if (adapter->rx_scrq[i]) {
+				free_irq(adapter->rx_scrq[i]->irq,
+					 adapter->rx_scrq[i]);
+				release_sub_crq_queue(adapter,
+						      adapter->rx_scrq[i]);
+			}
+		adapter->rx_scrq = NULL;
+	}
+
+	adapter->requested_caps = 0;
+}
+
+static int disable_scrq_irq(struct ibmvnic_adapter *adapter,
+			    struct ibmvnic_sub_crq_queue *scrq)
+{
+	struct device *dev = &adapter->vdev->dev;
+	unsigned long rc;
+
+	rc = plpar_hcall_norets(H_VIOCTL, adapter->vdev->unit_address,
+				H_DISABLE_VIO_INTERRUPT, scrq->hw_irq, 0, 0);
+	if (rc)
+		dev_err(dev, "Couldn't disable scrq irq 0x%lx. rc=%ld\n",
+			scrq->hw_irq, rc);
+	return rc;
+}
+
+static int enable_scrq_irq(struct ibmvnic_adapter *adapter,
+			   struct ibmvnic_sub_crq_queue *scrq)
+{
+	struct device *dev = &adapter->vdev->dev;
+	unsigned long rc;
+
+	if (scrq->hw_irq > 0x100000000ULL) {
+		dev_err(dev, "bad hw_irq = %lx\n", scrq->hw_irq);
+		return 1;
+	}
+
+	rc = plpar_hcall_norets(H_VIOCTL, adapter->vdev->unit_address,
+				H_ENABLE_VIO_INTERRUPT, scrq->hw_irq, 0, 0);
+	if (rc)
+		dev_err(dev, "Couldn't enable scrq irq 0x%lx. rc=%ld\n",
+			scrq->hw_irq, rc);
+	return rc;
+}
+
+static int ibmvnic_complete_tx(struct ibmvnic_adapter *adapter,
+			       struct ibmvnic_sub_crq_queue *scrq)
+{
+	struct device *dev = &adapter->vdev->dev;
+	struct ibmvnic_tx_buff *txbuff;
+	union sub_crq *next;
+	int index;
+	int i, j;
+
+restart_loop:
+	while (pending_scrq(adapter, scrq)) {
+		unsigned int pool = scrq->pool_index;
+
+		next = ibmvnic_next_scrq(adapter, scrq);
+		for (i = 0; i < next->tx_comp.num_comps; i++) {
+			if (next->tx_comp.rcs[i]) {
+				dev_err(dev, "tx error %x\n",
+					next->tx_comp.rcs[i]);
+				continue;
+			}
+			index = be32_to_cpu(next->tx_comp.correlators[i]);
+			txbuff = &adapter->tx_pool[pool].tx_buff[index];
+
+			for (j = 0; j < IBMVNIC_MAX_FRAGS_PER_CRQ; j++) {
+				if (!txbuff->data_dma[j])
+					continue;
+
+				txbuff->data_dma[j] = 0;
+				txbuff->used_bounce = false;
+			}
+
+			if (txbuff->last_frag)
+				dev_kfree_skb_any(txbuff->skb);
+
+			adapter->tx_pool[pool].free_map[adapter->tx_pool[pool].
+						     producer_index] = index;
+			adapter->tx_pool[pool].producer_index =
+			    (adapter->tx_pool[pool].producer_index + 1) %
+			    adapter->max_tx_entries_per_subcrq;
+		}
+		/* remove tx_comp scrq*/
+		next->tx_comp.first = 0;
+	}
+
+	enable_scrq_irq(adapter, scrq);
+
+	if (pending_scrq(adapter, scrq)) {
+		disable_scrq_irq(adapter, scrq);
+		goto restart_loop;
+	}
+
+	return 0;
+}
+
+static irqreturn_t ibmvnic_interrupt_tx(int irq, void *instance)
+{
+	struct ibmvnic_sub_crq_queue *scrq = instance;
+	struct ibmvnic_adapter *adapter = scrq->adapter;
+
+	disable_scrq_irq(adapter, scrq);
+	ibmvnic_complete_tx(adapter, scrq);
+
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t ibmvnic_interrupt_rx(int irq, void *instance)
+{
+	struct ibmvnic_sub_crq_queue *scrq = instance;
+	struct ibmvnic_adapter *adapter = scrq->adapter;
+
+	if (napi_schedule_prep(&adapter->napi[scrq->scrq_num])) {
+		disable_scrq_irq(adapter, scrq);
+		__napi_schedule(&adapter->napi[scrq->scrq_num]);
+	}
+
+	return IRQ_HANDLED;
+}
+
+static void init_sub_crqs(struct ibmvnic_adapter *adapter, int retry)
+{
+	struct device *dev = &adapter->vdev->dev;
+	struct ibmvnic_sub_crq_queue **allqueues;
+	int registered_queues = 0;
+	union ibmvnic_crq crq;
+	int total_queues;
+	int more = 0;
+	int i, j;
+	int rc;
+
+	if (!retry) {
+		/* Sub-CRQ entries are 32 byte long */
+		int entries_page = 4 * PAGE_SIZE / (sizeof(u64) * 4);
+
+		if (adapter->min_tx_entries_per_subcrq > entries_page ||
+		    adapter->min_rx_add_entries_per_subcrq > entries_page) {
+			dev_err(dev, "Fatal, invalid entries per sub-crq\n");
+			goto allqueues_failed;
+		}
+
+		/* Get the minimum between the queried max and the entries
+		 * that fit in our PAGE_SIZE
+		 */
+		adapter->req_tx_entries_per_subcrq =
+		    adapter->max_tx_entries_per_subcrq > entries_page ?
+		    entries_page : adapter->max_tx_entries_per_subcrq;
+		adapter->req_rx_add_entries_per_subcrq =
+		    adapter->max_rx_add_entries_per_subcrq > entries_page ?
+		    entries_page : adapter->max_rx_add_entries_per_subcrq;
+
+		/* Choosing the maximum number of queues supported by firmware*/
+		adapter->req_tx_queues = adapter->min_tx_queues;
+		adapter->req_rx_queues = adapter->min_rx_queues;
+		adapter->req_rx_add_queues = adapter->min_rx_add_queues;
+
+		adapter->req_mtu = adapter->max_mtu;
+	}
+
+	total_queues = adapter->req_tx_queues + adapter->req_rx_queues;
+
+	allqueues = kcalloc(total_queues, sizeof(*allqueues), GFP_ATOMIC);
+	if (!allqueues)
+		goto allqueues_failed;
+
+	for (i = 0; i < total_queues; i++) {
+		allqueues[i] = init_sub_crq_queue(adapter);
+		if (!allqueues[i]) {
+			dev_warn(dev, "Couldn't allocate all sub-crqs\n");
+			break;
+		}
+		registered_queues++;
+	}
+
+	/* Make sure we were able to register the minimum number of queues */
+	if (registered_queues <
+	    adapter->min_tx_queues + adapter->min_rx_queues) {
+		dev_err(dev, "Fatal: Couldn't init  min number of sub-crqs\n");
+		goto tx_failed;
+	}
+
+	/* Distribute the failed allocated queues*/
+	for (i = 0; i < total_queues - registered_queues + more ; i++) {
+		netdev_dbg(adapter->netdev, "Reducing number of queues\n");
+		switch (i % 3) {
+		case 0:
+			if (adapter->req_rx_queues > adapter->min_rx_queues)
+				adapter->req_rx_queues--;
+			else
+				more++;
+			break;
+		case 1:
+			if (adapter->req_tx_queues > adapter->min_tx_queues)
+				adapter->req_tx_queues--;
+			else
+				more++;
+			break;
+		}
+	}
+
+	adapter->tx_scrq = kcalloc(adapter->req_tx_queues,
+				   sizeof(*adapter->tx_scrq), GFP_ATOMIC);
+	if (!adapter->tx_scrq)
+		goto tx_failed;
+
+	for (i = 0; i < adapter->req_tx_queues; i++) {
+		adapter->tx_scrq[i] = allqueues[i];
+		adapter->tx_scrq[i]->pool_index = i;
+		rc = request_irq(adapter->tx_scrq[i]->irq, ibmvnic_interrupt_tx,
+				 0, "ibmvnic_tx", adapter->tx_scrq[i]);
+		if (rc) {
+			dev_err(dev, "Couldn't register tx irq 0x%x. rc=%d\n",
+				adapter->tx_scrq[i]->irq, rc);
+			goto req_tx_irq_failed;
+		}
+	}
+
+	adapter->rx_scrq = kcalloc(adapter->req_rx_queues,
+				   sizeof(*adapter->rx_scrq), GFP_ATOMIC);
+	if (!adapter->rx_scrq)
+		goto rx_failed;
+
+	for (i = 0; i < adapter->req_rx_queues; i++) {
+		adapter->rx_scrq[i] = allqueues[i + adapter->req_tx_queues];
+		adapter->rx_scrq[i]->scrq_num = i;
+		rc = request_irq(adapter->rx_scrq[i]->irq, ibmvnic_interrupt_rx,
+				 0, "ibmvnic_rx", adapter->rx_scrq[i]);
+		if (rc) {
+			dev_err(dev, "Couldn't register rx irq 0x%x. rc=%d\n",
+				adapter->rx_scrq[i]->irq, rc);
+			goto req_rx_irq_failed;
+		}
+	}
+
+	memset(&crq, 0, sizeof(crq));
+	crq.request_capability.first = IBMVNIC_CRQ_CMD;
+	crq.request_capability.cmd = REQUEST_CAPABILITY;
+
+	crq.request_capability.capability = cpu_to_be16(REQ_TX_QUEUES);
+	crq.request_capability.number = cpu_to_be32(adapter->req_tx_queues);
+	ibmvnic_send_crq(adapter, &crq);
+
+	crq.request_capability.capability = cpu_to_be16(REQ_RX_QUEUES);
+	crq.request_capability.number = cpu_to_be32(adapter->req_rx_queues);
+	ibmvnic_send_crq(adapter, &crq);
+
+	crq.request_capability.capability = cpu_to_be16(REQ_RX_ADD_QUEUES);
+	crq.request_capability.number = cpu_to_be32(adapter->req_rx_add_queues);
+	ibmvnic_send_crq(adapter, &crq);
+
+	crq.request_capability.capability =
+	    cpu_to_be16(REQ_TX_ENTRIES_PER_SUBCRQ);
+	crq.request_capability.number =
+	    cpu_to_be32(adapter->req_tx_entries_per_subcrq);
+	ibmvnic_send_crq(adapter, &crq);
+
+	crq.request_capability.capability =
+	    cpu_to_be16(REQ_RX_ADD_ENTRIES_PER_SUBCRQ);
+	crq.request_capability.number =
+	    cpu_to_be32(adapter->req_rx_add_entries_per_subcrq);
+	ibmvnic_send_crq(adapter, &crq);
+
+	crq.request_capability.capability = cpu_to_be16(REQ_MTU);
+	crq.request_capability.number = cpu_to_be32(adapter->req_mtu);
+	ibmvnic_send_crq(adapter, &crq);
+
+	if (adapter->netdev->flags & IFF_PROMISC) {
+		if (adapter->promisc_supported) {
+			crq.request_capability.capability =
+			    cpu_to_be16(PROMISC_REQUESTED);
+			crq.request_capability.number = cpu_to_be32(1);
+			ibmvnic_send_crq(adapter, &crq);
+		}
+	} else {
+		crq.request_capability.capability =
+		    cpu_to_be16(PROMISC_REQUESTED);
+		crq.request_capability.number = cpu_to_be32(0);
+		ibmvnic_send_crq(adapter, &crq);
+	}
+
+	kfree(allqueues);
+
+	return;
+
+req_rx_irq_failed:
+	for (j = 0; j < i; j++)
+		free_irq(adapter->rx_scrq[j]->irq, adapter->rx_scrq[j]);
+	i = adapter->req_tx_queues;
+req_tx_irq_failed:
+	for (j = 0; j < i; j++)
+		free_irq(adapter->tx_scrq[j]->irq, adapter->tx_scrq[j]);
+	kfree(adapter->rx_scrq);
+	adapter->rx_scrq = NULL;
+rx_failed:
+	kfree(adapter->tx_scrq);
+	adapter->tx_scrq = NULL;
+tx_failed:
+	for (i = 0; i < registered_queues; i++)
+		release_sub_crq_queue(adapter, allqueues[i]);
+	kfree(allqueues);
+allqueues_failed:
+	ibmvnic_remove(adapter->vdev);
+}
+
+static int pending_scrq(struct ibmvnic_adapter *adapter,
+			struct ibmvnic_sub_crq_queue *scrq)
+{
+	union sub_crq *entry = &scrq->msgs[scrq->cur];
+
+	if (entry->generic.first & IBMVNIC_CRQ_CMD_RSP || adapter->closing)
+		return 1;
+	else
+		return 0;
+}
+
+static union sub_crq *ibmvnic_next_scrq(struct ibmvnic_adapter *adapter,
+					struct ibmvnic_sub_crq_queue *scrq)
+{
+	union sub_crq *entry;
+	unsigned long flags;
+
+	spin_lock_irqsave(&scrq->lock, flags);
+	entry = &scrq->msgs[scrq->cur];
+	if (entry->generic.first & IBMVNIC_CRQ_CMD_RSP) {
+		if (++scrq->cur == scrq->size)
+			scrq->cur = 0;
+	} else {
+		entry = NULL;
+	}
+	spin_unlock_irqrestore(&scrq->lock, flags);
+
+	return entry;
+}
+
+static union ibmvnic_crq *ibmvnic_next_crq(struct ibmvnic_adapter *adapter)
+{
+	struct ibmvnic_crq_queue *queue = &adapter->crq;
+	union ibmvnic_crq *crq;
+
+	crq = &queue->msgs[queue->cur];
+	if (crq->generic.first & IBMVNIC_CRQ_CMD_RSP) {
+		if (++queue->cur == queue->size)
+			queue->cur = 0;
+	} else {
+		crq = NULL;
+	}
+
+	return crq;
+}
+
+static int send_subcrq(struct ibmvnic_adapter *adapter, u64 remote_handle,
+		       union sub_crq *sub_crq)
+{
+	unsigned int ua = adapter->vdev->unit_address;
+	struct device *dev = &adapter->vdev->dev;
+	u64 *u64_crq = (u64 *)sub_crq;
+	int rc;
+
+	netdev_dbg(adapter->netdev,
+		   "Sending sCRQ %016lx: %016lx %016lx %016lx %016lx\n",
+		   (unsigned long int)cpu_to_be64(remote_handle),
+		   (unsigned long int)cpu_to_be64(u64_crq[0]),
+		   (unsigned long int)cpu_to_be64(u64_crq[1]),
+		   (unsigned long int)cpu_to_be64(u64_crq[2]),
+		   (unsigned long int)cpu_to_be64(u64_crq[3]));
+
+	/* Make sure the hypervisor sees the complete request */
+	mb();
+
+	rc = plpar_hcall_norets(H_SEND_SUB_CRQ, ua,
+				cpu_to_be64(remote_handle),
+				cpu_to_be64(u64_crq[0]),
+				cpu_to_be64(u64_crq[1]),
+				cpu_to_be64(u64_crq[2]),
+				cpu_to_be64(u64_crq[3]));
+
+	if (rc) {
+		if (rc == H_CLOSED)
+			dev_warn(dev, "CRQ Queue closed\n");
+		dev_err(dev, "Send error (rc=%d)\n", rc);
+	}
+
+	return rc;
+}
+
+static int ibmvnic_send_crq(struct ibmvnic_adapter *adapter,
+			    union ibmvnic_crq *crq)
+{
+	unsigned int ua = adapter->vdev->unit_address;
+	struct device *dev = &adapter->vdev->dev;
+	u64 *u64_crq = (u64 *)crq;
+	int rc;
+
+	netdev_dbg(adapter->netdev, "Sending CRQ: %016lx %016lx\n",
+		   (unsigned long int)cpu_to_be64(u64_crq[0]),
+		   (unsigned long int)cpu_to_be64(u64_crq[1]));
+
+	/* Make sure the hypervisor sees the complete request */
+	mb();
+
+	rc = plpar_hcall_norets(H_SEND_CRQ, ua,
+				cpu_to_be64(u64_crq[0]),
+				cpu_to_be64(u64_crq[1]));
+
+	if (rc) {
+		if (rc == H_CLOSED)
+			dev_warn(dev, "CRQ Queue closed\n");
+		dev_warn(dev, "Send error (rc=%d)\n", rc);
+	}
+
+	return rc;
+}
+
+static int ibmvnic_send_crq_init(struct ibmvnic_adapter *adapter)
+{
+	union ibmvnic_crq crq;
+
+	memset(&crq, 0, sizeof(crq));
+	crq.generic.first = IBMVNIC_CRQ_INIT_CMD;
+	crq.generic.cmd = IBMVNIC_CRQ_INIT;
+	netdev_dbg(adapter->netdev, "Sending CRQ init\n");
+
+	return ibmvnic_send_crq(adapter, &crq);
+}
+
+static int ibmvnic_send_crq_init_complete(struct ibmvnic_adapter *adapter)
+{
+	union ibmvnic_crq crq;
+
+	memset(&crq, 0, sizeof(crq));
+	crq.generic.first = IBMVNIC_CRQ_INIT_CMD;
+	crq.generic.cmd = IBMVNIC_CRQ_INIT_COMPLETE;
+	netdev_dbg(adapter->netdev, "Sending CRQ init complete\n");
+
+	return ibmvnic_send_crq(adapter, &crq);
+}
+
+static int send_version_xchg(struct ibmvnic_adapter *adapter)
+{
+	union ibmvnic_crq crq;
+
+	memset(&crq, 0, sizeof(crq));
+	crq.version_exchange.first = IBMVNIC_CRQ_CMD;
+	crq.version_exchange.cmd = VERSION_EXCHANGE;
+	crq.version_exchange.version = cpu_to_be16(ibmvnic_version);
+
+	return ibmvnic_send_crq(adapter, &crq);
+}
+
+static void send_login(struct ibmvnic_adapter *adapter)
+{
+	struct ibmvnic_login_rsp_buffer *login_rsp_buffer;
+	struct ibmvnic_login_buffer *login_buffer;
+	struct ibmvnic_inflight_cmd *inflight_cmd;
+	struct device *dev = &adapter->vdev->dev;
+	dma_addr_t rsp_buffer_token;
+	dma_addr_t buffer_token;
+	size_t rsp_buffer_size;
+	union ibmvnic_crq crq;
+	unsigned long flags;
+	size_t buffer_size;
+	__be64 *tx_list_p;
+	__be64 *rx_list_p;
+	int i;
+
+	buffer_size =
+	    sizeof(struct ibmvnic_login_buffer) +
+	    sizeof(u64) * (adapter->req_tx_queues + adapter->req_rx_queues);
+
+	login_buffer = kmalloc(buffer_size, GFP_ATOMIC);
+	if (!login_buffer)
+		goto buf_alloc_failed;
+
+	buffer_token = dma_map_single(dev, login_buffer, buffer_size,
+				      DMA_TO_DEVICE);
+	if (dma_mapping_error(dev, buffer_token)) {
+		dev_err(dev, "Couldn't map login buffer\n");
+		goto buf_map_failed;
+	}
+
+	rsp_buffer_size =
+	    sizeof(struct ibmvnic_login_rsp_buffer) +
+	    sizeof(u64) * (adapter->req_tx_queues +
+			   adapter->req_rx_queues *
+			   adapter->req_rx_add_queues + adapter->
+			   req_rx_add_queues) +
+	    sizeof(u8) * (IBMVNIC_TX_DESC_VERSIONS);
+
+	login_rsp_buffer = kmalloc(rsp_buffer_size, GFP_ATOMIC);
+	if (!login_rsp_buffer)
+		goto buf_rsp_alloc_failed;
+
+	rsp_buffer_token = dma_map_single(dev, login_rsp_buffer,
+					  rsp_buffer_size, DMA_FROM_DEVICE);
+	if (dma_mapping_error(dev, rsp_buffer_token)) {
+		dev_err(dev, "Couldn't map login rsp buffer\n");
+		goto buf_rsp_map_failed;
+	}
+	inflight_cmd = kmalloc(sizeof(*inflight_cmd), GFP_ATOMIC);
+	if (!inflight_cmd) {
+		dev_err(dev, "Couldn't allocate inflight_cmd\n");
+		goto inflight_alloc_failed;
+	}
+	adapter->login_buf = login_buffer;
+	adapter->login_buf_token = buffer_token;
+	adapter->login_buf_sz = buffer_size;
+	adapter->login_rsp_buf = login_rsp_buffer;
+	adapter->login_rsp_buf_token = rsp_buffer_token;
+	adapter->login_rsp_buf_sz = rsp_buffer_size;
+
+	login_buffer->len = cpu_to_be32(buffer_size);
+	login_buffer->version = cpu_to_be32(INITIAL_VERSION_LB);
+	login_buffer->num_txcomp_subcrqs = cpu_to_be32(adapter->req_tx_queues);
+	login_buffer->off_txcomp_subcrqs =
+	    cpu_to_be32(sizeof(struct ibmvnic_login_buffer));
+	login_buffer->num_rxcomp_subcrqs = cpu_to_be32(adapter->req_rx_queues);
+	login_buffer->off_rxcomp_subcrqs =
+	    cpu_to_be32(sizeof(struct ibmvnic_login_buffer) +
+			sizeof(u64) * adapter->req_tx_queues);
+	login_buffer->login_rsp_ioba = cpu_to_be32(rsp_buffer_token);
+	login_buffer->login_rsp_len = cpu_to_be32(rsp_buffer_size);
+
+	tx_list_p = (__be64 *)((char *)login_buffer +
+				      sizeof(struct ibmvnic_login_buffer));
+	rx_list_p = (__be64 *)((char *)login_buffer +
+				      sizeof(struct ibmvnic_login_buffer) +
+				      sizeof(u64) * adapter->req_tx_queues);
+
+	for (i = 0; i < adapter->req_tx_queues; i++) {
+		if (adapter->tx_scrq[i]) {
+			tx_list_p[i] = cpu_to_be64(adapter->tx_scrq[i]->
+						   crq_num);
+		}
+	}
+
+	for (i = 0; i < adapter->req_rx_queues; i++) {
+		if (adapter->rx_scrq[i]) {
+			rx_list_p[i] = cpu_to_be64(adapter->rx_scrq[i]->
+						   crq_num);
+		}
+	}
+
+	netdev_dbg(adapter->netdev, "Login Buffer:\n");
+	for (i = 0; i < (adapter->login_buf_sz - 1) / 8 + 1; i++) {
+		netdev_dbg(adapter->netdev, "%016lx\n",
+			   ((unsigned long int *)(adapter->login_buf))[i]);
+	}
+
+	memset(&crq, 0, sizeof(crq));
+	crq.login.first = IBMVNIC_CRQ_CMD;
+	crq.login.cmd = LOGIN;
+	crq.login.ioba = cpu_to_be32(buffer_token);
+	crq.login.len = cpu_to_be32(buffer_size);
+
+	memcpy(&inflight_cmd->crq, &crq, sizeof(crq));
+
+	spin_lock_irqsave(&adapter->inflight_lock, flags);
+	list_add_tail(&inflight_cmd->list, &adapter->inflight);
+	spin_unlock_irqrestore(&adapter->inflight_lock, flags);
+
+	ibmvnic_send_crq(adapter, &crq);
+
+	return;
+
+inflight_alloc_failed:
+	dma_unmap_single(dev, rsp_buffer_token, rsp_buffer_size,
+			 DMA_FROM_DEVICE);
+buf_rsp_map_failed:
+	kfree(login_rsp_buffer);
+buf_rsp_alloc_failed:
+	dma_unmap_single(dev, buffer_token, buffer_size, DMA_TO_DEVICE);
+buf_map_failed:
+	kfree(login_buffer);
+buf_alloc_failed:
+	return;
+}
+
+static void send_request_map(struct ibmvnic_adapter *adapter, dma_addr_t addr,
+			     u32 len, u8 map_id)
+{
+	union ibmvnic_crq crq;
+
+	memset(&crq, 0, sizeof(crq));
+	crq.request_map.first = IBMVNIC_CRQ_CMD;
+	crq.request_map.cmd = REQUEST_MAP;
+	crq.request_map.map_id = map_id;
+	crq.request_map.ioba = cpu_to_be32(addr);
+	crq.request_map.len = cpu_to_be32(len);
+	ibmvnic_send_crq(adapter, &crq);
+}
+
+static void send_request_unmap(struct ibmvnic_adapter *adapter, u8 map_id)
+{
+	union ibmvnic_crq crq;
+
+	memset(&crq, 0, sizeof(crq));
+	crq.request_unmap.first = IBMVNIC_CRQ_CMD;
+	crq.request_unmap.cmd = REQUEST_UNMAP;
+	crq.request_unmap.map_id = map_id;
+	ibmvnic_send_crq(adapter, &crq);
+}
+
+static void send_map_query(struct ibmvnic_adapter *adapter)
+{
+	union ibmvnic_crq crq;
+
+	memset(&crq, 0, sizeof(crq));
+	crq.query_map.first = IBMVNIC_CRQ_CMD;
+	crq.query_map.cmd = QUERY_MAP;
+	ibmvnic_send_crq(adapter, &crq);
+}
+
+/* Send a series of CRQs requesting various capabilities of the VNIC server */
+static void send_cap_queries(struct ibmvnic_adapter *adapter)
+{
+	union ibmvnic_crq crq;
+
+	atomic_set(&adapter->running_cap_queries, 0);
+	memset(&crq, 0, sizeof(crq));
+	crq.query_capability.first = IBMVNIC_CRQ_CMD;
+	crq.query_capability.cmd = QUERY_CAPABILITY;
+
+	crq.query_capability.capability = cpu_to_be16(MIN_TX_QUEUES);
+	atomic_inc(&adapter->running_cap_queries);
+	ibmvnic_send_crq(adapter, &crq);
+
+	crq.query_capability.capability = cpu_to_be16(MIN_RX_QUEUES);
+	atomic_inc(&adapter->running_cap_queries);
+	ibmvnic_send_crq(adapter, &crq);
+
+	crq.query_capability.capability = cpu_to_be16(MIN_RX_ADD_QUEUES);
+	atomic_inc(&adapter->running_cap_queries);
+	ibmvnic_send_crq(adapter, &crq);
+
+	crq.query_capability.capability = cpu_to_be16(MAX_TX_QUEUES);
+	atomic_inc(&adapter->running_cap_queries);
+	ibmvnic_send_crq(adapter, &crq);
+
+	crq.query_capability.capability = cpu_to_be16(MAX_RX_QUEUES);
+	atomic_inc(&adapter->running_cap_queries);
+	ibmvnic_send_crq(adapter, &crq);
+
+	crq.query_capability.capability = cpu_to_be16(MAX_RX_ADD_QUEUES);
+	atomic_inc(&adapter->running_cap_queries);
+	ibmvnic_send_crq(adapter, &crq);
+
+	crq.query_capability.capability =
+	    cpu_to_be16(MIN_TX_ENTRIES_PER_SUBCRQ);
+	atomic_inc(&adapter->running_cap_queries);
+	ibmvnic_send_crq(adapter, &crq);
+
+	crq.query_capability.capability =
+	    cpu_to_be16(MIN_RX_ADD_ENTRIES_PER_SUBCRQ);
+	atomic_inc(&adapter->running_cap_queries);
+	ibmvnic_send_crq(adapter, &crq);
+
+	crq.query_capability.capability =
+	    cpu_to_be16(MAX_TX_ENTRIES_PER_SUBCRQ);
+	atomic_inc(&adapter->running_cap_queries);
+	ibmvnic_send_crq(adapter, &crq);
+
+	crq.query_capability.capability =
+	    cpu_to_be16(MAX_RX_ADD_ENTRIES_PER_SUBCRQ);
+	atomic_inc(&adapter->running_cap_queries);
+	ibmvnic_send_crq(adapter, &crq);
+
+	crq.query_capability.capability = cpu_to_be16(TCP_IP_OFFLOAD);
+	atomic_inc(&adapter->running_cap_queries);
+	ibmvnic_send_crq(adapter, &crq);
+
+	crq.query_capability.capability = cpu_to_be16(PROMISC_SUPPORTED);
+	atomic_inc(&adapter->running_cap_queries);
+	ibmvnic_send_crq(adapter, &crq);
+
+	crq.query_capability.capability = cpu_to_be16(MIN_MTU);
+	atomic_inc(&adapter->running_cap_queries);
+	ibmvnic_send_crq(adapter, &crq);
+
+	crq.query_capability.capability = cpu_to_be16(MAX_MTU);
+	atomic_inc(&adapter->running_cap_queries);
+	ibmvnic_send_crq(adapter, &crq);
+
+	crq.query_capability.capability = cpu_to_be16(MAX_MULTICAST_FILTERS);
+	atomic_inc(&adapter->running_cap_queries);
+	ibmvnic_send_crq(adapter, &crq);
+
+	crq.query_capability.capability = cpu_to_be16(VLAN_HEADER_INSERTION);
+	atomic_inc(&adapter->running_cap_queries);
+	ibmvnic_send_crq(adapter, &crq);
+
+	crq.query_capability.capability = cpu_to_be16(MAX_TX_SG_ENTRIES);
+	atomic_inc(&adapter->running_cap_queries);
+	ibmvnic_send_crq(adapter, &crq);
+
+	crq.query_capability.capability = cpu_to_be16(RX_SG_SUPPORTED);
+	atomic_inc(&adapter->running_cap_queries);
+	ibmvnic_send_crq(adapter, &crq);
+
+	crq.query_capability.capability = cpu_to_be16(OPT_TX_COMP_SUB_QUEUES);
+	atomic_inc(&adapter->running_cap_queries);
+	ibmvnic_send_crq(adapter, &crq);
+
+	crq.query_capability.capability = cpu_to_be16(OPT_RX_COMP_QUEUES);
+	atomic_inc(&adapter->running_cap_queries);
+	ibmvnic_send_crq(adapter, &crq);
+
+	crq.query_capability.capability =
+			cpu_to_be16(OPT_RX_BUFADD_Q_PER_RX_COMP_Q);
+	atomic_inc(&adapter->running_cap_queries);
+	ibmvnic_send_crq(adapter, &crq);
+
+	crq.query_capability.capability =
+			cpu_to_be16(OPT_TX_ENTRIES_PER_SUBCRQ);
+	atomic_inc(&adapter->running_cap_queries);
+	ibmvnic_send_crq(adapter, &crq);
+
+	crq.query_capability.capability =
+			cpu_to_be16(OPT_RXBA_ENTRIES_PER_SUBCRQ);
+	atomic_inc(&adapter->running_cap_queries);
+	ibmvnic_send_crq(adapter, &crq);
+
+	crq.query_capability.capability = cpu_to_be16(TX_RX_DESC_REQ);
+	atomic_inc(&adapter->running_cap_queries);
+	ibmvnic_send_crq(adapter, &crq);
+}
+
+static void handle_query_ip_offload_rsp(struct ibmvnic_adapter *adapter)
+{
+	struct device *dev = &adapter->vdev->dev;
+	struct ibmvnic_query_ip_offload_buffer *buf = &adapter->ip_offload_buf;
+	union ibmvnic_crq crq;
+	int i;
+
+	dma_unmap_single(dev, adapter->ip_offload_tok,
+			 sizeof(adapter->ip_offload_buf), DMA_FROM_DEVICE);
+
+	netdev_dbg(adapter->netdev, "Query IP Offload Buffer:\n");
+	for (i = 0; i < (sizeof(adapter->ip_offload_buf) - 1) / 8 + 1; i++)
+		netdev_dbg(adapter->netdev, "%016lx\n",
+			   ((unsigned long int *)(buf))[i]);
+
+	netdev_dbg(adapter->netdev, "ipv4_chksum = %d\n", buf->ipv4_chksum);
+	netdev_dbg(adapter->netdev, "ipv6_chksum = %d\n", buf->ipv6_chksum);
+	netdev_dbg(adapter->netdev, "tcp_ipv4_chksum = %d\n",
+		   buf->tcp_ipv4_chksum);
+	netdev_dbg(adapter->netdev, "tcp_ipv6_chksum = %d\n",
+		   buf->tcp_ipv6_chksum);
+	netdev_dbg(adapter->netdev, "udp_ipv4_chksum = %d\n",
+		   buf->udp_ipv4_chksum);
+	netdev_dbg(adapter->netdev, "udp_ipv6_chksum = %d\n",
+		   buf->udp_ipv6_chksum);
+	netdev_dbg(adapter->netdev, "large_tx_ipv4 = %d\n",
+		   buf->large_tx_ipv4);
+	netdev_dbg(adapter->netdev, "large_tx_ipv6 = %d\n",
+		   buf->large_tx_ipv6);
+	netdev_dbg(adapter->netdev, "large_rx_ipv4 = %d\n",
+		   buf->large_rx_ipv4);
+	netdev_dbg(adapter->netdev, "large_rx_ipv6 = %d\n",
+		   buf->large_rx_ipv6);
+	netdev_dbg(adapter->netdev, "max_ipv4_hdr_sz = %d\n",
+		   buf->max_ipv4_header_size);
+	netdev_dbg(adapter->netdev, "max_ipv6_hdr_sz = %d\n",
+		   buf->max_ipv6_header_size);
+	netdev_dbg(adapter->netdev, "max_tcp_hdr_size = %d\n",
+		   buf->max_tcp_header_size);
+	netdev_dbg(adapter->netdev, "max_udp_hdr_size = %d\n",
+		   buf->max_udp_header_size);
+	netdev_dbg(adapter->netdev, "max_large_tx_size = %d\n",
+		   buf->max_large_tx_size);
+	netdev_dbg(adapter->netdev, "max_large_rx_size = %d\n",
+		   buf->max_large_rx_size);
+	netdev_dbg(adapter->netdev, "ipv6_ext_hdr = %d\n",
+		   buf->ipv6_extension_header);
+	netdev_dbg(adapter->netdev, "tcp_pseudosum_req = %d\n",
+		   buf->tcp_pseudosum_req);
+	netdev_dbg(adapter->netdev, "num_ipv6_ext_hd = %d\n",
+		   buf->num_ipv6_ext_headers);
+	netdev_dbg(adapter->netdev, "off_ipv6_ext_hd = %d\n",
+		   buf->off_ipv6_ext_headers);
+
+	adapter->ip_offload_ctrl_tok =
+	    dma_map_single(dev, &adapter->ip_offload_ctrl,
+			   sizeof(adapter->ip_offload_ctrl), DMA_TO_DEVICE);
+
+	if (dma_mapping_error(dev, adapter->ip_offload_ctrl_tok)) {
+		dev_err(dev, "Couldn't map ip offload control buffer\n");
+		return;
+	}
+
+	adapter->ip_offload_ctrl.version = cpu_to_be32(INITIAL_VERSION_IOB);
+	adapter->ip_offload_ctrl.tcp_ipv4_chksum = buf->tcp_ipv4_chksum;
+	adapter->ip_offload_ctrl.udp_ipv4_chksum = buf->udp_ipv4_chksum;
+	adapter->ip_offload_ctrl.tcp_ipv6_chksum = buf->tcp_ipv6_chksum;
+	adapter->ip_offload_ctrl.udp_ipv6_chksum = buf->udp_ipv6_chksum;
+
+	/* large_tx/rx disabled for now, additional features needed */
+	adapter->ip_offload_ctrl.large_tx_ipv4 = 0;
+	adapter->ip_offload_ctrl.large_tx_ipv6 = 0;
+	adapter->ip_offload_ctrl.large_rx_ipv4 = 0;
+	adapter->ip_offload_ctrl.large_rx_ipv6 = 0;
+
+	adapter->netdev->features = NETIF_F_GSO;
+
+	if (buf->tcp_ipv4_chksum || buf->udp_ipv4_chksum)
+		adapter->netdev->features |= NETIF_F_IP_CSUM;
+
+	if (buf->tcp_ipv6_chksum || buf->udp_ipv6_chksum)
+		adapter->netdev->features |= NETIF_F_IPV6_CSUM;
+
+	memset(&crq, 0, sizeof(crq));
+	crq.control_ip_offload.first = IBMVNIC_CRQ_CMD;
+	crq.control_ip_offload.cmd = CONTROL_IP_OFFLOAD;
+	crq.control_ip_offload.len =
+	    cpu_to_be32(sizeof(adapter->ip_offload_ctrl));
+	crq.control_ip_offload.ioba = cpu_to_be32(adapter->ip_offload_ctrl_tok);
+	ibmvnic_send_crq(adapter, &crq);
+}
+
+static void handle_error_info_rsp(union ibmvnic_crq *crq,
+				  struct ibmvnic_adapter *adapter)
+{
+	struct device *dev = &adapter->vdev->dev;
+	struct ibmvnic_error_buff *error_buff, *tmp;
+	unsigned long flags;
+	bool found = false;
+	int i;
+
+	if (!crq->request_error_rsp.rc.code) {
+		dev_info(dev, "Request Error Rsp returned with rc=%x\n",
+			 crq->request_error_rsp.rc.code);
+		return;
+	}
+
+	spin_lock_irqsave(&adapter->error_list_lock, flags);
+	list_for_each_entry_safe(error_buff, tmp, &adapter->errors, list)
+		if (error_buff->error_id == crq->request_error_rsp.error_id) {
+			found = true;
+			list_del(&error_buff->list);
+			break;
+		}
+	spin_unlock_irqrestore(&adapter->error_list_lock, flags);
+
+	if (!found) {
+		dev_err(dev, "Couldn't find error id %x\n",
+			crq->request_error_rsp.error_id);
+		return;
+	}
+
+	dev_err(dev, "Detailed info for error id %x:",
+		crq->request_error_rsp.error_id);
+
+	for (i = 0; i < error_buff->len; i++) {
+		pr_cont("%02x", (int)error_buff->buff[i]);
+		if (i % 8 == 7)
+			pr_cont(" ");
+	}
+	pr_cont("\n");
+
+	dma_unmap_single(dev, error_buff->dma, error_buff->len,
+			 DMA_FROM_DEVICE);
+	kfree(error_buff->buff);
+	kfree(error_buff);
+}
+
+static void handle_dump_size_rsp(union ibmvnic_crq *crq,
+				 struct ibmvnic_adapter *adapter)
+{
+	int len = be32_to_cpu(crq->request_dump_size_rsp.len);
+	struct ibmvnic_inflight_cmd *inflight_cmd;
+	struct device *dev = &adapter->vdev->dev;
+	union ibmvnic_crq newcrq;
+	unsigned long flags;
+
+	/* allocate and map buffer */
+	adapter->dump_data = kmalloc(len, GFP_KERNEL);
+	if (!adapter->dump_data) {
+		complete(&adapter->fw_done);
+		return;
+	}
+
+	adapter->dump_data_token = dma_map_single(dev, adapter->dump_data, len,
+						  DMA_FROM_DEVICE);
+
+	if (dma_mapping_error(dev, adapter->dump_data_token)) {
+		if (!firmware_has_feature(FW_FEATURE_CMO))
+			dev_err(dev, "Couldn't map dump data\n");
+		kfree(adapter->dump_data);
+		complete(&adapter->fw_done);
+		return;
+	}
+
+	inflight_cmd = kmalloc(sizeof(*inflight_cmd), GFP_ATOMIC);
+	if (!inflight_cmd) {
+		dma_unmap_single(dev, adapter->dump_data_token, len,
+				 DMA_FROM_DEVICE);
+		kfree(adapter->dump_data);
+		complete(&adapter->fw_done);
+		return;
+	}
+
+	memset(&newcrq, 0, sizeof(newcrq));
+	newcrq.request_dump.first = IBMVNIC_CRQ_CMD;
+	newcrq.request_dump.cmd = REQUEST_DUMP;
+	newcrq.request_dump.ioba = cpu_to_be32(adapter->dump_data_token);
+	newcrq.request_dump.len = cpu_to_be32(adapter->dump_data_size);
+
+	memcpy(&inflight_cmd->crq, &newcrq, sizeof(newcrq));
+
+	spin_lock_irqsave(&adapter->inflight_lock, flags);
+	list_add_tail(&inflight_cmd->list, &adapter->inflight);
+	spin_unlock_irqrestore(&adapter->inflight_lock, flags);
+
+	ibmvnic_send_crq(adapter, &newcrq);
+}
+
+static void handle_error_indication(union ibmvnic_crq *crq,
+				    struct ibmvnic_adapter *adapter)
+{
+	int detail_len = be32_to_cpu(crq->error_indication.detail_error_sz);
+	struct ibmvnic_inflight_cmd *inflight_cmd;
+	struct device *dev = &adapter->vdev->dev;
+	struct ibmvnic_error_buff *error_buff;
+	union ibmvnic_crq new_crq;
+	unsigned long flags;
+
+	dev_err(dev, "Firmware reports %serror id %x, cause %d\n",
+		crq->error_indication.
+		    flags & IBMVNIC_FATAL_ERROR ? "FATAL " : "",
+		crq->error_indication.error_id,
+		crq->error_indication.error_cause);
+
+	error_buff = kmalloc(sizeof(*error_buff), GFP_ATOMIC);
+	if (!error_buff)
+		return;
+
+	error_buff->buff = kmalloc(detail_len, GFP_ATOMIC);
+	if (!error_buff->buff) {
+		kfree(error_buff);
+		return;
+	}
+
+	error_buff->dma = dma_map_single(dev, error_buff->buff, detail_len,
+					 DMA_FROM_DEVICE);
+	if (dma_mapping_error(dev, error_buff->dma)) {
+		if (!firmware_has_feature(FW_FEATURE_CMO))
+			dev_err(dev, "Couldn't map error buffer\n");
+		kfree(error_buff->buff);
+		kfree(error_buff);
+		return;
+	}
+
+	inflight_cmd = kmalloc(sizeof(*inflight_cmd), GFP_ATOMIC);
+	if (!inflight_cmd) {
+		dma_unmap_single(dev, error_buff->dma, detail_len,
+				 DMA_FROM_DEVICE);
+		kfree(error_buff->buff);
+		kfree(error_buff);
+		return;
+	}
+
+	error_buff->len = detail_len;
+	error_buff->error_id = crq->error_indication.error_id;
+
+	spin_lock_irqsave(&adapter->error_list_lock, flags);
+	list_add_tail(&error_buff->list, &adapter->errors);
+	spin_unlock_irqrestore(&adapter->error_list_lock, flags);
+
+	memset(&new_crq, 0, sizeof(new_crq));
+	new_crq.request_error_info.first = IBMVNIC_CRQ_CMD;
+	new_crq.request_error_info.cmd = REQUEST_ERROR_INFO;
+	new_crq.request_error_info.ioba = cpu_to_be32(error_buff->dma);
+	new_crq.request_error_info.len = cpu_to_be32(detail_len);
+	new_crq.request_error_info.error_id = crq->error_indication.error_id;
+
+	memcpy(&inflight_cmd->crq, &crq, sizeof(crq));
+
+	spin_lock_irqsave(&adapter->inflight_lock, flags);
+	list_add_tail(&inflight_cmd->list, &adapter->inflight);
+	spin_unlock_irqrestore(&adapter->inflight_lock, flags);
+
+	ibmvnic_send_crq(adapter, &new_crq);
+}
+
+static void handle_change_mac_rsp(union ibmvnic_crq *crq,
+				  struct ibmvnic_adapter *adapter)
+{
+	struct net_device *netdev = adapter->netdev;
+	struct device *dev = &adapter->vdev->dev;
+	long rc;
+
+	rc = crq->change_mac_addr_rsp.rc.code;
+	if (rc) {
+		dev_err(dev, "Error %ld in CHANGE_MAC_ADDR_RSP\n", rc);
+		return;
+	}
+	memcpy(netdev->dev_addr, &crq->change_mac_addr_rsp.mac_addr[0],
+	       ETH_ALEN);
+}
+
+static void handle_request_cap_rsp(union ibmvnic_crq *crq,
+				   struct ibmvnic_adapter *adapter)
+{
+	struct device *dev = &adapter->vdev->dev;
+	u64 *req_value;
+	char *name;
+
+	switch (be16_to_cpu(crq->request_capability_rsp.capability)) {
+	case REQ_TX_QUEUES:
+		req_value = &adapter->req_tx_queues;
+		name = "tx";
+		break;
+	case REQ_RX_QUEUES:
+		req_value = &adapter->req_rx_queues;
+		name = "rx";
+		break;
+	case REQ_RX_ADD_QUEUES:
+		req_value = &adapter->req_rx_add_queues;
+		name = "rx_add";
+		break;
+	case REQ_TX_ENTRIES_PER_SUBCRQ:
+		req_value = &adapter->req_tx_entries_per_subcrq;
+		name = "tx_entries_per_subcrq";
+		break;
+	case REQ_RX_ADD_ENTRIES_PER_SUBCRQ:
+		req_value = &adapter->req_rx_add_entries_per_subcrq;
+		name = "rx_add_entries_per_subcrq";
+		break;
+	case REQ_MTU:
+		req_value = &adapter->req_mtu;
+		name = "mtu";
+		break;
+	case PROMISC_REQUESTED:
+		req_value = &adapter->promisc;
+		name = "promisc";
+		break;
+	default:
+		dev_err(dev, "Got invalid cap request rsp %d\n",
+			crq->request_capability.capability);
+		return;
+	}
+
+	switch (crq->request_capability_rsp.rc.code) {
+	case SUCCESS:
+		break;
+	case PARTIALSUCCESS:
+		dev_info(dev, "req=%lld, rsp=%ld in %s queue, retrying.\n",
+			 *req_value,
+			 (long int)be32_to_cpu(crq->request_capability_rsp.
+					       number), name);
+		release_sub_crqs(adapter);
+		*req_value = be32_to_cpu(crq->request_capability_rsp.number);
+		complete(&adapter->init_done);
+		return;
+	default:
+		dev_err(dev, "Error %d in request cap rsp\n",
+			crq->request_capability_rsp.rc.code);
+		return;
+	}
+
+	/* Done receiving requested capabilities, query IP offload support */
+	if (++adapter->requested_caps == 7) {
+		union ibmvnic_crq newcrq;
+		int buf_sz = sizeof(struct ibmvnic_query_ip_offload_buffer);
+		struct ibmvnic_query_ip_offload_buffer *ip_offload_buf =
+		    &adapter->ip_offload_buf;
+
+		adapter->ip_offload_tok = dma_map_single(dev, ip_offload_buf,
+							 buf_sz,
+							 DMA_FROM_DEVICE);
+
+		if (dma_mapping_error(dev, adapter->ip_offload_tok)) {
+			if (!firmware_has_feature(FW_FEATURE_CMO))
+				dev_err(dev, "Couldn't map offload buffer\n");
+			return;
+		}
+
+		memset(&newcrq, 0, sizeof(newcrq));
+		newcrq.query_ip_offload.first = IBMVNIC_CRQ_CMD;
+		newcrq.query_ip_offload.cmd = QUERY_IP_OFFLOAD;
+		newcrq.query_ip_offload.len = cpu_to_be32(buf_sz);
+		newcrq.query_ip_offload.ioba =
+		    cpu_to_be32(adapter->ip_offload_tok);
+
+		ibmvnic_send_crq(adapter, &newcrq);
+	}
+}
+
+static int handle_login_rsp(union ibmvnic_crq *login_rsp_crq,
+			    struct ibmvnic_adapter *adapter)
+{
+	struct device *dev = &adapter->vdev->dev;
+	struct ibmvnic_login_rsp_buffer *login_rsp = adapter->login_rsp_buf;
+	struct ibmvnic_login_buffer *login = adapter->login_buf;
+	union ibmvnic_crq crq;
+	int i;
+
+	dma_unmap_single(dev, adapter->login_buf_token, adapter->login_buf_sz,
+			 DMA_BIDIRECTIONAL);
+	dma_unmap_single(dev, adapter->login_rsp_buf_token,
+			 adapter->login_rsp_buf_sz, DMA_BIDIRECTIONAL);
+
+	netdev_dbg(adapter->netdev, "Login Response Buffer:\n");
+	for (i = 0; i < (adapter->login_rsp_buf_sz - 1) / 8 + 1; i++) {
+		netdev_dbg(adapter->netdev, "%016lx\n",
+			   ((unsigned long int *)(adapter->login_rsp_buf))[i]);
+	}
+
+	/* Sanity checks */
+	if (login->num_txcomp_subcrqs != login_rsp->num_txsubm_subcrqs ||
+	    (be32_to_cpu(login->num_rxcomp_subcrqs) *
+	     adapter->req_rx_add_queues !=
+	     be32_to_cpu(login_rsp->num_rxadd_subcrqs))) {
+		dev_err(dev, "FATAL: Inconsistent login and login rsp\n");
+		ibmvnic_remove(adapter->vdev);
+		return -EIO;
+	}
+	complete(&adapter->init_done);
+
+	memset(&crq, 0, sizeof(crq));
+	crq.request_ras_comp_num.first = IBMVNIC_CRQ_CMD;
+	crq.request_ras_comp_num.cmd = REQUEST_RAS_COMP_NUM;
+	ibmvnic_send_crq(adapter, &crq);
+
+	return 0;
+}
+
+static void handle_request_map_rsp(union ibmvnic_crq *crq,
+				   struct ibmvnic_adapter *adapter)
+{
+	struct device *dev = &adapter->vdev->dev;
+	u8 map_id = crq->request_map_rsp.map_id;
+	int tx_subcrqs;
+	int rx_subcrqs;
+	long rc;
+	int i;
+
+	tx_subcrqs = be32_to_cpu(adapter->login_rsp_buf->num_txsubm_subcrqs);
+	rx_subcrqs = be32_to_cpu(adapter->login_rsp_buf->num_rxadd_subcrqs);
+
+	rc = crq->request_map_rsp.rc.code;
+	if (rc) {
+		dev_err(dev, "Error %ld in REQUEST_MAP_RSP\n", rc);
+		adapter->map_id--;
+		/* need to find and zero tx/rx_pool map_id */
+		for (i = 0; i < tx_subcrqs; i++) {
+			if (adapter->tx_pool[i].long_term_buff.map_id == map_id)
+				adapter->tx_pool[i].long_term_buff.map_id = 0;
+		}
+		for (i = 0; i < rx_subcrqs; i++) {
+			if (adapter->rx_pool[i].long_term_buff.map_id == map_id)
+				adapter->rx_pool[i].long_term_buff.map_id = 0;
+		}
+	}
+	complete(&adapter->fw_done);
+}
+
+static void handle_request_unmap_rsp(union ibmvnic_crq *crq,
+				     struct ibmvnic_adapter *adapter)
+{
+	struct device *dev = &adapter->vdev->dev;
+	long rc;
+
+	rc = crq->request_unmap_rsp.rc.code;
+	if (rc)
+		dev_err(dev, "Error %ld in REQUEST_UNMAP_RSP\n", rc);
+}
+
+static void handle_query_map_rsp(union ibmvnic_crq *crq,
+				 struct ibmvnic_adapter *adapter)
+{
+	struct net_device *netdev = adapter->netdev;
+	struct device *dev = &adapter->vdev->dev;
+	long rc;
+
+	rc = crq->query_map_rsp.rc.code;
+	if (rc) {
+		dev_err(dev, "Error %ld in QUERY_MAP_RSP\n", rc);
+		return;
+	}
+	netdev_dbg(netdev, "page_size = %d\ntot_pages = %d\nfree_pages = %d\n",
+		   crq->query_map_rsp.page_size, crq->query_map_rsp.tot_pages,
+		   crq->query_map_rsp.free_pages);
+}
+
+static void handle_query_cap_rsp(union ibmvnic_crq *crq,
+				 struct ibmvnic_adapter *adapter)
+{
+	struct net_device *netdev = adapter->netdev;
+	struct device *dev = &adapter->vdev->dev;
+	long rc;
+
+	atomic_dec(&adapter->running_cap_queries);
+	netdev_dbg(netdev, "Outstanding queries: %d\n",
+		   atomic_read(&adapter->running_cap_queries));
+	rc = crq->query_capability.rc.code;
+	if (rc) {
+		dev_err(dev, "Error %ld in QUERY_CAP_RSP\n", rc);
+		goto out;
+	}
+
+	switch (be16_to_cpu(crq->query_capability.capability)) {
+	case MIN_TX_QUEUES:
+		adapter->min_tx_queues =
+		    be32_to_cpu(crq->query_capability.number);
+		netdev_dbg(netdev, "min_tx_queues = %lld\n",
+			   adapter->min_tx_queues);
+		break;
+	case MIN_RX_QUEUES:
+		adapter->min_rx_queues =
+		    be32_to_cpu(crq->query_capability.number);
+		netdev_dbg(netdev, "min_rx_queues = %lld\n",
+			   adapter->min_rx_queues);
+		break;
+	case MIN_RX_ADD_QUEUES:
+		adapter->min_rx_add_queues =
+		    be32_to_cpu(crq->query_capability.number);
+		netdev_dbg(netdev, "min_rx_add_queues = %lld\n",
+			   adapter->min_rx_add_queues);
+		break;
+	case MAX_TX_QUEUES:
+		adapter->max_tx_queues =
+		    be32_to_cpu(crq->query_capability.number);
+		netdev_dbg(netdev, "max_tx_queues = %lld\n",
+			   adapter->max_tx_queues);
+		break;
+	case MAX_RX_QUEUES:
+		adapter->max_rx_queues =
+		    be32_to_cpu(crq->query_capability.number);
+		netdev_dbg(netdev, "max_rx_queues = %lld\n",
+			   adapter->max_rx_queues);
+		break;
+	case MAX_RX_ADD_QUEUES:
+		adapter->max_rx_add_queues =
+		    be32_to_cpu(crq->query_capability.number);
+		netdev_dbg(netdev, "max_rx_add_queues = %lld\n",
+			   adapter->max_rx_add_queues);
+		break;
+	case MIN_TX_ENTRIES_PER_SUBCRQ:
+		adapter->min_tx_entries_per_subcrq =
+		    be32_to_cpu(crq->query_capability.number);
+		netdev_dbg(netdev, "min_tx_entries_per_subcrq = %lld\n",
+			   adapter->min_tx_entries_per_subcrq);
+		break;
+	case MIN_RX_ADD_ENTRIES_PER_SUBCRQ:
+		adapter->min_rx_add_entries_per_subcrq =
+		    be32_to_cpu(crq->query_capability.number);
+		netdev_dbg(netdev, "min_rx_add_entrs_per_subcrq = %lld\n",
+			   adapter->min_rx_add_entries_per_subcrq);
+		break;
+	case MAX_TX_ENTRIES_PER_SUBCRQ:
+		adapter->max_tx_entries_per_subcrq =
+		    be32_to_cpu(crq->query_capability.number);
+		netdev_dbg(netdev, "max_tx_entries_per_subcrq = %lld\n",
+			   adapter->max_tx_entries_per_subcrq);
+		break;
+	case MAX_RX_ADD_ENTRIES_PER_SUBCRQ:
+		adapter->max_rx_add_entries_per_subcrq =
+		    be32_to_cpu(crq->query_capability.number);
+		netdev_dbg(netdev, "max_rx_add_entrs_per_subcrq = %lld\n",
+			   adapter->max_rx_add_entries_per_subcrq);
+		break;
+	case TCP_IP_OFFLOAD:
+		adapter->tcp_ip_offload =
+		    be32_to_cpu(crq->query_capability.number);
+		netdev_dbg(netdev, "tcp_ip_offload = %lld\n",
+			   adapter->tcp_ip_offload);
+		break;
+	case PROMISC_SUPPORTED:
+		adapter->promisc_supported =
+		    be32_to_cpu(crq->query_capability.number);
+		netdev_dbg(netdev, "promisc_supported = %lld\n",
+			   adapter->promisc_supported);
+		break;
+	case MIN_MTU:
+		adapter->min_mtu = be32_to_cpu(crq->query_capability.number);
+		netdev_dbg(netdev, "min_mtu = %lld\n", adapter->min_mtu);
+		break;
+	case MAX_MTU:
+		adapter->max_mtu = be32_to_cpu(crq->query_capability.number);
+		netdev_dbg(netdev, "max_mtu = %lld\n", adapter->max_mtu);
+		break;
+	case MAX_MULTICAST_FILTERS:
+		adapter->max_multicast_filters =
+		    be32_to_cpu(crq->query_capability.number);
+		netdev_dbg(netdev, "max_multicast_filters = %lld\n",
+			   adapter->max_multicast_filters);
+		break;
+	case VLAN_HEADER_INSERTION:
+		adapter->vlan_header_insertion =
+		    be32_to_cpu(crq->query_capability.number);
+		if (adapter->vlan_header_insertion)
+			netdev->features |= NETIF_F_HW_VLAN_STAG_TX;
+		netdev_dbg(netdev, "vlan_header_insertion = %lld\n",
+			   adapter->vlan_header_insertion);
+		break;
+	case MAX_TX_SG_ENTRIES:
+		adapter->max_tx_sg_entries =
+		    be32_to_cpu(crq->query_capability.number);
+		netdev_dbg(netdev, "max_tx_sg_entries = %lld\n",
+			   adapter->max_tx_sg_entries);
+		break;
+	case RX_SG_SUPPORTED:
+		adapter->rx_sg_supported =
+		    be32_to_cpu(crq->query_capability.number);
+		netdev_dbg(netdev, "rx_sg_supported = %lld\n",
+			   adapter->rx_sg_supported);
+		break;
+	case OPT_TX_COMP_SUB_QUEUES:
+		adapter->opt_tx_comp_sub_queues =
+		    be32_to_cpu(crq->query_capability.number);
+		netdev_dbg(netdev, "opt_tx_comp_sub_queues = %lld\n",
+			   adapter->opt_tx_comp_sub_queues);
+		break;
+	case OPT_RX_COMP_QUEUES:
+		adapter->opt_rx_comp_queues =
+		    be32_to_cpu(crq->query_capability.number);
+		netdev_dbg(netdev, "opt_rx_comp_queues = %lld\n",
+			   adapter->opt_rx_comp_queues);
+		break;
+	case OPT_RX_BUFADD_Q_PER_RX_COMP_Q:
+		adapter->opt_rx_bufadd_q_per_rx_comp_q =
+		    be32_to_cpu(crq->query_capability.number);
+		netdev_dbg(netdev, "opt_rx_bufadd_q_per_rx_comp_q = %lld\n",
+			   adapter->opt_rx_bufadd_q_per_rx_comp_q);
+		break;
+	case OPT_TX_ENTRIES_PER_SUBCRQ:
+		adapter->opt_tx_entries_per_subcrq =
+		    be32_to_cpu(crq->query_capability.number);
+		netdev_dbg(netdev, "opt_tx_entries_per_subcrq = %lld\n",
+			   adapter->opt_tx_entries_per_subcrq);
+		break;
+	case OPT_RXBA_ENTRIES_PER_SUBCRQ:
+		adapter->opt_rxba_entries_per_subcrq =
+		    be32_to_cpu(crq->query_capability.number);
+		netdev_dbg(netdev, "opt_rxba_entries_per_subcrq = %lld\n",
+			   adapter->opt_rxba_entries_per_subcrq);
+		break;
+	case TX_RX_DESC_REQ:
+		adapter->tx_rx_desc_req = crq->query_capability.number;
+		netdev_dbg(netdev, "tx_rx_desc_req = %llx\n",
+			   adapter->tx_rx_desc_req);
+		break;
+
+	default:
+		netdev_err(netdev, "Got invalid cap rsp %d\n",
+			   crq->query_capability.capability);
+	}
+
+out:
+	if (atomic_read(&adapter->running_cap_queries) == 0)
+		complete(&adapter->init_done);
+		/* We're done querying the capabilities, initialize sub-crqs */
+}
+
+static void handle_control_ras_rsp(union ibmvnic_crq *crq,
+				   struct ibmvnic_adapter *adapter)
+{
+	u8 correlator = crq->control_ras_rsp.correlator;
+	struct device *dev = &adapter->vdev->dev;
+	bool found = false;
+	int i;
+
+	if (crq->control_ras_rsp.rc.code) {
+		dev_warn(dev, "Control ras failed rc=%d\n",
+			 crq->control_ras_rsp.rc.code);
+		return;
+	}
+
+	for (i = 0; i < adapter->ras_comp_num; i++) {
+		if (adapter->ras_comps[i].correlator == correlator) {
+			found = true;
+			break;
+		}
+	}
+
+	if (!found) {
+		dev_warn(dev, "Correlator not found on control_ras_rsp\n");
+		return;
+	}
+
+	switch (crq->control_ras_rsp.op) {
+	case IBMVNIC_TRACE_LEVEL:
+		adapter->ras_comps[i].trace_level = crq->control_ras.level;
+		break;
+	case IBMVNIC_ERROR_LEVEL:
+		adapter->ras_comps[i].error_check_level =
+		    crq->control_ras.level;
+		break;
+	case IBMVNIC_TRACE_PAUSE:
+		adapter->ras_comp_int[i].paused = 1;
+		break;
+	case IBMVNIC_TRACE_RESUME:
+		adapter->ras_comp_int[i].paused = 0;
+		break;
+	case IBMVNIC_TRACE_ON:
+		adapter->ras_comps[i].trace_on = 1;
+		break;
+	case IBMVNIC_TRACE_OFF:
+		adapter->ras_comps[i].trace_on = 0;
+		break;
+	case IBMVNIC_CHG_TRACE_BUFF_SZ:
+		/* trace_buff_sz is 3 bytes, stuff it into an int */
+		((u8 *)(&adapter->ras_comps[i].trace_buff_size))[0] = 0;
+		((u8 *)(&adapter->ras_comps[i].trace_buff_size))[1] =
+		    crq->control_ras_rsp.trace_buff_sz[0];
+		((u8 *)(&adapter->ras_comps[i].trace_buff_size))[2] =
+		    crq->control_ras_rsp.trace_buff_sz[1];
+		((u8 *)(&adapter->ras_comps[i].trace_buff_size))[3] =
+		    crq->control_ras_rsp.trace_buff_sz[2];
+		break;
+	default:
+		dev_err(dev, "invalid op %d on control_ras_rsp",
+			crq->control_ras_rsp.op);
+	}
+}
+
+static int ibmvnic_fw_comp_open(struct inode *inode, struct file *file)
+{
+	file->private_data = inode->i_private;
+	return 0;
+}
+
+static ssize_t trace_read(struct file *file, char __user *user_buf, size_t len,
+			  loff_t *ppos)
+{
+	struct ibmvnic_fw_comp_internal *ras_comp_int = file->private_data;
+	struct ibmvnic_adapter *adapter = ras_comp_int->adapter;
+	struct device *dev = &adapter->vdev->dev;
+	struct ibmvnic_fw_trace_entry *trace;
+	int num = ras_comp_int->num;
+	union ibmvnic_crq crq;
+	dma_addr_t trace_tok;
+
+	if (*ppos >= be32_to_cpu(adapter->ras_comps[num].trace_buff_size))
+		return 0;
+
+	trace =
+	    dma_alloc_coherent(dev,
+			       be32_to_cpu(adapter->ras_comps[num].
+					   trace_buff_size), &trace_tok,
+			       GFP_KERNEL);
+	if (!trace) {
+		dev_err(dev, "Couldn't alloc trace buffer\n");
+		return 0;
+	}
+
+	memset(&crq, 0, sizeof(crq));
+	crq.collect_fw_trace.first = IBMVNIC_CRQ_CMD;
+	crq.collect_fw_trace.cmd = COLLECT_FW_TRACE;
+	crq.collect_fw_trace.correlator = adapter->ras_comps[num].correlator;
+	crq.collect_fw_trace.ioba = cpu_to_be32(trace_tok);
+	crq.collect_fw_trace.len = adapter->ras_comps[num].trace_buff_size;
+	ibmvnic_send_crq(adapter, &crq);
+
+	init_completion(&adapter->fw_done);
+	wait_for_completion(&adapter->fw_done);
+
+	if (*ppos + len > be32_to_cpu(adapter->ras_comps[num].trace_buff_size))
+		len =
+		    be32_to_cpu(adapter->ras_comps[num].trace_buff_size) -
+		    *ppos;
+
+	copy_to_user(user_buf, &((u8 *)trace)[*ppos], len);
+
+	dma_free_coherent(dev,
+			  be32_to_cpu(adapter->ras_comps[num].trace_buff_size),
+			  trace, trace_tok);
+	*ppos += len;
+	return len;
+}
+
+static const struct file_operations trace_ops = {
+	.owner		= THIS_MODULE,
+	.open		= ibmvnic_fw_comp_open,
+	.read		= trace_read,
+};
+
+static ssize_t paused_read(struct file *file, char __user *user_buf, size_t len,
+			   loff_t *ppos)
+{
+	struct ibmvnic_fw_comp_internal *ras_comp_int = file->private_data;
+	struct ibmvnic_adapter *adapter = ras_comp_int->adapter;
+	int num = ras_comp_int->num;
+	char buff[5]; /*  1 or 0 plus \n and \0 */
+	int size;
+
+	size = sprintf(buff, "%d\n", adapter->ras_comp_int[num].paused);
+
+	if (*ppos >= size)
+		return 0;
+
+	copy_to_user(user_buf, buff, size);
+	*ppos += size;
+	return size;
+}
+
+static ssize_t paused_write(struct file *file, const char __user *user_buf,
+			    size_t len, loff_t *ppos)
+{
+	struct ibmvnic_fw_comp_internal *ras_comp_int = file->private_data;
+	struct ibmvnic_adapter *adapter = ras_comp_int->adapter;
+	int num = ras_comp_int->num;
+	union ibmvnic_crq crq;
+	unsigned long val;
+	char buff[9]; /* decimal max int plus \n and \0 */
+
+	copy_from_user(buff, user_buf, sizeof(buff));
+	val = kstrtoul(buff, 10, NULL);
+
+	adapter->ras_comp_int[num].paused = val ? 1 : 0;
+
+	memset(&crq, 0, sizeof(crq));
+	crq.control_ras.first = IBMVNIC_CRQ_CMD;
+	crq.control_ras.cmd = CONTROL_RAS;
+	crq.control_ras.correlator = adapter->ras_comps[num].correlator;
+	crq.control_ras.op = val ? IBMVNIC_TRACE_PAUSE : IBMVNIC_TRACE_RESUME;
+	ibmvnic_send_crq(adapter, &crq);
+
+	return len;
+}
+
+static const struct file_operations paused_ops = {
+	.owner		= THIS_MODULE,
+	.open		= ibmvnic_fw_comp_open,
+	.read		= paused_read,
+	.write		= paused_write,
+};
+
+static ssize_t tracing_read(struct file *file, char __user *user_buf,
+			    size_t len, loff_t *ppos)
+{
+	struct ibmvnic_fw_comp_internal *ras_comp_int = file->private_data;
+	struct ibmvnic_adapter *adapter = ras_comp_int->adapter;
+	int num = ras_comp_int->num;
+	char buff[5]; /*  1 or 0 plus \n and \0 */
+	int size;
+
+	size = sprintf(buff, "%d\n", adapter->ras_comps[num].trace_on);
+
+	if (*ppos >= size)
+		return 0;
+
+	copy_to_user(user_buf, buff, size);
+	*ppos += size;
+	return size;
+}
+
+static ssize_t tracing_write(struct file *file, const char __user *user_buf,
+			     size_t len, loff_t *ppos)
+{
+	struct ibmvnic_fw_comp_internal *ras_comp_int = file->private_data;
+	struct ibmvnic_adapter *adapter = ras_comp_int->adapter;
+	int num = ras_comp_int->num;
+	union ibmvnic_crq crq;
+	unsigned long val;
+	char buff[9]; /* decimal max int plus \n and \0 */
+
+	copy_from_user(buff, user_buf, sizeof(buff));
+	val = kstrtoul(buff, 10, NULL);
+
+	memset(&crq, 0, sizeof(crq));
+	crq.control_ras.first = IBMVNIC_CRQ_CMD;
+	crq.control_ras.cmd = CONTROL_RAS;
+	crq.control_ras.correlator = adapter->ras_comps[num].correlator;
+	crq.control_ras.op = val ? IBMVNIC_TRACE_ON : IBMVNIC_TRACE_OFF;
+
+	return len;
+}
+
+static const struct file_operations tracing_ops = {
+	.owner		= THIS_MODULE,
+	.open		= ibmvnic_fw_comp_open,
+	.read		= tracing_read,
+	.write		= tracing_write,
+};
+
+static ssize_t error_level_read(struct file *file, char __user *user_buf,
+				size_t len, loff_t *ppos)
+{
+	struct ibmvnic_fw_comp_internal *ras_comp_int = file->private_data;
+	struct ibmvnic_adapter *adapter = ras_comp_int->adapter;
+	int num = ras_comp_int->num;
+	char buff[5]; /* decimal max char plus \n and \0 */
+	int size;
+
+	size = sprintf(buff, "%d\n", adapter->ras_comps[num].error_check_level);
+
+	if (*ppos >= size)
+		return 0;
+
+	copy_to_user(user_buf, buff, size);
+	*ppos += size;
+	return size;
+}
+
+static ssize_t error_level_write(struct file *file, const char __user *user_buf,
+				 size_t len, loff_t *ppos)
+{
+	struct ibmvnic_fw_comp_internal *ras_comp_int = file->private_data;
+	struct ibmvnic_adapter *adapter = ras_comp_int->adapter;
+	int num = ras_comp_int->num;
+	union ibmvnic_crq crq;
+	unsigned long val;
+	char buff[9]; /* decimal max int plus \n and \0 */
+
+	copy_from_user(buff, user_buf, sizeof(buff));
+	val = kstrtoul(buff, 10, NULL);
+
+	if (val > 9)
+		val = 9;
+
+	memset(&crq, 0, sizeof(crq));
+	crq.control_ras.first = IBMVNIC_CRQ_CMD;
+	crq.control_ras.cmd = CONTROL_RAS;
+	crq.control_ras.correlator = adapter->ras_comps[num].correlator;
+	crq.control_ras.op = IBMVNIC_ERROR_LEVEL;
+	crq.control_ras.level = val;
+	ibmvnic_send_crq(adapter, &crq);
+
+	return len;
+}
+
+static const struct file_operations error_level_ops = {
+	.owner		= THIS_MODULE,
+	.open		= ibmvnic_fw_comp_open,
+	.read		= error_level_read,
+	.write		= error_level_write,
+};
+
+static ssize_t trace_level_read(struct file *file, char __user *user_buf,
+				size_t len, loff_t *ppos)
+{
+	struct ibmvnic_fw_comp_internal *ras_comp_int = file->private_data;
+	struct ibmvnic_adapter *adapter = ras_comp_int->adapter;
+	int num = ras_comp_int->num;
+	char buff[5]; /* decimal max char plus \n and \0 */
+	int size;
+
+	size = sprintf(buff, "%d\n", adapter->ras_comps[num].trace_level);
+	if (*ppos >= size)
+		return 0;
+
+	copy_to_user(user_buf, buff, size);
+	*ppos += size;
+	return size;
+}
+
+static ssize_t trace_level_write(struct file *file, const char __user *user_buf,
+				 size_t len, loff_t *ppos)
+{
+	struct ibmvnic_fw_comp_internal *ras_comp_int = file->private_data;
+	struct ibmvnic_adapter *adapter = ras_comp_int->adapter;
+	union ibmvnic_crq crq;
+	unsigned long val;
+	char buff[9]; /* decimal max int plus \n and \0 */
+
+	copy_from_user(buff, user_buf, sizeof(buff));
+	val = kstrtoul(buff, 10, NULL);
+	if (val > 9)
+		val = 9;
+
+	memset(&crq, 0, sizeof(crq));
+	crq.control_ras.first = IBMVNIC_CRQ_CMD;
+	crq.control_ras.cmd = CONTROL_RAS;
+	crq.control_ras.correlator =
+	    adapter->ras_comps[ras_comp_int->num].correlator;
+	crq.control_ras.op = IBMVNIC_TRACE_LEVEL;
+	crq.control_ras.level = val;
+	ibmvnic_send_crq(adapter, &crq);
+
+	return len;
+}
+
+static const struct file_operations trace_level_ops = {
+	.owner		= THIS_MODULE,
+	.open		= ibmvnic_fw_comp_open,
+	.read		= trace_level_read,
+	.write		= trace_level_write,
+};
+
+static ssize_t trace_buff_size_read(struct file *file, char __user *user_buf,
+				    size_t len, loff_t *ppos)
+{
+	struct ibmvnic_fw_comp_internal *ras_comp_int = file->private_data;
+	struct ibmvnic_adapter *adapter = ras_comp_int->adapter;
+	int num = ras_comp_int->num;
+	char buff[9]; /* decimal max int plus \n and \0 */
+	int size;
+
+	size = sprintf(buff, "%d\n", adapter->ras_comps[num].trace_buff_size);
+	if (*ppos >= size)
+		return 0;
+
+	copy_to_user(user_buf, buff, size);
+	*ppos += size;
+	return size;
+}
+
+static ssize_t trace_buff_size_write(struct file *file,
+				     const char __user *user_buf, size_t len,
+				     loff_t *ppos)
+{
+	struct ibmvnic_fw_comp_internal *ras_comp_int = file->private_data;
+	struct ibmvnic_adapter *adapter = ras_comp_int->adapter;
+	union ibmvnic_crq crq;
+	unsigned long val;
+	char buff[9]; /* decimal max int plus \n and \0 */
+
+	copy_from_user(buff, user_buf, sizeof(buff));
+	val = kstrtoul(buff, 10, NULL);
+
+	memset(&crq, 0, sizeof(crq));
+	crq.control_ras.first = IBMVNIC_CRQ_CMD;
+	crq.control_ras.cmd = CONTROL_RAS;
+	crq.control_ras.correlator =
+	    adapter->ras_comps[ras_comp_int->num].correlator;
+	crq.control_ras.op = IBMVNIC_CHG_TRACE_BUFF_SZ;
+	/* trace_buff_sz is 3 bytes, stuff an int into it */
+	crq.control_ras.trace_buff_sz[0] = ((u8 *)(&val))[5];
+	crq.control_ras.trace_buff_sz[1] = ((u8 *)(&val))[6];
+	crq.control_ras.trace_buff_sz[2] = ((u8 *)(&val))[7];
+	ibmvnic_send_crq(adapter, &crq);
+
+	return len;
+}
+
+static const struct file_operations trace_size_ops = {
+	.owner		= THIS_MODULE,
+	.open		= ibmvnic_fw_comp_open,
+	.read		= trace_buff_size_read,
+	.write		= trace_buff_size_write,
+};
+
+static void handle_request_ras_comps_rsp(union ibmvnic_crq *crq,
+					 struct ibmvnic_adapter *adapter)
+{
+	struct device *dev = &adapter->vdev->dev;
+	struct dentry *dir_ent;
+	struct dentry *ent;
+	int i;
+
+	debugfs_remove_recursive(adapter->ras_comps_ent);
+
+	adapter->ras_comps_ent = debugfs_create_dir("ras_comps",
+						    adapter->debugfs_dir);
+	if (!adapter->ras_comps_ent || IS_ERR(adapter->ras_comps_ent)) {
+		dev_info(dev, "debugfs create ras_comps dir failed\n");
+		return;
+	}
+
+	for (i = 0; i < adapter->ras_comp_num; i++) {
+		dir_ent = debugfs_create_dir(adapter->ras_comps[i].name,
+					     adapter->ras_comps_ent);
+		if (!dir_ent || IS_ERR(dir_ent)) {
+			dev_info(dev, "debugfs create %s dir failed\n",
+				 adapter->ras_comps[i].name);
+			continue;
+		}
+
+		adapter->ras_comp_int[i].adapter = adapter;
+		adapter->ras_comp_int[i].num = i;
+		adapter->ras_comp_int[i].desc_blob.data =
+		    &adapter->ras_comps[i].description;
+		adapter->ras_comp_int[i].desc_blob.size =
+		    sizeof(adapter->ras_comps[i].description);
+
+		/* Don't need to remember the dentry's because the debugfs dir
+		 * gets removed recursively
+		 */
+		ent = debugfs_create_blob("description", S_IRUGO, dir_ent,
+					  &adapter->ras_comp_int[i].desc_blob);
+		ent = debugfs_create_file("trace_buf_size", S_IRUGO | S_IWUSR,
+					  dir_ent, &adapter->ras_comp_int[i],
+					  &trace_size_ops);
+		ent = debugfs_create_file("trace_level",
+					  S_IRUGO |
+					  (adapter->ras_comps[i].trace_level !=
+					   0xFF  ? S_IWUSR : 0),
+					   dir_ent, &adapter->ras_comp_int[i],
+					   &trace_level_ops);
+		ent = debugfs_create_file("error_level",
+					  S_IRUGO |
+					  (adapter->
+					   ras_comps[i].error_check_level !=
+					   0xFF ? S_IWUSR : 0),
+					  dir_ent, &adapter->ras_comp_int[i],
+					  &trace_level_ops);
+		ent = debugfs_create_file("tracing", S_IRUGO | S_IWUSR,
+					  dir_ent, &adapter->ras_comp_int[i],
+					  &tracing_ops);
+		ent = debugfs_create_file("paused", S_IRUGO | S_IWUSR,
+					  dir_ent, &adapter->ras_comp_int[i],
+					  &paused_ops);
+		ent = debugfs_create_file("trace", S_IRUGO, dir_ent,
+					  &adapter->ras_comp_int[i],
+					  &trace_ops);
+	}
+}
+
+static void handle_request_ras_comp_num_rsp(union ibmvnic_crq *crq,
+					    struct ibmvnic_adapter *adapter)
+{
+	int len = adapter->ras_comp_num * sizeof(struct ibmvnic_fw_component);
+	struct device *dev = &adapter->vdev->dev;
+	union ibmvnic_crq newcrq;
+
+	adapter->ras_comps = dma_alloc_coherent(dev, len,
+						&adapter->ras_comps_tok,
+						GFP_KERNEL);
+	if (!adapter->ras_comps) {
+		if (!firmware_has_feature(FW_FEATURE_CMO))
+			dev_err(dev, "Couldn't alloc fw comps buffer\n");
+		return;
+	}
+
+	adapter->ras_comp_int = kmalloc(adapter->ras_comp_num *
+					sizeof(struct ibmvnic_fw_comp_internal),
+					GFP_KERNEL);
+	if (!adapter->ras_comp_int)
+		dma_free_coherent(dev, len, adapter->ras_comps,
+				  adapter->ras_comps_tok);
+
+	memset(&newcrq, 0, sizeof(newcrq));
+	newcrq.request_ras_comps.first = IBMVNIC_CRQ_CMD;
+	newcrq.request_ras_comps.cmd = REQUEST_RAS_COMPS;
+	newcrq.request_ras_comps.ioba = cpu_to_be32(adapter->ras_comps_tok);
+	newcrq.request_ras_comps.len = cpu_to_be32(len);
+	ibmvnic_send_crq(adapter, &newcrq);
+}
+
+static void ibmvnic_free_inflight(struct ibmvnic_adapter *adapter)
+{
+	struct ibmvnic_inflight_cmd *inflight_cmd, *tmp1;
+	struct device *dev = &adapter->vdev->dev;
+	struct ibmvnic_error_buff *error_buff, *tmp2;
+	unsigned long flags;
+	unsigned long flags2;
+
+	spin_lock_irqsave(&adapter->inflight_lock, flags);
+	list_for_each_entry_safe(inflight_cmd, tmp1, &adapter->inflight, list) {
+		switch (inflight_cmd->crq.generic.cmd) {
+		case LOGIN:
+			dma_unmap_single(dev, adapter->login_buf_token,
+					 adapter->login_buf_sz,
+					 DMA_BIDIRECTIONAL);
+			dma_unmap_single(dev, adapter->login_rsp_buf_token,
+					 adapter->login_rsp_buf_sz,
+					 DMA_BIDIRECTIONAL);
+			kfree(adapter->login_rsp_buf);
+			kfree(adapter->login_buf);
+			break;
+		case REQUEST_DUMP:
+			complete(&adapter->fw_done);
+			break;
+		case REQUEST_ERROR_INFO:
+			spin_lock_irqsave(&adapter->error_list_lock, flags2);
+			list_for_each_entry_safe(error_buff, tmp2,
+						 &adapter->errors, list) {
+				dma_unmap_single(dev, error_buff->dma,
+						 error_buff->len,
+						 DMA_FROM_DEVICE);
+				kfree(error_buff->buff);
+				list_del(&error_buff->list);
+				kfree(error_buff);
+			}
+			spin_unlock_irqrestore(&adapter->error_list_lock,
+					       flags2);
+			break;
+		}
+		list_del(&inflight_cmd->list);
+		kfree(inflight_cmd);
+	}
+	spin_unlock_irqrestore(&adapter->inflight_lock, flags);
+}
+
+static void ibmvnic_handle_crq(union ibmvnic_crq *crq,
+			       struct ibmvnic_adapter *adapter)
+{
+	struct ibmvnic_generic_crq *gen_crq = &crq->generic;
+	struct net_device *netdev = adapter->netdev;
+	struct device *dev = &adapter->vdev->dev;
+	long rc;
+
+	netdev_dbg(netdev, "Handling CRQ: %016lx %016lx\n",
+		   ((unsigned long int *)crq)[0],
+		   ((unsigned long int *)crq)[1]);
+	switch (gen_crq->first) {
+	case IBMVNIC_CRQ_INIT_RSP:
+		switch (gen_crq->cmd) {
+		case IBMVNIC_CRQ_INIT:
+			dev_info(dev, "Partner initialized\n");
+			/* Send back a response */
+			rc = ibmvnic_send_crq_init_complete(adapter);
+			if (rc == 0)
+				send_version_xchg(adapter);
+			else
+				dev_err(dev, "Can't send initrsp rc=%ld\n", rc);
+			break;
+		case IBMVNIC_CRQ_INIT_COMPLETE:
+			dev_info(dev, "Partner initialization complete\n");
+			send_version_xchg(adapter);
+			break;
+		default:
+			dev_err(dev, "Unknown crq cmd: %d\n", gen_crq->cmd);
+		}
+		return;
+	case IBMVNIC_CRQ_XPORT_EVENT:
+		if (gen_crq->cmd == IBMVNIC_PARTITION_MIGRATED) {
+			dev_info(dev, "Re-enabling adapter\n");
+			adapter->migrated = true;
+			ibmvnic_free_inflight(adapter);
+			release_sub_crqs(adapter);
+			rc = ibmvnic_reenable_crq_queue(adapter);
+			if (rc)
+				dev_err(dev, "Error after enable rc=%ld\n", rc);
+			adapter->migrated = false;
+			rc = ibmvnic_send_crq_init(adapter);
+			if (rc)
+				dev_err(dev, "Error sending init rc=%ld\n", rc);
+		} else {
+			/* The adapter lost the connection */
+			dev_err(dev, "Virtual Adapter failed (rc=%d)\n",
+				gen_crq->cmd);
+			ibmvnic_free_inflight(adapter);
+			release_sub_crqs(adapter);
+		}
+		return;
+	case IBMVNIC_CRQ_CMD_RSP:
+		break;
+	default:
+		dev_err(dev, "Got an invalid msg type 0x%02x\n",
+			gen_crq->first);
+		return;
+	}
+
+	switch (gen_crq->cmd) {
+	case VERSION_EXCHANGE_RSP:
+		rc = crq->version_exchange_rsp.rc.code;
+		if (rc) {
+			dev_err(dev, "Error %ld in VERSION_EXCHG_RSP\n", rc);
+			break;
+		}
+		dev_info(dev, "Partner protocol version is %d\n",
+			 crq->version_exchange_rsp.version);
+		if (be16_to_cpu(crq->version_exchange_rsp.version) <
+		    ibmvnic_version)
+			ibmvnic_version =
+			    be16_to_cpu(crq->version_exchange_rsp.version);
+		send_cap_queries(adapter);
+		break;
+	case QUERY_CAPABILITY_RSP:
+		handle_query_cap_rsp(crq, adapter);
+		break;
+	case QUERY_MAP_RSP:
+		handle_query_map_rsp(crq, adapter);
+		break;
+	case REQUEST_MAP_RSP:
+		handle_request_map_rsp(crq, adapter);
+		break;
+	case REQUEST_UNMAP_RSP:
+		handle_request_unmap_rsp(crq, adapter);
+		break;
+	case REQUEST_CAPABILITY_RSP:
+		handle_request_cap_rsp(crq, adapter);
+		break;
+	case LOGIN_RSP:
+		netdev_dbg(netdev, "Got Login Response\n");
+		handle_login_rsp(crq, adapter);
+		break;
+	case LOGICAL_LINK_STATE_RSP:
+		netdev_dbg(netdev, "Got Logical Link State Response\n");
+		adapter->logical_link_state =
+		    crq->logical_link_state_rsp.link_state;
+		break;
+	case LINK_STATE_INDICATION:
+		netdev_dbg(netdev, "Got Logical Link State Indication\n");
+		adapter->phys_link_state =
+		    crq->link_state_indication.phys_link_state;
+		adapter->logical_link_state =
+		    crq->link_state_indication.logical_link_state;
+		break;
+	case CHANGE_MAC_ADDR_RSP:
+		netdev_dbg(netdev, "Got MAC address change Response\n");
+		handle_change_mac_rsp(crq, adapter);
+		break;
+	case ERROR_INDICATION:
+		netdev_dbg(netdev, "Got Error Indication\n");
+		handle_error_indication(crq, adapter);
+		break;
+	case REQUEST_ERROR_RSP:
+		netdev_dbg(netdev, "Got Error Detail Response\n");
+		handle_error_info_rsp(crq, adapter);
+		break;
+	case REQUEST_STATISTICS_RSP:
+		netdev_dbg(netdev, "Got Statistics Response\n");
+		complete(&adapter->stats_done);
+		break;
+	case REQUEST_DUMP_SIZE_RSP:
+		netdev_dbg(netdev, "Got Request Dump Size Response\n");
+		handle_dump_size_rsp(crq, adapter);
+		break;
+	case REQUEST_DUMP_RSP:
+		netdev_dbg(netdev, "Got Request Dump Response\n");
+		complete(&adapter->fw_done);
+		break;
+	case QUERY_IP_OFFLOAD_RSP:
+		netdev_dbg(netdev, "Got Query IP offload Response\n");
+		handle_query_ip_offload_rsp(adapter);
+		break;
+	case MULTICAST_CTRL_RSP:
+		netdev_dbg(netdev, "Got multicast control Response\n");
+		break;
+	case CONTROL_IP_OFFLOAD_RSP:
+		netdev_dbg(netdev, "Got Control IP offload Response\n");
+		dma_unmap_single(dev, adapter->ip_offload_ctrl_tok,
+				 sizeof(adapter->ip_offload_ctrl),
+				 DMA_TO_DEVICE);
+		/* We're done with the queries, perform the login */
+		send_login(adapter);
+		break;
+	case REQUEST_RAS_COMP_NUM_RSP:
+		netdev_dbg(netdev, "Got Request RAS Comp Num Response\n");
+		if (crq->request_ras_comp_num_rsp.rc.code == 10) {
+			netdev_dbg(netdev, "Request RAS Comp Num not supported\n");
+			break;
+		}
+		adapter->ras_comp_num =
+		    be32_to_cpu(crq->request_ras_comp_num_rsp.num_components);
+		handle_request_ras_comp_num_rsp(crq, adapter);
+		break;
+	case REQUEST_RAS_COMPS_RSP:
+		netdev_dbg(netdev, "Got Request RAS Comps Response\n");
+		handle_request_ras_comps_rsp(crq, adapter);
+		break;
+	case CONTROL_RAS_RSP:
+		netdev_dbg(netdev, "Got Control RAS Response\n");
+		handle_control_ras_rsp(crq, adapter);
+		break;
+	case COLLECT_FW_TRACE_RSP:
+		netdev_dbg(netdev, "Got Collect firmware trace Response\n");
+		complete(&adapter->fw_done);
+		break;
+	default:
+		netdev_err(netdev, "Got an invalid cmd type 0x%02x\n",
+			   gen_crq->cmd);
+	}
+}
+
+static irqreturn_t ibmvnic_interrupt(int irq, void *instance)
+{
+	struct ibmvnic_adapter *adapter = instance;
+	struct ibmvnic_crq_queue *queue = &adapter->crq;
+	struct vio_dev *vdev = adapter->vdev;
+	union ibmvnic_crq *crq;
+	unsigned long flags;
+	bool done = false;
+
+	spin_lock_irqsave(&queue->lock, flags);
+	vio_disable_interrupts(vdev);
+	while (!done) {
+		/* Pull all the valid messages off the CRQ */
+		while ((crq = ibmvnic_next_crq(adapter)) != NULL) {
+			ibmvnic_handle_crq(crq, adapter);
+			crq->generic.first = 0;
+		}
+		vio_enable_interrupts(vdev);
+		crq = ibmvnic_next_crq(adapter);
+		if (crq) {
+			vio_disable_interrupts(vdev);
+			ibmvnic_handle_crq(crq, adapter);
+			crq->generic.first = 0;
+		} else {
+			done = true;
+		}
+	}
+	spin_unlock_irqrestore(&queue->lock, flags);
+	return IRQ_HANDLED;
+}
+
+static int ibmvnic_reenable_crq_queue(struct ibmvnic_adapter *adapter)
+{
+	struct vio_dev *vdev = adapter->vdev;
+	int rc;
+
+	do {
+		rc = plpar_hcall_norets(H_ENABLE_CRQ, vdev->unit_address);
+	} while (rc == H_IN_PROGRESS || rc == H_BUSY || H_IS_LONG_BUSY(rc));
+
+	if (rc)
+		dev_err(&vdev->dev, "Error enabling adapter (rc=%d)\n", rc);
+
+	return rc;
+}
+
+static int ibmvnic_reset_crq(struct ibmvnic_adapter *adapter)
+{
+	struct ibmvnic_crq_queue *crq = &adapter->crq;
+	struct device *dev = &adapter->vdev->dev;
+	struct vio_dev *vdev = adapter->vdev;
+	int rc;
+
+	/* Close the CRQ */
+	do {
+		rc = plpar_hcall_norets(H_FREE_CRQ, vdev->unit_address);
+	} while (rc == H_BUSY || H_IS_LONG_BUSY(rc));
+
+	/* Clean out the queue */
+	memset(crq->msgs, 0, PAGE_SIZE);
+	crq->cur = 0;
+
+	/* And re-open it again */
+	rc = plpar_hcall_norets(H_REG_CRQ, vdev->unit_address,
+				crq->msg_token, PAGE_SIZE);
+
+	if (rc == H_CLOSED)
+		/* Adapter is good, but other end is not ready */
+		dev_warn(dev, "Partner adapter not ready\n");
+	else if (rc != 0)
+		dev_warn(dev, "Couldn't register crq (rc=%d)\n", rc);
+
+	return rc;
+}
+
+static void ibmvnic_release_crq_queue(struct ibmvnic_adapter *adapter)
+{
+	struct ibmvnic_crq_queue *crq = &adapter->crq;
+	struct vio_dev *vdev = adapter->vdev;
+	long rc;
+
+	netdev_dbg(adapter->netdev, "Releasing CRQ\n");
+	free_irq(vdev->irq, adapter);
+	do {
+		rc = plpar_hcall_norets(H_FREE_CRQ, vdev->unit_address);
+	} while (rc == H_BUSY || H_IS_LONG_BUSY(rc));
+
+	dma_unmap_single(&vdev->dev, crq->msg_token, PAGE_SIZE,
+			 DMA_BIDIRECTIONAL);
+	free_page((unsigned long)crq->msgs);
+}
+
+static int ibmvnic_init_crq_queue(struct ibmvnic_adapter *adapter)
+{
+	struct ibmvnic_crq_queue *crq = &adapter->crq;
+	struct device *dev = &adapter->vdev->dev;
+	struct vio_dev *vdev = adapter->vdev;
+	int rc, retrc = -ENOMEM;
+
+	crq->msgs = (union ibmvnic_crq *)get_zeroed_page(GFP_KERNEL);
+	/* Should we allocate more than one page? */
+
+	if (!crq->msgs)
+		return -ENOMEM;
+
+	crq->size = PAGE_SIZE / sizeof(*crq->msgs);
+	crq->msg_token = dma_map_single(dev, crq->msgs, PAGE_SIZE,
+					DMA_BIDIRECTIONAL);
+	if (dma_mapping_error(dev, crq->msg_token))
+		goto map_failed;
+
+	rc = plpar_hcall_norets(H_REG_CRQ, vdev->unit_address,
+				crq->msg_token, PAGE_SIZE);
+
+	if (rc == H_RESOURCE)
+		/* maybe kexecing and resource is busy. try a reset */
+		rc = ibmvnic_reset_crq(adapter);
+	retrc = rc;
+
+	if (rc == H_CLOSED) {
+		dev_warn(dev, "Partner adapter not ready\n");
+	} else if (rc) {
+		dev_warn(dev, "Error %d opening adapter\n", rc);
+		goto reg_crq_failed;
+	}
+
+	retrc = 0;
+
+	netdev_dbg(adapter->netdev, "registering irq 0x%x\n", vdev->irq);
+	rc = request_irq(vdev->irq, ibmvnic_interrupt, 0, IBMVNIC_NAME,
+			 adapter);
+	if (rc) {
+		dev_err(dev, "Couldn't register irq 0x%x. rc=%d\n",
+			vdev->irq, rc);
+		goto req_irq_failed;
+	}
+
+	rc = vio_enable_interrupts(vdev);
+	if (rc) {
+		dev_err(dev, "Error %d enabling interrupts\n", rc);
+		goto req_irq_failed;
+	}
+
+	crq->cur = 0;
+	spin_lock_init(&crq->lock);
+
+	return retrc;
+
+req_irq_failed:
+	do {
+		rc = plpar_hcall_norets(H_FREE_CRQ, vdev->unit_address);
+	} while (rc == H_BUSY || H_IS_LONG_BUSY(rc));
+reg_crq_failed:
+	dma_unmap_single(dev, crq->msg_token, PAGE_SIZE, DMA_BIDIRECTIONAL);
+map_failed:
+	free_page((unsigned long)crq->msgs);
+	return retrc;
+}
+
+/* debugfs for dump */
+static int ibmvnic_dump_show(struct seq_file *seq, void *v)
+{
+	struct net_device *netdev = seq->private;
+	struct ibmvnic_adapter *adapter = netdev_priv(netdev);
+	struct device *dev = &adapter->vdev->dev;
+	union ibmvnic_crq crq;
+
+	memset(&crq, 0, sizeof(crq));
+	crq.request_dump_size.first = IBMVNIC_CRQ_CMD;
+	crq.request_dump_size.cmd = REQUEST_DUMP_SIZE;
+	ibmvnic_send_crq(adapter, &crq);
+
+	init_completion(&adapter->fw_done);
+	wait_for_completion(&adapter->fw_done);
+
+	seq_write(seq, adapter->dump_data, adapter->dump_data_size);
+
+	dma_unmap_single(dev, adapter->dump_data_token, adapter->dump_data_size,
+			 DMA_BIDIRECTIONAL);
+
+	kfree(adapter->dump_data);
+
+	return 0;
+}
+
+static int ibmvnic_dump_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, ibmvnic_dump_show, inode->i_private);
+}
+
+static const struct file_operations ibmvnic_dump_ops = {
+	.owner          = THIS_MODULE,
+	.open           = ibmvnic_dump_open,
+	.read           = seq_read,
+	.llseek         = seq_lseek,
+	.release        = single_release,
+};
+
+static int ibmvnic_probe(struct vio_dev *dev, const struct vio_device_id *id)
+{
+	struct ibmvnic_adapter *adapter;
+	struct net_device *netdev;
+	unsigned char *mac_addr_p;
+	struct dentry *ent;
+	char buf[16]; /* debugfs name buf */
+	int rc;
+
+	dev_dbg(&dev->dev, "entering ibmvnic_probe for UA 0x%x\n",
+		dev->unit_address);
+
+	mac_addr_p = (unsigned char *)vio_get_attribute(dev,
+							VETH_MAC_ADDR, NULL);
+	if (!mac_addr_p) {
+		dev_err(&dev->dev,
+			"(%s:%3.3d) ERROR: Can't find MAC_ADDR attribute\n",
+			__FILE__, __LINE__);
+		return 0;
+	}
+
+	netdev = alloc_etherdev_mq(sizeof(struct ibmvnic_adapter),
+				   IBMVNIC_MAX_TX_QUEUES);
+	if (!netdev)
+		return -ENOMEM;
+
+	adapter = netdev_priv(netdev);
+	dev_set_drvdata(&dev->dev, netdev);
+	adapter->vdev = dev;
+	adapter->netdev = netdev;
+
+	ether_addr_copy(adapter->mac_addr, mac_addr_p);
+	ether_addr_copy(netdev->dev_addr, adapter->mac_addr);
+	netdev->irq = dev->irq;
+	netdev->netdev_ops = &ibmvnic_netdev_ops;
+	netdev->ethtool_ops = &ibmvnic_ethtool_ops;
+	SET_NETDEV_DEV(netdev, &dev->dev);
+
+	spin_lock_init(&adapter->stats_lock);
+
+	rc = ibmvnic_init_crq_queue(adapter);
+	if (rc) {
+		dev_err(&dev->dev, "Couldn't initialize crq. rc=%d\n", rc);
+		goto free_netdev;
+	}
+
+	INIT_LIST_HEAD(&adapter->errors);
+	INIT_LIST_HEAD(&adapter->inflight);
+	spin_lock_init(&adapter->error_list_lock);
+	spin_lock_init(&adapter->inflight_lock);
+
+	adapter->stats_token = dma_map_single(&dev->dev, &adapter->stats,
+					      sizeof(struct ibmvnic_statistics),
+					      DMA_FROM_DEVICE);
+	if (dma_mapping_error(&dev->dev, adapter->stats_token)) {
+		if (!firmware_has_feature(FW_FEATURE_CMO))
+			dev_err(&dev->dev, "Couldn't map stats buffer\n");
+		goto free_crq;
+	}
+
+	snprintf(buf, sizeof(buf), "ibmvnic_%x", dev->unit_address);
+	ent = debugfs_create_dir(buf, NULL);
+	if (!ent || IS_ERR(ent)) {
+		dev_info(&dev->dev, "debugfs create directory failed\n");
+		adapter->debugfs_dir = NULL;
+	} else {
+		adapter->debugfs_dir = ent;
+		ent = debugfs_create_file("dump", S_IRUGO, adapter->debugfs_dir,
+					  netdev, &ibmvnic_dump_ops);
+		if (!ent || IS_ERR(ent)) {
+			dev_info(&dev->dev,
+				 "debugfs create dump file failed\n");
+			adapter->debugfs_dump = NULL;
+		} else {
+			adapter->debugfs_dump = ent;
+		}
+	}
+	ibmvnic_send_crq_init(adapter);
+
+	init_completion(&adapter->init_done);
+	wait_for_completion(&adapter->init_done);
+
+	/* needed to pull init_sub_crqs outside of an interrupt context
+	 * because it creates IRQ mappings for the subCRQ queues, causing
+	 * a kernel warning
+	 */
+	init_sub_crqs(adapter, 0);
+
+	reinit_completion(&adapter->init_done);
+	wait_for_completion(&adapter->init_done);
+
+	/* if init_sub_crqs is partially successful, retry */
+	while (!adapter->tx_scrq || !adapter->rx_scrq) {
+		init_sub_crqs(adapter, 1);
+
+		reinit_completion(&adapter->init_done);
+		wait_for_completion(&adapter->init_done);
+	}
+
+	netdev->real_num_tx_queues = adapter->req_tx_queues;
+
+	rc = register_netdev(netdev);
+	if (rc) {
+		dev_err(&dev->dev, "failed to register netdev rc=%d\n", rc);
+		goto free_debugfs;
+	}
+	dev_info(&dev->dev, "ibmvnic registered\n");
+
+	return 0;
+
+free_debugfs:
+	if (adapter->debugfs_dir && !IS_ERR(adapter->debugfs_dir))
+		debugfs_remove_recursive(adapter->debugfs_dir);
+free_crq:
+	ibmvnic_release_crq_queue(adapter);
+free_netdev:
+	free_netdev(netdev);
+	return rc;
+}
+
+static int ibmvnic_remove(struct vio_dev *dev)
+{
+	struct net_device *netdev = dev_get_drvdata(&dev->dev);
+	struct ibmvnic_adapter *adapter = netdev_priv(netdev);
+
+	unregister_netdev(netdev);
+
+	release_sub_crqs(adapter);
+
+	ibmvnic_release_crq_queue(adapter);
+
+	if (adapter->debugfs_dir && !IS_ERR(adapter->debugfs_dir))
+		debugfs_remove_recursive(adapter->debugfs_dir);
+
+	if (adapter->ras_comps)
+		dma_free_coherent(&dev->dev,
+				  adapter->ras_comp_num *
+				  sizeof(struct ibmvnic_fw_component),
+				  adapter->ras_comps, adapter->ras_comps_tok);
+
+	kfree(adapter->ras_comp_int);
+
+	free_netdev(netdev);
+	dev_set_drvdata(&dev->dev, NULL);
+
+	return 0;
+}
+
+static unsigned long ibmvnic_get_desired_dma(struct vio_dev *vdev)
+{
+	struct net_device *netdev = dev_get_drvdata(&vdev->dev);
+	struct ibmvnic_adapter *adapter;
+	struct iommu_table *tbl;
+	unsigned long ret = 0;
+	int i;
+
+	tbl = get_iommu_table_base(&vdev->dev);
+
+	/* netdev inits at probe time along with the structures we need below*/
+	if (!netdev)
+		return IOMMU_PAGE_ALIGN(IBMVNIC_IO_ENTITLEMENT_DEFAULT, tbl);
+
+	adapter = netdev_priv(netdev);
+
+	ret += PAGE_SIZE; /* the crq message queue */
+	ret += adapter->bounce_buffer_size;
+	ret += IOMMU_PAGE_ALIGN(sizeof(struct ibmvnic_statistics), tbl);
+
+	for (i = 0; i < adapter->req_tx_queues + adapter->req_rx_queues; i++)
+		ret += 4 * PAGE_SIZE; /* the scrq message queue */
+
+	for (i = 0; i < be32_to_cpu(adapter->login_rsp_buf->num_rxadd_subcrqs);
+	     i++)
+		ret += adapter->rx_pool[i].size *
+		    IOMMU_PAGE_ALIGN(adapter->rx_pool[i].buff_size, tbl);
+
+	return ret;
+}
+
+static int ibmvnic_resume(struct device *dev)
+{
+	struct net_device *netdev = dev_get_drvdata(dev);
+	struct ibmvnic_adapter *adapter = netdev_priv(netdev);
+	int i;
+
+	/* kick the interrupt handlers just in case we lost an interrupt */
+	for (i = 0; i < adapter->req_rx_queues; i++)
+		ibmvnic_interrupt_rx(adapter->rx_scrq[i]->irq,
+				     adapter->rx_scrq[i]);
+
+	return 0;
+}
+
+static struct vio_device_id ibmvnic_device_table[] = {
+	{"network", "IBM,vnic"},
+	{"", "" }
+};
+MODULE_DEVICE_TABLE(vio, ibmvnic_device_table);
+
+static const struct dev_pm_ops ibmvnic_pm_ops = {
+	.resume = ibmvnic_resume
+};
+
+static struct vio_driver ibmvnic_driver = {
+	.id_table       = ibmvnic_device_table,
+	.probe          = ibmvnic_probe,
+	.remove         = ibmvnic_remove,
+	.get_desired_dma = ibmvnic_get_desired_dma,
+	.name		= ibmvnic_driver_name,
+	.pm		= &ibmvnic_pm_ops,
+};
+
+/* module functions */
+static int __init ibmvnic_module_init(void)
+{
+	pr_info("%s: %s %s\n", ibmvnic_driver_name, ibmvnic_driver_string,
+		IBMVNIC_DRIVER_VERSION);
+
+	return vio_register_driver(&ibmvnic_driver);
+}
+
+static void __exit ibmvnic_module_exit(void)
+{
+	vio_unregister_driver(&ibmvnic_driver);
+}
+
+module_init(ibmvnic_module_init);
+module_exit(ibmvnic_module_exit);
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/ibm/ibmvnic.h
@@ -0,0 +1,1046 @@
+/**************************************************************************/
+/*                                                                        */
+/*  IBM System i and System p Virtual NIC Device Driver                   */
+/*  Copyright (C) 2014 IBM Corp.                                          */
+/*  Santiago Leon (santi_leon@yahoo.com)                                  */
+/*  Thomas Falcon (tlfalcon@linux.vnet.ibm.com)                           */
+/*  John Allen (jallen@linux.vnet.ibm.com)                                */
+/*                                                                        */
+/*  This program is free software; you can redistribute it and/or modify  */
+/*  it under the terms of the GNU General Public License as published by  */
+/*  the Free Software Foundation; either version 2 of the License, or     */
+/*  (at your option) any later version.                                   */
+/*                                                                        */
+/*  This program is distributed in the hope that it will be useful,       */
+/*  but WITHOUT ANY WARRANTY; without even the implied warranty of        */
+/*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         */
+/*  GNU General Public License for more details.                          */
+/*                                                                        */
+/*  You should have received a copy of the GNU General Public License     */
+/*  along with this program.                                              */
+/*                                                                        */
+/* This module contains the implementation of a virtual ethernet device   */
+/* for use with IBM i/pSeries LPAR Linux.  It utilizes the logical LAN    */
+/* option of the RS/6000 Platform Architecture to interface with virtual */
+/* ethernet NICs that are presented to the partition by the hypervisor.   */
+/*                                                                        */
+/**************************************************************************/
+
+#define IBMVNIC_NAME		"ibmvnic"
+#define IBMVNIC_DRIVER_VERSION	"1.0"
+#define IBMVNIC_INVALID_MAP	-1
+#define IBMVNIC_STATS_TIMEOUT	1
+/* basic structures plus 100 2k buffers */
+#define IBMVNIC_IO_ENTITLEMENT_DEFAULT	610305
+
+/* Initial module_parameters */
+#define IBMVNIC_RX_WEIGHT		16
+/* when changing this, update IBMVNIC_IO_ENTITLEMENT_DEFAULT */
+#define IBMVNIC_BUFFS_PER_POOL	100
+#define IBMVNIC_MAX_TX_QUEUES	5
+
+struct ibmvnic_login_buffer {
+	__be32 len;
+	__be32 version;
+#define INITIAL_VERSION_LB 1
+	__be32 num_txcomp_subcrqs;
+	__be32 off_txcomp_subcrqs;
+	__be32 num_rxcomp_subcrqs;
+	__be32 off_rxcomp_subcrqs;
+	__be32 login_rsp_ioba;
+	__be32 login_rsp_len;
+} __packed __aligned(8);
+
+struct ibmvnic_login_rsp_buffer {
+	__be32 len;
+	__be32 version;
+#define INITIAL_VERSION_LRB 1
+	__be32 num_txsubm_subcrqs;
+	__be32 off_txsubm_subcrqs;
+	__be32 num_rxadd_subcrqs;
+	__be32 off_rxadd_subcrqs;
+	__be32 off_rxadd_buff_size;
+	__be32 num_supp_tx_desc;
+	__be32 off_supp_tx_desc;
+} __packed __aligned(8);
+
+struct ibmvnic_query_ip_offload_buffer {
+	__be32 len;
+	__be32 version;
+#define INITIAL_VERSION_IOB 1
+	u8 ipv4_chksum;
+	u8 ipv6_chksum;
+	u8 tcp_ipv4_chksum;
+	u8 tcp_ipv6_chksum;
+	u8 udp_ipv4_chksum;
+	u8 udp_ipv6_chksum;
+	u8 large_tx_ipv4;
+	u8 large_tx_ipv6;
+	u8 large_rx_ipv4;
+	u8 large_rx_ipv6;
+	u8 reserved1[14];
+	__be16 max_ipv4_header_size;
+	__be16 max_ipv6_header_size;
+	__be16 max_tcp_header_size;
+	__be16 max_udp_header_size;
+	__be32 max_large_tx_size;
+	__be32 max_large_rx_size;
+	u8 reserved2[16];
+	u8 ipv6_extension_header;
+#define IPV6_EH_NOT_SUPPORTED	0x00
+#define IPV6_EH_SUPPORTED_LIM	0x01
+#define IPV6_EH_SUPPORTED	0xFF
+	u8 tcp_pseudosum_req;
+#define TCP_PS_NOT_REQUIRED	0x00
+#define TCP_PS_REQUIRED		0x01
+	u8 reserved3[30];
+	__be16 num_ipv6_ext_headers;
+	__be32 off_ipv6_ext_headers;
+	u8 reserved4[154];
+} __packed __aligned(8);
+
+struct ibmvnic_control_ip_offload_buffer {
+	__be32 len;
+	__be32 version;
+#define INITIAL_VERSION_IOB 1
+	u8 ipv4_chksum;
+	u8 ipv6_chksum;
+	u8 tcp_ipv4_chksum;
+	u8 tcp_ipv6_chksum;
+	u8 udp_ipv4_chksum;
+	u8 udp_ipv6_chksum;
+	u8 large_tx_ipv4;
+	u8 large_tx_ipv6;
+	u8 bad_packet_rx;
+	u8 large_rx_ipv4;
+	u8 large_rx_ipv6;
+	u8 reserved4[111];
+} __packed __aligned(8);
+
+struct ibmvnic_fw_component {
+	u8 name[48];
+	__be32 trace_buff_size;
+	u8 correlator;
+	u8 trace_level;
+	u8 parent_correlator;
+	u8 error_check_level;
+	u8 trace_on;
+	u8 reserved[7];
+	u8 description[192];
+} __packed __aligned(8);
+
+struct ibmvnic_fw_trace_entry {
+	__be32 trace_id;
+	u8 num_valid_data;
+	u8 reserved[3];
+	__be64 pmc_registers;
+	__be64 timebase;
+	__be64 trace_data[5];
+} __packed __aligned(8);
+
+struct ibmvnic_statistics {
+	__be32 version;
+	__be32 promiscuous;
+	__be64 rx_packets;
+	__be64 rx_bytes;
+	__be64 tx_packets;
+	__be64 tx_bytes;
+	__be64 ucast_tx_packets;
+	__be64 ucast_rx_packets;
+	__be64 mcast_tx_packets;
+	__be64 mcast_rx_packets;
+	__be64 bcast_tx_packets;
+	__be64 bcast_rx_packets;
+	__be64 align_errors;
+	__be64 fcs_errors;
+	__be64 single_collision_frames;
+	__be64 multi_collision_frames;
+	__be64 sqe_test_errors;
+	__be64 deferred_tx;
+	__be64 late_collisions;
+	__be64 excess_collisions;
+	__be64 internal_mac_tx_errors;
+	__be64 carrier_sense;
+	__be64 too_long_frames;
+	__be64 internal_mac_rx_errors;
+	u8 reserved[72];
+} __packed __aligned(8);
+
+struct ibmvnic_acl_buffer {
+	__be32 len;
+	__be32 version;
+#define INITIAL_VERSION_IOB 1
+	u8 mac_acls_restrict;
+	u8 vlan_acls_restrict;
+	u8 reserved1[22];
+	__be32 num_mac_addrs;
+	__be32 offset_mac_addrs;
+	__be32 num_vlan_ids;
+	__be32 offset_vlan_ids;
+	u8 reserved2[80];
+} __packed __aligned(8);
+
+/* descriptors have been changed, how should this be defined?  1? 4? */
+
+#define IBMVNIC_TX_DESC_VERSIONS 3
+
+/* is this still needed? */
+struct ibmvnic_tx_comp_desc {
+	u8 first;
+	u8 num_comps;
+	__be16 rcs[5];
+	__be32 correlators[5];
+} __packed __aligned(8);
+
+/* some flags that included in v0 descriptor, which is gone
+ * only used for IBMVNIC_TCP_CHKSUM and IBMVNIC_UDP_CHKSUM
+ * and only in some offload_flags variable that doesn't seem
+ * to be used anywhere, can probably be removed?
+ */
+
+#define IBMVNIC_TCP_CHKSUM		0x20
+#define IBMVNIC_UDP_CHKSUM		0x08
+
+#define IBMVNIC_MAX_FRAGS_PER_CRQ 3
+
+struct ibmvnic_tx_desc {
+	u8 first;
+	u8 type;
+
+#define IBMVNIC_TX_DESC 0x10
+	u8 n_crq_elem;
+	u8 n_sge;
+	u8 flags1;
+#define IBMVNIC_TX_COMP_NEEDED		0x80
+#define IBMVNIC_TX_CHKSUM_OFFLOAD	0x40
+#define IBMVNIC_TX_LSO			0x20
+#define IBMVNIC_TX_PROT_TCP		0x10
+#define IBMVNIC_TX_PROT_UDP		0x08
+#define IBMVNIC_TX_PROT_IPV4		0x04
+#define IBMVNIC_TX_PROT_IPV6		0x02
+#define IBMVNIC_TX_VLAN_PRESENT		0x01
+	u8 flags2;
+#define IBMVNIC_TX_VLAN_INSERT		0x80
+	__be16 mss;
+	u8 reserved[4];
+	__be32 correlator;
+	__be16 vlan_id;
+	__be16 dma_reg;
+	__be32 sge_len;
+	__be64 ioba;
+} __packed __aligned(8);
+
+struct ibmvnic_hdr_desc {
+	u8 first;
+	u8 type;
+#define IBMVNIC_HDR_DESC		0x11
+	u8 len;
+	u8 l2_len;
+	__be16 l3_len;
+	u8 l4_len;
+	u8 flag;
+	u8 data[24];
+} __packed __aligned(8);
+
+struct ibmvnic_hdr_ext_desc {
+	u8 first;
+	u8 type;
+#define IBMVNIC_HDR_EXT_DESC		0x12
+	u8 len;
+	u8 data[29];
+} __packed __aligned(8);
+
+struct ibmvnic_sge_desc {
+	u8 first;
+	u8 type;
+#define IBMVNIC_SGE_DESC		0x30
+	__be16 sge1_dma_reg;
+	__be32 sge1_len;
+	__be64 sge1_ioba;
+	__be16 reserved;
+	__be16 sge2_dma_reg;
+	__be32 sge2_len;
+	__be64 sge2_ioba;
+} __packed __aligned(8);
+
+struct ibmvnic_rx_comp_desc {
+	u8 first;
+	u8 flags;
+#define IBMVNIC_IP_CHKSUM_GOOD		0x80
+#define IBMVNIC_TCP_UDP_CHKSUM_GOOD	0x40
+#define IBMVNIC_END_FRAME			0x20
+#define IBMVNIC_EXACT_MC			0x10
+#define IBMVNIC_VLAN_STRIPPED			0x08
+	__be16 off_frame_data;
+	__be32 len;
+	__be64 correlator;
+	__be16 vlan_tci;
+	__be16 rc;
+	u8 reserved[12];
+} __packed __aligned(8);
+
+struct ibmvnic_generic_scrq {
+	u8 first;
+	u8 reserved[31];
+} __packed __aligned(8);
+
+struct ibmvnic_rx_buff_add_desc {
+	u8 first;
+	u8 reserved[7];
+	__be64 correlator;
+	__be32 ioba;
+	u8 map_id;
+	__be32 len:24;
+	u8 reserved2[8];
+} __packed __aligned(8);
+
+struct ibmvnic_rc {
+	u8 code; /* one of enum ibmvnic_rc_codes */
+	u8 detailed_data[3];
+} __packed __aligned(4);
+
+struct ibmvnic_generic_crq {
+	u8 first;
+	u8 cmd;
+	u8 params[10];
+	struct ibmvnic_rc rc;
+} __packed __aligned(8);
+
+struct ibmvnic_version_exchange {
+	u8 first;
+	u8 cmd;
+	__be16 version;
+#define IBMVNIC_INITIAL_VERSION 1
+	u8 reserved[8];
+	struct ibmvnic_rc rc;
+} __packed __aligned(8);
+
+struct ibmvnic_capability {
+	u8 first;
+	u8 cmd;
+	__be16 capability; /* one of ibmvnic_capabilities */
+	struct ibmvnic_rc rc;
+	__be32 number; /*FIX: should be __be64, but I'm getting the least
+			* significant word first
+			*/
+} __packed __aligned(8);
+
+struct ibmvnic_login {
+	u8 first;
+	u8 cmd;
+	u8 reserved[6];
+	__be32 ioba;
+	__be32 len;
+} __packed __aligned(8);
+
+struct ibmvnic_phys_parms {
+	u8 first;
+	u8 cmd;
+	u8 flags1;
+#define IBMVNIC_EXTERNAL_LOOPBACK	0x80
+#define IBMVNIC_INTERNAL_LOOPBACK	0x40
+#define IBMVNIC_PROMISC		0x20
+#define IBMVNIC_PHYS_LINK_ACTIVE	0x10
+#define IBMVNIC_AUTONEG_DUPLEX	0x08
+#define IBMVNIC_FULL_DUPLEX	0x04
+#define IBMVNIC_HALF_DUPLEX	0x02
+#define IBMVNIC_CAN_CHG_PHYS_PARMS	0x01
+	u8 flags2;
+#define IBMVNIC_LOGICAL_LNK_ACTIVE 0x80
+	__be32 speed;
+#define IBMVNIC_AUTONEG		0x80
+#define IBMVNIC_10MBPS		0x40
+#define IBMVNIC_100MBPS		0x20
+#define IBMVNIC_1GBPS		0x10
+#define IBMVNIC_10GBPS		0x08
+	__be32 mtu;
+	struct ibmvnic_rc rc;
+} __packed __aligned(8);
+
+struct ibmvnic_logical_link_state {
+	u8 first;
+	u8 cmd;
+	u8 link_state;
+#define IBMVNIC_LOGICAL_LNK_DN 0x00
+#define IBMVNIC_LOGICAL_LNK_UP 0x01
+#define IBMVNIC_LOGICAL_LNK_QUERY 0xff
+	u8 reserved[9];
+	struct ibmvnic_rc rc;
+} __packed __aligned(8);
+
+struct ibmvnic_query_ip_offload {
+	u8 first;
+	u8 cmd;
+	u8 reserved[2];
+	__be32 len;
+	__be32 ioba;
+	struct ibmvnic_rc rc;
+} __packed __aligned(8);
+
+struct ibmvnic_control_ip_offload {
+	u8 first;
+	u8 cmd;
+	u8 reserved[2];
+	__be32 ioba;
+	__be32 len;
+	struct ibmvnic_rc rc;
+} __packed __aligned(8);
+
+struct ibmvnic_request_dump_size {
+	u8 first;
+	u8 cmd;
+	u8 reserved[6];
+	__be32 len;
+	struct ibmvnic_rc rc;
+} __packed __aligned(8);
+
+struct ibmvnic_request_dump {
+	u8 first;
+	u8 cmd;
+	u8 reserved1[2];
+	__be32 ioba;
+	__be32 len;
+	u8 reserved2[4];
+} __packed __aligned(8);
+
+struct ibmvnic_request_dump_rsp {
+	u8 first;
+	u8 cmd;
+	u8 reserved[6];
+	__be32 dumped_len;
+	struct ibmvnic_rc rc;
+} __packed __aligned(8);
+
+struct ibmvnic_request_ras_comp_num {
+	u8 first;
+	u8 cmd;
+	u8 reserved1[2];
+	__be32 num_components;
+	u8 reserved2[4];
+	struct ibmvnic_rc rc;
+} __packed __aligned(8);
+
+struct ibmvnic_request_ras_comps {
+	u8 first;
+	u8 cmd;
+	u8 reserved[2];
+	__be32 ioba;
+	__be32 len;
+	struct ibmvnic_rc rc;
+} __packed __aligned(8);
+
+struct ibmvnic_control_ras {
+	u8 first;
+	u8 cmd;
+	u8 correlator;
+	u8 level;
+	u8 op;
+#define IBMVNIC_TRACE_LEVEL	1
+#define IBMVNIC_ERROR_LEVEL	2
+#define IBMVNIC_TRACE_PAUSE	3
+#define IBMVNIC_TRACE_RESUME	4
+#define IBMVNIC_TRACE_ON		5
+#define IBMVNIC_TRACE_OFF		6
+#define IBMVNIC_CHG_TRACE_BUFF_SZ	7
+	u8 trace_buff_sz[3];
+	u8 reserved[4];
+	struct ibmvnic_rc rc;
+} __packed __aligned(8);
+
+struct ibmvnic_collect_fw_trace {
+	u8 first;
+	u8 cmd;
+	u8 correlator;
+	u8 reserved;
+	__be32 ioba;
+	__be32 len;
+	struct ibmvnic_rc rc;
+} __packed __aligned(8);
+
+struct ibmvnic_request_statistics {
+	u8 first;
+	u8 cmd;
+	u8 flags;
+#define IBMVNIC_PHYSICAL_PORT	0x80
+	u8 reserved1;
+	__be32 ioba;
+	__be32 len;
+	u8 reserved[4];
+} __packed __aligned(8);
+
+struct ibmvnic_request_debug_stats {
+	u8 first;
+	u8 cmd;
+	u8 reserved[2];
+	__be32 ioba;
+	__be32 len;
+	struct ibmvnic_rc rc;
+} __packed __aligned(8);
+
+struct ibmvnic_error_indication {
+	u8 first;
+	u8 cmd;
+	u8 flags;
+#define IBMVNIC_FATAL_ERROR	0x80
+	u8 reserved1;
+	__be32 error_id;
+	__be32 detail_error_sz;
+	__be16 error_cause;
+	u8 reserved2[2];
+} __packed __aligned(8);
+
+struct ibmvnic_request_error_info {
+	u8 first;
+	u8 cmd;
+	u8 reserved[2];
+	__be32 ioba;
+	__be32 len;
+	__be32 error_id;
+} __packed __aligned(8);
+
+struct ibmvnic_request_error_rsp {
+	u8 first;
+	u8 cmd;
+	u8 reserved[2];
+	__be32 error_id;
+	__be32 len;
+	struct ibmvnic_rc rc;
+} __packed __aligned(8);
+
+struct ibmvnic_link_state_indication {
+	u8 first;
+	u8 cmd;
+	u8 reserved1[2];
+	u8 phys_link_state;
+	u8 logical_link_state;
+	u8 reserved2[10];
+} __packed __aligned(8);
+
+struct ibmvnic_change_mac_addr {
+	u8 first;
+	u8 cmd;
+	u8 mac_addr[6];
+	struct ibmvnic_rc rc;
+	u8 reserved[4];
+} __packed __aligned(8);
+
+struct ibmvnic_multicast_ctrl {
+	u8 first;
+	u8 cmd;
+	u8 mac_addr[6];
+	u8 flags;
+#define IBMVNIC_ENABLE_MC		0x80
+#define IBMVNIC_DISABLE_MC		0x40
+#define IBMVNIC_ENABLE_ALL		0x20
+#define IBMVNIC_DISABLE_ALL	0x10
+	u8 reserved1;
+	__be16 reserved2; /* was num_enabled_mc_addr; */
+	struct ibmvnic_rc rc;
+} __packed __aligned(8);
+
+struct ibmvnic_get_vpd_size_rsp {
+	u8 first;
+	u8 cmd;
+	u8 reserved[2];
+	__be64 len;
+	struct ibmvnic_rc rc;
+} __packed __aligned(8);
+
+struct ibmvnic_get_vpd {
+	u8 first;
+	u8 cmd;
+	u8 reserved1[2];
+	__be32 ioba;
+	__be32 len;
+	u8 reserved[4];
+} __packed __aligned(8);
+
+struct ibmvnic_acl_change_indication {
+	u8 first;
+	u8 cmd;
+	__be16 change_type;
+#define IBMVNIC_MAC_ACL 0
+#define IBMVNIC_VLAN_ACL 1
+	u8 reserved[12];
+} __packed __aligned(8);
+
+struct ibmvnic_acl_query {
+	u8 first;
+	u8 cmd;
+	u8 reserved1[2];
+	__be32 ioba;
+	__be32 len;
+	u8 reserved2[4];
+} __packed __aligned(8);
+
+struct ibmvnic_tune {
+	u8 first;
+	u8 cmd;
+	u8 reserved1[2];
+	__be32 ioba;
+	__be32 len;
+	u8 reserved2[4];
+} __packed __aligned(8);
+
+struct ibmvnic_request_map {
+	u8 first;
+	u8 cmd;
+	u8 reserved1;
+	u8 map_id;
+	__be32 ioba;
+	__be32 len;
+	u8 reserved2[4];
+} __packed __aligned(8);
+
+struct ibmvnic_request_map_rsp {
+	u8 first;
+	u8 cmd;
+	u8 reserved1;
+	u8 map_id;
+	u8 reserved2[4];
+	struct ibmvnic_rc rc;
+} __packed __aligned(8);
+
+struct ibmvnic_request_unmap {
+	u8 first;
+	u8 cmd;
+	u8 reserved1;
+	u8 map_id;
+	u8 reserved2[12];
+} __packed __aligned(8);
+
+struct ibmvnic_request_unmap_rsp {
+	u8 first;
+	u8 cmd;
+	u8 reserved1;
+	u8 map_id;
+	u8 reserved2[8];
+	struct ibmvnic_rc rc;
+} __packed __aligned(8);
+
+struct ibmvnic_query_map {
+	u8 first;
+	u8 cmd;
+	u8 reserved[14];
+} __packed __aligned(8);
+
+struct ibmvnic_query_map_rsp {
+	u8 first;
+	u8 cmd;
+	u8 reserved;
+	u8 page_size;
+	__be32 tot_pages;
+	__be32 free_pages;
+	struct ibmvnic_rc rc;
+} __packed __aligned(8);
+
+union ibmvnic_crq {
+	struct ibmvnic_generic_crq generic;
+	struct ibmvnic_version_exchange version_exchange;
+	struct ibmvnic_version_exchange version_exchange_rsp;
+	struct ibmvnic_capability query_capability;
+	struct ibmvnic_capability query_capability_rsp;
+	struct ibmvnic_capability request_capability;
+	struct ibmvnic_capability request_capability_rsp;
+	struct ibmvnic_login login;
+	struct ibmvnic_generic_crq login_rsp;
+	struct ibmvnic_phys_parms query_phys_parms;
+	struct ibmvnic_phys_parms query_phys_parms_rsp;
+	struct ibmvnic_phys_parms query_phys_capabilities;
+	struct ibmvnic_phys_parms query_phys_capabilities_rsp;
+	struct ibmvnic_phys_parms set_phys_parms;
+	struct ibmvnic_phys_parms set_phys_parms_rsp;
+	struct ibmvnic_logical_link_state logical_link_state;
+	struct ibmvnic_logical_link_state logical_link_state_rsp;
+	struct ibmvnic_query_ip_offload query_ip_offload;
+	struct ibmvnic_query_ip_offload query_ip_offload_rsp;
+	struct ibmvnic_control_ip_offload control_ip_offload;
+	struct ibmvnic_control_ip_offload control_ip_offload_rsp;
+	struct ibmvnic_request_dump_size request_dump_size;
+	struct ibmvnic_request_dump_size request_dump_size_rsp;
+	struct ibmvnic_request_dump request_dump;
+	struct ibmvnic_request_dump_rsp request_dump_rsp;
+	struct ibmvnic_request_ras_comp_num request_ras_comp_num;
+	struct ibmvnic_request_ras_comp_num request_ras_comp_num_rsp;
+	struct ibmvnic_request_ras_comps request_ras_comps;
+	struct ibmvnic_request_ras_comps request_ras_comps_rsp;
+	struct ibmvnic_control_ras control_ras;
+	struct ibmvnic_control_ras control_ras_rsp;
+	struct ibmvnic_collect_fw_trace collect_fw_trace;
+	struct ibmvnic_collect_fw_trace collect_fw_trace_rsp;
+	struct ibmvnic_request_statistics request_statistics;
+	struct ibmvnic_generic_crq request_statistics_rsp;
+	struct ibmvnic_request_debug_stats request_debug_stats;
+	struct ibmvnic_request_debug_stats request_debug_stats_rsp;
+	struct ibmvnic_error_indication error_indication;
+	struct ibmvnic_request_error_info request_error_info;
+	struct ibmvnic_request_error_rsp request_error_rsp;
+	struct ibmvnic_link_state_indication link_state_indication;
+	struct ibmvnic_change_mac_addr change_mac_addr;
+	struct ibmvnic_change_mac_addr change_mac_addr_rsp;
+	struct ibmvnic_multicast_ctrl multicast_ctrl;
+	struct ibmvnic_multicast_ctrl multicast_ctrl_rsp;
+	struct ibmvnic_generic_crq get_vpd_size;
+	struct ibmvnic_get_vpd_size_rsp get_vpd_size_rsp;
+	struct ibmvnic_get_vpd get_vpd;
+	struct ibmvnic_generic_crq get_vpd_rsp;
+	struct ibmvnic_acl_change_indication acl_change_indication;
+	struct ibmvnic_acl_query acl_query;
+	struct ibmvnic_generic_crq acl_query_rsp;
+	struct ibmvnic_tune tune;
+	struct ibmvnic_generic_crq tune_rsp;
+	struct ibmvnic_request_map request_map;
+	struct ibmvnic_request_map_rsp request_map_rsp;
+	struct ibmvnic_request_unmap request_unmap;
+	struct ibmvnic_request_unmap_rsp request_unmap_rsp;
+	struct ibmvnic_query_map query_map;
+	struct ibmvnic_query_map_rsp query_map_rsp;
+};
+
+enum ibmvnic_rc_codes {
+	SUCCESS = 0,
+	PARTIALSUCCESS = 1,
+	PERMISSION = 2,
+	NOMEMORY = 3,
+	PARAMETER = 4,
+	UNKNOWNCOMMAND = 5,
+	ABORTED = 6,
+	INVALIDSTATE = 7,
+	INVALIDIOBA = 8,
+	INVALIDLENGTH = 9,
+	UNSUPPORTEDOPTION = 10,
+};
+
+enum ibmvnic_capabilities {
+	MIN_TX_QUEUES = 1,
+	MIN_RX_QUEUES = 2,
+	MIN_RX_ADD_QUEUES = 3,
+	MAX_TX_QUEUES = 4,
+	MAX_RX_QUEUES = 5,
+	MAX_RX_ADD_QUEUES = 6,
+	REQ_TX_QUEUES = 7,
+	REQ_RX_QUEUES = 8,
+	REQ_RX_ADD_QUEUES = 9,
+	MIN_TX_ENTRIES_PER_SUBCRQ = 10,
+	MIN_RX_ADD_ENTRIES_PER_SUBCRQ = 11,
+	MAX_TX_ENTRIES_PER_SUBCRQ = 12,
+	MAX_RX_ADD_ENTRIES_PER_SUBCRQ = 13,
+	REQ_TX_ENTRIES_PER_SUBCRQ = 14,
+	REQ_RX_ADD_ENTRIES_PER_SUBCRQ = 15,
+	TCP_IP_OFFLOAD = 16,
+	PROMISC_REQUESTED = 17,
+	PROMISC_SUPPORTED = 18,
+	MIN_MTU = 19,
+	MAX_MTU = 20,
+	REQ_MTU = 21,
+	MAX_MULTICAST_FILTERS = 22,
+	VLAN_HEADER_INSERTION = 23,
+	MAX_TX_SG_ENTRIES = 25,
+	RX_SG_SUPPORTED = 26,
+	RX_SG_REQUESTED = 27,
+	OPT_TX_COMP_SUB_QUEUES = 28,
+	OPT_RX_COMP_QUEUES = 29,
+	OPT_RX_BUFADD_Q_PER_RX_COMP_Q = 30,
+	OPT_TX_ENTRIES_PER_SUBCRQ = 31,
+	OPT_RXBA_ENTRIES_PER_SUBCRQ = 32,
+	TX_RX_DESC_REQ = 33,
+};
+
+enum ibmvnic_error_cause {
+	ADAPTER_PROBLEM = 0,
+	BUS_PROBLEM = 1,
+	FW_PROBLEM = 2,
+	DD_PROBLEM = 3,
+	EEH_RECOVERY = 4,
+	FW_UPDATED = 5,
+	LOW_MEMORY = 6,
+};
+
+enum ibmvnic_commands {
+	VERSION_EXCHANGE = 0x01,
+	VERSION_EXCHANGE_RSP = 0x81,
+	QUERY_CAPABILITY = 0x02,
+	QUERY_CAPABILITY_RSP = 0x82,
+	REQUEST_CAPABILITY = 0x03,
+	REQUEST_CAPABILITY_RSP = 0x83,
+	LOGIN = 0x04,
+	LOGIN_RSP = 0x84,
+	QUERY_PHYS_PARMS = 0x05,
+	QUERY_PHYS_PARMS_RSP = 0x85,
+	QUERY_PHYS_CAPABILITIES = 0x06,
+	QUERY_PHYS_CAPABILITIES_RSP = 0x86,
+	SET_PHYS_PARMS = 0x07,
+	SET_PHYS_PARMS_RSP = 0x87,
+	ERROR_INDICATION = 0x08,
+	REQUEST_ERROR_INFO = 0x09,
+	REQUEST_ERROR_RSP = 0x89,
+	REQUEST_DUMP_SIZE = 0x0A,
+	REQUEST_DUMP_SIZE_RSP = 0x8A,
+	REQUEST_DUMP = 0x0B,
+	REQUEST_DUMP_RSP = 0x8B,
+	LOGICAL_LINK_STATE = 0x0C,
+	LOGICAL_LINK_STATE_RSP = 0x8C,
+	REQUEST_STATISTICS = 0x0D,
+	REQUEST_STATISTICS_RSP = 0x8D,
+	REQUEST_RAS_COMP_NUM = 0x0E,
+	REQUEST_RAS_COMP_NUM_RSP = 0x8E,
+	REQUEST_RAS_COMPS = 0x0F,
+	REQUEST_RAS_COMPS_RSP = 0x8F,
+	CONTROL_RAS = 0x10,
+	CONTROL_RAS_RSP = 0x90,
+	COLLECT_FW_TRACE = 0x11,
+	COLLECT_FW_TRACE_RSP = 0x91,
+	LINK_STATE_INDICATION = 0x12,
+	CHANGE_MAC_ADDR = 0x13,
+	CHANGE_MAC_ADDR_RSP = 0x93,
+	MULTICAST_CTRL = 0x14,
+	MULTICAST_CTRL_RSP = 0x94,
+	GET_VPD_SIZE = 0x15,
+	GET_VPD_SIZE_RSP = 0x95,
+	GET_VPD = 0x16,
+	GET_VPD_RSP = 0x96,
+	TUNE = 0x17,
+	TUNE_RSP = 0x97,
+	QUERY_IP_OFFLOAD = 0x18,
+	QUERY_IP_OFFLOAD_RSP = 0x98,
+	CONTROL_IP_OFFLOAD = 0x19,
+	CONTROL_IP_OFFLOAD_RSP = 0x99,
+	ACL_CHANGE_INDICATION = 0x1A,
+	ACL_QUERY = 0x1B,
+	ACL_QUERY_RSP = 0x9B,
+	REQUEST_DEBUG_STATS = 0x1C,
+	REQUEST_DEBUG_STATS_RSP = 0x9C,
+	QUERY_MAP = 0x1D,
+	QUERY_MAP_RSP = 0x9D,
+	REQUEST_MAP = 0x1E,
+	REQUEST_MAP_RSP = 0x9E,
+	REQUEST_UNMAP = 0x1F,
+	REQUEST_UNMAP_RSP = 0x9F,
+	VLAN_CTRL = 0x20,
+	VLAN_CTRL_RSP = 0xA0,
+};
+
+enum ibmvnic_crq_type {
+	IBMVNIC_CRQ_CMD			= 0x80,
+	IBMVNIC_CRQ_CMD_RSP		= 0x80,
+	IBMVNIC_CRQ_INIT_CMD		= 0xC0,
+	IBMVNIC_CRQ_INIT_RSP		= 0xC0,
+	IBMVNIC_CRQ_XPORT_EVENT		= 0xFF,
+};
+
+enum ibmvfc_crq_format {
+	IBMVNIC_CRQ_INIT                 = 0x01,
+	IBMVNIC_CRQ_INIT_COMPLETE        = 0x02,
+	IBMVNIC_PARTITION_MIGRATED       = 0x06,
+};
+
+struct ibmvnic_crq_queue {
+	union ibmvnic_crq *msgs;
+	int size, cur;
+	dma_addr_t msg_token;
+	spinlock_t lock;
+};
+
+union sub_crq {
+	struct ibmvnic_generic_scrq generic;
+	struct ibmvnic_tx_comp_desc tx_comp;
+	struct ibmvnic_tx_desc v1;
+	struct ibmvnic_hdr_desc hdr;
+	struct ibmvnic_hdr_ext_desc hdr_ext;
+	struct ibmvnic_sge_desc sge;
+	struct ibmvnic_rx_comp_desc rx_comp;
+	struct ibmvnic_rx_buff_add_desc rx_add;
+};
+
+struct ibmvnic_sub_crq_queue {
+	union sub_crq *msgs;
+	int size, cur;
+	dma_addr_t msg_token;
+	unsigned long crq_num;
+	unsigned long hw_irq;
+	unsigned int irq;
+	unsigned int pool_index;
+	int scrq_num;
+	spinlock_t lock;
+	struct sk_buff *rx_skb_top;
+	struct ibmvnic_adapter *adapter;
+};
+
+struct ibmvnic_long_term_buff {
+	unsigned char *buff;
+	dma_addr_t addr;
+	u64 size;
+	u8 map_id;
+};
+
+struct ibmvnic_tx_buff {
+	struct sk_buff *skb;
+	dma_addr_t data_dma[IBMVNIC_MAX_FRAGS_PER_CRQ];
+	unsigned int data_len[IBMVNIC_MAX_FRAGS_PER_CRQ];
+	int index;
+	int pool_index;
+	bool last_frag;
+	bool used_bounce;
+};
+
+struct ibmvnic_tx_pool {
+	struct ibmvnic_tx_buff *tx_buff;
+	int *free_map;
+	int consumer_index;
+	int producer_index;
+	wait_queue_head_t ibmvnic_tx_comp_q;
+	struct task_struct *work_thread;
+	struct ibmvnic_long_term_buff long_term_buff;
+};
+
+struct ibmvnic_rx_buff {
+	struct sk_buff *skb;
+	dma_addr_t dma;
+	unsigned char *data;
+	int size;
+	int pool_index;
+};
+
+struct ibmvnic_rx_pool {
+	struct ibmvnic_rx_buff *rx_buff;
+	int size;
+	int index;
+	int buff_size;
+	atomic_t available;
+	int *free_map;
+	int next_free;
+	int next_alloc;
+	int active;
+	struct ibmvnic_long_term_buff long_term_buff;
+};
+
+struct ibmvnic_error_buff {
+	char *buff;
+	dma_addr_t dma;
+	int len;
+	struct list_head list;
+	__be32 error_id;
+};
+
+struct ibmvnic_fw_comp_internal {
+	struct ibmvnic_adapter *adapter;
+	int num;
+	struct debugfs_blob_wrapper desc_blob;
+	int paused;
+};
+
+struct ibmvnic_inflight_cmd {
+	union ibmvnic_crq crq;
+	struct list_head list;
+};
+
+struct ibmvnic_adapter {
+	struct vio_dev *vdev;
+	struct net_device *netdev;
+	struct ibmvnic_crq_queue crq;
+	u8 mac_addr[ETH_ALEN];
+	struct ibmvnic_query_ip_offload_buffer ip_offload_buf;
+	dma_addr_t ip_offload_tok;
+	struct ibmvnic_control_ip_offload_buffer ip_offload_ctrl;
+	dma_addr_t ip_offload_ctrl_tok;
+	bool migrated;
+	u32 msg_enable;
+	void *bounce_buffer;
+	int bounce_buffer_size;
+	dma_addr_t bounce_buffer_dma;
+
+	/* Statistics */
+	struct net_device_stats net_stats;
+	struct ibmvnic_statistics stats;
+	dma_addr_t stats_token;
+	struct completion stats_done;
+	spinlock_t stats_lock;
+	int replenish_no_mem;
+	int replenish_add_buff_success;
+	int replenish_add_buff_failure;
+	int replenish_task_cycles;
+	int tx_send_failed;
+	int tx_map_failed;
+
+	int phys_link_state;
+	int logical_link_state;
+
+	/* login data */
+	struct ibmvnic_login_buffer *login_buf;
+	dma_addr_t login_buf_token;
+	int login_buf_sz;
+
+	struct ibmvnic_login_rsp_buffer *login_rsp_buf;
+	dma_addr_t login_rsp_buf_token;
+	int login_rsp_buf_sz;
+
+	atomic_t running_cap_queries;
+
+	struct ibmvnic_sub_crq_queue **tx_scrq;
+	struct ibmvnic_sub_crq_queue **rx_scrq;
+	int requested_caps;
+
+	/* rx structs */
+	struct napi_struct *napi;
+	struct ibmvnic_rx_pool *rx_pool;
+	u64 promisc;
+
+	struct ibmvnic_tx_pool *tx_pool;
+	bool closing;
+	struct completion init_done;
+
+	struct list_head errors;
+	spinlock_t error_list_lock;
+
+	/* debugfs */
+	struct dentry *debugfs_dir;
+	struct dentry *debugfs_dump;
+	struct completion fw_done;
+	char *dump_data;
+	dma_addr_t dump_data_token;
+	int dump_data_size;
+	int ras_comp_num;
+	struct ibmvnic_fw_component *ras_comps;
+	struct ibmvnic_fw_comp_internal *ras_comp_int;
+	dma_addr_t ras_comps_tok;
+	struct dentry *ras_comps_ent;
+
+	/* in-flight commands that allocate and/or map memory*/
+	struct list_head inflight;
+	spinlock_t inflight_lock;
+
+	/* partner capabilities */
+	u64 min_tx_queues;
+	u64 min_rx_queues;
+	u64 min_rx_add_queues;
+	u64 max_tx_queues;
+	u64 max_rx_queues;
+	u64 max_rx_add_queues;
+	u64 req_tx_queues;
+	u64 req_rx_queues;
+	u64 req_rx_add_queues;
+	u64 min_tx_entries_per_subcrq;
+	u64 min_rx_add_entries_per_subcrq;
+	u64 max_tx_entries_per_subcrq;
+	u64 max_rx_add_entries_per_subcrq;
+	u64 req_tx_entries_per_subcrq;
+	u64 req_rx_add_entries_per_subcrq;
+	u64 tcp_ip_offload;
+	u64 promisc_requested;
+	u64 promisc_supported;
+	u64 min_mtu;
+	u64 max_mtu;
+	u64 req_mtu;
+	u64 max_multicast_filters;
+	u64 vlan_header_insertion;
+	u64 max_tx_sg_entries;
+	u64 rx_sg_supported;
+	u64 rx_sg_requested;
+	u64 opt_tx_comp_sub_queues;
+	u64 opt_rx_comp_queues;
+	u64 opt_rx_bufadd_q_per_rx_comp_q;
+	u64 opt_tx_entries_per_subcrq;
+	u64 opt_rxba_entries_per_subcrq;
+	__be64 tx_rx_desc_req;
+	u8 map_id;
+};
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/intel/Kconfig
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/intel/Kconfig
@@ -83,6 +83,15 @@ config E1000E
 	  To compile this driver as a module, choose M here. The module
 	  will be called e1000e.
 
+config E1000E_HWTS
+	bool "Support HW cross-timestamp on PCH devices"
+	default y
+	depends on E1000E && X86
+	---help---
+	 Say Y to enable hardware supported cross-timestamping on PCH
+	 devices. The cross-timestamp is available through the PTP clock
+	 driver precise cross-timestamp ioctl (PTP_SYS_OFFSET_PRECISE).
+
 config IGB
 	tristate "Intel(R) 82575/82576 PCI-Express Gigabit Ethernet support"
 	depends on PCI
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/intel/e1000/e1000.h
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/intel/e1000/e1000.h
@@ -213,8 +213,11 @@ struct e1000_rx_ring {
 };
 
 #define E1000_DESC_UNUSED(R)						\
-	((((R)->next_to_clean > (R)->next_to_use)			\
-	  ? 0 : (R)->count) + (R)->next_to_clean - (R)->next_to_use - 1)
+({									\
+	unsigned int clean = smp_load_acquire(&(R)->next_to_clean);	\
+	unsigned int use = READ_ONCE((R)->next_to_use);			\
+	(clean > use ? 0 : (R)->count) + clean - use - 1;		\
+})
 
 #define E1000_RX_DESC_EXT(R, i)						\
 	(&(((union e1000_rx_desc_extended *)((R).desc))[i]))
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/intel/e1000/e1000_hw.c
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/intel/e1000/e1000_hw.c
@@ -1,5 +1,5 @@
 /*******************************************************************************
-
+*
   Intel PRO/1000 Linux driver
   Copyright(c) 1999 - 2006 Intel Corporation.
 
@@ -106,7 +106,7 @@ u16 e1000_igp_cable_length_table[IGP01E1
 	    120, 120
 };
 
-static DEFINE_SPINLOCK(e1000_eeprom_lock);
+static DEFINE_MUTEX(e1000_eeprom_lock);
 static DEFINE_SPINLOCK(e1000_phy_lock);
 
 /**
@@ -624,8 +624,8 @@ s32 e1000_init_hw(struct e1000_hw *hw)
 		/* Workaround for PCI-X problem when BIOS sets MMRBC
 		 * incorrectly.
 		 */
-		if (hw->bus_type == e1000_bus_type_pcix
-		    && e1000_pcix_get_mmrbc(hw) > 2048)
+		if (hw->bus_type == e1000_bus_type_pcix &&
+		    e1000_pcix_get_mmrbc(hw) > 2048)
 			e1000_pcix_set_mmrbc(hw, 2048);
 		break;
 	}
@@ -683,10 +683,9 @@ static s32 e1000_adjust_serdes_amplitude
 	}
 
 	ret_val = e1000_read_eeprom(hw, EEPROM_SERDES_AMPLITUDE, 1,
-	                            &eeprom_data);
-	if (ret_val) {
+				    &eeprom_data);
+	if (ret_val)
 		return ret_val;
-	}
 
 	if (eeprom_data != EEPROM_RESERVED_WORD) {
 		/* Adjust SERDES output amplitude only. */
@@ -1074,8 +1073,8 @@ static s32 e1000_copper_link_preconfig(s
 
 	if (hw->mac_type <= e1000_82543 ||
 	    hw->mac_type == e1000_82541 || hw->mac_type == e1000_82547 ||
-	    hw->mac_type == e1000_82541_rev_2
-	    || hw->mac_type == e1000_82547_rev_2)
+	    hw->mac_type == e1000_82541_rev_2 ||
+	    hw->mac_type == e1000_82547_rev_2)
 		hw->phy_reset_disable = false;
 
 	return E1000_SUCCESS;
@@ -1652,7 +1651,7 @@ s32 e1000_phy_setup_autoneg(struct e1000
 		mii_1000t_ctrl_reg = 0;
 	} else {
 		ret_val = e1000_write_phy_reg(hw, PHY_1000T_CTRL,
-		                              mii_1000t_ctrl_reg);
+					      mii_1000t_ctrl_reg);
 		if (ret_val)
 			return ret_val;
 	}
@@ -1881,10 +1880,11 @@ static s32 e1000_phy_force_speed_duplex(
 		if (ret_val)
 			return ret_val;
 
-		if ((hw->mac_type == e1000_82544 || hw->mac_type == e1000_82543)
-		    && (!hw->autoneg)
-		    && (hw->forced_speed_duplex == e1000_10_full
-			|| hw->forced_speed_duplex == e1000_10_half)) {
+		if ((hw->mac_type == e1000_82544 ||
+		     hw->mac_type == e1000_82543) &&
+		    (!hw->autoneg) &&
+		    (hw->forced_speed_duplex == e1000_10_full ||
+		     hw->forced_speed_duplex == e1000_10_half)) {
 			ret_val = e1000_polarity_reversal_workaround(hw);
 			if (ret_val)
 				return ret_val;
@@ -2084,11 +2084,12 @@ static s32 e1000_config_fc_after_link_up
 	 * so we had to force link.  In this case, we need to force the
 	 * configuration of the MAC to match the "fc" parameter.
 	 */
-	if (((hw->media_type == e1000_media_type_fiber) && (hw->autoneg_failed))
-	    || ((hw->media_type == e1000_media_type_internal_serdes)
-		&& (hw->autoneg_failed))
-	    || ((hw->media_type == e1000_media_type_copper)
-		&& (!hw->autoneg))) {
+	if (((hw->media_type == e1000_media_type_fiber) &&
+	     (hw->autoneg_failed)) ||
+	    ((hw->media_type == e1000_media_type_internal_serdes) &&
+	     (hw->autoneg_failed)) ||
+	    ((hw->media_type == e1000_media_type_copper) &&
+	     (!hw->autoneg))) {
 		ret_val = e1000_force_mac_fc(hw);
 		if (ret_val) {
 			e_dbg("Error forcing flow control settings\n");
@@ -2193,8 +2194,7 @@ static s32 e1000_config_fc_after_link_up
 			else if (!(mii_nway_adv_reg & NWAY_AR_PAUSE) &&
 				 (mii_nway_adv_reg & NWAY_AR_ASM_DIR) &&
 				 (mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE) &&
-				 (mii_nway_lp_ability_reg & NWAY_LPAR_ASM_DIR))
-			{
+				 (mii_nway_lp_ability_reg & NWAY_LPAR_ASM_DIR)) {
 				hw->fc = E1000_FC_TX_PAUSE;
 				e_dbg
 				    ("Flow Control = TX PAUSE frames only.\n");
@@ -2210,8 +2210,7 @@ static s32 e1000_config_fc_after_link_up
 			else if ((mii_nway_adv_reg & NWAY_AR_PAUSE) &&
 				 (mii_nway_adv_reg & NWAY_AR_ASM_DIR) &&
 				 !(mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE) &&
-				 (mii_nway_lp_ability_reg & NWAY_LPAR_ASM_DIR))
-			{
+				 (mii_nway_lp_ability_reg & NWAY_LPAR_ASM_DIR)) {
 				hw->fc = E1000_FC_RX_PAUSE;
 				e_dbg
 				    ("Flow Control = RX PAUSE frames only.\n");
@@ -2460,10 +2459,11 @@ s32 e1000_check_for_link(struct e1000_hw
 			 * happen due to the execution of this workaround.
 			 */
 
-			if ((hw->mac_type == e1000_82544
-			     || hw->mac_type == e1000_82543) && (!hw->autoneg)
-			    && (hw->forced_speed_duplex == e1000_10_full
-				|| hw->forced_speed_duplex == e1000_10_half)) {
+			if ((hw->mac_type == e1000_82544 ||
+			     hw->mac_type == e1000_82543) &&
+			    (!hw->autoneg) &&
+			    (hw->forced_speed_duplex == e1000_10_full ||
+			     hw->forced_speed_duplex == e1000_10_half)) {
 				ew32(IMC, 0xffffffff);
 				ret_val =
 				    e1000_polarity_reversal_workaround(hw);
@@ -2528,8 +2528,10 @@ s32 e1000_check_for_link(struct e1000_hw
 		 */
 		if (hw->tbi_compatibility_en) {
 			u16 speed, duplex;
+
 			ret_val =
 			    e1000_get_speed_and_duplex(hw, &speed, &duplex);
+
 			if (ret_val) {
 				e_dbg
 				    ("Error getting link speed and duplex\n");
@@ -2628,10 +2630,10 @@ s32 e1000_get_speed_and_duplex(struct e1
 			    e1000_read_phy_reg(hw, PHY_LP_ABILITY, &phy_data);
 			if (ret_val)
 				return ret_val;
-			if ((*speed == SPEED_100
-			     && !(phy_data & NWAY_LPAR_100TX_FD_CAPS))
-			    || (*speed == SPEED_10
-				&& !(phy_data & NWAY_LPAR_10T_FD_CAPS)))
+			if ((*speed == SPEED_100 &&
+			     !(phy_data & NWAY_LPAR_100TX_FD_CAPS)) ||
+			    (*speed == SPEED_10 &&
+			     !(phy_data & NWAY_LPAR_10T_FD_CAPS)))
 				*duplex = HALF_DUPLEX;
 		}
 	}
@@ -2664,9 +2666,9 @@ static s32 e1000_wait_autoneg(struct e10
 		ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data);
 		if (ret_val)
 			return ret_val;
-		if (phy_data & MII_SR_AUTONEG_COMPLETE) {
+		if (phy_data & MII_SR_AUTONEG_COMPLETE)
 			return E1000_SUCCESS;
-		}
+
 		msleep(100);
 	}
 	return E1000_SUCCESS;
@@ -2803,11 +2805,11 @@ static u16 e1000_shift_in_mdi_bits(struc
 	return data;
 }
 
-
 /**
  * e1000_read_phy_reg - read a phy register
  * @hw: Struct containing variables accessed by shared code
  * @reg_addr: address of the PHY register to read
+ * @phy_data: pointer to the value on the PHY register
  *
  * Reads the value from a PHY register, if the value is on a specific non zero
  * page, sets the page first.
@@ -2823,14 +2825,13 @@ s32 e1000_read_phy_reg(struct e1000_hw *
 	    (reg_addr > MAX_PHY_MULTI_PAGE_REG)) {
 		ret_val = e1000_write_phy_reg_ex(hw, IGP01E1000_PHY_PAGE_SELECT,
 						 (u16) reg_addr);
-		if (ret_val) {
-			spin_unlock_irqrestore(&e1000_phy_lock, flags);
-			return ret_val;
-		}
+		if (ret_val)
+			goto out;
 	}
 
 	ret_val = e1000_read_phy_reg_ex(hw, MAX_PHY_REG_ADDRESS & reg_addr,
 					phy_data);
+out:
 	spin_unlock_irqrestore(&e1000_phy_lock, flags);
 
 	return ret_val;
@@ -2881,7 +2882,7 @@ static s32 e1000_read_phy_reg_ex(struct
 				e_dbg("MDI Read Error\n");
 				return -E1000_ERR_PHY;
 			}
-			*phy_data = (u16) mdic;
+			*phy_data = (u16)mdic;
 		} else {
 			mdic = ((reg_addr << E1000_MDIC_REG_SHIFT) |
 				(phy_addr << E1000_MDIC_PHY_SHIFT) |
@@ -2906,7 +2907,7 @@ static s32 e1000_read_phy_reg_ex(struct
 				e_dbg("MDI Error\n");
 				return -E1000_ERR_PHY;
 			}
-			*phy_data = (u16) mdic;
+			*phy_data = (u16)mdic;
 		}
 	} else {
 		/* We must first send a preamble through the MDIO pin to signal
@@ -2960,7 +2961,7 @@ s32 e1000_write_phy_reg(struct e1000_hw
 	if ((hw->phy_type == e1000_phy_igp) &&
 	    (reg_addr > MAX_PHY_MULTI_PAGE_REG)) {
 		ret_val = e1000_write_phy_reg_ex(hw, IGP01E1000_PHY_PAGE_SELECT,
-						 (u16) reg_addr);
+						 (u16)reg_addr);
 		if (ret_val) {
 			spin_unlock_irqrestore(&e1000_phy_lock, flags);
 			return ret_val;
@@ -2993,7 +2994,7 @@ static s32 e1000_write_phy_reg_ex(struct
 		 * the desired data.
 		 */
 		if (hw->mac_type == e1000_ce4100) {
-			mdic = (((u32) phy_data) |
+			mdic = (((u32)phy_data) |
 				(reg_addr << E1000_MDIC_REG_SHIFT) |
 				(phy_addr << E1000_MDIC_PHY_SHIFT) |
 				(INTEL_CE_GBE_MDIC_OP_WRITE) |
@@ -3015,7 +3016,7 @@ static s32 e1000_write_phy_reg_ex(struct
 				return -E1000_ERR_PHY;
 			}
 		} else {
-			mdic = (((u32) phy_data) |
+			mdic = (((u32)phy_data) |
 				(reg_addr << E1000_MDIC_REG_SHIFT) |
 				(phy_addr << E1000_MDIC_PHY_SHIFT) |
 				(E1000_MDIC_OP_WRITE));
@@ -3053,7 +3054,7 @@ static s32 e1000_write_phy_reg_ex(struct
 		mdic = ((PHY_TURNAROUND) | (reg_addr << 2) | (phy_addr << 7) |
 			(PHY_OP_WRITE << 12) | (PHY_SOF << 14));
 		mdic <<= 16;
-		mdic |= (u32) phy_data;
+		mdic |= (u32)phy_data;
 
 		e1000_shift_out_mdi_bits(hw, mdic, 32);
 	}
@@ -3176,14 +3177,14 @@ static s32 e1000_detect_gig_phy(struct e
 	if (ret_val)
 		return ret_val;
 
-	hw->phy_id = (u32) (phy_id_high << 16);
+	hw->phy_id = (u32)(phy_id_high << 16);
 	udelay(20);
 	ret_val = e1000_read_phy_reg(hw, PHY_ID2, &phy_id_low);
 	if (ret_val)
 		return ret_val;
 
-	hw->phy_id |= (u32) (phy_id_low & PHY_REVISION_MASK);
-	hw->phy_revision = (u32) phy_id_low & ~PHY_REVISION_MASK;
+	hw->phy_id |= (u32)(phy_id_low & PHY_REVISION_MASK);
+	hw->phy_revision = (u32)phy_id_low & ~PHY_REVISION_MASK;
 
 	switch (hw->mac_type) {
 	case e1000_82543:
@@ -3401,7 +3402,6 @@ static s32 e1000_phy_m88_get_info(struct
 		phy_info->remote_rx = ((phy_data & SR_1000T_REMOTE_RX_STATUS) >>
 				       SR_1000T_REMOTE_RX_STATUS_SHIFT) ?
 		    e1000_1000t_rx_status_ok : e1000_1000t_rx_status_not_ok;
-
 	}
 
 	return E1000_SUCCESS;
@@ -3449,7 +3449,7 @@ s32 e1000_phy_get_info(struct e1000_hw *
 	if (hw->phy_type == e1000_phy_igp)
 		return e1000_phy_igp_get_info(hw, phy_info);
 	else if ((hw->phy_type == e1000_phy_8211) ||
-	         (hw->phy_type == e1000_phy_8201))
+		 (hw->phy_type == e1000_phy_8201))
 		return E1000_SUCCESS;
 	else
 		return e1000_phy_m88_get_info(hw, phy_info);
@@ -3611,11 +3611,11 @@ static void e1000_shift_out_ee_bits(stru
 	 */
 	mask = 0x01 << (count - 1);
 	eecd = er32(EECD);
-	if (eeprom->type == e1000_eeprom_microwire) {
+	if (eeprom->type == e1000_eeprom_microwire)
 		eecd &= ~E1000_EECD_DO;
-	} else if (eeprom->type == e1000_eeprom_spi) {
+	else if (eeprom->type == e1000_eeprom_spi)
 		eecd |= E1000_EECD_DO;
-	}
+
 	do {
 		/* A "1" is shifted out to the EEPROM by setting bit "DI" to a
 		 * "1", and then raising and then lowering the clock (the SK bit
@@ -3851,7 +3851,7 @@ static s32 e1000_spi_eeprom_ready(struct
 	do {
 		e1000_shift_out_ee_bits(hw, EEPROM_RDSR_OPCODE_SPI,
 					hw->eeprom.opcode_bits);
-		spi_stat_reg = (u8) e1000_shift_in_ee_bits(hw, 8);
+		spi_stat_reg = (u8)e1000_shift_in_ee_bits(hw, 8);
 		if (!(spi_stat_reg & EEPROM_STATUS_RDY_SPI))
 			break;
 
@@ -3882,9 +3882,10 @@ static s32 e1000_spi_eeprom_ready(struct
 s32 e1000_read_eeprom(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
 {
 	s32 ret;
-	spin_lock(&e1000_eeprom_lock);
+
+	mutex_lock(&e1000_eeprom_lock);
 	ret = e1000_do_read_eeprom(hw, offset, words, data);
-	spin_unlock(&e1000_eeprom_lock);
+	mutex_unlock(&e1000_eeprom_lock);
 	return ret;
 }
 
@@ -3896,15 +3897,16 @@ static s32 e1000_do_read_eeprom(struct e
 
 	if (hw->mac_type == e1000_ce4100) {
 		GBE_CONFIG_FLASH_READ(GBE_CONFIG_BASE_VIRT, offset, words,
-		                      data);
+				      data);
 		return E1000_SUCCESS;
 	}
 
 	/* A check for invalid values:  offset too large, too many words, and
 	 * not enough words.
 	 */
-	if ((offset >= eeprom->word_size)
-	    || (words > eeprom->word_size - offset) || (words == 0)) {
+	if ((offset >= eeprom->word_size) ||
+	    (words > eeprom->word_size - offset) ||
+	    (words == 0)) {
 		e_dbg("\"words\" parameter out of bounds. Words = %d,"
 		      "size = %d\n", offset, eeprom->word_size);
 		return -E1000_ERR_EEPROM;
@@ -3940,7 +3942,7 @@ static s32 e1000_do_read_eeprom(struct e
 
 		/* Send the READ command (opcode + addr)  */
 		e1000_shift_out_ee_bits(hw, read_opcode, eeprom->opcode_bits);
-		e1000_shift_out_ee_bits(hw, (u16) (offset * 2),
+		e1000_shift_out_ee_bits(hw, (u16)(offset * 2),
 					eeprom->address_bits);
 
 		/* Read the data.  The address of the eeprom internally
@@ -3960,7 +3962,7 @@ static s32 e1000_do_read_eeprom(struct e
 			e1000_shift_out_ee_bits(hw,
 						EEPROM_READ_OPCODE_MICROWIRE,
 						eeprom->opcode_bits);
-			e1000_shift_out_ee_bits(hw, (u16) (offset + i),
+			e1000_shift_out_ee_bits(hw, (u16)(offset + i),
 						eeprom->address_bits);
 
 			/* Read the data.  For microwire, each word requires the
@@ -3968,6 +3970,7 @@ static s32 e1000_do_read_eeprom(struct e
 			 */
 			data[i] = e1000_shift_in_ee_bits(hw, 16);
 			e1000_standby_eeprom(hw);
+			cond_resched();
 		}
 	}
 
@@ -4004,7 +4007,7 @@ s32 e1000_validate_eeprom_checksum(struc
 		return E1000_SUCCESS;
 
 #endif
-	if (checksum == (u16) EEPROM_SUM)
+	if (checksum == (u16)EEPROM_SUM)
 		return E1000_SUCCESS;
 	else {
 		e_dbg("EEPROM Checksum Invalid\n");
@@ -4031,7 +4034,7 @@ s32 e1000_update_eeprom_checksum(struct
 		}
 		checksum += eeprom_data;
 	}
-	checksum = (u16) EEPROM_SUM - checksum;
+	checksum = (u16)EEPROM_SUM - checksum;
 	if (e1000_write_eeprom(hw, EEPROM_CHECKSUM_REG, 1, &checksum) < 0) {
 		e_dbg("EEPROM Write Error\n");
 		return -E1000_ERR_EEPROM;
@@ -4052,9 +4055,10 @@ s32 e1000_update_eeprom_checksum(struct
 s32 e1000_write_eeprom(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
 {
 	s32 ret;
-	spin_lock(&e1000_eeprom_lock);
+
+	mutex_lock(&e1000_eeprom_lock);
 	ret = e1000_do_write_eeprom(hw, offset, words, data);
-	spin_unlock(&e1000_eeprom_lock);
+	mutex_unlock(&e1000_eeprom_lock);
 	return ret;
 }
 
@@ -4066,15 +4070,16 @@ static s32 e1000_do_write_eeprom(struct
 
 	if (hw->mac_type == e1000_ce4100) {
 		GBE_CONFIG_FLASH_WRITE(GBE_CONFIG_BASE_VIRT, offset, words,
-		                       data);
+				       data);
 		return E1000_SUCCESS;
 	}
 
 	/* A check for invalid values:  offset too large, too many words, and
 	 * not enough words.
 	 */
-	if ((offset >= eeprom->word_size)
-	    || (words > eeprom->word_size - offset) || (words == 0)) {
+	if ((offset >= eeprom->word_size) ||
+	    (words > eeprom->word_size - offset) ||
+	    (words == 0)) {
 		e_dbg("\"words\" parameter out of bounds\n");
 		return -E1000_ERR_EEPROM;
 	}
@@ -4116,6 +4121,7 @@ static s32 e1000_write_eeprom_spi(struct
 			return -E1000_ERR_EEPROM;
 
 		e1000_standby_eeprom(hw);
+		cond_resched();
 
 		/*  Send the WRITE ENABLE command (8 bit opcode )  */
 		e1000_shift_out_ee_bits(hw, EEPROM_WREN_OPCODE_SPI,
@@ -4132,7 +4138,7 @@ static s32 e1000_write_eeprom_spi(struct
 		/* Send the Write command (8-bit opcode + addr) */
 		e1000_shift_out_ee_bits(hw, write_opcode, eeprom->opcode_bits);
 
-		e1000_shift_out_ee_bits(hw, (u16) ((offset + widx) * 2),
+		e1000_shift_out_ee_bits(hw, (u16)((offset + widx) * 2),
 					eeprom->address_bits);
 
 		/* Send the data */
@@ -4142,6 +4148,7 @@ static s32 e1000_write_eeprom_spi(struct
 		 */
 		while (widx < words) {
 			u16 word_out = data[widx];
+
 			word_out = (word_out >> 8) | (word_out << 8);
 			e1000_shift_out_ee_bits(hw, word_out, 16);
 			widx++;
@@ -4183,9 +4190,9 @@ static s32 e1000_write_eeprom_microwire(
 	 * EEPROM into write/erase mode.
 	 */
 	e1000_shift_out_ee_bits(hw, EEPROM_EWEN_OPCODE_MICROWIRE,
-				(u16) (eeprom->opcode_bits + 2));
+				(u16)(eeprom->opcode_bits + 2));
 
-	e1000_shift_out_ee_bits(hw, 0, (u16) (eeprom->address_bits - 2));
+	e1000_shift_out_ee_bits(hw, 0, (u16)(eeprom->address_bits - 2));
 
 	/* Prepare the EEPROM */
 	e1000_standby_eeprom(hw);
@@ -4195,7 +4202,7 @@ static s32 e1000_write_eeprom_microwire(
 		e1000_shift_out_ee_bits(hw, EEPROM_WRITE_OPCODE_MICROWIRE,
 					eeprom->opcode_bits);
 
-		e1000_shift_out_ee_bits(hw, (u16) (offset + words_written),
+		e1000_shift_out_ee_bits(hw, (u16)(offset + words_written),
 					eeprom->address_bits);
 
 		/* Send the data */
@@ -4224,6 +4231,7 @@ static s32 e1000_write_eeprom_microwire(
 
 		/* Recover from write */
 		e1000_standby_eeprom(hw);
+		cond_resched();
 
 		words_written++;
 	}
@@ -4235,9 +4243,9 @@ static s32 e1000_write_eeprom_microwire(
 	 * EEPROM out of write/erase mode.
 	 */
 	e1000_shift_out_ee_bits(hw, EEPROM_EWDS_OPCODE_MICROWIRE,
-				(u16) (eeprom->opcode_bits + 2));
+				(u16)(eeprom->opcode_bits + 2));
 
-	e1000_shift_out_ee_bits(hw, 0, (u16) (eeprom->address_bits - 2));
+	e1000_shift_out_ee_bits(hw, 0, (u16)(eeprom->address_bits - 2));
 
 	return E1000_SUCCESS;
 }
@@ -4260,8 +4268,8 @@ s32 e1000_read_mac_addr(struct e1000_hw
 			e_dbg("EEPROM Read Error\n");
 			return -E1000_ERR_EEPROM;
 		}
-		hw->perm_mac_addr[i] = (u8) (eeprom_data & 0x00FF);
-		hw->perm_mac_addr[i + 1] = (u8) (eeprom_data >> 8);
+		hw->perm_mac_addr[i] = (u8)(eeprom_data & 0x00FF);
+		hw->perm_mac_addr[i + 1] = (u8)(eeprom_data >> 8);
 	}
 
 	switch (hw->mac_type) {
@@ -4328,19 +4336,19 @@ u32 e1000_hash_mc_addr(struct e1000_hw *
 		 */
 	case 0:
 		/* [47:36] i.e. 0x563 for above example address */
-		hash_value = ((mc_addr[4] >> 4) | (((u16) mc_addr[5]) << 4));
+		hash_value = ((mc_addr[4] >> 4) | (((u16)mc_addr[5]) << 4));
 		break;
 	case 1:
 		/* [46:35] i.e. 0xAC6 for above example address */
-		hash_value = ((mc_addr[4] >> 3) | (((u16) mc_addr[5]) << 5));
+		hash_value = ((mc_addr[4] >> 3) | (((u16)mc_addr[5]) << 5));
 		break;
 	case 2:
 		/* [45:34] i.e. 0x5D8 for above example address */
-		hash_value = ((mc_addr[4] >> 2) | (((u16) mc_addr[5]) << 6));
+		hash_value = ((mc_addr[4] >> 2) | (((u16)mc_addr[5]) << 6));
 		break;
 	case 3:
 		/* [43:32] i.e. 0x634 for above example address */
-		hash_value = ((mc_addr[4]) | (((u16) mc_addr[5]) << 8));
+		hash_value = ((mc_addr[4]) | (((u16)mc_addr[5]) << 8));
 		break;
 	}
 
@@ -4361,9 +4369,9 @@ void e1000_rar_set(struct e1000_hw *hw,
 	/* HW expects these in little endian so we reverse the byte order
 	 * from network order (big endian) to little endian
 	 */
-	rar_low = ((u32) addr[0] | ((u32) addr[1] << 8) |
-		   ((u32) addr[2] << 16) | ((u32) addr[3] << 24));
-	rar_high = ((u32) addr[4] | ((u32) addr[5] << 8));
+	rar_low = ((u32)addr[0] | ((u32)addr[1] << 8) |
+		   ((u32)addr[2] << 16) | ((u32)addr[3] << 24));
+	rar_high = ((u32)addr[4] | ((u32)addr[5] << 8));
 
 	/* Disable Rx and flush all Rx frames before enabling RSS to avoid Rx
 	 * unit hang.
@@ -4537,7 +4545,7 @@ s32 e1000_setup_led(struct e1000_hw *hw)
 		if (ret_val)
 			return ret_val;
 		ret_val = e1000_write_phy_reg(hw, IGP01E1000_GMII_FIFO,
-					      (u16) (hw->phy_spd_default &
+					      (u16)(hw->phy_spd_default &
 						     ~IGP01E1000_GMII_SPD));
 		if (ret_val)
 			return ret_val;
@@ -4802,7 +4810,7 @@ void e1000_reset_adaptive(struct e1000_h
 void e1000_update_adaptive(struct e1000_hw *hw)
 {
 	if (hw->adaptive_ifs) {
-		if ((hw->collision_delta *hw->ifs_ratio) > hw->tx_packet_delta) {
+		if ((hw->collision_delta * hw->ifs_ratio) > hw->tx_packet_delta) {
 			if (hw->tx_packet_delta > MIN_NUM_XMITS) {
 				hw->in_ifs_mode = true;
 				if (hw->current_ifs_val < hw->ifs_max_val) {
@@ -4816,8 +4824,8 @@ void e1000_update_adaptive(struct e1000_
 				}
 			}
 		} else {
-			if (hw->in_ifs_mode
-			    && (hw->tx_packet_delta <= MIN_NUM_XMITS)) {
+			if (hw->in_ifs_mode &&
+			    (hw->tx_packet_delta <= MIN_NUM_XMITS)) {
 				hw->current_ifs_val = 0;
 				hw->in_ifs_mode = false;
 				ew32(AIT, 0);
@@ -4922,7 +4930,6 @@ static s32 e1000_get_cable_length(struct
 
 	/* Use old method for Phy older than IGP */
 	if (hw->phy_type == e1000_phy_m88) {
-
 		ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS,
 					     &phy_data);
 		if (ret_val)
@@ -4966,7 +4973,6 @@ static s32 e1000_get_cable_length(struct
 		};
 		/* Read the AGC registers for all channels */
 		for (i = 0; i < IGP01E1000_PHY_CHANNEL_NUM; i++) {
-
 			ret_val =
 			    e1000_read_phy_reg(hw, agc_reg_array[i], &phy_data);
 			if (ret_val)
@@ -4976,8 +4982,8 @@ static s32 e1000_get_cable_length(struct
 
 			/* Value bound check. */
 			if ((cur_agc_value >=
-			     IGP01E1000_AGC_LENGTH_TABLE_SIZE - 1)
-			    || (cur_agc_value == 0))
+			     IGP01E1000_AGC_LENGTH_TABLE_SIZE - 1) ||
+			    (cur_agc_value == 0))
 				return -E1000_ERR_PHY;
 
 			agc_value += cur_agc_value;
@@ -5054,7 +5060,6 @@ static s32 e1000_check_polarity(struct e
 		 */
 		if ((phy_data & IGP01E1000_PSSR_SPEED_MASK) ==
 		    IGP01E1000_PSSR_SPEED_1000MBPS) {
-
 			/* Read the GIG initialization PCS register (0x00B4) */
 			ret_val =
 			    e1000_read_phy_reg(hw, IGP01E1000_PHY_PCS_INIT_REG,
@@ -5175,8 +5180,8 @@ static s32 e1000_1000Mb_check_cable_leng
 				hw->ffe_config_state = e1000_ffe_config_active;
 
 				ret_val = e1000_write_phy_reg(hw,
-					      IGP01E1000_PHY_DSP_FFE,
-					      IGP01E1000_PHY_DSP_FFE_CM_CP);
+							      IGP01E1000_PHY_DSP_FFE,
+							      IGP01E1000_PHY_DSP_FFE_CM_CP);
 				if (ret_val)
 					return ret_val;
 				break;
@@ -5243,7 +5248,7 @@ static s32 e1000_config_dsp_after_link_c
 			msleep(20);
 
 			ret_val = e1000_write_phy_reg(hw, 0x0000,
-						    IGP01E1000_IEEE_FORCE_GIGA);
+						      IGP01E1000_IEEE_FORCE_GIGA);
 			if (ret_val)
 				return ret_val;
 			for (i = 0; i < IGP01E1000_PHY_CHANNEL_NUM; i++) {
@@ -5264,7 +5269,7 @@ static s32 e1000_config_dsp_after_link_c
 			}
 
 			ret_val = e1000_write_phy_reg(hw, 0x0000,
-					IGP01E1000_IEEE_RESTART_AUTONEG);
+						      IGP01E1000_IEEE_RESTART_AUTONEG);
 			if (ret_val)
 				return ret_val;
 
@@ -5299,7 +5304,7 @@ static s32 e1000_config_dsp_after_link_c
 			msleep(20);
 
 			ret_val = e1000_write_phy_reg(hw, 0x0000,
-						    IGP01E1000_IEEE_FORCE_GIGA);
+						      IGP01E1000_IEEE_FORCE_GIGA);
 			if (ret_val)
 				return ret_val;
 			ret_val =
@@ -5309,7 +5314,7 @@ static s32 e1000_config_dsp_after_link_c
 				return ret_val;
 
 			ret_val = e1000_write_phy_reg(hw, 0x0000,
-					IGP01E1000_IEEE_RESTART_AUTONEG);
+						      IGP01E1000_IEEE_RESTART_AUTONEG);
 			if (ret_val)
 				return ret_val;
 
@@ -5346,9 +5351,8 @@ static s32 e1000_set_phy_mode(struct e10
 		ret_val =
 		    e1000_read_eeprom(hw, EEPROM_PHY_CLASS_WORD, 1,
 				      &eeprom_data);
-		if (ret_val) {
+		if (ret_val)
 			return ret_val;
-		}
 
 		if ((eeprom_data != EEPROM_RESERVED_WORD) &&
 		    (eeprom_data & EEPROM_PHY_CLASS_A)) {
@@ -5395,8 +5399,8 @@ static s32 e1000_set_d3_lplu_state(struc
 	 * from the lowest speeds starting from 10Mbps. The capability is used
 	 * for Dx transitions and states
 	 */
-	if (hw->mac_type == e1000_82541_rev_2
-	    || hw->mac_type == e1000_82547_rev_2) {
+	if (hw->mac_type == e1000_82541_rev_2 ||
+	    hw->mac_type == e1000_82547_rev_2) {
 		ret_val =
 		    e1000_read_phy_reg(hw, IGP01E1000_GMII_FIFO, &phy_data);
 		if (ret_val)
@@ -5446,11 +5450,9 @@ static s32 e1000_set_d3_lplu_state(struc
 			if (ret_val)
 				return ret_val;
 		}
-	} else if ((hw->autoneg_advertised == AUTONEG_ADVERTISE_SPEED_DEFAULT)
-		   || (hw->autoneg_advertised == AUTONEG_ADVERTISE_10_ALL)
-		   || (hw->autoneg_advertised ==
-		       AUTONEG_ADVERTISE_10_100_ALL)) {
-
+	} else if ((hw->autoneg_advertised == AUTONEG_ADVERTISE_SPEED_DEFAULT) ||
+		   (hw->autoneg_advertised == AUTONEG_ADVERTISE_10_ALL) ||
+		   (hw->autoneg_advertised == AUTONEG_ADVERTISE_10_100_ALL)) {
 		if (hw->mac_type == e1000_82541_rev_2 ||
 		    hw->mac_type == e1000_82547_rev_2) {
 			phy_data |= IGP01E1000_GMII_FLEX_SPD;
@@ -5474,7 +5476,6 @@ static s32 e1000_set_d3_lplu_state(struc
 					phy_data);
 		if (ret_val)
 			return ret_val;
-
 	}
 	return E1000_SUCCESS;
 }
@@ -5542,7 +5543,6 @@ static s32 e1000_set_vco_speed(struct e1
 	return E1000_SUCCESS;
 }
 
-
 /**
  * e1000_enable_mng_pass_thru - check for bmc pass through
  * @hw: Struct containing variables accessed by shared code
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/intel/e1000/e1000_main.c
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/intel/e1000/e1000_main.c
@@ -99,13 +99,13 @@ int e1000_setup_all_rx_resources(struct
 void e1000_free_all_tx_resources(struct e1000_adapter *adapter);
 void e1000_free_all_rx_resources(struct e1000_adapter *adapter);
 static int e1000_setup_tx_resources(struct e1000_adapter *adapter,
-                             struct e1000_tx_ring *txdr);
+				    struct e1000_tx_ring *txdr);
 static int e1000_setup_rx_resources(struct e1000_adapter *adapter,
-                             struct e1000_rx_ring *rxdr);
+				    struct e1000_rx_ring *rxdr);
 static void e1000_free_tx_resources(struct e1000_adapter *adapter,
-                             struct e1000_tx_ring *tx_ring);
+				    struct e1000_tx_ring *tx_ring);
 static void e1000_free_rx_resources(struct e1000_adapter *adapter,
-                             struct e1000_rx_ring *rx_ring);
+				    struct e1000_rx_ring *rx_ring);
 void e1000_update_stats(struct e1000_adapter *adapter);
 
 static int e1000_init_module(void);
@@ -122,16 +122,16 @@ static void e1000_setup_rctl(struct e100
 static void e1000_clean_all_tx_rings(struct e1000_adapter *adapter);
 static void e1000_clean_all_rx_rings(struct e1000_adapter *adapter);
 static void e1000_clean_tx_ring(struct e1000_adapter *adapter,
-                                struct e1000_tx_ring *tx_ring);
+				struct e1000_tx_ring *tx_ring);
 static void e1000_clean_rx_ring(struct e1000_adapter *adapter,
-                                struct e1000_rx_ring *rx_ring);
+				struct e1000_rx_ring *rx_ring);
 static void e1000_set_rx_mode(struct net_device *netdev);
 static void e1000_update_phy_info_task(struct work_struct *work);
 static void e1000_watchdog(struct work_struct *work);
 static void e1000_82547_tx_fifo_stall_task(struct work_struct *work);
 static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb,
 				    struct net_device *netdev);
-static struct net_device_stats * e1000_get_stats(struct net_device *netdev);
+static struct net_device_stats *e1000_get_stats(struct net_device *netdev);
 static int e1000_change_mtu(struct net_device *netdev, int new_mtu);
 static int e1000_set_mac(struct net_device *netdev, void *p);
 static irqreturn_t e1000_intr(int irq, void *data);
@@ -164,7 +164,7 @@ static void e1000_tx_timeout(struct net_
 static void e1000_reset_task(struct work_struct *work);
 static void e1000_smartspeed(struct e1000_adapter *adapter);
 static int e1000_82547_fifo_workaround(struct e1000_adapter *adapter,
-                                       struct sk_buff *skb);
+				       struct sk_buff *skb);
 
 static bool e1000_vlan_used(struct e1000_adapter *adapter);
 static void e1000_vlan_mode(struct net_device *netdev,
@@ -195,7 +195,7 @@ MODULE_PARM_DESC(copybreak,
 	"Maximum size of packet that is copied to a new buffer on receive");
 
 static pci_ers_result_t e1000_io_error_detected(struct pci_dev *pdev,
-                     pci_channel_state_t state);
+						pci_channel_state_t state);
 static pci_ers_result_t e1000_io_slot_reset(struct pci_dev *pdev);
 static void e1000_io_resume(struct pci_dev *pdev);
 
@@ -287,7 +287,7 @@ static int e1000_request_irq(struct e100
 	int err;
 
 	err = request_irq(adapter->pdev->irq, handler, irq_flags, netdev->name,
-	                  netdev);
+			  netdev);
 	if (err) {
 		e_err(probe, "Unable to allocate interrupt Error: %d\n", err);
 	}
@@ -636,8 +636,8 @@ void e1000_reset(struct e1000_adapter *a
 		 * but don't include ethernet FCS because hardware appends it
 		 */
 		min_tx_space = (hw->max_frame_size +
-		                sizeof(struct e1000_tx_desc) -
-		                ETH_FCS_LEN) * 2;
+				sizeof(struct e1000_tx_desc) -
+				ETH_FCS_LEN) * 2;
 		min_tx_space = ALIGN(min_tx_space, 1024);
 		min_tx_space >>= 10;
 		/* software strips receive CRC, so leave room for it */
@@ -943,8 +943,8 @@ static int e1000_probe(struct pci_dev *p
 	struct e1000_adapter *adapter;
 	struct e1000_hw *hw;
 
-	static int cards_found = 0;
-	static int global_quad_port_a = 0; /* global ksp3 port a indication */
+	static int cards_found;
+	static int global_quad_port_a; /* global ksp3 port a indication */
 	int i, err, pci_using_dac;
 	u16 eeprom_data = 0;
 	u16 tmp = 0;
@@ -1046,7 +1046,7 @@ static int e1000_probe(struct pci_dev *p
 	if (hw->mac_type == e1000_ce4100) {
 		hw->ce4100_gbe_mdio_base_virt =
 					ioremap(pci_resource_start(pdev, BAR_1),
-		                                pci_resource_len(pdev, BAR_1));
+						pci_resource_len(pdev, BAR_1));
 
 		if (!hw->ce4100_gbe_mdio_base_virt)
 			goto err_mdio_ioremap;
@@ -1148,7 +1148,7 @@ static int e1000_probe(struct pci_dev *p
 		break;
 	case e1000_82546:
 	case e1000_82546_rev_3:
-		if (er32(STATUS) & E1000_STATUS_FUNC_1){
+		if (er32(STATUS) & E1000_STATUS_FUNC_1) {
 			e1000_read_eeprom(hw,
 				EEPROM_INIT_CONTROL3_PORT_B, 1, &eeprom_data);
 			break;
@@ -1199,13 +1199,13 @@ static int e1000_probe(struct pci_dev *p
 		for (i = 0; i < 32; i++) {
 			hw->phy_addr = i;
 			e1000_read_phy_reg(hw, PHY_ID2, &tmp);
-			if (tmp == 0 || tmp == 0xFF) {
-				if (i == 31)
-					goto err_eeprom;
-				continue;
-			} else
+
+			if (tmp != 0 && tmp != 0xFF)
 				break;
 		}
+
+		if (i >= 32)
+			goto err_eeprom;
 	}
 
 	/* reset the hardware with the new settings */
@@ -1263,7 +1263,7 @@ err_pci_reg:
  * @pdev: PCI device information struct
  *
  * e1000_remove is called by the PCI subsystem to alert the driver
- * that it should release a PCI device.  The could be caused by a
+ * that it should release a PCI device. That could be caused by a
  * Hot-Plug event, or because the driver is going to be removed from
  * memory.
  **/
@@ -1334,12 +1334,12 @@ static int e1000_sw_init(struct e1000_ad
 static int e1000_alloc_queues(struct e1000_adapter *adapter)
 {
 	adapter->tx_ring = kcalloc(adapter->num_tx_queues,
-	                           sizeof(struct e1000_tx_ring), GFP_KERNEL);
+				   sizeof(struct e1000_tx_ring), GFP_KERNEL);
 	if (!adapter->tx_ring)
 		return -ENOMEM;
 
 	adapter->rx_ring = kcalloc(adapter->num_rx_queues,
-	                           sizeof(struct e1000_rx_ring), GFP_KERNEL);
+				   sizeof(struct e1000_rx_ring), GFP_KERNEL);
 	if (!adapter->rx_ring) {
 		kfree(adapter->tx_ring);
 		return -ENOMEM;
@@ -1811,20 +1811,20 @@ static void e1000_setup_rctl(struct e100
 	rctl &= ~E1000_RCTL_SZ_4096;
 	rctl |= E1000_RCTL_BSEX;
 	switch (adapter->rx_buffer_len) {
-		case E1000_RXBUFFER_2048:
-		default:
-			rctl |= E1000_RCTL_SZ_2048;
-			rctl &= ~E1000_RCTL_BSEX;
-			break;
-		case E1000_RXBUFFER_4096:
-			rctl |= E1000_RCTL_SZ_4096;
-			break;
-		case E1000_RXBUFFER_8192:
-			rctl |= E1000_RCTL_SZ_8192;
-			break;
-		case E1000_RXBUFFER_16384:
-			rctl |= E1000_RCTL_SZ_16384;
-			break;
+	case E1000_RXBUFFER_2048:
+	default:
+		rctl |= E1000_RCTL_SZ_2048;
+		rctl &= ~E1000_RCTL_BSEX;
+		break;
+	case E1000_RXBUFFER_4096:
+		rctl |= E1000_RCTL_SZ_4096;
+		break;
+	case E1000_RXBUFFER_8192:
+		rctl |= E1000_RCTL_SZ_8192;
+		break;
+	case E1000_RXBUFFER_16384:
+		rctl |= E1000_RCTL_SZ_16384;
+		break;
 	}
 
 	/* This is useful for sniffing bad packets. */
@@ -1861,12 +1861,12 @@ static void e1000_configure_rx(struct e1
 
 	if (adapter->netdev->mtu > ETH_DATA_LEN) {
 		rdlen = adapter->rx_ring[0].count *
-		        sizeof(struct e1000_rx_desc);
+			sizeof(struct e1000_rx_desc);
 		adapter->clean_rx = e1000_clean_jumbo_rx_irq;
 		adapter->alloc_rx_buf = e1000_alloc_jumbo_rx_buffers;
 	} else {
 		rdlen = adapter->rx_ring[0].count *
-		        sizeof(struct e1000_rx_desc);
+			sizeof(struct e1000_rx_desc);
 		adapter->clean_rx = e1000_clean_rx_irq;
 		adapter->alloc_rx_buf = e1000_alloc_rx_buffers;
 	}
@@ -2761,7 +2761,9 @@ static int e1000_tso(struct e1000_adapte
 		buffer_info->time_stamp = jiffies;
 		buffer_info->next_to_watch = i;
 
-		if (++i == tx_ring->count) i = 0;
+		if (++i == tx_ring->count)
+			i = 0;
+
 		tx_ring->next_to_use = i;
 
 		return true;
@@ -2816,7 +2818,9 @@ static bool e1000_tx_csum(struct e1000_a
 	buffer_info->time_stamp = jiffies;
 	buffer_info->next_to_watch = i;
 
-	if (unlikely(++i == tx_ring->count)) i = 0;
+	if (unlikely(++i == tx_ring->count))
+		i = 0;
+
 	tx_ring->next_to_use = i;
 
 	return true;
@@ -2865,8 +2869,8 @@ static int e1000_tx_map(struct e1000_ada
 		 * packet is smaller than 2048 - 16 - 16 (or 2016) bytes
 		 */
 		if (unlikely((hw->bus_type == e1000_bus_type_pcix) &&
-		                (size > 2015) && count == 0))
-		        size = 2015;
+			     (size > 2015) && count == 0))
+			size = 2015;
 
 		/* Workaround for potential 82544 hang in PCI-X.  Avoid
 		 * terminating buffers within evenly-aligned dwords.
@@ -2963,7 +2967,7 @@ dma_error:
 		count--;
 
 	while (count--) {
-		if (i==0)
+		if (i == 0)
 			i += tx_ring->count;
 		i--;
 		buffer_info = &tx_ring->buffer_info[i];
@@ -3013,7 +3017,8 @@ static void e1000_tx_queue(struct e1000_
 		tx_desc->lower.data =
 			cpu_to_le32(txd_lower | buffer_info->length);
 		tx_desc->upper.data = cpu_to_le32(txd_upper);
-		if (unlikely(++i == tx_ring->count)) i = 0;
+		if (unlikely(++i == tx_ring->count))
+			i = 0;
 	}
 
 	tx_desc->lower.data |= cpu_to_le32(adapter->txd_cmd);
@@ -3101,7 +3106,7 @@ static int e1000_maybe_stop_tx(struct ne
 	return __e1000_maybe_stop_tx(netdev, size);
 }
 
-#define TXD_USE_COUNT(S, X) (((S) >> (X)) + 1 )
+#define TXD_USE_COUNT(S, X) (((S) + ((1 << (X)) - 1)) >> (X))
 static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb,
 				    struct net_device *netdev)
 {
@@ -3251,12 +3256,29 @@ static netdev_tx_t e1000_xmit_frame(stru
 			     nr_frags, mss);
 
 	if (count) {
+		/* The descriptors needed is higher than other Intel drivers
+		 * due to a number of workarounds.  The breakdown is below:
+		 * Data descriptors: MAX_SKB_FRAGS + 1
+		 * Context Descriptor: 1
+		 * Keep head from touching tail: 2
+		 * Workarounds: 3
+		 */
+		int desc_needed = MAX_SKB_FRAGS + 7;
+
 		netdev_sent_queue(netdev, skb->len);
 		skb_tx_timestamp(skb);
 
 		e1000_tx_queue(adapter, tx_ring, tx_flags, count);
+
+		/* 82544 potentially requires twice as many data descriptors
+		 * in order to guarantee buffers don't end on evenly-aligned
+		 * dwords
+		 */
+		if (adapter->pcix_82544)
+			desc_needed += MAX_SKB_FRAGS + 1;
+
 		/* Make sure there is space in the ring for the next send. */
-		e1000_maybe_stop_tx(netdev, tx_ring, MAX_SKB_FRAGS + 2);
+		e1000_maybe_stop_tx(netdev, tx_ring, desc_needed);
 
 		if (!skb->xmit_more ||
 		    netif_xmit_stopped(netdev_get_tx_queue(netdev, 0))) {
@@ -3841,7 +3863,7 @@ static bool e1000_clean_tx_irq(struct e1
 	struct e1000_tx_buffer *buffer_info;
 	unsigned int i, eop;
 	unsigned int count = 0;
-	unsigned int total_tx_bytes=0, total_tx_packets=0;
+	unsigned int total_tx_bytes = 0, total_tx_packets = 0;
 	unsigned int bytes_compl = 0, pkts_compl = 0;
 
 	i = tx_ring->next_to_clean;
@@ -3869,14 +3891,18 @@ static bool e1000_clean_tx_irq(struct e1
 			e1000_unmap_and_free_tx_resource(adapter, buffer_info);
 			tx_desc->upper.data = 0;
 
-			if (unlikely(++i == tx_ring->count)) i = 0;
+			if (unlikely(++i == tx_ring->count))
+				i = 0;
 		}
 
 		eop = tx_ring->buffer_info[i].next_to_watch;
 		eop_desc = E1000_TX_DESC(*tx_ring, eop);
 	}
 
-	tx_ring->next_to_clean = i;
+	/* Synchronize with E1000_DESC_UNUSED called from e1000_xmit_frame,
+	 * which will reuse the cleaned buffers.
+	 */
+	smp_store_release(&tx_ring->next_to_clean, i);
 
 	netdev_completed_queue(netdev, pkts_compl, bytes_compl);
 
@@ -3954,9 +3980,11 @@ static void e1000_rx_checksum(struct e10
 	skb_checksum_none_assert(skb);
 
 	/* 82543 or newer only */
-	if (unlikely(hw->mac_type < e1000_82543)) return;
+	if (unlikely(hw->mac_type < e1000_82543))
+		return;
 	/* Ignore Checksum bit is set */
-	if (unlikely(status & E1000_RXD_STAT_IXSM)) return;
+	if (unlikely(status & E1000_RXD_STAT_IXSM))
+		return;
 	/* TCP/UDP checksum error bit is set */
 	if (unlikely(errors & E1000_RXD_ERR_TCPE)) {
 		/* let the stack verify checksum errors */
@@ -4136,7 +4164,7 @@ static bool e1000_clean_jumbo_rx_irq(str
 	unsigned int i;
 	int cleaned_count = 0;
 	bool cleaned = false;
-	unsigned int total_rx_bytes=0, total_rx_packets=0;
+	unsigned int total_rx_bytes = 0, total_rx_packets = 0;
 
 	i = rx_ring->next_to_clean;
 	rx_desc = E1000_RX_DESC(*rx_ring, i);
@@ -4153,7 +4181,9 @@ static bool e1000_clean_jumbo_rx_irq(str
 
 		status = rx_desc->status;
 
-		if (++i == rx_ring->count) i = 0;
+		if (++i == rx_ring->count)
+			i = 0;
+
 		next_rxd = E1000_RX_DESC(*rx_ring, i);
 		prefetch(next_rxd);
 
@@ -4356,7 +4386,7 @@ static bool e1000_clean_rx_irq(struct e1
 	unsigned int i;
 	int cleaned_count = 0;
 	bool cleaned = false;
-	unsigned int total_rx_bytes=0, total_rx_packets=0;
+	unsigned int total_rx_bytes = 0, total_rx_packets = 0;
 
 	i = rx_ring->next_to_clean;
 	rx_desc = E1000_RX_DESC(*rx_ring, i);
@@ -4395,7 +4425,9 @@ static bool e1000_clean_rx_irq(struct e1
 			buffer_info->rxbuf.data = NULL;
 		}
 
-		if (++i == rx_ring->count) i = 0;
+		if (++i == rx_ring->count)
+			i = 0;
+
 		next_rxd = E1000_RX_DESC(*rx_ring, i);
 		prefetch(next_rxd);
 
@@ -4683,9 +4715,11 @@ static void e1000_smartspeed(struct e100
 		 * we assume back-to-back
 		 */
 		e1000_read_phy_reg(hw, PHY_1000T_STATUS, &phy_status);
-		if (!(phy_status & SR_1000T_MS_CONFIG_FAULT)) return;
+		if (!(phy_status & SR_1000T_MS_CONFIG_FAULT))
+			return;
 		e1000_read_phy_reg(hw, PHY_1000T_STATUS, &phy_status);
-		if (!(phy_status & SR_1000T_MS_CONFIG_FAULT)) return;
+		if (!(phy_status & SR_1000T_MS_CONFIG_FAULT))
+			return;
 		e1000_read_phy_reg(hw, PHY_1000T_CTRL, &phy_ctrl);
 		if (phy_ctrl & CR_1000T_MS_ENABLE) {
 			phy_ctrl &= ~CR_1000T_MS_ENABLE;
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/intel/e1000e/defines.h
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/intel/e1000e/defines.h
@@ -441,12 +441,13 @@
 #define E1000_IMS_RXQ1      E1000_ICR_RXQ1      /* Rx Queue 1 Interrupt */
 #define E1000_IMS_TXQ0      E1000_ICR_TXQ0      /* Tx Queue 0 Interrupt */
 #define E1000_IMS_TXQ1      E1000_ICR_TXQ1      /* Tx Queue 1 Interrupt */
-#define E1000_IMS_OTHER     E1000_ICR_OTHER     /* Other Interrupts */
+#define E1000_IMS_OTHER     E1000_ICR_OTHER     /* Other Interrupt */
 
 /* Interrupt Cause Set */
 #define E1000_ICS_LSC       E1000_ICR_LSC       /* Link Status Change */
 #define E1000_ICS_RXSEQ     E1000_ICR_RXSEQ     /* Rx sequence error */
 #define E1000_ICS_RXDMT0    E1000_ICR_RXDMT0    /* Rx desc min. threshold */
+#define E1000_ICS_OTHER     E1000_ICR_OTHER     /* Other Interrupt */
 
 /* Transmit Descriptor Control */
 #define E1000_TXDCTL_PTHRESH 0x0000003F /* TXDCTL Prefetch Threshold */
@@ -527,6 +528,11 @@
 #define E1000_RXCW_C          0x20000000        /* Receive config */
 #define E1000_RXCW_SYNCH      0x40000000        /* Receive config synch */
 
+/* HH Time Sync */
+#define E1000_TSYNCTXCTL_MAX_ALLOWED_DLY_MASK	0x0000F000 /* max delay */
+#define E1000_TSYNCTXCTL_SYNC_COMP		0x40000000 /* sync complete */
+#define E1000_TSYNCTXCTL_START_SYNC		0x80000000 /* initiate sync */
+
 #define E1000_TSYNCTXCTL_VALID		0x00000001 /* Tx timestamp valid */
 #define E1000_TSYNCTXCTL_ENABLED	0x00000010 /* enable Tx timestamping */
 
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/intel/e1000e/e1000.h
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/intel/e1000e/e1000.h
@@ -480,7 +480,7 @@ extern const char e1000e_driver_version[
 void e1000e_check_options(struct e1000_adapter *adapter);
 void e1000e_set_ethtool_ops(struct net_device *netdev);
 
-int e1000e_up(struct e1000_adapter *adapter);
+void e1000e_up(struct e1000_adapter *adapter);
 void e1000e_down(struct e1000_adapter *adapter, bool reset);
 void e1000e_reinit_locked(struct e1000_adapter *adapter);
 void e1000e_reset(struct e1000_adapter *adapter);
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/intel/e1000e/hw.h
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/intel/e1000e/hw.h
@@ -91,6 +91,7 @@ struct e1000_hw;
 #define E1000_DEV_ID_PCH_SPT_I219_V		0x1570	/* SPT PCH */
 #define E1000_DEV_ID_PCH_SPT_I219_LM2		0x15B7	/* SPT-H PCH */
 #define E1000_DEV_ID_PCH_SPT_I219_V2		0x15B8	/* SPT-H PCH */
+#define E1000_DEV_ID_PCH_LBG_I219_LM3		0x15B9	/* LBG PCH */
 
 #define E1000_REVISION_4	4
 
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/intel/e1000e/ich8lan.c
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/intel/e1000e/ich8lan.c
@@ -1984,7 +1984,7 @@ static s32 e1000_check_reset_block_ich8l
 	int i = 0;
 
 	while ((blocked = !(er32(FWSM) & E1000_ICH_FWSM_RSPCIPHY)) &&
-	       (i++ < 10))
+	       (i++ < 30))
 		usleep_range(10000, 20000);
 	return blocked ? E1000_BLK_PHY_RESET : 0;
 }
@@ -3093,24 +3093,45 @@ static s32 e1000_valid_nvm_bank_detect_i
 	struct e1000_nvm_info *nvm = &hw->nvm;
 	u32 bank1_offset = nvm->flash_bank_size * sizeof(u16);
 	u32 act_offset = E1000_ICH_NVM_SIG_WORD * 2 + 1;
+	u32 nvm_dword = 0;
 	u8 sig_byte = 0;
 	s32 ret_val;
 
 	switch (hw->mac.type) {
-		/* In SPT, read from the CTRL_EXT reg instead of
-		 * accessing the sector valid bits from the nvm
-		 */
 	case e1000_pch_spt:
-		*bank = er32(CTRL_EXT)
-		    & E1000_CTRL_EXT_NVMVS;
-		if ((*bank == 0) || (*bank == 1)) {
-			e_dbg("ERROR: No valid NVM bank present\n");
-			return -E1000_ERR_NVM;
-		} else {
-			*bank = *bank - 2;
+		bank1_offset = nvm->flash_bank_size;
+		act_offset = E1000_ICH_NVM_SIG_WORD;
+
+		/* set bank to 0 in case flash read fails */
+		*bank = 0;
+
+		/* Check bank 0 */
+		ret_val = e1000_read_flash_dword_ich8lan(hw, act_offset,
+							 &nvm_dword);
+		if (ret_val)
+			return ret_val;
+		sig_byte = (u8)((nvm_dword & 0xFF00) >> 8);
+		if ((sig_byte & E1000_ICH_NVM_VALID_SIG_MASK) ==
+		    E1000_ICH_NVM_SIG_VALUE) {
+			*bank = 0;
 			return 0;
 		}
-		break;
+
+		/* Check bank 1 */
+		ret_val = e1000_read_flash_dword_ich8lan(hw, act_offset +
+							 bank1_offset,
+							 &nvm_dword);
+		if (ret_val)
+			return ret_val;
+		sig_byte = (u8)((nvm_dword & 0xFF00) >> 8);
+		if ((sig_byte & E1000_ICH_NVM_VALID_SIG_MASK) ==
+		    E1000_ICH_NVM_SIG_VALUE) {
+			*bank = 1;
+			return 0;
+		}
+
+		e_dbg("ERROR: No valid NVM bank present\n");
+		return -E1000_ERR_NVM;
 	case e1000_ich8lan:
 	case e1000_ich9lan:
 		eecd = er32(EECD);
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/intel/e1000e/netdev.c
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/intel/e1000e/netdev.c
@@ -1905,30 +1905,15 @@ static irqreturn_t e1000_msix_other(int
 	struct net_device *netdev = data;
 	struct e1000_adapter *adapter = netdev_priv(netdev);
 	struct e1000_hw *hw = &adapter->hw;
-	u32 icr = er32(ICR);
-
-	if (!(icr & E1000_ICR_INT_ASSERTED)) {
-		if (!test_bit(__E1000_DOWN, &adapter->state))
-			ew32(IMS, E1000_IMS_OTHER);
-		return IRQ_NONE;
-	}
 
-	if (icr & adapter->eiac_mask)
-		ew32(ICS, (icr & adapter->eiac_mask));
+	hw->mac.get_link_status = true;
 
-	if (icr & E1000_ICR_OTHER) {
-		if (!(icr & E1000_ICR_LSC))
-			goto no_link_interrupt;
-		hw->mac.get_link_status = true;
-		/* guard against interrupt when we're going down */
-		if (!test_bit(__E1000_DOWN, &adapter->state))
-			mod_timer(&adapter->watchdog_timer, jiffies + 1);
+	/* guard against interrupt when we're going down */
+	if (!test_bit(__E1000_DOWN, &adapter->state)) {
+		mod_timer(&adapter->watchdog_timer, jiffies + 1);
+		ew32(IMS, E1000_IMS_OTHER);
 	}
 
-no_link_interrupt:
-	if (!test_bit(__E1000_DOWN, &adapter->state))
-		ew32(IMS, E1000_IMS_LSC | E1000_IMS_OTHER);
-
 	return IRQ_HANDLED;
 }
 
@@ -1946,6 +1931,9 @@ static irqreturn_t e1000_intr_msix_tx(in
 		/* Ring was not completely cleaned, so fire another interrupt */
 		ew32(ICS, tx_ring->ims_val);
 
+	if (!test_bit(__E1000_DOWN, &adapter->state))
+		ew32(IMS, adapter->tx_ring->ims_val);
+
 	return IRQ_HANDLED;
 }
 
@@ -1959,8 +1947,10 @@ static irqreturn_t e1000_intr_msix_rx(in
 	 * previous interrupt.
 	 */
 	if (rx_ring->set_itr) {
-		writel(1000000000 / (rx_ring->itr_val * 256),
-		       rx_ring->itr_register);
+		u32 itr = rx_ring->itr_val ?
+			  1000000000 / (rx_ring->itr_val * 256) : 0;
+
+		writel(itr, rx_ring->itr_register);
 		rx_ring->set_itr = 0;
 	}
 
@@ -2025,6 +2015,7 @@ static void e1000_configure_msix(struct
 		       hw->hw_addr + E1000_EITR_82574(vector));
 	else
 		writel(1, hw->hw_addr + E1000_EITR_82574(vector));
+	adapter->eiac_mask |= E1000_IMS_OTHER;
 
 	/* Cause Tx interrupts on every write back */
 	ivar |= (1 << 31);
@@ -2032,12 +2023,8 @@ static void e1000_configure_msix(struct
 	ew32(IVAR, ivar);
 
 	/* enable MSI-X PBA support */
-	ctrl_ext = er32(CTRL_EXT);
-	ctrl_ext |= E1000_CTRL_EXT_PBA_CLR;
-
-	/* Auto-Mask Other interrupts upon ICR read */
-	ew32(IAM, ~E1000_EIAC_MASK_82574 | E1000_IMS_OTHER);
-	ctrl_ext |= E1000_CTRL_EXT_EIAME;
+	ctrl_ext = er32(CTRL_EXT) & ~E1000_CTRL_EXT_IAME;
+	ctrl_ext |= E1000_CTRL_EXT_PBA_CLR | E1000_CTRL_EXT_EIAME;
 	ew32(CTRL_EXT, ctrl_ext);
 	e1e_flush();
 }
@@ -2253,7 +2240,7 @@ static void e1000_irq_enable(struct e100
 
 	if (adapter->msix_entries) {
 		ew32(EIAC_82574, adapter->eiac_mask & E1000_EIAC_MASK_82574);
-		ew32(IMS, adapter->eiac_mask | E1000_IMS_OTHER | E1000_IMS_LSC);
+		ew32(IMS, adapter->eiac_mask | E1000_IMS_LSC);
 	} else if ((hw->mac.type == e1000_pch_lpt) ||
 		   (hw->mac.type == e1000_pch_spt)) {
 		ew32(IMS, IMS_ENABLE_MASK | E1000_IMS_ECCER);
@@ -4144,10 +4131,24 @@ void e1000e_reset(struct e1000_adapter *
 
 }
 
-int e1000e_up(struct e1000_adapter *adapter)
+/**
+ * e1000e_trigger_lsc - trigger an LSC interrupt
+ * @adapter: 
+ *
+ * Fire a link status change interrupt to start the watchdog.
+ **/
+static void e1000e_trigger_lsc(struct e1000_adapter *adapter)
 {
 	struct e1000_hw *hw = &adapter->hw;
 
+	if (adapter->msix_entries)
+		ew32(ICS, E1000_ICS_OTHER);
+	else
+		ew32(ICS, E1000_ICS_LSC);
+}
+
+void e1000e_up(struct e1000_adapter *adapter)
+{
 	/* hardware has been reset, we need to reload some things */
 	e1000_configure(adapter);
 
@@ -4159,13 +4160,7 @@ int e1000e_up(struct e1000_adapter *adap
 
 	netif_start_queue(adapter->netdev);
 
-	/* fire a link change interrupt to start the watchdog */
-	if (adapter->msix_entries)
-		ew32(ICS, E1000_ICS_LSC | E1000_ICR_OTHER);
-	else
-		ew32(ICS, E1000_ICS_LSC);
-
-	return 0;
+	e1000e_trigger_lsc(adapter);
 }
 
 static void e1000e_flush_descriptors(struct e1000_adapter *adapter)
@@ -4590,11 +4585,7 @@ static int e1000_open(struct net_device
 	hw->mac.get_link_status = true;
 	pm_runtime_put(&pdev->dev);
 
-	/* fire a link status change interrupt to start the watchdog */
-	if (adapter->msix_entries)
-		ew32(ICS, E1000_ICS_LSC | E1000_ICR_OTHER);
-	else
-		ew32(ICS, E1000_ICS_LSC);
+	e1000e_trigger_lsc(adapter);
 
 	return 0;
 
@@ -6631,7 +6622,7 @@ static int e1000e_pm_runtime_resume(stru
 		return rc;
 
 	if (netdev->flags & IFF_UP)
-		rc = e1000e_up(adapter);
+		e1000e_up(adapter);
 
 	return rc;
 }
@@ -6822,13 +6813,8 @@ static void e1000_io_resume(struct pci_d
 
 	e1000_init_manageability_pt(adapter);
 
-	if (netif_running(netdev)) {
-		if (e1000e_up(adapter)) {
-			dev_err(&pdev->dev,
-				"can't bring device back up after reset\n");
-			return;
-		}
-	}
+	if (netif_running(netdev))
+		e1000e_up(adapter);
 
 	netif_device_attach(netdev);
 
@@ -7465,6 +7451,7 @@ static const struct pci_device_id e1000_
 	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_SPT_I219_V), board_pch_spt },
 	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_SPT_I219_LM2), board_pch_spt },
 	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_SPT_I219_V2), board_pch_spt },
+	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_LBG_I219_LM3), board_pch_spt },
 
 	{ 0, 0, 0, 0, 0, 0, 0 }	/* terminate list */
 };
@@ -7504,14 +7491,11 @@ static struct pci_driver e1000_driver =
  **/
 static int __init e1000_init_module(void)
 {
-	int ret;
-
 	pr_info("Intel(R) PRO/1000 Network Driver - %s\n",
 		e1000e_driver_version);
 	pr_info("Copyright(c) 1999 - 2015 Intel Corporation.\n");
-	ret = pci_register_driver(&e1000_driver);
 
-	return ret;
+	return pci_register_driver(&e1000_driver);
 }
 module_init(e1000_init_module);
 
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/intel/e1000e/ptp.c
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/intel/e1000e/ptp.c
@@ -26,6 +26,12 @@
 
 #include "e1000.h"
 
+#ifdef CONFIG_E1000E_HWTS
+#include <linux/clocksource.h>
+#include <linux/ktime.h>
+#include <asm/tsc.h>
+#endif
+
 /**
  * e1000e_phc_adjfreq - adjust the frequency of the hardware clock
  * @ptp: ptp clock structure
@@ -98,6 +104,78 @@ static int e1000e_phc_adjtime(struct ptp
 	return 0;
 }
 
+#ifdef CONFIG_E1000E_HWTS
+#define MAX_HW_WAIT_COUNT (3)
+
+/**
+ * e1000e_phc_get_syncdevicetime - Callback given to timekeeping code reads system/device registers
+ * @device: current device time
+ * @system: system counter value read synchronously with device time
+ * @ctx: context provided by timekeeping code
+ *
+ * Read device and system (ART) clock simultaneously and return the corrected
+ * clock values in ns.
+ **/
+static int e1000e_phc_get_syncdevicetime(ktime_t *device,
+					 struct system_counterval_t *system,
+					 void *ctx)
+{
+	struct e1000_adapter *adapter = (struct e1000_adapter *)ctx;
+	struct e1000_hw *hw = &adapter->hw;
+	unsigned long flags;
+	int i;
+	u32 tsync_ctrl;
+	cycle_t dev_cycles;
+	cycle_t sys_cycles;
+
+	tsync_ctrl = er32(TSYNCTXCTL);
+	tsync_ctrl |= E1000_TSYNCTXCTL_START_SYNC |
+		E1000_TSYNCTXCTL_MAX_ALLOWED_DLY_MASK;
+	ew32(TSYNCTXCTL, tsync_ctrl);
+	for (i = 0; i < MAX_HW_WAIT_COUNT; ++i) {
+		udelay(1);
+		tsync_ctrl = er32(TSYNCTXCTL);
+		if (tsync_ctrl & E1000_TSYNCTXCTL_SYNC_COMP)
+			break;
+	}
+
+	if (i == MAX_HW_WAIT_COUNT)
+		return -ETIMEDOUT;
+
+	dev_cycles = er32(SYSSTMPH);
+	dev_cycles <<= 32;
+	dev_cycles |= er32(SYSSTMPL);
+	spin_lock_irqsave(&adapter->systim_lock, flags);
+	*device = ns_to_ktime(timecounter_cyc2time(&adapter->tc, dev_cycles));
+	spin_unlock_irqrestore(&adapter->systim_lock, flags);
+
+	sys_cycles = er32(PLTSTMPH);
+	sys_cycles <<= 32;
+	sys_cycles |= er32(PLTSTMPL);
+	*system = convert_art_to_tsc(sys_cycles);
+
+	return 0;
+}
+
+/**
+ * e1000e_phc_getsynctime - Reads the current system/device cross timestamp
+ * @ptp: ptp clock structure
+ * @cts: structure containing timestamp
+ *
+ * Read device and system (ART) clock simultaneously and return the scaled
+ * clock values in ns.
+ **/
+static int e1000e_phc_getcrosststamp(struct ptp_clock_info *ptp,
+				     struct system_device_crosststamp *xtstamp)
+{
+	struct e1000_adapter *adapter = container_of(ptp, struct e1000_adapter,
+						     ptp_clock_info);
+
+	return get_device_system_crosststamp(e1000e_phc_get_syncdevicetime,
+						adapter, NULL, xtstamp);
+}
+#endif/*CONFIG_E1000E_HWTS*/
+
 /**
  * e1000e_phc_gettime - Reads the current time from the hardware clock
  * @ptp: ptp clock structure
@@ -236,6 +314,13 @@ void e1000e_ptp_init(struct e1000_adapte
 		break;
 	}
 
+#ifdef CONFIG_E1000E_HWTS
+	/* CPU must have ART and GBe must be from Sunrise Point or greater */
+	if (hw->mac.type >= e1000_pch_spt && boot_cpu_has(X86_FEATURE_ART))
+		adapter->ptp_clock_info.getcrosststamp =
+			e1000e_phc_getcrosststamp;
+#endif/*CONFIG_E1000E_HWTS*/
+
 	INIT_DELAYED_WORK(&adapter->systim_overflow_work,
 			  e1000e_systim_overflow_work);
 
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/intel/e1000e/regs.h
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/intel/e1000e/regs.h
@@ -245,6 +245,10 @@
 #define E1000_SYSTIML	0x0B600	/* System time register Low - RO */
 #define E1000_SYSTIMH	0x0B604	/* System time register High - RO */
 #define E1000_TIMINCA	0x0B608	/* Increment attributes register - RW */
+#define E1000_SYSSTMPL  0x0B648 /* HH Timesync system stamp low register */
+#define E1000_SYSSTMPH  0x0B64C /* HH Timesync system stamp hi register */
+#define E1000_PLTSTMPL  0x0B640 /* HH Timesync platform stamp low register */
+#define E1000_PLTSTMPH  0x0B644 /* HH Timesync platform stamp hi register */
 #define E1000_RXMTRL	0x0B634	/* Time sync Rx EtherType and Msg Type - RW */
 #define E1000_RXUDP	0x0B638	/* Time Sync Rx UDP Port - RW */
 
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/intel/fm10k/Makefile
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/intel/fm10k/Makefile
@@ -1,7 +1,7 @@
 ################################################################################
 #
 # Intel Ethernet Switch Host Interface Driver
-# Copyright(c) 2013 - 2014 Intel Corporation.
+# Copyright(c) 2013 - 2015 Intel Corporation.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms and conditions of the GNU General Public License,
@@ -27,7 +27,17 @@
 
 obj-$(CONFIG_FM10K) += fm10k.o
 
-fm10k-objs := fm10k_main.o fm10k_common.o fm10k_pci.o \
-	      fm10k_netdev.o fm10k_ethtool.o fm10k_pf.o fm10k_vf.o \
-	      fm10k_mbx.o fm10k_iov.o fm10k_tlv.o \
-	      fm10k_debugfs.o fm10k_ptp.o fm10k_dcbnl.o
+fm10k-y := fm10k_main.o \
+	   fm10k_common.o \
+	   fm10k_pci.o \
+	   fm10k_ptp.o \
+	   fm10k_netdev.o \
+	   fm10k_ethtool.o \
+	   fm10k_pf.o \
+	   fm10k_vf.o \
+	   fm10k_mbx.o \
+	   fm10k_iov.o \
+	   fm10k_tlv.o
+
+fm10k-$(CONFIG_DEBUG_FS) += fm10k_debugfs.o
+fm10k-$(CONFIG_DCB) += fm10k_dcbnl.o
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/intel/fm10k/fm10k.h
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/intel/fm10k/fm10k.h
@@ -23,6 +23,7 @@
 
 #include <linux/types.h>
 #include <linux/etherdevice.h>
+#include <linux/cpumask.h>
 #include <linux/rtnetlink.h>
 #include <linux/if_vlan.h>
 #include <linux/pci.h>
@@ -33,7 +34,7 @@
 #include "fm10k_pf.h"
 #include "fm10k_vf.h"
 
-#define FM10K_MAX_JUMBO_FRAME_SIZE	15358	/* Maximum supported size 15K */
+#define FM10K_MAX_JUMBO_FRAME_SIZE	15342	/* Maximum supported size 15K */
 
 #define MAX_QUEUES	FM10K_MAX_QUEUES_PF
 
@@ -66,6 +67,7 @@ struct fm10k_l2_accel {
 enum fm10k_ring_state_t {
 	__FM10K_TX_DETECT_HANG,
 	__FM10K_HANG_CHECK_ARMED,
+	__FM10K_TX_XPS_INIT_DONE,
 };
 
 #define check_for_tx_hang(ring) \
@@ -138,7 +140,7 @@ struct fm10k_ring {
 					 * different for DCB and RSS modes
 					 */
 	u8 qos_pc;			/* priority class of queue */
-	u16 vid;			/* default vlan ID of queue */
+	u16 vid;			/* default VLAN ID of queue */
 	u16 count;			/* amount of descriptors */
 
 	u16 next_to_alloc;
@@ -164,14 +166,20 @@ struct fm10k_ring_container {
 	unsigned int total_packets;	/* total packets processed this int */
 	u16 work_limit;			/* total work allowed per interrupt */
 	u16 itr;			/* interrupt throttle rate value */
+	u8 itr_scale;			/* ITR adjustment based on PCI speed */
 	u8 count;			/* total number of rings in vector */
 };
 
 #define FM10K_ITR_MAX		0x0FFF	/* maximum value for ITR */
 #define FM10K_ITR_10K		100	/* 100us */
 #define FM10K_ITR_20K		50	/* 50us */
+#define FM10K_ITR_40K		25	/* 25us */
 #define FM10K_ITR_ADAPTIVE	0x8000	/* adaptive interrupt moderation flag */
 
+#define ITR_IS_ADAPTIVE(itr) (!!(itr & FM10K_ITR_ADAPTIVE))
+
+#define FM10K_TX_ITR_DEFAULT	FM10K_ITR_40K
+#define FM10K_RX_ITR_DEFAULT	FM10K_ITR_20K
 #define FM10K_ITR_ENABLE	(FM10K_ITR_AUTOMASK | FM10K_ITR_MASK_CLEAR)
 
 static inline struct netdev_queue *txring_txq(const struct fm10k_ring *ring)
@@ -203,6 +211,7 @@ struct fm10k_q_vector {
 	struct fm10k_ring_container rx, tx;
 
 	struct napi_struct napi;
+	cpumask_t affinity_mask;
 	char name[IFNAMSIZ + 9];
 
 #ifdef CONFIG_DEBUG_FS
@@ -413,7 +422,7 @@ static inline u16 fm10k_desc_unused(stru
 	 (&(((union fm10k_rx_desc *)((R)->desc))[i]))
 
 #define FM10K_MAX_TXD_PWR	14
-#define FM10K_MAX_DATA_PER_TXD	(1 << FM10K_MAX_TXD_PWR)
+#define FM10K_MAX_DATA_PER_TXD	BIT(FM10K_MAX_TXD_PWR)
 
 /* Tx Descriptors needed, worst case */
 #define TXD_USE_COUNT(S)	DIV_ROUND_UP((S), FM10K_MAX_DATA_PER_TXD)
@@ -434,7 +443,7 @@ union fm10k_ftag_info {
 	struct {
 		/* dglort and sglort combined into a single 32bit desc read */
 		__le32 glort;
-		/* upper 16 bits of vlan are reserved 0 for swpri_type_user */
+		/* upper 16 bits of VLAN are reserved 0 for swpri_type_user */
 		__le32 vlan;
 	} d;
 	struct {
@@ -484,7 +493,7 @@ void fm10k_netpoll(struct net_device *ne
 #endif
 
 /* Netdev */
-struct net_device *fm10k_alloc_netdev(void);
+struct net_device *fm10k_alloc_netdev(const struct fm10k_info *info);
 int fm10k_setup_rx_resources(struct fm10k_ring *);
 int fm10k_setup_tx_resources(struct fm10k_ring *);
 void fm10k_free_rx_resources(struct fm10k_ring *);
@@ -551,5 +560,9 @@ int fm10k_get_ts_config(struct net_devic
 int fm10k_set_ts_config(struct net_device *netdev, struct ifreq *ifr);
 
 /* DCB */
+#ifdef CONFIG_DCB
 void fm10k_dcbnl_set_ops(struct net_device *dev);
+#else
+static inline void fm10k_dcbnl_set_ops(struct net_device *dev) {}
+#endif
 #endif /* _FM10K_H_ */
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/intel/fm10k/fm10k_dcbnl.c
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/intel/fm10k/fm10k_dcbnl.c
@@ -20,7 +20,6 @@
 
 #include "fm10k.h"
 
-#ifdef CONFIG_DCB
 /**
  * fm10k_dcbnl_ieee_getets - get the ETS configuration for the device
  * @dev: netdev interface for the device
@@ -155,7 +154,6 @@ static const struct dcbnl_rtnl_ops fm10k
 	.setdcbx	= fm10k_dcbnl_setdcbx,
 };
 
-#endif /* CONFIG_DCB */
 /**
  * fm10k_dcbnl_set_ops - Configures dcbnl ops pointer for netdev
  * @dev: netdev interface for the device
@@ -164,11 +162,9 @@ static const struct dcbnl_rtnl_ops fm10k
  **/
 void fm10k_dcbnl_set_ops(struct net_device *dev)
 {
-#ifdef CONFIG_DCB
 	struct fm10k_intfc *interface = netdev_priv(dev);
 	struct fm10k_hw *hw = &interface->hw;
 
 	if (hw->mac.type == fm10k_mac_pf)
 		dev->dcbnl_ops = &fm10k_dcbnl_ops;
-#endif /* CONFIG_DCB */
 }
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/intel/fm10k/fm10k_debugfs.c
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/intel/fm10k/fm10k_debugfs.c
@@ -18,8 +18,6 @@
  * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
  */
 
-#ifdef CONFIG_DEBUG_FS
-
 #include "fm10k.h"
 
 #include <linux/debugfs.h>
@@ -258,5 +256,3 @@ void fm10k_dbg_exit(void)
 	debugfs_remove_recursive(dbg_root);
 	dbg_root = NULL;
 }
-
-#endif /* CONFIG_DEBUG_FS */
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/intel/fm10k/fm10k_ethtool.c
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/intel/fm10k/fm10k_ethtool.c
@@ -111,12 +111,14 @@ static const struct fm10k_stats fm10k_gs
 
 static const struct fm10k_stats fm10k_gstrings_mbx_stats[] = {
 	FM10K_MBX_STAT("mbx_tx_busy", tx_busy),
-	FM10K_MBX_STAT("mbx_tx_oversized", tx_dropped),
+	FM10K_MBX_STAT("mbx_tx_dropped", tx_dropped),
 	FM10K_MBX_STAT("mbx_tx_messages", tx_messages),
 	FM10K_MBX_STAT("mbx_tx_dwords", tx_dwords),
+	FM10K_MBX_STAT("mbx_tx_mbmem_pulled", tx_mbmem_pulled),
 	FM10K_MBX_STAT("mbx_rx_messages", rx_messages),
 	FM10K_MBX_STAT("mbx_rx_dwords", rx_dwords),
 	FM10K_MBX_STAT("mbx_rx_parse_err", rx_parse_err),
+	FM10K_MBX_STAT("mbx_rx_mbmem_pushed", rx_mbmem_pushed),
 };
 
 #define FM10K_GLOBAL_STATS_LEN ARRAY_SIZE(fm10k_gstrings_global_stats)
@@ -125,7 +127,7 @@ static const struct fm10k_stats fm10k_gs
 #define FM10K_MBX_STATS_LEN ARRAY_SIZE(fm10k_gstrings_mbx_stats)
 
 #define FM10K_QUEUE_STATS_LEN(_n) \
-	( (_n) * 2 * (sizeof(struct fm10k_queue_stats) / sizeof(u64)))
+	((_n) * 2 * (sizeof(struct fm10k_queue_stats) / sizeof(u64)))
 
 #define FM10K_STATIC_STATS_LEN (FM10K_GLOBAL_STATS_LEN + \
 				FM10K_NETDEV_STATS_LEN + \
@@ -257,7 +259,8 @@ static int fm10k_get_sset_count(struct n
 			stats_len += FM10K_DEBUG_STATS_LEN;
 
 			if (iov_data)
-				stats_len += FM10K_MBX_STATS_LEN * iov_data->num_vfs;
+				stats_len += FM10K_MBX_STATS_LEN *
+					iov_data->num_vfs;
 		}
 
 		return stats_len;
@@ -296,14 +299,16 @@ static void fm10k_get_ethtool_stats(stru
 
 	if (interface->flags & FM10K_FLAG_DEBUG_STATS) {
 		for (i = 0; i < FM10K_DEBUG_STATS_LEN; i++) {
-			p = (char *)interface + fm10k_gstrings_debug_stats[i].stat_offset;
+			p = (char *)interface +
+				fm10k_gstrings_debug_stats[i].stat_offset;
 			*(data++) = (fm10k_gstrings_debug_stats[i].sizeof_stat ==
 				     sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
 		}
 	}
 
 	for (i = 0; i < FM10K_MBX_STATS_LEN; i++) {
-		p = (char *)&interface->hw.mbx + fm10k_gstrings_mbx_stats[i].stat_offset;
+		p = (char *)&interface->hw.mbx +
+			fm10k_gstrings_mbx_stats[i].stat_offset;
 		*(data++) = (fm10k_gstrings_mbx_stats[i].sizeof_stat ==
 			sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
 	}
@@ -320,6 +325,7 @@ static void fm10k_get_ethtool_stats(stru
 	if ((interface->flags & FM10K_FLAG_DEBUG_STATS) && iov_data) {
 		for (i = 0; i < iov_data->num_vfs; i++) {
 			struct fm10k_vf_info *vf_info;
+
 			vf_info = &iov_data->vf_info[i];
 
 			/* skip stats if we don't have a vf info */
@@ -329,7 +335,8 @@ static void fm10k_get_ethtool_stats(stru
 			}
 
 			for (j = 0; j < FM10K_MBX_STATS_LEN; j++) {
-				p = (char *)&vf_info->mbx + fm10k_gstrings_mbx_stats[j].stat_offset;
+				p = (char *)&vf_info->mbx +
+					fm10k_gstrings_mbx_stats[j].stat_offset;
 				*(data++) = (fm10k_gstrings_mbx_stats[j].sizeof_stat ==
 					     sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
 			}
@@ -699,12 +706,10 @@ static int fm10k_get_coalesce(struct net
 {
 	struct fm10k_intfc *interface = netdev_priv(dev);
 
-	ec->use_adaptive_tx_coalesce =
-		!!(interface->tx_itr & FM10K_ITR_ADAPTIVE);
+	ec->use_adaptive_tx_coalesce = ITR_IS_ADAPTIVE(interface->tx_itr);
 	ec->tx_coalesce_usecs = interface->tx_itr & ~FM10K_ITR_ADAPTIVE;
 
-	ec->use_adaptive_rx_coalesce =
-		!!(interface->rx_itr & FM10K_ITR_ADAPTIVE);
+	ec->use_adaptive_rx_coalesce = ITR_IS_ADAPTIVE(interface->rx_itr);
 	ec->rx_coalesce_usecs = interface->rx_itr & ~FM10K_ITR_ADAPTIVE;
 
 	return 0;
@@ -729,10 +734,10 @@ static int fm10k_set_coalesce(struct net
 
 	/* set initial values for adaptive ITR */
 	if (ec->use_adaptive_tx_coalesce)
-		tx_itr = FM10K_ITR_ADAPTIVE | FM10K_ITR_10K;
+		tx_itr = FM10K_ITR_ADAPTIVE | FM10K_TX_ITR_DEFAULT;
 
 	if (ec->use_adaptive_rx_coalesce)
-		rx_itr = FM10K_ITR_ADAPTIVE | FM10K_ITR_20K;
+		rx_itr = FM10K_ITR_ADAPTIVE | FM10K_RX_ITR_DEFAULT;
 
 	/* update interface */
 	interface->tx_itr = tx_itr;
@@ -1020,7 +1025,6 @@ static int fm10k_set_priv_flags(struct n
 	return 0;
 }
 
-
 static u32 fm10k_get_reta_size(struct net_device __always_unused *netdev)
 {
 	return FM10K_RETA_SIZE * FM10K_RETA_ENTRIES_PER_REG;
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/intel/fm10k/fm10k_main.c
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/intel/fm10k/fm10k_main.c
@@ -28,7 +28,7 @@
 
 #include "fm10k.h"
 
-#define DRV_VERSION	"0.15.2-k"
+#define DRV_VERSION	"0.19.3-k"
 const char fm10k_driver_version[] = DRV_VERSION;
 char fm10k_driver_name[] = "fm10k";
 static const char fm10k_driver_string[] =
@@ -42,7 +42,7 @@ MODULE_LICENSE("GPL");
 MODULE_VERSION(DRV_VERSION);
 
 /* single workqueue for entire fm10k driver */
-struct workqueue_struct *fm10k_workqueue = NULL;
+struct workqueue_struct *fm10k_workqueue;
 
 /**
  * fm10k_init_module - Driver Registration Routine
@@ -56,8 +56,7 @@ static int __init fm10k_init_module(void
 	pr_info("%s\n", fm10k_copyright);
 
 	/* create driver workqueue */
-	if (!fm10k_workqueue)
-		fm10k_workqueue = create_workqueue("fm10k");
+	fm10k_workqueue = create_workqueue("fm10k");
 
 	fm10k_dbg_init();
 
@@ -80,7 +79,6 @@ static void __exit fm10k_exit_module(voi
 	/* destroy driver workqueue */
 	flush_workqueue(fm10k_workqueue);
 	destroy_workqueue(fm10k_workqueue);
-	fm10k_workqueue = NULL;
 }
 module_exit(fm10k_exit_module);
 
@@ -917,7 +915,7 @@ static u8 fm10k_tx_desc_flags(struct sk_
 	/* set timestamping bits */
 	if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP) &&
 	    likely(skb_shinfo(skb)->tx_flags & SKBTX_IN_PROGRESS))
-			desc_flags |= FM10K_TXD_FLAG_TIME;
+		desc_flags |= FM10K_TXD_FLAG_TIME;
 
 	/* set checksum offload bits */
 	desc_flags |= FM10K_SET_FLAG(tx_flags, FM10K_TX_FLAGS_CSUM,
@@ -1094,11 +1092,11 @@ dma_error:
 netdev_tx_t fm10k_xmit_frame_ring(struct sk_buff *skb,
 				  struct fm10k_ring *tx_ring)
 {
+	u16 count = TXD_USE_COUNT(skb_headlen(skb));
 	struct fm10k_tx_buffer *first;
-	int tso;
-	u32 tx_flags = 0;
 	unsigned short f;
-	u16 count = TXD_USE_COUNT(skb_headlen(skb));
+	u32 tx_flags = 0;
+	int tso;
 
 	/* need: 1 descriptor per page * PAGE_SIZE/FM10K_MAX_DATA_PER_TXD,
 	 *       + 1 desc for skb_headlen/FM10K_MAX_DATA_PER_TXD,
@@ -1363,10 +1361,10 @@ static bool fm10k_clean_tx_irq(struct fm
  **/
 static void fm10k_update_itr(struct fm10k_ring_container *ring_container)
 {
-	unsigned int avg_wire_size, packets;
+	unsigned int avg_wire_size, packets, itr_round;
 
 	/* Only update ITR if we are using adaptive setting */
-	if (!(ring_container->itr & FM10K_ITR_ADAPTIVE))
+	if (!ITR_IS_ADAPTIVE(ring_container->itr))
 		goto clear_counts;
 
 	packets = ring_container->total_packets;
@@ -1375,18 +1373,44 @@ static void fm10k_update_itr(struct fm10
 
 	avg_wire_size = ring_container->total_bytes / packets;
 
-	/* Add 24 bytes to size to account for CRC, preamble, and gap */
-	avg_wire_size += 24;
+	/* The following is a crude approximation of:
+	 *  wmem_default / (size + overhead) = desired_pkts_per_int
+	 *  rate / bits_per_byte / (size + ethernet overhead) = pkt_rate
+	 *  (desired_pkt_rate / pkt_rate) * usecs_per_sec = ITR value
+	 *
+	 * Assuming wmem_default is 212992 and overhead is 640 bytes per
+	 * packet, (256 skb, 64 headroom, 320 shared info), we can reduce the
+	 * formula down to
+	 *
+	 *  (34 * (size + 24)) / (size + 640) = ITR
+	 *
+	 * We first do some math on the packet size and then finally bitshift
+	 * by 8 after rounding up. We also have to account for PCIe link speed
+	 * difference as ITR scales based on this.
+	 */
+	if (avg_wire_size <= 360) {
+		/* Start at 250K ints/sec and gradually drop to 77K ints/sec */
+		avg_wire_size *= 8;
+		avg_wire_size += 376;
+	} else if (avg_wire_size <= 1152) {
+		/* 77K ints/sec to 45K ints/sec */
+		avg_wire_size *= 3;
+		avg_wire_size += 2176;
+	} else if (avg_wire_size <= 1920) {
+		/* 45K ints/sec to 38K ints/sec */
+		avg_wire_size += 4480;
+	} else {
+		/* plateau at a limit of 38K ints/sec */
+		avg_wire_size = 6656;
+	}
 
-	/* Don't starve jumbo frames */
-	if (avg_wire_size > 3000)
-		avg_wire_size = 3000;
-
-	/* Give a little boost to mid-size frames */
-	if ((avg_wire_size > 300) && (avg_wire_size < 1200))
-		avg_wire_size /= 3;
-	else
-		avg_wire_size /= 2;
+	/* Perform final bitshift for division after rounding up to ensure
+	 * that the calculation will never get below a 1. The bit shift
+	 * accounts for changes in the ITR due to PCIe link speed.
+	 */
+	itr_round = ACCESS_ONCE(ring_container->itr_scale) + 8;
+	avg_wire_size += (1 << itr_round) - 1;
+	avg_wire_size >>= itr_round;
 
 	/* write back value and retain adaptive flag */
 	ring_container->itr = avg_wire_size | FM10K_ITR_ADAPTIVE;
@@ -1428,11 +1452,15 @@ static int fm10k_poll(struct napi_struct
 	fm10k_for_each_ring(ring, q_vector->tx)
 		clean_complete &= fm10k_clean_tx_irq(q_vector, ring);
 
+	/* Handle case where we are called by netpoll with a budget of 0 */
+	if (budget <= 0)
+		return budget;
+
 	/* attempt to distribute budget to each queue fairly, but don't
 	 * allow the budget to go below 1 because we'll exit polling
 	 */
 	if (q_vector->rx.count > 1)
-		per_ring_budget = max(budget/q_vector->rx.count, 1);
+		per_ring_budget = max(budget / q_vector->rx.count, 1);
 	else
 		per_ring_budget = budget;
 
@@ -1600,6 +1628,7 @@ static int fm10k_alloc_q_vector(struct f
 	q_vector->tx.ring = ring;
 	q_vector->tx.work_limit = FM10K_DEFAULT_TX_WORK;
 	q_vector->tx.itr = interface->tx_itr;
+	q_vector->tx.itr_scale = interface->hw.mac.itr_scale;
 	q_vector->tx.count = txr_count;
 
 	while (txr_count) {
@@ -1628,6 +1657,7 @@ static int fm10k_alloc_q_vector(struct f
 	/* save Rx ring container info */
 	q_vector->rx.ring = ring;
 	q_vector->rx.itr = interface->rx_itr;
+	q_vector->rx.itr_scale = interface->hw.mac.itr_scale;
 	q_vector->rx.count = rxr_count;
 
 	while (rxr_count) {
@@ -1907,8 +1937,10 @@ static void fm10k_init_reta(struct fm10k
 	u16 i, rss_i = interface->ring_feature[RING_F_RSS].indices;
 	u32 reta, base;
 
-	/* If the netdev is initialized we have to maintain table if possible */
-	if (interface->netdev->reg_state != NETREG_UNINITIALIZED) {
+	/* If the Rx flow indirection table has been configured manually, we
+	 * need to maintain it when possible.
+	 */
+	if (netif_is_rxfh_configured(interface->netdev)) {
 		for (i = FM10K_RETA_SIZE; i--;) {
 			reta = interface->reta[i];
 			if ((((reta << 24) >> 24) < rss_i) &&
@@ -1916,6 +1948,10 @@ static void fm10k_init_reta(struct fm10k
 			    (((reta <<  8) >> 24) < rss_i) &&
 			    (((reta)       >> 24) < rss_i))
 				continue;
+
+			/* this should never happen */
+			dev_err(&interface->pdev->dev,
+				"RSS indirection table assigned flows out of queue bounds. Reconfiguring.\n");
 			goto repopulate_reta;
 		}
 
@@ -1966,8 +2002,10 @@ int fm10k_init_queueing_scheme(struct fm
 
 	/* Allocate memory for queues */
 	err = fm10k_alloc_q_vectors(interface);
-	if (err)
+	if (err) {
+		fm10k_reset_msix_capability(interface);
 		return err;
+	}
 
 	/* Map rings to devices, and map devices to physical queues */
 	fm10k_assign_rings(interface);
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/intel/fm10k/fm10k_mbx.c
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/intel/fm10k/fm10k_mbx.c
@@ -57,7 +57,7 @@ static u16 fm10k_fifo_unused(struct fm10
 }
 
 /**
- *  fm10k_fifo_empty - Test to verify if fifo is empty
+ *  fm10k_fifo_empty - Test to verify if FIFO is empty
  *  @fifo: pointer to FIFO
  *
  *  This function returns true if the FIFO is empty, else false
@@ -72,7 +72,7 @@ static bool fm10k_fifo_empty(struct fm10
  *  @fifo: pointer to FIFO
  *  @offset: offset to add to head
  *
- *  This function returns the indices into the fifo based on head + offset
+ *  This function returns the indices into the FIFO based on head + offset
  **/
 static u16 fm10k_fifo_head_offset(struct fm10k_mbx_fifo *fifo, u16 offset)
 {
@@ -84,7 +84,7 @@ static u16 fm10k_fifo_head_offset(struct
  *  @fifo: pointer to FIFO
  *  @offset: offset to add to tail
  *
- *  This function returns the indices into the fifo based on tail + offset
+ *  This function returns the indices into the FIFO based on tail + offset
  **/
 static u16 fm10k_fifo_tail_offset(struct fm10k_mbx_fifo *fifo, u16 offset)
 {
@@ -160,7 +160,7 @@ static u16 fm10k_mbx_index_len(struct fm
 /**
  *  fm10k_mbx_tail_add - Determine new tail value with added offset
  *  @mbx: pointer to mailbox
- *  @offset: length to add to head offset
+ *  @offset: length to add to tail offset
  *
  *  This function takes the local tail index and recomputes it for
  *  a given length added as an offset.
@@ -176,7 +176,7 @@ static u16 fm10k_mbx_tail_add(struct fm1
 /**
  *  fm10k_mbx_tail_sub - Determine new tail value with subtracted offset
  *  @mbx: pointer to mailbox
- *  @offset: length to add to head offset
+ *  @offset: length to add to tail offset
  *
  *  This function takes the local tail index and recomputes it for
  *  a given length added as an offset.
@@ -240,7 +240,7 @@ static u16 fm10k_mbx_pushed_tail_len(str
 }
 
 /**
- *  fm10k_fifo_write_copy - pulls data off of msg and places it in fifo
+ *  fm10k_fifo_write_copy - pulls data off of msg and places it in FIFO
  *  @fifo: pointer to FIFO
  *  @msg: message array to populate
  *  @tail_offset: additional offset to add to tail pointer
@@ -336,6 +336,7 @@ static u16 fm10k_mbx_validate_msg_size(s
 
 /**
  *  fm10k_mbx_write_copy - pulls data off of Tx FIFO and places it in mbmem
+ *  @hw: pointer to hardware structure
  *  @mbx: pointer to mailbox
  *
  *  This function will take a section of the Tx FIFO and copy it into the
@@ -375,6 +376,8 @@ static void fm10k_mbx_write_copy(struct
 			if (!tail)
 				tail++;
 
+			mbx->tx_mbmem_pulled++;
+
 			/* write message to hardware FIFO */
 			fm10k_write_reg(hw, mbmem + tail++, *(head++));
 		} while (--len && --end);
@@ -459,6 +462,8 @@ static void fm10k_mbx_read_copy(struct f
 			if (!head)
 				head++;
 
+			mbx->rx_mbmem_pushed++;
+
 			/* read message from hardware FIFO */
 			*(tail++) = fm10k_read_reg(hw, mbmem + head++);
 		} while (--len && --end);
@@ -707,7 +712,7 @@ static bool fm10k_mbx_tx_complete(struct
  *  @hw: pointer to hardware structure
  *  @mbx: pointer to mailbox
  *
- *  This function dequeues messages and hands them off to the tlv parser.
+ *  This function dequeues messages and hands them off to the TLV parser.
  *  It will return the number of messages processed when called.
  **/
 static u16 fm10k_mbx_dequeue_rx(struct fm10k_hw *hw,
@@ -899,7 +904,7 @@ static void fm10k_mbx_create_disconnect_
 }
 
 /**
- *  fm10k_mbx_create_fake_disconnect_hdr - Generate a false disconnect mailbox header
+ *  fm10k_mbx_create_fake_disconnect_hdr - Generate a false disconnect mbox hdr
  *  @mbx: pointer to mailbox
  *
  *  This function creates a fake disconnect header for loading into remote
@@ -920,7 +925,7 @@ static void fm10k_mbx_create_fake_discon
 }
 
 /**
- *  fm10k_mbx_create_error_msg - Generate a error message
+ *  fm10k_mbx_create_error_msg - Generate an error message
  *  @mbx: pointer to mailbox
  *  @err: local error encountered
  *
@@ -953,7 +958,6 @@ static void fm10k_mbx_create_error_msg(s
 /**
  *  fm10k_mbx_validate_msg_hdr - Validate common fields in the message header
  *  @mbx: pointer to mailbox
- *  @msg: message array to read
  *
  *  This function will parse up the fields in the mailbox header and return
  *  an error if the header contains any of a number of invalid configurations
@@ -1017,11 +1021,12 @@ static s32 fm10k_mbx_validate_msg_hdr(st
 
 /**
  *  fm10k_mbx_create_reply - Generate reply based on state and remote head
+ *  @hw: pointer to hardware structure
  *  @mbx: pointer to mailbox
  *  @head: acknowledgement number
  *
  *  This function will generate an outgoing message based on the current
- *  mailbox state and the remote fifo head.  It will return the length
+ *  mailbox state and the remote FIFO head.  It will return the length
  *  of the outgoing message excluding header on success, and a negative value
  *  on error.
  **/
@@ -1147,8 +1152,8 @@ static void fm10k_mbx_connect_reset(stru
 
 /**
  *  fm10k_mbx_process_connect - Process connect header
+ *  @hw: pointer to hardware structure
  *  @mbx: pointer to mailbox
- *  @msg: message array to process
  *
  *  This function will read an incoming connect header and reply with the
  *  appropriate message.  It will return a value indicating the number of
@@ -1194,6 +1199,7 @@ static s32 fm10k_mbx_process_connect(str
 
 /**
  *  fm10k_mbx_process_data - Process data header
+ *  @hw: pointer to hardware structure
  *  @mbx: pointer to mailbox
  *
  *  This function will read an incoming data header and reply with the
@@ -1235,6 +1241,7 @@ static s32 fm10k_mbx_process_data(struct
 
 /**
  *  fm10k_mbx_process_disconnect - Process disconnect header
+ *  @hw: pointer to hardware structure
  *  @mbx: pointer to mailbox
  *
  *  This function will read an incoming disconnect header and reply with the
@@ -1287,6 +1294,7 @@ static s32 fm10k_mbx_process_disconnect(
 
 /**
  *  fm10k_mbx_process_error - Process error header
+ *  @hw: pointer to hardware structure
  *  @mbx: pointer to mailbox
  *
  *  This function will read an incoming error header and reply with the
@@ -1556,7 +1564,7 @@ static s32 fm10k_mbx_register_handlers(s
  *  @id: ID reference for PF as it supports up to 64 PF/VF mailboxes
  *
  *  This function initializes the mailbox for use.  It will split the
- *  buffer provided an use that th populate both the Tx and Rx FIFO by
+ *  buffer provided and use that to populate both the Tx and Rx FIFO by
  *  evenly splitting it.  In order to allow for easy masking of head/tail
  *  the value reported in size must be a power of 2 and is reported in
  *  DWORDs, not bytes.  Any invalid values will cause the mailbox to return
@@ -1633,7 +1641,7 @@ s32 fm10k_pfvf_mbx_init(struct fm10k_hw
  *  fm10k_sm_mbx_create_data_hdr - Generate a mailbox header for local FIFO
  *  @mbx: pointer to mailbox
  *
- *  This function returns a connection mailbox header
+ *  This function returns a data mailbox header
  **/
 static void fm10k_sm_mbx_create_data_hdr(struct fm10k_mbx_info *mbx)
 {
@@ -1726,8 +1734,6 @@ static s32 fm10k_sm_mbx_connect(struct f
 	fm10k_sm_mbx_create_connect_hdr(mbx, 0);
 	fm10k_mbx_write(hw, mbx);
 
-	/* enable interrupt and notify other party of new message */
-
 	return 0;
 }
 
@@ -1771,7 +1777,7 @@ static void fm10k_sm_mbx_disconnect(stru
 }
 
 /**
- *  fm10k_mbx_validate_fifo_hdr - Validate fields in the remote FIFO header
+ *  fm10k_sm_mbx_validate_fifo_hdr - Validate fields in the remote FIFO header
  *  @mbx: pointer to mailbox
  *
  *  This function will parse up the fields in the mailbox header and return
@@ -1849,7 +1855,7 @@ static void fm10k_sm_mbx_process_error(s
 }
 
 /**
- *  fm10k_sm_mbx_create_error_message - Process an error in FIFO hdr
+ *  fm10k_sm_mbx_create_error_msg - Process an error in FIFO header
  *  @mbx: pointer to mailbox
  *  @err: local error encountered
  *
@@ -1879,6 +1885,7 @@ static void fm10k_sm_mbx_create_error_ms
  *  fm10k_sm_mbx_receive - Take message from Rx mailbox FIFO and put it in Rx
  *  @hw: pointer to hardware structure
  *  @mbx: pointer to mailbox
+ *  @tail: tail index of message
  *
  *  This function will dequeue one message from the Rx switch manager mailbox
  *  FIFO and place it in the Rx mailbox FIFO for processing by software.
@@ -1918,6 +1925,7 @@ static s32 fm10k_sm_mbx_receive(struct f
  *  fm10k_sm_mbx_transmit - Take message from Tx and put it in Tx mailbox FIFO
  *  @hw: pointer to hardware structure
  *  @mbx: pointer to mailbox
+ *  @head: head index of message
  *
  *  This function will dequeue one message from the Tx mailbox FIFO and place
  *  it in the Tx switch manager mailbox FIFO for processing by hardware.
@@ -1957,11 +1965,12 @@ static void fm10k_sm_mbx_transmit(struct
 
 /**
  *  fm10k_sm_mbx_create_reply - Generate reply based on state and remote head
+ *  @hw: pointer to hardware structure
  *  @mbx: pointer to mailbox
  *  @head: acknowledgement number
  *
  *  This function will generate an outgoing message based on the current
- *  mailbox state and the remote fifo head.  It will return the length
+ *  mailbox state and the remote FIFO head.  It will return the length
  *  of the outgoing message excluding header on success, and a negative value
  *  on error.
  **/
@@ -2073,7 +2082,7 @@ send_reply:
 }
 
 /**
- *  fm10k_sm_mbx_process - Process mailbox switch mailbox interrupt
+ *  fm10k_sm_mbx_process - Process switch manager mailbox interrupt
  *  @hw: pointer to hardware structure
  *  @mbx: pointer to mailbox
  *
@@ -2129,13 +2138,19 @@ fifo_err:
  *  @mbx: pointer to mailbox
  *  @msg_data: handlers for mailbox events
  *
- *  This function for now is used to stub out the PF/SM mailbox
+ *  This function initializes the PF/SM mailbox for use.  It will split the
+ *  buffer provided and use that to populate both the Tx and Rx FIFO by
+ *  evenly splitting it.  In order to allow for easy masking of head/tail
+ *  the value reported in size must be a power of 2 and is reported in
+ *  DWORDs, not bytes.  Any invalid values will cause the mailbox to return
+ *  error.
  **/
 s32 fm10k_sm_mbx_init(struct fm10k_hw *hw, struct fm10k_mbx_info *mbx,
 		      const struct fm10k_msg_data *msg_data)
 {
 	mbx->mbx_reg = FM10K_GMBX;
 	mbx->mbmem_reg = FM10K_MBMEM_PF(0);
+
 	/* start out in closed state */
 	mbx->state = FM10K_STATE_CLOSED;
 
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/intel/fm10k/fm10k_mbx.h
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/intel/fm10k/fm10k_mbx.h
@@ -1,5 +1,5 @@
 /* Intel Ethernet Switch Host Interface Driver
- * Copyright(c) 2013 - 2014 Intel Corporation.
+ * Copyright(c) 2013 - 2015 Intel Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms and conditions of the GNU General Public License,
@@ -128,11 +128,11 @@ enum fm10k_mbx_state {
  *		The maximum message size is provided during connect to avoid
  *		jamming the mailbox with messages that do not fit.
  * Err_no: Error number - Applies only to error headers
- *		The error number provides a indication of the type of error
+ *		The error number provides an indication of the type of error
  *		experienced.
  */
 
-/* macros for retriving and setting header values */
+/* macros for retrieving and setting header values */
 #define FM10K_MSG_HDR_MASK(name) \
 	((0x1u << FM10K_MSG_##name##_SIZE) - 1)
 #define FM10K_MSG_HDR_FIELD_SET(value, name) \
@@ -291,8 +291,10 @@ struct fm10k_mbx_info {
 	u64 tx_dropped;
 	u64 tx_messages;
 	u64 tx_dwords;
+	u64 tx_mbmem_pulled;
 	u64 rx_messages;
 	u64 rx_dwords;
+	u64 rx_mbmem_pushed;
 	u64 rx_parse_err;
 
 	/* Buffer to store messages */
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/intel/fm10k/fm10k_netdev.c
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/intel/fm10k/fm10k_netdev.c
@@ -20,7 +20,7 @@
 
 #include "fm10k.h"
 #include <linux/vmalloc.h>
-#if IS_ENABLED(CONFIG_FM10K_VXLAN)
+#ifdef CONFIG_FM10K_VXLAN
 #include <net/vxlan.h>
 #endif /* CONFIG_FM10K_VXLAN */
 
@@ -556,11 +556,11 @@ int fm10k_open(struct net_device *netdev
 	if (err)
 		goto err_set_queues;
 
-#if IS_ENABLED(CONFIG_FM10K_VXLAN)
+#ifdef CONFIG_FM10K_VXLAN
 	/* update VXLAN port configuration */
 	vxlan_get_rx_port(netdev);
-
 #endif
+
 	fm10k_up(interface);
 
 	return 0;
@@ -608,7 +608,7 @@ static netdev_tx_t fm10k_xmit_frame(stru
 	unsigned int r_idx = skb->queue_mapping;
 	int err;
 
-	if ((skb->protocol ==  htons(ETH_P_8021Q)) &&
+	if ((skb->protocol == htons(ETH_P_8021Q)) &&
 	    !skb_vlan_tag_present(skb)) {
 		/* FM10K only supports hardware tagging, any tags in frame
 		 * are considered 2nd level or "outer" tags
@@ -632,7 +632,7 @@ static netdev_tx_t fm10k_xmit_frame(stru
 			return NETDEV_TX_OK;
 		}
 
-		/* locate vlan header */
+		/* locate VLAN header */
 		vhdr = (struct vlan_hdr *)(skb->data + ETH_HLEN);
 
 		/* pull the 2 key pieces of data out of it */
@@ -705,7 +705,7 @@ static void fm10k_tx_timeout(struct net_
 	} else {
 		netif_info(interface, drv, netdev,
 			   "Fake Tx hang detected with timeout of %d seconds\n",
-			   netdev->watchdog_timeo/HZ);
+			   netdev->watchdog_timeo / HZ);
 
 		/* fake Tx hang - increase the kernel timeout */
 		if (netdev->watchdog_timeo < TX_TIMEO_LIMIT)
@@ -778,7 +778,7 @@ static int fm10k_update_vid(struct net_d
 	if (!set)
 		clear_bit(vid, interface->active_vlans);
 
-	/* disable the default VID on ring if we have an active VLAN */
+	/* disable the default VLAN ID on ring if we have an active VLAN */
 	for (i = 0; i < interface->num_rx_queues; i++) {
 		struct fm10k_ring *rx_ring = interface->rx_ring[i];
 		u16 rx_vid = rx_ring->vid & (VLAN_N_VID - 1);
@@ -789,7 +789,9 @@ static int fm10k_update_vid(struct net_d
 			rx_ring->vid &= ~FM10K_VLAN_CLEAR;
 	}
 
-	/* Do not remove default VID related entries from VLAN and MAC tables */
+	/* Do not remove default VLAN ID related entries from VLAN and MAC
+	 * tables
+	 */
 	if (!set && vid == hw->mac.default_vid)
 		return 0;
 
@@ -814,7 +816,7 @@ static int fm10k_update_vid(struct net_d
 	if (err)
 		goto err_out;
 
-	/* set vid prior to syncing/unsyncing the VLAN */
+	/* set VLAN ID prior to syncing/unsyncing the VLAN */
 	interface->vid = vid + (set ? VLAN_N_VID : 0);
 
 	/* Update the unicast and multicast address list to add/drop VLAN */
@@ -1151,6 +1153,7 @@ static struct rtnl_link_stats64 *fm10k_g
 int fm10k_setup_tc(struct net_device *dev, u8 tc)
 {
 	struct fm10k_intfc *interface = netdev_priv(dev);
+	int err;
 
 	/* Currently only the PF supports priority classes */
 	if (tc && (interface->hw.mac.type != fm10k_mac_pf))
@@ -1175,17 +1178,39 @@ int fm10k_setup_tc(struct net_device *de
 	netdev_reset_tc(dev);
 	netdev_set_num_tc(dev, tc);
 
-	fm10k_init_queueing_scheme(interface);
+	err = fm10k_init_queueing_scheme(interface);
+	if (err)
+		goto err_queueing_scheme;
 
-	fm10k_mbx_request_irq(interface);
+	err = fm10k_mbx_request_irq(interface);
+	if (err)
+		goto err_mbx_irq;
 
-	if (netif_running(dev))
-		fm10k_open(dev);
+	err = netif_running(dev) ? fm10k_open(dev) : 0;
+	if (err)
+		goto err_open;
 
 	/* flag to indicate SWPRI has yet to be updated */
 	interface->flags |= FM10K_FLAG_SWPRI_CONFIG;
 
 	return 0;
+err_open:
+	fm10k_mbx_free_irq(interface);
+err_mbx_irq:
+	fm10k_clear_queueing_scheme(interface);
+err_queueing_scheme:
+	netif_device_detach(dev);
+
+	return err;
+}
+
+static int __fm10k_setup_tc(struct net_device *dev, u32 handle, __be16 proto,
+			    struct tc_to_netdev *tc)
+{
+	if (handle != TC_H_ROOT || tc->type != TC_SETUP_MQPRIO)
+		return -EINVAL;
+
+	return fm10k_setup_tc(dev, tc->tc);
 }
 
 static int fm10k_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
@@ -1370,7 +1395,7 @@ static const struct net_device_ops fm10k
 	.ndo_vlan_rx_kill_vid	= fm10k_vlan_rx_kill_vid,
 	.ndo_set_rx_mode	= fm10k_set_rx_mode,
 	.ndo_get_stats64	= fm10k_get_stats64,
-	.ndo_setup_tc		= fm10k_setup_tc,
+	.ndo_setup_tc		= __fm10k_setup_tc,
 	.ndo_set_vf_mac		= fm10k_ndo_set_vf_mac,
 	.ndo_set_vf_vlan	= fm10k_ndo_set_vf_vlan,
 	.ndo_set_vf_rate	= fm10k_ndo_set_vf_bw,
@@ -1388,8 +1413,9 @@ static const struct net_device_ops fm10k
 
 #define DEFAULT_DEBUG_LEVEL_SHIFT 3
 
-struct net_device *fm10k_alloc_netdev(void)
+struct net_device *fm10k_alloc_netdev(const struct fm10k_info *info)
 {
+	netdev_features_t hw_features;
 	struct fm10k_intfc *interface;
 	struct net_device *dev;
 
@@ -1412,27 +1438,31 @@ struct net_device *fm10k_alloc_netdev(vo
 			 NETIF_F_TSO |
 			 NETIF_F_TSO6 |
 			 NETIF_F_TSO_ECN |
-			 NETIF_F_GSO_UDP_TUNNEL |
 			 NETIF_F_RXHASH |
 			 NETIF_F_RXCSUM;
 
+	/* Only the PF can support VXLAN and NVGRE tunnel offloads */
+	if (info->mac == fm10k_mac_pf) {
+		dev->hw_enc_features = NETIF_F_IP_CSUM |
+				       NETIF_F_TSO |
+				       NETIF_F_TSO6 |
+				       NETIF_F_TSO_ECN |
+				       NETIF_F_GSO_UDP_TUNNEL |
+				       NETIF_F_IPV6_CSUM |
+				       NETIF_F_SG;
+
+		dev->features |= NETIF_F_GSO_UDP_TUNNEL;
+	}
+
 	/* all features defined to this point should be changeable */
-	dev->hw_features |= dev->features;
+	hw_features = dev->features;
 
 	/* allow user to enable L2 forwarding acceleration */
-	dev->hw_features |= NETIF_F_HW_L2FW_DOFFLOAD;
+	hw_features |= NETIF_F_HW_L2FW_DOFFLOAD;
 
 	/* configure VLAN features */
 	dev->vlan_features |= dev->features;
 
-	/* configure tunnel offloads */
-	dev->hw_enc_features |= NETIF_F_IP_CSUM |
-				NETIF_F_TSO |
-				NETIF_F_TSO6 |
-				NETIF_F_TSO_ECN |
-				NETIF_F_GSO_UDP_TUNNEL |
-				NETIF_F_IPV6_CSUM;
-
 	/* we want to leave these both on as we cannot disable VLAN tag
 	 * insertion or stripping on the hardware since it is contained
 	 * in the FTAG and not in the frame itself.
@@ -1443,5 +1473,7 @@ struct net_device *fm10k_alloc_netdev(vo
 
 	dev->priv_flags |= IFF_UNICAST_FLT;
 
+	dev->hw_features |= hw_features;
+
 	return dev;
 }
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/intel/fm10k/fm10k_pci.c
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/intel/fm10k/fm10k_pci.c
@@ -159,16 +159,40 @@ static void fm10k_reinit(struct fm10k_in
 
 	fm10k_mbx_free_irq(interface);
 
+	/* free interrupts */
+	fm10k_clear_queueing_scheme(interface);
+
 	/* delay any future reset requests */
 	interface->last_reset = jiffies + (10 * HZ);
 
 	/* reset and initialize the hardware so it is in a known state */
-	err = hw->mac.ops.reset_hw(hw) ? : hw->mac.ops.init_hw(hw);
-	if (err)
+	err = hw->mac.ops.reset_hw(hw);
+	if (err) {
+		dev_err(&interface->pdev->dev, "reset_hw failed: %d\n", err);
+		goto reinit_err;
+	}
+
+	err = hw->mac.ops.init_hw(hw);
+	if (err) {
 		dev_err(&interface->pdev->dev, "init_hw failed: %d\n", err);
+		goto reinit_err;
+	}
+
+	err = fm10k_init_queueing_scheme(interface);
+	if (err) {
+		dev_err(&interface->pdev->dev,
+			"init_queueing_scheme failed: %d\n", err);
+		goto reinit_err;
+	}
 
 	/* reassociate interrupts */
-	fm10k_mbx_request_irq(interface);
+	err = fm10k_mbx_request_irq(interface);
+	if (err)
+		goto err_mbx_irq;
+
+	err = fm10k_hw_ready(interface);
+	if (err)
+		goto err_open;
 
 	/* update hardware address for VFs if perm_addr has changed */
 	if (hw->mac.type == fm10k_mac_vf) {
@@ -188,14 +212,27 @@ static void fm10k_reinit(struct fm10k_in
 	/* reset clock */
 	fm10k_ts_reset(interface);
 
-	if (netif_running(netdev))
-		fm10k_open(netdev);
+	err = netif_running(netdev) ? fm10k_open(netdev) : 0;
+	if (err)
+		goto err_open;
 
 	fm10k_iov_resume(interface->pdev);
 
 	rtnl_unlock();
 
 	clear_bit(__FM10K_RESETTING, &interface->state);
+
+	return;
+err_open:
+	fm10k_mbx_free_irq(interface);
+err_mbx_irq:
+	fm10k_clear_queueing_scheme(interface);
+reinit_err:
+	netif_device_detach(netdev);
+
+	rtnl_unlock();
+
+	clear_bit(__FM10K_RESETTING, &interface->state);
 }
 
 static void fm10k_reset_subtask(struct fm10k_intfc *interface)
@@ -563,7 +600,7 @@ static void fm10k_configure_tx_ring(stru
 	/* store tail pointer */
 	ring->tail = &interface->uc_addr[FM10K_TDT(reg_idx)];
 
-	/* reset ntu and ntc to place SW in sync with hardwdare */
+	/* reset ntu and ntc to place SW in sync with hardware */
 	ring->next_to_clean = 0;
 	ring->next_to_use = 0;
 
@@ -579,6 +616,13 @@ static void fm10k_configure_tx_ring(stru
 	fm10k_write_reg(hw, FM10K_PFVTCTL(reg_idx),
 			FM10K_PFVTCTL_FTAG_DESC_ENABLE);
 
+	/* Initialize XPS */
+	if (!test_and_set_bit(__FM10K_TX_XPS_INIT_DONE, &ring->state) &&
+	    ring->q_vector)
+		netif_set_xps_queue(ring->netdev,
+				    &ring->q_vector->affinity_mask,
+				    ring->queue_index);
+
 	/* enable queue */
 	fm10k_write_reg(hw, FM10K_TXDCTL(reg_idx), txdctl);
 }
@@ -669,7 +713,7 @@ static void fm10k_configure_rx_ring(stru
 	/* store tail pointer */
 	ring->tail = &interface->uc_addr[FM10K_RDT(reg_idx)];
 
-	/* reset ntu and ntc to place SW in sync with hardwdare */
+	/* reset ntu and ntc to place SW in sync with hardware */
 	ring->next_to_clean = 0;
 	ring->next_to_use = 0;
 	ring->next_to_alloc = 0;
@@ -694,7 +738,7 @@ static void fm10k_configure_rx_ring(stru
 	/* assign default VLAN to queue */
 	ring->vid = hw->mac.default_vid;
 
-	/* if we have an active VLAN, disable default VID */
+	/* if we have an active VLAN, disable default VLAN ID */
 	if (test_bit(hw->mac.default_vid, interface->active_vlans))
 		ring->vid |= FM10K_VLAN_CLEAR;
 
@@ -846,7 +890,7 @@ static irqreturn_t fm10k_msix_clean_ring
 	struct fm10k_q_vector *q_vector = data;
 
 	if (q_vector->rx.count || q_vector->tx.count)
-		napi_schedule(&q_vector->napi);
+		napi_schedule_irqoff(&q_vector->napi);
 
 	return IRQ_HANDLED;
 }
@@ -859,7 +903,8 @@ static irqreturn_t fm10k_msix_mbx_vf(int
 
 	/* re-enable mailbox interrupt and indicate 20us delay */
 	fm10k_write_reg(hw, FM10K_VFITR(FM10K_MBX_VECTOR),
-			FM10K_ITR_ENABLE | FM10K_MBX_INT_DELAY);
+			FM10K_ITR_ENABLE | (FM10K_MBX_INT_DELAY >>
+					    hw->mac.itr_scale));
 
 	/* service upstream mailbox */
 	if (fm10k_mbx_trylock(interface)) {
@@ -867,7 +912,7 @@ static irqreturn_t fm10k_msix_mbx_vf(int
 		fm10k_mbx_unlock(interface);
 	}
 
-	hw->mac.get_host_state = 1;
+	hw->mac.get_host_state = true;
 	fm10k_service_event_schedule(interface);
 
 	return IRQ_HANDLED;
@@ -897,7 +942,7 @@ void fm10k_netpoll(struct net_device *ne
 #endif
 #define FM10K_ERR_MSG(type) case (type): error = #type; break
 static void fm10k_handle_fault(struct fm10k_intfc *interface, int type,
-			      struct fm10k_fault *fault)
+			       struct fm10k_fault *fault)
 {
 	struct pci_dev *pdev = interface->pdev;
 	struct fm10k_hw *hw = &interface->hw;
@@ -1083,14 +1128,15 @@ static irqreturn_t fm10k_msix_mbx_pf(int
 	}
 
 	/* we should validate host state after interrupt event */
-	hw->mac.get_host_state = 1;
+	hw->mac.get_host_state = true;
 
 	/* validate host state, and handle VF mailboxes in the service task */
 	fm10k_service_event_schedule(interface);
 
 	/* re-enable mailbox interrupt and indicate 20us delay */
 	fm10k_write_reg(hw, FM10K_ITR(FM10K_MBX_VECTOR),
-			FM10K_ITR_ENABLE | FM10K_MBX_INT_DELAY);
+			FM10K_ITR_ENABLE | (FM10K_MBX_INT_DELAY >>
+					    hw->mac.itr_scale));
 
 	return IRQ_HANDLED;
 }
@@ -1101,6 +1147,10 @@ void fm10k_mbx_free_irq(struct fm10k_int
 	struct fm10k_hw *hw = &interface->hw;
 	int itr_reg;
 
+	/* no mailbox IRQ to free if MSI-X is not enabled */
+	if (!interface->msix_entries)
+		return;
+
 	/* disconnect the mailbox */
 	hw->mbx.ops.disconnect(hw, &hw->mbx);
 
@@ -1141,7 +1191,7 @@ static s32 fm10k_mbx_mac_addr(struct fm1
 
 	/* MAC was changed so we need reset */
 	if (is_valid_ether_addr(hw->mac.perm_addr) &&
-	    memcmp(hw->mac.perm_addr, hw->mac.addr, ETH_ALEN))
+	    !ether_addr_equal(hw->mac.perm_addr, hw->mac.addr))
 		interface->flags |= FM10K_FLAG_RESET_REQUESTED;
 
 	/* VLAN override was changed, or default VLAN changed */
@@ -1269,7 +1319,7 @@ static s32 fm10k_update_pvid(struct fm10
 	if (!fm10k_glort_valid_pf(hw, glort))
 		return FM10K_ERR_PARAM;
 
-	/* verify VID is valid */
+	/* verify VLAN ID is valid */
 	if (pvid >= FM10K_VLAN_TABLE_VID_MAX)
 		return FM10K_ERR_PARAM;
 
@@ -1388,14 +1438,14 @@ static int fm10k_mbx_request_irq_pf(stru
 	}
 
 	/* Enable interrupts w/ no moderation for "other" interrupts */
-	fm10k_write_reg(hw, FM10K_INT_MAP(fm10k_int_PCIeFault), other_itr);
-	fm10k_write_reg(hw, FM10K_INT_MAP(fm10k_int_SwitchUpDown), other_itr);
-	fm10k_write_reg(hw, FM10K_INT_MAP(fm10k_int_SRAM), other_itr);
-	fm10k_write_reg(hw, FM10K_INT_MAP(fm10k_int_MaxHoldTime), other_itr);
-	fm10k_write_reg(hw, FM10K_INT_MAP(fm10k_int_VFLR), other_itr);
+	fm10k_write_reg(hw, FM10K_INT_MAP(fm10k_int_pcie_fault), other_itr);
+	fm10k_write_reg(hw, FM10K_INT_MAP(fm10k_int_switch_up_down), other_itr);
+	fm10k_write_reg(hw, FM10K_INT_MAP(fm10k_int_sram), other_itr);
+	fm10k_write_reg(hw, FM10K_INT_MAP(fm10k_int_max_hold_time), other_itr);
+	fm10k_write_reg(hw, FM10K_INT_MAP(fm10k_int_vflr), other_itr);
 
 	/* Enable interrupts w/ moderation for mailbox */
-	fm10k_write_reg(hw, FM10K_INT_MAP(fm10k_int_Mailbox), mbx_itr);
+	fm10k_write_reg(hw, FM10K_INT_MAP(fm10k_int_mailbox), mbx_itr);
 
 	/* Enable individual interrupt causes */
 	fm10k_write_reg(hw, FM10K_EIMR, FM10K_EIMR_ENABLE(PCA_FAULT) |
@@ -1423,10 +1473,15 @@ int fm10k_mbx_request_irq(struct fm10k_i
 		err = fm10k_mbx_request_irq_pf(interface);
 	else
 		err = fm10k_mbx_request_irq_vf(interface);
+	if (err)
+		return err;
 
 	/* connect mailbox */
-	if (!err)
-		err = hw->mbx.ops.connect(hw, &hw->mbx);
+	err = hw->mbx.ops.connect(hw, &hw->mbx);
+
+	/* if the mailbox failed to connect, then free IRQ */
+	if (err)
+		fm10k_mbx_free_irq(interface);
 
 	return err;
 }
@@ -1455,8 +1510,10 @@ void fm10k_qv_free_irq(struct fm10k_intf
 		if (!q_vector->tx.count && !q_vector->rx.count)
 			continue;
 
-		/* disable interrupts */
+		/* clear the affinity_mask in the IRQ descriptor */
+		irq_set_affinity_hint(entry->vector, NULL);
 
+		/* disable interrupts */
 		writel(FM10K_ITR_MASK_SET, q_vector->itr);
 
 		free_irq(entry->vector, q_vector);
@@ -1514,6 +1571,9 @@ int fm10k_qv_request_irq(struct fm10k_in
 			goto err_out;
 		}
 
+		/* assign the mask for this irq */
+		irq_set_affinity_hint(entry->vector, &q_vector->affinity_mask);
+
 		/* Enable q_vector */
 		writel(FM10K_ITR_ENABLE, q_vector->itr);
 
@@ -1534,8 +1594,10 @@ err_out:
 		if (!q_vector->tx.count && !q_vector->rx.count)
 			continue;
 
-		/* disable interrupts */
+		/* clear the affinity_mask in the IRQ descriptor */
+		irq_set_affinity_hint(entry->vector, NULL);
 
+		/* disable interrupts */
 		writel(FM10K_ITR_MASK_SET, q_vector->itr);
 
 		free_irq(entry->vector, q_vector);
@@ -1573,7 +1635,7 @@ void fm10k_up(struct fm10k_intfc *interf
 	netif_tx_start_all_queues(interface->netdev);
 
 	/* kick off the service timer now */
-	hw->mac.get_host_state = 1;
+	hw->mac.get_host_state = true;
 	mod_timer(&interface->service_timer, jiffies);
 }
 
@@ -1684,7 +1746,13 @@ static int fm10k_sw_init(struct fm10k_in
 	interface->last_reset = jiffies + (10 * HZ);
 
 	/* reset and initialize the hardware so it is in a known state */
-	err = hw->mac.ops.reset_hw(hw) ? : hw->mac.ops.init_hw(hw);
+	err = hw->mac.ops.reset_hw(hw);
+	if (err) {
+		dev_err(&pdev->dev, "reset_hw failed: %d\n", err);
+		return err;
+	}
+
+	err = hw->mac.ops.init_hw(hw);
 	if (err) {
 		dev_err(&pdev->dev, "init_hw failed: %d\n", err);
 		return err;
@@ -1722,13 +1790,6 @@ static int fm10k_sw_init(struct fm10k_in
 					     pci_resource_len(pdev, 4));
 	hw->sw_addr = interface->sw_addr;
 
-	/* Only the PF can support VXLAN and NVGRE offloads */
-	if (hw->mac.type != fm10k_mac_pf) {
-		netdev->hw_enc_features = 0;
-		netdev->features &= ~NETIF_F_GSO_UDP_TUNNEL;
-		netdev->hw_features &= ~NETIF_F_GSO_UDP_TUNNEL;
-	}
-
 	/* initialize DCBNL interface */
 	fm10k_dcbnl_set_ops(netdev);
 
@@ -1749,8 +1810,8 @@ static int fm10k_sw_init(struct fm10k_in
 	interface->rx_ring_count = FM10K_DEFAULT_RXD;
 
 	/* set default interrupt moderation */
-	interface->tx_itr = FM10K_ITR_10K;
-	interface->rx_itr = FM10K_ITR_ADAPTIVE | FM10K_ITR_20K;
+	interface->tx_itr = FM10K_TX_ITR_DEFAULT;
+	interface->rx_itr = FM10K_ITR_ADAPTIVE | FM10K_RX_ITR_DEFAULT;
 
 	/* initialize vxlan_port list */
 	INIT_LIST_HEAD(&interface->vxlan_port);
@@ -1835,17 +1896,18 @@ static void fm10k_slot_warn(struct fm10k
 		return;
 	}
 
-	if (max_gts < expected_gts) {
-		dev_warn(&interface->pdev->dev,
-			 "This device requires %dGT/s of bandwidth for optimal performance.\n",
-			 expected_gts);
-		dev_warn(&interface->pdev->dev,
-			 "A %sslot with x%d lanes is suggested.\n",
-			 (hw->bus_caps.speed == fm10k_bus_speed_2500 ? "2.5GT/s " :
-			  hw->bus_caps.speed == fm10k_bus_speed_5000 ? "5.0GT/s " :
-			  hw->bus_caps.speed == fm10k_bus_speed_8000 ? "8.0GT/s " : ""),
-			 hw->bus_caps.width);
-	}
+	if (max_gts >= expected_gts)
+		return;
+
+	dev_warn(&interface->pdev->dev,
+		 "This device requires %dGT/s of bandwidth for optimal performance.\n",
+		 expected_gts);
+	dev_warn(&interface->pdev->dev,
+		 "A %sslot with x%d lanes is suggested.\n",
+		 (hw->bus_caps.speed == fm10k_bus_speed_2500 ? "2.5GT/s " :
+		  hw->bus_caps.speed == fm10k_bus_speed_5000 ? "5.0GT/s " :
+		  hw->bus_caps.speed == fm10k_bus_speed_8000 ? "8.0GT/s " : ""),
+		 hw->bus_caps.width);
 }
 
 /**
@@ -1859,8 +1921,7 @@ static void fm10k_slot_warn(struct fm10k
  * The OS initialization, configuring of the interface private structure,
  * and a hardware reset occur.
  **/
-static int fm10k_probe(struct pci_dev *pdev,
-		       const struct pci_device_id *ent)
+static int fm10k_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 {
 	struct net_device *netdev;
 	struct fm10k_intfc *interface;
@@ -1894,7 +1955,7 @@ static int fm10k_probe(struct pci_dev *p
 	pci_set_master(pdev);
 	pci_save_state(pdev);
 
-	netdev = fm10k_alloc_netdev();
+	netdev = fm10k_alloc_netdev(fm10k_info_tbl[ent->driver_data]);
 	if (!netdev) {
 		err = -ENOMEM;
 		goto err_alloc_netdev;
@@ -2071,8 +2132,10 @@ static int fm10k_resume(struct pci_dev *
 
 	/* reset hardware to known state */
 	err = hw->mac.ops.init_hw(&interface->hw);
-	if (err)
+	if (err) {
+		dev_err(&pdev->dev, "init_hw failed: %d\n", err);
 		return err;
+	}
 
 	/* reset statistics starting values */
 	hw->mac.ops.rebind_hw_stats(hw, &interface->stats);
@@ -2083,16 +2146,22 @@ static int fm10k_resume(struct pci_dev *
 	rtnl_lock();
 
 	err = fm10k_init_queueing_scheme(interface);
-	if (!err) {
-		fm10k_mbx_request_irq(interface);
-		if (netif_running(netdev))
-			err = fm10k_open(netdev);
-	}
+	if (err)
+		goto err_queueing_scheme;
 
-	rtnl_unlock();
+	err = fm10k_mbx_request_irq(interface);
+	if (err)
+		goto err_mbx_irq;
 
+	err = fm10k_hw_ready(interface);
 	if (err)
-		return err;
+		goto err_open;
+
+	err = netif_running(netdev) ? fm10k_open(netdev) : 0;
+	if (err)
+		goto err_open;
+
+	rtnl_unlock();
 
 	/* assume host is not ready, to prevent race with watchdog in case we
 	 * actually don't have connection to the switch
@@ -2110,6 +2179,14 @@ static int fm10k_resume(struct pci_dev *
 	netif_device_attach(netdev);
 
 	return 0;
+err_open:
+	fm10k_mbx_free_irq(interface);
+err_mbx_irq:
+	fm10k_clear_queueing_scheme(interface);
+err_queueing_scheme:
+	rtnl_unlock();
+
+	return err;
 }
 
 /**
@@ -2185,6 +2262,9 @@ static pci_ers_result_t fm10k_io_error_d
 	if (netif_running(netdev))
 		fm10k_close(netdev);
 
+	/* free interrupts */
+	fm10k_clear_queueing_scheme(interface);
+
 	fm10k_mbx_free_irq(interface);
 
 	pci_disable_device(pdev);
@@ -2248,11 +2328,22 @@ static void fm10k_io_resume(struct pci_d
 	int err = 0;
 
 	/* reset hardware to known state */
-	hw->mac.ops.init_hw(&interface->hw);
+	err = hw->mac.ops.init_hw(&interface->hw);
+	if (err) {
+		dev_err(&pdev->dev, "init_hw failed: %d\n", err);
+		return;
+	}
 
 	/* reset statistics starting values */
 	hw->mac.ops.rebind_hw_stats(hw, &interface->stats);
 
+	err = fm10k_init_queueing_scheme(interface);
+	if (err) {
+		dev_err(&interface->pdev->dev,
+			"init_queueing_scheme failed: %d\n", err);
+		return;
+	}
+
 	/* reassociate interrupts */
 	fm10k_mbx_request_irq(interface);
 
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/intel/fm10k/fm10k_pf.c
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/intel/fm10k/fm10k_pf.c
@@ -1,5 +1,5 @@
 /* Intel Ethernet Switch Host Interface Driver
- * Copyright(c) 2013 - 2014 Intel Corporation.
+ * Copyright(c) 2013 - 2015 Intel Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms and conditions of the GNU General Public License,
@@ -150,19 +150,26 @@ static s32 fm10k_init_hw_pf(struct fm10k
 				FM10K_TPH_RXCTRL_HDR_WROEN);
 	}
 
-	/* set max hold interval to align with 1.024 usec in all modes */
+	/* set max hold interval to align with 1.024 usec in all modes and
+	 * store ITR scale
+	 */
 	switch (hw->bus.speed) {
 	case fm10k_bus_speed_2500:
 		dma_ctrl = FM10K_DMA_CTRL_MAX_HOLD_1US_GEN1;
+		hw->mac.itr_scale = FM10K_TDLEN_ITR_SCALE_GEN1;
 		break;
 	case fm10k_bus_speed_5000:
 		dma_ctrl = FM10K_DMA_CTRL_MAX_HOLD_1US_GEN2;
+		hw->mac.itr_scale = FM10K_TDLEN_ITR_SCALE_GEN2;
 		break;
 	case fm10k_bus_speed_8000:
 		dma_ctrl = FM10K_DMA_CTRL_MAX_HOLD_1US_GEN3;
+		hw->mac.itr_scale = FM10K_TDLEN_ITR_SCALE_GEN3;
 		break;
 	default:
 		dma_ctrl = 0;
+		/* just in case, assume Gen3 ITR scale */
+		hw->mac.itr_scale = FM10K_TDLEN_ITR_SCALE_GEN3;
 		break;
 	}
 
@@ -259,7 +266,6 @@ static s32 fm10k_read_mac_addr_pf(struct
 {
 	u8 perm_addr[ETH_ALEN];
 	u32 serial_num;
-	int i;
 
 	serial_num = fm10k_read_reg(hw, FM10K_SM_AREA(1));
 
@@ -281,10 +287,8 @@ static s32 fm10k_read_mac_addr_pf(struct
 	perm_addr[4] = (u8)(serial_num >> 8);
 	perm_addr[5] = (u8)(serial_num);
 
-	for (i = 0; i < ETH_ALEN; i++) {
-		hw->mac.perm_addr[i] = perm_addr[i];
-		hw->mac.addr[i] = perm_addr[i];
-	}
+	ether_addr_copy(hw->mac.perm_addr, perm_addr);
+	ether_addr_copy(hw->mac.addr, perm_addr);
 
 	return 0;
 }
@@ -325,7 +329,7 @@ static s32 fm10k_update_xc_addr_pf(struc
 	/* clear set bit from VLAN ID */
 	vid &= ~FM10K_VLAN_CLEAR;
 
-	/* if glort or vlan are not valid return error */
+	/* if glort or VLAN are not valid return error */
 	if (!fm10k_glort_valid_pf(hw, glort) || vid >= FM10K_VLAN_TABLE_VID_MAX)
 		return FM10K_ERR_PARAM;
 
@@ -334,8 +338,8 @@ static s32 fm10k_update_xc_addr_pf(struc
 						 ((u32)mac[3] << 16) |
 						 ((u32)mac[4] << 8) |
 						 ((u32)mac[5]));
-	mac_update.mac_upper = cpu_to_le16(((u32)mac[0] << 8) |
-						 ((u32)mac[1]));
+	mac_update.mac_upper = cpu_to_le16(((u16)mac[0] << 8) |
+					   ((u16)mac[1]));
 	mac_update.vlan = cpu_to_le16(vid);
 	mac_update.glort = cpu_to_le16(glort);
 	mac_update.action = add ? 0 : 1;
@@ -410,6 +414,7 @@ static s32 fm10k_update_xcast_mode_pf(st
 
 	if (mode > FM10K_XCAST_MODE_NONE)
 		return FM10K_ERR_PARAM;
+
 	/* if glort is not valid return error */
 	if (!fm10k_glort_valid_pf(hw, glort))
 		return FM10K_ERR_PARAM;
@@ -903,6 +908,13 @@ static s32 fm10k_iov_assign_default_mac_
 	fm10k_write_reg(hw, FM10K_TDBAL(vf_q_idx), tdbal);
 	fm10k_write_reg(hw, FM10K_TDBAH(vf_q_idx), tdbah);
 
+	/* Provide the VF the ITR scale, using software-defined fields in TDLEN
+	 * to pass the information during VF initialization. See definition of
+	 * FM10K_TDLEN_ITR_SCALE_SHIFT for more details.
+	 */
+	fm10k_write_reg(hw, FM10K_TDLEN(vf_q_idx), hw->mac.itr_scale <<
+						   FM10K_TDLEN_ITR_SCALE_SHIFT);
+
 err_out:
 	/* configure Queue control register */
 	txqctl = ((u32)vf_vid << FM10K_TXQCTL_VID_SHIFT) &
@@ -910,7 +922,7 @@ err_out:
 	txqctl |= (vf_idx << FM10K_TXQCTL_TC_SHIFT) |
 		  FM10K_TXQCTL_VF | vf_idx;
 
-	/* assign VID */
+	/* assign VLAN ID */
 	for (i = 0; i < queues_per_pool; i++)
 		fm10k_write_reg(hw, FM10K_TXQCTL(vf_q_idx + i), txqctl);
 
@@ -1035,6 +1047,12 @@ static s32 fm10k_iov_reset_resources_pf(
 	for (i = queues_per_pool; i--;) {
 		fm10k_write_reg(hw, FM10K_TDBAL(vf_q_idx + i), tdbal);
 		fm10k_write_reg(hw, FM10K_TDBAH(vf_q_idx + i), tdbah);
+		/* See definition of FM10K_TDLEN_ITR_SCALE_SHIFT for an
+		 * explanation of how TDLEN is used.
+		 */
+		fm10k_write_reg(hw, FM10K_TDLEN(vf_q_idx + i),
+				hw->mac.itr_scale <<
+				FM10K_TDLEN_ITR_SCALE_SHIFT);
 		fm10k_write_reg(hw, FM10K_TQMAP(qmap_idx + i), vf_q_idx + i);
 		fm10k_write_reg(hw, FM10K_RQMAP(qmap_idx + i), vf_q_idx + i);
 	}
@@ -1155,14 +1173,14 @@ s32 fm10k_iov_msg_msix_pf(struct fm10k_h
 }
 
 /**
- * fm10k_iov_select_vid - Select correct default VID
+ * fm10k_iov_select_vid - Select correct default VLAN ID
  * @hw: Pointer to hardware structure
- * @vid: VID to correct
+ * @vid: VLAN ID to correct
  *
- * Will report an error if VID is out of range. For VID = 0, it will return
- * either the pf_vid or sw_vid depending on which one is set.
+ * Will report an error if the VLAN ID is out of range. For VID = 0, it will
+ * return either the pf_vid or sw_vid depending on which one is set.
  */
-static inline s32 fm10k_iov_select_vid(struct fm10k_vf_info *vf_info, u16 vid)
+static s32 fm10k_iov_select_vid(struct fm10k_vf_info *vf_info, u16 vid)
 {
 	if (!vid)
 		return vf_info->pf_vid ? vf_info->pf_vid : vf_info->sw_vid;
@@ -1212,11 +1230,11 @@ s32 fm10k_iov_msg_mac_vlan_pf(struct fm1
 		set = !(vid & FM10K_VLAN_CLEAR);
 		vid &= ~FM10K_VLAN_CLEAR;
 
-		err = fm10k_iov_select_vid(vf_info, vid);
+		err = fm10k_iov_select_vid(vf_info, (u16)vid);
 		if (err < 0)
 			return err;
-		else
-			vid = err;
+
+		vid = err;
 
 		/* update VSI info for VF in regards to VLAN table */
 		err = hw->mac.ops.update_vlan(hw, vid, vf_info->vsi, set);
@@ -1232,7 +1250,7 @@ s32 fm10k_iov_msg_mac_vlan_pf(struct fm1
 
 		/* block attempts to set MAC for a locked device */
 		if (is_valid_ether_addr(vf_info->mac) &&
-		    memcmp(mac, vf_info->mac, ETH_ALEN))
+		    !ether_addr_equal(mac, vf_info->mac))
 			return FM10K_ERR_PARAM;
 
 		set = !(vlan & FM10K_VLAN_CLEAR);
@@ -1241,8 +1259,8 @@ s32 fm10k_iov_msg_mac_vlan_pf(struct fm1
 		err = fm10k_iov_select_vid(vf_info, vlan);
 		if (err < 0)
 			return err;
-		else
-			vlan = err;
+
+		vlan = (u16)err;
 
 		/* notify switch of request for new unicast address */
 		err = hw->mac.ops.update_uc_addr(hw, vf_info->glort,
@@ -1267,8 +1285,8 @@ s32 fm10k_iov_msg_mac_vlan_pf(struct fm1
 		err = fm10k_iov_select_vid(vf_info, vlan);
 		if (err < 0)
 			return err;
-		else
-			vlan = err;
+
+		vlan = (u16)err;
 
 		/* notify switch of request for new multicast address */
 		err = hw->mac.ops.update_mc_addr(hw, vf_info->glort,
@@ -1396,14 +1414,6 @@ s32 fm10k_iov_msg_lport_state_pf(struct
 	return err;
 }
 
-const struct fm10k_msg_data fm10k_iov_msg_data_pf[] = {
-	FM10K_TLV_MSG_TEST_HANDLER(fm10k_tlv_msg_test),
-	FM10K_VF_MSG_MSIX_HANDLER(fm10k_iov_msg_msix_pf),
-	FM10K_VF_MSG_MAC_VLAN_HANDLER(fm10k_iov_msg_mac_vlan_pf),
-	FM10K_VF_MSG_LPORT_STATE_HANDLER(fm10k_iov_msg_lport_state_pf),
-	FM10K_TLV_MSG_ERROR_HANDLER(fm10k_tlv_msg_error),
-};
-
 /**
  *  fm10k_update_stats_hw_pf - Updates hardware related statistics of PF
  *  @hw: pointer to hardware structure
@@ -1431,9 +1441,10 @@ static void fm10k_update_hw_stats_pf(str
 		xec = fm10k_read_hw_stats_32b(hw, FM10K_STATS_XEC, &stats->xec);
 		vlan_drop = fm10k_read_hw_stats_32b(hw, FM10K_STATS_VLAN_DROP,
 						    &stats->vlan_drop);
-		loopback_drop = fm10k_read_hw_stats_32b(hw,
-							FM10K_STATS_LOOPBACK_DROP,
-							&stats->loopback_drop);
+		loopback_drop =
+			fm10k_read_hw_stats_32b(hw,
+						FM10K_STATS_LOOPBACK_DROP,
+						&stats->loopback_drop);
 		nodesc_drop = fm10k_read_hw_stats_32b(hw,
 						      FM10K_STATS_NODESC_DROP,
 						      &stats->nodesc_drop);
@@ -1678,8 +1689,8 @@ const struct fm10k_tlv_attr fm10k_update
  *
  *  This handler configures the default VLAN for the PF
  **/
-s32 fm10k_msg_update_pvid_pf(struct fm10k_hw *hw, u32 **results,
-			     struct fm10k_mbx_info *mbx)
+static s32 fm10k_msg_update_pvid_pf(struct fm10k_hw *hw, u32 **results,
+				    struct fm10k_mbx_info *mbx)
 {
 	u16 glort, pvid;
 	u32 pvid_update;
@@ -1698,7 +1709,7 @@ s32 fm10k_msg_update_pvid_pf(struct fm10
 	if (!fm10k_glort_valid_pf(hw, glort))
 		return FM10K_ERR_PARAM;
 
-	/* verify VID is valid */
+	/* verify VLAN ID is valid */
 	if (pvid >= FM10K_VLAN_TABLE_VID_MAX)
 		return FM10K_ERR_PARAM;
 
@@ -1855,39 +1866,39 @@ static const struct fm10k_msg_data fm10k
 	FM10K_TLV_MSG_ERROR_HANDLER(fm10k_tlv_msg_error),
 };
 
-static struct fm10k_mac_ops mac_ops_pf = {
-	.get_bus_info		= &fm10k_get_bus_info_generic,
-	.reset_hw		= &fm10k_reset_hw_pf,
-	.init_hw		= &fm10k_init_hw_pf,
-	.start_hw		= &fm10k_start_hw_generic,
-	.stop_hw		= &fm10k_stop_hw_generic,
-	.update_vlan		= &fm10k_update_vlan_pf,
-	.read_mac_addr		= &fm10k_read_mac_addr_pf,
-	.update_uc_addr		= &fm10k_update_uc_addr_pf,
-	.update_mc_addr		= &fm10k_update_mc_addr_pf,
-	.update_xcast_mode	= &fm10k_update_xcast_mode_pf,
-	.update_int_moderator	= &fm10k_update_int_moderator_pf,
-	.update_lport_state	= &fm10k_update_lport_state_pf,
-	.update_hw_stats	= &fm10k_update_hw_stats_pf,
-	.rebind_hw_stats	= &fm10k_rebind_hw_stats_pf,
-	.configure_dglort_map	= &fm10k_configure_dglort_map_pf,
-	.set_dma_mask		= &fm10k_set_dma_mask_pf,
-	.get_fault		= &fm10k_get_fault_pf,
-	.get_host_state		= &fm10k_get_host_state_pf,
-	.adjust_systime		= &fm10k_adjust_systime_pf,
-	.read_systime		= &fm10k_read_systime_pf,
+static const struct fm10k_mac_ops mac_ops_pf = {
+	.get_bus_info		= fm10k_get_bus_info_generic,
+	.reset_hw		= fm10k_reset_hw_pf,
+	.init_hw		= fm10k_init_hw_pf,
+	.start_hw		= fm10k_start_hw_generic,
+	.stop_hw		= fm10k_stop_hw_generic,
+	.update_vlan		= fm10k_update_vlan_pf,
+	.read_mac_addr		= fm10k_read_mac_addr_pf,
+	.update_uc_addr		= fm10k_update_uc_addr_pf,
+	.update_mc_addr		= fm10k_update_mc_addr_pf,
+	.update_xcast_mode	= fm10k_update_xcast_mode_pf,
+	.update_int_moderator	= fm10k_update_int_moderator_pf,
+	.update_lport_state	= fm10k_update_lport_state_pf,
+	.update_hw_stats	= fm10k_update_hw_stats_pf,
+	.rebind_hw_stats	= fm10k_rebind_hw_stats_pf,
+	.configure_dglort_map	= fm10k_configure_dglort_map_pf,
+	.set_dma_mask		= fm10k_set_dma_mask_pf,
+	.get_fault		= fm10k_get_fault_pf,
+	.get_host_state		= fm10k_get_host_state_pf,
+	.adjust_systime		= fm10k_adjust_systime_pf,
+	.read_systime		= fm10k_read_systime_pf,
 };
 
-static struct fm10k_iov_ops iov_ops_pf = {
-	.assign_resources		= &fm10k_iov_assign_resources_pf,
-	.configure_tc			= &fm10k_iov_configure_tc_pf,
-	.assign_int_moderator		= &fm10k_iov_assign_int_moderator_pf,
+static const struct fm10k_iov_ops iov_ops_pf = {
+	.assign_resources		= fm10k_iov_assign_resources_pf,
+	.configure_tc			= fm10k_iov_configure_tc_pf,
+	.assign_int_moderator		= fm10k_iov_assign_int_moderator_pf,
 	.assign_default_mac_vlan	= fm10k_iov_assign_default_mac_vlan_pf,
-	.reset_resources		= &fm10k_iov_reset_resources_pf,
-	.set_lport			= &fm10k_iov_set_lport_pf,
-	.reset_lport			= &fm10k_iov_reset_lport_pf,
-	.update_stats			= &fm10k_iov_update_stats_pf,
-	.report_timestamp		= &fm10k_iov_report_timestamp_pf,
+	.reset_resources		= fm10k_iov_reset_resources_pf,
+	.set_lport			= fm10k_iov_set_lport_pf,
+	.reset_lport			= fm10k_iov_reset_lport_pf,
+	.update_stats			= fm10k_iov_update_stats_pf,
+	.report_timestamp		= fm10k_iov_report_timestamp_pf,
 };
 
 static s32 fm10k_get_invariants_pf(struct fm10k_hw *hw)
@@ -1897,9 +1908,9 @@ static s32 fm10k_get_invariants_pf(struc
 	return fm10k_sm_mbx_init(hw, &hw->mbx, fm10k_msg_data_pf);
 }
 
-struct fm10k_info fm10k_pf_info = {
+const struct fm10k_info fm10k_pf_info = {
 	.mac		= fm10k_mac_pf,
-	.get_invariants	= &fm10k_get_invariants_pf,
+	.get_invariants	= fm10k_get_invariants_pf,
 	.mac_ops	= &mac_ops_pf,
 	.iov_ops	= &iov_ops_pf,
 };
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/intel/fm10k/fm10k_pf.h
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/intel/fm10k/fm10k_pf.h
@@ -1,5 +1,5 @@
 /* Intel Ethernet Switch Host Interface Driver
- * Copyright(c) 2013 - 2014 Intel Corporation.
+ * Copyright(c) 2013 - 2015 Intel Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms and conditions of the GNU General Public License,
@@ -74,6 +74,11 @@ enum fm10k_pf_tlv_attr_id_v1 {
 #define FM10K_MSG_UPDATE_PVID_PVID_SHIFT	16
 #define FM10K_MSG_UPDATE_PVID_PVID_SIZE		16
 
+/* The following data structures are overlayed directly onto TLV mailbox
+ * messages, and must not break 4 byte alignment. Ensure the structures line
+ * up correctly as per their TLV definition.
+ */
+
 struct fm10k_mac_update {
 	__le32	mac_lower;
 	__le16	mac_upper;
@@ -81,34 +86,32 @@ struct fm10k_mac_update {
 	__le16	glort;
 	u8	flags;
 	u8	action;
-} __packed;
+} __aligned(4) __packed;
 
 struct fm10k_global_table_data {
 	__le32	used;
 	__le32	avail;
-} __packed;
+} __aligned(4) __packed;
 
 struct fm10k_swapi_error {
 	__le32				status;
 	struct fm10k_global_table_data	mac;
 	struct fm10k_global_table_data	nexthop;
 	struct fm10k_global_table_data	ffu;
-} __packed;
+} __aligned(4) __packed;
 
 struct fm10k_swapi_1588_timestamp {
 	__le64 egress;
 	__le64 ingress;
 	__le16 dglort;
 	__le16 sglort;
-} __packed;
+} __aligned(4) __packed;
 
 s32 fm10k_msg_lport_map_pf(struct fm10k_hw *, u32 **, struct fm10k_mbx_info *);
 extern const struct fm10k_tlv_attr fm10k_lport_map_msg_attr[];
 #define FM10K_PF_MSG_LPORT_MAP_HANDLER(func) \
 	FM10K_MSG_HANDLER(FM10K_PF_MSG_ID_LPORT_MAP, \
 			  fm10k_lport_map_msg_attr, func)
-s32 fm10k_msg_update_pvid_pf(struct fm10k_hw *, u32 **,
-			     struct fm10k_mbx_info *);
 extern const struct fm10k_tlv_attr fm10k_update_pvid_msg_attr[];
 #define FM10K_PF_MSG_UPDATE_PVID_HANDLER(func) \
 	FM10K_MSG_HANDLER(FM10K_PF_MSG_ID_UPDATE_PVID, \
@@ -129,7 +132,6 @@ s32 fm10k_iov_msg_mac_vlan_pf(struct fm1
 			      struct fm10k_mbx_info *);
 s32 fm10k_iov_msg_lport_state_pf(struct fm10k_hw *, u32 **,
 				 struct fm10k_mbx_info *);
-extern const struct fm10k_msg_data fm10k_iov_msg_data_pf[];
 
-extern struct fm10k_info fm10k_pf_info;
+extern const struct fm10k_info fm10k_pf_info;
 #endif /* _FM10K_PF_H */
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/intel/fm10k/fm10k_tlv.c
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/intel/fm10k/fm10k_tlv.c
@@ -1,5 +1,5 @@
 /* Intel Ethernet Switch Host Interface Driver
- * Copyright(c) 2013 - 2014 Intel Corporation.
+ * Copyright(c) 2013 - 2015 Intel Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms and conditions of the GNU General Public License,
@@ -48,8 +48,8 @@ s32 fm10k_tlv_msg_init(u32 *msg, u16 msg
  *  the attribute buffer.  It will return success if provided with a valid
  *  pointers.
  **/
-s32 fm10k_tlv_attr_put_null_string(u32 *msg, u16 attr_id,
-				   const unsigned char *string)
+static s32 fm10k_tlv_attr_put_null_string(u32 *msg, u16 attr_id,
+					  const unsigned char *string)
 {
 	u32 attr_data = 0, len = 0;
 	u32 *attr;
@@ -98,7 +98,7 @@ s32 fm10k_tlv_attr_put_null_string(u32 *
  *  it in the array pointed by by string.  It will return success if provided
  *  with a valid pointers.
  **/
-s32 fm10k_tlv_attr_get_null_string(u32 *attr, unsigned char *string)
+static s32 fm10k_tlv_attr_get_null_string(u32 *attr, unsigned char *string)
 {
 	u32 len;
 
@@ -353,7 +353,7 @@ s32 fm10k_tlv_attr_get_le_struct(u32 *at
  *  function will return NULL on failure, and a pointer to the start
  *  of the nested attributes on success.
  **/
-u32 *fm10k_tlv_attr_nest_start(u32 *msg, u16 attr_id)
+static u32 *fm10k_tlv_attr_nest_start(u32 *msg, u16 attr_id)
 {
 	u32 *attr;
 
@@ -370,7 +370,7 @@ u32 *fm10k_tlv_attr_nest_start(u32 *msg,
 }
 
 /**
- *  fm10k_tlv_attr_nest_start - Start a set of nested attributes
+ *  fm10k_tlv_attr_nest_stop - Stop a set of nested attributes
  *  @msg: Pointer to message block
  *
  *  This function closes off an existing set of nested attributes.  The
@@ -378,7 +378,7 @@ u32 *fm10k_tlv_attr_nest_start(u32 *msg,
  *  the case of a nest within the nest this would be the outer nest pointer.
  *  This function will return success provided all pointers are valid.
  **/
-s32 fm10k_tlv_attr_nest_stop(u32 *msg)
+static s32 fm10k_tlv_attr_nest_stop(u32 *msg)
 {
 	u32 *attr;
 	u32 len;
@@ -483,8 +483,8 @@ static s32 fm10k_tlv_attr_validate(u32 *
  *  FM10K_NOT_IMPLEMENTED for any attribute that is outside of the array
  *  and 0 on success.
  **/
-s32 fm10k_tlv_attr_parse(u32 *attr, u32 **results,
-			 const struct fm10k_tlv_attr *tlv_attr)
+static s32 fm10k_tlv_attr_parse(u32 *attr, u32 **results,
+				const struct fm10k_tlv_attr *tlv_attr)
 {
 	u32 i, attr_id, offset = 0;
 	s32 err = 0;
@@ -755,7 +755,7 @@ parse_nested:
 		err = fm10k_tlv_attr_get_mac_vlan(
 					results[FM10K_TEST_MSG_MAC_ADDR],
 					result_mac, &result_vlan);
-		if (!err && memcmp(test_mac, result_mac, ETH_ALEN))
+		if (!err && !ether_addr_equal(test_mac, result_mac))
 			err = FM10K_ERR_INVALID_VALUE;
 		if (!err && test_vlan != result_vlan)
 			err = FM10K_ERR_INVALID_VALUE;
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/intel/fm10k/fm10k_tlv.h
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/intel/fm10k/fm10k_tlv.h
@@ -1,5 +1,5 @@
 /* Intel Ethernet Switch Host Interface Driver
- * Copyright(c) 2013 - 2014 Intel Corporation.
+ * Copyright(c) 2013 - 2015 Intel Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms and conditions of the GNU General Public License,
@@ -38,9 +38,9 @@ struct fm10k_msg_data;
  * mailbox size we will provide a message with the above header and it
  * will be segmented and transported to the mailbox to the other side where
  * it is reassembled.  It contains the following fields:
- * Len: Length of the message in bytes excluding the message header
+ * Length: Length of the message in bytes excluding the message header
  * Flags: TBD
- * Rule: These will be the message/argument types we pass
+ * Type/ID: These will be the message/argument types we pass
  */
 /* message data header */
 #define FM10K_TLV_ID_SHIFT		0
@@ -106,8 +106,6 @@ struct fm10k_msg_data {
 #define FM10K_MSG_HANDLER(id, attr, func) { id, attr, func }
 
 s32 fm10k_tlv_msg_init(u32 *, u16);
-s32 fm10k_tlv_attr_put_null_string(u32 *, u16, const unsigned char *);
-s32 fm10k_tlv_attr_get_null_string(u32 *, unsigned char *);
 s32 fm10k_tlv_attr_put_mac_vlan(u32 *, u16, const u8 *, u16);
 s32 fm10k_tlv_attr_get_mac_vlan(u32 *, u8 *, u16 *);
 s32 fm10k_tlv_attr_put_bool(u32 *, u16);
@@ -147,9 +145,6 @@ s32 fm10k_tlv_attr_get_value(u32 *, void
 		fm10k_tlv_attr_get_value(attr, ptr, sizeof(s64))
 s32 fm10k_tlv_attr_put_le_struct(u32 *, u16, const void *, u32);
 s32 fm10k_tlv_attr_get_le_struct(u32 *, void *, u32);
-u32 *fm10k_tlv_attr_nest_start(u32 *, u16);
-s32 fm10k_tlv_attr_nest_stop(u32 *);
-s32 fm10k_tlv_attr_parse(u32 *, u32 **, const struct fm10k_tlv_attr *);
 s32 fm10k_tlv_msg_parse(struct fm10k_hw *, u32 *, struct fm10k_mbx_info *,
 			const struct fm10k_msg_data *);
 s32 fm10k_tlv_msg_error(struct fm10k_hw *hw, u32 **results,
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/intel/fm10k/fm10k_type.h
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/intel/fm10k/fm10k_type.h
@@ -1,5 +1,5 @@
 /* Intel Ethernet Switch Host Interface Driver
- * Copyright(c) 2013 - 2014 Intel Corporation.
+ * Copyright(c) 2013 - 2015 Intel Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms and conditions of the GNU General Public License,
@@ -77,6 +77,7 @@ struct fm10k_hw;
 #define FM10K_PCIE_SRIOV_CTRL_VFARI		0x10
 
 #define FM10K_ERR_PARAM				-2
+#define FM10K_ERR_NO_RESOURCES			-3
 #define FM10K_ERR_REQUESTS_PENDING		-4
 #define FM10K_ERR_RESET_REQUESTED		-5
 #define FM10K_ERR_DMA_PENDING			-6
@@ -271,6 +272,20 @@ struct fm10k_hw;
 #define FM10K_TDBAL(_n)		((0x40 * (_n)) + 0x8000)
 #define FM10K_TDBAH(_n)		((0x40 * (_n)) + 0x8001)
 #define FM10K_TDLEN(_n)		((0x40 * (_n)) + 0x8002)
+/* When fist initialized, VFs need to know the Interrupt Throttle Rate (ITR)
+ * scale which is based on the PCIe speed but the speed information in the PCI
+ * configuration space may not be accurate. The PF already knows the ITR scale
+ * but there is no defined method to pass that information from the PF to the
+ * VF. This is accomplished during VF initialization by temporarily co-opting
+ * the yet-to-be-used TDLEN register to have the PF store the ITR shift for
+ * the VF to retrieve before the VF needs to use the TDLEN register for its
+ * intended purpose, i.e. before the Tx resources are allocated.
+ */
+#define FM10K_TDLEN_ITR_SCALE_SHIFT		9
+#define FM10K_TDLEN_ITR_SCALE_MASK		0x00000E00
+#define FM10K_TDLEN_ITR_SCALE_GEN1		2
+#define FM10K_TDLEN_ITR_SCALE_GEN2		1
+#define FM10K_TDLEN_ITR_SCALE_GEN3		0
 #define FM10K_TPH_TXCTRL(_n)	((0x40 * (_n)) + 0x8003)
 #define FM10K_TPH_TXCTRL_DESC_TPHEN		0x00000020
 #define FM10K_TPH_TXCTRL_DESC_RROEN		0x00000200
@@ -339,7 +354,7 @@ struct fm10k_hw;
 #define FM10K_VLAN_TABLE_VID_MAX		4096
 #define FM10K_VLAN_TABLE_VSI_MAX		64
 #define FM10K_VLAN_LENGTH_SHIFT			16
-#define FM10K_VLAN_CLEAR			(1 << 15)
+#define FM10K_VLAN_CLEAR			BIT(15)
 #define FM10K_VLAN_ALL \
 	((FM10K_VLAN_TABLE_VID_MAX - 1) << FM10K_VLAN_LENGTH_SHIFT)
 
@@ -373,13 +388,13 @@ struct fm10k_hw;
 #define FM10K_SW_SYSTIME_PULSE(_n)	((_n) + 0x02252)
 
 enum fm10k_int_source {
-	fm10k_int_Mailbox	= 0,
-	fm10k_int_PCIeFault	= 1,
-	fm10k_int_SwitchUpDown	= 2,
-	fm10k_int_SwitchEvent	= 3,
-	fm10k_int_SRAM		= 4,
-	fm10k_int_VFLR		= 5,
-	fm10k_int_MaxHoldTime	= 6,
+	fm10k_int_mailbox		= 0,
+	fm10k_int_pcie_fault		= 1,
+	fm10k_int_switch_up_down	= 2,
+	fm10k_int_switch_event		= 3,
+	fm10k_int_sram			= 4,
+	fm10k_int_vflr			= 5,
+	fm10k_int_max_hold_time		= 6,
 	fm10k_int_sources_max_pf
 };
 
@@ -535,7 +550,6 @@ struct fm10k_mac_ops {
 				    struct fm10k_dglort_cfg *);
 	void (*set_dma_mask)(struct fm10k_hw *, u64);
 	s32 (*get_fault)(struct fm10k_hw *, int, struct fm10k_fault *);
-	void (*request_lport_map)(struct fm10k_hw *);
 	s32 (*adjust_systime)(struct fm10k_hw *, s32 ppb);
 	u64 (*read_systime)(struct fm10k_hw *);
 };
@@ -559,6 +573,7 @@ struct fm10k_mac_info {
 	bool get_host_state;
 	bool tx_ready;
 	u32 dglort_map;
+	u8 itr_scale;
 };
 
 struct fm10k_swapi_table_info {
@@ -644,10 +659,10 @@ enum fm10k_devices {
 };
 
 struct fm10k_info {
-	enum fm10k_mac_type	mac;
-	s32			(*get_invariants)(struct fm10k_hw *);
-	struct fm10k_mac_ops	*mac_ops;
-	struct fm10k_iov_ops	*iov_ops;
+	enum fm10k_mac_type		mac;
+	s32				(*get_invariants)(struct fm10k_hw *);
+	const struct fm10k_mac_ops	*mac_ops;
+	const struct fm10k_iov_ops	*iov_ops;
 };
 
 struct fm10k_hw {
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/intel/fm10k/fm10k_vf.c
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/intel/fm10k/fm10k_vf.c
@@ -28,7 +28,7 @@
 static s32 fm10k_stop_hw_vf(struct fm10k_hw *hw)
 {
 	u8 *perm_addr = hw->mac.perm_addr;
-	u32 bal = 0, bah = 0;
+	u32 bal = 0, bah = 0, tdlen;
 	s32 err;
 	u16 i;
 
@@ -48,6 +48,9 @@ static s32 fm10k_stop_hw_vf(struct fm10k
 		       ((u32)perm_addr[2]);
 	}
 
+	/* restore default itr_scale for next VF initialization */
+	tdlen = hw->mac.itr_scale << FM10K_TDLEN_ITR_SCALE_SHIFT;
+
 	/* The queues have already been disabled so we just need to
 	 * update their base address registers
 	 */
@@ -56,6 +59,12 @@ static s32 fm10k_stop_hw_vf(struct fm10k
 		fm10k_write_reg(hw, FM10K_TDBAH(i), bah);
 		fm10k_write_reg(hw, FM10K_RDBAL(i), bal);
 		fm10k_write_reg(hw, FM10K_RDBAH(i), bah);
+		/* Restore ITR scale in software-defined mechanism in TDLEN
+		 * for next VF initialization. See definition of
+		 * FM10K_TDLEN_ITR_SCALE_SHIFT for more details on the use of
+		 * TDLEN here.
+		 */
+		fm10k_write_reg(hw, FM10K_TDLEN(i), tdlen);
 	}
 
 	return 0;
@@ -103,7 +112,14 @@ static s32 fm10k_init_hw_vf(struct fm10k
 	s32 err;
 	u16 i;
 
-	/* assume we always have at least 1 queue */
+	/* verify we have at least 1 queue */
+	if (!~fm10k_read_reg(hw, FM10K_TXQCTL(0)) ||
+	    !~fm10k_read_reg(hw, FM10K_RXQCTL(0))) {
+		err = FM10K_ERR_NO_RESOURCES;
+		goto reset_max_queues;
+	}
+
+	/* determine how many queues we have */
 	for (i = 1; tqdloc0 && (i < FM10K_MAX_QUEUES_POOL); i++) {
 		/* verify the Descriptor cache offsets are increasing */
 		tqdloc = ~fm10k_read_reg(hw, FM10K_TQDLOC(i));
@@ -119,16 +135,28 @@ static s32 fm10k_init_hw_vf(struct fm10k
 	/* shut down queues we own and reset DMA configuration */
 	err = fm10k_disable_queues_generic(hw, i);
 	if (err)
-		return err;
+		goto reset_max_queues;
 
 	/* record maximum queue count */
 	hw->mac.max_queues = i;
 
-	/* fetch default VLAN */
+	/* fetch default VLAN and ITR scale */
 	hw->mac.default_vid = (fm10k_read_reg(hw, FM10K_TXQCTL(0)) &
 			       FM10K_TXQCTL_VID_MASK) >> FM10K_TXQCTL_VID_SHIFT;
+	/* Read the ITR scale from TDLEN. See the definition of
+	 * FM10K_TDLEN_ITR_SCALE_SHIFT for more information about how TDLEN is
+	 * used here.
+	 */
+	hw->mac.itr_scale = (fm10k_read_reg(hw, FM10K_TDLEN(0)) &
+			     FM10K_TDLEN_ITR_SCALE_MASK) >>
+			    FM10K_TDLEN_ITR_SCALE_SHIFT;
 
 	return 0;
+
+reset_max_queues:
+	hw->mac.max_queues = 0;
+
+	return err;
 }
 
 /* This structure defines the attibutes to be parsed below */
@@ -270,7 +298,7 @@ static s32 fm10k_update_uc_addr_vf(struc
 
 	/* verify we are not locked down on the MAC address */
 	if (is_valid_ether_addr(hw->mac.perm_addr) &&
-	    memcmp(hw->mac.perm_addr, mac, ETH_ALEN))
+	    !ether_addr_equal(hw->mac.perm_addr, mac))
 		return FM10K_ERR_PARAM;
 
 	/* add bit to notify us if this is a set or clear operation */
@@ -414,6 +442,7 @@ static s32 fm10k_update_xcast_mode_vf(st
 
 	if (mode > FM10K_XCAST_MODE_NONE)
 		return FM10K_ERR_PARAM;
+
 	/* generate message requesting to change xcast mode */
 	fm10k_tlv_msg_init(msg, FM10K_VF_MSG_ID_LPORT_STATE);
 	fm10k_tlv_attr_put_u8(msg, FM10K_LPORT_STATE_MSG_XCAST_MODE, mode);
@@ -533,25 +562,25 @@ static const struct fm10k_msg_data fm10k
 	FM10K_TLV_MSG_ERROR_HANDLER(fm10k_tlv_msg_error),
 };
 
-static struct fm10k_mac_ops mac_ops_vf = {
-	.get_bus_info		= &fm10k_get_bus_info_generic,
-	.reset_hw		= &fm10k_reset_hw_vf,
-	.init_hw		= &fm10k_init_hw_vf,
-	.start_hw		= &fm10k_start_hw_generic,
-	.stop_hw		= &fm10k_stop_hw_vf,
-	.update_vlan		= &fm10k_update_vlan_vf,
-	.read_mac_addr		= &fm10k_read_mac_addr_vf,
-	.update_uc_addr		= &fm10k_update_uc_addr_vf,
-	.update_mc_addr		= &fm10k_update_mc_addr_vf,
-	.update_xcast_mode	= &fm10k_update_xcast_mode_vf,
-	.update_int_moderator	= &fm10k_update_int_moderator_vf,
-	.update_lport_state	= &fm10k_update_lport_state_vf,
-	.update_hw_stats	= &fm10k_update_hw_stats_vf,
-	.rebind_hw_stats	= &fm10k_rebind_hw_stats_vf,
-	.configure_dglort_map	= &fm10k_configure_dglort_map_vf,
-	.get_host_state		= &fm10k_get_host_state_generic,
-	.adjust_systime		= &fm10k_adjust_systime_vf,
-	.read_systime		= &fm10k_read_systime_vf,
+static const struct fm10k_mac_ops mac_ops_vf = {
+	.get_bus_info		= fm10k_get_bus_info_generic,
+	.reset_hw		= fm10k_reset_hw_vf,
+	.init_hw		= fm10k_init_hw_vf,
+	.start_hw		= fm10k_start_hw_generic,
+	.stop_hw		= fm10k_stop_hw_vf,
+	.update_vlan		= fm10k_update_vlan_vf,
+	.read_mac_addr		= fm10k_read_mac_addr_vf,
+	.update_uc_addr		= fm10k_update_uc_addr_vf,
+	.update_mc_addr		= fm10k_update_mc_addr_vf,
+	.update_xcast_mode	= fm10k_update_xcast_mode_vf,
+	.update_int_moderator	= fm10k_update_int_moderator_vf,
+	.update_lport_state	= fm10k_update_lport_state_vf,
+	.update_hw_stats	= fm10k_update_hw_stats_vf,
+	.rebind_hw_stats	= fm10k_rebind_hw_stats_vf,
+	.configure_dglort_map	= fm10k_configure_dglort_map_vf,
+	.get_host_state		= fm10k_get_host_state_generic,
+	.adjust_systime		= fm10k_adjust_systime_vf,
+	.read_systime		= fm10k_read_systime_vf,
 };
 
 static s32 fm10k_get_invariants_vf(struct fm10k_hw *hw)
@@ -561,8 +590,8 @@ static s32 fm10k_get_invariants_vf(struc
 	return fm10k_pfvf_mbx_init(hw, &hw->mbx, fm10k_msg_data_vf, 0);
 }
 
-struct fm10k_info fm10k_vf_info = {
+const struct fm10k_info fm10k_vf_info = {
 	.mac		= fm10k_mac_vf,
-	.get_invariants	= &fm10k_get_invariants_vf,
+	.get_invariants	= fm10k_get_invariants_vf,
 	.mac_ops	= &mac_ops_vf,
 };
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/intel/fm10k/fm10k_vf.h
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/intel/fm10k/fm10k_vf.h
@@ -74,5 +74,5 @@ extern const struct fm10k_tlv_attr fm10k
 #define FM10K_VF_MSG_1588_HANDLER(func) \
 	FM10K_MSG_HANDLER(FM10K_VF_MSG_ID_1588, fm10k_1588_msg_attr, func)
 
-extern struct fm10k_info fm10k_vf_info;
+extern const struct fm10k_info fm10k_vf_info;
 #endif /* _FM10K_VF_H */
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/intel/i40e/i40e.h
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/intel/i40e/i40e.h
@@ -1,7 +1,7 @@
 /*******************************************************************************
  *
  * Intel Ethernet Controller XL710 Family Linux Driver
- * Copyright(c) 2013 - 2015 Intel Corporation.
+ * Copyright(c) 2013 - 2016 Intel Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms and conditions of the GNU General Public License,
@@ -42,7 +42,6 @@
 #include <linux/string.h>
 #include <linux/in.h>
 #include <linux/ip.h>
-#include <linux/tcp.h>
 #include <linux/sctp.h>
 #include <linux/pkt_sched.h>
 #include <linux/ipv6.h>
@@ -65,9 +64,6 @@
 #include "i40e_dcb.h"
 
 /* Useful i40e defaults */
-#define I40E_BASE_PF_SEID     16
-#define I40E_BASE_VSI_SEID    512
-#define I40E_BASE_VEB_SEID    288
 #define I40E_MAX_VEB          16
 
 #define I40E_MAX_NUM_DESCRIPTORS      4096
@@ -104,6 +100,8 @@
 #define I40E_PRIV_FLAGS_LINKPOLL_FLAG	BIT(1)
 #define I40E_PRIV_FLAGS_FD_ATR		BIT(2)
 #define I40E_PRIV_FLAGS_VEB_STATS	BIT(3)
+#define I40E_PRIV_FLAGS_PS		BIT(4)
+#define I40E_PRIV_FLAGS_HW_ATR_EVICT	BIT(5)
 
 #define I40E_NVM_VERSION_LO_SHIFT  0
 #define I40E_NVM_VERSION_LO_MASK   (0xff << I40E_NVM_VERSION_LO_SHIFT)
@@ -113,6 +111,7 @@
 #define I40E_OEM_VER_PATCH_MASK    0xff
 #define I40E_OEM_VER_BUILD_SHIFT   8
 #define I40E_OEM_VER_SHIFT         24
+#define I40E_PHY_DEBUG_PORT        BIT(4)
 
 /* The values in here are decimal coded as hex as is the case in the NVM map*/
 #define I40E_CURRENT_NVM_VERSION_HI 0x2
@@ -137,6 +136,19 @@
 /* default to trying for four seconds */
 #define I40E_TRY_LINK_TIMEOUT (4 * HZ)
 
+/**
+ * i40e_is_mac_710 - Return true if MAC is X710/XL710
+ * @hw: ptr to the hardware info
+ **/
+static inline bool i40e_is_mac_710(struct i40e_hw *hw)
+{
+	if ((hw->mac.type == I40E_MAC_X710) ||
+	    (hw->mac.type == I40E_MAC_XL710))
+		return true;
+
+	return false;
+}
+
 /* driver state flags */
 enum i40e_state_t {
 	__I40E_TESTING,
@@ -187,6 +199,7 @@ struct i40e_lump_tracking {
 #define I40E_FDIR_BUFFER_HEAD_ROOM_FOR_ATR (I40E_FDIR_BUFFER_HEAD_ROOM * 4)
 
 #define I40E_HKEY_ARRAY_SIZE ((I40E_PFQF_HKEY_MAX_INDEX + 1) * 4)
+#define I40E_HLUT_ARRAY_SIZE ((I40E_PFQF_HLUT_MAX_INDEX + 1) * 4)
 
 enum i40e_fd_stat_idx {
 	I40E_FD_STAT_ATR,
@@ -244,6 +257,11 @@ struct i40e_tc_configuration {
 	struct i40e_tc_info tc_info[I40E_MAX_TRAFFIC_CLASS];
 };
 
+struct i40e_udp_port_config {
+	__be16 index;
+	u8 type;
+};
+
 /* struct that defines the Ethernet device */
 struct i40e_pf {
 	struct pci_dev *pdev;
@@ -264,8 +282,9 @@ struct i40e_pf {
 #endif /* I40E_FCOE */
 	u16 num_lan_qps;           /* num lan queues this PF has set up */
 	u16 num_lan_msix;          /* num queue vectors for the base PF vsi */
+	u16 num_fdsb_msix;         /* num queue vectors for sideband Fdir */
 	int queues_left;           /* queues left unclaimed */
-	u16 rss_size;              /* num queues in the RSS array */
+	u16 alloc_rss_size;        /* allocated RSS queues */
 	u16 rss_size_max;          /* HW defined max RSS queues */
 	u16 fdir_pf_filter_count;  /* num of guaranteed filters for this PF */
 	u16 num_alloc_vsi;         /* num VSIs this driver supports */
@@ -280,11 +299,9 @@ struct i40e_pf {
 	u32 fd_atr_cnt;
 	u32 fd_tcp_rule;
 
-#ifdef CONFIG_I40E_VXLAN
-	__be16  vxlan_ports[I40E_MAX_PF_UDP_OFFLOAD_PORTS];
-	u16 pending_vxlan_bitmap;
+	struct i40e_udp_port_config udp_ports[I40E_MAX_PF_UDP_OFFLOAD_PORTS];
+	u16 pending_udp_bitmap;
 
-#endif
 	enum i40e_interrupt_policy int_policy;
 	u16 rx_itr_default;
 	u16 tx_itr_default;
@@ -321,9 +338,7 @@ struct i40e_pf {
 #define I40E_FLAG_FD_ATR_ENABLED		BIT_ULL(22)
 #define I40E_FLAG_PTP				BIT_ULL(25)
 #define I40E_FLAG_MFP_ENABLED			BIT_ULL(26)
-#ifdef CONFIG_I40E_VXLAN
-#define I40E_FLAG_VXLAN_FILTER_SYNC		BIT_ULL(27)
-#endif
+#define I40E_FLAG_UDP_FILTER_SYNC		BIT_ULL(27)
 #define I40E_FLAG_PORT_ID_VALID			BIT_ULL(28)
 #define I40E_FLAG_DCB_CAPABLE			BIT_ULL(29)
 #define I40E_FLAG_RSS_AQ_CAPABLE		BIT_ULL(31)
@@ -335,7 +350,15 @@ struct i40e_pf {
 #define I40E_FLAG_MULTIPLE_TCP_UDP_RSS_PCTYPE	BIT_ULL(38)
 #define I40E_FLAG_LINK_POLLING_ENABLED		BIT_ULL(39)
 #define I40E_FLAG_VEB_MODE_ENABLED		BIT_ULL(40)
+#define I40E_FLAG_GENEVE_OFFLOAD_CAPABLE	BIT_ULL(41)
 #define I40E_FLAG_NO_PCI_LINK_CHECK		BIT_ULL(42)
+#define I40E_FLAG_100M_SGMII_CAPABLE		BIT_ULL(43)
+#define I40E_FLAG_RESTART_AUTONEG		BIT_ULL(44)
+#define I40E_FLAG_NO_DCB_SUPPORT		BIT_ULL(45)
+#define I40E_FLAG_USE_SET_LLDP_MIB		BIT_ULL(46)
+#define I40E_FLAG_STOP_FW_LLDP			BIT_ULL(47)
+#define I40E_FLAG_HAVE_10GBASET_PHY		BIT_ULL(48)
+#define I40E_FLAG_PF_MAC			BIT_ULL(50)
 
 	/* tracks features that get auto disabled by errors */
 	u64 auto_disable_flags;
@@ -387,6 +410,7 @@ struct i40e_pf {
 	struct i40e_vf *vf;
 	int num_alloc_vfs;	/* actual number of VFs allocated */
 	u32 vf_aq_requests;
+	u32 arq_overflows;	/* Not fatal, possibly indicative of problems */
 
 	/* DCBx/DCBNL capability for PF that indicates
 	 * whether DCBx is managed by firmware or host
@@ -412,13 +436,14 @@ struct i40e_pf {
 	u32 rx_hwtstamp_cleared;
 	bool ptp_tx;
 	bool ptp_rx;
-	u16 rss_table_size;
+	u16 rss_table_size; /* HW RSS table size */
 	/* These are only valid in NPAR modes */
 	u32 npar_max_bw;
 	u32 npar_min_bw;
 
 	u32 ioremap_len;
 	u32 fd_inv;
+	u16 phy_led_val;
 };
 
 struct i40e_mac_filter {
@@ -487,6 +512,8 @@ struct i40e_vsi {
 	u32 tx_restart;
 	u32 tx_busy;
 	u64 tx_linearize;
+	u64 tx_force_wb;
+	u64 tx_lost_interrupt;
 	u32 rx_buf_failed;
 	u32 rx_page_failed;
 
@@ -504,8 +531,10 @@ struct i40e_vsi {
 	u16 tx_itr_setting;
 	u16 int_rate_limit;  /* value in usecs */
 
-	u16 rss_table_size;
-	u16 rss_size;
+	u16 rss_table_size; /* HW RSS table size */
+	u16 rss_size;       /* Allocated RSS queues */
+	u8  *rss_hkey_user; /* User configured hash keys */
+	u8  *rss_lut_user;  /* User configured lookup table entries */
 
 	u16 max_frame;
 	u16 rx_hdr_len;
@@ -575,6 +604,9 @@ struct i40e_q_vector {
 
 	u8 num_ringpairs;	/* total number of ring pairs in vector */
 
+#define I40E_Q_VECTOR_HUNG_DETECT 0 /* Bit Index for hung detection logic */
+	unsigned long hung_detected; /* Set/Reset for hung_detection logic */
+
 	cpumask_t affinity_mask;
 	struct rcu_head rcu;	/* to avoid race with update stats on free */
 	char name[I40E_INT_NAME_STR_LEN];
@@ -602,8 +634,8 @@ static inline char *i40e_nvm_version_str
 
 	full_ver = hw->nvm.oem_ver;
 	ver = (u8)(full_ver >> I40E_OEM_VER_SHIFT);
-	build = (u16)((full_ver >> I40E_OEM_VER_BUILD_SHIFT)
-		 & I40E_OEM_VER_BUILD_MASK);
+	build = (u16)((full_ver >> I40E_OEM_VER_BUILD_SHIFT) &
+		 I40E_OEM_VER_BUILD_MASK);
 	patch = (u8)(full_ver & I40E_OEM_VER_PATCH_MASK);
 
 	snprintf(buf, sizeof(buf),
@@ -668,6 +700,8 @@ extern const char i40e_driver_name[];
 extern const char i40e_driver_version_str[];
 void i40e_do_reset_safe(struct i40e_pf *pf, u32 reset_flags);
 void i40e_do_reset(struct i40e_pf *pf, u32 reset_flags);
+int i40e_config_rss(struct i40e_vsi *vsi, u8 *seed, u8 *lut, u16 lut_size);
+int i40e_get_rss(struct i40e_vsi *vsi, u8 *seed, u8 *lut, u16 lut_size);
 struct i40e_vsi *i40e_find_vsi_from_id(struct i40e_pf *pf, u16 id);
 void i40e_update_stats(struct i40e_vsi *vsi);
 void i40e_update_eth_stats(struct i40e_vsi *vsi);
@@ -691,7 +725,7 @@ struct i40e_mac_filter *i40e_add_filter(
 					bool is_vf, bool is_netdev);
 void i40e_del_filter(struct i40e_vsi *vsi, u8 *macaddr, s16 vlan,
 		     bool is_vf, bool is_netdev);
-int i40e_sync_vsi_filters(struct i40e_vsi *vsi, bool grab_rtnl);
+int i40e_sync_vsi_filters(struct i40e_vsi *vsi);
 struct i40e_vsi *i40e_vsi_setup(struct i40e_pf *pf, u8 type,
 				u16 uplink, u32 param1);
 int i40e_vsi_release(struct i40e_vsi *vsi);
@@ -709,7 +743,7 @@ struct i40e_veb *i40e_veb_setup(struct i
 void i40e_veb_release(struct i40e_veb *veb);
 
 int i40e_veb_config_tc(struct i40e_veb *veb, u8 enabled_tc);
-i40e_status i40e_vsi_add_pvid(struct i40e_vsi *vsi, u16 vid);
+int i40e_vsi_add_pvid(struct i40e_vsi *vsi, u16 vid);
 void i40e_vsi_remove_pvid(struct i40e_vsi *vsi);
 void i40e_vsi_reset_stats(struct i40e_vsi *vsi);
 void i40e_pf_reset_stats(struct i40e_pf *pf);
@@ -735,6 +769,9 @@ static inline void i40e_irq_dynamic_enab
 	struct i40e_hw *hw = &pf->hw;
 	u32 val;
 
+	/* definitely clear the PBA here, as this function is meant to
+	 * clean out all previous interrupts AND enable the interrupt
+	 */
 	val = I40E_PFINT_DYN_CTLN_INTENA_MASK |
 	      I40E_PFINT_DYN_CTLN_CLEARPBA_MASK |
 	      (I40E_ITR_NONE << I40E_PFINT_DYN_CTLN_ITR_INDX_SHIFT);
@@ -742,9 +779,8 @@ static inline void i40e_irq_dynamic_enab
 	/* skip the flush */
 }
 
-void i40e_irq_dynamic_disable(struct i40e_vsi *vsi, int vector);
 void i40e_irq_dynamic_disable_icr0(struct i40e_pf *pf);
-void i40e_irq_dynamic_enable_icr0(struct i40e_pf *pf);
+void i40e_irq_dynamic_enable_icr0(struct i40e_pf *pf, bool clearpba);
 #ifdef I40E_FCOE
 struct rtnl_link_stats64 *i40e_get_netdev_stats_struct(
 					     struct net_device *netdev,
@@ -767,12 +803,15 @@ int i40e_vsi_add_vlan(struct i40e_vsi *v
 int i40e_vsi_kill_vlan(struct i40e_vsi *vsi, s16 vid);
 struct i40e_mac_filter *i40e_put_mac_in_vlan(struct i40e_vsi *vsi, u8 *macaddr,
 					     bool is_vf, bool is_netdev);
+int i40e_del_mac_all_vlan(struct i40e_vsi *vsi, u8 *macaddr,
+			  bool is_vf, bool is_netdev);
 bool i40e_is_vsi_in_vlan(struct i40e_vsi *vsi);
 struct i40e_mac_filter *i40e_find_mac(struct i40e_vsi *vsi, u8 *macaddr,
 				      bool is_vf, bool is_netdev);
 #ifdef I40E_FCOE
 int i40e_close(struct net_device *netdev);
-int i40e_setup_tc(struct net_device *netdev, u8 tc);
+int __i40e_setup_tc(struct net_device *netdev, u32 handle, __be16 proto,
+		    struct tc_to_netdev *tc);
 void i40e_netpoll(struct net_device *netdev);
 int i40e_fcoe_enable(struct net_device *netdev);
 int i40e_fcoe_disable(struct net_device *netdev);
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/intel/i40e/i40e_adminq.c
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/intel/i40e/i40e_adminq.c
@@ -1,7 +1,7 @@
 /*******************************************************************************
  *
  * Intel Ethernet Controller XL710 Family Linux Driver
- * Copyright(c) 2013 - 2014 Intel Corporation.
+ * Copyright(c) 2013 - 2016 Intel Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms and conditions of the GNU General Public License,
@@ -953,6 +953,9 @@ i40e_status i40e_clean_arq_element(struc
 	u16 flags;
 	u16 ntu;
 
+	/* pre-clean the event info */
+	memset(&e->desc, 0, sizeof(e->desc));
+
 	/* take the lock before we start messing with the ring */
 	mutex_lock(&hw->aq.arq_mutex);
 
@@ -1020,14 +1023,6 @@ i40e_status i40e_clean_arq_element(struc
 	hw->aq.arq.next_to_clean = ntc;
 	hw->aq.arq.next_to_use = ntu;
 
-clean_arq_element_out:
-	/* Set pending if needed, unlock and return */
-	if (pending != NULL)
-		*pending = (ntc > ntu ? hw->aq.arq.count : 0) + (ntu - ntc);
-
-clean_arq_element_err:
-	mutex_unlock(&hw->aq.arq_mutex);
-
 	if (i40e_is_nvm_update_op(&e->desc)) {
 		if (hw->aq.nvm_release_on_done) {
 			i40e_release_nvm(hw);
@@ -1048,6 +1043,13 @@ clean_arq_element_err:
 		}
 	}
 
+clean_arq_element_out:
+	/* Set pending if needed, unlock and return */
+	if (pending)
+		*pending = (ntc > ntu ? hw->aq.arq.count : 0) + (ntu - ntc);
+clean_arq_element_err:
+	mutex_unlock(&hw->aq.arq_mutex);
+
 	return ret_code;
 }
 
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/intel/i40e/i40e_adminq_cmd.h
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/intel/i40e/i40e_adminq_cmd.h
@@ -1,7 +1,7 @@
 /*******************************************************************************
  *
  * Intel Ethernet Controller XL710 Family Linux Driver
- * Copyright(c) 2013 - 2014 Intel Corporation.
+ * Copyright(c) 2013 - 2016 Intel Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms and conditions of the GNU General Public License,
@@ -34,7 +34,7 @@
  */
 
 #define I40E_FW_API_VERSION_MAJOR	0x0001
-#define I40E_FW_API_VERSION_MINOR	0x0004
+#define I40E_FW_API_VERSION_MINOR	0x0005
 
 struct i40e_aq_desc {
 	__le16 flags;
@@ -145,6 +145,9 @@ enum i40e_admin_queue_opc {
 	i40e_aqc_opc_remove_statistics		= 0x0202,
 	i40e_aqc_opc_set_port_parameters	= 0x0203,
 	i40e_aqc_opc_get_switch_resource_alloc	= 0x0204,
+	i40e_aqc_opc_set_switch_config		= 0x0205,
+	i40e_aqc_opc_rx_ctl_reg_read		= 0x0206,
+	i40e_aqc_opc_rx_ctl_reg_write		= 0x0207,
 
 	i40e_aqc_opc_add_vsi			= 0x0210,
 	i40e_aqc_opc_update_vsi_parameters	= 0x0211,
@@ -220,6 +223,7 @@ enum i40e_admin_queue_opc {
 	i40e_aqc_opc_get_phy_wol_caps		= 0x0621,
 	i40e_aqc_opc_set_phy_debug		= 0x0622,
 	i40e_aqc_opc_upload_ext_phy_fm		= 0x0625,
+	i40e_aqc_opc_run_phy_activity		= 0x0626,
 
 	/* NVM commands */
 	i40e_aqc_opc_nvm_read			= 0x0701,
@@ -227,6 +231,8 @@ enum i40e_admin_queue_opc {
 	i40e_aqc_opc_nvm_update			= 0x0703,
 	i40e_aqc_opc_nvm_config_read		= 0x0704,
 	i40e_aqc_opc_nvm_config_write		= 0x0705,
+	i40e_aqc_opc_oem_post_update		= 0x0720,
+	i40e_aqc_opc_thermal_sensor		= 0x0721,
 
 	/* virtualization commands */
 	i40e_aqc_opc_send_msg_to_pf		= 0x0801,
@@ -401,6 +407,7 @@ struct i40e_aqc_list_capabilities_elemen
 #define I40E_AQ_CAP_ID_OS2BMC_CAP	0x0004
 #define I40E_AQ_CAP_ID_FUNCTIONS_VALID	0x0005
 #define I40E_AQ_CAP_ID_ALTERNATE_RAM	0x0006
+#define I40E_AQ_CAP_ID_WOL_AND_PROXY	0x0008
 #define I40E_AQ_CAP_ID_SRIOV		0x0012
 #define I40E_AQ_CAP_ID_VF		0x0013
 #define I40E_AQ_CAP_ID_VMDQ		0x0014
@@ -421,6 +428,7 @@ struct i40e_aqc_list_capabilities_elemen
 #define I40E_AQ_CAP_ID_LED		0x0061
 #define I40E_AQ_CAP_ID_SDP		0x0062
 #define I40E_AQ_CAP_ID_MDIO		0x0063
+#define I40E_AQ_CAP_ID_WSR_PROT		0x0064
 #define I40E_AQ_CAP_ID_FLEX10		0x00F1
 #define I40E_AQ_CAP_ID_CEM		0x00F2
 
@@ -679,6 +687,31 @@ struct i40e_aqc_switch_resource_alloc_el
 
 I40E_CHECK_STRUCT_LEN(0x10, i40e_aqc_switch_resource_alloc_element_resp);
 
+/* Set Switch Configuration (direct 0x0205) */
+struct i40e_aqc_set_switch_config {
+	__le16	flags;
+#define I40E_AQ_SET_SWITCH_CFG_PROMISC		0x0001
+#define I40E_AQ_SET_SWITCH_CFG_L2_FILTER	0x0002
+	__le16	valid_flags;
+	u8	reserved[12];
+};
+
+I40E_CHECK_CMD_LENGTH(i40e_aqc_set_switch_config);
+
+/* Read Receive control registers  (direct 0x0206)
+ * Write Receive control registers (direct 0x0207)
+ *     used for accessing Rx control registers that can be
+ *     slow and need special handling when under high Rx load
+ */
+struct i40e_aqc_rx_ctl_reg_read_write {
+	__le32 reserved1;
+	__le32 address;
+	__le32 reserved2;
+	__le32 value;
+};
+
+I40E_CHECK_CMD_LENGTH(i40e_aqc_rx_ctl_reg_read_write);
+
 /* Add VSI (indirect 0x0210)
  *    this indirect command uses struct i40e_aqc_vsi_properties_data
  *    as the indirect buffer (128 bytes)
@@ -905,7 +938,8 @@ struct i40e_aqc_add_veb {
 					I40E_AQC_ADD_VEB_PORT_TYPE_SHIFT)
 #define I40E_AQC_ADD_VEB_PORT_TYPE_DEFAULT	0x2
 #define I40E_AQC_ADD_VEB_PORT_TYPE_DATA		0x4
-#define I40E_AQC_ADD_VEB_ENABLE_L2_FILTER	0x8
+#define I40E_AQC_ADD_VEB_ENABLE_L2_FILTER	0x8     /* deprecated */
+#define I40E_AQC_ADD_VEB_ENABLE_DISABLE_STATS	0x10
 	u8	enable_tcs;
 	u8	reserved[9];
 };
@@ -972,6 +1006,7 @@ struct i40e_aqc_add_macvlan_element_data
 #define I40E_AQC_MACVLAN_ADD_HASH_MATCH		0x0002
 #define I40E_AQC_MACVLAN_ADD_IGNORE_VLAN	0x0004
 #define I40E_AQC_MACVLAN_ADD_TO_QUEUE		0x0008
+#define I40E_AQC_MACVLAN_ADD_USE_SHARED_MAC	0x0010
 	__le16	queue_number;
 #define I40E_AQC_MACVLAN_CMD_QUEUE_SHIFT	0
 #define I40E_AQC_MACVLAN_CMD_QUEUE_MASK		(0x7FF << \
@@ -1068,6 +1103,7 @@ struct i40e_aqc_set_vsi_promiscuous_mode
 #define I40E_AQC_SET_VSI_PROMISC_BROADCAST	0x04
 #define I40E_AQC_SET_VSI_DEFAULT		0x08
 #define I40E_AQC_SET_VSI_PROMISC_VLAN		0x10
+#define I40E_AQC_SET_VSI_PROMISC_TX		0x8000
 	__le16	seid;
 #define I40E_AQC_VSI_PROM_CMD_SEID_MASK		0x3FF
 	__le16	vlan_tag;
@@ -1256,10 +1292,16 @@ struct i40e_aqc_add_remove_cloud_filters
 
 #define I40E_AQC_ADD_CLOUD_TNL_TYPE_SHIFT		9
 #define I40E_AQC_ADD_CLOUD_TNL_TYPE_MASK		0x1E00
-#define I40E_AQC_ADD_CLOUD_TNL_TYPE_XVLAN		0
+#define I40E_AQC_ADD_CLOUD_TNL_TYPE_VXLAN		0
 #define I40E_AQC_ADD_CLOUD_TNL_TYPE_NVGRE_OMAC		1
-#define I40E_AQC_ADD_CLOUD_TNL_TYPE_NGE			2
+#define I40E_AQC_ADD_CLOUD_TNL_TYPE_GENEVE		2
 #define I40E_AQC_ADD_CLOUD_TNL_TYPE_IP			3
+#define I40E_AQC_ADD_CLOUD_TNL_TYPE_RESERVED		4
+#define I40E_AQC_ADD_CLOUD_TNL_TYPE_VXLAN_GPE		5
+
+#define I40E_AQC_ADD_CLOUD_FLAGS_SHARED_OUTER_MAC	0x2000
+#define I40E_AQC_ADD_CLOUD_FLAGS_SHARED_INNER_MAC	0x4000
+#define I40E_AQC_ADD_CLOUD_FLAGS_SHARED_OUTER_IP	0x8000
 
 	__le32	tenant_id;
 	u8	reserved[4];
@@ -1754,7 +1796,12 @@ struct i40e_aqc_get_link_status {
 	u8	config;
 #define I40E_AQ_CONFIG_CRC_ENA		0x04
 #define I40E_AQ_CONFIG_PACING_MASK	0x78
-	u8	reserved[5];
+	u8	external_power_ability;
+#define I40E_AQ_LINK_POWER_CLASS_1	0x00
+#define I40E_AQ_LINK_POWER_CLASS_2	0x01
+#define I40E_AQ_LINK_POWER_CLASS_3	0x02
+#define I40E_AQ_LINK_POWER_CLASS_4	0x03
+	u8	reserved[4];
 };
 
 I40E_CHECK_CMD_LENGTH(i40e_aqc_get_link_status);
@@ -1822,6 +1869,18 @@ enum i40e_aq_phy_reg_type {
 	I40E_AQC_PHY_REG_EXERNAL_MODULE	= 0x3
 };
 
+/* Run PHY Activity (0x0626) */
+struct i40e_aqc_run_phy_activity {
+	__le16  activity_id;
+	u8      flags;
+	u8      reserved1;
+	__le32  control;
+	__le32  data;
+	u8      reserved2[4];
+};
+
+I40E_CHECK_CMD_LENGTH(i40e_aqc_run_phy_activity);
+
 /* NVM Read command (indirect 0x0701)
  * NVM Erase commands (direct 0x0702)
  * NVM Update commands (indirect 0x0703)
@@ -1891,6 +1950,42 @@ struct i40e_aqc_nvm_config_data_immediat
 
 I40E_CHECK_STRUCT_LEN(0xc, i40e_aqc_nvm_config_data_immediate_field);
 
+/* OEM Post Update (indirect 0x0720)
+ * no command data struct used
+ */
+struct i40e_aqc_nvm_oem_post_update {
+#define I40E_AQ_NVM_OEM_POST_UPDATE_EXTERNAL_DATA	0x01
+	u8 sel_data;
+	u8 reserved[7];
+};
+
+I40E_CHECK_STRUCT_LEN(0x8, i40e_aqc_nvm_oem_post_update);
+
+struct i40e_aqc_nvm_oem_post_update_buffer {
+	u8 str_len;
+	u8 dev_addr;
+	__le16 eeprom_addr;
+	u8 data[36];
+};
+
+I40E_CHECK_STRUCT_LEN(0x28, i40e_aqc_nvm_oem_post_update_buffer);
+
+/* Thermal Sensor (indirect 0x0721)
+ *     read or set thermal sensor configs and values
+ *     takes a sensor and command specific data buffer, not detailed here
+ */
+struct i40e_aqc_thermal_sensor {
+	u8 sensor_action;
+#define I40E_AQ_THERMAL_SENSOR_READ_CONFIG	0
+#define I40E_AQ_THERMAL_SENSOR_SET_CONFIG	1
+#define I40E_AQ_THERMAL_SENSOR_READ_TEMP	2
+	u8 reserved[7];
+	__le32	addr_high;
+	__le32	addr_low;
+};
+
+I40E_CHECK_CMD_LENGTH(i40e_aqc_thermal_sensor);
+
 /* Send to PF command (indirect 0x0801) id is only used by PF
  * Send to VF command (indirect 0x0802) id is only used by PF
  * Send to Peer PF command (indirect 0x0803)
@@ -2170,6 +2265,7 @@ struct i40e_aqc_add_udp_tunnel {
 #define I40E_AQC_TUNNEL_TYPE_VXLAN	0x00
 #define I40E_AQC_TUNNEL_TYPE_NGE	0x01
 #define I40E_AQC_TUNNEL_TYPE_TEREDO	0x10
+#define I40E_AQC_TUNNEL_TYPE_VXLAN_GPE	0x11
 	u8	reserved1[10];
 };
 
@@ -2403,4 +2499,4 @@ struct i40e_aqc_debug_modify_internals {
 
 I40E_CHECK_CMD_LENGTH(i40e_aqc_debug_modify_internals);
 
-#endif
+#endif /* _I40E_ADMINQ_CMD_H_ */
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/intel/i40e/i40e_common.c
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/intel/i40e/i40e_common.c
@@ -1,7 +1,7 @@
 /*******************************************************************************
  *
  * Intel Ethernet Controller XL710 Family Linux Driver
- * Copyright(c) 2013 - 2015 Intel Corporation.
+ * Copyright(c) 2013 - 2016 Intel Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms and conditions of the GNU General Public License,
@@ -44,7 +44,6 @@ static i40e_status i40e_set_mac_type(str
 		switch (hw->device_id) {
 		case I40E_DEV_ID_SFP_XL710:
 		case I40E_DEV_ID_QEMU:
-		case I40E_DEV_ID_KX_A:
 		case I40E_DEV_ID_KX_B:
 		case I40E_DEV_ID_KX_C:
 		case I40E_DEV_ID_QSFP_A:
@@ -56,19 +55,13 @@ static i40e_status i40e_set_mac_type(str
 		case I40E_DEV_ID_20G_KR2_A:
 			hw->mac.type = I40E_MAC_XL710;
 			break;
+		case I40E_DEV_ID_KX_X722:
+		case I40E_DEV_ID_QSFP_X722:
 		case I40E_DEV_ID_SFP_X722:
 		case I40E_DEV_ID_1G_BASE_T_X722:
 		case I40E_DEV_ID_10G_BASE_T_X722:
 			hw->mac.type = I40E_MAC_X722;
 			break;
-		case I40E_DEV_ID_X722_VF:
-		case I40E_DEV_ID_X722_VF_HV:
-			hw->mac.type = I40E_MAC_X722_VF;
-			break;
-		case I40E_DEV_ID_VF:
-		case I40E_DEV_ID_VF_HV:
-			hw->mac.type = I40E_MAC_VF;
-			break;
 		default:
 			hw->mac.type = I40E_MAC_GENERIC;
 			break;
@@ -302,13 +295,15 @@ void i40e_debug_aq(struct i40e_hw *hw, e
 		   void *buffer, u16 buf_len)
 {
 	struct i40e_aq_desc *aq_desc = (struct i40e_aq_desc *)desc;
-	u16 len = le16_to_cpu(aq_desc->datalen);
+	u16 len;
 	u8 *buf = (u8 *)buffer;
 	u16 i = 0;
 
 	if ((!(mask & hw->debug_mask)) || (desc == NULL))
 		return;
 
+	len = le16_to_cpu(aq_desc->datalen);
+
 	i40e_debug(hw, mask,
 		   "AQ CMD: opcode 0x%04X, flags 0x%04X, datalen 0x%04X, retval 0x%04X\n",
 		   le16_to_cpu(aq_desc->opcode),
@@ -1246,7 +1241,13 @@ i40e_status i40e_pf_reset(struct i40e_hw
 	grst_del = (rd32(hw, I40E_GLGEN_RSTCTL) &
 		    I40E_GLGEN_RSTCTL_GRSTDEL_MASK) >>
 		    I40E_GLGEN_RSTCTL_GRSTDEL_SHIFT;
-	for (cnt = 0; cnt < grst_del + 10; cnt++) {
+
+	/* It can take upto 15 secs for GRST steady state.
+	 * Bump it to 16 secs max to be safe.
+	 */
+	grst_del = grst_del * 20;
+
+	for (cnt = 0; cnt < grst_del; cnt++) {
 		reg = rd32(hw, I40E_GLGEN_RSTAT);
 		if (!(reg & I40E_GLGEN_RSTAT_DEVSTATE_MASK))
 			break;
@@ -1895,6 +1896,32 @@ i40e_status i40e_aq_set_phy_int_mask(str
 }
 
 /**
+ * i40e_aq_set_phy_debug
+ * @hw: pointer to the hw struct
+ * @cmd_flags: debug command flags
+ * @cmd_details: pointer to command details structure or NULL
+ *
+ * Reset the external PHY.
+ **/
+enum i40e_status_code i40e_aq_set_phy_debug(struct i40e_hw *hw, u8 cmd_flags,
+					struct i40e_asq_cmd_details *cmd_details)
+{
+	struct i40e_aq_desc desc;
+	struct i40e_aqc_set_phy_debug *cmd =
+		(struct i40e_aqc_set_phy_debug *)&desc.params.raw;
+	enum i40e_status_code status;
+
+	i40e_fill_default_direct_cmd_desc(&desc,
+					  i40e_aqc_opc_set_phy_debug);
+
+	cmd->command_flags = cmd_flags;
+
+	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
+
+	return status;
+}
+
+/**
  * i40e_aq_add_vsi
  * @hw: pointer to the hw struct
  * @vsi_ctx: pointer to a vsi context struct
@@ -1959,12 +1986,19 @@ i40e_status i40e_aq_set_vsi_unicast_prom
 	i40e_fill_default_direct_cmd_desc(&desc,
 					i40e_aqc_opc_set_vsi_promiscuous_modes);
 
-	if (set)
+	if (set) {
 		flags |= I40E_AQC_SET_VSI_PROMISC_UNICAST;
+		if (((hw->aq.api_maj_ver == 1) && (hw->aq.api_min_ver >= 5)) ||
+		    (hw->aq.api_maj_ver > 1))
+			flags |= I40E_AQC_SET_VSI_PROMISC_TX;
+	}
 
 	cmd->promiscuous_flags = cpu_to_le16(flags);
 
 	cmd->valid_flags = cpu_to_le16(I40E_AQC_SET_VSI_PROMISC_UNICAST);
+	if (((hw->aq.api_maj_ver >= 1) && (hw->aq.api_min_ver >= 5)) ||
+	    (hw->aq.api_maj_ver > 1))
+		cmd->valid_flags |= cpu_to_le16(I40E_AQC_SET_VSI_PROMISC_TX);
 
 	cmd->seid = cpu_to_le16(seid);
 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
@@ -2040,6 +2074,37 @@ i40e_status i40e_aq_set_vsi_broadcast(st
 }
 
 /**
+ * i40e_aq_set_vsi_vlan_promisc - control the VLAN promiscuous setting
+ * @hw: pointer to the hw struct
+ * @seid: vsi number
+ * @enable: set MAC L2 layer unicast promiscuous enable/disable for a given VLAN
+ * @cmd_details: pointer to command details structure or NULL
+ **/
+i40e_status i40e_aq_set_vsi_vlan_promisc(struct i40e_hw *hw,
+				       u16 seid, bool enable,
+				       struct i40e_asq_cmd_details *cmd_details)
+{
+	struct i40e_aq_desc desc;
+	struct i40e_aqc_set_vsi_promiscuous_modes *cmd =
+		(struct i40e_aqc_set_vsi_promiscuous_modes *)&desc.params.raw;
+	i40e_status status;
+	u16 flags = 0;
+
+	i40e_fill_default_direct_cmd_desc(&desc,
+					i40e_aqc_opc_set_vsi_promiscuous_modes);
+	if (enable)
+		flags |= I40E_AQC_SET_VSI_PROMISC_VLAN;
+
+	cmd->promiscuous_flags = cpu_to_le16(flags);
+	cmd->valid_flags = cpu_to_le16(I40E_AQC_SET_VSI_PROMISC_VLAN);
+	cmd->seid = cpu_to_le16(seid);
+
+	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
+
+	return status;
+}
+
+/**
  * i40e_get_vsi_params - get VSI configuration info
  * @hw: pointer to the hw struct
  * @vsi_ctx: pointer to a vsi context struct
@@ -2284,8 +2349,8 @@ i40e_status i40e_update_link_info(struct
  * @downlink_seid: the VSI SEID
  * @enabled_tc: bitmap of TCs to be enabled
  * @default_port: true for default port VSI, false for control port
- * @enable_l2_filtering: true to add L2 filter table rules to regular forwarding rules for cloud support
  * @veb_seid: pointer to where to put the resulting VEB SEID
+ * @enable_stats: true to turn on VEB stats
  * @cmd_details: pointer to command details structure or NULL
  *
  * This asks the FW to add a VEB between the uplink and downlink
@@ -2293,8 +2358,8 @@ i40e_status i40e_update_link_info(struct
  **/
 i40e_status i40e_aq_add_veb(struct i40e_hw *hw, u16 uplink_seid,
 				u16 downlink_seid, u8 enabled_tc,
-				bool default_port, bool enable_l2_filtering,
-				u16 *veb_seid,
+				bool default_port, u16 *veb_seid,
+				bool enable_stats,
 				struct i40e_asq_cmd_details *cmd_details)
 {
 	struct i40e_aq_desc desc;
@@ -2321,8 +2386,9 @@ i40e_status i40e_aq_add_veb(struct i40e_
 	else
 		veb_flags |= I40E_AQC_ADD_VEB_PORT_TYPE_DATA;
 
-	if (enable_l2_filtering)
-		veb_flags |= I40E_AQC_ADD_VEB_ENABLE_L2_FILTER;
+	/* reverse logic here: set the bitflag to disable the stats */
+	if (!enable_stats)
+		veb_flags |= I40E_AQC_ADD_VEB_ENABLE_DISABLE_STATS;
 
 	cmd->veb_flags = cpu_to_le16(veb_flags);
 
@@ -2411,6 +2477,7 @@ i40e_status i40e_aq_add_macvlan(struct i
 		(struct i40e_aqc_macvlan *)&desc.params.raw;
 	i40e_status status;
 	u16 buf_size;
+	int i;
 
 	if (count == 0 || !mv_list || !hw)
 		return I40E_ERR_PARAM;
@@ -2424,12 +2491,17 @@ i40e_status i40e_aq_add_macvlan(struct i
 	cmd->seid[1] = 0;
 	cmd->seid[2] = 0;
 
+	for (i = 0; i < count; i++)
+		if (is_multicast_ether_addr(mv_list[i].mac_addr))
+			mv_list[i].flags |=
+			       cpu_to_le16(I40E_AQC_MACVLAN_ADD_USE_SHARED_MAC);
+
 	desc.flags |= cpu_to_le16((u16)(I40E_AQ_FLAG_BUF | I40E_AQ_FLAG_RD));
 	if (buf_size > I40E_AQ_LARGE_BUF)
 		desc.flags |= cpu_to_le16((u16)I40E_AQ_FLAG_LB);
 
 	status = i40e_asq_send_command(hw, &desc, mv_list, buf_size,
-				    cmd_details);
+				       cmd_details);
 
 	return status;
 }
@@ -2477,6 +2549,137 @@ i40e_status i40e_aq_remove_macvlan(struc
 }
 
 /**
+ * i40e_mirrorrule_op - Internal helper function to add/delete mirror rule
+ * @hw: pointer to the hw struct
+ * @opcode: AQ opcode for add or delete mirror rule
+ * @sw_seid: Switch SEID (to which rule refers)
+ * @rule_type: Rule Type (ingress/egress/VLAN)
+ * @id: Destination VSI SEID or Rule ID
+ * @count: length of the list
+ * @mr_list: list of mirrored VSI SEIDs or VLAN IDs
+ * @cmd_details: pointer to command details structure or NULL
+ * @rule_id: Rule ID returned from FW
+ * @rule_used: Number of rules used in internal switch
+ * @rule_free: Number of rules free in internal switch
+ *
+ * Add/Delete a mirror rule to a specific switch. Mirror rules are supported for
+ * VEBs/VEPA elements only
+ **/
+static i40e_status i40e_mirrorrule_op(struct i40e_hw *hw,
+				u16 opcode, u16 sw_seid, u16 rule_type, u16 id,
+				u16 count, __le16 *mr_list,
+				struct i40e_asq_cmd_details *cmd_details,
+				u16 *rule_id, u16 *rules_used, u16 *rules_free)
+{
+	struct i40e_aq_desc desc;
+	struct i40e_aqc_add_delete_mirror_rule *cmd =
+		(struct i40e_aqc_add_delete_mirror_rule *)&desc.params.raw;
+	struct i40e_aqc_add_delete_mirror_rule_completion *resp =
+	(struct i40e_aqc_add_delete_mirror_rule_completion *)&desc.params.raw;
+	i40e_status status;
+	u16 buf_size;
+
+	buf_size = count * sizeof(*mr_list);
+
+	/* prep the rest of the request */
+	i40e_fill_default_direct_cmd_desc(&desc, opcode);
+	cmd->seid = cpu_to_le16(sw_seid);
+	cmd->rule_type = cpu_to_le16(rule_type &
+				     I40E_AQC_MIRROR_RULE_TYPE_MASK);
+	cmd->num_entries = cpu_to_le16(count);
+	/* Dest VSI for add, rule_id for delete */
+	cmd->destination = cpu_to_le16(id);
+	if (mr_list) {
+		desc.flags |= cpu_to_le16((u16)(I40E_AQ_FLAG_BUF |
+						I40E_AQ_FLAG_RD));
+		if (buf_size > I40E_AQ_LARGE_BUF)
+			desc.flags |= cpu_to_le16((u16)I40E_AQ_FLAG_LB);
+	}
+
+	status = i40e_asq_send_command(hw, &desc, mr_list, buf_size,
+				       cmd_details);
+	if (!status ||
+	    hw->aq.asq_last_status == I40E_AQ_RC_ENOSPC) {
+		if (rule_id)
+			*rule_id = le16_to_cpu(resp->rule_id);
+		if (rules_used)
+			*rules_used = le16_to_cpu(resp->mirror_rules_used);
+		if (rules_free)
+			*rules_free = le16_to_cpu(resp->mirror_rules_free);
+	}
+	return status;
+}
+
+/**
+ * i40e_aq_add_mirrorrule - add a mirror rule
+ * @hw: pointer to the hw struct
+ * @sw_seid: Switch SEID (to which rule refers)
+ * @rule_type: Rule Type (ingress/egress/VLAN)
+ * @dest_vsi: SEID of VSI to which packets will be mirrored
+ * @count: length of the list
+ * @mr_list: list of mirrored VSI SEIDs or VLAN IDs
+ * @cmd_details: pointer to command details structure or NULL
+ * @rule_id: Rule ID returned from FW
+ * @rule_used: Number of rules used in internal switch
+ * @rule_free: Number of rules free in internal switch
+ *
+ * Add mirror rule. Mirror rules are supported for VEBs or VEPA elements only
+ **/
+i40e_status i40e_aq_add_mirrorrule(struct i40e_hw *hw, u16 sw_seid,
+			u16 rule_type, u16 dest_vsi, u16 count, __le16 *mr_list,
+			struct i40e_asq_cmd_details *cmd_details,
+			u16 *rule_id, u16 *rules_used, u16 *rules_free)
+{
+	if (!(rule_type == I40E_AQC_MIRROR_RULE_TYPE_ALL_INGRESS ||
+	    rule_type == I40E_AQC_MIRROR_RULE_TYPE_ALL_EGRESS)) {
+		if (count == 0 || !mr_list)
+			return I40E_ERR_PARAM;
+	}
+
+	return i40e_mirrorrule_op(hw, i40e_aqc_opc_add_mirror_rule, sw_seid,
+				  rule_type, dest_vsi, count, mr_list,
+				  cmd_details, rule_id, rules_used, rules_free);
+}
+
+/**
+ * i40e_aq_delete_mirrorrule - delete a mirror rule
+ * @hw: pointer to the hw struct
+ * @sw_seid: Switch SEID (to which rule refers)
+ * @rule_type: Rule Type (ingress/egress/VLAN)
+ * @count: length of the list
+ * @rule_id: Rule ID that is returned in the receive desc as part of
+ *		add_mirrorrule.
+ * @mr_list: list of mirrored VLAN IDs to be removed
+ * @cmd_details: pointer to command details structure or NULL
+ * @rule_used: Number of rules used in internal switch
+ * @rule_free: Number of rules free in internal switch
+ *
+ * Delete a mirror rule. Mirror rules are supported for VEBs/VEPA elements only
+ **/
+i40e_status i40e_aq_delete_mirrorrule(struct i40e_hw *hw, u16 sw_seid,
+			u16 rule_type, u16 rule_id, u16 count, __le16 *mr_list,
+			struct i40e_asq_cmd_details *cmd_details,
+			u16 *rules_used, u16 *rules_free)
+{
+	/* Rule ID has to be valid except rule_type: INGRESS VLAN mirroring */
+	if (rule_type != I40E_AQC_MIRROR_RULE_TYPE_VLAN) {
+		if (!rule_id)
+			return I40E_ERR_PARAM;
+	} else {
+		/* count and mr_list shall be valid for rule_type INGRESS VLAN
+		 * mirroring. For other rule_type, count and rule_type should
+		 * not matter.
+		 */
+		if (count == 0 || !mr_list)
+			return I40E_ERR_PARAM;
+	}
+
+	return i40e_mirrorrule_op(hw, i40e_aqc_opc_delete_mirror_rule, sw_seid,
+				  rule_type, rule_id, count, mr_list,
+				  cmd_details, NULL, rules_used, rules_free);
+}
+
+/**
  * i40e_aq_send_msg_to_vf
  * @hw: pointer to the hardware structure
  * @vfid: VF id to send msg
@@ -2766,35 +2969,6 @@ i40e_aq_erase_nvm_exit:
 	return status;
 }
 
-#define I40E_DEV_FUNC_CAP_SWITCH_MODE	0x01
-#define I40E_DEV_FUNC_CAP_MGMT_MODE	0x02
-#define I40E_DEV_FUNC_CAP_NPAR		0x03
-#define I40E_DEV_FUNC_CAP_OS2BMC	0x04
-#define I40E_DEV_FUNC_CAP_VALID_FUNC	0x05
-#define I40E_DEV_FUNC_CAP_SRIOV_1_1	0x12
-#define I40E_DEV_FUNC_CAP_VF		0x13
-#define I40E_DEV_FUNC_CAP_VMDQ		0x14
-#define I40E_DEV_FUNC_CAP_802_1_QBG	0x15
-#define I40E_DEV_FUNC_CAP_802_1_QBH	0x16
-#define I40E_DEV_FUNC_CAP_VSI		0x17
-#define I40E_DEV_FUNC_CAP_DCB		0x18
-#define I40E_DEV_FUNC_CAP_FCOE		0x21
-#define I40E_DEV_FUNC_CAP_ISCSI		0x22
-#define I40E_DEV_FUNC_CAP_RSS		0x40
-#define I40E_DEV_FUNC_CAP_RX_QUEUES	0x41
-#define I40E_DEV_FUNC_CAP_TX_QUEUES	0x42
-#define I40E_DEV_FUNC_CAP_MSIX		0x43
-#define I40E_DEV_FUNC_CAP_MSIX_VF	0x44
-#define I40E_DEV_FUNC_CAP_FLOW_DIRECTOR	0x45
-#define I40E_DEV_FUNC_CAP_IEEE_1588	0x46
-#define I40E_DEV_FUNC_CAP_FLEX10	0xF1
-#define I40E_DEV_FUNC_CAP_CEM		0xF2
-#define I40E_DEV_FUNC_CAP_IWARP		0x51
-#define I40E_DEV_FUNC_CAP_LED		0x61
-#define I40E_DEV_FUNC_CAP_SDP		0x62
-#define I40E_DEV_FUNC_CAP_MDIO		0x63
-#define I40E_DEV_FUNC_CAP_WR_CSR_PROT	0x64
-
 /**
  * i40e_parse_discover_capabilities
  * @hw: pointer to the hw struct
@@ -2833,79 +3007,79 @@ static void i40e_parse_discover_capabili
 		major_rev = cap->major_rev;
 
 		switch (id) {
-		case I40E_DEV_FUNC_CAP_SWITCH_MODE:
+		case I40E_AQ_CAP_ID_SWITCH_MODE:
 			p->switch_mode = number;
 			break;
-		case I40E_DEV_FUNC_CAP_MGMT_MODE:
+		case I40E_AQ_CAP_ID_MNG_MODE:
 			p->management_mode = number;
 			break;
-		case I40E_DEV_FUNC_CAP_NPAR:
+		case I40E_AQ_CAP_ID_NPAR_ACTIVE:
 			p->npar_enable = number;
 			break;
-		case I40E_DEV_FUNC_CAP_OS2BMC:
+		case I40E_AQ_CAP_ID_OS2BMC_CAP:
 			p->os2bmc = number;
 			break;
-		case I40E_DEV_FUNC_CAP_VALID_FUNC:
+		case I40E_AQ_CAP_ID_FUNCTIONS_VALID:
 			p->valid_functions = number;
 			break;
-		case I40E_DEV_FUNC_CAP_SRIOV_1_1:
+		case I40E_AQ_CAP_ID_SRIOV:
 			if (number == 1)
 				p->sr_iov_1_1 = true;
 			break;
-		case I40E_DEV_FUNC_CAP_VF:
+		case I40E_AQ_CAP_ID_VF:
 			p->num_vfs = number;
 			p->vf_base_id = logical_id;
 			break;
-		case I40E_DEV_FUNC_CAP_VMDQ:
+		case I40E_AQ_CAP_ID_VMDQ:
 			if (number == 1)
 				p->vmdq = true;
 			break;
-		case I40E_DEV_FUNC_CAP_802_1_QBG:
+		case I40E_AQ_CAP_ID_8021QBG:
 			if (number == 1)
 				p->evb_802_1_qbg = true;
 			break;
-		case I40E_DEV_FUNC_CAP_802_1_QBH:
+		case I40E_AQ_CAP_ID_8021QBR:
 			if (number == 1)
 				p->evb_802_1_qbh = true;
 			break;
-		case I40E_DEV_FUNC_CAP_VSI:
+		case I40E_AQ_CAP_ID_VSI:
 			p->num_vsis = number;
 			break;
-		case I40E_DEV_FUNC_CAP_DCB:
+		case I40E_AQ_CAP_ID_DCB:
 			if (number == 1) {
 				p->dcb = true;
 				p->enabled_tcmap = logical_id;
 				p->maxtc = phys_id;
 			}
 			break;
-		case I40E_DEV_FUNC_CAP_FCOE:
+		case I40E_AQ_CAP_ID_FCOE:
 			if (number == 1)
 				p->fcoe = true;
 			break;
-		case I40E_DEV_FUNC_CAP_ISCSI:
+		case I40E_AQ_CAP_ID_ISCSI:
 			if (number == 1)
 				p->iscsi = true;
 			break;
-		case I40E_DEV_FUNC_CAP_RSS:
+		case I40E_AQ_CAP_ID_RSS:
 			p->rss = true;
 			p->rss_table_size = number;
 			p->rss_table_entry_width = logical_id;
 			break;
-		case I40E_DEV_FUNC_CAP_RX_QUEUES:
+		case I40E_AQ_CAP_ID_RXQ:
 			p->num_rx_qp = number;
 			p->base_queue = phys_id;
 			break;
-		case I40E_DEV_FUNC_CAP_TX_QUEUES:
+		case I40E_AQ_CAP_ID_TXQ:
 			p->num_tx_qp = number;
 			p->base_queue = phys_id;
 			break;
-		case I40E_DEV_FUNC_CAP_MSIX:
+		case I40E_AQ_CAP_ID_MSIX:
 			p->num_msix_vectors = number;
 			break;
-		case I40E_DEV_FUNC_CAP_MSIX_VF:
+		case I40E_AQ_CAP_ID_VF_MSIX:
 			p->num_msix_vectors_vf = number;
 			break;
-		case I40E_DEV_FUNC_CAP_FLEX10:
+		case I40E_AQ_CAP_ID_FLEX10:
 			if (major_rev == 1) {
 				if (number == 1) {
 					p->flex10_enable = true;
@@ -2921,38 +3095,38 @@ static void i40e_parse_discover_capabili
 			p->flex10_mode = logical_id;
 			p->flex10_status = phys_id;
 			break;
-		case I40E_DEV_FUNC_CAP_CEM:
+		case I40E_AQ_CAP_ID_CEM:
 			if (number == 1)
 				p->mgmt_cem = true;
 			break;
-		case I40E_DEV_FUNC_CAP_IWARP:
+		case I40E_AQ_CAP_ID_IWARP:
 			if (number == 1)
 				p->iwarp = true;
 			break;
-		case I40E_DEV_FUNC_CAP_LED:
+		case I40E_AQ_CAP_ID_LED:
 			if (phys_id < I40E_HW_CAP_MAX_GPIO)
 				p->led[phys_id] = true;
 			break;
-		case I40E_DEV_FUNC_CAP_SDP:
+		case I40E_AQ_CAP_ID_SDP:
 			if (phys_id < I40E_HW_CAP_MAX_GPIO)
 				p->sdp[phys_id] = true;
 			break;
-		case I40E_DEV_FUNC_CAP_MDIO:
+		case I40E_AQ_CAP_ID_MDIO:
 			if (number == 1) {
 				p->mdio_port_num = phys_id;
 				p->mdio_port_mode = logical_id;
 			}
 			break;
-		case I40E_DEV_FUNC_CAP_IEEE_1588:
+		case I40E_AQ_CAP_ID_1588:
 			if (number == 1)
 				p->ieee_1588 = true;
 			break;
-		case I40E_DEV_FUNC_CAP_FLOW_DIRECTOR:
+		case I40E_AQ_CAP_ID_FLOW_DIRECTOR:
 			p->fd = true;
 			p->fd_filters_guaranteed = number;
 			p->fd_filters_best_effort = logical_id;
 			break;
-		case I40E_DEV_FUNC_CAP_WR_CSR_PROT:
+		case I40E_AQ_CAP_ID_WSR_PROT:
 			p->wr_csr_prot = (u64)number;
 			p->wr_csr_prot |= (u64)logical_id << 32;
 			break;
@@ -3710,7 +3884,7 @@ i40e_status i40e_set_filter_control(stru
 		return ret;
 
 	/* Read the PF Queue Filter control register */
-	val = rd32(hw, I40E_PFQF_CTL_0);
+	val = i40e_read_rx_ctl(hw, I40E_PFQF_CTL_0);
 
 	/* Program required PE hash buckets for the PF */
 	val &= ~I40E_PFQF_CTL_0_PEHSIZE_MASK;
@@ -3747,7 +3921,7 @@ i40e_status i40e_set_filter_control(stru
 	if (settings->enable_macvlan)
 		val |= I40E_PFQF_CTL_0_MACVLAN_ENA_MASK;
 
-	wr32(hw, I40E_PFQF_CTL_0, val);
+	i40e_write_rx_ctl(hw, I40E_PFQF_CTL_0, val);
 
 	return 0;
 }
@@ -4074,3 +4248,454 @@ i40e_status i40e_aq_configure_partition_
 
 	return status;
 }
+
+/**
+ * i40e_read_phy_register
+ * @hw: pointer to the HW structure
+ * @page: registers page number
+ * @reg: register address in the page
+ * @phy_adr: PHY address on MDIO interface
+ * @value: PHY register value
+ *
+ * Reads specified PHY register value
+ **/
+i40e_status i40e_read_phy_register(struct i40e_hw *hw,
+				   u8 page, u16 reg, u8 phy_addr,
+				   u16 *value)
+{
+	i40e_status status = I40E_ERR_TIMEOUT;
+	u32 command = 0;
+	u16 retry = 1000;
+	u8 port_num = hw->func_caps.mdio_port_num;
+
+	command = (reg << I40E_GLGEN_MSCA_MDIADD_SHIFT) |
+		  (page << I40E_GLGEN_MSCA_DEVADD_SHIFT) |
+		  (phy_addr << I40E_GLGEN_MSCA_PHYADD_SHIFT) |
+		  (I40E_MDIO_OPCODE_ADDRESS) |
+		  (I40E_MDIO_STCODE) |
+		  (I40E_GLGEN_MSCA_MDICMD_MASK) |
+		  (I40E_GLGEN_MSCA_MDIINPROGEN_MASK);
+	wr32(hw, I40E_GLGEN_MSCA(port_num), command);
+	do {
+		command = rd32(hw, I40E_GLGEN_MSCA(port_num));
+		if (!(command & I40E_GLGEN_MSCA_MDICMD_MASK)) {
+			status = 0;
+			break;
+		}
+		usleep_range(10, 20);
+		retry--;
+	} while (retry);
+
+	if (status) {
+		i40e_debug(hw, I40E_DEBUG_PHY,
+			   "PHY: Can't write command to external PHY.\n");
+		goto phy_read_end;
+	}
+
+	command = (page << I40E_GLGEN_MSCA_DEVADD_SHIFT) |
+		  (phy_addr << I40E_GLGEN_MSCA_PHYADD_SHIFT) |
+		  (I40E_MDIO_OPCODE_READ) |
+		  (I40E_MDIO_STCODE) |
+		  (I40E_GLGEN_MSCA_MDICMD_MASK) |
+		  (I40E_GLGEN_MSCA_MDIINPROGEN_MASK);
+	status = I40E_ERR_TIMEOUT;
+	retry = 1000;
+	wr32(hw, I40E_GLGEN_MSCA(port_num), command);
+	do {
+		command = rd32(hw, I40E_GLGEN_MSCA(port_num));
+		if (!(command & I40E_GLGEN_MSCA_MDICMD_MASK)) {
+			status = 0;
+			break;
+		}
+		usleep_range(10, 20);
+		retry--;
+	} while (retry);
+
+	if (!status) {
+		command = rd32(hw, I40E_GLGEN_MSRWD(port_num));
+		*value = (command & I40E_GLGEN_MSRWD_MDIRDDATA_MASK) >>
+			 I40E_GLGEN_MSRWD_MDIRDDATA_SHIFT;
+	} else {
+		i40e_debug(hw, I40E_DEBUG_PHY,
+			   "PHY: Can't read register value from external PHY.\n");
+	}
+
+phy_read_end:
+	return status;
+}
+
+/**
+ * i40e_write_phy_register
+ * @hw: pointer to the HW structure
+ * @page: registers page number
+ * @reg: register address in the page
+ * @phy_adr: PHY address on MDIO interface
+ * @value: PHY register value
+ *
+ * Writes value to specified PHY register
+ **/
+i40e_status i40e_write_phy_register(struct i40e_hw *hw,
+				    u8 page, u16 reg, u8 phy_addr,
+				    u16 value)
+{
+	i40e_status status = I40E_ERR_TIMEOUT;
+	u32 command = 0;
+	u16 retry = 1000;
+	u8 port_num = hw->func_caps.mdio_port_num;
+
+	command = (reg << I40E_GLGEN_MSCA_MDIADD_SHIFT) |
+		  (page << I40E_GLGEN_MSCA_DEVADD_SHIFT) |
+		  (phy_addr << I40E_GLGEN_MSCA_PHYADD_SHIFT) |
+		  (I40E_MDIO_OPCODE_ADDRESS) |
+		  (I40E_MDIO_STCODE) |
+		  (I40E_GLGEN_MSCA_MDICMD_MASK) |
+		  (I40E_GLGEN_MSCA_MDIINPROGEN_MASK);
+	wr32(hw, I40E_GLGEN_MSCA(port_num), command);
+	do {
+		command = rd32(hw, I40E_GLGEN_MSCA(port_num));
+		if (!(command & I40E_GLGEN_MSCA_MDICMD_MASK)) {
+			status = 0;
+			break;
+		}
+		usleep_range(10, 20);
+		retry--;
+	} while (retry);
+	if (status) {
+		i40e_debug(hw, I40E_DEBUG_PHY,
+			   "PHY: Can't write command to external PHY.\n");
+		goto phy_write_end;
+	}
+
+	command = value << I40E_GLGEN_MSRWD_MDIWRDATA_SHIFT;
+	wr32(hw, I40E_GLGEN_MSRWD(port_num), command);
+
+	command = (page << I40E_GLGEN_MSCA_DEVADD_SHIFT) |
+		  (phy_addr << I40E_GLGEN_MSCA_PHYADD_SHIFT) |
+		  (I40E_MDIO_OPCODE_WRITE) |
+		  (I40E_MDIO_STCODE) |
+		  (I40E_GLGEN_MSCA_MDICMD_MASK) |
+		  (I40E_GLGEN_MSCA_MDIINPROGEN_MASK);
+	status = I40E_ERR_TIMEOUT;
+	retry = 1000;
+	wr32(hw, I40E_GLGEN_MSCA(port_num), command);
+	do {
+		command = rd32(hw, I40E_GLGEN_MSCA(port_num));
+		if (!(command & I40E_GLGEN_MSCA_MDICMD_MASK)) {
+			status = 0;
+			break;
+		}
+		usleep_range(10, 20);
+		retry--;
+	} while (retry);
+
+phy_write_end:
+	return status;
+}
+
+/**
+ * i40e_get_phy_address
+ * @hw: pointer to the HW structure
+ * @dev_num: PHY port num that address we want
+ * @phy_addr: Returned PHY address
+ *
+ * Gets PHY address for current port
+ **/
+u8 i40e_get_phy_address(struct i40e_hw *hw, u8 dev_num)
+{
+	u8 port_num = hw->func_caps.mdio_port_num;
+	u32 reg_val = rd32(hw, I40E_GLGEN_MDIO_I2C_SEL(port_num));
+
+	return (u8)(reg_val >> ((dev_num + 1) * 5)) & 0x1f;
+}
+
+/**
+ * i40e_blink_phy_led
+ * @hw: pointer to the HW structure
+ * @time: time how long led will blinks in secs
+ * @interval: gap between LED on and off in msecs
+ *
+ * Blinks PHY link LED
+ **/
+i40e_status i40e_blink_phy_link_led(struct i40e_hw *hw,
+				    u32 time, u32 interval)
+{
+	i40e_status status = 0;
+	u32 i;
+	u16 led_ctl;
+	u16 gpio_led_port;
+	u16 led_reg;
+	u16 led_addr = I40E_PHY_LED_PROV_REG_1;
+	u8 phy_addr = 0;
+	u8 port_num;
+
+	i = rd32(hw, I40E_PFGEN_PORTNUM);
+	port_num = (u8)(i & I40E_PFGEN_PORTNUM_PORT_NUM_MASK);
+	phy_addr = i40e_get_phy_address(hw, port_num);
+
+	for (gpio_led_port = 0; gpio_led_port < 3; gpio_led_port++,
+	     led_addr++) {
+		status = i40e_read_phy_register(hw, I40E_PHY_COM_REG_PAGE,
+						led_addr, phy_addr, &led_reg);
+		if (status)
+			goto phy_blinking_end;
+		led_ctl = led_reg;
+		if (led_reg & I40E_PHY_LED_LINK_MODE_MASK) {
+			led_reg = 0;
+			status = i40e_write_phy_register(hw,
+							 I40E_PHY_COM_REG_PAGE,
+							 led_addr, phy_addr,
+							 led_reg);
+			if (status)
+				goto phy_blinking_end;
+			break;
+		}
+	}
+
+	if (time > 0 && interval > 0) {
+		for (i = 0; i < time * 1000; i += interval) {
+			status = i40e_read_phy_register(hw,
+							I40E_PHY_COM_REG_PAGE,
+							led_addr, phy_addr,
+							&led_reg);
+			if (status)
+				goto restore_config;
+			if (led_reg & I40E_PHY_LED_MANUAL_ON)
+				led_reg = 0;
+			else
+				led_reg = I40E_PHY_LED_MANUAL_ON;
+			status = i40e_write_phy_register(hw,
+							 I40E_PHY_COM_REG_PAGE,
+							 led_addr, phy_addr,
+							 led_reg);
+			if (status)
+				goto restore_config;
+			msleep(interval);
+		}
+	}
+
+restore_config:
+	status = i40e_write_phy_register(hw, I40E_PHY_COM_REG_PAGE, led_addr,
+					 phy_addr, led_ctl);
+
+phy_blinking_end:
+	return status;
+}
+
+/**
+ * i40e_led_get_phy - return current on/off mode
+ * @hw: pointer to the hw struct
+ * @led_addr: address of led register to use
+ * @val: original value of register to use
+ *
+ **/
+i40e_status i40e_led_get_phy(struct i40e_hw *hw, u16 *led_addr,
+			     u16 *val)
+{
+	i40e_status status = 0;
+	u16 gpio_led_port;
+	u8 phy_addr = 0;
+	u16 reg_val;
+	u16 temp_addr;
+	u8 port_num;
+	u32 i;
+
+	temp_addr = I40E_PHY_LED_PROV_REG_1;
+	i = rd32(hw, I40E_PFGEN_PORTNUM);
+	port_num = (u8)(i & I40E_PFGEN_PORTNUM_PORT_NUM_MASK);
+	phy_addr = i40e_get_phy_address(hw, port_num);
+
+	for (gpio_led_port = 0; gpio_led_port < 3; gpio_led_port++,
+	     temp_addr++) {
+		status = i40e_read_phy_register(hw, I40E_PHY_COM_REG_PAGE,
+						temp_addr, phy_addr, &reg_val);
+		if (status)
+			return status;
+		*val = reg_val;
+		if (reg_val & I40E_PHY_LED_LINK_MODE_MASK) {
+			*led_addr = temp_addr;
+			break;
+		}
+	}
+	return status;
+}
+
+/**
+ * i40e_led_set_phy
+ * @hw: pointer to the HW structure
+ * @on: true or false
+ * @mode: original val plus bit for set or ignore
+ * Set led's on or off when controlled by the PHY
+ *
+ **/
+i40e_status i40e_led_set_phy(struct i40e_hw *hw, bool on,
+			     u16 led_addr, u32 mode)
+{
+	i40e_status status = 0;
+	u16 led_ctl = 0;
+	u16 led_reg = 0;
+	u8 phy_addr = 0;
+	u8 port_num;
+	u32 i;
+
+	i = rd32(hw, I40E_PFGEN_PORTNUM);
+	port_num = (u8)(i & I40E_PFGEN_PORTNUM_PORT_NUM_MASK);
+	phy_addr = i40e_get_phy_address(hw, port_num);
+
+	status = i40e_read_phy_register(hw, I40E_PHY_COM_REG_PAGE, led_addr,
+					phy_addr, &led_reg);
+	if (status)
+		return status;
+	led_ctl = led_reg;
+	if (led_reg & I40E_PHY_LED_LINK_MODE_MASK) {
+		led_reg = 0;
+		status = i40e_write_phy_register(hw, I40E_PHY_COM_REG_PAGE,
+						 led_addr, phy_addr, led_reg);
+		if (status)
+			return status;
+	}
+	status = i40e_read_phy_register(hw, I40E_PHY_COM_REG_PAGE,
+					led_addr, phy_addr, &led_reg);
+	if (status)
+		goto restore_config;
+	if (on)
+		led_reg = I40E_PHY_LED_MANUAL_ON;
+	else
+		led_reg = 0;
+	status = i40e_write_phy_register(hw, I40E_PHY_COM_REG_PAGE,
+					 led_addr, phy_addr, led_reg);
+	if (status)
+		goto restore_config;
+	if (mode & I40E_PHY_LED_MODE_ORIG) {
+		led_ctl = (mode & I40E_PHY_LED_MODE_MASK);
+		status = i40e_write_phy_register(hw,
+						 I40E_PHY_COM_REG_PAGE,
+						 led_addr, phy_addr, led_ctl);
+	}
+	return status;
+restore_config:
+	status = i40e_write_phy_register(hw, I40E_PHY_COM_REG_PAGE, led_addr,
+					 phy_addr, led_ctl);
+	return status;
+}
+
+/**
+ * i40e_aq_rx_ctl_read_register - use FW to read from an Rx control register
+ * @hw: pointer to the hw struct
+ * @reg_addr: register address
+ * @reg_val: ptr to register value
+ * @cmd_details: pointer to command details structure or NULL
+ *
+ * Use the firmware to read the Rx control register,
+ * especially useful if the Rx unit is under heavy pressure
+ **/
+i40e_status i40e_aq_rx_ctl_read_register(struct i40e_hw *hw,
+				u32 reg_addr, u32 *reg_val,
+				struct i40e_asq_cmd_details *cmd_details)
+{
+	struct i40e_aq_desc desc;
+	struct i40e_aqc_rx_ctl_reg_read_write *cmd_resp =
+		(struct i40e_aqc_rx_ctl_reg_read_write *)&desc.params.raw;
+	i40e_status status;
+
+	if (!reg_val)
+		return I40E_ERR_PARAM;
+
+	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_rx_ctl_reg_read);
+
+	cmd_resp->address = cpu_to_le32(reg_addr);
+
+	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
+
+	if (status == 0)
+		*reg_val = le32_to_cpu(cmd_resp->value);
+
+	return status;
+}
+
+/**
+ * i40e_read_rx_ctl - read from an Rx control register
+ * @hw: pointer to the hw struct
+ * @reg_addr: register address
+ **/
+u32 i40e_read_rx_ctl(struct i40e_hw *hw, u32 reg_addr)
+{
+	i40e_status status = 0;
+	bool use_register;
+	int retry = 5;
+	u32 val = 0;
+
+	use_register = (hw->aq.api_maj_ver == 1) && (hw->aq.api_min_ver < 5);
+	if (!use_register) {
+do_retry:
+		status = i40e_aq_rx_ctl_read_register(hw, reg_addr, &val, NULL);
+		if (hw->aq.asq_last_status == I40E_AQ_RC_EAGAIN && retry) {
+			usleep_range(1000, 2000);
+			retry--;
+			goto do_retry;
+		}
+	}
+
+	/* if the AQ access failed, try the old-fashioned way */
+	if (status || use_register)
+		val = rd32(hw, reg_addr);
+
+	return val;
+}
+
+/**
+ * i40e_aq_rx_ctl_write_register
+ * @hw: pointer to the hw struct
+ * @reg_addr: register address
+ * @reg_val: register value
+ * @cmd_details: pointer to command details structure or NULL
+ *
+ * Use the firmware to write to an Rx control register,
+ * especially useful if the Rx unit is under heavy pressure
+ **/
+i40e_status i40e_aq_rx_ctl_write_register(struct i40e_hw *hw,
+				u32 reg_addr, u32 reg_val,
+				struct i40e_asq_cmd_details *cmd_details)
+{
+	struct i40e_aq_desc desc;
+	struct i40e_aqc_rx_ctl_reg_read_write *cmd =
+		(struct i40e_aqc_rx_ctl_reg_read_write *)&desc.params.raw;
+	i40e_status status;
+
+	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_rx_ctl_reg_write);
+
+	cmd->address = cpu_to_le32(reg_addr);
+	cmd->value = cpu_to_le32(reg_val);
+
+	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
+
+	return status;
+}
+
+/**
+ * i40e_write_rx_ctl - write to an Rx control register
+ * @hw: pointer to the hw struct
+ * @reg_addr: register address
+ * @reg_val: register value
+ **/
+void i40e_write_rx_ctl(struct i40e_hw *hw, u32 reg_addr, u32 reg_val)
+{
+	i40e_status status = 0;
+	bool use_register;
+	int retry = 5;
+
+	use_register = (hw->aq.api_maj_ver == 1) && (hw->aq.api_min_ver < 5);
+	if (!use_register) {
+do_retry:
+		status = i40e_aq_rx_ctl_write_register(hw, reg_addr,
+						       reg_val, NULL);
+		if (hw->aq.asq_last_status == I40E_AQ_RC_EAGAIN && retry) {
+			usleep_range(1000, 2000);
+			retry--;
+			goto do_retry;
+		}
+	}
+
+	/* if the AQ access failed, try the old-fashioned way */
+	if (status || use_register)
+		wr32(hw, reg_addr, reg_val);
+}
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/intel/i40e/i40e_dcb.c
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/intel/i40e/i40e_dcb.c
@@ -380,17 +380,20 @@ static void i40e_parse_cee_app_tlv(struc
 {
 	u16 length, typelength, offset = 0;
 	struct i40e_cee_app_prio *app;
-	u8 i, up, selector;
+	u8 i;
 
 	typelength = ntohs(tlv->hdr.typelen);
 	length = (u16)((typelength & I40E_LLDP_TLV_LEN_MASK) >>
 		       I40E_LLDP_TLV_LEN_SHIFT);
 
 	dcbcfg->numapps = length / sizeof(*app);
+
 	if (!dcbcfg->numapps)
 		return;
 
 	for (i = 0; i < dcbcfg->numapps; i++) {
+		u8 up, selector;
+
 		app = (struct i40e_cee_app_prio *)(tlv->tlvinfo + offset);
 		for (up = 0; up < I40E_MAX_USER_PRIORITY; up++) {
 			if (app->prio_map & BIT(up))
@@ -400,13 +403,17 @@ static void i40e_parse_cee_app_tlv(struc
 
 		/* Get Selector from lower 2 bits, and convert to IEEE */
 		selector = (app->upper_oui_sel & I40E_CEE_APP_SELECTOR_MASK);
-		if (selector == I40E_CEE_APP_SEL_ETHTYPE)
+		switch (selector) {
+		case I40E_CEE_APP_SEL_ETHTYPE:
 			dcbcfg->app[i].selector = I40E_APP_SEL_ETHTYPE;
-		else if (selector == I40E_CEE_APP_SEL_TCPIP)
+			break;
+		case I40E_CEE_APP_SEL_TCPIP:
 			dcbcfg->app[i].selector = I40E_APP_SEL_TCPIP;
-		else
+			break;
+		default:
 			/* Keep selector as it is for unknown types */
 			dcbcfg->app[i].selector = selector;
+		}
 
 		dcbcfg->app[i].protocolid = ntohs(app->protocol);
 		/* Move to next app */
@@ -814,13 +821,15 @@ i40e_status i40e_get_dcb_config(struct i
 	struct i40e_aqc_get_cee_dcb_cfg_resp cee_cfg;
 	struct i40e_aqc_get_cee_dcb_cfg_v1_resp cee_v1_cfg;
 
-	/* If Firmware version < v4.33 IEEE only */
-	if (((hw->aq.fw_maj_ver == 4) && (hw->aq.fw_min_ver < 33)) ||
-	    (hw->aq.fw_maj_ver < 4))
+	/* If Firmware version < v4.33 on X710/XL710, IEEE only */
+	if ((hw->mac.type == I40E_MAC_XL710) &&
+	    (((hw->aq.fw_maj_ver == 4) && (hw->aq.fw_min_ver < 33)) ||
+	      (hw->aq.fw_maj_ver < 4)))
 		return i40e_get_ieee_dcb_config(hw);
 
-	/* If Firmware version == v4.33 use old CEE struct */
-	if ((hw->aq.fw_maj_ver == 4) && (hw->aq.fw_min_ver == 33)) {
+	/* If Firmware version == v4.33 on X710/XL710, use old CEE struct */
+	if ((hw->mac.type == I40E_MAC_XL710) &&
+	    ((hw->aq.fw_maj_ver == 4) && (hw->aq.fw_min_ver == 33))) {
 		ret = i40e_aq_get_cee_dcb_config(hw, &cee_v1_cfg,
 						 sizeof(cee_v1_cfg), NULL);
 		if (!ret) {
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/intel/i40e/i40e_debugfs.c
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/intel/i40e/i40e_debugfs.c
@@ -1,7 +1,7 @@
 /*******************************************************************************
  *
  * Intel Ethernet Controller XL710 Family Linux Driver
- * Copyright(c) 2013 - 2014 Intel Corporation.
+ * Copyright(c) 2013 - 2016 Intel Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms and conditions of the GNU General Public License,
@@ -61,257 +61,13 @@ static struct i40e_veb *i40e_dbg_find_ve
 {
 	int i;
 
-	if ((seid < I40E_BASE_VEB_SEID) ||
-	    (seid > (I40E_BASE_VEB_SEID + I40E_MAX_VEB)))
-		dev_info(&pf->pdev->dev, "%d: bad seid\n", seid);
-	else
-		for (i = 0; i < I40E_MAX_VEB; i++)
-			if (pf->veb[i] && pf->veb[i]->seid == seid)
-				return pf->veb[i];
+	for (i = 0; i < I40E_MAX_VEB; i++)
+		if (pf->veb[i] && pf->veb[i]->seid == seid)
+			return pf->veb[i];
 	return NULL;
 }
 
 /**************************************************************
- * dump
- * The dump entry in debugfs is for getting a data snapshow of
- * the driver's current configuration and runtime details.
- * When the filesystem entry is written, a snapshot is taken.
- * When the entry is read, the most recent snapshot data is dumped.
- **************************************************************/
-static char *i40e_dbg_dump_buf;
-static ssize_t i40e_dbg_dump_data_len;
-static ssize_t i40e_dbg_dump_buffer_len;
-
-/**
- * i40e_dbg_dump_read - read the dump data
- * @filp: the opened file
- * @buffer: where to write the data for the user to read
- * @count: the size of the user's buffer
- * @ppos: file position offset
- **/
-static ssize_t i40e_dbg_dump_read(struct file *filp, char __user *buffer,
-				  size_t count, loff_t *ppos)
-{
-	int bytes_not_copied;
-	int len;
-
-	/* is *ppos bigger than the available data? */
-	if (*ppos >= i40e_dbg_dump_data_len || !i40e_dbg_dump_buf)
-		return 0;
-
-	/* be sure to not read beyond the end of available data */
-	len = min_t(int, count, (i40e_dbg_dump_data_len - *ppos));
-
-	bytes_not_copied = copy_to_user(buffer, &i40e_dbg_dump_buf[*ppos], len);
-	if (bytes_not_copied < 0)
-		return bytes_not_copied;
-
-	*ppos += len;
-	return len;
-}
-
-/**
- * i40e_dbg_prep_dump_buf
- * @pf: the PF we're working with
- * @buflen: the desired buffer length
- *
- * Return positive if success, 0 if failed
- **/
-static int i40e_dbg_prep_dump_buf(struct i40e_pf *pf, int buflen)
-{
-	/* if not already big enough, prep for re alloc */
-	if (i40e_dbg_dump_buffer_len && i40e_dbg_dump_buffer_len < buflen) {
-		kfree(i40e_dbg_dump_buf);
-		i40e_dbg_dump_buffer_len = 0;
-		i40e_dbg_dump_buf = NULL;
-	}
-
-	/* get a new buffer if needed */
-	if (!i40e_dbg_dump_buf) {
-		i40e_dbg_dump_buf = kzalloc(buflen, GFP_KERNEL);
-		if (i40e_dbg_dump_buf != NULL)
-			i40e_dbg_dump_buffer_len = buflen;
-	}
-
-	return i40e_dbg_dump_buffer_len;
-}
-
-/**
- * i40e_dbg_dump_write - trigger a datadump snapshot
- * @filp: the opened file
- * @buffer: where to find the user's data
- * @count: the length of the user's data
- * @ppos: file position offset
- *
- * Any write clears the stats
- **/
-static ssize_t i40e_dbg_dump_write(struct file *filp,
-				   const char __user *buffer,
-				   size_t count, loff_t *ppos)
-{
-	struct i40e_pf *pf = filp->private_data;
-	bool seid_found = false;
-	long seid = -1;
-	int buflen = 0;
-	int i, ret;
-	int len;
-	u8 *p;
-
-	/* don't allow partial writes */
-	if (*ppos != 0)
-		return 0;
-
-	/* decode the SEID given to be dumped */
-	ret = kstrtol_from_user(buffer, count, 0, &seid);
-
-	if (ret) {
-		dev_info(&pf->pdev->dev, "bad seid value\n");
-	} else if (seid == 0) {
-		seid_found = true;
-
-		kfree(i40e_dbg_dump_buf);
-		i40e_dbg_dump_buffer_len = 0;
-		i40e_dbg_dump_data_len = 0;
-		i40e_dbg_dump_buf = NULL;
-		dev_info(&pf->pdev->dev, "debug buffer freed\n");
-
-	} else if (seid == pf->pf_seid || seid == 1) {
-		seid_found = true;
-
-		buflen = sizeof(struct i40e_pf);
-		buflen += (sizeof(struct i40e_aq_desc)
-		     * (pf->hw.aq.num_arq_entries + pf->hw.aq.num_asq_entries));
-
-		if (i40e_dbg_prep_dump_buf(pf, buflen)) {
-			p = i40e_dbg_dump_buf;
-
-			len = sizeof(struct i40e_pf);
-			memcpy(p, pf, len);
-			p += len;
-
-			len = (sizeof(struct i40e_aq_desc)
-					* pf->hw.aq.num_asq_entries);
-			memcpy(p, pf->hw.aq.asq.desc_buf.va, len);
-			p += len;
-
-			len = (sizeof(struct i40e_aq_desc)
-					* pf->hw.aq.num_arq_entries);
-			memcpy(p, pf->hw.aq.arq.desc_buf.va, len);
-			p += len;
-
-			i40e_dbg_dump_data_len = buflen;
-			dev_info(&pf->pdev->dev,
-				 "PF seid %ld dumped %d bytes\n",
-				 seid, (int)i40e_dbg_dump_data_len);
-		}
-	} else if (seid >= I40E_BASE_VSI_SEID) {
-		struct i40e_vsi *vsi = NULL;
-		struct i40e_mac_filter *f;
-		int filter_count = 0;
-
-		mutex_lock(&pf->switch_mutex);
-		vsi = i40e_dbg_find_vsi(pf, seid);
-		if (!vsi) {
-			mutex_unlock(&pf->switch_mutex);
-			goto write_exit;
-		}
-
-		buflen = sizeof(struct i40e_vsi);
-		buflen += sizeof(struct i40e_q_vector) * vsi->num_q_vectors;
-		buflen += sizeof(struct i40e_ring) * 2 * vsi->num_queue_pairs;
-		buflen += sizeof(struct i40e_tx_buffer) * vsi->num_queue_pairs;
-		buflen += sizeof(struct i40e_rx_buffer) * vsi->num_queue_pairs;
-		list_for_each_entry(f, &vsi->mac_filter_list, list)
-			filter_count++;
-		buflen += sizeof(struct i40e_mac_filter) * filter_count;
-
-		if (i40e_dbg_prep_dump_buf(pf, buflen)) {
-			p = i40e_dbg_dump_buf;
-			seid_found = true;
-
-			len = sizeof(struct i40e_vsi);
-			memcpy(p, vsi, len);
-			p += len;
-
-			if (vsi->num_q_vectors) {
-				len = (sizeof(struct i40e_q_vector)
-					* vsi->num_q_vectors);
-				memcpy(p, vsi->q_vectors, len);
-				p += len;
-			}
-
-			if (vsi->num_queue_pairs) {
-				len = (sizeof(struct i40e_ring) *
-				      vsi->num_queue_pairs);
-				memcpy(p, vsi->tx_rings, len);
-				p += len;
-				memcpy(p, vsi->rx_rings, len);
-				p += len;
-			}
-
-			if (vsi->tx_rings[0]) {
-				len = sizeof(struct i40e_tx_buffer);
-				for (i = 0; i < vsi->num_queue_pairs; i++) {
-					memcpy(p, vsi->tx_rings[i]->tx_bi, len);
-					p += len;
-				}
-				len = sizeof(struct i40e_rx_buffer);
-				for (i = 0; i < vsi->num_queue_pairs; i++) {
-					memcpy(p, vsi->rx_rings[i]->rx_bi, len);
-					p += len;
-				}
-			}
-
-			/* macvlan filter list */
-			len = sizeof(struct i40e_mac_filter);
-			list_for_each_entry(f, &vsi->mac_filter_list, list) {
-				memcpy(p, f, len);
-				p += len;
-			}
-
-			i40e_dbg_dump_data_len = buflen;
-			dev_info(&pf->pdev->dev,
-				 "VSI seid %ld dumped %d bytes\n",
-				 seid, (int)i40e_dbg_dump_data_len);
-		}
-		mutex_unlock(&pf->switch_mutex);
-	} else if (seid >= I40E_BASE_VEB_SEID) {
-		struct i40e_veb *veb = NULL;
-
-		mutex_lock(&pf->switch_mutex);
-		veb = i40e_dbg_find_veb(pf, seid);
-		if (!veb) {
-			mutex_unlock(&pf->switch_mutex);
-			goto write_exit;
-		}
-
-		buflen = sizeof(struct i40e_veb);
-		if (i40e_dbg_prep_dump_buf(pf, buflen)) {
-			seid_found = true;
-			memcpy(i40e_dbg_dump_buf, veb, buflen);
-			i40e_dbg_dump_data_len = buflen;
-			dev_info(&pf->pdev->dev,
-				 "VEB seid %ld dumped %d bytes\n",
-				 seid, (int)i40e_dbg_dump_data_len);
-		}
-		mutex_unlock(&pf->switch_mutex);
-	}
-
-write_exit:
-	if (!seid_found)
-		dev_info(&pf->pdev->dev, "unknown seid %ld\n", seid);
-
-	return count;
-}
-
-static const struct file_operations i40e_dbg_dump_fops = {
-	.owner = THIS_MODULE,
-	.open =  simple_open,
-	.read =  i40e_dbg_dump_read,
-	.write = i40e_dbg_dump_write,
-};
-
-/**************************************************************
  * command
  * The command entry in debugfs is for giving the driver commands
  * to be executed - these may be for changing the internal switch
@@ -353,8 +109,8 @@ static ssize_t i40e_dbg_command_read(str
 	bytes_not_copied = copy_to_user(buffer, buf, len);
 	kfree(buf);
 
-	if (bytes_not_copied < 0)
-		return bytes_not_copied;
+	if (bytes_not_copied)
+		return -EFAULT;
 
 	*ppos = len;
 	return len;
@@ -379,19 +135,27 @@ static void i40e_dbg_dump_vsi_seid(struc
 		return;
 	}
 	dev_info(&pf->pdev->dev, "vsi seid %d\n", seid);
-	if (vsi->netdev)
-		dev_info(&pf->pdev->dev,
-			 "    netdev: name = %s\n",
-			 vsi->netdev->name);
+	if (vsi->netdev) {
+		struct net_device *nd = vsi->netdev;
+
+		dev_info(&pf->pdev->dev, "    netdev: name = %s, state = %lu, flags = 0x%08x\n",
+			 nd->name, nd->state, nd->flags);
+		dev_info(&pf->pdev->dev, "        features      = 0x%08lx\n",
+			 (unsigned long int)nd->features);
+		dev_info(&pf->pdev->dev, "        hw_features   = 0x%08lx\n",
+			 (unsigned long int)nd->hw_features);
+		dev_info(&pf->pdev->dev, "        vlan_features = 0x%08lx\n",
+			 (unsigned long int)nd->vlan_features);
+	}
 	if (vsi->active_vlans)
 		dev_info(&pf->pdev->dev,
 			 "    vlgrp: & = %p\n", vsi->active_vlans);
 	dev_info(&pf->pdev->dev,
-		 "    netdev_registered = %i, current_netdev_flags = 0x%04x, state = %li flags = 0x%08lx\n",
-		 vsi->netdev_registered,
-		 vsi->current_netdev_flags, vsi->state, vsi->flags);
+		 "    state = %li flags = 0x%08lx, netdev_registered = %i, current_netdev_flags = 0x%04x\n",
+		 vsi->state, vsi->flags,
+		 vsi->netdev_registered, vsi->current_netdev_flags);
 	if (vsi == pf->vsi[pf->lan_vsi])
-		dev_info(&pf->pdev->dev, "MAC address: %pM SAN MAC: %pM Port MAC: %pM\n",
+		dev_info(&pf->pdev->dev, "    MAC address: %pM SAN MAC: %pM Port MAC: %pM\n",
 			 pf->hw.mac.addr,
 			 pf->hw.mac.san_addr,
 			 pf->hw.mac.port_addr);
@@ -511,7 +275,7 @@ static void i40e_dbg_dump_vsi_seid(struc
 			 rx_ring->dtype);
 		dev_info(&pf->pdev->dev,
 			 "    rx_rings[%i]: hsplit = %d, next_to_use = %d, next_to_clean = %d, ring_active = %i\n",
-			 i, rx_ring->hsplit,
+			 i, ring_is_ps_enabled(rx_ring),
 			 rx_ring->next_to_use,
 			 rx_ring->next_to_clean,
 			 rx_ring->ring_active);
@@ -526,6 +290,11 @@ static void i40e_dbg_dump_vsi_seid(struc
 			 rx_ring->rx_stats.alloc_page_failed,
 			 rx_ring->rx_stats.alloc_buff_failed);
 		dev_info(&pf->pdev->dev,
+			 "    rx_rings[%i]: rx_stats: realloc_count = %lld, page_reuse_count = %lld\n",
+			 i,
+			 rx_ring->rx_stats.realloc_count,
+			 rx_ring->rx_stats.page_reuse_count);
+		dev_info(&pf->pdev->dev,
 			 "    rx_rings[%i]: size = %i, dma = 0x%08lx\n",
 			 i, rx_ring->size,
 			 (unsigned long int)rx_ring->dma);
@@ -557,8 +326,8 @@ static void i40e_dbg_dump_vsi_seid(struc
 			 "    tx_rings[%i]: dtype = %d\n",
 			 i, tx_ring->dtype);
 		dev_info(&pf->pdev->dev,
-			 "    tx_rings[%i]: hsplit = %d, next_to_use = %d, next_to_clean = %d, ring_active = %i\n",
-			 i, tx_ring->hsplit,
+			 "    tx_rings[%i]: next_to_use = %d, next_to_clean = %d, ring_active = %i\n",
+			 i,
 			 tx_ring->next_to_use,
 			 tx_ring->next_to_clean,
 			 tx_ring->ring_active);
@@ -815,20 +584,20 @@ static void i40e_dbg_dump_desc(int cnt,
 			if (!is_rx_ring) {
 				txd = I40E_TX_DESC(ring, i);
 				dev_info(&pf->pdev->dev,
-					 "   d[%03i] = 0x%016llx 0x%016llx\n",
+					 "   d[%03x] = 0x%016llx 0x%016llx\n",
 					 i, txd->buffer_addr,
 					 txd->cmd_type_offset_bsz);
 			} else if (sizeof(union i40e_rx_desc) ==
 				   sizeof(union i40e_16byte_rx_desc)) {
 				rxd = I40E_RX_DESC(ring, i);
 				dev_info(&pf->pdev->dev,
-					 "   d[%03i] = 0x%016llx 0x%016llx\n",
+					 "   d[%03x] = 0x%016llx 0x%016llx\n",
 					 i, rxd->read.pkt_addr,
 					 rxd->read.hdr_addr);
 			} else {
 				rxd = I40E_RX_DESC(ring, i);
 				dev_info(&pf->pdev->dev,
-					 "   d[%03i] = 0x%016llx 0x%016llx 0x%016llx 0x%016llx\n",
+					 "   d[%03x] = 0x%016llx 0x%016llx 0x%016llx 0x%016llx\n",
 					 i, rxd->read.pkt_addr,
 					 rxd->read.hdr_addr,
 					 rxd->read.rsvd1, rxd->read.rsvd2);
@@ -843,20 +612,20 @@ static void i40e_dbg_dump_desc(int cnt,
 		if (!is_rx_ring) {
 			txd = I40E_TX_DESC(ring, desc_n);
 			dev_info(&pf->pdev->dev,
-				 "vsi = %02i tx ring = %02i d[%03i] = 0x%016llx 0x%016llx\n",
+				 "vsi = %02i tx ring = %02i d[%03x] = 0x%016llx 0x%016llx\n",
 				 vsi_seid, ring_id, desc_n,
 				 txd->buffer_addr, txd->cmd_type_offset_bsz);
 		} else if (sizeof(union i40e_rx_desc) ==
 			   sizeof(union i40e_16byte_rx_desc)) {
 			rxd = I40E_RX_DESC(ring, desc_n);
 			dev_info(&pf->pdev->dev,
-				 "vsi = %02i rx ring = %02i d[%03i] = 0x%016llx 0x%016llx\n",
+				 "vsi = %02i rx ring = %02i d[%03x] = 0x%016llx 0x%016llx\n",
 				 vsi_seid, ring_id, desc_n,
 				 rxd->read.pkt_addr, rxd->read.hdr_addr);
 		} else {
 			rxd = I40E_RX_DESC(ring, desc_n);
 			dev_info(&pf->pdev->dev,
-				 "vsi = %02i rx ring = %02i d[%03i] = 0x%016llx 0x%016llx 0x%016llx 0x%016llx\n",
+				 "vsi = %02i rx ring = %02i d[%03x] = 0x%016llx 0x%016llx 0x%016llx 0x%016llx\n",
 				 vsi_seid, ring_id, desc_n,
 				 rxd->read.pkt_addr, rxd->read.hdr_addr,
 				 rxd->read.rsvd1, rxd->read.rsvd2);
@@ -918,12 +687,6 @@ static void i40e_dbg_dump_veb_seid(struc
 {
 	struct i40e_veb *veb;
 
-	if ((seid < I40E_BASE_VEB_SEID) ||
-	    (seid >= (I40E_MAX_VEB + I40E_BASE_VEB_SEID))) {
-		dev_info(&pf->pdev->dev, "%d: bad seid\n", seid);
-		return;
-	}
-
 	veb = i40e_dbg_find_veb(pf, seid);
 	if (!veb) {
 		dev_info(&pf->pdev->dev, "can't find veb %d\n", seid);
@@ -981,12 +744,10 @@ static ssize_t i40e_dbg_command_write(st
 	if (!cmd_buf)
 		return count;
 	bytes_not_copied = copy_from_user(cmd_buf, buffer, count);
-	if (bytes_not_copied < 0) {
+	if (bytes_not_copied) {
 		kfree(cmd_buf);
-		return bytes_not_copied;
+		return -EFAULT;
 	}
-	if (bytes_not_copied > 0)
-		count -= bytes_not_copied;
 	cmd_buf[count] = '\0';
 
 	cmd_buf_tmp = strchr(cmd_buf, '\n');
@@ -1140,7 +901,7 @@ static ssize_t i40e_dbg_command_write(st
 		spin_lock_bh(&vsi->mac_filter_list_lock);
 		f = i40e_add_filter(vsi, ma, vlan, false, false);
 		spin_unlock_bh(&vsi->mac_filter_list_lock);
-		ret = i40e_sync_vsi_filters(vsi, true);
+		ret = i40e_sync_vsi_filters(vsi);
 		if (f && !ret)
 			dev_info(&pf->pdev->dev,
 				 "add macaddr: %pM vlan=%d added to VSI %d\n",
@@ -1179,7 +940,7 @@ static ssize_t i40e_dbg_command_write(st
 		spin_lock_bh(&vsi->mac_filter_list_lock);
 		i40e_del_filter(vsi, ma, vlan, false, false);
 		spin_unlock_bh(&vsi->mac_filter_list_lock);
-		ret = i40e_sync_vsi_filters(vsi, true);
+		ret = i40e_sync_vsi_filters(vsi);
 		if (!ret)
 			dev_info(&pf->pdev->dev,
 				 "del macaddr: %pM vlan=%d removed from VSI %d\n",
@@ -2034,8 +1795,8 @@ static ssize_t i40e_dbg_netdev_ops_read(
 	bytes_not_copied = copy_to_user(buffer, buf, len);
 	kfree(buf);
 
-	if (bytes_not_copied < 0)
-		return bytes_not_copied;
+	if (bytes_not_copied)
+		return -EFAULT;
 
 	*ppos = len;
 	return len;
@@ -2068,10 +1829,8 @@ static ssize_t i40e_dbg_netdev_ops_write
 	memset(i40e_dbg_netdev_ops_buf, 0, sizeof(i40e_dbg_netdev_ops_buf));
 	bytes_not_copied = copy_from_user(i40e_dbg_netdev_ops_buf,
 					  buffer, count);
-	if (bytes_not_copied < 0)
-		return bytes_not_copied;
-	else if (bytes_not_copied > 0)
-		count -= bytes_not_copied;
+	if (bytes_not_copied)
+		return -EFAULT;
 	i40e_dbg_netdev_ops_buf[count] = '\0';
 
 	buf_tmp = strchr(i40e_dbg_netdev_ops_buf, '\n');
@@ -2206,11 +1965,6 @@ void i40e_dbg_pf_init(struct i40e_pf *pf
 	if (!pfile)
 		goto create_failed;
 
-	pfile = debugfs_create_file("dump", 0600, pf->i40e_dbg_pf, pf,
-				    &i40e_dbg_dump_fops);
-	if (!pfile)
-		goto create_failed;
-
 	pfile = debugfs_create_file("netdev_ops", 0600, pf->i40e_dbg_pf, pf,
 				    &i40e_dbg_netdev_ops_fops);
 	if (!pfile)
@@ -2231,9 +1985,6 @@ void i40e_dbg_pf_exit(struct i40e_pf *pf
 {
 	debugfs_remove_recursive(pf->i40e_dbg_pf);
 	pf->i40e_dbg_pf = NULL;
-
-	kfree(i40e_dbg_dump_buf);
-	i40e_dbg_dump_buf = NULL;
 }
 
 /**
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/intel/i40e/i40e_devids.h
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/intel/i40e/i40e_devids.h
@@ -30,7 +30,6 @@
 /* Device IDs */
 #define I40E_DEV_ID_SFP_XL710		0x1572
 #define I40E_DEV_ID_QEMU		0x1574
-#define I40E_DEV_ID_KX_A		0x157F
 #define I40E_DEV_ID_KX_B		0x1580
 #define I40E_DEV_ID_KX_C		0x1581
 #define I40E_DEV_ID_QSFP_A		0x1583
@@ -40,13 +39,11 @@
 #define I40E_DEV_ID_20G_KR2		0x1587
 #define I40E_DEV_ID_20G_KR2_A		0x1588
 #define I40E_DEV_ID_10G_BASE_T4		0x1589
-#define I40E_DEV_ID_VF			0x154C
-#define I40E_DEV_ID_VF_HV		0x1571
+#define I40E_DEV_ID_KX_X722		0x37CE
+#define I40E_DEV_ID_QSFP_X722		0x37CF
 #define I40E_DEV_ID_SFP_X722		0x37D0
 #define I40E_DEV_ID_1G_BASE_T_X722	0x37D1
 #define I40E_DEV_ID_10G_BASE_T_X722	0x37D2
-#define I40E_DEV_ID_X722_VF		0x37CD
-#define I40E_DEV_ID_X722_VF_HV		0x37D9
 
 #define i40e_is_40G_device(d)		((d) == I40E_DEV_ID_QSFP_A  || \
 					 (d) == I40E_DEV_ID_QSFP_B  || \
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
@@ -1,7 +1,7 @@
 /*******************************************************************************
  *
  * Intel Ethernet Controller XL710 Family Linux Driver
- * Copyright(c) 2013 - 2015 Intel Corporation.
+ * Copyright(c) 2013 - 2016 Intel Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms and conditions of the GNU General Public License,
@@ -88,6 +88,10 @@ static const struct i40e_stats i40e_gstr
 	I40E_VSI_STAT("tx_broadcast", eth_stats.tx_broadcast),
 	I40E_VSI_STAT("rx_unknown_protocol", eth_stats.rx_unknown_protocol),
 	I40E_VSI_STAT("tx_linearize", tx_linearize),
+	I40E_VSI_STAT("tx_force_wb", tx_force_wb),
+	I40E_VSI_STAT("tx_lost_interrupt", tx_lost_interrupt),
+	I40E_VSI_STAT("rx_alloc_fail", rx_buf_failed),
+	I40E_VSI_STAT("rx_pg_alloc_fail", rx_page_failed),
 };
 
 /* These PF_STATs might look like duplicates of some NETDEV_STATs,
@@ -142,6 +146,7 @@ static struct i40e_stats i40e_gstrings_s
 	I40E_PF_STAT("rx_oversize", stats.rx_oversize),
 	I40E_PF_STAT("rx_jabber", stats.rx_jabber),
 	I40E_PF_STAT("VF_admin_queue_requests", vf_aq_requests),
+	I40E_PF_STAT("arq_overflows", arq_overflows),
 	I40E_PF_STAT("rx_hwtstamp_cleared", rx_hwtstamp_cleared),
 	I40E_PF_STAT("fdir_flush_cnt", fd_flush_cnt),
 	I40E_PF_STAT("fdir_atr_match", stats.fd_atr_match),
@@ -230,6 +235,8 @@ static const char i40e_priv_flags_string
 	"LinkPolling",
 	"flow-director-atr",
 	"veb-stats",
+	"packet-split",
+	"hw-atr-eviction",
 };
 
 #define I40E_PRIV_FLAGS_STR_LEN ARRAY_SIZE(i40e_priv_flags_strings)
@@ -338,7 +345,7 @@ static void i40e_get_settings_link_up(st
 				  SUPPORTED_1000baseT_Full;
 		if (hw_link_info->requested_speeds & I40E_LINK_SPEED_1GB)
 			ecmd->advertising |= ADVERTISED_1000baseT_Full;
-		if (pf->hw.mac.type == I40E_MAC_X722) {
+		if (pf->flags & I40E_FLAG_100M_SGMII_CAPABLE) {
 			ecmd->supported |= SUPPORTED_100baseT_Full;
 			if (hw_link_info->requested_speeds &
 			    I40E_LINK_SPEED_100MB)
@@ -409,6 +416,10 @@ static void i40e_get_settings_link_down(
 		if (pf->hw.mac.type == I40E_MAC_X722) {
 			ecmd->supported |= SUPPORTED_100baseT_Full;
 			ecmd->advertising |= ADVERTISED_100baseT_Full;
+			if (pf->flags & I40E_FLAG_100M_SGMII_CAPABLE) {
+				ecmd->supported |= SUPPORTED_100baseT_Full;
+				ecmd->advertising |= ADVERTISED_100baseT_Full;
+			}
 		}
 	}
 	if (phy_types & I40E_CAP_PHY_TYPE_XAUI ||
@@ -994,16 +1005,19 @@ static int i40e_get_eeprom(struct net_de
 	/* check for NVMUpdate access method */
 	magic = hw->vendor_id | (hw->device_id << 16);
 	if (eeprom->magic && eeprom->magic != magic) {
-		struct i40e_nvm_access *cmd;
-		int errno;
+		struct i40e_nvm_access *cmd = (struct i40e_nvm_access *)eeprom;
+		int errno = 0;
 
 		/* make sure it is the right magic for NVMUpdate */
 		if ((eeprom->magic >> 16) != hw->device_id)
-			return -EINVAL;
+			errno = -EINVAL;
+		else if (test_bit(__I40E_RESET_RECOVERY_PENDING, &pf->state) ||
+			 test_bit(__I40E_RESET_INTR_RECEIVED, &pf->state))
+			errno = -EBUSY;
+		else
+			ret_val = i40e_nvmupd_command(hw, cmd, bytes, &errno);
 
-		cmd = (struct i40e_nvm_access *)eeprom;
-		ret_val = i40e_nvmupd_command(hw, cmd, bytes, &errno);
-		if (ret_val && (hw->debug_mask & I40E_DEBUG_NVM))
+		if ((errno || ret_val) && (hw->debug_mask & I40E_DEBUG_NVM))
 			dev_info(&pf->pdev->dev,
 				 "NVMUpdate read failed err=%d status=0x%x errno=%d module=%d offset=0x%x size=%d\n",
 				 ret_val, hw->aq.asq_last_status, errno,
@@ -1087,27 +1101,25 @@ static int i40e_set_eeprom(struct net_de
 	struct i40e_netdev_priv *np = netdev_priv(netdev);
 	struct i40e_hw *hw = &np->vsi->back->hw;
 	struct i40e_pf *pf = np->vsi->back;
-	struct i40e_nvm_access *cmd;
+	struct i40e_nvm_access *cmd = (struct i40e_nvm_access *)eeprom;
 	int ret_val = 0;
-	int errno;
+	int errno = 0;
 	u32 magic;
 
 	/* normal ethtool set_eeprom is not supported */
 	magic = hw->vendor_id | (hw->device_id << 16);
 	if (eeprom->magic == magic)
-		return -EOPNOTSUPP;
-
+		errno = -EOPNOTSUPP;
 	/* check for NVMUpdate access method */
-	if (!eeprom->magic || (eeprom->magic >> 16) != hw->device_id)
-		return -EINVAL;
-
-	if (test_bit(__I40E_RESET_RECOVERY_PENDING, &pf->state) ||
-	    test_bit(__I40E_RESET_INTR_RECEIVED, &pf->state))
-		return -EBUSY;
+	else if (!eeprom->magic || (eeprom->magic >> 16) != hw->device_id)
+		errno = -EINVAL;
+	else if (test_bit(__I40E_RESET_RECOVERY_PENDING, &pf->state) ||
+		 test_bit(__I40E_RESET_INTR_RECEIVED, &pf->state))
+		errno = -EBUSY;
+	else
+		ret_val = i40e_nvmupd_command(hw, cmd, bytes, &errno);
 
-	cmd = (struct i40e_nvm_access *)eeprom;
-	ret_val = i40e_nvmupd_command(hw, cmd, bytes, &errno);
-	if (ret_val && (hw->debug_mask & I40E_DEBUG_NVM))
+	if ((errno || ret_val) && (hw->debug_mask & I40E_DEBUG_NVM))
 		dev_info(&pf->pdev->dev,
 			 "NVMUpdate write failed err=%d status=0x%x errno=%d module=%d offset=0x%x size=%d\n",
 			 ret_val, hw->aq.asq_last_status, errno,
@@ -1814,28 +1826,52 @@ static int i40e_set_phys_id(struct net_d
 			    enum ethtool_phys_id_state state)
 {
 	struct i40e_netdev_priv *np = netdev_priv(netdev);
+	i40e_status ret = 0;
 	struct i40e_pf *pf = np->vsi->back;
 	struct i40e_hw *hw = &pf->hw;
 	int blink_freq = 2;
+	u16 temp_status;
 
 	switch (state) {
 	case ETHTOOL_ID_ACTIVE:
-		pf->led_status = i40e_led_get(hw);
+		if (!(pf->flags & I40E_FLAG_HAVE_10GBASET_PHY)) {
+			pf->led_status = i40e_led_get(hw);
+		} else {
+			i40e_aq_set_phy_debug(hw, I40E_PHY_DEBUG_PORT, NULL);
+			ret = i40e_led_get_phy(hw, &temp_status,
+					       &pf->phy_led_val);
+			pf->led_status = temp_status;
+		}
 		return blink_freq;
 	case ETHTOOL_ID_ON:
-		i40e_led_set(hw, 0xF, false);
+		if (!(pf->flags & I40E_FLAG_HAVE_10GBASET_PHY))
+			i40e_led_set(hw, 0xf, false);
+		else
+			ret = i40e_led_set_phy(hw, true, pf->led_status, 0);
 		break;
 	case ETHTOOL_ID_OFF:
-		i40e_led_set(hw, 0x0, false);
+		if (!(pf->flags & I40E_FLAG_HAVE_10GBASET_PHY))
+			i40e_led_set(hw, 0x0, false);
+		else
+			ret = i40e_led_set_phy(hw, false, pf->led_status, 0);
 		break;
 	case ETHTOOL_ID_INACTIVE:
-		i40e_led_set(hw, pf->led_status, false);
+		if (!(pf->flags & I40E_FLAG_HAVE_10GBASET_PHY)) {
+			i40e_led_set(hw, false, pf->led_status);
+		} else {
+			ret = i40e_led_set_phy(hw, false, pf->led_status,
+					       (pf->phy_led_val |
+					       I40E_PHY_LED_MODE_ORIG));
+			i40e_aq_set_phy_debug(hw, 0, NULL);
+		}
 		break;
 	default:
 		break;
 	}
-
-	return 0;
+		if (ret)
+			return -ENOENT;
+		else
+			return 0;
 }
 
 /* NOTE: i40e hardware uses a conversion factor of 2 for Interrupt
@@ -2110,7 +2146,7 @@ static int i40e_get_rxnfc(struct net_dev
 
 	switch (cmd->cmd) {
 	case ETHTOOL_GRXRINGS:
-		cmd->data = vsi->alloc_queue_pairs;
+		cmd->data = vsi->num_queue_pairs;
 		ret = 0;
 		break;
 	case ETHTOOL_GRXFH:
@@ -2145,8 +2181,8 @@ static int i40e_get_rxnfc(struct net_dev
 static int i40e_set_rss_hash_opt(struct i40e_pf *pf, struct ethtool_rxnfc *nfc)
 {
 	struct i40e_hw *hw = &pf->hw;
-	u64 hena = (u64)rd32(hw, I40E_PFQF_HENA(0)) |
-		   ((u64)rd32(hw, I40E_PFQF_HENA(1)) << 32);
+	u64 hena = (u64)i40e_read_rx_ctl(hw, I40E_PFQF_HENA(0)) |
+		   ((u64)i40e_read_rx_ctl(hw, I40E_PFQF_HENA(1)) << 32);
 
 	/* RSS does not support anything other than hashing
 	 * to queues on src and dst IPs and ports
@@ -2164,9 +2200,12 @@ static int i40e_set_rss_hash_opt(struct
 	case TCP_V4_FLOW:
 		switch (nfc->data & (RXH_L4_B_0_1 | RXH_L4_B_2_3)) {
 		case 0:
-			hena &= ~BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV4_TCP);
-			break;
+			return -EINVAL;
 		case (RXH_L4_B_0_1 | RXH_L4_B_2_3):
+			if (pf->flags & I40E_FLAG_MULTIPLE_TCP_UDP_RSS_PCTYPE)
+				hena |=
+			   BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV4_TCP_SYN_NO_ACK);
+
 			hena |= BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV4_TCP);
 			break;
 		default:
@@ -2176,9 +2215,12 @@ static int i40e_set_rss_hash_opt(struct
 	case TCP_V6_FLOW:
 		switch (nfc->data & (RXH_L4_B_0_1 | RXH_L4_B_2_3)) {
 		case 0:
-			hena &= ~BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV6_TCP);
-			break;
+			return -EINVAL;
 		case (RXH_L4_B_0_1 | RXH_L4_B_2_3):
+			if (pf->flags & I40E_FLAG_MULTIPLE_TCP_UDP_RSS_PCTYPE)
+				hena |=
+			   BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV6_TCP_SYN_NO_ACK);
+
 			hena |= BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV6_TCP);
 			break;
 		default:
@@ -2188,10 +2230,13 @@ static int i40e_set_rss_hash_opt(struct
 	case UDP_V4_FLOW:
 		switch (nfc->data & (RXH_L4_B_0_1 | RXH_L4_B_2_3)) {
 		case 0:
-			hena &= ~(BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV4_UDP) |
-				  BIT_ULL(I40E_FILTER_PCTYPE_FRAG_IPV4));
-			break;
+			return -EINVAL;
 		case (RXH_L4_B_0_1 | RXH_L4_B_2_3):
+			if (pf->flags & I40E_FLAG_MULTIPLE_TCP_UDP_RSS_PCTYPE)
+				hena |=
+			    BIT_ULL(I40E_FILTER_PCTYPE_NONF_UNICAST_IPV4_UDP) |
+			    BIT_ULL(I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV4_UDP);
+
 			hena |= (BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV4_UDP) |
 				 BIT_ULL(I40E_FILTER_PCTYPE_FRAG_IPV4));
 			break;
@@ -2202,10 +2247,13 @@ static int i40e_set_rss_hash_opt(struct
 	case UDP_V6_FLOW:
 		switch (nfc->data & (RXH_L4_B_0_1 | RXH_L4_B_2_3)) {
 		case 0:
-			hena &= ~(BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV6_UDP) |
-				  BIT_ULL(I40E_FILTER_PCTYPE_FRAG_IPV6));
-			break;
+			return -EINVAL;
 		case (RXH_L4_B_0_1 | RXH_L4_B_2_3):
+			if (pf->flags & I40E_FLAG_MULTIPLE_TCP_UDP_RSS_PCTYPE)
+				hena |=
+			    BIT_ULL(I40E_FILTER_PCTYPE_NONF_UNICAST_IPV6_UDP) |
+			    BIT_ULL(I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV6_UDP);
+
 			hena |= (BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV6_UDP) |
 				 BIT_ULL(I40E_FILTER_PCTYPE_FRAG_IPV6));
 			break;
@@ -2243,8 +2291,8 @@ static int i40e_set_rss_hash_opt(struct
 		return -EINVAL;
 	}
 
-	wr32(hw, I40E_PFQF_HENA(0), (u32)hena);
-	wr32(hw, I40E_PFQF_HENA(1), (u32)(hena >> 32));
+	i40e_write_rx_ctl(hw, I40E_PFQF_HENA(0), (u32)hena);
+	i40e_write_rx_ctl(hw, I40E_PFQF_HENA(1), (u32)(hena >> 32));
 	i40e_flush(hw);
 
 	/* Save setting for future output/update */
@@ -2583,7 +2631,6 @@ static int i40e_set_channels(struct net_
 		return -EINVAL;
 }
 
-#define I40E_HLUT_ARRAY_SIZE ((I40E_PFQF_HLUT_MAX_INDEX + 1) * 4)
 /**
  * i40e_get_rxfh_key_size - get the RSS hash key size
  * @netdev: network interface device structure
@@ -2611,10 +2658,9 @@ static int i40e_get_rxfh(struct net_devi
 {
 	struct i40e_netdev_priv *np = netdev_priv(netdev);
 	struct i40e_vsi *vsi = np->vsi;
-	struct i40e_pf *pf = vsi->back;
-	struct i40e_hw *hw = &pf->hw;
-	u32 reg_val;
-	int i, j;
+	u8 *lut, *seed = NULL;
+	int ret;
+	u16 i;
 
 	if (hfunc)
 		*hfunc = ETH_RSS_HASH_TOP;
@@ -2622,24 +2668,20 @@ static int i40e_get_rxfh(struct net_devi
 	if (!indir)
 		return 0;
 
-	for (i = 0, j = 0; i <= I40E_PFQF_HLUT_MAX_INDEX; i++) {
-		reg_val = rd32(hw, I40E_PFQF_HLUT(i));
-		indir[j++] = reg_val & 0xff;
-		indir[j++] = (reg_val >> 8) & 0xff;
-		indir[j++] = (reg_val >> 16) & 0xff;
-		indir[j++] = (reg_val >> 24) & 0xff;
-	}
+	seed = key;
+	lut = kzalloc(I40E_HLUT_ARRAY_SIZE, GFP_KERNEL);
+	if (!lut)
+		return -ENOMEM;
+	ret = i40e_get_rss(vsi, seed, lut, I40E_HLUT_ARRAY_SIZE);
+	if (ret)
+		goto out;
+	for (i = 0; i < I40E_HLUT_ARRAY_SIZE; i++)
+		indir[i] = (u32)(lut[i]);
 
-	if (key) {
-		for (i = 0, j = 0; i <= I40E_PFQF_HKEY_MAX_INDEX; i++) {
-			reg_val = rd32(hw, I40E_PFQF_HKEY(i));
-			key[j++] = (u8)(reg_val & 0xff);
-			key[j++] = (u8)((reg_val >> 8) & 0xff);
-			key[j++] = (u8)((reg_val >> 16) & 0xff);
-			key[j++] = (u8)((reg_val >> 24) & 0xff);
-		}
-	}
-	return 0;
+out:
+	kfree(lut);
+
+	return ret;
 }
 
 /**
@@ -2656,10 +2698,8 @@ static int i40e_set_rxfh(struct net_devi
 {
 	struct i40e_netdev_priv *np = netdev_priv(netdev);
 	struct i40e_vsi *vsi = np->vsi;
-	struct i40e_pf *pf = vsi->back;
-	struct i40e_hw *hw = &pf->hw;
-	u32 reg_val;
-	int i, j;
+	u8 *seed = NULL;
+	u16 i;
 
 	if (hfunc != ETH_RSS_HASH_NO_CHANGE && hfunc != ETH_RSS_HASH_TOP)
 		return -EOPNOTSUPP;
@@ -2667,24 +2707,28 @@ static int i40e_set_rxfh(struct net_devi
 	if (!indir)
 		return 0;
 
-	for (i = 0, j = 0; i <= I40E_PFQF_HLUT_MAX_INDEX; i++) {
-		reg_val = indir[j++];
-		reg_val |= indir[j++] << 8;
-		reg_val |= indir[j++] << 16;
-		reg_val |= indir[j++] << 24;
-		wr32(hw, I40E_PFQF_HLUT(i), reg_val);
-	}
-
 	if (key) {
-		for (i = 0, j = 0; i <= I40E_PFQF_HKEY_MAX_INDEX; i++) {
-			reg_val = key[j++];
-			reg_val |= key[j++] << 8;
-			reg_val |= key[j++] << 16;
-			reg_val |= key[j++] << 24;
-			wr32(hw, I40E_PFQF_HKEY(i), reg_val);
-		}
-	}
-	return 0;
+		if (!vsi->rss_hkey_user) {
+			vsi->rss_hkey_user = kzalloc(I40E_HKEY_ARRAY_SIZE,
+						     GFP_KERNEL);
+			if (!vsi->rss_hkey_user)
+				return -ENOMEM;
+		}
+		memcpy(vsi->rss_hkey_user, key, I40E_HKEY_ARRAY_SIZE);
+		seed = vsi->rss_hkey_user;
+	}
+	if (!vsi->rss_lut_user) {
+		vsi->rss_lut_user = kzalloc(I40E_HLUT_ARRAY_SIZE, GFP_KERNEL);
+		if (!vsi->rss_lut_user)
+			return -ENOMEM;
+	}
+
+	/* Each 32 bits pointed by 'indir' is stored with a lut entry */
+	for (i = 0; i < I40E_HLUT_ARRAY_SIZE; i++)
+		vsi->rss_lut_user[i] = (u8)(indir[i]);
+
+	return i40e_config_rss(vsi, seed, vsi->rss_lut_user,
+			       I40E_HLUT_ARRAY_SIZE);
 }
 
 /**
@@ -2712,6 +2756,10 @@ static u32 i40e_get_priv_flags(struct ne
 		I40E_PRIV_FLAGS_FD_ATR : 0;
 	ret_flags |= pf->flags & I40E_FLAG_VEB_STATS_ENABLED ?
 		I40E_PRIV_FLAGS_VEB_STATS : 0;
+	ret_flags |= pf->flags & I40E_FLAG_RX_PS_ENABLED ?
+		I40E_PRIV_FLAGS_PS : 0;
+	ret_flags |= pf->auto_disable_flags & I40E_FLAG_HW_ATR_EVICT_CAPABLE ?
+		0 : I40E_PRIV_FLAGS_HW_ATR_EVICT;
 
 	return ret_flags;
 }
@@ -2726,6 +2774,26 @@ static int i40e_set_priv_flags(struct ne
 	struct i40e_netdev_priv *np = netdev_priv(dev);
 	struct i40e_vsi *vsi = np->vsi;
 	struct i40e_pf *pf = vsi->back;
+	bool reset_required = false;
+
+	/* NOTE: MFP is not settable */
+
+	/* allow the user to control the method of receive
+	 * buffer DMA, whether the packet is split at header
+	 * boundaries into two separate buffers.  In some cases
+	 * one routine or the other will perform better.
+	 */
+	if ((flags & I40E_PRIV_FLAGS_PS) &&
+	    !(pf->flags & I40E_FLAG_RX_PS_ENABLED)) {
+		pf->flags |= I40E_FLAG_RX_PS_ENABLED;
+		pf->flags &= ~I40E_FLAG_RX_1BUF_ENABLED;
+		reset_required = true;
+	} else if (!(flags & I40E_PRIV_FLAGS_PS) &&
+		   (pf->flags & I40E_FLAG_RX_PS_ENABLED)) {
+		pf->flags &= ~I40E_FLAG_RX_PS_ENABLED;
+		pf->flags |= I40E_FLAG_RX_1BUF_ENABLED;
+		reset_required = true;
+	}
 
 	if (flags & I40E_PRIV_FLAGS_LINKPOLL_FLAG)
 		pf->flags |= I40E_FLAG_LINK_POLLING_ENABLED;
@@ -2743,10 +2811,25 @@ static int i40e_set_priv_flags(struct ne
 		pf->auto_disable_flags |= I40E_FLAG_FD_ATR_ENABLED;
 	}
 
-	if (flags & I40E_PRIV_FLAGS_VEB_STATS)
+	if ((flags & I40E_PRIV_FLAGS_VEB_STATS) &&
+	    !(pf->flags & I40E_FLAG_VEB_STATS_ENABLED)) {
 		pf->flags |= I40E_FLAG_VEB_STATS_ENABLED;
-	else
+		reset_required = true;
+	} else if (!(flags & I40E_PRIV_FLAGS_VEB_STATS) &&
+		   (pf->flags & I40E_FLAG_VEB_STATS_ENABLED)) {
 		pf->flags &= ~I40E_FLAG_VEB_STATS_ENABLED;
+		reset_required = true;
+	}
+
+	if ((flags & I40E_PRIV_FLAGS_HW_ATR_EVICT) &&
+	    (pf->flags & I40E_FLAG_HW_ATR_EVICT_CAPABLE))
+		pf->auto_disable_flags &= ~I40E_FLAG_HW_ATR_EVICT_CAPABLE;
+	else
+		pf->auto_disable_flags |= I40E_FLAG_HW_ATR_EVICT_CAPABLE;
+
+	/* if needed, issue reset to cause things to take effect */
+	if (reset_required)
+		i40e_do_reset(pf, BIT(__I40E_PF_RESET_REQUESTED));
 
 	return 0;
 }
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/intel/i40e/i40e_fcoe.c
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/intel/i40e/i40e_fcoe.c
@@ -295,11 +295,11 @@ void i40e_init_pf_fcoe(struct i40e_pf *p
 	}
 
 	/* enable FCoE hash filter */
-	val = rd32(hw, I40E_PFQF_HENA(1));
+	val = i40e_read_rx_ctl(hw, I40E_PFQF_HENA(1));
 	val |= BIT(I40E_FILTER_PCTYPE_FCOE_OX - 32);
 	val |= BIT(I40E_FILTER_PCTYPE_FCOE_RX - 32);
 	val &= I40E_PFQF_HENA_PTYPE_ENA_MASK;
-	wr32(hw, I40E_PFQF_HENA(1), val);
+	i40e_write_rx_ctl(hw, I40E_PFQF_HENA(1), val);
 
 	/* enable flag */
 	pf->flags |= I40E_FLAG_FCOE_ENABLED;
@@ -317,11 +317,11 @@ void i40e_init_pf_fcoe(struct i40e_pf *p
 	pf->filter_settings.fcoe_cntx_num = I40E_DMA_CNTX_SIZE_4K;
 
 	/* Setup max frame with FCoE_MTU plus L2 overheads */
-	val = rd32(hw, I40E_GLFCOE_RCTL);
+	val = i40e_read_rx_ctl(hw, I40E_GLFCOE_RCTL);
 	val &= ~I40E_GLFCOE_RCTL_MAX_SIZE_MASK;
 	val |= ((FCOE_MTU + ETH_HLEN + VLAN_HLEN + ETH_FCS_LEN)
 		 << I40E_GLFCOE_RCTL_MAX_SIZE_SHIFT);
-	wr32(hw, I40E_GLFCOE_RCTL, val);
+	i40e_write_rx_ctl(hw, I40E_GLFCOE_RCTL, val);
 
 	dev_info(&pf->pdev->dev, "FCoE is supported.\n");
 }
@@ -1359,16 +1359,32 @@ static netdev_tx_t i40e_fcoe_xmit_frame(
 	struct i40e_ring *tx_ring = vsi->tx_rings[skb->queue_mapping];
 	struct i40e_tx_buffer *first;
 	u32 tx_flags = 0;
+	int fso, count;
 	u8 hdr_len = 0;
 	u8 sof = 0;
 	u8 eof = 0;
-	int fso;
 
 	if (i40e_fcoe_set_skb_header(skb))
 		goto out_drop;
 
-	if (!i40e_xmit_descriptor_count(skb, tx_ring))
+	count = i40e_xmit_descriptor_count(skb);
+	if (i40e_chk_linearize(skb, count)) {
+		if (__skb_linearize(skb))
+			goto out_drop;
+		count = TXD_USE_COUNT(skb->len);
+		tx_ring->tx_stats.tx_linearize++;
+	}
+
+	/* need: 1 descriptor per page * PAGE_SIZE/I40E_MAX_DATA_PER_TXD,
+	 *       + 1 desc for skb_head_len/I40E_MAX_DATA_PER_TXD,
+	 *       + 4 desc gap to avoid the cache line where head is,
+	 *       + 1 desc for context descriptor,
+	 * otherwise try next time
+	 */
+	if (i40e_maybe_stop_tx(tx_ring, count + 4 + 1)) {
+		tx_ring->tx_stats.tx_busy++;
 		return NETDEV_TX_BUSY;
+	}
 
 	/* prepare the xmit flags */
 	if (i40e_tx_prepare_vlan_flags(skb, tx_ring, &tx_flags))
@@ -1457,7 +1473,7 @@ static const struct net_device_ops i40e_
 	.ndo_tx_timeout		= i40e_tx_timeout,
 	.ndo_vlan_rx_add_vid	= i40e_vlan_rx_add_vid,
 	.ndo_vlan_rx_kill_vid	= i40e_vlan_rx_kill_vid,
-	.ndo_setup_tc		= i40e_setup_tc,
+	.ndo_setup_tc		= __i40e_setup_tc,
 
 #ifdef CONFIG_NET_POLL_CONTROLLER
 	.ndo_poll_controller	= i40e_netpoll,
@@ -1544,8 +1560,6 @@ void i40e_fcoe_vsi_setup(struct i40e_pf
 	if (!(pf->flags & I40E_FLAG_FCOE_ENABLED))
 		return;
 
-	BUG_ON(!pf->vsi[pf->lan_vsi]);
-
 	for (i = 0; i < pf->num_alloc_vsi; i++) {
 		vsi = pf->vsi[i];
 		if (vsi && vsi->type == I40E_VSI_FCOE) {
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/intel/i40e/i40e_lan_hmc.c
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/intel/i40e/i40e_lan_hmc.c
@@ -762,7 +762,7 @@ static void i40e_write_byte(u8 *hmc_bits
 
 	/* prepare the bits and mask */
 	shift_width = ce_info->lsb % 8;
-	mask = BIT(ce_info->width) - 1;
+	mask = (u8)(BIT(ce_info->width) - 1);
 
 	src_byte = *from;
 	src_byte &= mask;
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/intel/i40e/i40e_main.c
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/intel/i40e/i40e_main.c
@@ -1,7 +1,7 @@
 /*******************************************************************************
  *
  * Intel Ethernet Controller XL710 Family Linux Driver
- * Copyright(c) 2013 - 2015 Intel Corporation.
+ * Copyright(c) 2013 - 2016 Intel Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms and conditions of the GNU General Public License,
@@ -24,12 +24,19 @@
  *
  ******************************************************************************/
 
+#include <linux/etherdevice.h>
+#include <linux/of_net.h>
+#include <linux/pci.h>
+
 /* Local includes */
 #include "i40e.h"
 #include "i40e_diag.h"
-#ifdef CONFIG_I40E_VXLAN
+#if IS_ENABLED(CONFIG_VXLAN)
 #include <net/vxlan.h>
 #endif
+#if IS_ENABLED(CONFIG_GENEVE)
+#include <net/geneve.h>
+#endif
 
 const char i40e_driver_name[] = "i40e";
 static const char i40e_driver_string[] =
@@ -38,8 +45,8 @@ static const char i40e_driver_string[] =
 #define DRV_KERN "-k"
 
 #define DRV_VERSION_MAJOR 1
-#define DRV_VERSION_MINOR 3
-#define DRV_VERSION_BUILD 46
+#define DRV_VERSION_MINOR 4
+#define DRV_VERSION_BUILD 25
 #define DRV_VERSION __stringify(DRV_VERSION_MAJOR) "." \
 	     __stringify(DRV_VERSION_MINOR) "." \
 	     __stringify(DRV_VERSION_BUILD)    DRV_KERN
@@ -55,6 +62,8 @@ static int i40e_setup_pf_switch(struct i
 static int i40e_setup_misc_vector(struct i40e_pf *pf);
 static void i40e_determine_queue_usage(struct i40e_pf *pf);
 static int i40e_setup_pf_filter_control(struct i40e_pf *pf);
+static void i40e_fill_rss_lut(struct i40e_pf *pf, u8 *lut,
+			      u16 rss_table_size, u16 rss_size);
 static void i40e_fdir_sb_setup(struct i40e_pf *pf);
 static int i40e_veb_get_bw_info(struct i40e_veb *veb);
 
@@ -68,7 +77,6 @@ static int i40e_veb_get_bw_info(struct i
 static const struct pci_device_id i40e_pci_tbl[] = {
 	{PCI_VDEVICE(INTEL, I40E_DEV_ID_SFP_XL710), 0},
 	{PCI_VDEVICE(INTEL, I40E_DEV_ID_QEMU), 0},
-	{PCI_VDEVICE(INTEL, I40E_DEV_ID_KX_A), 0},
 	{PCI_VDEVICE(INTEL, I40E_DEV_ID_KX_B), 0},
 	{PCI_VDEVICE(INTEL, I40E_DEV_ID_KX_C), 0},
 	{PCI_VDEVICE(INTEL, I40E_DEV_ID_QSFP_A), 0},
@@ -77,6 +85,8 @@ static const struct pci_device_id i40e_p
 	{PCI_VDEVICE(INTEL, I40E_DEV_ID_10G_BASE_T), 0},
 	{PCI_VDEVICE(INTEL, I40E_DEV_ID_10G_BASE_T4), 0},
 	{PCI_VDEVICE(INTEL, I40E_DEV_ID_20G_KR2), 0},
+	{PCI_VDEVICE(INTEL, I40E_DEV_ID_KX_X722), 0},
+	{PCI_VDEVICE(INTEL, I40E_DEV_ID_QSFP_X722), 0},
 	{PCI_VDEVICE(INTEL, I40E_DEV_ID_SFP_X722), 0},
 	{PCI_VDEVICE(INTEL, I40E_DEV_ID_1G_BASE_T_X722), 0},
 	{PCI_VDEVICE(INTEL, I40E_DEV_ID_10G_BASE_T_X722), 0},
@@ -97,6 +107,8 @@ MODULE_DESCRIPTION("Intel(R) Ethernet Co
 MODULE_LICENSE("GPL");
 MODULE_VERSION(DRV_VERSION);
 
+static struct workqueue_struct *i40e_wq;
+
 /**
  * i40e_allocate_dma_mem_d - OS specific memory alloc for shared code
  * @hw:   pointer to the HW structure
@@ -282,7 +294,7 @@ static void i40e_service_event_schedule(
 	if (!test_bit(__I40E_DOWN, &pf->state) &&
 	    !test_bit(__I40E_RESET_RECOVERY_PENDING, &pf->state) &&
 	    !test_and_set_bit(__I40E_SERVICE_SCHED, &pf->state))
-		schedule_work(&pf->service_task);
+		queue_work(i40e_wq, &pf->service_task);
 }
 
 /**
@@ -756,7 +768,7 @@ static void i40e_update_fcoe_stats(struc
 	if (vsi->type != I40E_VSI_FCOE)
 		return;
 
-	idx = (pf->pf_seid - I40E_BASE_PF_SEID) + I40E_FCOE_PF_STAT_OFFSET;
+	idx = hw->pf_id + I40E_FCOE_PF_STAT_OFFSET;
 	fs = &vsi->fcoe_stats;
 	ofs = &vsi->fcoe_stats_offsets;
 
@@ -790,75 +802,6 @@ static void i40e_update_fcoe_stats(struc
 
 #endif
 /**
- * i40e_update_link_xoff_rx - Update XOFF received in link flow control mode
- * @pf: the corresponding PF
- *
- * Update the Rx XOFF counter (PAUSE frames) in link flow control mode
- **/
-static void i40e_update_link_xoff_rx(struct i40e_pf *pf)
-{
-	struct i40e_hw_port_stats *osd = &pf->stats_offsets;
-	struct i40e_hw_port_stats *nsd = &pf->stats;
-	struct i40e_hw *hw = &pf->hw;
-	u64 xoff = 0;
-
-	if ((hw->fc.current_mode != I40E_FC_FULL) &&
-	    (hw->fc.current_mode != I40E_FC_RX_PAUSE))
-		return;
-
-	xoff = nsd->link_xoff_rx;
-	i40e_stat_update32(hw, I40E_GLPRT_LXOFFRXC(hw->port),
-			   pf->stat_offsets_loaded,
-			   &osd->link_xoff_rx, &nsd->link_xoff_rx);
-
-	/* No new LFC xoff rx */
-	if (!(nsd->link_xoff_rx - xoff))
-		return;
-
-}
-
-/**
- * i40e_update_prio_xoff_rx - Update XOFF received in PFC mode
- * @pf: the corresponding PF
- *
- * Update the Rx XOFF counter (PAUSE frames) in PFC mode
- **/
-static void i40e_update_prio_xoff_rx(struct i40e_pf *pf)
-{
-	struct i40e_hw_port_stats *osd = &pf->stats_offsets;
-	struct i40e_hw_port_stats *nsd = &pf->stats;
-	bool xoff[I40E_MAX_TRAFFIC_CLASS] = {false};
-	struct i40e_dcbx_config *dcb_cfg;
-	struct i40e_hw *hw = &pf->hw;
-	u16 i;
-	u8 tc;
-
-	dcb_cfg = &hw->local_dcbx_config;
-
-	/* Collect Link XOFF stats when PFC is disabled */
-	if (!dcb_cfg->pfc.pfcenable) {
-		i40e_update_link_xoff_rx(pf);
-		return;
-	}
-
-	for (i = 0; i < I40E_MAX_USER_PRIORITY; i++) {
-		u64 prio_xoff = nsd->priority_xoff_rx[i];
-
-		i40e_stat_update32(hw, I40E_GLPRT_PXOFFRXC(hw->port, i),
-				   pf->stat_offsets_loaded,
-				   &osd->priority_xoff_rx[i],
-				   &nsd->priority_xoff_rx[i]);
-
-		/* No new PFC xoff rx */
-		if (!(nsd->priority_xoff_rx[i] - prio_xoff))
-			continue;
-		/* Get the TC for given priority */
-		tc = dcb_cfg->etscfg.prioritytable[i];
-		xoff[tc] = true;
-	}
-}
-
-/**
  * i40e_update_vsi_stats - Update the vsi statistics counters.
  * @vsi: the VSI to be updated
  *
@@ -876,11 +819,13 @@ static void i40e_update_vsi_stats(struct
 	struct i40e_eth_stats *oes;
 	struct i40e_eth_stats *es;     /* device's eth stats */
 	u32 tx_restart, tx_busy;
+	u64 tx_lost_interrupt;
 	struct i40e_ring *p;
 	u32 rx_page, rx_buf;
 	u64 bytes, packets;
 	unsigned int start;
 	u64 tx_linearize;
+	u64 tx_force_wb;
 	u64 rx_p, rx_b;
 	u64 tx_p, tx_b;
 	u16 q;
@@ -899,7 +844,8 @@ static void i40e_update_vsi_stats(struct
 	 */
 	rx_b = rx_p = 0;
 	tx_b = tx_p = 0;
-	tx_restart = tx_busy = tx_linearize = 0;
+	tx_restart = tx_busy = tx_linearize = tx_force_wb = 0;
+	tx_lost_interrupt = 0;
 	rx_page = 0;
 	rx_buf = 0;
 	rcu_read_lock();
@@ -917,6 +863,8 @@ static void i40e_update_vsi_stats(struct
 		tx_restart += p->tx_stats.restart_queue;
 		tx_busy += p->tx_stats.tx_busy;
 		tx_linearize += p->tx_stats.tx_linearize;
+		tx_force_wb += p->tx_stats.tx_force_wb;
+		tx_lost_interrupt += p->tx_stats.tx_lost_interrupt;
 
 		/* Rx queue is part of the same block as Tx queue */
 		p = &p[1];
@@ -934,6 +882,8 @@ static void i40e_update_vsi_stats(struct
 	vsi->tx_restart = tx_restart;
 	vsi->tx_busy = tx_busy;
 	vsi->tx_linearize = tx_linearize;
+	vsi->tx_force_wb = tx_force_wb;
+	vsi->tx_lost_interrupt = tx_lost_interrupt;
 	vsi->rx_page_failed = rx_page;
 	vsi->rx_buf_failed = rx_buf;
 
@@ -1049,12 +999,18 @@ static void i40e_update_pf_stats(struct
 	i40e_stat_update32(hw, I40E_GLPRT_LXONTXC(hw->port),
 			   pf->stat_offsets_loaded,
 			   &osd->link_xon_tx, &nsd->link_xon_tx);
-	i40e_update_prio_xoff_rx(pf);  /* handles I40E_GLPRT_LXOFFRXC */
+	i40e_stat_update32(hw, I40E_GLPRT_LXOFFRXC(hw->port),
+			   pf->stat_offsets_loaded,
+			   &osd->link_xoff_rx, &nsd->link_xoff_rx);
 	i40e_stat_update32(hw, I40E_GLPRT_LXOFFTXC(hw->port),
 			   pf->stat_offsets_loaded,
 			   &osd->link_xoff_tx, &nsd->link_xoff_tx);
 
 	for (i = 0; i < 8; i++) {
+		i40e_stat_update32(hw, I40E_GLPRT_PXOFFRXC(hw->port, i),
+				   pf->stat_offsets_loaded,
+				   &osd->priority_xoff_rx[i],
+				   &nsd->priority_xoff_rx[i]);
 		i40e_stat_update32(hw, I40E_GLPRT_PXONRXC(hw->port, i),
 				   pf->stat_offsets_loaded,
 				   &osd->priority_xon_rx[i],
@@ -1317,6 +1273,42 @@ struct i40e_mac_filter *i40e_put_mac_in_
 }
 
 /**
+ * i40e_del_mac_all_vlan - Remove a MAC filter from all VLANS
+ * @vsi: the VSI to be searched
+ * @macaddr: the mac address to be removed
+ * @is_vf: true if it is a VF
+ * @is_netdev: true if it is a netdev
+ *
+ * Removes a given MAC address from a VSI, regardless of VLAN
+ *
+ * Returns 0 for success, or error
+ **/
+int i40e_del_mac_all_vlan(struct i40e_vsi *vsi, u8 *macaddr,
+			  bool is_vf, bool is_netdev)
+{
+	struct i40e_mac_filter *f = NULL;
+	int changed = 0;
+
+	WARN(!spin_is_locked(&vsi->mac_filter_list_lock),
+	     "Missing mac_filter_list_lock\n");
+	list_for_each_entry(f, &vsi->mac_filter_list, list) {
+		if ((ether_addr_equal(macaddr, f->macaddr)) &&
+		    (is_vf == f->is_vf) &&
+		    (is_netdev == f->is_netdev)) {
+			f->counter--;
+			f->changed = true;
+			changed = 1;
+		}
+	}
+	if (changed) {
+		vsi->flags |= I40E_VSI_FLAG_FILTER_CHANGED;
+		vsi->back->flags |= I40E_FLAG_FILTER_SYNC;
+		return 0;
+	}
+	return -ENOENT;
+}
+
+/**
  * i40e_rm_default_mac_filter - Remove the default MAC filter set by NVM
  * @vsi: the PF Main VSI - inappropriate for any other VSI
  * @macaddr: the MAC address
@@ -1379,7 +1371,7 @@ struct i40e_mac_filter *i40e_add_filter(
 		f->changed = true;
 
 		INIT_LIST_HEAD(&f->list);
-		list_add(&f->list, &vsi->mac_filter_list);
+		list_add_tail(&f->list, &vsi->mac_filter_list);
 	}
 
 	/* increment counter and add a new flag if needed */
@@ -1547,10 +1539,9 @@ static int i40e_set_mac(struct net_devic
 		spin_unlock_bh(&vsi->mac_filter_list_lock);
 	}
 
-	i40e_sync_vsi_filters(vsi, false);
 	ether_addr_copy(netdev->dev_addr, addr->sa_data);
 
-	return 0;
+	return i40e_sync_vsi_filters(vsi);
 }
 
 /**
@@ -1590,7 +1581,7 @@ static void i40e_vsi_setup_queue_map(str
 	if (enabled_tc && (vsi->back->flags & I40E_FLAG_DCB_ENABLED)) {
 		/* Find numtc from enabled TC bitmap */
 		for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++) {
-			if (enabled_tc & BIT_ULL(i)) /* TC is enabled */
+			if (enabled_tc & BIT(i)) /* TC is enabled */
 				numtc++;
 		}
 		if (!numtc) {
@@ -1619,13 +1610,14 @@ static void i40e_vsi_setup_queue_map(str
 	/* Setup queue offset/count for all TCs for given VSI */
 	for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++) {
 		/* See if the given TC is enabled for the given VSI */
-		if (vsi->tc_config.enabled_tc & BIT_ULL(i)) {
+		if (vsi->tc_config.enabled_tc & BIT(i)) {
 			/* TC is enabled */
 			int pow, num_qps;
 
 			switch (vsi->type) {
 			case I40E_VSI_MAIN:
-				qcount = min_t(int, pf->rss_size, num_tc_qps);
+				qcount = min_t(int, pf->alloc_rss_size,
+					       num_tc_qps);
 				break;
 #ifdef I40E_FCOE
 			case I40E_VSI_FCOE:
@@ -1851,13 +1843,12 @@ static void i40e_cleanup_add_list(struct
 /**
  * i40e_sync_vsi_filters - Update the VSI filter list to the HW
  * @vsi: ptr to the VSI
- * @grab_rtnl: whether RTNL needs to be grabbed
  *
  * Push any outstanding VSI filter changes through the AdminQ.
  *
  * Returns 0 or error value
  **/
-int i40e_sync_vsi_filters(struct i40e_vsi *vsi, bool grab_rtnl)
+int i40e_sync_vsi_filters(struct i40e_vsi *vsi)
 {
 	struct list_head tmp_del_list, tmp_add_list;
 	struct i40e_mac_filter *f, *ftmp, *fclone;
@@ -1865,8 +1856,9 @@ int i40e_sync_vsi_filters(struct i40e_vs
 	bool add_happened = false;
 	int filter_list_len = 0;
 	u32 changed_flags = 0;
+	i40e_status aq_ret = 0;
 	bool err_cond = false;
-	i40e_status ret = 0;
+	int retval = 0;
 	struct i40e_pf *pf;
 	int num_add = 0;
 	int num_del = 0;
@@ -1929,17 +1921,22 @@ int i40e_sync_vsi_filters(struct i40e_vs
 		}
 		spin_unlock_bh(&vsi->mac_filter_list_lock);
 
-		if (err_cond)
+		if (err_cond) {
 			i40e_cleanup_add_list(&tmp_add_list);
+			retval = -ENOMEM;
+			goto out;
+		}
 	}
 
 	/* Now process 'del_list' outside the lock */
 	if (!list_empty(&tmp_del_list)) {
+		int del_list_size;
+
 		filter_list_len = pf->hw.aq.asq_buf_size /
 			    sizeof(struct i40e_aqc_remove_macvlan_element_data);
-		del_list = kcalloc(filter_list_len,
-			    sizeof(struct i40e_aqc_remove_macvlan_element_data),
-			    GFP_KERNEL);
+		del_list_size = filter_list_len *
+			    sizeof(struct i40e_aqc_remove_macvlan_element_data);
+		del_list = kzalloc(del_list_size, GFP_ATOMIC);
 		if (!del_list) {
 			i40e_cleanup_add_list(&tmp_add_list);
 
@@ -1948,7 +1945,8 @@ int i40e_sync_vsi_filters(struct i40e_vs
 			i40e_undo_del_filter_entries(vsi, &tmp_del_list);
 			i40e_undo_add_filter_entries(vsi);
 			spin_unlock_bh(&vsi->mac_filter_list_lock);
-			return -ENOMEM;
+			retval = -ENOMEM;
+			goto out;
 		}
 
 		list_for_each_entry_safe(f, ftmp, &tmp_del_list, list) {
@@ -1966,18 +1964,22 @@ int i40e_sync_vsi_filters(struct i40e_vs
 
 			/* flush a full buffer */
 			if (num_del == filter_list_len) {
-				ret = i40e_aq_remove_macvlan(&pf->hw,
-						  vsi->seid, del_list, num_del,
-						  NULL);
+				aq_ret = i40e_aq_remove_macvlan(&pf->hw,
+								vsi->seid,
+								del_list,
+								num_del,
+								NULL);
 				aq_err = pf->hw.aq.asq_last_status;
 				num_del = 0;
-				memset(del_list, 0, sizeof(*del_list));
+				memset(del_list, 0, del_list_size);
 
-				if (ret && aq_err != I40E_AQ_RC_ENOENT)
+				if (aq_ret && aq_err != I40E_AQ_RC_ENOENT) {
+					retval = -EIO;
 					dev_err(&pf->pdev->dev,
 						"ignoring delete macvlan error, err %s, aq_err %s while flushing a full buffer\n",
-						i40e_stat_str(&pf->hw, ret),
+						i40e_stat_str(&pf->hw, aq_ret),
 						i40e_aq_str(&pf->hw, aq_err));
+				}
 			}
 			/* Release memory for MAC filter entries which were
 			 * synced up with HW.
@@ -1987,15 +1989,16 @@ int i40e_sync_vsi_filters(struct i40e_vs
 		}
 
 		if (num_del) {
-			ret = i40e_aq_remove_macvlan(&pf->hw, vsi->seid,
-						     del_list, num_del, NULL);
+			aq_ret = i40e_aq_remove_macvlan(&pf->hw, vsi->seid,
+							del_list, num_del,
+							NULL);
 			aq_err = pf->hw.aq.asq_last_status;
 			num_del = 0;
 
-			if (ret && aq_err != I40E_AQ_RC_ENOENT)
+			if (aq_ret && aq_err != I40E_AQ_RC_ENOENT)
 				dev_info(&pf->pdev->dev,
 					 "ignoring delete macvlan error, err %s aq_err %s\n",
-					 i40e_stat_str(&pf->hw, ret),
+					 i40e_stat_str(&pf->hw, aq_ret),
 					 i40e_aq_str(&pf->hw, aq_err));
 		}
 
@@ -2004,13 +2007,14 @@ int i40e_sync_vsi_filters(struct i40e_vs
 	}
 
 	if (!list_empty(&tmp_add_list)) {
+		int add_list_size;
 
 		/* do all the adds now */
 		filter_list_len = pf->hw.aq.asq_buf_size /
 			       sizeof(struct i40e_aqc_add_macvlan_element_data),
-		add_list = kcalloc(filter_list_len,
-			       sizeof(struct i40e_aqc_add_macvlan_element_data),
-			       GFP_KERNEL);
+		add_list_size = filter_list_len *
+			       sizeof(struct i40e_aqc_add_macvlan_element_data);
+		add_list = kzalloc(add_list_size, GFP_ATOMIC);
 		if (!add_list) {
 			/* Purge element from temporary lists */
 			i40e_cleanup_add_list(&tmp_add_list);
@@ -2019,7 +2023,8 @@ int i40e_sync_vsi_filters(struct i40e_vs
 			spin_lock_bh(&vsi->mac_filter_list_lock);
 			i40e_undo_add_filter_entries(vsi);
 			spin_unlock_bh(&vsi->mac_filter_list_lock);
-			return -ENOMEM;
+			retval = -ENOMEM;
+			goto out;
 		}
 
 		list_for_each_entry_safe(f, ftmp, &tmp_add_list, list) {
@@ -2040,15 +2045,15 @@ int i40e_sync_vsi_filters(struct i40e_vs
 
 			/* flush a full buffer */
 			if (num_add == filter_list_len) {
-				ret = i40e_aq_add_macvlan(&pf->hw, vsi->seid,
-							  add_list, num_add,
-							  NULL);
+				aq_ret = i40e_aq_add_macvlan(&pf->hw, vsi->seid,
+							     add_list, num_add,
+							     NULL);
 				aq_err = pf->hw.aq.asq_last_status;
 				num_add = 0;
 
-				if (ret)
+				if (aq_ret)
 					break;
-				memset(add_list, 0, sizeof(*add_list));
+				memset(add_list, 0, add_list_size);
 			}
 			/* Entries from tmp_add_list were cloned from MAC
 			 * filter list, hence clean those cloned entries
@@ -2058,18 +2063,19 @@ int i40e_sync_vsi_filters(struct i40e_vs
 		}
 
 		if (num_add) {
-			ret = i40e_aq_add_macvlan(&pf->hw, vsi->seid,
-						  add_list, num_add, NULL);
+			aq_ret = i40e_aq_add_macvlan(&pf->hw, vsi->seid,
+						     add_list, num_add, NULL);
 			aq_err = pf->hw.aq.asq_last_status;
 			num_add = 0;
 		}
 		kfree(add_list);
 		add_list = NULL;
 
-		if (add_happened && ret && aq_err != I40E_AQ_RC_EINVAL) {
+		if (add_happened && aq_ret && aq_err != I40E_AQ_RC_EINVAL) {
+			retval = i40e_aq_rc_to_posix(aq_ret, aq_err);
 			dev_info(&pf->pdev->dev,
 				 "add filter failed, err %s aq_err %s\n",
-				 i40e_stat_str(&pf->hw, ret),
+				 i40e_stat_str(&pf->hw, aq_ret),
 				 i40e_aq_str(&pf->hw, aq_err));
 			if ((pf->hw.aq.asq_last_status == I40E_AQ_RC_ENOSPC) &&
 			    !test_bit(__I40E_FILTER_OVERFLOW_PROMISC,
@@ -2087,16 +2093,19 @@ int i40e_sync_vsi_filters(struct i40e_vs
 		bool cur_multipromisc;
 
 		cur_multipromisc = !!(vsi->current_netdev_flags & IFF_ALLMULTI);
-		ret = i40e_aq_set_vsi_multicast_promiscuous(&vsi->back->hw,
-							    vsi->seid,
-							    cur_multipromisc,
-							    NULL);
-		if (ret)
+		aq_ret = i40e_aq_set_vsi_multicast_promiscuous(&vsi->back->hw,
+							       vsi->seid,
+							       cur_multipromisc,
+							       NULL);
+		if (aq_ret) {
+			retval = i40e_aq_rc_to_posix(aq_ret,
+						     pf->hw.aq.asq_last_status);
 			dev_info(&pf->pdev->dev,
 				 "set multi promisc failed, err %s aq_err %s\n",
-				 i40e_stat_str(&pf->hw, ret),
+				 i40e_stat_str(&pf->hw, aq_ret),
 				 i40e_aq_str(&pf->hw,
 					     pf->hw.aq.asq_last_status));
+		}
 	}
 	if ((changed_flags & IFF_PROMISC) || promisc_forced_on) {
 		bool cur_promisc;
@@ -2104,7 +2113,9 @@ int i40e_sync_vsi_filters(struct i40e_vs
 		cur_promisc = (!!(vsi->current_netdev_flags & IFF_PROMISC) ||
 			       test_bit(__I40E_FILTER_OVERFLOW_PROMISC,
 					&vsi->state));
-		if (vsi->type == I40E_VSI_MAIN && pf->lan_veb != I40E_NO_VEB) {
+		if ((vsi->type == I40E_VSI_MAIN) &&
+		    (pf->lan_veb != I40E_NO_VEB) &&
+		    !(pf->flags & I40E_FLAG_MFP_ENABLED)) {
 			/* set defport ON for Main VSI instead of true promisc
 			 * this way we will get all unicast/multicast and VLAN
 			 * promisc behavior but will not get VF or VMDq traffic
@@ -2112,44 +2123,54 @@ int i40e_sync_vsi_filters(struct i40e_vs
 			 */
 			if (pf->cur_promisc != cur_promisc) {
 				pf->cur_promisc = cur_promisc;
-				if (grab_rtnl)
-					i40e_do_reset_safe(pf,
-						BIT(__I40E_PF_RESET_REQUESTED));
-				else
-					i40e_do_reset(pf,
-						BIT(__I40E_PF_RESET_REQUESTED));
+				set_bit(__I40E_PF_RESET_REQUESTED, &pf->state);
 			}
 		} else {
-			ret = i40e_aq_set_vsi_unicast_promiscuous(
+			aq_ret = i40e_aq_set_vsi_unicast_promiscuous(
 							  &vsi->back->hw,
 							  vsi->seid,
 							  cur_promisc, NULL);
-			if (ret)
+			if (aq_ret) {
+				retval =
+				i40e_aq_rc_to_posix(aq_ret,
+						    pf->hw.aq.asq_last_status);
 				dev_info(&pf->pdev->dev,
 					 "set unicast promisc failed, err %d, aq_err %d\n",
-					 ret, pf->hw.aq.asq_last_status);
-			ret = i40e_aq_set_vsi_multicast_promiscuous(
+					 aq_ret, pf->hw.aq.asq_last_status);
+			}
+			aq_ret = i40e_aq_set_vsi_multicast_promiscuous(
 							  &vsi->back->hw,
 							  vsi->seid,
 							  cur_promisc, NULL);
-			if (ret)
+			if (aq_ret) {
+				retval =
+				i40e_aq_rc_to_posix(aq_ret,
+						    pf->hw.aq.asq_last_status);
 				dev_info(&pf->pdev->dev,
 					 "set multicast promisc failed, err %d, aq_err %d\n",
-					 ret, pf->hw.aq.asq_last_status);
+					 aq_ret, pf->hw.aq.asq_last_status);
+			}
 		}
-		ret = i40e_aq_set_vsi_broadcast(&vsi->back->hw,
-						vsi->seid,
-						cur_promisc, NULL);
-		if (ret)
+		aq_ret = i40e_aq_set_vsi_broadcast(&vsi->back->hw,
+						   vsi->seid,
+						   cur_promisc, NULL);
+		if (aq_ret) {
+			retval = i40e_aq_rc_to_posix(aq_ret,
+						     pf->hw.aq.asq_last_status);
 			dev_info(&pf->pdev->dev,
 				 "set brdcast promisc failed, err %s, aq_err %s\n",
-				 i40e_stat_str(&pf->hw, ret),
+				 i40e_stat_str(&pf->hw, aq_ret),
 				 i40e_aq_str(&pf->hw,
 					     pf->hw.aq.asq_last_status));
+		}
 	}
+out:
+	/* if something went wrong then set the changed flag so we try again */
+	if (retval)
+		vsi->flags |= I40E_VSI_FLAG_FILTER_CHANGED;
 
 	clear_bit(__I40E_CONFIG_BUSY, &vsi->state);
-	return 0;
+	return retval;
 }
 
 /**
@@ -2166,8 +2187,15 @@ static void i40e_sync_filters_subtask(st
 
 	for (v = 0; v < pf->num_alloc_vsi; v++) {
 		if (pf->vsi[v] &&
-		    (pf->vsi[v]->flags & I40E_VSI_FLAG_FILTER_CHANGED))
-			i40e_sync_vsi_filters(pf->vsi[v], true);
+		    (pf->vsi[v]->flags & I40E_VSI_FLAG_FILTER_CHANGED)) {
+			int ret = i40e_sync_vsi_filters(pf->vsi[v]);
+
+			if (ret) {
+				/* come back and try again later */
+				pf->flags |= I40E_FLAG_FILTER_SYNC;
+				break;
+			}
+		}
 	}
 }
 
@@ -2377,16 +2405,13 @@ int i40e_vsi_add_vlan(struct i40e_vsi *v
 		}
 	}
 
-	/* Make sure to release before sync_vsi_filter because that
-	 * function will lock/unlock as necessary
-	 */
 	spin_unlock_bh(&vsi->mac_filter_list_lock);
 
-	if (test_bit(__I40E_DOWN, &vsi->back->state) ||
-	    test_bit(__I40E_RESET_RECOVERY_PENDING, &vsi->back->state))
-		return 0;
-
-	return i40e_sync_vsi_filters(vsi, false);
+	/* schedule our worker thread which will take care of
+	 * applying the new filter changes
+	 */
+	i40e_service_event_schedule(vsi->back);
+	return 0;
 }
 
 /**
@@ -2459,16 +2484,13 @@ int i40e_vsi_kill_vlan(struct i40e_vsi *
 		}
 	}
 
-	/* Make sure to release before sync_vsi_filter because that
-	 * function with lock/unlock as necessary
-	 */
 	spin_unlock_bh(&vsi->mac_filter_list_lock);
 
-	if (test_bit(__I40E_DOWN, &vsi->back->state) ||
-	    test_bit(__I40E_RESET_RECOVERY_PENDING, &vsi->back->state))
-		return 0;
-
-	return i40e_sync_vsi_filters(vsi, false);
+	/* schedule our worker thread which will take care of
+	 * applying the new filter changes
+	 */
+	i40e_service_event_schedule(vsi->back);
+	return 0;
 }
 
 /**
@@ -2711,6 +2733,11 @@ static void i40e_config_xps_tx_ring(stru
 		netif_set_xps_queue(ring->netdev, mask, ring->queue_index);
 		free_cpumask_var(mask);
 	}
+
+	/* schedule our worker thread which will take care of
+	 * applying the new filter changes
+	 */
+	i40e_service_event_schedule(vsi->back);
 }
 
 /**
@@ -3227,14 +3254,15 @@ void i40e_irq_dynamic_disable_icr0(struc
 /**
  * i40e_irq_dynamic_enable_icr0 - Enable default interrupt generation for icr0
  * @pf: board private structure
+ * @clearpba: true when all pending interrupt events should be cleared
  **/
-void i40e_irq_dynamic_enable_icr0(struct i40e_pf *pf)
+void i40e_irq_dynamic_enable_icr0(struct i40e_pf *pf, bool clearpba)
 {
 	struct i40e_hw *hw = &pf->hw;
 	u32 val;
 
 	val = I40E_PFINT_DYN_CTL0_INTENA_MASK   |
-	      I40E_PFINT_DYN_CTL0_CLEARPBA_MASK |
+	      (clearpba ? I40E_PFINT_DYN_CTL0_CLEARPBA_MASK : 0) |
 	      (I40E_ITR_NONE << I40E_PFINT_DYN_CTL0_ITR_INDX_SHIFT);
 
 	wr32(hw, I40E_PFINT_DYN_CTL0, val);
@@ -3242,22 +3270,6 @@ void i40e_irq_dynamic_enable_icr0(struct
 }
 
 /**
- * i40e_irq_dynamic_disable - Disable default interrupt generation settings
- * @vsi: pointer to a vsi
- * @vector: disable a particular Hw Interrupt vector
- **/
-void i40e_irq_dynamic_disable(struct i40e_vsi *vsi, int vector)
-{
-	struct i40e_pf *pf = vsi->back;
-	struct i40e_hw *hw = &pf->hw;
-	u32 val;
-
-	val = I40E_ITR_NONE << I40E_PFINT_DYN_CTLN_ITR_INDX_SHIFT;
-	wr32(hw, I40E_PFINT_DYN_CTLN(vector - 1), val);
-	i40e_flush(hw);
-}
-
-/**
  * i40e_msix_clean_rings - MSIX mode Interrupt Handler
  * @irq: interrupt number
  * @data: pointer to a q_vector
@@ -3382,7 +3394,7 @@ static int i40e_vsi_enable_irq(struct i4
 		for (i = 0; i < vsi->num_q_vectors; i++)
 			i40e_irq_dynamic_enable(vsi, i);
 	} else {
-		i40e_irq_dynamic_enable_icr0(pf);
+		i40e_irq_dynamic_enable_icr0(pf, true);
 	}
 
 	i40e_flush(&pf->hw);
@@ -3441,16 +3453,12 @@ static irqreturn_t i40e_intr(int irq, vo
 		struct i40e_vsi *vsi = pf->vsi[pf->lan_vsi];
 		struct i40e_q_vector *q_vector = vsi->q_vectors[0];
 
-		/* temporarily disable queue cause for NAPI processing */
-		u32 qval = rd32(hw, I40E_QINT_RQCTL(0));
-
-		qval &= ~I40E_QINT_RQCTL_CAUSE_ENA_MASK;
-		wr32(hw, I40E_QINT_RQCTL(0), qval);
-
-		qval = rd32(hw, I40E_QINT_TQCTL(0));
-		qval &= ~I40E_QINT_TQCTL_CAUSE_ENA_MASK;
-		wr32(hw, I40E_QINT_TQCTL(0), qval);
-
+		/* We do not have a way to disarm Queue causes while leaving
+		 * interrupt enabled for all other causes, ideally
+		 * interrupt should be disabled while we are in NAPI but
+		 * this is not a performance path and napi_schedule()
+		 * can deal with rescheduling.
+		 */
 		if (!test_bit(__I40E_DOWN, &pf->state))
 			napi_schedule_irqoff(&q_vector->napi);
 	}
@@ -3458,6 +3466,7 @@ static irqreturn_t i40e_intr(int irq, vo
 	if (icr0 & I40E_PFINT_ICR0_ADMINQ_MASK) {
 		ena_mask &= ~I40E_PFINT_ICR0_ENA_ADMINQ_MASK;
 		set_bit(__I40E_ADMINQ_EVENT_PENDING, &pf->state);
+		i40e_debug(&pf->hw, I40E_DEBUG_NVM, "AdminQ event\n");
 	}
 
 	if (icr0 & I40E_PFINT_ICR0_MAL_DETECT_MASK) {
@@ -3528,7 +3537,7 @@ enable_intr:
 	wr32(hw, I40E_PFINT_ICR0_ENA, ena_mask);
 	if (!test_bit(__I40E_DOWN, &pf->state)) {
 		i40e_service_event_schedule(pf);
-		i40e_irq_dynamic_enable_icr0(pf);
+		i40e_irq_dynamic_enable_icr0(pf, false);
 	}
 
 	return ret;
@@ -3732,7 +3741,7 @@ static int i40e_vsi_request_irq(struct i
 
 #ifdef CONFIG_NET_POLL_CONTROLLER
 /**
- * i40e_netpoll - A Polling 'interrupt'handler
+ * i40e_netpoll - A Polling 'interrupt' handler
  * @netdev: network interface device structure
  *
  * This is used by netconsole to send skbs without having to re-enable
@@ -3911,6 +3920,9 @@ static int i40e_vsi_control_rx(struct i4
 		else
 			rx_reg &= ~I40E_QRX_ENA_QENA_REQ_MASK;
 		wr32(hw, I40E_QRX_ENA(pf_q), rx_reg);
+		/* No waiting for the Tx queue to disable */
+		if (!enable && test_bit(__I40E_PORT_TX_SUSPENDED, &pf->state))
+			continue;
 
 		/* wait for the change to finish */
 		ret = i40e_pf_rxq_wait(pf, pf_q, enable);
@@ -4269,12 +4281,12 @@ static void i40e_pf_unquiesce_all_vsi(st
 
 #ifdef CONFIG_I40E_DCB
 /**
- * i40e_vsi_wait_txq_disabled - Wait for VSI's queues to be disabled
+ * i40e_vsi_wait_queues_disabled - Wait for VSI's queues to be disabled
  * @vsi: the VSI being configured
  *
- * This function waits for the given VSI's Tx queues to be disabled.
+ * This function waits for the given VSI's queues to be disabled.
  **/
-static int i40e_vsi_wait_txq_disabled(struct i40e_vsi *vsi)
+static int i40e_vsi_wait_queues_disabled(struct i40e_vsi *vsi)
 {
 	struct i40e_pf *pf = vsi->back;
 	int i, pf_q, ret;
@@ -4291,24 +4303,36 @@ static int i40e_vsi_wait_txq_disabled(st
 		}
 	}
 
+	pf_q = vsi->base_queue;
+	for (i = 0; i < vsi->num_queue_pairs; i++, pf_q++) {
+		/* Check and wait for the disable status of the queue */
+		ret = i40e_pf_rxq_wait(pf, pf_q, false);
+		if (ret) {
+			dev_info(&pf->pdev->dev,
+				 "VSI seid %d Rx ring %d disable timeout\n",
+				 vsi->seid, pf_q);
+			return ret;
+		}
+	}
+
 	return 0;
 }
 
 /**
- * i40e_pf_wait_txq_disabled - Wait for all queues of PF VSIs to be disabled
+ * i40e_pf_wait_queues_disabled - Wait for all queues of PF VSIs to be disabled
  * @pf: the PF
  *
- * This function waits for the Tx queues to be in disabled state for all the
+ * This function waits for the queues to be in disabled state for all the
  * VSIs that are managed by this PF.
  **/
-static int i40e_pf_wait_txq_disabled(struct i40e_pf *pf)
+static int i40e_pf_wait_queues_disabled(struct i40e_pf *pf)
 {
 	int v, ret = 0;
 
 	for (v = 0; v < pf->hw.func_caps.num_vsis; v++) {
 		/* No need to wait for FCoE VSI queues */
 		if (pf->vsi[v] && pf->vsi[v]->type != I40E_VSI_FCOE) {
-			ret = i40e_vsi_wait_txq_disabled(pf->vsi[v]);
+			ret = i40e_vsi_wait_queues_disabled(pf->vsi[v]);
 			if (ret)
 				break;
 		}
@@ -4334,7 +4358,7 @@ static void i40e_detect_recover_hung_que
 {
 	struct i40e_ring *tx_ring = NULL;
 	struct i40e_pf	*pf;
-	u32 head, val, tx_pending;
+	u32 head, val, tx_pending_hw;
 	int i;
 
 	pf = vsi->back;
@@ -4362,15 +4386,43 @@ static void i40e_detect_recover_hung_que
 
 	head = i40e_get_head(tx_ring);
 
-	tx_pending = i40e_get_tx_pending(tx_ring);
+	tx_pending_hw = i40e_get_tx_pending(tx_ring, false);
 
-	/* Interrupts are disabled and TX pending is non-zero,
-	 * trigger the SW interrupt (don't wait). Worst case
-	 * there will be one extra interrupt which may result
-	 * into not cleaning any queues because queues are cleaned.
+	/* HW is done executing descriptors, updated HEAD write back,
+	 * but SW hasn't processed those descriptors. If interrupt is
+	 * not generated from this point ON, it could result into
+	 * dev_watchdog detecting timeout on those netdev_queue,
+	 * hence proactively trigger SW interrupt.
+	 */
+	if (tx_pending_hw && (!(val & I40E_PFINT_DYN_CTLN_INTENA_MASK))) {
+		/* NAPI Poll didn't run and clear since it was set */
+		if (test_and_clear_bit(I40E_Q_VECTOR_HUNG_DETECT,
+				       &tx_ring->q_vector->hung_detected)) {
+			netdev_info(vsi->netdev, "VSI_seid %d, Hung TX queue %d, tx_pending_hw: %d, NTC:0x%x, HWB: 0x%x, NTU: 0x%x, TAIL: 0x%x\n",
+				    vsi->seid, q_idx, tx_pending_hw,
+				    tx_ring->next_to_clean, head,
+				    tx_ring->next_to_use,
+				    readl(tx_ring->tail));
+			netdev_info(vsi->netdev, "VSI_seid %d, Issuing force_wb for TX queue %d, Interrupt Reg: 0x%x\n",
+				    vsi->seid, q_idx, val);
+			i40e_force_wb(vsi, tx_ring->q_vector);
+		} else {
+			/* First Chance - detected possible hung */
+			set_bit(I40E_Q_VECTOR_HUNG_DETECT,
+				&tx_ring->q_vector->hung_detected);
+		}
+	}
+
+	/* This is the case where we have interrupts missing,
+	 * so the tx_pending in HW will most likely be 0, but we
+	 * will have tx_pending in SW since the WB happened but the
+	 * interrupt got lost.
 	 */
-	if (tx_pending && (!(val & I40E_PFINT_DYN_CTLN_INTENA_MASK)))
-		i40e_force_wb(vsi, tx_ring->q_vector);
+	if ((!tx_pending_hw) && i40e_get_tx_pending(tx_ring, true) &&
+	    (!(val & I40E_PFINT_DYN_CTLN_INTENA_MASK))) {
+		if (napi_reschedule(&tx_ring->q_vector->napi))
+			tx_ring->tx_stats.tx_lost_interrupt++;
+	}
 }
 
 /**
@@ -4441,7 +4493,7 @@ static u8 i40e_get_iscsi_tc_map(struct i
 		if (app.selector == I40E_APP_SEL_TCPIP &&
 		    app.protocolid == I40E_APP_PROTOID_ISCSI) {
 			tc = dcbcfg->etscfg.prioritytable[app.priority];
-			enabled_tc |= BIT_ULL(tc);
+			enabled_tc |= BIT(tc);
 			break;
 		}
 	}
@@ -4525,7 +4577,7 @@ static u8 i40e_pf_get_num_tc(struct i40e
 	/* At least have TC0 */
 	enabled_tc = (enabled_tc ? enabled_tc : 0x1);
 	for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++) {
-		if (enabled_tc & BIT_ULL(i))
+		if (enabled_tc & BIT(i))
 			num_tc++;
 	}
 	return num_tc;
@@ -4547,7 +4599,7 @@ static u8 i40e_pf_get_default_tc(struct
 
 	/* Find the first enabled TC */
 	for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++) {
-		if (enabled_tc & BIT_ULL(i))
+		if (enabled_tc & BIT(i))
 			break;
 	}
 
@@ -4707,7 +4759,7 @@ static void i40e_vsi_config_netdev_tc(st
 		 * will set the numtc for netdev as 2 that will be
 		 * referenced by the netdev layer as TC 0 and 1.
 		 */
-		if (vsi->tc_config.enabled_tc & BIT_ULL(i))
+		if (vsi->tc_config.enabled_tc & BIT(i))
 			netdev_set_tc_queue(netdev,
 					vsi->tc_config.tc_info[i].netdev_tc,
 					vsi->tc_config.tc_info[i].qcount,
@@ -4769,7 +4821,7 @@ static int i40e_vsi_config_tc(struct i40
 
 	/* Enable ETS TCs with equal BW Share for now across all VSIs */
 	for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++) {
-		if (enabled_tc & BIT_ULL(i))
+		if (enabled_tc & BIT(i))
 			bw_share[i] = 1;
 	}
 
@@ -4843,7 +4895,7 @@ int i40e_veb_config_tc(struct i40e_veb *
 
 	/* Enable ETS TCs with equal BW Share for now */
 	for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++) {
-		if (enabled_tc & BIT_ULL(i))
+		if (enabled_tc & BIT(i))
 			bw_data.tc_bw_share_credits[i] = 1;
 	}
 
@@ -4974,8 +5026,7 @@ static int i40e_init_pf_dcb(struct i40e_
 	int err = 0;
 
 	/* Do not enable DCB for SW1 and SW2 images even if the FW is capable */
-	if (((pf->hw.aq.fw_maj_ver == 4) && (pf->hw.aq.fw_min_ver < 33)) ||
-	    (pf->hw.aq.fw_maj_ver < 4))
+	if (pf->flags & I40E_FLAG_NO_DCB_SUPPORT)
 		goto out;
 
 	/* Get the initial DCB configuration */
@@ -5207,11 +5258,7 @@ void i40e_down(struct i40e_vsi *vsi)
  * @netdev: net device to configure
  * @tc: number of traffic classes to enable
  **/
-#ifdef I40E_FCOE
-int i40e_setup_tc(struct net_device *netdev, u8 tc)
-#else
 static int i40e_setup_tc(struct net_device *netdev, u8 tc)
-#endif
 {
 	struct i40e_netdev_priv *np = netdev_priv(netdev);
 	struct i40e_vsi *vsi = np->vsi;
@@ -5240,7 +5287,7 @@ static int i40e_setup_tc(struct net_devi
 
 	/* Generate TC map for number of tc requested */
 	for (i = 0; i < tc; i++)
-		enabled_tc |= BIT_ULL(i);
+		enabled_tc |= BIT(i);
 
 	/* Requesting same TC configuration as already enabled */
 	if (enabled_tc == vsi->tc_config.enabled_tc)
@@ -5264,6 +5311,19 @@ exit:
 	return ret;
 }
 
+#ifdef I40E_FCOE
+int __i40e_setup_tc(struct net_device *netdev, u32 handle, __be16 proto,
+		    struct tc_to_netdev *tc)
+#else
+static int __i40e_setup_tc(struct net_device *netdev, u32 handle, __be16 proto,
+			   struct tc_to_netdev *tc)
+#endif
+{
+	if (handle != TC_H_ROOT || tc->type != TC_SETUP_MQPRIO)
+		return -EINVAL;
+	return i40e_setup_tc(netdev, tc->tc);
+}
+
 /**
  * i40e_open - Called when a network interface is made active
  * @netdev: network interface device structure
@@ -5305,6 +5365,10 @@ int i40e_open(struct net_device *netdev)
 #ifdef CONFIG_I40E_VXLAN
 	vxlan_get_rx_port(netdev);
 #endif
+#ifdef CONFIG_I40E_GENEVE
+	if (pf->flags & I40E_FLAG_GENEVE_OFFLOAD_CAPABLE)
+		geneve_get_rx_port(netdev);
+#endif
 
 	return 0;
 }
@@ -5668,8 +5732,8 @@ static int i40e_handle_lldp_event(struct
 	if (ret)
 		goto exit;
 
-	/* Wait for the PF's Tx queues to be disabled */
-	ret = i40e_pf_wait_txq_disabled(pf);
+	/* Wait for the PF's queues to be disabled */
+	ret = i40e_pf_wait_queues_disabled(pf);
 	if (ret) {
 		/* Schedule PF reset to recover */
 		set_bit(__I40E_PF_RESET_REQUESTED, &pf->state);
@@ -5738,7 +5802,7 @@ static void i40e_handle_lan_overflow_eve
  **/
 static void i40e_service_event_complete(struct i40e_pf *pf)
 {
-	BUG_ON(!test_bit(__I40E_SERVICE_SCHED, &pf->state));
+	WARN_ON(!test_bit(__I40E_SERVICE_SCHED, &pf->state));
 
 	/* flush memory to make sure state is correct before next watchog */
 	smp_mb__before_atomic();
@@ -6013,6 +6077,9 @@ static void i40e_link_event(struct i40e_
 	i40e_status status;
 	bool new_link, old_link;
 
+	/* save off old link status information */
+	pf->hw.phy.link_info_old = pf->hw.phy.link_info;
+
 	/* set this to force the get_link_status call to refresh state */
 	pf->hw.phy.get_link_info = true;
 
@@ -6101,23 +6168,23 @@ static void i40e_reset_subtask(struct i4
 
 	rtnl_lock();
 	if (test_bit(__I40E_REINIT_REQUESTED, &pf->state)) {
-		reset_flags |= BIT_ULL(__I40E_REINIT_REQUESTED);
+		reset_flags |= BIT(__I40E_REINIT_REQUESTED);
 		clear_bit(__I40E_REINIT_REQUESTED, &pf->state);
 	}
 	if (test_bit(__I40E_PF_RESET_REQUESTED, &pf->state)) {
-		reset_flags |= BIT_ULL(__I40E_PF_RESET_REQUESTED);
+		reset_flags |= BIT(__I40E_PF_RESET_REQUESTED);
 		clear_bit(__I40E_PF_RESET_REQUESTED, &pf->state);
 	}
 	if (test_bit(__I40E_CORE_RESET_REQUESTED, &pf->state)) {
-		reset_flags |= BIT_ULL(__I40E_CORE_RESET_REQUESTED);
+		reset_flags |= BIT(__I40E_CORE_RESET_REQUESTED);
 		clear_bit(__I40E_CORE_RESET_REQUESTED, &pf->state);
 	}
 	if (test_bit(__I40E_GLOBAL_RESET_REQUESTED, &pf->state)) {
-		reset_flags |= BIT_ULL(__I40E_GLOBAL_RESET_REQUESTED);
+		reset_flags |= BIT(__I40E_GLOBAL_RESET_REQUESTED);
 		clear_bit(__I40E_GLOBAL_RESET_REQUESTED, &pf->state);
 	}
 	if (test_bit(__I40E_DOWN_REQUESTED, &pf->state)) {
-		reset_flags |= BIT_ULL(__I40E_DOWN_REQUESTED);
+		reset_flags |= BIT(__I40E_DOWN_REQUESTED);
 		clear_bit(__I40E_DOWN_REQUESTED, &pf->state);
 	}
 
@@ -6147,13 +6214,9 @@ unlock:
 static void i40e_handle_link_event(struct i40e_pf *pf,
 				   struct i40e_arq_event_info *e)
 {
-	struct i40e_hw *hw = &pf->hw;
 	struct i40e_aqc_get_link_status *status =
 		(struct i40e_aqc_get_link_status *)&e->desc.params.raw;
 
-	/* save off old link status information */
-	hw->phy.link_info_old = hw->phy.link_info;
-
 	/* Do a new status request to re-enable LSE reporting
 	 * and load new status information into the hw struct
 	 * This completely ignores any state information
@@ -6192,15 +6255,19 @@ static void i40e_clean_adminq_subtask(st
 	val = rd32(&pf->hw, pf->hw.aq.arq.len);
 	oldval = val;
 	if (val & I40E_PF_ARQLEN_ARQVFE_MASK) {
-		dev_info(&pf->pdev->dev, "ARQ VF Error detected\n");
+		if (hw->debug_mask & I40E_DEBUG_AQ)
+			dev_info(&pf->pdev->dev, "ARQ VF Error detected\n");
 		val &= ~I40E_PF_ARQLEN_ARQVFE_MASK;
 	}
 	if (val & I40E_PF_ARQLEN_ARQOVFL_MASK) {
-		dev_info(&pf->pdev->dev, "ARQ Overflow Error detected\n");
+		if (hw->debug_mask & I40E_DEBUG_AQ)
+			dev_info(&pf->pdev->dev, "ARQ Overflow Error detected\n");
 		val &= ~I40E_PF_ARQLEN_ARQOVFL_MASK;
+		pf->arq_overflows++;
 	}
 	if (val & I40E_PF_ARQLEN_ARQCRIT_MASK) {
-		dev_info(&pf->pdev->dev, "ARQ Critical Error detected\n");
+		if (hw->debug_mask & I40E_DEBUG_AQ)
+			dev_info(&pf->pdev->dev, "ARQ Critical Error detected\n");
 		val &= ~I40E_PF_ARQLEN_ARQCRIT_MASK;
 	}
 	if (oldval != val)
@@ -6209,15 +6276,18 @@ static void i40e_clean_adminq_subtask(st
 	val = rd32(&pf->hw, pf->hw.aq.asq.len);
 	oldval = val;
 	if (val & I40E_PF_ATQLEN_ATQVFE_MASK) {
-		dev_info(&pf->pdev->dev, "ASQ VF Error detected\n");
+		if (pf->hw.debug_mask & I40E_DEBUG_AQ)
+			dev_info(&pf->pdev->dev, "ASQ VF Error detected\n");
 		val &= ~I40E_PF_ATQLEN_ATQVFE_MASK;
 	}
 	if (val & I40E_PF_ATQLEN_ATQOVFL_MASK) {
-		dev_info(&pf->pdev->dev, "ASQ Overflow Error detected\n");
+		if (pf->hw.debug_mask & I40E_DEBUG_AQ)
+			dev_info(&pf->pdev->dev, "ASQ Overflow Error detected\n");
 		val &= ~I40E_PF_ATQLEN_ATQOVFL_MASK;
 	}
 	if (val & I40E_PF_ATQLEN_ATQCRIT_MASK) {
-		dev_info(&pf->pdev->dev, "ASQ Critical Error detected\n");
+		if (pf->hw.debug_mask & I40E_DEBUG_AQ)
+			dev_info(&pf->pdev->dev, "ASQ Critical Error detected\n");
 		val &= ~I40E_PF_ATQLEN_ATQCRIT_MASK;
 	}
 	if (oldval != val)
@@ -6268,7 +6338,10 @@ static void i40e_clean_adminq_subtask(st
 			break;
 		case i40e_aqc_opc_nvm_erase:
 		case i40e_aqc_opc_nvm_update:
-			i40e_debug(&pf->hw, I40E_DEBUG_NVM, "ARQ NVM operation completed\n");
+		case i40e_aqc_opc_oem_post_update:
+			i40e_debug(&pf->hw, I40E_DEBUG_NVM,
+				   "ARQ NVM operation 0x%04x completed\n",
+				   opcode);
 			break;
 		default:
 			dev_info(&pf->pdev->dev,
@@ -6685,6 +6758,7 @@ static void i40e_reset_and_rebuild(struc
 	struct i40e_hw *hw = &pf->hw;
 	u8 set_fc_aq_fail = 0;
 	i40e_status ret;
+	u32 val;
 	u32 v;
 
 	/* Now we wait for GRST to settle out.
@@ -6751,12 +6825,12 @@ static void i40e_reset_and_rebuild(struc
 	if (ret)
 		goto end_core_reset;
 
-	/* driver is only interested in link up/down and module qualification
-	 * reports from firmware
+	/* The driver only wants link up/down and module qualification
+	 * reports from firmware.  Note the negative logic.
 	 */
 	ret = i40e_aq_set_phy_int_mask(&pf->hw,
-				       I40E_AQ_EVENT_LINK_UPDOWN |
-				       I40E_AQ_EVENT_MODULE_QUAL_FAIL, NULL);
+				       ~(I40E_AQ_EVENT_LINK_UPDOWN |
+					 I40E_AQ_EVENT_MODULE_QUAL_FAIL), NULL);
 	if (ret)
 		dev_info(&pf->pdev->dev, "set phy mask fail, err %s aq_err %s\n",
 			 i40e_stat_str(&pf->hw, ret),
@@ -6823,8 +6897,21 @@ static void i40e_reset_and_rebuild(struc
 		}
 	}
 
-	if (((pf->hw.aq.fw_maj_ver == 4) && (pf->hw.aq.fw_min_ver < 33)) ||
-	    (pf->hw.aq.fw_maj_ver < 4)) {
+	/* Reconfigure hardware for allowing smaller MSS in the case
+	 * of TSO, so that we avoid the MDD being fired and causing
+	 * a reset in the case of small MSS+TSO.
+	 */
+#define I40E_REG_MSS          0x000E64DC
+#define I40E_REG_MSS_MIN_MASK 0x3FF0000
+#define I40E_64BYTE_MSS       0x400000
+	val = rd32(hw, I40E_REG_MSS);
+	if ((val & I40E_REG_MSS_MIN_MASK) > I40E_64BYTE_MSS) {
+		val &= ~I40E_REG_MSS_MIN_MASK;
+		val |= I40E_64BYTE_MSS;
+		wr32(hw, I40E_REG_MSS, val);
+	}
+
+	if (pf->flags & I40E_FLAG_RESTART_AUTONEG) {
 		msleep(75);
 		ret = i40e_aq_set_link_restart_an(&pf->hw, true, NULL);
 		if (ret)
@@ -6984,49 +7071,50 @@ static void i40e_handle_mdd_event(struct
 	i40e_flush(hw);
 }
 
-#ifdef CONFIG_I40E_VXLAN
 /**
- * i40e_sync_vxlan_filters_subtask - Sync the VSI filter list with HW
+ * i40e_sync_udp_filters_subtask - Sync the VSI filter list with HW
  * @pf: board private structure
  **/
-static void i40e_sync_vxlan_filters_subtask(struct i40e_pf *pf)
+static void i40e_sync_udp_filters_subtask(struct i40e_pf *pf)
 {
+#if IS_ENABLED(CONFIG_VXLAN) || IS_ENABLED(CONFIG_GENEVE)
 	struct i40e_hw *hw = &pf->hw;
 	i40e_status ret;
 	__be16 port;
 	int i;
 
-	if (!(pf->flags & I40E_FLAG_VXLAN_FILTER_SYNC))
+	if (!(pf->flags & I40E_FLAG_UDP_FILTER_SYNC))
 		return;
 
-	pf->flags &= ~I40E_FLAG_VXLAN_FILTER_SYNC;
+	pf->flags &= ~I40E_FLAG_UDP_FILTER_SYNC;
 
 	for (i = 0; i < I40E_MAX_PF_UDP_OFFLOAD_PORTS; i++) {
-		if (pf->pending_vxlan_bitmap & BIT_ULL(i)) {
-			pf->pending_vxlan_bitmap &= ~BIT_ULL(i);
-			port = pf->vxlan_ports[i];
+		if (pf->pending_udp_bitmap & BIT_ULL(i)) {
+			pf->pending_udp_bitmap &= ~BIT_ULL(i);
+			port = pf->udp_ports[i].index;
 			if (port)
 				ret = i40e_aq_add_udp_tunnel(hw, ntohs(port),
-						     I40E_AQC_TUNNEL_TYPE_VXLAN,
+						     pf->udp_ports[i].type,
 						     NULL, NULL);
 			else
 				ret = i40e_aq_del_udp_tunnel(hw, i, NULL);
 
 			if (ret) {
-				dev_info(&pf->pdev->dev,
-					 "%s vxlan port %d, index %d failed, err %s aq_err %s\n",
-					 port ? "add" : "delete",
-					 ntohs(port), i,
-					 i40e_stat_str(&pf->hw, ret),
-					 i40e_aq_str(&pf->hw,
+				dev_dbg(&pf->pdev->dev,
+					"%s %s port %d, index %d failed, err %s aq_err %s\n",
+					pf->udp_ports[i].type ? "vxlan" : "geneve",
+					port ? "add" : "delete",
+					ntohs(port), i,
+					i40e_stat_str(&pf->hw, ret),
+					i40e_aq_str(&pf->hw,
 						    pf->hw.aq.asq_last_status));
-				pf->vxlan_ports[i] = 0;
+				pf->udp_ports[i].index = 0;
 			}
 		}
 	}
+#endif
 }
 
-#endif
 /**
  * i40e_service_task - Run the driver's async subtasks
  * @work: pointer to work_struct containing our data
@@ -7045,15 +7133,14 @@ static void i40e_service_task(struct wor
 	}
 
 	i40e_detect_recover_hung(pf);
+	i40e_sync_filters_subtask(pf);
 	i40e_reset_subtask(pf);
 	i40e_handle_mdd_event(pf);
 	i40e_vc_process_vflr_event(pf);
 	i40e_watchdog_subtask(pf);
 	i40e_fdir_reinit_subtask(pf);
 	i40e_sync_filters_subtask(pf);
-#ifdef CONFIG_I40E_VXLAN
-	i40e_sync_vxlan_filters_subtask(pf);
-#endif
+	i40e_sync_udp_filters_subtask(pf);
 	i40e_clean_adminq_subtask(pf);
 
 	i40e_service_event_complete(pf);
@@ -7106,7 +7193,7 @@ static int i40e_set_num_rings_in_vsi(str
 		vsi->alloc_queue_pairs = 1;
 		vsi->num_desc = ALIGN(I40E_FDIR_RING_COUNT,
 				      I40E_REQ_DESCRIPTOR_MULTIPLE);
-		vsi->num_q_vectors = 1;
+		vsi->num_q_vectors = pf->num_fdsb_msix;
 		break;
 
 	case I40E_VSI_VMDQ2:
@@ -7282,6 +7369,23 @@ static void i40e_vsi_free_arrays(struct
 }
 
 /**
+ * i40e_clear_rss_config_user - clear the user configured RSS hash keys
+ * and lookup table
+ * @vsi: Pointer to VSI structure
+ */
+static void i40e_clear_rss_config_user(struct i40e_vsi *vsi)
+{
+	if (!vsi)
+		return;
+
+	kfree(vsi->rss_hkey_user);
+	vsi->rss_hkey_user = NULL;
+
+	kfree(vsi->rss_lut_user);
+	vsi->rss_lut_user = NULL;
+}
+
+/**
  * i40e_vsi_clear - Deallocate the VSI provided
  * @vsi: the VSI being un-configured
  **/
@@ -7318,6 +7422,7 @@ static int i40e_vsi_clear(struct i40e_vs
 	i40e_put_lump(pf->irq_pile, vsi->base_vector, vsi->idx);
 
 	i40e_vsi_free_arrays(vsi, true);
+	i40e_clear_rss_config_user(vsi);
 
 	pf->vsi[vsi->idx] = NULL;
 	if (vsi->idx < pf->next_vsi)
@@ -7376,8 +7481,6 @@ static int i40e_alloc_rings(struct i40e_
 		tx_ring->dcb_tc = 0;
 		if (vsi->back->flags & I40E_FLAG_WB_ON_ITR_CAPABLE)
 			tx_ring->flags = I40E_TXR_FLAGS_WB_ON_ITR;
-		if (vsi->back->flags & I40E_FLAG_OUTER_UDP_CSUM_CAPABLE)
-			tx_ring->flags |= I40E_TXR_FLAGS_OUTER_UDP_CSUM;
 		vsi->tx_rings[i] = tx_ring;
 
 		rx_ring = &tx_ring[1];
@@ -7476,9 +7579,11 @@ static int i40e_init_msix(struct i40e_pf
 	/* reserve one vector for sideband flow director */
 	if (pf->flags & I40E_FLAG_FD_SB_ENABLED) {
 		if (vectors_left) {
+			pf->num_fdsb_msix = 1;
 			v_budget++;
 			vectors_left--;
 		} else {
+			pf->num_fdsb_msix = 0;
 			pf->flags &= ~I40E_FLAG_FD_SB_ENABLED;
 		}
 	}
@@ -7770,7 +7875,7 @@ static int i40e_setup_misc_vector(struct
 
 	i40e_flush(hw);
 
-	i40e_irq_dynamic_enable_icr0(pf);
+	i40e_irq_dynamic_enable_icr0(pf, true);
 
 	return err;
 }
@@ -7780,7 +7885,8 @@ static int i40e_setup_misc_vector(struct
  * @vsi: vsi structure
  * @seed: RSS hash seed
  **/
-static int i40e_config_rss_aq(struct i40e_vsi *vsi, const u8 *seed)
+static int i40e_config_rss_aq(struct i40e_vsi *vsi, const u8 *seed,
+			      u8 *lut, u16 lut_size)
 {
 	struct i40e_aqc_get_set_rss_key_data rss_key;
 	struct i40e_pf *pf = vsi->back;
@@ -7833,43 +7939,103 @@ static int i40e_vsi_config_rss(struct i4
 {
 	u8 seed[I40E_HKEY_ARRAY_SIZE];
 	struct i40e_pf *pf = vsi->back;
+	u8 *lut;
+	int ret;
+
+	if (!(pf->flags & I40E_FLAG_RSS_AQ_CAPABLE))
+		return 0;
 
+	lut = kzalloc(vsi->rss_table_size, GFP_KERNEL);
+	if (!lut)
+		return -ENOMEM;
+
+	i40e_fill_rss_lut(pf, lut, vsi->rss_table_size, vsi->rss_size);
 	netdev_rss_key_fill((void *)seed, I40E_HKEY_ARRAY_SIZE);
-	vsi->rss_size = min_t(int, pf->rss_size, vsi->num_queue_pairs);
+	vsi->rss_size = min_t(int, pf->alloc_rss_size, vsi->num_queue_pairs);
+	ret = i40e_config_rss_aq(vsi, seed, lut, vsi->rss_table_size);
+	kfree(lut);
 
-	if (pf->flags & I40E_FLAG_RSS_AQ_CAPABLE)
-		return i40e_config_rss_aq(vsi, seed);
+	return ret;
+}
 
-	return 0;
+/**
+ * i40e_get_rss_aq - Get RSS keys and lut by using AQ commands
+ * @vsi: Pointer to vsi structure
+ * @seed: Buffter to store the hash keys
+ * @lut: Buffer to store the lookup table entries
+ * @lut_size: Size of buffer to store the lookup table entries
+ *
+ * Return 0 on success, negative on failure
+ */
+static int i40e_get_rss_aq(struct i40e_vsi *vsi, const u8 *seed,
+			   u8 *lut, u16 lut_size)
+{
+	struct i40e_pf *pf = vsi->back;
+	struct i40e_hw *hw = &pf->hw;
+	int ret = 0;
+
+	if (seed) {
+		ret = i40e_aq_get_rss_key(hw, vsi->id,
+			(struct i40e_aqc_get_set_rss_key_data *)seed);
+		if (ret) {
+			dev_info(&pf->pdev->dev,
+				 "Cannot get RSS key, err %s aq_err %s\n",
+				 i40e_stat_str(&pf->hw, ret),
+				 i40e_aq_str(&pf->hw,
+					     pf->hw.aq.asq_last_status));
+			return ret;
+		}
+	}
+
+	if (lut) {
+		bool pf_lut = vsi->type == I40E_VSI_MAIN ? true : false;
+
+		ret = i40e_aq_get_rss_lut(hw, vsi->id, pf_lut, lut, lut_size);
+		if (ret) {
+			dev_info(&pf->pdev->dev,
+				 "Cannot get RSS lut, err %s aq_err %s\n",
+				 i40e_stat_str(&pf->hw, ret),
+				 i40e_aq_str(&pf->hw,
+					     pf->hw.aq.asq_last_status));
+			return ret;
+		}
+	}
+
+	return ret;
 }
 
 /**
- * i40e_config_rss_reg - Prepare for RSS if used
- * @pf: board private structure
+ * i40e_config_rss_reg - Configure RSS keys and lut by writing registers
+ * @vsi: Pointer to vsi structure
  * @seed: RSS hash seed
+ * @lut: Lookup table
+ * @lut_size: Lookup table size
+ *
+ * Returns 0 on success, negative on failure
  **/
-static int i40e_config_rss_reg(struct i40e_pf *pf, const u8 *seed)
+static int i40e_config_rss_reg(struct i40e_vsi *vsi, const u8 *seed,
+			       const u8 *lut, u16 lut_size)
 {
-	struct i40e_vsi *vsi = pf->vsi[pf->lan_vsi];
+	struct i40e_pf *pf = vsi->back;
 	struct i40e_hw *hw = &pf->hw;
-	u32 *seed_dw = (u32 *)seed;
-	u32 current_queue = 0;
-	u32 lut = 0;
-	int i, j;
+	u8 i;
 
 	/* Fill out hash function seed */
-	for (i = 0; i <= I40E_PFQF_HKEY_MAX_INDEX; i++)
-		wr32(hw, I40E_PFQF_HKEY(i), seed_dw[i]);
+	if (seed) {
+		u32 *seed_dw = (u32 *)seed;
 
-	for (i = 0; i <= I40E_PFQF_HLUT_MAX_INDEX; i++) {
-		lut = 0;
-		for (j = 0; j < 4; j++) {
-			if (current_queue == vsi->rss_size)
-				current_queue = 0;
-			lut |= ((current_queue) << (8 * j));
-			current_queue++;
-		}
-		wr32(&pf->hw, I40E_PFQF_HLUT(i), lut);
+		for (i = 0; i <= I40E_PFQF_HKEY_MAX_INDEX; i++)
+			i40e_write_rx_ctl(hw, I40E_PFQF_HKEY(i), seed_dw[i]);
+	}
+
+	if (lut) {
+		u32 *lut_dw = (u32 *)lut;
+
+		if (lut_size != I40E_HLUT_ARRAY_SIZE)
+			return -EINVAL;
+
+		for (i = 0; i <= I40E_PFQF_HLUT_MAX_INDEX; i++)
+			wr32(hw, I40E_PFQF_HLUT(i), lut_dw[i]);
 	}
 	i40e_flush(hw);
 
@@ -7877,40 +8043,148 @@ static int i40e_config_rss_reg(struct i4
 }
 
 /**
- * i40e_config_rss - Prepare for RSS if used
+ * i40e_get_rss_reg - Get the RSS keys and lut by reading registers
+ * @vsi: Pointer to VSI structure
+ * @seed: Buffer to store the keys
+ * @lut: Buffer to store the lookup table entries
+ * @lut_size: Size of buffer to store the lookup table entries
+ *
+ * Returns 0 on success, negative on failure
+ */
+static int i40e_get_rss_reg(struct i40e_vsi *vsi, u8 *seed,
+			    u8 *lut, u16 lut_size)
+{
+	struct i40e_pf *pf = vsi->back;
+	struct i40e_hw *hw = &pf->hw;
+	u16 i;
+
+	if (seed) {
+		u32 *seed_dw = (u32 *)seed;
+
+		for (i = 0; i <= I40E_PFQF_HKEY_MAX_INDEX; i++)
+			seed_dw[i] = i40e_read_rx_ctl(hw, I40E_PFQF_HKEY(i));
+	}
+	if (lut) {
+		u32 *lut_dw = (u32 *)lut;
+
+		if (lut_size != I40E_HLUT_ARRAY_SIZE)
+			return -EINVAL;
+		for (i = 0; i <= I40E_PFQF_HLUT_MAX_INDEX; i++)
+			lut_dw[i] = rd32(hw, I40E_PFQF_HLUT(i));
+	}
+
+	return 0;
+}
+
+/**
+ * i40e_config_rss - Configure RSS keys and lut
+ * @vsi: Pointer to VSI structure
+ * @seed: RSS hash seed
+ * @lut: Lookup table
+ * @lut_size: Lookup table size
+ *
+ * Returns 0 on success, negative on failure
+ */
+int i40e_config_rss(struct i40e_vsi *vsi, u8 *seed, u8 *lut, u16 lut_size)
+{
+	struct i40e_pf *pf = vsi->back;
+
+	if (pf->flags & I40E_FLAG_RSS_AQ_CAPABLE)
+		return i40e_config_rss_aq(vsi, seed, lut, lut_size);
+	else
+		return i40e_config_rss_reg(vsi, seed, lut, lut_size);
+}
+
+/**
+ * i40e_get_rss - Get RSS keys and lut
+ * @vsi: Pointer to VSI structure
+ * @seed: Buffer to store the keys
+ * @lut: Buffer to store the lookup table entries
+ * lut_size: Size of buffer to store the lookup table entries
+ *
+ * Returns 0 on success, negative on failure
+ */
+int i40e_get_rss(struct i40e_vsi *vsi, u8 *seed, u8 *lut, u16 lut_size)
+{
+	struct i40e_pf *pf = vsi->back;
+
+	if (pf->flags & I40E_FLAG_RSS_AQ_CAPABLE)
+		return i40e_get_rss_aq(vsi, seed, lut, lut_size);
+	else
+		return i40e_get_rss_reg(vsi, seed, lut, lut_size);
+}
+
+/**
+ * i40e_fill_rss_lut - Fill the RSS lookup table with default values
+ * @pf: Pointer to board private structure
+ * @lut: Lookup table
+ * @rss_table_size: Lookup table size
+ * @rss_size: Range of queue number for hashing
+ */
+static void i40e_fill_rss_lut(struct i40e_pf *pf, u8 *lut,
+			      u16 rss_table_size, u16 rss_size)
+{
+	u16 i;
+
+	for (i = 0; i < rss_table_size; i++)
+		lut[i] = i % rss_size;
+}
+
+/**
+ * i40e_pf_config_rss - Prepare for RSS if used
  * @pf: board private structure
  **/
-static int i40e_config_rss(struct i40e_pf *pf)
+static int i40e_pf_config_rss(struct i40e_pf *pf)
 {
 	struct i40e_vsi *vsi = pf->vsi[pf->lan_vsi];
 	u8 seed[I40E_HKEY_ARRAY_SIZE];
+	u8 *lut;
 	struct i40e_hw *hw = &pf->hw;
 	u32 reg_val;
 	u64 hena;
-
-	netdev_rss_key_fill((void *)seed, I40E_HKEY_ARRAY_SIZE);
+	int ret;
 
 	/* By default we enable TCP/UDP with IPv4/IPv6 ptypes */
-	hena = (u64)rd32(hw, I40E_PFQF_HENA(0)) |
-		((u64)rd32(hw, I40E_PFQF_HENA(1)) << 32);
+	hena = (u64)i40e_read_rx_ctl(hw, I40E_PFQF_HENA(0)) |
+		((u64)i40e_read_rx_ctl(hw, I40E_PFQF_HENA(1)) << 32);
 	hena |= i40e_pf_get_default_rss_hena(pf);
 
-	wr32(hw, I40E_PFQF_HENA(0), (u32)hena);
-	wr32(hw, I40E_PFQF_HENA(1), (u32)(hena >> 32));
-
-	vsi->rss_size = min_t(int, pf->rss_size, vsi->num_queue_pairs);
+	i40e_write_rx_ctl(hw, I40E_PFQF_HENA(0), (u32)hena);
+	i40e_write_rx_ctl(hw, I40E_PFQF_HENA(1), (u32)(hena >> 32));
 
 	/* Determine the RSS table size based on the hardware capabilities */
-	reg_val = rd32(hw, I40E_PFQF_CTL_0);
+	reg_val = i40e_read_rx_ctl(hw, I40E_PFQF_CTL_0);
 	reg_val = (pf->rss_table_size == 512) ?
 			(reg_val | I40E_PFQF_CTL_0_HASHLUTSIZE_512) :
 			(reg_val & ~I40E_PFQF_CTL_0_HASHLUTSIZE_512);
-	wr32(hw, I40E_PFQF_CTL_0, reg_val);
+	i40e_write_rx_ctl(hw, I40E_PFQF_CTL_0, reg_val);
 
-	if (pf->flags & I40E_FLAG_RSS_AQ_CAPABLE)
-		return i40e_config_rss_aq(pf->vsi[pf->lan_vsi], seed);
+	/* Determine the RSS size of the VSI */
+	if (!vsi->rss_size)
+		vsi->rss_size = min_t(int, pf->alloc_rss_size,
+				      vsi->num_queue_pairs);
+
+	lut = kzalloc(vsi->rss_table_size, GFP_KERNEL);
+	if (!lut)
+		return -ENOMEM;
+
+	/* Use user configured lut if there is one, otherwise use default */
+	if (vsi->rss_lut_user)
+		memcpy(lut, vsi->rss_lut_user, vsi->rss_table_size);
 	else
-		return i40e_config_rss_reg(pf, seed);
+		i40e_fill_rss_lut(pf, lut, vsi->rss_table_size, vsi->rss_size);
+
+	/* Use user configured hash key if there is one, otherwise
+	 * use default.
+	 */
+	if (vsi->rss_hkey_user)
+		memcpy(seed, vsi->rss_hkey_user, I40E_HKEY_ARRAY_SIZE);
+	else
+		netdev_rss_key_fill((void *)seed, I40E_HKEY_ARRAY_SIZE);
+	ret = i40e_config_rss(vsi, seed, lut, vsi->rss_table_size);
+	kfree(lut);
+
+	return ret;
 }
 
 /**
@@ -7935,13 +8209,28 @@ int i40e_reconfig_rss_queues(struct i40e
 		vsi->req_queue_pairs = queue_count;
 		i40e_prep_for_reset(pf);
 
-		pf->rss_size = new_rss_size;
+		pf->alloc_rss_size = new_rss_size;
 
 		i40e_reset_and_rebuild(pf, true);
-		i40e_config_rss(pf);
+
+		/* Discard the user configured hash keys and lut, if less
+		 * queues are enabled.
+		 */
+		if (queue_count < vsi->rss_size) {
+			i40e_clear_rss_config_user(vsi);
+			dev_dbg(&pf->pdev->dev,
+				"discard user configured hash keys and lut\n");
+		}
+
+		/* Reset vsi->rss_size, as number of enabled queues changed */
+		vsi->rss_size = min_t(int, pf->alloc_rss_size,
+				      vsi->num_queue_pairs);
+
+		i40e_pf_config_rss(pf);
 	}
-	dev_info(&pf->pdev->dev, "RSS count:  %d\n", pf->rss_size);
-	return pf->rss_size;
+	dev_info(&pf->pdev->dev, "RSS count/HW max RSS count:  %d/%d\n",
+		 pf->alloc_rss_size, pf->rss_size_max);
+	return pf->alloc_rss_size;
 }
 
 /**
@@ -8112,13 +8401,14 @@ static int i40e_sw_init(struct i40e_pf *
 	 * maximum might end up larger than the available queues
 	 */
 	pf->rss_size_max = BIT(pf->hw.func_caps.rss_table_entry_width);
-	pf->rss_size = 1;
+	pf->alloc_rss_size = 1;
 	pf->rss_table_size = pf->hw.func_caps.rss_table_size;
 	pf->rss_size_max = min_t(int, pf->rss_size_max,
 				 pf->hw.func_caps.num_tx_qp);
 	if (pf->hw.func_caps.rss) {
 		pf->flags |= I40E_FLAG_RSS_ENABLED;
-		pf->rss_size = min_t(int, pf->rss_size_max, num_online_cpus());
+		pf->alloc_rss_size = min_t(int, pf->rss_size_max,
+					   num_online_cpus());
 	}
 
 	/* MFP mode enabled */
@@ -8151,6 +8441,26 @@ static int i40e_sw_init(struct i40e_pf *
 				 pf->hw.func_caps.fd_filters_best_effort;
 	}
 
+	if (i40e_is_mac_710(&pf->hw) &&
+	    (((pf->hw.aq.fw_maj_ver == 4) && (pf->hw.aq.fw_min_ver < 33)) ||
+	    (pf->hw.aq.fw_maj_ver < 4))) {
+		pf->flags |= I40E_FLAG_RESTART_AUTONEG;
+		/* No DCB support  for FW < v4.33 */
+		pf->flags |= I40E_FLAG_NO_DCB_SUPPORT;
+	}
+
+	/* Disable FW LLDP if FW < v4.3 */
+	if (i40e_is_mac_710(&pf->hw) &&
+	    (((pf->hw.aq.fw_maj_ver == 4) && (pf->hw.aq.fw_min_ver < 3)) ||
+	    (pf->hw.aq.fw_maj_ver < 4)))
+		pf->flags |= I40E_FLAG_STOP_FW_LLDP;
+
+	/* Use the FW Set LLDP MIB API if FW > v4.40 */
+	if (i40e_is_mac_710(&pf->hw) &&
+	    (((pf->hw.aq.fw_maj_ver == 4) && (pf->hw.aq.fw_min_ver >= 40)) ||
+	    (pf->hw.aq.fw_maj_ver >= 5)))
+		pf->flags |= I40E_FLAG_USE_SET_LLDP_MIB;
+
 	if (pf->hw.func_caps.vmdq) {
 		pf->num_vmdq_vsis = I40E_DEFAULT_NUM_VMDQ_VSI;
 		pf->flags |= I40E_FLAG_VMDQ_ENABLED;
@@ -8176,8 +8486,20 @@ static int i40e_sw_init(struct i40e_pf *
 			     I40E_FLAG_HW_ATR_EVICT_CAPABLE |
 			     I40E_FLAG_OUTER_UDP_CSUM_CAPABLE |
 			     I40E_FLAG_WB_ON_ITR_CAPABLE |
-			     I40E_FLAG_MULTIPLE_TCP_UDP_RSS_PCTYPE;
+			     I40E_FLAG_MULTIPLE_TCP_UDP_RSS_PCTYPE |
+			     I40E_FLAG_100M_SGMII_CAPABLE |
+			     I40E_FLAG_USE_SET_LLDP_MIB |
+			     I40E_FLAG_GENEVE_OFFLOAD_CAPABLE;
+	} else if ((pf->hw.aq.api_maj_ver > 1) ||
+		   ((pf->hw.aq.api_maj_ver == 1) &&
+		    (pf->hw.aq.api_min_ver > 4))) {
+		/* Supported in FW API version higher than 1.4 */
+		pf->flags |= I40E_FLAG_GENEVE_OFFLOAD_CAPABLE;
+		pf->auto_disable_flags = I40E_FLAG_HW_ATR_EVICT_CAPABLE;
+	} else {
+		pf->auto_disable_flags = I40E_FLAG_HW_ATR_EVICT_CAPABLE;
 	}
+
 	pf->eeprom_version = 0xDEAD;
 	pf->lan_veb = I40E_NO_VEB;
 	pf->lan_vsi = I40E_NO_VSI;
@@ -8226,7 +8548,9 @@ bool i40e_set_ntuple(struct i40e_pf *pf,
 		/* Enable filters and mark for reset */
 		if (!(pf->flags & I40E_FLAG_FD_SB_ENABLED))
 			need_reset = true;
-		pf->flags |= I40E_FLAG_FD_SB_ENABLED;
+		/* enable FD_SB only if there is MSI-X vector */
+		if (pf->num_fdsb_msix > 0)
+			pf->flags |= I40E_FLAG_FD_SB_ENABLED;
 	} else {
 		/* turn off filters, mark for reset and clear SW filter list */
 		if (pf->flags & I40E_FLAG_FD_SB_ENABLED) {
@@ -8275,26 +8599,29 @@ static int i40e_set_features(struct net_
 	return 0;
 }
 
-#ifdef CONFIG_I40E_VXLAN
+#if IS_ENABLED(CONFIG_VXLAN) || IS_ENABLED(CONFIG_GENEVE)
 /**
- * i40e_get_vxlan_port_idx - Lookup a possibly offloaded for Rx UDP port
+ * i40e_get_udp_port_idx - Lookup a possibly offloaded for Rx UDP port
  * @pf: board private structure
  * @port: The UDP port to look up
  *
  * Returns the index number or I40E_MAX_PF_UDP_OFFLOAD_PORTS if port not found
  **/
-static u8 i40e_get_vxlan_port_idx(struct i40e_pf *pf, __be16 port)
+static u8 i40e_get_udp_port_idx(struct i40e_pf *pf, __be16 port)
 {
 	u8 i;
 
 	for (i = 0; i < I40E_MAX_PF_UDP_OFFLOAD_PORTS; i++) {
-		if (pf->vxlan_ports[i] == port)
+		if (pf->udp_ports[i].index == port)
 			return i;
 	}
 
 	return i;
 }
 
+#endif
+
+#if IS_ENABLED(CONFIG_VXLAN)
 /**
  * i40e_add_vxlan_port - Get notifications about VXLAN ports that come up
  * @netdev: This physical port's netdev
@@ -8310,10 +8637,7 @@ static void i40e_add_vxlan_port(struct n
 	u8 next_idx;
 	u8 idx;
 
-	if (sa_family == AF_INET6)
-		return;
-
-	idx = i40e_get_vxlan_port_idx(pf, port);
+	idx = i40e_get_udp_port_idx(pf, port);
 
 	/* Check if port already exists */
 	if (idx < I40E_MAX_PF_UDP_OFFLOAD_PORTS) {
@@ -8323,7 +8647,7 @@ static void i40e_add_vxlan_port(struct n
 	}
 
 	/* Now check if there is space to add the new port */
-	next_idx = i40e_get_vxlan_port_idx(pf, 0);
+	next_idx = i40e_get_udp_port_idx(pf, 0);
 
 	if (next_idx == I40E_MAX_PF_UDP_OFFLOAD_PORTS) {
 		netdev_info(netdev, "maximum number of vxlan UDP ports reached, not adding port %d\n",
@@ -8332,9 +8656,10 @@ static void i40e_add_vxlan_port(struct n
 	}
 
 	/* New port: add it and mark its index in the bitmap */
-	pf->vxlan_ports[next_idx] = port;
-	pf->pending_vxlan_bitmap |= BIT_ULL(next_idx);
-	pf->flags |= I40E_FLAG_VXLAN_FILTER_SYNC;
+	pf->udp_ports[next_idx].index = port;
+	pf->udp_ports[next_idx].type = I40E_AQC_TUNNEL_TYPE_VXLAN;
+	pf->pending_udp_bitmap |= BIT_ULL(next_idx);
+	pf->flags |= I40E_FLAG_UDP_FILTER_SYNC;
 }
 
 /**
@@ -8351,26 +8676,106 @@ static void i40e_del_vxlan_port(struct n
 	struct i40e_pf *pf = vsi->back;
 	u8 idx;
 
-	if (sa_family == AF_INET6)
-		return;
-
-	idx = i40e_get_vxlan_port_idx(pf, port);
+	idx = i40e_get_udp_port_idx(pf, port);
 
 	/* Check if port already exists */
 	if (idx < I40E_MAX_PF_UDP_OFFLOAD_PORTS) {
 		/* if port exists, set it to 0 (mark for deletion)
 		 * and make it pending
 		 */
-		pf->vxlan_ports[idx] = 0;
-		pf->pending_vxlan_bitmap |= BIT_ULL(idx);
-		pf->flags |= I40E_FLAG_VXLAN_FILTER_SYNC;
+		pf->udp_ports[idx].index = 0;
+		pf->pending_udp_bitmap |= BIT_ULL(idx);
+		pf->flags |= I40E_FLAG_UDP_FILTER_SYNC;
 	} else {
 		netdev_warn(netdev, "vxlan port %d was not found, not deleting\n",
 			    ntohs(port));
 	}
 }
+#endif
+
+#if IS_ENABLED(CONFIG_GENEVE)
+/**
+ * i40e_add_geneve_port - Get notifications about GENEVE ports that come up
+ * @netdev: This physical port's netdev
+ * @sa_family: Socket Family that GENEVE is notifying us about
+ * @port: New UDP port number that GENEVE started listening to
+ **/
+static void i40e_add_geneve_port(struct net_device *netdev,
+				 sa_family_t sa_family, __be16 port)
+{
+	struct i40e_netdev_priv *np = netdev_priv(netdev);
+	struct i40e_vsi *vsi = np->vsi;
+	struct i40e_pf *pf = vsi->back;
+	u8 next_idx;
+	u8 idx;
+
+	if (!(pf->flags & I40E_FLAG_GENEVE_OFFLOAD_CAPABLE))
+		return;
+
+	idx = i40e_get_udp_port_idx(pf, port);
 
+	/* Check if port already exists */
+	if (idx < I40E_MAX_PF_UDP_OFFLOAD_PORTS) {
+		netdev_info(netdev, "udp port %d already offloaded\n",
+			    ntohs(port));
+		return;
+	}
+
+	/* Now check if there is space to add the new port */
+	next_idx = i40e_get_udp_port_idx(pf, 0);
+
+	if (next_idx == I40E_MAX_PF_UDP_OFFLOAD_PORTS) {
+		netdev_info(netdev, "maximum number of UDP ports reached, not adding port %d\n",
+			    ntohs(port));
+		return;
+	}
+
+	/* New port: add it and mark its index in the bitmap */
+	pf->udp_ports[next_idx].index = port;
+	pf->udp_ports[next_idx].type = I40E_AQC_TUNNEL_TYPE_NGE;
+	pf->pending_udp_bitmap |= BIT_ULL(next_idx);
+	pf->flags |= I40E_FLAG_UDP_FILTER_SYNC;
+
+	dev_info(&pf->pdev->dev, "adding geneve port %d\n", ntohs(port));
+}
+
+/**
+ * i40e_del_geneve_port - Get notifications about GENEVE ports that go away
+ * @netdev: This physical port's netdev
+ * @sa_family: Socket Family that GENEVE is notifying us about
+ * @port: UDP port number that GENEVE stopped listening to
+ **/
+static void i40e_del_geneve_port(struct net_device *netdev,
+				 sa_family_t sa_family, __be16 port)
+{
+	struct i40e_netdev_priv *np = netdev_priv(netdev);
+	struct i40e_vsi *vsi = np->vsi;
+	struct i40e_pf *pf = vsi->back;
+	u8 idx;
+
+	if (!(pf->flags & I40E_FLAG_GENEVE_OFFLOAD_CAPABLE))
+		return;
+
+	idx = i40e_get_udp_port_idx(pf, port);
+
+	/* Check if port already exists */
+	if (idx < I40E_MAX_PF_UDP_OFFLOAD_PORTS) {
+		/* if port exists, set it to 0 (mark for deletion)
+		 * and make it pending
+		 */
+		pf->udp_ports[idx].index = 0;
+		pf->pending_udp_bitmap |= BIT_ULL(idx);
+		pf->flags |= I40E_FLAG_UDP_FILTER_SYNC;
+
+		dev_info(&pf->pdev->dev, "deleting geneve port %d\n",
+			 ntohs(port));
+	} else {
+		netdev_warn(netdev, "geneve port %d was not found, not deleting\n",
+			    ntohs(port));
+	}
+}
 #endif
+
 static int i40e_get_phys_port_id(struct net_device *netdev,
 				 struct netdev_phys_item_id *ppid)
 {
@@ -8548,7 +8953,10 @@ static int i40e_ndo_bridge_getlink(struc
 				       nlflags, 0, 0, filter_mask, NULL);
 }
 
-#define I40E_MAX_TUNNEL_HDR_LEN 80
+/* Hardware supports L4 tunnel length of 128B (=2^7) which includes
+ * inner mac plus all inner ethertypes.
+ */
+#define I40E_MAX_TUNNEL_HDR_LEN 128
 /**
  * i40e_features_check - Validate encapsulated packet conforms to limits
  * @skb: skb buff
@@ -8560,7 +8968,7 @@ static netdev_features_t i40e_features_c
 					     netdev_features_t features)
 {
 	if (skb->encapsulation &&
-	    (skb_inner_mac_header(skb) - skb_transport_header(skb) >
+	    ((skb_inner_network_header(skb) - skb_transport_header(skb)) >
 	     I40E_MAX_TUNNEL_HDR_LEN))
 		return features & ~(NETIF_F_ALL_CSUM | NETIF_F_GSO_MASK);
 
@@ -8583,7 +8991,7 @@ static const struct net_device_ops i40e_
 #ifdef CONFIG_NET_POLL_CONTROLLER
 	.ndo_poll_controller	= i40e_netpoll,
 #endif
-	.ndo_setup_tc		= i40e_setup_tc,
+	.ndo_setup_tc		= __i40e_setup_tc,
 #ifdef I40E_FCOE
 	.ndo_fcoe_enable	= i40e_fcoe_enable,
 	.ndo_fcoe_disable	= i40e_fcoe_disable,
@@ -8595,10 +9003,14 @@ static const struct net_device_ops i40e_
 	.ndo_get_vf_config	= i40e_ndo_get_vf_config,
 	.ndo_set_vf_link_state	= i40e_ndo_set_vf_link_state,
 	.ndo_set_vf_spoofchk	= i40e_ndo_set_vf_spoofchk,
-#ifdef CONFIG_I40E_VXLAN
+#if IS_ENABLED(CONFIG_VXLAN)
 	.ndo_add_vxlan_port	= i40e_add_vxlan_port,
 	.ndo_del_vxlan_port	= i40e_del_vxlan_port,
 #endif
+#if IS_ENABLED(CONFIG_GENEVE)
+	.ndo_add_geneve_port	= i40e_add_geneve_port,
+	.ndo_del_geneve_port	= i40e_del_geneve_port,
+#endif
 	.ndo_get_phys_port_id	= i40e_get_phys_port_id,
 	.ndo_fdb_add		= i40e_ndo_fdb_add,
 	.ndo_features_check	= i40e_features_check,
@@ -8631,14 +9043,19 @@ static int i40e_config_netdev(struct i40
 	np = netdev_priv(netdev);
 	np->vsi = vsi;
 
-	netdev->hw_enc_features |= NETIF_F_IP_CSUM	 |
-				  NETIF_F_GSO_UDP_TUNNEL |
-				  NETIF_F_GSO_GRE	 |
-				  NETIF_F_TSO;
+	netdev->hw_enc_features |= NETIF_F_IP_CSUM	       |
+				   NETIF_F_IPV6_CSUM	       |
+				   NETIF_F_TSO		       |
+				   NETIF_F_TSO6		       |
+				   NETIF_F_TSO_ECN	       |
+				   NETIF_F_GSO_GRE	       |
+				   NETIF_F_GSO_UDP_TUNNEL      |
+				   NETIF_F_GSO_UDP_TUNNEL_CSUM |
+				   0;
 
 	netdev->features = NETIF_F_SG		       |
 			   NETIF_F_IP_CSUM	       |
-			   NETIF_F_SCTP_CSUM	       |
+			   NETIF_F_SCTP_CRC	       |
 			   NETIF_F_HIGHDMA	       |
 			   NETIF_F_GSO_UDP_TUNNEL      |
 			   NETIF_F_GSO_GRE	       |
@@ -8655,6 +9072,8 @@ static int i40e_config_netdev(struct i40
 
 	if (!(pf->flags & I40E_FLAG_MFP_ENABLED))
 		netdev->features |= NETIF_F_NTUPLE;
+	if (pf->flags & I40E_FLAG_OUTER_UDP_CSUM_CAPABLE)
+		netdev->features |= NETIF_F_GSO_UDP_TUNNEL_CSUM;
 
 	/* copy netdev features into list of user selectable features */
 	netdev->hw_features |= netdev->features;
@@ -9051,7 +9470,7 @@ int i40e_vsi_release(struct i40e_vsi *vs
 				f->is_vf, f->is_netdev);
 	spin_unlock_bh(&vsi->mac_filter_list_lock);
 
-	i40e_sync_vsi_filters(vsi, false);
+	i40e_sync_vsi_filters(vsi);
 
 	i40e_vsi_delete(vsi);
 	i40e_vsi_free_q_vectors(vsi);
@@ -9159,10 +9578,15 @@ vector_setup_out:
  **/
 static struct i40e_vsi *i40e_vsi_reinit_setup(struct i40e_vsi *vsi)
 {
-	struct i40e_pf *pf = vsi->back;
+	struct i40e_pf *pf;
 	u8 enabled_tc;
 	int ret;
 
+	if (!vsi)
+		return NULL;
+
+	pf = vsi->back;
+
 	i40e_put_lump(pf->qp_pile, vsi->base_queue, vsi->idx);
 	i40e_vsi_clear_rings(vsi);
 
@@ -9213,6 +9637,44 @@ err_vsi:
 }
 
 /**
+ * i40e_macaddr_init - explicitly write the mac address filters.
+ *
+ * @vsi: pointer to the vsi.
+ * @macaddr: the MAC address
+ *
+ * This is needed when the macaddr has been obtained by other
+ * means than the default, e.g., from Open Firmware or IDPROM.
+ * Returns 0 on success, negative on failure
+ **/
+static int i40e_macaddr_init(struct i40e_vsi *vsi, u8 *macaddr)
+{
+	int ret;
+	struct i40e_aqc_add_macvlan_element_data element;
+
+	ret = i40e_aq_mac_address_write(&vsi->back->hw,
+					I40E_AQC_WRITE_TYPE_LAA_WOL,
+					macaddr, NULL);
+	if (ret) {
+		dev_info(&vsi->back->pdev->dev,
+			 "Addr change for VSI failed: %d\n", ret);
+		return -EADDRNOTAVAIL;
+	}
+
+	memset(&element, 0, sizeof(element));
+	ether_addr_copy(element.mac_addr, macaddr);
+	element.flags = cpu_to_le16(I40E_AQC_MACVLAN_ADD_PERFECT_MATCH);
+	ret = i40e_aq_add_macvlan(&vsi->back->hw, vsi->seid, &element, 1, NULL);
+	if (ret) {
+		dev_info(&vsi->back->pdev->dev,
+			 "add filter failed err %s aq_err %s\n",
+			 i40e_stat_str(&vsi->back->hw, ret),
+			 i40e_aq_str(&vsi->back->hw,
+				     vsi->back->hw.aq.asq_last_status));
+	}
+	return ret;
+}
+
+/**
  * i40e_vsi_setup - Set up a VSI by a given type
  * @pf: board private structure
  * @type: VSI type
@@ -9336,6 +9798,17 @@ struct i40e_vsi *i40e_vsi_setup(struct i
 	switch (vsi->type) {
 	/* setup the netdev if needed */
 	case I40E_VSI_MAIN:
+		/* Apply relevant filters if a platform-specific mac
+		 * address was selected.
+		 */
+		if (!!(pf->flags & I40E_FLAG_PF_MAC)) {
+			ret = i40e_macaddr_init(vsi, pf->hw.mac.addr);
+			if (ret) {
+				dev_warn(&pf->pdev->dev,
+					 "could not set up macaddr; err %d\n",
+					 ret);
+			}
+		}
 	case I40E_VSI_VMDQ2:
 	case I40E_VSI_FCOE:
 		ret = i40e_config_netdev(vsi);
@@ -9614,13 +10087,13 @@ static int i40e_add_veb(struct i40e_veb
 {
 	struct i40e_pf *pf = veb->pf;
 	bool is_default = veb->pf->cur_promisc;
-	bool is_cloud = false;
+	bool enable_stats = !!(pf->flags & I40E_FLAG_VEB_STATS_ENABLED);
 	int ret;
 
 	/* get a VEB from the hardware */
 	ret = i40e_aq_add_veb(&pf->hw, veb->uplink_seid, vsi->seid,
 			      veb->enabled_tc, is_default,
-			      is_cloud, &veb->seid, NULL);
+			      &veb->seid, enable_stats, NULL);
 	if (ret) {
 		dev_info(&pf->pdev->dev,
 			 "couldn't add VEB, err %s aq_err %s\n",
@@ -9947,7 +10420,7 @@ static int i40e_setup_pf_switch(struct i
 	 * the hash
 	 */
 	if ((pf->flags & I40E_FLAG_RSS_ENABLED))
-		i40e_config_rss(pf);
+		i40e_pf_config_rss(pf);
 
 	/* fill in link information and enable LSE reporting */
 	i40e_update_link_info(&pf->hw);
@@ -9985,7 +10458,7 @@ static void i40e_determine_queue_usage(s
 	    !(pf->flags & I40E_FLAG_MSIX_ENABLED)) {
 		/* one qp for PF, no queues for anything else */
 		queues_left = 0;
-		pf->rss_size = pf->num_lan_qps = 1;
+		pf->alloc_rss_size = pf->num_lan_qps = 1;
 
 		/* make sure all the fancies are disabled */
 		pf->flags &= ~(I40E_FLAG_RSS_ENABLED	|
@@ -10002,7 +10475,7 @@ static void i40e_determine_queue_usage(s
 				  I40E_FLAG_FD_ATR_ENABLED |
 				  I40E_FLAG_DCB_CAPABLE))) {
 		/* one qp for PF */
-		pf->rss_size = pf->num_lan_qps = 1;
+		pf->alloc_rss_size = pf->num_lan_qps = 1;
 		queues_left -= pf->num_lan_qps;
 
 		pf->flags &= ~(I40E_FLAG_RSS_ENABLED	|
@@ -10072,8 +10545,9 @@ static void i40e_determine_queue_usage(s
 		"qs_avail=%d FD SB=%d lan_qs=%d lan_tc0=%d vf=%d*%d vmdq=%d*%d, remaining=%d\n",
 		pf->hw.func_caps.num_tx_qp,
 		!!(pf->flags & I40E_FLAG_FD_SB_ENABLED),
-		pf->num_lan_qps, pf->rss_size, pf->num_req_vfs, pf->num_vf_qps,
-		pf->num_vmdq_vsis, pf->num_vmdq_qps, queues_left);
+		pf->num_lan_qps, pf->alloc_rss_size, pf->num_req_vfs,
+		pf->num_vf_qps, pf->num_vmdq_vsis, pf->num_vmdq_qps,
+		queues_left);
 #ifdef I40E_FCOE
 	dev_dbg(&pf->pdev->dev, "fcoe queues = %d\n", pf->num_fcoe_qps);
 #endif
@@ -10111,55 +10585,74 @@ static int i40e_setup_pf_filter_control(
 }
 
 #define INFO_STRING_LEN 255
+#define REMAIN(__x) (INFO_STRING_LEN - (__x))
 static void i40e_print_features(struct i40e_pf *pf)
 {
 	struct i40e_hw *hw = &pf->hw;
-	char *buf, *string;
+	char *buf;
+	int i;
 
-	string = kzalloc(INFO_STRING_LEN, GFP_KERNEL);
-	if (!string) {
-		dev_err(&pf->pdev->dev, "Features string allocation failed\n");
+	buf = kmalloc(INFO_STRING_LEN, GFP_KERNEL);
+	if (!buf)
 		return;
-	}
-
-	buf = string;
 
-	buf += sprintf(string, "Features: PF-id[%d] ", hw->pf_id);
+	i = snprintf(buf, INFO_STRING_LEN, "Features: PF-id[%d]", hw->pf_id);
 #ifdef CONFIG_PCI_IOV
-	buf += sprintf(buf, "VFs: %d ", pf->num_req_vfs);
+	i += snprintf(&buf[i], REMAIN(i), " VFs: %d", pf->num_req_vfs);
 #endif
-	buf += sprintf(buf, "VSIs: %d QP: %d RX: %s ",
-		       pf->hw.func_caps.num_vsis,
-		       pf->vsi[pf->lan_vsi]->num_queue_pairs,
-		       pf->flags & I40E_FLAG_RX_PS_ENABLED ? "PS" : "1BUF");
+	i += snprintf(&buf[i], REMAIN(i), " VSIs: %d QP: %d RX: %s",
+		      pf->hw.func_caps.num_vsis,
+		      pf->vsi[pf->lan_vsi]->num_queue_pairs,
+		      pf->flags & I40E_FLAG_RX_PS_ENABLED ? "PS" : "1BUF");
 
 	if (pf->flags & I40E_FLAG_RSS_ENABLED)
-		buf += sprintf(buf, "RSS ");
+		i += snprintf(&buf[i], REMAIN(i), " RSS");
 	if (pf->flags & I40E_FLAG_FD_ATR_ENABLED)
-		buf += sprintf(buf, "FD_ATR ");
+		i += snprintf(&buf[i], REMAIN(i), " FD_ATR");
 	if (pf->flags & I40E_FLAG_FD_SB_ENABLED) {
-		buf += sprintf(buf, "FD_SB ");
-		buf += sprintf(buf, "NTUPLE ");
+		i += snprintf(&buf[i], REMAIN(i), " FD_SB");
+		i += snprintf(&buf[i], REMAIN(i), " NTUPLE");
 	}
 	if (pf->flags & I40E_FLAG_DCB_CAPABLE)
-		buf += sprintf(buf, "DCB ");
+		i += snprintf(&buf[i], REMAIN(i), " DCB");
 #if IS_ENABLED(CONFIG_VXLAN)
-	buf += sprintf(buf, "VxLAN ");
+	i += snprintf(&buf[i], REMAIN(i), " VxLAN");
+#endif
+#if IS_ENABLED(CONFIG_GENEVE)
+	i += snprintf(&buf[i], REMAIN(i), " Geneve");
 #endif
 	if (pf->flags & I40E_FLAG_PTP)
-		buf += sprintf(buf, "PTP ");
+		i += snprintf(&buf[i], REMAIN(i), " PTP");
 #ifdef I40E_FCOE
 	if (pf->flags & I40E_FLAG_FCOE_ENABLED)
-		buf += sprintf(buf, "FCOE ");
+		i += snprintf(&buf[i], REMAIN(i), " FCOE");
 #endif
 	if (pf->flags & I40E_FLAG_VEB_MODE_ENABLED)
-		buf += sprintf(buf, "VEB ");
+		i += snprintf(&buf[i], REMAIN(i), " VEB");
 	else
-		buf += sprintf(buf, "VEPA ");
+		i += snprintf(&buf[i], REMAIN(i), " VEPA");
+
+	dev_info(&pf->pdev->dev, "%s\n", buf);
+	kfree(buf);
+	WARN_ON(i > INFO_STRING_LEN);
+}
 
-	BUG_ON(buf > (string + INFO_STRING_LEN));
-	dev_info(&pf->pdev->dev, "%s\n", string);
-	kfree(string);
+/**
+ * i40e_get_platform_mac_addr - get platform-specific MAC address
+ *
+ * @pdev: PCI device information struct
+ * @pf: board private structure
+ *
+ * Look up the MAC address in Open Firmware  on systems that support it,
+ * and use IDPROM on SPARC if no OF address is found. On return, the
+ * I40E_FLAG_PF_MAC will be wset in pf->flags if a platform-specific value
+ * has been selected.
+ **/
+static void i40e_get_platform_mac_addr(struct pci_dev *pdev, struct i40e_pf *pf)
+{
+	pf->flags &= ~I40E_FLAG_PF_MAC;
+	if (!eth_platform_get_mac_address(&pdev->dev, pf->hw.mac.addr))
+		pf->flags |= I40E_FLAG_PF_MAC;
 }
 
 /**
@@ -10182,7 +10675,7 @@ static int i40e_probe(struct pci_dev *pd
 	u16 wol_nvm_bits;
 	u16 link_status;
 	int err;
-	u32 len;
+	u32 val;
 	u32 i;
 	u8 set_fc_aq_fail;
 
@@ -10302,6 +10795,16 @@ static int i40e_probe(struct pci_dev *pd
 	mutex_init(&hw->aq.arq_mutex);
 
 	err = i40e_init_adminq(hw);
+	if (err) {
+		if (err == I40E_ERR_FIRMWARE_API_VERSION)
+			dev_info(&pdev->dev,
+				 "The driver for the device stopped because the NVM image is newer than expected. You must install the most recent version of the network driver.\n");
+		else
+			dev_info(&pdev->dev,
+				 "The driver for the device stopped because the device firmware failed to init. Try updating your NVM image.\n");
+
+		goto err_pf_reset;
+	}
 
 	/* provide nvm, fw, api versions */
 	dev_info(&pdev->dev, "fw %d.%d.%05d api %d.%d nvm %s\n",
@@ -10309,12 +10812,6 @@ static int i40e_probe(struct pci_dev *pd
 		 hw->aq.api_maj_ver, hw->aq.api_min_ver,
 		 i40e_nvm_version_str(hw));
 
-	if (err) {
-		dev_info(&pdev->dev,
-			 "The driver for the device stopped because the NVM image is newer than expected. You must install the most recent version of the network driver.\n");
-		goto err_pf_reset;
-	}
-
 	if (hw->aq.api_maj_ver == I40E_FW_API_VERSION_MAJOR &&
 	    hw->aq.api_min_ver > I40E_FW_API_VERSION_MINOR)
 		dev_info(&pdev->dev,
@@ -10360,13 +10857,14 @@ static int i40e_probe(struct pci_dev *pd
 	 * Ignore error return codes because if it was already disabled via
 	 * hardware settings this will fail
 	 */
-	if (((pf->hw.aq.fw_maj_ver == 4) && (pf->hw.aq.fw_min_ver < 3)) ||
-	    (pf->hw.aq.fw_maj_ver < 4)) {
+	if (pf->flags & I40E_FLAG_STOP_FW_LLDP) {
 		dev_info(&pdev->dev, "Stopping firmware LLDP agent.\n");
 		i40e_aq_stop_lldp(hw, true, NULL);
 	}
 
 	i40e_get_mac_addr(hw, hw->mac.addr);
+	/* allow a platform config to override the HW addr */
+	i40e_get_platform_mac_addr(pdev, pf);
 	if (!is_valid_ether_addr(hw->mac.addr)) {
 		dev_info(&pdev->dev, "invalid MAC address %pM\n", hw->mac.addr);
 		err = -EIO;
@@ -10411,7 +10909,7 @@ static int i40e_probe(struct pci_dev *pd
 
 	/* NVM bit on means WoL disabled for the port */
 	i40e_read_nvm_word(hw, I40E_SR_NVM_WAKE_ON_LAN, &wol_nvm_bits);
-	if ((1 << hw->port) & wol_nvm_bits || hw->partition_id != 1)
+	if (BIT (hw->port) & wol_nvm_bits || hw->partition_id != 1)
 		pf->wol_en = false;
 	else
 		pf->wol_en = true;
@@ -10434,8 +10932,8 @@ static int i40e_probe(struct pci_dev *pd
 		pf->num_alloc_vsi = pf->hw.func_caps.num_vsis;
 
 	/* Set up the *vsi struct and our local tracking of the MAIN PF vsi. */
-	len = sizeof(struct i40e_vsi *) * pf->num_alloc_vsi;
-	pf->vsi = kzalloc(len, GFP_KERNEL);
+	pf->vsi = kcalloc(pf->num_alloc_vsi, sizeof(struct i40e_vsi *),
+			  GFP_KERNEL);
 	if (!pf->vsi) {
 		err = -ENOMEM;
 		goto err_switch_setup;
@@ -10482,19 +10980,29 @@ static int i40e_probe(struct pci_dev *pd
 		}
 	}
 
-	/* driver is only interested in link up/down and module qualification
-	 * reports from firmware
+	/* The driver only wants link up/down and module qualification
+	 * reports from firmware.  Note the negative logic.
 	 */
 	err = i40e_aq_set_phy_int_mask(&pf->hw,
-				       I40E_AQ_EVENT_LINK_UPDOWN |
-				       I40E_AQ_EVENT_MODULE_QUAL_FAIL, NULL);
+				       ~(I40E_AQ_EVENT_LINK_UPDOWN |
+					 I40E_AQ_EVENT_MODULE_QUAL_FAIL), NULL);
 	if (err)
 		dev_info(&pf->pdev->dev, "set phy mask fail, err %s aq_err %s\n",
 			 i40e_stat_str(&pf->hw, err),
 			 i40e_aq_str(&pf->hw, pf->hw.aq.asq_last_status));
 
-	if (((pf->hw.aq.fw_maj_ver == 4) && (pf->hw.aq.fw_min_ver < 33)) ||
-	    (pf->hw.aq.fw_maj_ver < 4)) {
+	/* Reconfigure hardware for allowing smaller MSS in the case
+	 * of TSO, so that we avoid the MDD being fired and causing
+	 * a reset in the case of small MSS+TSO.
+	 */
+	val = rd32(hw, I40E_REG_MSS);
+	if ((val & I40E_REG_MSS_MIN_MASK) > I40E_64BYTE_MSS) {
+		val &= ~I40E_REG_MSS_MIN_MASK;
+		val |= I40E_64BYTE_MSS;
+		wr32(hw, I40E_REG_MSS, val);
+	}
+
+	if (pf->flags & I40E_FLAG_RESTART_AUTONEG) {
 		msleep(75);
 		err = i40e_aq_set_link_restart_an(&pf->hw, true, NULL);
 		if (err)
@@ -10528,8 +11036,6 @@ static int i40e_probe(struct pci_dev *pd
 	if ((pf->flags & I40E_FLAG_SRIOV_ENABLED) &&
 	    (pf->flags & I40E_FLAG_MSIX_ENABLED) &&
 	    !test_bit(__I40E_BAD_EEPROM, &pf->state)) {
-		u32 val;
-
 		/* disable link interrupts for VFs */
 		val = rd32(hw, I40E_PFGEN_PORTMDIO_NUM);
 		val &= ~I40E_PFGEN_PORTMDIO_NUM_VFLINK_STAT_ENA_MASK;
@@ -10640,6 +11146,10 @@ static int i40e_probe(struct pci_dev *pd
 	i40e_add_filter_to_drop_tx_flow_control_frames(&pf->hw,
 						       pf->main_vsi_seid);
 
+	if ((pf->hw.device_id == I40E_DEV_ID_10G_BASE_T) ||
+	    (pf->hw.device_id == I40E_DEV_ID_10G_BASE_T4))
+		pf->flags |= I40E_FLAG_HAVE_10GBASET_PHY;
+
 	/* print a string summarizing features */
 	i40e_print_features(pf);
 
@@ -10696,10 +11206,11 @@ static void i40e_remove(struct pci_dev *
 	i40e_ptp_stop(pf);
 
 	/* Disable RSS in hw */
-	wr32(hw, I40E_PFQF_HENA(0), 0);
-	wr32(hw, I40E_PFQF_HENA(1), 0);
+	i40e_write_rx_ctl(hw, I40E_PFQF_HENA(0), 0);
+	i40e_write_rx_ctl(hw, I40E_PFQF_HENA(1), 0);
 
 	/* no more scheduling of any task */
+	set_bit(__I40E_SUSPENDED, &pf->state);
 	set_bit(__I40E_DOWN, &pf->state);
 	del_timer_sync(&pf->service_timer);
 	cancel_work_sync(&pf->service_task);
@@ -10730,8 +11241,8 @@ static void i40e_remove(struct pci_dev *
 		i40e_vsi_release(pf->vsi[pf->lan_vsi]);
 
 	/* shutdown and destroy the HMC */
-	if (pf->hw.hmc.hmc_obj) {
-		ret_code = i40e_shutdown_lan_hmc(&pf->hw);
+	if (hw->hmc.hmc_obj) {
+		ret_code = i40e_shutdown_lan_hmc(hw);
 		if (ret_code)
 			dev_warn(&pdev->dev,
 				 "Failed to destroy the HMC resources: %d\n",
@@ -10739,7 +11250,7 @@ static void i40e_remove(struct pci_dev *
 	}
 
 	/* shutdown the adminq */
-	ret_code = i40e_shutdown_adminq(&pf->hw);
+	ret_code = i40e_shutdown_adminq(hw);
 	if (ret_code)
 		dev_warn(&pdev->dev,
 			 "Failed to destroy the Admin Queue resources: %d\n",
@@ -10767,7 +11278,7 @@ static void i40e_remove(struct pci_dev *
 	kfree(pf->qp_pile);
 	kfree(pf->vsi);
 
-	iounmap(pf->hw.hw_addr);
+	iounmap(hw->hw_addr);
 	kfree(pf);
 	pci_release_selected_regions(pdev,
 				     pci_select_bars(pdev, IORESOURCE_MEM));
@@ -11002,6 +11513,16 @@ static int __init i40e_init_module(void)
 		i40e_driver_string, i40e_driver_version_str);
 	pr_info("%s: %s\n", i40e_driver_name, i40e_copyright);
 
+	/* we will see if single thread per module is enough for now,
+	 * it can't be any worse than using the system workqueue which
+	 * was already single threaded
+	 */
+	i40e_wq = create_singlethread_workqueue(i40e_driver_name);
+	if (!i40e_wq) {
+		pr_err("%s: Failed to create workqueue\n", i40e_driver_name);
+		return -ENOMEM;
+	}
+
 	i40e_dbg_init();
 	return pci_register_driver(&i40e_driver);
 }
@@ -11016,6 +11537,7 @@ module_init(i40e_init_module);
 static void __exit i40e_exit_module(void)
 {
 	pci_unregister_driver(&i40e_driver);
+	destroy_workqueue(i40e_wq);
 	i40e_dbg_exit();
 }
 module_exit(i40e_exit_module);
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/intel/i40e/i40e_nvm.c
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/intel/i40e/i40e_nvm.c
@@ -693,10 +693,11 @@ i40e_status i40e_nvmupd_command(struct i
 	/* early check for status command and debug msgs */
 	upd_cmd = i40e_nvmupd_validate_command(hw, cmd, perrno);
 
-	i40e_debug(hw, I40E_DEBUG_NVM, "%s state %d nvm_release_on_hold %d\n",
+	i40e_debug(hw, I40E_DEBUG_NVM, "%s state %d nvm_release_on_hold %d cmd 0x%08x config 0x%08x offset 0x%08x data_size 0x%08x\n",
 		   i40e_nvm_update_state_str[upd_cmd],
 		   hw->nvmupd_state,
-		   hw->aq.nvm_release_on_done);
+		   hw->aq.nvm_release_on_done,
+		   cmd->command, cmd->config, cmd->offset, cmd->data_size);
 
 	if (upd_cmd == I40E_NVMUPD_INVALID) {
 		*perrno = -EFAULT;
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/intel/i40e/i40e_prototype.h
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/intel/i40e/i40e_prototype.h
@@ -1,7 +1,7 @@
 /*******************************************************************************
  *
  * Intel Ethernet Controller XL710 Family Linux Driver
- * Copyright(c) 2013 - 2015 Intel Corporation.
+ * Copyright(c) 2013 - 2016 Intel Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms and conditions of the GNU General Public License,
@@ -74,6 +74,12 @@ i40e_status i40e_aq_set_rss_key(struct i
 
 u32 i40e_led_get(struct i40e_hw *hw);
 void i40e_led_set(struct i40e_hw *hw, u32 mode, bool blink);
+i40e_status i40e_led_set_phy(struct i40e_hw *hw, bool on,
+			     u16 led_addr, u32 mode);
+i40e_status i40e_led_get_phy(struct i40e_hw *hw, u16 *led_addr,
+			     u16 *val);
+i40e_status i40e_blink_phy_link_led(struct i40e_hw *hw,
+				    u32 time, u32 interval);
 
 /* admin send queue commands */
 
@@ -127,6 +133,9 @@ i40e_status i40e_aq_set_vsi_unicast_prom
 		u16 vsi_id, bool set, struct i40e_asq_cmd_details *cmd_details);
 i40e_status i40e_aq_set_vsi_multicast_promiscuous(struct i40e_hw *hw,
 		u16 vsi_id, bool set, struct i40e_asq_cmd_details *cmd_details);
+i40e_status i40e_aq_set_vsi_vlan_promisc(struct i40e_hw *hw,
+				u16 seid, bool enable,
+				struct i40e_asq_cmd_details *cmd_details);
 i40e_status i40e_aq_get_vsi_params(struct i40e_hw *hw,
 				struct i40e_vsi_context *vsi_ctx,
 				struct i40e_asq_cmd_details *cmd_details);
@@ -135,8 +144,8 @@ i40e_status i40e_aq_update_vsi_params(st
 				struct i40e_asq_cmd_details *cmd_details);
 i40e_status i40e_aq_add_veb(struct i40e_hw *hw, u16 uplink_seid,
 				u16 downlink_seid, u8 enabled_tc,
-				bool default_port, bool enable_l2_filtering,
-				u16 *pveb_seid,
+				bool default_port, u16 *pveb_seid,
+				bool enable_stats,
 				struct i40e_asq_cmd_details *cmd_details);
 i40e_status i40e_aq_get_veb_parameters(struct i40e_hw *hw,
 				u16 veb_seid, u16 *switch_id, bool *floating,
@@ -149,6 +158,15 @@ i40e_status i40e_aq_add_macvlan(struct i
 i40e_status i40e_aq_remove_macvlan(struct i40e_hw *hw, u16 vsi_id,
 			struct i40e_aqc_remove_macvlan_element_data *mv_list,
 			u16 count, struct i40e_asq_cmd_details *cmd_details);
+i40e_status i40e_aq_add_mirrorrule(struct i40e_hw *hw, u16 sw_seid,
+			u16 rule_type, u16 dest_vsi, u16 count, __le16 *mr_list,
+			struct i40e_asq_cmd_details *cmd_details,
+			u16 *rule_id, u16 *rules_used, u16 *rules_free);
+i40e_status i40e_aq_delete_mirrorrule(struct i40e_hw *hw, u16 sw_seid,
+			u16 rule_type, u16 rule_id, u16 count, __le16 *mr_list,
+			struct i40e_asq_cmd_details *cmd_details,
+			u16 *rules_used, u16 *rules_free);
+
 i40e_status i40e_aq_send_msg_to_vf(struct i40e_hw *hw, u16 vfid,
 				u32 v_opcode, u32 v_retval, u8 *msg, u16 msglen,
 				struct i40e_asq_cmd_details *cmd_details);
@@ -324,4 +342,19 @@ i40e_status i40e_aq_debug_dump(struct i4
 			       struct i40e_asq_cmd_details *cmd_details);
 void i40e_add_filter_to_drop_tx_flow_control_frames(struct i40e_hw *hw,
 						    u16 vsi_seid);
+i40e_status i40e_aq_rx_ctl_read_register(struct i40e_hw *hw,
+				u32 reg_addr, u32 *reg_val,
+				struct i40e_asq_cmd_details *cmd_details);
+u32 i40e_read_rx_ctl(struct i40e_hw *hw, u32 reg_addr);
+i40e_status i40e_aq_rx_ctl_write_register(struct i40e_hw *hw,
+				u32 reg_addr, u32 reg_val,
+				struct i40e_asq_cmd_details *cmd_details);
+void i40e_write_rx_ctl(struct i40e_hw *hw, u32 reg_addr, u32 reg_val);
+i40e_status i40e_read_phy_register(struct i40e_hw *hw, u8 page,
+				   u16 reg, u8 phy_addr, u16 *value);
+i40e_status i40e_write_phy_register(struct i40e_hw *hw, u8 page,
+				    u16 reg, u8 phy_addr, u16 value);
+u8 i40e_get_phy_address(struct i40e_hw *hw, u8 dev_num);
+i40e_status i40e_blink_phy_link_led(struct i40e_hw *hw,
+				    u32 time, u32 interval);
 #endif /* _I40E_PROTOTYPE_H_ */
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/intel/i40e/i40e_register.h
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/intel/i40e/i40e_register.h
@@ -2045,6 +2045,14 @@
 #define I40E_PRTPM_TLPIC 0x001E43C0 /* Reset: GLOBR */
 #define I40E_PRTPM_TLPIC_ETLPIC_SHIFT 0
 #define I40E_PRTPM_TLPIC_ETLPIC_MASK I40E_MASK(0xFFFFFFFF, I40E_PRTPM_TLPIC_ETLPIC_SHIFT)
+#define I40E_GL_PRS_FVBM(_i) (0x00269760 + ((_i) * 4)) /* _i=0...3 */ /* Reset: CORER */
+#define I40E_GL_PRS_FVBM_MAX_INDEX 3
+#define I40E_GL_PRS_FVBM_FV_BYTE_INDX_SHIFT 0
+#define I40E_GL_PRS_FVBM_FV_BYTE_INDX_MASK I40E_MASK(0x7F, I40E_GL_PRS_FVBM_FV_BYTE_INDX_SHIFT)
+#define I40E_GL_PRS_FVBM_RULE_BUS_INDX_SHIFT 8
+#define I40E_GL_PRS_FVBM_RULE_BUS_INDX_MASK I40E_MASK(0x3F, I40E_GL_PRS_FVBM_RULE_BUS_INDX_SHIFT)
+#define I40E_GL_PRS_FVBM_MSK_ENA_SHIFT 31
+#define I40E_GL_PRS_FVBM_MSK_ENA_MASK I40E_MASK(0x1, I40E_GL_PRS_FVBM_MSK_ENA_SHIFT)
 #define I40E_GLRPB_DPSS 0x000AC828 /* Reset: CORER */
 #define I40E_GLRPB_DPSS_DPS_TCN_SHIFT 0
 #define I40E_GLRPB_DPSS_DPS_TCN_MASK I40E_MASK(0xFFFFF, I40E_GLRPB_DPSS_DPS_TCN_SHIFT)
@@ -2216,6 +2224,14 @@
 #define I40E_PRTQF_FD_FLXINSET_MAX_INDEX 63
 #define I40E_PRTQF_FD_FLXINSET_INSET_SHIFT 0
 #define I40E_PRTQF_FD_FLXINSET_INSET_MASK I40E_MASK(0xFF, I40E_PRTQF_FD_FLXINSET_INSET_SHIFT)
+#define I40E_PRTQF_FD_INSET(_i, _j) (0x00250000 + ((_i) * 64 + (_j) * 32)) /* _i=0...63, _j=0...1 */ /* Reset: CORER */
+#define I40E_PRTQF_FD_INSET_MAX_INDEX 63
+#define I40E_PRTQF_FD_INSET_INSET_SHIFT 0
+#define I40E_PRTQF_FD_INSET_INSET_MASK I40E_MASK(0xFFFFFFFF, I40E_PRTQF_FD_INSET_INSET_SHIFT)
+#define I40E_PRTQF_FD_INSET(_i, _j) (0x00250000 + ((_i) * 64 + (_j) * 32)) /* _i=0...63, _j=0...1 */ /* Reset: CORER */
+#define I40E_PRTQF_FD_INSET_MAX_INDEX 63
+#define I40E_PRTQF_FD_INSET_INSET_SHIFT 0
+#define I40E_PRTQF_FD_INSET_INSET_MASK I40E_MASK(0xFFFFFFFF, I40E_PRTQF_FD_INSET_INSET_SHIFT)
 #define I40E_PRTQF_FD_MSK(_i, _j) (0x00252000 + ((_i) * 64 + (_j) * 32)) /* _i=0...63, _j=0...1 */ /* Reset: CORER */
 #define I40E_PRTQF_FD_MSK_MAX_INDEX 63
 #define I40E_PRTQF_FD_MSK_MASK_SHIFT 0
@@ -5155,6 +5171,38 @@
 #define I40E_GLQF_FD_PCTYPES_MAX_INDEX 63
 #define I40E_GLQF_FD_PCTYPES_FD_PCTYPE_SHIFT 0
 #define I40E_GLQF_FD_PCTYPES_FD_PCTYPE_MASK I40E_MASK(0x3F, I40E_GLQF_FD_PCTYPES_FD_PCTYPE_SHIFT)
+#define I40E_GLQF_FD_MSK(_i, _j) (0x00267200 + ((_i) * 4 + (_j) * 8)) /* _i=0...1, _j=0...63 */ /* Reset: CORER */
+#define I40E_GLQF_FD_MSK_MAX_INDEX 1
+#define I40E_GLQF_FD_MSK_MASK_SHIFT 0
+#define I40E_GLQF_FD_MSK_MASK_MASK I40E_MASK(0xFFFF, I40E_GLQF_FD_MSK_MASK_SHIFT)
+#define I40E_GLQF_FD_MSK_OFFSET_SHIFT 16
+#define I40E_GLQF_FD_MSK_OFFSET_MASK I40E_MASK(0x3F, I40E_GLQF_FD_MSK_OFFSET_SHIFT)
+#define I40E_GLQF_HASH_INSET(_i, _j) (0x00267600 + ((_i) * 4 + (_j) * 8)) /* _i=0...1, _j=0...63 */ /* Reset: CORER */
+#define I40E_GLQF_HASH_INSET_MAX_INDEX 1
+#define I40E_GLQF_HASH_INSET_INSET_SHIFT 0
+#define I40E_GLQF_HASH_INSET_INSET_MASK I40E_MASK(0xFFFFFFFF, I40E_GLQF_HASH_INSET_INSET_SHIFT)
+#define I40E_GLQF_HASH_MSK(_i, _j) (0x00267A00 + ((_i) * 4 + (_j) * 8)) /* _i=0...1, _j=0...63 */ /* Reset: CORER */
+#define I40E_GLQF_HASH_MSK_MAX_INDEX 1
+#define I40E_GLQF_HASH_MSK_MASK_SHIFT 0
+#define I40E_GLQF_HASH_MSK_MASK_MASK I40E_MASK(0xFFFF, I40E_GLQF_HASH_MSK_MASK_SHIFT)
+#define I40E_GLQF_HASH_MSK_OFFSET_SHIFT 16
+#define I40E_GLQF_HASH_MSK_OFFSET_MASK I40E_MASK(0x3F, I40E_GLQF_HASH_MSK_OFFSET_SHIFT)
+#define I40E_GLQF_ORT(_i) (0x00268900 + ((_i) * 4)) /* _i=0...63 */ /* Reset: CORER */
+#define I40E_GLQF_ORT_MAX_INDEX 63
+#define I40E_GLQF_ORT_PIT_INDX_SHIFT 0
+#define I40E_GLQF_ORT_PIT_INDX_MASK I40E_MASK(0x1F, I40E_GLQF_ORT_PIT_INDX_SHIFT)
+#define I40E_GLQF_ORT_FIELD_CNT_SHIFT 5
+#define I40E_GLQF_ORT_FIELD_CNT_MASK I40E_MASK(0x3, I40E_GLQF_ORT_FIELD_CNT_SHIFT)
+#define I40E_GLQF_ORT_FLX_PAYLOAD_SHIFT 7
+#define I40E_GLQF_ORT_FLX_PAYLOAD_MASK I40E_MASK(0x1, I40E_GLQF_ORT_FLX_PAYLOAD_SHIFT)
+#define I40E_GLQF_PIT(_i) (0x00268C80 + ((_i) * 4)) /* _i=0...23 */ /* Reset: CORER */
+#define I40E_GLQF_PIT_MAX_INDEX 23
+#define I40E_GLQF_PIT_SOURCE_OFF_SHIFT 0
+#define I40E_GLQF_PIT_SOURCE_OFF_MASK I40E_MASK(0x1F, I40E_GLQF_PIT_SOURCE_OFF_SHIFT)
+#define I40E_GLQF_PIT_FSIZE_SHIFT 5
+#define I40E_GLQF_PIT_FSIZE_MASK I40E_MASK(0x1F, I40E_GLQF_PIT_FSIZE_SHIFT)
+#define I40E_GLQF_PIT_DEST_OFF_SHIFT 10
+#define I40E_GLQF_PIT_DEST_OFF_MASK I40E_MASK(0x3F, I40E_GLQF_PIT_DEST_OFF_SHIFT)
 #define I40E_GLQF_FDEVICTENA(_i) (0x00270384 + ((_i) * 4)) /* _i=0...1 */ /* Reset: CORER */
 #define I40E_GLQF_FDEVICTENA_MAX_INDEX 1
 #define I40E_GLQF_FDEVICTENA_GLQF_FDEVICTENA_SHIFT 0
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/intel/i40e/i40e_txrx.c
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/intel/i40e/i40e_txrx.c
@@ -1,7 +1,7 @@
 /*******************************************************************************
  *
  * Intel Ethernet Controller XL710 Family Linux Driver
- * Copyright(c) 2013 - 2014 Intel Corporation.
+ * Copyright(c) 2013 - 2016 Intel Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms and conditions of the GNU General Public License,
@@ -235,6 +235,9 @@ static int i40e_add_del_fdir_udpv4(struc
 				 "Filter deleted for PCTYPE %d loc = %d\n",
 				 fd_data->pctype, fd_data->fd_id);
 	}
+	if (err)
+		kfree(raw_packet);
+
 	return err ? -EOPNOTSUPP : 0;
 }
 
@@ -312,6 +315,9 @@ static int i40e_add_del_fdir_tcpv4(struc
 				 fd_data->pctype, fd_data->fd_id);
 	}
 
+	if (err)
+		kfree(raw_packet);
+
 	return err ? -EOPNOTSUPP : 0;
 }
 
@@ -322,7 +328,7 @@ static int i40e_add_del_fdir_tcpv4(struc
  * @fd_data: the flow director data required for the FDir descriptor
  * @add: true adds a filter, false removes it
  *
- * Always returns -EOPNOTSUPP
+ * Returns 0 if the filters were successfully added or removed
  **/
 static int i40e_add_del_fdir_sctpv4(struct i40e_vsi *vsi,
 				    struct i40e_fdir_filter *fd_data,
@@ -387,6 +393,9 @@ static int i40e_add_del_fdir_ipv4(struct
 		}
 	}
 
+	if (err)
+		kfree(raw_packet);
+
 	return err ? -EOPNOTSUPP : 0;
 }
 
@@ -506,9 +515,6 @@ static void i40e_fd_handle_status(struct
 				pf->auto_disable_flags |=
 							I40E_FLAG_FD_SB_ENABLED;
 			}
-		} else {
-			dev_info(&pdev->dev,
-				"FD filter programming failed due to incorrect filter parameters\n");
 		}
 	} else if (error == BIT(I40E_RX_PROG_STATUS_DESC_NO_FD_ENTRY_SHIFT)) {
 		if (I40E_DEBUG_FD & pf->hw.debug_mask)
@@ -526,11 +532,7 @@ static void i40e_unmap_and_free_tx_resou
 					    struct i40e_tx_buffer *tx_buffer)
 {
 	if (tx_buffer->skb) {
-		if (tx_buffer->tx_flags & I40E_TX_FLAGS_FD_SB)
-			kfree(tx_buffer->raw_buf);
-		else
-			dev_kfree_skb_any(tx_buffer->skb);
-
+		dev_kfree_skb_any(tx_buffer->skb);
 		if (dma_unmap_len(tx_buffer, len))
 			dma_unmap_single(ring->dev,
 					 dma_unmap_addr(tx_buffer, dma),
@@ -542,6 +544,10 @@ static void i40e_unmap_and_free_tx_resou
 			       dma_unmap_len(tx_buffer, len),
 			       DMA_TO_DEVICE);
 	}
+
+	if (tx_buffer->tx_flags & I40E_TX_FLAGS_FD_SB)
+		kfree(tx_buffer->raw_buf);
+
 	tx_buffer->next_to_watch = NULL;
 	tx_buffer->skb = NULL;
 	dma_unmap_len_set(tx_buffer, len, 0);
@@ -604,15 +610,19 @@ void i40e_free_tx_resources(struct i40e_
 /**
  * i40e_get_tx_pending - how many tx descriptors not processed
  * @tx_ring: the ring of descriptors
+ * @in_sw: is tx_pending being checked in SW or HW
  *
  * Since there is no access to the ring head register
  * in XL710, we need to use our local copies
  **/
-u32 i40e_get_tx_pending(struct i40e_ring *ring)
+u32 i40e_get_tx_pending(struct i40e_ring *ring, bool in_sw)
 {
 	u32 head, tail;
 
-	head = i40e_get_head(ring);
+	if (!in_sw)
+		head = i40e_get_head(ring);
+	else
+		head = ring->next_to_clean;
 	tail = readl(ring->tail);
 
 	if (head != tail)
@@ -735,7 +745,7 @@ static bool i40e_clean_tx_irq(struct i40
 		 * them to be written back in case we stay in NAPI.
 		 * In this mode on X722 we do not enable Interrupt.
 		 */
-		j = i40e_get_tx_pending(tx_ring);
+		j = i40e_get_tx_pending(tx_ring, false);
 
 		if (budget &&
 		    ((j / (WB_STRIDE + 1)) == 0) && (j != 0) &&
@@ -768,29 +778,48 @@ static bool i40e_clean_tx_irq(struct i40
 }
 
 /**
- * i40e_force_wb - Arm hardware to do a wb on noncache aligned descriptors
+ * i40e_enable_wb_on_itr - Arm hardware to do a wb, interrupts are not enabled
  * @vsi: the VSI we care about
- * @q_vector: the vector  on which to force writeback
+ * @q_vector: the vector on which to enable writeback
  *
  **/
-void i40e_force_wb(struct i40e_vsi *vsi, struct i40e_q_vector *q_vector)
+static void i40e_enable_wb_on_itr(struct i40e_vsi *vsi,
+				  struct i40e_q_vector *q_vector)
 {
 	u16 flags = q_vector->tx.ring[0].flags;
+	u32 val;
 
-	if (flags & I40E_TXR_FLAGS_WB_ON_ITR) {
-		u32 val;
+	if (!(flags & I40E_TXR_FLAGS_WB_ON_ITR))
+		return;
 
-		if (q_vector->arm_wb_state)
-			return;
+	if (q_vector->arm_wb_state)
+		return;
 
-		val = I40E_PFINT_DYN_CTLN_WB_ON_ITR_MASK;
+	if (vsi->back->flags & I40E_FLAG_MSIX_ENABLED) {
+		val = I40E_PFINT_DYN_CTLN_WB_ON_ITR_MASK |
+		      I40E_PFINT_DYN_CTLN_ITR_INDX_MASK; /* set noitr */
 
 		wr32(&vsi->back->hw,
-		     I40E_PFINT_DYN_CTLN(q_vector->v_idx +
-					 vsi->base_vector - 1),
+		     I40E_PFINT_DYN_CTLN(q_vector->v_idx + vsi->base_vector - 1),
 		     val);
-		q_vector->arm_wb_state = true;
-	} else if (vsi->back->flags & I40E_FLAG_MSIX_ENABLED) {
+	} else {
+		val = I40E_PFINT_DYN_CTL0_WB_ON_ITR_MASK |
+		      I40E_PFINT_DYN_CTL0_ITR_INDX_MASK; /* set noitr */
+
+		wr32(&vsi->back->hw, I40E_PFINT_DYN_CTL0, val);
+	}
+	q_vector->arm_wb_state = true;
+}
+
+/**
+ * i40e_force_wb - Issue SW Interrupt so HW does a wb
+ * @vsi: the VSI we care about
+ * @q_vector: the vector  on which to force writeback
+ *
+ **/
+void i40e_force_wb(struct i40e_vsi *vsi, struct i40e_q_vector *q_vector)
+{
+	if (vsi->back->flags & I40E_FLAG_MSIX_ENABLED) {
 		u32 val = I40E_PFINT_DYN_CTLN_INTENA_MASK |
 			  I40E_PFINT_DYN_CTLN_ITR_INDX_MASK | /* set noitr */
 			  I40E_PFINT_DYN_CTLN_SWINT_TRIG_MASK |
@@ -1035,7 +1064,7 @@ void i40e_clean_rx_ring(struct i40e_ring
 			if (rx_bi->page_dma) {
 				dma_unmap_page(dev,
 					       rx_bi->page_dma,
-					       PAGE_SIZE / 2,
+					       PAGE_SIZE,
 					       DMA_FROM_DEVICE);
 				rx_bi->page_dma = 0;
 			}
@@ -1170,16 +1199,19 @@ static inline void i40e_release_rx_desc(
  * i40e_alloc_rx_buffers_ps - Replace used receive buffers; packet split
  * @rx_ring: ring to place buffers on
  * @cleaned_count: number of buffers to replace
+ *
+ * Returns true if any errors on allocation
  **/
-void i40e_alloc_rx_buffers_ps(struct i40e_ring *rx_ring, u16 cleaned_count)
+bool i40e_alloc_rx_buffers_ps(struct i40e_ring *rx_ring, u16 cleaned_count)
 {
 	u16 i = rx_ring->next_to_use;
 	union i40e_rx_desc *rx_desc;
 	struct i40e_rx_buffer *bi;
+	const int current_node = numa_node_id();
 
 	/* do nothing if no valid netdev defined */
 	if (!rx_ring->netdev || !cleaned_count)
-		return;
+		return false;
 
 	while (cleaned_count--) {
 		rx_desc = I40E_RX_DESC(rx_ring, i);
@@ -1187,56 +1219,79 @@ void i40e_alloc_rx_buffers_ps(struct i40
 
 		if (bi->skb) /* desc is in use */
 			goto no_buffers;
+
+	/* If we've been moved to a different NUMA node, release the
+	 * page so we can get a new one on the current node.
+	 */
+		if (bi->page &&  page_to_nid(bi->page) != current_node) {
+			dma_unmap_page(rx_ring->dev,
+				       bi->page_dma,
+				       PAGE_SIZE,
+				       DMA_FROM_DEVICE);
+			__free_page(bi->page);
+			bi->page = NULL;
+			bi->page_dma = 0;
+			rx_ring->rx_stats.realloc_count++;
+		} else if (bi->page) {
+			rx_ring->rx_stats.page_reuse_count++;
+		}
+
 		if (!bi->page) {
 			bi->page = alloc_page(GFP_ATOMIC);
 			if (!bi->page) {
 				rx_ring->rx_stats.alloc_page_failed++;
 				goto no_buffers;
 			}
-		}
-
-		if (!bi->page_dma) {
-			/* use a half page if we're re-using */
-			bi->page_offset ^= PAGE_SIZE / 2;
 			bi->page_dma = dma_map_page(rx_ring->dev,
 						    bi->page,
-						    bi->page_offset,
-						    PAGE_SIZE / 2,
+						    0,
+						    PAGE_SIZE,
 						    DMA_FROM_DEVICE);
-			if (dma_mapping_error(rx_ring->dev,
-					      bi->page_dma)) {
+			if (dma_mapping_error(rx_ring->dev, bi->page_dma)) {
 				rx_ring->rx_stats.alloc_page_failed++;
+				__free_page(bi->page);
+				bi->page = NULL;
 				bi->page_dma = 0;
+				bi->page_offset = 0;
 				goto no_buffers;
 			}
+			bi->page_offset = 0;
 		}
 
-		dma_sync_single_range_for_device(rx_ring->dev,
-						 bi->dma,
-						 0,
-						 rx_ring->rx_hdr_len,
-						 DMA_FROM_DEVICE);
 		/* Refresh the desc even if buffer_addrs didn't change
 		 * because each write-back erases this info.
 		 */
-		rx_desc->read.pkt_addr = cpu_to_le64(bi->page_dma);
+		rx_desc->read.pkt_addr =
+				cpu_to_le64(bi->page_dma + bi->page_offset);
 		rx_desc->read.hdr_addr = cpu_to_le64(bi->dma);
 		i++;
 		if (i == rx_ring->count)
 			i = 0;
 	}
 
+	if (rx_ring->next_to_use != i)
+		i40e_release_rx_desc(rx_ring, i);
+
+	return false;
+
 no_buffers:
 	if (rx_ring->next_to_use != i)
 		i40e_release_rx_desc(rx_ring, i);
+
+	/* make sure to come back via polling to try again after
+	 * allocation failure
+	 */
+	return true;
 }
 
 /**
  * i40e_alloc_rx_buffers_1buf - Replace used receive buffers; single buffer
  * @rx_ring: ring to place buffers on
  * @cleaned_count: number of buffers to replace
+ *
+ * Returns true if any errors on allocation
  **/
-void i40e_alloc_rx_buffers_1buf(struct i40e_ring *rx_ring, u16 cleaned_count)
+bool i40e_alloc_rx_buffers_1buf(struct i40e_ring *rx_ring, u16 cleaned_count)
 {
 	u16 i = rx_ring->next_to_use;
 	union i40e_rx_desc *rx_desc;
@@ -1245,7 +1300,7 @@ void i40e_alloc_rx_buffers_1buf(struct i
 
 	/* do nothing if no valid netdev defined */
 	if (!rx_ring->netdev || !cleaned_count)
-		return;
+		return false;
 
 	while (cleaned_count--) {
 		rx_desc = I40E_RX_DESC(rx_ring, i);
@@ -1253,8 +1308,10 @@ void i40e_alloc_rx_buffers_1buf(struct i
 		skb = bi->skb;
 
 		if (!skb) {
-			skb = netdev_alloc_skb_ip_align(rx_ring->netdev,
-							rx_ring->rx_buf_len);
+			skb = __netdev_alloc_skb_ip_align(rx_ring->netdev,
+							  rx_ring->rx_buf_len,
+							  GFP_ATOMIC |
+							  __GFP_NOWARN);
 			if (!skb) {
 				rx_ring->rx_stats.alloc_buff_failed++;
 				goto no_buffers;
@@ -1272,6 +1329,8 @@ void i40e_alloc_rx_buffers_1buf(struct i
 			if (dma_mapping_error(rx_ring->dev, bi->dma)) {
 				rx_ring->rx_stats.alloc_buff_failed++;
 				bi->dma = 0;
+				dev_kfree_skb(bi->skb);
+				bi->skb = NULL;
 				goto no_buffers;
 			}
 		}
@@ -1283,9 +1342,19 @@ void i40e_alloc_rx_buffers_1buf(struct i
 			i = 0;
 	}
 
+	if (rx_ring->next_to_use != i)
+		i40e_release_rx_desc(rx_ring, i);
+
+	return false;
+
 no_buffers:
 	if (rx_ring->next_to_use != i)
 		i40e_release_rx_desc(rx_ring, i);
+
+	/* make sure to come back via polling to try again after
+	 * allocation failure
+	 */
+	return true;
 }
 
 /**
@@ -1320,16 +1389,7 @@ static inline void i40e_rx_checksum(stru
 				    u16 rx_ptype)
 {
 	struct i40e_rx_ptype_decoded decoded = decode_rx_desc_ptype(rx_ptype);
-	bool ipv4 = false, ipv6 = false;
-	bool ipv4_tunnel, ipv6_tunnel;
-	__wsum rx_udp_csum;
-	struct iphdr *iph;
-	__sum16 csum;
-
-	ipv4_tunnel = (rx_ptype >= I40E_RX_PTYPE_GRENAT4_MAC_PAY3) &&
-		     (rx_ptype <= I40E_RX_PTYPE_GRENAT4_MACVLAN_IPV6_ICMP_PAY4);
-	ipv6_tunnel = (rx_ptype >= I40E_RX_PTYPE_GRENAT6_MAC_PAY3) &&
-		     (rx_ptype <= I40E_RX_PTYPE_GRENAT6_MACVLAN_IPV6_ICMP_PAY4);
+	bool ipv4, ipv6, ipv4_tunnel, ipv6_tunnel;
 
 	skb->ip_summed = CHECKSUM_NONE;
 
@@ -1345,12 +1405,10 @@ static inline void i40e_rx_checksum(stru
 	if (!(decoded.known && decoded.outer_ip))
 		return;
 
-	if (decoded.outer_ip == I40E_RX_PTYPE_OUTER_IP &&
-	    decoded.outer_ip_ver == I40E_RX_PTYPE_OUTER_IPV4)
-		ipv4 = true;
-	else if (decoded.outer_ip == I40E_RX_PTYPE_OUTER_IP &&
-		 decoded.outer_ip_ver == I40E_RX_PTYPE_OUTER_IPV6)
-		ipv6 = true;
+	ipv4 = (decoded.outer_ip == I40E_RX_PTYPE_OUTER_IP) &&
+	       (decoded.outer_ip_ver == I40E_RX_PTYPE_OUTER_IPV4);
+	ipv6 = (decoded.outer_ip == I40E_RX_PTYPE_OUTER_IP) &&
+	       (decoded.outer_ip_ver == I40E_RX_PTYPE_OUTER_IPV6);
 
 	if (ipv4 &&
 	    (rx_error & (BIT(I40E_RX_DESC_ERROR_IPE_SHIFT) |
@@ -1374,37 +1432,17 @@ static inline void i40e_rx_checksum(stru
 	if (rx_error & BIT(I40E_RX_DESC_ERROR_PPRS_SHIFT))
 		return;
 
-	/* If VXLAN traffic has an outer UDPv4 checksum we need to check
-	 * it in the driver, hardware does not do it for us.
-	 * Since L3L4P bit was set we assume a valid IHL value (>=5)
-	 * so the total length of IPv4 header is IHL*4 bytes
-	 * The UDP_0 bit *may* bet set if the *inner* header is UDP
-	 */
-	if (!(vsi->back->flags & I40E_FLAG_OUTER_UDP_CSUM_CAPABLE) &&
-	    (ipv4_tunnel)) {
-		skb->transport_header = skb->mac_header +
-					sizeof(struct ethhdr) +
-					(ip_hdr(skb)->ihl * 4);
-
-		/* Add 4 bytes for VLAN tagged packets */
-		skb->transport_header += (skb->protocol == htons(ETH_P_8021Q) ||
-					  skb->protocol == htons(ETH_P_8021AD))
-					  ? VLAN_HLEN : 0;
-
-		if ((ip_hdr(skb)->protocol == IPPROTO_UDP) &&
-		    (udp_hdr(skb)->check != 0)) {
-			rx_udp_csum = udp_csum(skb);
-			iph = ip_hdr(skb);
-			csum = csum_tcpudp_magic(
-					iph->saddr, iph->daddr,
-					(skb->len - skb_transport_offset(skb)),
-					IPPROTO_UDP, rx_udp_csum);
-
-			if (udp_hdr(skb)->check != csum)
-				goto checksum_fail;
+	/* The hardware supported by this driver does not validate outer
+	 * checksums for tunneled VXLAN or GENEVE frames.  I don't agree
+	 * with it but the specification states that you "MAY validate", it
+	 * doesn't make it a hard requirement so if we have validated the
+	 * inner checksum report CHECKSUM_UNNECESSARY.
+	 */
 
-		} /* else its GRE and so no outer UDP header */
-	}
+	ipv4_tunnel = (rx_ptype >= I40E_RX_PTYPE_GRENAT4_MAC_PAY3) &&
+		     (rx_ptype <= I40E_RX_PTYPE_GRENAT4_MACVLAN_IPV6_ICMP_PAY4);
+	ipv6_tunnel = (rx_ptype >= I40E_RX_PTYPE_GRENAT6_MAC_PAY3) &&
+		     (rx_ptype <= I40E_RX_PTYPE_GRENAT6_MACVLAN_IPV6_ICMP_PAY4);
 
 	skb->ip_summed = CHECKSUM_UNNECESSARY;
 	skb->csum_level = ipv4_tunnel || ipv6_tunnel;
@@ -1416,31 +1454,12 @@ checksum_fail:
 }
 
 /**
- * i40e_rx_hash - returns the hash value from the Rx descriptor
- * @ring: descriptor ring
- * @rx_desc: specific descriptor
- **/
-static inline u32 i40e_rx_hash(struct i40e_ring *ring,
-			       union i40e_rx_desc *rx_desc)
-{
-	const __le64 rss_mask =
-		cpu_to_le64((u64)I40E_RX_DESC_FLTSTAT_RSS_HASH <<
-			    I40E_RX_DESC_STATUS_FLTSTAT_SHIFT);
-
-	if ((ring->netdev->features & NETIF_F_RXHASH) &&
-	    (rx_desc->wb.qword1.status_error_len & rss_mask) == rss_mask)
-		return le32_to_cpu(rx_desc->wb.qword0.hi_dword.rss);
-	else
-		return 0;
-}
-
-/**
- * i40e_ptype_to_hash - get a hash type
+ * i40e_ptype_to_htype - get a hash type
  * @ptype: the ptype value from the descriptor
  *
  * Returns a hash type to be used by skb_set_hash
  **/
-static inline enum pkt_hash_types i40e_ptype_to_hash(u8 ptype)
+static inline enum pkt_hash_types i40e_ptype_to_htype(u8 ptype)
 {
 	struct i40e_rx_ptype_decoded decoded = decode_rx_desc_ptype(ptype);
 
@@ -1458,24 +1477,49 @@ static inline enum pkt_hash_types i40e_p
 }
 
 /**
+ * i40e_rx_hash - set the hash value in the skb
+ * @ring: descriptor ring
+ * @rx_desc: specific descriptor
+ **/
+static inline void i40e_rx_hash(struct i40e_ring *ring,
+				union i40e_rx_desc *rx_desc,
+				struct sk_buff *skb,
+				u8 rx_ptype)
+{
+	u32 hash;
+	const __le64 rss_mask  =
+		cpu_to_le64((u64)I40E_RX_DESC_FLTSTAT_RSS_HASH <<
+			    I40E_RX_DESC_STATUS_FLTSTAT_SHIFT);
+
+	if (ring->netdev->features & NETIF_F_RXHASH)
+		return;
+
+	if ((rx_desc->wb.qword1.status_error_len & rss_mask) == rss_mask) {
+		hash = le32_to_cpu(rx_desc->wb.qword0.hi_dword.rss);
+		skb_set_hash(skb, hash, i40e_ptype_to_htype(rx_ptype));
+	}
+}
+
+/**
  * i40e_clean_rx_irq_ps - Reclaim resources after receive; packet split
  * @rx_ring:  rx ring to clean
  * @budget:   how many cleans we're allowed
  *
  * Returns true if there's any budget left (e.g. the clean is finished)
  **/
-static int i40e_clean_rx_irq_ps(struct i40e_ring *rx_ring, int budget)
+static int i40e_clean_rx_irq_ps(struct i40e_ring *rx_ring, const int budget)
 {
 	unsigned int total_rx_bytes = 0, total_rx_packets = 0;
 	u16 rx_packet_len, rx_header_len, rx_sph, rx_hbo;
 	u16 cleaned_count = I40E_DESC_UNUSED(rx_ring);
-	const int current_node = numa_mem_id();
 	struct i40e_vsi *vsi = rx_ring->vsi;
 	u16 i = rx_ring->next_to_clean;
 	union i40e_rx_desc *rx_desc;
 	u32 rx_error, rx_status;
+	bool failure = false;
 	u8 rx_ptype;
 	u64 qword;
+	u32 copysize;
 
 	if (budget <= 0)
 		return 0;
@@ -1486,7 +1530,9 @@ static int i40e_clean_rx_irq_ps(struct i
 		u16 vlan_tag;
 		/* return some buffers to hardware, one at a time is too slow */
 		if (cleaned_count >= I40E_RX_BUFFER_WRITE) {
-			i40e_alloc_rx_buffers_ps(rx_ring, cleaned_count);
+			failure = failure ||
+				  i40e_alloc_rx_buffers_ps(rx_ring,
+							   cleaned_count);
 			cleaned_count = 0;
 		}
 
@@ -1504,6 +1550,12 @@ static int i40e_clean_rx_irq_ps(struct i
 		 * DD bit is set.
 		 */
 		dma_rmb();
+		/* sync header buffer for reading */
+		dma_sync_single_range_for_cpu(rx_ring->dev,
+					      rx_ring->rx_bi[0].dma,
+					      i * rx_ring->rx_hdr_len,
+					      rx_ring->rx_hdr_len,
+					      DMA_FROM_DEVICE);
 		if (i40e_rx_is_programming_status(qword)) {
 			i40e_clean_programming_status(rx_ring, rx_desc);
 			I40E_RX_INCREMENT(rx_ring, i);
@@ -1512,10 +1564,13 @@ static int i40e_clean_rx_irq_ps(struct i
 		rx_bi = &rx_ring->rx_bi[i];
 		skb = rx_bi->skb;
 		if (likely(!skb)) {
-			skb = netdev_alloc_skb_ip_align(rx_ring->netdev,
-							rx_ring->rx_hdr_len);
+			skb = __netdev_alloc_skb_ip_align(rx_ring->netdev,
+							  rx_ring->rx_hdr_len,
+							  GFP_ATOMIC |
+							  __GFP_NOWARN);
 			if (!skb) {
 				rx_ring->rx_stats.alloc_buff_failed++;
+				failure = true;
 				break;
 			}
 
@@ -1523,8 +1578,8 @@ static int i40e_clean_rx_irq_ps(struct i
 			skb_record_rx_queue(skb, rx_ring->queue_index);
 			/* we are reusing so sync this buffer for CPU use */
 			dma_sync_single_range_for_cpu(rx_ring->dev,
-						      rx_bi->dma,
-						      0,
+						      rx_ring->rx_bi[0].dma,
+						      i * rx_ring->rx_hdr_len,
 						      rx_ring->rx_hdr_len,
 						      DMA_FROM_DEVICE);
 		}
@@ -1542,9 +1597,16 @@ static int i40e_clean_rx_irq_ps(struct i
 
 		rx_ptype = (qword & I40E_RXD_QW1_PTYPE_MASK) >>
 			   I40E_RXD_QW1_PTYPE_SHIFT;
-		prefetch(rx_bi->page);
+		/* sync half-page for reading */
+		dma_sync_single_range_for_cpu(rx_ring->dev,
+					      rx_bi->page_dma,
+					      rx_bi->page_offset,
+					      PAGE_SIZE / 2,
+					      DMA_FROM_DEVICE);
+		prefetch(page_address(rx_bi->page) + rx_bi->page_offset);
 		rx_bi->skb = NULL;
 		cleaned_count++;
+		copysize = 0;
 		if (rx_hbo || rx_sph) {
 			int len;
 
@@ -1555,38 +1617,50 @@ static int i40e_clean_rx_irq_ps(struct i
 			memcpy(__skb_put(skb, len), rx_bi->hdr_buf, len);
 		} else if (skb->len == 0) {
 			int len;
+			unsigned char *va = page_address(rx_bi->page) +
+					    rx_bi->page_offset;
 
-			len = (rx_packet_len > skb_headlen(skb) ?
-				skb_headlen(skb) : rx_packet_len);
-			memcpy(__skb_put(skb, len),
-			       rx_bi->page + rx_bi->page_offset,
-			       len);
-			rx_bi->page_offset += len;
+			len = min(rx_packet_len, rx_ring->rx_hdr_len);
+			memcpy(__skb_put(skb, len), va, len);
+			copysize = len;
 			rx_packet_len -= len;
 		}
-
 		/* Get the rest of the data if this was a header split */
 		if (rx_packet_len) {
-			skb_fill_page_desc(skb, skb_shinfo(skb)->nr_frags,
-					   rx_bi->page,
-					   rx_bi->page_offset,
-					   rx_packet_len);
-
-			skb->len += rx_packet_len;
-			skb->data_len += rx_packet_len;
-			skb->truesize += rx_packet_len;
-
-			if ((page_count(rx_bi->page) == 1) &&
-			    (page_to_nid(rx_bi->page) == current_node))
-				get_page(rx_bi->page);
-			else
+			skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags,
+					rx_bi->page,
+					rx_bi->page_offset + copysize,
+					rx_packet_len, I40E_RXBUFFER_2048);
+
+			/* If the page count is more than 2, then both halves
+			 * of the page are used and we need to free it. Do it
+			 * here instead of in the alloc code. Otherwise one
+			 * of the half-pages might be released between now and
+			 * then, and we wouldn't know which one to use.
+			 * Don't call get_page and free_page since those are
+			 * both expensive atomic operations that just change
+			 * the refcount in opposite directions. Just give the
+			 * page to the stack; he can have our refcount.
+			 */
+			if (page_count(rx_bi->page) > 2) {
+				dma_unmap_page(rx_ring->dev,
+					       rx_bi->page_dma,
+					       PAGE_SIZE,
+					       DMA_FROM_DEVICE);
 				rx_bi->page = NULL;
+				rx_bi->page_dma = 0;
+				rx_ring->rx_stats.realloc_count++;
+			} else {
+				get_page(rx_bi->page);
+				/* switch to the other half-page here; the
+				 * allocation code programs the right addr
+				 * into HW. If we haven't used this half-page,
+				 * the address won't be changed, and HW can
+				 * just use it next time through.
+				 */
+				rx_bi->page_offset ^= PAGE_SIZE / 2;
+			}
 
-			dma_unmap_page(rx_ring->dev,
-				       rx_bi->page_dma,
-				       PAGE_SIZE / 2,
-				       DMA_FROM_DEVICE);
-			rx_bi->page_dma = 0;
 		}
 		I40E_RX_INCREMENT(rx_ring, i);
 
@@ -1606,8 +1680,8 @@ static int i40e_clean_rx_irq_ps(struct i
 			continue;
 		}
 
-		skb_set_hash(skb, i40e_rx_hash(rx_ring, rx_desc),
-			     i40e_ptype_to_hash(rx_ptype));
+		i40e_rx_hash(rx_ring, rx_desc, skb, rx_ptype);
+
 		if (unlikely(rx_status & I40E_RXD_QW1_STATUS_TSYNVALID_MASK)) {
 			i40e_ptp_rx_hwtstamp(vsi->back, skb, (rx_status &
 					   I40E_RXD_QW1_STATUS_TSYNINDX_MASK) >>
@@ -1646,7 +1720,7 @@ static int i40e_clean_rx_irq_ps(struct i
 	rx_ring->q_vector->rx.total_packets += total_rx_packets;
 	rx_ring->q_vector->rx.total_bytes += total_rx_bytes;
 
-	return total_rx_packets;
+	return failure ? budget : total_rx_packets;
 }
 
 /**
@@ -1664,6 +1738,7 @@ static int i40e_clean_rx_irq_1buf(struct
 	union i40e_rx_desc *rx_desc;
 	u32 rx_error, rx_status;
 	u16 rx_packet_len;
+	bool failure = false;
 	u8 rx_ptype;
 	u64 qword;
 	u16 i;
@@ -1674,7 +1749,9 @@ static int i40e_clean_rx_irq_1buf(struct
 		u16 vlan_tag;
 		/* return some buffers to hardware, one at a time is too slow */
 		if (cleaned_count >= I40E_RX_BUFFER_WRITE) {
-			i40e_alloc_rx_buffers_1buf(rx_ring, cleaned_count);
+			failure = failure ||
+				  i40e_alloc_rx_buffers_1buf(rx_ring,
+							     cleaned_count);
 			cleaned_count = 0;
 		}
 
@@ -1736,8 +1813,7 @@ static int i40e_clean_rx_irq_1buf(struct
 			continue;
 		}
 
-		skb_set_hash(skb, i40e_rx_hash(rx_ring, rx_desc),
-			     i40e_ptype_to_hash(rx_ptype));
+		i40e_rx_hash(rx_ring, rx_desc, skb, rx_ptype);
 		if (unlikely(rx_status & I40E_RXD_QW1_STATUS_TSYNVALID_MASK)) {
 			i40e_ptp_rx_hwtstamp(vsi->back, skb, (rx_status &
 					   I40E_RXD_QW1_STATUS_TSYNINDX_MASK) >>
@@ -1774,7 +1850,7 @@ static int i40e_clean_rx_irq_1buf(struct
 	rx_ring->q_vector->rx.total_packets += total_rx_packets;
 	rx_ring->q_vector->rx.total_bytes += total_rx_bytes;
 
-	return total_rx_packets;
+	return failure ? budget : total_rx_packets;
 }
 
 static u32 i40e_buildreg_itr(const int type, const u16 itr)
@@ -1782,7 +1858,9 @@ static u32 i40e_buildreg_itr(const int t
 	u32 val;
 
 	val = I40E_PFINT_DYN_CTLN_INTENA_MASK |
-	      I40E_PFINT_DYN_CTLN_CLEARPBA_MASK |
+	      /* Don't clear PBA because that can cause lost interrupts that
+	       * came in while we were cleaning/polling
+	       */
 	      (type << I40E_PFINT_DYN_CTLN_ITR_INDX_SHIFT) |
 	      (itr << I40E_PFINT_DYN_CTLN_INTERVAL_SHIFT);
 
@@ -1864,7 +1942,6 @@ enable_int:
 		q_vector->itr_countdown--;
 	else
 		q_vector->itr_countdown = ITR_COUNTDOWN_START;
-
 }
 
 /**
@@ -1892,12 +1969,15 @@ int i40e_napi_poll(struct napi_struct *n
 		return 0;
 	}
 
+	/* Clear hung_detected bit */
+	clear_bit(I40E_Q_VECTOR_HUNG_DETECT, &q_vector->hung_detected);
 	/* Since the actual Tx work is minimal, we can give the Tx a larger
 	 * budget and be more aggressive about cleaning up the Tx descriptors.
 	 */
 	i40e_for_each_ring(ring, q_vector->tx) {
-		clean_complete &= i40e_clean_tx_irq(ring, vsi->work_limit);
-		arm_wb |= ring->arm_wb;
+		clean_complete = clean_complete &&
+				 i40e_clean_tx_irq(ring, vsi->work_limit);
+		arm_wb = arm_wb || ring->arm_wb;
 		ring->arm_wb = false;
 	}
 
@@ -1920,14 +2000,16 @@ int i40e_napi_poll(struct napi_struct *n
 
 		work_done += cleaned;
 		/* if we didn't clean as many as budgeted, we must be done */
-		clean_complete &= (budget_per_ring != cleaned);
+		clean_complete = clean_complete && (budget_per_ring > cleaned);
 	}
 
 	/* If work not completed, return budget and polling will return */
 	if (!clean_complete) {
 tx_only:
-		if (arm_wb)
-			i40e_force_wb(vsi, q_vector);
+		if (arm_wb) {
+			q_vector->tx.ring[0].tx_stats.tx_force_wb++;
+			i40e_enable_wb_on_itr(vsi, q_vector);
+		}
 		return budget;
 	}
 
@@ -1939,20 +2021,7 @@ tx_only:
 	if (vsi->back->flags & I40E_FLAG_MSIX_ENABLED) {
 		i40e_update_enable_itr(vsi, q_vector);
 	} else { /* Legacy mode */
-		struct i40e_hw *hw = &vsi->back->hw;
-		/* We re-enable the queue 0 cause, but
-		 * don't worry about dynamic_enable
-		 * because we left it on for the other
-		 * possible interrupts during napi
-		 */
-		u32 qval = rd32(hw, I40E_QINT_RQCTL(0)) |
-			   I40E_QINT_RQCTL_CAUSE_ENA_MASK;
-
-		wr32(hw, I40E_QINT_RQCTL(0), qval);
-		qval = rd32(hw, I40E_QINT_TQCTL(0)) |
-		       I40E_QINT_TQCTL_CAUSE_ENA_MASK;
-		wr32(hw, I40E_QINT_TQCTL(0), qval);
-		i40e_irq_dynamic_enable_icr0(vsi->back);
+		i40e_irq_dynamic_enable_icr0(vsi->back, false);
 	}
 	return 0;
 }
@@ -1962,10 +2031,9 @@ tx_only:
  * @tx_ring:  ring to add programming descriptor to
  * @skb:      send buffer
  * @tx_flags: send tx flags
- * @protocol: wire protocol
  **/
 static void i40e_atr(struct i40e_ring *tx_ring, struct sk_buff *skb,
-		     u32 tx_flags, __be16 protocol)
+		     u32 tx_flags)
 {
 	struct i40e_filter_program_desc *fdir_desc;
 	struct i40e_pf *pf = tx_ring->vsi->back;
@@ -1977,6 +2045,7 @@ static void i40e_atr(struct i40e_ring *t
 	struct tcphdr *th;
 	unsigned int hlen;
 	u32 flex_ptype, dtype_cmd;
+	int l4_proto;
 	u16 i;
 
 	/* make sure ATR is enabled */
@@ -1990,36 +2059,28 @@ static void i40e_atr(struct i40e_ring *t
 	if (!tx_ring->atr_sample_rate)
 		return;
 
+	/* Currently only IPv4/IPv6 with TCP is supported */
 	if (!(tx_flags & (I40E_TX_FLAGS_IPV4 | I40E_TX_FLAGS_IPV6)))
 		return;
 
-	if (!(tx_flags & I40E_TX_FLAGS_VXLAN_TUNNEL)) {
-		/* snag network header to get L4 type and address */
-		hdr.network = skb_network_header(skb);
+	/* snag network header to get L4 type and address */
+	hdr.network = (tx_flags & I40E_TX_FLAGS_UDP_TUNNEL) ?
+		      skb_inner_network_header(skb) : skb_network_header(skb);
 
-		/* Currently only IPv4/IPv6 with TCP is supported
-		 * access ihl as u8 to avoid unaligned access on ia64
-		 */
-		if (tx_flags & I40E_TX_FLAGS_IPV4)
-			hlen = (hdr.network[0] & 0x0F) << 2;
-		else if (protocol == htons(ETH_P_IPV6))
-			hlen = sizeof(struct ipv6hdr);
-		else
-			return;
+	/* Note: tx_flags gets modified to reflect inner protocols in
+	 * tx_enable_csum function if encap is enabled.
+	 */
+	if (tx_flags & I40E_TX_FLAGS_IPV4) {
+		/* access ihl as u8 to avoid unaligned access on ia64 */
+		hlen = (hdr.network[0] & 0x0F) << 2;
+		l4_proto = hdr.ipv4->protocol;
 	} else {
-		hdr.network = skb_inner_network_header(skb);
-		hlen = skb_inner_network_header_len(skb);
+		hlen = hdr.network - skb->data;
+		l4_proto = ipv6_find_hdr(skb, &hlen, IPPROTO_TCP, NULL, NULL);
+		hlen -= hdr.network - skb->data;
 	}
 
-	/* Currently only IPv4/IPv6 with TCP is supported
-	 * Note: tx_flags gets modified to reflect inner protocols in
-	 * tx_enable_csum function if encap is enabled.
-	 */
-	if ((tx_flags & I40E_TX_FLAGS_IPV4) &&
-	    (hdr.ipv4->protocol != IPPROTO_TCP))
-		return;
-	else if ((tx_flags & I40E_TX_FLAGS_IPV6) &&
-		 (hdr.ipv6->nexthdr != IPPROTO_TCP))
+	if (l4_proto != IPPROTO_TCP)
 		return;
 
 	th = (struct tcphdr *)(hdr.network + hlen);
@@ -2027,7 +2088,8 @@ static void i40e_atr(struct i40e_ring *t
 	/* Due to lack of space, no more new filters can be programmed */
 	if (th->syn && (pf->auto_disable_flags & I40E_FLAG_FD_ATR_ENABLED))
 		return;
-	if (pf->flags & I40E_FLAG_HW_ATR_EVICT_CAPABLE) {
+	if ((pf->flags & I40E_FLAG_HW_ATR_EVICT_CAPABLE) &&
+	    (!(pf->auto_disable_flags & I40E_FLAG_HW_ATR_EVICT_CAPABLE))) {
 		/* HW ATR eviction will take care of removing filters on FIN
 		 * and RST packets.
 		 */
@@ -2055,7 +2117,7 @@ static void i40e_atr(struct i40e_ring *t
 
 	flex_ptype = (tx_ring->queue_index << I40E_TXD_FLTR_QW0_QINDEX_SHIFT) &
 		      I40E_TXD_FLTR_QW0_QINDEX_MASK;
-	flex_ptype |= (protocol == htons(ETH_P_IP)) ?
+	flex_ptype |= (tx_flags & I40E_TX_FLAGS_IPV4) ?
 		      (I40E_FILTER_PCTYPE_NONF_IPV4_TCP <<
 		       I40E_TXD_FLTR_QW0_PCTYPE_SHIFT) :
 		      (I40E_FILTER_PCTYPE_NONF_IPV6_TCP <<
@@ -2078,7 +2140,7 @@ static void i40e_atr(struct i40e_ring *t
 		     I40E_TXD_FLTR_QW1_FD_STATUS_SHIFT;
 
 	dtype_cmd |= I40E_TXD_FLTR_QW1_CNT_ENA_MASK;
-	if (!(tx_flags & I40E_TX_FLAGS_VXLAN_TUNNEL))
+	if (!(tx_flags & I40E_TX_FLAGS_UDP_TUNNEL))
 		dtype_cmd |=
 			((u32)I40E_FD_ATR_STAT_IDX(pf->hw.pf_id) <<
 			I40E_TXD_FLTR_QW1_CNTINDEX_SHIFT) &
@@ -2089,7 +2151,8 @@ static void i40e_atr(struct i40e_ring *t
 			I40E_TXD_FLTR_QW1_CNTINDEX_SHIFT) &
 			I40E_TXD_FLTR_QW1_CNTINDEX_MASK;
 
-	if (pf->flags & I40E_FLAG_HW_ATR_EVICT_CAPABLE)
+	if ((pf->flags & I40E_FLAG_HW_ATR_EVICT_CAPABLE) &&
+	    (!(pf->auto_disable_flags & I40E_FLAG_HW_ATR_EVICT_CAPABLE)))
 		dtype_cmd |= I40E_TXD_FLTR_QW1_ATR_MASK;
 
 	fdir_desc->qindex_flex_ptype_vsi = cpu_to_le32(flex_ptype);
@@ -2187,22 +2250,30 @@ out:
  * @tx_ring:  ptr to the ring to send
  * @skb:      ptr to the skb we're sending
  * @hdr_len:  ptr to the size of the packet header
- * @cd_type_cmd_tso_mss: ptr to u64 object
- * @cd_tunneling: ptr to context descriptor bits
+ * @cd_type_cmd_tso_mss: Quad Word 1
  *
  * Returns 0 if no TSO can happen, 1 if tso is going, or error
  **/
 static int i40e_tso(struct i40e_ring *tx_ring, struct sk_buff *skb,
-		    u8 *hdr_len, u64 *cd_type_cmd_tso_mss,
-		    u32 *cd_tunneling)
+		    u8 *hdr_len, u64 *cd_type_cmd_tso_mss)
 {
-	u32 cd_cmd, cd_tso_len, cd_mss;
-	struct ipv6hdr *ipv6h;
-	struct tcphdr *tcph;
-	struct iphdr *iph;
-	u32 l4len;
+	u64 cd_cmd, cd_tso_len, cd_mss;
+	union {
+		struct iphdr *v4;
+		struct ipv6hdr *v6;
+		unsigned char *hdr;
+	} ip;
+	union {
+		struct tcphdr *tcp;
+		struct udphdr *udp;
+		unsigned char *hdr;
+	} l4;
+	u32 paylen, l4_offset;
 	int err;
 
+	if (skb->ip_summed != CHECKSUM_PARTIAL)
+		return 0;
+
 	if (!skb_is_gso(skb))
 		return 0;
 
@@ -2210,35 +2281,60 @@ static int i40e_tso(struct i40e_ring *tx
 	if (err < 0)
 		return err;
 
-	iph = skb->encapsulation ? inner_ip_hdr(skb) : ip_hdr(skb);
-	ipv6h = skb->encapsulation ? inner_ipv6_hdr(skb) : ipv6_hdr(skb);
+	ip.hdr = skb_network_header(skb);
+	l4.hdr = skb_transport_header(skb);
+
+	/* initialize outer IP header fields */
+	if (ip.v4->version == 4) {
+		ip.v4->tot_len = 0;
+		ip.v4->check = 0;
+	} else {
+		ip.v6->payload_len = 0;
+	}
 
-	if (iph->version == 4) {
-		tcph = skb->encapsulation ? inner_tcp_hdr(skb) : tcp_hdr(skb);
-		iph->tot_len = 0;
-		iph->check = 0;
-		tcph->check = ~csum_tcpudp_magic(iph->saddr, iph->daddr,
-						 0, IPPROTO_TCP, 0);
-	} else if (ipv6h->version == 6) {
-		tcph = skb->encapsulation ? inner_tcp_hdr(skb) : tcp_hdr(skb);
-		ipv6h->payload_len = 0;
-		tcph->check = ~csum_ipv6_magic(&ipv6h->saddr, &ipv6h->daddr,
-					       0, IPPROTO_TCP, 0);
-	}
-
-	l4len = skb->encapsulation ? inner_tcp_hdrlen(skb) : tcp_hdrlen(skb);
-	*hdr_len = (skb->encapsulation
-		    ? (skb_inner_transport_header(skb) - skb->data)
-		    : skb_transport_offset(skb)) + l4len;
+	if (skb_shinfo(skb)->gso_type & (SKB_GSO_UDP_TUNNEL | SKB_GSO_GRE |
+					 SKB_GSO_UDP_TUNNEL_CSUM)) {
+		if (skb_shinfo(skb)->gso_type & SKB_GSO_UDP_TUNNEL_CSUM) {
+			/* determine offset of outer transport header */
+			l4_offset = l4.hdr - skb->data;
+
+			/* remove payload length from outer checksum */
+			paylen = (__force u16)l4.udp->check;
+			paylen += ntohs(1) * (u16)~(skb->len - l4_offset);
+			l4.udp->check = ~csum_fold((__force __wsum)paylen);
+		}
+
+		/* reset pointers to inner headers */
+		ip.hdr = skb_inner_network_header(skb);
+		l4.hdr = skb_inner_transport_header(skb);
+
+		/* initialize inner IP header fields */
+		if (ip.v4->version == 4) {
+			ip.v4->tot_len = 0;
+			ip.v4->check = 0;
+		} else {
+			ip.v6->payload_len = 0;
+		}
+	}
+
+	/* determine offset of inner transport header */
+	l4_offset = l4.hdr - skb->data;
+
+	/* remove payload length from inner checksum */
+	paylen = (__force u16)l4.tcp->check;
+	paylen += ntohs(1) * (u16)~(skb->len - l4_offset);
+	l4.tcp->check = ~csum_fold((__force __wsum)paylen);
+
+	/* compute length of segmentation header */
+	*hdr_len = (l4.tcp->doff * 4) + l4_offset;
 
 	/* find the field values */
 	cd_cmd = I40E_TX_CTX_DESC_TSO;
 	cd_tso_len = skb->len - *hdr_len;
 	cd_mss = skb_shinfo(skb)->gso_size;
-	*cd_type_cmd_tso_mss |= ((u64)cd_cmd << I40E_TXD_CTX_QW1_CMD_SHIFT) |
-				((u64)cd_tso_len <<
-				 I40E_TXD_CTX_QW1_TSO_LEN_SHIFT) |
-				((u64)cd_mss << I40E_TXD_CTX_QW1_MSS_SHIFT);
+	*cd_type_cmd_tso_mss |= (cd_cmd << I40E_TXD_CTX_QW1_CMD_SHIFT) |
+				(cd_tso_len << I40E_TXD_CTX_QW1_TSO_LEN_SHIFT) |
+				(cd_mss << I40E_TXD_CTX_QW1_MSS_SHIFT);
 	return 1;
 }
 
@@ -2247,7 +2343,7 @@ static int i40e_tso(struct i40e_ring *tx
  * @tx_ring:  ptr to the ring to send
  * @skb:      ptr to the skb we're sending
  * @tx_flags: the collected send information
- * @cd_type_cmd_tso_mss: ptr to u64 object
+ * @cd_type_cmd_tso_mss: Quad Word 1
  *
  * Returns 0 if no Tx timestamp can happen and 1 if the timestamp will happen
  **/
@@ -2293,129 +2389,154 @@ static int i40e_tsyn(struct i40e_ring *t
  * @tx_ring: Tx descriptor ring
  * @cd_tunneling: ptr to context desc bits
  **/
-static void i40e_tx_enable_csum(struct sk_buff *skb, u32 *tx_flags,
-				u32 *td_cmd, u32 *td_offset,
-				struct i40e_ring *tx_ring,
-				u32 *cd_tunneling)
-{
-	struct ipv6hdr *this_ipv6_hdr;
-	unsigned int this_tcp_hdrlen;
-	struct iphdr *this_ip_hdr;
-	u32 network_hdr_len;
-	u8 l4_hdr = 0;
-	struct udphdr *oudph;
-	struct iphdr *oiph;
-	u32 l4_tunnel = 0;
+static int i40e_tx_enable_csum(struct sk_buff *skb, u32 *tx_flags,
+			       u32 *td_cmd, u32 *td_offset,
+			       struct i40e_ring *tx_ring,
+			       u32 *cd_tunneling)
+{
+	union {
+		struct iphdr *v4;
+		struct ipv6hdr *v6;
+		unsigned char *hdr;
+	} ip;
+	union {
+		struct tcphdr *tcp;
+		struct udphdr *udp;
+		unsigned char *hdr;
+	} l4;
+	unsigned char *exthdr;
+	u32 offset, cmd = 0, tunnel = 0;
+	__be16 frag_off;
+	u8 l4_proto = 0;
+
+	if (skb->ip_summed != CHECKSUM_PARTIAL)
+		return 0;
+
+	ip.hdr = skb_network_header(skb);
+	l4.hdr = skb_transport_header(skb);
+
+	/* compute outer L2 header size */
+	offset = ((ip.hdr - skb->data) / 2) << I40E_TX_DESC_LENGTH_MACLEN_SHIFT;
 
 	if (skb->encapsulation) {
-		switch (ip_hdr(skb)->protocol) {
+		/* define outer network header type */
+		if (*tx_flags & I40E_TX_FLAGS_IPV4) {
+			tunnel |= (*tx_flags & I40E_TX_FLAGS_TSO) ?
+				  I40E_TX_CTX_EXT_IP_IPV4 :
+				  I40E_TX_CTX_EXT_IP_IPV4_NO_CSUM;
+
+			l4_proto = ip.v4->protocol;
+		} else if (*tx_flags & I40E_TX_FLAGS_IPV6) {
+			tunnel |= I40E_TX_CTX_EXT_IP_IPV6;
+
+			exthdr = ip.hdr + sizeof(*ip.v6);
+			l4_proto = ip.v6->nexthdr;
+			if (l4.hdr != exthdr)
+				ipv6_skip_exthdr(skb, exthdr - skb->data,
+						 &l4_proto, &frag_off);
+		}
+
+		/* compute outer L3 header size */
+		tunnel |= ((l4.hdr - ip.hdr) / 4) <<
+			  I40E_TXD_CTX_QW0_EXT_IPLEN_SHIFT;
+
+		/* switch IP header pointer from outer to inner header */
+		ip.hdr = skb_inner_network_header(skb);
+
+		/* define outer transport */
+		switch (l4_proto) {
 		case IPPROTO_UDP:
-			oudph = udp_hdr(skb);
-			oiph = ip_hdr(skb);
-			l4_tunnel = I40E_TXD_CTX_UDP_TUNNELING;
-			*tx_flags |= I40E_TX_FLAGS_VXLAN_TUNNEL;
+			tunnel |= I40E_TXD_CTX_UDP_TUNNELING;
+			*tx_flags |= I40E_TX_FLAGS_UDP_TUNNEL;
 			break;
 		case IPPROTO_GRE:
-			l4_tunnel = I40E_TXD_CTX_GRE_TUNNELING;
+			tunnel |= I40E_TXD_CTX_GRE_TUNNELING;
+			*tx_flags |= I40E_TX_FLAGS_UDP_TUNNEL;
 			break;
 		default:
-			return;
-		}
-		network_hdr_len = skb_inner_network_header_len(skb);
-		this_ip_hdr = inner_ip_hdr(skb);
-		this_ipv6_hdr = inner_ipv6_hdr(skb);
-		this_tcp_hdrlen = inner_tcp_hdrlen(skb);
-
-		if (*tx_flags & I40E_TX_FLAGS_IPV4) {
-			if (*tx_flags & I40E_TX_FLAGS_TSO) {
-				*cd_tunneling |= I40E_TX_CTX_EXT_IP_IPV4;
-				ip_hdr(skb)->check = 0;
-			} else {
-				*cd_tunneling |=
-					 I40E_TX_CTX_EXT_IP_IPV4_NO_CSUM;
-			}
-		} else if (*tx_flags & I40E_TX_FLAGS_IPV6) {
-			*cd_tunneling |= I40E_TX_CTX_EXT_IP_IPV6;
 			if (*tx_flags & I40E_TX_FLAGS_TSO)
-				ip_hdr(skb)->check = 0;
+				return -1;
+
+			skb_checksum_help(skb);
+			return 0;
 		}
 
-		/* Now set the ctx descriptor fields */
-		*cd_tunneling |= (skb_network_header_len(skb) >> 2) <<
-				   I40E_TXD_CTX_QW0_EXT_IPLEN_SHIFT      |
-				   l4_tunnel                             |
-				   ((skb_inner_network_offset(skb) -
-					skb_transport_offset(skb)) >> 1) <<
-				   I40E_TXD_CTX_QW0_NATLEN_SHIFT;
-		if (this_ip_hdr->version == 6) {
-			*tx_flags &= ~I40E_TX_FLAGS_IPV4;
+		/* compute tunnel header size */
+		tunnel |= ((ip.hdr - l4.hdr) / 2) <<
+			  I40E_TXD_CTX_QW0_NATLEN_SHIFT;
+
+		/* indicate if we need to offload outer UDP header */
+		if ((*tx_flags & I40E_TX_FLAGS_TSO) &&
+		    (skb_shinfo(skb)->gso_type & SKB_GSO_UDP_TUNNEL_CSUM))
+			tunnel |= I40E_TXD_CTX_QW0_L4T_CS_MASK;
+
+		/* record tunnel offload values */
+		*cd_tunneling |= tunnel;
+
+		/* switch L4 header pointer from outer to inner */
+		l4.hdr = skb_inner_transport_header(skb);
+		l4_proto = 0;
+
+		/* reset type as we transition from outer to inner headers */
+		*tx_flags &= ~(I40E_TX_FLAGS_IPV4 | I40E_TX_FLAGS_IPV6);
+		if (ip.v4->version == 4)
+			*tx_flags |= I40E_TX_FLAGS_IPV4;
+		if (ip.v6->version == 6)
 			*tx_flags |= I40E_TX_FLAGS_IPV6;
-		}
-		if ((tx_ring->flags & I40E_TXR_FLAGS_OUTER_UDP_CSUM) &&
-		    (l4_tunnel == I40E_TXD_CTX_UDP_TUNNELING)        &&
-		    (*cd_tunneling & I40E_TXD_CTX_QW0_EXT_IP_MASK)) {
-			oudph->check = ~csum_tcpudp_magic(oiph->saddr,
-					oiph->daddr,
-					(skb->len - skb_transport_offset(skb)),
-					IPPROTO_UDP, 0);
-			*cd_tunneling |= I40E_TXD_CTX_QW0_L4T_CS_MASK;
-		}
-	} else {
-		network_hdr_len = skb_network_header_len(skb);
-		this_ip_hdr = ip_hdr(skb);
-		this_ipv6_hdr = ipv6_hdr(skb);
-		this_tcp_hdrlen = tcp_hdrlen(skb);
 	}
 
 	/* Enable IP checksum offloads */
 	if (*tx_flags & I40E_TX_FLAGS_IPV4) {
-		l4_hdr = this_ip_hdr->protocol;
+		l4_proto = ip.v4->protocol;
 		/* the stack computes the IP header already, the only time we
 		 * need the hardware to recompute it is in the case of TSO.
 		 */
-		if (*tx_flags & I40E_TX_FLAGS_TSO) {
-			*td_cmd |= I40E_TX_DESC_CMD_IIPT_IPV4_CSUM;
-			this_ip_hdr->check = 0;
-		} else {
-			*td_cmd |= I40E_TX_DESC_CMD_IIPT_IPV4;
-		}
-		/* Now set the td_offset for IP header length */
-		*td_offset = (network_hdr_len >> 2) <<
-			      I40E_TX_DESC_LENGTH_IPLEN_SHIFT;
+		cmd |= (*tx_flags & I40E_TX_FLAGS_TSO) ?
+		       I40E_TX_DESC_CMD_IIPT_IPV4_CSUM :
+		       I40E_TX_DESC_CMD_IIPT_IPV4;
 	} else if (*tx_flags & I40E_TX_FLAGS_IPV6) {
-		l4_hdr = this_ipv6_hdr->nexthdr;
-		*td_cmd |= I40E_TX_DESC_CMD_IIPT_IPV6;
-		/* Now set the td_offset for IP header length */
-		*td_offset = (network_hdr_len >> 2) <<
-			      I40E_TX_DESC_LENGTH_IPLEN_SHIFT;
-	}
-	/* words in MACLEN + dwords in IPLEN + dwords in L4Len */
-	*td_offset |= (skb_network_offset(skb) >> 1) <<
-		       I40E_TX_DESC_LENGTH_MACLEN_SHIFT;
+		cmd |= I40E_TX_DESC_CMD_IIPT_IPV6;
+
+		exthdr = ip.hdr + sizeof(*ip.v6);
+		l4_proto = ip.v6->nexthdr;
+		if (l4.hdr != exthdr)
+			ipv6_skip_exthdr(skb, exthdr - skb->data,
+					 &l4_proto, &frag_off);
+	}
+
+	/* compute inner L3 header size */
+	offset |= ((l4.hdr - ip.hdr) / 4) << I40E_TX_DESC_LENGTH_IPLEN_SHIFT;
 
 	/* Enable L4 checksum offloads */
-	switch (l4_hdr) {
+	switch (l4_proto) {
 	case IPPROTO_TCP:
 		/* enable checksum offloads */
-		*td_cmd |= I40E_TX_DESC_CMD_L4T_EOFT_TCP;
-		*td_offset |= (this_tcp_hdrlen >> 2) <<
-			       I40E_TX_DESC_LENGTH_L4_FC_LEN_SHIFT;
+		cmd |= I40E_TX_DESC_CMD_L4T_EOFT_TCP;
+		offset |= l4.tcp->doff << I40E_TX_DESC_LENGTH_L4_FC_LEN_SHIFT;
 		break;
 	case IPPROTO_SCTP:
 		/* enable SCTP checksum offload */
-		*td_cmd |= I40E_TX_DESC_CMD_L4T_EOFT_SCTP;
-		*td_offset |= (sizeof(struct sctphdr) >> 2) <<
-			       I40E_TX_DESC_LENGTH_L4_FC_LEN_SHIFT;
+		cmd |= I40E_TX_DESC_CMD_L4T_EOFT_SCTP;
+		offset |= (sizeof(struct sctphdr) >> 2) <<
+			  I40E_TX_DESC_LENGTH_L4_FC_LEN_SHIFT;
 		break;
 	case IPPROTO_UDP:
 		/* enable UDP checksum offload */
-		*td_cmd |= I40E_TX_DESC_CMD_L4T_EOFT_UDP;
-		*td_offset |= (sizeof(struct udphdr) >> 2) <<
-			       I40E_TX_DESC_LENGTH_L4_FC_LEN_SHIFT;
+		cmd |= I40E_TX_DESC_CMD_L4T_EOFT_UDP;
+		offset |= (sizeof(struct udphdr) >> 2) <<
+			  I40E_TX_DESC_LENGTH_L4_FC_LEN_SHIFT;
 		break;
 	default:
-		break;
+		if (*tx_flags & I40E_TX_FLAGS_TSO)
+			return -1;
+		skb_checksum_help(skb);
+		return 0;
 	}
+
+	*td_cmd |= cmd;
+	*td_offset |= offset;
+
+	return 1;
 }
 
 /**
@@ -2456,7 +2577,7 @@ static void i40e_create_tx_ctx(struct i4
  *
  * Returns -EBUSY if a stop is needed, else 0
  **/
-static inline int __i40e_maybe_stop_tx(struct i40e_ring *tx_ring, int size)
+int __i40e_maybe_stop_tx(struct i40e_ring *tx_ring, int size)
 {
 	netif_stop_subqueue(tx_ring->netdev, tx_ring->queue_index);
 	/* Memory barrier before checking head and tail */
@@ -2473,77 +2594,71 @@ static inline int __i40e_maybe_stop_tx(s
 }
 
 /**
- * i40e_maybe_stop_tx - 1st level check for tx stop conditions
- * @tx_ring: the ring to be checked
- * @size:    the size buffer we want to assure is available
- *
- * Returns 0 if stop is not needed
- **/
-#ifdef I40E_FCOE
-inline int i40e_maybe_stop_tx(struct i40e_ring *tx_ring, int size)
-#else
-static inline int i40e_maybe_stop_tx(struct i40e_ring *tx_ring, int size)
-#endif
-{
-	if (likely(I40E_DESC_UNUSED(tx_ring) >= size))
-		return 0;
-	return __i40e_maybe_stop_tx(tx_ring, size);
-}
-
-/**
- * i40e_chk_linearize - Check if there are more than 8 fragments per packet
+ * __i40e_chk_linearize - Check if there are more than 8 fragments per packet
  * @skb:      send buffer
- * @tx_flags: collected send information
  *
  * Note: Our HW can't scatter-gather more than 8 fragments to build
  * a packet on the wire and so we need to figure out the cases where we
  * need to linearize the skb.
  **/
-static bool i40e_chk_linearize(struct sk_buff *skb, u32 tx_flags)
+bool __i40e_chk_linearize(struct sk_buff *skb)
 {
-	struct skb_frag_struct *frag;
-	bool linearize = false;
-	unsigned int size = 0;
-	u16 num_frags;
-	u16 gso_segs;
+	const struct skb_frag_struct *frag, *stale;
+	int gso_size, nr_frags, sum;
 
-	num_frags = skb_shinfo(skb)->nr_frags;
-	gso_segs = skb_shinfo(skb)->gso_segs;
+	/* check to see if TSO is enabled, if so we may get a repreive */
+	gso_size = skb_shinfo(skb)->gso_size;
+	if (unlikely(!gso_size))
+		return true;
 
-	if (tx_flags & (I40E_TX_FLAGS_TSO | I40E_TX_FLAGS_FSO)) {
-		u16 j = 0;
+	/* no need to check if number of frags is less than 8 */
+	nr_frags = skb_shinfo(skb)->nr_frags;
+	if (nr_frags < I40E_MAX_BUFFER_TXD)
+		return false;
 
-		if (num_frags < (I40E_MAX_BUFFER_TXD))
-			goto linearize_chk_done;
-		/* try the simple math, if we have too many frags per segment */
-		if (DIV_ROUND_UP((num_frags + gso_segs), gso_segs) >
-		    I40E_MAX_BUFFER_TXD) {
-			linearize = true;
-			goto linearize_chk_done;
-		}
-		frag = &skb_shinfo(skb)->frags[0];
-		/* we might still have more fragments per segment */
-		do {
-			size += skb_frag_size(frag);
-			frag++; j++;
-			if ((size >= skb_shinfo(skb)->gso_size) &&
-			    (j < I40E_MAX_BUFFER_TXD)) {
-				size = (size % skb_shinfo(skb)->gso_size);
-				j = (size) ? 1 : 0;
-			}
-			if (j == I40E_MAX_BUFFER_TXD) {
-				linearize = true;
-				break;
-			}
-			num_frags--;
-		} while (num_frags);
-	} else {
-		if (num_frags >= I40E_MAX_BUFFER_TXD)
-			linearize = true;
+	/* We need to walk through the list and validate that each group
+	 * of 6 fragments totals at least gso_size.  However we don't need
+	 * to perform such validation on the first or last 6 since the first
+	 * 6 cannot inherit any data from a descriptor before them, and the
+	 * last 6 cannot inherit any data from a descriptor after them.
+	 */
+	nr_frags -= I40E_MAX_BUFFER_TXD - 1;
+	frag = &skb_shinfo(skb)->frags[0];
+
+	/* Initialize size to the negative value of gso_size minus 1.  We
+	 * use this as the worst case scenerio in which the frag ahead
+	 * of us only provides one byte which is why we are limited to 6
+	 * descriptors for a single transmit as the header and previous
+	 * fragment are already consuming 2 descriptors.
+	 */
+	sum = 1 - gso_size;
+
+	/* Add size of frags 1 through 5 to create our initial sum */
+	sum += skb_frag_size(++frag);
+	sum += skb_frag_size(++frag);
+	sum += skb_frag_size(++frag);
+	sum += skb_frag_size(++frag);
+	sum += skb_frag_size(++frag);
+
+	/* Walk through fragments adding latest fragment, testing it, and
+	 * then removing stale fragments from the sum.
+	 */
+	stale = &skb_shinfo(skb)->frags[0];
+	for (;;) {
+		sum += skb_frag_size(++frag);
+
+		/* if sum is negative we failed to make sufficient progress */
+		if (sum < 0)
+			return true;
+
+		/* use pre-decrement to avoid processing last fragment */
+		if (!--nr_frags)
+			break;
+
+		sum -= skb_frag_size(++stale);
 	}
 
-linearize_chk_done:
-	return linearize;
+	return false;
 }
 
 /**
@@ -2750,43 +2865,6 @@ dma_error:
 }
 
 /**
- * i40e_xmit_descriptor_count - calculate number of tx descriptors needed
- * @skb:     send buffer
- * @tx_ring: ring to send buffer on
- *
- * Returns number of data descriptors needed for this skb. Returns 0 to indicate
- * there is not enough descriptors available in this ring since we need at least
- * one descriptor.
- **/
-#ifdef I40E_FCOE
-inline int i40e_xmit_descriptor_count(struct sk_buff *skb,
-				      struct i40e_ring *tx_ring)
-#else
-static inline int i40e_xmit_descriptor_count(struct sk_buff *skb,
-					     struct i40e_ring *tx_ring)
-#endif
-{
-	unsigned int f;
-	int count = 0;
-
-	/* need: 1 descriptor per page * PAGE_SIZE/I40E_MAX_DATA_PER_TXD,
-	 *       + 1 desc for skb_head_len/I40E_MAX_DATA_PER_TXD,
-	 *       + 4 desc gap to avoid the cache line where head is,
-	 *       + 1 desc for context descriptor,
-	 * otherwise try next time
-	 */
-	for (f = 0; f < skb_shinfo(skb)->nr_frags; f++)
-		count += TXD_USE_COUNT(skb_shinfo(skb)->frags[f].size);
-
-	count += TXD_USE_COUNT(skb_headlen(skb));
-	if (i40e_maybe_stop_tx(tx_ring, count + 4 + 1)) {
-		tx_ring->tx_stats.tx_busy++;
-		return 0;
-	}
-	return count;
-}
-
-/**
  * i40e_xmit_frame_ring - Sends buffer on Tx ring
  * @skb:     send buffer
  * @tx_ring: ring to send buffer on
@@ -2804,11 +2882,30 @@ static netdev_tx_t i40e_xmit_frame_ring(
 	__be16 protocol;
 	u32 td_cmd = 0;
 	u8 hdr_len = 0;
+	int tso, count;
 	int tsyn;
-	int tso;
 
-	if (0 == i40e_xmit_descriptor_count(skb, tx_ring))
+	/* prefetch the data, we'll need it later */
+	prefetch(skb->data);
+
+	count = i40e_xmit_descriptor_count(skb);
+	if (i40e_chk_linearize(skb, count)) {
+		if (__skb_linearize(skb))
+			goto out_drop;
+		count = TXD_USE_COUNT(skb->len);
+		tx_ring->tx_stats.tx_linearize++;
+	}
+
+	/* need: 1 descriptor per page * PAGE_SIZE/I40E_MAX_DATA_PER_TXD,
+	 *       + 1 desc for skb_head_len/I40E_MAX_DATA_PER_TXD,
+	 *       + 4 desc gap to avoid the cache line where head is,
+	 *       + 1 desc for context descriptor,
+	 * otherwise try next time
+	 */
+	if (i40e_maybe_stop_tx(tx_ring, count + 4 + 1)) {
+		tx_ring->tx_stats.tx_busy++;
 		return NETDEV_TX_BUSY;
+	}
 
 	/* prepare the xmit flags */
 	if (i40e_tx_prepare_vlan_flags(skb, tx_ring, &tx_flags))
@@ -2826,37 +2923,29 @@ static netdev_tx_t i40e_xmit_frame_ring(
 	else if (protocol == htons(ETH_P_IPV6))
 		tx_flags |= I40E_TX_FLAGS_IPV6;
 
-	tso = i40e_tso(tx_ring, skb, &hdr_len,
-		       &cd_type_cmd_tso_mss, &cd_tunneling);
+	tso = i40e_tso(tx_ring, skb, &hdr_len, &cd_type_cmd_tso_mss);
 
 	if (tso < 0)
 		goto out_drop;
 	else if (tso)
 		tx_flags |= I40E_TX_FLAGS_TSO;
 
+	/* Always offload the checksum, since it's in the data descriptor */
+	tso = i40e_tx_enable_csum(skb, &tx_flags, &td_cmd, &td_offset,
+				  tx_ring, &cd_tunneling);
+	if (tso < 0)
+		goto out_drop;
+
 	tsyn = i40e_tsyn(tx_ring, skb, tx_flags, &cd_type_cmd_tso_mss);
 
 	if (tsyn)
 		tx_flags |= I40E_TX_FLAGS_TSYN;
 
-	if (i40e_chk_linearize(skb, tx_flags)) {
-		if (skb_linearize(skb))
-			goto out_drop;
-		tx_ring->tx_stats.tx_linearize++;
-	}
 	skb_tx_timestamp(skb);
 
 	/* always enable CRC insertion offload */
 	td_cmd |= I40E_TX_DESC_CMD_ICRC;
 
-	/* Always offload the checksum, since it's in the data descriptor */
-	if (skb->ip_summed == CHECKSUM_PARTIAL) {
-		tx_flags |= I40E_TX_FLAGS_CSUM;
-
-		i40e_tx_enable_csum(skb, &tx_flags, &td_cmd, &td_offset,
-				    tx_ring, &cd_tunneling);
-	}
-
 	i40e_create_tx_ctx(tx_ring, cd_type_cmd_tso_mss,
 			   cd_tunneling, cd_l2tag2);
 
@@ -2864,7 +2953,7 @@ static netdev_tx_t i40e_xmit_frame_ring(
 	 *
 	 * NOTE: this must always be directly before the data descriptor.
 	 */
-	i40e_atr(tx_ring, skb, tx_flags, protocol);
+	i40e_atr(tx_ring, skb, tx_flags);
 
 	i40e_tx_map(tx_ring, skb, first, tx_flags, hdr_len,
 		    td_cmd, td_offset);
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/intel/i40e/i40e_txrx.h
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/intel/i40e/i40e_txrx.h
@@ -1,7 +1,7 @@
 /*******************************************************************************
  *
  * Intel Ethernet Controller XL710 Family Linux Driver
- * Copyright(c) 2013 - 2014 Intel Corporation.
+ * Copyright(c) 2013 - 2016 Intel Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms and conditions of the GNU General Public License,
@@ -153,7 +153,6 @@ enum i40e_dyn_idx_t {
 #define DESC_NEEDED (MAX_SKB_FRAGS + 4)
 #define I40E_MIN_DESC_PENDING	4
 
-#define I40E_TX_FLAGS_CSUM		BIT(0)
 #define I40E_TX_FLAGS_HW_VLAN		BIT(1)
 #define I40E_TX_FLAGS_SW_VLAN		BIT(2)
 #define I40E_TX_FLAGS_TSO		BIT(3)
@@ -163,7 +162,7 @@ enum i40e_dyn_idx_t {
 #define I40E_TX_FLAGS_FSO		BIT(7)
 #define I40E_TX_FLAGS_TSYN		BIT(8)
 #define I40E_TX_FLAGS_FD_SB		BIT(9)
-#define I40E_TX_FLAGS_VXLAN_TUNNEL	BIT(10)
+#define I40E_TX_FLAGS_UDP_TUNNEL	BIT(10)
 #define I40E_TX_FLAGS_VLAN_MASK		0xffff0000
 #define I40E_TX_FLAGS_VLAN_PRIO_MASK	0xe0000000
 #define I40E_TX_FLAGS_VLAN_PRIO_SHIFT	29
@@ -202,12 +201,16 @@ struct i40e_tx_queue_stats {
 	u64 tx_busy;
 	u64 tx_done_old;
 	u64 tx_linearize;
+	u64 tx_force_wb;
+	u64 tx_lost_interrupt;
 };
 
 struct i40e_rx_queue_stats {
 	u64 non_eop_descs;
 	u64 alloc_page_failed;
 	u64 alloc_buff_failed;
+	u64 page_reuse_count;
+	u64 realloc_count;
 };
 
 enum i40e_ring_state_t {
@@ -253,7 +256,6 @@ struct i40e_ring {
 #define I40E_RX_DTYPE_NO_SPLIT      0
 #define I40E_RX_DTYPE_HEADER_SPLIT  1
 #define I40E_RX_DTYPE_SPLIT_ALWAYS  2
-	u8  hsplit;
 #define I40E_RX_SPLIT_L2      0x1
 #define I40E_RX_SPLIT_IP      0x2
 #define I40E_RX_SPLIT_TCP_UDP 0x4
@@ -274,7 +276,6 @@ struct i40e_ring {
 
 	u16 flags;
 #define I40E_TXR_FLAGS_WB_ON_ITR	BIT(0)
-#define I40E_TXR_FLAGS_OUTER_UDP_CSUM	BIT(1)
 #define I40E_TXR_FLAGS_LAST_XMIT_MORE_SET BIT(2)
 
 	/* stats structs */
@@ -315,8 +316,8 @@ struct i40e_ring_container {
 #define i40e_for_each_ring(pos, head) \
 	for (pos = (head).ring; pos != NULL; pos = pos->next)
 
-void i40e_alloc_rx_buffers_ps(struct i40e_ring *rxr, u16 cleaned_count);
-void i40e_alloc_rx_buffers_1buf(struct i40e_ring *rxr, u16 cleaned_count);
+bool i40e_alloc_rx_buffers_ps(struct i40e_ring *rxr, u16 cleaned_count);
+bool i40e_alloc_rx_buffers_1buf(struct i40e_ring *rxr, u16 cleaned_count);
 void i40e_alloc_rx_headers(struct i40e_ring *rxr);
 netdev_tx_t i40e_lan_xmit_frame(struct sk_buff *skb, struct net_device *netdev);
 void i40e_clean_tx_ring(struct i40e_ring *tx_ring);
@@ -330,13 +331,13 @@ int i40e_napi_poll(struct napi_struct *n
 void i40e_tx_map(struct i40e_ring *tx_ring, struct sk_buff *skb,
 		 struct i40e_tx_buffer *first, u32 tx_flags,
 		 const u8 hdr_len, u32 td_cmd, u32 td_offset);
-int i40e_maybe_stop_tx(struct i40e_ring *tx_ring, int size);
-int i40e_xmit_descriptor_count(struct sk_buff *skb, struct i40e_ring *tx_ring);
 int i40e_tx_prepare_vlan_flags(struct sk_buff *skb,
 			       struct i40e_ring *tx_ring, u32 *flags);
 #endif
 void i40e_force_wb(struct i40e_vsi *vsi, struct i40e_q_vector *q_vector);
-u32 i40e_get_tx_pending(struct i40e_ring *ring);
+u32 i40e_get_tx_pending(struct i40e_ring *ring, bool in_sw);
+int __i40e_maybe_stop_tx(struct i40e_ring *tx_ring, int size);
+bool __i40e_chk_linearize(struct sk_buff *skb);
 
 /**
  * i40e_get_head - Retrieve head from head writeback
@@ -351,4 +352,63 @@ static inline u32 i40e_get_head(struct i
 
 	return le32_to_cpu(*(volatile __le32 *)head);
 }
+
+/**
+ * i40e_xmit_descriptor_count - calculate number of Tx descriptors needed
+ * @skb:     send buffer
+ * @tx_ring: ring to send buffer on
+ *
+ * Returns number of data descriptors needed for this skb. Returns 0 to indicate
+ * there is not enough descriptors available in this ring since we need at least
+ * one descriptor.
+ **/
+static inline int i40e_xmit_descriptor_count(struct sk_buff *skb)
+{
+	const struct skb_frag_struct *frag = &skb_shinfo(skb)->frags[0];
+	unsigned int nr_frags = skb_shinfo(skb)->nr_frags;
+	int count = 0, size = skb_headlen(skb);
+
+	for (;;) {
+		count += TXD_USE_COUNT(size);
+
+		if (!nr_frags--)
+			break;
+
+		size = skb_frag_size(frag++);
+	}
+
+	return count;
+}
+
+/**
+ * i40e_maybe_stop_tx - 1st level check for Tx stop conditions
+ * @tx_ring: the ring to be checked
+ * @size:    the size buffer we want to assure is available
+ *
+ * Returns 0 if stop is not needed
+ **/
+static inline int i40e_maybe_stop_tx(struct i40e_ring *tx_ring, int size)
+{
+	if (likely(I40E_DESC_UNUSED(tx_ring) >= size))
+		return 0;
+	return __i40e_maybe_stop_tx(tx_ring, size);
+}
+
+/**
+ * i40e_chk_linearize - Check if there are more than 8 fragments per packet
+ * @skb:      send buffer
+ * @count:    number of buffers used
+ *
+ * Note: Our HW can't scatter-gather more than 8 fragments to build
+ * a packet on the wire and so we need to figure out the cases where we
+ * need to linearize the skb.
+ **/
+static inline bool i40e_chk_linearize(struct sk_buff *skb, int count)
+{
+	/* we can only support up to 8 data buffers for a single send */
+	if (likely(count <= I40E_MAX_BUFFER_TXD))
+		return false;
+
+	return __i40e_chk_linearize(skb);
+}
 #endif /* _I40E_TXRX_H_ */
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/intel/i40e/i40e_type.h
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/intel/i40e/i40e_type.h
@@ -90,6 +90,22 @@ enum i40e_debug_mask {
 	I40E_DEBUG_ALL			= 0xFFFFFFFF
 };
 
+#define I40E_MDIO_STCODE                0
+#define I40E_MDIO_OPCODE_ADDRESS        0
+#define I40E_MDIO_OPCODE_WRITE          I40E_MASK(1, \
+						  I40E_GLGEN_MSCA_OPCODE_SHIFT)
+#define I40E_MDIO_OPCODE_READ_INC_ADDR  I40E_MASK(2, \
+						  I40E_GLGEN_MSCA_OPCODE_SHIFT)
+#define I40E_MDIO_OPCODE_READ           I40E_MASK(3, \
+						  I40E_GLGEN_MSCA_OPCODE_SHIFT)
+
+#define I40E_PHY_COM_REG_PAGE                   0x1E
+#define I40E_PHY_LED_LINK_MODE_MASK             0xF0
+#define I40E_PHY_LED_MANUAL_ON                  0x100
+#define I40E_PHY_LED_PROV_REG_1                 0xC430
+#define I40E_PHY_LED_MODE_MASK                  0xFFFF
+#define I40E_PHY_LED_MODE_ORIG                  0x80000000
+
 /* These are structs for managing the hardware information and the operations.
  * The structures of function pointers are filled out at init time when we
  * know for sure exactly which hardware we're working with.  This gives us the
@@ -1096,6 +1112,10 @@ enum i40e_filter_program_desc_pcmd {
 
 #define I40E_TXD_FLTR_QW1_ATR_SHIFT	(0xEULL + \
 					 I40E_TXD_FLTR_QW1_CMD_SHIFT)
+#define I40E_TXD_FLTR_QW1_ATR_MASK	BIT_ULL(I40E_TXD_FLTR_QW1_ATR_SHIFT)
+
+#define I40E_TXD_FLTR_QW1_ATR_SHIFT	(0xEULL + \
+					 I40E_TXD_FLTR_QW1_CMD_SHIFT)
 #define I40E_TXD_FLTR_QW1_ATR_MASK	BIT_ULL(I40E_TXD_FLTR_QW1_ATR_SHIFT)
 
 #define I40E_TXD_FLTR_QW1_CNTINDEX_SHIFT 20
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/intel/i40e/i40e_virtchnl.h
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/intel/i40e/i40e_virtchnl.h
@@ -153,6 +153,7 @@ struct i40e_virtchnl_vsi_resource {
 #define I40E_VIRTCHNL_VF_OFFLOAD_WB_ON_ITR	0x00000020
 #define I40E_VIRTCHNL_VF_OFFLOAD_VLAN		0x00010000
 #define I40E_VIRTCHNL_VF_OFFLOAD_RX_POLLING	0x00020000
+#define I40E_VIRTCHNL_VF_OFFLOAD_RSS_PCTYPE_V2	0x00040000
 
 struct i40e_virtchnl_vf_resource {
 	u16 num_vsis;
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
@@ -1,7 +1,7 @@
 /*******************************************************************************
  *
  * Intel Ethernet Controller XL710 Family Linux Driver
- * Copyright(c) 2013 - 2015 Intel Corporation.
+ * Copyright(c) 2013 - 2016 Intel Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms and conditions of the GNU General Public License,
@@ -290,8 +290,8 @@ static void i40e_config_irq_link_list(st
 	next_q = find_first_bit(&linklistmap,
 				(I40E_MAX_VSI_QP *
 				 I40E_VIRTCHNL_SUPPORTED_QTYPES));
-	vsi_queue_id = next_q/I40E_VIRTCHNL_SUPPORTED_QTYPES;
-	qtype = next_q%I40E_VIRTCHNL_SUPPORTED_QTYPES;
+	vsi_queue_id = next_q / I40E_VIRTCHNL_SUPPORTED_QTYPES;
+	qtype = next_q % I40E_VIRTCHNL_SUPPORTED_QTYPES;
 	pf_queue_id = i40e_vc_get_pf_queue_id(vf, vsi_id, vsi_queue_id);
 	reg = ((qtype << I40E_VPINT_LNKLSTN_FIRSTQ_TYPE_SHIFT) | pf_queue_id);
 
@@ -461,7 +461,7 @@ static int i40e_config_vsi_rx_queue(stru
 		rx_ctx.hbuff = info->hdr_size >> I40E_RXQ_CTX_HBUFF_SHIFT;
 
 		/* set splitalways mode 10b */
-		rx_ctx.dtype = 0x2;
+		rx_ctx.dtype = I40E_RX_DTYPE_HEADER_SPLIT;
 	}
 
 	/* databuffer length validation */
@@ -549,12 +549,15 @@ static int i40e_alloc_vsi_res(struct i40
 			i40e_vsi_add_pvid(vsi, vf->port_vlan_id);
 
 		spin_lock_bh(&vsi->mac_filter_list_lock);
-		f = i40e_add_filter(vsi, vf->default_lan_addr.addr,
-				    vf->port_vlan_id ? vf->port_vlan_id : -1,
-				    true, false);
-		if (!f)
-			dev_info(&pf->pdev->dev,
-				 "Could not allocate VF MAC addr\n");
+		if (is_valid_ether_addr(vf->default_lan_addr.addr)) {
+			f = i40e_add_filter(vsi, vf->default_lan_addr.addr,
+				       vf->port_vlan_id ? vf->port_vlan_id : -1,
+				       true, false);
+			if (!f)
+				dev_info(&pf->pdev->dev,
+					 "Could not add MAC filter %pM for VF %d\n",
+					vf->default_lan_addr.addr, vf->vf_id);
+		}
 		f = i40e_add_filter(vsi, brdcast,
 				    vf->port_vlan_id ? vf->port_vlan_id : -1,
 				    true, false);
@@ -565,7 +568,7 @@ static int i40e_alloc_vsi_res(struct i40
 	}
 
 	/* program mac filter */
-	ret = i40e_sync_vsi_filters(vsi, false);
+	ret = i40e_sync_vsi_filters(vsi);
 	if (ret)
 		dev_err(&pf->pdev->dev, "Unable to program ucast filters\n");
 
@@ -599,8 +602,8 @@ static void i40e_enable_vf_mappings(stru
 	 * that VF queues be mapped using this method, even when they are
 	 * contiguous in real life
 	 */
-	wr32(hw, I40E_VSILAN_QBASE(vf->lan_vsi_id),
-	     I40E_VSILAN_QBASE_VSIQTABLE_ENA_MASK);
+	i40e_write_rx_ctl(hw, I40E_VSILAN_QBASE(vf->lan_vsi_id),
+			  I40E_VSILAN_QBASE_VSIQTABLE_ENA_MASK);
 
 	/* enable VF vplan_qtable mappings */
 	reg = I40E_VPLAN_MAPENA_TXRX_ENA_MASK;
@@ -627,7 +630,8 @@ static void i40e_enable_vf_mappings(stru
 						      (j * 2) + 1);
 			reg |= qid << 16;
 		}
-		wr32(hw, I40E_VSILAN_QTABLE(j, vf->lan_vsi_id), reg);
+		i40e_write_rx_ctl(hw, I40E_VSILAN_QTABLE(j, vf->lan_vsi_id),
+				  reg);
 	}
 
 	i40e_flush(hw);
@@ -977,7 +981,7 @@ err_alloc:
 		i40e_free_vfs(pf);
 err_iov:
 	/* Re-enable interrupt 0. */
-	i40e_irq_dynamic_enable_icr0(pf);
+	i40e_irq_dynamic_enable_icr0(pf, false);
 	return ret;
 }
 
@@ -1094,8 +1098,8 @@ static int i40e_vc_send_msg_to_vf(struct
 	/* single place to detect unsuccessful return values */
 	if (v_retval) {
 		vf->num_invalid_msgs++;
-		dev_err(&pf->pdev->dev, "Failed opcode %d Error: %d\n",
-			v_opcode, v_retval);
+		dev_err(&pf->pdev->dev, "VF %d failed opcode %d, error: %d\n",
+			vf->vf_id, v_opcode, v_retval);
 		if (vf->num_invalid_msgs >
 		    I40E_DEFAULT_NUM_INVALID_MSGS_ALLOWED) {
 			dev_err(&pf->pdev->dev,
@@ -1210,9 +1214,21 @@ static int i40e_vc_get_vf_resources_msg(
 		vfres->vf_offload_flags |= I40E_VIRTCHNL_VF_OFFLOAD_RSS_REG;
 	}
 
+	if (pf->flags & I40E_FLAG_MULTIPLE_TCP_UDP_RSS_PCTYPE) {
+		if (vf->driver_caps & I40E_VIRTCHNL_VF_OFFLOAD_RSS_PCTYPE_V2)
+			vfres->vf_offload_flags |=
+				I40E_VIRTCHNL_VF_OFFLOAD_RSS_PCTYPE_V2;
+	}
+
 	if (vf->driver_caps & I40E_VIRTCHNL_VF_OFFLOAD_RX_POLLING)
 		vfres->vf_offload_flags |= I40E_VIRTCHNL_VF_OFFLOAD_RX_POLLING;
 
+	if (pf->flags & I40E_FLAG_WB_ON_ITR_CAPABLE) {
+		if (vf->driver_caps & I40E_VIRTCHNL_VF_OFFLOAD_WB_ON_ITR)
+			vfres->vf_offload_flags |=
+					I40E_VIRTCHNL_VF_OFFLOAD_WB_ON_ITR;
+	}
+
 	vfres->num_vsis = num_vsis;
 	vfres->num_queue_pairs = vf->num_queue_pairs;
 	vfres->max_vectors = pf->hw.func_caps.num_msix_vectors_vf;
@@ -1623,7 +1639,8 @@ static int i40e_vc_add_mac_addr_msg(stru
 
 		if (!f) {
 			dev_err(&pf->pdev->dev,
-				"Unable to add VF MAC filter\n");
+				"Unable to add MAC filter %pM for VF %d\n",
+				 al->list[i].addr, vf->vf_id);
 			ret = I40E_ERR_PARAM;
 			spin_unlock_bh(&vsi->mac_filter_list_lock);
 			goto error_param;
@@ -1632,8 +1649,10 @@ static int i40e_vc_add_mac_addr_msg(stru
 	spin_unlock_bh(&vsi->mac_filter_list_lock);
 
 	/* program the updated filter list */
-	if (i40e_sync_vsi_filters(vsi, false))
-		dev_err(&pf->pdev->dev, "Unable to program VF MAC filters\n");
+	ret = i40e_sync_vsi_filters(vsi);
+	if (ret)
+		dev_err(&pf->pdev->dev, "Unable to program VF %d MAC filters, error %d\n",
+			vf->vf_id, ret);
 
 error_param:
 	/* send the response to the VF */
@@ -1669,8 +1688,8 @@ static int i40e_vc_del_mac_addr_msg(stru
 	for (i = 0; i < al->num_elements; i++) {
 		if (is_broadcast_ether_addr(al->list[i].addr) ||
 		    is_zero_ether_addr(al->list[i].addr)) {
-			dev_err(&pf->pdev->dev, "invalid VF MAC addr %pM\n",
-				al->list[i].addr);
+			dev_err(&pf->pdev->dev, "Invalid MAC addr %pM for VF %d\n",
+				al->list[i].addr, vf->vf_id);
 			ret = I40E_ERR_INVALID_MAC_ADDR;
 			goto error_param;
 		}
@@ -1680,13 +1699,19 @@ static int i40e_vc_del_mac_addr_msg(stru
 	spin_lock_bh(&vsi->mac_filter_list_lock);
 	/* delete addresses from the list */
 	for (i = 0; i < al->num_elements; i++)
-		i40e_del_filter(vsi, al->list[i].addr,
-				I40E_VLAN_ANY, true, false);
+		if (i40e_del_mac_all_vlan(vsi, al->list[i].addr, true, false)) {
+			ret = I40E_ERR_INVALID_MAC_ADDR;
+			spin_unlock_bh(&vsi->mac_filter_list_lock);
+			goto error_param;
+		}
+
 	spin_unlock_bh(&vsi->mac_filter_list_lock);
 
 	/* program the updated filter list */
-	if (i40e_sync_vsi_filters(vsi, false))
-		dev_err(&pf->pdev->dev, "Unable to program VF MAC filters\n");
+	ret = i40e_sync_vsi_filters(vsi);
+	if (ret)
+		dev_err(&pf->pdev->dev, "Unable to program VF %d MAC filters, error %d\n",
+			vf->vf_id, ret);
 
 error_param:
 	/* send the response to the VF */
@@ -1740,8 +1765,8 @@ static int i40e_vc_add_vlan_msg(struct i
 
 		if (ret)
 			dev_err(&pf->pdev->dev,
-				"Unable to add VF vlan filter %d, error %d\n",
-				vfl->vlan_id[i], ret);
+				"Unable to add VLAN filter %d for VF %d, error %d\n",
+				vfl->vlan_id[i], vf->vf_id, ret);
 	}
 
 error_param:
@@ -1792,8 +1817,8 @@ static int i40e_vc_remove_vlan_msg(struc
 
 		if (ret)
 			dev_err(&pf->pdev->dev,
-				"Unable to delete VF vlan filter %d, error %d\n",
-				vfl->vlan_id[i], ret);
+				"Unable to delete VLAN filter %d for VF %d, error %d\n",
+				vfl->vlan_id[i], vf->vf_id, ret);
 	}
 
 error_param:
@@ -2013,7 +2038,11 @@ int i40e_vc_process_vflr_event(struct i4
 	if (!test_bit(__I40E_VFLR_EVENT_PENDING, &pf->state))
 		return 0;
 
-	/* re-enable vflr interrupt cause */
+	/* Re-enable the VFLR interrupt cause here, before looking for which
+	 * VF got reset. Otherwise, if another VF gets a reset while the
+	 * first one is being processed, that interrupt will be lost, and
+	 * that VF will be stuck in reset forever.
+	 */
 	reg = rd32(hw, I40E_PFINT_ICR0_ENA);
 	reg |= I40E_PFINT_ICR0_ENA_VFLR_MASK;
 	wr32(hw, I40E_PFINT_ICR0_ENA, reg);
@@ -2066,15 +2095,15 @@ int i40e_ndo_set_vf_mac(struct net_devic
 	vf = &(pf->vf[vf_id]);
 	vsi = pf->vsi[vf->lan_vsi_idx];
 	if (!test_bit(I40E_VF_STAT_INIT, &vf->vf_states)) {
-		dev_err(&pf->pdev->dev,
-			"Uninitialized VF %d\n", vf_id);
-		ret = -EINVAL;
+		dev_err(&pf->pdev->dev, "VF %d still in reset. Try again.\n",
+			vf_id);
+		ret = -EAGAIN;
 		goto error_param;
 	}
 
-	if (!is_valid_ether_addr(mac)) {
+	if (is_multicast_ether_addr(mac)) {
 		dev_err(&pf->pdev->dev,
-			"Invalid VF ethernet address\n");
+			"Invalid Ethernet address %pM for VF %d\n", mac, vf_id);
 		ret = -EINVAL;
 		goto error_param;
 	}
@@ -2085,9 +2114,10 @@ int i40e_ndo_set_vf_mac(struct net_devic
 	spin_lock_bh(&vsi->mac_filter_list_lock);
 
 	/* delete the temporary mac address */
-	i40e_del_filter(vsi, vf->default_lan_addr.addr,
-			vf->port_vlan_id ? vf->port_vlan_id : -1,
-			true, false);
+	if (!is_zero_ether_addr(vf->default_lan_addr.addr))
+		i40e_del_filter(vsi, vf->default_lan_addr.addr,
+				vf->port_vlan_id ? vf->port_vlan_id : -1,
+				true, false);
 
 	/* Delete all the filters for this VSI - we're going to kill it
 	 * anyway.
@@ -2099,7 +2129,7 @@ int i40e_ndo_set_vf_mac(struct net_devic
 
 	dev_info(&pf->pdev->dev, "Setting MAC %pM on VF %d\n", mac, vf_id);
 	/* program mac filter */
-	if (i40e_sync_vsi_filters(vsi, false)) {
+	if (i40e_sync_vsi_filters(vsi)) {
 		dev_err(&pf->pdev->dev, "Unable to program ucast filters\n");
 		ret = -EIO;
 		goto error_param;
@@ -2150,8 +2180,9 @@ int i40e_ndo_set_vf_port_vlan(struct net
 	vf = &(pf->vf[vf_id]);
 	vsi = pf->vsi[vf->lan_vsi_idx];
 	if (!test_bit(I40E_VF_STAT_INIT, &vf->vf_states)) {
-		dev_err(&pf->pdev->dev, "Uninitialized VF %d\n", vf_id);
-		ret = -EINVAL;
+		dev_err(&pf->pdev->dev, "VF %d still in reset. Try again.\n",
+			vf_id);
+		ret = -EAGAIN;
 		goto error_pvid;
 	}
 
@@ -2172,6 +2203,8 @@ int i40e_ndo_set_vf_port_vlan(struct net
 		 * and then reloading the VF driver.
 		 */
 		i40e_vc_disable_vf(pf, vf);
+		/* During reset the VF got a new VSI, so refresh the pointer. */
+		vsi = pf->vsi[vf->lan_vsi_idx];
 	}
 
 	/* Check for condition where there was already a port VLAN ID
@@ -2270,8 +2303,9 @@ int i40e_ndo_set_vf_bw(struct net_device
 	vf = &(pf->vf[vf_id]);
 	vsi = pf->vsi[vf->lan_vsi_idx];
 	if (!test_bit(I40E_VF_STAT_INIT, &vf->vf_states)) {
-		dev_err(&pf->pdev->dev, "Uninitialized VF %d.\n", vf_id);
-		ret = -EINVAL;
+		dev_err(&pf->pdev->dev, "VF %d still in reset. Try again.\n",
+			vf_id);
+		ret = -EAGAIN;
 		goto error;
 	}
 
@@ -2279,6 +2313,9 @@ int i40e_ndo_set_vf_bw(struct net_device
 	case I40E_LINK_SPEED_40GB:
 		speed = 40000;
 		break;
+	case I40E_LINK_SPEED_20GB:
+		speed = 20000;
+		break;
 	case I40E_LINK_SPEED_10GB:
 		speed = 10000;
 		break;
@@ -2344,8 +2381,9 @@ int i40e_ndo_get_vf_config(struct net_de
 	/* first vsi is always the LAN vsi */
 	vsi = pf->vsi[vf->lan_vsi_idx];
 	if (!test_bit(I40E_VF_STAT_INIT, &vf->vf_states)) {
-		dev_err(&pf->pdev->dev, "Uninitialized VF %d\n", vf_id);
-		ret = -EINVAL;
+		dev_err(&pf->pdev->dev, "VF %d still in reset. Try again.\n",
+			vf_id);
+		ret = -EAGAIN;
 		goto error_param;
 	}
 
@@ -2460,6 +2498,12 @@ int i40e_ndo_set_vf_spoofchk(struct net_
 	}
 
 	vf = &(pf->vf[vf_id]);
+	if (!test_bit(I40E_VF_STAT_INIT, &vf->vf_states)) {
+		dev_err(&pf->pdev->dev, "VF %d still in reset. Try again.\n",
+			vf_id);
+		ret = -EAGAIN;
+		goto out;
+	}
 
 	if (enable == vf->spoofchk)
 		goto out;
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.h
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.h
@@ -91,8 +91,8 @@ struct i40e_vf {
 	 * When assigned, these will be non-zero, because VSI 0 is always
 	 * the main LAN VSI for the PF.
 	 */
-	u8 lan_vsi_idx;	        /* index into PF struct */
-	u8 lan_vsi_id;		/* ID as used by firmware */
+	u16 lan_vsi_idx;	/* index into PF struct */
+	u16 lan_vsi_id;		/* ID as used by firmware */
 
 	u8 num_queue_pairs;	/* num of qps assigned to VF vsis */
 	u64 num_mdd_events;	/* num of mdd events detected */
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/intel/i40evf/i40e_adminq.c
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/intel/i40evf/i40e_adminq.c
@@ -1,7 +1,7 @@
 /*******************************************************************************
  *
  * Intel Ethernet Controller XL710 Family Linux Virtual Function Driver
- * Copyright(c) 2013 - 2014 Intel Corporation.
+ * Copyright(c) 2013 - 2016 Intel Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms and conditions of the GNU General Public License,
@@ -887,6 +887,9 @@ i40e_status i40evf_clean_arq_element(str
 	u16 flags;
 	u16 ntu;
 
+	/* pre-clean the event info */
+	memset(&e->desc, 0, sizeof(e->desc));
+
 	/* take the lock before we start messing with the ring */
 	mutex_lock(&hw->aq.arq_mutex);
 
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/intel/i40evf/i40e_adminq_cmd.h
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/intel/i40evf/i40e_adminq_cmd.h
@@ -1,7 +1,7 @@
 /*******************************************************************************
  *
  * Intel Ethernet Controller XL710 Family Linux Virtual Function Driver
- * Copyright(c) 2013 - 2014 Intel Corporation.
+ * Copyright(c) 2013 - 2016 Intel Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms and conditions of the GNU General Public License,
@@ -34,7 +34,7 @@
  */
 
 #define I40E_FW_API_VERSION_MAJOR	0x0001
-#define I40E_FW_API_VERSION_MINOR	0x0004
+#define I40E_FW_API_VERSION_MINOR	0x0005
 
 struct i40e_aq_desc {
 	__le16 flags;
@@ -145,6 +145,9 @@ enum i40e_admin_queue_opc {
 	i40e_aqc_opc_remove_statistics		= 0x0202,
 	i40e_aqc_opc_set_port_parameters	= 0x0203,
 	i40e_aqc_opc_get_switch_resource_alloc	= 0x0204,
+	i40e_aqc_opc_set_switch_config		= 0x0205,
+	i40e_aqc_opc_rx_ctl_reg_read		= 0x0206,
+	i40e_aqc_opc_rx_ctl_reg_write		= 0x0207,
 
 	i40e_aqc_opc_add_vsi			= 0x0210,
 	i40e_aqc_opc_update_vsi_parameters	= 0x0211,
@@ -220,6 +223,7 @@ enum i40e_admin_queue_opc {
 	i40e_aqc_opc_get_phy_wol_caps		= 0x0621,
 	i40e_aqc_opc_set_phy_debug		= 0x0622,
 	i40e_aqc_opc_upload_ext_phy_fm		= 0x0625,
+	i40e_aqc_opc_run_phy_activity		= 0x0626,
 
 	/* NVM commands */
 	i40e_aqc_opc_nvm_read			= 0x0701,
@@ -227,6 +231,8 @@ enum i40e_admin_queue_opc {
 	i40e_aqc_opc_nvm_update			= 0x0703,
 	i40e_aqc_opc_nvm_config_read		= 0x0704,
 	i40e_aqc_opc_nvm_config_write		= 0x0705,
+	i40e_aqc_opc_oem_post_update		= 0x0720,
+	i40e_aqc_opc_thermal_sensor		= 0x0721,
 
 	/* virtualization commands */
 	i40e_aqc_opc_send_msg_to_pf		= 0x0801,
@@ -398,6 +404,7 @@ struct i40e_aqc_list_capabilities_elemen
 #define I40E_AQ_CAP_ID_OS2BMC_CAP	0x0004
 #define I40E_AQ_CAP_ID_FUNCTIONS_VALID	0x0005
 #define I40E_AQ_CAP_ID_ALTERNATE_RAM	0x0006
+#define I40E_AQ_CAP_ID_WOL_AND_PROXY	0x0008
 #define I40E_AQ_CAP_ID_SRIOV		0x0012
 #define I40E_AQ_CAP_ID_VF		0x0013
 #define I40E_AQ_CAP_ID_VMDQ		0x0014
@@ -418,6 +425,7 @@ struct i40e_aqc_list_capabilities_elemen
 #define I40E_AQ_CAP_ID_LED		0x0061
 #define I40E_AQ_CAP_ID_SDP		0x0062
 #define I40E_AQ_CAP_ID_MDIO		0x0063
+#define I40E_AQ_CAP_ID_WSR_PROT		0x0064
 #define I40E_AQ_CAP_ID_FLEX10		0x00F1
 #define I40E_AQ_CAP_ID_CEM		0x00F2
 
@@ -676,6 +684,31 @@ struct i40e_aqc_switch_resource_alloc_el
 
 I40E_CHECK_STRUCT_LEN(0x10, i40e_aqc_switch_resource_alloc_element_resp);
 
+/* Set Switch Configuration (direct 0x0205) */
+struct i40e_aqc_set_switch_config {
+	__le16	flags;
+#define I40E_AQ_SET_SWITCH_CFG_PROMISC		0x0001
+#define I40E_AQ_SET_SWITCH_CFG_L2_FILTER	0x0002
+	__le16	valid_flags;
+	u8	reserved[12];
+};
+
+I40E_CHECK_CMD_LENGTH(i40e_aqc_set_switch_config);
+
+/* Read Receive control registers  (direct 0x0206)
+ * Write Receive control registers (direct 0x0207)
+ *     used for accessing Rx control registers that can be
+ *     slow and need special handling when under high Rx load
+ */
+struct i40e_aqc_rx_ctl_reg_read_write {
+	__le32 reserved1;
+	__le32 address;
+	__le32 reserved2;
+	__le32 value;
+};
+
+I40E_CHECK_CMD_LENGTH(i40e_aqc_rx_ctl_reg_read_write);
+
 /* Add VSI (indirect 0x0210)
  *    this indirect command uses struct i40e_aqc_vsi_properties_data
  *    as the indirect buffer (128 bytes)
@@ -902,7 +935,8 @@ struct i40e_aqc_add_veb {
 					I40E_AQC_ADD_VEB_PORT_TYPE_SHIFT)
 #define I40E_AQC_ADD_VEB_PORT_TYPE_DEFAULT	0x2
 #define I40E_AQC_ADD_VEB_PORT_TYPE_DATA		0x4
-#define I40E_AQC_ADD_VEB_ENABLE_L2_FILTER	0x8
+#define I40E_AQC_ADD_VEB_ENABLE_L2_FILTER	0x8     /* deprecated */
+#define I40E_AQC_ADD_VEB_ENABLE_DISABLE_STATS	0x10
 	u8	enable_tcs;
 	u8	reserved[9];
 };
@@ -969,6 +1003,7 @@ struct i40e_aqc_add_macvlan_element_data
 #define I40E_AQC_MACVLAN_ADD_HASH_MATCH		0x0002
 #define I40E_AQC_MACVLAN_ADD_IGNORE_VLAN	0x0004
 #define I40E_AQC_MACVLAN_ADD_TO_QUEUE		0x0008
+#define I40E_AQC_MACVLAN_ADD_USE_SHARED_MAC	0x0010
 	__le16	queue_number;
 #define I40E_AQC_MACVLAN_CMD_QUEUE_SHIFT	0
 #define I40E_AQC_MACVLAN_CMD_QUEUE_MASK		(0x7FF << \
@@ -1065,6 +1100,7 @@ struct i40e_aqc_set_vsi_promiscuous_mode
 #define I40E_AQC_SET_VSI_PROMISC_BROADCAST	0x04
 #define I40E_AQC_SET_VSI_DEFAULT		0x08
 #define I40E_AQC_SET_VSI_PROMISC_VLAN		0x10
+#define I40E_AQC_SET_VSI_PROMISC_TX		0x8000
 	__le16	seid;
 #define I40E_AQC_VSI_PROM_CMD_SEID_MASK		0x3FF
 	__le16	vlan_tag;
@@ -1253,10 +1289,16 @@ struct i40e_aqc_add_remove_cloud_filters
 
 #define I40E_AQC_ADD_CLOUD_TNL_TYPE_SHIFT		9
 #define I40E_AQC_ADD_CLOUD_TNL_TYPE_MASK		0x1E00
-#define I40E_AQC_ADD_CLOUD_TNL_TYPE_XVLAN		0
+#define I40E_AQC_ADD_CLOUD_TNL_TYPE_VXLAN		0
 #define I40E_AQC_ADD_CLOUD_TNL_TYPE_NVGRE_OMAC		1
-#define I40E_AQC_ADD_CLOUD_TNL_TYPE_NGE			2
+#define I40E_AQC_ADD_CLOUD_TNL_TYPE_GENEVE		2
 #define I40E_AQC_ADD_CLOUD_TNL_TYPE_IP			3
+#define I40E_AQC_ADD_CLOUD_TNL_TYPE_RESERVED		4
+#define I40E_AQC_ADD_CLOUD_TNL_TYPE_VXLAN_GPE		5
+
+#define I40E_AQC_ADD_CLOUD_FLAGS_SHARED_OUTER_MAC	0x2000
+#define I40E_AQC_ADD_CLOUD_FLAGS_SHARED_INNER_MAC	0x4000
+#define I40E_AQC_ADD_CLOUD_FLAGS_SHARED_OUTER_IP	0x8000
 
 	__le32	tenant_id;
 	u8	reserved[4];
@@ -1751,7 +1793,12 @@ struct i40e_aqc_get_link_status {
 	u8	config;
 #define I40E_AQ_CONFIG_CRC_ENA		0x04
 #define I40E_AQ_CONFIG_PACING_MASK	0x78
-	u8	reserved[5];
+	u8	external_power_ability;
+#define I40E_AQ_LINK_POWER_CLASS_1	0x00
+#define I40E_AQ_LINK_POWER_CLASS_2	0x01
+#define I40E_AQ_LINK_POWER_CLASS_3	0x02
+#define I40E_AQ_LINK_POWER_CLASS_4	0x03
+	u8	reserved[4];
 };
 
 I40E_CHECK_CMD_LENGTH(i40e_aqc_get_link_status);
@@ -1819,6 +1866,18 @@ enum i40e_aq_phy_reg_type {
 	I40E_AQC_PHY_REG_EXERNAL_MODULE	= 0x3
 };
 
+/* Run PHY Activity (0x0626) */
+struct i40e_aqc_run_phy_activity {
+	__le16  activity_id;
+	u8      flags;
+	u8      reserved1;
+	__le32  control;
+	__le32  data;
+	u8      reserved2[4];
+};
+
+I40E_CHECK_CMD_LENGTH(i40e_aqc_run_phy_activity);
+
 /* NVM Read command (indirect 0x0701)
  * NVM Erase commands (direct 0x0702)
  * NVM Update commands (indirect 0x0703)
@@ -1888,6 +1947,42 @@ struct i40e_aqc_nvm_config_data_immediat
 
 I40E_CHECK_STRUCT_LEN(0xc, i40e_aqc_nvm_config_data_immediate_field);
 
+/* OEM Post Update (indirect 0x0720)
+ * no command data struct used
+ */
+ struct i40e_aqc_nvm_oem_post_update {
+#define I40E_AQ_NVM_OEM_POST_UPDATE_EXTERNAL_DATA	0x01
+	u8 sel_data;
+	u8 reserved[7];
+};
+
+I40E_CHECK_STRUCT_LEN(0x8, i40e_aqc_nvm_oem_post_update);
+
+struct i40e_aqc_nvm_oem_post_update_buffer {
+	u8 str_len;
+	u8 dev_addr;
+	__le16 eeprom_addr;
+	u8 data[36];
+};
+
+I40E_CHECK_STRUCT_LEN(0x28, i40e_aqc_nvm_oem_post_update_buffer);
+
+/* Thermal Sensor (indirect 0x0721)
+ *     read or set thermal sensor configs and values
+ *     takes a sensor and command specific data buffer, not detailed here
+ */
+struct i40e_aqc_thermal_sensor {
+	u8 sensor_action;
+#define I40E_AQ_THERMAL_SENSOR_READ_CONFIG	0
+#define I40E_AQ_THERMAL_SENSOR_SET_CONFIG	1
+#define I40E_AQ_THERMAL_SENSOR_READ_TEMP	2
+	u8 reserved[7];
+	__le32	addr_high;
+	__le32	addr_low;
+};
+
+I40E_CHECK_CMD_LENGTH(i40e_aqc_thermal_sensor);
+
 /* Send to PF command (indirect 0x0801) id is only used by PF
  * Send to VF command (indirect 0x0802) id is only used by PF
  * Send to Peer PF command (indirect 0x0803)
@@ -2062,6 +2157,7 @@ struct i40e_aqc_add_udp_tunnel {
 #define I40E_AQC_TUNNEL_TYPE_VXLAN	0x00
 #define I40E_AQC_TUNNEL_TYPE_NGE	0x01
 #define I40E_AQC_TUNNEL_TYPE_TEREDO	0x10
+#define I40E_AQC_TUNNEL_TYPE_VXLAN_GPE	0x11
 	u8	reserved1[10];
 };
 
@@ -2311,4 +2407,4 @@ struct i40e_aqc_debug_modify_internals {
 
 I40E_CHECK_CMD_LENGTH(i40e_aqc_debug_modify_internals);
 
-#endif
+#endif /* _I40E_ADMINQ_CMD_H_ */
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/intel/i40evf/i40e_common.c
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/intel/i40evf/i40e_common.c
@@ -44,7 +44,6 @@ i40e_status i40e_set_mac_type(struct i40
 		switch (hw->device_id) {
 		case I40E_DEV_ID_SFP_XL710:
 		case I40E_DEV_ID_QEMU:
-		case I40E_DEV_ID_KX_A:
 		case I40E_DEV_ID_KX_B:
 		case I40E_DEV_ID_KX_C:
 		case I40E_DEV_ID_QSFP_A:
@@ -905,6 +904,131 @@ struct i40e_rx_ptype_decoded i40evf_ptyp
 };
 
 /**
+ * i40evf_aq_rx_ctl_read_register - use FW to read from an Rx control register
+ * @hw: pointer to the hw struct
+ * @reg_addr: register address
+ * @reg_val: ptr to register value
+ * @cmd_details: pointer to command details structure or NULL
+ *
+ * Use the firmware to read the Rx control register,
+ * especially useful if the Rx unit is under heavy pressure
+ **/
+i40e_status i40evf_aq_rx_ctl_read_register(struct i40e_hw *hw,
+				u32 reg_addr, u32 *reg_val,
+				struct i40e_asq_cmd_details *cmd_details)
+{
+	struct i40e_aq_desc desc;
+	struct i40e_aqc_rx_ctl_reg_read_write *cmd_resp =
+		(struct i40e_aqc_rx_ctl_reg_read_write *)&desc.params.raw;
+	i40e_status status;
+
+	if (!reg_val)
+		return I40E_ERR_PARAM;
+
+	i40evf_fill_default_direct_cmd_desc(&desc,
+					    i40e_aqc_opc_rx_ctl_reg_read);
+
+	cmd_resp->address = cpu_to_le32(reg_addr);
+
+	status = i40evf_asq_send_command(hw, &desc, NULL, 0, cmd_details);
+
+	if (status == 0)
+		*reg_val = le32_to_cpu(cmd_resp->value);
+
+	return status;
+}
+
+/**
+ * i40evf_read_rx_ctl - read from an Rx control register
+ * @hw: pointer to the hw struct
+ * @reg_addr: register address
+ **/
+u32 i40evf_read_rx_ctl(struct i40e_hw *hw, u32 reg_addr)
+{
+	i40e_status status = 0;
+	bool use_register;
+	int retry = 5;
+	u32 val = 0;
+
+	use_register = (hw->aq.api_maj_ver == 1) && (hw->aq.api_min_ver < 5);
+	if (!use_register) {
+do_retry:
+		status = i40evf_aq_rx_ctl_read_register(hw, reg_addr,
+							&val, NULL);
+		if (hw->aq.asq_last_status == I40E_AQ_RC_EAGAIN && retry) {
+			usleep_range(1000, 2000);
+			retry--;
+			goto do_retry;
+		}
+	}
+
+	/* if the AQ access failed, try the old-fashioned way */
+	if (status || use_register)
+		val = rd32(hw, reg_addr);
+
+	return val;
+}
+
+/**
+ * i40evf_aq_rx_ctl_write_register
+ * @hw: pointer to the hw struct
+ * @reg_addr: register address
+ * @reg_val: register value
+ * @cmd_details: pointer to command details structure or NULL
+ *
+ * Use the firmware to write to an Rx control register,
+ * especially useful if the Rx unit is under heavy pressure
+ **/
+i40e_status i40evf_aq_rx_ctl_write_register(struct i40e_hw *hw,
+				u32 reg_addr, u32 reg_val,
+				struct i40e_asq_cmd_details *cmd_details)
+{
+	struct i40e_aq_desc desc;
+	struct i40e_aqc_rx_ctl_reg_read_write *cmd =
+		(struct i40e_aqc_rx_ctl_reg_read_write *)&desc.params.raw;
+	i40e_status status;
+
+	i40evf_fill_default_direct_cmd_desc(&desc,
+					    i40e_aqc_opc_rx_ctl_reg_write);
+
+	cmd->address = cpu_to_le32(reg_addr);
+	cmd->value = cpu_to_le32(reg_val);
+
+	status = i40evf_asq_send_command(hw, &desc, NULL, 0, cmd_details);
+
+	return status;
+}
+
+/**
+ * i40evf_write_rx_ctl - write to an Rx control register
+ * @hw: pointer to the hw struct
+ * @reg_addr: register address
+ * @reg_val: register value
+ **/
+void i40evf_write_rx_ctl(struct i40e_hw *hw, u32 reg_addr, u32 reg_val)
+{
+	i40e_status status = 0;
+	bool use_register;
+	int retry = 5;
+
+	use_register = (hw->aq.api_maj_ver == 1) && (hw->aq.api_min_ver < 5);
+	if (!use_register) {
+do_retry:
+		status = i40evf_aq_rx_ctl_write_register(hw, reg_addr,
+							 reg_val, NULL);
+		if (hw->aq.asq_last_status == I40E_AQ_RC_EAGAIN && retry) {
+			usleep_range(1000, 2000);
+			retry--;
+			goto do_retry;
+		}
+	}
+
+	/* if the AQ access failed, try the old-fashioned way */
+	if (status || use_register)
+		wr32(hw, reg_addr, reg_val);
+}
+
+/**
  * i40e_aq_send_msg_to_pf
  * @hw: pointer to the hardware structure
  * @v_opcode: opcodes for VF-PF communication
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/intel/i40evf/i40e_devids.h
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/intel/i40evf/i40e_devids.h
@@ -30,7 +30,6 @@
 /* Device IDs */
 #define I40E_DEV_ID_SFP_XL710		0x1572
 #define I40E_DEV_ID_QEMU		0x1574
-#define I40E_DEV_ID_KX_A		0x157F
 #define I40E_DEV_ID_KX_B		0x1580
 #define I40E_DEV_ID_KX_C		0x1581
 #define I40E_DEV_ID_QSFP_A		0x1583
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/intel/i40evf/i40e_prototype.h
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/intel/i40evf/i40e_prototype.h
@@ -103,4 +103,19 @@ i40e_status i40e_aq_add_rem_control_pack
 				struct i40e_asq_cmd_details *cmd_details);
 void i40e_add_filter_to_drop_tx_flow_control_frames(struct i40e_hw *hw,
 						    u16 vsi_seid);
+i40e_status i40evf_aq_rx_ctl_read_register(struct i40e_hw *hw,
+				u32 reg_addr, u32 *reg_val,
+				struct i40e_asq_cmd_details *cmd_details);
+u32 i40evf_read_rx_ctl(struct i40e_hw *hw, u32 reg_addr);
+i40e_status i40evf_aq_rx_ctl_write_register(struct i40e_hw *hw,
+				u32 reg_addr, u32 reg_val,
+				struct i40e_asq_cmd_details *cmd_details);
+void i40evf_write_rx_ctl(struct i40e_hw *hw, u32 reg_addr, u32 reg_val);
+i40e_status i40e_read_phy_register(struct i40e_hw *hw, u8 page,
+				   u16 reg, u8 phy_addr, u16 *value);
+i40e_status i40e_write_phy_register(struct i40e_hw *hw, u8 page,
+				    u16 reg, u8 phy_addr, u16 value);
+u8 i40e_get_phy_address(struct i40e_hw *hw, u8 dev_num);
+i40e_status i40e_blink_phy_link_led(struct i40e_hw *hw,
+				    u32 time, u32 interval);
 #endif /* _I40E_PROTOTYPE_H_ */
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/intel/i40evf/i40e_txrx.c
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/intel/i40evf/i40e_txrx.c
@@ -1,7 +1,7 @@
 /*******************************************************************************
  *
  * Intel Ethernet Controller XL710 Family Linux Virtual Function Driver
- * Copyright(c) 2013 - 2014 Intel Corporation.
+ * Copyright(c) 2013 - 2016 Intel Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms and conditions of the GNU General Public License,
@@ -51,11 +51,7 @@ static void i40e_unmap_and_free_tx_resou
 					    struct i40e_tx_buffer *tx_buffer)
 {
 	if (tx_buffer->skb) {
-		if (tx_buffer->tx_flags & I40E_TX_FLAGS_FD_SB)
-			kfree(tx_buffer->raw_buf);
-		else
-			dev_kfree_skb_any(tx_buffer->skb);
-
+		dev_kfree_skb_any(tx_buffer->skb);
 		if (dma_unmap_len(tx_buffer, len))
 			dma_unmap_single(ring->dev,
 					 dma_unmap_addr(tx_buffer, dma),
@@ -67,6 +63,10 @@ static void i40e_unmap_and_free_tx_resou
 			       dma_unmap_len(tx_buffer, len),
 			       DMA_TO_DEVICE);
 	}
+
+	if (tx_buffer->tx_flags & I40E_TX_FLAGS_FD_SB)
+		kfree(tx_buffer->raw_buf);
+
 	tx_buffer->next_to_watch = NULL;
 	tx_buffer->skb = NULL;
 	dma_unmap_len_set(tx_buffer, len, 0);
@@ -127,17 +127,28 @@ void i40evf_free_tx_resources(struct i40
 }
 
 /**
- * i40e_get_head - Retrieve head from head writeback
- * @tx_ring:  tx ring to fetch head of
+ * i40evf_get_tx_pending - how many Tx descriptors not processed
+ * @tx_ring: the ring of descriptors
+ * @in_sw: is tx_pending being checked in SW or HW
  *
- * Returns value of Tx ring head based on value stored
- * in head write-back location
+ * Since there is no access to the ring head register
+ * in XL710, we need to use our local copies
  **/
-static inline u32 i40e_get_head(struct i40e_ring *tx_ring)
+u32 i40evf_get_tx_pending(struct i40e_ring *ring, bool in_sw)
 {
-	void *head = (struct i40e_tx_desc *)tx_ring->desc + tx_ring->count;
+	u32 head, tail;
 
-	return le32_to_cpu(*(volatile __le32 *)head);
+	if (!in_sw)
+		head = i40e_get_head(ring);
+	else
+		head = ring->next_to_clean;
+	tail = readl(ring->tail);
+
+	if (head != tail)
+		return (head < tail) ?
+			tail - head : (tail + ring->count - head);
+
+	return 0;
 }
 
 #define WB_STRIDE 0x3
@@ -245,15 +256,21 @@ static bool i40e_clean_tx_irq(struct i40
 	tx_ring->q_vector->tx.total_bytes += total_bytes;
 	tx_ring->q_vector->tx.total_packets += total_packets;
 
-	/* check to see if there are any non-cache aligned descriptors
-	 * waiting to be written back, and kick the hardware to force
-	 * them to be written back in case of napi polling
-	 */
-	if (budget &&
-	    !((i & WB_STRIDE) == WB_STRIDE) &&
-	    !test_bit(__I40E_DOWN, &tx_ring->vsi->state) &&
-	    (I40E_DESC_UNUSED(tx_ring) != tx_ring->count))
-		tx_ring->arm_wb = true;
+	if (tx_ring->flags & I40E_TXR_FLAGS_WB_ON_ITR) {
+		unsigned int j = 0;
+		/* check to see if there are < 4 descriptors
+		 * waiting to be written back, then kick the hardware to force
+		 * them to be written back in case we stay in NAPI.
+		 * In this mode on X722 we do not enable Interrupt.
+		 */
+		j = i40evf_get_tx_pending(tx_ring, false);
+
+		if (budget &&
+		    ((j / (WB_STRIDE + 1)) == 0) && (j > 0) &&
+		    !test_bit(__I40E_DOWN, &tx_ring->vsi->state) &&
+		    (I40E_DESC_UNUSED(tx_ring) != tx_ring->count))
+			tx_ring->arm_wb = true;
+	}
 
 	netdev_tx_completed_queue(netdev_get_tx_queue(tx_ring->netdev,
 						      tx_ring->queue_index),
@@ -279,39 +296,49 @@ static bool i40e_clean_tx_irq(struct i40
 }
 
 /**
- * i40evf_force_wb -Arm hardware to do a wb on noncache aligned descriptors
+ * i40evf_enable_wb_on_itr - Arm hardware to do a wb, interrupts are not enabled
  * @vsi: the VSI we care about
- * @q_vector: the vector  on which to force writeback
+ * @q_vector: the vector on which to enable writeback
  *
  **/
-static void i40evf_force_wb(struct i40e_vsi *vsi, struct i40e_q_vector *q_vector)
+static void i40e_enable_wb_on_itr(struct i40e_vsi *vsi,
+				  struct i40e_q_vector *q_vector)
 {
 	u16 flags = q_vector->tx.ring[0].flags;
+	u32 val;
 
-	if (flags & I40E_TXR_FLAGS_WB_ON_ITR) {
-		u32 val;
+	if (!(flags & I40E_TXR_FLAGS_WB_ON_ITR))
+		return;
 
-		if (q_vector->arm_wb_state)
-			return;
+	if (q_vector->arm_wb_state)
+		return;
 
-		val = I40E_VFINT_DYN_CTLN1_WB_ON_ITR_MASK;
+	val = I40E_VFINT_DYN_CTLN1_WB_ON_ITR_MASK |
+	      I40E_VFINT_DYN_CTLN1_ITR_INDX_MASK; /* set noitr */
 
-		wr32(&vsi->back->hw,
-		     I40E_VFINT_DYN_CTLN1(q_vector->v_idx +
-					  vsi->base_vector - 1),
-		     val);
-		q_vector->arm_wb_state = true;
-	} else {
-		u32 val = I40E_VFINT_DYN_CTLN1_INTENA_MASK |
-			  I40E_VFINT_DYN_CTLN1_ITR_INDX_MASK | /* set noitr */
-			  I40E_VFINT_DYN_CTLN1_SWINT_TRIG_MASK |
-			  I40E_VFINT_DYN_CTLN1_SW_ITR_INDX_ENA_MASK;
-			  /* allow 00 to be written to the index */
-
-		wr32(&vsi->back->hw,
-		     I40E_VFINT_DYN_CTLN1(q_vector->v_idx +
-					  vsi->base_vector - 1), val);
-	}
+	wr32(&vsi->back->hw,
+	     I40E_VFINT_DYN_CTLN1(q_vector->v_idx +
+				  vsi->base_vector - 1), val);
+	q_vector->arm_wb_state = true;
+}
+
+/**
+ * i40evf_force_wb - Issue SW Interrupt so HW does a wb
+ * @vsi: the VSI we care about
+ * @q_vector: the vector  on which to force writeback
+ *
+ **/
+void i40evf_force_wb(struct i40e_vsi *vsi, struct i40e_q_vector *q_vector)
+{
+	u32 val = I40E_VFINT_DYN_CTLN1_INTENA_MASK |
+		  I40E_VFINT_DYN_CTLN1_ITR_INDX_MASK | /* set noitr */
+		  I40E_VFINT_DYN_CTLN1_SWINT_TRIG_MASK |
+		  I40E_VFINT_DYN_CTLN1_SW_ITR_INDX_ENA_MASK
+		  /* allow 00 to be written to the index */;
+
+	wr32(&vsi->back->hw,
+	     I40E_VFINT_DYN_CTLN1(q_vector->v_idx + vsi->base_vector - 1),
+	     val);
 }
 
 /**
@@ -414,7 +441,7 @@ static bool i40e_set_new_dynamic_itr(str
 	return false;
 }
 
-/*
+/**
  * i40evf_setup_tx_descriptors - Allocate the Tx descriptors
  * @tx_ring: the tx ring to set up
  *
@@ -509,7 +536,7 @@ void i40evf_clean_rx_ring(struct i40e_ri
 			if (rx_bi->page_dma) {
 				dma_unmap_page(dev,
 					       rx_bi->page_dma,
-					       PAGE_SIZE / 2,
+					       PAGE_SIZE,
 					       DMA_FROM_DEVICE);
 				rx_bi->page_dma = 0;
 			}
@@ -644,16 +671,19 @@ static inline void i40e_release_rx_desc(
  * i40evf_alloc_rx_buffers_ps - Replace used receive buffers; packet split
  * @rx_ring: ring to place buffers on
  * @cleaned_count: number of buffers to replace
+ *
+ * Returns true if any errors on allocation
  **/
-void i40evf_alloc_rx_buffers_ps(struct i40e_ring *rx_ring, u16 cleaned_count)
+bool i40evf_alloc_rx_buffers_ps(struct i40e_ring *rx_ring, u16 cleaned_count)
 {
 	u16 i = rx_ring->next_to_use;
 	union i40e_rx_desc *rx_desc;
 	struct i40e_rx_buffer *bi;
+	const int current_node = numa_node_id();
 
 	/* do nothing if no valid netdev defined */
 	if (!rx_ring->netdev || !cleaned_count)
-		return;
+		return false;
 
 	while (cleaned_count--) {
 		rx_desc = I40E_RX_DESC(rx_ring, i);
@@ -661,56 +691,79 @@ void i40evf_alloc_rx_buffers_ps(struct i
 
 		if (bi->skb) /* desc is in use */
 			goto no_buffers;
+
+	/* If we've been moved to a different NUMA node, release the
+	 * page so we can get a new one on the current node.
+	 */
+		if (bi->page &&  page_to_nid(bi->page) != current_node) {
+			dma_unmap_page(rx_ring->dev,
+				       bi->page_dma,
+				       PAGE_SIZE,
+				       DMA_FROM_DEVICE);
+			__free_page(bi->page);
+			bi->page = NULL;
+			bi->page_dma = 0;
+			rx_ring->rx_stats.realloc_count++;
+		} else if (bi->page) {
+			rx_ring->rx_stats.page_reuse_count++;
+		}
+
 		if (!bi->page) {
 			bi->page = alloc_page(GFP_ATOMIC);
 			if (!bi->page) {
 				rx_ring->rx_stats.alloc_page_failed++;
 				goto no_buffers;
 			}
-		}
-
-		if (!bi->page_dma) {
-			/* use a half page if we're re-using */
-			bi->page_offset ^= PAGE_SIZE / 2;
 			bi->page_dma = dma_map_page(rx_ring->dev,
 						    bi->page,
-						    bi->page_offset,
-						    PAGE_SIZE / 2,
+						    0,
+						    PAGE_SIZE,
 						    DMA_FROM_DEVICE);
-			if (dma_mapping_error(rx_ring->dev,
-					      bi->page_dma)) {
+			if (dma_mapping_error(rx_ring->dev, bi->page_dma)) {
 				rx_ring->rx_stats.alloc_page_failed++;
+				__free_page(bi->page);
+				bi->page = NULL;
 				bi->page_dma = 0;
+				bi->page_offset = 0;
 				goto no_buffers;
 			}
+			bi->page_offset = 0;
 		}
 
-		dma_sync_single_range_for_device(rx_ring->dev,
-						 bi->dma,
-						 0,
-						 rx_ring->rx_hdr_len,
-						 DMA_FROM_DEVICE);
 		/* Refresh the desc even if buffer_addrs didn't change
 		 * because each write-back erases this info.
 		 */
-		rx_desc->read.pkt_addr = cpu_to_le64(bi->page_dma);
+		rx_desc->read.pkt_addr =
+				cpu_to_le64(bi->page_dma + bi->page_offset);
 		rx_desc->read.hdr_addr = cpu_to_le64(bi->dma);
 		i++;
 		if (i == rx_ring->count)
 			i = 0;
 	}
 
+	if (rx_ring->next_to_use != i)
+		i40e_release_rx_desc(rx_ring, i);
+
+	return false;
+
 no_buffers:
 	if (rx_ring->next_to_use != i)
 		i40e_release_rx_desc(rx_ring, i);
+
+	/* make sure to come back via polling to try again after
+	 * allocation failure
+	 */
+	return true;
 }
 
 /**
  * i40evf_alloc_rx_buffers_1buf - Replace used receive buffers; single buffer
  * @rx_ring: ring to place buffers on
  * @cleaned_count: number of buffers to replace
+ *
+ * Returns true if any errors on allocation
  **/
-void i40evf_alloc_rx_buffers_1buf(struct i40e_ring *rx_ring, u16 cleaned_count)
+bool i40evf_alloc_rx_buffers_1buf(struct i40e_ring *rx_ring, u16 cleaned_count)
 {
 	u16 i = rx_ring->next_to_use;
 	union i40e_rx_desc *rx_desc;
@@ -719,7 +772,7 @@ void i40evf_alloc_rx_buffers_1buf(struct
 
 	/* do nothing if no valid netdev defined */
 	if (!rx_ring->netdev || !cleaned_count)
-		return;
+		return false;
 
 	while (cleaned_count--) {
 		rx_desc = I40E_RX_DESC(rx_ring, i);
@@ -727,8 +780,10 @@ void i40evf_alloc_rx_buffers_1buf(struct
 		skb = bi->skb;
 
 		if (!skb) {
-			skb = netdev_alloc_skb_ip_align(rx_ring->netdev,
-							rx_ring->rx_buf_len);
+			skb = __netdev_alloc_skb_ip_align(rx_ring->netdev,
+							  rx_ring->rx_buf_len,
+							  GFP_ATOMIC |
+							  __GFP_NOWARN);
 			if (!skb) {
 				rx_ring->rx_stats.alloc_buff_failed++;
 				goto no_buffers;
@@ -746,6 +801,8 @@ void i40evf_alloc_rx_buffers_1buf(struct
 			if (dma_mapping_error(rx_ring->dev, bi->dma)) {
 				rx_ring->rx_stats.alloc_buff_failed++;
 				bi->dma = 0;
+				dev_kfree_skb(bi->skb);
+				bi->skb = NULL;
 				goto no_buffers;
 			}
 		}
@@ -757,9 +814,19 @@ void i40evf_alloc_rx_buffers_1buf(struct
 			i = 0;
 	}
 
+	if (rx_ring->next_to_use != i)
+		i40e_release_rx_desc(rx_ring, i);
+
+	return false;
+
 no_buffers:
 	if (rx_ring->next_to_use != i)
 		i40e_release_rx_desc(rx_ring, i);
+
+	/* make sure to come back via polling to try again after
+	 * allocation failure
+	 */
+	return true;
 }
 
 /**
@@ -794,16 +861,7 @@ static inline void i40e_rx_checksum(stru
 				    u16 rx_ptype)
 {
 	struct i40e_rx_ptype_decoded decoded = decode_rx_desc_ptype(rx_ptype);
-	bool ipv4 = false, ipv6 = false;
-	bool ipv4_tunnel, ipv6_tunnel;
-	__wsum rx_udp_csum;
-	struct iphdr *iph;
-	__sum16 csum;
-
-	ipv4_tunnel = (rx_ptype >= I40E_RX_PTYPE_GRENAT4_MAC_PAY3) &&
-		     (rx_ptype <= I40E_RX_PTYPE_GRENAT4_MACVLAN_IPV6_ICMP_PAY4);
-	ipv6_tunnel = (rx_ptype >= I40E_RX_PTYPE_GRENAT6_MAC_PAY3) &&
-		     (rx_ptype <= I40E_RX_PTYPE_GRENAT6_MACVLAN_IPV6_ICMP_PAY4);
+	bool ipv4, ipv6, ipv4_tunnel, ipv6_tunnel;
 
 	skb->ip_summed = CHECKSUM_NONE;
 
@@ -819,12 +877,10 @@ static inline void i40e_rx_checksum(stru
 	if (!(decoded.known && decoded.outer_ip))
 		return;
 
-	if (decoded.outer_ip == I40E_RX_PTYPE_OUTER_IP &&
-	    decoded.outer_ip_ver == I40E_RX_PTYPE_OUTER_IPV4)
-		ipv4 = true;
-	else if (decoded.outer_ip == I40E_RX_PTYPE_OUTER_IP &&
-		 decoded.outer_ip_ver == I40E_RX_PTYPE_OUTER_IPV6)
-		ipv6 = true;
+	ipv4 = (decoded.outer_ip == I40E_RX_PTYPE_OUTER_IP) &&
+	       (decoded.outer_ip_ver == I40E_RX_PTYPE_OUTER_IPV4);
+	ipv6 = (decoded.outer_ip == I40E_RX_PTYPE_OUTER_IP) &&
+	       (decoded.outer_ip_ver == I40E_RX_PTYPE_OUTER_IPV6);
 
 	if (ipv4 &&
 	    (rx_error & (BIT(I40E_RX_DESC_ERROR_IPE_SHIFT) |
@@ -848,36 +904,17 @@ static inline void i40e_rx_checksum(stru
 	if (rx_error & BIT(I40E_RX_DESC_ERROR_PPRS_SHIFT))
 		return;
 
-	/* If VXLAN traffic has an outer UDPv4 checksum we need to check
-	 * it in the driver, hardware does not do it for us.
-	 * Since L3L4P bit was set we assume a valid IHL value (>=5)
-	 * so the total length of IPv4 header is IHL*4 bytes
-	 * The UDP_0 bit *may* bet set if the *inner* header is UDP
+	/* The hardware supported by this driver does not validate outer
+	 * checksums for tunneled VXLAN or GENEVE frames.  I don't agree
+	 * with it but the specification states that you "MAY validate", it
+	 * doesn't make it a hard requirement so if we have validated the
+	 * inner checksum report CHECKSUM_UNNECESSARY.
 	 */
-	if (ipv4_tunnel) {
-		skb->transport_header = skb->mac_header +
-					sizeof(struct ethhdr) +
-					(ip_hdr(skb)->ihl * 4);
-
-		/* Add 4 bytes for VLAN tagged packets */
-		skb->transport_header += (skb->protocol == htons(ETH_P_8021Q) ||
-					  skb->protocol == htons(ETH_P_8021AD))
-					  ? VLAN_HLEN : 0;
-
-		if ((ip_hdr(skb)->protocol == IPPROTO_UDP) &&
-		    (udp_hdr(skb)->check != 0)) {
-			rx_udp_csum = udp_csum(skb);
-			iph = ip_hdr(skb);
-			csum = csum_tcpudp_magic(iph->saddr, iph->daddr,
-						 (skb->len -
-						  skb_transport_offset(skb)),
-						 IPPROTO_UDP, rx_udp_csum);
 
-			if (udp_hdr(skb)->check != csum)
-				goto checksum_fail;
-
-		} /* else its GRE and so no outer UDP header */
-	}
+	ipv4_tunnel = (rx_ptype >= I40E_RX_PTYPE_GRENAT4_MAC_PAY3) &&
+		     (rx_ptype <= I40E_RX_PTYPE_GRENAT4_MACVLAN_IPV6_ICMP_PAY4);
+	ipv6_tunnel = (rx_ptype >= I40E_RX_PTYPE_GRENAT6_MAC_PAY3) &&
+		     (rx_ptype <= I40E_RX_PTYPE_GRENAT6_MACVLAN_IPV6_ICMP_PAY4);
 
 	skb->ip_summed = CHECKSUM_UNNECESSARY;
 	skb->csum_level = ipv4_tunnel || ipv6_tunnel;
@@ -889,31 +926,12 @@ checksum_fail:
 }
 
 /**
- * i40e_rx_hash - returns the hash value from the Rx descriptor
- * @ring: descriptor ring
- * @rx_desc: specific descriptor
- **/
-static inline u32 i40e_rx_hash(struct i40e_ring *ring,
-			       union i40e_rx_desc *rx_desc)
-{
-	const __le64 rss_mask =
-		cpu_to_le64((u64)I40E_RX_DESC_FLTSTAT_RSS_HASH <<
-			    I40E_RX_DESC_STATUS_FLTSTAT_SHIFT);
-
-	if ((ring->netdev->features & NETIF_F_RXHASH) &&
-	    (rx_desc->wb.qword1.status_error_len & rss_mask) == rss_mask)
-		return le32_to_cpu(rx_desc->wb.qword0.hi_dword.rss);
-	else
-		return 0;
-}
-
-/**
- * i40e_ptype_to_hash - get a hash type
+ * i40e_ptype_to_htype - get a hash type
  * @ptype: the ptype value from the descriptor
  *
  * Returns a hash type to be used by skb_set_hash
  **/
-static inline enum pkt_hash_types i40e_ptype_to_hash(u8 ptype)
+static inline enum pkt_hash_types i40e_ptype_to_htype(u8 ptype)
 {
 	struct i40e_rx_ptype_decoded decoded = decode_rx_desc_ptype(ptype);
 
@@ -931,24 +949,49 @@ static inline enum pkt_hash_types i40e_p
 }
 
 /**
+ * i40e_rx_hash - set the hash value in the skb
+ * @ring: descriptor ring
+ * @rx_desc: specific descriptor
+ **/
+static inline void i40e_rx_hash(struct i40e_ring *ring,
+				union i40e_rx_desc *rx_desc,
+				struct sk_buff *skb,
+				u8 rx_ptype)
+{
+	u32 hash;
+	const __le64 rss_mask  =
+		cpu_to_le64((u64)I40E_RX_DESC_FLTSTAT_RSS_HASH <<
+			    I40E_RX_DESC_STATUS_FLTSTAT_SHIFT);
+
+	if (ring->netdev->features & NETIF_F_RXHASH)
+		return;
+
+	if ((rx_desc->wb.qword1.status_error_len & rss_mask) == rss_mask) {
+		hash = le32_to_cpu(rx_desc->wb.qword0.hi_dword.rss);
+		skb_set_hash(skb, hash, i40e_ptype_to_htype(rx_ptype));
+	}
+}
+
+/**
  * i40e_clean_rx_irq_ps - Reclaim resources after receive; packet split
  * @rx_ring:  rx ring to clean
  * @budget:   how many cleans we're allowed
  *
  * Returns true if there's any budget left (e.g. the clean is finished)
  **/
-static int i40e_clean_rx_irq_ps(struct i40e_ring *rx_ring, int budget)
+static int i40e_clean_rx_irq_ps(struct i40e_ring *rx_ring, const int budget)
 {
 	unsigned int total_rx_bytes = 0, total_rx_packets = 0;
 	u16 rx_packet_len, rx_header_len, rx_sph, rx_hbo;
 	u16 cleaned_count = I40E_DESC_UNUSED(rx_ring);
-	const int current_node = numa_mem_id();
 	struct i40e_vsi *vsi = rx_ring->vsi;
 	u16 i = rx_ring->next_to_clean;
 	union i40e_rx_desc *rx_desc;
 	u32 rx_error, rx_status;
+	bool failure = false;
 	u8 rx_ptype;
 	u64 qword;
+	u32 copysize;
 
 	do {
 		struct i40e_rx_buffer *rx_bi;
@@ -956,7 +999,9 @@ static int i40e_clean_rx_irq_ps(struct i
 		u16 vlan_tag;
 		/* return some buffers to hardware, one at a time is too slow */
 		if (cleaned_count >= I40E_RX_BUFFER_WRITE) {
-			i40evf_alloc_rx_buffers_ps(rx_ring, cleaned_count);
+			failure = failure ||
+				  i40evf_alloc_rx_buffers_ps(rx_ring,
+							     cleaned_count);
 			cleaned_count = 0;
 		}
 
@@ -974,13 +1019,22 @@ static int i40e_clean_rx_irq_ps(struct i
 		 * DD bit is set.
 		 */
 		dma_rmb();
+		/* sync header buffer for reading */
+		dma_sync_single_range_for_cpu(rx_ring->dev,
+					      rx_ring->rx_bi[0].dma,
+					      i * rx_ring->rx_hdr_len,
+					      rx_ring->rx_hdr_len,
+					      DMA_FROM_DEVICE);
 		rx_bi = &rx_ring->rx_bi[i];
 		skb = rx_bi->skb;
 		if (likely(!skb)) {
-			skb = netdev_alloc_skb_ip_align(rx_ring->netdev,
-							rx_ring->rx_hdr_len);
+			skb = __netdev_alloc_skb_ip_align(rx_ring->netdev,
+							  rx_ring->rx_hdr_len,
+							  GFP_ATOMIC |
+							  __GFP_NOWARN);
 			if (!skb) {
 				rx_ring->rx_stats.alloc_buff_failed++;
+				failure = true;
 				break;
 			}
 
@@ -988,8 +1042,8 @@ static int i40e_clean_rx_irq_ps(struct i
 			skb_record_rx_queue(skb, rx_ring->queue_index);
 			/* we are reusing so sync this buffer for CPU use */
 			dma_sync_single_range_for_cpu(rx_ring->dev,
-						      rx_bi->dma,
-						      0,
+						      rx_ring->rx_bi[0].dma,
+						      i * rx_ring->rx_hdr_len,
 						      rx_ring->rx_hdr_len,
 						      DMA_FROM_DEVICE);
 		}
@@ -1007,9 +1061,16 @@ static int i40e_clean_rx_irq_ps(struct i
 
 		rx_ptype = (qword & I40E_RXD_QW1_PTYPE_MASK) >>
 			   I40E_RXD_QW1_PTYPE_SHIFT;
-		prefetch(rx_bi->page);
+		/* sync half-page for reading */
+		dma_sync_single_range_for_cpu(rx_ring->dev,
+					      rx_bi->page_dma,
+					      rx_bi->page_offset,
+					      PAGE_SIZE / 2,
+					      DMA_FROM_DEVICE);
+		prefetch(page_address(rx_bi->page) + rx_bi->page_offset);
 		rx_bi->skb = NULL;
 		cleaned_count++;
+		copysize = 0;
 		if (rx_hbo || rx_sph) {
 			int len;
 
@@ -1020,38 +1081,50 @@ static int i40e_clean_rx_irq_ps(struct i
 			memcpy(__skb_put(skb, len), rx_bi->hdr_buf, len);
 		} else if (skb->len == 0) {
 			int len;
+			unsigned char *va = page_address(rx_bi->page) +
+					    rx_bi->page_offset;
 
-			len = (rx_packet_len > skb_headlen(skb) ?
-				skb_headlen(skb) : rx_packet_len);
-			memcpy(__skb_put(skb, len),
-			       rx_bi->page + rx_bi->page_offset,
-			       len);
-			rx_bi->page_offset += len;
+			len = min(rx_packet_len, rx_ring->rx_hdr_len);
+			memcpy(__skb_put(skb, len), va, len);
+			copysize = len;
 			rx_packet_len -= len;
 		}
-
 		/* Get the rest of the data if this was a header split */
 		if (rx_packet_len) {
-			skb_fill_page_desc(skb, skb_shinfo(skb)->nr_frags,
-					   rx_bi->page,
-					   rx_bi->page_offset,
-					   rx_packet_len);
-
-			skb->len += rx_packet_len;
-			skb->data_len += rx_packet_len;
-			skb->truesize += rx_packet_len;
-
-			if ((page_count(rx_bi->page) == 1) &&
-			    (page_to_nid(rx_bi->page) == current_node))
-				get_page(rx_bi->page);
-			else
+			skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags,
+					rx_bi->page,
+					rx_bi->page_offset + copysize,
+					rx_packet_len, I40E_RXBUFFER_2048);
+
+			/* If the page count is more than 2, then both halves
+			 * of the page are used and we need to free it. Do it
+			 * here instead of in the alloc code. Otherwise one
+			 * of the half-pages might be released between now and
+			 * then, and we wouldn't know which one to use.
+			 * Don't call get_page and free_page since those are
+			 * both expensive atomic operations that just change
+			 * the refcount in opposite directions. Just give the
+			 * page to the stack; he can have our refcount.
+			 */
+			if (page_count(rx_bi->page) > 2) {
+				dma_unmap_page(rx_ring->dev,
+					       rx_bi->page_dma,
+					       PAGE_SIZE,
+					       DMA_FROM_DEVICE);
 				rx_bi->page = NULL;
+				rx_bi->page_dma = 0;
+				rx_ring->rx_stats.realloc_count++;
+			} else {
+				get_page(rx_bi->page);
+				/* switch to the other half-page here; the
+				 * allocation code programs the right addr
+				 * into HW. If we haven't used this half-page,
+				 * the address won't be changed, and HW can
+				 * just use it next time through.
+				 */
+				rx_bi->page_offset ^= PAGE_SIZE / 2;
+			}
 
-			dma_unmap_page(rx_ring->dev,
-				       rx_bi->page_dma,
-				       PAGE_SIZE / 2,
-				       DMA_FROM_DEVICE);
-			rx_bi->page_dma = 0;
 		}
 		I40E_RX_INCREMENT(rx_ring, i);
 
@@ -1071,8 +1144,8 @@ static int i40e_clean_rx_irq_ps(struct i
 			continue;
 		}
 
-		skb_set_hash(skb, i40e_rx_hash(rx_ring, rx_desc),
-			     i40e_ptype_to_hash(rx_ptype));
+		i40e_rx_hash(rx_ring, rx_desc, skb, rx_ptype);
+
 		/* probably a little skewed due to removing CRC */
 		total_rx_bytes += skb->len;
 		total_rx_packets++;
@@ -1104,7 +1177,7 @@ static int i40e_clean_rx_irq_ps(struct i
 	rx_ring->q_vector->rx.total_packets += total_rx_packets;
 	rx_ring->q_vector->rx.total_bytes += total_rx_bytes;
 
-	return total_rx_packets;
+	return failure ? budget : total_rx_packets;
 }
 
 /**
@@ -1122,6 +1195,7 @@ static int i40e_clean_rx_irq_1buf(struct
 	union i40e_rx_desc *rx_desc;
 	u32 rx_error, rx_status;
 	u16 rx_packet_len;
+	bool failure = false;
 	u8 rx_ptype;
 	u64 qword;
 	u16 i;
@@ -1132,7 +1206,9 @@ static int i40e_clean_rx_irq_1buf(struct
 		u16 vlan_tag;
 		/* return some buffers to hardware, one at a time is too slow */
 		if (cleaned_count >= I40E_RX_BUFFER_WRITE) {
-			i40evf_alloc_rx_buffers_1buf(rx_ring, cleaned_count);
+			failure = failure ||
+				  i40evf_alloc_rx_buffers_1buf(rx_ring,
+							       cleaned_count);
 			cleaned_count = 0;
 		}
 
@@ -1189,8 +1265,7 @@ static int i40e_clean_rx_irq_1buf(struct
 			continue;
 		}
 
-		skb_set_hash(skb, i40e_rx_hash(rx_ring, rx_desc),
-			     i40e_ptype_to_hash(rx_ptype));
+		i40e_rx_hash(rx_ring, rx_desc, skb, rx_ptype);
 		/* probably a little skewed due to removing CRC */
 		total_rx_bytes += skb->len;
 		total_rx_packets++;
@@ -1214,7 +1289,7 @@ static int i40e_clean_rx_irq_1buf(struct
 	rx_ring->q_vector->rx.total_packets += total_rx_packets;
 	rx_ring->q_vector->rx.total_bytes += total_rx_bytes;
 
-	return total_rx_packets;
+	return failure ? budget : total_rx_packets;
 }
 
 static u32 i40e_buildreg_itr(const int type, const u16 itr)
@@ -1222,7 +1297,9 @@ static u32 i40e_buildreg_itr(const int t
 	u32 val;
 
 	val = I40E_VFINT_DYN_CTLN1_INTENA_MASK |
-	      I40E_VFINT_DYN_CTLN1_CLEARPBA_MASK |
+	      /* Don't clear PBA because that can cause lost interrupts that
+	       * came in while we were cleaning/polling
+	       */
 	      (type << I40E_VFINT_DYN_CTLN1_ITR_INDX_SHIFT) |
 	      (itr << I40E_VFINT_DYN_CTLN1_INTERVAL_SHIFT);
 
@@ -1263,10 +1340,12 @@ static inline void i40e_update_enable_it
 		rx = i40e_set_new_dynamic_itr(&q_vector->rx);
 		rxval = i40e_buildreg_itr(I40E_RX_ITR, q_vector->rx.itr);
 	}
+
 	if (ITR_IS_DYNAMIC(vsi->tx_itr_setting)) {
 		tx = i40e_set_new_dynamic_itr(&q_vector->tx);
 		txval = i40e_buildreg_itr(I40E_TX_ITR, q_vector->tx.itr);
 	}
+
 	if (rx || tx) {
 		/* get the higher of the two ITR adjustments and
 		 * use the same value for both ITR registers
@@ -1302,7 +1381,6 @@ enable_int:
 		q_vector->itr_countdown--;
 	else
 		q_vector->itr_countdown = ITR_COUNTDOWN_START;
-
 }
 
 /**
@@ -1334,8 +1412,9 @@ int i40evf_napi_poll(struct napi_struct
 	 * budget and be more aggressive about cleaning up the Tx descriptors.
 	 */
 	i40e_for_each_ring(ring, q_vector->tx) {
-		clean_complete &= i40e_clean_tx_irq(ring, vsi->work_limit);
-		arm_wb |= ring->arm_wb;
+		clean_complete = clean_complete &&
+				 i40e_clean_tx_irq(ring, vsi->work_limit);
+		arm_wb = arm_wb || ring->arm_wb;
 		ring->arm_wb = false;
 	}
 
@@ -1358,14 +1437,16 @@ int i40evf_napi_poll(struct napi_struct
 
 		work_done += cleaned;
 		/* if we didn't clean as many as budgeted, we must be done */
-		clean_complete &= (budget_per_ring != cleaned);
+		clean_complete = clean_complete && (budget_per_ring > cleaned);
 	}
 
 	/* If work not completed, return budget and polling will return */
 	if (!clean_complete) {
 tx_only:
-		if (arm_wb)
-			i40evf_force_wb(vsi, q_vector);
+		if (arm_wb) {
+			q_vector->tx.ring[0].tx_stats.tx_force_wb++;
+			i40e_enable_wb_on_itr(vsi, q_vector);
+		}
 		return budget;
 	}
 
@@ -1437,21 +1518,30 @@ out:
  * @tx_ring:  ptr to the ring to send
  * @skb:      ptr to the skb we're sending
  * @hdr_len:  ptr to the size of the packet header
- * @cd_tunneling: ptr to context descriptor bits
+ * @cd_type_cmd_tso_mss: Quad Word 1
  *
  * Returns 0 if no TSO can happen, 1 if tso is going, or error
  **/
 static int i40e_tso(struct i40e_ring *tx_ring, struct sk_buff *skb,
-		    u8 *hdr_len, u64 *cd_type_cmd_tso_mss,
-		    u32 *cd_tunneling)
+		    u8 *hdr_len, u64 *cd_type_cmd_tso_mss)
 {
-	u32 cd_cmd, cd_tso_len, cd_mss;
-	struct ipv6hdr *ipv6h;
-	struct tcphdr *tcph;
-	struct iphdr *iph;
-	u32 l4len;
+	u64 cd_cmd, cd_tso_len, cd_mss;
+	union {
+		struct iphdr *v4;
+		struct ipv6hdr *v6;
+		unsigned char *hdr;
+	} ip;
+	union {
+		struct tcphdr *tcp;
+		struct udphdr *udp;
+		unsigned char *hdr;
+	} l4;
+	u32 paylen, l4_offset;
 	int err;
 
+	if (skb->ip_summed != CHECKSUM_PARTIAL)
+		return 0;
+
 	if (!skb_is_gso(skb))
 		return 0;
 
@@ -1459,35 +1549,60 @@ static int i40e_tso(struct i40e_ring *tx
 	if (err < 0)
 		return err;
 
-	iph = skb->encapsulation ? inner_ip_hdr(skb) : ip_hdr(skb);
-	ipv6h = skb->encapsulation ? inner_ipv6_hdr(skb) : ipv6_hdr(skb);
+	ip.hdr = skb_network_header(skb);
+	l4.hdr = skb_transport_header(skb);
+
+	/* initialize outer IP header fields */
+	if (ip.v4->version == 4) {
+		ip.v4->tot_len = 0;
+		ip.v4->check = 0;
+	} else {
+		ip.v6->payload_len = 0;
+	}
+
+	if (skb_shinfo(skb)->gso_type & (SKB_GSO_UDP_TUNNEL | SKB_GSO_GRE |
+					 SKB_GSO_UDP_TUNNEL_CSUM)) {
+		if (skb_shinfo(skb)->gso_type & SKB_GSO_UDP_TUNNEL_CSUM) {
+			/* determine offset of outer transport header */
+			l4_offset = l4.hdr - skb->data;
+
+			/* remove payload length from outer checksum */
+			paylen = (__force u16)l4.udp->check;
+			paylen += ntohs(1) * (u16)~(skb->len - l4_offset);
+			l4.udp->check = ~csum_fold((__force __wsum)paylen);
+		}
+
+		/* reset pointers to inner headers */
+		ip.hdr = skb_inner_network_header(skb);
+		l4.hdr = skb_inner_transport_header(skb);
 
-	if (iph->version == 4) {
-		tcph = skb->encapsulation ? inner_tcp_hdr(skb) : tcp_hdr(skb);
-		iph->tot_len = 0;
-		iph->check = 0;
-		tcph->check = ~csum_tcpudp_magic(iph->saddr, iph->daddr,
-						 0, IPPROTO_TCP, 0);
-	} else if (ipv6h->version == 6) {
-		tcph = skb->encapsulation ? inner_tcp_hdr(skb) : tcp_hdr(skb);
-		ipv6h->payload_len = 0;
-		tcph->check = ~csum_ipv6_magic(&ipv6h->saddr, &ipv6h->daddr,
-					       0, IPPROTO_TCP, 0);
-	}
-
-	l4len = skb->encapsulation ? inner_tcp_hdrlen(skb) : tcp_hdrlen(skb);
-	*hdr_len = (skb->encapsulation
-		    ? (skb_inner_transport_header(skb) - skb->data)
-		    : skb_transport_offset(skb)) + l4len;
+		/* initialize inner IP header fields */
+		if (ip.v4->version == 4) {
+			ip.v4->tot_len = 0;
+			ip.v4->check = 0;
+		} else {
+			ip.v6->payload_len = 0;
+		}
+	}
+
+	/* determine offset of inner transport header */
+	l4_offset = l4.hdr - skb->data;
+
+	/* remove payload length from inner checksum */
+	paylen = (__force u16)l4.tcp->check;
+	paylen += ntohs(1) * (u16)~(skb->len - l4_offset);
+	l4.tcp->check = ~csum_fold((__force __wsum)paylen);
+
+	/* compute length of segmentation header */
+	*hdr_len = (l4.tcp->doff * 4) + l4_offset;
 
 	/* find the field values */
 	cd_cmd = I40E_TX_CTX_DESC_TSO;
 	cd_tso_len = skb->len - *hdr_len;
 	cd_mss = skb_shinfo(skb)->gso_size;
-	*cd_type_cmd_tso_mss |= ((u64)cd_cmd << I40E_TXD_CTX_QW1_CMD_SHIFT) |
-				((u64)cd_tso_len <<
-				 I40E_TXD_CTX_QW1_TSO_LEN_SHIFT) |
-				((u64)cd_mss << I40E_TXD_CTX_QW1_MSS_SHIFT);
+	*cd_type_cmd_tso_mss |= (cd_cmd << I40E_TXD_CTX_QW1_CMD_SHIFT) |
+				(cd_tso_len << I40E_TXD_CTX_QW1_TSO_LEN_SHIFT) |
+				(cd_mss << I40E_TXD_CTX_QW1_MSS_SHIFT);
 	return 1;
 }
 
@@ -1497,130 +1612,157 @@ static int i40e_tso(struct i40e_ring *tx
  * @tx_flags: pointer to Tx flags currently set
  * @td_cmd: Tx descriptor command bits to set
  * @td_offset: Tx descriptor header offsets to set
+ * @tx_ring: Tx descriptor ring
  * @cd_tunneling: ptr to context desc bits
  **/
-static void i40e_tx_enable_csum(struct sk_buff *skb, u32 *tx_flags,
-				u32 *td_cmd, u32 *td_offset,
-				struct i40e_ring *tx_ring,
-				u32 *cd_tunneling)
-{
-	struct ipv6hdr *this_ipv6_hdr;
-	unsigned int this_tcp_hdrlen;
-	struct iphdr *this_ip_hdr;
-	u32 network_hdr_len;
-	u8 l4_hdr = 0;
-	struct udphdr *oudph;
-	struct iphdr *oiph;
-	u32 l4_tunnel = 0;
+static int i40e_tx_enable_csum(struct sk_buff *skb, u32 *tx_flags,
+			       u32 *td_cmd, u32 *td_offset,
+			       struct i40e_ring *tx_ring,
+			       u32 *cd_tunneling)
+{
+	union {
+		struct iphdr *v4;
+		struct ipv6hdr *v6;
+		unsigned char *hdr;
+	} ip;
+	union {
+		struct tcphdr *tcp;
+		struct udphdr *udp;
+		unsigned char *hdr;
+	} l4;
+	unsigned char *exthdr;
+	u32 offset, cmd = 0, tunnel = 0;
+	__be16 frag_off;
+	u8 l4_proto = 0;
+
+	if (skb->ip_summed != CHECKSUM_PARTIAL)
+		return 0;
+
+	ip.hdr = skb_network_header(skb);
+	l4.hdr = skb_transport_header(skb);
+
+	/* compute outer L2 header size */
+	offset = ((ip.hdr - skb->data) / 2) << I40E_TX_DESC_LENGTH_MACLEN_SHIFT;
 
 	if (skb->encapsulation) {
-		switch (ip_hdr(skb)->protocol) {
+		/* define outer network header type */
+		if (*tx_flags & I40E_TX_FLAGS_IPV4) {
+			tunnel |= (*tx_flags & I40E_TX_FLAGS_TSO) ?
+				  I40E_TX_CTX_EXT_IP_IPV4 :
+				  I40E_TX_CTX_EXT_IP_IPV4_NO_CSUM;
+
+			l4_proto = ip.v4->protocol;
+		} else if (*tx_flags & I40E_TX_FLAGS_IPV6) {
+			tunnel |= I40E_TX_CTX_EXT_IP_IPV6;
+
+			exthdr = ip.hdr + sizeof(*ip.v6);
+			l4_proto = ip.v6->nexthdr;
+			if (l4.hdr != exthdr)
+				ipv6_skip_exthdr(skb, exthdr - skb->data,
+						 &l4_proto, &frag_off);
+		}
+
+		/* compute outer L3 header size */
+		tunnel |= ((l4.hdr - ip.hdr) / 4) <<
+			  I40E_TXD_CTX_QW0_EXT_IPLEN_SHIFT;
+
+		/* switch IP header pointer from outer to inner header */
+		ip.hdr = skb_inner_network_header(skb);
+
+		/* define outer transport */
+		switch (l4_proto) {
 		case IPPROTO_UDP:
-			oudph = udp_hdr(skb);
-			oiph = ip_hdr(skb);
-			l4_tunnel = I40E_TXD_CTX_UDP_TUNNELING;
+			tunnel |= I40E_TXD_CTX_UDP_TUNNELING;
+			*tx_flags |= I40E_TX_FLAGS_VXLAN_TUNNEL;
+			break;
+		case IPPROTO_GRE:
+			tunnel |= I40E_TXD_CTX_GRE_TUNNELING;
 			*tx_flags |= I40E_TX_FLAGS_VXLAN_TUNNEL;
 			break;
 		default:
-			return;
-		}
-		network_hdr_len = skb_inner_network_header_len(skb);
-		this_ip_hdr = inner_ip_hdr(skb);
-		this_ipv6_hdr = inner_ipv6_hdr(skb);
-		this_tcp_hdrlen = inner_tcp_hdrlen(skb);
-
-		if (*tx_flags & I40E_TX_FLAGS_IPV4) {
-			if (*tx_flags & I40E_TX_FLAGS_TSO) {
-				*cd_tunneling |= I40E_TX_CTX_EXT_IP_IPV4;
-				ip_hdr(skb)->check = 0;
-			} else {
-				*cd_tunneling |=
-					 I40E_TX_CTX_EXT_IP_IPV4_NO_CSUM;
-			}
-		} else if (*tx_flags & I40E_TX_FLAGS_IPV6) {
-			*cd_tunneling |= I40E_TX_CTX_EXT_IP_IPV6;
 			if (*tx_flags & I40E_TX_FLAGS_TSO)
-				ip_hdr(skb)->check = 0;
-		}
+				return -1;
 
-		/* Now set the ctx descriptor fields */
-		*cd_tunneling |= (skb_network_header_len(skb) >> 2) <<
-				   I40E_TXD_CTX_QW0_EXT_IPLEN_SHIFT      |
-				   l4_tunnel                             |
-				   ((skb_inner_network_offset(skb) -
-					skb_transport_offset(skb)) >> 1) <<
-				   I40E_TXD_CTX_QW0_NATLEN_SHIFT;
-		if (this_ip_hdr->version == 6) {
-			*tx_flags &= ~I40E_TX_FLAGS_IPV4;
-			*tx_flags |= I40E_TX_FLAGS_IPV6;
+			skb_checksum_help(skb);
+			return 0;
 		}
 
+		/* compute tunnel header size */
+		tunnel |= ((ip.hdr - l4.hdr) / 2) <<
+			  I40E_TXD_CTX_QW0_NATLEN_SHIFT;
 
-		if ((tx_ring->flags & I40E_TXR_FLAGS_OUTER_UDP_CSUM) &&
-		    (l4_tunnel == I40E_TXD_CTX_UDP_TUNNELING)        &&
-		    (*cd_tunneling & I40E_TXD_CTX_QW0_EXT_IP_MASK)) {
-			oudph->check = ~csum_tcpudp_magic(oiph->saddr,
-					oiph->daddr,
-					(skb->len - skb_transport_offset(skb)),
-					IPPROTO_UDP, 0);
-			*cd_tunneling |= I40E_TXD_CTX_QW0_L4T_CS_MASK;
-		}
-	} else {
-		network_hdr_len = skb_network_header_len(skb);
-		this_ip_hdr = ip_hdr(skb);
-		this_ipv6_hdr = ipv6_hdr(skb);
-		this_tcp_hdrlen = tcp_hdrlen(skb);
+		/* indicate if we need to offload outer UDP header */
+		if ((*tx_flags & I40E_TX_FLAGS_TSO) &&
+		    (skb_shinfo(skb)->gso_type & SKB_GSO_UDP_TUNNEL_CSUM))
+			tunnel |= I40E_TXD_CTX_QW0_L4T_CS_MASK;
+
+		/* record tunnel offload values */
+		*cd_tunneling |= tunnel;
+
+		/* switch L4 header pointer from outer to inner */
+		l4.hdr = skb_inner_transport_header(skb);
+		l4_proto = 0;
+
+		/* reset type as we transition from outer to inner headers */
+		*tx_flags &= ~(I40E_TX_FLAGS_IPV4 | I40E_TX_FLAGS_IPV6);
+		if (ip.v4->version == 4)
+			*tx_flags |= I40E_TX_FLAGS_IPV4;
+		if (ip.v6->version == 6)
+			*tx_flags |= I40E_TX_FLAGS_IPV6;
 	}
 
 	/* Enable IP checksum offloads */
 	if (*tx_flags & I40E_TX_FLAGS_IPV4) {
-		l4_hdr = this_ip_hdr->protocol;
+		l4_proto = ip.v4->protocol;
 		/* the stack computes the IP header already, the only time we
 		 * need the hardware to recompute it is in the case of TSO.
 		 */
-		if (*tx_flags & I40E_TX_FLAGS_TSO) {
-			*td_cmd |= I40E_TX_DESC_CMD_IIPT_IPV4_CSUM;
-			this_ip_hdr->check = 0;
-		} else {
-			*td_cmd |= I40E_TX_DESC_CMD_IIPT_IPV4;
-		}
-		/* Now set the td_offset for IP header length */
-		*td_offset = (network_hdr_len >> 2) <<
-			      I40E_TX_DESC_LENGTH_IPLEN_SHIFT;
+		cmd |= (*tx_flags & I40E_TX_FLAGS_TSO) ?
+		       I40E_TX_DESC_CMD_IIPT_IPV4_CSUM :
+		       I40E_TX_DESC_CMD_IIPT_IPV4;
 	} else if (*tx_flags & I40E_TX_FLAGS_IPV6) {
-		l4_hdr = this_ipv6_hdr->nexthdr;
-		*td_cmd |= I40E_TX_DESC_CMD_IIPT_IPV6;
-		/* Now set the td_offset for IP header length */
-		*td_offset = (network_hdr_len >> 2) <<
-			      I40E_TX_DESC_LENGTH_IPLEN_SHIFT;
-	}
-	/* words in MACLEN + dwords in IPLEN + dwords in L4Len */
-	*td_offset |= (skb_network_offset(skb) >> 1) <<
-		       I40E_TX_DESC_LENGTH_MACLEN_SHIFT;
+		cmd |= I40E_TX_DESC_CMD_IIPT_IPV6;
+
+		exthdr = ip.hdr + sizeof(*ip.v6);
+		l4_proto = ip.v6->nexthdr;
+		if (l4.hdr != exthdr)
+			ipv6_skip_exthdr(skb, exthdr - skb->data,
+					 &l4_proto, &frag_off);
+	}
+
+	/* compute inner L3 header size */
+	offset |= ((l4.hdr - ip.hdr) / 4) << I40E_TX_DESC_LENGTH_IPLEN_SHIFT;
 
 	/* Enable L4 checksum offloads */
-	switch (l4_hdr) {
+	switch (l4_proto) {
 	case IPPROTO_TCP:
 		/* enable checksum offloads */
-		*td_cmd |= I40E_TX_DESC_CMD_L4T_EOFT_TCP;
-		*td_offset |= (this_tcp_hdrlen >> 2) <<
-			       I40E_TX_DESC_LENGTH_L4_FC_LEN_SHIFT;
+		cmd |= I40E_TX_DESC_CMD_L4T_EOFT_TCP;
+		offset |= l4.tcp->doff << I40E_TX_DESC_LENGTH_L4_FC_LEN_SHIFT;
 		break;
 	case IPPROTO_SCTP:
 		/* enable SCTP checksum offload */
-		*td_cmd |= I40E_TX_DESC_CMD_L4T_EOFT_SCTP;
-		*td_offset |= (sizeof(struct sctphdr) >> 2) <<
-			       I40E_TX_DESC_LENGTH_L4_FC_LEN_SHIFT;
+		cmd |= I40E_TX_DESC_CMD_L4T_EOFT_SCTP;
+		offset |= (sizeof(struct sctphdr) >> 2) <<
+			  I40E_TX_DESC_LENGTH_L4_FC_LEN_SHIFT;
 		break;
 	case IPPROTO_UDP:
 		/* enable UDP checksum offload */
-		*td_cmd |= I40E_TX_DESC_CMD_L4T_EOFT_UDP;
-		*td_offset |= (sizeof(struct udphdr) >> 2) <<
-			       I40E_TX_DESC_LENGTH_L4_FC_LEN_SHIFT;
+		cmd |= I40E_TX_DESC_CMD_L4T_EOFT_UDP;
+		offset |= (sizeof(struct udphdr) >> 2) <<
+			  I40E_TX_DESC_LENGTH_L4_FC_LEN_SHIFT;
 		break;
 	default:
-		break;
+		if (*tx_flags & I40E_TX_FLAGS_TSO)
+			return -1;
+		skb_checksum_help(skb);
+		return 0;
 	}
+
+	*td_cmd |= cmd;
+	*td_offset |= offset;
+
+	return 1;
 }
 
 /**
@@ -1654,60 +1796,72 @@ static void i40e_create_tx_ctx(struct i4
 	context_desc->type_cmd_tso_mss = cpu_to_le64(cd_type_cmd_tso_mss);
 }
 
- /**
- * i40e_chk_linearize - Check if there are more than 8 fragments per packet
+/**
+ * __i40evf_chk_linearize - Check if there are more than 8 fragments per packet
  * @skb:      send buffer
- * @tx_flags: collected send information
  *
  * Note: Our HW can't scatter-gather more than 8 fragments to build
  * a packet on the wire and so we need to figure out the cases where we
  * need to linearize the skb.
  **/
-static bool i40e_chk_linearize(struct sk_buff *skb, u32 tx_flags)
+bool __i40evf_chk_linearize(struct sk_buff *skb)
 {
-	struct skb_frag_struct *frag;
-	bool linearize = false;
-	unsigned int size = 0;
-	u16 num_frags;
-	u16 gso_segs;
+	const struct skb_frag_struct *frag, *stale;
+	int gso_size, nr_frags, sum;
 
-	num_frags = skb_shinfo(skb)->nr_frags;
-	gso_segs = skb_shinfo(skb)->gso_segs;
+	/* check to see if TSO is enabled, if so we may get a repreive */
+	gso_size = skb_shinfo(skb)->gso_size;
+	if (unlikely(!gso_size))
+		return true;
 
-	if (tx_flags & (I40E_TX_FLAGS_TSO | I40E_TX_FLAGS_FSO)) {
-		u16 j = 0;
+	/* no need to check if number of frags is less than 8 */
+	nr_frags = skb_shinfo(skb)->nr_frags;
+	if (nr_frags < I40E_MAX_BUFFER_TXD)
+		return false;
 
-		if (num_frags < (I40E_MAX_BUFFER_TXD))
-			goto linearize_chk_done;
-		/* try the simple math, if we have too many frags per segment */
-		if (DIV_ROUND_UP((num_frags + gso_segs), gso_segs) >
-		    I40E_MAX_BUFFER_TXD) {
-			linearize = true;
-			goto linearize_chk_done;
-		}
-		frag = &skb_shinfo(skb)->frags[0];
-		/* we might still have more fragments per segment */
-		do {
-			size += skb_frag_size(frag);
-			frag++; j++;
-			if ((size >= skb_shinfo(skb)->gso_size) &&
-			    (j < I40E_MAX_BUFFER_TXD)) {
-				size = (size % skb_shinfo(skb)->gso_size);
-				j = (size) ? 1 : 0;
-			}
-			if (j == I40E_MAX_BUFFER_TXD) {
-				linearize = true;
-				break;
-			}
-			num_frags--;
-		} while (num_frags);
-	} else {
-		if (num_frags >= I40E_MAX_BUFFER_TXD)
-			linearize = true;
+	/* We need to walk through the list and validate that each group
+	 * of 6 fragments totals at least gso_size.  However we don't need
+	 * to perform such validation on the first or last 6 since the first
+	 * 6 cannot inherit any data from a descriptor before them, and the
+	 * last 6 cannot inherit any data from a descriptor after them.
+	 */
+	nr_frags -= I40E_MAX_BUFFER_TXD - 1;
+	frag = &skb_shinfo(skb)->frags[0];
+
+	/* Initialize size to the negative value of gso_size minus 1.  We
+	 * use this as the worst case scenerio in which the frag ahead
+	 * of us only provides one byte which is why we are limited to 6
+	 * descriptors for a single transmit as the header and previous
+	 * fragment are already consuming 2 descriptors.
+	 */
+	sum = 1 - gso_size;
+
+	/* Add size of frags 1 through 5 to create our initial sum */
+	sum += skb_frag_size(++frag);
+	sum += skb_frag_size(++frag);
+	sum += skb_frag_size(++frag);
+	sum += skb_frag_size(++frag);
+	sum += skb_frag_size(++frag);
+
+	/* Walk through fragments adding latest fragment, testing it, and
+	 * then removing stale fragments from the sum.
+	 */
+	stale = &skb_shinfo(skb)->frags[0];
+	for (;;) {
+		sum += skb_frag_size(++frag);
+
+		/* if sum is negative we failed to make sufficient progress */
+		if (sum < 0)
+			return true;
+
+		/* use pre-decrement to avoid processing last fragment */
+		if (!--nr_frags)
+			break;
+
+		sum -= skb_frag_size(++stale);
 	}
 
-linearize_chk_done:
-	return linearize;
+	return false;
 }
 
 /**
@@ -1717,7 +1871,7 @@ linearize_chk_done:
  *
  * Returns -EBUSY if a stop is needed, else 0
  **/
-static inline int __i40evf_maybe_stop_tx(struct i40e_ring *tx_ring, int size)
+int __i40evf_maybe_stop_tx(struct i40e_ring *tx_ring, int size)
 {
 	netif_stop_subqueue(tx_ring->netdev, tx_ring->queue_index);
 	/* Memory barrier before checking head and tail */
@@ -1734,20 +1888,6 @@ static inline int __i40evf_maybe_stop_tx
 }
 
 /**
- * i40evf_maybe_stop_tx - 1st level check for tx stop conditions
- * @tx_ring: the ring to be checked
- * @size:    the size buffer we want to assure is available
- *
- * Returns 0 if stop is not needed
- **/
-static inline int i40evf_maybe_stop_tx(struct i40e_ring *tx_ring, int size)
-{
-	if (likely(I40E_DESC_UNUSED(tx_ring) >= size))
-		return 0;
-	return __i40evf_maybe_stop_tx(tx_ring, size);
-}
-
-/**
  * i40evf_tx_map - Build the Tx descriptor
  * @tx_ring:  ring to send buffer on
  * @skb:      send buffer
@@ -1770,6 +1910,9 @@ static inline void i40evf_tx_map(struct
 	u32 td_tag = 0;
 	dma_addr_t dma;
 	u16 gso_segs;
+	u16 desc_count = 0;
+	bool tail_bump = true;
+	bool do_rs = false;
 
 	if (tx_flags & I40E_TX_FLAGS_HW_VLAN) {
 		td_cmd |= I40E_TX_DESC_CMD_IL2TAG1;
@@ -1810,6 +1953,8 @@ static inline void i40evf_tx_map(struct
 
 			tx_desc++;
 			i++;
+			desc_count++;
+
 			if (i == tx_ring->count) {
 				tx_desc = I40E_TX_DESC(tx_ring, 0);
 				i = 0;
@@ -1829,6 +1974,8 @@ static inline void i40evf_tx_map(struct
 
 		tx_desc++;
 		i++;
+		desc_count++;
+
 		if (i == tx_ring->count) {
 			tx_desc = I40E_TX_DESC(tx_ring, 0);
 			i = 0;
@@ -1843,35 +1990,6 @@ static inline void i40evf_tx_map(struct
 		tx_bi = &tx_ring->tx_bi[i];
 	}
 
-	/* Place RS bit on last descriptor of any packet that spans across the
-	 * 4th descriptor (WB_STRIDE aka 0x3) in a 64B cacheline.
-	 */
-#define WB_STRIDE 0x3
-	if (((i & WB_STRIDE) != WB_STRIDE) &&
-	    (first <= &tx_ring->tx_bi[i]) &&
-	    (first >= &tx_ring->tx_bi[i & ~WB_STRIDE])) {
-		tx_desc->cmd_type_offset_bsz =
-			build_ctob(td_cmd, td_offset, size, td_tag) |
-			cpu_to_le64((u64)I40E_TX_DESC_CMD_EOP <<
-					 I40E_TXD_QW1_CMD_SHIFT);
-	} else {
-		tx_desc->cmd_type_offset_bsz =
-			build_ctob(td_cmd, td_offset, size, td_tag) |
-			cpu_to_le64((u64)I40E_TXD_CMD <<
-					 I40E_TXD_QW1_CMD_SHIFT);
-	}
-
-	netdev_tx_sent_queue(netdev_get_tx_queue(tx_ring->netdev,
-						 tx_ring->queue_index),
-			     first->bytecount);
-
-	/* Force memory writes to complete before letting h/w
-	 * know there are new descriptors to fetch.  (Only
-	 * applicable for weak-ordered memory model archs,
-	 * such as IA-64).
-	 */
-	wmb();
-
 	/* set next_to_watch value indicating a packet is present */
 	first->next_to_watch = tx_desc;
 
@@ -1881,15 +1999,72 @@ static inline void i40evf_tx_map(struct
 
 	tx_ring->next_to_use = i;
 
-	i40evf_maybe_stop_tx(tx_ring, DESC_NEEDED);
+	netdev_tx_sent_queue(netdev_get_tx_queue(tx_ring->netdev,
+						 tx_ring->queue_index),
+						 first->bytecount);
+	i40e_maybe_stop_tx(tx_ring, DESC_NEEDED);
+
+	/* Algorithm to optimize tail and RS bit setting:
+	 * if xmit_more is supported
+	 *	if xmit_more is true
+	 *		do not update tail and do not mark RS bit.
+	 *	if xmit_more is false and last xmit_more was false
+	 *		if every packet spanned less than 4 desc
+	 *			then set RS bit on 4th packet and update tail
+	 *			on every packet
+	 *		else
+	 *			update tail and set RS bit on every packet.
+	 *	if xmit_more is false and last_xmit_more was true
+	 *		update tail and set RS bit.
+	 *
+	 * Optimization: wmb to be issued only in case of tail update.
+	 * Also optimize the Descriptor WB path for RS bit with the same
+	 * algorithm.
+	 *
+	 * Note: If there are less than 4 packets
+	 * pending and interrupts were disabled the service task will
+	 * trigger a force WB.
+	 */
+	if (skb->xmit_more  &&
+	    !netif_xmit_stopped(netdev_get_tx_queue(tx_ring->netdev,
+						    tx_ring->queue_index))) {
+		tx_ring->flags |= I40E_TXR_FLAGS_LAST_XMIT_MORE_SET;
+		tail_bump = false;
+	} else if (!skb->xmit_more &&
+		   !netif_xmit_stopped(netdev_get_tx_queue(tx_ring->netdev,
+						       tx_ring->queue_index)) &&
+		   (!(tx_ring->flags & I40E_TXR_FLAGS_LAST_XMIT_MORE_SET)) &&
+		   (tx_ring->packet_stride < WB_STRIDE) &&
+		   (desc_count < WB_STRIDE)) {
+		tx_ring->packet_stride++;
+	} else {
+		tx_ring->packet_stride = 0;
+		tx_ring->flags &= ~I40E_TXR_FLAGS_LAST_XMIT_MORE_SET;
+		do_rs = true;
+	}
+	if (do_rs)
+		tx_ring->packet_stride = 0;
+
+	tx_desc->cmd_type_offset_bsz =
+			build_ctob(td_cmd, td_offset, size, td_tag) |
+			cpu_to_le64((u64)(do_rs ? I40E_TXD_CMD :
+						  I40E_TX_DESC_CMD_EOP) <<
+						  I40E_TXD_QW1_CMD_SHIFT);
+
 	/* notify HW of packet */
-	if (!skb->xmit_more ||
-	    netif_xmit_stopped(netdev_get_tx_queue(tx_ring->netdev,
-						   tx_ring->queue_index)))
-		writel(i, tx_ring->tail);
-	else
+	if (!tail_bump)
 		prefetchw(tx_desc + 1);
 
+	if (tail_bump) {
+		/* Force memory writes to complete before letting h/w
+		 * know there are new descriptors to fetch.  (Only
+		 * applicable for weak-ordered memory model archs,
+		 * such as IA-64).
+		 */
+		wmb();
+		writel(i, tx_ring->tail);
+	}
+
 	return;
 
 dma_error:
@@ -1910,38 +2085,6 @@ dma_error:
 }
 
 /**
- * i40evf_xmit_descriptor_count - calculate number of tx descriptors needed
- * @skb:     send buffer
- * @tx_ring: ring to send buffer on
- *
- * Returns number of data descriptors needed for this skb. Returns 0 to indicate
- * there is not enough descriptors available in this ring since we need at least
- * one descriptor.
- **/
-static inline int i40evf_xmit_descriptor_count(struct sk_buff *skb,
-					       struct i40e_ring *tx_ring)
-{
-	unsigned int f;
-	int count = 0;
-
-	/* need: 1 descriptor per page * PAGE_SIZE/I40E_MAX_DATA_PER_TXD,
-	 *       + 1 desc for skb_head_len/I40E_MAX_DATA_PER_TXD,
-	 *       + 4 desc gap to avoid the cache line where head is,
-	 *       + 1 desc for context descriptor,
-	 * otherwise try next time
-	 */
-	for (f = 0; f < skb_shinfo(skb)->nr_frags; f++)
-		count += TXD_USE_COUNT(skb_shinfo(skb)->frags[f].size);
-
-	count += TXD_USE_COUNT(skb_headlen(skb));
-	if (i40evf_maybe_stop_tx(tx_ring, count + 4 + 1)) {
-		tx_ring->tx_stats.tx_busy++;
-		return 0;
-	}
-	return count;
-}
-
-/**
  * i40e_xmit_frame_ring - Sends buffer on Tx ring
  * @skb:     send buffer
  * @tx_ring: ring to send buffer on
@@ -1959,10 +2102,29 @@ static netdev_tx_t i40e_xmit_frame_ring(
 	__be16 protocol;
 	u32 td_cmd = 0;
 	u8 hdr_len = 0;
-	int tso;
+	int tso, count;
+
+	/* prefetch the data, we'll need it later */
+	prefetch(skb->data);
+
+	count = i40e_xmit_descriptor_count(skb);
+	if (i40e_chk_linearize(skb, count)) {
+		if (__skb_linearize(skb))
+			goto out_drop;
+		count = TXD_USE_COUNT(skb->len);
+		tx_ring->tx_stats.tx_linearize++;
+	}
 
-	if (0 == i40evf_xmit_descriptor_count(skb, tx_ring))
+	/* need: 1 descriptor per page * PAGE_SIZE/I40E_MAX_DATA_PER_TXD,
+	 *       + 1 desc for skb_head_len/I40E_MAX_DATA_PER_TXD,
+	 *       + 4 desc gap to avoid the cache line where head is,
+	 *       + 1 desc for context descriptor,
+	 * otherwise try next time
+	 */
+	if (i40e_maybe_stop_tx(tx_ring, count + 4 + 1)) {
+		tx_ring->tx_stats.tx_busy++;
 		return NETDEV_TX_BUSY;
+	}
 
 	/* prepare the xmit flags */
 	if (i40evf_tx_prepare_vlan_flags(skb, tx_ring, &tx_flags))
@@ -1980,32 +2142,24 @@ static netdev_tx_t i40e_xmit_frame_ring(
 	else if (protocol == htons(ETH_P_IPV6))
 		tx_flags |= I40E_TX_FLAGS_IPV6;
 
-	tso = i40e_tso(tx_ring, skb, &hdr_len,
-		       &cd_type_cmd_tso_mss, &cd_tunneling);
+	tso = i40e_tso(tx_ring, skb, &hdr_len, &cd_type_cmd_tso_mss);
 
 	if (tso < 0)
 		goto out_drop;
 	else if (tso)
 		tx_flags |= I40E_TX_FLAGS_TSO;
 
-	if (i40e_chk_linearize(skb, tx_flags)) {
-		if (skb_linearize(skb))
-			goto out_drop;
-		tx_ring->tx_stats.tx_linearize++;
-	}
+	/* Always offload the checksum, since it's in the data descriptor */
+	tso = i40e_tx_enable_csum(skb, &tx_flags, &td_cmd, &td_offset,
+				  tx_ring, &cd_tunneling);
+	if (tso < 0)
+		goto out_drop;
+
 	skb_tx_timestamp(skb);
 
 	/* always enable CRC insertion offload */
 	td_cmd |= I40E_TX_DESC_CMD_ICRC;
 
-	/* Always offload the checksum, since it's in the data descriptor */
-	if (skb->ip_summed == CHECKSUM_PARTIAL) {
-		tx_flags |= I40E_TX_FLAGS_CSUM;
-
-		i40e_tx_enable_csum(skb, &tx_flags, &td_cmd, &td_offset,
-				    tx_ring, &cd_tunneling);
-	}
-
 	i40e_create_tx_ctx(tx_ring, cd_type_cmd_tso_mss,
 			   cd_tunneling, cd_l2tag2);
 
@@ -2029,7 +2183,7 @@ out_drop:
 netdev_tx_t i40evf_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
 {
 	struct i40evf_adapter *adapter = netdev_priv(netdev);
-	struct i40e_ring *tx_ring = adapter->tx_rings[skb->queue_mapping];
+	struct i40e_ring *tx_ring = &adapter->tx_rings[skb->queue_mapping];
 
 	/* hardware can't handle really short frames, hardware padding works
 	 * beyond this point
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/intel/i40evf/i40e_txrx.h
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/intel/i40evf/i40e_txrx.h
@@ -1,7 +1,7 @@
 /*******************************************************************************
  *
  * Intel Ethernet Controller XL710 Family Linux Virtual Function Driver
- * Copyright(c) 2013 - 2014 Intel Corporation.
+ * Copyright(c) 2013 - 2016 Intel Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms and conditions of the GNU General Public License,
@@ -153,7 +153,6 @@ enum i40e_dyn_idx_t {
 #define DESC_NEEDED (MAX_SKB_FRAGS + 4)
 #define I40E_MIN_DESC_PENDING	4
 
-#define I40E_TX_FLAGS_CSUM		BIT(0)
 #define I40E_TX_FLAGS_HW_VLAN		BIT(1)
 #define I40E_TX_FLAGS_SW_VLAN		BIT(2)
 #define I40E_TX_FLAGS_TSO		BIT(3)
@@ -201,12 +200,16 @@ struct i40e_tx_queue_stats {
 	u64 tx_busy;
 	u64 tx_done_old;
 	u64 tx_linearize;
+	u64 tx_force_wb;
+	u64 tx_lost_interrupt;
 };
 
 struct i40e_rx_queue_stats {
 	u64 non_eop_descs;
 	u64 alloc_page_failed;
 	u64 alloc_buff_failed;
+	u64 page_reuse_count;
+	u64 realloc_count;
 };
 
 enum i40e_ring_state_t {
@@ -252,7 +255,6 @@ struct i40e_ring {
 #define I40E_RX_DTYPE_NO_SPLIT      0
 #define I40E_RX_DTYPE_HEADER_SPLIT  1
 #define I40E_RX_DTYPE_SPLIT_ALWAYS  2
-	u8  hsplit;
 #define I40E_RX_SPLIT_L2      0x1
 #define I40E_RX_SPLIT_IP      0x2
 #define I40E_RX_SPLIT_TCP_UDP 0x4
@@ -267,10 +269,11 @@ struct i40e_ring {
 
 	bool ring_active;		/* is ring online or not */
 	bool arm_wb;		/* do something to arm write back */
+	u8 packet_stride;
+#define I40E_TXR_FLAGS_LAST_XMIT_MORE_SET BIT(2)
 
 	u16 flags;
 #define I40E_TXR_FLAGS_WB_ON_ITR	BIT(0)
-#define I40E_TXR_FLAGS_OUTER_UDP_CSUM	BIT(1)
 
 	/* stats structs */
 	struct i40e_queue_stats	stats;
@@ -310,8 +313,8 @@ struct i40e_ring_container {
 #define i40e_for_each_ring(pos, head) \
 	for (pos = (head).ring; pos != NULL; pos = pos->next)
 
-void i40evf_alloc_rx_buffers_ps(struct i40e_ring *rxr, u16 cleaned_count);
-void i40evf_alloc_rx_buffers_1buf(struct i40e_ring *rxr, u16 cleaned_count);
+bool i40evf_alloc_rx_buffers_ps(struct i40e_ring *rxr, u16 cleaned_count);
+bool i40evf_alloc_rx_buffers_1buf(struct i40e_ring *rxr, u16 cleaned_count);
 void i40evf_alloc_rx_headers(struct i40e_ring *rxr);
 netdev_tx_t i40evf_xmit_frame(struct sk_buff *skb, struct net_device *netdev);
 void i40evf_clean_tx_ring(struct i40e_ring *tx_ring);
@@ -321,4 +324,81 @@ int i40evf_setup_rx_descriptors(struct i
 void i40evf_free_tx_resources(struct i40e_ring *tx_ring);
 void i40evf_free_rx_resources(struct i40e_ring *rx_ring);
 int i40evf_napi_poll(struct napi_struct *napi, int budget);
+void i40evf_force_wb(struct i40e_vsi *vsi, struct i40e_q_vector *q_vector);
+u32 i40evf_get_tx_pending(struct i40e_ring *ring, bool in_sw);
+int __i40evf_maybe_stop_tx(struct i40e_ring *tx_ring, int size);
+bool __i40evf_chk_linearize(struct sk_buff *skb);
+
+/**
+ * i40e_get_head - Retrieve head from head writeback
+ * @tx_ring: Tx ring to fetch head of
+ *
+ * Returns value of Tx ring head based on value stored
+ * in head write-back location
+ **/
+static inline u32 i40e_get_head(struct i40e_ring *tx_ring)
+{
+	void *head = (struct i40e_tx_desc *)tx_ring->desc + tx_ring->count;
+
+	return le32_to_cpu(*(volatile __le32 *)head);
+}
+
+/**
+ * i40e_xmit_descriptor_count - calculate number of Tx descriptors needed
+ * @skb:     send buffer
+ * @tx_ring: ring to send buffer on
+ *
+ * Returns number of data descriptors needed for this skb. Returns 0 to indicate
+ * there is not enough descriptors available in this ring since we need at least
+ * one descriptor.
+ **/
+static inline int i40e_xmit_descriptor_count(struct sk_buff *skb)
+{
+	const struct skb_frag_struct *frag = &skb_shinfo(skb)->frags[0];
+	unsigned int nr_frags = skb_shinfo(skb)->nr_frags;
+	int count = 0, size = skb_headlen(skb);
+
+	for (;;) {
+		count += TXD_USE_COUNT(size);
+
+		if (!nr_frags--)
+			break;
+
+		size = skb_frag_size(frag++);
+	}
+
+	return count;
+}
+
+/**
+ * i40e_maybe_stop_tx - 1st level check for Tx stop conditions
+ * @tx_ring: the ring to be checked
+ * @size:    the size buffer we want to assure is available
+ *
+ * Returns 0 if stop is not needed
+ **/
+static inline int i40e_maybe_stop_tx(struct i40e_ring *tx_ring, int size)
+{
+	if (likely(I40E_DESC_UNUSED(tx_ring) >= size))
+		return 0;
+	return __i40evf_maybe_stop_tx(tx_ring, size);
+}
+
+/**
+ * i40e_chk_linearize - Check if there are more than 8 fragments per packet
+ * @skb:      send buffer
+ * @count:    number of buffers used
+ *
+ * Note: Our HW can't scatter-gather more than 8 fragments to build
+ * a packet on the wire and so we need to figure out the cases where we
+ * need to linearize the skb.
+ **/
+static inline bool i40e_chk_linearize(struct sk_buff *skb, int count)
+{
+	/* we can only support up to 8 data buffers for a single send */
+	if (likely(count <= I40E_MAX_BUFFER_TXD))
+		return false;
+
+	return __i40evf_chk_linearize(skb);
+}
 #endif /* _I40E_TXRX_H_ */
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/intel/i40evf/i40e_virtchnl.h
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/intel/i40evf/i40e_virtchnl.h
@@ -153,6 +153,7 @@ struct i40e_virtchnl_vsi_resource {
 #define I40E_VIRTCHNL_VF_OFFLOAD_WB_ON_ITR	0x00000020
 #define I40E_VIRTCHNL_VF_OFFLOAD_VLAN		0x00010000
 #define I40E_VIRTCHNL_VF_OFFLOAD_RX_POLLING	0x00020000
+#define I40E_VIRTCHNL_VF_OFFLOAD_RSS_PCTYPE_V2	0x00040000
 
 struct i40e_virtchnl_vf_resource {
 	u16 num_vsis;
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/intel/i40evf/i40evf.h
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/intel/i40evf/i40evf.h
@@ -1,7 +1,7 @@
 /*******************************************************************************
  *
  * Intel Ethernet Controller XL710 Family Linux Virtual Function Driver
- * Copyright(c) 2013 - 2014 Intel Corporation.
+ * Copyright(c) 2013 - 2016 Intel Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms and conditions of the GNU General Public License,
@@ -67,6 +67,8 @@ struct i40e_vsi {
 	u16 rx_itr_setting;
 	u16 tx_itr_setting;
 	u16 qs_handle;
+	u8 *rss_hkey_user; /* User configured hash keys */
+	u8 *rss_lut_user;  /* User configured lookup table entries */
 };
 
 /* How many Rx Buffers do we bundle into one write to the hardware ? */
@@ -95,10 +97,10 @@ struct i40e_vsi {
 #define I40E_TX_DESC(R, i) (&(((struct i40e_tx_desc *)((R)->desc))[i]))
 #define I40E_TX_CTXTDESC(R, i) \
 	(&(((struct i40e_tx_context_desc *)((R)->desc))[i]))
-#define MAX_RX_QUEUES 8
-#define MAX_TX_QUEUES MAX_RX_QUEUES
+#define MAX_QUEUES 16
 
 #define I40EVF_HKEY_ARRAY_SIZE ((I40E_VFQF_HKEY_MAX_INDEX + 1) * 4)
+#define I40EVF_HLUT_ARRAY_SIZE ((I40E_VFQF_HLUT_MAX_INDEX + 1) * 4)
 
 /* MAX_MSIX_Q_VECTORS of these are allocated,
  * but we only use one per queue-specific vector.
@@ -142,9 +144,6 @@ struct i40e_q_vector {
 #define OTHER_VECTOR 1
 #define NONQ_VECS (OTHER_VECTOR)
 
-#define MAX_MSIX_Q_VECTORS 4
-#define MAX_MSIX_COUNT 5
-
 #define MIN_MSIX_Q_VECTORS 1
 #define MIN_MSIX_COUNT (MIN_MSIX_Q_VECTORS + NONQ_VECS)
 
@@ -174,6 +173,7 @@ enum i40evf_state_t {
 	__I40EVF_RESETTING,		/* in reset */
 	/* Below here, watchdog is running */
 	__I40EVF_DOWN,			/* ready, can be opened */
+	__I40EVF_DOWN_PENDING,		/* descending, waiting for watchdog */
 	__I40EVF_TESTING,		/* in ethtool self-test */
 	__I40EVF_RUNNING,		/* opened, working */
 };
@@ -190,19 +190,19 @@ struct i40evf_adapter {
 	struct work_struct reset_task;
 	struct work_struct adminq_task;
 	struct delayed_work init_task;
-	struct i40e_q_vector *q_vector[MAX_MSIX_Q_VECTORS];
+	struct i40e_q_vector *q_vectors;
 	struct list_head vlan_filter_list;
 	char misc_vector_name[IFNAMSIZ + 9];
 	int num_active_queues;
 
 	/* TX */
-	struct i40e_ring *tx_rings[I40E_MAX_VSI_QP];
+	struct i40e_ring *tx_rings;
 	u32 tx_timeout_count;
 	struct list_head mac_filter_list;
 	u32 tx_desc_count;
 
 	/* RX */
-	struct i40e_ring *rx_rings[I40E_MAX_VSI_QP];
+	struct i40e_ring *rx_rings;
 	u64 hw_csum_rx_error;
 	u32 rx_desc_count;
 	int num_msix_vectors;
@@ -274,6 +274,9 @@ struct i40evf_adapter {
 };
 
 
+/* Ethtool Private Flags */
+#define I40EVF_PRIV_FLAGS_PS		BIT(0)
+
 /* needed by i40evf_ethtool.c */
 extern char i40evf_driver_name[];
 extern const char i40evf_driver_version[];
@@ -281,6 +284,7 @@ extern const char i40evf_driver_version[
 int i40evf_up(struct i40evf_adapter *adapter);
 void i40evf_down(struct i40evf_adapter *adapter);
 int i40evf_process_config(struct i40evf_adapter *adapter);
+void i40evf_schedule_reset(struct i40evf_adapter *adapter);
 void i40evf_reset(struct i40evf_adapter *adapter);
 void i40evf_set_ethtool_ops(struct net_device *netdev);
 void i40evf_update_stats(struct i40evf_adapter *adapter);
@@ -313,4 +317,8 @@ void i40evf_request_reset(struct i40evf_
 void i40evf_virtchnl_completion(struct i40evf_adapter *adapter,
 				enum i40e_virtchnl_ops v_opcode,
 				i40e_status v_retval, u8 *msg, u16 msglen);
+int i40evf_config_rss(struct i40e_vsi *vsi, const u8 *seed, u8 *lut,
+		      u16 lut_size);
+int i40evf_get_rss(struct i40e_vsi *vsi, const u8 *seed, u8 *lut,
+		   u16 lut_size);
 #endif /* _I40EVF_H_ */
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/intel/i40evf/i40evf_ethtool.c
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/intel/i40evf/i40evf_ethtool.c
@@ -1,7 +1,7 @@
 /*******************************************************************************
  *
  * Intel Ethernet Controller XL710 Family Linux Virtual Function Driver
- * Copyright(c) 2013 - 2015 Intel Corporation.
+ * Copyright(c) 2013 - 2016 Intel Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms and conditions of the GNU General Public License,
@@ -63,6 +63,12 @@ static const struct i40evf_stats i40evf_
 #define I40EVF_STATS_LEN(_dev) \
 	(I40EVF_GLOBAL_STATS_LEN + I40EVF_QUEUE_STATS_LEN(_dev))
 
+static const char i40evf_priv_flags_strings[][ETH_GSTRING_LEN] = {
+	"packet-split",
+};
+
+#define I40EVF_PRIV_FLAGS_STR_LEN ARRAY_SIZE(i40evf_priv_flags_strings)
+
 /**
  * i40evf_get_settings - Get Link Speed and Duplex settings
  * @netdev: network interface device structure
@@ -97,6 +103,8 @@ static int i40evf_get_sset_count(struct
 {
 	if (sset == ETH_SS_STATS)
 		return I40EVF_STATS_LEN(netdev);
+	else if (sset == ETH_SS_PRIV_FLAGS)
+		return I40EVF_PRIV_FLAGS_STR_LEN;
 	else
 		return -EINVAL;
 }
@@ -121,12 +129,12 @@ static void i40evf_get_ethtool_stats(str
 		data[i] =  *(u64 *)p;
 	}
 	for (j = 0; j < adapter->num_active_queues; j++) {
-		data[i++] = adapter->tx_rings[j]->stats.packets;
-		data[i++] = adapter->tx_rings[j]->stats.bytes;
+		data[i++] = adapter->tx_rings[j].stats.packets;
+		data[i++] = adapter->tx_rings[j].stats.bytes;
 	}
 	for (j = 0; j < adapter->num_active_queues; j++) {
-		data[i++] = adapter->rx_rings[j]->stats.packets;
-		data[i++] = adapter->rx_rings[j]->stats.bytes;
+		data[i++] = adapter->rx_rings[j].stats.packets;
+		data[i++] = adapter->rx_rings[j].stats.bytes;
 	}
 }
 
@@ -162,6 +170,12 @@ static void i40evf_get_strings(struct ne
 			snprintf(p, ETH_GSTRING_LEN, "rx-%u.bytes", i);
 			p += ETH_GSTRING_LEN;
 		}
+	} else if (sset == ETH_SS_PRIV_FLAGS) {
+		for (i = 0; i < I40EVF_PRIV_FLAGS_STR_LEN; i++) {
+			memcpy(data, i40evf_priv_flags_strings[i],
+			       ETH_GSTRING_LEN);
+			data += ETH_GSTRING_LEN;
+		}
 	}
 }
 
@@ -211,6 +225,7 @@ static void i40evf_get_drvinfo(struct ne
 	strlcpy(drvinfo->version, i40evf_driver_version, 32);
 	strlcpy(drvinfo->fw_version, "N/A", 4);
 	strlcpy(drvinfo->bus_info, pci_name(adapter->pdev), 32);
+	drvinfo->n_priv_flags = I40EVF_PRIV_FLAGS_STR_LEN;
 }
 
 /**
@@ -351,7 +366,7 @@ static int i40evf_set_coalesce(struct ne
 		vsi->tx_itr_setting &= ~I40E_ITR_DYNAMIC;
 
 	for (i = 0; i < adapter->num_msix_vectors - NONQ_VECS; i++) {
-		q_vector = adapter->q_vector[i];
+		q_vector = &adapter->q_vectors[i];
 		q_vector->rx.itr = ITR_TO_REG(vsi->rx_itr_setting);
 		wr32(hw, I40E_VFINT_ITRN1(0, i), q_vector->rx.itr);
 		q_vector->tx.itr = ITR_TO_REG(vsi->tx_itr_setting);
@@ -459,6 +474,7 @@ static int i40evf_set_rss_hash_opt(struc
 				   struct ethtool_rxnfc *nfc)
 {
 	struct i40e_hw *hw = &adapter->hw;
+	u32 flags = adapter->vf_res->vf_offload_flags;
 
 	u64 hena = (u64)rd32(hw, I40E_VFQF_HENA(0)) |
 		   ((u64)rd32(hw, I40E_VFQF_HENA(1)) << 32);
@@ -477,54 +493,50 @@ static int i40evf_set_rss_hash_opt(struc
 
 	switch (nfc->flow_type) {
 	case TCP_V4_FLOW:
-		switch (nfc->data & (RXH_L4_B_0_1 | RXH_L4_B_2_3)) {
-		case 0:
-			hena &= ~BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV4_TCP);
-			break;
-		case (RXH_L4_B_0_1 | RXH_L4_B_2_3):
+		if (nfc->data & (RXH_L4_B_0_1 | RXH_L4_B_2_3)) {
+			if (flags & I40E_VIRTCHNL_VF_OFFLOAD_RSS_PCTYPE_V2)
+				hena |=
+			   BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV4_TCP_SYN_NO_ACK);
+
 			hena |= BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV4_TCP);
-			break;
-		default:
+		} else {
 			return -EINVAL;
 		}
 		break;
 	case TCP_V6_FLOW:
-		switch (nfc->data & (RXH_L4_B_0_1 | RXH_L4_B_2_3)) {
-		case 0:
-			hena &= ~BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV6_TCP);
-			break;
-		case (RXH_L4_B_0_1 | RXH_L4_B_2_3):
+		if (nfc->data & (RXH_L4_B_0_1 | RXH_L4_B_2_3)) {
+			if (flags & I40E_VIRTCHNL_VF_OFFLOAD_RSS_PCTYPE_V2)
+				hena |=
+			   BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV6_TCP_SYN_NO_ACK);
+
 			hena |= BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV6_TCP);
-			break;
-		default:
+		} else {
 			return -EINVAL;
 		}
 		break;
 	case UDP_V4_FLOW:
-		switch (nfc->data & (RXH_L4_B_0_1 | RXH_L4_B_2_3)) {
-		case 0:
-			hena &= ~(BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV4_UDP) |
-				  BIT_ULL(I40E_FILTER_PCTYPE_FRAG_IPV4));
-			break;
-		case (RXH_L4_B_0_1 | RXH_L4_B_2_3):
+		if (nfc->data & (RXH_L4_B_0_1 | RXH_L4_B_2_3)) {
+			if (flags & I40E_VIRTCHNL_VF_OFFLOAD_RSS_PCTYPE_V2)
+				hena |=
+			    BIT_ULL(I40E_FILTER_PCTYPE_NONF_UNICAST_IPV4_UDP) |
+			    BIT_ULL(I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV4_UDP);
+
 			hena |= (BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV4_UDP) |
 				 BIT_ULL(I40E_FILTER_PCTYPE_FRAG_IPV4));
-			break;
-		default:
+		} else {
 			return -EINVAL;
 		}
 		break;
 	case UDP_V6_FLOW:
-		switch (nfc->data & (RXH_L4_B_0_1 | RXH_L4_B_2_3)) {
-		case 0:
-			hena &= ~(BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV6_UDP) |
-				  BIT_ULL(I40E_FILTER_PCTYPE_FRAG_IPV6));
-			break;
-		case (RXH_L4_B_0_1 | RXH_L4_B_2_3):
+		if (nfc->data & (RXH_L4_B_0_1 | RXH_L4_B_2_3)) {
+			if (flags & I40E_VIRTCHNL_VF_OFFLOAD_RSS_PCTYPE_V2)
+				hena |=
+			    BIT_ULL(I40E_FILTER_PCTYPE_NONF_UNICAST_IPV6_UDP) |
+			    BIT_ULL(I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV6_UDP);
+
 			hena |= (BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV6_UDP) |
 				 BIT_ULL(I40E_FILTER_PCTYPE_FRAG_IPV6));
-			break;
-		default:
+		} else {
 			return -EINVAL;
 		}
 		break;
@@ -634,25 +646,34 @@ static int i40evf_get_rxfh(struct net_de
 			   u8 *hfunc)
 {
 	struct i40evf_adapter *adapter = netdev_priv(netdev);
-	struct i40e_hw *hw = &adapter->hw;
-	u32 hlut_val;
-	int i, j;
+	struct i40e_vsi *vsi = &adapter->vsi;
+	u8 *seed = NULL, *lut;
+	int ret;
+	u16 i;
 
 	if (hfunc)
 		*hfunc = ETH_RSS_HASH_TOP;
 	if (!indir)
 		return 0;
 
-	if (indir) {
-		for (i = 0, j = 0; i <= I40E_VFQF_HLUT_MAX_INDEX; i++) {
-			hlut_val = rd32(hw, I40E_VFQF_HLUT(i));
-			indir[j++] = hlut_val & 0xff;
-			indir[j++] = (hlut_val >> 8) & 0xff;
-			indir[j++] = (hlut_val >> 16) & 0xff;
-			indir[j++] = (hlut_val >> 24) & 0xff;
-		}
-	}
-	return 0;
+	seed = key;
+
+	lut = kzalloc(I40EVF_HLUT_ARRAY_SIZE, GFP_KERNEL);
+	if (!lut)
+		return -ENOMEM;
+
+	ret = i40evf_get_rss(vsi, seed, lut, I40EVF_HLUT_ARRAY_SIZE);
+	if (ret)
+		goto out;
+
+	/* Each 32 bits pointed by 'indir' is stored with a lut entry */
+	for (i = 0; i < I40EVF_HLUT_ARRAY_SIZE; i++)
+		indir[i] = (u32)lut[i];
+
+out:
+	kfree(lut);
+
+	return ret;
 }
 
 /**
@@ -668,9 +689,9 @@ static int i40evf_set_rxfh(struct net_de
 			   const u8 *key, const u8 hfunc)
 {
 	struct i40evf_adapter *adapter = netdev_priv(netdev);
-	struct i40e_hw *hw = &adapter->hw;
-	u32 hlut_val;
-	int i, j;
+	struct i40e_vsi *vsi = &adapter->vsi;
+	u8 *seed = NULL;
+	u16 i;
 
 	/* We do not allow change in unsupported parameters */
 	if (key ||
@@ -679,14 +700,76 @@ static int i40evf_set_rxfh(struct net_de
 	if (!indir)
 		return 0;
 
-	for (i = 0, j = 0; i <= I40E_VFQF_HLUT_MAX_INDEX; i++) {
-		hlut_val = indir[j++];
-		hlut_val |= indir[j++] << 8;
-		hlut_val |= indir[j++] << 16;
-		hlut_val |= indir[j++] << 24;
-		wr32(hw, I40E_VFQF_HLUT(i), hlut_val);
+	if (key) {
+		if (!vsi->rss_hkey_user) {
+			vsi->rss_hkey_user = kzalloc(I40EVF_HKEY_ARRAY_SIZE,
+						     GFP_KERNEL);
+			if (!vsi->rss_hkey_user)
+				return -ENOMEM;
+		}
+		memcpy(vsi->rss_hkey_user, key, I40EVF_HKEY_ARRAY_SIZE);
+		seed = vsi->rss_hkey_user;
+	}
+	if (!vsi->rss_lut_user) {
+		vsi->rss_lut_user = kzalloc(I40EVF_HLUT_ARRAY_SIZE,
+					    GFP_KERNEL);
+		if (!vsi->rss_lut_user)
+			return -ENOMEM;
 	}
 
+	/* Each 32 bits pointed by 'indir' is stored with a lut entry */
+	for (i = 0; i < I40EVF_HLUT_ARRAY_SIZE; i++)
+		vsi->rss_lut_user[i] = (u8)(indir[i]);
+
+	return i40evf_config_rss(vsi, seed, vsi->rss_lut_user,
+				 I40EVF_HLUT_ARRAY_SIZE);
+}
+
+/**
+ * i40evf_get_priv_flags - report device private flags
+ * @dev: network interface device structure
+ *
+ * The get string set count and the string set should be matched for each
+ * flag returned.  Add new strings for each flag to the i40e_priv_flags_strings
+ * array.
+ *
+ * Returns a u32 bitmap of flags.
+ **/
+static u32 i40evf_get_priv_flags(struct net_device *dev)
+{
+	struct i40evf_adapter *adapter = netdev_priv(dev);
+	u32 ret_flags = 0;
+
+	ret_flags |= adapter->flags & I40EVF_FLAG_RX_PS_ENABLED ?
+		I40EVF_PRIV_FLAGS_PS : 0;
+
+	return ret_flags;
+}
+
+/**
+ * i40evf_set_priv_flags - set private flags
+ * @dev: network interface device structure
+ * @flags: bit flags to be set
+ **/
+static int i40evf_set_priv_flags(struct net_device *dev, u32 flags)
+{
+	struct i40evf_adapter *adapter = netdev_priv(dev);
+	bool reset_required = false;
+
+	if ((flags & I40EVF_PRIV_FLAGS_PS) &&
+	    !(adapter->flags & I40EVF_FLAG_RX_PS_ENABLED)) {
+		adapter->flags |= I40EVF_FLAG_RX_PS_ENABLED;
+		reset_required = true;
+	} else if (!(flags & I40EVF_PRIV_FLAGS_PS) &&
+		   (adapter->flags & I40EVF_FLAG_RX_PS_ENABLED)) {
+		adapter->flags &= ~I40EVF_FLAG_RX_PS_ENABLED;
+		reset_required = true;
+	}
+
+	/* if needed, issue reset to cause things to take effect */
+	if (reset_required)
+		i40evf_schedule_reset(adapter);
+
 	return 0;
 }
 
@@ -699,6 +782,8 @@ static const struct ethtool_ops i40evf_e
 	.get_strings		= i40evf_get_strings,
 	.get_ethtool_stats	= i40evf_get_ethtool_stats,
 	.get_sset_count		= i40evf_get_sset_count,
+	.get_priv_flags		= i40evf_get_priv_flags,
+	.set_priv_flags		= i40evf_set_priv_flags,
 	.get_msglevel		= i40evf_get_msglevel,
 	.set_msglevel		= i40evf_set_msglevel,
 	.get_coalesce		= i40evf_get_coalesce,
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/intel/i40evf/i40evf_main.c
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/intel/i40evf/i40evf_main.c
@@ -1,7 +1,7 @@
 /*******************************************************************************
  *
  * Intel Ethernet Controller XL710 Family Linux Virtual Function Driver
- * Copyright(c) 2013 - 2015 Intel Corporation.
+ * Copyright(c) 2013 - 2016 Intel Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms and conditions of the GNU General Public License,
@@ -32,9 +32,17 @@ static int i40evf_close(struct net_devic
 
 char i40evf_driver_name[] = "i40evf";
 static const char i40evf_driver_string[] =
-	"Intel(R) XL710/X710 Virtual Function Network Driver";
+	"Intel(R) 40-10 Gigabit Virtual Function Network Driver";
 
-#define DRV_VERSION "1.3.33"
+#define DRV_KERN "-k"
+
+#define DRV_VERSION_MAJOR 1
+#define DRV_VERSION_MINOR 4
+#define DRV_VERSION_BUILD 15
+#define DRV_VERSION __stringify(DRV_VERSION_MAJOR) "." \
+	     __stringify(DRV_VERSION_MINOR) "." \
+	     __stringify(DRV_VERSION_BUILD) \
+	     DRV_KERN
 const char i40evf_driver_version[] = DRV_VERSION;
 static const char i40evf_copyright[] =
 	"Copyright (c) 2013 - 2015 Intel Corporation.";
@@ -61,6 +69,8 @@ MODULE_DESCRIPTION("Intel(R) XL710 X710
 MODULE_LICENSE("GPL");
 MODULE_VERSION(DRV_VERSION);
 
+static struct workqueue_struct *i40evf_wq;
+
 /**
  * i40evf_allocate_dma_mem_d - OS specific memory alloc for shared code
  * @hw:   pointer to the HW structure
@@ -163,6 +173,19 @@ void i40evf_debug_d(void *hw, u32 mask,
 }
 
 /**
+ * i40evf_schedule_reset - Set the flags and schedule a reset event
+ * @adapter: board private structure
+ **/
+void i40evf_schedule_reset(struct i40evf_adapter *adapter)
+{
+	if (!(adapter->flags &
+	      (I40EVF_FLAG_RESET_PENDING | I40EVF_FLAG_RESET_NEEDED))) {
+		adapter->flags |= I40EVF_FLAG_RESET_NEEDED;
+		schedule_work(&adapter->reset_task);
+	}
+}
+
+/**
  * i40evf_tx_timeout - Respond to a Tx Hang
  * @netdev: network interface device structure
  **/
@@ -171,11 +194,7 @@ static void i40evf_tx_timeout(struct net
 	struct i40evf_adapter *adapter = netdev_priv(netdev);
 
 	adapter->tx_timeout_count++;
-	if (!(adapter->flags & (I40EVF_FLAG_RESET_PENDING |
-				I40EVF_FLAG_RESET_NEEDED))) {
-		adapter->flags |= I40EVF_FLAG_RESET_NEEDED;
-		schedule_work(&adapter->reset_task);
-	}
+	i40evf_schedule_reset(adapter);
 }
 
 /**
@@ -259,7 +278,7 @@ static void i40evf_fire_sw_int(struct i4
 {
 	struct i40e_hw *hw = &adapter->hw;
 	int i;
-	uint32_t dyn_ctl;
+	u32 dyn_ctl;
 
 	if (mask & 1) {
 		dyn_ctl = rd32(hw, I40E_VFINT_DYN_CTL01);
@@ -307,10 +326,9 @@ static irqreturn_t i40evf_msix_aq(int ir
 	struct i40e_hw *hw = &adapter->hw;
 	u32 val;
 
-	/* handle non-queue interrupts */
-	rd32(hw, I40E_VFINT_ICR01);
-	rd32(hw, I40E_VFINT_ICR0_ENA1);
-
+	/* handle non-queue interrupts, these reads clear the registers */
+	val = rd32(hw, I40E_VFINT_ICR01);
+	val = rd32(hw, I40E_VFINT_ICR0_ENA1);
 
 	val = rd32(hw, I40E_VFINT_DYN_CTL01) |
 	      I40E_VFINT_DYN_CTL01_CLEARPBA_MASK;
@@ -348,8 +366,8 @@ static irqreturn_t i40evf_msix_clean_rin
 static void
 i40evf_map_vector_to_rxq(struct i40evf_adapter *adapter, int v_idx, int r_idx)
 {
-	struct i40e_q_vector *q_vector = adapter->q_vector[v_idx];
-	struct i40e_ring *rx_ring = adapter->rx_rings[r_idx];
+	struct i40e_q_vector *q_vector = &adapter->q_vectors[v_idx];
+	struct i40e_ring *rx_ring = &adapter->rx_rings[r_idx];
 
 	rx_ring->q_vector = q_vector;
 	rx_ring->next = q_vector->rx.ring;
@@ -369,8 +387,8 @@ i40evf_map_vector_to_rxq(struct i40evf_a
 static void
 i40evf_map_vector_to_txq(struct i40evf_adapter *adapter, int v_idx, int t_idx)
 {
-	struct i40e_q_vector *q_vector = adapter->q_vector[v_idx];
-	struct i40e_ring *tx_ring = adapter->tx_rings[t_idx];
+	struct i40e_q_vector *q_vector = &adapter->q_vectors[v_idx];
+	struct i40e_ring *tx_ring = &adapter->tx_rings[t_idx];
 
 	tx_ring->q_vector = q_vector;
 	tx_ring->next = q_vector->tx.ring;
@@ -465,7 +483,7 @@ static void i40evf_netpoll(struct net_de
 		return;
 
 	for (i = 0; i < q_vectors; i++)
-		i40evf_msix_clean_rings(0, adapter->q_vector[i]);
+		i40evf_msix_clean_rings(0, &adapter->q_vectors[i]);
 }
 
 #endif
@@ -487,7 +505,7 @@ i40evf_request_traffic_irqs(struct i40ev
 	q_vectors = adapter->num_msix_vectors - NONQ_VECS;
 
 	for (vector = 0; vector < q_vectors; vector++) {
-		struct i40e_q_vector *q_vector = adapter->q_vector[vector];
+		struct i40e_q_vector *q_vector = &adapter->q_vectors[vector];
 
 		if (q_vector->tx.ring && q_vector->rx.ring) {
 			snprintf(q_vector->name, sizeof(q_vector->name) - 1,
@@ -532,7 +550,7 @@ free_queue_irqs:
 			adapter->msix_entries[vector + NONQ_VECS].vector,
 			NULL);
 		free_irq(adapter->msix_entries[vector + NONQ_VECS].vector,
-			 adapter->q_vector[vector]);
+			 &adapter->q_vectors[vector]);
 	}
 	return err;
 }
@@ -582,7 +600,7 @@ static void i40evf_free_traffic_irqs(str
 		irq_set_affinity_hint(adapter->msix_entries[i+1].vector,
 				      NULL);
 		free_irq(adapter->msix_entries[i+1].vector,
-			 adapter->q_vector[i]);
+			 &adapter->q_vectors[i]);
 	}
 }
 
@@ -611,7 +629,7 @@ static void i40evf_configure_tx(struct i
 	int i;
 
 	for (i = 0; i < adapter->num_active_queues; i++)
-		adapter->tx_rings[i]->tail = hw->hw_addr + I40E_QTX_TAIL1(i);
+		adapter->tx_rings[i].tail = hw->hw_addr + I40E_QTX_TAIL1(i);
 }
 
 /**
@@ -629,35 +647,22 @@ static void i40evf_configure_rx(struct i
 	int rx_buf_len;
 
 
-	adapter->flags &= ~I40EVF_FLAG_RX_PS_CAPABLE;
-	adapter->flags |= I40EVF_FLAG_RX_1BUF_CAPABLE;
-
-	/* Decide whether to use packet split mode or not */
-	if (netdev->mtu > ETH_DATA_LEN) {
-		if (adapter->flags & I40EVF_FLAG_RX_PS_CAPABLE)
-			adapter->flags |= I40EVF_FLAG_RX_PS_ENABLED;
-		else
-			adapter->flags &= ~I40EVF_FLAG_RX_PS_ENABLED;
-	} else {
-		if (adapter->flags & I40EVF_FLAG_RX_1BUF_CAPABLE)
-			adapter->flags &= ~I40EVF_FLAG_RX_PS_ENABLED;
-		else
-			adapter->flags |= I40EVF_FLAG_RX_PS_ENABLED;
-	}
-
 	/* Set the RX buffer length according to the mode */
-	if (adapter->flags & I40EVF_FLAG_RX_PS_ENABLED) {
-		rx_buf_len = I40E_RX_HDR_SIZE;
-	} else {
-		if (netdev->mtu <= ETH_DATA_LEN)
-			rx_buf_len = I40EVF_RXBUFFER_2048;
-		else
-			rx_buf_len = ALIGN(max_frame, 1024);
-	}
+	if (adapter->flags & I40EVF_FLAG_RX_PS_ENABLED ||
+	    netdev->mtu <= ETH_DATA_LEN)
+		rx_buf_len = I40EVF_RXBUFFER_2048;
+	else
+		rx_buf_len = ALIGN(max_frame, 1024);
 
 	for (i = 0; i < adapter->num_active_queues; i++) {
-		adapter->rx_rings[i]->tail = hw->hw_addr + I40E_QRX_TAIL1(i);
-		adapter->rx_rings[i]->rx_buf_len = rx_buf_len;
+		adapter->rx_rings[i].tail = hw->hw_addr + I40E_QRX_TAIL1(i);
+		adapter->rx_rings[i].rx_buf_len = rx_buf_len;
+		if (adapter->flags & I40EVF_FLAG_RX_PS_ENABLED) {
+			set_ring_ps_enabled(&adapter->rx_rings[i]);
+			adapter->rx_rings[i].rx_hdr_len = I40E_RX_HDR_SIZE;
+		} else {
+			clear_ring_ps_enabled(&adapter->rx_rings[i]);
+		}
 	}
 }
 
@@ -954,7 +959,7 @@ static void i40evf_napi_enable_all(struc
 	for (q_idx = 0; q_idx < q_vectors; q_idx++) {
 		struct napi_struct *napi;
 
-		q_vector = adapter->q_vector[q_idx];
+		q_vector = &adapter->q_vectors[q_idx];
 		napi = &q_vector->napi;
 		napi_enable(napi);
 	}
@@ -971,7 +976,7 @@ static void i40evf_napi_disable_all(stru
 	int q_vectors = adapter->num_msix_vectors - NONQ_VECS;
 
 	for (q_idx = 0; q_idx < q_vectors; q_idx++) {
-		q_vector = adapter->q_vector[q_idx];
+		q_vector = &adapter->q_vectors[q_idx];
 		napi_disable(&q_vector->napi);
 	}
 }
@@ -992,9 +997,14 @@ static void i40evf_configure(struct i40e
 	adapter->aq_required |= I40EVF_FLAG_AQ_CONFIGURE_QUEUES;
 
 	for (i = 0; i < adapter->num_active_queues; i++) {
-		struct i40e_ring *ring = adapter->rx_rings[i];
+		struct i40e_ring *ring = &adapter->rx_rings[i];
 
+	if (adapter->flags & I40EVF_FLAG_RX_PS_ENABLED) {
+		i40evf_alloc_rx_headers(ring);
+		i40evf_alloc_rx_buffers_ps(ring, ring->count);
+	} else {
 		i40evf_alloc_rx_buffers_1buf(ring, ring->count);
+	}
 		ring->next_to_use = ring->count - 1;
 		writel(ring->next_to_use, ring->tail);
 	}
@@ -1025,7 +1035,7 @@ void i40evf_down(struct i40evf_adapter *
 	struct net_device *netdev = adapter->netdev;
 	struct i40evf_mac_filter *f;
 
-	if (adapter->state == __I40EVF_DOWN)
+	if (adapter->state <= __I40EVF_DOWN_PENDING)
 		return;
 
 	while (test_and_set_bit(__I40EVF_IN_CRITICAL_TASK,
@@ -1112,16 +1122,12 @@ i40evf_acquire_msix_vectors(struct i40ev
  **/
 static void i40evf_free_queues(struct i40evf_adapter *adapter)
 {
-	int i;
-
 	if (!adapter->vsi_res)
 		return;
-	for (i = 0; i < adapter->num_active_queues; i++) {
-		if (adapter->tx_rings[i])
-			kfree_rcu(adapter->tx_rings[i], rcu);
-		adapter->tx_rings[i] = NULL;
-		adapter->rx_rings[i] = NULL;
-	}
+	kfree(adapter->tx_rings);
+	adapter->tx_rings = NULL;
+	kfree(adapter->rx_rings);
+	adapter->rx_rings = NULL;
 }
 
 /**
@@ -1136,13 +1142,20 @@ static int i40evf_alloc_queues(struct i4
 {
 	int i;
 
+	adapter->tx_rings = kcalloc(adapter->num_active_queues,
+				    sizeof(struct i40e_ring), GFP_KERNEL);
+	if (!adapter->tx_rings)
+		goto err_out;
+	adapter->rx_rings = kcalloc(adapter->num_active_queues,
+				    sizeof(struct i40e_ring), GFP_KERNEL);
+	if (!adapter->rx_rings)
+		goto err_out;
+
 	for (i = 0; i < adapter->num_active_queues; i++) {
 		struct i40e_ring *tx_ring;
 		struct i40e_ring *rx_ring;
 
-		tx_ring = kzalloc(sizeof(*tx_ring) * 2, GFP_KERNEL);
-		if (!tx_ring)
-			goto err_out;
+		tx_ring = &adapter->tx_rings[i];
 
 		tx_ring->queue_index = i;
 		tx_ring->netdev = adapter->netdev;
@@ -1150,14 +1163,12 @@ static int i40evf_alloc_queues(struct i4
 		tx_ring->count = adapter->tx_desc_count;
 		if (adapter->flags & I40E_FLAG_WB_ON_ITR_CAPABLE)
 			tx_ring->flags |= I40E_TXR_FLAGS_WB_ON_ITR;
-		adapter->tx_rings[i] = tx_ring;
 
-		rx_ring = &tx_ring[1];
+		rx_ring = &adapter->rx_rings[i];
 		rx_ring->queue_index = i;
 		rx_ring->netdev = adapter->netdev;
 		rx_ring->dev = &adapter->pdev->dev;
 		rx_ring->count = adapter->rx_desc_count;
-		adapter->rx_rings[i] = rx_ring;
 	}
 
 	return 0;
@@ -1207,115 +1218,277 @@ static int i40evf_set_interrupt_capabili
 	err = i40evf_acquire_msix_vectors(adapter, v_budget);
 
 out:
-	adapter->netdev->real_num_tx_queues = pairs;
+	netif_set_real_num_rx_queues(adapter->netdev, pairs);
+	netif_set_real_num_tx_queues(adapter->netdev, pairs);
 	return err;
 }
 
 /**
- * i40e_configure_rss_aq - Prepare for RSS using AQ commands
+ * i40e_config_rss_aq - Prepare for RSS using AQ commands
  * @vsi: vsi structure
  * @seed: RSS hash seed
+ * @lut: Lookup table
+ * @lut_size: Lookup table size
+ *
+ * Return 0 on success, negative on failure
  **/
-static void i40evf_configure_rss_aq(struct i40e_vsi *vsi, const u8 *seed)
+static int i40evf_config_rss_aq(struct i40e_vsi *vsi, const u8 *seed,
+				u8 *lut, u16 lut_size)
 {
-	struct i40e_aqc_get_set_rss_key_data rss_key;
 	struct i40evf_adapter *adapter = vsi->back;
 	struct i40e_hw *hw = &adapter->hw;
-	int ret = 0, i;
-	u8 *rss_lut;
+	int ret = 0;
 
 	if (!vsi->id)
-		return;
+		return -EINVAL;
 
 	if (adapter->current_op != I40E_VIRTCHNL_OP_UNKNOWN) {
 		/* bail because we already have a command pending */
 		dev_err(&adapter->pdev->dev, "Cannot confiure RSS, command %d pending\n",
 			adapter->current_op);
-		return;
+		return -EBUSY;
 	}
 
-	memset(&rss_key, 0, sizeof(rss_key));
-	memcpy(&rss_key, seed, sizeof(rss_key));
+	if (seed) {
+		struct i40e_aqc_get_set_rss_key_data *rss_key =
+			(struct i40e_aqc_get_set_rss_key_data *)seed;
+		ret = i40evf_aq_set_rss_key(hw, vsi->id, rss_key);
+		if (ret) {
+			dev_err(&adapter->pdev->dev, "Cannot set RSS key, err %s aq_err %s\n",
+				i40evf_stat_str(hw, ret),
+				i40evf_aq_str(hw, hw->aq.asq_last_status));
+			return ret;
+		}
+	}
 
-	rss_lut = kzalloc(((I40E_VFQF_HLUT_MAX_INDEX + 1) * 4), GFP_KERNEL);
-	if (!rss_lut)
-		return;
+	if (lut) {
+		ret = i40evf_aq_set_rss_lut(hw, vsi->id, false, lut, lut_size);
+		if (ret) {
+			dev_err(&adapter->pdev->dev,
+				"Cannot set RSS lut, err %s aq_err %s\n",
+				i40evf_stat_str(hw, ret),
+				i40evf_aq_str(hw, hw->aq.asq_last_status));
+			return ret;
+		}
+	}
 
-	/* Populate the LUT with max no. PF queues in round robin fashion */
-	for (i = 0; i <= (I40E_VFQF_HLUT_MAX_INDEX * 4); i++)
-		rss_lut[i] = i % adapter->num_active_queues;
+	return ret;
+}
 
-	ret = i40evf_aq_set_rss_key(hw, vsi->id, &rss_key);
-	if (ret) {
-		dev_err(&adapter->pdev->dev,
-			"Cannot set RSS key, err %s aq_err %s\n",
-			i40evf_stat_str(hw, ret),
-			i40evf_aq_str(hw, hw->aq.asq_last_status));
-		return;
+/**
+ * i40evf_config_rss_reg - Configure RSS keys and lut by writing registers
+ * @vsi: Pointer to vsi structure
+ * @seed: RSS hash seed
+ * @lut: Lookup table
+ * @lut_size: Lookup table size
+ *
+ * Returns 0 on success, negative on failure
+ **/
+static int i40evf_config_rss_reg(struct i40e_vsi *vsi, const u8 *seed,
+				 const u8 *lut, u16 lut_size)
+{
+	struct i40evf_adapter *adapter = vsi->back;
+	struct i40e_hw *hw = &adapter->hw;
+	u16 i;
+
+	if (seed) {
+		u32 *seed_dw = (u32 *)seed;
+
+		for (i = 0; i <= I40E_VFQF_HKEY_MAX_INDEX; i++)
+			wr32(hw, I40E_VFQF_HKEY(i), seed_dw[i]);
 	}
 
-	ret = i40evf_aq_set_rss_lut(hw, vsi->id, false, rss_lut,
-				    (I40E_VFQF_HLUT_MAX_INDEX + 1) * 4);
-	if (ret)
-		dev_err(&adapter->pdev->dev,
-			"Cannot set RSS lut, err %s aq_err %s\n",
-			i40evf_stat_str(hw, ret),
-			i40evf_aq_str(hw, hw->aq.asq_last_status));
+	if (lut) {
+		u32 *lut_dw = (u32 *)lut;
+
+		if (lut_size != I40EVF_HLUT_ARRAY_SIZE)
+			return -EINVAL;
+
+		for (i = 0; i <= I40E_VFQF_HLUT_MAX_INDEX; i++)
+			wr32(hw, I40E_VFQF_HLUT(i), lut_dw[i]);
+	}
+	i40e_flush(hw);
+
+	return 0;
 }
 
 /**
- * i40e_configure_rss_reg - Prepare for RSS if used
- * @adapter: board private structure
- * @seed: RSS hash seed
+ *  * i40evf_get_rss_aq - Get RSS keys and lut by using AQ commands
+ *  @vsi: Pointer to vsi structure
+ *  @seed: RSS hash seed
+ *  @lut: Lookup table
+ *  @lut_size: Lookup table size
+ *
+ *  Return 0 on success, negative on failure
  **/
-static void i40evf_configure_rss_reg(struct i40evf_adapter *adapter,
-				     const u8 *seed)
+static int i40evf_get_rss_aq(struct i40e_vsi *vsi, const u8 *seed,
+			     u8 *lut, u16 lut_size)
 {
+	struct i40evf_adapter *adapter = vsi->back;
 	struct i40e_hw *hw = &adapter->hw;
-	u32 *seed_dw = (u32 *)seed;
-	u32 cqueue = 0;
-	u32 lut = 0;
-	int i, j;
+	int ret = 0;
 
-	/* Fill out hash function seed */
-	for (i = 0; i <= I40E_VFQF_HKEY_MAX_INDEX; i++)
-		wr32(hw, I40E_VFQF_HKEY(i), seed_dw[i]);
-
-	/* Populate the LUT with max no. PF queues in round robin fashion */
-	for (i = 0; i <= I40E_VFQF_HLUT_MAX_INDEX; i++) {
-		lut = 0;
-		for (j = 0; j < 4; j++) {
-			if (cqueue == adapter->num_active_queues)
-				cqueue = 0;
-			lut |= ((cqueue) << (8 * j));
-			cqueue++;
+	if (seed) {
+		ret = i40evf_aq_get_rss_key(hw, vsi->id,
+			(struct i40e_aqc_get_set_rss_key_data *)seed);
+		if (ret) {
+			dev_err(&adapter->pdev->dev,
+				"Cannot get RSS key, err %s aq_err %s\n",
+				i40evf_stat_str(hw, ret),
+				i40evf_aq_str(hw, hw->aq.asq_last_status));
+			return ret;
 		}
-		wr32(hw, I40E_VFQF_HLUT(i), lut);
 	}
-	i40e_flush(hw);
+
+	if (lut) {
+		ret = i40evf_aq_get_rss_lut(hw, vsi->id, seed, lut, lut_size);
+		if (ret) {
+			dev_err(&adapter->pdev->dev,
+				"Cannot get RSS lut, err %s aq_err %s\n",
+				i40evf_stat_str(hw, ret),
+				i40evf_aq_str(hw, hw->aq.asq_last_status));
+			return ret;
+		}
+	}
+
+	return ret;
 }
 
 /**
- * i40evf_configure_rss - Prepare for RSS
+ *  * i40evf_get_rss_reg - Get RSS keys and lut by reading registers
+ *  @vsi: Pointer to vsi structure
+ *  @seed: RSS hash seed
+ *  @lut: Lookup table
+ *  @lut_size: Lookup table size
+ *
+ *  Returns 0 on success, negative on failure
+ **/
+static int i40evf_get_rss_reg(struct i40e_vsi *vsi, const u8 *seed,
+			      const u8 *lut, u16 lut_size)
+{
+	struct i40evf_adapter *adapter = vsi->back;
+	struct i40e_hw *hw = &adapter->hw;
+	u16 i;
+
+	if (seed) {
+		u32 *seed_dw = (u32 *)seed;
+
+		for (i = 0; i <= I40E_VFQF_HKEY_MAX_INDEX; i++)
+			seed_dw[i] = rd32(hw, I40E_VFQF_HKEY(i));
+	}
+
+	if (lut) {
+		u32 *lut_dw = (u32 *)lut;
+
+		if (lut_size != I40EVF_HLUT_ARRAY_SIZE)
+			return -EINVAL;
+
+		for (i = 0; i <= I40E_VFQF_HLUT_MAX_INDEX; i++)
+			lut_dw[i] = rd32(hw, I40E_VFQF_HLUT(i));
+	}
+
+	return 0;
+}
+
+/**
+ * i40evf_config_rss - Configure RSS keys and lut
+ * @vsi: Pointer to vsi structure
+ * @seed: RSS hash seed
+ * @lut: Lookup table
+ * @lut_size: Lookup table size
+ *
+ * Returns 0 on success, negative on failure
+ **/
+int i40evf_config_rss(struct i40e_vsi *vsi, const u8 *seed,
+		      u8 *lut, u16 lut_size)
+{
+	struct i40evf_adapter *adapter = vsi->back;
+
+	if (RSS_AQ(adapter))
+		return i40evf_config_rss_aq(vsi, seed, lut, lut_size);
+	else
+		return i40evf_config_rss_reg(vsi, seed, lut, lut_size);
+}
+
+/**
+ * i40evf_get_rss - Get RSS keys and lut
+ * @vsi: Pointer to vsi structure
+ * @seed: RSS hash seed
+ * @lut: Lookup table
+ * @lut_size: Lookup table size
+ *
+ * Returns 0 on success, negative on failure
+ **/
+int i40evf_get_rss(struct i40e_vsi *vsi, const u8 *seed, u8 *lut, u16 lut_size)
+{
+	struct i40evf_adapter *adapter = vsi->back;
+
+	if (RSS_AQ(adapter))
+		return i40evf_get_rss_aq(vsi, seed, lut, lut_size);
+	else
+		return i40evf_get_rss_reg(vsi, seed, lut, lut_size);
+}
+
+/**
+ * i40evf_fill_rss_lut - Fill the lut with default values
+ * @lut: Lookup table to be filled with
+ * @rss_table_size: Lookup table size
+ * @rss_size: Range of queue number for hashing
+ **/
+static void i40evf_fill_rss_lut(u8 *lut, u16 rss_table_size, u16 rss_size)
+{
+	u16 i;
+
+	for (i = 0; i < rss_table_size; i++)
+		lut[i] = i % rss_size;
+}
+
+/**
+ * i40evf_init_rss - Prepare for RSS
  * @adapter: board private structure
+ *
+ * Return 0 on success, negative on failure
  **/
-static void i40evf_configure_rss(struct i40evf_adapter *adapter)
+static int i40evf_init_rss(struct i40evf_adapter *adapter)
 {
+	struct i40e_vsi *vsi = &adapter->vsi;
 	struct i40e_hw *hw = &adapter->hw;
 	u8 seed[I40EVF_HKEY_ARRAY_SIZE];
 	u64 hena;
-
-	netdev_rss_key_fill((void *)seed, I40EVF_HKEY_ARRAY_SIZE);
+	u8 *lut;
+	int ret;
 
 	/* Enable PCTYPES for RSS, TCP/UDP with IPv4/IPv6 */
-	hena = I40E_DEFAULT_RSS_HENA;
+	if (adapter->vf_res->vf_offload_flags &
+					I40E_VIRTCHNL_VF_OFFLOAD_RSS_PCTYPE_V2)
+		hena = I40E_DEFAULT_RSS_HENA_EXPANDED;
+	else
+		hena = I40E_DEFAULT_RSS_HENA;
 	wr32(hw, I40E_VFQF_HENA(0), (u32)hena);
 	wr32(hw, I40E_VFQF_HENA(1), (u32)(hena >> 32));
 
-	if (RSS_AQ(adapter))
-		i40evf_configure_rss_aq(&adapter->vsi, seed);
+	lut = kzalloc(I40EVF_HLUT_ARRAY_SIZE, GFP_KERNEL);
+	if (!lut)
+		return -ENOMEM;
+
+	/* Use user configured lut if there is one, otherwise use default */
+	if (vsi->rss_lut_user)
+		memcpy(lut, vsi->rss_lut_user, I40EVF_HLUT_ARRAY_SIZE);
 	else
-		i40evf_configure_rss_reg(adapter, seed);
+		i40evf_fill_rss_lut(lut, I40EVF_HLUT_ARRAY_SIZE,
+				    adapter->num_active_queues);
+
+	/* Use user configured hash key if there is one, otherwise
+	 * user default.
+	 */
+	if (vsi->rss_hkey_user)
+		memcpy(seed, vsi->rss_hkey_user, I40EVF_HKEY_ARRAY_SIZE);
+	else
+		netdev_rss_key_fill((void *)seed, I40EVF_HKEY_ARRAY_SIZE);
+	ret = i40evf_config_rss(vsi, seed, lut, I40EVF_HLUT_ARRAY_SIZE);
+	kfree(lut);
+
+	return ret;
 }
 
 /**
@@ -1327,21 +1500,22 @@ static void i40evf_configure_rss(struct
  **/
 static int i40evf_alloc_q_vectors(struct i40evf_adapter *adapter)
 {
-	int q_idx, num_q_vectors;
+	int q_idx = 0, num_q_vectors;
 	struct i40e_q_vector *q_vector;
 
 	num_q_vectors = adapter->num_msix_vectors - NONQ_VECS;
+	adapter->q_vectors = kcalloc(num_q_vectors, sizeof(*q_vector),
+				     GFP_KERNEL);
+	if (!adapter->q_vectors)
+		goto err_out;
 
 	for (q_idx = 0; q_idx < num_q_vectors; q_idx++) {
-		q_vector = kzalloc(sizeof(*q_vector), GFP_KERNEL);
-		if (!q_vector)
-			goto err_out;
+		q_vector = &adapter->q_vectors[q_idx];
 		q_vector->adapter = adapter;
 		q_vector->vsi = &adapter->vsi;
 		q_vector->v_idx = q_idx;
 		netif_napi_add(adapter->netdev, &q_vector->napi,
 			       i40evf_napi_poll, NAPI_POLL_WEIGHT);
-		adapter->q_vector[q_idx] = q_vector;
 	}
 
 	return 0;
@@ -1349,11 +1523,10 @@ static int i40evf_alloc_q_vectors(struct
 err_out:
 	while (q_idx) {
 		q_idx--;
-		q_vector = adapter->q_vector[q_idx];
+		q_vector = &adapter->q_vectors[q_idx];
 		netif_napi_del(&q_vector->napi);
-		kfree(q_vector);
-		adapter->q_vector[q_idx] = NULL;
 	}
+	kfree(adapter->q_vectors);
 	return -ENOMEM;
 }
 
@@ -1374,13 +1547,11 @@ static void i40evf_free_q_vectors(struct
 	napi_vectors = adapter->num_active_queues;
 
 	for (q_idx = 0; q_idx < num_q_vectors; q_idx++) {
-		struct i40e_q_vector *q_vector = adapter->q_vector[q_idx];
-
-		adapter->q_vector[q_idx] = NULL;
+		struct i40e_q_vector *q_vector = &adapter->q_vectors[q_idx];
 		if (q_idx < napi_vectors)
 			netif_napi_del(&q_vector->napi);
-		kfree(q_vector);
 	}
+	kfree(adapter->q_vectors);
 }
 
 /**
@@ -1439,6 +1610,22 @@ err_set_interrupt:
 }
 
 /**
+ * i40evf_clear_rss_config_user - Clear user configurations of RSS
+ * @vsi: Pointer to VSI structure
+ **/
+static void i40evf_clear_rss_config_user(struct i40e_vsi *vsi)
+{
+	if (!vsi)
+		return;
+
+	kfree(vsi->rss_hkey_user);
+	vsi->rss_hkey_user = NULL;
+
+	kfree(vsi->rss_lut_user);
+	vsi->rss_lut_user = NULL;
+}
+
+/**
  * i40evf_watchdog_timer - Periodic call-back timer
  * @data: pointer to adapter disguised as unsigned long
  **/
@@ -1565,7 +1752,7 @@ static void i40evf_watchdog_task(struct
 		 * PF, so we don't have to set current_op as we will
 		 * not get a response through the ARQ.
 		 */
-		i40evf_configure_rss(adapter);
+		i40evf_init_rss(adapter);
 		adapter->aq_required &= ~I40EVF_FLAG_AQ_CONFIGURE_RSS;
 		goto watchdog_done;
 	}
@@ -1651,6 +1838,7 @@ static void i40evf_reset_task(struct wor
 			break;
 		msleep(I40EVF_RESET_WAIT_MS);
 	}
+	pci_set_master(adapter->pdev);
 	/* extra wait to make sure minimum wait is met */
 	msleep(I40EVF_RESET_WAIT_MS);
 	if (i == I40EVF_RESET_WAIT_COUNT) {
@@ -1695,6 +1883,7 @@ static void i40evf_reset_task(struct wor
 		adapter->netdev->flags &= ~IFF_UP;
 		clear_bit(__I40EVF_IN_CRITICAL_TASK, &adapter->crit_section);
 		adapter->flags &= ~I40EVF_FLAG_RESET_PENDING;
+		adapter->state = __I40EVF_DOWN;
 		dev_info(&adapter->pdev->dev, "Reset task did not complete, VF disabled\n");
 		return; /* Do not attempt to reinit. It's dead, Jim. */
 	}
@@ -1864,9 +2053,12 @@ void i40evf_free_all_tx_resources(struct
 {
 	int i;
 
+	if (!adapter->tx_rings)
+		return;
+
 	for (i = 0; i < adapter->num_active_queues; i++)
-		if (adapter->tx_rings[i]->desc)
-			i40evf_free_tx_resources(adapter->tx_rings[i]);
+		if (adapter->tx_rings[i].desc)
+			i40evf_free_tx_resources(&adapter->tx_rings[i]);
 }
 
 /**
@@ -1884,8 +2076,8 @@ static int i40evf_setup_all_tx_resources
 	int i, err = 0;
 
 	for (i = 0; i < adapter->num_active_queues; i++) {
-		adapter->tx_rings[i]->count = adapter->tx_desc_count;
-		err = i40evf_setup_tx_descriptors(adapter->tx_rings[i]);
+		adapter->tx_rings[i].count = adapter->tx_desc_count;
+		err = i40evf_setup_tx_descriptors(&adapter->tx_rings[i]);
 		if (!err)
 			continue;
 		dev_err(&adapter->pdev->dev,
@@ -1911,8 +2103,8 @@ static int i40evf_setup_all_rx_resources
 	int i, err = 0;
 
 	for (i = 0; i < adapter->num_active_queues; i++) {
-		adapter->rx_rings[i]->count = adapter->rx_desc_count;
-		err = i40evf_setup_rx_descriptors(adapter->rx_rings[i]);
+		adapter->rx_rings[i].count = adapter->rx_desc_count;
+		err = i40evf_setup_rx_descriptors(&adapter->rx_rings[i]);
 		if (!err)
 			continue;
 		dev_err(&adapter->pdev->dev,
@@ -1932,9 +2124,12 @@ void i40evf_free_all_rx_resources(struct
 {
 	int i;
 
+	if (!adapter->rx_rings)
+		return;
+
 	for (i = 0; i < adapter->num_active_queues; i++)
-		if (adapter->rx_rings[i]->desc)
-			i40evf_free_rx_resources(adapter->rx_rings[i]);
+		if (adapter->rx_rings[i].desc)
+			i40evf_free_rx_resources(&adapter->rx_rings[i]);
 }
 
 /**
@@ -1958,7 +2153,8 @@ static int i40evf_open(struct net_device
 		dev_err(&adapter->pdev->dev, "Unable to open device due to PF driver failure.\n");
 		return -EIO;
 	}
-	if (adapter->state != __I40EVF_DOWN || adapter->aq_required)
+
+	if (adapter->state != __I40EVF_DOWN)
 		return -EBUSY;
 
 	/* allocate transmit descriptors */
@@ -2013,14 +2209,14 @@ static int i40evf_close(struct net_devic
 {
 	struct i40evf_adapter *adapter = netdev_priv(netdev);
 
-	if (adapter->state <= __I40EVF_DOWN)
+	if (adapter->state <= __I40EVF_DOWN_PENDING)
 		return 0;
 
 
 	set_bit(__I40E_DOWN, &adapter->vsi.state);
 
 	i40evf_down(adapter);
-	adapter->state = __I40EVF_DOWN;
+	adapter->state = __I40EVF_DOWN_PENDING;
 	i40evf_free_traffic_irqs(adapter);
 
 	return 0;
@@ -2137,13 +2333,28 @@ int i40evf_process_config(struct i40evf_
 	netdev->features |= NETIF_F_HIGHDMA |
 			    NETIF_F_SG |
 			    NETIF_F_IP_CSUM |
-			    NETIF_F_SCTP_CSUM |
+			    NETIF_F_SCTP_CRC |
 			    NETIF_F_IPV6_CSUM |
 			    NETIF_F_TSO |
 			    NETIF_F_TSO6 |
+			    NETIF_F_TSO_ECN |
+			    NETIF_F_GSO_GRE	       |
+			    NETIF_F_GSO_UDP_TUNNEL |
 			    NETIF_F_RXCSUM |
 			    NETIF_F_GRO;
 
+	netdev->hw_enc_features |= NETIF_F_IP_CSUM	       |
+				   NETIF_F_IPV6_CSUM	       |
+				   NETIF_F_TSO		       |
+				   NETIF_F_TSO6		       |
+				   NETIF_F_TSO_ECN	       |
+				   NETIF_F_GSO_GRE	       |
+				   NETIF_F_GSO_UDP_TUNNEL      |
+				   NETIF_F_GSO_UDP_TUNNEL_CSUM;
+
+	if (adapter->flags & I40EVF_FLAG_OUTER_UDP_CSUM_CAPABLE)
+		netdev->features |= NETIF_F_GSO_UDP_TUNNEL_CSUM;
+
 	/* copy netdev features into list of user selectable features */
 	netdev->hw_features |= netdev->features;
 	netdev->hw_features &= ~NETIF_F_RXCSUM;
@@ -2263,6 +2474,14 @@ static void i40evf_init_task(struct work
 		if (err == I40E_ERR_ADMIN_QUEUE_NO_WORK) {
 			err = i40evf_send_vf_config_msg(adapter);
 			goto err;
+		} else if (err == I40E_ERR_PARAM) {
+			/* We only get ERR_PARAM if the device is in a very bad
+			 * state or if we've been disabled for previous bad
+			 * behavior. Either way, we're done now.
+			 */
+			i40evf_shutdown_adminq(hw);
+			dev_err(&pdev->dev, "Unable to get VF config due to PF error condition, not retrying\n");
+			return;
 		}
 		if (err) {
 			dev_err(&pdev->dev, "Unable to get VF config (%d)\n",
@@ -2274,11 +2493,20 @@ static void i40evf_init_task(struct work
 	default:
 		goto err_alloc;
 	}
+
+	if (hw->mac.type == I40E_MAC_X722_VF)
+		adapter->flags |= I40EVF_FLAG_OUTER_UDP_CSUM_CAPABLE;
+
 	if (i40evf_process_config(adapter))
 		goto err_alloc;
 	adapter->current_op = I40E_VIRTCHNL_OP_UNKNOWN;
 
 	adapter->flags |= I40EVF_FLAG_RX_CSUM_ENABLED;
+	adapter->flags |= I40EVF_FLAG_RX_1BUF_CAPABLE;
+	adapter->flags |= I40EVF_FLAG_RX_PS_CAPABLE;
+
+	/* Default to single buffer rx, can be changed through ethtool. */
+	adapter->flags &= ~I40EVF_FLAG_RX_PS_ENABLED;
 
 	netdev->netdev_ops = &i40evf_netdev_ops;
 	i40evf_set_ethtool_ops(netdev);
@@ -2310,10 +2538,9 @@ static void i40evf_init_task(struct work
 		goto err_sw_init;
 	i40evf_map_rings_to_vectors(adapter);
 	if (adapter->vf_res->vf_offload_flags &
-		    I40E_VIRTCHNL_VF_OFFLOAD_WB_ON_ITR)
+	    I40E_VIRTCHNL_VF_OFFLOAD_WB_ON_ITR)
 		adapter->flags |= I40EVF_FLAG_WB_ON_ITR_CAPABLE;
-	if (!RSS_AQ(adapter))
-		i40evf_configure_rss(adapter);
+
 	err = i40evf_request_misc_irq(adapter);
 	if (err)
 		goto err_sw_init;
@@ -2334,7 +2561,6 @@ static void i40evf_init_task(struct work
 	if (netdev->features & NETIF_F_GRO)
 		dev_info(&pdev->dev, "GRO is enabled\n");
 
-	dev_info(&pdev->dev, "%s\n", i40evf_driver_string);
 	adapter->state = __I40EVF_DOWN;
 	set_bit(__I40E_DOWN, &adapter->vsi.state);
 	i40evf_misc_irq_enable(adapter);
@@ -2343,7 +2569,7 @@ static void i40evf_init_task(struct work
 		adapter->aq_required |= I40EVF_FLAG_AQ_CONFIGURE_RSS;
 		mod_timer_pending(&adapter->watchdog_timer, jiffies + 1);
 	} else {
-		i40evf_configure_rss(adapter);
+		i40evf_init_rss(adapter);
 	}
 	return;
 restart:
@@ -2438,8 +2664,7 @@ static int i40evf_probe(struct pci_dev *
 
 	pci_set_master(pdev);
 
-	netdev = alloc_etherdev_mq(sizeof(struct i40evf_adapter),
-				   MAX_TX_QUEUES);
+	netdev = alloc_etherdev_mq(sizeof(struct i40evf_adapter), MAX_QUEUES);
 	if (!netdev) {
 		err = -ENOMEM;
 		goto err_alloc_etherdev;
@@ -2632,6 +2857,9 @@ static void i40evf_remove(struct pci_dev
 
 	flush_scheduled_work();
 
+	/* Clear user configurations for RSS */
+	i40evf_clear_rss_config_user(&adapter->vsi);
+
 	if (hw->aq.asq.count)
 		i40evf_shutdown_adminq(hw);
 
@@ -2692,6 +2920,11 @@ static int __init i40evf_init_module(voi
 
 	pr_info("%s\n", i40evf_copyright);
 
+	i40evf_wq = create_singlethread_workqueue(i40evf_driver_name);
+	if (!i40evf_wq) {
+		pr_err("%s: Failed to create workqueue\n", i40evf_driver_name);
+		return -ENOMEM;
+	}
 	ret = pci_register_driver(&i40evf_driver);
 	return ret;
 }
@@ -2707,6 +2940,7 @@ module_init(i40evf_init_module);
 static void __exit i40evf_exit_module(void)
 {
 	pci_unregister_driver(&i40evf_driver);
+	destroy_workqueue(i40evf_wq);
 }
 
 module_exit(i40evf_exit_module);
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/intel/i40evf/i40evf_virtchnl.c
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/intel/i40evf/i40evf_virtchnl.c
@@ -157,7 +157,9 @@ int i40evf_send_vf_config_msg(struct i40
 	       I40E_VIRTCHNL_VF_OFFLOAD_RSS_AQ |
 	       I40E_VIRTCHNL_VF_OFFLOAD_RSS_REG |
 	       I40E_VIRTCHNL_VF_OFFLOAD_VLAN |
-	       I40E_VIRTCHNL_VF_OFFLOAD_WB_ON_ITR;
+	       I40E_VIRTCHNL_VF_OFFLOAD_WB_ON_ITR |
+	       I40E_VIRTCHNL_VF_OFFLOAD_RSS_PCTYPE_V2;
+
 	adapter->current_op = I40E_VIRTCHNL_OP_GET_VF_RESOURCES;
 	adapter->aq_required &= ~I40EVF_FLAG_AQ_GET_CONFIG;
 	if (PF_IS_V11(adapter))
@@ -242,7 +244,7 @@ void i40evf_configure_queues(struct i40e
 	adapter->current_op = I40E_VIRTCHNL_OP_CONFIG_VSI_QUEUES;
 	len = sizeof(struct i40e_virtchnl_vsi_queue_config_info) +
 		       (sizeof(struct i40e_virtchnl_queue_pair_info) * pairs);
-	vqci = kzalloc(len, GFP_ATOMIC);
+	vqci = kzalloc(len, GFP_KERNEL);
 	if (!vqci)
 		return;
 
@@ -255,19 +257,23 @@ void i40evf_configure_queues(struct i40e
 	for (i = 0; i < pairs; i++) {
 		vqpi->txq.vsi_id = vqci->vsi_id;
 		vqpi->txq.queue_id = i;
-		vqpi->txq.ring_len = adapter->tx_rings[i]->count;
-		vqpi->txq.dma_ring_addr = adapter->tx_rings[i]->dma;
+		vqpi->txq.ring_len = adapter->tx_rings[i].count;
+		vqpi->txq.dma_ring_addr = adapter->tx_rings[i].dma;
 		vqpi->txq.headwb_enabled = 1;
 		vqpi->txq.dma_headwb_addr = vqpi->txq.dma_ring_addr +
 		    (vqpi->txq.ring_len * sizeof(struct i40e_tx_desc));
 
 		vqpi->rxq.vsi_id = vqci->vsi_id;
 		vqpi->rxq.queue_id = i;
-		vqpi->rxq.ring_len = adapter->rx_rings[i]->count;
-		vqpi->rxq.dma_ring_addr = adapter->rx_rings[i]->dma;
+		vqpi->rxq.ring_len = adapter->rx_rings[i].count;
+		vqpi->rxq.dma_ring_addr = adapter->rx_rings[i].dma;
 		vqpi->rxq.max_pkt_size = adapter->netdev->mtu
 					+ ETH_HLEN + VLAN_HLEN + ETH_FCS_LEN;
-		vqpi->rxq.databuffer_size = adapter->rx_rings[i]->rx_buf_len;
+		vqpi->rxq.databuffer_size = adapter->rx_rings[i].rx_buf_len;
+		if (adapter->flags & I40EVF_FLAG_RX_PS_ENABLED) {
+			vqpi->rxq.splithdr_enabled = true;
+			vqpi->rxq.hdr_size = I40E_RX_HDR_SIZE;
+		}
 		vqpi++;
 	}
 
@@ -353,14 +359,14 @@ void i40evf_map_queues(struct i40evf_ada
 	len = sizeof(struct i40e_virtchnl_irq_map_info) +
 	      (adapter->num_msix_vectors *
 		sizeof(struct i40e_virtchnl_vector_map));
-	vimi = kzalloc(len, GFP_ATOMIC);
+	vimi = kzalloc(len, GFP_KERNEL);
 	if (!vimi)
 		return;
 
 	vimi->num_vectors = adapter->num_msix_vectors;
 	/* Queue vectors first */
 	for (v_idx = 0; v_idx < q_vectors; v_idx++) {
-		q_vector = adapter->q_vector[v_idx];
+		q_vector = adapter->q_vectors + v_idx;
 		vimi->vecmap[v_idx].vsi_id = adapter->vsi_res->vsi_id;
 		vimi->vecmap[v_idx].vector_id = v_idx + NONQ_VECS;
 		vimi->vecmap[v_idx].txq_map = q_vector->ring_mask;
@@ -391,6 +397,7 @@ void i40evf_add_ether_addrs(struct i40ev
 	struct i40e_virtchnl_ether_addr_list *veal;
 	int len, i = 0, count = 0;
 	struct i40evf_mac_filter *f;
+	bool more = false;
 
 	if (adapter->current_op != I40E_VIRTCHNL_OP_UNKNOWN) {
 		/* bail because we already have a command pending */
@@ -415,10 +422,12 @@ void i40evf_add_ether_addrs(struct i40ev
 		count = (I40EVF_MAX_AQ_BUF_SIZE -
 			 sizeof(struct i40e_virtchnl_ether_addr_list)) /
 			sizeof(struct i40e_virtchnl_ether_addr);
-		len = I40EVF_MAX_AQ_BUF_SIZE;
+		len = sizeof(struct i40e_virtchnl_ether_addr_list) +
+		      (count * sizeof(struct i40e_virtchnl_ether_addr));
+		more = true;
 	}
 
-	veal = kzalloc(len, GFP_ATOMIC);
+	veal = kzalloc(len, GFP_KERNEL);
 	if (!veal)
 		return;
 
@@ -431,7 +440,8 @@ void i40evf_add_ether_addrs(struct i40ev
 			f->add = false;
 		}
 	}
-	adapter->aq_required &= ~I40EVF_FLAG_AQ_ADD_MAC_FILTER;
+	if (!more)
+		adapter->aq_required &= ~I40EVF_FLAG_AQ_ADD_MAC_FILTER;
 	i40evf_send_pf_msg(adapter, I40E_VIRTCHNL_OP_ADD_ETHER_ADDRESS,
 			   (u8 *)veal, len);
 	kfree(veal);
@@ -450,6 +460,7 @@ void i40evf_del_ether_addrs(struct i40ev
 	struct i40e_virtchnl_ether_addr_list *veal;
 	struct i40evf_mac_filter *f, *ftmp;
 	int len, i = 0, count = 0;
+	bool more = false;
 
 	if (adapter->current_op != I40E_VIRTCHNL_OP_UNKNOWN) {
 		/* bail because we already have a command pending */
@@ -474,9 +485,11 @@ void i40evf_del_ether_addrs(struct i40ev
 		count = (I40EVF_MAX_AQ_BUF_SIZE -
 			 sizeof(struct i40e_virtchnl_ether_addr_list)) /
 			sizeof(struct i40e_virtchnl_ether_addr);
-		len = I40EVF_MAX_AQ_BUF_SIZE;
+		len = sizeof(struct i40e_virtchnl_ether_addr_list) +
+		      (count * sizeof(struct i40e_virtchnl_ether_addr));
+		more = true;
 	}
-	veal = kzalloc(len, GFP_ATOMIC);
+	veal = kzalloc(len, GFP_KERNEL);
 	if (!veal)
 		return;
 
@@ -490,7 +503,8 @@ void i40evf_del_ether_addrs(struct i40ev
 			kfree(f);
 		}
 	}
-	adapter->aq_required &= ~I40EVF_FLAG_AQ_DEL_MAC_FILTER;
+	if (!more)
+		adapter->aq_required &= ~I40EVF_FLAG_AQ_DEL_MAC_FILTER;
 	i40evf_send_pf_msg(adapter, I40E_VIRTCHNL_OP_DEL_ETHER_ADDRESS,
 			   (u8 *)veal, len);
 	kfree(veal);
@@ -509,6 +523,7 @@ void i40evf_add_vlans(struct i40evf_adap
 	struct i40e_virtchnl_vlan_filter_list *vvfl;
 	int len, i = 0, count = 0;
 	struct i40evf_vlan_filter *f;
+	bool more = false;
 
 	if (adapter->current_op != I40E_VIRTCHNL_OP_UNKNOWN) {
 		/* bail because we already have a command pending */
@@ -534,9 +549,11 @@ void i40evf_add_vlans(struct i40evf_adap
 		count = (I40EVF_MAX_AQ_BUF_SIZE -
 			 sizeof(struct i40e_virtchnl_vlan_filter_list)) /
 			sizeof(u16);
-		len = I40EVF_MAX_AQ_BUF_SIZE;
+		len = sizeof(struct i40e_virtchnl_vlan_filter_list) +
+		      (count * sizeof(u16));
+		more = true;
 	}
-	vvfl = kzalloc(len, GFP_ATOMIC);
+	vvfl = kzalloc(len, GFP_KERNEL);
 	if (!vvfl)
 		return;
 
@@ -549,7 +566,8 @@ void i40evf_add_vlans(struct i40evf_adap
 			f->add = false;
 		}
 	}
-	adapter->aq_required &= ~I40EVF_FLAG_AQ_ADD_VLAN_FILTER;
+	if (!more)
+		adapter->aq_required &= ~I40EVF_FLAG_AQ_ADD_VLAN_FILTER;
 	i40evf_send_pf_msg(adapter, I40E_VIRTCHNL_OP_ADD_VLAN, (u8 *)vvfl, len);
 	kfree(vvfl);
 }
@@ -567,6 +585,7 @@ void i40evf_del_vlans(struct i40evf_adap
 	struct i40e_virtchnl_vlan_filter_list *vvfl;
 	struct i40evf_vlan_filter *f, *ftmp;
 	int len, i = 0, count = 0;
+	bool more = false;
 
 	if (adapter->current_op != I40E_VIRTCHNL_OP_UNKNOWN) {
 		/* bail because we already have a command pending */
@@ -592,9 +611,11 @@ void i40evf_del_vlans(struct i40evf_adap
 		count = (I40EVF_MAX_AQ_BUF_SIZE -
 			 sizeof(struct i40e_virtchnl_vlan_filter_list)) /
 			sizeof(u16);
-		len = I40EVF_MAX_AQ_BUF_SIZE;
+		len = sizeof(struct i40e_virtchnl_vlan_filter_list) +
+		      (count * sizeof(u16));
+		more = true;
 	}
-	vvfl = kzalloc(len, GFP_ATOMIC);
+	vvfl = kzalloc(len, GFP_KERNEL);
 	if (!vvfl)
 		return;
 
@@ -608,7 +629,8 @@ void i40evf_del_vlans(struct i40evf_adap
 			kfree(f);
 		}
 	}
-	adapter->aq_required &= ~I40EVF_FLAG_AQ_DEL_VLAN_FILTER;
+	if (!more)
+		adapter->aq_required &= ~I40EVF_FLAG_AQ_DEL_VLAN_FILTER;
 	i40evf_send_pf_msg(adapter, I40E_VIRTCHNL_OP_DEL_VLAN, (u8 *)vvfl, len);
 	kfree(vvfl);
 }
@@ -724,9 +746,29 @@ void i40evf_virtchnl_completion(struct i
 		return;
 	}
 	if (v_retval) {
-		dev_err(&adapter->pdev->dev, "PF returned error %d (%s) to our request %d\n",
-			v_retval, i40evf_stat_str(&adapter->hw, v_retval),
-			v_opcode);
+		switch (v_opcode) {
+		case I40E_VIRTCHNL_OP_ADD_VLAN:
+			dev_err(&adapter->pdev->dev, "Failed to add VLAN filter, error %s\n",
+				i40evf_stat_str(&adapter->hw, v_retval));
+			break;
+		case I40E_VIRTCHNL_OP_ADD_ETHER_ADDRESS:
+			dev_err(&adapter->pdev->dev, "Failed to add MAC filter, error %s\n",
+				i40evf_stat_str(&adapter->hw, v_retval));
+			break;
+		case I40E_VIRTCHNL_OP_DEL_VLAN:
+			dev_err(&adapter->pdev->dev, "Failed to delete VLAN filter, error %s\n",
+				i40evf_stat_str(&adapter->hw, v_retval));
+			break;
+		case I40E_VIRTCHNL_OP_DEL_ETHER_ADDRESS:
+			dev_err(&adapter->pdev->dev, "Failed to delete MAC filter, error %s\n",
+				i40evf_stat_str(&adapter->hw, v_retval));
+			break;
+		default:
+			dev_err(&adapter->pdev->dev, "PF returned error %d (%s) to our request %d\n",
+				v_retval,
+				i40evf_stat_str(&adapter->hw, v_retval),
+				v_opcode);
+		}
 	}
 	switch (v_opcode) {
 	case I40E_VIRTCHNL_OP_GET_STATS: {
@@ -766,6 +808,8 @@ void i40evf_virtchnl_completion(struct i
 	case I40E_VIRTCHNL_OP_DISABLE_QUEUES:
 		i40evf_free_all_tx_resources(adapter);
 		i40evf_free_all_rx_resources(adapter);
+		if (adapter->state == __I40EVF_DOWN_PENDING)
+			adapter->state = __I40EVF_DOWN;
 		break;
 	case I40E_VIRTCHNL_OP_VERSION:
 	case I40E_VIRTCHNL_OP_CONFIG_IRQ_MAP:
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/intel/igb/e1000_82575.c
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/intel/igb/e1000_82575.c
@@ -34,6 +34,7 @@
 #include "e1000_mac.h"
 #include "e1000_82575.h"
 #include "e1000_i210.h"
+#include "igb.h"
 
 static s32  igb_get_invariants_82575(struct e1000_hw *);
 static s32  igb_acquire_phy_82575(struct e1000_hw *);
@@ -45,8 +46,6 @@ static s32  igb_get_cfg_done_82575(struc
 static s32  igb_init_hw_82575(struct e1000_hw *);
 static s32  igb_phy_hw_reset_sgmii_82575(struct e1000_hw *);
 static s32  igb_read_phy_reg_sgmii_82575(struct e1000_hw *, u32, u16 *);
-static s32  igb_read_phy_reg_82580(struct e1000_hw *, u32, u16 *);
-static s32  igb_write_phy_reg_82580(struct e1000_hw *, u32, u16);
 static s32  igb_reset_hw_82575(struct e1000_hw *);
 static s32  igb_reset_hw_82580(struct e1000_hw *);
 static s32  igb_set_d0_lplu_state_82575(struct e1000_hw *, bool);
@@ -73,6 +72,32 @@ static s32 igb_update_nvm_checksum_i350(
 static const u16 e1000_82580_rxpbs_table[] = {
 	36, 72, 144, 1, 2, 4, 8, 16, 35, 70, 140 };
 
+/* Due to a hw errata, if the host tries to  configure the VFTA register
+ * while performing queries from the BMC or DMA, then the VFTA in some
+ * cases won't be written.
+ */
+
+/**
+ *  igb_write_vfta_i350 - Write value to VLAN filter table
+ *  @hw: pointer to the HW structure
+ *  @offset: register offset in VLAN filter table
+ *  @value: register value written to VLAN filter table
+ *
+ *  Writes value at the given offset in the register array which stores
+ *  the VLAN filter table.
+ **/
+static void igb_write_vfta_i350(struct e1000_hw *hw, u32 offset, u32 value)
+{
+	struct igb_adapter *adapter = hw->back;
+	int i;
+
+	for (i = 10; i--;)
+		array_wr32(E1000_VFTA, offset, value);
+
+	wrfl();
+	adapter->shadow_vfta[offset] = value;
+}
+
 /**
  *  igb_sgmii_uses_mdio_82575 - Determine if I2C pins are for external MDIO
  *  @hw: pointer to the HW structure
@@ -205,13 +230,10 @@ static s32 igb_init_phy_params_82575(str
 		case e1000_82580:
 		case e1000_i350:
 		case e1000_i354:
-			phy->ops.read_reg = igb_read_phy_reg_82580;
-			phy->ops.write_reg = igb_write_phy_reg_82580;
-			break;
 		case e1000_i210:
 		case e1000_i211:
-			phy->ops.read_reg = igb_read_phy_reg_gs40g;
-			phy->ops.write_reg = igb_write_phy_reg_gs40g;
+			phy->ops.read_reg = igb_read_phy_reg_82580;
+			phy->ops.write_reg = igb_write_phy_reg_82580;
 			break;
 		default:
 			phy->ops.read_reg = igb_read_phy_reg_igp;
@@ -272,6 +294,11 @@ static s32 igb_init_phy_params_82575(str
 			if (ret_val)
 				goto out;
 		}
+		if (phy->id == M88E1543_E_PHY_ID) {
+			ret_val = igb_initialize_M88E1543_phy(hw);
+			if (ret_val)
+				goto out;
+		}
 		break;
 	case IGP03E1000_E_PHY_ID:
 		phy->type = e1000_phy_igp_3;
@@ -294,6 +321,7 @@ static s32 igb_init_phy_params_82575(str
 	case I210_I_PHY_ID:
 		phy->type		= e1000_phy_i210;
 		phy->ops.check_polarity	= igb_check_polarity_m88;
+		phy->ops.get_cfg_done	= igb_get_cfg_done_i210;
 		phy->ops.get_phy_info	= igb_get_phy_info_m88;
 		phy->ops.get_cable_length = igb_get_cable_length_m88_gen2;
 		phy->ops.set_d0_lplu_state = igb_set_d0_lplu_state_82580;
@@ -397,6 +425,8 @@ static s32 igb_init_mac_params_82575(str
 
 	/* Set mta register count */
 	mac->mta_reg_count = 128;
+	/* Set uta register count */
+	mac->uta_reg_count = (hw->mac.type == e1000_82575) ? 0 : 128;
 	/* Set rar entry count */
 	switch (mac->type) {
 	case e1000_82576:
@@ -428,6 +458,11 @@ static s32 igb_init_mac_params_82575(str
 		mac->ops.release_swfw_sync = igb_release_swfw_sync_82575;
 	}
 
+	if ((hw->mac.type == e1000_i350) || (hw->mac.type == e1000_i354))
+		mac->ops.write_vfta = igb_write_vfta_i350;
+	else
+		mac->ops.write_vfta = igb_write_vfta;
+
 	/* Set if part includes ASF firmware */
 	mac->asf_firmware_present = true;
 	/* Set if manageability features are enabled. */
@@ -925,6 +960,8 @@ static s32 igb_phy_hw_reset_sgmii_82575(
 
 	if (phy->id == M88E1512_E_PHY_ID)
 		ret_val = igb_initialize_M88E1512_phy(hw);
+	if (phy->id == M88E1543_E_PHY_ID)
+		ret_val = igb_initialize_M88E1543_phy(hw);
 out:
 	return ret_val;
 }
@@ -1514,10 +1551,7 @@ static s32 igb_init_hw_82575(struct e100
 
 	/* Disabling VLAN filtering */
 	hw_dbg("Initializing the IEEE VLAN\n");
-	if ((hw->mac.type == e1000_i350) || (hw->mac.type == e1000_i354))
-		igb_clear_vfta_i350(hw);
-	else
-		igb_clear_vfta(hw);
+	igb_clear_vfta(hw);
 
 	/* Setup the receive address */
 	igb_init_rx_addrs(hw, rar_count);
@@ -2145,7 +2179,7 @@ void igb_vmdq_set_replication_pf(struct
  *  Reads the MDI control register in the PHY at offset and stores the
  *  information read to data.
  **/
-static s32 igb_read_phy_reg_82580(struct e1000_hw *hw, u32 offset, u16 *data)
+s32 igb_read_phy_reg_82580(struct e1000_hw *hw, u32 offset, u16 *data)
 {
 	s32 ret_val;
 
@@ -2169,7 +2203,7 @@ out:
  *
  *  Writes data to MDI control register in the PHY at offset.
  **/
-static s32 igb_write_phy_reg_82580(struct e1000_hw *hw, u32 offset, u16 data)
+s32 igb_write_phy_reg_82580(struct e1000_hw *hw, u32 offset, u16 data)
 {
 	s32 ret_val;
 
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/intel/igb/e1000_defines.h
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/intel/igb/e1000_defines.h
@@ -356,7 +356,8 @@
 /* Ethertype field values */
 #define ETHERNET_IEEE_VLAN_TYPE 0x8100  /* 802.3ac packet */
 
-#define MAX_JUMBO_FRAME_SIZE    0x3F00
+/* As per the EAS the maximum supported size is 9.5KB (9728 bytes) */
+#define MAX_JUMBO_FRAME_SIZE	0x2600
 
 /* PBA constants */
 #define E1000_PBA_34K 0x0022
@@ -927,7 +928,10 @@
 
 /* Intel i347-AT4 Registers */
 
-#define I347AT4_PCDL                   0x10 /* PHY Cable Diagnostics Length */
+#define I347AT4_PCDL0                  0x10 /* Pair 0 PHY Cable Diagnostics Length */
+#define I347AT4_PCDL1                  0x11 /* Pair 1 PHY Cable Diagnostics Length */
+#define I347AT4_PCDL2                  0x12 /* Pair 2 PHY Cable Diagnostics Length */
+#define I347AT4_PCDL3                  0x13 /* Pair 3 PHY Cable Diagnostics Length */
 #define I347AT4_PCDC                   0x15 /* PHY Cable Diagnostics Control */
 #define I347AT4_PAGE_SELECT            0x16
 
@@ -990,6 +994,7 @@
 #define E1000_M88E1543_PAGE_ADDR	0x16       /* Page Offset Register */
 #define E1000_M88E1543_EEE_CTRL_1	0x0
 #define E1000_M88E1543_EEE_CTRL_1_MS	0x0001     /* EEE Master/Slave */
+#define E1000_M88E1543_FIBER_CTRL	0x0
 #define E1000_EEE_ADV_DEV_I354		7
 #define E1000_EEE_ADV_ADDR_I354		60
 #define E1000_EEE_ADV_100_SUPPORTED	(1 << 1)   /* 100BaseTx EEE Supported */
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/intel/igb/e1000_hw.h
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/intel/igb/e1000_hw.h
@@ -325,7 +325,7 @@ struct e1000_mac_operations {
 	s32 (*get_thermal_sensor_data)(struct e1000_hw *);
 	s32 (*init_thermal_sensor_thresh)(struct e1000_hw *);
 #endif
-
+	void (*write_vfta)(struct e1000_hw *, u32, u32);
 };
 
 struct e1000_phy_operations {
@@ -441,6 +441,7 @@ struct e1000_phy_info {
 	u16 cable_length;
 	u16 max_cable_length;
 	u16 min_cable_length;
+	u16 pair_length[4];
 
 	u8 mdix;
 
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/intel/igb/e1000_i210.c
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/intel/igb/e1000_i210.c
@@ -861,10 +861,10 @@ s32 igb_pll_workaround_i210(struct e1000
 	if (ret_val)
 		nvm_word = E1000_INVM_DEFAULT_AL;
 	tmp_nvm = nvm_word | E1000_INVM_PLL_WO_VAL;
+	igb_write_phy_reg_82580(hw, I347AT4_PAGE_SELECT, E1000_PHY_PLL_FREQ_PAGE);
 	for (i = 0; i < E1000_MAX_PLL_TRIES; i++) {
 		/* check current state directly from internal PHY */
-		igb_read_phy_reg_gs40g(hw, (E1000_PHY_PLL_FREQ_PAGE |
-					 E1000_PHY_PLL_FREQ_REG), &phy_word);
+		igb_read_phy_reg_82580(hw, E1000_PHY_PLL_FREQ_REG, &phy_word);
 		if ((phy_word & E1000_PHY_PLL_UNCONF)
 		    != E1000_PHY_PLL_UNCONF) {
 			ret_val = 0;
@@ -896,7 +896,35 @@ s32 igb_pll_workaround_i210(struct e1000
 		/* restore WUC register */
 		wr32(E1000_WUC, wuc);
 	}
+	igb_write_phy_reg_82580(hw, I347AT4_PAGE_SELECT, 0);
 	/* restore MDICNFG setting */
 	wr32(E1000_MDICNFG, mdicnfg);
 	return ret_val;
 }
+
+/**
+ *  igb_get_cfg_done_i210 - Read config done bit
+ *  @hw: pointer to the HW structure
+ *
+ *  Read the management control register for the config done bit for
+ *  completion status.  NOTE: silicon which is EEPROM-less will fail trying
+ *  to read the config done bit, so an error is *ONLY* logged and returns
+ *  0.  If we were to return with error, EEPROM-less silicon
+ *  would not be able to be reset or change link.
+ **/
+s32 igb_get_cfg_done_i210(struct e1000_hw *hw)
+{
+	s32 timeout = PHY_CFG_TIMEOUT;
+	u32 mask = E1000_NVM_CFG_DONE_PORT_0;
+
+	while (timeout) {
+		if (rd32(E1000_EEMNGCTL_I210) & mask)
+			break;
+		usleep_range(1000, 2000);
+		timeout--;
+	}
+	if (!timeout)
+		hw_dbg("MNG configuration cycle has not completed.\n");
+
+	return 0;
+}
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/intel/igb/e1000_i210.h
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/intel/igb/e1000_i210.h
@@ -34,6 +34,7 @@ s32 igb_write_xmdio_reg(struct e1000_hw
 s32 igb_init_nvm_params_i210(struct e1000_hw *hw);
 bool igb_get_flash_presence_i210(struct e1000_hw *hw);
 s32 igb_pll_workaround_i210(struct e1000_hw *hw);
+s32 igb_get_cfg_done_i210(struct e1000_hw *hw);
 
 #define E1000_STM_OPCODE		0xDB00
 #define E1000_EEPROM_FLASH_SIZE_WORD	0x11
@@ -84,7 +85,7 @@ enum E1000_INVM_STRUCTURE_TYPE {
 #define E1000_PCI_PMCSR_D3		0x03
 #define E1000_MAX_PLL_TRIES		5
 #define E1000_PHY_PLL_UNCONF		0xFF
-#define E1000_PHY_PLL_FREQ_PAGE		0xFC0000
+#define E1000_PHY_PLL_FREQ_PAGE		0xFC
 #define E1000_PHY_PLL_FREQ_REG		0x000E
 #define E1000_INVM_DEFAULT_AL		0x202F
 #define E1000_INVM_AUTOLOAD		0x0A
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/intel/igb/e1000_mac.c
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/intel/igb/e1000_mac.c
@@ -92,10 +92,8 @@ void igb_clear_vfta(struct e1000_hw *hw)
 {
 	u32 offset;
 
-	for (offset = 0; offset < E1000_VLAN_FILTER_TBL_SIZE; offset++) {
-		array_wr32(E1000_VFTA, offset, 0);
-		wrfl();
-	}
+	for (offset = E1000_VLAN_FILTER_TBL_SIZE; offset--;)
+		hw->mac.ops.write_vfta(hw, offset, 0);
 }
 
 /**
@@ -107,54 +105,14 @@ void igb_clear_vfta(struct e1000_hw *hw)
  *  Writes value at the given offset in the register array which stores
  *  the VLAN filter table.
  **/
-static void igb_write_vfta(struct e1000_hw *hw, u32 offset, u32 value)
+void igb_write_vfta(struct e1000_hw *hw, u32 offset, u32 value)
 {
+	struct igb_adapter *adapter = hw->back;
+
 	array_wr32(E1000_VFTA, offset, value);
 	wrfl();
-}
-
-/* Due to a hw errata, if the host tries to  configure the VFTA register
- * while performing queries from the BMC or DMA, then the VFTA in some
- * cases won't be written.
- */
-
-/**
- *  igb_clear_vfta_i350 - Clear VLAN filter table
- *  @hw: pointer to the HW structure
- *
- *  Clears the register array which contains the VLAN filter table by
- *  setting all the values to 0.
- **/
-void igb_clear_vfta_i350(struct e1000_hw *hw)
-{
-	u32 offset;
-	int i;
 
-	for (offset = 0; offset < E1000_VLAN_FILTER_TBL_SIZE; offset++) {
-		for (i = 0; i < 10; i++)
-			array_wr32(E1000_VFTA, offset, 0);
-
-		wrfl();
-	}
-}
-
-/**
- *  igb_write_vfta_i350 - Write value to VLAN filter table
- *  @hw: pointer to the HW structure
- *  @offset: register offset in VLAN filter table
- *  @value: register value written to VLAN filter table
- *
- *  Writes value at the given offset in the register array which stores
- *  the VLAN filter table.
- **/
-static void igb_write_vfta_i350(struct e1000_hw *hw, u32 offset, u32 value)
-{
-	int i;
-
-	for (i = 0; i < 10; i++)
-		array_wr32(E1000_VFTA, offset, value);
-
-	wrfl();
+	adapter->shadow_vfta[offset] = value;
 }
 
 /**
@@ -183,40 +141,155 @@ void igb_init_rx_addrs(struct e1000_hw *
 }
 
 /**
+ *  igb_find_vlvf_slot - find the VLAN id or the first empty slot
+ *  @hw: pointer to hardware structure
+ *  @vlan: VLAN id to write to VLAN filter
+ *  @vlvf_bypass: skip VLVF if no match is found
+ *
+ *  return the VLVF index where this VLAN id should be placed
+ *
+ **/
+static s32 igb_find_vlvf_slot(struct e1000_hw *hw, u32 vlan, bool vlvf_bypass)
+{
+	s32 regindex, first_empty_slot;
+	u32 bits;
+
+	/* short cut the special case */
+	if (vlan == 0)
+		return 0;
+
+	/* if vlvf_bypass is set we don't want to use an empty slot, we
+	 * will simply bypass the VLVF if there are no entries present in the
+	 * VLVF that contain our VLAN
+	 */
+	first_empty_slot = vlvf_bypass ? -E1000_ERR_NO_SPACE : 0;
+
+	/* Search for the VLAN id in the VLVF entries. Save off the first empty
+	 * slot found along the way.
+	 *
+	 * pre-decrement loop covering (IXGBE_VLVF_ENTRIES - 1) .. 1
+	 */
+	for (regindex = E1000_VLVF_ARRAY_SIZE; --regindex > 0;) {
+		bits = rd32(E1000_VLVF(regindex)) & E1000_VLVF_VLANID_MASK;
+		if (bits == vlan)
+			return regindex;
+		if (!first_empty_slot && !bits)
+			first_empty_slot = regindex;
+	}
+
+	return first_empty_slot ? : -E1000_ERR_NO_SPACE;
+}
+
+/**
  *  igb_vfta_set - enable or disable vlan in VLAN filter table
  *  @hw: pointer to the HW structure
- *  @vid: VLAN id to add or remove
- *  @add: if true add filter, if false remove
+ *  @vlan: VLAN id to add or remove
+ *  @vind: VMDq output index that maps queue to VLAN id
+ *  @vlan_on: if true add filter, if false remove
  *
  *  Sets or clears a bit in the VLAN filter table array based on VLAN id
  *  and if we are adding or removing the filter
  **/
-s32 igb_vfta_set(struct e1000_hw *hw, u32 vid, bool add)
+s32 igb_vfta_set(struct e1000_hw *hw, u32 vlan, u32 vind,
+		 bool vlan_on, bool vlvf_bypass)
 {
-	u32 index = (vid >> E1000_VFTA_ENTRY_SHIFT) & E1000_VFTA_ENTRY_MASK;
-	u32 mask = 1 << (vid & E1000_VFTA_ENTRY_BIT_SHIFT_MASK);
-	u32 vfta;
 	struct igb_adapter *adapter = hw->back;
-	s32 ret_val = 0;
+	u32 regidx, vfta_delta, vfta, bits;
+	s32 vlvf_index;
 
-	vfta = adapter->shadow_vfta[index];
+	if ((vlan > 4095) || (vind > 7))
+		return -E1000_ERR_PARAM;
 
-	/* bit was set/cleared before we started */
-	if ((!!(vfta & mask)) == add) {
-		ret_val = -E1000_ERR_CONFIG;
-	} else {
-		if (add)
-			vfta |= mask;
-		else
-			vfta &= ~mask;
+	/* this is a 2 part operation - first the VFTA, then the
+	 * VLVF and VLVFB if VT Mode is set
+	 * We don't write the VFTA until we know the VLVF part succeeded.
+	 */
+
+	/* Part 1
+	 * The VFTA is a bitstring made up of 128 32-bit registers
+	 * that enable the particular VLAN id, much like the MTA:
+	 *    bits[11-5]: which register
+	 *    bits[4-0]:  which bit in the register
+	 */
+	regidx = vlan / 32;
+	vfta_delta = 1 << (vlan % 32);
+	vfta = adapter->shadow_vfta[regidx];
+
+	/* vfta_delta represents the difference between the current value
+	 * of vfta and the value we want in the register.  Since the diff
+	 * is an XOR mask we can just update vfta using an XOR.
+	 */
+	vfta_delta &= vlan_on ? ~vfta : vfta;
+	vfta ^= vfta_delta;
+
+	/* Part 2
+	 * If VT Mode is set
+	 *   Either vlan_on
+	 *     make sure the VLAN is in VLVF
+	 *     set the vind bit in the matching VLVFB
+	 *   Or !vlan_on
+	 *     clear the pool bit and possibly the vind
+	 */
+	if (!adapter->vfs_allocated_count)
+		goto vfta_update;
+
+	vlvf_index = igb_find_vlvf_slot(hw, vlan, vlvf_bypass);
+	if (vlvf_index < 0) {
+		if (vlvf_bypass)
+			goto vfta_update;
+		return vlvf_index;
 	}
-	if ((hw->mac.type == e1000_i350) || (hw->mac.type == e1000_i354))
-		igb_write_vfta_i350(hw, index, vfta);
-	else
-		igb_write_vfta(hw, index, vfta);
-	adapter->shadow_vfta[index] = vfta;
 
-	return ret_val;
+	bits = rd32(E1000_VLVF(vlvf_index));
+
+	/* set the pool bit */
+	bits |= 1 << (E1000_VLVF_POOLSEL_SHIFT + vind);
+	if (vlan_on)
+		goto vlvf_update;
+
+	/* clear the pool bit */
+	bits ^= 1 << (E1000_VLVF_POOLSEL_SHIFT + vind);
+
+	if (!(bits & E1000_VLVF_POOLSEL_MASK)) {
+		/* Clear VFTA first, then disable VLVF.  Otherwise
+		 * we run the risk of stray packets leaking into
+		 * the PF via the default pool
+		 */
+		if (vfta_delta)
+			hw->mac.ops.write_vfta(hw, regidx, vfta);
+
+		/* disable VLVF and clear remaining bit from pool */
+		wr32(E1000_VLVF(vlvf_index), 0);
+
+		return 0;
+	}
+
+	/* If there are still bits set in the VLVFB registers
+	 * for the VLAN ID indicated we need to see if the
+	 * caller is requesting that we clear the VFTA entry bit.
+	 * If the caller has requested that we clear the VFTA
+	 * entry bit but there are still pools/VFs using this VLAN
+	 * ID entry then ignore the request.  We're not worried
+	 * about the case where we're turning the VFTA VLAN ID
+	 * entry bit on, only when requested to turn it off as
+	 * there may be multiple pools and/or VFs using the
+	 * VLAN ID entry.  In that case we cannot clear the
+	 * VFTA bit until all pools/VFs using that VLAN ID have also
+	 * been cleared.  This will be indicated by "bits" being
+	 * zero.
+	 */
+	vfta_delta = 0;
+
+vlvf_update:
+	/* record pool change and enable VLAN ID if not already enabled */
+	wr32(E1000_VLVF(vlvf_index), bits | vlan | E1000_VLVF_VLANID_ENABLE);
+
+vfta_update:
+	/* bit was set/cleared before we started */
+	if (vfta_delta)
+		hw->mac.ops.write_vfta(hw, regidx, vfta);
+
+	return 0;
 }
 
 /**
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/intel/igb/e1000_mac.h
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/intel/igb/e1000_mac.h
@@ -56,8 +56,9 @@ s32  igb_write_8bit_ctrl_reg(struct e100
 
 void igb_clear_hw_cntrs_base(struct e1000_hw *hw);
 void igb_clear_vfta(struct e1000_hw *hw);
-void igb_clear_vfta_i350(struct e1000_hw *hw);
-s32  igb_vfta_set(struct e1000_hw *hw, u32 vid, bool add);
+void igb_write_vfta(struct e1000_hw *hw, u32 offset, u32 value);
+s32  igb_vfta_set(struct e1000_hw *hw, u32 vid, u32 vind,
+		  bool vlan_on, bool vlvf_bypass);
 void igb_config_collision_dist(struct e1000_hw *hw);
 void igb_init_rx_addrs(struct e1000_hw *hw, u16 rar_count);
 void igb_mta_set(struct e1000_hw *hw, u32 hash_value);
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/intel/igb/e1000_mbx.c
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/intel/igb/e1000_mbx.c
@@ -322,14 +322,20 @@ static s32 igb_obtain_mbx_lock_pf(struct
 {
 	s32 ret_val = -E1000_ERR_MBX;
 	u32 p2v_mailbox;
+	int count = 10;
 
-	/* Take ownership of the buffer */
-	wr32(E1000_P2VMAILBOX(vf_number), E1000_P2VMAILBOX_PFU);
+	do {
+		/* Take ownership of the buffer */
+		wr32(E1000_P2VMAILBOX(vf_number), E1000_P2VMAILBOX_PFU);
 
-	/* reserve mailbox for vf use */
-	p2v_mailbox = rd32(E1000_P2VMAILBOX(vf_number));
-	if (p2v_mailbox & E1000_P2VMAILBOX_PFU)
-		ret_val = 0;
+		/* reserve mailbox for vf use */
+		p2v_mailbox = rd32(E1000_P2VMAILBOX(vf_number));
+		if (p2v_mailbox & E1000_P2VMAILBOX_PFU) {
+			ret_val = 0;
+			break;
+		}
+		udelay(1000);
+	} while (count-- > 0);
 
 	return ret_val;
 }
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/intel/igb/e1000_phy.c
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/intel/igb/e1000_phy.c
@@ -1717,59 +1717,76 @@ s32 igb_get_cable_length_m88_gen2(struct
 	struct e1000_phy_info *phy = &hw->phy;
 	s32 ret_val;
 	u16 phy_data, phy_data2, index, default_page, is_cm;
+	int len_tot = 0;
+	u16 len_min;
+	u16 len_max;
 
 	switch (hw->phy.id) {
+	case M88E1543_E_PHY_ID:
+	case M88E1512_E_PHY_ID:
+	case I347AT4_E_PHY_ID:
 	case I210_I_PHY_ID:
-		/* Get cable length from PHY Cable Diagnostics Control Reg */
-		ret_val = phy->ops.read_reg(hw, (0x7 << GS40G_PAGE_SHIFT) +
-					    (I347AT4_PCDL + phy->addr),
-					    &phy_data);
+		/* Remember the original page select and set it to 7 */
+		ret_val = phy->ops.read_reg(hw, I347AT4_PAGE_SELECT,
+					    &default_page);
 		if (ret_val)
-			return ret_val;
+			goto out;
+
+		ret_val = phy->ops.write_reg(hw, I347AT4_PAGE_SELECT, 0x07);
+		if (ret_val)
+			goto out;
 
 		/* Check if the unit of cable length is meters or cm */
-		ret_val = phy->ops.read_reg(hw, (0x7 << GS40G_PAGE_SHIFT) +
-					    I347AT4_PCDC, &phy_data2);
+		ret_val = phy->ops.read_reg(hw, I347AT4_PCDC, &phy_data2);
 		if (ret_val)
-			return ret_val;
+			goto out;
 
 		is_cm = !(phy_data2 & I347AT4_PCDC_CABLE_LENGTH_UNIT);
 
-		/* Populate the phy structure with cable length in meters */
-		phy->min_cable_length = phy_data / (is_cm ? 100 : 1);
-		phy->max_cable_length = phy_data / (is_cm ? 100 : 1);
-		phy->cable_length = phy_data / (is_cm ? 100 : 1);
-		break;
-	case M88E1543_E_PHY_ID:
-	case M88E1512_E_PHY_ID:
-	case I347AT4_E_PHY_ID:
-		/* Remember the original page select and set it to 7 */
-		ret_val = phy->ops.read_reg(hw, I347AT4_PAGE_SELECT,
-					    &default_page);
+		/* Get cable length from Pair 0 length Regs */
+		ret_val = phy->ops.read_reg(hw, I347AT4_PCDL0, &phy_data);
 		if (ret_val)
 			goto out;
 
-		ret_val = phy->ops.write_reg(hw, I347AT4_PAGE_SELECT, 0x07);
+		phy->pair_length[0] = phy_data / (is_cm ? 100 : 1);
+		len_tot = phy->pair_length[0];
+		len_min = phy->pair_length[0];
+		len_max = phy->pair_length[0];
+
+		/* Get cable length from Pair 1 length Regs */
+		ret_val = phy->ops.read_reg(hw, I347AT4_PCDL1, &phy_data);
 		if (ret_val)
 			goto out;
 
-		/* Get cable length from PHY Cable Diagnostics Control Reg */
-		ret_val = phy->ops.read_reg(hw, (I347AT4_PCDL + phy->addr),
-					    &phy_data);
+		phy->pair_length[1] = phy_data / (is_cm ? 100 : 1);
+		len_tot += phy->pair_length[1];
+		len_min = min(len_min, phy->pair_length[1]);
+		len_max = max(len_max, phy->pair_length[1]);
+
+		/* Get cable length from Pair 2 length Regs */
+		ret_val = phy->ops.read_reg(hw, I347AT4_PCDL2, &phy_data);
 		if (ret_val)
 			goto out;
 
-		/* Check if the unit of cable length is meters or cm */
-		ret_val = phy->ops.read_reg(hw, I347AT4_PCDC, &phy_data2);
+		phy->pair_length[2] = phy_data / (is_cm ? 100 : 1);
+		len_tot += phy->pair_length[2];
+		len_min = min(len_min, phy->pair_length[2]);
+		len_max = max(len_max, phy->pair_length[2]);
+
+		/* Get cable length from Pair 3 length Regs */
+		ret_val = phy->ops.read_reg(hw, I347AT4_PCDL3, &phy_data);
 		if (ret_val)
 			goto out;
 
-		is_cm = !(phy_data2 & I347AT4_PCDC_CABLE_LENGTH_UNIT);
+		phy->pair_length[3] = phy_data / (is_cm ? 100 : 1);
+		len_tot += phy->pair_length[3];
+		len_min = min(len_min, phy->pair_length[3]);
+		len_max = max(len_max, phy->pair_length[3]);
 
 		/* Populate the phy structure with cable length in meters */
-		phy->min_cable_length = phy_data / (is_cm ? 100 : 1);
-		phy->max_cable_length = phy_data / (is_cm ? 100 : 1);
-		phy->cable_length = phy_data / (is_cm ? 100 : 1);
+		phy->min_cable_length = len_min;
+		phy->max_cable_length = len_max;
+		phy->cable_length = len_tot / 4;
 
 		/* Reset the page selec to its original value */
 		ret_val = phy->ops.write_reg(hw, I347AT4_PAGE_SELECT,
@@ -2278,6 +2295,100 @@ out:
 }
 
 /**
+ *  igb_initialize_M88E1543_phy - Initialize M88E1512 PHY
+ *  @hw: pointer to the HW structure
+ *
+ *  Initialize Marvell 1543 to work correctly with Avoton.
+ **/
+s32 igb_initialize_M88E1543_phy(struct e1000_hw *hw)
+{
+	struct e1000_phy_info *phy = &hw->phy;
+	s32 ret_val = 0;
+
+	/* Switch to PHY page 0xFF. */
+	ret_val = phy->ops.write_reg(hw, E1000_M88E1543_PAGE_ADDR, 0x00FF);
+	if (ret_val)
+		goto out;
+
+	ret_val = phy->ops.write_reg(hw, E1000_M88E1512_CFG_REG_2, 0x214B);
+	if (ret_val)
+		goto out;
+
+	ret_val = phy->ops.write_reg(hw, E1000_M88E1512_CFG_REG_1, 0x2144);
+	if (ret_val)
+		goto out;
+
+	ret_val = phy->ops.write_reg(hw, E1000_M88E1512_CFG_REG_2, 0x0C28);
+	if (ret_val)
+		goto out;
+
+	ret_val = phy->ops.write_reg(hw, E1000_M88E1512_CFG_REG_1, 0x2146);
+	if (ret_val)
+		goto out;
+
+	ret_val = phy->ops.write_reg(hw, E1000_M88E1512_CFG_REG_2, 0xB233);
+	if (ret_val)
+		goto out;
+
+	ret_val = phy->ops.write_reg(hw, E1000_M88E1512_CFG_REG_1, 0x214D);
+	if (ret_val)
+		goto out;
+
+	ret_val = phy->ops.write_reg(hw, E1000_M88E1512_CFG_REG_2, 0xDC0C);
+	if (ret_val)
+		goto out;
+
+	ret_val = phy->ops.write_reg(hw, E1000_M88E1512_CFG_REG_1, 0x2159);
+	if (ret_val)
+		goto out;
+
+	/* Switch to PHY page 0xFB. */
+	ret_val = phy->ops.write_reg(hw, E1000_M88E1543_PAGE_ADDR, 0x00FB);
+	if (ret_val)
+		goto out;
+
+	ret_val = phy->ops.write_reg(hw, E1000_M88E1512_CFG_REG_3, 0x0C0D);
+	if (ret_val)
+		goto out;
+
+	/* Switch to PHY page 0x12. */
+	ret_val = phy->ops.write_reg(hw, E1000_M88E1543_PAGE_ADDR, 0x12);
+	if (ret_val)
+		goto out;
+
+	/* Change mode to SGMII-to-Copper */
+	ret_val = phy->ops.write_reg(hw, E1000_M88E1512_MODE, 0x8001);
+	if (ret_val)
+		goto out;
+
+	/* Switch to PHY page 1. */
+	ret_val = phy->ops.write_reg(hw, E1000_M88E1543_PAGE_ADDR, 0x1);
+	if (ret_val)
+		goto out;
+
+	/* Change mode to 1000BASE-X/SGMII and autoneg enable */
+	ret_val = phy->ops.write_reg(hw, E1000_M88E1543_FIBER_CTRL, 0x9140);
+	if (ret_val)
+		goto out;
+
+	/* Return the PHY to page 0. */
+	ret_val = phy->ops.write_reg(hw, E1000_M88E1543_PAGE_ADDR, 0);
+	if (ret_val)
+		goto out;
+
+	ret_val = igb_phy_sw_reset(hw);
+	if (ret_val) {
+		hw_dbg("Error committing the PHY changes\n");
+		return ret_val;
+	}
+
+	/* msec_delay(1000); */
+	usleep_range(1000, 2000);
+out:
+	return ret_val;
+}
+
+/**
  * igb_power_up_phy_copper - Restore copper link in case of PHY power down
  * @hw: pointer to the HW structure
  *
@@ -2493,66 +2604,6 @@ out:
 	return ret_val;
 }
 
-/**
- *  igb_write_phy_reg_gs40g - Write GS40G PHY register
- *  @hw: pointer to the HW structure
- *  @offset: lower half is register offset to write to
- *     upper half is page to use.
- *  @data: data to write at register offset
- *
- *  Acquires semaphore, if necessary, then writes the data to PHY register
- *  at the offset.  Release any acquired semaphores before exiting.
- **/
-s32 igb_write_phy_reg_gs40g(struct e1000_hw *hw, u32 offset, u16 data)
-{
-	s32 ret_val;
-	u16 page = offset >> GS40G_PAGE_SHIFT;
-
-	offset = offset & GS40G_OFFSET_MASK;
-	ret_val = hw->phy.ops.acquire(hw);
-	if (ret_val)
-		return ret_val;
-
-	ret_val = igb_write_phy_reg_mdic(hw, GS40G_PAGE_SELECT, page);
-	if (ret_val)
-		goto release;
-	ret_val = igb_write_phy_reg_mdic(hw, offset, data);
-
-release:
-	hw->phy.ops.release(hw);
-	return ret_val;
-}
-
-/**
- *  igb_read_phy_reg_gs40g - Read GS40G  PHY register
- *  @hw: pointer to the HW structure
- *  @offset: lower half is register offset to read to
- *     upper half is page to use.
- *  @data: data to read at register offset
- *
- *  Acquires semaphore, if necessary, then reads the data in the PHY register
- *  at the offset.  Release any acquired semaphores before exiting.
- **/
-s32 igb_read_phy_reg_gs40g(struct e1000_hw *hw, u32 offset, u16 *data)
-{
-	s32 ret_val;
-	u16 page = offset >> GS40G_PAGE_SHIFT;
-
-	offset = offset & GS40G_OFFSET_MASK;
-	ret_val = hw->phy.ops.acquire(hw);
-	if (ret_val)
-		return ret_val;
-
-	ret_val = igb_write_phy_reg_mdic(hw, GS40G_PAGE_SELECT, page);
-	if (ret_val)
-		goto release;
-	ret_val = igb_read_phy_reg_mdic(hw, offset, data);
-
-release:
-	hw->phy.ops.release(hw);
-	return ret_val;
-}
-
 /**
  *  igb_set_master_slave_mode - Setup PHY for Master/slave mode
  *  @hw: pointer to the HW structure
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/intel/igb/e1000_phy.h
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/intel/igb/e1000_phy.h
@@ -62,6 +62,7 @@ void igb_power_up_phy_copper(struct e100
 void igb_power_down_phy_copper(struct e1000_hw *hw);
 s32  igb_phy_init_script_igp3(struct e1000_hw *hw);
 s32  igb_initialize_M88E1512_phy(struct e1000_hw *hw);
+s32  igb_initialize_M88E1543_phy(struct e1000_hw *hw);
 s32  igb_read_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 *data);
 s32  igb_write_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 data);
 s32  igb_read_phy_reg_i2c(struct e1000_hw *hw, u32 offset, u16 *data);
@@ -71,8 +72,8 @@ s32  igb_copper_link_setup_82580(struct
 s32  igb_get_phy_info_82580(struct e1000_hw *hw);
 s32  igb_phy_force_speed_duplex_82580(struct e1000_hw *hw);
 s32  igb_get_cable_length_82580(struct e1000_hw *hw);
-s32  igb_read_phy_reg_gs40g(struct e1000_hw *hw, u32 offset, u16 *data);
-s32  igb_write_phy_reg_gs40g(struct e1000_hw *hw, u32 offset, u16 data);
+s32  igb_read_phy_reg_82580(struct e1000_hw *hw, u32 offset, u16 *data);
+s32  igb_write_phy_reg_82580(struct e1000_hw *hw, u32 offset, u16 data);
 s32  igb_check_polarity_m88(struct e1000_hw *hw);
 
 /* IGP01E1000 Specific Registers */
@@ -143,17 +144,6 @@ s32  igb_check_polarity_m88(struct e1000
 
 #define E1000_CABLE_LENGTH_UNDEFINED      0xFF
 
-/* GS40G - I210 PHY defines */
-#define GS40G_PAGE_SELECT		0x16
-#define GS40G_PAGE_SHIFT		16
-#define GS40G_OFFSET_MASK		0xFFFF
-#define GS40G_PAGE_2			0x20000
-#define GS40G_MAC_REG2			0x15
-#define GS40G_MAC_LB			0x4140
-#define GS40G_MAC_SPEED_1G		0X0006
-#define GS40G_COPPER_SPEC		0x0010
-#define GS40G_LINE_LB			0x4000
-
 /* SFP modules ID memory locations */
 #define E1000_SFF_IDENTIFIER_OFFSET	0x00
 #define E1000_SFF_IDENTIFIER_SFF	0x02
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/intel/igb/e1000_regs.h
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/intel/igb/e1000_regs.h
@@ -66,6 +66,7 @@
 #define E1000_PBA      0x01000  /* Packet Buffer Allocation - RW */
 #define E1000_PBS      0x01008  /* Packet Buffer Size */
 #define E1000_EEMNGCTL 0x01010  /* MNG EEprom Control */
+#define E1000_EEMNGCTL_I210 0x12030  /* MNG EEprom Control */
 #define E1000_EEARBC_I210 0x12024  /* EEPROM Auto Read Bus Control */
 #define E1000_EEWR     0x0102C  /* EEPROM Write Register - RW */
 #define E1000_I2CCMD   0x01028  /* SFPI2C Command Register - RW */
@@ -385,8 +386,7 @@ do { \
 #define array_wr32(reg, offset, value) \
 	wr32((reg) + ((offset) << 2), (value))
 
-#define array_rd32(reg, offset) \
-	(readl(hw->hw_addr + reg + ((offset) << 2)))
+#define array_rd32(reg, offset) (igb_rd32(hw, reg + ((offset) << 2)))
 
 /* DMA Coalescing registers */
 #define E1000_PCIEMISC	0x05BB8 /* PCIE misc config register */
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/intel/igb/igb.h
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/intel/igb/igb.h
@@ -95,7 +95,6 @@ struct vf_data_storage {
 	unsigned char vf_mac_addresses[ETH_ALEN];
 	u16 vf_mc_hashes[IGB_MAX_VF_MC_ENTRIES];
 	u16 num_vf_mc_hashes;
-	u16 vlans_enabled;
 	u32 flags;
 	unsigned long last_nack;
 	u16 pf_vlan; /* When set, guest VLAN config not allowed. */
@@ -389,6 +388,8 @@ struct igb_adapter {
 	u16 link_speed;
 	u16 link_duplex;
 
+	u8 __iomem *io_addr; /* Mainly for iounmap use */
+
 	struct work_struct reset_task;
 	struct work_struct watchdog_task;
 	bool fc_autoneg;
@@ -480,6 +481,7 @@ struct igb_adapter {
 #define IGB_FLAG_MAS_ENABLE		(1 << 12)
 #define IGB_FLAG_HAS_MSIX		(1 << 13)
 #define IGB_FLAG_EEE			(1 << 14)
+#define IGB_FLAG_VLAN_PROMISC		BIT(15)
 
 /* Media Auto Sense */
 #define IGB_MAS_ENABLE_0		0X0001
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/intel/igb/igb_ethtool.c
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/intel/igb/igb_ethtool.c
@@ -127,10 +127,20 @@ static const struct igb_stats igb_gstrin
 #define IGB_STATS_LEN \
 	(IGB_GLOBAL_STATS_LEN + IGB_NETDEV_STATS_LEN + IGB_QUEUE_STATS_LEN)
 
+enum igb_diagnostics_results {
+	TEST_REG = 0,
+	TEST_EEP,
+	TEST_IRQ,
+	TEST_LOOP,
+	TEST_LINK
+};
+
 static const char igb_gstrings_test[][ETH_GSTRING_LEN] = {
-	"Register test  (offline)", "Eeprom test    (offline)",
-	"Interrupt test (offline)", "Loopback test  (offline)",
-	"Link test   (on/offline)"
+	[TEST_REG]  = "Register test  (offline)",
+	[TEST_EEP]  = "Eeprom test    (offline)",
+	[TEST_IRQ]  = "Interrupt test (offline)",
+	[TEST_LOOP] = "Loopback test  (offline)",
+	[TEST_LINK] = "Link test   (on/offline)"
 };
 #define IGB_TEST_LEN (sizeof(igb_gstrings_test) / ETH_GSTRING_LEN)
 
@@ -2002,7 +2012,7 @@ static void igb_diag_test(struct net_dev
 		/* Link test performed before hardware reset so autoneg doesn't
 		 * interfere with test result
 		 */
-		if (igb_link_test(adapter, &data[4]))
+		if (igb_link_test(adapter, &data[TEST_LINK]))
 			eth_test->flags |= ETH_TEST_FL_FAILED;
 
 		if (if_running)
@@ -2011,21 +2021,21 @@ static void igb_diag_test(struct net_dev
 		else
 			igb_reset(adapter);
 
-		if (igb_reg_test(adapter, &data[0]))
+		if (igb_reg_test(adapter, &data[TEST_REG]))
 			eth_test->flags |= ETH_TEST_FL_FAILED;
 
 		igb_reset(adapter);
-		if (igb_eeprom_test(adapter, &data[1]))
+		if (igb_eeprom_test(adapter, &data[TEST_EEP]))
 			eth_test->flags |= ETH_TEST_FL_FAILED;
 
 		igb_reset(adapter);
-		if (igb_intr_test(adapter, &data[2]))
+		if (igb_intr_test(adapter, &data[TEST_IRQ]))
 			eth_test->flags |= ETH_TEST_FL_FAILED;
 
 		igb_reset(adapter);
 		/* power up link for loopback test */
 		igb_power_up_link(adapter);
-		if (igb_loopback_test(adapter, &data[3]))
+		if (igb_loopback_test(adapter, &data[TEST_LOOP]))
 			eth_test->flags |= ETH_TEST_FL_FAILED;
 
 		/* restore speed, duplex, autoneg settings */
@@ -2045,16 +2055,16 @@ static void igb_diag_test(struct net_dev
 		dev_info(&adapter->pdev->dev, "online testing starting\n");
 
 		/* PHY is powered down when interface is down */
-		if (if_running && igb_link_test(adapter, &data[4]))
+		if (if_running && igb_link_test(adapter, &data[TEST_LINK]))
 			eth_test->flags |= ETH_TEST_FL_FAILED;
 		else
-			data[4] = 0;
+			data[TEST_LINK] = 0;
 
 		/* Online tests aren't run; pass by default */
-		data[0] = 0;
-		data[1] = 0;
-		data[2] = 0;
-		data[3] = 0;
+		data[TEST_REG] = 0;
+		data[TEST_EEP] = 0;
+		data[TEST_IRQ] = 0;
+		data[TEST_LOOP] = 0;
 
 		clear_bit(__IGB_TESTING, &adapter->state);
 	}
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/intel/igb/igb_main.c
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/intel/igb/igb_main.c
@@ -140,7 +140,7 @@ static struct rtnl_link_stats64 *igb_get
 					  struct rtnl_link_stats64 *stats);
 static int igb_change_mtu(struct net_device *, int);
 static int igb_set_mac(struct net_device *, void *);
-static void igb_set_uta(struct igb_adapter *adapter);
+static void igb_set_uta(struct igb_adapter *adapter, bool set);
 static irqreturn_t igb_intr(int irq, void *);
 static irqreturn_t igb_intr_msi(int irq, void *);
 static irqreturn_t igb_msix_other(int irq, void *);
@@ -946,7 +946,6 @@ static void igb_configure_msix(struct ig
 static int igb_request_msix(struct igb_adapter *adapter)
 {
 	struct net_device *netdev = adapter->netdev;
-	struct e1000_hw *hw = &adapter->hw;
 	int i, err = 0, vector = 0, free_vector = 0;
 
 	err = request_irq(adapter->msix_entries[vector].vector,
@@ -959,7 +958,7 @@ static int igb_request_msix(struct igb_a
 
 		vector++;
 
-		q_vector->itr_register = hw->hw_addr + E1000_EITR(vector);
+		q_vector->itr_register = adapter->io_addr + E1000_EITR(vector);
 
 		if (q_vector->rx.ring && q_vector->tx.ring)
 			sprintf(q_vector->name, "%s-TxRx-%u", netdev->name,
@@ -1230,7 +1229,7 @@ static int igb_alloc_q_vector(struct igb
 	q_vector->tx.work_limit = adapter->tx_work_limit;
 
 	/* initialize ITR configuration */
-	q_vector->itr_register = adapter->hw.hw_addr + E1000_EITR(0);
+	q_vector->itr_register = adapter->io_addr + E1000_EITR(0);
 	q_vector->itr_val = IGB_START_ITR;
 
 	/* initialize pointer to rings */
@@ -1535,12 +1534,13 @@ static void igb_irq_enable(struct igb_ad
 static void igb_update_mng_vlan(struct igb_adapter *adapter)
 {
 	struct e1000_hw *hw = &adapter->hw;
+	u16 pf_id = adapter->vfs_allocated_count;
 	u16 vid = adapter->hw.mng_cookie.vlan_id;
 	u16 old_vid = adapter->mng_vlan_id;
 
 	if (hw->mng_cookie.status & E1000_MNG_DHCP_COOKIE_STATUS_VLAN) {
 		/* add VID to filter table */
-		igb_vfta_set(hw, vid, true);
+		igb_vfta_set(hw, vid, pf_id, true, true);
 		adapter->mng_vlan_id = vid;
 	} else {
 		adapter->mng_vlan_id = IGB_MNG_VLAN_NONE;
@@ -1550,7 +1550,7 @@ static void igb_update_mng_vlan(struct i
 	    (vid != old_vid) &&
 	    !test_bit(old_vid, adapter->active_vlans)) {
 		/* remove VID from filter table */
-		igb_vfta_set(hw, old_vid, false);
+		igb_vfta_set(hw, vid, pf_id, false, true);
 	}
 }
 
@@ -1819,6 +1819,10 @@ void igb_down(struct igb_adapter *adapte
 
 	if (!pci_channel_offline(adapter->pdev))
 		igb_reset(adapter);
+
+	/* clear VLAN promisc flag so VFTA will be updated if necessary */
+	adapter->flags &= ~IGB_FLAG_VLAN_PROMISC;
+
 	igb_clean_all_tx_rings(adapter);
 	igb_clean_all_rx_rings(adapter);
 #ifdef CONFIG_IGB_DCA
@@ -1863,7 +1867,7 @@ void igb_reset(struct igb_adapter *adapt
 	struct e1000_hw *hw = &adapter->hw;
 	struct e1000_mac_info *mac = &hw->mac;
 	struct e1000_fc_info *fc = &hw->fc;
-	u32 pba = 0, tx_space, min_tx_space, min_rx_space, hwm;
+	u32 pba, hwm;
 
 	/* Repartition Pba for greater than 9k mtu
 	 * To take effect CTRL.RST is required.
@@ -1887,9 +1891,10 @@ void igb_reset(struct igb_adapter *adapt
 		break;
 	}
 
-	if ((adapter->max_frame_size > ETH_FRAME_LEN + ETH_FCS_LEN) &&
-	    (mac->type < e1000_82576)) {
-		/* adjust PBA for jumbo frames */
+	if (mac->type == e1000_82575) {
+		u32 min_rx_space, min_tx_space, needed_tx_space;
+
+		/* write Rx PBA so that hardware can report correct Tx PBA */
 		wr32(E1000_PBA, pba);
 
 		/* To maintain wire speed transmits, the Tx FIFO should be
@@ -1899,31 +1904,26 @@ void igb_reset(struct igb_adapter *adapt
 		 * one full receive packet and is similarly rounded up and
 		 * expressed in KB.
 		 */
-		pba = rd32(E1000_PBA);
-		/* upper 16 bits has Tx packet buffer allocation size in KB */
-		tx_space = pba >> 16;
-		/* lower 16 bits has Rx packet buffer allocation size in KB */
-		pba &= 0xffff;
-		/* the Tx fifo also stores 16 bytes of information about the Tx
-		 * but don't include ethernet FCS because hardware appends it
+		min_rx_space = DIV_ROUND_UP(MAX_JUMBO_FRAME_SIZE, 1024);
+
+		/* The Tx FIFO also stores 16 bytes of information about the Tx
+		 * but don't include Ethernet FCS because hardware appends it.
+		 * We only need to round down to the nearest 512 byte block
+		 * count since the value we care about is 2 frames, not 1.
 		 */
-		min_tx_space = (adapter->max_frame_size +
-				sizeof(union e1000_adv_tx_desc) -
-				ETH_FCS_LEN) * 2;
-		min_tx_space = ALIGN(min_tx_space, 1024);
-		min_tx_space >>= 10;
-		/* software strips receive CRC, so leave room for it */
-		min_rx_space = adapter->max_frame_size;
-		min_rx_space = ALIGN(min_rx_space, 1024);
-		min_rx_space >>= 10;
+		min_tx_space = adapter->max_frame_size;
+		min_tx_space += sizeof(union e1000_adv_tx_desc) - ETH_FCS_LEN;
+		min_tx_space = DIV_ROUND_UP(min_tx_space, 512);
+
+		/* upper 16 bits has Tx packet buffer allocation size in KB */
+		needed_tx_space = min_tx_space - (rd32(E1000_PBA) >> 16);
 
 		/* If current Tx allocation is less than the min Tx FIFO size,
 		 * and the min Tx FIFO size is less than the current Rx FIFO
-		 * allocation, take space away from current Rx allocation
+		 * allocation, take space away from current Rx allocation.
 		 */
-		if (tx_space < min_tx_space &&
-		    ((min_tx_space - tx_space) < pba)) {
-			pba = pba - (min_tx_space - tx_space);
+		if (needed_tx_space < pba) {
+			pba -= needed_tx_space;
 
 			/* if short on Rx space, Rx wins and must trump Tx
 			 * adjustment
@@ -1931,18 +1931,20 @@ void igb_reset(struct igb_adapter *adapt
 			if (pba < min_rx_space)
 				pba = min_rx_space;
 		}
+
+		/* adjust PBA for jumbo frames */
 		wr32(E1000_PBA, pba);
 	}
 
-	/* flow control settings */
-	/* The high water mark must be low enough to fit one full frame
-	 * (or the size used for early receive) above it in the Rx FIFO.
-	 * Set it to the lower of:
-	 * - 90% of the Rx FIFO size, or
-	 * - the full Rx FIFO size minus one full frame
+	/* flow control settings
+	 * The high water mark must be low enough to fit one full frame
+	 * after transmitting the pause frame.  As such we must have enough
+	 * space to allow for us to complete our current transmit and then
+	 * receive the frame that is in progress from the link partner.
+	 * Set it to:
+	 * - the full Rx FIFO size minus one full Tx plus one full Rx frame
 	 */
-	hwm = min(((pba << 10) * 9 / 10),
-			((pba << 10) - 2 * adapter->max_frame_size));
+	hwm = (pba << 10) - (adapter->max_frame_size + MAX_JUMBO_FRAME_SIZE);
 
 	fc->high_water = hwm & 0xFFFFFFF0;	/* 16-byte granularity */
 	fc->low_water = fc->high_water - 16;
@@ -2052,7 +2054,7 @@ static int igb_set_features(struct net_d
 	if (changed & NETIF_F_HW_VLAN_CTAG_RX)
 		igb_vlan_mode(netdev, features);
 
-	if (!(changed & NETIF_F_RXALL))
+	if (!(changed & (NETIF_F_RXALL | NETIF_F_NTUPLE)))
 		return 0;
 
 	netdev->features = features;
@@ -2065,6 +2067,25 @@ static int igb_set_features(struct net_d
 	return 0;
 }
 
+static int igb_ndo_fdb_add(struct ndmsg *ndm, struct nlattr *tb[],
+			   struct net_device *dev,
+			   const unsigned char *addr, u16 vid,
+			   u16 flags)
+{
+	/* guarantee we can provide a unique filter for the unicast address */
+	if (is_unicast_ether_addr(addr) || is_link_local_ether_addr(addr)) {
+		struct igb_adapter *adapter = netdev_priv(dev);
+		struct e1000_hw *hw = &adapter->hw;
+		int vfn = adapter->vfs_allocated_count;
+		int rar_entries = hw->mac.rar_entry_count - (vfn + 1);
+
+		if (netdev_uc_count(dev) >= rar_entries)
+			return -ENOMEM;
+	}
+
+	return ndo_dflt_fdb_add(ndm, tb, dev, addr, vid, flags);
+}
+
 static const struct net_device_ops igb_netdev_ops = {
 	.ndo_open		= igb_open,
 	.ndo_stop		= igb_close,
@@ -2088,6 +2109,7 @@ static const struct net_device_ops igb_n
 #endif
 	.ndo_fix_features	= igb_fix_features,
 	.ndo_set_features	= igb_set_features,
+	.ndo_fdb_add		= igb_ndo_fdb_add,
 	.ndo_features_check	= passthru_features_check,
 };
 
@@ -2294,9 +2316,11 @@ static int igb_probe(struct pci_dev *pde
 	adapter->msg_enable = netif_msg_init(debug, DEFAULT_MSG_ENABLE);
 
 	err = -EIO;
-	hw->hw_addr = pci_iomap(pdev, 0, 0);
-	if (!hw->hw_addr)
+	adapter->io_addr = pci_iomap(pdev, 0, 0);
+	if (!adapter->io_addr)
 		goto err_ioremap;
+	/* hw->hw_addr can be altered, we'll use adapter->io_addr for unmap */
+	hw->hw_addr = adapter->io_addr;
 
 	netdev->netdev_ops = &igb_netdev_ops;
 	igb_set_ethtool_ops(netdev);
@@ -2378,8 +2402,8 @@ static int igb_probe(struct pci_dev *pde
 	}
 
 	if (hw->mac.type >= e1000_82576) {
-		netdev->hw_features |= NETIF_F_SCTP_CSUM;
-		netdev->features |= NETIF_F_SCTP_CSUM;
+		netdev->hw_features |= NETIF_F_SCTP_CRC;
+		netdev->features |= NETIF_F_SCTP_CRC;
 	}
 
 	netdev->priv_flags |= IFF_UNICAST_FLT;
@@ -2656,7 +2680,7 @@ err_sw_init:
 #ifdef CONFIG_PCI_IOV
 	igb_disable_sriov(pdev);
 #endif
-	pci_iounmap(pdev, hw->hw_addr);
+	pci_iounmap(pdev, adapter->io_addr);
 err_ioremap:
 	free_netdev(netdev);
 err_alloc_etherdev:
@@ -2823,7 +2847,7 @@ static void igb_remove(struct pci_dev *p
 
 	igb_clear_interrupt_scheme(adapter);
 
-	pci_iounmap(pdev, hw->hw_addr);
+	pci_iounmap(pdev, adapter->io_addr);
 	if (hw->flash_address)
 		iounmap(hw->flash_address);
 	pci_release_selected_regions(pdev,
@@ -2856,6 +2880,13 @@ static void igb_probe_vfs(struct igb_ada
 	if ((hw->mac.type == e1000_i210) || (hw->mac.type == e1000_i211))
 		return;
 
+	/* Of the below we really only want the effect of getting
+	 * IGB_FLAG_HAS_MSIX set (if available), without which
+	 * igb_enable_sriov() has no effect.
+	 */
+	igb_set_interrupt_capability(adapter, true);
+	igb_reset_interrupt_capability(adapter);
+
 	pci_sriov_set_totalvfs(pdev, 7);
 	igb_enable_sriov(pdev, max_vfs);
 
@@ -2913,14 +2944,6 @@ void igb_set_flag_queue_pairs(struct igb
 		/* Device supports enough interrupts without queue pairing. */
 		break;
 	case e1000_82576:
-		/* If VFs are going to be allocated with RSS queues then we
-		 * should pair the queues in order to conserve interrupts due
-		 * to limited supply.
-		 */
-		if ((adapter->rss_queues > 1) &&
-		    (adapter->vfs_allocated_count > 6))
-			adapter->flags |= IGB_FLAG_QUEUE_PAIRS;
-		/* fall through */
 	case e1000_82580:
 	case e1000_i350:
 	case e1000_i354:
@@ -2931,6 +2954,8 @@ void igb_set_flag_queue_pairs(struct igb
 		 */
 		if (adapter->rss_queues > (max_rss_queues / 2))
 			adapter->flags |= IGB_FLAG_QUEUE_PAIRS;
+		else
+			adapter->flags &= ~IGB_FLAG_QUEUE_PAIRS;
 		break;
 	}
 }
@@ -3490,7 +3515,7 @@ void igb_setup_rctl(struct igb_adapter *
 	/* disable store bad packets and clear size bits. */
 	rctl &= ~(E1000_RCTL_SBP | E1000_RCTL_SZ_256);
 
-	/* enable LPE to prevent packets larger than max_frame_size */
+	/* enable LPE to allow for reception of jumbo frames */
 	rctl |= E1000_RCTL_LPE;
 
 	/* disable queue 0 to prevent tail write w/o re-config */
@@ -3514,8 +3539,7 @@ void igb_setup_rctl(struct igb_adapter *
 			 E1000_RCTL_BAM | /* RX All Bcast Pkts */
 			 E1000_RCTL_PMCF); /* RX All MAC Ctrl Pkts */
 
-		rctl &= ~(E1000_RCTL_VFE | /* Disable VLAN filter */
-			  E1000_RCTL_DPF | /* Allow filtered pause */
+		rctl &= ~(E1000_RCTL_DPF | /* Allow filtered pause */
 			  E1000_RCTL_CFIEN); /* Dis VLAN CFIEN Filter */
 		/* Do not mess with E1000_CTRL_VME, it affects transmit as well,
 		 * and that breaks VLANs.
@@ -3531,12 +3555,8 @@ static inline int igb_set_vf_rlpml(struc
 	struct e1000_hw *hw = &adapter->hw;
 	u32 vmolr;
 
-	/* if it isn't the PF check to see if VFs are enabled and
-	 * increase the size to support vlan tags
-	 */
-	if (vfn < adapter->vfs_allocated_count &&
-	    adapter->vf_data[vfn].vlans_enabled)
-		size += VLAN_TAG_SIZE;
+	if (size > MAX_JUMBO_FRAME_SIZE)
+		size = MAX_JUMBO_FRAME_SIZE;
 
 	vmolr = rd32(E1000_VMOLR(vfn));
 	vmolr &= ~E1000_VMOLR_RLPML_MASK;
@@ -3546,32 +3566,6 @@ static inline int igb_set_vf_rlpml(struc
 	return 0;
 }
 
-/**
- *  igb_rlpml_set - set maximum receive packet size
- *  @adapter: board private structure
- *
- *  Configure maximum receivable packet size.
- **/
-static void igb_rlpml_set(struct igb_adapter *adapter)
-{
-	u32 max_frame_size = adapter->max_frame_size;
-	struct e1000_hw *hw = &adapter->hw;
-	u16 pf_id = adapter->vfs_allocated_count;
-
-	if (pf_id) {
-		igb_set_vf_rlpml(adapter, max_frame_size, pf_id);
-		/* If we're in VMDQ or SR-IOV mode, then set global RLPML
-		 * to our max jumbo frame size, in case we need to enable
-		 * jumbo frames on one of the rings later.
-		 * This will not pass over-length frames into the default
-		 * queue because it's gated by the VMOLR.RLPML.
-		 */
-		max_frame_size = MAX_JUMBO_FRAME_SIZE;
-	}
-
-	wr32(E1000_RLPML, max_frame_size);
-}
-
 static inline void igb_set_vmolr(struct igb_adapter *adapter,
 				 int vfn, bool aupe)
 {
@@ -3676,9 +3670,6 @@ static void igb_configure_rx(struct igb_
 {
 	int i;
 
-	/* set UTA to appropriate mode */
-	igb_set_uta(adapter);
-
 	/* set the correct pool for the PF default MAC address in entry 0 */
 	igb_rar_set_qsel(adapter, adapter->hw.mac.addr, 0,
 			 adapter->vfs_allocated_count);
@@ -3996,6 +3987,130 @@ static int igb_write_uc_addr_list(struct
 	return count;
 }
 
+static int igb_vlan_promisc_enable(struct igb_adapter *adapter)
+{
+	struct e1000_hw *hw = &adapter->hw;
+	u32 i, pf_id;
+
+	switch (hw->mac.type) {
+	case e1000_i210:
+	case e1000_i211:
+	case e1000_i350:
+		/* VLAN filtering needed for VLAN prio filter */
+		if (adapter->netdev->features & NETIF_F_NTUPLE)
+			break;
+		/* fall through */
+	case e1000_82576:
+	case e1000_82580:
+	case e1000_i354:
+		/* VLAN filtering needed for pool filtering */
+		if (adapter->vfs_allocated_count)
+			break;
+		/* fall through */
+	default:
+		return 1;
+	}
+
+	/* We are already in VLAN promisc, nothing to do */
+	if (adapter->flags & IGB_FLAG_VLAN_PROMISC)
+		return 0;
+
+	if (!adapter->vfs_allocated_count)
+		goto set_vfta;
+
+	/* Add PF to all active pools */
+	pf_id = adapter->vfs_allocated_count + E1000_VLVF_POOLSEL_SHIFT;
+
+	for (i = E1000_VLVF_ARRAY_SIZE; --i;) {
+		u32 vlvf = rd32(E1000_VLVF(i));
+
+		vlvf |= 1 << pf_id;
+		wr32(E1000_VLVF(i), vlvf);
+	}
+
+set_vfta:
+	/* Set all bits in the VLAN filter table array */
+	for (i = E1000_VLAN_FILTER_TBL_SIZE; i--;)
+		hw->mac.ops.write_vfta(hw, i, ~0U);
+
+	/* Set flag so we don't redo unnecessary work */
+	adapter->flags |= IGB_FLAG_VLAN_PROMISC;
+
+	return 0;
+}
+
+#define VFTA_BLOCK_SIZE 8
+static void igb_scrub_vfta(struct igb_adapter *adapter, u32 vfta_offset)
+{
+	struct e1000_hw *hw = &adapter->hw;
+	u32 vfta[VFTA_BLOCK_SIZE] = { 0 };
+	u32 vid_start = vfta_offset * 32;
+	u32 vid_end = vid_start + (VFTA_BLOCK_SIZE * 32);
+	u32 i, vid, word, bits, pf_id;
+
+	/* guarantee that we don't scrub out management VLAN */
+	vid = adapter->mng_vlan_id;
+	if (vid >= vid_start && vid < vid_end)
+		vfta[(vid - vid_start) / 32] |= 1 << (vid % 32);
+
+	if (!adapter->vfs_allocated_count)
+		goto set_vfta;
+
+	pf_id = adapter->vfs_allocated_count + E1000_VLVF_POOLSEL_SHIFT;
+
+	for (i = E1000_VLVF_ARRAY_SIZE; --i;) {
+		u32 vlvf = rd32(E1000_VLVF(i));
+
+		/* pull VLAN ID from VLVF */
+		vid = vlvf & VLAN_VID_MASK;
+
+		/* only concern ourselves with a certain range */
+		if (vid < vid_start || vid >= vid_end)
+			continue;
+
+		if (vlvf & E1000_VLVF_VLANID_ENABLE) {
+			/* record VLAN ID in VFTA */
+			vfta[(vid - vid_start) / 32] |= 1 << (vid % 32);
+
+			/* if PF is part of this then continue */
+			if (test_bit(vid, adapter->active_vlans))
+				continue;
+		}
+
+		/* remove PF from the pool */
+		bits = ~(1 << pf_id);
+		bits &= rd32(E1000_VLVF(i));
+		wr32(E1000_VLVF(i), bits);
+	}
+
+set_vfta:
+	/* extract values from active_vlans and write back to VFTA */
+	for (i = VFTA_BLOCK_SIZE; i--;) {
+		vid = (vfta_offset + i) * 32;
+		word = vid / BITS_PER_LONG;
+		bits = vid % BITS_PER_LONG;
+
+		vfta[i] |= adapter->active_vlans[word] >> bits;
+
+		hw->mac.ops.write_vfta(hw, vfta_offset + i, vfta[i]);
+	}
+}
+
+static void igb_vlan_promisc_disable(struct igb_adapter *adapter)
+{
+	u32 i;
+
+	/* We are not in VLAN promisc, nothing to do */
+	if (!(adapter->flags & IGB_FLAG_VLAN_PROMISC))
+		return;
+
+	/* Set flag so we don't redo unnecessary work */
+	adapter->flags &= ~IGB_FLAG_VLAN_PROMISC;
+
+	for (i = 0; i < E1000_VLAN_FILTER_TBL_SIZE; i += VFTA_BLOCK_SIZE)
+		igb_scrub_vfta(adapter, i);
+}
+
 /**
  *  igb_set_rx_mode - Secondary Unicast, Multicast and Promiscuous mode set
  *  @netdev: network interface device structure
@@ -4010,21 +4125,17 @@ static void igb_set_rx_mode(struct net_d
 	struct igb_adapter *adapter = netdev_priv(netdev);
 	struct e1000_hw *hw = &adapter->hw;
 	unsigned int vfn = adapter->vfs_allocated_count;
-	u32 rctl, vmolr = 0;
+	u32 rctl = 0, vmolr = 0;
 	int count;
 
 	/* Check for Promiscuous and All Multicast modes */
-	rctl = rd32(E1000_RCTL);
-
-	/* clear the effected bits */
-	rctl &= ~(E1000_RCTL_UPE | E1000_RCTL_MPE | E1000_RCTL_VFE);
-
 	if (netdev->flags & IFF_PROMISC) {
-		/* retain VLAN HW filtering if in VT mode */
-		if (adapter->vfs_allocated_count)
-			rctl |= E1000_RCTL_VFE;
-		rctl |= (E1000_RCTL_UPE | E1000_RCTL_MPE);
-		vmolr |= (E1000_VMOLR_ROPE | E1000_VMOLR_MPME);
+		rctl |= E1000_RCTL_UPE | E1000_RCTL_MPE;
+		vmolr |= E1000_VMOLR_MPME;
+
+		/* enable use of UTA filter to force packets to default pool */
+		if (hw->mac.type == e1000_82576)
+			vmolr |= E1000_VMOLR_ROPE;
 	} else {
 		if (netdev->flags & IFF_ALLMULTI) {
 			rctl |= E1000_RCTL_MPE;
@@ -4042,17 +4153,34 @@ static void igb_set_rx_mode(struct net_d
 				vmolr |= E1000_VMOLR_ROMPE;
 			}
 		}
-		/* Write addresses to available RAR registers, if there is not
-		 * sufficient space to store all the addresses then enable
-		 * unicast promiscuous mode
-		 */
-		count = igb_write_uc_addr_list(netdev);
-		if (count < 0) {
-			rctl |= E1000_RCTL_UPE;
-			vmolr |= E1000_VMOLR_ROPE;
-		}
-		rctl |= E1000_RCTL_VFE;
 	}
+
+	/* Write addresses to available RAR registers, if there is not
+	 * sufficient space to store all the addresses then enable
+	 * unicast promiscuous mode
+	 */
+	count = igb_write_uc_addr_list(netdev);
+	if (count < 0) {
+		rctl |= E1000_RCTL_UPE;
+		vmolr |= E1000_VMOLR_ROPE;
+	}
+
+	/* enable VLAN filtering by default */
+	rctl |= E1000_RCTL_VFE;
+
+	/* disable VLAN filtering for modes that require it */
+	if ((netdev->flags & IFF_PROMISC) ||
+	    (netdev->features & NETIF_F_RXALL)) {
+		/* if we fail to set all rules then just clear VFE */
+		if (igb_vlan_promisc_enable(adapter))
+			rctl &= ~E1000_RCTL_VFE;
+	} else {
+		igb_vlan_promisc_disable(adapter);
+	}
+
+	/* update state of unicast, multicast, and VLAN filtering modes */
+	rctl |= rd32(E1000_RCTL) & ~(E1000_RCTL_UPE | E1000_RCTL_MPE |
+				     E1000_RCTL_VFE);
 	wr32(E1000_RCTL, rctl);
 
 	/* In order to support SR-IOV and eventually VMDq it is necessary to set
@@ -4063,9 +4191,19 @@ static void igb_set_rx_mode(struct net_d
 	if ((hw->mac.type < e1000_82576) || (hw->mac.type > e1000_i350))
 		return;
 
+	/* set UTA to appropriate mode */
+	igb_set_uta(adapter, !!(vmolr & E1000_VMOLR_ROPE));
+
 	vmolr |= rd32(E1000_VMOLR(vfn)) &
 		 ~(E1000_VMOLR_ROPE | E1000_VMOLR_MPME | E1000_VMOLR_ROMPE);
+
+	/* enable Rx jumbo frames, no need for restriction */
+	vmolr &= ~E1000_VMOLR_RLPML_MASK;
+	vmolr |= MAX_JUMBO_FRAME_SIZE | E1000_VMOLR_LPE;
+
 	wr32(E1000_VMOLR(vfn), vmolr);
+	wr32(E1000_RLPML, MAX_JUMBO_FRAME_SIZE);
+
 	igb_restore_vf_multicasts(adapter);
 }
 
@@ -5080,16 +5218,6 @@ static netdev_tx_t igb_xmit_frame(struct
 {
 	struct igb_adapter *adapter = netdev_priv(netdev);
 
-	if (test_bit(__IGB_DOWN, &adapter->state)) {
-		dev_kfree_skb_any(skb);
-		return NETDEV_TX_OK;
-	}
-
-	if (skb->len <= 0) {
-		dev_kfree_skb_any(skb);
-		return NETDEV_TX_OK;
-	}
-
 	/* The minimum packet size with TCTL.PSP set is 17 so pad the skb
 	 * in order to meet this minimum size requirement.
 	 */
@@ -5784,125 +5912,132 @@ static void igb_restore_vf_multicasts(st
 static void igb_clear_vf_vfta(struct igb_adapter *adapter, u32 vf)
 {
 	struct e1000_hw *hw = &adapter->hw;
-	u32 pool_mask, reg, vid;
-	int i;
+	u32 pool_mask, vlvf_mask, i;
 
-	pool_mask = 1 << (E1000_VLVF_POOLSEL_SHIFT + vf);
+	/* create mask for VF and other pools */
+	pool_mask = E1000_VLVF_POOLSEL_MASK;
+	vlvf_mask = 1 << (E1000_VLVF_POOLSEL_SHIFT + vf);
+
+	/* drop PF from pool bits */
+	pool_mask &= ~(1 << (E1000_VLVF_POOLSEL_SHIFT +
+			     adapter->vfs_allocated_count));
 
 	/* Find the vlan filter for this id */
-	for (i = 0; i < E1000_VLVF_ARRAY_SIZE; i++) {
-		reg = rd32(E1000_VLVF(i));
+	for (i = E1000_VLVF_ARRAY_SIZE; i--;) {
+		u32 vlvf = rd32(E1000_VLVF(i));
+		u32 vfta_mask, vid, vfta;
 
 		/* remove the vf from the pool */
-		reg &= ~pool_mask;
+		if (!(vlvf & vlvf_mask))
+			continue;
 
-		/* if pool is empty then remove entry from vfta */
-		if (!(reg & E1000_VLVF_POOLSEL_MASK) &&
-		    (reg & E1000_VLVF_VLANID_ENABLE)) {
-			reg = 0;
-			vid = reg & E1000_VLVF_VLANID_MASK;
-			igb_vfta_set(hw, vid, false);
-		}
+		/* clear out bit from VLVF */
+		vlvf ^= vlvf_mask;
+
+		/* if other pools are present, just remove ourselves */
+		if (vlvf & pool_mask)
+			goto update_vlvfb;
+
+		/* if PF is present, leave VFTA */
+		if (vlvf & E1000_VLVF_POOLSEL_MASK)
+			goto update_vlvf;
+
+		vid = vlvf & E1000_VLVF_VLANID_MASK;
+		vfta_mask = 1 << (vid % 32);
+
+		/* clear bit from VFTA */
+		vfta = adapter->shadow_vfta[vid / 32];
+		if (vfta & vfta_mask)
+			hw->mac.ops.write_vfta(hw, vid / 32, vfta ^ vfta_mask);
+update_vlvf:
+		/* clear pool selection enable */
+		if (adapter->flags & IGB_FLAG_VLAN_PROMISC)
+			vlvf &= E1000_VLVF_POOLSEL_MASK;
+		else
+			vlvf = 0;
+update_vlvfb:
+		/* clear pool bits */
+		wr32(E1000_VLVF(i), vlvf);
+	}
+}
+
+static int igb_find_vlvf_entry(struct e1000_hw *hw, u32 vlan)
+{
+	u32 vlvf;
+	int idx;
 
-		wr32(E1000_VLVF(i), reg);
+	/* short cut the special case */
+	if (vlan == 0)
+		return 0;
+
+	/* Search for the VLAN id in the VLVF entries */
+	for (idx = E1000_VLVF_ARRAY_SIZE; --idx;) {
+		vlvf = rd32(E1000_VLVF(idx));
+		if ((vlvf & VLAN_VID_MASK) == vlan)
+			break;
 	}
 
-	adapter->vf_data[vf].vlans_enabled = 0;
+	return idx;
 }
 
-static s32 igb_vlvf_set(struct igb_adapter *adapter, u32 vid, bool add, u32 vf)
+void igb_update_pf_vlvf(struct igb_adapter *adapter, u32 vid)
 {
 	struct e1000_hw *hw = &adapter->hw;
-	u32 reg, i;
+	u32 bits, pf_id;
+	int idx;
 
-	/* The vlvf table only exists on 82576 hardware and newer */
-	if (hw->mac.type < e1000_82576)
-		return -1;
+	idx = igb_find_vlvf_entry(hw, vid);
+	if (!idx)
+		return;
 
-	/* we only need to do this if VMDq is enabled */
-	if (!adapter->vfs_allocated_count)
-		return -1;
+	/* See if any other pools are set for this VLAN filter
+	 * entry other than the PF.
+	 */
+	pf_id = adapter->vfs_allocated_count + E1000_VLVF_POOLSEL_SHIFT;
+	bits = ~(1 << pf_id) & E1000_VLVF_POOLSEL_MASK;
+	bits &= rd32(E1000_VLVF(idx));
+
+	/* Disable the filter so this falls into the default pool. */
+	if (!bits) {
+		if (adapter->flags & IGB_FLAG_VLAN_PROMISC)
+			wr32(E1000_VLVF(idx), 1 << pf_id);
+		else
+			wr32(E1000_VLVF(idx), 0);
+	}
+}
 
-	/* Find the vlan filter for this id */
-	for (i = 0; i < E1000_VLVF_ARRAY_SIZE; i++) {
-		reg = rd32(E1000_VLVF(i));
-		if ((reg & E1000_VLVF_VLANID_ENABLE) &&
-		    vid == (reg & E1000_VLVF_VLANID_MASK))
-			break;
+static s32 igb_set_vf_vlan(struct igb_adapter *adapter, u32 vid,
+			   bool add, u32 vf)
+{
+	int pf_id = adapter->vfs_allocated_count;
+	struct e1000_hw *hw = &adapter->hw;
+	int err;
+
+	/* If VLAN overlaps with one the PF is currently monitoring make
+	 * sure that we are able to allocate a VLVF entry.  This may be
+	 * redundant but it guarantees PF will maintain visibility to
+	 * the VLAN.
+	 */
+	if (add && test_bit(vid, adapter->active_vlans)) {
+		err = igb_vfta_set(hw, vid, pf_id, true, false);
+		if (err)
+			return err;
 	}
 
-	if (add) {
-		if (i == E1000_VLVF_ARRAY_SIZE) {
-			/* Did not find a matching VLAN ID entry that was
-			 * enabled.  Search for a free filter entry, i.e.
-			 * one without the enable bit set
-			 */
-			for (i = 0; i < E1000_VLVF_ARRAY_SIZE; i++) {
-				reg = rd32(E1000_VLVF(i));
-				if (!(reg & E1000_VLVF_VLANID_ENABLE))
-					break;
-			}
-		}
-		if (i < E1000_VLVF_ARRAY_SIZE) {
-			/* Found an enabled/available entry */
-			reg |= 1 << (E1000_VLVF_POOLSEL_SHIFT + vf);
-
-			/* if !enabled we need to set this up in vfta */
-			if (!(reg & E1000_VLVF_VLANID_ENABLE)) {
-				/* add VID to filter table */
-				igb_vfta_set(hw, vid, true);
-				reg |= E1000_VLVF_VLANID_ENABLE;
-			}
-			reg &= ~E1000_VLVF_VLANID_MASK;
-			reg |= vid;
-			wr32(E1000_VLVF(i), reg);
-
-			/* do not modify RLPML for PF devices */
-			if (vf >= adapter->vfs_allocated_count)
-				return 0;
-
-			if (!adapter->vf_data[vf].vlans_enabled) {
-				u32 size;
-
-				reg = rd32(E1000_VMOLR(vf));
-				size = reg & E1000_VMOLR_RLPML_MASK;
-				size += 4;
-				reg &= ~E1000_VMOLR_RLPML_MASK;
-				reg |= size;
-				wr32(E1000_VMOLR(vf), reg);
-			}
+	err = igb_vfta_set(hw, vid, vf, add, false);
 
-			adapter->vf_data[vf].vlans_enabled++;
-		}
-	} else {
-		if (i < E1000_VLVF_ARRAY_SIZE) {
-			/* remove vf from the pool */
-			reg &= ~(1 << (E1000_VLVF_POOLSEL_SHIFT + vf));
-			/* if pool is empty then remove entry from vfta */
-			if (!(reg & E1000_VLVF_POOLSEL_MASK)) {
-				reg = 0;
-				igb_vfta_set(hw, vid, false);
-			}
-			wr32(E1000_VLVF(i), reg);
+	if (add && !err)
+		return err;
 
-			/* do not modify RLPML for PF devices */
-			if (vf >= adapter->vfs_allocated_count)
-				return 0;
-
-			adapter->vf_data[vf].vlans_enabled--;
-			if (!adapter->vf_data[vf].vlans_enabled) {
-				u32 size;
-
-				reg = rd32(E1000_VMOLR(vf));
-				size = reg & E1000_VMOLR_RLPML_MASK;
-				size -= 4;
-				reg &= ~E1000_VMOLR_RLPML_MASK;
-				reg |= size;
-				wr32(E1000_VMOLR(vf), reg);
-			}
-		}
-	}
-	return 0;
+	/* If we failed to add the VF VLAN or we are removing the VF VLAN
+	 * we may need to drop the PF pool bit in order to allow us to free
+	 * up the VLVF resources.
+	 */
+	if (test_bit(vid, adapter->active_vlans) ||
+	    (adapter->flags & IGB_FLAG_VLAN_PROMISC))
+		igb_update_pf_vlvf(adapter, vid);
+
+	return err;
 }
 
 static void igb_set_vmvir(struct igb_adapter *adapter, u32 vid, u32 vf)
@@ -5915,130 +6050,97 @@ static void igb_set_vmvir(struct igb_ada
 		wr32(E1000_VMVIR(vf), 0);
 }
 
-static int igb_ndo_set_vf_vlan(struct net_device *netdev,
-			       int vf, u16 vlan, u8 qos)
+static int igb_enable_port_vlan(struct igb_adapter *adapter, int vf,
+				u16 vlan, u8 qos)
 {
-	int err = 0;
-	struct igb_adapter *adapter = netdev_priv(netdev);
+	int err;
 
-	if ((vf >= adapter->vfs_allocated_count) || (vlan > 4095) || (qos > 7))
-		return -EINVAL;
-	if (vlan || qos) {
-		err = igb_vlvf_set(adapter, vlan, !!vlan, vf);
-		if (err)
-			goto out;
-		igb_set_vmvir(adapter, vlan | (qos << VLAN_PRIO_SHIFT), vf);
-		igb_set_vmolr(adapter, vf, !vlan);
-		adapter->vf_data[vf].pf_vlan = vlan;
-		adapter->vf_data[vf].pf_qos = qos;
-		dev_info(&adapter->pdev->dev,
-			 "Setting VLAN %d, QOS 0x%x on VF %d\n", vlan, qos, vf);
-		if (test_bit(__IGB_DOWN, &adapter->state)) {
-			dev_warn(&adapter->pdev->dev,
-				 "The VF VLAN has been set, but the PF device is not up.\n");
-			dev_warn(&adapter->pdev->dev,
-				 "Bring the PF device up before attempting to use the VF device.\n");
-		}
-	} else {
-		igb_vlvf_set(adapter, adapter->vf_data[vf].pf_vlan,
-			     false, vf);
-		igb_set_vmvir(adapter, vlan, vf);
-		igb_set_vmolr(adapter, vf, true);
-		adapter->vf_data[vf].pf_vlan = 0;
-		adapter->vf_data[vf].pf_qos = 0;
+	err = igb_set_vf_vlan(adapter, vlan, true, vf);
+	if (err)
+		return err;
+
+	igb_set_vmvir(adapter, vlan | (qos << VLAN_PRIO_SHIFT), vf);
+	igb_set_vmolr(adapter, vf, !vlan);
+
+	/* revoke access to previous VLAN */
+	if (vlan != adapter->vf_data[vf].pf_vlan)
+		igb_set_vf_vlan(adapter, adapter->vf_data[vf].pf_vlan,
+				false, vf);
+
+	adapter->vf_data[vf].pf_vlan = vlan;
+	adapter->vf_data[vf].pf_qos = qos;
+	dev_info(&adapter->pdev->dev,
+		 "Setting VLAN %d, QOS 0x%x on VF %d\n", vlan, qos, vf);
+	if (test_bit(__IGB_DOWN, &adapter->state)) {
+		dev_warn(&adapter->pdev->dev,
+			 "The VF VLAN has been set, but the PF device is not up.\n");
+		dev_warn(&adapter->pdev->dev,
+			 "Bring the PF device up before attempting to use the VF device.\n");
 	}
-out:
+
 	return err;
 }
 
-static int igb_find_vlvf_entry(struct igb_adapter *adapter, int vid)
+static int igb_disable_port_vlan(struct igb_adapter *adapter, int vf)
 {
-	struct e1000_hw *hw = &adapter->hw;
-	int i;
-	u32 reg;
+	/* Restore tagless access via VLAN 0 */
+	igb_set_vf_vlan(adapter, 0, true, vf);
 
-	/* Find the vlan filter for this id */
-	for (i = 0; i < E1000_VLVF_ARRAY_SIZE; i++) {
-		reg = rd32(E1000_VLVF(i));
-		if ((reg & E1000_VLVF_VLANID_ENABLE) &&
-		    vid == (reg & E1000_VLVF_VLANID_MASK))
-			break;
-	}
+	igb_set_vmvir(adapter, 0, vf);
+	igb_set_vmolr(adapter, vf, true);
+
+	/* Remove any PF assigned VLAN */
+	if (adapter->vf_data[vf].pf_vlan)
+		igb_set_vf_vlan(adapter, adapter->vf_data[vf].pf_vlan,
+				false, vf);
 
-	if (i >= E1000_VLVF_ARRAY_SIZE)
-		i = -1;
+	adapter->vf_data[vf].pf_vlan = 0;
+	adapter->vf_data[vf].pf_qos = 0;
 
-	return i;
+	return 0;
 }
 
-static int igb_set_vf_vlan(struct igb_adapter *adapter, u32 *msgbuf, u32 vf)
+static int igb_ndo_set_vf_vlan(struct net_device *netdev,
+			       int vf, u16 vlan, u8 qos)
 {
-	struct e1000_hw *hw = &adapter->hw;
-	int add = (msgbuf[0] & E1000_VT_MSGINFO_MASK) >> E1000_VT_MSGINFO_SHIFT;
-	int vid = (msgbuf[1] & E1000_VLVF_VLANID_MASK);
-	int err = 0;
+	struct igb_adapter *adapter = netdev_priv(netdev);
 
-	/* If in promiscuous mode we need to make sure the PF also has
-	 * the VLAN filter set.
-	 */
-	if (add && (adapter->netdev->flags & IFF_PROMISC))
-		err = igb_vlvf_set(adapter, vid, add,
-				   adapter->vfs_allocated_count);
-	if (err)
-		goto out;
+	if ((vf >= adapter->vfs_allocated_count) || (vlan > 4095) || (qos > 7))
+		return -EINVAL;
 
-	err = igb_vlvf_set(adapter, vid, add, vf);
+	return (vlan || qos) ? igb_enable_port_vlan(adapter, vf, vlan, qos) :
+			       igb_disable_port_vlan(adapter, vf);
+}
 
-	if (err)
-		goto out;
+static int igb_set_vf_vlan_msg(struct igb_adapter *adapter, u32 *msgbuf, u32 vf)
+{
+	int add = (msgbuf[0] & E1000_VT_MSGINFO_MASK) >> E1000_VT_MSGINFO_SHIFT;
+	int vid = (msgbuf[1] & E1000_VLVF_VLANID_MASK);
 
-	/* Go through all the checks to see if the VLAN filter should
-	 * be wiped completely.
-	 */
-	if (!add && (adapter->netdev->flags & IFF_PROMISC)) {
-		u32 vlvf, bits;
-		int regndx = igb_find_vlvf_entry(adapter, vid);
-
-		if (regndx < 0)
-			goto out;
-		/* See if any other pools are set for this VLAN filter
-		 * entry other than the PF.
-		 */
-		vlvf = bits = rd32(E1000_VLVF(regndx));
-		bits &= 1 << (E1000_VLVF_POOLSEL_SHIFT +
-			      adapter->vfs_allocated_count);
-		/* If the filter was removed then ensure PF pool bit
-		 * is cleared if the PF only added itself to the pool
-		 * because the PF is in promiscuous mode.
-		 */
-		if ((vlvf & VLAN_VID_MASK) == vid &&
-		    !test_bit(vid, adapter->active_vlans) &&
-		    !bits)
-			igb_vlvf_set(adapter, vid, add,
-				     adapter->vfs_allocated_count);
-	}
+	if (adapter->vf_data[vf].pf_vlan)
+		return -1;
 
-out:
-	return err;
+	/* VLAN 0 is a special case, don't allow it to be removed */
+	if (!vid && !add)
+		return 0;
+
+	return igb_set_vf_vlan(adapter, vid, !!add, vf);
 }
 
 static inline void igb_vf_reset(struct igb_adapter *adapter, u32 vf)
 {
-	/* clear flags - except flag that indicates PF has set the MAC */
-	adapter->vf_data[vf].flags &= IGB_VF_FLAG_PF_SET_MAC;
-	adapter->vf_data[vf].last_nack = jiffies;
+	struct vf_data_storage *vf_data = &adapter->vf_data[vf];
 
-	/* reset offloads to defaults */
-	igb_set_vmolr(adapter, vf, true);
+	/* clear flags - except flag that indicates PF has set the MAC */
+	vf_data->flags &= IGB_VF_FLAG_PF_SET_MAC;
+	vf_data->last_nack = jiffies;
 
 	/* reset vlans for device */
 	igb_clear_vf_vfta(adapter, vf);
-	if (adapter->vf_data[vf].pf_vlan)
-		igb_ndo_set_vf_vlan(adapter->netdev, vf,
-				    adapter->vf_data[vf].pf_vlan,
-				    adapter->vf_data[vf].pf_qos);
-	else
-		igb_clear_vf_vfta(adapter, vf);
+	igb_set_vf_vlan(adapter, vf_data->pf_vlan, true, vf);
+	igb_set_vmvir(adapter, vf_data->pf_vlan |
+			       (vf_data->pf_qos << VLAN_PRIO_SHIFT), vf);
+	igb_set_vmolr(adapter, vf, !vf_data->pf_vlan);
 
 	/* reset multicast table array for vf */
 	adapter->vf_data[vf].num_vf_mc_hashes = 0;
@@ -6183,7 +6285,7 @@ static void igb_rcv_msg_from_vf(struct i
 				 "VF %d attempted to override administratively set VLAN tag\nReload the VF driver to resume operations\n",
 				 vf);
 		else
-			retval = igb_set_vf_vlan(adapter, msgbuf, vf);
+			retval = igb_set_vf_vlan_msg(adapter, msgbuf, vf);
 		break;
 	default:
 		dev_err(&pdev->dev, "Unhandled Msg %08x\n", msgbuf[0]);
@@ -6225,6 +6327,7 @@ static void igb_msg_task(struct igb_adap
 /**
  *  igb_set_uta - Set unicast filter table address
  *  @adapter: board private structure
+ *  @set: boolean indicating if we are setting or clearing bits
  *
  *  The unicast table address is a register array of 32-bit registers.
  *  The table is meant to be used in a way similar to how the MTA is used
@@ -6232,21 +6335,18 @@ static void igb_msg_task(struct igb_adap
  *  set all the hash bits to 1 and use the VMOLR ROPE bit as a promiscuous
  *  enable bit to allow vlan tag stripping when promiscuous mode is enabled
  **/
-static void igb_set_uta(struct igb_adapter *adapter)
+static void igb_set_uta(struct igb_adapter *adapter, bool set)
 {
 	struct e1000_hw *hw = &adapter->hw;
+	u32 uta = set ? ~0 : 0;
 	int i;
 
-	/* The UTA table only exists on 82576 hardware and newer */
-	if (hw->mac.type < e1000_82576)
-		return;
-
 	/* we only need to do this if VMDq is enabled */
 	if (!adapter->vfs_allocated_count)
 		return;
 
-	for (i = 0; i < hw->mac.uta_reg_count; i++)
-		array_wr32(E1000_UTA, i, ~0);
+	for (i = hw->mac.uta_reg_count; i--;)
+		array_wr32(E1000_UTA, i, uta);
 }
 
 /**
@@ -7193,8 +7293,6 @@ static void igb_vlan_mode(struct net_dev
 		ctrl &= ~E1000_CTRL_VME;
 		wr32(E1000_CTRL, ctrl);
 	}
-
-	igb_rlpml_set(adapter);
 }
 
 static int igb_vlan_rx_add_vid(struct net_device *netdev,
@@ -7204,11 +7302,9 @@ static int igb_vlan_rx_add_vid(struct ne
 	struct e1000_hw *hw = &adapter->hw;
 	int pf_id = adapter->vfs_allocated_count;
 
-	/* attempt to add filter to vlvf array */
-	igb_vlvf_set(adapter, vid, true, pf_id);
-
 	/* add the filter since PF can receive vlans w/o entry in vlvf */
-	igb_vfta_set(hw, vid, true);
+	if (!vid || !(adapter->flags & IGB_FLAG_VLAN_PROMISC))
+		igb_vfta_set(hw, vid, pf_id, true, !!vid);
 
 	set_bit(vid, adapter->active_vlans);
 
@@ -7219,16 +7315,12 @@ static int igb_vlan_rx_kill_vid(struct n
 				__be16 proto, u16 vid)
 {
 	struct igb_adapter *adapter = netdev_priv(netdev);
-	struct e1000_hw *hw = &adapter->hw;
 	int pf_id = adapter->vfs_allocated_count;
-	s32 err;
+	struct e1000_hw *hw = &adapter->hw;
 
-	/* remove vlan from VLVF table array */
-	err = igb_vlvf_set(adapter, vid, false, pf_id);
-
-	/* if vid was not present in VLVF just remove it from table */
-	if (err)
-		igb_vfta_set(hw, vid, false);
+	/* remove VID from filter table */
+	if (vid && !(adapter->flags & IGB_FLAG_VLAN_PROMISC))
+		igb_vfta_set(hw, vid, pf_id, false, true);
 
 	clear_bit(vid, adapter->active_vlans);
 
@@ -7237,11 +7329,12 @@ static int igb_vlan_rx_kill_vid(struct n
 
 static void igb_restore_vlan(struct igb_adapter *adapter)
 {
-	u16 vid;
+	u16 vid = 1;
 
 	igb_vlan_mode(adapter->netdev, adapter->netdev->features);
+	igb_vlan_rx_add_vid(adapter->netdev, htons(ETH_P_8021Q), 0);
 
-	for_each_set_bit(vid, adapter->active_vlans, VLAN_N_VID)
+	for_each_set_bit_from(vid, adapter->active_vlans, VLAN_N_VID)
 		igb_vlan_rx_add_vid(adapter->netdev, htons(ETH_P_8021Q), vid);
 }
 
@@ -7696,15 +7789,14 @@ static void igb_io_resume(struct pci_dev
 static void igb_rar_set_qsel(struct igb_adapter *adapter, u8 *addr, u32 index,
 			     u8 qsel)
 {
-	u32 rar_low, rar_high;
 	struct e1000_hw *hw = &adapter->hw;
+	u32 rar_low, rar_high;
 
 	/* HW expects these in little endian so we reverse the byte order
-	 * from network order (big endian) to little endian
+	 * from network order (big endian) to CPU endian
 	 */
-	rar_low = ((u32) addr[0] | ((u32) addr[1] << 8) |
-		   ((u32) addr[2] << 16) | ((u32) addr[3] << 24));
-	rar_high = ((u32) addr[4] | ((u32) addr[5] << 8));
+	rar_low = le32_to_cpup((__be32 *)(addr));
+	rar_high = le16_to_cpup((__be16 *)(addr + 4));
 
 	/* Indicate to hardware the Address is Valid. */
 	rar_high |= E1000_RAH_AV;
@@ -7951,9 +8043,7 @@ static void igb_init_dmac(struct igb_ada
 			 * than the Rx threshold. Set hwm to PBA - max frame
 			 * size in 16B units, capping it at PBA - 6KB.
 			 */
-			hwm = 64 * pba - adapter->max_frame_size / 16;
-			if (hwm < 64 * (pba - 6))
-				hwm = 64 * (pba - 6);
+			hwm = 64 * (pba - 6);
 			reg = rd32(E1000_FCRTC);
 			reg &= ~E1000_FCRTC_RTH_COAL_MASK;
 			reg |= ((hwm << E1000_FCRTC_RTH_COAL_SHIFT)
@@ -7963,9 +8053,7 @@ static void igb_init_dmac(struct igb_ada
 			/* Set the DMA Coalescing Rx threshold to PBA - 2 * max
 			 * frame size, capping it at PBA - 10KB.
 			 */
-			dmac_thr = pba - adapter->max_frame_size / 512;
-			if (dmac_thr < pba - 10)
-				dmac_thr = pba - 10;
+			dmac_thr = pba - 10;
 			reg = rd32(E1000_DMACR);
 			reg &= ~E1000_DMACR_DMACTHR_MASK;
 			reg |= ((dmac_thr << E1000_DMACR_DMACTHR_SHIFT)
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/intel/igbvf/mbx.c
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/intel/igbvf/mbx.c
@@ -234,13 +234,19 @@ static s32 e1000_check_for_rst_vf(struct
 static s32 e1000_obtain_mbx_lock_vf(struct e1000_hw *hw)
 {
 	s32 ret_val = -E1000_ERR_MBX;
+	int count = 10;
 
-	/* Take ownership of the buffer */
-	ew32(V2PMAILBOX(0), E1000_V2PMAILBOX_VFU);
+	do {
+		/* Take ownership of the buffer */
+		ew32(V2PMAILBOX(0), E1000_V2PMAILBOX_VFU);
 
-	/* reserve mailbox for VF use */
-	if (e1000_read_v2p_mailbox(hw) & E1000_V2PMAILBOX_VFU)
-		ret_val = E1000_SUCCESS;
+		/* reserve mailbox for VF use */
+		if (e1000_read_v2p_mailbox(hw) & E1000_V2PMAILBOX_VFU) {
+			ret_val = 0;
+			break;
+		}
+		udelay(1000);
+	} while (count-- > 0);
 
 	return ret_val;
 }
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/intel/ixgbe/ixgbe.h
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/intel/ixgbe/ixgbe.h
@@ -139,6 +139,7 @@ enum ixgbe_tx_flags {
 #define IXGBE_X540_VF_DEVICE_ID         0x1515
 
 struct vf_data_storage {
+	struct pci_dev *vfdev;
 	unsigned char vf_mac_addresses[ETH_ALEN];
 	u16 vf_mc_hashes[IXGBE_MAX_VF_MC_ENTRIES];
 	u16 num_vf_mc_hashes;
@@ -224,6 +225,8 @@ struct ixgbe_rx_queue_stats {
 	u64 csum_err;
 };
 
+#define IXGBE_TS_HDR_LEN 8
+
 enum ixgbe_ring_state_t {
 	__IXGBE_TX_FDIR_INIT_DONE,
 	__IXGBE_TX_XPS_INIT_DONE,
@@ -282,6 +285,8 @@ struct ixgbe_ring {
 	u16 next_to_use;
 	u16 next_to_clean;
 
+	unsigned long last_rx_timestamp;
+
 	union {
 		u16 next_to_alloc;
 		struct {
@@ -312,7 +317,7 @@ enum ixgbe_ring_f_enum {
 };
 
 #define IXGBE_MAX_RSS_INDICES		16
-#define IXGBE_MAX_RSS_INDICES_X550	64
+#define IXGBE_MAX_RSS_INDICES_X550	63
 #define IXGBE_MAX_VMDQ_INDICES		64
 #define IXGBE_MAX_FDIR_INDICES		63	/* based on q_vector limit */
 #define IXGBE_MAX_FCOE_INDICES		8
@@ -587,9 +592,10 @@ static inline u16 ixgbe_desc_unused(stru
 
 struct ixgbe_mac_addr {
 	u8 addr[ETH_ALEN];
-	u16 queue;
+	u16 pool;
 	u16 state; /* bitmask */
 };
+
 #define IXGBE_MAC_STATE_DEFAULT		0x1
 #define IXGBE_MAC_STATE_MODIFIED	0x2
 #define IXGBE_MAC_STATE_IN_USE		0x4
@@ -639,6 +645,8 @@ struct ixgbe_adapter {
 #define IXGBE_FLAG_SRIOV_CAPABLE                (u32)(1 << 22)
 #define IXGBE_FLAG_SRIOV_ENABLED                (u32)(1 << 23)
 #define IXGBE_FLAG_VXLAN_OFFLOAD_CAPABLE	BIT(24)
+#define IXGBE_FLAG_RX_HWTSTAMP_ENABLED		BIT(25)
+#define IXGBE_FLAG_RX_HWTSTAMP_IN_REGISTER	BIT(26)
 
 	u32 flags2;
 #define IXGBE_FLAG2_RSC_CAPABLE                 (u32)(1 << 0)
@@ -656,6 +664,7 @@ struct ixgbe_adapter {
 #ifdef CONFIG_IXGBE_VXLAN
 #define IXGBE_FLAG2_VXLAN_REREG_NEEDED		BIT(12)
 #endif
+#define IXGBE_FLAG2_VLAN_PROMISC		BIT(13)
 
 	/* Tx fast path data */
 	int num_tx_queues;
@@ -755,9 +764,12 @@ struct ixgbe_adapter {
 	unsigned long last_rx_ptp_check;
 	unsigned long last_rx_timestamp;
 	spinlock_t tmreg_lock;
-	struct cyclecounter cc;
-	struct timecounter tc;
+	struct cyclecounter hw_cc;
+	struct timecounter hw_tc;
 	u32 base_incval;
+	u32 tx_hwtstamp_timeouts;
+	u32 rx_hwtstamp_cleared;
+	void (*ptp_setup_sdp)(struct ixgbe_adapter *);
 
 	/* SR-IOV */
 	DECLARE_BITMAP(active_vfs, IXGBE_MAX_VF_FUNCTIONS);
@@ -784,6 +796,10 @@ struct ixgbe_adapter {
 	u8 default_up;
 	unsigned long fwd_bitmask; /* Bitmask indicating in use pools */
 
+#define IXGBE_MAX_LINK_HANDLE 10
+	struct ixgbe_mat_field *jump_tables[IXGBE_MAX_LINK_HANDLE];
+	unsigned long tables;
+
 /* maximum number of RETA entries among all devices supported by ixgbe
  * driver: currently it's x550 device in non-SRIOV mode
  */
@@ -883,9 +899,10 @@ int ixgbe_wol_supported(struct ixgbe_ada
 void ixgbe_full_sync_mac_table(struct ixgbe_adapter *adapter);
 #endif
 int ixgbe_add_mac_filter(struct ixgbe_adapter *adapter,
-			 u8 *addr, u16 queue);
+			 const u8 *addr, u16 queue);
 int ixgbe_del_mac_filter(struct ixgbe_adapter *adapter,
-			 u8 *addr, u16 queue);
+			 const u8 *addr, u16 queue);
+void ixgbe_update_pf_promisc_vlvf(struct ixgbe_adapter *adapter, u32 vid);
 void ixgbe_clear_interrupt_scheme(struct ixgbe_adapter *adapter);
 netdev_tx_t ixgbe_xmit_frame_ring(struct sk_buff *, struct ixgbe_adapter *,
 				  struct ixgbe_ring *);
@@ -912,6 +929,9 @@ s32 ixgbe_fdir_erase_perfect_filter_8259
 					  u16 soft_id);
 void ixgbe_atr_compute_perfect_hash_82599(union ixgbe_atr_input *input,
 					  union ixgbe_atr_input *mask);
+int ixgbe_update_ethtool_fdir_entry(struct ixgbe_adapter *adapter,
+				    struct ixgbe_fdir_filter *input,
+				    u16 sw_idx);
 void ixgbe_set_rx_mode(struct net_device *netdev);
 #ifdef CONFIG_IXGBE_DCB
 void ixgbe_set_rx_drop_en(struct ixgbe_adapter *adapter);
@@ -968,12 +988,33 @@ void ixgbe_ptp_suspend(struct ixgbe_adap
 void ixgbe_ptp_stop(struct ixgbe_adapter *adapter);
 void ixgbe_ptp_overflow_check(struct ixgbe_adapter *adapter);
 void ixgbe_ptp_rx_hang(struct ixgbe_adapter *adapter);
-void ixgbe_ptp_rx_hwtstamp(struct ixgbe_adapter *adapter, struct sk_buff *skb);
+void ixgbe_ptp_rx_pktstamp(struct ixgbe_q_vector *, struct sk_buff *);
+void ixgbe_ptp_rx_rgtstamp(struct ixgbe_q_vector *, struct sk_buff *skb);
+static inline void ixgbe_ptp_rx_hwtstamp(struct ixgbe_ring *rx_ring,
+					 union ixgbe_adv_rx_desc *rx_desc,
+					 struct sk_buff *skb)
+{
+	if (unlikely(ixgbe_test_staterr(rx_desc, IXGBE_RXD_STAT_TSIP))) {
+		ixgbe_ptp_rx_pktstamp(rx_ring->q_vector, skb);
+		return;
+	}
+
+	if (unlikely(!ixgbe_test_staterr(rx_desc, IXGBE_RXDADV_STAT_TS)))
+		return;
+
+	ixgbe_ptp_rx_rgtstamp(rx_ring->q_vector, skb);
+
+	/* Update the last_rx_timestamp timer in order to enable watchdog check
+	 * for error case of latched timestamp on a dropped packet.
+	 */
+	rx_ring->last_rx_timestamp = jiffies;
+}
+
 int ixgbe_ptp_set_ts_config(struct ixgbe_adapter *adapter, struct ifreq *ifr);
 int ixgbe_ptp_get_ts_config(struct ixgbe_adapter *adapter, struct ifreq *ifr);
 void ixgbe_ptp_start_cyclecounter(struct ixgbe_adapter *adapter);
 void ixgbe_ptp_reset(struct ixgbe_adapter *adapter);
-void ixgbe_ptp_check_pps_event(struct ixgbe_adapter *adapter, u32 eicr);
+void ixgbe_ptp_check_pps_event(struct ixgbe_adapter *adapter);
 #ifdef CONFIG_PCI_IOV
 void ixgbe_sriov_reinit(struct ixgbe_adapter *adapter);
 #endif
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/intel/ixgbe/ixgbe_82598.c
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/intel/ixgbe/ixgbe_82598.c
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel 10 Gigabit PCI Express Linux driver
-  Copyright(c) 1999 - 2014 Intel Corporation.
+  Copyright(c) 1999 - 2015 Intel Corporation.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms and conditions of the GNU General Public License,
@@ -765,13 +765,14 @@ mac_reset_top:
 	ctrl = IXGBE_READ_REG(hw, IXGBE_CTRL) | IXGBE_CTRL_RST;
 	IXGBE_WRITE_REG(hw, IXGBE_CTRL, ctrl);
 	IXGBE_WRITE_FLUSH(hw);
+	usleep_range(1000, 1200);
 
 	/* Poll for reset bit to self-clear indicating reset is complete */
 	for (i = 0; i < 10; i++) {
-		udelay(1);
 		ctrl = IXGBE_READ_REG(hw, IXGBE_CTRL);
 		if (!(ctrl & IXGBE_CTRL_RST))
 			break;
+		udelay(1);
 	}
 	if (ctrl & IXGBE_CTRL_RST) {
 		status = IXGBE_ERR_RESET_FAILED;
@@ -879,11 +880,12 @@ static s32 ixgbe_clear_vmdq_82598(struct
  *  @vlan: VLAN id to write to VLAN filter
  *  @vind: VMDq output index that maps queue to VLAN id in VFTA
  *  @vlan_on: boolean flag to turn on/off VLAN in VFTA
+ *  @vlvf_bypass: boolean flag - unused
  *
  *  Turn on/off specified VLAN in the VLAN filter table.
  **/
 static s32 ixgbe_set_vfta_82598(struct ixgbe_hw *hw, u32 vlan, u32 vind,
-				bool vlan_on)
+				bool vlan_on, bool vlvf_bypass)
 {
 	u32 regindex;
 	u32 bitindex;
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/intel/ixgbe/ixgbe_82599.c
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/intel/ixgbe/ixgbe_82599.c
@@ -990,13 +990,14 @@ mac_reset_top:
 	ctrl |= IXGBE_READ_REG(hw, IXGBE_CTRL);
 	IXGBE_WRITE_REG(hw, IXGBE_CTRL, ctrl);
 	IXGBE_WRITE_FLUSH(hw);
+	usleep_range(1000, 1200);
 
 	/* Poll for reset bit to self-clear indicating reset is complete */
 	for (i = 0; i < 10; i++) {
-		udelay(1);
 		ctrl = IXGBE_READ_REG(hw, IXGBE_CTRL);
 		if (!(ctrl & IXGBE_CTRL_RST_MASK))
 			break;
+		udelay(1);
 	}
 
 	if (ctrl & IXGBE_CTRL_RST_MASK) {
@@ -1082,12 +1083,16 @@ mac_reset_top:
 
 	/* Add the SAN MAC address to the RAR only if it's a valid address */
 	if (is_valid_ether_addr(hw->mac.san_addr)) {
-		hw->mac.ops.set_rar(hw, hw->mac.num_rar_entries - 1,
-				    hw->mac.san_addr, 0, IXGBE_RAH_AV);
-
 		/* Save the SAN MAC RAR index */
 		hw->mac.san_mac_rar_index = hw->mac.num_rar_entries - 1;
 
+		hw->mac.ops.set_rar(hw, hw->mac.san_mac_rar_index,
+				    hw->mac.san_addr, 0, IXGBE_RAH_AV);
+
+		/* clear VMDq pool/queue selection for this RAR */
+		hw->mac.ops.clear_vmdq(hw, hw->mac.san_mac_rar_index,
+				       IXGBE_CLEAR_VMDQ_ALL);
+
 		/* Reserve the last RAR for the SAN MAC address */
 		hw->mac.num_rar_entries--;
 	}
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel 10 Gigabit PCI Express Linux driver
-  Copyright(c) 1999 - 2014 Intel Corporation.
+  Copyright(c) 1999 - 2015 Intel Corporation.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms and conditions of the GNU General Public License,
@@ -1884,10 +1884,11 @@ s32 ixgbe_init_rx_addrs_generic(struct i
 		hw_dbg(hw, " New MAC Addr =%pM\n", hw->mac.addr);
 
 		hw->mac.ops.set_rar(hw, 0, hw->mac.addr, 0, IXGBE_RAH_AV);
-
-		/*  clear VMDq pool/queue selection for RAR 0 */
-		hw->mac.ops.clear_vmdq(hw, 0, IXGBE_CLEAR_VMDQ_ALL);
 	}
+
+	/*  clear VMDq pool/queue selection for RAR 0 */
+	hw->mac.ops.clear_vmdq(hw, 0, IXGBE_CLEAR_VMDQ_ALL);
+
 	hw->addr_ctrl.overflow_promisc = 0;
 
 	hw->addr_ctrl.rar_used_count = 1;
@@ -2454,6 +2455,17 @@ static s32 ixgbe_disable_pcie_master(str
 	/* Always set this bit to ensure any future transactions are blocked */
 	IXGBE_WRITE_REG(hw, IXGBE_CTRL, IXGBE_CTRL_GIO_DIS);
 
+	/* Poll for bit to read as set */
+	for (i = 0; i < IXGBE_PCI_MASTER_DISABLE_TIMEOUT; i++) {
+		if (IXGBE_READ_REG(hw, IXGBE_CTRL) & IXGBE_CTRL_GIO_DIS)
+			break;
+		usleep_range(100, 120);
+	}
+	if (i >= IXGBE_PCI_MASTER_DISABLE_TIMEOUT) {
+		hw_dbg(hw, "GIO disable did not set - requesting resets\n");
+		goto gio_disable_fail;
+	}
+
 	/* Exit if master requests are blocked */
 	if (!(IXGBE_READ_REG(hw, IXGBE_STATUS) & IXGBE_STATUS_GIO) ||
 	    ixgbe_removed(hw->hw_addr))
@@ -2475,6 +2487,7 @@ static s32 ixgbe_disable_pcie_master(str
 	 * again to clear out any effects they may have had on our device.
 	 */
 	hw_dbg(hw, "GIO Master Disable bit didn't clear - requesting resets\n");
+gio_disable_fail:
 	hw->mac.flags |= IXGBE_FLAGS_DOUBLE_RESET_REQUIRED;
 
 	if (hw->mac.type >= ixgbe_mac_X550)
@@ -2987,43 +3000,44 @@ s32 ixgbe_init_uta_tables_generic(struct
  *  return the VLVF index where this VLAN id should be placed
  *
  **/
-static s32 ixgbe_find_vlvf_slot(struct ixgbe_hw *hw, u32 vlan)
+static s32 ixgbe_find_vlvf_slot(struct ixgbe_hw *hw, u32 vlan, bool vlvf_bypass)
 {
-	u32 bits = 0;
-	u32 first_empty_slot = 0;
-	s32 regindex;
+	s32 regindex, first_empty_slot;
+	u32 bits;
 
 	/* short cut the special case */
 	if (vlan == 0)
 		return 0;
 
-	/*
-	  * Search for the vlan id in the VLVF entries. Save off the first empty
-	  * slot found along the way
-	  */
-	for (regindex = 1; regindex < IXGBE_VLVF_ENTRIES; regindex++) {
+	/* if vlvf_bypass is set we don't want to use an empty slot, we
+	 * will simply bypass the VLVF if there are no entries present in the
+	 * VLVF that contain our VLAN
+	 */
+	first_empty_slot = vlvf_bypass ? IXGBE_ERR_NO_SPACE : 0;
+
+	/* add VLAN enable bit for comparison */
+	vlan |= IXGBE_VLVF_VIEN;
+
+	/* Search for the vlan id in the VLVF entries. Save off the first empty
+	 * slot found along the way.
+	 *
+	 * pre-decrement loop covering (IXGBE_VLVF_ENTRIES - 1) .. 1
+	 */
+	for (regindex = IXGBE_VLVF_ENTRIES; --regindex;) {
 		bits = IXGBE_READ_REG(hw, IXGBE_VLVF(regindex));
-		if (!bits && !(first_empty_slot))
+		if (bits == vlan)
+			return regindex;
+		if (!first_empty_slot && !bits)
 			first_empty_slot = regindex;
-		else if ((bits & 0x0FFF) == vlan)
-			break;
 	}
 
-	/*
-	  * If regindex is less than IXGBE_VLVF_ENTRIES, then we found the vlan
-	  * in the VLVF. Else use the first empty VLVF register for this
-	  * vlan id.
-	  */
-	if (regindex >= IXGBE_VLVF_ENTRIES) {
-		if (first_empty_slot)
-			regindex = first_empty_slot;
-		else {
-			hw_dbg(hw, "No space in VLVF.\n");
-			regindex = IXGBE_ERR_NO_SPACE;
-		}
-	}
+	/* If we are here then we didn't find the VLAN.  Return first empty
+	 * slot we found during our search, else error.
+	 */
+	if (!first_empty_slot)
+		hw_dbg(hw, "No space in VLVF.\n");
 
-	return regindex;
+	return first_empty_slot ? : IXGBE_ERR_NO_SPACE;
 }
 
 /**
@@ -3032,21 +3046,17 @@ static s32 ixgbe_find_vlvf_slot(struct i
  *  @vlan: VLAN id to write to VLAN filter
  *  @vind: VMDq output index that maps queue to VLAN id in VFVFB
  *  @vlan_on: boolean flag to turn on/off VLAN in VFVF
+ *  @vlvf_bypass: boolean flag indicating updating default pool is okay
  *
  *  Turn on/off specified VLAN in the VLAN filter table.
  **/
 s32 ixgbe_set_vfta_generic(struct ixgbe_hw *hw, u32 vlan, u32 vind,
-			   bool vlan_on)
+			   bool vlan_on, bool vlvf_bypass)
 {
-	s32 regindex;
-	u32 bitindex;
-	u32 vfta;
-	u32 bits;
-	u32 vt;
-	u32 targetbit;
-	bool vfta_changed = false;
+	u32 regidx, vfta_delta, vfta, bits;
+	s32 vlvf_index;
 
-	if (vlan > 4095)
+	if ((vlan > 4095) || (vind > 63))
 		return IXGBE_ERR_PARAM;
 
 	/*
@@ -3061,22 +3071,16 @@ s32 ixgbe_set_vfta_generic(struct ixgbe_
 	 *    bits[11-5]: which register
 	 *    bits[4-0]:  which bit in the register
 	 */
-	regindex = (vlan >> 5) & 0x7F;
-	bitindex = vlan & 0x1F;
-	targetbit = (1 << bitindex);
-	vfta = IXGBE_READ_REG(hw, IXGBE_VFTA(regindex));
-
-	if (vlan_on) {
-		if (!(vfta & targetbit)) {
-			vfta |= targetbit;
-			vfta_changed = true;
-		}
-	} else {
-		if ((vfta & targetbit)) {
-			vfta &= ~targetbit;
-			vfta_changed = true;
-		}
-	}
+	regidx = vlan / 32;
+	vfta_delta = 1 << (vlan % 32);
+	vfta = IXGBE_READ_REG(hw, IXGBE_VFTA(regidx));
+
+	/* vfta_delta represents the difference between the current value
+	 * of vfta and the value we want in the register.  Since the diff
+	 * is an XOR mask we can just update vfta using an XOR.
+	 */
+	vfta_delta &= vlan_on ? ~vfta : vfta;
+	vfta ^= vfta_delta;
 
 	/* Part 2
 	 * If VT Mode is set
@@ -3086,85 +3090,67 @@ s32 ixgbe_set_vfta_generic(struct ixgbe_
 	 *   Or !vlan_on
 	 *     clear the pool bit and possibly the vind
 	 */
-	vt = IXGBE_READ_REG(hw, IXGBE_VT_CTL);
-	if (vt & IXGBE_VT_CTL_VT_ENABLE) {
-		s32 vlvf_index;
-
-		vlvf_index = ixgbe_find_vlvf_slot(hw, vlan);
-		if (vlvf_index < 0)
-			return vlvf_index;
-
-		if (vlan_on) {
-			/* set the pool bit */
-			if (vind < 32) {
-				bits = IXGBE_READ_REG(hw,
-						IXGBE_VLVFB(vlvf_index*2));
-				bits |= (1 << vind);
-				IXGBE_WRITE_REG(hw,
-						IXGBE_VLVFB(vlvf_index*2),
-						bits);
-			} else {
-				bits = IXGBE_READ_REG(hw,
-						IXGBE_VLVFB((vlvf_index*2)+1));
-				bits |= (1 << (vind-32));
-				IXGBE_WRITE_REG(hw,
-						IXGBE_VLVFB((vlvf_index*2)+1),
-						bits);
-			}
-		} else {
-			/* clear the pool bit */
-			if (vind < 32) {
-				bits = IXGBE_READ_REG(hw,
-						IXGBE_VLVFB(vlvf_index*2));
-				bits &= ~(1 << vind);
-				IXGBE_WRITE_REG(hw,
-						IXGBE_VLVFB(vlvf_index*2),
-						bits);
-				bits |= IXGBE_READ_REG(hw,
-						IXGBE_VLVFB((vlvf_index*2)+1));
-			} else {
-				bits = IXGBE_READ_REG(hw,
-						IXGBE_VLVFB((vlvf_index*2)+1));
-				bits &= ~(1 << (vind-32));
-				IXGBE_WRITE_REG(hw,
-						IXGBE_VLVFB((vlvf_index*2)+1),
-						bits);
-				bits |= IXGBE_READ_REG(hw,
-						IXGBE_VLVFB(vlvf_index*2));
-			}
-		}
+	if (!(IXGBE_READ_REG(hw, IXGBE_VT_CTL) & IXGBE_VT_CTL_VT_ENABLE))
+		goto vfta_update;
 
-		/*
-		 * If there are still bits set in the VLVFB registers
-		 * for the VLAN ID indicated we need to see if the
-		 * caller is requesting that we clear the VFTA entry bit.
-		 * If the caller has requested that we clear the VFTA
-		 * entry bit but there are still pools/VFs using this VLAN
-		 * ID entry then ignore the request.  We're not worried
-		 * about the case where we're turning the VFTA VLAN ID
-		 * entry bit on, only when requested to turn it off as
-		 * there may be multiple pools and/or VFs using the
-		 * VLAN ID entry.  In that case we cannot clear the
-		 * VFTA bit until all pools/VFs using that VLAN ID have also
-		 * been cleared.  This will be indicated by "bits" being
-		 * zero.
+	vlvf_index = ixgbe_find_vlvf_slot(hw, vlan, vlvf_bypass);
+	if (vlvf_index < 0) {
+		if (vlvf_bypass)
+			goto vfta_update;
+		return vlvf_index;
+	}
+
+	bits = IXGBE_READ_REG(hw, IXGBE_VLVFB(vlvf_index * 2 + vind / 32));
+
+	/* set the pool bit */
+	bits |= 1 << (vind % 32);
+	if (vlan_on)
+		goto vlvf_update;
+
+	/* clear the pool bit */
+	bits ^= 1 << (vind % 32);
+
+	if (!bits &&
+	    !IXGBE_READ_REG(hw, IXGBE_VLVFB(vlvf_index * 2 + 1 - vind / 32))) {
+		/* Clear VFTA first, then disable VLVF.  Otherwise
+		 * we run the risk of stray packets leaking into
+		 * the PF via the default pool
 		 */
-		if (bits) {
-			IXGBE_WRITE_REG(hw, IXGBE_VLVF(vlvf_index),
-					(IXGBE_VLVF_VIEN | vlan));
-			if (!vlan_on) {
-				/* someone wants to clear the vfta entry
-				 * but some pools/VFs are still using it.
-				 * Ignore it. */
-				vfta_changed = false;
-			}
-		} else {
-			IXGBE_WRITE_REG(hw, IXGBE_VLVF(vlvf_index), 0);
-		}
+		if (vfta_delta)
+			IXGBE_WRITE_REG(hw, IXGBE_VFTA(regidx), vfta);
+
+		/* disable VLVF and clear remaining bit from pool */
+		IXGBE_WRITE_REG(hw, IXGBE_VLVF(vlvf_index), 0);
+		IXGBE_WRITE_REG(hw, IXGBE_VLVFB(vlvf_index * 2 + vind / 32), 0);
+
+		return 0;
 	}
 
-	if (vfta_changed)
-		IXGBE_WRITE_REG(hw, IXGBE_VFTA(regindex), vfta);
+	/* If there are still bits set in the VLVFB registers
+	 * for the VLAN ID indicated we need to see if the
+	 * caller is requesting that we clear the VFTA entry bit.
+	 * If the caller has requested that we clear the VFTA
+	 * entry bit but there are still pools/VFs using this VLAN
+	 * ID entry then ignore the request.  We're not worried
+	 * about the case where we're turning the VFTA VLAN ID
+	 * entry bit on, only when requested to turn it off as
+	 * there may be multiple pools and/or VFs using the
+	 * VLAN ID entry.  In that case we cannot clear the
+	 * VFTA bit until all pools/VFs using that VLAN ID have also
+	 * been cleared.  This will be indicated by "bits" being
+	 * zero.
+	 */
+	vfta_delta = 0;
+
+vlvf_update:
+	/* record pool change and enable VLAN ID if not already enabled */
+	IXGBE_WRITE_REG(hw, IXGBE_VLVFB(vlvf_index * 2 + vind / 32), bits);
+	IXGBE_WRITE_REG(hw, IXGBE_VLVF(vlvf_index), IXGBE_VLVF_VIEN | vlan);
+
+vfta_update:
+	/* Update VFTA now that we are ready for traffic */
+	if (vfta_delta)
+		IXGBE_WRITE_REG(hw, IXGBE_VFTA(regidx), vfta);
 
 	return 0;
 }
@@ -3184,8 +3170,8 @@ s32 ixgbe_clear_vfta_generic(struct ixgb
 
 	for (offset = 0; offset < IXGBE_VLVF_ENTRIES; offset++) {
 		IXGBE_WRITE_REG(hw, IXGBE_VLVF(offset), 0);
-		IXGBE_WRITE_REG(hw, IXGBE_VLVFB(offset*2), 0);
-		IXGBE_WRITE_REG(hw, IXGBE_VLVFB((offset*2)+1), 0);
+		IXGBE_WRITE_REG(hw, IXGBE_VLVFB(offset * 2), 0);
+		IXGBE_WRITE_REG(hw, IXGBE_VLVFB(offset * 2 + 1), 0);
 	}
 
 	return 0;
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/intel/ixgbe/ixgbe_common.h
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/intel/ixgbe/ixgbe_common.h
@@ -92,7 +92,7 @@ s32 ixgbe_set_vmdq_san_mac_generic(struc
 s32 ixgbe_clear_vmdq_generic(struct ixgbe_hw *hw, u32 rar, u32 vmdq);
 s32 ixgbe_init_uta_tables_generic(struct ixgbe_hw *hw);
 s32 ixgbe_set_vfta_generic(struct ixgbe_hw *hw, u32 vlan,
-			   u32 vind, bool vlan_on);
+			   u32 vind, bool vlan_on, bool vlvf_bypass);
 s32 ixgbe_clear_vfta_generic(struct ixgbe_hw *hw);
 s32 ixgbe_check_mac_link_generic(struct ixgbe_hw *hw,
 				 ixgbe_link_speed *speed,
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb.c
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb.c
@@ -139,6 +139,11 @@ s32 ixgbe_dcb_calculate_tc_credits(struc
 		/* Calculate credit refill ratio using multiplier */
 		credit_refill = min(link_percentage * min_multiplier,
 				    MAX_CREDIT_REFILL);
+
+		/* Refill at least minimum credit */
+		if (credit_refill < min_credit)
+			credit_refill = min_credit;
+
 		p->data_credits_refill = (u16)credit_refill;
 
 		/* Calculate maximum credit for the TC */
@@ -149,7 +154,7 @@ s32 ixgbe_dcb_calculate_tc_credits(struc
 		 * of a TC is too small, the maximum credit may not be
 		 * enough to send out a jumbo frame in data plane arbitration.
 		 */
-		if (credit_max && (credit_max < min_credit))
+		if (credit_max < min_credit)
 			credit_max = min_credit;
 
 		if (direction == DCB_TX_CONFIG) {
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_82599.c
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_82599.c
@@ -223,13 +223,13 @@ s32 ixgbe_dcb_config_pfc_82599(struct ix
 	reg |= IXGBE_MFLCN_DPF;
 
 	/*
-	 * X540 supports per TC Rx priority flow control.  So
-	 * clear all TCs and only enable those that should be
+	 * X540 & X550 supports per TC Rx priority flow control.
+	 * So clear all TCs and only enable those that should be
 	 * enabled.
 	 */
 	reg &= ~(IXGBE_MFLCN_RPFCE_MASK | IXGBE_MFLCN_RFCE);
 
-	if (hw->mac.type == ixgbe_mac_X540)
+	if (hw->mac.type >= ixgbe_mac_X540)
 		reg |= pfc_en << IXGBE_MFLCN_RPFCE_SHIFT;
 
 	if (pfc_en)
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c
@@ -151,47 +151,70 @@ static const char ixgbe_gstrings_test[][
 };
 #define IXGBE_TEST_LEN sizeof(ixgbe_gstrings_test) / ETH_GSTRING_LEN
 
+/* currently supported speeds for 10G */
+#define ADVRTSD_MSK_10G (SUPPORTED_10000baseT_Full | \
+			 SUPPORTED_10000baseKX4_Full | \
+			 SUPPORTED_10000baseKR_Full)
+
+#define ixgbe_isbackplane(type) ((type) == ixgbe_media_type_backplane)
+
+static u32 ixgbe_get_supported_10gtypes(struct ixgbe_hw *hw)
+{
+	if (!ixgbe_isbackplane(hw->phy.media_type))
+		return SUPPORTED_10000baseT_Full;
+
+	switch (hw->device_id) {
+	case IXGBE_DEV_ID_82598:
+	case IXGBE_DEV_ID_82599_KX4:
+	case IXGBE_DEV_ID_82599_KX4_MEZZ:
+	case IXGBE_DEV_ID_X550EM_X_KX4:
+		return SUPPORTED_10000baseKX4_Full;
+	case IXGBE_DEV_ID_82598_BX:
+	case IXGBE_DEV_ID_82599_KR:
+	case IXGBE_DEV_ID_X550EM_X_KR:
+		return SUPPORTED_10000baseKR_Full;
+	default:
+		return SUPPORTED_10000baseKX4_Full |
+		       SUPPORTED_10000baseKR_Full;
+	}
+}
+
 static int ixgbe_get_settings(struct net_device *netdev,
 			      struct ethtool_cmd *ecmd)
 {
 	struct ixgbe_adapter *adapter = netdev_priv(netdev);
 	struct ixgbe_hw *hw = &adapter->hw;
 	ixgbe_link_speed supported_link;
-	u32 link_speed = 0;
 	bool autoneg = false;
-	bool link_up;
 
 	hw->mac.ops.get_link_capabilities(hw, &supported_link, &autoneg);
 
 	/* set the supported link speeds */
 	if (supported_link & IXGBE_LINK_SPEED_10GB_FULL)
-		ecmd->supported |= SUPPORTED_10000baseT_Full;
-	if (supported_link & IXGBE_LINK_SPEED_2_5GB_FULL)
-		ecmd->supported |= SUPPORTED_2500baseX_Full;
+		ecmd->supported |= ixgbe_get_supported_10gtypes(hw);
 	if (supported_link & IXGBE_LINK_SPEED_1GB_FULL)
 		ecmd->supported |= SUPPORTED_1000baseT_Full;
 	if (supported_link & IXGBE_LINK_SPEED_100_FULL)
-		ecmd->supported |= SUPPORTED_100baseT_Full;
+		ecmd->supported |= ixgbe_isbackplane(hw->phy.media_type) ?
+				   SUPPORTED_1000baseKX_Full :
+				   SUPPORTED_1000baseT_Full;
 
+	/* default advertised speed if phy.autoneg_advertised isn't set */
+	ecmd->advertising = ecmd->supported;
 	/* set the advertised speeds */
 	if (hw->phy.autoneg_advertised) {
+		ecmd->advertising = 0;
 		if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_100_FULL)
 			ecmd->advertising |= ADVERTISED_100baseT_Full;
 		if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_10GB_FULL)
-			ecmd->advertising |= ADVERTISED_10000baseT_Full;
-		if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_2_5GB_FULL)
-			ecmd->advertising |= ADVERTISED_2500baseX_Full;
-		if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_1GB_FULL)
-			ecmd->advertising |= ADVERTISED_1000baseT_Full;
+			ecmd->advertising |= ecmd->supported & ADVRTSD_MSK_10G;
+		if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_1GB_FULL) {
+			if (ecmd->supported & SUPPORTED_1000baseKX_Full)
+				ecmd->advertising |= ADVERTISED_1000baseKX_Full;
+			else
+				ecmd->advertising |= ADVERTISED_1000baseT_Full;
+		}
 	} else {
-		/* default modes in case phy.autoneg_advertised isn't set */
-		if (supported_link & IXGBE_LINK_SPEED_10GB_FULL)
-			ecmd->advertising |= ADVERTISED_10000baseT_Full;
-		if (supported_link & IXGBE_LINK_SPEED_1GB_FULL)
-			ecmd->advertising |= ADVERTISED_1000baseT_Full;
-		if (supported_link & IXGBE_LINK_SPEED_100_FULL)
-			ecmd->advertising |= ADVERTISED_100baseT_Full;
-
 		if (hw->phy.multispeed_fiber && !autoneg) {
 			if (supported_link & IXGBE_LINK_SPEED_10GB_FULL)
 				ecmd->advertising = ADVERTISED_10000baseT_Full;
@@ -229,6 +252,10 @@ static int ixgbe_get_settings(struct net
 	case ixgbe_phy_sfp_avago:
 	case ixgbe_phy_sfp_intel:
 	case ixgbe_phy_sfp_unknown:
+	case ixgbe_phy_qsfp_passive_unknown:
+	case ixgbe_phy_qsfp_active_unknown:
+	case ixgbe_phy_qsfp_intel:
+	case ixgbe_phy_qsfp_unknown:
 		/* SFP+ devices, further checking needed */
 		switch (adapter->hw.phy.sfp_type) {
 		case ixgbe_sfp_type_da_cu:
@@ -284,9 +311,8 @@ static int ixgbe_get_settings(struct net
 		break;
 	}
 
-	hw->mac.ops.check_link(hw, &link_speed, &link_up, false);
-	if (link_up) {
-		switch (link_speed) {
+	if (netif_carrier_ok(netdev)) {
+		switch (adapter->link_speed) {
 		case IXGBE_LINK_SPEED_10GB_FULL:
 			ethtool_cmd_speed_set(ecmd, SPEED_10000);
 			break;
@@ -2494,9 +2520,9 @@ static int ixgbe_get_rxnfc(struct net_de
 	return ret;
 }
 
-static int ixgbe_update_ethtool_fdir_entry(struct ixgbe_adapter *adapter,
-					   struct ixgbe_fdir_filter *input,
-					   u16 sw_idx)
+int ixgbe_update_ethtool_fdir_entry(struct ixgbe_adapter *adapter,
+				    struct ixgbe_fdir_filter *input,
+				    u16 sw_idx)
 {
 	struct ixgbe_hw *hw = &adapter->hw;
 	struct hlist_node *node2;
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/intel/ixgbe/ixgbe_fcoe.c
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/intel/ixgbe/ixgbe_fcoe.c
@@ -77,7 +77,7 @@ int ixgbe_fcoe_ddp_put(struct net_device
 	if (!netdev)
 		return 0;
 
-	if (xid >= IXGBE_FCOE_DDP_MAX)
+	if (xid >= netdev->fcoe_ddp_xid)
 		return 0;
 
 	adapter = netdev_priv(netdev);
@@ -177,7 +177,7 @@ static int ixgbe_fcoe_ddp_setup(struct n
 		return 0;
 
 	adapter = netdev_priv(netdev);
-	if (xid >= IXGBE_FCOE_DDP_MAX) {
+	if (xid >= netdev->fcoe_ddp_xid) {
 		e_warn(drv, "xid=0x%x out-of-range\n", xid);
 		return 0;
 	}
@@ -517,6 +517,7 @@ int ixgbe_fso(struct ixgbe_ring *tx_ring
 	u32 vlan_macip_lens;
 	u32 fcoe_sof_eof = 0;
 	u32 mss_l4len_idx;
+	u32 type_tucmd = IXGBE_ADVTXT_TUCMD_FCOE;
 	u8 sof, eof;
 
 	if (skb_is_gso(skb) && (skb_shinfo(skb)->gso_type != SKB_GSO_FCOE)) {
@@ -593,6 +594,8 @@ int ixgbe_fso(struct ixgbe_ring *tx_ring
 					       skb_shinfo(skb)->gso_size);
 		first->bytecount += (first->gso_segs - 1) * *hdr_len;
 		first->tx_flags |= IXGBE_TX_FLAGS_TSO;
+		/* Hardware expects L4T to be RSV for FCoE TSO */
+		type_tucmd |= IXGBE_ADVTXD_TUCMD_L4T_RSV;
 	}
 
 	/* set flag indicating FCOE to ixgbe_tx_map call */
@@ -610,7 +613,7 @@ int ixgbe_fso(struct ixgbe_ring *tx_ring
 
 	/* write context desc */
 	ixgbe_tx_ctxtdesc(tx_ring, vlan_macip_lens, fcoe_sof_eof,
-			  IXGBE_ADVTXT_TUCMD_FCOE, mss_l4len_idx);
+			  type_tucmd, mss_l4len_idx);
 
 	return 0;
 }
@@ -620,8 +623,7 @@ static void ixgbe_fcoe_dma_pool_free(str
 	struct ixgbe_fcoe_ddp_pool *ddp_pool;
 
 	ddp_pool = per_cpu_ptr(fcoe->ddp_pool, cpu);
-	if (ddp_pool->pool)
-		dma_pool_destroy(ddp_pool->pool);
+	dma_pool_destroy(ddp_pool->pool);
 	ddp_pool->pool = NULL;
 }
 
@@ -997,8 +999,7 @@ int ixgbe_fcoe_get_hbainfo(struct net_de
 		return -EINVAL;
 
 	/* Don't return information on unsupported devices */
-	if (hw->mac.type != ixgbe_mac_82599EB &&
-	    hw->mac.type != ixgbe_mac_X540)
+	if (!(adapter->flags & IXGBE_FLAG_FCOE_ENABLED))
 		return -EINVAL;
 
 	/* Manufacturer */
@@ -1044,6 +1045,10 @@ int ixgbe_fcoe_get_hbainfo(struct net_de
 		snprintf(info->model,
 			 sizeof(info->model),
 			 "Intel 82599");
+	} else if (hw->mac.type == ixgbe_mac_X550) {
+		snprintf(info->model,
+			 sizeof(info->model),
+			 "Intel X550");
 	} else {
 		snprintf(info->model,
 			 sizeof(info->model),
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -51,6 +51,8 @@
 #include <linux/prefetch.h>
 #include <scsi/fc/fc_fcoe.h>
 #include <net/vxlan.h>
+#include <net/pkt_cls.h>
+#include <net/tc_act/tc_gact.h>
 
 #ifdef CONFIG_OF
 #include <linux/of_net.h>
@@ -65,9 +67,7 @@
 #include "ixgbe_common.h"
 #include "ixgbe_dcb_82599.h"
 #include "ixgbe_sriov.h"
-#ifdef CONFIG_IXGBE_VXLAN
-#include <net/vxlan.h>
-#endif
+#include "ixgbe_model.h"
 
 char ixgbe_driver_name[] = "ixgbe";
 static const char ixgbe_driver_string[] =
@@ -175,6 +175,8 @@ MODULE_DESCRIPTION("Intel(R) 10 Gigabit
 MODULE_LICENSE("GPL");
 MODULE_VERSION(DRV_VERSION);
 
+static struct workqueue_struct *ixgbe_wq;
+
 static bool ixgbe_check_cfg_remove(struct ixgbe_hw *hw, struct pci_dev *pdev);
 
 static int ixgbe_read_pci_cfg_word_parent(struct ixgbe_adapter *adapter,
@@ -316,7 +318,7 @@ static void ixgbe_service_event_schedule
 	if (!test_bit(__IXGBE_DOWN, &adapter->state) &&
 	    !test_bit(__IXGBE_REMOVING, &adapter->state) &&
 	    !test_and_set_bit(__IXGBE_SERVICE_SCHED, &adapter->state))
-		schedule_work(&adapter->service_task);
+		queue_work(ixgbe_wq, &adapter->service_task);
 }
 
 static void ixgbe_remove_adapter(struct ixgbe_hw *hw)
@@ -1088,9 +1090,10 @@ static void ixgbe_tx_timeout_reset(struc
  * ixgbe_clean_tx_irq - Reclaim resources after transmit completes
  * @q_vector: structure containing interrupt and ring information
  * @tx_ring: tx ring to clean
+ * @napi_budget: Used to determine if we are in netpoll
  **/
 static bool ixgbe_clean_tx_irq(struct ixgbe_q_vector *q_vector,
-			       struct ixgbe_ring *tx_ring)
+			       struct ixgbe_ring *tx_ring, int napi_budget)
 {
 	struct ixgbe_adapter *adapter = q_vector->adapter;
 	struct ixgbe_tx_buffer *tx_buffer;
@@ -1128,7 +1131,7 @@ static bool ixgbe_clean_tx_irq(struct ix
 		total_packets += tx_buffer->gso_segs;
 
 		/* free the skb */
-		dev_consume_skb_any(tx_buffer->skb);
+		napi_consume_skb(tx_buffer->skb, napi_budget);
 
 		/* unmap skb header data */
 		dma_unmap_single(tx_ring->dev,
@@ -1484,7 +1487,7 @@ static inline void ixgbe_rx_checksum(str
 			return;
 
 		if (ixgbe_test_staterr(rx_desc, IXGBE_RXDADV_ERR_OUTERIPER)) {
-			ring->rx_stats.csum_err++;
+			skb->ip_summed = CHECKSUM_NONE;
 			return;
 		}
 		/* If we checked the outer header let the stack know */
@@ -1635,6 +1638,7 @@ static void ixgbe_process_skb_fields(str
 				     struct sk_buff *skb)
 {
 	struct net_device *dev = rx_ring->netdev;
+	u32 flags = rx_ring->q_vector->adapter->flags;
 
 	ixgbe_update_rsc_stats(rx_ring, skb);
 
@@ -1642,8 +1646,8 @@ static void ixgbe_process_skb_fields(str
 
 	ixgbe_rx_checksum(rx_ring, rx_desc, skb);
 
-	if (unlikely(ixgbe_test_staterr(rx_desc, IXGBE_RXDADV_STAT_TS)))
-		ixgbe_ptp_rx_hwtstamp(rx_ring->q_vector->adapter, skb);
+	if (unlikely(flags & IXGBE_FLAG_RX_HWTSTAMP_ENABLED))
+		ixgbe_ptp_rx_hwtstamp(rx_ring, rx_desc, skb);
 
 	if ((dev->features & NETIF_F_HW_VLAN_CTAG_RX) &&
 	    ixgbe_test_staterr(rx_desc, IXGBE_RXD_STAT_VP)) {
@@ -2741,7 +2745,7 @@ static irqreturn_t ixgbe_msix_other(int
 	ixgbe_check_fan_failure(adapter, eicr);
 
 	if (unlikely(eicr & IXGBE_EICR_TIMESYNC))
-		ixgbe_ptp_check_pps_event(adapter, eicr);
+		ixgbe_ptp_check_pps_event(adapter);
 
 	/* re-enable the original interrupt state, no lsc, no queues */
 	if (!test_bit(__IXGBE_DOWN, &adapter->state))
@@ -2757,7 +2761,7 @@ static irqreturn_t ixgbe_msix_clean_ring
 	/* EIAM disabled interrupts (on this vector) for us */
 
 	if (q_vector->rx.ring || q_vector->tx.ring)
-		napi_schedule(&q_vector->napi);
+		napi_schedule_irqoff(&q_vector->napi);
 
 	return IRQ_HANDLED;
 }
@@ -2783,10 +2787,13 @@ int ixgbe_poll(struct napi_struct *napi,
 		ixgbe_update_dca(q_vector);
 #endif
 
-	ixgbe_for_each_ring(ring, q_vector->tx)
-		clean_complete &= !!ixgbe_clean_tx_irq(q_vector, ring);
+	ixgbe_for_each_ring(ring, q_vector->tx) {
+		if (!ixgbe_clean_tx_irq(q_vector, ring, budget))
+			clean_complete = false;
+	}
 
-	if (!ixgbe_qv_lock_napi(q_vector))
+	/* Exit if we are called by netpoll or busy polling is active */
+	if ((budget <= 0) || !ixgbe_qv_lock_napi(q_vector))
 		return budget;
 
 	/* attempt to distribute budget to each queue fairly, but don't allow
@@ -2801,7 +2808,8 @@ int ixgbe_poll(struct napi_struct *napi,
 						 per_ring_budget);
 
 		work_done += cleaned;
-		clean_complete &= (cleaned < per_ring_budget);
+		if (cleaned >= per_ring_budget)
+			clean_complete = false;
 	}
 
 	ixgbe_qv_unlock_napi(q_vector);
@@ -2947,10 +2955,10 @@ static irqreturn_t ixgbe_intr(int irq, v
 
 	ixgbe_check_fan_failure(adapter, eicr);
 	if (unlikely(eicr & IXGBE_EICR_TIMESYNC))
-		ixgbe_ptp_check_pps_event(adapter, eicr);
+		ixgbe_ptp_check_pps_event(adapter);
 
 	/* would disable interrupts here but EIAM disabled it */
-	napi_schedule(&q_vector->napi);
+	napi_schedule_irqoff(&q_vector->napi);
 
 	/*
 	 * re-enable link(maybe) and non-queue interrupts, no flush.
@@ -3315,8 +3323,7 @@ static void ixgbe_configure_srrctl(struc
 }
 
 /**
- * Return a number of entries in the RSS indirection table
- *
+ * ixgbe_rss_indir_tbl_entries - Return RSS indirection table entries
  * @adapter: device handle
  *
  *  - 82598/82599/X540:     128
@@ -3334,8 +3341,7 @@ u32 ixgbe_rss_indir_tbl_entries(struct i
 }
 
 /**
- * Write the RETA table to HW
- *
+ * ixgbe_store_reta - Write the RETA table to HW
  * @adapter: device handle
  *
  * Write the RSS redirection table stored in adapter.rss_indir_tbl[] to HW.
@@ -3374,8 +3380,7 @@ void ixgbe_store_reta(struct ixgbe_adapt
 }
 
 /**
- * Write the RETA table to HW (for x550 devices in SRIOV mode)
- *
+ * ixgbe_store_vfreta - Write the RETA table to HW (x550 devices in SRIOV mode)
  * @adapter: device handle
  *
  * Write the RSS redirection table stored in adapter.rss_indir_tbl[] to HW.
@@ -3621,6 +3626,9 @@ void ixgbe_configure_rx_ring(struct ixgb
 	IXGBE_WRITE_REG(hw, IXGBE_RDBAH(reg_idx), (rdba >> 32));
 	IXGBE_WRITE_REG(hw, IXGBE_RDLEN(reg_idx),
 			ring->count * sizeof(union ixgbe_adv_rx_desc));
+	/* Force flushing of IXGBE_RDLEN to prevent MDD */
+	IXGBE_WRITE_FLUSH(hw);
+
 	IXGBE_WRITE_REG(hw, IXGBE_RDH(reg_idx), 0);
 	IXGBE_WRITE_REG(hw, IXGBE_RDT(reg_idx), 0);
 	ring->tail = adapter->io_addr + IXGBE_RDT(reg_idx);
@@ -3704,6 +3712,9 @@ static void ixgbe_configure_virtualizati
 	/* Map PF MAC address in RAR Entry 0 to first pool following VFs */
 	hw->mac.ops.set_vmdq(hw, 0, VMDQ_P(0));
 
+	/* clear VLAN promisc flag so VFTA will be updated if necessary */
+	adapter->flags2 &= ~IXGBE_FLAG2_VLAN_PROMISC;
+
 	/*
 	 * Set up VF register offsets for selected VT Mode,
 	 * i.e. 32 or 64 VFs for SR-IOV
@@ -3901,12 +3912,56 @@ static int ixgbe_vlan_rx_add_vid(struct
 	struct ixgbe_hw *hw = &adapter->hw;
 
 	/* add VID to filter table */
-	hw->mac.ops.set_vfta(&adapter->hw, vid, VMDQ_P(0), true);
+	hw->mac.ops.set_vfta(&adapter->hw, vid, VMDQ_P(0), true, true);
 	set_bit(vid, adapter->active_vlans);
 
 	return 0;
 }
 
+static int ixgbe_find_vlvf_entry(struct ixgbe_hw *hw, u32 vlan)
+{
+	u32 vlvf;
+	int idx;
+
+	/* short cut the special case */
+	if (vlan == 0)
+		return 0;
+
+	/* Search for the vlan id in the VLVF entries */
+	for (idx = IXGBE_VLVF_ENTRIES; --idx;) {
+		vlvf = IXGBE_READ_REG(hw, IXGBE_VLVF(idx));
+		if ((vlvf & VLAN_VID_MASK) == vlan)
+			break;
+	}
+
+	return idx;
+}
+
+void ixgbe_update_pf_promisc_vlvf(struct ixgbe_adapter *adapter, u32 vid)
+{
+	struct ixgbe_hw *hw = &adapter->hw;
+	u32 bits, word;
+	int idx;
+
+	idx = ixgbe_find_vlvf_entry(hw, vid);
+	if (!idx)
+		return;
+
+	/* See if any other pools are set for this VLAN filter
+	 * entry other than the PF.
+	 */
+	word = idx * 2 + (VMDQ_P(0) / 32);
+	bits = ~(1 << (VMDQ_P(0)) % 32);
+	bits &= IXGBE_READ_REG(hw, IXGBE_VLVFB(word));
+
+	/* Disable the filter so this falls into the default pool. */
+	if (!bits && !IXGBE_READ_REG(hw, IXGBE_VLVFB(word ^ 1))) {
+		if (!(adapter->flags2 & IXGBE_FLAG2_VLAN_PROMISC))
+			IXGBE_WRITE_REG(hw, IXGBE_VLVFB(word), 0);
+		IXGBE_WRITE_REG(hw, IXGBE_VLVF(idx), 0);
+	}
+}
+
 static int ixgbe_vlan_rx_kill_vid(struct net_device *netdev,
 				  __be16 proto, u16 vid)
 {
@@ -3914,7 +3969,11 @@ static int ixgbe_vlan_rx_kill_vid(struct
 	struct ixgbe_hw *hw = &adapter->hw;
 
 	/* remove VID from filter table */
-	hw->mac.ops.set_vfta(&adapter->hw, vid, VMDQ_P(0), false);
+	if (adapter->flags2 & IXGBE_FLAG2_VLAN_PROMISC)
+		ixgbe_update_pf_promisc_vlvf(adapter, vid);
+	else
+		hw->mac.ops.set_vfta(hw, vid, VMDQ_P(0), false, true);
+
 	clear_bit(vid, adapter->active_vlans);
 
 	return 0;
@@ -3992,6 +4051,129 @@ static void ixgbe_vlan_strip_enable(stru
 	}
 }
 
+static void ixgbe_vlan_promisc_enable(struct ixgbe_adapter *adapter)
+{
+	struct ixgbe_hw *hw = &adapter->hw;
+	u32 vlnctrl, i;
+
+	switch (hw->mac.type) {
+	case ixgbe_mac_82599EB:
+	case ixgbe_mac_X540:
+	case ixgbe_mac_X550:
+	case ixgbe_mac_X550EM_x:
+	default:
+		if (adapter->flags & IXGBE_FLAG_VMDQ_ENABLED)
+			break;
+		/* fall through */
+	case ixgbe_mac_82598EB:
+		/* legacy case, we can just disable VLAN filtering */
+		vlnctrl = IXGBE_READ_REG(hw, IXGBE_VLNCTRL);
+		vlnctrl &= ~(IXGBE_VLNCTRL_VFE | IXGBE_VLNCTRL_CFIEN);
+		IXGBE_WRITE_REG(hw, IXGBE_VLNCTRL, vlnctrl);
+		return;
+	}
+
+	/* We are already in VLAN promisc, nothing to do */
+	if (adapter->flags2 & IXGBE_FLAG2_VLAN_PROMISC)
+		return;
+
+	/* Set flag so we don't redo unnecessary work */
+	adapter->flags2 |= IXGBE_FLAG2_VLAN_PROMISC;
+
+	/* Add PF to all active pools */
+	for (i = IXGBE_VLVF_ENTRIES; --i;) {
+		u32 reg_offset = IXGBE_VLVFB(i * 2 + VMDQ_P(0) / 32);
+		u32 vlvfb = IXGBE_READ_REG(hw, reg_offset);
+
+		vlvfb |= 1 << (VMDQ_P(0) % 32);
+		IXGBE_WRITE_REG(hw, reg_offset, vlvfb);
+	}
+
+	/* Set all bits in the VLAN filter table array */
+	for (i = hw->mac.vft_size; i--;)
+		IXGBE_WRITE_REG(hw, IXGBE_VFTA(i), ~0U);
+}
+
+#define VFTA_BLOCK_SIZE 8
+static void ixgbe_scrub_vfta(struct ixgbe_adapter *adapter, u32 vfta_offset)
+{
+	struct ixgbe_hw *hw = &adapter->hw;
+	u32 vfta[VFTA_BLOCK_SIZE] = { 0 };
+	u32 vid_start = vfta_offset * 32;
+	u32 vid_end = vid_start + (VFTA_BLOCK_SIZE * 32);
+	u32 i, vid, word, bits;
+
+	for (i = IXGBE_VLVF_ENTRIES; --i;) {
+		u32 vlvf = IXGBE_READ_REG(hw, IXGBE_VLVF(i));
+
+		/* pull VLAN ID from VLVF */
+		vid = vlvf & VLAN_VID_MASK;
+
+		/* only concern outselves with a certain range */
+		if (vid < vid_start || vid >= vid_end)
+			continue;
+
+		if (vlvf) {
+			/* record VLAN ID in VFTA */
+			vfta[(vid - vid_start) / 32] |= 1 << (vid % 32);
+
+			/* if PF is part of this then continue */
+			if (test_bit(vid, adapter->active_vlans))
+				continue;
+		}
+
+		/* remove PF from the pool */
+		word = i * 2 + VMDQ_P(0) / 32;
+		bits = ~(1 << (VMDQ_P(0) % 32));
+		bits &= IXGBE_READ_REG(hw, IXGBE_VLVFB(word));
+		IXGBE_WRITE_REG(hw, IXGBE_VLVFB(word), bits);
+	}
+
+	/* extract values from active_vlans and write back to VFTA */
+	for (i = VFTA_BLOCK_SIZE; i--;) {
+		vid = (vfta_offset + i) * 32;
+		word = vid / BITS_PER_LONG;
+		bits = vid % BITS_PER_LONG;
+
+		vfta[i] |= adapter->active_vlans[word] >> bits;
+
+		IXGBE_WRITE_REG(hw, IXGBE_VFTA(vfta_offset + i), vfta[i]);
+	}
+}
+
+static void ixgbe_vlan_promisc_disable(struct ixgbe_adapter *adapter)
+{
+	struct ixgbe_hw *hw = &adapter->hw;
+	u32 vlnctrl, i;
+
+	switch (hw->mac.type) {
+	case ixgbe_mac_82599EB:
+	case ixgbe_mac_X540:
+	case ixgbe_mac_X550:
+	case ixgbe_mac_X550EM_x:
+	default:
+		if (adapter->flags & IXGBE_FLAG_VMDQ_ENABLED)
+			break;
+		/* fall through */
+	case ixgbe_mac_82598EB:
+		vlnctrl = IXGBE_READ_REG(hw, IXGBE_VLNCTRL);
+		vlnctrl &= ~IXGBE_VLNCTRL_CFIEN;
+		vlnctrl |= IXGBE_VLNCTRL_VFE;
+		IXGBE_WRITE_REG(hw, IXGBE_VLNCTRL, vlnctrl);
+		return;
+	}
+
+	/* We are not in VLAN promisc, nothing to do */
+	if (!(adapter->flags2 & IXGBE_FLAG2_VLAN_PROMISC))
+		return;
+
+	/* Set flag so we don't redo unnecessary work */
+	adapter->flags2 &= ~IXGBE_FLAG2_VLAN_PROMISC;
+
+	for (i = 0; i < hw->mac.vft_size; i += VFTA_BLOCK_SIZE)
+		ixgbe_scrub_vfta(adapter, i);
+}
+
 static void ixgbe_restore_vlan(struct ixgbe_adapter *adapter)
 {
 	u16 vid;
@@ -4034,124 +4216,156 @@ static int ixgbe_write_mc_addr_list(stru
 #ifdef CONFIG_PCI_IOV
 void ixgbe_full_sync_mac_table(struct ixgbe_adapter *adapter)
 {
+	struct ixgbe_mac_addr *mac_table = &adapter->mac_table[0];
 	struct ixgbe_hw *hw = &adapter->hw;
 	int i;
-	for (i = 0; i < hw->mac.num_rar_entries; i++) {
-		if (adapter->mac_table[i].state & IXGBE_MAC_STATE_IN_USE)
-			hw->mac.ops.set_rar(hw, i, adapter->mac_table[i].addr,
-					    adapter->mac_table[i].queue,
+
+	for (i = 0; i < hw->mac.num_rar_entries; i++, mac_table++) {
+		mac_table->state &= ~IXGBE_MAC_STATE_MODIFIED;
+
+		if (mac_table->state & IXGBE_MAC_STATE_IN_USE)
+			hw->mac.ops.set_rar(hw, i,
+					    mac_table->addr,
+					    mac_table->pool,
 					    IXGBE_RAH_AV);
 		else
 			hw->mac.ops.clear_rar(hw, i);
-
-		adapter->mac_table[i].state &= ~(IXGBE_MAC_STATE_MODIFIED);
 	}
 }
-#endif
 
+#endif
 static void ixgbe_sync_mac_table(struct ixgbe_adapter *adapter)
 {
+	struct ixgbe_mac_addr *mac_table = &adapter->mac_table[0];
 	struct ixgbe_hw *hw = &adapter->hw;
 	int i;
-	for (i = 0; i < hw->mac.num_rar_entries; i++) {
-		if (adapter->mac_table[i].state & IXGBE_MAC_STATE_MODIFIED) {
-			if (adapter->mac_table[i].state &
-			    IXGBE_MAC_STATE_IN_USE)
-				hw->mac.ops.set_rar(hw, i,
-						adapter->mac_table[i].addr,
-						adapter->mac_table[i].queue,
-						IXGBE_RAH_AV);
-			else
-				hw->mac.ops.clear_rar(hw, i);
 
-			adapter->mac_table[i].state &=
-						~(IXGBE_MAC_STATE_MODIFIED);
-		}
+	for (i = 0; i < hw->mac.num_rar_entries; i++, mac_table++) {
+		if (!(mac_table->state & IXGBE_MAC_STATE_MODIFIED))
+			continue;
+
+		mac_table->state &= ~IXGBE_MAC_STATE_MODIFIED;
+
+		if (mac_table->state & IXGBE_MAC_STATE_IN_USE)
+			hw->mac.ops.set_rar(hw, i,
+					    mac_table->addr,
+					    mac_table->pool,
+					    IXGBE_RAH_AV);
+		else
+			hw->mac.ops.clear_rar(hw, i);
 	}
 }
 
 static void ixgbe_flush_sw_mac_table(struct ixgbe_adapter *adapter)
 {
-	int i;
+	struct ixgbe_mac_addr *mac_table = &adapter->mac_table[0];
 	struct ixgbe_hw *hw = &adapter->hw;
+	int i;
 
-	for (i = 0; i < hw->mac.num_rar_entries; i++) {
-		adapter->mac_table[i].state |= IXGBE_MAC_STATE_MODIFIED;
-		adapter->mac_table[i].state &= ~IXGBE_MAC_STATE_IN_USE;
-		eth_zero_addr(adapter->mac_table[i].addr);
-		adapter->mac_table[i].queue = 0;
+	for (i = 0; i < hw->mac.num_rar_entries; i++, mac_table++) {
+		mac_table->state |= IXGBE_MAC_STATE_MODIFIED;
+		mac_table->state &= ~IXGBE_MAC_STATE_IN_USE;
 	}
+
 	ixgbe_sync_mac_table(adapter);
 }
 
-static int ixgbe_available_rars(struct ixgbe_adapter *adapter)
+static int ixgbe_available_rars(struct ixgbe_adapter *adapter, u16 pool)
 {
+	struct ixgbe_mac_addr *mac_table = &adapter->mac_table[0];
 	struct ixgbe_hw *hw = &adapter->hw;
 	int i, count = 0;
 
-	for (i = 0; i < hw->mac.num_rar_entries; i++) {
-		if (adapter->mac_table[i].state == 0)
-			count++;
+	for (i = 0; i < hw->mac.num_rar_entries; i++, mac_table++) {
+		/* do not count default RAR as available */
+		if (mac_table->state & IXGBE_MAC_STATE_DEFAULT)
+			continue;
+
+		/* only count unused and addresses that belong to us */
+		if (mac_table->state & IXGBE_MAC_STATE_IN_USE) {
+			if (mac_table->pool != pool)
+				continue;
+		}
+
+		count++;
 	}
+
 	return count;
 }
 
 /* this function destroys the first RAR entry */
-static void ixgbe_mac_set_default_filter(struct ixgbe_adapter *adapter,
-					 u8 *addr)
+static void ixgbe_mac_set_default_filter(struct ixgbe_adapter *adapter)
 {
+	struct ixgbe_mac_addr *mac_table = &adapter->mac_table[0];
 	struct ixgbe_hw *hw = &adapter->hw;
 
-	memcpy(&adapter->mac_table[0].addr, addr, ETH_ALEN);
-	adapter->mac_table[0].queue = VMDQ_P(0);
-	adapter->mac_table[0].state = (IXGBE_MAC_STATE_DEFAULT |
-				       IXGBE_MAC_STATE_IN_USE);
-	hw->mac.ops.set_rar(hw, 0, adapter->mac_table[0].addr,
-			    adapter->mac_table[0].queue,
+	memcpy(&mac_table->addr, hw->mac.addr, ETH_ALEN);
+	mac_table->pool = VMDQ_P(0);
+
+	mac_table->state = IXGBE_MAC_STATE_DEFAULT | IXGBE_MAC_STATE_IN_USE;
+
+	hw->mac.ops.set_rar(hw, 0, mac_table->addr, mac_table->pool,
 			    IXGBE_RAH_AV);
 }
 
-int ixgbe_add_mac_filter(struct ixgbe_adapter *adapter, u8 *addr, u16 queue)
+int ixgbe_add_mac_filter(struct ixgbe_adapter *adapter,
+			 const u8 *addr, u16 pool)
 {
+	struct ixgbe_mac_addr *mac_table = &adapter->mac_table[0];
 	struct ixgbe_hw *hw = &adapter->hw;
 	int i;
 
 	if (is_zero_ether_addr(addr))
 		return -EINVAL;
 
-	for (i = 0; i < hw->mac.num_rar_entries; i++) {
-		if (adapter->mac_table[i].state & IXGBE_MAC_STATE_IN_USE)
+	for (i = 0; i < hw->mac.num_rar_entries; i++, mac_table++) {
+		if (mac_table->state & IXGBE_MAC_STATE_IN_USE)
 			continue;
-		adapter->mac_table[i].state |= (IXGBE_MAC_STATE_MODIFIED |
-						IXGBE_MAC_STATE_IN_USE);
-		ether_addr_copy(adapter->mac_table[i].addr, addr);
-		adapter->mac_table[i].queue = queue;
+
+		ether_addr_copy(mac_table->addr, addr);
+		mac_table->pool = pool;
+
+		mac_table->state |= IXGBE_MAC_STATE_MODIFIED |
+				    IXGBE_MAC_STATE_IN_USE;
+
 		ixgbe_sync_mac_table(adapter);
+
 		return i;
 	}
+
 	return -ENOMEM;
 }
 
-int ixgbe_del_mac_filter(struct ixgbe_adapter *adapter, u8 *addr, u16 queue)
+int ixgbe_del_mac_filter(struct ixgbe_adapter *adapter,
+			 const u8 *addr, u16 pool)
 {
-	/* search table for addr, if found, set to 0 and sync */
-	int i;
+	struct ixgbe_mac_addr *mac_table = &adapter->mac_table[0];
 	struct ixgbe_hw *hw = &adapter->hw;
+	int i;
 
 	if (is_zero_ether_addr(addr))
 		return -EINVAL;
 
-	for (i = 0; i < hw->mac.num_rar_entries; i++) {
-		if (ether_addr_equal(addr, adapter->mac_table[i].addr) &&
-		    adapter->mac_table[i].queue == queue) {
-			adapter->mac_table[i].state |= IXGBE_MAC_STATE_MODIFIED;
-			adapter->mac_table[i].state &= ~IXGBE_MAC_STATE_IN_USE;
-			eth_zero_addr(adapter->mac_table[i].addr);
-			adapter->mac_table[i].queue = 0;
-			ixgbe_sync_mac_table(adapter);
-			return 0;
-		}
+	/* search table for addr, if found clear IN_USE flag and sync */
+	for (i = 0; i < hw->mac.num_rar_entries; i++, mac_table++) {
+		/* we can only delete an entry if it is in use */
+		if (!(mac_table->state & IXGBE_MAC_STATE_IN_USE))
+			continue;
+		/* we only care about entries that belong to the given pool */
+		if (mac_table->pool != pool)
+			continue;
+		/* we only care about a specific MAC address */
+		if (!ether_addr_equal(addr, mac_table->addr))
+			continue;
+
+		mac_table->state |= IXGBE_MAC_STATE_MODIFIED;
+		mac_table->state &= ~IXGBE_MAC_STATE_IN_USE;
+
+		ixgbe_sync_mac_table(adapter);
+
+		return 0;
 	}
+
 	return -ENOMEM;
 }
 /**
@@ -4169,7 +4383,7 @@ static int ixgbe_write_uc_addr_list(stru
 	int count = 0;
 
 	/* return ENOMEM indicating insufficient memory for addresses */
-	if (netdev_uc_count(netdev) > ixgbe_available_rars(adapter))
+	if (netdev_uc_count(netdev) > ixgbe_available_rars(adapter, vfn))
 		return -ENOMEM;
 
 	if (!netdev_uc_empty(netdev)) {
@@ -4183,6 +4397,25 @@ static int ixgbe_write_uc_addr_list(stru
 	return count;
 }
 
+static int ixgbe_uc_sync(struct net_device *netdev, const unsigned char *addr)
+{
+	struct ixgbe_adapter *adapter = netdev_priv(netdev);
+	int ret;
+
+	ret = ixgbe_add_mac_filter(adapter, addr, VMDQ_P(0));
+
+	return min_t(int, ret, 0);
+}
+
+static int ixgbe_uc_unsync(struct net_device *netdev, const unsigned char *addr)
+{
+	struct ixgbe_adapter *adapter = netdev_priv(netdev);
+
+	ixgbe_del_mac_filter(adapter, addr, VMDQ_P(0));
+
+	return 0;
+}
+
 /**
  * ixgbe_set_rx_mode - Unicast, Multicast and Promiscuous mode set
  * @netdev: network interface device structure
@@ -4197,12 +4430,10 @@ void ixgbe_set_rx_mode(struct net_device
 	struct ixgbe_adapter *adapter = netdev_priv(netdev);
 	struct ixgbe_hw *hw = &adapter->hw;
 	u32 fctrl, vmolr = IXGBE_VMOLR_BAM | IXGBE_VMOLR_AUPE;
-	u32 vlnctrl;
 	int count;
 
 	/* Check for Promiscuous and All Multicast modes */
 	fctrl = IXGBE_READ_REG(hw, IXGBE_FCTRL);
-	vlnctrl = IXGBE_READ_REG(hw, IXGBE_VLNCTRL);
 
 	/* set all bits that we expect to always be set */
 	fctrl &= ~IXGBE_FCTRL_SBP; /* disable store-bad-packets */
@@ -4212,25 +4443,18 @@ void ixgbe_set_rx_mode(struct net_device
 
 	/* clear the bits we are changing the status of */
 	fctrl &= ~(IXGBE_FCTRL_UPE | IXGBE_FCTRL_MPE);
-	vlnctrl &= ~(IXGBE_VLNCTRL_VFE | IXGBE_VLNCTRL_CFIEN);
 	if (netdev->flags & IFF_PROMISC) {
 		hw->addr_ctrl.user_set_promisc = true;
 		fctrl |= (IXGBE_FCTRL_UPE | IXGBE_FCTRL_MPE);
 		vmolr |= IXGBE_VMOLR_MPE;
-		/* Only disable hardware filter vlans in promiscuous mode
-		 * if SR-IOV and VMDQ are disabled - otherwise ensure
-		 * that hardware VLAN filters remain enabled.
-		 */
-		if (adapter->flags & (IXGBE_FLAG_VMDQ_ENABLED |
-				      IXGBE_FLAG_SRIOV_ENABLED))
-			vlnctrl |= (IXGBE_VLNCTRL_VFE | IXGBE_VLNCTRL_CFIEN);
+		ixgbe_vlan_promisc_enable(adapter);
 	} else {
 		if (netdev->flags & IFF_ALLMULTI) {
 			fctrl |= IXGBE_FCTRL_MPE;
 			vmolr |= IXGBE_VMOLR_MPE;
 		}
-		vlnctrl |= IXGBE_VLNCTRL_VFE;
 		hw->addr_ctrl.user_set_promisc = false;
+		ixgbe_vlan_promisc_disable(adapter);
 	}
 
 	/*
@@ -4238,8 +4462,7 @@ void ixgbe_set_rx_mode(struct net_device
 	 * sufficient space to store all the addresses then enable
 	 * unicast promiscuous mode
 	 */
-	count = ixgbe_write_uc_addr_list(netdev, VMDQ_P(0));
-	if (count < 0) {
+	if (__dev_uc_sync(netdev, ixgbe_uc_sync, ixgbe_uc_unsync)) {
 		fctrl |= IXGBE_FCTRL_UPE;
 		vmolr |= IXGBE_VMOLR_ROPE;
 	}
@@ -4275,7 +4498,6 @@ void ixgbe_set_rx_mode(struct net_device
 		/* NOTE:  VLAN filtering is disabled by setting PROMISC */
 	}
 
-	IXGBE_WRITE_REG(hw, IXGBE_VLNCTRL, vlnctrl);
 	IXGBE_WRITE_REG(hw, IXGBE_FCTRL, fctrl);
 
 	if (netdev->features & NETIF_F_HW_VLAN_CTAG_RX)
@@ -5042,7 +5264,6 @@ void ixgbe_reset(struct ixgbe_adapter *a
 	struct ixgbe_hw *hw = &adapter->hw;
 	struct net_device *netdev = adapter->netdev;
 	int err;
-	u8 old_addr[ETH_ALEN];
 
 	if (ixgbe_removed(hw->hw_addr))
 		return;
@@ -5078,10 +5299,13 @@ void ixgbe_reset(struct ixgbe_adapter *a
 	}
 
 	clear_bit(__IXGBE_IN_SFP_INIT, &adapter->state);
-	/* do not flush user set addresses */
-	memcpy(old_addr, &adapter->mac_table[0].addr, netdev->addr_len);
+
+	/* flush entries out of MAC table */
 	ixgbe_flush_sw_mac_table(adapter);
-	ixgbe_mac_set_default_filter(adapter, old_addr);
+	__dev_uc_unsync(netdev, NULL);
+
+	/* do not flush user set addresses */
+	ixgbe_mac_set_default_filter(adapter);
 
 	/* update SAN MAC vmdq pool selection */
 	if (hw->mac.san_mac_rar_index)
@@ -5328,9 +5552,14 @@ static int ixgbe_sw_init(struct ixgbe_ad
 #endif /* CONFIG_IXGBE_DCB */
 #endif /* IXGBE_FCOE */
 
+	/* initialize static ixgbe jump table entries */
+	adapter->jump_tables[0] = ixgbe_ipv4_fields;
+
 	adapter->mac_table = kzalloc(sizeof(struct ixgbe_mac_addr) *
 				     hw->mac.num_rar_entries,
 				     GFP_ATOMIC);
+	if (!adapter->mac_table)
+		return -ENOMEM;
 
 	/* Set MAC specific capability flags and exceptions */
 	switch (hw->mac.type) {
@@ -6616,10 +6845,8 @@ static void ixgbe_check_for_bad_vf(struc
 {
 	struct ixgbe_hw *hw = &adapter->hw;
 	struct pci_dev *pdev = adapter->pdev;
-	struct pci_dev *vfdev;
+	unsigned int vf;
 	u32 gpc;
-	int pos;
-	unsigned short vf_id;
 
 	if (!(netif_carrier_ok(adapter->netdev)))
 		return;
@@ -6636,26 +6863,17 @@ static void ixgbe_check_for_bad_vf(struc
 	if (!pdev)
 		return;
 
-	pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_SRIOV);
-	if (!pos)
-		return;
-
-	/* get the device ID for the VF */
-	pci_read_config_word(pdev, pos + PCI_SRIOV_VF_DID, &vf_id);
-
 	/* check status reg for all VFs owned by this PF */
-	vfdev = pci_get_device(pdev->vendor, vf_id, NULL);
-	while (vfdev) {
-		if (vfdev->is_virtfn && (vfdev->physfn == pdev)) {
-			u16 status_reg;
-
-			pci_read_config_word(vfdev, PCI_STATUS, &status_reg);
-			if (status_reg & PCI_STATUS_REC_MASTER_ABORT)
-				/* issue VFLR */
-				ixgbe_issue_vf_flr(adapter, vfdev);
-		}
+	for (vf = 0; vf < adapter->num_vfs; ++vf) {
+		struct pci_dev *vfdev = adapter->vfinfo[vf].vfdev;
+		u16 status_reg;
 
-		vfdev = pci_get_device(pdev->vendor, vf_id, vfdev);
+		if (!vfdev)
+			continue;
+		pci_read_config_word(vfdev, PCI_STATUS, &status_reg);
+		if (status_reg != IXGBE_FAILED_READ_CFG_WORD &&
+		    status_reg & PCI_STATUS_REC_MASTER_ABORT)
+			ixgbe_issue_vf_flr(adapter, vfdev);
 	}
 }
 
@@ -7024,6 +7242,7 @@ static void ixgbe_tx_csum(struct ixgbe_r
 			struct tcphdr *tcphdr;
 			u8 *raw;
 		} transport_hdr;
+		__be16 frag_off;
 
 		if (skb->encapsulation) {
 			network_hdr.raw = skb_inner_network_header(skb);
@@ -7047,13 +7266,17 @@ static void ixgbe_tx_csum(struct ixgbe_r
 		case 6:
 			vlan_macip_lens |= transport_hdr.raw - network_hdr.raw;
 			l4_hdr = network_hdr.ipv6->nexthdr;
+			if (likely((transport_hdr.raw - network_hdr.raw) ==
+				   sizeof(struct ipv6hdr)))
+				break;
+			ipv6_skip_exthdr(skb, network_hdr.raw - skb->data +
+					      sizeof(struct ipv6hdr),
+					 &l4_hdr, &frag_off);
+			if (unlikely(frag_off))
+				l4_hdr = NEXTHDR_FRAGMENT;
 			break;
 		default:
-			if (unlikely(net_ratelimit())) {
-				dev_warn(tx_ring->dev,
-					 "partial checksum but version=%d\n",
-					 network_hdr.ipv4->version);
-			}
+			break;
 		}
 
 		switch (l4_hdr) {
@@ -7074,16 +7297,18 @@ static void ixgbe_tx_csum(struct ixgbe_r
 		default:
 			if (unlikely(net_ratelimit())) {
 				dev_warn(tx_ring->dev,
-				 "partial checksum but l4 proto=%x!\n",
-				 l4_hdr);
+					 "partial checksum, version=%d, l4 proto=%x\n",
+					 network_hdr.ipv4->version, l4_hdr);
 			}
-			break;
+			skb_checksum_help(skb);
+			goto no_csum;
 		}
 
 		/* update TX checksum flag */
 		first->tx_flags |= IXGBE_TX_FLAGS_CSUM;
 	}
 
+no_csum:
 	/* vlan_macip_lens: MACLEN, VLAN tag */
 	vlan_macip_lens |= first->tx_flags & IXGBE_TX_FLAGS_VLAN_MASK;
 
@@ -7358,7 +7583,9 @@ static void ixgbe_atr(struct ixgbe_ring
 	/* snag network header to get L4 type and address */
 	skb = first->skb;
 	hdr.network = skb_network_header(skb);
-	if (skb->encapsulation) {
+	if (!skb->encapsulation) {
+		th = tcp_hdr(skb);
+	} else {
 #ifdef CONFIG_IXGBE_VXLAN
 		struct ixgbe_adapter *adapter = q_vector->adapter;
 
@@ -7377,14 +7604,34 @@ static void ixgbe_atr(struct ixgbe_ring
 #else
 		return;
 #endif /* CONFIG_IXGBE_VXLAN */
-	} else {
-		/* Currently only IPv4/IPv6 with TCP is supported */
-		if ((first->protocol != htons(ETH_P_IPV6) ||
-		     hdr.ipv6->nexthdr != IPPROTO_TCP) &&
-		    (first->protocol != htons(ETH_P_IP) ||
-		     hdr.ipv4->protocol != IPPROTO_TCP))
+	}
+
+	/* Currently only IPv4/IPv6 with TCP is supported */
+	switch (hdr.ipv4->version) {
+	case IPVERSION:
+		if (hdr.ipv4->protocol != IPPROTO_TCP)
 			return;
-		th = tcp_hdr(skb);
+		break;
+	case 6:
+		if (likely((unsigned char *)th - hdr.network ==
+			   sizeof(struct ipv6hdr))) {
+			if (hdr.ipv6->nexthdr != IPPROTO_TCP)
+				return;
+		} else {
+			__be16 frag_off;
+			u8 l4_hdr;
+
+			ipv6_skip_exthdr(skb, hdr.network - skb->data +
+					      sizeof(struct ipv6hdr),
+					 &l4_hdr, &frag_off);
+			if (unlikely(frag_off))
+				return;
+			if (l4_hdr != IPPROTO_TCP)
+				return;
+		}
+		break;
+	default:
+		return;
 	}
 
 	/* skip this packet since it is invalid or the socket is closing */
@@ -7419,10 +7666,12 @@ static void ixgbe_atr(struct ixgbe_ring
 		common.port.src ^= th->dest ^ first->protocol;
 	common.port.dst ^= th->source;
 
-	if (first->protocol == htons(ETH_P_IP)) {
+	switch (hdr.ipv4->version) {
+	case IPVERSION:
 		input.formatted.flow_type = IXGBE_ATR_FLOW_TYPE_TCPV4;
 		common.ip ^= hdr.ipv4->saddr ^ hdr.ipv4->daddr;
-	} else {
+		break;
+	case 6:
 		input.formatted.flow_type = IXGBE_ATR_FLOW_TYPE_TCPV6;
 		common.ip ^= hdr.ipv6->saddr.s6_addr32[0] ^
 			     hdr.ipv6->saddr.s6_addr32[1] ^
@@ -7432,6 +7681,9 @@ static void ixgbe_atr(struct ixgbe_ring
 			     hdr.ipv6->daddr.s6_addr32[1] ^
 			     hdr.ipv6->daddr.s6_addr32[2] ^
 			     hdr.ipv6->daddr.s6_addr32[3];
+		break;
+	default:
+		break;
 	}
 
 #ifdef CONFIG_IXGBE_VXLAN
@@ -7659,17 +7911,16 @@ static int ixgbe_set_mac(struct net_devi
 	struct ixgbe_adapter *adapter = netdev_priv(netdev);
 	struct ixgbe_hw *hw = &adapter->hw;
 	struct sockaddr *addr = p;
-	int ret;
 
 	if (!is_valid_ether_addr(addr->sa_data))
 		return -EADDRNOTAVAIL;
 
-	ixgbe_del_mac_filter(adapter, hw->mac.addr, VMDQ_P(0));
 	memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
 	memcpy(hw->mac.addr, addr->sa_data, netdev->addr_len);
 
-	ret = ixgbe_add_mac_filter(adapter, hw->mac.addr, VMDQ_P(0));
-	return ret > 0 ? 0 : ret;
+	ixgbe_mac_set_default_filter(adapter);
+
+	return 0;
 }
 
 static int
@@ -7959,6 +8210,228 @@ int ixgbe_setup_tc(struct net_device *de
 	return 0;
 }
 
+static int ixgbe_delete_clsu32(struct ixgbe_adapter *adapter,
+			       struct tc_cls_u32_offload *cls)
+{
+	int err;
+
+	spin_lock(&adapter->fdir_perfect_lock);
+	err = ixgbe_update_ethtool_fdir_entry(adapter, NULL, cls->knode.handle);
+	spin_unlock(&adapter->fdir_perfect_lock);
+	return err;
+}
+
+static int ixgbe_configure_clsu32_add_hnode(struct ixgbe_adapter *adapter,
+					    __be16 protocol,
+					    struct tc_cls_u32_offload *cls)
+{
+	/* This ixgbe devices do not support hash tables at the moment
+	 * so abort when given hash tables.
+	 */
+	if (cls->hnode.divisor > 0)
+		return -EINVAL;
+
+	set_bit(TC_U32_USERHTID(cls->hnode.handle), &adapter->tables);
+	return 0;
+}
+
+static int ixgbe_configure_clsu32_del_hnode(struct ixgbe_adapter *adapter,
+					    struct tc_cls_u32_offload *cls)
+{
+	clear_bit(TC_U32_USERHTID(cls->hnode.handle), &adapter->tables);
+	return 0;
+}
+
+static int ixgbe_configure_clsu32(struct ixgbe_adapter *adapter,
+				  __be16 protocol,
+				  struct tc_cls_u32_offload *cls)
+{
+	u32 loc = cls->knode.handle & 0xfffff;
+	struct ixgbe_hw *hw = &adapter->hw;
+	struct ixgbe_mat_field *field_ptr;
+	struct ixgbe_fdir_filter *input;
+	union ixgbe_atr_input mask;
+#ifdef CONFIG_NET_CLS_ACT
+	const struct tc_action *a;
+#endif
+	int i, err = 0;
+	u8 queue;
+	u32 handle;
+
+	memset(&mask, 0, sizeof(union ixgbe_atr_input));
+	handle = cls->knode.handle;
+
+	/* At the moment cls_u32 jumps to transport layer and skips past
+	 * L2 headers. The canonical method to match L2 frames is to use
+	 * negative values. However this is error prone at best but really
+	 * just broken because there is no way to "know" what sort of hdr
+	 * is in front of the transport layer. Fix cls_u32 to support L2
+	 * headers when needed.
+	 */
+	if (protocol != htons(ETH_P_IP))
+		return -EINVAL;
+
+	if (cls->knode.link_handle ||
+	    cls->knode.link_handle >= IXGBE_MAX_LINK_HANDLE) {
+		struct ixgbe_nexthdr *nexthdr = ixgbe_ipv4_jumps;
+		u32 uhtid = TC_U32_USERHTID(cls->knode.link_handle);
+
+		if (!test_bit(uhtid, &adapter->tables))
+			return -EINVAL;
+
+		for (i = 0; nexthdr[i].jump; i++) {
+			if (nexthdr->o != cls->knode.sel->offoff ||
+			    nexthdr->s != cls->knode.sel->offshift ||
+			    nexthdr->m != cls->knode.sel->offmask ||
+			    /* do not support multiple key jumps its just mad */
+			    cls->knode.sel->nkeys > 1)
+				return -EINVAL;
+
+			if (nexthdr->off != cls->knode.sel->keys[0].off ||
+			    nexthdr->val != cls->knode.sel->keys[0].val ||
+			    nexthdr->mask != cls->knode.sel->keys[0].mask)
+				return -EINVAL;
+
+			if (uhtid >= IXGBE_MAX_LINK_HANDLE)
+				return -EINVAL;
+
+			adapter->jump_tables[uhtid] = nexthdr->jump;
+		}
+		return 0;
+	}
+
+	if (loc >= ((1024 << adapter->fdir_pballoc) - 2)) {
+		e_err(drv, "Location out of range\n");
+		return -EINVAL;
+	}
+
+	/* cls u32 is a graph starting at root node 0x800. The driver tracks
+	 * links and also the fields used to advance the parser across each
+	 * link (e.g. nexthdr/eat parameters from 'tc'). This way we can map
+	 * the u32 graph onto the hardware parse graph denoted in ixgbe_model.h
+	 * To add support for new nodes update ixgbe_model.h parse structures
+	 * this function _should_ be generic try not to hardcode values here.
+	 */
+	if (TC_U32_USERHTID(handle) == 0x800) {
+		field_ptr = adapter->jump_tables[0];
+	} else {
+		if (TC_U32_USERHTID(handle) >= ARRAY_SIZE(adapter->jump_tables))
+			return -EINVAL;
+
+		field_ptr = adapter->jump_tables[TC_U32_USERHTID(handle)];
+	}
+
+	if (!field_ptr)
+		return -EINVAL;
+
+	input = kzalloc(sizeof(*input), GFP_KERNEL);
+	if (!input)
+		return -ENOMEM;
+
+	for (i = 0; i < cls->knode.sel->nkeys; i++) {
+		int off = cls->knode.sel->keys[i].off;
+		__be32 val = cls->knode.sel->keys[i].val;
+		__be32 m = cls->knode.sel->keys[i].mask;
+		bool found_entry = false;
+		int j;
+
+		for (j = 0; field_ptr[j].val; j++) {
+			if (field_ptr[j].off == off &&
+			    field_ptr[j].mask == m) {
+				field_ptr[j].val(input, &mask, val, m);
+				input->filter.formatted.flow_type |=
+					field_ptr[j].type;
+				found_entry = true;
+				break;
+			}
+		}
+
+		if (!found_entry)
+			goto err_out;
+	}
+
+	mask.formatted.flow_type = IXGBE_ATR_L4TYPE_IPV6_MASK |
+				   IXGBE_ATR_L4TYPE_MASK;
+
+	if (input->filter.formatted.flow_type == IXGBE_ATR_FLOW_TYPE_IPV4)
+		mask.formatted.flow_type &= IXGBE_ATR_L4TYPE_IPV6_MASK;
+
+#ifdef CONFIG_NET_CLS_ACT
+	if (list_empty(&cls->knode.exts->actions))
+		goto err_out;
+
+	list_for_each_entry(a, &cls->knode.exts->actions, list) {
+		if (!is_tcf_gact_shot(a))
+			goto err_out;
+	}
+#endif
+
+	input->action = IXGBE_FDIR_DROP_QUEUE;
+	queue = IXGBE_FDIR_DROP_QUEUE;
+	input->sw_idx = loc;
+
+	spin_lock(&adapter->fdir_perfect_lock);
+
+	if (hlist_empty(&adapter->fdir_filter_list)) {
+		memcpy(&adapter->fdir_mask, &mask, sizeof(mask));
+		err = ixgbe_fdir_set_input_mask_82599(hw, &mask);
+		if (err)
+			goto err_out_w_lock;
+	} else if (memcmp(&adapter->fdir_mask, &mask, sizeof(mask))) {
+		err = -EINVAL;
+		goto err_out_w_lock;
+	}
+
+	ixgbe_atr_compute_perfect_hash_82599(&input->filter, &mask);
+	err = ixgbe_fdir_write_perfect_filter_82599(hw, &input->filter,
+						    input->sw_idx, queue);
+	if (!err)
+		ixgbe_update_ethtool_fdir_entry(adapter, input, input->sw_idx);
+	spin_unlock(&adapter->fdir_perfect_lock);
+
+	return err;
+err_out_w_lock:
+	spin_unlock(&adapter->fdir_perfect_lock);
+err_out:
+	kfree(input);
+	return -EINVAL;
+}
+
+int __ixgbe_setup_tc(struct net_device *dev, u32 handle, __be16 proto,
+		     struct tc_to_netdev *tc)
+{
+	struct ixgbe_adapter *adapter = netdev_priv(dev);
+
+	if (TC_H_MAJ(handle) == TC_H_MAJ(TC_H_INGRESS) &&
+	    tc->type == TC_SETUP_CLSU32) {
+		if (!(dev->features & NETIF_F_HW_TC))
+			return -EINVAL;
+
+		switch (tc->cls_u32->command) {
+		case TC_CLSU32_NEW_KNODE:
+		case TC_CLSU32_REPLACE_KNODE:
+			return ixgbe_configure_clsu32(adapter,
+						      proto, tc->cls_u32);
+		case TC_CLSU32_DELETE_KNODE:
+			return ixgbe_delete_clsu32(adapter, tc->cls_u32);
+		case TC_CLSU32_NEW_HNODE:
+		case TC_CLSU32_REPLACE_HNODE:
+			return ixgbe_configure_clsu32_add_hnode(adapter, proto,
+								tc->cls_u32);
+		case TC_CLSU32_DELETE_HNODE:
+			return ixgbe_configure_clsu32_del_hnode(adapter,
+								tc->cls_u32);
+		default:
+			return -EINVAL;
+		}
+	}
+
+	if (handle != TC_H_ROOT || tc->type != TC_SETUP_MQPRIO)
+		return -EINVAL;
+
+	return ixgbe_setup_tc(dev, tc->tc);
+}
+
 #ifdef CONFIG_PCI_IOV
 void ixgbe_sriov_reinit(struct ixgbe_adapter *adapter)
 {
@@ -8021,19 +8494,17 @@ static int ixgbe_set_features(struct net
 	}
 
 	/*
-	 * Check if Flow Director n-tuple support was enabled or disabled.  If
-	 * the state changed, we need to reset.
+	 * Check if Flow Director n-tuple support or hw_tc support was
+	 * enabled or disabled.  If the state changed, we need to reset.
 	 */
-	switch (features & NETIF_F_NTUPLE) {
-	case NETIF_F_NTUPLE:
+	if ((features & NETIF_F_NTUPLE) || (features & NETIF_F_HW_TC)) {
 		/* turn off ATR, enable perfect filters and reset */
 		if (!(adapter->flags & IXGBE_FLAG_FDIR_PERFECT_CAPABLE))
 			need_reset = true;
 
 		adapter->flags &= ~IXGBE_FLAG_FDIR_HASH_CAPABLE;
 		adapter->flags |= IXGBE_FLAG_FDIR_PERFECT_CAPABLE;
-		break;
-	default:
+	} else {
 		/* turn off perfect filters, enable ATR and reset */
 		if (adapter->flags & IXGBE_FLAG_FDIR_PERFECT_CAPABLE)
 			need_reset = true;
@@ -8041,23 +8512,16 @@ static int ixgbe_set_features(struct net
 		adapter->flags &= ~IXGBE_FLAG_FDIR_PERFECT_CAPABLE;
 
 		/* We cannot enable ATR if SR-IOV is enabled */
-		if (adapter->flags & IXGBE_FLAG_SRIOV_ENABLED)
-			break;
-
-		/* We cannot enable ATR if we have 2 or more traffic classes */
-		if (netdev_get_num_tc(netdev) > 1)
-			break;
-
-		/* We cannot enable ATR if RSS is disabled */
-		if (adapter->ring_feature[RING_F_RSS].limit <= 1)
-			break;
-
-		/* A sample rate of 0 indicates ATR disabled */
-		if (!adapter->atr_sample_rate)
-			break;
-
-		adapter->flags |= IXGBE_FLAG_FDIR_HASH_CAPABLE;
-		break;
+		if (adapter->flags & IXGBE_FLAG_SRIOV_ENABLED ||
+		    /* We cannot enable ATR if we have 2 or more tcs */
+		    (netdev_get_num_tc(netdev) > 1) ||
+		    /* We cannot enable ATR if RSS is disabled */
+		    (adapter->ring_feature[RING_F_RSS].limit <= 1) ||
+		    /* A sample rate of 0 indicates ATR disabled */
+		    (!adapter->atr_sample_rate))
+			; /* do nothing not supported */
+		else /* otherwise supported and set the flag */
+			adapter->flags |= IXGBE_FLAG_FDIR_HASH_CAPABLE;
 	}
 
 	if (features & NETIF_F_HW_VLAN_CTAG_RX)
@@ -8155,7 +8619,10 @@ static int ixgbe_ndo_fdb_add(struct ndms
 {
 	/* guarantee we can provide a unique filter for the unicast address */
 	if (is_unicast_ether_addr(addr) || is_link_local_ether_addr(addr)) {
-		if (IXGBE_MAX_PF_MACVLANS <= netdev_uc_count(dev))
+		struct ixgbe_adapter *adapter = netdev_priv(dev);
+		u16 pool = VMDQ_P(0);
+
+		if (netdev_uc_count(dev) >= ixgbe_available_rars(adapter, pool))
 			return -ENOMEM;
 	}
 
@@ -8413,9 +8880,7 @@ static const struct net_device_ops ixgbe
 	.ndo_set_vf_trust	= ixgbe_ndo_set_vf_trust,
 	.ndo_get_vf_config	= ixgbe_ndo_get_vf_config,
 	.ndo_get_stats64	= ixgbe_get_stats64,
-#ifdef CONFIG_IXGBE_DCB
-	.ndo_setup_tc		= ixgbe_setup_tc,
-#endif
+	.ndo_setup_tc		= __ixgbe_setup_tc,
 #ifdef CONFIG_NET_POLL_CONTROLLER
 	.ndo_poll_controller	= ixgbe_netpoll,
 #endif
@@ -8784,9 +9249,10 @@ skip_sriov:
 	case ixgbe_mac_X540:
 	case ixgbe_mac_X550:
 	case ixgbe_mac_X550EM_x:
-		netdev->features |= NETIF_F_SCTP_CSUM;
-		netdev->hw_features |= NETIF_F_SCTP_CSUM |
-				       NETIF_F_NTUPLE;
+		netdev->features |= NETIF_F_SCTP_CRC;
+		netdev->hw_features |= NETIF_F_SCTP_CRC |
+				       NETIF_F_NTUPLE |
+				       NETIF_F_HW_TC;
 		break;
 	default:
 		break;
@@ -8801,8 +9267,7 @@ skip_sriov:
 	netdev->vlan_features |= NETIF_F_IPV6_CSUM;
 	netdev->vlan_features |= NETIF_F_SG;
 
-	netdev->hw_enc_features |= NETIF_F_SG | NETIF_F_IP_CSUM |
-				   NETIF_F_IPV6_CSUM;
+	netdev->hw_enc_features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
 
 	netdev->priv_flags |= IFF_UNICAST_FLT;
 	netdev->priv_flags |= IFF_SUPP_NOFCS;
@@ -8811,9 +9276,7 @@ skip_sriov:
 	switch (adapter->hw.mac.type) {
 	case ixgbe_mac_X550:
 	case ixgbe_mac_X550EM_x:
-		netdev->hw_enc_features |= NETIF_F_RXCSUM |
-					   NETIF_F_IP_CSUM |
-					   NETIF_F_IPV6_CSUM;
+		netdev->hw_enc_features |= NETIF_F_RXCSUM;
 		break;
 	default:
 		break;
@@ -8873,7 +9336,7 @@ skip_sriov:
 		goto err_sw_init;
 	}
 
-	ixgbe_mac_set_default_filter(adapter, hw->mac.perm_addr);
+	ixgbe_mac_set_default_filter(adapter);
 
 	setup_timer(&adapter->service_timer, &ixgbe_service_timer,
 		    (unsigned long) adapter);
@@ -9328,6 +9791,12 @@ static int __init ixgbe_init_module(void
 	pr_info("%s - version %s\n", ixgbe_driver_string, ixgbe_driver_version);
 	pr_info("%s\n", ixgbe_copyright);
 
+	ixgbe_wq = create_singlethread_workqueue(ixgbe_driver_name);
+	if (!ixgbe_wq) {
+		pr_err("%s: Failed to create workqueue\n", ixgbe_driver_name);
+		return -ENOMEM;
+	}
+
 	ixgbe_dbg_init();
 
 	ret = pci_register_driver(&ixgbe_driver);
@@ -9359,6 +9828,10 @@ static void __exit ixgbe_exit_module(voi
 	pci_unregister_driver(&ixgbe_driver);
 
 	ixgbe_dbg_exit();
+	if (ixgbe_wq) {
+		destroy_workqueue(ixgbe_wq);
+		ixgbe_wq = NULL;
+	}
 }
 
 #ifdef CONFIG_IXGBE_DCA
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/intel/ixgbe/ixgbe_model.h
@@ -0,0 +1,112 @@
+/*******************************************************************************
+ *
+ * Intel 10 Gigabit PCI Express Linux drive
+ * Copyright(c) 2016 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
+ * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+ *
+ ******************************************************************************/
+
+#ifndef _IXGBE_MODEL_H_
+#define _IXGBE_MODEL_H_
+
+#include "ixgbe.h"
+#include "ixgbe_type.h"
+
+struct ixgbe_mat_field {
+	unsigned int off;
+	unsigned int mask;
+	int (*val)(struct ixgbe_fdir_filter *input,
+		   union ixgbe_atr_input *mask,
+		   u32 val, u32 m);
+	unsigned int type;
+};
+
+static inline int ixgbe_mat_prgm_sip(struct ixgbe_fdir_filter *input,
+				     union ixgbe_atr_input *mask,
+				     u32 val, u32 m)
+{
+	input->filter.formatted.src_ip[0] = val;
+	mask->formatted.src_ip[0] = m;
+	return 0;
+}
+
+static inline int ixgbe_mat_prgm_dip(struct ixgbe_fdir_filter *input,
+				     union ixgbe_atr_input *mask,
+				     u32 val, u32 m)
+{
+	input->filter.formatted.dst_ip[0] = val;
+	mask->formatted.dst_ip[0] = m;
+	return 0;
+}
+
+static struct ixgbe_mat_field ixgbe_ipv4_fields[] = {
+	{ .off = 12, .mask = -1, .val = ixgbe_mat_prgm_sip,
+	  .type = IXGBE_ATR_FLOW_TYPE_IPV4},
+	{ .off = 16, .mask = -1, .val = ixgbe_mat_prgm_dip,
+	  .type = IXGBE_ATR_FLOW_TYPE_IPV4},
+	{ .val = NULL } /* terminal node */
+};
+
+static inline int ixgbe_mat_prgm_sport(struct ixgbe_fdir_filter *input,
+				       union ixgbe_atr_input *mask,
+				       u32 val, u32 m)
+{
+	input->filter.formatted.src_port = val & 0xffff;
+	mask->formatted.src_port = m & 0xffff;
+	return 0;
+};
+
+static inline int ixgbe_mat_prgm_dport(struct ixgbe_fdir_filter *input,
+				       union ixgbe_atr_input *mask,
+				       u32 val, u32 m)
+{
+	input->filter.formatted.dst_port = val & 0xffff;
+	mask->formatted.dst_port = m & 0xffff;
+	return 0;
+};
+
+static struct ixgbe_mat_field ixgbe_tcp_fields[] = {
+	{.off = 0, .mask = 0xffff, .val = ixgbe_mat_prgm_sport,
+	 .type = IXGBE_ATR_FLOW_TYPE_TCPV4},
+	{.off = 2, .mask = 0xffff, .val = ixgbe_mat_prgm_dport,
+	 .type = IXGBE_ATR_FLOW_TYPE_TCPV4},
+	{ .val = NULL } /* terminal node */
+};
+
+struct ixgbe_nexthdr {
+	/* offset, shift, and mask of position to next header */
+	unsigned int o;
+	u32 s;
+	u32 m;
+	/* match criteria to make this jump*/
+	unsigned int off;
+	u32 val;
+	u32 mask;
+	/* location of jump to make */
+	struct ixgbe_mat_field *jump;
+};
+
+static struct ixgbe_nexthdr ixgbe_ipv4_jumps[] = {
+	{ .o = 0, .s = 6, .m = 0xf,
+	  .off = 8, .val = 0x600, .mask = 0xff00, .jump = ixgbe_tcp_fields},
+	{ .jump = NULL } /* terminal node */
+};
+#endif /* _IXGBE_MODEL_H_ */
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.c
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.c
@@ -2393,6 +2393,9 @@ s32 ixgbe_set_copper_phy_power(struct ix
 	if (hw->mac.ops.get_media_type(hw) != ixgbe_media_type_copper)
 		return 0;
 
+	if (!on && ixgbe_mng_present(hw))
+		return 0;
+
 	status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_VENDOR_SPECIFIC_1_CONTROL,
 				      IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
 				      &reg);
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel 10 Gigabit PCI Express Linux driver
-  Copyright(c) 1999 - 2013 Intel Corporation.
+  Copyright(c) 1999 - 2015 Intel Corporation.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms and conditions of the GNU General Public License,
@@ -27,6 +27,7 @@
 *******************************************************************************/
 #include "ixgbe.h"
 #include <linux/ptp_classify.h>
+#include <linux/clocksource.h>
 
 /*
  * The 82599 and the X540 do not have true 64bit nanosecond scale
@@ -93,7 +94,6 @@
 
 #define IXGBE_INCVAL_SHIFT_82599 7
 #define IXGBE_INCPER_SHIFT_82599 24
-#define IXGBE_MAX_TIMEADJ_VALUE  0x7FFFFFFFFFFFFFFFULL
 
 #define IXGBE_OVERFLOW_PERIOD    (HZ * 30)
 #define IXGBE_PTP_TX_TIMEOUT     (HZ * 15)
@@ -104,8 +104,68 @@
  */
 #define IXGBE_PTP_PPS_HALF_SECOND 500000000ULL
 
+/* In contrast, the X550 controller has two registers, SYSTIMEH and SYSTIMEL
+ * which contain measurements of seconds and nanoseconds respectively. This
+ * matches the standard linux representation of time in the kernel. In addition,
+ * the X550 also has a SYSTIMER register which represents residue, or
+ * subnanosecond overflow adjustments. To control clock adjustment, the TIMINCA
+ * register is used, but it is unlike the X540 and 82599 devices. TIMINCA
+ * represents units of 2^-32 nanoseconds, and uses 31 bits for this, with the
+ * high bit representing whether the adjustent is positive or negative. Every
+ * clock cycle, the X550 will add 12.5 ns + TIMINCA which can result in a range
+ * of 12 to 13 nanoseconds adjustment. Unlike the 82599 and X540 devices, the
+ * X550's clock for purposes of SYSTIME generation is constant and not dependent
+ * on the link speed.
+ *
+ *           SYSTIMEH           SYSTIMEL        SYSTIMER
+ *       +--------------+  +--------------+  +-------------+
+ * X550  |      32      |  |      32      |  |     32      |
+ *       *--------------+  +--------------+  +-------------+
+ *       \____seconds___/   \_nanoseconds_/  \__2^-32 ns__/
+ *
+ * This results in a full 96 bits to represent the clock, with 32 bits for
+ * seconds, 32 bits for nanoseconds (largest value is 0d999999999 or just under
+ * 1 second) and an additional 32 bits to measure sub nanosecond adjustments for
+ * underflow of adjustments.
+ *
+ * The 32 bits of seconds for the X550 overflows every
+ *   2^32 / ( 365.25 * 24 * 60 * 60 ) = ~136 years.
+ *
+ * In order to adjust the clock frequency for the X550, the TIMINCA register is
+ * provided. This register represents a + or minus nearly 0.5 ns adjustment to
+ * the base frequency. It is measured in 2^-32 ns units, with the high bit being
+ * the sign bit. This register enables software to calculate frequency
+ * adjustments and apply them directly to the clock rate.
+ *
+ * The math for converting ppb into TIMINCA values is fairly straightforward.
+ *   TIMINCA value = ( Base_Frequency * ppb ) / 1000000000ULL
+ *
+ * This assumes that ppb is never high enough to create a value bigger than
+ * TIMINCA's 31 bits can store. This is ensured by the stack. Calculating this
+ * value is also simple.
+ *   Max ppb = ( Max Adjustment / Base Frequency ) / 1000000000ULL
+ *
+ * For the X550, the Max adjustment is +/- 0.5 ns, and the base frequency is
+ * 12.5 nanoseconds. This means that the Max ppb is 39999999
+ *   Note: We subtract one in order to ensure no overflow, because the TIMINCA
+ *         register can only hold slightly under 0.5 nanoseconds.
+ *
+ * Because TIMINCA is measured in 2^-32 ns units, we have to convert 12.5 ns
+ * into 2^-32 units, which is
+ *
+ *  12.5 * 2^32 = C80000000
+ *
+ * Some revisions of hardware have a faster base frequency than the registers
+ * were defined for. To fix this, we use a timecounter structure with the
+ * proper mult and shift to convert the cycles into nanoseconds of time.
+ */
+#define IXGBE_X550_BASE_PERIOD 0xC80000000ULL
+#define INCVALUE_MASK	0x7FFFFFFF
+#define ISGN		0x80000000
+#define MAX_TIMADJ	0x7FFFFFFF
+
 /**
- * ixgbe_ptp_setup_sdp
+ * ixgbe_ptp_setup_sdp_x540
  * @hw: the hardware private structure
  *
  * this function enables or disables the clock out feature on SDP0 for
@@ -116,83 +176,116 @@
  * aligns the start of the PPS signal to that value. The shift is
  * necessary because it can change based on the link speed.
  */
-static void ixgbe_ptp_setup_sdp(struct ixgbe_adapter *adapter)
+static void ixgbe_ptp_setup_sdp_x540(struct ixgbe_adapter *adapter)
 {
 	struct ixgbe_hw *hw = &adapter->hw;
-	int shift = adapter->cc.shift;
+	int shift = adapter->hw_cc.shift;
 	u32 esdp, tsauxc, clktiml, clktimh, trgttiml, trgttimh, rem;
 	u64 ns = 0, clock_edge = 0;
 
-	if ((adapter->flags2 & IXGBE_FLAG2_PTP_PPS_ENABLED) &&
-	    (hw->mac.type == ixgbe_mac_X540)) {
+	/* disable the pin first */
+	IXGBE_WRITE_REG(hw, IXGBE_TSAUXC, 0x0);
+	IXGBE_WRITE_FLUSH(hw);
 
-		/* disable the pin first */
-		IXGBE_WRITE_REG(hw, IXGBE_TSAUXC, 0x0);
-		IXGBE_WRITE_FLUSH(hw);
+	if (!(adapter->flags2 & IXGBE_FLAG2_PTP_PPS_ENABLED))
+		return;
 
-		esdp = IXGBE_READ_REG(hw, IXGBE_ESDP);
+	esdp = IXGBE_READ_REG(hw, IXGBE_ESDP);
 
-		/*
-		 * enable the SDP0 pin as output, and connected to the
-		 * native function for Timesync (ClockOut)
-		 */
-		esdp |= (IXGBE_ESDP_SDP0_DIR |
-			 IXGBE_ESDP_SDP0_NATIVE);
+	/* enable the SDP0 pin as output, and connected to the
+	 * native function for Timesync (ClockOut)
+	 */
+	esdp |= IXGBE_ESDP_SDP0_DIR |
+		IXGBE_ESDP_SDP0_NATIVE;
 
-		/*
-		 * enable the Clock Out feature on SDP0, and allow
-		 * interrupts to occur when the pin changes
-		 */
-		tsauxc = (IXGBE_TSAUXC_EN_CLK |
-			  IXGBE_TSAUXC_SYNCLK |
-			  IXGBE_TSAUXC_SDP0_INT);
-
-		/* clock period (or pulse length) */
-		clktiml = (u32)(IXGBE_PTP_PPS_HALF_SECOND << shift);
-		clktimh = (u32)((IXGBE_PTP_PPS_HALF_SECOND << shift) >> 32);
+	/* enable the Clock Out feature on SDP0, and allow
+	 * interrupts to occur when the pin changes
+	 */
+	tsauxc = IXGBE_TSAUXC_EN_CLK |
+		 IXGBE_TSAUXC_SYNCLK |
+		 IXGBE_TSAUXC_SDP0_INT;
+
+	/* clock period (or pulse length) */
+	clktiml = (u32)(IXGBE_PTP_PPS_HALF_SECOND << shift);
+	clktimh = (u32)((IXGBE_PTP_PPS_HALF_SECOND << shift) >> 32);
+
+	/* Account for the cyclecounter wrap-around value by
+	 * using the converted ns value of the current time to
+	 * check for when the next aligned second would occur.
+	 */
+	clock_edge |= (u64)IXGBE_READ_REG(hw, IXGBE_SYSTIML);
+	clock_edge |= (u64)IXGBE_READ_REG(hw, IXGBE_SYSTIMH) << 32;
+	ns = timecounter_cyc2time(&adapter->hw_tc, clock_edge);
+
+	div_u64_rem(ns, IXGBE_PTP_PPS_HALF_SECOND, &rem);
+	clock_edge += ((IXGBE_PTP_PPS_HALF_SECOND - (u64)rem) << shift);
+
+	/* specify the initial clock start time */
+	trgttiml = (u32)clock_edge;
+	trgttimh = (u32)(clock_edge >> 32);
+
+	IXGBE_WRITE_REG(hw, IXGBE_CLKTIML, clktiml);
+	IXGBE_WRITE_REG(hw, IXGBE_CLKTIMH, clktimh);
+	IXGBE_WRITE_REG(hw, IXGBE_TRGTTIML0, trgttiml);
+	IXGBE_WRITE_REG(hw, IXGBE_TRGTTIMH0, trgttimh);
 
-		/*
-		 * Account for the cyclecounter wrap-around value by
-		 * using the converted ns value of the current time to
-		 * check for when the next aligned second would occur.
-		 */
-		clock_edge |= (u64)IXGBE_READ_REG(hw, IXGBE_SYSTIML);
-		clock_edge |= (u64)IXGBE_READ_REG(hw, IXGBE_SYSTIMH) << 32;
-		ns = timecounter_cyc2time(&adapter->tc, clock_edge);
-
-		div_u64_rem(ns, IXGBE_PTP_PPS_HALF_SECOND, &rem);
-		clock_edge += ((IXGBE_PTP_PPS_HALF_SECOND - (u64)rem) << shift);
-
-		/* specify the initial clock start time */
-		trgttiml = (u32)clock_edge;
-		trgttimh = (u32)(clock_edge >> 32);
-
-		IXGBE_WRITE_REG(hw, IXGBE_CLKTIML, clktiml);
-		IXGBE_WRITE_REG(hw, IXGBE_CLKTIMH, clktimh);
-		IXGBE_WRITE_REG(hw, IXGBE_TRGTTIML0, trgttiml);
-		IXGBE_WRITE_REG(hw, IXGBE_TRGTTIMH0, trgttimh);
-
-		IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp);
-		IXGBE_WRITE_REG(hw, IXGBE_TSAUXC, tsauxc);
-	} else {
-		IXGBE_WRITE_REG(hw, IXGBE_TSAUXC, 0x0);
-	}
+	IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp);
+	IXGBE_WRITE_REG(hw, IXGBE_TSAUXC, tsauxc);
 
 	IXGBE_WRITE_FLUSH(hw);
 }
 
 /**
- * ixgbe_ptp_read - read raw cycle counter (to be used by time counter)
+ * ixgbe_ptp_read_X550 - read cycle counter value
+ * @hw_cc: cyclecounter structure
+ *
+ * This function reads SYSTIME registers. It is called by the cyclecounter
+ * structure to convert from internal representation into nanoseconds. We need
+ * this for X550 since some skews do not have expected clock frequency and
+ * result of SYSTIME is 32bits of "billions of cycles" and 32 bits of
+ * "cycles", rather than seconds and nanoseconds.
+ */
+static cycle_t ixgbe_ptp_read_X550(const struct cyclecounter *hw_cc)
+{
+	struct ixgbe_adapter *adapter =
+			container_of(hw_cc, struct ixgbe_adapter, hw_cc);
+	struct ixgbe_hw *hw = &adapter->hw;
+	struct timespec64 ts;
+
+	/* storage is 32 bits of 'billions of cycles' and 32 bits of 'cycles'.
+	 * Some revisions of hardware run at a higher frequency and so the
+	 * cycles are not guaranteed to be nanoseconds. The timespec64 created
+	 * here is used for its math/conversions but does not necessarily
+	 * represent nominal time.
+	 *
+	 * It should be noted that this cyclecounter will overflow at a
+	 * non-bitmask field since we have to convert our billions of cycles
+	 * into an actual cycles count. This results in some possible weird
+	 * situations at high cycle counter stamps. However given that 32 bits
+	 * of "seconds" is ~138 years this isn't a problem. Even at the
+	 * increased frequency of some revisions, this is still ~103 years.
+	 * Since the SYSTIME values start at 0 and we never write them, it is
+	 * highly unlikely for the cyclecounter to overflow in practice.
+	 */
+	IXGBE_READ_REG(hw, IXGBE_SYSTIMR);
+	ts.tv_nsec = IXGBE_READ_REG(hw, IXGBE_SYSTIML);
+	ts.tv_sec = IXGBE_READ_REG(hw, IXGBE_SYSTIMH);
+
+	return (u64)timespec64_to_ns(&ts);
+}
+
+/**
+ * ixgbe_ptp_read_82599 - read raw cycle counter (to be used by time counter)
  * @cc: the cyclecounter structure
  *
  * this function reads the cyclecounter registers and is called by the
  * cyclecounter structure used to construct a ns counter from the
  * arbitrary fixed point registers
  */
-static cycle_t ixgbe_ptp_read(const struct cyclecounter *cc)
+static cycle_t ixgbe_ptp_read_82599(const struct cyclecounter *cc)
 {
 	struct ixgbe_adapter *adapter =
-		container_of(cc, struct ixgbe_adapter, cc);
+		container_of(cc, struct ixgbe_adapter, hw_cc);
 	struct ixgbe_hw *hw = &adapter->hw;
 	u64 stamp = 0;
 
@@ -203,20 +296,79 @@ static cycle_t ixgbe_ptp_read(const stru
 }
 
 /**
- * ixgbe_ptp_adjfreq
+ * ixgbe_ptp_convert_to_hwtstamp - convert register value to hw timestamp
+ * @adapter: private adapter structure
+ * @hwtstamp: stack timestamp structure
+ * @systim: unsigned 64bit system time value
+ *
+ * We need to convert the adapter's RX/TXSTMP registers into a hwtstamp value
+ * which can be used by the stack's ptp functions.
+ *
+ * The lock is used to protect consistency of the cyclecounter and the SYSTIME
+ * registers. However, it does not need to protect against the Rx or Tx
+ * timestamp registers, as there can't be a new timestamp until the old one is
+ * unlatched by reading.
+ *
+ * In addition to the timestamp in hardware, some controllers need a software
+ * overflow cyclecounter, and this function takes this into account as well.
+ **/
+static void ixgbe_ptp_convert_to_hwtstamp(struct ixgbe_adapter *adapter,
+					  struct skb_shared_hwtstamps *hwtstamp,
+					  u64 timestamp)
+{
+	unsigned long flags;
+	struct timespec64 systime;
+	u64 ns;
+
+	memset(hwtstamp, 0, sizeof(*hwtstamp));
+
+	switch (adapter->hw.mac.type) {
+	/* X550 and later hardware supposedly represent time using a seconds
+	 * and nanoseconds counter, instead of raw 64bits nanoseconds. We need
+	 * to convert the timestamp into cycles before it can be fed to the
+	 * cyclecounter. We need an actual cyclecounter because some revisions
+	 * of hardware run at a higher frequency and thus the counter does
+	 * not represent seconds/nanoseconds. Instead it can be thought of as
+	 * cycles and billions of cycles.
+	 */
+	case ixgbe_mac_X550:
+	case ixgbe_mac_X550EM_x:
+		/* Upper 32 bits represent billions of cycles, lower 32 bits
+		 * represent cycles. However, we use timespec64_to_ns for the
+		 * correct math even though the units haven't been corrected
+		 * yet.
+		 */
+		systime.tv_sec = timestamp >> 32;
+		systime.tv_nsec = timestamp & 0xFFFFFFFF;
+
+		timestamp = timespec64_to_ns(&systime);
+		break;
+	default:
+		break;
+	}
+
+	spin_lock_irqsave(&adapter->tmreg_lock, flags);
+	ns = timecounter_cyc2time(&adapter->hw_tc, timestamp);
+	spin_unlock_irqrestore(&adapter->tmreg_lock, flags);
+
+	hwtstamp->hwtstamp = ns_to_ktime(ns);
+}
+
+/**
+ * ixgbe_ptp_adjfreq_82599
  * @ptp: the ptp clock structure
  * @ppb: parts per billion adjustment from base
  *
  * adjust the frequency of the ptp cycle counter by the
  * indicated ppb from the base frequency.
  */
-static int ixgbe_ptp_adjfreq(struct ptp_clock_info *ptp, s32 ppb)
+static int ixgbe_ptp_adjfreq_82599(struct ptp_clock_info *ptp, s32 ppb)
 {
 	struct ixgbe_adapter *adapter =
 		container_of(ptp, struct ixgbe_adapter, ptp_caps);
 	struct ixgbe_hw *hw = &adapter->hw;
-	u64 freq;
-	u32 diff, incval;
+	u64 freq, incval;
+	u32 diff;
 	int neg_adj = 0;
 
 	if (ppb < 0) {
@@ -235,12 +387,16 @@ static int ixgbe_ptp_adjfreq(struct ptp_
 
 	switch (hw->mac.type) {
 	case ixgbe_mac_X540:
-		IXGBE_WRITE_REG(hw, IXGBE_TIMINCA, incval);
+		if (incval > 0xFFFFFFFFULL)
+			e_dev_warn("PTP ppb adjusted SYSTIME rate overflowed!\n");
+		IXGBE_WRITE_REG(hw, IXGBE_TIMINCA, (u32)incval);
 		break;
 	case ixgbe_mac_82599EB:
+		if (incval > 0x00FFFFFFULL)
+			e_dev_warn("PTP ppb adjusted SYSTIME rate overflowed!\n");
 		IXGBE_WRITE_REG(hw, IXGBE_TIMINCA,
 				(1 << IXGBE_INCPER_SHIFT_82599) |
-				incval);
+				((u32)incval & 0x00FFFFFFUL));
 		break;
 	default:
 		break;
@@ -250,6 +406,43 @@ static int ixgbe_ptp_adjfreq(struct ptp_
 }
 
 /**
+ * ixgbe_ptp_adjfreq_X550
+ * @ptp: the ptp clock structure
+ * @ppb: parts per billion adjustment from base
+ *
+ * adjust the frequency of the SYSTIME registers by the indicated ppb from base
+ * frequency
+ */
+static int ixgbe_ptp_adjfreq_X550(struct ptp_clock_info *ptp, s32 ppb)
+{
+	struct ixgbe_adapter *adapter =
+			container_of(ptp, struct ixgbe_adapter, ptp_caps);
+	struct ixgbe_hw *hw = &adapter->hw;
+	int neg_adj = 0;
+	u64 rate = IXGBE_X550_BASE_PERIOD;
+	u32 inca;
+
+	if (ppb < 0) {
+		neg_adj = 1;
+		ppb = -ppb;
+	}
+	rate *= ppb;
+	rate = div_u64(rate, 1000000000ULL);
+
+	/* warn if rate is too large */
+	if (rate >= INCVALUE_MASK)
+		e_dev_warn("PTP ppb adjusted SYSTIME rate overflowed!\n");
+
+	inca = rate & INCVALUE_MASK;
+	if (neg_adj)
+		inca |= ISGN;
+
+	IXGBE_WRITE_REG(hw, IXGBE_TIMINCA, inca);
+
+	return 0;
+}
+
+/**
  * ixgbe_ptp_adjtime
  * @ptp: the ptp clock structure
  * @delta: offset to adjust the cycle counter by
@@ -263,10 +456,11 @@ static int ixgbe_ptp_adjtime(struct ptp_
 	unsigned long flags;
 
 	spin_lock_irqsave(&adapter->tmreg_lock, flags);
-	timecounter_adjtime(&adapter->tc, delta);
+	timecounter_adjtime(&adapter->hw_tc, delta);
 	spin_unlock_irqrestore(&adapter->tmreg_lock, flags);
 
-	ixgbe_ptp_setup_sdp(adapter);
+	if (adapter->ptp_setup_sdp)
+		adapter->ptp_setup_sdp(adapter);
 
 	return 0;
 }
@@ -283,11 +477,11 @@ static int ixgbe_ptp_gettime(struct ptp_
 {
 	struct ixgbe_adapter *adapter =
 		container_of(ptp, struct ixgbe_adapter, ptp_caps);
-	u64 ns;
 	unsigned long flags;
+	u64 ns;
 
 	spin_lock_irqsave(&adapter->tmreg_lock, flags);
-	ns = timecounter_read(&adapter->tc);
+	ns = timecounter_read(&adapter->hw_tc);
 	spin_unlock_irqrestore(&adapter->tmreg_lock, flags);
 
 	*ts = ns_to_timespec64(ns);
@@ -308,17 +502,16 @@ static int ixgbe_ptp_settime(struct ptp_
 {
 	struct ixgbe_adapter *adapter =
 		container_of(ptp, struct ixgbe_adapter, ptp_caps);
-	u64 ns;
 	unsigned long flags;
-
-	ns = timespec64_to_ns(ts);
+	u64 ns = timespec64_to_ns(ts);
 
 	/* reset the timecounter */
 	spin_lock_irqsave(&adapter->tmreg_lock, flags);
-	timecounter_init(&adapter->tc, &adapter->cc, ns);
+	timecounter_init(&adapter->hw_tc, &adapter->hw_cc, ns);
 	spin_unlock_irqrestore(&adapter->tmreg_lock, flags);
 
-	ixgbe_ptp_setup_sdp(adapter);
+	if (adapter->ptp_setup_sdp)
+		adapter->ptp_setup_sdp(adapter);
 	return 0;
 }
 
@@ -343,33 +536,26 @@ static int ixgbe_ptp_feature_enable(stru
 	 * event when the clock SDP triggers. Clear mask when PPS is
 	 * disabled
 	 */
-	if (rq->type == PTP_CLK_REQ_PPS) {
-		switch (adapter->hw.mac.type) {
-		case ixgbe_mac_X540:
-			if (on)
-				adapter->flags2 |= IXGBE_FLAG2_PTP_PPS_ENABLED;
-			else
-				adapter->flags2 &= ~IXGBE_FLAG2_PTP_PPS_ENABLED;
-
-			ixgbe_ptp_setup_sdp(adapter);
-			return 0;
-		default:
-			break;
-		}
-	}
+	if (rq->type != PTP_CLK_REQ_PPS || !adapter->ptp_setup_sdp)
+		return -ENOTSUPP;
 
-	return -ENOTSUPP;
+	if (on)
+		adapter->flags2 |= IXGBE_FLAG2_PTP_PPS_ENABLED;
+	else
+		adapter->flags2 &= ~IXGBE_FLAG2_PTP_PPS_ENABLED;
+
+	adapter->ptp_setup_sdp(adapter);
+	return 0;
 }
 
 /**
  * ixgbe_ptp_check_pps_event
  * @adapter: the private adapter structure
- * @eicr: the interrupt cause register value
  *
  * This function is called by the interrupt routine when checking for
  * interrupts. It will check and handle a pps event.
  */
-void ixgbe_ptp_check_pps_event(struct ixgbe_adapter *adapter, u32 eicr)
+void ixgbe_ptp_check_pps_event(struct ixgbe_adapter *adapter)
 {
 	struct ixgbe_hw *hw = &adapter->hw;
 	struct ptp_clock_event event;
@@ -425,7 +611,9 @@ void ixgbe_ptp_rx_hang(struct ixgbe_adap
 {
 	struct ixgbe_hw *hw = &adapter->hw;
 	u32 tsyncrxctl = IXGBE_READ_REG(hw, IXGBE_TSYNCRXCTL);
+	struct ixgbe_ring *rx_ring;
 	unsigned long rx_event;
+	int n;
 
 	/* if we don't have a valid timestamp in the registers, just update the
 	 * timeout counter and exit
@@ -437,19 +625,43 @@ void ixgbe_ptp_rx_hang(struct ixgbe_adap
 
 	/* determine the most recent watchdog or rx_timestamp event */
 	rx_event = adapter->last_rx_ptp_check;
-	if (time_after(adapter->last_rx_timestamp, rx_event))
-		rx_event = adapter->last_rx_timestamp;
+	for (n = 0; n < adapter->num_rx_queues; n++) {
+		rx_ring = adapter->rx_ring[n];
+		if (time_after(rx_ring->last_rx_timestamp, rx_event))
+			rx_event = rx_ring->last_rx_timestamp;
+	}
 
 	/* only need to read the high RXSTMP register to clear the lock */
-	if (time_is_before_jiffies(rx_event + 5*HZ)) {
+	if (time_is_before_jiffies(rx_event + 5 * HZ)) {
 		IXGBE_READ_REG(hw, IXGBE_RXSTMPH);
 		adapter->last_rx_ptp_check = jiffies;
 
+		adapter->rx_hwtstamp_cleared++;
 		e_warn(drv, "clearing RX Timestamp hang\n");
 	}
 }
 
 /**
+ * ixgbe_ptp_clear_tx_timestamp - utility function to clear Tx timestamp state
+ * @adapter: the private adapter structure
+ *
+ * This function should be called whenever the state related to a Tx timestamp
+ * needs to be cleared. This helps ensure that all related bits are reset for
+ * the next Tx timestamp event.
+ */
+static void ixgbe_ptp_clear_tx_timestamp(struct ixgbe_adapter *adapter)
+{
+	struct ixgbe_hw *hw = &adapter->hw;
+
+	IXGBE_READ_REG(hw, IXGBE_TXSTMPH);
+	if (adapter->ptp_tx_skb) {
+		dev_kfree_skb_any(adapter->ptp_tx_skb);
+		adapter->ptp_tx_skb = NULL;
+	}
+	clear_bit_unlock(__IXGBE_PTP_TX_IN_PROGRESS, &adapter->state);
+}
+
+/**
  * ixgbe_ptp_tx_hwtstamp - utility function which checks for TX time stamp
  * @adapter: the private adapter struct
  *
@@ -461,23 +673,15 @@ static void ixgbe_ptp_tx_hwtstamp(struct
 {
 	struct ixgbe_hw *hw = &adapter->hw;
 	struct skb_shared_hwtstamps shhwtstamps;
-	u64 regval = 0, ns;
-	unsigned long flags;
+	u64 regval = 0;
 
 	regval |= (u64)IXGBE_READ_REG(hw, IXGBE_TXSTMPL);
 	regval |= (u64)IXGBE_READ_REG(hw, IXGBE_TXSTMPH) << 32;
 
-	spin_lock_irqsave(&adapter->tmreg_lock, flags);
-	ns = timecounter_cyc2time(&adapter->tc, regval);
-	spin_unlock_irqrestore(&adapter->tmreg_lock, flags);
-
-	memset(&shhwtstamps, 0, sizeof(shhwtstamps));
-	shhwtstamps.hwtstamp = ns_to_ktime(ns);
+	ixgbe_ptp_convert_to_hwtstamp(adapter, &shhwtstamps, regval);
 	skb_tstamp_tx(adapter->ptp_tx_skb, &shhwtstamps);
 
-	dev_kfree_skb_any(adapter->ptp_tx_skb);
-	adapter->ptp_tx_skb = NULL;
-	clear_bit_unlock(__IXGBE_PTP_TX_IN_PROGRESS, &adapter->state);
+	ixgbe_ptp_clear_tx_timestamp(adapter);
 }
 
 /**
@@ -497,38 +701,85 @@ static void ixgbe_ptp_tx_hwtstamp_work(s
 					      IXGBE_PTP_TX_TIMEOUT);
 	u32 tsynctxctl;
 
-	if (timeout) {
-		dev_kfree_skb_any(adapter->ptp_tx_skb);
-		adapter->ptp_tx_skb = NULL;
-		clear_bit_unlock(__IXGBE_PTP_TX_IN_PROGRESS, &adapter->state);
-		e_warn(drv, "clearing Tx Timestamp hang\n");
+	/* we have to have a valid skb to poll for a timestamp */
+	if (!adapter->ptp_tx_skb) {
+		ixgbe_ptp_clear_tx_timestamp(adapter);
 		return;
 	}
 
+	/* stop polling once we have a valid timestamp */
 	tsynctxctl = IXGBE_READ_REG(hw, IXGBE_TSYNCTXCTL);
-	if (tsynctxctl & IXGBE_TSYNCTXCTL_VALID)
+	if (tsynctxctl & IXGBE_TSYNCTXCTL_VALID) {
 		ixgbe_ptp_tx_hwtstamp(adapter);
-	else
+		return;
+	}
+
+	if (timeout) {
+		ixgbe_ptp_clear_tx_timestamp(adapter);
+		adapter->tx_hwtstamp_timeouts++;
+		e_warn(drv, "clearing Tx Timestamp hang\n");
+	} else {
 		/* reschedule to keep checking if it's not available yet */
 		schedule_work(&adapter->ptp_tx_work);
+	}
 }
 
 /**
- * ixgbe_ptp_rx_hwtstamp - utility function which checks for RX time stamp
- * @adapter: pointer to adapter struct
+ * ixgbe_ptp_rx_pktstamp - utility function to get RX time stamp from buffer
+ * @q_vector: structure containing interrupt and ring information
+ * @skb: the packet
+ *
+ * This function will be called by the Rx routine of the timestamp for this
+ * packet is stored in the buffer. The value is stored in little endian format
+ * starting at the end of the packet data.
+ */
+void ixgbe_ptp_rx_pktstamp(struct ixgbe_q_vector *q_vector,
+			   struct sk_buff *skb)
+{
+	__le64 regval;
+
+	/* copy the bits out of the skb, and then trim the skb length */
+	skb_copy_bits(skb, skb->len - IXGBE_TS_HDR_LEN, &regval,
+		      IXGBE_TS_HDR_LEN);
+	__pskb_trim(skb, skb->len - IXGBE_TS_HDR_LEN);
+
+	/* The timestamp is recorded in little endian format, and is stored at
+	 * the end of the packet.
+	 *
+	 * DWORD: N              N + 1      N + 2
+	 * Field: End of Packet  SYSTIMH    SYSTIML
+	 */
+	ixgbe_ptp_convert_to_hwtstamp(q_vector->adapter, skb_hwtstamps(skb),
+				      le64_to_cpu(regval));
+}
+
+/**
+ * ixgbe_ptp_rx_rgtstamp - utility function which checks for RX time stamp
+ * @q_vector: structure containing interrupt and ring information
  * @skb: particular skb to send timestamp with
  *
  * if the timestamp is valid, we convert it into the timecounter ns
  * value, then store that result into the shhwtstamps structure which
  * is passed up the network stack
  */
-void ixgbe_ptp_rx_hwtstamp(struct ixgbe_adapter *adapter, struct sk_buff *skb)
+void ixgbe_ptp_rx_rgtstamp(struct ixgbe_q_vector *q_vector,
+			   struct sk_buff *skb)
 {
-	struct ixgbe_hw *hw = &adapter->hw;
-	struct skb_shared_hwtstamps *shhwtstamps;
-	u64 regval = 0, ns;
+	struct ixgbe_adapter *adapter;
+	struct ixgbe_hw *hw;
+	u64 regval = 0;
 	u32 tsyncrxctl;
-	unsigned long flags;
+
+	/* we cannot process timestamps on a ring without a q_vector */
+	if (!q_vector || !q_vector->adapter)
+		return;
+
+	adapter = q_vector->adapter;
+	hw = &adapter->hw;
+
+	/* Read the tsyncrxctl register afterwards in order to prevent taking an
+	 * I/O hit on every packet.
+	 */
 
 	tsyncrxctl = IXGBE_READ_REG(hw, IXGBE_TSYNCRXCTL);
 	if (!(tsyncrxctl & IXGBE_TSYNCRXCTL_VALID))
@@ -537,17 +788,7 @@ void ixgbe_ptp_rx_hwtstamp(struct ixgbe_
 	regval |= (u64)IXGBE_READ_REG(hw, IXGBE_RXSTMPL);
 	regval |= (u64)IXGBE_READ_REG(hw, IXGBE_RXSTMPH) << 32;
 
-	spin_lock_irqsave(&adapter->tmreg_lock, flags);
-	ns = timecounter_cyc2time(&adapter->tc, regval);
-	spin_unlock_irqrestore(&adapter->tmreg_lock, flags);
-
-	shhwtstamps = skb_hwtstamps(skb);
-	shhwtstamps->hwtstamp = ns_to_ktime(ns);
-
-	/* Update the last_rx_timestamp timer in order to enable watchdog check
-	 * for error case of latched timestamp on a dropped packet.
-	 */
-	adapter->last_rx_timestamp = jiffies;
+	ixgbe_ptp_convert_to_hwtstamp(adapter, skb_hwtstamps(skb), regval);
 }
 
 int ixgbe_ptp_get_ts_config(struct ixgbe_adapter *adapter, struct ifreq *ifr)
@@ -610,14 +851,20 @@ static int ixgbe_ptp_set_timestamp_mode(
 	case HWTSTAMP_FILTER_NONE:
 		tsync_rx_ctl = 0;
 		tsync_rx_mtrl = 0;
+		adapter->flags &= ~(IXGBE_FLAG_RX_HWTSTAMP_ENABLED |
+				    IXGBE_FLAG_RX_HWTSTAMP_IN_REGISTER);
 		break;
 	case HWTSTAMP_FILTER_PTP_V1_L4_SYNC:
 		tsync_rx_ctl |= IXGBE_TSYNCRXCTL_TYPE_L4_V1;
 		tsync_rx_mtrl |= IXGBE_RXMTRL_V1_SYNC_MSG;
+		adapter->flags &= ~(IXGBE_FLAG_RX_HWTSTAMP_ENABLED |
+				    IXGBE_FLAG_RX_HWTSTAMP_IN_REGISTER);
 		break;
 	case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ:
 		tsync_rx_ctl |= IXGBE_TSYNCRXCTL_TYPE_L4_V1;
 		tsync_rx_mtrl |= IXGBE_RXMTRL_V1_DELAY_REQ_MSG;
+		adapter->flags &= ~(IXGBE_FLAG_RX_HWTSTAMP_ENABLED |
+				    IXGBE_FLAG_RX_HWTSTAMP_IN_REGISTER);
 		break;
 	case HWTSTAMP_FILTER_PTP_V2_EVENT:
 	case HWTSTAMP_FILTER_PTP_V2_L2_EVENT:
@@ -631,9 +878,21 @@ static int ixgbe_ptp_set_timestamp_mode(
 		tsync_rx_ctl |= IXGBE_TSYNCRXCTL_TYPE_EVENT_V2;
 		is_l2 = true;
 		config->rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT;
+		adapter->flags &= ~(IXGBE_FLAG_RX_HWTSTAMP_ENABLED |
+				    IXGBE_FLAG_RX_HWTSTAMP_IN_REGISTER);
 		break;
 	case HWTSTAMP_FILTER_PTP_V1_L4_EVENT:
 	case HWTSTAMP_FILTER_ALL:
+		/* The X550 controller is capable of timestamping all packets,
+		 * which allows it to accept any filter.
+		 */
+		if (hw->mac.type >= ixgbe_mac_X550) {
+			tsync_rx_ctl |= IXGBE_TSYNCRXCTL_TYPE_ALL;
+			config->rx_filter = HWTSTAMP_FILTER_ALL;
+			adapter->flags |= IXGBE_FLAG_RX_HWTSTAMP_ENABLED;
+			break;
+		}
+		/* fall through */
 	default:
 		/*
 		 * register RXMTRL must be set in order to do V1 packets,
@@ -641,16 +900,46 @@ static int ixgbe_ptp_set_timestamp_mode(
 		 * Delay_Req messages and hardware does not support
 		 * timestamping all packets => return error
 		 */
+		adapter->flags &= ~(IXGBE_FLAG_RX_HWTSTAMP_ENABLED |
+				    IXGBE_FLAG_RX_HWTSTAMP_IN_REGISTER);
 		config->rx_filter = HWTSTAMP_FILTER_NONE;
 		return -ERANGE;
 	}
 
 	if (hw->mac.type == ixgbe_mac_82598EB) {
+		adapter->flags &= ~(IXGBE_FLAG_RX_HWTSTAMP_ENABLED |
+				    IXGBE_FLAG_RX_HWTSTAMP_IN_REGISTER);
 		if (tsync_rx_ctl | tsync_tx_ctl)
 			return -ERANGE;
 		return 0;
 	}
 
+	/* Per-packet timestamping only works if the filter is set to all
+	 * packets. Since this is desired, always timestamp all packets as long
+	 * as any Rx filter was configured.
+	 */
+	switch (hw->mac.type) {
+	case ixgbe_mac_X550:
+	case ixgbe_mac_X550EM_x:
+		/* enable timestamping all packets only if at least some
+		 * packets were requested. Otherwise, play nice and disable
+		 * timestamping
+		 */
+		if (config->rx_filter == HWTSTAMP_FILTER_NONE)
+			break;
+
+		tsync_rx_ctl = IXGBE_TSYNCRXCTL_ENABLED |
+			       IXGBE_TSYNCRXCTL_TYPE_ALL |
+			       IXGBE_TSYNCRXCTL_TSIP_UT_EN;
+		config->rx_filter = HWTSTAMP_FILTER_ALL;
+		adapter->flags |= IXGBE_FLAG_RX_HWTSTAMP_ENABLED;
+		adapter->flags &= ~IXGBE_FLAG_RX_HWTSTAMP_IN_REGISTER;
+		is_l2 = true;
+		break;
+	default:
+		break;
+	}
+
 	/* define ethertype filter for timestamping L2 packets */
 	if (is_l2)
 		IXGBE_WRITE_REG(hw, IXGBE_ETQF(IXGBE_ETQF_FILTER_1588),
@@ -678,8 +967,8 @@ static int ixgbe_ptp_set_timestamp_mode(
 	IXGBE_WRITE_FLUSH(hw);
 
 	/* clear TX/RX time stamp registers, just to be sure */
-	regval = IXGBE_READ_REG(hw, IXGBE_TXSTMPH);
-	regval = IXGBE_READ_REG(hw, IXGBE_RXSTMPH);
+	ixgbe_ptp_clear_tx_timestamp(adapter);
+	IXGBE_READ_REG(hw, IXGBE_RXSTMPH);
 
 	return 0;
 }
@@ -712,23 +1001,9 @@ int ixgbe_ptp_set_ts_config(struct ixgbe
 		-EFAULT : 0;
 }
 
-/**
- * ixgbe_ptp_start_cyclecounter - create the cycle counter from hw
- * @adapter: pointer to the adapter structure
- *
- * This function should be called to set the proper values for the TIMINCA
- * register and tell the cyclecounter structure what the tick rate of SYSTIME
- * is. It does not directly modify SYSTIME registers or the timecounter
- * structure. It should be called whenever a new TIMINCA value is necessary,
- * such as during initialization or when the link speed changes.
- */
-void ixgbe_ptp_start_cyclecounter(struct ixgbe_adapter *adapter)
+static void ixgbe_ptp_link_speed_adjust(struct ixgbe_adapter *adapter,
+					u32 *shift, u32 *incval)
 {
-	struct ixgbe_hw *hw = &adapter->hw;
-	u32 incval = 0;
-	u32 shift = 0;
-	unsigned long flags;
-
 	/**
 	 * Scale the NIC cycle counter by a large factor so that
 	 * relatively small corrections to the frequency can be added
@@ -745,36 +1020,98 @@ void ixgbe_ptp_start_cyclecounter(struct
 	 */
 	switch (adapter->link_speed) {
 	case IXGBE_LINK_SPEED_100_FULL:
-		incval = IXGBE_INCVAL_100;
-		shift = IXGBE_INCVAL_SHIFT_100;
+		*shift = IXGBE_INCVAL_SHIFT_100;
+		*incval = IXGBE_INCVAL_100;
 		break;
 	case IXGBE_LINK_SPEED_1GB_FULL:
-		incval = IXGBE_INCVAL_1GB;
-		shift = IXGBE_INCVAL_SHIFT_1GB;
+		*shift = IXGBE_INCVAL_SHIFT_1GB;
+		*incval = IXGBE_INCVAL_1GB;
 		break;
 	case IXGBE_LINK_SPEED_10GB_FULL:
 	default:
-		incval = IXGBE_INCVAL_10GB;
-		shift = IXGBE_INCVAL_SHIFT_10GB;
+		*shift = IXGBE_INCVAL_SHIFT_10GB;
+		*incval = IXGBE_INCVAL_10GB;
 		break;
 	}
+}
 
-	/**
-	 * Modify the calculated values to fit within the correct
-	 * number of bits specified by the hardware. The 82599 doesn't
-	 * have the same space as the X540, so bitshift the calculated
-	 * values to fit.
+/**
+ * ixgbe_ptp_start_cyclecounter - create the cycle counter from hw
+ * @adapter: pointer to the adapter structure
+ *
+ * This function should be called to set the proper values for the TIMINCA
+ * register and tell the cyclecounter structure what the tick rate of SYSTIME
+ * is. It does not directly modify SYSTIME registers or the timecounter
+ * structure. It should be called whenever a new TIMINCA value is necessary,
+ * such as during initialization or when the link speed changes.
+ */
+void ixgbe_ptp_start_cyclecounter(struct ixgbe_adapter *adapter)
+{
+	struct ixgbe_hw *hw = &adapter->hw;
+	struct cyclecounter cc;
+	unsigned long flags;
+	u32 incval = 0;
+	u32 tsauxc = 0;
+	u32 fuse0 = 0;
+
+	/* For some of the boards below this mask is technically incorrect.
+	 * The timestamp mask overflows at approximately 61bits. However the
+	 * particular hardware does not overflow on an even bitmask value.
+	 * Instead, it overflows due to conversion of upper 32bits billions of
+	 * cycles. Timecounters are not really intended for this purpose so
+	 * they do not properly function if the overflow point isn't 2^N-1.
+	 * However, the actual SYSTIME values in question take ~138 years to
+	 * overflow. In practice this means they won't actually overflow. A
+	 * proper fix to this problem would require modification of the
+	 * timecounter delta calculations.
 	 */
+	cc.mask = CLOCKSOURCE_MASK(64);
+	cc.mult = 1;
+	cc.shift = 0;
+
 	switch (hw->mac.type) {
+	case ixgbe_mac_X550EM_x:
+		/* SYSTIME assumes X550EM_x board frequency is 300Mhz, and is
+		 * designed to represent seconds and nanoseconds when this is
+		 * the case. However, some revisions of hardware have a 400Mhz
+		 * clock and we have to compensate for this frequency
+		 * variation using corrected mult and shift values.
+		 */
+		fuse0 = IXGBE_READ_REG(hw, IXGBE_FUSES0_GROUP(0));
+		if (!(fuse0 & IXGBE_FUSES0_300MHZ)) {
+			cc.mult = 3;
+			cc.shift = 2;
+		}
+		/* fallthrough */
+	case ixgbe_mac_X550:
+		cc.read = ixgbe_ptp_read_X550;
+
+		/* enable SYSTIME counter */
+		IXGBE_WRITE_REG(hw, IXGBE_SYSTIMR, 0);
+		IXGBE_WRITE_REG(hw, IXGBE_SYSTIML, 0);
+		IXGBE_WRITE_REG(hw, IXGBE_SYSTIMH, 0);
+		tsauxc = IXGBE_READ_REG(hw, IXGBE_TSAUXC);
+		IXGBE_WRITE_REG(hw, IXGBE_TSAUXC,
+				tsauxc & ~IXGBE_TSAUXC_DISABLE_SYSTIME);
+		IXGBE_WRITE_REG(hw, IXGBE_TSIM, IXGBE_TSIM_TXTS);
+		IXGBE_WRITE_REG(hw, IXGBE_EIMS, IXGBE_EIMS_TIMESYNC);
+
+		IXGBE_WRITE_FLUSH(hw);
+		break;
 	case ixgbe_mac_X540:
+		cc.read = ixgbe_ptp_read_82599;
+
+		ixgbe_ptp_link_speed_adjust(adapter, &cc.shift, &incval);
 		IXGBE_WRITE_REG(hw, IXGBE_TIMINCA, incval);
 		break;
 	case ixgbe_mac_82599EB:
+		cc.read = ixgbe_ptp_read_82599;
+
+		ixgbe_ptp_link_speed_adjust(adapter, &cc.shift, &incval);
 		incval >>= IXGBE_INCVAL_SHIFT_82599;
-		shift -= IXGBE_INCVAL_SHIFT_82599;
+		cc.shift -= IXGBE_INCVAL_SHIFT_82599;
 		IXGBE_WRITE_REG(hw, IXGBE_TIMINCA,
-				(1 << IXGBE_INCPER_SHIFT_82599) |
-				incval);
+				(1 << IXGBE_INCPER_SHIFT_82599) | incval);
 		break;
 	default:
 		/* other devices aren't supported */
@@ -787,13 +1124,7 @@ void ixgbe_ptp_start_cyclecounter(struct
 
 	/* need lock to prevent incorrect read while modifying cyclecounter */
 	spin_lock_irqsave(&adapter->tmreg_lock, flags);
-
-	memset(&adapter->cc, 0, sizeof(adapter->cc));
-	adapter->cc.read = ixgbe_ptp_read;
-	adapter->cc.mask = CYCLECOUNTER_MASK(64);
-	adapter->cc.shift = shift;
-	adapter->cc.mult = 1;
-
+	memcpy(&adapter->hw_cc, &cc, sizeof(adapter->hw_cc));
 	spin_unlock_irqrestore(&adapter->tmreg_lock, flags);
 }
 
@@ -814,29 +1145,27 @@ void ixgbe_ptp_reset(struct ixgbe_adapte
 	struct ixgbe_hw *hw = &adapter->hw;
 	unsigned long flags;
 
-	/* set SYSTIME registers to 0 just in case */
-	IXGBE_WRITE_REG(hw, IXGBE_SYSTIML, 0x00000000);
-	IXGBE_WRITE_REG(hw, IXGBE_SYSTIMH, 0x00000000);
-	IXGBE_WRITE_FLUSH(hw);
-
 	/* reset the hardware timestamping mode */
 	ixgbe_ptp_set_timestamp_mode(adapter, &adapter->tstamp_config);
 
+	/* 82598 does not support PTP */
+	if (hw->mac.type == ixgbe_mac_82598EB)
+		return;
+
 	ixgbe_ptp_start_cyclecounter(adapter);
 
 	spin_lock_irqsave(&adapter->tmreg_lock, flags);
-
-	/* reset the ns time counter */
-	timecounter_init(&adapter->tc, &adapter->cc,
+	timecounter_init(&adapter->hw_tc, &adapter->hw_cc,
 			 ktime_to_ns(ktime_get_real()));
-
 	spin_unlock_irqrestore(&adapter->tmreg_lock, flags);
 
-	/*
-	 * Now that the shift has been calculated and the systime
+	adapter->last_overflow_check = jiffies;
+
+	/* Now that the shift has been calculated and the systime
 	 * registers reset, (re-)enable the Clock out feature
 	 */
-	ixgbe_ptp_setup_sdp(adapter);
+	if (adapter->ptp_setup_sdp)
+		adapter->ptp_setup_sdp(adapter);
 }
 
 /**
@@ -845,11 +1174,11 @@ void ixgbe_ptp_reset(struct ixgbe_adapte
  *
  * This function performs setup of the user entry point function table and
  * initializes the PTP clock device, which is used to access the clock-like
- * features of the PTP core. It will be called by ixgbe_ptp_init, only if
- * there isn't already a clock device (such as after a suspend/resume cycle,
- * where the clock device wasn't destroyed).
+ * features of the PTP core. It will be called by ixgbe_ptp_init, and may
+ * reuse a previously initialized clock (such as during a suspend/resume
+ * cycle).
  */
-static int ixgbe_ptp_create_clock(struct ixgbe_adapter *adapter)
+static long ixgbe_ptp_create_clock(struct ixgbe_adapter *adapter)
 {
 	struct net_device *netdev = adapter->netdev;
 	long err;
@@ -869,11 +1198,12 @@ static int ixgbe_ptp_create_clock(struct
 		adapter->ptp_caps.n_ext_ts = 0;
 		adapter->ptp_caps.n_per_out = 0;
 		adapter->ptp_caps.pps = 1;
-		adapter->ptp_caps.adjfreq = ixgbe_ptp_adjfreq;
+		adapter->ptp_caps.adjfreq = ixgbe_ptp_adjfreq_82599;
 		adapter->ptp_caps.adjtime = ixgbe_ptp_adjtime;
 		adapter->ptp_caps.gettime64 = ixgbe_ptp_gettime;
 		adapter->ptp_caps.settime64 = ixgbe_ptp_settime;
 		adapter->ptp_caps.enable = ixgbe_ptp_feature_enable;
+		adapter->ptp_setup_sdp = ixgbe_ptp_setup_sdp_x540;
 		break;
 	case ixgbe_mac_82599EB:
 		snprintf(adapter->ptp_caps.name,
@@ -885,14 +1215,31 @@ static int ixgbe_ptp_create_clock(struct
 		adapter->ptp_caps.n_ext_ts = 0;
 		adapter->ptp_caps.n_per_out = 0;
 		adapter->ptp_caps.pps = 0;
-		adapter->ptp_caps.adjfreq = ixgbe_ptp_adjfreq;
+		adapter->ptp_caps.adjfreq = ixgbe_ptp_adjfreq_82599;
+		adapter->ptp_caps.adjtime = ixgbe_ptp_adjtime;
+		adapter->ptp_caps.gettime64 = ixgbe_ptp_gettime;
+		adapter->ptp_caps.settime64 = ixgbe_ptp_settime;
+		adapter->ptp_caps.enable = ixgbe_ptp_feature_enable;
+		break;
+	case ixgbe_mac_X550:
+	case ixgbe_mac_X550EM_x:
+		snprintf(adapter->ptp_caps.name, 16, "%s", netdev->name);
+		adapter->ptp_caps.owner = THIS_MODULE;
+		adapter->ptp_caps.max_adj = 30000000;
+		adapter->ptp_caps.n_alarm = 0;
+		adapter->ptp_caps.n_ext_ts = 0;
+		adapter->ptp_caps.n_per_out = 0;
+		adapter->ptp_caps.pps = 0;
+		adapter->ptp_caps.adjfreq = ixgbe_ptp_adjfreq_X550;
 		adapter->ptp_caps.adjtime = ixgbe_ptp_adjtime;
 		adapter->ptp_caps.gettime64 = ixgbe_ptp_gettime;
 		adapter->ptp_caps.settime64 = ixgbe_ptp_settime;
 		adapter->ptp_caps.enable = ixgbe_ptp_feature_enable;
+		adapter->ptp_setup_sdp = NULL;
 		break;
 	default:
 		adapter->ptp_clock = NULL;
+		adapter->ptp_setup_sdp = NULL;
 		return -EOPNOTSUPP;
 	}
 
@@ -961,18 +1308,13 @@ void ixgbe_ptp_suspend(struct ixgbe_adap
 	if (!test_and_clear_bit(__IXGBE_PTP_RUNNING, &adapter->state))
 		return;
 
-	/* since this might be called in suspend, we don't clear the state,
-	 * but simply reset the auxiliary PPS signal control register
-	 */
-	IXGBE_WRITE_REG(&adapter->hw, IXGBE_TSAUXC, 0x0);
+	adapter->flags2 &= ~IXGBE_FLAG2_PTP_PPS_ENABLED;
+	if (adapter->ptp_setup_sdp)
+		adapter->ptp_setup_sdp(adapter);
 
 	/* ensure that we cancel any pending PTP Tx work item in progress */
 	cancel_work_sync(&adapter->ptp_tx_work);
-	if (adapter->ptp_tx_skb) {
-		dev_kfree_skb_any(adapter->ptp_tx_skb);
-		adapter->ptp_tx_skb = NULL;
-		clear_bit_unlock(__IXGBE_PTP_TX_IN_PROGRESS, &adapter->state);
-	}
+	ixgbe_ptp_clear_tx_timestamp(adapter);
 }
 
 /**
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel 10 Gigabit PCI Express Linux driver
-  Copyright(c) 1999 - 2014 Intel Corporation.
+  Copyright(c) 1999 - 2015 Intel Corporation.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms and conditions of the GNU General Public License,
@@ -130,6 +130,38 @@ static int __ixgbe_enable_sriov(struct i
 	return -ENOMEM;
 }
 
+/**
+ * ixgbe_get_vfs - Find and take references to all vf devices
+ * @adapter: Pointer to adapter struct
+ */
+static void ixgbe_get_vfs(struct ixgbe_adapter *adapter)
+{
+	struct pci_dev *pdev = adapter->pdev;
+	u16 vendor = pdev->vendor;
+	struct pci_dev *vfdev;
+	int vf = 0;
+	u16 vf_id;
+	int pos;
+
+	pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_SRIOV);
+	if (!pos)
+		return;
+	pci_read_config_word(pdev, pos + PCI_SRIOV_VF_DID, &vf_id);
+
+	vfdev = pci_get_device(vendor, vf_id, NULL);
+	for (; vfdev; vfdev = pci_get_device(vendor, vf_id, vfdev)) {
+		if (!vfdev->is_virtfn)
+			continue;
+		if (vfdev->physfn != pdev)
+			continue;
+		if (vf >= adapter->num_vfs)
+			continue;
+		pci_dev_get(vfdev);
+		adapter->vfinfo[vf].vfdev = vfdev;
+		++vf;
+	}
+}
+
 /* Note this function is called when the user wants to enable SR-IOV
  * VFs using the now deprecated module parameter
  */
@@ -170,8 +202,10 @@ void ixgbe_enable_sriov(struct ixgbe_ada
 		}
 	}
 
-	if (!__ixgbe_enable_sriov(adapter))
+	if (!__ixgbe_enable_sriov(adapter)) {
+		ixgbe_get_vfs(adapter);
 		return;
+	}
 
 	/* If we have gotten to this point then there is no memory available
 	 * to manage the VF devices - print message and bail.
@@ -184,6 +218,7 @@ void ixgbe_enable_sriov(struct ixgbe_ada
 #endif /* #ifdef CONFIG_PCI_IOV */
 int ixgbe_disable_sriov(struct ixgbe_adapter *adapter)
 {
+	unsigned int num_vfs = adapter->num_vfs, vf;
 	struct ixgbe_hw *hw = &adapter->hw;
 	u32 gpie;
 	u32 vmdctl;
@@ -192,6 +227,16 @@ int ixgbe_disable_sriov(struct ixgbe_ada
 	/* set num VFs to 0 to prevent access to vfinfo */
 	adapter->num_vfs = 0;
 
+	/* put the reference to all of the vf devices */
+	for (vf = 0; vf < num_vfs; ++vf) {
+		struct pci_dev *vfdev = adapter->vfinfo[vf].vfdev;
+
+		if (!vfdev)
+			continue;
+		adapter->vfinfo[vf].vfdev = NULL;
+		pci_dev_put(vfdev);
+	}
+
 	/* free VF control structures */
 	kfree(adapter->vfinfo);
 	adapter->vfinfo = NULL;
@@ -289,6 +334,7 @@ static int ixgbe_pci_sriov_enable(struct
 		e_dev_warn("Failed to enable PCI sriov: %d\n", err);
 		return err;
 	}
+	ixgbe_get_vfs(adapter);
 	ixgbe_sriov_reinit(adapter);
 
 	return num_vfs;
@@ -406,11 +452,34 @@ void ixgbe_restore_vf_multicasts(struct
 static int ixgbe_set_vf_vlan(struct ixgbe_adapter *adapter, int add, int vid,
 			     u32 vf)
 {
-	/* VLAN 0 is a special case, don't allow it to be removed */
-	if (!vid && !add)
-		return 0;
+	struct ixgbe_hw *hw = &adapter->hw;
+	int err;
 
-	return adapter->hw.mac.ops.set_vfta(&adapter->hw, vid, vf, (bool)add);
+	/* If VLAN overlaps with one the PF is currently monitoring make
+	 * sure that we are able to allocate a VLVF entry.  This may be
+	 * redundant but it guarantees PF will maintain visibility to
+	 * the VLAN.
+	 */
+	if (add && test_bit(vid, adapter->active_vlans)) {
+		err = hw->mac.ops.set_vfta(hw, vid, VMDQ_P(0), true, false);
+		if (err)
+			return err;
+	}
+
+	err = hw->mac.ops.set_vfta(hw, vid, vf, !!add, false);
+
+	if (add && !err)
+		return err;
+
+	/* If we failed to add the VF VLAN or we are removing the VF VLAN
+	 * we may need to drop the PF pool bit in order to allow us to free
+	 * up the VLVF resources.
+	 */
+	if (test_bit(vid, adapter->active_vlans) ||
+	    (adapter->flags2 & IXGBE_FLAG2_VLAN_PROMISC))
+		ixgbe_update_pf_promisc_vlvf(adapter, vid);
+
+	return err;
 }
 
 static s32 ixgbe_set_vf_lpe(struct ixgbe_adapter *adapter, u32 *msgbuf, u32 vf)
@@ -516,13 +585,75 @@ static void ixgbe_clear_vmvir(struct ixg
 
 	IXGBE_WRITE_REG(hw, IXGBE_VMVIR(vf), 0);
 }
+
+static void ixgbe_clear_vf_vlans(struct ixgbe_adapter *adapter, u32 vf)
+{
+	struct ixgbe_hw *hw = &adapter->hw;
+	u32 i;
+
+	/* post increment loop, covers VLVF_ENTRIES - 1 to 0 */
+	for (i = IXGBE_VLVF_ENTRIES; i--;) {
+		u32 bits[2], vlvfb, vid, vfta, vlvf;
+		u32 word = i * 2 + vf / 32;
+		u32 mask = 1 << (vf % 32);
+
+		vlvfb = IXGBE_READ_REG(hw, IXGBE_VLVFB(word));
+
+		/* if our bit isn't set we can skip it */
+		if (!(vlvfb & mask))
+			continue;
+
+		/* clear our bit from vlvfb */
+		vlvfb ^= mask;
+
+		/* create 64b mask to chedk to see if we should clear VLVF */
+		bits[word % 2] = vlvfb;
+		bits[~word % 2] = IXGBE_READ_REG(hw, IXGBE_VLVFB(word ^ 1));
+
+		/* if promisc is enabled, PF will be present, leave VFTA */
+		if (adapter->flags2 & IXGBE_FLAG2_VLAN_PROMISC) {
+			bits[VMDQ_P(0) / 32] &= ~(1 << (VMDQ_P(0) % 32));
+
+			if (bits[0] || bits[1])
+				goto update_vlvfb;
+			goto update_vlvf;
+		}
+
+		/* if other pools are present, just remove ourselves */
+		if (bits[0] || bits[1])
+			goto update_vlvfb;
+
+		/* if we cannot determine VLAN just remove ourselves */
+		vlvf = IXGBE_READ_REG(hw, IXGBE_VLVF(i));
+		if (!vlvf)
+			goto update_vlvfb;
+
+		vid = vlvf & VLAN_VID_MASK;
+		mask = 1 << (vid % 32);
+
+		/* clear bit from VFTA */
+		vfta = IXGBE_READ_REG(hw, IXGBE_VFTA(vid / 32));
+		if (vfta & mask)
+			IXGBE_WRITE_REG(hw, IXGBE_VFTA(vid / 32), vfta ^ mask);
+update_vlvf:
+		/* clear POOL selection enable */
+		IXGBE_WRITE_REG(hw, IXGBE_VLVF(i), 0);
+update_vlvfb:
+		/* clear pool bits */
+		IXGBE_WRITE_REG(hw, IXGBE_VLVFB(word), vlvfb);
+	}
+}
+
 static inline void ixgbe_vf_reset_event(struct ixgbe_adapter *adapter, u32 vf)
 {
 	struct ixgbe_hw *hw = &adapter->hw;
 	struct vf_data_storage *vfinfo = &adapter->vfinfo[vf];
 	u8 num_tcs = netdev_get_num_tc(adapter->netdev);
 
-	/* add PF assigned VLAN or VLAN 0 */
+	/* remove VLAN filters beloning to this VF */
+	ixgbe_clear_vf_vlans(adapter, vf);
+
+	/* add back PF assigned VLAN or VLAN 0 */
 	ixgbe_set_vf_vlan(adapter, true, vfinfo->pf_vlan, vf);
 
 	/* reset offloads to defaults */
@@ -768,40 +899,14 @@ static int ixgbe_set_vf_mac_addr(struct
 	return ixgbe_set_vf_mac(adapter, vf, new_mac) < 0;
 }
 
-static int ixgbe_find_vlvf_entry(struct ixgbe_hw *hw, u32 vlan)
-{
-	u32 vlvf;
-	s32 regindex;
-
-	/* short cut the special case */
-	if (vlan == 0)
-		return 0;
-
-	/* Search for the vlan id in the VLVF entries */
-	for (regindex = 1; regindex < IXGBE_VLVF_ENTRIES; regindex++) {
-		vlvf = IXGBE_READ_REG(hw, IXGBE_VLVF(regindex));
-		if ((vlvf & VLAN_VID_MASK) == vlan)
-			break;
-	}
-
-	/* Return a negative value if not found */
-	if (regindex >= IXGBE_VLVF_ENTRIES)
-		regindex = -1;
-
-	return regindex;
-}
-
 static int ixgbe_set_vf_vlan_msg(struct ixgbe_adapter *adapter,
 				 u32 *msgbuf, u32 vf)
 {
+	u32 add = (msgbuf[0] & IXGBE_VT_MSGINFO_MASK) >> IXGBE_VT_MSGINFO_SHIFT;
+	u32 vid = (msgbuf[1] & IXGBE_VLVF_VLANID_MASK);
+	u8 tcs = netdev_get_num_tc(adapter->netdev);
 	struct ixgbe_hw *hw = &adapter->hw;
-	int add = (msgbuf[0] & IXGBE_VT_MSGINFO_MASK) >> IXGBE_VT_MSGINFO_SHIFT;
-	int vid = (msgbuf[1] & IXGBE_VLVF_VLANID_MASK);
 	int err;
-	s32 reg_ndx;
-	u32 vlvf;
-	u32 bits;
-	u8 tcs = netdev_get_num_tc(adapter->netdev);
 
 	if (adapter->vfinfo[vf].pf_vlan || tcs) {
 		e_warn(drv,
@@ -811,54 +916,23 @@ static int ixgbe_set_vf_vlan_msg(struct
 		return -1;
 	}
 
-	if (add)
-		adapter->vfinfo[vf].vlan_count++;
-	else if (adapter->vfinfo[vf].vlan_count)
-		adapter->vfinfo[vf].vlan_count--;
-
-	/* in case of promiscuous mode any VLAN filter set for a VF must
-	 * also have the PF pool added to it.
-	 */
-	if (add && adapter->netdev->flags & IFF_PROMISC)
-		err = ixgbe_set_vf_vlan(adapter, add, vid, VMDQ_P(0));
+	/* VLAN 0 is a special case, don't allow it to be removed */
+	if (!vid && !add)
+		return 0;
 
 	err = ixgbe_set_vf_vlan(adapter, add, vid, vf);
-	if (!err && adapter->vfinfo[vf].spoofchk_enabled)
-		hw->mac.ops.set_vlan_anti_spoofing(hw, true, vf);
+	if (err)
+		return err;
 
-	/* Go through all the checks to see if the VLAN filter should
-	 * be wiped completely.
-	 */
-	if (!add && adapter->netdev->flags & IFF_PROMISC) {
-		reg_ndx = ixgbe_find_vlvf_entry(hw, vid);
-		if (reg_ndx < 0)
-			return err;
-		vlvf = IXGBE_READ_REG(hw, IXGBE_VLVF(reg_ndx));
-		/* See if any other pools are set for this VLAN filter
-		 * entry other than the PF.
-		 */
-		if (VMDQ_P(0) < 32) {
-			bits = IXGBE_READ_REG(hw, IXGBE_VLVFB(reg_ndx * 2));
-			bits &= ~(1 << VMDQ_P(0));
-			bits |= IXGBE_READ_REG(hw,
-					       IXGBE_VLVFB(reg_ndx * 2) + 1);
-		} else {
-			bits = IXGBE_READ_REG(hw,
-					      IXGBE_VLVFB(reg_ndx * 2) + 1);
-			bits &= ~(1 << (VMDQ_P(0) - 32));
-			bits |= IXGBE_READ_REG(hw, IXGBE_VLVFB(reg_ndx * 2));
-		}
+	if (adapter->vfinfo[vf].spoofchk_enabled)
+		hw->mac.ops.set_vlan_anti_spoofing(hw, true, vf);
 
-		/* If the filter was removed then ensure PF pool bit
-		 * is cleared if the PF only added itself to the pool
-		 * because the PF is in promiscuous mode.
-		 */
-		if ((vlvf & VLAN_VID_MASK) == vid &&
-		    !test_bit(vid, adapter->active_vlans) && !bits)
-			ixgbe_set_vf_vlan(adapter, add, vid, VMDQ_P(0));
-	}
+	if (add)
+		adapter->vfinfo[vf].vlan_count++;
+	else if (adapter->vfinfo[vf].vlan_count)
+		adapter->vfinfo[vf].vlan_count--;
 
-	return err;
+	return 0;
 }
 
 static int ixgbe_set_vf_macvlan_msg(struct ixgbe_adapter *adapter,
@@ -1239,6 +1313,9 @@ static int ixgbe_enable_port_vlan(struct
 	if (err)
 		goto out;
 
+	/* Revoke tagless access via VLAN 0 */
+	ixgbe_set_vf_vlan(adapter, false, 0, vf);
+
 	ixgbe_set_vmvir(adapter, vlan, qos, vf);
 	ixgbe_set_vmolr(hw, vf, false);
 	if (adapter->vfinfo[vf].spoofchk_enabled)
@@ -1272,6 +1349,8 @@ static int ixgbe_disable_port_vlan(struc
 
 	err = ixgbe_set_vf_vlan(adapter, false,
 				adapter->vfinfo[vf].pf_vlan, vf);
+	/* Restore tagless access via VLAN 0 */
+	ixgbe_set_vf_vlan(adapter, true, 0, vf);
 	ixgbe_clear_vmvir(adapter, vf);
 	ixgbe_set_vmolr(hw, vf, true);
 	hw->mac.ops.set_vlan_anti_spoofing(hw, false, vf);
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h
@@ -1020,6 +1020,7 @@ struct ixgbe_thermal_sensor_data {
 #define IXGBE_TXSTMPH    0x08C08 /* Tx timestamp value High - RO */
 #define IXGBE_SYSTIML    0x08C0C /* System time register Low - RO */
 #define IXGBE_SYSTIMH    0x08C10 /* System time register High - RO */
+#define IXGBE_SYSTIMR    0x08C58 /* System time register Residue - RO */
 #define IXGBE_TIMINCA    0x08C14 /* Increment attributes register - RW */
 #define IXGBE_TIMADJL    0x08C18 /* Time Adjustment Offset register Low - RW */
 #define IXGBE_TIMADJH    0x08C1C /* Time Adjustment Offset register High - RW */
@@ -1036,6 +1037,7 @@ struct ixgbe_thermal_sensor_data {
 #define IXGBE_AUXSTMPH0  0x08C40 /* Auxiliary Time Stamp 0 register High - RO */
 #define IXGBE_AUXSTMPL1  0x08C44 /* Auxiliary Time Stamp 1 register Low - RO */
 #define IXGBE_AUXSTMPH1  0x08C48 /* Auxiliary Time Stamp 1 register High - RO */
+#define IXGBE_TSIM       0x08C68 /* TimeSync Interrupt Mask Register - RW */
 
 /* Diagnostic Registers */
 #define IXGBE_RDSTATCTL   0x02C20
@@ -1345,7 +1347,10 @@ struct ixgbe_thermal_sensor_data {
 #define IXGBE_MDIO_GLOBAL_INT_CHIP_VEN_MASK	0xFF01 /* int chip-wide mask */
 #define IXGBE_MDIO_GLOBAL_INT_CHIP_VEN_FLAG	0xFC01 /* int chip-wide mask */
 #define IXGBE_MDIO_GLOBAL_ALARM_1		0xCC00 /* Global alarm 1 */
+#define IXGBE_MDIO_GLOBAL_ALM_1_DEV_FAULT	0x0010 /* device fault */
 #define IXGBE_MDIO_GLOBAL_ALM_1_HI_TMP_FAIL	0x4000 /* high temp failure */
+#define IXGBE_MDIO_GLOBAL_FAULT_MSG		0xC850 /* global fault msg */
+#define IXGBE_MDIO_GLOBAL_FAULT_MSG_HI_TMP	0x8007 /* high temp failure */
 #define IXGBE_MDIO_GLOBAL_INT_MASK		0xD400 /* Global int mask */
 /* autoneg vendor alarm int enable */
 #define IXGBE_MDIO_GLOBAL_AN_VEN_ALM_INT_EN	0x1000
@@ -1353,6 +1358,7 @@ struct ixgbe_thermal_sensor_data {
 #define IXGBE_MDIO_GLOBAL_VEN_ALM_INT_EN	0x1 /* vendor alarm int enable */
 #define IXGBE_MDIO_GLOBAL_STD_ALM2_INT		0x200 /* vendor alarm2 int mask */
 #define IXGBE_MDIO_GLOBAL_INT_HI_TEMP_EN	0x4000 /* int high temp enable */
+#define IXGBE_MDIO_GLOBAL_INT_DEV_FAULT_EN	0x0010 /*int dev fault enable */
 
 #define IXGBE_MDIO_PMA_PMD_SDA_SCL_ADDR	0xC30A /* PHY_XS SDA/SCL Addr Reg */
 #define IXGBE_MDIO_PMA_PMD_SDA_SCL_DATA	0xC30B /* PHY_XS SDA/SCL Data Reg */
@@ -2209,6 +2215,7 @@ enum {
 #define IXGBE_TSAUXC_EN_CLK   0x00000004
 #define IXGBE_TSAUXC_SYNCLK   0x00000008
 #define IXGBE_TSAUXC_SDP0_INT 0x00000040
+#define IXGBE_TSAUXC_DISABLE_SYSTIME	0x80000000
 
 #define IXGBE_TSYNCTXCTL_VALID		0x00000001 /* Tx timestamp valid */
 #define IXGBE_TSYNCTXCTL_ENABLED	0x00000010 /* Tx timestamping enabled */
@@ -2218,8 +2225,12 @@ enum {
 #define IXGBE_TSYNCRXCTL_TYPE_L2_V2	0x00
 #define IXGBE_TSYNCRXCTL_TYPE_L4_V1	0x02
 #define IXGBE_TSYNCRXCTL_TYPE_L2_L4_V2	0x04
+#define IXGBE_TSYNCRXCTL_TYPE_ALL	0x08
 #define IXGBE_TSYNCRXCTL_TYPE_EVENT_V2	0x0A
 #define IXGBE_TSYNCRXCTL_ENABLED	0x00000010 /* Rx Timestamping enabled */
+#define IXGBE_TSYNCRXCTL_TSIP_UT_EN	0x00800000 /* Rx Timestamp in Packet */
+
+#define IXGBE_TSIM_TXTS			0x00000002
 
 #define IXGBE_RXMTRL_V1_CTRLT_MASK	0x000000FF
 #define IXGBE_RXMTRL_V1_SYNC_MSG	0x00
@@ -2332,6 +2343,7 @@ enum {
 #define IXGBE_RXD_STAT_UDPV     0x400   /* Valid UDP checksum */
 #define IXGBE_RXD_STAT_DYNINT   0x800   /* Pkt caused INT via DYNINT */
 #define IXGBE_RXD_STAT_LLINT    0x800   /* Pkt caused Low Latency Interrupt */
+#define IXGBE_RXD_STAT_TSIP     0x08000 /* Time Stamp in packet buffer */
 #define IXGBE_RXD_STAT_TS       0x10000 /* Time Stamp */
 #define IXGBE_RXD_STAT_SECP     0x20000 /* Security Processing */
 #define IXGBE_RXD_STAT_LB       0x40000 /* Loopback Status */
@@ -2768,6 +2780,7 @@ struct ixgbe_adv_tx_context_desc {
 #define IXGBE_ADVTXD_TUCMD_L4T_UDP   0x00000000  /* L4 Packet TYPE of UDP */
 #define IXGBE_ADVTXD_TUCMD_L4T_TCP   0x00000800  /* L4 Packet TYPE of TCP */
 #define IXGBE_ADVTXD_TUCMD_L4T_SCTP  0x00001000  /* L4 Packet TYPE of SCTP */
+#define IXGBE_ADVTXD_TUCMD_L4T_RSV     0x00001800 /* RSV L4 Packet TYPE */
 #define IXGBE_ADVTXD_TUCMD_MKRREQ    0x00002000 /*Req requires Markers and CRC*/
 #define IXGBE_ADVTXD_POPTS_IPSEC      0x00000400 /* IPSec offload request */
 #define IXGBE_ADVTXD_TUCMD_IPSEC_TYPE_ESP 0x00002000 /* IPSec Type ESP */
@@ -3288,7 +3301,7 @@ struct ixgbe_mac_operations {
 	s32 (*enable_mc)(struct ixgbe_hw *);
 	s32 (*disable_mc)(struct ixgbe_hw *);
 	s32 (*clear_vfta)(struct ixgbe_hw *);
-	s32 (*set_vfta)(struct ixgbe_hw *, u32, u32, bool);
+	s32 (*set_vfta)(struct ixgbe_hw *, u32, u32, bool, bool);
 	s32 (*init_uta_tables)(struct ixgbe_hw *);
 	void (*set_mac_anti_spoofing)(struct ixgbe_hw *, bool, int);
 	void (*set_vlan_anti_spoofing)(struct ixgbe_hw *, bool, int);
@@ -3508,7 +3521,7 @@ struct ixgbe_info {
 
 #define IXGBE_FUSES0_GROUP(_i)		(0x11158 + ((_i) * 4))
 #define IXGBE_FUSES0_300MHZ		BIT(5)
-#define IXGBE_FUSES0_REV1		BIT(6)
+#define IXGBE_FUSES0_REV_MASK		(3 << 6)
 
 #define IXGBE_KRM_PORT_CAR_GEN_CTRL(P)	((P) ? 0x8010 : 0x4010)
 #define IXGBE_KRM_LINK_CTRL_1(P)	((P) ? 0x820C : 0x420C)
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/intel/ixgbe/ixgbe_x540.c
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/intel/ixgbe/ixgbe_x540.c
@@ -57,8 +57,7 @@ s32 ixgbe_get_invariants_X540(struct ixg
 	struct ixgbe_phy_info *phy = &hw->phy;
 
 	/* set_phy_power was set by default to NULL */
-	if (!ixgbe_mng_present(hw))
-		phy->ops.set_phy_power = ixgbe_set_copper_phy_power;
+	phy->ops.set_phy_power = ixgbe_set_copper_phy_power;
 
 	mac->mcft_size = IXGBE_X540_MC_TBL_SIZE;
 	mac->vft_size = IXGBE_X540_VFT_TBL_SIZE;
@@ -110,13 +109,14 @@ mac_reset_top:
 	ctrl |= IXGBE_READ_REG(hw, IXGBE_CTRL);
 	IXGBE_WRITE_REG(hw, IXGBE_CTRL, ctrl);
 	IXGBE_WRITE_FLUSH(hw);
+	usleep_range(1000, 1200);
 
 	/* Poll for reset bit to self-clear indicating reset is complete */
 	for (i = 0; i < 10; i++) {
-		udelay(1);
 		ctrl = IXGBE_READ_REG(hw, IXGBE_CTRL);
 		if (!(ctrl & IXGBE_CTRL_RST_MASK))
 			break;
+		udelay(1);
 	}
 
 	if (ctrl & IXGBE_CTRL_RST_MASK) {
@@ -154,12 +154,16 @@ mac_reset_top:
 
 	/* Add the SAN MAC address to the RAR only if it's a valid address */
 	if (is_valid_ether_addr(hw->mac.san_addr)) {
-		hw->mac.ops.set_rar(hw, hw->mac.num_rar_entries - 1,
-				    hw->mac.san_addr, 0, IXGBE_RAH_AV);
-
 		/* Save the SAN MAC RAR index */
 		hw->mac.san_mac_rar_index = hw->mac.num_rar_entries - 1;
 
+		hw->mac.ops.set_rar(hw, hw->mac.san_mac_rar_index,
+				    hw->mac.san_addr, 0, IXGBE_RAH_AV);
+
+		/* clear VMDq pool/queue selection for this RAR */
+		hw->mac.ops.clear_vmdq(hw, hw->mac.san_mac_rar_index,
+				       IXGBE_CLEAR_VMDQ_ALL);
+
 		/* Reserve the last RAR for the SAN MAC address */
 		hw->mac.num_rar_entries--;
 	}
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/intel/ixgbe/ixgbe_x550.c
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/intel/ixgbe/ixgbe_x550.c
@@ -26,6 +26,8 @@
 #include "ixgbe_common.h"
 #include "ixgbe_phy.h"
 
+static s32 ixgbe_setup_kr_speed_x550em(struct ixgbe_hw *, ixgbe_link_speed);
+
 static s32 ixgbe_get_invariants_X550_x(struct ixgbe_hw *hw)
 {
 	struct ixgbe_mac_info *mac = &hw->mac;
@@ -85,79 +87,6 @@ static s32 ixgbe_write_cs4227(struct ixg
 }
 
 /**
- * ixgbe_check_cs4227_reg - Perform diag on a CS4227 register
- * @hw: pointer to hardware structure
- * @reg: the register to check
- *
- * Performs a diagnostic on a register in the CS4227 chip. Returns an error
- * if it is not operating correctly.
- * This function assumes that the caller has acquired the proper semaphore.
- */
-static s32 ixgbe_check_cs4227_reg(struct ixgbe_hw *hw, u16 reg)
-{
-	s32 status;
-	u32 retry;
-	u16 reg_val;
-
-	reg_val = (IXGBE_CS4227_EDC_MODE_DIAG << 1) | 1;
-	status = ixgbe_write_cs4227(hw, reg, reg_val);
-	if (status)
-		return status;
-	for (retry = 0; retry < IXGBE_CS4227_RETRIES; retry++) {
-		msleep(IXGBE_CS4227_CHECK_DELAY);
-		reg_val = 0xFFFF;
-		ixgbe_read_cs4227(hw, reg, &reg_val);
-		if (!reg_val)
-			break;
-	}
-	if (reg_val) {
-		hw_err(hw, "CS4227 reg 0x%04X failed diagnostic\n", reg);
-		return status;
-	}
-
-	return 0;
-}
-
-/**
- * ixgbe_get_cs4227_status - Return CS4227 status
- * @hw: pointer to hardware structure
- *
- * Performs a diagnostic on the CS4227 chip. Returns an error if it is
- * not operating correctly.
- * This function assumes that the caller has acquired the proper semaphore.
- */
-static s32 ixgbe_get_cs4227_status(struct ixgbe_hw *hw)
-{
-	s32 status;
-	u16 value = 0;
-
-	/* Exit if the diagnostic has already been performed. */
-	status = ixgbe_read_cs4227(hw, IXGBE_CS4227_SCRATCH, &value);
-	if (status)
-		return status;
-	if (value == IXGBE_CS4227_RESET_COMPLETE)
-		return 0;
-
-	/* Check port 0. */
-	status = ixgbe_check_cs4227_reg(hw, IXGBE_CS4227_LINE_SPARE24_LSB);
-	if (status)
-		return status;
-
-	status = ixgbe_check_cs4227_reg(hw, IXGBE_CS4227_HOST_SPARE24_LSB);
-	if (status)
-		return status;
-
-	/* Check port 1. */
-	status = ixgbe_check_cs4227_reg(hw, IXGBE_CS4227_LINE_SPARE24_LSB +
-					(1 << 12));
-	if (status)
-		return status;
-
-	return ixgbe_check_cs4227_reg(hw, IXGBE_CS4227_HOST_SPARE24_LSB +
-				      (1 << 12));
-}
-
-/**
  * ixgbe_read_pe - Read register from port expander
  * @hw: pointer to hardware structure
  * @reg: register number to read
@@ -326,13 +255,6 @@ static void ixgbe_check_cs4227(struct ix
 		return;
 	}
 
-	/* Is the CS4227 working correctly? */
-	status = ixgbe_get_cs4227_status(hw);
-	if (status) {
-		hw_err(hw, "CS4227 status failed: %d", status);
-		goto out;
-	}
-
 	/* Record completion for next time. */
 	status = ixgbe_write_cs4227(hw, IXGBE_CS4227_SCRATCH,
 				    IXGBE_CS4227_RESET_COMPLETE);
@@ -1257,31 +1179,71 @@ ixgbe_setup_mac_link_sfp_x550em(struct i
 	if (status)
 		return status;
 
-	/* Configure CS4227 LINE side to 10G SR. */
-	slice = IXGBE_CS4227_LINE_SPARE22_MSB + (hw->bus.lan_id << 12);
-	value = IXGBE_CS4227_SPEED_10G;
-	status = ixgbe_write_i2c_combined_generic(hw, IXGBE_CS4227, slice,
-						  value);
-
-	/* Configure CS4227 for HOST connection rate then type. */
-	slice = IXGBE_CS4227_HOST_SPARE22_MSB + (hw->bus.lan_id << 12);
-	value = speed & IXGBE_LINK_SPEED_10GB_FULL ?
-		IXGBE_CS4227_SPEED_10G : IXGBE_CS4227_SPEED_1G;
-	status = ixgbe_write_i2c_combined_generic(hw, IXGBE_CS4227, slice,
-						  value);
-
-	slice = IXGBE_CS4227_HOST_SPARE24_LSB + (hw->bus.lan_id << 12);
-	if (setup_linear)
-		value = (IXGBE_CS4227_EDC_MODE_CX1 << 1) | 1;
-	else
+	if (!(hw->phy.nw_mng_if_sel & IXGBE_NW_MNG_IF_SEL_INT_PHY_MODE)) {
+		/* Configure CS4227 LINE side to 10G SR. */
+		slice = IXGBE_CS4227_LINE_SPARE22_MSB + (hw->bus.lan_id << 12);
+		value = IXGBE_CS4227_SPEED_10G;
+		status = ixgbe_write_i2c_combined_generic(hw, IXGBE_CS4227,
+							  slice, value);
+		if (status)
+			goto i2c_err;
+
+		slice = IXGBE_CS4227_LINE_SPARE24_LSB + (hw->bus.lan_id << 12);
 		value = (IXGBE_CS4227_EDC_MODE_SR << 1) | 1;
-	status = ixgbe_write_i2c_combined_generic(hw, IXGBE_CS4227, slice,
-						  value);
+		status = ixgbe_write_i2c_combined_generic(hw, IXGBE_CS4227,
+							  slice, value);
+		if (status)
+			goto i2c_err;
 
-	/* If internal link mode is XFI, then setup XFI internal link. */
-	if (!(hw->phy.nw_mng_if_sel & IXGBE_NW_MNG_IF_SEL_INT_PHY_MODE))
+		/* Configure CS4227 for HOST connection rate then type. */
+		slice = IXGBE_CS4227_HOST_SPARE22_MSB + (hw->bus.lan_id << 12);
+		value = speed & IXGBE_LINK_SPEED_10GB_FULL ?
+			IXGBE_CS4227_SPEED_10G : IXGBE_CS4227_SPEED_1G;
+		status = ixgbe_write_i2c_combined_generic(hw, IXGBE_CS4227,
+							  slice, value);
+		if (status)
+			goto i2c_err;
+
+		slice = IXGBE_CS4227_HOST_SPARE24_LSB + (hw->bus.lan_id << 12);
+		if (setup_linear)
+			value = (IXGBE_CS4227_EDC_MODE_CX1 << 1) | 1;
+		else
+			value = (IXGBE_CS4227_EDC_MODE_SR << 1) | 1;
+		status = ixgbe_write_i2c_combined_generic(hw, IXGBE_CS4227,
+							  slice, value);
+		if (status)
+			goto i2c_err;
+
+		/* Setup XFI internal link. */
 		status = ixgbe_setup_ixfi_x550em(hw, &speed);
+		if (status) {
+			hw_dbg(hw, "setup_ixfi failed with %d\n", status);
+			return status;
+		}
+	} else {
+		/* Configure internal PHY for KR/KX. */
+		status = ixgbe_setup_kr_speed_x550em(hw, speed);
+		if (status) {
+			hw_dbg(hw, "setup_kr_speed failed with %d\n", status);
+			return status;
+		}
+
+		/* Configure CS4227 LINE side to proper mode. */
+		slice = IXGBE_CS4227_LINE_SPARE24_LSB + (hw->bus.lan_id << 12);
+		if (setup_linear)
+			value = (IXGBE_CS4227_EDC_MODE_CX1 << 1) | 1;
+		else
+			value = (IXGBE_CS4227_EDC_MODE_SR << 1) | 1;
+		status = ixgbe_write_i2c_combined_generic(hw, IXGBE_CS4227,
+							  slice, value);
+		if (status)
+			goto i2c_err;
+	}
 
+	return 0;
+
+i2c_err:
+	hw_dbg(hw, "combined i2c access failed with %d\n", status);
 	return status;
 }
 
@@ -1482,7 +1444,7 @@ static s32 ixgbe_get_lasi_ext_t_x550em(s
 				IXGBE_MDIO_GLOBAL_ALARM_1_INT)))
 		return status;
 
-	/* High temperature failure alarm triggered */
+	/* Global alarm triggered */
 	status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_GLOBAL_ALARM_1,
 				      IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
 				      &reg);
@@ -1496,6 +1458,21 @@ static s32 ixgbe_get_lasi_ext_t_x550em(s
 		ixgbe_set_copper_phy_power(hw, false);
 		return IXGBE_ERR_OVERTEMP;
 	}
+	if (reg & IXGBE_MDIO_GLOBAL_ALM_1_DEV_FAULT) {
+		/*  device fault alarm triggered */
+		status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_GLOBAL_FAULT_MSG,
+					  IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
+					  &reg);
+		if (status)
+			return status;
+
+		/* if device fault was due to high temp alarm handle and exit */
+		if (reg == IXGBE_MDIO_GLOBAL_FAULT_MSG_HI_TMP) {
+			/* power down the PHY in case the PHY FW didn't */
+			ixgbe_set_copper_phy_power(hw, false);
+			return IXGBE_ERR_OVERTEMP;
+		}
+	}
 
 	/* Vendor alarm 2 triggered */
 	status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_GLOBAL_CHIP_STD_INT_FLAG,
@@ -1549,14 +1526,15 @@ static s32 ixgbe_enable_lasi_ext_t_x550e
 	if (status)
 		return status;
 
-	/* Enables high temperature failure alarm */
+	/* Enable high temperature failure and global fault alarms */
 	status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_GLOBAL_INT_MASK,
 				      IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
 				      &reg);
 	if (status)
 		return status;
 
-	reg |= IXGBE_MDIO_GLOBAL_INT_HI_TEMP_EN;
+	reg |= (IXGBE_MDIO_GLOBAL_INT_HI_TEMP_EN |
+		IXGBE_MDIO_GLOBAL_INT_DEV_FAULT_EN);
 
 	status = hw->phy.ops.write_reg(hw, IXGBE_MDIO_GLOBAL_INT_MASK,
 				       IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
@@ -1765,6 +1743,12 @@ static s32 ixgbe_setup_internal_phy_t_x5
 	if (hw->mac.ops.get_media_type(hw) != ixgbe_media_type_copper)
 		return IXGBE_ERR_CONFIG;
 
+	if (hw->phy.nw_mng_if_sel & IXGBE_NW_MNG_IF_SEL_INT_PHY_MODE) {
+		speed = IXGBE_LINK_SPEED_10GB_FULL |
+			IXGBE_LINK_SPEED_1GB_FULL;
+		return ixgbe_setup_kr_speed_x550em(hw, speed);
+	}
+
 	/* If link is not up, then there is no setup necessary so return  */
 	status = ixgbe_ext_phy_t_x550em_get_link(hw, &link_up);
 	if (status)
@@ -1873,10 +1857,6 @@ static s32 ixgbe_enter_lplu_t_x550em(str
 	u32 save_autoneg;
 	bool link_up;
 
-	/* SW LPLU not required on later HW revisions. */
-	if (IXGBE_FUSES0_REV1 & IXGBE_READ_REG(hw, IXGBE_FUSES0_GROUP(0)))
-		return 0;
-
 	/* If blocked by MNG FW, then don't restart AN */
 	if (ixgbe_check_reset_blocked(hw))
 		return 0;
@@ -1969,7 +1949,6 @@ static s32 ixgbe_enter_lplu_t_x550em(str
 static s32 ixgbe_init_phy_ops_X550em(struct ixgbe_hw *hw)
 {
 	struct ixgbe_phy_info *phy = &hw->phy;
-	ixgbe_link_speed speed;
 	s32 ret_val;
 
 	hw->mac.ops.set_lan_id(hw);
@@ -1982,13 +1961,6 @@ static s32 ixgbe_init_phy_ops_X550em(str
 		 * to determine internal PHY mode.
 		 */
 		phy->nw_mng_if_sel = IXGBE_READ_REG(hw, IXGBE_NW_MNG_IF_SEL);
-
-		/* If internal PHY mode is KR, then initialize KR link */
-		if (phy->nw_mng_if_sel & IXGBE_NW_MNG_IF_SEL_INT_PHY_MODE) {
-			speed = IXGBE_LINK_SPEED_10GB_FULL |
-				IXGBE_LINK_SPEED_1GB_FULL;
-			ret_val = ixgbe_setup_kr_speed_x550em(hw, speed);
-		}
 	}
 
 	/* Identify the PHY or SFP module */
@@ -2020,18 +1992,13 @@ static s32 ixgbe_init_phy_ops_X550em(str
 		/* If internal link mode is XFI, then setup iXFI internal link,
 		 * else setup KR now.
 		 */
-		if (!(phy->nw_mng_if_sel & IXGBE_NW_MNG_IF_SEL_INT_PHY_MODE)) {
-			phy->ops.setup_internal_link =
-					ixgbe_setup_internal_phy_t_x550em;
-		} else {
-			speed = IXGBE_LINK_SPEED_10GB_FULL |
-				IXGBE_LINK_SPEED_1GB_FULL;
-			ret_val = ixgbe_setup_kr_speed_x550em(hw, speed);
-		}
+		phy->ops.setup_internal_link =
+					      ixgbe_setup_internal_phy_t_x550em;
 
 		/* setup SW LPLU only for first revision */
-		if (!(IXGBE_FUSES0_REV1 & IXGBE_READ_REG(hw,
-							IXGBE_FUSES0_GROUP(0))))
+		if (hw->mac.type == ixgbe_mac_X550EM_x &&
+		    !(IXGBE_READ_REG(hw, IXGBE_FUSES0_GROUP(0)) &
+		      IXGBE_FUSES0_REV_MASK))
 			phy->ops.enter_lplu = ixgbe_enter_lplu_t_x550em;
 
 		phy->ops.handle_lasi = ixgbe_handle_lasi_ext_t_x550em;
@@ -2176,13 +2143,14 @@ mac_reset_top:
 	ctrl |= IXGBE_READ_REG(hw, IXGBE_CTRL);
 	IXGBE_WRITE_REG(hw, IXGBE_CTRL, ctrl);
 	IXGBE_WRITE_FLUSH(hw);
+	usleep_range(1000, 1200);
 
 	/* Poll for reset bit to self-clear meaning reset is complete */
 	for (i = 0; i < 10; i++) {
-		udelay(1);
 		ctrl = IXGBE_READ_REG(hw, IXGBE_CTRL);
 		if (!(ctrl & IXGBE_CTRL_RST_MASK))
 			break;
+		udelay(1);
 	}
 
 	if (ctrl & IXGBE_CTRL_RST_MASK) {
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/intel/ixgbevf/defines.h
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/intel/ixgbevf/defines.h
@@ -33,6 +33,11 @@
 #define IXGBE_DEV_ID_X550_VF		0x1565
 #define IXGBE_DEV_ID_X550EM_X_VF	0x15A8
 
+#define IXGBE_DEV_ID_82599_VF_HV	0x152E
+#define IXGBE_DEV_ID_X540_VF_HV		0x1530
+#define IXGBE_DEV_ID_X550_VF_HV		0x1564
+#define IXGBE_DEV_ID_X550EM_X_VF_HV	0x15A9
+
 #define IXGBE_VF_IRQ_CLEAR_MASK		7
 #define IXGBE_VF_MAX_TX_QUEUES		8
 #define IXGBE_VF_MAX_RX_QUEUES		8
@@ -74,7 +79,7 @@ typedef u32 ixgbe_link_speed;
 #define IXGBE_RXDCTL_RLPML_EN	0x00008000
 
 /* DCA Control */
-#define IXGBE_DCA_TXCTRL_TX_WB_RO_EN (1 << 11) /* Tx Desc writeback RO bit */
+#define IXGBE_DCA_TXCTRL_TX_WB_RO_EN BIT(11) /* Tx Desc writeback RO bit */
 
 /* PSRTYPE bit definitions */
 #define IXGBE_PSRTYPE_TCPHDR	0x00000010
@@ -296,16 +301,16 @@ struct ixgbe_adv_tx_context_desc {
 #define IXGBE_TXDCTL_SWFLSH		0x04000000 /* Tx Desc. wr-bk flushing */
 #define IXGBE_TXDCTL_WTHRESH_SHIFT	16	   /* shift to WTHRESH bits */
 
-#define IXGBE_DCA_RXCTRL_DESC_DCA_EN	(1 << 5)  /* Rx Desc enable */
-#define IXGBE_DCA_RXCTRL_HEAD_DCA_EN	(1 << 6)  /* Rx Desc header ena */
-#define IXGBE_DCA_RXCTRL_DATA_DCA_EN	(1 << 7)  /* Rx Desc payload ena */
-#define IXGBE_DCA_RXCTRL_DESC_RRO_EN	(1 << 9)  /* Rx rd Desc Relax Order */
-#define IXGBE_DCA_RXCTRL_DATA_WRO_EN	(1 << 13) /* Rx wr data Relax Order */
-#define IXGBE_DCA_RXCTRL_HEAD_WRO_EN	(1 << 15) /* Rx wr header RO */
-
-#define IXGBE_DCA_TXCTRL_DESC_DCA_EN	(1 << 5)  /* DCA Tx Desc enable */
-#define IXGBE_DCA_TXCTRL_DESC_RRO_EN	(1 << 9)  /* Tx rd Desc Relax Order */
-#define IXGBE_DCA_TXCTRL_DESC_WRO_EN	(1 << 11) /* Tx Desc writeback RO bit */
-#define IXGBE_DCA_TXCTRL_DATA_RRO_EN	(1 << 13) /* Tx rd data Relax Order */
+#define IXGBE_DCA_RXCTRL_DESC_DCA_EN	BIT(5)  /* Rx Desc enable */
+#define IXGBE_DCA_RXCTRL_HEAD_DCA_EN	BIT(6)  /* Rx Desc header ena */
+#define IXGBE_DCA_RXCTRL_DATA_DCA_EN	BIT(7)  /* Rx Desc payload ena */
+#define IXGBE_DCA_RXCTRL_DESC_RRO_EN	BIT(9)  /* Rx rd Desc Relax Order */
+#define IXGBE_DCA_RXCTRL_DATA_WRO_EN	BIT(13) /* Rx wr data Relax Order */
+#define IXGBE_DCA_RXCTRL_HEAD_WRO_EN	BIT(15) /* Rx wr header RO */
+
+#define IXGBE_DCA_TXCTRL_DESC_DCA_EN	BIT(5)  /* DCA Tx Desc enable */
+#define IXGBE_DCA_TXCTRL_DESC_RRO_EN	BIT(9)  /* Tx rd Desc Relax Order */
+#define IXGBE_DCA_TXCTRL_DESC_WRO_EN	BIT(11) /* Tx Desc writeback RO bit */
+#define IXGBE_DCA_TXCTRL_DATA_RRO_EN	BIT(13) /* Tx rd data Relax Order */
 
 #endif /* _IXGBEVF_DEFINES_H_ */
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/intel/ixgbevf/ethtool.c
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/intel/ixgbevf/ethtool.c
@@ -42,65 +42,54 @@
 
 #define IXGBE_ALL_RAR_ENTRIES 16
 
+enum {NETDEV_STATS, IXGBEVF_STATS};
+
 struct ixgbe_stats {
 	char stat_string[ETH_GSTRING_LEN];
-	struct {
-		int sizeof_stat;
-		int stat_offset;
-		int base_stat_offset;
-		int saved_reset_offset;
-	};
+	int type;
+	int sizeof_stat;
+	int stat_offset;
 };
 
-#define IXGBEVF_STAT(m, b, r) { \
-	.sizeof_stat = FIELD_SIZEOF(struct ixgbevf_adapter, m), \
-	.stat_offset = offsetof(struct ixgbevf_adapter, m), \
-	.base_stat_offset = offsetof(struct ixgbevf_adapter, b), \
-	.saved_reset_offset = offsetof(struct ixgbevf_adapter, r) \
-}
-
-#define IXGBEVF_ZSTAT(m) { \
-	.sizeof_stat = FIELD_SIZEOF(struct ixgbevf_adapter, m), \
-	.stat_offset = offsetof(struct ixgbevf_adapter, m), \
-	.base_stat_offset = -1, \
-	.saved_reset_offset = -1 \
-}
-
-static const struct ixgbe_stats ixgbe_gstrings_stats[] = {
-	{"rx_packets", IXGBEVF_STAT(stats.vfgprc, stats.base_vfgprc,
-				    stats.saved_reset_vfgprc)},
-	{"tx_packets", IXGBEVF_STAT(stats.vfgptc, stats.base_vfgptc,
-				    stats.saved_reset_vfgptc)},
-	{"rx_bytes", IXGBEVF_STAT(stats.vfgorc, stats.base_vfgorc,
-				  stats.saved_reset_vfgorc)},
-	{"tx_bytes", IXGBEVF_STAT(stats.vfgotc, stats.base_vfgotc,
-				  stats.saved_reset_vfgotc)},
-	{"tx_busy", IXGBEVF_ZSTAT(tx_busy)},
-	{"tx_restart_queue", IXGBEVF_ZSTAT(restart_queue)},
-	{"tx_timeout_count", IXGBEVF_ZSTAT(tx_timeout_count)},
-	{"multicast", IXGBEVF_STAT(stats.vfmprc, stats.base_vfmprc,
-				   stats.saved_reset_vfmprc)},
-	{"rx_csum_offload_errors", IXGBEVF_ZSTAT(hw_csum_rx_error)},
-#ifdef BP_EXTENDED_STATS
-	{"rx_bp_poll_yield", IXGBEVF_ZSTAT(bp_rx_yields)},
-	{"rx_bp_cleaned", IXGBEVF_ZSTAT(bp_rx_cleaned)},
-	{"rx_bp_misses", IXGBEVF_ZSTAT(bp_rx_missed)},
-	{"tx_bp_napi_yield", IXGBEVF_ZSTAT(bp_tx_yields)},
-	{"tx_bp_cleaned", IXGBEVF_ZSTAT(bp_tx_cleaned)},
-	{"tx_bp_misses", IXGBEVF_ZSTAT(bp_tx_missed)},
-#endif
+#define IXGBEVF_STAT(_name, _stat) { \
+	.stat_string = _name, \
+	.type = IXGBEVF_STATS, \
+	.sizeof_stat = FIELD_SIZEOF(struct ixgbevf_adapter, _stat), \
+	.stat_offset = offsetof(struct ixgbevf_adapter, _stat) \
+}
+
+#define IXGBEVF_NETDEV_STAT(_net_stat) { \
+	.stat_string = #_net_stat, \
+	.type = NETDEV_STATS, \
+	.sizeof_stat = FIELD_SIZEOF(struct net_device_stats, _net_stat), \
+	.stat_offset = offsetof(struct net_device_stats, _net_stat) \
+}
+
+static struct ixgbe_stats ixgbevf_gstrings_stats[] = {
+	IXGBEVF_NETDEV_STAT(rx_packets),
+	IXGBEVF_NETDEV_STAT(tx_packets),
+	IXGBEVF_NETDEV_STAT(rx_bytes),
+	IXGBEVF_NETDEV_STAT(tx_bytes),
+	IXGBEVF_STAT("tx_busy", tx_busy),
+	IXGBEVF_STAT("tx_restart_queue", restart_queue),
+	IXGBEVF_STAT("tx_timeout_count", tx_timeout_count),
+	IXGBEVF_NETDEV_STAT(multicast),
+	IXGBEVF_STAT("rx_csum_offload_errors", hw_csum_rx_error),
 };
 
-#define IXGBE_QUEUE_STATS_LEN 0
-#define IXGBE_GLOBAL_STATS_LEN	ARRAY_SIZE(ixgbe_gstrings_stats)
+#define IXGBEVF_QUEUE_STATS_LEN ( \
+	(((struct ixgbevf_adapter *)netdev_priv(netdev))->num_tx_queues + \
+	 ((struct ixgbevf_adapter *)netdev_priv(netdev))->num_rx_queues) * \
+	 (sizeof(struct ixgbe_stats) / sizeof(u64)))
+#define IXGBEVF_GLOBAL_STATS_LEN ARRAY_SIZE(ixgbevf_gstrings_stats)
 
-#define IXGBEVF_STATS_LEN (IXGBE_GLOBAL_STATS_LEN + IXGBE_QUEUE_STATS_LEN)
+#define IXGBEVF_STATS_LEN (IXGBEVF_GLOBAL_STATS_LEN + IXGBEVF_QUEUE_STATS_LEN)
 static const char ixgbe_gstrings_test[][ETH_GSTRING_LEN] = {
 	"Register test  (offline)",
 	"Link test   (on/offline)"
 };
 
-#define IXGBE_TEST_LEN (sizeof(ixgbe_gstrings_test) / ETH_GSTRING_LEN)
+#define IXGBEVF_TEST_LEN (sizeof(ixgbe_gstrings_test) / ETH_GSTRING_LEN)
 
 static int ixgbevf_get_settings(struct net_device *netdev,
 				struct ethtool_cmd *ecmd)
@@ -177,7 +166,8 @@ static void ixgbevf_get_regs(struct net_
 
 	memset(p, 0, regs_len);
 
-	regs->version = (1 << 24) | hw->revision_id << 16 | hw->device_id;
+	/* generate a number suitable for ethtool's register version */
+	regs->version = (1u << 24) | (hw->revision_id << 16) | hw->device_id;
 
 	/* General Registers */
 	regs_buff[0] = IXGBE_READ_REG(hw, IXGBE_VFCTRL);
@@ -392,13 +382,13 @@ clear_reset:
 	return err;
 }
 
-static int ixgbevf_get_sset_count(struct net_device *dev, int stringset)
+static int ixgbevf_get_sset_count(struct net_device *netdev, int stringset)
 {
 	switch (stringset) {
 	case ETH_SS_TEST:
-		return IXGBE_TEST_LEN;
+		return IXGBEVF_TEST_LEN;
 	case ETH_SS_STATS:
-		return IXGBE_GLOBAL_STATS_LEN;
+		return IXGBEVF_STATS_LEN;
 	default:
 		return -EINVAL;
 	}
@@ -408,70 +398,138 @@ static void ixgbevf_get_ethtool_stats(st
 				      struct ethtool_stats *stats, u64 *data)
 {
 	struct ixgbevf_adapter *adapter = netdev_priv(netdev);
-	char *base = (char *)adapter;
-	int i;
-#ifdef BP_EXTENDED_STATS
-	u64 rx_yields = 0, rx_cleaned = 0, rx_missed = 0,
-	    tx_yields = 0, tx_cleaned = 0, tx_missed = 0;
+	struct rtnl_link_stats64 temp;
+	const struct rtnl_link_stats64 *net_stats;
+	unsigned int start;
+	struct ixgbevf_ring *ring;
+	int i, j;
+	char *p;
 
-	for (i = 0; i < adapter->num_rx_queues; i++) {
-		rx_yields += adapter->rx_ring[i]->stats.yields;
-		rx_cleaned += adapter->rx_ring[i]->stats.cleaned;
-		rx_yields += adapter->rx_ring[i]->stats.yields;
-	}
+	ixgbevf_update_stats(adapter);
+	net_stats = dev_get_stats(netdev, &temp);
+	for (i = 0; i < IXGBEVF_GLOBAL_STATS_LEN; i++) {
+		switch (ixgbevf_gstrings_stats[i].type) {
+		case NETDEV_STATS:
+			p = (char *)net_stats +
+					ixgbevf_gstrings_stats[i].stat_offset;
+			break;
+		case IXGBEVF_STATS:
+			p = (char *)adapter +
+					ixgbevf_gstrings_stats[i].stat_offset;
+			break;
+		default:
+			data[i] = 0;
+			continue;
+		}
 
-	for (i = 0; i < adapter->num_tx_queues; i++) {
-		tx_yields += adapter->tx_ring[i]->stats.yields;
-		tx_cleaned += adapter->tx_ring[i]->stats.cleaned;
-		tx_yields += adapter->tx_ring[i]->stats.yields;
+		data[i] = (ixgbevf_gstrings_stats[i].sizeof_stat ==
+			   sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
 	}
 
-	adapter->bp_rx_yields = rx_yields;
-	adapter->bp_rx_cleaned = rx_cleaned;
-	adapter->bp_rx_missed = rx_missed;
+	/* populate Tx queue data */
+	for (j = 0; j < adapter->num_tx_queues; j++) {
+		ring = adapter->tx_ring[j];
+		if (!ring) {
+			data[i++] = 0;
+			data[i++] = 0;
+#ifdef BP_EXTENDED_STATS
+			data[i++] = 0;
+			data[i++] = 0;
+			data[i++] = 0;
+#endif
+			continue;
+		}
 
-	adapter->bp_tx_yields = tx_yields;
-	adapter->bp_tx_cleaned = tx_cleaned;
-	adapter->bp_tx_missed = tx_missed;
+		do {
+			start = u64_stats_fetch_begin_irq(&ring->syncp);
+			data[i]   = ring->stats.packets;
+			data[i + 1] = ring->stats.bytes;
+		} while (u64_stats_fetch_retry_irq(&ring->syncp, start));
+		i += 2;
+#ifdef BP_EXTENDED_STATS
+		data[i] = ring->stats.yields;
+		data[i + 1] = ring->stats.misses;
+		data[i + 2] = ring->stats.cleaned;
+		i += 3;
 #endif
+	}
 
-	ixgbevf_update_stats(adapter);
-	for (i = 0; i < IXGBE_GLOBAL_STATS_LEN; i++) {
-		char *p = base + ixgbe_gstrings_stats[i].stat_offset;
-		char *b = base + ixgbe_gstrings_stats[i].base_stat_offset;
-		char *r = base + ixgbe_gstrings_stats[i].saved_reset_offset;
-
-		if (ixgbe_gstrings_stats[i].sizeof_stat == sizeof(u64)) {
-			if (ixgbe_gstrings_stats[i].base_stat_offset >= 0)
-				data[i] = *(u64 *)p - *(u64 *)b + *(u64 *)r;
-			else
-				data[i] = *(u64 *)p;
-		} else {
-			if (ixgbe_gstrings_stats[i].base_stat_offset >= 0)
-				data[i] = *(u32 *)p - *(u32 *)b + *(u32 *)r;
-			else
-				data[i] = *(u32 *)p;
+	/* populate Rx queue data */
+	for (j = 0; j < adapter->num_rx_queues; j++) {
+		ring = adapter->rx_ring[j];
+		if (!ring) {
+			data[i++] = 0;
+			data[i++] = 0;
+#ifdef BP_EXTENDED_STATS
+			data[i++] = 0;
+			data[i++] = 0;
+			data[i++] = 0;
+#endif
+			continue;
 		}
+
+		do {
+			start = u64_stats_fetch_begin_irq(&ring->syncp);
+			data[i]   = ring->stats.packets;
+			data[i + 1] = ring->stats.bytes;
+		} while (u64_stats_fetch_retry_irq(&ring->syncp, start));
+		i += 2;
+#ifdef BP_EXTENDED_STATS
+		data[i] = ring->stats.yields;
+		data[i + 1] = ring->stats.misses;
+		data[i + 2] = ring->stats.cleaned;
+		i += 3;
+#endif
 	}
 }
 
 static void ixgbevf_get_strings(struct net_device *netdev, u32 stringset,
 				u8 *data)
 {
+	struct ixgbevf_adapter *adapter = netdev_priv(netdev);
 	char *p = (char *)data;
 	int i;
 
 	switch (stringset) {
 	case ETH_SS_TEST:
 		memcpy(data, *ixgbe_gstrings_test,
-		       IXGBE_TEST_LEN * ETH_GSTRING_LEN);
+		       IXGBEVF_TEST_LEN * ETH_GSTRING_LEN);
 		break;
 	case ETH_SS_STATS:
-		for (i = 0; i < IXGBE_GLOBAL_STATS_LEN; i++) {
-			memcpy(p, ixgbe_gstrings_stats[i].stat_string,
+		for (i = 0; i < IXGBEVF_GLOBAL_STATS_LEN; i++) {
+			memcpy(p, ixgbevf_gstrings_stats[i].stat_string,
 			       ETH_GSTRING_LEN);
 			p += ETH_GSTRING_LEN;
 		}
+
+		for (i = 0; i < adapter->num_tx_queues; i++) {
+			sprintf(p, "tx_queue_%u_packets", i);
+			p += ETH_GSTRING_LEN;
+			sprintf(p, "tx_queue_%u_bytes", i);
+			p += ETH_GSTRING_LEN;
+#ifdef BP_EXTENDED_STATS
+			sprintf(p, "tx_queue_%u_bp_napi_yield", i);
+			p += ETH_GSTRING_LEN;
+			sprintf(p, "tx_queue_%u_bp_misses", i);
+			p += ETH_GSTRING_LEN;
+			sprintf(p, "tx_queue_%u_bp_cleaned", i);
+			p += ETH_GSTRING_LEN;
+#endif /* BP_EXTENDED_STATS */
+		}
+		for (i = 0; i < adapter->num_rx_queues; i++) {
+			sprintf(p, "rx_queue_%u_packets", i);
+			p += ETH_GSTRING_LEN;
+			sprintf(p, "rx_queue_%u_bytes", i);
+			p += ETH_GSTRING_LEN;
+#ifdef BP_EXTENDED_STATS
+			sprintf(p, "rx_queue_%u_bp_poll_yield", i);
+			p += ETH_GSTRING_LEN;
+			sprintf(p, "rx_queue_%u_bp_misses", i);
+			p += ETH_GSTRING_LEN;
+			sprintf(p, "rx_queue_%u_bp_cleaned", i);
+			p += ETH_GSTRING_LEN;
+#endif /* BP_EXTENDED_STATS */
+		}
 		break;
 	}
 }
@@ -680,7 +738,7 @@ static void ixgbevf_diag_test(struct net
 
 		if (if_running)
 			/* indicate we're in test mode */
-			dev_close(netdev);
+			ixgbevf_close(netdev);
 		else
 			ixgbevf_reset(adapter);
 
@@ -692,7 +750,7 @@ static void ixgbevf_diag_test(struct net
 
 		clear_bit(__IXGBEVF_TESTING, &adapter->state);
 		if (if_running)
-			dev_open(netdev);
+			ixgbevf_open(netdev);
 	} else {
 		hw_dbg(&adapter->hw, "online testing starting\n");
 		/* Online tests */
@@ -774,7 +832,7 @@ static int ixgbevf_set_coalesce(struct n
 		adapter->tx_itr_setting = ec->tx_coalesce_usecs;
 
 	if (adapter->tx_itr_setting == 1)
-		tx_itr_param = IXGBE_10K_ITR;
+		tx_itr_param = IXGBE_12K_ITR;
 	else
 		tx_itr_param = adapter->tx_itr_setting;
 
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h
@@ -166,10 +166,10 @@ struct ixgbevf_ring {
 
 #define MAXIMUM_ETHERNET_VLAN_SIZE (VLAN_ETH_FRAME_LEN + ETH_FCS_LEN)
 
-#define IXGBE_TX_FLAGS_CSUM		(u32)(1)
-#define IXGBE_TX_FLAGS_VLAN		(u32)(1 << 1)
-#define IXGBE_TX_FLAGS_TSO		(u32)(1 << 2)
-#define IXGBE_TX_FLAGS_IPV4		(u32)(1 << 3)
+#define IXGBE_TX_FLAGS_CSUM		BIT(0)
+#define IXGBE_TX_FLAGS_VLAN		BIT(1)
+#define IXGBE_TX_FLAGS_TSO		BIT(2)
+#define IXGBE_TX_FLAGS_IPV4		BIT(3)
 #define IXGBE_TX_FLAGS_VLAN_MASK	0xffff0000
 #define IXGBE_TX_FLAGS_VLAN_PRIO_MASK	0x0000e000
 #define IXGBE_TX_FLAGS_VLAN_SHIFT	16
@@ -326,8 +326,7 @@ static inline bool ixgbevf_qv_disable(st
 #define IXGBE_MIN_RSC_ITR	24
 #define IXGBE_100K_ITR		40
 #define IXGBE_20K_ITR		200
-#define IXGBE_10K_ITR		400
-#define IXGBE_8K_ITR		500
+#define IXGBE_12K_ITR		336
 
 /* Helper macros to switch between ints/sec and what the register uses.
  * And yes, it's the same math going both ways.  The lowest value
@@ -404,13 +403,6 @@ struct ixgbevf_adapter {
 	u32 alloc_rx_page_failed;
 	u32 alloc_rx_buff_failed;
 
-	/* Some features need tri-state capability,
-	 * thus the additional *_CAPABLE flags.
-	 */
-	u32 flags;
-#define IXGBEVF_FLAG_RESET_REQUESTED		(u32)(1)
-#define IXGBEVF_FLAG_QUEUE_RESET_REQUESTED	(u32)(1 << 2)
-
 	struct msix_entry *msix_entries;
 
 	/* OS defined structs */
@@ -430,16 +422,6 @@ struct ixgbevf_adapter {
 	unsigned int tx_ring_count;
 	unsigned int rx_ring_count;
 
-#ifdef BP_EXTENDED_STATS
-	u64 bp_rx_yields;
-	u64 bp_rx_cleaned;
-	u64 bp_rx_missed;
-
-	u64 bp_tx_yields;
-	u64 bp_tx_cleaned;
-	u64 bp_tx_missed;
-#endif
-
 	u8 __iomem *io_addr; /* Mainly for iounmap use */
 	u32 link_speed;
 	bool link_up;
@@ -462,13 +444,19 @@ enum ixbgevf_state_t {
 	__IXGBEVF_REMOVING,
 	__IXGBEVF_SERVICE_SCHED,
 	__IXGBEVF_SERVICE_INITED,
+	__IXGBEVF_RESET_REQUESTED,
+	__IXGBEVF_QUEUE_RESET_REQUESTED,
 };
 
 enum ixgbevf_boards {
 	board_82599_vf,
+	board_82599_vf_hv,
 	board_X540_vf,
+	board_X540_vf_hv,
 	board_X550_vf,
+	board_X550_vf_hv,
 	board_X550EM_x_vf,
+	board_X550EM_x_vf_hv,
 };
 
 enum ixgbevf_xcast_modes {
@@ -483,10 +471,18 @@ extern const struct ixgbevf_info ixgbevf
 extern const struct ixgbevf_info ixgbevf_X550EM_x_vf_info;
 extern const struct ixgbe_mbx_operations ixgbevf_mbx_ops;
 
+extern const struct ixgbevf_info ixgbevf_82599_vf_hv_info;
+extern const struct ixgbevf_info ixgbevf_X540_vf_hv_info;
+extern const struct ixgbevf_info ixgbevf_X550_vf_hv_info;
+extern const struct ixgbevf_info ixgbevf_X550EM_x_vf_hv_info;
+extern const struct ixgbe_mbx_operations ixgbevf_hv_mbx_ops;
+
 /* needed by ethtool.c */
 extern const char ixgbevf_driver_name[];
 extern const char ixgbevf_driver_version[];
 
+int ixgbevf_open(struct net_device *netdev);
+int ixgbevf_close(struct net_device *netdev);
 void ixgbevf_up(struct ixgbevf_adapter *adapter);
 void ixgbevf_down(struct ixgbevf_adapter *adapter);
 void ixgbevf_reinit_locked(struct ixgbevf_adapter *adapter);
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
@@ -59,13 +59,17 @@ static const char ixgbevf_driver_string[
 #define DRV_VERSION "2.12.1-k"
 const char ixgbevf_driver_version[] = DRV_VERSION;
 static char ixgbevf_copyright[] =
-	"Copyright (c) 2009 - 2012 Intel Corporation.";
+	"Copyright (c) 2009 - 2015 Intel Corporation.";
 
 static const struct ixgbevf_info *ixgbevf_info_tbl[] = {
-	[board_82599_vf] = &ixgbevf_82599_vf_info,
-	[board_X540_vf]  = &ixgbevf_X540_vf_info,
-	[board_X550_vf]  = &ixgbevf_X550_vf_info,
-	[board_X550EM_x_vf] = &ixgbevf_X550EM_x_vf_info,
+	[board_82599_vf]	= &ixgbevf_82599_vf_info,
+	[board_82599_vf_hv]	= &ixgbevf_82599_vf_hv_info,
+	[board_X540_vf]		= &ixgbevf_X540_vf_info,
+	[board_X540_vf_hv]	= &ixgbevf_X540_vf_hv_info,
+	[board_X550_vf]		= &ixgbevf_X550_vf_info,
+	[board_X550_vf_hv]	= &ixgbevf_X550_vf_hv_info,
+	[board_X550EM_x_vf]	= &ixgbevf_X550EM_x_vf_info,
+	[board_X550EM_x_vf_hv]	= &ixgbevf_X550EM_x_vf_hv_info,
 };
 
 /* ixgbevf_pci_tbl - PCI Device ID Table
@@ -78,9 +82,13 @@ static const struct ixgbevf_info *ixgbev
  */
 static const struct pci_device_id ixgbevf_pci_tbl[] = {
 	{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_VF), board_82599_vf },
+	{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_VF_HV), board_82599_vf_hv },
 	{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_X540_VF), board_X540_vf },
+	{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_X540_VF_HV), board_X540_vf_hv },
 	{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_X550_VF), board_X550_vf },
+	{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_X550_VF_HV), board_X550_vf_hv },
 	{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_X550EM_X_VF), board_X550EM_x_vf },
+	{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_X550EM_X_VF_HV), board_X550EM_x_vf_hv},
 	/* required last entry */
 	{0, }
 };
@@ -96,12 +104,14 @@ static int debug = -1;
 module_param(debug, int, 0);
 MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)");
 
+static struct workqueue_struct *ixgbevf_wq;
+
 static void ixgbevf_service_event_schedule(struct ixgbevf_adapter *adapter)
 {
 	if (!test_bit(__IXGBEVF_DOWN, &adapter->state) &&
 	    !test_bit(__IXGBEVF_REMOVING, &adapter->state) &&
 	    !test_and_set_bit(__IXGBEVF_SERVICE_SCHED, &adapter->state))
-		schedule_work(&adapter->service_task);
+		queue_work(ixgbevf_wq, &adapter->service_task);
 }
 
 static void ixgbevf_service_event_complete(struct ixgbevf_adapter *adapter)
@@ -266,7 +276,7 @@ static void ixgbevf_tx_timeout_reset(str
 {
 	/* Do the reset outside of interrupt context */
 	if (!test_bit(__IXGBEVF_DOWN, &adapter->state)) {
-		adapter->flags |= IXGBEVF_FLAG_RESET_REQUESTED;
+		set_bit(__IXGBEVF_RESET_REQUESTED, &adapter->state);
 		ixgbevf_service_event_schedule(adapter);
 	}
 }
@@ -286,9 +296,10 @@ static void ixgbevf_tx_timeout(struct ne
  * ixgbevf_clean_tx_irq - Reclaim resources after transmit completes
  * @q_vector: board private structure
  * @tx_ring: tx ring to clean
+ * @napi_budget: Used to determine if we are in netpoll
  **/
 static bool ixgbevf_clean_tx_irq(struct ixgbevf_q_vector *q_vector,
-				 struct ixgbevf_ring *tx_ring)
+				 struct ixgbevf_ring *tx_ring, int napi_budget)
 {
 	struct ixgbevf_adapter *adapter = q_vector->adapter;
 	struct ixgbevf_tx_buffer *tx_buffer;
@@ -326,7 +337,7 @@ static bool ixgbevf_clean_tx_irq(struct
 		total_packets += tx_buffer->gso_segs;
 
 		/* free the skb */
-		dev_kfree_skb_any(tx_buffer->skb);
+		napi_consume_skb(tx_buffer->skb, napi_budget);
 
 		/* unmap skb header data */
 		dma_unmap_single(tx_ring->dev,
@@ -1011,9 +1022,13 @@ static int ixgbevf_poll(struct napi_stru
 	int per_ring_budget, work_done = 0;
 	bool clean_complete = true;
 
-	ixgbevf_for_each_ring(ring, q_vector->tx)
-		clean_complete &= ixgbevf_clean_tx_irq(q_vector, ring);
+	ixgbevf_for_each_ring(ring, q_vector->tx) {
+		if (!ixgbevf_clean_tx_irq(q_vector, ring, budget))
+			clean_complete = false;
+	}
 
+	if (budget <= 0)
+		return budget;
 #ifdef CONFIG_NET_RX_BUSY_POLL
 	if (!ixgbevf_qv_lock_napi(q_vector))
 		return budget;
@@ -1031,7 +1046,8 @@ static int ixgbevf_poll(struct napi_stru
 		int cleaned = ixgbevf_clean_rx_irq(q_vector, ring,
 						   per_ring_budget);
 		work_done += cleaned;
-		clean_complete &= (cleaned < per_ring_budget);
+		if (cleaned >= per_ring_budget)
+			clean_complete = false;
 	}
 
 #ifdef CONFIG_NET_RX_BUSY_POLL
@@ -1043,12 +1059,12 @@ static int ixgbevf_poll(struct napi_stru
 		return budget;
 	/* all work done, exit the polling mode */
 	napi_complete_done(napi, work_done);
-	if (adapter->rx_itr_setting & 1)
+	if (adapter->rx_itr_setting == 1)
 		ixgbevf_set_itr(q_vector);
 	if (!test_bit(__IXGBEVF_DOWN, &adapter->state) &&
 	    !test_bit(__IXGBEVF_REMOVING, &adapter->state))
 		ixgbevf_irq_enable_queues(adapter,
-					  1 << q_vector->v_idx);
+					  BIT(q_vector->v_idx));
 
 	return 0;
 }
@@ -1138,7 +1154,7 @@ static void ixgbevf_configure_msix(struc
 		if (q_vector->tx.ring && !q_vector->rx.ring) {
 			/* Tx only vector */
 			if (adapter->tx_itr_setting == 1)
-				q_vector->itr = IXGBE_10K_ITR;
+				q_vector->itr = IXGBE_12K_ITR;
 			else
 				q_vector->itr = adapter->tx_itr_setting;
 		} else {
@@ -1150,14 +1166,14 @@ static void ixgbevf_configure_msix(struc
 		}
 
 		/* add q_vector eims value to global eims_enable_mask */
-		adapter->eims_enable_mask |= 1 << v_idx;
+		adapter->eims_enable_mask |= BIT(v_idx);
 
 		ixgbevf_write_eitr(q_vector);
 	}
 
 	ixgbevf_set_ivar(adapter, -1, 1, v_idx);
 	/* setup eims_other and add value to global eims_enable_mask */
-	adapter->eims_other = 1 << v_idx;
+	adapter->eims_other = BIT(v_idx);
 	adapter->eims_enable_mask |= adapter->eims_other;
 }
 
@@ -1196,7 +1212,7 @@ static void ixgbevf_update_itr(struct ix
 	/* simple throttle rate management
 	 *    0-20MB/s lowest (100000 ints/s)
 	 *   20-100MB/s low   (20000 ints/s)
-	 *  100-1249MB/s bulk (8000 ints/s)
+	 *  100-1249MB/s bulk (12000 ints/s)
 	 */
 	/* what was last interrupt timeslice? */
 	timepassed_us = q_vector->itr >> 2;
@@ -1246,8 +1262,9 @@ static void ixgbevf_set_itr(struct ixgbe
 		new_itr = IXGBE_20K_ITR;
 		break;
 	case bulk_latency:
+		new_itr = IXGBE_12K_ITR;
+		break;
 	default:
-		new_itr = IXGBE_8K_ITR;
 		break;
 	}
 
@@ -1288,7 +1305,7 @@ static irqreturn_t ixgbevf_msix_clean_ri
 
 	/* EIAM disabled interrupts (on this vector) for us */
 	if (q_vector->rx.ring || q_vector->tx.ring)
-		napi_schedule(&q_vector->napi);
+		napi_schedule_irqoff(&q_vector->napi);
 
 	return IRQ_HANDLED;
 }
@@ -1332,7 +1349,6 @@ static int ixgbevf_map_rings_to_vectors(
 	int txr_remaining = adapter->num_tx_queues;
 	int i, j;
 	int rqpv, tqpv;
-	int err = 0;
 
 	q_vectors = adapter->num_msix_vectors - NON_Q_VECTORS;
 
@@ -1345,7 +1361,7 @@ static int ixgbevf_map_rings_to_vectors(
 
 		for (; txr_idx < txr_remaining; v_start++, txr_idx++)
 			map_vector_to_txq(adapter, v_start, txr_idx);
-		goto out;
+		return 0;
 	}
 
 	/* If we don't have enough vectors for a 1-to-1
@@ -1370,8 +1386,7 @@ static int ixgbevf_map_rings_to_vectors(
 		}
 	}
 
-out:
-	return err;
+	return 0;
 }
 
 /**
@@ -1469,9 +1484,7 @@ static inline void ixgbevf_reset_q_vecto
  **/
 static int ixgbevf_request_irq(struct ixgbevf_adapter *adapter)
 {
-	int err = 0;
-
-	err = ixgbevf_request_msix_irqs(adapter);
+	int err = ixgbevf_request_msix_irqs(adapter);
 
 	if (err)
 		hw_dbg(&adapter->hw, "request_irq failed, Error %d\n", err);
@@ -1584,8 +1597,8 @@ static void ixgbevf_configure_tx_ring(st
 	txdctl |= (8 << 16);    /* WTHRESH = 8 */
 
 	/* Setting PTHRESH to 32 both improves performance */
-	txdctl |= (1 << 8) |    /* HTHRESH = 1 */
-		  32;          /* PTHRESH = 32 */
+	txdctl |= (1u << 8) |    /* HTHRESH = 1 */
+		   32;           /* PTHRESH = 32 */
 
 	clear_bit(__IXGBEVF_HANG_CHECK_ARMED, &ring->state);
 
@@ -1641,7 +1654,7 @@ static void ixgbevf_setup_psrtype(struct
 		      IXGBE_PSRTYPE_L2HDR;
 
 	if (adapter->num_rx_queues > 1)
-		psrtype |= 1 << 29;
+		psrtype |= BIT(29);
 
 	IXGBE_WRITE_REG(hw, IXGBE_VFPSRTYPE, psrtype);
 }
@@ -1747,9 +1760,15 @@ static void ixgbevf_configure_rx_ring(st
 	IXGBE_WRITE_REG(hw, IXGBE_VFRDLEN(reg_idx),
 			ring->count * sizeof(union ixgbe_adv_rx_desc));
 
+#ifndef CONFIG_SPARC
 	/* enable relaxed ordering */
 	IXGBE_WRITE_REG(hw, IXGBE_VFDCA_RXCTRL(reg_idx),
 			IXGBE_DCA_RXCTRL_DESC_RRO_EN);
+#else
+	IXGBE_WRITE_REG(hw, IXGBE_VFDCA_RXCTRL(reg_idx),
+			IXGBE_DCA_RXCTRL_DESC_RRO_EN |
+			IXGBE_DCA_RXCTRL_DATA_WRO_EN);
+#endif
 
 	/* reset head and tail pointers */
 	IXGBE_WRITE_REG(hw, IXGBE_VFRDH(reg_idx), 0);
@@ -1790,7 +1809,7 @@ static void ixgbevf_configure_rx(struct
 		ixgbevf_setup_vfmrqc(adapter);
 
 	/* notify the PF of our intent to use this size of frame */
-	ixgbevf_rlpml_set_vf(hw, netdev->mtu + ETH_HLEN + ETH_FCS_LEN);
+	hw->mac.ops.set_rlpml(hw, netdev->mtu + ETH_HLEN + ETH_FCS_LEN);
 
 	/* Setup the HW Rx Head and Tail Descriptor Pointers and
 	 * the Base and Length of the Rx Descriptor Ring
@@ -1830,7 +1849,7 @@ static int ixgbevf_vlan_rx_kill_vid(stru
 {
 	struct ixgbevf_adapter *adapter = netdev_priv(netdev);
 	struct ixgbe_hw *hw = &adapter->hw;
-	int err = -EOPNOTSUPP;
+	int err;
 
 	spin_lock_bh(&adapter->mbx_lock);
 
@@ -1983,7 +2002,7 @@ static int ixgbevf_configure_dcb(struct
 		hw->mbx.timeout = 0;
 
 		/* wait for watchdog to come around and bail us out */
-		adapter->flags |= IXGBEVF_FLAG_QUEUE_RESET_REQUESTED;
+		set_bit(__IXGBEVF_QUEUE_RESET_REQUESTED, &adapter->state);
 	}
 
 	return 0;
@@ -2046,12 +2065,12 @@ static void ixgbevf_negotiate_api(struct
 		      ixgbe_mbox_api_11,
 		      ixgbe_mbox_api_10,
 		      ixgbe_mbox_api_unknown };
-	int err = 0, idx = 0;
+	int err, idx = 0;
 
 	spin_lock_bh(&adapter->mbx_lock);
 
 	while (api[idx] != ixgbe_mbox_api_unknown) {
-		err = ixgbevf_negotiate_api_version(hw, api[idx]);
+		err = hw->mac.ops.negotiate_api_version(hw, api[idx]);
 		if (!err)
 			break;
 		idx++;
@@ -2260,10 +2279,8 @@ void ixgbevf_reset(struct ixgbevf_adapte
 	}
 
 	if (is_valid_ether_addr(adapter->hw.mac.addr)) {
-		memcpy(netdev->dev_addr, adapter->hw.mac.addr,
-		       netdev->addr_len);
-		memcpy(netdev->perm_addr, adapter->hw.mac.addr,
-		       netdev->addr_len);
+		ether_addr_copy(netdev->dev_addr, adapter->hw.mac.addr);
+		ether_addr_copy(netdev->perm_addr, adapter->hw.mac.addr);
 	}
 
 	adapter->last_reset = jiffies;
@@ -2421,7 +2438,7 @@ err_allocation:
 static int ixgbevf_set_interrupt_capability(struct ixgbevf_adapter *adapter)
 {
 	struct net_device *netdev = adapter->netdev;
-	int err = 0;
+	int err;
 	int vector, v_budget;
 
 	/* It's easy to be greedy for MSI-X vectors, but it really
@@ -2439,26 +2456,21 @@ static int ixgbevf_set_interrupt_capabil
 	 */
 	adapter->msix_entries = kcalloc(v_budget,
 					sizeof(struct msix_entry), GFP_KERNEL);
-	if (!adapter->msix_entries) {
-		err = -ENOMEM;
-		goto out;
-	}
+	if (!adapter->msix_entries)
+		return -ENOMEM;
 
 	for (vector = 0; vector < v_budget; vector++)
 		adapter->msix_entries[vector].entry = vector;
 
 	err = ixgbevf_acquire_msix_vectors(adapter, v_budget);
 	if (err)
-		goto out;
+		return err;
 
 	err = netif_set_real_num_tx_queues(netdev, adapter->num_tx_queues);
 	if (err)
-		goto out;
-
-	err = netif_set_real_num_rx_queues(netdev, adapter->num_rx_queues);
+		return err;
 
-out:
-	return err;
+	return netif_set_real_num_rx_queues(netdev, adapter->num_rx_queues);
 }
 
 /**
@@ -2662,13 +2674,14 @@ static int ixgbevf_sw_init(struct ixgbev
 		else if (is_zero_ether_addr(adapter->hw.mac.addr))
 			dev_info(&pdev->dev,
 				 "MAC address not assigned by administrator.\n");
-		memcpy(netdev->dev_addr, hw->mac.addr, netdev->addr_len);
+		ether_addr_copy(netdev->dev_addr, hw->mac.addr);
 	}
 
 	if (!is_valid_ether_addr(netdev->dev_addr)) {
 		dev_info(&pdev->dev, "Assigning random MAC address\n");
 		eth_hw_addr_random(netdev);
-		memcpy(hw->mac.addr, netdev->dev_addr, netdev->addr_len);
+		ether_addr_copy(hw->mac.addr, netdev->dev_addr);
+		ether_addr_copy(hw->mac.perm_addr, netdev->dev_addr);
 	}
 
 	/* Enable dynamic interrupt throttling rates */
@@ -2757,11 +2770,9 @@ static void ixgbevf_service_timer(unsign
 
 static void ixgbevf_reset_subtask(struct ixgbevf_adapter *adapter)
 {
-	if (!(adapter->flags & IXGBEVF_FLAG_RESET_REQUESTED))
+	if (!test_and_clear_bit(__IXGBEVF_RESET_REQUESTED, &adapter->state))
 		return;
 
-	adapter->flags &= ~IXGBEVF_FLAG_RESET_REQUESTED;
-
 	/* If we're already down or resetting, just bail */
 	if (test_bit(__IXGBEVF_DOWN, &adapter->state) ||
 	    test_bit(__IXGBEVF_RESETTING, &adapter->state))
@@ -2803,7 +2814,7 @@ static void ixgbevf_check_hang_subtask(s
 		struct ixgbevf_q_vector *qv = adapter->q_vector[i];
 
 		if (qv->rx.ring || qv->tx.ring)
-			eics |= 1 << i;
+			eics |= BIT(i);
 	}
 
 	/* Cause software interrupt to ensure rings are cleaned */
@@ -2829,7 +2840,7 @@ static void ixgbevf_watchdog_update_link
 
 	/* if check for link returns error we will need to reset */
 	if (err && time_after(jiffies, adapter->last_reset + (10 * HZ))) {
-		adapter->flags |= IXGBEVF_FLAG_RESET_REQUESTED;
+		set_bit(__IXGBEVF_RESET_REQUESTED, &adapter->state);
 		link_up = false;
 	}
 
@@ -3130,7 +3141,7 @@ static void ixgbevf_free_all_rx_resource
  * handler is registered with the OS, the watchdog timer is started,
  * and the stack is notified that the interface is ready.
  **/
-static int ixgbevf_open(struct net_device *netdev)
+int ixgbevf_open(struct net_device *netdev)
 {
 	struct ixgbevf_adapter *adapter = netdev_priv(netdev);
 	struct ixgbe_hw *hw = &adapter->hw;
@@ -3213,7 +3224,7 @@ err_setup_reset:
  * needs to be disabled.  A global MAC reset is issued to stop the
  * hardware, and all transmit and receive resources are freed.
  **/
-static int ixgbevf_close(struct net_device *netdev)
+int ixgbevf_close(struct net_device *netdev)
 {
 	struct ixgbevf_adapter *adapter = netdev_priv(netdev);
 
@@ -3230,11 +3241,10 @@ static void ixgbevf_queue_reset_subtask(
 {
 	struct net_device *dev = adapter->netdev;
 
-	if (!(adapter->flags & IXGBEVF_FLAG_QUEUE_RESET_REQUESTED))
+	if (!test_and_clear_bit(__IXGBEVF_QUEUE_RESET_REQUESTED,
+				&adapter->state))
 		return;
 
-	adapter->flags &= ~IXGBEVF_FLAG_QUEUE_RESET_REQUESTED;
-
 	/* if interface is down do nothing */
 	if (test_bit(__IXGBEVF_DOWN, &adapter->state) ||
 	    test_bit(__IXGBEVF_RESETTING, &adapter->state))
@@ -3332,7 +3342,7 @@ static int ixgbevf_tso(struct ixgbevf_ri
 	/* mss_l4len_id: use 1 as index for TSO */
 	mss_l4len_idx = l4len << IXGBE_ADVTXD_L4LEN_SHIFT;
 	mss_l4len_idx |= skb_shinfo(skb)->gso_size << IXGBE_ADVTXD_MSS_SHIFT;
-	mss_l4len_idx |= 1 << IXGBE_ADVTXD_IDX_SHIFT;
+	mss_l4len_idx |= (1u << IXGBE_ADVTXD_IDX_SHIFT);
 
 	/* vlan_macip_lens: HEADLEN, MACLEN, VLAN tag */
 	vlan_macip_lens = skb_network_header_len(skb);
@@ -3345,70 +3355,55 @@ static int ixgbevf_tso(struct ixgbevf_ri
 	return 1;
 }
 
+static inline bool ixgbevf_ipv6_csum_is_sctp(struct sk_buff *skb)
+{
+	unsigned int offset = 0;
+
+	ipv6_find_hdr(skb, &offset, IPPROTO_SCTP, NULL, NULL);
+
+	return offset == skb_checksum_start_offset(skb);
+}
+
 static void ixgbevf_tx_csum(struct ixgbevf_ring *tx_ring,
 			    struct ixgbevf_tx_buffer *first)
 {
 	struct sk_buff *skb = first->skb;
 	u32 vlan_macip_lens = 0;
-	u32 mss_l4len_idx = 0;
 	u32 type_tucmd = 0;
 
-	if (skb->ip_summed == CHECKSUM_PARTIAL) {
-		u8 l4_hdr = 0;
-
-		switch (first->protocol) {
-		case htons(ETH_P_IP):
-			vlan_macip_lens |= skb_network_header_len(skb);
-			type_tucmd |= IXGBE_ADVTXD_TUCMD_IPV4;
-			l4_hdr = ip_hdr(skb)->protocol;
-			break;
-		case htons(ETH_P_IPV6):
-			vlan_macip_lens |= skb_network_header_len(skb);
-			l4_hdr = ipv6_hdr(skb)->nexthdr;
-			break;
-		default:
-			if (unlikely(net_ratelimit())) {
-				dev_warn(tx_ring->dev,
-					 "partial checksum but proto=%x!\n",
-					 first->protocol);
-			}
-			break;
-		}
+	if (skb->ip_summed != CHECKSUM_PARTIAL)
+		goto no_csum;
 
-		switch (l4_hdr) {
-		case IPPROTO_TCP:
-			type_tucmd |= IXGBE_ADVTXD_TUCMD_L4T_TCP;
-			mss_l4len_idx = tcp_hdrlen(skb) <<
-					IXGBE_ADVTXD_L4LEN_SHIFT;
-			break;
-		case IPPROTO_SCTP:
-			type_tucmd |= IXGBE_ADVTXD_TUCMD_L4T_SCTP;
-			mss_l4len_idx = sizeof(struct sctphdr) <<
-					IXGBE_ADVTXD_L4LEN_SHIFT;
-			break;
-		case IPPROTO_UDP:
-			mss_l4len_idx = sizeof(struct udphdr) <<
-					IXGBE_ADVTXD_L4LEN_SHIFT;
-			break;
-		default:
-			if (unlikely(net_ratelimit())) {
-				dev_warn(tx_ring->dev,
-					 "partial checksum but l4 proto=%x!\n",
-					 l4_hdr);
-			}
+	switch (skb->csum_offset) {
+	case offsetof(struct tcphdr, check):
+		type_tucmd = IXGBE_ADVTXD_TUCMD_L4T_TCP;
+		/* fall through */
+	case offsetof(struct udphdr, check):
+		break;
+	case offsetof(struct sctphdr, checksum):
+		/* validate that this is actually an SCTP request */
+		if (((first->protocol == htons(ETH_P_IP)) &&
+		     (ip_hdr(skb)->protocol == IPPROTO_SCTP)) ||
+		    ((first->protocol == htons(ETH_P_IPV6)) &&
+		     ixgbevf_ipv6_csum_is_sctp(skb))) {
+			type_tucmd = IXGBE_ADVTXD_TUCMD_L4T_SCTP;
 			break;
 		}
-
-		/* update TX checksum flag */
-		first->tx_flags |= IXGBE_TX_FLAGS_CSUM;
+		/* fall through */
+	default:
+		skb_checksum_help(skb);
+		goto no_csum;
 	}
-
+	/* update TX checksum flag */
+	first->tx_flags |= IXGBE_TX_FLAGS_CSUM;
+	vlan_macip_lens = skb_checksum_start_offset(skb) -
+			  skb_network_offset(skb);
+no_csum:
 	/* vlan_macip_lens: MACLEN, VLAN tag */
 	vlan_macip_lens |= skb_network_offset(skb) << IXGBE_ADVTXD_MACLEN_SHIFT;
 	vlan_macip_lens |= first->tx_flags & IXGBE_TX_FLAGS_VLAN_MASK;
 
-	ixgbevf_tx_ctxtdesc(tx_ring, vlan_macip_lens,
-			    type_tucmd, mss_l4len_idx);
+	ixgbevf_tx_ctxtdesc(tx_ring, vlan_macip_lens, type_tucmd, 0);
 }
 
 static __le32 ixgbevf_tx_cmd_type(u32 tx_flags)
@@ -3444,7 +3439,7 @@ static void ixgbevf_tx_olinfo_status(uni
 
 	/* use index 1 context for TSO/FSO/FCOE */
 	if (tx_flags & IXGBE_TX_FLAGS_TSO)
-		olinfo_status |= cpu_to_le32(1 << IXGBE_ADVTXD_IDX_SHIFT);
+		olinfo_status |= cpu_to_le32(1u << IXGBE_ADVTXD_IDX_SHIFT);
 
 	/* Check Context must be set if Tx switch is enabled, which it
 	 * always is for case where virtual functions are running
@@ -3694,19 +3689,23 @@ static int ixgbevf_set_mac(struct net_de
 	struct ixgbevf_adapter *adapter = netdev_priv(netdev);
 	struct ixgbe_hw *hw = &adapter->hw;
 	struct sockaddr *addr = p;
+	int err;
 
 	if (!is_valid_ether_addr(addr->sa_data))
 		return -EADDRNOTAVAIL;
 
-	memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
-	memcpy(hw->mac.addr, addr->sa_data, netdev->addr_len);
-
 	spin_lock_bh(&adapter->mbx_lock);
 
-	hw->mac.ops.set_rar(hw, 0, hw->mac.addr, 0);
+	err = hw->mac.ops.set_rar(hw, 0, addr->sa_data, 0);
 
 	spin_unlock_bh(&adapter->mbx_lock);
 
+	if (err)
+		return -EPERM;
+
+	ether_addr_copy(hw->mac.addr, addr->sa_data);
+	ether_addr_copy(netdev->dev_addr, addr->sa_data);
+
 	return 0;
 }
 
@@ -3745,7 +3744,7 @@ static int ixgbevf_change_mtu(struct net
 	netdev->mtu = new_mtu;
 
 	/* notify the PF of our intent to use this size of frame */
-	ixgbevf_rlpml_set_vf(hw, max_frame);
+	hw->mac.ops.set_rlpml(hw, max_frame);
 
 	return 0;
 }
@@ -4011,22 +4010,25 @@ static int ixgbevf_probe(struct pci_dev
 	}
 
 	netdev->hw_features = NETIF_F_SG |
-			      NETIF_F_IP_CSUM |
-			      NETIF_F_IPV6_CSUM |
 			      NETIF_F_TSO |
 			      NETIF_F_TSO6 |
-			      NETIF_F_RXCSUM;
+			      NETIF_F_RXCSUM |
+			      NETIF_F_HW_CSUM |
+			      NETIF_F_SCTP_CRC;
 
 	netdev->features = netdev->hw_features |
 			   NETIF_F_HW_VLAN_CTAG_TX |
 			   NETIF_F_HW_VLAN_CTAG_RX |
 			   NETIF_F_HW_VLAN_CTAG_FILTER;
 
-	netdev->vlan_features |= NETIF_F_TSO |
+	netdev->vlan_features |= NETIF_F_SG |
+				 NETIF_F_TSO |
 				 NETIF_F_TSO6 |
-				 NETIF_F_IP_CSUM |
-				 NETIF_F_IPV6_CSUM |
-				 NETIF_F_SG;
+				 NETIF_F_HW_CSUM |
+				 NETIF_F_SCTP_CRC;
+
+	netdev->mpls_features |= NETIF_F_HW_CSUM;
+	netdev->hw_enc_features |= NETIF_F_HW_CSUM;
 
 	if (pci_using_dac)
 		netdev->features |= NETIF_F_HIGHDMA;
@@ -4248,15 +4250,17 @@ static struct pci_driver ixgbevf_driver
  **/
 static int __init ixgbevf_init_module(void)
 {
-	int ret;
-
 	pr_info("%s - version %s\n", ixgbevf_driver_string,
 		ixgbevf_driver_version);
 
 	pr_info("%s\n", ixgbevf_copyright);
+	ixgbevf_wq = create_singlethread_workqueue(ixgbevf_driver_name);
+	if (!ixgbevf_wq) {
+		pr_err("%s: Failed to create workqueue\n", ixgbevf_driver_name);
+		return -ENOMEM;
+	}
 
-	ret = pci_register_driver(&ixgbevf_driver);
-	return ret;
+	return pci_register_driver(&ixgbevf_driver);
 }
 
 module_init(ixgbevf_init_module);
@@ -4270,6 +4274,10 @@ module_init(ixgbevf_init_module);
 static void __exit ixgbevf_exit_module(void)
 {
 	pci_unregister_driver(&ixgbevf_driver);
+	if (ixgbevf_wq) {
+		destroy_workqueue(ixgbevf_wq);
+		ixgbevf_wq = NULL;
+	}
 }
 
 #ifdef DEBUG
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/intel/ixgbevf/mbx.c
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/intel/ixgbevf/mbx.c
@@ -346,3 +346,14 @@ const struct ixgbe_mbx_operations ixgbev
 	.check_for_rst	= ixgbevf_check_for_rst_vf,
 };
 
+/* Mailbox operations when running on Hyper-V.
+ * On Hyper-V, PF/VF communication is not through the
+ * hardware mailbox; this communication is through
+ * a software mediated path.
+ * Most mail box operations are noop while running on
+ * Hyper-V.
+ */
+const struct ixgbe_mbx_operations ixgbevf_hv_mbx_ops = {
+	.init_params	= ixgbevf_init_mbx_params_vf,
+	.check_for_rst	= ixgbevf_check_for_rst_vf,
+};
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/intel/ixgbevf/vf.c
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/intel/ixgbevf/vf.c
@@ -27,6 +27,12 @@
 #include "vf.h"
 #include "ixgbevf.h"
 
+/* On Hyper-V, to reset, we need to read from this offset
+ * from the PCI config space. This is the mechanism used on
+ * Hyper-V to support PF/VF communication.
+ */
+#define IXGBE_HV_RESET_OFFSET           0x201
+
 /**
  *  ixgbevf_start_hw_vf - Prepare hardware for Tx/Rx
  *  @hw: pointer to hardware structure
@@ -117,13 +123,36 @@ static s32 ixgbevf_reset_hw_vf(struct ix
 	    msgbuf[0] != (IXGBE_VF_RESET | IXGBE_VT_MSGTYPE_NACK))
 		return IXGBE_ERR_INVALID_MAC_ADDR;
 
-	ether_addr_copy(hw->mac.perm_addr, addr);
+	if (msgbuf[0] == (IXGBE_VF_RESET | IXGBE_VT_MSGTYPE_ACK))
+		ether_addr_copy(hw->mac.perm_addr, addr);
+
 	hw->mac.mc_filter_type = msgbuf[IXGBE_VF_MC_TYPE_WORD];
 
 	return 0;
 }
 
 /**
+ * Hyper-V variant; the VF/PF communication is through the PCI
+ * config space.
+ */
+static s32 ixgbevf_hv_reset_hw_vf(struct ixgbe_hw *hw)
+{
+#if IS_ENABLED(CONFIG_PCI_MMCONFIG)
+	struct ixgbevf_adapter *adapter = hw->back;
+	int i;
+
+	for (i = 0; i < 6; i++)
+		pci_read_config_byte(adapter->pdev,
+				     (i + IXGBE_HV_RESET_OFFSET),
+				     &hw->mac.perm_addr[i]);
+	return 0;
+#else
+	pr_err("PCI_MMCONFIG needs to be enabled for Hyper-V\n");
+	return -EOPNOTSUPP;
+#endif
+}
+
+/**
  *  ixgbevf_stop_hw_vf - Generic stop Tx/Rx units
  *  @hw: pointer to hardware structure
  *
@@ -256,6 +285,11 @@ static s32 ixgbevf_set_uc_addr_vf(struct
 	return ret_val;
 }
 
+static s32 ixgbevf_hv_set_uc_addr_vf(struct ixgbe_hw *hw, u32 index, u8 *addr)
+{
+	return -EOPNOTSUPP;
+}
+
 /**
  * ixgbevf_get_reta_locked - get the RSS redirection table (RETA) contents.
  * @adapter: pointer to the port handle
@@ -406,12 +440,34 @@ static s32 ixgbevf_set_rar_vf(struct ixg
 
 	/* if nacked the address was rejected, use "perm_addr" */
 	if (!ret_val &&
-	    (msgbuf[0] == (IXGBE_VF_SET_MAC_ADDR | IXGBE_VT_MSGTYPE_NACK)))
+	    (msgbuf[0] == (IXGBE_VF_SET_MAC_ADDR | IXGBE_VT_MSGTYPE_NACK))) {
 		ixgbevf_get_mac_addr_vf(hw, hw->mac.addr);
+		return IXGBE_ERR_MBX;
+	}
 
 	return ret_val;
 }
 
+/**
+ *  ixgbevf_hv_set_rar_vf - set device MAC address Hyper-V variant
+ *  @hw: pointer to hardware structure
+ *  @index: Receive address register to write
+ *  @addr: Address to put into receive address register
+ *  @vmdq: Unused in this implementation
+ *
+ * We don't really allow setting the device MAC address. However,
+ * if the address being set is the permanent MAC address we will
+ * permit that.
+ **/
+static s32 ixgbevf_hv_set_rar_vf(struct ixgbe_hw *hw, u32 index, u8 *addr,
+				 u32 vmdq)
+{
+	if (ether_addr_equal(addr, hw->mac.perm_addr))
+		return 0;
+
+	return -EOPNOTSUPP;
+}
+
 static void ixgbevf_write_msg_read_ack(struct ixgbe_hw *hw,
 				       u32 *msg, u16 size)
 {
@@ -469,6 +525,15 @@ static s32 ixgbevf_update_mc_addr_list_v
 }
 
 /**
+ * Hyper-V variant - just a stub.
+ */
+static s32 ixgbevf_hv_update_mc_addr_list_vf(struct ixgbe_hw *hw,
+					     struct net_device *netdev)
+{
+	return -EOPNOTSUPP;
+}
+
+/**
  *  ixgbevf_update_xcast_mode - Update Multicast mode
  *  @hw: pointer to the HW structure
  *  @netdev: pointer to net device structure
@@ -509,6 +574,16 @@ static s32 ixgbevf_update_xcast_mode(str
 }
 
 /**
+ * Hyper-V variant - just a stub.
+ */
+static s32 ixgbevf_hv_update_xcast_mode(struct ixgbe_hw *hw,
+					struct net_device *netdev,
+					int xcast_mode)
+{
+	return -EOPNOTSUPP;
+}
+
+/**
  *  ixgbevf_set_vfta_vf - Set/Unset VLAN filter table address
  *  @hw: pointer to the HW structure
  *  @vlan: 12 bit VLAN ID
@@ -547,6 +622,15 @@ mbx_err:
 }
 
 /**
+ * Hyper-V variant - just a stub.
+ */
+static s32 ixgbevf_hv_set_vfta_vf(struct ixgbe_hw *hw, u32 vlan, u32 vind,
+				  bool vlan_on)
+{
+	return -EOPNOTSUPP;
+}
+
+/**
  *  ixgbevf_setup_mac_link_vf - Setup MAC link settings
  *  @hw: pointer to hardware structure
  *  @speed: Unused in this implementation
@@ -652,11 +736,72 @@ out:
 }
 
 /**
- *  ixgbevf_rlpml_set_vf - Set the maximum receive packet length
+ * Hyper-V variant; there is no mailbox communication.
+ */
+static s32 ixgbevf_hv_check_mac_link_vf(struct ixgbe_hw *hw,
+					ixgbe_link_speed *speed,
+					bool *link_up,
+					bool autoneg_wait_to_complete)
+{
+	struct ixgbe_mbx_info *mbx = &hw->mbx;
+	struct ixgbe_mac_info *mac = &hw->mac;
+	u32 links_reg;
+
+	/* If we were hit with a reset drop the link */
+	if (!mbx->ops.check_for_rst(hw) || !mbx->timeout)
+		mac->get_link_status = true;
+
+	if (!mac->get_link_status)
+		goto out;
+
+	/* if link status is down no point in checking to see if pf is up */
+	links_reg = IXGBE_READ_REG(hw, IXGBE_VFLINKS);
+	if (!(links_reg & IXGBE_LINKS_UP))
+		goto out;
+
+	/* for SFP+ modules and DA cables on 82599 it can take up to 500usecs
+	 * before the link status is correct
+	 */
+	if (mac->type == ixgbe_mac_82599_vf) {
+		int i;
+
+		for (i = 0; i < 5; i++) {
+			udelay(100);
+			links_reg = IXGBE_READ_REG(hw, IXGBE_VFLINKS);
+
+			if (!(links_reg & IXGBE_LINKS_UP))
+				goto out;
+		}
+	}
+
+	switch (links_reg & IXGBE_LINKS_SPEED_82599) {
+	case IXGBE_LINKS_SPEED_10G_82599:
+		*speed = IXGBE_LINK_SPEED_10GB_FULL;
+		break;
+	case IXGBE_LINKS_SPEED_1G_82599:
+		*speed = IXGBE_LINK_SPEED_1GB_FULL;
+		break;
+	case IXGBE_LINKS_SPEED_100_82599:
+		*speed = IXGBE_LINK_SPEED_100_FULL;
+		break;
+	}
+
+	/* if we passed all the tests above then the link is up and we no
+	 * longer need to check for link
+	 */
+	mac->get_link_status = false;
+
+out:
+	*link_up = !mac->get_link_status;
+	return 0;
+}
+
+/**
+ *  ixgbevf_set_rlpml_vf - Set the maximum receive packet length
  *  @hw: pointer to the HW structure
  *  @max_size: value to assign to max frame size
  **/
-void ixgbevf_rlpml_set_vf(struct ixgbe_hw *hw, u16 max_size)
+static void ixgbevf_set_rlpml_vf(struct ixgbe_hw *hw, u16 max_size)
 {
 	u32 msgbuf[2];
 
@@ -666,11 +811,30 @@ void ixgbevf_rlpml_set_vf(struct ixgbe_h
 }
 
 /**
- *  ixgbevf_negotiate_api_version - Negotiate supported API version
+ * ixgbevf_hv_set_rlpml_vf - Set the maximum receive packet length
+ * @hw: pointer to the HW structure
+ * @max_size: value to assign to max frame size
+ * Hyper-V variant.
+ **/
+static void ixgbevf_hv_set_rlpml_vf(struct ixgbe_hw *hw, u16 max_size)
+{
+	u32 reg;
+
+	/* If we are on Hyper-V, we implement this functionality
+	 * differently.
+	 */
+	reg =  IXGBE_READ_REG(hw, IXGBE_VFRXDCTL(0));
+	/* CRC == 4 */
+	reg |= ((max_size + 4) | IXGBE_RXDCTL_RLPML_EN);
+	IXGBE_WRITE_REG(hw, IXGBE_VFRXDCTL(0), reg);
+}
+
+/**
+ *  ixgbevf_negotiate_api_version_vf - Negotiate supported API version
  *  @hw: pointer to the HW structure
  *  @api: integer containing requested API version
  **/
-int ixgbevf_negotiate_api_version(struct ixgbe_hw *hw, int api)
+static int ixgbevf_negotiate_api_version_vf(struct ixgbe_hw *hw, int api)
 {
 	int err;
 	u32 msg[3];
@@ -699,6 +863,21 @@ int ixgbevf_negotiate_api_version(struct
 	return err;
 }
 
+/**
+ *  ixgbevf_hv_negotiate_api_version_vf - Negotiate supported API version
+ *  @hw: pointer to the HW structure
+ *  @api: integer containing requested API version
+ *  Hyper-V version - only ixgbe_mbox_api_10 supported.
+ **/
+static int ixgbevf_hv_negotiate_api_version_vf(struct ixgbe_hw *hw, int api)
+{
+	/* Hyper-V only supports api version ixgbe_mbox_api_10 */
+	if (api != ixgbe_mbox_api_10)
+		return IXGBE_ERR_INVALID_ARGUMENT;
+
+	return 0;
+}
+
 int ixgbevf_get_queues(struct ixgbe_hw *hw, unsigned int *num_tcs,
 		       unsigned int *default_tc)
 {
@@ -765,11 +944,30 @@ static const struct ixgbe_mac_operations
 	.stop_adapter		= ixgbevf_stop_hw_vf,
 	.setup_link		= ixgbevf_setup_mac_link_vf,
 	.check_link		= ixgbevf_check_mac_link_vf,
+	.negotiate_api_version	= ixgbevf_negotiate_api_version_vf,
 	.set_rar		= ixgbevf_set_rar_vf,
 	.update_mc_addr_list	= ixgbevf_update_mc_addr_list_vf,
 	.update_xcast_mode	= ixgbevf_update_xcast_mode,
 	.set_uc_addr		= ixgbevf_set_uc_addr_vf,
 	.set_vfta		= ixgbevf_set_vfta_vf,
+	.set_rlpml		= ixgbevf_set_rlpml_vf,
+};
+
+static const struct ixgbe_mac_operations ixgbevf_hv_mac_ops = {
+	.init_hw		= ixgbevf_init_hw_vf,
+	.reset_hw		= ixgbevf_hv_reset_hw_vf,
+	.start_hw		= ixgbevf_start_hw_vf,
+	.get_mac_addr		= ixgbevf_get_mac_addr_vf,
+	.stop_adapter		= ixgbevf_stop_hw_vf,
+	.setup_link		= ixgbevf_setup_mac_link_vf,
+	.check_link		= ixgbevf_hv_check_mac_link_vf,
+	.negotiate_api_version	= ixgbevf_hv_negotiate_api_version_vf,
+	.set_rar		= ixgbevf_hv_set_rar_vf,
+	.update_mc_addr_list	= ixgbevf_hv_update_mc_addr_list_vf,
+	.update_xcast_mode	= ixgbevf_hv_update_xcast_mode,
+	.set_uc_addr		= ixgbevf_hv_set_uc_addr_vf,
+	.set_vfta		= ixgbevf_hv_set_vfta_vf,
+	.set_rlpml		= ixgbevf_hv_set_rlpml_vf,
 };
 
 const struct ixgbevf_info ixgbevf_82599_vf_info = {
@@ -777,17 +975,37 @@ const struct ixgbevf_info ixgbevf_82599_
 	.mac_ops = &ixgbevf_mac_ops,
 };
 
+const struct ixgbevf_info ixgbevf_82599_vf_hv_info = {
+	.mac = ixgbe_mac_82599_vf,
+	.mac_ops = &ixgbevf_hv_mac_ops,
+};
+
 const struct ixgbevf_info ixgbevf_X540_vf_info = {
 	.mac = ixgbe_mac_X540_vf,
 	.mac_ops = &ixgbevf_mac_ops,
 };
 
+const struct ixgbevf_info ixgbevf_X540_vf_hv_info = {
+	.mac = ixgbe_mac_X540_vf,
+	.mac_ops = &ixgbevf_hv_mac_ops,
+};
+
 const struct ixgbevf_info ixgbevf_X550_vf_info = {
 	.mac = ixgbe_mac_X550_vf,
 	.mac_ops = &ixgbevf_mac_ops,
 };
 
+const struct ixgbevf_info ixgbevf_X550_vf_hv_info = {
+	.mac = ixgbe_mac_X550_vf,
+	.mac_ops = &ixgbevf_hv_mac_ops,
+};
+
 const struct ixgbevf_info ixgbevf_X550EM_x_vf_info = {
 	.mac = ixgbe_mac_X550EM_x_vf,
 	.mac_ops = &ixgbevf_mac_ops,
 };
+
+const struct ixgbevf_info ixgbevf_X550EM_x_vf_hv_info = {
+	.mac = ixgbe_mac_X550EM_x_vf,
+	.mac_ops = &ixgbevf_hv_mac_ops,
+};
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/intel/ixgbevf/vf.h
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/intel/ixgbevf/vf.h
@@ -51,6 +51,7 @@ struct ixgbe_mac_operations {
 	s32 (*get_mac_addr)(struct ixgbe_hw *, u8 *);
 	s32 (*stop_adapter)(struct ixgbe_hw *);
 	s32 (*get_bus_info)(struct ixgbe_hw *);
+	s32 (*negotiate_api_version)(struct ixgbe_hw *hw, int api);
 
 	/* Link */
 	s32 (*setup_link)(struct ixgbe_hw *, ixgbe_link_speed, bool, bool);
@@ -68,6 +69,7 @@ struct ixgbe_mac_operations {
 	s32 (*disable_mc)(struct ixgbe_hw *);
 	s32 (*clear_vfta)(struct ixgbe_hw *);
 	s32 (*set_vfta)(struct ixgbe_hw *, u32, u32, bool);
+	void (*set_rlpml)(struct ixgbe_hw *, u16);
 };
 
 enum ixgbe_mac_type {
@@ -207,8 +209,6 @@ static inline u32 ixgbe_read_reg_array(s
 
 #define IXGBE_READ_REG_ARRAY(h, r, o) ixgbe_read_reg_array(h, r, o)
 
-void ixgbevf_rlpml_set_vf(struct ixgbe_hw *hw, u16 max_size);
-int ixgbevf_negotiate_api_version(struct ixgbe_hw *hw, int api);
 int ixgbevf_get_queues(struct ixgbe_hw *hw, unsigned int *num_tcs,
 		       unsigned int *default_tc);
 int ixgbevf_get_reta_locked(struct ixgbe_hw *hw, u32 *reta, int num_rx_queues);
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/jme.c
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/jme.c
@@ -270,11 +270,17 @@ jme_reset_mac_processor(struct jme_adapt
 }
 
 static inline void
-jme_clear_pm(struct jme_adapter *jme)
+jme_clear_pm_enable_wol(struct jme_adapter *jme)
 {
 	jwrite32(jme, JME_PMCS, PMCS_STMASK | jme->reg_pmcs);
 }
 
+static inline void
+jme_clear_pm_disable_wol(struct jme_adapter *jme)
+{
+	jwrite32(jme, JME_PMCS, PMCS_STMASK);
+}
+
 static int
 jme_reload_eeprom(struct jme_adapter *jme)
 {
@@ -1853,7 +1859,7 @@ jme_open(struct net_device *netdev)
 	struct jme_adapter *jme = netdev_priv(netdev);
 	int rc;
 
-	jme_clear_pm(jme);
+	jme_clear_pm_disable_wol(jme);
 	JME_NAPI_ENABLE(jme);
 
 	tasklet_init(&jme->linkch_task, jme_link_change_tasklet,
@@ -1925,11 +1931,11 @@ jme_wait_link(struct jme_adapter *jme)
 static void
 jme_powersave_phy(struct jme_adapter *jme)
 {
-	if (jme->reg_pmcs) {
+	if (jme->reg_pmcs && device_may_wakeup(&jme->pdev->dev)) {
 		jme_set_100m_half(jme);
 		if (jme->reg_pmcs & (PMCS_LFEN | PMCS_LREN))
 			jme_wait_link(jme);
-		jme_clear_pm(jme);
+		jme_clear_pm_enable_wol(jme);
 	} else {
 		jme_phy_off(jme);
 	}
@@ -2646,9 +2652,6 @@ jme_set_wol(struct net_device *netdev,
 	if (wol->wolopts & WAKE_MAGIC)
 		jme->reg_pmcs |= PMCS_MFEN;
 
-	jwrite32(jme, JME_PMCS, jme->reg_pmcs);
-	device_set_wakeup_enable(&jme->pdev->dev, !!(jme->reg_pmcs));
-
 	return 0;
 }
 
@@ -3172,8 +3175,8 @@ jme_init_one(struct pci_dev *pdev,
 	jme->mii_if.mdio_read = jme_mdio_read;
 	jme->mii_if.mdio_write = jme_mdio_write;
 
-	jme_clear_pm(jme);
-	device_set_wakeup_enable(&pdev->dev, true);
+	jme_clear_pm_disable_wol(jme);
+	device_init_wakeup(&pdev->dev, true);
 
 	jme_set_phyfifo_5level(jme);
 	jme->pcirev = pdev->revision;
@@ -3304,7 +3307,7 @@ jme_resume(struct device *dev)
 	if (!netif_running(netdev))
 		return 0;
 
-	jme_clear_pm(jme);
+	jme_clear_pm_disable_wol(jme);
 	jme_phy_on(jme);
 	if (test_bit(JME_FLAG_SSET, &jme->flags))
 		jme_set_settings(netdev, &jme->old_ecmd);
@@ -3312,13 +3315,14 @@ jme_resume(struct device *dev)
 		jme_reset_phy_processor(jme);
 	jme_phy_calibration(jme);
 	jme_phy_setEA(jme);
-	jme_start_irq(jme);
 	netif_device_attach(netdev);
 
 	atomic_inc(&jme->link_changing);
 
 	jme_reset_link(jme);
 
+	jme_start_irq(jme);
+
 	return 0;
 }
 
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/marvell/mvneta.c
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/marvell/mvneta.c
@@ -226,7 +226,7 @@
 /* Various constants */
 
 /* Coalescing */
-#define MVNETA_TXDONE_COAL_PKTS		1
+#define MVNETA_TXDONE_COAL_PKTS		0	/* interrupt per packet */
 #define MVNETA_RX_COAL_PKTS		32
 #define MVNETA_RX_COAL_USEC		100
 
@@ -3404,7 +3404,7 @@ static int mvneta_probe(struct platform_
 	dev->features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO;
 	dev->hw_features |= dev->features;
 	dev->vlan_features |= dev->features;
-	dev->priv_flags |= IFF_UNICAST_FLT;
+	dev->priv_flags |= IFF_UNICAST_FLT | IFF_LIVE_ADDR_CHANGE;
 	dev->gso_max_segs = MVNETA_MAX_TSO_SEGS;
 
 	err = register_netdev(dev);
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/mellanox/mlx4/cq.c
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/mellanox/mlx4/cq.c
@@ -318,7 +318,9 @@ int mlx4_cq_alloc(struct mlx4_dev *dev,
 	if (timestamp_en)
 		cq_context->flags  |= cpu_to_be32(1 << 19);
 
-	cq_context->logsize_usrpage = cpu_to_be32((ilog2(nent) << 24) | uar->index);
+	cq_context->logsize_usrpage =
+		cpu_to_be32((ilog2(nent) << 24) |
+			    mlx4_to_hw_uar_index(dev, uar->index));
 	cq_context->comp_eqn	    = priv->eq_table.eq[MLX4_CQ_TO_EQ_VECTOR(vector)].eqn;
 	cq_context->log_page_size   = mtt->page_shift - MLX4_ICM_PAGE_SHIFT;
 
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/mellanox/mlx4/en_clock.c
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/mellanox/mlx4/en_clock.c
@@ -236,6 +236,24 @@ static const struct ptp_clock_info mlx4_
 	.enable		= mlx4_en_phc_enable,
 };
 
+#define MLX4_EN_WRAP_AROUND_SEC	10ULL
+
+/* This function calculates the max shift that enables the user range
+ * of MLX4_EN_WRAP_AROUND_SEC values in the cycles register.
+ */
+static u32 freq_to_shift(u16 freq)
+{
+	u32 freq_khz = freq * 1000;
+	u64 max_val_cycles = freq_khz * 1000 * MLX4_EN_WRAP_AROUND_SEC;
+	u64 max_val_cycles_rounded = is_power_of_2(max_val_cycles + 1) ?
+		max_val_cycles : roundup_pow_of_two(max_val_cycles) - 1;
+	/* calculate max possible multiplier in order to fit in 64bit */
+	u64 max_mul = div_u64(0xffffffffffffffffULL, max_val_cycles_rounded);
+
+	/* This comes from the reverse of clocksource_khz2mult */
+	return ilog2(div_u64(max_mul * freq_khz, 1000000));
+}
+
 void mlx4_en_init_timestamp(struct mlx4_en_dev *mdev)
 {
 	struct mlx4_dev *dev = mdev->dev;
@@ -254,12 +272,7 @@ void mlx4_en_init_timestamp(struct mlx4_
 	memset(&mdev->cycles, 0, sizeof(mdev->cycles));
 	mdev->cycles.read = mlx4_en_read_clock;
 	mdev->cycles.mask = CLOCKSOURCE_MASK(48);
-	/* Using shift to make calculation more accurate. Since current HW
-	 * clock frequency is 427 MHz, and cycles are given using a 48 bits
-	 * register, the biggest shift when calculating using u64, is 14
-	 * (max_cycles * multiplier < 2^64)
-	 */
-	mdev->cycles.shift = 14;
+	mdev->cycles.shift = freq_to_shift(dev->caps.hca_core_clock);
 	mdev->cycles.mult =
 		clocksource_khz2mult(1000 * dev->caps.hca_core_clock, mdev->cycles.shift);
 	mdev->nominal_c_mult = mdev->cycles.mult;
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
@@ -97,6 +97,15 @@ static int mlx4_en_low_latency_recv(stru
 }
 #endif	/* CONFIG_NET_RX_BUSY_POLL */
 
+static int __mlx4_en_setup_tc(struct net_device *dev, u32 handle, __be16 proto,
+			      struct tc_to_netdev *tc)
+{
+	if (handle != TC_H_ROOT || tc->type != TC_SETUP_MQPRIO)
+		return -EINVAL;
+
+	return mlx4_en_setup_tc(dev, tc->tc);
+}
+
 #ifdef CONFIG_RFS_ACCEL
 
 struct mlx4_en_filter {
@@ -2381,8 +2390,6 @@ out:
 	/* set offloads */
 	priv->dev->hw_enc_features |= NETIF_F_IP_CSUM | NETIF_F_RXCSUM |
 				      NETIF_F_TSO | NETIF_F_GSO_UDP_TUNNEL;
-	priv->dev->hw_features |= NETIF_F_GSO_UDP_TUNNEL;
-	priv->dev->features    |= NETIF_F_GSO_UDP_TUNNEL;
 }
 
 static void mlx4_en_del_vxlan_offloads(struct work_struct *work)
@@ -2393,8 +2400,6 @@ static void mlx4_en_del_vxlan_offloads(s
 	/* unset offloads */
 	priv->dev->hw_enc_features &= ~(NETIF_F_IP_CSUM | NETIF_F_RXCSUM |
 				      NETIF_F_TSO | NETIF_F_GSO_UDP_TUNNEL);
-	priv->dev->hw_features &= ~NETIF_F_GSO_UDP_TUNNEL;
-	priv->dev->features    &= ~NETIF_F_GSO_UDP_TUNNEL;
 
 	ret = mlx4_SET_PORT_VXLAN(priv->mdev->dev, priv->port,
 				  VXLAN_STEER_BY_OUTER_MAC, 0);
@@ -2503,7 +2508,7 @@ static const struct net_device_ops mlx4_
 #endif
 	.ndo_set_features	= mlx4_en_set_features,
 	.ndo_fix_features	= mlx4_en_fix_features,
-	.ndo_setup_tc		= mlx4_en_setup_tc,
+	.ndo_setup_tc		= __mlx4_en_setup_tc,
 #ifdef CONFIG_RFS_ACCEL
 	.ndo_rx_flow_steer	= mlx4_en_filter_rfs,
 #endif
@@ -2544,7 +2549,7 @@ static const struct net_device_ops mlx4_
 #endif
 	.ndo_set_features	= mlx4_en_set_features,
 	.ndo_fix_features	= mlx4_en_fix_features,
-	.ndo_setup_tc		= mlx4_en_setup_tc,
+	.ndo_setup_tc		= __mlx4_en_setup_tc,
 #ifdef CONFIG_RFS_ACCEL
 	.ndo_rx_flow_steer	= mlx4_en_filter_rfs,
 #endif
@@ -3020,6 +3025,11 @@ int mlx4_en_init_netdev(struct mlx4_en_d
 		priv->rss_hash_fn = ETH_RSS_HASH_TOP;
 	}
 
+	if (mdev->dev->caps.tunnel_offload_mode == MLX4_TUNNEL_OFFLOAD_MODE_VXLAN) {
+		dev->hw_features |= NETIF_F_GSO_UDP_TUNNEL;
+		dev->features    |= NETIF_F_GSO_UDP_TUNNEL;
+	}
+
 	mdev->pndev[port] = dev;
 	mdev->upper[port] = NULL;
 
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/mellanox/mlx4/en_port.c
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/mellanox/mlx4/en_port.c
@@ -238,11 +238,11 @@ int mlx4_en_DUMP_ETH_STATS(struct mlx4_e
 	stats->collisions = 0;
 	stats->rx_dropped = be32_to_cpu(mlx4_en_stats->RDROP);
 	stats->rx_length_errors = be32_to_cpu(mlx4_en_stats->RdropLength);
-	stats->rx_over_errors = be32_to_cpu(mlx4_en_stats->RdropOvflw);
+	stats->rx_over_errors = 0;
 	stats->rx_crc_errors = be32_to_cpu(mlx4_en_stats->RCRC);
 	stats->rx_frame_errors = 0;
 	stats->rx_fifo_errors = be32_to_cpu(mlx4_en_stats->RdropOvflw);
-	stats->rx_missed_errors = be32_to_cpu(mlx4_en_stats->RdropOvflw);
+	stats->rx_missed_errors = 0;
 	stats->tx_aborted_errors = 0;
 	stats->tx_carrier_errors = 0;
 	stats->tx_fifo_errors = 0;
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/mellanox/mlx4/en_resources.c
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/mellanox/mlx4/en_resources.c
@@ -58,7 +58,8 @@ void mlx4_en_fill_qp_context(struct mlx4
 	} else {
 		context->sq_size_stride = ilog2(TXBB_SIZE) - 4;
 	}
-	context->usr_page = cpu_to_be32(mdev->priv_uar.index);
+	context->usr_page = cpu_to_be32(mlx4_to_hw_uar_index(mdev->dev,
+					mdev->priv_uar.index));
 	context->local_qpn = cpu_to_be32(qpn);
 	context->pri_path.ackto = 1 & 0x07;
 	context->pri_path.sched_queue = 0x83 | (priv->port - 1) << 6;
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/mellanox/mlx4/en_rx.c
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/mellanox/mlx4/en_rx.c
@@ -704,7 +704,7 @@ static int get_fixed_ipv6_csum(__wsum hw
 
 	if (ipv6h->nexthdr == IPPROTO_FRAGMENT || ipv6h->nexthdr == IPPROTO_HOPOPTS)
 		return -1;
-	hw_checksum = csum_add(hw_checksum, (__force __wsum)(ipv6h->nexthdr << 8));
+	hw_checksum = csum_add(hw_checksum, (__force __wsum)htons(ipv6h->nexthdr));
 
 	csum_pseudo_hdr = csum_partial(&ipv6h->saddr,
 				       sizeof(ipv6h->saddr) + sizeof(ipv6h->daddr), 0);
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/mellanox/mlx4/en_tx.c
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/mellanox/mlx4/en_tx.c
@@ -213,7 +213,9 @@ int mlx4_en_activate_tx_ring(struct mlx4
 	mlx4_en_fill_qp_context(priv, ring->size, ring->stride, 1, 0, ring->qpn,
 				ring->cqn, user_prio, &ring->context);
 	if (ring->bf_alloced)
-		ring->context.usr_page = cpu_to_be32(ring->bf.uar->index);
+		ring->context.usr_page =
+			cpu_to_be32(mlx4_to_hw_uar_index(mdev->dev,
+							 ring->bf.uar->index));
 
 	err = mlx4_qp_to_ready(mdev->dev, &ring->wqres.mtt, &ring->context,
 			       &ring->qp, &ring->qp_state);
@@ -400,7 +402,6 @@ static bool mlx4_en_process_tx_cq(struct
 	u32 packets = 0;
 	u32 bytes = 0;
 	int factor = priv->cqe_factor;
-	u64 timestamp = 0;
 	int done = 0;
 	int budget = priv->tx_work_limit;
 	u32 last_nr_txbb;
@@ -440,9 +441,12 @@ static bool mlx4_en_process_tx_cq(struct
 		new_index = be16_to_cpu(cqe->wqe_index) & size_mask;
 
 		do {
+			u64 timestamp = 0;
+
 			txbbs_skipped += last_nr_txbb;
 			ring_index = (ring_index + last_nr_txbb) & size_mask;
-			if (ring->tx_info[ring_index].ts_requested)
+
+			if (unlikely(ring->tx_info[ring_index].ts_requested))
 				timestamp = mlx4_en_get_cqe_ts(cqe);
 
 			/* free next descriptor */
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/mellanox/mlx4/eq.c
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/mellanox/mlx4/eq.c
@@ -924,9 +924,10 @@ static void __iomem *mlx4_get_eq_uar(str
 
 	if (!priv->eq_table.uar_map[index]) {
 		priv->eq_table.uar_map[index] =
-			ioremap(pci_resource_start(dev->persist->pdev, 2) +
-				((eq->eqn / 4) << PAGE_SHIFT),
-				PAGE_SIZE);
+			ioremap(
+				pci_resource_start(dev->persist->pdev, 2) +
+				((eq->eqn / 4) << (dev->uar_page_shift)),
+				(1 << (dev->uar_page_shift)));
 		if (!priv->eq_table.uar_map[index]) {
 			mlx4_err(dev, "Couldn't map EQ doorbell for EQN 0x%06x\n",
 				 eq->eqn);
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/mellanox/mlx4/main.c
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/mellanox/mlx4/main.c
@@ -168,6 +168,20 @@ struct mlx4_port_config {
 
 static atomic_t pf_loading = ATOMIC_INIT(0);
 
+static inline void mlx4_set_num_reserved_uars(struct mlx4_dev *dev,
+					      struct mlx4_dev_cap *dev_cap)
+{
+	/* The reserved_uars is calculated by system page size unit.
+	 * Therefore, adjustment is added when the uar page size is less
+	 * than the system page size
+	 */
+	dev->caps.reserved_uars	=
+		max_t(int,
+		      mlx4_get_num_reserved_uar(dev),
+		      dev_cap->reserved_uars /
+			(1 << (PAGE_SHIFT - dev->uar_page_shift)));
+}
+
 int mlx4_check_port_params(struct mlx4_dev *dev,
 			   enum mlx4_port_type *port_type)
 {
@@ -386,8 +400,6 @@ static int mlx4_dev_cap(struct mlx4_dev
 	dev->caps.reserved_mtts      = dev_cap->reserved_mtts;
 	dev->caps.reserved_mrws	     = dev_cap->reserved_mrws;
 
-	/* The first 128 UARs are used for EQ doorbells */
-	dev->caps.reserved_uars	     = max_t(int, 128, dev_cap->reserved_uars);
 	dev->caps.reserved_pds	     = dev_cap->reserved_pds;
 	dev->caps.reserved_xrcds     = (dev->caps.flags & MLX4_DEV_CAP_FLAG_XRC) ?
 					dev_cap->reserved_xrcds : 0;
@@ -405,6 +417,15 @@ static int mlx4_dev_cap(struct mlx4_dev
 	dev->caps.max_gso_sz	     = dev_cap->max_gso_sz;
 	dev->caps.max_rss_tbl_sz     = dev_cap->max_rss_tbl_sz;
 
+	/* Save uar page shift */
+	if (!mlx4_is_slave(dev)) {
+		/* Virtual PCI function needs to determine UAR page size from
+		 * firmware. Only master PCI function can set the uar page size
+		 */
+		dev->uar_page_shift = DEFAULT_UAR_PAGE_SHIFT;
+		mlx4_set_num_reserved_uars(dev, dev_cap);
+	}
+
 	if (dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_PHV_EN) {
 		struct mlx4_init_hca_param hca_param;
 
@@ -815,15 +836,24 @@ static int mlx4_slave_cap(struct mlx4_de
 		return -ENODEV;
 	}
 
-	/* slave gets uar page size from QUERY_HCA fw command */
-	dev->caps.uar_page_size = 1 << (hca_param.uar_page_sz + 12);
+	/* Set uar_page_shift for VF */
+	dev->uar_page_shift = hca_param.uar_page_sz + 12;
 
-	/* TODO: relax this assumption */
-	if (dev->caps.uar_page_size != PAGE_SIZE) {
-		mlx4_err(dev, "UAR size:%d != kernel PAGE_SIZE of %ld\n",
-			 dev->caps.uar_page_size, PAGE_SIZE);
-		return -ENODEV;
-	}
+	/* Make sure the master uar page size is valid */
+	if (dev->uar_page_shift > PAGE_SHIFT) {
+		mlx4_err(dev,
+			 "Invalid configuration: uar page size is larger than system page size\n");
+		return  -ENODEV;
+	}
+
+	/* Set reserved_uars based on the uar_page_shift */
+	mlx4_set_num_reserved_uars(dev, &dev_cap);
+
+	/* Although uar page size in FW differs from system page size,
+	 * upper software layers (mlx4_ib, mlx4_en and part of mlx4_core)
+	 * still works with assumption that uar page size == system page size
+	 */
+	dev->caps.uar_page_size = PAGE_SIZE;
 
 	memset(&func_cap, 0, sizeof(func_cap));
 	err = mlx4_QUERY_FUNC_CAP(dev, 0, &func_cap);
@@ -2092,8 +2122,12 @@ static int mlx4_init_hca(struct mlx4_dev
 
 		dev->caps.max_fmr_maps = (1 << (32 - ilog2(dev->caps.num_mpts))) - 1;
 
-		init_hca.log_uar_sz = ilog2(dev->caps.num_uars);
-		init_hca.uar_page_sz = PAGE_SHIFT - 12;
+		/* Always set UAR page size 4KB, set log_uar_sz accordingly */
+		init_hca.log_uar_sz = ilog2(dev->caps.num_uars) +
+				      PAGE_SHIFT -
+				      DEFAULT_UAR_PAGE_SHIFT;
+		init_hca.uar_page_sz = DEFAULT_UAR_PAGE_SHIFT - 12;
+
 		init_hca.mw_enabled = 0;
 		if (dev->caps.flags & MLX4_DEV_CAP_FLAG_MEM_WINDOW ||
 		    dev->caps.bmme_flags & MLX4_BMME_FLAG_TYPE_2_WIN)
@@ -3009,6 +3043,34 @@ static int mlx4_check_dev_cap(struct mlx
 	return 0;
 }
 
+static int mlx4_pci_enable_device(struct mlx4_dev *dev)
+{
+	struct pci_dev *pdev = dev->persist->pdev;
+	int err = 0;
+
+	mutex_lock(&dev->persist->pci_status_mutex);
+	if (dev->persist->pci_status == MLX4_PCI_STATUS_DISABLED) {
+		err = pci_enable_device(pdev);
+		if (!err)
+			dev->persist->pci_status = MLX4_PCI_STATUS_ENABLED;
+	}
+	mutex_unlock(&dev->persist->pci_status_mutex);
+
+	return err;
+}
+
+static void mlx4_pci_disable_device(struct mlx4_dev *dev)
+{
+	struct pci_dev *pdev = dev->persist->pdev;
+
+	mutex_lock(&dev->persist->pci_status_mutex);
+	if (dev->persist->pci_status == MLX4_PCI_STATUS_ENABLED) {
+		pci_disable_device(pdev);
+		dev->persist->pci_status = MLX4_PCI_STATUS_DISABLED;
+	}
+	mutex_unlock(&dev->persist->pci_status_mutex);
+}
+
 static int mlx4_load_one(struct pci_dev *pdev, int pci_dev_data,
 			 int total_vfs, int *nvfs, struct mlx4_priv *priv,
 			 int reset_flow)
@@ -3419,7 +3481,7 @@ static int __mlx4_init_one(struct pci_de
 
 	pr_info(DRV_NAME ": Initializing %s\n", pci_name(pdev));
 
-	err = pci_enable_device(pdev);
+	err = mlx4_pci_enable_device(&priv->dev);
 	if (err) {
 		dev_err(&pdev->dev, "Cannot enable PCI device, aborting\n");
 		return err;
@@ -3552,7 +3614,7 @@ err_release_regions:
 	pci_release_regions(pdev);
 
 err_disable_pdev:
-	pci_disable_device(pdev);
+	mlx4_pci_disable_device(&priv->dev);
 	pci_set_drvdata(pdev, NULL);
 	return err;
 }
@@ -3581,6 +3643,7 @@ static int mlx4_init_one(struct pci_dev
 	priv->pci_dev_data = id->driver_data;
 	mutex_init(&dev->persist->device_state_mutex);
 	mutex_init(&dev->persist->interface_state_mutex);
+	mutex_init(&dev->persist->pci_status_mutex);
 
 	ret =  __mlx4_init_one(pdev, id->driver_data, priv);
 	if (ret) {
@@ -3719,7 +3782,7 @@ static void mlx4_remove_one(struct pci_d
 	}
 
 	pci_release_regions(pdev);
-	pci_disable_device(pdev);
+	mlx4_pci_disable_device(dev);
 	kfree(dev->persist);
 	kfree(priv);
 	pci_set_drvdata(pdev, NULL);
@@ -3837,7 +3900,7 @@ static pci_ers_result_t mlx4_pci_err_det
 	if (state == pci_channel_io_perm_failure)
 		return PCI_ERS_RESULT_DISCONNECT;
 
-	pci_disable_device(pdev);
+	mlx4_pci_disable_device(persist->dev);
 	return PCI_ERS_RESULT_NEED_RESET;
 }
 
@@ -3845,45 +3908,53 @@ static pci_ers_result_t mlx4_pci_slot_re
 {
 	struct mlx4_dev_persistent *persist = pci_get_drvdata(pdev);
 	struct mlx4_dev	 *dev  = persist->dev;
-	struct mlx4_priv *priv = mlx4_priv(dev);
-	int               ret;
-	int nvfs[MLX4_MAX_PORTS + 1] = {0, 0, 0};
-	int total_vfs;
+	int err;
 
 	mlx4_err(dev, "mlx4_pci_slot_reset was called\n");
-	ret = pci_enable_device(pdev);
-	if (ret) {
-		mlx4_err(dev, "Can not re-enable device, ret=%d\n", ret);
+	err = mlx4_pci_enable_device(dev);
+	if (err) {
+		mlx4_err(dev, "Can not re-enable device, err=%d\n", err);
 		return PCI_ERS_RESULT_DISCONNECT;
 	}
 
 	pci_set_master(pdev);
 	pci_restore_state(pdev);
 	pci_save_state(pdev);
+	return PCI_ERS_RESULT_RECOVERED;
+}
 
+static void mlx4_pci_resume(struct pci_dev *pdev)
+{
+	struct mlx4_dev_persistent *persist = pci_get_drvdata(pdev);
+	struct mlx4_dev	 *dev  = persist->dev;
+	struct mlx4_priv *priv = mlx4_priv(dev);
+	int nvfs[MLX4_MAX_PORTS + 1] = {0, 0, 0};
+	int total_vfs;
+	int err;
+
+	mlx4_err(dev, "%s was called\n", __func__);
 	total_vfs = dev->persist->num_vfs;
 	memcpy(nvfs, dev->persist->nvfs, sizeof(dev->persist->nvfs));
 
 	mutex_lock(&persist->interface_state_mutex);
 	if (!(persist->interface_state & MLX4_INTERFACE_STATE_UP)) {
-		ret = mlx4_load_one(pdev, priv->pci_dev_data, total_vfs, nvfs,
+		err = mlx4_load_one(pdev, priv->pci_dev_data, total_vfs, nvfs,
 				    priv, 1);
-		if (ret) {
-			mlx4_err(dev, "%s: mlx4_load_one failed, ret=%d\n",
-				 __func__,  ret);
+		if (err) {
+			mlx4_err(dev, "%s: mlx4_load_one failed, err=%d\n",
+				 __func__,  err);
 			goto end;
 		}
 
-		ret = restore_current_port_types(dev, dev->persist->
+		err = restore_current_port_types(dev, dev->persist->
 						 curr_port_type, dev->persist->
 						 curr_port_poss_type);
-		if (ret)
-			mlx4_err(dev, "could not restore original port types (%d)\n", ret);
+		if (err)
+			mlx4_err(dev, "could not restore original port types (%d)\n", err);
 	}
 end:
 	mutex_unlock(&persist->interface_state_mutex);
 
-	return ret ? PCI_ERS_RESULT_DISCONNECT : PCI_ERS_RESULT_RECOVERED;
 }
 
 static void mlx4_shutdown(struct pci_dev *pdev)
@@ -3900,6 +3971,7 @@ static void mlx4_shutdown(struct pci_dev
 static const struct pci_error_handlers mlx4_err_handler = {
 	.error_detected = mlx4_pci_err_detected,
 	.slot_reset     = mlx4_pci_slot_reset,
+	.resume		= mlx4_pci_resume,
 };
 
 static struct pci_driver mlx4_driver = {
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/mellanox/mlx4/pd.c
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/mellanox/mlx4/pd.c
@@ -269,9 +269,15 @@ EXPORT_SYMBOL_GPL(mlx4_bf_free);
 
 int mlx4_init_uar_table(struct mlx4_dev *dev)
 {
-	if (dev->caps.num_uars <= 128) {
-		mlx4_err(dev, "Only %d UAR pages (need more than 128)\n",
-			 dev->caps.num_uars);
+	int num_reserved_uar = mlx4_get_num_reserved_uar(dev);
+
+	mlx4_dbg(dev, "uar_page_shift = %d", dev->uar_page_shift);
+	mlx4_dbg(dev, "Effective reserved_uars=%d", dev->caps.reserved_uars);
+
+	if (dev->caps.num_uars <= num_reserved_uar) {
+		mlx4_err(
+			dev, "Only %d UAR pages (need more than %d)\n",
+			dev->caps.num_uars, num_reserved_uar);
 		mlx4_err(dev, "Increase firmware log2_uar_bar_megabytes?\n");
 		return -ENODEV;
 	}
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
@@ -3132,7 +3132,7 @@ static int verify_qp_parameters(struct m
 		case QP_TRANS_RTS2RTS:
 		case QP_TRANS_SQD2SQD:
 		case QP_TRANS_SQD2RTS:
-			if (slave != mlx4_master_func_num(dev))
+			if (slave != mlx4_master_func_num(dev)) {
 				if (optpar & MLX4_QP_OPTPAR_PRIMARY_ADDR_PATH) {
 					port = (qp_ctx->pri_path.sched_queue >> 6 & 1) + 1;
 					if (dev->caps.port_mask[port] != MLX4_PORT_TYPE_IB)
@@ -3151,6 +3151,7 @@ static int verify_qp_parameters(struct m
 					if (qp_ctx->alt_path.mgid_index >= num_gids)
 						return -EINVAL;
 				}
+			}
 			break;
 		default:
 			break;
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/mellanox/mlx5/core/Makefile
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/mellanox/mlx5/core/Makefile
@@ -2,7 +2,7 @@ obj-$(CONFIG_MLX5_CORE)		+= mlx5_core.o
 
 mlx5_core-y :=	main.o cmd.o debugfs.o fw.o eq.o uar.o pagealloc.o \
 		health.o mcg.o cq.o srq.o alloc.o qp.o port.o mr.o pd.o   \
-		mad.o transobj.o vport.o
-mlx5_core-$(CONFIG_MLX5_CORE_EN) += wq.o flow_table.o \
+		mad.o transobj.o vport.o sriov.o
+mlx5_core-$(CONFIG_MLX5_CORE_EN) += wq.o flow_table.o eswitch.o \
 		en_main.o en_flow_table.o en_ethtool.o en_tx.o en_rx.o \
 		en_txrx.o
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/mellanox/mlx5/core/cmd.c
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/mellanox/mlx5/core/cmd.c
@@ -143,13 +143,14 @@ static struct mlx5_cmd_layout *get_inst(
 	return cmd->cmd_buf + (idx << cmd->log_stride);
 }
 
-static u8 xor8_buf(void *buf, int len)
+static u8 xor8_buf(void *buf, size_t offset, int len)
 {
 	u8 *ptr = buf;
 	u8 sum = 0;
 	int i;
+	int end = len + offset;
 
-	for (i = 0; i < len; i++)
+	for (i = offset; i < end; i++)
 		sum ^= ptr[i];
 
 	return sum;
@@ -157,41 +158,49 @@ static u8 xor8_buf(void *buf, int len)
 
 static int verify_block_sig(struct mlx5_cmd_prot_block *block)
 {
-	if (xor8_buf(block->rsvd0, sizeof(*block) - sizeof(block->data) - 1) != 0xff)
+	size_t rsvd0_off = offsetof(struct mlx5_cmd_prot_block, rsvd0);
+	int xor_len = sizeof(*block) - sizeof(block->data) - 1;
+
+	if (xor8_buf(block, rsvd0_off, xor_len) != 0xff)
 		return -EINVAL;
 
-	if (xor8_buf(block, sizeof(*block)) != 0xff)
+	if (xor8_buf(block, 0, sizeof(*block)) != 0xff)
 		return -EINVAL;
 
 	return 0;
 }
 
-static void calc_block_sig(struct mlx5_cmd_prot_block *block, u8 token,
-			   int csum)
+static void calc_block_sig(struct mlx5_cmd_prot_block *block)
 {
-	block->token = token;
-	if (csum) {
-		block->ctrl_sig = ~xor8_buf(block->rsvd0, sizeof(*block) -
-					    sizeof(block->data) - 2);
-		block->sig = ~xor8_buf(block, sizeof(*block) - 1);
-	}
+	int ctrl_xor_len = sizeof(*block) - sizeof(block->data) - 2;
+	size_t rsvd0_off = offsetof(struct mlx5_cmd_prot_block, rsvd0);
+
+	block->ctrl_sig = ~xor8_buf(block, rsvd0_off, ctrl_xor_len);
+	block->sig = ~xor8_buf(block, 0, sizeof(*block) - 1);
 }
 
-static void calc_chain_sig(struct mlx5_cmd_msg *msg, u8 token, int csum)
+static void calc_chain_sig(struct mlx5_cmd_msg *msg)
 {
 	struct mlx5_cmd_mailbox *next = msg->next;
+	int size = msg->len;
+	int blen = size - min_t(int, sizeof(msg->first.data), size);
+	int n = (blen + MLX5_CMD_DATA_BLOCK_SIZE - 1)
+		/ MLX5_CMD_DATA_BLOCK_SIZE;
+	int i = 0;
 
-	while (next) {
-		calc_block_sig(next->buf, token, csum);
+	for (i = 0; i < n && next; i++)  {
+		calc_block_sig(next->buf);
 		next = next->next;
 	}
 }
 
 static void set_signature(struct mlx5_cmd_work_ent *ent, int csum)
 {
-	ent->lay->sig = ~xor8_buf(ent->lay, sizeof(*ent->lay));
-	calc_chain_sig(ent->in, ent->token, csum);
-	calc_chain_sig(ent->out, ent->token, csum);
+	ent->lay->sig = ~xor8_buf(ent->lay, 0,  sizeof(*ent->lay));
+	if (csum) {
+		calc_chain_sig(ent->in);
+		calc_chain_sig(ent->out);
+	}
 }
 
 static void poll_timeout(struct mlx5_cmd_work_ent *ent)
@@ -222,12 +231,17 @@ static int verify_signature(struct mlx5_
 	struct mlx5_cmd_mailbox *next = ent->out->next;
 	int err;
 	u8 sig;
+	int size = ent->out->len;
+	int blen = size - min_t(int, sizeof(ent->out->first.data), size);
+	int n = (blen + MLX5_CMD_DATA_BLOCK_SIZE - 1)
+		/ MLX5_CMD_DATA_BLOCK_SIZE;
+	int i = 0;
 
-	sig = xor8_buf(ent->lay, sizeof(*ent->lay));
+	sig = xor8_buf(ent->lay, 0, sizeof(*ent->lay));
 	if (sig != 0xff)
 		return -EINVAL;
 
-	while (next) {
+	for (i = 0; i < n && next; i++) {
 		err = verify_block_sig(next->buf);
 		if (err)
 			return err;
@@ -641,7 +655,6 @@ static void cmd_work_handler(struct work
 		spin_unlock_irqrestore(&cmd->alloc_lock, flags);
 	}
 
-	ent->token = alloc_token(cmd);
 	cmd->ent_arr[ent->idx] = ent;
 	lay = get_inst(cmd, ent->idx);
 	ent->lay = lay;
@@ -755,7 +768,8 @@ static u8 *get_status_ptr(struct mlx5_ou
 static int mlx5_cmd_invoke(struct mlx5_core_dev *dev, struct mlx5_cmd_msg *in,
 			   struct mlx5_cmd_msg *out, void *uout, int uout_size,
 			   mlx5_cmd_cbk_t callback,
-			   void *context, int page_queue, u8 *status)
+			   void *context, int page_queue, u8 *status,
+			   u8 token)
 {
 	struct mlx5_cmd *cmd = &dev->cmd;
 	struct mlx5_cmd_work_ent *ent;
@@ -772,6 +786,8 @@ static int mlx5_cmd_invoke(struct mlx5_c
 	if (IS_ERR(ent))
 		return PTR_ERR(ent);
 
+	ent->token = token;
+
 	if (!callback)
 		init_completion(&ent->done);
 
@@ -844,7 +860,8 @@ static const struct file_operations fops
 	.write	= dbg_write,
 };
 
-static int mlx5_copy_to_msg(struct mlx5_cmd_msg *to, void *from, int size)
+static int mlx5_copy_to_msg(struct mlx5_cmd_msg *to, void *from, int size,
+			    u8 token)
 {
 	struct mlx5_cmd_prot_block *block;
 	struct mlx5_cmd_mailbox *next;
@@ -870,6 +887,7 @@ static int mlx5_copy_to_msg(struct mlx5_
 		memcpy(block->data, from, copy);
 		from += copy;
 		size -= copy;
+		block->token = token;
 		next = next->next;
 	}
 
@@ -939,7 +957,8 @@ static void free_cmd_box(struct mlx5_cor
 }
 
 static struct mlx5_cmd_msg *mlx5_alloc_cmd_msg(struct mlx5_core_dev *dev,
-					       gfp_t flags, int size)
+					       gfp_t flags, int size,
+					       u8 token)
 {
 	struct mlx5_cmd_mailbox *tmp, *head = NULL;
 	struct mlx5_cmd_prot_block *block;
@@ -968,6 +987,7 @@ static struct mlx5_cmd_msg *mlx5_alloc_c
 		tmp->next = head;
 		block->next = cpu_to_be64(tmp->next ? tmp->next->dma : 0);
 		block->block_num = cpu_to_be32(n - i - 1);
+		block->token = token;
 		head = tmp;
 	}
 	msg->next = head;
@@ -1351,7 +1371,7 @@ static struct mlx5_cmd_msg *alloc_msg(st
 	}
 
 	if (IS_ERR(msg))
-		msg = mlx5_alloc_cmd_msg(dev, gfp, in_size);
+		msg = mlx5_alloc_cmd_msg(dev, gfp, in_size, 0);
 
 	return msg;
 }
@@ -1376,6 +1396,7 @@ static int cmd_exec(struct mlx5_core_dev
 	int err;
 	u8 status = 0;
 	u32 drv_synd;
+	u8 token;
 
 	if (pci_channel_offline(dev->pdev) ||
 	    dev->state == MLX5_DEVICE_STATE_INTERNAL_ERROR) {
@@ -1394,20 +1415,22 @@ static int cmd_exec(struct mlx5_core_dev
 		return err;
 	}
 
-	err = mlx5_copy_to_msg(inb, in, in_size);
+	token = alloc_token(&dev->cmd);
+
+	err = mlx5_copy_to_msg(inb, in, in_size, token);
 	if (err) {
 		mlx5_core_warn(dev, "err %d\n", err);
 		goto out_in;
 	}
 
-	outb = mlx5_alloc_cmd_msg(dev, gfp, out_size);
+	outb = mlx5_alloc_cmd_msg(dev, gfp, out_size, token);
 	if (IS_ERR(outb)) {
 		err = PTR_ERR(outb);
 		goto out_in;
 	}
 
 	err = mlx5_cmd_invoke(dev, inb, outb, out, out_size, callback, context,
-			      pages_queue, &status);
+			      pages_queue, &status, token);
 	if (err)
 		goto out_out;
 
@@ -1475,7 +1498,7 @@ static int create_msg_cache(struct mlx5_
 	INIT_LIST_HEAD(&cmd->cache.med.head);
 
 	for (i = 0; i < NUM_LONG_LISTS; i++) {
-		msg = mlx5_alloc_cmd_msg(dev, GFP_KERNEL, LONG_LIST_SIZE);
+		msg = mlx5_alloc_cmd_msg(dev, GFP_KERNEL, LONG_LIST_SIZE, 0);
 		if (IS_ERR(msg)) {
 			err = PTR_ERR(msg);
 			goto ex_err;
@@ -1485,7 +1508,7 @@ static int create_msg_cache(struct mlx5_
 	}
 
 	for (i = 0; i < NUM_MED_LISTS; i++) {
-		msg = mlx5_alloc_cmd_msg(dev, GFP_KERNEL, MED_LIST_SIZE);
+		msg = mlx5_alloc_cmd_msg(dev, GFP_KERNEL, MED_LIST_SIZE, 0);
 		if (IS_ERR(msg)) {
 			err = PTR_ERR(msg);
 			goto ex_err;
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/mellanox/mlx5/core/en.h
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/mellanox/mlx5/core/en.h
@@ -35,6 +35,7 @@
 #include <linux/mlx5/driver.h>
 #include <linux/mlx5/qp.h>
 #include <linux/mlx5/cq.h>
+#include <linux/mlx5/port.h>
 #include <linux/mlx5/vport.h>
 #include "wq.h"
 #include "transobj.h"
@@ -465,6 +466,7 @@ enum {
 };
 
 struct mlx5e_vlan_db {
+	unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)];
 	u32           active_vlans_ft_ix[VLAN_N_VID];
 	u32           untagged_rule_ft_ix;
 	u32           any_vlan_rule_ft_ix;
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c
@@ -399,6 +399,9 @@ static int mlx5e_get_coalesce(struct net
 {
 	struct mlx5e_priv *priv = netdev_priv(netdev);
 
+	if (!MLX5_CAP_GEN(priv->mdev, cq_moderation))
+		return -ENOTSUPP;
+
 	coal->rx_coalesce_usecs       = priv->params.rx_cq_moderation_usec;
 	coal->rx_max_coalesced_frames = priv->params.rx_cq_moderation_pkts;
 	coal->tx_coalesce_usecs       = priv->params.tx_cq_moderation_usec;
@@ -416,11 +419,18 @@ static int mlx5e_set_coalesce(struct net
 	int tc;
 	int i;
 
+	if (!MLX5_CAP_GEN(mdev, cq_moderation))
+		return -ENOTSUPP;
+
+	mutex_lock(&priv->state_lock);
 	priv->params.tx_cq_moderation_usec = coal->tx_coalesce_usecs;
 	priv->params.tx_cq_moderation_pkts = coal->tx_max_coalesced_frames;
 	priv->params.rx_cq_moderation_usec = coal->rx_coalesce_usecs;
 	priv->params.rx_cq_moderation_pkts = coal->rx_max_coalesced_frames;
 
+	if (!test_bit(MLX5E_STATE_OPENED, &priv->state))
+		goto out;
+
 	for (i = 0; i < priv->params.num_channels; ++i) {
 		c = priv->channel[i];
 
@@ -436,6 +446,8 @@ static int mlx5e_set_coalesce(struct net
 					       coal->rx_max_coalesced_frames);
 	}
 
+out:
+	mutex_unlock(&priv->state_lock);
 	return 0;
 }
 
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/mellanox/mlx5/core/en_flow_table.c
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/mellanox/mlx5/core/en_flow_table.c
@@ -502,6 +502,49 @@ add_eth_addr_rule_out:
 	return err;
 }
 
+static int mlx5e_vport_context_update_vlans(struct mlx5e_priv *priv)
+{
+	struct net_device *ndev = priv->netdev;
+	int max_list_size;
+	int list_size;
+	u16 *vlans;
+	int vlan;
+	int err;
+	int i;
+
+	list_size = 0;
+	for_each_set_bit(vlan, priv->vlan.active_vlans, VLAN_N_VID)
+		list_size++;
+
+	max_list_size = 1 << MLX5_CAP_GEN(priv->mdev, log_max_vlan_list);
+
+	if (list_size > max_list_size) {
+		netdev_warn(ndev,
+			    "netdev vlans list size (%d) > (%d) max vport list size, some vlans will be dropped\n",
+			    list_size, max_list_size);
+		list_size = max_list_size;
+	}
+
+	vlans = kcalloc(list_size, sizeof(*vlans), GFP_KERNEL);
+	if (!vlans)
+		return -ENOMEM;
+
+	i = 0;
+	for_each_set_bit(vlan, priv->vlan.active_vlans, VLAN_N_VID) {
+		if (i >= list_size)
+			break;
+		vlans[i++] = vlan;
+	}
+
+	err = mlx5_modify_nic_vport_vlans(priv->mdev, vlans, list_size);
+	if (err)
+		netdev_err(ndev, "Failed to modify vport vlans list err(%d)\n",
+			   err);
+
+	kfree(vlans);
+	return err;
+}
+
 enum mlx5e_vlan_rule_type {
 	MLX5E_VLAN_RULE_TYPE_UNTAGGED,
 	MLX5E_VLAN_RULE_TYPE_ANY_VID,
@@ -552,6 +595,10 @@ static int mlx5e_add_vlan_rule(struct ml
 			 1);
 		break;
 	default: /* MLX5E_VLAN_RULE_TYPE_MATCH_VID */
+		err = mlx5e_vport_context_update_vlans(priv);
+		if (err)
+			goto add_vlan_rule_out;
+
 		ft_ix = &priv->vlan.active_vlans_ft_ix[vid];
 		MLX5_SET(fte_match_param, match_value, outer_headers.vlan_tag,
 			 1);
@@ -588,6 +635,7 @@ static void mlx5e_del_vlan_rule(struct m
 	case MLX5E_VLAN_RULE_TYPE_MATCH_VID:
 		mlx5_del_flow_table_entry(priv->ft.vlan,
 					  priv->vlan.active_vlans_ft_ix[vid]);
+		mlx5e_vport_context_update_vlans(priv);
 		break;
 	}
 }
@@ -619,6 +667,8 @@ int mlx5e_vlan_rx_add_vid(struct net_dev
 {
 	struct mlx5e_priv *priv = netdev_priv(dev);
 
+	set_bit(vid, priv->vlan.active_vlans);
+
 	return mlx5e_add_vlan_rule(priv, MLX5E_VLAN_RULE_TYPE_MATCH_VID, vid);
 }
 
@@ -627,6 +677,8 @@ int mlx5e_vlan_rx_kill_vid(struct net_de
 {
 	struct mlx5e_priv *priv = netdev_priv(dev);
 
+	clear_bit(vid, priv->vlan.active_vlans);
+
 	mlx5e_del_vlan_rule(priv, MLX5E_VLAN_RULE_TYPE_MATCH_VID, vid);
 
 	return 0;
@@ -671,6 +723,91 @@ static void mlx5e_sync_netdev_addr(struc
 	netif_addr_unlock_bh(netdev);
 }
 
+static void mlx5e_fill_addr_array(struct mlx5e_priv *priv, int list_type,
+				  u8 addr_array[][ETH_ALEN], int size)
+{
+	bool is_uc = (list_type == MLX5_NVPRT_LIST_TYPE_UC);
+	struct net_device *ndev = priv->netdev;
+	struct mlx5e_eth_addr_hash_node *hn;
+	struct hlist_head *addr_list;
+	struct hlist_node *tmp;
+	int i = 0;
+	int hi;
+
+	addr_list = is_uc ? priv->eth_addr.netdev_uc : priv->eth_addr.netdev_mc;
+
+	if (is_uc) /* Make sure our own address is pushed first */
+		ether_addr_copy(addr_array[i++], ndev->dev_addr);
+	else if (priv->eth_addr.broadcast_enabled)
+		ether_addr_copy(addr_array[i++], ndev->broadcast);
+
+	mlx5e_for_each_hash_node(hn, tmp, addr_list, hi) {
+		if (ether_addr_equal(ndev->dev_addr, hn->ai.addr))
+			continue;
+		if (i >= size)
+			break;
+		ether_addr_copy(addr_array[i++], hn->ai.addr);
+	}
+}
+
+static void mlx5e_vport_context_update_addr_list(struct mlx5e_priv *priv,
+						 int list_type)
+{
+	bool is_uc = (list_type == MLX5_NVPRT_LIST_TYPE_UC);
+	struct mlx5e_eth_addr_hash_node *hn;
+	u8 (*addr_array)[ETH_ALEN] = NULL;
+	struct hlist_head *addr_list;
+	struct hlist_node *tmp;
+	int max_size;
+	int size;
+	int err;
+	int hi;
+
+	size = is_uc ? 0 : (priv->eth_addr.broadcast_enabled ? 1 : 0);
+	max_size = is_uc ?
+		1 << MLX5_CAP_GEN(priv->mdev, log_max_current_uc_list) :
+		1 << MLX5_CAP_GEN(priv->mdev, log_max_current_mc_list);
+
+	addr_list = is_uc ? priv->eth_addr.netdev_uc : priv->eth_addr.netdev_mc;
+	mlx5e_for_each_hash_node(hn, tmp, addr_list, hi)
+		size++;
+
+	if (size > max_size) {
+		netdev_warn(priv->netdev,
+			    "netdev %s list size (%d) > (%d) max vport list size, some addresses will be dropped\n",
+			    is_uc ? "UC" : "MC", size, max_size);
+		size = max_size;
+	}
+
+	if (size) {
+		addr_array = kcalloc(size, ETH_ALEN, GFP_KERNEL);
+		if (!addr_array) {
+			err = -ENOMEM;
+			goto out;
+		}
+		mlx5e_fill_addr_array(priv, list_type, addr_array, size);
+	}
+
+	err = mlx5_modify_nic_vport_mac_list(priv->mdev, list_type, addr_array, size);
+out:
+	if (err)
+		netdev_err(priv->netdev,
+			   "Failed to modify vport %s list err(%d)\n",
+			   is_uc ? "UC" : "MC", err);
+	kfree(addr_array);
+}
+
+static void mlx5e_vport_context_update(struct mlx5e_priv *priv)
+{
+	struct mlx5e_eth_addr_db *ea = &priv->eth_addr;
+
+	mlx5e_vport_context_update_addr_list(priv, MLX5_NVPRT_LIST_TYPE_UC);
+	mlx5e_vport_context_update_addr_list(priv, MLX5_NVPRT_LIST_TYPE_MC);
+	mlx5_modify_nic_vport_promisc(priv->mdev, 0,
+				      ea->allmulti_enabled,
+				      ea->promisc_enabled);
+}
+
 static void mlx5e_apply_netdev_addr(struct mlx5e_priv *priv)
 {
 	struct mlx5e_eth_addr_hash_node *hn;
@@ -748,6 +885,8 @@ void mlx5e_set_rx_mode_work(struct work_
 	ea->promisc_enabled   = promisc_enabled;
 	ea->allmulti_enabled  = allmulti_enabled;
 	ea->broadcast_enabled = broadcast_enabled;
+
+	mlx5e_vport_context_update(priv);
 }
 
 void mlx5e_init_eth_addr(struct mlx5e_priv *priv)
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
@@ -32,6 +32,7 @@
 
 #include <linux/mlx5/flow_table.h>
 #include "en.h"
+#include "eswitch.h"
 
 struct mlx5e_rq_param {
 	u32                        rqc[MLX5_ST_SZ_DW(rqc)];
@@ -63,7 +64,7 @@ static void mlx5e_update_carrier(struct
 	u8 port_state;
 
 	port_state = mlx5_query_vport_state(mdev,
-		MLX5_QUERY_VPORT_STATE_IN_OP_MOD_VNIC_VPORT);
+		MLX5_QUERY_VPORT_STATE_IN_OP_MOD_VNIC_VPORT, 0);
 
 	if (port_state == VPORT_STATE_UP)
 		netif_carrier_on(priv->netdev);
@@ -746,7 +747,7 @@ static int mlx5e_create_cq(struct mlx5e_
 	struct mlx5_core_dev *mdev = priv->mdev;
 	struct mlx5_core_cq *mcq = &cq->mcq;
 	int eqn_not_used;
-	int irqn;
+	unsigned int irqn;
 	int err;
 	u32 i;
 
@@ -800,7 +801,7 @@ static int mlx5e_enable_cq(struct mlx5e_
 	void *in;
 	void *cqc;
 	int inlen;
-	int irqn_not_used;
+	unsigned int irqn_not_used;
 	int eqn;
 	int err;
 
@@ -863,12 +864,10 @@ static int mlx5e_open_cq(struct mlx5e_ch
 	if (err)
 		goto err_destroy_cq;
 
-	err = mlx5_core_modify_cq_moderation(mdev, &cq->mcq,
-					     moderation_usecs,
-					     moderation_frames);
-	if (err)
-		goto err_destroy_cq;
-
+	if (MLX5_CAP_GEN(mdev, cq_moderation))
+		mlx5_core_modify_cq_moderation(mdev, &cq->mcq,
+					       moderation_usecs,
+					       moderation_frames);
 	return 0;
 
 err_destroy_cq:
@@ -1372,7 +1371,7 @@ static int mlx5e_set_dev_port_mtu(struct
 {
 	struct mlx5e_priv *priv = netdev_priv(netdev);
 	struct mlx5_core_dev *mdev = priv->mdev;
-	int hw_mtu;
+	u16 hw_mtu;
 	int err;
 
 	err = mlx5_set_port_mtu(mdev, MLX5E_SW2HW_MTU(netdev->mtu), 1);
@@ -1504,7 +1503,7 @@ static int mlx5e_create_drop_cq(struct m
 	struct mlx5_core_dev *mdev = priv->mdev;
 	struct mlx5_core_cq *mcq = &cq->mcq;
 	int eqn_not_used;
-	int irqn;
+	unsigned int irqn;
 	int err;
 
 	err = mlx5_cqwq_create(mdev, &param->wq, param->cqc, &cq->wq,
@@ -1891,22 +1890,27 @@ static int mlx5e_set_features(struct net
 	return err;
 }
 
+#define MXL5_HW_MIN_MTU 64
+#define MXL5E_MIN_MTU (MXL5_HW_MIN_MTU + ETH_FCS_LEN)
+
 static int mlx5e_change_mtu(struct net_device *netdev, int new_mtu)
 {
 	struct mlx5e_priv *priv = netdev_priv(netdev);
 	struct mlx5_core_dev *mdev = priv->mdev;
 	bool was_opened;
-	int max_mtu;
+	u16 max_mtu;
+	u16 min_mtu;
 	int err = 0;
 
 	mlx5_query_port_max_mtu(mdev, &max_mtu, 1);
 
 	max_mtu = MLX5E_HW2SW_MTU(max_mtu);
+	min_mtu = MLX5E_HW2SW_MTU(MXL5E_MIN_MTU);
 
-	if (new_mtu > max_mtu) {
+	if (new_mtu > max_mtu || new_mtu < min_mtu) {
 		netdev_err(netdev,
-			   "%s: Bad MTU (%d) > (%d) Max\n",
-			   __func__, new_mtu, max_mtu);
+			   "%s: Bad MTU (%d), valid range is: [%d..%d]\n",
+			   __func__, new_mtu, min_mtu, max_mtu);
 		return -EINVAL;
 	}
 
@@ -1926,6 +1930,79 @@ static int mlx5e_change_mtu(struct net_d
 	return err;
 }
 
+static int mlx5e_set_vf_mac(struct net_device *dev, int vf, u8 *mac)
+{
+	struct mlx5e_priv *priv = netdev_priv(dev);
+	struct mlx5_core_dev *mdev = priv->mdev;
+
+	return mlx5_eswitch_set_vport_mac(mdev->priv.eswitch, vf + 1, mac);
+}
+
+static int mlx5e_set_vf_vlan(struct net_device *dev, int vf, u16 vlan, u8 qos)
+{
+	struct mlx5e_priv *priv = netdev_priv(dev);
+	struct mlx5_core_dev *mdev = priv->mdev;
+
+	return mlx5_eswitch_set_vport_vlan(mdev->priv.eswitch, vf + 1,
+					   vlan, qos);
+}
+
+static int mlx5_vport_link2ifla(u8 esw_link)
+{
+	switch (esw_link) {
+	case MLX5_ESW_VPORT_ADMIN_STATE_DOWN:
+		return IFLA_VF_LINK_STATE_DISABLE;
+	case MLX5_ESW_VPORT_ADMIN_STATE_UP:
+		return IFLA_VF_LINK_STATE_ENABLE;
+	}
+	return IFLA_VF_LINK_STATE_AUTO;
+}
+
+static int mlx5_ifla_link2vport(u8 ifla_link)
+{
+	switch (ifla_link) {
+	case IFLA_VF_LINK_STATE_DISABLE:
+		return MLX5_ESW_VPORT_ADMIN_STATE_DOWN;
+	case IFLA_VF_LINK_STATE_ENABLE:
+		return MLX5_ESW_VPORT_ADMIN_STATE_UP;
+	}
+	return MLX5_ESW_VPORT_ADMIN_STATE_AUTO;
+}
+
+static int mlx5e_set_vf_link_state(struct net_device *dev, int vf,
+				   int link_state)
+{
+	struct mlx5e_priv *priv = netdev_priv(dev);
+	struct mlx5_core_dev *mdev = priv->mdev;
+
+	return mlx5_eswitch_set_vport_state(mdev->priv.eswitch, vf + 1,
+					    mlx5_ifla_link2vport(link_state));
+}
+
+static int mlx5e_get_vf_config(struct net_device *dev,
+			       int vf, struct ifla_vf_info *ivi)
+{
+	struct mlx5e_priv *priv = netdev_priv(dev);
+	struct mlx5_core_dev *mdev = priv->mdev;
+	int err;
+
+	err = mlx5_eswitch_get_vport_config(mdev->priv.eswitch, vf + 1, ivi);
+	if (err)
+		return err;
+	ivi->linkstate = mlx5_vport_link2ifla(ivi->linkstate);
+	return 0;
+}
+
+static int mlx5e_get_vf_stats(struct net_device *dev,
+			      int vf, struct ifla_vf_stats *vf_stats)
+{
+	struct mlx5e_priv *priv = netdev_priv(dev);
+	struct mlx5_core_dev *mdev = priv->mdev;
+
+	return mlx5_eswitch_get_vport_stats(mdev->priv.eswitch, vf + 1,
+					    vf_stats);
+}
+
 static struct net_device_ops mlx5e_netdev_ops = {
 	.ndo_open                = mlx5e_open,
 	.ndo_stop                = mlx5e_close,
@@ -1936,7 +2013,7 @@ static struct net_device_ops mlx5e_netde
 	.ndo_vlan_rx_add_vid	 = mlx5e_vlan_rx_add_vid,
 	.ndo_vlan_rx_kill_vid	 = mlx5e_vlan_rx_kill_vid,
 	.ndo_set_features        = mlx5e_set_features,
-	.ndo_change_mtu		 = mlx5e_change_mtu,
+	.ndo_change_mtu		 = mlx5e_change_mtu
 };
 
 static int mlx5e_check_required_hca_cap(struct mlx5_core_dev *mdev)
@@ -1958,6 +2035,8 @@ static int mlx5e_check_required_hca_cap(
 	}
 	if (!MLX5_CAP_ETH(mdev, self_lb_en_modifiable))
 		mlx5_core_warn(mdev, "Self loop back prevention is not supported\n");
+	if (!MLX5_CAP_GEN(mdev, cq_moderation))
+		mlx5_core_warn(mdev, "CQ modiration is not supported\n");
 
 	return 0;
 }
@@ -2023,7 +2102,12 @@ static void mlx5e_set_netdev_dev_addr(st
 {
 	struct mlx5e_priv *priv = netdev_priv(netdev);
 
-	mlx5_query_nic_vport_mac_address(priv->mdev, netdev->dev_addr);
+	mlx5_query_nic_vport_mac_address(priv->mdev, 0, netdev->dev_addr);
+	if (is_zero_ether_addr(netdev->dev_addr) &&
+	    !MLX5_CAP_GEN(priv->mdev, vport_group_manager)) {
+		eth_hw_addr_random(netdev);
+		mlx5_core_info(priv->mdev, "Assigned random MAC address %pM\n", netdev->dev_addr);
+	}
 }
 
 static void mlx5e_build_netdev(struct net_device *netdev)
@@ -2036,6 +2120,14 @@ static void mlx5e_build_netdev(struct ne
 	if (priv->params.num_tc > 1)
 		mlx5e_netdev_ops.ndo_select_queue = mlx5e_select_queue;
 
+	if (MLX5_CAP_GEN(mdev, vport_group_manager)) {
+		mlx5e_netdev_ops.ndo_set_vf_mac = mlx5e_set_vf_mac;
+		mlx5e_netdev_ops.ndo_set_vf_vlan = mlx5e_set_vf_vlan;
+		mlx5e_netdev_ops.ndo_get_vf_config = mlx5e_get_vf_config;
+		mlx5e_netdev_ops.ndo_set_vf_link_state = mlx5e_set_vf_link_state;
+		mlx5e_netdev_ops.ndo_get_vf_stats = mlx5e_get_vf_stats;
+	}
+
 	netdev->netdev_ops        = &mlx5e_netdev_ops;
 	netdev->watchdog_timeo    = 15 * HZ;
 
@@ -2236,7 +2328,16 @@ static void mlx5e_destroy_netdev(struct
 	schedule_work(&priv->set_rx_mode_work);
 	mlx5e_disable_async_events(priv);
 	flush_scheduled_work();
-	unregister_netdev(netdev);
+	if (test_bit(MLX5_INTERFACE_STATE_SHUTDOWN, &mdev->intf_state)) {
+		netif_device_detach(netdev);
+		mutex_lock(&priv->state_lock);
+		if (test_bit(MLX5E_STATE_OPENED, &priv->state))
+			mlx5e_close_locked(netdev);
+		mutex_unlock(&priv->state_lock);
+	} else {
+		unregister_netdev(netdev);
+	}
+
 	mlx5e_destroy_flow_tables(priv);
 	mlx5e_destroy_tirs(priv);
 	mlx5e_destroy_rqt(priv, MLX5E_SINGLE_RQ_RQT);
@@ -2247,7 +2348,9 @@ static void mlx5e_destroy_netdev(struct
 	mlx5_dealloc_transport_domain(priv->mdev, priv->tdn);
 	mlx5_core_dealloc_pd(priv->mdev, priv->pdn);
 	mlx5_unmap_free_uar(priv->mdev, &priv->cq_uar);
-	free_netdev(netdev);
+
+	if (!test_bit(MLX5_INTERFACE_STATE_SHUTDOWN, &mdev->intf_state))
+		free_netdev(netdev);
 }
 
 static void *mlx5e_get_netdev(void *vpriv)
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/mellanox/mlx5/core/eq.c
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/mellanox/mlx5/core/eq.c
@@ -35,6 +35,9 @@
 #include <linux/mlx5/driver.h>
 #include <linux/mlx5/cmd.h>
 #include "mlx5_core.h"
+#ifdef CONFIG_MLX5_CORE_EN
+#include "eswitch.h"
+#endif
 
 enum {
 	MLX5_EQE_SIZE		= sizeof(struct mlx5_eqe),
@@ -287,6 +290,11 @@ static int mlx5_eq_int(struct mlx5_core_
 			break;
 #endif
 
+#ifdef CONFIG_MLX5_CORE_EN
+		case MLX5_EVENT_TYPE_NIC_VPORT_CHANGE:
+			mlx5_eswitch_vport_event(dev->priv.eswitch, eqe);
+			break;
+#endif
 		default:
 			mlx5_core_warn(dev, "Unhandled event 0x%x on EQ 0x%x\n",
 				       eqe->type, eq->eqn);
@@ -459,6 +467,11 @@ int mlx5_start_eqs(struct mlx5_core_dev
 	if (MLX5_CAP_GEN(dev, pg))
 		async_event_mask |= (1ull << MLX5_EVENT_TYPE_PAGE_FAULT);
 
+	if (MLX5_CAP_GEN(dev, port_type) == MLX5_CAP_PORT_TYPE_ETH &&
+	    MLX5_CAP_GEN(dev, vport_group_manager) &&
+	    mlx5_core_is_pf(dev))
+		async_event_mask |= (1ull << MLX5_EVENT_TYPE_NIC_VPORT_CHANGE);
+
 	err = mlx5_create_map_eq(dev, &table->cmd_eq, MLX5_EQ_VEC_CMD,
 				 MLX5_NUM_CMD_EQE, 1ull << MLX5_EVENT_TYPE_CMD,
 				 "mlx5_cmd_eq", &dev->priv.uuari.uars[0]);
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c
@@ -0,0 +1,1282 @@
+/*
+ * Copyright (c) 2015, Mellanox Technologies. All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include <linux/etherdevice.h>
+#include <linux/mlx5/driver.h>
+#include <linux/mlx5/mlx5_ifc.h>
+#include <linux/mlx5/vport.h>
+#include <linux/mlx5/flow_table.h>
+#include "mlx5_core.h"
+#include "eswitch.h"
+
+#define UPLINK_VPORT 0xFFFF
+
+#define MLX5_DEBUG_ESWITCH_MASK BIT(3)
+
+#define esw_info(dev, format, ...)				\
+	pr_info("(%s): E-Switch: " format, (dev)->priv.name, ##__VA_ARGS__)
+
+#define esw_warn(dev, format, ...)				\
+	pr_warn("(%s): E-Switch: " format, (dev)->priv.name, ##__VA_ARGS__)
+
+#define esw_debug(dev, format, ...)				\
+	mlx5_core_dbg_mask(dev, MLX5_DEBUG_ESWITCH_MASK, format, ##__VA_ARGS__)
+
+enum {
+	MLX5_ACTION_NONE = 0,
+	MLX5_ACTION_ADD  = 1,
+	MLX5_ACTION_DEL  = 2,
+};
+
+/* E-Switch UC L2 table hash node */
+struct esw_uc_addr {
+	struct l2addr_node node;
+	u32                table_index;
+	u32                vport;
+};
+
+/* E-Switch MC FDB table hash node */
+struct esw_mc_addr { /* SRIOV only */
+	struct l2addr_node     node;
+	struct mlx5_flow_rule *uplink_rule; /* Forward to uplink rule */
+	u32                    refcnt;
+};
+
+/* Vport UC/MC hash node */
+struct vport_addr {
+	struct l2addr_node     node;
+	u8                     action;
+	u32                    vport;
+	struct mlx5_flow_rule *flow_rule; /* SRIOV only */
+};
+
+enum {
+	UC_ADDR_CHANGE = BIT(0),
+	MC_ADDR_CHANGE = BIT(1),
+};
+
+/* Vport context events */
+#define SRIOV_VPORT_EVENTS (UC_ADDR_CHANGE | \
+			    MC_ADDR_CHANGE)
+
+static int arm_vport_context_events_cmd(struct mlx5_core_dev *dev, u16 vport,
+					u32 events_mask)
+{
+	int in[MLX5_ST_SZ_DW(modify_nic_vport_context_in)];
+	int out[MLX5_ST_SZ_DW(modify_nic_vport_context_out)];
+	void *nic_vport_ctx;
+	int err;
+
+	memset(out, 0, sizeof(out));
+	memset(in, 0, sizeof(in));
+
+	MLX5_SET(modify_nic_vport_context_in, in,
+		 opcode, MLX5_CMD_OP_MODIFY_NIC_VPORT_CONTEXT);
+	MLX5_SET(modify_nic_vport_context_in, in, field_select.change_event, 1);
+	MLX5_SET(modify_nic_vport_context_in, in, vport_number, vport);
+	if (vport)
+		MLX5_SET(modify_nic_vport_context_in, in, other_vport, 1);
+	nic_vport_ctx = MLX5_ADDR_OF(modify_nic_vport_context_in,
+				     in, nic_vport_context);
+
+	MLX5_SET(nic_vport_context, nic_vport_ctx, arm_change_event, 1);
+
+	if (events_mask & UC_ADDR_CHANGE)
+		MLX5_SET(nic_vport_context, nic_vport_ctx,
+			 event_on_uc_address_change, 1);
+	if (events_mask & MC_ADDR_CHANGE)
+		MLX5_SET(nic_vport_context, nic_vport_ctx,
+			 event_on_mc_address_change, 1);
+
+	err = mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out));
+	if (err)
+		goto ex;
+	err = mlx5_cmd_status_to_err_v2(out);
+	if (err)
+		goto ex;
+	return 0;
+ex:
+	return err;
+}
+
+/* E-Switch vport context HW commands */
+static int query_esw_vport_context_cmd(struct mlx5_core_dev *mdev, u32 vport,
+				       u32 *out, int outlen)
+{
+	u32 in[MLX5_ST_SZ_DW(query_esw_vport_context_in)];
+
+	memset(in, 0, sizeof(in));
+
+	MLX5_SET(query_nic_vport_context_in, in, opcode,
+		 MLX5_CMD_OP_QUERY_ESW_VPORT_CONTEXT);
+
+	MLX5_SET(query_esw_vport_context_in, in, vport_number, vport);
+	if (vport)
+		MLX5_SET(query_esw_vport_context_in, in, other_vport, 1);
+
+	return mlx5_cmd_exec_check_status(mdev, in, sizeof(in), out, outlen);
+}
+
+static int query_esw_vport_cvlan(struct mlx5_core_dev *dev, u32 vport,
+				 u16 *vlan, u8 *qos)
+{
+	u32 out[MLX5_ST_SZ_DW(query_esw_vport_context_out)];
+	int err;
+	bool cvlan_strip;
+	bool cvlan_insert;
+
+	memset(out, 0, sizeof(out));
+
+	*vlan = 0;
+	*qos = 0;
+
+	if (!MLX5_CAP_ESW(dev, vport_cvlan_strip) ||
+	    !MLX5_CAP_ESW(dev, vport_cvlan_insert_if_not_exist))
+		return -ENOTSUPP;
+
+	err = query_esw_vport_context_cmd(dev, vport, out, sizeof(out));
+	if (err)
+		goto out;
+
+	cvlan_strip = MLX5_GET(query_esw_vport_context_out, out,
+			       esw_vport_context.vport_cvlan_strip);
+
+	cvlan_insert = MLX5_GET(query_esw_vport_context_out, out,
+				esw_vport_context.vport_cvlan_insert);
+
+	if (cvlan_strip || cvlan_insert) {
+		*vlan = MLX5_GET(query_esw_vport_context_out, out,
+				 esw_vport_context.cvlan_id);
+		*qos = MLX5_GET(query_esw_vport_context_out, out,
+				esw_vport_context.cvlan_pcp);
+	}
+
+	esw_debug(dev, "Query Vport[%d] cvlan: VLAN %d qos=%d\n",
+		  vport, *vlan, *qos);
+out:
+	return err;
+}
+
+static int modify_esw_vport_context_cmd(struct mlx5_core_dev *dev, u16 vport,
+					void *in, int inlen)
+{
+	u32 out[MLX5_ST_SZ_DW(modify_esw_vport_context_out)];
+
+	memset(out, 0, sizeof(out));
+
+	MLX5_SET(modify_esw_vport_context_in, in, vport_number, vport);
+	if (vport)
+		MLX5_SET(modify_esw_vport_context_in, in, other_vport, 1);
+
+	MLX5_SET(modify_esw_vport_context_in, in, opcode,
+		 MLX5_CMD_OP_MODIFY_ESW_VPORT_CONTEXT);
+
+	return mlx5_cmd_exec_check_status(dev, in, inlen,
+					  out, sizeof(out));
+}
+
+static int modify_esw_vport_cvlan(struct mlx5_core_dev *dev, u32 vport,
+				  u16 vlan, u8 qos, bool set)
+{
+	u32 in[MLX5_ST_SZ_DW(modify_esw_vport_context_in)];
+
+	memset(in, 0, sizeof(in));
+
+	if (!MLX5_CAP_ESW(dev, vport_cvlan_strip) ||
+	    !MLX5_CAP_ESW(dev, vport_cvlan_insert_if_not_exist))
+		return -ENOTSUPP;
+
+	esw_debug(dev, "Set Vport[%d] VLAN %d qos %d set=%d\n",
+		  vport, vlan, qos, set);
+
+	if (set) {
+		MLX5_SET(modify_esw_vport_context_in, in,
+			 esw_vport_context.vport_cvlan_strip, 1);
+		/* insert only if no vlan in packet */
+		MLX5_SET(modify_esw_vport_context_in, in,
+			 esw_vport_context.vport_cvlan_insert, 1);
+		MLX5_SET(modify_esw_vport_context_in, in,
+			 esw_vport_context.cvlan_pcp, qos);
+		MLX5_SET(modify_esw_vport_context_in, in,
+			 esw_vport_context.cvlan_id, vlan);
+	}
+
+	MLX5_SET(modify_esw_vport_context_in, in,
+		 field_select.vport_cvlan_strip, 1);
+	MLX5_SET(modify_esw_vport_context_in, in,
+		 field_select.vport_cvlan_insert, 1);
+
+	return modify_esw_vport_context_cmd(dev, vport, in, sizeof(in));
+}
+
+/* HW L2 Table (MPFS) management */
+static int set_l2_table_entry_cmd(struct mlx5_core_dev *dev, u32 index,
+				  u8 *mac, u8 vlan_valid, u16 vlan)
+{
+	u32 in[MLX5_ST_SZ_DW(set_l2_table_entry_in)];
+	u32 out[MLX5_ST_SZ_DW(set_l2_table_entry_out)];
+	u8 *in_mac_addr;
+
+	memset(in, 0, sizeof(in));
+	memset(out, 0, sizeof(out));
+
+	MLX5_SET(set_l2_table_entry_in, in, opcode,
+		 MLX5_CMD_OP_SET_L2_TABLE_ENTRY);
+	MLX5_SET(set_l2_table_entry_in, in, table_index, index);
+	MLX5_SET(set_l2_table_entry_in, in, vlan_valid, vlan_valid);
+	MLX5_SET(set_l2_table_entry_in, in, vlan, vlan);
+
+	in_mac_addr = MLX5_ADDR_OF(set_l2_table_entry_in, in, mac_address);
+	ether_addr_copy(&in_mac_addr[2], mac);
+
+	return mlx5_cmd_exec_check_status(dev, in, sizeof(in),
+					  out, sizeof(out));
+}
+
+static int del_l2_table_entry_cmd(struct mlx5_core_dev *dev, u32 index)
+{
+	u32 in[MLX5_ST_SZ_DW(delete_l2_table_entry_in)];
+	u32 out[MLX5_ST_SZ_DW(delete_l2_table_entry_out)];
+
+	memset(in, 0, sizeof(in));
+	memset(out, 0, sizeof(out));
+
+	MLX5_SET(delete_l2_table_entry_in, in, opcode,
+		 MLX5_CMD_OP_DELETE_L2_TABLE_ENTRY);
+	MLX5_SET(delete_l2_table_entry_in, in, table_index, index);
+	return mlx5_cmd_exec_check_status(dev, in, sizeof(in),
+					  out, sizeof(out));
+}
+
+static int alloc_l2_table_index(struct mlx5_l2_table *l2_table, u32 *ix)
+{
+	int err = 0;
+
+	*ix = find_first_zero_bit(l2_table->bitmap, l2_table->size);
+	if (*ix >= l2_table->size)
+		err = -ENOSPC;
+	else
+		__set_bit(*ix, l2_table->bitmap);
+
+	return err;
+}
+
+static void free_l2_table_index(struct mlx5_l2_table *l2_table, u32 ix)
+{
+	__clear_bit(ix, l2_table->bitmap);
+}
+
+static int set_l2_table_entry(struct mlx5_core_dev *dev, u8 *mac,
+			      u8 vlan_valid, u16 vlan,
+			      u32 *index)
+{
+	struct mlx5_l2_table *l2_table = &dev->priv.eswitch->l2_table;
+	int err;
+
+	err = alloc_l2_table_index(l2_table, index);
+	if (err)
+		return err;
+
+	err = set_l2_table_entry_cmd(dev, *index, mac, vlan_valid, vlan);
+	if (err)
+		free_l2_table_index(l2_table, *index);
+
+	return err;
+}
+
+static void del_l2_table_entry(struct mlx5_core_dev *dev, u32 index)
+{
+	struct mlx5_l2_table *l2_table = &dev->priv.eswitch->l2_table;
+
+	del_l2_table_entry_cmd(dev, index);
+	free_l2_table_index(l2_table, index);
+}
+
+/* E-Switch FDB flow steering */
+struct dest_node {
+	struct list_head list;
+	struct mlx5_flow_destination dest;
+};
+
+static int _mlx5_flow_rule_apply(struct mlx5_flow_rule *fr)
+{
+	bool was_valid = fr->valid;
+	struct dest_node *dest_n;
+	u32 dest_list_size = 0;
+	void *in_match_value;
+	u32 *flow_context;
+	u32 flow_index;
+	int err;
+	int i;
+
+	if (list_empty(&fr->dest_list)) {
+		if (fr->valid)
+			mlx5_del_flow_table_entry(fr->ft, fr->fi);
+		fr->valid = false;
+		return 0;
+	}
+
+	list_for_each_entry(dest_n, &fr->dest_list, list)
+		dest_list_size++;
+
+	flow_context = mlx5_vzalloc(MLX5_ST_SZ_BYTES(flow_context) +
+				    MLX5_ST_SZ_BYTES(dest_format_struct) *
+				    dest_list_size);
+	if (!flow_context)
+		return -ENOMEM;
+
+	MLX5_SET(flow_context, flow_context, flow_tag, fr->flow_tag);
+	MLX5_SET(flow_context, flow_context, action, fr->action);
+	MLX5_SET(flow_context, flow_context, destination_list_size,
+		 dest_list_size);
+
+	i = 0;
+	list_for_each_entry(dest_n, &fr->dest_list, list) {
+		void *dest_addr = MLX5_ADDR_OF(flow_context, flow_context,
+					       destination[i++]);
+
+		MLX5_SET(dest_format_struct, dest_addr, destination_type,
+			 dest_n->dest.type);
+		MLX5_SET(dest_format_struct, dest_addr, destination_id,
+			 dest_n->dest.vport_num);
+	}
+
+	in_match_value = MLX5_ADDR_OF(flow_context, flow_context, match_value);
+	memcpy(in_match_value, fr->match_value, MLX5_ST_SZ_BYTES(fte_match_param));
+
+	err = mlx5_add_flow_table_entry(fr->ft, fr->match_criteria_enable,
+					fr->match_criteria, flow_context,
+					&flow_index);
+	if (!err) {
+		if (was_valid)
+			mlx5_del_flow_table_entry(fr->ft, fr->fi);
+		fr->fi = flow_index;
+		fr->valid = true;
+	}
+	kfree(flow_context);
+	return err;
+}
+
+static int mlx5_flow_rule_add_dest(struct mlx5_flow_rule *fr,
+				   struct mlx5_flow_destination *new_dest)
+{
+	struct dest_node *dest_n;
+	int err;
+
+	dest_n = kzalloc(sizeof(*dest_n), GFP_KERNEL);
+	if (!dest_n)
+		return -ENOMEM;
+
+	memcpy(&dest_n->dest, new_dest, sizeof(dest_n->dest));
+	mutex_lock(&fr->mutex);
+	list_add(&dest_n->list, &fr->dest_list);
+	err = _mlx5_flow_rule_apply(fr);
+	if (err) {
+		list_del(&dest_n->list);
+		kfree(dest_n);
+	}
+	mutex_unlock(&fr->mutex);
+	return err;
+}
+
+static int mlx5_flow_rule_del_dest(struct mlx5_flow_rule *fr,
+				   struct mlx5_flow_destination *dest)
+{
+	struct dest_node *dest_n;
+	struct dest_node *n;
+	int err;
+
+	mutex_lock(&fr->mutex);
+	list_for_each_entry_safe(dest_n, n, &fr->dest_list, list) {
+		if (dest->vport_num == dest_n->dest.vport_num)
+			goto found;
+	}
+	mutex_unlock(&fr->mutex);
+	return -ENOENT;
+
+found:
+	list_del(&dest_n->list);
+	err = _mlx5_flow_rule_apply(fr);
+	mutex_unlock(&fr->mutex);
+	kfree(dest_n);
+
+	return err;
+}
+
+static struct mlx5_flow_rule *find_fr(struct mlx5_eswitch *esw,
+				      u8 match_criteria_enable,
+				      u32 *match_value)
+{
+	struct hlist_head *hash = esw->mc_table;
+	struct esw_mc_addr *esw_mc;
+	u8 *dmac_v;
+
+	dmac_v = MLX5_ADDR_OF(fte_match_param, match_value,
+			      outer_headers.dmac_47_16);
+
+	/* UNICAST FULL MATCH */
+	if (!is_multicast_ether_addr(dmac_v))
+		return NULL;
+
+	/* MULTICAST FULL MATCH */
+	esw_mc = l2addr_hash_find(hash, dmac_v, struct esw_mc_addr);
+
+	return esw_mc ? esw_mc->uplink_rule : NULL;
+}
+
+static struct mlx5_flow_rule *alloc_fr(void *ft,
+				       u8 match_criteria_enable,
+				       u32 *match_criteria,
+				       u32 *match_value,
+				       u32 action,
+				       u32 flow_tag)
+{
+	struct mlx5_flow_rule *fr = kzalloc(sizeof(*fr), GFP_KERNEL);
+
+	if (!fr)
+		return NULL;
+
+	fr->match_criteria = kzalloc(MLX5_ST_SZ_BYTES(fte_match_param), GFP_KERNEL);
+	fr->match_value = kzalloc(MLX5_ST_SZ_BYTES(fte_match_param), GFP_KERNEL);
+	if (!fr->match_criteria || !fr->match_value) {
+		kfree(fr->match_criteria);
+		kfree(fr->match_value);
+		kfree(fr);
+		return NULL;
+	}
+
+	memcpy(fr->match_criteria, match_criteria, MLX5_ST_SZ_BYTES(fte_match_param));
+	memcpy(fr->match_value, match_value, MLX5_ST_SZ_BYTES(fte_match_param));
+	fr->match_criteria_enable = match_criteria_enable;
+	fr->flow_tag = flow_tag;
+	fr->action = action;
+
+	mutex_init(&fr->mutex);
+	INIT_LIST_HEAD(&fr->dest_list);
+	atomic_set(&fr->refcount, 0);
+	fr->ft = ft;
+	return fr;
+}
+
+static void deref_fr(struct mlx5_flow_rule *fr)
+{
+	if (!atomic_dec_and_test(&fr->refcount))
+		return;
+
+	kfree(fr->match_criteria);
+	kfree(fr->match_value);
+	kfree(fr);
+}
+
+static struct mlx5_flow_rule *
+mlx5_add_flow_rule(struct mlx5_eswitch *esw,
+		   u8 match_criteria_enable,
+		   u32 *match_criteria,
+		   u32 *match_value,
+		   u32 action,
+		   u32 flow_tag,
+		   struct mlx5_flow_destination *dest)
+{
+	struct mlx5_flow_rule *fr;
+	int err;
+
+	fr = find_fr(esw, match_criteria_enable, match_value);
+	fr = fr ? fr : alloc_fr(esw->fdb_table.fdb, match_criteria_enable, match_criteria,
+				match_value, action, flow_tag);
+	if (!fr)
+		return NULL;
+
+	atomic_inc(&fr->refcount);
+
+	err = mlx5_flow_rule_add_dest(fr, dest);
+	if (err) {
+		deref_fr(fr);
+		return NULL;
+	}
+
+	return fr;
+}
+
+static void mlx5_del_flow_rule(struct mlx5_flow_rule *fr, u32 vport)
+{
+	struct mlx5_flow_destination dest;
+
+	dest.vport_num = vport;
+	mlx5_flow_rule_del_dest(fr, &dest);
+	deref_fr(fr);
+}
+
+/* E-Switch FDB */
+static struct mlx5_flow_rule *
+esw_fdb_set_vport_rule(struct mlx5_eswitch *esw, u8 mac[ETH_ALEN], u32 vport)
+{
+	int match_header = MLX5_MATCH_OUTER_HEADERS;
+	struct mlx5_flow_destination dest;
+	struct mlx5_flow_rule *flow_rule = NULL;
+	u32 *match_v;
+	u32 *match_c;
+	u8 *dmac_v;
+	u8 *dmac_c;
+
+	match_v = kzalloc(MLX5_ST_SZ_BYTES(fte_match_param), GFP_KERNEL);
+	match_c = kzalloc(MLX5_ST_SZ_BYTES(fte_match_param), GFP_KERNEL);
+	if (!match_v || !match_c) {
+		pr_warn("FDB: Failed to alloc match parameters\n");
+		goto out;
+	}
+	dmac_v = MLX5_ADDR_OF(fte_match_param, match_v,
+			      outer_headers.dmac_47_16);
+	dmac_c = MLX5_ADDR_OF(fte_match_param, match_c,
+			      outer_headers.dmac_47_16);
+
+	ether_addr_copy(dmac_v, mac);
+	/* Match criteria mask */
+	memset(dmac_c, 0xff, 6);
+
+	dest.type = MLX5_FLOW_DESTINATION_TYPE_VPORT;
+	dest.vport_num = vport;
+
+	esw_debug(esw->dev,
+		  "\tFDB add rule dmac_v(%pM) dmac_c(%pM) -> vport(%d)\n",
+		  dmac_v, dmac_c, vport);
+	flow_rule =
+		mlx5_add_flow_rule(esw,
+				   match_header,
+				   match_c,
+				   match_v,
+				   MLX5_FLOW_CONTEXT_ACTION_FWD_DEST,
+				   0, &dest);
+	if (IS_ERR_OR_NULL(flow_rule)) {
+		pr_warn(
+			"FDB: Failed to add flow rule: dmac_v(%pM) dmac_c(%pM) -> vport(%d), err(%ld)\n",
+			 dmac_v, dmac_c, vport, PTR_ERR(flow_rule));
+		flow_rule = NULL;
+	}
+out:
+	kfree(match_v);
+	kfree(match_c);
+	return flow_rule;
+}
+
+static int esw_create_fdb_table(struct mlx5_eswitch *esw, int nvports)
+{
+	struct mlx5_core_dev *dev = esw->dev;
+	struct mlx5_flow_table_group g;
+	struct mlx5_flow_table *fdb;
+	u8 *dmac;
+
+	esw_debug(dev, "Create FDB log_max_size(%d)\n",
+		  MLX5_CAP_ESW_FLOWTABLE_FDB(dev, log_max_ft_size));
+
+	memset(&g, 0, sizeof(g));
+	/* UC MC Full match rules*/
+	g.log_sz = MLX5_CAP_ESW_FLOWTABLE_FDB(dev, log_max_ft_size);
+	g.match_criteria_enable = MLX5_MATCH_OUTER_HEADERS;
+	dmac = MLX5_ADDR_OF(fte_match_param, g.match_criteria,
+			    outer_headers.dmac_47_16);
+	/* Match criteria mask */
+	memset(dmac, 0xff, 6);
+
+	fdb = mlx5_create_flow_table(dev, 0,
+				     MLX5_FLOW_TABLE_TYPE_ESWITCH,
+				     1, &g);
+	if (fdb)
+		esw_debug(dev, "ESW: FDB Table created fdb->id %d\n", mlx5_get_flow_table_id(fdb));
+	else
+		esw_warn(dev, "ESW: Failed to create FDB Table\n");
+
+	esw->fdb_table.fdb = fdb;
+	return fdb ? 0 : -ENOMEM;
+}
+
+static void esw_destroy_fdb_table(struct mlx5_eswitch *esw)
+{
+	if (!esw->fdb_table.fdb)
+		return;
+
+	esw_debug(esw->dev, "Destroy FDB Table fdb(%d)\n",
+		  mlx5_get_flow_table_id(esw->fdb_table.fdb));
+	mlx5_destroy_flow_table(esw->fdb_table.fdb);
+	esw->fdb_table.fdb = NULL;
+}
+
+/* E-Switch vport UC/MC lists management */
+typedef int (*vport_addr_action)(struct mlx5_eswitch *esw,
+				 struct vport_addr *vaddr);
+
+static int esw_add_uc_addr(struct mlx5_eswitch *esw, struct vport_addr *vaddr)
+{
+	struct hlist_head *hash = esw->l2_table.l2_hash;
+	struct esw_uc_addr *esw_uc;
+	u8 *mac = vaddr->node.addr;
+	u32 vport = vaddr->vport;
+	int err;
+
+	esw_uc = l2addr_hash_find(hash, mac, struct esw_uc_addr);
+	if (esw_uc) {
+		esw_warn(esw->dev,
+			 "Failed to set L2 mac(%pM) for vport(%d), mac is already in use by vport(%d)\n",
+			 mac, vport, esw_uc->vport);
+		return -EEXIST;
+	}
+
+	esw_uc = l2addr_hash_add(hash, mac, struct esw_uc_addr, GFP_KERNEL);
+	if (!esw_uc)
+		return -ENOMEM;
+	esw_uc->vport = vport;
+
+	err = set_l2_table_entry(esw->dev, mac, 0, 0, &esw_uc->table_index);
+	if (err)
+		goto abort;
+
+	if (esw->fdb_table.fdb) /* SRIOV is enabled: Forward UC MAC to vport */
+		vaddr->flow_rule = esw_fdb_set_vport_rule(esw, mac, vport);
+
+	esw_debug(esw->dev, "\tADDED UC MAC: vport[%d] %pM index:%d fr(%p)\n",
+		  vport, mac, esw_uc->table_index, vaddr->flow_rule);
+	return err;
+abort:
+	l2addr_hash_del(esw_uc);
+	return err;
+}
+
+static int esw_del_uc_addr(struct mlx5_eswitch *esw, struct vport_addr *vaddr)
+{
+	struct hlist_head *hash = esw->l2_table.l2_hash;
+	struct esw_uc_addr *esw_uc;
+	u8 *mac = vaddr->node.addr;
+	u32 vport = vaddr->vport;
+
+	esw_uc = l2addr_hash_find(hash, mac, struct esw_uc_addr);
+	if (!esw_uc || esw_uc->vport != vport) {
+		esw_debug(esw->dev,
+			  "MAC(%pM) doesn't belong to vport (%d)\n",
+			  mac, vport);
+		return -EINVAL;
+	}
+	esw_debug(esw->dev, "\tDELETE UC MAC: vport[%d] %pM index:%d fr(%p)\n",
+		  vport, mac, esw_uc->table_index, vaddr->flow_rule);
+
+	del_l2_table_entry(esw->dev, esw_uc->table_index);
+
+	if (vaddr->flow_rule)
+		mlx5_del_flow_rule(vaddr->flow_rule, vport);
+	vaddr->flow_rule = NULL;
+
+	l2addr_hash_del(esw_uc);
+	return 0;
+}
+
+static int esw_add_mc_addr(struct mlx5_eswitch *esw, struct vport_addr *vaddr)
+{
+	struct hlist_head *hash = esw->mc_table;
+	struct esw_mc_addr *esw_mc;
+	u8 *mac = vaddr->node.addr;
+	u32 vport = vaddr->vport;
+
+	if (!esw->fdb_table.fdb)
+		return 0;
+
+	esw_mc = l2addr_hash_find(hash, mac, struct esw_mc_addr);
+	if (esw_mc)
+		goto add;
+
+	esw_mc = l2addr_hash_add(hash, mac, struct esw_mc_addr, GFP_KERNEL);
+	if (!esw_mc)
+		return -ENOMEM;
+
+	esw_mc->uplink_rule = /* Forward MC MAC to Uplink */
+		esw_fdb_set_vport_rule(esw, mac, UPLINK_VPORT);
+add:
+	esw_mc->refcnt++;
+	/* Forward MC MAC to vport */
+	vaddr->flow_rule = esw_fdb_set_vport_rule(esw, mac, vport);
+	esw_debug(esw->dev,
+		  "\tADDED MC MAC: vport[%d] %pM fr(%p) refcnt(%d) uplinkfr(%p)\n",
+		  vport, mac, vaddr->flow_rule,
+		  esw_mc->refcnt, esw_mc->uplink_rule);
+	return 0;
+}
+
+static int esw_del_mc_addr(struct mlx5_eswitch *esw, struct vport_addr *vaddr)
+{
+	struct hlist_head *hash = esw->mc_table;
+	struct esw_mc_addr *esw_mc;
+	u8 *mac = vaddr->node.addr;
+	u32 vport = vaddr->vport;
+
+	if (!esw->fdb_table.fdb)
+		return 0;
+
+	esw_mc = l2addr_hash_find(hash, mac, struct esw_mc_addr);
+	if (!esw_mc) {
+		esw_warn(esw->dev,
+			 "Failed to find eswitch MC addr for MAC(%pM) vport(%d)",
+			 mac, vport);
+		return -EINVAL;
+	}
+	esw_debug(esw->dev,
+		  "\tDELETE MC MAC: vport[%d] %pM fr(%p) refcnt(%d) uplinkfr(%p)\n",
+		  vport, mac, vaddr->flow_rule, esw_mc->refcnt,
+		  esw_mc->uplink_rule);
+
+	if (vaddr->flow_rule)
+		mlx5_del_flow_rule(vaddr->flow_rule, vport);
+	vaddr->flow_rule = NULL;
+
+	if (--esw_mc->refcnt)
+		return 0;
+
+	if (esw_mc->uplink_rule)
+		mlx5_del_flow_rule(esw_mc->uplink_rule, UPLINK_VPORT);
+
+	l2addr_hash_del(esw_mc);
+	return 0;
+}
+
+/* Apply vport UC/MC list to HW l2 table and FDB table */
+static void esw_apply_vport_addr_list(struct mlx5_eswitch *esw,
+				      u32 vport_num, int list_type)
+{
+	struct mlx5_vport *vport = &esw->vports[vport_num];
+	bool is_uc = list_type == MLX5_NVPRT_LIST_TYPE_UC;
+	vport_addr_action vport_addr_add;
+	vport_addr_action vport_addr_del;
+	struct vport_addr *addr;
+	struct l2addr_node *node;
+	struct hlist_head *hash;
+	struct hlist_node *tmp;
+	int hi;
+
+	vport_addr_add = is_uc ? esw_add_uc_addr :
+				 esw_add_mc_addr;
+	vport_addr_del = is_uc ? esw_del_uc_addr :
+				 esw_del_mc_addr;
+
+	hash = is_uc ? vport->uc_list : vport->mc_list;
+	for_each_l2hash_node(node, tmp, hash, hi) {
+		addr = container_of(node, struct vport_addr, node);
+		switch (addr->action) {
+		case MLX5_ACTION_ADD:
+			vport_addr_add(esw, addr);
+			addr->action = MLX5_ACTION_NONE;
+			break;
+		case MLX5_ACTION_DEL:
+			vport_addr_del(esw, addr);
+			l2addr_hash_del(addr);
+			break;
+		}
+	}
+}
+
+/* Sync vport UC/MC list from vport context */
+static void esw_update_vport_addr_list(struct mlx5_eswitch *esw,
+				       u32 vport_num, int list_type)
+{
+	struct mlx5_vport *vport = &esw->vports[vport_num];
+	bool is_uc = list_type == MLX5_NVPRT_LIST_TYPE_UC;
+	u8 (*mac_list)[ETH_ALEN];
+	struct l2addr_node *node;
+	struct vport_addr *addr;
+	struct hlist_head *hash;
+	struct hlist_node *tmp;
+	int size;
+	int err;
+	int hi;
+	int i;
+
+	size = is_uc ? MLX5_MAX_UC_PER_VPORT(esw->dev) :
+		       MLX5_MAX_MC_PER_VPORT(esw->dev);
+
+	mac_list = kcalloc(size, ETH_ALEN, GFP_KERNEL);
+	if (!mac_list)
+		return;
+
+	hash = is_uc ? vport->uc_list : vport->mc_list;
+
+	for_each_l2hash_node(node, tmp, hash, hi) {
+		addr = container_of(node, struct vport_addr, node);
+		addr->action = MLX5_ACTION_DEL;
+	}
+
+	err = mlx5_query_nic_vport_mac_list(esw->dev, vport_num, list_type,
+					    mac_list, &size);
+	if (err)
+		return;
+	esw_debug(esw->dev, "vport[%d] context update %s list size (%d)\n",
+		  vport_num, is_uc ? "UC" : "MC", size);
+
+	for (i = 0; i < size; i++) {
+		if (is_uc && !is_valid_ether_addr(mac_list[i]))
+			continue;
+
+		if (!is_uc && !is_multicast_ether_addr(mac_list[i]))
+			continue;
+
+		addr = l2addr_hash_find(hash, mac_list[i], struct vport_addr);
+		if (addr) {
+			addr->action = MLX5_ACTION_NONE;
+			continue;
+		}
+
+		addr = l2addr_hash_add(hash, mac_list[i], struct vport_addr,
+				       GFP_KERNEL);
+		if (!addr) {
+			esw_warn(esw->dev,
+				 "Failed to add MAC(%pM) to vport[%d] DB\n",
+				 mac_list[i], vport_num);
+			continue;
+		}
+		addr->vport = vport_num;
+		addr->action = MLX5_ACTION_ADD;
+	}
+	kfree(mac_list);
+}
+
+static void esw_vport_change_handler(struct work_struct *work)
+{
+	struct mlx5_vport *vport =
+		container_of(work, struct mlx5_vport, vport_change_handler);
+	struct mlx5_core_dev *dev = vport->dev;
+	struct mlx5_eswitch *esw = dev->priv.eswitch;
+	u8 mac[ETH_ALEN];
+
+	mlx5_query_nic_vport_mac_address(dev, vport->vport, mac);
+	esw_debug(dev, "vport[%d] Context Changed: perm mac: %pM\n",
+		  vport->vport, mac);
+
+	if (vport->enabled_events & UC_ADDR_CHANGE) {
+		esw_update_vport_addr_list(esw, vport->vport,
+					   MLX5_NVPRT_LIST_TYPE_UC);
+		esw_apply_vport_addr_list(esw, vport->vport,
+					  MLX5_NVPRT_LIST_TYPE_UC);
+	}
+
+	if (vport->enabled_events & MC_ADDR_CHANGE) {
+		esw_update_vport_addr_list(esw, vport->vport,
+					   MLX5_NVPRT_LIST_TYPE_MC);
+		esw_apply_vport_addr_list(esw, vport->vport,
+					  MLX5_NVPRT_LIST_TYPE_MC);
+	}
+
+	esw_debug(esw->dev, "vport[%d] Context Changed: Done\n", vport->vport);
+	if (vport->enabled)
+		arm_vport_context_events_cmd(dev, vport->vport,
+					     vport->enabled_events);
+}
+
+static void esw_enable_vport(struct mlx5_eswitch *esw, int vport_num,
+			     int enable_events)
+{
+	struct mlx5_vport *vport = &esw->vports[vport_num];
+	unsigned long flags;
+
+	WARN_ON(vport->enabled);
+
+	esw_debug(esw->dev, "Enabling VPORT(%d)\n", vport_num);
+	mlx5_modify_vport_admin_state(esw->dev,
+				      MLX5_QUERY_VPORT_STATE_IN_OP_MOD_ESW_VPORT,
+				      vport_num,
+				      MLX5_ESW_VPORT_ADMIN_STATE_AUTO);
+
+	/* Sync with current vport context */
+	vport->enabled_events = enable_events;
+	esw_vport_change_handler(&vport->vport_change_handler);
+
+	spin_lock_irqsave(&vport->lock, flags);
+	vport->enabled = true;
+	spin_unlock_irqrestore(&vport->lock, flags);
+
+	arm_vport_context_events_cmd(esw->dev, vport_num, enable_events);
+
+	esw->enabled_vports++;
+	esw_debug(esw->dev, "Enabled VPORT(%d)\n", vport_num);
+}
+
+static void esw_cleanup_vport(struct mlx5_eswitch *esw, u16 vport_num)
+{
+	struct mlx5_vport *vport = &esw->vports[vport_num];
+	struct l2addr_node *node;
+	struct vport_addr *addr;
+	struct hlist_node *tmp;
+	int hi;
+
+	for_each_l2hash_node(node, tmp, vport->uc_list, hi) {
+		addr = container_of(node, struct vport_addr, node);
+		addr->action = MLX5_ACTION_DEL;
+	}
+	esw_apply_vport_addr_list(esw, vport_num, MLX5_NVPRT_LIST_TYPE_UC);
+
+	for_each_l2hash_node(node, tmp, vport->mc_list, hi) {
+		addr = container_of(node, struct vport_addr, node);
+		addr->action = MLX5_ACTION_DEL;
+	}
+	esw_apply_vport_addr_list(esw, vport_num, MLX5_NVPRT_LIST_TYPE_MC);
+}
+
+static void esw_disable_vport(struct mlx5_eswitch *esw, int vport_num)
+{
+	struct mlx5_vport *vport = &esw->vports[vport_num];
+	unsigned long flags;
+
+	if (!vport->enabled)
+		return;
+
+	esw_debug(esw->dev, "Disabling vport(%d)\n", vport_num);
+	/* Mark this vport as disabled to discard new events */
+	spin_lock_irqsave(&vport->lock, flags);
+	vport->enabled = false;
+	vport->enabled_events = 0;
+	spin_unlock_irqrestore(&vport->lock, flags);
+
+	mlx5_modify_vport_admin_state(esw->dev,
+				      MLX5_QUERY_VPORT_STATE_IN_OP_MOD_ESW_VPORT,
+				      vport_num,
+				      MLX5_ESW_VPORT_ADMIN_STATE_DOWN);
+	/* Wait for current already scheduled events to complete */
+	flush_workqueue(esw->work_queue);
+	/* Disable events from this vport */
+	arm_vport_context_events_cmd(esw->dev, vport->vport, 0);
+	/* We don't assume VFs will cleanup after themselves */
+	esw_cleanup_vport(esw, vport_num);
+	esw->enabled_vports--;
+}
+
+/* Public E-Switch API */
+int mlx5_eswitch_enable_sriov(struct mlx5_eswitch *esw, int nvfs)
+{
+	int err;
+	int i;
+
+	if (!esw || !MLX5_CAP_GEN(esw->dev, vport_group_manager) ||
+	    MLX5_CAP_GEN(esw->dev, port_type) != MLX5_CAP_PORT_TYPE_ETH)
+		return 0;
+
+	if (!MLX5_CAP_GEN(esw->dev, eswitch_flow_table) ||
+	    !MLX5_CAP_ESW_FLOWTABLE_FDB(esw->dev, ft_support)) {
+		esw_warn(esw->dev, "E-Switch FDB is not supported, aborting ...\n");
+		return -ENOTSUPP;
+	}
+
+	esw_info(esw->dev, "E-Switch enable SRIOV: nvfs(%d)\n", nvfs);
+
+	esw_disable_vport(esw, 0);
+
+	err = esw_create_fdb_table(esw, nvfs + 1);
+	if (err)
+		goto abort;
+
+	for (i = 0; i <= nvfs; i++)
+		esw_enable_vport(esw, i, SRIOV_VPORT_EVENTS);
+
+	esw_info(esw->dev, "SRIOV enabled: active vports(%d)\n",
+		 esw->enabled_vports);
+	return 0;
+
+abort:
+	esw_enable_vport(esw, 0, UC_ADDR_CHANGE);
+	return err;
+}
+
+void mlx5_eswitch_disable_sriov(struct mlx5_eswitch *esw)
+{
+	int i;
+
+	if (!esw || !MLX5_CAP_GEN(esw->dev, vport_group_manager) ||
+	    MLX5_CAP_GEN(esw->dev, port_type) != MLX5_CAP_PORT_TYPE_ETH)
+		return;
+
+	esw_info(esw->dev, "disable SRIOV: active vports(%d)\n",
+		 esw->enabled_vports);
+
+	for (i = 0; i < esw->total_vports; i++)
+		esw_disable_vport(esw, i);
+
+	esw_destroy_fdb_table(esw);
+
+	/* VPORT 0 (PF) must be enabled back with non-sriov configuration */
+	esw_enable_vport(esw, 0, UC_ADDR_CHANGE);
+}
+
+int mlx5_eswitch_init(struct mlx5_core_dev *dev)
+{
+	int l2_table_size = 1 << MLX5_CAP_GEN(dev, log_max_l2_table);
+	int total_vports = 1 + pci_sriov_get_totalvfs(dev->pdev);
+	struct mlx5_eswitch *esw;
+	int vport_num;
+	int err;
+
+	if (!MLX5_CAP_GEN(dev, vport_group_manager) ||
+	    MLX5_CAP_GEN(dev, port_type) != MLX5_CAP_PORT_TYPE_ETH)
+		return 0;
+
+	esw_info(dev,
+		 "Total vports %d, l2 table size(%d), per vport: max uc(%d) max mc(%d)\n",
+		 total_vports, l2_table_size,
+		 MLX5_MAX_UC_PER_VPORT(dev),
+		 MLX5_MAX_MC_PER_VPORT(dev));
+
+	esw = kzalloc(sizeof(*esw), GFP_KERNEL);
+	if (!esw)
+		return -ENOMEM;
+
+	esw->dev = dev;
+
+	esw->l2_table.bitmap = kcalloc(BITS_TO_LONGS(l2_table_size),
+				   sizeof(uintptr_t), GFP_KERNEL);
+	if (!esw->l2_table.bitmap) {
+		err = -ENOMEM;
+		goto abort;
+	}
+	esw->l2_table.size = l2_table_size;
+
+	esw->work_queue = create_singlethread_workqueue("mlx5_esw_wq");
+	if (!esw->work_queue) {
+		err = -ENOMEM;
+		goto abort;
+	}
+
+	esw->vports = kcalloc(total_vports, sizeof(struct mlx5_vport),
+			      GFP_KERNEL);
+	if (!esw->vports) {
+		err = -ENOMEM;
+		goto abort;
+	}
+
+	for (vport_num = 0; vport_num < total_vports; vport_num++) {
+		struct mlx5_vport *vport = &esw->vports[vport_num];
+
+		vport->vport = vport_num;
+		vport->dev = dev;
+		INIT_WORK(&vport->vport_change_handler,
+			  esw_vport_change_handler);
+		spin_lock_init(&vport->lock);
+	}
+
+	esw->total_vports = total_vports;
+	esw->enabled_vports = 0;
+
+	dev->priv.eswitch = esw;
+	esw_enable_vport(esw, 0, UC_ADDR_CHANGE);
+	/* VF Vports will be enabled when SRIOV is enabled */
+	return 0;
+abort:
+	if (esw->work_queue)
+		destroy_workqueue(esw->work_queue);
+	kfree(esw->l2_table.bitmap);
+	kfree(esw->vports);
+	kfree(esw);
+	return err;
+}
+
+void mlx5_eswitch_cleanup(struct mlx5_eswitch *esw)
+{
+	if (!esw || !MLX5_CAP_GEN(esw->dev, vport_group_manager) ||
+	    MLX5_CAP_GEN(esw->dev, port_type) != MLX5_CAP_PORT_TYPE_ETH)
+		return;
+
+	esw_info(esw->dev, "cleanup\n");
+	esw_disable_vport(esw, 0);
+
+	esw->dev->priv.eswitch = NULL;
+	destroy_workqueue(esw->work_queue);
+	kfree(esw->l2_table.bitmap);
+	kfree(esw->vports);
+	kfree(esw);
+}
+
+void mlx5_eswitch_vport_event(struct mlx5_eswitch *esw, struct mlx5_eqe *eqe)
+{
+	struct mlx5_eqe_vport_change *vc_eqe = &eqe->data.vport_change;
+	u16 vport_num = be16_to_cpu(vc_eqe->vport_num);
+	struct mlx5_vport *vport;
+
+	if (!esw) {
+		pr_warn("MLX5 E-Switch: vport %d got an event while eswitch is not initialized\n",
+			vport_num);
+		return;
+	}
+
+	vport = &esw->vports[vport_num];
+	spin_lock(&vport->lock);
+	if (vport->enabled)
+		queue_work(esw->work_queue, &vport->vport_change_handler);
+	spin_unlock(&vport->lock);
+}
+
+/* Vport Administration */
+#define ESW_ALLOWED(esw) \
+	(esw && MLX5_CAP_GEN(esw->dev, vport_group_manager) && mlx5_core_is_pf(esw->dev))
+#define LEGAL_VPORT(esw, vport) (vport >= 0 && vport < esw->total_vports)
+
+int mlx5_eswitch_set_vport_mac(struct mlx5_eswitch *esw,
+			       int vport, u8 mac[ETH_ALEN])
+{
+	int err = 0;
+
+	if (!ESW_ALLOWED(esw))
+		return -EPERM;
+	if (!LEGAL_VPORT(esw, vport))
+		return -EINVAL;
+
+	err = mlx5_modify_nic_vport_mac_address(esw->dev, vport, mac);
+	if (err) {
+		mlx5_core_warn(esw->dev,
+			       "Failed to mlx5_modify_nic_vport_mac vport(%d) err=(%d)\n",
+			       vport, err);
+		return err;
+	}
+
+	return err;
+}
+
+int mlx5_eswitch_set_vport_state(struct mlx5_eswitch *esw,
+				 int vport, int link_state)
+{
+	if (!ESW_ALLOWED(esw))
+		return -EPERM;
+	if (!LEGAL_VPORT(esw, vport))
+		return -EINVAL;
+
+	return mlx5_modify_vport_admin_state(esw->dev,
+					     MLX5_QUERY_VPORT_STATE_IN_OP_MOD_ESW_VPORT,
+					     vport, link_state);
+}
+
+int mlx5_eswitch_get_vport_config(struct mlx5_eswitch *esw,
+				  int vport, struct ifla_vf_info *ivi)
+{
+	u16 vlan;
+	u8 qos;
+
+	if (!ESW_ALLOWED(esw))
+		return -EPERM;
+	if (!LEGAL_VPORT(esw, vport))
+		return -EINVAL;
+
+	memset(ivi, 0, sizeof(*ivi));
+	ivi->vf = vport - 1;
+
+	mlx5_query_nic_vport_mac_address(esw->dev, vport, ivi->mac);
+	ivi->linkstate = mlx5_query_vport_admin_state(esw->dev,
+						      MLX5_QUERY_VPORT_STATE_IN_OP_MOD_ESW_VPORT,
+						      vport);
+	query_esw_vport_cvlan(esw->dev, vport, &vlan, &qos);
+	ivi->vlan = vlan;
+	ivi->qos = qos;
+	ivi->spoofchk = 0;
+
+	return 0;
+}
+
+int mlx5_eswitch_set_vport_vlan(struct mlx5_eswitch *esw,
+				int vport, u16 vlan, u8 qos)
+{
+	int set = 0;
+
+	if (!ESW_ALLOWED(esw))
+		return -EPERM;
+	if (!LEGAL_VPORT(esw, vport) || (vlan > 4095) || (qos > 7))
+		return -EINVAL;
+
+	if (vlan || qos)
+		set = 1;
+
+	return modify_esw_vport_cvlan(esw->dev, vport, vlan, qos, set);
+}
+
+int mlx5_eswitch_get_vport_stats(struct mlx5_eswitch *esw,
+				 int vport,
+				 struct ifla_vf_stats *vf_stats)
+{
+	int outlen = MLX5_ST_SZ_BYTES(query_vport_counter_out);
+	u32 in[MLX5_ST_SZ_DW(query_vport_counter_in)];
+	int err = 0;
+	u32 *out;
+
+	if (!ESW_ALLOWED(esw))
+		return -EPERM;
+	if (!LEGAL_VPORT(esw, vport))
+		return -EINVAL;
+
+	out = mlx5_vzalloc(outlen);
+	if (!out)
+		return -ENOMEM;
+
+	memset(in, 0, sizeof(in));
+
+	MLX5_SET(query_vport_counter_in, in, opcode,
+		 MLX5_CMD_OP_QUERY_VPORT_COUNTER);
+	MLX5_SET(query_vport_counter_in, in, op_mod, 0);
+	MLX5_SET(query_vport_counter_in, in, vport_number, vport);
+	if (vport)
+		MLX5_SET(query_vport_counter_in, in, other_vport, 1);
+
+	memset(out, 0, outlen);
+	err = mlx5_cmd_exec(esw->dev, in, sizeof(in), out, outlen);
+	if (err)
+		goto free_out;
+
+	#define MLX5_GET_CTR(p, x) \
+		MLX5_GET64(query_vport_counter_out, p, x)
+
+	memset(vf_stats, 0, sizeof(*vf_stats));
+	vf_stats->rx_packets =
+		MLX5_GET_CTR(out, received_eth_unicast.packets) +
+		MLX5_GET_CTR(out, received_eth_multicast.packets) +
+		MLX5_GET_CTR(out, received_eth_broadcast.packets);
+
+	vf_stats->rx_bytes =
+		MLX5_GET_CTR(out, received_eth_unicast.octets) +
+		MLX5_GET_CTR(out, received_eth_multicast.octets) +
+		MLX5_GET_CTR(out, received_eth_broadcast.octets);
+
+	vf_stats->tx_packets =
+		MLX5_GET_CTR(out, transmitted_eth_unicast.packets) +
+		MLX5_GET_CTR(out, transmitted_eth_multicast.packets) +
+		MLX5_GET_CTR(out, transmitted_eth_broadcast.packets);
+
+	vf_stats->tx_bytes =
+		MLX5_GET_CTR(out, transmitted_eth_unicast.octets) +
+		MLX5_GET_CTR(out, transmitted_eth_multicast.octets) +
+		MLX5_GET_CTR(out, transmitted_eth_broadcast.octets);
+
+	vf_stats->multicast =
+		MLX5_GET_CTR(out, received_eth_multicast.packets);
+
+	vf_stats->broadcast =
+		MLX5_GET_CTR(out, received_eth_broadcast.packets);
+
+free_out:
+	kvfree(out);
+	return err;
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h
@@ -0,0 +1,160 @@
+/*
+ * Copyright (c) 2015, Mellanox Technologies, Ltd.  All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef __MLX5_ESWITCH_H__
+#define __MLX5_ESWITCH_H__
+
+#include <linux/if_ether.h>
+#include <linux/if_link.h>
+#include <linux/mlx5/device.h>
+
+#define MLX5_MAX_UC_PER_VPORT(dev) \
+	(1 << MLX5_CAP_GEN(dev, log_max_current_uc_list))
+
+#define MLX5_MAX_MC_PER_VPORT(dev) \
+	(1 << MLX5_CAP_GEN(dev, log_max_current_mc_list))
+
+#define MLX5_L2_ADDR_HASH_SIZE (BIT(BITS_PER_BYTE))
+#define MLX5_L2_ADDR_HASH(addr) (addr[5])
+
+/* L2 -mac address based- hash helpers */
+struct l2addr_node {
+	struct hlist_node hlist;
+	u8                addr[ETH_ALEN];
+};
+
+#define for_each_l2hash_node(hn, tmp, hash, i) \
+	for (i = 0; i < MLX5_L2_ADDR_HASH_SIZE; i++) \
+		hlist_for_each_entry_safe(hn, tmp, &hash[i], hlist)
+
+#define l2addr_hash_find(hash, mac, type) ({                \
+	int ix = MLX5_L2_ADDR_HASH(mac);                    \
+	bool found = false;                                 \
+	type *ptr = NULL;                                   \
+							    \
+	hlist_for_each_entry(ptr, &hash[ix], node.hlist)    \
+		if (ether_addr_equal(ptr->node.addr, mac)) {\
+			found = true;                       \
+			break;                              \
+		}                                           \
+	if (!found)                                         \
+		ptr = NULL;                                 \
+	ptr;                                                \
+})
+
+#define l2addr_hash_add(hash, mac, type, gfp) ({            \
+	int ix = MLX5_L2_ADDR_HASH(mac);                    \
+	type *ptr = NULL;                                   \
+							    \
+	ptr = kzalloc(sizeof(type), gfp);                   \
+	if (ptr) {                                          \
+		ether_addr_copy(ptr->node.addr, mac);       \
+		hlist_add_head(&ptr->node.hlist, &hash[ix]);\
+	}                                                   \
+	ptr;                                                \
+})
+
+#define l2addr_hash_del(ptr) ({                             \
+	hlist_del(&ptr->node.hlist);                        \
+	kfree(ptr);                                         \
+})
+
+struct mlx5_flow_rule {
+	void             *ft;
+	u32              fi;
+	u8               match_criteria_enable;
+	u32              *match_criteria;
+	u32              *match_value;
+	u32              action;
+	u32              flow_tag;
+	bool             valid;
+	atomic_t         refcount;
+	struct mutex     mutex; /* protect flow rule updates */
+	struct list_head dest_list;
+};
+
+struct mlx5_vport {
+	struct mlx5_core_dev    *dev;
+	int                     vport;
+	struct hlist_head       uc_list[MLX5_L2_ADDR_HASH_SIZE];
+	struct hlist_head       mc_list[MLX5_L2_ADDR_HASH_SIZE];
+	struct work_struct      vport_change_handler;
+
+	/* This spinlock protects access to vport data, between
+	 * "esw_vport_disable" and ongoing interrupt "mlx5_eswitch_vport_event"
+	 * once vport marked as disabled new interrupts are discarded.
+	 */
+	spinlock_t              lock; /* vport events sync */
+	bool                    enabled;
+	u16                     enabled_events;
+};
+
+struct mlx5_l2_table {
+	struct hlist_head l2_hash[MLX5_L2_ADDR_HASH_SIZE];
+	u32                  size;
+	unsigned long        *bitmap;
+};
+
+struct mlx5_eswitch_fdb {
+	void *fdb;
+};
+
+struct mlx5_eswitch {
+	struct mlx5_core_dev    *dev;
+	struct mlx5_l2_table    l2_table;
+	struct mlx5_eswitch_fdb fdb_table;
+	struct hlist_head       mc_table[MLX5_L2_ADDR_HASH_SIZE];
+	struct workqueue_struct *work_queue;
+	struct mlx5_vport       *vports;
+	int                     total_vports;
+	int                     enabled_vports;
+};
+
+/* E-Switch API */
+int mlx5_eswitch_init(struct mlx5_core_dev *dev);
+void mlx5_eswitch_cleanup(struct mlx5_eswitch *esw);
+void mlx5_eswitch_vport_event(struct mlx5_eswitch *esw, struct mlx5_eqe *eqe);
+int mlx5_eswitch_enable_sriov(struct mlx5_eswitch *esw, int nvfs);
+void mlx5_eswitch_disable_sriov(struct mlx5_eswitch *esw);
+int mlx5_eswitch_set_vport_mac(struct mlx5_eswitch *esw,
+			       int vport, u8 mac[ETH_ALEN]);
+int mlx5_eswitch_set_vport_state(struct mlx5_eswitch *esw,
+				 int vport, int link_state);
+int mlx5_eswitch_set_vport_vlan(struct mlx5_eswitch *esw,
+				int vport, u16 vlan, u8 qos);
+int mlx5_eswitch_get_vport_config(struct mlx5_eswitch *esw,
+				  int vport, struct ifla_vf_info *ivi);
+int mlx5_eswitch_get_vport_stats(struct mlx5_eswitch *esw,
+				 int vport,
+				 struct ifla_vf_stats *vf_stats);
+
+#endif /* __MLX5_ESWITCH_H__ */
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/mellanox/mlx5/core/fw.c
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/mellanox/mlx5/core/fw.c
@@ -160,6 +160,30 @@ int mlx5_query_hca_caps(struct mlx5_core
 		if (err)
 			return err;
 	}
+
+	if (MLX5_CAP_GEN(dev, vport_group_manager) &&
+	    MLX5_CAP_GEN(dev, eswitch_flow_table)) {
+		err = mlx5_core_get_caps(dev, MLX5_CAP_ESWITCH_FLOW_TABLE,
+					 HCA_CAP_OPMOD_GET_CUR);
+		if (err)
+			return err;
+		err = mlx5_core_get_caps(dev, MLX5_CAP_ESWITCH_FLOW_TABLE,
+					 HCA_CAP_OPMOD_GET_MAX);
+		if (err)
+			return err;
+	}
+
+	if (MLX5_CAP_GEN(dev, eswitch_flow_table)) {
+		err = mlx5_core_get_caps(dev, MLX5_CAP_ESWITCH,
+					 HCA_CAP_OPMOD_GET_CUR);
+		if (err)
+			return err;
+		err = mlx5_core_get_caps(dev, MLX5_CAP_ESWITCH,
+					 HCA_CAP_OPMOD_GET_MAX);
+		if (err)
+			return err;
+	}
+
 	return 0;
 }
 
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/mellanox/mlx5/core/main.c
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/mellanox/mlx5/core/main.c
@@ -49,6 +49,9 @@
 #include <linux/delay.h>
 #include <linux/mlx5/mlx5_ifc.h>
 #include "mlx5_core.h"
+#ifdef CONFIG_MLX5_CORE_EN
+#include "eswitch.h"
+#endif
 
 MODULE_AUTHOR("Eli Cohen <eli@mellanox.com>");
 MODULE_DESCRIPTION("Mellanox Connect-IB, ConnectX-4 core driver");
@@ -454,6 +457,9 @@ static int set_hca_ctrl(struct mlx5_core
 	struct mlx5_reg_host_endianess he_out;
 	int err;
 
+	if (!mlx5_core_is_pf(dev))
+		return 0;
+
 	memset(&he_in, 0, sizeof(he_in));
 	he_in.he = MLX5_SET_HOST_ENDIANNESS;
 	err = mlx5_core_access_reg(dev, &he_in,  sizeof(he_in),
@@ -462,42 +468,39 @@ static int set_hca_ctrl(struct mlx5_core
 	return err;
 }
 
-static int mlx5_core_enable_hca(struct mlx5_core_dev *dev)
+int mlx5_core_enable_hca(struct mlx5_core_dev *dev, u16 func_id)
 {
+	u32 out[MLX5_ST_SZ_DW(enable_hca_out)];
+	u32 in[MLX5_ST_SZ_DW(enable_hca_in)];
 	int err;
-	struct mlx5_enable_hca_mbox_in in;
-	struct mlx5_enable_hca_mbox_out out;
 
-	memset(&in, 0, sizeof(in));
-	memset(&out, 0, sizeof(out));
-	in.hdr.opcode = cpu_to_be16(MLX5_CMD_OP_ENABLE_HCA);
+	memset(in, 0, sizeof(in));
+	MLX5_SET(enable_hca_in, in, opcode, MLX5_CMD_OP_ENABLE_HCA);
+	MLX5_SET(enable_hca_in, in, function_id, func_id);
+	memset(out, 0, sizeof(out));
+
 	err = mlx5_cmd_exec(dev, &in, sizeof(in), &out, sizeof(out));
 	if (err)
 		return err;
 
-	if (out.hdr.status)
-		return mlx5_cmd_status_to_err(&out.hdr);
-
-	return 0;
+	return mlx5_cmd_status_to_err_v2(out);
 }
 
-static int mlx5_core_disable_hca(struct mlx5_core_dev *dev)
+int mlx5_core_disable_hca(struct mlx5_core_dev *dev, u16 func_id)
 {
+	u32 out[MLX5_ST_SZ_DW(disable_hca_out)];
+	u32 in[MLX5_ST_SZ_DW(disable_hca_in)];
 	int err;
-	struct mlx5_disable_hca_mbox_in in;
-	struct mlx5_disable_hca_mbox_out out;
 
-	memset(&in, 0, sizeof(in));
-	memset(&out, 0, sizeof(out));
-	in.hdr.opcode = cpu_to_be16(MLX5_CMD_OP_DISABLE_HCA);
-	err = mlx5_cmd_exec(dev, &in, sizeof(in), &out, sizeof(out));
+	memset(in, 0, sizeof(in));
+	MLX5_SET(disable_hca_in, in, opcode, MLX5_CMD_OP_DISABLE_HCA);
+	MLX5_SET(disable_hca_in, in, function_id, func_id);
+	memset(out, 0, sizeof(out));
+	err = mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out));
 	if (err)
 		return err;
 
-	if (out.hdr.status)
-		return mlx5_cmd_status_to_err(&out.hdr);
-
-	return 0;
+	return mlx5_cmd_status_to_err_v2(out);
 }
 
 static int mlx5_irq_set_affinity_hint(struct mlx5_core_dev *mdev, int i)
@@ -568,7 +571,8 @@ static void mlx5_irq_clear_affinity_hint
 		mlx5_irq_clear_affinity_hint(mdev, i);
 }
 
-int mlx5_vector2eqn(struct mlx5_core_dev *dev, int vector, int *eqn, int *irqn)
+int mlx5_vector2eqn(struct mlx5_core_dev *dev, int vector, int *eqn,
+		    unsigned int *irqn)
 {
 	struct mlx5_eq_table *table = &dev->priv.eq_table;
 	struct mlx5_eq *eq, *n;
@@ -913,7 +917,7 @@ static int mlx5_load_one(struct mlx5_cor
 	int err;
 
 	mutex_lock(&dev->intf_state_mutex);
-	if (dev->interface_state == MLX5_INTERFACE_STATE_UP) {
+	if (test_bit(MLX5_INTERFACE_STATE_UP, &dev->intf_state)) {
 		dev_warn(&dev->pdev->dev, "%s: interface is up, NOP\n",
 			 __func__);
 		goto out;
@@ -942,7 +946,7 @@ static int mlx5_load_one(struct mlx5_cor
 
 	mlx5_pagealloc_init(dev);
 
-	err = mlx5_core_enable_hca(dev);
+	err = mlx5_core_enable_hca(dev, 0);
 	if (err) {
 		dev_err(&pdev->dev, "enable hca failed\n");
 		goto err_pagealloc_cleanup;
@@ -1052,6 +1056,20 @@ static int mlx5_load_one(struct mlx5_cor
 	mlx5_init_srq_table(dev);
 	mlx5_init_mr_table(dev);
 
+#ifdef CONFIG_MLX5_CORE_EN
+	err = mlx5_eswitch_init(dev);
+	if (err) {
+		dev_err(&pdev->dev, "eswitch init failed %d\n", err);
+		goto err_reg_dev;
+	}
+#endif
+
+	err = mlx5_sriov_init(dev);
+	if (err) {
+		dev_err(&pdev->dev, "sriov init failed %d\n", err);
+		goto err_sriov;
+	}
+
 	err = mlx5_register_device(dev);
 	if (err) {
 		dev_err(&pdev->dev, "mlx5_register_device failed %d\n", err);
@@ -1062,12 +1080,20 @@ static int mlx5_load_one(struct mlx5_cor
 	if (err)
 		pr_info("failed request module on %s\n", MLX5_IB_MOD);
 
-	dev->interface_state = MLX5_INTERFACE_STATE_UP;
+	clear_bit(MLX5_INTERFACE_STATE_DOWN, &dev->intf_state);
+	set_bit(MLX5_INTERFACE_STATE_UP, &dev->intf_state);
 out:
 	mutex_unlock(&dev->intf_state_mutex);
 
 	return 0;
 
+err_sriov:
+	if (mlx5_sriov_cleanup(dev))
+		dev_err(&dev->pdev->dev, "sriov cleanup failed\n");
+
+#ifdef CONFIG_MLX5_CORE_EN
+	mlx5_eswitch_cleanup(dev->priv.eswitch);
+#endif
 err_reg_dev:
 	mlx5_cleanup_mr_table(dev);
 	mlx5_cleanup_srq_table(dev);
@@ -1106,7 +1132,7 @@ reclaim_boot_pages:
 	mlx5_reclaim_startup_pages(dev);
 
 err_disable_hca:
-	mlx5_core_disable_hca(dev);
+	mlx5_core_disable_hca(dev, 0);
 
 err_pagealloc_cleanup:
 	mlx5_pagealloc_cleanup(dev);
@@ -1123,13 +1149,24 @@ static int mlx5_unload_one(struct mlx5_c
 {
 	int err = 0;
 
+	err = mlx5_sriov_cleanup(dev);
+	if (err) {
+		dev_warn(&dev->pdev->dev, "%s: sriov cleanup failed - abort\n",
+			 __func__);
+		return err;
+	}
+
 	mutex_lock(&dev->intf_state_mutex);
-	if (dev->interface_state == MLX5_INTERFACE_STATE_DOWN) {
+	if (test_bit(MLX5_INTERFACE_STATE_DOWN, &dev->intf_state)) {
 		dev_warn(&dev->pdev->dev, "%s: interface is down, NOP\n",
 			 __func__);
 		goto out;
 	}
 	mlx5_unregister_device(dev);
+#ifdef CONFIG_MLX5_CORE_EN
+	mlx5_eswitch_cleanup(dev->priv.eswitch);
+#endif
+
 	mlx5_cleanup_mr_table(dev);
 	mlx5_cleanup_srq_table(dev);
 	mlx5_cleanup_qp_table(dev);
@@ -1149,12 +1186,13 @@ static int mlx5_unload_one(struct mlx5_c
 	}
 	mlx5_pagealloc_stop(dev);
 	mlx5_reclaim_startup_pages(dev);
-	mlx5_core_disable_hca(dev);
+	mlx5_core_disable_hca(dev, 0);
 	mlx5_pagealloc_cleanup(dev);
 	mlx5_cmd_cleanup(dev);
 
 out:
-	dev->interface_state = MLX5_INTERFACE_STATE_DOWN;
+	clear_bit(MLX5_INTERFACE_STATE_UP, &dev->intf_state);
+	set_bit(MLX5_INTERFACE_STATE_DOWN, &dev->intf_state);
 	mutex_unlock(&dev->intf_state_mutex);
 	return err;
 }
@@ -1195,6 +1233,7 @@ static int init_one(struct pci_dev *pdev
 		return -ENOMEM;
 	}
 	priv = &dev->priv;
+	priv->pci_dev_data = id->driver_data;
 
 	pci_set_drvdata(pdev, dev);
 
@@ -1364,13 +1403,25 @@ static const struct pci_error_handlers m
 	.resume		= mlx5_pci_resume
 };
 
+static void shutdown(struct pci_dev *pdev)
+{
+	struct mlx5_core_dev *dev  = pci_get_drvdata(pdev);
+	struct mlx5_priv *priv = &dev->priv;
+
+	dev_info(&pdev->dev, "Shutdown was called\n");
+	/* Notify mlx5 clients that the kernel is being shut down */
+	set_bit(MLX5_INTERFACE_STATE_SHUTDOWN, &dev->intf_state);
+	mlx5_unload_one(dev, priv);
+	mlx5_pci_disable_device(dev);
+}
+
 static const struct pci_device_id mlx5_core_pci_table[] = {
-	{ PCI_VDEVICE(MELLANOX, 0x1011) }, /* Connect-IB */
-	{ PCI_VDEVICE(MELLANOX, 0x1012) }, /* Connect-IB VF */
-	{ PCI_VDEVICE(MELLANOX, 0x1013) }, /* ConnectX-4 */
-	{ PCI_VDEVICE(MELLANOX, 0x1014) }, /* ConnectX-4 VF */
-	{ PCI_VDEVICE(MELLANOX, 0x1015) }, /* ConnectX-4LX */
-	{ PCI_VDEVICE(MELLANOX, 0x1016) }, /* ConnectX-4LX VF */
+	{ PCI_VDEVICE(MELLANOX, 0x1011) },			/* Connect-IB */
+	{ PCI_VDEVICE(MELLANOX, 0x1012), MLX5_PCI_DEV_IS_VF},	/* Connect-IB VF */
+	{ PCI_VDEVICE(MELLANOX, 0x1013) },			/* ConnectX-4 */
+	{ PCI_VDEVICE(MELLANOX, 0x1014), MLX5_PCI_DEV_IS_VF},	/* ConnectX-4 VF */
+	{ PCI_VDEVICE(MELLANOX, 0x1015) },			/* ConnectX-4LX */
+	{ PCI_VDEVICE(MELLANOX, 0x1016), MLX5_PCI_DEV_IS_VF},	/* ConnectX-4LX VF */
 	{ 0, }
 };
 
@@ -1381,7 +1432,9 @@ static struct pci_driver mlx5_core_drive
 	.id_table       = mlx5_core_pci_table,
 	.probe          = init_one,
 	.remove         = remove_one,
-	.err_handler	= &mlx5_err_handler
+	.shutdown	= shutdown,
+	.err_handler	= &mlx5_err_handler,
+	.sriov_configure   = mlx5_core_sriov_configure,
 };
 
 static int __init init(void)
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.h
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.h
@@ -36,6 +36,7 @@
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
+#include <linux/if_link.h>
 
 #define DRIVER_NAME "mlx5_core"
 #define DRIVER_VERSION "3.0-1"
@@ -64,6 +65,9 @@ do {									\
 		(__dev)->priv.name, __func__, __LINE__, current->pid,	\
 		##__VA_ARGS__)
 
+#define mlx5_core_info(__dev, format, ...)				\
+	dev_info(&(__dev)->pdev->dev, format, ##__VA_ARGS__)
+
 enum {
 	MLX5_CMD_DATA, /* print command payload only */
 	MLX5_CMD_TIME, /* print command execution time */
@@ -90,6 +94,10 @@ void mlx5_core_event(struct mlx5_core_de
 		     unsigned long param);
 void mlx5_enter_error_state(struct mlx5_core_dev *dev);
 void mlx5_disable_device(struct mlx5_core_dev *dev);
+int mlx5_core_sriov_configure(struct pci_dev *dev, int num_vfs);
+int mlx5_core_enable_hca(struct mlx5_core_dev *dev, u16 func_id);
+int mlx5_core_disable_hca(struct mlx5_core_dev *dev, u16 func_id);
+int mlx5_wait_for_vf_pages(struct mlx5_core_dev *dev);
 
 void mlx5e_init(void);
 void mlx5e_cleanup(void);
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c
@@ -33,6 +33,7 @@
 #include <linux/highmem.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/delay.h>
 #include <linux/mlx5/driver.h>
 #include <linux/mlx5/cmd.h>
 #include "mlx5_core.h"
@@ -95,6 +96,7 @@ struct mlx5_manage_pages_outbox {
 
 enum {
 	MAX_RECLAIM_TIME_MSECS	= 5000,
+	MAX_RECLAIM_VFS_PAGES_TIME_MSECS = 2 * 1000 * 60,
 };
 
 enum {
@@ -352,6 +354,10 @@ retry:
 		goto out_4k;
 	}
 
+	dev->priv.fw_pages += npages;
+	if (func_id)
+		dev->priv.vfs_pages += npages;
+
 	mlx5_core_dbg(dev, "err %d\n", err);
 
 	kvfree(in);
@@ -405,6 +411,12 @@ static int reclaim_pages(struct mlx5_cor
 	}
 
 	num_claimed = be32_to_cpu(out->num_entries);
+	if (num_claimed > npages) {
+		mlx5_core_warn(dev, "fw returned %d, driver asked %d => corruption\n",
+			       num_claimed, npages);
+		err = -EINVAL;
+		goto out_free;
+	}
 	if (nclaimed)
 		*nclaimed = num_claimed;
 
@@ -412,6 +424,9 @@ static int reclaim_pages(struct mlx5_cor
 		addr = be64_to_cpu(out->pas[i]);
 		free_4k(dev, addr);
 	}
+	dev->priv.fw_pages -= num_claimed;
+	if (func_id)
+		dev->priv.vfs_pages -= num_claimed;
 
 out_free:
 	kvfree(out);
@@ -548,3 +563,26 @@ void mlx5_pagealloc_stop(struct mlx5_cor
 {
 	destroy_workqueue(dev->priv.pg_wq);
 }
+
+int mlx5_wait_for_vf_pages(struct mlx5_core_dev *dev)
+{
+	unsigned long end = jiffies + msecs_to_jiffies(MAX_RECLAIM_VFS_PAGES_TIME_MSECS);
+	int prev_vfs_pages = dev->priv.vfs_pages;
+
+	mlx5_core_dbg(dev, "Waiting for %d pages from %s\n", prev_vfs_pages,
+		      dev->priv.name);
+	while (dev->priv.vfs_pages) {
+		if (time_after(jiffies, end)) {
+			mlx5_core_warn(dev, "aborting while there are %d pending pages\n", dev->priv.vfs_pages);
+			return -ETIMEDOUT;
+		}
+		if (dev->priv.vfs_pages < prev_vfs_pages) {
+			end = jiffies + msecs_to_jiffies(MAX_RECLAIM_VFS_PAGES_TIME_MSECS);
+			prev_vfs_pages = dev->priv.vfs_pages;
+		}
+		msleep(50);
+	}
+
+	mlx5_core_dbg(dev, "All pages received from %s\n", dev->priv.name);
+	return 0;
+}
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/mellanox/mlx5/core/port.c
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/mellanox/mlx5/core/port.c
@@ -32,6 +32,7 @@
 
 #include <linux/module.h>
 #include <linux/mlx5/driver.h>
+#include <linux/mlx5/port.h>
 #include <linux/mlx5/cmd.h>
 #include "mlx5_core.h"
 
@@ -246,8 +247,8 @@ int mlx5_query_port_admin_status(struct
 }
 EXPORT_SYMBOL_GPL(mlx5_query_port_admin_status);
 
-static void mlx5_query_port_mtu(struct mlx5_core_dev *dev, int *admin_mtu,
-				int *max_mtu, int *oper_mtu, u8 port)
+static void mlx5_query_port_mtu(struct mlx5_core_dev *dev, u16 *admin_mtu,
+				u16 *max_mtu, u16 *oper_mtu, u8 port)
 {
 	u32 in[MLX5_ST_SZ_DW(pmtu_reg)];
 	u32 out[MLX5_ST_SZ_DW(pmtu_reg)];
@@ -267,7 +268,7 @@ static void mlx5_query_port_mtu(struct m
 		*admin_mtu = MLX5_GET(pmtu_reg, out, admin_mtu);
 }
 
-int mlx5_set_port_mtu(struct mlx5_core_dev *dev, int mtu, u8 port)
+int mlx5_set_port_mtu(struct mlx5_core_dev *dev, u16 mtu, u8 port)
 {
 	u32 in[MLX5_ST_SZ_DW(pmtu_reg)];
 	u32 out[MLX5_ST_SZ_DW(pmtu_reg)];
@@ -282,14 +283,14 @@ int mlx5_set_port_mtu(struct mlx5_core_d
 }
 EXPORT_SYMBOL_GPL(mlx5_set_port_mtu);
 
-void mlx5_query_port_max_mtu(struct mlx5_core_dev *dev, int *max_mtu,
+void mlx5_query_port_max_mtu(struct mlx5_core_dev *dev, u16 *max_mtu,
 			     u8 port)
 {
 	mlx5_query_port_mtu(dev, NULL, max_mtu, NULL, port);
 }
 EXPORT_SYMBOL_GPL(mlx5_query_port_max_mtu);
 
-void mlx5_query_port_oper_mtu(struct mlx5_core_dev *dev, int *oper_mtu,
+void mlx5_query_port_oper_mtu(struct mlx5_core_dev *dev, u16 *oper_mtu,
 			      u8 port)
 {
 	mlx5_query_port_mtu(dev, NULL, NULL, oper_mtu, port);
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/mellanox/mlx5/core/sriov.c
@@ -0,0 +1,233 @@
+/*
+ * Copyright (c) 2014, Mellanox Technologies inc.  All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include <linux/pci.h>
+#include <linux/mlx5/driver.h>
+#include "mlx5_core.h"
+#ifdef CONFIG_MLX5_CORE_EN
+#include "eswitch.h"
+#endif
+
+static void enable_vfs(struct mlx5_core_dev *dev, int num_vfs)
+{
+	struct mlx5_core_sriov *sriov = &dev->priv.sriov;
+	int err;
+	int vf;
+
+	for (vf = 1; vf <= num_vfs; vf++) {
+		err = mlx5_core_enable_hca(dev, vf);
+		if (err) {
+			mlx5_core_warn(dev, "failed to enable VF %d\n", vf - 1);
+		} else {
+			sriov->vfs_ctx[vf - 1].enabled = 1;
+			mlx5_core_dbg(dev, "successfully enabled VF %d\n", vf - 1);
+		}
+	}
+}
+
+static void disable_vfs(struct mlx5_core_dev *dev, int num_vfs)
+{
+	struct mlx5_core_sriov *sriov = &dev->priv.sriov;
+	int vf;
+
+	for (vf = 1; vf <= num_vfs; vf++) {
+		if (sriov->vfs_ctx[vf - 1].enabled) {
+			if (mlx5_core_disable_hca(dev, vf))
+				mlx5_core_warn(dev, "failed to disable VF %d\n", vf - 1);
+			else
+				sriov->vfs_ctx[vf - 1].enabled = 0;
+		}
+	}
+}
+
+static int mlx5_core_create_vfs(struct pci_dev *pdev, int num_vfs)
+{
+	struct mlx5_core_dev *dev  = pci_get_drvdata(pdev);
+	int err;
+
+	if (pci_num_vf(pdev))
+		pci_disable_sriov(pdev);
+
+	enable_vfs(dev, num_vfs);
+
+	err = pci_enable_sriov(pdev, num_vfs);
+	if (err) {
+		dev_warn(&pdev->dev, "enable sriov failed %d\n", err);
+		goto ex;
+	}
+
+	return 0;
+
+ex:
+	disable_vfs(dev, num_vfs);
+	return err;
+}
+
+static int mlx5_core_sriov_enable(struct pci_dev *pdev, int num_vfs)
+{
+	struct mlx5_core_dev *dev  = pci_get_drvdata(pdev);
+	struct mlx5_core_sriov *sriov = &dev->priv.sriov;
+	int err;
+
+	kfree(sriov->vfs_ctx);
+	sriov->vfs_ctx = kcalloc(num_vfs, sizeof(*sriov->vfs_ctx), GFP_ATOMIC);
+	if (!sriov->vfs_ctx)
+		return -ENOMEM;
+
+	sriov->enabled_vfs = num_vfs;
+	err = mlx5_core_create_vfs(pdev, num_vfs);
+	if (err) {
+		kfree(sriov->vfs_ctx);
+		sriov->vfs_ctx = NULL;
+		return err;
+	}
+
+	return 0;
+}
+
+static void mlx5_core_init_vfs(struct mlx5_core_dev *dev, int num_vfs)
+{
+	struct mlx5_core_sriov *sriov = &dev->priv.sriov;
+
+	sriov->num_vfs = num_vfs;
+}
+
+static void mlx5_core_cleanup_vfs(struct mlx5_core_dev *dev)
+{
+	struct mlx5_core_sriov *sriov;
+
+	sriov = &dev->priv.sriov;
+	disable_vfs(dev, sriov->num_vfs);
+
+	if (mlx5_wait_for_vf_pages(dev))
+		mlx5_core_warn(dev, "timeout claiming VFs pages\n");
+
+	sriov->num_vfs = 0;
+}
+
+int mlx5_core_sriov_configure(struct pci_dev *pdev, int num_vfs)
+{
+	struct mlx5_core_dev *dev  = pci_get_drvdata(pdev);
+	struct mlx5_core_sriov *sriov = &dev->priv.sriov;
+	int err;
+
+	mlx5_core_dbg(dev, "requsted num_vfs %d\n", num_vfs);
+	if (!mlx5_core_is_pf(dev))
+		return -EPERM;
+
+	mlx5_core_cleanup_vfs(dev);
+
+	if (!num_vfs) {
+#ifdef CONFIG_MLX5_CORE_EN
+		mlx5_eswitch_disable_sriov(dev->priv.eswitch);
+#endif
+		kfree(sriov->vfs_ctx);
+		sriov->vfs_ctx = NULL;
+		if (!pci_vfs_assigned(pdev))
+			pci_disable_sriov(pdev);
+		else
+			pr_info("unloading PF driver while leaving orphan VFs\n");
+		return 0;
+	}
+
+	err = mlx5_core_sriov_enable(pdev, num_vfs);
+	if (err) {
+		dev_warn(&pdev->dev, "mlx5_core_sriov_enable failed %d\n", err);
+		return err;
+	}
+
+	mlx5_core_init_vfs(dev, num_vfs);
+#ifdef CONFIG_MLX5_CORE_EN
+	mlx5_eswitch_enable_sriov(dev->priv.eswitch, num_vfs);
+#endif
+
+	return num_vfs;
+}
+
+static int sync_required(struct pci_dev *pdev)
+{
+	struct mlx5_core_dev *dev  = pci_get_drvdata(pdev);
+	struct mlx5_core_sriov *sriov = &dev->priv.sriov;
+	int cur_vfs = pci_num_vf(pdev);
+
+	if (cur_vfs != sriov->num_vfs) {
+		pr_info("current VFs %d, registered %d - sync needed\n", cur_vfs, sriov->num_vfs);
+		return 1;
+	}
+
+	return 0;
+}
+
+int mlx5_sriov_init(struct mlx5_core_dev *dev)
+{
+	struct mlx5_core_sriov *sriov = &dev->priv.sriov;
+	struct pci_dev *pdev = dev->pdev;
+	int cur_vfs;
+
+	if (!mlx5_core_is_pf(dev))
+		return 0;
+
+	if (!sync_required(dev->pdev))
+		return 0;
+
+	cur_vfs = pci_num_vf(pdev);
+	sriov->vfs_ctx = kcalloc(cur_vfs, sizeof(*sriov->vfs_ctx), GFP_KERNEL);
+	if (!sriov->vfs_ctx)
+		return -ENOMEM;
+
+	sriov->enabled_vfs = cur_vfs;
+
+	mlx5_core_init_vfs(dev, cur_vfs);
+#ifdef CONFIG_MLX5_CORE_EN
+	if (cur_vfs)
+		mlx5_eswitch_enable_sriov(dev->priv.eswitch, cur_vfs);
+#endif
+
+	enable_vfs(dev, cur_vfs);
+
+	return 0;
+}
+
+int mlx5_sriov_cleanup(struct mlx5_core_dev *dev)
+{
+	struct pci_dev *pdev = dev->pdev;
+	int err;
+
+	if (!mlx5_core_is_pf(dev))
+		return 0;
+
+	err = mlx5_core_sriov_configure(pdev, 0);
+	if (err)
+		return err;
+
+	return 0;
+}
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/mellanox/mlx5/core/vport.c
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/mellanox/mlx5/core/vport.c
@@ -36,54 +36,399 @@
 #include <linux/mlx5/vport.h>
 #include "mlx5_core.h"
 
-u8 mlx5_query_vport_state(struct mlx5_core_dev *mdev, u8 opmod)
+static int _mlx5_query_vport_state(struct mlx5_core_dev *mdev, u8 opmod,
+				   u16 vport, u32 *out, int outlen)
 {
-	u32 in[MLX5_ST_SZ_DW(query_vport_state_in)];
-	u32 out[MLX5_ST_SZ_DW(query_vport_state_out)];
 	int err;
+	u32 in[MLX5_ST_SZ_DW(query_vport_state_in)];
 
 	memset(in, 0, sizeof(in));
 
 	MLX5_SET(query_vport_state_in, in, opcode,
 		 MLX5_CMD_OP_QUERY_VPORT_STATE);
 	MLX5_SET(query_vport_state_in, in, op_mod, opmod);
+	MLX5_SET(query_vport_state_in, in, vport_number, vport);
+	if (vport)
+		MLX5_SET(query_vport_state_in, in, other_vport, 1);
 
-	err = mlx5_cmd_exec_check_status(mdev, in, sizeof(in), out,
-					 sizeof(out));
+	err = mlx5_cmd_exec_check_status(mdev, in, sizeof(in), out, outlen);
 	if (err)
 		mlx5_core_warn(mdev, "MLX5_CMD_OP_QUERY_VPORT_STATE failed\n");
 
+	return err;
+}
+
+u8 mlx5_query_vport_state(struct mlx5_core_dev *mdev, u8 opmod, u16 vport)
+{
+	u32 out[MLX5_ST_SZ_DW(query_vport_state_out)] = {0};
+
+	_mlx5_query_vport_state(mdev, opmod, vport, out, sizeof(out));
+
 	return MLX5_GET(query_vport_state_out, out, state);
 }
-EXPORT_SYMBOL(mlx5_query_vport_state);
+EXPORT_SYMBOL_GPL(mlx5_query_vport_state);
+
+u8 mlx5_query_vport_admin_state(struct mlx5_core_dev *mdev, u8 opmod, u16 vport)
+{
+	u32 out[MLX5_ST_SZ_DW(query_vport_state_out)] = {0};
+
+	_mlx5_query_vport_state(mdev, opmod, vport, out, sizeof(out));
+
+	return MLX5_GET(query_vport_state_out, out, admin_state);
+}
+EXPORT_SYMBOL(mlx5_query_vport_admin_state);
+
+int mlx5_modify_vport_admin_state(struct mlx5_core_dev *mdev, u8 opmod,
+				  u16 vport, u8 state)
+{
+	u32 in[MLX5_ST_SZ_DW(modify_vport_state_in)];
+	u32 out[MLX5_ST_SZ_DW(modify_vport_state_out)];
+	int err;
+
+	memset(in, 0, sizeof(in));
+
+	MLX5_SET(modify_vport_state_in, in, opcode,
+		 MLX5_CMD_OP_MODIFY_VPORT_STATE);
+	MLX5_SET(modify_vport_state_in, in, op_mod, opmod);
+	MLX5_SET(modify_vport_state_in, in, vport_number, vport);
+
+	if (vport)
+		MLX5_SET(modify_vport_state_in, in, other_vport, 1);
+
+	MLX5_SET(modify_vport_state_in, in, admin_state, state);
+
+	err = mlx5_cmd_exec_check_status(mdev, in, sizeof(in), out,
+					 sizeof(out));
+	if (err)
+		mlx5_core_warn(mdev, "MLX5_CMD_OP_MODIFY_VPORT_STATE failed\n");
+
+	return err;
+}
+EXPORT_SYMBOL(mlx5_modify_vport_admin_state);
+
+static int mlx5_query_nic_vport_context(struct mlx5_core_dev *mdev, u16 vport,
+					u32 *out, int outlen)
+{
+	u32 in[MLX5_ST_SZ_DW(query_nic_vport_context_in)];
+
+	memset(in, 0, sizeof(in));
+
+	MLX5_SET(query_nic_vport_context_in, in, opcode,
+		 MLX5_CMD_OP_QUERY_NIC_VPORT_CONTEXT);
+
+	MLX5_SET(query_nic_vport_context_in, in, vport_number, vport);
+	if (vport)
+		MLX5_SET(query_nic_vport_context_in, in, other_vport, 1);
+
+	return mlx5_cmd_exec_check_status(mdev, in, sizeof(in), out, outlen);
+}
+
+static int mlx5_modify_nic_vport_context(struct mlx5_core_dev *mdev, void *in,
+					 int inlen)
+{
+	u32 out[MLX5_ST_SZ_DW(modify_nic_vport_context_out)];
+
+	MLX5_SET(modify_nic_vport_context_in, in, opcode,
+		 MLX5_CMD_OP_MODIFY_NIC_VPORT_CONTEXT);
+
+	memset(out, 0, sizeof(out));
+	return mlx5_cmd_exec_check_status(mdev, in, inlen, out, sizeof(out));
+}
 
-void mlx5_query_nic_vport_mac_address(struct mlx5_core_dev *mdev, u8 *addr)
+int mlx5_query_nic_vport_mac_address(struct mlx5_core_dev *mdev,
+				     u16 vport, u8 *addr)
 {
-	u32  in[MLX5_ST_SZ_DW(query_nic_vport_context_in)];
 	u32 *out;
 	int outlen = MLX5_ST_SZ_BYTES(query_nic_vport_context_out);
 	u8 *out_addr;
+	int err;
 
 	out = mlx5_vzalloc(outlen);
 	if (!out)
-		return;
+		return -ENOMEM;
 
 	out_addr = MLX5_ADDR_OF(query_nic_vport_context_out, out,
 				nic_vport_context.permanent_address);
 
+	err = mlx5_query_nic_vport_context(mdev, vport, out, outlen);
+	if (err)
+		goto out;
+
+	ether_addr_copy(addr, &out_addr[2]);
+
+out:
+	kvfree(out);
+	return err;
+}
+EXPORT_SYMBOL_GPL(mlx5_query_nic_vport_mac_address);
+
+int mlx5_modify_nic_vport_mac_address(struct mlx5_core_dev *mdev,
+				      u16 vport, u8 *addr)
+{
+	void *in;
+	int inlen = MLX5_ST_SZ_BYTES(modify_nic_vport_context_in);
+	int err;
+	void *nic_vport_ctx;
+	u8 *perm_mac;
+
+	in = mlx5_vzalloc(inlen);
+	if (!in) {
+		mlx5_core_warn(mdev, "failed to allocate inbox\n");
+		return -ENOMEM;
+	}
+
+	MLX5_SET(modify_nic_vport_context_in, in,
+		 field_select.permanent_address, 1);
+	MLX5_SET(modify_nic_vport_context_in, in, vport_number, vport);
+
+	if (vport)
+		MLX5_SET(modify_nic_vport_context_in, in, other_vport, 1);
+
+	nic_vport_ctx = MLX5_ADDR_OF(modify_nic_vport_context_in,
+				     in, nic_vport_context);
+	perm_mac = MLX5_ADDR_OF(nic_vport_context, nic_vport_ctx,
+				permanent_address);
+
+	ether_addr_copy(&perm_mac[2], addr);
+
+	err = mlx5_modify_nic_vport_context(mdev, in, inlen);
+
+	kvfree(in);
+
+	return err;
+}
+EXPORT_SYMBOL(mlx5_modify_nic_vport_mac_address);
+
+int mlx5_query_nic_vport_mac_list(struct mlx5_core_dev *dev,
+				  u32 vport,
+				  enum mlx5_list_type list_type,
+				  u8 addr_list[][ETH_ALEN],
+				  int *list_size)
+{
+	u32 in[MLX5_ST_SZ_DW(query_nic_vport_context_in)];
+	void *nic_vport_ctx;
+	int max_list_size;
+	int req_list_size;
+	int out_sz;
+	void *out;
+	int err;
+	int i;
+
+	req_list_size = *list_size;
+
+	max_list_size = list_type == MLX5_NVPRT_LIST_TYPE_UC ?
+		1 << MLX5_CAP_GEN(dev, log_max_current_uc_list) :
+		1 << MLX5_CAP_GEN(dev, log_max_current_mc_list);
+
+	if (req_list_size > max_list_size) {
+		mlx5_core_warn(dev, "Requested list size (%d) > (%d) max_list_size\n",
+			       req_list_size, max_list_size);
+		req_list_size = max_list_size;
+	}
+
+	out_sz = MLX5_ST_SZ_BYTES(modify_nic_vport_context_in) +
+			req_list_size * MLX5_ST_SZ_BYTES(mac_address_layout);
+
 	memset(in, 0, sizeof(in));
+	out = kzalloc(out_sz, GFP_KERNEL);
+	if (!out)
+		return -ENOMEM;
 
 	MLX5_SET(query_nic_vport_context_in, in, opcode,
 		 MLX5_CMD_OP_QUERY_NIC_VPORT_CONTEXT);
+	MLX5_SET(query_nic_vport_context_in, in, allowed_list_type, list_type);
+	MLX5_SET(query_nic_vport_context_in, in, vport_number, vport);
 
-	memset(out, 0, outlen);
-	mlx5_cmd_exec_check_status(mdev, in, sizeof(in), out, outlen);
+	if (vport)
+		MLX5_SET(query_nic_vport_context_in, in, other_vport, 1);
 
-	ether_addr_copy(addr, &out_addr[2]);
+	err = mlx5_cmd_exec_check_status(dev, in, sizeof(in), out, out_sz);
+	if (err)
+		goto out;
 
-	kvfree(out);
+	nic_vport_ctx = MLX5_ADDR_OF(query_nic_vport_context_out, out,
+				     nic_vport_context);
+	req_list_size = MLX5_GET(nic_vport_context, nic_vport_ctx,
+				 allowed_list_size);
+
+	*list_size = req_list_size;
+	for (i = 0; i < req_list_size; i++) {
+		u8 *mac_addr = MLX5_ADDR_OF(nic_vport_context,
+					nic_vport_ctx,
+					current_uc_mac_address[i]) + 2;
+		ether_addr_copy(addr_list[i], mac_addr);
+	}
+out:
+	kfree(out);
+	return err;
 }
-EXPORT_SYMBOL(mlx5_query_nic_vport_mac_address);
+EXPORT_SYMBOL_GPL(mlx5_query_nic_vport_mac_list);
+
+int mlx5_modify_nic_vport_mac_list(struct mlx5_core_dev *dev,
+				   enum mlx5_list_type list_type,
+				   u8 addr_list[][ETH_ALEN],
+				   int list_size)
+{
+	u32 out[MLX5_ST_SZ_DW(modify_nic_vport_context_out)];
+	void *nic_vport_ctx;
+	int max_list_size;
+	int in_sz;
+	void *in;
+	int err;
+	int i;
+
+	max_list_size = list_type == MLX5_NVPRT_LIST_TYPE_UC ?
+		 1 << MLX5_CAP_GEN(dev, log_max_current_uc_list) :
+		 1 << MLX5_CAP_GEN(dev, log_max_current_mc_list);
+
+	if (list_size > max_list_size)
+		return -ENOSPC;
+
+	in_sz = MLX5_ST_SZ_BYTES(modify_nic_vport_context_in) +
+		list_size * MLX5_ST_SZ_BYTES(mac_address_layout);
+
+	memset(out, 0, sizeof(out));
+	in = kzalloc(in_sz, GFP_KERNEL);
+	if (!in)
+		return -ENOMEM;
+
+	MLX5_SET(modify_nic_vport_context_in, in, opcode,
+		 MLX5_CMD_OP_MODIFY_NIC_VPORT_CONTEXT);
+	MLX5_SET(modify_nic_vport_context_in, in,
+		 field_select.addresses_list, 1);
+
+	nic_vport_ctx = MLX5_ADDR_OF(modify_nic_vport_context_in, in,
+				     nic_vport_context);
+
+	MLX5_SET(nic_vport_context, nic_vport_ctx,
+		 allowed_list_type, list_type);
+	MLX5_SET(nic_vport_context, nic_vport_ctx,
+		 allowed_list_size, list_size);
+
+	for (i = 0; i < list_size; i++) {
+		u8 *curr_mac = MLX5_ADDR_OF(nic_vport_context,
+					    nic_vport_ctx,
+					    current_uc_mac_address[i]) + 2;
+		ether_addr_copy(curr_mac, addr_list[i]);
+	}
+
+	err = mlx5_cmd_exec_check_status(dev, in, in_sz, out, sizeof(out));
+	kfree(in);
+	return err;
+}
+EXPORT_SYMBOL_GPL(mlx5_modify_nic_vport_mac_list);
+
+int mlx5_query_nic_vport_vlans(struct mlx5_core_dev *dev,
+			       u32 vport,
+			       u16 vlans[],
+			       int *size)
+{
+	u32 in[MLX5_ST_SZ_DW(query_nic_vport_context_in)];
+	void *nic_vport_ctx;
+	int req_list_size;
+	int max_list_size;
+	int out_sz;
+	void *out;
+	int err;
+	int i;
+
+	req_list_size = *size;
+	max_list_size = 1 << MLX5_CAP_GEN(dev, log_max_vlan_list);
+	if (req_list_size > max_list_size) {
+		mlx5_core_warn(dev, "Requested list size (%d) > (%d) max list size\n",
+			       req_list_size, max_list_size);
+		req_list_size = max_list_size;
+	}
+
+	out_sz = MLX5_ST_SZ_BYTES(modify_nic_vport_context_in) +
+			req_list_size * MLX5_ST_SZ_BYTES(vlan_layout);
+
+	memset(in, 0, sizeof(in));
+	out = kzalloc(out_sz, GFP_KERNEL);
+	if (!out)
+		return -ENOMEM;
+
+	MLX5_SET(query_nic_vport_context_in, in, opcode,
+		 MLX5_CMD_OP_QUERY_NIC_VPORT_CONTEXT);
+	MLX5_SET(query_nic_vport_context_in, in, allowed_list_type,
+		 MLX5_NVPRT_LIST_TYPE_VLAN);
+	MLX5_SET(query_nic_vport_context_in, in, vport_number, vport);
+
+	if (vport)
+		MLX5_SET(query_nic_vport_context_in, in, other_vport, 1);
+
+	err = mlx5_cmd_exec_check_status(dev, in, sizeof(in), out, out_sz);
+	if (err)
+		goto out;
+
+	nic_vport_ctx = MLX5_ADDR_OF(query_nic_vport_context_out, out,
+				     nic_vport_context);
+	req_list_size = MLX5_GET(nic_vport_context, nic_vport_ctx,
+				 allowed_list_size);
+
+	*size = req_list_size;
+	for (i = 0; i < req_list_size; i++) {
+		void *vlan_addr = MLX5_ADDR_OF(nic_vport_context,
+					       nic_vport_ctx,
+					       current_uc_mac_address[i]);
+		vlans[i] = MLX5_GET(vlan_layout, vlan_addr, vlan);
+	}
+out:
+	kfree(out);
+	return err;
+}
+EXPORT_SYMBOL_GPL(mlx5_query_nic_vport_vlans);
+
+int mlx5_modify_nic_vport_vlans(struct mlx5_core_dev *dev,
+				u16 vlans[],
+				int list_size)
+{
+	u32 out[MLX5_ST_SZ_DW(modify_nic_vport_context_out)];
+	void *nic_vport_ctx;
+	int max_list_size;
+	int in_sz;
+	void *in;
+	int err;
+	int i;
+
+	max_list_size = 1 << MLX5_CAP_GEN(dev, log_max_vlan_list);
+
+	if (list_size > max_list_size)
+		return -ENOSPC;
+
+	in_sz = MLX5_ST_SZ_BYTES(modify_nic_vport_context_in) +
+		list_size * MLX5_ST_SZ_BYTES(vlan_layout);
+
+	memset(out, 0, sizeof(out));
+	in = kzalloc(in_sz, GFP_KERNEL);
+	if (!in)
+		return -ENOMEM;
+
+	MLX5_SET(modify_nic_vport_context_in, in, opcode,
+		 MLX5_CMD_OP_MODIFY_NIC_VPORT_CONTEXT);
+	MLX5_SET(modify_nic_vport_context_in, in,
+		 field_select.addresses_list, 1);
+
+	nic_vport_ctx = MLX5_ADDR_OF(modify_nic_vport_context_in, in,
+				     nic_vport_context);
+
+	MLX5_SET(nic_vport_context, nic_vport_ctx,
+		 allowed_list_type, MLX5_NVPRT_LIST_TYPE_VLAN);
+	MLX5_SET(nic_vport_context, nic_vport_ctx,
+		 allowed_list_size, list_size);
+
+	for (i = 0; i < list_size; i++) {
+		void *vlan_addr = MLX5_ADDR_OF(nic_vport_context,
+					       nic_vport_ctx,
+					       current_uc_mac_address[i]);
+		MLX5_SET(vlan_layout, vlan_addr, vlan, vlans[i]);
+	}
+
+	err = mlx5_cmd_exec_check_status(dev, in, in_sz, out, sizeof(out));
+	kfree(in);
+	return err;
+}
+EXPORT_SYMBOL_GPL(mlx5_modify_nic_vport_vlans);
 
 int mlx5_query_hca_vport_gid(struct mlx5_core_dev *dev, u8 other_vport,
 			     u8 port_num, u16  vf_num, u16 gid_index,
@@ -343,3 +688,65 @@ int mlx5_query_hca_vport_node_guid(struc
 	return err;
 }
 EXPORT_SYMBOL_GPL(mlx5_query_hca_vport_node_guid);
+
+int mlx5_query_nic_vport_promisc(struct mlx5_core_dev *mdev,
+				 u32 vport,
+				 int *promisc_uc,
+				 int *promisc_mc,
+				 int *promisc_all)
+{
+	u32 *out;
+	int outlen = MLX5_ST_SZ_BYTES(query_nic_vport_context_out);
+	int err;
+
+	out = kzalloc(outlen, GFP_KERNEL);
+	if (!out)
+		return -ENOMEM;
+
+	err = mlx5_query_nic_vport_context(mdev, vport, out, outlen);
+	if (err)
+		goto out;
+
+	*promisc_uc = MLX5_GET(query_nic_vport_context_out, out,
+			       nic_vport_context.promisc_uc);
+	*promisc_mc = MLX5_GET(query_nic_vport_context_out, out,
+			       nic_vport_context.promisc_mc);
+	*promisc_all = MLX5_GET(query_nic_vport_context_out, out,
+				nic_vport_context.promisc_all);
+
+out:
+	kfree(out);
+	return err;
+}
+EXPORT_SYMBOL_GPL(mlx5_query_nic_vport_promisc);
+
+int mlx5_modify_nic_vport_promisc(struct mlx5_core_dev *mdev,
+				  int promisc_uc,
+				  int promisc_mc,
+				  int promisc_all)
+{
+	void *in;
+	int inlen = MLX5_ST_SZ_BYTES(modify_nic_vport_context_in);
+	int err;
+
+	in = mlx5_vzalloc(inlen);
+	if (!in) {
+		mlx5_core_err(mdev, "failed to allocate inbox\n");
+		return -ENOMEM;
+	}
+
+	MLX5_SET(modify_nic_vport_context_in, in, field_select.promisc, 1);
+	MLX5_SET(modify_nic_vport_context_in, in,
+		 nic_vport_context.promisc_uc, promisc_uc);
+	MLX5_SET(modify_nic_vport_context_in, in,
+		 nic_vport_context.promisc_mc, promisc_mc);
+	MLX5_SET(modify_nic_vport_context_in, in,
+		 nic_vport_context.promisc_all, promisc_all);
+
+	err = mlx5_modify_nic_vport_context(mdev, in, inlen);
+
+	kvfree(in);
+
+	return err;
+}
+EXPORT_SYMBOL_GPL(mlx5_modify_nic_vport_promisc);
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/mellanox/mlxsw/spectrum.h
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/mellanox/mlxsw/spectrum.h
@@ -61,6 +61,8 @@ struct mlxsw_sp {
 #define MLXSW_SP_DEFAULT_LEARNING_INTERVAL 100
 		unsigned int interval; /* ms */
 	} fdb_notify;
+#define MLXSW_SP_MIN_AGEING_TIME 10
+#define MLXSW_SP_MAX_AGEING_TIME 1000000
 #define MLXSW_SP_DEFAULT_AGEING_TIME 300
 	u32 ageing_time;
 	struct {
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
@@ -45,6 +45,7 @@
 #include <linux/if_bridge.h>
 #include <linux/workqueue.h>
 #include <linux/jiffies.h>
+#include <linux/rtnetlink.h>
 #include <net/switchdev.h>
 
 #include "spectrum.h"
@@ -231,8 +232,13 @@ static int mlxsw_sp_port_attr_br_ageing_
 	unsigned long ageing_jiffies = clock_t_to_jiffies(ageing_clock_t);
 	u32 ageing_time = jiffies_to_msecs(ageing_jiffies) / 1000;
 
-	if (switchdev_trans_ph_prepare(trans))
-		return 0;
+	if (switchdev_trans_ph_prepare(trans)) {
+		if (ageing_time < MLXSW_SP_MIN_AGEING_TIME ||
+		    ageing_time > MLXSW_SP_MAX_AGEING_TIME)
+			return -ERANGE;
+		else
+			return 0;
+	}
 
 	return mlxsw_sp_ageing_set(mlxsw_sp, ageing_time);
 }
@@ -812,6 +818,7 @@ static void mlxsw_sp_fdb_notify_work(str
 
 	mlxsw_sp = container_of(work, struct mlxsw_sp, fdb_notify.dw.work);
 
+	rtnl_lock();
 	do {
 		mlxsw_reg_sfn_pack(sfn_pl);
 		err = mlxsw_reg_query(mlxsw_sp->core, MLXSW_REG(sfn), sfn_pl);
@@ -824,6 +831,7 @@ static void mlxsw_sp_fdb_notify_work(str
 			mlxsw_sp_fdb_notify_rec_process(mlxsw_sp, sfn_pl, i);
 
 	} while (num_rec);
+	rtnl_unlock();
 
 	kfree(sfn_pl);
 	mlxsw_sp_fdb_notify_work_schedule(mlxsw_sp);
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/neterion/vxge/vxge-main.c
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/neterion/vxge/vxge-main.c
@@ -4219,6 +4219,9 @@ out:
 	return ret;
 }
 
+#define VXGE_PXE_FIRMWARE "vxge/X3fw-pxe.ncf"
+#define VXGE_FIRMWARE "vxge/X3fw.ncf"
+
 static int vxge_probe_fw_update(struct vxgedev *vdev)
 {
 	u32 maj, min, bld;
@@ -4261,9 +4264,9 @@ static int vxge_probe_fw_update(struct v
 			}
 	}
 	if (gpxe)
-		fw_name = "vxge/X3fw-pxe.ncf";
+		fw_name = VXGE_PXE_FIRMWARE;
 	else
-		fw_name = "vxge/X3fw.ncf";
+		fw_name = VXGE_FIRMWARE;
 
 	ret = vxge_fw_upgrade(vdev, fw_name, 0);
 	/* -EINVAL and -ENOENT are not fatal errors for flashing firmware on
@@ -4868,3 +4871,5 @@ vxge_closer(void)
 }
 module_init(vxge_starter);
 module_exit(vxge_closer);
+MODULE_FIRMWARE(VXGE_PXE_FIRMWARE);
+MODULE_FIRMWARE(VXGE_FIRMWARE);
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/qlogic/qed/qed_main.c
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/qlogic/qed/qed_main.c
@@ -45,6 +45,8 @@ MODULE_VERSION(DRV_MODULE_VERSION);
 #define QED_FW_FILE_NAME	\
 	"qed/qed_init_values_zipped-" FW_FILE_VERSION ".bin"
 
+MODULE_FIRMWARE(QED_FW_FILE_NAME);
+
 static int __init qed_init(void)
 {
 	pr_notice("qed_init called\n");
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/qlogic/qed/qed_spq.c
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/qlogic/qed/qed_spq.c
@@ -794,13 +794,12 @@ int qed_spq_completion(struct qed_hwfn *
 			 * in a bitmap and increasing the chain consumer only
 			 * for the first successive completed entries.
 			 */
-			bitmap_set(p_spq->p_comp_bitmap, pos, SPQ_RING_SIZE);
+			__set_bit(pos, p_spq->p_comp_bitmap);
 
 			while (test_bit(p_spq->comp_bitmap_idx,
 					p_spq->p_comp_bitmap)) {
-				bitmap_clear(p_spq->p_comp_bitmap,
-					     p_spq->comp_bitmap_idx,
-					     SPQ_RING_SIZE);
+				__clear_bit(p_spq->comp_bitmap_idx,
+					    p_spq->p_comp_bitmap);
 				p_spq->comp_bitmap_idx++;
 				qed_chain_return_produced(&p_spq->chain);
 			}
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
@@ -566,6 +566,7 @@ struct qlcnic_adapter_stats {
 	u64  tx_dma_map_error;
 	u64  spurious_intr;
 	u64  mac_filter_limit_overrun;
+	u64  mbx_spurious_intr;
 };
 
 /*
@@ -1099,7 +1100,7 @@ struct qlcnic_mailbox {
 	unsigned long		status;
 	spinlock_t		queue_lock;	/* Mailbox queue lock */
 	spinlock_t		aen_lock;	/* Mailbox response/AEN lock */
-	atomic_t		rsp_status;
+	u32			rsp_status;
 	u32			num_cmds;
 };
 
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
@@ -491,7 +491,7 @@ irqreturn_t qlcnic_83xx_clear_legacy_int
 
 static inline void qlcnic_83xx_notify_mbx_response(struct qlcnic_mailbox *mbx)
 {
-	atomic_set(&mbx->rsp_status, QLC_83XX_MBX_RESPONSE_ARRIVED);
+	mbx->rsp_status = QLC_83XX_MBX_RESPONSE_ARRIVED;
 	complete(&mbx->completion);
 }
 
@@ -510,7 +510,7 @@ static void qlcnic_83xx_poll_process_aen
 	if (event &  QLCNIC_MBX_ASYNC_EVENT) {
 		__qlcnic_83xx_process_aen(adapter);
 	} else {
-		if (atomic_read(&mbx->rsp_status) != rsp_status)
+		if (mbx->rsp_status != rsp_status)
 			qlcnic_83xx_notify_mbx_response(mbx);
 	}
 out:
@@ -1023,7 +1023,7 @@ static void qlcnic_83xx_process_aen(stru
 		if (event &  QLCNIC_MBX_ASYNC_EVENT) {
 			__qlcnic_83xx_process_aen(adapter);
 		} else {
-			if (atomic_read(&mbx->rsp_status) != rsp_status)
+			if (mbx->rsp_status != rsp_status)
 				qlcnic_83xx_notify_mbx_response(mbx);
 		}
 	}
@@ -2338,9 +2338,9 @@ static void qlcnic_83xx_handle_link_aen(
 
 static irqreturn_t qlcnic_83xx_handle_aen(int irq, void *data)
 {
+	u32 mask, resp, event, rsp_status = QLC_83XX_MBX_RESPONSE_ARRIVED;
 	struct qlcnic_adapter *adapter = data;
 	struct qlcnic_mailbox *mbx;
-	u32 mask, resp, event;
 	unsigned long flags;
 
 	mbx = adapter->ahw->mailbox;
@@ -2350,10 +2350,14 @@ static irqreturn_t qlcnic_83xx_handle_ae
 		goto out;
 
 	event = readl(QLCNIC_MBX_FW(adapter->ahw, 0));
-	if (event &  QLCNIC_MBX_ASYNC_EVENT)
+	if (event &  QLCNIC_MBX_ASYNC_EVENT) {
 		__qlcnic_83xx_process_aen(adapter);
-	else
-		qlcnic_83xx_notify_mbx_response(mbx);
+	} else {
+		if (mbx->rsp_status != rsp_status)
+			qlcnic_83xx_notify_mbx_response(mbx);
+		else
+			adapter->stats.mbx_spurious_intr++;
+	}
 
 out:
 	mask = QLCRDX(adapter->ahw, QLCNIC_DEF_INT_MASK);
@@ -4050,10 +4054,10 @@ static void qlcnic_83xx_mailbox_worker(s
 	struct qlcnic_adapter *adapter = mbx->adapter;
 	const struct qlcnic_mbx_ops *mbx_ops = mbx->ops;
 	struct device *dev = &adapter->pdev->dev;
-	atomic_t *rsp_status = &mbx->rsp_status;
 	struct list_head *head = &mbx->cmd_q;
 	struct qlcnic_hardware_context *ahw;
 	struct qlcnic_cmd_args *cmd = NULL;
+	unsigned long flags;
 
 	ahw = adapter->ahw;
 
@@ -4063,7 +4067,9 @@ static void qlcnic_83xx_mailbox_worker(s
 			return;
 		}
 
-		atomic_set(rsp_status, QLC_83XX_MBX_RESPONSE_WAIT);
+		spin_lock_irqsave(&mbx->aen_lock, flags);
+		mbx->rsp_status = QLC_83XX_MBX_RESPONSE_WAIT;
+		spin_unlock_irqrestore(&mbx->aen_lock, flags);
 
 		spin_lock(&mbx->queue_lock);
 
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c
@@ -59,7 +59,8 @@ static const struct qlcnic_stats qlcnic_
 	 QLC_OFF(stats.mac_filter_limit_overrun)},
 	{"spurious intr", QLC_SIZEOF(stats.spurious_intr),
 	 QLC_OFF(stats.spurious_intr)},
-
+	{"mbx spurious intr", QLC_SIZEOF(stats.mbx_spurious_intr),
+	 QLC_OFF(stats.mbx_spurious_intr)},
 };
 
 static const char qlcnic_device_gstrings_stats[][ETH_GSTRING_LEN] = {
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/qlogic/qlge/qlge_main.c
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/qlogic/qlge/qlge_main.c
@@ -1648,7 +1648,18 @@ static void ql_process_mac_rx_skb(struct
 		return;
 	}
 	skb_reserve(new_skb, NET_IP_ALIGN);
+
+	pci_dma_sync_single_for_cpu(qdev->pdev,
+				    dma_unmap_addr(sbq_desc, mapaddr),
+				    dma_unmap_len(sbq_desc, maplen),
+				    PCI_DMA_FROMDEVICE);
+
 	memcpy(skb_put(new_skb, length), skb->data, length);
+
+	pci_dma_sync_single_for_device(qdev->pdev,
+				       dma_unmap_addr(sbq_desc, mapaddr),
+				       dma_unmap_len(sbq_desc, maplen),
+				       PCI_DMA_FROMDEVICE);
 	skb = new_skb;
 
 	/* Frame error, so drop the packet. */
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/qualcomm/qca_spi.c
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/qualcomm/qca_spi.c
@@ -811,7 +811,7 @@ qcaspi_netdev_setup(struct net_device *d
 	dev->netdev_ops = &qcaspi_netdev_ops;
 	qcaspi_set_ethtool_ops(dev);
 	dev->watchdog_timeo = QCASPI_TX_TIMEOUT;
-	dev->flags = IFF_MULTICAST;
+	dev->priv_flags &= ~IFF_TX_SKB_SHARING;
 	dev->tx_queue_len = 100;
 
 	qca = netdev_priv(dev);
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/renesas/sh_eth.c
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/renesas/sh_eth.c
@@ -1185,11 +1185,8 @@ static void sh_eth_ring_format(struct ne
 			break;
 		sh_eth_set_receive_align(skb);
 
-		/* RX descriptor */
-		rxdesc = &mdp->rx_ring[i];
 		/* The size of the buffer is a multiple of 32 bytes. */
 		buf_len = ALIGN(mdp->rx_buf_sz, 32);
-		rxdesc->len = cpu_to_edmac(mdp, buf_len << 16);
 		dma_addr = dma_map_single(&ndev->dev, skb->data, buf_len,
 					  DMA_FROM_DEVICE);
 		if (dma_mapping_error(&ndev->dev, dma_addr)) {
@@ -1197,6 +1194,10 @@ static void sh_eth_ring_format(struct ne
 			break;
 		}
 		mdp->rx_skbuff[i] = skb;
+
+		/* RX descriptor */
+		rxdesc = &mdp->rx_ring[i];
+		rxdesc->len = cpu_to_edmac(mdp, buf_len << 16);
 		rxdesc->addr = cpu_to_edmac(mdp, dma_addr);
 		rxdesc->status = cpu_to_edmac(mdp, RD_RACT | RD_RFP);
 
@@ -1212,7 +1213,8 @@ static void sh_eth_ring_format(struct ne
 	mdp->dirty_rx = (u32) (i - mdp->num_rx_ring);
 
 	/* Mark the last entry as wrapping the ring. */
-	rxdesc->status |= cpu_to_edmac(mdp, RD_RDLE);
+	if (rxdesc)
+		rxdesc->status |= cpu_to_edmac(mdp, RD_RDLE);
 
 	memset(mdp->tx_ring, 0, tx_ringsize);
 
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/rocker/rocker.c
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/rocker/rocker.c
@@ -239,6 +239,7 @@ struct rocker {
 	struct {
 		u64 id;
 	} hw;
+	unsigned long ageing_time;
 	spinlock_t cmd_ring_lock;		/* for cmd ring accesses */
 	struct rocker_dma_ring_info cmd_ring;
 	struct rocker_dma_ring_info event_ring;
@@ -3531,12 +3532,14 @@ static void rocker_port_fdb_learn_work(s
 	info.addr = lw->addr;
 	info.vid = lw->vid;
 
+	rtnl_lock();
 	if (learned && removing)
 		call_switchdev_notifiers(SWITCHDEV_FDB_DEL,
 					 lw->rocker_port->dev, &info.info);
 	else if (learned && !removing)
 		call_switchdev_notifiers(SWITCHDEV_FDB_ADD,
 					 lw->rocker_port->dev, &info.info);
+	rtnl_unlock();
 
 	rocker_port_kfree(lw->trans, work);
 }
@@ -3702,7 +3705,7 @@ static void rocker_fdb_cleanup(unsigned
 	struct rocker_port *rocker_port;
 	struct rocker_fdb_tbl_entry *entry;
 	struct hlist_node *tmp;
-	unsigned long next_timer = jiffies + BR_MIN_AGEING_TIME;
+	unsigned long next_timer = jiffies + rocker->ageing_time;
 	unsigned long expires;
 	unsigned long lock_flags;
 	int flags = ROCKER_OP_FLAG_NOWAIT | ROCKER_OP_FLAG_REMOVE |
@@ -4365,8 +4368,12 @@ static int rocker_port_bridge_ageing_tim
 					  struct switchdev_trans *trans,
 					  u32 ageing_time)
 {
+	struct rocker *rocker = rocker_port->rocker;
+
 	if (!switchdev_trans_ph_prepare(trans)) {
 		rocker_port->ageing_time = clock_t_to_jiffies(ageing_time);
+		if (rocker_port->ageing_time < rocker->ageing_time)
+			rocker->ageing_time = rocker_port->ageing_time;
 		mod_timer(&rocker_port->rocker->fdb_cleanup_timer, jiffies);
 	}
 
@@ -4468,7 +4475,7 @@ static int rocker_port_obj_add(struct ne
 		fib4 = SWITCHDEV_OBJ_IPV4_FIB(obj);
 		err = rocker_port_fib_ipv4(rocker_port, trans,
 					   htonl(fib4->dst), fib4->dst_len,
-					   &fib4->fi, fib4->tb_id, 0);
+					   fib4->fi, fib4->tb_id, 0);
 		break;
 	case SWITCHDEV_OBJ_ID_PORT_FDB:
 		err = rocker_port_fdb_add(rocker_port, trans,
@@ -4540,7 +4547,7 @@ static int rocker_port_obj_del(struct ne
 		fib4 = SWITCHDEV_OBJ_IPV4_FIB(obj);
 		err = rocker_port_fib_ipv4(rocker_port, NULL,
 					   htonl(fib4->dst), fib4->dst_len,
-					   &fib4->fi, fib4->tb_id,
+					   fib4->fi, fib4->tb_id,
 					   ROCKER_OP_FLAG_REMOVE);
 		break;
 	case SWITCHDEV_OBJ_ID_PORT_FDB:
@@ -5204,10 +5211,13 @@ static int rocker_probe(struct pci_dev *
 		goto err_init_tbls;
 	}
 
+	rocker->ageing_time = BR_DEFAULT_AGEING_TIME;
 	setup_timer(&rocker->fdb_cleanup_timer, rocker_fdb_cleanup,
 		    (unsigned long) rocker);
 	mod_timer(&rocker->fdb_cleanup_timer, jiffies);
 
+	rocker->ageing_time = BR_DEFAULT_AGEING_TIME;
+
 	err = rocker_probe_ports(rocker);
 	if (err) {
 		dev_err(&pdev->dev, "failed to probe ports\n");
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/sfc/ef10.c
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/sfc/ef10.c
@@ -619,6 +619,17 @@ fail:
 	return rc;
 }
 
+static void efx_ef10_forget_old_piobufs(struct efx_nic *efx)
+{
+	struct efx_channel *channel;
+	struct efx_tx_queue *tx_queue;
+
+	/* All our existing PIO buffers went away */
+	efx_for_each_channel(channel, efx)
+		efx_for_each_channel_tx_queue(tx_queue, channel)
+			tx_queue->piobuf = NULL;
+}
+
 #else /* !EFX_USE_PIO */
 
 static int efx_ef10_alloc_piobufs(struct efx_nic *efx, unsigned int n)
@@ -635,6 +646,10 @@ static void efx_ef10_free_piobufs(struct
 {
 }
 
+static void efx_ef10_forget_old_piobufs(struct efx_nic *efx)
+{
+}
+
 #endif /* EFX_USE_PIO */
 
 static void efx_ef10_remove(struct efx_nic *efx)
@@ -1018,6 +1033,7 @@ static void efx_ef10_reset_mc_allocation
 	nic_data->must_realloc_vis = true;
 	nic_data->must_restore_filters = true;
 	nic_data->must_restore_piobufs = true;
+	efx_ef10_forget_old_piobufs(efx);
 	nic_data->rx_rss_context = EFX_EF10_RSS_CONTEXT_INVALID;
 
 	/* Driver-created vswitches and vports must be re-created */
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/sfc/efx.h
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/sfc/efx.h
@@ -32,7 +32,8 @@ netdev_tx_t efx_hard_start_xmit(struct s
 				struct net_device *net_dev);
 netdev_tx_t efx_enqueue_skb(struct efx_tx_queue *tx_queue, struct sk_buff *skb);
 void efx_xmit_done(struct efx_tx_queue *tx_queue, unsigned int index);
-int efx_setup_tc(struct net_device *net_dev, u8 num_tc);
+int efx_setup_tc(struct net_device *net_dev, u32 handle, __be16 proto,
+		 struct tc_to_netdev *tc);
 unsigned int efx_tx_max_skb_descs(struct efx_nic *efx);
 extern unsigned int efx_piobuf_size;
 extern bool efx_separate_tx_channels;
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/sfc/tx.c
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/sfc/tx.c
@@ -562,14 +562,20 @@ void efx_init_tx_queue_core_txq(struct e
 				     efx->n_tx_channels : 0));
 }
 
-int efx_setup_tc(struct net_device *net_dev, u8 num_tc)
+int efx_setup_tc(struct net_device *net_dev, u32 handle, __be16 proto,
+		 struct tc_to_netdev *ntc)
 {
 	struct efx_nic *efx = netdev_priv(net_dev);
 	struct efx_channel *channel;
 	struct efx_tx_queue *tx_queue;
-	unsigned tc;
+	unsigned tc, num_tc;
 	int rc;
 
+	if (handle != TC_H_ROOT || ntc->type != TC_SETUP_MQPRIO)
+		return -EINVAL;
+
+	num_tc = ntc->tc;
+
 	if (efx_nic_rev(efx) < EFX_REV_FALCON_B0 || num_tc > EFX_MAX_TX_TC)
 		return -EINVAL;
 
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/smsc/smc91x.c
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/smsc/smc91x.c
@@ -2269,6 +2269,13 @@ static int smc_drv_probe(struct platform
 	if (pd) {
 		memcpy(&lp->cfg, pd, sizeof(lp->cfg));
 		lp->io_shift = SMC91X_IO_SHIFT(lp->cfg.flags);
+
+		if (!SMC_8BIT(lp) && !SMC_16BIT(lp)) {
+			dev_err(&pdev->dev,
+				"at least one of 8-bit or 16-bit access support is required.\n");
+			ret = -ENXIO;
+			goto out_free_netdev;
+		}
 	}
 
 #if IS_BUILTIN(CONFIG_OF)
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/smsc/smc91x.h
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/smsc/smc91x.h
@@ -37,6 +37,27 @@
 #include <linux/smc91x.h>
 
 /*
+ * Any 16-bit access is performed with two 8-bit accesses if the hardware
+ * can't do it directly. Most registers are 16-bit so those are mandatory.
+ */
+#define SMC_outw_b(x, a, r)						\
+	do {								\
+		unsigned int __val16 = (x);				\
+		unsigned int __reg = (r);				\
+		SMC_outb(__val16, a, __reg);				\
+		SMC_outb(__val16 >> 8, a, __reg + (1 << SMC_IO_SHIFT));	\
+	} while (0)
+
+#define SMC_inw_b(a, r)							\
+	({								\
+		unsigned int __val16;					\
+		unsigned int __reg = r;					\
+		__val16  = SMC_inb(a, __reg);				\
+		__val16 |= SMC_inb(a, __reg + (1 << SMC_IO_SHIFT)) << 8; \
+		__val16;						\
+	})
+
+/*
  * Define your architecture specific bus configuration parameters here.
  */
 
@@ -55,10 +76,30 @@
 #define SMC_IO_SHIFT		(lp->io_shift)
 
 #define SMC_inb(a, r)		readb((a) + (r))
-#define SMC_inw(a, r)		readw((a) + (r))
+#define SMC_inw(a, r)							\
+	({								\
+		unsigned int __smc_r = r;				\
+		SMC_16BIT(lp) ? readw((a) + __smc_r) :			\
+		SMC_8BIT(lp) ? SMC_inw_b(a, __smc_r) :			\
+		({ BUG(); 0; });					\
+	})
+
 #define SMC_inl(a, r)		readl((a) + (r))
 #define SMC_outb(v, a, r)	writeb(v, (a) + (r))
+#define SMC_outw(v, a, r)						\
+	do {								\
+		unsigned int __v = v, __smc_r = r;			\
+		if (SMC_16BIT(lp))					\
+			__SMC_outw(__v, a, __smc_r);			\
+		else if (SMC_8BIT(lp))					\
+			SMC_outw_b(__v, a, __smc_r);			\
+		else							\
+			BUG();						\
+	} while (0)
+
 #define SMC_outl(v, a, r)	writel(v, (a) + (r))
+#define SMC_insb(a, r, p, l)	readsb((a) + (r), p, l)
+#define SMC_outsb(a, r, p, l)	writesb((a) + (r), p, l)
 #define SMC_insw(a, r, p, l)	readsw((a) + (r), p, l)
 #define SMC_outsw(a, r, p, l)	writesw((a) + (r), p, l)
 #define SMC_insl(a, r, p, l)	readsl((a) + (r), p, l)
@@ -66,7 +107,7 @@
 #define SMC_IRQ_FLAGS		(-1)	/* from resource */
 
 /* We actually can't write halfwords properly if not word aligned */
-static inline void SMC_outw(u16 val, void __iomem *ioaddr, int reg)
+static inline void __SMC_outw(u16 val, void __iomem *ioaddr, int reg)
 {
 	if ((machine_is_mainstone() || machine_is_stargate2() ||
 	     machine_is_pxa_idp()) && reg & 2) {
@@ -405,24 +446,8 @@ smc_pxa_dma_insw(void __iomem *ioaddr, s
 
 #if ! SMC_CAN_USE_16BIT
 
-/*
- * Any 16-bit access is performed with two 8-bit accesses if the hardware
- * can't do it directly. Most registers are 16-bit so those are mandatory.
- */
-#define SMC_outw(x, ioaddr, reg)					\
-	do {								\
-		unsigned int __val16 = (x);				\
-		SMC_outb( __val16, ioaddr, reg );			\
-		SMC_outb( __val16 >> 8, ioaddr, reg + (1 << SMC_IO_SHIFT));\
-	} while (0)
-#define SMC_inw(ioaddr, reg)						\
-	({								\
-		unsigned int __val16;					\
-		__val16 =  SMC_inb( ioaddr, reg );			\
-		__val16 |= SMC_inb( ioaddr, reg + (1 << SMC_IO_SHIFT)) << 8; \
-		__val16;						\
-	})
-
+#define SMC_outw(x, ioaddr, reg)	SMC_outw_b(x, ioaddr, reg)
+#define SMC_inw(ioaddr, reg)		SMC_inw_b(ioaddr, reg)
 #define SMC_insw(a, r, p, l)		BUG()
 #define SMC_outsw(a, r, p, l)		BUG()
 
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/synopsys/dwc_eth_qos.c
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/synopsys/dwc_eth_qos.c
@@ -2107,7 +2107,7 @@ static int dwceqos_tx_frags(struct sk_bu
 			dd = &lp->tx_descs[lp->tx_next];
 
 			/* Set DMA Descriptor fields */
-			dd->des0 = dma_handle;
+			dd->des0 = dma_handle + consumed_size;
 			dd->des1 = 0;
 			dd->des2 = dma_size;
 
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/ti/cpsw.c
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/ti/cpsw.c
@@ -742,6 +742,7 @@ static void cpsw_rx_handler(void *token,
 		netif_receive_skb(skb);
 		ndev->stats.rx_bytes += len;
 		ndev->stats.rx_packets++;
+		kmemleak_not_leak(new_skb);
 	} else {
 		ndev->stats.rx_dropped++;
 		new_skb = skb;
@@ -1243,6 +1244,7 @@ static void cpsw_slave_stop(struct cpsw_
 	slave->phy = NULL;
 	cpsw_ale_control_set(priv->ale, slave_port,
 			     ALE_PORT_STATE, ALE_PORT_STATE_DISABLE);
+	soft_reset_slave(slave);
 }
 
 static int cpsw_ndo_open(struct net_device *ndev)
@@ -1251,12 +1253,16 @@ static int cpsw_ndo_open(struct net_devi
 	int i, ret;
 	u32 reg;
 
+	ret = pm_runtime_get_sync(&priv->pdev->dev);
+	if (ret < 0) {
+		pm_runtime_put_noidle(&priv->pdev->dev);
+		return ret;
+	}
+
 	if (!cpsw_common_res_usage_state(priv))
 		cpsw_intr_disable(priv);
 	netif_carrier_off(ndev);
 
-	pm_runtime_get_sync(&priv->pdev->dev);
-
 	reg = priv->version;
 
 	dev_info(priv->dev, "initializing cpsw version %d.%d (%d)\n",
@@ -1322,6 +1328,7 @@ static int cpsw_ndo_open(struct net_devi
 				kfree_skb(skb);
 				goto err_cleanup;
 			}
+			kmemleak_not_leak(skb);
 		}
 		/* continue even if we didn't manage to submit all
 		 * receive descs
@@ -1611,10 +1618,17 @@ static int cpsw_ndo_set_mac_address(stru
 	struct sockaddr *addr = (struct sockaddr *)p;
 	int flags = 0;
 	u16 vid = 0;
+	int ret;
 
 	if (!is_valid_ether_addr(addr->sa_data))
 		return -EADDRNOTAVAIL;
 
+	ret = pm_runtime_get_sync(&priv->pdev->dev);
+	if (ret < 0) {
+		pm_runtime_put_noidle(&priv->pdev->dev);
+		return ret;
+	}
+
 	if (priv->data.dual_emac) {
 		vid = priv->slaves[priv->emac_port].port_vlan;
 		flags = ALE_VLAN;
@@ -1629,6 +1643,8 @@ static int cpsw_ndo_set_mac_address(stru
 	memcpy(ndev->dev_addr, priv->mac_addr, ETH_ALEN);
 	for_each_slave(priv, cpsw_set_slave_mac, priv);
 
+	pm_runtime_put(&priv->pdev->dev);
+
 	return 0;
 }
 
@@ -1693,10 +1709,17 @@ static int cpsw_ndo_vlan_rx_add_vid(stru
 				    __be16 proto, u16 vid)
 {
 	struct cpsw_priv *priv = netdev_priv(ndev);
+	int ret;
 
 	if (vid == priv->data.default_vlan)
 		return 0;
 
+	ret = pm_runtime_get_sync(&priv->pdev->dev);
+	if (ret < 0) {
+		pm_runtime_put_noidle(&priv->pdev->dev);
+		return ret;
+	}
+
 	if (priv->data.dual_emac) {
 		/* In dual EMAC, reserved VLAN id should not be used for
 		 * creating VLAN interfaces as this can break the dual
@@ -1711,7 +1734,10 @@ static int cpsw_ndo_vlan_rx_add_vid(stru
 	}
 
 	dev_info(priv->dev, "Adding vlanid %d to vlan filter\n", vid);
-	return cpsw_add_vlan_ale_entry(priv, vid);
+	ret = cpsw_add_vlan_ale_entry(priv, vid);
+
+	pm_runtime_put(&priv->pdev->dev);
+	return ret;
 }
 
 static int cpsw_ndo_vlan_rx_kill_vid(struct net_device *ndev,
@@ -1723,6 +1749,12 @@ static int cpsw_ndo_vlan_rx_kill_vid(str
 	if (vid == priv->data.default_vlan)
 		return 0;
 
+	ret = pm_runtime_get_sync(&priv->pdev->dev);
+	if (ret < 0) {
+		pm_runtime_put_noidle(&priv->pdev->dev);
+		return ret;
+	}
+
 	if (priv->data.dual_emac) {
 		int i;
 
@@ -1742,8 +1774,10 @@ static int cpsw_ndo_vlan_rx_kill_vid(str
 	if (ret != 0)
 		return ret;
 
-	return cpsw_ale_del_mcast(priv->ale, priv->ndev->broadcast,
-				  0, ALE_VLAN, vid);
+	ret = cpsw_ale_del_mcast(priv->ale, priv->ndev->broadcast,
+				 0, ALE_VLAN, vid);
+	pm_runtime_put(&priv->pdev->dev);
+	return ret;
 }
 
 static const struct net_device_ops cpsw_netdev_ops = {
@@ -1902,10 +1936,33 @@ static int cpsw_set_pauseparam(struct ne
 	priv->tx_pause = pause->tx_pause ? true : false;
 
 	for_each_slave(priv, _cpsw_adjust_link, priv, &link);
-
 	return 0;
 }
 
+static int cpsw_ethtool_op_begin(struct net_device *ndev)
+{
+	struct cpsw_priv *priv = netdev_priv(ndev);
+	int ret;
+
+	ret = pm_runtime_get_sync(&priv->pdev->dev);
+	if (ret < 0) {
+		cpsw_err(priv, drv, "ethtool begin failed %d\n", ret);
+		pm_runtime_put_noidle(&priv->pdev->dev);
+	}
+
+	return ret;
+}
+
+static void cpsw_ethtool_op_complete(struct net_device *ndev)
+{
+	struct cpsw_priv *priv = netdev_priv(ndev);
+	int ret;
+
+	ret = pm_runtime_put(&priv->pdev->dev);
+	if (ret < 0)
+		cpsw_err(priv, drv, "ethtool complete failed %d\n", ret);
+}
+
 static const struct ethtool_ops cpsw_ethtool_ops = {
 	.get_drvinfo	= cpsw_get_drvinfo,
 	.get_msglevel	= cpsw_get_msglevel,
@@ -1925,6 +1982,8 @@ static const struct ethtool_ops cpsw_eth
 	.set_wol	= cpsw_set_wol,
 	.get_regs_len	= cpsw_get_regs_len,
 	.get_regs	= cpsw_get_regs,
+	.begin		= cpsw_ethtool_op_begin,
+	.complete	= cpsw_ethtool_op_complete,
 };
 
 static void cpsw_slave_init(struct cpsw_slave *slave, struct cpsw_priv *priv,
@@ -2325,7 +2384,11 @@ static int cpsw_probe(struct platform_de
 	/* Need to enable clocks with runtime PM api to access module
 	 * registers
 	 */
-	pm_runtime_get_sync(&pdev->dev);
+	ret = pm_runtime_get_sync(&pdev->dev);
+	if (ret < 0) {
+		pm_runtime_put_noidle(&pdev->dev);
+		goto clean_runtime_disable_ret;
+	}
 	priv->version = readl(&priv->regs->id_ver);
 	pm_runtime_put_sync(&pdev->dev);
 
@@ -2519,19 +2582,17 @@ clean_ndev_ret:
 	return ret;
 }
 
-static int cpsw_remove_child_device(struct device *dev, void *c)
-{
-	struct platform_device *pdev = to_platform_device(dev);
-
-	of_device_unregister(pdev);
-
-	return 0;
-}
-
 static int cpsw_remove(struct platform_device *pdev)
 {
 	struct net_device *ndev = platform_get_drvdata(pdev);
 	struct cpsw_priv *priv = netdev_priv(ndev);
+	int ret;
+
+	ret = pm_runtime_get_sync(&pdev->dev);
+	if (ret < 0) {
+		pm_runtime_put_noidle(&pdev->dev);
+		return ret;
+	}
 
 	if (priv->data.dual_emac)
 		unregister_netdev(cpsw_get_slave_ndev(priv, 1));
@@ -2541,8 +2602,9 @@ static int cpsw_remove(struct platform_d
 	cpdma_chan_destroy(priv->txch);
 	cpdma_chan_destroy(priv->rxch);
 	cpdma_ctlr_destroy(priv->dma);
+	of_platform_depopulate(&pdev->dev);
+	pm_runtime_put_sync(&pdev->dev);
 	pm_runtime_disable(&pdev->dev);
-	device_for_each_child(&pdev->dev, NULL, cpsw_remove_child_device);
 	if (priv->data.dual_emac)
 		free_netdev(cpsw_get_slave_ndev(priv, 1));
 	free_netdev(ndev);
@@ -2562,16 +2624,12 @@ static int cpsw_suspend(struct device *d
 		for (i = 0; i < priv->data.slaves; i++) {
 			if (netif_running(priv->slaves[i].ndev))
 				cpsw_ndo_stop(priv->slaves[i].ndev);
-			soft_reset_slave(priv->slaves + i);
 		}
 	} else {
 		if (netif_running(ndev))
 			cpsw_ndo_stop(ndev);
-		for_each_slave(priv, soft_reset_slave);
 	}
 
-	pm_runtime_put_sync(&pdev->dev);
-
 	/* Select sleep pin state */
 	pinctrl_pm_select_sleep_state(&pdev->dev);
 
@@ -2584,8 +2642,6 @@ static int cpsw_resume(struct device *de
 	struct net_device	*ndev = platform_get_drvdata(pdev);
 	struct cpsw_priv	*priv = netdev_priv(ndev);
 
-	pm_runtime_get_sync(&pdev->dev);
-
 	/* Select default pin state */
 	pinctrl_pm_select_default_state(&pdev->dev);
 
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/ti/davinci_cpdma.c
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/ti/davinci_cpdma.c
@@ -442,13 +442,11 @@ EXPORT_SYMBOL_GPL(cpdma_ctlr_dump);
 
 int cpdma_ctlr_destroy(struct cpdma_ctlr *ctlr)
 {
-	unsigned long flags;
 	int ret = 0, i;
 
 	if (!ctlr)
 		return -EINVAL;
 
-	spin_lock_irqsave(&ctlr->lock, flags);
 	if (ctlr->state != CPDMA_STATE_IDLE)
 		cpdma_ctlr_stop(ctlr);
 
@@ -456,7 +454,6 @@ int cpdma_ctlr_destroy(struct cpdma_ctlr
 		cpdma_chan_destroy(ctlr->channels[i]);
 
 	cpdma_desc_pool_destroy(ctlr->pool);
-	spin_unlock_irqrestore(&ctlr->lock, flags);
 	return ret;
 }
 EXPORT_SYMBOL_GPL(cpdma_ctlr_destroy);
--- zfcpdump-kernel-4.4.orig/drivers/net/ethernet/ti/netcp_core.c
+++ zfcpdump-kernel-4.4/drivers/net/ethernet/ti/netcp_core.c
@@ -1811,22 +1811,26 @@ static u16 netcp_select_queue(struct net
 	return 0;
 }
 
-static int netcp_setup_tc(struct net_device *dev, u8 num_tc)
+static int netcp_setup_tc(struct net_device *dev, u32 handle, __be16 proto,
+			  struct tc_to_netdev tc)
 {
 	int i;
 
 	/* setup tc must be called under rtnl lock */
 	ASSERT_RTNL();
 
+	if (handle != TC_H_ROOT || tc->type != TC_SETUP_MQPRIO)
+		return -EINVAL;
+
 	/* Sanity-check the number of traffic classes requested */
 	if ((dev->real_num_tx_queues <= 1) ||
-	    (dev->real_num_tx_queues < num_tc))
+	    (dev->real_num_tx_queues < tc->tc))
 		return -EINVAL;
 
 	/* Configure traffic class to queue mappings */
-	if (num_tc) {
-		netdev_set_num_tc(dev, num_tc);
-		for (i = 0; i < num_tc; i++)
+	if (tc->tc) {
+		netdev_set_num_tc(dev, tc->tc);
+		for (i = 0; i < tc->tc; i++)
 			netdev_set_tc_queue(dev, i, 1, i);
 	} else {
 		netdev_reset_tc(dev);
--- zfcpdump-kernel-4.4.orig/drivers/net/geneve.c
+++ zfcpdump-kernel-4.4/drivers/net/geneve.c
@@ -71,8 +71,14 @@ struct geneve_dev {
 	__be16		   dst_port;
 	bool		   collect_md;
 	struct gro_cells   gro_cells;
+	u32		   flags;
 };
 
+/* Geneve device flags */
+#define GENEVE_F_UDP_CSUM		BIT(0)
+#define GENEVE_F_UDP_ZERO_CSUM6_TX	BIT(1)
+#define GENEVE_F_UDP_ZERO_CSUM6_RX	BIT(2)
+
 struct geneve_sock {
 	bool			collect_md;
 	struct list_head	list;
@@ -81,6 +87,7 @@ struct geneve_sock {
 	int			refcnt;
 	struct udp_offload	udp_offloads;
 	struct hlist_head	vni_list[VNI_HASH_SIZE];
+	u32			flags;
 };
 
 static inline __u32 geneve_net_vni_hash(u8 vni[3])
@@ -310,15 +317,15 @@ static int geneve_udp_encap_recv(struct
 
 	/* Need Geneve and inner Ethernet header to be present */
 	if (unlikely(!pskb_may_pull(skb, GENEVE_BASE_HLEN)))
-		goto error;
+		goto drop;
 
 	/* Return packets with reserved bits set */
 	geneveh = geneve_hdr(skb);
 	if (unlikely(geneveh->ver != GENEVE_VER))
-		goto error;
+		goto drop;
 
 	if (unlikely(geneveh->proto_type != htons(ETH_P_TEB)))
-		goto error;
+		goto drop;
 
 	opts_len = geneveh->opt_len * 4;
 	if (iptunnel_pull_header(skb, GENEVE_BASE_HLEN + opts_len,
@@ -336,14 +343,10 @@ drop:
 	/* Consume bad packet */
 	kfree_skb(skb);
 	return 0;
-
-error:
-	/* Let the UDP layer deal with the skb */
-	return 1;
 }
 
 static struct socket *geneve_create_sock(struct net *net, bool ipv6,
-					 __be16 port)
+					 __be16 port, u32 flags)
 {
 	struct socket *sock;
 	struct udp_port_cfg udp_conf;
@@ -354,6 +357,8 @@ static struct socket *geneve_create_sock
 	if (ipv6) {
 		udp_conf.family = AF_INET6;
 		udp_conf.ipv6_v6only = 1;
+		udp_conf.use_udp6_rx_checksums =
+		    !(flags & GENEVE_F_UDP_ZERO_CSUM6_RX);
 	} else {
 		udp_conf.family = AF_INET;
 		udp_conf.local_ip.s_addr = htonl(INADDR_ANY);
@@ -371,8 +376,11 @@ static struct socket *geneve_create_sock
 
 static void geneve_notify_add_rx_port(struct geneve_sock *gs)
 {
+	struct net_device *dev;
 	struct sock *sk = gs->sock->sk;
+	struct net *net = sock_net(sk);
 	sa_family_t sa_family = sk->sk_family;
+	__be16 port = inet_sk(sk)->inet_sport;
 	int err;
 
 	if (sa_family == AF_INET) {
@@ -381,6 +389,14 @@ static void geneve_notify_add_rx_port(st
 			pr_warn("geneve: udp_add_offload failed with status %d\n",
 				err);
 	}
+
+	rcu_read_lock();
+	for_each_netdev_rcu(net, dev) {
+		if (dev->netdev_ops->ndo_add_geneve_port)
+			dev->netdev_ops->ndo_add_geneve_port(dev, sa_family,
+							     port);
+	}
+	rcu_read_unlock();
 }
 
 static int geneve_hlen(struct genevehdr *gh)
@@ -444,7 +460,7 @@ static struct sk_buff **geneve_gro_recei
 
 	skb_gro_pull(skb, gh_len);
 	skb_gro_postpull_rcsum(skb, gh, gh_len);
-	pp = ptype->callbacks.gro_receive(head, skb);
+	pp = call_gro_receive(ptype->callbacks.gro_receive, head, skb);
 
 out_unlock:
 	rcu_read_unlock();
@@ -480,7 +496,7 @@ static int geneve_gro_complete(struct sk
 
 /* Create new listen socket if needed */
 static struct geneve_sock *geneve_socket_create(struct net *net, __be16 port,
-						bool ipv6)
+						bool ipv6, u32 flags)
 {
 	struct geneve_net *gn = net_generic(net, geneve_net_id);
 	struct geneve_sock *gs;
@@ -492,7 +508,7 @@ static struct geneve_sock *geneve_socket
 	if (!gs)
 		return ERR_PTR(-ENOMEM);
 
-	sock = geneve_create_sock(net, ipv6, port);
+	sock = geneve_create_sock(net, ipv6, port, flags);
 	if (IS_ERR(sock)) {
 		kfree(gs);
 		return ERR_CAST(sock);
@@ -521,8 +537,20 @@ static struct geneve_sock *geneve_socket
 
 static void geneve_notify_del_rx_port(struct geneve_sock *gs)
 {
+	struct net_device *dev;
 	struct sock *sk = gs->sock->sk;
+	struct net *net = sock_net(sk);
 	sa_family_t sa_family = sk->sk_family;
+	__be16 port = inet_sk(sk)->inet_sport;
+
+	rcu_read_lock();
+	for_each_netdev_rcu(net, dev) {
+		if (dev->netdev_ops->ndo_del_geneve_port)
+			dev->netdev_ops->ndo_del_geneve_port(dev, sa_family,
+							     port);
+	}
+
+	rcu_read_unlock();
 
 	if (sa_family == AF_INET)
 		udp_del_offload(&gs->udp_offloads);
@@ -575,12 +603,13 @@ static int geneve_sock_add(struct geneve
 		goto out;
 	}
 
-	gs = geneve_socket_create(net, geneve->dst_port, ipv6);
+	gs = geneve_socket_create(net, geneve->dst_port, ipv6, geneve->flags);
 	if (IS_ERR(gs))
 		return PTR_ERR(gs);
 
 out:
 	gs->collect_md = geneve->collect_md;
+	gs->flags = geneve->flags;
 #if IS_ENABLED(CONFIG_IPV6)
 	if (ipv6)
 		geneve->sock6 = gs;
@@ -642,11 +671,12 @@ static void geneve_build_header(struct g
 
 static int geneve_build_skb(struct rtable *rt, struct sk_buff *skb,
 			    __be16 tun_flags, u8 vni[3], u8 opt_len, u8 *opt,
-			    bool csum, bool xnet)
+			    u32 flags, bool xnet)
 {
 	struct genevehdr *gnvh;
 	int min_headroom;
 	int err;
+	bool udp_sum = !!(flags & GENEVE_F_UDP_CSUM);
 
 	skb_scrub_packet(skb, xnet);
 
@@ -658,7 +688,7 @@ static int geneve_build_skb(struct rtabl
 		goto free_rt;
 	}
 
-	skb = udp_tunnel_handle_offloads(skb, csum);
+	skb = udp_tunnel_handle_offloads(skb, udp_sum);
 	if (IS_ERR(skb)) {
 		err = PTR_ERR(skb);
 		goto free_rt;
@@ -678,11 +708,12 @@ free_rt:
 #if IS_ENABLED(CONFIG_IPV6)
 static int geneve6_build_skb(struct dst_entry *dst, struct sk_buff *skb,
 			     __be16 tun_flags, u8 vni[3], u8 opt_len, u8 *opt,
-			     bool csum, bool xnet)
+			     u32 flags, bool xnet)
 {
 	struct genevehdr *gnvh;
 	int min_headroom;
 	int err;
+	bool udp_sum = !(flags & GENEVE_F_UDP_ZERO_CSUM6_TX);
 
 	skb_scrub_packet(skb, xnet);
 
@@ -694,7 +725,7 @@ static int geneve6_build_skb(struct dst_
 		goto free_dst;
 	}
 
-	skb = udp_tunnel_handle_offloads(skb, csum);
+	skb = udp_tunnel_handle_offloads(skb, udp_sum);
 	if (IS_ERR(skb)) {
 		err = PTR_ERR(skb);
 		goto free_dst;
@@ -824,9 +855,9 @@ static netdev_tx_t geneve_xmit_skb(struc
 	struct flowi4 fl4;
 	__u8 tos, ttl;
 	__be16 sport;
-	bool udp_csum;
 	__be16 df;
 	bool xnet = !net_eq(geneve->net, dev_net(geneve->dev));
+	u32 flags = geneve->flags;
 
 	if (geneve->collect_md) {
 		if (unlikely(!info || !(info->mode & IP_TUNNEL_INFO_TX))) {
@@ -857,9 +888,13 @@ static netdev_tx_t geneve_xmit_skb(struc
 		if (key->tun_flags & TUNNEL_GENEVE_OPT)
 			opts = ip_tunnel_info_opts(info);
 
-		udp_csum = !!(key->tun_flags & TUNNEL_CSUM);
+		if (key->tun_flags & TUNNEL_CSUM)
+			flags |= GENEVE_F_UDP_CSUM;
+		else
+			flags &= ~GENEVE_F_UDP_CSUM;
+
 		err = geneve_build_skb(rt, skb, key->tun_flags, vni,
-				       info->options_len, opts, udp_csum, xnet);
+				       info->options_len, opts, flags, xnet);
 		if (unlikely(err))
 			goto err;
 
@@ -867,9 +902,8 @@ static netdev_tx_t geneve_xmit_skb(struc
 		ttl = key->ttl;
 		df = key->tun_flags & TUNNEL_DONT_FRAGMENT ? htons(IP_DF) : 0;
 	} else {
-		udp_csum = false;
 		err = geneve_build_skb(rt, skb, 0, geneve->vni,
-				       0, NULL, udp_csum, xnet);
+				       0, NULL, flags, xnet);
 		if (unlikely(err))
 			goto err;
 
@@ -883,7 +917,7 @@ static netdev_tx_t geneve_xmit_skb(struc
 	err = udp_tunnel_xmit_skb(rt, gs4->sock->sk, skb, fl4.saddr, fl4.daddr,
 				  tos, ttl, df, sport, geneve->dst_port,
 				  !net_eq(geneve->net, dev_net(geneve->dev)),
-				  !udp_csum);
+				  !(flags & GENEVE_F_UDP_CSUM));
 
 	iptunnel_xmit_stats(err, &dev->stats, dev->tstats);
 	return NETDEV_TX_OK;
@@ -912,8 +946,8 @@ static netdev_tx_t geneve6_xmit_skb(stru
 	struct flowi6 fl6;
 	__u8 prio, ttl;
 	__be16 sport;
-	bool udp_csum;
 	bool xnet = !net_eq(geneve->net, dev_net(geneve->dev));
+	u32 flags = geneve->flags;
 
 	if (geneve->collect_md) {
 		if (unlikely(!info || !(info->mode & IP_TUNNEL_INFO_TX))) {
@@ -942,19 +976,22 @@ static netdev_tx_t geneve6_xmit_skb(stru
 		if (key->tun_flags & TUNNEL_GENEVE_OPT)
 			opts = ip_tunnel_info_opts(info);
 
-		udp_csum = !!(key->tun_flags & TUNNEL_CSUM);
+		if (key->tun_flags & TUNNEL_CSUM)
+			flags |= GENEVE_F_UDP_CSUM;
+		else
+			flags &= ~GENEVE_F_UDP_CSUM;
+
 		err = geneve6_build_skb(dst, skb, key->tun_flags, vni,
 					info->options_len, opts,
-					udp_csum, xnet);
+					flags, xnet);
 		if (unlikely(err))
 			goto err;
 
 		prio = ip_tunnel_ecn_encap(key->tos, iip, skb);
 		ttl = key->ttl;
 	} else {
-		udp_csum = false;
 		err = geneve6_build_skb(dst, skb, 0, geneve->vni,
-					0, NULL, udp_csum, xnet);
+					0, NULL, flags, xnet);
 		if (unlikely(err))
 			goto err;
 
@@ -966,7 +1003,10 @@ static netdev_tx_t geneve6_xmit_skb(stru
 	}
 	err = udp_tunnel6_xmit_skb(dst, gs6->sock->sk, skb, dev,
 				   &fl6.saddr, &fl6.daddr, prio, ttl,
-				   sport, geneve->dst_port, !udp_csum);
+				   sport, geneve->dst_port,
+				   !!(flags & GENEVE_F_UDP_ZERO_CSUM6_TX));
+
+	iptunnel_xmit_stats(err, &dev->stats, dev->tstats);
 	return NETDEV_TX_OK;
 
 tx_error:
@@ -998,6 +1038,17 @@ static netdev_tx_t geneve_xmit(struct sk
 	return geneve_xmit_skb(skb, dev, info);
 }
 
+static int geneve_change_mtu(struct net_device *dev, int new_mtu)
+{
+	/* GENEVE overhead is not fixed, so we can't enforce a more
+	 * precise max MTU.
+	 */
+	if (new_mtu < 68 || new_mtu > IP_MAX_MTU)
+		return -EINVAL;
+	dev->mtu = new_mtu;
+	return 0;
+}
+
 static int geneve_fill_metadata_dst(struct net_device *dev, struct sk_buff *skb)
 {
 	struct ip_tunnel_info *info = skb_tunnel_info(skb);
@@ -1042,7 +1093,7 @@ static const struct net_device_ops genev
 	.ndo_stop		= geneve_stop,
 	.ndo_start_xmit		= geneve_xmit,
 	.ndo_get_stats64	= ip_tunnel_get_stats64,
-	.ndo_change_mtu		= eth_change_mtu,
+	.ndo_change_mtu		= geneve_change_mtu,
 	.ndo_validate_addr	= eth_validate_addr,
 	.ndo_set_mac_address	= eth_mac_addr,
 	.ndo_fill_metadata_dst	= geneve_fill_metadata_dst,
@@ -1065,6 +1116,30 @@ static struct device_type geneve_type =
 	.name = "geneve",
 };
 
+/* Calls the ndo_add_geneve_port of the caller in order to
+ * supply the listening GENEVE udp ports. Callers are expected
+ * to implement the ndo_add_geneve_port.
+ */
+void geneve_get_rx_port(struct net_device *dev)
+{
+	struct net *net = dev_net(dev);
+	struct geneve_net *gn = net_generic(net, geneve_net_id);
+	struct geneve_sock *gs;
+	sa_family_t sa_family;
+	struct sock *sk;
+	__be16 port;
+
+	rcu_read_lock();
+	list_for_each_entry_rcu(gs, &gn->sock_list, list) {
+		sk = gs->sock->sk;
+		sa_family = sk->sk_family;
+		port = inet_sk(sk)->inet_sport;
+		dev->netdev_ops->ndo_add_geneve_port(dev, sa_family, port);
+	}
+	rcu_read_unlock();
+}
+EXPORT_SYMBOL_GPL(geneve_get_rx_port);
+
 /* Initialize the device structure. */
 static void geneve_setup(struct net_device *dev)
 {
@@ -1097,6 +1172,9 @@ static const struct nla_policy geneve_po
 	[IFLA_GENEVE_TOS]		= { .type = NLA_U8 },
 	[IFLA_GENEVE_PORT]		= { .type = NLA_U16 },
 	[IFLA_GENEVE_COLLECT_METADATA]	= { .type = NLA_FLAG },
+	[IFLA_GENEVE_UDP_CSUM]		= { .type = NLA_U8 },
+	[IFLA_GENEVE_UDP_ZERO_CSUM6_TX]	= { .type = NLA_U8 },
+	[IFLA_GENEVE_UDP_ZERO_CSUM6_RX]	= { .type = NLA_U8 },
 };
 
 static int geneve_validate(struct nlattr *tb[], struct nlattr *data[])
@@ -1150,7 +1228,7 @@ static struct geneve_dev *geneve_find_de
 static int geneve_configure(struct net *net, struct net_device *dev,
 			    union geneve_addr *remote,
 			    __u32 vni, __u8 ttl, __u8 tos, __be16 dst_port,
-			    bool metadata)
+			    bool metadata, u32 flags)
 {
 	struct geneve_net *gn = net_generic(net, geneve_net_id);
 	struct geneve_dev *t, *geneve = netdev_priv(dev);
@@ -1181,6 +1259,7 @@ static int geneve_configure(struct net *
 	geneve->tos = tos;
 	geneve->dst_port = dst_port;
 	geneve->collect_md = metadata;
+	geneve->flags = flags;
 
 	t = geneve_find_dev(gn, dst_port, remote, geneve->vni,
 			    &tun_on_same_port, &tun_collect_md);
@@ -1219,6 +1298,7 @@ static int geneve_newlink(struct net *ne
 	bool metadata = false;
 	union geneve_addr remote = geneve_remote_unspec;
 	__u32 vni = 0;
+	u32 flags = 0;
 
 	if (data[IFLA_GENEVE_REMOTE] && data[IFLA_GENEVE_REMOTE6])
 		return -EINVAL;
@@ -1259,8 +1339,20 @@ static int geneve_newlink(struct net *ne
 	if (data[IFLA_GENEVE_COLLECT_METADATA])
 		metadata = true;
 
+	if (data[IFLA_GENEVE_UDP_CSUM] &&
+	    nla_get_u8(data[IFLA_GENEVE_UDP_CSUM]))
+		flags |= GENEVE_F_UDP_CSUM;
+
+	if (data[IFLA_GENEVE_UDP_ZERO_CSUM6_TX] &&
+	    nla_get_u8(data[IFLA_GENEVE_UDP_ZERO_CSUM6_TX]))
+		flags |= GENEVE_F_UDP_ZERO_CSUM6_TX;
+
+	if (data[IFLA_GENEVE_UDP_ZERO_CSUM6_RX] &&
+	    nla_get_u8(data[IFLA_GENEVE_UDP_ZERO_CSUM6_RX]))
+		flags |= GENEVE_F_UDP_ZERO_CSUM6_RX;
+
 	return geneve_configure(net, dev, &remote, vni, ttl, tos, dst_port,
-				metadata);
+				metadata, flags);
 }
 
 static void geneve_dellink(struct net_device *dev, struct list_head *head)
@@ -1279,6 +1371,9 @@ static size_t geneve_get_size(const stru
 		nla_total_size(sizeof(__u8)) +  /* IFLA_GENEVE_TOS */
 		nla_total_size(sizeof(__be16)) +  /* IFLA_GENEVE_PORT */
 		nla_total_size(0) +	 /* IFLA_GENEVE_COLLECT_METADATA */
+		nla_total_size(sizeof(__u8)) + /* IFLA_GENEVE_UDP_CSUM */
+		nla_total_size(sizeof(__u8)) + /* IFLA_GENEVE_UDP_ZERO_CSUM6_TX */
+		nla_total_size(sizeof(__u8)) + /* IFLA_GENEVE_UDP_ZERO_CSUM6_RX */
 		0;
 }
 
@@ -1315,6 +1410,14 @@ static int geneve_fill_info(struct sk_bu
 			goto nla_put_failure;
 	}
 
+	if (nla_put_u8(skb, IFLA_GENEVE_UDP_CSUM,
+		       !!(geneve->flags & GENEVE_F_UDP_CSUM)) ||
+	    nla_put_u8(skb, IFLA_GENEVE_UDP_ZERO_CSUM6_TX,
+		       !!(geneve->flags & GENEVE_F_UDP_ZERO_CSUM6_TX)) ||
+	    nla_put_u8(skb, IFLA_GENEVE_UDP_ZERO_CSUM6_RX,
+		       !!(geneve->flags & GENEVE_F_UDP_ZERO_CSUM6_RX)))
+		goto nla_put_failure;
+
 	return 0;
 
 nla_put_failure:
@@ -1348,12 +1451,22 @@ struct net_device *geneve_dev_create_fb(
 		return dev;
 
 	err = geneve_configure(net, dev, &geneve_remote_unspec,
-			       0, 0, 0, htons(dst_port), true);
-	if (err) {
-		free_netdev(dev);
-		return ERR_PTR(err);
-	}
+			       0, 0, 0, htons(dst_port), true, 0);
+	if (err)
+		goto err;
+
+	/* openvswitch users expect packet sizes to be unrestricted,
+	 * so set the largest MTU we can.
+	 */
+	err = geneve_change_mtu(dev, IP_MAX_MTU);
+	if (err)
+		goto err;
+
 	return dev;
+
+ err:
+	free_netdev(dev);
+	return ERR_PTR(err);
 }
 EXPORT_SYMBOL_GPL(geneve_dev_create_fb);
 
--- zfcpdump-kernel-4.4.orig/drivers/net/hyperv/hyperv_net.h
+++ zfcpdump-kernel-4.4/drivers/net/hyperv/hyperv_net.h
@@ -124,37 +124,22 @@ struct ndis_tcp_ip_checksum_info;
 /*
  * Represent netvsc packet which contains 1 RNDIS and 1 ethernet frame
  * within the RNDIS
+ *
+ * The size of this structure is less than 48 bytes and we can now
+ * place this structure in the skb->cb field.
  */
 struct hv_netvsc_packet {
 	/* Bookkeeping stuff */
-	u32 status;
-
-	bool is_data_pkt;
-	bool xmit_more; /* from skb */
-	bool cp_partial; /* partial copy into send buffer */
+	u8 cp_partial; /* partial copy into send buffer */
 
-	u16 vlan_tci;
+	u8 rmsg_size; /* RNDIS header and PPI size */
+	u8 rmsg_pgcnt; /* page count of RNDIS header and PPI */
+	u8 page_buf_cnt;
 
 	u16 q_idx;
-	struct vmbus_channel *channel;
-
-	u64 send_completion_tid;
-	void *send_completion_ctx;
-	void (*send_completion)(void *context);
-
 	u32 send_buf_index;
 
-	/* This points to the memory after page_buf */
-	struct rndis_message *rndis_msg;
-
-	u32 rmsg_size; /* RNDIS header and PPI size */
-	u32 rmsg_pgcnt; /* page count of RNDIS header and PPI */
-
 	u32 total_data_buflen;
-	/* Points to the send/receive buffer where the ethernet frame is */
-	void *data;
-	u32 page_buf_cnt;
-	struct hv_page_buffer *page_buf;
 };
 
 struct netvsc_device_info {
@@ -173,11 +158,10 @@ enum rndis_device_state {
 };
 
 struct rndis_device {
-	struct netvsc_device *net_dev;
+	struct net_device *ndev;
 
 	enum rndis_device_state state;
 	bool link_state;
-	bool link_change;
 	atomic_t new_req_id;
 
 	spinlock_t request_lock;
@@ -188,28 +172,38 @@ struct rndis_device {
 
 
 /* Interface */
+struct rndis_message;
+struct netvsc_device;
 int netvsc_device_add(struct hv_device *device, void *additional_info);
 int netvsc_device_remove(struct hv_device *device);
 int netvsc_send(struct hv_device *device,
-		struct hv_netvsc_packet *packet);
+		struct hv_netvsc_packet *packet,
+		struct rndis_message *rndis_msg,
+		struct hv_page_buffer **page_buffer,
+		struct sk_buff *skb);
 void netvsc_linkstatus_callback(struct hv_device *device_obj,
 				struct rndis_message *resp);
-void netvsc_xmit_completion(void *context);
 int netvsc_recv_callback(struct hv_device *device_obj,
 			struct hv_netvsc_packet *packet,
-			struct ndis_tcp_ip_checksum_info *csum_info);
+			void **data,
+			struct ndis_tcp_ip_checksum_info *csum_info,
+			struct vmbus_channel *channel,
+			u16 vlan_tci);
 void netvsc_channel_cb(void *context);
-int rndis_filter_open(struct hv_device *dev);
-int rndis_filter_close(struct hv_device *dev);
+int rndis_filter_open(struct netvsc_device *nvdev);
+int rndis_filter_close(struct netvsc_device *nvdev);
 int rndis_filter_device_add(struct hv_device *dev,
 			void *additional_info);
 void rndis_filter_device_remove(struct hv_device *dev);
 int rndis_filter_receive(struct hv_device *dev,
-			struct hv_netvsc_packet *pkt);
+			struct hv_netvsc_packet *pkt,
+			void **data,
+			struct vmbus_channel *channel);
 
 int rndis_filter_set_packet_filter(struct rndis_device *dev, u32 new_filter);
-int rndis_filter_set_device_mac(struct hv_device *hdev, char *mac);
+int rndis_filter_set_device_mac(struct net_device *ndev, char *mac);
 
+void netvsc_switch_datapath(struct net_device *nv_dev, bool vf);
 
 #define NVSP_INVALID_PROTOCOL_VERSION	((u32)0xFFFFFFFF)
 
@@ -628,12 +622,13 @@ struct nvsp_message {
 #define NETVSC_PACKET_SIZE                      4096
 
 #define VRSS_SEND_TAB_SIZE 16
+#define VRSS_CHANNEL_MAX 64
 
 #define RNDIS_MAX_PKT_DEFAULT 8
 #define RNDIS_PKT_ALIGN_DEFAULT 8
 
 struct multi_send_data {
-	spinlock_t lock; /* protect struct multi_send_data */
+	struct sk_buff *skb; /* skb containing the pkt */
 	struct hv_netvsc_packet *pkt; /* netvsc pkt pending */
 	u32 count; /* counter of batched packets */
 };
@@ -644,27 +639,55 @@ struct netvsc_stats {
 	struct u64_stats_sync syncp;
 };
 
+struct netvsc_reconfig {
+	struct list_head list;
+	u32 event;
+};
+
 /* The context of the netvsc device  */
 struct net_device_context {
 	/* point back to our device context */
 	struct hv_device *device_ctx;
+	/* netvsc_device */
+	struct netvsc_device *nvdev;
+	/* reconfigure work */
 	struct delayed_work dwork;
+	/* last reconfig time */
+	unsigned long last_reconfig;
+	/* reconfig events */
+	struct list_head reconfig_events;
+	/* list protection */
+	spinlock_t lock;
+
 	struct work_struct work;
 	u32 msg_enable; /* debug level */
 
 	struct netvsc_stats __percpu *tx_stats;
 	struct netvsc_stats __percpu *rx_stats;
+
+	/* Ethtool settings */
+	u8 duplex;
+	u32 speed;
+
+	/* the device is going away */
+	bool start_remove;
+
+	/* State to manage the associated VF interface. */
+	struct net_device *vf_netdev;
+	bool vf_inject;
+	atomic_t vf_use_cnt;
+	/* 1: allocated, serial number is valid. 0: not allocated */
+	u32 vf_alloc;
+	/* Serial number of the VF to team with */
+	u32 vf_serial;
 };
 
 /* Per netvsc device */
 struct netvsc_device {
-	struct hv_device *dev;
-
 	u32 nvsp_version;
 
 	atomic_t num_outstanding_sends;
 	wait_queue_head_t wait_drain;
-	bool start_remove;
 	bool destroy;
 
 	/* Receive buffer allocated by us but manages by NetVSP */
@@ -690,15 +713,13 @@ struct netvsc_device {
 	struct nvsp_message revoke_packet;
 	/* unsigned char HwMacAddr[HW_MACADDR_LEN]; */
 
-	struct net_device *ndev;
-
-	struct vmbus_channel *chn_table[NR_CPUS];
+	struct vmbus_channel *chn_table[VRSS_CHANNEL_MAX];
 	u32 send_table[VRSS_SEND_TAB_SIZE];
 	u32 max_chn;
 	u32 num_chn;
 	spinlock_t sc_lock; /* Protects num_sc_offered variable */
 	u32 num_sc_offered;
-	atomic_t queue_sends[NR_CPUS];
+	atomic_t queue_sends[VRSS_CHANNEL_MAX];
 
 	/* Holds rndis device info */
 	void *extension;
@@ -710,19 +731,25 @@ struct netvsc_device {
 	/* The sub channel callback buffer */
 	unsigned char *sub_cb_buf;
 
-	struct multi_send_data msd[NR_CPUS];
+	struct multi_send_data msd[VRSS_CHANNEL_MAX];
 	u32 max_pkt; /* max number of pkt in one send, e.g. 8 */
 	u32 pkt_align; /* alignment bytes, e.g. 8 */
 
-	/* The net device context */
-	struct net_device_context *nd_ctx;
-
-	/* 1: allocated, serial number is valid. 0: not allocated */
-	u32 vf_alloc;
-	/* Serial number of the VF to team with */
-	u32 vf_serial;
+	atomic_t open_cnt;
 };
 
+static inline struct netvsc_device *
+net_device_to_netvsc_device(struct net_device *ndev)
+{
+	return ((struct net_device_context *)netdev_priv(ndev))->nvdev;
+}
+
+static inline struct netvsc_device *
+hv_device_to_netvsc_device(struct hv_device *device)
+{
+	return net_device_to_netvsc_device(hv_get_drvdata(device));
+}
+
 /* NdisInitialize message */
 struct rndis_initialize_request {
 	u32 req_id;
@@ -1260,5 +1287,4 @@ struct rndis_message {
 #define TRANSPORT_INFO_IPV6_TCP ((INFO_IPV6 << 16) | INFO_TCP)
 #define TRANSPORT_INFO_IPV6_UDP ((INFO_IPV6 << 16) | INFO_UDP)
 
-
 #endif /* _HYPERV_NET_H */
--- zfcpdump-kernel-4.4.orig/drivers/net/hyperv/netvsc.c
+++ zfcpdump-kernel-4.4/drivers/net/hyperv/netvsc.c
@@ -33,12 +33,36 @@
 
 #include "hyperv_net.h"
 
+/*
+ * Switch the data path from the synthetic interface to the VF
+ * interface.
+ */
+void netvsc_switch_datapath(struct net_device *ndev, bool vf)
+{
+	struct net_device_context *net_device_ctx = netdev_priv(ndev);
+	struct hv_device *dev = net_device_ctx->device_ctx;
+	struct netvsc_device *nv_dev = net_device_ctx->nvdev;
+	struct nvsp_message *init_pkt = &nv_dev->channel_init_pkt;
+
+	memset(init_pkt, 0, sizeof(struct nvsp_message));
+	init_pkt->hdr.msg_type = NVSP_MSG4_TYPE_SWITCH_DATA_PATH;
+	if (vf)
+		init_pkt->msg.v4_msg.active_dp.active_datapath =
+			NVSP_DATAPATH_VF;
+	else
+		init_pkt->msg.v4_msg.active_dp.active_datapath =
+			NVSP_DATAPATH_SYNTHETIC;
+
+	vmbus_sendpacket(dev->channel, init_pkt,
+			       sizeof(struct nvsp_message),
+			       (unsigned long)init_pkt,
+			       VM_PKT_DATA_INBAND, 0);
+}
+
 
-static struct netvsc_device *alloc_net_device(struct hv_device *device)
+static struct netvsc_device *alloc_net_device(void)
 {
 	struct netvsc_device *net_device;
-	struct net_device *ndev = hv_get_drvdata(device);
-	int i;
 
 	net_device = kzalloc(sizeof(struct netvsc_device), GFP_KERNEL);
 	if (!net_device)
@@ -51,17 +75,11 @@ static struct netvsc_device *alloc_net_d
 	}
 
 	init_waitqueue_head(&net_device->wait_drain);
-	net_device->start_remove = false;
 	net_device->destroy = false;
-	net_device->dev = device;
-	net_device->ndev = ndev;
+	atomic_set(&net_device->open_cnt, 0);
 	net_device->max_pkt = RNDIS_MAX_PKT_DEFAULT;
 	net_device->pkt_align = RNDIS_PKT_ALIGN_DEFAULT;
 
-	for (i = 0; i < num_online_cpus(); i++)
-		spin_lock_init(&net_device->msd[i].lock);
-
-	hv_set_drvdata(device, net_device);
 	return net_device;
 }
 
@@ -73,9 +91,8 @@ static void free_netvsc_device(struct ne
 
 static struct netvsc_device *get_outbound_net_device(struct hv_device *device)
 {
-	struct netvsc_device *net_device;
+	struct netvsc_device *net_device = hv_device_to_netvsc_device(device);
 
-	net_device = hv_get_drvdata(device);
 	if (net_device && net_device->destroy)
 		net_device = NULL;
 
@@ -84,9 +101,7 @@ static struct netvsc_device *get_outboun
 
 static struct netvsc_device *get_inbound_net_device(struct hv_device *device)
 {
-	struct netvsc_device *net_device;
-
-	net_device = hv_get_drvdata(device);
+	struct netvsc_device *net_device = hv_device_to_netvsc_device(device);
 
 	if (!net_device)
 		goto get_in_err;
@@ -100,11 +115,12 @@ get_in_err:
 }
 
 
-static int netvsc_destroy_buf(struct netvsc_device *net_device)
+static int netvsc_destroy_buf(struct hv_device *device)
 {
 	struct nvsp_message *revoke_packet;
 	int ret = 0;
-	struct net_device *ndev = net_device->ndev;
+	struct net_device *ndev = hv_get_drvdata(device);
+	struct netvsc_device *net_device = net_device_to_netvsc_device(ndev);
 
 	/*
 	 * If we got a section count, it means we received a
@@ -122,7 +138,7 @@ static int netvsc_destroy_buf(struct net
 		revoke_packet->msg.v1_msg.
 		revoke_recv_buf.id = NETVSC_RECEIVE_BUFFER_ID;
 
-		ret = vmbus_sendpacket(net_device->dev->channel,
+		ret = vmbus_sendpacket(device->channel,
 				       revoke_packet,
 				       sizeof(struct nvsp_message),
 				       (unsigned long)revoke_packet,
@@ -140,8 +156,8 @@ static int netvsc_destroy_buf(struct net
 
 	/* Teardown the gpadl on the vsp end */
 	if (net_device->recv_buf_gpadl_handle) {
-		ret = vmbus_teardown_gpadl(net_device->dev->channel,
-			   net_device->recv_buf_gpadl_handle);
+		ret = vmbus_teardown_gpadl(device->channel,
+					   net_device->recv_buf_gpadl_handle);
 
 		/* If we failed here, we might as well return and have a leak
 		 * rather than continue and a bugchk
@@ -182,7 +198,7 @@ static int netvsc_destroy_buf(struct net
 		revoke_packet->msg.v1_msg.revoke_send_buf.id =
 			NETVSC_SEND_BUFFER_ID;
 
-		ret = vmbus_sendpacket(net_device->dev->channel,
+		ret = vmbus_sendpacket(device->channel,
 				       revoke_packet,
 				       sizeof(struct nvsp_message),
 				       (unsigned long)revoke_packet,
@@ -198,7 +214,7 @@ static int netvsc_destroy_buf(struct net
 	}
 	/* Teardown the gpadl on the vsp end */
 	if (net_device->send_buf_gpadl_handle) {
-		ret = vmbus_teardown_gpadl(net_device->dev->channel,
+		ret = vmbus_teardown_gpadl(device->channel,
 					   net_device->send_buf_gpadl_handle);
 
 		/* If we failed here, we might as well return and have a leak
@@ -224,7 +240,6 @@ static int netvsc_destroy_buf(struct net
 static int netvsc_init_buf(struct hv_device *device)
 {
 	int ret = 0;
-	unsigned long t;
 	struct netvsc_device *net_device;
 	struct nvsp_message *init_packet;
 	struct net_device *ndev;
@@ -233,7 +248,7 @@ static int netvsc_init_buf(struct hv_dev
 	net_device = get_outbound_net_device(device);
 	if (!net_device)
 		return -ENODEV;
-	ndev = net_device->ndev;
+	ndev = hv_get_drvdata(device);
 
 	node = cpu_to_node(device->channel->target_cpu);
 	net_device->recv_buf = vzalloc_node(net_device->recv_buf_size, node);
@@ -285,9 +300,7 @@ static int netvsc_init_buf(struct hv_dev
 		goto cleanup;
 	}
 
-	t = wait_for_completion_timeout(&net_device->channel_init_wait, 5*HZ);
-	BUG_ON(t == 0);
-
+	wait_for_completion(&net_device->channel_init_wait);
 
 	/* Check the response */
 	if (init_packet->msg.v1_msg.
@@ -370,8 +383,7 @@ static int netvsc_init_buf(struct hv_dev
 		goto cleanup;
 	}
 
-	t = wait_for_completion_timeout(&net_device->channel_init_wait, 5*HZ);
-	BUG_ON(t == 0);
+	wait_for_completion(&net_device->channel_init_wait);
 
 	/* Check the response */
 	if (init_packet->msg.v1_msg.
@@ -410,7 +422,7 @@ static int netvsc_init_buf(struct hv_dev
 	goto exit;
 
 cleanup:
-	netvsc_destroy_buf(net_device);
+	netvsc_destroy_buf(device);
 
 exit:
 	return ret;
@@ -423,8 +435,8 @@ static int negotiate_nvsp_ver(struct hv_
 			      struct nvsp_message *init_packet,
 			      u32 nvsp_ver)
 {
+	struct net_device *ndev = hv_get_drvdata(device);
 	int ret;
-	unsigned long t;
 
 	memset(init_packet, 0, sizeof(struct nvsp_message));
 	init_packet->hdr.msg_type = NVSP_MSG_TYPE_INIT;
@@ -441,10 +453,7 @@ static int negotiate_nvsp_ver(struct hv_
 	if (ret != 0)
 		return ret;
 
-	t = wait_for_completion_timeout(&net_device->channel_init_wait, 5*HZ);
-
-	if (t == 0)
-		return -ETIMEDOUT;
+	wait_for_completion(&net_device->channel_init_wait);
 
 	if (init_packet->msg.init_msg.init_complete.status !=
 	    NVSP_STAT_SUCCESS)
@@ -456,8 +465,7 @@ static int negotiate_nvsp_ver(struct hv_
 	/* NVSPv2 or later: Send NDIS config */
 	memset(init_packet, 0, sizeof(struct nvsp_message));
 	init_packet->hdr.msg_type = NVSP_MSG2_TYPE_SEND_NDIS_CONFIG;
-	init_packet->msg.v2_msg.send_ndis_config.mtu = net_device->ndev->mtu +
-						       ETH_HLEN;
+	init_packet->msg.v2_msg.send_ndis_config.mtu = ndev->mtu + ETH_HLEN;
 	init_packet->msg.v2_msg.send_ndis_config.capability.ieee8021q = 1;
 
 	if (nvsp_ver >= NVSP_PROTOCOL_VERSION_5)
@@ -477,7 +485,6 @@ static int netvsc_connect_vsp(struct hv_
 	struct netvsc_device *net_device;
 	struct nvsp_message *init_packet;
 	int ndis_version;
-	struct net_device *ndev;
 	u32 ver_list[] = { NVSP_PROTOCOL_VERSION_1, NVSP_PROTOCOL_VERSION_2,
 		NVSP_PROTOCOL_VERSION_4, NVSP_PROTOCOL_VERSION_5 };
 	int i, num_ver = 4; /* number of different NVSP versions */
@@ -485,7 +492,6 @@ static int netvsc_connect_vsp(struct hv_
 	net_device = get_outbound_net_device(device);
 	if (!net_device)
 		return -ENODEV;
-	ndev = net_device->ndev;
 
 	init_packet = &net_device->channel_init_pkt;
 
@@ -541,9 +547,9 @@ cleanup:
 	return ret;
 }
 
-static void netvsc_disconnect_vsp(struct netvsc_device *net_device)
+static void netvsc_disconnect_vsp(struct hv_device *device)
 {
-	netvsc_destroy_buf(net_device);
+	netvsc_destroy_buf(device);
 }
 
 /*
@@ -551,24 +557,13 @@ static void netvsc_disconnect_vsp(struct
  */
 int netvsc_device_remove(struct hv_device *device)
 {
-	struct netvsc_device *net_device;
-	unsigned long flags;
-
-	net_device = hv_get_drvdata(device);
-
-	netvsc_disconnect_vsp(net_device);
+	struct net_device *ndev = hv_get_drvdata(device);
+	struct net_device_context *net_device_ctx = netdev_priv(ndev);
+	struct netvsc_device *net_device = net_device_ctx->nvdev;
 
-	/*
-	 * Since we have already drained, we don't need to busy wait
-	 * as was done in final_release_stor_device()
-	 * Note that we cannot set the ext pointer to NULL until
-	 * we have drained - to drain the outgoing packets, we need to
-	 * allow incoming packets.
-	 */
+	netvsc_disconnect_vsp(device);
 
-	spin_lock_irqsave(&device->channel->inbound_lock, flags);
-	hv_set_drvdata(device, NULL);
-	spin_unlock_irqrestore(&device->channel->inbound_lock, flags);
+	net_device_ctx->nvdev = NULL;
 
 	/*
 	 * At this point, no one should be accessing net_device
@@ -610,15 +605,16 @@ static inline void netvsc_free_send_slot
 }
 
 static void netvsc_send_completion(struct netvsc_device *net_device,
+				   struct vmbus_channel *incoming_channel,
 				   struct hv_device *device,
 				   struct vmpacket_descriptor *packet)
 {
 	struct nvsp_message *nvsp_packet;
 	struct hv_netvsc_packet *nvsc_packet;
-	struct net_device *ndev;
+	struct net_device *ndev = hv_get_drvdata(device);
+	struct net_device_context *net_device_ctx = netdev_priv(ndev);
 	u32 send_index;
-
-	ndev = net_device->ndev;
+	struct sk_buff *skb;
 
 	nvsp_packet = (struct nvsp_message *)((unsigned long)packet +
 			(packet->offset8 << 3));
@@ -642,18 +638,17 @@ static void netvsc_send_completion(struc
 		int queue_sends;
 
 		/* Get the send context */
-		nvsc_packet = (struct hv_netvsc_packet *)(unsigned long)
-			packet->trans_id;
+		skb = (struct sk_buff *)(unsigned long)packet->trans_id;
 
 		/* Notify the layer above us */
-		if (nvsc_packet) {
+		if (skb) {
+			nvsc_packet = (struct hv_netvsc_packet *) skb->cb;
 			send_index = nvsc_packet->send_buf_index;
 			if (send_index != NETVSC_INVALID_INDEX)
 				netvsc_free_send_slot(net_device, send_index);
 			q_idx = nvsc_packet->q_idx;
-			channel = nvsc_packet->channel;
-			nvsc_packet->send_completion(nvsc_packet->
-						     send_completion_ctx);
+			channel = incoming_channel;
+			dev_kfree_skb_any(skb);
 		}
 
 		num_outstanding_sends =
@@ -665,7 +660,7 @@ static void netvsc_send_completion(struc
 			wake_up(&net_device->wait_drain);
 
 		if (netif_tx_queue_stopped(netdev_get_tx_queue(ndev, q_idx)) &&
-		    !net_device->start_remove &&
+		    !net_device_ctx->start_remove &&
 		    (hv_ringbuf_avail_percent(&channel->outbound) >
 		     RING_AVAIL_PERCENT_HIWATER || queue_sends < 1))
 				netif_tx_wake_queue(netdev_get_tx_queue(
@@ -705,12 +700,17 @@ static u32 netvsc_get_next_send_section(
 static u32 netvsc_copy_to_send_buf(struct netvsc_device *net_device,
 				   unsigned int section_index,
 				   u32 pend_size,
-				   struct hv_netvsc_packet *packet)
+				   struct hv_netvsc_packet *packet,
+				   struct rndis_message *rndis_msg,
+				   struct hv_page_buffer **pb,
+				   struct sk_buff *skb)
 {
 	char *start = net_device->send_buf;
 	char *dest = start + (section_index * net_device->send_section_size)
 		     + pend_size;
 	int i;
+	bool is_data_pkt = (skb != NULL) ? true : false;
+	bool xmit_more = (skb != NULL) ? skb->xmit_more : false;
 	u32 msg_size = 0;
 	u32 padding = 0;
 	u32 remain = packet->total_data_buflen % net_device->pkt_align;
@@ -718,17 +718,17 @@ static u32 netvsc_copy_to_send_buf(struc
 		packet->page_buf_cnt;
 
 	/* Add padding */
-	if (packet->is_data_pkt && packet->xmit_more && remain &&
+	if (is_data_pkt && xmit_more && remain &&
 	    !packet->cp_partial) {
 		padding = net_device->pkt_align - remain;
-		packet->rndis_msg->msg_len += padding;
+		rndis_msg->msg_len += padding;
 		packet->total_data_buflen += padding;
 	}
 
 	for (i = 0; i < page_count; i++) {
-		char *src = phys_to_virt(packet->page_buf[i].pfn << PAGE_SHIFT);
-		u32 offset = packet->page_buf[i].offset;
-		u32 len = packet->page_buf[i].len;
+		char *src = phys_to_virt((*pb)[i].pfn << PAGE_SHIFT);
+		u32 offset = (*pb)[i].offset;
+		u32 len = (*pb)[i].len;
 
 		memcpy(dest, (src + offset), len);
 		msg_size += len;
@@ -744,20 +744,24 @@ static u32 netvsc_copy_to_send_buf(struc
 }
 
 static inline int netvsc_send_pkt(
+	struct hv_device *device,
 	struct hv_netvsc_packet *packet,
-	struct netvsc_device *net_device)
+	struct netvsc_device *net_device,
+	struct hv_page_buffer **pb,
+	struct sk_buff *skb)
 {
 	struct nvsp_message nvmsg;
-	struct vmbus_channel *out_channel = packet->channel;
 	u16 q_idx = packet->q_idx;
-	struct net_device *ndev = net_device->ndev;
+	struct vmbus_channel *out_channel = net_device->chn_table[q_idx];
+	struct net_device *ndev = hv_get_drvdata(device);
 	u64 req_id;
 	int ret;
 	struct hv_page_buffer *pgbuf;
 	u32 ring_avail = hv_ringbuf_avail_percent(&out_channel->outbound);
+	bool xmit_more = (skb != NULL) ? skb->xmit_more : false;
 
 	nvmsg.hdr.msg_type = NVSP_MSG1_TYPE_SEND_RNDIS_PKT;
-	if (packet->is_data_pkt) {
+	if (skb != NULL) {
 		/* 0 is RMC_DATA; */
 		nvmsg.msg.v1_msg.send_rndis_pkt.channel_type = 0;
 	} else {
@@ -773,10 +777,7 @@ static inline int netvsc_send_pkt(
 		nvmsg.msg.v1_msg.send_rndis_pkt.send_buf_section_size =
 			packet->total_data_buflen;
 
-	if (packet->send_completion)
-		req_id = (ulong)packet;
-	else
-		req_id = 0;
+	req_id = (ulong)skb;
 
 	if (out_channel->rescind)
 		return -ENODEV;
@@ -789,11 +790,11 @@ static inline int netvsc_send_pkt(
 	 * unnecessarily.
 	 */
 	if (ring_avail < (RING_AVAIL_PERCENT_LOWATER + 1))
-		packet->xmit_more = false;
+		xmit_more = false;
 
 	if (packet->page_buf_cnt) {
-		pgbuf = packet->cp_partial ? packet->page_buf +
-			packet->rmsg_pgcnt : packet->page_buf;
+		pgbuf = packet->cp_partial ? (*pb) +
+			packet->rmsg_pgcnt : (*pb);
 		ret = vmbus_sendpacket_pagebuffer_ctl(out_channel,
 						      pgbuf,
 						      packet->page_buf_cnt,
@@ -801,14 +802,14 @@ static inline int netvsc_send_pkt(
 						      sizeof(struct nvsp_message),
 						      req_id,
 						      VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED,
-						      !packet->xmit_more);
+						      !xmit_more);
 	} else {
 		ret = vmbus_sendpacket_ctl(out_channel, &nvmsg,
 					   sizeof(struct nvsp_message),
 					   req_id,
 					   VM_PKT_DATA_INBAND,
 					   VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED,
-					   !packet->xmit_more);
+					   !xmit_more);
 	}
 
 	if (ret == 0) {
@@ -839,8 +840,23 @@ static inline int netvsc_send_pkt(
 	return ret;
 }
 
+/* Move packet out of multi send data (msd), and clear msd */
+static inline void move_pkt_msd(struct hv_netvsc_packet **msd_send,
+				struct sk_buff **msd_skb,
+				struct multi_send_data *msdp)
+{
+	*msd_skb = msdp->skb;
+	*msd_send = msdp->pkt;
+	msdp->skb = NULL;
+	msdp->pkt = NULL;
+	msdp->count = 0;
+}
+
 int netvsc_send(struct hv_device *device,
-		struct hv_netvsc_packet *packet)
+		struct hv_netvsc_packet *packet,
+		struct rndis_message *rndis_msg,
+		struct hv_page_buffer **pb,
+		struct sk_buff *skb)
 {
 	struct netvsc_device *net_device;
 	int ret = 0, m_ret = 0;
@@ -848,33 +864,36 @@ int netvsc_send(struct hv_device *device
 	u16 q_idx = packet->q_idx;
 	u32 pktlen = packet->total_data_buflen, msd_len = 0;
 	unsigned int section_index = NETVSC_INVALID_INDEX;
-	unsigned long flag;
 	struct multi_send_data *msdp;
 	struct hv_netvsc_packet *msd_send = NULL, *cur_send = NULL;
+	struct sk_buff *msd_skb = NULL;
 	bool try_batch;
+	bool xmit_more = (skb != NULL) ? skb->xmit_more : false;
 
 	net_device = get_outbound_net_device(device);
 	if (!net_device)
 		return -ENODEV;
 
 	out_channel = net_device->chn_table[q_idx];
-	if (!out_channel) {
-		out_channel = device->channel;
-		q_idx = 0;
-		packet->q_idx = 0;
-	}
-	packet->channel = out_channel;
+
 	packet->send_buf_index = NETVSC_INVALID_INDEX;
 	packet->cp_partial = false;
 
+	/* Send control message directly without accessing msd (Multi-Send
+	 * Data) field which may be changed during data packet processing.
+	 */
+	if (!skb) {
+		cur_send = packet;
+		goto send_now;
+	}
+
 	msdp = &net_device->msd[q_idx];
 
 	/* batch packets in send buffer if possible */
-	spin_lock_irqsave(&msdp->lock, flag);
 	if (msdp->pkt)
 		msd_len = msdp->pkt->total_data_buflen;
 
-	try_batch = packet->is_data_pkt && msd_len > 0 && msdp->count <
+	try_batch = (skb != NULL) && msd_len > 0 && msdp->count <
 		    net_device->max_pkt;
 
 	if (try_batch && msd_len + pktlen + net_device->pkt_align <
@@ -886,21 +905,19 @@ int netvsc_send(struct hv_device *device
 		section_index = msdp->pkt->send_buf_index;
 		packet->cp_partial = true;
 
-	} else if (packet->is_data_pkt && pktlen + net_device->pkt_align <
+	} else if ((skb != NULL) && pktlen + net_device->pkt_align <
 		   net_device->send_section_size) {
 		section_index = netvsc_get_next_send_section(net_device);
 		if (section_index != NETVSC_INVALID_INDEX) {
-				msd_send = msdp->pkt;
-				msdp->pkt = NULL;
-				msdp->count = 0;
-				msd_len = 0;
+			move_pkt_msd(&msd_send, &msd_skb, msdp);
+			msd_len = 0;
 		}
 	}
 
 	if (section_index != NETVSC_INVALID_INDEX) {
 		netvsc_copy_to_send_buf(net_device,
 					section_index, msd_len,
-					packet);
+					packet, rndis_msg, pb, skb);
 
 		packet->send_buf_index = section_index;
 
@@ -912,38 +929,38 @@ int netvsc_send(struct hv_device *device
 			packet->total_data_buflen += msd_len;
 		}
 
-		if (msdp->pkt)
-			netvsc_xmit_completion(msdp->pkt);
+		if (msdp->skb)
+			dev_kfree_skb_any(msdp->skb);
 
-		if (packet->xmit_more && !packet->cp_partial) {
+		if (xmit_more && !packet->cp_partial) {
+			msdp->skb = skb;
 			msdp->pkt = packet;
 			msdp->count++;
 		} else {
 			cur_send = packet;
+			msdp->skb = NULL;
 			msdp->pkt = NULL;
 			msdp->count = 0;
 		}
 	} else {
-		msd_send = msdp->pkt;
-		msdp->pkt = NULL;
-		msdp->count = 0;
+		move_pkt_msd(&msd_send, &msd_skb, msdp);
 		cur_send = packet;
 	}
 
-	spin_unlock_irqrestore(&msdp->lock, flag);
-
 	if (msd_send) {
-		m_ret = netvsc_send_pkt(msd_send, net_device);
+		m_ret = netvsc_send_pkt(device, msd_send, net_device,
+					NULL, msd_skb);
 
 		if (m_ret != 0) {
 			netvsc_free_send_slot(net_device,
 					      msd_send->send_buf_index);
-			netvsc_xmit_completion(msd_send);
+			dev_kfree_skb_any(msd_skb);
 		}
 	}
 
+send_now:
 	if (cur_send)
-		ret = netvsc_send_pkt(cur_send, net_device);
+		ret = netvsc_send_pkt(device, cur_send, net_device, pb, skb);
 
 	if (ret != 0 && section_index != NETVSC_INVALID_INDEX)
 		netvsc_free_send_slot(net_device, section_index);
@@ -959,9 +976,7 @@ static void netvsc_send_recv_completion(
 	struct nvsp_message recvcompMessage;
 	int retries = 0;
 	int ret;
-	struct net_device *ndev;
-
-	ndev = net_device->ndev;
+	struct net_device *ndev = hv_get_drvdata(device);
 
 	recvcompMessage.hdr.msg_type =
 				NVSP_MSG1_TYPE_SEND_RNDIS_PKT_COMPLETE;
@@ -1008,9 +1023,8 @@ static void netvsc_receive(struct netvsc
 	u32 status = NVSP_STAT_SUCCESS;
 	int i;
 	int count = 0;
-	struct net_device *ndev;
-
-	ndev = net_device->ndev;
+	struct net_device *ndev = hv_get_drvdata(device);
+	void *data;
 
 	/*
 	 * All inbound packets other than send completion should be xfer page
@@ -1043,22 +1057,19 @@ static void netvsc_receive(struct netvsc
 	}
 
 	count = vmxferpage_packet->range_cnt;
-	netvsc_packet->channel = channel;
 
 	/* Each range represents 1 RNDIS pkt that contains 1 ethernet frame */
 	for (i = 0; i < count; i++) {
 		/* Initialize the netvsc packet */
-		netvsc_packet->status = NVSP_STAT_SUCCESS;
-		netvsc_packet->data = (void *)((unsigned long)net_device->
+		data = (void *)((unsigned long)net_device->
 			recv_buf + vmxferpage_packet->ranges[i].byte_offset);
 		netvsc_packet->total_data_buflen =
 					vmxferpage_packet->ranges[i].byte_count;
 
 		/* Pass it to the upper layer */
-		rndis_filter_receive(device, netvsc_packet);
+		status = rndis_filter_receive(device, netvsc_packet, &data,
+					      channel);
 
-		if (netvsc_packet->status != NVSP_STAT_SUCCESS)
-			status = NVSP_STAT_FAIL;
 	}
 
 	netvsc_send_recv_completion(device, channel, net_device,
@@ -1070,14 +1081,13 @@ static void netvsc_send_table(struct hv_
 			      struct nvsp_message *nvmsg)
 {
 	struct netvsc_device *nvscdev;
-	struct net_device *ndev;
+	struct net_device *ndev = hv_get_drvdata(hdev);
 	int i;
 	u32 count, *tab;
 
 	nvscdev = get_outbound_net_device(hdev);
 	if (!nvscdev)
 		return;
-	ndev = nvscdev->ndev;
 
 	count = nvmsg->msg.v5_msg.send_table.count;
 	if (count != VRSS_SEND_TAB_SIZE) {
@@ -1092,16 +1102,16 @@ static void netvsc_send_table(struct hv_
 		nvscdev->send_table[i] = tab[i];
 }
 
-static void netvsc_send_vf(struct netvsc_device *nvdev,
+static void netvsc_send_vf(struct net_device_context *net_device_ctx,
 			   struct nvsp_message *nvmsg)
 {
-	nvdev->vf_alloc = nvmsg->msg.v4_msg.vf_assoc.allocated;
-	nvdev->vf_serial = nvmsg->msg.v4_msg.vf_assoc.serial;
+	net_device_ctx->vf_alloc = nvmsg->msg.v4_msg.vf_assoc.allocated;
+	net_device_ctx->vf_serial = nvmsg->msg.v4_msg.vf_assoc.serial;
 }
 
 static inline void netvsc_receive_inband(struct hv_device *hdev,
-					 struct netvsc_device *nvdev,
-					 struct nvsp_message *nvmsg)
+				 struct net_device_context *net_device_ctx,
+				 struct nvsp_message *nvmsg)
 {
 	switch (nvmsg->hdr.msg_type) {
 	case NVSP_MSG5_TYPE_SEND_INDIRECTION_TABLE:
@@ -1109,11 +1119,45 @@ static inline void netvsc_receive_inband
 		break;
 
 	case NVSP_MSG4_TYPE_SEND_VF_ASSOCIATION:
-		netvsc_send_vf(nvdev, nvmsg);
+		netvsc_send_vf(net_device_ctx, nvmsg);
+		break;
+	}
+}
+
+static void netvsc_process_raw_pkt(struct hv_device *device,
+				   struct vmbus_channel *channel,
+				   struct netvsc_device *net_device,
+				   struct net_device *ndev,
+				   u64 request_id,
+				   struct vmpacket_descriptor *desc)
+{
+	struct nvsp_message *nvmsg;
+	struct net_device_context *net_device_ctx = netdev_priv(ndev);
+
+	nvmsg = (struct nvsp_message *)((unsigned long)
+		desc + (desc->offset8 << 3));
+
+	switch (desc->type) {
+	case VM_PKT_COMP:
+		netvsc_send_completion(net_device, channel, device, desc);
+		break;
+
+	case VM_PKT_DATA_USING_XFER_PAGES:
+		netvsc_receive(net_device, channel, device, desc);
+		break;
+
+	case VM_PKT_DATA_INBAND:
+		netvsc_receive_inband(device, net_device_ctx, nvmsg);
+		break;
+
+	default:
+		netdev_err(ndev, "unhandled packet type %d, tid %llx\n",
+			   desc->type, request_id);
 		break;
 	}
 }
 
+
 void netvsc_channel_cb(void *context)
 {
 	int ret;
@@ -1126,7 +1170,7 @@ void netvsc_channel_cb(void *context)
 	unsigned char *buffer;
 	int bufferlen = NETVSC_PACKET_SIZE;
 	struct net_device *ndev;
-	struct nvsp_message *nvmsg;
+	bool need_to_commit = false;
 
 	if (channel->primary_channel != NULL)
 		device = channel->primary_channel->device_obj;
@@ -1136,42 +1180,40 @@ void netvsc_channel_cb(void *context)
 	net_device = get_inbound_net_device(device);
 	if (!net_device)
 		return;
-	ndev = net_device->ndev;
+	ndev = hv_get_drvdata(device);
 	buffer = get_per_channel_state(channel);
 
 	do {
+		desc = get_next_pkt_raw(channel);
+		if (desc != NULL) {
+			netvsc_process_raw_pkt(device,
+					       channel,
+					       net_device,
+					       ndev,
+					       desc->trans_id,
+					       desc);
+
+			put_pkt_raw(channel, desc);
+			need_to_commit = true;
+			continue;
+		}
+		if (need_to_commit) {
+			need_to_commit = false;
+			commit_rd_index(channel);
+		}
+
 		ret = vmbus_recvpacket_raw(channel, buffer, bufferlen,
 					   &bytes_recvd, &request_id);
 		if (ret == 0) {
 			if (bytes_recvd > 0) {
 				desc = (struct vmpacket_descriptor *)buffer;
-				nvmsg = (struct nvsp_message *)((unsigned long)
-					 desc + (desc->offset8 << 3));
-				switch (desc->type) {
-				case VM_PKT_COMP:
-					netvsc_send_completion(net_device,
-								device, desc);
-					break;
-
-				case VM_PKT_DATA_USING_XFER_PAGES:
-					netvsc_receive(net_device, channel,
-						       device, desc);
-					break;
-
-				case VM_PKT_DATA_INBAND:
-					netvsc_receive_inband(device,
-							      net_device,
-							      nvmsg);
-					break;
-
-				default:
-					netdev_err(ndev,
-						   "unhandled packet type %d, "
-						   "tid %llx len %d\n",
-						   desc->type, request_id,
-						   bytes_recvd);
-					break;
-				}
+				netvsc_process_raw_pkt(device,
+						       channel,
+						       net_device,
+						       ndev,
+						       request_id,
+						       desc);
+
 
 			} else {
 				/*
@@ -1208,30 +1250,19 @@ void netvsc_channel_cb(void *context)
  */
 int netvsc_device_add(struct hv_device *device, void *additional_info)
 {
-	int ret = 0;
+	int i, ret = 0;
 	int ring_size =
 	((struct netvsc_device_info *)additional_info)->ring_size;
 	struct netvsc_device *net_device;
-	struct net_device *ndev;
+	struct net_device *ndev = hv_get_drvdata(device);
+	struct net_device_context *net_device_ctx = netdev_priv(ndev);
 
-	net_device = alloc_net_device(device);
+	net_device = alloc_net_device();
 	if (!net_device)
 		return -ENOMEM;
 
 	net_device->ring_size = ring_size;
 
-	/*
-	 * Coming into this function, struct net_device * is
-	 * registered as the driver private data.
-	 * In alloc_net_device(), we register struct netvsc_device *
-	 * as the driver private data and stash away struct net_device *
-	 * in struct netvsc_device *.
-	 */
-	ndev = net_device->ndev;
-
-	/* Add netvsc_device context to netvsc_device */
-	net_device->nd_ctx = netdev_priv(ndev);
-
 	/* Initialize the NetVSC channel extension */
 	init_completion(&net_device->channel_init_wait);
 
@@ -1250,7 +1281,19 @@ int netvsc_device_add(struct hv_device *
 	/* Channel is opened */
 	pr_info("hv_netvsc channel opened successfully\n");
 
-	net_device->chn_table[0] = device->channel;
+	/* If we're reopening the device we may have multiple queues, fill the
+	 * chn_table with the default channel to use it before subchannels are
+	 * opened.
+	 */
+	for (i = 0; i < VRSS_CHANNEL_MAX; i++)
+		net_device->chn_table[i] = device->channel;
+
+	/* Writing nvdev pointer unlocks netvsc_send(), make sure chn_table is
+	 * populated.
+	 */
+	wmb();
+
+	net_device_ctx->nvdev = net_device;
 
 	/* Connect with the NetVsp */
 	ret = netvsc_connect_vsp(device);
--- zfcpdump-kernel-4.4.orig/drivers/net/hyperv/netvsc_drv.c
+++ zfcpdump-kernel-4.4/drivers/net/hyperv/netvsc_drv.c
@@ -42,6 +42,12 @@
 
 
 #define RING_SIZE_MIN 64
+#define LINKCHANGE_INT (2 * HZ)
+#define NETVSC_HW_FEATURES	(NETIF_F_RXCSUM | \
+				 NETIF_F_SG | \
+				 NETIF_F_TSO | \
+				 NETIF_F_TSO6 | \
+				 NETIF_F_HW_CSUM)
 static int ring_size = 128;
 module_param(ring_size, int, S_IRUGO);
 MODULE_PARM_DESC(ring_size, "Ring buffer size (# of pages)");
@@ -61,18 +67,19 @@ static void do_set_multicast(struct work
 {
 	struct net_device_context *ndevctx =
 		container_of(w, struct net_device_context, work);
-	struct netvsc_device *nvdev;
+	struct hv_device *device_obj = ndevctx->device_ctx;
+	struct net_device *ndev = hv_get_drvdata(device_obj);
+	struct netvsc_device *nvdev = ndevctx->nvdev;
 	struct rndis_device *rdev;
 
-	nvdev = hv_get_drvdata(ndevctx->device_ctx);
-	if (nvdev == NULL || nvdev->ndev == NULL)
+	if (!nvdev)
 		return;
 
 	rdev = nvdev->extension;
 	if (rdev == NULL)
 		return;
 
-	if (nvdev->ndev->flags & IFF_PROMISC)
+	if (ndev->flags & IFF_PROMISC)
 		rndis_filter_set_packet_filter(rdev,
 			NDIS_PACKET_TYPE_PROMISCUOUS);
 	else
@@ -91,16 +98,14 @@ static void netvsc_set_multicast_list(st
 
 static int netvsc_open(struct net_device *net)
 {
-	struct net_device_context *net_device_ctx = netdev_priv(net);
-	struct hv_device *device_obj = net_device_ctx->device_ctx;
-	struct netvsc_device *nvdev;
+	struct netvsc_device *nvdev = net_device_to_netvsc_device(net);
 	struct rndis_device *rdev;
 	int ret = 0;
 
 	netif_carrier_off(net);
 
 	/* Open up the device */
-	ret = rndis_filter_open(device_obj);
+	ret = rndis_filter_open(nvdev);
 	if (ret != 0) {
 		netdev_err(net, "unable to open device (ret %d).\n", ret);
 		return ret;
@@ -108,7 +113,6 @@ static int netvsc_open(struct net_device
 
 	netif_tx_wake_all_queues(net);
 
-	nvdev = hv_get_drvdata(device_obj);
 	rdev = nvdev->extension;
 	if (!rdev->link_state)
 		netif_carrier_on(net);
@@ -119,8 +123,7 @@ static int netvsc_open(struct net_device
 static int netvsc_close(struct net_device *net)
 {
 	struct net_device_context *net_device_ctx = netdev_priv(net);
-	struct hv_device *device_obj = net_device_ctx->device_ctx;
-	struct netvsc_device *nvdev = hv_get_drvdata(device_obj);
+	struct netvsc_device *nvdev = net_device_ctx->nvdev;
 	int ret;
 	u32 aread, awrite, i, msec = 10, retry = 0, retry_max = 20;
 	struct vmbus_channel *chn;
@@ -129,7 +132,7 @@ static int netvsc_close(struct net_devic
 
 	/* Make sure netvsc_set_multicast_list doesn't re-enable filter! */
 	cancel_work_sync(&net_device_ctx->work);
-	ret = rndis_filter_close(device_obj);
+	ret = rndis_filter_close(nvdev);
 	if (ret != 0) {
 		netdev_err(net, "unable to close device (ret %d).\n", ret);
 		return ret;
@@ -195,94 +198,25 @@ static void *init_ppi_data(struct rndis_
 	return ppi;
 }
 
-union sub_key {
-	u64 k;
-	struct {
-		u8 pad[3];
-		u8 kb;
-		u32 ka;
-	};
-};
-
-/* Toeplitz hash function
- * data: network byte order
- * return: host byte order
- */
-static u32 comp_hash(u8 *key, int klen, void *data, int dlen)
-{
-	union sub_key subk;
-	int k_next = 4;
-	u8 dt;
-	int i, j;
-	u32 ret = 0;
-
-	subk.k = 0;
-	subk.ka = ntohl(*(u32 *)key);
-
-	for (i = 0; i < dlen; i++) {
-		subk.kb = key[k_next];
-		k_next = (k_next + 1) % klen;
-		dt = ((u8 *)data)[i];
-		for (j = 0; j < 8; j++) {
-			if (dt & 0x80)
-				ret ^= subk.ka;
-			dt <<= 1;
-			subk.k <<= 1;
-		}
-	}
-
-	return ret;
-}
-
-static bool netvsc_set_hash(u32 *hash, struct sk_buff *skb)
-{
-	struct flow_keys flow;
-	int data_len;
-
-	if (!skb_flow_dissect_flow_keys(skb, &flow, 0) ||
-	    !(flow.basic.n_proto == htons(ETH_P_IP) ||
-	      flow.basic.n_proto == htons(ETH_P_IPV6)))
-		return false;
-
-	if (flow.basic.ip_proto == IPPROTO_TCP)
-		data_len = 12;
-	else
-		data_len = 8;
-
-	*hash = comp_hash(netvsc_hash_key, HASH_KEYLEN, &flow, data_len);
-
-	return true;
-}
-
 static u16 netvsc_select_queue(struct net_device *ndev, struct sk_buff *skb,
 			void *accel_priv, select_queue_fallback_t fallback)
 {
 	struct net_device_context *net_device_ctx = netdev_priv(ndev);
-	struct hv_device *hdev =  net_device_ctx->device_ctx;
-	struct netvsc_device *nvsc_dev = hv_get_drvdata(hdev);
+	struct netvsc_device *nvsc_dev = net_device_ctx->nvdev;
 	u32 hash;
 	u16 q_idx = 0;
 
 	if (nvsc_dev == NULL || ndev->real_num_tx_queues <= 1)
 		return 0;
 
-	if (netvsc_set_hash(&hash, skb)) {
-		q_idx = nvsc_dev->send_table[hash % VRSS_SEND_TAB_SIZE] %
-			ndev->real_num_tx_queues;
-		skb_set_hash(skb, hash, PKT_HASH_TYPE_L3);
-	}
-
-	return q_idx;
-}
+	hash = skb_get_hash(skb);
+	q_idx = nvsc_dev->send_table[hash % VRSS_SEND_TAB_SIZE] %
+		ndev->real_num_tx_queues;
 
-void netvsc_xmit_completion(void *context)
-{
-	struct hv_netvsc_packet *packet = (struct hv_netvsc_packet *)context;
-	struct sk_buff *skb = (struct sk_buff *)
-		(unsigned long)packet->send_completion_tid;
+	if (!nvsc_dev->chn_table[q_idx])
+		q_idx = 0;
 
-	if (skb)
-		dev_kfree_skb_any(skb);
+	return q_idx;
 }
 
 static u32 fill_pg_buf(struct page *page, u32 offset, u32 len,
@@ -320,9 +254,10 @@ static u32 fill_pg_buf(struct page *page
 }
 
 static u32 init_page_array(void *hdr, u32 len, struct sk_buff *skb,
-			   struct hv_netvsc_packet *packet)
+			   struct hv_netvsc_packet *packet,
+			   struct hv_page_buffer **page_buf)
 {
-	struct hv_page_buffer *pb = packet->page_buf;
+	struct hv_page_buffer *pb = *page_buf;
 	u32 slots_used = 0;
 	char *data = skb->data;
 	int frags = skb_shinfo(skb)->nr_frags;
@@ -432,8 +367,8 @@ static int netvsc_start_xmit(struct sk_b
 	u32 net_trans_info;
 	u32 hash;
 	u32 skb_length;
-	u32 pkt_sz;
 	struct hv_page_buffer page_buf[MAX_PAGE_BUFFER_COUNT];
+	struct hv_page_buffer *pb = page_buf;
 	struct netvsc_stats *tx_stats = this_cpu_ptr(net_device_ctx->tx_stats);
 
 	/* We will atmost need two pages to describe the rndis
@@ -460,42 +395,34 @@ check_size:
 		goto check_size;
 	}
 
-	pkt_sz = sizeof(struct hv_netvsc_packet) + RNDIS_AND_PPI_SIZE;
-
-	ret = skb_cow_head(skb, pkt_sz);
+	/*
+	 * Place the rndis header in the skb head room and
+	 * the skb->cb will be used for hv_netvsc_packet
+	 * structure.
+	 */
+	ret = skb_cow_head(skb, RNDIS_AND_PPI_SIZE);
 	if (ret) {
 		netdev_err(net, "unable to alloc hv_netvsc_packet\n");
 		ret = -ENOMEM;
 		goto drop;
 	}
-	/* Use the headroom for building up the packet */
-	packet = (struct hv_netvsc_packet *)skb->head;
+	/* Use the skb control buffer for building up the packet */
+	BUILD_BUG_ON(sizeof(struct hv_netvsc_packet) >
+			FIELD_SIZEOF(struct sk_buff, cb));
+	packet = (struct hv_netvsc_packet *)skb->cb;
 
-	packet->status = 0;
-	packet->xmit_more = skb->xmit_more;
-
-	packet->vlan_tci = skb->vlan_tci;
-	packet->page_buf = page_buf;
 
 	packet->q_idx = skb_get_queue_mapping(skb);
 
-	packet->is_data_pkt = true;
 	packet->total_data_buflen = skb->len;
 
-	packet->rndis_msg = (struct rndis_message *)((unsigned long)packet +
-				sizeof(struct hv_netvsc_packet));
-
-	memset(packet->rndis_msg, 0, RNDIS_AND_PPI_SIZE);
+	rndis_msg = (struct rndis_message *)skb->head;
 
-	/* Set the completion routine */
-	packet->send_completion = netvsc_xmit_completion;
-	packet->send_completion_ctx = packet;
-	packet->send_completion_tid = (unsigned long)skb;
+	memset(rndis_msg, 0, RNDIS_AND_PPI_SIZE);
 
-	isvlan = packet->vlan_tci & VLAN_TAG_PRESENT;
+	isvlan = skb->vlan_tci & VLAN_TAG_PRESENT;
 
 	/* Add the rndis header */
-	rndis_msg = packet->rndis_msg;
 	rndis_msg->ndis_msg_type = RNDIS_MSG_PACKET;
 	rndis_msg->msg_len = packet->total_data_buflen;
 	rndis_pkt = &rndis_msg->msg.pkt;
@@ -521,8 +448,8 @@ check_size:
 					IEEE_8021Q_INFO);
 		vlan = (struct ndis_pkt_8021q_info *)((void *)ppi +
 						ppi->ppi_offset);
-		vlan->vlanid = packet->vlan_tci & VLAN_VID_MASK;
-		vlan->pri = (packet->vlan_tci & VLAN_PRIO_MASK) >>
+		vlan->vlanid = skb->vlan_tci & VLAN_VID_MASK;
+		vlan->pri = (skb->vlan_tci & VLAN_PRIO_MASK) >>
 				VLAN_PRIO_SHIFT;
 	}
 
@@ -617,9 +544,12 @@ do_send:
 	rndis_msg->msg_len += rndis_msg_size;
 	packet->total_data_buflen = rndis_msg->msg_len;
 	packet->page_buf_cnt = init_page_array(rndis_msg, rndis_msg_size,
-					       skb, packet);
+					       skb, packet, &pb);
 
-	ret = netvsc_send(net_device_ctx->device_ctx, packet);
+	/* timestamp packet in software */
+	skb_tx_timestamp(skb);
+	ret = netvsc_send(net_device_ctx->device_ctx, packet,
+			  rndis_msg, &pb, skb);
 
 drop:
 	if (ret == 0) {
@@ -646,75 +576,52 @@ void netvsc_linkstatus_callback(struct h
 	struct rndis_indicate_status *indicate = &resp->msg.indicate_status;
 	struct net_device *net;
 	struct net_device_context *ndev_ctx;
-	struct netvsc_device *net_device;
-	struct rndis_device *rdev;
-
-	net_device = hv_get_drvdata(device_obj);
-	rdev = net_device->extension;
+	struct netvsc_reconfig *event;
+	unsigned long flags;
 
-	switch (indicate->status) {
-	case RNDIS_STATUS_MEDIA_CONNECT:
-		rdev->link_state = false;
-		break;
-	case RNDIS_STATUS_MEDIA_DISCONNECT:
-		rdev->link_state = true;
-		break;
-	case RNDIS_STATUS_NETWORK_CHANGE:
-		rdev->link_change = true;
-		break;
-	default:
+	/* Handle link change statuses only */
+	if (indicate->status != RNDIS_STATUS_NETWORK_CHANGE &&
+	    indicate->status != RNDIS_STATUS_MEDIA_CONNECT &&
+	    indicate->status != RNDIS_STATUS_MEDIA_DISCONNECT)
 		return;
-	}
 
-	net = net_device->ndev;
+	net = hv_get_drvdata(device_obj);
 
 	if (!net || net->reg_state != NETREG_REGISTERED)
 		return;
 
 	ndev_ctx = netdev_priv(net);
-	if (!rdev->link_state) {
-		schedule_delayed_work(&ndev_ctx->dwork, 0);
-		schedule_delayed_work(&ndev_ctx->dwork, msecs_to_jiffies(20));
-	} else {
-		schedule_delayed_work(&ndev_ctx->dwork, 0);
-	}
+
+	event = kzalloc(sizeof(*event), GFP_ATOMIC);
+	if (!event)
+		return;
+	event->event = indicate->status;
+
+	spin_lock_irqsave(&ndev_ctx->lock, flags);
+	list_add_tail(&event->list, &ndev_ctx->reconfig_events);
+	spin_unlock_irqrestore(&ndev_ctx->lock, flags);
+
+	schedule_delayed_work(&ndev_ctx->dwork, 0);
 }
 
-/*
- * netvsc_recv_callback -  Callback when we receive a packet from the
- * "wire" on the specified device.
- */
-int netvsc_recv_callback(struct hv_device *device_obj,
+
+static struct sk_buff *netvsc_alloc_recv_skb(struct net_device *net,
 				struct hv_netvsc_packet *packet,
-				struct ndis_tcp_ip_checksum_info *csum_info)
+				struct ndis_tcp_ip_checksum_info *csum_info,
+				void *data, u16 vlan_tci)
 {
-	struct net_device *net;
-	struct net_device_context *net_device_ctx;
 	struct sk_buff *skb;
-	struct netvsc_stats *rx_stats;
 
-	net = ((struct netvsc_device *)hv_get_drvdata(device_obj))->ndev;
-	if (!net || net->reg_state != NETREG_REGISTERED) {
-		packet->status = NVSP_STAT_FAIL;
-		return 0;
-	}
-	net_device_ctx = netdev_priv(net);
-	rx_stats = this_cpu_ptr(net_device_ctx->rx_stats);
-
-	/* Allocate a skb - TODO direct I/O to pages? */
 	skb = netdev_alloc_skb_ip_align(net, packet->total_data_buflen);
-	if (unlikely(!skb)) {
-		++net->stats.rx_dropped;
-		packet->status = NVSP_STAT_FAIL;
-		return 0;
-	}
+	if (!skb)
+		return skb;
 
 	/*
 	 * Copy to skb. This copy is needed here since the memory pointed by
 	 * hv_netvsc_packet cannot be deallocated
 	 */
-	memcpy(skb_put(skb, packet->total_data_buflen), packet->data,
-		packet->total_data_buflen);
+	memcpy(skb_put(skb, packet->total_data_buflen), data,
+	       packet->total_data_buflen);
 
 	skb->protocol = eth_type_trans(skb, net);
 	if (csum_info) {
@@ -728,11 +635,79 @@ int netvsc_recv_callback(struct hv_devic
 			skb->ip_summed = CHECKSUM_NONE;
 	}
 
-	if (packet->vlan_tci & VLAN_TAG_PRESENT)
+	if (vlan_tci & VLAN_TAG_PRESENT)
 		__vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q),
-				       packet->vlan_tci);
+				       vlan_tci);
+
+	return skb;
+}
+
+/*
+ * netvsc_recv_callback -  Callback when we receive a packet from the
+ * "wire" on the specified device.
+ */
+int netvsc_recv_callback(struct hv_device *device_obj,
+				struct hv_netvsc_packet *packet,
+				void **data,
+				struct ndis_tcp_ip_checksum_info *csum_info,
+				struct vmbus_channel *channel,
+				u16 vlan_tci)
+{
+	struct net_device *net = hv_get_drvdata(device_obj);
+	struct net_device_context *net_device_ctx = netdev_priv(net);
+	struct sk_buff *skb;
+	struct sk_buff *vf_skb;
+	struct netvsc_stats *rx_stats;
+	u32 bytes_recvd = packet->total_data_buflen;
+	int ret = 0;
+
+	if (!net || net->reg_state != NETREG_REGISTERED)
+		return NVSP_STAT_FAIL;
+
+	if (READ_ONCE(net_device_ctx->vf_inject)) {
+		atomic_inc(&net_device_ctx->vf_use_cnt);
+		if (!READ_ONCE(net_device_ctx->vf_inject)) {
+			/*
+			 * We raced; just move on.
+			 */
+			atomic_dec(&net_device_ctx->vf_use_cnt);
+			goto vf_injection_done;
+		}
+
+		/*
+		 * Inject this packet into the VF inerface.
+		 * On Hyper-V, multicast and brodcast packets
+		 * are only delivered on the synthetic interface
+		 * (after subjecting these to policy filters on
+		 * the host). Deliver these via the VF interface
+		 * in the guest.
+		 */
+		vf_skb = netvsc_alloc_recv_skb(net_device_ctx->vf_netdev,
+					       packet, csum_info, *data,
+					       vlan_tci);
+		if (vf_skb != NULL) {
+			++net_device_ctx->vf_netdev->stats.rx_packets;
+			net_device_ctx->vf_netdev->stats.rx_bytes +=
+				bytes_recvd;
+			netif_receive_skb(vf_skb);
+		} else {
+			++net->stats.rx_dropped;
+			ret = NVSP_STAT_FAIL;
+		}
+		atomic_dec(&net_device_ctx->vf_use_cnt);
+		return ret;
+	}
+
+vf_injection_done:
+	rx_stats = this_cpu_ptr(net_device_ctx->rx_stats);
 
-	skb_record_rx_queue(skb, packet->channel->
+	/* Allocate a skb - TODO direct I/O to pages? */
+	skb = netvsc_alloc_recv_skb(net, packet, csum_info, *data, vlan_tci);
+	if (unlikely(!skb)) {
+		++net->stats.rx_dropped;
+		return NVSP_STAT_FAIL;
+	}
+	skb_record_rx_queue(skb, channel->
 			    offermsg.offer.sub_channel_index);
 
 	u64_stats_update_begin(&rx_stats->syncp);
@@ -761,8 +736,7 @@ static void netvsc_get_channels(struct n
 				struct ethtool_channels *channel)
 {
 	struct net_device_context *net_device_ctx = netdev_priv(net);
-	struct hv_device *dev = net_device_ctx->device_ctx;
-	struct netvsc_device *nvdev = hv_get_drvdata(dev);
+	struct netvsc_device *nvdev = net_device_ctx->nvdev;
 
 	if (nvdev) {
 		channel->max_combined	= nvdev->max_chn;
@@ -775,14 +749,14 @@ static int netvsc_set_channels(struct ne
 {
 	struct net_device_context *net_device_ctx = netdev_priv(net);
 	struct hv_device *dev = net_device_ctx->device_ctx;
-	struct netvsc_device *nvdev = hv_get_drvdata(dev);
+	struct netvsc_device *nvdev = net_device_ctx->nvdev;
 	struct netvsc_device_info device_info;
 	u32 num_chn;
 	u32 max_chn;
 	int ret = 0;
 	bool recovering = false;
 
-	if (!nvdev || nvdev->destroy)
+	if (net_device_ctx->start_remove || !nvdev || nvdev->destroy)
 		return -ENODEV;
 
 	num_chn = nvdev->num_chn;
@@ -811,14 +785,11 @@ static int netvsc_set_channels(struct ne
 		goto out;
 
  do_set:
-	nvdev->start_remove = true;
+	net_device_ctx->start_remove = true;
 	rndis_filter_device_remove(dev);
 
 	nvdev->num_chn = channels->combined_count;
 
-	net_device_ctx->device_ctx = dev;
-	hv_set_drvdata(dev, net);
-
 	memset(&device_info, 0, sizeof(device_info));
 	device_info.num_chn = nvdev->num_chn; /* passed to RNDIS */
 	device_info.ring_size = ring_size;
@@ -833,7 +804,7 @@ static int netvsc_set_channels(struct ne
 		goto recover;
 	}
 
-	nvdev = hv_get_drvdata(dev);
+	nvdev = net_device_ctx->nvdev;
 
 	ret = netif_set_real_num_tx_queues(net, nvdev->num_chn);
 	if (ret) {
@@ -855,6 +826,9 @@ static int netvsc_set_channels(struct ne
 
  out:
 	netvsc_open(net);
+	net_device_ctx->start_remove = false;
+	/* We may have missed link change notifications */
+	schedule_delayed_work(&net_device_ctx->dwork, 0);
 
 	return ret;
 
@@ -868,16 +842,69 @@ static int netvsc_set_channels(struct ne
 	goto do_set;
 }
 
+static bool netvsc_validate_ethtool_ss_cmd(const struct ethtool_cmd *cmd)
+{
+	struct ethtool_cmd diff1 = *cmd;
+	struct ethtool_cmd diff2 = {};
+
+	ethtool_cmd_speed_set(&diff1, 0);
+	diff1.duplex = 0;
+	/* advertising and cmd are usually set */
+	diff1.advertising = 0;
+	diff1.cmd = 0;
+	/* We set port to PORT_OTHER */
+	diff2.port = PORT_OTHER;
+
+	return !memcmp(&diff1, &diff2, sizeof(diff1));
+}
+
+static void netvsc_init_settings(struct net_device *dev)
+{
+	struct net_device_context *ndc = netdev_priv(dev);
+
+	ndc->speed = SPEED_UNKNOWN;
+	ndc->duplex = DUPLEX_UNKNOWN;
+}
+
+static int netvsc_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+{
+	struct net_device_context *ndc = netdev_priv(dev);
+
+	ethtool_cmd_speed_set(cmd, ndc->speed);
+	cmd->duplex = ndc->duplex;
+	cmd->port = PORT_OTHER;
+
+	return 0;
+}
+
+static int netvsc_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+{
+	struct net_device_context *ndc = netdev_priv(dev);
+	u32 speed;
+
+	speed = ethtool_cmd_speed(cmd);
+	if (!ethtool_validate_speed(speed) ||
+	    !ethtool_validate_duplex(cmd->duplex) ||
+	    !netvsc_validate_ethtool_ss_cmd(cmd))
+		return -EINVAL;
+
+	ndc->speed = speed;
+	ndc->duplex = cmd->duplex;
+
+	return 0;
+}
+
 static int netvsc_change_mtu(struct net_device *ndev, int mtu)
 {
 	struct net_device_context *ndevctx = netdev_priv(ndev);
-	struct hv_device *hdev =  ndevctx->device_ctx;
-	struct netvsc_device *nvdev = hv_get_drvdata(hdev);
+	struct netvsc_device *nvdev = ndevctx->nvdev;
+	struct hv_device *hdev = ndevctx->device_ctx;
 	struct netvsc_device_info device_info;
 	int limit = ETH_DATA_LEN;
+	u32 num_chn;
 	int ret = 0;
 
-	if (nvdev == NULL || nvdev->destroy)
+	if (ndevctx->start_remove || !nvdev || nvdev->destroy)
 		return -ENODEV;
 
 	if (nvdev->nvsp_version >= NVSP_PROTOCOL_VERSION_2)
@@ -890,22 +917,25 @@ static int netvsc_change_mtu(struct net_
 	if (ret)
 		goto out;
 
-	nvdev->start_remove = true;
+	num_chn = nvdev->num_chn;
+
+	ndevctx->start_remove = true;
 	rndis_filter_device_remove(hdev);
 
 	ndev->mtu = mtu;
 
-	ndevctx->device_ctx = hdev;
-	hv_set_drvdata(hdev, ndev);
-
 	memset(&device_info, 0, sizeof(device_info));
 	device_info.ring_size = ring_size;
-	device_info.num_chn = nvdev->num_chn;
+	device_info.num_chn = num_chn;
 	device_info.max_num_vrss_chns = max_num_vrss_chns;
 	rndis_filter_device_add(hdev, &device_info);
 
 out:
 	netvsc_open(ndev);
+	ndevctx->start_remove = false;
+
+	/* We may have missed link change notifications */
+	schedule_delayed_work(&ndevctx->dwork, 0);
 
 	return ret;
 }
@@ -953,8 +983,6 @@ static struct rtnl_link_stats64 *netvsc_
 
 static int netvsc_set_mac_addr(struct net_device *ndev, void *p)
 {
-	struct net_device_context *ndevctx = netdev_priv(ndev);
-	struct hv_device *hdev =  ndevctx->device_ctx;
 	struct sockaddr *addr = p;
 	char save_adr[ETH_ALEN];
 	unsigned char save_aatype;
@@ -967,7 +995,7 @@ static int netvsc_set_mac_addr(struct ne
 	if (err != 0)
 		return err;
 
-	err = rndis_filter_set_device_mac(hdev, addr->sa_data);
+	err = rndis_filter_set_device_mac(ndev, addr->sa_data);
 	if (err != 0) {
 		/* roll back to saved MAC */
 		memcpy(ndev->dev_addr, save_adr, ETH_ALEN);
@@ -991,6 +1019,9 @@ static const struct ethtool_ops ethtool_
 	.get_link	= ethtool_op_get_link,
 	.get_channels   = netvsc_get_channels,
 	.set_channels   = netvsc_set_channels,
+	.get_ts_info	= ethtool_op_get_ts_info,
+	.get_settings	= netvsc_get_settings,
+	.set_settings	= netvsc_set_settings,
 };
 
 static const struct net_device_ops device_ops = {
@@ -1009,49 +1040,106 @@ static const struct net_device_ops devic
 };
 
 /*
- * Send GARP packet to network peers after migrations.
- * After Quick Migration, the network is not immediately operational in the
- * current context when receiving RNDIS_STATUS_MEDIA_CONNECT event. So, add
- * another netif_notify_peers() into a delayed work, otherwise GARP packet
- * will not be sent after quick migration, and cause network disconnection.
- * Also, we update the carrier status here.
+ * Handle link status changes. For RNDIS_STATUS_NETWORK_CHANGE emulate link
+ * down/up sequence. In case of RNDIS_STATUS_MEDIA_CONNECT when carrier is
+ * present send GARP packet to network peers with netif_notify_peers().
  */
 static void netvsc_link_change(struct work_struct *w)
 {
-	struct net_device_context *ndev_ctx;
-	struct net_device *net;
+	struct net_device_context *ndev_ctx =
+		container_of(w, struct net_device_context, dwork.work);
+	struct hv_device *device_obj = ndev_ctx->device_ctx;
+	struct net_device *net = hv_get_drvdata(device_obj);
 	struct netvsc_device *net_device;
 	struct rndis_device *rdev;
-	bool notify, refresh = false;
-	char *argv[] = { "/etc/init.d/network", "restart", NULL };
-	char *envp[] = { "HOME=/", "PATH=/sbin:/usr/sbin:/bin:/usr/bin", NULL };
+	struct netvsc_reconfig *event = NULL;
+	bool notify = false, reschedule = false;
+	unsigned long flags, next_reconfig, delay;
 
 	rtnl_lock();
+	if (ndev_ctx->start_remove)
+		goto out_unlock;
 
-	ndev_ctx = container_of(w, struct net_device_context, dwork.work);
-	net_device = hv_get_drvdata(ndev_ctx->device_ctx);
+	net_device = ndev_ctx->nvdev;
 	rdev = net_device->extension;
-	net = net_device->ndev;
 
-	if (rdev->link_state) {
-		netif_carrier_off(net);
-		notify = false;
-	} else {
-		netif_carrier_on(net);
-		notify = true;
-		if (rdev->link_change) {
-			rdev->link_change = false;
-			refresh = true;
+	next_reconfig = ndev_ctx->last_reconfig + LINKCHANGE_INT;
+	if (time_is_after_jiffies(next_reconfig)) {
+		/* link_watch only sends one notification with current state
+		 * per second, avoid doing reconfig more frequently. Handle
+		 * wrap around.
+		 */
+		delay = next_reconfig - jiffies;
+		delay = delay < LINKCHANGE_INT ? delay : LINKCHANGE_INT;
+		schedule_delayed_work(&ndev_ctx->dwork, delay);
+		goto out_unlock;
+	}
+	ndev_ctx->last_reconfig = jiffies;
+
+	spin_lock_irqsave(&ndev_ctx->lock, flags);
+	if (!list_empty(&ndev_ctx->reconfig_events)) {
+		event = list_first_entry(&ndev_ctx->reconfig_events,
+					 struct netvsc_reconfig, list);
+		list_del(&event->list);
+		reschedule = !list_empty(&ndev_ctx->reconfig_events);
+	}
+	spin_unlock_irqrestore(&ndev_ctx->lock, flags);
+
+	if (!event)
+		goto out_unlock;
+
+	switch (event->event) {
+		/* Only the following events are possible due to the check in
+		 * netvsc_linkstatus_callback()
+		 */
+	case RNDIS_STATUS_MEDIA_CONNECT:
+		if (rdev->link_state) {
+			rdev->link_state = false;
+			netif_carrier_on(net);
+			netif_tx_wake_all_queues(net);
+		} else {
+			notify = true;
+		}
+		kfree(event);
+		break;
+	case RNDIS_STATUS_MEDIA_DISCONNECT:
+		if (!rdev->link_state) {
+			rdev->link_state = true;
+			netif_carrier_off(net);
+			netif_tx_stop_all_queues(net);
 		}
+		kfree(event);
+		break;
+	case RNDIS_STATUS_NETWORK_CHANGE:
+		/* Only makes sense if carrier is present */
+		if (!rdev->link_state) {
+			rdev->link_state = true;
+			netif_carrier_off(net);
+			netif_tx_stop_all_queues(net);
+			event->event = RNDIS_STATUS_MEDIA_CONNECT;
+			spin_lock_irqsave(&ndev_ctx->lock, flags);
+			list_add(&event->list, &ndev_ctx->reconfig_events);
+			spin_unlock_irqrestore(&ndev_ctx->lock, flags);
+			reschedule = true;
+		}
+		break;
 	}
 
 	rtnl_unlock();
 
-	if (refresh)
-		call_usermodehelper(argv[0], argv, envp, UMH_WAIT_EXEC);
-
 	if (notify)
 		netdev_notify_peers(net);
+
+	/* link_watch only sends one notification with current state per
+	 * second, handle next reconfig event in 2 seconds.
+	 */
+	if (reschedule)
+		schedule_delayed_work(&ndev_ctx->dwork, LINKCHANGE_INT);
+
+	return;
+
+out_unlock:
+	rtnl_unlock();
 }
 
 static void netvsc_free_netdev(struct net_device *netdev)
@@ -1063,6 +1151,176 @@ static void netvsc_free_netdev(struct ne
 	free_netdev(netdev);
 }
 
+static struct net_device *get_netvsc_net_device(char *mac)
+{
+	struct net_device *dev, *found = NULL;
+	int rtnl_locked;
+
+	rtnl_locked = rtnl_trylock();
+
+	for_each_netdev(&init_net, dev) {
+		if (memcmp(dev->dev_addr, mac, ETH_ALEN) == 0) {
+			if (dev->netdev_ops != &device_ops)
+				continue;
+			found = dev;
+			break;
+		}
+	}
+	if (rtnl_locked)
+		rtnl_unlock();
+
+	return found;
+}
+
+static int netvsc_register_vf(struct net_device *vf_netdev)
+{
+	struct net_device *ndev;
+	struct net_device_context *net_device_ctx;
+	struct netvsc_device *netvsc_dev;
+	const struct ethtool_ops *eth_ops = vf_netdev->ethtool_ops;
+
+	if (eth_ops == NULL || eth_ops == &ethtool_ops)
+		return NOTIFY_DONE;
+
+	/*
+	 * We will use the MAC address to locate the synthetic interface to
+	 * associate with the VF interface. If we don't find a matching
+	 * synthetic interface, move on.
+	 */
+	ndev = get_netvsc_net_device(vf_netdev->dev_addr);
+	if (!ndev)
+		return NOTIFY_DONE;
+
+	net_device_ctx = netdev_priv(ndev);
+	netvsc_dev = net_device_ctx->nvdev;
+	if (!netvsc_dev || net_device_ctx->vf_netdev)
+		return NOTIFY_DONE;
+
+	netdev_info(ndev, "VF registering: %s\n", vf_netdev->name);
+	/*
+	 * Take a reference on the module.
+	 */
+	try_module_get(THIS_MODULE);
+	net_device_ctx->vf_netdev = vf_netdev;
+	return NOTIFY_OK;
+}
+
+static void netvsc_inject_enable(struct net_device_context *net_device_ctx)
+{
+	net_device_ctx->vf_inject = true;
+}
+
+static void netvsc_inject_disable(struct net_device_context *net_device_ctx)
+{
+	net_device_ctx->vf_inject = false;
+
+	/* Wait for currently active users to drain out. */
+	while (atomic_read(&net_device_ctx->vf_use_cnt) != 0)
+		udelay(50);
+}
+
+static int netvsc_vf_up(struct net_device *vf_netdev)
+{
+	struct net_device *ndev;
+	struct netvsc_device *netvsc_dev;
+	const struct ethtool_ops *eth_ops = vf_netdev->ethtool_ops;
+	struct net_device_context *net_device_ctx;
+
+	if (eth_ops == &ethtool_ops)
+		return NOTIFY_DONE;
+
+	ndev = get_netvsc_net_device(vf_netdev->dev_addr);
+	if (!ndev)
+		return NOTIFY_DONE;
+
+	net_device_ctx = netdev_priv(ndev);
+	netvsc_dev = net_device_ctx->nvdev;
+
+	if (!netvsc_dev || !net_device_ctx->vf_netdev)
+		return NOTIFY_DONE;
+
+	netdev_info(ndev, "VF up: %s\n", vf_netdev->name);
+	netvsc_inject_enable(net_device_ctx);
+
+	/*
+	 * Open the device before switching data path.
+	 */
+	rndis_filter_open(netvsc_dev);
+
+	/*
+	 * notify the host to switch the data path.
+	 */
+	netvsc_switch_datapath(ndev, true);
+	netdev_info(ndev, "Data path switched to VF: %s\n", vf_netdev->name);
+
+	netif_carrier_off(ndev);
+
+	/* Now notify peers through VF device. */
+	call_netdevice_notifiers(NETDEV_NOTIFY_PEERS, vf_netdev);
+
+	return NOTIFY_OK;
+}
+
+
+static int netvsc_vf_down(struct net_device *vf_netdev)
+{
+	struct net_device *ndev;
+	struct netvsc_device *netvsc_dev;
+	struct net_device_context *net_device_ctx;
+	const struct ethtool_ops *eth_ops = vf_netdev->ethtool_ops;
+
+	if (eth_ops == &ethtool_ops)
+		return NOTIFY_DONE;
+
+	ndev = get_netvsc_net_device(vf_netdev->dev_addr);
+	if (!ndev)
+		return NOTIFY_DONE;
+
+	net_device_ctx = netdev_priv(ndev);
+	netvsc_dev = net_device_ctx->nvdev;
+
+	if (!netvsc_dev || !net_device_ctx->vf_netdev)
+		return NOTIFY_DONE;
+
+	netdev_info(ndev, "VF down: %s\n", vf_netdev->name);
+	netvsc_inject_disable(net_device_ctx);
+	netvsc_switch_datapath(ndev, false);
+	netdev_info(ndev, "Data path switched from VF: %s\n", vf_netdev->name);
+	rndis_filter_close(netvsc_dev);
+	netif_carrier_on(ndev);
+
+	/* Now notify peers through netvsc device. */
+	call_netdevice_notifiers(NETDEV_NOTIFY_PEERS, ndev);
+
+	return NOTIFY_OK;
+}
+
+
+static int netvsc_unregister_vf(struct net_device *vf_netdev)
+{
+	struct net_device *ndev;
+	struct netvsc_device *netvsc_dev;
+	const struct ethtool_ops *eth_ops = vf_netdev->ethtool_ops;
+	struct net_device_context *net_device_ctx;
+
+	if (eth_ops == &ethtool_ops)
+		return NOTIFY_DONE;
+
+	ndev = get_netvsc_net_device(vf_netdev->dev_addr);
+	if (!ndev)
+		return NOTIFY_DONE;
+
+	net_device_ctx = netdev_priv(ndev);
+	netvsc_dev = net_device_ctx->nvdev;
+	if (!netvsc_dev || !net_device_ctx->vf_netdev)
+		return NOTIFY_DONE;
+	netdev_info(ndev, "VF unregistering: %s\n", vf_netdev->name);
+	netvsc_inject_disable(net_device_ctx);
+	net_device_ctx->vf_netdev = NULL;
+	module_put(THIS_MODULE);
+	return NOTIFY_OK;
+}
+
 static int netvsc_probe(struct hv_device *dev,
 			const struct hv_vmbus_device_id *dev_id)
 {
@@ -1071,16 +1329,12 @@ static int netvsc_probe(struct hv_device
 	struct netvsc_device_info device_info;
 	struct netvsc_device *nvdev;
 	int ret;
-	u32 max_needed_headroom;
 
 	net = alloc_etherdev_mq(sizeof(struct net_device_context),
 				num_online_cpus());
 	if (!net)
 		return -ENOMEM;
 
-	max_needed_headroom = sizeof(struct hv_netvsc_packet) +
-			      RNDIS_AND_PPI_SIZE;
-
 	netif_carrier_off(net);
 
 	net_device_ctx = netdev_priv(net);
@@ -1103,25 +1357,29 @@ static int netvsc_probe(struct hv_device
 	}
 
 	hv_set_drvdata(dev, net);
+
+	net_device_ctx->start_remove = false;
+
 	INIT_DELAYED_WORK(&net_device_ctx->dwork, netvsc_link_change);
 	INIT_WORK(&net_device_ctx->work, do_set_multicast);
 
+	spin_lock_init(&net_device_ctx->lock);
+	INIT_LIST_HEAD(&net_device_ctx->reconfig_events);
+
+	atomic_set(&net_device_ctx->vf_use_cnt, 0);
+	net_device_ctx->vf_netdev = NULL;
+	net_device_ctx->vf_inject = false;
+
 	net->netdev_ops = &device_ops;
 
-	net->hw_features = NETIF_F_RXCSUM | NETIF_F_SG | NETIF_F_IP_CSUM |
-				NETIF_F_TSO;
-	net->features = NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_SG | NETIF_F_RXCSUM |
-			NETIF_F_IP_CSUM | NETIF_F_TSO;
+	net->hw_features = NETVSC_HW_FEATURES;
+	net->features = NETVSC_HW_FEATURES | NETIF_F_HW_VLAN_CTAG_TX;
 
 	net->ethtool_ops = &ethtool_ops;
 	SET_NETDEV_DEV(net, &dev->device);
 
-	/*
-	 * Request additional head room in the skb.
-	 * We will use this space to build the rndis
-	 * heaser and other state we need to maintain.
-	 */
-	net->needed_headroom = max_needed_headroom;
+	/* We always need headroom for rndis header */
+	net->needed_headroom = RNDIS_AND_PPI_SIZE;
 
 	/* Notify the netvsc driver of the new device */
 	memset(&device_info, 0, sizeof(device_info));
@@ -1136,17 +1394,17 @@ static int netvsc_probe(struct hv_device
 	}
 	memcpy(net->dev_addr, device_info.mac_adr, ETH_ALEN);
 
-	nvdev = hv_get_drvdata(dev);
+	nvdev = net_device_ctx->nvdev;
 	netif_set_real_num_tx_queues(net, nvdev->num_chn);
 	netif_set_real_num_rx_queues(net, nvdev->num_chn);
 
+	netvsc_init_settings(net);
+
 	ret = register_netdev(net);
 	if (ret != 0) {
 		pr_err("Unable to register netdev.\n");
 		rndis_filter_device_remove(dev);
 		netvsc_free_netdev(net);
-	} else {
-		schedule_delayed_work(&net_device_ctx->dwork, 0);
 	}
 
 	return ret;
@@ -1158,17 +1416,24 @@ static int netvsc_remove(struct hv_devic
 	struct net_device_context *ndev_ctx;
 	struct netvsc_device *net_device;
 
-	net_device = hv_get_drvdata(dev);
-	net = net_device->ndev;
+	net = hv_get_drvdata(dev);
 
 	if (net == NULL) {
 		dev_err(&dev->device, "No net device to remove\n");
 		return 0;
 	}
 
-	net_device->start_remove = true;
 
 	ndev_ctx = netdev_priv(net);
+	net_device = ndev_ctx->nvdev;
+
+	/* Avoid racing with netvsc_change_mtu()/netvsc_set_channels()
+	 * removing the device.
+	 */
+	rtnl_lock();
+	ndev_ctx->start_remove = true;
+	rtnl_unlock();
+
 	cancel_delayed_work_sync(&ndev_ctx->dwork);
 	cancel_work_sync(&ndev_ctx->work);
 
@@ -1183,6 +1448,8 @@ static int netvsc_remove(struct hv_devic
 	 */
 	rndis_filter_device_remove(dev);
 
+	hv_set_drvdata(dev, NULL);
+
 	netvsc_free_netdev(net);
 	return 0;
 }
@@ -1203,19 +1470,67 @@ static struct  hv_driver netvsc_drv = {
 	.remove = netvsc_remove,
 };
 
+
+/*
+ * On Hyper-V, every VF interface is matched with a corresponding
+ * synthetic interface. The synthetic interface is presented first
+ * to the guest. When the corresponding VF instance is registered,
+ * we will take care of switching the data path.
+ */
+static int netvsc_netdev_event(struct notifier_block *this,
+			       unsigned long event, void *ptr)
+{
+	struct net_device *event_dev = netdev_notifier_info_to_dev(ptr);
+
+	/* Avoid Vlan dev with same MAC registering as VF */
+	if (event_dev->priv_flags & IFF_802_1Q_VLAN)
+		return NOTIFY_DONE;
+
+	/* Avoid Bonding master dev with same MAC registering as VF */
+	if (event_dev->priv_flags & IFF_BONDING &&
+	    event_dev->flags & IFF_MASTER)
+		return NOTIFY_DONE;
+
+	switch (event) {
+	case NETDEV_REGISTER:
+		return netvsc_register_vf(event_dev);
+	case NETDEV_UNREGISTER:
+		return netvsc_unregister_vf(event_dev);
+	case NETDEV_UP:
+		return netvsc_vf_up(event_dev);
+	case NETDEV_DOWN:
+		return netvsc_vf_down(event_dev);
+	default:
+		return NOTIFY_DONE;
+	}
+}
+
+static struct notifier_block netvsc_netdev_notifier = {
+	.notifier_call = netvsc_netdev_event,
+};
+
 static void __exit netvsc_drv_exit(void)
 {
+	unregister_netdevice_notifier(&netvsc_netdev_notifier);
 	vmbus_driver_unregister(&netvsc_drv);
 }
 
 static int __init netvsc_drv_init(void)
 {
+	int ret;
+
 	if (ring_size < RING_SIZE_MIN) {
 		ring_size = RING_SIZE_MIN;
 		pr_info("Increased ring_size to %d (min allowed)\n",
 			ring_size);
 	}
-	return vmbus_driver_register(&netvsc_drv);
+	ret = vmbus_driver_register(&netvsc_drv);
+
+	if (ret)
+		return ret;
+
+	register_netdevice_notifier(&netvsc_netdev_notifier);
+	return 0;
 }
 
 MODULE_LICENSE("GPL");
--- zfcpdump-kernel-4.4.orig/drivers/net/hyperv/rndis_filter.c
+++ zfcpdump-kernel-4.4/drivers/net/hyperv/rndis_filter.c
@@ -126,11 +126,7 @@ static void put_rndis_request(struct rnd
 static void dump_rndis_message(struct hv_device *hv_dev,
 			struct rndis_message *rndis_msg)
 {
-	struct net_device *netdev;
-	struct netvsc_device *net_device;
-
-	net_device = hv_get_drvdata(hv_dev);
-	netdev = net_device->ndev;
+	struct net_device *netdev = hv_get_drvdata(hv_dev);
 
 	switch (rndis_msg->ndis_msg_type) {
 	case RNDIS_MSG_PACKET:
@@ -210,37 +206,34 @@ static int rndis_filter_send_request(str
 	int ret;
 	struct hv_netvsc_packet *packet;
 	struct hv_page_buffer page_buf[2];
+	struct hv_page_buffer *pb = page_buf;
+	struct net_device_context *net_device_ctx = netdev_priv(dev->ndev);
 
 	/* Setup the packet to send it */
 	packet = &req->pkt;
 
-	packet->is_data_pkt = false;
 	packet->total_data_buflen = req->request_msg.msg_len;
 	packet->page_buf_cnt = 1;
-	packet->page_buf = page_buf;
 
-	packet->page_buf[0].pfn = virt_to_phys(&req->request_msg) >>
+	pb[0].pfn = virt_to_phys(&req->request_msg) >>
 					PAGE_SHIFT;
-	packet->page_buf[0].len = req->request_msg.msg_len;
-	packet->page_buf[0].offset =
+	pb[0].len = req->request_msg.msg_len;
+	pb[0].offset =
 		(unsigned long)&req->request_msg & (PAGE_SIZE - 1);
 
 	/* Add one page_buf when request_msg crossing page boundary */
-	if (packet->page_buf[0].offset + packet->page_buf[0].len > PAGE_SIZE) {
+	if (pb[0].offset + pb[0].len > PAGE_SIZE) {
 		packet->page_buf_cnt++;
-		packet->page_buf[0].len = PAGE_SIZE -
-			packet->page_buf[0].offset;
-		packet->page_buf[1].pfn = virt_to_phys((void *)&req->request_msg
-			+ packet->page_buf[0].len) >> PAGE_SHIFT;
-		packet->page_buf[1].offset = 0;
-		packet->page_buf[1].len = req->request_msg.msg_len -
-			packet->page_buf[0].len;
+		pb[0].len = PAGE_SIZE -
+			pb[0].offset;
+		pb[1].pfn = virt_to_phys((void *)&req->request_msg
+			+ pb[0].len) >> PAGE_SHIFT;
+		pb[1].offset = 0;
+		pb[1].len = req->request_msg.msg_len -
+			pb[0].len;
 	}
 
-	packet->send_completion = NULL;
-	packet->xmit_more = false;
-
-	ret = netvsc_send(dev->net_dev->dev, packet);
+	ret = netvsc_send(net_device_ctx->device_ctx, packet, NULL, &pb, NULL);
 	return ret;
 }
 
@@ -266,9 +259,7 @@ static void rndis_filter_receive_respons
 	struct rndis_request *request = NULL;
 	bool found = false;
 	unsigned long flags;
-	struct net_device *ndev;
-
-	ndev = dev->net_dev->ndev;
+	struct net_device *ndev = dev->ndev;
 
 	spin_lock_irqsave(&dev->request_lock, flags);
 	list_for_each_entry(request, &dev->req_list, list_ent) {
@@ -348,14 +339,18 @@ static inline void *rndis_get_ppi(struct
 	return NULL;
 }
 
-static void rndis_filter_receive_data(struct rndis_device *dev,
+static int rndis_filter_receive_data(struct rndis_device *dev,
 				   struct rndis_message *msg,
-				   struct hv_netvsc_packet *pkt)
+				   struct hv_netvsc_packet *pkt,
+				   void **data,
+				   struct vmbus_channel *channel)
 {
 	struct rndis_packet *rndis_pkt;
 	u32 data_offset;
 	struct ndis_pkt_8021q_info *vlan;
 	struct ndis_tcp_ip_checksum_info *csum_info;
+	u16 vlan_tci = 0;
+	struct net_device_context *net_device_ctx = netdev_priv(dev->ndev);
 
 	rndis_pkt = &msg->msg.pkt;
 
@@ -369,11 +364,11 @@ static void rndis_filter_receive_data(st
 	 * should be the data packet size plus the trailer padding size
 	 */
 	if (pkt->total_data_buflen < rndis_pkt->data_len) {
-		netdev_err(dev->net_dev->ndev, "rndis message buffer "
+		netdev_err(dev->ndev, "rndis message buffer "
 			   "overflow detected (got %u, min %u)"
 			   "...dropping this message!\n",
 			   pkt->total_data_buflen, rndis_pkt->data_len);
-		return;
+		return NVSP_STAT_FAIL;
 	}
 
 	/*
@@ -382,41 +377,41 @@ static void rndis_filter_receive_data(st
 	 * the data packet to the stack, without the rndis trailer padding
 	 */
 	pkt->total_data_buflen = rndis_pkt->data_len;
-	pkt->data = (void *)((unsigned long)pkt->data + data_offset);
+	*data = (void *)((unsigned long)(*data) + data_offset);
 
 	vlan = rndis_get_ppi(rndis_pkt, IEEE_8021Q_INFO);
 	if (vlan) {
-		pkt->vlan_tci = VLAN_TAG_PRESENT | vlan->vlanid |
+		vlan_tci = VLAN_TAG_PRESENT | vlan->vlanid |
 			(vlan->pri << VLAN_PRIO_SHIFT);
-	} else {
-		pkt->vlan_tci = 0;
 	}
 
 	csum_info = rndis_get_ppi(rndis_pkt, TCPIP_CHKSUM_PKTINFO);
-	netvsc_recv_callback(dev->net_dev->dev, pkt, csum_info);
+	return netvsc_recv_callback(net_device_ctx->device_ctx, pkt, data,
+				    csum_info, channel, vlan_tci);
 }
 
 int rndis_filter_receive(struct hv_device *dev,
-				struct hv_netvsc_packet	*pkt)
-{
-	struct netvsc_device *net_dev = hv_get_drvdata(dev);
+				struct hv_netvsc_packet	*pkt,
+				void **data,
+				struct vmbus_channel *channel)
+{
+	struct net_device *ndev = hv_get_drvdata(dev);
+	struct net_device_context *net_device_ctx = netdev_priv(ndev);
+	struct netvsc_device *net_dev = net_device_ctx->nvdev;
 	struct rndis_device *rndis_dev;
 	struct rndis_message *rndis_msg;
-	struct net_device *ndev;
 	int ret = 0;
 
 	if (!net_dev) {
-		ret = -EINVAL;
+		ret = NVSP_STAT_FAIL;
 		goto exit;
 	}
 
-	ndev = net_dev->ndev;
-
 	/* Make sure the rndis device state is initialized */
 	if (!net_dev->extension) {
 		netdev_err(ndev, "got rndis message but no rndis device - "
 			  "dropping this message!\n");
-		ret = -ENODEV;
+		ret = NVSP_STAT_FAIL;
 		goto exit;
 	}
 
@@ -424,19 +419,20 @@ int rndis_filter_receive(struct hv_devic
 	if (rndis_dev->state == RNDIS_DEV_UNINITIALIZED) {
 		netdev_err(ndev, "got rndis message but rndis device "
 			   "uninitialized...dropping this message!\n");
-		ret = -ENODEV;
+		ret = NVSP_STAT_FAIL;
 		goto exit;
 	}
 
-	rndis_msg = pkt->data;
+	rndis_msg = *data;
 
-	if (netif_msg_rx_err(net_dev->nd_ctx))
+	if (netif_msg_rx_err(net_device_ctx))
 		dump_rndis_message(dev, rndis_msg);
 
 	switch (rndis_msg->ndis_msg_type) {
 	case RNDIS_MSG_PACKET:
 		/* data msg */
-		rndis_filter_receive_data(rndis_dev, rndis_msg, pkt);
+		ret = rndis_filter_receive_data(rndis_dev, rndis_msg, pkt,
+						data, channel);
 		break;
 
 	case RNDIS_MSG_INIT_C:
@@ -459,9 +455,6 @@ int rndis_filter_receive(struct hv_devic
 	}
 
 exit:
-	if (ret != 0)
-		pkt->status = NVSP_STAT_FAIL;
-
 	return ret;
 }
 
@@ -473,7 +466,6 @@ static int rndis_filter_query_device(str
 	struct rndis_query_request *query;
 	struct rndis_query_complete *query_complete;
 	int ret = 0;
-	unsigned long t;
 
 	if (!result)
 		return -EINVAL;
@@ -510,11 +502,7 @@ static int rndis_filter_query_device(str
 	if (ret != 0)
 		goto cleanup;
 
-	t = wait_for_completion_timeout(&request->wait_event, 5*HZ);
-	if (t == 0) {
-		ret = -ETIMEDOUT;
-		goto cleanup;
-	}
+	wait_for_completion(&request->wait_event);
 
 	/* Copy the response back */
 	query_complete = &request->response_msg.msg.query_complete;
@@ -550,11 +538,10 @@ static int rndis_filter_query_device_mac
 #define NWADR_STR "NetworkAddress"
 #define NWADR_STRLEN 14
 
-int rndis_filter_set_device_mac(struct hv_device *hdev, char *mac)
+int rndis_filter_set_device_mac(struct net_device *ndev, char *mac)
 {
-	struct netvsc_device *nvdev = hv_get_drvdata(hdev);
+	struct netvsc_device *nvdev = net_device_to_netvsc_device(ndev);
 	struct rndis_device *rdev = nvdev->extension;
-	struct net_device *ndev = nvdev->ndev;
 	struct rndis_request *request;
 	struct rndis_set_request *set;
 	struct rndis_config_parameter_info *cpi;
@@ -564,7 +551,6 @@ int rndis_filter_set_device_mac(struct h
 	u32 extlen = sizeof(struct rndis_config_parameter_info) +
 		2*NWADR_STRLEN + 4*ETH_ALEN;
 	int ret;
-	unsigned long t;
 
 	request = get_rndis_request(rdev, RNDIS_MSG_SET,
 		RNDIS_MESSAGE_SIZE(struct rndis_set_request) + extlen);
@@ -605,21 +591,13 @@ int rndis_filter_set_device_mac(struct h
 	if (ret != 0)
 		goto cleanup;
 
-	t = wait_for_completion_timeout(&request->wait_event, 5*HZ);
-	if (t == 0) {
-		netdev_err(ndev, "timeout before we got a set response...\n");
-		/*
-		 * can't put_rndis_request, since we may still receive a
-		 * send-completion.
-		 */
-		return -EBUSY;
-	} else {
-		set_complete = &request->response_msg.msg.set_complete;
-		if (set_complete->status != RNDIS_STATUS_SUCCESS) {
-			netdev_err(ndev, "Fail to set MAC on host side:0x%x\n",
-				   set_complete->status);
-			ret = -EINVAL;
-		}
+	wait_for_completion(&request->wait_event);
+
+	set_complete = &request->response_msg.msg.set_complete;
+	if (set_complete->status != RNDIS_STATUS_SUCCESS) {
+		netdev_err(ndev, "Fail to set MAC on host side:0x%x\n",
+			   set_complete->status);
+		ret = -EINVAL;
 	}
 
 cleanup:
@@ -628,19 +606,17 @@ cleanup:
 }
 
 static int
-rndis_filter_set_offload_params(struct hv_device *hdev,
+rndis_filter_set_offload_params(struct net_device *ndev,
 				struct ndis_offload_params *req_offloads)
 {
-	struct netvsc_device *nvdev = hv_get_drvdata(hdev);
+	struct netvsc_device *nvdev = net_device_to_netvsc_device(ndev);
 	struct rndis_device *rdev = nvdev->extension;
-	struct net_device *ndev = nvdev->ndev;
 	struct rndis_request *request;
 	struct rndis_set_request *set;
 	struct ndis_offload_params *offload_params;
 	struct rndis_set_complete *set_complete;
 	u32 extlen = sizeof(struct ndis_offload_params);
 	int ret;
-	unsigned long t;
 	u32 vsp_version = nvdev->nvsp_version;
 
 	if (vsp_version <= NVSP_PROTOCOL_VERSION_4) {
@@ -674,20 +650,12 @@ rndis_filter_set_offload_params(struct h
 	if (ret != 0)
 		goto cleanup;
 
-	t = wait_for_completion_timeout(&request->wait_event, 5*HZ);
-	if (t == 0) {
-		netdev_err(ndev, "timeout before we got aOFFLOAD set response...\n");
-		/* can't put_rndis_request, since we may still receive a
-		 * send-completion.
-		 */
-		return -EBUSY;
-	} else {
-		set_complete = &request->response_msg.msg.set_complete;
-		if (set_complete->status != RNDIS_STATUS_SUCCESS) {
-			netdev_err(ndev, "Fail to set offload on host side:0x%x\n",
-				   set_complete->status);
-			ret = -EINVAL;
-		}
+	wait_for_completion(&request->wait_event);
+	set_complete = &request->response_msg.msg.set_complete;
+	if (set_complete->status != RNDIS_STATUS_SUCCESS) {
+		netdev_err(ndev, "Fail to set offload on host side:0x%x\n",
+			   set_complete->status);
+		ret = -EINVAL;
 	}
 
 cleanup:
@@ -705,7 +673,7 @@ u8 netvsc_hash_key[HASH_KEYLEN] = {
 
 static int rndis_filter_set_rss_param(struct rndis_device *rdev, int num_queue)
 {
-	struct net_device *ndev = rdev->net_dev->ndev;
+	struct net_device *ndev = rdev->ndev;
 	struct rndis_request *request;
 	struct rndis_set_request *set;
 	struct rndis_set_complete *set_complete;
@@ -715,7 +683,6 @@ static int rndis_filter_set_rss_param(st
 	u32 *itab;
 	u8 *keyp;
 	int i, ret;
-	unsigned long t;
 
 	request = get_rndis_request(
 			rdev, RNDIS_MSG_SET,
@@ -758,20 +725,12 @@ static int rndis_filter_set_rss_param(st
 	if (ret != 0)
 		goto cleanup;
 
-	t = wait_for_completion_timeout(&request->wait_event, 5*HZ);
-	if (t == 0) {
-		netdev_err(ndev, "timeout before we got a set response...\n");
-		/* can't put_rndis_request, since we may still receive a
-		 * send-completion.
-		 */
-		return -ETIMEDOUT;
-	} else {
-		set_complete = &request->response_msg.msg.set_complete;
-		if (set_complete->status != RNDIS_STATUS_SUCCESS) {
-			netdev_err(ndev, "Fail to set RSS parameters:0x%x\n",
-				   set_complete->status);
-			ret = -EINVAL;
-		}
+	wait_for_completion(&request->wait_event);
+	set_complete = &request->response_msg.msg.set_complete;
+	if (set_complete->status != RNDIS_STATUS_SUCCESS) {
+		netdev_err(ndev, "Fail to set RSS parameters:0x%x\n",
+			   set_complete->status);
+		ret = -EINVAL;
 	}
 
 cleanup:
@@ -800,10 +759,6 @@ int rndis_filter_set_packet_filter(struc
 	struct rndis_set_complete *set_complete;
 	u32 status;
 	int ret;
-	unsigned long t;
-	struct net_device *ndev;
-
-	ndev = dev->net_dev->ndev;
 
 	request = get_rndis_request(dev, RNDIS_MSG_SET,
 			RNDIS_MESSAGE_SIZE(struct rndis_set_request) +
@@ -826,26 +781,14 @@ int rndis_filter_set_packet_filter(struc
 	if (ret != 0)
 		goto cleanup;
 
-	t = wait_for_completion_timeout(&request->wait_event, 5*HZ);
+	wait_for_completion(&request->wait_event);
 
-	if (t == 0) {
-		netdev_err(ndev,
-			"timeout before we got a set response...\n");
-		ret = -ETIMEDOUT;
-		/*
-		 * We can't deallocate the request since we may still receive a
-		 * send completion for it.
-		 */
-		goto exit;
-	} else {
-		set_complete = &request->response_msg.msg.set_complete;
-		status = set_complete->status;
-	}
+	set_complete = &request->response_msg.msg.set_complete;
+	status = set_complete->status;
 
 cleanup:
 	if (request)
 		put_rndis_request(dev, request);
-exit:
 	return ret;
 }
 
@@ -857,8 +800,7 @@ static int rndis_filter_init_device(stru
 	struct rndis_initialize_complete *init_complete;
 	u32 status;
 	int ret;
-	unsigned long t;
-	struct netvsc_device *nvdev = dev->net_dev;
+	struct netvsc_device *nvdev = net_device_to_netvsc_device(dev->ndev);
 
 	request = get_rndis_request(dev, RNDIS_MSG_INIT,
 			RNDIS_MESSAGE_SIZE(struct rndis_initialize_request));
@@ -881,13 +823,7 @@ static int rndis_filter_init_device(stru
 		goto cleanup;
 	}
 
-
-	t = wait_for_completion_timeout(&request->wait_event, 5*HZ);
-
-	if (t == 0) {
-		ret = -ETIMEDOUT;
-		goto cleanup;
-	}
+	wait_for_completion(&request->wait_event);
 
 	init_complete = &request->response_msg.msg.init_complete;
 	status = init_complete->status;
@@ -912,8 +848,9 @@ static void rndis_filter_halt_device(str
 {
 	struct rndis_request *request;
 	struct rndis_halt_request *halt;
-	struct netvsc_device *nvdev = dev->net_dev;
-	struct hv_device *hdev = nvdev->dev;
+	struct net_device_context *net_device_ctx = netdev_priv(dev->ndev);
+	struct netvsc_device *nvdev = net_device_ctx->nvdev;
+	struct hv_device *hdev = net_device_ctx->device_ctx;
 	ulong flags;
 
 	/* Attempt to do a rndis device halt */
@@ -981,19 +918,13 @@ static int rndis_filter_close_device(str
 
 static void netvsc_sc_open(struct vmbus_channel *new_sc)
 {
-	struct netvsc_device *nvscdev;
+	struct net_device *ndev =
+		hv_get_drvdata(new_sc->primary_channel->device_obj);
+	struct netvsc_device *nvscdev = net_device_to_netvsc_device(ndev);
 	u16 chn_index = new_sc->offermsg.offer.sub_channel_index;
 	int ret;
 	unsigned long flags;
 
-	nvscdev = hv_get_drvdata(new_sc->primary_channel->device_obj);
-
-	spin_lock_irqsave(&nvscdev->sc_lock, flags);
-	nvscdev->num_sc_offered--;
-	spin_unlock_irqrestore(&nvscdev->sc_lock, flags);
-	if (nvscdev->num_sc_offered == 0)
-		complete(&nvscdev->channel_init_wait);
-
 	if (chn_index >= nvscdev->num_chn)
 		return;
 
@@ -1006,18 +937,25 @@ static void netvsc_sc_open(struct vmbus_
 
 	if (ret == 0)
 		nvscdev->chn_table[chn_index] = new_sc;
+
+	spin_lock_irqsave(&nvscdev->sc_lock, flags);
+	nvscdev->num_sc_offered--;
+	spin_unlock_irqrestore(&nvscdev->sc_lock, flags);
+	if (nvscdev->num_sc_offered == 0)
+		complete(&nvscdev->channel_init_wait);
 }
 
 int rndis_filter_device_add(struct hv_device *dev,
 				  void *additional_info)
 {
 	int ret;
+	struct net_device *net = hv_get_drvdata(dev);
+	struct net_device_context *net_device_ctx = netdev_priv(net);
 	struct netvsc_device *net_device;
 	struct rndis_device *rndis_device;
 	struct netvsc_device_info *device_info = additional_info;
 	struct ndis_offload_params offloads;
 	struct nvsp_message *init_packet;
-	unsigned long t;
 	struct ndis_recv_scale_cap rsscap;
 	u32 rsscap_size = sizeof(struct ndis_recv_scale_cap);
 	u32 mtu, size;
@@ -1042,16 +980,15 @@ int rndis_filter_device_add(struct hv_de
 		return ret;
 	}
 
-
 	/* Initialize the rndis device */
-	net_device = hv_get_drvdata(dev);
+	net_device = net_device_ctx->nvdev;
 	net_device->max_chn = 1;
 	net_device->num_chn = 1;
 
 	spin_lock_init(&net_device->sc_lock);
 
 	net_device->extension = rndis_device;
-	rndis_device->net_dev = net_device;
+	rndis_device->ndev = net;
 
 	/* Send the rndis initialization message */
 	ret = rndis_filter_init_device(rndis_device);
@@ -1065,8 +1002,8 @@ int rndis_filter_device_add(struct hv_de
 	ret = rndis_filter_query_device(rndis_device,
 					RNDIS_OID_GEN_MAXIMUM_FRAME_SIZE,
 					&mtu, &size);
-	if (ret == 0 && size == sizeof(u32) && mtu < net_device->ndev->mtu)
-		net_device->ndev->mtu = mtu;
+	if (ret == 0 && size == sizeof(u32) && mtu < net->mtu)
+		net->mtu = mtu;
 
 	/* Get the mac address */
 	ret = rndis_filter_query_device_mac(rndis_device);
@@ -1092,7 +1029,7 @@ int rndis_filter_device_add(struct hv_de
 	offloads.lso_v2_ipv4 = NDIS_OFFLOAD_PARAMETERS_LSOV2_ENABLED;
 
 
-	ret = rndis_filter_set_offload_params(dev, &offloads);
+	ret = rndis_filter_set_offload_params(net, &offloads);
 	if (ret)
 		goto err_dev_remv;
 
@@ -1115,9 +1052,9 @@ int rndis_filter_device_add(struct hv_de
 	if (ret || rsscap.num_recv_que < 2)
 		goto out;
 
-	num_rss_qs = min(device_info->max_num_vrss_chns, rsscap.num_recv_que);
+	net_device->max_chn = min_t(u32, VRSS_CHANNEL_MAX, rsscap.num_recv_que);
 
-	net_device->max_chn = rsscap.num_recv_que;
+	num_rss_qs = min(device_info->max_num_vrss_chns, net_device->max_chn);
 
 	/*
 	 * We will limit the VRSS channels to the number CPUs in the NUMA node
@@ -1161,11 +1098,8 @@ int rndis_filter_device_add(struct hv_de
 			       VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
 	if (ret)
 		goto out;
-	t = wait_for_completion_timeout(&net_device->channel_init_wait, 5*HZ);
-	if (t == 0) {
-		ret = -ETIMEDOUT;
-		goto out;
-	}
+	wait_for_completion(&net_device->channel_init_wait);
+
 	if (init_packet->msg.v5_msg.subchn_comp.status !=
 	    NVSP_STAT_SUCCESS) {
 		ret = -ENODEV;
@@ -1177,22 +1111,18 @@ int rndis_filter_device_add(struct hv_de
 	ret = rndis_filter_set_rss_param(rndis_device, net_device->num_chn);
 
 	/*
-	 * Wait for the host to send us the sub-channel offers.
+	 * Set the number of sub-channels to be received.
 	 */
 	spin_lock_irqsave(&net_device->sc_lock, flags);
 	sc_delta = num_rss_qs - (net_device->num_chn - 1);
 	net_device->num_sc_offered -= sc_delta;
 	spin_unlock_irqrestore(&net_device->sc_lock, flags);
 
-	while (net_device->num_sc_offered != 0) {
-		t = wait_for_completion_timeout(&net_device->channel_init_wait, 10*HZ);
-		if (t == 0)
-			WARN(1, "Netvsc: Waiting for sub-channel processing");
-	}
 out:
 	if (ret) {
 		net_device->max_chn = 1;
 		net_device->num_chn = 1;
+		net_device->num_sc_offered = 0;
 	}
 
 	return 0; /* return 0 because primary channel can be used alone */
@@ -1204,9 +1134,15 @@ err_dev_remv:
 
 void rndis_filter_device_remove(struct hv_device *dev)
 {
-	struct netvsc_device *net_dev = hv_get_drvdata(dev);
+	struct netvsc_device *net_dev = hv_device_to_netvsc_device(dev);
 	struct rndis_device *rndis_dev = net_dev->extension;
 
+	/* If not all subchannel offers are complete, wait for them until
+	 * completion to avoid race.
+	 */
+	if (net_dev->num_sc_offered > 0)
+		wait_for_completion(&net_dev->channel_init_wait);
+
 	/* Halt and release the rndis device */
 	rndis_filter_halt_device(rndis_dev);
 
@@ -1217,22 +1153,24 @@ void rndis_filter_device_remove(struct h
 }
 
 
-int rndis_filter_open(struct hv_device *dev)
+int rndis_filter_open(struct netvsc_device *nvdev)
 {
-	struct netvsc_device *net_device = hv_get_drvdata(dev);
-
-	if (!net_device)
+	if (!nvdev)
 		return -EINVAL;
 
-	return rndis_filter_open_device(net_device->extension);
+	if (atomic_inc_return(&nvdev->open_cnt) != 1)
+		return 0;
+
+	return rndis_filter_open_device(nvdev->extension);
 }
 
-int rndis_filter_close(struct hv_device *dev)
+int rndis_filter_close(struct netvsc_device *nvdev)
 {
-	struct netvsc_device *nvdev = hv_get_drvdata(dev);
-
 	if (!nvdev)
 		return -EINVAL;
 
+	if (atomic_dec_return(&nvdev->open_cnt) != 0)
+		return 0;
+
 	return rndis_filter_close_device(nvdev->extension);
 }
--- zfcpdump-kernel-4.4.orig/drivers/net/irda/irtty-sir.c
+++ zfcpdump-kernel-4.4/drivers/net/irda/irtty-sir.c
@@ -430,16 +430,6 @@ static int irtty_open(struct tty_struct
 
 	/* Module stuff handled via irda_ldisc.owner - Jean II */
 
-	/* First make sure we're not already connected. */
-	if (tty->disc_data != NULL) {
-		priv = tty->disc_data;
-		if (priv && priv->magic == IRTTY_MAGIC) {
-			ret = -EEXIST;
-			goto out;
-		}
-		tty->disc_data = NULL;		/* ### */
-	}
-
 	/* stop the underlying  driver */
 	irtty_stop_receiver(tty, TRUE);
 	if (tty->ops->stop)
--- zfcpdump-kernel-4.4.orig/drivers/net/loopback.c
+++ zfcpdump-kernel-4.4/drivers/net/loopback.c
@@ -175,7 +175,7 @@ static void loopback_setup(struct net_de
 		| NETIF_F_UFO
 		| NETIF_F_HW_CSUM
 		| NETIF_F_RXCSUM
-		| NETIF_F_SCTP_CSUM
+		| NETIF_F_SCTP_CRC
 		| NETIF_F_HIGHDMA
 		| NETIF_F_LLTX
 		| NETIF_F_NETNS_LOCAL
--- zfcpdump-kernel-4.4.orig/drivers/net/macvtap.c
+++ zfcpdump-kernel-4.4/drivers/net/macvtap.c
@@ -760,6 +760,8 @@ static ssize_t macvtap_get_user(struct m
 			macvtap16_to_cpu(q, vnet_hdr.hdr_len) : GOODCOPY_LEN;
 		if (copylen > good_linear)
 			copylen = good_linear;
+		else if (copylen < ETH_HLEN)
+			copylen = ETH_HLEN;
 		linear = copylen;
 		i = *from;
 		iov_iter_advance(&i, copylen);
@@ -769,10 +771,11 @@ static ssize_t macvtap_get_user(struct m
 
 	if (!zerocopy) {
 		copylen = len;
-		if (macvtap16_to_cpu(q, vnet_hdr.hdr_len) > good_linear)
+		linear = macvtap16_to_cpu(q, vnet_hdr.hdr_len);
+		if (linear > good_linear)
 			linear = good_linear;
-		else
-			linear = macvtap16_to_cpu(q, vnet_hdr.hdr_len);
+		else if (linear < ETH_HLEN)
+			linear = ETH_HLEN;
 	}
 
 	skb = macvtap_alloc_skb(&q->sk, MACVTAP_RESERVE, copylen,
--- zfcpdump-kernel-4.4.orig/drivers/net/phy/Kconfig
+++ zfcpdump-kernel-4.4/drivers/net/phy/Kconfig
@@ -183,14 +183,28 @@ config MDIO_GPIO
 	  To compile this driver as a module, choose M here: the module
 	  will be called mdio-gpio.
 
+config MDIO_CAVIUM
+	tristate
+
 config MDIO_OCTEON
-	tristate "Support for MDIO buses on Octeon and ThunderX SOCs"
+	tristate "Support for MDIO buses on Octeon and some ThunderX SOCs"
 	depends on 64BIT
+	select MDIO_CAVIUM
 	help
-
 	  This module provides a driver for the Octeon and ThunderX MDIO
-	  busses. It is required by the Octeon and ThunderX ethernet device
-	  drivers.
+	  buses. It is required by the Octeon and ThunderX ethernet device
+	  drivers on some systems.
+
+config MDIO_THUNDER
+	tristate "Support for MDIO buses on ThunderX SOCs"
+	depends on 64BIT
+	depends on PCI
+	select MDIO_CAVIUM
+	help
+	  This driver supports the MDIO interfaces found on Cavium
+	  ThunderX SoCs when the MDIO bus device appears as a PCI
+	  device.
+
 
 config MDIO_SUN4I
 	tristate "Allwinner sun4i MDIO interface support"
--- zfcpdump-kernel-4.4.orig/drivers/net/phy/Makefile
+++ zfcpdump-kernel-4.4/drivers/net/phy/Makefile
@@ -31,6 +31,8 @@ obj-$(CONFIG_DP83867_PHY)	+= dp83867.o
 obj-$(CONFIG_STE10XP)		+= ste10Xp.o
 obj-$(CONFIG_MICREL_PHY)	+= micrel.o
 obj-$(CONFIG_MDIO_OCTEON)	+= mdio-octeon.o
+obj-$(CONFIG_MDIO_THUNDER)	+= mdio-thunder.o
+obj-$(CONFIG_MDIO_CAVIUM)	+= mdio-cavium.o
 obj-$(CONFIG_MICREL_KS8995MA)	+= spi_ks8995.o
 obj-$(CONFIG_AT803X_PHY)	+= at803x.o
 obj-$(CONFIG_AMD_PHY)		+= amd.o
--- zfcpdump-kernel-4.4.orig/drivers/net/phy/dp83640.c
+++ zfcpdump-kernel-4.4/drivers/net/phy/dp83640.c
@@ -845,6 +845,11 @@ static void decode_rxts(struct dp83640_p
 	struct skb_shared_hwtstamps *shhwtstamps = NULL;
 	struct sk_buff *skb;
 	unsigned long flags;
+	u8 overflow;
+
+	overflow = (phy_rxts->ns_hi >> 14) & 0x3;
+	if (overflow)
+		pr_debug("rx timestamp queue overflow, count %d\n", overflow);
 
 	spin_lock_irqsave(&dp83640->rx_lock, flags);
 
@@ -887,6 +892,7 @@ static void decode_txts(struct dp83640_p
 	struct skb_shared_hwtstamps shhwtstamps;
 	struct sk_buff *skb;
 	u64 ns;
+	u8 overflow;
 
 	/* We must already have the skb that triggered this. */
 
@@ -896,6 +902,17 @@ static void decode_txts(struct dp83640_p
 		pr_debug("have timestamp but tx_queue empty\n");
 		return;
 	}
+
+	overflow = (phy_txts->ns_hi >> 14) & 0x3;
+	if (overflow) {
+		pr_debug("tx timestamp queue overflow, count %d\n", overflow);
+		while (skb) {
+			skb_complete_tx_timestamp(skb, NULL);
+			skb = skb_dequeue(&dp83640->tx_queue);
+		}
+		return;
+	}
+
 	ns = phy2txts(phy_txts);
 	memset(&shhwtstamps, 0, sizeof(shhwtstamps));
 	shhwtstamps.hwtstamp = ns_to_ktime(ns);
--- zfcpdump-kernel-4.4.orig/drivers/net/phy/fixed_phy.c
+++ zfcpdump-kernel-4.4/drivers/net/phy/fixed_phy.c
@@ -5,6 +5,7 @@
  *         Anton Vorontsov <avorontsov@ru.mvista.com>
  *
  * Copyright (c) 2006-2007 MontaVista Software, Inc.
+ * Copyright 2009 Freescale Semiconductor, Inc.
  *
  * This program is free software; you can redistribute  it and/or modify it
  * under  the terms of  the GNU General  Public License as published by the
@@ -17,6 +18,7 @@
 #include <linux/platform_device.h>
 #include <linux/list.h>
 #include <linux/mii.h>
+#include <linux/mdio.h>
 #include <linux/phy.h>
 #include <linux/phy_fixed.h>
 #include <linux/err.h>
@@ -59,6 +61,9 @@ static int fixed_phy_update_regs(struct
 
 	if (fp->status.duplex) {
 		switch (fp->status.speed) {
+		case 10000:
+			fp->regs[MDIO_STAT2] = MDIO_STAT2_DEVPRST_VAL;
+			break;
 		case 1000:
 			bmsr |= BMSR_ESTATEN;
 			break;
@@ -73,6 +78,9 @@ static int fixed_phy_update_regs(struct
 		}
 	} else {
 		switch (fp->status.speed) {
+		case 10000:
+			fp->regs[MDIO_STAT2] = MDIO_STAT2_DEVPRST_VAL;
+			break;
 		case 1000:
 			bmsr |= BMSR_ESTATEN;
 			break;
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/net/phy/mdio-cavium.c
@@ -0,0 +1,153 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2009-2016 Cavium, Inc.
+ */
+
+#include <linux/delay.h>
+#include <linux/module.h>
+#include <linux/phy.h>
+#include <linux/io.h>
+
+#include "mdio-cavium.h"
+
+static void cavium_mdiobus_set_mode(struct cavium_mdiobus *p,
+				    enum cavium_mdiobus_mode m)
+{
+	union cvmx_smix_clk smi_clk;
+
+	if (m == p->mode)
+		return;
+
+	smi_clk.u64 = oct_mdio_readq(p->register_base + SMI_CLK);
+	smi_clk.s.mode = (m == C45) ? 1 : 0;
+	smi_clk.s.preamble = 1;
+	oct_mdio_writeq(smi_clk.u64, p->register_base + SMI_CLK);
+	p->mode = m;
+}
+
+static int cavium_mdiobus_c45_addr(struct cavium_mdiobus *p,
+				   int phy_id, int regnum)
+{
+	union cvmx_smix_cmd smi_cmd;
+	union cvmx_smix_wr_dat smi_wr;
+	int timeout = 1000;
+
+	cavium_mdiobus_set_mode(p, C45);
+
+	smi_wr.u64 = 0;
+	smi_wr.s.dat = regnum & 0xffff;
+	oct_mdio_writeq(smi_wr.u64, p->register_base + SMI_WR_DAT);
+
+	regnum = (regnum >> 16) & 0x1f;
+
+	smi_cmd.u64 = 0;
+	smi_cmd.s.phy_op = 0; /* MDIO_CLAUSE_45_ADDRESS */
+	smi_cmd.s.phy_adr = phy_id;
+	smi_cmd.s.reg_adr = regnum;
+	oct_mdio_writeq(smi_cmd.u64, p->register_base + SMI_CMD);
+
+	do {
+		/* Wait 1000 clocks so we don't saturate the RSL bus
+		 * doing reads.
+		 */
+		__delay(1000);
+		smi_wr.u64 = oct_mdio_readq(p->register_base + SMI_WR_DAT);
+	} while (smi_wr.s.pending && --timeout);
+
+	if (timeout <= 0)
+		return -EIO;
+	return 0;
+}
+
+int cavium_mdiobus_read(struct mii_bus *bus, int phy_id, int regnum)
+{
+	struct cavium_mdiobus *p = bus->priv;
+	union cvmx_smix_cmd smi_cmd;
+	union cvmx_smix_rd_dat smi_rd;
+	unsigned int op = 1; /* MDIO_CLAUSE_22_READ */
+	int timeout = 1000;
+
+	if (regnum & MII_ADDR_C45) {
+		int r = cavium_mdiobus_c45_addr(p, phy_id, regnum);
+
+		if (r < 0)
+			return r;
+
+		regnum = (regnum >> 16) & 0x1f;
+		op = 3; /* MDIO_CLAUSE_45_READ */
+	} else {
+		cavium_mdiobus_set_mode(p, C22);
+	}
+
+	smi_cmd.u64 = 0;
+	smi_cmd.s.phy_op = op;
+	smi_cmd.s.phy_adr = phy_id;
+	smi_cmd.s.reg_adr = regnum;
+	oct_mdio_writeq(smi_cmd.u64, p->register_base + SMI_CMD);
+
+	do {
+		/* Wait 1000 clocks so we don't saturate the RSL bus
+		 * doing reads.
+		 */
+		__delay(1000);
+		smi_rd.u64 = oct_mdio_readq(p->register_base + SMI_RD_DAT);
+	} while (smi_rd.s.pending && --timeout);
+
+	if (smi_rd.s.val)
+		return smi_rd.s.dat;
+	else
+		return -EIO;
+}
+EXPORT_SYMBOL(cavium_mdiobus_read);
+
+int cavium_mdiobus_write(struct mii_bus *bus, int phy_id, int regnum, u16 val)
+{
+	struct cavium_mdiobus *p = bus->priv;
+	union cvmx_smix_cmd smi_cmd;
+	union cvmx_smix_wr_dat smi_wr;
+	unsigned int op = 0; /* MDIO_CLAUSE_22_WRITE */
+	int timeout = 1000;
+
+	if (regnum & MII_ADDR_C45) {
+		int r = cavium_mdiobus_c45_addr(p, phy_id, regnum);
+
+		if (r < 0)
+			return r;
+
+		regnum = (regnum >> 16) & 0x1f;
+		op = 1; /* MDIO_CLAUSE_45_WRITE */
+	} else {
+		cavium_mdiobus_set_mode(p, C22);
+	}
+
+	smi_wr.u64 = 0;
+	smi_wr.s.dat = val;
+	oct_mdio_writeq(smi_wr.u64, p->register_base + SMI_WR_DAT);
+
+	smi_cmd.u64 = 0;
+	smi_cmd.s.phy_op = op;
+	smi_cmd.s.phy_adr = phy_id;
+	smi_cmd.s.reg_adr = regnum;
+	oct_mdio_writeq(smi_cmd.u64, p->register_base + SMI_CMD);
+
+	do {
+		/* Wait 1000 clocks so we don't saturate the RSL bus
+		 * doing reads.
+		 */
+		__delay(1000);
+		smi_wr.u64 = oct_mdio_readq(p->register_base + SMI_WR_DAT);
+	} while (smi_wr.s.pending && --timeout);
+
+	if (timeout <= 0)
+		return -EIO;
+
+	return 0;
+}
+EXPORT_SYMBOL(cavium_mdiobus_write);
+
+MODULE_DESCRIPTION("Common code for OCTEON and Thunder MDIO bus drivers");
+MODULE_AUTHOR("David Daney");
+MODULE_LICENSE("GPL");
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/net/phy/mdio-cavium.h
@@ -0,0 +1,120 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2009-2016 Cavium, Inc.
+ */
+
+enum cavium_mdiobus_mode {
+	UNINIT = 0,
+	C22,
+	C45
+};
+
+#define SMI_CMD		0x0
+#define SMI_WR_DAT	0x8
+#define SMI_RD_DAT	0x10
+#define SMI_CLK		0x18
+#define SMI_EN		0x20
+
+#ifdef __BIG_ENDIAN_BITFIELD
+#define OCT_MDIO_BITFIELD_FIELD(field, more)	\
+	field;					\
+	more
+
+#else
+#define OCT_MDIO_BITFIELD_FIELD(field, more)	\
+	more					\
+	field;
+
+#endif
+
+union cvmx_smix_clk {
+	u64 u64;
+	struct cvmx_smix_clk_s {
+	  OCT_MDIO_BITFIELD_FIELD(u64 reserved_25_63:39,
+	  OCT_MDIO_BITFIELD_FIELD(u64 mode:1,
+	  OCT_MDIO_BITFIELD_FIELD(u64 reserved_21_23:3,
+	  OCT_MDIO_BITFIELD_FIELD(u64 sample_hi:5,
+	  OCT_MDIO_BITFIELD_FIELD(u64 sample_mode:1,
+	  OCT_MDIO_BITFIELD_FIELD(u64 reserved_14_14:1,
+	  OCT_MDIO_BITFIELD_FIELD(u64 clk_idle:1,
+	  OCT_MDIO_BITFIELD_FIELD(u64 preamble:1,
+	  OCT_MDIO_BITFIELD_FIELD(u64 sample:4,
+	  OCT_MDIO_BITFIELD_FIELD(u64 phase:8,
+	  ;))))))))))
+	} s;
+};
+
+union cvmx_smix_cmd {
+	u64 u64;
+	struct cvmx_smix_cmd_s {
+	  OCT_MDIO_BITFIELD_FIELD(u64 reserved_18_63:46,
+	  OCT_MDIO_BITFIELD_FIELD(u64 phy_op:2,
+	  OCT_MDIO_BITFIELD_FIELD(u64 reserved_13_15:3,
+	  OCT_MDIO_BITFIELD_FIELD(u64 phy_adr:5,
+	  OCT_MDIO_BITFIELD_FIELD(u64 reserved_5_7:3,
+	  OCT_MDIO_BITFIELD_FIELD(u64 reg_adr:5,
+	  ;))))))
+	} s;
+};
+
+union cvmx_smix_en {
+	u64 u64;
+	struct cvmx_smix_en_s {
+	  OCT_MDIO_BITFIELD_FIELD(u64 reserved_1_63:63,
+	  OCT_MDIO_BITFIELD_FIELD(u64 en:1,
+	  ;))
+	} s;
+};
+
+union cvmx_smix_rd_dat {
+	u64 u64;
+	struct cvmx_smix_rd_dat_s {
+	  OCT_MDIO_BITFIELD_FIELD(u64 reserved_18_63:46,
+	  OCT_MDIO_BITFIELD_FIELD(u64 pending:1,
+	  OCT_MDIO_BITFIELD_FIELD(u64 val:1,
+	  OCT_MDIO_BITFIELD_FIELD(u64 dat:16,
+	  ;))))
+	} s;
+};
+
+union cvmx_smix_wr_dat {
+	u64 u64;
+	struct cvmx_smix_wr_dat_s {
+	  OCT_MDIO_BITFIELD_FIELD(u64 reserved_18_63:46,
+	  OCT_MDIO_BITFIELD_FIELD(u64 pending:1,
+	  OCT_MDIO_BITFIELD_FIELD(u64 val:1,
+	  OCT_MDIO_BITFIELD_FIELD(u64 dat:16,
+	  ;))))
+	} s;
+};
+
+struct cavium_mdiobus {
+	struct mii_bus *mii_bus;
+	u64 register_base;
+	enum cavium_mdiobus_mode mode;
+	int phy_irq[PHY_MAX_ADDR];
+};
+
+#ifdef CONFIG_CAVIUM_OCTEON_SOC
+
+#include <asm/octeon/octeon.h>
+
+static inline void oct_mdio_writeq(u64 val, u64 addr)
+{
+	cvmx_write_csr(addr, val);
+}
+
+static inline u64 oct_mdio_readq(u64 addr)
+{
+	return cvmx_read_csr(addr);
+}
+#else
+#define oct_mdio_writeq(val, addr)	writeq(val, (void *)addr)
+#define oct_mdio_readq(addr)		readq((void *)addr)
+#endif
+
+int cavium_mdiobus_read(struct mii_bus *bus, int phy_id, int regnum);
+int cavium_mdiobus_write(struct mii_bus *bus, int phy_id, int regnum, u16 val);
--- zfcpdump-kernel-4.4.orig/drivers/net/phy/mdio-octeon.c
+++ zfcpdump-kernel-4.4/drivers/net/phy/mdio-octeon.c
@@ -3,272 +3,25 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 2009-2012 Cavium, Inc.
+ * Copyright (C) 2009-2015 Cavium, Inc.
  */
 
 #include <linux/platform_device.h>
 #include <linux/of_address.h>
 #include <linux/of_mdio.h>
-#include <linux/delay.h>
 #include <linux/module.h>
 #include <linux/gfp.h>
 #include <linux/phy.h>
 #include <linux/io.h>
 
-#ifdef CONFIG_CAVIUM_OCTEON_SOC
-#include <asm/octeon/octeon.h>
-#endif
-
-#define DRV_VERSION "1.1"
-#define DRV_DESCRIPTION "Cavium Networks Octeon/ThunderX SMI/MDIO driver"
-
-#define SMI_CMD		0x0
-#define SMI_WR_DAT	0x8
-#define SMI_RD_DAT	0x10
-#define SMI_CLK		0x18
-#define SMI_EN		0x20
-
-#ifdef __BIG_ENDIAN_BITFIELD
-#define OCT_MDIO_BITFIELD_FIELD(field, more)	\
-	field;					\
-	more
-
-#else
-#define OCT_MDIO_BITFIELD_FIELD(field, more)	\
-	more					\
-	field;
-
-#endif
-
-union cvmx_smix_clk {
-	u64 u64;
-	struct cvmx_smix_clk_s {
-	  OCT_MDIO_BITFIELD_FIELD(u64 reserved_25_63:39,
-	  OCT_MDIO_BITFIELD_FIELD(u64 mode:1,
-	  OCT_MDIO_BITFIELD_FIELD(u64 reserved_21_23:3,
-	  OCT_MDIO_BITFIELD_FIELD(u64 sample_hi:5,
-	  OCT_MDIO_BITFIELD_FIELD(u64 sample_mode:1,
-	  OCT_MDIO_BITFIELD_FIELD(u64 reserved_14_14:1,
-	  OCT_MDIO_BITFIELD_FIELD(u64 clk_idle:1,
-	  OCT_MDIO_BITFIELD_FIELD(u64 preamble:1,
-	  OCT_MDIO_BITFIELD_FIELD(u64 sample:4,
-	  OCT_MDIO_BITFIELD_FIELD(u64 phase:8,
-	  ;))))))))))
-	} s;
-};
-
-union cvmx_smix_cmd {
-	u64 u64;
-	struct cvmx_smix_cmd_s {
-	  OCT_MDIO_BITFIELD_FIELD(u64 reserved_18_63:46,
-	  OCT_MDIO_BITFIELD_FIELD(u64 phy_op:2,
-	  OCT_MDIO_BITFIELD_FIELD(u64 reserved_13_15:3,
-	  OCT_MDIO_BITFIELD_FIELD(u64 phy_adr:5,
-	  OCT_MDIO_BITFIELD_FIELD(u64 reserved_5_7:3,
-	  OCT_MDIO_BITFIELD_FIELD(u64 reg_adr:5,
-	  ;))))))
-	} s;
-};
-
-union cvmx_smix_en {
-	u64 u64;
-	struct cvmx_smix_en_s {
-	  OCT_MDIO_BITFIELD_FIELD(u64 reserved_1_63:63,
-	  OCT_MDIO_BITFIELD_FIELD(u64 en:1,
-	  ;))
-	} s;
-};
-
-union cvmx_smix_rd_dat {
-	u64 u64;
-	struct cvmx_smix_rd_dat_s {
-	  OCT_MDIO_BITFIELD_FIELD(u64 reserved_18_63:46,
-	  OCT_MDIO_BITFIELD_FIELD(u64 pending:1,
-	  OCT_MDIO_BITFIELD_FIELD(u64 val:1,
-	  OCT_MDIO_BITFIELD_FIELD(u64 dat:16,
-	  ;))))
-	} s;
-};
-
-union cvmx_smix_wr_dat {
-	u64 u64;
-	struct cvmx_smix_wr_dat_s {
-	  OCT_MDIO_BITFIELD_FIELD(u64 reserved_18_63:46,
-	  OCT_MDIO_BITFIELD_FIELD(u64 pending:1,
-	  OCT_MDIO_BITFIELD_FIELD(u64 val:1,
-	  OCT_MDIO_BITFIELD_FIELD(u64 dat:16,
-	  ;))))
-	} s;
-};
-
-enum octeon_mdiobus_mode {
-	UNINIT = 0,
-	C22,
-	C45
-};
-
-struct octeon_mdiobus {
-	struct mii_bus *mii_bus;
-	u64 register_base;
-	resource_size_t mdio_phys;
-	resource_size_t regsize;
-	enum octeon_mdiobus_mode mode;
-	int phy_irq[PHY_MAX_ADDR];
-};
-
-#ifdef CONFIG_CAVIUM_OCTEON_SOC
-static void oct_mdio_writeq(u64 val, u64 addr)
-{
-	cvmx_write_csr(addr, val);
-}
-
-static u64 oct_mdio_readq(u64 addr)
-{
-	return cvmx_read_csr(addr);
-}
-#else
-#define oct_mdio_writeq(val, addr)	writeq_relaxed(val, (void *)addr)
-#define oct_mdio_readq(addr)		readq_relaxed((void *)addr)
-#endif
-
-static void octeon_mdiobus_set_mode(struct octeon_mdiobus *p,
-				    enum octeon_mdiobus_mode m)
-{
-	union cvmx_smix_clk smi_clk;
-
-	if (m == p->mode)
-		return;
-
-	smi_clk.u64 = oct_mdio_readq(p->register_base + SMI_CLK);
-	smi_clk.s.mode = (m == C45) ? 1 : 0;
-	smi_clk.s.preamble = 1;
-	oct_mdio_writeq(smi_clk.u64, p->register_base + SMI_CLK);
-	p->mode = m;
-}
-
-static int octeon_mdiobus_c45_addr(struct octeon_mdiobus *p,
-				   int phy_id, int regnum)
-{
-	union cvmx_smix_cmd smi_cmd;
-	union cvmx_smix_wr_dat smi_wr;
-	int timeout = 1000;
-
-	octeon_mdiobus_set_mode(p, C45);
-
-	smi_wr.u64 = 0;
-	smi_wr.s.dat = regnum & 0xffff;
-	oct_mdio_writeq(smi_wr.u64, p->register_base + SMI_WR_DAT);
-
-	regnum = (regnum >> 16) & 0x1f;
-
-	smi_cmd.u64 = 0;
-	smi_cmd.s.phy_op = 0; /* MDIO_CLAUSE_45_ADDRESS */
-	smi_cmd.s.phy_adr = phy_id;
-	smi_cmd.s.reg_adr = regnum;
-	oct_mdio_writeq(smi_cmd.u64, p->register_base + SMI_CMD);
-
-	do {
-		/* Wait 1000 clocks so we don't saturate the RSL bus
-		 * doing reads.
-		 */
-		__delay(1000);
-		smi_wr.u64 = oct_mdio_readq(p->register_base + SMI_WR_DAT);
-	} while (smi_wr.s.pending && --timeout);
-
-	if (timeout <= 0)
-		return -EIO;
-	return 0;
-}
-
-static int octeon_mdiobus_read(struct mii_bus *bus, int phy_id, int regnum)
-{
-	struct octeon_mdiobus *p = bus->priv;
-	union cvmx_smix_cmd smi_cmd;
-	union cvmx_smix_rd_dat smi_rd;
-	unsigned int op = 1; /* MDIO_CLAUSE_22_READ */
-	int timeout = 1000;
-
-	if (regnum & MII_ADDR_C45) {
-		int r = octeon_mdiobus_c45_addr(p, phy_id, regnum);
-		if (r < 0)
-			return r;
-
-		regnum = (regnum >> 16) & 0x1f;
-		op = 3; /* MDIO_CLAUSE_45_READ */
-	} else {
-		octeon_mdiobus_set_mode(p, C22);
-	}
-
-
-	smi_cmd.u64 = 0;
-	smi_cmd.s.phy_op = op;
-	smi_cmd.s.phy_adr = phy_id;
-	smi_cmd.s.reg_adr = regnum;
-	oct_mdio_writeq(smi_cmd.u64, p->register_base + SMI_CMD);
-
-	do {
-		/* Wait 1000 clocks so we don't saturate the RSL bus
-		 * doing reads.
-		 */
-		__delay(1000);
-		smi_rd.u64 = oct_mdio_readq(p->register_base + SMI_RD_DAT);
-	} while (smi_rd.s.pending && --timeout);
-
-	if (smi_rd.s.val)
-		return smi_rd.s.dat;
-	else
-		return -EIO;
-}
-
-static int octeon_mdiobus_write(struct mii_bus *bus, int phy_id,
-				int regnum, u16 val)
-{
-	struct octeon_mdiobus *p = bus->priv;
-	union cvmx_smix_cmd smi_cmd;
-	union cvmx_smix_wr_dat smi_wr;
-	unsigned int op = 0; /* MDIO_CLAUSE_22_WRITE */
-	int timeout = 1000;
-
-
-	if (regnum & MII_ADDR_C45) {
-		int r = octeon_mdiobus_c45_addr(p, phy_id, regnum);
-		if (r < 0)
-			return r;
-
-		regnum = (regnum >> 16) & 0x1f;
-		op = 1; /* MDIO_CLAUSE_45_WRITE */
-	} else {
-		octeon_mdiobus_set_mode(p, C22);
-	}
-
-	smi_wr.u64 = 0;
-	smi_wr.s.dat = val;
-	oct_mdio_writeq(smi_wr.u64, p->register_base + SMI_WR_DAT);
-
-	smi_cmd.u64 = 0;
-	smi_cmd.s.phy_op = op;
-	smi_cmd.s.phy_adr = phy_id;
-	smi_cmd.s.reg_adr = regnum;
-	oct_mdio_writeq(smi_cmd.u64, p->register_base + SMI_CMD);
-
-	do {
-		/* Wait 1000 clocks so we don't saturate the RSL bus
-		 * doing reads.
-		 */
-		__delay(1000);
-		smi_wr.u64 = oct_mdio_readq(p->register_base + SMI_WR_DAT);
-	} while (smi_wr.s.pending && --timeout);
-
-	if (timeout <= 0)
-		return -EIO;
-
-	return 0;
-}
+#include "mdio-cavium.h"
 
 static int octeon_mdiobus_probe(struct platform_device *pdev)
 {
-	struct octeon_mdiobus *bus;
+	struct cavium_mdiobus *bus;
 	struct resource *res_mem;
+	resource_size_t mdio_phys;
+	resource_size_t regsize;
 	union cvmx_smix_en smi_en;
 	int err = -ENOENT;
 
@@ -282,17 +35,17 @@ static int octeon_mdiobus_probe(struct p
 		return -ENXIO;
 	}
 
-	bus->mdio_phys = res_mem->start;
-	bus->regsize = resource_size(res_mem);
+	mdio_phys = res_mem->start;
+	regsize = resource_size(res_mem);
 
-	if (!devm_request_mem_region(&pdev->dev, bus->mdio_phys, bus->regsize,
+	if (!devm_request_mem_region(&pdev->dev, mdio_phys, regsize,
 				     res_mem->name)) {
 		dev_err(&pdev->dev, "request_mem_region failed\n");
 		return -ENXIO;
 	}
 
 	bus->register_base =
-		(u64)devm_ioremap(&pdev->dev, bus->mdio_phys, bus->regsize);
+		(u64)devm_ioremap(&pdev->dev, mdio_phys, regsize);
 	if (!bus->register_base) {
 		dev_err(&pdev->dev, "dev_ioremap failed\n");
 		return -ENOMEM;
@@ -306,14 +59,13 @@ static int octeon_mdiobus_probe(struct p
 	smi_en.s.en = 1;
 	oct_mdio_writeq(smi_en.u64, bus->register_base + SMI_EN);
 
-	bus->mii_bus->priv = bus;
 	bus->mii_bus->irq = bus->phy_irq;
-	bus->mii_bus->name = "mdio-octeon";
+	bus->mii_bus->name = KBUILD_MODNAME;
 	snprintf(bus->mii_bus->id, MII_BUS_ID_SIZE, "%llx", bus->register_base);
 	bus->mii_bus->parent = &pdev->dev;
 
-	bus->mii_bus->read = octeon_mdiobus_read;
-	bus->mii_bus->write = octeon_mdiobus_write;
+	bus->mii_bus->read = cavium_mdiobus_read;
+	bus->mii_bus->write = cavium_mdiobus_write;
 
 	platform_set_drvdata(pdev, bus);
 
@@ -321,7 +73,7 @@ static int octeon_mdiobus_probe(struct p
 	if (err)
 		goto fail_register;
 
-	dev_info(&pdev->dev, "Version " DRV_VERSION "\n");
+	dev_info(&pdev->dev, "Probed\n");
 
 	return 0;
 fail_register:
@@ -334,7 +86,7 @@ fail:
 
 static int octeon_mdiobus_remove(struct platform_device *pdev)
 {
-	struct octeon_mdiobus *bus;
+	struct cavium_mdiobus *bus;
 	union cvmx_smix_en smi_en;
 
 	bus = platform_get_drvdata(pdev);
@@ -356,7 +108,7 @@ MODULE_DEVICE_TABLE(of, octeon_mdiobus_m
 
 static struct platform_driver octeon_mdiobus_driver = {
 	.driver = {
-		.name		= "mdio-octeon",
+		.name		= KBUILD_MODNAME,
 		.of_match_table = octeon_mdiobus_match,
 	},
 	.probe		= octeon_mdiobus_probe,
@@ -371,7 +123,6 @@ EXPORT_SYMBOL(octeon_mdiobus_force_mod_d
 
 module_platform_driver(octeon_mdiobus_driver);
 
-MODULE_DESCRIPTION(DRV_DESCRIPTION);
-MODULE_VERSION(DRV_VERSION);
+MODULE_DESCRIPTION("Cavium OCTEON MDIO bus driver");
 MODULE_AUTHOR("David Daney");
 MODULE_LICENSE("GPL");
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/net/phy/mdio-thunder.c
@@ -0,0 +1,154 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2009-2016 Cavium, Inc.
+ */
+
+#include <linux/of_address.h>
+#include <linux/of_mdio.h>
+#include <linux/module.h>
+#include <linux/gfp.h>
+#include <linux/phy.h>
+#include <linux/io.h>
+#include <linux/acpi.h>
+#include <linux/pci.h>
+
+#include "mdio-cavium.h"
+
+struct thunder_mdiobus_nexus {
+	void __iomem *bar0;
+	struct cavium_mdiobus *buses[4];
+};
+
+static int thunder_mdiobus_pci_probe(struct pci_dev *pdev,
+				     const struct pci_device_id *ent)
+{
+	struct device_node *node;
+	struct fwnode_handle *fwn;
+	struct thunder_mdiobus_nexus *nexus;
+	int err;
+	int i;
+
+	nexus = devm_kzalloc(&pdev->dev, sizeof(*nexus), GFP_KERNEL);
+	if (!nexus)
+		return -ENOMEM;
+
+	pci_set_drvdata(pdev, nexus);
+
+	err = pcim_enable_device(pdev);
+	if (err) {
+		dev_err(&pdev->dev, "Failed to enable PCI device\n");
+		pci_set_drvdata(pdev, NULL);
+		return err;
+	}
+
+	err = pci_request_regions(pdev, KBUILD_MODNAME);
+	if (err) {
+		dev_err(&pdev->dev, "pci_request_regions failed\n");
+		goto err_disable_device;
+	}
+
+	nexus->bar0 = pcim_iomap(pdev, 0, pci_resource_len(pdev, 0));
+	if (!nexus->bar0) {
+		err = -ENOMEM;
+		goto err_release_regions;
+	}
+
+	i = 0;
+	device_for_each_child_node(&pdev->dev, fwn) {
+		struct resource r;
+		struct mii_bus *mii_bus;
+		struct cavium_mdiobus *bus;
+		union cvmx_smix_en smi_en;
+
+		/* If it is not an OF node we cannot handle it yet, so
+		 * exit the loop.
+		 */
+		node = to_of_node(fwn);
+		if (!node)
+			break;
+
+		err = of_address_to_resource(node, 0, &r);
+		if (err) {
+			dev_err(&pdev->dev,
+				"Couldn't translate address for \"%s\"\n",
+				node->name);
+			break;
+		}
+
+		mii_bus = devm_mdiobus_alloc_size(&pdev->dev, sizeof(*bus));
+		if (!mii_bus)
+			break;
+		bus = mii_bus->priv;
+		bus->mii_bus = mii_bus;
+
+		nexus->buses[i] = bus;
+		i++;
+
+		bus->register_base = (u64)nexus->bar0 +
+			r.start - pci_resource_start(pdev, 0);
+
+		smi_en.u64 = 0;
+		smi_en.s.en = 1;
+		oct_mdio_writeq(smi_en.u64, bus->register_base + SMI_EN);
+		bus->mii_bus->name = KBUILD_MODNAME;
+		snprintf(bus->mii_bus->id, MII_BUS_ID_SIZE, "%llx", r.start);
+		bus->mii_bus->parent = &pdev->dev;
+		bus->mii_bus->read = cavium_mdiobus_read;
+		bus->mii_bus->write = cavium_mdiobus_write;
+
+		err = of_mdiobus_register(bus->mii_bus, node);
+		if (err)
+			dev_err(&pdev->dev, "of_mdiobus_register failed\n");
+
+		dev_info(&pdev->dev, "Added bus at %llx\n", r.start);
+		if (i >= ARRAY_SIZE(nexus->buses))
+			break;
+	}
+	return 0;
+
+err_release_regions:
+	pci_release_regions(pdev);
+
+err_disable_device:
+	pci_set_drvdata(pdev, NULL);
+	return err;
+}
+
+static void thunder_mdiobus_pci_remove(struct pci_dev *pdev)
+{
+	int i;
+	struct thunder_mdiobus_nexus *nexus = pci_get_drvdata(pdev);
+
+	for (i = 0; i < ARRAY_SIZE(nexus->buses); i++) {
+		struct cavium_mdiobus *bus = nexus->buses[i];
+
+		if (!bus)
+			continue;
+
+		mdiobus_unregister(bus->mii_bus);
+		mdiobus_free(bus->mii_bus);
+		oct_mdio_writeq(0, bus->register_base + SMI_EN);
+	}
+	pci_set_drvdata(pdev, NULL);
+}
+
+static const struct pci_device_id thunder_mdiobus_id_table[] = {
+	{ PCI_DEVICE(PCI_VENDOR_ID_CAVIUM, 0xa02b) },
+	{ 0, } /* End of table. */
+};
+MODULE_DEVICE_TABLE(pci, thunder_mdiobus_id_table);
+
+static struct pci_driver thunder_mdiobus_driver = {
+	.name = KBUILD_MODNAME,
+	.id_table = thunder_mdiobus_id_table,
+	.probe = thunder_mdiobus_pci_probe,
+	.remove = thunder_mdiobus_pci_remove,
+};
+
+module_pci_driver(thunder_mdiobus_driver);
+
+MODULE_DESCRIPTION("Cavium ThunderX MDIO bus driver");
+MODULE_LICENSE("GPL");
--- zfcpdump-kernel-4.4.orig/drivers/net/phy/phy.c
+++ zfcpdump-kernel-4.4/drivers/net/phy/phy.c
@@ -640,8 +640,10 @@ phy_err:
 int phy_start_interrupts(struct phy_device *phydev)
 {
 	atomic_set(&phydev->irq_disable, 0);
-	if (request_irq(phydev->irq, phy_interrupt, 0, "phy_interrupt",
-			phydev) < 0) {
+	if (request_irq(phydev->irq, phy_interrupt,
+				IRQF_SHARED,
+				"phy_interrupt",
+				phydev) < 0) {
 		pr_warn("%s: Can't get IRQ %d (PHY)\n",
 			phydev->bus->name, phydev->irq);
 		phydev->irq = PHY_POLL;
--- zfcpdump-kernel-4.4.orig/drivers/net/phy/vitesse.c
+++ zfcpdump-kernel-4.4/drivers/net/phy/vitesse.c
@@ -75,7 +75,7 @@ MODULE_DESCRIPTION("Vitesse PHY driver")
 MODULE_AUTHOR("Kriston Carson");
 MODULE_LICENSE("GPL");
 
-static int vsc824x_add_skew(struct phy_device *phydev)
+int vsc824x_add_skew(struct phy_device *phydev)
 {
 	int err;
 	int extcon;
@@ -95,6 +95,7 @@ static int vsc824x_add_skew(struct phy_d
 
 	return err;
 }
+EXPORT_SYMBOL(vsc824x_add_skew);
 
 static int vsc824x_config_init(struct phy_device *phydev)
 {
--- zfcpdump-kernel-4.4.orig/drivers/net/ppp/ppp_generic.c
+++ zfcpdump-kernel-4.4/drivers/net/ppp/ppp_generic.c
@@ -567,7 +567,7 @@ static int get_filter(void __user *arg,
 
 static long ppp_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 {
-	struct ppp_file *pf = file->private_data;
+	struct ppp_file *pf;
 	struct ppp *ppp;
 	int err = -EFAULT, val, val2, i;
 	struct ppp_idle idle;
@@ -577,9 +577,14 @@ static long ppp_ioctl(struct file *file,
 	void __user *argp = (void __user *)arg;
 	int __user *p = argp;
 
-	if (!pf)
-		return ppp_unattached_ioctl(current->nsproxy->net_ns,
-					pf, file, cmd, arg);
+	mutex_lock(&ppp_mutex);
+
+	pf = file->private_data;
+	if (!pf) {
+		err = ppp_unattached_ioctl(current->nsproxy->net_ns,
+					   pf, file, cmd, arg);
+		goto out;
+	}
 
 	if (cmd == PPPIOCDETACH) {
 		/*
@@ -594,7 +599,6 @@ static long ppp_ioctl(struct file *file,
 		 * this fd and reopening /dev/ppp.
 		 */
 		err = -EINVAL;
-		mutex_lock(&ppp_mutex);
 		if (pf->kind == INTERFACE) {
 			ppp = PF_TO_PPP(pf);
 			rtnl_lock();
@@ -608,15 +612,13 @@ static long ppp_ioctl(struct file *file,
 		} else
 			pr_warn("PPPIOCDETACH file->f_count=%ld\n",
 				atomic_long_read(&file->f_count));
-		mutex_unlock(&ppp_mutex);
-		return err;
+		goto out;
 	}
 
 	if (pf->kind == CHANNEL) {
 		struct channel *pch;
 		struct ppp_channel *chan;
 
-		mutex_lock(&ppp_mutex);
 		pch = PF_TO_CHANNEL(pf);
 
 		switch (cmd) {
@@ -638,17 +640,16 @@ static long ppp_ioctl(struct file *file,
 				err = chan->ops->ioctl(chan, cmd, arg);
 			up_read(&pch->chan_sem);
 		}
-		mutex_unlock(&ppp_mutex);
-		return err;
+		goto out;
 	}
 
 	if (pf->kind != INTERFACE) {
 		/* can't happen */
 		pr_err("PPP: not interface or channel??\n");
-		return -EINVAL;
+		err = -EINVAL;
+		goto out;
 	}
 
-	mutex_lock(&ppp_mutex);
 	ppp = PF_TO_PPP(pf);
 	switch (cmd) {
 	case PPPIOCSMRU:
@@ -823,7 +824,10 @@ static long ppp_ioctl(struct file *file,
 	default:
 		err = -ENOTTY;
 	}
+
+out:
 	mutex_unlock(&ppp_mutex);
+
 	return err;
 }
 
@@ -836,7 +840,6 @@ static int ppp_unattached_ioctl(struct n
 	struct ppp_net *pn;
 	int __user *p = (int __user *)arg;
 
-	mutex_lock(&ppp_mutex);
 	switch (cmd) {
 	case PPPIOCNEWUNIT:
 		/* Create a new ppp unit */
@@ -886,7 +889,7 @@ static int ppp_unattached_ioctl(struct n
 	default:
 		err = -ENOTTY;
 	}
-	mutex_unlock(&ppp_mutex);
+
 	return err;
 }
 
@@ -2290,7 +2293,7 @@ int ppp_register_net_channel(struct net
 
 	pch->ppp = NULL;
 	pch->chan = chan;
-	pch->chan_net = net;
+	pch->chan_net = get_net(net);
 	chan->ppp = pch;
 	init_ppp_file(&pch->file, CHANNEL);
 	pch->file.hdrlen = chan->hdrlen;
@@ -2387,6 +2390,8 @@ ppp_unregister_channel(struct ppp_channe
 	spin_lock_bh(&pn->all_channels_lock);
 	list_del(&pch->list);
 	spin_unlock_bh(&pn->all_channels_lock);
+	put_net(pch->chan_net);
+	pch->chan_net = NULL;
 
 	pch->file.dead = 1;
 	wake_up_interruptible(&pch->file.rwait);
@@ -2803,6 +2808,7 @@ static struct ppp *ppp_create_interface(
 
 out2:
 	mutex_unlock(&pn->all_ppp_mutex);
+	rtnl_unlock();
 	free_netdev(dev);
 out1:
 	*retp = ret;
--- zfcpdump-kernel-4.4.orig/drivers/net/ppp/pppoe.c
+++ zfcpdump-kernel-4.4/drivers/net/ppp/pppoe.c
@@ -395,6 +395,8 @@ static int pppoe_rcv_core(struct sock *s
 
 		if (!__pppoe_xmit(sk_pppox(relay_po), skb))
 			goto abort_put;
+
+		sock_put(sk_pppox(relay_po));
 	} else {
 		if (sock_queue_rcv_skb(sk, skb))
 			goto abort_kfree;
--- zfcpdump-kernel-4.4.orig/drivers/net/ppp/pptp.c
+++ zfcpdump-kernel-4.4/drivers/net/ppp/pptp.c
@@ -129,24 +129,27 @@ static int lookup_chan_dst(u16 call_id,
 	return i < MAX_CALLID;
 }
 
-static int add_chan(struct pppox_sock *sock)
+static int add_chan(struct pppox_sock *sock,
+		    struct pptp_addr *sa)
 {
 	static int call_id;
 
 	spin_lock(&chan_lock);
-	if (!sock->proto.pptp.src_addr.call_id)	{
+	if (!sa->call_id)	{
 		call_id = find_next_zero_bit(callid_bitmap, MAX_CALLID, call_id + 1);
 		if (call_id == MAX_CALLID) {
 			call_id = find_next_zero_bit(callid_bitmap, MAX_CALLID, 1);
 			if (call_id == MAX_CALLID)
 				goto out_err;
 		}
-		sock->proto.pptp.src_addr.call_id = call_id;
-	} else if (test_bit(sock->proto.pptp.src_addr.call_id, callid_bitmap))
+		sa->call_id = call_id;
+	} else if (test_bit(sa->call_id, callid_bitmap)) {
 		goto out_err;
+	}
 
-	set_bit(sock->proto.pptp.src_addr.call_id, callid_bitmap);
-	rcu_assign_pointer(callid_sock[sock->proto.pptp.src_addr.call_id], sock);
+	sock->proto.pptp.src_addr = *sa;
+	set_bit(sa->call_id, callid_bitmap);
+	rcu_assign_pointer(callid_sock[sa->call_id], sock);
 	spin_unlock(&chan_lock);
 
 	return 0;
@@ -416,7 +419,6 @@ static int pptp_bind(struct socket *sock
 	struct sock *sk = sock->sk;
 	struct sockaddr_pppox *sp = (struct sockaddr_pppox *) uservaddr;
 	struct pppox_sock *po = pppox_sk(sk);
-	struct pptp_opt *opt = &po->proto.pptp;
 	int error = 0;
 
 	if (sockaddr_len < sizeof(struct sockaddr_pppox))
@@ -424,10 +426,22 @@ static int pptp_bind(struct socket *sock
 
 	lock_sock(sk);
 
-	opt->src_addr = sp->sa_addr.pptp;
-	if (add_chan(po))
+	if (sk->sk_state & PPPOX_DEAD) {
+		error = -EALREADY;
+		goto out;
+	}
+
+	if (sk->sk_state & PPPOX_BOUND) {
 		error = -EBUSY;
+		goto out;
+	}
+
+	if (add_chan(po, &sp->sa_addr.pptp))
+		error = -EBUSY;
+	else
+		sk->sk_state |= PPPOX_BOUND;
 
+out:
 	release_sock(sk);
 	return error;
 }
@@ -498,7 +512,7 @@ static int pptp_connect(struct socket *s
 	}
 
 	opt->dst_addr = sp->sa_addr.pptp;
-	sk->sk_state = PPPOX_CONNECTED;
+	sk->sk_state |= PPPOX_CONNECTED;
 
  end:
 	release_sock(sk);
--- zfcpdump-kernel-4.4.orig/drivers/net/rionet.c
+++ zfcpdump-kernel-4.4/drivers/net/rionet.c
@@ -280,7 +280,7 @@ static void rionet_outb_msg_event(struct
 	struct net_device *ndev = dev_id;
 	struct rionet_private *rnet = netdev_priv(ndev);
 
-	spin_lock(&rnet->lock);
+	spin_lock(&rnet->tx_lock);
 
 	if (netif_msg_intr(rnet))
 		printk(KERN_INFO
@@ -299,7 +299,7 @@ static void rionet_outb_msg_event(struct
 	if (rnet->tx_cnt < RIONET_TX_RING_SIZE)
 		netif_wake_queue(ndev);
 
-	spin_unlock(&rnet->lock);
+	spin_unlock(&rnet->tx_lock);
 }
 
 static int rionet_open(struct net_device *ndev)
--- zfcpdump-kernel-4.4.orig/drivers/net/team/team.c
+++ zfcpdump-kernel-4.4/drivers/net/team/team.c
@@ -969,7 +969,7 @@ static void team_port_disable(struct tea
 			    NETIF_F_FRAGLIST | NETIF_F_ALL_TSO | \
 			    NETIF_F_HIGHDMA | NETIF_F_LRO)
 
-static void __team_compute_features(struct team *team)
+static void ___team_compute_features(struct team *team)
 {
 	struct team_port *port;
 	u32 vlan_features = TEAM_VLAN_FEATURES & NETIF_F_ALL_FOR_ALL;
@@ -993,15 +993,20 @@ static void __team_compute_features(stru
 	team->dev->priv_flags &= ~IFF_XMIT_DST_RELEASE;
 	if (dst_release_flag == (IFF_XMIT_DST_RELEASE | IFF_XMIT_DST_RELEASE_PERM))
 		team->dev->priv_flags |= IFF_XMIT_DST_RELEASE;
+}
 
+static void __team_compute_features(struct team *team)
+{
+	___team_compute_features(team);
 	netdev_change_features(team->dev);
 }
 
 static void team_compute_features(struct team *team)
 {
 	mutex_lock(&team->lock);
-	__team_compute_features(team);
+	___team_compute_features(team);
 	mutex_unlock(&team->lock);
+	netdev_change_features(team->dev);
 }
 
 static int team_port_enter(struct team *team, struct team_port *port)
@@ -1845,10 +1850,10 @@ static int team_vlan_rx_kill_vid(struct
 	struct team *team = netdev_priv(dev);
 	struct team_port *port;
 
-	rcu_read_lock();
-	list_for_each_entry_rcu(port, &team->port_list, list)
+	mutex_lock(&team->lock);
+	list_for_each_entry(port, &team->port_list, list)
 		vlan_vid_del(port->dev, proto, vid);
-	rcu_read_unlock();
+	mutex_unlock(&team->lock);
 
 	return 0;
 }
@@ -2054,6 +2059,7 @@ static void team_setup(struct net_device
 	dev->flags |= IFF_MULTICAST;
 	dev->priv_flags &= ~(IFF_XMIT_DST_RELEASE | IFF_TX_SKB_SHARING);
 	dev->priv_flags |= IFF_NO_QUEUE;
+	dev->priv_flags |= IFF_TEAM;
 
 	/*
 	 * Indicate we support unicast address filtering. That way core won't
--- zfcpdump-kernel-4.4.orig/drivers/net/tun.c
+++ zfcpdump-kernel-4.4/drivers/net/tun.c
@@ -567,11 +567,13 @@ static void tun_detach_all(struct net_de
 	for (i = 0; i < n; i++) {
 		tfile = rtnl_dereference(tun->tfiles[i]);
 		BUG_ON(!tfile);
+		tfile->socket.sk->sk_shutdown = RCV_SHUTDOWN;
 		tfile->socket.sk->sk_data_ready(tfile->socket.sk);
 		RCU_INIT_POINTER(tfile->tun, NULL);
 		--tun->numqueues;
 	}
 	list_for_each_entry(tfile, &tun->disabled, next) {
+		tfile->socket.sk->sk_shutdown = RCV_SHUTDOWN;
 		tfile->socket.sk->sk_data_ready(tfile->socket.sk);
 		RCU_INIT_POINTER(tfile->tun, NULL);
 	}
@@ -621,11 +623,13 @@ static int tun_attach(struct tun_struct
 
 	/* Re-attach the filter to persist device */
 	if (!skip_filter && (tun->filter_attached == true)) {
-		err = sk_attach_filter(&tun->fprog, tfile->socket.sk);
+		err = __sk_attach_filter(&tun->fprog, tfile->socket.sk,
+					 lockdep_rtnl_is_held());
 		if (!err)
 			goto out;
 	}
 	tfile->queue_index = tun->numqueues;
+	tfile->socket.sk->sk_shutdown &= ~RCV_SHUTDOWN;
 	rcu_assign_pointer(tfile->tun, tun);
 	rcu_assign_pointer(tun->tfiles[tun->numqueues], tfile);
 	tun->numqueues++;
@@ -1000,7 +1004,6 @@ static void tun_net_init(struct net_devi
 		/* Zero header length */
 		dev->type = ARPHRD_NONE;
 		dev->flags = IFF_POINTOPOINT | IFF_NOARP | IFF_MULTICAST;
-		dev->tx_queue_len = TUN_READQ_SIZE;  /* We prefer our own queue length */
 		break;
 
 	case IFF_TAP:
@@ -1012,7 +1015,6 @@ static void tun_net_init(struct net_devi
 
 		eth_hw_addr_random(dev);
 
-		dev->tx_queue_len = TUN_READQ_SIZE;  /* We prefer our own queue length */
 		break;
 	}
 }
@@ -1409,9 +1411,6 @@ static ssize_t tun_do_read(struct tun_st
 	if (!iov_iter_count(to))
 		return 0;
 
-	if (tun->dev->reg_state != NETREG_REGISTERED)
-		return -EIO;
-
 	/* Read frames from queue */
 	skb = __skb_recv_datagram(tfile->socket.sk, noblock ? MSG_DONTWAIT : 0,
 				  &peeked, &off, &err);
@@ -1463,6 +1462,8 @@ static void tun_setup(struct net_device
 
 	dev->ethtool_ops = &tun_ethtool_ops;
 	dev->destructor = tun_free_netdev;
+	/* We prefer our own queue length */
+	dev->tx_queue_len = TUN_READQ_SIZE;
 }
 
 /* Trivial set of netlink ops to allow deleting tun or tap
@@ -1804,7 +1805,7 @@ static void tun_detach_filter(struct tun
 
 	for (i = 0; i < n; i++) {
 		tfile = rtnl_dereference(tun->tfiles[i]);
-		sk_detach_filter(tfile->socket.sk);
+		__sk_detach_filter(tfile->socket.sk, lockdep_rtnl_is_held());
 	}
 
 	tun->filter_attached = false;
@@ -1817,7 +1818,8 @@ static int tun_attach_filter(struct tun_
 
 	for (i = 0; i < tun->numqueues; i++) {
 		tfile = rtnl_dereference(tun->tfiles[i]);
-		ret = sk_attach_filter(&tun->fprog, tfile->socket.sk);
+		ret = __sk_attach_filter(&tun->fprog, tfile->socket.sk,
+					 lockdep_rtnl_is_held());
 		if (ret) {
 			tun_detach_filter(tun, i);
 			return ret;
--- zfcpdump-kernel-4.4.orig/drivers/net/usb/asix_common.c
+++ zfcpdump-kernel-4.4/drivers/net/usb/asix_common.c
@@ -66,7 +66,7 @@ int asix_rx_fixup_internal(struct usbnet
 	 * buffer.
 	 */
 	if (rx->remaining && (rx->remaining + sizeof(u32) <= skb->len)) {
-		offset = ((rx->remaining + 1) & 0xfffe) + sizeof(u32);
+		offset = ((rx->remaining + 1) & 0xfffe);
 		rx->header = get_unaligned_le32(skb->data + offset);
 		offset = 0;
 
--- zfcpdump-kernel-4.4.orig/drivers/net/usb/cdc_ether.c
+++ zfcpdump-kernel-4.4/drivers/net/usb/cdc_ether.c
@@ -160,6 +160,12 @@ int usbnet_generic_cdc_bind(struct usbne
 	info->u = header.usb_cdc_union_desc;
 	info->header = header.usb_cdc_header_desc;
 	info->ether = header.usb_cdc_ether_desc;
+	if (!info->u) {
+		if (rndis)
+			goto skip;
+		else /* in that case a quirk is mandatory */
+			goto bad_desc;
+	}
 	/* we need a master/control interface (what we're
 	 * probed with) and a slave/data interface; union
 	 * descriptors sort this all out.
@@ -256,7 +262,7 @@ skip:
 			goto bad_desc;
 		}
 
-	} else if (!info->header || !info->u || (!rndis && !info->ether)) {
+	} else if (!info->header || (!rndis && !info->ether)) {
 		dev_dbg(&intf->dev, "missing cdc %s%s%sdescriptor\n",
 			info->header ? "" : "header ",
 			info->u ? "" : "union ",
--- zfcpdump-kernel-4.4.orig/drivers/net/usb/cdc_mbim.c
+++ zfcpdump-kernel-4.4/drivers/net/usb/cdc_mbim.c
@@ -617,8 +617,13 @@ static const struct usb_device_id mbim_d
 	{ USB_VENDOR_AND_INTERFACE_INFO(0x0bdb, USB_CLASS_COMM, USB_CDC_SUBCLASS_MBIM, USB_CDC_PROTO_NONE),
 	  .driver_info = (unsigned long)&cdc_mbim_info,
 	},
-	/* Huawei E3372 fails unless NDP comes after the IP packets */
-	{ USB_DEVICE_AND_INTERFACE_INFO(0x12d1, 0x157d, USB_CLASS_COMM, USB_CDC_SUBCLASS_MBIM, USB_CDC_PROTO_NONE),
+
+	/* Some Huawei devices, ME906s-158 (12d1:15c1) and E3372
+	 * (12d1:157d), are known to fail unless the NDP is placed
+	 * after the IP packets.  Applying the quirk to all Huawei
+	 * devices is broader than necessary, but harmless.
+	 */
+	{ USB_VENDOR_AND_INTERFACE_INFO(0x12d1, USB_CLASS_COMM, USB_CDC_SUBCLASS_MBIM, USB_CDC_PROTO_NONE),
 	  .driver_info = (unsigned long)&cdc_mbim_info_ndp_to_end,
 	},
 	/* default entry */
--- zfcpdump-kernel-4.4.orig/drivers/net/usb/cdc_ncm.c
+++ zfcpdump-kernel-4.4/drivers/net/usb/cdc_ncm.c
@@ -794,7 +794,11 @@ int cdc_ncm_bind_common(struct usbnet *d
 
 	iface_no = ctx->data->cur_altsetting->desc.bInterfaceNumber;
 
-	/* reset data interface */
+	/* Reset data interface. Some devices will not reset properly
+	 * unless they are configured first.  Toggle the altsetting to
+	 * force a reset
+	 */
+	usb_set_interface(dev->udev, iface_no, data_altsetting);
 	temp = usb_set_interface(dev->udev, iface_no, 0);
 	if (temp) {
 		dev_dbg(&intf->dev, "set interface failed\n");
@@ -805,6 +809,13 @@ int cdc_ncm_bind_common(struct usbnet *d
 	if (cdc_ncm_init(dev))
 		goto error2;
 
+	/* Some firmwares need a pause here or they will silently fail
+	 * to set up the interface properly.  This value was decided
+	 * empirically on a Sierra Wireless MC7455 running 02.08.02.00
+	 * firmware.
+	 */
+	usleep_range(10000, 20000);
+
 	/* configure data interface */
 	temp = usb_set_interface(dev->udev, iface_no, data_altsetting);
 	if (temp) {
@@ -941,8 +952,6 @@ EXPORT_SYMBOL_GPL(cdc_ncm_select_altsett
 
 static int cdc_ncm_bind(struct usbnet *dev, struct usb_interface *intf)
 {
-	int ret;
-
 	/* MBIM backwards compatible function? */
 	if (cdc_ncm_select_altsetting(intf) != CDC_NCM_COMM_ALTSETTING_NCM)
 		return -ENODEV;
@@ -951,16 +960,7 @@ static int cdc_ncm_bind(struct usbnet *d
 	 * Additionally, generic NCM devices are assumed to accept arbitrarily
 	 * placed NDP.
 	 */
-	ret = cdc_ncm_bind_common(dev, intf, CDC_NCM_DATA_ALTSETTING_NCM, 0);
-
-	/*
-	 * We should get an event when network connection is "connected" or
-	 * "disconnected". Set network connection in "disconnected" state
-	 * (carrier is OFF) during attach, so the IP network stack does not
-	 * start IPv6 negotiation and more.
-	 */
-	usbnet_link_change(dev, 0, 0);
-	return ret;
+	return cdc_ncm_bind_common(dev, intf, CDC_NCM_DATA_ALTSETTING_NCM, 0);
 }
 
 static void cdc_ncm_align_tail(struct sk_buff *skb, size_t modulus, size_t remainder, size_t max)
@@ -1543,7 +1543,8 @@ static void cdc_ncm_status(struct usbnet
 
 static const struct driver_info cdc_ncm_info = {
 	.description = "CDC NCM",
-	.flags = FLAG_POINTTOPOINT | FLAG_NO_SETINT | FLAG_MULTI_PACKET,
+	.flags = FLAG_POINTTOPOINT | FLAG_NO_SETINT | FLAG_MULTI_PACKET
+			| FLAG_LINK_INTR,
 	.bind = cdc_ncm_bind,
 	.unbind = cdc_ncm_unbind,
 	.manage_power = usbnet_manage_power,
@@ -1556,7 +1557,7 @@ static const struct driver_info cdc_ncm_
 static const struct driver_info wwan_info = {
 	.description = "Mobile Broadband Network Device",
 	.flags = FLAG_POINTTOPOINT | FLAG_NO_SETINT | FLAG_MULTI_PACKET
-			| FLAG_WWAN,
+			| FLAG_LINK_INTR | FLAG_WWAN,
 	.bind = cdc_ncm_bind,
 	.unbind = cdc_ncm_unbind,
 	.manage_power = usbnet_manage_power,
@@ -1569,7 +1570,7 @@ static const struct driver_info wwan_inf
 static const struct driver_info wwan_noarp_info = {
 	.description = "Mobile Broadband Network Device (NO ARP)",
 	.flags = FLAG_POINTTOPOINT | FLAG_NO_SETINT | FLAG_MULTI_PACKET
-			| FLAG_WWAN | FLAG_NOARP,
+			| FLAG_LINK_INTR | FLAG_WWAN | FLAG_NOARP,
 	.bind = cdc_ncm_bind,
 	.unbind = cdc_ncm_unbind,
 	.manage_power = usbnet_manage_power,
--- zfcpdump-kernel-4.4.orig/drivers/net/usb/qmi_wwan.c
+++ zfcpdump-kernel-4.4/drivers/net/usb/qmi_wwan.c
@@ -492,6 +492,7 @@ static const struct usb_device_id produc
 
 	/* 3. Combined interface devices matching on interface number */
 	{QMI_FIXED_INTF(0x0408, 0xea42, 4)},	/* Yota / Megafon M100-1 */
+	{QMI_FIXED_INTF(0x05c6, 0x6001, 3)},	/* 4G LTE usb-modem U901 */
 	{QMI_FIXED_INTF(0x05c6, 0x7000, 0)},
 	{QMI_FIXED_INTF(0x05c6, 0x7001, 1)},
 	{QMI_FIXED_INTF(0x05c6, 0x7002, 1)},
@@ -698,6 +699,7 @@ static const struct usb_device_id produc
 	{QMI_FIXED_INTF(0x19d2, 0x1426, 2)},	/* ZTE MF91 */
 	{QMI_FIXED_INTF(0x19d2, 0x1428, 2)},	/* Telewell TW-LTE 4G v2 */
 	{QMI_FIXED_INTF(0x19d2, 0x2002, 4)},	/* ZTE (Vodafone) K3765-Z */
+	{QMI_FIXED_INTF(0x2001, 0x7e19, 4)},	/* D-Link DWM-221 B1 */
 	{QMI_FIXED_INTF(0x0f3d, 0x68a2, 8)},    /* Sierra Wireless MC7700 */
 	{QMI_FIXED_INTF(0x114f, 0x68a2, 8)},    /* Sierra Wireless MC7750 */
 	{QMI_FIXED_INTF(0x1199, 0x68a2, 8)},	/* Sierra Wireless MC7710 in QMI mode */
@@ -717,8 +719,10 @@ static const struct usb_device_id produc
 	{QMI_FIXED_INTF(0x1199, 0x9061, 8)},	/* Sierra Wireless Modem */
 	{QMI_FIXED_INTF(0x1199, 0x9070, 8)},	/* Sierra Wireless MC74xx/EM74xx */
 	{QMI_FIXED_INTF(0x1199, 0x9070, 10)},	/* Sierra Wireless MC74xx/EM74xx */
-	{QMI_FIXED_INTF(0x1199, 0x9071, 8)},	/* Sierra Wireless MC74xx/EM74xx */
-	{QMI_FIXED_INTF(0x1199, 0x9071, 10)},	/* Sierra Wireless MC74xx/EM74xx */
+	{QMI_FIXED_INTF(0x1199, 0x9071, 8)},	/* Sierra Wireless MC74xx */
+	{QMI_FIXED_INTF(0x1199, 0x9071, 10)},	/* Sierra Wireless MC74xx */
+	{QMI_FIXED_INTF(0x1199, 0x9079, 8)},	/* Sierra Wireless EM74xx */
+	{QMI_FIXED_INTF(0x1199, 0x9079, 10)},	/* Sierra Wireless EM74xx */
 	{QMI_FIXED_INTF(0x1bbb, 0x011e, 4)},	/* Telekom Speedstick LTE II (Alcatel One Touch L100V LTE) */
 	{QMI_FIXED_INTF(0x1bbb, 0x0203, 2)},	/* Alcatel L800MA */
 	{QMI_FIXED_INTF(0x2357, 0x0201, 4)},	/* TP-LINK HSUPA Modem MA180 */
--- zfcpdump-kernel-4.4.orig/drivers/net/usb/r8152.c
+++ zfcpdump-kernel-4.4/drivers/net/usb/r8152.c
@@ -25,6 +25,8 @@
 #include <uapi/linux/mdio.h>
 #include <linux/mdio.h>
 #include <linux/usb/cdc.h>
+#include <linux/suspend.h>
+#include <linux/acpi.h>
 
 /* Information for net-next */
 #define NETNEXT_VERSION		"08"
@@ -454,6 +456,11 @@
 /* SRAM_IMPEDANCE */
 #define RX_DRIVING_MASK		0x6000
 
+/* MAC PASSTHRU */
+#define AD_MASK			0xfee0
+#define EFUSE			0xcfdb
+#define PASS_THRU_MASK		0x1
+
 enum rtl_register_content {
 	_1000bps	= 0x10,
 	_100bps		= 0x08,
@@ -1026,6 +1033,65 @@ out1:
 	return ret;
 }
 
+/* Devices containing RTL8153-AD can support a persistent
+ * host system provided MAC address.
+ * Examples of this are Dell TB15 and Dell WD15 docks
+ */
+static int vendor_mac_passthru_addr_read(struct r8152 *tp, struct sockaddr *sa)
+{
+	acpi_status status;
+	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
+	union acpi_object *obj;
+	int ret = -EINVAL;
+	u32 ocp_data;
+	unsigned char buf[6];
+
+	/* test for -AD variant of RTL8153 */
+	ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_MISC_0);
+	if ((ocp_data & AD_MASK) != 0x1000)
+		return -ENODEV;
+
+	/* test for MAC address pass-through bit */
+	ocp_data = ocp_read_byte(tp, MCU_TYPE_USB, EFUSE);
+	if ((ocp_data & PASS_THRU_MASK) != 1)
+		return -ENODEV;
+
+	/* returns _AUXMAC_#AABBCCDDEEFF# */
+	status = acpi_evaluate_object(NULL, "\\_SB.AMAC", NULL, &buffer);
+	obj = (union acpi_object *)buffer.pointer;
+	if (!ACPI_SUCCESS(status))
+		return -ENODEV;
+	if (obj->type != ACPI_TYPE_BUFFER || obj->string.length != 0x17) {
+		netif_warn(tp, probe, tp->netdev,
+			   "Invalid buffer when reading pass-thru MAC addr: "
+			   "(%d, %d)\n",
+			   obj->type, obj->string.length);
+		goto amacout;
+	}
+	if (strncmp(obj->string.pointer, "_AUXMAC_#", 9) != 0 ||
+	    strncmp(obj->string.pointer + 0x15, "#", 1) != 0) {
+		netif_warn(tp, probe, tp->netdev,
+			   "Invalid header when reading pass-thru MAC addr\n");
+		goto amacout;
+	}
+	ret = hex2bin(buf, obj->string.pointer + 9, 6);
+	if (!(ret == 0 && is_valid_ether_addr(buf))) {
+		netif_warn(tp, probe, tp->netdev,
+			   "Invalid MAC when reading pass-thru MAC addr: "
+			   "%d, %pM\n", ret, buf);
+		ret = -EINVAL;
+		goto amacout;
+	}
+	memcpy(sa->sa_data, buf, 6);
+	ether_addr_copy(tp->netdev->dev_addr, sa->sa_data);
+	netif_info(tp, probe, tp->netdev,
+		   "Using pass-thru MAC addr %pM\n", sa->sa_data);
+
+amacout:
+	kfree(obj);
+	return ret;
+}
+
 static int set_ethernet_addr(struct r8152 *tp)
 {
 	struct net_device *dev = tp->netdev;
@@ -1034,8 +1100,15 @@ static int set_ethernet_addr(struct r815
 
 	if (tp->version == RTL_VER_01)
 		ret = pla_ocp_read(tp, PLA_IDR, 8, sa.sa_data);
-	else
-		ret = pla_ocp_read(tp, PLA_BACKUP, 8, sa.sa_data);
+	else {
+		/* if this is not an RTL8153-AD, no eFuse mac pass thru set,
+		 * or system doesn't provide valid _SB.AMAC this will be
+		 * be expected to non-zero
+		 */
+		ret = vendor_mac_passthru_addr_read(tp, &sa);
+		if (ret < 0)
+			ret = pla_ocp_read(tp, PLA_BACKUP, 8, sa.sa_data);
+	}
 
 	if (ret < 0) {
 		netif_err(tp, probe, dev, "Get ether addr fail\n");
--- zfcpdump-kernel-4.4.orig/drivers/net/usb/usbnet.c
+++ zfcpdump-kernel-4.4/drivers/net/usb/usbnet.c
@@ -1766,6 +1766,13 @@ out3:
 	if (info->unbind)
 		info->unbind (dev, udev);
 out1:
+	/* subdrivers must undo all they did in bind() if they
+	 * fail it, but we may fail later and a deferred kevent
+	 * may trigger an error resubmitting itself and, worse,
+	 * schedule a timer. So we kill it all just in case.
+	 */
+	cancel_work_sync(&dev->kevent);
+	del_timer_sync(&dev->delay);
 	free_netdev(net);
 out:
 	return status;
--- zfcpdump-kernel-4.4.orig/drivers/net/virtio_net.c
+++ zfcpdump-kernel-4.4/drivers/net/virtio_net.c
@@ -146,6 +146,10 @@ struct virtnet_info {
 	virtio_net_ctrl_ack ctrl_status;
 	u8 ctrl_promisc;
 	u8 ctrl_allmulti;
+
+	/* Ethtool settings */
+	u8 duplex;
+	u32 speed;
 };
 
 struct padded_vnet_hdr {
@@ -1378,6 +1382,60 @@ static void virtnet_get_channels(struct
 	channels->other_count = 0;
 }
 
+/* Check if the user is trying to change anything besides speed/duplex */
+static bool virtnet_validate_ethtool_cmd(const struct ethtool_cmd *cmd)
+{
+	struct ethtool_cmd diff1 = *cmd;
+	struct ethtool_cmd diff2 = {};
+
+	/* cmd is always set so we need to clear it, validate the port type
+	 * and also without autonegotiation we can ignore advertising
+	 */
+	ethtool_cmd_speed_set(&diff1, 0);
+	diff2.port = PORT_OTHER;
+	diff1.advertising = 0;
+	diff1.duplex = 0;
+	diff1.cmd = 0;
+
+	return !memcmp(&diff1, &diff2, sizeof(diff1));
+}
+
+static int virtnet_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+{
+	struct virtnet_info *vi = netdev_priv(dev);
+	u32 speed;
+
+	speed = ethtool_cmd_speed(cmd);
+	/* don't allow custom speed and duplex */
+	if (!ethtool_validate_speed(speed) ||
+	    !ethtool_validate_duplex(cmd->duplex) ||
+	    !virtnet_validate_ethtool_cmd(cmd))
+		return -EINVAL;
+	vi->speed = speed;
+	vi->duplex = cmd->duplex;
+
+	return 0;
+}
+
+static int virtnet_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+{
+	struct virtnet_info *vi = netdev_priv(dev);
+
+	ethtool_cmd_speed_set(cmd, vi->speed);
+	cmd->duplex = vi->duplex;
+	cmd->port = PORT_OTHER;
+
+	return 0;
+}
+
+static void virtnet_init_settings(struct net_device *dev)
+{
+	struct virtnet_info *vi = netdev_priv(dev);
+
+	vi->speed = SPEED_UNKNOWN;
+	vi->duplex = DUPLEX_UNKNOWN;
+}
+
 static const struct ethtool_ops virtnet_ethtool_ops = {
 	.get_drvinfo = virtnet_get_drvinfo,
 	.get_link = ethtool_op_get_link,
@@ -1385,6 +1443,8 @@ static const struct ethtool_ops virtnet_
 	.set_channels = virtnet_set_channels,
 	.get_channels = virtnet_get_channels,
 	.get_ts_info = ethtool_op_get_ts_info,
+	.get_settings = virtnet_get_settings,
+	.set_settings = virtnet_set_settings,
 };
 
 #define MIN_MTU 68
@@ -1858,6 +1918,8 @@ static int virtnet_probe(struct virtio_d
 	netif_set_real_num_tx_queues(dev, vi->curr_queue_pairs);
 	netif_set_real_num_rx_queues(dev, vi->curr_queue_pairs);
 
+	virtnet_init_settings(dev);
+
 	err = register_netdev(dev);
 	if (err) {
 		pr_debug("virtio_net: registering device failed\n");
--- zfcpdump-kernel-4.4.orig/drivers/net/vmxnet3/vmxnet3_drv.c
+++ zfcpdump-kernel-4.4/drivers/net/vmxnet3/vmxnet3_drv.c
@@ -1133,12 +1133,16 @@ vmxnet3_rx_csum(struct vmxnet3_adapter *
 		union Vmxnet3_GenericDesc *gdesc)
 {
 	if (!gdesc->rcd.cnc && adapter->netdev->features & NETIF_F_RXCSUM) {
-		/* typical case: TCP/UDP over IP and both csums are correct */
-		if ((le32_to_cpu(gdesc->dword[3]) & VMXNET3_RCD_CSUM_OK) ==
-							VMXNET3_RCD_CSUM_OK) {
+		if (gdesc->rcd.v4 &&
+		    (le32_to_cpu(gdesc->dword[3]) &
+		     VMXNET3_RCD_CSUM_OK) == VMXNET3_RCD_CSUM_OK) {
+			skb->ip_summed = CHECKSUM_UNNECESSARY;
+			BUG_ON(!(gdesc->rcd.tcp || gdesc->rcd.udp));
+			BUG_ON(gdesc->rcd.frg);
+		} else if (gdesc->rcd.v6 && (le32_to_cpu(gdesc->dword[3]) &
+					     (1 << VMXNET3_RCD_TUC_SHIFT))) {
 			skb->ip_summed = CHECKSUM_UNNECESSARY;
 			BUG_ON(!(gdesc->rcd.tcp || gdesc->rcd.udp));
-			BUG_ON(!(gdesc->rcd.v4  || gdesc->rcd.v6));
 			BUG_ON(gdesc->rcd.frg);
 		} else {
 			if (gdesc->rcd.csum) {
--- zfcpdump-kernel-4.4.orig/drivers/net/vmxnet3/vmxnet3_int.h
+++ zfcpdump-kernel-4.4/drivers/net/vmxnet3/vmxnet3_int.h
@@ -69,10 +69,10 @@
 /*
  * Version numbers
  */
-#define VMXNET3_DRIVER_VERSION_STRING   "1.4.5.0-k"
+#define VMXNET3_DRIVER_VERSION_STRING   "1.4.7.0-k"
 
 /* a 32-bit int, each byte encode a verion number in VMXNET3_DRIVER_VERSION */
-#define VMXNET3_DRIVER_VERSION_NUM      0x01040500
+#define VMXNET3_DRIVER_VERSION_NUM      0x01040700
 
 #if defined(CONFIG_PCI_MSI)
 	/* RSS only makes sense if MSI-X is supported. */
--- zfcpdump-kernel-4.4.orig/drivers/net/vrf.c
+++ zfcpdump-kernel-4.4/drivers/net/vrf.c
@@ -114,20 +114,23 @@ static struct dst_ops vrf_dst_ops = {
 #if IS_ENABLED(CONFIG_IPV6)
 static bool check_ipv6_frame(const struct sk_buff *skb)
 {
-	const struct ipv6hdr *ipv6h = (struct ipv6hdr *)skb->data;
-	size_t hlen = sizeof(*ipv6h);
+	const struct ipv6hdr *ipv6h;
+	struct ipv6hdr _ipv6h;
 	bool rc = true;
 
-	if (skb->len < hlen)
+	ipv6h = skb_header_pointer(skb, 0, sizeof(_ipv6h), &_ipv6h);
+	if (!ipv6h)
 		goto out;
 
 	if (ipv6h->nexthdr == NEXTHDR_ICMP) {
 		const struct icmp6hdr *icmph;
+		struct icmp6hdr _icmph;
 
-		if (skb->len < hlen + sizeof(*icmph))
+		icmph = skb_header_pointer(skb, sizeof(_ipv6h),
+					   sizeof(_icmph), &_icmph);
+		if (!icmph)
 			goto out;
 
-		icmph = (struct icmp6hdr *)(skb->data + sizeof(*ipv6h));
 		switch (icmph->icmp6_type) {
 		case NDISC_ROUTER_SOLICITATION:
 		case NDISC_ROUTER_ADVERTISEMENT:
--- zfcpdump-kernel-4.4.orig/drivers/net/vxlan.c
+++ zfcpdump-kernel-4.4/drivers/net/vxlan.c
@@ -23,6 +23,7 @@
 #include <linux/udp.h>
 #include <linux/igmp.h>
 #include <linux/etherdevice.h>
+#include <linux/inetdevice.h>
 #include <linux/if_ether.h>
 #include <linux/if_vlan.h>
 #include <linux/hash.h>
@@ -106,6 +107,167 @@ static inline bool vxlan_collect_metadat
 	       ip_tunnel_collect_metadata();
 }
 
+static struct ip_fan_map *vxlan_fan_find_map(struct vxlan_dev *vxlan, __be32 daddr)
+{
+	struct ip_fan_map *fan_map;
+
+	rcu_read_lock();
+	list_for_each_entry_rcu(fan_map, &vxlan->fan.fan_maps, list) {
+		if (fan_map->overlay ==
+		    (daddr & inet_make_mask(fan_map->overlay_prefix))) {
+			rcu_read_unlock();
+			return fan_map;
+		}
+	}
+	rcu_read_unlock();
+
+	return NULL;
+}
+
+static void vxlan_fan_flush_map(struct vxlan_dev *vxlan)
+{
+	struct ip_fan_map *fan_map;
+
+	list_for_each_entry_rcu(fan_map, &vxlan->fan.fan_maps, list) {
+		list_del_rcu(&fan_map->list);
+		kfree_rcu(fan_map, rcu);
+	}
+}
+
+static int vxlan_fan_del_map(struct vxlan_dev *vxlan, __be32 overlay)
+{
+	struct ip_fan_map *fan_map;
+
+	fan_map = vxlan_fan_find_map(vxlan, overlay);
+	if (!fan_map)
+		return -ENOENT;
+
+	list_del_rcu(&fan_map->list);
+	kfree_rcu(fan_map, rcu);
+
+	return 0;
+}
+
+static int vxlan_fan_add_map(struct vxlan_dev *vxlan, struct ifla_fan_map *map)
+{
+	__be32 overlay_mask, underlay_mask;
+	struct ip_fan_map *fan_map;
+
+	overlay_mask = inet_make_mask(map->overlay_prefix);
+	underlay_mask = inet_make_mask(map->underlay_prefix);
+
+	netdev_dbg(vxlan->dev, "vfam: map: o %x/%d u %x/%d om %x um %x\n",
+		   map->overlay, map->overlay_prefix,
+		   map->underlay, map->underlay_prefix,
+		   overlay_mask, underlay_mask);
+
+	if ((map->overlay & ~overlay_mask) || (map->underlay & ~underlay_mask))
+		return -EINVAL;
+
+	if (!(map->overlay & overlay_mask) && (map->underlay & underlay_mask))
+		return -EINVAL;
+
+	/* Special case: overlay 0 and underlay 0: flush all mappings */
+	if (!map->overlay && !map->underlay) {
+		vxlan_fan_flush_map(vxlan);
+		return 0;
+	}
+	
+	/* Special case: overlay set and underlay 0: clear map for overlay */
+	if (!map->underlay)
+		return vxlan_fan_del_map(vxlan, map->overlay);
+
+	if (vxlan_fan_find_map(vxlan, map->overlay))
+		return -EEXIST;
+
+	fan_map = kmalloc(sizeof(*fan_map), GFP_KERNEL);
+	fan_map->underlay = map->underlay;
+	fan_map->overlay = map->overlay;
+	fan_map->underlay_prefix = map->underlay_prefix;
+	fan_map->overlay_mask = ntohl(overlay_mask);
+	fan_map->overlay_prefix = map->overlay_prefix;
+
+	list_add_tail_rcu(&fan_map->list, &vxlan->fan.fan_maps);
+
+	return 0;
+}
+	
+static int vxlan_parse_fan_map(struct nlattr *data[], struct vxlan_dev *vxlan)
+{
+	struct ifla_fan_map *map;
+	struct nlattr *attr;
+	int rem, rv;
+
+	nla_for_each_nested(attr, data[IFLA_IPTUN_FAN_MAP], rem) {
+		map = nla_data(attr);
+		rv = vxlan_fan_add_map(vxlan, map);
+		if (rv)
+			return rv;
+	}
+
+	return 0;
+}
+
+static int vxlan_fan_build_rdst(struct vxlan_dev *vxlan, struct sk_buff *skb,
+				      struct vxlan_rdst *fan_rdst)
+{
+	struct ip_fan_map *f_map;
+	union vxlan_addr *va;
+	u32 daddr, underlay;
+	struct arphdr *arp;
+	void *arp_ptr;
+	struct ethhdr *eth;
+	struct iphdr *iph;
+
+	eth = eth_hdr(skb);
+	switch (eth->h_proto) {
+	case htons(ETH_P_IP):
+		iph = ip_hdr(skb);
+		if (!iph)
+			return -EINVAL;
+		daddr = iph->daddr;
+		break;
+	case htons(ETH_P_ARP):
+		arp = arp_hdr(skb);
+		if (!arp)
+			return -EINVAL;
+		arp_ptr = arp + 1;
+		netdev_dbg(vxlan->dev,
+			   "vfbr: arp sha %pM sip %pI4 tha %pM tip %pI4\n",
+			   arp_ptr, arp_ptr + skb->dev->addr_len,
+			   arp_ptr + skb->dev->addr_len + 4,
+			   arp_ptr + (skb->dev->addr_len * 2) + 4);
+		arp_ptr += (skb->dev->addr_len * 2) + 4;
+		memcpy(&daddr, arp_ptr, 4);
+		break;
+	default:
+		netdev_dbg(vxlan->dev, "vfbr: unknown eth p %x\n", eth->h_proto);
+		return -EINVAL;
+	}
+
+	f_map = vxlan_fan_find_map(vxlan, daddr);
+	if (!f_map)
+		return -EINVAL;
+
+	daddr = ntohl(daddr);
+	underlay = ntohl(f_map->underlay);
+	if (!underlay)
+		return -EINVAL;
+
+	memset(fan_rdst, 0, sizeof(*fan_rdst));
+	va = &fan_rdst->remote_ip;
+	va->sa.sa_family = AF_INET;
+	fan_rdst->remote_vni = vxlan->default_dst.remote_vni;
+	va->sin.sin_addr.s_addr = htonl(underlay |
+					((daddr & ~f_map->overlay_mask) >>
+					 (32 - f_map->overlay_prefix -
+					  (32 - f_map->underlay_prefix))));
+	netdev_dbg(vxlan->dev, "vfbr: daddr %x ul %x dst %x\n",
+		   daddr, underlay, va->sin.sin_addr.s_addr);
+
+	return 0;
+}
+
 #if IS_ENABLED(CONFIG_IPV6)
 static inline
 bool vxlan_addr_equal(const union vxlan_addr *a, const union vxlan_addr *b)
@@ -593,7 +755,7 @@ static struct sk_buff **vxlan_gro_receiv
 		}
 	}
 
-	pp = eth_gro_receive(head, skb);
+	pp = call_gro_receive(eth_gro_receive, head, skb);
 
 out:
 	skb_gro_remcsum_cleanup(skb, &grc);
@@ -1254,7 +1416,7 @@ static int vxlan_udp_encap_recv(struct s
 
 	/* Need Vxlan and inner Ethernet header to be present */
 	if (!pskb_may_pull(skb, VXLAN_HLEN))
-		goto error;
+		goto drop;
 
 	vxh = (struct vxlanhdr *)(udp_hdr(skb) + 1);
 	flags = ntohl(vxh->vx_flags);
@@ -1306,8 +1468,10 @@ static int vxlan_udp_encap_recv(struct s
 		gbp = (struct vxlanhdr_gbp *)vxh;
 		md->gbp = ntohs(gbp->policy_id);
 
-		if (tun_dst)
+		if (tun_dst) {
 			tun_dst->u.tun_info.key.tun_flags |= TUNNEL_VXLAN_OPT;
+			tun_dst->u.tun_info.options_len = sizeof(*md);
+		}
 
 		if (gbp->dont_learn)
 			md->gbp |= VXLAN_GBP_DONT_LEARN;
@@ -1342,13 +1506,7 @@ drop:
 bad_flags:
 	netdev_dbg(skb->dev, "invalid vxlan flags=%#x vni=%#x\n",
 		   ntohl(vxh->vx_flags), ntohl(vxh->vx_vni));
-
-error:
-	if (tun_dst)
-		dst_release((struct dst_entry *)tun_dst);
-
-	/* Return non vxlan pkt */
-	return 1;
+	goto drop;
 }
 
 static int arp_reduce(struct net_device *dev, struct sk_buff *skb)
@@ -1984,11 +2142,6 @@ static void vxlan_xmit_one(struct sk_buf
 				     vxlan->cfg.port_max, true);
 
 	if (info) {
-		if (info->key.tun_flags & TUNNEL_CSUM)
-			flags |= VXLAN_F_UDP_CSUM;
-		else
-			flags &= ~VXLAN_F_UDP_CSUM;
-
 		ttl = info->key.ttl;
 		tos = info->key.tos;
 
@@ -2003,8 +2156,15 @@ static void vxlan_xmit_one(struct sk_buf
 			goto drop;
 		sk = vxlan->vn4_sock->sock->sk;
 
-		if (info && (info->key.tun_flags & TUNNEL_DONT_FRAGMENT))
-			df = htons(IP_DF);
+		if (info) {
+			if (info->key.tun_flags & TUNNEL_DONT_FRAGMENT)
+				df = htons(IP_DF);
+
+			if (info->key.tun_flags & TUNNEL_CSUM)
+				flags |= VXLAN_F_UDP_CSUM;
+			else
+				flags &= ~VXLAN_F_UDP_CSUM;
+		}
 
 		memset(&fl4, 0, sizeof(fl4));
 		fl4.flowi4_oif = rdst ? rdst->remote_ifindex : 0;
@@ -2029,6 +2189,13 @@ static void vxlan_xmit_one(struct sk_buf
 			goto rt_tx_error;
 		}
 
+		if (fan_has_map(&vxlan->fan) && rt->rt_flags & RTCF_LOCAL) {
+			netdev_dbg(dev, "discard fan to localhost %pI4\n",
+				   &dst->sin.sin_addr.s_addr);
+			ip_rt_put(rt);
+			goto tx_free;
+		}
+
 		/* Bypass encapsulation if the destination is local */
 		if (rt->rt_flags & RTCF_LOCAL &&
 		    !(rt->rt_flags & (RTCF_BROADCAST | RTCF_MULTICAST))) {
@@ -2102,6 +2269,13 @@ static void vxlan_xmit_one(struct sk_buf
 			return;
 		}
 
+		if (info) {
+			if (info->key.tun_flags & TUNNEL_CSUM)
+				flags &= ~VXLAN_F_UDP_ZERO_CSUM6_TX;
+			else
+				flags |= VXLAN_F_UDP_ZERO_CSUM6_TX;
+		}
+
 		ttl = ttl ? : ip6_dst_hoplimit(ndst);
 		err = vxlan6_xmit_skb(ndst, sk, skb, dev, &saddr, &dst->sin6.sin6_addr,
 				      0, ttl, src_port, dst_port, htonl(vni << 8), md,
@@ -2169,6 +2343,20 @@ static netdev_tx_t vxlan_xmit(struct sk_
 		return NETDEV_TX_OK;
 	}
 
+	if (fan_has_map(&vxlan->fan)) {
+		struct vxlan_rdst fan_rdst;
+
+		netdev_dbg(vxlan->dev, "vxlan_xmit p %x d %pM\n",
+			   eth->h_proto, eth->h_dest);
+		if (vxlan_fan_build_rdst(vxlan, skb, &fan_rdst)) {
+			dev->stats.tx_dropped++;
+			kfree_skb(skb);
+			return NETDEV_TX_OK;
+		}
+		vxlan_xmit_one(skb, dev, &fan_rdst, 0);
+		return NETDEV_TX_OK;
+	}
+
 	f = vxlan_find_mac(vxlan, eth->h_dest);
 	did_rsc = false;
 
@@ -2359,29 +2547,43 @@ static void vxlan_set_multicast_list(str
 {
 }
 
-static int vxlan_change_mtu(struct net_device *dev, int new_mtu)
+static int __vxlan_change_mtu(struct net_device *dev,
+			      struct net_device *lowerdev,
+			      struct vxlan_rdst *dst, int new_mtu, bool strict)
 {
-	struct vxlan_dev *vxlan = netdev_priv(dev);
-	struct vxlan_rdst *dst = &vxlan->default_dst;
-	struct net_device *lowerdev;
-	int max_mtu;
+	int max_mtu = IP_MAX_MTU;
 
-	lowerdev = __dev_get_by_index(vxlan->net, dst->remote_ifindex);
-	if (lowerdev == NULL)
-		return eth_change_mtu(dev, new_mtu);
+	if (lowerdev)
+		max_mtu = lowerdev->mtu;
 
 	if (dst->remote_ip.sa.sa_family == AF_INET6)
-		max_mtu = lowerdev->mtu - VXLAN6_HEADROOM;
+		max_mtu -= VXLAN6_HEADROOM;
 	else
-		max_mtu = lowerdev->mtu - VXLAN_HEADROOM;
+		max_mtu -= VXLAN_HEADROOM;
 
-	if (new_mtu < 68 || new_mtu > max_mtu)
+	if (new_mtu < 68)
 		return -EINVAL;
 
+	if (new_mtu > max_mtu) {
+		if (strict)
+			return -EINVAL;
+
+		new_mtu = max_mtu;
+	}
+
 	dev->mtu = new_mtu;
 	return 0;
 }
 
+static int vxlan_change_mtu(struct net_device *dev, int new_mtu)
+{
+	struct vxlan_dev *vxlan = netdev_priv(dev);
+	struct vxlan_rdst *dst = &vxlan->default_dst;
+	struct net_device *lowerdev = __dev_get_by_index(vxlan->net,
+							 dst->remote_ifindex);
+	return __vxlan_change_mtu(dev, lowerdev, dst, new_mtu, true);
+}
+
 static int egress_ipv4_tun_info(struct net_device *dev, struct sk_buff *skb,
 				struct ip_tunnel_info *info,
 				__be16 sport, __be16 dport)
@@ -2532,6 +2734,8 @@ static void vxlan_setup(struct net_devic
 
 	for (h = 0; h < FDB_HASH_SIZE; ++h)
 		INIT_HLIST_HEAD(&vxlan->fdb_head[h]);
+
+	INIT_LIST_HEAD(&vxlan->fan.fan_maps);
 }
 
 static const struct nla_policy vxlan_policy[IFLA_VXLAN_MAX + 1] = {
@@ -2751,12 +2955,13 @@ static int vxlan_dev_configure(struct ne
 			       struct vxlan_config *conf)
 {
 	struct vxlan_net *vn = net_generic(src_net, vxlan_net_id);
-	struct vxlan_dev *vxlan = netdev_priv(dev);
+	struct vxlan_dev *vxlan = netdev_priv(dev), *tmp;
 	struct vxlan_rdst *dst = &vxlan->default_dst;
 	unsigned short needed_headroom = ETH_HLEN;
 	int err;
 	bool use_ipv6 = false;
 	__be16 default_port = vxlan->cfg.dst_port;
+	struct net_device *lowerdev = NULL;
 
 	vxlan->net = src_net;
 
@@ -2777,9 +2982,7 @@ static int vxlan_dev_configure(struct ne
 	}
 
 	if (conf->remote_ifindex) {
-		struct net_device *lowerdev
-			 = __dev_get_by_index(src_net, conf->remote_ifindex);
-
+		lowerdev = __dev_get_by_index(src_net, conf->remote_ifindex);
 		dst->remote_ifindex = conf->remote_ifindex;
 
 		if (!lowerdev) {
@@ -2803,6 +3006,12 @@ static int vxlan_dev_configure(struct ne
 		needed_headroom = lowerdev->hard_header_len;
 	}
 
+	if (conf->mtu) {
+		err = __vxlan_change_mtu(dev, lowerdev, dst, conf->mtu, false);
+		if (err)
+			return err;
+	}
+
 	if (use_ipv6 || conf->flags & VXLAN_F_COLLECT_METADATA)
 		needed_headroom += VXLAN6_HEADROOM;
 	else
@@ -2817,9 +3026,15 @@ static int vxlan_dev_configure(struct ne
 	if (!vxlan->cfg.age_interval)
 		vxlan->cfg.age_interval = FDB_AGE_DEFAULT;
 
-	if (vxlan_find_vni(src_net, conf->vni, use_ipv6 ? AF_INET6 : AF_INET,
-			   vxlan->cfg.dst_port, vxlan->flags))
+	list_for_each_entry(tmp, &vn->vxlan_list, next) {
+		if (tmp->cfg.vni == conf->vni &&
+		    (tmp->default_dst.remote_ip.sa.sa_family == AF_INET6 ||
+		     tmp->cfg.saddr.sa.sa_family == AF_INET6) == use_ipv6 &&
+		    tmp->cfg.dst_port == vxlan->cfg.dst_port &&
+		    (tmp->flags & VXLAN_F_RCV_FLAGS) ==
+		    (vxlan->flags & VXLAN_F_RCV_FLAGS))
 		return -EEXIST;
+	}
 
 	dev->ethtool_ops = &vxlan_ethtool_ops;
 
@@ -2875,6 +3090,7 @@ EXPORT_SYMBOL_GPL(vxlan_dev_create);
 static int vxlan_newlink(struct net *src_net, struct net_device *dev,
 			 struct nlattr *tb[], struct nlattr *data[])
 {
+	struct vxlan_dev *vxlan = netdev_priv(dev);
 	struct vxlan_config conf;
 	int err;
 
@@ -2893,6 +3109,12 @@ static int vxlan_newlink(struct net *src
 		conf.remote_ip.sa.sa_family = AF_INET6;
 	}
 
+	if (data[IFLA_VXLAN_FAN_MAP]) {
+		err = vxlan_parse_fan_map(data, vxlan);
+		if (err)
+			return err;
+	}
+
 	if (data[IFLA_VXLAN_LOCAL]) {
 		conf.saddr.sin.sin_addr.s_addr = nla_get_in_addr(data[IFLA_VXLAN_LOCAL]);
 		conf.saddr.sa.sa_family = AF_INET;
@@ -2974,6 +3196,9 @@ static int vxlan_newlink(struct net *src
 	if (data[IFLA_VXLAN_REMCSUM_NOPARTIAL])
 		conf.flags |= VXLAN_F_REMCSUM_NOPARTIAL;
 
+	if (tb[IFLA_MTU])
+		conf.mtu = nla_get_u32(tb[IFLA_MTU]);
+
 	err = vxlan_dev_configure(src_net, dev, &conf);
 	switch (err) {
 	case -ENODEV:
@@ -3031,6 +3256,7 @@ static size_t vxlan_get_size(const struc
 		nla_total_size(sizeof(__u8)) + /* IFLA_VXLAN_UDP_ZERO_CSUM6_RX */
 		nla_total_size(sizeof(__u8)) + /* IFLA_VXLAN_REMCSUM_TX */
 		nla_total_size(sizeof(__u8)) + /* IFLA_VXLAN_REMCSUM_RX */
+		nla_total_size(sizeof(struct ip_fan_map) * 256) +
 		0;
 }
 
@@ -3077,6 +3303,26 @@ static int vxlan_fill_info(struct sk_buf
 		}
 	}
 
+	if (fan_has_map(&vxlan->fan)) {
+		struct nlattr *fan_nest;
+		struct ip_fan_map *fan_map;
+
+		fan_nest = nla_nest_start(skb, IFLA_VXLAN_FAN_MAP);
+		if (!fan_nest)
+			goto nla_put_failure;
+		list_for_each_entry_rcu(fan_map, &vxlan->fan.fan_maps, list) {
+			struct ifla_fan_map map;
+
+			map.underlay = fan_map->underlay;
+			map.underlay_prefix = fan_map->underlay_prefix;
+			map.overlay = fan_map->overlay;
+			map.overlay_prefix = fan_map->overlay_prefix;
+			if (nla_put(skb, IFLA_FAN_MAPPING, sizeof(map), &map))
+				goto nla_put_failure;
+		}
+		nla_nest_end(skb, fan_nest);
+	}
+
 	if (nla_put_u8(skb, IFLA_VXLAN_TTL, vxlan->cfg.ttl) ||
 	    nla_put_u8(skb, IFLA_VXLAN_TOS, vxlan->cfg.tos) ||
 	    nla_put_u8(skb, IFLA_VXLAN_LEARNING,
@@ -3195,6 +3441,22 @@ static __net_init int vxlan_init_net(str
 	return 0;
 }
 
+#ifdef CONFIG_SYSCTL
+static struct ctl_table_header *vxlan_fan_header;
+static unsigned int vxlan_fan_version = 4;
+
+static struct ctl_table vxlan_fan_sysctls[] = {
+	{
+		.procname	= "vxlan",
+		.data		= &vxlan_fan_version,
+		.maxlen		= sizeof(vxlan_fan_version),
+		.mode		= 0444,
+		.proc_handler	= proc_dointvec,
+	},
+	{},
+};
+#endif /* CONFIG_SYSCTL */
+
 static void __net_exit vxlan_exit_net(struct net *net)
 {
 	struct vxlan_net *vn = net_generic(net, vxlan_net_id);
@@ -3250,7 +3512,20 @@ static int __init vxlan_init_module(void
 	if (rc)
 		goto out3;
 
+#ifdef CONFIG_SYSCTL
+	vxlan_fan_header = register_net_sysctl(&init_net, "net/fan",
+					      vxlan_fan_sysctls);
+	if (!vxlan_fan_header) {
+		rc = -ENOMEM;
+		goto sysctl_failed;
+	}
+#endif /* CONFIG_SYSCTL */
+
 	return 0;
+#ifdef CONFIG_SYSCTL
+sysctl_failed:
+	rtnl_link_unregister(&vxlan_link_ops);
+#endif /* CONFIG_SYSCTL */
 out3:
 	unregister_netdevice_notifier(&vxlan_notifier_block);
 out2:
@@ -3263,6 +3538,9 @@ late_initcall(vxlan_init_module);
 
 static void __exit vxlan_cleanup_module(void)
 {
+#ifdef CONFIG_SYSCTL
+	unregister_net_sysctl_table(vxlan_fan_header);
+#endif /* CONFIG_SYSCTL */
 	rtnl_link_unregister(&vxlan_link_ops);
 	unregister_netdevice_notifier(&vxlan_notifier_block);
 	destroy_workqueue(vxlan_wq);
--- zfcpdump-kernel-4.4.orig/drivers/net/wan/farsync.c
+++ zfcpdump-kernel-4.4/drivers/net/wan/farsync.c
@@ -2516,7 +2516,7 @@ fst_add_one(struct pci_dev *pdev, const
                 dev->mem_start   = card->phys_mem
                                  + BUF_OFFSET ( txBuffer[i][0][0]);
                 dev->mem_end     = card->phys_mem
-                                 + BUF_OFFSET ( txBuffer[i][NUM_TX_BUFFER][0]);
+                                 + BUF_OFFSET ( txBuffer[i][NUM_TX_BUFFER - 1][LEN_RX_BUFFER - 1]);
                 dev->base_addr   = card->pci_conf;
                 dev->irq         = card->irq;
 
--- zfcpdump-kernel-4.4.orig/drivers/net/wireless/ath/ath10k/core.c
+++ zfcpdump-kernel-4.4/drivers/net/wireless/ath/ath10k/core.c
@@ -1681,6 +1681,10 @@ int ath10k_core_start(struct ath10k *ar,
 		goto err_hif_stop;
 	}
 
+	ar->free_vdev_map = (1LL << ar->max_num_vdevs) - 1;
+
+	INIT_LIST_HEAD(&ar->arvifs);
+
 	/* we don't care about HTT in UTF mode */
 	if (mode == ATH10K_FIRMWARE_MODE_NORMAL) {
 		status = ath10k_htt_setup(&ar->htt);
@@ -1694,10 +1698,6 @@ int ath10k_core_start(struct ath10k *ar,
 	if (status)
 		goto err_hif_stop;
 
-	ar->free_vdev_map = (1LL << ar->max_num_vdevs) - 1;
-
-	INIT_LIST_HEAD(&ar->arvifs);
-
 	return 0;
 
 err_hif_stop:
--- zfcpdump-kernel-4.4.orig/drivers/net/wireless/ath/ath10k/debug.c
+++ zfcpdump-kernel-4.4/drivers/net/wireless/ath/ath10k/debug.c
@@ -1986,7 +1986,12 @@ static ssize_t ath10k_write_pktlog_filte
 		goto out;
 	}
 
-	if (filter && (filter != ar->debug.pktlog_filter)) {
+	if (filter == ar->debug.pktlog_filter) {
+		ret = count;
+		goto out;
+	}
+
+	if (filter) {
 		ret = ath10k_wmi_pdev_pktlog_enable(ar, filter);
 		if (ret) {
 			ath10k_warn(ar, "failed to enable pktlog filter %x: %d\n",
--- zfcpdump-kernel-4.4.orig/drivers/net/wireless/ath/ath10k/mac.c
+++ zfcpdump-kernel-4.4/drivers/net/wireless/ath/ath10k/mac.c
@@ -4456,7 +4456,10 @@ static int ath10k_add_interface(struct i
 		goto err_vdev_delete;
 	}
 
-	if (ar->cfg_tx_chainmask) {
+	/* Configuring number of spatial stream for monitor interface is causing
+	 * target assert in qca9888 and qca6174.
+	 */
+	if (ar->cfg_tx_chainmask && (vif->type != NL80211_IFTYPE_MONITOR)) {
 		u16 nss = get_nss_from_chainmask(ar->cfg_tx_chainmask);
 
 		vdev_param = ar->wmi.vdev_param->nss;
@@ -6416,7 +6419,13 @@ ath10k_mac_update_rx_channel(struct ath1
 			def = &vifs[0].new_ctx->def;
 
 		ar->rx_channel = def->chan;
-	} else if (ctx && ath10k_mac_num_chanctxs(ar) == 0) {
+	} else if ((ctx && ath10k_mac_num_chanctxs(ar) == 0) ||
+		   (ctx && (ar->state == ATH10K_STATE_RESTARTED))) {
+		/* During driver restart due to firmware assert, since mac80211
+		 * already has valid channel context for given radio, channel
+		 * context iteration return num_chanctx > 0. So fix rx_channel
+		 * when restart is in progress.
+		 */
 		ar->rx_channel = ctx->def.chan;
 	} else {
 		ar->rx_channel = NULL;
--- zfcpdump-kernel-4.4.orig/drivers/net/wireless/ath/ath5k/led.c
+++ zfcpdump-kernel-4.4/drivers/net/wireless/ath/ath5k/led.c
@@ -77,7 +77,7 @@ static const struct pci_device_id ath5k_
 	/* HP Compaq CQ60-206US (ddreggors@jumptv.com) */
 	{ ATH_SDEVICE(PCI_VENDOR_ID_HP, 0x0137a), ATH_LED(3, 1) },
 	/* HP Compaq C700 (nitrousnrg@gmail.com) */
-	{ ATH_SDEVICE(PCI_VENDOR_ID_HP, 0x0137b), ATH_LED(3, 1) },
+	{ ATH_SDEVICE(PCI_VENDOR_ID_HP, 0x0137b), ATH_LED(3, 0) },
 	/* LiteOn AR5BXB63 (magooz@salug.it) */
 	{ ATH_SDEVICE(PCI_VENDOR_ID_ATHEROS, 0x3067), ATH_LED(3, 0) },
 	/* IBM-specific AR5212 (all others) */
--- zfcpdump-kernel-4.4.orig/drivers/net/wireless/ath/ath9k/ar5008_phy.c
+++ zfcpdump-kernel-4.4/drivers/net/wireless/ath/ath9k/ar5008_phy.c
@@ -274,6 +274,9 @@ void ar5008_hw_cmn_spur_mitigate(struct
 	};
 	static const int inc[4] = { 0, 100, 0, 0 };
 
+	memset(&mask_m, 0, sizeof(int8_t) * 123);
+	memset(&mask_p, 0, sizeof(int8_t) * 123);
+
 	cur_bin = -6000;
 	upper = bin + 100;
 	lower = bin - 100;
@@ -424,14 +427,9 @@ static void ar5008_hw_spur_mitigate(stru
 	int tmp, new;
 	int i;
 
-	int8_t mask_m[123];
-	int8_t mask_p[123];
 	int cur_bb_spur;
 	bool is2GHz = IS_CHAN_2GHZ(chan);
 
-	memset(&mask_m, 0, sizeof(int8_t) * 123);
-	memset(&mask_p, 0, sizeof(int8_t) * 123);
-
 	for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
 		cur_bb_spur = ah->eep_ops->get_spur_channel(ah, i, is2GHz);
 		if (AR_NO_SPUR == cur_bb_spur)
--- zfcpdump-kernel-4.4.orig/drivers/net/wireless/ath/ath9k/ar9002_phy.c
+++ zfcpdump-kernel-4.4/drivers/net/wireless/ath/ath9k/ar9002_phy.c
@@ -178,14 +178,9 @@ static void ar9002_hw_spur_mitigate(stru
 	int i;
 	struct chan_centers centers;
 
-	int8_t mask_m[123];
-	int8_t mask_p[123];
 	int cur_bb_spur;
 	bool is2GHz = IS_CHAN_2GHZ(chan);
 
-	memset(&mask_m, 0, sizeof(int8_t) * 123);
-	memset(&mask_p, 0, sizeof(int8_t) * 123);
-
 	ath9k_hw_get_channel_centers(ah, chan, &centers);
 	freq = centers.synth_center;
 
--- zfcpdump-kernel-4.4.orig/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
+++ zfcpdump-kernel-4.4/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
@@ -4176,7 +4176,7 @@ static void ath9k_hw_ar9300_set_board_va
 	if (!AR_SREV_9330(ah) && !AR_SREV_9340(ah) && !AR_SREV_9531(ah))
 		ar9003_hw_internal_regulator_apply(ah);
 	ar9003_hw_apply_tuning_caps(ah);
-	ar9003_hw_apply_minccapwr_thresh(ah, chan);
+	ar9003_hw_apply_minccapwr_thresh(ah, is2ghz);
 	ar9003_hw_txend_to_xpa_off_apply(ah, is2ghz);
 	ar9003_hw_thermometer_apply(ah);
 	ar9003_hw_thermo_cal_apply(ah);
--- zfcpdump-kernel-4.4.orig/drivers/net/wireless/ath/ath9k/eeprom.c
+++ zfcpdump-kernel-4.4/drivers/net/wireless/ath/ath9k/eeprom.c
@@ -403,10 +403,9 @@ void ath9k_hw_get_gain_boundaries_pdadcs
 
 	if (match) {
 		if (AR_SREV_9287(ah)) {
-			/* FIXME: array overrun? */
 			for (i = 0; i < numXpdGains; i++) {
 				minPwrT4[i] = data_9287[idxL].pwrPdg[i][0];
-				maxPwrT4[i] = data_9287[idxL].pwrPdg[i][4];
+				maxPwrT4[i] = data_9287[idxL].pwrPdg[i][intercepts - 1];
 				ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
 						data_9287[idxL].pwrPdg[i],
 						data_9287[idxL].vpdPdg[i],
@@ -416,7 +415,7 @@ void ath9k_hw_get_gain_boundaries_pdadcs
 		} else if (eeprom_4k) {
 			for (i = 0; i < numXpdGains; i++) {
 				minPwrT4[i] = data_4k[idxL].pwrPdg[i][0];
-				maxPwrT4[i] = data_4k[idxL].pwrPdg[i][4];
+				maxPwrT4[i] = data_4k[idxL].pwrPdg[i][intercepts - 1];
 				ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
 						data_4k[idxL].pwrPdg[i],
 						data_4k[idxL].vpdPdg[i],
@@ -426,7 +425,7 @@ void ath9k_hw_get_gain_boundaries_pdadcs
 		} else {
 			for (i = 0; i < numXpdGains; i++) {
 				minPwrT4[i] = data_def[idxL].pwrPdg[i][0];
-				maxPwrT4[i] = data_def[idxL].pwrPdg[i][4];
+				maxPwrT4[i] = data_def[idxL].pwrPdg[i][intercepts - 1];
 				ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
 						data_def[idxL].pwrPdg[i],
 						data_def[idxL].vpdPdg[i],
--- zfcpdump-kernel-4.4.orig/drivers/net/wireless/ath/ath9k/init.c
+++ zfcpdump-kernel-4.4/drivers/net/wireless/ath/ath9k/init.c
@@ -49,6 +49,10 @@ int ath9k_led_blink;
 module_param_named(blink, ath9k_led_blink, int, 0444);
 MODULE_PARM_DESC(blink, "Enable LED blink on activity");
 
+static int ath9k_led_active_high = -1;
+module_param_named(led_active_high, ath9k_led_active_high, int, 0444);
+MODULE_PARM_DESC(led_active_high, "Invert LED polarity");
+
 static int ath9k_btcoex_enable;
 module_param_named(btcoex_enable, ath9k_btcoex_enable, int, 0444);
 MODULE_PARM_DESC(btcoex_enable, "Enable wifi-BT coexistence");
@@ -600,6 +604,9 @@ static int ath9k_init_softc(u16 devid, s
 	if (ret)
 		return ret;
 
+	if (ath9k_led_active_high != -1)
+		ah->config.led_active_high = ath9k_led_active_high == 1;
+
 	/*
 	 * Enable WLAN/BT RX Antenna diversity only when:
 	 *
@@ -862,8 +869,8 @@ static void ath9k_set_hw_capab(struct at
 			hw->wiphy->interface_modes |=
 					BIT(NL80211_IFTYPE_P2P_DEVICE);
 
-			hw->wiphy->iface_combinations = if_comb;
-			hw->wiphy->n_iface_combinations = ARRAY_SIZE(if_comb);
+		hw->wiphy->iface_combinations = if_comb;
+		hw->wiphy->n_iface_combinations = ARRAY_SIZE(if_comb);
 	}
 
 	hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
--- zfcpdump-kernel-4.4.orig/drivers/net/wireless/ath/ath9k/main.c
+++ zfcpdump-kernel-4.4/drivers/net/wireless/ath/ath9k/main.c
@@ -1550,13 +1550,13 @@ static int ath9k_sta_state(struct ieee80
 	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
 	int ret = 0;
 
-	if (old_state == IEEE80211_STA_AUTH &&
-	    new_state == IEEE80211_STA_ASSOC) {
+	if (old_state == IEEE80211_STA_NOTEXIST &&
+	    new_state == IEEE80211_STA_NONE) {
 		ret = ath9k_sta_add(hw, vif, sta);
 		ath_dbg(common, CONFIG,
 			"Add station: %pM\n", sta->addr);
-	} else if (old_state == IEEE80211_STA_ASSOC &&
-		   new_state == IEEE80211_STA_AUTH) {
+	} else if (old_state == IEEE80211_STA_NONE &&
+		   new_state == IEEE80211_STA_NOTEXIST) {
 		ret = ath9k_sta_remove(hw, vif, sta);
 		ath_dbg(common, CONFIG,
 			"Remove station: %pM\n", sta->addr);
--- zfcpdump-kernel-4.4.orig/drivers/net/wireless/ath/ath9k/pci.c
+++ zfcpdump-kernel-4.4/drivers/net/wireless/ath/ath9k/pci.c
@@ -28,6 +28,16 @@ static const struct pci_device_id ath_pc
 	{ PCI_VDEVICE(ATHEROS, 0x0024) }, /* PCI-E */
 	{ PCI_VDEVICE(ATHEROS, 0x0027) }, /* PCI   */
 	{ PCI_VDEVICE(ATHEROS, 0x0029) }, /* PCI   */
+
+#ifdef CONFIG_ATH9K_PCOEM
+	/* Mini PCI AR9220 MB92 cards: Compex WLM200NX, Wistron DNMA-92 */
+	{ PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
+			 0x0029,
+			 PCI_VENDOR_ID_ATHEROS,
+			 0x2096),
+	  .driver_data = ATH9K_PCI_LED_ACT_HI },
+#endif
+
 	{ PCI_VDEVICE(ATHEROS, 0x002A) }, /* PCI-E */
 
 #ifdef CONFIG_ATH9K_PCOEM
--- zfcpdump-kernel-4.4.orig/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
+++ zfcpdump-kernel-4.4/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
@@ -726,8 +726,10 @@ int brcmf_sdiod_recv_chain(struct brcmf_
 			return -ENOMEM;
 		err = brcmf_sdiod_buffrw(sdiodev, SDIO_FUNC_2, false, addr,
 					 glom_skb);
-		if (err)
+		if (err) {
+			brcmu_pkt_buf_free_skb(glom_skb);
 			goto done;
+		}
 
 		skb_queue_walk(pktq, skb) {
 			memcpy(skb->data, glom_skb->data, skb->len);
--- zfcpdump-kernel-4.4.orig/drivers/net/wireless/brcm80211/brcmsmac/dma.c
+++ zfcpdump-kernel-4.4/drivers/net/wireless/brcm80211/brcmsmac/dma.c
@@ -1079,8 +1079,10 @@ bool dma_rxfill(struct dma_pub *pub)
 
 		pa = dma_map_single(di->dmadev, p->data, di->rxbufsize,
 				    DMA_FROM_DEVICE);
-		if (dma_mapping_error(di->dmadev, pa))
+		if (dma_mapping_error(di->dmadev, pa)) {
+			brcmu_pkt_buf_free_skb(p);
 			return false;
+		}
 
 		/* save the free packet pointer */
 		di->rxp[rxout] = p;
--- zfcpdump-kernel-4.4.orig/drivers/net/wireless/brcm80211/brcmsmac/stf.c
+++ zfcpdump-kernel-4.4/drivers/net/wireless/brcm80211/brcmsmac/stf.c
@@ -87,7 +87,7 @@ void
 brcms_c_stf_ss_algo_channel_get(struct brcms_c_info *wlc, u16 *ss_algo_channel,
 			    u16 chanspec)
 {
-	struct tx_power power;
+	struct tx_power power = { };
 	u8 siso_mcs_id, cdd_mcs_id, stbc_mcs_id;
 
 	/* Clear previous settings */
--- zfcpdump-kernel-4.4.orig/drivers/net/wireless/hostap/hostap_hw.c
+++ zfcpdump-kernel-4.4/drivers/net/wireless/hostap/hostap_hw.c
@@ -69,7 +69,7 @@ static char essid[33] = "test";
 module_param_string(essid, essid, sizeof(essid), 0444);
 MODULE_PARM_DESC(essid, "Host AP's ESSID");
 
-static int iw_mode[MAX_PARM_DEVICES] = { IW_MODE_MASTER, DEF_INTS };
+static int iw_mode[MAX_PARM_DEVICES] = { IW_MODE_INFRA, DEF_INTS };
 module_param_array(iw_mode, int, NULL, 0444);
 MODULE_PARM_DESC(iw_mode, "Initial operation mode");
 
--- zfcpdump-kernel-4.4.orig/drivers/net/wireless/iwlegacy/3945.c
+++ zfcpdump-kernel-4.4/drivers/net/wireless/iwlegacy/3945.c
@@ -1019,12 +1019,13 @@ il3945_hw_txq_ctx_free(struct il_priv *i
 	int txq_id;
 
 	/* Tx queues */
-	if (il->txq)
+	if (il->txq) {
 		for (txq_id = 0; txq_id < il->hw_params.max_txq_num; txq_id++)
 			if (txq_id == IL39_CMD_QUEUE_NUM)
 				il_cmd_queue_free(il);
 			else
 				il_tx_queue_free(il, txq_id);
+	}
 
 	/* free tx queue structure */
 	il_free_txq_mem(il);
--- zfcpdump-kernel-4.4.orig/drivers/net/wireless/iwlwifi/dvm/calib.c
+++ zfcpdump-kernel-4.4/drivers/net/wireless/iwlwifi/dvm/calib.c
@@ -901,7 +901,7 @@ static void iwlagn_gain_computation(stru
 		/* bound gain by 2 bits value max, 3rd bit is sign */
 		data->delta_gain_code[i] =
 			min(abs(delta_g),
-			(long) CHAIN_NOISE_MAX_DELTA_GAIN_CODE);
+			(s32) CHAIN_NOISE_MAX_DELTA_GAIN_CODE);
 
 		if (delta_g < 0)
 			/*
--- zfcpdump-kernel-4.4.orig/drivers/net/wireless/iwlwifi/dvm/lib.c
+++ zfcpdump-kernel-4.4/drivers/net/wireless/iwlwifi/dvm/lib.c
@@ -1154,6 +1154,9 @@ int iwlagn_suspend(struct iwl_priv *priv
 
 	priv->ucode_loaded = false;
 	iwl_trans_stop_device(priv->trans);
+	ret = iwl_trans_start_hw(priv->trans);
+	if (ret)
+		goto out;
 
 	priv->wowlan = true;
 
--- zfcpdump-kernel-4.4.orig/drivers/net/wireless/iwlwifi/mvm/fw.c
+++ zfcpdump-kernel-4.4/drivers/net/wireless/iwlwifi/mvm/fw.c
@@ -106,7 +106,7 @@ static int iwl_send_tx_ant_cfg(struct iw
 				    sizeof(tx_ant_cmd), &tx_ant_cmd);
 }
 
-static void iwl_free_fw_paging(struct iwl_mvm *mvm)
+void iwl_free_fw_paging(struct iwl_mvm *mvm)
 {
 	int i;
 
@@ -126,6 +126,8 @@ static void iwl_free_fw_paging(struct iw
 			     get_order(mvm->fw_paging_db[i].fw_paging_size));
 	}
 	kfree(mvm->trans->paging_download_buf);
+	mvm->trans->paging_download_buf = NULL;
+
 	memset(mvm->fw_paging_db, 0, sizeof(mvm->fw_paging_db));
 }
 
@@ -933,7 +935,8 @@ int iwl_mvm_start_fw_dbg_conf(struct iwl
 	}
 
 	mvm->fw_dbg_conf = conf_id;
-	return ret;
+
+	return 0;
 }
 
 static int iwl_mvm_config_ltr(struct iwl_mvm *mvm)
--- zfcpdump-kernel-4.4.orig/drivers/net/wireless/iwlwifi/mvm/mac80211.c
+++ zfcpdump-kernel-4.4/drivers/net/wireless/iwlwifi/mvm/mac80211.c
@@ -1557,6 +1557,8 @@ void __iwl_mvm_mac_stop(struct iwl_mvm *
 	/* the fw is stopped, the aux sta is dead: clean up driver state */
 	iwl_mvm_del_aux_sta(mvm);
 
+	iwl_free_fw_paging(mvm);
+
 	/*
 	 * Clear IN_HW_RESTART flag when stopping the hw (as restart_complete()
 	 * won't be called in this case).
@@ -3990,8 +3992,8 @@ static int iwl_mvm_mac_get_survey(struct
 	if (idx != 0)
 		return -ENOENT;
 
-	if (fw_has_capa(&mvm->fw->ucode_capa,
-			IWL_UCODE_TLV_CAPA_RADIO_BEACON_STATS))
+	if (!fw_has_capa(&mvm->fw->ucode_capa,
+			 IWL_UCODE_TLV_CAPA_RADIO_BEACON_STATS))
 		return -ENOENT;
 
 	mutex_lock(&mvm->mutex);
@@ -4037,8 +4039,8 @@ static void iwl_mvm_mac_sta_statistics(s
 	struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
 	struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
 
-	if (fw_has_capa(&mvm->fw->ucode_capa,
-			IWL_UCODE_TLV_CAPA_RADIO_BEACON_STATS))
+	if (!fw_has_capa(&mvm->fw->ucode_capa,
+			 IWL_UCODE_TLV_CAPA_RADIO_BEACON_STATS))
 		return;
 
 	/* if beacon filtering isn't on mac80211 does it anyway */
--- zfcpdump-kernel-4.4.orig/drivers/net/wireless/iwlwifi/mvm/mvm.h
+++ zfcpdump-kernel-4.4/drivers/net/wireless/iwlwifi/mvm/mvm.h
@@ -1190,6 +1190,9 @@ void iwl_mvm_rx_umac_scan_complete_notif
 void iwl_mvm_rx_umac_scan_iter_complete_notif(struct iwl_mvm *mvm,
 					      struct iwl_rx_cmd_buffer *rxb);
 
+/* Paging */
+void iwl_free_fw_paging(struct iwl_mvm *mvm);
+
 /* MVM debugfs */
 #ifdef CONFIG_IWLWIFI_DEBUGFS
 int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir);
--- zfcpdump-kernel-4.4.orig/drivers/net/wireless/iwlwifi/mvm/scan.c
+++ zfcpdump-kernel-4.4/drivers/net/wireless/iwlwifi/mvm/scan.c
@@ -1267,6 +1267,10 @@ int iwl_mvm_sched_scan_start(struct iwl_
 		return -EBUSY;
 	}
 
+	/* we don't support "match all" in the firmware */
+	if (!req->n_match_sets)
+		return -EOPNOTSUPP;
+
 	ret = iwl_mvm_check_running_scans(mvm, type);
 	if (ret)
 		return ret;
--- zfcpdump-kernel-4.4.orig/drivers/net/wireless/iwlwifi/mvm/sf.c
+++ zfcpdump-kernel-4.4/drivers/net/wireless/iwlwifi/mvm/sf.c
@@ -215,7 +215,7 @@ static int iwl_mvm_sf_config(struct iwl_
 			     enum iwl_sf_state new_state)
 {
 	struct iwl_sf_cfg_cmd sf_cmd = {
-		.state = cpu_to_le32(SF_FULL_ON),
+		.state = cpu_to_le32(new_state),
 	};
 	struct ieee80211_sta *sta;
 	int ret = 0;
--- zfcpdump-kernel-4.4.orig/drivers/net/wireless/iwlwifi/mvm/tx.c
+++ zfcpdump-kernel-4.4/drivers/net/wireless/iwlwifi/mvm/tx.c
@@ -421,6 +421,15 @@ int iwl_mvm_tx_skb_non_sta(struct iwl_mv
 		return -1;
 	}
 
+	/*
+	 * Increase the pending frames counter, so that later when a reply comes
+	 * in and the counter is decreased - we don't start getting negative
+	 * values.
+	 * Note that we don't need to make sure it isn't agg'd, since we're
+	 * TXing non-sta
+	 */
+	atomic_inc(&mvm->pending_frames[sta_id]);
+
 	return 0;
 }
 
--- zfcpdump-kernel-4.4.orig/drivers/net/wireless/iwlwifi/pcie/drv.c
+++ zfcpdump-kernel-4.4/drivers/net/wireless/iwlwifi/pcie/drv.c
@@ -384,6 +384,7 @@ static const struct pci_device_id iwl_hw
 	{IWL_PCI_DEVICE(0x095B, 0x5310, iwl7265_2ac_cfg)},
 	{IWL_PCI_DEVICE(0x095B, 0x5302, iwl7265_n_cfg)},
 	{IWL_PCI_DEVICE(0x095B, 0x5210, iwl7265_2ac_cfg)},
+	{IWL_PCI_DEVICE(0x095A, 0x5C10, iwl7265_2ac_cfg)},
 	{IWL_PCI_DEVICE(0x095A, 0x5012, iwl7265_2ac_cfg)},
 	{IWL_PCI_DEVICE(0x095A, 0x5412, iwl7265_2ac_cfg)},
 	{IWL_PCI_DEVICE(0x095A, 0x5410, iwl7265_2ac_cfg)},
@@ -401,10 +402,10 @@ static const struct pci_device_id iwl_hw
 	{IWL_PCI_DEVICE(0x095A, 0x900A, iwl7265_2ac_cfg)},
 	{IWL_PCI_DEVICE(0x095A, 0x9110, iwl7265_2ac_cfg)},
 	{IWL_PCI_DEVICE(0x095A, 0x9112, iwl7265_2ac_cfg)},
-	{IWL_PCI_DEVICE(0x095A, 0x9210, iwl7265_2ac_cfg)},
+	{IWL_PCI_DEVICE(0x095B, 0x9210, iwl7265_2ac_cfg)},
 	{IWL_PCI_DEVICE(0x095B, 0x9200, iwl7265_2ac_cfg)},
 	{IWL_PCI_DEVICE(0x095A, 0x9510, iwl7265_2ac_cfg)},
-	{IWL_PCI_DEVICE(0x095A, 0x9310, iwl7265_2ac_cfg)},
+	{IWL_PCI_DEVICE(0x095B, 0x9310, iwl7265_2ac_cfg)},
 	{IWL_PCI_DEVICE(0x095A, 0x9410, iwl7265_2ac_cfg)},
 	{IWL_PCI_DEVICE(0x095A, 0x5020, iwl7265_2n_cfg)},
 	{IWL_PCI_DEVICE(0x095A, 0x502A, iwl7265_2n_cfg)},
--- zfcpdump-kernel-4.4.orig/drivers/net/wireless/iwlwifi/pcie/trans.c
+++ zfcpdump-kernel-4.4/drivers/net/wireless/iwlwifi/pcie/trans.c
@@ -7,6 +7,7 @@
  *
  * Copyright(c) 2007 - 2015 Intel Corporation. All rights reserved.
  * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
+ * Copyright(c) 2016 Intel Deutschland GmbH
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of version 2 of the GNU General Public License as
@@ -33,6 +34,7 @@
  *
  * Copyright(c) 2005 - 2015 Intel Corporation. All rights reserved.
  * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
+ * Copyright(c) 2016 Intel Deutschland GmbH
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -729,8 +731,8 @@ static int iwl_pcie_rsa_race_bug_wa(stru
 	 */
 	val = iwl_read_prph(trans, PREG_AUX_BUS_WPROT_0);
 	if (val & (BIT(1) | BIT(17))) {
-		IWL_INFO(trans,
-			 "can't access the RSA semaphore it is write protected\n");
+		IWL_DEBUG_INFO(trans,
+			       "can't access the RSA semaphore it is write protected\n");
 		return 0;
 	}
 
@@ -924,9 +926,16 @@ monitor:
 	if (dest->monitor_mode == EXTERNAL_MODE && trans_pcie->fw_mon_size) {
 		iwl_write_prph(trans, le32_to_cpu(dest->base_reg),
 			       trans_pcie->fw_mon_phys >> dest->base_shift);
-		iwl_write_prph(trans, le32_to_cpu(dest->end_reg),
-			       (trans_pcie->fw_mon_phys +
-				trans_pcie->fw_mon_size) >> dest->end_shift);
+		if (trans->cfg->device_family == IWL_DEVICE_FAMILY_8000)
+			iwl_write_prph(trans, le32_to_cpu(dest->end_reg),
+				       (trans_pcie->fw_mon_phys +
+					trans_pcie->fw_mon_size - 256) >>
+						dest->end_shift);
+		else
+			iwl_write_prph(trans, le32_to_cpu(dest->end_reg),
+				       (trans_pcie->fw_mon_phys +
+					trans_pcie->fw_mon_size) >>
+						dest->end_shift);
 	}
 }
 
--- zfcpdump-kernel-4.4.orig/drivers/net/wireless/iwlwifi/pcie/tx.c
+++ zfcpdump-kernel-4.4/drivers/net/wireless/iwlwifi/pcie/tx.c
@@ -1508,9 +1508,9 @@ static int iwl_pcie_enqueue_hcmd(struct
 
 	/* start the TFD with the scratchbuf */
 	scratch_size = min_t(int, copy_size, IWL_HCMD_SCRATCHBUF_SIZE);
-	memcpy(&txq->scratchbufs[q->write_ptr], &out_cmd->hdr, scratch_size);
+	memcpy(&txq->scratchbufs[idx], &out_cmd->hdr, scratch_size);
 	iwl_pcie_txq_build_tfd(trans, txq,
-			       iwl_pcie_get_scratchbuf_dma(txq, q->write_ptr),
+			       iwl_pcie_get_scratchbuf_dma(txq, idx),
 			       scratch_size, true);
 
 	/* map first command fragment, if any remains */
--- zfcpdump-kernel-4.4.orig/drivers/net/wireless/mac80211_hwsim.c
+++ zfcpdump-kernel-4.4/drivers/net/wireless/mac80211_hwsim.c
@@ -2723,6 +2723,7 @@ static int hwsim_tx_info_frame_received_
 	if (!info->attrs[HWSIM_ATTR_ADDR_TRANSMITTER] ||
 	    !info->attrs[HWSIM_ATTR_FLAGS] ||
 	    !info->attrs[HWSIM_ATTR_COOKIE] ||
+	    !info->attrs[HWSIM_ATTR_SIGNAL] ||
 	    !info->attrs[HWSIM_ATTR_TX_INFO])
 		goto out;
 
--- zfcpdump-kernel-4.4.orig/drivers/net/wireless/mwifiex/Makefile
+++ zfcpdump-kernel-4.4/drivers/net/wireless/mwifiex/Makefile
@@ -42,6 +42,7 @@ mwifiex-y += cfg80211.o
 mwifiex-y += ethtool.o
 mwifiex-y += 11h.o
 mwifiex-y += tdls.o
+mwifiex-y += vendor.o
 mwifiex-$(CONFIG_DEBUG_FS) += debugfs.o
 obj-$(CONFIG_MWIFIEX) += mwifiex.o
 
--- zfcpdump-kernel-4.4.orig/drivers/net/wireless/mwifiex/cfg80211.c
+++ zfcpdump-kernel-4.4/drivers/net/wireless/mwifiex/cfg80211.c
@@ -3802,6 +3802,10 @@ int mwifiex_register_cfg80211(struct mwi
 	wiphy->cipher_suites = mwifiex_cipher_suites;
 	wiphy->n_cipher_suites = ARRAY_SIZE(mwifiex_cipher_suites);
 
+	if (adapter->region_code)
+		wiphy->regulatory_flags |= REGULATORY_DISABLE_BEACON_HINTS |
+					   REGULATORY_COUNTRY_IE_IGNORE;
+
 	ether_addr_copy(wiphy->perm_addr, adapter->perm_addr);
 	wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
 	wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME |
@@ -3838,6 +3842,8 @@ int mwifiex_register_cfg80211(struct mwi
 	if (adapter->fw_api_ver == MWIFIEX_FW_V15)
 		wiphy->features |= NL80211_FEATURE_SK_TX_STATUS;
 
+	marvell_set_vendor_commands(wiphy);
+
 	/* Reserve space for mwifiex specific private data for BSS */
 	wiphy->bss_priv_size = sizeof(struct mwifiex_bss_priv);
 
@@ -3862,11 +3868,15 @@ int mwifiex_register_cfg80211(struct mwi
 			    "driver hint alpha2: %2.2s\n", reg_alpha2);
 		regulatory_hint(wiphy, reg_alpha2);
 	} else {
-		country_code = mwifiex_11d_code_2_region(adapter->region_code);
-		if (country_code)
-			mwifiex_dbg(adapter, WARN,
-				    "ignoring F/W country code %2.2s\n",
-				    country_code);
+		if (adapter->region_code == 0x00) {
+			mwifiex_dbg(adapter, WARN, "Ignore world regulatory domain\n");
+		} else {
+			country_code =
+				mwifiex_11d_code_2_region(adapter->region_code);
+			if (country_code &&
+			    regulatory_hint(wiphy, country_code))
+				mwifiex_dbg(priv->adapter, ERROR, "regulatory_hint() failed\n");
+		}
 	}
 
 	mwifiex_send_cmd(priv, HostCmd_CMD_802_11_SNMP_MIB,
--- zfcpdump-kernel-4.4.orig/drivers/net/wireless/mwifiex/cfp.c
+++ zfcpdump-kernel-4.4/drivers/net/wireless/mwifiex/cfp.c
@@ -66,8 +66,8 @@ static u8 supported_rates_bg[BG_SUPPORTE
 					0x12, 0x16, 0x18, 0x24, 0x30, 0x48,
 					0x60, 0x6c, 0 };
 
-u16 region_code_index[MWIFIEX_MAX_REGION_CODE] = { 0x10, 0x20, 0x30,
-						0x32, 0x40, 0x41, 0xff };
+u16 region_code_index[MWIFIEX_MAX_REGION_CODE] = { 0x00, 0x10, 0x20, 0x30,
+						0x31, 0x32, 0x40, 0x41, 0x50 };
 
 static u8 supported_rates_n[N_SUPPORTED_RATES] = { 0x02, 0x04, 0 };
 
@@ -168,7 +168,7 @@ struct region_code_mapping {
 static struct region_code_mapping region_code_mapping_t[] = {
 	{ 0x10, "US " }, /* US FCC */
 	{ 0x20, "CA " }, /* IC Canada */
-	{ 0x30, "EU " }, /* ETSI */
+	{ 0x30, "FR " }, /* France */
 	{ 0x31, "ES " }, /* Spain */
 	{ 0x32, "FR " }, /* France */
 	{ 0x40, "JP " }, /* Japan */
--- zfcpdump-kernel-4.4.orig/drivers/net/wireless/mwifiex/cmdevt.c
+++ zfcpdump-kernel-4.4/drivers/net/wireless/mwifiex/cmdevt.c
@@ -1637,9 +1637,9 @@ int mwifiex_ret_get_hw_spec(struct mwifi
 		if (adapter->region_code == region_code_index[i])
 			break;
 
-	/* If it's unidentified region code, use the default (USA) */
+	/* If it's unidentified region code, use the default (world) */
 	if (i >= MWIFIEX_MAX_REGION_CODE) {
-		adapter->region_code = 0x10;
+		adapter->region_code = 0x00;
 		mwifiex_dbg(adapter, WARN,
 			    "cmd: unknown region code, use default (USA)\n");
 	}
--- zfcpdump-kernel-4.4.orig/drivers/net/wireless/mwifiex/fw.h
+++ zfcpdump-kernel-4.4/drivers/net/wireless/mwifiex/fw.h
@@ -185,6 +185,7 @@ enum MWIFIEX_802_11_PRIVACY_FILTER {
 #define TLV_TYPE_CHANNEL_STATS      (PROPRIETARY_TLV_BASE_ID + 198)
 #define TLV_BTCOEX_WL_AGGR_WINSIZE  (PROPRIETARY_TLV_BASE_ID + 202)
 #define TLV_BTCOEX_WL_SCANTIME      (PROPRIETARY_TLV_BASE_ID + 203)
+#define TLV_TYPE_LED_CONTROL        (PROPRIETARY_TLV_BASE_ID + 205)
 #define TLV_TYPE_BSS_MODE           (PROPRIETARY_TLV_BASE_ID + 206)
 
 #define MWIFIEX_TX_DATA_BUF_SIZE_2K        2048
@@ -329,6 +330,7 @@ enum MWIFIEX_802_11_PRIVACY_FILTER {
 #define HostCmd_CMD_802_11_AD_HOC_JOIN                0x002c
 #define HostCmd_CMD_802_11_AD_HOC_STOP                0x0040
 #define HostCmd_CMD_802_11_MAC_ADDRESS                0x004D
+#define HostCmd_CMD_802_11_LED_CONTROL			0X004E
 #define HostCmd_CMD_802_11D_DOMAIN_INFO               0x005b
 #define HostCmd_CMD_802_11_KEY_MATERIAL               0x005e
 #define HostCmd_CMD_802_11_BG_SCAN_QUERY              0x006c
@@ -1080,6 +1082,16 @@ struct ieee_types_oper_mode_ntf {
 	u8 oper_mode;
 } __packed;
 
+struct mwifiex_led_param {
+	__le16 mode;
+	__le16 on;
+} __packed;
+
+struct mwifiex_ie_types_led_param {
+	struct mwifiex_ie_types_header header;
+	struct mwifiex_led_param led_cfg;
+} __packed;
+
 struct host_cmd_ds_802_11_ad_hoc_start {
 	u8 ssid[IEEE80211_MAX_SSID_LEN];
 	u8 bss_mode;
@@ -1092,9 +1104,15 @@ struct host_cmd_ds_802_11_ad_hoc_start {
 	u8 data_rate[HOSTCMD_SUPPORTED_RATES];
 } __packed;
 
-struct host_cmd_ds_802_11_ad_hoc_result {
+struct host_cmd_ds_802_11_ad_hoc_start_result {
 	u8 pad[3];
 	u8 bssid[ETH_ALEN];
+	u8 pad2[2];
+	u8 result;
+} __packed;
+
+struct host_cmd_ds_802_11_ad_hoc_join_result {
+	u8 result;
 } __packed;
 
 struct adhoc_bss_desc {
@@ -1197,6 +1215,11 @@ struct host_cmd_ds_802_11_hs_cfg_enh {
 	} params;
 } __packed;
 
+struct host_cmd_ds_802_11_led_control {
+	__le16 action;
+	__le16 num_led;
+} __packed;
+
 enum SNMP_MIB_INDEX {
 	OP_RATE_SET_I = 1,
 	DTIM_PERIOD_I = 3,
@@ -1206,6 +1229,7 @@ enum SNMP_MIB_INDEX {
 	FRAG_THRESH_I = 8,
 	DOT11D_I = 9,
 	DOT11H_I = 10,
+	TURBO_MODE_I = 39,
 };
 
 enum mwifiex_assocmd_failurepoint {
@@ -2124,7 +2148,8 @@ struct host_cmd_ds_command {
 		struct host_cmd_ds_802_11_associate_rsp associate_rsp;
 		struct host_cmd_ds_802_11_deauthenticate deauth;
 		struct host_cmd_ds_802_11_ad_hoc_start adhoc_start;
-		struct host_cmd_ds_802_11_ad_hoc_result adhoc_result;
+		struct host_cmd_ds_802_11_ad_hoc_start_result start_result;
+		struct host_cmd_ds_802_11_ad_hoc_join_result join_result;
 		struct host_cmd_ds_802_11_ad_hoc_join adhoc_join;
 		struct host_cmd_ds_802_11d_domain_info domain_info;
 		struct host_cmd_ds_802_11d_domain_info_rsp domain_info_resp;
@@ -2163,6 +2188,7 @@ struct host_cmd_ds_command {
 		struct host_cmd_sdio_sp_rx_aggr_cfg sdio_rx_aggr_cfg;
 		struct host_cmd_ds_multi_chan_policy mc_policy;
 		struct host_cmd_ds_robust_coex coex;
+		struct host_cmd_ds_802_11_led_control led_cfg;
 	} params;
 } __packed;
 
--- zfcpdump-kernel-4.4.orig/drivers/net/wireless/mwifiex/ie.c
+++ zfcpdump-kernel-4.4/drivers/net/wireless/mwifiex/ie.c
@@ -140,7 +140,7 @@ mwifiex_update_autoindex_ies(struct mwif
 	if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_UAP)
 		return mwifiex_send_cmd(priv, HostCmd_CMD_UAP_SYS_CONFIG,
 					HostCmd_ACT_GEN_SET,
-					UAP_CUSTOM_IE_I, ie_list, false);
+					UAP_CUSTOM_IE_I, ie_list, true);
 
 	return 0;
 }
--- zfcpdump-kernel-4.4.orig/drivers/net/wireless/mwifiex/join.c
+++ zfcpdump-kernel-4.4/drivers/net/wireless/mwifiex/join.c
@@ -1247,20 +1247,26 @@ int mwifiex_ret_802_11_ad_hoc(struct mwi
 {
 	int ret = 0;
 	struct mwifiex_adapter *adapter = priv->adapter;
-	struct host_cmd_ds_802_11_ad_hoc_result *adhoc_result;
+	struct host_cmd_ds_802_11_ad_hoc_start_result *start_result =
+				&resp->params.start_result;
+	struct host_cmd_ds_802_11_ad_hoc_join_result *join_result =
+				&resp->params.join_result;
 	struct mwifiex_bssdescriptor *bss_desc;
-	u16 reason_code;
+	u16 cmd = le16_to_cpu(resp->command);
+	u8 result;
 
-	adhoc_result = &resp->params.adhoc_result;
+	if (cmd == HostCmd_CMD_802_11_AD_HOC_START)
+		result = start_result->result;
+	else
+		result = join_result->result;
 
 	bss_desc = priv->attempted_bss_desc;
 
 	/* Join result code 0 --> SUCCESS */
-	reason_code = le16_to_cpu(resp->result);
-	if (reason_code) {
+	if (result) {
 		mwifiex_dbg(priv->adapter, ERROR, "ADHOC_RESP: failed\n");
 		if (priv->media_connected)
-			mwifiex_reset_connect_state(priv, reason_code);
+			mwifiex_reset_connect_state(priv, result);
 
 		memset(&priv->curr_bss_params.bss_descriptor,
 		       0x00, sizeof(struct mwifiex_bssdescriptor));
@@ -1278,7 +1284,7 @@ int mwifiex_ret_802_11_ad_hoc(struct mwi
 
 		/* Update the created network descriptor with the new BSSID */
 		memcpy(bss_desc->mac_address,
-		       adhoc_result->bssid, ETH_ALEN);
+		       start_result->bssid, ETH_ALEN);
 
 		priv->adhoc_state = ADHOC_STARTED;
 	} else {
--- zfcpdump-kernel-4.4.orig/drivers/net/wireless/mwifiex/main.c
+++ zfcpdump-kernel-4.4/drivers/net/wireless/mwifiex/main.c
@@ -674,8 +674,10 @@ static int mwifiex_init_hw_fw(struct mwi
 static int
 mwifiex_open(struct net_device *dev)
 {
-	netif_carrier_off(dev);
+	struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
 
+	netif_carrier_off(dev);
+	mwifiex_set_led(priv->adapter, MWIFIEX_LED_ON);
 	return 0;
 }
 
@@ -695,6 +697,7 @@ mwifiex_close(struct net_device *dev)
 		priv->scan_aborting = true;
 	}
 
+	mwifiex_set_led(priv->adapter, MWIFIEX_LED_OFF);
 	return 0;
 }
 
--- zfcpdump-kernel-4.4.orig/drivers/net/wireless/mwifiex/main.h
+++ zfcpdump-kernel-4.4/drivers/net/wireless/mwifiex/main.h
@@ -84,7 +84,7 @@ enum {
 
 #define MWIFIEX_KEY_BUFFER_SIZE			16
 #define MWIFIEX_DEFAULT_LISTEN_INTERVAL 10
-#define MWIFIEX_MAX_REGION_CODE         7
+#define MWIFIEX_MAX_REGION_CODE         9
 
 #define DEFAULT_BCN_AVG_FACTOR          8
 #define DEFAULT_DATA_AVG_FACTOR         8
@@ -115,6 +115,10 @@ enum {
 
 #define PKT_TYPE_MGMT	0xE5
 
+#define MWIFIEX_LED_ON		1
+#define MWIFIEX_LED_OFF		0
+#define MWIFIEX_LED_MAX		3
+
 /*
  * Do not check for data_received for USB, as data_received
  * is handled in mwifiex_usb_recv for USB
@@ -667,6 +671,7 @@ struct mwifiex_private {
 	struct mwifiex_ds_mem_rw mem_rw;
 	struct sk_buff_head bypass_txq;
 	struct mwifiex_user_scan_chan hidden_chan[MWIFIEX_USER_SCAN_CHAN_MAX];
+	bool is_edge_gateway;
 };
 
 
@@ -994,6 +999,8 @@ struct mwifiex_adapter {
 	u8 active_scan_triggered;
 	bool usb_mc_status;
 	bool usb_mc_setup;
+	u8 *cfg_data;
+	int cfg_len;
 };
 
 void mwifiex_process_tx_queue(struct mwifiex_adapter *adapter);
@@ -1375,6 +1382,7 @@ int mwifiex_wait_queue_complete(struct m
 				struct cmd_ctrl_node *cmd_queued);
 int mwifiex_bss_start(struct mwifiex_private *priv, struct cfg80211_bss *bss,
 		      struct cfg80211_ssid *req_ssid);
+int mwifiex_set_led(struct mwifiex_adapter *adapter, int on);
 int mwifiex_cancel_hs(struct mwifiex_private *priv, int cmd_type);
 int mwifiex_enable_hs(struct mwifiex_adapter *adapter);
 int mwifiex_disable_auto_ds(struct mwifiex_private *priv);
@@ -1569,6 +1577,8 @@ void mwifiex_process_multi_chan_event(st
 				      struct sk_buff *event_skb);
 void mwifiex_multi_chan_resync(struct mwifiex_adapter *adapter);
 
+void marvell_set_vendor_commands(struct wiphy *wiphy);
+
 #ifdef CONFIG_DEBUG_FS
 void mwifiex_debugfs_init(void);
 void mwifiex_debugfs_remove(void);
--- zfcpdump-kernel-4.4.orig/drivers/net/wireless/mwifiex/pcie.c
+++ zfcpdump-kernel-4.4/drivers/net/wireless/mwifiex/pcie.c
@@ -17,6 +17,7 @@
  * this warranty disclaimer.
  */
 
+#include <linux/dmi.h>
 #include <linux/firmware.h>
 
 #include "decl.h"
@@ -189,6 +190,7 @@ static int mwifiex_pcie_probe(struct pci
 					const struct pci_device_id *ent)
 {
 	struct pcie_service_card *card;
+	struct mwifiex_private *priv;
 
 	pr_debug("info: vendor=0x%4.04X device=0x%4.04X rev=%d\n",
 		 pdev->vendor, pdev->device, pdev->revision);
@@ -216,6 +218,10 @@ static int mwifiex_pcie_probe(struct pci
 		return -1;
 	}
 
+	priv = mwifiex_get_priv(card->adapter, MWIFIEX_BSS_ROLE_STA);
+	if (dmi_match(DMI_PRODUCT_NAME, "Edge Gateway 5000") ||
+		dmi_match(DMI_PRODUCT_NAME, "Edge Gateway 5100"))
+		priv->is_edge_gateway = true;
 	return 0;
 }
 
--- zfcpdump-kernel-4.4.orig/drivers/net/wireless/mwifiex/sta_cmd.c
+++ zfcpdump-kernel-4.4/drivers/net/wireless/mwifiex/sta_cmd.c
@@ -393,6 +393,31 @@ mwifiex_cmd_802_11_hs_cfg(struct mwifiex
 	return 0;
 }
 
+static int mwifiex_cmd_802_11_led_cfg(struct mwifiex_private *priv,
+					struct host_cmd_ds_command *cmd,
+					u16 cmd_action,
+					struct mwifiex_led_param *ledcfg_param)
+{
+	struct host_cmd_ds_802_11_led_control *led_cfg = &cmd->params.led_cfg;
+	struct mwifiex_ie_types_led_param *led_tlv;
+	u8 *pos;
+
+	cmd->command = cpu_to_le16(HostCmd_CMD_802_11_LED_CONTROL);
+	cmd->size = cpu_to_le16(S_DS_GEN);
+	le16_add_cpu(&cmd->size, sizeof(struct host_cmd_ds_802_11_led_control));
+
+	led_cfg->action = cpu_to_le16(cmd_action);
+	led_cfg->num_led = cpu_to_le16(MWIFIEX_LED_MAX);
+
+	pos = (u8 *)led_cfg + sizeof(struct host_cmd_ds_802_11_led_control);
+	led_tlv = (void *)pos;
+	led_tlv->header.type = cpu_to_le16(TLV_TYPE_LED_CONTROL);
+	led_tlv->header.len = cpu_to_le16(sizeof(struct mwifiex_led_param));
+	memcpy(&led_tlv->led_cfg, ledcfg_param, sizeof(struct mwifiex_led_param));
+	le16_add_cpu(&cmd->size, sizeof(struct mwifiex_ie_types_led_param));
+	return 0;
+}
+
 /*
  * This function prepares command to set/get MAC address.
  *
@@ -1487,9 +1512,10 @@ static int mwifiex_cmd_cfg_data(struct m
 {
 	struct mwifiex_adapter *adapter = priv->adapter;
 	struct property *prop = data_buf;
-	u32 len;
+	u32 len = 0;
 	u8 *data = (u8 *)cmd + S_DS_GEN;
 	int ret;
+	const struct firmware *cal_data = adapter->cal_data;
 
 	if (prop) {
 		len = prop->length;
@@ -1500,11 +1526,19 @@ static int mwifiex_cmd_cfg_data(struct m
 		mwifiex_dbg(adapter, INFO,
 			    "download cfg_data from device tree: %s\n",
 			    prop->name);
-	} else if (adapter->cal_data->data && adapter->cal_data->size > 0) {
-		len = mwifiex_parse_cal_cfg((u8 *)adapter->cal_data->data,
-					    adapter->cal_data->size, data);
-		mwifiex_dbg(adapter, INFO,
-			    "download cfg_data from config file\n");
+	} else if (cal_data) {
+		if (cal_data->data && cal_data->size > 0) {
+			len = mwifiex_parse_cal_cfg((u8 *)cal_data->data,
+						    cal_data->size, data);
+			mwifiex_dbg(adapter, INFO,
+				    "download cfg_data from config file\n");
+		} else {
+			return -1;
+		}
+	} else if (adapter->cfg_data && adapter->cfg_len > 0) {
+		len = mwifiex_parse_cal_cfg(adapter->cfg_data,
+					    adapter->cfg_len, data);
+		mwifiex_dbg(adapter, INFO, "download cfg_data from iw vendor command\n");
 	} else {
 		return -1;
 	}
@@ -1870,6 +1904,10 @@ int mwifiex_sta_prepare_cmd(struct mwifi
 		ret = mwifiex_cmd_802_11_hs_cfg(priv, cmd_ptr, cmd_action,
 				(struct mwifiex_hs_config_param *) data_buf);
 		break;
+	case HostCmd_CMD_802_11_LED_CONTROL:
+		ret = mwifiex_cmd_802_11_led_cfg(priv, cmd_ptr, cmd_action,
+						data_buf);
+		break;
 	case HostCmd_CMD_802_11_SCAN:
 		ret = mwifiex_cmd_802_11_scan(cmd_ptr, data_buf);
 		break;
--- zfcpdump-kernel-4.4.orig/drivers/net/wireless/mwifiex/sta_cmdresp.c
+++ zfcpdump-kernel-4.4/drivers/net/wireless/mwifiex/sta_cmdresp.c
@@ -1238,6 +1238,8 @@ int mwifiex_process_sta_cmdresp(struct m
 	case HostCmd_CMD_ROBUST_COEX:
 		ret = mwifiex_ret_robust_coex(priv, resp, data_buf);
 		break;
+	case HostCmd_CMD_802_11_LED_CONTROL:
+		break;
 	default:
 		mwifiex_dbg(adapter, ERROR,
 			    "CMD_RESP: unknown cmd response %#x\n",
--- zfcpdump-kernel-4.4.orig/drivers/net/wireless/mwifiex/sta_ioctl.c
+++ zfcpdump-kernel-4.4/drivers/net/wireless/mwifiex/sta_ioctl.c
@@ -17,6 +17,8 @@
  * this warranty disclaimer.
  */
 
+#include <linux/dmi.h>
+
 #include "decl.h"
 #include "ioctl.h"
 #include "util.h"
@@ -272,7 +274,8 @@ int mwifiex_bss_start(struct mwifiex_pri
 	priv->scan_block = false;
 
 	if (bss) {
-		mwifiex_process_country_ie(priv, bss);
+		if (adapter->region_code == 0x00)
+			mwifiex_process_country_ie(priv, bss);
 
 		/* Allocate and fill new bss descriptor */
 		bss_desc = kzalloc(sizeof(struct mwifiex_bssdescriptor),
@@ -313,6 +316,7 @@ int mwifiex_bss_start(struct mwifiex_pri
 			mwifiex_dbg(adapter, ERROR,
 				    "Attempt to reconnect on csa closed chan(%d)\n",
 				    bss_desc->channel);
+			ret = -1;
 			goto done;
 		}
 
@@ -538,6 +542,24 @@ int mwifiex_enable_hs(struct mwifiex_ada
 }
 EXPORT_SYMBOL_GPL(mwifiex_enable_hs);
 
+int mwifiex_set_led(struct mwifiex_adapter *adapter, int on)
+{
+	struct mwifiex_private *priv;
+	struct mwifiex_led_param ledcfg;
+
+	priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA);
+	if (!priv->is_edge_gateway)
+		return -ENODEV;
+
+	memset(&ledcfg, 0, sizeof(struct mwifiex_led_param));
+	ledcfg.on = cpu_to_le16(on);
+
+	return mwifiex_send_cmd(priv,
+				HostCmd_CMD_802_11_LED_CONTROL,
+				HostCmd_ACT_GEN_SET, 0,
+				&ledcfg, true);
+}
+
 /*
  * IOCTL request handler to get BSS information.
  *
--- zfcpdump-kernel-4.4.orig/drivers/net/wireless/mwifiex/uap_cmd.c
+++ zfcpdump-kernel-4.4/drivers/net/wireless/mwifiex/uap_cmd.c
@@ -848,9 +848,9 @@ int mwifiex_config_start_uap(struct mwif
 
 	if (mwifiex_send_cmd(priv, HostCmd_CMD_UAP_SYS_CONFIG,
 			     HostCmd_ACT_GEN_SET,
-			     UAP_BSS_PARAMS_I, bss_cfg, false)) {
+			     UAP_BSS_PARAMS_I, bss_cfg, true)) {
 		mwifiex_dbg(priv->adapter, ERROR,
-			    "Failed to set the SSID\n");
+			    "Failed to set AP configuration\n");
 		return -1;
 	}
 
@@ -865,7 +865,7 @@ int mwifiex_config_start_uap(struct mwif
 	}
 
 	if (mwifiex_send_cmd(priv, HostCmd_CMD_UAP_BSS_START,
-			     HostCmd_ACT_GEN_SET, 0, NULL, false)) {
+			     HostCmd_ACT_GEN_SET, 0, NULL, true)) {
 		mwifiex_dbg(priv->adapter, ERROR,
 			    "Failed to start the BSS\n");
 		return -1;
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/net/wireless/mwifiex/vendor.c
@@ -0,0 +1,83 @@
+/* Marvell Wireless LAN device driver: TDLS handling
+ *
+ * Copyright (C) 2014, Marvell International Ltd.
+ *
+ * This software file (the "File") is distributed by Marvell International
+ * Ltd. under the terms of the GNU General Public License Version 2, June 1991
+ * (the "License").  You may use, redistribute and/or modify this File in
+ * accordance with the terms and conditions of the License, a copy of which
+ * is available on the worldwide web at
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
+ *
+ * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
+ * ARE EXPRESSLY DISCLAIMED.  The License provides additional details about
+ * this warranty disclaimer.
+ */
+
+#include <net/mac80211.h>
+#include <net/netlink.h>
+#include "vendor.h"
+#include "main.h"
+
+static int
+marvell_vendor_cmd_set_turbo_mode(struct wiphy *wiphy,
+				  struct wireless_dev *wdev,
+				  const void *data, int data_len)
+{
+	struct mwifiex_private *priv = mwifiex_netdev_get_priv(wdev->netdev);
+	u8 mode = *(u8 *)data;
+	int ret;
+
+	ret = mwifiex_send_cmd(priv, HostCmd_CMD_802_11_SNMP_MIB,
+			       HostCmd_ACT_GEN_SET, TURBO_MODE_I, &mode, true);
+
+	return 0;
+}
+
+static int
+mwifiex_vendor_cmd_set_cfg_data(struct wiphy *wiphy,
+				struct wireless_dev *wdev,
+				const void *data, int data_len)
+{
+	struct mwifiex_private *priv = mwifiex_netdev_get_priv(wdev->netdev);
+	int ret;
+
+	priv->adapter->cfg_data = (u8 *)data;
+	priv->adapter->cfg_len = data_len;
+
+	ret = mwifiex_send_cmd(priv, HostCmd_CMD_CFG_DATA,
+			       HostCmd_ACT_GEN_SET, 0, NULL, true);
+
+	priv->adapter->cfg_data = NULL;
+	priv->adapter->cfg_len = 0;
+
+	return 0;
+}
+
+static const struct wiphy_vendor_command marvell_vendor_commands[] = {
+	{
+		.info = {
+			.vendor_id = MARVELL_OUI,
+			.subcmd = MARVELL_VENDOR_CMD_SET_TURBO_MODE,
+		},
+		.flags = WIPHY_VENDOR_CMD_NEED_NETDEV |
+			 WIPHY_VENDOR_CMD_NEED_RUNNING,
+		.doit = marvell_vendor_cmd_set_turbo_mode,
+	},
+	{
+		.info = {
+			.vendor_id = MARVELL_OUI,
+			.subcmd = MARVELL_VENDOR_CMD_SET_CONF_DATA,
+		},
+		.flags = WIPHY_VENDOR_CMD_NEED_NETDEV |
+			 WIPHY_VENDOR_CMD_NEED_RUNNING,
+		.doit = mwifiex_vendor_cmd_set_cfg_data,
+	},
+};
+
+void marvell_set_vendor_commands(struct wiphy *wiphy)
+{
+	wiphy->vendor_commands = marvell_vendor_commands;
+	wiphy->n_vendor_commands = ARRAY_SIZE(marvell_vendor_commands);
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/net/wireless/mwifiex/vendor.h
@@ -0,0 +1,28 @@
+/* Marvell Wireless LAN device driver: TDLS handling
+ *
+ * Copyright (C) 2014, Marvell International Ltd.
+ *
+ * This software file (the "File") is distributed by Marvell International
+ * Ltd. under the terms of the GNU General Public License Version 2, June 1991
+ * (the "License").  You may use, redistribute and/or modify this File in
+ * accordance with the terms and conditions of the License, a copy of which
+ * is available on the worldwide web at
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
+ *
+ * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
+ * ARE EXPRESSLY DISCLAIMED.  The License provides additional details about
+ * this warranty disclaimer.
+ */
+
+#ifndef __MARVELL_VENDOR_H__
+#define __MARVELL_VENDOR_H__
+
+#define MARVELL_OUI	0x005043
+
+enum marvell_vendor_commands {
+	MARVELL_VENDOR_CMD_SET_TURBO_MODE,
+	MARVELL_VENDOR_CMD_SET_CONF_DATA,
+};
+
+#endif /* __MARVELL_VENDOR_H__ */
--- zfcpdump-kernel-4.4.orig/drivers/net/wireless/realtek/rtlwifi/base.c
+++ zfcpdump-kernel-4.4/drivers/net/wireless/realtek/rtlwifi/base.c
@@ -1660,9 +1660,9 @@ void rtl_watchdog_wq_callback(void *data
 		if (((rtlpriv->link_info.num_rx_inperiod +
 		      rtlpriv->link_info.num_tx_inperiod) > 8) ||
 		    (rtlpriv->link_info.num_rx_inperiod > 2))
-			rtl_lps_enter(hw);
-		else
 			rtl_lps_leave(hw);
+		else
+			rtl_lps_enter(hw);
 	}
 
 	rtlpriv->link_info.num_rx_inperiod = 0;
--- zfcpdump-kernel-4.4.orig/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8723b2ant.c
+++ zfcpdump-kernel-4.4/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8723b2ant.c
@@ -1203,7 +1203,6 @@ static void btc8723b2ant_set_ant_path(st
 
 		/* Force GNT_BT to low */
 		btcoexist->btc_write_1byte_bitmask(btcoexist, 0x765, 0x18, 0x0);
-		btcoexist->btc_write_2byte(btcoexist, 0x948, 0x0);
 
 		if (board_info->btdm_ant_pos == BTC_ANTENNA_AT_MAIN_PORT) {
 			/* tell firmware "no antenna inverse" */
@@ -1211,19 +1210,25 @@ static void btc8723b2ant_set_ant_path(st
 			h2c_parameter[1] = 1;  /* ext switch type */
 			btcoexist->btc_fill_h2c(btcoexist, 0x65, 2,
 						h2c_parameter);
+			btcoexist->btc_write_2byte(btcoexist, 0x948, 0x0);
 		} else {
 			/* tell firmware "antenna inverse" */
 			h2c_parameter[0] = 1;
 			h2c_parameter[1] = 1;  /* ext switch type */
 			btcoexist->btc_fill_h2c(btcoexist, 0x65, 2,
 						h2c_parameter);
+			btcoexist->btc_write_2byte(btcoexist, 0x948, 0x280);
 		}
 	}
 
 	/* ext switch setting */
 	if (use_ext_switch) {
 		/* fixed internal switch S1->WiFi, S0->BT */
-		btcoexist->btc_write_2byte(btcoexist, 0x948, 0x0);
+		if (board_info->btdm_ant_pos == BTC_ANTENNA_AT_MAIN_PORT)
+			btcoexist->btc_write_2byte(btcoexist, 0x948, 0x0);
+		else
+			btcoexist->btc_write_2byte(btcoexist, 0x948, 0x280);
+
 		switch (antpos_type) {
 		case BTC_ANT_WIFI_AT_MAIN:
 			/* ext switch main at wifi */
--- zfcpdump-kernel-4.4.orig/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtcoutsrc.c
+++ zfcpdump-kernel-4.4/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtcoutsrc.c
@@ -965,13 +965,38 @@ void exhalbtc_set_chip_type(u8 chip_type
 	}
 }
 
-void exhalbtc_set_ant_num(u8 type, u8 ant_num)
+void exhalbtc_set_ant_num(struct rtl_priv *rtlpriv, u8 type, u8 ant_num)
 {
 	if (BT_COEX_ANT_TYPE_PG == type) {
 		gl_bt_coexist.board_info.pg_ant_num = ant_num;
 		gl_bt_coexist.board_info.btdm_ant_num = ant_num;
+		/* The antenna position:
+		 * Main (default) or Aux for pgAntNum=2 && btdmAntNum =1.
+		 * The antenna position should be determined by
+		 * auto-detect mechanism.
+		 * The following is assumed to main,
+		 * and those must be modified
+		 * if y auto-detect mechanism is ready
+		 */
+		if ((gl_bt_coexist.board_info.pg_ant_num == 2) &&
+		    (gl_bt_coexist.board_info.btdm_ant_num == 1))
+			gl_bt_coexist.board_info.btdm_ant_pos =
+						       BTC_ANTENNA_AT_MAIN_PORT;
+		else
+			gl_bt_coexist.board_info.btdm_ant_pos =
+						       BTC_ANTENNA_AT_MAIN_PORT;
 	} else if (BT_COEX_ANT_TYPE_ANTDIV == type) {
 		gl_bt_coexist.board_info.btdm_ant_num = ant_num;
+		gl_bt_coexist.board_info.btdm_ant_pos =
+						       BTC_ANTENNA_AT_MAIN_PORT;
+	} else if (type == BT_COEX_ANT_TYPE_DETECTED) {
+		gl_bt_coexist.board_info.btdm_ant_num = ant_num;
+		if (rtlpriv->cfg->mod_params->ant_sel == 1)
+			gl_bt_coexist.board_info.btdm_ant_pos =
+				BTC_ANTENNA_AT_AUX_PORT;
+		else
+			gl_bt_coexist.board_info.btdm_ant_pos =
+				BTC_ANTENNA_AT_MAIN_PORT;
 	}
 }
 
--- zfcpdump-kernel-4.4.orig/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtcoutsrc.h
+++ zfcpdump-kernel-4.4/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtcoutsrc.h
@@ -535,7 +535,7 @@ void exhalbtc_set_bt_patch_version(u16 b
 void exhalbtc_update_min_bt_rssi(char bt_rssi);
 void exhalbtc_set_bt_exist(bool bt_exist);
 void exhalbtc_set_chip_type(u8 chip_type);
-void exhalbtc_set_ant_num(u8 type, u8 ant_num);
+void exhalbtc_set_ant_num(struct rtl_priv *rtlpriv, u8 type, u8 ant_num);
 void exhalbtc_display_bt_coex_info(struct btc_coexist *btcoexist);
 void exhalbtc_signal_compensation(struct btc_coexist *btcoexist,
 				  u8 *rssi_wifi, u8 *rssi_bt);
--- zfcpdump-kernel-4.4.orig/drivers/net/wireless/realtek/rtlwifi/btcoexist/rtl_btc.c
+++ zfcpdump-kernel-4.4/drivers/net/wireless/realtek/rtlwifi/btcoexist/rtl_btc.c
@@ -72,7 +72,10 @@ void rtl_btc_init_hal_vars(struct rtl_pr
 		 __func__, bt_type);
 	exhalbtc_set_chip_type(bt_type);
 
-	exhalbtc_set_ant_num(BT_COEX_ANT_TYPE_PG, ant_num);
+	if (rtlpriv->cfg->mod_params->ant_sel == 1)
+		exhalbtc_set_ant_num(rtlpriv, BT_COEX_ANT_TYPE_DETECTED, 1);
+	else
+		exhalbtc_set_ant_num(rtlpriv, BT_COEX_ANT_TYPE_PG, ant_num);
 }
 
 void rtl_btc_init_hw_config(struct rtl_priv *rtlpriv)
--- zfcpdump-kernel-4.4.orig/drivers/net/wireless/realtek/rtlwifi/pci.c
+++ zfcpdump-kernel-4.4/drivers/net/wireless/realtek/rtlwifi/pci.c
@@ -801,7 +801,9 @@ static void _rtl_pci_rx_interrupt(struct
 								      hw_queue);
 			if (rx_remained_cnt == 0)
 				return;
-
+			buffer_desc = &rtlpci->rx_ring[rxring_idx].buffer_desc[
+				rtlpci->rx_ring[rxring_idx].idx];
+			pdesc = (struct rtl_rx_desc *)skb->data;
 		} else {	/* rx descriptor */
 			pdesc = &rtlpci->rx_ring[rxring_idx].desc[
 				rtlpci->rx_ring[rxring_idx].idx];
@@ -824,13 +826,6 @@ static void _rtl_pci_rx_interrupt(struct
 		new_skb = dev_alloc_skb(rtlpci->rxbuffersize);
 		if (unlikely(!new_skb))
 			goto no_new;
-		if (rtlpriv->use_new_trx_flow) {
-			buffer_desc =
-			  &rtlpci->rx_ring[rxring_idx].buffer_desc
-				[rtlpci->rx_ring[rxring_idx].idx];
-			/*means rx wifi info*/
-			pdesc = (struct rtl_rx_desc *)skb->data;
-		}
 		memset(&rx_status , 0 , sizeof(rx_status));
 		rtlpriv->cfg->ops->query_rx_desc(hw, &stats,
 						 &rx_status, (u8 *)pdesc, skb);
@@ -1578,7 +1573,7 @@ int rtl_pci_reset_trx_ring(struct ieee80
 							 true,
 							 HW_DESC_TXBUFF_ADDR),
 						 skb->len, PCI_DMA_TODEVICE);
-				kfree_skb(skb);
+				dev_kfree_skb_irq(skb);
 				ring->idx = (ring->idx + 1) % ring->entries;
 			}
 			ring->idx = 0;
--- zfcpdump-kernel-4.4.orig/drivers/net/wireless/realtek/rtlwifi/regd.c
+++ zfcpdump-kernel-4.4/drivers/net/wireless/realtek/rtlwifi/regd.c
@@ -351,7 +351,6 @@ static const struct ieee80211_regdomain
 	case COUNTRY_CODE_SPAIN:
 	case COUNTRY_CODE_FRANCE:
 	case COUNTRY_CODE_ISRAEL:
-	case COUNTRY_CODE_WORLD_WIDE_13:
 		return &rtl_regdom_12_13;
 	case COUNTRY_CODE_MKK:
 	case COUNTRY_CODE_MKK1:
@@ -360,6 +359,7 @@ static const struct ieee80211_regdomain
 		return &rtl_regdom_14_60_64;
 	case COUNTRY_CODE_GLOBAL_DOMAIN:
 		return &rtl_regdom_14;
+	case COUNTRY_CODE_WORLD_WIDE_13:
 	case COUNTRY_CODE_WORLD_WIDE_13_5G_ALL:
 		return &rtl_regdom_12_13_5g_all;
 	default:
--- zfcpdump-kernel-4.4.orig/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/sw.c
+++ zfcpdump-kernel-4.4/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/sw.c
@@ -88,8 +88,6 @@ int rtl88e_init_sw_vars(struct ieee80211
 	u8 tid;
 
 	rtl8188ee_bt_reg_init(hw);
-	rtlpci->msi_support = rtlpriv->cfg->mod_params->msi_support;
-
 	rtlpriv->dm.dm_initialgain_enable = 1;
 	rtlpriv->dm.dm_flag = 0;
 	rtlpriv->dm.disable_framebursting = 0;
@@ -138,6 +136,11 @@ int rtl88e_init_sw_vars(struct ieee80211
 	rtlpriv->psc.inactiveps = rtlpriv->cfg->mod_params->inactiveps;
 	rtlpriv->psc.swctrl_lps = rtlpriv->cfg->mod_params->swctrl_lps;
 	rtlpriv->psc.fwctrl_lps = rtlpriv->cfg->mod_params->fwctrl_lps;
+	rtlpci->msi_support = rtlpriv->cfg->mod_params->msi_support;
+	rtlpriv->cfg->mod_params->sw_crypto =
+		rtlpriv->cfg->mod_params->sw_crypto;
+	rtlpriv->cfg->mod_params->disable_watchdog =
+		rtlpriv->cfg->mod_params->disable_watchdog;
 	if (rtlpriv->cfg->mod_params->disable_watchdog)
 		pr_info("watchdog disabled\n");
 	if (!rtlpriv->psc.inactiveps)
--- zfcpdump-kernel-4.4.orig/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/sw.c
+++ zfcpdump-kernel-4.4/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/sw.c
@@ -139,6 +139,8 @@ int rtl92c_init_sw_vars(struct ieee80211
 	rtlpriv->psc.inactiveps = rtlpriv->cfg->mod_params->inactiveps;
 	rtlpriv->psc.swctrl_lps = rtlpriv->cfg->mod_params->swctrl_lps;
 	rtlpriv->psc.fwctrl_lps = rtlpriv->cfg->mod_params->fwctrl_lps;
+	rtlpriv->cfg->mod_params->sw_crypto =
+		rtlpriv->cfg->mod_params->sw_crypto;
 	if (!rtlpriv->psc.inactiveps)
 		pr_info("rtl8192ce: Power Save off (module option)\n");
 	if (!rtlpriv->psc.fwctrl_lps)
--- zfcpdump-kernel-4.4.orig/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/sw.c
+++ zfcpdump-kernel-4.4/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/sw.c
@@ -65,6 +65,8 @@ static int rtl92cu_init_sw_vars(struct i
 	rtlpriv->dm.disable_framebursting = false;
 	rtlpriv->dm.thermalvalue = 0;
 	rtlpriv->dbg.global_debuglevel = rtlpriv->cfg->mod_params->debug;
+	rtlpriv->cfg->mod_params->sw_crypto =
+		rtlpriv->cfg->mod_params->sw_crypto;
 
 	/* for firmware buf */
 	rtlpriv->rtlhal.pfirmware = vzalloc(0x4000);
--- zfcpdump-kernel-4.4.orig/drivers/net/wireless/realtek/rtlwifi/rtl8192de/sw.c
+++ zfcpdump-kernel-4.4/drivers/net/wireless/realtek/rtlwifi/rtl8192de/sw.c
@@ -376,8 +376,8 @@ module_param_named(swlps, rtl92de_mod_pa
 module_param_named(fwlps, rtl92de_mod_params.fwctrl_lps, bool, 0444);
 MODULE_PARM_DESC(swenc, "Set to 1 for software crypto (default 0)\n");
 MODULE_PARM_DESC(ips, "Set to 0 to not use link power save (default 1)\n");
-MODULE_PARM_DESC(swlps, "Set to 1 to use SW control power save (default 0)\n");
-MODULE_PARM_DESC(fwlps, "Set to 1 to use FW control power save (default 1)\n");
+MODULE_PARM_DESC(swlps, "Set to 1 to use SW control power save (default 1)\n");
+MODULE_PARM_DESC(fwlps, "Set to 1 to use FW control power save (default 0)\n");
 MODULE_PARM_DESC(debug, "Set debug level (0-5) (default 0)");
 
 static SIMPLE_DEV_PM_OPS(rtlwifi_pm_ops, rtl_pci_suspend, rtl_pci_resume);
--- zfcpdump-kernel-4.4.orig/drivers/net/wireless/realtek/rtlwifi/rtl8192se/sw.c
+++ zfcpdump-kernel-4.4/drivers/net/wireless/realtek/rtlwifi/rtl8192se/sw.c
@@ -187,6 +187,8 @@ static int rtl92s_init_sw_vars(struct ie
 	rtlpriv->psc.inactiveps = rtlpriv->cfg->mod_params->inactiveps;
 	rtlpriv->psc.swctrl_lps = rtlpriv->cfg->mod_params->swctrl_lps;
 	rtlpriv->psc.fwctrl_lps = rtlpriv->cfg->mod_params->fwctrl_lps;
+	rtlpriv->cfg->mod_params->sw_crypto =
+		rtlpriv->cfg->mod_params->sw_crypto;
 	if (!rtlpriv->psc.inactiveps)
 		pr_info("Power Save off (module option)\n");
 	if (!rtlpriv->psc.fwctrl_lps)
@@ -425,8 +427,8 @@ module_param_named(swlps, rtl92se_mod_pa
 module_param_named(fwlps, rtl92se_mod_params.fwctrl_lps, bool, 0444);
 MODULE_PARM_DESC(swenc, "Set to 1 for software crypto (default 0)\n");
 MODULE_PARM_DESC(ips, "Set to 0 to not use link power save (default 1)\n");
-MODULE_PARM_DESC(swlps, "Set to 1 to use SW control power save (default 0)\n");
-MODULE_PARM_DESC(fwlps, "Set to 1 to use FW control power save (default 1)\n");
+MODULE_PARM_DESC(swlps, "Set to 1 to use SW control power save (default 1)\n");
+MODULE_PARM_DESC(fwlps, "Set to 1 to use FW control power save (default 0)\n");
 MODULE_PARM_DESC(debug, "Set debug level (0-5) (default 0)");
 
 static SIMPLE_DEV_PM_OPS(rtlwifi_pm_ops, rtl_pci_suspend, rtl_pci_resume);
--- zfcpdump-kernel-4.4.orig/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/sw.c
+++ zfcpdump-kernel-4.4/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/sw.c
@@ -150,6 +150,11 @@ int rtl8723e_init_sw_vars(struct ieee802
 	rtlpriv->psc.inactiveps = rtlpriv->cfg->mod_params->inactiveps;
 	rtlpriv->psc.swctrl_lps = rtlpriv->cfg->mod_params->swctrl_lps;
 	rtlpriv->psc.fwctrl_lps = rtlpriv->cfg->mod_params->fwctrl_lps;
+	rtlpci->msi_support = rtlpriv->cfg->mod_params->msi_support;
+	rtlpriv->cfg->mod_params->sw_crypto =
+		rtlpriv->cfg->mod_params->sw_crypto;
+	rtlpriv->cfg->mod_params->disable_watchdog =
+		rtlpriv->cfg->mod_params->disable_watchdog;
 	if (rtlpriv->cfg->mod_params->disable_watchdog)
 		pr_info("watchdog disabled\n");
 	rtlpriv->psc.reg_fwctrl_lps = 3;
@@ -267,6 +272,8 @@ static struct rtl_mod_params rtl8723e_mo
 	.swctrl_lps = false,
 	.fwctrl_lps = true,
 	.debug = DBG_EMERG,
+	.msi_support = false,
+	.disable_watchdog = false,
 };
 
 static struct rtl_hal_cfg rtl8723e_hal_cfg = {
@@ -383,12 +390,14 @@ module_param_named(debug, rtl8723e_mod_p
 module_param_named(ips, rtl8723e_mod_params.inactiveps, bool, 0444);
 module_param_named(swlps, rtl8723e_mod_params.swctrl_lps, bool, 0444);
 module_param_named(fwlps, rtl8723e_mod_params.fwctrl_lps, bool, 0444);
+module_param_named(msi, rtl8723e_mod_params.msi_support, bool, 0444);
 module_param_named(disable_watchdog, rtl8723e_mod_params.disable_watchdog,
 		   bool, 0444);
 MODULE_PARM_DESC(swenc, "Set to 1 for software crypto (default 0)\n");
 MODULE_PARM_DESC(ips, "Set to 0 to not use link power save (default 1)\n");
 MODULE_PARM_DESC(swlps, "Set to 1 to use SW control power save (default 0)\n");
 MODULE_PARM_DESC(fwlps, "Set to 1 to use FW control power save (default 1)\n");
+MODULE_PARM_DESC(msi, "Set to 1 to use MSI interrupts mode (default 0)\n");
 MODULE_PARM_DESC(debug, "Set debug level (0-5) (default 0)");
 MODULE_PARM_DESC(disable_watchdog, "Set to 1 to disable the watchdog (default 0)\n");
 
--- zfcpdump-kernel-4.4.orig/drivers/net/wireless/realtek/rtlwifi/rtl8723be/hw.c
+++ zfcpdump-kernel-4.4/drivers/net/wireless/realtek/rtlwifi/rtl8723be/hw.c
@@ -2684,6 +2684,7 @@ void rtl8723be_read_bt_coexist_info_from
 					      bool auto_load_fail, u8 *hwinfo)
 {
 	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	struct rtl_mod_params *mod_params = rtlpriv->cfg->mod_params;
 	u8 value;
 	u32 tmpu_32;
 
@@ -2702,6 +2703,10 @@ void rtl8723be_read_bt_coexist_info_from
 		rtlpriv->btcoexist.btc_info.ant_num = ANT_X2;
 	}
 
+	/* override ant_num / ant_path */
+	if (mod_params->ant_sel)
+		rtlpriv->btcoexist.btc_info.ant_num =
+			(mod_params->ant_sel == 1 ? ANT_X2 : ANT_X1);
 }
 
 void rtl8723be_bt_reg_init(struct ieee80211_hw *hw)
--- zfcpdump-kernel-4.4.orig/drivers/net/wireless/realtek/rtlwifi/rtl8723be/sw.c
+++ zfcpdump-kernel-4.4/drivers/net/wireless/realtek/rtlwifi/rtl8723be/sw.c
@@ -93,7 +93,6 @@ int rtl8723be_init_sw_vars(struct ieee80
 	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
 
 	rtl8723be_bt_reg_init(hw);
-	rtlpci->msi_support = rtlpriv->cfg->mod_params->msi_support;
 	rtlpriv->btcoexist.btc_ops = rtl_btc_get_ops_pointer();
 
 	rtlpriv->dm.dm_initialgain_enable = 1;
@@ -151,6 +150,10 @@ int rtl8723be_init_sw_vars(struct ieee80
 	rtlpriv->psc.swctrl_lps = rtlpriv->cfg->mod_params->swctrl_lps;
 	rtlpriv->psc.fwctrl_lps = rtlpriv->cfg->mod_params->fwctrl_lps;
 	rtlpci->msi_support = rtlpriv->cfg->mod_params->msi_support;
+	rtlpriv->cfg->mod_params->sw_crypto =
+		 rtlpriv->cfg->mod_params->sw_crypto;
+	rtlpriv->cfg->mod_params->disable_watchdog =
+		 rtlpriv->cfg->mod_params->disable_watchdog;
 	if (rtlpriv->cfg->mod_params->disable_watchdog)
 		pr_info("watchdog disabled\n");
 	rtlpriv->psc.reg_fwctrl_lps = 3;
@@ -267,6 +270,10 @@ static struct rtl_mod_params rtl8723be_m
 	.inactiveps = true,
 	.swctrl_lps = false,
 	.fwctrl_lps = true,
+	.msi_support = false,
+	.disable_watchdog = false,
+	.debug = DBG_EMERG,
+	.ant_sel = 0,
 };
 
 static struct rtl_hal_cfg rtl8723be_hal_cfg = {
@@ -388,6 +395,7 @@ module_param_named(fwlps, rtl8723be_mod_
 module_param_named(msi, rtl8723be_mod_params.msi_support, bool, 0444);
 module_param_named(disable_watchdog, rtl8723be_mod_params.disable_watchdog,
 		   bool, 0444);
+module_param_named(ant_sel, rtl8723be_mod_params.ant_sel, int, 0444);
 MODULE_PARM_DESC(swenc, "Set to 1 for software crypto (default 0)\n");
 MODULE_PARM_DESC(ips, "Set to 0 to not use link power save (default 1)\n");
 MODULE_PARM_DESC(swlps, "Set to 1 to use SW control power save (default 0)\n");
@@ -396,6 +404,7 @@ MODULE_PARM_DESC(msi, "Set to 1 to use M
 MODULE_PARM_DESC(debug, "Set debug level (0-5) (default 0)");
 MODULE_PARM_DESC(disable_watchdog,
 		 "Set to 1 to disable the watchdog (default 0)\n");
+MODULE_PARM_DESC(ant_sel, "Set to 1 or 2 to force antenna number (default 0)\n");
 
 static SIMPLE_DEV_PM_OPS(rtlwifi_pm_ops, rtl_pci_suspend, rtl_pci_resume);
 
--- zfcpdump-kernel-4.4.orig/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/sw.c
+++ zfcpdump-kernel-4.4/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/sw.c
@@ -95,8 +95,6 @@ int rtl8821ae_init_sw_vars(struct ieee80
 	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
 
 	rtl8821ae_bt_reg_init(hw);
-	rtlpci->msi_support = rtlpriv->cfg->mod_params->msi_support;
-	rtlpci->int_clear = rtlpriv->cfg->mod_params->int_clear;
 	rtlpriv->btcoexist.btc_ops = rtl_btc_get_ops_pointer();
 
 	rtlpriv->dm.dm_initialgain_enable = 1;
@@ -168,12 +166,15 @@ int rtl8821ae_init_sw_vars(struct ieee80
 	rtlpriv->psc.swctrl_lps = rtlpriv->cfg->mod_params->swctrl_lps;
 	rtlpriv->psc.fwctrl_lps = rtlpriv->cfg->mod_params->fwctrl_lps;
 	rtlpci->msi_support = rtlpriv->cfg->mod_params->msi_support;
-	rtlpci->msi_support = rtlpriv->cfg->mod_params->int_clear;
+	rtlpci->int_clear = rtlpriv->cfg->mod_params->int_clear;
+	rtlpriv->cfg->mod_params->sw_crypto =
+		rtlpriv->cfg->mod_params->sw_crypto;
+	rtlpriv->cfg->mod_params->disable_watchdog =
+		rtlpriv->cfg->mod_params->disable_watchdog;
 	if (rtlpriv->cfg->mod_params->disable_watchdog)
 		pr_info("watchdog disabled\n");
 	rtlpriv->psc.reg_fwctrl_lps = 3;
 	rtlpriv->psc.reg_max_lps_awakeintvl = 5;
-	rtlpci->msi_support = rtlpriv->cfg->mod_params->msi_support;
 
 	/* for ASPM, you can close aspm through
 	 * set const_support_pciaspm = 0
--- zfcpdump-kernel-4.4.orig/drivers/net/wireless/realtek/rtlwifi/usb.c
+++ zfcpdump-kernel-4.4/drivers/net/wireless/realtek/rtlwifi/usb.c
@@ -531,6 +531,8 @@ static void _rtl_usb_rx_process_noagg(st
 			ieee80211_rx(hw, skb);
 		else
 			dev_kfree_skb_any(skb);
+	} else {
+		dev_kfree_skb_any(skb);
 	}
 }
 
--- zfcpdump-kernel-4.4.orig/drivers/net/wireless/realtek/rtlwifi/wifi.h
+++ zfcpdump-kernel-4.4/drivers/net/wireless/realtek/rtlwifi/wifi.h
@@ -2252,6 +2252,9 @@ struct rtl_mod_params {
 
 	/* default 0: 1 means do not disable interrupts */
 	bool int_clear;
+
+	/* select antenna */
+	int ant_sel;
 };
 
 struct rtl_hal_usbint_cfg {
--- zfcpdump-kernel-4.4.orig/drivers/net/wireless/ti/wlcore/io.h
+++ zfcpdump-kernel-4.4/drivers/net/wireless/ti/wlcore/io.h
@@ -207,19 +207,23 @@ static inline int __must_check wlcore_wr
 
 static inline void wl1271_power_off(struct wl1271 *wl)
 {
-	int ret;
+	int ret = 0;
 
 	if (!test_bit(WL1271_FLAG_GPIO_POWER, &wl->flags))
 		return;
 
-	ret = wl->if_ops->power(wl->dev, false);
+	if (wl->if_ops->power)
+		ret = wl->if_ops->power(wl->dev, false);
 	if (!ret)
 		clear_bit(WL1271_FLAG_GPIO_POWER, &wl->flags);
 }
 
 static inline int wl1271_power_on(struct wl1271 *wl)
 {
-	int ret = wl->if_ops->power(wl->dev, true);
+	int ret = 0;
+
+	if (wl->if_ops->power)
+		ret = wl->if_ops->power(wl->dev, true);
 	if (ret == 0)
 		set_bit(WL1271_FLAG_GPIO_POWER, &wl->flags);
 
--- zfcpdump-kernel-4.4.orig/drivers/net/wireless/ti/wlcore/spi.c
+++ zfcpdump-kernel-4.4/drivers/net/wireless/ti/wlcore/spi.c
@@ -73,7 +73,10 @@
  */
 #define SPI_AGGR_BUFFER_SIZE (4 * PAGE_SIZE)
 
-#define WSPI_MAX_NUM_OF_CHUNKS (SPI_AGGR_BUFFER_SIZE / WSPI_MAX_CHUNK_SIZE)
+/* Maximum number of SPI write chunks */
+#define WSPI_MAX_NUM_OF_CHUNKS \
+	((SPI_AGGR_BUFFER_SIZE / WSPI_MAX_CHUNK_SIZE) + 1)
+
 
 struct wl12xx_spi_glue {
 	struct device *dev;
@@ -268,9 +271,10 @@ static int __must_check wl12xx_spi_raw_w
 					     void *buf, size_t len, bool fixed)
 {
 	struct wl12xx_spi_glue *glue = dev_get_drvdata(child->parent);
-	struct spi_transfer t[2 * (WSPI_MAX_NUM_OF_CHUNKS + 1)];
+	/* SPI write buffers - 2 for each chunk */
+	struct spi_transfer t[2 * WSPI_MAX_NUM_OF_CHUNKS];
 	struct spi_message m;
-	u32 commands[WSPI_MAX_NUM_OF_CHUNKS];
+	u32 commands[WSPI_MAX_NUM_OF_CHUNKS]; /* 1 command per chunk */
 	u32 *cmd;
 	u32 chunk_len;
 	int i;
--- zfcpdump-kernel-4.4.orig/drivers/nfc/fdp/fdp.c
+++ zfcpdump-kernel-4.4/drivers/nfc/fdp/fdp.c
@@ -352,7 +352,7 @@ static int fdp_nci_patch_otp(struct nci_
 {
 	struct fdp_nci_info *info = nci_get_drvdata(ndev);
 	struct device *dev = &info->phy->i2c_dev->dev;
-	u8 conn_id;
+	int conn_id;
 	int r = 0;
 
 	if (info->otp_version >= info->otp_patch_version)
@@ -423,7 +423,7 @@ static int fdp_nci_patch_ram(struct nci_
 {
 	struct fdp_nci_info *info = nci_get_drvdata(ndev);
 	struct device *dev = &info->phy->i2c_dev->dev;
-	u8 conn_id;
+	int conn_id;
 	int r = 0;
 
 	if (info->ram_version >= info->ram_patch_version)
--- zfcpdump-kernel-4.4.orig/drivers/ntb/hw/Kconfig
+++ zfcpdump-kernel-4.4/drivers/ntb/hw/Kconfig
@@ -1 +1,2 @@
+source "drivers/ntb/hw/amd/Kconfig"
 source "drivers/ntb/hw/intel/Kconfig"
--- zfcpdump-kernel-4.4.orig/drivers/ntb/hw/Makefile
+++ zfcpdump-kernel-4.4/drivers/ntb/hw/Makefile
@@ -1 +1,2 @@
+obj-$(CONFIG_NTB_AMD)	+= amd/
 obj-$(CONFIG_NTB_INTEL)	+= intel/
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/ntb/hw/amd/Kconfig
@@ -0,0 +1,7 @@
+config NTB_AMD
+	tristate "AMD Non-Transparent Bridge support"
+	depends on X86_64
+	help
+	 This driver supports AMD NTB on capable Zeppelin hardware.
+
+	 If unsure, say N.
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/ntb/hw/amd/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_NTB_AMD) += ntb_hw_amd.o
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/ntb/hw/amd/ntb_hw_amd.c
@@ -0,0 +1,1143 @@
+/*
+ * This file is provided under a dual BSD/GPLv2 license.  When using or
+ *   redistributing this file, you may do so under either license.
+ *
+ *   GPL LICENSE SUMMARY
+ *
+ *   Copyright (C) 2016 Advanced Micro Devices, Inc. All Rights Reserved.
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of version 2 of the GNU General Public License as
+ *   published by the Free Software Foundation.
+ *
+ *   BSD LICENSE
+ *
+ *   Copyright (C) 2016 Advanced Micro Devices, Inc. All Rights Reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copy
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of AMD Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * AMD PCIe NTB Linux driver
+ *
+ * Contact Information:
+ * Xiangliang Yu <Xiangliang.Yu@amd.com>
+ */
+
+#include <linux/debugfs.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/acpi.h>
+#include <linux/pci.h>
+#include <linux/random.h>
+#include <linux/slab.h>
+#include <linux/ntb.h>
+
+#include "ntb_hw_amd.h"
+
+#define NTB_NAME	"ntb_hw_amd"
+#define NTB_DESC	"AMD(R) PCI-E Non-Transparent Bridge Driver"
+#define NTB_VER		"1.0"
+
+MODULE_DESCRIPTION(NTB_DESC);
+MODULE_VERSION(NTB_VER);
+MODULE_LICENSE("Dual BSD/GPL");
+MODULE_AUTHOR("AMD Inc.");
+
+static const struct file_operations amd_ntb_debugfs_info;
+static struct dentry *debugfs_dir;
+
+static int ndev_mw_to_bar(struct amd_ntb_dev *ndev, int idx)
+{
+	if (idx < 0 || idx > ndev->mw_count)
+		return -EINVAL;
+
+	return 1 << idx;
+}
+
+static int amd_ntb_mw_count(struct ntb_dev *ntb)
+{
+	return ntb_ndev(ntb)->mw_count;
+}
+
+static int amd_ntb_mw_get_range(struct ntb_dev *ntb, int idx,
+				phys_addr_t *base,
+				resource_size_t *size,
+				resource_size_t *align,
+				resource_size_t *align_size)
+{
+	struct amd_ntb_dev *ndev = ntb_ndev(ntb);
+	int bar;
+
+	bar = ndev_mw_to_bar(ndev, idx);
+	if (bar < 0)
+		return bar;
+
+	if (base)
+		*base = pci_resource_start(ndev->ntb.pdev, bar);
+
+	if (size)
+		*size = pci_resource_len(ndev->ntb.pdev, bar);
+
+	if (align)
+		*align = SZ_4K;
+
+	if (align_size)
+		*align_size = 1;
+
+	return 0;
+}
+
+static int amd_ntb_mw_set_trans(struct ntb_dev *ntb, int idx,
+				dma_addr_t addr, resource_size_t size)
+{
+	struct amd_ntb_dev *ndev = ntb_ndev(ntb);
+	unsigned long xlat_reg, limit_reg = 0;
+	resource_size_t mw_size;
+	void __iomem *mmio, *peer_mmio;
+	u64 base_addr, limit, reg_val;
+	int bar;
+
+	bar = ndev_mw_to_bar(ndev, idx);
+	if (bar < 0)
+		return bar;
+
+	mw_size = pci_resource_len(ndev->ntb.pdev, bar);
+
+	/* make sure the range fits in the usable mw size */
+	if (size > mw_size)
+		return -EINVAL;
+
+	mmio = ndev->self_mmio;
+	peer_mmio = ndev->peer_mmio;
+
+	base_addr = pci_resource_start(ndev->ntb.pdev, bar);
+
+	if (bar != 1) {
+		xlat_reg = AMD_BAR23XLAT_OFFSET + ((bar - 2) << 3);
+		limit_reg = AMD_BAR23LMT_OFFSET + ((bar - 2) << 3);
+
+		/* Set the limit if supported */
+		limit = base_addr + size;
+
+		/* set and verify setting the translation address */
+		write64(addr, peer_mmio + xlat_reg);
+		reg_val = read64(peer_mmio + xlat_reg);
+		if (reg_val != addr) {
+			write64(0, peer_mmio + xlat_reg);
+			return -EIO;
+		}
+
+		/* set and verify setting the limit */
+		write64(limit, mmio + limit_reg);
+		reg_val = read64(mmio + limit_reg);
+		if (reg_val != limit) {
+			write64(base_addr, mmio + limit_reg);
+			write64(0, peer_mmio + xlat_reg);
+			return -EIO;
+		}
+	} else {
+		xlat_reg = AMD_BAR1XLAT_OFFSET;
+		limit_reg = AMD_BAR1LMT_OFFSET;
+
+		/* split bar addr range must all be 32 bit */
+		if (addr & (~0ull << 32))
+			return -EINVAL;
+		if ((addr + size) & (~0ull << 32))
+			return -EINVAL;
+
+		/* Set the limit if supported */
+		limit = base_addr + size;
+
+		/* set and verify setting the translation address */
+		write64(addr, peer_mmio + xlat_reg);
+		reg_val = read64(peer_mmio + xlat_reg);
+		if (reg_val != addr) {
+			write64(0, peer_mmio + xlat_reg);
+			return -EIO;
+		}
+
+		/* set and verify setting the limit */
+		writel(limit, mmio + limit_reg);
+		reg_val = readl(mmio + limit_reg);
+		if (reg_val != limit) {
+			writel(base_addr, mmio + limit_reg);
+			writel(0, peer_mmio + xlat_reg);
+			return -EIO;
+		}
+	}
+
+	return 0;
+}
+
+static int amd_link_is_up(struct amd_ntb_dev *ndev)
+{
+	if (!ndev->peer_sta)
+		return NTB_LNK_STA_ACTIVE(ndev->cntl_sta);
+
+	/* If peer_sta is reset or D0 event, the ISR has
+	 * started a timer to check link status of hardware.
+	 * So here just clear status bit. And if peer_sta is
+	 * D3 or PME_TO, D0/reset event will be happened when
+	 * system wakeup/poweron, so do nothing here.
+	 */
+	if (ndev->peer_sta & AMD_PEER_RESET_EVENT)
+		ndev->peer_sta &= ~AMD_PEER_RESET_EVENT;
+	else if (ndev->peer_sta & AMD_PEER_D0_EVENT)
+		ndev->peer_sta = 0;
+
+	return 0;
+}
+
+static int amd_ntb_link_is_up(struct ntb_dev *ntb,
+			      enum ntb_speed *speed,
+			      enum ntb_width *width)
+{
+	struct amd_ntb_dev *ndev = ntb_ndev(ntb);
+	int ret = 0;
+
+	if (amd_link_is_up(ndev)) {
+		if (speed)
+			*speed = NTB_LNK_STA_SPEED(ndev->lnk_sta);
+		if (width)
+			*width = NTB_LNK_STA_WIDTH(ndev->lnk_sta);
+
+		dev_dbg(ndev_dev(ndev), "link is up.\n");
+
+		ret = 1;
+	} else {
+		if (speed)
+			*speed = NTB_SPEED_NONE;
+		if (width)
+			*width = NTB_WIDTH_NONE;
+
+		dev_dbg(ndev_dev(ndev), "link is down.\n");
+	}
+
+	return ret;
+}
+
+static int amd_ntb_link_enable(struct ntb_dev *ntb,
+			       enum ntb_speed max_speed,
+			       enum ntb_width max_width)
+{
+	struct amd_ntb_dev *ndev = ntb_ndev(ntb);
+	void __iomem *mmio = ndev->self_mmio;
+	u32 ntb_ctl;
+
+	/* Enable event interrupt */
+	ndev->int_mask &= ~AMD_EVENT_INTMASK;
+	writel(ndev->int_mask, mmio + AMD_INTMASK_OFFSET);
+
+	if (ndev->ntb.topo == NTB_TOPO_SEC)
+		return -EINVAL;
+	dev_dbg(ndev_dev(ndev), "Enabling Link.\n");
+
+	ntb_ctl = readl(mmio + AMD_CNTL_OFFSET);
+	ntb_ctl |= (PMM_REG_CTL | SMM_REG_CTL);
+	writel(ntb_ctl, mmio + AMD_CNTL_OFFSET);
+
+	return 0;
+}
+
+static int amd_ntb_link_disable(struct ntb_dev *ntb)
+{
+	struct amd_ntb_dev *ndev = ntb_ndev(ntb);
+	void __iomem *mmio = ndev->self_mmio;
+	u32 ntb_ctl;
+
+	/* Disable event interrupt */
+	ndev->int_mask |= AMD_EVENT_INTMASK;
+	writel(ndev->int_mask, mmio + AMD_INTMASK_OFFSET);
+
+	if (ndev->ntb.topo == NTB_TOPO_SEC)
+		return -EINVAL;
+	dev_dbg(ndev_dev(ndev), "Enabling Link.\n");
+
+	ntb_ctl = readl(mmio + AMD_CNTL_OFFSET);
+	ntb_ctl &= ~(PMM_REG_CTL | SMM_REG_CTL);
+	writel(ntb_ctl, mmio + AMD_CNTL_OFFSET);
+
+	return 0;
+}
+
+static u64 amd_ntb_db_valid_mask(struct ntb_dev *ntb)
+{
+	return ntb_ndev(ntb)->db_valid_mask;
+}
+
+static int amd_ntb_db_vector_count(struct ntb_dev *ntb)
+{
+	return ntb_ndev(ntb)->db_count;
+}
+
+static u64 amd_ntb_db_vector_mask(struct ntb_dev *ntb, int db_vector)
+{
+	struct amd_ntb_dev *ndev = ntb_ndev(ntb);
+
+	if (db_vector < 0 || db_vector > ndev->db_count)
+		return 0;
+
+	return ntb_ndev(ntb)->db_valid_mask & (1 << db_vector);
+}
+
+static u64 amd_ntb_db_read(struct ntb_dev *ntb)
+{
+	struct amd_ntb_dev *ndev = ntb_ndev(ntb);
+	void __iomem *mmio = ndev->self_mmio;
+
+	return (u64)readw(mmio + AMD_DBSTAT_OFFSET);
+}
+
+static int amd_ntb_db_clear(struct ntb_dev *ntb, u64 db_bits)
+{
+	struct amd_ntb_dev *ndev = ntb_ndev(ntb);
+	void __iomem *mmio = ndev->self_mmio;
+
+	writew((u16)db_bits, mmio + AMD_DBSTAT_OFFSET);
+
+	return 0;
+}
+
+static int amd_ntb_db_set_mask(struct ntb_dev *ntb, u64 db_bits)
+{
+	struct amd_ntb_dev *ndev = ntb_ndev(ntb);
+	void __iomem *mmio = ndev->self_mmio;
+	unsigned long flags;
+
+	if (db_bits & ~ndev->db_valid_mask)
+		return -EINVAL;
+
+	spin_lock_irqsave(&ndev->db_mask_lock, flags);
+	ndev->db_mask |= db_bits;
+	writew((u16)ndev->db_mask, mmio + AMD_DBMASK_OFFSET);
+	spin_unlock_irqrestore(&ndev->db_mask_lock, flags);
+
+	return 0;
+}
+
+static int amd_ntb_db_clear_mask(struct ntb_dev *ntb, u64 db_bits)
+{
+	struct amd_ntb_dev *ndev = ntb_ndev(ntb);
+	void __iomem *mmio = ndev->self_mmio;
+	unsigned long flags;
+
+	if (db_bits & ~ndev->db_valid_mask)
+		return -EINVAL;
+
+	spin_lock_irqsave(&ndev->db_mask_lock, flags);
+	ndev->db_mask &= ~db_bits;
+	writew((u16)ndev->db_mask, mmio + AMD_DBMASK_OFFSET);
+	spin_unlock_irqrestore(&ndev->db_mask_lock, flags);
+
+	return 0;
+}
+
+static int amd_ntb_peer_db_addr(struct ntb_dev *ntb,
+				phys_addr_t *db_addr,
+				resource_size_t *db_size)
+{
+	struct amd_ntb_dev *ndev = ntb_ndev(ntb);
+
+	if (db_addr)
+		*db_addr = (phys_addr_t)(ndev->peer_mmio + AMD_DBREQ_OFFSET);
+	if (db_size)
+		*db_size = sizeof(u32);
+
+	return 0;
+}
+
+static int amd_ntb_peer_db_set(struct ntb_dev *ntb, u64 db_bits)
+{
+	struct amd_ntb_dev *ndev = ntb_ndev(ntb);
+	void __iomem *mmio = ndev->self_mmio;
+
+	writew((u16)db_bits, mmio + AMD_DBREQ_OFFSET);
+
+	return 0;
+}
+
+static int amd_ntb_spad_count(struct ntb_dev *ntb)
+{
+	return ntb_ndev(ntb)->spad_count;
+}
+
+static u32 amd_ntb_spad_read(struct ntb_dev *ntb, int idx)
+{
+	struct amd_ntb_dev *ndev = ntb_ndev(ntb);
+	void __iomem *mmio = ndev->self_mmio;
+	u32 offset;
+
+	if (idx < 0 || idx >= ndev->spad_count)
+		return 0;
+
+	offset = ndev->self_spad + (idx << 2);
+	return readl(mmio + AMD_SPAD_OFFSET + offset);
+}
+
+static int amd_ntb_spad_write(struct ntb_dev *ntb,
+			      int idx, u32 val)
+{
+	struct amd_ntb_dev *ndev = ntb_ndev(ntb);
+	void __iomem *mmio = ndev->self_mmio;
+	u32 offset;
+
+	if (idx < 0 || idx >= ndev->spad_count)
+		return -EINVAL;
+
+	offset = ndev->self_spad + (idx << 2);
+	writel(val, mmio + AMD_SPAD_OFFSET + offset);
+
+	return 0;
+}
+
+static int amd_ntb_peer_spad_addr(struct ntb_dev *ntb, int idx,
+				  phys_addr_t *spad_addr)
+{
+	struct amd_ntb_dev *ndev = ntb_ndev(ntb);
+
+	if (idx < 0 || idx >= ndev->spad_count)
+		return -EINVAL;
+
+	if (spad_addr)
+		*spad_addr = (phys_addr_t)(ndev->self_mmio + AMD_SPAD_OFFSET +
+					   ndev->peer_spad + (idx << 2));
+	return 0;
+}
+
+static u32 amd_ntb_peer_spad_read(struct ntb_dev *ntb, int idx)
+{
+	struct amd_ntb_dev *ndev = ntb_ndev(ntb);
+	void __iomem *mmio = ndev->self_mmio;
+	u32 offset;
+
+	if (idx < 0 || idx >= ndev->spad_count)
+		return -EINVAL;
+
+	offset = ndev->peer_spad + (idx << 2);
+	return readl(mmio + AMD_SPAD_OFFSET + offset);
+}
+
+static int amd_ntb_peer_spad_write(struct ntb_dev *ntb,
+				   int idx, u32 val)
+{
+	struct amd_ntb_dev *ndev = ntb_ndev(ntb);
+	void __iomem *mmio = ndev->self_mmio;
+	u32 offset;
+
+	if (idx < 0 || idx >= ndev->spad_count)
+		return -EINVAL;
+
+	offset = ndev->peer_spad + (idx << 2);
+	writel(val, mmio + AMD_SPAD_OFFSET + offset);
+
+	return 0;
+}
+
+static const struct ntb_dev_ops amd_ntb_ops = {
+	.mw_count		= amd_ntb_mw_count,
+	.mw_get_range		= amd_ntb_mw_get_range,
+	.mw_set_trans		= amd_ntb_mw_set_trans,
+	.link_is_up		= amd_ntb_link_is_up,
+	.link_enable		= amd_ntb_link_enable,
+	.link_disable		= amd_ntb_link_disable,
+	.db_valid_mask		= amd_ntb_db_valid_mask,
+	.db_vector_count	= amd_ntb_db_vector_count,
+	.db_vector_mask		= amd_ntb_db_vector_mask,
+	.db_read		= amd_ntb_db_read,
+	.db_clear		= amd_ntb_db_clear,
+	.db_set_mask		= amd_ntb_db_set_mask,
+	.db_clear_mask		= amd_ntb_db_clear_mask,
+	.peer_db_addr		= amd_ntb_peer_db_addr,
+	.peer_db_set		= amd_ntb_peer_db_set,
+	.spad_count		= amd_ntb_spad_count,
+	.spad_read		= amd_ntb_spad_read,
+	.spad_write		= amd_ntb_spad_write,
+	.peer_spad_addr		= amd_ntb_peer_spad_addr,
+	.peer_spad_read		= amd_ntb_peer_spad_read,
+	.peer_spad_write	= amd_ntb_peer_spad_write,
+};
+
+static void amd_ack_smu(struct amd_ntb_dev *ndev, u32 bit)
+{
+	void __iomem *mmio = ndev->self_mmio;
+	int reg;
+
+	reg = readl(mmio + AMD_SMUACK_OFFSET);
+	reg |= bit;
+	writel(reg, mmio + AMD_SMUACK_OFFSET);
+
+	ndev->peer_sta |= bit;
+}
+
+static void amd_handle_event(struct amd_ntb_dev *ndev, int vec)
+{
+	void __iomem *mmio = ndev->self_mmio;
+	u32 status;
+
+	status = readl(mmio + AMD_INTSTAT_OFFSET);
+	if (!(status & AMD_EVENT_INTMASK))
+		return;
+
+	dev_dbg(ndev_dev(ndev), "status = 0x%x and vec = %d\n", status, vec);
+
+	status &= AMD_EVENT_INTMASK;
+	switch (status) {
+	case AMD_PEER_FLUSH_EVENT:
+		dev_info(ndev_dev(ndev), "Flush is done.\n");
+		break;
+	case AMD_PEER_RESET_EVENT:
+		amd_ack_smu(ndev, AMD_PEER_RESET_EVENT);
+
+		/* link down first */
+		ntb_link_event(&ndev->ntb);
+		/* polling peer status */
+		schedule_delayed_work(&ndev->hb_timer, AMD_LINK_HB_TIMEOUT);
+
+		break;
+	case AMD_PEER_D3_EVENT:
+	case AMD_PEER_PMETO_EVENT:
+		amd_ack_smu(ndev, status);
+
+		/* link down */
+		ntb_link_event(&ndev->ntb);
+
+		break;
+	case AMD_PEER_D0_EVENT:
+		mmio = ndev->peer_mmio;
+		status = readl(mmio + AMD_PMESTAT_OFFSET);
+		/* check if this is WAKEUP event */
+		if (status & 0x1)
+			dev_info(ndev_dev(ndev), "Wakeup is done.\n");
+
+		amd_ack_smu(ndev, AMD_PEER_D0_EVENT);
+
+		/* start a timer to poll link status */
+		schedule_delayed_work(&ndev->hb_timer,
+				      AMD_LINK_HB_TIMEOUT);
+		break;
+	default:
+		dev_info(ndev_dev(ndev), "event status = 0x%x.\n", status);
+		break;
+	}
+}
+
+static irqreturn_t ndev_interrupt(struct amd_ntb_dev *ndev, int vec)
+{
+	dev_dbg(ndev_dev(ndev), "vec %d\n", vec);
+
+	if (vec > (AMD_DB_CNT - 1) || (ndev->msix_vec_count == 1))
+		amd_handle_event(ndev, vec);
+
+	if (vec < AMD_DB_CNT)
+		ntb_db_event(&ndev->ntb, vec);
+
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t ndev_vec_isr(int irq, void *dev)
+{
+	struct amd_ntb_vec *nvec = dev;
+
+	return ndev_interrupt(nvec->ndev, nvec->num);
+}
+
+static irqreturn_t ndev_irq_isr(int irq, void *dev)
+{
+	struct amd_ntb_dev *ndev = dev;
+
+	return ndev_interrupt(ndev, irq - ndev_pdev(ndev)->irq);
+}
+
+static int ndev_init_isr(struct amd_ntb_dev *ndev,
+			 int msix_min, int msix_max)
+{
+	struct pci_dev *pdev;
+	int rc, i, msix_count, node;
+
+	pdev = ndev_pdev(ndev);
+
+	node = dev_to_node(&pdev->dev);
+
+	ndev->db_mask = ndev->db_valid_mask;
+
+	/* Try to set up msix irq */
+	ndev->vec = kzalloc_node(msix_max * sizeof(*ndev->vec),
+				 GFP_KERNEL, node);
+	if (!ndev->vec)
+		goto err_msix_vec_alloc;
+
+	ndev->msix = kzalloc_node(msix_max * sizeof(*ndev->msix),
+				  GFP_KERNEL, node);
+	if (!ndev->msix)
+		goto err_msix_alloc;
+
+	for (i = 0; i < msix_max; ++i)
+		ndev->msix[i].entry = i;
+
+	msix_count = pci_enable_msix_range(pdev, ndev->msix,
+					   msix_min, msix_max);
+	if (msix_count < 0)
+		goto err_msix_enable;
+
+	/* NOTE: Disable MSIX if msix count is less than 16 because of
+	 * hardware limitation.
+	 */
+	if (msix_count < msix_min) {
+		pci_disable_msix(pdev);
+		goto err_msix_enable;
+	}
+
+	for (i = 0; i < msix_count; ++i) {
+		ndev->vec[i].ndev = ndev;
+		ndev->vec[i].num = i;
+		rc = request_irq(ndev->msix[i].vector, ndev_vec_isr, 0,
+				 "ndev_vec_isr", &ndev->vec[i]);
+		if (rc)
+			goto err_msix_request;
+	}
+
+	dev_dbg(ndev_dev(ndev), "Using msix interrupts\n");
+	ndev->db_count = msix_min;
+	ndev->msix_vec_count = msix_max;
+	return 0;
+
+err_msix_request:
+	while (i-- > 0)
+		free_irq(ndev->msix[i].vector, ndev);
+	pci_disable_msix(pdev);
+err_msix_enable:
+	kfree(ndev->msix);
+err_msix_alloc:
+	kfree(ndev->vec);
+err_msix_vec_alloc:
+	ndev->msix = NULL;
+	ndev->vec = NULL;
+
+	/* Try to set up msi irq */
+	rc = pci_enable_msi(pdev);
+	if (rc)
+		goto err_msi_enable;
+
+	rc = request_irq(pdev->irq, ndev_irq_isr, 0,
+			 "ndev_irq_isr", ndev);
+	if (rc)
+		goto err_msi_request;
+
+	dev_dbg(ndev_dev(ndev), "Using msi interrupts\n");
+	ndev->db_count = 1;
+	ndev->msix_vec_count = 1;
+	return 0;
+
+err_msi_request:
+	pci_disable_msi(pdev);
+err_msi_enable:
+
+	/* Try to set up intx irq */
+	pci_intx(pdev, 1);
+
+	rc = request_irq(pdev->irq, ndev_irq_isr, IRQF_SHARED,
+			 "ndev_irq_isr", ndev);
+	if (rc)
+		goto err_intx_request;
+
+	dev_dbg(ndev_dev(ndev), "Using intx interrupts\n");
+	ndev->db_count = 1;
+	ndev->msix_vec_count = 1;
+	return 0;
+
+err_intx_request:
+	return rc;
+}
+
+static void ndev_deinit_isr(struct amd_ntb_dev *ndev)
+{
+	struct pci_dev *pdev;
+	void __iomem *mmio = ndev->self_mmio;
+	int i;
+
+	pdev = ndev_pdev(ndev);
+
+	/* Mask all doorbell interrupts */
+	ndev->db_mask = ndev->db_valid_mask;
+	writel(ndev->db_mask, mmio + AMD_DBMASK_OFFSET);
+
+	if (ndev->msix) {
+		i = ndev->msix_vec_count;
+		while (i--)
+			free_irq(ndev->msix[i].vector, &ndev->vec[i]);
+		pci_disable_msix(pdev);
+		kfree(ndev->msix);
+		kfree(ndev->vec);
+	} else {
+		free_irq(pdev->irq, ndev);
+		if (pci_dev_msi_enabled(pdev))
+			pci_disable_msi(pdev);
+		else
+			pci_intx(pdev, 0);
+	}
+}
+
+static ssize_t ndev_debugfs_read(struct file *filp, char __user *ubuf,
+				 size_t count, loff_t *offp)
+{
+	struct amd_ntb_dev *ndev;
+	void __iomem *mmio;
+	char *buf;
+	size_t buf_size;
+	ssize_t ret, off;
+	union { u64 v64; u32 v32; u16 v16; } u;
+
+	ndev = filp->private_data;
+	mmio = ndev->self_mmio;
+
+	buf_size = min(count, 0x800ul);
+
+	buf = kmalloc(buf_size, GFP_KERNEL);
+	if (!buf)
+		return -ENOMEM;
+
+	off = 0;
+
+	off += scnprintf(buf + off, buf_size - off,
+			 "NTB Device Information:\n");
+
+	off += scnprintf(buf + off, buf_size - off,
+			 "Connection Topology -\t%s\n",
+			 ntb_topo_string(ndev->ntb.topo));
+
+	off += scnprintf(buf + off, buf_size - off,
+			 "LNK STA -\t\t%#06x\n", ndev->lnk_sta);
+
+	if (!amd_link_is_up(ndev)) {
+		off += scnprintf(buf + off, buf_size - off,
+				 "Link Status -\t\tDown\n");
+	} else {
+		off += scnprintf(buf + off, buf_size - off,
+				 "Link Status -\t\tUp\n");
+		off += scnprintf(buf + off, buf_size - off,
+				 "Link Speed -\t\tPCI-E Gen %u\n",
+				 NTB_LNK_STA_SPEED(ndev->lnk_sta));
+		off += scnprintf(buf + off, buf_size - off,
+				 "Link Width -\t\tx%u\n",
+				 NTB_LNK_STA_WIDTH(ndev->lnk_sta));
+	}
+
+	off += scnprintf(buf + off, buf_size - off,
+			 "Memory Window Count -\t%u\n", ndev->mw_count);
+	off += scnprintf(buf + off, buf_size - off,
+			 "Scratchpad Count -\t%u\n", ndev->spad_count);
+	off += scnprintf(buf + off, buf_size - off,
+			 "Doorbell Count -\t%u\n", ndev->db_count);
+	off += scnprintf(buf + off, buf_size - off,
+			 "MSIX Vector Count -\t%u\n", ndev->msix_vec_count);
+
+	off += scnprintf(buf + off, buf_size - off,
+			 "Doorbell Valid Mask -\t%#llx\n", ndev->db_valid_mask);
+
+	u.v32 = readl(ndev->self_mmio + AMD_DBMASK_OFFSET);
+	off += scnprintf(buf + off, buf_size - off,
+			 "Doorbell Mask -\t\t\t%#06x\n", u.v32);
+
+	u.v32 = readl(mmio + AMD_DBSTAT_OFFSET);
+	off += scnprintf(buf + off, buf_size - off,
+			 "Doorbell Bell -\t\t\t%#06x\n", u.v32);
+
+	off += scnprintf(buf + off, buf_size - off,
+			 "\nNTB Incoming XLAT:\n");
+
+	u.v64 = read64(mmio + AMD_BAR1XLAT_OFFSET);
+	off += scnprintf(buf + off, buf_size - off,
+			 "XLAT1 -\t\t%#018llx\n", u.v64);
+
+	u.v64 = read64(ndev->self_mmio + AMD_BAR23XLAT_OFFSET);
+	off += scnprintf(buf + off, buf_size - off,
+			 "XLAT23 -\t\t%#018llx\n", u.v64);
+
+	u.v64 = read64(ndev->self_mmio + AMD_BAR45XLAT_OFFSET);
+	off += scnprintf(buf + off, buf_size - off,
+			 "XLAT45 -\t\t%#018llx\n", u.v64);
+
+	u.v32 = readl(mmio + AMD_BAR1LMT_OFFSET);
+	off += scnprintf(buf + off, buf_size - off,
+			 "LMT1 -\t\t\t%#06x\n", u.v32);
+
+	u.v64 = read64(ndev->self_mmio + AMD_BAR23LMT_OFFSET);
+	off += scnprintf(buf + off, buf_size - off,
+			 "LMT23 -\t\t\t%#018llx\n", u.v64);
+
+	u.v64 = read64(ndev->self_mmio + AMD_BAR45LMT_OFFSET);
+	off += scnprintf(buf + off, buf_size - off,
+			 "LMT45 -\t\t\t%#018llx\n", u.v64);
+
+	ret = simple_read_from_buffer(ubuf, count, offp, buf, off);
+	kfree(buf);
+	return ret;
+}
+
+static void ndev_init_debugfs(struct amd_ntb_dev *ndev)
+{
+	if (!debugfs_dir) {
+		ndev->debugfs_dir = NULL;
+		ndev->debugfs_info = NULL;
+	} else {
+		ndev->debugfs_dir =
+			debugfs_create_dir(ndev_name(ndev), debugfs_dir);
+		if (!ndev->debugfs_dir)
+			ndev->debugfs_info = NULL;
+		else
+			ndev->debugfs_info =
+				debugfs_create_file("info", S_IRUSR,
+						    ndev->debugfs_dir, ndev,
+						    &amd_ntb_debugfs_info);
+	}
+}
+
+static void ndev_deinit_debugfs(struct amd_ntb_dev *ndev)
+{
+	debugfs_remove_recursive(ndev->debugfs_dir);
+}
+
+static inline void ndev_init_struct(struct amd_ntb_dev *ndev,
+				    struct pci_dev *pdev)
+{
+	ndev->ntb.pdev = pdev;
+	ndev->ntb.topo = NTB_TOPO_NONE;
+	ndev->ntb.ops = &amd_ntb_ops;
+	ndev->int_mask = AMD_EVENT_INTMASK;
+	spin_lock_init(&ndev->db_mask_lock);
+}
+
+static int amd_poll_link(struct amd_ntb_dev *ndev)
+{
+	void __iomem *mmio = ndev->peer_mmio;
+	u32 reg, stat;
+	int rc;
+
+	reg = readl(mmio + AMD_SIDEINFO_OFFSET);
+	reg &= NTB_LIN_STA_ACTIVE_BIT;
+
+	dev_dbg(ndev_dev(ndev), "%s: reg_val = 0x%x.\n", __func__, reg);
+
+	if (reg == ndev->cntl_sta)
+		return 0;
+
+	ndev->cntl_sta = reg;
+
+	rc = pci_read_config_dword(ndev->ntb.pdev,
+				   AMD_LINK_STATUS_OFFSET, &stat);
+	if (rc)
+		return 0;
+	ndev->lnk_sta = stat;
+
+	return 1;
+}
+
+static void amd_link_hb(struct work_struct *work)
+{
+	struct amd_ntb_dev *ndev = hb_ndev(work);
+
+	if (amd_poll_link(ndev))
+		ntb_link_event(&ndev->ntb);
+
+	if (!amd_link_is_up(ndev))
+		schedule_delayed_work(&ndev->hb_timer, AMD_LINK_HB_TIMEOUT);
+}
+
+static int amd_init_isr(struct amd_ntb_dev *ndev)
+{
+	return ndev_init_isr(ndev, AMD_DB_CNT, AMD_MSIX_VECTOR_CNT);
+}
+
+static void amd_init_side_info(struct amd_ntb_dev *ndev)
+{
+	void __iomem *mmio = ndev->self_mmio;
+	unsigned int reg;
+
+	reg = readl(mmio + AMD_SIDEINFO_OFFSET);
+	if (!(reg & AMD_SIDE_READY)) {
+		reg |= AMD_SIDE_READY;
+		writel(reg, mmio + AMD_SIDEINFO_OFFSET);
+	}
+}
+
+static void amd_deinit_side_info(struct amd_ntb_dev *ndev)
+{
+	void __iomem *mmio = ndev->self_mmio;
+	unsigned int reg;
+
+	reg = readl(mmio + AMD_SIDEINFO_OFFSET);
+	if (reg & AMD_SIDE_READY) {
+		reg &= ~AMD_SIDE_READY;
+		writel(reg, mmio + AMD_SIDEINFO_OFFSET);
+		readl(mmio + AMD_SIDEINFO_OFFSET);
+	}
+}
+
+static int amd_init_ntb(struct amd_ntb_dev *ndev)
+{
+	void __iomem *mmio = ndev->self_mmio;
+
+	ndev->mw_count = AMD_MW_CNT;
+	ndev->spad_count = AMD_SPADS_CNT;
+	ndev->db_count = AMD_DB_CNT;
+
+	switch (ndev->ntb.topo) {
+	case NTB_TOPO_PRI:
+	case NTB_TOPO_SEC:
+		ndev->spad_count >>= 1;
+		if (ndev->ntb.topo == NTB_TOPO_PRI) {
+			ndev->self_spad = 0;
+			ndev->peer_spad = 0x20;
+		} else {
+			ndev->self_spad = 0x20;
+			ndev->peer_spad = 0;
+		}
+
+		INIT_DELAYED_WORK(&ndev->hb_timer, amd_link_hb);
+		schedule_delayed_work(&ndev->hb_timer, AMD_LINK_HB_TIMEOUT);
+
+		break;
+	default:
+		dev_err(ndev_dev(ndev), "AMD NTB does not support B2B mode.\n");
+		return -EINVAL;
+	}
+
+	ndev->db_valid_mask = BIT_ULL(ndev->db_count) - 1;
+
+	/* Mask event interrupts */
+	writel(ndev->int_mask, mmio + AMD_INTMASK_OFFSET);
+
+	return 0;
+}
+
+static enum ntb_topo amd_get_topo(struct amd_ntb_dev *ndev)
+{
+	void __iomem *mmio = ndev->self_mmio;
+	u32 info;
+
+	info = readl(mmio + AMD_SIDEINFO_OFFSET);
+	if (info & AMD_SIDE_MASK)
+		return NTB_TOPO_SEC;
+	else
+		return NTB_TOPO_PRI;
+}
+
+static int amd_init_dev(struct amd_ntb_dev *ndev)
+{
+	struct pci_dev *pdev;
+	int rc = 0;
+
+	pdev = ndev_pdev(ndev);
+
+	ndev->ntb.topo = amd_get_topo(ndev);
+	dev_dbg(ndev_dev(ndev), "AMD NTB topo is %s\n",
+		ntb_topo_string(ndev->ntb.topo));
+
+	rc = amd_init_ntb(ndev);
+	if (rc)
+		return rc;
+
+	rc = amd_init_isr(ndev);
+	if (rc) {
+		dev_err(ndev_dev(ndev), "fail to init isr.\n");
+		return rc;
+	}
+
+	ndev->db_valid_mask = BIT_ULL(ndev->db_count) - 1;
+
+	return 0;
+}
+
+static void amd_deinit_dev(struct amd_ntb_dev *ndev)
+{
+	cancel_delayed_work_sync(&ndev->hb_timer);
+
+	ndev_deinit_isr(ndev);
+}
+
+static int amd_ntb_init_pci(struct amd_ntb_dev *ndev,
+			    struct pci_dev *pdev)
+{
+	int rc;
+
+	pci_set_drvdata(pdev, ndev);
+
+	rc = pci_enable_device(pdev);
+	if (rc)
+		goto err_pci_enable;
+
+	rc = pci_request_regions(pdev, NTB_NAME);
+	if (rc)
+		goto err_pci_regions;
+
+	pci_set_master(pdev);
+
+	rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(64));
+	if (rc) {
+		rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
+		if (rc)
+			goto err_dma_mask;
+		dev_warn(ndev_dev(ndev), "Cannot DMA highmem\n");
+	}
+
+	rc = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64));
+	if (rc) {
+		rc = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
+		if (rc)
+			goto err_dma_mask;
+		dev_warn(ndev_dev(ndev), "Cannot DMA consistent highmem\n");
+	}
+
+	ndev->self_mmio = pci_iomap(pdev, 0, 0);
+	if (!ndev->self_mmio) {
+		rc = -EIO;
+		goto err_dma_mask;
+	}
+	ndev->peer_mmio = ndev->self_mmio + AMD_PEER_OFFSET;
+
+	return 0;
+
+err_dma_mask:
+	pci_clear_master(pdev);
+err_pci_regions:
+	pci_disable_device(pdev);
+err_pci_enable:
+	pci_set_drvdata(pdev, NULL);
+	return rc;
+}
+
+static void amd_ntb_deinit_pci(struct amd_ntb_dev *ndev)
+{
+	struct pci_dev *pdev = ndev_pdev(ndev);
+
+	pci_iounmap(pdev, ndev->self_mmio);
+
+	pci_clear_master(pdev);
+	pci_release_regions(pdev);
+	pci_disable_device(pdev);
+	pci_set_drvdata(pdev, NULL);
+}
+
+static int amd_ntb_pci_probe(struct pci_dev *pdev,
+			     const struct pci_device_id *id)
+{
+	struct amd_ntb_dev *ndev;
+	int rc, node;
+
+	node = dev_to_node(&pdev->dev);
+
+	ndev = kzalloc_node(sizeof(*ndev), GFP_KERNEL, node);
+	if (!ndev) {
+		rc = -ENOMEM;
+		goto err_ndev;
+	}
+
+	ndev_init_struct(ndev, pdev);
+
+	rc = amd_ntb_init_pci(ndev, pdev);
+	if (rc)
+		goto err_init_pci;
+
+	rc = amd_init_dev(ndev);
+	if (rc)
+		goto err_init_dev;
+
+	/* write side info */
+	amd_init_side_info(ndev);
+
+	amd_poll_link(ndev);
+
+	ndev_init_debugfs(ndev);
+
+	rc = ntb_register_device(&ndev->ntb);
+	if (rc)
+		goto err_register;
+
+	dev_info(&pdev->dev, "NTB device registered.\n");
+
+	return 0;
+
+err_register:
+	ndev_deinit_debugfs(ndev);
+	amd_deinit_dev(ndev);
+err_init_dev:
+	amd_ntb_deinit_pci(ndev);
+err_init_pci:
+	kfree(ndev);
+err_ndev:
+	return rc;
+}
+
+static void amd_ntb_pci_remove(struct pci_dev *pdev)
+{
+	struct amd_ntb_dev *ndev = pci_get_drvdata(pdev);
+
+	ntb_unregister_device(&ndev->ntb);
+	ndev_deinit_debugfs(ndev);
+	amd_deinit_side_info(ndev);
+	amd_deinit_dev(ndev);
+	amd_ntb_deinit_pci(ndev);
+	kfree(ndev);
+}
+
+static const struct file_operations amd_ntb_debugfs_info = {
+	.owner = THIS_MODULE,
+	.open = simple_open,
+	.read = ndev_debugfs_read,
+};
+
+static const struct pci_device_id amd_ntb_pci_tbl[] = {
+	{PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_NTB)},
+	{0}
+};
+MODULE_DEVICE_TABLE(pci, amd_ntb_pci_tbl);
+
+static struct pci_driver amd_ntb_pci_driver = {
+	.name		= KBUILD_MODNAME,
+	.id_table	= amd_ntb_pci_tbl,
+	.probe		= amd_ntb_pci_probe,
+	.remove		= amd_ntb_pci_remove,
+};
+
+static int __init amd_ntb_pci_driver_init(void)
+{
+	pr_info("%s %s\n", NTB_DESC, NTB_VER);
+
+	if (debugfs_initialized())
+		debugfs_dir = debugfs_create_dir(KBUILD_MODNAME, NULL);
+
+	return pci_register_driver(&amd_ntb_pci_driver);
+}
+module_init(amd_ntb_pci_driver_init);
+
+static void __exit amd_ntb_pci_driver_exit(void)
+{
+	pci_unregister_driver(&amd_ntb_pci_driver);
+	debugfs_remove_recursive(debugfs_dir);
+}
+module_exit(amd_ntb_pci_driver_exit);
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/ntb/hw/amd/ntb_hw_amd.h
@@ -0,0 +1,217 @@
+/*
+ * This file is provided under a dual BSD/GPLv2 license.  When using or
+ *   redistributing this file, you may do so under either license.
+ *
+ *   GPL LICENSE SUMMARY
+ *
+ *   Copyright (C) 2016 Advanced Micro Devices, Inc. All Rights Reserved.
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of version 2 of the GNU General Public License as
+ *   published by the Free Software Foundation.
+ *
+ *   BSD LICENSE
+ *
+ *   Copyright (C) 2016 Advanced Micro Devices, Inc. All Rights Reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copy
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of AMD Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * AMD PCIe NTB Linux driver
+ *
+ * Contact Information:
+ * Xiangliang Yu <Xiangliang.Yu@amd.com>
+ */
+
+#ifndef NTB_HW_AMD_H
+#define NTB_HW_AMD_H
+
+#include <linux/ntb.h>
+#include <linux/pci.h>
+
+#define PCI_DEVICE_ID_AMD_NTB	0x145B
+#define AMD_LINK_HB_TIMEOUT	msecs_to_jiffies(1000)
+#define AMD_LINK_STATUS_OFFSET	0x68
+#define NTB_LIN_STA_ACTIVE_BIT	0x00000002
+#define NTB_LNK_STA_SPEED_MASK	0x000F0000
+#define NTB_LNK_STA_WIDTH_MASK	0x03F00000
+#define NTB_LNK_STA_ACTIVE(x)	(!!((x) & NTB_LIN_STA_ACTIVE_BIT))
+#define NTB_LNK_STA_SPEED(x)	(((x) & NTB_LNK_STA_SPEED_MASK) >> 16)
+#define NTB_LNK_STA_WIDTH(x)	(((x) & NTB_LNK_STA_WIDTH_MASK) >> 20)
+
+#ifndef read64
+#ifdef readq
+#define read64 readq
+#else
+#define read64 _read64
+static inline u64 _read64(void __iomem *mmio)
+{
+	u64 low, high;
+
+	low = readl(mmio);
+	high = readl(mmio + sizeof(u32));
+	return low | (high << 32);
+}
+#endif
+#endif
+
+#ifndef write64
+#ifdef writeq
+#define write64 writeq
+#else
+#define write64 _write64
+static inline void _write64(u64 val, void __iomem *mmio)
+{
+	writel(val, mmio);
+	writel(val >> 32, mmio + sizeof(u32));
+}
+#endif
+#endif
+
+enum {
+	/* AMD NTB Capability */
+	AMD_MW_CNT		= 3,
+	AMD_DB_CNT		= 16,
+	AMD_MSIX_VECTOR_CNT	= 24,
+	AMD_SPADS_CNT		= 16,
+
+	/*  AMD NTB register offset */
+	AMD_CNTL_OFFSET		= 0x200,
+
+	/* NTB control register bits */
+	PMM_REG_CTL		= BIT(21),
+	SMM_REG_CTL		= BIT(20),
+	SMM_REG_ACC_PATH	= BIT(18),
+	PMM_REG_ACC_PATH	= BIT(17),
+	NTB_CLK_EN		= BIT(16),
+
+	AMD_STA_OFFSET		= 0x204,
+	AMD_PGSLV_OFFSET	= 0x208,
+	AMD_SPAD_MUX_OFFSET	= 0x20C,
+	AMD_SPAD_OFFSET		= 0x210,
+	AMD_RSMU_HCID		= 0x250,
+	AMD_RSMU_SIID		= 0x254,
+	AMD_PSION_OFFSET	= 0x300,
+	AMD_SSION_OFFSET	= 0x330,
+	AMD_MMINDEX_OFFSET	= 0x400,
+	AMD_MMDATA_OFFSET	= 0x404,
+	AMD_SIDEINFO_OFFSET	= 0x408,
+
+	AMD_SIDE_MASK		= BIT(0),
+	AMD_SIDE_READY		= BIT(1),
+
+	/* limit register */
+	AMD_ROMBARLMT_OFFSET	= 0x410,
+	AMD_BAR1LMT_OFFSET	= 0x414,
+	AMD_BAR23LMT_OFFSET	= 0x418,
+	AMD_BAR45LMT_OFFSET	= 0x420,
+	/* xlat address */
+	AMD_POMBARXLAT_OFFSET	= 0x428,
+	AMD_BAR1XLAT_OFFSET	= 0x430,
+	AMD_BAR23XLAT_OFFSET	= 0x438,
+	AMD_BAR45XLAT_OFFSET	= 0x440,
+	/* doorbell and interrupt */
+	AMD_DBFM_OFFSET		= 0x450,
+	AMD_DBREQ_OFFSET	= 0x454,
+	AMD_MIRRDBSTAT_OFFSET	= 0x458,
+	AMD_DBMASK_OFFSET	= 0x45C,
+	AMD_DBSTAT_OFFSET	= 0x460,
+	AMD_INTMASK_OFFSET	= 0x470,
+	AMD_INTSTAT_OFFSET	= 0x474,
+
+	/* event type */
+	AMD_PEER_FLUSH_EVENT	= BIT(0),
+	AMD_PEER_RESET_EVENT	= BIT(1),
+	AMD_PEER_D3_EVENT	= BIT(2),
+	AMD_PEER_PMETO_EVENT	= BIT(3),
+	AMD_PEER_D0_EVENT	= BIT(4),
+	AMD_EVENT_INTMASK	= (AMD_PEER_FLUSH_EVENT |
+				AMD_PEER_RESET_EVENT | AMD_PEER_D3_EVENT |
+				AMD_PEER_PMETO_EVENT | AMD_PEER_D0_EVENT),
+
+	AMD_PMESTAT_OFFSET	= 0x480,
+	AMD_PMSGTRIG_OFFSET	= 0x490,
+	AMD_LTRLATENCY_OFFSET	= 0x494,
+	AMD_FLUSHTRIG_OFFSET	= 0x498,
+
+	/* SMU register*/
+	AMD_SMUACK_OFFSET	= 0x4A0,
+	AMD_SINRST_OFFSET	= 0x4A4,
+	AMD_RSPNUM_OFFSET	= 0x4A8,
+	AMD_SMU_SPADMUTEX	= 0x4B0,
+	AMD_SMU_SPADOFFSET	= 0x4B4,
+
+	AMD_PEER_OFFSET		= 0x400,
+};
+
+struct amd_ntb_dev;
+
+struct amd_ntb_vec {
+	struct amd_ntb_dev	*ndev;
+	int			num;
+};
+
+struct amd_ntb_dev {
+	struct ntb_dev ntb;
+
+	u32 ntb_side;
+	u32 lnk_sta;
+	u32 cntl_sta;
+	u32 peer_sta;
+
+	unsigned char mw_count;
+	unsigned char spad_count;
+	unsigned char db_count;
+	unsigned char msix_vec_count;
+
+	u64 db_valid_mask;
+	u64 db_mask;
+	u32 int_mask;
+
+	struct msix_entry *msix;
+	struct amd_ntb_vec *vec;
+
+	/* synchronize rmw access of db_mask and hw reg */
+	spinlock_t db_mask_lock;
+
+	void __iomem *self_mmio;
+	void __iomem *peer_mmio;
+	unsigned int self_spad;
+	unsigned int peer_spad;
+
+	struct delayed_work hb_timer;
+
+	struct dentry *debugfs_dir;
+	struct dentry *debugfs_info;
+};
+
+#define ndev_pdev(ndev) ((ndev)->ntb.pdev)
+#define ndev_name(ndev) pci_name(ndev_pdev(ndev))
+#define ndev_dev(ndev) (&ndev_pdev(ndev)->dev)
+#define ntb_ndev(__ntb) container_of(__ntb, struct amd_ntb_dev, ntb)
+#define hb_ndev(__work) container_of(__work, struct amd_ntb_dev, hb_timer.work)
+
+#endif
--- zfcpdump-kernel-4.4.orig/drivers/nvdimm/bus.c
+++ zfcpdump-kernel-4.4/drivers/nvdimm/bus.c
@@ -335,7 +335,7 @@ static const struct nd_cmd_desc __nd_cmd
 	[ND_CMD_IMPLEMENTED] = { },
 	[ND_CMD_SMART] = {
 		.out_num = 2,
-		.out_sizes = { 4, 8, },
+		.out_sizes = { 4, 128, },
 	},
 	[ND_CMD_SMART_THRESHOLD] = {
 		.out_num = 2,
@@ -513,10 +513,10 @@ static int __nd_ioctl(struct nvdimm_bus
 
 	/* fail write commands (when read-only) */
 	if (read_only)
-		switch (ioctl_cmd) {
-		case ND_IOCTL_VENDOR:
-		case ND_IOCTL_SET_CONFIG_DATA:
-		case ND_IOCTL_ARS_START:
+		switch (cmd) {
+		case ND_CMD_VENDOR:
+		case ND_CMD_SET_CONFIG_DATA:
+		case ND_CMD_ARS_START:
 			dev_dbg(&nvdimm_bus->dev, "'%s' command while read-only.\n",
 					nvdimm ? nvdimm_cmd_name(cmd)
 					: nvdimm_bus_cmd_name(cmd));
--- zfcpdump-kernel-4.4.orig/drivers/nvdimm/namespace_devs.c
+++ zfcpdump-kernel-4.4/drivers/nvdimm/namespace_devs.c
@@ -77,6 +77,59 @@ static bool is_namespace_io(struct devic
 	return dev ? dev->type == &namespace_io_device_type : false;
 }
 
+static int is_uuid_busy(struct device *dev, void *data)
+{
+	u8 *uuid1 = data, *uuid2 = NULL;
+
+	if (is_namespace_pmem(dev)) {
+		struct nd_namespace_pmem *nspm = to_nd_namespace_pmem(dev);
+
+		uuid2 = nspm->uuid;
+	} else if (is_namespace_blk(dev)) {
+		struct nd_namespace_blk *nsblk = to_nd_namespace_blk(dev);
+
+		uuid2 = nsblk->uuid;
+	} else if (is_nd_btt(dev)) {
+		struct nd_btt *nd_btt = to_nd_btt(dev);
+
+		uuid2 = nd_btt->uuid;
+	} else if (is_nd_pfn(dev)) {
+		struct nd_pfn *nd_pfn = to_nd_pfn(dev);
+
+		uuid2 = nd_pfn->uuid;
+	}
+
+	if (uuid2 && memcmp(uuid1, uuid2, NSLABEL_UUID_LEN) == 0)
+		return -EBUSY;
+
+	return 0;
+}
+
+static int is_namespace_uuid_busy(struct device *dev, void *data)
+{
+	if (is_nd_pmem(dev) || is_nd_blk(dev))
+		return device_for_each_child(dev, data, is_uuid_busy);
+	return 0;
+}
+
+/**
+ * nd_is_uuid_unique - verify that no other namespace has @uuid
+ * @dev: any device on a nvdimm_bus
+ * @uuid: uuid to check
+ */
+bool nd_is_uuid_unique(struct device *dev, u8 *uuid)
+{
+	struct nvdimm_bus *nvdimm_bus = walk_to_nvdimm_bus(dev);
+
+	if (!nvdimm_bus)
+		return false;
+	WARN_ON_ONCE(!is_nvdimm_bus_locked(&nvdimm_bus->dev));
+	if (device_for_each_child(&nvdimm_bus->dev, uuid,
+				is_namespace_uuid_busy) != 0)
+		return false;
+	return true;
+}
+
 bool pmem_should_map_pages(struct device *dev)
 {
 	struct nd_region *nd_region = to_nd_region(dev->parent);
--- zfcpdump-kernel-4.4.orig/drivers/nvdimm/pfn_devs.c
+++ zfcpdump-kernel-4.4/drivers/nvdimm/pfn_devs.c
@@ -275,7 +275,7 @@ int nd_pfn_validate(struct nd_pfn *nd_pf
 	} else {
 		/* from init we validate */
 		if (memcmp(nd_pfn->uuid, pfn_sb->uuid, 16) != 0)
-			return -EINVAL;
+			return -ENODEV;
 	}
 
 	/*
--- zfcpdump-kernel-4.4.orig/drivers/nvdimm/region_devs.c
+++ zfcpdump-kernel-4.4/drivers/nvdimm/region_devs.c
@@ -134,62 +134,6 @@ int nd_region_to_nstype(struct nd_region
 }
 EXPORT_SYMBOL(nd_region_to_nstype);
 
-static int is_uuid_busy(struct device *dev, void *data)
-{
-	struct nd_region *nd_region = to_nd_region(dev->parent);
-	u8 *uuid = data;
-
-	switch (nd_region_to_nstype(nd_region)) {
-	case ND_DEVICE_NAMESPACE_PMEM: {
-		struct nd_namespace_pmem *nspm = to_nd_namespace_pmem(dev);
-
-		if (!nspm->uuid)
-			break;
-		if (memcmp(uuid, nspm->uuid, NSLABEL_UUID_LEN) == 0)
-			return -EBUSY;
-		break;
-	}
-	case ND_DEVICE_NAMESPACE_BLK: {
-		struct nd_namespace_blk *nsblk = to_nd_namespace_blk(dev);
-
-		if (!nsblk->uuid)
-			break;
-		if (memcmp(uuid, nsblk->uuid, NSLABEL_UUID_LEN) == 0)
-			return -EBUSY;
-		break;
-	}
-	default:
-		break;
-	}
-
-	return 0;
-}
-
-static int is_namespace_uuid_busy(struct device *dev, void *data)
-{
-	if (is_nd_pmem(dev) || is_nd_blk(dev))
-		return device_for_each_child(dev, data, is_uuid_busy);
-	return 0;
-}
-
-/**
- * nd_is_uuid_unique - verify that no other namespace has @uuid
- * @dev: any device on a nvdimm_bus
- * @uuid: uuid to check
- */
-bool nd_is_uuid_unique(struct device *dev, u8 *uuid)
-{
-	struct nvdimm_bus *nvdimm_bus = walk_to_nvdimm_bus(dev);
-
-	if (!nvdimm_bus)
-		return false;
-	WARN_ON_ONCE(!is_nvdimm_bus_locked(&nvdimm_bus->dev));
-	if (device_for_each_child(&nvdimm_bus->dev, uuid,
-				is_namespace_uuid_busy) != 0)
-		return false;
-	return true;
-}
-
 static ssize_t size_show(struct device *dev,
 		struct device_attribute *attr, char *buf)
 {
--- zfcpdump-kernel-4.4.orig/drivers/nvme/host/Kconfig
+++ zfcpdump-kernel-4.4/drivers/nvme/host/Kconfig
@@ -8,3 +8,14 @@ config BLK_DEV_NVME
 
 	  To compile this driver as a module, choose M here: the
 	  module will be called nvme.
+
+config BLK_DEV_NVME_SCSI
+	bool "SCSI emulation for NVMe device nodes"
+	depends on BLK_DEV_NVME
+	---help---
+	  This adds support for the SG_IO ioctl on the NVMe character
+	  and block devices nodes, as well a a translation for a small
+	  number of selected SCSI commands to NVMe commands to the NVMe
+	  driver.  If you don't know what this means you probably want
+	  to say N here, and if you know what it means you probably
+	  want to say N as well.
--- zfcpdump-kernel-4.4.orig/drivers/nvme/host/Makefile
+++ zfcpdump-kernel-4.4/drivers/nvme/host/Makefile
@@ -1,5 +1,6 @@
 
 obj-$(CONFIG_BLK_DEV_NVME)     += nvme.o
 
-lightnvm-$(CONFIG_NVM)	:= lightnvm.o
-nvme-y		+= pci.o scsi.o $(lightnvm-y)
+lightnvm-$(CONFIG_NVM)			:= lightnvm.o
+nvme-y					+= core.o pci.o $(lightnvm-y)
+nvme-$(CONFIG_BLK_DEV_NVME_SCSI)        += scsi.o
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/nvme/host/core.c
@@ -0,0 +1,1519 @@
+/*
+ * NVM Express device driver
+ * Copyright (c) 2011-2014, Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ */
+
+#include <linux/blkdev.h>
+#include <linux/blk-mq.h>
+#include <linux/delay.h>
+#include <linux/errno.h>
+#include <linux/hdreg.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/list_sort.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+#include <linux/pr.h>
+#include <linux/ptrace.h>
+#include <linux/nvme_ioctl.h>
+#include <linux/t10-pi.h>
+#include <scsi/sg.h>
+#include <asm/unaligned.h>
+
+#include "nvme.h"
+
+#define NVME_MINORS		(1U << MINORBITS)
+
+static int nvme_major;
+module_param(nvme_major, int, 0);
+
+static int nvme_char_major;
+module_param(nvme_char_major, int, 0);
+
+static LIST_HEAD(nvme_ctrl_list);
+DEFINE_SPINLOCK(dev_list_lock);
+
+static struct class *nvme_class;
+
+static void nvme_free_ns(struct kref *kref)
+{
+	struct nvme_ns *ns = container_of(kref, struct nvme_ns, kref);
+
+	if (ns->type == NVME_NS_LIGHTNVM)
+		nvme_nvm_unregister(ns->queue, ns->disk->disk_name);
+
+	spin_lock(&dev_list_lock);
+	ns->disk->private_data = NULL;
+	spin_unlock(&dev_list_lock);
+
+	nvme_put_ctrl(ns->ctrl);
+	put_disk(ns->disk);
+	kfree(ns);
+}
+
+static void nvme_put_ns(struct nvme_ns *ns)
+{
+	kref_put(&ns->kref, nvme_free_ns);
+}
+
+static struct nvme_ns *nvme_get_ns_from_disk(struct gendisk *disk)
+{
+	struct nvme_ns *ns;
+
+	spin_lock(&dev_list_lock);
+	ns = disk->private_data;
+	if (ns && !kref_get_unless_zero(&ns->kref))
+		ns = NULL;
+	spin_unlock(&dev_list_lock);
+
+	return ns;
+}
+
+void nvme_requeue_req(struct request *req)
+{
+	unsigned long flags;
+
+	blk_mq_requeue_request(req);
+	spin_lock_irqsave(req->q->queue_lock, flags);
+	if (!blk_queue_stopped(req->q))
+		blk_mq_kick_requeue_list(req->q);
+	spin_unlock_irqrestore(req->q->queue_lock, flags);
+}
+
+struct request *nvme_alloc_request(struct request_queue *q,
+		struct nvme_command *cmd, unsigned int flags)
+{
+	bool write = cmd->common.opcode & 1;
+	struct request *req;
+
+	req = blk_mq_alloc_request(q, write, flags);
+	if (IS_ERR(req))
+		return req;
+
+	req->cmd_type = REQ_TYPE_DRV_PRIV;
+	req->cmd_flags |= REQ_FAILFAST_DRIVER;
+	req->__data_len = 0;
+	req->__sector = (sector_t) -1;
+	req->bio = req->biotail = NULL;
+
+	req->cmd = (unsigned char *)cmd;
+	req->cmd_len = sizeof(struct nvme_command);
+	req->special = (void *)0;
+
+	return req;
+}
+
+/*
+ * Returns 0 on success.  If the result is negative, it's a Linux error code;
+ * if the result is positive, it's an NVM Express status code
+ */
+int __nvme_submit_sync_cmd(struct request_queue *q, struct nvme_command *cmd,
+		void *buffer, unsigned bufflen, u32 *result, unsigned timeout)
+{
+	struct request *req;
+	int ret;
+
+	req = nvme_alloc_request(q, cmd, 0);
+	if (IS_ERR(req))
+		return PTR_ERR(req);
+
+	req->timeout = timeout ? timeout : ADMIN_TIMEOUT;
+
+	if (buffer && bufflen) {
+		ret = blk_rq_map_kern(q, req, buffer, bufflen, GFP_KERNEL);
+		if (ret)
+			goto out;
+	}
+
+	blk_execute_rq(req->q, NULL, req, 0);
+	if (result)
+		*result = (u32)(uintptr_t)req->special;
+	ret = req->errors;
+ out:
+	blk_mq_free_request(req);
+	return ret;
+}
+
+int nvme_submit_sync_cmd(struct request_queue *q, struct nvme_command *cmd,
+		void *buffer, unsigned bufflen)
+{
+	return __nvme_submit_sync_cmd(q, cmd, buffer, bufflen, NULL, 0);
+}
+
+int __nvme_submit_user_cmd(struct request_queue *q, struct nvme_command *cmd,
+		void __user *ubuffer, unsigned bufflen,
+		void __user *meta_buffer, unsigned meta_len, u32 meta_seed,
+		u32 *result, unsigned timeout)
+{
+	bool write = cmd->common.opcode & 1;
+	struct nvme_ns *ns = q->queuedata;
+	struct gendisk *disk = ns ? ns->disk : NULL;
+	struct request *req;
+	struct bio *bio = NULL;
+	void *meta = NULL;
+	int ret;
+
+	req = nvme_alloc_request(q, cmd, 0);
+	if (IS_ERR(req))
+		return PTR_ERR(req);
+
+	req->timeout = timeout ? timeout : ADMIN_TIMEOUT;
+
+	if (ubuffer && bufflen) {
+		ret = blk_rq_map_user(q, req, NULL, ubuffer, bufflen,
+				GFP_KERNEL);
+		if (ret)
+			goto out;
+		bio = req->bio;
+
+		if (!disk)
+			goto submit;
+		bio->bi_bdev = bdget_disk(disk, 0);
+		if (!bio->bi_bdev) {
+			ret = -ENODEV;
+			goto out_unmap;
+		}
+
+		if (meta_buffer) {
+			struct bio_integrity_payload *bip;
+
+			meta = kmalloc(meta_len, GFP_KERNEL);
+			if (!meta) {
+				ret = -ENOMEM;
+				goto out_unmap;
+			}
+
+			if (write) {
+				if (copy_from_user(meta, meta_buffer,
+						meta_len)) {
+					ret = -EFAULT;
+					goto out_free_meta;
+				}
+			}
+
+			bip = bio_integrity_alloc(bio, GFP_KERNEL, 1);
+			if (IS_ERR(bip)) {
+				ret = PTR_ERR(bip);
+				goto out_free_meta;
+			}
+
+			bip->bip_iter.bi_size = meta_len;
+			bip->bip_iter.bi_sector = meta_seed;
+
+			ret = bio_integrity_add_page(bio, virt_to_page(meta),
+					meta_len, offset_in_page(meta));
+			if (ret != meta_len) {
+				ret = -ENOMEM;
+				goto out_free_meta;
+			}
+		}
+	}
+ submit:
+	blk_execute_rq(req->q, disk, req, 0);
+	ret = req->errors;
+	if (result)
+		*result = (u32)(uintptr_t)req->special;
+	if (meta && !ret && !write) {
+		if (copy_to_user(meta_buffer, meta, meta_len))
+			ret = -EFAULT;
+	}
+ out_free_meta:
+	kfree(meta);
+ out_unmap:
+	if (bio) {
+		if (disk && bio->bi_bdev)
+			bdput(bio->bi_bdev);
+		blk_rq_unmap_user(bio);
+	}
+ out:
+	blk_mq_free_request(req);
+	return ret;
+}
+
+int nvme_submit_user_cmd(struct request_queue *q, struct nvme_command *cmd,
+		void __user *ubuffer, unsigned bufflen, u32 *result,
+		unsigned timeout)
+{
+	return __nvme_submit_user_cmd(q, cmd, ubuffer, bufflen, NULL, 0, 0,
+			result, timeout);
+}
+
+int nvme_identify_ctrl(struct nvme_ctrl *dev, struct nvme_id_ctrl **id)
+{
+	struct nvme_command c = { };
+	int error;
+
+	/* gcc-4.4.4 (at least) has issues with initializers and anon unions */
+	c.identify.opcode = nvme_admin_identify;
+	c.identify.cns = cpu_to_le32(1);
+
+	*id = kmalloc(sizeof(struct nvme_id_ctrl), GFP_KERNEL);
+	if (!*id)
+		return -ENOMEM;
+
+	error = nvme_submit_sync_cmd(dev->admin_q, &c, *id,
+			sizeof(struct nvme_id_ctrl));
+	if (error)
+		kfree(*id);
+	return error;
+}
+
+static int nvme_identify_ns_list(struct nvme_ctrl *dev, unsigned nsid, __le32 *ns_list)
+{
+	struct nvme_command c = { };
+
+	c.identify.opcode = nvme_admin_identify;
+	c.identify.cns = cpu_to_le32(2);
+	c.identify.nsid = cpu_to_le32(nsid);
+	return nvme_submit_sync_cmd(dev->admin_q, &c, ns_list, 0x1000);
+}
+
+int nvme_identify_ns(struct nvme_ctrl *dev, unsigned nsid,
+		struct nvme_id_ns **id)
+{
+	struct nvme_command c = { };
+	int error;
+
+	/* gcc-4.4.4 (at least) has issues with initializers and anon unions */
+	c.identify.opcode = nvme_admin_identify,
+	c.identify.nsid = cpu_to_le32(nsid),
+
+	*id = kmalloc(sizeof(struct nvme_id_ns), GFP_KERNEL);
+	if (!*id)
+		return -ENOMEM;
+
+	error = nvme_submit_sync_cmd(dev->admin_q, &c, *id,
+			sizeof(struct nvme_id_ns));
+	if (error)
+		kfree(*id);
+	return error;
+}
+
+int nvme_get_features(struct nvme_ctrl *dev, unsigned fid, unsigned nsid,
+					dma_addr_t dma_addr, u32 *result)
+{
+	struct nvme_command c;
+
+	memset(&c, 0, sizeof(c));
+	c.features.opcode = nvme_admin_get_features;
+	c.features.nsid = cpu_to_le32(nsid);
+	c.features.prp1 = cpu_to_le64(dma_addr);
+	c.features.fid = cpu_to_le32(fid);
+
+	return __nvme_submit_sync_cmd(dev->admin_q, &c, NULL, 0, result, 0);
+}
+
+int nvme_set_features(struct nvme_ctrl *dev, unsigned fid, unsigned dword11,
+					dma_addr_t dma_addr, u32 *result)
+{
+	struct nvme_command c;
+
+	memset(&c, 0, sizeof(c));
+	c.features.opcode = nvme_admin_set_features;
+	c.features.prp1 = cpu_to_le64(dma_addr);
+	c.features.fid = cpu_to_le32(fid);
+	c.features.dword11 = cpu_to_le32(dword11);
+
+	return __nvme_submit_sync_cmd(dev->admin_q, &c, NULL, 0, result, 0);
+}
+
+int nvme_get_log_page(struct nvme_ctrl *dev, struct nvme_smart_log **log)
+{
+	struct nvme_command c = { };
+	int error;
+
+	c.common.opcode = nvme_admin_get_log_page,
+	c.common.nsid = cpu_to_le32(0xFFFFFFFF),
+	c.common.cdw10[0] = cpu_to_le32(
+			(((sizeof(struct nvme_smart_log) / 4) - 1) << 16) |
+			 NVME_LOG_SMART),
+
+	*log = kmalloc(sizeof(struct nvme_smart_log), GFP_KERNEL);
+	if (!*log)
+		return -ENOMEM;
+
+	error = nvme_submit_sync_cmd(dev->admin_q, &c, *log,
+			sizeof(struct nvme_smart_log));
+	if (error)
+		kfree(*log);
+	return error;
+}
+
+int nvme_set_queue_count(struct nvme_ctrl *ctrl, int *count)
+{
+	u32 q_count = (*count - 1) | ((*count - 1) << 16);
+	u32 result;
+	int status, nr_io_queues;
+
+	status = nvme_set_features(ctrl, NVME_FEAT_NUM_QUEUES, q_count, 0,
+			&result);
+	if (status)
+		return status;
+
+	nr_io_queues = min(result & 0xffff, result >> 16) + 1;
+	*count = min(*count, nr_io_queues);
+	return 0;
+}
+
+static int nvme_submit_io(struct nvme_ns *ns, struct nvme_user_io __user *uio)
+{
+	struct nvme_user_io io;
+	struct nvme_command c;
+	unsigned length, meta_len;
+	void __user *metadata;
+
+	if (copy_from_user(&io, uio, sizeof(io)))
+		return -EFAULT;
+
+	switch (io.opcode) {
+	case nvme_cmd_write:
+	case nvme_cmd_read:
+	case nvme_cmd_compare:
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	length = (io.nblocks + 1) << ns->lba_shift;
+	meta_len = (io.nblocks + 1) * ns->ms;
+	metadata = (void __user *)(uintptr_t)io.metadata;
+
+	if (ns->ext) {
+		length += meta_len;
+		meta_len = 0;
+	} else if (meta_len) {
+		if ((io.metadata & 3) || !io.metadata)
+			return -EINVAL;
+	}
+
+	memset(&c, 0, sizeof(c));
+	c.rw.opcode = io.opcode;
+	c.rw.flags = io.flags;
+	c.rw.nsid = cpu_to_le32(ns->ns_id);
+	c.rw.slba = cpu_to_le64(io.slba);
+	c.rw.length = cpu_to_le16(io.nblocks);
+	c.rw.control = cpu_to_le16(io.control);
+	c.rw.dsmgmt = cpu_to_le32(io.dsmgmt);
+	c.rw.reftag = cpu_to_le32(io.reftag);
+	c.rw.apptag = cpu_to_le16(io.apptag);
+	c.rw.appmask = cpu_to_le16(io.appmask);
+
+	return __nvme_submit_user_cmd(ns->queue, &c,
+			(void __user *)(uintptr_t)io.addr, length,
+			metadata, meta_len, io.slba, NULL, 0);
+}
+
+static int nvme_user_cmd(struct nvme_ctrl *ctrl, struct nvme_ns *ns,
+			struct nvme_passthru_cmd __user *ucmd)
+{
+	struct nvme_passthru_cmd cmd;
+	struct nvme_command c;
+	unsigned timeout = 0;
+	int status;
+
+	if (!capable(CAP_SYS_ADMIN))
+		return -EACCES;
+	if (copy_from_user(&cmd, ucmd, sizeof(cmd)))
+		return -EFAULT;
+
+	memset(&c, 0, sizeof(c));
+	c.common.opcode = cmd.opcode;
+	c.common.flags = cmd.flags;
+	c.common.nsid = cpu_to_le32(cmd.nsid);
+	c.common.cdw2[0] = cpu_to_le32(cmd.cdw2);
+	c.common.cdw2[1] = cpu_to_le32(cmd.cdw3);
+	c.common.cdw10[0] = cpu_to_le32(cmd.cdw10);
+	c.common.cdw10[1] = cpu_to_le32(cmd.cdw11);
+	c.common.cdw10[2] = cpu_to_le32(cmd.cdw12);
+	c.common.cdw10[3] = cpu_to_le32(cmd.cdw13);
+	c.common.cdw10[4] = cpu_to_le32(cmd.cdw14);
+	c.common.cdw10[5] = cpu_to_le32(cmd.cdw15);
+
+	if (cmd.timeout_ms)
+		timeout = msecs_to_jiffies(cmd.timeout_ms);
+
+	status = nvme_submit_user_cmd(ns ? ns->queue : ctrl->admin_q, &c,
+			(void __user *)(uintptr_t)cmd.addr, cmd.data_len,
+			&cmd.result, timeout);
+	if (status >= 0) {
+		if (put_user(cmd.result, &ucmd->result))
+			return -EFAULT;
+	}
+
+	return status;
+}
+
+static int nvme_ioctl(struct block_device *bdev, fmode_t mode,
+		unsigned int cmd, unsigned long arg)
+{
+	struct nvme_ns *ns = bdev->bd_disk->private_data;
+
+	switch (cmd) {
+	case NVME_IOCTL_ID:
+		force_successful_syscall_return();
+		return ns->ns_id;
+	case NVME_IOCTL_ADMIN_CMD:
+		return nvme_user_cmd(ns->ctrl, NULL, (void __user *)arg);
+	case NVME_IOCTL_IO_CMD:
+		return nvme_user_cmd(ns->ctrl, ns, (void __user *)arg);
+	case NVME_IOCTL_SUBMIT_IO:
+		return nvme_submit_io(ns, (void __user *)arg);
+#ifdef CONFIG_BLK_DEV_NVME_SCSI
+	case SG_GET_VERSION_NUM:
+		return nvme_sg_get_version_num((void __user *)arg);
+	case SG_IO:
+		return nvme_sg_io(ns, (void __user *)arg);
+#endif
+	default:
+		return -ENOTTY;
+	}
+}
+
+#ifdef CONFIG_COMPAT
+static int nvme_compat_ioctl(struct block_device *bdev, fmode_t mode,
+			unsigned int cmd, unsigned long arg)
+{
+	switch (cmd) {
+	case SG_IO:
+		return -ENOIOCTLCMD;
+	}
+	return nvme_ioctl(bdev, mode, cmd, arg);
+}
+#else
+#define nvme_compat_ioctl	NULL
+#endif
+
+static int nvme_open(struct block_device *bdev, fmode_t mode)
+{
+	return nvme_get_ns_from_disk(bdev->bd_disk) ? 0 : -ENXIO;
+}
+
+static void nvme_release(struct gendisk *disk, fmode_t mode)
+{
+	nvme_put_ns(disk->private_data);
+}
+
+static int nvme_getgeo(struct block_device *bdev, struct hd_geometry *geo)
+{
+	/* some standard values */
+	geo->heads = 1 << 6;
+	geo->sectors = 1 << 5;
+	geo->cylinders = get_capacity(bdev->bd_disk) >> 11;
+	return 0;
+}
+
+#ifdef CONFIG_BLK_DEV_INTEGRITY
+static void nvme_init_integrity(struct nvme_ns *ns)
+{
+	struct blk_integrity integrity;
+
+	switch (ns->pi_type) {
+	case NVME_NS_DPS_PI_TYPE3:
+		integrity.profile = &t10_pi_type3_crc;
+		break;
+	case NVME_NS_DPS_PI_TYPE1:
+	case NVME_NS_DPS_PI_TYPE2:
+		integrity.profile = &t10_pi_type1_crc;
+		break;
+	default:
+		integrity.profile = NULL;
+		break;
+	}
+	integrity.tuple_size = ns->ms;
+	blk_integrity_register(ns->disk, &integrity);
+	blk_queue_max_integrity_segments(ns->queue, 1);
+}
+#else
+static void nvme_init_integrity(struct nvme_ns *ns)
+{
+}
+#endif /* CONFIG_BLK_DEV_INTEGRITY */
+
+static void nvme_config_discard(struct nvme_ns *ns)
+{
+	struct nvme_ctrl *ctrl = ns->ctrl;
+	u32 logical_block_size = queue_logical_block_size(ns->queue);
+
+	if (ctrl->quirks & NVME_QUIRK_DISCARD_ZEROES)
+		ns->queue->limits.discard_zeroes_data = 1;
+	else
+		ns->queue->limits.discard_zeroes_data = 0;
+
+	ns->queue->limits.discard_alignment = logical_block_size;
+	ns->queue->limits.discard_granularity = logical_block_size;
+	blk_queue_max_discard_sectors(ns->queue, 0xffffffff);
+	queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, ns->queue);
+}
+
+static int nvme_revalidate_disk(struct gendisk *disk)
+{
+	struct nvme_ns *ns = disk->private_data;
+	struct nvme_id_ns *id;
+	u8 lbaf, pi_type;
+	u16 old_ms;
+	unsigned short bs;
+
+	if (test_bit(NVME_NS_DEAD, &ns->flags)) {
+		set_capacity(disk, 0);
+		return -ENODEV;
+	}
+	if (nvme_identify_ns(ns->ctrl, ns->ns_id, &id)) {
+		dev_warn(ns->ctrl->dev, "%s: Identify failure nvme%dn%d\n",
+				__func__, ns->ctrl->instance, ns->ns_id);
+		return -ENODEV;
+	}
+	if (id->ncap == 0) {
+		kfree(id);
+		return -ENODEV;
+	}
+
+	if (nvme_nvm_ns_supported(ns, id) && ns->type != NVME_NS_LIGHTNVM) {
+		if (nvme_nvm_register(ns->queue, disk->disk_name)) {
+			dev_warn(ns->ctrl->dev,
+				"%s: LightNVM init failure\n", __func__);
+			kfree(id);
+			return -ENODEV;
+		}
+		ns->type = NVME_NS_LIGHTNVM;
+	}
+
+	if (ns->ctrl->vs >= NVME_VS(1, 1))
+		memcpy(ns->eui, id->eui64, sizeof(ns->eui));
+	if (ns->ctrl->vs >= NVME_VS(1, 2))
+		memcpy(ns->uuid, id->nguid, sizeof(ns->uuid));
+
+	old_ms = ns->ms;
+	lbaf = id->flbas & NVME_NS_FLBAS_LBA_MASK;
+	ns->lba_shift = id->lbaf[lbaf].ds;
+	ns->ms = le16_to_cpu(id->lbaf[lbaf].ms);
+	ns->ext = ns->ms && (id->flbas & NVME_NS_FLBAS_META_EXT);
+
+	/*
+	 * If identify namespace failed, use default 512 byte block size so
+	 * block layer can use before failing read/write for 0 capacity.
+	 */
+	if (ns->lba_shift == 0)
+		ns->lba_shift = 9;
+	bs = 1 << ns->lba_shift;
+	/* XXX: PI implementation requires metadata equal t10 pi tuple size */
+	pi_type = ns->ms == sizeof(struct t10_pi_tuple) ?
+					id->dps & NVME_NS_DPS_PI_MASK : 0;
+
+	blk_mq_freeze_queue(disk->queue);
+	if (blk_get_integrity(disk) && (ns->pi_type != pi_type ||
+				ns->ms != old_ms ||
+				bs != queue_logical_block_size(disk->queue) ||
+				(ns->ms && ns->ext)))
+		blk_integrity_unregister(disk);
+
+	ns->pi_type = pi_type;
+	blk_queue_logical_block_size(ns->queue, bs);
+
+	if (ns->ms && !blk_get_integrity(disk) && !ns->ext)
+		nvme_init_integrity(ns);
+	if (ns->ms && !(ns->ms == 8 && ns->pi_type) && !blk_get_integrity(disk))
+		set_capacity(disk, 0);
+	else
+		set_capacity(disk, le64_to_cpup(&id->nsze) << (ns->lba_shift - 9));
+
+	if (ns->ctrl->oncs & NVME_CTRL_ONCS_DSM)
+		nvme_config_discard(ns);
+	blk_mq_unfreeze_queue(disk->queue);
+
+	kfree(id);
+	return 0;
+}
+
+static char nvme_pr_type(enum pr_type type)
+{
+	switch (type) {
+	case PR_WRITE_EXCLUSIVE:
+		return 1;
+	case PR_EXCLUSIVE_ACCESS:
+		return 2;
+	case PR_WRITE_EXCLUSIVE_REG_ONLY:
+		return 3;
+	case PR_EXCLUSIVE_ACCESS_REG_ONLY:
+		return 4;
+	case PR_WRITE_EXCLUSIVE_ALL_REGS:
+		return 5;
+	case PR_EXCLUSIVE_ACCESS_ALL_REGS:
+		return 6;
+	default:
+		return 0;
+	}
+};
+
+static int nvme_pr_command(struct block_device *bdev, u32 cdw10,
+				u64 key, u64 sa_key, u8 op)
+{
+	struct nvme_ns *ns = bdev->bd_disk->private_data;
+	struct nvme_command c;
+	u8 data[16] = { 0, };
+
+	put_unaligned_le64(key, &data[0]);
+	put_unaligned_le64(sa_key, &data[8]);
+
+	memset(&c, 0, sizeof(c));
+	c.common.opcode = op;
+	c.common.nsid = cpu_to_le32(ns->ns_id);
+	c.common.cdw10[0] = cpu_to_le32(cdw10);
+
+	return nvme_submit_sync_cmd(ns->queue, &c, data, 16);
+}
+
+static int nvme_pr_register(struct block_device *bdev, u64 old,
+		u64 new, unsigned flags)
+{
+	u32 cdw10;
+
+	if (flags & ~PR_FL_IGNORE_KEY)
+		return -EOPNOTSUPP;
+
+	cdw10 = old ? 2 : 0;
+	cdw10 |= (flags & PR_FL_IGNORE_KEY) ? 1 << 3 : 0;
+	cdw10 |= (1 << 30) | (1 << 31); /* PTPL=1 */
+	return nvme_pr_command(bdev, cdw10, old, new, nvme_cmd_resv_register);
+}
+
+static int nvme_pr_reserve(struct block_device *bdev, u64 key,
+		enum pr_type type, unsigned flags)
+{
+	u32 cdw10;
+
+	if (flags & ~PR_FL_IGNORE_KEY)
+		return -EOPNOTSUPP;
+
+	cdw10 = nvme_pr_type(type) << 8;
+	cdw10 |= ((flags & PR_FL_IGNORE_KEY) ? 1 << 3 : 0);
+	return nvme_pr_command(bdev, cdw10, key, 0, nvme_cmd_resv_acquire);
+}
+
+static int nvme_pr_preempt(struct block_device *bdev, u64 old, u64 new,
+		enum pr_type type, bool abort)
+{
+	u32 cdw10 = nvme_pr_type(type) << 8 | abort ? 2 : 1;
+	return nvme_pr_command(bdev, cdw10, old, new, nvme_cmd_resv_acquire);
+}
+
+static int nvme_pr_clear(struct block_device *bdev, u64 key)
+{
+	u32 cdw10 = 1 | (key ? 1 << 3 : 0);
+	return nvme_pr_command(bdev, cdw10, key, 0, nvme_cmd_resv_register);
+}
+
+static int nvme_pr_release(struct block_device *bdev, u64 key, enum pr_type type)
+{
+	u32 cdw10 = nvme_pr_type(type) << 8 | key ? 1 << 3 : 0;
+	return nvme_pr_command(bdev, cdw10, key, 0, nvme_cmd_resv_release);
+}
+
+static const struct pr_ops nvme_pr_ops = {
+	.pr_register	= nvme_pr_register,
+	.pr_reserve	= nvme_pr_reserve,
+	.pr_release	= nvme_pr_release,
+	.pr_preempt	= nvme_pr_preempt,
+	.pr_clear	= nvme_pr_clear,
+};
+
+static const struct block_device_operations nvme_fops = {
+	.owner		= THIS_MODULE,
+	.ioctl		= nvme_ioctl,
+	.compat_ioctl	= nvme_compat_ioctl,
+	.open		= nvme_open,
+	.release	= nvme_release,
+	.getgeo		= nvme_getgeo,
+	.revalidate_disk= nvme_revalidate_disk,
+	.pr_ops		= &nvme_pr_ops,
+};
+
+static int nvme_wait_ready(struct nvme_ctrl *ctrl, u64 cap, bool enabled)
+{
+	unsigned long timeout =
+		((NVME_CAP_TIMEOUT(cap) + 1) * HZ / 2) + jiffies;
+	u32 csts, bit = enabled ? NVME_CSTS_RDY : 0;
+	int ret;
+
+	while ((ret = ctrl->ops->reg_read32(ctrl, NVME_REG_CSTS, &csts)) == 0) {
+		if ((csts & NVME_CSTS_RDY) == bit)
+			break;
+
+		msleep(100);
+		if (fatal_signal_pending(current))
+			return -EINTR;
+		if (time_after(jiffies, timeout)) {
+			dev_err(ctrl->dev,
+				"Device not ready; aborting %s\n", enabled ?
+						"initialisation" : "reset");
+			return -ENODEV;
+		}
+	}
+
+	return ret;
+}
+
+/*
+ * If the device has been passed off to us in an enabled state, just clear
+ * the enabled bit.  The spec says we should set the 'shutdown notification
+ * bits', but doing so may cause the device to complete commands to the
+ * admin queue ... and we don't know what memory that might be pointing at!
+ */
+int nvme_disable_ctrl(struct nvme_ctrl *ctrl, u64 cap)
+{
+	int ret;
+
+	ctrl->ctrl_config &= ~NVME_CC_SHN_MASK;
+	ctrl->ctrl_config &= ~NVME_CC_ENABLE;
+
+	ret = ctrl->ops->reg_write32(ctrl, NVME_REG_CC, ctrl->ctrl_config);
+	if (ret)
+		return ret;
+
+	/* Checking for ctrl->tagset is a trick to avoid sleeping on module
+	 * load, since we only need the quirk on reset_controller. Notice
+	 * that the HGST device needs this delay only in firmware activation
+	 * procedure; unfortunately we have no (easy) way to verify this.
+	 */
+	if ((ctrl->quirks & NVME_QUIRK_DELAY_BEFORE_CHK_RDY) && ctrl->tagset)
+		msleep(NVME_QUIRK_DELAY_AMOUNT);
+
+	return nvme_wait_ready(ctrl, cap, false);
+}
+
+int nvme_enable_ctrl(struct nvme_ctrl *ctrl, u64 cap)
+{
+	/*
+	 * Default to a 4K page size, with the intention to update this
+	 * path in the future to accomodate architectures with differing
+	 * kernel and IO page sizes.
+	 */
+	unsigned dev_page_min = NVME_CAP_MPSMIN(cap) + 12, page_shift = 12;
+	int ret;
+
+	if (page_shift < dev_page_min) {
+		dev_err(ctrl->dev,
+			"Minimum device page size %u too large for host (%u)\n",
+			1 << dev_page_min, 1 << page_shift);
+		return -ENODEV;
+	}
+
+	ctrl->page_size = 1 << page_shift;
+
+	ctrl->ctrl_config = NVME_CC_CSS_NVM;
+	ctrl->ctrl_config |= (page_shift - 12) << NVME_CC_MPS_SHIFT;
+	ctrl->ctrl_config |= NVME_CC_ARB_RR | NVME_CC_SHN_NONE;
+	ctrl->ctrl_config |= NVME_CC_IOSQES | NVME_CC_IOCQES;
+	ctrl->ctrl_config |= NVME_CC_ENABLE;
+
+	ret = ctrl->ops->reg_write32(ctrl, NVME_REG_CC, ctrl->ctrl_config);
+	if (ret)
+		return ret;
+	return nvme_wait_ready(ctrl, cap, true);
+}
+
+int nvme_shutdown_ctrl(struct nvme_ctrl *ctrl)
+{
+	unsigned long timeout = SHUTDOWN_TIMEOUT + jiffies;
+	u32 csts;
+	int ret;
+
+	ctrl->ctrl_config &= ~NVME_CC_SHN_MASK;
+	ctrl->ctrl_config |= NVME_CC_SHN_NORMAL;
+
+	ret = ctrl->ops->reg_write32(ctrl, NVME_REG_CC, ctrl->ctrl_config);
+	if (ret)
+		return ret;
+
+	while ((ret = ctrl->ops->reg_read32(ctrl, NVME_REG_CSTS, &csts)) == 0) {
+		if ((csts & NVME_CSTS_SHST_MASK) == NVME_CSTS_SHST_CMPLT)
+			break;
+
+		msleep(100);
+		if (fatal_signal_pending(current))
+			return -EINTR;
+		if (time_after(jiffies, timeout)) {
+			dev_err(ctrl->dev,
+				"Device shutdown incomplete; abort shutdown\n");
+			return -ENODEV;
+		}
+	}
+
+	return ret;
+}
+
+static void nvme_set_queue_limits(struct nvme_ctrl *ctrl,
+		struct request_queue *q)
+{
+	if (ctrl->max_hw_sectors) {
+		u32 max_segments =
+			(ctrl->max_hw_sectors / (ctrl->page_size >> 9)) + 1;
+
+		blk_queue_max_hw_sectors(q, ctrl->max_hw_sectors);
+		blk_queue_max_segments(q, min_t(u32, max_segments, USHRT_MAX));
+	}
+	if (ctrl->stripe_size)
+		blk_queue_chunk_sectors(q, ctrl->stripe_size >> 9);
+	if (ctrl->vwc & NVME_CTRL_VWC_PRESENT)
+		blk_queue_flush(q, REQ_FLUSH | REQ_FUA);
+	blk_queue_virt_boundary(q, ctrl->page_size - 1);
+}
+
+/*
+ * Initialize the cached copies of the Identify data and various controller
+ * register in our nvme_ctrl structure.  This should be called as soon as
+ * the admin queue is fully up and running.
+ */
+int nvme_init_identify(struct nvme_ctrl *ctrl)
+{
+	struct nvme_id_ctrl *id;
+	u64 cap;
+	int ret, page_shift;
+
+	ret = ctrl->ops->reg_read32(ctrl, NVME_REG_VS, &ctrl->vs);
+	if (ret) {
+		dev_err(ctrl->dev, "Reading VS failed (%d)\n", ret);
+		return ret;
+	}
+
+	ret = ctrl->ops->reg_read64(ctrl, NVME_REG_CAP, &cap);
+	if (ret) {
+		dev_err(ctrl->dev, "Reading CAP failed (%d)\n", ret);
+		return ret;
+	}
+	page_shift = NVME_CAP_MPSMIN(cap) + 12;
+
+	if (ctrl->vs >= NVME_VS(1, 1))
+		ctrl->subsystem = NVME_CAP_NSSRC(cap);
+
+	ret = nvme_identify_ctrl(ctrl, &id);
+	if (ret) {
+		dev_err(ctrl->dev, "Identify Controller failed (%d)\n", ret);
+		return -EIO;
+	}
+
+	ctrl->oncs = le16_to_cpup(&id->oncs);
+	atomic_set(&ctrl->abort_limit, id->acl + 1);
+	ctrl->vwc = id->vwc;
+	memcpy(ctrl->serial, id->sn, sizeof(id->sn));
+	memcpy(ctrl->model, id->mn, sizeof(id->mn));
+	memcpy(ctrl->firmware_rev, id->fr, sizeof(id->fr));
+	if (id->mdts)
+		ctrl->max_hw_sectors = 1 << (id->mdts + page_shift - 9);
+	else
+		ctrl->max_hw_sectors = UINT_MAX;
+
+	if ((ctrl->quirks & NVME_QUIRK_STRIPE_SIZE) && id->vs[3]) {
+		unsigned int max_hw_sectors;
+
+		ctrl->stripe_size = 1 << (id->vs[3] + page_shift);
+		max_hw_sectors = ctrl->stripe_size >> (page_shift - 9);
+		if (ctrl->max_hw_sectors) {
+			ctrl->max_hw_sectors = min(max_hw_sectors,
+							ctrl->max_hw_sectors);
+		} else {
+			ctrl->max_hw_sectors = max_hw_sectors;
+		}
+	}
+
+	nvme_set_queue_limits(ctrl, ctrl->admin_q);
+
+	kfree(id);
+	return 0;
+}
+
+static int nvme_dev_open(struct inode *inode, struct file *file)
+{
+	struct nvme_ctrl *ctrl;
+	int instance = iminor(inode);
+	int ret = -ENODEV;
+
+	spin_lock(&dev_list_lock);
+	list_for_each_entry(ctrl, &nvme_ctrl_list, node) {
+		if (ctrl->instance != instance)
+			continue;
+
+		if (!ctrl->admin_q) {
+			ret = -EWOULDBLOCK;
+			break;
+		}
+		if (!kref_get_unless_zero(&ctrl->kref))
+			break;
+		file->private_data = ctrl;
+		ret = 0;
+		break;
+	}
+	spin_unlock(&dev_list_lock);
+
+	return ret;
+}
+
+static int nvme_dev_release(struct inode *inode, struct file *file)
+{
+	nvme_put_ctrl(file->private_data);
+	return 0;
+}
+
+static int nvme_dev_user_cmd(struct nvme_ctrl *ctrl, void __user *argp)
+{
+	struct nvme_ns *ns;
+	int ret;
+
+	mutex_lock(&ctrl->namespaces_mutex);
+	if (list_empty(&ctrl->namespaces)) {
+		ret = -ENOTTY;
+		goto out_unlock;
+	}
+
+	ns = list_first_entry(&ctrl->namespaces, struct nvme_ns, list);
+	if (ns != list_last_entry(&ctrl->namespaces, struct nvme_ns, list)) {
+		dev_warn(ctrl->dev,
+			"NVME_IOCTL_IO_CMD not supported when multiple namespaces present!\n");
+		ret = -EINVAL;
+		goto out_unlock;
+	}
+
+	dev_warn(ctrl->dev,
+		"using deprecated NVME_IOCTL_IO_CMD ioctl on the char device!\n");
+	kref_get(&ns->kref);
+	mutex_unlock(&ctrl->namespaces_mutex);
+
+	ret = nvme_user_cmd(ctrl, ns, argp);
+	nvme_put_ns(ns);
+	return ret;
+
+out_unlock:
+	mutex_unlock(&ctrl->namespaces_mutex);
+	return ret;
+}
+
+static long nvme_dev_ioctl(struct file *file, unsigned int cmd,
+		unsigned long arg)
+{
+	struct nvme_ctrl *ctrl = file->private_data;
+	void __user *argp = (void __user *)arg;
+
+	switch (cmd) {
+	case NVME_IOCTL_ADMIN_CMD:
+		return nvme_user_cmd(ctrl, NULL, argp);
+	case NVME_IOCTL_IO_CMD:
+		return nvme_dev_user_cmd(ctrl, argp);
+	case NVME_IOCTL_RESET:
+		dev_warn(ctrl->dev, "resetting controller\n");
+		return ctrl->ops->reset_ctrl(ctrl);
+	case NVME_IOCTL_SUBSYS_RESET:
+		return nvme_reset_subsystem(ctrl);
+	default:
+		return -ENOTTY;
+	}
+}
+
+static const struct file_operations nvme_dev_fops = {
+	.owner		= THIS_MODULE,
+	.open		= nvme_dev_open,
+	.release	= nvme_dev_release,
+	.unlocked_ioctl	= nvme_dev_ioctl,
+	.compat_ioctl	= nvme_dev_ioctl,
+};
+
+static ssize_t nvme_sysfs_reset(struct device *dev,
+				struct device_attribute *attr, const char *buf,
+				size_t count)
+{
+	struct nvme_ctrl *ctrl = dev_get_drvdata(dev);
+	int ret;
+
+	ret = ctrl->ops->reset_ctrl(ctrl);
+	if (ret < 0)
+		return ret;
+	return count;
+}
+static DEVICE_ATTR(reset_controller, S_IWUSR, NULL, nvme_sysfs_reset);
+
+static ssize_t uuid_show(struct device *dev, struct device_attribute *attr,
+								char *buf)
+{
+	struct nvme_ns *ns = dev_to_disk(dev)->private_data;
+	return sprintf(buf, "%pU\n", ns->uuid);
+}
+static DEVICE_ATTR(uuid, S_IRUGO, uuid_show, NULL);
+
+static ssize_t eui_show(struct device *dev, struct device_attribute *attr,
+								char *buf)
+{
+	struct nvme_ns *ns = dev_to_disk(dev)->private_data;
+	return sprintf(buf, "%8phd\n", ns->eui);
+}
+static DEVICE_ATTR(eui, S_IRUGO, eui_show, NULL);
+
+static ssize_t nsid_show(struct device *dev, struct device_attribute *attr,
+								char *buf)
+{
+	struct nvme_ns *ns = dev_to_disk(dev)->private_data;
+	return sprintf(buf, "%d\n", ns->ns_id);
+}
+static DEVICE_ATTR(nsid, S_IRUGO, nsid_show, NULL);
+
+static struct attribute *nvme_ns_attrs[] = {
+	&dev_attr_uuid.attr,
+	&dev_attr_eui.attr,
+	&dev_attr_nsid.attr,
+	NULL,
+};
+
+static umode_t nvme_attrs_are_visible(struct kobject *kobj,
+		struct attribute *a, int n)
+{
+	struct device *dev = container_of(kobj, struct device, kobj);
+	struct nvme_ns *ns = dev_to_disk(dev)->private_data;
+
+	if (a == &dev_attr_uuid.attr) {
+		if (!memchr_inv(ns->uuid, 0, sizeof(ns->uuid)))
+			return 0;
+	}
+	if (a == &dev_attr_eui.attr) {
+		if (!memchr_inv(ns->eui, 0, sizeof(ns->eui)))
+			return 0;
+	}
+	return a->mode;
+}
+
+static const struct attribute_group nvme_ns_attr_group = {
+	.attrs		= nvme_ns_attrs,
+	.is_visible	= nvme_attrs_are_visible,
+};
+
+#define nvme_show_function(field)						\
+static ssize_t  field##_show(struct device *dev,				\
+			    struct device_attribute *attr, char *buf)		\
+{										\
+        struct nvme_ctrl *ctrl = dev_get_drvdata(dev);				\
+        return sprintf(buf, "%.*s\n", (int)sizeof(ctrl->field), ctrl->field);	\
+}										\
+static DEVICE_ATTR(field, S_IRUGO, field##_show, NULL);
+
+nvme_show_function(model);
+nvme_show_function(serial);
+nvme_show_function(firmware_rev);
+
+static struct attribute *nvme_dev_attrs[] = {
+	&dev_attr_reset_controller.attr,
+	&dev_attr_model.attr,
+	&dev_attr_serial.attr,
+	&dev_attr_firmware_rev.attr,
+	NULL
+};
+
+static struct attribute_group nvme_dev_attrs_group = {
+	.attrs = nvme_dev_attrs,
+};
+
+static const struct attribute_group *nvme_dev_attr_groups[] = {
+	&nvme_dev_attrs_group,
+	NULL,
+};
+
+static int ns_cmp(void *priv, struct list_head *a, struct list_head *b)
+{
+	struct nvme_ns *nsa = container_of(a, struct nvme_ns, list);
+	struct nvme_ns *nsb = container_of(b, struct nvme_ns, list);
+
+	return nsa->ns_id - nsb->ns_id;
+}
+
+static struct nvme_ns *nvme_find_ns(struct nvme_ctrl *ctrl, unsigned nsid)
+{
+	struct nvme_ns *ns;
+
+	lockdep_assert_held(&ctrl->namespaces_mutex);
+
+	list_for_each_entry(ns, &ctrl->namespaces, list) {
+		if (ns->ns_id == nsid)
+			return ns;
+		if (ns->ns_id > nsid)
+			break;
+	}
+	return NULL;
+}
+
+static void nvme_alloc_ns(struct nvme_ctrl *ctrl, unsigned nsid)
+{
+	struct nvme_ns *ns;
+	struct gendisk *disk;
+	int node = dev_to_node(ctrl->dev);
+
+	lockdep_assert_held(&ctrl->namespaces_mutex);
+
+	ns = kzalloc_node(sizeof(*ns), GFP_KERNEL, node);
+	if (!ns)
+		return;
+
+	ns->queue = blk_mq_init_queue(ctrl->tagset);
+	if (IS_ERR(ns->queue))
+		goto out_free_ns;
+	queue_flag_set_unlocked(QUEUE_FLAG_NOMERGES, ns->queue);
+	queue_flag_set_unlocked(QUEUE_FLAG_NONROT, ns->queue);
+	ns->queue->queuedata = ns;
+	ns->ctrl = ctrl;
+
+	disk = alloc_disk_node(0, node);
+	if (!disk)
+		goto out_free_queue;
+
+	kref_init(&ns->kref);
+	ns->ns_id = nsid;
+	ns->disk = disk;
+	ns->lba_shift = 9; /* set to a default value for 512 until disk is validated */
+
+
+	blk_queue_logical_block_size(ns->queue, 1 << ns->lba_shift);
+	nvme_set_queue_limits(ctrl, ns->queue);
+
+	disk->major = nvme_major;
+	disk->first_minor = 0;
+	disk->fops = &nvme_fops;
+	disk->private_data = ns;
+	disk->queue = ns->queue;
+	disk->driverfs_dev = ctrl->device;
+	disk->flags = GENHD_FL_EXT_DEVT;
+	sprintf(disk->disk_name, "nvme%dn%d", ctrl->instance, nsid);
+
+	if (nvme_revalidate_disk(ns->disk))
+		goto out_free_disk;
+
+	list_add_tail(&ns->list, &ctrl->namespaces);
+	kref_get(&ctrl->kref);
+	if (ns->type == NVME_NS_LIGHTNVM)
+		return;
+
+	add_disk(ns->disk);
+	if (sysfs_create_group(&disk_to_dev(ns->disk)->kobj,
+					&nvme_ns_attr_group))
+		pr_warn("%s: failed to create sysfs group for identification\n",
+			ns->disk->disk_name);
+	return;
+ out_free_disk:
+	kfree(disk);
+ out_free_queue:
+	blk_cleanup_queue(ns->queue);
+ out_free_ns:
+	kfree(ns);
+}
+
+static void nvme_ns_remove(struct nvme_ns *ns)
+{
+	if (test_and_set_bit(NVME_NS_REMOVING, &ns->flags))
+		return;
+
+	if (ns->disk->flags & GENHD_FL_UP) {
+		if (blk_get_integrity(ns->disk))
+			blk_integrity_unregister(ns->disk);
+		sysfs_remove_group(&disk_to_dev(ns->disk)->kobj,
+					&nvme_ns_attr_group);
+		del_gendisk(ns->disk);
+		blk_mq_abort_requeue_list(ns->queue);
+		blk_cleanup_queue(ns->queue);
+	}
+	mutex_lock(&ns->ctrl->namespaces_mutex);
+	list_del_init(&ns->list);
+	mutex_unlock(&ns->ctrl->namespaces_mutex);
+	nvme_put_ns(ns);
+}
+
+static void nvme_validate_ns(struct nvme_ctrl *ctrl, unsigned nsid)
+{
+	struct nvme_ns *ns;
+
+	ns = nvme_find_ns(ctrl, nsid);
+	if (ns) {
+		if (revalidate_disk(ns->disk))
+			nvme_ns_remove(ns);
+	} else
+		nvme_alloc_ns(ctrl, nsid);
+}
+
+static int nvme_scan_ns_list(struct nvme_ctrl *ctrl, unsigned nn)
+{
+	struct nvme_ns *ns;
+	__le32 *ns_list;
+	unsigned i, j, nsid, prev = 0, num_lists = DIV_ROUND_UP(nn, 1024);
+	int ret = 0;
+
+	ns_list = kzalloc(0x1000, GFP_KERNEL);
+	if (!ns_list)
+		return -ENOMEM;
+
+	for (i = 0; i < num_lists; i++) {
+		ret = nvme_identify_ns_list(ctrl, prev, ns_list);
+		if (ret)
+			goto out;
+
+		for (j = 0; j < min(nn, 1024U); j++) {
+			nsid = le32_to_cpu(ns_list[j]);
+			if (!nsid)
+				goto out;
+
+			nvme_validate_ns(ctrl, nsid);
+
+			while (++prev < nsid) {
+				ns = nvme_find_ns(ctrl, prev);
+				if (ns)
+					nvme_ns_remove(ns);
+			}
+		}
+		nn -= j;
+	}
+ out:
+	kfree(ns_list);
+	return ret;
+}
+
+static void __nvme_scan_namespaces(struct nvme_ctrl *ctrl, unsigned nn)
+{
+	struct nvme_ns *ns, *next;
+	unsigned i;
+
+	lockdep_assert_held(&ctrl->namespaces_mutex);
+
+	for (i = 1; i <= nn; i++)
+		nvme_validate_ns(ctrl, i);
+
+	list_for_each_entry_safe(ns, next, &ctrl->namespaces, list) {
+		if (ns->ns_id > nn)
+			nvme_ns_remove(ns);
+	}
+}
+
+void nvme_scan_namespaces(struct nvme_ctrl *ctrl)
+{
+	struct nvme_id_ctrl *id;
+	unsigned nn;
+
+	if (nvme_identify_ctrl(ctrl, &id))
+		return;
+
+	mutex_lock(&ctrl->namespaces_mutex);
+	nn = le32_to_cpu(id->nn);
+	if (ctrl->vs >= NVME_VS(1, 1) &&
+	    !(ctrl->quirks & NVME_QUIRK_IDENTIFY_CNS)) {
+		if (!nvme_scan_ns_list(ctrl, nn))
+			goto done;
+	}
+	__nvme_scan_namespaces(ctrl, le32_to_cpup(&id->nn));
+ done:
+	list_sort(NULL, &ctrl->namespaces, ns_cmp);
+	mutex_unlock(&ctrl->namespaces_mutex);
+	kfree(id);
+}
+
+void nvme_remove_namespaces(struct nvme_ctrl *ctrl)
+{
+	struct nvme_ns *ns, *next;
+
+	list_for_each_entry_safe(ns, next, &ctrl->namespaces, list)
+		nvme_ns_remove(ns);
+}
+
+static DEFINE_IDA(nvme_instance_ida);
+
+static int nvme_set_instance(struct nvme_ctrl *ctrl)
+{
+	int instance, error;
+
+	do {
+		if (!ida_pre_get(&nvme_instance_ida, GFP_KERNEL))
+			return -ENODEV;
+
+		spin_lock(&dev_list_lock);
+		error = ida_get_new(&nvme_instance_ida, &instance);
+		spin_unlock(&dev_list_lock);
+	} while (error == -EAGAIN);
+
+	if (error)
+		return -ENODEV;
+
+	ctrl->instance = instance;
+	return 0;
+}
+
+static void nvme_release_instance(struct nvme_ctrl *ctrl)
+{
+	spin_lock(&dev_list_lock);
+	ida_remove(&nvme_instance_ida, ctrl->instance);
+	spin_unlock(&dev_list_lock);
+}
+
+void nvme_uninit_ctrl(struct nvme_ctrl *ctrl)
+ {
+	device_destroy(nvme_class, MKDEV(nvme_char_major, ctrl->instance));
+
+	spin_lock(&dev_list_lock);
+	list_del(&ctrl->node);
+	spin_unlock(&dev_list_lock);
+}
+
+static void nvme_free_ctrl(struct kref *kref)
+{
+	struct nvme_ctrl *ctrl = container_of(kref, struct nvme_ctrl, kref);
+
+	put_device(ctrl->device);
+	nvme_release_instance(ctrl);
+
+	ctrl->ops->free_ctrl(ctrl);
+}
+
+void nvme_put_ctrl(struct nvme_ctrl *ctrl)
+{
+	kref_put(&ctrl->kref, nvme_free_ctrl);
+}
+
+/*
+ * Initialize a NVMe controller structures.  This needs to be called during
+ * earliest initialization so that we have the initialized structured around
+ * during probing.
+ */
+int nvme_init_ctrl(struct nvme_ctrl *ctrl, struct device *dev,
+		const struct nvme_ctrl_ops *ops, unsigned long quirks)
+{
+	int ret;
+
+	INIT_LIST_HEAD(&ctrl->namespaces);
+	mutex_init(&ctrl->namespaces_mutex);
+	kref_init(&ctrl->kref);
+	ctrl->dev = dev;
+	ctrl->ops = ops;
+	ctrl->quirks = quirks;
+
+	ret = nvme_set_instance(ctrl);
+	if (ret)
+		goto out;
+
+	ctrl->device = device_create_with_groups(nvme_class, ctrl->dev,
+				MKDEV(nvme_char_major, ctrl->instance),
+				dev, nvme_dev_attr_groups,
+				"nvme%d", ctrl->instance);
+	if (IS_ERR(ctrl->device)) {
+		ret = PTR_ERR(ctrl->device);
+		goto out_release_instance;
+	}
+	get_device(ctrl->device);
+	dev_set_drvdata(ctrl->device, ctrl);
+
+	spin_lock(&dev_list_lock);
+	list_add_tail(&ctrl->node, &nvme_ctrl_list);
+	spin_unlock(&dev_list_lock);
+
+	return 0;
+out_release_instance:
+	nvme_release_instance(ctrl);
+out:
+	return ret;
+}
+
+/**
+ * nvme_kill_queues(): Ends all namespace queues
+ * @ctrl: the dead controller that needs to end
+ *
+ * Call this function when the driver determines it is unable to get the
+ * controller in a state capable of servicing IO.
+ */
+void nvme_kill_queues(struct nvme_ctrl *ctrl)
+{
+	struct nvme_ns *ns;
+
+	mutex_lock(&ctrl->namespaces_mutex);
+	list_for_each_entry(ns, &ctrl->namespaces, list) {
+		if (!kref_get_unless_zero(&ns->kref))
+			continue;
+
+		/*
+		 * Revalidating a dead namespace sets capacity to 0. This will
+		 * end buffered writers dirtying pages that can't be synced.
+		 */
+		if (!test_and_set_bit(NVME_NS_DEAD, &ns->flags))
+			revalidate_disk(ns->disk);
+
+		blk_set_queue_dying(ns->queue);
+		blk_mq_abort_requeue_list(ns->queue);
+		blk_mq_start_stopped_hw_queues(ns->queue, true);
+
+		nvme_put_ns(ns);
+	}
+	mutex_unlock(&ctrl->namespaces_mutex);
+}
+
+void nvme_stop_queues(struct nvme_ctrl *ctrl)
+{
+	struct nvme_ns *ns;
+
+	mutex_lock(&ctrl->namespaces_mutex);
+	list_for_each_entry(ns, &ctrl->namespaces, list) {
+		spin_lock_irq(ns->queue->queue_lock);
+		queue_flag_set(QUEUE_FLAG_STOPPED, ns->queue);
+		spin_unlock_irq(ns->queue->queue_lock);
+
+		blk_mq_cancel_requeue_work(ns->queue);
+		blk_mq_stop_hw_queues(ns->queue);
+	}
+	mutex_unlock(&ctrl->namespaces_mutex);
+}
+
+void nvme_start_queues(struct nvme_ctrl *ctrl)
+{
+	struct nvme_ns *ns;
+
+	mutex_lock(&ctrl->namespaces_mutex);
+	list_for_each_entry(ns, &ctrl->namespaces, list) {
+		queue_flag_clear_unlocked(QUEUE_FLAG_STOPPED, ns->queue);
+		blk_mq_start_stopped_hw_queues(ns->queue, true);
+		blk_mq_kick_requeue_list(ns->queue);
+	}
+	mutex_unlock(&ctrl->namespaces_mutex);
+}
+
+int __init nvme_core_init(void)
+{
+	int result;
+
+	result = register_blkdev(nvme_major, "nvme");
+	if (result < 0)
+		return result;
+	else if (result > 0)
+		nvme_major = result;
+
+	result = __register_chrdev(nvme_char_major, 0, NVME_MINORS, "nvme",
+							&nvme_dev_fops);
+	if (result < 0)
+		goto unregister_blkdev;
+	else if (result > 0)
+		nvme_char_major = result;
+
+	nvme_class = class_create(THIS_MODULE, "nvme");
+	if (IS_ERR(nvme_class)) {
+		result = PTR_ERR(nvme_class);
+		goto unregister_chrdev;
+	}
+
+	return 0;
+
+ unregister_chrdev:
+	__unregister_chrdev(nvme_char_major, 0, NVME_MINORS, "nvme");
+ unregister_blkdev:
+	unregister_blkdev(nvme_major, "nvme");
+	return result;
+}
+
+void nvme_core_exit(void)
+{
+	unregister_blkdev(nvme_major, "nvme");
+	class_destroy(nvme_class);
+	__unregister_chrdev(nvme_char_major, 0, NVME_MINORS, "nvme");
+}
--- zfcpdump-kernel-4.4.orig/drivers/nvme/host/lightnvm.c
+++ zfcpdump-kernel-4.4/drivers/nvme/host/lightnvm.c
@@ -146,6 +146,16 @@ struct nvme_nvm_command {
 	};
 };
 
+struct nvme_nvm_lp_mlc {
+	__u16			num_pairs;
+	__u8			pairs[886];
+};
+
+struct nvme_nvm_lp_tbl {
+	__u8			id[8];
+	struct nvme_nvm_lp_mlc	mlc;
+};
+
 struct nvme_nvm_id_group {
 	__u8			mtype;
 	__u8			fmtype;
@@ -169,7 +179,8 @@ struct nvme_nvm_id_group {
 	__le32			mpos;
 	__le32			mccap;
 	__le16			cpar;
-	__u8			reserved[906];
+	__u8			reserved[10];
+	struct nvme_nvm_lp_tbl lptbl;
 } __packed;
 
 struct nvme_nvm_addr_format {
@@ -266,6 +277,15 @@ static int init_grps(struct nvm_id *nvm_
 		dst->mccap = le32_to_cpu(src->mccap);
 
 		dst->cpar = le16_to_cpu(src->cpar);
+
+		if (dst->fmtype == NVM_ID_FMTYPE_MLC) {
+			memcpy(dst->lptbl.id, src->lptbl.id, 8);
+			dst->lptbl.mlc.num_pairs =
+					le16_to_cpu(src->lptbl.mlc.num_pairs);
+			/* 4 bits per pair */
+			memcpy(dst->lptbl.mlc.pairs, src->lptbl.mlc.pairs,
+						dst->lptbl.mlc.num_pairs >> 1);
+		}
 	}
 
 	return 0;
@@ -274,7 +294,6 @@ static int init_grps(struct nvm_id *nvm_
 static int nvme_nvm_identity(struct nvm_dev *nvmdev, struct nvm_id *nvm_id)
 {
 	struct nvme_ns *ns = nvmdev->q->queuedata;
-	struct nvme_dev *dev = ns->dev;
 	struct nvme_nvm_id *nvme_nvm_id;
 	struct nvme_nvm_command c = {};
 	int ret;
@@ -287,7 +306,7 @@ static int nvme_nvm_identity(struct nvm_
 	if (!nvme_nvm_id)
 		return -ENOMEM;
 
-	ret = nvme_submit_sync_cmd(dev->admin_q, (struct nvme_command *)&c,
+	ret = nvme_submit_sync_cmd(ns->ctrl->admin_q, (struct nvme_command *)&c,
 				nvme_nvm_id, sizeof(struct nvme_nvm_id));
 	if (ret) {
 		ret = -EIO;
@@ -312,9 +331,8 @@ static int nvme_nvm_get_l2p_tbl(struct n
 				nvm_l2p_update_fn *update_l2p, void *priv)
 {
 	struct nvme_ns *ns = nvmdev->q->queuedata;
-	struct nvme_dev *dev = ns->dev;
 	struct nvme_nvm_command c = {};
-	u32 len = queue_max_hw_sectors(dev->admin_q) << 9;
+	u32 len = queue_max_hw_sectors(ns->ctrl->admin_q) << 9;
 	u32 nlb_pr_rq = len / sizeof(u64);
 	u64 cmd_slba = slba;
 	void *entries;
@@ -332,10 +350,10 @@ static int nvme_nvm_get_l2p_tbl(struct n
 		c.l2p.slba = cpu_to_le64(cmd_slba);
 		c.l2p.nlb = cpu_to_le32(cmd_nlb);
 
-		ret = nvme_submit_sync_cmd(dev->admin_q,
+		ret = nvme_submit_sync_cmd(ns->ctrl->admin_q,
 				(struct nvme_command *)&c, entries, len);
 		if (ret) {
-			dev_err(dev->dev, "L2P table transfer failed (%d)\n",
+			dev_err(ns->ctrl->dev, "L2P table transfer failed (%d)\n",
 									ret);
 			ret = -EIO;
 			goto out;
@@ -361,7 +379,7 @@ static int nvme_nvm_get_bb_tbl(struct nv
 {
 	struct request_queue *q = nvmdev->q;
 	struct nvme_ns *ns = q->queuedata;
-	struct nvme_dev *dev = ns->dev;
+	struct nvme_ctrl *ctrl = ns->ctrl;
 	struct nvme_nvm_command c = {};
 	struct nvme_nvm_bb_tbl *bb_tbl;
 	int tblsz = sizeof(struct nvme_nvm_bb_tbl) + nr_blocks;
@@ -375,41 +393,36 @@ static int nvme_nvm_get_bb_tbl(struct nv
 	if (!bb_tbl)
 		return -ENOMEM;
 
-	ret = nvme_submit_sync_cmd(dev->admin_q, (struct nvme_command *)&c,
+	ret = nvme_submit_sync_cmd(ctrl->admin_q, (struct nvme_command *)&c,
 								bb_tbl, tblsz);
 	if (ret) {
-		dev_err(dev->dev, "get bad block table failed (%d)\n", ret);
+		dev_err(ctrl->dev, "get bad block table failed (%d)\n", ret);
 		ret = -EIO;
 		goto out;
 	}
 
 	if (bb_tbl->tblid[0] != 'B' || bb_tbl->tblid[1] != 'B' ||
 		bb_tbl->tblid[2] != 'L' || bb_tbl->tblid[3] != 'T') {
-		dev_err(dev->dev, "bbt format mismatch\n");
+		dev_err(ctrl->dev, "bbt format mismatch\n");
 		ret = -EINVAL;
 		goto out;
 	}
 
 	if (le16_to_cpu(bb_tbl->verid) != 1) {
 		ret = -EINVAL;
-		dev_err(dev->dev, "bbt version not supported\n");
+		dev_err(ctrl->dev, "bbt version not supported\n");
 		goto out;
 	}
 
 	if (le32_to_cpu(bb_tbl->tblks) != nr_blocks) {
 		ret = -EINVAL;
-		dev_err(dev->dev, "bbt unsuspected blocks returned (%u!=%u)",
+		dev_err(ctrl->dev, "bbt unsuspected blocks returned (%u!=%u)",
 					le32_to_cpu(bb_tbl->tblks), nr_blocks);
 		goto out;
 	}
 
 	ppa = dev_to_generic_addr(nvmdev, ppa);
 	ret = update_bbtbl(ppa, nr_blocks, bb_tbl->blk, priv);
-	if (ret) {
-		ret = -EINTR;
-		goto out;
-	}
-
 out:
 	kfree(bb_tbl);
 	return ret;
@@ -419,7 +432,6 @@ static int nvme_nvm_set_bb_tbl(struct nv
 								int type)
 {
 	struct nvme_ns *ns = nvmdev->q->queuedata;
-	struct nvme_dev *dev = ns->dev;
 	struct nvme_nvm_command c = {};
 	int ret = 0;
 
@@ -429,10 +441,10 @@ static int nvme_nvm_set_bb_tbl(struct nv
 	c.set_bb.nlb = cpu_to_le16(rqd->nr_pages - 1);
 	c.set_bb.value = type;
 
-	ret = nvme_submit_sync_cmd(dev->admin_q, (struct nvme_command *)&c,
+	ret = nvme_submit_sync_cmd(ns->ctrl->admin_q, (struct nvme_command *)&c,
 								NULL, 0);
 	if (ret)
-		dev_err(dev->dev, "set bad block table failed (%d)\n", ret);
+		dev_err(ns->ctrl->dev, "set bad block table failed (%d)\n", ret);
 	return ret;
 }
 
@@ -453,11 +465,8 @@ static inline void nvme_nvm_rqtocmd(stru
 static void nvme_nvm_end_io(struct request *rq, int error)
 {
 	struct nvm_rq *rqd = rq->end_io_data;
-	struct nvm_dev *dev = rqd->dev;
 
-	if (dev->mt && dev->mt->end_io(rqd, error))
-		pr_err("nvme: err status: %x result: %lx\n",
-				rq->errors, (unsigned long)rq->special);
+	nvm_end_io(rqd, error);
 
 	kfree(rq->cmd);
 	blk_mq_free_request(rq);
@@ -471,7 +480,7 @@ static int nvme_nvm_submit_io(struct nvm
 	struct bio *bio = rqd->bio;
 	struct nvme_nvm_command *cmd;
 
-	rq = blk_mq_alloc_request(q, bio_rw(bio), GFP_KERNEL, 0);
+	rq = blk_mq_alloc_request(q, bio_rw(bio), 0);
 	if (IS_ERR(rq))
 		return -ENOMEM;
 
@@ -520,9 +529,8 @@ static int nvme_nvm_erase_block(struct n
 static void *nvme_nvm_create_dma_pool(struct nvm_dev *nvmdev, char *name)
 {
 	struct nvme_ns *ns = nvmdev->q->queuedata;
-	struct nvme_dev *dev = ns->dev;
 
-	return dma_pool_create(name, dev->dev, PAGE_SIZE, PAGE_SIZE, 0);
+	return dma_pool_create(name, ns->ctrl->dev, PAGE_SIZE, PAGE_SIZE, 0);
 }
 
 static void nvme_nvm_destroy_dma_pool(void *pool)
@@ -580,8 +588,9 @@ void nvme_nvm_unregister(struct request_
 
 int nvme_nvm_ns_supported(struct nvme_ns *ns, struct nvme_id_ns *id)
 {
-	struct nvme_dev *dev = ns->dev;
-	struct pci_dev *pdev = to_pci_dev(dev->dev);
+	struct nvme_ctrl *ctrl = ns->ctrl;
+	/* XXX: this is poking into PCI structures from generic code! */
+	struct pci_dev *pdev = to_pci_dev(ctrl->dev);
 
 	/* QEMU NVMe simulator - PCI ID + Vendor specific bit */
 	if (pdev->vendor == PCI_VENDOR_ID_CNEX &&
--- zfcpdump-kernel-4.4.orig/drivers/nvme/host/nvme.h
+++ zfcpdump-kernel-4.4/drivers/nvme/host/nvme.h
@@ -19,58 +19,96 @@
 #include <linux/kref.h>
 #include <linux/blk-mq.h>
 
+enum {
+	/*
+	 * Driver internal status code for commands that were cancelled due
+	 * to timeouts or controller shutdown.  The value is negative so
+	 * that it a) doesn't overlap with the unsigned hardware error codes,
+	 * and b) can easily be tested for.
+	 */
+	NVME_SC_CANCELLED		= -EINTR,
+};
+
 extern unsigned char nvme_io_timeout;
 #define NVME_IO_TIMEOUT	(nvme_io_timeout * HZ)
 
+extern unsigned char admin_timeout;
+#define ADMIN_TIMEOUT	(admin_timeout * HZ)
+
+extern unsigned char shutdown_timeout;
+#define SHUTDOWN_TIMEOUT	(shutdown_timeout * HZ)
+
 enum {
 	NVME_NS_LBA		= 0,
 	NVME_NS_LIGHTNVM	= 1,
 };
 
 /*
- * Represents an NVM Express device.  Each nvme_dev is a PCI function.
+ * List of workarounds for devices that required behavior not specified in
+ * the standard.
  */
-struct nvme_dev {
-	struct list_head node;
-	struct nvme_queue **queues;
+enum nvme_quirks {
+	/*
+	 * Prefers I/O aligned to a stripe size specified in a vendor
+	 * specific Identify field.
+	 */
+	NVME_QUIRK_STRIPE_SIZE			= (1 << 0),
+
+	/*
+	 * The controller doesn't handle Identify value others than 0 or 1
+	 * correctly.
+	 */
+	NVME_QUIRK_IDENTIFY_CNS			= (1 << 1),
+
+	/*
+	 * The controller deterministically returns O's on reads to discarded
+	 * logical blocks.
+	 */
+	NVME_QUIRK_DISCARD_ZEROES		= (1 << 2),
+
+	/*
+	 * The controller needs a delay before starts checking the device
+	 * readiness, which is done by reading the NVME_CSTS_RDY bit.
+	 */
+	NVME_QUIRK_DELAY_BEFORE_CHK_RDY		= (1 << 3),
+};
+
+/* The below value is the specific amount of delay needed before checking
+ * readiness in case of the PCI_DEVICE(0x1c58, 0x0003), which needs the
+ * NVME_QUIRK_DELAY_BEFORE_CHK_RDY quirk enabled. The value (in ms) was
+ * found empirically.
+ */
+#define NVME_QUIRK_DELAY_AMOUNT		2000
+
+struct nvme_ctrl {
+	const struct nvme_ctrl_ops *ops;
 	struct request_queue *admin_q;
-	struct blk_mq_tag_set tagset;
-	struct blk_mq_tag_set admin_tagset;
-	u32 __iomem *dbs;
 	struct device *dev;
-	struct dma_pool *prp_page_pool;
-	struct dma_pool *prp_small_pool;
+	struct kref kref;
 	int instance;
-	unsigned queue_count;
-	unsigned online_queues;
-	unsigned max_qid;
-	int q_depth;
-	u32 db_stride;
-	u32 ctrl_config;
-	struct msix_entry *entry;
-	struct nvme_bar __iomem *bar;
+	struct blk_mq_tag_set *tagset;
 	struct list_head namespaces;
-	struct kref kref;
-	struct device *device;
-	struct work_struct reset_work;
-	struct work_struct probe_work;
-	struct work_struct scan_work;
+	struct mutex namespaces_mutex;
+	struct device *device;	/* char device */
+	struct list_head node;
+
 	char name[12];
 	char serial[20];
 	char model[40];
 	char firmware_rev[8];
-	bool subsystem;
+
+	u32 ctrl_config;
+
+	u32 page_size;
 	u32 max_hw_sectors;
 	u32 stripe_size;
-	u32 page_size;
-	void __iomem *cmb;
-	dma_addr_t cmb_dma_addr;
-	u64 cmb_size;
-	u32 cmbsz;
 	u16 oncs;
-	u16 abort_limit;
+	atomic_t abort_limit;
 	u8 event_limit;
 	u8 vwc;
+	u32 vs;
+	bool subsystem;
+	unsigned long quirks;
 };
 
 /*
@@ -79,56 +117,180 @@ struct nvme_dev {
 struct nvme_ns {
 	struct list_head list;
 
-	struct nvme_dev *dev;
+	struct nvme_ctrl *ctrl;
 	struct request_queue *queue;
 	struct gendisk *disk;
 	struct kref kref;
 
+	u8 eui[8];
+	u8 uuid[16];
+
 	unsigned ns_id;
 	int lba_shift;
 	u16 ms;
 	bool ext;
 	u8 pi_type;
 	int type;
+	unsigned long flags;
+
+#define NVME_NS_REMOVING 0
+#define NVME_NS_DEAD     1
+
 	u64 mode_select_num_blocks;
 	u32 mode_select_block_len;
 };
 
-/*
- * The nvme_iod describes the data in an I/O, including the list of PRP
- * entries.  You can't see it in this data structure because C doesn't let
- * me express that.  Use nvme_alloc_iod to ensure there's enough space
- * allocated to store the PRP list.
- */
-struct nvme_iod {
-	unsigned long private;	/* For the use of the submitter of the I/O */
-	int npages;		/* In the PRP list. 0 means small pool in use */
-	int offset;		/* Of PRP list */
-	int nents;		/* Used in scatterlist */
-	int length;		/* Of data, in bytes */
-	dma_addr_t first_dma;
-	struct scatterlist meta_sg[1]; /* metadata requires single contiguous buffer */
-	struct scatterlist sg[0];
+struct nvme_ctrl_ops {
+	int (*reg_read32)(struct nvme_ctrl *ctrl, u32 off, u32 *val);
+	int (*reg_write32)(struct nvme_ctrl *ctrl, u32 off, u32 val);
+	int (*reg_read64)(struct nvme_ctrl *ctrl, u32 off, u64 *val);
+	bool (*io_incapable)(struct nvme_ctrl *ctrl);
+	int (*reset_ctrl)(struct nvme_ctrl *ctrl);
+	void (*free_ctrl)(struct nvme_ctrl *ctrl);
 };
 
+static inline bool nvme_ctrl_ready(struct nvme_ctrl *ctrl)
+{
+	u32 val = 0;
+
+	if (ctrl->ops->reg_read32(ctrl, NVME_REG_CSTS, &val))
+		return false;
+	return val & NVME_CSTS_RDY;
+}
+
+static inline bool nvme_io_incapable(struct nvme_ctrl *ctrl)
+{
+	u32 val = 0;
+
+	if (ctrl->ops->io_incapable(ctrl))
+		return false;
+	if (ctrl->ops->reg_read32(ctrl, NVME_REG_CSTS, &val))
+		return false;
+	return val & NVME_CSTS_CFS;
+}
+
+static inline int nvme_reset_subsystem(struct nvme_ctrl *ctrl)
+{
+	if (!ctrl->subsystem)
+		return -ENOTTY;
+	return ctrl->ops->reg_write32(ctrl, NVME_REG_NSSR, 0x4E564D65);
+}
+
 static inline u64 nvme_block_nr(struct nvme_ns *ns, sector_t sector)
 {
 	return (sector >> (ns->lba_shift - 9));
 }
 
+static inline void nvme_setup_flush(struct nvme_ns *ns,
+		struct nvme_command *cmnd)
+{
+	memset(cmnd, 0, sizeof(*cmnd));
+	cmnd->common.opcode = nvme_cmd_flush;
+	cmnd->common.nsid = cpu_to_le32(ns->ns_id);
+}
+
+static inline void nvme_setup_rw(struct nvme_ns *ns, struct request *req,
+		struct nvme_command *cmnd)
+{
+	u16 control = 0;
+	u32 dsmgmt = 0;
+
+	if (req->cmd_flags & REQ_FUA)
+		control |= NVME_RW_FUA;
+	if (req->cmd_flags & (REQ_FAILFAST_DEV | REQ_RAHEAD))
+		control |= NVME_RW_LR;
+
+	if (req->cmd_flags & REQ_RAHEAD)
+		dsmgmt |= NVME_RW_DSM_FREQ_PREFETCH;
+
+	memset(cmnd, 0, sizeof(*cmnd));
+	cmnd->rw.opcode = (rq_data_dir(req) ? nvme_cmd_write : nvme_cmd_read);
+	cmnd->rw.command_id = req->tag;
+	cmnd->rw.nsid = cpu_to_le32(ns->ns_id);
+	cmnd->rw.slba = cpu_to_le64(nvme_block_nr(ns, blk_rq_pos(req)));
+	cmnd->rw.length = cpu_to_le16((blk_rq_bytes(req) >> ns->lba_shift) - 1);
+
+	if (ns->ms) {
+		switch (ns->pi_type) {
+		case NVME_NS_DPS_PI_TYPE3:
+			control |= NVME_RW_PRINFO_PRCHK_GUARD;
+			break;
+		case NVME_NS_DPS_PI_TYPE1:
+		case NVME_NS_DPS_PI_TYPE2:
+			control |= NVME_RW_PRINFO_PRCHK_GUARD |
+					NVME_RW_PRINFO_PRCHK_REF;
+			cmnd->rw.reftag = cpu_to_le32(
+					nvme_block_nr(ns, blk_rq_pos(req)));
+			break;
+		}
+		if (!blk_integrity_rq(req))
+			control |= NVME_RW_PRINFO_PRACT;
+	}
+
+	cmnd->rw.control = cpu_to_le16(control);
+	cmnd->rw.dsmgmt = cpu_to_le32(dsmgmt);
+}
+
+
+static inline int nvme_error_status(u16 status)
+{
+	switch (status & 0x7ff) {
+	case NVME_SC_SUCCESS:
+		return 0;
+	case NVME_SC_CAP_EXCEEDED:
+		return -ENOSPC;
+	default:
+		return -EIO;
+	}
+}
+
+static inline bool nvme_req_needs_retry(struct request *req, u16 status)
+{
+	return !(status & NVME_SC_DNR || blk_noretry_request(req)) &&
+		(jiffies - req->start_time) < req->timeout;
+}
+
+int nvme_disable_ctrl(struct nvme_ctrl *ctrl, u64 cap);
+int nvme_enable_ctrl(struct nvme_ctrl *ctrl, u64 cap);
+int nvme_shutdown_ctrl(struct nvme_ctrl *ctrl);
+int nvme_init_ctrl(struct nvme_ctrl *ctrl, struct device *dev,
+		const struct nvme_ctrl_ops *ops, unsigned long quirks);
+void nvme_uninit_ctrl(struct nvme_ctrl *ctrl);
+void nvme_put_ctrl(struct nvme_ctrl *ctrl);
+int nvme_init_identify(struct nvme_ctrl *ctrl);
+
+void nvme_scan_namespaces(struct nvme_ctrl *ctrl);
+void nvme_remove_namespaces(struct nvme_ctrl *ctrl);
+
+void nvme_stop_queues(struct nvme_ctrl *ctrl);
+void nvme_start_queues(struct nvme_ctrl *ctrl);
+void nvme_kill_queues(struct nvme_ctrl *ctrl);
+
+struct request *nvme_alloc_request(struct request_queue *q,
+		struct nvme_command *cmd, unsigned int flags);
+void nvme_requeue_req(struct request *req);
 int nvme_submit_sync_cmd(struct request_queue *q, struct nvme_command *cmd,
 		void *buf, unsigned bufflen);
 int __nvme_submit_sync_cmd(struct request_queue *q, struct nvme_command *cmd,
-		void *buffer, void __user *ubuffer, unsigned bufflen,
+		void *buffer, unsigned bufflen,  u32 *result, unsigned timeout);
+int nvme_submit_user_cmd(struct request_queue *q, struct nvme_command *cmd,
+		void __user *ubuffer, unsigned bufflen, u32 *result,
+		unsigned timeout);
+int __nvme_submit_user_cmd(struct request_queue *q, struct nvme_command *cmd,
+		void __user *ubuffer, unsigned bufflen,
+		void __user *meta_buffer, unsigned meta_len, u32 meta_seed,
 		u32 *result, unsigned timeout);
-int nvme_identify_ctrl(struct nvme_dev *dev, struct nvme_id_ctrl **id);
-int nvme_identify_ns(struct nvme_dev *dev, unsigned nsid,
+int nvme_identify_ctrl(struct nvme_ctrl *dev, struct nvme_id_ctrl **id);
+int nvme_identify_ns(struct nvme_ctrl *dev, unsigned nsid,
 		struct nvme_id_ns **id);
-int nvme_get_log_page(struct nvme_dev *dev, struct nvme_smart_log **log);
-int nvme_get_features(struct nvme_dev *dev, unsigned fid, unsigned nsid,
+int nvme_get_log_page(struct nvme_ctrl *dev, struct nvme_smart_log **log);
+int nvme_get_features(struct nvme_ctrl *dev, unsigned fid, unsigned nsid,
 			dma_addr_t dma_addr, u32 *result);
-int nvme_set_features(struct nvme_dev *dev, unsigned fid, unsigned dword11,
+int nvme_set_features(struct nvme_ctrl *dev, unsigned fid, unsigned dword11,
 			dma_addr_t dma_addr, u32 *result);
+int nvme_set_queue_count(struct nvme_ctrl *ctrl, int *count);
+
+extern spinlock_t dev_list_lock;
 
 struct sg_io_hdr;
 
@@ -154,4 +316,7 @@ static inline int nvme_nvm_ns_supported(
 }
 #endif /* CONFIG_NVM */
 
+int __init nvme_core_init(void);
+void nvme_core_exit(void);
+
 #endif /* _NVME_H */
--- zfcpdump-kernel-4.4.orig/drivers/nvme/host/pci.c
+++ zfcpdump-kernel-4.4/drivers/nvme/host/pci.c
@@ -12,6 +12,7 @@
  * more details.
  */
 
+#include <linux/aer.h>
 #include <linux/bitops.h>
 #include <linux/blkdev.h>
 #include <linux/blk-mq.h>
@@ -26,36 +27,37 @@
 #include <linux/interrupt.h>
 #include <linux/io.h>
 #include <linux/kdev_t.h>
-#include <linux/kthread.h>
 #include <linux/kernel.h>
-#include <linux/list_sort.h>
 #include <linux/mm.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
+#include <linux/mutex.h>
 #include <linux/pci.h>
 #include <linux/poison.h>
 #include <linux/ptrace.h>
 #include <linux/sched.h>
 #include <linux/slab.h>
 #include <linux/t10-pi.h>
+#include <linux/timer.h>
 #include <linux/types.h>
-#include <linux/pr.h>
-#include <scsi/sg.h>
 #include <linux/io-64-nonatomic-lo-hi.h>
 #include <asm/unaligned.h>
 
-#include <uapi/linux/nvme_ioctl.h>
 #include "nvme.h"
 
-#define NVME_MINORS		(1U << MINORBITS)
 #define NVME_Q_DEPTH		1024
 #define NVME_AQ_DEPTH		256
 #define SQ_SIZE(depth)		(depth * sizeof(struct nvme_command))
 #define CQ_SIZE(depth)		(depth * sizeof(struct nvme_completion))
-#define ADMIN_TIMEOUT		(admin_timeout * HZ)
-#define SHUTDOWN_TIMEOUT	(shutdown_timeout * HZ)
+		
+/*
+ * We handle AEN commands ourselves and don't even let the
+ * block layer know about them.
+ */
+#define NVME_NR_AEN_COMMANDS	1
+#define NVME_AQ_BLKMQ_DEPTH	(NVME_AQ_DEPTH - NVME_NR_AEN_COMMANDS)
 
-static unsigned char admin_timeout = 60;
+unsigned char admin_timeout = 60;
 module_param(admin_timeout, byte, 0644);
 MODULE_PARM_DESC(admin_timeout, "timeout in seconds for admin commands");
 
@@ -63,16 +65,10 @@ unsigned char nvme_io_timeout = 30;
 module_param_named(io_timeout, nvme_io_timeout, byte, 0644);
 MODULE_PARM_DESC(io_timeout, "timeout in seconds for I/O");
 
-static unsigned char shutdown_timeout = 5;
+unsigned char shutdown_timeout = 5;
 module_param(shutdown_timeout, byte, 0644);
 MODULE_PARM_DESC(shutdown_timeout, "timeout in seconds for controller shutdown");
 
-static int nvme_major;
-module_param(nvme_major, int, 0);
-
-static int nvme_char_major;
-module_param(nvme_char_major, int, 0);
-
 static int use_threaded_interrupts;
 module_param(use_threaded_interrupts, int, 0);
 
@@ -80,28 +76,59 @@ static bool use_cmb_sqes = true;
 module_param(use_cmb_sqes, bool, 0644);
 MODULE_PARM_DESC(use_cmb_sqes, "use controller's memory buffer for I/O SQes");
 
-static DEFINE_SPINLOCK(dev_list_lock);
-static LIST_HEAD(dev_list);
-static struct task_struct *nvme_thread;
 static struct workqueue_struct *nvme_workq;
-static wait_queue_head_t nvme_kthread_wait;
 
-static struct class *nvme_class;
+struct nvme_dev;
+struct nvme_queue;
 
-static int __nvme_reset(struct nvme_dev *dev);
 static int nvme_reset(struct nvme_dev *dev);
 static void nvme_process_cq(struct nvme_queue *nvmeq);
-static void nvme_dead_ctrl(struct nvme_dev *dev);
+static void nvme_remove_dead_ctrl(struct nvme_dev *dev);
+static void nvme_dev_disable(struct nvme_dev *dev, bool shutdown);
 
-struct async_cmd_info {
-	struct kthread_work work;
-	struct kthread_worker *worker;
-	struct request *req;
-	u32 result;
-	int status;
-	void *ctx;
+/*
+ * Represents an NVM Express device.  Each nvme_dev is a PCI function.
+ */
+struct nvme_dev {
+	struct nvme_queue **queues;
+	struct blk_mq_tag_set tagset;
+	struct blk_mq_tag_set admin_tagset;
+	u32 __iomem *dbs;
+	struct device *dev;
+	struct dma_pool *prp_page_pool;
+	struct dma_pool *prp_small_pool;
+	unsigned queue_count;
+	unsigned online_queues;
+	unsigned max_qid;
+	int q_depth;
+	u32 db_stride;
+	struct msix_entry *entry;
+	void __iomem *bar;
+	struct work_struct reset_work;
+	struct work_struct scan_work;
+	struct work_struct remove_work;
+	struct work_struct async_work;
+	struct timer_list watchdog_timer;
+	struct mutex shutdown_lock;
+	bool subsystem;
+	void __iomem *cmb;
+	dma_addr_t cmb_dma_addr;
+	u64 cmb_size;
+	u32 cmbsz;
+	unsigned long flags;
+
+#define NVME_CTRL_RESETTING    0
+#define NVME_CTRL_REMOVING     1
+
+	struct nvme_ctrl ctrl;
+	struct completion ioq_wait;
 };
 
+static inline struct nvme_dev *to_nvme_dev(struct nvme_ctrl *ctrl)
+{
+	return container_of(ctrl, struct nvme_dev, ctrl);
+}
+
 /*
  * An NVM Express queue.  Each device has at least two (one for admin
  * commands and one for I/O commands).
@@ -126,7 +153,24 @@ struct nvme_queue {
 	u16 qid;
 	u8 cq_phase;
 	u8 cqe_seen;
-	struct async_cmd_info cmdinfo;
+};
+
+/*
+ * The nvme_iod describes the data in an I/O, including the list of PRP
+ * entries.  You can't see it in this data structure because C doesn't let
+ * me express that.  Use nvme_init_iod to ensure there's enough space
+ * allocated to store the PRP list.
+ */
+struct nvme_iod {
+	struct nvme_queue *nvmeq;
+	int aborted;
+	int npages;		/* In the PRP list. 0 means small pool in use */
+	int nents;		/* Used in scatterlist */
+	int length;		/* Of data, in bytes */
+	dma_addr_t first_dma;
+	struct scatterlist meta_sg; /* metadata requires single contiguous buffer */
+	struct scatterlist *sg;
+	struct scatterlist inline_sg[0];
 };
 
 /*
@@ -148,23 +192,11 @@ static inline void _nvme_check_size(void
 	BUILD_BUG_ON(sizeof(struct nvme_smart_log) != 512);
 }
 
-typedef void (*nvme_completion_fn)(struct nvme_queue *, void *,
-						struct nvme_completion *);
-
-struct nvme_cmd_info {
-	nvme_completion_fn fn;
-	void *ctx;
-	int aborted;
-	struct nvme_queue *nvmeq;
-	struct nvme_iod iod[0];
-};
-
 /*
  * Max size of iod being embedded in the request payload
  */
 #define NVME_INT_PAGES		2
-#define NVME_INT_BYTES(dev)	(NVME_INT_PAGES * (dev)->page_size)
-#define NVME_INT_MASK		0x01
+#define NVME_INT_BYTES(dev)	(NVME_INT_PAGES * (dev)->ctrl.page_size)
 
 /*
  * Will slightly overestimate the number of pages needed.  This is OK
@@ -173,19 +205,22 @@ struct nvme_cmd_info {
  */
 static int nvme_npages(unsigned size, struct nvme_dev *dev)
 {
-	unsigned nprps = DIV_ROUND_UP(size + dev->page_size, dev->page_size);
+	unsigned nprps = DIV_ROUND_UP(size + dev->ctrl.page_size,
+				      dev->ctrl.page_size);
 	return DIV_ROUND_UP(8 * nprps, PAGE_SIZE - 8);
 }
 
-static unsigned int nvme_cmd_size(struct nvme_dev *dev)
+static unsigned int nvme_iod_alloc_size(struct nvme_dev *dev,
+		unsigned int size, unsigned int nseg)
 {
-	unsigned int ret = sizeof(struct nvme_cmd_info);
-
-	ret += sizeof(struct nvme_iod);
-	ret += sizeof(__le64 *) * nvme_npages(NVME_INT_BYTES(dev), dev);
-	ret += sizeof(struct scatterlist) * NVME_INT_PAGES;
+	return sizeof(__le64 *) * nvme_npages(size, dev) +
+			sizeof(struct scatterlist) * nseg;
+}
 
-	return ret;
+static unsigned int nvme_cmd_size(struct nvme_dev *dev)
+{
+	return sizeof(struct nvme_iod) +
+		nvme_iod_alloc_size(dev, NVME_INT_BYTES(dev), NVME_INT_PAGES);
 }
 
 static int nvme_admin_init_hctx(struct blk_mq_hw_ctx *hctx, void *data,
@@ -215,11 +250,11 @@ static int nvme_admin_init_request(void
 				unsigned int numa_node)
 {
 	struct nvme_dev *dev = data;
-	struct nvme_cmd_info *cmd = blk_mq_rq_to_pdu(req);
+	struct nvme_iod *iod = blk_mq_rq_to_pdu(req);
 	struct nvme_queue *nvmeq = dev->queues[0];
 
 	BUG_ON(!nvmeq);
-	cmd->nvmeq = nvmeq;
+	iod->nvmeq = nvmeq;
 	return 0;
 }
 
@@ -242,148 +277,50 @@ static int nvme_init_request(void *data,
 				unsigned int numa_node)
 {
 	struct nvme_dev *dev = data;
-	struct nvme_cmd_info *cmd = blk_mq_rq_to_pdu(req);
+	struct nvme_iod *iod = blk_mq_rq_to_pdu(req);
 	struct nvme_queue *nvmeq = dev->queues[hctx_idx + 1];
 
 	BUG_ON(!nvmeq);
-	cmd->nvmeq = nvmeq;
+	iod->nvmeq = nvmeq;
 	return 0;
 }
 
-static void nvme_set_info(struct nvme_cmd_info *cmd, void *ctx,
-				nvme_completion_fn handler)
+static void nvme_queue_scan(struct nvme_dev *dev)
 {
-	cmd->fn = handler;
-	cmd->ctx = ctx;
-	cmd->aborted = 0;
-	blk_mq_start_request(blk_mq_rq_from_pdu(cmd));
-}
-
-static void *iod_get_private(struct nvme_iod *iod)
-{
-	return (void *) (iod->private & ~0x1UL);
-}
-
-/*
- * If bit 0 is set, the iod is embedded in the request payload.
- */
-static bool iod_should_kfree(struct nvme_iod *iod)
-{
-	return (iod->private & NVME_INT_MASK) == 0;
-}
-
-/* Special values must be less than 0x1000 */
-#define CMD_CTX_BASE		((void *)POISON_POINTER_DELTA)
-#define CMD_CTX_CANCELLED	(0x30C + CMD_CTX_BASE)
-#define CMD_CTX_COMPLETED	(0x310 + CMD_CTX_BASE)
-#define CMD_CTX_INVALID		(0x314 + CMD_CTX_BASE)
-
-static void special_completion(struct nvme_queue *nvmeq, void *ctx,
-						struct nvme_completion *cqe)
-{
-	if (ctx == CMD_CTX_CANCELLED)
-		return;
-	if (ctx == CMD_CTX_COMPLETED) {
-		dev_warn(nvmeq->q_dmadev,
-				"completed id %d twice on queue %d\n",
-				cqe->command_id, le16_to_cpup(&cqe->sq_id));
-		return;
-	}
-	if (ctx == CMD_CTX_INVALID) {
-		dev_warn(nvmeq->q_dmadev,
-				"invalid id %d completed on queue %d\n",
-				cqe->command_id, le16_to_cpup(&cqe->sq_id));
+	/*
+	 * Do not queue new scan work when a controller is reset during
+	 * removal.
+	 */
+	if (test_bit(NVME_CTRL_REMOVING, &dev->flags))
 		return;
-	}
-	dev_warn(nvmeq->q_dmadev, "Unknown special completion %p\n", ctx);
+	queue_work(nvme_workq, &dev->scan_work);
 }
 
-static void *cancel_cmd_info(struct nvme_cmd_info *cmd, nvme_completion_fn *fn)
+static void nvme_complete_async_event(struct nvme_dev *dev,
+		struct nvme_completion *cqe)
 {
-	void *ctx;
-
-	if (fn)
-		*fn = cmd->fn;
-	ctx = cmd->ctx;
-	cmd->fn = special_completion;
-	cmd->ctx = CMD_CTX_CANCELLED;
-	return ctx;
-}
+	u16 status = le16_to_cpu(cqe->status) >> 1;
+	u32 result = le32_to_cpu(cqe->result);
 
-static void async_req_completion(struct nvme_queue *nvmeq, void *ctx,
-						struct nvme_completion *cqe)
-{
-	u32 result = le32_to_cpup(&cqe->result);
-	u16 status = le16_to_cpup(&cqe->status) >> 1;
+	if (status == NVME_SC_SUCCESS || status == NVME_SC_ABORT_REQ) {
+		++dev->ctrl.event_limit;
+		queue_work(nvme_workq, &dev->async_work);
+	}
 
-	if (status == NVME_SC_SUCCESS || status == NVME_SC_ABORT_REQ)
-		++nvmeq->dev->event_limit;
 	if (status != NVME_SC_SUCCESS)
 		return;
 
 	switch (result & 0xff07) {
 	case NVME_AER_NOTICE_NS_CHANGED:
-		dev_info(nvmeq->q_dmadev, "rescanning\n");
-		schedule_work(&nvmeq->dev->scan_work);
+		dev_info(dev->dev, "rescanning\n");
+		nvme_queue_scan(dev);
 	default:
-		dev_warn(nvmeq->q_dmadev, "async event result %08x\n", result);
+		dev_warn(dev->dev, "async event result %08x\n", result);
 	}
 }
 
-static void abort_completion(struct nvme_queue *nvmeq, void *ctx,
-						struct nvme_completion *cqe)
-{
-	struct request *req = ctx;
-
-	u16 status = le16_to_cpup(&cqe->status) >> 1;
-	u32 result = le32_to_cpup(&cqe->result);
-
-	blk_mq_free_request(req);
-
-	dev_warn(nvmeq->q_dmadev, "Abort status:%x result:%x", status, result);
-	++nvmeq->dev->abort_limit;
-}
-
-static void async_completion(struct nvme_queue *nvmeq, void *ctx,
-						struct nvme_completion *cqe)
-{
-	struct async_cmd_info *cmdinfo = ctx;
-	cmdinfo->result = le32_to_cpup(&cqe->result);
-	cmdinfo->status = le16_to_cpup(&cqe->status) >> 1;
-	queue_kthread_work(cmdinfo->worker, &cmdinfo->work);
-	blk_mq_free_request(cmdinfo->req);
-}
-
-static inline struct nvme_cmd_info *get_cmd_from_tag(struct nvme_queue *nvmeq,
-				  unsigned int tag)
-{
-	struct request *req = blk_mq_tag_to_rq(*nvmeq->tags, tag);
-
-	return blk_mq_rq_to_pdu(req);
-}
-
-/*
- * Called with local interrupts disabled and the q_lock held.  May not sleep.
- */
-static void *nvme_finish_cmd(struct nvme_queue *nvmeq, int tag,
-						nvme_completion_fn *fn)
-{
-	struct nvme_cmd_info *cmd = get_cmd_from_tag(nvmeq, tag);
-	void *ctx;
-	if (tag >= nvmeq->q_depth) {
-		*fn = special_completion;
-		return CMD_CTX_INVALID;
-	}
-	if (fn)
-		*fn = cmd->fn;
-	ctx = cmd->ctx;
-	cmd->fn = special_completion;
-	cmd->ctx = CMD_CTX_COMPLETED;
-	return ctx;
-}
-
 /**
- * nvme_submit_cmd() - Copy a command into a queue and ring the doorbell
+ * __nvme_submit_cmd() - Copy a command into a queue and ring the doorbell
  * @nvmeq: The queue to use
  * @cmd: The command to send
  *
@@ -405,69 +342,44 @@ static void __nvme_submit_cmd(struct nvm
 	nvmeq->sq_tail = tail;
 }
 
-static void nvme_submit_cmd(struct nvme_queue *nvmeq, struct nvme_command *cmd)
-{
-	unsigned long flags;
-	spin_lock_irqsave(&nvmeq->q_lock, flags);
-	__nvme_submit_cmd(nvmeq, cmd);
-	spin_unlock_irqrestore(&nvmeq->q_lock, flags);
-}
-
-static __le64 **iod_list(struct nvme_iod *iod)
-{
-	return ((void *)iod) + iod->offset;
-}
-
-static inline void iod_init(struct nvme_iod *iod, unsigned nbytes,
-			    unsigned nseg, unsigned long private)
-{
-	iod->private = private;
-	iod->offset = offsetof(struct nvme_iod, sg[nseg]);
-	iod->npages = -1;
-	iod->length = nbytes;
-	iod->nents = 0;
-}
-
-static struct nvme_iod *
-__nvme_alloc_iod(unsigned nseg, unsigned bytes, struct nvme_dev *dev,
-		 unsigned long priv, gfp_t gfp)
+static __le64 **iod_list(struct request *req)
 {
-	struct nvme_iod *iod = kmalloc(sizeof(struct nvme_iod) +
-				sizeof(__le64 *) * nvme_npages(bytes, dev) +
-				sizeof(struct scatterlist) * nseg, gfp);
-
-	if (iod)
-		iod_init(iod, bytes, nseg, priv);
-
-	return iod;
+	struct nvme_iod *iod = blk_mq_rq_to_pdu(req);
+	return (__le64 **)(iod->sg + req->nr_phys_segments);
 }
 
-static struct nvme_iod *nvme_alloc_iod(struct request *rq, struct nvme_dev *dev,
-			               gfp_t gfp)
+static int nvme_init_iod(struct request *rq, struct nvme_dev *dev)
 {
-	unsigned size = !(rq->cmd_flags & REQ_DISCARD) ? blk_rq_bytes(rq) :
-                                                sizeof(struct nvme_dsm_range);
-	struct nvme_iod *iod;
+	struct nvme_iod *iod = blk_mq_rq_to_pdu(rq);
+	int nseg = rq->nr_phys_segments;
+	unsigned size;
 
-	if (rq->nr_phys_segments <= NVME_INT_PAGES &&
-	    size <= NVME_INT_BYTES(dev)) {
-		struct nvme_cmd_info *cmd = blk_mq_rq_to_pdu(rq);
+	if (rq->cmd_flags & REQ_DISCARD)
+		size = sizeof(struct nvme_dsm_range);
+	else
+		size = blk_rq_bytes(rq);
 
-		iod = cmd->iod;
-		iod_init(iod, size, rq->nr_phys_segments,
-				(unsigned long) rq | NVME_INT_MASK);
-		return iod;
+	if (nseg > NVME_INT_PAGES || size > NVME_INT_BYTES(dev)) {
+		iod->sg = kmalloc(nvme_iod_alloc_size(dev, size, nseg), GFP_ATOMIC);
+		if (!iod->sg)
+			return BLK_MQ_RQ_QUEUE_BUSY;
+	} else {
+		iod->sg = iod->inline_sg;
 	}
 
-	return __nvme_alloc_iod(rq->nr_phys_segments, size, dev,
-				(unsigned long) rq, gfp);
+	iod->aborted = 0;
+	iod->npages = -1;
+	iod->nents = 0;
+	iod->length = size;
+	return 0;
 }
 
-static void nvme_free_iod(struct nvme_dev *dev, struct nvme_iod *iod)
+static void nvme_free_iod(struct nvme_dev *dev, struct request *req)
 {
-	const int last_prp = dev->page_size / 8 - 1;
+	struct nvme_iod *iod = blk_mq_rq_to_pdu(req);
+	const int last_prp = dev->ctrl.page_size / 8 - 1;
 	int i;
-	__le64 **list = iod_list(iod);
+	__le64 **list = iod_list(req);
 	dma_addr_t prp_dma = iod->first_dma;
 
 	if (iod->npages == 0)
@@ -479,20 +391,8 @@ static void nvme_free_iod(struct nvme_de
 		prp_dma = next_prp_dma;
 	}
 
-	if (iod_should_kfree(iod))
-		kfree(iod);
-}
-
-static int nvme_error_status(u16 status)
-{
-	switch (status & 0x7ff) {
-	case NVME_SC_SUCCESS:
-		return 0;
-	case NVME_SC_CAP_EXCEEDED:
-		return -ENOSPC;
-	default:
-		return -EIO;
-	}
+	if (iod->sg != iod->inline_sg)
+		kfree(iod->sg);
 }
 
 #ifdef CONFIG_BLK_DEV_INTEGRITY
@@ -549,27 +449,6 @@ static void nvme_dif_remap(struct reques
 	}
 	kunmap_atomic(pmap);
 }
-
-static void nvme_init_integrity(struct nvme_ns *ns)
-{
-	struct blk_integrity integrity;
-
-	switch (ns->pi_type) {
-	case NVME_NS_DPS_PI_TYPE3:
-		integrity.profile = &t10_pi_type3_crc;
-		break;
-	case NVME_NS_DPS_PI_TYPE1:
-	case NVME_NS_DPS_PI_TYPE2:
-		integrity.profile = &t10_pi_type1_crc;
-		break;
-	default:
-		integrity.profile = NULL;
-		break;
-	}
-	integrity.tuple_size = ns->ms;
-	blk_integrity_register(ns->disk, &integrity);
-	blk_queue_max_integrity_segments(ns->queue, 1);
-}
 #else /* CONFIG_BLK_DEV_INTEGRITY */
 static void nvme_dif_remap(struct request *req,
 			void (*dif_swap)(u32 p, u32 v, struct t10_pi_tuple *pi))
@@ -581,91 +460,27 @@ static void nvme_dif_prep(u32 p, u32 v,
 static void nvme_dif_complete(u32 p, u32 v, struct t10_pi_tuple *pi)
 {
 }
-static void nvme_init_integrity(struct nvme_ns *ns)
-{
-}
 #endif
 
-static void req_completion(struct nvme_queue *nvmeq, void *ctx,
-						struct nvme_completion *cqe)
-{
-	struct nvme_iod *iod = ctx;
-	struct request *req = iod_get_private(iod);
-	struct nvme_cmd_info *cmd_rq = blk_mq_rq_to_pdu(req);
-	u16 status = le16_to_cpup(&cqe->status) >> 1;
-	bool requeue = false;
-	int error = 0;
-
-	if (unlikely(status)) {
-		if (!(status & NVME_SC_DNR || blk_noretry_request(req))
-		    && (jiffies - req->start_time) < req->timeout) {
-			unsigned long flags;
-
-			requeue = true;
-			blk_mq_requeue_request(req);
-			spin_lock_irqsave(req->q->queue_lock, flags);
-			if (!blk_queue_stopped(req->q))
-				blk_mq_kick_requeue_list(req->q);
-			spin_unlock_irqrestore(req->q->queue_lock, flags);
-			goto release_iod;
-		}
-
-		if (req->cmd_type == REQ_TYPE_DRV_PRIV) {
-			if (cmd_rq->ctx == CMD_CTX_CANCELLED)
-				error = -EINTR;
-			else
-				error = status;
-		} else {
-			error = nvme_error_status(status);
-		}
-	}
-
-	if (req->cmd_type == REQ_TYPE_DRV_PRIV) {
-		u32 result = le32_to_cpup(&cqe->result);
-		req->special = (void *)(uintptr_t)result;
-	}
-
-	if (cmd_rq->aborted)
-		dev_warn(nvmeq->dev->dev,
-			"completing aborted command with status:%04x\n",
-			error);
-
-release_iod:
-	if (iod->nents) {
-		dma_unmap_sg(nvmeq->dev->dev, iod->sg, iod->nents,
-			rq_data_dir(req) ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
-		if (blk_integrity_rq(req)) {
-			if (!rq_data_dir(req))
-				nvme_dif_remap(req, nvme_dif_complete);
-			dma_unmap_sg(nvmeq->dev->dev, iod->meta_sg, 1,
-				rq_data_dir(req) ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
-		}
-	}
-	nvme_free_iod(nvmeq->dev, iod);
-
-	if (likely(!requeue))
-		blk_mq_complete_request(req, error);
-}
-
-/* length is in bytes.  gfp flags indicates whether we may sleep. */
-static int nvme_setup_prps(struct nvme_dev *dev, struct nvme_iod *iod,
-		int total_len, gfp_t gfp)
+static bool nvme_setup_prps(struct nvme_dev *dev, struct request *req,
+		int total_len)
 {
+	struct nvme_iod *iod = blk_mq_rq_to_pdu(req);
 	struct dma_pool *pool;
 	int length = total_len;
 	struct scatterlist *sg = iod->sg;
 	int dma_len = sg_dma_len(sg);
 	u64 dma_addr = sg_dma_address(sg);
-	u32 page_size = dev->page_size;
+	u32 page_size = dev->ctrl.page_size;
 	int offset = dma_addr & (page_size - 1);
 	__le64 *prp_list;
-	__le64 **list = iod_list(iod);
+	__le64 **list = iod_list(req);
 	dma_addr_t prp_dma;
 	int nprps, i;
 
 	length -= (page_size - offset);
 	if (length <= 0)
-		return total_len;
+		return true;
 
 	dma_len -= (page_size - offset);
 	if (dma_len) {
@@ -678,7 +493,7 @@ static int nvme_setup_prps(struct nvme_d
 
 	if (length <= page_size) {
 		iod->first_dma = dma_addr;
-		return total_len;
+		return true;
 	}
 
 	nprps = DIV_ROUND_UP(length, page_size);
@@ -690,11 +505,11 @@ static int nvme_setup_prps(struct nvme_d
 		iod->npages = 1;
 	}
 
-	prp_list = dma_pool_alloc(pool, gfp, &prp_dma);
+	prp_list = dma_pool_alloc(pool, GFP_ATOMIC, &prp_dma);
 	if (!prp_list) {
 		iod->first_dma = dma_addr;
 		iod->npages = -1;
-		return (total_len - length) + page_size;
+		return false;
 	}
 	list[0] = prp_list;
 	iod->first_dma = prp_dma;
@@ -702,9 +517,9 @@ static int nvme_setup_prps(struct nvme_d
 	for (;;) {
 		if (i == page_size >> 3) {
 			__le64 *old_prp_list = prp_list;
-			prp_list = dma_pool_alloc(pool, gfp, &prp_dma);
+			prp_list = dma_pool_alloc(pool, GFP_ATOMIC, &prp_dma);
 			if (!prp_list)
-				return total_len - length;
+				return false;
 			list[iod->npages++] = prp_list;
 			prp_list[0] = old_prp_list[i - 1];
 			old_prp_list[i - 1] = cpu_to_le64(prp_dma);
@@ -724,115 +539,105 @@ static int nvme_setup_prps(struct nvme_d
 		dma_len = sg_dma_len(sg);
 	}
 
-	return total_len;
+	return true;
 }
 
-static void nvme_submit_priv(struct nvme_queue *nvmeq, struct request *req,
-		struct nvme_iod *iod)
+static int nvme_map_data(struct nvme_dev *dev, struct request *req,
+		struct nvme_command *cmnd)
 {
-	struct nvme_command cmnd;
+	struct nvme_iod *iod = blk_mq_rq_to_pdu(req);
+	struct request_queue *q = req->q;
+	enum dma_data_direction dma_dir = rq_data_dir(req) ?
+			DMA_TO_DEVICE : DMA_FROM_DEVICE;
+	int ret = BLK_MQ_RQ_QUEUE_ERROR;
 
-	memcpy(&cmnd, req->cmd, sizeof(cmnd));
-	cmnd.rw.command_id = req->tag;
-	if (req->nr_phys_segments) {
-		cmnd.rw.prp1 = cpu_to_le64(sg_dma_address(iod->sg));
-		cmnd.rw.prp2 = cpu_to_le64(iod->first_dma);
-	}
+	sg_init_table(iod->sg, req->nr_phys_segments);
+	iod->nents = blk_rq_map_sg(q, req, iod->sg);
+	if (!iod->nents)
+		goto out;
 
-	__nvme_submit_cmd(nvmeq, &cmnd);
-}
+	ret = BLK_MQ_RQ_QUEUE_BUSY;
+	if (!dma_map_sg(dev->dev, iod->sg, iod->nents, dma_dir))
+		goto out;
 
-/*
- * We reuse the small pool to allocate the 16-byte range here as it is not
- * worth having a special pool for these or additional cases to handle freeing
- * the iod.
- */
-static void nvme_submit_discard(struct nvme_queue *nvmeq, struct nvme_ns *ns,
-		struct request *req, struct nvme_iod *iod)
-{
-	struct nvme_dsm_range *range =
-				(struct nvme_dsm_range *)iod_list(iod)[0];
-	struct nvme_command cmnd;
+	if (!nvme_setup_prps(dev, req, blk_rq_bytes(req)))
+		goto out_unmap;
 
-	range->cattr = cpu_to_le32(0);
-	range->nlb = cpu_to_le32(blk_rq_bytes(req) >> ns->lba_shift);
-	range->slba = cpu_to_le64(nvme_block_nr(ns, blk_rq_pos(req)));
+	ret = BLK_MQ_RQ_QUEUE_ERROR;
+	if (blk_integrity_rq(req)) {
+		if (blk_rq_count_integrity_sg(q, req->bio) != 1)
+			goto out_unmap;
 
-	memset(&cmnd, 0, sizeof(cmnd));
-	cmnd.dsm.opcode = nvme_cmd_dsm;
-	cmnd.dsm.command_id = req->tag;
-	cmnd.dsm.nsid = cpu_to_le32(ns->ns_id);
-	cmnd.dsm.prp1 = cpu_to_le64(iod->first_dma);
-	cmnd.dsm.nr = 0;
-	cmnd.dsm.attributes = cpu_to_le32(NVME_DSMGMT_AD);
+		sg_init_table(&iod->meta_sg, 1);
+		if (blk_rq_map_integrity_sg(q, req->bio, &iod->meta_sg) != 1)
+			goto out_unmap;
 
-	__nvme_submit_cmd(nvmeq, &cmnd);
-}
+		if (rq_data_dir(req))
+			nvme_dif_remap(req, nvme_dif_prep);
 
-static void nvme_submit_flush(struct nvme_queue *nvmeq, struct nvme_ns *ns,
-								int cmdid)
-{
-	struct nvme_command cmnd;
+		if (!dma_map_sg(dev->dev, &iod->meta_sg, 1, dma_dir))
+			goto out_unmap;
+	}
 
-	memset(&cmnd, 0, sizeof(cmnd));
-	cmnd.common.opcode = nvme_cmd_flush;
-	cmnd.common.command_id = cmdid;
-	cmnd.common.nsid = cpu_to_le32(ns->ns_id);
+	cmnd->rw.prp1 = cpu_to_le64(sg_dma_address(iod->sg));
+	cmnd->rw.prp2 = cpu_to_le64(iod->first_dma);
+	if (blk_integrity_rq(req))
+		cmnd->rw.metadata = cpu_to_le64(sg_dma_address(&iod->meta_sg));
+	return BLK_MQ_RQ_QUEUE_OK;
 
-	__nvme_submit_cmd(nvmeq, &cmnd);
+out_unmap:
+	dma_unmap_sg(dev->dev, iod->sg, iod->nents, dma_dir);
+out:
+	return ret;
 }
 
-static int nvme_submit_iod(struct nvme_queue *nvmeq, struct nvme_iod *iod,
-							struct nvme_ns *ns)
+static void nvme_unmap_data(struct nvme_dev *dev, struct request *req)
 {
-	struct request *req = iod_get_private(iod);
-	struct nvme_command cmnd;
-	u16 control = 0;
-	u32 dsmgmt = 0;
+	struct nvme_iod *iod = blk_mq_rq_to_pdu(req);
+	enum dma_data_direction dma_dir = rq_data_dir(req) ?
+			DMA_TO_DEVICE : DMA_FROM_DEVICE;
 
-	if (req->cmd_flags & REQ_FUA)
-		control |= NVME_RW_FUA;
-	if (req->cmd_flags & (REQ_FAILFAST_DEV | REQ_RAHEAD))
-		control |= NVME_RW_LR;
-
-	if (req->cmd_flags & REQ_RAHEAD)
-		dsmgmt |= NVME_RW_DSM_FREQ_PREFETCH;
-
-	memset(&cmnd, 0, sizeof(cmnd));
-	cmnd.rw.opcode = (rq_data_dir(req) ? nvme_cmd_write : nvme_cmd_read);
-	cmnd.rw.command_id = req->tag;
-	cmnd.rw.nsid = cpu_to_le32(ns->ns_id);
-	cmnd.rw.prp1 = cpu_to_le64(sg_dma_address(iod->sg));
-	cmnd.rw.prp2 = cpu_to_le64(iod->first_dma);
-	cmnd.rw.slba = cpu_to_le64(nvme_block_nr(ns, blk_rq_pos(req)));
-	cmnd.rw.length = cpu_to_le16((blk_rq_bytes(req) >> ns->lba_shift) - 1);
-
-	if (ns->ms) {
-		switch (ns->pi_type) {
-		case NVME_NS_DPS_PI_TYPE3:
-			control |= NVME_RW_PRINFO_PRCHK_GUARD;
-			break;
-		case NVME_NS_DPS_PI_TYPE1:
-		case NVME_NS_DPS_PI_TYPE2:
-			control |= NVME_RW_PRINFO_PRCHK_GUARD |
-					NVME_RW_PRINFO_PRCHK_REF;
-			cmnd.rw.reftag = cpu_to_le32(
-					nvme_block_nr(ns, blk_rq_pos(req)));
-			break;
+	if (iod->nents) {
+		dma_unmap_sg(dev->dev, iod->sg, iod->nents, dma_dir);
+		if (blk_integrity_rq(req)) {
+			if (!rq_data_dir(req))
+				nvme_dif_remap(req, nvme_dif_complete);
+			dma_unmap_sg(dev->dev, &iod->meta_sg, 1, dma_dir);
 		}
-		if (blk_integrity_rq(req))
-			cmnd.rw.metadata =
-				cpu_to_le64(sg_dma_address(iod->meta_sg));
-		else
-			control |= NVME_RW_PRINFO_PRACT;
 	}
 
-	cmnd.rw.control = cpu_to_le16(control);
-	cmnd.rw.dsmgmt = cpu_to_le32(dsmgmt);
+	nvme_free_iod(dev, req);
+}
 
-	__nvme_submit_cmd(nvmeq, &cmnd);
+/*
+ * We reuse the small pool to allocate the 16-byte range here as it is not
+ * worth having a special pool for these or additional cases to handle freeing
+ * the iod.
+ */
+static int nvme_setup_discard(struct nvme_queue *nvmeq, struct nvme_ns *ns,
+		struct request *req, struct nvme_command *cmnd)
+{
+	struct nvme_iod *iod = blk_mq_rq_to_pdu(req);
+	struct nvme_dsm_range *range;
 
-	return 0;
+	range = dma_pool_alloc(nvmeq->dev->prp_small_pool, GFP_ATOMIC,
+						&iod->first_dma);
+	if (!range)
+		return BLK_MQ_RQ_QUEUE_BUSY;
+	iod_list(req)[0] = (__le64 *)range;
+	iod->npages = 0;
+
+	range->cattr = cpu_to_le32(0);
+	range->nlb = cpu_to_le32(blk_rq_bytes(req) >> ns->lba_shift);
+	range->slba = cpu_to_le64(nvme_block_nr(ns, blk_rq_pos(req)));
+
+	memset(cmnd, 0, sizeof(*cmnd));
+	cmnd->dsm.opcode = nvme_cmd_dsm;
+	cmnd->dsm.nsid = cpu_to_le32(ns->ns_id);
+	cmnd->dsm.prp1 = cpu_to_le64(iod->first_dma);
+	cmnd->dsm.nr = 0;
+	cmnd->dsm.attributes = cpu_to_le32(NVME_DSMGMT_AD);
+	return BLK_MQ_RQ_QUEUE_OK;
 }
 
 /*
@@ -845,9 +650,8 @@ static int nvme_queue_rq(struct blk_mq_h
 	struct nvme_queue *nvmeq = hctx->driver_data;
 	struct nvme_dev *dev = nvmeq->dev;
 	struct request *req = bd->rq;
-	struct nvme_cmd_info *cmd = blk_mq_rq_to_pdu(req);
-	struct nvme_iod *iod;
-	enum dma_data_direction dma_dir;
+	struct nvme_command cmnd;
+	int ret = BLK_MQ_RQ_QUEUE_OK;
 
 	/*
 	 * If formated with metadata, require the block layer provide a buffer
@@ -857,91 +661,80 @@ static int nvme_queue_rq(struct blk_mq_h
 	if (ns && ns->ms && !blk_integrity_rq(req)) {
 		if (!(ns->pi_type && ns->ms == 8) &&
 					req->cmd_type != REQ_TYPE_DRV_PRIV) {
-			blk_mq_complete_request(req, -EFAULT);
+			blk_mq_end_request(req, -EFAULT);
 			return BLK_MQ_RQ_QUEUE_OK;
 		}
 	}
 
-	iod = nvme_alloc_iod(req, dev, GFP_ATOMIC);
-	if (!iod)
-		return BLK_MQ_RQ_QUEUE_BUSY;
+	ret = nvme_init_iod(req, dev);
+	if (ret)
+		return ret;
 
 	if (req->cmd_flags & REQ_DISCARD) {
-		void *range;
-		/*
-		 * We reuse the small pool to allocate the 16-byte range here
-		 * as it is not worth having a special pool for these or
-		 * additional cases to handle freeing the iod.
-		 */
-		range = dma_pool_alloc(dev->prp_small_pool, GFP_ATOMIC,
-						&iod->first_dma);
-		if (!range)
-			goto retry_cmd;
-		iod_list(iod)[0] = (__le64 *)range;
-		iod->npages = 0;
-	} else if (req->nr_phys_segments) {
-		dma_dir = rq_data_dir(req) ? DMA_TO_DEVICE : DMA_FROM_DEVICE;
+		ret = nvme_setup_discard(nvmeq, ns, req, &cmnd);
+	} else {
+		if (req->cmd_type == REQ_TYPE_DRV_PRIV)
+			memcpy(&cmnd, req->cmd, sizeof(cmnd));
+		else if (req->cmd_flags & REQ_FLUSH)
+			nvme_setup_flush(ns, &cmnd);
+		else
+			nvme_setup_rw(ns, req, &cmnd);
 
-		sg_init_table(iod->sg, req->nr_phys_segments);
-		iod->nents = blk_rq_map_sg(req->q, req, iod->sg);
-		if (!iod->nents)
-			goto error_cmd;
-
-		if (!dma_map_sg(nvmeq->q_dmadev, iod->sg, iod->nents, dma_dir))
-			goto retry_cmd;
-
-		if (blk_rq_bytes(req) !=
-                    nvme_setup_prps(dev, iod, blk_rq_bytes(req), GFP_ATOMIC)) {
-			dma_unmap_sg(dev->dev, iod->sg, iod->nents, dma_dir);
-			goto retry_cmd;
-		}
-		if (blk_integrity_rq(req)) {
-			if (blk_rq_count_integrity_sg(req->q, req->bio) != 1) {
-				dma_unmap_sg(dev->dev, iod->sg, iod->nents,
-						dma_dir);
-				goto error_cmd;
-			}
-
-			sg_init_table(iod->meta_sg, 1);
-			if (blk_rq_map_integrity_sg(
-					req->q, req->bio, iod->meta_sg) != 1) {
-				dma_unmap_sg(dev->dev, iod->sg, iod->nents,
-						dma_dir);
-				goto error_cmd;
-			}
-
-			if (rq_data_dir(req))
-				nvme_dif_remap(req, nvme_dif_prep);
-
-			if (!dma_map_sg(nvmeq->q_dmadev, iod->meta_sg, 1, dma_dir)) {
-				dma_unmap_sg(dev->dev, iod->sg, iod->nents,
-						dma_dir);
-				goto error_cmd;
-			}
-		}
+		if (req->nr_phys_segments)
+			ret = nvme_map_data(dev, req, &cmnd);
 	}
 
-	nvme_set_info(cmd, iod, req_completion);
-	spin_lock_irq(&nvmeq->q_lock);
-	if (req->cmd_type == REQ_TYPE_DRV_PRIV)
-		nvme_submit_priv(nvmeq, req, iod);
-	else if (req->cmd_flags & REQ_DISCARD)
-		nvme_submit_discard(nvmeq, ns, req, iod);
-	else if (req->cmd_flags & REQ_FLUSH)
-		nvme_submit_flush(nvmeq, ns, req->tag);
-	else
-		nvme_submit_iod(nvmeq, iod, ns);
+	if (ret)
+		goto out;
 
+	cmnd.common.command_id = req->tag;
+	blk_mq_start_request(req);
+
+	spin_lock_irq(&nvmeq->q_lock);
+	if (unlikely(nvmeq->cq_vector < 0)) {
+		if (ns && !test_bit(NVME_NS_DEAD, &ns->flags))
+			ret = BLK_MQ_RQ_QUEUE_BUSY;
+		else
+			ret = BLK_MQ_RQ_QUEUE_ERROR;
+		spin_unlock_irq(&nvmeq->q_lock);
+		goto out;
+	}
+	__nvme_submit_cmd(nvmeq, &cmnd);
 	nvme_process_cq(nvmeq);
 	spin_unlock_irq(&nvmeq->q_lock);
 	return BLK_MQ_RQ_QUEUE_OK;
+out:
+	nvme_free_iod(dev, req);
+	return ret;
+}
+
+static void nvme_complete_rq(struct request *req)
+{
+	struct nvme_iod *iod = blk_mq_rq_to_pdu(req);
+	struct nvme_dev *dev = iod->nvmeq->dev;
+	int error = 0;
+
+	nvme_unmap_data(dev, req);
+
+	if (unlikely(req->errors)) {
+		if (nvme_req_needs_retry(req, req->errors)) {
+			nvme_requeue_req(req);
+			return;
+		}
+
+		if (req->cmd_type == REQ_TYPE_DRV_PRIV)
+			error = req->errors;
+		else
+			error = nvme_error_status(req->errors);
+	}
+
+	if (unlikely(iod->aborted)) {
+		dev_warn(dev->dev,
+			"completing aborted command with status: %04x\n",
+			req->errors);
+	}
 
- error_cmd:
-	nvme_free_iod(dev, iod);
-	return BLK_MQ_RQ_QUEUE_ERROR;
- retry_cmd:
-	nvme_free_iod(dev, iod);
-	return BLK_MQ_RQ_QUEUE_BUSY;
+	blk_mq_end_request(req, error);
 }
 
 static void __nvme_process_cq(struct nvme_queue *nvmeq, unsigned int *tag)
@@ -952,20 +745,47 @@ static void __nvme_process_cq(struct nvm
 	phase = nvmeq->cq_phase;
 
 	for (;;) {
-		void *ctx;
-		nvme_completion_fn fn;
 		struct nvme_completion cqe = nvmeq->cqes[head];
-		if ((le16_to_cpu(cqe.status) & 1) != phase)
+		u16 status = le16_to_cpu(cqe.status);
+		struct request *req;
+
+		if ((status & 1) != phase)
 			break;
 		nvmeq->sq_head = le16_to_cpu(cqe.sq_head);
 		if (++head == nvmeq->q_depth) {
 			head = 0;
 			phase = !phase;
 		}
+
 		if (tag && *tag == cqe.command_id)
 			*tag = -1;
-		ctx = nvme_finish_cmd(nvmeq, cqe.command_id, &fn);
-		fn(nvmeq, ctx, &cqe);
+
+		if (unlikely(cqe.command_id >= nvmeq->q_depth)) {
+			dev_warn(nvmeq->q_dmadev,
+				"invalid id %d completed on queue %d\n",
+				cqe.command_id, le16_to_cpu(cqe.sq_id));
+			continue;
+		}
+
+		/*
+		 * AEN requests are special as they don't time out and can
+		 * survive any kind of queue freeze and often don't respond to
+		 * aborts.  We don't even bother to allocate a struct request
+		 * for them but rather special case them here.
+		 */
+		if (unlikely(nvmeq->qid == 0 &&
+				cqe.command_id >= NVME_AQ_BLKMQ_DEPTH)) {
+			nvme_complete_async_event(nvmeq->dev, &cqe);
+			continue;
+		}
+
+		req = blk_mq_tag_to_rq(*nvmeq->tags, cqe.command_id);
+		if (req->cmd_type == REQ_TYPE_DRV_PRIV) {
+			u32 result = le32_to_cpu(cqe.result);
+			req->special = (void *)(uintptr_t)result;
+		}
+		blk_mq_complete_request(req, status >> 1);
+
 	}
 
 	/* If the controller ignores the cq head doorbell and continuously
@@ -1028,126 +848,37 @@ static int nvme_poll(struct blk_mq_hw_ct
 	return 0;
 }
 
-/*
- * Returns 0 on success.  If the result is negative, it's a Linux error code;
- * if the result is positive, it's an NVM Express status code
- */
-int __nvme_submit_sync_cmd(struct request_queue *q, struct nvme_command *cmd,
-		void *buffer, void __user *ubuffer, unsigned bufflen,
-		u32 *result, unsigned timeout)
+static void nvme_async_event_work(struct work_struct *work)
 {
-	bool write = cmd->common.opcode & 1;
-	struct bio *bio = NULL;
-	struct request *req;
-	int ret;
+	struct nvme_dev *dev = container_of(work, struct nvme_dev, async_work);
+	struct nvme_queue *nvmeq = dev->queues[0];
+	struct nvme_command c;
 
-	req = blk_mq_alloc_request(q, write, GFP_KERNEL, false);
-	if (IS_ERR(req))
-		return PTR_ERR(req);
+	memset(&c, 0, sizeof(c));
+	c.common.opcode = nvme_admin_async_event;
 
-	req->cmd_type = REQ_TYPE_DRV_PRIV;
-	req->cmd_flags |= REQ_FAILFAST_DRIVER;
-	req->__data_len = 0;
-	req->__sector = (sector_t) -1;
-	req->bio = req->biotail = NULL;
-
-	req->timeout = timeout ? timeout : ADMIN_TIMEOUT;
-
-	req->cmd = (unsigned char *)cmd;
-	req->cmd_len = sizeof(struct nvme_command);
-	req->special = (void *)0;
-
-	if (buffer && bufflen) {
-		ret = blk_rq_map_kern(q, req, buffer, bufflen,
-				      __GFP_DIRECT_RECLAIM);
-		if (ret)
-			goto out;
-	} else if (ubuffer && bufflen) {
-		ret = blk_rq_map_user(q, req, NULL, ubuffer, bufflen,
-				      __GFP_DIRECT_RECLAIM);
-		if (ret)
-			goto out;
-		bio = req->bio;
-	}
-
-	blk_execute_rq(req->q, NULL, req, 0);
-	if (bio)
-		blk_rq_unmap_user(bio);
-	if (result)
-		*result = (u32)(uintptr_t)req->special;
-	ret = req->errors;
- out:
-	blk_mq_free_request(req);
-	return ret;
+	spin_lock_irq(&nvmeq->q_lock);
+	while (dev->ctrl.event_limit > 0) {
+		c.common.command_id = NVME_AQ_BLKMQ_DEPTH +
+			--dev->ctrl.event_limit;
+		__nvme_submit_cmd(nvmeq, &c);
+	}
+	spin_unlock_irq(&nvmeq->q_lock);
 }
 
-int nvme_submit_sync_cmd(struct request_queue *q, struct nvme_command *cmd,
-		void *buffer, unsigned bufflen)
+static int adapter_delete_queue(struct nvme_dev *dev, u8 opcode, u16 id)
 {
-	return __nvme_submit_sync_cmd(q, cmd, buffer, NULL, bufflen, NULL, 0);
+	struct nvme_command c;
+
+	memset(&c, 0, sizeof(c));
+	c.delete_queue.opcode = opcode;
+	c.delete_queue.qid = cpu_to_le16(id);
+
+	return nvme_submit_sync_cmd(dev->ctrl.admin_q, &c, NULL, 0);
 }
 
-static int nvme_submit_async_admin_req(struct nvme_dev *dev)
-{
-	struct nvme_queue *nvmeq = dev->queues[0];
-	struct nvme_command c;
-	struct nvme_cmd_info *cmd_info;
-	struct request *req;
-
-	req = blk_mq_alloc_request(dev->admin_q, WRITE, GFP_ATOMIC, true);
-	if (IS_ERR(req))
-		return PTR_ERR(req);
-
-	req->cmd_flags |= REQ_NO_TIMEOUT;
-	cmd_info = blk_mq_rq_to_pdu(req);
-	nvme_set_info(cmd_info, NULL, async_req_completion);
-
-	memset(&c, 0, sizeof(c));
-	c.common.opcode = nvme_admin_async_event;
-	c.common.command_id = req->tag;
-
-	blk_mq_free_request(req);
-	__nvme_submit_cmd(nvmeq, &c);
-	return 0;
-}
-
-static int nvme_submit_admin_async_cmd(struct nvme_dev *dev,
-			struct nvme_command *cmd,
-			struct async_cmd_info *cmdinfo, unsigned timeout)
-{
-	struct nvme_queue *nvmeq = dev->queues[0];
-	struct request *req;
-	struct nvme_cmd_info *cmd_rq;
-
-	req = blk_mq_alloc_request(dev->admin_q, WRITE, GFP_KERNEL, false);
-	if (IS_ERR(req))
-		return PTR_ERR(req);
-
-	req->timeout = timeout;
-	cmd_rq = blk_mq_rq_to_pdu(req);
-	cmdinfo->req = req;
-	nvme_set_info(cmd_rq, cmdinfo, async_completion);
-	cmdinfo->status = -EINTR;
-
-	cmd->common.command_id = req->tag;
-
-	nvme_submit_cmd(nvmeq, cmd);
-	return 0;
-}
-
-static int adapter_delete_queue(struct nvme_dev *dev, u8 opcode, u16 id)
-{
-	struct nvme_command c;
-
-	memset(&c, 0, sizeof(c));
-	c.delete_queue.opcode = opcode;
-	c.delete_queue.qid = cpu_to_le16(id);
-
-	return nvme_submit_sync_cmd(dev->admin_q, &c, NULL, 0);
-}
-
-static int adapter_alloc_cq(struct nvme_dev *dev, u16 qid,
-						struct nvme_queue *nvmeq)
+static int adapter_alloc_cq(struct nvme_dev *dev, u16 qid,
+						struct nvme_queue *nvmeq)
 {
 	struct nvme_command c;
 	int flags = NVME_QUEUE_PHYS_CONTIG | NVME_CQ_IRQ_ENABLED;
@@ -1164,7 +895,7 @@ static int adapter_alloc_cq(struct nvme_
 	c.create_cq.cq_flags = cpu_to_le16(flags);
 	c.create_cq.irq_vector = cpu_to_le16(nvmeq->cq_vector);
 
-	return nvme_submit_sync_cmd(dev->admin_q, &c, NULL, 0);
+	return nvme_submit_sync_cmd(dev->ctrl.admin_q, &c, NULL, 0);
 }
 
 static int adapter_alloc_sq(struct nvme_dev *dev, u16 qid,
@@ -1185,7 +916,7 @@ static int adapter_alloc_sq(struct nvme_
 	c.create_sq.sq_flags = cpu_to_le16(flags);
 	c.create_sq.cqid = cpu_to_le16(qid);
 
-	return nvme_submit_sync_cmd(dev->admin_q, &c, NULL, 0);
+	return nvme_submit_sync_cmd(dev->ctrl.admin_q, &c, NULL, 0);
 }
 
 static int adapter_delete_cq(struct nvme_dev *dev, u16 cqid)
@@ -1198,195 +929,111 @@ static int adapter_delete_sq(struct nvme
 	return adapter_delete_queue(dev, nvme_admin_delete_sq, sqid);
 }
 
-int nvme_identify_ctrl(struct nvme_dev *dev, struct nvme_id_ctrl **id)
-{
-	struct nvme_command c = { };
-	int error;
-
-	/* gcc-4.4.4 (at least) has issues with initializers and anon unions */
-	c.identify.opcode = nvme_admin_identify;
-	c.identify.cns = cpu_to_le32(1);
-
-	*id = kmalloc(sizeof(struct nvme_id_ctrl), GFP_KERNEL);
-	if (!*id)
-		return -ENOMEM;
-
-	error = nvme_submit_sync_cmd(dev->admin_q, &c, *id,
-			sizeof(struct nvme_id_ctrl));
-	if (error)
-		kfree(*id);
-	return error;
-}
-
-int nvme_identify_ns(struct nvme_dev *dev, unsigned nsid,
-		struct nvme_id_ns **id)
-{
-	struct nvme_command c = { };
-	int error;
-
-	/* gcc-4.4.4 (at least) has issues with initializers and anon unions */
-	c.identify.opcode = nvme_admin_identify,
-	c.identify.nsid = cpu_to_le32(nsid),
-
-	*id = kmalloc(sizeof(struct nvme_id_ns), GFP_KERNEL);
-	if (!*id)
-		return -ENOMEM;
-
-	error = nvme_submit_sync_cmd(dev->admin_q, &c, *id,
-			sizeof(struct nvme_id_ns));
-	if (error)
-		kfree(*id);
-	return error;
-}
-
-int nvme_get_features(struct nvme_dev *dev, unsigned fid, unsigned nsid,
-					dma_addr_t dma_addr, u32 *result)
-{
-	struct nvme_command c;
-
-	memset(&c, 0, sizeof(c));
-	c.features.opcode = nvme_admin_get_features;
-	c.features.nsid = cpu_to_le32(nsid);
-	c.features.prp1 = cpu_to_le64(dma_addr);
-	c.features.fid = cpu_to_le32(fid);
-
-	return __nvme_submit_sync_cmd(dev->admin_q, &c, NULL, NULL, 0,
-			result, 0);
-}
-
-int nvme_set_features(struct nvme_dev *dev, unsigned fid, unsigned dword11,
-					dma_addr_t dma_addr, u32 *result)
-{
-	struct nvme_command c;
-
-	memset(&c, 0, sizeof(c));
-	c.features.opcode = nvme_admin_set_features;
-	c.features.prp1 = cpu_to_le64(dma_addr);
-	c.features.fid = cpu_to_le32(fid);
-	c.features.dword11 = cpu_to_le32(dword11);
-
-	return __nvme_submit_sync_cmd(dev->admin_q, &c, NULL, NULL, 0,
-			result, 0);
-}
-
-int nvme_get_log_page(struct nvme_dev *dev, struct nvme_smart_log **log)
+static void abort_endio(struct request *req, int error)
 {
-	struct nvme_command c = { };
-	int error;
-
-	c.common.opcode = nvme_admin_get_log_page,
-	c.common.nsid = cpu_to_le32(0xFFFFFFFF),
-	c.common.cdw10[0] = cpu_to_le32(
-			(((sizeof(struct nvme_smart_log) / 4) - 1) << 16) |
-			 NVME_LOG_SMART),
+	struct nvme_iod *iod = blk_mq_rq_to_pdu(req);
+	struct nvme_queue *nvmeq = iod->nvmeq;
+	u32 result = (u32)(uintptr_t)req->special;
+	u16 status = req->errors;
 
-	*log = kmalloc(sizeof(struct nvme_smart_log), GFP_KERNEL);
-	if (!*log)
-		return -ENOMEM;
+	dev_warn(nvmeq->q_dmadev, "Abort status:%x result:%x", status, result);
+	atomic_inc(&nvmeq->dev->ctrl.abort_limit);
 
-	error = nvme_submit_sync_cmd(dev->admin_q, &c, *log,
-			sizeof(struct nvme_smart_log));
-	if (error)
-		kfree(*log);
-	return error;
+	blk_mq_free_request(req);
 }
 
-/**
- * nvme_abort_req - Attempt aborting a request
- *
- * Schedule controller reset if the command was already aborted once before and
- * still hasn't been returned to the driver, or if this is the admin queue.
- */
-static void nvme_abort_req(struct request *req)
+static enum blk_eh_timer_return nvme_timeout(struct request *req, bool reserved)
 {
-	struct nvme_cmd_info *cmd_rq = blk_mq_rq_to_pdu(req);
-	struct nvme_queue *nvmeq = cmd_rq->nvmeq;
+	struct nvme_iod *iod = blk_mq_rq_to_pdu(req);
+	struct nvme_queue *nvmeq = iod->nvmeq;
 	struct nvme_dev *dev = nvmeq->dev;
 	struct request *abort_req;
-	struct nvme_cmd_info *abort_cmd;
 	struct nvme_command cmd;
 
-	if (!nvmeq->qid || cmd_rq->aborted) {
-		spin_lock(&dev_list_lock);
-		if (!__nvme_reset(dev)) {
-			dev_warn(dev->dev,
-				 "I/O %d QID %d timeout, reset controller\n",
-				 req->tag, nvmeq->qid);
-		}
-		spin_unlock(&dev_list_lock);
-		return;
+	/*
+	 * Shutdown immediately if controller times out while starting. The
+	 * reset work will see the pci device disabled when it gets the forced
+	 * cancellation error. All outstanding requests are completed on
+	 * shutdown, so we return BLK_EH_HANDLED.
+	 */
+	if (test_bit(NVME_CTRL_RESETTING, &dev->flags)) {
+		dev_warn(dev->dev,
+			 "I/O %d QID %d timeout, disable controller\n",
+			 req->tag, nvmeq->qid);
+		nvme_dev_disable(dev, false);
+		req->errors = NVME_SC_CANCELLED;
+		return BLK_EH_HANDLED;
 	}
 
-	if (!dev->abort_limit)
-		return;
+	/*
+ 	 * Shutdown the controller immediately and schedule a reset if the
+ 	 * command was already aborted once before and still hasn't been
+ 	 * returned to the driver, or if this is the admin queue.
+	 */
+	if (!nvmeq->qid || iod->aborted) {
+		dev_warn(dev->dev,
+			 "I/O %d QID %d timeout, reset controller\n",
+			 req->tag, nvmeq->qid);
+		nvme_dev_disable(dev, false);
+		queue_work(nvme_workq, &dev->reset_work);
 
-	abort_req = blk_mq_alloc_request(dev->admin_q, WRITE, GFP_ATOMIC,
-									false);
-	if (IS_ERR(abort_req))
-		return;
+		/*
+		 * Mark the request as handled, since the inline shutdown
+		 * forces all outstanding requests to complete.
+		 */
+		req->errors = NVME_SC_CANCELLED;
+		return BLK_EH_HANDLED;
+	}
 
-	abort_cmd = blk_mq_rq_to_pdu(abort_req);
-	nvme_set_info(abort_cmd, abort_req, abort_completion);
+	iod->aborted = 1;
+
+	if (atomic_dec_return(&dev->ctrl.abort_limit) < 0) {
+		atomic_inc(&dev->ctrl.abort_limit);
+		return BLK_EH_RESET_TIMER;
+	}
 
 	memset(&cmd, 0, sizeof(cmd));
 	cmd.abort.opcode = nvme_admin_abort_cmd;
 	cmd.abort.cid = req->tag;
 	cmd.abort.sqid = cpu_to_le16(nvmeq->qid);
-	cmd.abort.command_id = abort_req->tag;
 
-	--dev->abort_limit;
-	cmd_rq->aborted = 1;
+	dev_warn(nvmeq->q_dmadev, "I/O %d QID %d timeout, aborting\n",
+				 req->tag, nvmeq->qid);
+
+	abort_req = nvme_alloc_request(dev->ctrl.admin_q, &cmd,
+			BLK_MQ_REQ_NOWAIT);
+	if (IS_ERR(abort_req)) {
+		atomic_inc(&dev->ctrl.abort_limit);
+		return BLK_EH_RESET_TIMER;
+	}
+
+	abort_req->timeout = ADMIN_TIMEOUT;
+	abort_req->end_io_data = NULL;
+	blk_execute_rq_nowait(abort_req->q, NULL, abort_req, 0, abort_endio);
 
-	dev_warn(nvmeq->q_dmadev, "Aborting I/O %d QID %d\n", req->tag,
-							nvmeq->qid);
-	nvme_submit_cmd(dev->queues[0], &cmd);
+	/*
+	 * The aborted req will be completed on receiving the abort req.
+	 * We enable the timer again. If hit twice, it'll cause a device reset,
+	 * as the device then is in a faulty state.
+	 */
+	return BLK_EH_RESET_TIMER;
 }
 
 static void nvme_cancel_queue_ios(struct request *req, void *data, bool reserved)
 {
 	struct nvme_queue *nvmeq = data;
-	void *ctx;
-	nvme_completion_fn fn;
-	struct nvme_cmd_info *cmd;
-	struct nvme_completion cqe;
+	int status;
 
 	if (!blk_mq_request_started(req))
 		return;
 
-	cmd = blk_mq_rq_to_pdu(req);
-
-	if (cmd->ctx == CMD_CTX_CANCELLED)
-		return;
+	dev_warn(nvmeq->q_dmadev,
+		 "Cancelling I/O %d QID %d\n", req->tag, nvmeq->qid);
 
+	status = NVME_SC_ABORT_REQ;
 	if (blk_queue_dying(req->q))
-		cqe.status = cpu_to_le16((NVME_SC_ABORT_REQ | NVME_SC_DNR) << 1);
-	else
-		cqe.status = cpu_to_le16(NVME_SC_ABORT_REQ << 1);
-
-
-	dev_warn(nvmeq->q_dmadev, "Cancelling I/O %d QID %d\n",
-						req->tag, nvmeq->qid);
-	ctx = cancel_cmd_info(cmd, &fn);
-	fn(nvmeq, ctx, &cqe);
-}
-
-static enum blk_eh_timer_return nvme_timeout(struct request *req, bool reserved)
-{
-	struct nvme_cmd_info *cmd = blk_mq_rq_to_pdu(req);
-	struct nvme_queue *nvmeq = cmd->nvmeq;
-
-	dev_warn(nvmeq->q_dmadev, "Timeout I/O %d QID %d\n", req->tag,
-							nvmeq->qid);
-	spin_lock_irq(&nvmeq->q_lock);
-	nvme_abort_req(req);
-	spin_unlock_irq(&nvmeq->q_lock);
-
-	/*
-	 * The aborted req will be completed on receiving the abort req.
-	 * We enable the timer again. If hit twice, it'll cause a device reset,
-	 * as the device then is in a faulty state.
-	 */
-	return BLK_EH_RESET_TIMER;
+		status |= NVME_SC_DNR;
+	blk_mq_complete_request(req, status);
 }
 
 static void nvme_free_queue(struct nvme_queue *nvmeq)
@@ -1429,8 +1076,8 @@ static int nvme_suspend_queue(struct nvm
 	nvmeq->cq_vector = -1;
 	spin_unlock_irq(&nvmeq->q_lock);
 
-	if (!nvmeq->qid && nvmeq->dev->admin_q)
-		blk_mq_freeze_queue_start(nvmeq->dev->admin_q);
+	if (!nvmeq->qid && nvmeq->dev->ctrl.admin_q)
+		blk_mq_stop_hw_queues(nvmeq->dev->ctrl.admin_q);
 
 	irq_set_affinity_hint(vector, NULL);
 	free_irq(vector, nvmeq);
@@ -1446,21 +1093,20 @@ static void nvme_clear_queue(struct nvme
 	spin_unlock_irq(&nvmeq->q_lock);
 }
 
-static void nvme_disable_queue(struct nvme_dev *dev, int qid)
+static void nvme_disable_admin_queue(struct nvme_dev *dev, bool shutdown)
 {
-	struct nvme_queue *nvmeq = dev->queues[qid];
+	struct nvme_queue *nvmeq = dev->queues[0];
 
 	if (!nvmeq)
 		return;
 	if (nvme_suspend_queue(nvmeq))
 		return;
 
-	/* Don't tell the adapter to delete the admin queue.
-	 * Don't tell a removed adapter to delete IO queues. */
-	if (qid && readl(&dev->bar->csts) != -1) {
-		adapter_delete_sq(dev, qid);
-		adapter_delete_cq(dev, qid);
-	}
+	if (shutdown)
+		nvme_shutdown_ctrl(&dev->ctrl);
+	else
+		nvme_disable_ctrl(&dev->ctrl, lo_hi_readq(
+						dev->bar + NVME_REG_CAP));
 
 	spin_lock_irq(&nvmeq->q_lock);
 	nvme_process_cq(nvmeq);
@@ -1471,11 +1117,12 @@ static int nvme_cmb_qdepth(struct nvme_d
 				int entry_size)
 {
 	int q_depth = dev->q_depth;
-	unsigned q_size_aligned = roundup(q_depth * entry_size, dev->page_size);
+	unsigned q_size_aligned = roundup(q_depth * entry_size,
+					  dev->ctrl.page_size);
 
 	if (q_size_aligned * nr_io_queues > dev->cmb_size) {
 		u64 mem_per_q = div_u64(dev->cmb_size, nr_io_queues);
-		mem_per_q = round_down(mem_per_q, dev->page_size);
+		mem_per_q = round_down(mem_per_q, dev->ctrl.page_size);
 		q_depth = div_u64(mem_per_q, entry_size);
 
 		/*
@@ -1494,8 +1141,8 @@ static int nvme_alloc_sq_cmds(struct nvm
 				int qid, int depth)
 {
 	if (qid && dev->cmb && use_cmb_sqes && NVME_CMB_SQS(dev->cmbsz)) {
-		unsigned offset = (qid - 1) *
-					roundup(SQ_SIZE(depth), dev->page_size);
+		unsigned offset = (qid - 1) * roundup(SQ_SIZE(depth),
+						      dev->ctrl.page_size);
 		nvmeq->sq_dma_addr = dev->cmb_dma_addr + offset;
 		nvmeq->sq_cmds_io = dev->cmb + offset;
 	} else {
@@ -1526,7 +1173,7 @@ static struct nvme_queue *nvme_alloc_que
 	nvmeq->q_dmadev = dev->dev;
 	nvmeq->dev = dev;
 	snprintf(nvmeq->irqname, sizeof(nvmeq->irqname), "nvme%dq%d",
-			dev->instance, qid);
+			dev->ctrl.instance, qid);
 	spin_lock_init(&nvmeq->q_lock);
 	nvmeq->cq_head = 0;
 	nvmeq->cq_phase = 1;
@@ -1535,9 +1182,6 @@ static struct nvme_queue *nvme_alloc_que
 	nvmeq->qid = qid;
 	nvmeq->cq_vector = -1;
 	dev->queues[qid] = nvmeq;
-
-	/* make sure queue descriptor is set before queue count, for kthread */
-	mb();
 	dev->queue_count++;
 
 	return nvmeq;
@@ -1603,79 +1247,9 @@ static int nvme_create_queue(struct nvme
 	return result;
 }
 
-static int nvme_wait_ready(struct nvme_dev *dev, u64 cap, bool enabled)
-{
-	unsigned long timeout;
-	u32 bit = enabled ? NVME_CSTS_RDY : 0;
-
-	timeout = ((NVME_CAP_TIMEOUT(cap) + 1) * HZ / 2) + jiffies;
-
-	while ((readl(&dev->bar->csts) & NVME_CSTS_RDY) != bit) {
-		msleep(100);
-		if (fatal_signal_pending(current))
-			return -EINTR;
-		if (time_after(jiffies, timeout)) {
-			dev_err(dev->dev,
-				"Device not ready; aborting %s\n", enabled ?
-						"initialisation" : "reset");
-			return -ENODEV;
-		}
-	}
-
-	return 0;
-}
-
-/*
- * If the device has been passed off to us in an enabled state, just clear
- * the enabled bit.  The spec says we should set the 'shutdown notification
- * bits', but doing so may cause the device to complete commands to the
- * admin queue ... and we don't know what memory that might be pointing at!
- */
-static int nvme_disable_ctrl(struct nvme_dev *dev, u64 cap)
-{
-	dev->ctrl_config &= ~NVME_CC_SHN_MASK;
-	dev->ctrl_config &= ~NVME_CC_ENABLE;
-	writel(dev->ctrl_config, &dev->bar->cc);
-
-	return nvme_wait_ready(dev, cap, false);
-}
-
-static int nvme_enable_ctrl(struct nvme_dev *dev, u64 cap)
-{
-	dev->ctrl_config &= ~NVME_CC_SHN_MASK;
-	dev->ctrl_config |= NVME_CC_ENABLE;
-	writel(dev->ctrl_config, &dev->bar->cc);
-
-	return nvme_wait_ready(dev, cap, true);
-}
-
-static int nvme_shutdown_ctrl(struct nvme_dev *dev)
-{
-	unsigned long timeout;
-
-	dev->ctrl_config &= ~NVME_CC_SHN_MASK;
-	dev->ctrl_config |= NVME_CC_SHN_NORMAL;
-
-	writel(dev->ctrl_config, &dev->bar->cc);
-
-	timeout = SHUTDOWN_TIMEOUT + jiffies;
-	while ((readl(&dev->bar->csts) & NVME_CSTS_SHST_MASK) !=
-							NVME_CSTS_SHST_CMPLT) {
-		msleep(100);
-		if (fatal_signal_pending(current))
-			return -EINTR;
-		if (time_after(jiffies, timeout)) {
-			dev_err(dev->dev,
-				"Device shutdown incomplete; abort shutdown\n");
-			return -ENODEV;
-		}
-	}
-
-	return 0;
-}
-
 static struct blk_mq_ops nvme_mq_admin_ops = {
 	.queue_rq	= nvme_queue_rq,
+	.complete	= nvme_complete_rq,
 	.map_queue	= blk_mq_map_queue,
 	.init_hctx	= nvme_admin_init_hctx,
 	.exit_hctx      = nvme_admin_exit_hctx,
@@ -1685,6 +1259,7 @@ static struct blk_mq_ops nvme_mq_admin_o
 
 static struct blk_mq_ops nvme_mq_ops = {
 	.queue_rq	= nvme_queue_rq,
+	.complete	= nvme_complete_rq,
 	.map_queue	= blk_mq_map_queue,
 	.init_hctx	= nvme_init_hctx,
 	.init_request	= nvme_init_request,
@@ -1694,19 +1269,29 @@ static struct blk_mq_ops nvme_mq_ops = {
 
 static void nvme_dev_remove_admin(struct nvme_dev *dev)
 {
-	if (dev->admin_q && !blk_queue_dying(dev->admin_q)) {
-		blk_cleanup_queue(dev->admin_q);
+	if (dev->ctrl.admin_q && !blk_queue_dying(dev->ctrl.admin_q)) {
+		/*
+		 * If the controller was reset during removal, it's possible
+		 * user requests may be waiting on a stopped queue. Start the
+		 * queue to flush these to completion.
+		 */
+		blk_mq_start_stopped_hw_queues(dev->ctrl.admin_q, true);
+		blk_cleanup_queue(dev->ctrl.admin_q);
 		blk_mq_free_tag_set(&dev->admin_tagset);
 	}
 }
 
 static int nvme_alloc_admin_tags(struct nvme_dev *dev)
 {
-	if (!dev->admin_q) {
+	if (!dev->ctrl.admin_q) {
 		dev->admin_tagset.ops = &nvme_mq_admin_ops;
 		dev->admin_tagset.nr_hw_queues = 1;
-		dev->admin_tagset.queue_depth = NVME_AQ_DEPTH - 1;
-		dev->admin_tagset.reserved_tags = 1;
+
+		/*
+		 * Subtract one to leave an empty queue entry for 'Full Queue'
+		 * condition. See NVM-Express 1.2 specification, section 4.1.2.
+		 */
+		dev->admin_tagset.queue_depth = NVME_AQ_BLKMQ_DEPTH - 1;
 		dev->admin_tagset.timeout = ADMIN_TIMEOUT;
 		dev->admin_tagset.numa_node = dev_to_node(dev->dev);
 		dev->admin_tagset.cmd_size = nvme_cmd_size(dev);
@@ -1715,18 +1300,18 @@ static int nvme_alloc_admin_tags(struct
 		if (blk_mq_alloc_tag_set(&dev->admin_tagset))
 			return -ENOMEM;
 
-		dev->admin_q = blk_mq_init_queue(&dev->admin_tagset);
-		if (IS_ERR(dev->admin_q)) {
+		dev->ctrl.admin_q = blk_mq_init_queue(&dev->admin_tagset);
+		if (IS_ERR(dev->ctrl.admin_q)) {
 			blk_mq_free_tag_set(&dev->admin_tagset);
 			return -ENOMEM;
 		}
-		if (!blk_get_queue(dev->admin_q)) {
+		if (!blk_get_queue(dev->ctrl.admin_q)) {
 			nvme_dev_remove_admin(dev);
-			dev->admin_q = NULL;
+			dev->ctrl.admin_q = NULL;
 			return -ENODEV;
 		}
 	} else
-		blk_mq_unfreeze_queue(dev->admin_q);
+		blk_mq_start_stopped_hw_queues(dev->ctrl.admin_q, true);
 
 	return 0;
 }
@@ -1735,31 +1320,17 @@ static int nvme_configure_admin_queue(st
 {
 	int result;
 	u32 aqa;
-	u64 cap = lo_hi_readq(&dev->bar->cap);
+	u64 cap = lo_hi_readq(dev->bar + NVME_REG_CAP);
 	struct nvme_queue *nvmeq;
-	/*
-	 * default to a 4K page size, with the intention to update this
-	 * path in the future to accomodate architectures with differing
-	 * kernel and IO page sizes.
-	 */
-	unsigned page_shift = 12;
-	unsigned dev_page_min = NVME_CAP_MPSMIN(cap) + 12;
-
-	if (page_shift < dev_page_min) {
-		dev_err(dev->dev,
-				"Minimum device page size (%u) too large for "
-				"host (%u)\n", 1 << dev_page_min,
-				1 << page_shift);
-		return -ENODEV;
-	}
 
-	dev->subsystem = readl(&dev->bar->vs) >= NVME_VS(1, 1) ?
+	dev->subsystem = readl(dev->bar + NVME_REG_VS) >= NVME_VS(1, 1) ?
 						NVME_CAP_NSSRC(cap) : 0;
 
-	if (dev->subsystem && (readl(&dev->bar->csts) & NVME_CSTS_NSSRO))
-		writel(NVME_CSTS_NSSRO, &dev->bar->csts);
+	if (dev->subsystem &&
+	    (readl(dev->bar + NVME_REG_CSTS) & NVME_CSTS_NSSRO))
+		writel(NVME_CSTS_NSSRO, dev->bar + NVME_REG_CSTS);
 
-	result = nvme_disable_ctrl(dev, cap);
+	result = nvme_disable_ctrl(&dev->ctrl, cap);
 	if (result < 0)
 		return result;
 
@@ -1773,18 +1344,11 @@ static int nvme_configure_admin_queue(st
 	aqa = nvmeq->q_depth - 1;
 	aqa |= aqa << 16;
 
-	dev->page_size = 1 << page_shift;
-
-	dev->ctrl_config = NVME_CC_CSS_NVM;
-	dev->ctrl_config |= (page_shift - 12) << NVME_CC_MPS_SHIFT;
-	dev->ctrl_config |= NVME_CC_ARB_RR | NVME_CC_SHN_NONE;
-	dev->ctrl_config |= NVME_CC_IOSQES | NVME_CC_IOCQES;
-
-	writel(aqa, &dev->bar->aqa);
-	lo_hi_writeq(nvmeq->sq_dma_addr, &dev->bar->asq);
-	lo_hi_writeq(nvmeq->cq_dma_addr, &dev->bar->acq);
+	writel(aqa, dev->bar + NVME_REG_AQA);
+	lo_hi_writeq(nvmeq->sq_dma_addr, dev->bar + NVME_REG_ASQ);
+	lo_hi_writeq(nvmeq->cq_dma_addr, dev->bar + NVME_REG_ACQ);
 
-	result = nvme_enable_ctrl(dev, cap);
+	result = nvme_enable_ctrl(&dev->ctrl, cap);
 	if (result)
 		goto free_nvmeq;
 
@@ -1802,639 +1366,157 @@ static int nvme_configure_admin_queue(st
 	return result;
 }
 
-static int nvme_submit_io(struct nvme_ns *ns, struct nvme_user_io __user *uio)
+static bool nvme_should_reset(struct nvme_dev *dev, u32 csts)
 {
-	struct nvme_dev *dev = ns->dev;
-	struct nvme_user_io io;
-	struct nvme_command c;
-	unsigned length, meta_len;
-	int status, write;
-	dma_addr_t meta_dma = 0;
-	void *meta = NULL;
-	void __user *metadata;
-
-	if (copy_from_user(&io, uio, sizeof(io)))
-		return -EFAULT;
-
-	switch (io.opcode) {
-	case nvme_cmd_write:
-	case nvme_cmd_read:
-	case nvme_cmd_compare:
-		break;
-	default:
-		return -EINVAL;
-	}
-
-	length = (io.nblocks + 1) << ns->lba_shift;
-	meta_len = (io.nblocks + 1) * ns->ms;
-	metadata = (void __user *)(uintptr_t)io.metadata;
-	write = io.opcode & 1;
 
-	if (ns->ext) {
-		length += meta_len;
-		meta_len = 0;
-	}
-	if (meta_len) {
-		if (((io.metadata & 3) || !io.metadata) && !ns->ext)
-			return -EINVAL;
+	/* If true, indicates loss of adapter communication, possibly by a
+	 * NVMe Subsystem reset.
+	 */
+	bool nssro = dev->subsystem && (csts & NVME_CSTS_NSSRO);
 
-		meta = dma_alloc_coherent(dev->dev, meta_len,
-						&meta_dma, GFP_KERNEL);
+	/* If there is a reset ongoing, we shouldn't reset again. */
+	if (work_busy(&dev->reset_work))
+		return false;
 
-		if (!meta) {
-			status = -ENOMEM;
-			goto unmap;
-		}
-		if (write) {
-			if (copy_from_user(meta, metadata, meta_len)) {
-				status = -EFAULT;
-				goto unmap;
-			}
-		}
-	}
+	/* We shouldn't reset unless the controller is on fatal error state
+	 * _or_ if we lost the communication with it.
+	 */
+	if (!(csts & NVME_CSTS_CFS) && !nssro)
+		return false;
 
-	memset(&c, 0, sizeof(c));
-	c.rw.opcode = io.opcode;
-	c.rw.flags = io.flags;
-	c.rw.nsid = cpu_to_le32(ns->ns_id);
-	c.rw.slba = cpu_to_le64(io.slba);
-	c.rw.length = cpu_to_le16(io.nblocks);
-	c.rw.control = cpu_to_le16(io.control);
-	c.rw.dsmgmt = cpu_to_le32(io.dsmgmt);
-	c.rw.reftag = cpu_to_le32(io.reftag);
-	c.rw.apptag = cpu_to_le16(io.apptag);
-	c.rw.appmask = cpu_to_le16(io.appmask);
-	c.rw.metadata = cpu_to_le64(meta_dma);
+	/* If PCI error recovery process is happening, we cannot reset or
+	 * the recovery mechanism will surely fail.
+	 */
+	if (pci_channel_offline(to_pci_dev(dev->dev)))
+		return false;
 
-	status = __nvme_submit_sync_cmd(ns->queue, &c, NULL,
-			(void __user *)(uintptr_t)io.addr, length, NULL, 0);
- unmap:
-	if (meta) {
-		if (status == NVME_SC_SUCCESS && !write) {
-			if (copy_to_user(metadata, meta, meta_len))
-				status = -EFAULT;
-		}
-		dma_free_coherent(dev->dev, meta_len, meta, meta_dma);
-	}
-	return status;
+	return true;
 }
 
-static int nvme_user_cmd(struct nvme_dev *dev, struct nvme_ns *ns,
-			struct nvme_passthru_cmd __user *ucmd)
+static void nvme_watchdog_timer(unsigned long data)
 {
-	struct nvme_passthru_cmd cmd;
-	struct nvme_command c;
-	unsigned timeout = 0;
-	int status;
+	struct nvme_dev *dev = (struct nvme_dev *)data;
+	u32 csts = readl(dev->bar + NVME_REG_CSTS);
 
-	if (!capable(CAP_SYS_ADMIN))
-		return -EACCES;
-	if (copy_from_user(&cmd, ucmd, sizeof(cmd)))
-		return -EFAULT;
+	/* Skip controllers under certain specific conditions. */
+	if (nvme_should_reset(dev, csts)) {
+		if (queue_work(nvme_workq, &dev->reset_work))
+			dev_warn(dev->dev,
+				"Failed status: 0x%x, reset controller.\n",
+				csts);
+		return;
+	}
 
-	memset(&c, 0, sizeof(c));
-	c.common.opcode = cmd.opcode;
-	c.common.flags = cmd.flags;
-	c.common.nsid = cpu_to_le32(cmd.nsid);
-	c.common.cdw2[0] = cpu_to_le32(cmd.cdw2);
-	c.common.cdw2[1] = cpu_to_le32(cmd.cdw3);
-	c.common.cdw10[0] = cpu_to_le32(cmd.cdw10);
-	c.common.cdw10[1] = cpu_to_le32(cmd.cdw11);
-	c.common.cdw10[2] = cpu_to_le32(cmd.cdw12);
-	c.common.cdw10[3] = cpu_to_le32(cmd.cdw13);
-	c.common.cdw10[4] = cpu_to_le32(cmd.cdw14);
-	c.common.cdw10[5] = cpu_to_le32(cmd.cdw15);
-
-	if (cmd.timeout_ms)
-		timeout = msecs_to_jiffies(cmd.timeout_ms);
-
-	status = __nvme_submit_sync_cmd(ns ? ns->queue : dev->admin_q, &c,
-			NULL, (void __user *)(uintptr_t)cmd.addr, cmd.data_len,
-			&cmd.result, timeout);
-	if (status >= 0) {
-		if (put_user(cmd.result, &ucmd->result))
-			return -EFAULT;
-	}
-
-	return status;
-}
-
-static int nvme_subsys_reset(struct nvme_dev *dev)
-{
-	if (!dev->subsystem)
-		return -ENOTTY;
-
-	writel(0x4E564D65, &dev->bar->nssr); /* "NVMe" */
-	return 0;
+	mod_timer(&dev->watchdog_timer, round_jiffies(jiffies + HZ));
 }
 
-static int nvme_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd,
-							unsigned long arg)
-{
-	struct nvme_ns *ns = bdev->bd_disk->private_data;
-
-	switch (cmd) {
-	case NVME_IOCTL_ID:
-		force_successful_syscall_return();
-		return ns->ns_id;
-	case NVME_IOCTL_ADMIN_CMD:
-		return nvme_user_cmd(ns->dev, NULL, (void __user *)arg);
-	case NVME_IOCTL_IO_CMD:
-		return nvme_user_cmd(ns->dev, ns, (void __user *)arg);
-	case NVME_IOCTL_SUBMIT_IO:
-		return nvme_submit_io(ns, (void __user *)arg);
-	case SG_GET_VERSION_NUM:
-		return nvme_sg_get_version_num((void __user *)arg);
-	case SG_IO:
-		return nvme_sg_io(ns, (void __user *)arg);
-	default:
-		return -ENOTTY;
+static int nvme_create_io_queues(struct nvme_dev *dev)
+{
+	unsigned i;
+	int ret = 0;
+
+	for (i = dev->queue_count; i <= dev->max_qid; i++) {
+		if (!nvme_alloc_queue(dev, i, dev->q_depth)) {
+			ret = -ENOMEM;
+			break;
+		}
 	}
-}
 
-#ifdef CONFIG_COMPAT
-static int nvme_compat_ioctl(struct block_device *bdev, fmode_t mode,
-					unsigned int cmd, unsigned long arg)
-{
-	switch (cmd) {
-	case SG_IO:
-		return -ENOIOCTLCMD;
+	for (i = dev->online_queues; i <= dev->queue_count - 1; i++) {
+		ret = nvme_create_queue(dev->queues[i], i);
+		if (ret) {
+			nvme_free_queues(dev, i);
+			break;
+		}
 	}
-	return nvme_ioctl(bdev, mode, cmd, arg);
+
+	/*
+	 * Ignore failing Create SQ/CQ commands, we can continue with less
+	 * than the desired aount of queues, and even a controller without
+	 * I/O queues an still be used to issue admin commands.  This might
+	 * be useful to upgrade a buggy firmware for example.
+	 */
+	return ret >= 0 ? 0 : ret;
 }
-#else
-#define nvme_compat_ioctl	NULL
-#endif
 
-static void nvme_free_dev(struct kref *kref);
-static void nvme_free_ns(struct kref *kref)
+static void __iomem *nvme_map_cmb(struct nvme_dev *dev)
 {
-	struct nvme_ns *ns = container_of(kref, struct nvme_ns, kref);
+	u64 szu, size, offset;
+	u32 cmbloc;
+	resource_size_t bar_size;
+	struct pci_dev *pdev = to_pci_dev(dev->dev);
+	void __iomem *cmb;
+	dma_addr_t dma_addr;
 
-	if (ns->type == NVME_NS_LIGHTNVM)
-		nvme_nvm_unregister(ns->queue, ns->disk->disk_name);
+	if (!use_cmb_sqes)
+		return NULL;
 
-	spin_lock(&dev_list_lock);
-	ns->disk->private_data = NULL;
-	spin_unlock(&dev_list_lock);
+	dev->cmbsz = readl(dev->bar + NVME_REG_CMBSZ);
+	if (!(NVME_CMB_SZ(dev->cmbsz)))
+		return NULL;
 
-	kref_put(&ns->dev->kref, nvme_free_dev);
-	put_disk(ns->disk);
-	kfree(ns);
-}
+	cmbloc = readl(dev->bar + NVME_REG_CMBLOC);
 
-static int nvme_open(struct block_device *bdev, fmode_t mode)
-{
-	int ret = 0;
-	struct nvme_ns *ns;
+	szu = (u64)1 << (12 + 4 * NVME_CMB_SZU(dev->cmbsz));
+	size = szu * NVME_CMB_SZ(dev->cmbsz);
+	offset = szu * NVME_CMB_OFST(cmbloc);
+	bar_size = pci_resource_len(pdev, NVME_CMB_BIR(cmbloc));
+
+	if (offset > bar_size)
+		return NULL;
 
-	spin_lock(&dev_list_lock);
-	ns = bdev->bd_disk->private_data;
-	if (!ns)
-		ret = -ENXIO;
-	else if (!kref_get_unless_zero(&ns->kref))
-		ret = -ENXIO;
-	spin_unlock(&dev_list_lock);
+	/*
+	 * Controllers may support a CMB size larger than their BAR,
+	 * for example, due to being behind a bridge. Reduce the CMB to
+	 * the reported size of the BAR
+	 */
+	if (size > bar_size - offset)
+		size = bar_size - offset;
 
-	return ret;
-}
+	dma_addr = pci_resource_start(pdev, NVME_CMB_BIR(cmbloc)) + offset;
+	cmb = ioremap_wc(dma_addr, size);
+	if (!cmb)
+		return NULL;
 
-static void nvme_release(struct gendisk *disk, fmode_t mode)
-{
-	struct nvme_ns *ns = disk->private_data;
-	kref_put(&ns->kref, nvme_free_ns);
+	dev->cmb_dma_addr = dma_addr;
+	dev->cmb_size = size;
+	return cmb;
 }
 
-static int nvme_getgeo(struct block_device *bd, struct hd_geometry *geo)
+static inline void nvme_release_cmb(struct nvme_dev *dev)
 {
-	/* some standard values */
-	geo->heads = 1 << 6;
-	geo->sectors = 1 << 5;
-	geo->cylinders = get_capacity(bd->bd_disk) >> 11;
-	return 0;
+	if (dev->cmb) {
+		iounmap(dev->cmb);
+		dev->cmb = NULL;
+	}
 }
 
-static void nvme_config_discard(struct nvme_ns *ns)
+static size_t db_bar_size(struct nvme_dev *dev, unsigned nr_io_queues)
 {
-	u32 logical_block_size = queue_logical_block_size(ns->queue);
-	ns->queue->limits.discard_zeroes_data = 0;
-	ns->queue->limits.discard_alignment = logical_block_size;
-	ns->queue->limits.discard_granularity = logical_block_size;
-	blk_queue_max_discard_sectors(ns->queue, 0xffffffff);
-	queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, ns->queue);
+	return 4096 + ((nr_io_queues + 1) * 8 * dev->db_stride);
 }
 
-static int nvme_revalidate_disk(struct gendisk *disk)
+static int nvme_setup_io_queues(struct nvme_dev *dev)
 {
-	struct nvme_ns *ns = disk->private_data;
-	struct nvme_dev *dev = ns->dev;
-	struct nvme_id_ns *id;
-	u8 lbaf, pi_type;
-	u16 old_ms;
-	unsigned short bs;
+	struct nvme_queue *adminq = dev->queues[0];
+	struct pci_dev *pdev = to_pci_dev(dev->dev);
+	int result, i, vecs, nr_io_queues, size;
 
-	if (nvme_identify_ns(dev, ns->ns_id, &id)) {
-		dev_warn(dev->dev, "%s: Identify failure nvme%dn%d\n", __func__,
-						dev->instance, ns->ns_id);
-		return -ENODEV;
-	}
-	if (id->ncap == 0) {
-		kfree(id);
-		return -ENODEV;
-	}
-
-	if (nvme_nvm_ns_supported(ns, id) && ns->type != NVME_NS_LIGHTNVM) {
-		if (nvme_nvm_register(ns->queue, disk->disk_name)) {
-			dev_warn(dev->dev,
-				"%s: LightNVM init failure\n", __func__);
-			kfree(id);
-			return -ENODEV;
-		}
-		ns->type = NVME_NS_LIGHTNVM;
-	}
-
-	old_ms = ns->ms;
-	lbaf = id->flbas & NVME_NS_FLBAS_LBA_MASK;
-	ns->lba_shift = id->lbaf[lbaf].ds;
-	ns->ms = le16_to_cpu(id->lbaf[lbaf].ms);
-	ns->ext = ns->ms && (id->flbas & NVME_NS_FLBAS_META_EXT);
+	nr_io_queues = num_possible_cpus();
+	result = nvme_set_queue_count(&dev->ctrl, &nr_io_queues);
+	if (result < 0)
+		return result;
 
 	/*
-	 * If identify namespace failed, use default 512 byte block size so
-	 * block layer can use before failing read/write for 0 capacity.
+	 * Degraded controllers might return an error when setting the queue
+	 * count.  We still want to be able to bring them online and offer
+	 * access to the admin queue, as that might be only way to fix them up.
 	 */
-	if (ns->lba_shift == 0)
-		ns->lba_shift = 9;
-	bs = 1 << ns->lba_shift;
-
-	/* XXX: PI implementation requires metadata equal t10 pi tuple size */
-	pi_type = ns->ms == sizeof(struct t10_pi_tuple) ?
-					id->dps & NVME_NS_DPS_PI_MASK : 0;
-
-	blk_mq_freeze_queue(disk->queue);
-	if (blk_get_integrity(disk) && (ns->pi_type != pi_type ||
-				ns->ms != old_ms ||
-				bs != queue_logical_block_size(disk->queue) ||
-				(ns->ms && ns->ext)))
-		blk_integrity_unregister(disk);
-
-	ns->pi_type = pi_type;
-	blk_queue_logical_block_size(ns->queue, bs);
-
-	if (ns->ms && !ns->ext)
-		nvme_init_integrity(ns);
-
-	if ((ns->ms && !(ns->ms == 8 && ns->pi_type) &&
-						!blk_get_integrity(disk)) ||
-						ns->type == NVME_NS_LIGHTNVM)
-		set_capacity(disk, 0);
-	else
-		set_capacity(disk, le64_to_cpup(&id->nsze) << (ns->lba_shift - 9));
-
-	if (dev->oncs & NVME_CTRL_ONCS_DSM)
-		nvme_config_discard(ns);
-	blk_mq_unfreeze_queue(disk->queue);
-
-	kfree(id);
-	return 0;
-}
-
-static char nvme_pr_type(enum pr_type type)
-{
-	switch (type) {
-	case PR_WRITE_EXCLUSIVE:
-		return 1;
-	case PR_EXCLUSIVE_ACCESS:
-		return 2;
-	case PR_WRITE_EXCLUSIVE_REG_ONLY:
-		return 3;
-	case PR_EXCLUSIVE_ACCESS_REG_ONLY:
-		return 4;
-	case PR_WRITE_EXCLUSIVE_ALL_REGS:
-		return 5;
-	case PR_EXCLUSIVE_ACCESS_ALL_REGS:
-		return 6;
-	default:
+	if (result > 0) {
+		dev_err(dev->ctrl.device,
+			"Could not set queue count (%d)\n", result);
 		return 0;
 	}
-};
-
-static int nvme_pr_command(struct block_device *bdev, u32 cdw10,
-				u64 key, u64 sa_key, u8 op)
-{
-	struct nvme_ns *ns = bdev->bd_disk->private_data;
-	struct nvme_command c;
-	u8 data[16] = { 0, };
-
-	put_unaligned_le64(key, &data[0]);
-	put_unaligned_le64(sa_key, &data[8]);
-
-	memset(&c, 0, sizeof(c));
-	c.common.opcode = op;
-	c.common.nsid = cpu_to_le32(ns->ns_id);
-	c.common.cdw10[0] = cpu_to_le32(cdw10);
-
-	return nvme_submit_sync_cmd(ns->queue, &c, data, 16);
-}
-
-static int nvme_pr_register(struct block_device *bdev, u64 old,
-		u64 new, unsigned flags)
-{
-	u32 cdw10;
-
-	if (flags & ~PR_FL_IGNORE_KEY)
-		return -EOPNOTSUPP;
-
-	cdw10 = old ? 2 : 0;
-	cdw10 |= (flags & PR_FL_IGNORE_KEY) ? 1 << 3 : 0;
-	cdw10 |= (1 << 30) | (1 << 31); /* PTPL=1 */
-	return nvme_pr_command(bdev, cdw10, old, new, nvme_cmd_resv_register);
-}
-
-static int nvme_pr_reserve(struct block_device *bdev, u64 key,
-		enum pr_type type, unsigned flags)
-{
-	u32 cdw10;
-
-	if (flags & ~PR_FL_IGNORE_KEY)
-		return -EOPNOTSUPP;
-
-	cdw10 = nvme_pr_type(type) << 8;
-	cdw10 |= ((flags & PR_FL_IGNORE_KEY) ? 1 << 3 : 0);
-	return nvme_pr_command(bdev, cdw10, key, 0, nvme_cmd_resv_acquire);
-}
-
-static int nvme_pr_preempt(struct block_device *bdev, u64 old, u64 new,
-		enum pr_type type, bool abort)
-{
-	u32 cdw10 = nvme_pr_type(type) << 8 | abort ? 2 : 1;
-	return nvme_pr_command(bdev, cdw10, old, new, nvme_cmd_resv_acquire);
-}
-
-static int nvme_pr_clear(struct block_device *bdev, u64 key)
-{
-	u32 cdw10 = 1 | (key ? 1 << 3 : 0);
-	return nvme_pr_command(bdev, cdw10, key, 0, nvme_cmd_resv_register);
-}
-
-static int nvme_pr_release(struct block_device *bdev, u64 key, enum pr_type type)
-{
-	u32 cdw10 = nvme_pr_type(type) << 8 | key ? 1 << 3 : 0;
-	return nvme_pr_command(bdev, cdw10, key, 0, nvme_cmd_resv_release);
-}
-
-static const struct pr_ops nvme_pr_ops = {
-	.pr_register	= nvme_pr_register,
-	.pr_reserve	= nvme_pr_reserve,
-	.pr_release	= nvme_pr_release,
-	.pr_preempt	= nvme_pr_preempt,
-	.pr_clear	= nvme_pr_clear,
-};
-
-static const struct block_device_operations nvme_fops = {
-	.owner		= THIS_MODULE,
-	.ioctl		= nvme_ioctl,
-	.compat_ioctl	= nvme_compat_ioctl,
-	.open		= nvme_open,
-	.release	= nvme_release,
-	.getgeo		= nvme_getgeo,
-	.revalidate_disk= nvme_revalidate_disk,
-	.pr_ops		= &nvme_pr_ops,
-};
-
-static int nvme_kthread(void *data)
-{
-	struct nvme_dev *dev, *next;
-
-	while (!kthread_should_stop()) {
-		set_current_state(TASK_INTERRUPTIBLE);
-		spin_lock(&dev_list_lock);
-		list_for_each_entry_safe(dev, next, &dev_list, node) {
-			int i;
-			u32 csts = readl(&dev->bar->csts);
-
-			if ((dev->subsystem && (csts & NVME_CSTS_NSSRO)) ||
-							csts & NVME_CSTS_CFS) {
-				if (!__nvme_reset(dev)) {
-					dev_warn(dev->dev,
-						"Failed status: %x, reset controller\n",
-						readl(&dev->bar->csts));
-				}
-				continue;
-			}
-			for (i = 0; i < dev->queue_count; i++) {
-				struct nvme_queue *nvmeq = dev->queues[i];
-				if (!nvmeq)
-					continue;
-				spin_lock_irq(&nvmeq->q_lock);
-				nvme_process_cq(nvmeq);
-
-				while ((i == 0) && (dev->event_limit > 0)) {
-					if (nvme_submit_async_admin_req(dev))
-						break;
-					dev->event_limit--;
-				}
-				spin_unlock_irq(&nvmeq->q_lock);
-			}
-		}
-		spin_unlock(&dev_list_lock);
-		schedule_timeout(round_jiffies_relative(HZ));
-	}
-	return 0;
-}
-
-static void nvme_alloc_ns(struct nvme_dev *dev, unsigned nsid)
-{
-	struct nvme_ns *ns;
-	struct gendisk *disk;
-	int node = dev_to_node(dev->dev);
-
-	ns = kzalloc_node(sizeof(*ns), GFP_KERNEL, node);
-	if (!ns)
-		return;
-
-	ns->queue = blk_mq_init_queue(&dev->tagset);
-	if (IS_ERR(ns->queue))
-		goto out_free_ns;
-	queue_flag_set_unlocked(QUEUE_FLAG_NOMERGES, ns->queue);
-	queue_flag_set_unlocked(QUEUE_FLAG_NONROT, ns->queue);
-	ns->dev = dev;
-	ns->queue->queuedata = ns;
-
-	disk = alloc_disk_node(0, node);
-	if (!disk)
-		goto out_free_queue;
-
-	kref_init(&ns->kref);
-	ns->ns_id = nsid;
-	ns->disk = disk;
-	ns->lba_shift = 9; /* set to a default value for 512 until disk is validated */
-	list_add_tail(&ns->list, &dev->namespaces);
-
-	blk_queue_logical_block_size(ns->queue, 1 << ns->lba_shift);
-	if (dev->max_hw_sectors) {
-		blk_queue_max_hw_sectors(ns->queue, dev->max_hw_sectors);
-		blk_queue_max_segments(ns->queue,
-			(dev->max_hw_sectors / (dev->page_size >> 9)) + 1);
-	}
-	if (dev->stripe_size)
-		blk_queue_chunk_sectors(ns->queue, dev->stripe_size >> 9);
-	if (dev->vwc & NVME_CTRL_VWC_PRESENT)
-		blk_queue_flush(ns->queue, REQ_FLUSH | REQ_FUA);
-	blk_queue_virt_boundary(ns->queue, dev->page_size - 1);
-
-	disk->major = nvme_major;
-	disk->first_minor = 0;
-	disk->fops = &nvme_fops;
-	disk->private_data = ns;
-	disk->queue = ns->queue;
-	disk->driverfs_dev = dev->device;
-	disk->flags = GENHD_FL_EXT_DEVT;
-	sprintf(disk->disk_name, "nvme%dn%d", dev->instance, nsid);
-
-	/*
-	 * Initialize capacity to 0 until we establish the namespace format and
-	 * setup integrity extentions if necessary. The revalidate_disk after
-	 * add_disk allows the driver to register with integrity if the format
-	 * requires it.
-	 */
-	set_capacity(disk, 0);
-	if (nvme_revalidate_disk(ns->disk))
-		goto out_free_disk;
-
-	kref_get(&dev->kref);
-	if (ns->type != NVME_NS_LIGHTNVM) {
-		add_disk(ns->disk);
-		if (ns->ms) {
-			struct block_device *bd = bdget_disk(ns->disk, 0);
-			if (!bd)
-				return;
-			if (blkdev_get(bd, FMODE_READ, NULL)) {
-				bdput(bd);
-				return;
-			}
-			blkdev_reread_part(bd);
-			blkdev_put(bd, FMODE_READ);
-		}
-	}
-	return;
- out_free_disk:
-	kfree(disk);
-	list_del(&ns->list);
- out_free_queue:
-	blk_cleanup_queue(ns->queue);
- out_free_ns:
-	kfree(ns);
-}
-
-/*
- * Create I/O queues.  Failing to create an I/O queue is not an issue,
- * we can continue with less than the desired amount of queues, and
- * even a controller without I/O queues an still be used to issue
- * admin commands.  This might be useful to upgrade a buggy firmware
- * for example.
- */
-static void nvme_create_io_queues(struct nvme_dev *dev)
-{
-	unsigned i;
-
-	for (i = dev->queue_count; i <= dev->max_qid; i++)
-		if (!nvme_alloc_queue(dev, i, dev->q_depth))
-			break;
-
-	for (i = dev->online_queues; i <= dev->queue_count - 1; i++)
-		if (nvme_create_queue(dev->queues[i], i)) {
-			nvme_free_queues(dev, i);
-			break;
-		}
-}
-
-static int set_queue_count(struct nvme_dev *dev, int count)
-{
-	int status;
-	u32 result;
-	u32 q_count = (count - 1) | ((count - 1) << 16);
-
-	status = nvme_set_features(dev, NVME_FEAT_NUM_QUEUES, q_count, 0,
-								&result);
-	if (status < 0)
-		return status;
-	if (status > 0) {
-		dev_err(dev->dev, "Could not set queue count (%d)\n", status);
-		return 0;
-	}
-	return min(result & 0xffff, result >> 16) + 1;
-}
-
-static void __iomem *nvme_map_cmb(struct nvme_dev *dev)
-{
-	u64 szu, size, offset;
-	u32 cmbloc;
-	resource_size_t bar_size;
-	struct pci_dev *pdev = to_pci_dev(dev->dev);
-	void __iomem *cmb;
-	dma_addr_t dma_addr;
-
-	if (!use_cmb_sqes)
-		return NULL;
-
-	dev->cmbsz = readl(&dev->bar->cmbsz);
-	if (!(NVME_CMB_SZ(dev->cmbsz)))
-		return NULL;
-
-	cmbloc = readl(&dev->bar->cmbloc);
-
-	szu = (u64)1 << (12 + 4 * NVME_CMB_SZU(dev->cmbsz));
-	size = szu * NVME_CMB_SZ(dev->cmbsz);
-	offset = szu * NVME_CMB_OFST(cmbloc);
-	bar_size = pci_resource_len(pdev, NVME_CMB_BIR(cmbloc));
-
-	if (offset > bar_size)
-		return NULL;
-
-	/*
-	 * Controllers may support a CMB size larger than their BAR,
-	 * for example, due to being behind a bridge. Reduce the CMB to
-	 * the reported size of the BAR
-	 */
-	if (size > bar_size - offset)
-		size = bar_size - offset;
-
-	dma_addr = pci_resource_start(pdev, NVME_CMB_BIR(cmbloc)) + offset;
-	cmb = ioremap_wc(dma_addr, size);
-	if (!cmb)
-		return NULL;
-
-	dev->cmb_dma_addr = dma_addr;
-	dev->cmb_size = size;
-	return cmb;
-}
-
-static inline void nvme_release_cmb(struct nvme_dev *dev)
-{
-	if (dev->cmb) {
-		iounmap(dev->cmb);
-		dev->cmb = NULL;
-	}
-}
-
-static size_t db_bar_size(struct nvme_dev *dev, unsigned nr_io_queues)
-{
-	return 4096 + ((nr_io_queues + 1) * 8 * dev->db_stride);
-}
-
-static int nvme_setup_io_queues(struct nvme_dev *dev)
-{
-	struct nvme_queue *adminq = dev->queues[0];
-	struct pci_dev *pdev = to_pci_dev(dev->dev);
-	int result, i, vecs, nr_io_queues, size;
-
-	nr_io_queues = num_possible_cpus();
-	result = set_queue_count(dev, nr_io_queues);
-	if (result <= 0)
-		return result;
-	if (result < nr_io_queues)
-		nr_io_queues = result;
 
 	if (dev->cmb && NVME_CMB_SQS(dev->cmbsz)) {
 		result = nvme_cmb_qdepth(dev, nr_io_queues,
@@ -2456,7 +1538,7 @@ static int nvme_setup_io_queues(struct n
 				return -ENOMEM;
 			size = db_bar_size(dev, nr_io_queues);
 		} while (1);
-		dev->dbs = ((void __iomem *)dev->bar) + 4096;
+		dev->dbs = dev->bar + 4096;
 		adminq->q_db = dev->dbs;
 	}
 
@@ -2467,7 +1549,9 @@ static int nvme_setup_io_queues(struct n
 	 * If we enable msix early due to not intx, disable it again before
 	 * setting up the full range we need.
 	 */
-	if (!pdev->irq)
+	if (pdev->msi_enabled)
+		pci_disable_msi(pdev);
+	else if (pdev->msix_enabled)
 		pci_disable_msix(pdev);
 
 	for (i = 0; i < nr_io_queues; i++)
@@ -2500,115 +1584,110 @@ static int nvme_setup_io_queues(struct n
 
 	/* Free previously allocated queues that are no longer usable */
 	nvme_free_queues(dev, nr_io_queues + 1);
-	nvme_create_io_queues(dev);
-
-	return 0;
+	return nvme_create_io_queues(dev);
 
  free_queues:
 	nvme_free_queues(dev, 1);
 	return result;
 }
 
-static int ns_cmp(void *priv, struct list_head *a, struct list_head *b)
+static void nvme_set_irq_hints(struct nvme_dev *dev)
 {
-	struct nvme_ns *nsa = container_of(a, struct nvme_ns, list);
-	struct nvme_ns *nsb = container_of(b, struct nvme_ns, list);
+	struct nvme_queue *nvmeq;
+	int i;
 
-	return nsa->ns_id - nsb->ns_id;
-}
+	for (i = 0; i < dev->online_queues; i++) {
+		nvmeq = dev->queues[i];
 
-static struct nvme_ns *nvme_find_ns(struct nvme_dev *dev, unsigned nsid)
-{
-	struct nvme_ns *ns;
+		if (!nvmeq->tags || !(*nvmeq->tags))
+			continue;
 
-	list_for_each_entry(ns, &dev->namespaces, list) {
-		if (ns->ns_id == nsid)
-			return ns;
-		if (ns->ns_id > nsid)
-			break;
+		irq_set_affinity_hint(dev->entry[nvmeq->cq_vector].vector,
+					blk_mq_tags_cpumask(*nvmeq->tags));
 	}
-	return NULL;
 }
 
-static inline bool nvme_io_incapable(struct nvme_dev *dev)
+static void nvme_dev_scan(struct work_struct *work)
 {
-	return (!dev->bar || readl(&dev->bar->csts) & NVME_CSTS_CFS ||
-							dev->online_queues < 2);
+	struct nvme_dev *dev = container_of(work, struct nvme_dev, scan_work);
+
+	if (!dev->tagset.tags)
+		return;
+	nvme_scan_namespaces(&dev->ctrl);
+	nvme_set_irq_hints(dev);
 }
 
-static void nvme_ns_remove(struct nvme_ns *ns)
+static void nvme_del_queue_end(struct request *req, int error)
 {
-	bool kill = nvme_io_incapable(ns->dev) && !blk_queue_dying(ns->queue);
+	struct nvme_queue *nvmeq = req->end_io_data;
 
-	if (kill) {
-		blk_set_queue_dying(ns->queue);
-
-		/*
-		 * The controller was shutdown first if we got here through
-		 * device removal. The shutdown may requeue outstanding
-		 * requests. These need to be aborted immediately so
-		 * del_gendisk doesn't block indefinitely for their completion.
-		 */
-		blk_mq_abort_requeue_list(ns->queue);
-	}
-	if (ns->disk->flags & GENHD_FL_UP)
-		del_gendisk(ns->disk);
-	if (kill || !blk_queue_dying(ns->queue)) {
-		blk_mq_abort_requeue_list(ns->queue);
-		blk_cleanup_queue(ns->queue);
-	}
-	list_del_init(&ns->list);
-	kref_put(&ns->kref, nvme_free_ns);
+	blk_mq_free_request(req);
+	complete(&nvmeq->dev->ioq_wait);
 }
 
-static void nvme_scan_namespaces(struct nvme_dev *dev, unsigned nn)
+static void nvme_del_cq_end(struct request *req, int error)
 {
-	struct nvme_ns *ns, *next;
-	unsigned i;
+	struct nvme_queue *nvmeq = req->end_io_data;
+
+	if (!error) {
+		unsigned long flags;
 
-	for (i = 1; i <= nn; i++) {
-		ns = nvme_find_ns(dev, i);
-		if (ns) {
-			if (revalidate_disk(ns->disk))
-				nvme_ns_remove(ns);
-		} else
-			nvme_alloc_ns(dev, i);
-	}
-	list_for_each_entry_safe(ns, next, &dev->namespaces, list) {
-		if (ns->ns_id > nn)
-			nvme_ns_remove(ns);
+		spin_lock_irqsave(&nvmeq->q_lock, flags);
+		nvme_process_cq(nvmeq);
+		spin_unlock_irqrestore(&nvmeq->q_lock, flags);
 	}
-	list_sort(NULL, &dev->namespaces, ns_cmp);
+
+	nvme_del_queue_end(req, error);
 }
 
-static void nvme_set_irq_hints(struct nvme_dev *dev)
+static int nvme_delete_queue(struct nvme_queue *nvmeq, u8 opcode)
 {
-	struct nvme_queue *nvmeq;
-	int i;
+	struct request_queue *q = nvmeq->dev->ctrl.admin_q;
+	struct request *req;
+	struct nvme_command cmd;
 
-	for (i = 0; i < dev->online_queues; i++) {
-		nvmeq = dev->queues[i];
+	memset(&cmd, 0, sizeof(cmd));
+	cmd.delete_queue.opcode = opcode;
+	cmd.delete_queue.qid = cpu_to_le16(nvmeq->qid);
 
-		if (!nvmeq->tags || !(*nvmeq->tags))
-			continue;
+	req = nvme_alloc_request(q, &cmd, BLK_MQ_REQ_NOWAIT);
+	if (IS_ERR(req))
+		return PTR_ERR(req);
 
-		irq_set_affinity_hint(dev->entry[nvmeq->cq_vector].vector,
-					blk_mq_tags_cpumask(*nvmeq->tags));
-	}
+	req->timeout = ADMIN_TIMEOUT;
+	req->end_io_data = nvmeq;
+
+	blk_execute_rq_nowait(q, NULL, req, false,
+			opcode == nvme_admin_delete_cq ?
+				nvme_del_cq_end : nvme_del_queue_end);
+	return 0;
 }
 
-static void nvme_dev_scan(struct work_struct *work)
+static void nvme_disable_io_queues(struct nvme_dev *dev)
 {
-	struct nvme_dev *dev = container_of(work, struct nvme_dev, scan_work);
-	struct nvme_id_ctrl *ctrl;
+	int pass;
+	unsigned long timeout;
+	u8 opcode = nvme_admin_delete_sq;
 
-	if (!dev->tagset.tags)
-		return;
-	if (nvme_identify_ctrl(dev, &ctrl))
-		return;
-	nvme_scan_namespaces(dev, le32_to_cpup(&ctrl->nn));
-	kfree(ctrl);
-	nvme_set_irq_hints(dev);
+	for (pass = 0; pass < 2; pass++) {
+		int sent = 0, i = dev->queue_count - 1;
+
+		reinit_completion(&dev->ioq_wait);
+ retry:
+		timeout = ADMIN_TIMEOUT;
+		for (; i > 0; i--, sent++)
+			if (nvme_delete_queue(dev->queues[i], opcode))
+				break;
+
+		while (sent--) {
+			timeout = wait_for_completion_io_timeout(&dev->ioq_wait, timeout);
+			if (timeout == 0)
+				return;
+			if (i)
+				goto retry;
+		}
+		opcode = nvme_admin_delete_cq;
+	}
 }
 
 /*
@@ -2619,42 +1698,7 @@ static void nvme_dev_scan(struct work_st
  */
 static int nvme_dev_add(struct nvme_dev *dev)
 {
-	struct pci_dev *pdev = to_pci_dev(dev->dev);
-	int res;
-	struct nvme_id_ctrl *ctrl;
-	int shift = NVME_CAP_MPSMIN(lo_hi_readq(&dev->bar->cap)) + 12;
-
-	res = nvme_identify_ctrl(dev, &ctrl);
-	if (res) {
-		dev_err(dev->dev, "Identify Controller failed (%d)\n", res);
-		return -EIO;
-	}
-
-	dev->oncs = le16_to_cpup(&ctrl->oncs);
-	dev->abort_limit = ctrl->acl + 1;
-	dev->vwc = ctrl->vwc;
-	memcpy(dev->serial, ctrl->sn, sizeof(ctrl->sn));
-	memcpy(dev->model, ctrl->mn, sizeof(ctrl->mn));
-	memcpy(dev->firmware_rev, ctrl->fr, sizeof(ctrl->fr));
-	if (ctrl->mdts)
-		dev->max_hw_sectors = 1 << (ctrl->mdts + shift - 9);
-	else
-		dev->max_hw_sectors = UINT_MAX;
-	if ((pdev->vendor == PCI_VENDOR_ID_INTEL) &&
-			(pdev->device == 0x0953) && ctrl->vs[3]) {
-		unsigned int max_hw_sectors;
-
-		dev->stripe_size = 1 << (ctrl->vs[3] + shift);
-		max_hw_sectors = dev->stripe_size >> (shift - 9);
-		if (dev->max_hw_sectors) {
-			dev->max_hw_sectors = min(max_hw_sectors,
-							dev->max_hw_sectors);
-		} else
-			dev->max_hw_sectors = max_hw_sectors;
-	}
-	kfree(ctrl);
-
-	if (!dev->tagset.tags) {
+	if (!dev->ctrl.tagset) {
 		dev->tagset.ops = &nvme_mq_ops;
 		dev->tagset.nr_hw_queues = dev->online_queues - 1;
 		dev->tagset.timeout = NVME_IO_TIMEOUT;
@@ -2667,15 +1711,16 @@ static int nvme_dev_add(struct nvme_dev
 
 		if (blk_mq_alloc_tag_set(&dev->tagset))
 			return 0;
+		dev->ctrl.tagset = &dev->tagset;
 	}
-	schedule_work(&dev->scan_work);
+	nvme_queue_scan(dev);
 	return 0;
 }
 
-static int nvme_dev_map(struct nvme_dev *dev)
+static int nvme_pci_enable(struct nvme_dev *dev)
 {
 	u64 cap;
-	int bars, result = -ENOMEM;
+	int result = -ENOMEM;
 	struct pci_dev *pdev = to_pci_dev(dev->dev);
 
 	if (pci_enable_device_mem(pdev))
@@ -2683,24 +1728,14 @@ static int nvme_dev_map(struct nvme_dev
 
 	dev->entry[0].vector = pdev->irq;
 	pci_set_master(pdev);
-	bars = pci_select_bars(pdev, IORESOURCE_MEM);
-	if (!bars)
-		goto disable_pci;
-
-	if (pci_request_selected_regions(pdev, bars, "nvme"))
-		goto disable_pci;
 
 	if (dma_set_mask_and_coherent(dev->dev, DMA_BIT_MASK(64)) &&
 	    dma_set_mask_and_coherent(dev->dev, DMA_BIT_MASK(32)))
 		goto disable;
 
-	dev->bar = ioremap(pci_resource_start(pdev, 0), 8192);
-	if (!dev->bar)
-		goto disable;
-
-	if (readl(&dev->bar->csts) == -1) {
+	if (readl(dev->bar + NVME_REG_CSTS) == -1) {
 		result = -ENODEV;
-		goto unmap;
+		goto disable;
 	}
 
 	/*
@@ -2710,13 +1745,13 @@ static int nvme_dev_map(struct nvme_dev
 	if (!pdev->irq) {
 		result = pci_enable_msix(pdev, dev->entry, 1);
 		if (result < 0)
-			goto unmap;
+			goto disable;
 	}
 
-	cap = lo_hi_readq(&dev->bar->cap);
+	cap = lo_hi_readq(dev->bar + NVME_REG_CAP);
 	dev->q_depth = min_t(int, NVME_CAP_MQES(cap) + 1, NVME_Q_DEPTH);
 	dev->db_stride = 1 << NVME_CAP_STRIDE(cap);
-	dev->dbs = ((void __iomem *)dev->bar) + 4096;
+	dev->dbs = dev->bar + 4096;
 
 	/*
 	 * Temporary fix for the Apple controller found in the MacBook8,1 and
@@ -2729,23 +1764,28 @@ static int nvme_dev_map(struct nvme_dev
 			dev->q_depth);
 	}
 
-	if (readl(&dev->bar->vs) >= NVME_VS(1, 2))
+	if (readl(dev->bar + NVME_REG_VS) >= NVME_VS(1, 2))
 		dev->cmb = nvme_map_cmb(dev);
 
+	pci_enable_pcie_error_reporting(pdev);
+	pci_save_state(pdev);
 	return 0;
 
- unmap:
-	iounmap(dev->bar);
-	dev->bar = NULL;
  disable:
-	pci_release_regions(pdev);
- disable_pci:
 	pci_disable_device(pdev);
+
 	return result;
 }
 
 static void nvme_dev_unmap(struct nvme_dev *dev)
 {
+	if (dev->bar)
+		iounmap(dev->bar);
+	pci_release_regions(to_pci_dev(dev->dev));
+}
+
+static void nvme_pci_disable(struct nvme_dev *dev)
+{
 	struct pci_dev *pdev = to_pci_dev(dev->dev);
 
 	if (pdev->msi_enabled)
@@ -2753,250 +1793,44 @@ static void nvme_dev_unmap(struct nvme_d
 	else if (pdev->msix_enabled)
 		pci_disable_msix(pdev);
 
-	if (dev->bar) {
-		iounmap(dev->bar);
-		dev->bar = NULL;
-		pci_release_regions(pdev);
-	}
-
-	if (pci_is_enabled(pdev))
+	if (pci_is_enabled(pdev)) {
+		pci_disable_pcie_error_reporting(pdev);
 		pci_disable_device(pdev);
-}
-
-struct nvme_delq_ctx {
-	struct task_struct *waiter;
-	struct kthread_worker *worker;
-	atomic_t refcount;
-};
-
-static void nvme_wait_dq(struct nvme_delq_ctx *dq, struct nvme_dev *dev)
-{
-	dq->waiter = current;
-	mb();
-
-	for (;;) {
-		set_current_state(TASK_KILLABLE);
-		if (!atomic_read(&dq->refcount))
-			break;
-		if (!schedule_timeout(ADMIN_TIMEOUT) ||
-					fatal_signal_pending(current)) {
-			/*
-			 * Disable the controller first since we can't trust it
-			 * at this point, but leave the admin queue enabled
-			 * until all queue deletion requests are flushed.
-			 * FIXME: This may take a while if there are more h/w
-			 * queues than admin tags.
-			 */
-			set_current_state(TASK_RUNNING);
-			nvme_disable_ctrl(dev, lo_hi_readq(&dev->bar->cap));
-			nvme_clear_queue(dev->queues[0]);
-			flush_kthread_worker(dq->worker);
-			nvme_disable_queue(dev, 0);
-			return;
-		}
 	}
-	set_current_state(TASK_RUNNING);
-}
-
-static void nvme_put_dq(struct nvme_delq_ctx *dq)
-{
-	atomic_dec(&dq->refcount);
-	if (dq->waiter)
-		wake_up_process(dq->waiter);
-}
-
-static struct nvme_delq_ctx *nvme_get_dq(struct nvme_delq_ctx *dq)
-{
-	atomic_inc(&dq->refcount);
-	return dq;
 }
 
-static void nvme_del_queue_end(struct nvme_queue *nvmeq)
-{
-	struct nvme_delq_ctx *dq = nvmeq->cmdinfo.ctx;
-	nvme_put_dq(dq);
-
-	spin_lock_irq(&nvmeq->q_lock);
-	nvme_process_cq(nvmeq);
-	spin_unlock_irq(&nvmeq->q_lock);
-}
-
-static int adapter_async_del_queue(struct nvme_queue *nvmeq, u8 opcode,
-						kthread_work_func_t fn)
-{
-	struct nvme_command c;
-
-	memset(&c, 0, sizeof(c));
-	c.delete_queue.opcode = opcode;
-	c.delete_queue.qid = cpu_to_le16(nvmeq->qid);
-
-	init_kthread_work(&nvmeq->cmdinfo.work, fn);
-	return nvme_submit_admin_async_cmd(nvmeq->dev, &c, &nvmeq->cmdinfo,
-								ADMIN_TIMEOUT);
-}
-
-static void nvme_del_cq_work_handler(struct kthread_work *work)
-{
-	struct nvme_queue *nvmeq = container_of(work, struct nvme_queue,
-							cmdinfo.work);
-	nvme_del_queue_end(nvmeq);
-}
-
-static int nvme_delete_cq(struct nvme_queue *nvmeq)
-{
-	return adapter_async_del_queue(nvmeq, nvme_admin_delete_cq,
-						nvme_del_cq_work_handler);
-}
-
-static void nvme_del_sq_work_handler(struct kthread_work *work)
-{
-	struct nvme_queue *nvmeq = container_of(work, struct nvme_queue,
-							cmdinfo.work);
-	int status = nvmeq->cmdinfo.status;
-
-	if (!status)
-		status = nvme_delete_cq(nvmeq);
-	if (status)
-		nvme_del_queue_end(nvmeq);
-}
-
-static int nvme_delete_sq(struct nvme_queue *nvmeq)
-{
-	return adapter_async_del_queue(nvmeq, nvme_admin_delete_sq,
-						nvme_del_sq_work_handler);
-}
-
-static void nvme_del_queue_start(struct kthread_work *work)
-{
-	struct nvme_queue *nvmeq = container_of(work, struct nvme_queue,
-							cmdinfo.work);
-	if (nvme_delete_sq(nvmeq))
-		nvme_del_queue_end(nvmeq);
-}
-
-static void nvme_disable_io_queues(struct nvme_dev *dev)
+static void nvme_dev_disable(struct nvme_dev *dev, bool shutdown)
 {
 	int i;
-	DEFINE_KTHREAD_WORKER_ONSTACK(worker);
-	struct nvme_delq_ctx dq;
-	struct task_struct *kworker_task = kthread_run(kthread_worker_fn,
-					&worker, "nvme%d", dev->instance);
-
-	if (IS_ERR(kworker_task)) {
-		dev_err(dev->dev,
-			"Failed to create queue del task\n");
-		for (i = dev->queue_count - 1; i > 0; i--)
-			nvme_disable_queue(dev, i);
-		return;
-	}
-
-	dq.waiter = NULL;
-	atomic_set(&dq.refcount, 0);
-	dq.worker = &worker;
-	for (i = dev->queue_count - 1; i > 0; i--) {
-		struct nvme_queue *nvmeq = dev->queues[i];
-
-		if (nvme_suspend_queue(nvmeq))
-			continue;
-		nvmeq->cmdinfo.ctx = nvme_get_dq(&dq);
-		nvmeq->cmdinfo.worker = dq.worker;
-		init_kthread_work(&nvmeq->cmdinfo.work, nvme_del_queue_start);
-		queue_kthread_work(dq.worker, &nvmeq->cmdinfo.work);
-	}
-	nvme_wait_dq(&dq, dev);
-	kthread_stop(kworker_task);
-}
-
-/*
-* Remove the node from the device list and check
-* for whether or not we need to stop the nvme_thread.
-*/
-static void nvme_dev_list_remove(struct nvme_dev *dev)
-{
-	struct task_struct *tmp = NULL;
-
-	spin_lock(&dev_list_lock);
-	list_del_init(&dev->node);
-	if (list_empty(&dev_list) && !IS_ERR_OR_NULL(nvme_thread)) {
-		tmp = nvme_thread;
-		nvme_thread = NULL;
-	}
-	spin_unlock(&dev_list_lock);
-
-	if (tmp)
-		kthread_stop(tmp);
-}
-
-static void nvme_freeze_queues(struct nvme_dev *dev)
-{
-	struct nvme_ns *ns;
-
-	list_for_each_entry(ns, &dev->namespaces, list) {
-		blk_mq_freeze_queue_start(ns->queue);
+	u32 csts = -1;
 
-		spin_lock_irq(ns->queue->queue_lock);
-		queue_flag_set(QUEUE_FLAG_STOPPED, ns->queue);
-		spin_unlock_irq(ns->queue->queue_lock);
+	del_timer_sync(&dev->watchdog_timer);
 
-		blk_mq_cancel_requeue_work(ns->queue);
-		blk_mq_stop_hw_queues(ns->queue);
+	mutex_lock(&dev->shutdown_lock);
+	if (pci_is_enabled(to_pci_dev(dev->dev))) {
+		nvme_stop_queues(&dev->ctrl);
+		csts = readl(dev->bar + NVME_REG_CSTS);
 	}
-}
 
-static void nvme_unfreeze_queues(struct nvme_dev *dev)
-{
-	struct nvme_ns *ns;
+	for (i = dev->queue_count - 1; i > 0; i--)
+		nvme_suspend_queue(dev->queues[i]);
 
-	list_for_each_entry(ns, &dev->namespaces, list) {
-		queue_flag_clear_unlocked(QUEUE_FLAG_STOPPED, ns->queue);
-		blk_mq_unfreeze_queue(ns->queue);
-		blk_mq_start_stopped_hw_queues(ns->queue, true);
-		blk_mq_kick_requeue_list(ns->queue);
-	}
-}
-
-static void nvme_dev_shutdown(struct nvme_dev *dev)
-{
-	int i;
-	u32 csts = -1;
-
-	nvme_dev_list_remove(dev);
-
-	if (dev->bar) {
-		nvme_freeze_queues(dev);
-		csts = readl(&dev->bar->csts);
-	}
 	if (csts & NVME_CSTS_CFS || !(csts & NVME_CSTS_RDY)) {
-		for (i = dev->queue_count - 1; i >= 0; i--) {
-			struct nvme_queue *nvmeq = dev->queues[i];
-			nvme_suspend_queue(nvmeq);
-		}
+		/* A device might become IO incapable very soon during
+		 * probe, before the admin queue is configured. Thus,
+		 * queue_count can be 0 here.
+		 */
+		if (dev->queue_count)
+			nvme_suspend_queue(dev->queues[0]);
 	} else {
 		nvme_disable_io_queues(dev);
-		nvme_shutdown_ctrl(dev);
-		nvme_disable_queue(dev, 0);
+		nvme_disable_admin_queue(dev, shutdown);
 	}
-	nvme_dev_unmap(dev);
+	nvme_pci_disable(dev);
 
 	for (i = dev->queue_count - 1; i >= 0; i--)
 		nvme_clear_queue(dev->queues[i]);
-}
-
-static void nvme_dev_remove(struct nvme_dev *dev)
-{
-	struct nvme_ns *ns, *next;
-
-	if (nvme_io_incapable(dev)) {
-		/*
-		 * If the device is not capable of IO (surprise hot-removal,
-		 * for example), we need to quiesce prior to deleting the
-		 * namespaces. This will end outstanding requests and prevent
-		 * attempts to sync dirty data.
-		 */
-		nvme_dev_shutdown(dev);
-	}
-	list_for_each_entry_safe(ns, next, &dev->namespaces, list)
-		nvme_ns_remove(ns);
+	mutex_unlock(&dev->shutdown_lock);
 }
 
 static int nvme_setup_prp_pools(struct nvme_dev *dev)
@@ -3022,121 +1856,41 @@ static void nvme_release_prp_pools(struc
 	dma_pool_destroy(dev->prp_small_pool);
 }
 
-static DEFINE_IDA(nvme_instance_ida);
-
-static int nvme_set_instance(struct nvme_dev *dev)
-{
-	int instance, error;
-
-	do {
-		if (!ida_pre_get(&nvme_instance_ida, GFP_KERNEL))
-			return -ENODEV;
-
-		spin_lock(&dev_list_lock);
-		error = ida_get_new(&nvme_instance_ida, &instance);
-		spin_unlock(&dev_list_lock);
-	} while (error == -EAGAIN);
-
-	if (error)
-		return -ENODEV;
-
-	dev->instance = instance;
-	return 0;
-}
-
-static void nvme_release_instance(struct nvme_dev *dev)
-{
-	spin_lock(&dev_list_lock);
-	ida_remove(&nvme_instance_ida, dev->instance);
-	spin_unlock(&dev_list_lock);
-}
-
-static void nvme_free_dev(struct kref *kref)
+static void nvme_pci_free_ctrl(struct nvme_ctrl *ctrl)
 {
-	struct nvme_dev *dev = container_of(kref, struct nvme_dev, kref);
+	struct nvme_dev *dev = to_nvme_dev(ctrl);
 
 	put_device(dev->dev);
-	put_device(dev->device);
-	nvme_release_instance(dev);
 	if (dev->tagset.tags)
 		blk_mq_free_tag_set(&dev->tagset);
-	if (dev->admin_q)
-		blk_put_queue(dev->admin_q);
+	if (dev->ctrl.admin_q)
+		blk_put_queue(dev->ctrl.admin_q);
 	kfree(dev->queues);
 	kfree(dev->entry);
 	kfree(dev);
 }
 
-static int nvme_dev_open(struct inode *inode, struct file *f)
+static void nvme_reset_work(struct work_struct *work)
 {
-	struct nvme_dev *dev;
-	int instance = iminor(inode);
-	int ret = -ENODEV;
-
-	spin_lock(&dev_list_lock);
-	list_for_each_entry(dev, &dev_list, node) {
-		if (dev->instance == instance) {
-			if (!dev->admin_q) {
-				ret = -EWOULDBLOCK;
-				break;
-			}
-			if (!kref_get_unless_zero(&dev->kref))
-				break;
-			f->private_data = dev;
-			ret = 0;
-			break;
-		}
-	}
-	spin_unlock(&dev_list_lock);
-
-	return ret;
-}
+	struct nvme_dev *dev = container_of(work, struct nvme_dev, reset_work);
+	int result;
 
-static int nvme_dev_release(struct inode *inode, struct file *f)
-{
-	struct nvme_dev *dev = f->private_data;
-	kref_put(&dev->kref, nvme_free_dev);
-	return 0;
-}
+	if (WARN_ON(test_bit(NVME_CTRL_RESETTING, &dev->flags)))
+		goto out;
 
-static long nvme_dev_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
-{
-	struct nvme_dev *dev = f->private_data;
-	struct nvme_ns *ns;
-
-	switch (cmd) {
-	case NVME_IOCTL_ADMIN_CMD:
-		return nvme_user_cmd(dev, NULL, (void __user *)arg);
-	case NVME_IOCTL_IO_CMD:
-		if (list_empty(&dev->namespaces))
-			return -ENOTTY;
-		ns = list_first_entry(&dev->namespaces, struct nvme_ns, list);
-		return nvme_user_cmd(dev, ns, (void __user *)arg);
-	case NVME_IOCTL_RESET:
-		dev_warn(dev->dev, "resetting controller\n");
-		return nvme_reset(dev);
-	case NVME_IOCTL_SUBSYS_RESET:
-		return nvme_subsys_reset(dev);
-	default:
-		return -ENOTTY;
-	}
-}
+	/*
+	 * If we're called to reset a live controller first shut it down before
+	 * moving on.
+	 */
+	if (dev->ctrl.ctrl_config & NVME_CC_ENABLE)
+		nvme_dev_disable(dev, false);
 
-static const struct file_operations nvme_dev_fops = {
-	.owner		= THIS_MODULE,
-	.open		= nvme_dev_open,
-	.release	= nvme_dev_release,
-	.unlocked_ioctl	= nvme_dev_ioctl,
-	.compat_ioctl	= nvme_dev_ioctl,
-};
+	if (test_bit(NVME_CTRL_REMOVING, &dev->flags))
+		goto out;
 
-static void nvme_probe_work(struct work_struct *work)
-{
-	struct nvme_dev *dev = container_of(work, struct nvme_dev, probe_work);
-	bool start_thread = false;
-	int result;
+	set_bit(NVME_CTRL_RESETTING, &dev->flags);
 
-	result = nvme_dev_map(dev);
+	result = nvme_pci_enable(dev);
 	if (result)
 		goto out;
 
@@ -3144,35 +1898,23 @@ static void nvme_probe_work(struct work_
 	if (result)
 		goto unmap;
 
-	spin_lock(&dev_list_lock);
-	if (list_empty(&dev_list) && IS_ERR_OR_NULL(nvme_thread)) {
-		start_thread = true;
-		nvme_thread = NULL;
-	}
-	list_add(&dev->node, &dev_list);
-	spin_unlock(&dev_list_lock);
-
-	if (start_thread) {
-		nvme_thread = kthread_run(nvme_kthread, NULL, "nvme");
-		wake_up_all(&nvme_kthread_wait);
-	} else
-		wait_event_killable(nvme_kthread_wait, nvme_thread);
-
-	if (IS_ERR_OR_NULL(nvme_thread)) {
-		result = nvme_thread ? PTR_ERR(nvme_thread) : -EINTR;
-		goto disable;
-	}
-
 	nvme_init_queue(dev->queues[0], 0);
 	result = nvme_alloc_admin_tags(dev);
 	if (result)
 		goto disable;
 
+	result = nvme_init_identify(&dev->ctrl);
+	if (result)
+		goto free_tags;
+
 	result = nvme_setup_io_queues(dev);
 	if (result)
 		goto free_tags;
 
-	dev->event_limit = 1;
+	dev->ctrl.event_limit = NVME_NR_AEN_COMMANDS;
+	queue_work(nvme_workq, &dev->async_work);
+
+	mod_timer(&dev->watchdog_timer, round_jiffies(jiffies + HZ));
 
 	/*
 	 * Keep the controller around but remove all namespaces if we don't have
@@ -3180,117 +1922,119 @@ static void nvme_probe_work(struct work_
 	 */
 	if (dev->online_queues < 2) {
 		dev_warn(dev->dev, "IO queues not created\n");
-		nvme_dev_remove(dev);
+		nvme_remove_namespaces(&dev->ctrl);
 	} else {
-		nvme_unfreeze_queues(dev);
+		nvme_start_queues(&dev->ctrl);
 		nvme_dev_add(dev);
 	}
 
+	clear_bit(NVME_CTRL_RESETTING, &dev->flags);
 	return;
 
  free_tags:
 	nvme_dev_remove_admin(dev);
-	blk_put_queue(dev->admin_q);
-	dev->admin_q = NULL;
+	blk_put_queue(dev->ctrl.admin_q);
+	dev->ctrl.admin_q = NULL;
 	dev->queues[0]->tags = NULL;
  disable:
-	nvme_disable_queue(dev, 0);
-	nvme_dev_list_remove(dev);
+	nvme_disable_admin_queue(dev, false);
  unmap:
 	nvme_dev_unmap(dev);
  out:
-	if (!work_busy(&dev->reset_work))
-		nvme_dead_ctrl(dev);
+	nvme_remove_dead_ctrl(dev);
 }
 
-static int nvme_remove_dead_ctrl(void *arg)
+static void nvme_remove_dead_ctrl_work(struct work_struct *work)
 {
-	struct nvme_dev *dev = (struct nvme_dev *)arg;
+	struct nvme_dev *dev = container_of(work, struct nvme_dev, remove_work);
 	struct pci_dev *pdev = to_pci_dev(dev->dev);
 
+	nvme_kill_queues(&dev->ctrl);
 	if (pci_get_drvdata(pdev))
 		pci_stop_and_remove_bus_device_locked(pdev);
-	kref_put(&dev->kref, nvme_free_dev);
-	return 0;
+	nvme_put_ctrl(&dev->ctrl);
 }
 
-static void nvme_dead_ctrl(struct nvme_dev *dev)
+static void nvme_remove_dead_ctrl(struct nvme_dev *dev)
 {
-	dev_warn(dev->dev, "Device failed to resume\n");
-	kref_get(&dev->kref);
-	if (IS_ERR(kthread_run(nvme_remove_dead_ctrl, dev, "nvme%d",
-						dev->instance))) {
-		dev_err(dev->dev,
-			"Failed to start controller remove task\n");
-		kref_put(&dev->kref, nvme_free_dev);
-	}
+	dev_warn(dev->dev, "Removing after probe failure\n");
+	kref_get(&dev->ctrl.kref);
+	nvme_dev_disable(dev, false);
+	if (!schedule_work(&dev->remove_work))
+		nvme_put_ctrl(&dev->ctrl);
 }
 
-static void nvme_reset_work(struct work_struct *ws)
+static int nvme_reset(struct nvme_dev *dev)
 {
-	struct nvme_dev *dev = container_of(ws, struct nvme_dev, reset_work);
-	bool in_probe = work_busy(&dev->probe_work);
+	if (!dev->ctrl.admin_q || blk_queue_dying(dev->ctrl.admin_q))
+		return -ENODEV;
 
-	nvme_dev_shutdown(dev);
+	if (!queue_work(nvme_workq, &dev->reset_work))
+		return -EBUSY;
 
-	/* Synchronize with device probe so that work will see failure status
-	 * and exit gracefully without trying to schedule another reset */
-	flush_work(&dev->probe_work);
+	flush_work(&dev->reset_work);
+	return 0;
+}
 
-	/* Fail this device if reset occured during probe to avoid
-	 * infinite initialization loops. */
-	if (in_probe) {
-		nvme_dead_ctrl(dev);
-		return;
-	}
-	/* Schedule device resume asynchronously so the reset work is available
-	 * to cleanup errors that may occur during reinitialization */
-	schedule_work(&dev->probe_work);
+static int nvme_pci_reg_read32(struct nvme_ctrl *ctrl, u32 off, u32 *val)
+{
+	*val = readl(to_nvme_dev(ctrl)->bar + off);
+	return 0;
 }
 
-static int __nvme_reset(struct nvme_dev *dev)
+static int nvme_pci_reg_write32(struct nvme_ctrl *ctrl, u32 off, u32 val)
 {
-	if (work_pending(&dev->reset_work))
-		return -EBUSY;
-	list_del_init(&dev->node);
-	queue_work(nvme_workq, &dev->reset_work);
+	writel(val, to_nvme_dev(ctrl)->bar + off);
 	return 0;
 }
 
-static int nvme_reset(struct nvme_dev *dev)
+static int nvme_pci_reg_read64(struct nvme_ctrl *ctrl, u32 off, u64 *val)
 {
-	int ret;
+	*val = readq(to_nvme_dev(ctrl)->bar + off);
+	return 0;
+}
 
-	if (!dev->admin_q || blk_queue_dying(dev->admin_q))
-		return -ENODEV;
+static bool nvme_pci_io_incapable(struct nvme_ctrl *ctrl)
+{
+	struct nvme_dev *dev = to_nvme_dev(ctrl);
 
-	spin_lock(&dev_list_lock);
-	ret = __nvme_reset(dev);
-	spin_unlock(&dev_list_lock);
-
-	if (!ret) {
-		flush_work(&dev->reset_work);
-		flush_work(&dev->probe_work);
-		return 0;
-	}
+	return !dev->bar || dev->online_queues < 2;
+}
 
-	return ret;
+static int nvme_pci_reset_ctrl(struct nvme_ctrl *ctrl)
+{
+	return nvme_reset(to_nvme_dev(ctrl));
 }
 
-static ssize_t nvme_sysfs_reset(struct device *dev,
-				struct device_attribute *attr, const char *buf,
-				size_t count)
+static const struct nvme_ctrl_ops nvme_pci_ctrl_ops = {
+	.reg_read32		= nvme_pci_reg_read32,
+	.reg_write32		= nvme_pci_reg_write32,
+	.reg_read64		= nvme_pci_reg_read64,
+	.io_incapable		= nvme_pci_io_incapable,
+	.reset_ctrl		= nvme_pci_reset_ctrl,
+	.free_ctrl		= nvme_pci_free_ctrl,
+};
+
+static int nvme_dev_map(struct nvme_dev *dev)
 {
-	struct nvme_dev *ndev = dev_get_drvdata(dev);
-	int ret;
+	int bars;
+	struct pci_dev *pdev = to_pci_dev(dev->dev);
 
-	ret = nvme_reset(ndev);
-	if (ret < 0)
-		return ret;
+	bars = pci_select_bars(pdev, IORESOURCE_MEM);
+	if (!bars)
+		return -ENODEV;
+	if (pci_request_selected_regions(pdev, bars, "nvme"))
+		return -ENODEV;
 
-	return count;
+	dev->bar = ioremap(pci_resource_start(pdev, 0), 8192);
+	if (!dev->bar)
+		goto release;
+
+       return 0;
+  release:
+       pci_release_regions(pdev);
+       return -ENODEV;
 }
-static DEVICE_ATTR(reset_controller, S_IWUSR, NULL, nvme_sysfs_reset);
 
 static int nvme_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 {
@@ -3313,48 +2057,39 @@ static int nvme_probe(struct pci_dev *pd
 	if (!dev->queues)
 		goto free;
 
-	INIT_LIST_HEAD(&dev->namespaces);
-	INIT_WORK(&dev->reset_work, nvme_reset_work);
 	dev->dev = get_device(&pdev->dev);
 	pci_set_drvdata(pdev, dev);
-	result = nvme_set_instance(dev);
+
+	result = nvme_dev_map(dev);
 	if (result)
-		goto put_pci;
+		goto free;
+
+	INIT_WORK(&dev->scan_work, nvme_dev_scan);
+	INIT_WORK(&dev->reset_work, nvme_reset_work);
+	INIT_WORK(&dev->remove_work, nvme_remove_dead_ctrl_work);
+	INIT_WORK(&dev->async_work, nvme_async_event_work);
+	setup_timer(&dev->watchdog_timer, nvme_watchdog_timer,
+		(unsigned long)dev);
+	mutex_init(&dev->shutdown_lock);
+	init_completion(&dev->ioq_wait);
 
 	result = nvme_setup_prp_pools(dev);
 	if (result)
-		goto release;
-
-	kref_init(&dev->kref);
-	dev->device = device_create(nvme_class, &pdev->dev,
-				MKDEV(nvme_char_major, dev->instance),
-				dev, "nvme%d", dev->instance);
-	if (IS_ERR(dev->device)) {
-		result = PTR_ERR(dev->device);
-		goto release_pools;
-	}
-	get_device(dev->device);
-	dev_set_drvdata(dev->device, dev);
+		goto put_pci;
 
-	result = device_create_file(dev->device, &dev_attr_reset_controller);
+	result = nvme_init_ctrl(&dev->ctrl, &pdev->dev, &nvme_pci_ctrl_ops,
+			id->driver_data);
 	if (result)
-		goto put_dev;
+		goto release_pools;
 
-	INIT_LIST_HEAD(&dev->node);
-	INIT_WORK(&dev->scan_work, nvme_dev_scan);
-	INIT_WORK(&dev->probe_work, nvme_probe_work);
-	schedule_work(&dev->probe_work);
+	queue_work(nvme_workq, &dev->reset_work);
 	return 0;
 
- put_dev:
-	device_destroy(nvme_class, MKDEV(nvme_char_major, dev->instance));
-	put_device(dev->device);
  release_pools:
 	nvme_release_prp_pools(dev);
- release:
-	nvme_release_instance(dev);
  put_pci:
 	put_device(dev->dev);
+	nvme_dev_unmap(dev);
  free:
 	kfree(dev->queues);
 	kfree(dev->entry);
@@ -3367,54 +2102,44 @@ static void nvme_reset_notify(struct pci
 	struct nvme_dev *dev = pci_get_drvdata(pdev);
 
 	if (prepare)
-		nvme_dev_shutdown(dev);
+		nvme_dev_disable(dev, false);
 	else
-		schedule_work(&dev->probe_work);
+		queue_work(nvme_workq, &dev->reset_work);
 }
 
 static void nvme_shutdown(struct pci_dev *pdev)
 {
 	struct nvme_dev *dev = pci_get_drvdata(pdev);
-	nvme_dev_shutdown(dev);
+	nvme_dev_disable(dev, true);
 }
 
 static void nvme_remove(struct pci_dev *pdev)
 {
 	struct nvme_dev *dev = pci_get_drvdata(pdev);
 
-	spin_lock(&dev_list_lock);
-	list_del_init(&dev->node);
-	spin_unlock(&dev_list_lock);
-
+	set_bit(NVME_CTRL_REMOVING, &dev->flags);
 	pci_set_drvdata(pdev, NULL);
-	flush_work(&dev->probe_work);
+	flush_work(&dev->async_work);
 	flush_work(&dev->reset_work);
 	flush_work(&dev->scan_work);
-	device_remove_file(dev->device, &dev_attr_reset_controller);
-	nvme_dev_remove(dev);
-	nvme_dev_shutdown(dev);
+	nvme_remove_namespaces(&dev->ctrl);
+	nvme_uninit_ctrl(&dev->ctrl);
+	nvme_dev_disable(dev, true);
 	nvme_dev_remove_admin(dev);
-	device_destroy(nvme_class, MKDEV(nvme_char_major, dev->instance));
 	nvme_free_queues(dev, 0);
 	nvme_release_cmb(dev);
 	nvme_release_prp_pools(dev);
-	kref_put(&dev->kref, nvme_free_dev);
+	nvme_dev_unmap(dev);
+	nvme_put_ctrl(&dev->ctrl);
 }
 
-/* These functions are yet to be implemented */
-#define nvme_error_detected NULL
-#define nvme_dump_registers NULL
-#define nvme_link_reset NULL
-#define nvme_slot_reset NULL
-#define nvme_error_resume NULL
-
 #ifdef CONFIG_PM_SLEEP
 static int nvme_suspend(struct device *dev)
 {
 	struct pci_dev *pdev = to_pci_dev(dev);
 	struct nvme_dev *ndev = pci_get_drvdata(pdev);
 
-	nvme_dev_shutdown(ndev);
+	nvme_dev_disable(ndev, true);
 	return 0;
 }
 
@@ -3423,17 +2148,53 @@ static int nvme_resume(struct device *de
 	struct pci_dev *pdev = to_pci_dev(dev);
 	struct nvme_dev *ndev = pci_get_drvdata(pdev);
 
-	schedule_work(&ndev->probe_work);
+	queue_work(nvme_workq, &ndev->reset_work);
 	return 0;
 }
 #endif
 
 static SIMPLE_DEV_PM_OPS(nvme_dev_pm_ops, nvme_suspend, nvme_resume);
 
+static pci_ers_result_t nvme_error_detected(struct pci_dev *pdev,
+						pci_channel_state_t state)
+{
+	struct nvme_dev *dev = pci_get_drvdata(pdev);
+
+	/*
+	 * A frozen channel requires a reset. When detected, this method will
+	 * shutdown the controller to quiesce. The controller will be restarted
+	 * after the slot reset through driver's slot_reset callback.
+	 */
+	dev_warn(&pdev->dev, "error detected: state:%d\n", state);
+	switch (state) {
+	case pci_channel_io_normal:
+		return PCI_ERS_RESULT_CAN_RECOVER;
+	case pci_channel_io_frozen:
+		nvme_dev_disable(dev, false);
+		return PCI_ERS_RESULT_NEED_RESET;
+	case pci_channel_io_perm_failure:
+		return PCI_ERS_RESULT_DISCONNECT;
+	}
+	return PCI_ERS_RESULT_NEED_RESET;
+}
+
+static pci_ers_result_t nvme_slot_reset(struct pci_dev *pdev)
+{
+	struct nvme_dev *dev = pci_get_drvdata(pdev);
+
+	dev_info(&pdev->dev, "restart after slot reset\n");
+	pci_restore_state(pdev);
+	queue_work(nvme_workq, &dev->reset_work);
+	return PCI_ERS_RESULT_RECOVERED;
+}
+
+static void nvme_error_resume(struct pci_dev *pdev)
+{
+	pci_cleanup_aer_uncorrect_error_status(pdev);
+}
+
 static const struct pci_error_handlers nvme_err_handler = {
 	.error_detected	= nvme_error_detected,
-	.mmio_enabled	= nvme_dump_registers,
-	.link_reset	= nvme_link_reset,
 	.slot_reset	= nvme_slot_reset,
 	.resume		= nvme_error_resume,
 	.reset_notify	= nvme_reset_notify,
@@ -3443,6 +2204,13 @@ static const struct pci_error_handlers n
 #define PCI_CLASS_STORAGE_EXPRESS	0x010802
 
 static const struct pci_device_id nvme_id_table[] = {
+	{ PCI_VDEVICE(INTEL, 0x0953),
+		.driver_data = NVME_QUIRK_STRIPE_SIZE |
+				NVME_QUIRK_DISCARD_ZEROES, },
+	{ PCI_VDEVICE(INTEL, 0x5845),	/* Qemu emulated controller */
+		.driver_data = NVME_QUIRK_IDENTIFY_CNS, },
+	{ PCI_DEVICE(0x1c58, 0x0003),	/* HGST adapter */
+		.driver_data = NVME_QUIRK_DELAY_BEFORE_CHK_RDY, },
 	{ PCI_DEVICE_CLASS(PCI_CLASS_STORAGE_EXPRESS, 0xffffff) },
 	{ PCI_DEVICE(PCI_VENDOR_ID_APPLE, 0x2001) },
 	{ 0, }
@@ -3465,42 +2233,21 @@ static int __init nvme_init(void)
 {
 	int result;
 
-	init_waitqueue_head(&nvme_kthread_wait);
-
-	nvme_workq = create_singlethread_workqueue("nvme");
+	nvme_workq = alloc_workqueue("nvme", WQ_UNBOUND | WQ_MEM_RECLAIM, 0);
 	if (!nvme_workq)
 		return -ENOMEM;
 
-	result = register_blkdev(nvme_major, "nvme");
+	result = nvme_core_init();
 	if (result < 0)
 		goto kill_workq;
-	else if (result > 0)
-		nvme_major = result;
-
-	result = __register_chrdev(nvme_char_major, 0, NVME_MINORS, "nvme",
-							&nvme_dev_fops);
-	if (result < 0)
-		goto unregister_blkdev;
-	else if (result > 0)
-		nvme_char_major = result;
-
-	nvme_class = class_create(THIS_MODULE, "nvme");
-	if (IS_ERR(nvme_class)) {
-		result = PTR_ERR(nvme_class);
-		goto unregister_chrdev;
-	}
 
 	result = pci_register_driver(&nvme_driver);
 	if (result)
-		goto destroy_class;
+		goto core_exit;
 	return 0;
 
- destroy_class:
-	class_destroy(nvme_class);
- unregister_chrdev:
-	__unregister_chrdev(nvme_char_major, 0, NVME_MINORS, "nvme");
- unregister_blkdev:
-	unregister_blkdev(nvme_major, "nvme");
+ core_exit:
+	nvme_core_exit();
  kill_workq:
 	destroy_workqueue(nvme_workq);
 	return result;
@@ -3509,11 +2256,8 @@ static int __init nvme_init(void)
 static void __exit nvme_exit(void)
 {
 	pci_unregister_driver(&nvme_driver);
-	unregister_blkdev(nvme_major, "nvme");
+	nvme_core_exit();
 	destroy_workqueue(nvme_workq);
-	class_destroy(nvme_class);
-	__unregister_chrdev(nvme_char_major, 0, NVME_MINORS, "nvme");
-	BUG_ON(nvme_thread && !IS_ERR(nvme_thread));
 	_nvme_check_size();
 }
 
--- zfcpdump-kernel-4.4.orig/drivers/nvme/host/scsi.c
+++ zfcpdump-kernel-4.4/drivers/nvme/host/scsi.c
@@ -524,7 +524,7 @@ static int nvme_trans_standard_inquiry_p
 					struct sg_io_hdr *hdr, u8 *inq_response,
 					int alloc_len)
 {
-	struct nvme_dev *dev = ns->dev;
+	struct nvme_ctrl *ctrl = ns->ctrl;
 	struct nvme_id_ns *id_ns;
 	int res;
 	int nvme_sc;
@@ -532,10 +532,10 @@ static int nvme_trans_standard_inquiry_p
 	u8 resp_data_format = 0x02;
 	u8 protect;
 	u8 cmdque = 0x01 << 1;
-	u8 fw_offset = sizeof(dev->firmware_rev);
+	u8 fw_offset = sizeof(ctrl->firmware_rev);
 
 	/* nvme ns identify - use DPS value for PROTECT field */
-	nvme_sc = nvme_identify_ns(dev, ns->ns_id, &id_ns);
+	nvme_sc = nvme_identify_ns(ctrl, ns->ns_id, &id_ns);
 	res = nvme_trans_status_code(hdr, nvme_sc);
 	if (res)
 		return res;
@@ -553,12 +553,12 @@ static int nvme_trans_standard_inquiry_p
 	inq_response[5] = protect;	/* sccs=0 | acc=0 | tpgs=0 | pc3=0 */
 	inq_response[7] = cmdque;	/* wbus16=0 | sync=0 | vs=0 */
 	strncpy(&inq_response[8], "NVMe    ", 8);
-	strncpy(&inq_response[16], dev->model, 16);
+	strncpy(&inq_response[16], ctrl->model, 16);
 
-	while (dev->firmware_rev[fw_offset - 1] == ' ' && fw_offset > 4)
+	while (ctrl->firmware_rev[fw_offset - 1] == ' ' && fw_offset > 4)
 		fw_offset--;
 	fw_offset -= 4;
-	strncpy(&inq_response[32], dev->firmware_rev + fw_offset, 4);
+	strncpy(&inq_response[32], ctrl->firmware_rev + fw_offset, 4);
 
 	xfer_len = min(alloc_len, STANDARD_INQUIRY_LENGTH);
 	return nvme_trans_copy_to_user(hdr, inq_response, xfer_len);
@@ -588,82 +588,113 @@ static int nvme_trans_unit_serial_page(s
 					struct sg_io_hdr *hdr, u8 *inq_response,
 					int alloc_len)
 {
-	struct nvme_dev *dev = ns->dev;
 	int xfer_len;
 
 	memset(inq_response, 0, STANDARD_INQUIRY_LENGTH);
 	inq_response[1] = INQ_UNIT_SERIAL_NUMBER_PAGE; /* Page Code */
 	inq_response[3] = INQ_SERIAL_NUMBER_LENGTH;    /* Page Length */
-	strncpy(&inq_response[4], dev->serial, INQ_SERIAL_NUMBER_LENGTH);
+	strncpy(&inq_response[4], ns->ctrl->serial, INQ_SERIAL_NUMBER_LENGTH);
 
 	xfer_len = min(alloc_len, STANDARD_INQUIRY_LENGTH);
 	return nvme_trans_copy_to_user(hdr, inq_response, xfer_len);
 }
 
-static int nvme_trans_device_id_page(struct nvme_ns *ns, struct sg_io_hdr *hdr,
-					u8 *inq_response, int alloc_len)
+static int nvme_fill_device_id_eui64(struct nvme_ns *ns, struct sg_io_hdr *hdr,
+		u8 *inq_response, int alloc_len)
 {
-	struct nvme_dev *dev = ns->dev;
-	int res;
-	int nvme_sc;
-	int xfer_len;
-	__be32 tmp_id = cpu_to_be32(ns->ns_id);
+	struct nvme_id_ns *id_ns;
+	int nvme_sc, res;
+	size_t len;
+	void *eui;
 
-	memset(inq_response, 0, alloc_len);
-	inq_response[1] = INQ_DEVICE_IDENTIFICATION_PAGE;    /* Page Code */
-	if (readl(&dev->bar->vs) >= NVME_VS(1, 1)) {
-		struct nvme_id_ns *id_ns;
-		void *eui;
-		int len;
+	nvme_sc = nvme_identify_ns(ns->ctrl, ns->ns_id, &id_ns);
+	res = nvme_trans_status_code(hdr, nvme_sc);
+	if (res)
+		return res;
 
-		nvme_sc = nvme_identify_ns(dev, ns->ns_id, &id_ns);
-		res = nvme_trans_status_code(hdr, nvme_sc);
-		if (res)
-			return res;
+	eui = id_ns->eui64;
+	len = sizeof(id_ns->eui64);
 
-		eui = id_ns->eui64;
-		len = sizeof(id_ns->eui64);
-		if (readl(&dev->bar->vs) >= NVME_VS(1, 2)) {
-			if (bitmap_empty(eui, len * 8)) {
-				eui = id_ns->nguid;
-				len = sizeof(id_ns->nguid);
-			}
-		}
+	if (ns->ctrl->vs >= NVME_VS(1, 2)) {
 		if (bitmap_empty(eui, len * 8)) {
-			kfree(id_ns);
-			goto scsi_string;
+			eui = id_ns->nguid;
+			len = sizeof(id_ns->nguid);
 		}
+	}
 
-		inq_response[3] = 4 + len; /* Page Length */
-		/* Designation Descriptor start */
-		inq_response[4] = 0x01;    /* Proto ID=0h | Code set=1h */
-		inq_response[5] = 0x02;    /* PIV=0b | Asso=00b | Designator Type=2h */
-		inq_response[6] = 0x00;    /* Rsvd */
-		inq_response[7] = len;     /* Designator Length */
-		memcpy(&inq_response[8], eui, len);
-		kfree(id_ns);
-	} else {
- scsi_string:
-		if (alloc_len < 72) {
-			return nvme_trans_completion(hdr,
-					SAM_STAT_CHECK_CONDITION,
-					ILLEGAL_REQUEST, SCSI_ASC_INVALID_CDB,
-					SCSI_ASCQ_CAUSE_NOT_REPORTABLE);
-		}
-		inq_response[3] = 0x48;    /* Page Length */
-		/* Designation Descriptor start */
-		inq_response[4] = 0x03;    /* Proto ID=0h | Code set=3h */
-		inq_response[5] = 0x08;    /* PIV=0b | Asso=00b | Designator Type=8h */
-		inq_response[6] = 0x00;    /* Rsvd */
-		inq_response[7] = 0x44;    /* Designator Length */
-
-		sprintf(&inq_response[8], "%04x", to_pci_dev(dev->dev)->vendor);
-		memcpy(&inq_response[12], dev->model, sizeof(dev->model));
-		sprintf(&inq_response[52], "%04x", tmp_id);
-		memcpy(&inq_response[56], dev->serial, sizeof(dev->serial));
+	if (bitmap_empty(eui, len * 8)) {
+		res = -EOPNOTSUPP;
+		goto out_free_id;
 	}
-	xfer_len = alloc_len;
-	return nvme_trans_copy_to_user(hdr, inq_response, xfer_len);
+
+	memset(inq_response, 0, alloc_len);
+	inq_response[1] = INQ_DEVICE_IDENTIFICATION_PAGE;
+	inq_response[3] = 4 + len; /* Page Length */
+
+	/* Designation Descriptor start */
+	inq_response[4] = 0x01;	/* Proto ID=0h | Code set=1h */
+	inq_response[5] = 0x02;	/* PIV=0b | Asso=00b | Designator Type=2h */
+	inq_response[6] = 0x00;	/* Rsvd */
+	inq_response[7] = len;	/* Designator Length */
+	memcpy(&inq_response[8], eui, len);
+
+	res = nvme_trans_copy_to_user(hdr, inq_response, alloc_len);
+out_free_id:
+	kfree(id_ns);
+	return res;
+}
+
+static int nvme_fill_device_id_scsi_string(struct nvme_ns *ns,
+		struct sg_io_hdr *hdr, u8 *inq_response, int alloc_len)
+{
+	struct nvme_ctrl *ctrl = ns->ctrl;
+	struct nvme_id_ctrl *id_ctrl;
+	int nvme_sc, res;
+
+	if (alloc_len < 72) {
+		return nvme_trans_completion(hdr,
+				SAM_STAT_CHECK_CONDITION,
+				ILLEGAL_REQUEST, SCSI_ASC_INVALID_CDB,
+				SCSI_ASCQ_CAUSE_NOT_REPORTABLE);
+	}
+
+	nvme_sc = nvme_identify_ctrl(ctrl, &id_ctrl);
+	res = nvme_trans_status_code(hdr, nvme_sc);
+	if (res)
+		return res;
+
+	memset(inq_response, 0, alloc_len);
+	inq_response[1] = INQ_DEVICE_IDENTIFICATION_PAGE;
+	inq_response[3] = 0x48;	/* Page Length */
+
+	/* Designation Descriptor start */
+	inq_response[4] = 0x03;	/* Proto ID=0h | Code set=3h */
+	inq_response[5] = 0x08;	/* PIV=0b | Asso=00b | Designator Type=8h */
+	inq_response[6] = 0x00;	/* Rsvd */
+	inq_response[7] = 0x44;	/* Designator Length */
+
+	sprintf(&inq_response[8], "%04x", le16_to_cpu(id_ctrl->vid));
+	memcpy(&inq_response[12], ctrl->model, sizeof(ctrl->model));
+	sprintf(&inq_response[52], "%04x", cpu_to_be32(ns->ns_id));
+	memcpy(&inq_response[56], ctrl->serial, sizeof(ctrl->serial));
+
+	res = nvme_trans_copy_to_user(hdr, inq_response, alloc_len);
+	kfree(id_ctrl);
+	return res;
+}
+
+static int nvme_trans_device_id_page(struct nvme_ns *ns, struct sg_io_hdr *hdr,
+					u8 *resp, int alloc_len)
+{
+	int res;
+
+	if (ns->ctrl->vs >= NVME_VS(1, 1)) {
+		res = nvme_fill_device_id_eui64(ns, hdr, resp, alloc_len);
+		if (res != -EOPNOTSUPP)
+			return res;
+	}
+
+	return nvme_fill_device_id_scsi_string(ns, hdr, resp, alloc_len);
 }
 
 static int nvme_trans_ext_inq_page(struct nvme_ns *ns, struct sg_io_hdr *hdr,
@@ -672,7 +703,7 @@ static int nvme_trans_ext_inq_page(struc
 	u8 *inq_response;
 	int res;
 	int nvme_sc;
-	struct nvme_dev *dev = ns->dev;
+	struct nvme_ctrl *ctrl = ns->ctrl;
 	struct nvme_id_ctrl *id_ctrl;
 	struct nvme_id_ns *id_ns;
 	int xfer_len;
@@ -688,7 +719,7 @@ static int nvme_trans_ext_inq_page(struc
 	if (inq_response == NULL)
 		return -ENOMEM;
 
-	nvme_sc = nvme_identify_ns(dev, ns->ns_id, &id_ns);
+	nvme_sc = nvme_identify_ns(ctrl, ns->ns_id, &id_ns);
 	res = nvme_trans_status_code(hdr, nvme_sc);
 	if (res)
 		goto out_free_inq;
@@ -704,7 +735,7 @@ static int nvme_trans_ext_inq_page(struc
 	app_chk = protect << 1;
 	ref_chk = protect;
 
-	nvme_sc = nvme_identify_ctrl(dev, &id_ctrl);
+	nvme_sc = nvme_identify_ctrl(ctrl, &id_ctrl);
 	res = nvme_trans_status_code(hdr, nvme_sc);
 	if (res)
 		goto out_free_inq;
@@ -815,7 +846,6 @@ static int nvme_trans_log_info_exception
 	int res;
 	int xfer_len;
 	u8 *log_response;
-	struct nvme_dev *dev = ns->dev;
 	struct nvme_smart_log *smart_log;
 	u8 temp_c;
 	u16 temp_k;
@@ -824,7 +854,7 @@ static int nvme_trans_log_info_exception
 	if (log_response == NULL)
 		return -ENOMEM;
 
-	res = nvme_get_log_page(dev, &smart_log);
+	res = nvme_get_log_page(ns->ctrl, &smart_log);
 	if (res < 0)
 		goto out_free_response;
 
@@ -862,7 +892,6 @@ static int nvme_trans_log_temperature(st
 	int res;
 	int xfer_len;
 	u8 *log_response;
-	struct nvme_dev *dev = ns->dev;
 	struct nvme_smart_log *smart_log;
 	u32 feature_resp;
 	u8 temp_c_cur, temp_c_thresh;
@@ -872,7 +901,7 @@ static int nvme_trans_log_temperature(st
 	if (log_response == NULL)
 		return -ENOMEM;
 
-	res = nvme_get_log_page(dev, &smart_log);
+	res = nvme_get_log_page(ns->ctrl, &smart_log);
 	if (res < 0)
 		goto out_free_response;
 
@@ -886,7 +915,7 @@ static int nvme_trans_log_temperature(st
 	kfree(smart_log);
 
 	/* Get Features for Temp Threshold */
-	res = nvme_get_features(dev, NVME_FEAT_TEMP_THRESH, 0, 0,
+	res = nvme_get_features(ns->ctrl, NVME_FEAT_TEMP_THRESH, 0, 0,
 								&feature_resp);
 	if (res != NVME_SC_SUCCESS)
 		temp_c_thresh = LOG_TEMP_UNKNOWN;
@@ -948,7 +977,6 @@ static int nvme_trans_fill_blk_desc(stru
 {
 	int res;
 	int nvme_sc;
-	struct nvme_dev *dev = ns->dev;
 	struct nvme_id_ns *id_ns;
 	u8 flbas;
 	u32 lba_length;
@@ -958,7 +986,7 @@ static int nvme_trans_fill_blk_desc(stru
 	else if (llbaa > 0 && len < MODE_PAGE_LLBAA_BLK_DES_LEN)
 		return -EINVAL;
 
-	nvme_sc = nvme_identify_ns(dev, ns->ns_id, &id_ns);
+	nvme_sc = nvme_identify_ns(ns->ctrl, ns->ns_id, &id_ns);
 	res = nvme_trans_status_code(hdr, nvme_sc);
 	if (res)
 		return res;
@@ -1014,14 +1042,13 @@ static int nvme_trans_fill_caching_page(
 {
 	int res = 0;
 	int nvme_sc;
-	struct nvme_dev *dev = ns->dev;
 	u32 feature_resp;
 	u8 vwc;
 
 	if (len < MODE_PAGE_CACHING_LEN)
 		return -EINVAL;
 
-	nvme_sc = nvme_get_features(dev, NVME_FEAT_VOLATILE_WC, 0, 0,
+	nvme_sc = nvme_get_features(ns->ctrl, NVME_FEAT_VOLATILE_WC, 0, 0,
 								&feature_resp);
 	res = nvme_trans_status_code(hdr, nvme_sc);
 	if (res)
@@ -1207,12 +1234,11 @@ static int nvme_trans_power_state(struct
 {
 	int res;
 	int nvme_sc;
-	struct nvme_dev *dev = ns->dev;
 	struct nvme_id_ctrl *id_ctrl;
 	int lowest_pow_st;	/* max npss = lowest power consumption */
 	unsigned ps_desired = 0;
 
-	nvme_sc = nvme_identify_ctrl(dev, &id_ctrl);
+	nvme_sc = nvme_identify_ctrl(ns->ctrl, &id_ctrl);
 	res = nvme_trans_status_code(hdr, nvme_sc);
 	if (res)
 		return res;
@@ -1256,7 +1282,7 @@ static int nvme_trans_power_state(struct
 				SCSI_ASCQ_CAUSE_NOT_REPORTABLE);
 		break;
 	}
-	nvme_sc = nvme_set_features(dev, NVME_FEAT_POWER_MGMT, ps_desired, 0,
+	nvme_sc = nvme_set_features(ns->ctrl, NVME_FEAT_POWER_MGMT, ps_desired, 0,
 				    NULL);
 	return nvme_trans_status_code(hdr, nvme_sc);
 }
@@ -1280,7 +1306,6 @@ static int nvme_trans_send_download_fw_c
 					u8 buffer_id)
 {
 	int nvme_sc;
-	struct nvme_dev *dev = ns->dev;
 	struct nvme_command c;
 
 	if (hdr->iovec_count > 0) {
@@ -1297,7 +1322,7 @@ static int nvme_trans_send_download_fw_c
 	c.dlfw.numd = cpu_to_le32((tot_len/BYTES_TO_DWORDS) - 1);
 	c.dlfw.offset = cpu_to_le32(offset/BYTES_TO_DWORDS);
 
-	nvme_sc = __nvme_submit_sync_cmd(dev->admin_q, &c, NULL,
+	nvme_sc = nvme_submit_user_cmd(ns->ctrl->admin_q, &c,
 			hdr->dxferp, tot_len, NULL, 0);
 	return nvme_trans_status_code(hdr, nvme_sc);
 }
@@ -1364,14 +1389,13 @@ static int nvme_trans_modesel_get_mp(str
 {
 	int res = 0;
 	int nvme_sc;
-	struct nvme_dev *dev = ns->dev;
 	unsigned dword11;
 
 	switch (page_code) {
 	case MODE_PAGE_CACHING:
 		dword11 = ((mode_page[2] & CACHING_MODE_PAGE_WCE_MASK) ? 1 : 0);
-		nvme_sc = nvme_set_features(dev, NVME_FEAT_VOLATILE_WC, dword11,
-					    0, NULL);
+		nvme_sc = nvme_set_features(ns->ctrl, NVME_FEAT_VOLATILE_WC,
+					    dword11, 0, NULL);
 		res = nvme_trans_status_code(hdr, nvme_sc);
 		break;
 	case MODE_PAGE_CONTROL:
@@ -1473,7 +1497,6 @@ static int nvme_trans_fmt_set_blk_size_c
 {
 	int res = 0;
 	int nvme_sc;
-	struct nvme_dev *dev = ns->dev;
 	u8 flbas;
 
 	/*
@@ -1486,7 +1509,7 @@ static int nvme_trans_fmt_set_blk_size_c
 	if (ns->mode_select_num_blocks == 0 || ns->mode_select_block_len == 0) {
 		struct nvme_id_ns *id_ns;
 
-		nvme_sc = nvme_identify_ns(dev, ns->ns_id, &id_ns);
+		nvme_sc = nvme_identify_ns(ns->ctrl, ns->ns_id, &id_ns);
 		res = nvme_trans_status_code(hdr, nvme_sc);
 		if (res)
 			return res;
@@ -1570,7 +1593,6 @@ static int nvme_trans_fmt_send_cmd(struc
 {
 	int res;
 	int nvme_sc;
-	struct nvme_dev *dev = ns->dev;
 	struct nvme_id_ns *id_ns;
 	u8 i;
 	u8 flbas, nlbaf;
@@ -1579,7 +1601,7 @@ static int nvme_trans_fmt_send_cmd(struc
 	struct nvme_command c;
 
 	/* Loop thru LBAF's in id_ns to match reqd lbaf, put in cdw10 */
-	nvme_sc = nvme_identify_ns(dev, ns->ns_id, &id_ns);
+	nvme_sc = nvme_identify_ns(ns->ctrl, ns->ns_id, &id_ns);
 	res = nvme_trans_status_code(hdr, nvme_sc);
 	if (res)
 		return res;
@@ -1611,7 +1633,7 @@ static int nvme_trans_fmt_send_cmd(struc
 	c.format.nsid = cpu_to_le32(ns->ns_id);
 	c.format.cdw10 = cpu_to_le32(cdw10);
 
-	nvme_sc = nvme_submit_sync_cmd(dev->admin_q, &c, NULL, 0);
+	nvme_sc = nvme_submit_sync_cmd(ns->ctrl->admin_q, &c, NULL, 0);
 	res = nvme_trans_status_code(hdr, nvme_sc);
 
 	kfree(id_ns);
@@ -1704,7 +1726,7 @@ static int nvme_trans_do_nvme_io(struct
 			nvme_sc = NVME_SC_LBA_RANGE;
 			break;
 		}
-		nvme_sc = __nvme_submit_sync_cmd(ns->queue, &c, NULL,
+		nvme_sc = nvme_submit_user_cmd(ns->queue, &c,
 				next_mapping_addr, unit_len, NULL, 0);
 		if (nvme_sc)
 			break;
@@ -2040,7 +2062,6 @@ static int nvme_trans_read_capacity(stru
 	u32 alloc_len;
 	u32 resp_size;
 	u32 xfer_len;
-	struct nvme_dev *dev = ns->dev;
 	struct nvme_id_ns *id_ns;
 	u8 *response;
 
@@ -2052,7 +2073,7 @@ static int nvme_trans_read_capacity(stru
 		resp_size = READ_CAP_10_RESP_SIZE;
 	}
 
-	nvme_sc = nvme_identify_ns(dev, ns->ns_id, &id_ns);
+	nvme_sc = nvme_identify_ns(ns->ctrl, ns->ns_id, &id_ns);
 	res = nvme_trans_status_code(hdr, nvme_sc);
 	if (res)
 		return res;	
@@ -2080,7 +2101,6 @@ static int nvme_trans_report_luns(struct
 	int nvme_sc;
 	u32 alloc_len, xfer_len, resp_size;
 	u8 *response;
-	struct nvme_dev *dev = ns->dev;
 	struct nvme_id_ctrl *id_ctrl;
 	u32 ll_length, lun_id;
 	u8 lun_id_offset = REPORT_LUNS_FIRST_LUN_OFFSET;
@@ -2094,7 +2114,7 @@ static int nvme_trans_report_luns(struct
 	case ALL_LUNS_RETURNED:
 	case ALL_WELL_KNOWN_LUNS_RETURNED:
 	case RESTRICTED_LUNS_RETURNED:
-		nvme_sc = nvme_identify_ctrl(dev, &id_ctrl);
+		nvme_sc = nvme_identify_ctrl(ns->ctrl, &id_ctrl);
 		res = nvme_trans_status_code(hdr, nvme_sc);
 		if (res)
 			return res;
@@ -2295,9 +2315,7 @@ static int nvme_trans_test_unit_ready(st
 					struct sg_io_hdr *hdr,
 					u8 *cmd)
 {
-	struct nvme_dev *dev = ns->dev;
-
-	if (!(readl(&dev->bar->csts) & NVME_CSTS_RDY))
+	if (nvme_ctrl_ready(ns->ctrl))
 		return nvme_trans_completion(hdr, SAM_STAT_CHECK_CONDITION,
 					    NOT_READY, SCSI_ASC_LUN_NOT_READY,
 					    SCSI_ASCQ_CAUSE_NOT_REPORTABLE);
--- zfcpdump-kernel-4.4.orig/drivers/nvmem/mxs-ocotp.c
+++ zfcpdump-kernel-4.4/drivers/nvmem/mxs-ocotp.c
@@ -94,7 +94,7 @@ static int mxs_ocotp_read(void *context,
 	if (ret)
 		goto close_banks;
 
-	while (val_size) {
+	while (val_size >= reg_size) {
 		if ((offset < OCOTP_DATA_OFFSET) || (offset % 16)) {
 			/* fill up non-data register */
 			*buf = 0;
@@ -103,7 +103,7 @@ static int mxs_ocotp_read(void *context,
 		}
 
 		buf++;
-		val_size--;
+		val_size -= reg_size;
 		offset += reg_size;
 	}
 
--- zfcpdump-kernel-4.4.orig/drivers/of/Kconfig
+++ zfcpdump-kernel-4.4/drivers/of/Kconfig
@@ -112,4 +112,7 @@ config OF_OVERLAY
 	  While this option is selected automatically when needed, you can
 	  enable it manually to improve device tree unit test coverage.
 
+config OF_NUMA
+	bool
+
 endif # OF
--- zfcpdump-kernel-4.4.orig/drivers/of/Makefile
+++ zfcpdump-kernel-4.4/drivers/of/Makefile
@@ -14,5 +14,6 @@ obj-$(CONFIG_OF_MTD)	+= of_mtd.o
 obj-$(CONFIG_OF_RESERVED_MEM) += of_reserved_mem.o
 obj-$(CONFIG_OF_RESOLVE)  += resolver.o
 obj-$(CONFIG_OF_OVERLAY) += overlay.o
+obj-$(CONFIG_OF_NUMA) += of_numa.o
 
 obj-$(CONFIG_OF_UNITTEST) += unittest-data/
--- zfcpdump-kernel-4.4.orig/drivers/of/base.c
+++ zfcpdump-kernel-4.4/drivers/of/base.c
@@ -112,6 +112,7 @@ static ssize_t of_node_property_read(str
 	return memory_read_from_buffer(buf, count, &offset, pp->value, pp->length);
 }
 
+/* always return newly allocated name, caller must free after use */
 static const char *safe_name(struct kobject *kobj, const char *orig_name)
 {
 	const char *name = orig_name;
@@ -126,9 +127,12 @@ static const char *safe_name(struct kobj
 		name = kasprintf(GFP_KERNEL, "%s#%i", orig_name, ++i);
 	}
 
-	if (name != orig_name)
+	if (name == orig_name) {
+		name = kstrdup(orig_name, GFP_KERNEL);
+	} else {
 		pr_warn("device-tree: Duplicate name in %s, renamed to \"%s\"\n",
 			kobject_name(kobj), name);
+	}
 	return name;
 }
 
@@ -159,6 +163,7 @@ int __of_add_property_sysfs(struct devic
 int __of_attach_node_sysfs(struct device_node *np)
 {
 	const char *name;
+	struct kobject *parent;
 	struct property *pp;
 	int rc;
 
@@ -171,15 +176,16 @@ int __of_attach_node_sysfs(struct device
 	np->kobj.kset = of_kset;
 	if (!np->parent) {
 		/* Nodes without parents are new top level trees */
-		rc = kobject_add(&np->kobj, NULL, "%s",
-				 safe_name(&of_kset->kobj, "base"));
+		name = safe_name(&of_kset->kobj, "base");
+		parent = NULL;
 	} else {
 		name = safe_name(&np->parent->kobj, kbasename(np->full_name));
-		if (!name || !name[0])
-			return -EINVAL;
-
-		rc = kobject_add(&np->kobj, &np->parent->kobj, "%s", name);
+		parent = &np->parent->kobj;
 	}
+	if (!name)
+		return -ENOMEM;
+	rc = kobject_add(&np->kobj, parent, "%s", name);
+	kfree(name);
 	if (rc)
 		return rc;
 
@@ -1753,6 +1759,12 @@ int __of_remove_property(struct device_n
 	return 0;
 }
 
+void __of_sysfs_remove_bin_file(struct device_node *np, struct property *prop)
+{
+	sysfs_remove_bin_file(&np->kobj, &prop->attr);
+	kfree(prop->attr.attr.name);
+}
+
 void __of_remove_property_sysfs(struct device_node *np, struct property *prop)
 {
 	if (!IS_ENABLED(CONFIG_SYSFS))
@@ -1760,7 +1772,7 @@ void __of_remove_property_sysfs(struct d
 
 	/* at early boot, bail here and defer setup to of_init() */
 	if (of_kset && of_node_is_attached(np))
-		sysfs_remove_bin_file(&np->kobj, &prop->attr);
+		__of_sysfs_remove_bin_file(np, prop);
 }
 
 /**
@@ -1830,7 +1842,7 @@ void __of_update_property_sysfs(struct d
 		return;
 
 	if (oldprop)
-		sysfs_remove_bin_file(&np->kobj, &oldprop->attr);
+		__of_sysfs_remove_bin_file(np, oldprop);
 	__of_add_property_sysfs(np, newprop);
 }
 
@@ -2241,20 +2253,13 @@ struct device_node *of_graph_get_endpoin
 	const struct device_node *parent, int port_reg, int reg)
 {
 	struct of_endpoint endpoint;
-	struct device_node *node, *prev_node = NULL;
-
-	while (1) {
-		node = of_graph_get_next_endpoint(parent, prev_node);
-		of_node_put(prev_node);
-		if (!node)
-			break;
+	struct device_node *node = NULL;
 
+	for_each_endpoint_of_node(parent, node) {
 		of_graph_parse_endpoint(node, &endpoint);
 		if (((port_reg == -1) || (endpoint.port == port_reg)) &&
 			((reg == -1) || (endpoint.id == reg)))
 			return node;
-
-		prev_node = node;
 	}
 
 	return NULL;
--- zfcpdump-kernel-4.4.orig/drivers/of/dynamic.c
+++ zfcpdump-kernel-4.4/drivers/of/dynamic.c
@@ -55,7 +55,7 @@ void __of_detach_node_sysfs(struct devic
 	/* only remove properties if on sysfs */
 	if (of_node_is_attached(np)) {
 		for_each_property_of_node(np, pp)
-			sysfs_remove_bin_file(&np->kobj, &pp->attr);
+			__of_sysfs_remove_bin_file(np, pp);
 		kobject_del(&np->kobj);
 	}
 
--- zfcpdump-kernel-4.4.orig/drivers/of/irq.c
+++ zfcpdump-kernel-4.4/drivers/of/irq.c
@@ -386,13 +386,13 @@ int of_irq_to_resource(struct device_nod
 EXPORT_SYMBOL_GPL(of_irq_to_resource);
 
 /**
- * of_irq_get - Decode a node's IRQ and return it as a Linux irq number
+ * of_irq_get - Decode a node's IRQ and return it as a Linux IRQ number
  * @dev: pointer to device tree node
- * @index: zero-based index of the irq
- *
- * Returns Linux irq number on success, or -EPROBE_DEFER if the irq domain
- * is not yet created.
+ * @index: zero-based index of the IRQ
  *
+ * Returns Linux IRQ number on success, or 0 on the IRQ mapping failure, or
+ * -EPROBE_DEFER if the IRQ domain is not yet created, or error code in case
+ * of any other failure.
  */
 int of_irq_get(struct device_node *dev, int index)
 {
@@ -413,12 +413,13 @@ int of_irq_get(struct device_node *dev,
 EXPORT_SYMBOL_GPL(of_irq_get);
 
 /**
- * of_irq_get_byname - Decode a node's IRQ and return it as a Linux irq number
+ * of_irq_get_byname - Decode a node's IRQ and return it as a Linux IRQ number
  * @dev: pointer to device tree node
- * @name: irq name
+ * @name: IRQ name
  *
- * Returns Linux irq number on success, or -EPROBE_DEFER if the irq domain
- * is not yet created, or error code in case of any other failure.
+ * Returns Linux IRQ number on success, or 0 on the IRQ mapping failure, or
+ * -EPROBE_DEFER if the IRQ domain is not yet created, or error code in case
+ * of any other failure.
  */
 int of_irq_get_byname(struct device_node *dev, const char *name)
 {
@@ -636,6 +637,13 @@ static u32 __of_msi_map_rid(struct devic
 		msi_base = be32_to_cpup(msi_map + 2);
 		rid_len = be32_to_cpup(msi_map + 3);
 
+		if (rid_base & ~map_mask) {
+			dev_err(parent_dev,
+				"Invalid msi-map translation - msi-map-mask (0x%x) ignores rid-base (0x%x)\n",
+				map_mask, rid_base);
+			return rid_out;
+		}
+
 		msi_controller_node = of_find_node_by_phandle(phandle);
 
 		matched = (masked_rid >= rid_base &&
@@ -655,7 +663,7 @@ static u32 __of_msi_map_rid(struct devic
 	if (!matched)
 		return rid_out;
 
-	rid_out = masked_rid + msi_base;
+	rid_out = masked_rid - rid_base + msi_base;
 	dev_dbg(dev,
 		"msi-map at: %s, using mask %08x, rid-base: %08x, msi-base: %08x, length: %08x, rid: %08x -> %08x\n",
 		dev_name(parent_dev), map_mask, rid_base, msi_base,
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/of/of_numa.c
@@ -0,0 +1,211 @@
+/*
+ * OF NUMA Parsing support.
+ *
+ * Copyright (C) 2015 - 2016 Cavium Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/nodemask.h>
+
+#include <asm/numa.h>
+
+/* define default numa node to 0 */
+#define DEFAULT_NODE 0
+
+/*
+ * Even though we connect cpus to numa domains later in SMP
+ * init, we need to know the node ids now for all cpus.
+*/
+static void __init of_numa_parse_cpu_nodes(void)
+{
+	u32 nid;
+	int r;
+	struct device_node *cpus;
+	struct device_node *np = NULL;
+
+	cpus = of_find_node_by_path("/cpus");
+	if (!cpus)
+		return;
+
+	for_each_child_of_node(cpus, np) {
+		/* Skip things that are not CPUs */
+		if (of_node_cmp(np->type, "cpu") != 0)
+			continue;
+
+		r = of_property_read_u32(np, "numa-node-id", &nid);
+		if (r)
+			continue;
+
+		pr_debug("NUMA: CPU on %u\n", nid);
+		if (nid >= MAX_NUMNODES)
+			pr_warn("NUMA: Node id %u exceeds maximum value\n",
+				nid);
+		else
+			node_set(nid, numa_nodes_parsed);
+	}
+}
+
+static int __init of_numa_parse_memory_nodes(void)
+{
+	struct device_node *np = NULL;
+	struct resource rsrc;
+	u32 nid;
+	int r = 0;
+
+	for (;;) {
+		np = of_find_node_by_type(np, "memory");
+		if (!np)
+			break;
+
+		r = of_property_read_u32(np, "numa-node-id", &nid);
+		if (r == -EINVAL)
+			/*
+			 * property doesn't exist if -EINVAL, continue
+			 * looking for more memory nodes with
+			 * "numa-node-id" property
+			 */
+			continue;
+		else if (r)
+			/* some other error */
+			break;
+
+		r = of_address_to_resource(np, 0, &rsrc);
+		if (r) {
+			pr_err("NUMA: bad reg property in memory node\n");
+			break;
+		}
+
+		pr_debug("NUMA:  base = %llx len = %llx, node = %u\n",
+			 rsrc.start, rsrc.end - rsrc.start + 1, nid);
+
+		r = numa_add_memblk(nid, rsrc.start,
+				    rsrc.end - rsrc.start + 1);
+		if (r)
+			break;
+	}
+	of_node_put(np);
+
+	return r;
+}
+
+static int __init of_numa_parse_distance_map_v1(struct device_node *map)
+{
+	const __be32 *matrix;
+	int entry_count;
+	int i;
+
+	pr_info("NUMA: parsing numa-distance-map-v1\n");
+
+	matrix = of_get_property(map, "distance-matrix", NULL);
+	if (!matrix) {
+		pr_err("NUMA: No distance-matrix property in distance-map\n");
+		return -EINVAL;
+	}
+
+	entry_count = of_property_count_u32_elems(map, "distance-matrix");
+	if (entry_count <= 0) {
+		pr_err("NUMA: Invalid distance-matrix\n");
+		return -EINVAL;
+	}
+
+	for (i = 0; i + 2 < entry_count; i += 3) {
+		u32 nodea, nodeb, distance;
+
+		nodea = of_read_number(matrix, 1);
+		matrix++;
+		nodeb = of_read_number(matrix, 1);
+		matrix++;
+		distance = of_read_number(matrix, 1);
+		matrix++;
+
+		numa_set_distance(nodea, nodeb, distance);
+		pr_debug("NUMA:  distance[node%d -> node%d] = %d\n",
+			 nodea, nodeb, distance);
+
+		/* Set default distance of node B->A same as A->B */
+		if (nodeb > nodea)
+			numa_set_distance(nodeb, nodea, distance);
+	}
+
+	return 0;
+}
+
+static int __init of_numa_parse_distance_map(void)
+{
+	int ret = 0;
+	struct device_node *np;
+
+	np = of_find_compatible_node(NULL, NULL,
+				     "numa-distance-map-v1");
+	if (np)
+		ret = of_numa_parse_distance_map_v1(np);
+
+	of_node_put(np);
+	return ret;
+}
+
+int of_node_to_nid(struct device_node *device)
+{
+	struct device_node *np;
+	u32 nid;
+	int r = -ENODATA;
+
+	np = of_node_get(device);
+
+	while (np) {
+		struct device_node *parent;
+
+		r = of_property_read_u32(np, "numa-node-id", &nid);
+		/*
+		 * -EINVAL indicates the property was not found, and
+		 *  we walk up the tree trying to find a parent with a
+		 *  "numa-node-id".  Any other type of error indicates
+		 *  a bad device tree and we give up.
+		 */
+		if (r != -EINVAL)
+			break;
+
+		parent = of_get_parent(np);
+		of_node_put(np);
+		np = parent;
+	}
+	if (np && r)
+		pr_warn("NUMA: Invalid \"numa-node-id\" property in node %s\n",
+			np->name);
+	of_node_put(np);
+
+	if (!r) {
+		if (nid >= MAX_NUMNODES)
+			pr_warn("NUMA: Node id %u exceeds maximum value\n",
+				nid);
+		else
+			return nid;
+	}
+
+	return NUMA_NO_NODE;
+}
+EXPORT_SYMBOL(of_node_to_nid);
+
+int __init of_numa_init(void)
+{
+	int r;
+
+	of_numa_parse_cpu_nodes();
+	r = of_numa_parse_memory_nodes();
+	if (r)
+		return r;
+	return of_numa_parse_distance_map();
+}
--- zfcpdump-kernel-4.4.orig/drivers/of/of_private.h
+++ zfcpdump-kernel-4.4/drivers/of/of_private.h
@@ -81,6 +81,9 @@ extern int __of_attach_node_sysfs(struct
 extern void __of_detach_node(struct device_node *np);
 extern void __of_detach_node_sysfs(struct device_node *np);
 
+extern void __of_sysfs_remove_bin_file(struct device_node *np,
+				       struct property *prop);
+
 /* iterators for transactions, used for overlays */
 /* forward iterator */
 #define for_each_transaction_entry(_oft, _te) \
--- zfcpdump-kernel-4.4.orig/drivers/of/of_reserved_mem.c
+++ zfcpdump-kernel-4.4/drivers/of/of_reserved_mem.c
@@ -32,11 +32,13 @@ int __init __weak early_init_dt_alloc_re
 	phys_addr_t align, phys_addr_t start, phys_addr_t end, bool nomap,
 	phys_addr_t *res_base)
 {
+	phys_addr_t base;
 	/*
 	 * We use __memblock_alloc_base() because memblock_alloc_base()
 	 * panic()s on allocation failure.
 	 */
-	phys_addr_t base = __memblock_alloc_base(size, align, end);
+	end = !end ? MEMBLOCK_ALLOC_ANYWHERE : end;
+	base = __memblock_alloc_base(size, align, end);
 	if (!base)
 		return -ENOMEM;
 
--- zfcpdump-kernel-4.4.orig/drivers/pci/Kconfig
+++ zfcpdump-kernel-4.4/drivers/pci/Kconfig
@@ -118,4 +118,11 @@ config PCI_LABEL
 	def_bool y if (DMI || ACPI)
 	select NLS
 
+config PCI_HYPERV
+        tristate "Hyper-V PCI Frontend"
+        depends on PCI && X86 && HYPERV && PCI_MSI && PCI_MSI_IRQ_DOMAIN && X86_64
+        help
+          The PCI device frontend driver allows the kernel to import arbitrary
+          PCI devices from a PCI backend to support PCI driver domains.
+
 source "drivers/pci/host/Kconfig"
--- zfcpdump-kernel-4.4.orig/drivers/pci/bus.c
+++ zfcpdump-kernel-4.4/drivers/pci/bus.c
@@ -140,6 +140,8 @@ static int pci_bus_alloc_from_region(str
 	type_mask |= IORESOURCE_TYPE_BITS;
 
 	pci_bus_for_each_resource(bus, r, i) {
+		resource_size_t min_used = min;
+
 		if (!r)
 			continue;
 
@@ -163,12 +165,12 @@ static int pci_bus_alloc_from_region(str
 		 * overrides "min".
 		 */
 		if (avail.start)
-			min = avail.start;
+			min_used = avail.start;
 
 		max = avail.end;
 
 		/* Ok, try it out.. */
-		ret = allocate_resource(r, res, size, min, max,
+		ret = allocate_resource(r, res, size, min_used, max,
 					align, alignf, alignf_data);
 		if (ret == 0)
 			return 0;
--- zfcpdump-kernel-4.4.orig/drivers/pci/host/Kconfig
+++ zfcpdump-kernel-4.4/drivers/pci/host/Kconfig
@@ -54,9 +54,13 @@ config PCI_RCAR_GEN2_PCIE
 	help
 	  Say Y here if you want PCIe controller support on R-Car Gen2 SoCs.
 
+config PCI_HOST_COMMON
+	bool
+
 config PCI_HOST_GENERIC
 	bool "Generic PCI host controller"
 	depends on (ARM || ARM64) && OF
+	select PCI_HOST_COMMON
 	help
 	  Say Y here if you want to support a simple generic PCI host
 	  controller, such as the one emulated by kvmtool.
@@ -173,4 +177,18 @@ config PCI_HISI
 	help
 	  Say Y here if you want PCIe controller support on HiSilicon HIP05 SoC
 
+config PCI_HOST_THUNDER_PEM
+	bool "Cavium Thunder PCIe controller to off-chip devices"
+	depends on OF && ARM64
+	select PCI_HOST_COMMON
+	help
+	  Say Y here if you want PCIe support for CN88XX Cavium Thunder SoCs.
+
+config PCI_HOST_THUNDER_ECAM
+	bool "Cavium Thunder ECAM controller to on-chip devices on pass-1.x silicon"
+	depends on OF && ARM64
+	select PCI_HOST_COMMON
+	help
+	  Say Y here if you want ECAM support for CN88XX-Pass-1.x Cavium Thunder SoCs.
+
 endmenu
--- zfcpdump-kernel-4.4.orig/drivers/pci/host/Makefile
+++ zfcpdump-kernel-4.4/drivers/pci/host/Makefile
@@ -2,10 +2,12 @@ obj-$(CONFIG_PCIE_DW) += pcie-designware
 obj-$(CONFIG_PCI_DRA7XX) += pci-dra7xx.o
 obj-$(CONFIG_PCI_EXYNOS) += pci-exynos.o
 obj-$(CONFIG_PCI_IMX6) += pci-imx6.o
+obj-$(CONFIG_PCI_HYPERV) += pci-hyperv.o
 obj-$(CONFIG_PCI_MVEBU) += pci-mvebu.o
 obj-$(CONFIG_PCI_TEGRA) += pci-tegra.o
 obj-$(CONFIG_PCI_RCAR_GEN2) += pci-rcar-gen2.o
 obj-$(CONFIG_PCI_RCAR_GEN2_PCIE) += pcie-rcar.o
+obj-$(CONFIG_PCI_HOST_COMMON) += pci-host-common.o
 obj-$(CONFIG_PCI_HOST_GENERIC) += pci-host-generic.o
 obj-$(CONFIG_PCIE_SPEAR13XX) += pcie-spear13xx.o
 obj-$(CONFIG_PCI_KEYSTONE) += pci-keystone-dw.o pci-keystone.o
@@ -20,3 +22,5 @@ obj-$(CONFIG_PCIE_IPROC_BCMA) += pcie-ip
 obj-$(CONFIG_PCIE_ALTERA) += pcie-altera.o
 obj-$(CONFIG_PCIE_ALTERA_MSI) += pcie-altera-msi.o
 obj-$(CONFIG_PCI_HISI) += pcie-hisi.o
+obj-$(CONFIG_PCI_HOST_THUNDER_ECAM) += pci-thunder-ecam.o
+obj-$(CONFIG_PCI_HOST_THUNDER_PEM) += pci-thunder-pem.o
--- zfcpdump-kernel-4.4.orig/drivers/pci/host/pci-dra7xx.c
+++ zfcpdump-kernel-4.4/drivers/pci/host/pci-dra7xx.c
@@ -302,7 +302,8 @@ static int __init dra7xx_add_pcie_port(s
 	}
 
 	ret = devm_request_irq(&pdev->dev, pp->irq,
-			       dra7xx_pcie_msi_irq_handler, IRQF_SHARED,
+			       dra7xx_pcie_msi_irq_handler,
+			       IRQF_SHARED | IRQF_NO_THREAD,
 			       "dra7-pcie-msi",	pp);
 	if (ret) {
 		dev_err(&pdev->dev, "failed to request irq\n");
--- zfcpdump-kernel-4.4.orig/drivers/pci/host/pci-exynos.c
+++ zfcpdump-kernel-4.4/drivers/pci/host/pci-exynos.c
@@ -522,7 +522,8 @@ static int __init exynos_add_pcie_port(s
 
 		ret = devm_request_irq(&pdev->dev, pp->msi_irq,
 					exynos_pcie_msi_irq_handler,
-					IRQF_SHARED, "exynos-pcie", pp);
+					IRQF_SHARED | IRQF_NO_THREAD,
+					"exynos-pcie", pp);
 		if (ret) {
 			dev_err(&pdev->dev, "failed to request msi irq\n");
 			return ret;
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/pci/host/pci-host-common.c
@@ -0,0 +1,194 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Copyright (C) 2014 ARM Limited
+ *
+ * Author: Will Deacon <will.deacon@arm.com>
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of_address.h>
+#include <linux/of_pci.h>
+#include <linux/platform_device.h>
+
+#include "pci-host-common.h"
+
+static void gen_pci_release_of_pci_ranges(struct gen_pci *pci)
+{
+	pci_free_resource_list(&pci->resources);
+}
+
+static int gen_pci_parse_request_of_pci_ranges(struct gen_pci *pci)
+{
+	int err, res_valid = 0;
+	struct device *dev = pci->host.dev.parent;
+	struct device_node *np = dev->of_node;
+	resource_size_t iobase;
+	struct resource_entry *win;
+
+	err = of_pci_get_host_bridge_resources(np, 0, 0xff, &pci->resources,
+					       &iobase);
+	if (err)
+		return err;
+
+	resource_list_for_each_entry(win, &pci->resources) {
+		struct resource *parent, *res = win->res;
+
+		switch (resource_type(res)) {
+		case IORESOURCE_IO:
+			parent = &ioport_resource;
+			err = pci_remap_iospace(res, iobase);
+			if (err) {
+				dev_warn(dev, "error %d: failed to map resource %pR\n",
+					 err, res);
+				continue;
+			}
+			break;
+		case IORESOURCE_MEM:
+			parent = &iomem_resource;
+			res_valid |= !(res->flags & IORESOURCE_PREFETCH);
+			break;
+		case IORESOURCE_BUS:
+			pci->cfg.bus_range = res;
+		default:
+			continue;
+		}
+
+		err = devm_request_resource(dev, parent, res);
+		if (err)
+			goto out_release_res;
+	}
+
+	if (!res_valid) {
+		dev_err(dev, "non-prefetchable memory resource required\n");
+		err = -EINVAL;
+		goto out_release_res;
+	}
+
+	return 0;
+
+out_release_res:
+	gen_pci_release_of_pci_ranges(pci);
+	return err;
+}
+
+static int gen_pci_parse_map_cfg_windows(struct gen_pci *pci)
+{
+	int err;
+	u8 bus_max;
+	resource_size_t busn;
+	struct resource *bus_range;
+	struct device *dev = pci->host.dev.parent;
+	struct device_node *np = dev->of_node;
+	u32 sz = 1 << pci->cfg.ops->bus_shift;
+
+	err = of_address_to_resource(np, 0, &pci->cfg.res);
+	if (err) {
+		dev_err(dev, "missing \"reg\" property\n");
+		return err;
+	}
+
+	/* Limit the bus-range to fit within reg */
+	bus_max = pci->cfg.bus_range->start +
+		  (resource_size(&pci->cfg.res) >> pci->cfg.ops->bus_shift) - 1;
+	pci->cfg.bus_range->end = min_t(resource_size_t,
+					pci->cfg.bus_range->end, bus_max);
+
+	pci->cfg.win = devm_kcalloc(dev, resource_size(pci->cfg.bus_range),
+				    sizeof(*pci->cfg.win), GFP_KERNEL);
+	if (!pci->cfg.win)
+		return -ENOMEM;
+
+	/* Map our Configuration Space windows */
+	if (!devm_request_mem_region(dev, pci->cfg.res.start,
+				     resource_size(&pci->cfg.res),
+				     "Configuration Space"))
+		return -ENOMEM;
+
+	bus_range = pci->cfg.bus_range;
+	for (busn = bus_range->start; busn <= bus_range->end; ++busn) {
+		u32 idx = busn - bus_range->start;
+
+		pci->cfg.win[idx] = devm_ioremap(dev,
+						 pci->cfg.res.start + idx * sz,
+						 sz);
+		if (!pci->cfg.win[idx])
+			return -ENOMEM;
+	}
+
+	return 0;
+}
+
+int pci_host_common_probe(struct platform_device *pdev,
+			  struct gen_pci *pci)
+{
+	int err;
+	const char *type;
+	struct device *dev = &pdev->dev;
+	struct device_node *np = dev->of_node;
+	struct pci_bus *bus, *child;
+
+	type = of_get_property(np, "device_type", NULL);
+	if (!type || strcmp(type, "pci")) {
+		dev_err(dev, "invalid \"device_type\" %s\n", type);
+		return -EINVAL;
+	}
+
+	of_pci_check_probe_only();
+
+	pci->host.dev.parent = dev;
+	INIT_LIST_HEAD(&pci->host.windows);
+	INIT_LIST_HEAD(&pci->resources);
+
+	/* Parse our PCI ranges and request their resources */
+	err = gen_pci_parse_request_of_pci_ranges(pci);
+	if (err)
+		return err;
+
+	/* Parse and map our Configuration Space windows */
+	err = gen_pci_parse_map_cfg_windows(pci);
+	if (err) {
+		gen_pci_release_of_pci_ranges(pci);
+		return err;
+	}
+
+	/* Do not reassign resources if probe only */
+	if (!pci_has_flag(PCI_PROBE_ONLY))
+		pci_add_flags(PCI_REASSIGN_ALL_RSRC | PCI_REASSIGN_ALL_BUS);
+
+
+	bus = pci_scan_root_bus(dev, pci->cfg.bus_range->start,
+				&pci->cfg.ops->ops, pci, &pci->resources);
+	if (!bus) {
+		dev_err(dev, "Scanning rootbus failed");
+		return -ENODEV;
+	}
+
+	pci_fixup_irqs(pci_common_swizzle, of_irq_parse_and_map_pci);
+
+	if (!pci_has_flag(PCI_PROBE_ONLY)) {
+		pci_bus_size_bridges(bus);
+		pci_bus_assign_resources(bus);
+
+		list_for_each_entry(child, &bus->children, node)
+			pcie_bus_configure_settings(child);
+	}
+
+	pci_bus_add_devices(bus);
+	return 0;
+}
+
+MODULE_DESCRIPTION("Generic PCI host driver common code");
+MODULE_AUTHOR("Will Deacon <will.deacon@arm.com>");
+MODULE_LICENSE("GPL v2");
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/pci/host/pci-host-common.h
@@ -0,0 +1,56 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Copyright (C) 2014 ARM Limited
+ *
+ * Author: Will Deacon <will.deacon@arm.com>
+ */
+
+#ifndef _PCI_HOST_COMMON_H
+#define _PCI_HOST_COMMON_H
+
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+
+struct gen_pci_cfg_bus_ops {
+	u32 bus_shift;
+	struct pci_ops ops;
+};
+
+struct gen_pci_cfg_windows {
+	struct resource				res;
+	struct resource				*bus_range;
+	void __iomem				**win;
+
+	struct gen_pci_cfg_bus_ops		*ops;
+};
+
+/*
+ * ARM pcibios functions expect the ARM struct pci_sys_data as the PCI
+ * sysdata.  Add pci_sys_data as the first element in struct gen_pci so
+ * that when we use a gen_pci pointer as sysdata, it is also a pointer to
+ * a struct pci_sys_data.
+ */
+struct gen_pci {
+#ifdef CONFIG_ARM
+	struct pci_sys_data			sys;
+#endif
+	struct pci_host_bridge			host;
+	struct gen_pci_cfg_windows		cfg;
+	struct list_head			resources;
+};
+
+int pci_host_common_probe(struct platform_device *pdev,
+			  struct gen_pci *pci);
+
+#endif /* _PCI_HOST_COMMON_H */
--- zfcpdump-kernel-4.4.orig/drivers/pci/host/pci-host-generic.c
+++ zfcpdump-kernel-4.4/drivers/pci/host/pci-host-generic.c
@@ -25,33 +25,7 @@
 #include <linux/of_pci.h>
 #include <linux/platform_device.h>
 
-struct gen_pci_cfg_bus_ops {
-	u32 bus_shift;
-	struct pci_ops ops;
-};
-
-struct gen_pci_cfg_windows {
-	struct resource				res;
-	struct resource				*bus_range;
-	void __iomem				**win;
-
-	struct gen_pci_cfg_bus_ops		*ops;
-};
-
-/*
- * ARM pcibios functions expect the ARM struct pci_sys_data as the PCI
- * sysdata.  Add pci_sys_data as the first element in struct gen_pci so
- * that when we use a gen_pci pointer as sysdata, it is also a pointer to
- * a struct pci_sys_data.
- */
-struct gen_pci {
-#ifdef CONFIG_ARM
-	struct pci_sys_data			sys;
-#endif
-	struct pci_host_bridge			host;
-	struct gen_pci_cfg_windows		cfg;
-	struct list_head			resources;
-};
+#include "pci-host-common.h"
 
 static void __iomem *gen_pci_map_cfg_bus_cam(struct pci_bus *bus,
 					     unsigned int devfn,
@@ -102,175 +76,19 @@ static const struct of_device_id gen_pci
 };
 MODULE_DEVICE_TABLE(of, gen_pci_of_match);
 
-static void gen_pci_release_of_pci_ranges(struct gen_pci *pci)
-{
-	pci_free_resource_list(&pci->resources);
-}
-
-static int gen_pci_parse_request_of_pci_ranges(struct gen_pci *pci)
-{
-	int err, res_valid = 0;
-	struct device *dev = pci->host.dev.parent;
-	struct device_node *np = dev->of_node;
-	resource_size_t iobase;
-	struct resource_entry *win;
-
-	err = of_pci_get_host_bridge_resources(np, 0, 0xff, &pci->resources,
-					       &iobase);
-	if (err)
-		return err;
-
-	resource_list_for_each_entry(win, &pci->resources) {
-		struct resource *parent, *res = win->res;
-
-		switch (resource_type(res)) {
-		case IORESOURCE_IO:
-			parent = &ioport_resource;
-			err = pci_remap_iospace(res, iobase);
-			if (err) {
-				dev_warn(dev, "error %d: failed to map resource %pR\n",
-					 err, res);
-				continue;
-			}
-			break;
-		case IORESOURCE_MEM:
-			parent = &iomem_resource;
-			res_valid |= !(res->flags & IORESOURCE_PREFETCH);
-			break;
-		case IORESOURCE_BUS:
-			pci->cfg.bus_range = res;
-		default:
-			continue;
-		}
-
-		err = devm_request_resource(dev, parent, res);
-		if (err)
-			goto out_release_res;
-	}
-
-	if (!res_valid) {
-		dev_err(dev, "non-prefetchable memory resource required\n");
-		err = -EINVAL;
-		goto out_release_res;
-	}
-
-	return 0;
-
-out_release_res:
-	gen_pci_release_of_pci_ranges(pci);
-	return err;
-}
-
-static int gen_pci_parse_map_cfg_windows(struct gen_pci *pci)
-{
-	int err;
-	u8 bus_max;
-	resource_size_t busn;
-	struct resource *bus_range;
-	struct device *dev = pci->host.dev.parent;
-	struct device_node *np = dev->of_node;
-	u32 sz = 1 << pci->cfg.ops->bus_shift;
-
-	err = of_address_to_resource(np, 0, &pci->cfg.res);
-	if (err) {
-		dev_err(dev, "missing \"reg\" property\n");
-		return err;
-	}
-
-	/* Limit the bus-range to fit within reg */
-	bus_max = pci->cfg.bus_range->start +
-		  (resource_size(&pci->cfg.res) >> pci->cfg.ops->bus_shift) - 1;
-	pci->cfg.bus_range->end = min_t(resource_size_t,
-					pci->cfg.bus_range->end, bus_max);
-
-	pci->cfg.win = devm_kcalloc(dev, resource_size(pci->cfg.bus_range),
-				    sizeof(*pci->cfg.win), GFP_KERNEL);
-	if (!pci->cfg.win)
-		return -ENOMEM;
-
-	/* Map our Configuration Space windows */
-	if (!devm_request_mem_region(dev, pci->cfg.res.start,
-				     resource_size(&pci->cfg.res),
-				     "Configuration Space"))
-		return -ENOMEM;
-
-	bus_range = pci->cfg.bus_range;
-	for (busn = bus_range->start; busn <= bus_range->end; ++busn) {
-		u32 idx = busn - bus_range->start;
-
-		pci->cfg.win[idx] = devm_ioremap(dev,
-						 pci->cfg.res.start + idx * sz,
-						 sz);
-		if (!pci->cfg.win[idx])
-			return -ENOMEM;
-	}
-
-	return 0;
-}
-
 static int gen_pci_probe(struct platform_device *pdev)
 {
-	int err;
-	const char *type;
-	const struct of_device_id *of_id;
 	struct device *dev = &pdev->dev;
-	struct device_node *np = dev->of_node;
+	const struct of_device_id *of_id;
 	struct gen_pci *pci = devm_kzalloc(dev, sizeof(*pci), GFP_KERNEL);
-	struct pci_bus *bus, *child;
 
 	if (!pci)
 		return -ENOMEM;
 
-	type = of_get_property(np, "device_type", NULL);
-	if (!type || strcmp(type, "pci")) {
-		dev_err(dev, "invalid \"device_type\" %s\n", type);
-		return -EINVAL;
-	}
-
-	of_pci_check_probe_only();
-
-	of_id = of_match_node(gen_pci_of_match, np);
+	of_id = of_match_node(gen_pci_of_match, dev->of_node);
 	pci->cfg.ops = (struct gen_pci_cfg_bus_ops *)of_id->data;
-	pci->host.dev.parent = dev;
-	INIT_LIST_HEAD(&pci->host.windows);
-	INIT_LIST_HEAD(&pci->resources);
-
-	/* Parse our PCI ranges and request their resources */
-	err = gen_pci_parse_request_of_pci_ranges(pci);
-	if (err)
-		return err;
-
-	/* Parse and map our Configuration Space windows */
-	err = gen_pci_parse_map_cfg_windows(pci);
-	if (err) {
-		gen_pci_release_of_pci_ranges(pci);
-		return err;
-	}
-
-	/* Do not reassign resources if probe only */
-	if (!pci_has_flag(PCI_PROBE_ONLY))
-		pci_add_flags(PCI_REASSIGN_ALL_RSRC | PCI_REASSIGN_ALL_BUS);
-
-
-	bus = pci_scan_root_bus(dev, pci->cfg.bus_range->start,
-				&pci->cfg.ops->ops, pci, &pci->resources);
-	if (!bus) {
-		dev_err(dev, "Scanning rootbus failed");
-		return -ENODEV;
-	}
-
-	pci_fixup_irqs(pci_common_swizzle, of_irq_parse_and_map_pci);
-
-	if (!pci_has_flag(PCI_PROBE_ONLY)) {
-		pci_bus_size_bridges(bus);
-		pci_bus_assign_resources(bus);
-
-		list_for_each_entry(child, &bus->children, node)
-			pcie_bus_configure_settings(child);
-	}
 
-	pci_bus_add_devices(bus);
-	return 0;
+	return pci_host_common_probe(pdev, pci);
 }
 
 static struct platform_driver gen_pci_driver = {
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/pci/host/pci-hyperv.c
@@ -0,0 +1,2364 @@
+/*
+ * Copyright (c) Microsoft Corporation.
+ *
+ * Author:
+ *   Jake Oshins <jakeo@microsoft.com>
+ *
+ * This driver acts as a paravirtual front-end for PCI Express root buses.
+ * When a PCI Express function (either an entire device or an SR-IOV
+ * Virtual Function) is being passed through to the VM, this driver exposes
+ * a new bus to the guest VM.  This is modeled as a root PCI bus because
+ * no bridges are being exposed to the VM.  In fact, with a "Generation 2"
+ * VM within Hyper-V, there may seem to be no PCI bus at all in the VM
+ * until a device as been exposed using this driver.
+ *
+ * Each root PCI bus has its own PCI domain, which is called "Segment" in
+ * the PCI Firmware Specifications.  Thus while each device passed through
+ * to the VM using this front-end will appear at "device 0", the domain will
+ * be unique.  Typically, each bus will have one PCI function on it, though
+ * this driver does support more than one.
+ *
+ * In order to map the interrupts from the device through to the guest VM,
+ * this driver also implements an IRQ Domain, which handles interrupts (either
+ * MSI or MSI-X) associated with the functions on the bus.  As interrupts are
+ * set up, torn down, or reaffined, this driver communicates with the
+ * underlying hypervisor to adjust the mappings in the I/O MMU so that each
+ * interrupt will be delivered to the correct virtual processor at the right
+ * vector.  This driver does not support level-triggered (line-based)
+ * interrupts, and will report that the Interrupt Line register in the
+ * function's configuration space is zero.
+ *
+ * The rest of this driver mostly maps PCI concepts onto underlying Hyper-V
+ * facilities.  For instance, the configuration space of a function exposed
+ * by Hyper-V is mapped into a single page of memory space, and the
+ * read and write handlers for config space must be aware of this mechanism.
+ * Similarly, device setup and teardown involves messages sent to and from
+ * the PCI back-end driver in Hyper-V.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ * NON INFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/semaphore.h>
+#include <linux/irqdomain.h>
+#include <asm/irqdomain.h>
+#include <asm/apic.h>
+#include <linux/msi.h>
+#include <linux/hyperv.h>
+#include <asm/mshyperv.h>
+
+/*
+ * Protocol versions. The low word is the minor version, the high word the
+ * major version.
+ */
+
+#define PCI_MAKE_VERSION(major, minor) ((u32)(((major) << 16) | (major)))
+#define PCI_MAJOR_VERSION(version) ((u32)(version) >> 16)
+#define PCI_MINOR_VERSION(version) ((u32)(version) & 0xff)
+
+enum {
+	PCI_PROTOCOL_VERSION_1_1 = PCI_MAKE_VERSION(1, 1),
+	PCI_PROTOCOL_VERSION_CURRENT = PCI_PROTOCOL_VERSION_1_1
+};
+
+#define PCI_CONFIG_MMIO_LENGTH	0x2000
+#define CFG_PAGE_OFFSET 0x1000
+#define CFG_PAGE_SIZE (PCI_CONFIG_MMIO_LENGTH - CFG_PAGE_OFFSET)
+
+#define MAX_SUPPORTED_MSI_MESSAGES 0x400
+
+/*
+ * Message Types
+ */
+
+enum pci_message_type {
+	/*
+	 * Version 1.1
+	 */
+	PCI_MESSAGE_BASE                = 0x42490000,
+	PCI_BUS_RELATIONS               = PCI_MESSAGE_BASE + 0,
+	PCI_QUERY_BUS_RELATIONS         = PCI_MESSAGE_BASE + 1,
+	PCI_POWER_STATE_CHANGE          = PCI_MESSAGE_BASE + 4,
+	PCI_QUERY_RESOURCE_REQUIREMENTS = PCI_MESSAGE_BASE + 5,
+	PCI_QUERY_RESOURCE_RESOURCES    = PCI_MESSAGE_BASE + 6,
+	PCI_BUS_D0ENTRY                 = PCI_MESSAGE_BASE + 7,
+	PCI_BUS_D0EXIT                  = PCI_MESSAGE_BASE + 8,
+	PCI_READ_BLOCK                  = PCI_MESSAGE_BASE + 9,
+	PCI_WRITE_BLOCK                 = PCI_MESSAGE_BASE + 0xA,
+	PCI_EJECT                       = PCI_MESSAGE_BASE + 0xB,
+	PCI_QUERY_STOP                  = PCI_MESSAGE_BASE + 0xC,
+	PCI_REENABLE                    = PCI_MESSAGE_BASE + 0xD,
+	PCI_QUERY_STOP_FAILED           = PCI_MESSAGE_BASE + 0xE,
+	PCI_EJECTION_COMPLETE           = PCI_MESSAGE_BASE + 0xF,
+	PCI_RESOURCES_ASSIGNED          = PCI_MESSAGE_BASE + 0x10,
+	PCI_RESOURCES_RELEASED          = PCI_MESSAGE_BASE + 0x11,
+	PCI_INVALIDATE_BLOCK            = PCI_MESSAGE_BASE + 0x12,
+	PCI_QUERY_PROTOCOL_VERSION      = PCI_MESSAGE_BASE + 0x13,
+	PCI_CREATE_INTERRUPT_MESSAGE    = PCI_MESSAGE_BASE + 0x14,
+	PCI_DELETE_INTERRUPT_MESSAGE    = PCI_MESSAGE_BASE + 0x15,
+	PCI_MESSAGE_MAXIMUM
+};
+
+/*
+ * Structures defining the virtual PCI Express protocol.
+ */
+
+union pci_version {
+	struct {
+		u16 minor_version;
+		u16 major_version;
+	} parts;
+	u32 version;
+} __packed;
+
+/*
+ * Function numbers are 8-bits wide on Express, as interpreted through ARI,
+ * which is all this driver does.  This representation is the one used in
+ * Windows, which is what is expected when sending this back and forth with
+ * the Hyper-V parent partition.
+ */
+union win_slot_encoding {
+	struct {
+		u32	func:8;
+		u32	reserved:24;
+	} bits;
+	u32 slot;
+} __packed;
+
+/*
+ * Pretty much as defined in the PCI Specifications.
+ */
+struct pci_function_description {
+	u16	v_id;	/* vendor ID */
+	u16	d_id;	/* device ID */
+	u8	rev;
+	u8	prog_intf;
+	u8	subclass;
+	u8	base_class;
+	u32	subsystem_id;
+	union win_slot_encoding win_slot;
+	u32	ser;	/* serial number */
+} __packed;
+
+/**
+ * struct hv_msi_desc
+ * @vector:		IDT entry
+ * @delivery_mode:	As defined in Intel's Programmer's
+ *			Reference Manual, Volume 3, Chapter 8.
+ * @vector_count:	Number of contiguous entries in the
+ *			Interrupt Descriptor Table that are
+ *			occupied by this Message-Signaled
+ *			Interrupt. For "MSI", as first defined
+ *			in PCI 2.2, this can be between 1 and
+ *			32. For "MSI-X," as first defined in PCI
+ *			3.0, this must be 1, as each MSI-X table
+ *			entry would have its own descriptor.
+ * @reserved:		Empty space
+ * @cpu_mask:		All the target virtual processors.
+ */
+struct hv_msi_desc {
+	u8	vector;
+	u8	delivery_mode;
+	u16	vector_count;
+	u32	reserved;
+	u64	cpu_mask;
+} __packed;
+
+/**
+ * struct tran_int_desc
+ * @reserved:		unused, padding
+ * @vector_count:	same as in hv_msi_desc
+ * @data:		This is the "data payload" value that is
+ *			written by the device when it generates
+ *			a message-signaled interrupt, either MSI
+ *			or MSI-X.
+ * @address:		This is the address to which the data
+ *			payload is written on interrupt
+ *			generation.
+ */
+struct tran_int_desc {
+	u16	reserved;
+	u16	vector_count;
+	u32	data;
+	u64	address;
+} __packed;
+
+/*
+ * A generic message format for virtual PCI.
+ * Specific message formats are defined later in the file.
+ */
+
+struct pci_message {
+	u32 message_type;
+} __packed;
+
+struct pci_child_message {
+	u32 message_type;
+	union win_slot_encoding wslot;
+} __packed;
+
+struct pci_incoming_message {
+	struct vmpacket_descriptor hdr;
+	struct pci_message message_type;
+} __packed;
+
+struct pci_response {
+	struct vmpacket_descriptor hdr;
+	s32 status;			/* negative values are failures */
+} __packed;
+
+struct pci_packet {
+	void (*completion_func)(void *context, struct pci_response *resp,
+				int resp_packet_size);
+	void *compl_ctxt;
+	struct pci_message message;
+};
+
+/*
+ * Specific message types supporting the PCI protocol.
+ */
+
+/*
+ * Version negotiation message. Sent from the guest to the host.
+ * The guest is free to try different versions until the host
+ * accepts the version.
+ *
+ * pci_version: The protocol version requested.
+ * is_last_attempt: If TRUE, this is the last version guest will request.
+ * reservedz: Reserved field, set to zero.
+ */
+
+struct pci_version_request {
+	struct pci_message message_type;
+	enum pci_message_type protocol_version;
+} __packed;
+
+/*
+ * Bus D0 Entry.  This is sent from the guest to the host when the virtual
+ * bus (PCI Express port) is ready for action.
+ */
+
+struct pci_bus_d0_entry {
+	struct pci_message message_type;
+	u32 reserved;
+	u64 mmio_base;
+} __packed;
+
+struct pci_bus_relations {
+	struct pci_incoming_message incoming;
+	u32 device_count;
+	struct pci_function_description func[1];
+} __packed;
+
+struct pci_q_res_req_response {
+	struct vmpacket_descriptor hdr;
+	s32 status;			/* negative values are failures */
+	u32 probed_bar[6];
+} __packed;
+
+struct pci_set_power {
+	struct pci_message message_type;
+	union win_slot_encoding wslot;
+	u32 power_state;		/* In Windows terms */
+	u32 reserved;
+} __packed;
+
+struct pci_set_power_response {
+	struct vmpacket_descriptor hdr;
+	s32 status;			/* negative values are failures */
+	union win_slot_encoding wslot;
+	u32 resultant_state;		/* In Windows terms */
+	u32 reserved;
+} __packed;
+
+struct pci_resources_assigned {
+	struct pci_message message_type;
+	union win_slot_encoding wslot;
+	u8 memory_range[0x14][6];	/* not used here */
+	u32 msi_descriptors;
+	u32 reserved[4];
+} __packed;
+
+struct pci_create_interrupt {
+	struct pci_message message_type;
+	union win_slot_encoding wslot;
+	struct hv_msi_desc int_desc;
+} __packed;
+
+struct pci_create_int_response {
+	struct pci_response response;
+	u32 reserved;
+	struct tran_int_desc int_desc;
+} __packed;
+
+struct pci_delete_interrupt {
+	struct pci_message message_type;
+	union win_slot_encoding wslot;
+	struct tran_int_desc int_desc;
+} __packed;
+
+struct pci_dev_incoming {
+	struct pci_incoming_message incoming;
+	union win_slot_encoding wslot;
+} __packed;
+
+struct pci_eject_response {
+	u32 message_type;
+	union win_slot_encoding wslot;
+	u32 status;
+} __packed;
+
+static int pci_ring_size = (4 * PAGE_SIZE);
+
+/*
+ * Definitions or interrupt steering hypercall.
+ */
+#define HV_PARTITION_ID_SELF		((u64)-1)
+#define HVCALL_RETARGET_INTERRUPT	0x7e
+
+struct retarget_msi_interrupt {
+	u64	partition_id;		/* use "self" */
+	u64	device_id;
+	u32	source;			/* 1 for MSI(-X) */
+	u32	reserved1;
+	u32	address;
+	u32	data;
+	u64	reserved2;
+	u32	vector;
+	u32	flags;
+	u64	vp_mask;
+} __packed;
+
+/*
+ * Driver specific state.
+ */
+
+enum hv_pcibus_state {
+	hv_pcibus_init = 0,
+	hv_pcibus_probed,
+	hv_pcibus_installed,
+	hv_pcibus_maximum
+};
+
+struct hv_pcibus_device {
+	struct pci_sysdata sysdata;
+	enum hv_pcibus_state state;
+	atomic_t remove_lock;
+	struct hv_device *hdev;
+	resource_size_t low_mmio_space;
+	resource_size_t high_mmio_space;
+	struct resource *mem_config;
+	struct resource *low_mmio_res;
+	struct resource *high_mmio_res;
+	struct completion *survey_event;
+	struct completion remove_event;
+	struct pci_bus *pci_bus;
+	spinlock_t config_lock;	/* Avoid two threads writing index page */
+	spinlock_t device_list_lock;	/* Protect lists below */
+	void __iomem *cfg_addr;
+
+	struct semaphore enum_sem;
+	struct list_head resources_for_children;
+
+	struct list_head children;
+	struct list_head dr_list;
+	struct work_struct wrk;
+
+	struct msi_domain_info msi_info;
+	struct msi_controller msi_chip;
+	struct irq_domain *irq_domain;
+};
+
+/*
+ * Tracks "Device Relations" messages from the host, which must be both
+ * processed in order and deferred so that they don't run in the context
+ * of the incoming packet callback.
+ */
+struct hv_dr_work {
+	struct work_struct wrk;
+	struct hv_pcibus_device *bus;
+};
+
+struct hv_dr_state {
+	struct list_head list_entry;
+	u32 device_count;
+	struct pci_function_description func[1];
+};
+
+enum hv_pcichild_state {
+	hv_pcichild_init = 0,
+	hv_pcichild_requirements,
+	hv_pcichild_resourced,
+	hv_pcichild_ejecting,
+	hv_pcichild_maximum
+};
+
+enum hv_pcidev_ref_reason {
+	hv_pcidev_ref_invalid = 0,
+	hv_pcidev_ref_initial,
+	hv_pcidev_ref_by_slot,
+	hv_pcidev_ref_packet,
+	hv_pcidev_ref_pnp,
+	hv_pcidev_ref_childlist,
+	hv_pcidev_irqdata,
+	hv_pcidev_ref_max
+};
+
+struct hv_pci_dev {
+	/* List protected by pci_rescan_remove_lock */
+	struct list_head list_entry;
+	atomic_t refs;
+	enum hv_pcichild_state state;
+	struct pci_function_description desc;
+	bool reported_missing;
+	struct hv_pcibus_device *hbus;
+	struct work_struct wrk;
+
+	/*
+	 * What would be observed if one wrote 0xFFFFFFFF to a BAR and then
+	 * read it back, for each of the BAR offsets within config space.
+	 */
+	u32 probed_bar[6];
+};
+
+struct hv_pci_compl {
+	struct completion host_event;
+	s32 completion_status;
+};
+
+/**
+ * hv_pci_generic_compl() - Invoked for a completion packet
+ * @context:		Set up by the sender of the packet.
+ * @resp:		The response packet
+ * @resp_packet_size:	Size in bytes of the packet
+ *
+ * This function is used to trigger an event and report status
+ * for any message for which the completion packet contains a
+ * status and nothing else.
+ */
+static
+void
+hv_pci_generic_compl(void *context, struct pci_response *resp,
+		     int resp_packet_size)
+{
+	struct hv_pci_compl *comp_pkt = context;
+
+	if (resp_packet_size >= offsetofend(struct pci_response, status))
+		comp_pkt->completion_status = resp->status;
+	complete(&comp_pkt->host_event);
+}
+
+static struct hv_pci_dev *get_pcichild_wslot(struct hv_pcibus_device *hbus,
+						u32 wslot);
+static void get_pcichild(struct hv_pci_dev *hv_pcidev,
+			 enum hv_pcidev_ref_reason reason);
+static void put_pcichild(struct hv_pci_dev *hv_pcidev,
+			 enum hv_pcidev_ref_reason reason);
+
+static void get_hvpcibus(struct hv_pcibus_device *hv_pcibus);
+static void put_hvpcibus(struct hv_pcibus_device *hv_pcibus);
+
+/**
+ * devfn_to_wslot() - Convert from Linux PCI slot to Windows
+ * @devfn:	The Linux representation of PCI slot
+ *
+ * Windows uses a slightly different representation of PCI slot.
+ *
+ * Return: The Windows representation
+ */
+static u32 devfn_to_wslot(int devfn)
+{
+	union win_slot_encoding wslot;
+
+	wslot.slot = 0;
+	wslot.bits.func = PCI_SLOT(devfn) | (PCI_FUNC(devfn) << 5);
+
+	return wslot.slot;
+}
+
+/**
+ * wslot_to_devfn() - Convert from Windows PCI slot to Linux
+ * @wslot:	The Windows representation of PCI slot
+ *
+ * Windows uses a slightly different representation of PCI slot.
+ *
+ * Return: The Linux representation
+ */
+static int wslot_to_devfn(u32 wslot)
+{
+	union win_slot_encoding slot_no;
+
+	slot_no.slot = wslot;
+	return PCI_DEVFN(0, slot_no.bits.func);
+}
+
+/*
+ * PCI Configuration Space for these root PCI buses is implemented as a pair
+ * of pages in memory-mapped I/O space.  Writing to the first page chooses
+ * the PCI function being written or read.  Once the first page has been
+ * written to, the following page maps in the entire configuration space of
+ * the function.
+ */
+
+/**
+ * _hv_pcifront_read_config() - Internal PCI config read
+ * @hpdev:	The PCI driver's representation of the device
+ * @where:	Offset within config space
+ * @size:	Size of the transfer
+ * @val:	Pointer to the buffer receiving the data
+ */
+static void _hv_pcifront_read_config(struct hv_pci_dev *hpdev, int where,
+				     int size, u32 *val)
+{
+	unsigned long flags;
+	void __iomem *addr = hpdev->hbus->cfg_addr + CFG_PAGE_OFFSET + where;
+
+	/*
+	 * If the attempt is to read the IDs or the ROM BAR, simulate that.
+	 */
+	if (where + size <= PCI_COMMAND) {
+		memcpy(val, ((u8 *)&hpdev->desc.v_id) + where, size);
+	} else if (where >= PCI_CLASS_REVISION && where + size <=
+		   PCI_CACHE_LINE_SIZE) {
+		memcpy(val, ((u8 *)&hpdev->desc.rev) + where -
+		       PCI_CLASS_REVISION, size);
+	} else if (where >= PCI_SUBSYSTEM_VENDOR_ID && where + size <=
+		   PCI_ROM_ADDRESS) {
+		memcpy(val, (u8 *)&hpdev->desc.subsystem_id + where -
+		       PCI_SUBSYSTEM_VENDOR_ID, size);
+	} else if (where >= PCI_ROM_ADDRESS && where + size <=
+		   PCI_CAPABILITY_LIST) {
+		/* ROM BARs are unimplemented */
+		*val = 0;
+	} else if (where >= PCI_INTERRUPT_LINE && where + size <=
+		   PCI_INTERRUPT_PIN) {
+		/*
+		 * Interrupt Line and Interrupt PIN are hard-wired to zero
+		 * because this front-end only supports message-signaled
+		 * interrupts.
+		 */
+		*val = 0;
+	} else if (where + size <= CFG_PAGE_SIZE) {
+		spin_lock_irqsave(&hpdev->hbus->config_lock, flags);
+		/* Choose the function to be read. (See comment above) */
+		writel(hpdev->desc.win_slot.slot, hpdev->hbus->cfg_addr);
+		/* Make sure the function was chosen before we start reading. */
+		mb();
+		/* Read from that function's config space. */
+		switch (size) {
+		case 1:
+			*val = readb(addr);
+			break;
+		case 2:
+			*val = readw(addr);
+			break;
+		default:
+			*val = readl(addr);
+			break;
+		}
+		/*
+		 * Make sure the write was done before we release the spinlock
+		 * allowing consecutive reads/writes.
+		 */
+		mb();
+		spin_unlock_irqrestore(&hpdev->hbus->config_lock, flags);
+	} else {
+		dev_err(&hpdev->hbus->hdev->device,
+			"Attempt to read beyond a function's config space.\n");
+	}
+}
+
+/**
+ * _hv_pcifront_write_config() - Internal PCI config write
+ * @hpdev:	The PCI driver's representation of the device
+ * @where:	Offset within config space
+ * @size:	Size of the transfer
+ * @val:	The data being transferred
+ */
+static void _hv_pcifront_write_config(struct hv_pci_dev *hpdev, int where,
+				      int size, u32 val)
+{
+	unsigned long flags;
+	void __iomem *addr = hpdev->hbus->cfg_addr + CFG_PAGE_OFFSET + where;
+
+	if (where >= PCI_SUBSYSTEM_VENDOR_ID &&
+	    where + size <= PCI_CAPABILITY_LIST) {
+		/* SSIDs and ROM BARs are read-only */
+	} else if (where >= PCI_COMMAND && where + size <= CFG_PAGE_SIZE) {
+		spin_lock_irqsave(&hpdev->hbus->config_lock, flags);
+		/* Choose the function to be written. (See comment above) */
+		writel(hpdev->desc.win_slot.slot, hpdev->hbus->cfg_addr);
+		/* Make sure the function was chosen before we start writing. */
+		wmb();
+		/* Write to that function's config space. */
+		switch (size) {
+		case 1:
+			writeb(val, addr);
+			break;
+		case 2:
+			writew(val, addr);
+			break;
+		default:
+			writel(val, addr);
+			break;
+		}
+		/*
+		 * Make sure the write was done before we release the spinlock
+		 * allowing consecutive reads/writes.
+		 */
+		mb();
+		spin_unlock_irqrestore(&hpdev->hbus->config_lock, flags);
+	} else {
+		dev_err(&hpdev->hbus->hdev->device,
+			"Attempt to write beyond a function's config space.\n");
+	}
+}
+
+/**
+ * hv_pcifront_read_config() - Read configuration space
+ * @bus: PCI Bus structure
+ * @devfn: Device/function
+ * @where: Offset from base
+ * @size: Byte/word/dword
+ * @val: Value to be read
+ *
+ * Return: PCIBIOS_SUCCESSFUL on success
+ *	   PCIBIOS_DEVICE_NOT_FOUND on failure
+ */
+static int hv_pcifront_read_config(struct pci_bus *bus, unsigned int devfn,
+				   int where, int size, u32 *val)
+{
+	struct hv_pcibus_device *hbus =
+		container_of(bus->sysdata, struct hv_pcibus_device, sysdata);
+	struct hv_pci_dev *hpdev;
+
+	hpdev = get_pcichild_wslot(hbus, devfn_to_wslot(devfn));
+	if (!hpdev)
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	_hv_pcifront_read_config(hpdev, where, size, val);
+
+	put_pcichild(hpdev, hv_pcidev_ref_by_slot);
+	return PCIBIOS_SUCCESSFUL;
+}
+
+/**
+ * hv_pcifront_write_config() - Write configuration space
+ * @bus: PCI Bus structure
+ * @devfn: Device/function
+ * @where: Offset from base
+ * @size: Byte/word/dword
+ * @val: Value to be written to device
+ *
+ * Return: PCIBIOS_SUCCESSFUL on success
+ *	   PCIBIOS_DEVICE_NOT_FOUND on failure
+ */
+static int hv_pcifront_write_config(struct pci_bus *bus, unsigned int devfn,
+				    int where, int size, u32 val)
+{
+	struct hv_pcibus_device *hbus =
+	    container_of(bus->sysdata, struct hv_pcibus_device, sysdata);
+	struct hv_pci_dev *hpdev;
+
+	hpdev = get_pcichild_wslot(hbus, devfn_to_wslot(devfn));
+	if (!hpdev)
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	_hv_pcifront_write_config(hpdev, where, size, val);
+
+	put_pcichild(hpdev, hv_pcidev_ref_by_slot);
+	return PCIBIOS_SUCCESSFUL;
+}
+
+/* PCIe operations */
+static struct pci_ops hv_pcifront_ops = {
+	.read  = hv_pcifront_read_config,
+	.write = hv_pcifront_write_config,
+};
+
+/* Interrupt management hooks */
+static void hv_int_desc_free(struct hv_pci_dev *hpdev,
+			     struct tran_int_desc *int_desc)
+{
+	struct pci_delete_interrupt *int_pkt;
+	struct {
+		struct pci_packet pkt;
+		u8 buffer[sizeof(struct pci_delete_interrupt) -
+			  sizeof(struct pci_message)];
+	} ctxt;
+
+	memset(&ctxt, 0, sizeof(ctxt));
+	int_pkt = (struct pci_delete_interrupt *)&ctxt.pkt.message;
+	int_pkt->message_type.message_type =
+		PCI_DELETE_INTERRUPT_MESSAGE;
+	int_pkt->wslot.slot = hpdev->desc.win_slot.slot;
+	int_pkt->int_desc = *int_desc;
+	vmbus_sendpacket(hpdev->hbus->hdev->channel, int_pkt, sizeof(*int_pkt),
+			 (unsigned long)&ctxt.pkt, VM_PKT_DATA_INBAND, 0);
+	kfree(int_desc);
+}
+
+/**
+ * hv_msi_free() - Free the MSI.
+ * @domain:	The interrupt domain pointer
+ * @info:	Extra MSI-related context
+ * @irq:	Identifies the IRQ.
+ *
+ * The Hyper-V parent partition and hypervisor are tracking the
+ * messages that are in use, keeping the interrupt redirection
+ * table up to date.  This callback sends a message that frees
+ * the IRT entry and related tracking nonsense.
+ */
+static void hv_msi_free(struct irq_domain *domain, struct msi_domain_info *info,
+			unsigned int irq)
+{
+	struct hv_pcibus_device *hbus;
+	struct hv_pci_dev *hpdev;
+	struct pci_dev *pdev;
+	struct tran_int_desc *int_desc;
+	struct irq_data *irq_data = irq_domain_get_irq_data(domain, irq);
+	struct msi_desc *msi = irq_data_get_msi_desc(irq_data);
+
+	pdev = msi_desc_to_pci_dev(msi);
+	hbus = info->data;
+	int_desc = irq_data_get_irq_chip_data(irq_data);
+	if (!int_desc)
+		return;
+
+	irq_data->chip_data = NULL;
+	hpdev = get_pcichild_wslot(hbus, devfn_to_wslot(pdev->devfn));
+	if (!hpdev) {
+		kfree(int_desc);
+		return;
+	}
+
+	hv_int_desc_free(hpdev, int_desc);
+	put_pcichild(hpdev, hv_pcidev_ref_by_slot);
+}
+
+static int hv_set_affinity(struct irq_data *data, const struct cpumask *dest,
+			   bool force)
+{
+	struct irq_data *parent = data->parent_data;
+
+	return parent->chip->irq_set_affinity(parent, dest, force);
+}
+
+void hv_irq_mask(struct irq_data *data)
+{
+	pci_msi_mask_irq(data);
+}
+
+/**
+ * hv_irq_unmask() - "Unmask" the IRQ by setting its current
+ * affinity.
+ * @data:	Describes the IRQ
+ *
+ * Build new a destination for the MSI and make a hypercall to
+ * update the Interrupt Redirection Table. "Device Logical ID"
+ * is built out of this PCI bus's instance GUID and the function
+ * number of the device.
+ */
+void hv_irq_unmask(struct irq_data *data)
+{
+	struct msi_desc *msi_desc = irq_data_get_msi_desc(data);
+	struct irq_cfg *cfg = irqd_cfg(data);
+	struct retarget_msi_interrupt params;
+	struct hv_pcibus_device *hbus;
+	struct cpumask *dest;
+	struct pci_bus *pbus;
+	struct pci_dev *pdev;
+	int cpu;
+
+	dest = irq_data_get_affinity_mask(data);
+	pdev = msi_desc_to_pci_dev(msi_desc);
+	pbus = pdev->bus;
+	hbus = container_of(pbus->sysdata, struct hv_pcibus_device, sysdata);
+
+	memset(&params, 0, sizeof(params));
+	params.partition_id = HV_PARTITION_ID_SELF;
+	params.source = 1; /* MSI(-X) */
+	params.address = msi_desc->msg.address_lo;
+	params.data = msi_desc->msg.data;
+	params.device_id = (hbus->hdev->dev_instance.b[5] << 24) |
+			   (hbus->hdev->dev_instance.b[4] << 16) |
+			   (hbus->hdev->dev_instance.b[7] << 8) |
+			   (hbus->hdev->dev_instance.b[6] & 0xf8) |
+			   PCI_FUNC(pdev->devfn);
+	params.vector = cfg->vector;
+
+	for_each_cpu_and(cpu, dest, cpu_online_mask)
+		params.vp_mask |= (1ULL << vmbus_cpu_number_to_vp_number(cpu));
+
+	hv_do_hypercall(HVCALL_RETARGET_INTERRUPT, &params, NULL);
+
+	pci_msi_unmask_irq(data);
+}
+
+struct compose_comp_ctxt {
+	struct hv_pci_compl comp_pkt;
+	struct tran_int_desc int_desc;
+};
+
+static void hv_pci_compose_compl(void *context, struct pci_response *resp,
+				 int resp_packet_size)
+{
+	struct compose_comp_ctxt *comp_pkt = context;
+	struct pci_create_int_response *int_resp =
+		(struct pci_create_int_response *)resp;
+
+	comp_pkt->comp_pkt.completion_status = resp->status;
+	comp_pkt->int_desc = int_resp->int_desc;
+	complete(&comp_pkt->comp_pkt.host_event);
+}
+
+/**
+ * hv_compose_msi_msg() - Supplies a valid MSI address/data
+ * @data:	Everything about this MSI
+ * @msg:	Buffer that is filled in by this function
+ *
+ * This function unpacks the IRQ looking for target CPU set, IDT
+ * vector and mode and sends a message to the parent partition
+ * asking for a mapping for that tuple in this partition.  The
+ * response supplies a data value and address to which that data
+ * should be written to trigger that interrupt.
+ */
+static void hv_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
+{
+	struct irq_cfg *cfg = irqd_cfg(data);
+	struct hv_pcibus_device *hbus;
+	struct hv_pci_dev *hpdev;
+	struct pci_bus *pbus;
+	struct pci_dev *pdev;
+	struct pci_create_interrupt *int_pkt;
+	struct compose_comp_ctxt comp;
+	struct tran_int_desc *int_desc;
+	struct cpumask *affinity;
+	struct {
+		struct pci_packet pkt;
+		u8 buffer[sizeof(struct pci_create_interrupt) -
+			  sizeof(struct pci_message)];
+	} ctxt;
+	int cpu;
+	int ret;
+
+	pdev = msi_desc_to_pci_dev(irq_data_get_msi_desc(data));
+	pbus = pdev->bus;
+	hbus = container_of(pbus->sysdata, struct hv_pcibus_device, sysdata);
+	hpdev = get_pcichild_wslot(hbus, devfn_to_wslot(pdev->devfn));
+	if (!hpdev)
+		goto return_null_message;
+
+	/* Free any previous message that might have already been composed. */
+	if (data->chip_data) {
+		int_desc = data->chip_data;
+		data->chip_data = NULL;
+		hv_int_desc_free(hpdev, int_desc);
+	}
+
+	int_desc = kzalloc(sizeof(*int_desc), GFP_KERNEL);
+	if (!int_desc)
+		goto drop_reference;
+
+	memset(&ctxt, 0, sizeof(ctxt));
+	init_completion(&comp.comp_pkt.host_event);
+	ctxt.pkt.completion_func = hv_pci_compose_compl;
+	ctxt.pkt.compl_ctxt = &comp;
+	int_pkt = (struct pci_create_interrupt *)&ctxt.pkt.message;
+	int_pkt->message_type.message_type = PCI_CREATE_INTERRUPT_MESSAGE;
+	int_pkt->wslot.slot = hpdev->desc.win_slot.slot;
+	int_pkt->int_desc.vector = cfg->vector;
+	int_pkt->int_desc.vector_count = 1;
+	int_pkt->int_desc.delivery_mode =
+		(apic->irq_delivery_mode == dest_LowestPrio) ? 1 : 0;
+
+	/*
+	 * This bit doesn't have to work on machines with more than 64
+	 * processors because Hyper-V only supports 64 in a guest.
+	 */
+	affinity = irq_data_get_affinity_mask(data);
+	for_each_cpu_and(cpu, affinity, cpu_online_mask) {
+		int_pkt->int_desc.cpu_mask |=
+			(1ULL << vmbus_cpu_number_to_vp_number(cpu));
+	}
+
+	ret = vmbus_sendpacket(hpdev->hbus->hdev->channel, int_pkt,
+			       sizeof(*int_pkt), (unsigned long)&ctxt.pkt,
+			       VM_PKT_DATA_INBAND,
+			       VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
+	if (!ret)
+		wait_for_completion(&comp.comp_pkt.host_event);
+
+	if (comp.comp_pkt.completion_status < 0) {
+		dev_err(&hbus->hdev->device,
+			"Request for interrupt failed: 0x%x",
+			comp.comp_pkt.completion_status);
+		goto free_int_desc;
+	}
+
+	/*
+	 * Record the assignment so that this can be unwound later. Using
+	 * irq_set_chip_data() here would be appropriate, but the lock it takes
+	 * is already held.
+	 */
+	*int_desc = comp.int_desc;
+	data->chip_data = int_desc;
+
+	/* Pass up the result. */
+	msg->address_hi = comp.int_desc.address >> 32;
+	msg->address_lo = comp.int_desc.address & 0xffffffff;
+	msg->data = comp.int_desc.data;
+
+	put_pcichild(hpdev, hv_pcidev_ref_by_slot);
+	return;
+
+free_int_desc:
+	kfree(int_desc);
+drop_reference:
+	put_pcichild(hpdev, hv_pcidev_ref_by_slot);
+return_null_message:
+	msg->address_hi = 0;
+	msg->address_lo = 0;
+	msg->data = 0;
+}
+
+/* HW Interrupt Chip Descriptor */
+static struct irq_chip hv_msi_irq_chip = {
+	.name			= "Hyper-V PCIe MSI",
+	.irq_compose_msi_msg	= hv_compose_msi_msg,
+	.irq_set_affinity	= hv_set_affinity,
+	.irq_ack		= irq_chip_ack_parent,
+	.irq_mask		= hv_irq_mask,
+	.irq_unmask		= hv_irq_unmask,
+};
+
+static irq_hw_number_t hv_msi_domain_ops_get_hwirq(struct msi_domain_info *info,
+						   msi_alloc_info_t *arg)
+{
+	return arg->msi_hwirq;
+}
+
+static struct msi_domain_ops hv_msi_ops = {
+	.get_hwirq	= hv_msi_domain_ops_get_hwirq,
+	.msi_prepare	= pci_msi_prepare,
+	.set_desc	= pci_msi_set_desc,
+	.msi_free	= hv_msi_free,
+};
+
+/**
+ * hv_pcie_init_irq_domain() - Initialize IRQ domain
+ * @hbus:	The root PCI bus
+ *
+ * This function creates an IRQ domain which will be used for
+ * interrupts from devices that have been passed through.  These
+ * devices only support MSI and MSI-X, not line-based interrupts
+ * or simulations of line-based interrupts through PCIe's
+ * fabric-layer messages.  Because interrupts are remapped, we
+ * can support multi-message MSI here.
+ *
+ * Return: '0' on success and error value on failure
+ */
+static int hv_pcie_init_irq_domain(struct hv_pcibus_device *hbus)
+{
+	hbus->msi_info.chip = &hv_msi_irq_chip;
+	hbus->msi_info.ops = &hv_msi_ops;
+	hbus->msi_info.flags = (MSI_FLAG_USE_DEF_DOM_OPS |
+		MSI_FLAG_USE_DEF_CHIP_OPS | MSI_FLAG_MULTI_PCI_MSI |
+		MSI_FLAG_PCI_MSIX);
+	hbus->msi_info.handler = handle_edge_irq;
+	hbus->msi_info.handler_name = "edge";
+	hbus->msi_info.data = hbus;
+	hbus->irq_domain = pci_msi_create_irq_domain(hbus->sysdata.fwnode,
+						     &hbus->msi_info,
+						     x86_vector_domain);
+	if (!hbus->irq_domain) {
+		dev_err(&hbus->hdev->device,
+			"Failed to build an MSI IRQ domain\n");
+		return -ENODEV;
+	}
+
+	return 0;
+}
+
+/**
+ * get_bar_size() - Get the address space consumed by a BAR
+ * @bar_val:	Value that a BAR returned after -1 was written
+ *              to it.
+ *
+ * This function returns the size of the BAR, rounded up to 1
+ * page.  It has to be rounded up because the hypervisor's page
+ * table entry that maps the BAR into the VM can't specify an
+ * offset within a page.  The invariant is that the hypervisor
+ * must place any BARs of smaller than page length at the
+ * beginning of a page.
+ *
+ * Return:	Size in bytes of the consumed MMIO space.
+ */
+static u64 get_bar_size(u64 bar_val)
+{
+	return round_up((1 + ~(bar_val & PCI_BASE_ADDRESS_MEM_MASK)),
+			PAGE_SIZE);
+}
+
+/**
+ * survey_child_resources() - Total all MMIO requirements
+ * @hbus:	Root PCI bus, as understood by this driver
+ */
+static void survey_child_resources(struct hv_pcibus_device *hbus)
+{
+	struct list_head *iter;
+	struct hv_pci_dev *hpdev;
+	resource_size_t bar_size = 0;
+	unsigned long flags;
+	struct completion *event;
+	u64 bar_val;
+	int i;
+
+	/* If nobody is waiting on the answer, don't compute it. */
+	event = xchg(&hbus->survey_event, NULL);
+	if (!event)
+		return;
+
+	/* If the answer has already been computed, go with it. */
+	if (hbus->low_mmio_space || hbus->high_mmio_space) {
+		complete(event);
+		return;
+	}
+
+	spin_lock_irqsave(&hbus->device_list_lock, flags);
+
+	/*
+	 * Due to an interesting quirk of the PCI spec, all memory regions
+	 * for a child device are a power of 2 in size and aligned in memory,
+	 * so it's sufficient to just add them up without tracking alignment.
+	 */
+	list_for_each(iter, &hbus->children) {
+		hpdev = container_of(iter, struct hv_pci_dev, list_entry);
+		for (i = 0; i < 6; i++) {
+			if (hpdev->probed_bar[i] & PCI_BASE_ADDRESS_SPACE_IO)
+				dev_err(&hbus->hdev->device,
+					"There's an I/O BAR in this list!\n");
+
+			if (hpdev->probed_bar[i] != 0) {
+				/*
+				 * A probed BAR has all the upper bits set that
+				 * can be changed.
+				 */
+
+				bar_val = hpdev->probed_bar[i];
+				if (bar_val & PCI_BASE_ADDRESS_MEM_TYPE_64)
+					bar_val |=
+					((u64)hpdev->probed_bar[++i] << 32);
+				else
+					bar_val |= 0xffffffff00000000ULL;
+
+				bar_size = get_bar_size(bar_val);
+
+				if (bar_val & PCI_BASE_ADDRESS_MEM_TYPE_64)
+					hbus->high_mmio_space += bar_size;
+				else
+					hbus->low_mmio_space += bar_size;
+			}
+		}
+	}
+
+	spin_unlock_irqrestore(&hbus->device_list_lock, flags);
+	complete(event);
+}
+
+/**
+ * prepopulate_bars() - Fill in BARs with defaults
+ * @hbus:	Root PCI bus, as understood by this driver
+ *
+ * The core PCI driver code seems much, much happier if the BARs
+ * for a device have values upon first scan. So fill them in.
+ * The algorithm below works down from large sizes to small,
+ * attempting to pack the assignments optimally. The assumption,
+ * enforced in other parts of the code, is that the beginning of
+ * the memory-mapped I/O space will be aligned on the largest
+ * BAR size.
+ */
+static void prepopulate_bars(struct hv_pcibus_device *hbus)
+{
+	resource_size_t high_size = 0;
+	resource_size_t low_size = 0;
+	resource_size_t high_base = 0;
+	resource_size_t low_base = 0;
+	resource_size_t bar_size;
+	struct hv_pci_dev *hpdev;
+	struct list_head *iter;
+	unsigned long flags;
+	u64 bar_val;
+	u32 command;
+	bool high;
+	int i;
+
+	if (hbus->low_mmio_space) {
+		low_size = 1ULL << (63 - __builtin_clzll(hbus->low_mmio_space));
+		low_base = hbus->low_mmio_res->start;
+	}
+
+	if (hbus->high_mmio_space) {
+		high_size = 1ULL <<
+			(63 - __builtin_clzll(hbus->high_mmio_space));
+		high_base = hbus->high_mmio_res->start;
+	}
+
+	spin_lock_irqsave(&hbus->device_list_lock, flags);
+
+	/* Pick addresses for the BARs. */
+	do {
+		list_for_each(iter, &hbus->children) {
+			hpdev = container_of(iter, struct hv_pci_dev,
+					     list_entry);
+			for (i = 0; i < 6; i++) {
+				bar_val = hpdev->probed_bar[i];
+				if (bar_val == 0)
+					continue;
+				high = bar_val & PCI_BASE_ADDRESS_MEM_TYPE_64;
+				if (high) {
+					bar_val |=
+						((u64)hpdev->probed_bar[i + 1]
+						 << 32);
+				} else {
+					bar_val |= 0xffffffffULL << 32;
+				}
+				bar_size = get_bar_size(bar_val);
+				if (high) {
+					if (high_size != bar_size) {
+						i++;
+						continue;
+					}
+					_hv_pcifront_write_config(hpdev,
+						PCI_BASE_ADDRESS_0 + (4 * i),
+						4,
+						(u32)(high_base & 0xffffff00));
+					i++;
+					_hv_pcifront_write_config(hpdev,
+						PCI_BASE_ADDRESS_0 + (4 * i),
+						4, (u32)(high_base >> 32));
+					high_base += bar_size;
+				} else {
+					if (low_size != bar_size)
+						continue;
+					_hv_pcifront_write_config(hpdev,
+						PCI_BASE_ADDRESS_0 + (4 * i),
+						4,
+						(u32)(low_base & 0xffffff00));
+					low_base += bar_size;
+				}
+			}
+			if (high_size <= 1 && low_size <= 1) {
+				/* Set the memory enable bit. */
+				_hv_pcifront_read_config(hpdev, PCI_COMMAND, 2,
+							 &command);
+				command |= PCI_COMMAND_MEMORY;
+				_hv_pcifront_write_config(hpdev, PCI_COMMAND, 2,
+							  command);
+				break;
+			}
+		}
+
+		high_size >>= 1;
+		low_size >>= 1;
+	}  while (high_size || low_size);
+
+	spin_unlock_irqrestore(&hbus->device_list_lock, flags);
+}
+
+/**
+ * create_root_hv_pci_bus() - Expose a new root PCI bus
+ * @hbus:	Root PCI bus, as understood by this driver
+ *
+ * Return: 0 on success, -errno on failure
+ */
+static int create_root_hv_pci_bus(struct hv_pcibus_device *hbus)
+{
+	/* Register the device */
+	hbus->pci_bus = pci_create_root_bus(&hbus->hdev->device,
+					    0, /* bus number is always zero */
+					    &hv_pcifront_ops,
+					    &hbus->sysdata,
+					    &hbus->resources_for_children);
+	if (!hbus->pci_bus)
+		return -ENODEV;
+
+	hbus->pci_bus->msi = &hbus->msi_chip;
+	hbus->pci_bus->msi->dev = &hbus->hdev->device;
+
+	pci_scan_child_bus(hbus->pci_bus);
+	pci_bus_assign_resources(hbus->pci_bus);
+	pci_bus_add_devices(hbus->pci_bus);
+	hbus->state = hv_pcibus_installed;
+	return 0;
+}
+
+struct q_res_req_compl {
+	struct completion host_event;
+	struct hv_pci_dev *hpdev;
+};
+
+/**
+ * q_resource_requirements() - Query Resource Requirements
+ * @context:		The completion context.
+ * @resp:		The response that came from the host.
+ * @resp_packet_size:	The size in bytes of resp.
+ *
+ * This function is invoked on completion of a Query Resource
+ * Requirements packet.
+ */
+static void q_resource_requirements(void *context, struct pci_response *resp,
+				    int resp_packet_size)
+{
+	struct q_res_req_compl *completion = context;
+	struct pci_q_res_req_response *q_res_req =
+		(struct pci_q_res_req_response *)resp;
+	int i;
+
+	if (resp->status < 0) {
+		dev_err(&completion->hpdev->hbus->hdev->device,
+			"query resource requirements failed: %x\n",
+			resp->status);
+	} else {
+		for (i = 0; i < 6; i++) {
+			completion->hpdev->probed_bar[i] =
+				q_res_req->probed_bar[i];
+		}
+	}
+
+	complete(&completion->host_event);
+}
+
+static void get_pcichild(struct hv_pci_dev *hpdev,
+			    enum hv_pcidev_ref_reason reason)
+{
+	atomic_inc(&hpdev->refs);
+}
+
+static void put_pcichild(struct hv_pci_dev *hpdev,
+			    enum hv_pcidev_ref_reason reason)
+{
+	if (atomic_dec_and_test(&hpdev->refs))
+		kfree(hpdev);
+}
+
+/**
+ * new_pcichild_device() - Create a new child device
+ * @hbus:	The internal struct tracking this root PCI bus.
+ * @desc:	The information supplied so far from the host
+ *              about the device.
+ *
+ * This function creates the tracking structure for a new child
+ * device and kicks off the process of figuring out what it is.
+ *
+ * Return: Pointer to the new tracking struct
+ */
+static struct hv_pci_dev *new_pcichild_device(struct hv_pcibus_device *hbus,
+		struct pci_function_description *desc)
+{
+	struct hv_pci_dev *hpdev;
+	struct pci_child_message *res_req;
+	struct q_res_req_compl comp_pkt;
+	union {
+	struct pci_packet init_packet;
+		u8 buffer[0x100];
+	} pkt;
+	unsigned long flags;
+	int ret;
+
+	hpdev = kzalloc(sizeof(*hpdev), GFP_ATOMIC);
+	if (!hpdev)
+		return NULL;
+
+	hpdev->hbus = hbus;
+
+	memset(&pkt, 0, sizeof(pkt));
+	init_completion(&comp_pkt.host_event);
+	comp_pkt.hpdev = hpdev;
+	pkt.init_packet.compl_ctxt = &comp_pkt;
+	pkt.init_packet.completion_func = q_resource_requirements;
+	res_req = (struct pci_child_message *)&pkt.init_packet.message;
+	res_req->message_type = PCI_QUERY_RESOURCE_REQUIREMENTS;
+	res_req->wslot.slot = desc->win_slot.slot;
+
+	ret = vmbus_sendpacket(hbus->hdev->channel, res_req,
+			       sizeof(struct pci_child_message),
+			       (unsigned long)&pkt.init_packet,
+			       VM_PKT_DATA_INBAND,
+			       VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
+	if (ret)
+		goto error;
+
+	wait_for_completion(&comp_pkt.host_event);
+
+	hpdev->desc = *desc;
+	get_pcichild(hpdev, hv_pcidev_ref_initial);
+	get_pcichild(hpdev, hv_pcidev_ref_childlist);
+	spin_lock_irqsave(&hbus->device_list_lock, flags);
+	list_add_tail(&hpdev->list_entry, &hbus->children);
+	spin_unlock_irqrestore(&hbus->device_list_lock, flags);
+	return hpdev;
+
+error:
+	kfree(hpdev);
+	return NULL;
+}
+
+/**
+ * get_pcichild_wslot() - Find device from slot
+ * @hbus:	Root PCI bus, as understood by this driver
+ * @wslot:	Location on the bus
+ *
+ * This function looks up a PCI device and returns the internal
+ * representation of it.  It acquires a reference on it, so that
+ * the device won't be deleted while somebody is using it.  The
+ * caller is responsible for calling put_pcichild() to release
+ * this reference.
+ *
+ * Return:	Internal representation of a PCI device
+ */
+static struct hv_pci_dev *get_pcichild_wslot(struct hv_pcibus_device *hbus,
+					     u32 wslot)
+{
+	unsigned long flags;
+	struct hv_pci_dev *iter, *hpdev = NULL;
+
+	spin_lock_irqsave(&hbus->device_list_lock, flags);
+	list_for_each_entry(iter, &hbus->children, list_entry) {
+		if (iter->desc.win_slot.slot == wslot) {
+			hpdev = iter;
+			get_pcichild(hpdev, hv_pcidev_ref_by_slot);
+			break;
+		}
+	}
+	spin_unlock_irqrestore(&hbus->device_list_lock, flags);
+
+	return hpdev;
+}
+
+/**
+ * pci_devices_present_work() - Handle new list of child devices
+ * @work:	Work struct embedded in struct hv_dr_work
+ *
+ * "Bus Relations" is the Windows term for "children of this
+ * bus."  The terminology is preserved here for people trying to
+ * debug the interaction between Hyper-V and Linux.  This
+ * function is called when the parent partition reports a list
+ * of functions that should be observed under this PCI Express
+ * port (bus).
+ *
+ * This function updates the list, and must tolerate being
+ * called multiple times with the same information.  The typical
+ * number of child devices is one, with very atypical cases
+ * involving three or four, so the algorithms used here can be
+ * simple and inefficient.
+ *
+ * It must also treat the omission of a previously observed device as
+ * notification that the device no longer exists.
+ *
+ * Note that this function is a work item, and it may not be
+ * invoked in the order that it was queued.  Back to back
+ * updates of the list of present devices may involve queuing
+ * multiple work items, and this one may run before ones that
+ * were sent later. As such, this function only does something
+ * if is the last one in the queue.
+ */
+static void pci_devices_present_work(struct work_struct *work)
+{
+	u32 child_no;
+	bool found;
+	struct list_head *iter;
+	struct pci_function_description *new_desc;
+	struct hv_pci_dev *hpdev;
+	struct hv_pcibus_device *hbus;
+	struct list_head removed;
+	struct hv_dr_work *dr_wrk;
+	struct hv_dr_state *dr = NULL;
+	unsigned long flags;
+
+	dr_wrk = container_of(work, struct hv_dr_work, wrk);
+	hbus = dr_wrk->bus;
+	kfree(dr_wrk);
+
+	INIT_LIST_HEAD(&removed);
+
+	if (down_interruptible(&hbus->enum_sem)) {
+		put_hvpcibus(hbus);
+		return;
+	}
+
+	/* Pull this off the queue and process it if it was the last one. */
+	spin_lock_irqsave(&hbus->device_list_lock, flags);
+	while (!list_empty(&hbus->dr_list)) {
+		dr = list_first_entry(&hbus->dr_list, struct hv_dr_state,
+				      list_entry);
+		list_del(&dr->list_entry);
+
+		/* Throw this away if the list still has stuff in it. */
+		if (!list_empty(&hbus->dr_list)) {
+			kfree(dr);
+			continue;
+		}
+	}
+	spin_unlock_irqrestore(&hbus->device_list_lock, flags);
+
+	if (!dr) {
+		up(&hbus->enum_sem);
+		put_hvpcibus(hbus);
+		return;
+	}
+
+	/* First, mark all existing children as reported missing. */
+	spin_lock_irqsave(&hbus->device_list_lock, flags);
+	list_for_each(iter, &hbus->children) {
+			hpdev = container_of(iter, struct hv_pci_dev,
+					     list_entry);
+			hpdev->reported_missing = true;
+	}
+	spin_unlock_irqrestore(&hbus->device_list_lock, flags);
+
+	/* Next, add back any reported devices. */
+	for (child_no = 0; child_no < dr->device_count; child_no++) {
+		found = false;
+		new_desc = &dr->func[child_no];
+
+		spin_lock_irqsave(&hbus->device_list_lock, flags);
+		list_for_each(iter, &hbus->children) {
+			hpdev = container_of(iter, struct hv_pci_dev,
+					     list_entry);
+			if ((hpdev->desc.win_slot.slot ==
+			     new_desc->win_slot.slot) &&
+			    (hpdev->desc.v_id == new_desc->v_id) &&
+			    (hpdev->desc.d_id == new_desc->d_id) &&
+			    (hpdev->desc.ser == new_desc->ser)) {
+				hpdev->reported_missing = false;
+				found = true;
+			}
+		}
+		spin_unlock_irqrestore(&hbus->device_list_lock, flags);
+
+		if (!found) {
+			hpdev = new_pcichild_device(hbus, new_desc);
+			if (!hpdev)
+				dev_err(&hbus->hdev->device,
+					"couldn't record a child device.\n");
+		}
+	}
+
+	/* Move missing children to a list on the stack. */
+	spin_lock_irqsave(&hbus->device_list_lock, flags);
+	do {
+		found = false;
+		list_for_each(iter, &hbus->children) {
+			hpdev = container_of(iter, struct hv_pci_dev,
+					     list_entry);
+			if (hpdev->reported_missing) {
+				found = true;
+				put_pcichild(hpdev, hv_pcidev_ref_childlist);
+				list_del(&hpdev->list_entry);
+				list_add_tail(&hpdev->list_entry, &removed);
+				break;
+			}
+		}
+	} while (found);
+	spin_unlock_irqrestore(&hbus->device_list_lock, flags);
+
+	/* Delete everything that should no longer exist. */
+	while (!list_empty(&removed)) {
+		hpdev = list_first_entry(&removed, struct hv_pci_dev,
+					 list_entry);
+		list_del(&hpdev->list_entry);
+		put_pcichild(hpdev, hv_pcidev_ref_initial);
+	}
+
+	/* Tell the core to rescan bus because there may have been changes. */
+	if (hbus->state == hv_pcibus_installed) {
+		pci_lock_rescan_remove();
+		pci_scan_child_bus(hbus->pci_bus);
+		pci_unlock_rescan_remove();
+	} else {
+		survey_child_resources(hbus);
+	}
+
+	up(&hbus->enum_sem);
+	put_hvpcibus(hbus);
+	kfree(dr);
+}
+
+/**
+ * hv_pci_devices_present() - Handles list of new children
+ * @hbus:	Root PCI bus, as understood by this driver
+ * @relations:	Packet from host listing children
+ *
+ * This function is invoked whenever a new list of devices for
+ * this bus appears.
+ */
+static void hv_pci_devices_present(struct hv_pcibus_device *hbus,
+				   struct pci_bus_relations *relations)
+{
+	struct hv_dr_state *dr;
+	struct hv_dr_work *dr_wrk;
+	unsigned long flags;
+
+	dr_wrk = kzalloc(sizeof(*dr_wrk), GFP_NOWAIT);
+	if (!dr_wrk)
+		return;
+
+	dr = kzalloc(offsetof(struct hv_dr_state, func) +
+		     (sizeof(struct pci_function_description) *
+		      (relations->device_count)), GFP_NOWAIT);
+	if (!dr)  {
+		kfree(dr_wrk);
+		return;
+	}
+
+	INIT_WORK(&dr_wrk->wrk, pci_devices_present_work);
+	dr_wrk->bus = hbus;
+	dr->device_count = relations->device_count;
+	if (dr->device_count != 0) {
+		memcpy(dr->func, relations->func,
+		       sizeof(struct pci_function_description) *
+		       dr->device_count);
+	}
+
+	spin_lock_irqsave(&hbus->device_list_lock, flags);
+	list_add_tail(&dr->list_entry, &hbus->dr_list);
+	spin_unlock_irqrestore(&hbus->device_list_lock, flags);
+
+	get_hvpcibus(hbus);
+	schedule_work(&dr_wrk->wrk);
+}
+
+/**
+ * hv_eject_device_work() - Asynchronously handles ejection
+ * @work:	Work struct embedded in internal device struct
+ *
+ * This function handles ejecting a device.  Windows will
+ * attempt to gracefully eject a device, waiting 60 seconds to
+ * hear back from the guest OS that this completed successfully.
+ * If this timer expires, the device will be forcibly removed.
+ */
+static void hv_eject_device_work(struct work_struct *work)
+{
+	struct pci_eject_response *ejct_pkt;
+	struct hv_pci_dev *hpdev;
+	struct pci_dev *pdev;
+	unsigned long flags;
+	int wslot;
+	struct {
+		struct pci_packet pkt;
+		u8 buffer[sizeof(struct pci_eject_response) -
+			  sizeof(struct pci_message)];
+	} ctxt;
+
+	hpdev = container_of(work, struct hv_pci_dev, wrk);
+
+	if (hpdev->state != hv_pcichild_ejecting) {
+		put_pcichild(hpdev, hv_pcidev_ref_pnp);
+		return;
+	}
+
+	/*
+	 * Ejection can come before or after the PCI bus has been set up, so
+	 * attempt to find it and tear down the bus state, if it exists.  This
+	 * must be done without constructs like pci_domain_nr(hbus->pci_bus)
+	 * because hbus->pci_bus may not exist yet.
+	 */
+	wslot = wslot_to_devfn(hpdev->desc.win_slot.slot);
+	pdev = pci_get_domain_bus_and_slot(hpdev->hbus->sysdata.domain, 0,
+					   wslot);
+	if (pdev) {
+		pci_stop_and_remove_bus_device(pdev);
+		pci_dev_put(pdev);
+	}
+
+	memset(&ctxt, 0, sizeof(ctxt));
+	ejct_pkt = (struct pci_eject_response *)&ctxt.pkt.message;
+	ejct_pkt->message_type = PCI_EJECTION_COMPLETE;
+	ejct_pkt->wslot.slot = hpdev->desc.win_slot.slot;
+	vmbus_sendpacket(hpdev->hbus->hdev->channel, ejct_pkt,
+			 sizeof(*ejct_pkt), (unsigned long)&ctxt.pkt,
+			 VM_PKT_DATA_INBAND, 0);
+
+	spin_lock_irqsave(&hpdev->hbus->device_list_lock, flags);
+	list_del(&hpdev->list_entry);
+	spin_unlock_irqrestore(&hpdev->hbus->device_list_lock, flags);
+
+	put_pcichild(hpdev, hv_pcidev_ref_childlist);
+	put_pcichild(hpdev, hv_pcidev_ref_pnp);
+	put_hvpcibus(hpdev->hbus);
+}
+
+/**
+ * hv_pci_eject_device() - Handles device ejection
+ * @hpdev:	Internal device tracking struct
+ *
+ * This function is invoked when an ejection packet arrives.  It
+ * just schedules work so that we don't re-enter the packet
+ * delivery code handling the ejection.
+ */
+static void hv_pci_eject_device(struct hv_pci_dev *hpdev)
+{
+	hpdev->state = hv_pcichild_ejecting;
+	get_pcichild(hpdev, hv_pcidev_ref_pnp);
+	INIT_WORK(&hpdev->wrk, hv_eject_device_work);
+	get_hvpcibus(hpdev->hbus);
+	schedule_work(&hpdev->wrk);
+}
+
+/**
+ * hv_pci_onchannelcallback() - Handles incoming packets
+ * @context:	Internal bus tracking struct
+ *
+ * This function is invoked whenever the host sends a packet to
+ * this channel (which is private to this root PCI bus).
+ */
+static void hv_pci_onchannelcallback(void *context)
+{
+	const int packet_size = 0x100;
+	int ret;
+	struct hv_pcibus_device *hbus = context;
+	u32 bytes_recvd;
+	u64 req_id;
+	struct vmpacket_descriptor *desc;
+	unsigned char *buffer;
+	int bufferlen = packet_size;
+	struct pci_packet *comp_packet;
+	struct pci_response *response;
+	struct pci_incoming_message *new_message;
+	struct pci_bus_relations *bus_rel;
+	struct pci_dev_incoming *dev_message;
+	struct hv_pci_dev *hpdev;
+
+	buffer = kmalloc(bufferlen, GFP_ATOMIC);
+	if (!buffer)
+		return;
+
+	while (1) {
+		ret = vmbus_recvpacket_raw(hbus->hdev->channel, buffer,
+					   bufferlen, &bytes_recvd, &req_id);
+
+		if (ret == -ENOBUFS) {
+			kfree(buffer);
+			/* Handle large packet */
+			bufferlen = bytes_recvd;
+			buffer = kmalloc(bytes_recvd, GFP_ATOMIC);
+			if (!buffer)
+				return;
+			continue;
+		}
+
+		/* Zero length indicates there are no more packets. */
+		if (ret || !bytes_recvd)
+			break;
+
+		/*
+		 * All incoming packets must be at least as large as a
+		 * response.
+		 */
+		if (bytes_recvd <= sizeof(struct pci_response))
+			continue;
+		desc = (struct vmpacket_descriptor *)buffer;
+
+		switch (desc->type) {
+		case VM_PKT_COMP:
+
+			/*
+			 * The host is trusted, and thus it's safe to interpret
+			 * this transaction ID as a pointer.
+			 */
+			comp_packet = (struct pci_packet *)req_id;
+			response = (struct pci_response *)buffer;
+			comp_packet->completion_func(comp_packet->compl_ctxt,
+						     response,
+						     bytes_recvd);
+			break;
+
+		case VM_PKT_DATA_INBAND:
+
+			new_message = (struct pci_incoming_message *)buffer;
+			switch (new_message->message_type.message_type) {
+			case PCI_BUS_RELATIONS:
+
+				bus_rel = (struct pci_bus_relations *)buffer;
+				if (bytes_recvd <
+				    offsetof(struct pci_bus_relations, func) +
+				    (sizeof(struct pci_function_description) *
+				     (bus_rel->device_count))) {
+					dev_err(&hbus->hdev->device,
+						"bus relations too small\n");
+					break;
+				}
+
+				hv_pci_devices_present(hbus, bus_rel);
+				break;
+
+			case PCI_EJECT:
+
+				dev_message = (struct pci_dev_incoming *)buffer;
+				hpdev = get_pcichild_wslot(hbus,
+						      dev_message->wslot.slot);
+				if (hpdev) {
+					hv_pci_eject_device(hpdev);
+					put_pcichild(hpdev,
+							hv_pcidev_ref_by_slot);
+				}
+				break;
+
+			default:
+				dev_warn(&hbus->hdev->device,
+					"Unimplemented protocol message %x\n",
+					new_message->message_type.message_type);
+				break;
+			}
+			break;
+
+		default:
+			dev_err(&hbus->hdev->device,
+				"unhandled packet type %d, tid %llx len %d\n",
+				desc->type, req_id, bytes_recvd);
+			break;
+		}
+	}
+
+	kfree(buffer);
+}
+
+/**
+ * hv_pci_protocol_negotiation() - Set up protocol
+ * @hdev:	VMBus's tracking struct for this root PCI bus
+ *
+ * This driver is intended to support running on Windows 10
+ * (server) and later versions. It will not run on earlier
+ * versions, as they assume that many of the operations which
+ * Linux needs accomplished with a spinlock held were done via
+ * asynchronous messaging via VMBus.  Windows 10 increases the
+ * surface area of PCI emulation so that these actions can take
+ * place by suspending a virtual processor for their duration.
+ *
+ * This function negotiates the channel protocol version,
+ * failing if the host doesn't support the necessary protocol
+ * level.
+ */
+static int hv_pci_protocol_negotiation(struct hv_device *hdev)
+{
+	struct pci_version_request *version_req;
+	struct hv_pci_compl comp_pkt;
+	struct pci_packet *pkt;
+	int ret;
+
+	/*
+	 * Initiate the handshake with the host and negotiate
+	 * a version that the host can support. We start with the
+	 * highest version number and go down if the host cannot
+	 * support it.
+	 */
+	pkt = kzalloc(sizeof(*pkt) + sizeof(*version_req), GFP_KERNEL);
+	if (!pkt)
+		return -ENOMEM;
+
+	init_completion(&comp_pkt.host_event);
+	pkt->completion_func = hv_pci_generic_compl;
+	pkt->compl_ctxt = &comp_pkt;
+	version_req = (struct pci_version_request *)&pkt->message;
+	version_req->message_type.message_type = PCI_QUERY_PROTOCOL_VERSION;
+	version_req->protocol_version = PCI_PROTOCOL_VERSION_CURRENT;
+
+	ret = vmbus_sendpacket(hdev->channel, version_req,
+			       sizeof(struct pci_version_request),
+			       (unsigned long)pkt, VM_PKT_DATA_INBAND,
+			       VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
+	if (ret)
+		goto exit;
+
+	wait_for_completion(&comp_pkt.host_event);
+
+	if (comp_pkt.completion_status < 0) {
+		dev_err(&hdev->device,
+			"PCI Pass-through VSP failed version request %x\n",
+			comp_pkt.completion_status);
+		ret = -EPROTO;
+		goto exit;
+	}
+
+	ret = 0;
+
+exit:
+	kfree(pkt);
+	return ret;
+}
+
+/**
+ * hv_pci_free_bridge_windows() - Release memory regions for the
+ * bus
+ * @hbus:	Root PCI bus, as understood by this driver
+ */
+static void hv_pci_free_bridge_windows(struct hv_pcibus_device *hbus)
+{
+	/*
+	 * Set the resources back to the way they looked when they
+	 * were allocated by setting IORESOURCE_BUSY again.
+	 */
+
+	if (hbus->low_mmio_space && hbus->low_mmio_res) {
+		hbus->low_mmio_res->flags |= IORESOURCE_BUSY;
+		vmbus_free_mmio(hbus->low_mmio_res->start,
+				resource_size(hbus->low_mmio_res));
+	}
+
+	if (hbus->high_mmio_space && hbus->high_mmio_res) {
+		hbus->high_mmio_res->flags |= IORESOURCE_BUSY;
+		vmbus_free_mmio(hbus->high_mmio_res->start,
+				resource_size(hbus->high_mmio_res));
+	}
+}
+
+/**
+ * hv_pci_allocate_bridge_windows() - Allocate memory regions
+ * for the bus
+ * @hbus:	Root PCI bus, as understood by this driver
+ *
+ * This function calls vmbus_allocate_mmio(), which is itself a
+ * bit of a compromise.  Ideally, we might change the pnp layer
+ * in the kernel such that it comprehends either PCI devices
+ * which are "grandchildren of ACPI," with some intermediate bus
+ * node (in this case, VMBus) or change it such that it
+ * understands VMBus.  The pnp layer, however, has been declared
+ * deprecated, and not subject to change.
+ *
+ * The workaround, implemented here, is to ask VMBus to allocate
+ * MMIO space for this bus.  VMBus itself knows which ranges are
+ * appropriate by looking at its own ACPI objects.  Then, after
+ * these ranges are claimed, they're modified to look like they
+ * would have looked if the ACPI and pnp code had allocated
+ * bridge windows.  These descriptors have to exist in this form
+ * in order to satisfy the code which will get invoked when the
+ * endpoint PCI function driver calls request_mem_region() or
+ * request_mem_region_exclusive().
+ *
+ * Return: 0 on success, -errno on failure
+ */
+static int hv_pci_allocate_bridge_windows(struct hv_pcibus_device *hbus)
+{
+	resource_size_t align;
+	int ret;
+
+	if (hbus->low_mmio_space) {
+		align = 1ULL << (63 - __builtin_clzll(hbus->low_mmio_space));
+		ret = vmbus_allocate_mmio(&hbus->low_mmio_res, hbus->hdev, 0,
+					  (u64)(u32)0xffffffff,
+					  hbus->low_mmio_space,
+					  align, false);
+		if (ret) {
+			dev_err(&hbus->hdev->device,
+				"Need %#llx of low MMIO space. Consider reconfiguring the VM.\n",
+				hbus->low_mmio_space);
+			return ret;
+		}
+
+		/* Modify this resource to become a bridge window. */
+		hbus->low_mmio_res->flags |= IORESOURCE_WINDOW;
+		hbus->low_mmio_res->flags &= ~IORESOURCE_BUSY;
+		pci_add_resource(&hbus->resources_for_children,
+				 hbus->low_mmio_res);
+	}
+
+	if (hbus->high_mmio_space) {
+		align = 1ULL << (63 - __builtin_clzll(hbus->high_mmio_space));
+		ret = vmbus_allocate_mmio(&hbus->high_mmio_res, hbus->hdev,
+					  0x100000000, -1,
+					  hbus->high_mmio_space, align,
+					  false);
+		if (ret) {
+			dev_err(&hbus->hdev->device,
+				"Need %#llx of high MMIO space. Consider reconfiguring the VM.\n",
+				hbus->high_mmio_space);
+			goto release_low_mmio;
+		}
+
+		/* Modify this resource to become a bridge window. */
+		hbus->high_mmio_res->flags |= IORESOURCE_WINDOW;
+		hbus->high_mmio_res->flags &= ~IORESOURCE_BUSY;
+		pci_add_resource(&hbus->resources_for_children,
+				 hbus->high_mmio_res);
+	}
+
+	return 0;
+
+release_low_mmio:
+	if (hbus->low_mmio_res) {
+		vmbus_free_mmio(hbus->low_mmio_res->start,
+				resource_size(hbus->low_mmio_res));
+	}
+
+	return ret;
+}
+
+/**
+ * hv_allocate_config_window() - Find MMIO space for PCI Config
+ * @hbus:	Root PCI bus, as understood by this driver
+ *
+ * This function claims memory-mapped I/O space for accessing
+ * configuration space for the functions on this bus.
+ *
+ * Return: 0 on success, -errno on failure
+ */
+static int hv_allocate_config_window(struct hv_pcibus_device *hbus)
+{
+	int ret;
+
+	/*
+	 * Set up a region of MMIO space to use for accessing configuration
+	 * space.
+	 */
+	ret = vmbus_allocate_mmio(&hbus->mem_config, hbus->hdev, 0, -1,
+				  PCI_CONFIG_MMIO_LENGTH, 0x1000, false);
+	if (ret)
+		return ret;
+
+	/*
+	 * vmbus_allocate_mmio() gets used for allocating both device endpoint
+	 * resource claims (those which cannot be overlapped) and the ranges
+	 * which are valid for the children of this bus, which are intended
+	 * to be overlapped by those children.  Set the flag on this claim
+	 * meaning that this region can't be overlapped.
+	 */
+
+	hbus->mem_config->flags |= IORESOURCE_BUSY;
+
+	return 0;
+}
+
+static void hv_free_config_window(struct hv_pcibus_device *hbus)
+{
+	vmbus_free_mmio(hbus->mem_config->start, PCI_CONFIG_MMIO_LENGTH);
+}
+
+/**
+ * hv_pci_enter_d0() - Bring the "bus" into the D0 power state
+ * @hdev:	VMBus's tracking struct for this root PCI bus
+ *
+ * Return: 0 on success, -errno on failure
+ */
+static int hv_pci_enter_d0(struct hv_device *hdev)
+{
+	struct hv_pcibus_device *hbus = hv_get_drvdata(hdev);
+	struct pci_bus_d0_entry *d0_entry;
+	struct hv_pci_compl comp_pkt;
+	struct pci_packet *pkt;
+	int ret;
+
+	/*
+	 * Tell the host that the bus is ready to use, and moved into the
+	 * powered-on state.  This includes telling the host which region
+	 * of memory-mapped I/O space has been chosen for configuration space
+	 * access.
+	 */
+	pkt = kzalloc(sizeof(*pkt) + sizeof(*d0_entry), GFP_KERNEL);
+	if (!pkt)
+		return -ENOMEM;
+
+	init_completion(&comp_pkt.host_event);
+	pkt->completion_func = hv_pci_generic_compl;
+	pkt->compl_ctxt = &comp_pkt;
+	d0_entry = (struct pci_bus_d0_entry *)&pkt->message;
+	d0_entry->message_type.message_type = PCI_BUS_D0ENTRY;
+	d0_entry->mmio_base = hbus->mem_config->start;
+
+	ret = vmbus_sendpacket(hdev->channel, d0_entry, sizeof(*d0_entry),
+			       (unsigned long)pkt, VM_PKT_DATA_INBAND,
+			       VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
+	if (ret)
+		goto exit;
+
+	wait_for_completion(&comp_pkt.host_event);
+
+	if (comp_pkt.completion_status < 0) {
+		dev_err(&hdev->device,
+			"PCI Pass-through VSP failed D0 Entry with status %x\n",
+			comp_pkt.completion_status);
+		ret = -EPROTO;
+		goto exit;
+	}
+
+	ret = 0;
+
+exit:
+	kfree(pkt);
+	return ret;
+}
+
+/**
+ * hv_pci_query_relations() - Ask host to send list of child
+ * devices
+ * @hdev:	VMBus's tracking struct for this root PCI bus
+ *
+ * Return: 0 on success, -errno on failure
+ */
+static int hv_pci_query_relations(struct hv_device *hdev)
+{
+	struct hv_pcibus_device *hbus = hv_get_drvdata(hdev);
+	struct pci_message message;
+	struct completion comp;
+	int ret;
+
+	/* Ask the host to send along the list of child devices */
+	init_completion(&comp);
+	if (cmpxchg(&hbus->survey_event, NULL, &comp))
+		return -ENOTEMPTY;
+
+	memset(&message, 0, sizeof(message));
+	message.message_type = PCI_QUERY_BUS_RELATIONS;
+
+	ret = vmbus_sendpacket(hdev->channel, &message, sizeof(message),
+			       0, VM_PKT_DATA_INBAND, 0);
+	if (ret)
+		return ret;
+
+	wait_for_completion(&comp);
+	return 0;
+}
+
+/**
+ * hv_send_resources_allocated() - Report local resource choices
+ * @hdev:	VMBus's tracking struct for this root PCI bus
+ *
+ * The host OS is expecting to be sent a request as a message
+ * which contains all the resources that the device will use.
+ * The response contains those same resources, "translated"
+ * which is to say, the values which should be used by the
+ * hardware, when it delivers an interrupt.  (MMIO resources are
+ * used in local terms.)  This is nice for Windows, and lines up
+ * with the FDO/PDO split, which doesn't exist in Linux.  Linux
+ * is deeply expecting to scan an emulated PCI configuration
+ * space.  So this message is sent here only to drive the state
+ * machine on the host forward.
+ *
+ * Return: 0 on success, -errno on failure
+ */
+static int hv_send_resources_allocated(struct hv_device *hdev)
+{
+	struct hv_pcibus_device *hbus = hv_get_drvdata(hdev);
+	struct pci_resources_assigned *res_assigned;
+	struct hv_pci_compl comp_pkt;
+	struct hv_pci_dev *hpdev;
+	struct pci_packet *pkt;
+	u32 wslot;
+	int ret;
+
+	pkt = kmalloc(sizeof(*pkt) + sizeof(*res_assigned), GFP_KERNEL);
+	if (!pkt)
+		return -ENOMEM;
+
+	ret = 0;
+
+	for (wslot = 0; wslot < 256; wslot++) {
+		hpdev = get_pcichild_wslot(hbus, wslot);
+		if (!hpdev)
+			continue;
+
+		memset(pkt, 0, sizeof(*pkt) + sizeof(*res_assigned));
+		init_completion(&comp_pkt.host_event);
+		pkt->completion_func = hv_pci_generic_compl;
+		pkt->compl_ctxt = &comp_pkt;
+		pkt->message.message_type = PCI_RESOURCES_ASSIGNED;
+		res_assigned = (struct pci_resources_assigned *)&pkt->message;
+		res_assigned->wslot.slot = hpdev->desc.win_slot.slot;
+
+		put_pcichild(hpdev, hv_pcidev_ref_by_slot);
+
+		ret = vmbus_sendpacket(
+			hdev->channel, &pkt->message,
+			sizeof(*res_assigned),
+			(unsigned long)pkt,
+			VM_PKT_DATA_INBAND,
+			VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
+		if (ret)
+			break;
+
+		wait_for_completion(&comp_pkt.host_event);
+
+		if (comp_pkt.completion_status < 0) {
+			ret = -EPROTO;
+			dev_err(&hdev->device,
+				"resource allocated returned 0x%x",
+				comp_pkt.completion_status);
+			break;
+		}
+	}
+
+	kfree(pkt);
+	return ret;
+}
+
+/**
+ * hv_send_resources_released() - Report local resources
+ * released
+ * @hdev:	VMBus's tracking struct for this root PCI bus
+ *
+ * Return: 0 on success, -errno on failure
+ */
+static int hv_send_resources_released(struct hv_device *hdev)
+{
+	struct hv_pcibus_device *hbus = hv_get_drvdata(hdev);
+	struct pci_child_message pkt;
+	struct hv_pci_dev *hpdev;
+	u32 wslot;
+	int ret;
+
+	for (wslot = 0; wslot < 256; wslot++) {
+		hpdev = get_pcichild_wslot(hbus, wslot);
+		if (!hpdev)
+			continue;
+
+		memset(&pkt, 0, sizeof(pkt));
+		pkt.message_type = PCI_RESOURCES_RELEASED;
+		pkt.wslot.slot = hpdev->desc.win_slot.slot;
+
+		put_pcichild(hpdev, hv_pcidev_ref_by_slot);
+
+		ret = vmbus_sendpacket(hdev->channel, &pkt, sizeof(pkt), 0,
+				       VM_PKT_DATA_INBAND, 0);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
+static void get_hvpcibus(struct hv_pcibus_device *hbus)
+{
+	atomic_inc(&hbus->remove_lock);
+}
+
+static void put_hvpcibus(struct hv_pcibus_device *hbus)
+{
+	if (atomic_dec_and_test(&hbus->remove_lock))
+		complete(&hbus->remove_event);
+}
+
+/**
+ * hv_pci_probe() - New VMBus channel probe, for a root PCI bus
+ * @hdev:	VMBus's tracking struct for this root PCI bus
+ * @dev_id:	Identifies the device itself
+ *
+ * Return: 0 on success, -errno on failure
+ */
+static int hv_pci_probe(struct hv_device *hdev,
+			const struct hv_vmbus_device_id *dev_id)
+{
+	struct hv_pcibus_device *hbus;
+	int ret;
+
+	hbus = kzalloc(sizeof(*hbus), GFP_KERNEL);
+	if (!hbus)
+		return -ENOMEM;
+
+	/*
+	 * The PCI bus "domain" is what is called "segment" in ACPI and
+	 * other specs.  Pull it from the instance ID, to get something
+	 * unique.  Bytes 8 and 9 are what is used in Windows guests, so
+	 * do the same thing for consistency.  Note that, since this code
+	 * only runs in a Hyper-V VM, Hyper-V can (and does) guarantee
+	 * that (1) the only domain in use for something that looks like
+	 * a physical PCI bus (which is actually emulated by the
+	 * hypervisor) is domain 0 and (2) there will be no overlap
+	 * between domains derived from these instance IDs in the same
+	 * VM.
+	 */
+	hbus->sysdata.domain = hdev->dev_instance.b[9] |
+			       hdev->dev_instance.b[8] << 8;
+
+	hbus->hdev = hdev;
+	atomic_inc(&hbus->remove_lock);
+	INIT_LIST_HEAD(&hbus->children);
+	INIT_LIST_HEAD(&hbus->dr_list);
+	INIT_LIST_HEAD(&hbus->resources_for_children);
+	spin_lock_init(&hbus->config_lock);
+	spin_lock_init(&hbus->device_list_lock);
+	sema_init(&hbus->enum_sem, 1);
+	init_completion(&hbus->remove_event);
+
+	ret = vmbus_open(hdev->channel, pci_ring_size, pci_ring_size, NULL, 0,
+			 hv_pci_onchannelcallback, hbus);
+	if (ret)
+		goto free_bus;
+
+	hv_set_drvdata(hdev, hbus);
+
+	ret = hv_pci_protocol_negotiation(hdev);
+	if (ret)
+		goto close;
+
+	ret = hv_allocate_config_window(hbus);
+	if (ret)
+		goto close;
+
+	hbus->cfg_addr = ioremap(hbus->mem_config->start,
+				 PCI_CONFIG_MMIO_LENGTH);
+	if (!hbus->cfg_addr) {
+		dev_err(&hdev->device,
+			"Unable to map a virtual address for config space\n");
+		ret = -ENOMEM;
+		goto free_config;
+	}
+
+	hbus->sysdata.fwnode = irq_domain_alloc_fwnode(hbus);
+	if (!hbus->sysdata.fwnode) {
+		ret = -ENOMEM;
+		goto unmap;
+	}
+
+	ret = hv_pcie_init_irq_domain(hbus);
+	if (ret)
+		goto free_fwnode;
+
+	ret = hv_pci_query_relations(hdev);
+	if (ret)
+		goto free_irq_domain;
+
+	ret = hv_pci_enter_d0(hdev);
+	if (ret)
+		goto free_irq_domain;
+
+	ret = hv_pci_allocate_bridge_windows(hbus);
+	if (ret)
+		goto free_irq_domain;
+
+	ret = hv_send_resources_allocated(hdev);
+	if (ret)
+		goto free_windows;
+
+	prepopulate_bars(hbus);
+
+	hbus->state = hv_pcibus_probed;
+
+	ret = create_root_hv_pci_bus(hbus);
+	if (ret)
+		goto free_windows;
+
+	return 0;
+
+free_windows:
+	hv_pci_free_bridge_windows(hbus);
+free_irq_domain:
+	irq_domain_remove(hbus->irq_domain);
+free_fwnode:
+	irq_domain_free_fwnode(hbus->sysdata.fwnode);
+unmap:
+	iounmap(hbus->cfg_addr);
+free_config:
+	hv_free_config_window(hbus);
+close:
+	vmbus_close(hdev->channel);
+free_bus:
+	kfree(hbus);
+	return ret;
+}
+
+/**
+ * hv_pci_remove() - Remove routine for this VMBus channel
+ * @hdev:	VMBus's tracking struct for this root PCI bus
+ *
+ * Return: 0 on success, -errno on failure
+ */
+static int hv_pci_remove(struct hv_device *hdev)
+{
+	int ret;
+	struct hv_pcibus_device *hbus;
+	union {
+		struct pci_packet teardown_packet;
+		u8 buffer[0x100];
+	} pkt;
+	struct pci_bus_relations relations;
+	struct hv_pci_compl comp_pkt;
+
+	hbus = hv_get_drvdata(hdev);
+
+	memset(&pkt.teardown_packet, 0, sizeof(pkt.teardown_packet));
+	init_completion(&comp_pkt.host_event);
+	pkt.teardown_packet.completion_func = hv_pci_generic_compl;
+	pkt.teardown_packet.compl_ctxt = &comp_pkt;
+	pkt.teardown_packet.message.message_type = PCI_BUS_D0EXIT;
+
+	ret = vmbus_sendpacket(hdev->channel, &pkt.teardown_packet.message,
+			       sizeof(struct pci_message),
+			       (unsigned long)&pkt.teardown_packet,
+			       VM_PKT_DATA_INBAND,
+			       VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
+	if (!ret)
+		wait_for_completion_timeout(&comp_pkt.host_event, 10 * HZ);
+
+	if (hbus->state == hv_pcibus_installed) {
+		/* Remove the bus from PCI's point of view. */
+		pci_lock_rescan_remove();
+		pci_stop_root_bus(hbus->pci_bus);
+		pci_remove_root_bus(hbus->pci_bus);
+		pci_unlock_rescan_remove();
+	}
+
+	ret = hv_send_resources_released(hdev);
+	if (ret)
+		dev_err(&hdev->device,
+			"Couldn't send resources released packet(s)\n");
+
+	vmbus_close(hdev->channel);
+
+	/* Delete any children which might still exist. */
+	memset(&relations, 0, sizeof(relations));
+	hv_pci_devices_present(hbus, &relations);
+
+	iounmap(hbus->cfg_addr);
+	hv_free_config_window(hbus);
+	pci_free_resource_list(&hbus->resources_for_children);
+	hv_pci_free_bridge_windows(hbus);
+	irq_domain_remove(hbus->irq_domain);
+	irq_domain_free_fwnode(hbus->sysdata.fwnode);
+	put_hvpcibus(hbus);
+	wait_for_completion(&hbus->remove_event);
+	kfree(hbus);
+	return 0;
+}
+
+static const struct hv_vmbus_device_id hv_pci_id_table[] = {
+	/* PCI Pass-through Class ID */
+	/* 44C4F61D-4444-4400-9D52-802E27EDE19F */
+	{ HV_PCIE_GUID, },
+	{ },
+};
+
+MODULE_DEVICE_TABLE(vmbus, hv_pci_id_table);
+
+static struct hv_driver hv_pci_drv = {
+	.name		= "hv_pci",
+	.id_table	= hv_pci_id_table,
+	.probe		= hv_pci_probe,
+	.remove		= hv_pci_remove,
+};
+
+static void __exit exit_hv_pci_drv(void)
+{
+	vmbus_driver_unregister(&hv_pci_drv);
+}
+
+static int __init init_hv_pci_drv(void)
+{
+	return vmbus_driver_register(&hv_pci_drv);
+}
+
+module_init(init_hv_pci_drv);
+module_exit(exit_hv_pci_drv);
+
+MODULE_DESCRIPTION("Hyper-V PCI");
+MODULE_LICENSE("GPL v2");
--- zfcpdump-kernel-4.4.orig/drivers/pci/host/pci-imx6.c
+++ zfcpdump-kernel-4.4/drivers/pci/host/pci-imx6.c
@@ -537,7 +537,8 @@ static int __init imx6_add_pcie_port(str
 
 		ret = devm_request_irq(&pdev->dev, pp->msi_irq,
 				       imx6_pcie_msi_handler,
-				       IRQF_SHARED, "mx6-pcie-msi", pp);
+				       IRQF_SHARED | IRQF_NO_THREAD,
+				       "mx6-pcie-msi", pp);
 		if (ret) {
 			dev_err(&pdev->dev, "failed to request MSI irq\n");
 			return ret;
--- zfcpdump-kernel-4.4.orig/drivers/pci/host/pci-keystone-dw.c
+++ zfcpdump-kernel-4.4/drivers/pci/host/pci-keystone-dw.c
@@ -58,11 +58,6 @@
 
 #define to_keystone_pcie(x)	container_of(x, struct keystone_pcie, pp)
 
-static inline struct pcie_port *sys_to_pcie(struct pci_sys_data *sys)
-{
-	return sys->private_data;
-}
-
 static inline void update_reg_offset_bit_pos(u32 offset, u32 *reg_offset,
 					     u32 *bit_pos)
 {
@@ -108,7 +103,7 @@ static void ks_dw_pcie_msi_irq_ack(struc
 	struct pcie_port *pp;
 
 	msi = irq_data_get_msi_desc(d);
-	pp = sys_to_pcie(msi_desc_to_pci_sysdata(msi));
+	pp = (struct pcie_port *) msi_desc_to_pci_sysdata(msi);
 	ks_pcie = to_keystone_pcie(pp);
 	offset = d->irq - irq_linear_revmap(pp->irq_domain, 0);
 	update_reg_offset_bit_pos(offset, &reg_offset, &bit_pos);
@@ -146,7 +141,7 @@ static void ks_dw_pcie_msi_irq_mask(stru
 	u32 offset;
 
 	msi = irq_data_get_msi_desc(d);
-	pp = sys_to_pcie(msi_desc_to_pci_sysdata(msi));
+	pp = (struct pcie_port *) msi_desc_to_pci_sysdata(msi);
 	ks_pcie = to_keystone_pcie(pp);
 	offset = d->irq - irq_linear_revmap(pp->irq_domain, 0);
 
@@ -167,7 +162,7 @@ static void ks_dw_pcie_msi_irq_unmask(st
 	u32 offset;
 
 	msi = irq_data_get_msi_desc(d);
-	pp = sys_to_pcie(msi_desc_to_pci_sysdata(msi));
+	pp = (struct pcie_port *) msi_desc_to_pci_sysdata(msi);
 	ks_pcie = to_keystone_pcie(pp);
 	offset = d->irq - irq_linear_revmap(pp->irq_domain, 0);
 
--- zfcpdump-kernel-4.4.orig/drivers/pci/host/pci-tegra.c
+++ zfcpdump-kernel-4.4/drivers/pci/host/pci-tegra.c
@@ -1288,7 +1288,7 @@ static int tegra_pcie_enable_msi(struct
 
 	msi->irq = err;
 
-	err = request_irq(msi->irq, tegra_pcie_msi_irq, 0,
+	err = request_irq(msi->irq, tegra_pcie_msi_irq, IRQF_NO_THREAD,
 			  tegra_msi_irq_chip.name, pcie);
 	if (err < 0) {
 		dev_err(&pdev->dev, "failed to request IRQ: %d\n", err);
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/pci/host/pci-thunder-ecam.c
@@ -0,0 +1,403 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2015, 2016 Cavium, Inc.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/ioport.h>
+#include <linux/of_pci.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+
+#include "pci-host-common.h"
+
+/* Mapping is standard ECAM */
+static void __iomem *thunder_ecam_map_bus(struct pci_bus *bus,
+					  unsigned int devfn,
+					  int where)
+{
+	struct gen_pci *pci = bus->sysdata;
+	resource_size_t idx = bus->number - pci->cfg.bus_range->start;
+
+	return pci->cfg.win[idx] + ((devfn << 12) | where);
+}
+
+static void set_val(u32 v, int where, int size, u32 *val)
+{
+	int shift = (where & 3) * 8;
+
+	pr_debug("set_val %04x: %08x\n", (unsigned)(where & ~3), v);
+	v >>= shift;
+	if (size == 1)
+		v &= 0xff;
+	else if (size == 2)
+		v &= 0xffff;
+	*val = v;
+}
+
+static int handle_ea_bar(u32 e0, int bar, struct pci_bus *bus,
+			 unsigned int devfn, int where, int size, u32 *val)
+{
+	void __iomem *addr;
+	u32 v;
+
+	/* Entries are 16-byte aligned; bits[2,3] select word in entry */
+	int where_a = where & 0xc;
+
+	if (where_a == 0) {
+		set_val(e0, where, size, val);
+		return PCIBIOS_SUCCESSFUL;
+	}
+	if (where_a == 0x4) {
+		addr = bus->ops->map_bus(bus, devfn, bar); /* BAR 0 */
+		if (!addr) {
+			*val = ~0;
+			return PCIBIOS_DEVICE_NOT_FOUND;
+		}
+		v = readl(addr);
+		v &= ~0xf;
+		v |= 2; /* EA entry-1. Base-L */
+		set_val(v, where, size, val);
+		return PCIBIOS_SUCCESSFUL;
+	}
+	if (where_a == 0x8) {
+		u32 barl_orig;
+		u32 barl_rb;
+
+		addr = bus->ops->map_bus(bus, devfn, bar); /* BAR 0 */
+		if (!addr) {
+			*val = ~0;
+			return PCIBIOS_DEVICE_NOT_FOUND;
+		}
+		barl_orig = readl(addr + 0);
+		writel(0xffffffff, addr + 0);
+		barl_rb = readl(addr + 0);
+		writel(barl_orig, addr + 0);
+		/* zeros in unsettable bits */
+		v = ~barl_rb & ~3;
+		v |= 0xc; /* EA entry-2. Offset-L */
+		set_val(v, where, size, val);
+		return PCIBIOS_SUCCESSFUL;
+	}
+	if (where_a == 0xc) {
+		addr = bus->ops->map_bus(bus, devfn, bar + 4); /* BAR 1 */
+		if (!addr) {
+			*val = ~0;
+			return PCIBIOS_DEVICE_NOT_FOUND;
+		}
+		v = readl(addr); /* EA entry-3. Base-H */
+		set_val(v, where, size, val);
+		return PCIBIOS_SUCCESSFUL;
+	}
+	return PCIBIOS_DEVICE_NOT_FOUND;
+}
+
+static int thunder_ecam_p2_config_read(struct pci_bus *bus, unsigned int devfn,
+				       int where, int size, u32 *val)
+{
+	struct gen_pci *pci = bus->sysdata;
+	int where_a = where & ~3;
+	void __iomem *addr;
+	u32 node_bits;
+	u32 v;
+
+	/* EA Base[63:32] may be missing some bits ... */
+	switch (where_a) {
+	case 0xa8:
+	case 0xbc:
+	case 0xd0:
+	case 0xe4:
+		break;
+	default:
+		return pci_generic_config_read(bus, devfn, where, size, val);
+	}
+
+	addr = bus->ops->map_bus(bus, devfn, where_a);
+	if (!addr) {
+		*val = ~0;
+		return PCIBIOS_DEVICE_NOT_FOUND;
+	}
+
+	v = readl(addr);
+
+	/*
+	 * Bit 44 of the 64-bit Base must match the same bit in
+	 * the config space access window.  Since we are working with
+	 * the high-order 32 bits, shift everything down by 32 bits.
+	 */
+	node_bits = (pci->cfg.res.start >> 32) & (1 << 12);
+
+	v |= node_bits;
+	set_val(v, where, size, val);
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int thunder_ecam_config_read(struct pci_bus *bus, unsigned int devfn,
+				    int where, int size, u32 *val)
+{
+	u32 v;
+	u32 vendor_device;
+	u32 class_rev;
+	void __iomem *addr;
+	int cfg_type;
+	int where_a = where & ~3;
+
+	addr = bus->ops->map_bus(bus, devfn, 0xc);
+	if (!addr) {
+		*val = ~0;
+		return PCIBIOS_DEVICE_NOT_FOUND;
+	}
+
+	v = readl(addr);
+
+	/* Check for non type-00 header */
+	cfg_type = (v >> 16) & 0x7f;
+
+	addr = bus->ops->map_bus(bus, devfn, 8);
+	if (!addr) {
+		*val = ~0;
+		return PCIBIOS_DEVICE_NOT_FOUND;
+	}
+
+	class_rev = readl(addr);
+	if (class_rev == 0xffffffff)
+		goto no_emulation;
+
+	if ((class_rev & 0xff) >= 8) {
+		/* Pass-2 handling */
+		if (cfg_type)
+			goto no_emulation;
+		return thunder_ecam_p2_config_read(bus, devfn, where,
+						   size, val);
+	}
+
+	/*
+	 * All BARs have fixed addresses specified by the EA
+	 * capability; they must return zero on read.
+	 */
+	if (cfg_type == 0 &&
+	    ((where >= 0x10 && where < 0x2c) ||
+	     (where >= 0x1a4 && where < 0x1bc))) {
+		/* BAR or SR-IOV BAR */
+		*val = 0;
+		return PCIBIOS_SUCCESSFUL;
+	}
+
+	addr = bus->ops->map_bus(bus, devfn, 0);
+	if (!addr) {
+		*val = ~0;
+		return PCIBIOS_DEVICE_NOT_FOUND;
+	}
+
+	vendor_device = readl(addr);
+	if (vendor_device == 0xffffffff)
+		goto no_emulation;
+
+	pr_debug("%04x:%04x - Fix pass#: %08x, where: %03x, devfn: %03x\n",
+		 vendor_device & 0xffff, vendor_device >> 16, class_rev,
+		 (unsigned) where, devfn);
+
+	/* Check for non type-00 header */
+	if (cfg_type == 0) {
+		bool has_msix;
+		bool is_nic = (vendor_device == 0xa01e177d);
+		bool is_tns = (vendor_device == 0xa01f177d);
+
+		addr = bus->ops->map_bus(bus, devfn, 0x70);
+		if (!addr) {
+			*val = ~0;
+			return PCIBIOS_DEVICE_NOT_FOUND;
+		}
+		/* E_CAP */
+		v = readl(addr);
+		has_msix = (v & 0xff00) != 0;
+
+		if (!has_msix && where_a == 0x70) {
+			v |= 0xbc00; /* next capability is EA at 0xbc */
+			set_val(v, where, size, val);
+			return PCIBIOS_SUCCESSFUL;
+		}
+		if (where_a == 0xb0) {
+			addr = bus->ops->map_bus(bus, devfn, where_a);
+			if (!addr) {
+				*val = ~0;
+				return PCIBIOS_DEVICE_NOT_FOUND;
+			}
+			v = readl(addr);
+			if (v & 0xff00)
+				pr_err("Bad MSIX cap header: %08x\n", v);
+			v |= 0xbc00; /* next capability is EA at 0xbc */
+			set_val(v, where, size, val);
+			return PCIBIOS_SUCCESSFUL;
+		}
+		if (where_a == 0xbc) {
+			if (is_nic)
+				v = 0x40014; /* EA last in chain, 4 entries */
+			else if (is_tns)
+				v = 0x30014; /* EA last in chain, 3 entries */
+			else if (has_msix)
+				v = 0x20014; /* EA last in chain, 2 entries */
+			else
+				v = 0x10014; /* EA last in chain, 1 entry */
+			set_val(v, where, size, val);
+			return PCIBIOS_SUCCESSFUL;
+		}
+		if (where_a >= 0xc0 && where_a < 0xd0)
+			/* EA entry-0. PP=0, BAR0 Size:3 */
+			return handle_ea_bar(0x80ff0003,
+					     0x10, bus, devfn, where,
+					     size, val);
+		if (where_a >= 0xd0 && where_a < 0xe0 && has_msix)
+			 /* EA entry-1. PP=0, BAR4 Size:3 */
+			return handle_ea_bar(0x80ff0043,
+					     0x20, bus, devfn, where,
+					     size, val);
+		if (where_a >= 0xe0 && where_a < 0xf0 && is_tns)
+			/* EA entry-2. PP=0, BAR2, Size:3 */
+			return handle_ea_bar(0x80ff0023,
+					     0x18, bus, devfn, where,
+					     size, val);
+		if (where_a >= 0xe0 && where_a < 0xf0 && is_nic)
+			/* EA entry-2. PP=4, VF_BAR0 (9), Size:3 */
+			return handle_ea_bar(0x80ff0493,
+					     0x1a4, bus, devfn, where,
+					     size, val);
+		if (where_a >= 0xf0 && where_a < 0x100 && is_nic)
+			/* EA entry-3. PP=4, VF_BAR4 (d), Size:3 */
+			return handle_ea_bar(0x80ff04d3,
+					     0x1b4, bus, devfn, where,
+					     size, val);
+	} else if (cfg_type == 1) {
+		bool is_rsl_bridge = devfn == 0x08;
+		bool is_rad_bridge = devfn == 0xa0;
+		bool is_zip_bridge = devfn == 0xa8;
+		bool is_dfa_bridge = devfn == 0xb0;
+		bool is_nic_bridge = devfn == 0x10;
+
+		if (where_a == 0x70) {
+			addr = bus->ops->map_bus(bus, devfn, where_a);
+			if (!addr) {
+				*val = ~0;
+				return PCIBIOS_DEVICE_NOT_FOUND;
+			}
+			v = readl(addr);
+			if (v & 0xff00)
+				pr_err("Bad PCIe cap header: %08x\n", v);
+			v |= 0xbc00; /* next capability is EA at 0xbc */
+			set_val(v, where, size, val);
+			return PCIBIOS_SUCCESSFUL;
+		}
+		if (where_a == 0xbc) {
+			if (is_nic_bridge)
+				v = 0x10014; /* EA last in chain, 1 entry */
+			else
+				v = 0x00014; /* EA last in chain, no entries */
+			set_val(v, where, size, val);
+			return PCIBIOS_SUCCESSFUL;
+		}
+		if (where_a == 0xc0) {
+			if (is_rsl_bridge || is_nic_bridge)
+				v = 0x0101; /* subordinate:secondary = 1:1 */
+			else if (is_rad_bridge)
+				v = 0x0202; /* subordinate:secondary = 2:2 */
+			else if (is_zip_bridge)
+				v = 0x0303; /* subordinate:secondary = 3:3 */
+			else if (is_dfa_bridge)
+				v = 0x0404; /* subordinate:secondary = 4:4 */
+			set_val(v, where, size, val);
+			return PCIBIOS_SUCCESSFUL;
+		}
+		if (where_a == 0xc4 && is_nic_bridge) {
+			/* Enabled, not-Write, SP=ff, PP=05, BEI=6, ES=4 */
+			v = 0x80ff0564;
+			set_val(v, where, size, val);
+			return PCIBIOS_SUCCESSFUL;
+		}
+		if (where_a == 0xc8 && is_nic_bridge) {
+			v = 0x00000002; /* Base-L 64-bit */
+			set_val(v, where, size, val);
+			return PCIBIOS_SUCCESSFUL;
+		}
+		if (where_a == 0xcc && is_nic_bridge) {
+			v = 0xfffffffe; /* MaxOffset-L 64-bit */
+			set_val(v, where, size, val);
+			return PCIBIOS_SUCCESSFUL;
+		}
+		if (where_a == 0xd0 && is_nic_bridge) {
+			v = 0x00008430; /* NIC Base-H */
+			set_val(v, where, size, val);
+			return PCIBIOS_SUCCESSFUL;
+		}
+		if (where_a == 0xd4 && is_nic_bridge) {
+			v = 0x0000000f; /* MaxOffset-H */
+			set_val(v, where, size, val);
+			return PCIBIOS_SUCCESSFUL;
+		}
+	}
+no_emulation:
+	return pci_generic_config_read(bus, devfn, where, size, val);
+}
+
+static int thunder_ecam_config_write(struct pci_bus *bus, unsigned int devfn,
+				     int where, int size, u32 val)
+{
+	/*
+	 * All BARs have fixed addresses; ignore BAR writes so they
+	 * don't get corrupted.
+	 */
+	if ((where >= 0x10 && where < 0x2c) ||
+	    (where >= 0x1a4 && where < 0x1bc))
+		/* BAR or SR-IOV BAR */
+		return PCIBIOS_SUCCESSFUL;
+
+	return pci_generic_config_write(bus, devfn, where, size, val);
+}
+
+static struct gen_pci_cfg_bus_ops thunder_ecam_bus_ops = {
+	.bus_shift	= 20,
+	.ops		= {
+		.map_bus        = thunder_ecam_map_bus,
+		.read           = thunder_ecam_config_read,
+		.write          = thunder_ecam_config_write,
+	}
+};
+
+static const struct of_device_id thunder_ecam_of_match[] = {
+	{ .compatible = "cavium,pci-host-thunder-ecam",
+	  .data = &thunder_ecam_bus_ops },
+
+	{ },
+};
+MODULE_DEVICE_TABLE(of, thunder_ecam_of_match);
+
+static int thunder_ecam_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	const struct of_device_id *of_id;
+	struct gen_pci *pci = devm_kzalloc(dev, sizeof(*pci), GFP_KERNEL);
+
+	if (!pci)
+		return -ENOMEM;
+
+	of_id = of_match_node(thunder_ecam_of_match, dev->of_node);
+	pci->cfg.ops = (struct gen_pci_cfg_bus_ops *)of_id->data;
+
+	return pci_host_common_probe(pdev, pci);
+}
+
+static struct platform_driver thunder_ecam_driver = {
+	.driver = {
+		.name = KBUILD_MODNAME,
+		.of_match_table = thunder_ecam_of_match,
+	},
+	.probe = thunder_ecam_probe,
+};
+module_platform_driver(thunder_ecam_driver);
+
+MODULE_DESCRIPTION("Thunder ECAM PCI host driver");
+MODULE_LICENSE("GPL v2");
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/pci/host/pci-thunder-pem.c
@@ -0,0 +1,346 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Copyright (C) 2015 - 2016 Cavium, Inc.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of_address.h>
+#include <linux/of_pci.h>
+#include <linux/platform_device.h>
+
+#include "pci-host-common.h"
+
+#define PEM_CFG_WR 0x28
+#define PEM_CFG_RD 0x30
+
+struct thunder_pem_pci {
+	struct gen_pci	gen_pci;
+	u32		ea_entry[3];
+	void __iomem	*pem_reg_base;
+};
+
+static void __iomem *thunder_pem_map_bus(struct pci_bus *bus,
+					 unsigned int devfn, int where)
+{
+	struct gen_pci *pci = bus->sysdata;
+	resource_size_t idx = bus->number - pci->cfg.bus_range->start;
+
+	return pci->cfg.win[idx] + ((devfn << 16) | where);
+}
+
+static int thunder_pem_bridge_read(struct pci_bus *bus, unsigned int devfn,
+				   int where, int size, u32 *val)
+{
+	u64 read_val;
+	struct thunder_pem_pci *pem_pci;
+	struct gen_pci *pci = bus->sysdata;
+
+	pem_pci = container_of(pci, struct thunder_pem_pci, gen_pci);
+
+	if (devfn != 0 || where >= 2048) {
+		*val = ~0;
+		return PCIBIOS_DEVICE_NOT_FOUND;
+	}
+
+	/*
+	 * 32-bit accesses only.  Write the address to the low order
+	 * bits of PEM_CFG_RD, then trigger the read by reading back.
+	 * The config data lands in the upper 32-bits of PEM_CFG_RD.
+	 */
+	read_val = where & ~3ull;
+	writeq(read_val, pem_pci->pem_reg_base + PEM_CFG_RD);
+	read_val = readq(pem_pci->pem_reg_base + PEM_CFG_RD);
+	read_val >>= 32;
+
+	/*
+	 * The config space contains some garbage, fix it up.  Also
+	 * synthesize an EA capability for the BAR used by MSI-X.
+	 */
+	switch (where & ~3) {
+	case 0x40:
+		read_val &= 0xffff00ff;
+		read_val |= 0x00007000; /* Skip MSI CAP */
+		break;
+	case 0x70: /* Express Cap */
+		/* PME interrupt on vector 2*/
+		read_val |= (2u << 25);
+		break;
+	case 0xb0: /* MSI-X Cap */
+		/* TableSize=4, Next Cap is EA */
+		read_val &= 0xc00000ff;
+		read_val |= 0x0003bc00;
+		break;
+	case 0xb4:
+		/* Table offset=0, BIR=0 */
+		read_val = 0x00000000;
+		break;
+	case 0xb8:
+		/* BPA offset=0xf0000, BIR=0 */
+		read_val = 0x000f0000;
+		break;
+	case 0xbc:
+		/* EA, 1 entry, no next Cap */
+		read_val = 0x00010014;
+		break;
+	case 0xc0:
+		/* DW2 for type-1 */
+		read_val = 0x00000000;
+		break;
+	case 0xc4:
+		/* Entry BEI=0, PP=0x00, SP=0xff, ES=3 */
+		read_val = 0x80ff0003;
+		break;
+	case 0xc8:
+		read_val = pem_pci->ea_entry[0];
+		break;
+	case 0xcc:
+		read_val = pem_pci->ea_entry[1];
+		break;
+	case 0xd0:
+		read_val = pem_pci->ea_entry[2];
+		break;
+	default:
+		break;
+	}
+	read_val >>= (8 * (where & 3));
+	switch (size) {
+	case 1:
+		read_val &= 0xff;
+		break;
+	case 2:
+		read_val &= 0xffff;
+		break;
+	default:
+		break;
+	}
+	*val = read_val;
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int thunder_pem_config_read(struct pci_bus *bus, unsigned int devfn,
+				   int where, int size, u32 *val)
+{
+	struct gen_pci *pci = bus->sysdata;
+
+	if (bus->number < pci->cfg.bus_range->start ||
+	    bus->number > pci->cfg.bus_range->end)
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	/*
+	 * The first device on the bus is the PEM PCIe bridge.
+	 * Special case its config access.
+	 */
+	if (bus->number == pci->cfg.bus_range->start)
+		return thunder_pem_bridge_read(bus, devfn, where, size, val);
+
+	return pci_generic_config_read(bus, devfn, where, size, val);
+}
+
+/*
+ * Some of the w1c_bits below also include read-only or non-writable
+ * reserved bits, this makes the code simpler and is OK as the bits
+ * are not affected by writing zeros to them.
+ */
+static u32 thunder_pem_bridge_w1c_bits(int where)
+{
+	u32 w1c_bits = 0;
+
+	switch (where & ~3) {
+	case 0x04: /* Command/Status */
+	case 0x1c: /* Base and I/O Limit/Secondary Status */
+		w1c_bits = 0xff000000;
+		break;
+	case 0x44: /* Power Management Control and Status */
+		w1c_bits = 0xfffffe00;
+		break;
+	case 0x78: /* Device Control/Device Status */
+	case 0x80: /* Link Control/Link Status */
+	case 0x88: /* Slot Control/Slot Status */
+	case 0x90: /* Root Status */
+	case 0xa0: /* Link Control 2 Registers/Link Status 2 */
+		w1c_bits = 0xffff0000;
+		break;
+	case 0x104: /* Uncorrectable Error Status */
+	case 0x110: /* Correctable Error Status */
+	case 0x130: /* Error Status */
+	case 0x160: /* Link Control 4 */
+		w1c_bits = 0xffffffff;
+		break;
+	default:
+		break;
+	}
+	return w1c_bits;
+}
+
+static int thunder_pem_bridge_write(struct pci_bus *bus, unsigned int devfn,
+				    int where, int size, u32 val)
+{
+	struct gen_pci *pci = bus->sysdata;
+	struct thunder_pem_pci *pem_pci;
+	u64 write_val, read_val;
+	u32 mask = 0;
+
+	pem_pci = container_of(pci, struct thunder_pem_pci, gen_pci);
+
+	if (devfn != 0 || where >= 2048)
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	/*
+	 * 32-bit accesses only.  If the write is for a size smaller
+	 * than 32-bits, we must first read the 32-bit value and merge
+	 * in the desired bits and then write the whole 32-bits back
+	 * out.
+	 */
+	switch (size) {
+	case 1:
+		read_val = where & ~3ull;
+		writeq(read_val, pem_pci->pem_reg_base + PEM_CFG_RD);
+		read_val = readq(pem_pci->pem_reg_base + PEM_CFG_RD);
+		read_val >>= 32;
+		mask = ~(0xff << (8 * (where & 3)));
+		read_val &= mask;
+		val = (val & 0xff) << (8 * (where & 3));
+		val |= (u32)read_val;
+		break;
+	case 2:
+		read_val = where & ~3ull;
+		writeq(read_val, pem_pci->pem_reg_base + PEM_CFG_RD);
+		read_val = readq(pem_pci->pem_reg_base + PEM_CFG_RD);
+		read_val >>= 32;
+		mask = ~(0xffff << (8 * (where & 3)));
+		read_val &= mask;
+		val = (val & 0xffff) << (8 * (where & 3));
+		val |= (u32)read_val;
+		break;
+	default:
+		break;
+	}
+
+	/*
+	 * By expanding the write width to 32 bits, we may
+	 * inadvertently hit some W1C bits that were not intended to
+	 * be written.  Calculate the mask that must be applied to the
+	 * data to be written to avoid these cases.
+	 */
+	if (mask) {
+		u32 w1c_bits = thunder_pem_bridge_w1c_bits(where);
+
+		if (w1c_bits) {
+			mask &= w1c_bits;
+			val &= ~mask;
+		}
+	}
+
+	/*
+	 * Low order bits are the config address, the high order 32
+	 * bits are the data to be written.
+	 */
+	write_val = where & ~3ull;
+	write_val |= (((u64)val) << 32);
+	writeq(write_val, pem_pci->pem_reg_base + PEM_CFG_WR);
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int thunder_pem_config_write(struct pci_bus *bus, unsigned int devfn,
+				    int where, int size, u32 val)
+{
+	struct gen_pci *pci = bus->sysdata;
+
+	if (bus->number < pci->cfg.bus_range->start ||
+	    bus->number > pci->cfg.bus_range->end)
+		return PCIBIOS_DEVICE_NOT_FOUND;
+	/*
+	 * The first device on the bus is the PEM PCIe bridge.
+	 * Special case its config access.
+	 */
+	if (bus->number == pci->cfg.bus_range->start)
+		return thunder_pem_bridge_write(bus, devfn, where, size, val);
+
+
+	return pci_generic_config_write(bus, devfn, where, size, val);
+}
+
+static struct gen_pci_cfg_bus_ops thunder_pem_bus_ops = {
+	.bus_shift	= 24,
+	.ops		= {
+		.map_bus	= thunder_pem_map_bus,
+		.read		= thunder_pem_config_read,
+		.write		= thunder_pem_config_write,
+	}
+};
+
+static const struct of_device_id thunder_pem_of_match[] = {
+	{ .compatible = "cavium,pci-host-thunder-pem",
+	  .data = &thunder_pem_bus_ops },
+
+	{ },
+};
+MODULE_DEVICE_TABLE(of, thunder_pem_of_match);
+
+static int thunder_pem_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	const struct of_device_id *of_id;
+	resource_size_t bar4_start;
+	struct resource *res_pem;
+	struct thunder_pem_pci *pem_pci;
+
+	pem_pci = devm_kzalloc(dev, sizeof(*pem_pci), GFP_KERNEL);
+	if (!pem_pci)
+		return -ENOMEM;
+
+	of_id = of_match_node(thunder_pem_of_match, dev->of_node);
+	pem_pci->gen_pci.cfg.ops = (struct gen_pci_cfg_bus_ops *)of_id->data;
+
+	/*
+	 * The second register range is the PEM bridge to the PCIe
+	 * bus.  It has a different config access method than those
+	 * devices behind the bridge.
+	 */
+	res_pem = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+	if (!res_pem) {
+		dev_err(dev, "missing \"reg[1]\"property\n");
+		return -EINVAL;
+	}
+
+	pem_pci->pem_reg_base = devm_ioremap(dev, res_pem->start, 0x10000);
+	if (!pem_pci->pem_reg_base)
+		return -ENOMEM;
+
+	/*
+	 * The MSI-X BAR for the PEM and AER interrupts is located at
+	 * a fixed offset from the PEM register base.  Generate a
+	 * fragment of the synthesized Enhanced Allocation capability
+	 * structure here for the BAR.
+	 */
+	bar4_start = res_pem->start + 0xf00000;
+	pem_pci->ea_entry[0] = (u32)bar4_start | 2;
+	pem_pci->ea_entry[1] = (u32)(res_pem->end - bar4_start) & ~3u;
+	pem_pci->ea_entry[2] = (u32)(bar4_start >> 32);
+
+	return pci_host_common_probe(pdev, &pem_pci->gen_pci);
+}
+
+static struct platform_driver thunder_pem_driver = {
+	.driver = {
+		.name = KBUILD_MODNAME,
+		.of_match_table = thunder_pem_of_match,
+	},
+	.probe = thunder_pem_probe,
+};
+module_platform_driver(thunder_pem_driver);
+
+MODULE_DESCRIPTION("Thunder PEM PCIe host driver");
+MODULE_LICENSE("GPL v2");
--- zfcpdump-kernel-4.4.orig/drivers/pci/host/pcie-rcar.c
+++ zfcpdump-kernel-4.4/drivers/pci/host/pcie-rcar.c
@@ -720,14 +720,16 @@ static int rcar_pcie_enable_msi(struct r
 
 	/* Two irqs are for MSI, but they are also used for non-MSI irqs */
 	err = devm_request_irq(&pdev->dev, msi->irq1, rcar_pcie_msi_irq,
-			       IRQF_SHARED, rcar_msi_irq_chip.name, pcie);
+			       IRQF_SHARED | IRQF_NO_THREAD,
+			       rcar_msi_irq_chip.name, pcie);
 	if (err < 0) {
 		dev_err(&pdev->dev, "failed to request IRQ: %d\n", err);
 		goto err;
 	}
 
 	err = devm_request_irq(&pdev->dev, msi->irq2, rcar_pcie_msi_irq,
-			       IRQF_SHARED, rcar_msi_irq_chip.name, pcie);
+			       IRQF_SHARED | IRQF_NO_THREAD,
+			       rcar_msi_irq_chip.name, pcie);
 	if (err < 0) {
 		dev_err(&pdev->dev, "failed to request IRQ: %d\n", err);
 		goto err;
--- zfcpdump-kernel-4.4.orig/drivers/pci/host/pcie-spear13xx.c
+++ zfcpdump-kernel-4.4/drivers/pci/host/pcie-spear13xx.c
@@ -279,7 +279,8 @@ static int spear13xx_add_pcie_port(struc
 		return -ENODEV;
 	}
 	ret = devm_request_irq(dev, pp->irq, spear13xx_pcie_irq_handler,
-			       IRQF_SHARED, "spear1340-pcie", pp);
+			       IRQF_SHARED | IRQF_NO_THREAD,
+			       "spear1340-pcie", pp);
 	if (ret) {
 		dev_err(dev, "failed to request irq %d\n", pp->irq);
 		return ret;
--- zfcpdump-kernel-4.4.orig/drivers/pci/host/pcie-xilinx.c
+++ zfcpdump-kernel-4.4/drivers/pci/host/pcie-xilinx.c
@@ -781,7 +781,8 @@ static int xilinx_pcie_parse_dt(struct x
 
 	port->irq = irq_of_parse_and_map(node, 0);
 	err = devm_request_irq(dev, port->irq, xilinx_pcie_intr_handler,
-			       IRQF_SHARED, "xilinx-pcie", port);
+			       IRQF_SHARED | IRQF_NO_THREAD,
+			       "xilinx-pcie", port);
 	if (err) {
 		dev_err(dev, "unable to request irq %d\n", port->irq);
 		return err;
--- zfcpdump-kernel-4.4.orig/drivers/pci/hotplug/acpiphp_glue.c
+++ zfcpdump-kernel-4.4/drivers/pci/hotplug/acpiphp_glue.c
@@ -953,8 +953,10 @@ int acpiphp_enable_slot(struct acpiphp_s
 {
 	pci_lock_rescan_remove();
 
-	if (slot->flags & SLOT_IS_GOING_AWAY)
+	if (slot->flags & SLOT_IS_GOING_AWAY) {
+		pci_unlock_rescan_remove();
 		return -ENODEV;
+	}
 
 	/* configure all functions */
 	if (!(slot->flags & SLOT_ENABLED))
--- zfcpdump-kernel-4.4.orig/drivers/pci/hotplug/rpaphp_slot.c
+++ zfcpdump-kernel-4.4/drivers/pci/hotplug/rpaphp_slot.c
@@ -117,8 +117,10 @@ EXPORT_SYMBOL_GPL(rpaphp_deregister_slot
 int rpaphp_register_slot(struct slot *slot)
 {
 	struct hotplug_slot *php_slot = slot->hotplug_slot;
+	struct device_node *child;
+	u32 my_index;
 	int retval;
-	int slotno;
+	int slotno = -1;
 
 	dbg("%s registering slot:path[%s] index[%x], name[%s] pdomain[%x] type[%d]\n",
 		__func__, slot->dn->full_name, slot->index, slot->name,
@@ -130,10 +132,15 @@ int rpaphp_register_slot(struct slot *sl
 		return -EAGAIN;
 	}
 
-	if (slot->dn->child)
-		slotno = PCI_SLOT(PCI_DN(slot->dn->child)->devfn);
-	else
-		slotno = -1;
+	for_each_child_of_node(slot->dn, child) {
+		retval = of_property_read_u32(child, "ibm,my-drc-index", &my_index);
+		if (my_index == slot->index) {
+			slotno = PCI_SLOT(PCI_DN(child)->devfn);
+			of_node_put(child);
+			break;
+		}
+	}
+
 	retval = pci_hp_register(php_slot, slot->bus, slotno, slot->name);
 	if (retval) {
 		err("pci_hp_register failed with error %d\n", retval);
--- zfcpdump-kernel-4.4.orig/drivers/pci/hotplug/s390_pci_hpc.c
+++ zfcpdump-kernel-4.4/drivers/pci/hotplug/s390_pci_hpc.c
@@ -93,13 +93,17 @@ out_deconfigure:
 static int disable_slot(struct hotplug_slot *hotplug_slot)
 {
 	struct slot *slot = hotplug_slot->private;
+	struct pci_dev *pdev;
 	int rc;
 
 	if (!zpci_fn_configured(slot->zdev->state))
 		return -EIO;
 
-	if (slot->zdev->pdev)
-		pci_stop_and_remove_bus_device_locked(slot->zdev->pdev);
+	pdev = pci_get_slot(slot->zdev->bus, ZPCI_DEVFN);
+	if (pdev) {
+		pci_stop_and_remove_bus_device_locked(pdev);
+		pci_dev_put(pdev);
+	}
 
 	rc = zpci_disable_device(slot->zdev);
 	if (rc)
--- zfcpdump-kernel-4.4.orig/drivers/pci/msi.c
+++ zfcpdump-kernel-4.4/drivers/pci/msi.c
@@ -257,6 +257,7 @@ void pci_msi_mask_irq(struct irq_data *d
 {
 	msi_set_mask_bit(data, 1);
 }
+EXPORT_SYMBOL_GPL(pci_msi_mask_irq);
 
 /**
  * pci_msi_unmask_irq - Generic irq chip callback to unmask PCI/MSI interrupts
@@ -266,6 +267,7 @@ void pci_msi_unmask_irq(struct irq_data
 {
 	msi_set_mask_bit(data, 0);
 }
+EXPORT_SYMBOL_GPL(pci_msi_unmask_irq);
 
 void default_restore_msi_irqs(struct pci_dev *dev)
 {
@@ -1126,6 +1128,7 @@ struct pci_dev *msi_desc_to_pci_dev(stru
 {
 	return to_pci_dev(desc->dev);
 }
+EXPORT_SYMBOL(msi_desc_to_pci_dev);
 
 void *msi_desc_to_pci_sysdata(struct msi_desc *desc)
 {
@@ -1278,6 +1281,8 @@ struct irq_domain *pci_msi_create_irq_do
 	if (info->flags & MSI_FLAG_USE_DEF_CHIP_OPS)
 		pci_msi_domain_update_chip_ops(info);
 
+	info->flags |= MSI_FLAG_ACTIVATE_EARLY;
+
 	domain = msi_create_irq_domain(fwnode, info, parent);
 	if (!domain)
 		return NULL;
@@ -1285,6 +1290,7 @@ struct irq_domain *pci_msi_create_irq_do
 	domain->bus_token = DOMAIN_BUS_PCI_MSI;
 	return domain;
 }
+EXPORT_SYMBOL_GPL(pci_msi_create_irq_domain);
 
 /**
  * pci_msi_domain_alloc_irqs - Allocate interrupts for @dev in @domain
--- zfcpdump-kernel-4.4.orig/drivers/pci/pci-acpi.c
+++ zfcpdump-kernel-4.4/drivers/pci/pci-acpi.c
@@ -9,7 +9,9 @@
 
 #include <linux/delay.h>
 #include <linux/init.h>
+#include <linux/irqdomain.h>
 #include <linux/pci.h>
+#include <linux/msi.h>
 #include <linux/pci_hotplug.h>
 #include <linux/module.h>
 #include <linux/pci-aspm.h>
@@ -689,6 +691,46 @@ static struct acpi_bus_type acpi_pci_bus
 	.cleanup = pci_acpi_cleanup,
 };
 
+
+static struct fwnode_handle *(*pci_msi_get_fwnode_cb)(struct device *dev);
+
+/**
+ * pci_msi_register_fwnode_provider - Register callback to retrieve fwnode
+ * @fn:       Callback matching a device to a fwnode that identifies a PCI
+ *            MSI domain.
+ *
+ * This should be called by irqchip driver, which is the parent of
+ * the MSI domain to provide callback interface to query fwnode.
+ */
+void
+pci_msi_register_fwnode_provider(struct fwnode_handle *(*fn)(struct device *))
+{
+	pci_msi_get_fwnode_cb = fn;
+}
+
+/**
+ * pci_host_bridge_acpi_msi_domain - Retrieve MSI domain of a PCI host bridge
+ * @bus:      The PCI host bridge bus.
+ *
+ * This function uses the callback function registered by
+ * pci_msi_register_fwnode_provider() to retrieve the irq_domain with
+ * type DOMAIN_BUS_PCI_MSI of the specified host bridge bus.
+ * This returns NULL on error or when the domain is not found.
+ */
+struct irq_domain *pci_host_bridge_acpi_msi_domain(struct pci_bus *bus)
+{
+	struct fwnode_handle *fwnode;
+
+	if (!pci_msi_get_fwnode_cb)
+		return NULL;
+
+	fwnode = pci_msi_get_fwnode_cb(&bus->dev);
+	if (!fwnode)
+		return NULL;
+
+	return irq_find_matching_fwnode(fwnode, DOMAIN_BUS_PCI_MSI);
+}
+
 static int __init acpi_pci_init(void)
 {
 	int ret;
--- zfcpdump-kernel-4.4.orig/drivers/pci/pci-sysfs.c
+++ zfcpdump-kernel-4.4/drivers/pci/pci-sysfs.c
@@ -30,6 +30,7 @@
 #include <linux/vgaarb.h>
 #include <linux/pm_runtime.h>
 #include <linux/of.h>
+#include <linux/module.h>
 #include "pci.h"
 
 static int sysfs_initialized;	/* = 0 */
@@ -713,6 +714,9 @@ static ssize_t pci_write_config(struct f
 	loff_t init_off = off;
 	u8 *data = (u8 *) buf;
 
+	if (secure_modules())
+		return -EPERM;
+
 	if (off > dev->cfg_size)
 		return 0;
 	if (off + count > dev->cfg_size) {
@@ -1007,6 +1011,9 @@ static int pci_mmap_resource(struct kobj
 	resource_size_t start, end;
 	int i;
 
+	if (secure_modules())
+		return -EPERM;
+
 	for (i = 0; i < PCI_ROM_RESOURCE; i++)
 		if (res == &pdev->resource[i])
 			break;
@@ -1108,6 +1115,9 @@ static ssize_t pci_write_resource_io(str
 				     struct bin_attribute *attr, char *buf,
 				     loff_t off, size_t count)
 {
+	if (secure_modules())
+		return -EPERM;
+
 	return pci_resource_io(filp, kobj, attr, buf, off, count, true);
 }
 
@@ -1372,10 +1382,10 @@ int __must_check pci_create_sysfs_dev_fi
 	if (!sysfs_initialized)
 		return -EACCES;
 
-	if (pdev->cfg_size < PCI_CFG_SPACE_EXP_SIZE)
-		retval = sysfs_create_bin_file(&pdev->dev.kobj, &pci_config_attr);
-	else
+	if (pdev->cfg_size > PCI_CFG_SPACE_SIZE)
 		retval = sysfs_create_bin_file(&pdev->dev.kobj, &pcie_config_attr);
+	else
+		retval = sysfs_create_bin_file(&pdev->dev.kobj, &pci_config_attr);
 	if (retval)
 		goto err;
 
@@ -1427,10 +1437,10 @@ err_rom_file:
 err_resource_files:
 	pci_remove_resource_files(pdev);
 err_config_file:
-	if (pdev->cfg_size < PCI_CFG_SPACE_EXP_SIZE)
-		sysfs_remove_bin_file(&pdev->dev.kobj, &pci_config_attr);
-	else
+	if (pdev->cfg_size > PCI_CFG_SPACE_SIZE)
 		sysfs_remove_bin_file(&pdev->dev.kobj, &pcie_config_attr);
+	else
+		sysfs_remove_bin_file(&pdev->dev.kobj, &pci_config_attr);
 err:
 	return retval;
 }
@@ -1464,10 +1474,10 @@ void pci_remove_sysfs_dev_files(struct p
 
 	pci_remove_capabilities_sysfs(pdev);
 
-	if (pdev->cfg_size < PCI_CFG_SPACE_EXP_SIZE)
-		sysfs_remove_bin_file(&pdev->dev.kobj, &pci_config_attr);
-	else
+	if (pdev->cfg_size > PCI_CFG_SPACE_SIZE)
 		sysfs_remove_bin_file(&pdev->dev.kobj, &pcie_config_attr);
+	else
+		sysfs_remove_bin_file(&pdev->dev.kobj, &pci_config_attr);
 
 	pci_remove_resource_files(pdev);
 
--- zfcpdump-kernel-4.4.orig/drivers/pci/pci.c
+++ zfcpdump-kernel-4.4/drivers/pci/pci.c
@@ -4772,8 +4772,10 @@ int pci_get_new_domain_nr(void)
 void pci_bus_assign_domain_nr(struct pci_bus *bus, struct device *parent)
 {
 	static int use_dt_domains = -1;
-	int domain = of_get_pci_domain_nr(parent->of_node);
+	int domain = -1;
 
+	if (parent)
+		domain = of_get_pci_domain_nr(parent->of_node);
 	/*
 	 * Check DT domain and use_dt_domains values.
 	 *
--- zfcpdump-kernel-4.4.orig/drivers/pci/pcie/aer/aerdrv.c
+++ zfcpdump-kernel-4.4/drivers/pci/pcie/aer/aerdrv.c
@@ -262,7 +262,6 @@ static struct aer_rpc *aer_alloc_rpc(str
 	rpc->rpd = dev;
 	INIT_WORK(&rpc->dpc_handler, aer_isr);
 	mutex_init(&rpc->rpc_mutex);
-	init_waitqueue_head(&rpc->wait_release);
 
 	/* Use PCIe bus function to store rpc into PCIe device */
 	set_service_data(dev, rpc);
@@ -285,8 +284,7 @@ static void aer_remove(struct pcie_devic
 		if (rpc->isr)
 			free_irq(dev->irq, dev);
 
-		wait_event(rpc->wait_release, rpc->prod_idx == rpc->cons_idx);
-
+		flush_work(&rpc->dpc_handler);
 		aer_disable_rootport(rpc);
 		kfree(rpc);
 		set_service_data(dev, NULL);
--- zfcpdump-kernel-4.4.orig/drivers/pci/pcie/aer/aerdrv.h
+++ zfcpdump-kernel-4.4/drivers/pci/pcie/aer/aerdrv.h
@@ -72,7 +72,6 @@ struct aer_rpc {
 					 * recovery on the same
 					 * root port hierarchy
 					 */
-	wait_queue_head_t wait_release;
 };
 
 struct aer_broadcast_data {
--- zfcpdump-kernel-4.4.orig/drivers/pci/pcie/aer/aerdrv_core.c
+++ zfcpdump-kernel-4.4/drivers/pci/pcie/aer/aerdrv_core.c
@@ -811,8 +811,6 @@ void aer_isr(struct work_struct *work)
 	while (get_e_source(rpc, &e_src))
 		aer_isr_one_error(p_device, &e_src);
 	mutex_unlock(&rpc->rpc_mutex);
-
-	wake_up(&rpc->wait_release);
 }
 
 /**
--- zfcpdump-kernel-4.4.orig/drivers/pci/probe.c
+++ zfcpdump-kernel-4.4/drivers/pci/probe.c
@@ -15,6 +15,7 @@
 #include <linux/pci-aspm.h>
 #include <linux/aer.h>
 #include <linux/acpi.h>
+#include <linux/irqdomain.h>
 #include <asm-generic/pci-bridge.h>
 #include "pci.h"
 
@@ -319,6 +320,9 @@ static void pci_read_bases(struct pci_de
 {
 	unsigned int pos, reg;
 
+	if (dev->non_compliant_bars)
+		return;
+
 	for (pos = 0; pos < howmany; pos++) {
 		struct resource *res = &dev->resource[pos];
 		reg = PCI_BASE_ADDRESS_0 + (pos << 2);
@@ -672,6 +676,22 @@ static struct irq_domain *pci_host_bridg
 	 * should be called from here.
 	 */
 	d = pci_host_bridge_of_msi_domain(bus);
+	if (!d)
+		d = pci_host_bridge_acpi_msi_domain(bus);
+
+#ifdef CONFIG_PCI_MSI_IRQ_DOMAIN
+	/*
+	 * If no IRQ domain was found via the OF tree, try looking it up
+	 * directly through the fwnode_handle.
+	 */
+	if (!d) {
+		struct fwnode_handle *fwnode = pci_root_bus_fwnode(bus);
+
+		if (fwnode)
+			d = irq_find_matching_fwnode(fwnode,
+						     DOMAIN_BUS_PCI_MSI);
+	}
+#endif
 
 	return d;
 }
@@ -1174,6 +1194,7 @@ void pci_msi_setup_pci_dev(struct pci_de
 int pci_setup_device(struct pci_dev *dev)
 {
 	u32 class;
+	u16 cmd;
 	u8 hdr_type;
 	int pos = 0;
 	struct pci_bus_region region;
@@ -1219,6 +1240,16 @@ int pci_setup_device(struct pci_dev *dev
 	/* device class may be changed after fixup */
 	class = dev->class >> 8;
 
+	if (dev->non_compliant_bars) {
+		pci_read_config_word(dev, PCI_COMMAND, &cmd);
+		if (cmd & (PCI_COMMAND_IO | PCI_COMMAND_MEMORY)) {
+			dev_info(&dev->dev, "device has non-compliant BARs; disabling IO/MEM decoding\n");
+			cmd &= ~PCI_COMMAND_IO;
+			cmd &= ~PCI_COMMAND_MEMORY;
+			pci_write_config_word(dev, PCI_COMMAND, cmd);
+		}
+	}
+
 	switch (dev->hdr_type) {		    /* header type */
 	case PCI_HEADER_TYPE_NORMAL:		    /* standard header */
 		if (class == PCI_CLASS_BRIDGE_PCI)
--- zfcpdump-kernel-4.4.orig/drivers/pci/proc.c
+++ zfcpdump-kernel-4.4/drivers/pci/proc.c
@@ -116,6 +116,9 @@ static ssize_t proc_bus_pci_write(struct
 	int size = dev->cfg_size;
 	int cnt;
 
+	if (secure_modules())
+		return -EPERM;
+
 	if (pos >= size)
 		return 0;
 	if (nbytes >= size)
@@ -195,6 +198,9 @@ static long proc_bus_pci_ioctl(struct fi
 #endif /* HAVE_PCI_MMAP */
 	int ret = 0;
 
+	if (secure_modules())
+		return -EPERM;
+
 	switch (cmd) {
 	case PCIIOC_CONTROLLER:
 		ret = pci_domain_nr(dev->bus);
@@ -233,7 +239,7 @@ static int proc_bus_pci_mmap(struct file
 	struct pci_filp_private *fpriv = file->private_data;
 	int i, ret;
 
-	if (!capable(CAP_SYS_RAWIO))
+	if (!capable(CAP_SYS_RAWIO) || secure_modules())
 		return -EPERM;
 
 	/* Make sure the caller is mapping a real resource for this device */
--- zfcpdump-kernel-4.4.orig/drivers/pci/quirks.c
+++ zfcpdump-kernel-4.4/drivers/pci/quirks.c
@@ -41,6 +41,21 @@ static void quirk_mmio_always_on(struct
 DECLARE_PCI_FIXUP_CLASS_EARLY(PCI_ANY_ID, PCI_ANY_ID,
 				PCI_CLASS_BRIDGE_HOST, 8, quirk_mmio_always_on);
 
+/* The BAR0 ~ BAR4 of Marvell 9125 device can't be accessed
+*  by IO resource file, and need to skip the files
+*/
+static void quirk_marvell_mask_bar(struct pci_dev *dev)
+{
+	int i;
+
+	for (i = 0; i < 5; i++)
+		if (dev->resource[i].start)
+			dev->resource[i].start =
+				dev->resource[i].end = 0;
+}
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MARVELL_EXT, 0x9125,
+				quirk_marvell_mask_bar);
+
 /* The Mellanox Tavor device gives false positive parity errors
  * Mark this device with a broken_parity_status, to allow
  * PCI scanning code to "skip" this now blacklisted device.
@@ -287,6 +302,18 @@ static void quirk_citrine(struct pci_dev
 }
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_IBM,	PCI_DEVICE_ID_IBM_CITRINE,	quirk_citrine);
 
+/*
+ * This chip can cause bus lockups if config addresses above 0x600
+ * are read or written.
+ */
+static void quirk_nfp6000(struct pci_dev *dev)
+{
+	dev->cfg_size = 0x600;
+}
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NETRONOME,	PCI_DEVICE_ID_NETRONOME_NFP4000,	quirk_nfp6000);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NETRONOME,	PCI_DEVICE_ID_NETRONOME_NFP6000,	quirk_nfp6000);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NETRONOME,	PCI_DEVICE_ID_NETRONOME_NFP6000_VF,	quirk_nfp6000);
+
 /*  On IBM Crocodile ipr SAS adapters, expand BAR to system page size */
 static void quirk_extend_bar_to_page(struct pci_dev *dev)
 {
@@ -2735,6 +2762,26 @@ static void quirk_hotplug_bridge(struct
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_HINT, 0x0020, quirk_hotplug_bridge);
 
 /*
+ * Apple: Avoid programming the memory/io aperture of 00:1c.0
+ *
+ * BIOS does not declare any resource for 00:1c.0, but with
+ * hotplug flag set, thus the OS allocates:
+ * [mem 0x7fa00000 - 0x7fbfffff]
+ * [mem 0x7fc00000-0x7fdfffff 64bit pref]
+ * which is conflict with an unreported device, which
+ * causes unpredictable result such as accessing io port.
+ * So clear the hotplug flag to work around it.
+ */
+static void quirk_apple_mbp_poweroff(struct pci_dev *dev)
+{
+	if (dmi_match(DMI_PRODUCT_NAME, "MacBookPro11,4") ||
+	    dmi_match(DMI_PRODUCT_NAME, "MacBookPro11,5"))
+		dev->is_hotplug_bridge = 0;
+}
+
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x8c10, quirk_apple_mbp_poweroff);
+
+/*
  * This is a quirk for the Ricoh MMC controller found as a part of
  * some mulifunction chips.
 
@@ -3115,13 +3162,15 @@ static void quirk_no_bus_reset(struct pc
 }
 
 /*
- * Atheros AR93xx chips do not behave after a bus reset.  The device will
- * throw a Link Down error on AER-capable systems and regardless of AER,
- * config space of the device is never accessible again and typically
- * causes the system to hang or reset when access is attempted.
+ * Some Atheros AR9xxx and QCA988x chips do not behave after a bus reset.
+ * The device will throw a Link Down error on AER-capable systems and
+ * regardless of AER, config space of the device is never accessible again
+ * and typically causes the system to hang or reset when access is attempted.
  * http://www.spinics.net/lists/linux-pci/msg34797.html
  */
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATHEROS, 0x0030, quirk_no_bus_reset);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATHEROS, 0x0032, quirk_no_bus_reset);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATHEROS, 0x003c, quirk_no_bus_reset);
 
 static void quirk_no_pm_reset(struct pci_dev *dev)
 {
--- zfcpdump-kernel-4.4.orig/drivers/pci/syscall.c
+++ zfcpdump-kernel-4.4/drivers/pci/syscall.c
@@ -10,6 +10,7 @@
 #include <linux/errno.h>
 #include <linux/pci.h>
 #include <linux/syscalls.h>
+#include <linux/module.h>
 #include <asm/uaccess.h>
 #include "pci.h"
 
@@ -92,7 +93,7 @@ SYSCALL_DEFINE5(pciconfig_write, unsigne
 	u32 dword;
 	int err = 0;
 
-	if (!capable(CAP_SYS_ADMIN))
+	if (!capable(CAP_SYS_ADMIN) || secure_modules())
 		return -EPERM;
 
 	dev = pci_get_bus_and_slot(bus, dfn);
--- zfcpdump-kernel-4.4.orig/drivers/pci/xen-pcifront.c
+++ zfcpdump-kernel-4.4/drivers/pci/xen-pcifront.c
@@ -53,7 +53,7 @@ struct pcifront_device {
 };
 
 struct pcifront_sd {
-	int domain;
+	struct pci_sysdata sd;
 	struct pcifront_device *pdev;
 };
 
@@ -67,7 +67,9 @@ static inline void pcifront_init_sd(stru
 				    unsigned int domain, unsigned int bus,
 				    struct pcifront_device *pdev)
 {
-	sd->domain = domain;
+	/* Because we do not expose that information via XenBus. */
+	sd->sd.node = first_online_node;
+	sd->sd.domain = domain;
 	sd->pdev = pdev;
 }
 
@@ -468,8 +470,8 @@ static int pcifront_scan_root(struct pci
 	dev_info(&pdev->xdev->dev, "Creating PCI Frontend Bus %04x:%02x\n",
 		 domain, bus);
 
-	bus_entry = kmalloc(sizeof(*bus_entry), GFP_KERNEL);
-	sd = kmalloc(sizeof(*sd), GFP_KERNEL);
+	bus_entry = kzalloc(sizeof(*bus_entry), GFP_KERNEL);
+	sd = kzalloc(sizeof(*sd), GFP_KERNEL);
 	if (!bus_entry || !sd) {
 		err = -ENOMEM;
 		goto err_out;
--- zfcpdump-kernel-4.4.orig/drivers/pcmcia/db1xxx_ss.c
+++ zfcpdump-kernel-4.4/drivers/pcmcia/db1xxx_ss.c
@@ -56,6 +56,7 @@ struct db1x_pcmcia_sock {
 	int	stschg_irq;	/* card-status-change irq */
 	int	card_irq;	/* card irq */
 	int	eject_irq;	/* db1200/pb1200 have these */
+	int	insert_gpio;	/* db1000 carddetect gpio */
 
 #define BOARD_TYPE_DEFAULT	0	/* most boards */
 #define BOARD_TYPE_DB1200	1	/* IRQs aren't gpios */
@@ -83,7 +84,7 @@ static int db1200_card_inserted(struct d
 /* carddetect gpio: low-active */
 static int db1000_card_inserted(struct db1x_pcmcia_sock *sock)
 {
-	return !gpio_get_value(irq_to_gpio(sock->insert_irq));
+	return !gpio_get_value(sock->insert_gpio);
 }
 
 static int db1x_card_inserted(struct db1x_pcmcia_sock *sock)
@@ -457,9 +458,15 @@ static int db1x_pcmcia_socket_probe(stru
 	r = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "card");
 	sock->card_irq = r ? r->start : 0;
 
-	/* insert: irq which triggers on card insertion/ejection */
+	/* insert: irq which triggers on card insertion/ejection
+	 * BIG FAT NOTE: on DB1000/1100/1500/1550 we pass a GPIO here!
+	 */
 	r = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "insert");
 	sock->insert_irq = r ? r->start : -1;
+	if (sock->board_type == BOARD_TYPE_DEFAULT) {
+		sock->insert_gpio = r ? r->start : -1;
+		sock->insert_irq = r ? gpio_to_irq(r->start) : -1;
+	}
 
 	/* stschg: irq which trigger on card status change (optional) */
 	r = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "stschg");
--- zfcpdump-kernel-4.4.orig/drivers/perf/arm_pmu.c
+++ zfcpdump-kernel-4.4/drivers/perf/arm_pmu.c
@@ -551,14 +551,6 @@ static void armpmu_init(struct arm_pmu *
 	};
 }
 
-int armpmu_register(struct arm_pmu *armpmu, int type)
-{
-	armpmu_init(armpmu);
-	pr_info("enabled with %s PMU driver, %d counters available\n",
-			armpmu->name, armpmu->num_events);
-	return perf_pmu_register(&armpmu->pmu, armpmu->name, type);
-}
-
 /* Set at runtime when we know what CPU type we are. */
 static struct arm_pmu *__oprofile_cpu_pmu;
 
@@ -815,6 +807,7 @@ static int of_pmu_irq_cfg(struct arm_pmu
 			if (i > 0 && spi != using_spi) {
 				pr_err("PPI/SPI IRQ type mismatch for %s!\n",
 					dn->name);
+				of_node_put(dn);
 				kfree(irqs);
 				return -EINVAL;
 			}
@@ -887,6 +880,8 @@ int arm_pmu_device_probe(struct platform
 		return -ENOMEM;
 	}
 
+	armpmu_init(pmu);
+
 	if (!__oprofile_cpu_pmu)
 		__oprofile_cpu_pmu = pmu;
 
@@ -912,10 +907,13 @@ int arm_pmu_device_probe(struct platform
 	if (ret)
 		goto out_free;
 
-	ret = armpmu_register(pmu, -1);
+	ret = perf_pmu_register(&pmu->pmu, pmu->name, -1);
 	if (ret)
 		goto out_destroy;
 
+	pr_info("enabled with %s PMU driver, %d counters available\n",
+			pmu->name, pmu->num_events);
+
 	return 0;
 
 out_destroy:
--- zfcpdump-kernel-4.4.orig/drivers/phy/phy-core.c
+++ zfcpdump-kernel-4.4/drivers/phy/phy-core.c
@@ -275,20 +275,21 @@ EXPORT_SYMBOL_GPL(phy_exit);
 
 int phy_power_on(struct phy *phy)
 {
-	int ret;
+	int ret = 0;
 
 	if (!phy)
-		return 0;
+		goto out;
 
 	if (phy->pwr) {
 		ret = regulator_enable(phy->pwr);
 		if (ret)
-			return ret;
+			goto out;
 	}
 
 	ret = phy_pm_runtime_get_sync(phy);
 	if (ret < 0 && ret != -ENOTSUPP)
-		return ret;
+		goto err_pm_sync;
+
 	ret = 0; /* Override possible ret == -ENOTSUPP */
 
 	mutex_lock(&phy->mutex);
@@ -296,19 +297,20 @@ int phy_power_on(struct phy *phy)
 		ret = phy->ops->power_on(phy);
 		if (ret < 0) {
 			dev_err(&phy->dev, "phy poweron failed --> %d\n", ret);
-			goto out;
+			goto err_pwr_on;
 		}
 	}
 	++phy->power_count;
 	mutex_unlock(&phy->mutex);
 	return 0;
 
-out:
+err_pwr_on:
 	mutex_unlock(&phy->mutex);
 	phy_pm_runtime_put_sync(phy);
+err_pm_sync:
 	if (phy->pwr)
 		regulator_disable(phy->pwr);
-
+out:
 	return ret;
 }
 EXPORT_SYMBOL_GPL(phy_power_on);
--- zfcpdump-kernel-4.4.orig/drivers/phy/phy-twl4030-usb.c
+++ zfcpdump-kernel-4.4/drivers/phy/phy-twl4030-usb.c
@@ -715,6 +715,7 @@ static int twl4030_usb_probe(struct plat
 	pm_runtime_use_autosuspend(&pdev->dev);
 	pm_runtime_set_autosuspend_delay(&pdev->dev, 2000);
 	pm_runtime_enable(&pdev->dev);
+	pm_runtime_get_sync(&pdev->dev);
 
 	/* Our job is to use irqs and status from the power module
 	 * to keep the transceiver disabled when nothing's connected.
@@ -750,6 +751,7 @@ static int twl4030_usb_remove(struct pla
 	struct twl4030_usb *twl = platform_get_drvdata(pdev);
 	int val;
 
+	usb_remove_phy(&twl->phy);
 	pm_runtime_get_sync(twl->dev);
 	cancel_delayed_work(&twl->id_workaround_work);
 	device_remove_file(twl->dev, &dev_attr_vbus);
@@ -757,6 +759,13 @@ static int twl4030_usb_remove(struct pla
 	/* set transceiver mode to power on defaults */
 	twl4030_usb_set_mode(twl, -1);
 
+	/* idle ulpi before powering off */
+	if (cable_present(twl->linkstat))
+		pm_runtime_put_noidle(twl->dev);
+	pm_runtime_mark_last_busy(twl->dev);
+	pm_runtime_put_sync_suspend(twl->dev);
+	pm_runtime_disable(twl->dev);
+
 	/* autogate 60MHz ULPI clock,
 	 * clear dpll clock request for i2c access,
 	 * disable 32KHz
@@ -771,11 +780,6 @@ static int twl4030_usb_remove(struct pla
 	/* disable complete OTG block */
 	twl4030_usb_clear_bits(twl, POWER_CTRL, POWER_CTRL_OTG_ENAB);
 
-	if (cable_present(twl->linkstat))
-		pm_runtime_put_noidle(twl->dev);
-	pm_runtime_mark_last_busy(twl->dev);
-	pm_runtime_put(twl->dev);
-
 	return 0;
 }
 
--- zfcpdump-kernel-4.4.orig/drivers/pinctrl/bcm/pinctrl-bcm2835.c
+++ zfcpdump-kernel-4.4/drivers/pinctrl/bcm/pinctrl-bcm2835.c
@@ -779,7 +779,7 @@ static int bcm2835_pctl_dt_node_to_map(s
 		}
 		if (num_pulls) {
 			err = of_property_read_u32_index(np, "brcm,pull",
-					(num_funcs > 1) ? i : 0, &pull);
+					(num_pulls > 1) ? i : 0, &pull);
 			if (err)
 				goto out;
 			err = bcm2835_pctl_dt_node_to_map_pull(pc, np, pin,
--- zfcpdump-kernel-4.4.orig/drivers/pinctrl/freescale/pinctrl-imx.c
+++ zfcpdump-kernel-4.4/drivers/pinctrl/freescale/pinctrl-imx.c
@@ -207,9 +207,9 @@ static int imx_pmx_set(struct pinctrl_de
 		pin_reg = &info->pin_regs[pin_id];
 
 		if (pin_reg->mux_reg == -1) {
-			dev_err(ipctl->dev, "Pin(%s) does not support mux function\n",
+			dev_dbg(ipctl->dev, "Pin(%s) does not support mux function\n",
 				info->pins[pin_id].name);
-			return -EINVAL;
+			continue;
 		}
 
 		if (info->flags & SHARE_MUX_CONF_REG) {
@@ -726,19 +726,18 @@ int imx_pinctrl_probe(struct platform_de
 
 	if (of_property_read_bool(dev_np, "fsl,input-sel")) {
 		np = of_parse_phandle(dev_np, "fsl,input-sel", 0);
-		if (np) {
-			ipctl->input_sel_base = of_iomap(np, 0);
-			if (IS_ERR(ipctl->input_sel_base)) {
-				of_node_put(np);
-				dev_err(&pdev->dev,
-					"iomuxc input select base address not found\n");
-				return PTR_ERR(ipctl->input_sel_base);
-			}
-		} else {
+		if (!np) {
 			dev_err(&pdev->dev, "iomuxc fsl,input-sel property not found\n");
 			return -EINVAL;
 		}
+
+		ipctl->input_sel_base = of_iomap(np, 0);
 		of_node_put(np);
+		if (!ipctl->input_sel_base) {
+			dev_err(&pdev->dev,
+				"iomuxc input select base address not found\n");
+			return -ENOMEM;
+		}
 	}
 
 	imx_pinctrl_desc.name = dev_name(&pdev->dev);
--- zfcpdump-kernel-4.4.orig/drivers/pinctrl/intel/pinctrl-cherryview.c
+++ zfcpdump-kernel-4.4/drivers/pinctrl/intel/pinctrl-cherryview.c
@@ -160,7 +160,6 @@ struct chv_pin_context {
  * @pctldev: Pointer to the pin controller device
  * @chip: GPIO chip in this pin controller
  * @regs: MMIO registers
- * @lock: Lock to serialize register accesses
  * @intr_lines: Stores mapping between 16 HW interrupt wires and GPIO
  *		offset (in GPIO number space)
  * @community: Community this pinctrl instance represents
@@ -174,7 +173,6 @@ struct chv_pinctrl {
 	struct pinctrl_dev *pctldev;
 	struct gpio_chip chip;
 	void __iomem *regs;
-	raw_spinlock_t lock;
 	unsigned intr_lines[16];
 	const struct chv_community *community;
 	u32 saved_intmask;
@@ -659,6 +657,17 @@ static const struct chv_community *chv_c
 	&southeast_community,
 };
 
+/*
+ * Lock to serialize register accesses
+ *
+ * Due to a silicon issue, a shared lock must be used to prevent
+ * concurrent accesses across the 4 GPIO controllers.
+ *
+ * See Intel Atom Z8000 Processor Series Specification Update (Rev. 005),
+ * errata #CHT34, for further information.
+ */
+static DEFINE_RAW_SPINLOCK(chv_lock);
+
 static void __iomem *chv_padreg(struct chv_pinctrl *pctrl, unsigned offset,
 				unsigned reg)
 {
@@ -720,13 +729,13 @@ static void chv_pin_dbg_show(struct pinc
 	u32 ctrl0, ctrl1;
 	bool locked;
 
-	raw_spin_lock_irqsave(&pctrl->lock, flags);
+	raw_spin_lock_irqsave(&chv_lock, flags);
 
 	ctrl0 = readl(chv_padreg(pctrl, offset, CHV_PADCTRL0));
 	ctrl1 = readl(chv_padreg(pctrl, offset, CHV_PADCTRL1));
 	locked = chv_pad_locked(pctrl, offset);
 
-	raw_spin_unlock_irqrestore(&pctrl->lock, flags);
+	raw_spin_unlock_irqrestore(&chv_lock, flags);
 
 	if (ctrl0 & CHV_PADCTRL0_GPIOEN) {
 		seq_puts(s, "GPIO ");
@@ -789,14 +798,14 @@ static int chv_pinmux_set_mux(struct pin
 
 	grp = &pctrl->community->groups[group];
 
-	raw_spin_lock_irqsave(&pctrl->lock, flags);
+	raw_spin_lock_irqsave(&chv_lock, flags);
 
 	/* Check first that the pad is not locked */
 	for (i = 0; i < grp->npins; i++) {
 		if (chv_pad_locked(pctrl, grp->pins[i])) {
 			dev_warn(pctrl->dev, "unable to set mode for locked pin %u\n",
 				 grp->pins[i]);
-			raw_spin_unlock_irqrestore(&pctrl->lock, flags);
+			raw_spin_unlock_irqrestore(&chv_lock, flags);
 			return -EBUSY;
 		}
 	}
@@ -839,7 +848,7 @@ static int chv_pinmux_set_mux(struct pin
 			pin, altfunc->mode, altfunc->invert_oe ? "" : "not ");
 	}
 
-	raw_spin_unlock_irqrestore(&pctrl->lock, flags);
+	raw_spin_unlock_irqrestore(&chv_lock, flags);
 
 	return 0;
 }
@@ -853,13 +862,13 @@ static int chv_gpio_request_enable(struc
 	void __iomem *reg;
 	u32 value;
 
-	raw_spin_lock_irqsave(&pctrl->lock, flags);
+	raw_spin_lock_irqsave(&chv_lock, flags);
 
 	if (chv_pad_locked(pctrl, offset)) {
 		value = readl(chv_padreg(pctrl, offset, CHV_PADCTRL0));
 		if (!(value & CHV_PADCTRL0_GPIOEN)) {
 			/* Locked so cannot enable */
-			raw_spin_unlock_irqrestore(&pctrl->lock, flags);
+			raw_spin_unlock_irqrestore(&chv_lock, flags);
 			return -EBUSY;
 		}
 	} else {
@@ -899,7 +908,7 @@ static int chv_gpio_request_enable(struc
 		chv_writel(value, reg);
 	}
 
-	raw_spin_unlock_irqrestore(&pctrl->lock, flags);
+	raw_spin_unlock_irqrestore(&chv_lock, flags);
 
 	return 0;
 }
@@ -913,13 +922,13 @@ static void chv_gpio_disable_free(struct
 	void __iomem *reg;
 	u32 value;
 
-	raw_spin_lock_irqsave(&pctrl->lock, flags);
+	raw_spin_lock_irqsave(&chv_lock, flags);
 
 	reg = chv_padreg(pctrl, offset, CHV_PADCTRL0);
 	value = readl(reg) & ~CHV_PADCTRL0_GPIOEN;
 	chv_writel(value, reg);
 
-	raw_spin_unlock_irqrestore(&pctrl->lock, flags);
+	raw_spin_unlock_irqrestore(&chv_lock, flags);
 }
 
 static int chv_gpio_set_direction(struct pinctrl_dev *pctldev,
@@ -931,7 +940,7 @@ static int chv_gpio_set_direction(struct
 	unsigned long flags;
 	u32 ctrl0;
 
-	raw_spin_lock_irqsave(&pctrl->lock, flags);
+	raw_spin_lock_irqsave(&chv_lock, flags);
 
 	ctrl0 = readl(reg) & ~CHV_PADCTRL0_GPIOCFG_MASK;
 	if (input)
@@ -940,7 +949,7 @@ static int chv_gpio_set_direction(struct
 		ctrl0 |= CHV_PADCTRL0_GPIOCFG_GPO << CHV_PADCTRL0_GPIOCFG_SHIFT;
 	chv_writel(ctrl0, reg);
 
-	raw_spin_unlock_irqrestore(&pctrl->lock, flags);
+	raw_spin_unlock_irqrestore(&chv_lock, flags);
 
 	return 0;
 }
@@ -965,10 +974,10 @@ static int chv_config_get(struct pinctrl
 	u16 arg = 0;
 	u32 term;
 
-	raw_spin_lock_irqsave(&pctrl->lock, flags);
+	raw_spin_lock_irqsave(&chv_lock, flags);
 	ctrl0 = readl(chv_padreg(pctrl, pin, CHV_PADCTRL0));
 	ctrl1 = readl(chv_padreg(pctrl, pin, CHV_PADCTRL1));
-	raw_spin_unlock_irqrestore(&pctrl->lock, flags);
+	raw_spin_unlock_irqrestore(&chv_lock, flags);
 
 	term = (ctrl0 & CHV_PADCTRL0_TERM_MASK) >> CHV_PADCTRL0_TERM_SHIFT;
 
@@ -1042,7 +1051,7 @@ static int chv_config_set_pull(struct ch
 	unsigned long flags;
 	u32 ctrl0, pull;
 
-	raw_spin_lock_irqsave(&pctrl->lock, flags);
+	raw_spin_lock_irqsave(&chv_lock, flags);
 	ctrl0 = readl(reg);
 
 	switch (param) {
@@ -1065,7 +1074,7 @@ static int chv_config_set_pull(struct ch
 			pull = CHV_PADCTRL0_TERM_20K << CHV_PADCTRL0_TERM_SHIFT;
 			break;
 		default:
-			raw_spin_unlock_irqrestore(&pctrl->lock, flags);
+			raw_spin_unlock_irqrestore(&chv_lock, flags);
 			return -EINVAL;
 		}
 
@@ -1083,7 +1092,7 @@ static int chv_config_set_pull(struct ch
 			pull = CHV_PADCTRL0_TERM_20K << CHV_PADCTRL0_TERM_SHIFT;
 			break;
 		default:
-			raw_spin_unlock_irqrestore(&pctrl->lock, flags);
+			raw_spin_unlock_irqrestore(&chv_lock, flags);
 			return -EINVAL;
 		}
 
@@ -1091,12 +1100,12 @@ static int chv_config_set_pull(struct ch
 		break;
 
 	default:
-		raw_spin_unlock_irqrestore(&pctrl->lock, flags);
+		raw_spin_unlock_irqrestore(&chv_lock, flags);
 		return -EINVAL;
 	}
 
 	chv_writel(ctrl0, reg);
-	raw_spin_unlock_irqrestore(&pctrl->lock, flags);
+	raw_spin_unlock_irqrestore(&chv_lock, flags);
 
 	return 0;
 }
@@ -1162,9 +1171,9 @@ static int chv_gpio_get(struct gpio_chip
 	unsigned long flags;
 	u32 ctrl0, cfg;
 
-	raw_spin_lock_irqsave(&pctrl->lock, flags);
+	raw_spin_lock_irqsave(&chv_lock, flags);
 	ctrl0 = readl(chv_padreg(pctrl, pin, CHV_PADCTRL0));
-	raw_spin_unlock_irqrestore(&pctrl->lock, flags);
+	raw_spin_unlock_irqrestore(&chv_lock, flags);
 
 	cfg = ctrl0 & CHV_PADCTRL0_GPIOCFG_MASK;
 	cfg >>= CHV_PADCTRL0_GPIOCFG_SHIFT;
@@ -1182,7 +1191,7 @@ static void chv_gpio_set(struct gpio_chi
 	void __iomem *reg;
 	u32 ctrl0;
 
-	raw_spin_lock_irqsave(&pctrl->lock, flags);
+	raw_spin_lock_irqsave(&chv_lock, flags);
 
 	reg = chv_padreg(pctrl, pin, CHV_PADCTRL0);
 	ctrl0 = readl(reg);
@@ -1194,7 +1203,7 @@ static void chv_gpio_set(struct gpio_chi
 
 	chv_writel(ctrl0, reg);
 
-	raw_spin_unlock_irqrestore(&pctrl->lock, flags);
+	raw_spin_unlock_irqrestore(&chv_lock, flags);
 }
 
 static int chv_gpio_get_direction(struct gpio_chip *chip, unsigned offset)
@@ -1204,9 +1213,9 @@ static int chv_gpio_get_direction(struct
 	u32 ctrl0, direction;
 	unsigned long flags;
 
-	raw_spin_lock_irqsave(&pctrl->lock, flags);
+	raw_spin_lock_irqsave(&chv_lock, flags);
 	ctrl0 = readl(chv_padreg(pctrl, pin, CHV_PADCTRL0));
-	raw_spin_unlock_irqrestore(&pctrl->lock, flags);
+	raw_spin_unlock_irqrestore(&chv_lock, flags);
 
 	direction = ctrl0 & CHV_PADCTRL0_GPIOCFG_MASK;
 	direction >>= CHV_PADCTRL0_GPIOCFG_SHIFT;
@@ -1244,14 +1253,14 @@ static void chv_gpio_irq_ack(struct irq_
 	int pin = chv_gpio_offset_to_pin(pctrl, irqd_to_hwirq(d));
 	u32 intr_line;
 
-	raw_spin_lock(&pctrl->lock);
+	raw_spin_lock(&chv_lock);
 
 	intr_line = readl(chv_padreg(pctrl, pin, CHV_PADCTRL0));
 	intr_line &= CHV_PADCTRL0_INTSEL_MASK;
 	intr_line >>= CHV_PADCTRL0_INTSEL_SHIFT;
 	chv_writel(BIT(intr_line), pctrl->regs + CHV_INTSTAT);
 
-	raw_spin_unlock(&pctrl->lock);
+	raw_spin_unlock(&chv_lock);
 }
 
 static void chv_gpio_irq_mask_unmask(struct irq_data *d, bool mask)
@@ -1262,7 +1271,7 @@ static void chv_gpio_irq_mask_unmask(str
 	u32 value, intr_line;
 	unsigned long flags;
 
-	raw_spin_lock_irqsave(&pctrl->lock, flags);
+	raw_spin_lock_irqsave(&chv_lock, flags);
 
 	intr_line = readl(chv_padreg(pctrl, pin, CHV_PADCTRL0));
 	intr_line &= CHV_PADCTRL0_INTSEL_MASK;
@@ -1275,7 +1284,7 @@ static void chv_gpio_irq_mask_unmask(str
 		value |= BIT(intr_line);
 	chv_writel(value, pctrl->regs + CHV_INTMASK);
 
-	raw_spin_unlock_irqrestore(&pctrl->lock, flags);
+	raw_spin_unlock_irqrestore(&chv_lock, flags);
 }
 
 static void chv_gpio_irq_mask(struct irq_data *d)
@@ -1309,7 +1318,7 @@ static unsigned chv_gpio_irq_startup(str
 		unsigned long flags;
 		u32 intsel, value;
 
-		raw_spin_lock_irqsave(&pctrl->lock, flags);
+		raw_spin_lock_irqsave(&chv_lock, flags);
 		intsel = readl(chv_padreg(pctrl, pin, CHV_PADCTRL0));
 		intsel &= CHV_PADCTRL0_INTSEL_MASK;
 		intsel >>= CHV_PADCTRL0_INTSEL_SHIFT;
@@ -1324,7 +1333,7 @@ static unsigned chv_gpio_irq_startup(str
 			irq_set_handler_locked(d, handler);
 			pctrl->intr_lines[intsel] = offset;
 		}
-		raw_spin_unlock_irqrestore(&pctrl->lock, flags);
+		raw_spin_unlock_irqrestore(&chv_lock, flags);
 	}
 
 	chv_gpio_irq_unmask(d);
@@ -1340,7 +1349,7 @@ static int chv_gpio_irq_type(struct irq_
 	unsigned long flags;
 	u32 value;
 
-	raw_spin_lock_irqsave(&pctrl->lock, flags);
+	raw_spin_lock_irqsave(&chv_lock, flags);
 
 	/*
 	 * Pins which can be used as shared interrupt are configured in
@@ -1389,7 +1398,7 @@ static int chv_gpio_irq_type(struct irq_
 	else if (type & IRQ_TYPE_LEVEL_MASK)
 		irq_set_handler_locked(d, handle_level_irq);
 
-	raw_spin_unlock_irqrestore(&pctrl->lock, flags);
+	raw_spin_unlock_irqrestore(&chv_lock, flags);
 
 	return 0;
 }
@@ -1501,7 +1510,6 @@ static int chv_pinctrl_probe(struct plat
 	if (i == ARRAY_SIZE(chv_communities))
 		return -ENODEV;
 
-	raw_spin_lock_init(&pctrl->lock);
 	pctrl->dev = &pdev->dev;
 
 #ifdef CONFIG_PM_SLEEP
--- zfcpdump-kernel-4.4.orig/drivers/pinctrl/mediatek/pinctrl-mtk-common.c
+++ zfcpdump-kernel-4.4/drivers/pinctrl/mediatek/pinctrl-mtk-common.c
@@ -939,7 +939,8 @@ static int mtk_gpio_set_debounce(struct
 	struct mtk_pinctrl *pctl = dev_get_drvdata(chip->dev);
 	int eint_num, virq, eint_offset;
 	unsigned int set_offset, bit, clr_bit, clr_offset, rst, i, unmask, dbnc;
-	static const unsigned int dbnc_arr[] = {0 , 1, 16, 32, 64, 128, 256};
+	static const unsigned int debounce_time[] = {500, 1000, 16000, 32000, 64000,
+						128000, 256000};
 	const struct mtk_desc_pin *pin;
 	struct irq_data *d;
 
@@ -957,9 +958,9 @@ static int mtk_gpio_set_debounce(struct
 	if (!mtk_eint_can_en_debounce(pctl, eint_num))
 		return -ENOSYS;
 
-	dbnc = ARRAY_SIZE(dbnc_arr);
-	for (i = 0; i < ARRAY_SIZE(dbnc_arr); i++) {
-		if (debounce <= dbnc_arr[i]) {
+	dbnc = ARRAY_SIZE(debounce_time);
+	for (i = 0; i < ARRAY_SIZE(debounce_time); i++) {
+		if (debounce <= debounce_time[i]) {
 			dbnc = i;
 			break;
 		}
@@ -1190,9 +1191,10 @@ static void mtk_eint_irq_handler(struct
 	const struct mtk_desc_pin *pin;
 
 	chained_irq_enter(chip, desc);
-	for (eint_num = 0; eint_num < pctl->devdata->ap_num; eint_num += 32) {
+	for (eint_num = 0;
+	     eint_num < pctl->devdata->ap_num;
+	     eint_num += 32, reg += 4) {
 		status = readl(reg);
-		reg += 4;
 		while (status) {
 			offset = __ffs(status);
 			index = eint_num + offset;
--- zfcpdump-kernel-4.4.orig/drivers/pinctrl/nomadik/pinctrl-nomadik.c
+++ zfcpdump-kernel-4.4/drivers/pinctrl/nomadik/pinctrl-nomadik.c
@@ -995,7 +995,7 @@ static void nmk_gpio_dbg_show_one(struct
 		int val;
 
 		if (pull)
-			pullidx = data_out ? 1 : 2;
+			pullidx = data_out ? 2 : 1;
 
 		seq_printf(s, " gpio-%-3d (%-20.20s) in  %s %s",
 			   gpio,
--- zfcpdump-kernel-4.4.orig/drivers/pinctrl/pinctrl-amd.c
+++ zfcpdump-kernel-4.4/drivers/pinctrl/pinctrl-amd.c
@@ -48,17 +48,6 @@ static int amd_gpio_direction_input(stru
 
 	spin_lock_irqsave(&gpio_dev->lock, flags);
 	pin_reg = readl(gpio_dev->base + offset * 4);
-	/*
-	 * Suppose BIOS or Bootloader sets specific debounce for the
-	 * GPIO. if not, set debounce to be  2.75ms and remove glitch.
-	*/
-	if ((pin_reg & DB_TMR_OUT_MASK) == 0) {
-		pin_reg |= 0xf;
-		pin_reg |= BIT(DB_TMR_OUT_UNIT_OFF);
-		pin_reg |= DB_TYPE_REMOVE_GLITCH << DB_CNTRL_OFF;
-		pin_reg &= ~BIT(DB_TMR_LARGE_OFF);
-	}
-
 	pin_reg &= ~BIT(OUTPUT_ENABLE_OFF);
 	writel(pin_reg, gpio_dev->base + offset * 4);
 	spin_unlock_irqrestore(&gpio_dev->lock, flags);
@@ -331,15 +320,6 @@ static void amd_gpio_irq_enable(struct i
 
 	spin_lock_irqsave(&gpio_dev->lock, flags);
 	pin_reg = readl(gpio_dev->base + (d->hwirq)*4);
-	/*
-		Suppose BIOS or Bootloader sets specific debounce for the
-		GPIO. if not, set debounce to be  2.75ms.
-	*/
-	if ((pin_reg & DB_TMR_OUT_MASK) == 0) {
-		pin_reg |= 0xf;
-		pin_reg |= BIT(DB_TMR_OUT_UNIT_OFF);
-		pin_reg &= ~BIT(DB_TMR_LARGE_OFF);
-	}
 	pin_reg |= BIT(INTERRUPT_ENABLE_OFF);
 	pin_reg |= BIT(INTERRUPT_MASK_OFF);
 	writel(pin_reg, gpio_dev->base + (d->hwirq)*4);
--- zfcpdump-kernel-4.4.orig/drivers/pinctrl/pinctrl-at91-pio4.c
+++ zfcpdump-kernel-4.4/drivers/pinctrl/pinctrl-at91-pio4.c
@@ -717,9 +717,11 @@ static int atmel_conf_pin_config_group_s
 			break;
 		case PIN_CONFIG_BIAS_PULL_UP:
 			conf |= ATMEL_PIO_PUEN_MASK;
+			conf &= (~ATMEL_PIO_PDEN_MASK);
 			break;
 		case PIN_CONFIG_BIAS_PULL_DOWN:
 			conf |= ATMEL_PIO_PDEN_MASK;
+			conf &= (~ATMEL_PIO_PUEN_MASK);
 			break;
 		case PIN_CONFIG_DRIVE_OPEN_DRAIN:
 			if (arg == 0)
@@ -1000,7 +1002,7 @@ static int atmel_pinctrl_probe(struct pl
 		atmel_pioctrl->irqs[i] = res->start;
 		irq_set_chained_handler(res->start, atmel_gpio_irq_handler);
 		irq_set_handler_data(res->start, atmel_pioctrl);
-		dev_dbg(dev, "bank %i: hwirq=%u\n", i, res->start);
+		dev_dbg(dev, "bank %i: irq=%pr\n", i, res);
 	}
 
 	atmel_pioctrl->irq_domain = irq_domain_add_linear(dev->of_node,
--- zfcpdump-kernel-4.4.orig/drivers/pinctrl/pinctrl-pistachio.c
+++ zfcpdump-kernel-4.4/drivers/pinctrl/pinctrl-pistachio.c
@@ -469,27 +469,27 @@ static const char * const pistachio_mips
 	"mfio83",
 };
 
-static const char * const pistachio_sys_pll_lock_groups[] = {
+static const char * const pistachio_audio_pll_lock_groups[] = {
 	"mfio84",
 };
 
-static const char * const pistachio_wifi_pll_lock_groups[] = {
+static const char * const pistachio_rpu_v_pll_lock_groups[] = {
 	"mfio85",
 };
 
-static const char * const pistachio_bt_pll_lock_groups[] = {
+static const char * const pistachio_rpu_l_pll_lock_groups[] = {
 	"mfio86",
 };
 
-static const char * const pistachio_rpu_v_pll_lock_groups[] = {
+static const char * const pistachio_sys_pll_lock_groups[] = {
 	"mfio87",
 };
 
-static const char * const pistachio_rpu_l_pll_lock_groups[] = {
+static const char * const pistachio_wifi_pll_lock_groups[] = {
 	"mfio88",
 };
 
-static const char * const pistachio_audio_pll_lock_groups[] = {
+static const char * const pistachio_bt_pll_lock_groups[] = {
 	"mfio89",
 };
 
@@ -559,12 +559,12 @@ enum pistachio_mux_option {
 	PISTACHIO_FUNCTION_DREQ4,
 	PISTACHIO_FUNCTION_DREQ5,
 	PISTACHIO_FUNCTION_MIPS_PLL_LOCK,
+	PISTACHIO_FUNCTION_AUDIO_PLL_LOCK,
+	PISTACHIO_FUNCTION_RPU_V_PLL_LOCK,
+	PISTACHIO_FUNCTION_RPU_L_PLL_LOCK,
 	PISTACHIO_FUNCTION_SYS_PLL_LOCK,
 	PISTACHIO_FUNCTION_WIFI_PLL_LOCK,
 	PISTACHIO_FUNCTION_BT_PLL_LOCK,
-	PISTACHIO_FUNCTION_RPU_V_PLL_LOCK,
-	PISTACHIO_FUNCTION_RPU_L_PLL_LOCK,
-	PISTACHIO_FUNCTION_AUDIO_PLL_LOCK,
 	PISTACHIO_FUNCTION_DEBUG_RAW_CCA_IND,
 	PISTACHIO_FUNCTION_DEBUG_ED_SEC20_CCA_IND,
 	PISTACHIO_FUNCTION_DEBUG_ED_SEC40_CCA_IND,
@@ -620,12 +620,12 @@ static const struct pistachio_function p
 	FUNCTION(dreq4),
 	FUNCTION(dreq5),
 	FUNCTION(mips_pll_lock),
+	FUNCTION(audio_pll_lock),
+	FUNCTION(rpu_v_pll_lock),
+	FUNCTION(rpu_l_pll_lock),
 	FUNCTION(sys_pll_lock),
 	FUNCTION(wifi_pll_lock),
 	FUNCTION(bt_pll_lock),
-	FUNCTION(rpu_v_pll_lock),
-	FUNCTION(rpu_l_pll_lock),
-	FUNCTION(audio_pll_lock),
 	FUNCTION(debug_raw_cca_ind),
 	FUNCTION(debug_ed_sec20_cca_ind),
 	FUNCTION(debug_ed_sec40_cca_ind),
@@ -809,17 +809,17 @@ static const struct pistachio_pin_group
 			   PADS_FUNCTION_SELECT2, 12, 0x3),
 	MFIO_MUX_PIN_GROUP(83, MIPS_PLL_LOCK, MIPS_TRACE_DATA, USB_DEBUG,
 			   PADS_FUNCTION_SELECT2, 14, 0x3),
-	MFIO_MUX_PIN_GROUP(84, SYS_PLL_LOCK, MIPS_TRACE_DATA, USB_DEBUG,
+	MFIO_MUX_PIN_GROUP(84, AUDIO_PLL_LOCK, MIPS_TRACE_DATA, USB_DEBUG,
 			   PADS_FUNCTION_SELECT2, 16, 0x3),
-	MFIO_MUX_PIN_GROUP(85, WIFI_PLL_LOCK, MIPS_TRACE_DATA, SDHOST_DEBUG,
+	MFIO_MUX_PIN_GROUP(85, RPU_V_PLL_LOCK, MIPS_TRACE_DATA, SDHOST_DEBUG,
 			   PADS_FUNCTION_SELECT2, 18, 0x3),
-	MFIO_MUX_PIN_GROUP(86, BT_PLL_LOCK, MIPS_TRACE_DATA, SDHOST_DEBUG,
+	MFIO_MUX_PIN_GROUP(86, RPU_L_PLL_LOCK, MIPS_TRACE_DATA, SDHOST_DEBUG,
 			   PADS_FUNCTION_SELECT2, 20, 0x3),
-	MFIO_MUX_PIN_GROUP(87, RPU_V_PLL_LOCK, DREQ2, SOCIF_DEBUG,
+	MFIO_MUX_PIN_GROUP(87, SYS_PLL_LOCK, DREQ2, SOCIF_DEBUG,
 			   PADS_FUNCTION_SELECT2, 22, 0x3),
-	MFIO_MUX_PIN_GROUP(88, RPU_L_PLL_LOCK, DREQ3, SOCIF_DEBUG,
+	MFIO_MUX_PIN_GROUP(88, WIFI_PLL_LOCK, DREQ3, SOCIF_DEBUG,
 			   PADS_FUNCTION_SELECT2, 24, 0x3),
-	MFIO_MUX_PIN_GROUP(89, AUDIO_PLL_LOCK, DREQ4, DREQ5,
+	MFIO_MUX_PIN_GROUP(89, BT_PLL_LOCK, DREQ4, DREQ5,
 			   PADS_FUNCTION_SELECT2, 26, 0x3),
 	PIN_GROUP(TCK, "tck"),
 	PIN_GROUP(TRSTN, "trstn"),
--- zfcpdump-kernel-4.4.orig/drivers/pinctrl/pinctrl-single.c
+++ zfcpdump-kernel-4.4/drivers/pinctrl/pinctrl-single.c
@@ -1273,9 +1273,9 @@ static int pcs_parse_bits_in_pinctrl_ent
 
 		/* Parse pins in each row from LSB */
 		while (mask) {
-			bit_pos = ffs(mask);
+			bit_pos = __ffs(mask);
 			pin_num_from_lsb = bit_pos / pcs->bits_per_pin;
-			mask_pos = ((pcs->fmask) << (bit_pos - 1));
+			mask_pos = ((pcs->fmask) << bit_pos);
 			val_pos = val & mask_pos;
 			submask = mask & mask_pos;
 
@@ -1576,6 +1576,9 @@ static inline void pcs_irq_set(struct pc
 		else
 			mask &= ~soc_mask;
 		pcs->write(mask, pcswi->reg);
+
+		/* flush posted write */
+		mask = pcs->read(pcswi->reg);
 		raw_spin_unlock(&pcs->lock);
 	}
 
@@ -1847,7 +1850,7 @@ static int pcs_probe(struct platform_dev
 	ret = of_property_read_u32(np, "pinctrl-single,function-mask",
 				   &pcs->fmask);
 	if (!ret) {
-		pcs->fshift = ffs(pcs->fmask) - 1;
+		pcs->fshift = __ffs(pcs->fmask);
 		pcs->fmax = pcs->fmask >> pcs->fshift;
 	} else {
 		/* If mask property doesn't exist, function mux is invalid. */
--- zfcpdump-kernel-4.4.orig/drivers/pinctrl/samsung/pinctrl-exynos5440.c
+++ zfcpdump-kernel-4.4/drivers/pinctrl/samsung/pinctrl-exynos5440.c
@@ -107,6 +107,7 @@ struct exynos5440_pmx_func {
  * @nr_groups: number of pin groups available.
  * @pmx_functions: list of pin functions parsed from device tree.
  * @nr_functions: number of pin functions available.
+ * @range: gpio range to register with pinctrl
  */
 struct exynos5440_pinctrl_priv_data {
 	void __iomem			*reg_base;
@@ -117,6 +118,7 @@ struct exynos5440_pinctrl_priv_data {
 	unsigned int			nr_groups;
 	const struct exynos5440_pmx_func	*pmx_functions;
 	unsigned int			nr_functions;
+	struct pinctrl_gpio_range	range;
 };
 
 /**
@@ -742,7 +744,6 @@ static int exynos5440_pinctrl_register(s
 	struct pinctrl_desc *ctrldesc;
 	struct pinctrl_dev *pctl_dev;
 	struct pinctrl_pin_desc *pindesc, *pdesc;
-	struct pinctrl_gpio_range grange;
 	char *pin_names;
 	int pin, ret;
 
@@ -794,12 +795,12 @@ static int exynos5440_pinctrl_register(s
 		return PTR_ERR(pctl_dev);
 	}
 
-	grange.name = "exynos5440-pctrl-gpio-range";
-	grange.id = 0;
-	grange.base = 0;
-	grange.npins = EXYNOS5440_MAX_PINS;
-	grange.gc = priv->gc;
-	pinctrl_add_gpio_range(pctl_dev, &grange);
+	priv->range.name = "exynos5440-pctrl-gpio-range";
+	priv->range.id = 0;
+	priv->range.base = 0;
+	priv->range.npins = EXYNOS5440_MAX_PINS;
+	priv->range.gc = priv->gc;
+	pinctrl_add_gpio_range(pctl_dev, &priv->range);
 	return 0;
 }
 
--- zfcpdump-kernel-4.4.orig/drivers/pinctrl/sh-pfc/core.c
+++ zfcpdump-kernel-4.4/drivers/pinctrl/sh-pfc/core.c
@@ -545,7 +545,9 @@ static int sh_pfc_probe(struct platform_
 			return ret;
 	}
 
-	pinctrl_provide_dummies();
+	/* Enable dummy states for those platforms without pinctrl support */
+	if (!of_have_populated_dt())
+		pinctrl_provide_dummies();
 
 	ret = sh_pfc_init_ranges(pfc);
 	if (ret < 0)
--- zfcpdump-kernel-4.4.orig/drivers/pinctrl/sunxi/pinctrl-sun8i-a23.c
+++ zfcpdump-kernel-4.4/drivers/pinctrl/sunxi/pinctrl-sun8i-a23.c
@@ -485,12 +485,12 @@ static const struct sunxi_desc_pin sun8i
 	SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 8),
 		  SUNXI_FUNCTION(0x0, "gpio_in"),
 		  SUNXI_FUNCTION(0x1, "gpio_out"),
-		  SUNXI_FUNCTION(0x2, "uart2"),		/* RTS */
+		  SUNXI_FUNCTION(0x2, "uart1"),		/* RTS */
 		  SUNXI_FUNCTION_IRQ_BANK(0x4, 2, 8)),	/* PG_EINT8 */
 	SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 9),
 		  SUNXI_FUNCTION(0x0, "gpio_in"),
 		  SUNXI_FUNCTION(0x1, "gpio_out"),
-		  SUNXI_FUNCTION(0x2, "uart2"),		/* CTS */
+		  SUNXI_FUNCTION(0x2, "uart1"),		/* CTS */
 		  SUNXI_FUNCTION_IRQ_BANK(0x4, 2, 9)),	/* PG_EINT9 */
 	SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 10),
 		  SUNXI_FUNCTION(0x0, "gpio_in"),
--- zfcpdump-kernel-4.4.orig/drivers/pinctrl/sunxi/pinctrl-sun8i-a33.c
+++ zfcpdump-kernel-4.4/drivers/pinctrl/sunxi/pinctrl-sun8i-a33.c
@@ -407,12 +407,12 @@ static const struct sunxi_desc_pin sun8i
 	SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 8),
 		  SUNXI_FUNCTION(0x0, "gpio_in"),
 		  SUNXI_FUNCTION(0x1, "gpio_out"),
-		  SUNXI_FUNCTION(0x2, "uart2"),		/* RTS */
+		  SUNXI_FUNCTION(0x2, "uart1"),		/* RTS */
 		  SUNXI_FUNCTION_IRQ_BANK(0x4, 1, 8)),	/* PG_EINT8 */
 	SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 9),
 		  SUNXI_FUNCTION(0x0, "gpio_in"),
 		  SUNXI_FUNCTION(0x1, "gpio_out"),
-		  SUNXI_FUNCTION(0x2, "uart2"),		/* CTS */
+		  SUNXI_FUNCTION(0x2, "uart1"),		/* CTS */
 		  SUNXI_FUNCTION_IRQ_BANK(0x4, 1, 9)),	/* PG_EINT9 */
 	SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 10),
 		  SUNXI_FUNCTION(0x0, "gpio_in"),
@@ -485,6 +485,7 @@ static const struct sunxi_pinctrl_desc s
 	.pins = sun8i_a33_pins,
 	.npins = ARRAY_SIZE(sun8i_a33_pins),
 	.irq_banks = 2,
+	.irq_bank_base = 1,
 };
 
 static int sun8i_a33_pinctrl_probe(struct platform_device *pdev)
--- zfcpdump-kernel-4.4.orig/drivers/pinctrl/sunxi/pinctrl-sunxi.c
+++ zfcpdump-kernel-4.4/drivers/pinctrl/sunxi/pinctrl-sunxi.c
@@ -578,7 +578,7 @@ static void sunxi_pinctrl_irq_release_re
 static int sunxi_pinctrl_irq_set_type(struct irq_data *d, unsigned int type)
 {
 	struct sunxi_pinctrl *pctl = irq_data_get_irq_chip_data(d);
-	u32 reg = sunxi_irq_cfg_reg(d->hwirq);
+	u32 reg = sunxi_irq_cfg_reg(d->hwirq, pctl->desc->irq_bank_base);
 	u8 index = sunxi_irq_cfg_offset(d->hwirq);
 	unsigned long flags;
 	u32 regval;
@@ -625,7 +625,8 @@ static int sunxi_pinctrl_irq_set_type(st
 static void sunxi_pinctrl_irq_ack(struct irq_data *d)
 {
 	struct sunxi_pinctrl *pctl = irq_data_get_irq_chip_data(d);
-	u32 status_reg = sunxi_irq_status_reg(d->hwirq);
+	u32 status_reg = sunxi_irq_status_reg(d->hwirq,
+					      pctl->desc->irq_bank_base);
 	u8 status_idx = sunxi_irq_status_offset(d->hwirq);
 
 	/* Clear the IRQ */
@@ -635,7 +636,7 @@ static void sunxi_pinctrl_irq_ack(struct
 static void sunxi_pinctrl_irq_mask(struct irq_data *d)
 {
 	struct sunxi_pinctrl *pctl = irq_data_get_irq_chip_data(d);
-	u32 reg = sunxi_irq_ctrl_reg(d->hwirq);
+	u32 reg = sunxi_irq_ctrl_reg(d->hwirq, pctl->desc->irq_bank_base);
 	u8 idx = sunxi_irq_ctrl_offset(d->hwirq);
 	unsigned long flags;
 	u32 val;
@@ -652,7 +653,7 @@ static void sunxi_pinctrl_irq_mask(struc
 static void sunxi_pinctrl_irq_unmask(struct irq_data *d)
 {
 	struct sunxi_pinctrl *pctl = irq_data_get_irq_chip_data(d);
-	u32 reg = sunxi_irq_ctrl_reg(d->hwirq);
+	u32 reg = sunxi_irq_ctrl_reg(d->hwirq, pctl->desc->irq_bank_base);
 	u8 idx = sunxi_irq_ctrl_offset(d->hwirq);
 	unsigned long flags;
 	u32 val;
@@ -744,7 +745,7 @@ static void sunxi_pinctrl_irq_handler(st
 	if (bank == pctl->desc->irq_banks)
 		return;
 
-	reg = sunxi_irq_status_reg_from_bank(bank);
+	reg = sunxi_irq_status_reg_from_bank(bank, pctl->desc->irq_bank_base);
 	val = readl(pctl->membase + reg);
 
 	if (val) {
@@ -1023,9 +1024,11 @@ int sunxi_pinctrl_init(struct platform_d
 
 	for (i = 0; i < pctl->desc->irq_banks; i++) {
 		/* Mask and clear all IRQs before registering a handler */
-		writel(0, pctl->membase + sunxi_irq_ctrl_reg_from_bank(i));
+		writel(0, pctl->membase + sunxi_irq_ctrl_reg_from_bank(i,
+						pctl->desc->irq_bank_base));
 		writel(0xffffffff,
-			pctl->membase + sunxi_irq_status_reg_from_bank(i));
+		       pctl->membase + sunxi_irq_status_reg_from_bank(i,
+						pctl->desc->irq_bank_base));
 
 		irq_set_chained_handler_and_data(pctl->irq[i],
 						 sunxi_pinctrl_irq_handler,
--- zfcpdump-kernel-4.4.orig/drivers/pinctrl/sunxi/pinctrl-sunxi.h
+++ zfcpdump-kernel-4.4/drivers/pinctrl/sunxi/pinctrl-sunxi.h
@@ -97,6 +97,7 @@ struct sunxi_pinctrl_desc {
 	int				npins;
 	unsigned			pin_base;
 	unsigned			irq_banks;
+	unsigned			irq_bank_base;
 	bool				irq_read_needs_mux;
 };
 
@@ -233,12 +234,12 @@ static inline u32 sunxi_pull_offset(u16
 	return pin_num * PULL_PINS_BITS;
 }
 
-static inline u32 sunxi_irq_cfg_reg(u16 irq)
+static inline u32 sunxi_irq_cfg_reg(u16 irq, unsigned bank_base)
 {
 	u8 bank = irq / IRQ_PER_BANK;
 	u8 reg = (irq % IRQ_PER_BANK) / IRQ_CFG_IRQ_PER_REG * 0x04;
 
-	return IRQ_CFG_REG + bank * IRQ_MEM_SIZE + reg;
+	return IRQ_CFG_REG + (bank_base + bank) * IRQ_MEM_SIZE + reg;
 }
 
 static inline u32 sunxi_irq_cfg_offset(u16 irq)
@@ -247,16 +248,16 @@ static inline u32 sunxi_irq_cfg_offset(u
 	return irq_num * IRQ_CFG_IRQ_BITS;
 }
 
-static inline u32 sunxi_irq_ctrl_reg_from_bank(u8 bank)
+static inline u32 sunxi_irq_ctrl_reg_from_bank(u8 bank, unsigned bank_base)
 {
-	return IRQ_CTRL_REG + bank * IRQ_MEM_SIZE;
+	return IRQ_CTRL_REG + (bank_base + bank) * IRQ_MEM_SIZE;
 }
 
-static inline u32 sunxi_irq_ctrl_reg(u16 irq)
+static inline u32 sunxi_irq_ctrl_reg(u16 irq, unsigned bank_base)
 {
 	u8 bank = irq / IRQ_PER_BANK;
 
-	return sunxi_irq_ctrl_reg_from_bank(bank);
+	return sunxi_irq_ctrl_reg_from_bank(bank, bank_base);
 }
 
 static inline u32 sunxi_irq_ctrl_offset(u16 irq)
@@ -265,16 +266,16 @@ static inline u32 sunxi_irq_ctrl_offset(
 	return irq_num * IRQ_CTRL_IRQ_BITS;
 }
 
-static inline u32 sunxi_irq_status_reg_from_bank(u8 bank)
+static inline u32 sunxi_irq_status_reg_from_bank(u8 bank, unsigned bank_base)
 {
-	return IRQ_STATUS_REG + bank * IRQ_MEM_SIZE;
+	return IRQ_STATUS_REG + (bank_base + bank) * IRQ_MEM_SIZE;
 }
 
-static inline u32 sunxi_irq_status_reg(u16 irq)
+static inline u32 sunxi_irq_status_reg(u16 irq, unsigned bank_base)
 {
 	u8 bank = irq / IRQ_PER_BANK;
 
-	return sunxi_irq_status_reg_from_bank(bank);
+	return sunxi_irq_status_reg_from_bank(bank, bank_base);
 }
 
 static inline u32 sunxi_irq_status_offset(u16 irq)
--- zfcpdump-kernel-4.4.orig/drivers/pinctrl/uniphier/pinctrl-uniphier-core.c
+++ zfcpdump-kernel-4.4/drivers/pinctrl/uniphier/pinctrl-uniphier-core.c
@@ -73,6 +73,12 @@ static void uniphier_pctl_pin_dbg_show(s
 	case UNIPHIER_PIN_PULL_DOWN:
 		pull_dir = "DOWN";
 		break;
+	case UNIPHIER_PIN_PULL_UP_FIXED:
+		pull_dir = "UP(FIXED)";
+		break;
+	case UNIPHIER_PIN_PULL_DOWN_FIXED:
+		pull_dir = "DOWN(FIXED)";
+		break;
 	case UNIPHIER_PIN_PULL_NONE:
 		pull_dir = "NONE";
 		break;
--- zfcpdump-kernel-4.4.orig/drivers/platform/chrome/cros_ec_dev.c
+++ zfcpdump-kernel-4.4/drivers/platform/chrome/cros_ec_dev.c
@@ -147,13 +147,19 @@ static long ec_device_ioctl_xcmd(struct
 		goto exit;
 	}
 
+	if (u_cmd.outsize != s_cmd->outsize ||
+	    u_cmd.insize != s_cmd->insize) {
+		ret = -EINVAL;
+		goto exit;
+	}
+
 	s_cmd->command += ec->cmd_offset;
 	ret = cros_ec_cmd_xfer(ec->ec_dev, s_cmd);
 	/* Only copy data to userland if data was received. */
 	if (ret < 0)
 		goto exit;
 
-	if (copy_to_user(arg, s_cmd, sizeof(*s_cmd) + u_cmd.insize))
+	if (copy_to_user(arg, s_cmd, sizeof(*s_cmd) + s_cmd->insize))
 		ret = -EFAULT;
 exit:
 	kfree(s_cmd);
--- zfcpdump-kernel-4.4.orig/drivers/platform/chrome/cros_ec_proto.c
+++ zfcpdump-kernel-4.4/drivers/platform/chrome/cros_ec_proto.c
@@ -380,3 +380,20 @@ int cros_ec_cmd_xfer(struct cros_ec_devi
 	return ret;
 }
 EXPORT_SYMBOL(cros_ec_cmd_xfer);
+
+int cros_ec_cmd_xfer_status(struct cros_ec_device *ec_dev,
+			    struct cros_ec_command *msg)
+{
+	int ret;
+
+	ret = cros_ec_cmd_xfer(ec_dev, msg);
+	if (ret < 0) {
+		dev_err(ec_dev->dev, "Command xfer error (err:%d)\n", ret);
+	} else if (msg->result != EC_RES_SUCCESS) {
+		dev_dbg(ec_dev->dev, "Command result (err: %d)\n", msg->result);
+		return -EPROTO;
+	}
+
+	return ret;
+}
+EXPORT_SYMBOL(cros_ec_cmd_xfer_status);
--- zfcpdump-kernel-4.4.orig/drivers/platform/x86/Kconfig
+++ zfcpdump-kernel-4.4/drivers/platform/x86/Kconfig
@@ -731,6 +731,30 @@ config ACPI_CMPC
 	  keys as input device, backlight device, tablet and accelerometer
 	  devices.
 
+config INTEL_HID_EVENT
+	tristate "INTEL HID Event"
+	depends on ACPI
+	depends on INPUT
+	select INPUT_SPARSEKMAP
+	help
+	  This driver provides support for the Intel HID Event hotkey interface.
+	  Some laptops require this driver for hotkey support.
+
+	  To compile this driver as a module, choose M here: the module will
+	  be called intel_hid.
+
+config INTEL_VBTN
+	tristate "INTEL VIRTUAL BUTTON"
+	depends on ACPI
+	depends on INPUT
+	select INPUT_SPARSEKMAP
+	help
+	  This driver provides support for the Intel Virtual Button interface.
+	  Some laptops require this driver for power button support.
+
+	  To compile this driver as a module, choose M here: the module will
+	  be called intel_vbtn.
+
 config INTEL_SCU_IPC
 	bool "Intel SCU IPC Support"
 	depends on X86_INTEL_MID
@@ -944,4 +968,21 @@ config SURFACE_PRO3_BUTTON
 	depends on ACPI && INPUT
 	---help---
 	  This driver handles the power/home/volume buttons on the Microsoft Surface Pro 3 tablet.
+
+config INTEL_PUNIT_IPC
+	tristate "Intel P-Unit IPC Driver"
+	---help---
+	  This driver provides support for Intel P-Unit Mailbox IPC mechanism,
+	  which is used to bridge the communications between kernel and P-Unit.
+
+config INTEL_TELEMETRY
+	tristate "Intel SoC Telemetry Driver"
+	default n
+	depends on INTEL_PMC_IPC && INTEL_PUNIT_IPC && X86_64
+	---help---
+	  This driver provides interfaces to configure and use
+	  telemetry for INTEL SoC from APL onwards. It is also
+	  used to get various SoC events and parameters
+	  directly via debugfs files. Various tools may use
+	  this interface for SoC state monitoring.
 endif # X86_PLATFORM_DEVICES
--- zfcpdump-kernel-4.4.orig/drivers/platform/x86/Makefile
+++ zfcpdump-kernel-4.4/drivers/platform/x86/Makefile
@@ -41,6 +41,8 @@ obj-$(CONFIG_ACPI_TOSHIBA)	+= toshiba_ac
 obj-$(CONFIG_TOSHIBA_BT_RFKILL)	+= toshiba_bluetooth.o
 obj-$(CONFIG_TOSHIBA_HAPS)	+= toshiba_haps.o
 obj-$(CONFIG_TOSHIBA_WMI)	+= toshiba-wmi.o
+obj-$(CONFIG_INTEL_HID_EVENT)	+= intel-hid.o
+obj-$(CONFIG_INTEL_VBTN)	+= intel-vbtn.o
 obj-$(CONFIG_INTEL_SCU_IPC)	+= intel_scu_ipc.o
 obj-$(CONFIG_INTEL_SCU_IPC_UTIL) += intel_scu_ipcutil.o
 obj-$(CONFIG_INTEL_MFLD_THERMAL) += intel_mid_thermal.o
@@ -62,3 +64,7 @@ obj-$(CONFIG_PVPANIC)           += pvpan
 obj-$(CONFIG_ALIENWARE_WMI)	+= alienware-wmi.o
 obj-$(CONFIG_INTEL_PMC_IPC)	+= intel_pmc_ipc.o
 obj-$(CONFIG_SURFACE_PRO3_BUTTON)	+= surfacepro3_button.o
+obj-$(CONFIG_INTEL_PUNIT_IPC)  += intel_punit_ipc.o
+obj-$(CONFIG_INTEL_TELEMETRY)	+= intel_telemetry_core.o \
+				   intel_telemetry_pltdrv.o \
+				   intel_telemetry_debugfs.o
--- zfcpdump-kernel-4.4.orig/drivers/platform/x86/asus-wmi.c
+++ zfcpdump-kernel-4.4/drivers/platform/x86/asus-wmi.c
@@ -1870,6 +1870,9 @@ static int show_dsts(struct seq_file *m,
 	int err;
 	u32 retval = -1;
 
+	if (secure_modules())
+		return -EPERM;
+
 	err = asus_wmi_get_devstate(asus, asus->debug.dev_id, &retval);
 
 	if (err < 0)
@@ -1886,6 +1889,9 @@ static int show_devs(struct seq_file *m,
 	int err;
 	u32 retval = -1;
 
+	if (secure_modules())
+		return -EPERM;
+
 	err = asus_wmi_set_devstate(asus->debug.dev_id, asus->debug.ctrl_param,
 				    &retval);
 
@@ -1910,6 +1916,9 @@ static int show_call(struct seq_file *m,
 	union acpi_object *obj;
 	acpi_status status;
 
+	if (secure_modules())
+		return -EPERM;
+
 	status = wmi_evaluate_method(ASUS_WMI_MGMT_GUID,
 				     1, asus->debug.method_id,
 				     &input, &output);
--- zfcpdump-kernel-4.4.orig/drivers/platform/x86/dell-rbtn.c
+++ zfcpdump-kernel-4.4/drivers/platform/x86/dell-rbtn.c
@@ -28,6 +28,7 @@ struct rbtn_data {
 	enum rbtn_type type;
 	struct rfkill *rfkill;
 	struct input_dev *input_dev;
+	bool suspended;
 };
 
 
@@ -220,9 +221,55 @@ static const struct acpi_device_id rbtn_
 	{ "", 0 },
 };
 
+#ifdef CONFIG_PM_SLEEP
+static void ACPI_SYSTEM_XFACE rbtn_clear_suspended_flag(void *context)
+{
+	struct rbtn_data *rbtn_data = context;
+
+	rbtn_data->suspended = false;
+}
+
+static int rbtn_suspend(struct device *dev)
+{
+	struct acpi_device *device = to_acpi_device(dev);
+	struct rbtn_data *rbtn_data = acpi_driver_data(device);
+
+	rbtn_data->suspended = true;
+
+	return 0;
+}
+
+static int rbtn_resume(struct device *dev)
+{
+	struct acpi_device *device = to_acpi_device(dev);
+	struct rbtn_data *rbtn_data = acpi_driver_data(device);
+	acpi_status status;
+
+	/*
+	 * Upon resume, some BIOSes send an ACPI notification thet triggers
+	 * an unwanted input event. In order to ignore it, we use a flag
+	 * that we set at suspend and clear once we have received the extra
+	 * ACPI notification. Since ACPI notifications are delivered
+	 * asynchronously to drivers, we clear the flag from the workqueue
+	 * used to deliver the notifications. This should be enough
+	 * to have the flag cleared only after we received the extra
+	 * notification, if any.
+	 */
+	status = acpi_os_execute(OSL_NOTIFY_HANDLER,
+			 rbtn_clear_suspended_flag, rbtn_data);
+	if (ACPI_FAILURE(status))
+		rbtn_clear_suspended_flag(rbtn_data);
+
+	return 0;
+}
+#endif
+
+static SIMPLE_DEV_PM_OPS(rbtn_pm_ops, rbtn_suspend, rbtn_resume);
+
 static struct acpi_driver rbtn_driver = {
 	.name = "dell-rbtn",
 	.ids = rbtn_ids,
+	.drv.pm = &rbtn_pm_ops,
 	.ops = {
 		.add = rbtn_add,
 		.remove = rbtn_remove,
@@ -384,6 +431,15 @@ static void rbtn_notify(struct acpi_devi
 {
 	struct rbtn_data *rbtn_data = device->driver_data;
 
+	/*
+	 * Some BIOSes send a notification at resume.
+	 * Ignore it to prevent unwanted input events.
+	 */
+	if (rbtn_data->suspended) {
+		dev_dbg(&device->dev, "ACPI notification ignored\n");
+		return;
+	}
+
 	if (event != 0x80) {
 		dev_info(&device->dev, "Received unknown event (0x%x)\n",
 			 event);
--- zfcpdump-kernel-4.4.orig/drivers/platform/x86/hp-wmi.c
+++ zfcpdump-kernel-4.4/drivers/platform/x86/hp-wmi.c
@@ -723,6 +723,11 @@ static int __init hp_wmi_rfkill_setup(st
 	if (err)
 		return err;
 
+	err = hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, 1, &wireless,
+				   sizeof(wireless), 0);
+	if (err)
+		return err;
+
 	if (wireless & 0x1) {
 		wifi_rfkill = rfkill_alloc("hp-wifi", &device->dev,
 					   RFKILL_TYPE_WLAN,
@@ -910,7 +915,7 @@ static int __init hp_wmi_bios_setup(stru
 	gps_rfkill = NULL;
 	rfkill2_count = 0;
 
-	if (hp_wmi_bios_2009_later() || hp_wmi_rfkill_setup(device))
+	if (hp_wmi_rfkill_setup(device))
 		hp_wmi_rfkill2_setup(device);
 
 	err = device_create_file(&device->dev, &dev_attr_display);
--- zfcpdump-kernel-4.4.orig/drivers/platform/x86/ideapad-laptop.c
+++ zfcpdump-kernel-4.4/drivers/platform/x86/ideapad-laptop.c
@@ -563,6 +563,7 @@ static void ideapad_sysfs_exit(struct id
 static const struct key_entry ideapad_keymap[] = {
 	{ KE_KEY, 6,  { KEY_SWITCHVIDEOMODE } },
 	{ KE_KEY, 7,  { KEY_CAMERA } },
+	{ KE_KEY, 8,  { KEY_MICMUTE } },
 	{ KE_KEY, 11, { KEY_F16 } },
 	{ KE_KEY, 13, { KEY_WLAN } },
 	{ KE_KEY, 16, { KEY_PROG1 } },
@@ -805,6 +806,7 @@ static void ideapad_acpi_notify(acpi_han
 				break;
 			case 13:
 			case 11:
+			case 8:
 			case 7:
 			case 6:
 				ideapad_input_report(priv, vpc_bit);
@@ -865,6 +867,27 @@ static const struct dmi_system_id no_hw_
 		},
 	},
 	{
+		.ident = "Lenovo ideapad Y700-15ISK",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+			DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo ideapad Y700-15ISK"),
+		},
+	},
+	{
+		.ident = "Lenovo ideapad Y700 Touch-15ISK",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+			DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo ideapad Y700 Touch-15ISK"),
+		},
+	},
+	{
+		.ident = "Lenovo ideapad Y700-17ISK",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+			DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo ideapad Y700-17ISK"),
+		},
+	},
+	{
 		.ident = "Lenovo Yoga 2 11 / 13 / Pro",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
@@ -893,6 +916,13 @@ static const struct dmi_system_id no_hw_
 		},
 	},
 	{
+		.ident = "Lenovo Yoga 700",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+			DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo YOGA 700"),
+		},
+	},
+	{
 		.ident = "Lenovo Yoga 900",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/platform/x86/intel-hid.c
@@ -0,0 +1,289 @@
+/*
+ *  Intel HID event driver for Windows 8
+ *
+ *  Copyright (C) 2015 Alex Hung <alex.hung@canonical.com>
+ *  Copyright (C) 2015 Andrew Lutomirski <luto@kernel.org>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/input.h>
+#include <linux/platform_device.h>
+#include <linux/input/sparse-keymap.h>
+#include <linux/acpi.h>
+#include <acpi/acpi_bus.h>
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Alex Hung");
+
+static const struct acpi_device_id intel_hid_ids[] = {
+	{"INT33D5", 0},
+	{"", 0},
+};
+
+/* In theory, these are HID usages. */
+static const struct key_entry intel_hid_keymap[] = {
+	/* 1: LSuper (Page 0x07, usage 0xE3) -- unclear what to do */
+	/* 2: Toggle SW_ROTATE_LOCK -- easy to implement if seen in wild */
+	{ KE_KEY, 3, { KEY_NUMLOCK } },
+	{ KE_KEY, 4, { KEY_HOME } },
+	{ KE_KEY, 5, { KEY_END } },
+	{ KE_KEY, 6, { KEY_PAGEUP } },
+	{ KE_KEY, 7, { KEY_PAGEDOWN } },
+	{ KE_KEY, 8, { KEY_RFKILL } },
+	{ KE_KEY, 9, { KEY_POWER } },
+	{ KE_KEY, 11, { KEY_SLEEP } },
+	/* 13 has two different meanings in the spec -- ignore it. */
+	{ KE_KEY, 14, { KEY_STOPCD } },
+	{ KE_KEY, 15, { KEY_PLAYPAUSE } },
+	{ KE_KEY, 16, { KEY_MUTE } },
+	{ KE_KEY, 17, { KEY_VOLUMEUP } },
+	{ KE_KEY, 18, { KEY_VOLUMEDOWN } },
+	{ KE_KEY, 19, { KEY_BRIGHTNESSUP } },
+	{ KE_KEY, 20, { KEY_BRIGHTNESSDOWN } },
+	/* 27: wake -- needs special handling */
+	{ KE_END },
+};
+
+struct intel_hid_priv {
+	struct input_dev *input_dev;
+};
+
+static int intel_hid_set_enable(struct device *device, int enable)
+{
+	union acpi_object arg0 = { ACPI_TYPE_INTEGER };
+	struct acpi_object_list args = { 1, &arg0 };
+	acpi_status status;
+
+	arg0.integer.value = enable;
+	status = acpi_evaluate_object(ACPI_HANDLE(device), "HDSM", &args, NULL);
+	if (!ACPI_SUCCESS(status)) {
+		dev_warn(device, "failed to %sable hotkeys\n",
+			 enable ? "en" : "dis");
+		return -EIO;
+	}
+
+	return 0;
+}
+
+static int intel_hid_pl_suspend_handler(struct device *device)
+{
+	intel_hid_set_enable(device, 0);
+	return 0;
+}
+
+static int intel_hid_pl_resume_handler(struct device *device)
+{
+	intel_hid_set_enable(device, 1);
+	return 0;
+}
+
+static const struct dev_pm_ops intel_hid_pl_pm_ops = {
+	.freeze  = intel_hid_pl_suspend_handler,
+	.restore  = intel_hid_pl_resume_handler,
+	.suspend  = intel_hid_pl_suspend_handler,
+	.resume  = intel_hid_pl_resume_handler,
+};
+
+static int intel_hid_input_setup(struct platform_device *device)
+{
+	struct intel_hid_priv *priv = dev_get_drvdata(&device->dev);
+	int ret;
+
+	priv->input_dev = input_allocate_device();
+	if (!priv->input_dev)
+		return -ENOMEM;
+
+	ret = sparse_keymap_setup(priv->input_dev, intel_hid_keymap, NULL);
+	if (ret)
+		goto err_free_device;
+
+	priv->input_dev->dev.parent = &device->dev;
+	priv->input_dev->name = "Intel HID events";
+	priv->input_dev->id.bustype = BUS_HOST;
+	set_bit(KEY_RFKILL, priv->input_dev->keybit);
+
+	ret = input_register_device(priv->input_dev);
+	if (ret)
+		goto err_free_device;
+
+	return 0;
+
+err_free_device:
+		input_free_device(priv->input_dev);
+		return ret;
+}
+
+static void intel_hid_input_destroy(struct platform_device *device)
+{
+	struct intel_hid_priv *priv = dev_get_drvdata(&device->dev);
+
+	input_unregister_device(priv->input_dev);
+}
+
+static void notify_handler(acpi_handle handle, u32 event, void *context)
+{
+	struct platform_device *device = context;
+	struct intel_hid_priv *priv = dev_get_drvdata(&device->dev);
+	unsigned long long ev_index;
+	acpi_status status;
+
+	/* The platform spec only defines one event code: 0xC0. */
+	if (event != 0xc0) {
+		dev_warn(&device->dev, "received unknown event (0x%x)\n",
+			 event);
+		return;
+	}
+
+	status = acpi_evaluate_integer(handle, "HDEM", NULL, &ev_index);
+	if (!ACPI_SUCCESS(status)) {
+		dev_warn(&device->dev, "failed to get event index\n");
+		return;
+	}
+
+	if (!sparse_keymap_report_event(priv->input_dev, ev_index, 1, true))
+		dev_info(&device->dev, "unknown event index 0x%llx\n",
+			 ev_index);
+}
+
+static int intel_hid_probe(struct platform_device *device)
+{
+	acpi_handle handle = ACPI_HANDLE(&device->dev);
+	struct intel_hid_priv *priv;
+	unsigned long long mode;
+	acpi_status status;
+	int err;
+
+	status = acpi_evaluate_integer(handle, "HDMM", NULL, &mode);
+	if (!ACPI_SUCCESS(status)) {
+		dev_warn(&device->dev, "failed to read mode\n");
+		return -ENODEV;
+	}
+
+	if (mode != 0) {
+		/*
+		 * This driver only implements "simple" mode.  There appear
+		 * to be no other modes, but we should be paranoid and check
+		 * for compatibility.
+		 */
+		dev_info(&device->dev, "platform is not in simple mode\n");
+		return -ENODEV;
+	}
+
+	priv = devm_kzalloc(&device->dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+	dev_set_drvdata(&device->dev, priv);
+
+	err = intel_hid_input_setup(device);
+	if (err) {
+		pr_err("Failed to setup Intel HID hotkeys\n");
+		return err;
+	}
+
+	status = acpi_install_notify_handler(handle,
+					     ACPI_DEVICE_NOTIFY,
+					     notify_handler,
+					     device);
+	if (ACPI_FAILURE(status)) {
+		err = -EBUSY;
+		goto err_remove_input;
+	}
+
+	err = intel_hid_set_enable(&device->dev, 1);
+	if (err)
+		goto err_remove_notify;
+
+	return 0;
+
+err_remove_notify:
+	acpi_remove_notify_handler(handle, ACPI_DEVICE_NOTIFY, notify_handler);
+
+err_remove_input:
+	intel_hid_input_destroy(device);
+
+	return err;
+}
+
+static int intel_hid_remove(struct platform_device *device)
+{
+	acpi_handle handle = ACPI_HANDLE(&device->dev);
+
+	acpi_remove_notify_handler(handle, ACPI_DEVICE_NOTIFY, notify_handler);
+	intel_hid_input_destroy(device);
+	intel_hid_set_enable(&device->dev, 0);
+	acpi_remove_notify_handler(handle, ACPI_DEVICE_NOTIFY, notify_handler);
+
+	/*
+	 * Even if we failed to shut off the event stream, we can still
+	 * safely detach from the device.
+	 */
+	return 0;
+}
+
+static struct platform_driver intel_hid_pl_driver = {
+	.driver = {
+		.name = "intel-hid",
+		.acpi_match_table = intel_hid_ids,
+		.pm = &intel_hid_pl_pm_ops,
+	},
+	.probe = intel_hid_probe,
+	.remove = intel_hid_remove,
+};
+MODULE_DEVICE_TABLE(acpi, intel_hid_ids);
+
+/*
+ * Unfortunately, some laptops provide a _HID="INT33D5" device with
+ * _CID="PNP0C02".  This causes the pnpacpi scan driver to claim the
+ * ACPI node, so no platform device will be created.  The pnpacpi
+ * driver rejects this device in subsequent processing, so no physical
+ * node is created at all.
+ *
+ * As a workaround until the ACPI core figures out how to handle
+ * this corner case, manually ask the ACPI platform device code to
+ * claim the ACPI node.
+ */
+static acpi_status __init
+check_acpi_dev(acpi_handle handle, u32 lvl, void *context, void **rv)
+{
+	const struct acpi_device_id *ids = context;
+	struct acpi_device *dev;
+
+	if (acpi_bus_get_device(handle, &dev) != 0)
+		return AE_OK;
+
+	if (acpi_match_device_ids(dev, ids) == 0)
+		if (acpi_create_platform_device(dev))
+			dev_info(&dev->dev,
+				 "intel-hid: created platform device\n");
+
+	return AE_OK;
+}
+
+static int __init intel_hid_init(void)
+{
+	acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
+			    ACPI_UINT32_MAX, check_acpi_dev, NULL,
+			    (void *)intel_hid_ids, NULL);
+
+	return platform_driver_register(&intel_hid_pl_driver);
+}
+module_init(intel_hid_init);
+
+static void __exit intel_hid_exit(void)
+{
+	platform_driver_unregister(&intel_hid_pl_driver);
+}
+module_exit(intel_hid_exit);
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/platform/x86/intel-vbtn.c
@@ -0,0 +1,188 @@
+/*
+ *  Intel Virtual Button driver for Windows 8.1+
+ *
+ *  Copyright (C) 2016 AceLan Kao <acelan.kao@canonical.com>
+ *  Copyright (C) 2016 Alex Hung <alex.hung@canonical.com>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/input.h>
+#include <linux/platform_device.h>
+#include <linux/input/sparse-keymap.h>
+#include <linux/acpi.h>
+#include <acpi/acpi_bus.h>
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("AceLan Kao");
+
+static const struct acpi_device_id intel_vbtn_ids[] = {
+	{"INT33D6", 0},
+	{"", 0},
+};
+
+/* In theory, these are HID usages. */
+static const struct key_entry intel_vbtn_keymap[] = {
+	{ KE_IGNORE, 0xC0, { KEY_POWER } },	/* power key press */
+	{ KE_KEY, 0xC1, { KEY_POWER } },	/* power key release */
+	{ KE_END },
+};
+
+struct intel_vbtn_priv {
+	struct input_dev *input_dev;
+};
+
+static int intel_vbtn_input_setup(struct platform_device *device)
+{
+	struct intel_vbtn_priv *priv = dev_get_drvdata(&device->dev);
+	int ret;
+
+	priv->input_dev = input_allocate_device();
+	if (!priv->input_dev)
+		return -ENOMEM;
+
+	ret = sparse_keymap_setup(priv->input_dev, intel_vbtn_keymap, NULL);
+	if (ret)
+		goto err_free_device;
+
+	priv->input_dev->dev.parent = &device->dev;
+	priv->input_dev->name = "Intel Virtual Button driver";
+	priv->input_dev->id.bustype = BUS_HOST;
+
+	ret = input_register_device(priv->input_dev);
+	if (ret)
+		goto err_free_device;
+
+	return 0;
+
+err_free_device:
+	input_free_device(priv->input_dev);
+	return ret;
+}
+
+static void intel_vbtn_input_destroy(struct platform_device *device)
+{
+	struct intel_vbtn_priv *priv = dev_get_drvdata(&device->dev);
+
+	input_unregister_device(priv->input_dev);
+}
+
+static void notify_handler(acpi_handle handle, u32 event, void *context)
+{
+	struct platform_device *device = context;
+	struct intel_vbtn_priv *priv = dev_get_drvdata(&device->dev);
+
+	if (!sparse_keymap_report_event(priv->input_dev, event, 1, true))
+		dev_info(&device->dev, "unknown event index 0x%x\n",
+			 event);
+}
+
+static int intel_vbtn_probe(struct platform_device *device)
+{
+	acpi_handle handle = ACPI_HANDLE(&device->dev);
+	struct intel_vbtn_priv *priv;
+	acpi_status status;
+	int err;
+
+	status = acpi_evaluate_object(handle, "VBDL", NULL, NULL);
+	if (!ACPI_SUCCESS(status)) {
+		dev_warn(&device->dev, "failed to read Intel Virtual Button driver\n");
+		return -ENODEV;
+	}
+
+	priv = devm_kzalloc(&device->dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+	dev_set_drvdata(&device->dev, priv);
+
+	err = intel_vbtn_input_setup(device);
+	if (err) {
+		pr_err("Failed to setup Intel Virtual Button\n");
+		return err;
+	}
+
+	status = acpi_install_notify_handler(handle,
+					     ACPI_DEVICE_NOTIFY,
+					     notify_handler,
+					     device);
+	if (ACPI_FAILURE(status)) {
+		err = -EBUSY;
+		goto err_remove_input;
+	}
+
+	return 0;
+
+err_remove_input:
+	intel_vbtn_input_destroy(device);
+
+	return err;
+}
+
+static int intel_vbtn_remove(struct platform_device *device)
+{
+	acpi_handle handle = ACPI_HANDLE(&device->dev);
+
+	intel_vbtn_input_destroy(device);
+	acpi_remove_notify_handler(handle, ACPI_DEVICE_NOTIFY, notify_handler);
+
+	/*
+	 * Even if we failed to shut off the event stream, we can still
+	 * safely detach from the device.
+	 */
+	return 0;
+}
+
+static struct platform_driver intel_vbtn_pl_driver = {
+	.driver = {
+		.name = "intel-vbtn",
+		.acpi_match_table = intel_vbtn_ids,
+	},
+	.probe = intel_vbtn_probe,
+	.remove = intel_vbtn_remove,
+};
+MODULE_DEVICE_TABLE(acpi, intel_vbtn_ids);
+
+static acpi_status __init
+check_acpi_dev(acpi_handle handle, u32 lvl, void *context, void **rv)
+{
+	const struct acpi_device_id *ids = context;
+	struct acpi_device *dev;
+
+	if (acpi_bus_get_device(handle, &dev) != 0)
+		return AE_OK;
+
+	if (acpi_match_device_ids(dev, ids) == 0)
+		if (acpi_create_platform_device(dev))
+			dev_info(&dev->dev,
+				 "intel-vbtn: created platform device\n");
+
+	return AE_OK;
+}
+
+static int __init intel_vbtn_init(void)
+{
+	acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
+			    ACPI_UINT32_MAX, check_acpi_dev, NULL,
+			    (void *)intel_vbtn_ids, NULL);
+
+	return platform_driver_register(&intel_vbtn_pl_driver);
+}
+module_init(intel_vbtn_init);
+
+static void __exit intel_vbtn_exit(void)
+{
+	platform_driver_unregister(&intel_vbtn_pl_driver);
+}
+module_exit(intel_vbtn_exit);
--- zfcpdump-kernel-4.4.orig/drivers/platform/x86/intel_ips.c
+++ zfcpdump-kernel-4.4/drivers/platform/x86/intel_ips.c
@@ -74,6 +74,7 @@
 #include <linux/timer.h>
 #include <linux/dmi.h>
 #include <drm/i915_drm.h>
+#include <drm/i915_drm_bpo.h>
 #include <asm/msr.h>
 #include <asm/processor.h>
 #include "intel_ips.h"
@@ -251,6 +252,9 @@
 static const int IPS_ADJUST_PERIOD = 5000; /* ms */
 static bool late_i915_load = false;
 
+int i915_bpo_enabled = 0;
+EXPORT_SYMBOL(i915_bpo_enabled);
+
 /* For initial average collection */
 static const int IPS_SAMPLE_PERIOD = 200; /* ms */
 static const int IPS_SAMPLE_WINDOW = 5000; /* 5s moving window of samples */
@@ -1421,8 +1425,43 @@ out:
  * enable graphics turbo, otherwise we must disable it to avoid exceeding
  * thermal and power limits in the MCP.
  */
+static bool ips_get_i915_bpo_syms(struct ips_driver *ips)
+{
+	ips->read_mch_val = symbol_get(i915_bpo_read_mch_val);
+	if (!ips->read_mch_val)
+		goto out_err;
+	ips->gpu_raise = symbol_get(i915_bpo_gpu_raise);
+	if (!ips->gpu_raise)
+		goto out_put_mch;
+	ips->gpu_lower = symbol_get(i915_bpo_gpu_lower);
+	if (!ips->gpu_lower)
+		goto out_put_raise;
+	ips->gpu_busy = symbol_get(i915_bpo_gpu_busy);
+	if (!ips->gpu_busy)
+		goto out_put_lower;
+	ips->gpu_turbo_disable = symbol_get(i915_bpo_gpu_turbo_disable);
+	if (!ips->gpu_turbo_disable)
+		goto out_put_busy;
+
+	return true;
+
+out_put_busy:
+	symbol_put(i915_bpo_gpu_busy);
+out_put_lower:
+	symbol_put(i915_bpo_gpu_lower);
+out_put_raise:
+	symbol_put(i915_bpo_gpu_raise);
+out_put_mch:
+	symbol_put(i915_bpo_read_mch_val);
+out_err:
+	return false;
+}
+
 static bool ips_get_i915_syms(struct ips_driver *ips)
 {
+	if (ips_get_i915_bpo_syms(ips) != false)
+		return true;
+
 	ips->read_mch_val = symbol_get(i915_read_mch_val);
 	if (!ips->read_mch_val)
 		goto out_err;
@@ -1501,6 +1540,14 @@ static const struct dmi_system_id ips_bl
 			DMI_MATCH(DMI_PRODUCT_NAME, "HP ProBook"),
 		},
 	},
+	{
+		.callback = ips_blacklist_callback,
+		.ident = "G60JX",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
+			DMI_MATCH(DMI_PRODUCT_NAME, "G60JX"),
+		},
+	},
 	{ }	/* terminating entry */
 };
 
--- zfcpdump-kernel-4.4.orig/drivers/platform/x86/intel_pmc_ipc.c
+++ zfcpdump-kernel-4.4/drivers/platform/x86/intel_pmc_ipc.c
@@ -68,8 +68,13 @@
 #define PLAT_RESOURCE_IPC_INDEX		0
 #define PLAT_RESOURCE_IPC_SIZE		0x1000
 #define PLAT_RESOURCE_GCR_SIZE		0x1000
-#define PLAT_RESOURCE_PUNIT_DATA_INDEX	1
-#define PLAT_RESOURCE_PUNIT_INTER_INDEX	2
+#define PLAT_RESOURCE_BIOS_DATA_INDEX	1
+#define PLAT_RESOURCE_BIOS_IFACE_INDEX	2
+#define PLAT_RESOURCE_TELEM_SSRAM_INDEX	3
+#define PLAT_RESOURCE_ISP_DATA_INDEX	4
+#define PLAT_RESOURCE_ISP_IFACE_INDEX	5
+#define PLAT_RESOURCE_GTD_DATA_INDEX	6
+#define PLAT_RESOURCE_GTD_IFACE_INDEX	7
 #define PLAT_RESOURCE_ACPI_IO_INDEX	0
 
 /*
@@ -84,6 +89,10 @@
 #define TCO_BASE_OFFSET			0x60
 #define TCO_REGS_SIZE			16
 #define PUNIT_DEVICE_NAME		"intel_punit_ipc"
+#define TELEMETRY_DEVICE_NAME		"intel_telemetry"
+#define TELEM_SSRAM_SIZE		240
+#define TELEM_PMC_SSRAM_OFFSET		0x1B00
+#define TELEM_PUNIT_SSRAM_OFFSET	0x1A00
 
 static const int iTCO_version = 3;
 
@@ -105,11 +114,15 @@ static struct intel_pmc_ipc_dev {
 	int gcr_size;
 
 	/* punit */
-	resource_size_t punit_base;
-	int punit_size;
-	resource_size_t punit_base2;
-	int punit_size2;
 	struct platform_device *punit_dev;
+
+	/* Telemetry */
+	resource_size_t telem_pmc_ssram_base;
+	resource_size_t telem_punit_ssram_base;
+	int telem_pmc_ssram_size;
+	int telem_punit_ssram_size;
+	u8 telem_res_inval;
+	struct platform_device *telemetry_dev;
 } ipcdev;
 
 static char *ipc_err_sources[] = {
@@ -444,9 +457,22 @@ static const struct attribute_group inte
 	.attrs = intel_ipc_attrs,
 };
 
-#define PUNIT_RESOURCE_INTER		1
-static struct resource punit_res[] = {
-	/* Punit */
+static struct resource punit_res_array[] = {
+	/* Punit BIOS */
+	{
+		.flags = IORESOURCE_MEM,
+	},
+	{
+		.flags = IORESOURCE_MEM,
+	},
+	/* Punit ISP */
+	{
+		.flags = IORESOURCE_MEM,
+	},
+	{
+		.flags = IORESOURCE_MEM,
+	},
+	/* Punit GTD */
 	{
 		.flags = IORESOURCE_MEM,
 	},
@@ -478,10 +504,21 @@ static struct itco_wdt_platform_data tco
 	.version = 3,
 };
 
+#define TELEMETRY_RESOURCE_PUNIT_SSRAM	0
+#define TELEMETRY_RESOURCE_PMC_SSRAM	1
+static struct resource telemetry_res[] = {
+	/*Telemetry*/
+	{
+		.flags = IORESOURCE_MEM,
+	},
+	{
+		.flags = IORESOURCE_MEM,
+	},
+};
+
 static int ipc_create_punit_device(void)
 {
 	struct platform_device *pdev;
-	struct resource *res;
 	int ret;
 
 	pdev = platform_device_alloc(PUNIT_DEVICE_NAME, -1);
@@ -491,17 +528,8 @@ static int ipc_create_punit_device(void)
 	}
 
 	pdev->dev.parent = ipcdev.dev;
-
-	res = punit_res;
-	res->start = ipcdev.punit_base;
-	res->end = res->start + ipcdev.punit_size - 1;
-
-	res = punit_res + PUNIT_RESOURCE_INTER;
-	res->start = ipcdev.punit_base2;
-	res->end = res->start + ipcdev.punit_size2 - 1;
-
-	ret = platform_device_add_resources(pdev, punit_res,
-					    ARRAY_SIZE(punit_res));
+	ret = platform_device_add_resources(pdev, punit_res_array,
+					    ARRAY_SIZE(punit_res_array));
 	if (ret) {
 		dev_err(ipcdev.dev, "Failed to add platform punit resources\n");
 		goto err;
@@ -571,6 +599,51 @@ err:
 	return ret;
 }
 
+static int ipc_create_telemetry_device(void)
+{
+	struct platform_device *pdev;
+	struct resource *res;
+	int ret;
+
+	pdev = platform_device_alloc(TELEMETRY_DEVICE_NAME, -1);
+	if (!pdev) {
+		dev_err(ipcdev.dev,
+			"Failed to allocate telemetry platform device\n");
+		return -ENOMEM;
+	}
+
+	pdev->dev.parent = ipcdev.dev;
+
+	res = telemetry_res + TELEMETRY_RESOURCE_PUNIT_SSRAM;
+	res->start = ipcdev.telem_punit_ssram_base;
+	res->end = res->start + ipcdev.telem_punit_ssram_size - 1;
+
+	res = telemetry_res + TELEMETRY_RESOURCE_PMC_SSRAM;
+	res->start = ipcdev.telem_pmc_ssram_base;
+	res->end = res->start + ipcdev.telem_pmc_ssram_size - 1;
+
+	ret = platform_device_add_resources(pdev, telemetry_res,
+					    ARRAY_SIZE(telemetry_res));
+	if (ret) {
+		dev_err(ipcdev.dev,
+			"Failed to add telemetry platform resources\n");
+		goto err;
+	}
+
+	ret = platform_device_add(pdev);
+	if (ret) {
+		dev_err(ipcdev.dev,
+			"Failed to add telemetry platform device\n");
+		goto err;
+	}
+	ipcdev.telemetry_dev = pdev;
+
+	return 0;
+err:
+	platform_device_put(pdev);
+	return ret;
+}
+
 static int ipc_create_pmc_devices(void)
 {
 	int ret;
@@ -585,12 +658,20 @@ static int ipc_create_pmc_devices(void)
 		dev_err(ipcdev.dev, "Failed to add punit platform device\n");
 		platform_device_unregister(ipcdev.tco_dev);
 	}
+
+	if (!ipcdev.telem_res_inval) {
+		ret = ipc_create_telemetry_device();
+		if (ret)
+			dev_warn(ipcdev.dev,
+				"Failed to add telemetry platform device\n");
+	}
+
 	return ret;
 }
 
 static int ipc_plat_get_res(struct platform_device *pdev)
 {
-	struct resource *res;
+	struct resource *res, *punit_res;
 	void __iomem *addr;
 	int size;
 
@@ -603,32 +684,68 @@ static int ipc_plat_get_res(struct platf
 	size = resource_size(res);
 	ipcdev.acpi_io_base = res->start;
 	ipcdev.acpi_io_size = size;
-	dev_info(&pdev->dev, "io res: %llx %x\n",
-		 (long long)res->start, (int)resource_size(res));
+	dev_info(&pdev->dev, "io res: %pR\n", res);
 
+	/* This is index 0 to cover BIOS data register */
+	punit_res = punit_res_array;
 	res = platform_get_resource(pdev, IORESOURCE_MEM,
-				    PLAT_RESOURCE_PUNIT_DATA_INDEX);
+				    PLAT_RESOURCE_BIOS_DATA_INDEX);
 	if (!res) {
-		dev_err(&pdev->dev, "Failed to get punit resource\n");
+		dev_err(&pdev->dev, "Failed to get res of punit BIOS data\n");
 		return -ENXIO;
 	}
-	size = resource_size(res);
-	ipcdev.punit_base = res->start;
-	ipcdev.punit_size = size;
-	dev_info(&pdev->dev, "punit data res: %llx %x\n",
-		 (long long)res->start, (int)resource_size(res));
+	*punit_res = *res;
+	dev_info(&pdev->dev, "punit BIOS data res: %pR\n", res);
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM,
-				    PLAT_RESOURCE_PUNIT_INTER_INDEX);
+				    PLAT_RESOURCE_BIOS_IFACE_INDEX);
 	if (!res) {
-		dev_err(&pdev->dev, "Failed to get punit inter resource\n");
+		dev_err(&pdev->dev, "Failed to get res of punit BIOS iface\n");
 		return -ENXIO;
 	}
-	size = resource_size(res);
-	ipcdev.punit_base2 = res->start;
-	ipcdev.punit_size2 = size;
-	dev_info(&pdev->dev, "punit interface res: %llx %x\n",
-		 (long long)res->start, (int)resource_size(res));
+	/* This is index 1 to cover BIOS interface register */
+	*++punit_res = *res;
+	dev_info(&pdev->dev, "punit BIOS interface res: %pR\n", res);
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM,
+				    PLAT_RESOURCE_ISP_DATA_INDEX);
+	if (!res) {
+		dev_err(&pdev->dev, "Failed to get res of punit ISP data\n");
+		return -ENXIO;
+	}
+	/* This is index 2 to cover ISP data register */
+	*++punit_res = *res;
+	dev_info(&pdev->dev, "punit ISP data res: %pR\n", res);
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM,
+				    PLAT_RESOURCE_ISP_IFACE_INDEX);
+	if (!res) {
+		dev_err(&pdev->dev, "Failed to get res of punit ISP iface\n");
+		return -ENXIO;
+	}
+	/* This is index 3 to cover ISP interface register */
+	*++punit_res = *res;
+	dev_info(&pdev->dev, "punit ISP interface res: %pR\n", res);
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM,
+				    PLAT_RESOURCE_GTD_DATA_INDEX);
+	if (!res) {
+		dev_err(&pdev->dev, "Failed to get res of punit GTD data\n");
+		return -ENXIO;
+	}
+	/* This is index 4 to cover GTD data register */
+	*++punit_res = *res;
+	dev_info(&pdev->dev, "punit GTD data res: %pR\n", res);
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM,
+				    PLAT_RESOURCE_GTD_IFACE_INDEX);
+	if (!res) {
+		dev_err(&pdev->dev, "Failed to get res of punit GTD iface\n");
+		return -ENXIO;
+	}
+	/* This is index 5 to cover GTD interface register */
+	*++punit_res = *res;
+	dev_info(&pdev->dev, "punit GTD interface res: %pR\n", res);
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM,
 				    PLAT_RESOURCE_IPC_INDEX);
@@ -651,8 +768,23 @@ static int ipc_plat_get_res(struct platf
 
 	ipcdev.gcr_base = res->start + size;
 	ipcdev.gcr_size = PLAT_RESOURCE_GCR_SIZE;
-	dev_info(&pdev->dev, "ipc res: %llx %x\n",
-		 (long long)res->start, (int)resource_size(res));
+	dev_info(&pdev->dev, "ipc res: %pR\n", res);
+
+	ipcdev.telem_res_inval = 0;
+	res = platform_get_resource(pdev, IORESOURCE_MEM,
+				    PLAT_RESOURCE_TELEM_SSRAM_INDEX);
+	if (!res) {
+		dev_err(&pdev->dev, "Failed to get telemetry ssram resource\n");
+		ipcdev.telem_res_inval = 1;
+	} else {
+		ipcdev.telem_punit_ssram_base = res->start +
+						TELEM_PUNIT_SSRAM_OFFSET;
+		ipcdev.telem_punit_ssram_size = TELEM_SSRAM_SIZE;
+		ipcdev.telem_pmc_ssram_base = res->start +
+						TELEM_PMC_SSRAM_OFFSET;
+		ipcdev.telem_pmc_ssram_size = TELEM_SSRAM_SIZE;
+		dev_info(&pdev->dev, "telemetry ssram res: %pR\n", res);
+	}
 
 	return 0;
 }
@@ -711,6 +843,7 @@ err_sys:
 err_irq:
 	platform_device_unregister(ipcdev.tco_dev);
 	platform_device_unregister(ipcdev.punit_dev);
+	platform_device_unregister(ipcdev.telemetry_dev);
 err_device:
 	iounmap(ipcdev.ipc_base);
 	res = platform_get_resource(pdev, IORESOURCE_MEM,
@@ -728,6 +861,7 @@ static int ipc_plat_remove(struct platfo
 	free_irq(ipcdev.irq, &ipcdev);
 	platform_device_unregister(ipcdev.tco_dev);
 	platform_device_unregister(ipcdev.punit_dev);
+	platform_device_unregister(ipcdev.telemetry_dev);
 	iounmap(ipcdev.ipc_base);
 	res = platform_get_resource(pdev, IORESOURCE_MEM,
 				    PLAT_RESOURCE_IPC_INDEX);
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/platform/x86/intel_punit_ipc.c
@@ -0,0 +1,342 @@
+/*
+ * Driver for the Intel P-Unit Mailbox IPC mechanism
+ *
+ * (C) Copyright 2015 Intel Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * The heart of the P-Unit is the Foxton microcontroller and its firmware,
+ * which provide mailbox interface for power management usage.
+ */
+
+#include <linux/module.h>
+#include <linux/acpi.h>
+#include <linux/delay.h>
+#include <linux/bitops.h>
+#include <linux/device.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <asm/intel_punit_ipc.h>
+
+/* IPC Mailbox registers */
+#define OFFSET_DATA_LOW		0x0
+#define OFFSET_DATA_HIGH	0x4
+/* bit field of interface register */
+#define	CMD_RUN			BIT(31)
+#define	CMD_ERRCODE_MASK	GENMASK(7, 0)
+#define	CMD_PARA1_SHIFT		8
+#define	CMD_PARA2_SHIFT		16
+
+#define CMD_TIMEOUT_SECONDS	1
+
+enum {
+	BASE_DATA = 0,
+	BASE_IFACE,
+	BASE_MAX,
+};
+
+typedef struct {
+	struct device *dev;
+	struct mutex lock;
+	int irq;
+	struct completion cmd_complete;
+	/* base of interface and data registers */
+	void __iomem *base[RESERVED_IPC][BASE_MAX];
+	IPC_TYPE type;
+} IPC_DEV;
+
+static IPC_DEV *punit_ipcdev;
+
+static inline u32 ipc_read_status(IPC_DEV *ipcdev, IPC_TYPE type)
+{
+	return readl(ipcdev->base[type][BASE_IFACE]);
+}
+
+static inline void ipc_write_cmd(IPC_DEV *ipcdev, IPC_TYPE type, u32 cmd)
+{
+	writel(cmd, ipcdev->base[type][BASE_IFACE]);
+}
+
+static inline u32 ipc_read_data_low(IPC_DEV *ipcdev, IPC_TYPE type)
+{
+	return readl(ipcdev->base[type][BASE_DATA] + OFFSET_DATA_LOW);
+}
+
+static inline u32 ipc_read_data_high(IPC_DEV *ipcdev, IPC_TYPE type)
+{
+	return readl(ipcdev->base[type][BASE_DATA] + OFFSET_DATA_HIGH);
+}
+
+static inline void ipc_write_data_low(IPC_DEV *ipcdev, IPC_TYPE type, u32 data)
+{
+	writel(data, ipcdev->base[type][BASE_DATA] + OFFSET_DATA_LOW);
+}
+
+static inline void ipc_write_data_high(IPC_DEV *ipcdev, IPC_TYPE type, u32 data)
+{
+	writel(data, ipcdev->base[type][BASE_DATA] + OFFSET_DATA_HIGH);
+}
+
+static const char *ipc_err_string(int error)
+{
+	if (error == IPC_PUNIT_ERR_SUCCESS)
+		return "no error";
+	else if (error == IPC_PUNIT_ERR_INVALID_CMD)
+		return "invalid command";
+	else if (error == IPC_PUNIT_ERR_INVALID_PARAMETER)
+		return "invalid parameter";
+	else if (error == IPC_PUNIT_ERR_CMD_TIMEOUT)
+		return "command timeout";
+	else if (error == IPC_PUNIT_ERR_CMD_LOCKED)
+		return "command locked";
+	else if (error == IPC_PUNIT_ERR_INVALID_VR_ID)
+		return "invalid vr id";
+	else if (error == IPC_PUNIT_ERR_VR_ERR)
+		return "vr error";
+	else
+		return "unknown error";
+}
+
+static int intel_punit_ipc_check_status(IPC_DEV *ipcdev, IPC_TYPE type)
+{
+	int loops = CMD_TIMEOUT_SECONDS * USEC_PER_SEC;
+	int errcode;
+	int status;
+
+	if (ipcdev->irq) {
+		if (!wait_for_completion_timeout(&ipcdev->cmd_complete,
+						 CMD_TIMEOUT_SECONDS * HZ)) {
+			dev_err(ipcdev->dev, "IPC timed out\n");
+			return -ETIMEDOUT;
+		}
+	} else {
+		while ((ipc_read_status(ipcdev, type) & CMD_RUN) && --loops)
+			udelay(1);
+		if (!loops) {
+			dev_err(ipcdev->dev, "IPC timed out\n");
+			return -ETIMEDOUT;
+		}
+	}
+
+	status = ipc_read_status(ipcdev, type);
+	errcode = status & CMD_ERRCODE_MASK;
+	if (errcode) {
+		dev_err(ipcdev->dev, "IPC failed: %s, IPC_STS=0x%x\n",
+			ipc_err_string(errcode), status);
+		return -EIO;
+	}
+
+	return 0;
+}
+
+/**
+ * intel_punit_ipc_simple_command() - Simple IPC command
+ * @cmd:	IPC command code.
+ * @para1:	First 8bit parameter, set 0 if not used.
+ * @para2:	Second 8bit parameter, set 0 if not used.
+ *
+ * Send a IPC command to P-Unit when there is no data transaction
+ *
+ * Return:	IPC error code or 0 on success.
+ */
+int intel_punit_ipc_simple_command(int cmd, int para1, int para2)
+{
+	IPC_DEV *ipcdev = punit_ipcdev;
+	IPC_TYPE type;
+	u32 val;
+	int ret;
+
+	mutex_lock(&ipcdev->lock);
+
+	reinit_completion(&ipcdev->cmd_complete);
+	type = (cmd & IPC_PUNIT_CMD_TYPE_MASK) >> IPC_TYPE_OFFSET;
+
+	val = cmd & ~IPC_PUNIT_CMD_TYPE_MASK;
+	val |= CMD_RUN | para2 << CMD_PARA2_SHIFT | para1 << CMD_PARA1_SHIFT;
+	ipc_write_cmd(ipcdev, type, val);
+	ret = intel_punit_ipc_check_status(ipcdev, type);
+
+	mutex_unlock(&ipcdev->lock);
+
+	return ret;
+}
+EXPORT_SYMBOL(intel_punit_ipc_simple_command);
+
+/**
+ * intel_punit_ipc_command() - IPC command with data and pointers
+ * @cmd:	IPC command code.
+ * @para1:	First 8bit parameter, set 0 if not used.
+ * @para2:	Second 8bit parameter, set 0 if not used.
+ * @in:		Input data, 32bit for BIOS cmd, two 32bit for GTD and ISPD.
+ * @out:	Output data.
+ *
+ * Send a IPC command to P-Unit with data transaction
+ *
+ * Return:	IPC error code or 0 on success.
+ */
+int intel_punit_ipc_command(u32 cmd, u32 para1, u32 para2, u32 *in, u32 *out)
+{
+	IPC_DEV *ipcdev = punit_ipcdev;
+	IPC_TYPE type;
+	u32 val;
+	int ret;
+
+	mutex_lock(&ipcdev->lock);
+
+	reinit_completion(&ipcdev->cmd_complete);
+	type = (cmd & IPC_PUNIT_CMD_TYPE_MASK) >> IPC_TYPE_OFFSET;
+
+	if (in) {
+		ipc_write_data_low(ipcdev, type, *in);
+		if (type == GTDRIVER_IPC || type == ISPDRIVER_IPC)
+			ipc_write_data_high(ipcdev, type, *++in);
+	}
+
+	val = cmd & ~IPC_PUNIT_CMD_TYPE_MASK;
+	val |= CMD_RUN | para2 << CMD_PARA2_SHIFT | para1 << CMD_PARA1_SHIFT;
+	ipc_write_cmd(ipcdev, type, val);
+
+	ret = intel_punit_ipc_check_status(ipcdev, type);
+	if (ret)
+		goto out;
+
+	if (out) {
+		*out = ipc_read_data_low(ipcdev, type);
+		if (type == GTDRIVER_IPC || type == ISPDRIVER_IPC)
+			*++out = ipc_read_data_high(ipcdev, type);
+	}
+
+out:
+	mutex_unlock(&ipcdev->lock);
+	return ret;
+}
+EXPORT_SYMBOL_GPL(intel_punit_ipc_command);
+
+static irqreturn_t intel_punit_ioc(int irq, void *dev_id)
+{
+	IPC_DEV *ipcdev = dev_id;
+
+	complete(&ipcdev->cmd_complete);
+	return IRQ_HANDLED;
+}
+
+static int intel_punit_get_bars(struct platform_device *pdev)
+{
+	struct resource *res;
+	void __iomem *addr;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	addr = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(addr))
+		return PTR_ERR(addr);
+	punit_ipcdev->base[BIOS_IPC][BASE_DATA] = addr;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+	addr = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(addr))
+		return PTR_ERR(addr);
+	punit_ipcdev->base[BIOS_IPC][BASE_IFACE] = addr;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 2);
+	addr = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(addr))
+		return PTR_ERR(addr);
+	punit_ipcdev->base[ISPDRIVER_IPC][BASE_DATA] = addr;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 3);
+	addr = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(addr))
+		return PTR_ERR(addr);
+	punit_ipcdev->base[ISPDRIVER_IPC][BASE_IFACE] = addr;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 4);
+	addr = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(addr))
+		return PTR_ERR(addr);
+	punit_ipcdev->base[GTDRIVER_IPC][BASE_DATA] = addr;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 5);
+	addr = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(addr))
+		return PTR_ERR(addr);
+	punit_ipcdev->base[GTDRIVER_IPC][BASE_IFACE] = addr;
+
+	return 0;
+}
+
+static int intel_punit_ipc_probe(struct platform_device *pdev)
+{
+	int irq, ret;
+
+	punit_ipcdev = devm_kzalloc(&pdev->dev,
+				    sizeof(*punit_ipcdev), GFP_KERNEL);
+	if (!punit_ipcdev)
+		return -ENOMEM;
+
+	platform_set_drvdata(pdev, punit_ipcdev);
+
+	irq = platform_get_irq(pdev, 0);
+	if (irq < 0) {
+		punit_ipcdev->irq = 0;
+		dev_warn(&pdev->dev, "Invalid IRQ, using polling mode\n");
+	} else {
+		ret = devm_request_irq(&pdev->dev, irq, intel_punit_ioc,
+				       IRQF_NO_SUSPEND, "intel_punit_ipc",
+				       &punit_ipcdev);
+		if (ret) {
+			dev_err(&pdev->dev, "Failed to request irq: %d\n", irq);
+			return ret;
+		}
+		punit_ipcdev->irq = irq;
+	}
+
+	ret = intel_punit_get_bars(pdev);
+	if (ret)
+		goto out;
+
+	punit_ipcdev->dev = &pdev->dev;
+	mutex_init(&punit_ipcdev->lock);
+	init_completion(&punit_ipcdev->cmd_complete);
+
+out:
+	return ret;
+}
+
+static int intel_punit_ipc_remove(struct platform_device *pdev)
+{
+	return 0;
+}
+
+static const struct acpi_device_id punit_ipc_acpi_ids[] = {
+	{ "INT34D4", 0 },
+	{ }
+};
+
+static struct platform_driver intel_punit_ipc_driver = {
+	.probe = intel_punit_ipc_probe,
+	.remove = intel_punit_ipc_remove,
+	.driver = {
+		.name = "intel_punit_ipc",
+		.acpi_match_table = ACPI_PTR(punit_ipc_acpi_ids),
+	},
+};
+
+static int __init intel_punit_ipc_init(void)
+{
+	return platform_driver_register(&intel_punit_ipc_driver);
+}
+
+static void __exit intel_punit_ipc_exit(void)
+{
+	platform_driver_unregister(&intel_punit_ipc_driver);
+}
+
+MODULE_AUTHOR("Zha Qipeng <qipeng.zha@intel.com>");
+MODULE_DESCRIPTION("Intel P-Unit IPC driver");
+MODULE_LICENSE("GPL v2");
+
+/* Some modules are dependent on this, so init earlier */
+fs_initcall(intel_punit_ipc_init);
+module_exit(intel_punit_ipc_exit);
--- zfcpdump-kernel-4.4.orig/drivers/platform/x86/intel_scu_ipcutil.c
+++ zfcpdump-kernel-4.4/drivers/platform/x86/intel_scu_ipcutil.c
@@ -49,7 +49,7 @@ struct scu_ipc_data {
 
 static int scu_reg_access(u32 cmd, struct scu_ipc_data  *data)
 {
-	int count = data->count;
+	unsigned int count = data->count;
 
 	if (count == 0 || count == 3 || count > 4)
 		return -EINVAL;
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/platform/x86/intel_telemetry_core.c
@@ -0,0 +1,464 @@
+/*
+ * Intel SoC Core Telemetry Driver
+ * Copyright (C) 2015, Intel Corporation.
+ * All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * Telemetry Framework provides platform related PM and performance statistics.
+ * This file provides the core telemetry API implementation.
+ */
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/device.h>
+
+#include <asm/intel_telemetry.h>
+
+#define DRIVER_NAME "intel_telemetry_core"
+
+struct telemetry_core_config {
+	struct telemetry_plt_config *plt_config;
+	struct telemetry_core_ops *telem_ops;
+};
+
+static struct telemetry_core_config telm_core_conf;
+
+static int telemetry_def_update_events(struct telemetry_evtconfig pss_evtconfig,
+				      struct telemetry_evtconfig ioss_evtconfig)
+{
+	return 0;
+}
+
+static int telemetry_def_set_sampling_period(u8 pss_period, u8 ioss_period)
+{
+	return 0;
+}
+
+static int telemetry_def_get_sampling_period(u8 *pss_min_period,
+					     u8 *pss_max_period,
+					     u8 *ioss_min_period,
+					     u8 *ioss_max_period)
+{
+	return 0;
+}
+
+static int telemetry_def_get_eventconfig(
+			struct telemetry_evtconfig *pss_evtconfig,
+			struct telemetry_evtconfig *ioss_evtconfig,
+			int pss_len, int ioss_len)
+{
+	return 0;
+}
+
+static int telemetry_def_get_trace_verbosity(enum telemetry_unit telem_unit,
+					     u32 *verbosity)
+{
+	return 0;
+}
+
+
+static int telemetry_def_set_trace_verbosity(enum telemetry_unit telem_unit,
+					     u32 verbosity)
+{
+	return 0;
+}
+
+static int telemetry_def_raw_read_eventlog(enum telemetry_unit telem_unit,
+					   struct telemetry_evtlog *evtlog,
+					   int len, int log_all_evts)
+{
+	return 0;
+}
+
+static int telemetry_def_read_eventlog(enum telemetry_unit telem_unit,
+				       struct telemetry_evtlog *evtlog,
+				       int len, int log_all_evts)
+{
+	return 0;
+}
+
+static int telemetry_def_add_events(u8 num_pss_evts, u8 num_ioss_evts,
+				    u32 *pss_evtmap, u32 *ioss_evtmap)
+{
+	return 0;
+}
+
+static int telemetry_def_reset_events(void)
+{
+	return 0;
+}
+
+static struct telemetry_core_ops telm_defpltops = {
+	.set_sampling_period = telemetry_def_set_sampling_period,
+	.get_sampling_period = telemetry_def_get_sampling_period,
+	.get_trace_verbosity = telemetry_def_get_trace_verbosity,
+	.set_trace_verbosity = telemetry_def_set_trace_verbosity,
+	.raw_read_eventlog = telemetry_def_raw_read_eventlog,
+	.get_eventconfig = telemetry_def_get_eventconfig,
+	.read_eventlog = telemetry_def_read_eventlog,
+	.update_events = telemetry_def_update_events,
+	.reset_events = telemetry_def_reset_events,
+	.add_events = telemetry_def_add_events,
+};
+
+/**
+ * telemetry_update_events() - Update telemetry Configuration
+ * @pss_evtconfig: PSS related config. No change if num_evts = 0.
+ * @pss_evtconfig: IOSS related config. No change if num_evts = 0.
+ *
+ * This API updates the IOSS & PSS Telemetry configuration. Old config
+ * is overwritten. Call telemetry_reset_events when logging is over
+ * All sample period values should be in the form of:
+ * bits[6:3] -> value; bits [0:2]-> Exponent; Period = (Value *16^Exponent)
+ *
+ * Return: 0 success, < 0 for failure
+ */
+int telemetry_update_events(struct telemetry_evtconfig pss_evtconfig,
+			    struct telemetry_evtconfig ioss_evtconfig)
+{
+	return telm_core_conf.telem_ops->update_events(pss_evtconfig,
+						       ioss_evtconfig);
+}
+EXPORT_SYMBOL_GPL(telemetry_update_events);
+
+
+/**
+ * telemetry_set_sampling_period() - Sets the IOSS & PSS sampling period
+ * @pss_period:  placeholder for PSS Period to be set.
+ *		 Set to 0 if not required to be updated
+ * @ioss_period: placeholder for IOSS Period to be set
+ *		 Set to 0 if not required to be updated
+ *
+ * All values should be in the form of:
+ * bits[6:3] -> value; bits [0:2]-> Exponent; Period = (Value *16^Exponent)
+ *
+ * Return: 0 success, < 0 for failure
+ */
+int telemetry_set_sampling_period(u8 pss_period, u8 ioss_period)
+{
+	return telm_core_conf.telem_ops->set_sampling_period(pss_period,
+							     ioss_period);
+}
+EXPORT_SYMBOL_GPL(telemetry_set_sampling_period);
+
+/**
+ * telemetry_get_sampling_period() - Get IOSS & PSS min & max sampling period
+ * @pss_min_period:  placeholder for PSS Min Period supported
+ * @pss_max_period:  placeholder for PSS Max Period supported
+ * @ioss_min_period: placeholder for IOSS Min Period supported
+ * @ioss_max_period: placeholder for IOSS Max Period supported
+ *
+ * All values should be in the form of:
+ * bits[6:3] -> value; bits [0:2]-> Exponent; Period = (Value *16^Exponent)
+ *
+ * Return: 0 success, < 0 for failure
+ */
+int telemetry_get_sampling_period(u8 *pss_min_period, u8 *pss_max_period,
+				  u8 *ioss_min_period, u8 *ioss_max_period)
+{
+	return telm_core_conf.telem_ops->get_sampling_period(pss_min_period,
+							     pss_max_period,
+							     ioss_min_period,
+							     ioss_max_period);
+}
+EXPORT_SYMBOL_GPL(telemetry_get_sampling_period);
+
+
+/**
+ * telemetry_reset_events() - Restore the IOSS & PSS configuration to default
+ *
+ * Return: 0 success, < 0 for failure
+ */
+int telemetry_reset_events(void)
+{
+	return telm_core_conf.telem_ops->reset_events();
+}
+EXPORT_SYMBOL_GPL(telemetry_reset_events);
+
+/**
+ * telemetry_get_eventconfig() - Returns the pss and ioss events enabled
+ * @pss_evtconfig: Pointer to PSS related configuration.
+ * @pss_evtconfig: Pointer to IOSS related configuration.
+ * @pss_len:	   Number of u32 elements allocated for pss_evtconfig array
+ * @ioss_len:	   Number of u32 elements allocated for ioss_evtconfig array
+ *
+ * Return: 0 success, < 0 for failure
+ */
+int telemetry_get_eventconfig(struct telemetry_evtconfig *pss_evtconfig,
+			      struct telemetry_evtconfig *ioss_evtconfig,
+			      int pss_len, int ioss_len)
+{
+	return telm_core_conf.telem_ops->get_eventconfig(pss_evtconfig,
+							 ioss_evtconfig,
+							 pss_len, ioss_len);
+}
+EXPORT_SYMBOL_GPL(telemetry_get_eventconfig);
+
+/**
+ * telemetry_add_events() - Add IOSS & PSS configuration to existing settings.
+ * @num_pss_evts:  Number of PSS Events (<29) in pss_evtmap. Can be 0.
+ * @num_ioss_evts: Number of IOSS Events (<29) in ioss_evtmap. Can be 0.
+ * @pss_evtmap:    Array of PSS Event-IDs to Enable
+ * @ioss_evtmap:   Array of PSS Event-IDs to Enable
+ *
+ * Events are appended to Old Configuration. In case of total events > 28, it
+ * returns error. Call telemetry_reset_events to reset after eventlog done
+ *
+ * Return: 0 success, < 0 for failure
+ */
+int telemetry_add_events(u8 num_pss_evts, u8 num_ioss_evts,
+			 u32 *pss_evtmap, u32 *ioss_evtmap)
+{
+	return telm_core_conf.telem_ops->add_events(num_pss_evts,
+						    num_ioss_evts, pss_evtmap,
+						    ioss_evtmap);
+}
+EXPORT_SYMBOL_GPL(telemetry_add_events);
+
+/**
+ * telemetry_read_events() - Fetches samples as specified by evtlog.telem_evt_id
+ * @telem_unit: Specify whether IOSS or PSS Read
+ * @evtlog:     Array of telemetry_evtlog structs to fill data
+ *		evtlog.telem_evt_id specifies the ids to read
+ * @len:	Length of array of evtlog
+ *
+ * Return: number of eventlogs read for success, < 0 for failure
+ */
+int telemetry_read_events(enum telemetry_unit telem_unit,
+			  struct telemetry_evtlog *evtlog, int len)
+{
+	return telm_core_conf.telem_ops->read_eventlog(telem_unit, evtlog,
+						       len, 0);
+}
+EXPORT_SYMBOL_GPL(telemetry_read_events);
+
+/**
+ * telemetry_raw_read_events() - Fetch samples specified by evtlog.telem_evt_id
+ * @telem_unit: Specify whether IOSS or PSS Read
+ * @evtlog:	Array of telemetry_evtlog structs to fill data
+ *		evtlog.telem_evt_id specifies the ids to read
+ * @len:	Length of array of evtlog
+ *
+ * The caller must take care of locking in this case.
+ *
+ * Return: number of eventlogs read for success, < 0 for failure
+ */
+int telemetry_raw_read_events(enum telemetry_unit telem_unit,
+			      struct telemetry_evtlog *evtlog, int len)
+{
+	return telm_core_conf.telem_ops->raw_read_eventlog(telem_unit, evtlog,
+							   len, 0);
+}
+EXPORT_SYMBOL_GPL(telemetry_raw_read_events);
+
+/**
+ * telemetry_read_eventlog() - Fetch the Telemetry log from PSS or IOSS
+ * @telem_unit: Specify whether IOSS or PSS Read
+ * @evtlog:	Array of telemetry_evtlog structs to fill data
+ * @len:	Length of array of evtlog
+ *
+ * Return: number of eventlogs read for success, < 0 for failure
+ */
+int telemetry_read_eventlog(enum telemetry_unit telem_unit,
+			    struct telemetry_evtlog *evtlog, int len)
+{
+	return telm_core_conf.telem_ops->read_eventlog(telem_unit, evtlog,
+						       len, 1);
+}
+EXPORT_SYMBOL_GPL(telemetry_read_eventlog);
+
+/**
+ * telemetry_raw_read_eventlog() - Fetch the Telemetry log from PSS or IOSS
+ * @telem_unit: Specify whether IOSS or PSS Read
+ * @evtlog:	Array of telemetry_evtlog structs to fill data
+ * @len:	Length of array of evtlog
+ *
+ * The caller must take care of locking in this case.
+ *
+ * Return: number of eventlogs read for success, < 0 for failure
+ */
+int telemetry_raw_read_eventlog(enum telemetry_unit telem_unit,
+				struct telemetry_evtlog *evtlog, int len)
+{
+	return telm_core_conf.telem_ops->raw_read_eventlog(telem_unit, evtlog,
+							   len, 1);
+}
+EXPORT_SYMBOL_GPL(telemetry_raw_read_eventlog);
+
+
+/**
+ * telemetry_get_trace_verbosity() - Get the IOSS & PSS Trace verbosity
+ * @telem_unit: Specify whether IOSS or PSS Read
+ * @verbosity:	Pointer to return Verbosity
+ *
+ * Return: 0 success, < 0 for failure
+ */
+int telemetry_get_trace_verbosity(enum telemetry_unit telem_unit,
+				  u32 *verbosity)
+{
+	return telm_core_conf.telem_ops->get_trace_verbosity(telem_unit,
+							     verbosity);
+}
+EXPORT_SYMBOL_GPL(telemetry_get_trace_verbosity);
+
+
+/**
+ * telemetry_set_trace_verbosity() - Update the IOSS & PSS Trace verbosity
+ * @telem_unit: Specify whether IOSS or PSS Read
+ * @verbosity:	Verbosity to set
+ *
+ * Return: 0 success, < 0 for failure
+ */
+int telemetry_set_trace_verbosity(enum telemetry_unit telem_unit, u32 verbosity)
+{
+	return telm_core_conf.telem_ops->set_trace_verbosity(telem_unit,
+							     verbosity);
+}
+EXPORT_SYMBOL_GPL(telemetry_set_trace_verbosity);
+
+/**
+ * telemetry_set_pltdata() - Set the platform specific Data
+ * @ops:	Pointer to ops structure
+ * @pltconfig:	Platform config data
+ *
+ * Usage by other than telemetry pltdrv module is invalid
+ *
+ * Return: 0 success, < 0 for failure
+ */
+int telemetry_set_pltdata(struct telemetry_core_ops *ops,
+			  struct telemetry_plt_config *pltconfig)
+{
+	if (ops)
+		telm_core_conf.telem_ops = ops;
+
+	if (pltconfig)
+		telm_core_conf.plt_config = pltconfig;
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(telemetry_set_pltdata);
+
+/**
+ * telemetry_clear_pltdata() - Clear the platform specific Data
+ *
+ * Usage by other than telemetry pltdrv module is invalid
+ *
+ * Return: 0 success, < 0 for failure
+ */
+int telemetry_clear_pltdata(void)
+{
+	telm_core_conf.telem_ops = &telm_defpltops;
+	telm_core_conf.plt_config = NULL;
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(telemetry_clear_pltdata);
+
+/**
+ * telemetry_pltconfig_valid() - Checkif platform config is valid
+ *
+ * Usage by other than telemetry module is invalid
+ *
+ * Return: 0 success, < 0 for failure
+ */
+int telemetry_pltconfig_valid(void)
+{
+	if (telm_core_conf.plt_config)
+		return 0;
+
+	else
+		return -EINVAL;
+}
+EXPORT_SYMBOL_GPL(telemetry_pltconfig_valid);
+
+static inline int telemetry_get_pssevtname(enum telemetry_unit telem_unit,
+					   const char **name, int len)
+{
+	struct telemetry_unit_config psscfg;
+	int i;
+
+	if (!telm_core_conf.plt_config)
+		return -EINVAL;
+
+	psscfg = telm_core_conf.plt_config->pss_config;
+
+	if (len > psscfg.ssram_evts_used)
+		len = psscfg.ssram_evts_used;
+
+	for (i = 0; i < len; i++)
+		name[i] = psscfg.telem_evts[i].name;
+
+	return 0;
+}
+
+static inline int telemetry_get_iossevtname(enum telemetry_unit telem_unit,
+					    const char **name, int len)
+{
+	struct telemetry_unit_config iosscfg;
+	int i;
+
+	if (!(telm_core_conf.plt_config))
+		return -EINVAL;
+
+	iosscfg = telm_core_conf.plt_config->ioss_config;
+
+	if (len > iosscfg.ssram_evts_used)
+		len = iosscfg.ssram_evts_used;
+
+	for (i = 0; i < len; i++)
+		name[i] = iosscfg.telem_evts[i].name;
+
+	return 0;
+
+}
+
+/**
+ * telemetry_get_evtname() - Checkif platform config is valid
+ * @telem_unit:	Telemetry Unit to check
+ * @name:	Array of character pointers to contain name
+ * @len:	length of array name provided by user
+ *
+ * Usage by other than telemetry debugfs module is invalid
+ *
+ * Return: 0 success, < 0 for failure
+ */
+int telemetry_get_evtname(enum telemetry_unit telem_unit,
+			  const char **name, int len)
+{
+	int ret = -EINVAL;
+
+	if (telem_unit == TELEM_PSS)
+		ret = telemetry_get_pssevtname(telem_unit, name, len);
+
+	else if (telem_unit == TELEM_IOSS)
+		ret = telemetry_get_iossevtname(telem_unit, name, len);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(telemetry_get_evtname);
+
+static int __init telemetry_module_init(void)
+{
+	pr_info(pr_fmt(DRIVER_NAME) " Init\n");
+
+	telm_core_conf.telem_ops = &telm_defpltops;
+	return 0;
+}
+
+static void __exit telemetry_module_exit(void)
+{
+}
+
+module_init(telemetry_module_init);
+module_exit(telemetry_module_exit);
+
+MODULE_AUTHOR("Souvik Kumar Chakravarty <souvik.k.chakravarty@intel.com>");
+MODULE_DESCRIPTION("Intel SoC Telemetry Interface");
+MODULE_LICENSE("GPL");
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/platform/x86/intel_telemetry_debugfs.c
@@ -0,0 +1,1030 @@
+/*
+ * Intel SOC Telemetry debugfs Driver: Currently supports APL
+ * Copyright (c) 2015, Intel Corporation.
+ * All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * This file provides the debugfs interfaces for telemetry.
+ * /sys/kernel/debug/telemetry/pss_info: Shows Primary Control Sub-Sys Counters
+ * /sys/kernel/debug/telemetry/ioss_info: Shows IO Sub-System Counters
+ * /sys/kernel/debug/telemetry/soc_states: Shows SoC State
+ * /sys/kernel/debug/telemetry/pss_trace_verbosity: Read and Change Tracing
+ *				Verbosity via firmware
+ * /sys/kernel/debug/telemetry/ioss_race_verbosity: Write and Change Tracing
+ *				Verbosity via firmware
+ */
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/debugfs.h>
+#include <linux/seq_file.h>
+#include <linux/io.h>
+#include <linux/uaccess.h>
+#include <linux/pci.h>
+#include <linux/suspend.h>
+
+#include <asm/cpu_device_id.h>
+#include <asm/intel_pmc_ipc.h>
+#include <asm/intel_punit_ipc.h>
+#include <asm/intel_telemetry.h>
+
+#define DRIVER_NAME	"telemetry_soc_debugfs"
+#define DRIVER_VERSION	"1.0.0"
+
+/* ApolloLake SoC Event-IDs */
+#define TELEM_APL_PSS_PSTATES_ID	0x2802
+#define TELEM_APL_PSS_IDLE_ID		0x2806
+#define TELEM_APL_PCS_IDLE_BLOCKED_ID	0x2C00
+#define TELEM_APL_PCS_S0IX_BLOCKED_ID	0x2C01
+#define TELEM_APL_PSS_WAKEUP_ID		0x2C02
+#define TELEM_APL_PSS_LTR_BLOCKING_ID	0x2C03
+
+#define TELEM_APL_S0IX_TOTAL_OCC_ID	0x4000
+#define TELEM_APL_S0IX_SHLW_OCC_ID	0x4001
+#define TELEM_APL_S0IX_DEEP_OCC_ID	0x4002
+#define TELEM_APL_S0IX_TOTAL_RES_ID	0x4800
+#define TELEM_APL_S0IX_SHLW_RES_ID	0x4801
+#define TELEM_APL_S0IX_DEEP_RES_ID	0x4802
+#define TELEM_APL_D0IX_ID		0x581A
+#define TELEM_APL_D3_ID			0x5819
+#define TELEM_APL_PG_ID			0x5818
+
+#define TELEM_INFO_SRAMEVTS_MASK	0xFF00
+#define TELEM_INFO_SRAMEVTS_SHIFT	0x8
+#define TELEM_SSRAM_READ_TIMEOUT	10
+
+#define TELEM_MASK_BIT			1
+#define TELEM_MASK_BYTE			0xFF
+#define BYTES_PER_LONG			8
+#define TELEM_APL_MASK_PCS_STATE	0xF
+
+/* Max events in bitmap to check for */
+#define TELEM_PSS_IDLE_EVTS		25
+#define TELEM_PSS_IDLE_BLOCKED_EVTS	20
+#define TELEM_PSS_S0IX_BLOCKED_EVTS	20
+#define TELEM_PSS_S0IX_WAKEUP_EVTS	20
+#define TELEM_PSS_LTR_BLOCKING_EVTS	20
+#define TELEM_IOSS_DX_D0IX_EVTS		25
+#define TELEM_IOSS_PG_EVTS		30
+
+#define TELEM_EVT_LEN(x) (sizeof(x)/sizeof((x)[0]))
+
+#define TELEM_DEBUGFS_CPU(model, data) \
+	{ X86_VENDOR_INTEL, 6, model, X86_FEATURE_MWAIT, (unsigned long)&data}
+
+#define TELEM_CHECK_AND_PARSE_EVTS(EVTID, EVTNUM, BUF, EVTLOG, EVTDAT, MASK) { \
+	if (evtlog[index].telem_evtid == (EVTID)) { \
+		for (idx = 0; idx < (EVTNUM); idx++) \
+			(BUF)[idx] = ((EVTLOG) >> (EVTDAT)[idx].bit_pos) & \
+				     (MASK); \
+	continue; \
+	} \
+}
+
+#define TELEM_CHECK_AND_PARSE_CTRS(EVTID, CTR) { \
+	if (evtlog[index].telem_evtid == (EVTID)) { \
+		(CTR) = evtlog[index].telem_evtlog; \
+		continue; \
+	} \
+}
+
+static u8 suspend_prep_ok;
+static u32 suspend_shlw_ctr_temp, suspend_deep_ctr_temp;
+static u64 suspend_shlw_res_temp, suspend_deep_res_temp;
+
+struct telemetry_susp_stats {
+	u32 shlw_swake_ctr;
+	u32 deep_swake_ctr;
+	u64 shlw_swake_res;
+	u64 deep_swake_res;
+	u32 shlw_ctr;
+	u32 deep_ctr;
+	u64 shlw_res;
+	u64 deep_res;
+};
+
+/* Bitmap definitions for default counters in APL */
+struct telem_pss_idle_stateinfo {
+	const char *name;
+	u32 bit_pos;
+};
+
+static struct telem_pss_idle_stateinfo telem_apl_pss_idle_data[] = {
+	{"IA_CORE0_C1E",		0},
+	{"IA_CORE1_C1E",		1},
+	{"IA_CORE2_C1E",		2},
+	{"IA_CORE3_C1E",		3},
+	{"IA_CORE0_C6",			16},
+	{"IA_CORE1_C6",			17},
+	{"IA_CORE2_C6",			18},
+	{"IA_CORE3_C6",			19},
+	{"IA_MODULE0_C7",		32},
+	{"IA_MODULE1_C7",		33},
+	{"GT_RC6",			40},
+	{"IUNIT_PROCESSING_IDLE",	41},
+	{"FAR_MEM_IDLE",		43},
+	{"DISPLAY_IDLE",		44},
+	{"IUNIT_INPUT_SYSTEM_IDLE",	45},
+	{"PCS_STATUS",			60},
+};
+
+struct telem_pcs_blkd_info {
+	const char *name;
+	u32 bit_pos;
+};
+
+static struct telem_pcs_blkd_info telem_apl_pcs_idle_blkd_data[] = {
+	{"COMPUTE",			0},
+	{"MISC",			8},
+	{"MODULE_ACTIONS_PENDING",	16},
+	{"LTR",				24},
+	{"DISPLAY_WAKE",		32},
+	{"ISP_WAKE",			40},
+	{"PSF0_ACTIVE",			48},
+};
+
+static struct telem_pcs_blkd_info telem_apl_pcs_s0ix_blkd_data[] = {
+	{"LTR",				0},
+	{"IRTL",			8},
+	{"WAKE_DEADLINE_PENDING",	16},
+	{"DISPLAY",			24},
+	{"ISP",				32},
+	{"CORE",			40},
+	{"PMC",				48},
+	{"MISC",			56},
+};
+
+struct telem_pss_ltr_info {
+	const char *name;
+	u32 bit_pos;
+};
+
+static struct telem_pss_ltr_info telem_apl_pss_ltr_data[] = {
+	{"CORE_ACTIVE",		0},
+	{"MEM_UP",		8},
+	{"DFX",			16},
+	{"DFX_FORCE_LTR",	24},
+	{"DISPLAY",		32},
+	{"ISP",			40},
+	{"SOUTH",		48},
+};
+
+struct telem_pss_wakeup_info {
+	const char *name;
+	u32 bit_pos;
+};
+
+static struct telem_pss_wakeup_info telem_apl_pss_wakeup[] = {
+	{"IP_IDLE",			0},
+	{"DISPLAY_WAKE",		8},
+	{"VOLTAGE_REG_INT",		16},
+	{"DROWSY_TIMER (HOTPLUG)",	24},
+	{"CORE_WAKE",			32},
+	{"MISC_S0IX",			40},
+	{"MISC_ABORT",			56},
+};
+
+struct telem_ioss_d0ix_stateinfo {
+	const char *name;
+	u32 bit_pos;
+};
+
+static struct telem_ioss_d0ix_stateinfo telem_apl_ioss_d0ix_data[] = {
+	{"CSE",		0},
+	{"SCC2",	1},
+	{"GMM",		2},
+	{"XDCI",	3},
+	{"XHCI",	4},
+	{"ISH",		5},
+	{"AVS",		6},
+	{"PCIE0P1",	7},
+	{"PECI0P0",	8},
+	{"LPSS",	9},
+	{"SCC",		10},
+	{"PWM",		11},
+	{"PCIE1_P3",    12},
+	{"PCIE1_P2",    13},
+	{"PCIE1_P1",    14},
+	{"PCIE1_P0",    15},
+	{"CNV",		16},
+	{"SATA",	17},
+	{"PRTC",	18},
+};
+
+struct telem_ioss_pg_info {
+	const char *name;
+	u32 bit_pos;
+};
+
+static struct telem_ioss_pg_info telem_apl_ioss_pg_data[] = {
+	{"LPSS",	0},
+	{"SCC",		1},
+	{"P2SB",	2},
+	{"SCC2",	3},
+	{"GMM",		4},
+	{"PCIE0",	5},
+	{"XDCI",	6},
+	{"xHCI",	7},
+	{"CSE",		8},
+	{"SPI",		9},
+	{"AVSPGD4",	10},
+	{"AVSPGD3",	11},
+	{"AVSPGD2",	12},
+	{"AVSPGD1",	13},
+	{"ISH",		14},
+	{"EXI",		15},
+	{"NPKVRC",	16},
+	{"NPKVNN",	17},
+	{"CUNIT",	18},
+	{"FUSE_CTRL",	19},
+	{"PCIE1",	20},
+	{"CNV",		21},
+	{"LPC",		22},
+	{"SATA",	23},
+	{"SMB",		24},
+	{"PRTC",	25},
+};
+
+
+struct telemetry_debugfs_conf {
+	struct telemetry_susp_stats suspend_stats;
+	struct dentry *telemetry_dbg_dir;
+
+	/* Bitmap Data */
+	struct telem_ioss_d0ix_stateinfo *ioss_d0ix_data;
+	struct telem_pss_idle_stateinfo *pss_idle_data;
+	struct telem_pcs_blkd_info *pcs_idle_blkd_data;
+	struct telem_pcs_blkd_info *pcs_s0ix_blkd_data;
+	struct telem_pss_wakeup_info *pss_wakeup;
+	struct telem_pss_ltr_info *pss_ltr_data;
+	struct telem_ioss_pg_info *ioss_pg_data;
+	u8 pcs_idle_blkd_evts;
+	u8 pcs_s0ix_blkd_evts;
+	u8 pss_wakeup_evts;
+	u8 pss_idle_evts;
+	u8 pss_ltr_evts;
+	u8 ioss_d0ix_evts;
+	u8 ioss_pg_evts;
+
+	/* IDs */
+	u16  pss_ltr_blocking_id;
+	u16  pcs_idle_blkd_id;
+	u16  pcs_s0ix_blkd_id;
+	u16  s0ix_total_occ_id;
+	u16  s0ix_shlw_occ_id;
+	u16  s0ix_deep_occ_id;
+	u16  s0ix_total_res_id;
+	u16  s0ix_shlw_res_id;
+	u16  s0ix_deep_res_id;
+	u16  pss_wakeup_id;
+	u16  ioss_d0ix_id;
+	u16  pstates_id;
+	u16  pss_idle_id;
+	u16  ioss_d3_id;
+	u16  ioss_pg_id;
+};
+
+static struct telemetry_debugfs_conf *debugfs_conf;
+
+static struct telemetry_debugfs_conf telem_apl_debugfs_conf = {
+	.pss_idle_data = telem_apl_pss_idle_data,
+	.pcs_idle_blkd_data = telem_apl_pcs_idle_blkd_data,
+	.pcs_s0ix_blkd_data = telem_apl_pcs_s0ix_blkd_data,
+	.pss_ltr_data = telem_apl_pss_ltr_data,
+	.pss_wakeup = telem_apl_pss_wakeup,
+	.ioss_d0ix_data = telem_apl_ioss_d0ix_data,
+	.ioss_pg_data = telem_apl_ioss_pg_data,
+
+	.pss_idle_evts = TELEM_EVT_LEN(telem_apl_pss_idle_data),
+	.pcs_idle_blkd_evts = TELEM_EVT_LEN(telem_apl_pcs_idle_blkd_data),
+	.pcs_s0ix_blkd_evts = TELEM_EVT_LEN(telem_apl_pcs_s0ix_blkd_data),
+	.pss_ltr_evts = TELEM_EVT_LEN(telem_apl_pss_ltr_data),
+	.pss_wakeup_evts = TELEM_EVT_LEN(telem_apl_pss_wakeup),
+	.ioss_d0ix_evts = TELEM_EVT_LEN(telem_apl_ioss_d0ix_data),
+	.ioss_pg_evts = TELEM_EVT_LEN(telem_apl_ioss_pg_data),
+
+	.pstates_id = TELEM_APL_PSS_PSTATES_ID,
+	.pss_idle_id = TELEM_APL_PSS_IDLE_ID,
+	.pcs_idle_blkd_id = TELEM_APL_PCS_IDLE_BLOCKED_ID,
+	.pcs_s0ix_blkd_id = TELEM_APL_PCS_S0IX_BLOCKED_ID,
+	.pss_wakeup_id = TELEM_APL_PSS_WAKEUP_ID,
+	.pss_ltr_blocking_id = TELEM_APL_PSS_LTR_BLOCKING_ID,
+	.s0ix_total_occ_id = TELEM_APL_S0IX_TOTAL_OCC_ID,
+	.s0ix_shlw_occ_id = TELEM_APL_S0IX_SHLW_OCC_ID,
+	.s0ix_deep_occ_id = TELEM_APL_S0IX_DEEP_OCC_ID,
+	.s0ix_total_res_id = TELEM_APL_S0IX_TOTAL_RES_ID,
+	.s0ix_shlw_res_id = TELEM_APL_S0IX_SHLW_RES_ID,
+	.s0ix_deep_res_id = TELEM_APL_S0IX_DEEP_RES_ID,
+	.ioss_d0ix_id = TELEM_APL_D0IX_ID,
+	.ioss_d3_id = TELEM_APL_D3_ID,
+	.ioss_pg_id = TELEM_APL_PG_ID,
+};
+
+static const struct x86_cpu_id telemetry_debugfs_cpu_ids[] = {
+	TELEM_DEBUGFS_CPU(0x5c, telem_apl_debugfs_conf),
+	{}
+};
+
+MODULE_DEVICE_TABLE(x86cpu, telemetry_debugfs_cpu_ids);
+
+static int telemetry_debugfs_check_evts(void)
+{
+	if ((debugfs_conf->pss_idle_evts > TELEM_PSS_IDLE_EVTS) ||
+	    (debugfs_conf->pcs_idle_blkd_evts > TELEM_PSS_IDLE_BLOCKED_EVTS) ||
+	    (debugfs_conf->pcs_s0ix_blkd_evts > TELEM_PSS_S0IX_BLOCKED_EVTS) ||
+	    (debugfs_conf->pss_ltr_evts > TELEM_PSS_LTR_BLOCKING_EVTS) ||
+	    (debugfs_conf->pss_wakeup_evts > TELEM_PSS_S0IX_WAKEUP_EVTS) ||
+	    (debugfs_conf->ioss_d0ix_evts > TELEM_IOSS_DX_D0IX_EVTS) ||
+	    (debugfs_conf->ioss_pg_evts > TELEM_IOSS_PG_EVTS))
+		return -EINVAL;
+
+	return 0;
+}
+
+static int telem_pss_states_show(struct seq_file *s, void *unused)
+{
+	struct telemetry_evtlog evtlog[TELEM_MAX_OS_ALLOCATED_EVENTS];
+	struct telemetry_debugfs_conf *conf = debugfs_conf;
+	const char *name[TELEM_MAX_OS_ALLOCATED_EVENTS];
+	u32 pcs_idle_blkd[TELEM_PSS_IDLE_BLOCKED_EVTS],
+	    pcs_s0ix_blkd[TELEM_PSS_S0IX_BLOCKED_EVTS],
+	    pss_s0ix_wakeup[TELEM_PSS_S0IX_WAKEUP_EVTS],
+	    pss_ltr_blkd[TELEM_PSS_LTR_BLOCKING_EVTS],
+	    pss_idle[TELEM_PSS_IDLE_EVTS];
+	int index, idx, ret, err = 0;
+	u64 pstates = 0;
+
+	ret = telemetry_read_eventlog(TELEM_PSS, evtlog,
+				      TELEM_MAX_OS_ALLOCATED_EVENTS);
+	if (ret < 0)
+		return ret;
+
+	err = telemetry_get_evtname(TELEM_PSS, name,
+				    TELEM_MAX_OS_ALLOCATED_EVENTS);
+	if (err < 0)
+		return err;
+
+	seq_puts(s, "\n----------------------------------------------------\n");
+	seq_puts(s, "\tPSS TELEM EVENTLOG (Residency = field/19.2 us\n");
+	seq_puts(s, "----------------------------------------------------\n");
+	for (index = 0; index < ret; index++) {
+		seq_printf(s, "%-32s %llu\n",
+			   name[index], evtlog[index].telem_evtlog);
+
+		/* Fetch PSS IDLE State */
+		if (evtlog[index].telem_evtid == conf->pss_idle_id) {
+			pss_idle[conf->pss_idle_evts - 1] =
+			(evtlog[index].telem_evtlog >>
+			conf->pss_idle_data[conf->pss_idle_evts - 1].bit_pos) &
+			TELEM_APL_MASK_PCS_STATE;
+		}
+
+
+		TELEM_CHECK_AND_PARSE_EVTS(conf->pss_idle_id,
+					   conf->pss_idle_evts - 1,
+					   pss_idle, evtlog[index].telem_evtlog,
+					   conf->pss_idle_data, TELEM_MASK_BIT);
+
+		TELEM_CHECK_AND_PARSE_EVTS(conf->pcs_idle_blkd_id,
+					   conf->pcs_idle_blkd_evts,
+					   pcs_idle_blkd,
+					   evtlog[index].telem_evtlog,
+					   conf->pcs_idle_blkd_data,
+					   TELEM_MASK_BYTE);
+
+		TELEM_CHECK_AND_PARSE_EVTS(conf->pcs_s0ix_blkd_id,
+					   conf->pcs_s0ix_blkd_evts,
+					   pcs_s0ix_blkd,
+					   evtlog[index].telem_evtlog,
+					   conf->pcs_s0ix_blkd_data,
+					   TELEM_MASK_BYTE);
+
+
+		TELEM_CHECK_AND_PARSE_EVTS(conf->pss_wakeup_id,
+					   conf->pss_wakeup_evts,
+					   pss_s0ix_wakeup,
+					   evtlog[index].telem_evtlog,
+					   conf->pss_wakeup, TELEM_MASK_BYTE);
+
+		TELEM_CHECK_AND_PARSE_EVTS(conf->pss_ltr_blocking_id,
+					   conf->pss_ltr_evts, pss_ltr_blkd,
+					   evtlog[index].telem_evtlog,
+					   conf->pss_ltr_data, TELEM_MASK_BYTE);
+
+		if (evtlog[index].telem_evtid == debugfs_conf->pstates_id)
+			pstates = evtlog[index].telem_evtlog;
+	}
+
+	seq_puts(s, "\n--------------------------------------\n");
+	seq_puts(s, "PStates\n");
+	seq_puts(s, "--------------------------------------\n");
+	seq_puts(s, "Domain\t\t\t\tFreq(Mhz)\n");
+	seq_printf(s, " IA\t\t\t\t %llu\n GT\t\t\t\t %llu\n",
+		   (pstates & TELEM_MASK_BYTE)*100,
+		   ((pstates >> 8) & TELEM_MASK_BYTE)*50/3);
+
+	seq_printf(s, " IUNIT\t\t\t\t %llu\n SA\t\t\t\t %llu\n",
+		   ((pstates >> 16) & TELEM_MASK_BYTE)*25,
+		   ((pstates >> 24) & TELEM_MASK_BYTE)*50/3);
+
+	seq_puts(s, "\n--------------------------------------\n");
+	seq_puts(s, "PSS IDLE Status\n");
+	seq_puts(s, "--------------------------------------\n");
+	seq_puts(s, "Device\t\t\t\t\tIDLE\n");
+	for (index = 0; index < debugfs_conf->pss_idle_evts; index++) {
+		seq_printf(s, "%-32s\t%u\n",
+			   debugfs_conf->pss_idle_data[index].name,
+			   pss_idle[index]);
+	}
+
+	seq_puts(s, "\n--------------------------------------\n");
+	seq_puts(s, "PSS Idle blkd Status (~1ms saturating bucket)\n");
+	seq_puts(s, "--------------------------------------\n");
+	seq_puts(s, "Blocker\t\t\t\t\tCount\n");
+	for (index = 0; index < debugfs_conf->pcs_idle_blkd_evts; index++) {
+		seq_printf(s, "%-32s\t%u\n",
+			   debugfs_conf->pcs_idle_blkd_data[index].name,
+			   pcs_idle_blkd[index]);
+	}
+
+	seq_puts(s, "\n--------------------------------------\n");
+	seq_puts(s, "PSS S0ix blkd Status (~1ms saturating bucket)\n");
+	seq_puts(s, "--------------------------------------\n");
+	seq_puts(s, "Blocker\t\t\t\t\tCount\n");
+	for (index = 0; index < debugfs_conf->pcs_s0ix_blkd_evts; index++) {
+		seq_printf(s, "%-32s\t%u\n",
+			   debugfs_conf->pcs_s0ix_blkd_data[index].name,
+			   pcs_s0ix_blkd[index]);
+	}
+
+	seq_puts(s, "\n--------------------------------------\n");
+	seq_puts(s, "LTR Blocking Status (~1ms saturating bucket)\n");
+	seq_puts(s, "--------------------------------------\n");
+	seq_puts(s, "Blocker\t\t\t\t\tCount\n");
+	for (index = 0; index < debugfs_conf->pss_ltr_evts; index++) {
+		seq_printf(s, "%-32s\t%u\n",
+			   debugfs_conf->pss_ltr_data[index].name,
+			   pss_s0ix_wakeup[index]);
+	}
+
+	seq_puts(s, "\n--------------------------------------\n");
+	seq_puts(s, "Wakes Status (~1ms saturating bucket)\n");
+	seq_puts(s, "--------------------------------------\n");
+	seq_puts(s, "Wakes\t\t\t\t\tCount\n");
+	for (index = 0; index < debugfs_conf->pss_wakeup_evts; index++) {
+		seq_printf(s, "%-32s\t%u\n",
+			   debugfs_conf->pss_wakeup[index].name,
+			   pss_ltr_blkd[index]);
+	}
+
+	return 0;
+}
+
+static int telem_pss_state_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, telem_pss_states_show, inode->i_private);
+}
+
+static const struct file_operations telem_pss_ops = {
+	.open		= telem_pss_state_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
+
+static int telem_ioss_states_show(struct seq_file *s, void *unused)
+{
+	struct telemetry_evtlog evtlog[TELEM_MAX_OS_ALLOCATED_EVENTS];
+	const char *name[TELEM_MAX_OS_ALLOCATED_EVENTS];
+	int index, ret, err;
+
+	ret = telemetry_read_eventlog(TELEM_IOSS, evtlog,
+				      TELEM_MAX_OS_ALLOCATED_EVENTS);
+	if (ret < 0)
+		return ret;
+
+	err = telemetry_get_evtname(TELEM_IOSS, name,
+				    TELEM_MAX_OS_ALLOCATED_EVENTS);
+	if (err < 0)
+		return err;
+
+	seq_puts(s, "--------------------------------------\n");
+	seq_puts(s, "\tI0SS TELEMETRY EVENTLOG\n");
+	seq_puts(s, "--------------------------------------\n");
+	for (index = 0; index < ret; index++) {
+		seq_printf(s, "%-32s 0x%llx\n",
+			   name[index], evtlog[index].telem_evtlog);
+	}
+
+	return 0;
+}
+
+static int telem_ioss_state_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, telem_ioss_states_show, inode->i_private);
+}
+
+static const struct file_operations telem_ioss_ops = {
+	.open		= telem_ioss_state_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
+static int telem_soc_states_show(struct seq_file *s, void *unused)
+{
+	u32 d3_sts[TELEM_IOSS_DX_D0IX_EVTS], d0ix_sts[TELEM_IOSS_DX_D0IX_EVTS];
+	u32 pg_sts[TELEM_IOSS_PG_EVTS], pss_idle[TELEM_PSS_IDLE_EVTS];
+	struct telemetry_evtlog evtlog[TELEM_MAX_OS_ALLOCATED_EVENTS];
+	u32 s0ix_total_ctr = 0, s0ix_shlw_ctr = 0, s0ix_deep_ctr = 0;
+	u64 s0ix_total_res = 0, s0ix_shlw_res = 0, s0ix_deep_res = 0;
+	struct telemetry_debugfs_conf *conf = debugfs_conf;
+	struct pci_dev *dev = NULL;
+	int index, idx, ret;
+	u32 d3_state;
+	u16 pmcsr;
+
+	ret = telemetry_read_eventlog(TELEM_IOSS, evtlog,
+				      TELEM_MAX_OS_ALLOCATED_EVENTS);
+	if (ret < 0)
+		return ret;
+
+	for (index = 0; index < ret; index++) {
+		TELEM_CHECK_AND_PARSE_EVTS(conf->ioss_d3_id,
+					   conf->ioss_d0ix_evts,
+					   d3_sts, evtlog[index].telem_evtlog,
+					   conf->ioss_d0ix_data,
+					   TELEM_MASK_BIT);
+
+		TELEM_CHECK_AND_PARSE_EVTS(conf->ioss_pg_id, conf->ioss_pg_evts,
+					   pg_sts, evtlog[index].telem_evtlog,
+					   conf->ioss_pg_data, TELEM_MASK_BIT);
+
+		TELEM_CHECK_AND_PARSE_EVTS(conf->ioss_d0ix_id,
+					   conf->ioss_d0ix_evts,
+					   d0ix_sts, evtlog[index].telem_evtlog,
+					   conf->ioss_d0ix_data,
+					   TELEM_MASK_BIT);
+
+		TELEM_CHECK_AND_PARSE_CTRS(conf->s0ix_total_occ_id,
+					   s0ix_total_ctr);
+
+		TELEM_CHECK_AND_PARSE_CTRS(conf->s0ix_shlw_occ_id,
+					   s0ix_shlw_ctr);
+
+		TELEM_CHECK_AND_PARSE_CTRS(conf->s0ix_deep_occ_id,
+					   s0ix_deep_ctr);
+
+		TELEM_CHECK_AND_PARSE_CTRS(conf->s0ix_total_res_id,
+					   s0ix_total_res);
+
+		TELEM_CHECK_AND_PARSE_CTRS(conf->s0ix_shlw_res_id,
+					   s0ix_shlw_res);
+
+		TELEM_CHECK_AND_PARSE_CTRS(conf->s0ix_deep_res_id,
+					   s0ix_deep_res);
+	}
+
+	seq_puts(s, "\n---------------------------------------------------\n");
+	seq_puts(s, "S0IX Type\t\t\t Occurrence\t\t Residency(us)\n");
+	seq_puts(s, "---------------------------------------------------\n");
+
+	seq_printf(s, "S0IX Shallow\t\t\t %10u\t %10llu\n",
+		   s0ix_shlw_ctr -
+		   conf->suspend_stats.shlw_ctr -
+		   conf->suspend_stats.shlw_swake_ctr,
+		   (u64)((s0ix_shlw_res -
+		   conf->suspend_stats.shlw_res -
+		   conf->suspend_stats.shlw_swake_res)*10/192));
+
+	seq_printf(s, "S0IX Deep\t\t\t %10u\t %10llu\n",
+		   s0ix_deep_ctr -
+		   conf->suspend_stats.deep_ctr -
+		   conf->suspend_stats.deep_swake_ctr,
+		   (u64)((s0ix_deep_res -
+		   conf->suspend_stats.deep_res -
+		   conf->suspend_stats.deep_swake_res)*10/192));
+
+	seq_printf(s, "Suspend(With S0ixShallow)\t %10u\t %10llu\n",
+		   conf->suspend_stats.shlw_ctr,
+		   (u64)(conf->suspend_stats.shlw_res*10)/192);
+
+	seq_printf(s, "Suspend(With S0ixDeep)\t\t %10u\t %10llu\n",
+		   conf->suspend_stats.deep_ctr,
+		   (u64)(conf->suspend_stats.deep_res*10)/192);
+
+	seq_printf(s, "Suspend(With Shallow-Wakes)\t %10u\t %10llu\n",
+		   conf->suspend_stats.shlw_swake_ctr +
+		   conf->suspend_stats.deep_swake_ctr,
+		   (u64)((conf->suspend_stats.shlw_swake_res +
+		   conf->suspend_stats.deep_swake_res)*10/192));
+
+	seq_printf(s, "S0IX+Suspend Total\t\t %10u\t %10llu\n", s0ix_total_ctr,
+				(u64)(s0ix_total_res*10/192));
+	seq_puts(s, "\n-------------------------------------------------\n");
+	seq_puts(s, "\t\tDEVICE STATES\n");
+	seq_puts(s, "-------------------------------------------------\n");
+
+	for_each_pci_dev(dev) {
+		pci_read_config_word(dev, dev->pm_cap + PCI_PM_CTRL, &pmcsr);
+		d3_state = ((pmcsr & PCI_PM_CTRL_STATE_MASK) ==
+			    (__force int)PCI_D3hot) ? 1 : 0;
+
+		seq_printf(s, "pci %04x %04X %s %20.20s: ",
+			   dev->vendor, dev->device, dev_name(&dev->dev),
+			   dev_driver_string(&dev->dev));
+		seq_printf(s, " d3:%x\n", d3_state);
+	}
+
+	seq_puts(s, "\n--------------------------------------\n");
+	seq_puts(s, "D3/D0i3 Status\n");
+	seq_puts(s, "--------------------------------------\n");
+	seq_puts(s, "Block\t\t D3\t D0i3\n");
+	for (index = 0; index < conf->ioss_d0ix_evts; index++) {
+		seq_printf(s, "%-10s\t %u\t %u\n",
+			   conf->ioss_d0ix_data[index].name,
+			   d3_sts[index], d0ix_sts[index]);
+	}
+
+	seq_puts(s, "\n--------------------------------------\n");
+	seq_puts(s, "South Complex PowerGate Status\n");
+	seq_puts(s, "--------------------------------------\n");
+	seq_puts(s, "Device\t\t PG\n");
+	for (index = 0; index < conf->ioss_pg_evts; index++) {
+		seq_printf(s, "%-10s\t %u\n",
+			   conf->ioss_pg_data[index].name,
+			   pg_sts[index]);
+	}
+
+	evtlog->telem_evtid = conf->pss_idle_id;
+	ret = telemetry_read_events(TELEM_PSS, evtlog, 1);
+	if (ret < 0)
+		return ret;
+
+	seq_puts(s, "\n-----------------------------------------\n");
+	seq_puts(s, "North Idle Status\n");
+	seq_puts(s, "-----------------------------------------\n");
+	for (idx = 0; idx < conf->pss_idle_evts - 1; idx++) {
+		pss_idle[idx] =	(evtlog->telem_evtlog >>
+				conf->pss_idle_data[idx].bit_pos) &
+				TELEM_MASK_BIT;
+	}
+
+	pss_idle[idx] = (evtlog->telem_evtlog >>
+			conf->pss_idle_data[idx].bit_pos) &
+			TELEM_APL_MASK_PCS_STATE;
+
+	for (index = 0; index < conf->pss_idle_evts; index++) {
+		seq_printf(s, "%-30s %u\n",
+			   conf->pss_idle_data[index].name,
+			   pss_idle[index]);
+	}
+
+	seq_puts(s, "\nPCS_STATUS Code\n");
+	seq_puts(s, "0:C0 1:C1 2:C1_DN_WT_DEV 3:C2 4:C2_WT_DE_MEM_UP\n");
+	seq_puts(s, "5:C2_WT_DE_MEM_DOWN 6:C2_UP_WT_DEV 7:C2_DN 8:C2_VOA\n");
+	seq_puts(s, "9:C2_VOA_UP 10:S0IX_PRE 11:S0IX\n");
+
+	return 0;
+}
+
+static int telem_soc_state_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, telem_soc_states_show, inode->i_private);
+}
+
+static const struct file_operations telem_socstate_ops = {
+	.open		= telem_soc_state_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
+static int telem_pss_trc_verb_show(struct seq_file *s, void *unused)
+{
+	u32 verbosity;
+	int err;
+
+	err = telemetry_get_trace_verbosity(TELEM_PSS, &verbosity);
+	if (err) {
+		pr_err("Get PSS Trace Verbosity Failed with Error %d\n", err);
+		return -EFAULT;
+	}
+
+	seq_printf(s, "PSS Trace Verbosity %u\n", verbosity);
+	return 0;
+}
+
+static ssize_t telem_pss_trc_verb_write(struct file *file,
+					const char __user *userbuf,
+					size_t count, loff_t *ppos)
+{
+	u32 verbosity;
+	int err;
+
+	if (kstrtou32_from_user(userbuf, count, 0, &verbosity))
+		return -EFAULT;
+
+	err = telemetry_set_trace_verbosity(TELEM_PSS, verbosity);
+	if (err) {
+		pr_err("Changing PSS Trace Verbosity Failed. Error %d\n", err);
+		count = err;
+	}
+
+	return count;
+}
+
+static int telem_pss_trc_verb_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, telem_pss_trc_verb_show, inode->i_private);
+}
+
+static const struct file_operations telem_pss_trc_verb_ops = {
+	.open		= telem_pss_trc_verb_open,
+	.read		= seq_read,
+	.write		= telem_pss_trc_verb_write,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
+
+static int telem_ioss_trc_verb_show(struct seq_file *s, void *unused)
+{
+	u32 verbosity;
+	int err;
+
+	err = telemetry_get_trace_verbosity(TELEM_IOSS, &verbosity);
+	if (err) {
+		pr_err("Get IOSS Trace Verbosity Failed with Error %d\n", err);
+		return -EFAULT;
+	}
+
+	seq_printf(s, "IOSS Trace Verbosity %u\n", verbosity);
+	return 0;
+}
+
+static ssize_t telem_ioss_trc_verb_write(struct file *file,
+					 const char __user *userbuf,
+					 size_t count, loff_t *ppos)
+{
+	u32 verbosity;
+	int err;
+
+	if (kstrtou32_from_user(userbuf, count, 0, &verbosity))
+		return -EFAULT;
+
+	err = telemetry_set_trace_verbosity(TELEM_IOSS, verbosity);
+	if (err) {
+		pr_err("Changing IOSS Trace Verbosity Failed. Error %d\n", err);
+		count = err;
+	}
+
+	return count;
+}
+
+static int telem_ioss_trc_verb_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, telem_ioss_trc_verb_show, inode->i_private);
+}
+
+static const struct file_operations telem_ioss_trc_verb_ops = {
+	.open		= telem_ioss_trc_verb_open,
+	.read		= seq_read,
+	.write		= telem_ioss_trc_verb_write,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
+#ifdef CONFIG_PM_SLEEP
+static int pm_suspend_prep_cb(void)
+{
+	struct telemetry_evtlog evtlog[TELEM_MAX_OS_ALLOCATED_EVENTS];
+	struct telemetry_debugfs_conf *conf = debugfs_conf;
+	int ret, index;
+
+	ret = telemetry_raw_read_eventlog(TELEM_IOSS, evtlog,
+			TELEM_MAX_OS_ALLOCATED_EVENTS);
+	if (ret < 0) {
+		suspend_prep_ok = 0;
+		goto out;
+	}
+
+	for (index = 0; index < ret; index++) {
+
+		TELEM_CHECK_AND_PARSE_CTRS(conf->s0ix_shlw_occ_id,
+					   suspend_shlw_ctr_temp);
+
+		TELEM_CHECK_AND_PARSE_CTRS(conf->s0ix_deep_occ_id,
+					   suspend_deep_ctr_temp);
+
+		TELEM_CHECK_AND_PARSE_CTRS(conf->s0ix_shlw_res_id,
+					   suspend_shlw_res_temp);
+
+		TELEM_CHECK_AND_PARSE_CTRS(conf->s0ix_deep_res_id,
+					   suspend_deep_res_temp);
+	}
+	suspend_prep_ok = 1;
+out:
+	return NOTIFY_OK;
+}
+
+static int pm_suspend_exit_cb(void)
+{
+	struct telemetry_evtlog evtlog[TELEM_MAX_OS_ALLOCATED_EVENTS];
+	static u32 suspend_shlw_ctr_exit, suspend_deep_ctr_exit;
+	static u64 suspend_shlw_res_exit, suspend_deep_res_exit;
+	struct telemetry_debugfs_conf *conf = debugfs_conf;
+	int ret, index;
+
+	if (!suspend_prep_ok)
+		goto out;
+
+	ret = telemetry_raw_read_eventlog(TELEM_IOSS, evtlog,
+					  TELEM_MAX_OS_ALLOCATED_EVENTS);
+	if (ret < 0)
+		goto out;
+
+	for (index = 0; index < ret; index++) {
+		TELEM_CHECK_AND_PARSE_CTRS(conf->s0ix_shlw_occ_id,
+					   suspend_shlw_ctr_exit);
+
+		TELEM_CHECK_AND_PARSE_CTRS(conf->s0ix_deep_occ_id,
+					   suspend_deep_ctr_exit);
+
+		TELEM_CHECK_AND_PARSE_CTRS(conf->s0ix_shlw_res_id,
+					   suspend_shlw_res_exit);
+
+		TELEM_CHECK_AND_PARSE_CTRS(conf->s0ix_deep_res_id,
+					   suspend_deep_res_exit);
+	}
+
+	if ((suspend_shlw_ctr_exit < suspend_shlw_ctr_temp) ||
+	    (suspend_deep_ctr_exit < suspend_deep_ctr_temp) ||
+	    (suspend_shlw_res_exit < suspend_shlw_res_temp) ||
+	    (suspend_deep_res_exit < suspend_deep_res_temp)) {
+		pr_err("Wrong s0ix counters detected\n");
+		goto out;
+	}
+
+	suspend_shlw_ctr_exit -= suspend_shlw_ctr_temp;
+	suspend_deep_ctr_exit -= suspend_deep_ctr_temp;
+	suspend_shlw_res_exit -= suspend_shlw_res_temp;
+	suspend_deep_res_exit -= suspend_deep_res_temp;
+
+	if (suspend_shlw_ctr_exit == 1) {
+		conf->suspend_stats.shlw_ctr +=
+		suspend_shlw_ctr_exit;
+
+		conf->suspend_stats.shlw_res +=
+		suspend_shlw_res_exit;
+	}
+	/* Shallow Wakes Case */
+	else if (suspend_shlw_ctr_exit > 1) {
+		conf->suspend_stats.shlw_swake_ctr +=
+		suspend_shlw_ctr_exit;
+
+		conf->suspend_stats.shlw_swake_res +=
+		suspend_shlw_res_exit;
+	}
+
+	if (suspend_deep_ctr_exit == 1) {
+		conf->suspend_stats.deep_ctr +=
+		suspend_deep_ctr_exit;
+
+		conf->suspend_stats.deep_res +=
+		suspend_deep_res_exit;
+	}
+
+	/* Shallow Wakes Case */
+	else if (suspend_deep_ctr_exit > 1) {
+		conf->suspend_stats.deep_swake_ctr +=
+		suspend_deep_ctr_exit;
+
+		conf->suspend_stats.deep_swake_res +=
+		suspend_deep_res_exit;
+	}
+
+out:
+	suspend_prep_ok = 0;
+	return NOTIFY_OK;
+}
+
+static int pm_notification(struct notifier_block *this,
+			   unsigned long event, void *ptr)
+{
+	switch (event) {
+	case PM_SUSPEND_PREPARE:
+		return pm_suspend_prep_cb();
+	case PM_POST_SUSPEND:
+		return pm_suspend_exit_cb();
+	}
+
+	return NOTIFY_DONE;
+}
+
+static struct notifier_block pm_notifier = {
+	.notifier_call = pm_notification,
+};
+#endif /* CONFIG_PM_SLEEP */
+
+static int __init telemetry_debugfs_init(void)
+{
+	const struct x86_cpu_id *id;
+	int err = -ENOMEM;
+	struct dentry *f;
+
+	/* Only APL supported for now */
+	id = x86_match_cpu(telemetry_debugfs_cpu_ids);
+	if (!id)
+		return -ENODEV;
+
+	debugfs_conf = (struct telemetry_debugfs_conf *)id->driver_data;
+
+	err = telemetry_pltconfig_valid();
+	if (err < 0)
+		return -ENODEV;
+
+	err = telemetry_debugfs_check_evts();
+	if (err < 0)
+		return -EINVAL;
+
+
+#ifdef CONFIG_PM_SLEEP
+	register_pm_notifier(&pm_notifier);
+#endif /* CONFIG_PM_SLEEP */
+
+	debugfs_conf->telemetry_dbg_dir = debugfs_create_dir("telemetry", NULL);
+	if (!debugfs_conf->telemetry_dbg_dir)
+		return -ENOMEM;
+
+	f = debugfs_create_file("pss_info", S_IFREG | S_IRUGO,
+				debugfs_conf->telemetry_dbg_dir, NULL,
+				&telem_pss_ops);
+	if (!f) {
+		pr_err("pss_sample_info debugfs register failed\n");
+		goto out;
+	}
+
+	f = debugfs_create_file("ioss_info", S_IFREG | S_IRUGO,
+				debugfs_conf->telemetry_dbg_dir, NULL,
+				&telem_ioss_ops);
+	if (!f) {
+		pr_err("ioss_sample_info debugfs register failed\n");
+		goto out;
+	}
+
+	f = debugfs_create_file("soc_states", S_IFREG | S_IRUGO,
+				debugfs_conf->telemetry_dbg_dir,
+				NULL, &telem_socstate_ops);
+	if (!f) {
+		pr_err("ioss_sample_info debugfs register failed\n");
+		goto out;
+	}
+
+	f = debugfs_create_file("pss_trace_verbosity", S_IFREG | S_IRUGO,
+				debugfs_conf->telemetry_dbg_dir, NULL,
+				&telem_pss_trc_verb_ops);
+	if (!f) {
+		pr_err("pss_trace_verbosity debugfs register failed\n");
+		goto out;
+	}
+
+	f = debugfs_create_file("ioss_trace_verbosity", S_IFREG | S_IRUGO,
+				debugfs_conf->telemetry_dbg_dir, NULL,
+				&telem_ioss_trc_verb_ops);
+	if (!f) {
+		pr_err("ioss_trace_verbosity debugfs register failed\n");
+		goto out;
+	}
+
+	return 0;
+
+out:
+	debugfs_remove_recursive(debugfs_conf->telemetry_dbg_dir);
+	debugfs_conf->telemetry_dbg_dir = NULL;
+
+	return err;
+}
+
+static void __exit telemetry_debugfs_exit(void)
+{
+	debugfs_remove_recursive(debugfs_conf->telemetry_dbg_dir);
+	debugfs_conf->telemetry_dbg_dir = NULL;
+}
+
+late_initcall(telemetry_debugfs_init);
+module_exit(telemetry_debugfs_exit);
+
+MODULE_AUTHOR("Souvik Kumar Chakravarty <souvik.k.chakravarty@intel.com>");
+MODULE_DESCRIPTION("Intel SoC Telemetry debugfs Interface");
+MODULE_VERSION(DRIVER_VERSION);
+MODULE_LICENSE("GPL");
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/platform/x86/intel_telemetry_pltdrv.c
@@ -0,0 +1,1206 @@
+/*
+ * Intel SOC Telemetry Platform Driver: Currently supports APL
+ * Copyright (c) 2015, Intel Corporation.
+ * All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * This file provides the platform specific telemetry implementation for APL.
+ * It used the PUNIT and PMC IPC interfaces for configuring the counters.
+ * The accumulated results are fetched from SRAM.
+ */
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/debugfs.h>
+#include <linux/seq_file.h>
+#include <linux/io.h>
+#include <linux/uaccess.h>
+#include <linux/pci.h>
+#include <linux/suspend.h>
+#include <linux/platform_device.h>
+
+#include <asm/cpu_device_id.h>
+#include <asm/intel_pmc_ipc.h>
+#include <asm/intel_punit_ipc.h>
+#include <asm/intel_telemetry.h>
+
+#define DRIVER_NAME	"intel_telemetry"
+#define DRIVER_VERSION	"1.0.0"
+
+#define TELEM_TRC_VERBOSITY_MASK	0x3
+
+#define TELEM_MIN_PERIOD(x)		((x) & 0x7F0000)
+#define TELEM_MAX_PERIOD(x)		((x) & 0x7F000000)
+#define TELEM_SAMPLE_PERIOD_INVALID(x)	((x) & (BIT(7)))
+#define TELEM_CLEAR_SAMPLE_PERIOD(x)	((x) &= ~0x7F)
+
+#define TELEM_SAMPLING_DEFAULT_PERIOD	0xD
+
+#define TELEM_MAX_EVENTS_SRAM		28
+#define TELEM_MAX_OS_ALLOCATED_EVENTS	20
+#define TELEM_SSRAM_STARTTIME_OFFSET	8
+#define TELEM_SSRAM_EVTLOG_OFFSET	16
+
+#define IOSS_TELEM_EVENT_READ		0x0
+#define IOSS_TELEM_EVENT_WRITE		0x1
+#define IOSS_TELEM_INFO_READ		0x2
+#define IOSS_TELEM_TRACE_CTL_READ	0x5
+#define IOSS_TELEM_TRACE_CTL_WRITE	0x6
+#define IOSS_TELEM_EVENT_CTL_READ	0x7
+#define IOSS_TELEM_EVENT_CTL_WRITE	0x8
+#define IOSS_TELEM_EVT_CTRL_WRITE_SIZE	0x4
+#define IOSS_TELEM_READ_WORD		0x1
+#define IOSS_TELEM_WRITE_FOURBYTES	0x4
+#define IOSS_TELEM_EVT_WRITE_SIZE	0x3
+
+#define TELEM_INFO_SRAMEVTS_MASK	0xFF00
+#define TELEM_INFO_SRAMEVTS_SHIFT	0x8
+#define TELEM_SSRAM_READ_TIMEOUT	10
+
+#define TELEM_INFO_NENABLES_MASK	0xFF
+#define TELEM_EVENT_ENABLE		0x8000
+
+#define TELEM_MASK_BIT			1
+#define TELEM_MASK_BYTE			0xFF
+#define BYTES_PER_LONG			8
+#define TELEM_MASK_PCS_STATE		0xF
+
+#define TELEM_DISABLE(x)		((x) &= ~(BIT(31)))
+#define TELEM_CLEAR_EVENTS(x)		((x) |= (BIT(30)))
+#define TELEM_ENABLE_SRAM_EVT_TRACE(x)	((x) &= ~(BIT(30) | BIT(24)))
+#define TELEM_ENABLE_PERIODIC(x)	((x) |= (BIT(23) | BIT(31) | BIT(7)))
+#define TELEM_EXTRACT_VERBOSITY(x, y)	((y) = (((x) >> 27) & 0x3))
+#define TELEM_CLEAR_VERBOSITY_BITS(x)	((x) &= ~(BIT(27) | BIT(28)))
+#define TELEM_SET_VERBOSITY_BITS(x, y)	((x) |= ((y) << 27))
+
+#define TELEM_CPU(model, data) \
+	{ X86_VENDOR_INTEL, 6, model, X86_FEATURE_MWAIT, (unsigned long)&data }
+
+enum telemetry_action {
+	TELEM_UPDATE = 0,
+	TELEM_ADD,
+	TELEM_RESET,
+	TELEM_ACTION_NONE
+};
+
+struct telem_ssram_region {
+	u64 timestamp;
+	u64 start_time;
+	u64 events[TELEM_MAX_EVENTS_SRAM];
+};
+
+static struct telemetry_plt_config *telm_conf;
+
+/*
+ * The following counters are programmed by default during setup.
+ * Only 20 allocated to kernel driver
+ */
+static struct telemetry_evtmap
+	telemetry_apl_ioss_default_events[TELEM_MAX_OS_ALLOCATED_EVENTS] = {
+	{"SOC_S0IX_TOTAL_RES",			0x4800},
+	{"SOC_S0IX_TOTAL_OCC",			0x4000},
+	{"SOC_S0IX_SHALLOW_RES",		0x4801},
+	{"SOC_S0IX_SHALLOW_OCC",		0x4001},
+	{"SOC_S0IX_DEEP_RES",			0x4802},
+	{"SOC_S0IX_DEEP_OCC",			0x4002},
+	{"PMC_POWER_GATE",			0x5818},
+	{"PMC_D3_STATES",			0x5819},
+	{"PMC_D0I3_STATES",			0x581A},
+	{"PMC_S0IX_WAKE_REASON_GPIO",		0x6000},
+	{"PMC_S0IX_WAKE_REASON_TIMER",		0x6001},
+	{"PMC_S0IX_WAKE_REASON_VNNREQ",         0x6002},
+	{"PMC_S0IX_WAKE_REASON_LOWPOWER",       0x6003},
+	{"PMC_S0IX_WAKE_REASON_EXTERNAL",       0x6004},
+	{"PMC_S0IX_WAKE_REASON_MISC",           0x6005},
+	{"PMC_S0IX_BLOCKING_IPS_D3_D0I3",       0x6006},
+	{"PMC_S0IX_BLOCKING_IPS_PG",            0x6007},
+	{"PMC_S0IX_BLOCKING_MISC_IPS_PG",       0x6008},
+	{"PMC_S0IX_BLOCK_IPS_VNN_REQ",          0x6009},
+	{"PMC_S0IX_BLOCK_IPS_CLOCKS",           0x600B},
+};
+
+
+static struct telemetry_evtmap
+	telemetry_apl_pss_default_events[TELEM_MAX_OS_ALLOCATED_EVENTS] = {
+	{"IA_CORE0_C6_RES",			0x0400},
+	{"IA_CORE0_C6_CTR",			0x0000},
+	{"IA_MODULE0_C7_RES",			0x0410},
+	{"IA_MODULE0_C7_CTR",			0x000E},
+	{"IA_C0_RES",				0x0805},
+	{"PCS_LTR",				0x2801},
+	{"PSTATES",				0x2802},
+	{"SOC_S0I3_RES",			0x0409},
+	{"SOC_S0I3_CTR",			0x000A},
+	{"PCS_S0I3_CTR",			0x0009},
+	{"PCS_C1E_RES",				0x041A},
+	{"PCS_IDLE_STATUS",			0x2806},
+	{"IA_PERF_LIMITS",			0x280B},
+	{"GT_PERF_LIMITS",			0x280C},
+	{"PCS_WAKEUP_S0IX_CTR",			0x0030},
+	{"PCS_IDLE_BLOCKED",			0x2C00},
+	{"PCS_S0IX_BLOCKED",			0x2C01},
+	{"PCS_S0IX_WAKE_REASONS",		0x2C02},
+	{"PCS_LTR_BLOCKING",			0x2C03},
+	{"PC2_AND_MEM_SHALLOW_IDLE_RES",	0x1D40},
+};
+
+/* APL specific Data */
+static struct telemetry_plt_config telem_apl_config = {
+	.pss_config = {
+		.telem_evts = telemetry_apl_pss_default_events,
+	},
+	.ioss_config = {
+		.telem_evts = telemetry_apl_ioss_default_events,
+	},
+};
+
+static const struct x86_cpu_id telemetry_cpu_ids[] = {
+	TELEM_CPU(0x5c, telem_apl_config),
+	{}
+};
+
+MODULE_DEVICE_TABLE(x86cpu, telemetry_cpu_ids);
+
+static inline int telem_get_unitconfig(enum telemetry_unit telem_unit,
+				     struct telemetry_unit_config **unit_config)
+{
+	if (telem_unit == TELEM_PSS)
+		*unit_config = &(telm_conf->pss_config);
+	else if (telem_unit == TELEM_IOSS)
+		*unit_config = &(telm_conf->ioss_config);
+	else
+		return -EINVAL;
+
+	return 0;
+
+}
+
+static int telemetry_check_evtid(enum telemetry_unit telem_unit,
+				 u32 *evtmap, u8 len,
+				 enum telemetry_action action)
+{
+	struct telemetry_unit_config *unit_config;
+	int ret;
+
+	ret = telem_get_unitconfig(telem_unit, &unit_config);
+	if (ret < 0)
+		return ret;
+
+	switch (action) {
+	case TELEM_RESET:
+		if (len > TELEM_MAX_EVENTS_SRAM)
+			return -EINVAL;
+
+		break;
+
+	case TELEM_UPDATE:
+		if (len > TELEM_MAX_EVENTS_SRAM)
+			return -EINVAL;
+
+		if ((len > 0) && (evtmap == NULL))
+			return -EINVAL;
+
+		break;
+
+	case TELEM_ADD:
+		if ((len + unit_config->ssram_evts_used) >
+		    TELEM_MAX_EVENTS_SRAM)
+			return -EINVAL;
+
+		if ((len > 0) && (evtmap == NULL))
+			return -EINVAL;
+
+		break;
+
+	default:
+		pr_err("Unknown Telemetry action Specified %d\n", action);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+
+static inline int telemetry_plt_config_ioss_event(u32 evt_id, int index)
+{
+	u32 write_buf;
+	int ret;
+
+	write_buf = evt_id | TELEM_EVENT_ENABLE;
+	write_buf <<= BITS_PER_BYTE;
+	write_buf |= index;
+
+	ret = intel_pmc_ipc_command(PMC_IPC_PMC_TELEMTRY,
+				    IOSS_TELEM_EVENT_WRITE, (u8 *)&write_buf,
+				    IOSS_TELEM_EVT_WRITE_SIZE, NULL, 0);
+
+	return ret;
+}
+
+static inline int telemetry_plt_config_pss_event(u32 evt_id, int index)
+{
+	u32 write_buf;
+	int ret;
+
+	write_buf = evt_id | TELEM_EVENT_ENABLE;
+	ret = intel_punit_ipc_command(IPC_PUNIT_BIOS_WRITE_TELE_EVENT,
+				      index, 0, &write_buf, NULL);
+
+	return ret;
+}
+
+static int telemetry_setup_iossevtconfig(struct telemetry_evtconfig evtconfig,
+					 enum telemetry_action action)
+{
+	u8 num_ioss_evts, ioss_period;
+	int ret, index, idx;
+	u32 *ioss_evtmap;
+	u32 telem_ctrl;
+
+	num_ioss_evts = evtconfig.num_evts;
+	ioss_period = evtconfig.period;
+	ioss_evtmap = evtconfig.evtmap;
+
+	/* Get telemetry EVENT CTL */
+	ret = intel_pmc_ipc_command(PMC_IPC_PMC_TELEMTRY,
+				    IOSS_TELEM_EVENT_CTL_READ, NULL, 0,
+				    &telem_ctrl, IOSS_TELEM_READ_WORD);
+	if (ret) {
+		pr_err("IOSS TELEM_CTRL Read Failed\n");
+		return ret;
+	}
+
+	/* Disable Telemetry */
+	TELEM_DISABLE(telem_ctrl);
+
+	ret = intel_pmc_ipc_command(PMC_IPC_PMC_TELEMTRY,
+				    IOSS_TELEM_EVENT_CTL_WRITE,
+				    (u8 *)&telem_ctrl,
+				    IOSS_TELEM_EVT_CTRL_WRITE_SIZE,
+				    NULL, 0);
+	if (ret) {
+		pr_err("IOSS TELEM_CTRL Event Disable Write Failed\n");
+		return ret;
+	}
+
+
+	/* Reset Everything */
+	if (action == TELEM_RESET) {
+		/* Clear All Events */
+		TELEM_CLEAR_EVENTS(telem_ctrl);
+
+		ret = intel_pmc_ipc_command(PMC_IPC_PMC_TELEMTRY,
+					    IOSS_TELEM_EVENT_CTL_WRITE,
+					    (u8 *)&telem_ctrl,
+					    IOSS_TELEM_EVT_CTRL_WRITE_SIZE,
+					    NULL, 0);
+		if (ret) {
+			pr_err("IOSS TELEM_CTRL Event Disable Write Failed\n");
+			return ret;
+		}
+		telm_conf->ioss_config.ssram_evts_used = 0;
+
+		/* Configure Events */
+		for (idx = 0; idx < num_ioss_evts; idx++) {
+			if (telemetry_plt_config_ioss_event(
+			    telm_conf->ioss_config.telem_evts[idx].evt_id,
+			    idx)) {
+				pr_err("IOSS TELEM_RESET Fail for data: %x\n",
+				telm_conf->ioss_config.telem_evts[idx].evt_id);
+				continue;
+			}
+			telm_conf->ioss_config.ssram_evts_used++;
+		}
+	}
+
+	/* Re-Configure Everything */
+	if (action == TELEM_UPDATE) {
+		/* Clear All Events */
+		TELEM_CLEAR_EVENTS(telem_ctrl);
+
+		ret = intel_pmc_ipc_command(PMC_IPC_PMC_TELEMTRY,
+					    IOSS_TELEM_EVENT_CTL_WRITE,
+					    (u8 *)&telem_ctrl,
+					    IOSS_TELEM_EVT_CTRL_WRITE_SIZE,
+					    NULL, 0);
+		if (ret) {
+			pr_err("IOSS TELEM_CTRL Event Disable Write Failed\n");
+			return ret;
+		}
+		telm_conf->ioss_config.ssram_evts_used = 0;
+
+		/* Configure Events */
+		for (index = 0; index < num_ioss_evts; index++) {
+			telm_conf->ioss_config.telem_evts[index].evt_id =
+			ioss_evtmap[index];
+
+			if (telemetry_plt_config_ioss_event(
+			    telm_conf->ioss_config.telem_evts[index].evt_id,
+			    index)) {
+				pr_err("IOSS TELEM_UPDATE Fail for Evt%x\n",
+					ioss_evtmap[index]);
+				continue;
+			}
+			telm_conf->ioss_config.ssram_evts_used++;
+		}
+	}
+
+	/* Add some Events */
+	if (action == TELEM_ADD) {
+		/* Configure Events */
+		for (index = telm_conf->ioss_config.ssram_evts_used, idx = 0;
+		     idx < num_ioss_evts; index++, idx++) {
+			telm_conf->ioss_config.telem_evts[index].evt_id =
+			ioss_evtmap[idx];
+
+			if (telemetry_plt_config_ioss_event(
+			    telm_conf->ioss_config.telem_evts[index].evt_id,
+			    index)) {
+				pr_err("IOSS TELEM_ADD Fail for Event %x\n",
+					ioss_evtmap[idx]);
+				continue;
+			}
+			telm_conf->ioss_config.ssram_evts_used++;
+		}
+	}
+
+	/* Enable Periodic Telemetry Events and enable SRAM trace */
+	TELEM_CLEAR_SAMPLE_PERIOD(telem_ctrl);
+	TELEM_ENABLE_SRAM_EVT_TRACE(telem_ctrl);
+	TELEM_ENABLE_PERIODIC(telem_ctrl);
+	telem_ctrl |= ioss_period;
+
+	ret = intel_pmc_ipc_command(PMC_IPC_PMC_TELEMTRY,
+				    IOSS_TELEM_EVENT_CTL_WRITE,
+				    (u8 *)&telem_ctrl,
+				    IOSS_TELEM_EVT_CTRL_WRITE_SIZE, NULL, 0);
+	if (ret) {
+		pr_err("IOSS TELEM_CTRL Event Enable Write Failed\n");
+		return ret;
+	}
+
+	telm_conf->ioss_config.curr_period = ioss_period;
+
+	return 0;
+}
+
+
+static int telemetry_setup_pssevtconfig(struct telemetry_evtconfig evtconfig,
+					enum telemetry_action action)
+{
+	u8 num_pss_evts, pss_period;
+	int ret, index, idx;
+	u32 *pss_evtmap;
+	u32 telem_ctrl;
+
+	num_pss_evts = evtconfig.num_evts;
+	pss_period = evtconfig.period;
+	pss_evtmap = evtconfig.evtmap;
+
+	/* PSS Config */
+	/* Get telemetry EVENT CTL */
+	ret = intel_punit_ipc_command(IPC_PUNIT_BIOS_READ_TELE_EVENT_CTRL,
+				      0, 0, NULL, &telem_ctrl);
+	if (ret) {
+		pr_err("PSS TELEM_CTRL Read Failed\n");
+		return ret;
+	}
+
+	/* Disable Telemetry */
+	TELEM_DISABLE(telem_ctrl);
+	ret = intel_punit_ipc_command(IPC_PUNIT_BIOS_WRITE_TELE_EVENT_CTRL,
+				      0, 0, &telem_ctrl, NULL);
+	if (ret) {
+		pr_err("PSS TELEM_CTRL Event Disable Write Failed\n");
+		return ret;
+	}
+
+	/* Reset Everything */
+	if (action == TELEM_RESET) {
+		/* Clear All Events */
+		TELEM_CLEAR_EVENTS(telem_ctrl);
+
+		ret = intel_punit_ipc_command(
+				IPC_PUNIT_BIOS_WRITE_TELE_EVENT_CTRL,
+				0, 0, &telem_ctrl, NULL);
+		if (ret) {
+			pr_err("PSS TELEM_CTRL Event Disable Write Failed\n");
+			return ret;
+		}
+		telm_conf->pss_config.ssram_evts_used = 0;
+		/* Configure Events */
+		for (idx = 0; idx < num_pss_evts; idx++) {
+			if (telemetry_plt_config_pss_event(
+			    telm_conf->pss_config.telem_evts[idx].evt_id,
+			    idx)) {
+				pr_err("PSS TELEM_RESET Fail for Event %x\n",
+				telm_conf->pss_config.telem_evts[idx].evt_id);
+				continue;
+			}
+			telm_conf->pss_config.ssram_evts_used++;
+		}
+	}
+
+	/* Re-Configure Everything */
+	if (action == TELEM_UPDATE) {
+		/* Clear All Events */
+		TELEM_CLEAR_EVENTS(telem_ctrl);
+
+		ret = intel_punit_ipc_command(
+				IPC_PUNIT_BIOS_WRITE_TELE_EVENT_CTRL,
+				0, 0, &telem_ctrl, NULL);
+		if (ret) {
+			pr_err("PSS TELEM_CTRL Event Disable Write Failed\n");
+			return ret;
+		}
+		telm_conf->pss_config.ssram_evts_used = 0;
+
+		/* Configure Events */
+		for (index = 0; index < num_pss_evts; index++) {
+			telm_conf->pss_config.telem_evts[index].evt_id =
+			pss_evtmap[index];
+
+			if (telemetry_plt_config_pss_event(
+			    telm_conf->pss_config.telem_evts[index].evt_id,
+			    index)) {
+				pr_err("PSS TELEM_UPDATE Fail for Event %x\n",
+					pss_evtmap[index]);
+				continue;
+			}
+			telm_conf->pss_config.ssram_evts_used++;
+		}
+	}
+
+	/* Add some Events */
+	if (action == TELEM_ADD) {
+		/* Configure Events */
+		for (index = telm_conf->pss_config.ssram_evts_used, idx = 0;
+		     idx < num_pss_evts; index++, idx++) {
+
+			telm_conf->pss_config.telem_evts[index].evt_id =
+			pss_evtmap[idx];
+
+			if (telemetry_plt_config_pss_event(
+			    telm_conf->pss_config.telem_evts[index].evt_id,
+			    index)) {
+				pr_err("PSS TELEM_ADD Fail for Event %x\n",
+					pss_evtmap[idx]);
+				continue;
+			}
+			telm_conf->pss_config.ssram_evts_used++;
+		}
+	}
+
+	/* Enable Periodic Telemetry Events and enable SRAM trace */
+	TELEM_CLEAR_SAMPLE_PERIOD(telem_ctrl);
+	TELEM_ENABLE_SRAM_EVT_TRACE(telem_ctrl);
+	TELEM_ENABLE_PERIODIC(telem_ctrl);
+	telem_ctrl |= pss_period;
+
+	ret = intel_punit_ipc_command(IPC_PUNIT_BIOS_WRITE_TELE_EVENT_CTRL,
+				      0, 0, &telem_ctrl, NULL);
+	if (ret) {
+		pr_err("PSS TELEM_CTRL Event Enable Write Failed\n");
+		return ret;
+	}
+
+	telm_conf->pss_config.curr_period = pss_period;
+
+	return 0;
+}
+
+static int telemetry_setup_evtconfig(struct telemetry_evtconfig pss_evtconfig,
+				     struct telemetry_evtconfig ioss_evtconfig,
+				     enum telemetry_action action)
+{
+	int ret;
+
+	mutex_lock(&(telm_conf->telem_lock));
+
+	if ((action == TELEM_UPDATE) && (telm_conf->telem_in_use)) {
+		ret = -EBUSY;
+		goto out;
+	}
+
+	ret = telemetry_check_evtid(TELEM_PSS, pss_evtconfig.evtmap,
+				    pss_evtconfig.num_evts, action);
+	if (ret)
+		goto out;
+
+	ret = telemetry_check_evtid(TELEM_IOSS, ioss_evtconfig.evtmap,
+				    ioss_evtconfig.num_evts, action);
+	if (ret)
+		goto out;
+
+	if (ioss_evtconfig.num_evts) {
+		ret = telemetry_setup_iossevtconfig(ioss_evtconfig, action);
+		if (ret)
+			goto out;
+	}
+
+	if (pss_evtconfig.num_evts) {
+		ret = telemetry_setup_pssevtconfig(pss_evtconfig, action);
+		if (ret)
+			goto out;
+	}
+
+	if ((action == TELEM_UPDATE) || (action == TELEM_ADD))
+		telm_conf->telem_in_use = true;
+	else
+		telm_conf->telem_in_use = false;
+
+out:
+	mutex_unlock(&(telm_conf->telem_lock));
+	return ret;
+}
+
+static int telemetry_setup(struct platform_device *pdev)
+{
+	struct telemetry_evtconfig pss_evtconfig, ioss_evtconfig;
+	u32 read_buf, events, event_regs;
+	int ret;
+
+	ret = intel_pmc_ipc_command(PMC_IPC_PMC_TELEMTRY, IOSS_TELEM_INFO_READ,
+				    NULL, 0, &read_buf, IOSS_TELEM_READ_WORD);
+	if (ret) {
+		dev_err(&pdev->dev, "IOSS TELEM_INFO Read Failed\n");
+		return ret;
+	}
+
+	/* Get telemetry Info */
+	events = (read_buf & TELEM_INFO_SRAMEVTS_MASK) >>
+		  TELEM_INFO_SRAMEVTS_SHIFT;
+	event_regs = read_buf & TELEM_INFO_NENABLES_MASK;
+	if ((events < TELEM_MAX_EVENTS_SRAM) ||
+	    (event_regs < TELEM_MAX_EVENTS_SRAM)) {
+		dev_err(&pdev->dev, "IOSS:Insufficient Space for SRAM Trace\n");
+		dev_err(&pdev->dev, "SRAM Events %d; Event Regs %d\n",
+			events, event_regs);
+		return -ENOMEM;
+	}
+
+	telm_conf->ioss_config.min_period = TELEM_MIN_PERIOD(read_buf);
+	telm_conf->ioss_config.max_period = TELEM_MAX_PERIOD(read_buf);
+
+	/* PUNIT Mailbox Setup */
+	ret = intel_punit_ipc_command(IPC_PUNIT_BIOS_READ_TELE_INFO, 0, 0,
+				      NULL, &read_buf);
+	if (ret) {
+		dev_err(&pdev->dev, "PSS TELEM_INFO Read Failed\n");
+		return ret;
+	}
+
+	/* Get telemetry Info */
+	events = (read_buf & TELEM_INFO_SRAMEVTS_MASK) >>
+		  TELEM_INFO_SRAMEVTS_SHIFT;
+	event_regs = read_buf & TELEM_INFO_SRAMEVTS_MASK;
+	if ((events < TELEM_MAX_EVENTS_SRAM) ||
+	    (event_regs < TELEM_MAX_EVENTS_SRAM)) {
+		dev_err(&pdev->dev, "PSS:Insufficient Space for SRAM Trace\n");
+		dev_err(&pdev->dev, "SRAM Events %d; Event Regs %d\n",
+			events, event_regs);
+		return -ENOMEM;
+	}
+
+	telm_conf->pss_config.min_period = TELEM_MIN_PERIOD(read_buf);
+	telm_conf->pss_config.max_period = TELEM_MAX_PERIOD(read_buf);
+
+	pss_evtconfig.evtmap = NULL;
+	pss_evtconfig.num_evts = TELEM_MAX_OS_ALLOCATED_EVENTS;
+	pss_evtconfig.period = TELEM_SAMPLING_DEFAULT_PERIOD;
+
+	ioss_evtconfig.evtmap = NULL;
+	ioss_evtconfig.num_evts = TELEM_MAX_OS_ALLOCATED_EVENTS;
+	ioss_evtconfig.period = TELEM_SAMPLING_DEFAULT_PERIOD;
+
+	ret = telemetry_setup_evtconfig(pss_evtconfig, ioss_evtconfig,
+					TELEM_RESET);
+	if (ret) {
+		dev_err(&pdev->dev, "TELEMTRY Setup Failed\n");
+		return ret;
+	}
+	return 0;
+}
+
+static int telemetry_plt_update_events(struct telemetry_evtconfig pss_evtconfig,
+				struct telemetry_evtconfig ioss_evtconfig)
+{
+	int ret;
+
+	if ((pss_evtconfig.num_evts > 0) &&
+	    (TELEM_SAMPLE_PERIOD_INVALID(pss_evtconfig.period))) {
+		pr_err("PSS Sampling Period Out of Range\n");
+		return -EINVAL;
+	}
+
+	if ((ioss_evtconfig.num_evts > 0) &&
+	    (TELEM_SAMPLE_PERIOD_INVALID(ioss_evtconfig.period))) {
+		pr_err("IOSS Sampling Period Out of Range\n");
+		return -EINVAL;
+	}
+
+	ret = telemetry_setup_evtconfig(pss_evtconfig, ioss_evtconfig,
+					TELEM_UPDATE);
+	if (ret)
+		pr_err("TELEMTRY Config Failed\n");
+
+	return ret;
+}
+
+
+static int telemetry_plt_set_sampling_period(u8 pss_period, u8 ioss_period)
+{
+	u32 telem_ctrl = 0;
+	int ret;
+
+	mutex_lock(&(telm_conf->telem_lock));
+	if (ioss_period) {
+		if (TELEM_SAMPLE_PERIOD_INVALID(ioss_period)) {
+			pr_err("IOSS Sampling Period Out of Range\n");
+			ret = -EINVAL;
+			goto out;
+		}
+
+		/* Get telemetry EVENT CTL */
+		ret = intel_pmc_ipc_command(PMC_IPC_PMC_TELEMTRY,
+					    IOSS_TELEM_EVENT_CTL_READ, NULL, 0,
+					    &telem_ctrl, IOSS_TELEM_READ_WORD);
+		if (ret) {
+			pr_err("IOSS TELEM_CTRL Read Failed\n");
+			goto out;
+		}
+
+		/* Disable Telemetry */
+		TELEM_DISABLE(telem_ctrl);
+
+		ret = intel_pmc_ipc_command(PMC_IPC_PMC_TELEMTRY,
+					    IOSS_TELEM_EVENT_CTL_WRITE,
+					    (u8 *)&telem_ctrl,
+					    IOSS_TELEM_EVT_CTRL_WRITE_SIZE,
+					    NULL, 0);
+		if (ret) {
+			pr_err("IOSS TELEM_CTRL Event Disable Write Failed\n");
+			goto out;
+		}
+
+		/* Enable Periodic Telemetry Events and enable SRAM trace */
+		TELEM_CLEAR_SAMPLE_PERIOD(telem_ctrl);
+		TELEM_ENABLE_SRAM_EVT_TRACE(telem_ctrl);
+		TELEM_ENABLE_PERIODIC(telem_ctrl);
+		telem_ctrl |= ioss_period;
+
+		ret = intel_pmc_ipc_command(PMC_IPC_PMC_TELEMTRY,
+					    IOSS_TELEM_EVENT_CTL_WRITE,
+					    (u8 *)&telem_ctrl,
+					    IOSS_TELEM_EVT_CTRL_WRITE_SIZE,
+					    NULL, 0);
+		if (ret) {
+			pr_err("IOSS TELEM_CTRL Event Enable Write Failed\n");
+			goto out;
+		}
+		telm_conf->ioss_config.curr_period = ioss_period;
+	}
+
+	if (pss_period) {
+		if (TELEM_SAMPLE_PERIOD_INVALID(pss_period)) {
+			pr_err("PSS Sampling Period Out of Range\n");
+			ret = -EINVAL;
+			goto out;
+		}
+
+		/* Get telemetry EVENT CTL */
+		ret = intel_punit_ipc_command(
+				IPC_PUNIT_BIOS_READ_TELE_EVENT_CTRL,
+				0, 0, NULL, &telem_ctrl);
+		if (ret) {
+			pr_err("PSS TELEM_CTRL Read Failed\n");
+			goto out;
+		}
+
+		/* Disable Telemetry */
+		TELEM_DISABLE(telem_ctrl);
+		ret = intel_punit_ipc_command(
+				IPC_PUNIT_BIOS_WRITE_TELE_EVENT_CTRL,
+				0, 0, &telem_ctrl, NULL);
+		if (ret) {
+			pr_err("PSS TELEM_CTRL Event Disable Write Failed\n");
+			goto out;
+		}
+
+		/* Enable Periodic Telemetry Events and enable SRAM trace */
+		TELEM_CLEAR_SAMPLE_PERIOD(telem_ctrl);
+		TELEM_ENABLE_SRAM_EVT_TRACE(telem_ctrl);
+		TELEM_ENABLE_PERIODIC(telem_ctrl);
+		telem_ctrl |= pss_period;
+
+		ret = intel_punit_ipc_command(
+				IPC_PUNIT_BIOS_WRITE_TELE_EVENT_CTRL,
+				0, 0, &telem_ctrl, NULL);
+		if (ret) {
+			pr_err("PSS TELEM_CTRL Event Enable Write Failed\n");
+			goto out;
+		}
+		telm_conf->pss_config.curr_period = pss_period;
+	}
+
+out:
+	mutex_unlock(&(telm_conf->telem_lock));
+	return ret;
+}
+
+
+static int telemetry_plt_get_sampling_period(u8 *pss_min_period,
+					     u8 *pss_max_period,
+					     u8 *ioss_min_period,
+					     u8 *ioss_max_period)
+{
+	*pss_min_period = telm_conf->pss_config.min_period;
+	*pss_max_period = telm_conf->pss_config.max_period;
+	*ioss_min_period = telm_conf->ioss_config.min_period;
+	*ioss_max_period = telm_conf->ioss_config.max_period;
+
+	return 0;
+}
+
+
+static int telemetry_plt_reset_events(void)
+{
+	struct telemetry_evtconfig pss_evtconfig, ioss_evtconfig;
+	int ret;
+
+	pss_evtconfig.evtmap = NULL;
+	pss_evtconfig.num_evts = TELEM_MAX_OS_ALLOCATED_EVENTS;
+	pss_evtconfig.period = TELEM_SAMPLING_DEFAULT_PERIOD;
+
+	ioss_evtconfig.evtmap = NULL;
+	ioss_evtconfig.num_evts = TELEM_MAX_OS_ALLOCATED_EVENTS;
+	ioss_evtconfig.period = TELEM_SAMPLING_DEFAULT_PERIOD;
+
+	ret = telemetry_setup_evtconfig(pss_evtconfig, ioss_evtconfig,
+					TELEM_RESET);
+	if (ret)
+		pr_err("TELEMTRY Reset Failed\n");
+
+	return ret;
+}
+
+
+static int telemetry_plt_get_eventconfig(struct telemetry_evtconfig *pss_config,
+					struct telemetry_evtconfig *ioss_config,
+					int pss_len, int ioss_len)
+{
+	u32 *pss_evtmap, *ioss_evtmap;
+	u32 index;
+
+	pss_evtmap = pss_config->evtmap;
+	ioss_evtmap = ioss_config->evtmap;
+
+	mutex_lock(&(telm_conf->telem_lock));
+	pss_config->num_evts = telm_conf->pss_config.ssram_evts_used;
+	ioss_config->num_evts = telm_conf->ioss_config.ssram_evts_used;
+
+	pss_config->period = telm_conf->pss_config.curr_period;
+	ioss_config->period = telm_conf->ioss_config.curr_period;
+
+	if ((pss_len < telm_conf->pss_config.ssram_evts_used) ||
+	    (ioss_len < telm_conf->ioss_config.ssram_evts_used)) {
+		mutex_unlock(&(telm_conf->telem_lock));
+		return -EINVAL;
+	}
+
+	for (index = 0; index < telm_conf->pss_config.ssram_evts_used;
+	     index++) {
+		pss_evtmap[index] =
+		telm_conf->pss_config.telem_evts[index].evt_id;
+	}
+
+	for (index = 0; index < telm_conf->ioss_config.ssram_evts_used;
+	     index++) {
+		ioss_evtmap[index] =
+		telm_conf->ioss_config.telem_evts[index].evt_id;
+	}
+
+	mutex_unlock(&(telm_conf->telem_lock));
+	return 0;
+}
+
+
+static int telemetry_plt_add_events(u8 num_pss_evts, u8 num_ioss_evts,
+				    u32 *pss_evtmap, u32 *ioss_evtmap)
+{
+	struct telemetry_evtconfig pss_evtconfig, ioss_evtconfig;
+	int ret;
+
+	pss_evtconfig.evtmap = pss_evtmap;
+	pss_evtconfig.num_evts = num_pss_evts;
+	pss_evtconfig.period = telm_conf->pss_config.curr_period;
+
+	ioss_evtconfig.evtmap = ioss_evtmap;
+	ioss_evtconfig.num_evts = num_ioss_evts;
+	ioss_evtconfig.period = telm_conf->ioss_config.curr_period;
+
+	ret = telemetry_setup_evtconfig(pss_evtconfig, ioss_evtconfig,
+					TELEM_ADD);
+	if (ret)
+		pr_err("TELEMTRY ADD Failed\n");
+
+	return ret;
+}
+
+static int telem_evtlog_read(enum telemetry_unit telem_unit,
+			     struct telem_ssram_region *ssram_region, u8 len)
+{
+	struct telemetry_unit_config *unit_config;
+	u64 timestamp_prev, timestamp_next;
+	int ret, index, timeout = 0;
+
+	ret = telem_get_unitconfig(telem_unit, &unit_config);
+	if (ret < 0)
+		return ret;
+
+	if (len > unit_config->ssram_evts_used)
+		len = unit_config->ssram_evts_used;
+
+	do {
+		timestamp_prev = readq(unit_config->regmap);
+		if (!timestamp_prev) {
+			pr_err("Ssram under update. Please Try Later\n");
+			return -EBUSY;
+		}
+
+		ssram_region->start_time = readq(unit_config->regmap +
+						 TELEM_SSRAM_STARTTIME_OFFSET);
+
+		for (index = 0; index < len; index++) {
+			ssram_region->events[index] =
+			readq(unit_config->regmap + TELEM_SSRAM_EVTLOG_OFFSET +
+			      BYTES_PER_LONG*index);
+		}
+
+		timestamp_next = readq(unit_config->regmap);
+		if (!timestamp_next) {
+			pr_err("Ssram under update. Please Try Later\n");
+			return -EBUSY;
+		}
+
+		if (timeout++ > TELEM_SSRAM_READ_TIMEOUT) {
+			pr_err("Timeout while reading Events\n");
+			return -EBUSY;
+		}
+
+	} while (timestamp_prev != timestamp_next);
+
+	ssram_region->timestamp = timestamp_next;
+
+	return len;
+}
+
+static int telemetry_plt_raw_read_eventlog(enum telemetry_unit telem_unit,
+					   struct telemetry_evtlog *evtlog,
+					   int len, int log_all_evts)
+{
+	int index, idx1, ret, readlen = len;
+	struct telem_ssram_region ssram_region;
+	struct telemetry_evtmap *evtmap;
+
+	switch (telem_unit)	{
+	case TELEM_PSS:
+		evtmap = telm_conf->pss_config.telem_evts;
+		break;
+
+	case TELEM_IOSS:
+		evtmap = telm_conf->ioss_config.telem_evts;
+		break;
+
+	default:
+		pr_err("Unknown Telemetry Unit Specified %d\n", telem_unit);
+		return -EINVAL;
+	}
+
+	if (!log_all_evts)
+		readlen = TELEM_MAX_EVENTS_SRAM;
+
+	ret = telem_evtlog_read(telem_unit, &ssram_region, readlen);
+	if (ret < 0)
+		return ret;
+
+	/* Invalid evt-id array specified via length mismatch */
+	if ((!log_all_evts) && (len > ret))
+		return -EINVAL;
+
+	if (log_all_evts)
+		for (index = 0; index < ret; index++) {
+			evtlog[index].telem_evtlog = ssram_region.events[index];
+			evtlog[index].telem_evtid = evtmap[index].evt_id;
+		}
+	else
+		for (index = 0, readlen = 0; (index < ret) && (readlen < len);
+		     index++) {
+			for (idx1 = 0; idx1 < len; idx1++) {
+				/* Elements matched */
+				if (evtmap[index].evt_id ==
+				    evtlog[idx1].telem_evtid) {
+					evtlog[idx1].telem_evtlog =
+					ssram_region.events[index];
+					readlen++;
+
+					break;
+				}
+			}
+		}
+
+	return readlen;
+}
+
+static int telemetry_plt_read_eventlog(enum telemetry_unit telem_unit,
+		struct telemetry_evtlog *evtlog, int len, int log_all_evts)
+{
+	int ret;
+
+	mutex_lock(&(telm_conf->telem_lock));
+	ret = telemetry_plt_raw_read_eventlog(telem_unit, evtlog,
+					      len, log_all_evts);
+	mutex_unlock(&(telm_conf->telem_lock));
+
+	return ret;
+}
+
+static int telemetry_plt_get_trace_verbosity(enum telemetry_unit telem_unit,
+					     u32 *verbosity)
+{
+	u32 temp = 0;
+	int ret;
+
+	if (verbosity == NULL)
+		return -EINVAL;
+
+	mutex_lock(&(telm_conf->telem_trace_lock));
+	switch (telem_unit) {
+	case TELEM_PSS:
+		ret = intel_punit_ipc_command(
+				IPC_PUNIT_BIOS_READ_TELE_TRACE_CTRL,
+				0, 0, NULL, &temp);
+		if (ret) {
+			pr_err("PSS TRACE_CTRL Read Failed\n");
+			goto out;
+		}
+
+		break;
+
+	case TELEM_IOSS:
+		ret = intel_pmc_ipc_command(PMC_IPC_PMC_TELEMTRY,
+				IOSS_TELEM_TRACE_CTL_READ, NULL, 0, &temp,
+				IOSS_TELEM_READ_WORD);
+		if (ret) {
+			pr_err("IOSS TRACE_CTL Read Failed\n");
+			goto out;
+		}
+
+		break;
+
+	default:
+		pr_err("Unknown Telemetry Unit Specified %d\n", telem_unit);
+		ret = -EINVAL;
+		break;
+	}
+	TELEM_EXTRACT_VERBOSITY(temp, *verbosity);
+
+out:
+	mutex_unlock(&(telm_conf->telem_trace_lock));
+	return ret;
+}
+
+static int telemetry_plt_set_trace_verbosity(enum telemetry_unit telem_unit,
+					     u32 verbosity)
+{
+	u32 temp = 0;
+	int ret;
+
+	verbosity &= TELEM_TRC_VERBOSITY_MASK;
+
+	mutex_lock(&(telm_conf->telem_trace_lock));
+	switch (telem_unit) {
+	case TELEM_PSS:
+		ret = intel_punit_ipc_command(
+				IPC_PUNIT_BIOS_WRITE_TELE_TRACE_CTRL,
+				0, 0, &verbosity, NULL);
+		if (ret) {
+			pr_err("PSS TRACE_CTRL Verbosity Set Failed\n");
+			goto out;
+		}
+		break;
+
+	case TELEM_IOSS:
+		ret = intel_pmc_ipc_command(PMC_IPC_PMC_TELEMTRY,
+				IOSS_TELEM_TRACE_CTL_READ, NULL, 0, &temp,
+				IOSS_TELEM_READ_WORD);
+		if (ret) {
+			pr_err("IOSS TRACE_CTL Read Failed\n");
+			goto out;
+		}
+
+		TELEM_CLEAR_VERBOSITY_BITS(temp);
+		TELEM_SET_VERBOSITY_BITS(temp, verbosity);
+
+		ret = intel_pmc_ipc_command(PMC_IPC_PMC_TELEMTRY,
+				IOSS_TELEM_TRACE_CTL_WRITE, (u8 *)&temp,
+				IOSS_TELEM_WRITE_FOURBYTES, NULL, 0);
+		if (ret) {
+			pr_err("IOSS TRACE_CTL Verbosity Set Failed\n");
+			goto out;
+		}
+		break;
+
+	default:
+		pr_err("Unknown Telemetry Unit Specified %d\n", telem_unit);
+		ret = -EINVAL;
+		break;
+	}
+
+out:
+	mutex_unlock(&(telm_conf->telem_trace_lock));
+	return ret;
+}
+
+static struct telemetry_core_ops telm_pltops = {
+	.get_trace_verbosity = telemetry_plt_get_trace_verbosity,
+	.set_trace_verbosity = telemetry_plt_set_trace_verbosity,
+	.set_sampling_period = telemetry_plt_set_sampling_period,
+	.get_sampling_period = telemetry_plt_get_sampling_period,
+	.raw_read_eventlog = telemetry_plt_raw_read_eventlog,
+	.get_eventconfig = telemetry_plt_get_eventconfig,
+	.update_events = telemetry_plt_update_events,
+	.read_eventlog = telemetry_plt_read_eventlog,
+	.reset_events = telemetry_plt_reset_events,
+	.add_events = telemetry_plt_add_events,
+};
+
+static int telemetry_pltdrv_probe(struct platform_device *pdev)
+{
+	struct resource *res0 = NULL, *res1 = NULL;
+	const struct x86_cpu_id *id;
+	int size, ret = -ENOMEM;
+
+	id = x86_match_cpu(telemetry_cpu_ids);
+	if (!id)
+		return -ENODEV;
+
+	telm_conf = (struct telemetry_plt_config *)id->driver_data;
+
+	res0 = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res0) {
+		ret = -EINVAL;
+		goto out;
+	}
+	size = resource_size(res0);
+	if (!devm_request_mem_region(&pdev->dev, res0->start, size,
+				     pdev->name)) {
+		ret = -EBUSY;
+		goto out;
+	}
+	telm_conf->pss_config.ssram_base_addr = res0->start;
+	telm_conf->pss_config.ssram_size = size;
+
+	res1 = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+	if (!res1) {
+		ret = -EINVAL;
+		goto out;
+	}
+	size = resource_size(res1);
+	if (!devm_request_mem_region(&pdev->dev, res1->start, size,
+				     pdev->name)) {
+		ret = -EBUSY;
+		goto out;
+	}
+
+	telm_conf->ioss_config.ssram_base_addr = res1->start;
+	telm_conf->ioss_config.ssram_size = size;
+
+	telm_conf->pss_config.regmap = ioremap_nocache(
+					telm_conf->pss_config.ssram_base_addr,
+					telm_conf->pss_config.ssram_size);
+	if (!telm_conf->pss_config.regmap) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	telm_conf->ioss_config.regmap = ioremap_nocache(
+				telm_conf->ioss_config.ssram_base_addr,
+				telm_conf->ioss_config.ssram_size);
+	if (!telm_conf->ioss_config.regmap) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	mutex_init(&telm_conf->telem_lock);
+	mutex_init(&telm_conf->telem_trace_lock);
+
+	ret = telemetry_setup(pdev);
+	if (ret)
+		goto out;
+
+	ret = telemetry_set_pltdata(&telm_pltops, telm_conf);
+	if (ret) {
+		dev_err(&pdev->dev, "TELEMTRY Set Pltops Failed.\n");
+		goto out;
+	}
+
+	return 0;
+
+out:
+	if (res0)
+		release_mem_region(res0->start, resource_size(res0));
+	if (res1)
+		release_mem_region(res1->start, resource_size(res1));
+	if (telm_conf->pss_config.regmap)
+		iounmap(telm_conf->pss_config.regmap);
+	if (telm_conf->ioss_config.regmap)
+		iounmap(telm_conf->ioss_config.regmap);
+	dev_err(&pdev->dev, "TELEMTRY Setup Failed.\n");
+
+	return ret;
+}
+
+static int telemetry_pltdrv_remove(struct platform_device *pdev)
+{
+	telemetry_clear_pltdata();
+	iounmap(telm_conf->pss_config.regmap);
+	iounmap(telm_conf->ioss_config.regmap);
+
+	return 0;
+}
+
+static struct platform_driver telemetry_soc_driver = {
+	.probe		= telemetry_pltdrv_probe,
+	.remove		= telemetry_pltdrv_remove,
+	.driver		= {
+		.name	= DRIVER_NAME,
+	},
+};
+
+static int __init telemetry_module_init(void)
+{
+	pr_info(DRIVER_NAME ": version %s loaded\n", DRIVER_VERSION);
+	return platform_driver_register(&telemetry_soc_driver);
+}
+
+static void __exit telemetry_module_exit(void)
+{
+	platform_driver_unregister(&telemetry_soc_driver);
+}
+
+device_initcall(telemetry_module_init);
+module_exit(telemetry_module_exit);
+
+MODULE_AUTHOR("Souvik Kumar Chakravarty <souvik.k.chakravarty@intel.com>");
+MODULE_DESCRIPTION("Intel SoC Telemetry Platform Driver");
+MODULE_VERSION(DRIVER_VERSION);
+MODULE_LICENSE("GPL");
--- zfcpdump-kernel-4.4.orig/drivers/platform/x86/thinkpad_acpi.c
+++ zfcpdump-kernel-4.4/drivers/platform/x86/thinkpad_acpi.c
@@ -303,6 +303,7 @@ static struct {
 	u32 hotkey_mask:1;
 	u32 hotkey_wlsw:1;
 	u32 hotkey_tablet:1;
+	u32 kbdlight:1;
 	u32 light:1;
 	u32 light_status:1;
 	u32 bright_acpimode:1;
@@ -4986,6 +4987,207 @@ static struct ibm_struct video_driver_da
 #endif /* CONFIG_THINKPAD_ACPI_VIDEO */
 
 /*************************************************************************
+ * Keyboard backlight subdriver
+ */
+
+static int kbdlight_set_level(int level)
+{
+	if (!hkey_handle)
+		return -ENXIO;
+
+	if (!acpi_evalf(hkey_handle, NULL, "MLCS", "dd", level))
+		return -EIO;
+
+	return 0;
+}
+
+static int kbdlight_get_level(void)
+{
+	int status = 0;
+
+	if (!hkey_handle)
+		return -ENXIO;
+
+	if (!acpi_evalf(hkey_handle, &status, "MLCG", "dd", 0))
+		return -EIO;
+
+	if (status < 0)
+		return status;
+
+	return status & 0x3;
+}
+
+static bool kbdlight_is_supported(void)
+{
+	int status = 0;
+
+	if (!hkey_handle)
+		return false;
+
+	if (!acpi_has_method(hkey_handle, "MLCG")) {
+		vdbg_printk(TPACPI_DBG_INIT, "kbdlight MLCG is unavailable\n");
+		return false;
+	}
+
+	if (!acpi_evalf(hkey_handle, &status, "MLCG", "qdd", 0)) {
+		vdbg_printk(TPACPI_DBG_INIT, "kbdlight MLCG failed\n");
+		return false;
+	}
+
+	if (status < 0) {
+		vdbg_printk(TPACPI_DBG_INIT, "kbdlight MLCG err: %d\n", status);
+		return false;
+	}
+
+	vdbg_printk(TPACPI_DBG_INIT, "kbdlight MLCG returned 0x%x\n", status);
+	/*
+	 * Guessed test for keyboard backlight:
+	 *
+	 * Machines with backlight keyboard return:
+	 *   b010100000010000000XX - ThinkPad X1 Carbon 3rd
+	 *   b110100010010000000XX - ThinkPad x230
+	 *   b010100000010000000XX - ThinkPad x240
+	 *   b010100000010000000XX - ThinkPad W541
+	 * (XX is current backlight level)
+	 *
+	 * Machines without backlight keyboard return:
+	 *   b10100001000000000000 - ThinkPad x230
+	 *   b10110001000000000000 - ThinkPad E430
+	 *   b00000000000000000000 - ThinkPad E450
+	 *
+	 * Candidate BITs for detection test (XOR):
+	 *   b01000000001000000000
+	 *              ^
+	 */
+	return status & BIT(9);
+}
+
+static void kbdlight_set_worker(struct work_struct *work)
+{
+	struct tpacpi_led_classdev *data =
+			container_of(work, struct tpacpi_led_classdev, work);
+
+	if (likely(tpacpi_lifecycle == TPACPI_LIFE_RUNNING))
+		kbdlight_set_level(data->new_state);
+}
+
+static void kbdlight_sysfs_set(struct led_classdev *led_cdev,
+			enum led_brightness brightness)
+{
+	struct tpacpi_led_classdev *data =
+			container_of(led_cdev,
+				     struct tpacpi_led_classdev,
+				     led_classdev);
+	data->new_state = brightness;
+	queue_work(tpacpi_wq, &data->work);
+}
+
+static enum led_brightness kbdlight_sysfs_get(struct led_classdev *led_cdev)
+{
+	int level;
+
+	level = kbdlight_get_level();
+	if (level < 0)
+		return 0;
+
+	return level;
+}
+
+static struct tpacpi_led_classdev tpacpi_led_kbdlight = {
+	.led_classdev = {
+		.name		= "tpacpi::kbd_backlight",
+		.max_brightness	= 2,
+		.brightness_set	= &kbdlight_sysfs_set,
+		.brightness_get	= &kbdlight_sysfs_get,
+		.flags		= LED_CORE_SUSPENDRESUME,
+	}
+};
+
+static int __init kbdlight_init(struct ibm_init_struct *iibm)
+{
+	int rc;
+
+	vdbg_printk(TPACPI_DBG_INIT, "initializing kbdlight subdriver\n");
+
+	TPACPI_ACPIHANDLE_INIT(hkey);
+	INIT_WORK(&tpacpi_led_kbdlight.work, kbdlight_set_worker);
+
+	if (!kbdlight_is_supported()) {
+		tp_features.kbdlight = 0;
+		vdbg_printk(TPACPI_DBG_INIT, "kbdlight is unsupported\n");
+		return 1;
+	}
+
+	tp_features.kbdlight = 1;
+
+	rc = led_classdev_register(&tpacpi_pdev->dev,
+				   &tpacpi_led_kbdlight.led_classdev);
+	if (rc < 0) {
+		tp_features.kbdlight = 0;
+		return rc;
+	}
+
+	return 0;
+}
+
+static void kbdlight_exit(void)
+{
+	if (tp_features.kbdlight)
+		led_classdev_unregister(&tpacpi_led_kbdlight.led_classdev);
+	flush_workqueue(tpacpi_wq);
+}
+
+static int kbdlight_read(struct seq_file *m)
+{
+	int level;
+
+	if (!tp_features.kbdlight) {
+		seq_printf(m, "status:\t\tnot supported\n");
+	} else {
+		level = kbdlight_get_level();
+		if (level < 0)
+			seq_printf(m, "status:\t\terror %d\n", level);
+		else
+			seq_printf(m, "status:\t\t%d\n", level);
+		seq_printf(m, "commands:\t0, 1, 2\n");
+	}
+
+	return 0;
+}
+
+static int kbdlight_write(char *buf)
+{
+	char *cmd;
+	int level = -1;
+
+	if (!tp_features.kbdlight)
+		return -ENODEV;
+
+	while ((cmd = next_cmd(&buf))) {
+		if (strlencmp(cmd, "0") == 0)
+			level = 0;
+		else if (strlencmp(cmd, "1") == 0)
+			level = 1;
+		else if (strlencmp(cmd, "2") == 0)
+			level = 2;
+		else
+			return -EINVAL;
+	}
+
+	if (level == -1)
+		return -EINVAL;
+
+	return kbdlight_set_level(level);
+}
+
+static struct ibm_struct kbdlight_driver_data = {
+	.name = "kbdlight",
+	.read = kbdlight_read,
+	.write = kbdlight_write,
+	.exit = kbdlight_exit,
+};
+
+/*************************************************************************
  * Light (thinklight) subdriver
  */
 
@@ -9207,6 +9409,10 @@ static struct ibm_init_struct ibms_init[
 	},
 #endif
 	{
+		.init = kbdlight_init,
+		.data = &kbdlight_driver_data,
+	},
+	{
 		.init = light_init,
 		.data = &light_driver_data,
 	},
--- zfcpdump-kernel-4.4.orig/drivers/platform/x86/toshiba_acpi.c
+++ zfcpdump-kernel-4.4/drivers/platform/x86/toshiba_acpi.c
@@ -131,7 +131,7 @@ MODULE_LICENSE("GPL");
 /* Field definitions */
 #define HCI_ACCEL_MASK			0x7fff
 #define HCI_HOTKEY_DISABLE		0x0b
-#define HCI_HOTKEY_ENABLE		0x01
+#define HCI_HOTKEY_ENABLE		0x09
 #define HCI_HOTKEY_SPECIAL_FUNCTIONS	0x10
 #define HCI_LCD_BRIGHTNESS_BITS		3
 #define HCI_LCD_BRIGHTNESS_SHIFT	(16-HCI_LCD_BRIGHTNESS_BITS)
@@ -2484,6 +2484,14 @@ static int toshiba_acpi_setup_backlight(
 	brightness = __get_lcd_brightness(dev);
 	if (brightness < 0)
 		return 0;
+	/*
+	 * If transflective backlight is supported and the brightness is zero
+	 * (lowest brightness level), the set_lcd_brightness function will
+	 * activate the transflective backlight, making the LCD appear to be
+	 * turned off, simply increment the brightness level to avoid that.
+	 */
+	if (dev->tr_backlight_supported && brightness == 0)
+		brightness++;
 	ret = set_lcd_brightness(dev, brightness);
 	if (ret) {
 		pr_debug("Backlight method is read-only, disabling backlight support\n");
--- zfcpdump-kernel-4.4.orig/drivers/pnp/isapnp/core.c
+++ zfcpdump-kernel-4.4/drivers/pnp/isapnp/core.c
@@ -41,6 +41,7 @@
 #include <linux/init.h>
 #include <linux/isapnp.h>
 #include <linux/mutex.h>
+#include <linux/async.h>
 #include <asm/io.h>
 
 #include "../base.h"
@@ -990,7 +991,7 @@ struct pnp_protocol isapnp_protocol = {
 	.disable = isapnp_disable_resources,
 };
 
-static int __init isapnp_init(void)
+static int __init real_isapnp_init(void)
 {
 	int cards;
 	struct pnp_card *card;
@@ -1084,6 +1085,16 @@ static int __init isapnp_init(void)
 	return 0;
 }
 
+static void __init async_isapnp_init(void *unused, async_cookie_t cookie)
+{
+	(void)real_isapnp_init();
+}
+
+static int __init isapnp_init(void)
+{
+	async_schedule(async_isapnp_init, NULL);
+	return 0;
+}
 device_initcall(isapnp_init);
 
 /* format is: noisapnp */
--- zfcpdump-kernel-4.4.orig/drivers/pnp/quirks.c
+++ zfcpdump-kernel-4.4/drivers/pnp/quirks.c
@@ -342,7 +342,9 @@ static void quirk_amd_mmconfig_area(stru
 /* Device IDs of parts that have 32KB MCH space */
 static const unsigned int mch_quirk_devices[] = {
 	0x0154,	/* Ivy Bridge */
+	0x0a04, /* Haswell-ULT */
 	0x0c00,	/* Haswell */
+	0x1604, /* Broadwell */
 };
 
 static struct pci_dev *get_intel_host(void)
--- zfcpdump-kernel-4.4.orig/drivers/power/max17042_battery.c
+++ zfcpdump-kernel-4.4/drivers/power/max17042_battery.c
@@ -457,13 +457,16 @@ static inline void max17042_write_model_
 }
 
 static inline void max17042_read_model_data(struct max17042_chip *chip,
-					u8 addr, u32 *data, int size)
+					u8 addr, u16 *data, int size)
 {
 	struct regmap *map = chip->regmap;
 	int i;
+	u32 tmp;
 
-	for (i = 0; i < size; i++)
-		regmap_read(map, addr + i, &data[i]);
+	for (i = 0; i < size; i++) {
+		regmap_read(map, addr + i, &tmp);
+		data[i] = (u16)tmp;
+	}
 }
 
 static inline int max17042_model_data_compare(struct max17042_chip *chip,
@@ -486,7 +489,7 @@ static int max17042_init_model(struct ma
 {
 	int ret;
 	int table_size = ARRAY_SIZE(chip->pdata->config_data->cell_char_tbl);
-	u32 *temp_data;
+	u16 *temp_data;
 
 	temp_data = kcalloc(table_size, sizeof(*temp_data), GFP_KERNEL);
 	if (!temp_data)
@@ -501,7 +504,7 @@ static int max17042_init_model(struct ma
 	ret = max17042_model_data_compare(
 		chip,
 		chip->pdata->config_data->cell_char_tbl,
-		(u16 *)temp_data,
+		temp_data,
 		table_size);
 
 	max10742_lock_model(chip);
@@ -514,7 +517,7 @@ static int max17042_verify_model_lock(st
 {
 	int i;
 	int table_size = ARRAY_SIZE(chip->pdata->config_data->cell_char_tbl);
-	u32 *temp_data;
+	u16 *temp_data;
 	int ret = 0;
 
 	temp_data = kcalloc(table_size, sizeof(*temp_data), GFP_KERNEL);
--- zfcpdump-kernel-4.4.orig/drivers/power/power_supply_core.c
+++ zfcpdump-kernel-4.4/drivers/power/power_supply_core.c
@@ -565,11 +565,12 @@ static int power_supply_read_temp(struct
 
 	WARN_ON(tzd == NULL);
 	psy = tzd->devdata;
-	ret = psy->desc->get_property(psy, POWER_SUPPLY_PROP_TEMP, &val);
+	ret = power_supply_get_property(psy, POWER_SUPPLY_PROP_TEMP, &val);
+	if (ret)
+		return ret;
 
 	/* Convert tenths of degree Celsius to milli degree Celsius. */
-	if (!ret)
-		*temp = val.intval * 100;
+	*temp = val.intval * 100;
 
 	return ret;
 }
@@ -612,10 +613,12 @@ static int ps_get_max_charge_cntl_limit(
 	int ret;
 
 	psy = tcd->devdata;
-	ret = psy->desc->get_property(psy,
-		POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT_MAX, &val);
-	if (!ret)
-		*state = val.intval;
+	ret = power_supply_get_property(psy,
+			POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT_MAX, &val);
+	if (ret)
+		return ret;
+
+	*state = val.intval;
 
 	return ret;
 }
@@ -628,10 +631,12 @@ static int ps_get_cur_chrage_cntl_limit(
 	int ret;
 
 	psy = tcd->devdata;
-	ret = psy->desc->get_property(psy,
-		POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT, &val);
-	if (!ret)
-		*state = val.intval;
+	ret = power_supply_get_property(psy,
+			POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT, &val);
+	if (ret)
+		return ret;
+
+	*state = val.intval;
 
 	return ret;
 }
--- zfcpdump-kernel-4.4.orig/drivers/power/reset/hisi-reboot.c
+++ zfcpdump-kernel-4.4/drivers/power/reset/hisi-reboot.c
@@ -53,13 +53,16 @@ static int hisi_reboot_probe(struct plat
 
 	if (of_property_read_u32(np, "reboot-offset", &reboot_offset) < 0) {
 		pr_err("failed to find reboot-offset property\n");
+		iounmap(base);
 		return -EINVAL;
 	}
 
 	err = register_restart_handler(&hisi_restart_nb);
-	if (err)
+	if (err) {
 		dev_err(&pdev->dev, "cannot register restart handler (err=%d)\n",
 			err);
+		iounmap(base);
+	}
 
 	return err;
 }
--- zfcpdump-kernel-4.4.orig/drivers/power/tps65217_charger.c
+++ zfcpdump-kernel-4.4/drivers/power/tps65217_charger.c
@@ -205,6 +205,7 @@ static int tps65217_charger_probe(struct
 	if (!charger)
 		return -ENOMEM;
 
+	platform_set_drvdata(pdev, charger);
 	charger->tps = tps;
 	charger->dev = &pdev->dev;
 
--- zfcpdump-kernel-4.4.orig/drivers/pps/clients/pps_parport.c
+++ zfcpdump-kernel-4.4/drivers/pps/clients/pps_parport.c
@@ -195,7 +195,7 @@ static void parport_detach(struct parpor
 	struct pps_client_pp *device;
 
 	/* FIXME: oooh, this is ugly! */
-	if (strcmp(pardev->name, KBUILD_MODNAME))
+	if (!pardev || strcmp(pardev->name, KBUILD_MODNAME))
 		/* not our port */
 		return;
 
--- zfcpdump-kernel-4.4.orig/drivers/ptp/ptp_chardev.c
+++ zfcpdump-kernel-4.4/drivers/ptp/ptp_chardev.c
@@ -22,6 +22,7 @@
 #include <linux/poll.h>
 #include <linux/sched.h>
 #include <linux/slab.h>
+#include <linux/timekeeping.h>
 
 #include "ptp_private.h"
 
@@ -120,11 +121,13 @@ long ptp_ioctl(struct posix_clock *pc, u
 	struct ptp_clock_caps caps;
 	struct ptp_clock_request req;
 	struct ptp_sys_offset *sysoff = NULL;
+	struct ptp_sys_offset_precise precise_offset;
 	struct ptp_pin_desc pd;
 	struct ptp_clock *ptp = container_of(pc, struct ptp_clock, clock);
 	struct ptp_clock_info *ops = ptp->info;
 	struct ptp_clock_time *pct;
 	struct timespec64 ts;
+	struct system_device_crosststamp xtstamp;
 	int enable, err = 0;
 	unsigned int i, pin_index;
 
@@ -138,6 +141,7 @@ long ptp_ioctl(struct posix_clock *pc, u
 		caps.n_per_out = ptp->info->n_per_out;
 		caps.pps = ptp->info->pps;
 		caps.n_pins = ptp->info->n_pins;
+		caps.cross_timestamping = ptp->info->getcrosststamp != NULL;
 		if (copy_to_user((void __user *)arg, &caps, sizeof(caps)))
 			err = -EFAULT;
 		break;
@@ -180,6 +184,29 @@ long ptp_ioctl(struct posix_clock *pc, u
 		err = ops->enable(ops, &req, enable);
 		break;
 
+	case PTP_SYS_OFFSET_PRECISE:
+		if (!ptp->info->getcrosststamp) {
+			err = -EOPNOTSUPP;
+			break;
+		}
+		err = ptp->info->getcrosststamp(ptp->info, &xtstamp);
+		if (err)
+			break;
+
+		ts = ktime_to_timespec64(xtstamp.device);
+		precise_offset.device.sec = ts.tv_sec;
+		precise_offset.device.nsec = ts.tv_nsec;
+		ts = ktime_to_timespec64(xtstamp.sys_realtime);
+		precise_offset.sys_realtime.sec = ts.tv_sec;
+		precise_offset.sys_realtime.nsec = ts.tv_nsec;
+		ts = ktime_to_timespec64(xtstamp.sys_monoraw);
+		precise_offset.sys_monoraw.sec = ts.tv_sec;
+		precise_offset.sys_monoraw.nsec = ts.tv_nsec;
+		if (copy_to_user((void __user *)arg, &precise_offset,
+				 sizeof(precise_offset)))
+			err = -EFAULT;
+		break;
+
 	case PTP_SYS_OFFSET:
 		sysoff = kmalloc(sizeof(*sysoff), GFP_KERNEL);
 		if (!sysoff) {
--- zfcpdump-kernel-4.4.orig/drivers/pwm/Kconfig
+++ zfcpdump-kernel-4.4/drivers/pwm/Kconfig
@@ -148,6 +148,7 @@ config PWM_EP93XX
 
 config PWM_FSL_FTM
 	tristate "Freescale FlexTimer Module (FTM) PWM support"
+	depends on HAS_IOMEM
 	depends on OF
 	select REGMAP_MMIO
 	help
@@ -222,18 +223,12 @@ config PWM_LPC32XX
 	  will be called pwm-lpc32xx.
 
 config PWM_LPSS
-	tristate "Intel LPSS PWM support"
-	depends on X86
-	help
-	  Generic PWM framework driver for Intel Low Power Subsystem PWM
-	  controller.
-
-	  To compile this driver as a module, choose M here: the module
-	  will be called pwm-lpss.
+	tristate
 
 config PWM_LPSS_PCI
 	tristate "Intel LPSS PWM PCI driver"
-	depends on PWM_LPSS && PCI
+	depends on X86 && PCI
+	select PWM_LPSS
 	help
 	  The PCI driver for Intel Low Power Subsystem PWM controller.
 
@@ -242,7 +237,8 @@ config PWM_LPSS_PCI
 
 config PWM_LPSS_PLATFORM
 	tristate "Intel LPSS PWM platform driver"
-	depends on PWM_LPSS && ACPI
+	depends on X86 && ACPI
+	select PWM_LPSS
 	help
 	  The platform driver for Intel Low Power Subsystem PWM controller.
 
@@ -270,6 +266,15 @@ config PWM_MXS
 	  To compile this driver as a module, choose M here: the module
 	  will be called pwm-mxs.
 
+config PWM_OMAP_DMTIMER
+	tristate "OMAP Dual-Mode Timer PWM support"
+	depends on OF && ARCH_OMAP && OMAP_DM_TIMER
+	help
+	  Generic PWM framework driver for OMAP Dual-Mode Timer PWM output
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called pwm-omap-dmtimer
+
 config PWM_PCA9685
 	tristate "NXP PCA9685 PWM driver"
 	depends on I2C
--- zfcpdump-kernel-4.4.orig/drivers/pwm/Makefile
+++ zfcpdump-kernel-4.4/drivers/pwm/Makefile
@@ -24,6 +24,7 @@ obj-$(CONFIG_PWM_LPSS_PCI)	+= pwm-lpss-p
 obj-$(CONFIG_PWM_LPSS_PLATFORM)	+= pwm-lpss-platform.o
 obj-$(CONFIG_PWM_MTK_DISP)	+= pwm-mtk-disp.o
 obj-$(CONFIG_PWM_MXS)		+= pwm-mxs.o
+obj-$(CONFIG_PWM_OMAP_DMTIMER)	+= pwm-omap-dmtimer.o
 obj-$(CONFIG_PWM_PCA9685)	+= pwm-pca9685.o
 obj-$(CONFIG_PWM_PUV3)		+= pwm-puv3.o
 obj-$(CONFIG_PWM_PXA)		+= pwm-pxa.o
--- zfcpdump-kernel-4.4.orig/drivers/pwm/core.c
+++ zfcpdump-kernel-4.4/drivers/pwm/core.c
@@ -889,7 +889,7 @@ EXPORT_SYMBOL_GPL(devm_pwm_put);
   */
 bool pwm_can_sleep(struct pwm_device *pwm)
 {
-	return pwm->chip->can_sleep;
+	return true;
 }
 EXPORT_SYMBOL_GPL(pwm_can_sleep);
 
--- zfcpdump-kernel-4.4.orig/drivers/pwm/pwm-bcm2835.c
+++ zfcpdump-kernel-4.4/drivers/pwm/pwm-bcm2835.c
@@ -29,7 +29,6 @@
 struct bcm2835_pwm {
 	struct pwm_chip chip;
 	struct device *dev;
-	unsigned long scaler;
 	void __iomem *base;
 	struct clk *clk;
 };
@@ -66,6 +65,15 @@ static int bcm2835_pwm_config(struct pwm
 			      int duty_ns, int period_ns)
 {
 	struct bcm2835_pwm *pc = to_bcm2835_pwm(chip);
+	unsigned long rate = clk_get_rate(pc->clk);
+	unsigned long scaler;
+
+	if (!rate) {
+		dev_err(pc->dev, "failed to get clock rate\n");
+		return -EINVAL;
+	}
+
+	scaler = NSEC_PER_SEC / rate;
 
 	if (period_ns <= MIN_PERIOD) {
 		dev_err(pc->dev, "period %d not supported, minimum %d\n",
@@ -73,8 +81,8 @@ static int bcm2835_pwm_config(struct pwm
 		return -EINVAL;
 	}
 
-	writel(duty_ns / pc->scaler, pc->base + DUTY(pwm->hwpwm));
-	writel(period_ns / pc->scaler, pc->base + PERIOD(pwm->hwpwm));
+	writel(duty_ns / scaler, pc->base + DUTY(pwm->hwpwm));
+	writel(period_ns / scaler, pc->base + PERIOD(pwm->hwpwm));
 
 	return 0;
 }
@@ -156,8 +164,6 @@ static int bcm2835_pwm_probe(struct plat
 	if (ret)
 		return ret;
 
-	pc->scaler = NSEC_PER_SEC / clk_get_rate(pc->clk);
-
 	pc->chip.dev = &pdev->dev;
 	pc->chip.ops = &bcm2835_pwm_ops;
 	pc->chip.npwm = 2;
@@ -200,6 +206,6 @@ static struct platform_driver bcm2835_pw
 };
 module_platform_driver(bcm2835_pwm_driver);
 
-MODULE_AUTHOR("Bart Tanghe <bart.tanghe@thomasmore.be");
+MODULE_AUTHOR("Bart Tanghe <bart.tanghe@thomasmore.be>");
 MODULE_DESCRIPTION("Broadcom BCM2835 PWM driver");
 MODULE_LICENSE("GPL v2");
--- zfcpdump-kernel-4.4.orig/drivers/pwm/pwm-brcmstb.c
+++ zfcpdump-kernel-4.4/drivers/pwm/pwm-brcmstb.c
@@ -274,8 +274,8 @@ static int brcmstb_pwm_probe(struct plat
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	p->base = devm_ioremap_resource(&pdev->dev, res);
-	if (!p->base) {
-		ret = -ENOMEM;
+	if (IS_ERR(p->base)) {
+		ret = PTR_ERR(p->base);
 		goto out_clk;
 	}
 
--- zfcpdump-kernel-4.4.orig/drivers/pwm/pwm-fsl-ftm.c
+++ zfcpdump-kernel-4.4/drivers/pwm/pwm-fsl-ftm.c
@@ -80,7 +80,6 @@ struct fsl_pwm_chip {
 
 	struct mutex lock;
 
-	unsigned int use_count;
 	unsigned int cnt_select;
 	unsigned int clk_ps;
 
@@ -300,9 +299,6 @@ static int fsl_counter_clock_enable(stru
 {
 	int ret;
 
-	if (fpc->use_count++ != 0)
-		return 0;
-
 	/* select counter clock source */
 	regmap_update_bits(fpc->regmap, FTM_SC, FTM_SC_CLK_MASK,
 			   FTM_SC_CLK(fpc->cnt_select));
@@ -334,25 +330,6 @@ static int fsl_pwm_enable(struct pwm_chi
 	return ret;
 }
 
-static void fsl_counter_clock_disable(struct fsl_pwm_chip *fpc)
-{
-	/*
-	 * already disabled, do nothing
-	 */
-	if (fpc->use_count == 0)
-		return;
-
-	/* there are still users, so can't disable yet */
-	if (--fpc->use_count > 0)
-		return;
-
-	/* no users left, disable PWM counter clock */
-	regmap_update_bits(fpc->regmap, FTM_SC, FTM_SC_CLK_MASK, 0);
-
-	clk_disable_unprepare(fpc->clk[FSL_PWM_CLK_CNTEN]);
-	clk_disable_unprepare(fpc->clk[fpc->cnt_select]);
-}
-
 static void fsl_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
 {
 	struct fsl_pwm_chip *fpc = to_fsl_chip(chip);
@@ -362,7 +339,8 @@ static void fsl_pwm_disable(struct pwm_c
 	regmap_update_bits(fpc->regmap, FTM_OUTMASK, BIT(pwm->hwpwm),
 			   BIT(pwm->hwpwm));
 
-	fsl_counter_clock_disable(fpc);
+	clk_disable_unprepare(fpc->clk[FSL_PWM_CLK_CNTEN]);
+	clk_disable_unprepare(fpc->clk[fpc->cnt_select]);
 
 	regmap_read(fpc->regmap, FTM_OUTMASK, &val);
 	if ((val & 0xFF) == 0xFF)
@@ -492,17 +470,24 @@ static int fsl_pwm_remove(struct platfor
 static int fsl_pwm_suspend(struct device *dev)
 {
 	struct fsl_pwm_chip *fpc = dev_get_drvdata(dev);
-	u32 val;
+	int i;
 
 	regcache_cache_only(fpc->regmap, true);
 	regcache_mark_dirty(fpc->regmap);
 
-	/* read from cache */
-	regmap_read(fpc->regmap, FTM_OUTMASK, &val);
-	if ((val & 0xFF) != 0xFF) {
+	for (i = 0; i < fpc->chip.npwm; i++) {
+		struct pwm_device *pwm = &fpc->chip.pwms[i];
+
+		if (!test_bit(PWMF_REQUESTED, &pwm->flags))
+			continue;
+
+		clk_disable_unprepare(fpc->clk[FSL_PWM_CLK_SYS]);
+
+		if (!pwm_is_enabled(pwm))
+			continue;
+
 		clk_disable_unprepare(fpc->clk[FSL_PWM_CLK_CNTEN]);
 		clk_disable_unprepare(fpc->clk[fpc->cnt_select]);
-		clk_disable_unprepare(fpc->clk[FSL_PWM_CLK_SYS]);
 	}
 
 	return 0;
@@ -511,12 +496,19 @@ static int fsl_pwm_suspend(struct device
 static int fsl_pwm_resume(struct device *dev)
 {
 	struct fsl_pwm_chip *fpc = dev_get_drvdata(dev);
-	u32 val;
+	int i;
+
+	for (i = 0; i < fpc->chip.npwm; i++) {
+		struct pwm_device *pwm = &fpc->chip.pwms[i];
+
+		if (!test_bit(PWMF_REQUESTED, &pwm->flags))
+			continue;
 
-	/* read from cache */
-	regmap_read(fpc->regmap, FTM_OUTMASK, &val);
-	if ((val & 0xFF) != 0xFF) {
 		clk_prepare_enable(fpc->clk[FSL_PWM_CLK_SYS]);
+
+		if (!pwm_is_enabled(pwm))
+			continue;
+
 		clk_prepare_enable(fpc->clk[fpc->cnt_select]);
 		clk_prepare_enable(fpc->clk[FSL_PWM_CLK_CNTEN]);
 	}
--- zfcpdump-kernel-4.4.orig/drivers/pwm/pwm-lpc32xx.c
+++ zfcpdump-kernel-4.4/drivers/pwm/pwm-lpc32xx.c
@@ -24,9 +24,7 @@ struct lpc32xx_pwm_chip {
 	void __iomem *base;
 };
 
-#define PWM_ENABLE	(1 << 31)
-#define PWM_RELOADV(x)	(((x) & 0xFF) << 8)
-#define PWM_DUTY(x)	((x) & 0xFF)
+#define PWM_ENABLE	BIT(31)
 
 #define to_lpc32xx_pwm_chip(_chip) \
 	container_of(_chip, struct lpc32xx_pwm_chip, chip)
@@ -38,40 +36,27 @@ static int lpc32xx_pwm_config(struct pwm
 	unsigned long long c;
 	int period_cycles, duty_cycles;
 	u32 val;
+	c = clk_get_rate(lpc32xx->clk);
 
-	c = clk_get_rate(lpc32xx->clk) / 256;
-	c = c * period_ns;
-	do_div(c, NSEC_PER_SEC);
-
-	/* Handle high and low extremes */
-	if (c == 0)
-		c = 1;
-	if (c > 255)
-		c = 0; /* 0 set division by 256 */
-	period_cycles = c;
-
-	/* The duty-cycle value is as follows:
-	 *
-	 *  DUTY-CYCLE     HIGH LEVEL
-	 *      1            99.9%
-	 *      25           90.0%
-	 *      128          50.0%
-	 *      220          10.0%
-	 *      255           0.1%
-	 *      0             0.0%
-	 *
-	 * In other words, the register value is duty-cycle % 256 with
-	 * duty-cycle in the range 1-256.
-	 */
-	c = 256 * duty_ns;
-	do_div(c, period_ns);
-	if (c > 255)
-		c = 255;
-	duty_cycles = 256 - c;
+	/* The highest acceptable divisor is 256, which is represented by 0 */
+	period_cycles = div64_u64(c * period_ns,
+			       (unsigned long long)NSEC_PER_SEC * 256);
+	if (!period_cycles || period_cycles > 256)
+		return -ERANGE;
+	if (period_cycles == 256)
+		period_cycles = 0;
+
+	/* Compute 256 x #duty/period value and care for corner cases */
+	duty_cycles = div64_u64((unsigned long long)(period_ns - duty_ns) * 256,
+				period_ns);
+	if (!duty_cycles)
+		duty_cycles = 1;
+	if (duty_cycles > 255)
+		duty_cycles = 255;
 
 	val = readl(lpc32xx->base + (pwm->hwpwm << 2));
 	val &= ~0xFFFF;
-	val |= PWM_RELOADV(period_cycles) | PWM_DUTY(duty_cycles);
+	val |= (period_cycles << 8) | duty_cycles;
 	writel(val, lpc32xx->base + (pwm->hwpwm << 2));
 
 	return 0;
@@ -83,7 +68,7 @@ static int lpc32xx_pwm_enable(struct pwm
 	u32 val;
 	int ret;
 
-	ret = clk_enable(lpc32xx->clk);
+	ret = clk_prepare_enable(lpc32xx->clk);
 	if (ret)
 		return ret;
 
@@ -103,7 +88,7 @@ static void lpc32xx_pwm_disable(struct p
 	val &= ~PWM_ENABLE;
 	writel(val, lpc32xx->base + (pwm->hwpwm << 2));
 
-	clk_disable(lpc32xx->clk);
+	clk_disable_unprepare(lpc32xx->clk);
 }
 
 static const struct pwm_ops lpc32xx_pwm_ops = {
@@ -134,7 +119,7 @@ static int lpc32xx_pwm_probe(struct plat
 
 	lpc32xx->chip.dev = &pdev->dev;
 	lpc32xx->chip.ops = &lpc32xx_pwm_ops;
-	lpc32xx->chip.npwm = 2;
+	lpc32xx->chip.npwm = 1;
 	lpc32xx->chip.base = -1;
 
 	ret = pwmchip_add(&lpc32xx->chip);
--- zfcpdump-kernel-4.4.orig/drivers/pwm/pwm-lpss.c
+++ zfcpdump-kernel-4.4/drivers/pwm/pwm-lpss.c
@@ -13,10 +13,12 @@
  * published by the Free Software Foundation.
  */
 
+#include <linux/delay.h>
 #include <linux/io.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/pm_runtime.h>
+#include <linux/time.h>
 
 #include "pwm-lpss.h"
 
@@ -24,11 +26,8 @@
 #define PWM_ENABLE			BIT(31)
 #define PWM_SW_UPDATE			BIT(30)
 #define PWM_BASE_UNIT_SHIFT		8
-#define PWM_BASE_UNIT_MASK		0x00ffff00
 #define PWM_ON_TIME_DIV_MASK		0x000000ff
 #define PWM_DIVISION_CORRECTION		0x2
-#define PWM_LIMIT			(0x8000 + PWM_DIVISION_CORRECTION)
-#define NSECS_PER_SEC			1000000000UL
 
 /* Size of each PWM register space if multiple */
 #define PWM_SIZE			0x400
@@ -36,13 +35,14 @@
 struct pwm_lpss_chip {
 	struct pwm_chip chip;
 	void __iomem *regs;
-	unsigned long clk_rate;
+	const struct pwm_lpss_boardinfo *info;
 };
 
 /* BayTrail */
 const struct pwm_lpss_boardinfo pwm_lpss_byt_info = {
 	.clk_rate = 25000000,
 	.npwm = 1,
+	.base_unit_bits = 16,
 };
 EXPORT_SYMBOL_GPL(pwm_lpss_byt_info);
 
@@ -50,6 +50,7 @@ EXPORT_SYMBOL_GPL(pwm_lpss_byt_info);
 const struct pwm_lpss_boardinfo pwm_lpss_bsw_info = {
 	.clk_rate = 19200000,
 	.npwm = 1,
+	.base_unit_bits = 16,
 };
 EXPORT_SYMBOL_GPL(pwm_lpss_bsw_info);
 
@@ -57,6 +58,7 @@ EXPORT_SYMBOL_GPL(pwm_lpss_bsw_info);
 const struct pwm_lpss_boardinfo pwm_lpss_bxt_info = {
 	.clk_rate = 19200000,
 	.npwm = 4,
+	.base_unit_bits = 22,
 };
 EXPORT_SYMBOL_GPL(pwm_lpss_bxt_info);
 
@@ -79,28 +81,37 @@ static inline void pwm_lpss_write(const
 	writel(value, lpwm->regs + pwm->hwpwm * PWM_SIZE + PWM);
 }
 
+static void pwm_lpss_update(struct pwm_device *pwm)
+{
+	pwm_lpss_write(pwm, pwm_lpss_read(pwm) | PWM_SW_UPDATE);
+	/* Give it some time to propagate */
+	usleep_range(10, 50);
+}
+
 static int pwm_lpss_config(struct pwm_chip *chip, struct pwm_device *pwm,
 			   int duty_ns, int period_ns)
 {
 	struct pwm_lpss_chip *lpwm = to_lpwm(chip);
 	u8 on_time_div;
-	unsigned long c;
-	unsigned long long base_unit, freq = NSECS_PER_SEC;
+	unsigned long c, base_unit_range;
+	unsigned long long base_unit, freq = NSEC_PER_SEC;
 	u32 ctrl;
 
 	do_div(freq, period_ns);
 
-	/* The equation is: base_unit = ((freq / c) * 65536) + correction */
-	base_unit = freq * 65536;
+	/*
+	 * The equation is:
+	 * base_unit = ((freq / c) * base_unit_range) + correction
+	 */
+	base_unit_range = BIT(lpwm->info->base_unit_bits);
+	base_unit = freq * base_unit_range;
 
-	c = lpwm->clk_rate;
+	c = lpwm->info->clk_rate;
 	if (!c)
 		return -EINVAL;
 
 	do_div(base_unit, c);
 	base_unit += PWM_DIVISION_CORRECTION;
-	if (base_unit > PWM_LIMIT)
-		return -EINVAL;
 
 	if (duty_ns <= 0)
 		duty_ns = 1;
@@ -109,13 +120,20 @@ static int pwm_lpss_config(struct pwm_ch
 	pm_runtime_get_sync(chip->dev);
 
 	ctrl = pwm_lpss_read(pwm);
-	ctrl &= ~(PWM_BASE_UNIT_MASK | PWM_ON_TIME_DIV_MASK);
-	ctrl |= (u16) base_unit << PWM_BASE_UNIT_SHIFT;
+	ctrl &= ~PWM_ON_TIME_DIV_MASK;
+	ctrl &= ~((base_unit_range - 1) << PWM_BASE_UNIT_SHIFT);
+	base_unit &= (base_unit_range - 1);
+	ctrl |= (u32) base_unit << PWM_BASE_UNIT_SHIFT;
 	ctrl |= on_time_div;
-	/* request PWM to update on next cycle */
-	ctrl |= PWM_SW_UPDATE;
 	pwm_lpss_write(pwm, ctrl);
 
+	/*
+	 * If the PWM is already enabled we need to notify the hardware
+	 * about the change by setting PWM_SW_UPDATE.
+	 */
+	if (pwm_is_enabled(pwm))
+		pwm_lpss_update(pwm);
+
 	pm_runtime_put(chip->dev);
 
 	return 0;
@@ -124,6 +142,12 @@ static int pwm_lpss_config(struct pwm_ch
 static int pwm_lpss_enable(struct pwm_chip *chip, struct pwm_device *pwm)
 {
 	pm_runtime_get_sync(chip->dev);
+
+	/*
+	 * Hardware must first see PWM_SW_UPDATE before the PWM can be
+	 * enabled.
+	 */
+	pwm_lpss_update(pwm);
 	pwm_lpss_write(pwm, pwm_lpss_read(pwm) | PWM_ENABLE);
 	return 0;
 }
@@ -135,7 +159,6 @@ static void pwm_lpss_disable(struct pwm_
 }
 
 static const struct pwm_ops pwm_lpss_ops = {
-	.free = pwm_lpss_disable,
 	.config = pwm_lpss_config,
 	.enable = pwm_lpss_enable,
 	.disable = pwm_lpss_disable,
@@ -156,7 +179,7 @@ struct pwm_lpss_chip *pwm_lpss_probe(str
 	if (IS_ERR(lpwm->regs))
 		return ERR_CAST(lpwm->regs);
 
-	lpwm->clk_rate = info->clk_rate;
+	lpwm->info = info;
 	lpwm->chip.dev = dev;
 	lpwm->chip.ops = &pwm_lpss_ops;
 	lpwm->chip.base = -1;
--- zfcpdump-kernel-4.4.orig/drivers/pwm/pwm-lpss.h
+++ zfcpdump-kernel-4.4/drivers/pwm/pwm-lpss.h
@@ -21,6 +21,7 @@ struct pwm_lpss_chip;
 struct pwm_lpss_boardinfo {
 	unsigned long clk_rate;
 	unsigned int npwm;
+	unsigned long base_unit_bits;
 };
 
 extern const struct pwm_lpss_boardinfo pwm_lpss_byt_info;
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/pwm/pwm-omap-dmtimer.c
@@ -0,0 +1,327 @@
+/*
+ * Copyright (c) 2015 Neil Armstrong <narmstrong@baylibre.com>
+ * Copyright (c) 2014 Joachim Eastwood <manabian@gmail.com>
+ * Copyright (c) 2012 NeilBrown <neilb@suse.de>
+ * Heavily based on earlier code which is:
+ * Copyright (c) 2010 Grant Erickson <marathon96@gmail.com>
+ *
+ * Also based on pwm-samsung.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * Description:
+ *   This file is the core OMAP support for the generic, Linux
+ *   PWM driver / controller, using the OMAP's dual-mode timers.
+ */
+
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/platform_data/pwm_omap_dmtimer.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/pwm.h>
+#include <linux/slab.h>
+#include <linux/time.h>
+
+#define DM_TIMER_LOAD_MIN 0xfffffffe
+
+struct pwm_omap_dmtimer_chip {
+	struct pwm_chip chip;
+	struct mutex mutex;
+	pwm_omap_dmtimer *dm_timer;
+	struct pwm_omap_dmtimer_pdata *pdata;
+	struct platform_device *dm_timer_pdev;
+};
+
+static inline struct pwm_omap_dmtimer_chip *
+to_pwm_omap_dmtimer_chip(struct pwm_chip *chip)
+{
+	return container_of(chip, struct pwm_omap_dmtimer_chip, chip);
+}
+
+static int pwm_omap_dmtimer_calc_value(unsigned long clk_rate, int ns)
+{
+	u64 c = (u64)clk_rate * ns;
+
+	do_div(c, NSEC_PER_SEC);
+
+	return DM_TIMER_LOAD_MIN - c;
+}
+
+static void pwm_omap_dmtimer_start(struct pwm_omap_dmtimer_chip *omap)
+{
+	/*
+	 * According to OMAP 4 TRM section 22.2.4.10 the counter should be
+	 * started at 0xFFFFFFFE when overflow and match is used to ensure
+	 * that the PWM line is toggled on the first event.
+	 *
+	 * Note that omap_dm_timer_enable/disable is for register access and
+	 * not the timer counter itself.
+	 */
+	omap->pdata->enable(omap->dm_timer);
+	omap->pdata->write_counter(omap->dm_timer, DM_TIMER_LOAD_MIN);
+	omap->pdata->disable(omap->dm_timer);
+
+	omap->pdata->start(omap->dm_timer);
+}
+
+static int pwm_omap_dmtimer_enable(struct pwm_chip *chip,
+				   struct pwm_device *pwm)
+{
+	struct pwm_omap_dmtimer_chip *omap = to_pwm_omap_dmtimer_chip(chip);
+
+	mutex_lock(&omap->mutex);
+	pwm_omap_dmtimer_start(omap);
+	mutex_unlock(&omap->mutex);
+
+	return 0;
+}
+
+static void pwm_omap_dmtimer_disable(struct pwm_chip *chip,
+				     struct pwm_device *pwm)
+{
+	struct pwm_omap_dmtimer_chip *omap = to_pwm_omap_dmtimer_chip(chip);
+
+	mutex_lock(&omap->mutex);
+	omap->pdata->stop(omap->dm_timer);
+	mutex_unlock(&omap->mutex);
+}
+
+static int pwm_omap_dmtimer_config(struct pwm_chip *chip,
+				   struct pwm_device *pwm,
+				   int duty_ns, int period_ns)
+{
+	struct pwm_omap_dmtimer_chip *omap = to_pwm_omap_dmtimer_chip(chip);
+	int load_value, match_value;
+	struct clk *fclk;
+	unsigned long clk_rate;
+	bool timer_active;
+
+	dev_dbg(chip->dev, "duty cycle: %d, period %d\n", duty_ns, period_ns);
+
+	mutex_lock(&omap->mutex);
+	if (duty_ns == pwm_get_duty_cycle(pwm) &&
+	    period_ns == pwm_get_period(pwm)) {
+		/* No change - don't cause any transients. */
+		mutex_unlock(&omap->mutex);
+		return 0;
+	}
+
+	fclk = omap->pdata->get_fclk(omap->dm_timer);
+	if (!fclk) {
+		dev_err(chip->dev, "invalid pmtimer fclk\n");
+		mutex_unlock(&omap->mutex);
+		return -EINVAL;
+	}
+
+	clk_rate = clk_get_rate(fclk);
+	if (!clk_rate) {
+		dev_err(chip->dev, "invalid pmtimer fclk rate\n");
+		mutex_unlock(&omap->mutex);
+		return -EINVAL;
+	}
+
+	dev_dbg(chip->dev, "clk rate: %luHz\n", clk_rate);
+
+	/*
+	 * Calculate the appropriate load and match values based on the
+	 * specified period and duty cycle. The load value determines the
+	 * cycle time and the match value determines the duty cycle.
+	 */
+	load_value = pwm_omap_dmtimer_calc_value(clk_rate, period_ns);
+	match_value = pwm_omap_dmtimer_calc_value(clk_rate,
+						  period_ns - duty_ns);
+
+	/*
+	 * We MUST stop the associated dual-mode timer before attempting to
+	 * write its registers, but calls to omap_dm_timer_start/stop must
+	 * be balanced so check if timer is active before calling timer_stop.
+	 */
+	timer_active = pm_runtime_active(&omap->dm_timer_pdev->dev);
+	if (timer_active)
+		omap->pdata->stop(omap->dm_timer);
+
+	omap->pdata->set_load(omap->dm_timer, true, load_value);
+	omap->pdata->set_match(omap->dm_timer, true, match_value);
+
+	dev_dbg(chip->dev, "load value: %#08x (%d), match value: %#08x (%d)\n",
+		load_value, load_value,	match_value, match_value);
+
+	omap->pdata->set_pwm(omap->dm_timer,
+			      pwm->polarity == PWM_POLARITY_INVERSED,
+			      true,
+			      PWM_OMAP_DMTIMER_TRIGGER_OVERFLOW_AND_COMPARE);
+
+	/* If config was called while timer was running it must be reenabled. */
+	if (timer_active)
+		pwm_omap_dmtimer_start(omap);
+
+	mutex_unlock(&omap->mutex);
+
+	return 0;
+}
+
+static int pwm_omap_dmtimer_set_polarity(struct pwm_chip *chip,
+					 struct pwm_device *pwm,
+					 enum pwm_polarity polarity)
+{
+	struct pwm_omap_dmtimer_chip *omap = to_pwm_omap_dmtimer_chip(chip);
+
+	/*
+	 * PWM core will not call set_polarity while PWM is enabled so it's
+	 * safe to reconfigure the timer here without stopping it first.
+	 */
+	mutex_lock(&omap->mutex);
+	omap->pdata->set_pwm(omap->dm_timer,
+			      polarity == PWM_POLARITY_INVERSED,
+			      true,
+			      PWM_OMAP_DMTIMER_TRIGGER_OVERFLOW_AND_COMPARE);
+	mutex_unlock(&omap->mutex);
+
+	return 0;
+}
+
+static const struct pwm_ops pwm_omap_dmtimer_ops = {
+	.enable	= pwm_omap_dmtimer_enable,
+	.disable = pwm_omap_dmtimer_disable,
+	.config	= pwm_omap_dmtimer_config,
+	.set_polarity = pwm_omap_dmtimer_set_polarity,
+	.owner = THIS_MODULE,
+};
+
+static int pwm_omap_dmtimer_probe(struct platform_device *pdev)
+{
+	struct device_node *np = pdev->dev.of_node;
+	struct device_node *timer;
+	struct pwm_omap_dmtimer_chip *omap;
+	struct pwm_omap_dmtimer_pdata *pdata;
+	pwm_omap_dmtimer *dm_timer;
+	u32 prescaler;
+	int status;
+
+	pdata = dev_get_platdata(&pdev->dev);
+	if (!pdata) {
+		dev_err(&pdev->dev, "Missing dmtimer platform data\n");
+		return -EINVAL;
+	}
+
+	if (!pdata->request_by_node ||
+	    !pdata->free ||
+	    !pdata->enable ||
+	    !pdata->disable ||
+	    !pdata->get_fclk ||
+	    !pdata->start ||
+	    !pdata->stop ||
+	    !pdata->set_load ||
+	    !pdata->set_match ||
+	    !pdata->set_pwm ||
+	    !pdata->set_prescaler ||
+	    !pdata->write_counter) {
+		dev_err(&pdev->dev, "Incomplete dmtimer pdata structure\n");
+		return -EINVAL;
+	}
+
+	timer = of_parse_phandle(np, "ti,timers", 0);
+	if (!timer)
+		return -ENODEV;
+
+	if (!of_get_property(timer, "ti,timer-pwm", NULL)) {
+		dev_err(&pdev->dev, "Missing ti,timer-pwm capability\n");
+		return -ENODEV;
+	}
+
+	dm_timer = pdata->request_by_node(timer);
+	if (!dm_timer)
+		return -EPROBE_DEFER;
+
+	omap = devm_kzalloc(&pdev->dev, sizeof(*omap), GFP_KERNEL);
+	if (!omap) {
+		pdata->free(dm_timer);
+		return -ENOMEM;
+	}
+
+	omap->pdata = pdata;
+	omap->dm_timer = dm_timer;
+
+	omap->dm_timer_pdev = of_find_device_by_node(timer);
+	if (!omap->dm_timer_pdev) {
+		dev_err(&pdev->dev, "Unable to find timer pdev\n");
+		omap->pdata->free(dm_timer);
+		return -EINVAL;
+	}
+
+	/*
+	 * Ensure that the timer is stopped before we allow PWM core to call
+	 * pwm_enable.
+	 */
+	if (pm_runtime_active(&omap->dm_timer_pdev->dev))
+		omap->pdata->stop(omap->dm_timer);
+
+	/* setup dmtimer prescaler */
+	if (!of_property_read_u32(pdev->dev.of_node, "ti,prescaler",
+				&prescaler))
+		omap->pdata->set_prescaler(omap->dm_timer, prescaler);
+
+	omap->chip.dev = &pdev->dev;
+	omap->chip.ops = &pwm_omap_dmtimer_ops;
+	omap->chip.base = -1;
+	omap->chip.npwm = 1;
+	omap->chip.of_xlate = of_pwm_xlate_with_flags;
+	omap->chip.of_pwm_n_cells = 3;
+
+	mutex_init(&omap->mutex);
+
+	status = pwmchip_add(&omap->chip);
+	if (status < 0) {
+		dev_err(&pdev->dev, "failed to register PWM\n");
+		omap->pdata->free(omap->dm_timer);
+		return status;
+	}
+
+	platform_set_drvdata(pdev, omap);
+
+	return 0;
+}
+
+static int pwm_omap_dmtimer_remove(struct platform_device *pdev)
+{
+	struct pwm_omap_dmtimer_chip *omap = platform_get_drvdata(pdev);
+
+	if (pm_runtime_active(&omap->dm_timer_pdev->dev))
+		omap->pdata->stop(omap->dm_timer);
+
+	omap->pdata->free(omap->dm_timer);
+
+	mutex_destroy(&omap->mutex);
+
+	return pwmchip_remove(&omap->chip);
+}
+
+static const struct of_device_id pwm_omap_dmtimer_of_match[] = {
+	{.compatible = "ti,omap-dmtimer-pwm"},
+	{}
+};
+MODULE_DEVICE_TABLE(of, pwm_omap_dmtimer_of_match);
+
+static struct platform_driver pwm_omap_dmtimer_driver = {
+	.driver = {
+		.name = "omap-dmtimer-pwm",
+		.of_match_table = of_match_ptr(pwm_omap_dmtimer_of_match),
+	},
+	.probe = pwm_omap_dmtimer_probe,
+	.remove	= pwm_omap_dmtimer_remove,
+};
+module_platform_driver(pwm_omap_dmtimer_driver);
+
+MODULE_AUTHOR("Grant Erickson <marathon96@gmail.com>");
+MODULE_AUTHOR("NeilBrown <neilb@suse.de>");
+MODULE_AUTHOR("Neil Armstrong <narmstrong@baylibre.com>");
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("OMAP PWM Driver using Dual-mode Timers");
--- zfcpdump-kernel-4.4.orig/drivers/pwm/pwm-rcar.c
+++ zfcpdump-kernel-4.4/drivers/pwm/pwm-rcar.c
@@ -81,7 +81,7 @@ static int rcar_pwm_get_clock_division(s
 		max = (unsigned long long)NSEC_PER_SEC * RCAR_PWM_MAX_CYCLE *
 			(1 << div);
 		do_div(max, clk_rate);
-		if (period_ns < max)
+		if (period_ns <= max)
 			break;
 	}
 
--- zfcpdump-kernel-4.4.orig/drivers/regulator/Kconfig
+++ zfcpdump-kernel-4.4/drivers/regulator/Kconfig
@@ -446,6 +446,7 @@ config REGULATOR_MC13892
 config REGULATOR_MT6311
 	tristate "MediaTek MT6311 PMIC"
 	depends on I2C
+	select REGMAP_I2C
 	help
 	  Say y here to select this option to enable the power regulator of
 	  MediaTek MT6311 PMIC.
--- zfcpdump-kernel-4.4.orig/drivers/regulator/anatop-regulator.c
+++ zfcpdump-kernel-4.4/drivers/regulator/anatop-regulator.c
@@ -296,7 +296,7 @@ static int anatop_regulator_probe(struct
 		if (!sreg->sel && !strcmp(sreg->name, "vddpu"))
 			sreg->sel = 22;
 
-		if (!sreg->sel) {
+		if (!sreg->bypass && !sreg->sel) {
 			dev_err(&pdev->dev, "Failed to read a valid default voltage selector.\n");
 			return -EINVAL;
 		}
--- zfcpdump-kernel-4.4.orig/drivers/regulator/axp20x-regulator.c
+++ zfcpdump-kernel-4.4/drivers/regulator/axp20x-regulator.c
@@ -27,8 +27,8 @@
 #define AXP20X_IO_ENABLED		0x03
 #define AXP20X_IO_DISABLED		0x07
 
-#define AXP22X_IO_ENABLED		0x04
-#define AXP22X_IO_DISABLED		0x03
+#define AXP22X_IO_ENABLED		0x03
+#define AXP22X_IO_DISABLED		0x04
 
 #define AXP20X_WORKMODE_DCDC2_MASK	BIT(2)
 #define AXP20X_WORKMODE_DCDC3_MASK	BIT(1)
@@ -221,10 +221,10 @@ static const struct regulator_desc axp22
 		 AXP22X_ELDO2_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL2, BIT(1)),
 	AXP_DESC(AXP22X, ELDO3, "eldo3", "eldoin", 700, 3300, 100,
 		 AXP22X_ELDO3_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL2, BIT(2)),
-	AXP_DESC_IO(AXP22X, LDO_IO0, "ldo_io0", "ips", 1800, 3300, 100,
+	AXP_DESC_IO(AXP22X, LDO_IO0, "ldo_io0", "ips", 700, 3300, 100,
 		    AXP22X_LDO_IO0_V_OUT, 0x1f, AXP20X_GPIO0_CTRL, 0x07,
 		    AXP22X_IO_ENABLED, AXP22X_IO_DISABLED),
-	AXP_DESC_IO(AXP22X, LDO_IO1, "ldo_io1", "ips", 1800, 3300, 100,
+	AXP_DESC_IO(AXP22X, LDO_IO1, "ldo_io1", "ips", 700, 3300, 100,
 		    AXP22X_LDO_IO1_V_OUT, 0x1f, AXP20X_GPIO1_CTRL, 0x07,
 		    AXP22X_IO_ENABLED, AXP22X_IO_DISABLED),
 	AXP_DESC_FIXED(AXP22X, RTC_LDO, "rtc_ldo", "ips", 3000),
--- zfcpdump-kernel-4.4.orig/drivers/regulator/core.c
+++ zfcpdump-kernel-4.4/drivers/regulator/core.c
@@ -132,24 +132,24 @@ static bool have_full_constraints(void)
 	return has_full_constraints || of_have_populated_dt();
 }
 
+static inline struct regulator_dev *rdev_get_supply(struct regulator_dev *rdev)
+{
+	if (rdev && rdev->supply)
+		return rdev->supply->rdev;
+
+	return NULL;
+}
+
 /**
  * regulator_lock_supply - lock a regulator and its supplies
  * @rdev:         regulator source
  */
 static void regulator_lock_supply(struct regulator_dev *rdev)
 {
-	struct regulator *supply;
-	int i = 0;
-
-	while (1) {
-		mutex_lock_nested(&rdev->mutex, i++);
-		supply = rdev->supply;
-
-		if (!rdev->supply)
-			return;
+	int i;
 
-		rdev = supply->rdev;
-	}
+	for (i = 0; rdev; rdev = rdev_get_supply(rdev), i++)
+		mutex_lock_nested(&rdev->mutex, i);
 }
 
 /**
--- zfcpdump-kernel-4.4.orig/drivers/regulator/qcom_smd-regulator.c
+++ zfcpdump-kernel-4.4/drivers/regulator/qcom_smd-regulator.c
@@ -166,29 +166,30 @@ static const struct regulator_desc pm8x4
 static const struct regulator_desc pm8841_ftsmps = {
 	.linear_ranges = (struct regulator_linear_range[]) {
 		REGULATOR_LINEAR_RANGE(350000,  0, 184, 5000),
-		REGULATOR_LINEAR_RANGE(700000, 185, 339, 10000),
+		REGULATOR_LINEAR_RANGE(1280000, 185, 261, 10000),
 	},
 	.n_linear_ranges = 2,
-	.n_voltages = 340,
+	.n_voltages = 262,
 	.ops = &rpm_smps_ldo_ops,
 };
 
 static const struct regulator_desc pm8941_boost = {
 	.linear_ranges = (struct regulator_linear_range[]) {
-		REGULATOR_LINEAR_RANGE(4000000, 0, 15, 100000),
+		REGULATOR_LINEAR_RANGE(4000000, 0, 30, 50000),
 	},
 	.n_linear_ranges = 1,
-	.n_voltages = 16,
+	.n_voltages = 31,
 	.ops = &rpm_smps_ldo_ops,
 };
 
 static const struct regulator_desc pm8941_pldo = {
 	.linear_ranges = (struct regulator_linear_range[]) {
-		REGULATOR_LINEAR_RANGE( 750000,  0,  30, 25000),
-		REGULATOR_LINEAR_RANGE(1500000, 31, 99, 50000),
+		REGULATOR_LINEAR_RANGE( 750000,  0,  63, 12500),
+		REGULATOR_LINEAR_RANGE(1550000, 64, 126, 25000),
+		REGULATOR_LINEAR_RANGE(3100000, 127, 163, 50000),
 	},
-	.n_linear_ranges = 2,
-	.n_voltages = 100,
+	.n_linear_ranges = 3,
+	.n_voltages = 164,
 	.ops = &rpm_smps_ldo_ops,
 };
 
--- zfcpdump-kernel-4.4.orig/drivers/regulator/qcom_spmi-regulator.c
+++ zfcpdump-kernel-4.4/drivers/regulator/qcom_spmi-regulator.c
@@ -1050,6 +1050,8 @@ static struct regulator_ops spmi_vs_ops
 	.set_pull_down		= spmi_regulator_common_set_pull_down,
 	.set_soft_start		= spmi_regulator_common_set_soft_start,
 	.set_over_current_protection = spmi_regulator_vs_ocp,
+	.set_mode		= spmi_regulator_common_set_mode,
+	.get_mode		= spmi_regulator_common_get_mode,
 };
 
 static struct regulator_ops spmi_boost_ops = {
@@ -1440,6 +1442,7 @@ static const struct spmi_regulator_data
 	{ "s1", 0x1400, "vdd_s1", },
 	{ "s2", 0x1700, "vdd_s2", },
 	{ "s3", 0x1a00, "vdd_s3", },
+	{ "s4", 0xa000, },
 	{ "l1", 0x4000, "vdd_l1_l3", },
 	{ "l2", 0x4100, "vdd_l2_lvs_1_2_3", },
 	{ "l3", 0x4200, "vdd_l1_l3", },
@@ -1467,8 +1470,8 @@ static const struct spmi_regulator_data
 	{ "lvs1", 0x8000, "vdd_l2_lvs_1_2_3", },
 	{ "lvs2", 0x8100, "vdd_l2_lvs_1_2_3", },
 	{ "lvs3", 0x8200, "vdd_l2_lvs_1_2_3", },
-	{ "mvs1", 0x8300, "vin_5vs", },
-	{ "mvs2", 0x8400, "vin_5vs", },
+	{ "5vs1", 0x8300, "vin_5vs", "ocp-5vs1", },
+	{ "5vs2", 0x8400, "vin_5vs", "ocp-5vs2", },
 	{ }
 };
 
--- zfcpdump-kernel-4.4.orig/drivers/regulator/s2mps11.c
+++ zfcpdump-kernel-4.4/drivers/regulator/s2mps11.c
@@ -305,7 +305,7 @@ static struct regulator_ops s2mps11_buck
 	.enable_mask	= S2MPS11_ENABLE_MASK			\
 }
 
-#define regulator_desc_s2mps11_buck6_10(num, min, step) {	\
+#define regulator_desc_s2mps11_buck67810(num, min, step) {	\
 	.name		= "BUCK"#num,				\
 	.id		= S2MPS11_BUCK##num,			\
 	.ops		= &s2mps11_buck_ops,			\
@@ -321,6 +321,22 @@ static struct regulator_ops s2mps11_buck
 	.enable_mask	= S2MPS11_ENABLE_MASK			\
 }
 
+#define regulator_desc_s2mps11_buck9 {				\
+	.name		= "BUCK9",				\
+	.id		= S2MPS11_BUCK9,			\
+	.ops		= &s2mps11_buck_ops,			\
+	.type		= REGULATOR_VOLTAGE,			\
+	.owner		= THIS_MODULE,				\
+	.min_uV		= MIN_3000_MV,				\
+	.uV_step	= STEP_25_MV,				\
+	.n_voltages	= S2MPS11_BUCK9_N_VOLTAGES,		\
+	.ramp_delay	= S2MPS11_RAMP_DELAY,			\
+	.vsel_reg	= S2MPS11_REG_B9CTRL2,			\
+	.vsel_mask	= S2MPS11_BUCK9_VSEL_MASK,		\
+	.enable_reg	= S2MPS11_REG_B9CTRL1,			\
+	.enable_mask	= S2MPS11_ENABLE_MASK			\
+}
+
 static const struct regulator_desc s2mps11_regulators[] = {
 	regulator_desc_s2mps11_ldo(1, STEP_25_MV),
 	regulator_desc_s2mps11_ldo(2, STEP_50_MV),
@@ -365,11 +381,11 @@ static const struct regulator_desc s2mps
 	regulator_desc_s2mps11_buck1_4(3),
 	regulator_desc_s2mps11_buck1_4(4),
 	regulator_desc_s2mps11_buck5,
-	regulator_desc_s2mps11_buck6_10(6, MIN_600_MV, STEP_6_25_MV),
-	regulator_desc_s2mps11_buck6_10(7, MIN_600_MV, STEP_6_25_MV),
-	regulator_desc_s2mps11_buck6_10(8, MIN_600_MV, STEP_6_25_MV),
-	regulator_desc_s2mps11_buck6_10(9, MIN_3000_MV, STEP_25_MV),
-	regulator_desc_s2mps11_buck6_10(10, MIN_750_MV, STEP_12_5_MV),
+	regulator_desc_s2mps11_buck67810(6, MIN_600_MV, STEP_6_25_MV),
+	regulator_desc_s2mps11_buck67810(7, MIN_600_MV, STEP_6_25_MV),
+	regulator_desc_s2mps11_buck67810(8, MIN_600_MV, STEP_6_25_MV),
+	regulator_desc_s2mps11_buck9,
+	regulator_desc_s2mps11_buck67810(10, MIN_750_MV, STEP_12_5_MV),
 };
 
 static struct regulator_ops s2mps14_reg_ops;
--- zfcpdump-kernel-4.4.orig/drivers/regulator/s5m8767.c
+++ zfcpdump-kernel-4.4/drivers/regulator/s5m8767.c
@@ -202,9 +202,10 @@ static int s5m8767_get_register(struct s
 		}
 	}
 
-	if (i < s5m8767->num_regulators)
-		*enable_ctrl =
-		s5m8767_opmode_reg[reg_id][mode] << S5M8767_ENCTRL_SHIFT;
+	if (i >= s5m8767->num_regulators)
+		return -EINVAL;
+
+	*enable_ctrl = s5m8767_opmode_reg[reg_id][mode] << S5M8767_ENCTRL_SHIFT;
 
 	return 0;
 }
@@ -937,8 +938,12 @@ static int s5m8767_pmic_probe(struct pla
 			else
 				regulators[id].vsel_mask = 0xff;
 
-			s5m8767_get_register(s5m8767, id, &enable_reg,
+			ret = s5m8767_get_register(s5m8767, id, &enable_reg,
 					     &enable_val);
+			if (ret) {
+				dev_err(s5m8767->dev, "error reading registers\n");
+				return ret;
+			}
 			regulators[id].enable_reg = enable_reg;
 			regulators[id].enable_mask = S5M8767_ENCTRL_MASK;
 			regulators[id].enable_val = enable_val;
--- zfcpdump-kernel-4.4.orig/drivers/remoteproc/remoteproc_core.c
+++ zfcpdump-kernel-4.4/drivers/remoteproc/remoteproc_core.c
@@ -1239,11 +1239,6 @@ int rproc_add(struct rproc *rproc)
 	if (ret < 0)
 		return ret;
 
-	/* expose to rproc_get_by_phandle users */
-	mutex_lock(&rproc_list_mutex);
-	list_add(&rproc->node, &rproc_list);
-	mutex_unlock(&rproc_list_mutex);
-
 	dev_info(dev, "%s is available\n", rproc->name);
 
 	dev_info(dev, "Note: remoteproc is still under development and considered experimental.\n");
@@ -1251,8 +1246,16 @@ int rproc_add(struct rproc *rproc)
 
 	/* create debugfs entries */
 	rproc_create_debug_dir(rproc);
+	ret = rproc_add_virtio_devices(rproc);
+	if (ret < 0)
+		return ret;
+
+	/* expose to rproc_get_by_phandle users */
+	mutex_lock(&rproc_list_mutex);
+	list_add(&rproc->node, &rproc_list);
+	mutex_unlock(&rproc_list_mutex);
 
-	return rproc_add_virtio_devices(rproc);
+	return 0;
 }
 EXPORT_SYMBOL(rproc_add);
 
--- zfcpdump-kernel-4.4.orig/drivers/rtc/interface.c
+++ zfcpdump-kernel-4.4/drivers/rtc/interface.c
@@ -748,9 +748,23 @@ EXPORT_SYMBOL_GPL(rtc_irq_set_freq);
  */
 static int rtc_timer_enqueue(struct rtc_device *rtc, struct rtc_timer *timer)
 {
+	struct timerqueue_node *next = timerqueue_getnext(&rtc->timerqueue);
+	struct rtc_time tm;
+	ktime_t now;
+
 	timer->enabled = 1;
+	__rtc_read_time(rtc, &tm);
+	now = rtc_tm_to_ktime(tm);
+
+	/* Skip over expired timers */
+	while (next) {
+		if (next->expires.tv64 >= now.tv64)
+			break;
+		next = timerqueue_iterate_next(next);
+	}
+
 	timerqueue_add(&rtc->timerqueue, &timer->node);
-	if (&timer->node == timerqueue_getnext(&rtc->timerqueue)) {
+	if (!next) {
 		struct rtc_wkalrm alarm;
 		int err;
 		alarm.time = rtc_ktime_to_tm(timer->node.expires);
--- zfcpdump-kernel-4.4.orig/drivers/rtc/rtc-ds1685.c
+++ zfcpdump-kernel-4.4/drivers/rtc/rtc-ds1685.c
@@ -187,9 +187,9 @@ ds1685_rtc_end_data_access(struct ds1685
  * Only use this where you are certain another lock will not be held.
  */
 static inline void
-ds1685_rtc_begin_ctrl_access(struct ds1685_priv *rtc, unsigned long flags)
+ds1685_rtc_begin_ctrl_access(struct ds1685_priv *rtc, unsigned long *flags)
 {
-	spin_lock_irqsave(&rtc->lock, flags);
+	spin_lock_irqsave(&rtc->lock, *flags);
 	ds1685_rtc_switch_to_bank1(rtc);
 }
 
@@ -1304,7 +1304,7 @@ ds1685_rtc_sysfs_ctrl_regs_store(struct
 {
 	struct ds1685_priv *rtc = dev_get_drvdata(dev);
 	u8 reg = 0, bit = 0, tmp;
-	unsigned long flags = 0;
+	unsigned long flags;
 	long int val = 0;
 	const struct ds1685_rtc_ctrl_regs *reg_info =
 		ds1685_rtc_sysfs_ctrl_regs_lookup(attr->attr.name);
@@ -1325,7 +1325,7 @@ ds1685_rtc_sysfs_ctrl_regs_store(struct
 	bit = reg_info->bit;
 
 	/* Safe to spinlock during a write. */
-	ds1685_rtc_begin_ctrl_access(rtc, flags);
+	ds1685_rtc_begin_ctrl_access(rtc, &flags);
 	tmp = rtc->read(rtc, reg);
 	rtc->write(rtc, reg, (val ? (tmp | bit) : (tmp & ~(bit))));
 	ds1685_rtc_end_ctrl_access(rtc, flags);
--- zfcpdump-kernel-4.4.orig/drivers/rtc/rtc-hym8563.c
+++ zfcpdump-kernel-4.4/drivers/rtc/rtc-hym8563.c
@@ -144,7 +144,7 @@ static int hym8563_rtc_set_time(struct d
 	 * it does not seem to carry it over a subsequent write/read.
 	 * So we'll limit ourself to 100 years, starting at 2000 for now.
 	 */
-	buf[6] = tm->tm_year - 100;
+	buf[6] = bin2bcd(tm->tm_year - 100);
 
 	/*
 	 * CTL1 only contains TEST-mode bits apart from stop,
--- zfcpdump-kernel-4.4.orig/drivers/rtc/rtc-max77686.c
+++ zfcpdump-kernel-4.4/drivers/rtc/rtc-max77686.c
@@ -465,7 +465,7 @@ static int max77686_rtc_probe(struct pla
 
 	info->virq = regmap_irq_get_virq(max77686->rtc_irq_data,
 					 MAX77686_RTCIRQ_RTCA1);
-	if (!info->virq) {
+	if (info->virq <= 0) {
 		ret = -ENXIO;
 		goto err_rtc;
 	}
--- zfcpdump-kernel-4.4.orig/drivers/rtc/rtc-rx8025.c
+++ zfcpdump-kernel-4.4/drivers/rtc/rtc-rx8025.c
@@ -65,7 +65,6 @@
 
 static const struct i2c_device_id rx8025_id[] = {
 	{ "rx8025", 0 },
-	{ "rv8803", 1 },
 	{ }
 };
 MODULE_DEVICE_TABLE(i2c, rx8025_id);
--- zfcpdump-kernel-4.4.orig/drivers/rtc/rtc-s3c.c
+++ zfcpdump-kernel-4.4/drivers/rtc/rtc-s3c.c
@@ -149,12 +149,14 @@ static int s3c_rtc_setfreq(struct s3c_rt
 	if (!is_power_of_2(freq))
 		return -EINVAL;
 
+	s3c_rtc_enable_clk(info);
 	spin_lock_irq(&info->pie_lock);
 
 	if (info->data->set_freq)
 		info->data->set_freq(info, freq);
 
 	spin_unlock_irq(&info->pie_lock);
+	s3c_rtc_disable_clk(info);
 
 	return 0;
 }
--- zfcpdump-kernel-4.4.orig/drivers/rtc/rtc-vr41xx.c
+++ zfcpdump-kernel-4.4/drivers/rtc/rtc-vr41xx.c
@@ -272,12 +272,13 @@ static irqreturn_t rtclong1_interrupt(in
 }
 
 static const struct rtc_class_ops vr41xx_rtc_ops = {
-	.release	= vr41xx_rtc_release,
-	.ioctl		= vr41xx_rtc_ioctl,
-	.read_time	= vr41xx_rtc_read_time,
-	.set_time	= vr41xx_rtc_set_time,
-	.read_alarm	= vr41xx_rtc_read_alarm,
-	.set_alarm	= vr41xx_rtc_set_alarm,
+	.release		= vr41xx_rtc_release,
+	.ioctl			= vr41xx_rtc_ioctl,
+	.read_time		= vr41xx_rtc_read_time,
+	.set_time		= vr41xx_rtc_set_time,
+	.read_alarm		= vr41xx_rtc_read_alarm,
+	.set_alarm		= vr41xx_rtc_set_alarm,
+	.alarm_irq_enable	= vr41xx_rtc_alarm_irq_enable,
 };
 
 static int rtc_probe(struct platform_device *pdev)
--- zfcpdump-kernel-4.4.orig/drivers/s390/block/dasd.c
+++ zfcpdump-kernel-4.4/drivers/s390/block/dasd.c
@@ -1584,9 +1584,18 @@ void dasd_int_handler(struct ccw_device
 	unsigned long long now;
 	int expires;
 
+	cqr = (struct dasd_ccw_req *) intparm;
 	if (IS_ERR(irb)) {
 		switch (PTR_ERR(irb)) {
 		case -EIO:
+			if (cqr && cqr->status == DASD_CQR_CLEAR_PENDING) {
+				device = (struct dasd_device *) cqr->startdev;
+				cqr->status = DASD_CQR_CLEARED;
+				dasd_device_clear_timer(device);
+				wake_up(&dasd_flush_wq);
+				dasd_schedule_device_bh(device);
+				return;
+			}
 			break;
 		case -ETIMEDOUT:
 			DBF_EVENT_DEVID(DBF_WARNING, cdev, "%s: "
@@ -1602,7 +1611,6 @@ void dasd_int_handler(struct ccw_device
 	}
 
 	now = get_tod_clock();
-	cqr = (struct dasd_ccw_req *) intparm;
 	/* check for conditions that should be handled immediately */
 	if (!cqr ||
 	    !(scsw_dstat(&irb->scsw) == (DEV_STAT_CHN_END | DEV_STAT_DEV_END) &&
@@ -3031,6 +3039,7 @@ static void dasd_setup_queue(struct dasd
 		max = block->base->discipline->max_blocks << block->s2b_shift;
 	}
 	queue_flag_set_unlocked(QUEUE_FLAG_NONROT, block->request_queue);
+	block->request_queue->limits.max_dev_sectors = max;
 	blk_queue_logical_block_size(block->request_queue,
 				     block->bp_block);
 	blk_queue_max_hw_sectors(block->request_queue, max);
--- zfcpdump-kernel-4.4.orig/drivers/s390/block/dasd_alias.c
+++ zfcpdump-kernel-4.4/drivers/s390/block/dasd_alias.c
@@ -264,8 +264,10 @@ void dasd_alias_disconnect_device_from_l
 		spin_unlock_irqrestore(&lcu->lock, flags);
 		cancel_work_sync(&lcu->suc_data.worker);
 		spin_lock_irqsave(&lcu->lock, flags);
-		if (device == lcu->suc_data.device)
+		if (device == lcu->suc_data.device) {
+			dasd_put_device(device);
 			lcu->suc_data.device = NULL;
+		}
 	}
 	was_pending = 0;
 	if (device == lcu->ruac_data.device) {
@@ -273,8 +275,10 @@ void dasd_alias_disconnect_device_from_l
 		was_pending = 1;
 		cancel_delayed_work_sync(&lcu->ruac_data.dwork);
 		spin_lock_irqsave(&lcu->lock, flags);
-		if (device == lcu->ruac_data.device)
+		if (device == lcu->ruac_data.device) {
+			dasd_put_device(device);
 			lcu->ruac_data.device = NULL;
+		}
 	}
 	private->lcu = NULL;
 	spin_unlock_irqrestore(&lcu->lock, flags);
@@ -549,8 +553,10 @@ static void lcu_update_work(struct work_
 	if ((rc && (rc != -EOPNOTSUPP)) || (lcu->flags & NEED_UAC_UPDATE)) {
 		DBF_DEV_EVENT(DBF_WARNING, device, "could not update"
 			    " alias data in lcu (rc = %d), retry later", rc);
-		schedule_delayed_work(&lcu->ruac_data.dwork, 30*HZ);
+		if (!schedule_delayed_work(&lcu->ruac_data.dwork, 30*HZ))
+			dasd_put_device(device);
 	} else {
+		dasd_put_device(device);
 		lcu->ruac_data.device = NULL;
 		lcu->flags &= ~UPDATE_PENDING;
 	}
@@ -593,8 +599,10 @@ static int _schedule_lcu_update(struct a
 	 */
 	if (!usedev)
 		return -EINVAL;
+	dasd_get_device(usedev);
 	lcu->ruac_data.device = usedev;
-	schedule_delayed_work(&lcu->ruac_data.dwork, 0);
+	if (!schedule_delayed_work(&lcu->ruac_data.dwork, 0))
+		dasd_put_device(usedev);
 	return 0;
 }
 
@@ -723,7 +731,7 @@ static int reset_summary_unit_check(stru
 	ASCEBC((char *) &cqr->magic, 4);
 	ccw = cqr->cpaddr;
 	ccw->cmd_code = DASD_ECKD_CCW_RSCK;
-	ccw->flags = 0 ;
+	ccw->flags = CCW_FLAG_SLI;
 	ccw->count = 16;
 	ccw->cda = (__u32)(addr_t) cqr->data;
 	((char *)cqr->data)[0] = reason;
@@ -930,6 +938,7 @@ static void summary_unit_check_handling_
 	/* 3. read new alias configuration */
 	_schedule_lcu_update(lcu, device);
 	lcu->suc_data.device = NULL;
+	dasd_put_device(device);
 	spin_unlock_irqrestore(&lcu->lock, flags);
 }
 
@@ -989,6 +998,8 @@ void dasd_alias_handle_summary_unit_chec
 	}
 	lcu->suc_data.reason = reason;
 	lcu->suc_data.device = device;
+	dasd_get_device(device);
 	spin_unlock(&lcu->lock);
-	schedule_work(&lcu->suc_data.worker);
+	if (!schedule_work(&lcu->suc_data.worker))
+		dasd_put_device(device);
 };
--- zfcpdump-kernel-4.4.orig/drivers/s390/block/dasd_diag.c
+++ zfcpdump-kernel-4.4/drivers/s390/block/dasd_diag.c
@@ -67,7 +67,7 @@ static const u8 DASD_DIAG_CMS1[] = { 0xc
  * and function code cmd.
  * In case of an exception return 3. Otherwise return result of bitwise OR of
  * resulting condition code and DIAG return code. */
-static inline int dia250(void *iob, int cmd)
+static inline int __dia250(void *iob, int cmd)
 {
 	register unsigned long reg2 asm ("2") = (unsigned long) iob;
 	typedef union {
@@ -77,7 +77,6 @@ static inline int dia250(void *iob, int
 	int rc;
 
 	rc = 3;
-	diag_stat_inc(DIAG_STAT_X250);
 	asm volatile(
 		"	diag	2,%2,0x250\n"
 		"0:	ipm	%0\n"
@@ -91,6 +90,12 @@ static inline int dia250(void *iob, int
 	return rc;
 }
 
+static inline int dia250(void *iob, int cmd)
+{
+	diag_stat_inc(DIAG_STAT_X250);
+	return __dia250(iob, cmd);
+}
+
 /* Initialize block I/O to DIAG device using the specified blocksize and
  * block offset. On success, return zero and set end_block to contain the
  * number of blocks on the device minus the specified offset. Return non-zero
--- zfcpdump-kernel-4.4.orig/drivers/s390/char/sclp_ctl.c
+++ zfcpdump-kernel-4.4/drivers/s390/char/sclp_ctl.c
@@ -56,6 +56,7 @@ static int sclp_ctl_ioctl_sccb(void __us
 {
 	struct sclp_ctl_sccb ctl_sccb;
 	struct sccb_header *sccb;
+	unsigned long copied;
 	int rc;
 
 	if (copy_from_user(&ctl_sccb, user_area, sizeof(ctl_sccb)))
@@ -65,14 +66,15 @@ static int sclp_ctl_ioctl_sccb(void __us
 	sccb = (void *) get_zeroed_page(GFP_KERNEL | GFP_DMA);
 	if (!sccb)
 		return -ENOMEM;
-	if (copy_from_user(sccb, u64_to_uptr(ctl_sccb.sccb), sizeof(*sccb))) {
+	copied = PAGE_SIZE -
+		copy_from_user(sccb, u64_to_uptr(ctl_sccb.sccb), PAGE_SIZE);
+	if (offsetof(struct sccb_header, length) +
+	    sizeof(sccb->length) > copied || sccb->length > copied) {
 		rc = -EFAULT;
 		goto out_free;
 	}
-	if (sccb->length > PAGE_SIZE || sccb->length < 8)
-		return -EINVAL;
-	if (copy_from_user(sccb, u64_to_uptr(ctl_sccb.sccb), sccb->length)) {
-		rc = -EFAULT;
+	if (sccb->length < 8) {
+		rc = -EINVAL;
 		goto out_free;
 	}
 	rc = sclp_sync_request(ctl_sccb.cmdw, sccb);
--- zfcpdump-kernel-4.4.orig/drivers/s390/cio/chp.c
+++ zfcpdump-kernel-4.4/drivers/s390/cio/chp.c
@@ -139,11 +139,11 @@ static ssize_t chp_measurement_chars_rea
 
 	device = container_of(kobj, struct device, kobj);
 	chp = to_channelpath(device);
-	if (!chp->cmg_chars)
+	if (chp->cmg == -1)
 		return 0;
 
-	return memory_read_from_buffer(buf, count, &off,
-				chp->cmg_chars, sizeof(struct cmg_chars));
+	return memory_read_from_buffer(buf, count, &off, &chp->cmg_chars,
+				       sizeof(chp->cmg_chars));
 }
 
 static struct bin_attribute chp_measurement_chars_attr = {
@@ -416,7 +416,8 @@ static void chp_release(struct device *d
  * chp_update_desc - update channel-path description
  * @chp - channel-path
  *
- * Update the channel-path description of the specified channel-path.
+ * Update the channel-path description of the specified channel-path
+ * including channel measurement related information.
  * Return zero on success, non-zero otherwise.
  */
 int chp_update_desc(struct channel_path *chp)
@@ -428,8 +429,10 @@ int chp_update_desc(struct channel_path
 		return rc;
 
 	rc = chsc_determine_fmt1_channel_path_desc(chp->chpid, &chp->desc_fmt1);
+	if (rc)
+		return rc;
 
-	return rc;
+	return chsc_get_channel_measurement_chars(chp);
 }
 
 /**
@@ -466,14 +469,6 @@ int chp_new(struct chp_id chpid)
 		ret = -ENODEV;
 		goto out_free;
 	}
-	/* Get channel-measurement characteristics. */
-	if (css_chsc_characteristics.scmc && css_chsc_characteristics.secm) {
-		ret = chsc_get_channel_measurement_chars(chp);
-		if (ret)
-			goto out_free;
-	} else {
-		chp->cmg = -1;
-	}
 	dev_set_name(&chp->dev, "chp%x.%02x", chpid.cssid, chpid.id);
 
 	/* make it known to the system */
--- zfcpdump-kernel-4.4.orig/drivers/s390/cio/chp.h
+++ zfcpdump-kernel-4.4/drivers/s390/cio/chp.h
@@ -48,7 +48,7 @@ struct channel_path {
 	/* Channel-measurement related stuff: */
 	int cmg;
 	int shared;
-	void *cmg_chars;
+	struct cmg_chars cmg_chars;
 };
 
 /* Return channel_path struct for given chpid. */
--- zfcpdump-kernel-4.4.orig/drivers/s390/cio/chsc.c
+++ zfcpdump-kernel-4.4/drivers/s390/cio/chsc.c
@@ -14,6 +14,7 @@
 #include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/device.h>
+#include <linux/mutex.h>
 #include <linux/pci.h>
 
 #include <asm/cio.h>
@@ -224,8 +225,9 @@ out_unreg:
 
 void chsc_chp_offline(struct chp_id chpid)
 {
-	char dbf_txt[15];
+	struct channel_path *chp = chpid_to_chp(chpid);
 	struct chp_link link;
+	char dbf_txt[15];
 
 	sprintf(dbf_txt, "chpr%x.%02x", chpid.cssid, chpid.id);
 	CIO_TRACE_EVENT(2, dbf_txt);
@@ -236,6 +238,11 @@ void chsc_chp_offline(struct chp_id chpi
 	link.chpid = chpid;
 	/* Wait until previous actions have settled. */
 	css_wait_for_slow_path();
+
+	mutex_lock(&chp->lock);
+	chp_update_desc(chp);
+	mutex_unlock(&chp->lock);
+
 	for_each_subchannel_staged(s390_subchannel_remove_chpid, NULL, &link);
 }
 
@@ -690,8 +697,9 @@ static void chsc_process_crw(struct crw
 
 void chsc_chp_online(struct chp_id chpid)
 {
-	char dbf_txt[15];
+	struct channel_path *chp = chpid_to_chp(chpid);
 	struct chp_link link;
+	char dbf_txt[15];
 
 	sprintf(dbf_txt, "cadd%x.%02x", chpid.cssid, chpid.id);
 	CIO_TRACE_EVENT(2, dbf_txt);
@@ -701,6 +709,11 @@ void chsc_chp_online(struct chp_id chpid
 		link.chpid = chpid;
 		/* Wait until previous actions have settled. */
 		css_wait_for_slow_path();
+
+		mutex_lock(&chp->lock);
+		chp_update_desc(chp);
+		mutex_unlock(&chp->lock);
+
 		for_each_subchannel_staged(__s390_process_res_acc, NULL,
 					   &link);
 		css_schedule_reprobe();
@@ -967,22 +980,19 @@ static void
 chsc_initialize_cmg_chars(struct channel_path *chp, u8 cmcv,
 			  struct cmg_chars *chars)
 {
-	struct cmg_chars *cmg_chars;
 	int i, mask;
 
-	cmg_chars = chp->cmg_chars;
 	for (i = 0; i < NR_MEASUREMENT_CHARS; i++) {
 		mask = 0x80 >> (i + 3);
 		if (cmcv & mask)
-			cmg_chars->values[i] = chars->values[i];
+			chp->cmg_chars.values[i] = chars->values[i];
 		else
-			cmg_chars->values[i] = 0;
+			chp->cmg_chars.values[i] = 0;
 	}
 }
 
 int chsc_get_channel_measurement_chars(struct channel_path *chp)
 {
-	struct cmg_chars *cmg_chars;
 	int ccode, ret;
 
 	struct {
@@ -1006,10 +1016,11 @@ int chsc_get_channel_measurement_chars(s
 		u32 data[NR_MEASUREMENT_CHARS];
 	} __attribute__ ((packed)) *scmc_area;
 
-	chp->cmg_chars = NULL;
-	cmg_chars = kmalloc(sizeof(*cmg_chars), GFP_KERNEL);
-	if (!cmg_chars)
-		return -ENOMEM;
+	chp->shared = -1;
+	chp->cmg = -1;
+
+	if (!css_chsc_characteristics.scmc || !css_chsc_characteristics.secm)
+		return 0;
 
 	spin_lock_irq(&chsc_page_lock);
 	memset(chsc_page, 0, PAGE_SIZE);
@@ -1031,25 +1042,19 @@ int chsc_get_channel_measurement_chars(s
 			      scmc_area->response.code);
 		goto out;
 	}
-	if (scmc_area->not_valid) {
-		chp->cmg = -1;
-		chp->shared = -1;
+	if (scmc_area->not_valid)
 		goto out;
-	}
+
 	chp->cmg = scmc_area->cmg;
 	chp->shared = scmc_area->shared;
 	if (chp->cmg != 2 && chp->cmg != 3) {
 		/* No cmg-dependent data. */
 		goto out;
 	}
-	chp->cmg_chars = cmg_chars;
 	chsc_initialize_cmg_chars(chp, scmc_area->cmcv,
 				  (struct cmg_chars *) &scmc_area->data);
 out:
 	spin_unlock_irq(&chsc_page_lock);
-	if (!chp->cmg_chars)
-		kfree(cmg_chars);
-
 	return ret;
 }
 
--- zfcpdump-kernel-4.4.orig/drivers/s390/cio/cmf.c
+++ zfcpdump-kernel-4.4/drivers/s390/cio/cmf.c
@@ -753,6 +753,17 @@ static void reset_cmb(struct ccw_device
 	cmf_generic_reset(cdev);
 }
 
+static int cmf_enabled(struct ccw_device *cdev)
+{
+	int enabled;
+
+	spin_lock_irq(cdev->ccwlock);
+	enabled = !!cdev->private->cmb;
+	spin_unlock_irq(cdev->ccwlock);
+
+	return enabled;
+}
+
 static struct attribute_group cmf_attr_group;
 
 static struct cmb_operations cmbops_basic = {
@@ -1153,13 +1164,8 @@ static ssize_t cmb_enable_show(struct de
 			       char *buf)
 {
 	struct ccw_device *cdev = to_ccwdev(dev);
-	int enabled;
 
-	spin_lock_irq(cdev->ccwlock);
-	enabled = !!cdev->private->cmb;
-	spin_unlock_irq(cdev->ccwlock);
-
-	return sprintf(buf, "%d\n", enabled);
+	return sprintf(buf, "%d\n", cmf_enabled(cdev));
 }
 
 static ssize_t cmb_enable_store(struct device *dev,
@@ -1199,15 +1205,20 @@ int ccw_set_cmf(struct ccw_device *cdev,
  *  @cdev:	The ccw device to be enabled
  *
  *  Returns %0 for success or a negative error value.
- *
+ *  Note: If this is called on a device for which channel measurement is already
+ *	  enabled a reset of the measurement data is triggered.
  *  Context:
  *    non-atomic
  */
 int enable_cmf(struct ccw_device *cdev)
 {
-	int ret;
+	int ret = 0;
 
 	device_lock(&cdev->dev);
+	if (cmf_enabled(cdev)) {
+		cmbops->reset(cdev);
+		goto out_unlock;
+	}
 	get_device(&cdev->dev);
 	ret = cmbops->alloc(cdev);
 	if (ret)
@@ -1226,7 +1237,7 @@ int enable_cmf(struct ccw_device *cdev)
 out:
 	if (ret)
 		put_device(&cdev->dev);
-
+out_unlock:
 	device_unlock(&cdev->dev);
 	return ret;
 }
--- zfcpdump-kernel-4.4.orig/drivers/s390/net/qeth_l2_main.c
+++ zfcpdump-kernel-4.4/drivers/s390/net/qeth_l2_main.c
@@ -1051,6 +1051,7 @@ static void qeth_l2_remove_device(struct
 		qeth_l2_set_offline(cgdev);
 
 	if (card->dev) {
+		netif_napi_del(&card->napi);
 		unregister_netdev(card->dev);
 		card->dev = NULL;
 	}
@@ -1126,6 +1127,7 @@ static int qeth_l2_setup_netdev(struct q
 	qeth_l2_request_initial_mac(card);
 	SET_NETDEV_DEV(card->dev, &card->gdev->dev);
 	netif_napi_add(card->dev, &card->napi, qeth_l2_poll, QETH_NAPI_WEIGHT);
+	netif_carrier_off(card->dev);
 	return register_netdev(card->dev);
 }
 
--- zfcpdump-kernel-4.4.orig/drivers/s390/net/qeth_l3_main.c
+++ zfcpdump-kernel-4.4/drivers/s390/net/qeth_l3_main.c
@@ -3220,6 +3220,7 @@ static int qeth_l3_setup_netdev(struct q
 
 	SET_NETDEV_DEV(card->dev, &card->gdev->dev);
 	netif_napi_add(card->dev, &card->napi, qeth_l3_poll, QETH_NAPI_WEIGHT);
+	netif_carrier_off(card->dev);
 	return register_netdev(card->dev);
 }
 
@@ -3246,6 +3247,7 @@ static void qeth_l3_remove_device(struct
 		qeth_l3_set_offline(cgdev);
 
 	if (card->dev) {
+		netif_napi_del(&card->napi);
 		unregister_netdev(card->dev);
 		card->dev = NULL;
 	}
--- zfcpdump-kernel-4.4.orig/drivers/scsi/53c700.c
+++ zfcpdump-kernel-4.4/drivers/scsi/53c700.c
@@ -1122,7 +1122,7 @@ process_script_interrupt(__u32 dsps, __u
 		} else {
 			struct scsi_cmnd *SCp;
 
-			SCp = scsi_host_find_tag(SDp->host, SCSI_NO_TAG);
+			SCp = SDp->current_cmnd;
 			if(unlikely(SCp == NULL)) {
 				sdev_printk(KERN_ERR, SDp,
 					"no saved request for untagged cmd\n");
@@ -1826,7 +1826,7 @@ NCR_700_queuecommand_lck(struct scsi_cmn
 		       slot->tag, slot);
 	} else {
 		slot->tag = SCSI_NO_TAG;
-		/* must populate current_cmnd for scsi_host_find_tag to work */
+		/* save current command for reselection */
 		SCp->device->current_cmnd = SCp;
 	}
 	/* sanity check: some of the commands generated by the mid-layer
--- zfcpdump-kernel-4.4.orig/drivers/scsi/Kconfig
+++ zfcpdump-kernel-4.4/drivers/scsi/Kconfig
@@ -845,6 +845,23 @@ config SCSI_IBMVSCSI
 	  To compile this driver as a module, choose M here: the
 	  module will be called ibmvscsi.
 
+config SCSI_IBMVSCSIS
+	tristate "IBM Virtual SCSI Server support"
+	depends on PPC_PSERIES && TARGET_CORE && SCSI && PCI
+	help
+	  This is the IBM POWER Virtual SCSI Target Server
+	  This driver uses the SRP protocol for communication betwen servers
+	  guest and/or the host that run on the same server.
+	  More information on VSCSI protocol can be found at www.power.org
+
+	  The userspace configuration needed to initialize the driver can be
+	  be found here:
+
+	  https://github.com/powervm/ibmvscsis/wiki/Configuration
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called ibmvscsis.
+
 config SCSI_IBMVFC
 	tristate "IBM Virtual FC support"
 	depends on PPC_PSERIES && SCSI
--- zfcpdump-kernel-4.4.orig/drivers/scsi/Makefile
+++ zfcpdump-kernel-4.4/drivers/scsi/Makefile
@@ -128,6 +128,7 @@ obj-$(CONFIG_SCSI_SNI_53C710)	+= 53c700.
 obj-$(CONFIG_SCSI_NSP32)	+= nsp32.o
 obj-$(CONFIG_SCSI_IPR)		+= ipr.o
 obj-$(CONFIG_SCSI_IBMVSCSI)	+= ibmvscsi/
+obj-$(CONFIG_SCSI_IBMVSCSIS)	+= ibmvscsi_tgt/
 obj-$(CONFIG_SCSI_IBMVFC)	+= ibmvscsi/
 obj-$(CONFIG_SCSI_HPTIOP)	+= hptiop.o
 obj-$(CONFIG_SCSI_STEX)		+= stex.o
--- zfcpdump-kernel-4.4.orig/drivers/scsi/aacraid/aacraid.h
+++ zfcpdump-kernel-4.4/drivers/scsi/aacraid/aacraid.h
@@ -29,6 +29,7 @@ enum {
 #define AAC_INT_MODE_MSI		(1<<1)
 #define AAC_INT_MODE_AIF		(1<<2)
 #define AAC_INT_MODE_SYNC		(1<<3)
+#define AAC_INT_MODE_MSIX		(1<<16)
 
 #define AAC_INT_ENABLE_TYPE1_INTX	0xfffffffb
 #define AAC_INT_ENABLE_TYPE1_MSIX	0xfffffffa
@@ -944,6 +945,7 @@ struct fib {
 	 */
 	struct list_head	fiblink;
 	void			*data;
+	u32			vector_no;
 	struct hw_fib		*hw_fib_va;		/* Actual shared object */
 	dma_addr_t		hw_fib_pa;		/* physical address of hw_fib*/
 };
@@ -2113,6 +2115,7 @@ static inline unsigned int cap_to_cyls(s
 int aac_acquire_irq(struct aac_dev *dev);
 void aac_free_irq(struct aac_dev *dev);
 const char *aac_driverinfo(struct Scsi_Host *);
+void aac_fib_vector_assign(struct aac_dev *dev);
 struct fib *aac_fib_alloc(struct aac_dev *dev);
 int aac_fib_setup(struct aac_dev *dev);
 void aac_fib_map_free(struct aac_dev *dev);
--- zfcpdump-kernel-4.4.orig/drivers/scsi/aacraid/commctrl.c
+++ zfcpdump-kernel-4.4/drivers/scsi/aacraid/commctrl.c
@@ -63,7 +63,7 @@ static int ioctl_send_fib(struct aac_dev
 	struct fib *fibptr;
 	struct hw_fib * hw_fib = (struct hw_fib *)0;
 	dma_addr_t hw_fib_pa = (dma_addr_t)0LL;
-	unsigned size;
+	unsigned int size, osize;
 	int retval;
 
 	if (dev->in_reset) {
@@ -87,7 +87,8 @@ static int ioctl_send_fib(struct aac_dev
 	 *	will not overrun the buffer when we copy the memory. Return
 	 *	an error if we would.
 	 */
-	size = le16_to_cpu(kfib->header.Size) + sizeof(struct aac_fibhdr);
+	osize = size = le16_to_cpu(kfib->header.Size) +
+		sizeof(struct aac_fibhdr);
 	if (size < le16_to_cpu(kfib->header.SenderSize))
 		size = le16_to_cpu(kfib->header.SenderSize);
 	if (size > dev->max_fib_size) {
@@ -118,6 +119,14 @@ static int ioctl_send_fib(struct aac_dev
 		goto cleanup;
 	}
 
+	/* Sanity check the second copy */
+	if ((osize != le16_to_cpu(kfib->header.Size) +
+		sizeof(struct aac_fibhdr))
+		|| (size < le16_to_cpu(kfib->header.SenderSize))) {
+		retval = -EINVAL;
+		goto cleanup;
+	}
+
 	if (kfib->header.Command == cpu_to_le16(TakeABreakPt)) {
 		aac_adapter_interrupt(dev);
 		/*
--- zfcpdump-kernel-4.4.orig/drivers/scsi/aacraid/comminit.c
+++ zfcpdump-kernel-4.4/drivers/scsi/aacraid/comminit.c
@@ -37,6 +37,7 @@
 #include <linux/spinlock.h>
 #include <linux/slab.h>
 #include <linux/blkdev.h>
+#include <linux/delay.h>
 #include <linux/completion.h>
 #include <linux/mm.h>
 #include <scsi/scsi_host.h>
@@ -47,6 +48,20 @@ struct aac_common aac_config = {
 	.irq_mod = 1
 };
 
+static inline int aac_is_msix_mode(struct aac_dev *dev)
+{
+	u32 status;
+
+	status = src_readl(dev, MUnit.OMR);
+	return (status & AAC_INT_MODE_MSIX);
+}
+
+static inline void aac_change_to_intx(struct aac_dev *dev)
+{
+	aac_src_access_devreg(dev, AAC_DISABLE_MSIX);
+	aac_src_access_devreg(dev, AAC_ENABLE_INTX);
+}
+
 static int aac_alloc_comm(struct aac_dev *dev, void **commaddr, unsigned long commsize, unsigned long commalign)
 {
 	unsigned char *base;
@@ -425,6 +440,15 @@ struct aac_dev *aac_init_adapter(struct
 	dev->comm_interface = AAC_COMM_PRODUCER;
 	dev->raw_io_interface = dev->raw_io_64 = 0;
 
+
+	/*
+	 * Enable INTX mode, if not done already Enabled
+	 */
+	if (aac_is_msix_mode(dev)) {
+		aac_change_to_intx(dev);
+		dev_info(&dev->pdev->dev, "Changed firmware to INTX mode");
+	}
+
 	if ((!aac_adapter_sync_cmd(dev, GET_ADAPTER_PROPERTIES,
 		0, 0, 0, 0, 0, 0,
 		status+0, status+1, status+2, status+3, NULL)) &&
--- zfcpdump-kernel-4.4.orig/drivers/scsi/aacraid/commsup.c
+++ zfcpdump-kernel-4.4/drivers/scsi/aacraid/commsup.c
@@ -83,13 +83,38 @@ static int fib_map_alloc(struct aac_dev
 
 void aac_fib_map_free(struct aac_dev *dev)
 {
-	pci_free_consistent(dev->pdev,
-	  dev->max_fib_size * (dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB),
-	  dev->hw_fib_va, dev->hw_fib_pa);
+	if (dev->hw_fib_va && dev->max_fib_size) {
+		pci_free_consistent(dev->pdev,
+		(dev->max_fib_size *
+		(dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB)),
+		dev->hw_fib_va, dev->hw_fib_pa);
+	}
 	dev->hw_fib_va = NULL;
 	dev->hw_fib_pa = 0;
 }
 
+void aac_fib_vector_assign(struct aac_dev *dev)
+{
+	u32 i = 0;
+	u32 vector = 1;
+	struct fib *fibptr = NULL;
+
+	for (i = 0, fibptr = &dev->fibs[i];
+		i < (dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB);
+		i++, fibptr++) {
+		if ((dev->max_msix == 1) ||
+		  (i > ((dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB - 1)
+			- dev->vector_cap))) {
+			fibptr->vector_no = 0;
+		} else {
+			fibptr->vector_no = vector;
+			vector++;
+			if (vector == dev->max_msix)
+				vector = 1;
+		}
+	}
+}
+
 /**
  *	aac_fib_setup	-	setup the fibs
  *	@dev: Adapter to set up
@@ -151,6 +176,12 @@ int aac_fib_setup(struct aac_dev * dev)
 		hw_fib_pa = hw_fib_pa +
 			dev->max_fib_size + sizeof(struct aac_fib_xporthdr);
 	}
+
+	/*
+	 *Assign vector numbers to fibs
+	 */
+	aac_fib_vector_assign(dev);
+
 	/*
 	 *	Add the fib chain to the free list
 	 */
@@ -580,10 +611,10 @@ int aac_fib_send(u16 command, struct fib
 					}
 					return -EFAULT;
 				}
-				/* We used to udelay() here but that absorbed
-				 * a CPU when a timeout occured. Not very
-				 * useful. */
-				cpu_relax();
+				/*
+				 * Allow other processes / CPUS to use core
+				 */
+				schedule();
 			}
 		} else if (down_interruptible(&fibptr->event_wait)) {
 			/* Do nothing ... satisfy
@@ -1939,6 +1970,10 @@ int aac_command_thread(void *data)
 		if (difference <= 0)
 			difference = 1;
 		set_current_state(TASK_INTERRUPTIBLE);
+
+		if (kthread_should_stop())
+			break;
+
 		schedule_timeout(difference);
 
 		if (kthread_should_stop())
--- zfcpdump-kernel-4.4.orig/drivers/scsi/aacraid/linit.c
+++ zfcpdump-kernel-4.4/drivers/scsi/aacraid/linit.c
@@ -1404,8 +1404,18 @@ static int aac_acquire_resources(struct
 
 	aac_adapter_enable_int(dev);
 
-	if (!dev->sync_mode)
+	/*max msix may change  after EEH
+	 * Re-assign vectors to fibs
+	 */
+	aac_fib_vector_assign(dev);
+
+	if (!dev->sync_mode) {
+		/* After EEH recovery or suspend resume, max_msix count
+		 * may change, therfore updating in init as well.
+		 */
 		aac_adapter_start(dev);
+		dev->init->Sa_MSIXVectors = cpu_to_le32(dev->max_msix);
+	}
 	return 0;
 
 error_iounmap:
--- zfcpdump-kernel-4.4.orig/drivers/scsi/aacraid/src.c
+++ zfcpdump-kernel-4.4/drivers/scsi/aacraid/src.c
@@ -156,8 +156,8 @@ static irqreturn_t aac_src_intr_message(
 				break;
 			if (dev->msi_enabled && dev->max_msix > 1)
 				atomic_dec(&dev->rrq_outstanding[vector_no]);
-			aac_intr_normal(dev, handle-1, 0, isFastResponse, NULL);
 			dev->host_rrq[index++] = 0;
+			aac_intr_normal(dev, handle-1, 0, isFastResponse, NULL);
 			if (index == (vector_no + 1) * dev->vector_cap)
 				index = vector_no * dev->vector_cap;
 			dev->host_rrq_idx[vector_no] = index;
@@ -452,36 +452,20 @@ static int aac_src_deliver_message(struc
 #endif
 
 	u16 hdr_size = le16_to_cpu(fib->hw_fib_va->header.Size);
+	u16 vector_no;
 
 	atomic_inc(&q->numpending);
 
 	if (dev->msi_enabled && fib->hw_fib_va->header.Command != AifRequest &&
 	    dev->max_msix > 1) {
-		u_int16_t vector_no, first_choice = 0xffff;
-
-		vector_no = dev->fibs_pushed_no % dev->max_msix;
-		do {
-			vector_no += 1;
-			if (vector_no == dev->max_msix)
-				vector_no = 1;
-			if (atomic_read(&dev->rrq_outstanding[vector_no]) <
-			    dev->vector_cap)
-				break;
-			if (0xffff == first_choice)
-				first_choice = vector_no;
-			else if (vector_no == first_choice)
-				break;
-		} while (1);
-		if (vector_no == first_choice)
-			vector_no = 0;
-		atomic_inc(&dev->rrq_outstanding[vector_no]);
-		if (dev->fibs_pushed_no == 0xffffffff)
-			dev->fibs_pushed_no = 0;
-		else
-			dev->fibs_pushed_no++;
+		vector_no = fib->vector_no;
 		fib->hw_fib_va->header.Handle += (vector_no << 16);
+	} else {
+		vector_no = 0;
 	}
 
+	atomic_inc(&dev->rrq_outstanding[vector_no]);
+
 	if (dev->comm_interface == AAC_COMM_MESSAGE_TYPE2) {
 		/* Calculate the amount to the fibsize bits */
 		fibsize = (hdr_size + 127) / 128 - 1;
--- zfcpdump-kernel-4.4.orig/drivers/scsi/aic7xxx/aic7xxx_osm.c
+++ zfcpdump-kernel-4.4/drivers/scsi/aic7xxx/aic7xxx_osm.c
@@ -1336,6 +1336,7 @@ ahc_platform_set_tags(struct ahc_softc *
 	case AHC_DEV_Q_TAGGED:
 		scsi_change_queue_depth(sdev,
 				dev->openings + dev->active);
+		break;
 	default:
 		/*
 		 * We allow the OS to queue 2 untagged transactions to
--- zfcpdump-kernel-4.4.orig/drivers/scsi/arcmsr/arcmsr.h
+++ zfcpdump-kernel-4.4/drivers/scsi/arcmsr/arcmsr.h
@@ -52,7 +52,7 @@ struct device_attribute;
 	#define ARCMSR_MAX_FREECCB_NUM	320
 #define ARCMSR_MAX_OUTSTANDING_CMD	255
 #endif
-#define ARCMSR_DRIVER_VERSION		"v1.30.00.04-20140919"
+#define ARCMSR_DRIVER_VERSION		"v1.30.00.22-20151126"
 #define ARCMSR_SCSI_INITIATOR_ID						255
 #define ARCMSR_MAX_XFER_SECTORS							512
 #define ARCMSR_MAX_XFER_SECTORS_B						4096
@@ -74,6 +74,9 @@ struct device_attribute;
 #ifndef PCI_DEVICE_ID_ARECA_1214
 	#define PCI_DEVICE_ID_ARECA_1214	0x1214
 #endif
+#ifndef PCI_DEVICE_ID_ARECA_1203
+	#define PCI_DEVICE_ID_ARECA_1203	0x1203
+#endif
 /*
 **********************************************************************************
 **
@@ -245,6 +248,12 @@ struct FIRMWARE_INFO
 /* window of "instruction flags" from iop to driver */
 #define ARCMSR_IOP2DRV_DOORBELL                       0x00020408
 #define ARCMSR_IOP2DRV_DOORBELL_MASK                  0x0002040C
+/* window of "instruction flags" from iop to driver */
+#define ARCMSR_IOP2DRV_DOORBELL_1203                  0x00021870
+#define ARCMSR_IOP2DRV_DOORBELL_MASK_1203             0x00021874
+/* window of "instruction flags" from driver to iop */
+#define ARCMSR_DRV2IOP_DOORBELL_1203                  0x00021878
+#define ARCMSR_DRV2IOP_DOORBELL_MASK_1203             0x0002187C
 /* ARECA FLAG LANGUAGE */
 /* ioctl transfer */
 #define ARCMSR_IOP2DRV_DATA_WRITE_OK                  0x00000001
@@ -288,6 +297,9 @@ struct FIRMWARE_INFO
 #define ARCMSR_MESSAGE_RBUFFER			      0x0000ff00
 /* iop message_rwbuffer for message command */
 #define ARCMSR_MESSAGE_RWBUFFER			      0x0000fa00
+
+#define MEM_BASE0(x)	(u32 __iomem *)((unsigned long)acb->mem_base0 + x)
+#define MEM_BASE1(x)	(u32 __iomem *)((unsigned long)acb->mem_base1 + x)
 /* 
 ************************************************************************
 **                SPEC. for Areca HBC adapter
--- zfcpdump-kernel-4.4.orig/drivers/scsi/arcmsr/arcmsr_hba.c
+++ zfcpdump-kernel-4.4/drivers/scsi/arcmsr/arcmsr_hba.c
@@ -114,6 +114,7 @@ static void arcmsr_hardware_reset(struct
 static const char *arcmsr_info(struct Scsi_Host *);
 static irqreturn_t arcmsr_interrupt(struct AdapterControlBlock *acb);
 static void arcmsr_free_irq(struct pci_dev *, struct AdapterControlBlock *);
+static void arcmsr_wait_firmware_ready(struct AdapterControlBlock *acb);
 static int arcmsr_adjust_disk_queue_depth(struct scsi_device *sdev, int queue_depth)
 {
 	if (queue_depth > ARCMSR_MAX_CMD_PERLUN)
@@ -157,6 +158,8 @@ static struct pci_device_id arcmsr_devic
 		.driver_data = ACB_ADAPTER_TYPE_B},
 	{PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1202),
 		.driver_data = ACB_ADAPTER_TYPE_B},
+	{PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1203),
+		.driver_data = ACB_ADAPTER_TYPE_B},
 	{PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1210),
 		.driver_data = ACB_ADAPTER_TYPE_A},
 	{PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1214),
@@ -495,6 +498,91 @@ static void arcmsr_flush_adapter_cache(s
 	}
 }
 
+static bool arcmsr_alloc_io_queue(struct AdapterControlBlock *acb)
+{
+	bool rtn = true;
+	void *dma_coherent;
+	dma_addr_t dma_coherent_handle;
+	struct pci_dev *pdev = acb->pdev;
+
+	switch (acb->adapter_type) {
+	case ACB_ADAPTER_TYPE_B: {
+		struct MessageUnit_B *reg;
+		acb->roundup_ccbsize = roundup(sizeof(struct MessageUnit_B), 32);
+		dma_coherent = dma_zalloc_coherent(&pdev->dev, acb->roundup_ccbsize,
+			&dma_coherent_handle, GFP_KERNEL);
+		if (!dma_coherent) {
+			pr_notice("arcmsr%d: DMA allocation failed\n", acb->host->host_no);
+			return false;
+		}
+		acb->dma_coherent_handle2 = dma_coherent_handle;
+		acb->dma_coherent2 = dma_coherent;
+		reg = (struct MessageUnit_B *)dma_coherent;
+		acb->pmuB = reg;
+		if (acb->pdev->device == PCI_DEVICE_ID_ARECA_1203) {
+			reg->drv2iop_doorbell = MEM_BASE0(ARCMSR_DRV2IOP_DOORBELL_1203);
+			reg->drv2iop_doorbell_mask = MEM_BASE0(ARCMSR_DRV2IOP_DOORBELL_MASK_1203);
+			reg->iop2drv_doorbell = MEM_BASE0(ARCMSR_IOP2DRV_DOORBELL_1203);
+			reg->iop2drv_doorbell_mask = MEM_BASE0(ARCMSR_IOP2DRV_DOORBELL_MASK_1203);
+		} else {
+			reg->drv2iop_doorbell = MEM_BASE0(ARCMSR_DRV2IOP_DOORBELL);
+			reg->drv2iop_doorbell_mask = MEM_BASE0(ARCMSR_DRV2IOP_DOORBELL_MASK);
+			reg->iop2drv_doorbell = MEM_BASE0(ARCMSR_IOP2DRV_DOORBELL);
+			reg->iop2drv_doorbell_mask = MEM_BASE0(ARCMSR_IOP2DRV_DOORBELL_MASK);
+		}
+		reg->message_wbuffer = MEM_BASE1(ARCMSR_MESSAGE_WBUFFER);
+		reg->message_rbuffer = MEM_BASE1(ARCMSR_MESSAGE_RBUFFER);
+		reg->message_rwbuffer = MEM_BASE1(ARCMSR_MESSAGE_RWBUFFER);
+		}
+		break;
+	case ACB_ADAPTER_TYPE_D: {
+		struct MessageUnit_D *reg;
+
+		acb->roundup_ccbsize = roundup(sizeof(struct MessageUnit_D), 32);
+		dma_coherent = dma_zalloc_coherent(&pdev->dev, acb->roundup_ccbsize,
+			&dma_coherent_handle, GFP_KERNEL);
+		if (!dma_coherent) {
+			pr_notice("arcmsr%d: DMA allocation failed\n", acb->host->host_no);
+			return false;
+		}
+		acb->dma_coherent_handle2 = dma_coherent_handle;
+		acb->dma_coherent2 = dma_coherent;
+		reg = (struct MessageUnit_D *)dma_coherent;
+		acb->pmuD = reg;
+		reg->chip_id = MEM_BASE0(ARCMSR_ARC1214_CHIP_ID);
+		reg->cpu_mem_config = MEM_BASE0(ARCMSR_ARC1214_CPU_MEMORY_CONFIGURATION);
+		reg->i2o_host_interrupt_mask = MEM_BASE0(ARCMSR_ARC1214_I2_HOST_INTERRUPT_MASK);
+		reg->sample_at_reset = MEM_BASE0(ARCMSR_ARC1214_SAMPLE_RESET);
+		reg->reset_request = MEM_BASE0(ARCMSR_ARC1214_RESET_REQUEST);
+		reg->host_int_status = MEM_BASE0(ARCMSR_ARC1214_MAIN_INTERRUPT_STATUS);
+		reg->pcief0_int_enable = MEM_BASE0(ARCMSR_ARC1214_PCIE_F0_INTERRUPT_ENABLE);
+		reg->inbound_msgaddr0 = MEM_BASE0(ARCMSR_ARC1214_INBOUND_MESSAGE0);
+		reg->inbound_msgaddr1 = MEM_BASE0(ARCMSR_ARC1214_INBOUND_MESSAGE1);
+		reg->outbound_msgaddr0 = MEM_BASE0(ARCMSR_ARC1214_OUTBOUND_MESSAGE0);
+		reg->outbound_msgaddr1 = MEM_BASE0(ARCMSR_ARC1214_OUTBOUND_MESSAGE1);
+		reg->inbound_doorbell = MEM_BASE0(ARCMSR_ARC1214_INBOUND_DOORBELL);
+		reg->outbound_doorbell = MEM_BASE0(ARCMSR_ARC1214_OUTBOUND_DOORBELL);
+		reg->outbound_doorbell_enable = MEM_BASE0(ARCMSR_ARC1214_OUTBOUND_DOORBELL_ENABLE);
+		reg->inboundlist_base_low = MEM_BASE0(ARCMSR_ARC1214_INBOUND_LIST_BASE_LOW);
+		reg->inboundlist_base_high = MEM_BASE0(ARCMSR_ARC1214_INBOUND_LIST_BASE_HIGH);
+		reg->inboundlist_write_pointer = MEM_BASE0(ARCMSR_ARC1214_INBOUND_LIST_WRITE_POINTER);
+		reg->outboundlist_base_low = MEM_BASE0(ARCMSR_ARC1214_OUTBOUND_LIST_BASE_LOW);
+		reg->outboundlist_base_high = MEM_BASE0(ARCMSR_ARC1214_OUTBOUND_LIST_BASE_HIGH);
+		reg->outboundlist_copy_pointer = MEM_BASE0(ARCMSR_ARC1214_OUTBOUND_LIST_COPY_POINTER);
+		reg->outboundlist_read_pointer = MEM_BASE0(ARCMSR_ARC1214_OUTBOUND_LIST_READ_POINTER);
+		reg->outboundlist_interrupt_cause = MEM_BASE0(ARCMSR_ARC1214_OUTBOUND_INTERRUPT_CAUSE);
+		reg->outboundlist_interrupt_enable = MEM_BASE0(ARCMSR_ARC1214_OUTBOUND_INTERRUPT_ENABLE);
+		reg->message_wbuffer = MEM_BASE0(ARCMSR_ARC1214_MESSAGE_WBUFFER);
+		reg->message_rbuffer = MEM_BASE0(ARCMSR_ARC1214_MESSAGE_RBUFFER);
+		reg->msgcode_rwbuffer = MEM_BASE0(ARCMSR_ARC1214_MESSAGE_RWBUFFER);
+		}
+		break;
+	default:
+		break;
+	}
+	return rtn;
+}
+
 static int arcmsr_alloc_ccb_pool(struct AdapterControlBlock *acb)
 {
 	struct pci_dev *pdev = acb->pdev;
@@ -739,9 +827,12 @@ static int arcmsr_probe(struct pci_dev *
 	if(!error){
 		goto pci_release_regs;
 	}
+	error = arcmsr_alloc_io_queue(acb);
+	if (!error)
+		goto unmap_pci_region;
 	error = arcmsr_get_firmware_spec(acb);
 	if(!error){
-		goto unmap_pci_region;
+		goto free_hbb_mu;
 	}
 	error = arcmsr_alloc_ccb_pool(acb);
 	if(error){
@@ -2622,9 +2713,6 @@ static bool arcmsr_hbaA_get_config(struc
 static bool arcmsr_hbaB_get_config(struct AdapterControlBlock *acb)
 {
 	struct MessageUnit_B *reg = acb->pmuB;
-	struct pci_dev *pdev = acb->pdev;
-	void *dma_coherent;
-	dma_addr_t dma_coherent_handle;
 	char *acb_firm_model = acb->firm_model;
 	char *acb_firm_version = acb->firm_version;
 	char *acb_device_map = acb->device_map;
@@ -2636,30 +2724,16 @@ static bool arcmsr_hbaB_get_config(struc
 	/*firm_version,21,84-99*/
 	int count;
 
-	acb->roundup_ccbsize = roundup(sizeof(struct MessageUnit_B), 32);
-	dma_coherent = dma_alloc_coherent(&pdev->dev, acb->roundup_ccbsize,
-			&dma_coherent_handle, GFP_KERNEL);
-	if (!dma_coherent){
-		printk(KERN_NOTICE
-			"arcmsr%d: dma_alloc_coherent got error for hbb mu\n",
-			acb->host->host_no);
-		return false;
-	}
-	acb->dma_coherent_handle2 = dma_coherent_handle;
-	acb->dma_coherent2 = dma_coherent;
-	reg = (struct MessageUnit_B *)dma_coherent;
-	acb->pmuB = reg;
-	reg->drv2iop_doorbell= (uint32_t __iomem *)((unsigned long)acb->mem_base0 + ARCMSR_DRV2IOP_DOORBELL);
-	reg->drv2iop_doorbell_mask = (uint32_t __iomem *)((unsigned long)acb->mem_base0 + ARCMSR_DRV2IOP_DOORBELL_MASK);
-	reg->iop2drv_doorbell = (uint32_t __iomem *)((unsigned long)acb->mem_base0 + ARCMSR_IOP2DRV_DOORBELL);
-	reg->iop2drv_doorbell_mask = (uint32_t __iomem *)((unsigned long)acb->mem_base0 + ARCMSR_IOP2DRV_DOORBELL_MASK);
-	reg->message_wbuffer = (uint32_t __iomem *)((unsigned long)acb->mem_base1 + ARCMSR_MESSAGE_WBUFFER);
-	reg->message_rbuffer =  (uint32_t __iomem *)((unsigned long)acb->mem_base1 + ARCMSR_MESSAGE_RBUFFER);
-	reg->message_rwbuffer = (uint32_t __iomem *)((unsigned long)acb->mem_base1 + ARCMSR_MESSAGE_RWBUFFER);
 	iop_firm_model = (char __iomem *)(&reg->message_rwbuffer[15]);	/*firm_model,15,60-67*/
 	iop_firm_version = (char __iomem *)(&reg->message_rwbuffer[17]);	/*firm_version,17,68-83*/
 	iop_device_map = (char __iomem *)(&reg->message_rwbuffer[21]);	/*firm_version,21,84-99*/
 
+	arcmsr_wait_firmware_ready(acb);
+	writel(ARCMSR_MESSAGE_START_DRIVER_MODE, reg->drv2iop_doorbell);
+	if (!arcmsr_hbaB_wait_msgint_ready(acb)) {
+		printk(KERN_ERR "arcmsr%d: can't set driver mode.\n", acb->host->host_no);
+		return false;
+	}
 	writel(ARCMSR_MESSAGE_GET_CONFIG, reg->drv2iop_doorbell);
 	if (!arcmsr_hbaB_wait_msgint_ready(acb)) {
 		printk(KERN_NOTICE "arcmsr%d: wait 'get adapter firmware \
@@ -2694,15 +2768,15 @@ static bool arcmsr_hbaB_get_config(struc
 		acb->firm_model,
 		acb->firm_version);
 
-	acb->signature = readl(&reg->message_rwbuffer[1]);
+	acb->signature = readl(&reg->message_rwbuffer[0]);
 	/*firm_signature,1,00-03*/
-	acb->firm_request_len = readl(&reg->message_rwbuffer[2]);
+	acb->firm_request_len = readl(&reg->message_rwbuffer[1]);
 	/*firm_request_len,1,04-07*/
-	acb->firm_numbers_queue = readl(&reg->message_rwbuffer[3]);
+	acb->firm_numbers_queue = readl(&reg->message_rwbuffer[2]);
 	/*firm_numbers_queue,2,08-11*/
-	acb->firm_sdram_size = readl(&reg->message_rwbuffer[4]);
+	acb->firm_sdram_size = readl(&reg->message_rwbuffer[3]);
 	/*firm_sdram_size,3,12-15*/
-	acb->firm_hd_channels = readl(&reg->message_rwbuffer[5]);
+	acb->firm_hd_channels = readl(&reg->message_rwbuffer[4]);
 	/*firm_ide_channels,4,16-19*/
 	acb->firm_cfg_version = readl(&reg->message_rwbuffer[25]);  /*firm_cfg_version,25,100-103*/
 	/*firm_ide_channels,4,16-19*/
@@ -2777,70 +2851,8 @@ static bool arcmsr_hbaD_get_config(struc
 	char __iomem *iop_firm_version;
 	char __iomem *iop_device_map;
 	u32 count;
-	struct MessageUnit_D *reg;
-	void *dma_coherent2;
-	dma_addr_t dma_coherent_handle2;
-	struct pci_dev *pdev = acb->pdev;
+	struct MessageUnit_D *reg = acb->pmuD;
 
-	acb->roundup_ccbsize = roundup(sizeof(struct MessageUnit_D), 32);
-	dma_coherent2 = dma_alloc_coherent(&pdev->dev, acb->roundup_ccbsize,
-		&dma_coherent_handle2, GFP_KERNEL);
-	if (!dma_coherent2) {
-		pr_notice("DMA allocation failed...\n");
-		return false;
-	}
-	memset(dma_coherent2, 0, acb->roundup_ccbsize);
-	acb->dma_coherent_handle2 = dma_coherent_handle2;
-	acb->dma_coherent2 = dma_coherent2;
-	reg = (struct MessageUnit_D *)dma_coherent2;
-	acb->pmuD = reg;
-	reg->chip_id = acb->mem_base0 + ARCMSR_ARC1214_CHIP_ID;
-	reg->cpu_mem_config = acb->mem_base0 +
-		ARCMSR_ARC1214_CPU_MEMORY_CONFIGURATION;
-	reg->i2o_host_interrupt_mask = acb->mem_base0 +
-		ARCMSR_ARC1214_I2_HOST_INTERRUPT_MASK;
-	reg->sample_at_reset = acb->mem_base0 + ARCMSR_ARC1214_SAMPLE_RESET;
-	reg->reset_request = acb->mem_base0 + ARCMSR_ARC1214_RESET_REQUEST;
-	reg->host_int_status = acb->mem_base0 +
-		ARCMSR_ARC1214_MAIN_INTERRUPT_STATUS;
-	reg->pcief0_int_enable = acb->mem_base0 +
-		ARCMSR_ARC1214_PCIE_F0_INTERRUPT_ENABLE;
-	reg->inbound_msgaddr0 = acb->mem_base0 +
-		ARCMSR_ARC1214_INBOUND_MESSAGE0;
-	reg->inbound_msgaddr1 = acb->mem_base0 +
-		ARCMSR_ARC1214_INBOUND_MESSAGE1;
-	reg->outbound_msgaddr0 = acb->mem_base0 +
-		ARCMSR_ARC1214_OUTBOUND_MESSAGE0;
-	reg->outbound_msgaddr1 = acb->mem_base0 +
-		ARCMSR_ARC1214_OUTBOUND_MESSAGE1;
-	reg->inbound_doorbell = acb->mem_base0 +
-		ARCMSR_ARC1214_INBOUND_DOORBELL;
-	reg->outbound_doorbell = acb->mem_base0 +
-		ARCMSR_ARC1214_OUTBOUND_DOORBELL;
-	reg->outbound_doorbell_enable = acb->mem_base0 +
-		ARCMSR_ARC1214_OUTBOUND_DOORBELL_ENABLE;
-	reg->inboundlist_base_low = acb->mem_base0 +
-		ARCMSR_ARC1214_INBOUND_LIST_BASE_LOW;
-	reg->inboundlist_base_high = acb->mem_base0 +
-		ARCMSR_ARC1214_INBOUND_LIST_BASE_HIGH;
-	reg->inboundlist_write_pointer = acb->mem_base0 +
-		ARCMSR_ARC1214_INBOUND_LIST_WRITE_POINTER;
-	reg->outboundlist_base_low = acb->mem_base0 +
-		ARCMSR_ARC1214_OUTBOUND_LIST_BASE_LOW;
-	reg->outboundlist_base_high = acb->mem_base0 +
-		ARCMSR_ARC1214_OUTBOUND_LIST_BASE_HIGH;
-	reg->outboundlist_copy_pointer = acb->mem_base0 +
-		ARCMSR_ARC1214_OUTBOUND_LIST_COPY_POINTER;
-	reg->outboundlist_read_pointer = acb->mem_base0 +
-		ARCMSR_ARC1214_OUTBOUND_LIST_READ_POINTER;
-	reg->outboundlist_interrupt_cause = acb->mem_base0 +
-		ARCMSR_ARC1214_OUTBOUND_INTERRUPT_CAUSE;
-	reg->outboundlist_interrupt_enable = acb->mem_base0 +
-		ARCMSR_ARC1214_OUTBOUND_INTERRUPT_ENABLE;
-	reg->message_wbuffer = acb->mem_base0 + ARCMSR_ARC1214_MESSAGE_WBUFFER;
-	reg->message_rbuffer = acb->mem_base0 + ARCMSR_ARC1214_MESSAGE_RBUFFER;
-	reg->msgcode_rwbuffer = acb->mem_base0 +
-		ARCMSR_ARC1214_MESSAGE_RWBUFFER;
 	iop_firm_model = (char __iomem *)(&reg->msgcode_rwbuffer[15]);
 	iop_firm_version = (char __iomem *)(&reg->msgcode_rwbuffer[17]);
 	iop_device_map = (char __iomem *)(&reg->msgcode_rwbuffer[21]);
@@ -2855,8 +2867,6 @@ static bool arcmsr_hbaD_get_config(struc
 	if (!arcmsr_hbaD_wait_msgint_ready(acb)) {
 		pr_notice("arcmsr%d: wait get adapter firmware "
 			"miscellaneous data timeout\n", acb->host->host_no);
-		dma_free_coherent(&acb->pdev->dev, acb->roundup_ccbsize,
-			acb->dma_coherent2, acb->dma_coherent_handle2);
 		return false;
 	}
 	count = 8;
@@ -2880,15 +2890,15 @@ static bool arcmsr_hbaD_get_config(struc
 		iop_device_map++;
 		count--;
 	}
-	acb->signature = readl(&reg->msgcode_rwbuffer[1]);
+	acb->signature = readl(&reg->msgcode_rwbuffer[0]);
 	/*firm_signature,1,00-03*/
-	acb->firm_request_len = readl(&reg->msgcode_rwbuffer[2]);
+	acb->firm_request_len = readl(&reg->msgcode_rwbuffer[1]);
 	/*firm_request_len,1,04-07*/
-	acb->firm_numbers_queue = readl(&reg->msgcode_rwbuffer[3]);
+	acb->firm_numbers_queue = readl(&reg->msgcode_rwbuffer[2]);
 	/*firm_numbers_queue,2,08-11*/
-	acb->firm_sdram_size = readl(&reg->msgcode_rwbuffer[4]);
+	acb->firm_sdram_size = readl(&reg->msgcode_rwbuffer[3]);
 	/*firm_sdram_size,3,12-15*/
-	acb->firm_hd_channels = readl(&reg->msgcode_rwbuffer[5]);
+	acb->firm_hd_channels = readl(&reg->msgcode_rwbuffer[4]);
 	/*firm_hd_channels,4,16-19*/
 	acb->firm_cfg_version = readl(&reg->msgcode_rwbuffer[25]);
 	pr_notice("Areca RAID Controller%d: Model %s, F/W %s\n",
@@ -3998,6 +4008,7 @@ static const char *arcmsr_info(struct Sc
 	case PCI_DEVICE_ID_ARECA_1160:
 	case PCI_DEVICE_ID_ARECA_1170:
 	case PCI_DEVICE_ID_ARECA_1201:
+	case PCI_DEVICE_ID_ARECA_1203:
 	case PCI_DEVICE_ID_ARECA_1220:
 	case PCI_DEVICE_ID_ARECA_1230:
 	case PCI_DEVICE_ID_ARECA_1260:
--- zfcpdump-kernel-4.4.orig/drivers/scsi/be2iscsi/be_main.c
+++ zfcpdump-kernel-4.4/drivers/scsi/be2iscsi/be_main.c
@@ -232,20 +232,20 @@ static int beiscsi_eh_abort(struct scsi_
 	cls_session = starget_to_session(scsi_target(sc->device));
 	session = cls_session->dd_data;
 
-	spin_lock_bh(&session->frwd_lock);
+	spin_lock_bh(&session->lock);
 	if (!aborted_task || !aborted_task->sc) {
 		/* we raced */
-		spin_unlock_bh(&session->frwd_lock);
+		spin_unlock_bh(&session->lock);
 		return SUCCESS;
 	}
 
 	aborted_io_task = aborted_task->dd_data;
 	if (!aborted_io_task->scsi_cmnd) {
 		/* raced or invalid command */
-		spin_unlock_bh(&session->frwd_lock);
+		spin_unlock_bh(&session->lock);
 		return SUCCESS;
 	}
-	spin_unlock_bh(&session->frwd_lock);
+	spin_unlock_bh(&session->lock);
 	/* Invalidate WRB Posted for this Task */
 	AMAP_SET_BITS(struct amap_iscsi_wrb, invld,
 		      aborted_io_task->pwrb_handle->pwrb,
@@ -310,9 +310,9 @@ static int beiscsi_eh_device_reset(struc
 	/* invalidate iocbs */
 	cls_session = starget_to_session(scsi_target(sc->device));
 	session = cls_session->dd_data;
-	spin_lock_bh(&session->frwd_lock);
+	spin_lock_bh(&session->lock);
 	if (!session->leadconn || session->state != ISCSI_STATE_LOGGED_IN) {
-		spin_unlock_bh(&session->frwd_lock);
+		spin_unlock_bh(&session->lock);
 		return FAILED;
 	}
 	conn = session->leadconn;
@@ -341,7 +341,7 @@ static int beiscsi_eh_device_reset(struc
 		num_invalidate++;
 		inv_tbl++;
 	}
-	spin_unlock_bh(&session->frwd_lock);
+	spin_unlock_bh(&session->lock);
 	inv_tbl = phba->inv_tbl;
 
 	nonemb_cmd.va = pci_alloc_consistent(phba->ctrl.pdev,
@@ -1137,9 +1137,9 @@ beiscsi_process_async_pdu(struct beiscsi
 		return 1;
 	}
 
-	spin_lock_bh(&session->back_lock);
+	spin_lock_bh(&session->lock);
 	__iscsi_complete_pdu(conn, (struct iscsi_hdr *)ppdu, pbuffer, buf_len);
-	spin_unlock_bh(&session->back_lock);
+	spin_unlock_bh(&session->lock);
 	return 0;
 }
 
@@ -1562,7 +1562,7 @@ static void hwi_complete_cmd(struct beis
 	pwrb = pwrb_handle->pwrb;
 	type = ((struct beiscsi_io_task *)task->dd_data)->wrb_type;
 
-	spin_lock_bh(&session->back_lock);
+	spin_lock_bh(&session->lock);
 	switch (type) {
 	case HWH_TYPE_IO:
 	case HWH_TYPE_IO_RD:
@@ -1601,7 +1601,7 @@ static void hwi_complete_cmd(struct beis
 		break;
 	}
 
-	spin_unlock_bh(&session->back_lock);
+	spin_unlock_bh(&session->lock);
 }
 
 static struct list_head *hwi_get_async_busy_list(struct hwi_async_pdu_context
@@ -4470,6 +4470,7 @@ put_shost:
 	scsi_host_put(phba->shost);
 free_kset:
 	iscsi_boot_destroy_kset(phba->boot_kset);
+	phba->boot_kset = NULL;
 	return -ENOMEM;
 }
 
@@ -4691,9 +4692,9 @@ beiscsi_offload_connection(struct beiscs
 	 * login/startup related tasks.
 	 */
 	beiscsi_conn->login_in_progress = 0;
-	spin_lock_bh(&session->back_lock);
+	spin_lock_bh(&session->lock);
 	beiscsi_cleanup_task(task);
-	spin_unlock_bh(&session->back_lock);
+	spin_unlock_bh(&session->lock);
 
 	pwrb_handle = alloc_wrb_handle(phba, beiscsi_conn->beiscsi_conn_cid,
 				       &pwrb_context);
--- zfcpdump-kernel-4.4.orig/drivers/scsi/bnx2i/bnx2i_hwi.c
+++ zfcpdump-kernel-4.4/drivers/scsi/bnx2i/bnx2i_hwi.c
@@ -1363,7 +1363,7 @@ int bnx2i_process_scsi_cmd_resp(struct i
 	u32 datalen = 0;
 
 	resp_cqe = (struct bnx2i_cmd_response *)cqe;
-	spin_lock_bh(&session->back_lock);
+	spin_lock_bh(&session->lock);
 	task = iscsi_itt_to_task(conn,
 				 resp_cqe->itt & ISCSI_CMD_RESPONSE_INDEX);
 	if (!task)
@@ -1434,7 +1434,7 @@ done:
 	__iscsi_complete_pdu(conn, (struct iscsi_hdr *)hdr,
 			     conn->data, datalen);
 fail:
-	spin_unlock_bh(&session->back_lock);
+	spin_unlock_bh(&session->lock);
 	return 0;
 }
 
@@ -1459,7 +1459,7 @@ static int bnx2i_process_login_resp(stru
 	int pad_len;
 
 	login = (struct bnx2i_login_response *) cqe;
-	spin_lock(&session->back_lock);
+	spin_lock(&session->lock);
 	task = iscsi_itt_to_task(conn,
 				 login->itt & ISCSI_LOGIN_RESPONSE_INDEX);
 	if (!task)
@@ -1502,7 +1502,7 @@ static int bnx2i_process_login_resp(stru
 		bnx2i_conn->gen_pdu.resp_buf,
 		bnx2i_conn->gen_pdu.resp_wr_ptr - bnx2i_conn->gen_pdu.resp_buf);
 done:
-	spin_unlock(&session->back_lock);
+	spin_unlock(&session->lock);
 	return 0;
 }
 
@@ -1527,7 +1527,7 @@ static int bnx2i_process_text_resp(struc
 	int pad_len;
 
 	text = (struct bnx2i_text_response *) cqe;
-	spin_lock(&session->back_lock);
+	spin_lock(&session->lock);
 	task = iscsi_itt_to_task(conn, text->itt & ISCSI_LOGIN_RESPONSE_INDEX);
 	if (!task)
 		goto done;
@@ -1563,7 +1563,7 @@ static int bnx2i_process_text_resp(struc
 			     bnx2i_conn->gen_pdu.resp_wr_ptr -
 			     bnx2i_conn->gen_pdu.resp_buf);
 done:
-	spin_unlock(&session->back_lock);
+	spin_unlock(&session->lock);
 	return 0;
 }
 
@@ -1586,7 +1586,7 @@ static int bnx2i_process_tmf_resp(struct
 	struct iscsi_tm_rsp *resp_hdr;
 
 	tmf_cqe = (struct bnx2i_tmf_response *)cqe;
-	spin_lock(&session->back_lock);
+	spin_lock(&session->lock);
 	task = iscsi_itt_to_task(conn,
 				 tmf_cqe->itt & ISCSI_TMF_RESPONSE_INDEX);
 	if (!task)
@@ -1602,7 +1602,7 @@ static int bnx2i_process_tmf_resp(struct
 
 	__iscsi_complete_pdu(conn, (struct iscsi_hdr *)resp_hdr, NULL, 0);
 done:
-	spin_unlock(&session->back_lock);
+	spin_unlock(&session->lock);
 	return 0;
 }
 
@@ -1625,7 +1625,7 @@ static int bnx2i_process_logout_resp(str
 	struct iscsi_logout_rsp *resp_hdr;
 
 	logout = (struct bnx2i_logout_response *) cqe;
-	spin_lock(&session->back_lock);
+	spin_lock(&session->lock);
 	task = iscsi_itt_to_task(conn,
 				 logout->itt & ISCSI_LOGOUT_RESPONSE_INDEX);
 	if (!task)
@@ -1649,7 +1649,7 @@ static int bnx2i_process_logout_resp(str
 
 	bnx2i_conn->ep->state = EP_STATE_LOGOUT_RESP_RCVD;
 done:
-	spin_unlock(&session->back_lock);
+	spin_unlock(&session->lock);
 	return 0;
 }
 
@@ -1670,12 +1670,12 @@ static void bnx2i_process_nopin_local_cm
 	struct iscsi_task *task;
 
 	nop_in = (struct bnx2i_nop_in_msg *)cqe;
-	spin_lock(&session->back_lock);
+	spin_lock(&session->lock);
 	task = iscsi_itt_to_task(conn,
 				 nop_in->itt & ISCSI_NOP_IN_MSG_INDEX);
 	if (task)
 		__iscsi_put_task(task);
-	spin_unlock(&session->back_lock);
+	spin_unlock(&session->lock);
 }
 
 /**
@@ -1714,7 +1714,7 @@ static int bnx2i_process_nopin_mesg(stru
 
 	nop_in = (struct bnx2i_nop_in_msg *)cqe;
 
-	spin_lock(&session->back_lock);
+	spin_lock(&session->lock);
 	hdr = (struct iscsi_nopin *)&bnx2i_conn->gen_pdu.resp_hdr;
 	memset(hdr, 0, sizeof(struct iscsi_hdr));
 	hdr->opcode = nop_in->op_code;
@@ -1740,7 +1740,7 @@ static int bnx2i_process_nopin_mesg(stru
 	}
 done:
 	__iscsi_complete_pdu(conn, (struct iscsi_hdr *)hdr, NULL, 0);
-	spin_unlock(&session->back_lock);
+	spin_unlock(&session->lock);
 
 	return tgt_async_nop;
 }
@@ -1773,7 +1773,7 @@ static void bnx2i_process_async_mesg(str
 		return;
 	}
 
-	spin_lock(&session->back_lock);
+	spin_lock(&session->lock);
 	resp_hdr = (struct iscsi_async *) &bnx2i_conn->gen_pdu.resp_hdr;
 	memset(resp_hdr, 0, sizeof(struct iscsi_hdr));
 	resp_hdr->opcode = async_cqe->op_code;
@@ -1792,7 +1792,7 @@ static void bnx2i_process_async_mesg(str
 
 	__iscsi_complete_pdu(bnx2i_conn->cls_conn->dd_data,
 			     (struct iscsi_hdr *)resp_hdr, NULL, 0);
-	spin_unlock(&session->back_lock);
+	spin_unlock(&session->lock);
 }
 
 
@@ -1819,7 +1819,7 @@ static void bnx2i_process_reject_mesg(st
 	} else
 		bnx2i_unsol_pdu_adjust_rq(bnx2i_conn);
 
-	spin_lock(&session->back_lock);
+	spin_lock(&session->lock);
 	hdr = (struct iscsi_reject *) &bnx2i_conn->gen_pdu.resp_hdr;
 	memset(hdr, 0, sizeof(struct iscsi_hdr));
 	hdr->opcode = reject->op_code;
@@ -1830,7 +1830,7 @@ static void bnx2i_process_reject_mesg(st
 	hdr->ffffffff = cpu_to_be32(RESERVED_ITT);
 	__iscsi_complete_pdu(conn, (struct iscsi_hdr *)hdr, conn->data,
 			     reject->data_length);
-	spin_unlock(&session->back_lock);
+	spin_unlock(&session->lock);
 }
 
 /**
@@ -1850,13 +1850,13 @@ static void bnx2i_process_cmd_cleanup_re
 	struct iscsi_task *task;
 
 	cmd_clean_rsp = (struct bnx2i_cleanup_response *)cqe;
-	spin_lock(&session->back_lock);
+	spin_lock(&session->lock);
 	task = iscsi_itt_to_task(conn,
 			cmd_clean_rsp->itt & ISCSI_CLEANUP_RESPONSE_INDEX);
 	if (!task)
 		printk(KERN_ALERT "bnx2i: cmd clean ITT %x not active\n",
 			cmd_clean_rsp->itt & ISCSI_CLEANUP_RESPONSE_INDEX);
-	spin_unlock(&session->back_lock);
+	spin_unlock(&session->lock);
 	complete(&bnx2i_conn->cmd_cleanup_cmpl);
 }
 
@@ -1923,11 +1923,11 @@ static int bnx2i_queue_scsi_cmd_resp(str
 	int rc = 0;
 	int cpu;
 
-	spin_lock(&session->back_lock);
+	spin_lock(&session->lock);
 	task = iscsi_itt_to_task(bnx2i_conn->cls_conn->dd_data,
 				 cqe->itt & ISCSI_CMD_RESPONSE_INDEX);
 	if (!task || !task->sc) {
-		spin_unlock(&session->back_lock);
+		spin_unlock(&session->lock);
 		return -EINVAL;
 	}
 	sc = task->sc;
@@ -1937,7 +1937,7 @@ static int bnx2i_queue_scsi_cmd_resp(str
 	else
 		cpu = sc->request->cpu;
 
-	spin_unlock(&session->back_lock);
+	spin_unlock(&session->lock);
 
 	p = &per_cpu(bnx2i_percpu, cpu);
 	spin_lock(&p->p_work_lock);
--- zfcpdump-kernel-4.4.orig/drivers/scsi/bnx2i/bnx2i_iscsi.c
+++ zfcpdump-kernel-4.4/drivers/scsi/bnx2i/bnx2i_iscsi.c
@@ -1172,12 +1172,10 @@ static void bnx2i_cleanup_task(struct is
 	if (task->state == ISCSI_TASK_ABRT_TMF) {
 		bnx2i_send_cmd_cleanup_req(hba, task->dd_data);
 
-		spin_unlock_bh(&conn->session->back_lock);
-		spin_unlock_bh(&conn->session->frwd_lock);
+		spin_unlock_bh(&conn->session->lock);
 		wait_for_completion_timeout(&bnx2i_conn->cmd_cleanup_cmpl,
 				msecs_to_jiffies(ISCSI_CMD_CLEANUP_TIMEOUT));
-		spin_lock_bh(&conn->session->frwd_lock);
-		spin_lock_bh(&conn->session->back_lock);
+		spin_lock_bh(&conn->session->lock);
 	}
 	bnx2i_iscsi_unmap_sg_list(task->dd_data);
 }
@@ -2063,7 +2061,7 @@ int bnx2i_hw_ep_disconnect(struct bnx2i_
 		goto out;
 
 	if (session) {
-		spin_lock_bh(&session->frwd_lock);
+		spin_lock_bh(&session->lock);
 		if (bnx2i_ep->state != EP_STATE_TCP_FIN_RCVD) {
 			if (session->state == ISCSI_STATE_LOGGING_OUT) {
 				if (bnx2i_ep->state == EP_STATE_LOGOUT_SENT) {
@@ -2079,7 +2077,7 @@ int bnx2i_hw_ep_disconnect(struct bnx2i_
 		} else
 			close = 1;
 
-		spin_unlock_bh(&session->frwd_lock);
+		spin_unlock_bh(&session->lock);
 	}
 
 	bnx2i_ep->state = EP_STATE_DISCONN_START;
--- zfcpdump-kernel-4.4.orig/drivers/scsi/constants.c
+++ zfcpdump-kernel-4.4/drivers/scsi/constants.c
@@ -1181,8 +1181,9 @@ static const char * const snstext[] = {
 
 /* Get sense key string or NULL if not available */
 const char *
-scsi_sense_key_string(unsigned char key) {
-	if (key <= 0xE)
+scsi_sense_key_string(unsigned char key)
+{
+	if (key < ARRAY_SIZE(snstext))
 		return snstext[key];
 	return NULL;
 }
--- zfcpdump-kernel-4.4.orig/drivers/scsi/cxlflash/common.h
+++ zfcpdump-kernel-4.4/drivers/scsi/cxlflash/common.h
@@ -34,7 +34,6 @@ extern const struct file_operations cxlf
 								   sectors
 								*/
 
-#define NUM_RRQ_ENTRY    16     /* for master issued cmds */
 #define MAX_RHT_PER_CONTEXT (PAGE_SIZE / sizeof(struct sisl_rht_entry))
 
 /* AFU command retry limit */
@@ -48,9 +47,12 @@ extern const struct file_operations cxlf
 							   index derivation
 							 */
 
-#define CXLFLASH_MAX_CMDS               16
+#define CXLFLASH_MAX_CMDS               256
 #define CXLFLASH_MAX_CMDS_PER_LUN       CXLFLASH_MAX_CMDS
 
+/* RRQ for master issued cmds */
+#define NUM_RRQ_ENTRY                   CXLFLASH_MAX_CMDS
+
 
 static inline void check_sizes(void)
 {
@@ -106,7 +108,6 @@ struct cxlflash_cfg {
 	atomic_t scan_host_needed;
 
 	struct cxl_afu *cxl_afu;
-	struct pci_dev *parent_dev;
 
 	atomic_t recovery_threads;
 	struct mutex ctx_recovery_mutex;
@@ -149,7 +150,7 @@ struct afu_cmd {
 struct afu {
 	/* Stuff requiring alignment go first. */
 
-	u64 rrq_entry[NUM_RRQ_ENTRY];	/* 128B RRQ */
+	u64 rrq_entry[NUM_RRQ_ENTRY];	/* 2K RRQ */
 	/*
 	 * Command & data for AFU commands.
 	 */
@@ -165,6 +166,8 @@ struct afu {
 	struct sisl_host_map __iomem *host_map;		/* MC host map */
 	struct sisl_ctrl_map __iomem *ctrl_map;		/* MC control map */
 
+	struct kref mapcount;
+
 	ctx_hndl_t ctx_hndl;	/* master's context handle */
 	u64 *hrrq_start;
 	u64 *hrrq_end;
--- zfcpdump-kernel-4.4.orig/drivers/scsi/cxlflash/main.c
+++ zfcpdump-kernel-4.4/drivers/scsi/cxlflash/main.c
@@ -289,7 +289,7 @@ static void context_reset(struct afu_cmd
 		atomic64_set(&afu->room, room);
 		if (room)
 			goto write_rrin;
-		udelay(nretry);
+		udelay(1 << nretry);
 	} while (nretry++ < MC_ROOM_RETRY_CNT);
 
 	pr_err("%s: no cmd_room to send reset\n", __func__);
@@ -303,7 +303,7 @@ write_rrin:
 		if (rrin != 0x1)
 			break;
 		/* Double delay each time */
-		udelay(2 << nretry);
+		udelay(1 << nretry);
 	} while (nretry++ < MC_ROOM_RETRY_CNT);
 }
 
@@ -338,7 +338,7 @@ retry:
 			atomic64_set(&afu->room, room);
 			if (room)
 				goto write_ioarrin;
-			udelay(nretry);
+			udelay(1 << nretry);
 		} while (nretry++ < MC_ROOM_RETRY_CNT);
 
 		dev_err(dev, "%s: no cmd_room to send 0x%X\n",
@@ -352,7 +352,7 @@ retry:
 		 * afu->room.
 		 */
 		if (nretry++ < MC_ROOM_RETRY_CNT) {
-			udelay(nretry);
+			udelay(1 << nretry);
 			goto retry;
 		}
 
@@ -368,6 +368,7 @@ out:
 
 no_room:
 	afu->read_room = true;
+	kref_get(&cfg->afu->mapcount);
 	schedule_work(&cfg->work_q);
 	rc = SCSI_MLQUEUE_HOST_BUSY;
 	goto out;
@@ -473,6 +474,16 @@ out:
 	return rc;
 }
 
+static void afu_unmap(struct kref *ref)
+{
+	struct afu *afu = container_of(ref, struct afu, mapcount);
+
+	if (likely(afu->afu_map)) {
+		cxl_psa_unmap((void __iomem *)afu->afu_map);
+		afu->afu_map = NULL;
+	}
+}
+
 /**
  * cxlflash_driver_info() - information handler for this host driver
  * @host:	SCSI host associated with device.
@@ -503,6 +514,7 @@ static int cxlflash_queuecommand(struct
 	ulong lock_flags;
 	short lflag = 0;
 	int rc = 0;
+	int kref_got = 0;
 
 	dev_dbg_ratelimited(dev, "%s: (scp=%p) %d/%d/%d/%llu "
 			    "cdb=(%08X-%08X-%08X-%08X)\n",
@@ -547,6 +559,9 @@ static int cxlflash_queuecommand(struct
 		goto out;
 	}
 
+	kref_get(&cfg->afu->mapcount);
+	kref_got = 1;
+
 	cmd->rcb.ctx_id = afu->ctx_hndl;
 	cmd->rcb.port_sel = port_sel;
 	cmd->rcb.lun_id = lun_to_lunid(scp->device->lun);
@@ -587,6 +602,8 @@ static int cxlflash_queuecommand(struct
 	}
 
 out:
+	if (kref_got)
+		kref_put(&afu->mapcount, afu_unmap);
 	pr_devel("%s: returning rc=%d\n", __func__, rc);
 	return rc;
 }
@@ -632,46 +649,57 @@ static void free_mem(struct cxlflash_cfg
  * @cfg:	Internal structure associated with the host.
  *
  * Safe to call with AFU in a partially allocated/initialized state.
+ *
+ * Cleans up all state associated with the command queue, and unmaps
+ * the MMIO space.
+ *
+ *  - complete() will take care of commands we initiated (they'll be checked
+ *  in as part of the cleanup that occurs after the completion)
+ *
+ *  - cmd_checkin() will take care of entries that we did not initiate and that
+ *  have not (and will not) complete because they are sitting on a [now stale]
+ *  hardware queue
  */
 static void stop_afu(struct cxlflash_cfg *cfg)
 {
 	int i;
 	struct afu *afu = cfg->afu;
+	struct afu_cmd *cmd;
 
 	if (likely(afu)) {
-		for (i = 0; i < CXLFLASH_NUM_CMDS; i++)
-			complete(&afu->cmd[i].cevent);
+		for (i = 0; i < CXLFLASH_NUM_CMDS; i++) {
+			cmd = &afu->cmd[i];
+			complete(&cmd->cevent);
+			if (!atomic_read(&cmd->free))
+				cmd_checkin(cmd);
+		}
 
 		if (likely(afu->afu_map)) {
 			cxl_psa_unmap((void __iomem *)afu->afu_map);
 			afu->afu_map = NULL;
 		}
+		kref_put(&afu->mapcount, afu_unmap);
 	}
 }
 
 /**
- * term_mc() - terminates the master context
+ * term_intr() - disables all AFU interrupts
  * @cfg:	Internal structure associated with the host.
  * @level:	Depth of allocation, where to begin waterfall tear down.
  *
  * Safe to call with AFU/MC in partially allocated/initialized state.
  */
-static void term_mc(struct cxlflash_cfg *cfg, enum undo_level level)
+static void term_intr(struct cxlflash_cfg *cfg, enum undo_level level)
 {
-	int rc = 0;
 	struct afu *afu = cfg->afu;
 	struct device *dev = &cfg->dev->dev;
 
 	if (!afu || !cfg->mcctx) {
-		dev_err(dev, "%s: returning from term_mc with NULL afu or MC\n",
-		       __func__);
+		dev_err(dev, "%s: returning with NULL afu or MC\n", __func__);
 		return;
 	}
 
 	switch (level) {
-	case UNDO_START:
-		rc = cxl_stop_context(cfg->mcctx);
-		BUG_ON(rc);
 	case UNMAP_THREE:
 		cxl_unmap_afu_irq(cfg->mcctx, 3, afu);
 	case UNMAP_TWO:
@@ -680,12 +708,37 @@ static void term_mc(struct cxlflash_cfg
 		cxl_unmap_afu_irq(cfg->mcctx, 1, afu);
 	case FREE_IRQ:
 		cxl_free_afu_irqs(cfg->mcctx);
-	case RELEASE_CONTEXT:
-		cfg->mcctx = NULL;
+		/* fall through */
+	case UNDO_NOOP:
+		/* No action required */
+		break;
 	}
 }
 
 /**
+ * term_mc() - terminates the master context
+ * @cfg:	Internal structure associated with the host.
+ * @level:	Depth of allocation, where to begin waterfall tear down.
+ *
+ * Safe to call with AFU/MC in partially allocated/initialized state.
+ */
+static void term_mc(struct cxlflash_cfg *cfg)
+{
+	int rc = 0;
+	struct afu *afu = cfg->afu;
+	struct device *dev = &cfg->dev->dev;
+
+	if (!afu || !cfg->mcctx) {
+		dev_err(dev, "%s: returning with NULL afu or MC\n", __func__);
+		return;
+	}
+
+	rc = cxl_stop_context(cfg->mcctx);
+	WARN_ON(rc);
+	cfg->mcctx = NULL;
+}
+
+/**
  * term_afu() - terminates the AFU
  * @cfg:	Internal structure associated with the host.
  *
@@ -693,15 +746,94 @@ static void term_mc(struct cxlflash_cfg
  */
 static void term_afu(struct cxlflash_cfg *cfg)
 {
-	term_mc(cfg, UNDO_START);
-
+	/*
+	 * Tear down is carefully orchestrated to ensure
+	 * no interrupts can come in when the problem state
+	 * area is unmapped.
+	 *
+	 * 1) Disable all AFU interrupts
+	 * 2) Unmap the problem state area
+	 * 3) Stop the master context
+	 */
+	term_intr(cfg, UNMAP_THREE);
 	if (cfg->afu)
 		stop_afu(cfg);
 
+	term_mc(cfg);
+
 	pr_debug("%s: returning\n", __func__);
 }
 
 /**
+ * notify_shutdown() - notifies device of pending shutdown
+ * @cfg:	Internal structure associated with the host.
+ * @wait:	Whether to wait for shutdown processing to complete.
+ *
+ * This function will notify the AFU that the adapter is being shutdown
+ * and will wait for shutdown processing to complete if wait is true.
+ * This notification should flush pending I/Os to the device and halt
+ * further I/Os until the next AFU reset is issued and device restarted.
+ */
+static void notify_shutdown(struct cxlflash_cfg *cfg, bool wait)
+{
+	struct afu *afu = cfg->afu;
+	struct device *dev = &cfg->dev->dev;
+	struct sisl_global_map __iomem *global;
+	struct dev_dependent_vals *ddv;
+	u64 reg, status;
+	int i, retry_cnt = 0;
+
+	ddv = (struct dev_dependent_vals *)cfg->dev_id->driver_data;
+	if (!(ddv->flags & CXLFLASH_NOTIFY_SHUTDOWN))
+		return;
+
+	if (!afu || !afu->afu_map) {
+		dev_dbg(dev, "%s: The problem state area is not mapped\n",
+			__func__);
+		return;
+	}
+
+	global = &afu->afu_map->global;
+
+	/* Notify AFU */
+	for (i = 0; i < NUM_FC_PORTS; i++) {
+		reg = readq_be(&global->fc_regs[i][FC_CONFIG2 / 8]);
+		reg |= SISL_FC_SHUTDOWN_NORMAL;
+		writeq_be(reg, &global->fc_regs[i][FC_CONFIG2 / 8]);
+	}
+
+	if (!wait)
+		return;
+
+	/* Wait up to 1.5 seconds for shutdown processing to complete */
+	for (i = 0; i < NUM_FC_PORTS; i++) {
+		retry_cnt = 0;
+		while (true) {
+			status = readq_be(&global->fc_regs[i][FC_STATUS / 8]);
+			if (status & SISL_STATUS_SHUTDOWN_COMPLETE)
+				break;
+			if (++retry_cnt >= MC_RETRY_CNT) {
+				dev_dbg(dev, "%s: port %d shutdown processing "
+					"not yet completed\n", __func__, i);
+				break;
+			}
+			msleep(100 * retry_cnt);
+		}
+	}
+}
+
+/**
+ * cxlflash_shutdown() - shutdown handler
+ * @pdev:	PCI device associated with the host.
+ */
+static void cxlflash_shutdown(struct pci_dev *pdev)
+{
+	struct cxlflash_cfg *cfg = pci_get_drvdata(pdev);
+
+	notify_shutdown(cfg, false);
+}
+
+/**
  * cxlflash_remove() - PCI entry point to tear down host
  * @pdev:	PCI device associated with the host.
  *
@@ -722,6 +854,9 @@ static void cxlflash_remove(struct pci_d
 						  cfg->tmf_slock);
 	spin_unlock_irqrestore(&cfg->tmf_slock, lock_flags);
 
+	/* Notify AFU and wait for shutdown processing to complete */
+	notify_shutdown(cfg, true);
+
 	cfg->state = STATE_FAILTERM;
 	cxlflash_stop_term_user_contexts(cfg);
 
@@ -731,10 +866,9 @@ static void cxlflash_remove(struct pci_d
 		scsi_remove_host(cfg->host);
 		/* fall through */
 	case INIT_STATE_AFU:
-		term_afu(cfg);
 		cancel_work_sync(&cfg->work_q);
+		term_afu(cfg);
 	case INIT_STATE_PCI:
-		pci_release_regions(cfg->dev);
 		pci_disable_device(pdev);
 	case INIT_STATE_NONE:
 		free_mem(cfg);
@@ -807,15 +941,6 @@ static int init_pci(struct cxlflash_cfg
 	struct pci_dev *pdev = cfg->dev;
 	int rc = 0;
 
-	cfg->cxlflash_regs_pci = pci_resource_start(pdev, 0);
-	rc = pci_request_regions(pdev, CXLFLASH_NAME);
-	if (rc < 0) {
-		dev_err(&pdev->dev,
-			"%s: Couldn't register memory range of registers\n",
-			__func__);
-		goto out;
-	}
-
 	rc = pci_enable_device(pdev);
 	if (rc || pci_channel_offline(pdev)) {
 		if (pci_channel_offline(pdev)) {
@@ -827,55 +952,13 @@ static int init_pci(struct cxlflash_cfg
 			dev_err(&pdev->dev, "%s: Cannot enable adapter\n",
 				__func__);
 			cxlflash_wait_for_pci_err_recovery(cfg);
-			goto out_release_regions;
-		}
-	}
-
-	rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(64));
-	if (rc < 0) {
-		dev_dbg(&pdev->dev, "%s: Failed to set 64 bit PCI DMA mask\n",
-			__func__);
-		rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
-	}
-
-	if (rc < 0) {
-		dev_err(&pdev->dev, "%s: Failed to set PCI DMA mask\n",
-			__func__);
-		goto out_disable;
-	}
-
-	pci_set_master(pdev);
-
-	if (pci_channel_offline(pdev)) {
-		cxlflash_wait_for_pci_err_recovery(cfg);
-		if (pci_channel_offline(pdev)) {
-			rc = -EIO;
-			goto out_msi_disable;
+			goto out;
 		}
 	}
 
-	rc = pci_save_state(pdev);
-
-	if (rc != PCIBIOS_SUCCESSFUL) {
-		dev_err(&pdev->dev, "%s: Failed to save PCI config space\n",
-			__func__);
-		rc = -EIO;
-		goto cleanup_nolog;
-	}
-
 out:
 	pr_debug("%s: returning rc=%d\n", __func__, rc);
 	return rc;
-
-cleanup_nolog:
-out_msi_disable:
-	cxlflash_wait_for_pci_err_recovery(cfg);
-out_disable:
-	pci_disable_device(pdev);
-out_release_regions:
-	pci_release_regions(pdev);
-	goto out;
-
 }
 
 /**
@@ -1108,7 +1191,7 @@ static const struct asyc_intr_info ainfo
 	{SISL_ASTATUS_FC1_OTHER, "other error", 1, CLR_FC_ERROR | LINK_RESET},
 	{SISL_ASTATUS_FC1_LOGO, "target initiated LOGO", 1, 0},
 	{SISL_ASTATUS_FC1_CRC_T, "CRC threshold exceeded", 1, LINK_RESET},
-	{SISL_ASTATUS_FC1_LOGI_R, "login timed out, retrying", 1, 0},
+	{SISL_ASTATUS_FC1_LOGI_R, "login timed out, retrying", 1, LINK_RESET},
 	{SISL_ASTATUS_FC1_LOGI_F, "login failed", 1, CLR_FC_ERROR},
 	{SISL_ASTATUS_FC1_LOGI_S, "login succeeded", 1, SCAN_HOST},
 	{SISL_ASTATUS_FC1_LINK_DN, "link down", 1, 0},
@@ -1316,6 +1399,7 @@ static irqreturn_t cxlflash_async_err_ir
 				__func__, port);
 			cfg->lr_state = LINK_RESET_REQUIRED;
 			cfg->lr_port = port;
+			kref_get(&cfg->afu->mapcount);
 			schedule_work(&cfg->work_q);
 		}
 
@@ -1336,6 +1420,7 @@ static irqreturn_t cxlflash_async_err_ir
 
 		if (info->action & SCAN_HOST) {
 			atomic_inc(&cfg->scan_host_needed);
+			kref_get(&cfg->afu->mapcount);
 			schedule_work(&cfg->work_q);
 		}
 	}
@@ -1372,7 +1457,7 @@ static int start_context(struct cxlflash
  */
 static int read_vpd(struct cxlflash_cfg *cfg, u64 wwpn[])
 {
-	struct pci_dev *dev = cfg->parent_dev;
+	struct pci_dev *dev = cfg->dev;
 	int rc = 0;
 	int ro_start, ro_size, i, j, k;
 	ssize_t vpd_size;
@@ -1381,7 +1466,7 @@ static int read_vpd(struct cxlflash_cfg
 	char *wwpn_vpd_tags[NUM_FC_PORTS] = { "V5", "V6" };
 
 	/* Get the VPD data from the device */
-	vpd_size = pci_read_vpd(dev, 0, sizeof(vpd_data), vpd_data);
+	vpd_size = cxl_read_adapter_vpd(dev, vpd_data, sizeof(vpd_data));
 	if (unlikely(vpd_size <= 0)) {
 		dev_err(&dev->dev, "%s: Unable to read VPD (size = %ld)\n",
 		       __func__, vpd_size);
@@ -1614,41 +1699,24 @@ static int start_afu(struct cxlflash_cfg
 }
 
 /**
- * init_mc() - create and register as the master context
+ * init_intr() - setup interrupt handlers for the master context
  * @cfg:	Internal structure associated with the host.
  *
  * Return: 0 on success, -errno on failure
  */
-static int init_mc(struct cxlflash_cfg *cfg)
+static enum undo_level init_intr(struct cxlflash_cfg *cfg,
+				 struct cxl_context *ctx)
 {
-	struct cxl_context *ctx;
-	struct device *dev = &cfg->dev->dev;
 	struct afu *afu = cfg->afu;
+	struct device *dev = &cfg->dev->dev;
 	int rc = 0;
-	enum undo_level level;
-
-	ctx = cxl_get_context(cfg->dev);
-	if (unlikely(!ctx))
-		return -ENOMEM;
-	cfg->mcctx = ctx;
-
-	/* Set it up as a master with the CXL */
-	cxl_set_master(ctx);
-
-	/* During initialization reset the AFU to start from a clean slate */
-	rc = cxl_afu_reset(cfg->mcctx);
-	if (unlikely(rc)) {
-		dev_err(dev, "%s: initial AFU reset failed rc=%d\n",
-			__func__, rc);
-		level = RELEASE_CONTEXT;
-		goto out;
-	}
+	enum undo_level level = UNDO_NOOP;
 
 	rc = cxl_allocate_afu_irqs(ctx, 3);
 	if (unlikely(rc)) {
 		dev_err(dev, "%s: call to allocate_afu_irqs failed rc=%d!\n",
 			__func__, rc);
-		level = RELEASE_CONTEXT;
+		level = UNDO_NOOP;
 		goto out;
 	}
 
@@ -1678,8 +1746,47 @@ static int init_mc(struct cxlflash_cfg *
 		level = UNMAP_TWO;
 		goto out;
 	}
+out:
+	return level;
+}
+
+/**
+ * init_mc() - create and register as the master context
+ * @cfg:	Internal structure associated with the host.
+ *
+ * Return: 0 on success, -errno on failure
+ */
+static int init_mc(struct cxlflash_cfg *cfg)
+{
+	struct cxl_context *ctx;
+	struct device *dev = &cfg->dev->dev;
+	int rc = 0;
+	enum undo_level level;
+
+	ctx = cxl_get_context(cfg->dev);
+	if (unlikely(!ctx)) {
+		rc = -ENOMEM;
+		goto ret;
+	}
+	cfg->mcctx = ctx;
 
-	rc = 0;
+	/* Set it up as a master with the CXL */
+	cxl_set_master(ctx);
+
+	/* During initialization reset the AFU to start from a clean slate */
+	rc = cxl_afu_reset(cfg->mcctx);
+	if (unlikely(rc)) {
+		dev_err(dev, "%s: initial AFU reset failed rc=%d\n",
+			__func__, rc);
+		goto ret;
+	}
+
+	level = init_intr(cfg, ctx);
+	if (unlikely(level)) {
+		dev_err(dev, "%s: setting up interrupts failed rc=%d\n",
+			__func__, rc);
+		goto out;
+	}
 
 	/* This performs the equivalent of the CXL_IOCTL_START_WORK.
 	 * The CXL_IOCTL_GET_PROCESS_ELEMENT is implicit in the process
@@ -1695,7 +1802,7 @@ ret:
 	pr_debug("%s: returning rc=%d\n", __func__, rc);
 	return rc;
 out:
-	term_mc(cfg, level);
+	term_intr(cfg, level);
 	goto ret;
 }
 
@@ -1731,6 +1838,7 @@ static int init_afu(struct cxlflash_cfg
 		rc = -ENOMEM;
 		goto err1;
 	}
+	kref_init(&afu->mapcount);
 
 	/* No byte reverse on reading afu_version or string will be backwards */
 	reg = readq(&afu->afu_map->global.regs.afu_version);
@@ -1765,10 +1873,10 @@ out:
 	return rc;
 
 err2:
-	cxl_psa_unmap((void __iomem *)afu->afu_map);
-	afu->afu_map = NULL;
+	kref_put(&afu->mapcount, afu_unmap);
 err1:
-	term_mc(cfg, UNDO_START);
+	term_intr(cfg, UNMAP_THREE);
+	term_mc(cfg);
 	goto out;
 }
 
@@ -1880,6 +1988,19 @@ static int afu_reset(struct cxlflash_cfg
 }
 
 /**
+ * drain_ioctls() - wait until all currently executing ioctls have completed
+ * @cfg:	Internal structure associated with the host.
+ *
+ * Obtain write access to read/write semaphore that wraps ioctl
+ * handling to 'drain' ioctls currently executing.
+ */
+static void drain_ioctls(struct cxlflash_cfg *cfg)
+{
+	down_write(&cfg->ioctl_rwsem);
+	up_write(&cfg->ioctl_rwsem);
+}
+
+/**
  * cxlflash_eh_device_reset_handler() - reset a single LUN
  * @scp:	SCSI command to send.
  *
@@ -1950,6 +2071,7 @@ static int cxlflash_eh_host_reset_handle
 	switch (cfg->state) {
 	case STATE_NORMAL:
 		cfg->state = STATE_RESET;
+		drain_ioctls(cfg);
 		cxlflash_mark_contexts_error(cfg);
 		rcr = afu_reset(cfg);
 		if (rcr) {
@@ -2114,6 +2236,16 @@ static ssize_t lun_mode_store(struct dev
 	rc = kstrtouint(buf, 10, &lun_mode);
 	if (!rc && (lun_mode < 5) && (lun_mode != afu->internal_lun)) {
 		afu->internal_lun = lun_mode;
+
+		/*
+		 * When configured for internal LUN, there is only one channel,
+		 * channel number 0, else there will be 2 (default).
+		 */
+		if (afu->internal_lun)
+			shost->max_channel = 0;
+		else
+			shost->max_channel = NUM_FC_PORTS - 1;
+
 		afu_reset(cfg);
 		scsi_scan_host(cfg->host);
 	}
@@ -2260,7 +2392,7 @@ static struct scsi_host_template driver_
 	.eh_device_reset_handler = cxlflash_eh_device_reset_handler,
 	.eh_host_reset_handler = cxlflash_eh_host_reset_handler,
 	.change_queue_depth = cxlflash_change_queue_depth,
-	.cmd_per_lun = 16,
+	.cmd_per_lun = CXLFLASH_MAX_CMDS_PER_LUN,
 	.can_queue = CXLFLASH_MAX_CMDS,
 	.this_id = -1,
 	.sg_tablesize = SG_NONE,	/* No scatter gather support */
@@ -2273,7 +2405,10 @@ static struct scsi_host_template driver_
 /*
  * Device dependent values
  */
-static struct dev_dependent_vals dev_corsa_vals = { CXLFLASH_MAX_SECTORS };
+static struct dev_dependent_vals dev_corsa_vals = { CXLFLASH_MAX_SECTORS,
+					0ULL };
+static struct dev_dependent_vals dev_flash_gt_vals = { CXLFLASH_MAX_SECTORS,
+					CXLFLASH_NOTIFY_SHUTDOWN };
 
 /*
  * PCI device binding table
@@ -2281,6 +2416,8 @@ static struct dev_dependent_vals dev_cor
 static struct pci_device_id cxlflash_pci_table[] = {
 	{PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CORSA,
 	 PCI_ANY_ID, PCI_ANY_ID, 0, 0, (kernel_ulong_t)&dev_corsa_vals},
+	{PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_FLASH_GT,
+	 PCI_ANY_ID, PCI_ANY_ID, 0, 0, (kernel_ulong_t)&dev_flash_gt_vals},
 	{}
 };
 
@@ -2339,6 +2476,7 @@ static void cxlflash_worker_thread(struc
 
 	if (atomic_dec_if_positive(&cfg->scan_host_needed) >= 0)
 		scsi_scan_host(cfg->host);
+	kref_put(&afu->mapcount, afu_unmap);
 }
 
 /**
@@ -2353,7 +2491,6 @@ static int cxlflash_probe(struct pci_dev
 {
 	struct Scsi_Host *host;
 	struct cxlflash_cfg *cfg = NULL;
-	struct device *phys_dev;
 	struct dev_dependent_vals *ddv;
 	int rc = 0;
 
@@ -2419,19 +2556,6 @@ static int cxlflash_probe(struct pci_dev
 
 	pci_set_drvdata(pdev, cfg);
 
-	/*
-	 * Use the special service provided to look up the physical
-	 * PCI device, since we are called on the probe of the virtual
-	 * PCI host bus (vphb)
-	 */
-	phys_dev = cxl_get_phys_dev(pdev);
-	if (!dev_is_pci(phys_dev)) {
-		dev_err(&pdev->dev, "%s: not a pci dev\n", __func__);
-		rc = -ENODEV;
-		goto out_remove;
-	}
-	cfg->parent_dev = to_pci_dev(phys_dev);
-
 	cfg->cxl_afu = cxl_pci_to_afu(pdev);
 
 	rc = init_pci(cfg);
@@ -2468,19 +2592,6 @@ out_remove:
 }
 
 /**
- * drain_ioctls() - wait until all currently executing ioctls have completed
- * @cfg:	Internal structure associated with the host.
- *
- * Obtain write access to read/write semaphore that wraps ioctl
- * handling to 'drain' ioctls currently executing.
- */
-static void drain_ioctls(struct cxlflash_cfg *cfg)
-{
-	down_write(&cfg->ioctl_rwsem);
-	up_write(&cfg->ioctl_rwsem);
-}
-
-/**
  * cxlflash_pci_error_detected() - called when a PCI error is detected
  * @pdev:	PCI device struct.
  * @state:	PCI channel state.
@@ -2505,8 +2616,7 @@ static pci_ers_result_t cxlflash_pci_err
 		if (unlikely(rc))
 			dev_err(dev, "%s: Failed to mark user contexts!(%d)\n",
 				__func__, rc);
-		term_mc(cfg, UNDO_START);
-		stop_afu(cfg);
+		term_afu(cfg);
 		return PCI_ERS_RESULT_NEED_RESET;
 	case pci_channel_io_perm_failure:
 		cfg->state = STATE_FAILTERM;
@@ -2575,6 +2685,7 @@ static struct pci_driver cxlflash_driver
 	.id_table = cxlflash_pci_table,
 	.probe = cxlflash_probe,
 	.remove = cxlflash_remove,
+	.shutdown = cxlflash_shutdown,
 	.err_handler = &cxlflash_err_handler,
 };
 
@@ -2585,8 +2696,7 @@ static struct pci_driver cxlflash_driver
  */
 static int __init init_cxlflash(void)
 {
-	pr_info("%s: IBM Power CXL Flash Adapter: %s\n",
-		__func__, CXLFLASH_DRIVER_DATE);
+	pr_info("%s: %s\n", __func__, CXLFLASH_ADAPTER_NAME);
 
 	cxlflash_list_init();
 
--- zfcpdump-kernel-4.4.orig/drivers/scsi/cxlflash/main.h
+++ zfcpdump-kernel-4.4/drivers/scsi/cxlflash/main.h
@@ -22,10 +22,9 @@
 
 #define CXLFLASH_NAME		"cxlflash"
 #define CXLFLASH_ADAPTER_NAME	"IBM POWER CXL Flash Adapter"
-#define CXLFLASH_DRIVER_DATE	"(August 13, 2015)"
 
-#define PCI_DEVICE_ID_IBM_CORSA	0x04F0
-#define CXLFLASH_SUBS_DEV_ID	0x04F0
+#define PCI_DEVICE_ID_IBM_CORSA		0x04F0
+#define PCI_DEVICE_ID_IBM_FLASH_GT	0x0600
 
 /* Since there is only one target, make it 0 */
 #define CXLFLASH_TARGET		0
@@ -80,16 +79,17 @@
 #define WWPN_BUF_LEN	(WWPN_LEN + 1)
 
 enum undo_level {
-	RELEASE_CONTEXT = 0,
+	UNDO_NOOP = 0,
 	FREE_IRQ,
 	UNMAP_ONE,
 	UNMAP_TWO,
-	UNMAP_THREE,
-	UNDO_START
+	UNMAP_THREE
 };
 
 struct dev_dependent_vals {
 	u64 max_sectors;
+	u64 flags;
+#define CXLFLASH_NOTIFY_SHUTDOWN   0x0000000000000001ULL
 };
 
 struct asyc_intr_info {
--- zfcpdump-kernel-4.4.orig/drivers/scsi/cxlflash/sislite.h
+++ zfcpdump-kernel-4.4/drivers/scsi/cxlflash/sislite.h
@@ -311,6 +311,12 @@ struct sisl_global_regs {
 #define SISL_FC_INTERNAL_MASK	~(SISL_FC_INTERNAL_UNMASK)
 #define SISL_FC_INTERNAL_SHIFT	32
 
+#define SISL_FC_SHUTDOWN_NORMAL		0x0000000000000010ULL
+#define SISL_FC_SHUTDOWN_ABRUPT		0x0000000000000020ULL
+
+#define SISL_STATUS_SHUTDOWN_ACTIVE	0x0000000000000010ULL
+#define SISL_STATUS_SHUTDOWN_COMPLETE	0x0000000000000020ULL
+
 #define SISL_ASTATUS_UNMASK	0xFFFFULL		/* 1 means unmasked */
 #define SISL_ASTATUS_MASK	~(SISL_ASTATUS_UNMASK)	/* 1 means masked */
 
--- zfcpdump-kernel-4.4.orig/drivers/scsi/cxlflash/superpipe.c
+++ zfcpdump-kernel-4.4/drivers/scsi/cxlflash/superpipe.c
@@ -709,27 +709,32 @@ int cxlflash_disk_release(struct scsi_de
  * @cfg:	Internal structure associated with the host.
  * @ctxi:	Context to release.
  *
- * Note that the rht_lun member of the context was cut from a single
- * allocation when the context was created and therefore does not need
- * to be explicitly freed. Also note that we conditionally check for the
- * existence of the context control map before clearing the RHT registers
- * and context capabilities because it is possible to destroy a context
- * while the context is in the error state (previous mapping was removed
- * [so we don't have to worry about clearing] and context is waiting for
- * a new mapping).
+ * This routine is safe to be called with a a non-initialized context
+ * and is tolerant of being called with the context's mutex held (it
+ * will be unlocked if necessary before freeing). Also note that the
+ * routine conditionally checks for the existence of the context control
+ * map before clearing the RHT registers and context capabilities because
+ * it is possible to destroy a context while the context is in the error
+ * state (previous mapping was removed [so there is no need to worry about
+ * clearing] and context is waiting for a new mapping).
  */
 static void destroy_context(struct cxlflash_cfg *cfg,
 			    struct ctx_info *ctxi)
 {
 	struct afu *afu = cfg->afu;
 
-	WARN_ON(!list_empty(&ctxi->luns));
+	if (ctxi->initialized) {
+		WARN_ON(!list_empty(&ctxi->luns));
 
-	/* Clear RHT registers and drop all capabilities for this context */
-	if (afu->afu_map && ctxi->ctrl_map) {
-		writeq_be(0, &ctxi->ctrl_map->rht_start);
-		writeq_be(0, &ctxi->ctrl_map->rht_cnt_id);
-		writeq_be(0, &ctxi->ctrl_map->ctx_cap);
+		/* Clear RHT registers and drop all capabilities for context */
+		if (afu->afu_map && ctxi->ctrl_map) {
+			writeq_be(0, &ctxi->ctrl_map->rht_start);
+			writeq_be(0, &ctxi->ctrl_map->rht_cnt_id);
+			writeq_be(0, &ctxi->ctrl_map->ctx_cap);
+		}
+
+		if (mutex_is_locked(&ctxi->mutex))
+			mutex_unlock(&ctxi->mutex);
 	}
 
 	/* Free memory associated with context */
@@ -742,23 +747,12 @@ static void destroy_context(struct cxlfl
 /**
  * create_context() - allocates and initializes a context
  * @cfg:	Internal structure associated with the host.
- * @ctx:	Previously obtained CXL context reference.
- * @ctxid:	Previously obtained process element associated with CXL context.
- * @adap_fd:	Previously obtained adapter fd associated with CXL context.
- * @file:	Previously obtained file associated with CXL context.
- * @perms:	User-specified permissions.
- *
- * The context's mutex is locked when an allocated context is returned.
  *
  * Return: Allocated context on success, NULL on failure
  */
-static struct ctx_info *create_context(struct cxlflash_cfg *cfg,
-				       struct cxl_context *ctx, int ctxid,
-				       int adap_fd, struct file *file,
-				       u32 perms)
+static struct ctx_info *create_context(struct cxlflash_cfg *cfg)
 {
 	struct device *dev = &cfg->dev->dev;
-	struct afu *afu = cfg->afu;
 	struct ctx_info *ctxi = NULL;
 	struct llun_info **lli = NULL;
 	u8 *ws = NULL;
@@ -781,28 +775,49 @@ static struct ctx_info *create_context(s
 	ctxi->rht_lun = lli;
 	ctxi->rht_needs_ws = ws;
 	ctxi->rht_start = rhte;
-	ctxi->rht_perms = perms;
+out:
+	return ctxi;
+
+err:
+	kfree(ws);
+	kfree(lli);
+	kfree(ctxi);
+	ctxi = NULL;
+	goto out;
+}
+
+/**
+ * init_context() - initializes a previously allocated context
+ * @ctxi:	Previously allocated context
+ * @cfg:	Internal structure associated with the host.
+ * @ctx:	Previously obtained CXL context reference.
+ * @ctxid:	Previously obtained process element associated with CXL context.
+ * @adap_fd:	Previously obtained adapter fd associated with CXL context.
+ * @file:	Previously obtained file associated with CXL context.
+ * @perms:	User-specified permissions.
+ *
+ * Upon return, the context is marked as initialized and the context's mutex
+ * is locked.
+ */
+static void init_context(struct ctx_info *ctxi, struct cxlflash_cfg *cfg,
+			 struct cxl_context *ctx, int ctxid, int adap_fd,
+			 struct file *file, u32 perms)
+{
+	struct afu *afu = cfg->afu;
 
+	ctxi->rht_perms = perms;
 	ctxi->ctrl_map = &afu->afu_map->ctrls[ctxid].ctrl;
 	ctxi->ctxid = ENCODE_CTXID(ctxi, ctxid);
 	ctxi->lfd = adap_fd;
 	ctxi->pid = current->tgid; /* tgid = pid */
 	ctxi->ctx = ctx;
 	ctxi->file = file;
+	ctxi->initialized = true;
 	mutex_init(&ctxi->mutex);
 	INIT_LIST_HEAD(&ctxi->luns);
 	INIT_LIST_HEAD(&ctxi->list); /* initialize for list_empty() */
 
 	mutex_lock(&ctxi->mutex);
-out:
-	return ctxi;
-
-err:
-	kfree(ws);
-	kfree(lli);
-	kfree(ctxi);
-	ctxi = NULL;
-	goto out;
 }
 
 /**
@@ -1300,9 +1315,9 @@ static int cxlflash_disk_attach(struct s
 	u32 perms;
 	int ctxid = -1;
 	u64 rctxid = 0UL;
-	struct file *file;
+	struct file *file = NULL;
 
-	struct cxl_context *ctx;
+	struct cxl_context *ctx = NULL;
 
 	int fd = -1;
 
@@ -1356,7 +1371,7 @@ static int cxlflash_disk_attach(struct s
 	if (unlikely(!lun_access)) {
 		dev_err(dev, "%s: Unable to allocate lun_access!\n", __func__);
 		rc = -ENOMEM;
-		goto err0;
+		goto err;
 	}
 
 	lun_access->lli = lli;
@@ -1371,53 +1386,56 @@ static int cxlflash_disk_attach(struct s
 		goto out_attach;
 	}
 
+	ctxi = create_context(cfg);
+	if (unlikely(!ctxi)) {
+		dev_err(dev, "%s: Failed to create context! (%d)\n",
+			__func__, ctxid);
+		goto err;
+	}
+
 	ctx = cxl_dev_context_init(cfg->dev);
-	if (unlikely(IS_ERR_OR_NULL(ctx))) {
+	if (IS_ERR_OR_NULL(ctx)) {
 		dev_err(dev, "%s: Could not initialize context %p\n",
 			__func__, ctx);
 		rc = -ENODEV;
-		goto err1;
+		goto err;
+	}
+
+	work = &ctxi->work;
+	work->num_interrupts = attach->num_interrupts;
+	work->flags = CXL_START_WORK_NUM_IRQS;
+
+	rc = cxl_start_work(ctx, work);
+	if (unlikely(rc)) {
+		dev_dbg(dev, "%s: Could not start context rc=%d\n",
+			__func__, rc);
+		goto err;
 	}
 
 	ctxid = cxl_process_element(ctx);
-	if (unlikely((ctxid > MAX_CONTEXT) || (ctxid < 0))) {
+	if (unlikely((ctxid >= MAX_CONTEXT) || (ctxid < 0))) {
 		dev_err(dev, "%s: ctxid (%d) invalid!\n", __func__, ctxid);
 		rc = -EPERM;
-		goto err2;
+		goto err;
 	}
 
 	file = cxl_get_fd(ctx, &cfg->cxl_fops, &fd);
 	if (unlikely(fd < 0)) {
 		rc = -ENODEV;
 		dev_err(dev, "%s: Could not get file descriptor\n", __func__);
-		goto err2;
+		goto err;
 	}
 
 	/* Translate read/write O_* flags from fcntl.h to AFU permission bits */
 	perms = SISL_RHT_PERM(attach->hdr.flags + 1);
 
-	ctxi = create_context(cfg, ctx, ctxid, fd, file, perms);
-	if (unlikely(!ctxi)) {
-		dev_err(dev, "%s: Failed to create context! (%d)\n",
-			__func__, ctxid);
-		goto err3;
-	}
-
-	work = &ctxi->work;
-	work->num_interrupts = attach->num_interrupts;
-	work->flags = CXL_START_WORK_NUM_IRQS;
-
-	rc = cxl_start_work(ctx, work);
-	if (unlikely(rc)) {
-		dev_dbg(dev, "%s: Could not start context rc=%d\n",
-			__func__, rc);
-		goto err4;
-	}
+	/* Context mutex is locked upon return */
+	init_context(ctxi, cfg, ctx, ctxid, fd, file, perms);
 
 	rc = afu_attach(cfg, ctxi);
 	if (unlikely(rc)) {
 		dev_err(dev, "%s: Could not attach AFU rc %d\n", __func__, rc);
-		goto err5;
+		goto err;
 	}
 
 	/*
@@ -1453,13 +1471,14 @@ out:
 		__func__, ctxid, fd, attach->block_size, rc, attach->last_lba);
 	return rc;
 
-err5:
-	cxl_stop_context(ctx);
-err4:
-	put_context(ctxi);
-	destroy_context(cfg, ctxi);
-	ctxi = NULL;
-err3:
+err:
+	/* Cleanup CXL context; okay to 'stop' even if it was not started */
+	if (!IS_ERR_OR_NULL(ctx)) {
+		cxl_stop_context(ctx);
+		cxl_release_context(ctx);
+		ctx = NULL;
+	}
+
 	/*
 	 * Here, we're overriding the fops with a dummy all-NULL fops because
 	 * fput() calls the release fop, which will cause us to mistakenly
@@ -1467,15 +1486,21 @@ err3:
 	 * to that routine (cxlflash_cxl_release) we should try to fix the
 	 * issue here.
 	 */
-	file->f_op = &null_fops;
-	fput(file);
-	put_unused_fd(fd);
-	fd = -1;
-err2:
-	cxl_release_context(ctx);
-err1:
+	if (fd > 0) {
+		file->f_op = &null_fops;
+		fput(file);
+		put_unused_fd(fd);
+		fd = -1;
+		file = NULL;
+	}
+
+	/* Cleanup our context; safe to call even with mutex locked */
+	if (ctxi) {
+		destroy_context(cfg, ctxi);
+		ctxi = NULL;
+	}
+
 	kfree(lun_access);
-err0:
 	scsi_device_put(sdev);
 	goto out;
 }
@@ -1500,31 +1525,31 @@ static int recover_context(struct cxlfla
 	struct afu *afu = cfg->afu;
 
 	ctx = cxl_dev_context_init(cfg->dev);
-	if (unlikely(IS_ERR_OR_NULL(ctx))) {
+	if (IS_ERR_OR_NULL(ctx)) {
 		dev_err(dev, "%s: Could not initialize context %p\n",
 			__func__, ctx);
 		rc = -ENODEV;
 		goto out;
 	}
 
+	rc = cxl_start_work(ctx, &ctxi->work);
+	if (unlikely(rc)) {
+		dev_dbg(dev, "%s: Could not start context rc=%d\n",
+			__func__, rc);
+		goto err1;
+	}
+
 	ctxid = cxl_process_element(ctx);
-	if (unlikely((ctxid > MAX_CONTEXT) || (ctxid < 0))) {
+	if (unlikely((ctxid >= MAX_CONTEXT) || (ctxid < 0))) {
 		dev_err(dev, "%s: ctxid (%d) invalid!\n", __func__, ctxid);
 		rc = -EPERM;
-		goto err1;
+		goto err2;
 	}
 
 	file = cxl_get_fd(ctx, &cfg->cxl_fops, &fd);
 	if (unlikely(fd < 0)) {
 		rc = -ENODEV;
 		dev_err(dev, "%s: Could not get file descriptor\n", __func__);
-		goto err1;
-	}
-
-	rc = cxl_start_work(ctx, &ctxi->work);
-	if (unlikely(rc)) {
-		dev_dbg(dev, "%s: Could not start context rc=%d\n",
-			__func__, rc);
 		goto err2;
 	}
 
@@ -1569,10 +1594,10 @@ out:
 	return rc;
 
 err3:
-	cxl_stop_context(ctx);
-err2:
 	fput(file);
 	put_unused_fd(fd);
+err2:
+	cxl_stop_context(ctx);
 err1:
 	cxl_release_context(ctx);
 	goto out;
@@ -1590,6 +1615,13 @@ err1:
  * place at the same time and the failure was due to CXL services being
  * unable to keep up.
  *
+ * As this routine is called on ioctl context, it holds the ioctl r/w
+ * semaphore that is used to drain ioctls in recovery scenarios. The
+ * implementation to achieve the pacing described above (a local mutex)
+ * requires that the ioctl r/w semaphore be dropped and reacquired to
+ * avoid a 3-way deadlock when multiple process recoveries operate in
+ * parallel.
+ *
  * Because a user can detect an error condition before the kernel, it is
  * quite possible for this routine to act as the kernel's EEH detection
  * source (MMIO read of mbox_r). Because of this, there is a window of
@@ -1617,9 +1649,17 @@ static int cxlflash_afu_recover(struct s
 	int rc = 0;
 
 	atomic_inc(&cfg->recovery_threads);
+	up_read(&cfg->ioctl_rwsem);
 	rc = mutex_lock_interruptible(mutex);
+	down_read(&cfg->ioctl_rwsem);
 	if (rc)
 		goto out;
+	rc = check_state(cfg);
+	if (rc) {
+		dev_err(dev, "%s: Failed state! rc=%d\n", __func__, rc);
+		rc = -ENODEV;
+		goto out;
+	}
 
 	dev_dbg(dev, "%s: reason 0x%016llX rctxid=%016llX\n",
 		__func__, recover->reason, rctxid);
--- zfcpdump-kernel-4.4.orig/drivers/scsi/cxlflash/superpipe.h
+++ zfcpdump-kernel-4.4/drivers/scsi/cxlflash/superpipe.h
@@ -102,6 +102,7 @@ struct ctx_info {
 	u64 ctxid;
 	int lfd;
 	pid_t pid;
+	bool initialized;
 	bool unavail;
 	bool err_recovery_active;
 	struct mutex mutex; /* Context protection */
--- zfcpdump-kernel-4.4.orig/drivers/scsi/cxlflash/vlun.c
+++ zfcpdump-kernel-4.4/drivers/scsi/cxlflash/vlun.c
@@ -1008,6 +1008,8 @@ int cxlflash_disk_virtual_open(struct sc
 	virt->last_lba = last_lba;
 	virt->rsrc_handle = rsrc_handle;
 
+	if (lli->port_sel == BOTH_PORTS)
+		virt->hdr.return_flags |= DK_CXLFLASH_ALL_PORTS_ACTIVE;
 out:
 	if (likely(ctxi))
 		put_context(ctxi);
--- zfcpdump-kernel-4.4.orig/drivers/scsi/device_handler/Kconfig
+++ zfcpdump-kernel-4.4/drivers/scsi/device_handler/Kconfig
@@ -13,13 +13,13 @@ menuconfig SCSI_DH
 
 config SCSI_DH_RDAC
 	tristate "LSI RDAC Device Handler"
-	depends on SCSI_DH
+	depends on SCSI_DH && SCSI
 	help
 	If you have a LSI RDAC select y. Otherwise, say N.
 
 config SCSI_DH_HP_SW
 	tristate "HP/COMPAQ MSA Device Handler"
-	depends on SCSI_DH
+	depends on SCSI_DH && SCSI
 	help
 	If you have a HP/COMPAQ MSA device that requires START_STOP to
 	be sent to start it and cannot upgrade the firmware then select y.
@@ -27,13 +27,13 @@ config SCSI_DH_HP_SW
 
 config SCSI_DH_EMC
 	tristate "EMC CLARiiON Device Handler"
-	depends on SCSI_DH
+	depends on SCSI_DH && SCSI
 	help
 	If you have a EMC CLARiiON select y. Otherwise, say N.
 
 config SCSI_DH_ALUA
 	tristate "SPC-3 ALUA Device Handler"
-	depends on SCSI_DH
+	depends on SCSI_DH && SCSI
 	help
 	  SCSI Device handler for generic SPC-3 Asymmetric Logical Unit
 	  Access (ALUA).
--- zfcpdump-kernel-4.4.orig/drivers/scsi/device_handler/scsi_dh_alua.c
+++ zfcpdump-kernel-4.4/drivers/scsi/device_handler/scsi_dh_alua.c
@@ -22,7 +22,9 @@
 #include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/module.h>
+#include <asm/unaligned.h>
 #include <scsi/scsi.h>
+#include <scsi/scsi_dbg.h>
 #include <scsi/scsi_eh.h>
 #include <scsi/scsi_dh.h>
 
@@ -54,27 +56,60 @@
 #define TPGS_MODE_IMPLICIT		0x1
 #define TPGS_MODE_EXPLICIT		0x2
 
-#define ALUA_INQUIRY_SIZE		36
+#define ALUA_RTPG_SIZE			128
 #define ALUA_FAILOVER_TIMEOUT		60
 #define ALUA_FAILOVER_RETRIES		5
+#define ALUA_RTPG_DELAY_MSECS		5
 
-/* flags passed from user level */
-#define ALUA_OPTIMIZE_STPG		1
+/* device handler flags */
+#define ALUA_OPTIMIZE_STPG		0x01
+#define ALUA_RTPG_EXT_HDR_UNSUPP	0x02
+#define ALUA_SYNC_STPG			0x04
+/* State machine flags */
+#define ALUA_PG_RUN_RTPG		0x10
+#define ALUA_PG_RUN_STPG		0x20
+#define ALUA_PG_RUNNING			0x40
 
-struct alua_dh_data {
+static uint optimize_stpg;
+module_param(optimize_stpg, uint, S_IRUGO|S_IWUSR);
+MODULE_PARM_DESC(optimize_stpg, "Allow use of a non-optimized path, rather than sending a STPG, when implicit TPGS is supported (0=No,1=Yes). Default is 0.");
+
+static LIST_HEAD(port_group_list);
+static DEFINE_SPINLOCK(port_group_lock);
+static struct workqueue_struct *kaluad_wq;
+static struct workqueue_struct *kaluad_sync_wq;
+
+struct alua_port_group {
+	struct kref		kref;
+	struct rcu_head		rcu;
+	struct list_head	node;
+	unsigned char		device_id_str[256];
+	int			device_id_len;
 	int			group_id;
-	int			rel_port;
 	int			tpgs;
 	int			state;
 	int			pref;
 	unsigned		flags; /* used for optimizing STPG */
-	unsigned char		inq[ALUA_INQUIRY_SIZE];
-	unsigned char		*buff;
-	int			bufflen;
 	unsigned char		transition_tmo;
-	unsigned char		sense[SCSI_SENSE_BUFFERSIZE];
-	int			senselen;
+	unsigned long		expiry;
+	unsigned long		interval;
+	struct delayed_work	rtpg_work;
+	spinlock_t		lock;
+	struct list_head	rtpg_list;
+	struct scsi_device	*rtpg_sdev;
+};
+
+struct alua_dh_data {
+	struct alua_port_group	*pg;
+	int			group_id;
+	spinlock_t		pg_lock;
 	struct scsi_device	*sdev;
+	int			init_error;
+	struct mutex		init_mutex;
+};
+
+struct alua_queue_data {
+	struct list_head	entry;
 	activate_complete	callback_fn;
 	void			*callback_data;
 };
@@ -82,231 +117,162 @@ struct alua_dh_data {
 #define ALUA_POLICY_SWITCH_CURRENT	0
 #define ALUA_POLICY_SWITCH_ALL		1
 
-static char print_alua_state(int);
-static int alua_check_sense(struct scsi_device *, struct scsi_sense_hdr *);
+static void alua_rtpg_work(struct work_struct *work);
+static void alua_rtpg_queue(struct alua_port_group *pg,
+			    struct scsi_device *sdev,
+			    struct alua_queue_data *qdata, bool force);
+static void alua_check(struct scsi_device *sdev, bool force);
 
-static int realloc_buffer(struct alua_dh_data *h, unsigned len)
+static void release_port_group(struct kref *kref)
 {
-	if (h->buff && h->buff != h->inq)
-		kfree(h->buff);
+	struct alua_port_group *pg;
 
-	h->buff = kmalloc(len, GFP_NOIO);
-	if (!h->buff) {
-		h->buff = h->inq;
-		h->bufflen = ALUA_INQUIRY_SIZE;
-		return 1;
-	}
-	h->bufflen = len;
-	return 0;
-}
-
-static struct request *get_alua_req(struct scsi_device *sdev,
-				    void *buffer, unsigned buflen, int rw)
-{
-	struct request *rq;
-	struct request_queue *q = sdev->request_queue;
-
-	rq = blk_get_request(q, rw, GFP_NOIO);
-
-	if (IS_ERR(rq)) {
-		sdev_printk(KERN_INFO, sdev,
-			    "%s: blk_get_request failed\n", __func__);
-		return NULL;
-	}
-	blk_rq_set_block_pc(rq);
-
-	if (buflen && blk_rq_map_kern(q, rq, buffer, buflen, GFP_NOIO)) {
-		blk_put_request(rq);
-		sdev_printk(KERN_INFO, sdev,
-			    "%s: blk_rq_map_kern failed\n", __func__);
-		return NULL;
-	}
-
-	rq->cmd_flags |= REQ_FAILFAST_DEV | REQ_FAILFAST_TRANSPORT |
-			 REQ_FAILFAST_DRIVER;
-	rq->retries = ALUA_FAILOVER_RETRIES;
-	rq->timeout = ALUA_FAILOVER_TIMEOUT * HZ;
-
-	return rq;
+	pg = container_of(kref, struct alua_port_group, kref);
+	if (pg->rtpg_sdev)
+		flush_delayed_work(&pg->rtpg_work);
+	spin_lock(&port_group_lock);
+	list_del(&pg->node);
+	spin_unlock(&port_group_lock);
+	kfree_rcu(pg, rcu);
 }
 
 /*
- * submit_vpd_inquiry - Issue an INQUIRY VPD page 0x83 command
+ * submit_rtpg - Issue a REPORT TARGET GROUP STATES command
  * @sdev: sdev the command should be sent to
  */
-static int submit_vpd_inquiry(struct scsi_device *sdev, struct alua_dh_data *h)
+static int submit_rtpg(struct scsi_device *sdev, unsigned char *buff,
+		       int bufflen, struct scsi_sense_hdr *sshdr, int flags)
 {
-	struct request *rq;
-	int err = SCSI_DH_RES_TEMP_UNAVAIL;
-
-	rq = get_alua_req(sdev, h->buff, h->bufflen, READ);
-	if (!rq)
-		goto done;
+	u8 cdb[COMMAND_SIZE(MAINTENANCE_IN)];
+	int req_flags = REQ_FAILFAST_DEV | REQ_FAILFAST_TRANSPORT |
+		REQ_FAILFAST_DRIVER;
 
 	/* Prepare the command. */
-	rq->cmd[0] = INQUIRY;
-	rq->cmd[1] = 1;
-	rq->cmd[2] = 0x83;
-	rq->cmd[4] = h->bufflen;
-	rq->cmd_len = COMMAND_SIZE(INQUIRY);
-
-	rq->sense = h->sense;
-	memset(rq->sense, 0, SCSI_SENSE_BUFFERSIZE);
-	rq->sense_len = h->senselen = 0;
+	memset(cdb, 0x0, COMMAND_SIZE(MAINTENANCE_IN));
+	cdb[0] = MAINTENANCE_IN;
+	if (!(flags & ALUA_RTPG_EXT_HDR_UNSUPP))
+		cdb[1] = MI_REPORT_TARGET_PGS | MI_EXT_HDR_PARAM_FMT;
+	else
+		cdb[1] = MI_REPORT_TARGET_PGS;
+	put_unaligned_be32(bufflen, &cdb[6]);
 
-	err = blk_execute_rq(rq->q, NULL, rq, 1);
-	if (err == -EIO) {
-		sdev_printk(KERN_INFO, sdev,
-			    "%s: evpd inquiry failed with %x\n",
-			    ALUA_DH_NAME, rq->errors);
-		h->senselen = rq->sense_len;
-		err = SCSI_DH_IO;
-	}
-	blk_put_request(rq);
-done:
-	return err;
+	return scsi_execute_req_flags(sdev, cdb, DMA_FROM_DEVICE,
+				      buff, bufflen, sshdr,
+				      ALUA_FAILOVER_TIMEOUT * HZ,
+				      ALUA_FAILOVER_RETRIES, NULL, req_flags);
 }
 
 /*
- * submit_rtpg - Issue a REPORT TARGET GROUP STATES command
- * @sdev: sdev the command should be sent to
+ * submit_stpg - Issue a SET TARGET PORT GROUP command
+ *
+ * Currently we're only setting the current target port group state
+ * to 'active/optimized' and let the array firmware figure out
+ * the states of the remaining groups.
  */
-static unsigned submit_rtpg(struct scsi_device *sdev, struct alua_dh_data *h,
-			    bool rtpg_ext_hdr_req)
+static int submit_stpg(struct scsi_device *sdev, int group_id,
+		       struct scsi_sense_hdr *sshdr)
 {
-	struct request *rq;
-	int err = SCSI_DH_RES_TEMP_UNAVAIL;
+	u8 cdb[COMMAND_SIZE(MAINTENANCE_OUT)];
+	unsigned char stpg_data[8];
+	int stpg_len = 8;
+	int req_flags = REQ_FAILFAST_DEV | REQ_FAILFAST_TRANSPORT |
+		REQ_FAILFAST_DRIVER;
 
-	rq = get_alua_req(sdev, h->buff, h->bufflen, READ);
-	if (!rq)
-		goto done;
+	/* Prepare the data buffer */
+	memset(stpg_data, 0, stpg_len);
+	stpg_data[4] = TPGS_STATE_OPTIMIZED & 0x0f;
+	put_unaligned_be16(group_id, &stpg_data[6]);
 
 	/* Prepare the command. */
-	rq->cmd[0] = MAINTENANCE_IN;
-	if (rtpg_ext_hdr_req)
-		rq->cmd[1] = MI_REPORT_TARGET_PGS | MI_EXT_HDR_PARAM_FMT;
-	else
-		rq->cmd[1] = MI_REPORT_TARGET_PGS;
-	rq->cmd[6] = (h->bufflen >> 24) & 0xff;
-	rq->cmd[7] = (h->bufflen >> 16) & 0xff;
-	rq->cmd[8] = (h->bufflen >>  8) & 0xff;
-	rq->cmd[9] = h->bufflen & 0xff;
-	rq->cmd_len = COMMAND_SIZE(MAINTENANCE_IN);
-
-	rq->sense = h->sense;
-	memset(rq->sense, 0, SCSI_SENSE_BUFFERSIZE);
-	rq->sense_len = h->senselen = 0;
-
-	err = blk_execute_rq(rq->q, NULL, rq, 1);
-	if (err == -EIO) {
-		sdev_printk(KERN_INFO, sdev,
-			    "%s: rtpg failed with %x\n",
-			    ALUA_DH_NAME, rq->errors);
-		h->senselen = rq->sense_len;
-		err = SCSI_DH_IO;
-	}
-	blk_put_request(rq);
-done:
-	return err;
+	memset(cdb, 0x0, COMMAND_SIZE(MAINTENANCE_OUT));
+	cdb[0] = MAINTENANCE_OUT;
+	cdb[1] = MO_SET_TARGET_PGS;
+	put_unaligned_be32(stpg_len, &cdb[6]);
+
+	return scsi_execute_req_flags(sdev, cdb, DMA_TO_DEVICE,
+				      stpg_data, stpg_len,
+				      sshdr, ALUA_FAILOVER_TIMEOUT * HZ,
+				      ALUA_FAILOVER_RETRIES, NULL, req_flags);
 }
 
-/*
- * alua_stpg - Evaluate SET TARGET GROUP STATES
- * @sdev: the device to be evaluated
- * @state: the new target group state
- *
- * Send a SET TARGET GROUP STATES command to the device.
- * We only have to test here if we should resubmit the command;
- * any other error is assumed as a failure.
- */
-static void stpg_endio(struct request *req, int error)
+struct alua_port_group *alua_find_get_pg(char *id_str, size_t id_size,
+					 int group_id)
 {
-	struct alua_dh_data *h = req->end_io_data;
-	struct scsi_sense_hdr sense_hdr;
-	unsigned err = SCSI_DH_OK;
+	struct alua_port_group *pg;
 
-	if (host_byte(req->errors) != DID_OK ||
-	    msg_byte(req->errors) != COMMAND_COMPLETE) {
-		err = SCSI_DH_IO;
-		goto done;
-	}
+	if (!id_str || !id_size || !strlen(id_str))
+		return NULL;
 
-	if (req->sense_len > 0) {
-		err = scsi_normalize_sense(h->sense, SCSI_SENSE_BUFFERSIZE,
-					   &sense_hdr);
-		if (!err) {
-			err = SCSI_DH_IO;
-			goto done;
-		}
-		err = alua_check_sense(h->sdev, &sense_hdr);
-		if (err == ADD_TO_MLQUEUE) {
-			err = SCSI_DH_RETRY;
-			goto done;
-		}
-		sdev_printk(KERN_INFO, h->sdev,
-			    "%s: stpg sense code: %02x/%02x/%02x\n",
-			    ALUA_DH_NAME, sense_hdr.sense_key,
-			    sense_hdr.asc, sense_hdr.ascq);
-		err = SCSI_DH_IO;
-	} else if (error)
-		err = SCSI_DH_IO;
-
-	if (err == SCSI_DH_OK) {
-		h->state = TPGS_STATE_OPTIMIZED;
-		sdev_printk(KERN_INFO, h->sdev,
-			    "%s: port group %02x switched to state %c\n",
-			    ALUA_DH_NAME, h->group_id,
-			    print_alua_state(h->state));
-	}
-done:
-	req->end_io_data = NULL;
-	__blk_put_request(req->q, req);
-	if (h->callback_fn) {
-		h->callback_fn(h->callback_data, err);
-		h->callback_fn = h->callback_data = NULL;
+	list_for_each_entry(pg, &port_group_list, node) {
+		if (pg->group_id != group_id)
+			continue;
+		if (!pg->device_id_len || pg->device_id_len != id_size)
+			continue;
+		if (strncmp(pg->device_id_str, id_str, id_size))
+			continue;
+		if (!kref_get_unless_zero(&pg->kref))
+			continue;
+		return pg;
 	}
-	return;
+
+	return NULL;
 }
 
 /*
- * submit_stpg - Issue a SET TARGET GROUP STATES command
+ * alua_alloc_pg - Allocate a new port_group structure
+ * @sdev: scsi device
+ * @h: alua device_handler data
+ * @group_id: port group id
  *
- * Currently we're only setting the current target port group state
- * to 'active/optimized' and let the array firmware figure out
- * the states of the remaining groups.
+ * Allocate a new port_group structure for a given
+ * device.
  */
-static unsigned submit_stpg(struct alua_dh_data *h)
+struct alua_port_group *alua_alloc_pg(struct scsi_device *sdev,
+				      int group_id, int tpgs)
 {
-	struct request *rq;
-	int stpg_len = 8;
-	struct scsi_device *sdev = h->sdev;
+	struct alua_port_group *pg, *tmp_pg;
 
-	/* Prepare the data buffer */
-	memset(h->buff, 0, stpg_len);
-	h->buff[4] = TPGS_STATE_OPTIMIZED & 0x0f;
-	h->buff[6] = (h->group_id >> 8) & 0xff;
-	h->buff[7] = h->group_id & 0xff;
-
-	rq = get_alua_req(sdev, h->buff, stpg_len, WRITE);
-	if (!rq)
-		return SCSI_DH_RES_TEMP_UNAVAIL;
+	pg = kzalloc(sizeof(struct alua_port_group), GFP_KERNEL);
+	if (!pg)
+		return ERR_PTR(-ENOMEM);
+
+	pg->device_id_len = scsi_vpd_lun_id(sdev, pg->device_id_str,
+					    sizeof(pg->device_id_str));
+	if (pg->device_id_len <= 0) {
+		/*
+		 * TPGS supported but no device identification found.
+		 * Generate private device identification.
+		 */
+		sdev_printk(KERN_INFO, sdev,
+			    "%s: No device descriptors found\n",
+			    ALUA_DH_NAME);
+		pg->device_id_str[0] = '\0';
+		pg->device_id_len = 0;
+	}
+	pg->group_id = group_id;
+	pg->tpgs = tpgs;
+	pg->state = TPGS_STATE_OPTIMIZED;
+	if (optimize_stpg)
+		pg->flags |= ALUA_OPTIMIZE_STPG;
+	kref_init(&pg->kref);
+	INIT_DELAYED_WORK(&pg->rtpg_work, alua_rtpg_work);
+	INIT_LIST_HEAD(&pg->rtpg_list);
+	INIT_LIST_HEAD(&pg->node);
+	spin_lock_init(&pg->lock);
+
+	spin_lock(&port_group_lock);
+	tmp_pg = alua_find_get_pg(pg->device_id_str, pg->device_id_len,
+				  group_id);
+	if (tmp_pg) {
+		spin_unlock(&port_group_lock);
+		kfree(pg);
+		return tmp_pg;
+	}
 
-	/* Prepare the command. */
-	rq->cmd[0] = MAINTENANCE_OUT;
-	rq->cmd[1] = MO_SET_TARGET_PGS;
-	rq->cmd[6] = (stpg_len >> 24) & 0xff;
-	rq->cmd[7] = (stpg_len >> 16) & 0xff;
-	rq->cmd[8] = (stpg_len >>  8) & 0xff;
-	rq->cmd[9] = stpg_len & 0xff;
-	rq->cmd_len = COMMAND_SIZE(MAINTENANCE_OUT);
-
-	rq->sense = h->sense;
-	memset(rq->sense, 0, SCSI_SENSE_BUFFERSIZE);
-	rq->sense_len = h->senselen = 0;
-	rq->end_io_data = h;
+	list_add(&pg->node, &port_group_list);
+	spin_unlock(&port_group_lock);
 
-	blk_execute_rq_nowait(rq->q, NULL, rq, 1, stpg_endio);
-	return SCSI_DH_OK;
+	return pg;
 }
 
 /*
@@ -316,12 +282,23 @@ static unsigned submit_stpg(struct alua_
  * Examine the TPGS setting of the sdev to find out if ALUA
  * is supported.
  */
-static int alua_check_tpgs(struct scsi_device *sdev, struct alua_dh_data *h)
+static int alua_check_tpgs(struct scsi_device *sdev)
 {
-	int err = SCSI_DH_OK;
+	int tpgs = TPGS_MODE_NONE;
 
-	h->tpgs = scsi_device_tpgs(sdev);
-	switch (h->tpgs) {
+	/*
+	 * ALUA support for non-disk devices is fraught with
+	 * difficulties, so disable it for now.
+	 */
+	if (sdev->type != TYPE_DISK) {
+		sdev_printk(KERN_INFO, sdev,
+			    "%s: disable for non-disk devices\n",
+			    ALUA_DH_NAME);
+		return tpgs;
+	}
+
+	tpgs = scsi_device_tpgs(sdev);
+	switch (tpgs) {
 	case TPGS_MODE_EXPLICIT|TPGS_MODE_IMPLICIT:
 		sdev_printk(KERN_INFO, sdev,
 			    "%s: supports implicit and explicit TPGS\n",
@@ -335,71 +312,36 @@ static int alua_check_tpgs(struct scsi_d
 		sdev_printk(KERN_INFO, sdev, "%s: supports implicit TPGS\n",
 			    ALUA_DH_NAME);
 		break;
-	default:
-		h->tpgs = TPGS_MODE_NONE;
+	case TPGS_MODE_NONE:
 		sdev_printk(KERN_INFO, sdev, "%s: not supported\n",
 			    ALUA_DH_NAME);
-		err = SCSI_DH_DEV_UNSUPP;
+		break;
+	default:
+		sdev_printk(KERN_INFO, sdev,
+			    "%s: unsupported TPGS setting %d\n",
+			    ALUA_DH_NAME, tpgs);
+		tpgs = TPGS_MODE_NONE;
 		break;
 	}
 
-	return err;
+	return tpgs;
 }
 
 /*
- * alua_vpd_inquiry - Evaluate INQUIRY vpd page 0x83
+ * alua_check_vpd - Evaluate INQUIRY vpd page 0x83
  * @sdev: device to be checked
  *
  * Extract the relative target port and the target port group
  * descriptor from the list of identificators.
  */
-static int alua_vpd_inquiry(struct scsi_device *sdev, struct alua_dh_data *h)
+static int alua_check_vpd(struct scsi_device *sdev, struct alua_dh_data *h,
+			  int tpgs)
 {
-	int len;
-	unsigned err;
-	unsigned char *d;
-
- retry:
-	err = submit_vpd_inquiry(sdev, h);
-
-	if (err != SCSI_DH_OK)
-		return err;
+	int rel_port = -1, group_id;
+	struct alua_port_group *pg, *old_pg = NULL;
 
-	/* Check if vpd page exceeds initial buffer */
-	len = (h->buff[2] << 8) + h->buff[3] + 4;
-	if (len > h->bufflen) {
-		/* Resubmit with the correct length */
-		if (realloc_buffer(h, len)) {
-			sdev_printk(KERN_WARNING, sdev,
-				    "%s: kmalloc buffer failed\n",
-				    ALUA_DH_NAME);
-			/* Temporary failure, bypass */
-			return SCSI_DH_DEV_TEMP_BUSY;
-		}
-		goto retry;
-	}
-
-	/*
-	 * Now look for the correct descriptor.
-	 */
-	d = h->buff + 4;
-	while (d < h->buff + len) {
-		switch (d[1] & 0xf) {
-		case 0x4:
-			/* Relative target port */
-			h->rel_port = (d[6] << 8) + d[7];
-			break;
-		case 0x5:
-			/* Target port group */
-			h->group_id = (d[6] << 8) + d[7];
-			break;
-		default:
-			break;
-		}
-		d += d[3] + 4;
-	}
-
-	if (h->group_id == -1) {
+	group_id = scsi_vpd_tpg_id(sdev, &rel_port);
+	if (group_id < 0) {
 		/*
 		 * Internal error; TPGS supported but required
 		 * VPD identification descriptors not present.
@@ -408,16 +350,41 @@ static int alua_vpd_inquiry(struct scsi_
 		sdev_printk(KERN_INFO, sdev,
 			    "%s: No target port descriptors found\n",
 			    ALUA_DH_NAME);
-		h->state = TPGS_STATE_OPTIMIZED;
-		h->tpgs = TPGS_MODE_NONE;
-		err = SCSI_DH_DEV_UNSUPP;
-	} else {
-		sdev_printk(KERN_INFO, sdev,
-			    "%s: port group %02x rel port %02x\n",
-			    ALUA_DH_NAME, h->group_id, h->rel_port);
+		return SCSI_DH_DEV_UNSUPP;
 	}
 
-	return err;
+	pg = alua_alloc_pg(sdev, group_id, tpgs);
+	if (IS_ERR(pg)) {
+		if (PTR_ERR(pg) == -ENOMEM)
+			return SCSI_DH_NOMEM;
+		return SCSI_DH_DEV_UNSUPP;
+	}
+	if (pg->device_id_len)
+		sdev_printk(KERN_INFO, sdev,
+			    "%s: device %s port group %x rel port %x\n",
+			    ALUA_DH_NAME, pg->device_id_str,
+			    group_id, rel_port);
+	else
+		sdev_printk(KERN_INFO, sdev,
+			    "%s: port group %x rel port %x\n",
+			    ALUA_DH_NAME, group_id, rel_port);
+
+	/* Check for existing port group references */
+	spin_lock(&h->pg_lock);
+	old_pg = h->pg;
+	if (old_pg != pg) {
+		/* port group has changed. Update to new port group */
+		rcu_assign_pointer(h->pg, pg);
+	}
+	if (sdev->synchronous_alua)
+		pg->flags |= ALUA_SYNC_STPG;
+	alua_rtpg_queue(h->pg, sdev, NULL, true);
+	spin_unlock(&h->pg_lock);
+
+	if (old_pg)
+		kref_put(&old_pg->kref, release_port_group);
+
+	return SCSI_DH_OK;
 }
 
 static char print_alua_state(int state)
@@ -447,40 +414,24 @@ static int alua_check_sense(struct scsi_
 {
 	switch (sense_hdr->sense_key) {
 	case NOT_READY:
-		if (sense_hdr->asc == 0x04 && sense_hdr->ascq == 0x0a)
+		if (sense_hdr->asc == 0x04 && sense_hdr->ascq == 0x0a) {
 			/*
 			 * LUN Not Accessible - ALUA state transition
 			 */
-			return ADD_TO_MLQUEUE;
-		if (sense_hdr->asc == 0x04 && sense_hdr->ascq == 0x0b)
-			/*
-			 * LUN Not Accessible -- Target port in standby state
-			 */
-			return SUCCESS;
-		if (sense_hdr->asc == 0x04 && sense_hdr->ascq == 0x0c)
-			/*
-			 * LUN Not Accessible -- Target port in unavailable state
-			 */
-			return SUCCESS;
-		if (sense_hdr->asc == 0x04 && sense_hdr->ascq == 0x12)
-			/*
-			 * LUN Not Ready -- Offline
-			 */
-			return SUCCESS;
-		if (sdev->allow_restart &&
-		    sense_hdr->asc == 0x04 && sense_hdr->ascq == 0x02)
-			/*
-			 * if the device is not started, we need to wake
-			 * the error handler to start the motor
-			 */
-			return FAILED;
+			alua_check(sdev, false);
+			return NEEDS_RETRY;
+		}
 		break;
 	case UNIT_ATTENTION:
-		if (sense_hdr->asc == 0x29 && sense_hdr->ascq == 0x00)
+		if (sense_hdr->asc == 0x29 && sense_hdr->ascq == 0x00) {
 			/*
-			 * Power On, Reset, or Bus Device Reset, just retry.
+			 * Power On, Reset, or Bus Device Reset.
+			 * Might have obscured a state transition,
+			 * so schedule a recheck.
 			 */
+			alua_check(sdev, true);
 			return ADD_TO_MLQUEUE;
+		}
 		if (sense_hdr->asc == 0x29 && sense_hdr->ascq == 0x04)
 			/*
 			 * Device internal reset
@@ -491,16 +442,20 @@ static int alua_check_sense(struct scsi_
 			 * Mode Parameters Changed
 			 */
 			return ADD_TO_MLQUEUE;
-		if (sense_hdr->asc == 0x2a && sense_hdr->ascq == 0x06)
+		if (sense_hdr->asc == 0x2a && sense_hdr->ascq == 0x06) {
 			/*
 			 * ALUA state changed
 			 */
+			alua_check(sdev, true);
 			return ADD_TO_MLQUEUE;
-		if (sense_hdr->asc == 0x2a && sense_hdr->ascq == 0x07)
+		}
+		if (sense_hdr->asc == 0x2a && sense_hdr->ascq == 0x07) {
 			/*
 			 * Implicit ALUA state transition failed
 			 */
+			alua_check(sdev, true);
 			return ADD_TO_MLQUEUE;
+		}
 		if (sense_hdr->asc == 0x3f && sense_hdr->ascq == 0x03)
 			/*
 			 * Inquiry data has changed
@@ -520,38 +475,74 @@ static int alua_check_sense(struct scsi_
 }
 
 /*
+ * alua_tur - Send a TEST UNIT READY
+ * @sdev: device to which the TEST UNIT READY command should be send
+ *
+ * Send a TEST UNIT READY to @sdev to figure out the device state
+ * Returns SCSI_DH_RETRY if the sense code is NOT READY/ALUA TRANSITIONING,
+ * SCSI_DH_OK if no error occurred, and SCSI_DH_IO otherwise.
+ */
+static int alua_tur(struct scsi_device *sdev)
+{
+	struct scsi_sense_hdr sense_hdr;
+	int retval;
+
+	retval = scsi_test_unit_ready(sdev, ALUA_FAILOVER_TIMEOUT * HZ,
+				      ALUA_FAILOVER_RETRIES, &sense_hdr);
+	if (sense_hdr.sense_key == NOT_READY &&
+	    sense_hdr.asc == 0x04 && sense_hdr.ascq == 0x0a)
+		return SCSI_DH_RETRY;
+	else if (retval)
+		return SCSI_DH_IO;
+	else
+		return SCSI_DH_OK;
+}
+
+/*
  * alua_rtpg - Evaluate REPORT TARGET GROUP STATES
  * @sdev: the device to be evaluated.
- * @wait_for_transition: if nonzero, wait ALUA_FAILOVER_TIMEOUT seconds for device to exit transitioning state
  *
  * Evaluate the Target Port Group State.
  * Returns SCSI_DH_DEV_OFFLINED if the path is
  * found to be unusable.
  */
-static int alua_rtpg(struct scsi_device *sdev, struct alua_dh_data *h, int wait_for_transition)
+static int alua_rtpg(struct scsi_device *sdev, struct alua_port_group *pg)
 {
 	struct scsi_sense_hdr sense_hdr;
-	int len, k, off, valid_states = 0;
-	unsigned char *ucp;
-	unsigned err;
-	bool rtpg_ext_hdr_req = 1;
-	unsigned long expiry, interval = 0;
+	struct alua_port_group *tmp_pg;
+	int len, k, off, valid_states = 0, bufflen = ALUA_RTPG_SIZE;
+	unsigned char *desc, *buff;
+	unsigned err, retval;
 	unsigned int tpg_desc_tbl_off;
 	unsigned char orig_transition_tmo;
+	unsigned long flags;
 
-	if (!h->transition_tmo)
-		expiry = round_jiffies_up(jiffies + ALUA_FAILOVER_TIMEOUT * HZ);
-	else
-		expiry = round_jiffies_up(jiffies + h->transition_tmo * HZ);
+	if (!pg->expiry) {
+		unsigned long transition_tmo = ALUA_FAILOVER_TIMEOUT * HZ;
+
+		if (pg->transition_tmo)
+			transition_tmo = pg->transition_tmo * HZ;
+
+		pg->expiry = round_jiffies_up(jiffies + transition_tmo);
+	}
+
+	buff = kzalloc(bufflen, GFP_KERNEL);
+	if (!buff)
+		return SCSI_DH_DEV_TEMP_BUSY;
 
  retry:
-	err = submit_rtpg(sdev, h, rtpg_ext_hdr_req);
+	retval = submit_rtpg(sdev, buff, bufflen, &sense_hdr, pg->flags);
 
-	if (err == SCSI_DH_IO && h->senselen > 0) {
-		err = scsi_normalize_sense(h->sense, SCSI_SENSE_BUFFERSIZE,
-					   &sense_hdr);
-		if (!err)
+	if (retval) {
+		if (!scsi_sense_valid(&sense_hdr)) {
+			sdev_printk(KERN_INFO, sdev,
+				    "%s: rtpg failed, result %d\n",
+				    ALUA_DH_NAME, retval);
+			kfree(buff);
+			if (driver_byte(retval) == DRIVER_ERROR)
+				return SCSI_DH_DEV_TEMP_BUSY;
 			return SCSI_DH_IO;
+		}
 
 		/*
 		 * submit_rtpg() has failed on existing arrays
@@ -561,73 +552,101 @@ static int alua_rtpg(struct scsi_device
 		 * The retry without rtpg_ext_hdr_req set
 		 * handles this.
 		 */
-		if (rtpg_ext_hdr_req == 1 &&
+		if (!(pg->flags & ALUA_RTPG_EXT_HDR_UNSUPP) &&
 		    sense_hdr.sense_key == ILLEGAL_REQUEST &&
 		    sense_hdr.asc == 0x24 && sense_hdr.ascq == 0) {
-			rtpg_ext_hdr_req = 0;
+			pg->flags |= ALUA_RTPG_EXT_HDR_UNSUPP;
 			goto retry;
 		}
-
-		err = alua_check_sense(sdev, &sense_hdr);
-		if (err == ADD_TO_MLQUEUE && time_before(jiffies, expiry))
-			goto retry;
-		sdev_printk(KERN_INFO, sdev,
-			    "%s: rtpg sense code %02x/%02x/%02x\n",
-			    ALUA_DH_NAME, sense_hdr.sense_key,
-			    sense_hdr.asc, sense_hdr.ascq);
-		err = SCSI_DH_IO;
+		/*
+		 * Retry on ALUA state transition or if any
+		 * UNIT ATTENTION occurred.
+		 */
+		if (sense_hdr.sense_key == NOT_READY &&
+		    sense_hdr.asc == 0x04 && sense_hdr.ascq == 0x0a)
+			err = SCSI_DH_RETRY;
+		else if (sense_hdr.sense_key == UNIT_ATTENTION)
+			err = SCSI_DH_RETRY;
+		if (err == SCSI_DH_RETRY &&
+		    pg->expiry != 0 && time_before(jiffies, pg->expiry)) {
+			sdev_printk(KERN_ERR, sdev, "%s: rtpg retry\n",
+				    ALUA_DH_NAME);
+			scsi_print_sense_hdr(sdev, ALUA_DH_NAME, &sense_hdr);
+			return err;
+		}
+		sdev_printk(KERN_ERR, sdev, "%s: rtpg failed\n",
+			    ALUA_DH_NAME);
+		scsi_print_sense_hdr(sdev, ALUA_DH_NAME, &sense_hdr);
+		kfree(buff);
+		pg->expiry = 0;
+		return SCSI_DH_IO;
 	}
-	if (err != SCSI_DH_OK)
-		return err;
 
-	len = (h->buff[0] << 24) + (h->buff[1] << 16) +
-		(h->buff[2] << 8) + h->buff[3] + 4;
+	len = get_unaligned_be32(&buff[0]) + 4;
 
-	if (len > h->bufflen) {
+	if (len > bufflen) {
 		/* Resubmit with the correct length */
-		if (realloc_buffer(h, len)) {
+		kfree(buff);
+		bufflen = len;
+		buff = kmalloc(bufflen, GFP_KERNEL);
+		if (!buff) {
 			sdev_printk(KERN_WARNING, sdev,
 				    "%s: kmalloc buffer failed\n",__func__);
 			/* Temporary failure, bypass */
+			pg->expiry = 0;
 			return SCSI_DH_DEV_TEMP_BUSY;
 		}
 		goto retry;
 	}
 
-	orig_transition_tmo = h->transition_tmo;
-	if ((h->buff[4] & RTPG_FMT_MASK) == RTPG_FMT_EXT_HDR && h->buff[5] != 0)
-		h->transition_tmo = h->buff[5];
+	orig_transition_tmo = pg->transition_tmo;
+	if ((buff[4] & RTPG_FMT_MASK) == RTPG_FMT_EXT_HDR && buff[5] != 0)
+		pg->transition_tmo = buff[5];
 	else
-		h->transition_tmo = ALUA_FAILOVER_TIMEOUT;
+		pg->transition_tmo = ALUA_FAILOVER_TIMEOUT;
 
-	if (wait_for_transition && (orig_transition_tmo != h->transition_tmo)) {
+	if (orig_transition_tmo != pg->transition_tmo) {
 		sdev_printk(KERN_INFO, sdev,
 			    "%s: transition timeout set to %d seconds\n",
-			    ALUA_DH_NAME, h->transition_tmo);
-		expiry = jiffies + h->transition_tmo * HZ;
+			    ALUA_DH_NAME, pg->transition_tmo);
+		pg->expiry = jiffies + pg->transition_tmo * HZ;
 	}
 
-	if ((h->buff[4] & RTPG_FMT_MASK) == RTPG_FMT_EXT_HDR)
+	if ((buff[4] & RTPG_FMT_MASK) == RTPG_FMT_EXT_HDR)
 		tpg_desc_tbl_off = 8;
 	else
 		tpg_desc_tbl_off = 4;
 
-	for (k = tpg_desc_tbl_off, ucp = h->buff + tpg_desc_tbl_off;
+	for (k = tpg_desc_tbl_off, desc = buff + tpg_desc_tbl_off;
 	     k < len;
-	     k += off, ucp += off) {
+	     k += off, desc += off) {
+		u16 group_id = get_unaligned_be16(&desc[2]);
 
-		if (h->group_id == (ucp[2] << 8) + ucp[3]) {
-			h->state = ucp[0] & 0x0f;
-			h->pref = ucp[0] >> 7;
-			valid_states = ucp[1];
+		spin_lock_irqsave(&port_group_lock, flags);
+		tmp_pg = alua_find_get_pg(pg->device_id_str, pg->device_id_len,
+					  group_id);
+		spin_unlock_irqrestore(&port_group_lock, flags);
+		if (tmp_pg) {
+			if (spin_trylock_irqsave(&tmp_pg->lock, flags)) {
+				if ((tmp_pg == pg) ||
+				    !(tmp_pg->flags & ALUA_PG_RUNNING)) {
+					tmp_pg->state = desc[0] & 0x0f;
+					tmp_pg->pref = desc[0] >> 7;
+				}
+				if (tmp_pg == pg)
+					valid_states = desc[1];
+				spin_unlock_irqrestore(&tmp_pg->lock, flags);
+			}
+			kref_put(&tmp_pg->kref, release_port_group);
 		}
-		off = 8 + (ucp[7] * 4);
+		off = 8 + (desc[7] * 4);
 	}
 
+	spin_lock_irqsave(&pg->lock, flags);
 	sdev_printk(KERN_INFO, sdev,
 		    "%s: port group %02x state %c %s supports %c%c%c%c%c%c%c\n",
-		    ALUA_DH_NAME, h->group_id, print_alua_state(h->state),
-		    h->pref ? "preferred" : "non-preferred",
+		    ALUA_DH_NAME, pg->group_id, print_alua_state(pg->state),
+		    pg->pref ? "preferred" : "non-preferred",
 		    valid_states&TPGS_SUPPORT_TRANSITION?'T':'t',
 		    valid_states&TPGS_SUPPORT_OFFLINE?'O':'o',
 		    valid_states&TPGS_SUPPORT_LBA_DEPENDENT?'L':'l',
@@ -636,36 +655,224 @@ static int alua_rtpg(struct scsi_device
 		    valid_states&TPGS_SUPPORT_NONOPTIMIZED?'N':'n',
 		    valid_states&TPGS_SUPPORT_OPTIMIZED?'A':'a');
 
-	switch (h->state) {
+	switch (pg->state) {
 	case TPGS_STATE_TRANSITIONING:
-		if (wait_for_transition) {
-			if (time_before(jiffies, expiry)) {
-				/* State transition, retry */
-				interval += 2000;
-				msleep(interval);
-				goto retry;
-			}
+		if (time_before(jiffies, pg->expiry)) {
+			/* State transition, retry */
+			pg->interval = 2;
 			err = SCSI_DH_RETRY;
 		} else {
-			err = SCSI_DH_OK;
+			/* Transitioning time exceeded, set port to standby */
+			err = SCSI_DH_IO;
+			pg->state = TPGS_STATE_STANDBY;
+			pg->expiry = 0;
 		}
-
-		/* Transitioning time exceeded, set port to standby */
-		h->state = TPGS_STATE_STANDBY;
 		break;
 	case TPGS_STATE_OFFLINE:
 		/* Path unusable */
 		err = SCSI_DH_DEV_OFFLINED;
+		pg->expiry = 0;
 		break;
 	default:
 		/* Useable path if active */
 		err = SCSI_DH_OK;
+		pg->expiry = 0;
 		break;
 	}
+	spin_unlock_irqrestore(&pg->lock, flags);
+	kfree(buff);
 	return err;
 }
 
 /*
+ * alua_stpg - Issue a SET TARGET PORT GROUP command
+ *
+ * Issue a SET TARGET PORT GROUP command and evaluate the
+ * response. Returns SCSI_DH_RETRY per default to trigger
+ * a re-evaluation of the target group state or SCSI_DH_OK
+ * if no further action needs to be taken.
+ */
+static unsigned alua_stpg(struct scsi_device *sdev, struct alua_port_group *pg)
+{
+	int retval;
+	struct scsi_sense_hdr sense_hdr;
+
+	if (!(pg->tpgs & TPGS_MODE_EXPLICIT)) {
+		/* Only implicit ALUA supported, retry */
+		return SCSI_DH_RETRY;
+	}
+	switch (pg->state) {
+	case TPGS_STATE_OPTIMIZED:
+		return SCSI_DH_OK;
+	case TPGS_STATE_NONOPTIMIZED:
+		if ((pg->flags & ALUA_OPTIMIZE_STPG) &&
+		    !pg->pref &&
+		    (pg->tpgs & TPGS_MODE_IMPLICIT))
+			return SCSI_DH_OK;
+		break;
+	case TPGS_STATE_STANDBY:
+	case TPGS_STATE_UNAVAILABLE:
+		break;
+	case TPGS_STATE_OFFLINE:
+		return SCSI_DH_IO;
+	case TPGS_STATE_TRANSITIONING:
+		break;
+	default:
+		sdev_printk(KERN_INFO, sdev,
+			    "%s: stpg failed, unhandled TPGS state %d",
+			    ALUA_DH_NAME, pg->state);
+		return SCSI_DH_NOSYS;
+	}
+	retval = submit_stpg(sdev, pg->group_id, &sense_hdr);
+
+	if (retval) {
+		if (!scsi_sense_valid(&sense_hdr)) {
+			sdev_printk(KERN_INFO, sdev,
+				    "%s: stpg failed, result %d",
+				    ALUA_DH_NAME, retval);
+			if (driver_byte(retval) == DRIVER_ERROR)
+				return SCSI_DH_DEV_TEMP_BUSY;
+		} else {
+			sdev_printk(KERN_INFO, sdev, "%s: stpg failed\n",
+				    ALUA_DH_NAME);
+			scsi_print_sense_hdr(sdev, ALUA_DH_NAME, &sense_hdr);
+		}
+	}
+	/* Retry RTPG */
+	return SCSI_DH_RETRY;
+}
+
+static void alua_rtpg_work(struct work_struct *work)
+{
+	struct alua_port_group *pg =
+		container_of(work, struct alua_port_group, rtpg_work.work);
+	struct scsi_device *sdev;
+	LIST_HEAD(qdata_list);
+	int err = SCSI_DH_OK;
+	struct alua_queue_data *qdata, *tmp;
+	unsigned long flags;
+	struct workqueue_struct *alua_wq = kaluad_wq;
+
+	spin_lock_irqsave(&pg->lock, flags);
+	sdev = pg->rtpg_sdev;
+	if (!sdev) {
+		WARN_ON(pg->flags & ALUA_PG_RUN_RTPG);
+		WARN_ON(pg->flags & ALUA_PG_RUN_STPG);
+		spin_unlock_irqrestore(&pg->lock, flags);
+		return;
+	}
+	if (pg->flags & ALUA_SYNC_STPG)
+		alua_wq = kaluad_sync_wq;
+	pg->flags |= ALUA_PG_RUNNING;
+	if (pg->flags & ALUA_PG_RUN_RTPG) {
+		int state = pg->state;
+
+		pg->flags &= ~ALUA_PG_RUN_RTPG;
+		spin_unlock_irqrestore(&pg->lock, flags);
+		if (state == TPGS_STATE_TRANSITIONING) {
+			if (alua_tur(sdev) == SCSI_DH_RETRY) {
+				spin_lock_irqsave(&pg->lock, flags);
+				pg->flags &= ~ALUA_PG_RUNNING;
+				pg->flags |= ALUA_PG_RUN_RTPG;
+				spin_unlock_irqrestore(&pg->lock, flags);
+				queue_delayed_work(alua_wq, &pg->rtpg_work,
+						   pg->interval * HZ);
+				return;
+			}
+			/* Send RTPG on failure or if TUR indicates SUCCESS */
+		}
+		err = alua_rtpg(sdev, pg);
+		spin_lock_irqsave(&pg->lock, flags);
+		if (err == SCSI_DH_RETRY || pg->flags & ALUA_PG_RUN_RTPG) {
+			pg->flags &= ~ALUA_PG_RUNNING;
+			pg->flags |= ALUA_PG_RUN_RTPG;
+			spin_unlock_irqrestore(&pg->lock, flags);
+			queue_delayed_work(alua_wq, &pg->rtpg_work,
+					   pg->interval * HZ);
+			return;
+		}
+		if (err != SCSI_DH_OK)
+			pg->flags &= ~ALUA_PG_RUN_STPG;
+	}
+	if (pg->flags & ALUA_PG_RUN_STPG) {
+		pg->flags &= ~ALUA_PG_RUN_STPG;
+		spin_unlock_irqrestore(&pg->lock, flags);
+		err = alua_stpg(sdev, pg);
+		spin_lock_irqsave(&pg->lock, flags);
+		if (err == SCSI_DH_RETRY || pg->flags & ALUA_PG_RUN_RTPG) {
+			pg->flags |= ALUA_PG_RUN_RTPG;
+			pg->interval = 0;
+			pg->flags &= ~ALUA_PG_RUNNING;
+			spin_unlock_irqrestore(&pg->lock, flags);
+			queue_delayed_work(alua_wq, &pg->rtpg_work,
+					   pg->interval * HZ);
+			return;
+		}
+	}
+
+	list_splice_init(&pg->rtpg_list, &qdata_list);
+	pg->rtpg_sdev = NULL;
+	spin_unlock_irqrestore(&pg->lock, flags);
+
+	list_for_each_entry_safe(qdata, tmp, &qdata_list, entry) {
+		list_del(&qdata->entry);
+		if (qdata->callback_fn)
+			qdata->callback_fn(qdata->callback_data, err);
+		kfree(qdata);
+	}
+	spin_lock_irqsave(&pg->lock, flags);
+	pg->flags &= ~ALUA_PG_RUNNING;
+	spin_unlock_irqrestore(&pg->lock, flags);
+	scsi_device_put(sdev);
+	kref_put(&pg->kref, release_port_group);
+}
+
+static void alua_rtpg_queue(struct alua_port_group *pg,
+			    struct scsi_device *sdev,
+			    struct alua_queue_data *qdata, bool force)
+{
+	int start_queue = 0;
+	unsigned long flags;
+	struct workqueue_struct *alua_wq = kaluad_wq;
+
+	if (!pg)
+		return;
+
+	spin_lock_irqsave(&pg->lock, flags);
+	if (qdata) {
+		list_add_tail(&qdata->entry, &pg->rtpg_list);
+		pg->flags |= ALUA_PG_RUN_STPG;
+		force = true;
+	}
+	if (pg->rtpg_sdev == NULL) {
+		pg->interval = 0;
+		pg->flags |= ALUA_PG_RUN_RTPG;
+		kref_get(&pg->kref);
+		pg->rtpg_sdev = sdev;
+		scsi_device_get(sdev);
+		start_queue = 1;
+	} else if (!(pg->flags & ALUA_PG_RUN_RTPG) && force) {
+		pg->flags |= ALUA_PG_RUN_RTPG;
+		/* Do not queue if the worker is already running */
+		if (!(pg->flags & ALUA_PG_RUNNING)) {
+			kref_get(&pg->kref);
+			start_queue = 1;
+		}
+	}
+
+	if (pg->flags & ALUA_SYNC_STPG)
+		alua_wq = kaluad_sync_wq;
+	spin_unlock_irqrestore(&pg->lock, flags);
+
+	if (start_queue &&
+	    !queue_delayed_work(alua_wq, &pg->rtpg_work,
+				msecs_to_jiffies(ALUA_RTPG_DELAY_MSECS))) {
+		scsi_device_put(sdev);
+		kref_put(&pg->kref, release_port_group);
+	}
+}
+
+/*
  * alua_initialize - Initialize ALUA state
  * @sdev: the device to be initialized
  *
@@ -674,21 +881,14 @@ static int alua_rtpg(struct scsi_device
  */
 static int alua_initialize(struct scsi_device *sdev, struct alua_dh_data *h)
 {
-	int err;
-
-	err = alua_check_tpgs(sdev, h);
-	if (err != SCSI_DH_OK)
-		goto out;
-
-	err = alua_vpd_inquiry(sdev, h);
-	if (err != SCSI_DH_OK)
-		goto out;
-
-	err = alua_rtpg(sdev, h, 0);
-	if (err != SCSI_DH_OK)
-		goto out;
+	int err = SCSI_DH_DEV_UNSUPP, tpgs;
 
-out:
+	mutex_lock(&h->init_mutex);
+	tpgs = alua_check_tpgs(sdev);
+	if (tpgs != TPGS_MODE_NONE)
+		err = alua_check_vpd(sdev, h, tpgs);
+	h->init_error = err;
+	mutex_unlock(&h->init_mutex);
 	return err;
 }
 /*
@@ -703,9 +903,11 @@ out:
 static int alua_set_params(struct scsi_device *sdev, const char *params)
 {
 	struct alua_dh_data *h = sdev->handler_data;
+	struct alua_port_group __rcu *pg = NULL;
 	unsigned int optimize = 0, argc;
 	const char *p = params;
 	int result = SCSI_DH_OK;
+	unsigned long flags;
 
 	if ((sscanf(params, "%u", &argc) != 1) || (argc != 1))
 		return -EINVAL;
@@ -715,18 +917,23 @@ static int alua_set_params(struct scsi_d
 	if ((sscanf(p, "%u", &optimize) != 1) || (optimize > 1))
 		return -EINVAL;
 
+	rcu_read_lock();
+	pg = rcu_dereference(h->pg);
+	if (!pg) {
+		rcu_read_unlock();
+		return -ENXIO;
+	}
+	spin_lock_irqsave(&pg->lock, flags);
 	if (optimize)
-		h->flags |= ALUA_OPTIMIZE_STPG;
+		pg->flags |= ALUA_OPTIMIZE_STPG;
 	else
-		h->flags &= ~ALUA_OPTIMIZE_STPG;
+		pg->flags &= ~ALUA_OPTIMIZE_STPG;
+	spin_unlock_irqrestore(&pg->lock, flags);
+	rcu_read_unlock();
 
 	return result;
 }
 
-static uint optimize_stpg;
-module_param(optimize_stpg, uint, S_IRUGO|S_IWUSR);
-MODULE_PARM_DESC(optimize_stpg, "Allow use of a non-optimized path, rather than sending a STPG, when implicit TPGS is supported (0=No,1=Yes). Default is 0.");
-
 /*
  * alua_activate - activate a path
  * @sdev: device on the path to be activated
@@ -742,48 +949,33 @@ static int alua_activate(struct scsi_dev
 {
 	struct alua_dh_data *h = sdev->handler_data;
 	int err = SCSI_DH_OK;
-	int stpg = 0;
+	struct alua_queue_data *qdata;
+	struct alua_port_group __rcu *pg;
 
-	err = alua_rtpg(sdev, h, 1);
-	if (err != SCSI_DH_OK)
+	qdata = kzalloc(sizeof(*qdata), GFP_KERNEL);
+	if (!qdata) {
+		err = SCSI_DH_RES_TEMP_UNAVAIL;
 		goto out;
-
-	if (optimize_stpg)
-		h->flags |= ALUA_OPTIMIZE_STPG;
-
-	if (h->tpgs & TPGS_MODE_EXPLICIT) {
-		switch (h->state) {
-		case TPGS_STATE_NONOPTIMIZED:
-			stpg = 1;
-			if ((h->flags & ALUA_OPTIMIZE_STPG) &&
-			    (!h->pref) &&
-			    (h->tpgs & TPGS_MODE_IMPLICIT))
-				stpg = 0;
-			break;
-		case TPGS_STATE_STANDBY:
-		case TPGS_STATE_UNAVAILABLE:
-			stpg = 1;
-			break;
-		case TPGS_STATE_OFFLINE:
-			err = SCSI_DH_IO;
-			break;
-		case TPGS_STATE_TRANSITIONING:
-			err = SCSI_DH_RETRY;
-			break;
-		default:
-			break;
-		}
 	}
+	qdata->callback_fn = fn;
+	qdata->callback_data = data;
 
-	if (stpg) {
-		h->callback_fn = fn;
-		h->callback_data = data;
-		err = submit_stpg(h);
-		if (err == SCSI_DH_OK)
-			return 0;
-		h->callback_fn = h->callback_data = NULL;
+	mutex_lock(&h->init_mutex);
+	rcu_read_lock();
+	pg = rcu_dereference(h->pg);
+	if (!pg || !kref_get_unless_zero(&pg->kref)) {
+		rcu_read_unlock();
+		kfree(qdata);
+		err = h->init_error;
+		mutex_unlock(&h->init_mutex);
+		goto out;
 	}
+	fn = NULL;
+	rcu_read_unlock();
+	mutex_unlock(&h->init_mutex);
 
+	alua_rtpg_queue(pg, sdev, qdata, true);
+	kref_put(&pg->kref, release_port_group);
 out:
 	if (fn)
 		fn(data, err);
@@ -791,6 +983,29 @@ out:
 }
 
 /*
+ * alua_check - check path status
+ * @sdev: device on the path to be checked
+ *
+ * Check the device status
+ */
+static void alua_check(struct scsi_device *sdev, bool force)
+{
+	struct alua_dh_data *h = sdev->handler_data;
+	struct alua_port_group *pg;
+
+	rcu_read_lock();
+	pg = rcu_dereference(h->pg);
+	if (!pg || !kref_get_unless_zero(&pg->kref)) {
+		rcu_read_unlock();
+		return;
+	}
+	rcu_read_unlock();
+
+	alua_rtpg_queue(pg, sdev, NULL, force);
+	kref_put(&pg->kref, release_port_group);
+}
+
+/*
  * alua_prep_fn - request callback
  *
  * Fail I/O to all paths not in state
@@ -799,13 +1014,20 @@ out:
 static int alua_prep_fn(struct scsi_device *sdev, struct request *req)
 {
 	struct alua_dh_data *h = sdev->handler_data;
+	struct alua_port_group __rcu *pg;
+	int state = TPGS_STATE_OPTIMIZED;
 	int ret = BLKPREP_OK;
 
-	if (h->state == TPGS_STATE_TRANSITIONING)
+	rcu_read_lock();
+	pg = rcu_dereference(h->pg);
+	if (pg)
+		state = pg->state;
+	rcu_read_unlock();
+	if (state == TPGS_STATE_TRANSITIONING)
 		ret = BLKPREP_DEFER;
-	else if (h->state != TPGS_STATE_OPTIMIZED &&
-		 h->state != TPGS_STATE_NONOPTIMIZED &&
-		 h->state != TPGS_STATE_LBA_DEPENDENT) {
+	else if (state != TPGS_STATE_OPTIMIZED &&
+		 state != TPGS_STATE_NONOPTIMIZED &&
+		 state != TPGS_STATE_LBA_DEPENDENT) {
 		ret = BLKPREP_KILL;
 		req->cmd_flags |= REQ_QUIET;
 	}
@@ -820,20 +1042,20 @@ static int alua_prep_fn(struct scsi_devi
 static int alua_bus_attach(struct scsi_device *sdev)
 {
 	struct alua_dh_data *h;
-	int err;
+	int err, ret = -EINVAL;
 
 	h = kzalloc(sizeof(*h) , GFP_KERNEL);
 	if (!h)
 		return -ENOMEM;
-	h->tpgs = TPGS_MODE_UNINITIALIZED;
-	h->state = TPGS_STATE_OPTIMIZED;
-	h->group_id = -1;
-	h->rel_port = -1;
-	h->buff = h->inq;
-	h->bufflen = ALUA_INQUIRY_SIZE;
+	spin_lock_init(&h->pg_lock);
+	rcu_assign_pointer(h->pg, NULL);
+	h->init_error = SCSI_DH_OK;
 	h->sdev = sdev;
 
+	mutex_init(&h->init_mutex);
 	err = alua_initialize(sdev, h);
+	if (err == SCSI_DH_NOMEM)
+		ret = -ENOMEM;
 	if (err != SCSI_DH_OK && err != SCSI_DH_DEV_OFFLINED)
 		goto failed;
 
@@ -841,7 +1063,7 @@ static int alua_bus_attach(struct scsi_d
 	return 0;
 failed:
 	kfree(h);
-	return -EINVAL;
+	return ret;
 }
 
 /*
@@ -851,9 +1073,16 @@ failed:
 static void alua_bus_detach(struct scsi_device *sdev)
 {
 	struct alua_dh_data *h = sdev->handler_data;
+	struct alua_port_group *pg;
+
+	spin_lock(&h->pg_lock);
+	pg = h->pg;
+	rcu_assign_pointer(h->pg, NULL);
+	h->sdev = NULL;
+	spin_unlock(&h->pg_lock);
+	if (pg)
+		kref_put(&pg->kref, release_port_group);
 
-	if (h->buff && h->inq != h->buff)
-		kfree(h->buff);
 	sdev->handler_data = NULL;
 	kfree(h);
 }
@@ -873,16 +1102,31 @@ static int __init alua_init(void)
 {
 	int r;
 
+	kaluad_wq = alloc_workqueue("kaluad", WQ_MEM_RECLAIM, 0);
+	if (!kaluad_wq) {
+		/* Temporary failure, bypass */
+		return SCSI_DH_DEV_TEMP_BUSY;
+	}
+	kaluad_sync_wq = create_workqueue("kaluad_sync");
+	if (!kaluad_sync_wq) {
+		destroy_workqueue(kaluad_wq);
+		return SCSI_DH_DEV_TEMP_BUSY;
+	}
 	r = scsi_register_device_handler(&alua_dh);
-	if (r != 0)
+	if (r != 0) {
 		printk(KERN_ERR "%s: Failed to register scsi device handler",
 			ALUA_DH_NAME);
+		destroy_workqueue(kaluad_sync_wq);
+		destroy_workqueue(kaluad_wq);
+	}
 	return r;
 }
 
 static void __exit alua_exit(void)
 {
 	scsi_unregister_device_handler(&alua_dh);
+	destroy_workqueue(kaluad_sync_wq);
+	destroy_workqueue(kaluad_wq);
 }
 
 module_init(alua_init);
--- zfcpdump-kernel-4.4.orig/drivers/scsi/device_handler/scsi_dh_rdac.c
+++ zfcpdump-kernel-4.4/drivers/scsi/device_handler/scsi_dh_rdac.c
@@ -562,7 +562,7 @@ static int mode_select_handle_sense(stru
 			/*
 			 * Command Lock contention
 			 */
-			err = SCSI_DH_RETRY;
+			err = SCSI_DH_IMM_RETRY;
 		break;
 	default:
 		break;
@@ -612,6 +612,8 @@ retry:
 		err = mode_select_handle_sense(sdev, h->sense);
 		if (err == SCSI_DH_RETRY && retry_cnt--)
 			goto retry;
+		if (err == SCSI_DH_IMM_RETRY)
+			goto retry;
 	}
 	if (err == SCSI_DH_OK) {
 		h->state = RDAC_STATE_ACTIVE;
--- zfcpdump-kernel-4.4.orig/drivers/scsi/fnic/fnic_fcs.c
+++ zfcpdump-kernel-4.4/drivers/scsi/fnic/fnic_fcs.c
@@ -954,8 +954,8 @@ int fnic_alloc_rq_frame(struct vnic_rq *
 	skb_put(skb, len);
 	pa = pci_map_single(fnic->pdev, skb->data, len, PCI_DMA_FROMDEVICE);
 
-	r = pci_dma_mapping_error(fnic->pdev, pa);
-	if (r) {
+	if (pci_dma_mapping_error(fnic->pdev, pa)) {
+		r = -ENOMEM;
 		printk(KERN_ERR "PCI mapping failed with error %d\n", r);
 		goto free_skb;
 	}
@@ -1093,8 +1093,8 @@ static int fnic_send_frame(struct fnic *
 
 	pa = pci_map_single(fnic->pdev, eth_hdr, tot_len, PCI_DMA_TODEVICE);
 
-	ret = pci_dma_mapping_error(fnic->pdev, pa);
-	if (ret) {
+	if (pci_dma_mapping_error(fnic->pdev, pa)) {
+		ret = -ENOMEM;
 		printk(KERN_ERR "DMA map failed with error %d\n", ret);
 		goto free_skb_on_err;
 	}
--- zfcpdump-kernel-4.4.orig/drivers/scsi/ibmvscsi/ibmvfc.c
+++ zfcpdump-kernel-4.4/drivers/scsi/ibmvscsi/ibmvfc.c
@@ -717,7 +717,6 @@ static int ibmvfc_reset_crq(struct ibmvf
 	spin_lock_irqsave(vhost->host->host_lock, flags);
 	vhost->state = IBMVFC_NO_CRQ;
 	vhost->logged_in = 0;
-	ibmvfc_set_host_action(vhost, IBMVFC_HOST_ACTION_NONE);
 
 	/* Clean out the queue */
 	memset(crq->msgs, 0, PAGE_SIZE);
--- zfcpdump-kernel-4.4.orig/drivers/scsi/ibmvscsi/ibmvfc.h
+++ zfcpdump-kernel-4.4/drivers/scsi/ibmvscsi/ibmvfc.h
@@ -26,7 +26,7 @@
 
 #include <linux/list.h>
 #include <linux/types.h>
-#include "viosrp.h"
+#include <scsi/viosrp.h>
 
 #define IBMVFC_NAME	"ibmvfc"
 #define IBMVFC_DRIVER_VERSION		"1.0.11"
--- zfcpdump-kernel-4.4.orig/drivers/scsi/ibmvscsi/ibmvscsi.c
+++ zfcpdump-kernel-4.4/drivers/scsi/ibmvscsi/ibmvscsi.c
@@ -2041,7 +2041,7 @@ static ssize_t show_host_partition_numbe
 	int len;
 
 	len = snprintf(buf, PAGE_SIZE, "%d\n",
-		       hostdata->madapter_info.partition_number);
+		       be32_to_cpu(hostdata->madapter_info.partition_number));
 	return len;
 }
 
@@ -2061,7 +2061,7 @@ static ssize_t show_host_mad_version(str
 	int len;
 
 	len = snprintf(buf, PAGE_SIZE, "%d\n",
-		       hostdata->madapter_info.mad_version);
+		       be32_to_cpu(hostdata->madapter_info.mad_version));
 	return len;
 }
 
@@ -2080,7 +2080,8 @@ static ssize_t show_host_os_type(struct
 	struct ibmvscsi_host_data *hostdata = shost_priv(shost);
 	int len;
 
-	len = snprintf(buf, PAGE_SIZE, "%d\n", hostdata->madapter_info.os_type);
+	len = snprintf(buf, PAGE_SIZE, "%d\n",
+		       be32_to_cpu(hostdata->madapter_info.os_type));
 	return len;
 }
 
--- zfcpdump-kernel-4.4.orig/drivers/scsi/ibmvscsi/ibmvscsi.h
+++ zfcpdump-kernel-4.4/drivers/scsi/ibmvscsi/ibmvscsi.h
@@ -33,7 +33,7 @@
 #include <linux/list.h>
 #include <linux/completion.h>
 #include <linux/interrupt.h>
-#include "viosrp.h"
+#include <scsi/viosrp.h>
 
 struct scsi_cmnd;
 struct Scsi_Host;
--- zfcpdump-kernel-4.4.orig/drivers/scsi/ibmvscsi/viosrp.h
+++ /dev/null
@@ -1,217 +0,0 @@
-/*****************************************************************************/
-/* srp.h -- SCSI RDMA Protocol definitions                                   */
-/*                                                                           */
-/* Written By: Colin Devilbis, IBM Corporation                               */
-/*                                                                           */
-/* Copyright (C) 2003 IBM Corporation                                        */
-/*                                                                           */
-/* This program is free software; you can redistribute it and/or modify      */
-/* it under the terms of the GNU General Public License as published by      */
-/* the Free Software Foundation; either version 2 of the License, or         */
-/* (at your option) any later version.                                       */
-/*                                                                           */
-/* This program is distributed in the hope that it will be useful,           */
-/* but WITHOUT ANY WARRANTY; without even the implied warranty of            */
-/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the             */
-/* GNU General Public License for more details.                              */
-/*                                                                           */
-/* You should have received a copy of the GNU General Public License         */
-/* along with this program; if not, write to the Free Software               */
-/* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
-/*                                                                           */
-/*                                                                           */
-/* This file contains structures and definitions for IBM RPA (RS/6000        */
-/* platform architecture) implementation of the SRP (SCSI RDMA Protocol)     */
-/* standard.  SRP is used on IBM iSeries and pSeries platforms to send SCSI  */
-/* commands between logical partitions.                                      */
-/*                                                                           */
-/* SRP Information Units (IUs) are sent on a "Command/Response Queue" (CRQ)  */
-/* between partitions.  The definitions in this file are architected,        */
-/* and cannot be changed without breaking compatibility with other versions  */
-/* of Linux and other operating systems (AIX, OS/400) that talk this protocol*/
-/* between logical partitions                                                */
-/*****************************************************************************/
-#ifndef VIOSRP_H
-#define VIOSRP_H
-#include <scsi/srp.h>
-
-#define SRP_VERSION "16.a"
-#define SRP_MAX_IU_LEN	256
-#define SRP_MAX_LOC_LEN 32
-
-union srp_iu {
-	struct srp_login_req login_req;
-	struct srp_login_rsp login_rsp;
-	struct srp_login_rej login_rej;
-	struct srp_i_logout i_logout;
-	struct srp_t_logout t_logout;
-	struct srp_tsk_mgmt tsk_mgmt;
-	struct srp_cmd cmd;
-	struct srp_rsp rsp;
-	u8 reserved[SRP_MAX_IU_LEN];
-};
-
-enum viosrp_crq_formats {
-	VIOSRP_SRP_FORMAT = 0x01,
-	VIOSRP_MAD_FORMAT = 0x02,
-	VIOSRP_OS400_FORMAT = 0x03,
-	VIOSRP_AIX_FORMAT = 0x04,
-	VIOSRP_LINUX_FORMAT = 0x06,
-	VIOSRP_INLINE_FORMAT = 0x07
-};
-
-enum viosrp_crq_status {
-	VIOSRP_OK = 0x0,
-	VIOSRP_NONRECOVERABLE_ERR = 0x1,
-	VIOSRP_VIOLATES_MAX_XFER = 0x2,
-	VIOSRP_PARTNER_PANIC = 0x3,
-	VIOSRP_DEVICE_BUSY = 0x8,
-	VIOSRP_ADAPTER_FAIL = 0x10,
-	VIOSRP_OK2 = 0x99,
-};
-
-struct viosrp_crq {
-	u8 valid;		/* used by RPA */
-	u8 format;		/* SCSI vs out-of-band */
-	u8 reserved;
-	u8 status;		/* non-scsi failure? (e.g. DMA failure) */
-	__be16 timeout;		/* in seconds */
-	__be16 IU_length;		/* in bytes */
-	__be64 IU_data_ptr;	/* the TCE for transferring data */
-};
-
-/* MADs are Management requests above and beyond the IUs defined in the SRP
- * standard.  
- */
-enum viosrp_mad_types {
-	VIOSRP_EMPTY_IU_TYPE = 0x01,
-	VIOSRP_ERROR_LOG_TYPE = 0x02,
-	VIOSRP_ADAPTER_INFO_TYPE = 0x03,
-	VIOSRP_HOST_CONFIG_TYPE = 0x04,
-	VIOSRP_CAPABILITIES_TYPE = 0x05,
-	VIOSRP_ENABLE_FAST_FAIL = 0x08,
-};
-
-enum viosrp_mad_status {
-	VIOSRP_MAD_SUCCESS = 0x00,
-	VIOSRP_MAD_NOT_SUPPORTED = 0xF1,
-	VIOSRP_MAD_FAILED = 0xF7,
-};
-
-enum viosrp_capability_type {
-	MIGRATION_CAPABILITIES = 0x01,
-	RESERVATION_CAPABILITIES = 0x02,
-};
-
-enum viosrp_capability_support {
-	SERVER_DOES_NOT_SUPPORTS_CAP = 0x0,
-	SERVER_SUPPORTS_CAP = 0x01,
-	SERVER_CAP_DATA = 0x02,
-};
-
-enum viosrp_reserve_type {
-	CLIENT_RESERVE_SCSI_2 = 0x01,
-};
-
-enum viosrp_capability_flag {
-	CLIENT_MIGRATED = 0x01,
-	CLIENT_RECONNECT = 0x02,
-	CAP_LIST_SUPPORTED = 0x04,
-	CAP_LIST_DATA = 0x08,
-};
-
-/* 
- * Common MAD header
- */
-struct mad_common {
-	__be32 type;
-	__be16 status;
-	__be16 length;
-	__be64 tag;
-};
-
-/*
- * All SRP (and MAD) requests normally flow from the
- * client to the server.  There is no way for the server to send
- * an asynchronous message back to the client.  The Empty IU is used
- * to hang out a meaningless request to the server so that it can respond
- * asynchrouously with something like a SCSI AER 
- */
-struct viosrp_empty_iu {
-	struct mad_common common;
-	__be64 buffer;
-	__be32 port;
-};
-
-struct viosrp_error_log {
-	struct mad_common common;
-	__be64 buffer;
-};
-
-struct viosrp_adapter_info {
-	struct mad_common common;
-	__be64 buffer;
-};
-
-struct viosrp_host_config {
-	struct mad_common common;
-	__be64 buffer;
-};
-
-struct viosrp_fast_fail {
-	struct mad_common common;
-};
-
-struct viosrp_capabilities {
-	struct mad_common common;
-	__be64 buffer;
-};
-
-struct mad_capability_common {
-	__be32 cap_type;
-	__be16 length;
-	__be16 server_support;
-};
-
-struct mad_reserve_cap {
-	struct mad_capability_common common;
-	__be32 type;
-};
-
-struct mad_migration_cap {
-	struct mad_capability_common common;
-	__be32 ecl;
-};
-
-struct capabilities{
-	__be32 flags;
-	char name[SRP_MAX_LOC_LEN];
-	char loc[SRP_MAX_LOC_LEN];
-	struct mad_migration_cap migration;
-	struct mad_reserve_cap reserve;
-};
-
-union mad_iu {
-	struct viosrp_empty_iu empty_iu;
-	struct viosrp_error_log error_log;
-	struct viosrp_adapter_info adapter_info;
-	struct viosrp_host_config host_config;
-	struct viosrp_fast_fail fast_fail;
-	struct viosrp_capabilities capabilities;
-};
-
-union viosrp_iu {
-	union srp_iu srp;
-	union mad_iu mad;
-};
-
-struct mad_adapter_info_data {
-	char srp_version[8];
-	char partition_name[96];
-	__be32 partition_number;
-	__be32 mad_version;
-	__be32 os_type;
-	__be32 port_max_txu[8];	/* per-port maximum transfer */
-};
-
-#endif
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/scsi/ibmvscsi_tgt/Makefile
@@ -0,0 +1,3 @@
+obj-$(CONFIG_SCSI_IBMVSCSIS)	+= ibmvscsis.o
+
+ibmvscsis-y := libsrp.o ibmvscsi_tgt.o
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c
@@ -0,0 +1,4067 @@
+/*******************************************************************************
+ * IBM Virtual SCSI Target Driver
+ * Copyright (C) 2003-2005 Dave Boutcher (boutcher@us.ibm.com) IBM Corp.
+ *			   Santiago Leon (santil@us.ibm.com) IBM Corp.
+ *			   Linda Xie (lxie@us.ibm.com) IBM Corp.
+ *
+ * Copyright (C) 2005-2011 FUJITA Tomonori <tomof@acm.org>
+ * Copyright (C) 2010 Nicholas A. Bellinger <nab@kernel.org>
+ *
+ * Authors: Bryant G. Ly <bryantly@linux.vnet.ibm.com>
+ * Authors: Michael Cyr <mikecyr@linux.vnet.ibm.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ ****************************************************************************/
+
+#define pr_fmt(fmt)     KBUILD_MODNAME ": " fmt
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+#include <linux/list.h>
+#include <linux/string.h>
+
+#include <target/target_core_base.h>
+#include <target/target_core_fabric.h>
+
+#include <asm/hvcall.h>
+#include <asm/vio.h>
+
+#include <scsi/viosrp.h>
+
+#include "ibmvscsi_tgt.h"
+
+#define IBMVSCSIS_VERSION	"v0.2"
+
+#define	INITIAL_SRP_LIMIT	800
+#define	DEFAULT_MAX_SECTORS	256
+
+static uint max_vdma_size = MAX_H_COPY_RDMA;
+
+static char system_id[SYS_ID_NAME_LEN] = "";
+static char partition_name[PARTITION_NAMELEN] = "UNKNOWN";
+static uint partition_number = -1;
+
+/* Adapter list and lock to control it */
+static DEFINE_SPINLOCK(ibmvscsis_dev_lock);
+static LIST_HEAD(ibmvscsis_dev_list);
+
+static long ibmvscsis_parse_command(struct scsi_info *vscsi,
+				    struct viosrp_crq *crq);
+
+static void ibmvscsis_adapter_idle(struct scsi_info *vscsi);
+
+static void ibmvscsis_determine_resid(struct se_cmd *se_cmd,
+				      struct srp_rsp *rsp)
+{
+	u32 residual_count = se_cmd->residual_count;
+
+	if (!residual_count)
+		return;
+
+	if (se_cmd->se_cmd_flags & SCF_UNDERFLOW_BIT) {
+		if (se_cmd->data_direction == DMA_TO_DEVICE) {
+			/* residual data from an underflow write */
+			rsp->flags = SRP_RSP_FLAG_DOUNDER;
+			rsp->data_out_res_cnt = cpu_to_be32(residual_count);
+		} else if (se_cmd->data_direction == DMA_FROM_DEVICE) {
+			/* residual data from an underflow read */
+			rsp->flags = SRP_RSP_FLAG_DIUNDER;
+			rsp->data_in_res_cnt = cpu_to_be32(residual_count);
+		}
+	} else if (se_cmd->se_cmd_flags & SCF_OVERFLOW_BIT) {
+		if (se_cmd->data_direction == DMA_TO_DEVICE) {
+			/*  residual data from an overflow write */
+			rsp->flags = SRP_RSP_FLAG_DOOVER;
+			rsp->data_out_res_cnt = cpu_to_be32(residual_count);
+		} else if (se_cmd->data_direction == DMA_FROM_DEVICE) {
+			/* residual data from an overflow read */
+			rsp->flags = SRP_RSP_FLAG_DIOVER;
+			rsp->data_in_res_cnt = cpu_to_be32(residual_count);
+		}
+	}
+}
+
+/**
+ * connection_broken() - Determine if the connection to the client is good
+ * @vscsi:	Pointer to our adapter structure
+ *
+ * This function attempts to send a ping MAD to the client. If the call to
+ * queue the request returns H_CLOSED then the connection has been broken
+ * and the function returns TRUE.
+ *
+ * EXECUTION ENVIRONMENT:
+ *      Interrupt or Process environment
+ */
+static bool connection_broken(struct scsi_info *vscsi)
+{
+	struct viosrp_crq *crq;
+	u64 buffer[2] = { 0, 0 };
+	long h_return_code;
+	bool rc = false;
+
+	/* create a PING crq */
+	crq = (struct viosrp_crq *)&buffer;
+	crq->valid = VALID_CMD_RESP_EL;
+	crq->format = MESSAGE_IN_CRQ;
+	crq->status = PING;
+
+	h_return_code = h_send_crq(vscsi->dds.unit_id,
+				   cpu_to_be64(buffer[MSG_HI]),
+				   cpu_to_be64(buffer[MSG_LOW]));
+
+	pr_debug("connection_broken: rc %ld\n", h_return_code);
+
+	if (h_return_code == H_CLOSED)
+		rc = true;
+
+	return rc;
+}
+
+/**
+ * ibmvscsis_unregister_command_q() - Helper Function-Unregister Command Queue
+ * @vscsi:	Pointer to our adapter structure
+ *
+ * This function calls h_free_q then frees the interrupt bit etc.
+ * It must release the lock before doing so because of the time it can take
+ * for h_free_crq in PHYP
+ * NOTE: the caller must make sure that state and or flags will prevent
+ *	 interrupt handler from scheduling work.
+ * NOTE: anyone calling this function may need to set the CRQ_CLOSED flag
+ *	 we can't do it here, because we don't have the lock
+ *
+ * EXECUTION ENVIRONMENT:
+ *	Process level
+ */
+static long ibmvscsis_unregister_command_q(struct scsi_info *vscsi)
+{
+	long qrc;
+	long rc = ADAPT_SUCCESS;
+	int ticks = 0;
+
+	do {
+		qrc = h_free_crq(vscsi->dds.unit_id);
+		switch (qrc) {
+		case H_SUCCESS:
+			break;
+
+		case H_HARDWARE:
+		case H_PARAMETER:
+			dev_err(&vscsi->dev, "unregister_command_q: error from h_free_crq %ld\n",
+				qrc);
+			rc = ERROR;
+			break;
+
+		case H_BUSY:
+		case H_LONG_BUSY_ORDER_1_MSEC:
+			/* msleep not good for small values */
+			usleep_range(1000, 2000);
+			ticks += 1;
+			break;
+		case H_LONG_BUSY_ORDER_10_MSEC:
+			usleep_range(10000, 20000);
+			ticks += 10;
+			break;
+		case H_LONG_BUSY_ORDER_100_MSEC:
+			msleep(100);
+			ticks += 100;
+			break;
+		case H_LONG_BUSY_ORDER_1_SEC:
+			ssleep(1);
+			ticks += 1000;
+			break;
+		case H_LONG_BUSY_ORDER_10_SEC:
+			ssleep(10);
+			ticks += 10000;
+			break;
+		case H_LONG_BUSY_ORDER_100_SEC:
+			ssleep(100);
+			ticks += 100000;
+			break;
+		default:
+			dev_err(&vscsi->dev, "unregister_command_q: unknown error %ld from h_free_crq\n",
+				qrc);
+			rc = ERROR;
+			break;
+		}
+
+		/*
+		 * dont wait more then 300 seconds
+		 * ticks are in milliseconds more or less
+		 */
+		if (ticks > 300000 && qrc != H_SUCCESS) {
+			rc = ERROR;
+			dev_err(&vscsi->dev, "Excessive wait for h_free_crq\n");
+		}
+	} while (qrc != H_SUCCESS && rc == ADAPT_SUCCESS);
+
+	pr_debug("Freeing CRQ: phyp rc %ld, rc %ld\n", qrc, rc);
+
+	return rc;
+}
+
+/**
+ * ibmvscsis_delete_client_info() - Helper function to Delete Client Info
+ * @vscsi:	Pointer to our adapter structure
+ * @client_closed:	True if client closed its queue
+ *
+ * Deletes information specific to the client when the client goes away
+ *
+ * EXECUTION ENVIRONMENT:
+ *	Interrupt or Process
+ */
+static void ibmvscsis_delete_client_info(struct scsi_info *vscsi,
+					 bool client_closed)
+{
+	vscsi->client_cap = 0;
+
+	/*
+	 * Some things we don't want to clear if we're closing the queue,
+	 * because some clients don't resend the host handshake when they
+	 * get a transport event.
+	 */
+	if (client_closed)
+		vscsi->client_data.os_type = 0;
+}
+
+/**
+ * ibmvscsis_free_command_q() - Free Command Queue
+ * @vscsi:	Pointer to our adapter structure
+ *
+ * This function calls unregister_command_q, then clears interrupts and
+ * any pending interrupt acknowledgments associated with the command q.
+ * It also clears memory if there is no error.
+ *
+ * PHYP did not meet the PAPR architecture so that we must give up the
+ * lock. This causes a timing hole regarding state change.  To close the
+ * hole this routine does accounting on any change that occurred during
+ * the time the lock is not held.
+ * NOTE: must give up and then acquire the interrupt lock, the caller must
+ *	 make sure that state and or flags will prevent interrupt handler from
+ *	 scheduling work.
+ *
+ * EXECUTION ENVIRONMENT:
+ *	Process level, interrupt lock is held
+ */
+static long ibmvscsis_free_command_q(struct scsi_info *vscsi)
+{
+	int bytes;
+	u32 flags_under_lock;
+	u16 state_under_lock;
+	long rc = ADAPT_SUCCESS;
+
+	if (!(vscsi->flags & CRQ_CLOSED)) {
+		vio_disable_interrupts(vscsi->dma_dev);
+
+		state_under_lock = vscsi->new_state;
+		flags_under_lock = vscsi->flags;
+		vscsi->phyp_acr_state = 0;
+		vscsi->phyp_acr_flags = 0;
+
+		spin_unlock_bh(&vscsi->intr_lock);
+		rc = ibmvscsis_unregister_command_q(vscsi);
+		spin_lock_bh(&vscsi->intr_lock);
+
+		if (state_under_lock != vscsi->new_state)
+			vscsi->phyp_acr_state = vscsi->new_state;
+
+		vscsi->phyp_acr_flags = ((~flags_under_lock) & vscsi->flags);
+
+		if (rc == ADAPT_SUCCESS) {
+			bytes = vscsi->cmd_q.size * PAGE_SIZE;
+			memset(vscsi->cmd_q.base_addr, 0, bytes);
+			vscsi->cmd_q.index = 0;
+			vscsi->flags |= CRQ_CLOSED;
+
+			ibmvscsis_delete_client_info(vscsi, false);
+		}
+
+		pr_debug("free_command_q: flags 0x%x, state 0x%hx, acr_flags 0x%x, acr_state 0x%hx\n",
+			 vscsi->flags, vscsi->state, vscsi->phyp_acr_flags,
+			 vscsi->phyp_acr_state);
+	}
+	return rc;
+}
+
+/**
+ * ibmvscsis_cmd_q_dequeue() - Get valid Command element
+ * @mask:	Mask to use in case index wraps
+ * @current_index:	Current index into command queue
+ * @base_addr:	Pointer to start of command queue
+ *
+ * Returns a pointer to a valid command element or NULL, if the command
+ * queue is empty
+ *
+ * EXECUTION ENVIRONMENT:
+ *	Interrupt environment, interrupt lock held
+ */
+static struct viosrp_crq *ibmvscsis_cmd_q_dequeue(uint mask,
+						  uint *current_index,
+						  struct viosrp_crq *base_addr)
+{
+	struct viosrp_crq *ptr;
+
+	ptr = base_addr + *current_index;
+
+	if (ptr->valid) {
+		*current_index = (*current_index + 1) & mask;
+		dma_rmb();
+	} else {
+		ptr = NULL;
+	}
+
+	return ptr;
+}
+
+/**
+ * ibmvscsis_send_init_message() -  send initialize message to the client
+ * @vscsi:	Pointer to our adapter structure
+ * @format:	Which Init Message format to send
+ *
+ * EXECUTION ENVIRONMENT:
+ *	Interrupt environment interrupt lock held
+ */
+static long ibmvscsis_send_init_message(struct scsi_info *vscsi, u8 format)
+{
+	struct viosrp_crq *crq;
+	u64 buffer[2] = { 0, 0 };
+	long rc;
+
+	crq = (struct viosrp_crq *)&buffer;
+	crq->valid = VALID_INIT_MSG;
+	crq->format = format;
+	rc = h_send_crq(vscsi->dds.unit_id, cpu_to_be64(buffer[MSG_HI]),
+			cpu_to_be64(buffer[MSG_LOW]));
+
+	return rc;
+}
+
+/**
+ * ibmvscsis_check_init_msg() - Check init message valid
+ * @vscsi:	Pointer to our adapter structure
+ * @format:	Pointer to return format of Init Message, if any.
+ *		Set to UNUSED_FORMAT if no Init Message in queue.
+ *
+ * Checks if an initialize message was queued by the initiatior
+ * after the queue was created and before the interrupt was enabled.
+ *
+ * EXECUTION ENVIRONMENT:
+ *	Process level only, interrupt lock held
+ */
+static long ibmvscsis_check_init_msg(struct scsi_info *vscsi, uint *format)
+{
+	struct viosrp_crq *crq;
+	long rc = ADAPT_SUCCESS;
+
+	crq = ibmvscsis_cmd_q_dequeue(vscsi->cmd_q.mask, &vscsi->cmd_q.index,
+				      vscsi->cmd_q.base_addr);
+	if (!crq) {
+		*format = (uint)UNUSED_FORMAT;
+	} else if (crq->valid == VALID_INIT_MSG && crq->format == INIT_MSG) {
+		*format = (uint)INIT_MSG;
+		crq->valid = INVALIDATE_CMD_RESP_EL;
+		dma_rmb();
+
+		/*
+		 * the caller has ensured no initialize message was
+		 * sent after the queue was
+		 * created so there should be no other message on the queue.
+		 */
+		crq = ibmvscsis_cmd_q_dequeue(vscsi->cmd_q.mask,
+					      &vscsi->cmd_q.index,
+					      vscsi->cmd_q.base_addr);
+		if (crq) {
+			*format = (uint)(crq->format);
+			rc =  ERROR;
+			crq->valid = INVALIDATE_CMD_RESP_EL;
+			dma_rmb();
+		}
+	} else {
+		*format = (uint)(crq->format);
+		rc =  ERROR;
+		crq->valid = INVALIDATE_CMD_RESP_EL;
+		dma_rmb();
+	}
+
+	return rc;
+}
+
+/**
+ * ibmvscsis_establish_new_q() - Establish new CRQ queue
+ * @vscsi:	Pointer to our adapter structure
+ * @new_state:	New state being established after resetting the queue
+ *
+ * Must be called with interrupt lock held.
+ */
+static long ibmvscsis_establish_new_q(struct scsi_info *vscsi,  uint new_state)
+{
+	long rc = ADAPT_SUCCESS;
+	uint format;
+
+	vscsi->flags &= PRESERVE_FLAG_FIELDS;
+	vscsi->rsp_q_timer.timer_pops = 0;
+	vscsi->debit = 0;
+	vscsi->credit = 0;
+
+	rc = vio_enable_interrupts(vscsi->dma_dev);
+	if (rc) {
+		pr_warn("reset_queue: failed to enable interrupts, rc %ld\n",
+			rc);
+		return rc;
+	}
+
+	rc = ibmvscsis_check_init_msg(vscsi, &format);
+	if (rc) {
+		dev_err(&vscsi->dev, "reset_queue: check_init_msg failed, rc %ld\n",
+			rc);
+		return rc;
+	}
+
+	if (format == UNUSED_FORMAT && new_state == WAIT_CONNECTION) {
+		rc = ibmvscsis_send_init_message(vscsi, INIT_MSG);
+		switch (rc) {
+		case H_SUCCESS:
+		case H_DROPPED:
+		case H_CLOSED:
+			rc = ADAPT_SUCCESS;
+			break;
+
+		case H_PARAMETER:
+		case H_HARDWARE:
+			break;
+
+		default:
+			vscsi->state = UNDEFINED;
+			rc = H_HARDWARE;
+			break;
+		}
+	}
+
+	return rc;
+}
+
+/**
+ * ibmvscsis_reset_queue() - Reset CRQ Queue
+ * @vscsi:	Pointer to our adapter structure
+ * @new_state:	New state to establish after resetting the queue
+ *
+ * This function calls h_free_q and then calls h_reg_q and does all
+ * of the bookkeeping to get us back to where we can communicate.
+ *
+ * Actually, we don't always call h_free_crq.  A problem was discovered
+ * where one partition would close and reopen his queue, which would
+ * cause his partner to get a transport event, which would cause him to
+ * close and reopen his queue, which would cause the original partition
+ * to get a transport event, etc., etc.  To prevent this, we don't
+ * actually close our queue if the client initiated the reset, (i.e.
+ * either we got a transport event or we have detected that the client's
+ * queue is gone)
+ *
+ * EXECUTION ENVIRONMENT:
+ *	Process environment, called with interrupt lock held
+ */
+static void ibmvscsis_reset_queue(struct scsi_info *vscsi, uint new_state)
+{
+	int bytes;
+	long rc = ADAPT_SUCCESS;
+
+	pr_debug("reset_queue: flags 0x%x\n", vscsi->flags);
+
+	/* don't reset, the client did it for us */
+	if (vscsi->flags & (CLIENT_FAILED | TRANS_EVENT)) {
+		vscsi->flags &=  PRESERVE_FLAG_FIELDS;
+		vscsi->rsp_q_timer.timer_pops = 0;
+		vscsi->debit = 0;
+		vscsi->credit = 0;
+		vscsi->state = new_state;
+		vio_enable_interrupts(vscsi->dma_dev);
+	} else {
+		rc = ibmvscsis_free_command_q(vscsi);
+		if (rc == ADAPT_SUCCESS) {
+			vscsi->state = new_state;
+
+			bytes = vscsi->cmd_q.size * PAGE_SIZE;
+			rc = h_reg_crq(vscsi->dds.unit_id,
+				       vscsi->cmd_q.crq_token, bytes);
+			if (rc == H_CLOSED || rc == H_SUCCESS) {
+				rc = ibmvscsis_establish_new_q(vscsi,
+							       new_state);
+			}
+
+			if (rc != ADAPT_SUCCESS) {
+				pr_debug("reset_queue: reg_crq rc %ld\n", rc);
+
+				vscsi->state = ERR_DISCONNECTED;
+				vscsi->flags |=  RESPONSE_Q_DOWN;
+				ibmvscsis_free_command_q(vscsi);
+			}
+		} else {
+			vscsi->state = ERR_DISCONNECTED;
+			vscsi->flags |= RESPONSE_Q_DOWN;
+		}
+	}
+}
+
+/**
+ * ibmvscsis_free_cmd_resources() - Free command resources
+ * @vscsi:	Pointer to our adapter structure
+ * @cmd:	Command which is not longer in use
+ *
+ * Must be called with interrupt lock held.
+ */
+static void ibmvscsis_free_cmd_resources(struct scsi_info *vscsi,
+					 struct ibmvscsis_cmd *cmd)
+{
+	struct iu_entry *iue = cmd->iue;
+
+	switch (cmd->type) {
+	case TASK_MANAGEMENT:
+	case SCSI_CDB:
+		/*
+		 * When the queue goes down this value is cleared, so it
+		 * cannot be cleared in this general purpose function.
+		 */
+		if (vscsi->debit)
+			vscsi->debit -= 1;
+		break;
+	case ADAPTER_MAD:
+		vscsi->flags &= ~PROCESSING_MAD;
+		break;
+	case UNSET_TYPE:
+		break;
+	default:
+		dev_err(&vscsi->dev, "free_cmd_resources unknown type %d\n",
+			cmd->type);
+		break;
+	}
+
+	cmd->iue = NULL;
+	list_add_tail(&cmd->list, &vscsi->free_cmd);
+	srp_iu_put(iue);
+
+	if (list_empty(&vscsi->active_q) && list_empty(&vscsi->schedule_q) &&
+	    list_empty(&vscsi->waiting_rsp) && (vscsi->flags & WAIT_FOR_IDLE)) {
+		vscsi->flags &= ~WAIT_FOR_IDLE;
+		complete(&vscsi->wait_idle);
+	}
+}
+
+/**
+ * ibmvscsis_disconnect() - Helper function to disconnect
+ * @work:	Pointer to work_struct, gives access to our adapter structure
+ *
+ * An error has occurred or the driver received a Transport event,
+ * and the driver is requesting that the command queue be de-registered
+ * in a safe manner. If there is no outstanding I/O then we can stop the
+ * queue. If we are restarting the queue it will be reflected in the
+ * the state of the adapter.
+ *
+ * EXECUTION ENVIRONMENT:
+ *	Process environment
+ */
+static void ibmvscsis_disconnect(struct work_struct *work)
+{
+	struct scsi_info *vscsi = container_of(work, struct scsi_info,
+					       proc_work);
+	u16 new_state;
+	bool wait_idle = false;
+	long rc = ADAPT_SUCCESS;
+
+	spin_lock_bh(&vscsi->intr_lock);
+	new_state = vscsi->new_state;
+	vscsi->new_state = 0;
+
+	pr_debug("disconnect: flags 0x%x, state 0x%hx\n", vscsi->flags,
+		 vscsi->state);
+
+	/*
+	 * check which state we are in and see if we
+	 * should transitition to the new state
+	 */
+	switch (vscsi->state) {
+	/*  Should never be called while in this state. */
+	case NO_QUEUE:
+	/*
+	 * Can never transition from this state;
+	 * igonore errors and logout.
+	 */
+	case UNCONFIGURING:
+		break;
+
+	/* can transition from this state to UNCONFIGURING */
+	case ERR_DISCONNECT:
+		if (new_state == UNCONFIGURING)
+			vscsi->state = new_state;
+		break;
+
+	/*
+	 * Can transition from this state to to unconfiguring
+	 * or err disconnect.
+	 */
+	case ERR_DISCONNECT_RECONNECT:
+		switch (new_state) {
+		case UNCONFIGURING:
+		case ERR_DISCONNECT:
+			vscsi->state = new_state;
+			break;
+
+		case WAIT_IDLE:
+			break;
+		default:
+			break;
+		}
+		break;
+
+	/* can transition from this state to UNCONFIGURING */
+	case ERR_DISCONNECTED:
+		if (new_state == UNCONFIGURING)
+			vscsi->state = new_state;
+		break;
+
+	/*
+	 * If this is a transition into an error state.
+	 * a client is attempting to establish a connection
+	 * and has violated the RPA protocol.
+	 * There can be nothing pending on the adapter although
+	 * there can be requests in the command queue.
+	 */
+	case WAIT_ENABLED:
+	case PART_UP_WAIT_ENAB:
+		switch (new_state) {
+		case ERR_DISCONNECT:
+			vscsi->flags |= RESPONSE_Q_DOWN;
+			vscsi->state = new_state;
+			vscsi->flags &= ~(SCHEDULE_DISCONNECT |
+					  DISCONNECT_SCHEDULED);
+			ibmvscsis_free_command_q(vscsi);
+			break;
+		case ERR_DISCONNECT_RECONNECT:
+			ibmvscsis_reset_queue(vscsi, WAIT_ENABLED);
+			break;
+
+		/* should never happen */
+		case WAIT_IDLE:
+			rc = ERROR;
+			dev_err(&vscsi->dev, "disconnect: invalid state %d for WAIT_IDLE\n",
+				vscsi->state);
+			break;
+		}
+		break;
+
+	case WAIT_IDLE:
+		switch (new_state) {
+		case ERR_DISCONNECT:
+		case ERR_DISCONNECT_RECONNECT:
+			vscsi->state = new_state;
+			break;
+		}
+		break;
+
+	/*
+	 * Initiator has not done a successful srp login
+	 * or has done a successful srp logout ( adapter was not
+	 * busy). In the first case there can be responses queued
+	 * waiting for space on the initiators response queue (MAD)
+	 * The second case the adapter is idle. Assume the worse case,
+	 * i.e. the second case.
+	 */
+	case WAIT_CONNECTION:
+	case CONNECTED:
+	case SRP_PROCESSING:
+		wait_idle = true;
+		vscsi->state = new_state;
+		break;
+
+	/* can transition from this state to UNCONFIGURING */
+	case UNDEFINED:
+		if (new_state == UNCONFIGURING)
+			vscsi->state = new_state;
+		break;
+	default:
+		break;
+	}
+
+	if (wait_idle) {
+		pr_debug("disconnect start wait, active %d, sched %d\n",
+			 (int)list_empty(&vscsi->active_q),
+			 (int)list_empty(&vscsi->schedule_q));
+		if (!list_empty(&vscsi->active_q) ||
+		    !list_empty(&vscsi->schedule_q)) {
+			vscsi->flags |= WAIT_FOR_IDLE;
+			pr_debug("disconnect flags 0x%x\n", vscsi->flags);
+			/*
+			 * This routine is can not be called with the interrupt
+			 * lock held.
+			 */
+			spin_unlock_bh(&vscsi->intr_lock);
+			wait_for_completion(&vscsi->wait_idle);
+			spin_lock_bh(&vscsi->intr_lock);
+		}
+		pr_debug("disconnect stop wait\n");
+
+		ibmvscsis_adapter_idle(vscsi);
+	}
+
+	spin_unlock_bh(&vscsi->intr_lock);
+}
+
+/**
+ * ibmvscsis_post_disconnect() - Schedule the disconnect
+ * @vscsi:	Pointer to our adapter structure
+ * @new_state:	State to move to after disconnecting
+ * @flag_bits:	Flags to turn on in adapter structure
+ *
+ * If it's already been scheduled, then see if we need to "upgrade"
+ * the new state (if the one passed in is more "severe" than the
+ * previous one).
+ *
+ * PRECONDITION:
+ *	interrupt lock is held
+ */
+static void ibmvscsis_post_disconnect(struct scsi_info *vscsi, uint new_state,
+				      uint flag_bits)
+{
+	uint state;
+
+	/* check the validity of the new state */
+	switch (new_state) {
+	case UNCONFIGURING:
+	case ERR_DISCONNECT:
+	case ERR_DISCONNECT_RECONNECT:
+	case WAIT_IDLE:
+		break;
+
+	default:
+		dev_err(&vscsi->dev, "post_disconnect: Invalid new state %d\n",
+			new_state);
+		return;
+	}
+
+	vscsi->flags |= flag_bits;
+
+	pr_debug("post_disconnect: new_state 0x%x, flag_bits 0x%x, vscsi->flags 0x%x, state %hx\n",
+		 new_state, flag_bits, vscsi->flags, vscsi->state);
+
+	if (!(vscsi->flags & (DISCONNECT_SCHEDULED | SCHEDULE_DISCONNECT))) {
+		vscsi->flags |= SCHEDULE_DISCONNECT;
+		vscsi->new_state = new_state;
+
+		INIT_WORK(&vscsi->proc_work, ibmvscsis_disconnect);
+		(void)queue_work(vscsi->work_q, &vscsi->proc_work);
+	} else {
+		if (vscsi->new_state)
+			state = vscsi->new_state;
+		else
+			state = vscsi->state;
+
+		switch (state) {
+		case NO_QUEUE:
+		case UNCONFIGURING:
+			break;
+
+		case ERR_DISCONNECTED:
+		case ERR_DISCONNECT:
+		case UNDEFINED:
+			if (new_state == UNCONFIGURING)
+				vscsi->new_state = new_state;
+			break;
+
+		case ERR_DISCONNECT_RECONNECT:
+			switch (new_state) {
+			case UNCONFIGURING:
+			case ERR_DISCONNECT:
+				vscsi->new_state = new_state;
+				break;
+			default:
+				break;
+			}
+			break;
+
+		case WAIT_ENABLED:
+		case PART_UP_WAIT_ENAB:
+		case WAIT_IDLE:
+		case WAIT_CONNECTION:
+		case CONNECTED:
+		case SRP_PROCESSING:
+			vscsi->new_state = new_state;
+			break;
+
+		default:
+			break;
+		}
+	}
+
+	pr_debug("Leaving post_disconnect: flags 0x%x, new_state 0x%x\n",
+		 vscsi->flags, vscsi->new_state);
+}
+
+/**
+ * ibmvscsis_trans_event() - Handle a Transport Event
+ * @vscsi:	Pointer to our adapter structure
+ * @crq:	Pointer to CRQ entry containing the Transport Event
+ *
+ * Do the logic to close the I_T nexus.  This function may not
+ * behave to specification.
+ *
+ * EXECUTION ENVIRONMENT:
+ *	Interrupt, interrupt lock held
+ */
+static long ibmvscsis_trans_event(struct scsi_info *vscsi,
+				  struct viosrp_crq *crq)
+{
+	long rc = ADAPT_SUCCESS;
+
+	pr_debug("trans_event: format %d, flags 0x%x, state 0x%hx\n",
+		 (int)crq->format, vscsi->flags, vscsi->state);
+
+	switch (crq->format) {
+	case MIGRATED:
+	case PARTNER_FAILED:
+	case PARTNER_DEREGISTER:
+		ibmvscsis_delete_client_info(vscsi, true);
+		break;
+
+	default:
+		rc = ERROR;
+		dev_err(&vscsi->dev, "trans_event: invalid format %d\n",
+			(uint)crq->format);
+		ibmvscsis_post_disconnect(vscsi, ERR_DISCONNECT,
+					  RESPONSE_Q_DOWN);
+		break;
+	}
+
+	if (rc == ADAPT_SUCCESS) {
+		switch (vscsi->state) {
+		case NO_QUEUE:
+		case ERR_DISCONNECTED:
+		case UNDEFINED:
+			break;
+
+		case UNCONFIGURING:
+			vscsi->flags |= (RESPONSE_Q_DOWN | TRANS_EVENT);
+			break;
+
+		case WAIT_ENABLED:
+			break;
+
+		case WAIT_CONNECTION:
+			break;
+
+		case CONNECTED:
+			ibmvscsis_post_disconnect(vscsi, WAIT_IDLE,
+						  (RESPONSE_Q_DOWN |
+						   TRANS_EVENT));
+			break;
+
+		case PART_UP_WAIT_ENAB:
+			vscsi->state = WAIT_ENABLED;
+			break;
+
+		case SRP_PROCESSING:
+			if ((vscsi->debit > 0) ||
+			    !list_empty(&vscsi->schedule_q) ||
+			    !list_empty(&vscsi->waiting_rsp) ||
+			    !list_empty(&vscsi->active_q)) {
+				pr_debug("debit %d, sched %d, wait %d, active %d\n",
+					 vscsi->debit,
+					 (int)list_empty(&vscsi->schedule_q),
+					 (int)list_empty(&vscsi->waiting_rsp),
+					 (int)list_empty(&vscsi->active_q));
+				pr_warn("connection lost with outstanding work\n");
+			} else {
+				pr_debug("trans_event: SRP Processing, but no outstanding work\n");
+			}
+
+			ibmvscsis_post_disconnect(vscsi, WAIT_IDLE,
+						  (RESPONSE_Q_DOWN |
+						   TRANS_EVENT));
+			break;
+
+		case ERR_DISCONNECT:
+		case ERR_DISCONNECT_RECONNECT:
+		case WAIT_IDLE:
+			vscsi->flags |= (RESPONSE_Q_DOWN | TRANS_EVENT);
+			break;
+		}
+	}
+
+	rc =  vscsi->flags & SCHEDULE_DISCONNECT;
+
+	pr_debug("Leaving trans_event: flags 0x%x, state 0x%hx, rc %ld\n",
+		 vscsi->flags, vscsi->state, rc);
+
+	return rc;
+}
+
+/**
+ * ibmvscsis_poll_cmd_q() - Poll Command Queue
+ * @vscsi:	Pointer to our adapter structure
+ *
+ * Called to handle command elements that may have arrived while
+ * interrupts were disabled.
+ *
+ * EXECUTION ENVIRONMENT:
+ *	intr_lock must be held
+ */
+static void ibmvscsis_poll_cmd_q(struct scsi_info *vscsi)
+{
+	struct viosrp_crq *crq;
+	long rc;
+	bool ack = true;
+	volatile u8 valid;
+
+	pr_debug("poll_cmd_q: flags 0x%x, state 0x%hx, q index %ud\n",
+		 vscsi->flags, vscsi->state, vscsi->cmd_q.index);
+
+	rc = vscsi->flags & SCHEDULE_DISCONNECT;
+	crq = vscsi->cmd_q.base_addr + vscsi->cmd_q.index;
+	valid = crq->valid;
+	dma_rmb();
+
+	while (valid) {
+poll_work:
+		vscsi->cmd_q.index =
+			(vscsi->cmd_q.index + 1) & vscsi->cmd_q.mask;
+
+		if (!rc) {
+			rc = ibmvscsis_parse_command(vscsi, crq);
+		} else {
+			if ((uint)crq->valid == VALID_TRANS_EVENT) {
+				/*
+				 * must service the transport layer events even
+				 * in an error state, dont break out until all
+				 * the consecutive transport events have been
+				 * processed
+				 */
+				rc = ibmvscsis_trans_event(vscsi, crq);
+			} else if (vscsi->flags & TRANS_EVENT) {
+				/*
+				 * if a tranport event has occurred leave
+				 * everything but transport events on the queue
+				 */
+				pr_debug("poll_cmd_q, ignoring\n");
+
+				/*
+				 * need to decrement the queue index so we can
+				 * look at the elment again
+				 */
+				if (vscsi->cmd_q.index)
+					vscsi->cmd_q.index -= 1;
+				else
+					/*
+					 * index is at 0 it just wrapped.
+					 * have it index last element in q
+					 */
+					vscsi->cmd_q.index = vscsi->cmd_q.mask;
+				break;
+			}
+		}
+
+		crq->valid = INVALIDATE_CMD_RESP_EL;
+
+		crq = vscsi->cmd_q.base_addr + vscsi->cmd_q.index;
+		valid = crq->valid;
+		dma_rmb();
+	}
+
+	if (!rc) {
+		if (ack) {
+			vio_enable_interrupts(vscsi->dma_dev);
+			ack = false;
+			pr_debug("poll_cmd_q, reenabling interrupts\n");
+		}
+		valid = crq->valid;
+		dma_rmb();
+		if (valid)
+			goto poll_work;
+	}
+
+	pr_debug("Leaving poll_cmd_q: rc %ld\n", rc);
+}
+
+/**
+ * ibmvscsis_free_cmd_qs() - Free elements in queue
+ * @vscsi:	Pointer to our adapter structure
+ *
+ * Free all of the elements on all queues that are waiting for
+ * whatever reason.
+ *
+ * PRECONDITION:
+ *	Called with interrupt lock held
+ */
+static void ibmvscsis_free_cmd_qs(struct scsi_info *vscsi)
+{
+	struct ibmvscsis_cmd *cmd, *nxt;
+
+	pr_debug("free_cmd_qs: waiting_rsp empty %d, timer starter %d\n",
+		 (int)list_empty(&vscsi->waiting_rsp),
+		 vscsi->rsp_q_timer.started);
+
+	list_for_each_entry_safe(cmd, nxt, &vscsi->waiting_rsp, list) {
+		list_del(&cmd->list);
+		ibmvscsis_free_cmd_resources(vscsi, cmd);
+	}
+}
+
+/**
+ * ibmvscsis_get_free_cmd() - Get free command from list
+ * @vscsi:	Pointer to our adapter structure
+ *
+ * Must be called with interrupt lock held.
+ */
+static struct ibmvscsis_cmd *ibmvscsis_get_free_cmd(struct scsi_info *vscsi)
+{
+	struct ibmvscsis_cmd *cmd = NULL;
+	struct iu_entry *iue;
+
+	iue = srp_iu_get(&vscsi->target);
+	if (iue) {
+		cmd = list_first_entry_or_null(&vscsi->free_cmd,
+					       struct ibmvscsis_cmd, list);
+		if (cmd) {
+			list_del(&cmd->list);
+			cmd->iue = iue;
+			cmd->type = UNSET_TYPE;
+			memset(&cmd->se_cmd, 0, sizeof(cmd->se_cmd));
+		} else {
+			srp_iu_put(iue);
+		}
+	}
+
+	return cmd;
+}
+
+/**
+ * ibmvscsis_adapter_idle() - Helper function to handle idle adapter
+ * @vscsi:	Pointer to our adapter structure
+ *
+ * This function is called when the adapter is idle when the driver
+ * is attempting to clear an error condition.
+ * The adapter is considered busy if any of its cmd queues
+ * are non-empty. This function can be invoked
+ * from the off level disconnect function.
+ *
+ * EXECUTION ENVIRONMENT:
+ *	Process environment called with interrupt lock held
+ */
+static void ibmvscsis_adapter_idle(struct scsi_info *vscsi)
+{
+	int free_qs = false;
+
+	pr_debug("adapter_idle: flags 0x%x, state 0x%hx\n", vscsi->flags,
+		 vscsi->state);
+
+	/* Only need to free qs if we're disconnecting from client */
+	if (vscsi->state != WAIT_CONNECTION || vscsi->flags & TRANS_EVENT)
+		free_qs = true;
+
+	switch (vscsi->state) {
+	case ERR_DISCONNECT_RECONNECT:
+		ibmvscsis_reset_queue(vscsi, WAIT_CONNECTION);
+		pr_debug("adapter_idle, disc_rec: flags 0x%x\n", vscsi->flags);
+		break;
+
+	case ERR_DISCONNECT:
+		ibmvscsis_free_command_q(vscsi);
+		vscsi->flags &= ~DISCONNECT_SCHEDULED;
+		vscsi->flags |= RESPONSE_Q_DOWN;
+		vscsi->state = ERR_DISCONNECTED;
+		pr_debug("adapter_idle, disc: flags 0x%x, state 0x%hx\n",
+			 vscsi->flags, vscsi->state);
+		break;
+
+	case WAIT_IDLE:
+		vscsi->rsp_q_timer.timer_pops = 0;
+		vscsi->debit = 0;
+		vscsi->credit = 0;
+		if (vscsi->flags & TRANS_EVENT) {
+			vscsi->state = WAIT_CONNECTION;
+			vscsi->flags &= PRESERVE_FLAG_FIELDS;
+		} else {
+			vscsi->state = CONNECTED;
+			vscsi->flags &= ~DISCONNECT_SCHEDULED;
+		}
+
+		pr_debug("adapter_idle, wait: flags 0x%x, state 0x%hx\n",
+			 vscsi->flags, vscsi->state);
+		ibmvscsis_poll_cmd_q(vscsi);
+		break;
+
+	case ERR_DISCONNECTED:
+		vscsi->flags &= ~DISCONNECT_SCHEDULED;
+		pr_debug("adapter_idle, disconnected: flags 0x%x, state 0x%hx\n",
+			 vscsi->flags, vscsi->state);
+		break;
+
+	default:
+		dev_err(&vscsi->dev, "adapter_idle: in invalid state %d\n",
+			vscsi->state);
+		break;
+	}
+
+	if (free_qs)
+		ibmvscsis_free_cmd_qs(vscsi);
+
+	/*
+	 * There is a timing window where we could lose a disconnect request.
+	 * The known path to this window occurs during the DISCONNECT_RECONNECT
+	 * case above: reset_queue calls free_command_q, which will release the
+	 * interrupt lock.  During that time, a new post_disconnect call can be
+	 * made with a "more severe" state (DISCONNECT or UNCONFIGURING).
+	 * Because the DISCONNECT_SCHEDULED flag is already set, post_disconnect
+	 * will only set the new_state.  Now free_command_q reacquires the intr
+	 * lock and clears the DISCONNECT_SCHEDULED flag (using PRESERVE_FLAG_
+	 * FIELDS), and the disconnect is lost.  This is particularly bad when
+	 * the new disconnect was for UNCONFIGURING, since the unconfigure hangs
+	 * forever.
+	 * Fix is that free command queue sets acr state and acr flags if there
+	 * is a change under the lock
+	 * note free command queue writes to this state it clears it
+	 * before releasing the lock, different drivers call the free command
+	 * queue different times so dont initialize above
+	 */
+	if (vscsi->phyp_acr_state != 0)	{
+		/*
+		 * set any bits in flags that may have been cleared by
+		 * a call to free command queue in switch statement
+		 * or reset queue
+		 */
+		vscsi->flags |= vscsi->phyp_acr_flags;
+		ibmvscsis_post_disconnect(vscsi, vscsi->phyp_acr_state, 0);
+		vscsi->phyp_acr_state = 0;
+		vscsi->phyp_acr_flags = 0;
+
+		pr_debug("adapter_idle: flags 0x%x, state 0x%hx, acr_flags 0x%x, acr_state 0x%hx\n",
+			 vscsi->flags, vscsi->state, vscsi->phyp_acr_flags,
+			 vscsi->phyp_acr_state);
+	}
+
+	pr_debug("Leaving adapter_idle: flags 0x%x, state 0x%hx, new_state 0x%x\n",
+		 vscsi->flags, vscsi->state, vscsi->new_state);
+}
+
+/**
+ * ibmvscsis_copy_crq_packet() - Copy CRQ Packet
+ * @vscsi:	Pointer to our adapter structure
+ * @cmd:	Pointer to command element to use to process the request
+ * @crq:	Pointer to CRQ entry containing the request
+ *
+ * Copy the srp information unit from the hosted
+ * partition using remote dma
+ *
+ * EXECUTION ENVIRONMENT:
+ *	Interrupt, interrupt lock held
+ */
+static long ibmvscsis_copy_crq_packet(struct scsi_info *vscsi,
+				      struct ibmvscsis_cmd *cmd,
+				      struct viosrp_crq *crq)
+{
+	struct iu_entry *iue = cmd->iue;
+	long rc = 0;
+	u16 len;
+
+	len = be16_to_cpu(crq->IU_length);
+	if ((len > SRP_MAX_IU_LEN) || (len == 0)) {
+		dev_err(&vscsi->dev, "copy_crq: Invalid len %d passed", len);
+		ibmvscsis_post_disconnect(vscsi, ERR_DISCONNECT_RECONNECT, 0);
+		return SRP_VIOLATION;
+	}
+
+	rc = h_copy_rdma(len, vscsi->dds.window[REMOTE].liobn,
+			 be64_to_cpu(crq->IU_data_ptr),
+			 vscsi->dds.window[LOCAL].liobn, iue->sbuf->dma);
+
+	switch (rc) {
+	case H_SUCCESS:
+		cmd->init_time = mftb();
+		iue->remote_token = crq->IU_data_ptr;
+		iue->iu_len = len;
+		pr_debug("copy_crq: ioba 0x%llx, init_time 0x%llx\n",
+			 be64_to_cpu(crq->IU_data_ptr), cmd->init_time);
+		break;
+	case H_PERMISSION:
+		if (connection_broken(vscsi))
+			ibmvscsis_post_disconnect(vscsi,
+						  ERR_DISCONNECT_RECONNECT,
+						  (RESPONSE_Q_DOWN |
+						   CLIENT_FAILED));
+		else
+			ibmvscsis_post_disconnect(vscsi,
+						  ERR_DISCONNECT_RECONNECT, 0);
+
+		dev_err(&vscsi->dev, "copy_crq: h_copy_rdma failed, rc %ld\n",
+			rc);
+		break;
+	case H_DEST_PARM:
+	case H_SOURCE_PARM:
+	default:
+		dev_err(&vscsi->dev, "copy_crq: h_copy_rdma failed, rc %ld\n",
+			rc);
+		ibmvscsis_post_disconnect(vscsi, ERR_DISCONNECT_RECONNECT, 0);
+		break;
+	}
+
+	return rc;
+}
+
+/**
+ * ibmvscsis_adapter_info - Service an Adapter Info MAnagement Data gram
+ * @vscsi:	Pointer to our adapter structure
+ * @iue:	Information Unit containing the Adapter Info MAD request
+ *
+ * EXECUTION ENVIRONMENT:
+ *	Interrupt adpater lock is held
+ */
+static long ibmvscsis_adapter_info(struct scsi_info *vscsi,
+				   struct iu_entry *iue)
+{
+	struct viosrp_adapter_info *mad = &vio_iu(iue)->mad.adapter_info;
+	struct mad_adapter_info_data *info;
+	uint flag_bits = 0;
+	dma_addr_t token;
+	long rc;
+
+	mad->common.status = cpu_to_be16(VIOSRP_MAD_SUCCESS);
+
+	if (be16_to_cpu(mad->common.length) > sizeof(*info)) {
+		mad->common.status = cpu_to_be16(VIOSRP_MAD_FAILED);
+		return 0;
+	}
+
+	info = dma_alloc_coherent(&vscsi->dma_dev->dev, sizeof(*info), &token,
+				  GFP_KERNEL);
+	if (!info) {
+		dev_err(&vscsi->dev, "bad dma_alloc_coherent %p\n",
+			iue->target);
+		mad->common.status = cpu_to_be16(VIOSRP_MAD_FAILED);
+		return 0;
+	}
+
+	/* Get remote info */
+	rc = h_copy_rdma(be16_to_cpu(mad->common.length),
+			 vscsi->dds.window[REMOTE].liobn,
+			 be64_to_cpu(mad->buffer),
+			 vscsi->dds.window[LOCAL].liobn, token);
+
+	if (rc != H_SUCCESS) {
+		if (rc == H_PERMISSION) {
+			if (connection_broken(vscsi))
+				flag_bits = (RESPONSE_Q_DOWN | CLIENT_FAILED);
+		}
+		pr_warn("adapter_info: h_copy_rdma from client failed, rc %ld\n",
+			rc);
+		pr_debug("adapter_info: ioba 0x%llx, flags 0x%x, flag_bits 0x%x\n",
+			 be64_to_cpu(mad->buffer), vscsi->flags, flag_bits);
+		ibmvscsis_post_disconnect(vscsi, ERR_DISCONNECT_RECONNECT,
+					  flag_bits);
+		goto free_dma;
+	}
+
+	/*
+	 * Copy client info, but ignore partition number, which we
+	 * already got from phyp - unless we failed to get it from
+	 * phyp (e.g. if we're running on a p5 system).
+	 */
+	if (vscsi->client_data.partition_number == 0)
+		vscsi->client_data.partition_number =
+			be32_to_cpu(info->partition_number);
+	strncpy(vscsi->client_data.srp_version, info->srp_version,
+		sizeof(vscsi->client_data.srp_version));
+	strncpy(vscsi->client_data.partition_name, info->partition_name,
+		sizeof(vscsi->client_data.partition_name));
+	vscsi->client_data.mad_version = be32_to_cpu(info->mad_version);
+	vscsi->client_data.os_type = be32_to_cpu(info->os_type);
+
+	/* Copy our info */
+	strncpy(info->srp_version, SRP_VERSION,
+		sizeof(info->srp_version));
+	strncpy(info->partition_name, vscsi->dds.partition_name,
+		sizeof(info->partition_name));
+	info->partition_number = cpu_to_be32(vscsi->dds.partition_num);
+	info->mad_version = cpu_to_be32(MAD_VERSION_1);
+	info->os_type = cpu_to_be32(LINUX);
+	memset(&info->port_max_txu[0], 0, sizeof(info->port_max_txu));
+	info->port_max_txu[0] = cpu_to_be32(128 * PAGE_SIZE);
+
+	dma_wmb();
+	rc = h_copy_rdma(sizeof(*info), vscsi->dds.window[LOCAL].liobn,
+			 token, vscsi->dds.window[REMOTE].liobn,
+			 be64_to_cpu(mad->buffer));
+	switch (rc) {
+	case H_SUCCESS:
+		break;
+
+	case H_SOURCE_PARM:
+	case H_DEST_PARM:
+	case H_PERMISSION:
+		if (connection_broken(vscsi))
+			flag_bits = (RESPONSE_Q_DOWN | CLIENT_FAILED);
+	default:
+		dev_err(&vscsi->dev, "adapter_info: h_copy_rdma to client failed, rc %ld\n",
+			rc);
+		ibmvscsis_post_disconnect(vscsi,
+					  ERR_DISCONNECT_RECONNECT,
+					  flag_bits);
+		break;
+	}
+
+free_dma:
+	dma_free_coherent(&vscsi->dma_dev->dev, sizeof(*info), info, token);
+	pr_debug("Leaving adapter_info, rc %ld\n", rc);
+
+	return rc;
+}
+
+/**
+ * ibmvscsis_cap_mad() - Service a Capabilities MAnagement Data gram
+ * @vscsi:	Pointer to our adapter structure
+ * @iue:	Information Unit containing the Capabilities MAD request
+ *
+ * NOTE: if you return an error from this routine you must be
+ * disconnecting or you will cause a hang
+ *
+ * EXECUTION ENVIRONMENT:
+ *	Interrupt called with adapter lock held
+ */
+static int ibmvscsis_cap_mad(struct scsi_info *vscsi, struct iu_entry *iue)
+{
+	struct viosrp_capabilities *mad = &vio_iu(iue)->mad.capabilities;
+	struct capabilities *cap;
+	struct mad_capability_common *common;
+	dma_addr_t token;
+	u16 olen, len, status, min_len, cap_len;
+	u32 flag;
+	uint flag_bits = 0;
+	long rc = 0;
+
+	olen = be16_to_cpu(mad->common.length);
+	/*
+	 * struct capabilities hardcodes a couple capabilities after the
+	 * header, but the capabilities can actually be in any order.
+	 */
+	min_len = offsetof(struct capabilities, migration);
+	if ((olen < min_len) || (olen > PAGE_SIZE)) {
+		pr_warn("cap_mad: invalid len %d\n", olen);
+		mad->common.status = cpu_to_be16(VIOSRP_MAD_FAILED);
+		return 0;
+	}
+
+	cap = dma_alloc_coherent(&vscsi->dma_dev->dev, olen, &token,
+				 GFP_KERNEL);
+	if (!cap) {
+		dev_err(&vscsi->dev, "bad dma_alloc_coherent %p\n",
+			iue->target);
+		mad->common.status = cpu_to_be16(VIOSRP_MAD_FAILED);
+		return 0;
+	}
+	rc = h_copy_rdma(olen, vscsi->dds.window[REMOTE].liobn,
+			 be64_to_cpu(mad->buffer),
+			 vscsi->dds.window[LOCAL].liobn, token);
+	if (rc == H_SUCCESS) {
+		strncpy(cap->name, dev_name(&vscsi->dma_dev->dev),
+			SRP_MAX_LOC_LEN);
+
+		len = olen - min_len;
+		status = VIOSRP_MAD_SUCCESS;
+		common = (struct mad_capability_common *)&cap->migration;
+
+		while ((len > 0) && (status == VIOSRP_MAD_SUCCESS) && !rc) {
+			pr_debug("cap_mad: len left %hd, cap type %d, cap len %hd\n",
+				 len, be32_to_cpu(common->cap_type),
+				 be16_to_cpu(common->length));
+
+			cap_len = be16_to_cpu(common->length);
+			if (cap_len > len) {
+				dev_err(&vscsi->dev, "cap_mad: cap len mismatch with total len\n");
+				status = VIOSRP_MAD_FAILED;
+				break;
+			}
+
+			if (cap_len == 0) {
+				dev_err(&vscsi->dev, "cap_mad: cap len is 0\n");
+				status = VIOSRP_MAD_FAILED;
+				break;
+			}
+
+			switch (common->cap_type) {
+			default:
+				pr_debug("cap_mad: unsupported capability\n");
+				common->server_support = 0;
+				flag = cpu_to_be32((u32)CAP_LIST_SUPPORTED);
+				cap->flags &= ~flag;
+				break;
+			}
+
+			len = len - cap_len;
+			common = (struct mad_capability_common *)
+				((char *)common + cap_len);
+		}
+
+		mad->common.status = cpu_to_be16(status);
+
+		dma_wmb();
+		rc = h_copy_rdma(olen, vscsi->dds.window[LOCAL].liobn, token,
+				 vscsi->dds.window[REMOTE].liobn,
+				 be64_to_cpu(mad->buffer));
+
+		if (rc != H_SUCCESS) {
+			pr_debug("cap_mad: failed to copy to client, rc %ld\n",
+				 rc);
+
+			if (rc == H_PERMISSION) {
+				if (connection_broken(vscsi))
+					flag_bits = (RESPONSE_Q_DOWN |
+						     CLIENT_FAILED);
+			}
+
+			pr_warn("cap_mad: error copying data to client, rc %ld\n",
+				rc);
+			ibmvscsis_post_disconnect(vscsi,
+						  ERR_DISCONNECT_RECONNECT,
+						  flag_bits);
+		}
+	}
+
+	dma_free_coherent(&vscsi->dma_dev->dev, olen, cap, token);
+
+	pr_debug("Leaving cap_mad, rc %ld, client_cap 0x%x\n",
+		 rc, vscsi->client_cap);
+
+	return rc;
+}
+
+/**
+ * ibmvscsis_process_mad() - Service a MAnagement Data gram
+ * @vscsi:	Pointer to our adapter structure
+ * @iue:	Information Unit containing the MAD request
+ *
+ * Must be called with interrupt lock held.
+ */
+static long ibmvscsis_process_mad(struct scsi_info *vscsi, struct iu_entry *iue)
+{
+	struct mad_common *mad = (struct mad_common *)&vio_iu(iue)->mad;
+	struct viosrp_empty_iu *empty;
+	long rc = ADAPT_SUCCESS;
+
+	switch (be32_to_cpu(mad->type)) {
+	case VIOSRP_EMPTY_IU_TYPE:
+		empty = &vio_iu(iue)->mad.empty_iu;
+		vscsi->empty_iu_id = be64_to_cpu(empty->buffer);
+		vscsi->empty_iu_tag = be64_to_cpu(empty->common.tag);
+		mad->status = cpu_to_be16(VIOSRP_MAD_SUCCESS);
+		break;
+	case VIOSRP_ADAPTER_INFO_TYPE:
+		rc = ibmvscsis_adapter_info(vscsi, iue);
+		break;
+	case VIOSRP_CAPABILITIES_TYPE:
+		rc = ibmvscsis_cap_mad(vscsi, iue);
+		break;
+	case VIOSRP_ENABLE_FAST_FAIL:
+		if (vscsi->state == CONNECTED) {
+			vscsi->fast_fail = true;
+			mad->status = cpu_to_be16(VIOSRP_MAD_SUCCESS);
+		} else {
+			pr_warn("fast fail mad sent after login\n");
+			mad->status = cpu_to_be16(VIOSRP_MAD_FAILED);
+		}
+		break;
+	default:
+		mad->status = cpu_to_be16(VIOSRP_MAD_NOT_SUPPORTED);
+		break;
+	}
+
+	return rc;
+}
+
+/**
+ * srp_snd_msg_failed() - Handle an error when sending a response
+ * @vscsi:	Pointer to our adapter structure
+ * @rc:		The return code from the h_send_crq command
+ *
+ * Must be called with interrupt lock held.
+ */
+static void srp_snd_msg_failed(struct scsi_info *vscsi, long rc)
+{
+	ktime_t kt;
+
+	if (rc != H_DROPPED) {
+		ibmvscsis_free_cmd_qs(vscsi);
+
+		if (rc == H_CLOSED)
+			vscsi->flags |= CLIENT_FAILED;
+
+		/* don't flag the same problem multiple times */
+		if (!(vscsi->flags & RESPONSE_Q_DOWN)) {
+			vscsi->flags |= RESPONSE_Q_DOWN;
+			if (!(vscsi->state & (ERR_DISCONNECT |
+					      ERR_DISCONNECT_RECONNECT |
+					      ERR_DISCONNECTED | UNDEFINED))) {
+				dev_err(&vscsi->dev, "snd_msg_failed: setting RESPONSE_Q_DOWN, state 0x%hx, flags 0x%x, rc %ld\n",
+					vscsi->state, vscsi->flags, rc);
+			}
+			ibmvscsis_post_disconnect(vscsi,
+						  ERR_DISCONNECT_RECONNECT, 0);
+		}
+		return;
+	}
+
+	/*
+	 * The response queue is full.
+	 * If the server is processing SRP requests, i.e.
+	 * the client has successfully done an
+	 * SRP_LOGIN, then it will wait forever for room in
+	 * the queue.  However if the system admin
+	 * is attempting to unconfigure the server then one
+	 * or more children will be in a state where
+	 * they are being removed. So if there is even one
+	 * child being removed then the driver assumes
+	 * the system admin is attempting to break the
+	 * connection with the client and MAX_TIMER_POPS
+	 * is honored.
+	 */
+	if ((vscsi->rsp_q_timer.timer_pops < MAX_TIMER_POPS) ||
+	    (vscsi->state == SRP_PROCESSING)) {
+		pr_debug("snd_msg_failed: response queue full, flags 0x%x, timer started %d, pops %d\n",
+			 vscsi->flags, (int)vscsi->rsp_q_timer.started,
+			 vscsi->rsp_q_timer.timer_pops);
+
+		/*
+		 * Check if the timer is running; if it
+		 * is not then start it up.
+		 */
+		if (!vscsi->rsp_q_timer.started) {
+			if (vscsi->rsp_q_timer.timer_pops <
+			    MAX_TIMER_POPS) {
+				kt = ktime_set(0, WAIT_NANO_SECONDS);
+			} else {
+				/*
+				 * slide the timeslice if the maximum
+				 * timer pops have already happened
+				 */
+				kt = ktime_set(WAIT_SECONDS, 0);
+			}
+
+			vscsi->rsp_q_timer.started = true;
+			hrtimer_start(&vscsi->rsp_q_timer.timer, kt,
+				      HRTIMER_MODE_REL);
+		}
+	} else {
+		/*
+		 * TBD: Do we need to worry about this? Need to get
+		 *      remove working.
+		 */
+		/*
+		 * waited a long time and it appears the system admin
+		 * is bring this driver down
+		 */
+		vscsi->flags |= RESPONSE_Q_DOWN;
+		ibmvscsis_free_cmd_qs(vscsi);
+		/*
+		 * if the driver is already attempting to disconnect
+		 * from the client and has already logged an error
+		 * trace this event but don't put it in the error log
+		 */
+		if (!(vscsi->state & (ERR_DISCONNECT |
+				      ERR_DISCONNECT_RECONNECT |
+				      ERR_DISCONNECTED | UNDEFINED))) {
+			dev_err(&vscsi->dev, "client crq full too long\n");
+			ibmvscsis_post_disconnect(vscsi,
+						  ERR_DISCONNECT_RECONNECT,
+						  0);
+		}
+	}
+}
+
+/**
+ * ibmvscsis_send_messages() - Send a Response
+ * @vscsi:	Pointer to our adapter structure
+ *
+ * Send a response, first checking the waiting queue. Responses are
+ * sent in order they are received. If the response cannot be sent,
+ * because the client queue is full, it stays on the waiting queue.
+ *
+ * PRECONDITION:
+ *	Called with interrupt lock held
+ */
+static void ibmvscsis_send_messages(struct scsi_info *vscsi)
+{
+	u64 msg_hi = 0;
+	/* note do not attmempt to access the IU_data_ptr with this pointer
+	 * it is not valid
+	 */
+	struct viosrp_crq *crq = (struct viosrp_crq *)&msg_hi;
+	struct ibmvscsis_cmd *cmd, *nxt;
+	struct iu_entry *iue;
+	long rc = ADAPT_SUCCESS;
+
+	if (!(vscsi->flags & RESPONSE_Q_DOWN)) {
+		list_for_each_entry_safe(cmd, nxt, &vscsi->waiting_rsp, list) {
+			iue = cmd->iue;
+
+			crq->valid = VALID_CMD_RESP_EL;
+			crq->format = cmd->rsp.format;
+
+			if (cmd->flags & CMD_FAST_FAIL)
+				crq->status = VIOSRP_ADAPTER_FAIL;
+
+			crq->IU_length = cpu_to_be16(cmd->rsp.len);
+
+			rc = h_send_crq(vscsi->dma_dev->unit_address,
+					be64_to_cpu(msg_hi),
+					be64_to_cpu(cmd->rsp.tag));
+
+			pr_debug("send_messages: tag 0x%llx, rc %ld\n",
+				 be64_to_cpu(cmd->rsp.tag), rc);
+
+			/* if all ok free up the command element resources */
+			if (rc == H_SUCCESS) {
+				/* some movement has occurred */
+				vscsi->rsp_q_timer.timer_pops = 0;
+				list_del(&cmd->list);
+
+				ibmvscsis_free_cmd_resources(vscsi, cmd);
+			} else {
+				srp_snd_msg_failed(vscsi, rc);
+				break;
+			}
+		}
+
+		if (!rc) {
+			/*
+			 * The timer could pop with the queue empty.  If
+			 * this happens, rc will always indicate a
+			 * success; clear the pop count.
+			 */
+			vscsi->rsp_q_timer.timer_pops = 0;
+		}
+	} else {
+		ibmvscsis_free_cmd_qs(vscsi);
+	}
+}
+
+/* Called with intr lock held */
+static void ibmvscsis_send_mad_resp(struct scsi_info *vscsi,
+				    struct ibmvscsis_cmd *cmd,
+				    struct viosrp_crq *crq)
+{
+	struct iu_entry *iue = cmd->iue;
+	struct mad_common *mad = (struct mad_common *)&vio_iu(iue)->mad;
+	uint flag_bits = 0;
+	long rc;
+
+	dma_wmb();
+	rc = h_copy_rdma(sizeof(struct mad_common),
+			 vscsi->dds.window[LOCAL].liobn, iue->sbuf->dma,
+			 vscsi->dds.window[REMOTE].liobn,
+			 be64_to_cpu(crq->IU_data_ptr));
+	if (!rc) {
+		cmd->rsp.format = VIOSRP_MAD_FORMAT;
+		cmd->rsp.len = sizeof(struct mad_common);
+		cmd->rsp.tag = mad->tag;
+		list_add_tail(&cmd->list, &vscsi->waiting_rsp);
+		ibmvscsis_send_messages(vscsi);
+	} else {
+		pr_debug("Error sending mad response, rc %ld\n", rc);
+		if (rc == H_PERMISSION) {
+			if (connection_broken(vscsi))
+				flag_bits = (RESPONSE_Q_DOWN | CLIENT_FAILED);
+		}
+		dev_err(&vscsi->dev, "mad: failed to copy to client, rc %ld\n",
+			rc);
+
+		ibmvscsis_free_cmd_resources(vscsi, cmd);
+		ibmvscsis_post_disconnect(vscsi, ERR_DISCONNECT_RECONNECT,
+					  flag_bits);
+	}
+}
+
+/**
+ * ibmvscsis_mad() - Service a MAnagement Data gram.
+ * @vscsi:	Pointer to our adapter structure
+ * @crq:	Pointer to the CRQ entry containing the MAD request
+ *
+ * EXECUTION ENVIRONMENT:
+ *	Interrupt  called with adapter lock held
+ */
+static long ibmvscsis_mad(struct scsi_info *vscsi, struct viosrp_crq *crq)
+{
+	struct iu_entry *iue;
+	struct ibmvscsis_cmd *cmd;
+	struct mad_common *mad;
+	long rc = ADAPT_SUCCESS;
+
+	switch (vscsi->state) {
+		/*
+		 * We have not exchanged Init Msgs yet, so this MAD was sent
+		 * before the last Transport Event; client will not be
+		 * expecting a response.
+		 */
+	case WAIT_CONNECTION:
+		pr_debug("mad: in Wait Connection state, ignoring MAD, flags %d\n",
+			 vscsi->flags);
+		return ADAPT_SUCCESS;
+
+	case SRP_PROCESSING:
+	case CONNECTED:
+		break;
+
+		/*
+		 * We should never get here while we're in these states.
+		 * Just log an error and get out.
+		 */
+	case UNCONFIGURING:
+	case WAIT_IDLE:
+	case ERR_DISCONNECT:
+	case ERR_DISCONNECT_RECONNECT:
+	default:
+		dev_err(&vscsi->dev, "mad: invalid adapter state %d for mad\n",
+			vscsi->state);
+		return ADAPT_SUCCESS;
+	}
+
+	cmd = ibmvscsis_get_free_cmd(vscsi);
+	if (!cmd) {
+		dev_err(&vscsi->dev, "mad: failed to get cmd, debit %d\n",
+			vscsi->debit);
+		ibmvscsis_post_disconnect(vscsi, ERR_DISCONNECT_RECONNECT, 0);
+		return ERROR;
+	}
+	iue = cmd->iue;
+	cmd->type = ADAPTER_MAD;
+
+	rc = ibmvscsis_copy_crq_packet(vscsi, cmd, crq);
+	if (!rc) {
+		mad = (struct mad_common *)&vio_iu(iue)->mad;
+
+		pr_debug("mad: type %d\n", be32_to_cpu(mad->type));
+
+		if (be16_to_cpu(mad->length) < 0) {
+			dev_err(&vscsi->dev, "mad: length is < 0\n");
+			ibmvscsis_post_disconnect(vscsi,
+						  ERR_DISCONNECT_RECONNECT, 0);
+			rc = SRP_VIOLATION;
+		} else {
+			rc = ibmvscsis_process_mad(vscsi, iue);
+		}
+
+		pr_debug("mad: status %hd, rc %ld\n", be16_to_cpu(mad->status),
+			 rc);
+
+		if (!rc)
+			ibmvscsis_send_mad_resp(vscsi, cmd, crq);
+	} else {
+		ibmvscsis_free_cmd_resources(vscsi, cmd);
+	}
+
+	pr_debug("Leaving mad, rc %ld\n", rc);
+	return rc;
+}
+
+/**
+ * ibmvscsis_login_rsp() - Create/copy a login response notice to the client
+ * @vscsi:	Pointer to our adapter structure
+ * @cmd:	Pointer to the command for the SRP Login request
+ *
+ * EXECUTION ENVIRONMENT:
+ *	Interrupt, interrupt lock held
+ */
+static long ibmvscsis_login_rsp(struct scsi_info *vscsi,
+				struct ibmvscsis_cmd *cmd)
+{
+	struct iu_entry *iue = cmd->iue;
+	struct srp_login_rsp *rsp = &vio_iu(iue)->srp.login_rsp;
+	struct format_code *fmt;
+	uint flag_bits = 0;
+	long rc = ADAPT_SUCCESS;
+
+	memset(rsp, 0, sizeof(struct srp_login_rsp));
+
+	rsp->opcode = SRP_LOGIN_RSP;
+	rsp->req_lim_delta = cpu_to_be32(vscsi->request_limit);
+	rsp->tag = cmd->rsp.tag;
+	rsp->max_it_iu_len = cpu_to_be32(SRP_MAX_IU_LEN);
+	rsp->max_ti_iu_len = cpu_to_be32(SRP_MAX_IU_LEN);
+	fmt = (struct format_code *)&rsp->buf_fmt;
+	fmt->buffers = SUPPORTED_FORMATS;
+	vscsi->credit = 0;
+
+	cmd->rsp.len = sizeof(struct srp_login_rsp);
+
+	dma_wmb();
+	rc = h_copy_rdma(cmd->rsp.len, vscsi->dds.window[LOCAL].liobn,
+			 iue->sbuf->dma, vscsi->dds.window[REMOTE].liobn,
+			 be64_to_cpu(iue->remote_token));
+
+	switch (rc) {
+	case H_SUCCESS:
+		break;
+
+	case H_PERMISSION:
+		if (connection_broken(vscsi))
+			flag_bits = RESPONSE_Q_DOWN | CLIENT_FAILED;
+		dev_err(&vscsi->dev, "login_rsp: error copying to client, rc %ld\n",
+			rc);
+		ibmvscsis_post_disconnect(vscsi, ERR_DISCONNECT_RECONNECT,
+					  flag_bits);
+		break;
+	case H_SOURCE_PARM:
+	case H_DEST_PARM:
+	default:
+		dev_err(&vscsi->dev, "login_rsp: error copying to client, rc %ld\n",
+			rc);
+		ibmvscsis_post_disconnect(vscsi, ERR_DISCONNECT_RECONNECT, 0);
+		break;
+	}
+
+	return rc;
+}
+
+/**
+ * ibmvscsis_srp_login_rej() - Create/copy a login rejection notice to client
+ * @vscsi:	Pointer to our adapter structure
+ * @cmd:	Pointer to the command for the SRP Login request
+ * @reason:	The reason the SRP Login is being rejected, per SRP protocol
+ *
+ * EXECUTION ENVIRONMENT:
+ *	Interrupt, interrupt lock held
+ */
+static long ibmvscsis_srp_login_rej(struct scsi_info *vscsi,
+				    struct ibmvscsis_cmd *cmd, u32 reason)
+{
+	struct iu_entry *iue = cmd->iue;
+	struct srp_login_rej *rej = &vio_iu(iue)->srp.login_rej;
+	struct format_code *fmt;
+	uint flag_bits = 0;
+	long rc = ADAPT_SUCCESS;
+
+	memset(rej, 0, sizeof(*rej));
+
+	rej->opcode = SRP_LOGIN_REJ;
+	rej->reason = cpu_to_be32(reason);
+	rej->tag = cmd->rsp.tag;
+	fmt = (struct format_code *)&rej->buf_fmt;
+	fmt->buffers = SUPPORTED_FORMATS;
+
+	cmd->rsp.len = sizeof(*rej);
+
+	dma_wmb();
+	rc = h_copy_rdma(cmd->rsp.len, vscsi->dds.window[LOCAL].liobn,
+			 iue->sbuf->dma, vscsi->dds.window[REMOTE].liobn,
+			 be64_to_cpu(iue->remote_token));
+
+	switch (rc) {
+	case H_SUCCESS:
+		break;
+	case H_PERMISSION:
+		if (connection_broken(vscsi))
+			flag_bits =  RESPONSE_Q_DOWN | CLIENT_FAILED;
+		dev_err(&vscsi->dev, "login_rej: error copying to client, rc %ld\n",
+			rc);
+		ibmvscsis_post_disconnect(vscsi, ERR_DISCONNECT_RECONNECT,
+					  flag_bits);
+		break;
+	case H_SOURCE_PARM:
+	case H_DEST_PARM:
+	default:
+		dev_err(&vscsi->dev, "login_rej: error copying to client, rc %ld\n",
+			rc);
+		ibmvscsis_post_disconnect(vscsi, ERR_DISCONNECT_RECONNECT, 0);
+		break;
+	}
+
+	return rc;
+}
+
+static int ibmvscsis_make_nexus(struct ibmvscsis_tport *tport)
+{
+	char *name = tport->tport_name;
+	struct ibmvscsis_nexus *nexus;
+	int rc;
+
+	if (tport->ibmv_nexus) {
+		pr_debug("tport->ibmv_nexus already exists\n");
+		return 0;
+	}
+
+	nexus = kzalloc(sizeof(*nexus), GFP_KERNEL);
+	if (!nexus) {
+		pr_err("Unable to allocate struct ibmvscsis_nexus\n");
+		return -ENOMEM;
+	}
+
+	nexus->se_sess = target_alloc_session(&tport->se_tpg, 0, 0,
+					      TARGET_PROT_NORMAL, name, nexus,
+					      NULL);
+	if (IS_ERR(nexus->se_sess)) {
+		rc = PTR_ERR(nexus->se_sess);
+		goto transport_init_fail;
+	}
+
+	tport->ibmv_nexus = nexus;
+
+	return 0;
+
+transport_init_fail:
+	kfree(nexus);
+	return rc;
+}
+
+static int ibmvscsis_drop_nexus(struct ibmvscsis_tport *tport)
+{
+	struct se_session *se_sess;
+	struct ibmvscsis_nexus *nexus;
+
+	nexus = tport->ibmv_nexus;
+	if (!nexus)
+		return -ENODEV;
+
+	se_sess = nexus->se_sess;
+	if (!se_sess)
+		return -ENODEV;
+
+	/*
+	 * Release the SCSI I_T Nexus to the emulated ibmvscsis Target Port
+	 */
+	target_wait_for_sess_cmds(se_sess);
+	transport_deregister_session_configfs(se_sess);
+	transport_deregister_session(se_sess);
+	tport->ibmv_nexus = NULL;
+	kfree(nexus);
+
+	return 0;
+}
+
+/**
+ * ibmvscsis_srp_login() - Process an SRP Login Request
+ * @vscsi:	Pointer to our adapter structure
+ * @cmd:	Command element to use to process the SRP Login request
+ * @crq:	Pointer to CRQ entry containing the SRP Login request
+ *
+ * EXECUTION ENVIRONMENT:
+ *	Interrupt, called with interrupt lock held
+ */
+static long ibmvscsis_srp_login(struct scsi_info *vscsi,
+				struct ibmvscsis_cmd *cmd,
+				struct viosrp_crq *crq)
+{
+	struct iu_entry *iue = cmd->iue;
+	struct srp_login_req *req = &vio_iu(iue)->srp.login_req;
+	struct port_id {
+		__be64 id_extension;
+		__be64 io_guid;
+	} *iport, *tport;
+	struct format_code *fmt;
+	u32 reason = 0x0;
+	long rc = ADAPT_SUCCESS;
+
+	iport = (struct port_id *)req->initiator_port_id;
+	tport = (struct port_id *)req->target_port_id;
+	fmt = (struct format_code *)&req->req_buf_fmt;
+	if (be32_to_cpu(req->req_it_iu_len) > SRP_MAX_IU_LEN)
+		reason = SRP_LOGIN_REJ_REQ_IT_IU_LENGTH_TOO_LARGE;
+	else if (be32_to_cpu(req->req_it_iu_len) < 64)
+		reason = SRP_LOGIN_REJ_UNABLE_ESTABLISH_CHANNEL;
+	else if ((be64_to_cpu(iport->id_extension) > (MAX_NUM_PORTS - 1)) ||
+		 (be64_to_cpu(tport->id_extension) > (MAX_NUM_PORTS - 1)))
+		reason = SRP_LOGIN_REJ_UNABLE_ASSOCIATE_CHANNEL;
+	else if (req->req_flags & SRP_MULTICHAN_MULTI)
+		reason = SRP_LOGIN_REJ_MULTI_CHANNEL_UNSUPPORTED;
+	else if (fmt->buffers & (~SUPPORTED_FORMATS))
+		reason = SRP_LOGIN_REJ_UNSUPPORTED_DESCRIPTOR_FMT;
+	else if ((fmt->buffers & SUPPORTED_FORMATS) == 0)
+		reason = SRP_LOGIN_REJ_UNSUPPORTED_DESCRIPTOR_FMT;
+
+	if (vscsi->state == SRP_PROCESSING)
+		reason = SRP_LOGIN_REJ_CHANNEL_LIMIT_REACHED;
+
+	rc = ibmvscsis_make_nexus(&vscsi->tport);
+	if (rc)
+		reason = SRP_LOGIN_REJ_UNABLE_ESTABLISH_CHANNEL;
+
+	cmd->rsp.format = VIOSRP_SRP_FORMAT;
+	cmd->rsp.tag = req->tag;
+
+	pr_debug("srp_login: reason 0x%x\n", reason);
+
+	if (reason)
+		rc = ibmvscsis_srp_login_rej(vscsi, cmd, reason);
+	else
+		rc = ibmvscsis_login_rsp(vscsi, cmd);
+
+	if (!rc) {
+		if (!reason)
+			vscsi->state = SRP_PROCESSING;
+
+		list_add_tail(&cmd->list, &vscsi->waiting_rsp);
+		ibmvscsis_send_messages(vscsi);
+	} else {
+		ibmvscsis_free_cmd_resources(vscsi, cmd);
+	}
+
+	pr_debug("Leaving srp_login, rc %ld\n", rc);
+	return rc;
+}
+
+/**
+ * ibmvscsis_srp_i_logout() - Helper Function to close I_T Nexus
+ * @vscsi:	Pointer to our adapter structure
+ * @cmd:	Command element to use to process the Implicit Logout request
+ * @crq:	Pointer to CRQ entry containing the Implicit Logout request
+ *
+ * Do the logic to close the I_T nexus.  This function may not
+ * behave to specification.
+ *
+ * EXECUTION ENVIRONMENT:
+ *	Interrupt, interrupt lock held
+ */
+static long ibmvscsis_srp_i_logout(struct scsi_info *vscsi,
+				   struct ibmvscsis_cmd *cmd,
+				   struct viosrp_crq *crq)
+{
+	struct iu_entry *iue = cmd->iue;
+	struct srp_i_logout *log_out = &vio_iu(iue)->srp.i_logout;
+	long rc = ADAPT_SUCCESS;
+
+	if ((vscsi->debit > 0) || !list_empty(&vscsi->schedule_q) ||
+	    !list_empty(&vscsi->waiting_rsp)) {
+		dev_err(&vscsi->dev, "i_logout: outstanding work\n");
+		ibmvscsis_post_disconnect(vscsi, ERR_DISCONNECT, 0);
+	} else {
+		cmd->rsp.format = SRP_FORMAT;
+		cmd->rsp.tag = log_out->tag;
+		cmd->rsp.len = sizeof(struct mad_common);
+		list_add_tail(&cmd->list, &vscsi->waiting_rsp);
+		ibmvscsis_send_messages(vscsi);
+
+		ibmvscsis_post_disconnect(vscsi, WAIT_IDLE, 0);
+	}
+
+	return rc;
+}
+
+/* Called with intr lock held */
+static void ibmvscsis_srp_cmd(struct scsi_info *vscsi, struct viosrp_crq *crq)
+{
+	struct ibmvscsis_cmd *cmd;
+	struct iu_entry *iue;
+	struct srp_cmd *srp;
+	struct srp_tsk_mgmt *tsk;
+	long rc;
+
+	if (vscsi->request_limit - vscsi->debit <= 0) {
+		/* Client has exceeded request limit */
+		dev_err(&vscsi->dev, "Client exceeded the request limit (%d), debit %d\n",
+			vscsi->request_limit, vscsi->debit);
+		ibmvscsis_post_disconnect(vscsi, ERR_DISCONNECT_RECONNECT, 0);
+		return;
+	}
+
+	cmd = ibmvscsis_get_free_cmd(vscsi);
+	if (!cmd) {
+		dev_err(&vscsi->dev, "srp_cmd failed to get cmd, debit %d\n",
+			vscsi->debit);
+		ibmvscsis_post_disconnect(vscsi, ERR_DISCONNECT_RECONNECT, 0);
+		return;
+	}
+	iue = cmd->iue;
+	srp = &vio_iu(iue)->srp.cmd;
+
+	rc = ibmvscsis_copy_crq_packet(vscsi, cmd, crq);
+	if (rc) {
+		ibmvscsis_free_cmd_resources(vscsi, cmd);
+		return;
+	}
+
+	if (vscsi->state == SRP_PROCESSING) {
+		switch (srp->opcode) {
+		case SRP_LOGIN_REQ:
+			rc = ibmvscsis_srp_login(vscsi, cmd, crq);
+			break;
+
+		case SRP_TSK_MGMT:
+			tsk = &vio_iu(iue)->srp.tsk_mgmt;
+			pr_debug("tsk_mgmt tag: %llu (0x%llx)\n", tsk->tag,
+				 tsk->tag);
+			cmd->rsp.tag = tsk->tag;
+			vscsi->debit += 1;
+			cmd->type = TASK_MANAGEMENT;
+			list_add_tail(&cmd->list, &vscsi->schedule_q);
+			queue_work(vscsi->work_q, &cmd->work);
+			break;
+
+		case SRP_CMD:
+			pr_debug("srp_cmd tag: %llu (0x%llx)\n", srp->tag,
+				 srp->tag);
+			cmd->rsp.tag = srp->tag;
+			vscsi->debit += 1;
+			cmd->type = SCSI_CDB;
+			/*
+			 * We want to keep track of work waiting for
+			 * the workqueue.
+			 */
+			list_add_tail(&cmd->list, &vscsi->schedule_q);
+			queue_work(vscsi->work_q, &cmd->work);
+			break;
+
+		case SRP_I_LOGOUT:
+			rc = ibmvscsis_srp_i_logout(vscsi, cmd, crq);
+			break;
+
+		case SRP_CRED_RSP:
+		case SRP_AER_RSP:
+		default:
+			ibmvscsis_free_cmd_resources(vscsi, cmd);
+			dev_err(&vscsi->dev, "invalid srp cmd, opcode %d\n",
+				(uint)srp->opcode);
+			ibmvscsis_post_disconnect(vscsi,
+						  ERR_DISCONNECT_RECONNECT, 0);
+			break;
+		}
+	} else if (srp->opcode == SRP_LOGIN_REQ && vscsi->state == CONNECTED) {
+		rc = ibmvscsis_srp_login(vscsi, cmd, crq);
+	} else {
+		ibmvscsis_free_cmd_resources(vscsi, cmd);
+		dev_err(&vscsi->dev, "Invalid state %d to handle srp cmd\n",
+			vscsi->state);
+		ibmvscsis_post_disconnect(vscsi, ERR_DISCONNECT_RECONNECT, 0);
+	}
+}
+
+/**
+ * ibmvscsis_ping_response() - Respond to a ping request
+ * @vscsi:	Pointer to our adapter structure
+ *
+ * Let the client know that the server is alive and waiting on
+ * its native I/O stack.
+ * If any type of error occurs from the call to queue a ping
+ * response then the client is either not accepting or receiving
+ * interrupts.  Disconnect with an error.
+ *
+ * EXECUTION ENVIRONMENT:
+ *	Interrupt, interrupt lock held
+ */
+static long ibmvscsis_ping_response(struct scsi_info *vscsi)
+{
+	struct viosrp_crq *crq;
+	u64 buffer[2] = { 0, 0 };
+	long rc;
+
+	crq = (struct viosrp_crq *)&buffer;
+	crq->valid = VALID_CMD_RESP_EL;
+	crq->format = (u8)MESSAGE_IN_CRQ;
+	crq->status = PING_RESPONSE;
+
+	rc = h_send_crq(vscsi->dds.unit_id, cpu_to_be64(buffer[MSG_HI]),
+			cpu_to_be64(buffer[MSG_LOW]));
+
+	switch (rc) {
+	case H_SUCCESS:
+		break;
+	case H_CLOSED:
+		vscsi->flags |= CLIENT_FAILED;
+	case H_DROPPED:
+		vscsi->flags |= RESPONSE_Q_DOWN;
+	case H_REMOTE_PARM:
+		dev_err(&vscsi->dev, "ping_response: h_send_crq failed, rc %ld\n",
+			rc);
+		ibmvscsis_post_disconnect(vscsi, ERR_DISCONNECT_RECONNECT, 0);
+		break;
+	default:
+		dev_err(&vscsi->dev, "ping_response: h_send_crq returned unknown rc %ld\n",
+			rc);
+		ibmvscsis_post_disconnect(vscsi, ERR_DISCONNECT, 0);
+		break;
+	}
+
+	return rc;
+}
+
+/**
+ * ibmvscsis_handle_init_compl_msg() - Respond to an Init Complete Message
+ * @vscsi:	Pointer to our adapter structure
+ *
+ * Must be called with interrupt lock held.
+ */
+static long ibmvscsis_handle_init_compl_msg(struct scsi_info *vscsi)
+{
+	long rc = ADAPT_SUCCESS;
+
+	switch (vscsi->state) {
+	case NO_QUEUE:
+	case ERR_DISCONNECT:
+	case ERR_DISCONNECT_RECONNECT:
+	case ERR_DISCONNECTED:
+	case UNCONFIGURING:
+	case UNDEFINED:
+		rc = ERROR;
+		break;
+
+	case WAIT_CONNECTION:
+		vscsi->state = CONNECTED;
+		break;
+
+	case WAIT_IDLE:
+	case SRP_PROCESSING:
+	case CONNECTED:
+	case WAIT_ENABLED:
+	case PART_UP_WAIT_ENAB:
+	default:
+		rc = ERROR;
+		dev_err(&vscsi->dev, "init_msg: invalid state %d to get init compl msg\n",
+			vscsi->state);
+		ibmvscsis_post_disconnect(vscsi, ERR_DISCONNECT_RECONNECT, 0);
+		break;
+	}
+
+	return rc;
+}
+
+/**
+ * ibmvscsis_handle_init_msg() - Respond to an Init Message
+ * @vscsi:	Pointer to our adapter structure
+ *
+ * Must be called with interrupt lock held.
+ */
+static long ibmvscsis_handle_init_msg(struct scsi_info *vscsi)
+{
+	long rc = ADAPT_SUCCESS;
+
+	switch (vscsi->state) {
+	case WAIT_ENABLED:
+		vscsi->state = PART_UP_WAIT_ENAB;
+		break;
+
+	case WAIT_CONNECTION:
+		rc = ibmvscsis_send_init_message(vscsi, INIT_COMPLETE_MSG);
+		switch (rc) {
+		case H_SUCCESS:
+			vscsi->state = CONNECTED;
+			break;
+
+		case H_PARAMETER:
+			dev_err(&vscsi->dev, "init_msg: failed to send, rc %ld\n",
+				rc);
+			ibmvscsis_post_disconnect(vscsi, ERR_DISCONNECT, 0);
+			break;
+
+		case H_DROPPED:
+			dev_err(&vscsi->dev, "init_msg: failed to send, rc %ld\n",
+				rc);
+			rc = ERROR;
+			ibmvscsis_post_disconnect(vscsi,
+						  ERR_DISCONNECT_RECONNECT, 0);
+			break;
+
+		case H_CLOSED:
+			pr_warn("init_msg: failed to send, rc %ld\n", rc);
+			rc = 0;
+			break;
+		}
+		break;
+
+	case UNDEFINED:
+		rc = ERROR;
+		break;
+
+	case UNCONFIGURING:
+		break;
+
+	case PART_UP_WAIT_ENAB:
+	case CONNECTED:
+	case SRP_PROCESSING:
+	case WAIT_IDLE:
+	case NO_QUEUE:
+	case ERR_DISCONNECT:
+	case ERR_DISCONNECT_RECONNECT:
+	case ERR_DISCONNECTED:
+	default:
+		rc = ERROR;
+		dev_err(&vscsi->dev, "init_msg: invalid state %d to get init msg\n",
+			vscsi->state);
+		ibmvscsis_post_disconnect(vscsi, ERR_DISCONNECT_RECONNECT, 0);
+		break;
+	}
+
+	return rc;
+}
+
+/**
+ * ibmvscsis_init_msg() - Respond to an init message
+ * @vscsi:	Pointer to our adapter structure
+ * @crq:	Pointer to CRQ element containing the Init Message
+ *
+ * EXECUTION ENVIRONMENT:
+ *	Interrupt, interrupt lock held
+ */
+static long ibmvscsis_init_msg(struct scsi_info *vscsi, struct viosrp_crq *crq)
+{
+	long rc = ADAPT_SUCCESS;
+
+	pr_debug("init_msg: state 0x%hx\n", vscsi->state);
+
+	rc = h_vioctl(vscsi->dds.unit_id, H_GET_PARTNER_INFO,
+		      (u64)vscsi->map_ioba | ((u64)PAGE_SIZE << 32), 0, 0, 0,
+		      0);
+	if (rc == H_SUCCESS) {
+		vscsi->client_data.partition_number =
+			be64_to_cpu(*(u64 *)vscsi->map_buf);
+		pr_debug("init_msg, part num %d\n",
+			 vscsi->client_data.partition_number);
+	} else {
+		pr_debug("init_msg h_vioctl rc %ld\n", rc);
+		rc = ADAPT_SUCCESS;
+	}
+
+	if (crq->format == INIT_MSG) {
+		rc = ibmvscsis_handle_init_msg(vscsi);
+	} else if (crq->format == INIT_COMPLETE_MSG) {
+		rc = ibmvscsis_handle_init_compl_msg(vscsi);
+	} else {
+		rc = ERROR;
+		dev_err(&vscsi->dev, "init_msg: invalid format %d\n",
+			(uint)crq->format);
+		ibmvscsis_post_disconnect(vscsi, ERR_DISCONNECT_RECONNECT, 0);
+	}
+
+	return rc;
+}
+
+/**
+ * ibmvscsis_parse_command() - Parse an element taken from the cmd rsp queue.
+ * @vscsi:	Pointer to our adapter structure
+ * @crq:	Pointer to CRQ element containing the SRP request
+ *
+ * This function will return success if the command queue element is valid
+ * and the srp iu or MAD request it pointed to was also valid.  That does
+ * not mean that an error was not returned to the client.
+ *
+ * EXECUTION ENVIRONMENT:
+ *	Interrupt, intr lock held
+ */
+static long ibmvscsis_parse_command(struct scsi_info *vscsi,
+				    struct viosrp_crq *crq)
+{
+	long rc = ADAPT_SUCCESS;
+
+	switch (crq->valid) {
+	case VALID_CMD_RESP_EL:
+		switch (crq->format) {
+		case OS400_FORMAT:
+		case AIX_FORMAT:
+		case LINUX_FORMAT:
+		case MAD_FORMAT:
+			if (vscsi->flags & PROCESSING_MAD) {
+				rc = ERROR;
+				dev_err(&vscsi->dev, "parse_command: already processing mad\n");
+				ibmvscsis_post_disconnect(vscsi,
+						       ERR_DISCONNECT_RECONNECT,
+						       0);
+			} else {
+				vscsi->flags |= PROCESSING_MAD;
+				rc = ibmvscsis_mad(vscsi, crq);
+			}
+			break;
+
+		case SRP_FORMAT:
+			ibmvscsis_srp_cmd(vscsi, crq);
+			break;
+
+		case MESSAGE_IN_CRQ:
+			if (crq->status == PING)
+				ibmvscsis_ping_response(vscsi);
+			break;
+
+		default:
+			dev_err(&vscsi->dev, "parse_command: invalid format %d\n",
+				(uint)crq->format);
+			ibmvscsis_post_disconnect(vscsi,
+						  ERR_DISCONNECT_RECONNECT, 0);
+			break;
+		}
+		break;
+
+	case VALID_TRANS_EVENT:
+		rc =  ibmvscsis_trans_event(vscsi, crq);
+		break;
+
+	case VALID_INIT_MSG:
+		rc = ibmvscsis_init_msg(vscsi, crq);
+		break;
+
+	default:
+		dev_err(&vscsi->dev, "parse_command: invalid valid field %d\n",
+			(uint)crq->valid);
+		ibmvscsis_post_disconnect(vscsi, ERR_DISCONNECT_RECONNECT, 0);
+		break;
+	}
+
+	/*
+	 * Return only what the interrupt handler cares
+	 * about. Most errors we keep right on trucking.
+	 */
+	rc = vscsi->flags & SCHEDULE_DISCONNECT;
+
+	return rc;
+}
+
+static int read_dma_window(struct scsi_info *vscsi)
+{
+	struct vio_dev *vdev = vscsi->dma_dev;
+	const __be32 *dma_window;
+	const __be32 *prop;
+
+	/* TODO Using of_parse_dma_window would be better, but it doesn't give
+	 * a way to read multiple windows without already knowing the size of
+	 * a window or the number of windows.
+	 */
+	dma_window = (const __be32 *)vio_get_attribute(vdev,
+						       "ibm,my-dma-window",
+						       NULL);
+	if (!dma_window) {
+		pr_err("Couldn't find ibm,my-dma-window property\n");
+		return -1;
+	}
+
+	vscsi->dds.window[LOCAL].liobn = be32_to_cpu(*dma_window);
+	dma_window++;
+
+	prop = (const __be32 *)vio_get_attribute(vdev, "ibm,#dma-address-cells",
+						 NULL);
+	if (!prop) {
+		pr_warn("Couldn't find ibm,#dma-address-cells property\n");
+		dma_window++;
+	} else {
+		dma_window += be32_to_cpu(*prop);
+	}
+
+	prop = (const __be32 *)vio_get_attribute(vdev, "ibm,#dma-size-cells",
+						 NULL);
+	if (!prop) {
+		pr_warn("Couldn't find ibm,#dma-size-cells property\n");
+		dma_window++;
+	} else {
+		dma_window += be32_to_cpu(*prop);
+	}
+
+	/* dma_window should point to the second window now */
+	vscsi->dds.window[REMOTE].liobn = be32_to_cpu(*dma_window);
+
+	return 0;
+}
+
+static struct ibmvscsis_tport *ibmvscsis_lookup_port(const char *name)
+{
+	struct ibmvscsis_tport *tport = NULL;
+	struct vio_dev *vdev;
+	struct scsi_info *vscsi;
+
+	spin_lock_bh(&ibmvscsis_dev_lock);
+	list_for_each_entry(vscsi, &ibmvscsis_dev_list, list) {
+		vdev = vscsi->dma_dev;
+		if (!strcmp(dev_name(&vdev->dev), name)) {
+			tport = &vscsi->tport;
+			break;
+		}
+	}
+	spin_unlock_bh(&ibmvscsis_dev_lock);
+
+	return tport;
+}
+
+/**
+ * ibmvscsis_parse_cmd() - Parse SRP Command
+ * @vscsi:	Pointer to our adapter structure
+ * @cmd:	Pointer to command element with SRP command
+ *
+ * Parse the srp command; if it is valid then submit it to tcm.
+ * Note: The return code does not reflect the status of the SCSI CDB.
+ *
+ * EXECUTION ENVIRONMENT:
+ *	Process level
+ */
+static void ibmvscsis_parse_cmd(struct scsi_info *vscsi,
+				struct ibmvscsis_cmd *cmd)
+{
+	struct iu_entry *iue = cmd->iue;
+	struct srp_cmd *srp = (struct srp_cmd *)iue->sbuf->buf;
+	struct ibmvscsis_nexus *nexus;
+	u64 data_len = 0;
+	enum dma_data_direction dir;
+	int attr = 0;
+	int rc = 0;
+
+	nexus = vscsi->tport.ibmv_nexus;
+	/*
+	 * additional length in bytes.  Note that the SRP spec says that
+	 * additional length is in 4-byte words, but technically the
+	 * additional length field is only the upper 6 bits of the byte.
+	 * The lower 2 bits are reserved.  If the lower 2 bits are 0 (as
+	 * all reserved fields should be), then interpreting the byte as
+	 * an int will yield the length in bytes.
+	 */
+	if (srp->add_cdb_len & 0x03) {
+		dev_err(&vscsi->dev, "parse_cmd: reserved bits set in IU\n");
+		spin_lock_bh(&vscsi->intr_lock);
+		ibmvscsis_post_disconnect(vscsi, ERR_DISCONNECT_RECONNECT, 0);
+		ibmvscsis_free_cmd_resources(vscsi, cmd);
+		spin_unlock_bh(&vscsi->intr_lock);
+		return;
+	}
+
+	if (srp_get_desc_table(srp, &dir, &data_len)) {
+		dev_err(&vscsi->dev, "0x%llx: parsing SRP descriptor table failed.\n",
+			srp->tag);
+		goto fail;
+		return;
+	}
+
+	cmd->rsp.sol_not = srp->sol_not;
+
+	switch (srp->task_attr) {
+	case SRP_SIMPLE_TASK:
+		attr = TCM_SIMPLE_TAG;
+		break;
+	case SRP_ORDERED_TASK:
+		attr = TCM_ORDERED_TAG;
+		break;
+	case SRP_HEAD_TASK:
+		attr = TCM_HEAD_TAG;
+		break;
+	case SRP_ACA_TASK:
+		attr = TCM_ACA_TAG;
+		break;
+	default:
+		dev_err(&vscsi->dev, "Invalid task attribute %d\n",
+			srp->task_attr);
+		goto fail;
+	}
+
+	cmd->se_cmd.tag = be64_to_cpu(srp->tag);
+
+	spin_lock_bh(&vscsi->intr_lock);
+	list_add_tail(&cmd->list, &vscsi->active_q);
+	spin_unlock_bh(&vscsi->intr_lock);
+
+	srp->lun.scsi_lun[0] &= 0x3f;
+
+	rc = target_submit_cmd(&cmd->se_cmd, nexus->se_sess, srp->cdb,
+			       cmd->sense_buf, scsilun_to_int(&srp->lun),
+			       data_len, attr, dir, 0);
+	if (rc) {
+		dev_err(&vscsi->dev, "target_submit_cmd failed, rc %d\n", rc);
+		goto fail;
+	}
+	return;
+
+fail:
+	spin_lock_bh(&vscsi->intr_lock);
+	ibmvscsis_post_disconnect(vscsi, ERR_DISCONNECT_RECONNECT, 0);
+	spin_unlock_bh(&vscsi->intr_lock);
+}
+
+/**
+ * ibmvscsis_parse_task() - Parse SRP Task Management Request
+ * @vscsi:	Pointer to our adapter structure
+ * @cmd:	Pointer to command element with SRP task management request
+ *
+ * Parse the srp task management request; if it is valid then submit it to tcm.
+ * Note: The return code does not reflect the status of the task management
+ * request.
+ *
+ * EXECUTION ENVIRONMENT:
+ *	Processor level
+ */
+static void ibmvscsis_parse_task(struct scsi_info *vscsi,
+				 struct ibmvscsis_cmd *cmd)
+{
+	struct iu_entry *iue = cmd->iue;
+	struct srp_tsk_mgmt *srp_tsk = &vio_iu(iue)->srp.tsk_mgmt;
+	int tcm_type;
+	u64 tag_to_abort = 0;
+	int rc = 0;
+	struct ibmvscsis_nexus *nexus;
+
+	nexus = vscsi->tport.ibmv_nexus;
+
+	cmd->rsp.sol_not = srp_tsk->sol_not;
+
+	switch (srp_tsk->tsk_mgmt_func) {
+	case SRP_TSK_ABORT_TASK:
+		tcm_type = TMR_ABORT_TASK;
+		tag_to_abort = be64_to_cpu(srp_tsk->task_tag);
+		break;
+	case SRP_TSK_ABORT_TASK_SET:
+		tcm_type = TMR_ABORT_TASK_SET;
+		break;
+	case SRP_TSK_CLEAR_TASK_SET:
+		tcm_type = TMR_CLEAR_TASK_SET;
+		break;
+	case SRP_TSK_LUN_RESET:
+		tcm_type = TMR_LUN_RESET;
+		break;
+	case SRP_TSK_CLEAR_ACA:
+		tcm_type = TMR_CLEAR_ACA;
+		break;
+	default:
+		dev_err(&vscsi->dev, "unknown task mgmt func %d\n",
+			srp_tsk->tsk_mgmt_func);
+		cmd->se_cmd.se_tmr_req->response =
+			TMR_TASK_MGMT_FUNCTION_NOT_SUPPORTED;
+		rc = -1;
+		break;
+	}
+
+	if (!rc) {
+		cmd->se_cmd.tag = be64_to_cpu(srp_tsk->tag);
+
+		spin_lock_bh(&vscsi->intr_lock);
+		list_add_tail(&cmd->list, &vscsi->active_q);
+		spin_unlock_bh(&vscsi->intr_lock);
+
+		srp_tsk->lun.scsi_lun[0] &= 0x3f;
+
+		pr_debug("calling submit_tmr, func %d\n",
+			 srp_tsk->tsk_mgmt_func);
+		rc = target_submit_tmr(&cmd->se_cmd, nexus->se_sess, NULL,
+				       scsilun_to_int(&srp_tsk->lun), srp_tsk,
+				       tcm_type, GFP_KERNEL, tag_to_abort, 0);
+		if (rc) {
+			dev_err(&vscsi->dev, "target_submit_tmr failed, rc %d\n",
+				rc);
+			cmd->se_cmd.se_tmr_req->response =
+				TMR_FUNCTION_REJECTED;
+		}
+	}
+
+	if (rc)
+		transport_send_check_condition_and_sense(&cmd->se_cmd, 0, 0);
+}
+
+static void ibmvscsis_scheduler(struct work_struct *work)
+{
+	struct ibmvscsis_cmd *cmd = container_of(work, struct ibmvscsis_cmd,
+						 work);
+	struct scsi_info *vscsi = cmd->adapter;
+
+	spin_lock_bh(&vscsi->intr_lock);
+
+	/* Remove from schedule_q */
+	list_del(&cmd->list);
+
+	/* Don't submit cmd if we're disconnecting */
+	if (vscsi->flags & (SCHEDULE_DISCONNECT | DISCONNECT_SCHEDULED)) {
+		ibmvscsis_free_cmd_resources(vscsi, cmd);
+
+		/* ibmvscsis_disconnect might be waiting for us */
+		if (list_empty(&vscsi->active_q) &&
+		    list_empty(&vscsi->schedule_q) &&
+		    (vscsi->flags & WAIT_FOR_IDLE)) {
+			vscsi->flags &= ~WAIT_FOR_IDLE;
+			complete(&vscsi->wait_idle);
+		}
+
+		spin_unlock_bh(&vscsi->intr_lock);
+		return;
+	}
+
+	spin_unlock_bh(&vscsi->intr_lock);
+
+	switch (cmd->type) {
+	case SCSI_CDB:
+		ibmvscsis_parse_cmd(vscsi, cmd);
+		break;
+	case TASK_MANAGEMENT:
+		ibmvscsis_parse_task(vscsi, cmd);
+		break;
+	default:
+		dev_err(&vscsi->dev, "scheduler, invalid cmd type %d\n",
+			cmd->type);
+		spin_lock_bh(&vscsi->intr_lock);
+		ibmvscsis_free_cmd_resources(vscsi, cmd);
+		spin_unlock_bh(&vscsi->intr_lock);
+		break;
+	}
+}
+
+static int ibmvscsis_alloc_cmds(struct scsi_info *vscsi, int num)
+{
+	struct ibmvscsis_cmd *cmd;
+	int i;
+
+	INIT_LIST_HEAD(&vscsi->free_cmd);
+	vscsi->cmd_pool = kcalloc(num, sizeof(struct ibmvscsis_cmd),
+				  GFP_KERNEL);
+	if (!vscsi->cmd_pool)
+		return -ENOMEM;
+
+	for (i = 0, cmd = (struct ibmvscsis_cmd *)vscsi->cmd_pool; i < num;
+	     i++, cmd++) {
+		cmd->adapter = vscsi;
+		INIT_WORK(&cmd->work, ibmvscsis_scheduler);
+		list_add_tail(&cmd->list, &vscsi->free_cmd);
+	}
+
+	return 0;
+}
+
+static void ibmvscsis_free_cmds(struct scsi_info *vscsi)
+{
+	kfree(vscsi->cmd_pool);
+	vscsi->cmd_pool = NULL;
+	INIT_LIST_HEAD(&vscsi->free_cmd);
+}
+
+/**
+ * ibmvscsis_service_wait_q() - Service Waiting Queue
+ * @timer:	Pointer to timer which has expired
+ *
+ * This routine is called when the timer pops to service the waiting
+ * queue. Elements on the queue have completed, their responses have been
+ * copied to the client, but the client's response queue was full so
+ * the queue message could not be sent. The routine grabs the proper locks
+ * and calls send messages.
+ *
+ * EXECUTION ENVIRONMENT:
+ *	called at interrupt level
+ */
+static enum hrtimer_restart ibmvscsis_service_wait_q(struct hrtimer *timer)
+{
+	struct timer_cb *p_timer = container_of(timer, struct timer_cb, timer);
+	struct scsi_info *vscsi = container_of(p_timer, struct scsi_info,
+					       rsp_q_timer);
+
+	spin_lock_bh(&vscsi->intr_lock);
+	p_timer->timer_pops += 1;
+	p_timer->started = false;
+	ibmvscsis_send_messages(vscsi);
+	spin_unlock_bh(&vscsi->intr_lock);
+
+	return HRTIMER_NORESTART;
+}
+
+static long ibmvscsis_alloctimer(struct scsi_info *vscsi)
+{
+	struct timer_cb *p_timer;
+
+	p_timer = &vscsi->rsp_q_timer;
+	hrtimer_init(&p_timer->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
+
+	p_timer->timer.function = ibmvscsis_service_wait_q;
+	p_timer->started = false;
+	p_timer->timer_pops = 0;
+
+	return ADAPT_SUCCESS;
+}
+
+static void ibmvscsis_freetimer(struct scsi_info *vscsi)
+{
+	struct timer_cb *p_timer;
+
+	p_timer = &vscsi->rsp_q_timer;
+
+	(void)hrtimer_cancel(&p_timer->timer);
+
+	p_timer->started = false;
+	p_timer->timer_pops = 0;
+}
+
+static irqreturn_t ibmvscsis_interrupt(int dummy, void *data)
+{
+	struct scsi_info *vscsi = data;
+
+	vio_disable_interrupts(vscsi->dma_dev);
+	tasklet_schedule(&vscsi->work_task);
+
+	return IRQ_HANDLED;
+}
+
+/**
+ * ibmvscsis_check_q() - Helper function to Check Init Message Valid
+ * @vscsi:	Pointer to our adapter structure
+ *
+ * Checks if a initialize message was queued by the initiatior
+ * while the timing window was open.  This function is called from
+ * probe after the CRQ is created and interrupts are enabled.
+ * It would only be used by adapters who wait for some event before
+ * completing the init handshake with the client.  For ibmvscsi, this
+ * event is waiting for the port to be enabled.
+ *
+ * EXECUTION ENVIRONMENT:
+ *	Process level only, interrupt lock held
+ */
+static long ibmvscsis_check_q(struct scsi_info *vscsi)
+{
+	uint format;
+	long rc;
+
+	rc = ibmvscsis_check_init_msg(vscsi, &format);
+	if (rc)
+		ibmvscsis_post_disconnect(vscsi, ERR_DISCONNECT_RECONNECT, 0);
+	else if (format == UNUSED_FORMAT)
+		vscsi->state = WAIT_ENABLED;
+	else
+		vscsi->state = PART_UP_WAIT_ENAB;
+
+	return rc;
+}
+
+/**
+ * ibmvscsis_enable_change_state() - Set new state based on enabled status
+ * @vscsi:	Pointer to our adapter structure
+ *
+ * This function determines our new state now that we are enabled.  This
+ * may involve sending an Init Complete message to the client.
+ *
+ * Must be called with interrupt lock held.
+ */
+static long ibmvscsis_enable_change_state(struct scsi_info *vscsi)
+{
+	long rc = ADAPT_SUCCESS;
+
+handle_state_change:
+	switch (vscsi->state) {
+	case WAIT_ENABLED:
+		rc = ibmvscsis_send_init_message(vscsi, INIT_MSG);
+		switch (rc) {
+		case H_SUCCESS:
+		case H_DROPPED:
+		case H_CLOSED:
+			vscsi->state =  WAIT_CONNECTION;
+			rc = ADAPT_SUCCESS;
+			break;
+
+		case H_PARAMETER:
+			break;
+
+		case H_HARDWARE:
+			break;
+
+		default:
+			vscsi->state = UNDEFINED;
+			rc = H_HARDWARE;
+			break;
+		}
+		break;
+	case PART_UP_WAIT_ENAB:
+		rc = ibmvscsis_send_init_message(vscsi, INIT_COMPLETE_MSG);
+		switch (rc) {
+		case H_SUCCESS:
+			vscsi->state = CONNECTED;
+			rc = ADAPT_SUCCESS;
+			break;
+
+		case H_DROPPED:
+		case H_CLOSED:
+			vscsi->state = WAIT_ENABLED;
+			goto handle_state_change;
+
+		case H_PARAMETER:
+			break;
+
+		case H_HARDWARE:
+			break;
+
+		default:
+			rc = H_HARDWARE;
+			break;
+		}
+		break;
+
+	case WAIT_CONNECTION:
+	case WAIT_IDLE:
+	case SRP_PROCESSING:
+	case CONNECTED:
+		rc = ADAPT_SUCCESS;
+		break;
+		/* should not be able to get here */
+	case UNCONFIGURING:
+		rc = ERROR;
+		vscsi->state = UNDEFINED;
+		break;
+
+		/* driver should never allow this to happen */
+	case ERR_DISCONNECT:
+	case ERR_DISCONNECT_RECONNECT:
+	default:
+		dev_err(&vscsi->dev, "in invalid state %d during enable_change_state\n",
+			vscsi->state);
+		rc = ADAPT_SUCCESS;
+		break;
+	}
+
+	return rc;
+}
+
+/**
+ * ibmvscsis_create_command_q() - Create Command Queue
+ * @vscsi:	Pointer to our adapter structure
+ * @num_cmds:	Currently unused.  In the future, may be used to determine
+ *		the size of the CRQ.
+ *
+ * Allocates memory for command queue maps remote memory into an ioba
+ * initializes the command response queue
+ *
+ * EXECUTION ENVIRONMENT:
+ *	Process level only
+ */
+static long ibmvscsis_create_command_q(struct scsi_info *vscsi, int num_cmds)
+{
+	long rc = 0;
+	int pages;
+	struct vio_dev *vdev = vscsi->dma_dev;
+
+	/* We might support multiple pages in the future, but just 1 for now */
+	pages = 1;
+
+	vscsi->cmd_q.size = pages;
+
+	vscsi->cmd_q.base_addr =
+		(struct viosrp_crq *)get_zeroed_page(GFP_KERNEL);
+	if (!vscsi->cmd_q.base_addr)
+		return -ENOMEM;
+
+	vscsi->cmd_q.mask = ((uint)pages * CRQ_PER_PAGE) - 1;
+
+	vscsi->cmd_q.crq_token = dma_map_single(&vdev->dev,
+						vscsi->cmd_q.base_addr,
+						PAGE_SIZE, DMA_BIDIRECTIONAL);
+	if (dma_mapping_error(&vdev->dev, vscsi->cmd_q.crq_token)) {
+		free_page((unsigned long)vscsi->cmd_q.base_addr);
+		return -ENOMEM;
+	}
+
+	rc =  h_reg_crq(vscsi->dds.unit_id, vscsi->cmd_q.crq_token, PAGE_SIZE);
+	if (rc) {
+		if (rc == H_CLOSED) {
+			vscsi->state = WAIT_ENABLED;
+			rc = 0;
+		} else {
+			dma_unmap_single(&vdev->dev, vscsi->cmd_q.crq_token,
+					 PAGE_SIZE, DMA_BIDIRECTIONAL);
+			free_page((unsigned long)vscsi->cmd_q.base_addr);
+			rc = -ENODEV;
+		}
+	} else {
+		vscsi->state = WAIT_ENABLED;
+	}
+
+	return rc;
+}
+
+/**
+ * ibmvscsis_destroy_command_q - Destroy Command Queue
+ * @vscsi:	Pointer to our adapter structure
+ *
+ * Releases memory for command queue and unmaps mapped remote memory.
+ *
+ * EXECUTION ENVIRONMENT:
+ *	Process level only
+ */
+static void ibmvscsis_destroy_command_q(struct scsi_info *vscsi)
+{
+	dma_unmap_single(&vscsi->dma_dev->dev, vscsi->cmd_q.crq_token,
+			 PAGE_SIZE, DMA_BIDIRECTIONAL);
+	free_page((unsigned long)vscsi->cmd_q.base_addr);
+	vscsi->cmd_q.base_addr = NULL;
+	vscsi->state = NO_QUEUE;
+}
+
+static u8 ibmvscsis_fast_fail(struct scsi_info *vscsi,
+			      struct ibmvscsis_cmd *cmd)
+{
+	struct iu_entry *iue = cmd->iue;
+	struct se_cmd *se_cmd = &cmd->se_cmd;
+	struct srp_cmd *srp = (struct srp_cmd *)iue->sbuf->buf;
+	struct scsi_sense_hdr sshdr;
+	u8 rc = se_cmd->scsi_status;
+
+	if (vscsi->fast_fail && (READ_CMD(srp->cdb) || WRITE_CMD(srp->cdb)))
+		if (scsi_normalize_sense(se_cmd->sense_buffer,
+					 se_cmd->scsi_sense_length, &sshdr))
+			if (sshdr.sense_key == HARDWARE_ERROR &&
+			    (se_cmd->residual_count == 0 ||
+			     se_cmd->residual_count == se_cmd->data_length)) {
+				rc = NO_SENSE;
+				cmd->flags |= CMD_FAST_FAIL;
+			}
+
+	return rc;
+}
+
+/**
+ * srp_build_response() - Build an SRP response buffer
+ * @vscsi:	Pointer to our adapter structure
+ * @cmd:	Pointer to command for which to send the response
+ * @len_p:	Where to return the length of the IU response sent.  This
+ *		is needed to construct the CRQ response.
+ *
+ * Build the SRP response buffer and copy it to the client's memory space.
+ */
+static long srp_build_response(struct scsi_info *vscsi,
+			       struct ibmvscsis_cmd *cmd, uint *len_p)
+{
+	struct iu_entry *iue = cmd->iue;
+	struct se_cmd *se_cmd = &cmd->se_cmd;
+	struct srp_rsp *rsp;
+	uint len;
+	u32 rsp_code;
+	char *data;
+	u32 *tsk_status;
+	long rc = ADAPT_SUCCESS;
+
+	spin_lock_bh(&vscsi->intr_lock);
+
+	rsp = &vio_iu(iue)->srp.rsp;
+	len = sizeof(*rsp);
+	memset(rsp, 0, len);
+	data = rsp->data;
+
+	rsp->opcode = SRP_RSP;
+
+	if (vscsi->credit > 0 && vscsi->state == SRP_PROCESSING)
+		rsp->req_lim_delta = cpu_to_be32(vscsi->credit);
+	else
+		rsp->req_lim_delta = cpu_to_be32(1 + vscsi->credit);
+	rsp->tag = cmd->rsp.tag;
+	rsp->flags = 0;
+
+	if (cmd->type == SCSI_CDB) {
+		rsp->status = ibmvscsis_fast_fail(vscsi, cmd);
+		if (rsp->status) {
+			pr_debug("build_resp: cmd %p, scsi status %d\n", cmd,
+				 (int)rsp->status);
+			ibmvscsis_determine_resid(se_cmd, rsp);
+			if (se_cmd->scsi_sense_length && se_cmd->sense_buffer) {
+				rsp->sense_data_len =
+					cpu_to_be32(se_cmd->scsi_sense_length);
+				rsp->flags |= SRP_RSP_FLAG_SNSVALID;
+				len += se_cmd->scsi_sense_length;
+				memcpy(data, se_cmd->sense_buffer,
+				       se_cmd->scsi_sense_length);
+			}
+			rsp->sol_not = (cmd->rsp.sol_not & UCSOLNT) >>
+				UCSOLNT_RESP_SHIFT;
+		} else if (cmd->flags & CMD_FAST_FAIL) {
+			pr_debug("build_resp: cmd %p, fast fail\n", cmd);
+			rsp->sol_not = (cmd->rsp.sol_not & UCSOLNT) >>
+				UCSOLNT_RESP_SHIFT;
+		} else {
+			rsp->sol_not = (cmd->rsp.sol_not & SCSOLNT) >>
+				SCSOLNT_RESP_SHIFT;
+		}
+	} else {
+		/* this is task management */
+		rsp->status = 0;
+		rsp->resp_data_len = cpu_to_be32(4);
+		rsp->flags |= SRP_RSP_FLAG_RSPVALID;
+
+		switch (se_cmd->se_tmr_req->response) {
+		case TMR_FUNCTION_COMPLETE:
+		case TMR_TASK_DOES_NOT_EXIST:
+			rsp_code = SRP_TASK_MANAGEMENT_FUNCTION_COMPLETE;
+			rsp->sol_not = (cmd->rsp.sol_not & SCSOLNT) >>
+				SCSOLNT_RESP_SHIFT;
+			break;
+		case TMR_TASK_MGMT_FUNCTION_NOT_SUPPORTED:
+		case TMR_LUN_DOES_NOT_EXIST:
+			rsp_code = SRP_TASK_MANAGEMENT_FUNCTION_NOT_SUPPORTED;
+			rsp->sol_not = (cmd->rsp.sol_not & UCSOLNT) >>
+				UCSOLNT_RESP_SHIFT;
+			break;
+		case TMR_FUNCTION_FAILED:
+		case TMR_FUNCTION_REJECTED:
+		default:
+			rsp_code = SRP_TASK_MANAGEMENT_FUNCTION_FAILED;
+			rsp->sol_not = (cmd->rsp.sol_not & UCSOLNT) >>
+				UCSOLNT_RESP_SHIFT;
+			break;
+		}
+
+		tsk_status = (u32 *)data;
+		*tsk_status = cpu_to_be32(rsp_code);
+		data = (char *)(tsk_status + 1);
+		len += 4;
+	}
+
+	dma_wmb();
+	rc = h_copy_rdma(len, vscsi->dds.window[LOCAL].liobn, iue->sbuf->dma,
+			 vscsi->dds.window[REMOTE].liobn,
+			 be64_to_cpu(iue->remote_token));
+
+	switch (rc) {
+	case H_SUCCESS:
+		vscsi->credit = 0;
+		*len_p = len;
+		break;
+	case H_PERMISSION:
+		if (connection_broken(vscsi))
+			vscsi->flags |= RESPONSE_Q_DOWN | CLIENT_FAILED;
+
+		dev_err(&vscsi->dev, "build_response: error copying to client, rc %ld, flags 0x%x, state 0x%hx\n",
+			rc, vscsi->flags, vscsi->state);
+		break;
+	case H_SOURCE_PARM:
+	case H_DEST_PARM:
+	default:
+		dev_err(&vscsi->dev, "build_response: error copying to client, rc %ld\n",
+			rc);
+		break;
+	}
+
+	spin_unlock_bh(&vscsi->intr_lock);
+
+	return rc;
+}
+
+static int ibmvscsis_rdma(struct ibmvscsis_cmd *cmd, struct scatterlist *sg,
+			  int nsg, struct srp_direct_buf *md, int nmd,
+			  enum dma_data_direction dir, unsigned int bytes)
+{
+	struct iu_entry *iue = cmd->iue;
+	struct srp_target *target = iue->target;
+	struct scsi_info *vscsi = target->ldata;
+	struct scatterlist *sgp;
+	dma_addr_t client_ioba, server_ioba;
+	ulong buf_len;
+	ulong client_len, server_len;
+	int md_idx;
+	long tx_len;
+	long rc = 0;
+
+	if (bytes == 0)
+		return 0;
+
+	sgp = sg;
+	client_len = 0;
+	server_len = 0;
+	md_idx = 0;
+	tx_len = bytes;
+
+	do {
+		if (client_len == 0) {
+			if (md_idx >= nmd) {
+				dev_err(&vscsi->dev, "rdma: ran out of client memory descriptors\n");
+				rc = -EIO;
+				break;
+			}
+			client_ioba = be64_to_cpu(md[md_idx].va);
+			client_len = be32_to_cpu(md[md_idx].len);
+		}
+		if (server_len == 0) {
+			if (!sgp) {
+				dev_err(&vscsi->dev, "rdma: ran out of scatter/gather list\n");
+				rc = -EIO;
+				break;
+			}
+			server_ioba = sg_dma_address(sgp);
+			server_len = sg_dma_len(sgp);
+		}
+
+		buf_len = tx_len;
+
+		if (buf_len > client_len)
+			buf_len = client_len;
+
+		if (buf_len > server_len)
+			buf_len = server_len;
+
+		if (buf_len > max_vdma_size)
+			buf_len = max_vdma_size;
+
+		if (dir == DMA_TO_DEVICE) {
+			/* read from client */
+			rc = h_copy_rdma(buf_len,
+					 vscsi->dds.window[REMOTE].liobn,
+					 client_ioba,
+					 vscsi->dds.window[LOCAL].liobn,
+					 server_ioba);
+		} else {
+			/* write to client */
+			struct srp_cmd *srp = (struct srp_cmd *)iue->sbuf->buf;
+
+			/* The h_copy_rdma will cause phyp, running in another
+			 * partition, to read memory, so we need to make sure
+			 * the data has been written out, hence these syncs.
+			 */
+			/* ensure that everything is in memory */
+			isync();
+			/* ensure that memory has been made visible */
+			dma_wmb();
+			rc = h_copy_rdma(buf_len,
+					 vscsi->dds.window[LOCAL].liobn,
+					 server_ioba,
+					 vscsi->dds.window[REMOTE].liobn,
+					 client_ioba);
+		}
+		switch (rc) {
+		case H_SUCCESS:
+			break;
+		case H_PERMISSION:
+		case H_SOURCE_PARM:
+		case H_DEST_PARM:
+			if (connection_broken(vscsi)) {
+				spin_lock_bh(&vscsi->intr_lock);
+				vscsi->flags |=
+					(RESPONSE_Q_DOWN | CLIENT_FAILED);
+				spin_unlock_bh(&vscsi->intr_lock);
+			}
+			dev_err(&vscsi->dev, "rdma: h_copy_rdma failed, rc %ld\n",
+				rc);
+			break;
+
+		default:
+			dev_err(&vscsi->dev, "rdma: unknown error %ld from h_copy_rdma\n",
+				rc);
+			break;
+		}
+
+		if (!rc) {
+			tx_len -= buf_len;
+			if (tx_len) {
+				client_len -= buf_len;
+				if (client_len == 0)
+					md_idx++;
+				else
+					client_ioba += buf_len;
+
+				server_len -= buf_len;
+				if (server_len == 0)
+					sgp = sg_next(sgp);
+				else
+					server_ioba += buf_len;
+			} else {
+				break;
+			}
+		}
+	} while (!rc);
+
+	return rc;
+}
+
+/**
+ * ibmvscsis_handle_crq() - Handle CRQ
+ * @data:	Pointer to our adapter structure
+ *
+ * Read the command elements from the command queue and copy the payloads
+ * associated with the command elements to local memory and execute the
+ * SRP requests.
+ *
+ * Note: this is an edge triggered interrupt. It can not be shared.
+ */
+static void ibmvscsis_handle_crq(unsigned long data)
+{
+	struct scsi_info *vscsi = (struct scsi_info *)data;
+	struct viosrp_crq *crq;
+	long rc;
+	bool ack = true;
+	volatile u8 valid;
+
+	spin_lock_bh(&vscsi->intr_lock);
+
+	pr_debug("got interrupt\n");
+
+	/*
+	 * if we are in a path where we are waiting for all pending commands
+	 * to complete because we received a transport event and anything in
+	 * the command queue is for a new connection,  do nothing
+	 */
+	if (TARGET_STOP(vscsi)) {
+		vio_enable_interrupts(vscsi->dma_dev);
+
+		pr_debug("handle_crq, don't process: flags 0x%x, state 0x%hx\n",
+			 vscsi->flags, vscsi->state);
+		spin_unlock_bh(&vscsi->intr_lock);
+		return;
+	}
+
+	rc = vscsi->flags & SCHEDULE_DISCONNECT;
+	crq = vscsi->cmd_q.base_addr + vscsi->cmd_q.index;
+	valid = crq->valid;
+	dma_rmb();
+
+	while (valid) {
+		/*
+		 * These are edege triggered interrupts. After dropping out of
+		 * the while loop, the code must check for work since an
+		 * interrupt could be lost, and an elment be left on the queue,
+		 * hence the label.
+		 */
+cmd_work:
+		vscsi->cmd_q.index =
+			(vscsi->cmd_q.index + 1) & vscsi->cmd_q.mask;
+
+		if (!rc) {
+			rc = ibmvscsis_parse_command(vscsi, crq);
+		} else {
+			if ((uint)crq->valid == VALID_TRANS_EVENT) {
+				/*
+				 * must service the transport layer events even
+				 * in an error state, dont break out until all
+				 * the consecutive transport events have been
+				 * processed
+				 */
+				rc = ibmvscsis_trans_event(vscsi, crq);
+			} else if (vscsi->flags & TRANS_EVENT) {
+				/*
+				 * if a transport event has occurred leave
+				 * everything but transport events on the queue
+				 *
+				 * need to decrement the queue index so we can
+				 * look at the elment again
+				 */
+				if (vscsi->cmd_q.index)
+					vscsi->cmd_q.index -= 1;
+				else
+					/*
+					 * index is at 0 it just wrapped.
+					 * have it index last element in q
+					 */
+					vscsi->cmd_q.index = vscsi->cmd_q.mask;
+				break;
+			}
+		}
+
+		crq->valid = INVALIDATE_CMD_RESP_EL;
+
+		crq = vscsi->cmd_q.base_addr + vscsi->cmd_q.index;
+		valid = crq->valid;
+		dma_rmb();
+	}
+
+	if (!rc) {
+		if (ack) {
+			vio_enable_interrupts(vscsi->dma_dev);
+			ack = false;
+			pr_debug("handle_crq, reenabling interrupts\n");
+		}
+		valid = crq->valid;
+		dma_rmb();
+		if (valid)
+			goto cmd_work;
+	} else {
+		pr_debug("handle_crq, error: flags 0x%x, state 0x%hx, crq index 0x%x\n",
+			 vscsi->flags, vscsi->state, vscsi->cmd_q.index);
+	}
+
+	pr_debug("Leaving handle_crq: schedule_q empty %d, flags 0x%x, state 0x%hx\n",
+		 (int)list_empty(&vscsi->schedule_q), vscsi->flags,
+		 vscsi->state);
+
+	spin_unlock_bh(&vscsi->intr_lock);
+}
+
+static int ibmvscsis_probe(struct vio_dev *vdev,
+			   const struct vio_device_id *id)
+{
+	struct scsi_info *vscsi;
+	int rc = 0;
+	long hrc = 0;
+	char wq_name[24];
+
+	vscsi = kzalloc(sizeof(*vscsi), GFP_KERNEL);
+	if (!vscsi) {
+		rc = -ENOMEM;
+		pr_err("probe: allocation of adapter failed\n");
+		return rc;
+	}
+
+	vscsi->dma_dev = vdev;
+	vscsi->dev = vdev->dev;
+	INIT_LIST_HEAD(&vscsi->schedule_q);
+	INIT_LIST_HEAD(&vscsi->waiting_rsp);
+	INIT_LIST_HEAD(&vscsi->active_q);
+
+	snprintf(vscsi->tport.tport_name, 256, "%s", dev_name(&vdev->dev));
+
+	pr_debug("probe tport_name: %s\n", vscsi->tport.tport_name);
+
+	rc = read_dma_window(vscsi);
+	if (rc)
+		goto free_adapter;
+	pr_debug("Probe: liobn 0x%x, riobn 0x%x\n",
+		 vscsi->dds.window[LOCAL].liobn,
+		 vscsi->dds.window[REMOTE].liobn);
+
+	strcpy(vscsi->eye, "VSCSI ");
+	strncat(vscsi->eye, vdev->name, MAX_EYE);
+
+	vscsi->dds.unit_id = vdev->unit_address;
+
+	spin_lock_bh(&ibmvscsis_dev_lock);
+	list_add_tail(&vscsi->list, &ibmvscsis_dev_list);
+	spin_unlock_bh(&ibmvscsis_dev_lock);
+
+	/*
+	 * TBD: How do we determine # of cmds to request?  Do we know how
+	 * many "children" we have?
+	 */
+	vscsi->request_limit = INITIAL_SRP_LIMIT;
+	rc = srp_target_alloc(&vscsi->target, &vdev->dev, vscsi->request_limit,
+			      SRP_MAX_IU_LEN);
+	if (rc)
+		goto rem_list;
+
+	vscsi->target.ldata = vscsi;
+
+	rc = ibmvscsis_alloc_cmds(vscsi, vscsi->request_limit);
+	if (rc) {
+		dev_err(&vscsi->dev, "alloc_cmds failed, rc %d, num %d\n",
+			rc, vscsi->request_limit);
+		goto free_target;
+	}
+
+	/*
+	 * Note: the lock is used in freeing timers, so must initialize
+	 * first so that ordering in case of error is correct.
+	 */
+	spin_lock_init(&vscsi->intr_lock);
+
+	rc = ibmvscsis_alloctimer(vscsi);
+	if (rc) {
+		dev_err(&vscsi->dev, "probe: alloctimer failed, rc %d\n", rc);
+		goto free_cmds;
+	}
+
+	rc = ibmvscsis_create_command_q(vscsi, 256);
+	if (rc) {
+		dev_err(&vscsi->dev, "probe: create_command_q failed, rc %d\n",
+			rc);
+		goto free_timer;
+	}
+
+	vscsi->map_buf = kzalloc(PAGE_SIZE, GFP_KERNEL);
+	if (!vscsi->map_buf) {
+		rc = -ENOMEM;
+		dev_err(&vscsi->dev, "probe: allocating cmd buffer failed\n");
+		goto destroy_queue;
+	}
+
+	vscsi->map_ioba = dma_map_single(&vdev->dev, vscsi->map_buf, PAGE_SIZE,
+					 DMA_BIDIRECTIONAL);
+	if (dma_mapping_error(&vdev->dev, vscsi->map_ioba)) {
+		dev_err(&vscsi->dev, "probe: error mapping command buffer\n");
+		goto free_buf;
+	}
+
+	hrc = h_vioctl(vscsi->dds.unit_id, H_GET_PARTNER_INFO,
+		       (u64)vscsi->map_ioba | ((u64)PAGE_SIZE << 32), 0, 0, 0,
+		       0);
+	if (hrc == H_SUCCESS)
+		vscsi->client_data.partition_number =
+			be64_to_cpu(*(u64 *)vscsi->map_buf);
+	/*
+	 * We expect the VIOCTL to fail if we're configured as "any
+	 * client can connect" and the client isn't activated yet.
+	 * We'll make the call again when he sends an init msg.
+	 */
+	pr_debug("probe hrc %ld, client partition num %d\n",
+		 hrc, vscsi->client_data.partition_number);
+
+	tasklet_init(&vscsi->work_task, ibmvscsis_handle_crq,
+		     (unsigned long)vscsi);
+
+	init_completion(&vscsi->wait_idle);
+
+	snprintf(wq_name, 24, "ibmvscsis%s", dev_name(&vdev->dev));
+	vscsi->work_q = create_workqueue(wq_name);
+	if (!vscsi->work_q) {
+		rc = -ENOMEM;
+		dev_err(&vscsi->dev, "create_workqueue failed\n");
+		goto unmap_buf;
+	}
+
+	rc = request_irq(vdev->irq, ibmvscsis_interrupt, 0, "ibmvscsis", vscsi);
+	if (rc) {
+		rc = -EPERM;
+		dev_err(&vscsi->dev, "probe: request_irq failed, rc %d\n", rc);
+		goto destroy_WQ;
+	}
+
+	spin_lock_bh(&vscsi->intr_lock);
+	vio_enable_interrupts(vdev);
+	if (rc) {
+		dev_err(&vscsi->dev, "enabling interrupts failed, rc %d\n", rc);
+		rc = -ENODEV;
+		spin_unlock_bh(&vscsi->intr_lock);
+		goto free_irq;
+	}
+
+	if (ibmvscsis_check_q(vscsi)) {
+		rc = ERROR;
+		dev_err(&vscsi->dev, "probe: check_q failed, rc %d\n", rc);
+		spin_unlock_bh(&vscsi->intr_lock);
+		goto disable_interrupt;
+	}
+	spin_unlock_bh(&vscsi->intr_lock);
+
+	dev_set_drvdata(&vdev->dev, vscsi);
+
+	return 0;
+
+disable_interrupt:
+	vio_disable_interrupts(vdev);
+free_irq:
+	free_irq(vdev->irq, vscsi);
+destroy_WQ:
+	destroy_workqueue(vscsi->work_q);
+unmap_buf:
+	dma_unmap_single(&vdev->dev, vscsi->map_ioba, PAGE_SIZE,
+			 DMA_BIDIRECTIONAL);
+free_buf:
+	kfree(vscsi->map_buf);
+destroy_queue:
+	tasklet_kill(&vscsi->work_task);
+	ibmvscsis_unregister_command_q(vscsi);
+	ibmvscsis_destroy_command_q(vscsi);
+free_timer:
+	ibmvscsis_freetimer(vscsi);
+free_cmds:
+	ibmvscsis_free_cmds(vscsi);
+free_target:
+	srp_target_free(&vscsi->target);
+rem_list:
+	spin_lock_bh(&ibmvscsis_dev_lock);
+	list_del(&vscsi->list);
+	spin_unlock_bh(&ibmvscsis_dev_lock);
+free_adapter:
+	kfree(vscsi);
+
+	return rc;
+}
+
+static int ibmvscsis_remove(struct vio_dev *vdev)
+{
+	struct scsi_info *vscsi = dev_get_drvdata(&vdev->dev);
+
+	pr_debug("remove (%s)\n", dev_name(&vscsi->dma_dev->dev));
+
+	/*
+	 * TBD: Need to handle if there are commands on the waiting_rsp q
+	 *      Actually, can there still be cmds outstanding to tcm?
+	 */
+
+	vio_disable_interrupts(vdev);
+	free_irq(vdev->irq, vscsi);
+	destroy_workqueue(vscsi->work_q);
+	dma_unmap_single(&vdev->dev, vscsi->map_ioba, PAGE_SIZE,
+			 DMA_BIDIRECTIONAL);
+	kfree(vscsi->map_buf);
+	tasklet_kill(&vscsi->work_task);
+	ibmvscsis_unregister_command_q(vscsi);
+	ibmvscsis_destroy_command_q(vscsi);
+	ibmvscsis_freetimer(vscsi);
+	ibmvscsis_free_cmds(vscsi);
+	srp_target_free(&vscsi->target);
+	spin_lock_bh(&ibmvscsis_dev_lock);
+	list_del(&vscsi->list);
+	spin_unlock_bh(&ibmvscsis_dev_lock);
+	kfree(vscsi);
+
+	return 0;
+}
+
+static ssize_t system_id_show(struct device *dev,
+			      struct device_attribute *attr, char *buf)
+{
+	return snprintf(buf, PAGE_SIZE, "%s\n", system_id);
+}
+
+static ssize_t partition_number_show(struct device *dev,
+				     struct device_attribute *attr, char *buf)
+{
+	return snprintf(buf, PAGE_SIZE, "%x\n", partition_number);
+}
+
+static ssize_t unit_address_show(struct device *dev,
+				 struct device_attribute *attr, char *buf)
+{
+	struct scsi_info *vscsi = container_of(dev, struct scsi_info, dev);
+
+	return snprintf(buf, PAGE_SIZE, "%x\n", vscsi->dma_dev->unit_address);
+}
+
+static int ibmvscsis_get_system_info(void)
+{
+	struct device_node *rootdn, *vdevdn;
+	const char *id, *model, *name;
+	const uint *num;
+
+	rootdn = of_find_node_by_path("/");
+	if (!rootdn)
+		return -ENOENT;
+
+	model = of_get_property(rootdn, "model", NULL);
+	id = of_get_property(rootdn, "system-id", NULL);
+	if (model && id)
+		snprintf(system_id, sizeof(system_id), "%s-%s", model, id);
+
+	name = of_get_property(rootdn, "ibm,partition-name", NULL);
+	if (name)
+		strncpy(partition_name, name, sizeof(partition_name));
+
+	num = of_get_property(rootdn, "ibm,partition-no", NULL);
+	if (num)
+		partition_number = *num;
+
+	of_node_put(rootdn);
+
+	vdevdn = of_find_node_by_path("/vdevice");
+	if (vdevdn) {
+		const uint *mvds;
+
+		mvds = of_get_property(vdevdn, "ibm,max-virtual-dma-size",
+				       NULL);
+		if (mvds)
+			max_vdma_size = *mvds;
+		of_node_put(vdevdn);
+	}
+
+	return 0;
+}
+
+static char *ibmvscsis_get_fabric_name(void)
+{
+	return "ibmvscsis";
+}
+
+static char *ibmvscsis_get_fabric_wwn(struct se_portal_group *se_tpg)
+{
+	struct ibmvscsis_tport *tport =
+		container_of(se_tpg, struct ibmvscsis_tport, se_tpg);
+
+	return tport->tport_name;
+}
+
+static u16 ibmvscsis_get_tag(struct se_portal_group *se_tpg)
+{
+	struct ibmvscsis_tport *tport =
+		container_of(se_tpg, struct ibmvscsis_tport, se_tpg);
+
+	return tport->tport_tpgt;
+}
+
+static u32 ibmvscsis_get_default_depth(struct se_portal_group *se_tpg)
+{
+	return 1;
+}
+
+static int ibmvscsis_check_true(struct se_portal_group *se_tpg)
+{
+	return 1;
+}
+
+static int ibmvscsis_check_false(struct se_portal_group *se_tpg)
+{
+	return 0;
+}
+
+static u32 ibmvscsis_tpg_get_inst_index(struct se_portal_group *se_tpg)
+{
+	return 1;
+}
+
+static int ibmvscsis_check_stop_free(struct se_cmd *se_cmd)
+{
+	return target_put_sess_cmd(se_cmd);
+}
+
+static void ibmvscsis_release_cmd(struct se_cmd *se_cmd)
+{
+	struct ibmvscsis_cmd *cmd = container_of(se_cmd, struct ibmvscsis_cmd,
+						 se_cmd);
+	struct scsi_info *vscsi = cmd->adapter;
+
+	spin_lock_bh(&vscsi->intr_lock);
+	/* Remove from active_q */
+	list_del(&cmd->list);
+	list_add_tail(&cmd->list, &vscsi->waiting_rsp);
+	ibmvscsis_send_messages(vscsi);
+	spin_unlock_bh(&vscsi->intr_lock);
+}
+
+static u32 ibmvscsis_sess_get_index(struct se_session *se_sess)
+{
+	return 0;
+}
+
+static int ibmvscsis_write_pending(struct se_cmd *se_cmd)
+{
+	struct ibmvscsis_cmd *cmd = container_of(se_cmd, struct ibmvscsis_cmd,
+						 se_cmd);
+	struct iu_entry *iue = cmd->iue;
+	int rc;
+
+	rc = srp_transfer_data(cmd, &vio_iu(iue)->srp.cmd, ibmvscsis_rdma,
+			       1, 1);
+	if (rc) {
+		pr_err("srp_transfer_data() failed: %d\n", rc);
+		return -EAGAIN;
+	}
+	/*
+	 * We now tell TCM to add this WRITE CDB directly into the TCM storage
+	 * object execution queue.
+	 */
+	target_execute_cmd(se_cmd);
+	return 0;
+}
+
+static int ibmvscsis_write_pending_status(struct se_cmd *se_cmd)
+{
+	return 0;
+}
+
+static void ibmvscsis_set_default_node_attrs(struct se_node_acl *nacl)
+{
+}
+
+static int ibmvscsis_get_cmd_state(struct se_cmd *se_cmd)
+{
+	return 0;
+}
+
+static int ibmvscsis_queue_data_in(struct se_cmd *se_cmd)
+{
+	struct ibmvscsis_cmd *cmd = container_of(se_cmd, struct ibmvscsis_cmd,
+						 se_cmd);
+	struct iu_entry *iue = cmd->iue;
+	struct scsi_info *vscsi = cmd->adapter;
+	char *sd;
+	uint len = 0;
+	int rc;
+
+	rc = srp_transfer_data(cmd, &vio_iu(iue)->srp.cmd, ibmvscsis_rdma, 1,
+			       1);
+	if (rc) {
+		pr_err("srp_transfer_data failed: %d\n", rc);
+		sd = se_cmd->sense_buffer;
+		se_cmd->scsi_sense_length = 18;
+		memset(se_cmd->sense_buffer, 0, se_cmd->scsi_sense_length);
+		/* Logical Unit Communication Time-out asc/ascq = 0x0801 */
+		scsi_build_sense_buffer(0, se_cmd->sense_buffer, MEDIUM_ERROR,
+					0x08, 0x01);
+	}
+
+	srp_build_response(vscsi, cmd, &len);
+	cmd->rsp.format = SRP_FORMAT;
+	cmd->rsp.len = len;
+
+	return 0;
+}
+
+static int ibmvscsis_queue_status(struct se_cmd *se_cmd)
+{
+	struct ibmvscsis_cmd *cmd = container_of(se_cmd, struct ibmvscsis_cmd,
+						 se_cmd);
+	struct scsi_info *vscsi = cmd->adapter;
+	uint len;
+
+	pr_debug("queue_status %p\n", se_cmd);
+
+	srp_build_response(vscsi, cmd, &len);
+	cmd->rsp.format = SRP_FORMAT;
+	cmd->rsp.len = len;
+
+	return 0;
+}
+
+static void ibmvscsis_queue_tm_rsp(struct se_cmd *se_cmd)
+{
+	struct ibmvscsis_cmd *cmd = container_of(se_cmd, struct ibmvscsis_cmd,
+						 se_cmd);
+	struct scsi_info *vscsi = cmd->adapter;
+	uint len;
+
+	pr_debug("queue_tm_rsp %p, status %d\n",
+		 se_cmd, (int)se_cmd->se_tmr_req->response);
+
+	srp_build_response(vscsi, cmd, &len);
+	cmd->rsp.format = SRP_FORMAT;
+	cmd->rsp.len = len;
+}
+
+static void ibmvscsis_aborted_task(struct se_cmd *se_cmd)
+{
+	/* TBD: What (if anything) should we do here? */
+	pr_debug("ibmvscsis_aborted_task %p\n", se_cmd);
+}
+
+static struct se_wwn *ibmvscsis_make_tport(struct target_fabric_configfs *tf,
+					   struct config_group *group,
+					   const char *name)
+{
+	struct ibmvscsis_tport *tport;
+
+	tport = ibmvscsis_lookup_port(name);
+	if (tport) {
+		tport->tport_proto_id = SCSI_PROTOCOL_SRP;
+		pr_debug("make_tport(%s), pointer:%p, tport_id:%x\n",
+			 name, tport, tport->tport_proto_id);
+		return &tport->tport_wwn;
+	}
+
+	return ERR_PTR(-EINVAL);
+}
+
+static void ibmvscsis_drop_tport(struct se_wwn *wwn)
+{
+	struct ibmvscsis_tport *tport = container_of(wwn,
+						     struct ibmvscsis_tport,
+						     tport_wwn);
+
+	pr_debug("drop_tport(%s)\n",
+		 config_item_name(&tport->tport_wwn.wwn_group.cg_item));
+}
+
+static struct se_portal_group *ibmvscsis_make_tpg(struct se_wwn *wwn,
+						  struct config_group *group,
+						  const char *name)
+{
+	struct ibmvscsis_tport *tport =
+		container_of(wwn, struct ibmvscsis_tport, tport_wwn);
+	int rc;
+
+	tport->releasing = false;
+
+	rc = core_tpg_register(&tport->tport_wwn, &tport->se_tpg,
+			       tport->tport_proto_id);
+	if (rc)
+		return ERR_PTR(rc);
+
+	return &tport->se_tpg;
+}
+
+static void ibmvscsis_drop_tpg(struct se_portal_group *se_tpg)
+{
+	struct ibmvscsis_tport *tport = container_of(se_tpg,
+						     struct ibmvscsis_tport,
+						     se_tpg);
+
+	tport->releasing = true;
+	tport->enabled = false;
+
+	/*
+	 * Release the virtual I_T Nexus for this ibmvscsis TPG
+	 */
+	ibmvscsis_drop_nexus(tport);
+	/*
+	 * Deregister the se_tpg from TCM..
+	 */
+	core_tpg_deregister(se_tpg);
+}
+
+static ssize_t ibmvscsis_wwn_version_show(struct config_item *item,
+					  char *page)
+{
+	return scnprintf(page, PAGE_SIZE, "%s\n", IBMVSCSIS_VERSION);
+}
+CONFIGFS_ATTR_RO(ibmvscsis_wwn_, version);
+
+static struct configfs_attribute *ibmvscsis_wwn_attrs[] = {
+	&ibmvscsis_wwn_attr_version,
+	NULL,
+};
+
+static ssize_t ibmvscsis_tpg_enable_show(struct config_item *item,
+					 char *page)
+{
+	struct se_portal_group *se_tpg = to_tpg(item);
+	struct ibmvscsis_tport *tport = container_of(se_tpg,
+						     struct ibmvscsis_tport,
+						     se_tpg);
+
+	return snprintf(page, PAGE_SIZE, "%d\n", (tport->enabled) ? 1 : 0);
+}
+
+static ssize_t ibmvscsis_tpg_enable_store(struct config_item *item,
+					  const char *page, size_t count)
+{
+	struct se_portal_group *se_tpg = to_tpg(item);
+	struct ibmvscsis_tport *tport = container_of(se_tpg,
+						     struct ibmvscsis_tport,
+						     se_tpg);
+	struct scsi_info *vscsi = container_of(tport, struct scsi_info, tport);
+	unsigned long tmp;
+	int rc;
+	long lrc;
+
+	rc = kstrtoul(page, 0, &tmp);
+	if (rc < 0) {
+		pr_err("Unable to extract srpt_tpg_store_enable\n");
+		return -EINVAL;
+	}
+
+	if ((tmp != 0) && (tmp != 1)) {
+		pr_err("Illegal value for srpt_tpg_store_enable\n");
+		return -EINVAL;
+	}
+
+	if (tmp) {
+		tport->enabled = true;
+		spin_lock_bh(&vscsi->intr_lock);
+		lrc = ibmvscsis_enable_change_state(vscsi);
+		if (lrc)
+			pr_err("enable_change_state failed, rc %ld state %d\n",
+			       lrc, vscsi->state);
+		spin_unlock_bh(&vscsi->intr_lock);
+	} else {
+		tport->enabled = false;
+	}
+
+	pr_debug("tpg_enable_store, state %d\n", vscsi->state);
+
+	return count;
+}
+CONFIGFS_ATTR(ibmvscsis_tpg_, enable);
+
+static struct configfs_attribute *ibmvscsis_tpg_attrs[] = {
+	&ibmvscsis_tpg_attr_enable,
+	NULL,
+};
+
+static const struct target_core_fabric_ops ibmvscsis_ops = {
+	.module				= THIS_MODULE,
+	.name				= "ibmvscsis",
+	.get_fabric_name		= ibmvscsis_get_fabric_name,
+	.tpg_get_wwn			= ibmvscsis_get_fabric_wwn,
+	.tpg_get_tag			= ibmvscsis_get_tag,
+	.tpg_get_default_depth		= ibmvscsis_get_default_depth,
+	.tpg_check_demo_mode		= ibmvscsis_check_true,
+	.tpg_check_demo_mode_cache	= ibmvscsis_check_true,
+	.tpg_check_demo_mode_write_protect = ibmvscsis_check_false,
+	.tpg_check_prod_mode_write_protect = ibmvscsis_check_false,
+	.tpg_get_inst_index		= ibmvscsis_tpg_get_inst_index,
+	.check_stop_free		= ibmvscsis_check_stop_free,
+	.release_cmd			= ibmvscsis_release_cmd,
+	.sess_get_index			= ibmvscsis_sess_get_index,
+	.write_pending			= ibmvscsis_write_pending,
+	.write_pending_status		= ibmvscsis_write_pending_status,
+	.set_default_node_attributes	= ibmvscsis_set_default_node_attrs,
+	.get_cmd_state			= ibmvscsis_get_cmd_state,
+	.queue_data_in			= ibmvscsis_queue_data_in,
+	.queue_status			= ibmvscsis_queue_status,
+	.queue_tm_rsp			= ibmvscsis_queue_tm_rsp,
+	.aborted_task			= ibmvscsis_aborted_task,
+	/*
+	 * Setup function pointers for logic in target_core_fabric_configfs.c
+	 */
+	.fabric_make_wwn		= ibmvscsis_make_tport,
+	.fabric_drop_wwn		= ibmvscsis_drop_tport,
+	.fabric_make_tpg		= ibmvscsis_make_tpg,
+	.fabric_drop_tpg		= ibmvscsis_drop_tpg,
+
+	.tfc_wwn_attrs			= ibmvscsis_wwn_attrs,
+	.tfc_tpg_base_attrs		= ibmvscsis_tpg_attrs,
+};
+
+static void ibmvscsis_dev_release(struct device *dev) {};
+
+static struct class_attribute ibmvscsis_class_attrs[] = {
+	__ATTR_NULL,
+};
+
+static struct device_attribute dev_attr_system_id =
+	__ATTR(system_id, S_IRUGO, system_id_show, NULL);
+
+static struct device_attribute dev_attr_partition_number =
+	__ATTR(partition_number, S_IRUGO, partition_number_show, NULL);
+
+static struct device_attribute dev_attr_unit_address =
+	__ATTR(unit_address, S_IRUGO, unit_address_show, NULL);
+
+static struct attribute *ibmvscsis_dev_attrs[] = {
+	&dev_attr_system_id.attr,
+	&dev_attr_partition_number.attr,
+	&dev_attr_unit_address.attr,
+};
+ATTRIBUTE_GROUPS(ibmvscsis_dev);
+
+static struct class ibmvscsis_class = {
+	.name           = "ibmvscsis",
+	.dev_release    = ibmvscsis_dev_release,
+	.class_attrs    = ibmvscsis_class_attrs,
+	.dev_groups     = ibmvscsis_dev_groups,
+};
+
+static struct vio_device_id ibmvscsis_device_table[] = {
+	{ "v-scsi-host", "IBM,v-scsi-host" },
+	{ "", "" }
+};
+MODULE_DEVICE_TABLE(vio, ibmvscsis_device_table);
+
+static struct vio_driver ibmvscsis_driver = {
+	.name = "ibmvscsis",
+	.id_table = ibmvscsis_device_table,
+	.probe = ibmvscsis_probe,
+	.remove = ibmvscsis_remove,
+};
+
+/*
+ * ibmvscsis_init() - Kernel Module initialization
+ *
+ * Note: vio_register_driver() registers callback functions, and at least one
+ * of those callback functions calls TCM - Linux IO Target Subsystem, thus
+ * the SCSI Target template must be registered before vio_register_driver()
+ * is called.
+ */
+static int __init ibmvscsis_init(void)
+{
+	int rc = 0;
+
+	rc = ibmvscsis_get_system_info();
+	if (rc) {
+		pr_err("rc %d from get_system_info\n", rc);
+		goto out;
+	}
+
+	rc = class_register(&ibmvscsis_class);
+	if (rc) {
+		pr_err("failed class register\n");
+		goto out;
+	}
+
+	rc = target_register_template(&ibmvscsis_ops);
+	if (rc) {
+		pr_err("rc %d from target_register_template\n", rc);
+		goto unregister_class;
+	}
+
+	rc = vio_register_driver(&ibmvscsis_driver);
+	if (rc) {
+		pr_err("rc %d from vio_register_driver\n", rc);
+		goto unregister_target;
+	}
+
+	return 0;
+
+unregister_target:
+	target_unregister_template(&ibmvscsis_ops);
+unregister_class:
+	class_unregister(&ibmvscsis_class);
+out:
+	return rc;
+}
+
+static void __exit ibmvscsis_exit(void)
+{
+	pr_info("Unregister IBM virtual SCSI host driver\n");
+	vio_unregister_driver(&ibmvscsis_driver);
+	target_unregister_template(&ibmvscsis_ops);
+	class_unregister(&ibmvscsis_class);
+}
+
+MODULE_DESCRIPTION("IBMVSCSIS fabric driver");
+MODULE_AUTHOR("Bryant G. Ly and Michael Cyr");
+MODULE_LICENSE("GPL");
+MODULE_VERSION(IBMVSCSIS_VERSION);
+module_init(ibmvscsis_init);
+module_exit(ibmvscsis_exit);
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.h
@@ -0,0 +1,346 @@
+/*******************************************************************************
+ * IBM Virtual SCSI Target Driver
+ * Copyright (C) 2003-2005 Dave Boutcher (boutcher@us.ibm.com) IBM Corp.
+ *			   Santiago Leon (santil@us.ibm.com) IBM Corp.
+ *			   Linda Xie (lxie@us.ibm.com) IBM Corp.
+ *
+ * Copyright (C) 2005-2011 FUJITA Tomonori <tomof@acm.org>
+ * Copyright (C) 2010 Nicholas A. Bellinger <nab@kernel.org>
+ * Copyright (C) 2016 Bryant G. Ly <bryantly@linux.vnet.ibm.com> IBM Corp.
+ *
+ * Authors: Bryant G. Ly <bryantly@linux.vnet.ibm.com>
+ * Authors: Michael Cyr <mikecyr@linux.vnet.ibm.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ ****************************************************************************/
+
+#ifndef __H_IBMVSCSI_TGT
+#define __H_IBMVSCSI_TGT
+
+#include "libsrp.h"
+
+#define SYS_ID_NAME_LEN		64
+#define PARTITION_NAMELEN	96
+#define IBMVSCSIS_NAMELEN       32
+
+#define MSG_HI  0
+#define MSG_LOW 1
+
+#define MAX_CMD_Q_PAGES       4
+#define CRQ_PER_PAGE          (PAGE_SIZE / sizeof(struct viosrp_crq))
+/* in terms of number of elements */
+#define DEFAULT_CMD_Q_SIZE    CRQ_PER_PAGE
+#define MAX_CMD_Q_SIZE        (DEFAULT_CMD_Q_SIZE * MAX_CMD_Q_PAGES)
+
+#define SRP_VIOLATION           0x102  /* general error code */
+
+/*
+ * SRP buffer formats defined as of 16.a supported by this driver.
+ */
+#define SUPPORTED_FORMATS  ((SRP_DATA_DESC_DIRECT << 1) | \
+			    (SRP_DATA_DESC_INDIRECT << 1))
+
+#define SCSI_LUN_ADDR_METHOD_FLAT	1
+
+struct dma_window {
+	u32 liobn;	/* Unique per vdevice */
+	u64 tce_base;	/* Physical location of the TCE table */
+	u64 tce_size;	/* Size of the TCE table in bytes */
+};
+
+struct target_dds {
+	u64 unit_id;                /* 64 bit will force alignment */
+#define NUM_DMA_WINDOWS 2
+#define LOCAL  0
+#define REMOTE 1
+	struct dma_window  window[NUM_DMA_WINDOWS];
+
+	/* root node property "ibm,partition-no" */
+	uint partition_num;
+	char partition_name[PARTITION_NAMELEN];
+};
+
+#define MAX_NUM_PORTS        1
+#define MAX_H_COPY_RDMA      (128 * 1024)
+
+#define MAX_EYE   64
+
+/* Return codes */
+#define ADAPT_SUCCESS            0L
+/* choose error codes that do not conflict with PHYP */
+#define ERROR                   -40L
+
+struct format_code {
+	u8 reserved;
+	u8 buffers;
+};
+
+struct client_info {
+#define SRP_VERSION "16.a"
+	char srp_version[8];
+	/* root node property ibm,partition-name */
+	char partition_name[PARTITION_NAMELEN];
+	/* root node property ibm,partition-no */
+	u32 partition_number;
+	/* initially 1 */
+	u32 mad_version;
+	u32 os_type;
+};
+
+/*
+ * Changing this constant changes the number of seconds to wait before
+ * considering the client will never service its queue again.
+ */
+#define SECONDS_TO_CONSIDER_FAILED 30
+/*
+ * These constants set the polling period used to determine if the client
+ * has freed at least one element in the response queue.
+ */
+#define WAIT_SECONDS 1
+#define WAIT_NANO_SECONDS 5000
+#define MAX_TIMER_POPS ((1000000 / WAIT_NANO_SECONDS) * \
+			SECONDS_TO_CONSIDER_FAILED)
+/*
+ * general purpose timer control block
+ * which can be used for multiple functions
+ */
+struct timer_cb {
+	struct hrtimer timer;
+	/*
+	 * how long has it been since the client
+	 * serviced the queue. The variable is incrmented
+	 * in the service_wait_q routine and cleared
+	 * in send messages
+	 */
+	int timer_pops;
+	/* the timer is started */
+	bool started;
+};
+
+struct cmd_queue {
+	/* kva */
+	struct viosrp_crq *base_addr;
+	dma_addr_t crq_token;
+	/* used to maintain index */
+	uint mask;
+	/* current element */
+	uint index;
+	int size;
+};
+
+#define SCSOLNT_RESP_SHIFT	1
+#define UCSOLNT_RESP_SHIFT	2
+
+#define SCSOLNT         BIT(SCSOLNT_RESP_SHIFT)
+#define UCSOLNT         BIT(UCSOLNT_RESP_SHIFT)
+
+enum cmd_type {
+	SCSI_CDB	= 0x01,
+	TASK_MANAGEMENT	= 0x02,
+	/* MAD or addressed to port 0 */
+	ADAPTER_MAD	= 0x04,
+	UNSET_TYPE	= 0x08,
+};
+
+struct iu_rsp {
+	u8 format;
+	u8 sol_not;
+	u16 len;
+	/* tag is just to help client identify cmd, so don't translate be/le */
+	u64 tag;
+};
+
+struct ibmvscsis_cmd {
+	struct list_head list;
+	/* Used for TCM Core operations */
+	struct se_cmd se_cmd;
+	struct iu_entry *iue;
+	struct iu_rsp rsp;
+	struct work_struct work;
+	struct scsi_info *adapter;
+	/* Sense buffer that will be mapped into outgoing status */
+	unsigned char sense_buf[TRANSPORT_SENSE_BUFFER];
+	u64 init_time;
+#define CMD_FAST_FAIL	BIT(0)
+	u32 flags;
+	char type;
+};
+
+struct ibmvscsis_nexus {
+	struct se_session *se_sess;
+};
+
+struct ibmvscsis_tport {
+	/* SCSI protocol the tport is providing */
+	u8 tport_proto_id;
+	/* ASCII formatted WWPN for SRP Target port */
+	char tport_name[IBMVSCSIS_NAMELEN];
+	/* Returned by ibmvscsis_make_tport() */
+	struct se_wwn tport_wwn;
+	/* Returned by ibmvscsis_make_tpg() */
+	struct se_portal_group se_tpg;
+	/* ibmvscsis port target portal group tag for TCM */
+	u16 tport_tpgt;
+	/* Pointer to TCM session for I_T Nexus */
+	struct ibmvscsis_nexus *ibmv_nexus;
+	bool enabled;
+	bool releasing;
+};
+
+struct scsi_info {
+	struct list_head list;
+	char eye[MAX_EYE];
+
+	/* commands waiting for space on repsonse queue */
+	struct list_head waiting_rsp;
+#define NO_QUEUE                    0x00
+#define WAIT_ENABLED                0X01
+	/* driver has received an initialize command */
+#define PART_UP_WAIT_ENAB           0x02
+#define WAIT_CONNECTION             0x04
+	/* have established a connection */
+#define CONNECTED                   0x08
+	/* at least one port is processing SRP IU */
+#define SRP_PROCESSING              0x10
+	/* remove request received */
+#define UNCONFIGURING               0x20
+	/* disconnect by letting adapter go idle, no error */
+#define WAIT_IDLE                   0x40
+	/* disconnecting to clear an error */
+#define ERR_DISCONNECT              0x80
+	/* disconnect to clear error state, then come back up */
+#define ERR_DISCONNECT_RECONNECT    0x100
+	/* disconnected after clearing an error */
+#define ERR_DISCONNECTED            0x200
+	/* A series of errors caused unexpected errors */
+#define UNDEFINED                   0x400
+	u16  state;
+	int fast_fail;
+	struct target_dds dds;
+	char *cmd_pool;
+	/* list of free commands */
+	struct list_head free_cmd;
+	/* command elements ready for scheduler */
+	struct list_head schedule_q;
+	/* commands sent to TCM */
+	struct list_head active_q;
+	caddr_t *map_buf;
+	/* ioba of map buffer */
+	dma_addr_t map_ioba;
+	/* allowable number of outstanding SRP requests */
+	int request_limit;
+	/* extra credit */
+	int credit;
+	/* outstanding transactions against credit limit */
+	int debit;
+
+	/* allow only one outstanding mad request */
+#define PROCESSING_MAD                0x00002
+	/* Waiting to go idle */
+#define WAIT_FOR_IDLE		      0x00004
+	/* H_REG_CRQ called */
+#define CRQ_CLOSED                    0x00010
+	/* detected that client has failed */
+#define CLIENT_FAILED                 0x00040
+	/* detected that transport event occurred */
+#define TRANS_EVENT                   0x00080
+	/* don't attempt to send anything to the client */
+#define RESPONSE_Q_DOWN               0x00100
+	/* request made to schedule disconnect handler */
+#define SCHEDULE_DISCONNECT           0x00400
+	/* disconnect handler is scheduled */
+#define DISCONNECT_SCHEDULED          0x00800
+	u32 flags;
+	/* adapter lock */
+	spinlock_t intr_lock;
+	/* information needed to manage command queue */
+	struct cmd_queue cmd_q;
+	/* used in hcall to copy response back into srp buffer */
+	u64  empty_iu_id;
+	/* used in crq, to tag what iu the response is for */
+	u64  empty_iu_tag;
+	uint new_state;
+	/* control block for the response queue timer */
+	struct timer_cb rsp_q_timer;
+	/* keep last client to enable proper accounting */
+	struct client_info client_data;
+	/* what can this client do */
+	u32 client_cap;
+	/*
+	 * The following two fields capture state and flag changes that
+	 * can occur when the lock is given up.  In the orginal design,
+	 * the lock was held during calls into phyp;
+	 * however, phyp did not meet PAPR architecture.  This is
+	 * a work around.
+	 */
+	u16  phyp_acr_state;
+	u32 phyp_acr_flags;
+
+	struct workqueue_struct *work_q;
+	struct completion wait_idle;
+	struct device dev;
+	struct vio_dev *dma_dev;
+	struct srp_target target;
+	struct ibmvscsis_tport tport;
+	struct tasklet_struct work_task;
+	struct work_struct proc_work;
+};
+
+/*
+ * Provide a constant that allows software to detect the adapter is
+ * disconnecting from the client from one of several states.
+ */
+#define IS_DISCONNECTING (UNCONFIGURING | ERR_DISCONNECT_RECONNECT | \
+			  ERR_DISCONNECT)
+
+/*
+ * Provide a constant that can be used with interrupt handling that
+ * essentially lets the interrupt handler know that all requests should
+ * be thrown out,
+ */
+#define DONT_PROCESS_STATE (IS_DISCONNECTING | UNDEFINED | \
+			    ERR_DISCONNECTED  | WAIT_IDLE)
+
+/*
+ * If any of these flag bits are set then do not allow the interrupt
+ * handler to schedule the off level handler.
+ */
+#define BLOCK (DISCONNECT_SCHEDULED)
+
+/* State and transition events that stop the interrupt handler */
+#define TARGET_STOP(VSCSI) (long)(((VSCSI)->state & DONT_PROCESS_STATE) | \
+				  ((VSCSI)->flags & BLOCK))
+
+/* flag bit that are not reset during disconnect */
+#define PRESERVE_FLAG_FIELDS 0
+
+#define vio_iu(IUE) ((union viosrp_iu *)((IUE)->sbuf->buf))
+
+#define READ_CMD(cdb)	(((cdb)[0] & 0x1F) == 8)
+#define WRITE_CMD(cdb)	(((cdb)[0] & 0x1F) == 0xA)
+
+#ifndef H_GET_PARTNER_INFO
+#define H_GET_PARTNER_INFO      0x0000000000000008LL
+#endif
+
+#define h_copy_rdma(l, sa, sb, da, db) \
+		plpar_hcall_norets(H_COPY_RDMA, l, sa, sb, da, db)
+#define h_vioctl(u, o, a, u1, u2, u3, u4) \
+		plpar_hcall_norets(H_VIOCTL, u, o, a, u1, u2)
+#define h_reg_crq(ua, tok, sz) \
+		plpar_hcall_norets(H_REG_CRQ, ua, tok, sz)
+#define h_free_crq(ua) \
+		plpar_hcall_norets(H_FREE_CRQ, ua)
+#define h_send_crq(ua, d1, d2) \
+		plpar_hcall_norets(H_SEND_CRQ, ua, d1, d2)
+
+#endif
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/scsi/ibmvscsi_tgt/libsrp.c
@@ -0,0 +1,427 @@
+/*******************************************************************************
+ * SCSI RDMA Protocol lib functions
+ *
+ * Copyright (C) 2006 FUJITA Tomonori <tomof@acm.org>
+ * Copyright (C) 2016 Bryant G. Ly <bryantly@linux.vnet.ibm.com> IBM Corp.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ ***********************************************************************/
+
+#define pr_fmt(fmt)	"libsrp: " fmt
+
+#include <linux/printk.h>
+#include <linux/err.h>
+#include <linux/slab.h>
+#include <linux/kfifo.h>
+#include <linux/scatterlist.h>
+#include <linux/dma-mapping.h>
+#include <linux/module.h>
+#include <scsi/srp.h>
+#include <target/target_core_base.h>
+#include "libsrp.h"
+#include "ibmvscsi_tgt.h"
+
+static int srp_iu_pool_alloc(struct srp_queue *q, size_t max,
+			     struct srp_buf **ring)
+{
+	struct iu_entry *iue;
+	int i;
+
+	q->pool = kcalloc(max, sizeof(struct iu_entry *), GFP_KERNEL);
+	if (!q->pool)
+		return -ENOMEM;
+	q->items = kcalloc(max, sizeof(struct iu_entry), GFP_KERNEL);
+	if (!q->items)
+		goto free_pool;
+
+	spin_lock_init(&q->lock);
+	kfifo_init(&q->queue, (void *)q->pool, max * sizeof(void *));
+
+	for (i = 0, iue = q->items; i < max; i++) {
+		kfifo_in(&q->queue, (void *)&iue, sizeof(void *));
+		iue->sbuf = ring[i];
+		iue++;
+	}
+	return 0;
+
+free_pool:
+	kfree(q->pool);
+	return -ENOMEM;
+}
+
+static void srp_iu_pool_free(struct srp_queue *q)
+{
+	kfree(q->items);
+	kfree(q->pool);
+}
+
+static struct srp_buf **srp_ring_alloc(struct device *dev,
+				       size_t max, size_t size)
+{
+	struct srp_buf **ring;
+	int i;
+
+	ring = kcalloc(max, sizeof(struct srp_buf *), GFP_KERNEL);
+	if (!ring)
+		return NULL;
+
+	for (i = 0; i < max; i++) {
+		ring[i] = kzalloc(sizeof(*ring[i]), GFP_KERNEL);
+		if (!ring[i])
+			goto out;
+		ring[i]->buf = dma_alloc_coherent(dev, size, &ring[i]->dma,
+						  GFP_KERNEL);
+		if (!ring[i]->buf)
+			goto out;
+	}
+	return ring;
+
+out:
+	for (i = 0; i < max && ring[i]; i++) {
+		if (ring[i]->buf) {
+			dma_free_coherent(dev, size, ring[i]->buf,
+					  ring[i]->dma);
+		}
+		kfree(ring[i]);
+	}
+	kfree(ring);
+
+	return NULL;
+}
+
+static void srp_ring_free(struct device *dev, struct srp_buf **ring,
+			  size_t max, size_t size)
+{
+	int i;
+
+	for (i = 0; i < max; i++) {
+		dma_free_coherent(dev, size, ring[i]->buf, ring[i]->dma);
+		kfree(ring[i]);
+	}
+	kfree(ring);
+}
+
+int srp_target_alloc(struct srp_target *target, struct device *dev,
+		     size_t nr, size_t iu_size)
+{
+	int err;
+
+	spin_lock_init(&target->lock);
+
+	target->dev = dev;
+
+	target->srp_iu_size = iu_size;
+	target->rx_ring_size = nr;
+	target->rx_ring = srp_ring_alloc(target->dev, nr, iu_size);
+	if (!target->rx_ring)
+		return -ENOMEM;
+	err = srp_iu_pool_alloc(&target->iu_queue, nr, target->rx_ring);
+	if (err)
+		goto free_ring;
+
+	dev_set_drvdata(target->dev, target);
+	return 0;
+
+free_ring:
+	srp_ring_free(target->dev, target->rx_ring, nr, iu_size);
+	return -ENOMEM;
+}
+
+void srp_target_free(struct srp_target *target)
+{
+	dev_set_drvdata(target->dev, NULL);
+	srp_ring_free(target->dev, target->rx_ring, target->rx_ring_size,
+		      target->srp_iu_size);
+	srp_iu_pool_free(&target->iu_queue);
+}
+
+struct iu_entry *srp_iu_get(struct srp_target *target)
+{
+	struct iu_entry *iue = NULL;
+
+	if (kfifo_out_locked(&target->iu_queue.queue, (void *)&iue,
+			     sizeof(void *),
+			     &target->iu_queue.lock) != sizeof(void *)) {
+		WARN_ONCE(1, "unexpected fifo state");
+		return NULL;
+	}
+	if (!iue)
+		return iue;
+	iue->target = target;
+	iue->flags = 0;
+	return iue;
+}
+
+void srp_iu_put(struct iu_entry *iue)
+{
+	kfifo_in_locked(&iue->target->iu_queue.queue, (void *)&iue,
+			sizeof(void *), &iue->target->iu_queue.lock);
+}
+
+static int srp_direct_data(struct ibmvscsis_cmd *cmd, struct srp_direct_buf *md,
+			   enum dma_data_direction dir, srp_rdma_t rdma_io,
+			   int dma_map, int ext_desc)
+{
+	struct iu_entry *iue = NULL;
+	struct scatterlist *sg = NULL;
+	int err, nsg = 0, len;
+
+	if (dma_map) {
+		iue = cmd->iue;
+		sg = cmd->se_cmd.t_data_sg;
+		nsg = dma_map_sg(iue->target->dev, sg, cmd->se_cmd.t_data_nents,
+				 DMA_BIDIRECTIONAL);
+		if (!nsg) {
+			pr_err("fail to map %p %d\n", iue,
+			       cmd->se_cmd.t_data_nents);
+			return 0;
+		}
+		len = min(cmd->se_cmd.data_length, be32_to_cpu(md->len));
+	} else {
+		len = be32_to_cpu(md->len);
+	}
+
+	err = rdma_io(cmd, sg, nsg, md, 1, dir, len);
+
+	if (dma_map)
+		dma_unmap_sg(iue->target->dev, sg, nsg, DMA_BIDIRECTIONAL);
+
+	return err;
+}
+
+static int srp_indirect_data(struct ibmvscsis_cmd *cmd, struct srp_cmd *srp_cmd,
+			     struct srp_indirect_buf *id,
+			     enum dma_data_direction dir, srp_rdma_t rdma_io,
+			     int dma_map, int ext_desc)
+{
+	struct iu_entry *iue = NULL;
+	struct srp_direct_buf *md = NULL;
+	struct scatterlist dummy, *sg = NULL;
+	dma_addr_t token = 0;
+	int err = 0;
+	int nmd, nsg = 0, len;
+
+	if (dma_map || ext_desc) {
+		iue = cmd->iue;
+		sg = cmd->se_cmd.t_data_sg;
+	}
+
+	nmd = be32_to_cpu(id->table_desc.len) / sizeof(struct srp_direct_buf);
+
+	if ((dir == DMA_FROM_DEVICE && nmd == srp_cmd->data_in_desc_cnt) ||
+	    (dir == DMA_TO_DEVICE && nmd == srp_cmd->data_out_desc_cnt)) {
+		md = &id->desc_list[0];
+		goto rdma;
+	}
+
+	if (ext_desc && dma_map) {
+		md = dma_alloc_coherent(iue->target->dev,
+					be32_to_cpu(id->table_desc.len),
+					&token, GFP_KERNEL);
+		if (!md) {
+			pr_err("Can't get dma memory %u\n",
+			       be32_to_cpu(id->table_desc.len));
+			return -ENOMEM;
+		}
+
+		sg_init_one(&dummy, md, be32_to_cpu(id->table_desc.len));
+		sg_dma_address(&dummy) = token;
+		sg_dma_len(&dummy) = be32_to_cpu(id->table_desc.len);
+		err = rdma_io(cmd, &dummy, 1, &id->table_desc, 1, DMA_TO_DEVICE,
+			      be32_to_cpu(id->table_desc.len));
+		if (err) {
+			pr_err("Error copying indirect table %d\n", err);
+			goto free_mem;
+		}
+	} else {
+		pr_err("This command uses external indirect buffer\n");
+		return -EINVAL;
+	}
+
+rdma:
+	if (dma_map) {
+		nsg = dma_map_sg(iue->target->dev, sg, cmd->se_cmd.t_data_nents,
+				 DMA_BIDIRECTIONAL);
+		if (!nsg) {
+			pr_err("fail to map %p %d\n", iue,
+			       cmd->se_cmd.t_data_nents);
+			err = -EIO;
+			goto free_mem;
+		}
+		len = min(cmd->se_cmd.data_length, be32_to_cpu(id->len));
+	} else {
+		len = be32_to_cpu(id->len);
+	}
+
+	err = rdma_io(cmd, sg, nsg, md, nmd, dir, len);
+
+	if (dma_map)
+		dma_unmap_sg(iue->target->dev, sg, nsg, DMA_BIDIRECTIONAL);
+
+free_mem:
+	if (token && dma_map) {
+		dma_free_coherent(iue->target->dev,
+				  be32_to_cpu(id->table_desc.len), md, token);
+	}
+	return err;
+}
+
+static int data_out_desc_size(struct srp_cmd *cmd)
+{
+	int size = 0;
+	u8 fmt = cmd->buf_fmt >> 4;
+
+	switch (fmt) {
+	case SRP_NO_DATA_DESC:
+		break;
+	case SRP_DATA_DESC_DIRECT:
+		size = sizeof(struct srp_direct_buf);
+		break;
+	case SRP_DATA_DESC_INDIRECT:
+		size = sizeof(struct srp_indirect_buf) +
+			sizeof(struct srp_direct_buf) * cmd->data_out_desc_cnt;
+		break;
+	default:
+		pr_err("client error. Invalid data_out_format %x\n", fmt);
+		break;
+	}
+	return size;
+}
+
+/*
+ * TODO: this can be called multiple times for a single command if it
+ * has very long data.
+ */
+int srp_transfer_data(struct ibmvscsis_cmd *cmd, struct srp_cmd *srp_cmd,
+		      srp_rdma_t rdma_io, int dma_map, int ext_desc)
+{
+	struct srp_direct_buf *md;
+	struct srp_indirect_buf *id;
+	enum dma_data_direction dir;
+	int offset, err = 0;
+	u8 format;
+
+	if (!cmd->se_cmd.t_data_nents)
+		return 0;
+
+	offset = srp_cmd->add_cdb_len & ~3;
+
+	dir = srp_cmd_direction(srp_cmd);
+	if (dir == DMA_FROM_DEVICE)
+		offset += data_out_desc_size(srp_cmd);
+
+	if (dir == DMA_TO_DEVICE)
+		format = srp_cmd->buf_fmt >> 4;
+	else
+		format = srp_cmd->buf_fmt & ((1U << 4) - 1);
+
+	switch (format) {
+	case SRP_NO_DATA_DESC:
+		break;
+	case SRP_DATA_DESC_DIRECT:
+		md = (struct srp_direct_buf *)(srp_cmd->add_data + offset);
+		err = srp_direct_data(cmd, md, dir, rdma_io, dma_map, ext_desc);
+		break;
+	case SRP_DATA_DESC_INDIRECT:
+		id = (struct srp_indirect_buf *)(srp_cmd->add_data + offset);
+		err = srp_indirect_data(cmd, srp_cmd, id, dir, rdma_io, dma_map,
+					ext_desc);
+		break;
+	default:
+		pr_err("Unknown format %d %x\n", dir, format);
+		err = -EINVAL;
+	}
+
+	return err;
+}
+
+u64 srp_data_length(struct srp_cmd *cmd, enum dma_data_direction dir)
+{
+	struct srp_direct_buf *md;
+	struct srp_indirect_buf *id;
+	u64 len = 0;
+	uint offset = cmd->add_cdb_len & ~3;
+	u8 fmt;
+
+	if (dir == DMA_TO_DEVICE) {
+		fmt = cmd->buf_fmt >> 4;
+	} else {
+		fmt = cmd->buf_fmt & ((1U << 4) - 1);
+		offset += data_out_desc_size(cmd);
+	}
+
+	switch (fmt) {
+	case SRP_NO_DATA_DESC:
+		break;
+	case SRP_DATA_DESC_DIRECT:
+		md = (struct srp_direct_buf *)(cmd->add_data + offset);
+		len = be32_to_cpu(md->len);
+		break;
+	case SRP_DATA_DESC_INDIRECT:
+		id = (struct srp_indirect_buf *)(cmd->add_data + offset);
+		len = be32_to_cpu(id->len);
+		break;
+	default:
+		pr_err("invalid data format %x\n", fmt);
+		break;
+	}
+	return len;
+}
+
+int srp_get_desc_table(struct srp_cmd *srp_cmd, enum dma_data_direction *dir,
+		       u64 *data_len)
+{
+	struct srp_indirect_buf *idb;
+	struct srp_direct_buf *db;
+	uint add_cdb_offset;
+	int rc;
+
+	/*
+	 * The pointer computations below will only be compiled correctly
+	 * if srp_cmd::add_data is declared as s8*, u8*, s8[] or u8[], so check
+	 * whether srp_cmd::add_data has been declared as a byte pointer.
+	 */
+	BUILD_BUG_ON(!__same_type(srp_cmd->add_data[0], (s8)0)
+		     && !__same_type(srp_cmd->add_data[0], (u8)0));
+
+	BUG_ON(!dir);
+	BUG_ON(!data_len);
+
+	rc = 0;
+	*data_len = 0;
+
+	*dir = DMA_NONE;
+
+	if (srp_cmd->buf_fmt & 0xf)
+		*dir = DMA_FROM_DEVICE;
+	else if (srp_cmd->buf_fmt >> 4)
+		*dir = DMA_TO_DEVICE;
+
+	add_cdb_offset = srp_cmd->add_cdb_len & ~3;
+	if (((srp_cmd->buf_fmt & 0xf) == SRP_DATA_DESC_DIRECT) ||
+	    ((srp_cmd->buf_fmt >> 4) == SRP_DATA_DESC_DIRECT)) {
+		db = (struct srp_direct_buf *)(srp_cmd->add_data
+					       + add_cdb_offset);
+		*data_len = be32_to_cpu(db->len);
+	} else if (((srp_cmd->buf_fmt & 0xf) == SRP_DATA_DESC_INDIRECT) ||
+		   ((srp_cmd->buf_fmt >> 4) == SRP_DATA_DESC_INDIRECT)) {
+		idb = (struct srp_indirect_buf *)(srp_cmd->add_data
+						  + add_cdb_offset);
+
+		*data_len = be32_to_cpu(idb->len);
+	}
+	return rc;
+}
+
+MODULE_DESCRIPTION("SCSI RDMA Protocol lib functions");
+MODULE_AUTHOR("FUJITA Tomonori");
+MODULE_LICENSE("GPL");
--- /dev/null
+++ zfcpdump-kernel-4.4/drivers/scsi/ibmvscsi_tgt/libsrp.h
@@ -0,0 +1,123 @@
+#ifndef __LIBSRP_H__
+#define __LIBSRP_H__
+
+#include <linux/list.h>
+#include <linux/kfifo.h>
+#include <scsi/srp.h>
+
+enum srp_valid {
+	INVALIDATE_CMD_RESP_EL = 0,
+	VALID_CMD_RESP_EL = 0x80,
+	VALID_INIT_MSG = 0xC0,
+	VALID_TRANS_EVENT = 0xFF
+};
+
+enum srp_format {
+	SRP_FORMAT = 1,
+	MAD_FORMAT = 2,
+	OS400_FORMAT = 3,
+	AIX_FORMAT = 4,
+	LINUX_FORMAT = 5,
+	MESSAGE_IN_CRQ = 6
+};
+
+enum srp_init_msg {
+	INIT_MSG = 1,
+	INIT_COMPLETE_MSG = 2
+};
+
+enum srp_trans_event {
+	UNUSED_FORMAT = 0,
+	PARTNER_FAILED = 1,
+	PARTNER_DEREGISTER = 2,
+	MIGRATED = 6
+};
+
+enum srp_status {
+	HEADER_DESCRIPTOR = 0xF1,
+	PING = 0xF5,
+	PING_RESPONSE = 0xF6
+};
+
+enum srp_mad_version {
+	MAD_VERSION_1 = 1
+};
+
+enum srp_os_type {
+	OS400 = 1,
+	LINUX = 2,
+	AIX = 3,
+	OFW = 4
+};
+
+enum srp_task_attributes {
+	SRP_SIMPLE_TASK = 0,
+	SRP_HEAD_TASK = 1,
+	SRP_ORDERED_TASK = 2,
+	SRP_ACA_TASK = 4
+};
+
+enum {
+	SRP_TASK_MANAGEMENT_FUNCTION_COMPLETE           = 0,
+	SRP_REQUEST_FIELDS_INVALID                      = 2,
+	SRP_TASK_MANAGEMENT_FUNCTION_NOT_SUPPORTED      = 4,
+	SRP_TASK_MANAGEMENT_FUNCTION_FAILED             = 5
+};
+
+struct srp_buf {
+	dma_addr_t dma;
+	void *buf;
+};
+
+struct srp_queue {
+	void *pool;
+	void *items;
+	struct kfifo queue;
+	spinlock_t lock;
+};
+
+struct srp_target {
+	struct device *dev;
+
+	spinlock_t lock;
+	struct list_head cmd_queue;
+
+	size_t srp_iu_size;
+	struct srp_queue iu_queue;
+	size_t rx_ring_size;
+	struct srp_buf **rx_ring;
+
+	void *ldata;
+};
+
+struct iu_entry {
+	struct srp_target *target;
+
+	struct list_head ilist;
+	dma_addr_t remote_token;
+	unsigned long flags;
+
+	struct srp_buf *sbuf;
+	u16 iu_len;
+};
+
+struct ibmvscsis_cmd;
+
+typedef int (srp_rdma_t)(struct ibmvscsis_cmd *, struct scatterlist *, int,
+			 struct srp_direct_buf *, int,
+			 enum dma_data_direction, unsigned int);
+int srp_target_alloc(struct srp_target *, struct device *, size_t, size_t);
+void srp_target_free(struct srp_target *);
+struct iu_entry *srp_iu_get(struct srp_target *);
+void srp_iu_put(struct iu_entry *);
+int srp_transfer_data(struct ibmvscsis_cmd *, struct srp_cmd *,
+		      srp_rdma_t, int, int);
+u64 srp_data_length(struct srp_cmd *cmd, enum dma_data_direction dir);
+int srp_get_desc_table(struct srp_cmd *srp_cmd, enum dma_data_direction *dir,
+		       u64 *data_len);
+static inline int srp_cmd_direction(struct srp_cmd *cmd)
+{
+	return (cmd->buf_fmt >> 4) ? DMA_TO_DEVICE : DMA_FROM_DEVICE;
+}
+
+#endif
--- zfcpdump-kernel-4.4.orig/drivers/scsi/ipr.c
+++ zfcpdump-kernel-4.4/drivers/scsi/ipr.c
@@ -4003,13 +4003,17 @@ static ssize_t ipr_store_update_fw(struc
 	struct ipr_sglist *sglist;
 	char fname[100];
 	char *src;
-	int len, result, dnld_size;
+	char *endline;
+	int result, dnld_size;
 
 	if (!capable(CAP_SYS_ADMIN))
 		return -EACCES;
 
-	len = snprintf(fname, 99, "%s", buf);
-	fname[len-1] = '\0';
+	snprintf(fname, sizeof(fname), "%s", buf);
+
+	endline = strchr(fname, '\n');
+	if (endline)
+		*endline = '\0';
 
 	if (request_firmware(&fw_entry, fname, &ioa_cfg->pdev->dev)) {
 		dev_err(&ioa_cfg->pdev->dev, "Firmware file %s not found\n", fname);
@@ -10091,6 +10095,7 @@ static int ipr_probe_ioa(struct pci_dev
 		ioa_cfg->intr_flag = IPR_USE_MSI;
 	else {
 		ioa_cfg->intr_flag = IPR_USE_LSI;
+		ioa_cfg->clear_isr = 1;
 		ioa_cfg->nvectors = 1;
 		dev_info(&pdev->dev, "Cannot enable MSI.\n");
 	}
--- zfcpdump-kernel-4.4.orig/drivers/scsi/iscsi_tcp.c
+++ zfcpdump-kernel-4.4/drivers/scsi/iscsi_tcp.c
@@ -593,9 +593,9 @@ static void iscsi_sw_tcp_release_conn(st
 	iscsi_sw_tcp_conn_restore_callbacks(conn);
 	sock_put(sock->sk);
 
-	spin_lock_bh(&session->frwd_lock);
+	spin_lock_bh(&session->lock);
 	tcp_sw_conn->sock = NULL;
-	spin_unlock_bh(&session->frwd_lock);
+	spin_unlock_bh(&session->lock);
 	sockfd_put(sock);
 }
 
@@ -663,10 +663,10 @@ iscsi_sw_tcp_conn_bind(struct iscsi_cls_
 	if (err)
 		goto free_socket;
 
-	spin_lock_bh(&session->frwd_lock);
+	spin_lock_bh(&session->lock);
 	/* bind iSCSI connection and socket */
 	tcp_sw_conn->sock = sock;
-	spin_unlock_bh(&session->frwd_lock);
+	spin_unlock_bh(&session->lock);
 
 	/* setup Socket parameters */
 	sk = sock->sk;
@@ -727,9 +727,9 @@ static int iscsi_sw_tcp_conn_get_param(s
 	case ISCSI_PARAM_CONN_PORT:
 	case ISCSI_PARAM_CONN_ADDRESS:
 	case ISCSI_PARAM_LOCAL_PORT:
-		spin_lock_bh(&conn->session->frwd_lock);
+		spin_lock_bh(&conn->session->lock);
 		if (!tcp_sw_conn || !tcp_sw_conn->sock) {
-			spin_unlock_bh(&conn->session->frwd_lock);
+			spin_unlock_bh(&conn->session->lock);
 			return -ENOTCONN;
 		}
 		if (param == ISCSI_PARAM_LOCAL_PORT)
@@ -738,7 +738,7 @@ static int iscsi_sw_tcp_conn_get_param(s
 		else
 			rc = kernel_getpeername(tcp_sw_conn->sock,
 						(struct sockaddr *)&addr, &len);
-		spin_unlock_bh(&conn->session->frwd_lock);
+		spin_unlock_bh(&conn->session->lock);
 		if (rc)
 			return rc;
 
@@ -767,23 +767,23 @@ static int iscsi_sw_tcp_host_get_param(s
 		if (!session)
 			return -ENOTCONN;
 
-		spin_lock_bh(&session->frwd_lock);
+		spin_lock_bh(&session->lock);
 		conn = session->leadconn;
 		if (!conn) {
-			spin_unlock_bh(&session->frwd_lock);
+			spin_unlock_bh(&session->lock);
 			return -ENOTCONN;
 		}
 		tcp_conn = conn->dd_data;
 
 		tcp_sw_conn = tcp_conn->dd_data;
 		if (!tcp_sw_conn->sock) {
-			spin_unlock_bh(&session->frwd_lock);
+			spin_unlock_bh(&session->lock);
 			return -ENOTCONN;
 		}
 
 		rc = kernel_getsockname(tcp_sw_conn->sock,
 					(struct sockaddr *)&addr, &len);
-		spin_unlock_bh(&session->frwd_lock);
+		spin_unlock_bh(&session->lock);
 		if (rc)
 			return rc;
 
--- zfcpdump-kernel-4.4.orig/drivers/scsi/libiscsi.c
+++ zfcpdump-kernel-4.4/drivers/scsi/libiscsi.c
@@ -477,7 +477,7 @@ static int iscsi_prep_scsi_cmd_pdu(struc
  * iscsi_free_task - free a task
  * @task: iscsi cmd task
  *
- * Must be called with session back_lock.
+ * Must be called with session lock.
  * This function returns the scsi command to scsi-ml or cleans
  * up mgmt tasks then returns the task to the pool.
  */
@@ -531,10 +531,9 @@ void iscsi_put_task(struct iscsi_task *t
 {
 	struct iscsi_session *session = task->conn->session;
 
-	/* regular RX path uses back_lock */
-	spin_lock_bh(&session->back_lock);
+	spin_lock_bh(&session->lock);
 	__iscsi_put_task(task);
-	spin_unlock_bh(&session->back_lock);
+	spin_unlock_bh(&session->lock);
 }
 EXPORT_SYMBOL_GPL(iscsi_put_task);
 
@@ -543,7 +542,7 @@ EXPORT_SYMBOL_GPL(iscsi_put_task);
  * @task: iscsi cmd task
  * @state: state to complete task with
  *
- * Must be called with session back_lock.
+ * Must be called with session lock.
  */
 static void iscsi_complete_task(struct iscsi_task *task, int state)
 {
@@ -582,7 +581,7 @@ static void iscsi_complete_task(struct i
  * This is used when drivers do not need or cannot perform
  * lower level pdu processing.
  *
- * Called with session back_lock
+ * Called with session lock
  */
 void iscsi_complete_scsi_task(struct iscsi_task *task,
 			      uint32_t exp_cmdsn, uint32_t max_cmdsn)
@@ -599,7 +598,7 @@ EXPORT_SYMBOL_GPL(iscsi_complete_scsi_ta
 
 
 /*
- * session back_lock must be held and if not called for a task that is
+ * session lock must be held and if not called for a task that is
  * still pending or from the xmit thread, then xmit thread must
  * be suspended.
  */
@@ -639,10 +638,7 @@ static void fail_scsi_task(struct iscsi_
 		scsi_in(sc)->resid = scsi_in(sc)->length;
 	}
 
-	/* regular RX path uses back_lock */
-	spin_lock_bh(&conn->session->back_lock);
 	iscsi_complete_task(task, state);
-	spin_unlock_bh(&conn->session->back_lock);
 }
 
 static int iscsi_prep_mgmt_task(struct iscsi_conn *conn,
@@ -790,10 +786,7 @@ __iscsi_conn_send_pdu(struct iscsi_conn
 	return task;
 
 free_task:
-	/* regular RX path uses back_lock */
-	spin_lock_bh(&session->back_lock);
 	__iscsi_put_task(task);
-	spin_unlock_bh(&session->back_lock);
 	return NULL;
 }
 
@@ -804,10 +797,10 @@ int iscsi_conn_send_pdu(struct iscsi_cls
 	struct iscsi_session *session = conn->session;
 	int err = 0;
 
-	spin_lock_bh(&session->frwd_lock);
+	spin_lock_bh(&session->lock);
 	if (!__iscsi_conn_send_pdu(conn, hdr, data, data_size))
 		err = -EPERM;
-	spin_unlock_bh(&session->frwd_lock);
+	spin_unlock_bh(&session->lock);
 	return err;
 }
 EXPORT_SYMBOL_GPL(iscsi_conn_send_pdu);
@@ -1071,19 +1064,14 @@ static int iscsi_handle_reject(struct is
 		if (opcode != ISCSI_OP_NOOP_OUT)
 			return 0;
 
-		 if (rejected_pdu.itt == cpu_to_be32(ISCSI_RESERVED_TAG)) {
+		 if (rejected_pdu.itt == cpu_to_be32(ISCSI_RESERVED_TAG))
 			/*
 			 * nop-out in response to target's nop-out rejected.
 			 * Just resend.
 			 */
-			/* In RX path we are under back lock */
-			spin_unlock(&conn->session->back_lock);
-			spin_lock(&conn->session->frwd_lock);
 			iscsi_send_nopout(conn,
 					  (struct iscsi_nopin*)&rejected_pdu);
-			spin_unlock(&conn->session->frwd_lock);
-			spin_lock(&conn->session->back_lock);
-		} else {
+		else {
 			struct iscsi_task *task;
 			/*
 			 * Our nop as ping got dropped. We know the target
@@ -1119,7 +1107,7 @@ static int iscsi_handle_reject(struct is
  * This should be used for mgmt tasks like login and nops, or if
  * the LDD's itt space does not include the session age.
  *
- * The session back_lock must be held.
+ * The session lock must be held.
  */
 struct iscsi_task *iscsi_itt_to_task(struct iscsi_conn *conn, itt_t itt)
 {
@@ -1148,7 +1136,7 @@ EXPORT_SYMBOL_GPL(iscsi_itt_to_task);
  * @datalen: len of data buffer
  *
  * Completes pdu processing by freeing any resources allocated at
- * queuecommand or send generic. session back_lock must be held and verify
+ * queuecommand or send generic. session lock must be held and verify
  * itt must have been called.
  */
 int __iscsi_complete_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
@@ -1185,12 +1173,7 @@ int __iscsi_complete_pdu(struct iscsi_co
 			if (hdr->ttt == cpu_to_be32(ISCSI_RESERVED_TAG))
 				break;
 
-			/* In RX path we are under back lock */
-			spin_unlock(&session->back_lock);
-			spin_lock(&session->frwd_lock);
 			iscsi_send_nopout(conn, (struct iscsi_nopin*)hdr);
-			spin_unlock(&session->frwd_lock);
-			spin_lock(&session->back_lock);
 			break;
 		case ISCSI_OP_REJECT:
 			rc = iscsi_handle_reject(conn, hdr, data, datalen);
@@ -1297,9 +1280,9 @@ int iscsi_complete_pdu(struct iscsi_conn
 {
 	int rc;
 
-	spin_lock(&conn->session->back_lock);
+	spin_lock(&conn->session->lock);
 	rc = __iscsi_complete_pdu(conn, hdr, data, datalen);
-	spin_unlock(&conn->session->back_lock);
+	spin_unlock(&conn->session->lock);
 	return rc;
 }
 EXPORT_SYMBOL_GPL(iscsi_complete_pdu);
@@ -1343,7 +1326,7 @@ EXPORT_SYMBOL_GPL(iscsi_verify_itt);
  *
  * This should be used for cmd tasks.
  *
- * The session back_lock must be held.
+ * The session lock must be held.
  */
 struct iscsi_task *iscsi_itt_to_ctask(struct iscsi_conn *conn, itt_t itt)
 {
@@ -1373,15 +1356,15 @@ void iscsi_session_failure(struct iscsi_
 	struct iscsi_conn *conn;
 	struct device *dev;
 
-	spin_lock_bh(&session->frwd_lock);
+	spin_lock_bh(&session->lock);
 	conn = session->leadconn;
 	if (session->state == ISCSI_STATE_TERMINATE || !conn) {
-		spin_unlock_bh(&session->frwd_lock);
+		spin_unlock_bh(&session->lock);
 		return;
 	}
 
 	dev = get_device(&conn->cls_conn->dev);
-	spin_unlock_bh(&session->frwd_lock);
+	spin_unlock_bh(&session->lock);
 	if (!dev)
 	        return;
 	/*
@@ -1401,15 +1384,15 @@ void iscsi_conn_failure(struct iscsi_con
 {
 	struct iscsi_session *session = conn->session;
 
-	spin_lock_bh(&session->frwd_lock);
+	spin_lock_bh(&session->lock);
 	if (session->state == ISCSI_STATE_FAILED) {
-		spin_unlock_bh(&session->frwd_lock);
+		spin_unlock_bh(&session->lock);
 		return;
 	}
 
 	if (conn->stop_stage == 0)
 		session->state = ISCSI_STATE_FAILED;
-	spin_unlock_bh(&session->frwd_lock);
+	spin_unlock_bh(&session->lock);
 
 	set_bit(ISCSI_SUSPEND_BIT, &conn->suspend_tx);
 	set_bit(ISCSI_SUSPEND_BIT, &conn->suspend_rx);
@@ -1443,18 +1426,15 @@ static int iscsi_xmit_task(struct iscsi_
 		return -ENODATA;
 
 	__iscsi_get_task(task);
-	spin_unlock_bh(&conn->session->frwd_lock);
+	spin_unlock_bh(&conn->session->lock);
 	rc = conn->session->tt->xmit_task(task);
-	spin_lock_bh(&conn->session->frwd_lock);
+	spin_lock_bh(&conn->session->lock);
 	if (!rc) {
 		/* done with this task */
 		task->last_xfer = jiffies;
 		conn->task = NULL;
 	}
-	/* regular RX path uses back_lock */
-	spin_lock(&conn->session->back_lock);
 	__iscsi_put_task(task);
-	spin_unlock(&conn->session->back_lock);
 	return rc;
 }
 
@@ -1463,7 +1443,7 @@ static int iscsi_xmit_task(struct iscsi_
  * @task: task to requeue
  *
  * LLDs that need to run a task from the session workqueue should call
- * this. The session frwd_lock must be held. This should only be called
+ * this. The session lock must be held. This should only be called
  * by software drivers.
  */
 void iscsi_requeue_task(struct iscsi_task *task)
@@ -1494,10 +1474,10 @@ static int iscsi_data_xmit(struct iscsi_
 	struct iscsi_task *task;
 	int rc = 0;
 
-	spin_lock_bh(&conn->session->frwd_lock);
+	spin_lock_bh(&conn->session->lock);
 	if (test_bit(ISCSI_SUSPEND_BIT, &conn->suspend_tx)) {
 		ISCSI_DBG_SESSION(conn->session, "Tx suspended!\n");
-		spin_unlock_bh(&conn->session->frwd_lock);
+		spin_unlock_bh(&conn->session->lock);
 		return -ENODATA;
 	}
 
@@ -1518,10 +1498,7 @@ check_mgmt:
 					 struct iscsi_task, running);
 		list_del_init(&conn->task->running);
 		if (iscsi_prep_mgmt_task(conn, conn->task)) {
-			/* regular RX path uses back_lock */
-			spin_lock_bh(&conn->session->back_lock);
 			__iscsi_put_task(conn->task);
-			spin_unlock_bh(&conn->session->back_lock);
 			conn->task = NULL;
 			continue;
 		}
@@ -1583,11 +1560,11 @@ check_mgmt:
 		if (!list_empty(&conn->mgmtqueue))
 			goto check_mgmt;
 	}
-	spin_unlock_bh(&conn->session->frwd_lock);
+	spin_unlock_bh(&conn->session->lock);
 	return -ENODATA;
 
 done:
-	spin_unlock_bh(&conn->session->frwd_lock);
+	spin_unlock_bh(&conn->session->lock);
 	return rc;
 }
 
@@ -1657,7 +1634,7 @@ int iscsi_queuecommand(struct Scsi_Host
 
 	cls_session = starget_to_session(scsi_target(sc->device));
 	session = cls_session->dd_data;
-	spin_lock_bh(&session->frwd_lock);
+	spin_lock_bh(&session->lock);
 
 	reason = iscsi_session_chkready(cls_session);
 	if (reason) {
@@ -1743,13 +1720,13 @@ int iscsi_queuecommand(struct Scsi_Host
 	}
 
 	session->queued_cmdsn++;
-	spin_unlock_bh(&session->frwd_lock);
+	spin_unlock_bh(&session->lock);
 	return 0;
 
 prepd_reject:
 	iscsi_complete_task(task, ISCSI_TASK_REQUEUE_SCSIQ);
 reject:
-	spin_unlock_bh(&session->frwd_lock);
+	spin_unlock_bh(&session->lock);
 	ISCSI_DBG_SESSION(session, "cmd 0x%x rejected (%d)\n",
 			  sc->cmnd[0], reason);
 	return SCSI_MLQUEUE_TARGET_BUSY;
@@ -1757,7 +1734,7 @@ reject:
 prepd_fault:
 	iscsi_complete_task(task, ISCSI_TASK_REQUEUE_SCSIQ);
 fault:
-	spin_unlock_bh(&session->frwd_lock);
+	spin_unlock_bh(&session->lock);
 	ISCSI_DBG_SESSION(session, "iscsi: cmd 0x%x is not queued (%d)\n",
 			  sc->cmnd[0], reason);
 	if (!scsi_bidi_cmnd(sc))
@@ -1786,14 +1763,14 @@ static void iscsi_tmf_timedout(unsigned
 	struct iscsi_conn *conn = (struct iscsi_conn *)data;
 	struct iscsi_session *session = conn->session;
 
-	spin_lock(&session->frwd_lock);
+	spin_lock(&session->lock);
 	if (conn->tmf_state == TMF_QUEUED) {
 		conn->tmf_state = TMF_TIMEDOUT;
 		ISCSI_DBG_EH(session, "tmf timedout\n");
 		/* unblock eh_abort() */
 		wake_up(&conn->ehwait);
 	}
-	spin_unlock(&session->frwd_lock);
+	spin_unlock(&session->lock);
 }
 
 static int iscsi_exec_task_mgmt_fn(struct iscsi_conn *conn,
@@ -1806,10 +1783,10 @@ static int iscsi_exec_task_mgmt_fn(struc
 	task = __iscsi_conn_send_pdu(conn, (struct iscsi_hdr *)hdr,
 				      NULL, 0);
 	if (!task) {
-		spin_unlock_bh(&session->frwd_lock);
+		spin_unlock_bh(&session->lock);
 		iscsi_conn_printk(KERN_ERR, conn, "Could not send TMF.\n");
 		iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED);
-		spin_lock_bh(&session->frwd_lock);
+		spin_lock_bh(&session->lock);
 		return -EPERM;
 	}
 	conn->tmfcmd_pdus_cnt++;
@@ -1819,7 +1796,7 @@ static int iscsi_exec_task_mgmt_fn(struc
 	add_timer(&conn->tmf_timer);
 	ISCSI_DBG_EH(session, "tmf set timeout\n");
 
-	spin_unlock_bh(&session->frwd_lock);
+	spin_unlock_bh(&session->lock);
 	mutex_unlock(&session->eh_mutex);
 
 	/*
@@ -1838,7 +1815,7 @@ static int iscsi_exec_task_mgmt_fn(struc
 	del_timer_sync(&conn->tmf_timer);
 
 	mutex_lock(&session->eh_mutex);
-	spin_lock_bh(&session->frwd_lock);
+	spin_lock_bh(&session->lock);
 	/* if the session drops it will clean up the task */
 	if (age != session->age ||
 	    session->state != ISCSI_STATE_LOGGED_IN)
@@ -1874,7 +1851,7 @@ static void fail_scsi_tasks(struct iscsi
  * iscsi_suspend_queue - suspend iscsi_queuecommand
  * @conn: iscsi conn to stop queueing IO on
  *
- * This grabs the session frwd_lock to make sure no one is in
+ * This grabs the session lock to make sure no one is in
  * xmit_task/queuecommand, and then sets suspend to prevent
  * new commands from being queued. This only needs to be called
  * by offload drivers that need to sync a path like ep disconnect
@@ -1883,9 +1860,9 @@ static void fail_scsi_tasks(struct iscsi
  */
 void iscsi_suspend_queue(struct iscsi_conn *conn)
 {
-	spin_lock_bh(&conn->session->frwd_lock);
+	spin_lock_bh(&conn->session->lock);
 	set_bit(ISCSI_SUSPEND_BIT, &conn->suspend_tx);
-	spin_unlock_bh(&conn->session->frwd_lock);
+	spin_unlock_bh(&conn->session->lock);
 }
 EXPORT_SYMBOL_GPL(iscsi_suspend_queue);
 
@@ -1944,7 +1921,7 @@ static enum blk_eh_timer_return iscsi_eh
 
 	ISCSI_DBG_EH(session, "scsi cmd %p timedout\n", sc);
 
-	spin_lock(&session->frwd_lock);
+	spin_lock(&session->lock);
 	task = (struct iscsi_task *)sc->SCp.ptr;
 	if (!task) {
 		/*
@@ -2058,7 +2035,7 @@ static enum blk_eh_timer_return iscsi_eh
 done:
 	if (task)
 		task->last_timeout = jiffies;
-	spin_unlock(&session->frwd_lock);
+	spin_unlock(&session->lock);
 	ISCSI_DBG_EH(session, "return %s\n", rc == BLK_EH_RESET_TIMER ?
 		     "timer reset" : "nh");
 	return rc;
@@ -2070,7 +2047,7 @@ static void iscsi_check_transport_timeou
 	struct iscsi_session *session = conn->session;
 	unsigned long recv_timeout, next_timeout = 0, last_recv;
 
-	spin_lock(&session->frwd_lock);
+	spin_lock(&session->lock);
 	if (session->state != ISCSI_STATE_LOGGED_IN)
 		goto done;
 
@@ -2087,7 +2064,7 @@ static void iscsi_check_transport_timeou
 				  "last ping %lu, now %lu\n",
 				  conn->ping_timeout, conn->recv_timeout,
 				  last_recv, conn->last_ping, jiffies);
-		spin_unlock(&session->frwd_lock);
+		spin_unlock(&session->lock);
 		iscsi_conn_failure(conn, ISCSI_ERR_NOP_TIMEDOUT);
 		return;
 	}
@@ -2105,7 +2082,7 @@ static void iscsi_check_transport_timeou
 	ISCSI_DBG_CONN(conn, "Setting next tmo %lu\n", next_timeout);
 	mod_timer(&conn->transport_timer, next_timeout);
 done:
-	spin_unlock(&session->frwd_lock);
+	spin_unlock(&session->lock);
 }
 
 static void iscsi_prep_abort_task_pdu(struct iscsi_task *task,
@@ -2135,7 +2112,7 @@ int iscsi_eh_abort(struct scsi_cmnd *sc)
 	ISCSI_DBG_EH(session, "aborting sc %p\n", sc);
 
 	mutex_lock(&session->eh_mutex);
-	spin_lock_bh(&session->frwd_lock);
+	spin_lock_bh(&session->lock);
 	/*
 	 * if session was ISCSI_STATE_IN_RECOVERY then we may not have
 	 * got the command.
@@ -2143,7 +2120,7 @@ int iscsi_eh_abort(struct scsi_cmnd *sc)
 	if (!sc->SCp.ptr) {
 		ISCSI_DBG_EH(session, "sc never reached iscsi layer or "
 				      "it completed.\n");
-		spin_unlock_bh(&session->frwd_lock);
+		spin_unlock_bh(&session->lock);
 		mutex_unlock(&session->eh_mutex);
 		return SUCCESS;
 	}
@@ -2154,7 +2131,7 @@ int iscsi_eh_abort(struct scsi_cmnd *sc)
 	 */
 	if (!session->leadconn || session->state != ISCSI_STATE_LOGGED_IN ||
 	    sc->SCp.phase != session->age) {
-		spin_unlock_bh(&session->frwd_lock);
+		spin_unlock_bh(&session->lock);
 		mutex_unlock(&session->eh_mutex);
 		ISCSI_DBG_EH(session, "failing abort due to dropped "
 				  "session.\n");
@@ -2195,7 +2172,7 @@ int iscsi_eh_abort(struct scsi_cmnd *sc)
 
 	switch (conn->tmf_state) {
 	case TMF_SUCCESS:
-		spin_unlock_bh(&session->frwd_lock);
+		spin_unlock_bh(&session->lock);
 		/*
 		 * stop tx side incase the target had sent a abort rsp but
 		 * the initiator was still writing out data.
@@ -2206,15 +2183,15 @@ int iscsi_eh_abort(struct scsi_cmnd *sc)
 		 * good and have never sent us a successful tmf response
 		 * then sent more data for the cmd.
 		 */
-		spin_lock_bh(&session->frwd_lock);
+		spin_lock_bh(&session->lock);
 		fail_scsi_task(task, DID_ABORT);
 		conn->tmf_state = TMF_INITIAL;
 		memset(hdr, 0, sizeof(*hdr));
-		spin_unlock_bh(&session->frwd_lock);
+		spin_unlock_bh(&session->lock);
 		iscsi_start_tx(conn);
 		goto success_unlocked;
 	case TMF_TIMEDOUT:
-		spin_unlock_bh(&session->frwd_lock);
+		spin_unlock_bh(&session->lock);
 		iscsi_conn_failure(conn, ISCSI_ERR_SCSI_EH_SESSION_RST);
 		goto failed_unlocked;
 	case TMF_NOT_FOUND:
@@ -2233,7 +2210,7 @@ int iscsi_eh_abort(struct scsi_cmnd *sc)
 	}
 
 success:
-	spin_unlock_bh(&session->frwd_lock);
+	spin_unlock_bh(&session->lock);
 success_unlocked:
 	ISCSI_DBG_EH(session, "abort success [sc %p itt 0x%x]\n",
 		     sc, task->itt);
@@ -2241,7 +2218,7 @@ success_unlocked:
 	return SUCCESS;
 
 failed:
-	spin_unlock_bh(&session->frwd_lock);
+	spin_unlock_bh(&session->lock);
 failed_unlocked:
 	ISCSI_DBG_EH(session, "abort failed [sc %p itt 0x%x]\n", sc,
 		     task ? task->itt : 0);
@@ -2275,7 +2252,7 @@ int iscsi_eh_device_reset(struct scsi_cm
 		     sc->device->lun);
 
 	mutex_lock(&session->eh_mutex);
-	spin_lock_bh(&session->frwd_lock);
+	spin_lock_bh(&session->lock);
 	/*
 	 * Just check if we are not logged in. We cannot check for
 	 * the phase because the reset could come from a ioctl.
@@ -2302,7 +2279,7 @@ int iscsi_eh_device_reset(struct scsi_cm
 	case TMF_SUCCESS:
 		break;
 	case TMF_TIMEDOUT:
-		spin_unlock_bh(&session->frwd_lock);
+		spin_unlock_bh(&session->lock);
 		iscsi_conn_failure(conn, ISCSI_ERR_SCSI_EH_SESSION_RST);
 		goto done;
 	default:
@@ -2311,21 +2288,21 @@ int iscsi_eh_device_reset(struct scsi_cm
 	}
 
 	rc = SUCCESS;
-	spin_unlock_bh(&session->frwd_lock);
+	spin_unlock_bh(&session->lock);
 
 	iscsi_suspend_tx(conn);
 
-	spin_lock_bh(&session->frwd_lock);
+	spin_lock_bh(&session->lock);
 	memset(hdr, 0, sizeof(*hdr));
 	fail_scsi_tasks(conn, sc->device->lun, DID_ERROR);
 	conn->tmf_state = TMF_INITIAL;
-	spin_unlock_bh(&session->frwd_lock);
+	spin_unlock_bh(&session->lock);
 
 	iscsi_start_tx(conn);
 	goto done;
 
 unlock:
-	spin_unlock_bh(&session->frwd_lock);
+	spin_unlock_bh(&session->lock);
 done:
 	ISCSI_DBG_EH(session, "dev reset result = %s\n",
 		     rc == SUCCESS ? "SUCCESS" : "FAILED");
@@ -2338,13 +2315,13 @@ void iscsi_session_recovery_timedout(str
 {
 	struct iscsi_session *session = cls_session->dd_data;
 
-	spin_lock_bh(&session->frwd_lock);
+	spin_lock_bh(&session->lock);
 	if (session->state != ISCSI_STATE_LOGGED_IN) {
 		session->state = ISCSI_STATE_RECOVERY_FAILED;
 		if (session->leadconn)
 			wake_up(&session->leadconn->ehwait);
 	}
-	spin_unlock_bh(&session->frwd_lock);
+	spin_unlock_bh(&session->lock);
 }
 EXPORT_SYMBOL_GPL(iscsi_session_recovery_timedout);
 
@@ -2366,19 +2343,19 @@ int iscsi_eh_session_reset(struct scsi_c
 	conn = session->leadconn;
 
 	mutex_lock(&session->eh_mutex);
-	spin_lock_bh(&session->frwd_lock);
+	spin_lock_bh(&session->lock);
 	if (session->state == ISCSI_STATE_TERMINATE) {
 failed:
 		ISCSI_DBG_EH(session,
 			     "failing session reset: Could not log back into "
 			     "%s, %s [age %d]\n", session->targetname,
 			     conn->persistent_address, session->age);
-		spin_unlock_bh(&session->frwd_lock);
+		spin_unlock_bh(&session->lock);
 		mutex_unlock(&session->eh_mutex);
 		return FAILED;
 	}
 
-	spin_unlock_bh(&session->frwd_lock);
+	spin_unlock_bh(&session->lock);
 	mutex_unlock(&session->eh_mutex);
 	/*
 	 * we drop the lock here but the leadconn cannot be destoyed while
@@ -2395,14 +2372,14 @@ failed:
 		flush_signals(current);
 
 	mutex_lock(&session->eh_mutex);
-	spin_lock_bh(&session->frwd_lock);
+	spin_lock_bh(&session->lock);
 	if (session->state == ISCSI_STATE_LOGGED_IN) {
 		ISCSI_DBG_EH(session,
 			     "session reset succeeded for %s,%s\n",
 			     session->targetname, conn->persistent_address);
 	} else
 		goto failed;
-	spin_unlock_bh(&session->frwd_lock);
+	spin_unlock_bh(&session->lock);
 	mutex_unlock(&session->eh_mutex);
 	return SUCCESS;
 }
@@ -2438,7 +2415,7 @@ int iscsi_eh_target_reset(struct scsi_cm
 		     session->targetname);
 
 	mutex_lock(&session->eh_mutex);
-	spin_lock_bh(&session->frwd_lock);
+	spin_lock_bh(&session->lock);
 	/*
 	 * Just check if we are not logged in. We cannot check for
 	 * the phase because the reset could come from a ioctl.
@@ -2465,7 +2442,7 @@ int iscsi_eh_target_reset(struct scsi_cm
 	case TMF_SUCCESS:
 		break;
 	case TMF_TIMEDOUT:
-		spin_unlock_bh(&session->frwd_lock);
+		spin_unlock_bh(&session->lock);
 		iscsi_conn_failure(conn, ISCSI_ERR_SCSI_EH_SESSION_RST);
 		goto done;
 	default:
@@ -2474,21 +2451,21 @@ int iscsi_eh_target_reset(struct scsi_cm
 	}
 
 	rc = SUCCESS;
-	spin_unlock_bh(&session->frwd_lock);
+	spin_unlock_bh(&session->lock);
 
 	iscsi_suspend_tx(conn);
 
-	spin_lock_bh(&session->frwd_lock);
+	spin_lock_bh(&session->lock);
 	memset(hdr, 0, sizeof(*hdr));
 	fail_scsi_tasks(conn, -1, DID_ERROR);
 	conn->tmf_state = TMF_INITIAL;
-	spin_unlock_bh(&session->frwd_lock);
+	spin_unlock_bh(&session->lock);
 
 	iscsi_start_tx(conn);
 	goto done;
 
 unlock:
-	spin_unlock_bh(&session->frwd_lock);
+	spin_unlock_bh(&session->lock);
 done:
 	ISCSI_DBG_EH(session, "tgt %s reset result = %s\n", session->targetname,
 		     rc == SUCCESS ? "SUCCESS" : "FAILED");
@@ -2786,10 +2763,8 @@ iscsi_session_setup(struct iscsi_transpo
 	session->max_r2t = 1;
 	session->tt = iscsit;
 	session->dd_data = cls_session->dd_data + sizeof(*session);
-
 	mutex_init(&session->eh_mutex);
-	spin_lock_init(&session->frwd_lock);
-	spin_lock_init(&session->back_lock);
+	spin_lock_init(&session->lock);
 
 	/* initialize SCSI PDU commands pool */
 	if (iscsi_pool_init(&session->cmdpool, session->cmds_max,
@@ -2903,14 +2878,14 @@ iscsi_conn_setup(struct iscsi_cls_sessio
 	INIT_WORK(&conn->xmitwork, iscsi_xmitworker);
 
 	/* allocate login_task used for the login/text sequences */
-	spin_lock_bh(&session->frwd_lock);
+	spin_lock_bh(&session->lock);
 	if (!kfifo_out(&session->cmdpool.queue,
                          (void*)&conn->login_task,
 			 sizeof(void*))) {
-		spin_unlock_bh(&session->frwd_lock);
+		spin_unlock_bh(&session->lock);
 		goto login_task_alloc_fail;
 	}
-	spin_unlock_bh(&session->frwd_lock);
+	spin_unlock_bh(&session->lock);
 
 	data = (char *) __get_free_pages(GFP_KERNEL,
 					 get_order(ISCSI_DEF_MAX_RECV_SEG_LEN));
@@ -2947,7 +2922,7 @@ void iscsi_conn_teardown(struct iscsi_cl
 	del_timer_sync(&conn->transport_timer);
 
 	mutex_lock(&session->eh_mutex);
-	spin_lock_bh(&session->frwd_lock);
+	spin_lock_bh(&session->lock);
 	conn->c_stage = ISCSI_CONN_CLEANUP_WAIT;
 	if (session->leadconn == conn) {
 		/*
@@ -2956,24 +2931,21 @@ void iscsi_conn_teardown(struct iscsi_cl
 		session->state = ISCSI_STATE_TERMINATE;
 		wake_up(&conn->ehwait);
 	}
-	spin_unlock_bh(&session->frwd_lock);
+	spin_unlock_bh(&session->lock);
 
 	/* flush queued up work because we free the connection below */
 	iscsi_suspend_tx(conn);
 
-	spin_lock_bh(&session->frwd_lock);
+	spin_lock_bh(&session->lock);
 	free_pages((unsigned long) conn->data,
 		   get_order(ISCSI_DEF_MAX_RECV_SEG_LEN));
 	kfree(conn->persistent_address);
 	kfree(conn->local_ipaddr);
-	/* regular RX path uses back_lock */
-	spin_lock_bh(&session->back_lock);
 	kfifo_in(&session->cmdpool.queue, (void*)&conn->login_task,
 		    sizeof(void*));
-	spin_unlock_bh(&session->back_lock);
 	if (session->leadconn == conn)
 		session->leadconn = NULL;
-	spin_unlock_bh(&session->frwd_lock);
+	spin_unlock_bh(&session->lock);
 	mutex_unlock(&session->eh_mutex);
 
 	iscsi_destroy_conn(cls_conn);
@@ -3011,7 +2983,7 @@ int iscsi_conn_start(struct iscsi_cls_co
 		conn->ping_timeout = 5;
 	}
 
-	spin_lock_bh(&session->frwd_lock);
+	spin_lock_bh(&session->lock);
 	conn->c_stage = ISCSI_CONN_STARTED;
 	session->state = ISCSI_STATE_LOGGED_IN;
 	session->queued_cmdsn = session->cmdsn;
@@ -3040,7 +3012,7 @@ int iscsi_conn_start(struct iscsi_cls_co
 	default:
 		break;
 	}
-	spin_unlock_bh(&session->frwd_lock);
+	spin_unlock_bh(&session->lock);
 
 	iscsi_unblock_session(session->cls_session);
 	wake_up(&conn->ehwait);
@@ -3079,9 +3051,9 @@ static void iscsi_start_session_recovery
 	int old_stop_stage;
 
 	mutex_lock(&session->eh_mutex);
-	spin_lock_bh(&session->frwd_lock);
+	spin_lock_bh(&session->lock);
 	if (conn->stop_stage == STOP_CONN_TERM) {
-		spin_unlock_bh(&session->frwd_lock);
+		spin_unlock_bh(&session->lock);
 		mutex_unlock(&session->eh_mutex);
 		return;
 	}
@@ -3098,14 +3070,14 @@ static void iscsi_start_session_recovery
 
 	old_stop_stage = conn->stop_stage;
 	conn->stop_stage = flag;
-	spin_unlock_bh(&session->frwd_lock);
+	spin_unlock_bh(&session->lock);
 
 	del_timer_sync(&conn->transport_timer);
 	iscsi_suspend_tx(conn);
 
-	spin_lock_bh(&session->frwd_lock);
+	spin_lock_bh(&session->lock);
 	conn->c_stage = ISCSI_CONN_STOPPED;
-	spin_unlock_bh(&session->frwd_lock);
+	spin_unlock_bh(&session->lock);
 
 	/*
 	 * for connection level recovery we should not calculate
@@ -3126,11 +3098,11 @@ static void iscsi_start_session_recovery
 	/*
 	 * flush queues.
 	 */
-	spin_lock_bh(&session->frwd_lock);
+	spin_lock_bh(&session->lock);
 	fail_scsi_tasks(conn, -1, DID_TRANSPORT_DISRUPTED);
 	fail_mgmt_tasks(session, conn);
 	memset(&conn->tmhdr, 0, sizeof(conn->tmhdr));
-	spin_unlock_bh(&session->frwd_lock);
+	spin_unlock_bh(&session->lock);
 	mutex_unlock(&session->eh_mutex);
 }
 
@@ -3157,10 +3129,10 @@ int iscsi_conn_bind(struct iscsi_cls_ses
 	struct iscsi_session *session = cls_session->dd_data;
 	struct iscsi_conn *conn = cls_conn->dd_data;
 
-	spin_lock_bh(&session->frwd_lock);
+	spin_lock_bh(&session->lock);
 	if (is_leading)
 		session->leadconn = conn;
-	spin_unlock_bh(&session->frwd_lock);
+	spin_unlock_bh(&session->lock);
 
 	/*
 	 * Unblock xmitworker(), Login Phase will pass through.
--- zfcpdump-kernel-4.4.orig/drivers/scsi/libiscsi_tcp.c
+++ zfcpdump-kernel-4.4/drivers/scsi/libiscsi_tcp.c
@@ -446,7 +446,7 @@ iscsi_tcp_data_recv_prep(struct iscsi_tc
  * iscsi_tcp_cleanup_task - free tcp_task resources
  * @task: iscsi task
  *
- * must be called with session back_lock
+ * must be called with session lock
  */
 void iscsi_tcp_cleanup_task(struct iscsi_task *task)
 {
@@ -457,7 +457,6 @@ void iscsi_tcp_cleanup_task(struct iscsi
 	if (!task->sc)
 		return;
 
-	spin_lock_bh(&tcp_task->queue2pool);
 	/* flush task's r2t queues */
 	while (kfifo_out(&tcp_task->r2tqueue, (void*)&r2t, sizeof(void*))) {
 		kfifo_in(&tcp_task->r2tpool.queue, (void*)&r2t,
@@ -471,7 +470,6 @@ void iscsi_tcp_cleanup_task(struct iscsi
 			    sizeof(void*));
 		tcp_task->r2t = NULL;
 	}
-	spin_unlock_bh(&tcp_task->queue2pool);
 }
 EXPORT_SYMBOL_GPL(iscsi_tcp_cleanup_task);
 
@@ -579,13 +577,11 @@ static int iscsi_tcp_r2t_rsp(struct iscs
 		return ISCSI_ERR_DATALEN;
 	}
 
-	spin_lock(&tcp_task->pool2queue);
 	rc = kfifo_out(&tcp_task->r2tpool.queue, (void *)&r2t, sizeof(void *));
 	if (!rc) {
 		iscsi_conn_printk(KERN_ERR, conn, "Could not allocate R2T. "
 				  "Target has sent more R2Ts than it "
 				  "negotiated for or driver has leaked.\n");
-		spin_unlock(&tcp_task->pool2queue);
 		return ISCSI_ERR_PROTO;
 	}
 
@@ -600,7 +596,6 @@ static int iscsi_tcp_r2t_rsp(struct iscs
 	tcp_task->exp_datasn = r2tsn + 1;
 	kfifo_in(&tcp_task->r2tqueue, (void*)&r2t, sizeof(void*));
 	conn->r2t_pdus_cnt++;
-	spin_unlock(&tcp_task->pool2queue);
 
 	iscsi_requeue_task(task);
 	return 0;
@@ -673,14 +668,14 @@ iscsi_tcp_hdr_dissect(struct iscsi_conn
 
 	switch(opcode) {
 	case ISCSI_OP_SCSI_DATA_IN:
-		spin_lock(&conn->session->back_lock);
+		spin_lock(&conn->session->lock);
 		task = iscsi_itt_to_ctask(conn, hdr->itt);
 		if (!task)
 			rc = ISCSI_ERR_BAD_ITT;
 		else
 			rc = iscsi_tcp_data_in(conn, task);
 		if (rc) {
-			spin_unlock(&conn->session->back_lock);
+			spin_unlock(&conn->session->lock);
 			break;
 		}
 
@@ -713,11 +708,11 @@ iscsi_tcp_hdr_dissect(struct iscsi_conn
 						   tcp_conn->in.datalen,
 						   iscsi_tcp_process_data_in,
 						   rx_hash);
-			spin_unlock(&conn->session->back_lock);
+			spin_unlock(&conn->session->lock);
 			return rc;
 		}
 		rc = __iscsi_complete_pdu(conn, hdr, NULL, 0);
-		spin_unlock(&conn->session->back_lock);
+		spin_unlock(&conn->session->lock);
 		break;
 	case ISCSI_OP_SCSI_CMD_RSP:
 		if (tcp_conn->in.datalen) {
@@ -727,20 +722,18 @@ iscsi_tcp_hdr_dissect(struct iscsi_conn
 		rc = iscsi_complete_pdu(conn, hdr, NULL, 0);
 		break;
 	case ISCSI_OP_R2T:
-		spin_lock(&conn->session->back_lock);
+		spin_lock(&conn->session->lock);
 		task = iscsi_itt_to_ctask(conn, hdr->itt);
-		spin_unlock(&conn->session->back_lock);
 		if (!task)
 			rc = ISCSI_ERR_BAD_ITT;
 		else if (ahslen)
 			rc = ISCSI_ERR_AHSLEN;
 		else if (task->sc->sc_data_direction == DMA_TO_DEVICE) {
 			task->last_xfer = jiffies;
-			spin_lock(&conn->session->frwd_lock);
 			rc = iscsi_tcp_r2t_rsp(conn, task);
-			spin_unlock(&conn->session->frwd_lock);
 		} else
 			rc = ISCSI_ERR_PROTO;
+		spin_unlock(&conn->session->lock);
 		break;
 	case ISCSI_OP_LOGIN_RSP:
 	case ISCSI_OP_TEXT_RSP:
@@ -988,13 +981,14 @@ EXPORT_SYMBOL_GPL(iscsi_tcp_task_init);
 
 static struct iscsi_r2t_info *iscsi_tcp_get_curr_r2t(struct iscsi_task *task)
 {
+	struct iscsi_session *session = task->conn->session;
 	struct iscsi_tcp_task *tcp_task = task->dd_data;
 	struct iscsi_r2t_info *r2t = NULL;
 
 	if (iscsi_task_has_unsol_data(task))
 		r2t = &task->unsol_r2t;
 	else {
-		spin_lock_bh(&tcp_task->queue2pool);
+		spin_lock_bh(&session->lock);
 		if (tcp_task->r2t) {
 			r2t = tcp_task->r2t;
 			/* Continue with this R2T? */
@@ -1016,7 +1010,7 @@ static struct iscsi_r2t_info *iscsi_tcp_
 			else
 				r2t = tcp_task->r2t;
 		}
-		spin_unlock_bh(&tcp_task->queue2pool);
+		spin_unlock_bh(&session->lock);
 	}
 
 	return r2t;
@@ -1146,8 +1140,6 @@ int iscsi_tcp_r2tpool_alloc(struct iscsi
 			iscsi_pool_free(&tcp_task->r2tpool);
 			goto r2t_alloc_fail;
 		}
-		spin_lock_init(&tcp_task->pool2queue);
-		spin_lock_init(&tcp_task->queue2pool);
 	}
 
 	return 0;
--- zfcpdump-kernel-4.4.orig/drivers/scsi/lpfc/lpfc.h
+++ zfcpdump-kernel-4.4/drivers/scsi/lpfc/lpfc.h
@@ -386,7 +386,6 @@ struct lpfc_vport {
 	uint32_t work_port_events; /* Timeout to be handled  */
 #define WORKER_DISC_TMO                0x1	/* vport: Discovery timeout */
 #define WORKER_ELS_TMO                 0x2	/* vport: ELS timeout */
-#define WORKER_FDMI_TMO                0x4	/* vport: FDMI timeout */
 #define WORKER_DELAYED_DISC_TMO        0x8	/* vport: delayed discovery */
 
 #define WORKER_MBOX_TMO                0x100	/* hba: MBOX timeout */
@@ -396,7 +395,6 @@ struct lpfc_vport {
 #define WORKER_RAMP_UP_QUEUE           0x1000	/* hba: Increase Q depth */
 #define WORKER_SERVICE_TXQ             0x2000	/* hba: IOCBs on the txq */
 
-	struct timer_list fc_fdmitmo;
 	struct timer_list els_tmofunc;
 	struct timer_list delayed_disc_tmo;
 
@@ -405,6 +403,7 @@ struct lpfc_vport {
 	uint8_t load_flag;
 #define FC_LOADING		0x1	/* HBA in process of loading drvr */
 #define FC_UNLOADING		0x2	/* HBA in process of unloading drvr */
+#define FC_ALLOW_FDMI		0x4	/* port is ready for FDMI requests */
 	/* Vport Config Parameters */
 	uint32_t cfg_scan_down;
 	uint32_t cfg_lun_queue_depth;
@@ -414,10 +413,6 @@ struct lpfc_vport {
 	uint32_t cfg_peer_port_login;
 	uint32_t cfg_fcp_class;
 	uint32_t cfg_use_adisc;
-	uint32_t cfg_fdmi_on;
-#define LPFC_FDMI_SUPPORT	1	/* bit 0 - FDMI supported? */
-#define LPFC_FDMI_REG_DELAY	2	/* bit 1 - 60 sec registration delay */
-#define LPFC_FDMI_ALL_ATTRIB	4	/* bit 2 - register ALL attributes? */
 	uint32_t cfg_discovery_threads;
 	uint32_t cfg_log_verbose;
 	uint32_t cfg_max_luns;
@@ -443,6 +438,10 @@ struct lpfc_vport {
 	unsigned long rcv_buffer_time_stamp;
 	uint32_t vport_flag;
 #define STATIC_VPORT	1
+
+	uint16_t fdmi_num_disc;
+	uint32_t fdmi_hba_mask;
+	uint32_t fdmi_port_mask;
 };
 
 struct hbq_s {
@@ -755,6 +754,11 @@ struct lpfc_hba {
 #define LPFC_DELAY_INIT_LINK              1	/* layered driver hold off */
 #define LPFC_DELAY_INIT_LINK_INDEFINITELY 2	/* wait, manual intervention */
 	uint32_t cfg_enable_dss;
+	uint32_t cfg_fdmi_on;
+#define LPFC_FDMI_NO_SUPPORT	0	/* FDMI not supported */
+#define LPFC_FDMI_SUPPORT	1	/* FDMI supported? */
+#define LPFC_FDMI_SMART_SAN	2	/* SmartSAN supported */
+	uint32_t cfg_enable_SmartSAN;
 	lpfc_vpd_t vpd;		/* vital product data */
 
 	struct pci_dev *pcidev;
@@ -775,9 +779,9 @@ struct lpfc_hba {
 
 	atomic_t fcp_qidx;		/* next work queue to post work to */
 
-	unsigned long pci_bar0_map;     /* Physical address for PCI BAR0 */
-	unsigned long pci_bar1_map;     /* Physical address for PCI BAR1 */
-	unsigned long pci_bar2_map;     /* Physical address for PCI BAR2 */
+	phys_addr_t pci_bar0_map;     /* Physical address for PCI BAR0 */
+	phys_addr_t pci_bar1_map;     /* Physical address for PCI BAR1 */
+	phys_addr_t pci_bar2_map;     /* Physical address for PCI BAR2 */
 	void __iomem *slim_memmap_p;	/* Kernel memory mapped address for
 					   PCI BAR0 */
 	void __iomem *ctrl_regs_memmap_p;/* Kernel memory mapped address for
--- zfcpdump-kernel-4.4.orig/drivers/scsi/lpfc/lpfc_attr.c
+++ zfcpdump-kernel-4.4/drivers/scsi/lpfc/lpfc_attr.c
@@ -4572,19 +4572,27 @@ LPFC_ATTR_R(multi_ring_type, FC_TYPE_IP,
 	     255, "Identifies TYPE for additional ring configuration");
 
 /*
-# lpfc_fdmi_on: controls FDMI support.
-#               Set                NOT Set
-#       bit 0 = FDMI support       no FDMI support
-#           LPFC_FDMI_SUPPORT just turns basic support on/off
-#       bit 1 = Register delay     no register delay  (60 seconds)
-#           LPFC_FDMI_REG_DELAY	60 sec registration delay after FDMI login
-#       bit 2 = All attributes     Use a attribute subset
-#           LPFC_FDMI_ALL_ATTRIB applies to both port and HBA attributes
-#           Port attrutes subset: 1 thru 6 OR all: 1 thru 0xd 0x101 0x102 0x103
-#           HBA attributes subset: 1 thru 0xb OR all: 1 thru 0xc
-# Value range [0,7]. Default value is 0.
+# lpfc_enable_SmartSAN: Sets up FDMI support for SmartSAN
+#       0  = SmartSAN functionality disabled (default)
+#       1  = SmartSAN functionality enabled
+# This parameter will override the value of lpfc_fdmi_on module parameter.
+# Value range is [0,1]. Default value is 0.
 */
-LPFC_VPORT_ATTR_RW(fdmi_on, 0, 0, 7, "Enable FDMI support");
+LPFC_ATTR_R(enable_SmartSAN, 0, 0, 1, "Enable SmartSAN functionality");
+
+/*
+# lpfc_fdmi_on: Controls FDMI support.
+#       0       No FDMI support (default)
+#       1       Traditional FDMI support
+#       2       Smart SAN support
+# If lpfc_enable_SmartSAN is set 1, the driver sets lpfc_fdmi_on to value 2
+# overwriting the current value.  If lpfc_enable_SmartSAN is set 0, the
+# driver uses the current value of lpfc_fdmi_on provided it has value 0 or 1.
+# A value of 2 with lpfc_enable_SmartSAN set to 0 causes the driver to
+# set lpfc_fdmi_on back to 1.
+# Value range [0,2]. Default value is 0.
+*/
+LPFC_ATTR_R(fdmi_on, 0, 0, 2, "Enable FDMI support");
 
 /*
 # Specifies the maximum number of ELS cmds we can have outstanding (for
@@ -4815,6 +4823,7 @@ struct device_attribute *lpfc_hba_attrs[
 	&dev_attr_lpfc_multi_ring_rctl,
 	&dev_attr_lpfc_multi_ring_type,
 	&dev_attr_lpfc_fdmi_on,
+	&dev_attr_lpfc_enable_SmartSAN,
 	&dev_attr_lpfc_max_luns,
 	&dev_attr_lpfc_enable_npiv,
 	&dev_attr_lpfc_fcf_failover_policy,
@@ -4887,7 +4896,6 @@ struct device_attribute *lpfc_vport_attr
 	&dev_attr_lpfc_fcp_class,
 	&dev_attr_lpfc_use_adisc,
 	&dev_attr_lpfc_first_burst_size,
-	&dev_attr_lpfc_fdmi_on,
 	&dev_attr_lpfc_max_luns,
 	&dev_attr_nport_evt_cnt,
 	&dev_attr_npiv_info,
@@ -5247,7 +5255,7 @@ lpfc_get_host_speed(struct Scsi_Host *sh
 
 	spin_lock_irq(shost->host_lock);
 
-	if (lpfc_is_link_up(phba)) {
+	if ((lpfc_is_link_up(phba)) && (!(phba->hba_flag & HBA_FCOE_MODE))) {
 		switch(phba->fc_linkspeed) {
 		case LPFC_LINK_SPEED_1GHZ:
 			fc_host_speed(shost) = FC_PORTSPEED_1GBIT;
@@ -5826,6 +5834,8 @@ lpfc_get_cfgparam(struct lpfc_hba *phba)
 	lpfc_enable_npiv_init(phba, lpfc_enable_npiv);
 	lpfc_fcf_failover_policy_init(phba, lpfc_fcf_failover_policy);
 	lpfc_enable_rrq_init(phba, lpfc_enable_rrq);
+	lpfc_fdmi_on_init(phba, lpfc_fdmi_on);
+	lpfc_enable_SmartSAN_init(phba, lpfc_enable_SmartSAN);
 	lpfc_use_msi_init(phba, lpfc_use_msi);
 	lpfc_fcp_imax_init(phba, lpfc_fcp_imax);
 	lpfc_fcp_cpu_map_init(phba, lpfc_fcp_cpu_map);
@@ -5846,6 +5856,15 @@ lpfc_get_cfgparam(struct lpfc_hba *phba)
 		phba->cfg_poll = 0;
 	else
 		phba->cfg_poll = lpfc_poll;
+
+	/* Ensure fdmi_on and enable_SmartSAN don't conflict */
+	if (phba->cfg_enable_SmartSAN) {
+		phba->cfg_fdmi_on = LPFC_FDMI_SMART_SAN;
+	} else {
+		if (phba->cfg_fdmi_on == LPFC_FDMI_SMART_SAN)
+			phba->cfg_fdmi_on = LPFC_FDMI_SUPPORT;
+	}
+
 	phba->cfg_soft_wwnn = 0L;
 	phba->cfg_soft_wwpn = 0L;
 	lpfc_sg_seg_cnt_init(phba, lpfc_sg_seg_cnt);
@@ -5879,7 +5898,6 @@ lpfc_get_vport_cfgparam(struct lpfc_vpor
 	lpfc_use_adisc_init(vport, lpfc_use_adisc);
 	lpfc_first_burst_size_init(vport, lpfc_first_burst_size);
 	lpfc_max_scsicmpl_time_init(vport, lpfc_max_scsicmpl_time);
-	lpfc_fdmi_on_init(vport, lpfc_fdmi_on);
 	lpfc_discovery_threads_init(vport, lpfc_discovery_threads);
 	lpfc_max_luns_init(vport, lpfc_max_luns);
 	lpfc_scan_down_init(vport, lpfc_scan_down);
--- zfcpdump-kernel-4.4.orig/drivers/scsi/lpfc/lpfc_crtn.h
+++ zfcpdump-kernel-4.4/drivers/scsi/lpfc/lpfc_crtn.h
@@ -72,6 +72,7 @@ void lpfc_cancel_all_vport_retry_delay_t
 void lpfc_retry_pport_discovery(struct lpfc_hba *);
 void lpfc_release_rpi(struct lpfc_hba *, struct lpfc_vport *, uint16_t);
 
+void lpfc_mbx_cmpl_local_config_link(struct lpfc_hba *, LPFC_MBOXQ_t *);
 void lpfc_mbx_cmpl_reg_login(struct lpfc_hba *, LPFC_MBOXQ_t *);
 void lpfc_mbx_cmpl_dflt_rpi(struct lpfc_hba *, LPFC_MBOXQ_t *);
 void lpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba *, LPFC_MBOXQ_t *);
@@ -167,9 +168,8 @@ void lpfc_ct_unsol_event(struct lpfc_hba
 			 struct lpfc_iocbq *);
 int lpfc_ct_handle_unsol_abort(struct lpfc_hba *, struct hbq_dmabuf *);
 int lpfc_ns_cmd(struct lpfc_vport *, int, uint8_t, uint32_t);
-int lpfc_fdmi_cmd(struct lpfc_vport *, struct lpfc_nodelist *, int);
-void lpfc_fdmi_tmo(unsigned long);
-void lpfc_fdmi_timeout_handler(struct lpfc_vport *);
+int lpfc_fdmi_cmd(struct lpfc_vport *, struct lpfc_nodelist *, int, uint32_t);
+void lpfc_fdmi_num_disc_check(struct lpfc_vport *);
 void lpfc_delayed_disc_tmo(unsigned long);
 void lpfc_delayed_disc_timeout_handler(struct lpfc_vport *);
 
--- zfcpdump-kernel-4.4.orig/drivers/scsi/lpfc/lpfc_ct.c
+++ zfcpdump-kernel-4.4/drivers/scsi/lpfc/lpfc_ct.c
@@ -48,15 +48,26 @@
 #include "lpfc_vport.h"
 #include "lpfc_debugfs.h"
 
-/* FDMI Port Speed definitions */
-#define HBA_PORTSPEED_1GBIT		0x0001	/* 1 GBit/sec */
-#define HBA_PORTSPEED_2GBIT		0x0002	/* 2 GBit/sec */
-#define HBA_PORTSPEED_4GBIT		0x0008	/* 4 GBit/sec */
-#define HBA_PORTSPEED_10GBIT		0x0004	/* 10 GBit/sec */
-#define HBA_PORTSPEED_8GBIT		0x0010	/* 8 GBit/sec */
-#define HBA_PORTSPEED_16GBIT		0x0020	/* 16 GBit/sec */
-#define HBA_PORTSPEED_32GBIT		0x0040  /* 32 GBit/sec */
-#define HBA_PORTSPEED_UNKNOWN		0x0800	/* Unknown */
+/* FDMI Port Speed definitions - FC-GS-7 */
+#define HBA_PORTSPEED_1GFC		0x00000001	/* 1G FC */
+#define HBA_PORTSPEED_2GFC		0x00000002	/* 2G FC */
+#define HBA_PORTSPEED_4GFC		0x00000008	/* 4G FC */
+#define HBA_PORTSPEED_10GFC		0x00000004	/* 10G FC */
+#define HBA_PORTSPEED_8GFC		0x00000010	/* 8G FC */
+#define HBA_PORTSPEED_16GFC		0x00000020	/* 16G FC */
+#define HBA_PORTSPEED_32GFC		0x00000040	/* 32G FC */
+#define HBA_PORTSPEED_20GFC		0x00000080	/* 20G FC */
+#define HBA_PORTSPEED_40GFC		0x00000100	/* 40G FC */
+#define HBA_PORTSPEED_128GFC		0x00000200	/* 128G FC */
+#define HBA_PORTSPEED_64GFC		0x00000400	/* 64G FC */
+#define HBA_PORTSPEED_256GFC		0x00000800	/* 256G FC */
+#define HBA_PORTSPEED_UNKNOWN		0x00008000	/* Unknown */
+#define HBA_PORTSPEED_10GE		0x00010000	/* 10G E */
+#define HBA_PORTSPEED_40GE		0x00020000	/* 40G E */
+#define HBA_PORTSPEED_100GE		0x00040000	/* 100G E */
+#define HBA_PORTSPEED_25GE		0x00080000	/* 25G E */
+#define HBA_PORTSPEED_50GE		0x00100000	/* 50G E */
+#define HBA_PORTSPEED_400GE		0x00200000	/* 400G E */
 
 #define FOURBYTES	4
 
@@ -287,6 +298,17 @@ lpfc_ct_free_iocb(struct lpfc_hba *phba,
 	return 0;
 }
 
+/**
+ * lpfc_gen_req - Build and issue a GEN_REQUEST command  to the SLI Layer
+ * @vport: pointer to a host virtual N_Port data structure.
+ * @bmp: Pointer to BPL for SLI command
+ * @inp: Pointer to data buffer for response data.
+ * @outp: Pointer to data buffer that hold the CT command.
+ * @cmpl: completion routine to call when command completes
+ * @ndlp: Destination NPort nodelist entry
+ *
+ * This function as the final part for issuing a CT command.
+ */
 static int
 lpfc_gen_req(struct lpfc_vport *vport, struct lpfc_dmabuf *bmp,
 	     struct lpfc_dmabuf *inp, struct lpfc_dmabuf *outp,
@@ -311,7 +333,7 @@ lpfc_gen_req(struct lpfc_vport *vport, s
 	icmd->un.genreq64.bdl.addrHigh = putPaddrHigh(bmp->phys);
 	icmd->un.genreq64.bdl.addrLow = putPaddrLow(bmp->phys);
 	icmd->un.genreq64.bdl.bdeFlags = BUFF_TYPE_BLP_64;
-	icmd->un.genreq64.bdl.bdeSize = (num_entry * sizeof (struct ulp_bde64));
+	icmd->un.genreq64.bdl.bdeSize = (num_entry * sizeof(struct ulp_bde64));
 
 	if (usr_flg)
 		geniocb->context3 = NULL;
@@ -370,6 +392,16 @@ lpfc_gen_req(struct lpfc_vport *vport, s
 	return 0;
 }
 
+/**
+ * lpfc_ct_cmd - Build and issue a CT command
+ * @vport: pointer to a host virtual N_Port data structure.
+ * @inmp: Pointer to data buffer for response data.
+ * @bmp: Pointer to BPL for SLI command
+ * @ndlp: Destination NPort nodelist entry
+ * @cmpl: completion routine to call when command completes
+ *
+ * This function is called for issuing a CT command.
+ */
 static int
 lpfc_ct_cmd(struct lpfc_vport *vport, struct lpfc_dmabuf *inmp,
 	    struct lpfc_dmabuf *bmp, struct lpfc_nodelist *ndlp,
@@ -453,7 +485,7 @@ lpfc_ns_rsp(struct lpfc_vport *vport, st
 			Cnt -= 16;	/* subtract length of CT header */
 
 		/* Loop through entire NameServer list of DIDs */
-		while (Cnt >= sizeof (uint32_t)) {
+		while (Cnt >= sizeof(uint32_t)) {
 			/* Get next DID from NameServer List */
 			CTentry = *ctptr++;
 			Did = ((be32_to_cpu(CTentry)) & Mask_DID);
@@ -558,7 +590,7 @@ lpfc_ns_rsp(struct lpfc_vport *vport, st
 			}
 			if (CTentry & (cpu_to_be32(SLI_CT_LAST_ENTRY)))
 				goto nsout1;
-			Cnt -= sizeof (uint32_t);
+			Cnt -= sizeof(uint32_t);
 		}
 		ctptr = NULL;
 
@@ -1146,7 +1178,7 @@ lpfc_ns_cmd(struct lpfc_vport *vport, in
 
 	/* fill in BDEs for command */
 	/* Allocate buffer for command payload */
-	mp = kmalloc(sizeof (struct lpfc_dmabuf), GFP_KERNEL);
+	mp = kmalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL);
 	if (!mp) {
 		rc=2;
 		goto ns_cmd_exit;
@@ -1160,7 +1192,7 @@ lpfc_ns_cmd(struct lpfc_vport *vport, in
 	}
 
 	/* Allocate buffer for Buffer ptr list */
-	bmp = kmalloc(sizeof (struct lpfc_dmabuf), GFP_KERNEL);
+	bmp = kmalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL);
 	if (!bmp) {
 		rc=4;
 		goto ns_cmd_free_mpvirt;
@@ -1204,7 +1236,7 @@ lpfc_ns_cmd(struct lpfc_vport *vport, in
 	bpl->tus.w = le32_to_cpu(bpl->tus.w);
 
 	CtReq = (struct lpfc_sli_ct_request *) mp->virt;
-	memset(CtReq, 0, sizeof (struct lpfc_sli_ct_request));
+	memset(CtReq, 0, sizeof(struct lpfc_sli_ct_request));
 	CtReq->RevisionId.bits.Revision = SLI_CT_REVISION;
 	CtReq->RevisionId.bits.InId = 0;
 	CtReq->FsType = SLI_CT_DIRECTORY_SERVICE;
@@ -1244,7 +1276,7 @@ lpfc_ns_cmd(struct lpfc_vport *vport, in
 		    cpu_to_be16(SLI_CTNS_RNN_ID);
 		CtReq->un.rnn.PortId = cpu_to_be32(vport->fc_myDID);
 		memcpy(CtReq->un.rnn.wwnn,  &vport->fc_nodename,
-		       sizeof (struct lpfc_name));
+		       sizeof(struct lpfc_name));
 		cmpl = lpfc_cmpl_ct_cmd_rnn_id;
 		break;
 
@@ -1264,7 +1296,7 @@ lpfc_ns_cmd(struct lpfc_vport *vport, in
 		CtReq->CommandResponse.bits.CmdRsp =
 		    cpu_to_be16(SLI_CTNS_RSNN_NN);
 		memcpy(CtReq->un.rsnn.wwnn, &vport->fc_nodename,
-		       sizeof (struct lpfc_name));
+		       sizeof(struct lpfc_name));
 		size = sizeof(CtReq->un.rsnn.symbname);
 		CtReq->un.rsnn.len =
 			lpfc_vport_symbolic_node_name(vport,
@@ -1319,20 +1351,29 @@ ns_cmd_exit:
 	return 1;
 }
 
+/**
+ * lpfc_cmpl_ct_disc_fdmi - Handle a discovery FDMI completion
+ * @phba: Pointer to HBA context object.
+ * @cmdiocb: Pointer to the command IOCBQ.
+ * @rspiocb: Pointer to the response IOCBQ.
+ *
+ * This function to handle the completion of a driver initiated FDMI
+ * CT command issued during discovery.
+ */
 static void
-lpfc_cmpl_ct_cmd_fdmi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
-		      struct lpfc_iocbq * rspiocb)
+lpfc_cmpl_ct_disc_fdmi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
+		       struct lpfc_iocbq *rspiocb)
 {
+	struct lpfc_vport *vport = cmdiocb->vport;
 	struct lpfc_dmabuf *inp = cmdiocb->context1;
 	struct lpfc_dmabuf *outp = cmdiocb->context2;
-	struct lpfc_sli_ct_request *CTrsp = outp->virt;
 	struct lpfc_sli_ct_request *CTcmd = inp->virt;
-	struct lpfc_nodelist *ndlp;
+	struct lpfc_sli_ct_request *CTrsp = outp->virt;
 	uint16_t fdmi_cmd = CTcmd->CommandResponse.bits.CmdRsp;
 	uint16_t fdmi_rsp = CTrsp->CommandResponse.bits.CmdRsp;
-	struct lpfc_vport *vport = cmdiocb->vport;
 	IOCB_t *irsp = &rspiocb->iocb;
-	uint32_t latt;
+	struct lpfc_nodelist *ndlp;
+	uint32_t latt, cmd, err;
 
 	latt = lpfc_els_chk_latt(vport);
 	lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_CT,
@@ -1340,91 +1381,1115 @@ lpfc_cmpl_ct_cmd_fdmi(struct lpfc_hba *p
 		irsp->ulpStatus, irsp->un.ulpWord[4], latt);
 
 	if (latt || irsp->ulpStatus) {
+
+		/* Look for a retryable error */
+		if (irsp->ulpStatus == IOSTAT_LOCAL_REJECT) {
+			switch ((irsp->un.ulpWord[4] & IOERR_PARAM_MASK)) {
+			case IOERR_SLI_ABORTED:
+			case IOERR_ABORT_IN_PROGRESS:
+			case IOERR_SEQUENCE_TIMEOUT:
+			case IOERR_ILLEGAL_FRAME:
+			case IOERR_NO_RESOURCES:
+			case IOERR_ILLEGAL_COMMAND:
+				cmdiocb->retry++;
+				if (cmdiocb->retry >= LPFC_FDMI_MAX_RETRY)
+					break;
+
+				/* Retry the same FDMI command */
+				err = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING,
+							  cmdiocb, 0);
+				if (err == IOCB_ERROR)
+					break;
+				return;
+			default:
+				break;
+			}
+		}
+
 		lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
 				 "0229 FDMI cmd %04x failed, latt = %d "
 				 "ulpStatus: x%x, rid x%x\n",
 				 be16_to_cpu(fdmi_cmd), latt, irsp->ulpStatus,
 				 irsp->un.ulpWord[4]);
-		goto fail_out;
 	}
+	lpfc_ct_free_iocb(phba, cmdiocb);
 
 	ndlp = lpfc_findnode_did(vport, FDMI_DID);
 	if (!ndlp || !NLP_CHK_NODE_ACT(ndlp))
-		goto fail_out;
+		return;
 
+	/* Check for a CT LS_RJT response */
+	cmd =  be16_to_cpu(fdmi_cmd);
 	if (fdmi_rsp == cpu_to_be16(SLI_CT_RESPONSE_FS_RJT)) {
 		/* FDMI rsp failed */
 		lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
-				 "0220 FDMI rsp failed Data: x%x\n",
-				 be16_to_cpu(fdmi_cmd));
-	}
+				 "0220 FDMI cmd failed FS_RJT Data: x%x", cmd);
 
-fail_out:
-	lpfc_ct_free_iocb(phba, cmdiocb);
-}
-
-static void
-lpfc_cmpl_ct_disc_fdmi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
-		       struct lpfc_iocbq *rspiocb)
-{
-	struct lpfc_vport *vport = cmdiocb->vport;
-	struct lpfc_dmabuf *inp = cmdiocb->context1;
-	struct lpfc_sli_ct_request *CTcmd = inp->virt;
-	uint16_t fdmi_cmd = CTcmd->CommandResponse.bits.CmdRsp;
-	struct lpfc_nodelist *ndlp;
+		/* Should we fallback to FDMI-2 / FDMI-1 ? */
+		switch (cmd) {
+		case SLI_MGMT_RHBA:
+			if (vport->fdmi_hba_mask == LPFC_FDMI2_HBA_ATTR) {
+				/* Fallback to FDMI-1 */
+				vport->fdmi_hba_mask = LPFC_FDMI1_HBA_ATTR;
+				vport->fdmi_port_mask = LPFC_FDMI1_PORT_ATTR;
+				/* Start over */
+				lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_DHBA, 0);
+			}
+			return;
 
-	lpfc_cmpl_ct_cmd_fdmi(phba, cmdiocb, rspiocb);
+		case SLI_MGMT_RPRT:
+			if (vport->fdmi_port_mask == LPFC_FDMI2_PORT_ATTR) {
+				/* Fallback to FDMI-1 */
+				vport->fdmi_port_mask = LPFC_FDMI1_PORT_ATTR;
+				/* Start over */
+				lpfc_fdmi_cmd(vport, ndlp, cmd, 0);
+			}
+			if (vport->fdmi_port_mask == LPFC_FDMI2_SMART_ATTR) {
+				vport->fdmi_port_mask = LPFC_FDMI2_PORT_ATTR;
+				/* Retry the same command */
+				lpfc_fdmi_cmd(vport, ndlp, cmd, 0);
+			}
+			return;
 
-	ndlp = lpfc_findnode_did(vport, FDMI_DID);
-	if (!ndlp || !NLP_CHK_NODE_ACT(ndlp))
-		return;
+		case SLI_MGMT_RPA:
+			if (vport->fdmi_port_mask == LPFC_FDMI2_PORT_ATTR) {
+				/* Fallback to FDMI-1 */
+				vport->fdmi_hba_mask = LPFC_FDMI1_HBA_ATTR;
+				vport->fdmi_port_mask = LPFC_FDMI1_PORT_ATTR;
+				/* Start over */
+				lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_DHBA, 0);
+			}
+			if (vport->fdmi_port_mask == LPFC_FDMI2_SMART_ATTR) {
+				vport->fdmi_port_mask = LPFC_FDMI2_PORT_ATTR;
+				/* Retry the same command */
+				lpfc_fdmi_cmd(vport, ndlp, cmd, 0);
+			}
+			return;
+		}
+	}
 
 	/*
-	 * Need to cycle thru FDMI registration for discovery
-	 * DHBA -> DPRT -> RHBA -> RPA
+	 * On success, need to cycle thru FDMI registration for discovery
+	 * DHBA -> DPRT -> RHBA -> RPA  (physical port)
+	 * DPRT -> RPRT (vports)
 	 */
-	switch (be16_to_cpu(fdmi_cmd)) {
+	switch (cmd) {
 	case SLI_MGMT_RHBA:
-		lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_RPA);
+		lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_RPA, 0);
 		break;
 
 	case SLI_MGMT_DHBA:
-		lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_DPRT);
+		lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_DPRT, 0);
 		break;
 
 	case SLI_MGMT_DPRT:
-		lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_RHBA);
+		if (vport->port_type == LPFC_PHYSICAL_PORT)
+			lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_RHBA, 0);
+		else
+			lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_RPRT, 0);
 		break;
 	}
+	return;
+}
+
+
+/**
+ * lpfc_fdmi_num_disc_check - Check how many mapped NPorts we are connected to
+ * @vport: pointer to a host virtual N_Port data structure.
+ *
+ * Called from hbeat timeout routine to check if the number of discovered
+ * ports has changed. If so, re-register thar port Attribute.
+ */
+void
+lpfc_fdmi_num_disc_check(struct lpfc_vport *vport)
+{
+	struct lpfc_hba *phba = vport->phba;
+	struct lpfc_nodelist *ndlp;
+	uint16_t cnt;
+
+	if (!lpfc_is_link_up(phba))
+		return;
+
+	if (!(vport->fdmi_port_mask & LPFC_FDMI_PORT_ATTR_num_disc))
+		return;
+
+	cnt = lpfc_find_map_node(vport);
+	if (cnt == vport->fdmi_num_disc)
+		return;
+
+	ndlp = lpfc_findnode_did(vport, FDMI_DID);
+	if (!ndlp || !NLP_CHK_NODE_ACT(ndlp))
+		return;
+
+	if (vport->port_type == LPFC_PHYSICAL_PORT) {
+		lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_RPA,
+			      LPFC_FDMI_PORT_ATTR_num_disc);
+	} else {
+		lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_RPRT,
+			      LPFC_FDMI_PORT_ATTR_num_disc);
+	}
+}
+
+/* Routines for all individual HBA attributes */
+int
+lpfc_fdmi_hba_attr_wwnn(struct lpfc_vport *vport, struct lpfc_fdmi_attr_def *ad)
+{
+	struct lpfc_fdmi_attr_entry *ae;
+	uint32_t size;
+
+	ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
+	memset(ae, 0, sizeof(struct lpfc_name));
+
+	memcpy(&ae->un.AttrWWN, &vport->fc_sparam.nodeName,
+	       sizeof(struct lpfc_name));
+	size = FOURBYTES + sizeof(struct lpfc_name);
+	ad->AttrLen = cpu_to_be16(size);
+	ad->AttrType = cpu_to_be16(RHBA_NODENAME);
+	return size;
+}
+int
+lpfc_fdmi_hba_attr_manufacturer(struct lpfc_vport *vport,
+				struct lpfc_fdmi_attr_def *ad)
+{
+	struct lpfc_fdmi_attr_entry *ae;
+	uint32_t len, size;
+
+	ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
+	memset(ae, 0, 256);
+
+	strncpy(ae->un.AttrString,
+		"Emulex Corporation",
+		       sizeof(ae->un.AttrString));
+	len = strnlen(ae->un.AttrString,
+			  sizeof(ae->un.AttrString));
+	len += (len & 3) ? (4 - (len & 3)) : 4;
+	size = FOURBYTES + len;
+	ad->AttrLen = cpu_to_be16(size);
+	ad->AttrType = cpu_to_be16(RHBA_MANUFACTURER);
+	return size;
+}
+
+int
+lpfc_fdmi_hba_attr_sn(struct lpfc_vport *vport, struct lpfc_fdmi_attr_def *ad)
+{
+	struct lpfc_hba *phba = vport->phba;
+	struct lpfc_fdmi_attr_entry *ae;
+	uint32_t len, size;
+
+	ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
+	memset(ae, 0, 256);
+
+	strncpy(ae->un.AttrString, phba->SerialNumber,
+		sizeof(ae->un.AttrString));
+	len = strnlen(ae->un.AttrString,
+			  sizeof(ae->un.AttrString));
+	len += (len & 3) ? (4 - (len & 3)) : 4;
+	size = FOURBYTES + len;
+	ad->AttrLen = cpu_to_be16(size);
+	ad->AttrType = cpu_to_be16(RHBA_SERIAL_NUMBER);
+	return size;
+}
+
+int
+lpfc_fdmi_hba_attr_model(struct lpfc_vport *vport,
+			 struct lpfc_fdmi_attr_def *ad)
+{
+	struct lpfc_hba *phba = vport->phba;
+	struct lpfc_fdmi_attr_entry *ae;
+	uint32_t len, size;
+
+	ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
+	memset(ae, 0, 256);
+
+	strncpy(ae->un.AttrString, phba->ModelName,
+		sizeof(ae->un.AttrString));
+	len = strnlen(ae->un.AttrString, sizeof(ae->un.AttrString));
+	len += (len & 3) ? (4 - (len & 3)) : 4;
+	size = FOURBYTES + len;
+	ad->AttrLen = cpu_to_be16(size);
+	ad->AttrType = cpu_to_be16(RHBA_MODEL);
+	return size;
+}
+
+int
+lpfc_fdmi_hba_attr_description(struct lpfc_vport *vport,
+			       struct lpfc_fdmi_attr_def *ad)
+{
+	struct lpfc_hba *phba = vport->phba;
+	struct lpfc_fdmi_attr_entry *ae;
+	uint32_t len, size;
+
+	ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
+	memset(ae, 0, 256);
+
+	strncpy(ae->un.AttrString, phba->ModelDesc,
+		sizeof(ae->un.AttrString));
+	len = strnlen(ae->un.AttrString,
+				  sizeof(ae->un.AttrString));
+	len += (len & 3) ? (4 - (len & 3)) : 4;
+	size = FOURBYTES + len;
+	ad->AttrLen = cpu_to_be16(size);
+	ad->AttrType = cpu_to_be16(RHBA_MODEL_DESCRIPTION);
+	return size;
 }
 
+int
+lpfc_fdmi_hba_attr_hdw_ver(struct lpfc_vport *vport,
+			   struct lpfc_fdmi_attr_def *ad)
+{
+	struct lpfc_hba *phba = vport->phba;
+	lpfc_vpd_t *vp = &phba->vpd;
+	struct lpfc_fdmi_attr_entry *ae;
+	uint32_t i, j, incr, size;
+
+	ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
+	memset(ae, 0, 256);
+
+	/* Convert JEDEC ID to ascii for hardware version */
+	incr = vp->rev.biuRev;
+	for (i = 0; i < 8; i++) {
+		j = (incr & 0xf);
+		if (j <= 9)
+			ae->un.AttrString[7 - i] =
+			    (char)((uint8_t) 0x30 +
+				   (uint8_t) j);
+		else
+			ae->un.AttrString[7 - i] =
+			    (char)((uint8_t) 0x61 +
+				   (uint8_t) (j - 10));
+		incr = (incr >> 4);
+	}
+	size = FOURBYTES + 8;
+	ad->AttrLen = cpu_to_be16(size);
+	ad->AttrType = cpu_to_be16(RHBA_HARDWARE_VERSION);
+	return size;
+}
 
 int
-lpfc_fdmi_cmd(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, int cmdcode)
+lpfc_fdmi_hba_attr_drvr_ver(struct lpfc_vport *vport,
+			    struct lpfc_fdmi_attr_def *ad)
+{
+	struct lpfc_fdmi_attr_entry *ae;
+	uint32_t len, size;
+
+	ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
+	memset(ae, 0, 256);
+
+	strncpy(ae->un.AttrString, lpfc_release_version,
+		sizeof(ae->un.AttrString));
+	len = strnlen(ae->un.AttrString,
+			  sizeof(ae->un.AttrString));
+	len += (len & 3) ? (4 - (len & 3)) : 4;
+	size = FOURBYTES + len;
+	ad->AttrLen = cpu_to_be16(size);
+	ad->AttrType = cpu_to_be16(RHBA_DRIVER_VERSION);
+	return size;
+}
+
+int
+lpfc_fdmi_hba_attr_rom_ver(struct lpfc_vport *vport,
+			   struct lpfc_fdmi_attr_def *ad)
+{
+	struct lpfc_hba *phba = vport->phba;
+	struct lpfc_fdmi_attr_entry *ae;
+	uint32_t len, size;
+
+	ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
+	memset(ae, 0, 256);
+
+	if (phba->sli_rev == LPFC_SLI_REV4)
+		lpfc_decode_firmware_rev(phba, ae->un.AttrString, 1);
+	else
+		strncpy(ae->un.AttrString, phba->OptionROMVersion,
+			sizeof(ae->un.AttrString));
+	len = strnlen(ae->un.AttrString,
+			  sizeof(ae->un.AttrString));
+	len += (len & 3) ? (4 - (len & 3)) : 4;
+	size = FOURBYTES + len;
+	ad->AttrLen = cpu_to_be16(size);
+	ad->AttrType = cpu_to_be16(RHBA_OPTION_ROM_VERSION);
+	return size;
+}
+
+int
+lpfc_fdmi_hba_attr_fmw_ver(struct lpfc_vport *vport,
+			   struct lpfc_fdmi_attr_def *ad)
+{
+	struct lpfc_hba *phba = vport->phba;
+	struct lpfc_fdmi_attr_entry *ae;
+	uint32_t len, size;
+
+	ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
+	memset(ae, 0, 256);
+
+	lpfc_decode_firmware_rev(phba, ae->un.AttrString, 1);
+	len = strnlen(ae->un.AttrString,
+			  sizeof(ae->un.AttrString));
+	len += (len & 3) ? (4 - (len & 3)) : 4;
+	size = FOURBYTES + len;
+	ad->AttrLen = cpu_to_be16(size);
+	ad->AttrType = cpu_to_be16(RHBA_FIRMWARE_VERSION);
+	return size;
+}
+
+int
+lpfc_fdmi_hba_attr_os_ver(struct lpfc_vport *vport,
+			  struct lpfc_fdmi_attr_def *ad)
+{
+	struct lpfc_fdmi_attr_entry *ae;
+	uint32_t len, size;
+
+	ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
+	memset(ae, 0, 256);
+
+	snprintf(ae->un.AttrString, sizeof(ae->un.AttrString), "%s %s %s",
+		 init_utsname()->sysname,
+		 init_utsname()->release,
+		 init_utsname()->version);
+
+	len = strnlen(ae->un.AttrString, sizeof(ae->un.AttrString));
+	len += (len & 3) ? (4 - (len & 3)) : 4;
+	size = FOURBYTES + len;
+	ad->AttrLen = cpu_to_be16(size);
+	ad->AttrType = cpu_to_be16(RHBA_OS_NAME_VERSION);
+	return size;
+}
+
+int
+lpfc_fdmi_hba_attr_ct_len(struct lpfc_vport *vport,
+			  struct lpfc_fdmi_attr_def *ad)
+{
+	struct lpfc_fdmi_attr_entry *ae;
+	uint32_t size;
+
+	ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
+
+	ae->un.AttrInt =  cpu_to_be32(LPFC_MAX_CT_SIZE);
+	size = FOURBYTES + sizeof(uint32_t);
+	ad->AttrLen = cpu_to_be16(size);
+	ad->AttrType = cpu_to_be16(RHBA_MAX_CT_PAYLOAD_LEN);
+	return size;
+}
+
+int
+lpfc_fdmi_hba_attr_symbolic_name(struct lpfc_vport *vport,
+				 struct lpfc_fdmi_attr_def *ad)
+{
+	struct lpfc_fdmi_attr_entry *ae;
+	uint32_t len, size;
+
+	ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
+	memset(ae, 0, 256);
+
+	len = lpfc_vport_symbolic_node_name(vport,
+				ae->un.AttrString, 256);
+	len += (len & 3) ? (4 - (len & 3)) : 4;
+	size = FOURBYTES + len;
+	ad->AttrLen = cpu_to_be16(size);
+	ad->AttrType = cpu_to_be16(RHBA_SYM_NODENAME);
+	return size;
+}
+
+int
+lpfc_fdmi_hba_attr_vendor_info(struct lpfc_vport *vport,
+			       struct lpfc_fdmi_attr_def *ad)
+{
+	struct lpfc_fdmi_attr_entry *ae;
+	uint32_t size;
+
+	ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
+
+	/* Nothing is defined for this currently */
+	ae->un.AttrInt =  cpu_to_be32(0);
+	size = FOURBYTES + sizeof(uint32_t);
+	ad->AttrLen = cpu_to_be16(size);
+	ad->AttrType = cpu_to_be16(RHBA_VENDOR_INFO);
+	return size;
+}
+
+int
+lpfc_fdmi_hba_attr_num_ports(struct lpfc_vport *vport,
+			     struct lpfc_fdmi_attr_def *ad)
+{
+	struct lpfc_fdmi_attr_entry *ae;
+	uint32_t size;
+
+	ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
+
+	/* Each driver instance corresponds to a single port */
+	ae->un.AttrInt =  cpu_to_be32(1);
+	size = FOURBYTES + sizeof(uint32_t);
+	ad->AttrLen = cpu_to_be16(size);
+	ad->AttrType = cpu_to_be16(RHBA_NUM_PORTS);
+	return size;
+}
+
+int
+lpfc_fdmi_hba_attr_fabric_wwnn(struct lpfc_vport *vport,
+			       struct lpfc_fdmi_attr_def *ad)
+{
+	struct lpfc_fdmi_attr_entry *ae;
+	uint32_t size;
+
+	ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
+	memset(ae, 0, sizeof(struct lpfc_name));
+
+	memcpy(&ae->un.AttrWWN, &vport->fabric_nodename,
+	       sizeof(struct lpfc_name));
+	size = FOURBYTES + sizeof(struct lpfc_name);
+	ad->AttrLen = cpu_to_be16(size);
+	ad->AttrType = cpu_to_be16(RHBA_FABRIC_WWNN);
+	return size;
+}
+
+int
+lpfc_fdmi_hba_attr_bios_ver(struct lpfc_vport *vport,
+			    struct lpfc_fdmi_attr_def *ad)
+{
+	struct lpfc_hba *phba = vport->phba;
+	struct lpfc_fdmi_attr_entry *ae;
+	uint32_t len, size;
+
+	ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
+	memset(ae, 0, 256);
+
+	lpfc_decode_firmware_rev(phba, ae->un.AttrString, 1);
+	len = strnlen(ae->un.AttrString,
+			  sizeof(ae->un.AttrString));
+	len += (len & 3) ? (4 - (len & 3)) : 4;
+	size = FOURBYTES + len;
+	ad->AttrLen = cpu_to_be16(size);
+	ad->AttrType = cpu_to_be16(RHBA_BIOS_VERSION);
+	return size;
+}
+
+int
+lpfc_fdmi_hba_attr_bios_state(struct lpfc_vport *vport,
+			      struct lpfc_fdmi_attr_def *ad)
+{
+	struct lpfc_fdmi_attr_entry *ae;
+	uint32_t size;
+
+	ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
+
+	/* Driver doesn't have access to this information */
+	ae->un.AttrInt =  cpu_to_be32(0);
+	size = FOURBYTES + sizeof(uint32_t);
+	ad->AttrLen = cpu_to_be16(size);
+	ad->AttrType = cpu_to_be16(RHBA_BIOS_STATE);
+	return size;
+}
+
+int
+lpfc_fdmi_hba_attr_vendor_id(struct lpfc_vport *vport,
+			     struct lpfc_fdmi_attr_def *ad)
+{
+	struct lpfc_fdmi_attr_entry *ae;
+	uint32_t len, size;
+
+	ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
+	memset(ae, 0, 256);
+
+	strncpy(ae->un.AttrString, "EMULEX",
+		sizeof(ae->un.AttrString));
+	len = strnlen(ae->un.AttrString,
+			  sizeof(ae->un.AttrString));
+	len += (len & 3) ? (4 - (len & 3)) : 4;
+	size = FOURBYTES + len;
+	ad->AttrLen = cpu_to_be16(size);
+	ad->AttrType = cpu_to_be16(RHBA_VENDOR_ID);
+	return size;
+}
+
+/* Routines for all individual PORT attributes */
+int
+lpfc_fdmi_port_attr_fc4type(struct lpfc_vport *vport,
+			    struct lpfc_fdmi_attr_def *ad)
+{
+	struct lpfc_fdmi_attr_entry *ae;
+	uint32_t size;
+
+	ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
+	memset(ae, 0, 32);
+
+	ae->un.AttrTypes[3] = 0x02; /* Type 1 - ELS */
+	ae->un.AttrTypes[2] = 0x01; /* Type 8 - FCP */
+	ae->un.AttrTypes[7] = 0x01; /* Type 32 - CT */
+	size = FOURBYTES + 32;
+	ad->AttrLen = cpu_to_be16(size);
+	ad->AttrType = cpu_to_be16(RPRT_SUPPORTED_FC4_TYPES);
+	return size;
+}
+
+int
+lpfc_fdmi_port_attr_support_speed(struct lpfc_vport *vport,
+				  struct lpfc_fdmi_attr_def *ad)
+{
+	struct lpfc_hba   *phba = vport->phba;
+	struct lpfc_fdmi_attr_entry *ae;
+	uint32_t size;
+
+	ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
+
+	ae->un.AttrInt = 0;
+	if (!(phba->hba_flag & HBA_FCOE_MODE)) {
+		if (phba->lmt & LMT_32Gb)
+			ae->un.AttrInt |= HBA_PORTSPEED_32GFC;
+		if (phba->lmt & LMT_16Gb)
+			ae->un.AttrInt |= HBA_PORTSPEED_16GFC;
+		if (phba->lmt & LMT_10Gb)
+			ae->un.AttrInt |= HBA_PORTSPEED_10GFC;
+		if (phba->lmt & LMT_8Gb)
+			ae->un.AttrInt |= HBA_PORTSPEED_8GFC;
+		if (phba->lmt & LMT_4Gb)
+			ae->un.AttrInt |= HBA_PORTSPEED_4GFC;
+		if (phba->lmt & LMT_2Gb)
+			ae->un.AttrInt |= HBA_PORTSPEED_2GFC;
+		if (phba->lmt & LMT_1Gb)
+			ae->un.AttrInt |= HBA_PORTSPEED_1GFC;
+	} else {
+		/* FCoE links support only one speed */
+		switch (phba->fc_linkspeed) {
+		case LPFC_ASYNC_LINK_SPEED_10GBPS:
+			ae->un.AttrInt = HBA_PORTSPEED_10GE;
+			break;
+		case LPFC_ASYNC_LINK_SPEED_25GBPS:
+			ae->un.AttrInt = HBA_PORTSPEED_25GE;
+			break;
+		case LPFC_ASYNC_LINK_SPEED_40GBPS:
+			ae->un.AttrInt = HBA_PORTSPEED_40GE;
+			break;
+		case LPFC_ASYNC_LINK_SPEED_100GBPS:
+			ae->un.AttrInt = HBA_PORTSPEED_100GE;
+			break;
+		}
+	}
+	ae->un.AttrInt = cpu_to_be32(ae->un.AttrInt);
+	size = FOURBYTES + sizeof(uint32_t);
+	ad->AttrLen = cpu_to_be16(size);
+	ad->AttrType = cpu_to_be16(RPRT_SUPPORTED_SPEED);
+	return size;
+}
+
+int
+lpfc_fdmi_port_attr_speed(struct lpfc_vport *vport,
+			  struct lpfc_fdmi_attr_def *ad)
+{
+	struct lpfc_hba   *phba = vport->phba;
+	struct lpfc_fdmi_attr_entry *ae;
+	uint32_t size;
+
+	ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
+
+	if (!(phba->hba_flag & HBA_FCOE_MODE)) {
+		switch (phba->fc_linkspeed) {
+		case LPFC_LINK_SPEED_1GHZ:
+			ae->un.AttrInt = HBA_PORTSPEED_1GFC;
+			break;
+		case LPFC_LINK_SPEED_2GHZ:
+			ae->un.AttrInt = HBA_PORTSPEED_2GFC;
+			break;
+		case LPFC_LINK_SPEED_4GHZ:
+			ae->un.AttrInt = HBA_PORTSPEED_4GFC;
+			break;
+		case LPFC_LINK_SPEED_8GHZ:
+			ae->un.AttrInt = HBA_PORTSPEED_8GFC;
+			break;
+		case LPFC_LINK_SPEED_10GHZ:
+			ae->un.AttrInt = HBA_PORTSPEED_10GFC;
+			break;
+		case LPFC_LINK_SPEED_16GHZ:
+			ae->un.AttrInt = HBA_PORTSPEED_16GFC;
+			break;
+		case LPFC_LINK_SPEED_32GHZ:
+			ae->un.AttrInt = HBA_PORTSPEED_32GFC;
+			break;
+		default:
+			ae->un.AttrInt = HBA_PORTSPEED_UNKNOWN;
+			break;
+		}
+	} else {
+		switch (phba->fc_linkspeed) {
+		case LPFC_ASYNC_LINK_SPEED_10GBPS:
+			ae->un.AttrInt = HBA_PORTSPEED_10GE;
+			break;
+		case LPFC_ASYNC_LINK_SPEED_25GBPS:
+			ae->un.AttrInt = HBA_PORTSPEED_25GE;
+			break;
+		case LPFC_ASYNC_LINK_SPEED_40GBPS:
+			ae->un.AttrInt = HBA_PORTSPEED_40GE;
+			break;
+		case LPFC_ASYNC_LINK_SPEED_100GBPS:
+			ae->un.AttrInt = HBA_PORTSPEED_100GE;
+			break;
+		default:
+			ae->un.AttrInt = HBA_PORTSPEED_UNKNOWN;
+			break;
+		}
+	}
+
+	ae->un.AttrInt = cpu_to_be32(ae->un.AttrInt);
+	size = FOURBYTES + sizeof(uint32_t);
+	ad->AttrLen = cpu_to_be16(size);
+	ad->AttrType = cpu_to_be16(RPRT_PORT_SPEED);
+	return size;
+}
+
+int
+lpfc_fdmi_port_attr_max_frame(struct lpfc_vport *vport,
+			      struct lpfc_fdmi_attr_def *ad)
+{
+	struct serv_parm *hsp;
+	struct lpfc_fdmi_attr_entry *ae;
+	uint32_t size;
+
+	ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
+
+	hsp = (struct serv_parm *)&vport->fc_sparam;
+	ae->un.AttrInt = (((uint32_t) hsp->cmn.bbRcvSizeMsb) << 8) |
+			  (uint32_t) hsp->cmn.bbRcvSizeLsb;
+	ae->un.AttrInt = cpu_to_be32(ae->un.AttrInt);
+	size = FOURBYTES + sizeof(uint32_t);
+	ad->AttrLen = cpu_to_be16(size);
+	ad->AttrType = cpu_to_be16(RPRT_MAX_FRAME_SIZE);
+	return size;
+}
+
+int
+lpfc_fdmi_port_attr_os_devname(struct lpfc_vport *vport,
+			       struct lpfc_fdmi_attr_def *ad)
+{
+	struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
+	struct lpfc_fdmi_attr_entry *ae;
+	uint32_t len, size;
+
+	ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
+	memset(ae, 0, 256);
+
+	snprintf(ae->un.AttrString, sizeof(ae->un.AttrString),
+		 "/sys/class/scsi_host/host%d", shost->host_no);
+	len = strnlen((char *)ae->un.AttrString,
+			  sizeof(ae->un.AttrString));
+	len += (len & 3) ? (4 - (len & 3)) : 4;
+	size = FOURBYTES + len;
+	ad->AttrLen = cpu_to_be16(size);
+	ad->AttrType = cpu_to_be16(RPRT_OS_DEVICE_NAME);
+	return size;
+}
+
+int
+lpfc_fdmi_port_attr_host_name(struct lpfc_vport *vport,
+			      struct lpfc_fdmi_attr_def *ad)
+{
+	struct lpfc_fdmi_attr_entry *ae;
+	uint32_t len, size;
+
+	ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
+	memset(ae, 0, 256);
+
+	snprintf(ae->un.AttrString, sizeof(ae->un.AttrString), "%s",
+		 init_utsname()->nodename);
+
+	len = strnlen(ae->un.AttrString, sizeof(ae->un.AttrString));
+	len += (len & 3) ? (4 - (len & 3)) : 4;
+	size = FOURBYTES + len;
+	ad->AttrLen = cpu_to_be16(size);
+	ad->AttrType = cpu_to_be16(RPRT_HOST_NAME);
+	return size;
+}
+
+int
+lpfc_fdmi_port_attr_wwnn(struct lpfc_vport *vport,
+			 struct lpfc_fdmi_attr_def *ad)
+{
+	struct lpfc_fdmi_attr_entry *ae;
+	uint32_t size;
+
+	ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
+	memset(ae, 0,  sizeof(struct lpfc_name));
+
+	memcpy(&ae->un.AttrWWN, &vport->fc_sparam.nodeName,
+	       sizeof(struct lpfc_name));
+	size = FOURBYTES + sizeof(struct lpfc_name);
+	ad->AttrLen = cpu_to_be16(size);
+	ad->AttrType = cpu_to_be16(RPRT_NODENAME);
+	return size;
+}
+
+int
+lpfc_fdmi_port_attr_wwpn(struct lpfc_vport *vport,
+			 struct lpfc_fdmi_attr_def *ad)
+{
+	struct lpfc_fdmi_attr_entry *ae;
+	uint32_t size;
+
+	ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
+	memset(ae, 0,  sizeof(struct lpfc_name));
+
+	memcpy(&ae->un.AttrWWN, &vport->fc_sparam.portName,
+	       sizeof(struct lpfc_name));
+	size = FOURBYTES + sizeof(struct lpfc_name);
+	ad->AttrLen = cpu_to_be16(size);
+	ad->AttrType = cpu_to_be16(RPRT_PORTNAME);
+	return size;
+}
+
+int
+lpfc_fdmi_port_attr_symbolic_name(struct lpfc_vport *vport,
+				  struct lpfc_fdmi_attr_def *ad)
+{
+	struct lpfc_fdmi_attr_entry *ae;
+	uint32_t len, size;
+
+	ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
+	memset(ae, 0, 256);
+
+	len = lpfc_vport_symbolic_port_name(vport, ae->un.AttrString, 256);
+	len += (len & 3) ? (4 - (len & 3)) : 4;
+	size = FOURBYTES + len;
+	ad->AttrLen = cpu_to_be16(size);
+	ad->AttrType = cpu_to_be16(RPRT_SYM_PORTNAME);
+	return size;
+}
+
+int
+lpfc_fdmi_port_attr_port_type(struct lpfc_vport *vport,
+			      struct lpfc_fdmi_attr_def *ad)
+{
+	struct lpfc_hba *phba = vport->phba;
+	struct lpfc_fdmi_attr_entry *ae;
+	uint32_t size;
+
+	ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
+	if (phba->fc_topology == LPFC_TOPOLOGY_LOOP)
+		ae->un.AttrInt =  cpu_to_be32(LPFC_FDMI_PORTTYPE_NLPORT);
+	else
+		ae->un.AttrInt =  cpu_to_be32(LPFC_FDMI_PORTTYPE_NPORT);
+	size = FOURBYTES + sizeof(uint32_t);
+	ad->AttrLen = cpu_to_be16(size);
+	ad->AttrType = cpu_to_be16(RPRT_PORT_TYPE);
+	return size;
+}
+
+int
+lpfc_fdmi_port_attr_class(struct lpfc_vport *vport,
+			  struct lpfc_fdmi_attr_def *ad)
+{
+	struct lpfc_fdmi_attr_entry *ae;
+	uint32_t size;
+
+	ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
+	ae->un.AttrInt = cpu_to_be32(FC_COS_CLASS2 | FC_COS_CLASS3);
+	size = FOURBYTES + sizeof(uint32_t);
+	ad->AttrLen = cpu_to_be16(size);
+	ad->AttrType = cpu_to_be16(RPRT_SUPPORTED_CLASS);
+	return size;
+}
+
+int
+lpfc_fdmi_port_attr_fabric_wwpn(struct lpfc_vport *vport,
+				struct lpfc_fdmi_attr_def *ad)
+{
+	struct lpfc_fdmi_attr_entry *ae;
+	uint32_t size;
+
+	ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
+	memset(ae, 0,  sizeof(struct lpfc_name));
+
+	memcpy(&ae->un.AttrWWN, &vport->fabric_portname,
+	       sizeof(struct lpfc_name));
+	size = FOURBYTES + sizeof(struct lpfc_name);
+	ad->AttrLen = cpu_to_be16(size);
+	ad->AttrType = cpu_to_be16(RPRT_FABRICNAME);
+	return size;
+}
+
+int
+lpfc_fdmi_port_attr_active_fc4type(struct lpfc_vport *vport,
+				   struct lpfc_fdmi_attr_def *ad)
+{
+	struct lpfc_fdmi_attr_entry *ae;
+	uint32_t size;
+
+	ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
+	memset(ae, 0, 32);
+
+	ae->un.AttrTypes[3] = 0x02; /* Type 1 - ELS */
+	ae->un.AttrTypes[2] = 0x01; /* Type 8 - FCP */
+	ae->un.AttrTypes[7] = 0x01; /* Type 32 - CT */
+	size = FOURBYTES + 32;
+	ad->AttrLen = cpu_to_be16(size);
+	ad->AttrType = cpu_to_be16(RPRT_ACTIVE_FC4_TYPES);
+	return size;
+}
+
+int
+lpfc_fdmi_port_attr_port_state(struct lpfc_vport *vport,
+			       struct lpfc_fdmi_attr_def *ad)
+{
+	struct lpfc_fdmi_attr_entry *ae;
+	uint32_t size;
+
+	ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
+	/* Link Up - operational */
+	ae->un.AttrInt =  cpu_to_be32(LPFC_FDMI_PORTSTATE_ONLINE);
+	size = FOURBYTES + sizeof(uint32_t);
+	ad->AttrLen = cpu_to_be16(size);
+	ad->AttrType = cpu_to_be16(RPRT_PORT_STATE);
+	return size;
+}
+
+int
+lpfc_fdmi_port_attr_num_disc(struct lpfc_vport *vport,
+			     struct lpfc_fdmi_attr_def *ad)
+{
+	struct lpfc_fdmi_attr_entry *ae;
+	uint32_t size;
+
+	ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
+	vport->fdmi_num_disc = lpfc_find_map_node(vport);
+	ae->un.AttrInt = cpu_to_be32(vport->fdmi_num_disc);
+	size = FOURBYTES + sizeof(uint32_t);
+	ad->AttrLen = cpu_to_be16(size);
+	ad->AttrType = cpu_to_be16(RPRT_DISC_PORT);
+	return size;
+}
+
+int
+lpfc_fdmi_port_attr_nportid(struct lpfc_vport *vport,
+			    struct lpfc_fdmi_attr_def *ad)
+{
+	struct lpfc_fdmi_attr_entry *ae;
+	uint32_t size;
+
+	ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
+	ae->un.AttrInt =  cpu_to_be32(vport->fc_myDID);
+	size = FOURBYTES + sizeof(uint32_t);
+	ad->AttrLen = cpu_to_be16(size);
+	ad->AttrType = cpu_to_be16(RPRT_PORT_ID);
+	return size;
+}
+
+int
+lpfc_fdmi_smart_attr_service(struct lpfc_vport *vport,
+			     struct lpfc_fdmi_attr_def *ad)
+{
+	struct lpfc_fdmi_attr_entry *ae;
+	uint32_t len, size;
+
+	ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
+	memset(ae, 0, 256);
+
+	strncpy(ae->un.AttrString, "Smart SAN Initiator",
+		sizeof(ae->un.AttrString));
+	len = strnlen(ae->un.AttrString,
+			  sizeof(ae->un.AttrString));
+	len += (len & 3) ? (4 - (len & 3)) : 4;
+	size = FOURBYTES + len;
+	ad->AttrLen = cpu_to_be16(size);
+	ad->AttrType = cpu_to_be16(RPRT_SMART_SERVICE);
+	return size;
+}
+
+int
+lpfc_fdmi_smart_attr_guid(struct lpfc_vport *vport,
+			  struct lpfc_fdmi_attr_def *ad)
+{
+	struct lpfc_fdmi_attr_entry *ae;
+	uint32_t size;
+
+	ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
+	memset(ae, 0, 256);
+
+	memcpy(&ae->un.AttrString, &vport->fc_sparam.nodeName,
+	       sizeof(struct lpfc_name));
+	memcpy((((uint8_t *)&ae->un.AttrString) +
+		sizeof(struct lpfc_name)),
+		&vport->fc_sparam.portName, sizeof(struct lpfc_name));
+	size = FOURBYTES + (2 * sizeof(struct lpfc_name));
+	ad->AttrLen =  cpu_to_be16(size);
+	ad->AttrType = cpu_to_be16(RPRT_SMART_GUID);
+	return size;
+}
+
+int
+lpfc_fdmi_smart_attr_version(struct lpfc_vport *vport,
+			     struct lpfc_fdmi_attr_def *ad)
+{
+	struct lpfc_fdmi_attr_entry *ae;
+	uint32_t len, size;
+
+	ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
+	memset(ae, 0, 256);
+
+	strncpy(ae->un.AttrString, "Smart SAN Version 1.0",
+		sizeof(ae->un.AttrString));
+	len = strnlen(ae->un.AttrString,
+			  sizeof(ae->un.AttrString));
+	len += (len & 3) ? (4 - (len & 3)) : 4;
+	size = FOURBYTES + len;
+	ad->AttrLen =  cpu_to_be16(size);
+	ad->AttrType = cpu_to_be16(RPRT_SMART_VERSION);
+	return size;
+}
+
+int
+lpfc_fdmi_smart_attr_model(struct lpfc_vport *vport,
+			   struct lpfc_fdmi_attr_def *ad)
+{
+	struct lpfc_hba *phba = vport->phba;
+	struct lpfc_fdmi_attr_entry *ae;
+	uint32_t len, size;
+
+	ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
+	memset(ae, 0, 256);
+
+	strncpy(ae->un.AttrString, phba->ModelName,
+		sizeof(ae->un.AttrString));
+	len = strnlen(ae->un.AttrString, sizeof(ae->un.AttrString));
+	len += (len & 3) ? (4 - (len & 3)) : 4;
+	size = FOURBYTES + len;
+	ad->AttrLen = cpu_to_be16(size);
+	ad->AttrType = cpu_to_be16(RPRT_SMART_MODEL);
+	return size;
+}
+
+int
+lpfc_fdmi_smart_attr_port_info(struct lpfc_vport *vport,
+			       struct lpfc_fdmi_attr_def *ad)
+{
+	struct lpfc_fdmi_attr_entry *ae;
+	uint32_t size;
+
+	ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
+
+	/* SRIOV (type 3) is not supported */
+	if (vport->vpi)
+		ae->un.AttrInt =  cpu_to_be32(2);  /* NPIV */
+	else
+		ae->un.AttrInt =  cpu_to_be32(1);  /* Physical */
+	size = FOURBYTES + sizeof(uint32_t);
+	ad->AttrLen = cpu_to_be16(size);
+	ad->AttrType = cpu_to_be16(RPRT_SMART_PORT_INFO);
+	return size;
+}
+
+int
+lpfc_fdmi_smart_attr_qos(struct lpfc_vport *vport,
+			 struct lpfc_fdmi_attr_def *ad)
+{
+	struct lpfc_fdmi_attr_entry *ae;
+	uint32_t size;
+
+	ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
+	ae->un.AttrInt =  cpu_to_be32(0);
+	size = FOURBYTES + sizeof(uint32_t);
+	ad->AttrLen = cpu_to_be16(size);
+	ad->AttrType = cpu_to_be16(RPRT_SMART_QOS);
+	return size;
+}
+
+int
+lpfc_fdmi_smart_attr_security(struct lpfc_vport *vport,
+			      struct lpfc_fdmi_attr_def *ad)
+{
+	struct lpfc_fdmi_attr_entry *ae;
+	uint32_t size;
+
+	ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
+	ae->un.AttrInt =  cpu_to_be32(0);
+	size = FOURBYTES + sizeof(uint32_t);
+	ad->AttrLen = cpu_to_be16(size);
+	ad->AttrType = cpu_to_be16(RPRT_SMART_SECURITY);
+	return size;
+}
+
+/* RHBA attribute jump table */
+int (*lpfc_fdmi_hba_action[])
+	(struct lpfc_vport *vport, struct lpfc_fdmi_attr_def *ad) = {
+	/* Action routine                 Mask bit     Attribute type */
+	lpfc_fdmi_hba_attr_wwnn,	  /* bit0     RHBA_NODENAME           */
+	lpfc_fdmi_hba_attr_manufacturer,  /* bit1     RHBA_MANUFACTURER       */
+	lpfc_fdmi_hba_attr_sn,		  /* bit2     RHBA_SERIAL_NUMBER      */
+	lpfc_fdmi_hba_attr_model,	  /* bit3     RHBA_MODEL              */
+	lpfc_fdmi_hba_attr_description,	  /* bit4     RHBA_MODEL_DESCRIPTION  */
+	lpfc_fdmi_hba_attr_hdw_ver,	  /* bit5     RHBA_HARDWARE_VERSION   */
+	lpfc_fdmi_hba_attr_drvr_ver,	  /* bit6     RHBA_DRIVER_VERSION     */
+	lpfc_fdmi_hba_attr_rom_ver,	  /* bit7     RHBA_OPTION_ROM_VERSION */
+	lpfc_fdmi_hba_attr_fmw_ver,	  /* bit8     RHBA_FIRMWARE_VERSION   */
+	lpfc_fdmi_hba_attr_os_ver,	  /* bit9     RHBA_OS_NAME_VERSION    */
+	lpfc_fdmi_hba_attr_ct_len,	  /* bit10    RHBA_MAX_CT_PAYLOAD_LEN */
+	lpfc_fdmi_hba_attr_symbolic_name, /* bit11    RHBA_SYM_NODENAME       */
+	lpfc_fdmi_hba_attr_vendor_info,	  /* bit12    RHBA_VENDOR_INFO        */
+	lpfc_fdmi_hba_attr_num_ports,	  /* bit13    RHBA_NUM_PORTS          */
+	lpfc_fdmi_hba_attr_fabric_wwnn,	  /* bit14    RHBA_FABRIC_WWNN        */
+	lpfc_fdmi_hba_attr_bios_ver,	  /* bit15    RHBA_BIOS_VERSION       */
+	lpfc_fdmi_hba_attr_bios_state,	  /* bit16    RHBA_BIOS_STATE         */
+	lpfc_fdmi_hba_attr_vendor_id,	  /* bit17    RHBA_VENDOR_ID          */
+};
+
+/* RPA / RPRT attribute jump table */
+int (*lpfc_fdmi_port_action[])
+	(struct lpfc_vport *vport, struct lpfc_fdmi_attr_def *ad) = {
+	/* Action routine                   Mask bit   Attribute type */
+	lpfc_fdmi_port_attr_fc4type,        /* bit0   RPRT_SUPPORT_FC4_TYPES  */
+	lpfc_fdmi_port_attr_support_speed,  /* bit1   RPRT_SUPPORTED_SPEED    */
+	lpfc_fdmi_port_attr_speed,          /* bit2   RPRT_PORT_SPEED         */
+	lpfc_fdmi_port_attr_max_frame,      /* bit3   RPRT_MAX_FRAME_SIZE     */
+	lpfc_fdmi_port_attr_os_devname,     /* bit4   RPRT_OS_DEVICE_NAME     */
+	lpfc_fdmi_port_attr_host_name,      /* bit5   RPRT_HOST_NAME          */
+	lpfc_fdmi_port_attr_wwnn,           /* bit6   RPRT_NODENAME           */
+	lpfc_fdmi_port_attr_wwpn,           /* bit7   RPRT_PORTNAME           */
+	lpfc_fdmi_port_attr_symbolic_name,  /* bit8   RPRT_SYM_PORTNAME       */
+	lpfc_fdmi_port_attr_port_type,      /* bit9   RPRT_PORT_TYPE          */
+	lpfc_fdmi_port_attr_class,          /* bit10  RPRT_SUPPORTED_CLASS    */
+	lpfc_fdmi_port_attr_fabric_wwpn,    /* bit11  RPRT_FABRICNAME         */
+	lpfc_fdmi_port_attr_active_fc4type, /* bit12  RPRT_ACTIVE_FC4_TYPES   */
+	lpfc_fdmi_port_attr_port_state,     /* bit13  RPRT_PORT_STATE         */
+	lpfc_fdmi_port_attr_num_disc,       /* bit14  RPRT_DISC_PORT          */
+	lpfc_fdmi_port_attr_nportid,        /* bit15  RPRT_PORT_ID            */
+	lpfc_fdmi_smart_attr_service,       /* bit16  RPRT_SMART_SERVICE      */
+	lpfc_fdmi_smart_attr_guid,          /* bit17  RPRT_SMART_GUID         */
+	lpfc_fdmi_smart_attr_version,       /* bit18  RPRT_SMART_VERSION      */
+	lpfc_fdmi_smart_attr_model,         /* bit19  RPRT_SMART_MODEL        */
+	lpfc_fdmi_smart_attr_port_info,     /* bit20  RPRT_SMART_PORT_INFO    */
+	lpfc_fdmi_smart_attr_qos,           /* bit21  RPRT_SMART_QOS          */
+	lpfc_fdmi_smart_attr_security,      /* bit22  RPRT_SMART_SECURITY     */
+};
+
+/**
+ * lpfc_fdmi_cmd - Build and send a FDMI cmd to the specified NPort
+ * @vport: pointer to a host virtual N_Port data structure.
+ * @ndlp: ndlp to send FDMI cmd to (if NULL use FDMI_DID)
+ * cmdcode: FDMI command to send
+ * mask: Mask of HBA or PORT Attributes to send
+ *
+ * Builds and sends a FDMI command using the CT subsystem.
+ */
+int
+lpfc_fdmi_cmd(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
+	      int cmdcode, uint32_t new_mask)
 {
 	struct lpfc_hba *phba = vport->phba;
 	struct lpfc_dmabuf *mp, *bmp;
 	struct lpfc_sli_ct_request *CtReq;
 	struct ulp_bde64 *bpl;
+	uint32_t bit_pos;
 	uint32_t size;
 	uint32_t rsp_size;
+	uint32_t mask;
 	struct lpfc_fdmi_reg_hba *rh;
 	struct lpfc_fdmi_port_entry *pe;
 	struct lpfc_fdmi_reg_portattr *pab = NULL;
 	struct lpfc_fdmi_attr_block *ab = NULL;
-	struct lpfc_fdmi_attr_entry *ae;
-	struct lpfc_fdmi_attr_def *ad;
-	void (*cmpl) (struct lpfc_hba *, struct lpfc_iocbq *,
-		      struct lpfc_iocbq *);
+	int  (*func)(struct lpfc_vport *vport, struct lpfc_fdmi_attr_def *ad);
+	void (*cmpl)(struct lpfc_hba *, struct lpfc_iocbq *,
+		     struct lpfc_iocbq *);
 
-	if (ndlp == NULL) {
-		ndlp = lpfc_findnode_did(vport, FDMI_DID);
-		if (!ndlp || !NLP_CHK_NODE_ACT(ndlp))
-			return 0;
-		cmpl = lpfc_cmpl_ct_cmd_fdmi; /* cmd interface */
-	} else {
-		cmpl = lpfc_cmpl_ct_disc_fdmi; /* called from discovery */
-	}
+	if (!ndlp || !NLP_CHK_NODE_ACT(ndlp))
+		return 0;
+
+	cmpl = lpfc_cmpl_ct_disc_fdmi; /* called from discovery */
 
 	/* fill in BDEs for command */
 	/* Allocate buffer for command payload */
@@ -1470,573 +2535,99 @@ lpfc_fdmi_cmd(struct lpfc_vport *vport,
 	switch (cmdcode) {
 	case SLI_MGMT_RHAT:
 	case SLI_MGMT_RHBA:
-		{
-			lpfc_vpd_t *vp = &phba->vpd;
-			uint32_t i, j, incr;
-			int len = 0;
+		rh = (struct lpfc_fdmi_reg_hba *)&CtReq->un.PortID;
+		/* HBA Identifier */
+		memcpy(&rh->hi.PortName, &phba->pport->fc_sparam.portName,
+		       sizeof(struct lpfc_name));
 
-			rh = (struct lpfc_fdmi_reg_hba *)&CtReq->un.PortID;
-			/* HBA Identifier */
-			memcpy(&rh->hi.PortName, &vport->fc_sparam.portName,
+		if (cmdcode == SLI_MGMT_RHBA) {
+			/* Registered Port List */
+			/* One entry (port) per adapter */
+			rh->rpl.EntryCnt = cpu_to_be32(1);
+			memcpy(&rh->rpl.pe, &phba->pport->fc_sparam.portName,
 			       sizeof(struct lpfc_name));
 
-			if (cmdcode == SLI_MGMT_RHBA) {
-				/* Registered Port List */
-				/* One entry (port) per adapter */
-				rh->rpl.EntryCnt = cpu_to_be32(1);
-				memcpy(&rh->rpl.pe, &vport->fc_sparam.portName,
-				       sizeof(struct lpfc_name));
-
-				/* point to the HBA attribute block */
-				size = 2 * sizeof(struct lpfc_name) +
-					FOURBYTES;
-			} else {
-				size = sizeof(struct lpfc_name);
-			}
-			ab = (struct lpfc_fdmi_attr_block *)
-				((uint8_t *)rh + size);
-			ab->EntryCnt = 0;
-			size += FOURBYTES;
+			/* point to the HBA attribute block */
+			size = 2 * sizeof(struct lpfc_name) +
+				FOURBYTES;
+		} else {
+			size = sizeof(struct lpfc_name);
+		}
+		ab = (struct lpfc_fdmi_attr_block *)((uint8_t *)rh + size);
+		ab->EntryCnt = 0;
+		size += FOURBYTES;
+		bit_pos = 0;
+		if (new_mask)
+			mask = new_mask;
+		else
+			mask = vport->fdmi_hba_mask;
 
-			/*
-			 * Point to beginning of first HBA attribute entry
-			 */
-			/* #1 HBA attribute entry */
-			ad = (struct lpfc_fdmi_attr_def *)
-				((uint8_t *)rh + size);
-			ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
-			memset(ae, 0, sizeof(struct lpfc_name));
-			ad->AttrType = cpu_to_be16(RHBA_NODENAME);
-			ad->AttrLen =  cpu_to_be16(FOURBYTES
-						+ sizeof(struct lpfc_name));
-			memcpy(&ae->un.NodeName, &vport->fc_sparam.nodeName,
-			       sizeof(struct lpfc_name));
-			ab->EntryCnt++;
-			size += FOURBYTES + sizeof(struct lpfc_name);
-			if ((size + LPFC_FDMI_MAX_AE_SIZE) >
-					(LPFC_BPL_SIZE - LPFC_CT_PREAMBLE))
-				goto hba_out;
-
-			/* #2 HBA attribute entry */
-			ad = (struct lpfc_fdmi_attr_def *)
-				((uint8_t *)rh + size);
-			ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
-			memset(ae, 0, sizeof(ae->un.Manufacturer));
-			ad->AttrType = cpu_to_be16(RHBA_MANUFACTURER);
-			strncpy(ae->un.Manufacturer, "Emulex Corporation",
-				sizeof(ae->un.Manufacturer));
-			len = strnlen(ae->un.Manufacturer,
-					  sizeof(ae->un.Manufacturer));
-			len += (len & 3) ? (4 - (len & 3)) : 4;
-			ad->AttrLen = cpu_to_be16(FOURBYTES + len);
-			ab->EntryCnt++;
-			size += FOURBYTES + len;
-			if ((size + LPFC_FDMI_MAX_AE_SIZE) >
-					(LPFC_BPL_SIZE - LPFC_CT_PREAMBLE))
-				goto hba_out;
-
-			/* #3 HBA attribute entry */
-			ad = (struct lpfc_fdmi_attr_def *)
-				((uint8_t *)rh + size);
-			ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
-			memset(ae, 0, sizeof(ae->un.SerialNumber));
-			ad->AttrType = cpu_to_be16(RHBA_SERIAL_NUMBER);
-			strncpy(ae->un.SerialNumber, phba->SerialNumber,
-				sizeof(ae->un.SerialNumber));
-			len = strnlen(ae->un.SerialNumber,
-					  sizeof(ae->un.SerialNumber));
-			len += (len & 3) ? (4 - (len & 3)) : 4;
-			ad->AttrLen = cpu_to_be16(FOURBYTES + len);
-			ab->EntryCnt++;
-			size += FOURBYTES + len;
-			if ((size + LPFC_FDMI_MAX_AE_SIZE) >
-					(LPFC_BPL_SIZE - LPFC_CT_PREAMBLE))
-				goto hba_out;
-
-			/* #4 HBA attribute entry */
-			ad = (struct lpfc_fdmi_attr_def *)
-				((uint8_t *)rh + size);
-			ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
-			memset(ae, 0, sizeof(ae->un.Model));
-			ad->AttrType = cpu_to_be16(RHBA_MODEL);
-			strncpy(ae->un.Model, phba->ModelName,
-				sizeof(ae->un.Model));
-			len = strnlen(ae->un.Model, sizeof(ae->un.Model));
-			len += (len & 3) ? (4 - (len & 3)) : 4;
-			ad->AttrLen = cpu_to_be16(FOURBYTES + len);
-			ab->EntryCnt++;
-			size += FOURBYTES + len;
-			if ((size + LPFC_FDMI_MAX_AE_SIZE) >
-					(LPFC_BPL_SIZE - LPFC_CT_PREAMBLE))
-				goto hba_out;
-
-			/* #5 HBA attribute entry */
-			ad = (struct lpfc_fdmi_attr_def *)
-				((uint8_t *)rh + size);
-			ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
-			memset(ae, 0, sizeof(ae->un.ModelDescription));
-			ad->AttrType = cpu_to_be16(RHBA_MODEL_DESCRIPTION);
-			strncpy(ae->un.ModelDescription, phba->ModelDesc,
-				sizeof(ae->un.ModelDescription));
-			len = strnlen(ae->un.ModelDescription,
-					  sizeof(ae->un.ModelDescription));
-			len += (len & 3) ? (4 - (len & 3)) : 4;
-			ad->AttrLen = cpu_to_be16(FOURBYTES + len);
-			ab->EntryCnt++;
-			size += FOURBYTES + len;
-			if ((size + 8) > (LPFC_BPL_SIZE - LPFC_CT_PREAMBLE))
-				goto hba_out;
-
-			/* #6 HBA attribute entry */
-			ad = (struct lpfc_fdmi_attr_def *)
-				((uint8_t *)rh + size);
-			ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
-			memset(ae, 0, 8);
-			ad->AttrType = cpu_to_be16(RHBA_HARDWARE_VERSION);
-			ad->AttrLen = cpu_to_be16(FOURBYTES + 8);
-			/* Convert JEDEC ID to ascii for hardware version */
-			incr = vp->rev.biuRev;
-			for (i = 0; i < 8; i++) {
-				j = (incr & 0xf);
-				if (j <= 9)
-					ae->un.HardwareVersion[7 - i] =
-					    (char)((uint8_t)0x30 +
-						   (uint8_t)j);
-				else
-					ae->un.HardwareVersion[7 - i] =
-					    (char)((uint8_t)0x61 +
-						   (uint8_t)(j - 10));
-				incr = (incr >> 4);
+		/* Mask will dictate what attributes to build in the request */
+		while (mask) {
+			if (mask & 0x1) {
+				func = lpfc_fdmi_hba_action[bit_pos];
+				size += func(vport,
+					     (struct lpfc_fdmi_attr_def *)
+					     ((uint8_t *)rh + size));
+				ab->EntryCnt++;
+				if ((size + 256) >
+				    (LPFC_BPL_SIZE - LPFC_CT_PREAMBLE))
+					goto hba_out;
 			}
-			ab->EntryCnt++;
-			size += FOURBYTES + 8;
-			if ((size + LPFC_FDMI_MAX_AE_SIZE) >
-					(LPFC_BPL_SIZE - LPFC_CT_PREAMBLE))
-				goto hba_out;
-
-			/* #7 HBA attribute entry */
-			ad = (struct lpfc_fdmi_attr_def *)
-				((uint8_t *)rh + size);
-			ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
-			memset(ae, 0, sizeof(ae->un.DriverVersion));
-			ad->AttrType = cpu_to_be16(RHBA_DRIVER_VERSION);
-			strncpy(ae->un.DriverVersion, lpfc_release_version,
-				sizeof(ae->un.DriverVersion));
-			len = strnlen(ae->un.DriverVersion,
-					sizeof(ae->un.DriverVersion));
-			len += (len & 3) ? (4 - (len & 3)) : 4;
-			ad->AttrLen = cpu_to_be16(FOURBYTES + len);
-			ab->EntryCnt++;
-			size += FOURBYTES + len;
-			if ((size + LPFC_FDMI_MAX_AE_SIZE) >
-					(LPFC_BPL_SIZE - LPFC_CT_PREAMBLE))
-				goto hba_out;
-
-			/* #8 HBA attribute entry */
-			ad = (struct lpfc_fdmi_attr_def *)
-				((uint8_t *)rh + size);
-			ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
-			memset(ae, 0, sizeof(ae->un.OptionROMVersion));
-			ad->AttrType = cpu_to_be16(RHBA_OPTION_ROM_VERSION);
-			strncpy(ae->un.OptionROMVersion, phba->OptionROMVersion,
-				sizeof(ae->un.OptionROMVersion));
-			len = strnlen(ae->un.OptionROMVersion,
-				      sizeof(ae->un.OptionROMVersion));
-			len += (len & 3) ? (4 - (len & 3)) : 4;
-			ad->AttrLen = cpu_to_be16(FOURBYTES + len);
-			ab->EntryCnt++;
-			size += FOURBYTES + len;
-			if ((size + LPFC_FDMI_MAX_AE_SIZE) >
-					(LPFC_BPL_SIZE - LPFC_CT_PREAMBLE))
-				goto hba_out;
-
-			/* #9 HBA attribute entry */
-			ad = (struct lpfc_fdmi_attr_def *)
-				((uint8_t *)rh + size);
-			ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
-			memset(ae, 0, sizeof(ae->un.FirmwareVersion));
-			ad->AttrType = cpu_to_be16(RHBA_FIRMWARE_VERSION);
-			lpfc_decode_firmware_rev(phba, ae->un.FirmwareVersion,
-				1);
-			len = strnlen(ae->un.FirmwareVersion,
-					sizeof(ae->un.FirmwareVersion));
-			len += (len & 3) ? (4 - (len & 3)) : 4;
-			ad->AttrLen = cpu_to_be16(FOURBYTES + len);
-			ab->EntryCnt++;
-			size += FOURBYTES + len;
-			if ((size + LPFC_FDMI_MAX_AE_SIZE) >
-					(LPFC_BPL_SIZE - LPFC_CT_PREAMBLE))
-				goto hba_out;
-
-			/* #10 HBA attribute entry */
-			ad = (struct lpfc_fdmi_attr_def *)
-				((uint8_t *)rh + size);
-			ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
-			memset(ae, 0, sizeof(ae->un.OsNameVersion));
-			ad->AttrType = cpu_to_be16(RHBA_OS_NAME_VERSION);
-			snprintf(ae->un.OsNameVersion,
-				 sizeof(ae->un.OsNameVersion),
-				 "%s %s %s",
-				 init_utsname()->sysname,
-				 init_utsname()->release,
-				 init_utsname()->version);
-			len = strnlen(ae->un.OsNameVersion,
-				      sizeof(ae->un.OsNameVersion));
-			len += (len & 3) ? (4 - (len & 3)) : 4;
-			ad->AttrLen = cpu_to_be16(FOURBYTES + len);
-			ab->EntryCnt++;
-			size += FOURBYTES + len;
-			if ((size + 4) > (LPFC_BPL_SIZE - LPFC_CT_PREAMBLE))
-				goto hba_out;
-
-			/* #11 HBA attribute entry */
-			ad = (struct lpfc_fdmi_attr_def *)
-				((uint8_t *)rh + size);
-			ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
-			ad->AttrType =
-				cpu_to_be16(RHBA_MAX_CT_PAYLOAD_LEN);
-			ad->AttrLen = cpu_to_be16(FOURBYTES + 4);
-			ae->un.MaxCTPayloadLen = cpu_to_be32(LPFC_MAX_CT_SIZE);
-			ab->EntryCnt++;
-			size += FOURBYTES + 4;
-			if ((size + LPFC_FDMI_MAX_AE_SIZE) >
-					(LPFC_BPL_SIZE - LPFC_CT_PREAMBLE))
-				goto hba_out;
-
-			/*
-			 * Currently switches don't seem to support the
-			 * following extended HBA attributes.
-			 */
-			if (!(vport->cfg_fdmi_on & LPFC_FDMI_ALL_ATTRIB))
-				goto hba_out;
-
-			/* #12 HBA attribute entry */
-			ad = (struct lpfc_fdmi_attr_def *)
-				((uint8_t *)rh + size);
-			ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
-			memset(ae, 0, sizeof(ae->un.NodeSymName));
-			ad->AttrType = cpu_to_be16(RHBA_SYM_NODENAME);
-			len = lpfc_vport_symbolic_node_name(vport,
-				ae->un.NodeSymName, sizeof(ae->un.NodeSymName));
-			len += (len & 3) ? (4 - (len & 3)) : 4;
-			ad->AttrLen = cpu_to_be16(FOURBYTES + len);
-			ab->EntryCnt++;
-			size += FOURBYTES + len;
-hba_out:
-			ab->EntryCnt = cpu_to_be32(ab->EntryCnt);
-			/* Total size */
-			size = GID_REQUEST_SZ - 4 + size;
+			mask = mask >> 1;
+			bit_pos++;
 		}
+hba_out:
+		ab->EntryCnt = cpu_to_be32(ab->EntryCnt);
+		/* Total size */
+		size = GID_REQUEST_SZ - 4 + size;
 		break;
 
 	case SLI_MGMT_RPRT:
 	case SLI_MGMT_RPA:
-		{
-			struct serv_parm *hsp;
-			int len = 0;
-
-			if (cmdcode == SLI_MGMT_RPRT) {
-				rh = (struct lpfc_fdmi_reg_hba *)
-					&CtReq->un.PortID;
-				/* HBA Identifier */
-				memcpy(&rh->hi.PortName,
-				       &vport->fc_sparam.portName,
-				       sizeof(struct lpfc_name));
-				pab = (struct lpfc_fdmi_reg_portattr *)
-					&rh->rpl.EntryCnt;
-			} else
-				pab = (struct lpfc_fdmi_reg_portattr *)
-					&CtReq->un.PortID;
-			size = sizeof(struct lpfc_name) + FOURBYTES;
-			memcpy((uint8_t *)&pab->PortName,
-			       (uint8_t *)&vport->fc_sparam.portName,
+		pab = (struct lpfc_fdmi_reg_portattr *)&CtReq->un.PortID;
+		if (cmdcode == SLI_MGMT_RPRT) {
+			rh = (struct lpfc_fdmi_reg_hba *)pab;
+			/* HBA Identifier */
+			memcpy(&rh->hi.PortName,
+			       &phba->pport->fc_sparam.portName,
 			       sizeof(struct lpfc_name));
-			pab->ab.EntryCnt = 0;
-
-			/* #1 Port attribute entry */
-			ad = (struct lpfc_fdmi_attr_def *)
-				((uint8_t *)pab + size);
-			ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
-			memset(ae, 0, sizeof(ae->un.FC4Types));
-			ad->AttrType =
-				cpu_to_be16(RPRT_SUPPORTED_FC4_TYPES);
-			ad->AttrLen = cpu_to_be16(FOURBYTES + 32);
-			ae->un.FC4Types[0] = 0x40; /* Type 1 - ELS */
-			ae->un.FC4Types[1] = 0x80; /* Type 8 - FCP */
-			ae->un.FC4Types[4] = 0x80; /* Type 32 - CT */
-			pab->ab.EntryCnt++;
-			size += FOURBYTES + 32;
-
-			/* #2 Port attribute entry */
-			ad = (struct lpfc_fdmi_attr_def *)
-				((uint8_t *)pab + size);
-			ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
-			ad->AttrType = cpu_to_be16(RPRT_SUPPORTED_SPEED);
-			ad->AttrLen = cpu_to_be16(FOURBYTES + 4);
-			ae->un.SupportSpeed = 0;
-			if (phba->lmt & LMT_32Gb)
-				ae->un.SupportSpeed |= HBA_PORTSPEED_32GBIT;
-			if (phba->lmt & LMT_16Gb)
-				ae->un.SupportSpeed |= HBA_PORTSPEED_16GBIT;
-			if (phba->lmt & LMT_10Gb)
-				ae->un.SupportSpeed |= HBA_PORTSPEED_10GBIT;
-			if (phba->lmt & LMT_8Gb)
-				ae->un.SupportSpeed |= HBA_PORTSPEED_8GBIT;
-			if (phba->lmt & LMT_4Gb)
-				ae->un.SupportSpeed |= HBA_PORTSPEED_4GBIT;
-			if (phba->lmt & LMT_2Gb)
-				ae->un.SupportSpeed |= HBA_PORTSPEED_2GBIT;
-			if (phba->lmt & LMT_1Gb)
-				ae->un.SupportSpeed |= HBA_PORTSPEED_1GBIT;
-			ae->un.SupportSpeed =
-				cpu_to_be32(ae->un.SupportSpeed);
-
-			pab->ab.EntryCnt++;
-			size += FOURBYTES + 4;
-
-			/* #3 Port attribute entry */
-			ad = (struct lpfc_fdmi_attr_def *)
-				((uint8_t *)pab + size);
-			ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
-			ad->AttrType = cpu_to_be16(RPRT_PORT_SPEED);
-			ad->AttrLen = cpu_to_be16(FOURBYTES + 4);
-			switch (phba->fc_linkspeed) {
-			case LPFC_LINK_SPEED_1GHZ:
-				ae->un.PortSpeed = HBA_PORTSPEED_1GBIT;
-				break;
-			case LPFC_LINK_SPEED_2GHZ:
-				ae->un.PortSpeed = HBA_PORTSPEED_2GBIT;
-				break;
-			case LPFC_LINK_SPEED_4GHZ:
-				ae->un.PortSpeed = HBA_PORTSPEED_4GBIT;
-				break;
-			case LPFC_LINK_SPEED_8GHZ:
-				ae->un.PortSpeed = HBA_PORTSPEED_8GBIT;
-				break;
-			case LPFC_LINK_SPEED_10GHZ:
-				ae->un.PortSpeed = HBA_PORTSPEED_10GBIT;
-				break;
-			case LPFC_LINK_SPEED_16GHZ:
-				ae->un.PortSpeed = HBA_PORTSPEED_16GBIT;
-				break;
-			case LPFC_LINK_SPEED_32GHZ:
-				ae->un.PortSpeed = HBA_PORTSPEED_32GBIT;
-				break;
-			default:
-				ae->un.PortSpeed = HBA_PORTSPEED_UNKNOWN;
-				break;
-			}
-			ae->un.PortSpeed = cpu_to_be32(ae->un.PortSpeed);
-			pab->ab.EntryCnt++;
-			size += FOURBYTES + 4;
-
-			/* #4 Port attribute entry */
-			ad = (struct lpfc_fdmi_attr_def *)
-				((uint8_t *)pab + size);
-			ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
-			ad->AttrType = cpu_to_be16(RPRT_MAX_FRAME_SIZE);
-			ad->AttrLen = cpu_to_be16(FOURBYTES + 4);
-			hsp = (struct serv_parm *)&vport->fc_sparam;
-			ae->un.MaxFrameSize =
-			    (((uint32_t)hsp->cmn.
-			      bbRcvSizeMsb) << 8) | (uint32_t)hsp->cmn.
-			    bbRcvSizeLsb;
-			ae->un.MaxFrameSize =
-				cpu_to_be32(ae->un.MaxFrameSize);
-			pab->ab.EntryCnt++;
-			size += FOURBYTES + 4;
-			if ((size + LPFC_FDMI_MAX_AE_SIZE) >
-					(LPFC_BPL_SIZE - LPFC_CT_PREAMBLE))
-				goto port_out;
-
-			/* #5 Port attribute entry */
-			ad = (struct lpfc_fdmi_attr_def *)
-				((uint8_t *)pab + size);
-			ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
-			memset(ae, 0, sizeof(ae->un.OsDeviceName));
-			ad->AttrType = cpu_to_be16(RPRT_OS_DEVICE_NAME);
-			strncpy((char *)ae->un.OsDeviceName, LPFC_DRIVER_NAME,
-				sizeof(ae->un.OsDeviceName));
-			len = strnlen((char *)ae->un.OsDeviceName,
-					  sizeof(ae->un.OsDeviceName));
-			len += (len & 3) ? (4 - (len & 3)) : 4;
-			ad->AttrLen = cpu_to_be16(FOURBYTES + len);
-			pab->ab.EntryCnt++;
-			size += FOURBYTES + len;
-			if ((size + LPFC_FDMI_MAX_AE_SIZE) >
-					(LPFC_BPL_SIZE - LPFC_CT_PREAMBLE))
-				goto port_out;
-
-			/* #6 Port attribute entry */
-			ad = (struct lpfc_fdmi_attr_def *)
-				((uint8_t *)pab + size);
-			ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
-			memset(ae, 0, sizeof(ae->un.HostName));
-			snprintf(ae->un.HostName, sizeof(ae->un.HostName), "%s",
-				 init_utsname()->nodename);
-			ad->AttrType = cpu_to_be16(RPRT_HOST_NAME);
-			len = strnlen(ae->un.HostName,
-					sizeof(ae->un.HostName));
-			len += (len & 3) ? (4 - (len & 3)) : 4;
-			ad->AttrLen =
-				cpu_to_be16(FOURBYTES + len);
-			pab->ab.EntryCnt++;
-			size += FOURBYTES + len;
-			if ((size + sizeof(struct lpfc_name)) >
-					(LPFC_BPL_SIZE - LPFC_CT_PREAMBLE))
-				goto port_out;
+			pab = (struct lpfc_fdmi_reg_portattr *)
+				((uint8_t *)pab +  sizeof(struct lpfc_name));
+		}
 
-			/*
-			 * Currently switches don't seem to support the
-			 * following extended Port attributes.
-			 */
-			if (!(vport->cfg_fdmi_on & LPFC_FDMI_ALL_ATTRIB))
-				goto port_out;
+		memcpy((uint8_t *)&pab->PortName,
+		       (uint8_t *)&vport->fc_sparam.portName,
+		       sizeof(struct lpfc_name));
+		size += sizeof(struct lpfc_name) + FOURBYTES;
+		pab->ab.EntryCnt = 0;
+		bit_pos = 0;
+		if (new_mask)
+			mask = new_mask;
+		else
+			mask = vport->fdmi_port_mask;
 
-			/* #7 Port attribute entry */
-			ad = (struct lpfc_fdmi_attr_def *)
-				((uint8_t *)pab + size);
-			ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
-			memset(ae, 0,  sizeof(struct lpfc_name));
-			ad->AttrType = cpu_to_be16(RPRT_NODENAME);
-			ad->AttrLen =  cpu_to_be16(FOURBYTES
-						+ sizeof(struct lpfc_name));
-			memcpy(&ae->un.NodeName, &vport->fc_sparam.nodeName,
-			       sizeof(struct lpfc_name));
-			pab->ab.EntryCnt++;
-			size += FOURBYTES + sizeof(struct lpfc_name);
-			if ((size + sizeof(struct lpfc_name)) >
-					(LPFC_BPL_SIZE - LPFC_CT_PREAMBLE))
-				goto port_out;
-
-			/* #8 Port attribute entry */
-			ad = (struct lpfc_fdmi_attr_def *)
-				((uint8_t *)pab + size);
-			ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
-			memset(ae, 0,  sizeof(struct lpfc_name));
-			ad->AttrType = cpu_to_be16(RPRT_PORTNAME);
-			ad->AttrLen =  cpu_to_be16(FOURBYTES
-						+ sizeof(struct lpfc_name));
-			memcpy(&ae->un.PortName, &vport->fc_sparam.portName,
-			       sizeof(struct lpfc_name));
-			pab->ab.EntryCnt++;
-			size += FOURBYTES + sizeof(struct lpfc_name);
-			if ((size + LPFC_FDMI_MAX_AE_SIZE) >
-					(LPFC_BPL_SIZE - LPFC_CT_PREAMBLE))
-				goto port_out;
-
-			/* #9 Port attribute entry */
-			ad = (struct lpfc_fdmi_attr_def *)
-				((uint8_t *)pab + size);
-			ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
-			memset(ae, 0, sizeof(ae->un.NodeSymName));
-			ad->AttrType = cpu_to_be16(RPRT_SYM_PORTNAME);
-			len = lpfc_vport_symbolic_port_name(vport,
-				ae->un.NodeSymName, sizeof(ae->un.NodeSymName));
-			len += (len & 3) ? (4 - (len & 3)) : 4;
-			ad->AttrLen = cpu_to_be16(FOURBYTES + len);
-			pab->ab.EntryCnt++;
-			size += FOURBYTES + len;
-			if ((size + 4) > (LPFC_BPL_SIZE - LPFC_CT_PREAMBLE))
-				goto port_out;
-
-			/* #10 Port attribute entry */
-			ad = (struct lpfc_fdmi_attr_def *)
-				((uint8_t *)pab + size);
-			ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
-			ad->AttrType = cpu_to_be16(RPRT_PORT_TYPE);
-			ae->un.PortState = 0;
-			ad->AttrLen = cpu_to_be16(FOURBYTES + 4);
-			pab->ab.EntryCnt++;
-			size += FOURBYTES + 4;
-			if ((size + 4) > (LPFC_BPL_SIZE - LPFC_CT_PREAMBLE))
-				goto port_out;
-
-			/* #11 Port attribute entry */
-			ad = (struct lpfc_fdmi_attr_def *)
-				((uint8_t *)pab + size);
-			ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
-			ad->AttrType = cpu_to_be16(RPRT_SUPPORTED_CLASS);
-			ae->un.SupportClass =
-				cpu_to_be32(FC_COS_CLASS2 | FC_COS_CLASS3);
-			ad->AttrLen = cpu_to_be16(FOURBYTES + 4);
-			pab->ab.EntryCnt++;
-			size += FOURBYTES + 4;
-			if ((size + sizeof(struct lpfc_name)) >
-					(LPFC_BPL_SIZE - LPFC_CT_PREAMBLE))
-				goto port_out;
-
-			/* #12 Port attribute entry */
-			ad = (struct lpfc_fdmi_attr_def *)
-				((uint8_t *)pab + size);
-			ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
-			memset(ae, 0, sizeof(struct lpfc_name));
-			ad->AttrType = cpu_to_be16(RPRT_FABRICNAME);
-			ad->AttrLen =  cpu_to_be16(FOURBYTES
-						+ sizeof(struct lpfc_name));
-			memcpy(&ae->un.FabricName, &vport->fabric_nodename,
-			       sizeof(struct lpfc_name));
-			pab->ab.EntryCnt++;
-			size += FOURBYTES + sizeof(struct lpfc_name);
-			if ((size + LPFC_FDMI_MAX_AE_SIZE) >
-					(LPFC_BPL_SIZE - LPFC_CT_PREAMBLE))
-				goto port_out;
-
-			/* #13 Port attribute entry */
-			ad = (struct lpfc_fdmi_attr_def *)
-				((uint8_t *)pab + size);
-			ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
-			memset(ae, 0, sizeof(ae->un.FC4Types));
-			ad->AttrType =
-				cpu_to_be16(RPRT_ACTIVE_FC4_TYPES);
-			ad->AttrLen = cpu_to_be16(FOURBYTES + 32);
-			ae->un.FC4Types[0] = 0x40; /* Type 1 - ELS */
-			ae->un.FC4Types[1] = 0x80; /* Type 8 - FCP */
-			ae->un.FC4Types[4] = 0x80; /* Type 32 - CT */
-			pab->ab.EntryCnt++;
-			size += FOURBYTES + 32;
-			if ((size + 4) > (LPFC_BPL_SIZE - LPFC_CT_PREAMBLE))
-				goto port_out;
-
-			/* #257 Port attribute entry */
-			ad = (struct lpfc_fdmi_attr_def *)
-				((uint8_t *)pab + size);
-			ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
-			ad->AttrType = cpu_to_be16(RPRT_PORT_STATE);
-			ae->un.PortState = 0;
-			ad->AttrLen = cpu_to_be16(FOURBYTES + 4);
-			pab->ab.EntryCnt++;
-			size += FOURBYTES + 4;
-			if ((size + 4) > (LPFC_BPL_SIZE - LPFC_CT_PREAMBLE))
-				goto port_out;
-
-			/* #258 Port attribute entry */
-			ad = (struct lpfc_fdmi_attr_def *)
-				((uint8_t *)pab + size);
-			ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
-			ad->AttrType = cpu_to_be16(RPRT_DISC_PORT);
-			ae->un.PortState = lpfc_find_map_node(vport);
-			ae->un.PortState = cpu_to_be32(ae->un.PortState);
-			ad->AttrLen = cpu_to_be16(FOURBYTES + 4);
-			pab->ab.EntryCnt++;
-			size += FOURBYTES + 4;
-			if ((size + 4) > (LPFC_BPL_SIZE - LPFC_CT_PREAMBLE))
-				goto port_out;
-
-			/* #259 Port attribute entry */
-			ad = (struct lpfc_fdmi_attr_def *)
-				((uint8_t *)pab + size);
-			ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
-			ad->AttrType = cpu_to_be16(RPRT_PORT_ID);
-			ae->un.PortId =  cpu_to_be32(vport->fc_myDID);
-			ad->AttrLen = cpu_to_be16(FOURBYTES + 4);
-			pab->ab.EntryCnt++;
-			size += FOURBYTES + 4;
-port_out:
-			pab->ab.EntryCnt = cpu_to_be32(pab->ab.EntryCnt);
-			/* Total size */
-			size = GID_REQUEST_SZ - 4 + size;
+		/* Mask will dictate what attributes to build in the request */
+		while (mask) {
+			if (mask & 0x1) {
+				func = lpfc_fdmi_port_action[bit_pos];
+				size += func(vport,
+					     (struct lpfc_fdmi_attr_def *)
+					     ((uint8_t *)pab + size));
+				pab->ab.EntryCnt++;
+				if ((size + 256) >
+				    (LPFC_BPL_SIZE - LPFC_CT_PREAMBLE))
+					goto port_out;
+			}
+			mask = mask >> 1;
+			bit_pos++;
 		}
+port_out:
+		pab->ab.EntryCnt = cpu_to_be32(pab->ab.EntryCnt);
+		/* Total size */
+		if (cmdcode == SLI_MGMT_RPRT)
+			size += sizeof(struct lpfc_name);
+		size = GID_REQUEST_SZ - 4 + size;
 		break;
 
 	case SLI_MGMT_GHAT:
@@ -2158,41 +2749,6 @@ lpfc_delayed_disc_timeout_handler(struct
 }
 
 void
-lpfc_fdmi_tmo(unsigned long ptr)
-{
-	struct lpfc_vport *vport = (struct lpfc_vport *)ptr;
-	struct lpfc_hba   *phba = vport->phba;
-	uint32_t tmo_posted;
-	unsigned long iflag;
-
-	spin_lock_irqsave(&vport->work_port_lock, iflag);
-	tmo_posted = vport->work_port_events & WORKER_FDMI_TMO;
-	if (!tmo_posted)
-		vport->work_port_events |= WORKER_FDMI_TMO;
-	spin_unlock_irqrestore(&vport->work_port_lock, iflag);
-
-	if (!tmo_posted)
-		lpfc_worker_wake_up(phba);
-	return;
-}
-
-void
-lpfc_fdmi_timeout_handler(struct lpfc_vport *vport)
-{
-	struct lpfc_nodelist *ndlp;
-
-	ndlp = lpfc_findnode_did(vport, FDMI_DID);
-	if (ndlp && NLP_CHK_NODE_ACT(ndlp)) {
-		if (init_utsname()->nodename[0] != '\0')
-			lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_DHBA);
-		else
-			mod_timer(&vport->fc_fdmitmo, jiffies +
-				  msecs_to_jiffies(1000 * 60));
-	}
-	return;
-}
-
-void
 lpfc_decode_firmware_rev(struct lpfc_hba *phba, char *fwrevision, int flag)
 {
 	struct lpfc_sli *psli = &phba->sli;
--- zfcpdump-kernel-4.4.orig/drivers/scsi/lpfc/lpfc_els.c
+++ zfcpdump-kernel-4.4/drivers/scsi/lpfc/lpfc_els.c
@@ -455,9 +455,9 @@ int
 lpfc_issue_reg_vfi(struct lpfc_vport *vport)
 {
 	struct lpfc_hba  *phba = vport->phba;
-	LPFC_MBOXQ_t *mboxq;
+	LPFC_MBOXQ_t *mboxq = NULL;
 	struct lpfc_nodelist *ndlp;
-	struct lpfc_dmabuf *dmabuf;
+	struct lpfc_dmabuf *dmabuf = NULL;
 	int rc = 0;
 
 	/* move forward in case of SLI4 FC port loopback test and pt2pt mode */
@@ -471,25 +471,33 @@ lpfc_issue_reg_vfi(struct lpfc_vport *vp
 		}
 	}
 
-	dmabuf = kzalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL);
-	if (!dmabuf) {
+	mboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
+	if (!mboxq) {
 		rc = -ENOMEM;
 		goto fail;
 	}
-	dmabuf->virt = lpfc_mbuf_alloc(phba, MEM_PRI, &dmabuf->phys);
-	if (!dmabuf->virt) {
-		rc = -ENOMEM;
-		goto fail_free_dmabuf;
-	}
 
-	mboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
-	if (!mboxq) {
-		rc = -ENOMEM;
-		goto fail_free_coherent;
+	/* Supply CSP's only if we are fabric connect or pt-to-pt connect */
+	if ((vport->fc_flag & FC_FABRIC) || (vport->fc_flag & FC_PT2PT)) {
+		dmabuf = kzalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL);
+		if (!dmabuf) {
+			rc = -ENOMEM;
+			goto fail;
+		}
+		dmabuf->virt = lpfc_mbuf_alloc(phba, MEM_PRI, &dmabuf->phys);
+		if (!dmabuf->virt) {
+			rc = -ENOMEM;
+			goto fail;
+		}
+		memcpy(dmabuf->virt, &phba->fc_fabparam,
+		       sizeof(struct serv_parm));
 	}
+
 	vport->port_state = LPFC_FABRIC_CFG_LINK;
-	memcpy(dmabuf->virt, &phba->fc_fabparam, sizeof(vport->fc_sparam));
-	lpfc_reg_vfi(mboxq, vport, dmabuf->phys);
+	if (dmabuf)
+		lpfc_reg_vfi(mboxq, vport, dmabuf->phys);
+	else
+		lpfc_reg_vfi(mboxq, vport, 0);
 
 	mboxq->mbox_cmpl = lpfc_mbx_cmpl_reg_vfi;
 	mboxq->vport = vport;
@@ -497,17 +505,19 @@ lpfc_issue_reg_vfi(struct lpfc_vport *vp
 	rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_NOWAIT);
 	if (rc == MBX_NOT_FINISHED) {
 		rc = -ENXIO;
-		goto fail_free_mbox;
+		goto fail;
 	}
 	return 0;
 
-fail_free_mbox:
-	mempool_free(mboxq, phba->mbox_mem_pool);
-fail_free_coherent:
-	lpfc_mbuf_free(phba, dmabuf->virt, dmabuf->phys);
-fail_free_dmabuf:
-	kfree(dmabuf);
 fail:
+	if (mboxq)
+		mempool_free(mboxq, phba->mbox_mem_pool);
+	if (dmabuf) {
+		if (dmabuf->virt)
+			lpfc_mbuf_free(phba, dmabuf->virt, dmabuf->phys);
+		kfree(dmabuf);
+	}
+
 	lpfc_vport_set_state(vport, FC_VPORT_FAILED);
 	lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
 		"0289 Issue Register VFI failed: Err %d\n", rc);
@@ -678,6 +688,21 @@ lpfc_cmpl_els_flogi_fabric(struct lpfc_v
 				sp->cmn.bbRcvSizeLsb;
 
 	fabric_param_changed = lpfc_check_clean_addr_bit(vport, sp);
+	if (fabric_param_changed) {
+		/* Reset FDMI attribute masks based on config parameter */
+		if (phba->cfg_fdmi_on == LPFC_FDMI_NO_SUPPORT) {
+			vport->fdmi_hba_mask = 0;
+			vport->fdmi_port_mask = 0;
+		} else {
+			/* Setup appropriate attribute masks */
+			vport->fdmi_hba_mask = LPFC_FDMI2_HBA_ATTR;
+			if (phba->cfg_fdmi_on == LPFC_FDMI_SMART_SAN)
+				vport->fdmi_port_mask = LPFC_FDMI2_SMART_ATTR;
+			else
+				vport->fdmi_port_mask = LPFC_FDMI2_PORT_ATTR;
+		}
+
+	}
 	memcpy(&vport->fabric_portname, &sp->portName,
 			sizeof(struct lpfc_name));
 	memcpy(&vport->fabric_nodename, &sp->nodeName,
@@ -711,9 +736,10 @@ lpfc_cmpl_els_flogi_fabric(struct lpfc_v
 	 * For FC we need to do some special processing because of the SLI
 	 * Port's default settings of the Common Service Parameters.
 	 */
-	if (phba->sli4_hba.lnk_info.lnk_tp == LPFC_LNK_TYPE_FC) {
+	if ((phba->sli_rev == LPFC_SLI_REV4) &&
+	    (phba->sli4_hba.lnk_info.lnk_tp == LPFC_LNK_TYPE_FC)) {
 		/* If physical FC port changed, unreg VFI and ALL VPIs / RPIs */
-		if ((phba->sli_rev == LPFC_SLI_REV4) && fabric_param_changed)
+		if (fabric_param_changed)
 			lpfc_unregister_fcf_prep(phba);
 
 		/* This should just update the VFI CSPs*/
@@ -824,13 +850,21 @@ lpfc_cmpl_els_flogi_nport(struct lpfc_vp
 
 	spin_lock_irq(shost->host_lock);
 	vport->fc_flag &= ~(FC_FABRIC | FC_PUBLIC_LOOP);
+	vport->fc_flag |= FC_PT2PT;
 	spin_unlock_irq(shost->host_lock);
 
-	phba->fc_edtov = FF_DEF_EDTOV;
-	phba->fc_ratov = FF_DEF_RATOV;
+	/* If physical FC port changed, unreg VFI and ALL VPIs / RPIs */
+	if ((phba->sli_rev == LPFC_SLI_REV4) && phba->fc_topology_changed) {
+		lpfc_unregister_fcf_prep(phba);
+
+		spin_lock_irq(shost->host_lock);
+		vport->fc_flag &= ~FC_VFI_REGISTERED;
+		spin_unlock_irq(shost->host_lock);
+		phba->fc_topology_changed = 0;
+	}
+
 	rc = memcmp(&vport->fc_portname, &sp->portName,
 		    sizeof(vport->fc_portname));
-	memcpy(&phba->fc_fabparam, sp, sizeof(struct serv_parm));
 
 	if (rc >= 0) {
 		/* This side will initiate the PLOGI */
@@ -839,38 +873,14 @@ lpfc_cmpl_els_flogi_nport(struct lpfc_vp
 		spin_unlock_irq(shost->host_lock);
 
 		/*
-		 * N_Port ID cannot be 0, set our to LocalID the other
-		 * side will be RemoteID.
+		 * N_Port ID cannot be 0, set our Id to LocalID
+		 * the other side will be RemoteID.
 		 */
 
 		/* not equal */
 		if (rc)
 			vport->fc_myDID = PT2PT_LocalID;
 
-		mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
-		if (!mbox)
-			goto fail;
-
-		lpfc_config_link(phba, mbox);
-
-		mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
-		mbox->vport = vport;
-		rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT);
-		if (rc == MBX_NOT_FINISHED) {
-			mempool_free(mbox, phba->mbox_mem_pool);
-			goto fail;
-		}
-
-		/*
-		 * For SLI4, the VFI/VPI are registered AFTER the
-		 * Nport with the higher WWPN sends the PLOGI with
-		 * an assigned NPortId.
-		 */
-
-		/* not equal */
-		if ((phba->sli_rev == LPFC_SLI_REV4) && rc)
-			lpfc_issue_reg_vfi(vport);
-
 		/* Decrement ndlp reference count indicating that ndlp can be
 		 * safely released when other references to it are done.
 		 */
@@ -912,29 +922,20 @@ lpfc_cmpl_els_flogi_nport(struct lpfc_vp
 	/* If we are pt2pt with another NPort, force NPIV off! */
 	phba->sli3_options &= ~LPFC_SLI3_NPIV_ENABLED;
 
-	spin_lock_irq(shost->host_lock);
-	vport->fc_flag |= FC_PT2PT;
-	spin_unlock_irq(shost->host_lock);
-	/* If physical FC port changed, unreg VFI and ALL VPIs / RPIs */
-	if ((phba->sli_rev == LPFC_SLI_REV4) && phba->fc_topology_changed) {
-		lpfc_unregister_fcf_prep(phba);
+	mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
+	if (!mbox)
+		goto fail;
 
-		/* The FC_VFI_REGISTERED flag will get clear in the cmpl
-		 * handler for unreg_vfi, but if we don't force the
-		 * FC_VFI_REGISTERED flag then the reg_vfi mailbox could be
-		 * built with the update bit set instead of just the vp bit to
-		 * change the Nport ID.  We need to have the vp set and the
-		 * Upd cleared on topology changes.
-		 */
-		spin_lock_irq(shost->host_lock);
-		vport->fc_flag &= ~FC_VFI_REGISTERED;
-		spin_unlock_irq(shost->host_lock);
-		phba->fc_topology_changed = 0;
-		lpfc_issue_reg_vfi(vport);
+	lpfc_config_link(phba, mbox);
+
+	mbox->mbox_cmpl = lpfc_mbx_cmpl_local_config_link;
+	mbox->vport = vport;
+	rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT);
+	if (rc == MBX_NOT_FINISHED) {
+		mempool_free(mbox, phba->mbox_mem_pool);
+		goto fail;
 	}
 
-	/* Start discovery - this should just do CLEAR_LA */
-	lpfc_disc_start(vport);
 	return 0;
 fail:
 	return -ENXIO;
@@ -1157,6 +1158,7 @@ flogifail:
 	spin_lock_irq(&phba->hbalock);
 	phba->fcf.fcf_flag &= ~FCF_DISCOVERY;
 	spin_unlock_irq(&phba->hbalock);
+
 	lpfc_nlp_put(ndlp);
 
 	if (!lpfc_error_lost_link(irsp)) {
@@ -3792,14 +3794,17 @@ lpfc_cmpl_els_rsp(struct lpfc_hba *phba,
 				lpfc_nlp_set_state(vport, ndlp,
 					   NLP_STE_REG_LOGIN_ISSUE);
 			}
+
+			ndlp->nlp_flag |= NLP_REG_LOGIN_SEND;
 			if (lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT)
 			    != MBX_NOT_FINISHED)
 				goto out;
-			else
-				/* Decrement the ndlp reference count we
-				 * set for this failed mailbox command.
-				 */
-				lpfc_nlp_put(ndlp);
+
+			/* Decrement the ndlp reference count we
+			 * set for this failed mailbox command.
+			 */
+			lpfc_nlp_put(ndlp);
+			ndlp->nlp_flag &= ~NLP_REG_LOGIN_SEND;
 
 			/* ELS rsp: Cannot issue reg_login for <NPortid> */
 			lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
@@ -3856,6 +3861,7 @@ out:
 				 * the routine lpfc_els_free_iocb.
 				 */
 				cmdiocb->context1 = NULL;
+
 	}
 
 	lpfc_els_free_iocb(phba, cmdiocb);
@@ -3898,6 +3904,7 @@ lpfc_els_rsp_acc(struct lpfc_vport *vpor
 	IOCB_t *oldcmd;
 	struct lpfc_iocbq *elsiocb;
 	uint8_t *pcmd;
+	struct serv_parm *sp;
 	uint16_t cmdsize;
 	int rc;
 	ELS_PKT *els_pkt_ptr;
@@ -3927,6 +3934,7 @@ lpfc_els_rsp_acc(struct lpfc_vport *vpor
 			"Issue ACC:       did:x%x flg:x%x",
 			ndlp->nlp_DID, ndlp->nlp_flag, 0);
 		break;
+	case ELS_CMD_FLOGI:
 	case ELS_CMD_PLOGI:
 		cmdsize = (sizeof(struct serv_parm) + sizeof(uint32_t));
 		elsiocb = lpfc_prep_els_iocb(vport, 0, cmdsize, oldiocb->retry,
@@ -3944,10 +3952,34 @@ lpfc_els_rsp_acc(struct lpfc_vport *vpor
 
 		*((uint32_t *) (pcmd)) = ELS_CMD_ACC;
 		pcmd += sizeof(uint32_t);
-		memcpy(pcmd, &vport->fc_sparam, sizeof(struct serv_parm));
+		sp = (struct serv_parm *)pcmd;
+
+		if (flag == ELS_CMD_FLOGI) {
+			/* Copy the received service parameters back */
+			memcpy(sp, &phba->fc_fabparam,
+			       sizeof(struct serv_parm));
+
+			/* Clear the F_Port bit */
+			sp->cmn.fPort = 0;
+
+			/* Mark all class service parameters as invalid */
+			sp->cls1.classValid = 0;
+			sp->cls2.classValid = 0;
+			sp->cls3.classValid = 0;
+			sp->cls4.classValid = 0;
+
+			/* Copy our worldwide names */
+			memcpy(&sp->portName, &vport->fc_sparam.portName,
+			       sizeof(struct lpfc_name));
+			memcpy(&sp->nodeName, &vport->fc_sparam.nodeName,
+			       sizeof(struct lpfc_name));
+		} else {
+			memcpy(pcmd, &vport->fc_sparam,
+			       sizeof(struct serv_parm));
+		}
 
 		lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_RSP,
-			"Issue ACC PLOGI: did:x%x flg:x%x",
+			"Issue ACC FLOGI/PLOGI: did:x%x flg:x%x",
 			ndlp->nlp_DID, ndlp->nlp_flag, 0);
 		break;
 	case ELS_CMD_PRLO:
@@ -4673,6 +4705,23 @@ lpfc_rdp_res_link_error(struct fc_rdp_li
 	desc->length = cpu_to_be32(sizeof(desc->info));
 }
 
+int
+lpfc_rdp_res_fec_desc(struct fc_fec_rdp_desc *desc, READ_LNK_VAR *stat)
+{
+	if (bf_get(lpfc_read_link_stat_gec2, stat) == 0)
+		return 0;
+	desc->tag = cpu_to_be32(RDP_FEC_DESC_TAG);
+
+	desc->info.CorrectedBlocks =
+		cpu_to_be32(stat->fecCorrBlkCount);
+	desc->info.UncorrectableBlocks =
+		cpu_to_be32(stat->fecUncorrBlkCount);
+
+	desc->length = cpu_to_be32(sizeof(desc->info));
+
+	return sizeof(struct fc_fec_rdp_desc);
+}
+
 void
 lpfc_rdp_res_speed(struct fc_rdp_port_speed_desc *desc, struct lpfc_hba *phba)
 {
@@ -4681,26 +4730,26 @@ lpfc_rdp_res_speed(struct fc_rdp_port_sp
 
 	desc->tag = cpu_to_be32(RDP_PORT_SPEED_DESC_TAG);
 
-	switch (phba->sli4_hba.link_state.speed) {
-	case LPFC_FC_LA_SPEED_1G:
+	switch (phba->fc_linkspeed) {
+	case LPFC_LINK_SPEED_1GHZ:
 		rdp_speed = RDP_PS_1GB;
 		break;
-	case LPFC_FC_LA_SPEED_2G:
+	case LPFC_LINK_SPEED_2GHZ:
 		rdp_speed = RDP_PS_2GB;
 		break;
-	case LPFC_FC_LA_SPEED_4G:
+	case LPFC_LINK_SPEED_4GHZ:
 		rdp_speed = RDP_PS_4GB;
 		break;
-	case LPFC_FC_LA_SPEED_8G:
+	case LPFC_LINK_SPEED_8GHZ:
 		rdp_speed = RDP_PS_8GB;
 		break;
-	case LPFC_FC_LA_SPEED_10G:
+	case LPFC_LINK_SPEED_10GHZ:
 		rdp_speed = RDP_PS_10GB;
 		break;
-	case LPFC_FC_LA_SPEED_16G:
+	case LPFC_LINK_SPEED_16GHZ:
 		rdp_speed = RDP_PS_16GB;
 		break;
-	case LPFC_FC_LA_SPEED_32G:
+	case LPFC_LINK_SPEED_32GHZ:
 		rdp_speed = RDP_PS_32GB;
 		break;
 	default:
@@ -4778,15 +4827,18 @@ lpfc_els_rdp_cmpl(struct lpfc_hba *phba,
 	struct lpfc_nodelist *ndlp = rdp_context->ndlp;
 	struct lpfc_vport *vport = ndlp->vport;
 	struct lpfc_iocbq *elsiocb;
+	struct ulp_bde64 *bpl;
 	IOCB_t *icmd;
 	uint8_t *pcmd;
 	struct ls_rjt *stat;
 	struct fc_rdp_res_frame *rdp_res;
 	uint32_t cmdsize;
-	int rc;
+	int rc, fec_size;
 
 	if (status != SUCCESS)
 		goto error;
+
+	/* This will change once we know the true size of the RDP payload */
 	cmdsize = sizeof(struct fc_rdp_res_frame);
 
 	elsiocb = lpfc_prep_els_iocb(vport, 0, cmdsize,
@@ -4823,10 +4875,18 @@ lpfc_els_rdp_cmpl(struct lpfc_hba *phba,
 	lpfc_rdp_res_diag_port_names(&rdp_res->diag_port_names_desc, phba);
 	lpfc_rdp_res_attach_port_names(&rdp_res->attached_port_names_desc,
 			vport, ndlp);
-	rdp_res->length = cpu_to_be32(RDP_DESC_PAYLOAD_SIZE);
-
+	fec_size = lpfc_rdp_res_fec_desc(&rdp_res->fec_desc,
+			&rdp_context->link_stat);
+	rdp_res->length = cpu_to_be32(fec_size + RDP_DESC_PAYLOAD_SIZE);
 	elsiocb->iocb_cmpl = lpfc_cmpl_els_rsp;
 
+	/* Now that we know the true size of the payload, update the BPL */
+	bpl = (struct ulp_bde64 *)
+		(((struct lpfc_dmabuf *)(elsiocb->context3))->virt);
+	bpl->tus.f.bdeSize = (fec_size + RDP_DESC_PAYLOAD_SIZE + 8);
+	bpl->tus.f.bdeFlags = 0;
+	bpl->tus.w = le32_to_cpu(bpl->tus.w);
+
 	phba->fc_stat.elsXmitACC++;
 	rc = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, elsiocb, 0);
 	if (rc == IOCB_ERROR)
@@ -4956,13 +5016,12 @@ lpfc_els_rcv_rdp(struct lpfc_vport *vpor
 	if (RDP_NPORT_ID_SIZE !=
 			be32_to_cpu(rdp_req->nport_id_desc.length))
 		goto rjt_logerr;
-	rdp_context = kmalloc(sizeof(struct lpfc_rdp_context), GFP_KERNEL);
+	rdp_context = kzalloc(sizeof(struct lpfc_rdp_context), GFP_KERNEL);
 	if (!rdp_context) {
 		rjt_err = LSRJT_UNABLE_TPC;
 		goto error;
 	}
 
-	memset(rdp_context, 0, sizeof(struct lpfc_rdp_context));
 	cmd = &cmdiocb->iocb;
 	rdp_context->ndlp = lpfc_nlp_get(ndlp);
 	rdp_context->ox_id = cmd->unsli3.rcvsli3.ox_id;
@@ -5739,7 +5798,6 @@ lpfc_els_rcv_flogi(struct lpfc_vport *vp
 	IOCB_t *icmd = &cmdiocb->iocb;
 	struct serv_parm *sp;
 	LPFC_MBOXQ_t *mbox;
-	struct ls_rjt stat;
 	uint32_t cmd, did;
 	int rc;
 	uint32_t fc_flag = 0;
@@ -5765,135 +5823,92 @@ lpfc_els_rcv_flogi(struct lpfc_vport *vp
 		return 1;
 	}
 
-	if ((lpfc_check_sparm(vport, ndlp, sp, CLASS3, 1))) {
-		/* For a FLOGI we accept, then if our portname is greater
-		 * then the remote portname we initiate Nport login.
-		 */
+	(void) lpfc_check_sparm(vport, ndlp, sp, CLASS3, 1);
 
-		rc = memcmp(&vport->fc_portname, &sp->portName,
-			    sizeof(struct lpfc_name));
 
-		if (!rc) {
-			if (phba->sli_rev < LPFC_SLI_REV4) {
-				mbox = mempool_alloc(phba->mbox_mem_pool,
-						     GFP_KERNEL);
-				if (!mbox)
-					return 1;
-				lpfc_linkdown(phba);
-				lpfc_init_link(phba, mbox,
-					       phba->cfg_topology,
-					       phba->cfg_link_speed);
-				mbox->u.mb.un.varInitLnk.lipsr_AL_PA = 0;
-				mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
-				mbox->vport = vport;
-				rc = lpfc_sli_issue_mbox(phba, mbox,
-							 MBX_NOWAIT);
-				lpfc_set_loopback_flag(phba);
-				if (rc == MBX_NOT_FINISHED)
-					mempool_free(mbox, phba->mbox_mem_pool);
-				return 1;
-			} else {
-				/* abort the flogi coming back to ourselves
-				 * due to external loopback on the port.
-				 */
-				lpfc_els_abort_flogi(phba);
-				return 0;
-			}
-		} else if (rc > 0) {	/* greater than */
-			spin_lock_irq(shost->host_lock);
-			vport->fc_flag |= FC_PT2PT_PLOGI;
-			spin_unlock_irq(shost->host_lock);
+	/*
+	 * If our portname is greater than the remote portname,
+	 * then we initiate Nport login.
+	 */
 
-			/* If we have the high WWPN we can assign our own
-			 * myDID; otherwise, we have to WAIT for a PLOGI
-			 * from the remote NPort to find out what it
-			 * will be.
-			 */
-			vport->fc_myDID = PT2PT_LocalID;
-		} else
-			vport->fc_myDID = PT2PT_RemoteID;
+	rc = memcmp(&vport->fc_portname, &sp->portName,
+		    sizeof(struct lpfc_name));
 
-		/*
-		 * The vport state should go to LPFC_FLOGI only
-		 * AFTER we issue a FLOGI, not receive one.
+	if (!rc) {
+		if (phba->sli_rev < LPFC_SLI_REV4) {
+			mbox = mempool_alloc(phba->mbox_mem_pool,
+					     GFP_KERNEL);
+			if (!mbox)
+				return 1;
+			lpfc_linkdown(phba);
+			lpfc_init_link(phba, mbox,
+				       phba->cfg_topology,
+				       phba->cfg_link_speed);
+			mbox->u.mb.un.varInitLnk.lipsr_AL_PA = 0;
+			mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
+			mbox->vport = vport;
+			rc = lpfc_sli_issue_mbox(phba, mbox,
+						 MBX_NOWAIT);
+			lpfc_set_loopback_flag(phba);
+			if (rc == MBX_NOT_FINISHED)
+				mempool_free(mbox, phba->mbox_mem_pool);
+			return 1;
+		}
+
+		/* abort the flogi coming back to ourselves
+		 * due to external loopback on the port.
 		 */
+		lpfc_els_abort_flogi(phba);
+		return 0;
+
+	} else if (rc > 0) {	/* greater than */
 		spin_lock_irq(shost->host_lock);
-		fc_flag = vport->fc_flag;
-		port_state = vport->port_state;
-		vport->fc_flag |= FC_PT2PT;
-		vport->fc_flag &= ~(FC_FABRIC | FC_PUBLIC_LOOP);
+		vport->fc_flag |= FC_PT2PT_PLOGI;
 		spin_unlock_irq(shost->host_lock);
-		lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
-				 "3311 Rcv Flogi PS x%x new PS x%x "
-				 "fc_flag x%x new fc_flag x%x\n",
-				 port_state, vport->port_state,
-				 fc_flag, vport->fc_flag);
 
-		/*
-		 * We temporarily set fc_myDID to make it look like we are
-		 * a Fabric. This is done just so we end up with the right
-		 * did / sid on the FLOGI ACC rsp.
+		/* If we have the high WWPN we can assign our own
+		 * myDID; otherwise, we have to WAIT for a PLOGI
+		 * from the remote NPort to find out what it
+		 * will be.
 		 */
-		did = vport->fc_myDID;
-		vport->fc_myDID = Fabric_DID;
-
+		vport->fc_myDID = PT2PT_LocalID;
 	} else {
-		/* Reject this request because invalid parameters */
-		stat.un.b.lsRjtRsvd0 = 0;
-		stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC;
-		stat.un.b.lsRjtRsnCodeExp = LSEXP_SPARM_OPTIONS;
-		stat.un.b.vendorUnique = 0;
-
-		/*
-		 * We temporarily set fc_myDID to make it look like we are
-		 * a Fabric. This is done just so we end up with the right
-		 * did / sid on the FLOGI LS_RJT rsp.
-		 */
-		did = vport->fc_myDID;
-		vport->fc_myDID = Fabric_DID;
-
-		lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp,
-			NULL);
+		vport->fc_myDID = PT2PT_RemoteID;
+	}
 
-		/* Now lets put fc_myDID back to what its supposed to be */
-		vport->fc_myDID = did;
+	/*
+	 * The vport state should go to LPFC_FLOGI only
+	 * AFTER we issue a FLOGI, not receive one.
+	 */
+	spin_lock_irq(shost->host_lock);
+	fc_flag = vport->fc_flag;
+	port_state = vport->port_state;
+	vport->fc_flag |= FC_PT2PT;
+	vport->fc_flag &= ~(FC_FABRIC | FC_PUBLIC_LOOP);
+	spin_unlock_irq(shost->host_lock);
+	lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
+			 "3311 Rcv Flogi PS x%x new PS x%x "
+			 "fc_flag x%x new fc_flag x%x\n",
+			 port_state, vport->port_state,
+			 fc_flag, vport->fc_flag);
 
-		return 1;
-	}
+	/*
+	 * We temporarily set fc_myDID to make it look like we are
+	 * a Fabric. This is done just so we end up with the right
+	 * did / sid on the FLOGI ACC rsp.
+	 */
+	did = vport->fc_myDID;
+	vport->fc_myDID = Fabric_DID;
 
-	/* send our FLOGI first */
-	if (vport->port_state < LPFC_FLOGI) {
-		vport->fc_myDID = 0;
-		lpfc_initial_flogi(vport);
-		vport->fc_myDID = Fabric_DID;
-	}
+	memcpy(&phba->fc_fabparam, sp, sizeof(struct serv_parm));
 
 	/* Send back ACC */
-	lpfc_els_rsp_acc(vport, ELS_CMD_PLOGI, cmdiocb, ndlp, NULL);
+	lpfc_els_rsp_acc(vport, ELS_CMD_FLOGI, cmdiocb, ndlp, NULL);
 
 	/* Now lets put fc_myDID back to what its supposed to be */
 	vport->fc_myDID = did;
 
-	if (!(vport->fc_flag & FC_PT2PT_PLOGI)) {
-
-		mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
-		if (!mbox)
-			goto fail;
-
-		lpfc_config_link(phba, mbox);
-
-		mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
-		mbox->vport = vport;
-		rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT);
-		if (rc == MBX_NOT_FINISHED) {
-			mempool_free(mbox, phba->mbox_mem_pool);
-			goto fail;
-		}
-	}
-
 	return 0;
-fail:
-	return 1;
 }
 
 /**
@@ -7345,7 +7360,7 @@ lpfc_els_unsol_buffer(struct lpfc_hba *p
 
 	/* reject till our FLOGI completes */
 	if ((vport->port_state < LPFC_FABRIC_CFG_LINK) &&
-		(cmd != ELS_CMD_FLOGI)) {
+	    (cmd != ELS_CMD_FLOGI)) {
 		rjt_err = LSRJT_UNABLE_TPC;
 		rjt_exp = LSEXP_NOTHING_MORE;
 		goto lsrjt;
@@ -7381,6 +7396,7 @@ lpfc_els_unsol_buffer(struct lpfc_hba *p
 			rjt_exp = LSEXP_NOTHING_MORE;
 			break;
 		}
+
 		if (vport->port_state < LPFC_DISC_AUTH) {
 			if (!(phba->pport->fc_flag & FC_PT2PT) ||
 				(phba->pport->fc_flag & FC_PT2PT_PLOGI)) {
@@ -7730,6 +7746,35 @@ lpfc_els_unsol_event(struct lpfc_hba *ph
 	}
 }
 
+void
+lpfc_start_fdmi(struct lpfc_vport *vport)
+{
+	struct lpfc_hba *phba = vport->phba;
+	struct lpfc_nodelist *ndlp;
+
+	/* If this is the first time, allocate an ndlp and initialize
+	 * it. Otherwise, make sure the node is enabled and then do the
+	 * login.
+	 */
+	ndlp = lpfc_findnode_did(vport, FDMI_DID);
+	if (!ndlp) {
+		ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL);
+		if (ndlp) {
+			lpfc_nlp_init(vport, ndlp, FDMI_DID);
+			ndlp->nlp_type |= NLP_FABRIC;
+		} else {
+			return;
+		}
+	}
+	if (!NLP_CHK_NODE_ACT(ndlp))
+		ndlp = lpfc_enable_node(vport, ndlp, NLP_STE_NPR_NODE);
+
+	if (ndlp) {
+		lpfc_nlp_set_state(vport, ndlp, NLP_STE_PLOGI_ISSUE);
+		lpfc_issue_els_plogi(vport, ndlp->nlp_DID, 0);
+	}
+}
+
 /**
  * lpfc_do_scr_ns_plogi - Issue a plogi to the name server for scr
  * @phba: pointer to lpfc hba data structure.
@@ -7746,7 +7791,7 @@ lpfc_els_unsol_event(struct lpfc_hba *ph
 void
 lpfc_do_scr_ns_plogi(struct lpfc_hba *phba, struct lpfc_vport *vport)
 {
-	struct lpfc_nodelist *ndlp, *ndlp_fdmi;
+	struct lpfc_nodelist *ndlp;
 	struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
 
 	/*
@@ -7804,32 +7849,9 @@ lpfc_do_scr_ns_plogi(struct lpfc_hba *ph
 		return;
 	}
 
-	if (vport->cfg_fdmi_on & LPFC_FDMI_SUPPORT) {
-		/* If this is the first time, allocate an ndlp and initialize
-		 * it. Otherwise, make sure the node is enabled and then do the
-		 * login.
-		 */
-		ndlp_fdmi = lpfc_findnode_did(vport, FDMI_DID);
-		if (!ndlp_fdmi) {
-			ndlp_fdmi = mempool_alloc(phba->nlp_mem_pool,
-						  GFP_KERNEL);
-			if (ndlp_fdmi) {
-				lpfc_nlp_init(vport, ndlp_fdmi, FDMI_DID);
-				ndlp_fdmi->nlp_type |= NLP_FABRIC;
-			} else
-				return;
-		}
-		if (!NLP_CHK_NODE_ACT(ndlp_fdmi))
-			ndlp_fdmi = lpfc_enable_node(vport,
-						     ndlp_fdmi,
-						     NLP_STE_NPR_NODE);
-
-		if (ndlp_fdmi) {
-			lpfc_nlp_set_state(vport, ndlp_fdmi,
-					   NLP_STE_PLOGI_ISSUE);
-			lpfc_issue_els_plogi(vport, ndlp_fdmi->nlp_DID, 0);
-		}
-	}
+	if ((phba->cfg_fdmi_on > LPFC_FDMI_NO_SUPPORT) &&
+	    (vport->load_flag & FC_ALLOW_FDMI))
+		lpfc_start_fdmi(vport);
 }
 
 /**
--- zfcpdump-kernel-4.4.orig/drivers/scsi/lpfc/lpfc_hbadisc.c
+++ zfcpdump-kernel-4.4/drivers/scsi/lpfc/lpfc_hbadisc.c
@@ -674,8 +674,6 @@ lpfc_work_done(struct lpfc_hba *phba)
 				lpfc_mbox_timeout_handler(phba);
 			if (work_port_events & WORKER_FABRIC_BLOCK_TMO)
 				lpfc_unblock_fabric_iocbs(phba);
-			if (work_port_events & WORKER_FDMI_TMO)
-				lpfc_fdmi_timeout_handler(vport);
 			if (work_port_events & WORKER_RAMP_DOWN_QUEUE)
 				lpfc_ramp_down_queue_handler(phba);
 			if (work_port_events & WORKER_DELAYED_DISC_TMO)
@@ -1083,7 +1081,7 @@ out:
 }
 
 
-static void
+void
 lpfc_mbx_cmpl_local_config_link(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
 {
 	struct lpfc_vport *vport = pmb->vport;
@@ -1113,8 +1111,10 @@ lpfc_mbx_cmpl_local_config_link(struct l
 	/* Start discovery by sending a FLOGI. port_state is identically
 	 * LPFC_FLOGI while waiting for FLOGI cmpl
 	 */
-	if (vport->port_state != LPFC_FLOGI || vport->fc_flag & FC_PT2PT_PLOGI)
+	if (vport->port_state != LPFC_FLOGI)
 		lpfc_initial_flogi(vport);
+	else if (vport->fc_flag & FC_PT2PT)
+		lpfc_disc_start(vport);
 	return;
 
 out:
@@ -2963,8 +2963,10 @@ lpfc_mbx_cmpl_reg_vfi(struct lpfc_hba *p
 
 out_free_mem:
 	mempool_free(mboxq, phba->mbox_mem_pool);
-	lpfc_mbuf_free(phba, dmabuf->virt, dmabuf->phys);
-	kfree(dmabuf);
+	if (dmabuf) {
+		lpfc_mbuf_free(phba, dmabuf->virt, dmabuf->phys);
+		kfree(dmabuf);
+	}
 	return;
 }
 
@@ -3035,19 +3037,22 @@ lpfc_mbx_process_link_up(struct lpfc_hba
 	uint32_t fc_flags = 0;
 
 	spin_lock_irq(&phba->hbalock);
-	switch (bf_get(lpfc_mbx_read_top_link_spd, la)) {
-	case LPFC_LINK_SPEED_1GHZ:
-	case LPFC_LINK_SPEED_2GHZ:
-	case LPFC_LINK_SPEED_4GHZ:
-	case LPFC_LINK_SPEED_8GHZ:
-	case LPFC_LINK_SPEED_10GHZ:
-	case LPFC_LINK_SPEED_16GHZ:
-	case LPFC_LINK_SPEED_32GHZ:
-		phba->fc_linkspeed = bf_get(lpfc_mbx_read_top_link_spd, la);
-		break;
-	default:
-		phba->fc_linkspeed = LPFC_LINK_SPEED_UNKNOWN;
-		break;
+	phba->fc_linkspeed = bf_get(lpfc_mbx_read_top_link_spd, la);
+
+	if (!(phba->hba_flag & HBA_FCOE_MODE)) {
+		switch (bf_get(lpfc_mbx_read_top_link_spd, la)) {
+		case LPFC_LINK_SPEED_1GHZ:
+		case LPFC_LINK_SPEED_2GHZ:
+		case LPFC_LINK_SPEED_4GHZ:
+		case LPFC_LINK_SPEED_8GHZ:
+		case LPFC_LINK_SPEED_10GHZ:
+		case LPFC_LINK_SPEED_16GHZ:
+		case LPFC_LINK_SPEED_32GHZ:
+			break;
+		default:
+			phba->fc_linkspeed = LPFC_LINK_SPEED_UNKNOWN;
+			break;
+		}
 	}
 
 	if (phba->fc_topology &&
@@ -3448,10 +3453,10 @@ lpfc_mbx_cmpl_reg_login(struct lpfc_hba
 		spin_lock_irq(shost->host_lock);
 		ndlp->nlp_flag &= ~NLP_IGNR_REG_CMPL;
 		spin_unlock_irq(shost->host_lock);
-	} else
-		/* Good status, call state machine */
-		lpfc_disc_state_machine(vport, ndlp, pmb,
-				NLP_EVT_CMPL_REG_LOGIN);
+	}
+
+	/* Call state machine */
+	lpfc_disc_state_machine(vport, ndlp, pmb, NLP_EVT_CMPL_REG_LOGIN);
 
 	lpfc_mbuf_free(phba, mp->virt, mp->phys);
 	kfree(mp);
@@ -5550,15 +5555,15 @@ lpfc_mbx_cmpl_fdmi_reg_login(struct lpfc
 			 ndlp->nlp_usg_map, ndlp);
 	/*
 	 * Start issuing Fabric-Device Management Interface (FDMI) command to
-	 * 0xfffffa (FDMI well known port) or Delay issuing FDMI command if
-	 * fdmi-on=2 (supporting RPA/hostnmae)
+	 * 0xfffffa (FDMI well known port).
+	 * DHBA -> DPRT -> RHBA -> RPA  (physical port)
+	 * DPRT -> RPRT (vports)
 	 */
-
-	if (vport->cfg_fdmi_on & LPFC_FDMI_REG_DELAY)
-		mod_timer(&vport->fc_fdmitmo,
-			  jiffies + msecs_to_jiffies(1000 * 60));
+	if (vport->port_type == LPFC_PHYSICAL_PORT)
+		lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_DHBA, 0);
 	else
-		lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_DHBA);
+		lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_DPRT, 0);
+
 
 	/* decrement the node reference count held for this callback
 	 * function.
--- zfcpdump-kernel-4.4.orig/drivers/scsi/lpfc/lpfc_hw.h
+++ zfcpdump-kernel-4.4/drivers/scsi/lpfc/lpfc_hw.h
@@ -1097,6 +1097,18 @@ struct fc_rdp_port_name_desc {
 };
 
 
+struct fc_rdp_fec_info {
+	uint32_t CorrectedBlocks;
+	uint32_t UncorrectableBlocks;
+};
+
+#define RDP_FEC_DESC_TAG  0x00010005
+struct fc_fec_rdp_desc {
+	uint32_t tag;
+	uint32_t length;
+	struct fc_rdp_fec_info info;
+};
+
 struct fc_rdp_link_error_status_payload_info {
 	struct fc_link_status link_status; /* 24 bytes */
 	uint32_t  port_type;             /* bits 31-30 only */
@@ -1196,14 +1208,15 @@ struct fc_rdp_res_frame {
 	struct fc_rdp_link_error_status_desc link_error_desc; /* Word 13-21 */
 	struct fc_rdp_port_name_desc diag_port_names_desc;    /* Word 22-27 */
 	struct fc_rdp_port_name_desc attached_port_names_desc;/* Word 28-33 */
+	struct fc_fec_rdp_desc fec_desc;	      /* FC Word 34 - 37 */
 };
 
 
 #define RDP_DESC_PAYLOAD_SIZE (sizeof(struct fc_rdp_link_service_desc) \
-			+ sizeof(struct fc_rdp_sfp_desc) \
-			+ sizeof(struct fc_rdp_port_speed_desc) \
-			+ sizeof(struct fc_rdp_link_error_status_desc) \
-			+ (sizeof(struct fc_rdp_port_name_desc) * 2))
+				+ sizeof(struct fc_rdp_sfp_desc) \
+				+ sizeof(struct fc_rdp_port_speed_desc) \
+				+ sizeof(struct fc_rdp_link_error_status_desc) \
+				+ (sizeof(struct fc_rdp_port_name_desc) * 2))
 
 
 /******** FDMI ********/
@@ -1233,31 +1246,10 @@ struct lpfc_fdmi_attr_def { /* Defined i
 /* Attribute Entry */
 struct lpfc_fdmi_attr_entry {
 	union {
-		uint32_t VendorSpecific;
-		uint32_t SupportClass;
-		uint32_t SupportSpeed;
-		uint32_t PortSpeed;
-		uint32_t MaxFrameSize;
-		uint32_t MaxCTPayloadLen;
-		uint32_t PortState;
-		uint32_t PortId;
-		struct lpfc_name NodeName;
-		struct lpfc_name PortName;
-		struct lpfc_name FabricName;
-		uint8_t FC4Types[32];
-		uint8_t Manufacturer[64];
-		uint8_t SerialNumber[64];
-		uint8_t Model[256];
-		uint8_t ModelDescription[256];
-		uint8_t HardwareVersion[256];
-		uint8_t DriverVersion[256];
-		uint8_t OptionROMVersion[256];
-		uint8_t FirmwareVersion[256];
-		uint8_t OsHostName[256];
-		uint8_t NodeSymName[256];
-		uint8_t OsDeviceName[256];
-		uint8_t OsNameVersion[256];
-		uint8_t HostName[256];
+		uint32_t AttrInt;
+		uint8_t  AttrTypes[32];
+		uint8_t  AttrString[256];
+		struct lpfc_name AttrWWN;
 	} un;
 };
 
@@ -1327,6 +1319,8 @@ struct lpfc_fdmi_reg_portattr {
 #define  SLI_MGMT_DPRT     0x310	/* De-register Port */
 #define  SLI_MGMT_DPA      0x311	/* De-register Port attributes */
 
+#define LPFC_FDMI_MAX_RETRY     3  /* Max retries for a FDMI command */
+
 /*
  * HBA Attribute Types
  */
@@ -1342,6 +1336,39 @@ struct lpfc_fdmi_reg_portattr {
 #define  RHBA_OS_NAME_VERSION	 0xa /* 4 to 256 byte ASCII string */
 #define  RHBA_MAX_CT_PAYLOAD_LEN 0xb /* 32-bit unsigned int */
 #define  RHBA_SYM_NODENAME       0xc /* 4 to 256 byte ASCII string */
+#define  RHBA_VENDOR_INFO        0xd  /* 32-bit unsigned int */
+#define  RHBA_NUM_PORTS          0xe  /* 32-bit unsigned int */
+#define  RHBA_FABRIC_WWNN        0xf  /* 8 byte WWNN */
+#define  RHBA_BIOS_VERSION       0x10 /* 4 to 256 byte ASCII string */
+#define  RHBA_BIOS_STATE         0x11 /* 32-bit unsigned int */
+#define  RHBA_VENDOR_ID          0xe0 /* 8 byte ASCII string */
+
+/* Bit mask for all individual HBA attributes */
+#define LPFC_FDMI_HBA_ATTR_wwnn			0x00000001
+#define LPFC_FDMI_HBA_ATTR_manufacturer		0x00000002
+#define LPFC_FDMI_HBA_ATTR_sn			0x00000004
+#define LPFC_FDMI_HBA_ATTR_model		0x00000008
+#define LPFC_FDMI_HBA_ATTR_description		0x00000010
+#define LPFC_FDMI_HBA_ATTR_hdw_ver		0x00000020
+#define LPFC_FDMI_HBA_ATTR_drvr_ver		0x00000040
+#define LPFC_FDMI_HBA_ATTR_rom_ver		0x00000080
+#define LPFC_FDMI_HBA_ATTR_fmw_ver		0x00000100
+#define LPFC_FDMI_HBA_ATTR_os_ver		0x00000200
+#define LPFC_FDMI_HBA_ATTR_ct_len		0x00000400
+#define LPFC_FDMI_HBA_ATTR_symbolic_name	0x00000800
+#define LPFC_FDMI_HBA_ATTR_vendor_info		0x00001000 /* Not used */
+#define LPFC_FDMI_HBA_ATTR_num_ports		0x00002000
+#define LPFC_FDMI_HBA_ATTR_fabric_wwnn		0x00004000
+#define LPFC_FDMI_HBA_ATTR_bios_ver		0x00008000
+#define LPFC_FDMI_HBA_ATTR_bios_state		0x00010000 /* Not used */
+#define LPFC_FDMI_HBA_ATTR_vendor_id		0x00020000
+
+/* Bit mask for FDMI-1 defined HBA attributes */
+#define LPFC_FDMI1_HBA_ATTR			0x000007ff
+
+/* Bit mask for FDMI-2 defined HBA attributes */
+/* Skip vendor_info and bios_state */
+#define LPFC_FDMI2_HBA_ATTR			0x0002efff
 
 /*
  * Port Attrubute Types
@@ -1353,15 +1380,65 @@ struct lpfc_fdmi_reg_portattr {
 #define  RPRT_OS_DEVICE_NAME          0x5 /* 4 to 256 byte ASCII string */
 #define  RPRT_HOST_NAME               0x6 /* 4 to 256 byte ASCII string */
 #define  RPRT_NODENAME                0x7 /* 8 byte WWNN */
-#define  RPRT_PORTNAME                0x8 /* 8 byte WWNN */
+#define  RPRT_PORTNAME                0x8 /* 8 byte WWPN */
 #define  RPRT_SYM_PORTNAME            0x9 /* 4 to 256 byte ASCII string */
 #define  RPRT_PORT_TYPE               0xa /* 32-bit unsigned int */
 #define  RPRT_SUPPORTED_CLASS         0xb /* 32-bit unsigned int */
-#define  RPRT_FABRICNAME              0xc /* 8 byte Fabric WWNN */
+#define  RPRT_FABRICNAME              0xc /* 8 byte Fabric WWPN */
 #define  RPRT_ACTIVE_FC4_TYPES        0xd /* 32 byte binary array */
 #define  RPRT_PORT_STATE              0x101 /* 32-bit unsigned int */
 #define  RPRT_DISC_PORT               0x102 /* 32-bit unsigned int */
 #define  RPRT_PORT_ID                 0x103 /* 32-bit unsigned int */
+#define  RPRT_SMART_SERVICE           0xf100 /* 4 to 256 byte ASCII string */
+#define  RPRT_SMART_GUID              0xf101 /* 8 byte WWNN + 8 byte WWPN */
+#define  RPRT_SMART_VERSION           0xf102 /* 4 to 256 byte ASCII string */
+#define  RPRT_SMART_MODEL             0xf103 /* 4 to 256 byte ASCII string */
+#define  RPRT_SMART_PORT_INFO         0xf104 /* 32-bit unsigned int */
+#define  RPRT_SMART_QOS               0xf105 /* 32-bit unsigned int */
+#define  RPRT_SMART_SECURITY          0xf106 /* 32-bit unsigned int */
+
+/* Bit mask for all individual PORT attributes */
+#define LPFC_FDMI_PORT_ATTR_fc4type		0x00000001
+#define LPFC_FDMI_PORT_ATTR_support_speed	0x00000002
+#define LPFC_FDMI_PORT_ATTR_speed		0x00000004
+#define LPFC_FDMI_PORT_ATTR_max_frame		0x00000008
+#define LPFC_FDMI_PORT_ATTR_os_devname		0x00000010
+#define LPFC_FDMI_PORT_ATTR_host_name		0x00000020
+#define LPFC_FDMI_PORT_ATTR_wwnn		0x00000040
+#define LPFC_FDMI_PORT_ATTR_wwpn		0x00000080
+#define LPFC_FDMI_PORT_ATTR_symbolic_name	0x00000100
+#define LPFC_FDMI_PORT_ATTR_port_type		0x00000200
+#define LPFC_FDMI_PORT_ATTR_class		0x00000400
+#define LPFC_FDMI_PORT_ATTR_fabric_wwpn		0x00000800
+#define LPFC_FDMI_PORT_ATTR_port_state		0x00001000
+#define LPFC_FDMI_PORT_ATTR_active_fc4type	0x00002000
+#define LPFC_FDMI_PORT_ATTR_num_disc		0x00004000
+#define LPFC_FDMI_PORT_ATTR_nportid		0x00008000
+#define LPFC_FDMI_SMART_ATTR_service		0x00010000 /* Vendor specific */
+#define LPFC_FDMI_SMART_ATTR_guid		0x00020000 /* Vendor specific */
+#define LPFC_FDMI_SMART_ATTR_version		0x00040000 /* Vendor specific */
+#define LPFC_FDMI_SMART_ATTR_model		0x00080000 /* Vendor specific */
+#define LPFC_FDMI_SMART_ATTR_port_info		0x00100000 /* Vendor specific */
+#define LPFC_FDMI_SMART_ATTR_qos		0x00200000 /* Vendor specific */
+#define LPFC_FDMI_SMART_ATTR_security		0x00400000 /* Vendor specific */
+
+/* Bit mask for FDMI-1 defined PORT attributes */
+#define LPFC_FDMI1_PORT_ATTR			0x0000003f
+
+/* Bit mask for FDMI-2 defined PORT attributes */
+#define LPFC_FDMI2_PORT_ATTR			0x0000ffff
+
+/* Bit mask for Smart SAN defined PORT attributes */
+#define LPFC_FDMI2_SMART_ATTR			0x007fffff
+
+/* Defines for PORT port state attribute */
+#define LPFC_FDMI_PORTSTATE_UNKNOWN	1
+#define LPFC_FDMI_PORTSTATE_ONLINE	2
+
+/* Defines for PORT port type attribute */
+#define LPFC_FDMI_PORTTYPE_UNKNOWN	0
+#define LPFC_FDMI_PORTTYPE_NPORT	1
+#define LPFC_FDMI_PORTTYPE_NLPORT	2
 
 /*
  *  Begin HBA configuration parameters.
@@ -2498,10 +2575,38 @@ typedef struct {
 /* Structure for MB Command READ_LINK_STAT (18) */
 
 typedef struct {
-	uint32_t rsvd1;
+	uint32_t word0;
+
+#define lpfc_read_link_stat_rec_SHIFT   0
+#define lpfc_read_link_stat_rec_MASK   0x1
+#define lpfc_read_link_stat_rec_WORD   word0
+
+#define lpfc_read_link_stat_gec_SHIFT	1
+#define lpfc_read_link_stat_gec_MASK   0x1
+#define lpfc_read_link_stat_gec_WORD   word0
+
+#define lpfc_read_link_stat_w02oftow23of_SHIFT	2
+#define lpfc_read_link_stat_w02oftow23of_MASK   0x3FFFFF
+#define lpfc_read_link_stat_w02oftow23of_WORD   word0
+
+#define lpfc_read_link_stat_rsvd_SHIFT	24
+#define lpfc_read_link_stat_rsvd_MASK   0x1F
+#define lpfc_read_link_stat_rsvd_WORD   word0
+
+#define lpfc_read_link_stat_gec2_SHIFT  29
+#define lpfc_read_link_stat_gec2_MASK   0x1
+#define lpfc_read_link_stat_gec2_WORD   word0
+
+#define lpfc_read_link_stat_clrc_SHIFT  30
+#define lpfc_read_link_stat_clrc_MASK   0x1
+#define lpfc_read_link_stat_clrc_WORD   word0
+
+#define lpfc_read_link_stat_clof_SHIFT  31
+#define lpfc_read_link_stat_clof_MASK   0x1
+#define lpfc_read_link_stat_clof_WORD   word0
+
 	uint32_t linkFailureCnt;
 	uint32_t lossSyncCnt;
-
 	uint32_t lossSignalCnt;
 	uint32_t primSeqErrCnt;
 	uint32_t invalidXmitWord;
@@ -2509,6 +2614,19 @@ typedef struct {
 	uint32_t primSeqTimeout;
 	uint32_t elasticOverrun;
 	uint32_t arbTimeout;
+	uint32_t advRecBufCredit;
+	uint32_t curRecBufCredit;
+	uint32_t advTransBufCredit;
+	uint32_t curTransBufCredit;
+	uint32_t recEofCount;
+	uint32_t recEofdtiCount;
+	uint32_t recEofniCount;
+	uint32_t recSofcount;
+	uint32_t rsvd1;
+	uint32_t rsvd2;
+	uint32_t recDrpXriCount;
+	uint32_t fecCorrBlkCount;
+	uint32_t fecUncorrBlkCount;
 } READ_LNK_VAR;
 
 /* Structure for MB Command REG_LOGIN (19) */
--- zfcpdump-kernel-4.4.orig/drivers/scsi/lpfc/lpfc_hw4.h
+++ zfcpdump-kernel-4.4/drivers/scsi/lpfc/lpfc_hw4.h
@@ -3317,6 +3317,7 @@ struct lpfc_acqe_link {
 #define LPFC_ASYNC_LINK_SPEED_20GBPS		0x5
 #define LPFC_ASYNC_LINK_SPEED_25GBPS		0x6
 #define LPFC_ASYNC_LINK_SPEED_40GBPS		0x7
+#define LPFC_ASYNC_LINK_SPEED_100GBPS		0x8
 #define lpfc_acqe_link_duplex_SHIFT		16
 #define lpfc_acqe_link_duplex_MASK		0x000000FF
 #define lpfc_acqe_link_duplex_WORD		word0
@@ -3447,23 +3448,50 @@ struct lpfc_acqe_fc_la {
 struct lpfc_acqe_misconfigured_event {
 	struct {
 	uint32_t word0;
-#define lpfc_sli_misconfigured_port0_SHIFT	0
-#define lpfc_sli_misconfigured_port0_MASK	0x000000FF
-#define lpfc_sli_misconfigured_port0_WORD	word0
-#define lpfc_sli_misconfigured_port1_SHIFT	8
-#define lpfc_sli_misconfigured_port1_MASK	0x000000FF
-#define lpfc_sli_misconfigured_port1_WORD	word0
-#define lpfc_sli_misconfigured_port2_SHIFT	16
-#define lpfc_sli_misconfigured_port2_MASK	0x000000FF
-#define lpfc_sli_misconfigured_port2_WORD	word0
-#define lpfc_sli_misconfigured_port3_SHIFT	24
-#define lpfc_sli_misconfigured_port3_MASK	0x000000FF
-#define lpfc_sli_misconfigured_port3_WORD	word0
+#define lpfc_sli_misconfigured_port0_state_SHIFT	0
+#define lpfc_sli_misconfigured_port0_state_MASK		0x000000FF
+#define lpfc_sli_misconfigured_port0_state_WORD		word0
+#define lpfc_sli_misconfigured_port1_state_SHIFT	8
+#define lpfc_sli_misconfigured_port1_state_MASK		0x000000FF
+#define lpfc_sli_misconfigured_port1_state_WORD		word0
+#define lpfc_sli_misconfigured_port2_state_SHIFT	16
+#define lpfc_sli_misconfigured_port2_state_MASK		0x000000FF
+#define lpfc_sli_misconfigured_port2_state_WORD		word0
+#define lpfc_sli_misconfigured_port3_state_SHIFT	24
+#define lpfc_sli_misconfigured_port3_state_MASK		0x000000FF
+#define lpfc_sli_misconfigured_port3_state_WORD		word0
+	uint32_t word1;
+#define lpfc_sli_misconfigured_port0_op_SHIFT		0
+#define lpfc_sli_misconfigured_port0_op_MASK		0x00000001
+#define lpfc_sli_misconfigured_port0_op_WORD		word1
+#define lpfc_sli_misconfigured_port0_severity_SHIFT	1
+#define lpfc_sli_misconfigured_port0_severity_MASK	0x00000003
+#define lpfc_sli_misconfigured_port0_severity_WORD	word1
+#define lpfc_sli_misconfigured_port1_op_SHIFT		8
+#define lpfc_sli_misconfigured_port1_op_MASK		0x00000001
+#define lpfc_sli_misconfigured_port1_op_WORD		word1
+#define lpfc_sli_misconfigured_port1_severity_SHIFT	9
+#define lpfc_sli_misconfigured_port1_severity_MASK	0x00000003
+#define lpfc_sli_misconfigured_port1_severity_WORD	word1
+#define lpfc_sli_misconfigured_port2_op_SHIFT		16
+#define lpfc_sli_misconfigured_port2_op_MASK		0x00000001
+#define lpfc_sli_misconfigured_port2_op_WORD		word1
+#define lpfc_sli_misconfigured_port2_severity_SHIFT	17
+#define lpfc_sli_misconfigured_port2_severity_MASK	0x00000003
+#define lpfc_sli_misconfigured_port2_severity_WORD	word1
+#define lpfc_sli_misconfigured_port3_op_SHIFT		24
+#define lpfc_sli_misconfigured_port3_op_MASK		0x00000001
+#define lpfc_sli_misconfigured_port3_op_WORD		word1
+#define lpfc_sli_misconfigured_port3_severity_SHIFT	25
+#define lpfc_sli_misconfigured_port3_severity_MASK	0x00000003
+#define lpfc_sli_misconfigured_port3_severity_WORD	word1
 	} theEvent;
 #define LPFC_SLI_EVENT_STATUS_VALID			0x00
 #define LPFC_SLI_EVENT_STATUS_NOT_PRESENT	0x01
 #define LPFC_SLI_EVENT_STATUS_WRONG_TYPE	0x02
 #define LPFC_SLI_EVENT_STATUS_UNSUPPORTED	0x03
+#define LPFC_SLI_EVENT_STATUS_UNQUALIFIED	0x04
+#define LPFC_SLI_EVENT_STATUS_UNCERTIFIED	0x05
 };
 
 struct lpfc_acqe_sli {
--- zfcpdump-kernel-4.4.orig/drivers/scsi/lpfc/lpfc_init.c
+++ zfcpdump-kernel-4.4/drivers/scsi/lpfc/lpfc_init.c
@@ -1184,8 +1184,10 @@ lpfc_hb_timeout_handler(struct lpfc_hba
 
 	vports = lpfc_create_vport_work_array(phba);
 	if (vports != NULL)
-		for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++)
+		for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++) {
 			lpfc_rcv_seq_check_edtov(vports[i]);
+			lpfc_fdmi_num_disc_check(vports[i]);
+		}
 	lpfc_destroy_vport_work_array(phba, vports);
 
 	if ((phba->link_state == LPFC_HBA_ERROR) ||
@@ -1290,6 +1292,10 @@ lpfc_hb_timeout_handler(struct lpfc_hba
 				jiffies +
 				msecs_to_jiffies(1000 * LPFC_HB_MBOX_TIMEOUT));
 		}
+	} else {
+			mod_timer(&phba->hb_tmofunc,
+				jiffies +
+				msecs_to_jiffies(1000 * LPFC_HB_MBOX_INTERVAL));
 	}
 }
 
@@ -2621,7 +2627,6 @@ void
 lpfc_stop_vport_timers(struct lpfc_vport *vport)
 {
 	del_timer_sync(&vport->els_tmofunc);
-	del_timer_sync(&vport->fc_fdmitmo);
 	del_timer_sync(&vport->delayed_disc_tmo);
 	lpfc_can_disctmo(vport);
 	return;
@@ -2855,7 +2860,7 @@ lpfc_online(struct lpfc_hba *phba)
 	}
 
 	vports = lpfc_create_vport_work_array(phba);
-	if (vports != NULL)
+	if (vports != NULL) {
 		for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++) {
 			struct Scsi_Host *shost;
 			shost = lpfc_shost_from_vport(vports[i]);
@@ -2872,7 +2877,8 @@ lpfc_online(struct lpfc_hba *phba)
 			}
 			spin_unlock_irq(shost->host_lock);
 		}
-		lpfc_destroy_vport_work_array(phba, vports);
+	}
+	lpfc_destroy_vport_work_array(phba, vports);
 
 	lpfc_unblock_mgmt_io(phba);
 	return 0;
@@ -3340,10 +3346,6 @@ lpfc_create_port(struct lpfc_hba *phba,
 	vport->fc_disctmo.function = lpfc_disc_timeout;
 	vport->fc_disctmo.data = (unsigned long)vport;
 
-	init_timer(&vport->fc_fdmitmo);
-	vport->fc_fdmitmo.function = lpfc_fdmi_tmo;
-	vport->fc_fdmitmo.data = (unsigned long)vport;
-
 	init_timer(&vport->els_tmofunc);
 	vport->els_tmofunc.function = lpfc_els_timeout;
 	vport->els_tmofunc.data = (unsigned long)vport;
@@ -3709,49 +3711,6 @@ lpfc_sli4_parse_latt_type(struct lpfc_hb
 }
 
 /**
- * lpfc_sli4_parse_latt_link_speed - Parse sli4 link-attention link speed
- * @phba: pointer to lpfc hba data structure.
- * @acqe_link: pointer to the async link completion queue entry.
- *
- * This routine is to parse the SLI4 link-attention link speed and translate
- * it into the base driver's link-attention link speed coding.
- *
- * Return: Link-attention link speed in terms of base driver's coding.
- **/
-static uint8_t
-lpfc_sli4_parse_latt_link_speed(struct lpfc_hba *phba,
-				struct lpfc_acqe_link *acqe_link)
-{
-	uint8_t link_speed;
-
-	switch (bf_get(lpfc_acqe_link_speed, acqe_link)) {
-	case LPFC_ASYNC_LINK_SPEED_ZERO:
-	case LPFC_ASYNC_LINK_SPEED_10MBPS:
-	case LPFC_ASYNC_LINK_SPEED_100MBPS:
-		link_speed = LPFC_LINK_SPEED_UNKNOWN;
-		break;
-	case LPFC_ASYNC_LINK_SPEED_1GBPS:
-		link_speed = LPFC_LINK_SPEED_1GHZ;
-		break;
-	case LPFC_ASYNC_LINK_SPEED_10GBPS:
-		link_speed = LPFC_LINK_SPEED_10GHZ;
-		break;
-	case LPFC_ASYNC_LINK_SPEED_20GBPS:
-	case LPFC_ASYNC_LINK_SPEED_25GBPS:
-	case LPFC_ASYNC_LINK_SPEED_40GBPS:
-		link_speed = LPFC_LINK_SPEED_UNKNOWN;
-		break;
-	default:
-		lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
-				"0483 Invalid link-attention link speed: x%x\n",
-				bf_get(lpfc_acqe_link_speed, acqe_link));
-		link_speed = LPFC_LINK_SPEED_UNKNOWN;
-		break;
-	}
-	return link_speed;
-}
-
-/**
  * lpfc_sli_port_speed_get - Get sli3 link speed code to link speed
  * @phba: pointer to lpfc hba data structure.
  *
@@ -3767,27 +3726,35 @@ lpfc_sli_port_speed_get(struct lpfc_hba
 	if (!lpfc_is_link_up(phba))
 		return 0;
 
-	switch (phba->fc_linkspeed) {
-	case LPFC_LINK_SPEED_1GHZ:
-		link_speed = 1000;
-		break;
-	case LPFC_LINK_SPEED_2GHZ:
-		link_speed = 2000;
-		break;
-	case LPFC_LINK_SPEED_4GHZ:
-		link_speed = 4000;
-		break;
-	case LPFC_LINK_SPEED_8GHZ:
-		link_speed = 8000;
-		break;
-	case LPFC_LINK_SPEED_10GHZ:
-		link_speed = 10000;
-		break;
-	case LPFC_LINK_SPEED_16GHZ:
-		link_speed = 16000;
-		break;
-	default:
-		link_speed = 0;
+	if (phba->sli_rev <= LPFC_SLI_REV3) {
+		switch (phba->fc_linkspeed) {
+		case LPFC_LINK_SPEED_1GHZ:
+			link_speed = 1000;
+			break;
+		case LPFC_LINK_SPEED_2GHZ:
+			link_speed = 2000;
+			break;
+		case LPFC_LINK_SPEED_4GHZ:
+			link_speed = 4000;
+			break;
+		case LPFC_LINK_SPEED_8GHZ:
+			link_speed = 8000;
+			break;
+		case LPFC_LINK_SPEED_10GHZ:
+			link_speed = 10000;
+			break;
+		case LPFC_LINK_SPEED_16GHZ:
+			link_speed = 16000;
+			break;
+		default:
+			link_speed = 0;
+		}
+	} else {
+		if (phba->sli4_hba.link_state.logical_speed)
+			link_speed =
+			      phba->sli4_hba.link_state.logical_speed;
+		else
+			link_speed = phba->sli4_hba.link_state.speed;
 	}
 	return link_speed;
 }
@@ -3983,7 +3950,7 @@ lpfc_sli4_async_link_evt(struct lpfc_hba
 	la->eventTag = acqe_link->event_tag;
 	bf_set(lpfc_mbx_read_top_att_type, la, att_type);
 	bf_set(lpfc_mbx_read_top_link_spd, la,
-	       lpfc_sli4_parse_latt_link_speed(phba, acqe_link));
+	       (bf_get(lpfc_acqe_link_speed, acqe_link)));
 
 	/* Fake the the following irrelvant fields */
 	bf_set(lpfc_mbx_read_top_topology, la, LPFC_TOPOLOGY_PT_PT);
@@ -4113,22 +4080,18 @@ lpfc_sli4_async_sli_evt(struct lpfc_hba
 	char message[128];
 	uint8_t status;
 	uint8_t evt_type;
+	uint8_t operational = 0;
 	struct temp_event temp_event_data;
 	struct lpfc_acqe_misconfigured_event *misconfigured;
 	struct Scsi_Host  *shost;
 
 	evt_type = bf_get(lpfc_trailer_type, acqe_sli);
 
-	/* Special case Lancer */
-	if (bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) !=
-		 LPFC_SLI_INTF_IF_TYPE_2) {
-		lpfc_printf_log(phba, KERN_INFO, LOG_SLI,
-				"2901 Async SLI event - Event Data1:x%08x Event Data2:"
-				"x%08x SLI Event Type:%d\n",
-				acqe_sli->event_data1, acqe_sli->event_data2,
-				evt_type);
-		return;
-	}
+	lpfc_printf_log(phba, KERN_INFO, LOG_SLI,
+			"2901 Async SLI event - Event Data1:x%08x Event Data2:"
+			"x%08x SLI Event Type:%d\n",
+			acqe_sli->event_data1, acqe_sli->event_data2,
+			evt_type);
 
 	port_name = phba->Port[0];
 	if (port_name == 0x00)
@@ -4174,29 +4137,46 @@ lpfc_sli4_async_sli_evt(struct lpfc_hba
 		/* fetch the status for this port */
 		switch (phba->sli4_hba.lnk_info.lnk_no) {
 		case LPFC_LINK_NUMBER_0:
-			status = bf_get(lpfc_sli_misconfigured_port0,
+			status = bf_get(lpfc_sli_misconfigured_port0_state,
+					&misconfigured->theEvent);
+			operational = bf_get(lpfc_sli_misconfigured_port0_op,
 					&misconfigured->theEvent);
 			break;
 		case LPFC_LINK_NUMBER_1:
-			status = bf_get(lpfc_sli_misconfigured_port1,
+			status = bf_get(lpfc_sli_misconfigured_port1_state,
+					&misconfigured->theEvent);
+			operational = bf_get(lpfc_sli_misconfigured_port1_op,
 					&misconfigured->theEvent);
 			break;
 		case LPFC_LINK_NUMBER_2:
-			status = bf_get(lpfc_sli_misconfigured_port2,
+			status = bf_get(lpfc_sli_misconfigured_port2_state,
+					&misconfigured->theEvent);
+			operational = bf_get(lpfc_sli_misconfigured_port2_op,
 					&misconfigured->theEvent);
 			break;
 		case LPFC_LINK_NUMBER_3:
-			status = bf_get(lpfc_sli_misconfigured_port3,
+			status = bf_get(lpfc_sli_misconfigured_port3_state,
+					&misconfigured->theEvent);
+			operational = bf_get(lpfc_sli_misconfigured_port3_op,
 					&misconfigured->theEvent);
 			break;
 		default:
-			status = ~LPFC_SLI_EVENT_STATUS_VALID;
-			break;
+			lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
+					"3296 "
+					"LPFC_SLI_EVENT_TYPE_MISCONFIGURED "
+					"event: Invalid link %d",
+					phba->sli4_hba.lnk_info.lnk_no);
+			return;
 		}
 
+		/* Skip if optic state unchanged */
+		if (phba->sli4_hba.lnk_info.optic_state == status)
+			return;
+
 		switch (status) {
 		case LPFC_SLI_EVENT_STATUS_VALID:
-			return; /* no message if the sfp is okay */
+			sprintf(message, "Physical Link is functional");
+			break;
 		case LPFC_SLI_EVENT_STATUS_NOT_PRESENT:
 			sprintf(message, "Optics faulted/incorrectly "
 				"installed/not installed - Reseat optics, "
@@ -4211,15 +4191,26 @@ lpfc_sli4_async_sli_evt(struct lpfc_hba
 			sprintf(message, "Incompatible optics - Replace with "
 				"compatible optics for card to function.");
 			break;
+		case LPFC_SLI_EVENT_STATUS_UNQUALIFIED:
+			sprintf(message, "Unqualified optics - Replace with "
+				"Avago optics for Warranty and Technical "
+				"Support - Link is%s operational",
+				(operational) ? "" : " not");
+			break;
+		case LPFC_SLI_EVENT_STATUS_UNCERTIFIED:
+			sprintf(message, "Uncertified optics - Replace with "
+				"Avago-certified optics to enable link "
+				"operation - Link is%s operational",
+				(operational) ? "" : " not");
+			break;
 		default:
 			/* firmware is reporting a status we don't know about */
 			sprintf(message, "Unknown event status x%02x", status);
 			break;
 		}
-
+		phba->sli4_hba.lnk_info.optic_state = status;
 		lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
-				"3176 Misconfigured Physical Port - "
-				"Port Name %c %s\n", port_name, message);
+				"3176 Port Name %c %s\n", port_name, message);
 		break;
 	case LPFC_SLI_EVENT_TYPE_REMOTE_DPORT:
 		lpfc_printf_log(phba, KERN_INFO, LOG_SLI,
@@ -5293,6 +5284,9 @@ lpfc_sli4_driver_resource_setup(struct l
 	INIT_LIST_HEAD(&phba->sli4_hba.lpfc_vfi_blk_list);
 	INIT_LIST_HEAD(&phba->lpfc_vpi_blk_list);
 
+	/* initialize optic_state to 0xFF */
+	phba->sli4_hba.lnk_info.optic_state = 0xff;
+
 	/* Initialize the driver internal SLI layer lists. */
 	lpfc_sli_setup(phba);
 	lpfc_sli_queue_setup(phba);
@@ -6159,6 +6153,20 @@ lpfc_create_shost(struct lpfc_hba *phba)
 	/* Put reference to SCSI host to driver's device private data */
 	pci_set_drvdata(phba->pcidev, shost);
 
+	/*
+	 * At this point we are fully registered with PSA. In addition,
+	 * any initial discovery should be completed.
+	 */
+	vport->load_flag |= FC_ALLOW_FDMI;
+	if (phba->cfg_fdmi_on > LPFC_FDMI_NO_SUPPORT) {
+
+		/* Setup appropriate attribute masks */
+		vport->fdmi_hba_mask = LPFC_FDMI2_HBA_ATTR;
+		if (phba->cfg_fdmi_on == LPFC_FDMI_SMART_SAN)
+			vport->fdmi_port_mask = LPFC_FDMI2_SMART_ATTR;
+		else
+			vport->fdmi_port_mask = LPFC_FDMI2_PORT_ATTR;
+	}
 	return 0;
 }
 
@@ -8833,9 +8841,12 @@ found:
 				 * already mapped to this phys_id.
 				 */
 				if (cpup->irq != LPFC_VECTOR_MAP_EMPTY) {
-					chann[saved_chann] =
-						cpup->channel_id;
-					saved_chann++;
+					if (saved_chann <=
+					    LPFC_FCP_IO_CHAN_MAX) {
+						chann[saved_chann] =
+							cpup->channel_id;
+						saved_chann++;
+					}
 					goto out;
 				}
 
--- zfcpdump-kernel-4.4.orig/drivers/scsi/lpfc/lpfc_mbox.c
+++ zfcpdump-kernel-4.4/drivers/scsi/lpfc/lpfc_mbox.c
@@ -2145,10 +2145,12 @@ lpfc_reg_vfi(struct lpfcMboxq *mbox, str
 	reg_vfi->wwn[1] = cpu_to_le32(reg_vfi->wwn[1]);
 	reg_vfi->e_d_tov = phba->fc_edtov;
 	reg_vfi->r_a_tov = phba->fc_ratov;
-	reg_vfi->bde.addrHigh = putPaddrHigh(phys);
-	reg_vfi->bde.addrLow = putPaddrLow(phys);
-	reg_vfi->bde.tus.f.bdeSize = sizeof(vport->fc_sparam);
-	reg_vfi->bde.tus.f.bdeFlags = BUFF_TYPE_BDE_64;
+	if (phys) {
+		reg_vfi->bde.addrHigh = putPaddrHigh(phys);
+		reg_vfi->bde.addrLow = putPaddrLow(phys);
+		reg_vfi->bde.tus.f.bdeSize = sizeof(vport->fc_sparam);
+		reg_vfi->bde.tus.f.bdeFlags = BUFF_TYPE_BDE_64;
+	}
 	bf_set(lpfc_reg_vfi_nport_id, reg_vfi, vport->fc_myDID);
 
 	/* Only FC supports upd bit */
--- zfcpdump-kernel-4.4.orig/drivers/scsi/lpfc/lpfc_mem.c
+++ zfcpdump-kernel-4.4/drivers/scsi/lpfc/lpfc_mem.c
@@ -231,15 +231,13 @@ lpfc_mem_free(struct lpfc_hba *phba)
 	if (phba->lpfc_hbq_pool)
 		pci_pool_destroy(phba->lpfc_hbq_pool);
 	phba->lpfc_hbq_pool = NULL;
-
-	if (phba->rrq_pool)
-		mempool_destroy(phba->rrq_pool);
+	mempool_destroy(phba->rrq_pool);
 	phba->rrq_pool = NULL;
 
 	/* Free NLP memory pool */
 	mempool_destroy(phba->nlp_mem_pool);
 	phba->nlp_mem_pool = NULL;
-	if (phba->sli_rev == LPFC_SLI_REV4 && phba->active_rrq_pool) {
+	if (phba->sli_rev == LPFC_SLI_REV4) {
 		mempool_destroy(phba->active_rrq_pool);
 		phba->active_rrq_pool = NULL;
 	}
--- zfcpdump-kernel-4.4.orig/drivers/scsi/lpfc/lpfc_nportdisc.c
+++ zfcpdump-kernel-4.4/drivers/scsi/lpfc/lpfc_nportdisc.c
@@ -280,38 +280,12 @@ lpfc_rcv_plogi(struct lpfc_vport *vport,
 	uint32_t *lp;
 	IOCB_t *icmd;
 	struct serv_parm *sp;
+	uint32_t ed_tov;
 	LPFC_MBOXQ_t *mbox;
 	struct ls_rjt stat;
 	int rc;
 
 	memset(&stat, 0, sizeof (struct ls_rjt));
-	if (vport->port_state <= LPFC_FDISC) {
-		/* Before responding to PLOGI, check for pt2pt mode.
-		 * If we are pt2pt, with an outstanding FLOGI, abort
-		 * the FLOGI and resend it first.
-		 */
-		if (vport->fc_flag & FC_PT2PT) {
-			 lpfc_els_abort_flogi(phba);
-		        if (!(vport->fc_flag & FC_PT2PT_PLOGI)) {
-				/* If the other side is supposed to initiate
-				 * the PLOGI anyway, just ACC it now and
-				 * move on with discovery.
-				 */
-				phba->fc_edtov = FF_DEF_EDTOV;
-				phba->fc_ratov = FF_DEF_RATOV;
-				/* Start discovery - this should just do
-				   CLEAR_LA */
-				lpfc_disc_start(vport);
-			} else
-				lpfc_initial_flogi(vport);
-		} else {
-			stat.un.b.lsRjtRsnCode = LSRJT_LOGICAL_BSY;
-			stat.un.b.lsRjtRsnCodeExp = LSEXP_NOTHING_MORE;
-			lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb,
-					    ndlp, NULL);
-			return 0;
-		}
-	}
 	pcmd = (struct lpfc_dmabuf *) cmdiocb->context2;
 	lp = (uint32_t *) pcmd->virt;
 	sp = (struct serv_parm *) ((uint8_t *) lp + sizeof (uint32_t));
@@ -404,30 +378,46 @@ lpfc_rcv_plogi(struct lpfc_vport *vport,
 	/* Check for Nport to NPort pt2pt protocol */
 	if ((vport->fc_flag & FC_PT2PT) &&
 	    !(vport->fc_flag & FC_PT2PT_PLOGI)) {
-
 		/* rcv'ed PLOGI decides what our NPortId will be */
 		vport->fc_myDID = icmd->un.rcvels.parmRo;
-		mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
-		if (mbox == NULL)
-			goto out;
-		lpfc_config_link(phba, mbox);
-		mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
-		mbox->vport = vport;
-		rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT);
-		if (rc == MBX_NOT_FINISHED) {
-			mempool_free(mbox, phba->mbox_mem_pool);
-			goto out;
+
+		ed_tov = be32_to_cpu(sp->cmn.e_d_tov);
+		if (sp->cmn.edtovResolution) {
+			/* E_D_TOV ticks are in nanoseconds */
+			ed_tov = (phba->fc_edtov + 999999) / 1000000;
 		}
+
 		/*
-		 * For SLI4, the VFI/VPI are registered AFTER the
-		 * Nport with the higher WWPN sends us a PLOGI with
-		 * our assigned NPortId.
+		 * For pt-to-pt, use the larger EDTOV
+		 * RATOV = 2 * EDTOV
 		 */
+		if (ed_tov > phba->fc_edtov)
+			phba->fc_edtov = ed_tov;
+		phba->fc_ratov = (2 * phba->fc_edtov) / 1000;
+
+		memcpy(&phba->fc_fabparam, sp, sizeof(struct serv_parm));
+
+		/* Issue config_link / reg_vfi to account for updated TOV's */
+
 		if (phba->sli_rev == LPFC_SLI_REV4)
 			lpfc_issue_reg_vfi(vport);
+		else {
+			mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
+			if (mbox == NULL)
+				goto out;
+			lpfc_config_link(phba, mbox);
+			mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
+			mbox->vport = vport;
+			rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT);
+			if (rc == MBX_NOT_FINISHED) {
+				mempool_free(mbox, phba->mbox_mem_pool);
+				goto out;
+			}
+		}
 
 		lpfc_can_disctmo(vport);
 	}
+
 	mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
 	if (!mbox)
 		goto out;
@@ -1038,7 +1028,9 @@ lpfc_cmpl_plogi_plogi_issue(struct lpfc_
 	uint32_t *lp;
 	IOCB_t *irsp;
 	struct serv_parm *sp;
+	uint32_t ed_tov;
 	LPFC_MBOXQ_t *mbox;
+	int rc;
 
 	cmdiocb = (struct lpfc_iocbq *) arg;
 	rspiocb = cmdiocb->context_un.rsp_iocb;
@@ -1094,18 +1086,63 @@ lpfc_cmpl_plogi_plogi_issue(struct lpfc_
 	ndlp->nlp_maxframe =
 		((sp->cmn.bbRcvSizeMsb & 0x0F) << 8) | sp->cmn.bbRcvSizeLsb;
 
+	if ((vport->fc_flag & FC_PT2PT) &&
+	    (vport->fc_flag & FC_PT2PT_PLOGI)) {
+		ed_tov = be32_to_cpu(sp->cmn.e_d_tov);
+		if (sp->cmn.edtovResolution) {
+			/* E_D_TOV ticks are in nanoseconds */
+			ed_tov = (phba->fc_edtov + 999999) / 1000000;
+		}
+
+		/*
+		 * Use the larger EDTOV
+		 * RATOV = 2 * EDTOV for pt-to-pt
+		 */
+		if (ed_tov > phba->fc_edtov)
+			phba->fc_edtov = ed_tov;
+		phba->fc_ratov = (2 * phba->fc_edtov) / 1000;
+
+		memcpy(&phba->fc_fabparam, sp, sizeof(struct serv_parm));
+
+		/* Issue config_link / reg_vfi to account for updated TOV's */
+		if (phba->sli_rev == LPFC_SLI_REV4) {
+			lpfc_issue_reg_vfi(vport);
+		} else {
+			mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
+			if (!mbox) {
+				lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
+						 "0133 PLOGI: no memory "
+						 "for config_link "
+						 "Data: x%x x%x x%x x%x\n",
+						 ndlp->nlp_DID, ndlp->nlp_state,
+						 ndlp->nlp_flag, ndlp->nlp_rpi);
+				goto out;
+			}
+
+			lpfc_config_link(phba, mbox);
+
+			mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
+			mbox->vport = vport;
+			rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT);
+			if (rc == MBX_NOT_FINISHED) {
+				mempool_free(mbox, phba->mbox_mem_pool);
+				goto out;
+			}
+		}
+	}
+
+	lpfc_unreg_rpi(vport, ndlp);
+
 	mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
 	if (!mbox) {
 		lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
-			"0133 PLOGI: no memory for reg_login "
-			"Data: x%x x%x x%x x%x\n",
-			ndlp->nlp_DID, ndlp->nlp_state,
-			ndlp->nlp_flag, ndlp->nlp_rpi);
+				 "0018 PLOGI: no memory for reg_login "
+				 "Data: x%x x%x x%x x%x\n",
+				 ndlp->nlp_DID, ndlp->nlp_state,
+				 ndlp->nlp_flag, ndlp->nlp_rpi);
 		goto out;
 	}
 
-	lpfc_unreg_rpi(vport, ndlp);
-
 	if (lpfc_reg_rpi(phba, vport->vpi, irsp->un.elsreq64.remoteID,
 			 (uint8_t *) sp, mbox, ndlp->nlp_rpi) == 0) {
 		switch (ndlp->nlp_DID) {
@@ -2299,6 +2336,9 @@ lpfc_cmpl_reglogin_npr_node(struct lpfc_
 		if (vport->phba->sli_rev < LPFC_SLI_REV4)
 			ndlp->nlp_rpi = mb->un.varWords[0];
 		ndlp->nlp_flag |= NLP_RPI_REGISTERED;
+		if (ndlp->nlp_flag & NLP_LOGO_ACC) {
+			lpfc_unreg_rpi(vport, ndlp);
+		}
 	} else {
 		if (ndlp->nlp_flag & NLP_NODEV_REMOVE) {
 			lpfc_drop_node(vport, ndlp);
--- zfcpdump-kernel-4.4.orig/drivers/scsi/lpfc/lpfc_scsi.c
+++ zfcpdump-kernel-4.4/drivers/scsi/lpfc/lpfc_scsi.c
@@ -3676,6 +3676,7 @@ static void
 lpfc_handle_fcp_err(struct lpfc_vport *vport, struct lpfc_scsi_buf *lpfc_cmd,
 		    struct lpfc_iocbq *rsp_iocb)
 {
+	struct lpfc_hba *phba = vport->phba;
 	struct scsi_cmnd *cmnd = lpfc_cmd->pCmd;
 	struct fcp_cmnd *fcpcmd = lpfc_cmd->fcp_cmnd;
 	struct fcp_rsp *fcprsp = lpfc_cmd->fcp_rsp;
@@ -3685,6 +3686,7 @@ lpfc_handle_fcp_err(struct lpfc_vport *v
 	uint32_t *lp;
 	uint32_t host_status = DID_OK;
 	uint32_t rsplen = 0;
+	uint32_t fcpDl;
 	uint32_t logit = LOG_FCP | LOG_FCP_ERROR;
 
 
@@ -3755,13 +3757,14 @@ lpfc_handle_fcp_err(struct lpfc_vport *v
 			 fcprsp->rspInfo3);
 
 	scsi_set_resid(cmnd, 0);
+	fcpDl = be32_to_cpu(fcpcmd->fcpDl);
 	if (resp_info & RESID_UNDER) {
 		scsi_set_resid(cmnd, be32_to_cpu(fcprsp->rspResId));
 
 		lpfc_printf_vlog(vport, KERN_INFO, LOG_FCP_UNDER,
 				 "9025 FCP Read Underrun, expected %d, "
 				 "residual %d Data: x%x x%x x%x\n",
-				 be32_to_cpu(fcpcmd->fcpDl),
+				 fcpDl,
 				 scsi_get_resid(cmnd), fcpi_parm, cmnd->cmnd[0],
 				 cmnd->underflow);
 
@@ -3777,7 +3780,7 @@ lpfc_handle_fcp_err(struct lpfc_vport *v
 					 LOG_FCP | LOG_FCP_ERROR,
 					 "9026 FCP Read Check Error "
 					 "and Underrun Data: x%x x%x x%x x%x\n",
-					 be32_to_cpu(fcpcmd->fcpDl),
+					 fcpDl,
 					 scsi_get_resid(cmnd), fcpi_parm,
 					 cmnd->cmnd[0]);
 			scsi_set_resid(cmnd, scsi_bufflen(cmnd));
@@ -3812,13 +3815,25 @@ lpfc_handle_fcp_err(struct lpfc_vport *v
 	 * Check SLI validation that all the transfer was actually done
 	 * (fcpi_parm should be zero). Apply check only to reads.
 	 */
-	} else if (fcpi_parm && (cmnd->sc_data_direction == DMA_FROM_DEVICE)) {
+	} else if (fcpi_parm) {
 		lpfc_printf_vlog(vport, KERN_WARNING, LOG_FCP | LOG_FCP_ERROR,
-				 "9029 FCP Read Check Error Data: "
+				 "9029 FCP %s Check Error xri x%x  Data: "
 				 "x%x x%x x%x x%x x%x\n",
-				 be32_to_cpu(fcpcmd->fcpDl),
-				 be32_to_cpu(fcprsp->rspResId),
+				 ((cmnd->sc_data_direction == DMA_FROM_DEVICE) ?
+				 "Read" : "Write"),
+				 ((phba->sli_rev == LPFC_SLI_REV4) ?
+				 lpfc_cmd->cur_iocbq.sli4_xritag :
+				 rsp_iocb->iocb.ulpContext),
+				 fcpDl, be32_to_cpu(fcprsp->rspResId),
 				 fcpi_parm, cmnd->cmnd[0], scsi_status);
+
+		/* There is some issue with the LPe12000 that causes it
+		 * to miscalculate the fcpi_parm and falsely trip this
+		 * recovery logic.  Detect this case and don't error when true.
+		 */
+		if (fcpi_parm > fcpDl)
+			goto out;
+
 		switch (scsi_status) {
 		case SAM_STAT_GOOD:
 		case SAM_STAT_CHECK_CONDITION:
@@ -3859,7 +3874,7 @@ int lpfc_sli4_scmd_to_wqidx_distr(struct
 	uint32_t tag;
 	uint16_t hwq;
 
-	if (shost_use_blk_mq(cmnd->device->host)) {
+	if (cmnd && shost_use_blk_mq(cmnd->device->host)) {
 		tag = blk_mq_unique_tag(cmnd->request);
 		hwq = blk_mq_unique_tag_to_hwq(tag);
 
@@ -3908,9 +3923,9 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba
 	uint32_t logit = LOG_FCP;
 
 	/* Sanity check on return of outstanding command */
-	if (!(lpfc_cmd->pCmd))
-		return;
 	cmd = lpfc_cmd->pCmd;
+	if (!cmd)
+		return;
 	shost = cmd->device->host;
 
 	lpfc_cmd->result = (pIocbOut->iocb.un.ulpWord[4] & IOERR_PARAM_MASK);
@@ -4446,15 +4461,7 @@ lpfc_info(struct Scsi_Host *host)
 				 phba->Port);
 		}
 		len = strlen(lpfcinfobuf);
-		if (phba->sli_rev <= LPFC_SLI_REV3) {
-			link_speed = lpfc_sli_port_speed_get(phba);
-		} else {
-			if (phba->sli4_hba.link_state.logical_speed)
-				link_speed =
-				      phba->sli4_hba.link_state.logical_speed;
-			else
-				link_speed = phba->sli4_hba.link_state.speed;
-		}
+		link_speed = lpfc_sli_port_speed_get(phba);
 		if (link_speed != 0)
 			snprintf(lpfcinfobuf + len, 384-len,
 				 " Logical Link Speed: %d Mbps", link_speed);
--- zfcpdump-kernel-4.4.orig/drivers/scsi/lpfc/lpfc_sli.c
+++ zfcpdump-kernel-4.4/drivers/scsi/lpfc/lpfc_sli.c
@@ -14842,10 +14842,12 @@ lpfc_fc_frame_add(struct lpfc_vport *vpo
 	struct lpfc_dmabuf *h_buf;
 	struct hbq_dmabuf *seq_dmabuf = NULL;
 	struct hbq_dmabuf *temp_dmabuf = NULL;
+	uint8_t	found = 0;
 
 	INIT_LIST_HEAD(&dmabuf->dbuf.list);
 	dmabuf->time_stamp = jiffies;
 	new_hdr = (struct fc_frame_header *)dmabuf->hbuf.virt;
+
 	/* Use the hdr_buf to find the sequence that this frame belongs to */
 	list_for_each_entry(h_buf, &vport->rcv_buffer_list, list) {
 		temp_hdr = (struct fc_frame_header *)h_buf->virt;
@@ -14885,7 +14887,8 @@ lpfc_fc_frame_add(struct lpfc_vport *vpo
 		return seq_dmabuf;
 	}
 	/* find the correct place in the sequence to insert this frame */
-	list_for_each_entry_reverse(d_buf, &seq_dmabuf->dbuf.list, list) {
+	d_buf = list_entry(seq_dmabuf->dbuf.list.prev, typeof(*d_buf), list);
+	while (!found) {
 		temp_dmabuf = container_of(d_buf, struct hbq_dmabuf, dbuf);
 		temp_hdr = (struct fc_frame_header *)temp_dmabuf->hbuf.virt;
 		/*
@@ -14895,9 +14898,17 @@ lpfc_fc_frame_add(struct lpfc_vport *vpo
 		if (be16_to_cpu(new_hdr->fh_seq_cnt) >
 			be16_to_cpu(temp_hdr->fh_seq_cnt)) {
 			list_add(&dmabuf->dbuf.list, &temp_dmabuf->dbuf.list);
-			return seq_dmabuf;
+			found = 1;
+			break;
 		}
+
+		if (&d_buf->list == &seq_dmabuf->dbuf.list)
+			break;
+		d_buf = list_entry(d_buf->list.prev, typeof(*d_buf), list);
 	}
+
+	if (found)
+		return seq_dmabuf;
 	return NULL;
 }
 
@@ -16173,7 +16184,7 @@ fail_fcf_read:
 }
 
 /**
- * lpfc_check_next_fcf_pri
+ * lpfc_check_next_fcf_pri_level
  * phba pointer to the lpfc_hba struct for this port.
  * This routine is called from the lpfc_sli4_fcf_rr_next_index_get
  * routine when the rr_bmask is empty. The FCF indecies are put into the
@@ -16329,8 +16340,12 @@ next_priority:
 
 	if (next_fcf_index < LPFC_SLI4_FCF_TBL_INDX_MAX &&
 		phba->fcf.fcf_pri[next_fcf_index].fcf_rec.flag &
-		LPFC_FCF_FLOGI_FAILED)
+		LPFC_FCF_FLOGI_FAILED) {
+		if (list_is_singular(&phba->fcf.fcf_pri_list))
+			return LPFC_FCOE_FCF_NEXT_NONE;
+
 		goto next_priority;
+	}
 
 	lpfc_printf_log(phba, KERN_INFO, LOG_FIP,
 			"2845 Get next roundrobin failover FCF (x%x)\n",
--- zfcpdump-kernel-4.4.orig/drivers/scsi/lpfc/lpfc_sli4.h
+++ zfcpdump-kernel-4.4/drivers/scsi/lpfc/lpfc_sli4.h
@@ -442,6 +442,7 @@ struct lpfc_sli4_lnk_info {
 #define LPFC_LNK_GE	0x0 /* FCoE */
 #define LPFC_LNK_FC	0x1 /* FC   */
 	uint8_t lnk_no;
+	uint8_t optic_state;
 };
 
 #define LPFC_SLI4_HANDLER_CNT		(LPFC_FCP_IO_CHAN_MAX+ \
--- zfcpdump-kernel-4.4.orig/drivers/scsi/lpfc/lpfc_version.h
+++ zfcpdump-kernel-4.4/drivers/scsi/lpfc/lpfc_version.h
@@ -18,7 +18,7 @@
  * included with this package.                                     *
  *******************************************************************/
 
-#define LPFC_DRIVER_VERSION "11.0.0.0."
+#define LPFC_DRIVER_VERSION "11.0.0.10."
 #define LPFC_DRIVER_NAME		"lpfc"
 
 /* Used for SLI 2/3 */
--- zfcpdump-kernel-4.4.orig/drivers/scsi/lpfc/lpfc_vport.c
+++ zfcpdump-kernel-4.4/drivers/scsi/lpfc/lpfc_vport.c
@@ -393,6 +393,14 @@ lpfc_vport_create(struct fc_vport *fc_vp
 	*(struct lpfc_vport **)fc_vport->dd_data = vport;
 	vport->fc_vport = fc_vport;
 
+	/* At this point we are fully registered with SCSI Layer.  */
+	vport->load_flag |= FC_ALLOW_FDMI;
+	if (phba->cfg_fdmi_on > LPFC_FDMI_NO_SUPPORT) {
+		/* Setup appropriate attribute masks */
+		vport->fdmi_hba_mask = phba->pport->fdmi_hba_mask;
+		vport->fdmi_port_mask = phba->pport->fdmi_port_mask;
+	}
+
 	/*
 	 * In SLI4, the vpi must be activated before it can be used
 	 * by the port.
--- zfcpdump-kernel-4.4.orig/drivers/scsi/megaraid/megaraid_mm.c
+++ zfcpdump-kernel-4.4/drivers/scsi/megaraid/megaraid_mm.c
@@ -179,8 +179,12 @@ mraid_mm_ioctl(struct file *filep, unsig
 
 	/*
 	 * The following call will block till a kioc is available
+	 * or return NULL if the list head is empty for the pointer
+	 * of type mraid_mmapt passed to mraid_mm_alloc_kioc
 	 */
 	kioc = mraid_mm_alloc_kioc(adp);
+	if (!kioc)
+		return -ENXIO;
 
 	/*
 	 * User sent the old mimd_t ioctl packet. Convert it to uioc_t.
--- zfcpdump-kernel-4.4.orig/drivers/scsi/megaraid/megaraid_sas.h
+++ zfcpdump-kernel-4.4/drivers/scsi/megaraid/megaraid_sas.h
@@ -35,8 +35,8 @@
 /*
  * MegaRAID SAS Driver meta data
  */
-#define MEGASAS_VERSION				"06.808.16.00-rc1"
-#define MEGASAS_RELDATE				"Oct. 8, 2015"
+#define MEGASAS_VERSION				"06.810.09.00-rc1"
+#define MEGASAS_RELDATE				"Jan. 28, 2016"
 
 /*
  * Device IDs
@@ -152,6 +152,7 @@
 #define MFI_RESET_FLAGS				MFI_INIT_READY| \
 						MFI_INIT_MFIMODE| \
 						MFI_INIT_ABORT
+#define MPI2_IOCINIT_MSGFLAG_RDPQ_ARRAY_MODE    (0x01)
 
 /*
  * MFI frame flags
@@ -170,6 +171,7 @@
 
 /* Driver internal */
 #define DRV_DCMD_POLLED_MODE		0x1
+#define DRV_DCMD_SKIP_REFIRE		0x2
 
 /*
  * Definition for cmd_status
@@ -214,6 +216,7 @@
 
 #define MR_DCMD_CTRL_SET_CRASH_DUMP_PARAMS	0x01190100
 #define MR_DRIVER_SET_APP_CRASHDUMP_MODE	(0xF0010000 | 0x0600)
+#define MR_DCMD_PD_GET_INFO			0x02020000
 
 /*
  * Global functions
@@ -390,6 +393,7 @@ enum MR_EVT_ARGS {
 
 
 #define SGE_BUFFER_SIZE	4096
+#define MEGASAS_CLUSTER_ID_SIZE	16
 /*
  * define constants for device list query options
  */
@@ -434,6 +438,257 @@ enum MR_PD_STATE {
 	MR_PD_STATE_SYSTEM              = 0x40,
  };
 
+union MR_PD_REF {
+	struct {
+		u16	 deviceId;
+		u16	 seqNum;
+	} mrPdRef;
+	u32	 ref;
+};
+
+/*
+ * define the DDF Type bit structure
+ */
+union MR_PD_DDF_TYPE {
+	 struct {
+		union {
+			struct {
+#ifndef __BIG_ENDIAN_BITFIELD
+				 u16	 forcedPDGUID:1;
+				 u16	 inVD:1;
+				 u16	 isGlobalSpare:1;
+				 u16	 isSpare:1;
+				 u16	 isForeign:1;
+				 u16	 reserved:7;
+				 u16	 intf:4;
+#else
+				 u16	 intf:4;
+				 u16	 reserved:7;
+				 u16	 isForeign:1;
+				 u16	 isSpare:1;
+				 u16	 isGlobalSpare:1;
+				 u16	 inVD:1;
+				 u16	 forcedPDGUID:1;
+#endif
+			 } pdType;
+			 u16	 type;
+		 };
+		 u16	 reserved;
+	 } ddf;
+	 struct {
+		 u32	reserved;
+	 } nonDisk;
+	 u32	 type;
+} __packed;
+
+/*
+ * defines the progress structure
+ */
+union MR_PROGRESS {
+	struct  {
+		u16 progress;
+		union {
+			u16 elapsedSecs;
+			u16 elapsedSecsForLastPercent;
+		};
+	} mrProgress;
+	u32 w;
+} __packed;
+
+/*
+ * defines the physical drive progress structure
+ */
+struct MR_PD_PROGRESS {
+	struct {
+#ifndef MFI_BIG_ENDIAN
+		u32     rbld:1;
+		u32     patrol:1;
+		u32     clear:1;
+		u32     copyBack:1;
+		u32     erase:1;
+		u32     locate:1;
+		u32     reserved:26;
+#else
+		u32     reserved:26;
+		u32     locate:1;
+		u32     erase:1;
+		u32     copyBack:1;
+		u32     clear:1;
+		u32     patrol:1;
+		u32     rbld:1;
+#endif
+	} active;
+	union MR_PROGRESS     rbld;
+	union MR_PROGRESS     patrol;
+	union {
+		union MR_PROGRESS     clear;
+		union MR_PROGRESS     erase;
+	};
+
+	struct {
+#ifndef MFI_BIG_ENDIAN
+		u32     rbld:1;
+		u32     patrol:1;
+		u32     clear:1;
+		u32     copyBack:1;
+		u32     erase:1;
+		u32     reserved:27;
+#else
+		u32     reserved:27;
+		u32     erase:1;
+		u32     copyBack:1;
+		u32     clear:1;
+		u32     patrol:1;
+		u32     rbld:1;
+#endif
+	} pause;
+
+	union MR_PROGRESS     reserved[3];
+} __packed;
+
+struct  MR_PD_INFO {
+	union MR_PD_REF	ref;
+	u8 inquiryData[96];
+	u8 vpdPage83[64];
+	u8 notSupported;
+	u8 scsiDevType;
+
+	union {
+		u8 connectedPortBitmap;
+		u8 connectedPortNumbers;
+	};
+
+	u8 deviceSpeed;
+	u32 mediaErrCount;
+	u32 otherErrCount;
+	u32 predFailCount;
+	u32 lastPredFailEventSeqNum;
+
+	u16 fwState;
+	u8 disabledForRemoval;
+	u8 linkSpeed;
+	union MR_PD_DDF_TYPE state;
+
+	struct {
+		u8 count;
+#ifndef __BIG_ENDIAN_BITFIELD
+		u8 isPathBroken:4;
+		u8 reserved3:3;
+		u8 widePortCapable:1;
+#else
+		u8 widePortCapable:1;
+		u8 reserved3:3;
+		u8 isPathBroken:4;
+#endif
+
+		u8 connectorIndex[2];
+		u8 reserved[4];
+		u64 sasAddr[2];
+		u8 reserved2[16];
+	} pathInfo;
+
+	u64 rawSize;
+	u64 nonCoercedSize;
+	u64 coercedSize;
+	u16 enclDeviceId;
+	u8 enclIndex;
+
+	union {
+		u8 slotNumber;
+		u8 enclConnectorIndex;
+	};
+
+	struct MR_PD_PROGRESS progInfo;
+	u8 badBlockTableFull;
+	u8 unusableInCurrentConfig;
+	u8 vpdPage83Ext[64];
+	u8 powerState;
+	u8 enclPosition;
+	u32 allowedOps;
+	u16 copyBackPartnerId;
+	u16 enclPartnerDeviceId;
+	struct {
+#ifndef __BIG_ENDIAN_BITFIELD
+		u16 fdeCapable:1;
+		u16 fdeEnabled:1;
+		u16 secured:1;
+		u16 locked:1;
+		u16 foreign:1;
+		u16 needsEKM:1;
+		u16 reserved:10;
+#else
+		u16 reserved:10;
+		u16 needsEKM:1;
+		u16 foreign:1;
+		u16 locked:1;
+		u16 secured:1;
+		u16 fdeEnabled:1;
+		u16 fdeCapable:1;
+#endif
+	} security;
+	u8 mediaType;
+	u8 notCertified;
+	u8 bridgeVendor[8];
+	u8 bridgeProductIdentification[16];
+	u8 bridgeProductRevisionLevel[4];
+	u8 satBridgeExists;
+
+	u8 interfaceType;
+	u8 temperature;
+	u8 emulatedBlockSize;
+	u16 userDataBlockSize;
+	u16 reserved2;
+
+	struct {
+#ifndef __BIG_ENDIAN_BITFIELD
+		u32 piType:3;
+		u32 piFormatted:1;
+		u32 piEligible:1;
+		u32 NCQ:1;
+		u32 WCE:1;
+		u32 commissionedSpare:1;
+		u32 emergencySpare:1;
+		u32 ineligibleForSSCD:1;
+		u32 ineligibleForLd:1;
+		u32 useSSEraseType:1;
+		u32 wceUnchanged:1;
+		u32 supportScsiUnmap:1;
+		u32 reserved:18;
+#else
+		u32 reserved:18;
+		u32 supportScsiUnmap:1;
+		u32 wceUnchanged:1;
+		u32 useSSEraseType:1;
+		u32 ineligibleForLd:1;
+		u32 ineligibleForSSCD:1;
+		u32 emergencySpare:1;
+		u32 commissionedSpare:1;
+		u32 WCE:1;
+		u32 NCQ:1;
+		u32 piEligible:1;
+		u32 piFormatted:1;
+		u32 piType:3;
+#endif
+	} properties;
+
+	u64 shieldDiagCompletionTime;
+	u8 shieldCounter;
+
+	u8 linkSpeedOther;
+	u8 reserved4[2];
+
+	struct {
+#ifndef __BIG_ENDIAN_BITFIELD
+		u32 bbmErrCountSupported:1;
+		u32 bbmErrCount:31;
+#else
+		u32 bbmErrCount:31;
+		u32 bbmErrCountSupported:1;
+#endif
+	} bbmErr;
+
+	u8 reserved1[512-428];
+} __packed;
 
  /*
  * defines the physical drive address structure
@@ -473,6 +728,7 @@ struct megasas_pd_list {
 	u16             tid;
 	u8             driveType;
 	u8             driveState;
+	u8             interface;
 } __packed;
 
  /*
@@ -972,7 +1228,8 @@ struct megasas_ctrl_info {
 	*/
 	struct {
 #if defined(__BIG_ENDIAN_BITFIELD)
-		u32     reserved:26;
+		u32     reserved:25;
+		u32     passive:1;
 		u32     premiumFeatureMismatch:1;
 		u32     ctrlPropIncompatible:1;
 		u32     fwVersionMismatch:1;
@@ -986,11 +1243,12 @@ struct megasas_ctrl_info {
 		u32     fwVersionMismatch:1;
 		u32     ctrlPropIncompatible:1;
 		u32     premiumFeatureMismatch:1;
-		u32     reserved:26;
+		u32     passive:1;
+		u32     reserved:25;
 #endif
 	} cluster;
 
-	char clusterId[16];                     /*7D4h */
+	char clusterId[MEGASAS_CLUSTER_ID_SIZE]; /*0x7D4 */
 	struct {
 		u8  maxVFsSupported;            /*0x7E4*/
 		u8  numVFsEnabled;              /*0x7E5*/
@@ -1083,6 +1341,8 @@ struct megasas_ctrl_info {
 
 #define VD_EXT_DEBUG 0
 
+#define SCAN_PD_CHANNEL	0x1
+#define SCAN_VD_CHANNEL	0x2
 
 enum MR_SCSI_CMD_TYPE {
 	READ_WRITE_LDIO = 0,
@@ -1091,6 +1351,17 @@ enum MR_SCSI_CMD_TYPE {
 	NON_READ_WRITE_SYSPDIO = 3,
 };
 
+enum DCMD_TIMEOUT_ACTION {
+	INITIATE_OCR = 0,
+	KILL_ADAPTER = 1,
+	IGNORE_TIMEOUT = 2,
+};
+
+enum FW_BOOT_CONTEXT {
+	PROBE_CONTEXT = 0,
+	OCR_CONTEXT = 1,
+};
+
 /* Frame Type */
 #define IO_FRAME				0
 #define PTHRU_FRAME				1
@@ -1137,6 +1408,7 @@ enum MR_SCSI_CMD_TYPE {
 
 #define MFI_OB_INTR_STATUS_MASK			0x00000002
 #define MFI_POLL_TIMEOUT_SECS			60
+#define MFI_IO_TIMEOUT_SECS			180
 #define MEGASAS_SRIOV_HEARTBEAT_INTERVAL_VF	(5 * HZ)
 #define MEGASAS_OCR_SETTLE_TIME_VF		(1000 * 30)
 #define MEGASAS_ROUTINE_WAIT_TIME_VF		300
@@ -1154,6 +1426,7 @@ enum MR_SCSI_CMD_TYPE {
 #define MR_MAX_REPLY_QUEUES_EXT_OFFSET          0X003FC000
 #define MR_MAX_REPLY_QUEUES_EXT_OFFSET_SHIFT    14
 #define MR_MAX_MSIX_REG_ARRAY                   16
+#define MR_RDPQ_MODE_OFFSET			0X00800000
 /*
 * register set for both 1068 and 1078 controllers
 * structure extended for 1078 registers
@@ -1193,8 +1466,9 @@ struct megasas_register_set {
 
 	u32 	outbound_scratch_pad ;		/*00B0h*/
 	u32	outbound_scratch_pad_2;         /*00B4h*/
+	u32	outbound_scratch_pad_3;         /*00B8h*/
 
-	u32	reserved_4[2];			/*00B8h*/
+	u32	reserved_4;			/*00BCh*/
 
 	u32 	inbound_low_queue_port ;	/*00C0h*/
 
@@ -1266,7 +1540,10 @@ union megasas_sgl_frame {
 typedef union _MFI_CAPABILITIES {
 	struct {
 #if   defined(__BIG_ENDIAN_BITFIELD)
-		u32     reserved:23;
+		u32     reserved:20;
+		u32     support_qd_throttling:1;
+		u32     support_fp_rlbypass:1;
+		u32     support_vfid_in_ioframe:1;
 		u32     support_ext_io_size:1;
 		u32	support_ext_queue_depth:1;
 		u32     security_protocol_cmds_fw:1;
@@ -1286,7 +1563,10 @@ typedef union _MFI_CAPABILITIES {
 		u32     security_protocol_cmds_fw:1;
 		u32	support_ext_queue_depth:1;
 		u32     support_ext_io_size:1;
-		u32     reserved:23;
+		u32     support_vfid_in_ioframe:1;
+		u32     support_fp_rlbypass:1;
+		u32     support_qd_throttling:1;
+		u32     reserved:20;
 #endif
 	} mfi_capabilities;
 	__le32		reg;
@@ -1511,6 +1791,15 @@ union megasas_frame {
 	u8 raw_bytes[64];
 };
 
+/**
+ * struct MR_PRIV_DEVICE - sdev private hostdata
+ * @is_tm_capable: firmware managed tm_capable flag
+ * @tm_busy: TM request is in progress
+ */
+struct MR_PRIV_DEVICE {
+	bool is_tm_capable;
+	bool tm_busy;
+};
 struct megasas_cmd;
 
 union megasas_evt_class_locale {
@@ -1700,6 +1989,19 @@ struct MR_DRV_SYSTEM_INFO {
 	u8	reserved[1980];
 };
 
+enum MR_PD_TYPE {
+		 UNKNOWN_DRIVE = 0,
+		 PARALLEL_SCSI = 1,
+		 SAS_PD = 2,
+		 SATA_PD = 3,
+		 FC_PD = 4,
+};
+
+/* JBOD Queue depth definitions */
+#define MEGASAS_SATA_QD	32
+#define MEGASAS_SAS_QD	64
+#define MEGASAS_DEFAULT_PD_QD	64
+
 struct megasas_instance {
 
 	__le32 *producer;
@@ -1714,6 +2016,8 @@ struct megasas_instance {
 	dma_addr_t vf_affiliation_111_h;
 	struct MR_CTRL_HB_HOST_MEM *hb_host_mem;
 	dma_addr_t hb_host_mem_h;
+	struct MR_PD_INFO *pd_info;
+	dma_addr_t pd_info_h;
 
 	__le32 *reply_queue;
 	dma_addr_t reply_queue_h;
@@ -1745,6 +2049,8 @@ struct megasas_instance {
 	u16 max_fw_cmds;
 	u16 max_mfi_cmds;
 	u16 max_scsi_cmds;
+	u16 ldio_threshold;
+	u16 cur_can_queue;
 	u32 max_sectors_per_req;
 	struct megasas_aen_event *ev;
 
@@ -1762,7 +2068,7 @@ struct megasas_instance {
 	struct megasas_evt_detail *evt_detail;
 	dma_addr_t evt_detail_h;
 	struct megasas_cmd *aen_cmd;
-	struct mutex aen_mutex;
+	struct mutex hba_mutex;
 	struct semaphore ioctl_sem;
 
 	struct Scsi_Host *host;
@@ -1775,6 +2081,7 @@ struct megasas_instance {
 	u32 fw_support_ieee;
 
 	atomic_t fw_outstanding;
+	atomic_t ldio_outstanding;
 	atomic_t fw_reset_no_pci_access;
 
 	struct megasas_instance_template *instancet;
@@ -1790,14 +2097,14 @@ struct megasas_instance {
 	u8 UnevenSpanSupport;
 
 	u8 supportmax256vd;
-	u8 allow_fw_scan;
+	u8 pd_list_not_supported;
 	u16 fw_supported_vd_count;
 	u16 fw_supported_pd_count;
 
 	u16 drv_supported_vd_count;
 	u16 drv_supported_pd_count;
 
-	u8 adprecovery;
+	atomic_t adprecovery;
 	unsigned long last_time;
 	u32 mfiStatus;
 	u32 last_seq_num;
@@ -1822,11 +2129,14 @@ struct megasas_instance {
 	char skip_heartbeat_timer_del;
 	u8 requestorId;
 	char PlasmaFW111;
-	char mpio;
+	char clusterId[MEGASAS_CLUSTER_ID_SIZE];
+	u8 peerIsPresent;
+	u8 passive;
 	u16 throttlequeuedepth;
 	u8 mask_interrupts;
 	u16 max_chain_frame_sz;
 	u8 is_imr;
+	u8 is_rdpq;
 	bool dev_handle;
 };
 struct MR_LD_VF_MAP {
@@ -1916,7 +2226,7 @@ struct megasas_instance_template {
 	u32 (*init_adapter)(struct megasas_instance *);
 	u32 (*build_and_issue_cmd) (struct megasas_instance *,
 				    struct scsi_cmnd *);
-	void (*issue_dcmd) (struct megasas_instance *instance,
+	int (*issue_dcmd)(struct megasas_instance *instance,
 			    struct megasas_cmd *cmd);
 };
 
@@ -2014,6 +2324,19 @@ struct megasas_mgmt_info {
 	int max_index;
 };
 
+enum MEGASAS_OCR_CAUSE {
+	FW_FAULT_OCR			= 0,
+	SCSIIO_TIMEOUT_OCR		= 1,
+	MFI_IO_TIMEOUT_OCR		= 2,
+};
+
+enum DCMD_RETURN_STATUS {
+	DCMD_SUCCESS		= 0,
+	DCMD_TIMEOUT		= 1,
+	DCMD_FAILED		= 2,
+	DCMD_NOT_FIRED		= 3,
+};
+
 u8
 MR_BuildRaidContext(struct megasas_instance *instance,
 		    struct IO_REQUEST_INFO *io_info,
@@ -2051,4 +2374,8 @@ void megasas_return_mfi_mpt_pthr(struct
 int megasas_cmd_type(struct scsi_cmnd *cmd);
 void megasas_setup_jbod_map(struct megasas_instance *instance);
 
+void megasas_update_sdev_properties(struct scsi_device *sdev);
+int megasas_reset_fusion(struct Scsi_Host *shost, int reason);
+int megasas_task_abort_fusion(struct scsi_cmnd *scmd);
+int megasas_reset_target_fusion(struct scsi_cmnd *scmd);
 #endif				/*LSI_MEGARAID_SAS_H */
--- zfcpdump-kernel-4.4.orig/drivers/scsi/megaraid/megaraid_sas_base.c
+++ zfcpdump-kernel-4.4/drivers/scsi/megaraid/megaraid_sas_base.c
@@ -83,7 +83,7 @@ module_param(throttlequeuedepth, int, S_
 MODULE_PARM_DESC(throttlequeuedepth,
 	"Adapter queue depth when throttled due to I/O timeout. Default: 16");
 
-int resetwaittime = MEGASAS_RESET_WAIT_TIME;
+unsigned int resetwaittime = MEGASAS_RESET_WAIT_TIME;
 module_param(resetwaittime, int, S_IRUGO);
 MODULE_PARM_DESC(resetwaittime, "Wait time in seconds after I/O timeout "
 		 "before resetting adapter. Default: 180");
@@ -92,6 +92,18 @@ int smp_affinity_enable = 1;
 module_param(smp_affinity_enable, int, S_IRUGO);
 MODULE_PARM_DESC(smp_affinity_enable, "SMP affinity feature enable/disbale Default: enable(1)");
 
+int rdpq_enable = 1;
+module_param(rdpq_enable, int, S_IRUGO);
+MODULE_PARM_DESC(rdpq_enable, " Allocate reply queue in chunks for large queue depth enable/disable Default: disable(0)");
+
+unsigned int dual_qdepth_disable;
+module_param(dual_qdepth_disable, int, S_IRUGO);
+MODULE_PARM_DESC(dual_qdepth_disable, "Disable dual queue depth feature. Default: 0");
+
+unsigned int scmd_timeout = MEGASAS_DEFAULT_CMD_TIMEOUT;
+module_param(scmd_timeout, int, S_IRUGO);
+MODULE_PARM_DESC(scmd_timeout, "scsi command timeout (10-90s), default 90s. See megasas_reset_timer.");
+
 MODULE_LICENSE("GPL");
 MODULE_VERSION(MEGASAS_VERSION);
 MODULE_AUTHOR("megaraidlinux.pdl@avagotech.com");
@@ -104,6 +116,8 @@ static int megasas_ld_list_query(struct
 static int megasas_issue_init_mfi(struct megasas_instance *instance);
 static int megasas_register_aen(struct megasas_instance *instance,
 				u32 seq_num, u32 class_locale_word);
+static int
+megasas_get_pd_info(struct megasas_instance *instance, u16 device_id);
 /*
  * PCI ID table for all supported controllers
  */
@@ -189,18 +203,18 @@ int
 wait_and_poll(struct megasas_instance *instance, struct megasas_cmd *cmd,
 	int seconds);
 void megasas_reset_reply_desc(struct megasas_instance *instance);
-int megasas_reset_fusion(struct Scsi_Host *shost, int iotimeout);
 void megasas_fusion_ocr_wq(struct work_struct *work);
 static int megasas_get_ld_vf_affiliation(struct megasas_instance *instance,
 					 int initial);
 int megasas_check_mpio_paths(struct megasas_instance *instance,
 			     struct scsi_cmnd *scmd);
 
-void
+int
 megasas_issue_dcmd(struct megasas_instance *instance, struct megasas_cmd *cmd)
 {
 	instance->instancet->fire_cmd(instance,
 		cmd->frame_phys_addr, 0, instance->reg_set);
+	return 0;
 }
 
 /**
@@ -473,7 +487,7 @@ static int
 megasas_check_reset_xscale(struct megasas_instance *instance,
 		struct megasas_register_set __iomem *regs)
 {
-	if ((instance->adprecovery != MEGASAS_HBA_OPERATIONAL) &&
+	if ((atomic_read(&instance->adprecovery) != MEGASAS_HBA_OPERATIONAL) &&
 	    (le32_to_cpu(*instance->consumer) ==
 		MEGASAS_ADPRESET_INPROG_SIGN))
 		return 1;
@@ -609,7 +623,7 @@ static int
 megasas_check_reset_ppc(struct megasas_instance *instance,
 			struct megasas_register_set __iomem *regs)
 {
-	if (instance->adprecovery != MEGASAS_HBA_OPERATIONAL)
+	if (atomic_read(&instance->adprecovery) != MEGASAS_HBA_OPERATIONAL)
 		return 1;
 
 	return 0;
@@ -735,6 +749,7 @@ megasas_fire_cmd_skinny(struct megasas_i
 	       &(regs)->inbound_high_queue_port);
 	writel((lower_32_bits(frame_phys_addr) | (frame_count<<1))|1,
 	       &(regs)->inbound_low_queue_port);
+	mmiowb();
 	spin_unlock_irqrestore(&instance->hba_lock, flags);
 }
 
@@ -746,7 +761,7 @@ static int
 megasas_check_reset_skinny(struct megasas_instance *instance,
 				struct megasas_register_set __iomem *regs)
 {
-	if (instance->adprecovery != MEGASAS_HBA_OPERATIONAL)
+	if (atomic_read(&instance->adprecovery) != MEGASAS_HBA_OPERATIONAL)
 		return 1;
 
 	return 0;
@@ -940,9 +955,8 @@ static int
 megasas_check_reset_gen2(struct megasas_instance *instance,
 		struct megasas_register_set __iomem *regs)
 {
-	if (instance->adprecovery != MEGASAS_HBA_OPERATIONAL) {
+	if (atomic_read(&instance->adprecovery) != MEGASAS_HBA_OPERATIONAL)
 		return 1;
-	}
 
 	return 0;
 }
@@ -983,25 +997,20 @@ extern struct megasas_instance_template
 int
 megasas_issue_polled(struct megasas_instance *instance, struct megasas_cmd *cmd)
 {
-	int seconds;
 	struct megasas_header *frame_hdr = &cmd->frame->hdr;
 
-	frame_hdr->cmd_status = MFI_CMD_STATUS_POLL_MODE;
+	frame_hdr->cmd_status = MFI_STAT_INVALID_STATUS;
 	frame_hdr->flags |= cpu_to_le16(MFI_FRAME_DONT_POST_IN_REPLY_QUEUE);
 
-	/*
-	 * Issue the frame using inbound queue port
-	 */
-	instance->instancet->issue_dcmd(instance, cmd);
+	if ((atomic_read(&instance->adprecovery) == MEGASAS_HW_CRITICAL_ERROR) ||
+		(instance->instancet->issue_dcmd(instance, cmd))) {
+		dev_err(&instance->pdev->dev, "Failed from %s %d\n",
+			__func__, __LINE__);
+		return DCMD_NOT_FIRED;
+	}
 
-	/*
-	 * Wait for cmd_status to change
-	 */
-	if (instance->requestorId)
-		seconds = MEGASAS_ROUTINE_WAIT_TIME_VF;
-	else
-		seconds = MFI_POLL_TIMEOUT_SECS;
-	return wait_and_poll(instance, cmd, seconds);
+	return wait_and_poll(instance, cmd, instance->requestorId ?
+			MEGASAS_ROUTINE_WAIT_TIME_VF : MFI_IO_TIMEOUT_SECS);
 }
 
 /**
@@ -1019,21 +1028,29 @@ megasas_issue_blocked_cmd(struct megasas
 			  struct megasas_cmd *cmd, int timeout)
 {
 	int ret = 0;
-
 	cmd->cmd_status_drv = MFI_STAT_INVALID_STATUS;
 
-	instance->instancet->issue_dcmd(instance, cmd);
+	if ((atomic_read(&instance->adprecovery) == MEGASAS_HW_CRITICAL_ERROR) ||
+		(instance->instancet->issue_dcmd(instance, cmd))) {
+		dev_err(&instance->pdev->dev, "Failed from %s %d\n",
+			__func__, __LINE__);
+		return DCMD_NOT_FIRED;
+	}
+
 	if (timeout) {
 		ret = wait_event_timeout(instance->int_cmd_wait_q,
 				cmd->cmd_status_drv != MFI_STAT_INVALID_STATUS, timeout * HZ);
-		if (!ret)
-			return 1;
+		if (!ret) {
+			dev_err(&instance->pdev->dev, "Failed from %s %d DCMD Timed out\n",
+				__func__, __LINE__);
+			return DCMD_TIMEOUT;
+		}
 	} else
 		wait_event(instance->int_cmd_wait_q,
 				cmd->cmd_status_drv != MFI_STAT_INVALID_STATUS);
 
 	return (cmd->cmd_status_drv == MFI_STAT_OK) ?
-		0 : 1;
+		DCMD_SUCCESS : DCMD_FAILED;
 }
 
 /**
@@ -1077,15 +1094,20 @@ megasas_issue_blocked_abort_cmd(struct m
 	cmd->sync_cmd = 1;
 	cmd->cmd_status_drv = MFI_STAT_INVALID_STATUS;
 
-	instance->instancet->issue_dcmd(instance, cmd);
+	if ((atomic_read(&instance->adprecovery) == MEGASAS_HW_CRITICAL_ERROR) ||
+		(instance->instancet->issue_dcmd(instance, cmd))) {
+		dev_err(&instance->pdev->dev, "Failed from %s %d\n",
+			__func__, __LINE__);
+		return DCMD_NOT_FIRED;
+	}
 
 	if (timeout) {
 		ret = wait_event_timeout(instance->abort_cmd_wait_q,
 				cmd->cmd_status_drv != MFI_STAT_INVALID_STATUS, timeout * HZ);
 		if (!ret) {
-			dev_err(&instance->pdev->dev, "Command timedout"
-				"from %s\n", __func__);
-			return 1;
+			dev_err(&instance->pdev->dev, "Failed from %s %d Abort Timed out\n",
+				__func__, __LINE__);
+			return DCMD_TIMEOUT;
 		}
 	} else
 		wait_event(instance->abort_cmd_wait_q,
@@ -1094,7 +1116,8 @@ megasas_issue_blocked_abort_cmd(struct m
 	cmd->sync_cmd = 0;
 
 	megasas_return_cmd(instance, cmd);
-	return 0;
+	return (cmd->cmd_status_drv == MFI_STAT_OK) ?
+		DCMD_SUCCESS : DCMD_FAILED;
 }
 
 /**
@@ -1621,7 +1644,7 @@ megasas_build_and_issue_cmd(struct megas
 	return 0;
 out_return_cmd:
 	megasas_return_cmd(instance, cmd);
-	return 1;
+	return SCSI_MLQUEUE_HOST_BUSY;
 }
 
 
@@ -1634,7 +1657,7 @@ static int
 megasas_queue_command(struct Scsi_Host *shost, struct scsi_cmnd *scmd)
 {
 	struct megasas_instance *instance;
-	unsigned long flags;
+	struct MR_PRIV_DEVICE *mr_device_priv_data;
 
 	instance = (struct megasas_instance *)
 	    scmd->device->host->hostdata;
@@ -1648,35 +1671,38 @@ megasas_queue_command(struct Scsi_Host *
 	if (instance->issuepend_done == 0)
 		return SCSI_MLQUEUE_HOST_BUSY;
 
-	spin_lock_irqsave(&instance->hba_lock, flags);
 
 	/* Check for an mpio path and adjust behavior */
-	if (instance->adprecovery == MEGASAS_ADPRESET_SM_INFAULT) {
+	if (atomic_read(&instance->adprecovery) == MEGASAS_ADPRESET_SM_INFAULT) {
 		if (megasas_check_mpio_paths(instance, scmd) ==
 		    (DID_RESET << 16)) {
-			spin_unlock_irqrestore(&instance->hba_lock, flags);
 			return SCSI_MLQUEUE_HOST_BUSY;
 		} else {
-			spin_unlock_irqrestore(&instance->hba_lock, flags);
 			scmd->result = DID_NO_CONNECT << 16;
 			scmd->scsi_done(scmd);
 			return 0;
 		}
 	}
 
-	if (instance->adprecovery == MEGASAS_HW_CRITICAL_ERROR) {
-		spin_unlock_irqrestore(&instance->hba_lock, flags);
+	if (atomic_read(&instance->adprecovery) == MEGASAS_HW_CRITICAL_ERROR) {
 		scmd->result = DID_NO_CONNECT << 16;
 		scmd->scsi_done(scmd);
 		return 0;
 	}
 
-	if (instance->adprecovery != MEGASAS_HBA_OPERATIONAL) {
-		spin_unlock_irqrestore(&instance->hba_lock, flags);
-		return SCSI_MLQUEUE_HOST_BUSY;
+	mr_device_priv_data = scmd->device->hostdata;
+	if (!mr_device_priv_data) {
+		scmd->result = DID_NO_CONNECT << 16;
+		scmd->scsi_done(scmd);
+		return 0;
 	}
 
-	spin_unlock_irqrestore(&instance->hba_lock, flags);
+	if (atomic_read(&instance->adprecovery) != MEGASAS_HBA_OPERATIONAL)
+		return SCSI_MLQUEUE_HOST_BUSY;
+
+	if (mr_device_priv_data->tm_busy)
+		return SCSI_MLQUEUE_DEVICE_BUSY;
+
 
 	scmd->result = 0;
 
@@ -1699,12 +1725,7 @@ megasas_queue_command(struct Scsi_Host *
 		break;
 	}
 
-	if (instance->instancet->build_and_issue_cmd(instance, scmd)) {
-		dev_err(&instance->pdev->dev, "Err returned from build_and_issue_cmd\n");
-		return SCSI_MLQUEUE_HOST_BUSY;
-	}
-
-	return 0;
+	return instance->instancet->build_and_issue_cmd(instance, scmd);
 
  out_done:
 	scmd->scsi_done(scmd);
@@ -1726,27 +1747,39 @@ static struct megasas_instance *megasas_
 }
 
 /*
-* megasas_set_dma_alignment - Set DMA alignment for PI enabled VD
+* megasas_update_sdev_properties - Update sdev structure based on controller's FW capabilities
 *
 * @sdev: OS provided scsi device
 *
 * Returns void
 */
-static void megasas_set_dma_alignment(struct scsi_device *sdev)
+void megasas_update_sdev_properties(struct scsi_device *sdev)
 {
+	u16 pd_index = 0;
 	u32 device_id, ld;
 	struct megasas_instance *instance;
 	struct fusion_context *fusion;
+	struct MR_PRIV_DEVICE *mr_device_priv_data;
+	struct MR_PD_CFG_SEQ_NUM_SYNC *pd_sync;
 	struct MR_LD_RAID *raid;
 	struct MR_DRV_RAID_MAP_ALL *local_map_ptr;
 
 	instance = megasas_lookup_instance(sdev->host->host_no);
 	fusion = instance->ctrl_context;
+	mr_device_priv_data = sdev->hostdata;
 
 	if (!fusion)
 		return;
 
-	if (sdev->channel >= MEGASAS_MAX_PD_CHANNELS) {
+	if (sdev->channel < MEGASAS_MAX_PD_CHANNELS &&
+		instance->use_seqnum_jbod_fp) {
+		pd_index = (sdev->channel * MEGASAS_MAX_DEV_PER_CHANNEL) +
+			sdev->id;
+		pd_sync = (void *)fusion->pd_seq_sync
+				[(instance->pd_seq_map_id - 1) & 1];
+		mr_device_priv_data->is_tm_capable =
+			pd_sync->seq[pd_index].capability.tmCapable;
+	} else {
 		device_id = ((sdev->channel % 2) * MEGASAS_MAX_DEV_PER_CHANNEL)
 					+ sdev->id;
 		local_map_ptr = fusion->ld_drv_map[(instance->map_id & 1)];
@@ -1754,17 +1787,58 @@ static void megasas_set_dma_alignment(st
 		raid = MR_LdRaidGet(ld, local_map_ptr);
 
 		if (raid->capability.ldPiMode == MR_PROT_INFO_TYPE_CONTROLLER)
-			blk_queue_update_dma_alignment(sdev->request_queue, 0x7);
+		blk_queue_update_dma_alignment(sdev->request_queue, 0x7);
+		mr_device_priv_data->is_tm_capable =
+			raid->capability.tmCapable;
+	}
+}
+
+static void megasas_set_device_queue_depth(struct scsi_device *sdev)
+{
+	u16				pd_index = 0;
+	int		ret = DCMD_FAILED;
+	struct megasas_instance *instance;
+
+	instance = megasas_lookup_instance(sdev->host->host_no);
+
+	if (sdev->channel < MEGASAS_MAX_PD_CHANNELS) {
+		pd_index = (sdev->channel * MEGASAS_MAX_DEV_PER_CHANNEL) + sdev->id;
+
+		if (instance->pd_info) {
+			mutex_lock(&instance->hba_mutex);
+			ret = megasas_get_pd_info(instance, pd_index);
+			mutex_unlock(&instance->hba_mutex);
+		}
+
+		if (ret != DCMD_SUCCESS)
+			return;
+
+		if (instance->pd_list[pd_index].driveState == MR_PD_STATE_SYSTEM) {
+
+			switch (instance->pd_list[pd_index].interface) {
+			case SAS_PD:
+				scsi_change_queue_depth(sdev, MEGASAS_SAS_QD);
+				break;
+
+			case SATA_PD:
+				scsi_change_queue_depth(sdev, MEGASAS_SATA_QD);
+				break;
+
+			default:
+				scsi_change_queue_depth(sdev, MEGASAS_DEFAULT_PD_QD);
+			}
+		}
 	}
 }
 
+
 static int megasas_slave_configure(struct scsi_device *sdev)
 {
 	u16 pd_index = 0;
 	struct megasas_instance *instance;
 
 	instance = megasas_lookup_instance(sdev->host->host_no);
-	if (instance->allow_fw_scan) {
+	if (instance->pd_list_not_supported) {
 		if (sdev->channel < MEGASAS_MAX_PD_CHANNELS &&
 			sdev->type == TYPE_DISK) {
 			pd_index = (sdev->channel * MEGASAS_MAX_DEV_PER_CHANNEL) +
@@ -1774,12 +1848,14 @@ static int megasas_slave_configure(struc
 				return -ENXIO;
 		}
 	}
-	megasas_set_dma_alignment(sdev);
+	megasas_set_device_queue_depth(sdev);
+	megasas_update_sdev_properties(sdev);
+
 	/*
 	 * The RAID firmware may require extended timeouts.
 	 */
 	blk_queue_rq_timeout(sdev->request_queue,
-		MEGASAS_DEFAULT_CMD_TIMEOUT * HZ);
+		scmd_timeout * HZ);
 
 	return 0;
 }
@@ -1788,6 +1864,7 @@ static int megasas_slave_alloc(struct sc
 {
 	u16 pd_index = 0;
 	struct megasas_instance *instance ;
+	struct MR_PRIV_DEVICE *mr_device_priv_data;
 
 	instance = megasas_lookup_instance(sdev->host->host_no);
 	if (sdev->channel < MEGASAS_MAX_PD_CHANNELS) {
@@ -1797,15 +1874,29 @@ static int megasas_slave_alloc(struct sc
 		pd_index =
 			(sdev->channel * MEGASAS_MAX_DEV_PER_CHANNEL) +
 			sdev->id;
-		if ((instance->allow_fw_scan || instance->pd_list[pd_index].driveState ==
+		if ((instance->pd_list_not_supported ||
+			instance->pd_list[pd_index].driveState ==
 			MR_PD_STATE_SYSTEM)) {
-			return 0;
+			goto scan_target;
 		}
 		return -ENXIO;
 	}
+
+scan_target:
+	mr_device_priv_data = kzalloc(sizeof(*mr_device_priv_data),
+					GFP_KERNEL);
+	if (!mr_device_priv_data)
+		return -ENOMEM;
+	sdev->hostdata = mr_device_priv_data;
 	return 0;
 }
 
+static void megasas_slave_destroy(struct scsi_device *sdev)
+{
+	kfree(sdev->hostdata);
+	sdev->hostdata = NULL;
+}
+
 /*
 * megasas_complete_outstanding_ioctls - Complete outstanding ioctls after a
 *                                       kill adapter
@@ -1845,7 +1936,7 @@ static void megasas_complete_outstanding
 void megaraid_sas_kill_hba(struct megasas_instance *instance)
 {
 	/* Set critical error to block I/O & ioctls in case caller didn't */
-	instance->adprecovery = MEGASAS_HW_CRITICAL_ERROR;
+	atomic_set(&instance->adprecovery, MEGASAS_HW_CRITICAL_ERROR);
 	/* Wait 1 second to ensure IO or ioctls in build have posted */
 	msleep(1000);
 	if ((instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
@@ -1854,7 +1945,7 @@ void megaraid_sas_kill_hba(struct megasa
 		writel(MFI_STOP_ADP, &instance->reg_set->doorbell);
 		/* Flush */
 		readl(&instance->reg_set->doorbell);
-		if (instance->mpio && instance->requestorId)
+		if (instance->requestorId && instance->peerIsPresent)
 			memset(instance->ld_ids, 0xff, MEGASAS_MAX_LD_IDS);
 	} else {
 		writel(MFI_STOP_ADP,
@@ -1883,7 +1974,7 @@ megasas_check_and_restore_queue_depth(st
 		spin_lock_irqsave(instance->host->host_lock, flags);
 		instance->flag &= ~MEGASAS_FW_BUSY;
 
-		instance->host->can_queue = instance->max_scsi_cmds;
+		instance->host->can_queue = instance->cur_can_queue;
 		spin_unlock_irqrestore(instance->host->host_lock, flags);
 	}
 }
@@ -1905,7 +1996,7 @@ static void megasas_complete_cmd_dpc(uns
 	unsigned long flags;
 
 	/* If we have already declared adapter dead, donot complete cmds */
-	if (instance->adprecovery == MEGASAS_HW_CRITICAL_ERROR)
+	if (atomic_read(&instance->adprecovery) == MEGASAS_HW_CRITICAL_ERROR)
 		return;
 
 	spin_lock_irqsave(&instance->completion_lock, flags);
@@ -1974,7 +2065,7 @@ void megasas_do_ocr(struct megasas_insta
 		*instance->consumer = cpu_to_le32(MEGASAS_ADPRESET_INPROG_SIGN);
 	}
 	instance->instancet->disable_intr(instance);
-	instance->adprecovery   = MEGASAS_ADPRESET_SM_INFAULT;
+	atomic_set(&instance->adprecovery, MEGASAS_ADPRESET_SM_INFAULT);
 	instance->issuepend_done = 0;
 
 	atomic_set(&instance->fw_outstanding, 0);
@@ -2054,9 +2145,7 @@ static int megasas_get_ld_vf_affiliation
 	dev_warn(&instance->pdev->dev, "SR-IOV: Getting LD/VF affiliation for "
 	       "scsi%d\n", instance->host->host_no);
 
-	megasas_issue_blocked_cmd(instance, cmd, 0);
-
-	if (dcmd->cmd_status) {
+	if (megasas_issue_blocked_cmd(instance, cmd, 0) != DCMD_SUCCESS) {
 		dev_warn(&instance->pdev->dev, "SR-IOV: LD/VF affiliation DCMD"
 		       " failed with status 0x%x for scsi%d\n",
 		       dcmd->cmd_status, instance->host->host_no);
@@ -2166,9 +2255,8 @@ static int megasas_get_ld_vf_affiliation
 	dev_warn(&instance->pdev->dev, "SR-IOV: Getting LD/VF affiliation for "
 	       "scsi%d\n", instance->host->host_no);
 
-	megasas_issue_blocked_cmd(instance, cmd, 0);
 
-	if (dcmd->cmd_status) {
+	if (megasas_issue_blocked_cmd(instance, cmd, 0) != DCMD_SUCCESS) {
 		dev_warn(&instance->pdev->dev, "SR-IOV: LD/VF affiliation DCMD"
 		       " failed with status 0x%x for scsi%d\n",
 		       dcmd->cmd_status, instance->host->host_no);
@@ -2373,21 +2461,21 @@ void megasas_sriov_heartbeat_handler(uns
  */
 static int megasas_wait_for_outstanding(struct megasas_instance *instance)
 {
-	int i;
+	int i, sl, outstanding;
 	u32 reset_index;
 	u32 wait_time = MEGASAS_RESET_WAIT_TIME;
-	u8 adprecovery;
 	unsigned long flags;
 	struct list_head clist_local;
 	struct megasas_cmd *reset_cmd;
 	u32 fw_state;
-	u8 kill_adapter_flag;
 
-	spin_lock_irqsave(&instance->hba_lock, flags);
-	adprecovery = instance->adprecovery;
-	spin_unlock_irqrestore(&instance->hba_lock, flags);
+	if (atomic_read(&instance->adprecovery) == MEGASAS_HW_CRITICAL_ERROR) {
+		dev_info(&instance->pdev->dev, "%s:%d HBA is killed.\n",
+		__func__, __LINE__);
+		return FAILED;
+	}
 
-	if (adprecovery != MEGASAS_HBA_OPERATIONAL) {
+	if (atomic_read(&instance->adprecovery) != MEGASAS_HBA_OPERATIONAL) {
 
 		INIT_LIST_HEAD(&clist_local);
 		spin_lock_irqsave(&instance->hba_lock, flags);
@@ -2398,18 +2486,13 @@ static int megasas_wait_for_outstanding(
 		dev_notice(&instance->pdev->dev, "HBA reset wait ...\n");
 		for (i = 0; i < wait_time; i++) {
 			msleep(1000);
-			spin_lock_irqsave(&instance->hba_lock, flags);
-			adprecovery = instance->adprecovery;
-			spin_unlock_irqrestore(&instance->hba_lock, flags);
-			if (adprecovery == MEGASAS_HBA_OPERATIONAL)
+			if (atomic_read(&instance->adprecovery) == MEGASAS_HBA_OPERATIONAL)
 				break;
 		}
 
-		if (adprecovery != MEGASAS_HBA_OPERATIONAL) {
+		if (atomic_read(&instance->adprecovery) != MEGASAS_HBA_OPERATIONAL) {
 			dev_notice(&instance->pdev->dev, "reset: Stopping HBA.\n");
-			spin_lock_irqsave(&instance->hba_lock, flags);
-			instance->adprecovery = MEGASAS_HW_CRITICAL_ERROR;
-			spin_unlock_irqrestore(&instance->hba_lock, flags);
+			atomic_set(&instance->adprecovery, MEGASAS_HW_CRITICAL_ERROR);
 			return FAILED;
 		}
 
@@ -2447,7 +2530,7 @@ static int megasas_wait_for_outstanding(
 	}
 
 	for (i = 0; i < resetwaittime; i++) {
-		int outstanding = atomic_read(&instance->fw_outstanding);
+		outstanding = atomic_read(&instance->fw_outstanding);
 
 		if (!outstanding)
 			break;
@@ -2466,67 +2549,60 @@ static int megasas_wait_for_outstanding(
 	}
 
 	i = 0;
-	kill_adapter_flag = 0;
+	outstanding = atomic_read(&instance->fw_outstanding);
+	fw_state = instance->instancet->read_fw_status_reg(instance->reg_set) & MFI_STATE_MASK;
+
+	if ((!outstanding && (fw_state == MFI_STATE_OPERATIONAL)))
+		goto no_outstanding;
+
+	if (instance->disableOnlineCtrlReset)
+		goto kill_hba_and_failed;
 	do {
-		fw_state = instance->instancet->read_fw_status_reg(
-					instance->reg_set) & MFI_STATE_MASK;
-		if ((fw_state == MFI_STATE_FAULT) &&
-			(instance->disableOnlineCtrlReset == 0)) {
-			if (i == 3) {
-				kill_adapter_flag = 2;
-				break;
-			}
+		if ((fw_state == MFI_STATE_FAULT) || atomic_read(&instance->fw_outstanding)) {
+			dev_info(&instance->pdev->dev,
+				"%s:%d waiting_for_outstanding: before issue OCR. FW state = 0x%x, oustanding 0x%x\n",
+				__func__, __LINE__, fw_state, atomic_read(&instance->fw_outstanding));
+			if (i == 3)
+				goto kill_hba_and_failed;
 			megasas_do_ocr(instance);
-			kill_adapter_flag = 1;
 
-			/* wait for 1 secs to let FW finish the pending cmds */
-			msleep(1000);
+			if (atomic_read(&instance->adprecovery) == MEGASAS_HW_CRITICAL_ERROR) {
+				dev_info(&instance->pdev->dev, "%s:%d OCR failed and HBA is killed.\n",
+				__func__, __LINE__);
+				return FAILED;
+			}
+			dev_info(&instance->pdev->dev, "%s:%d waiting_for_outstanding: after issue OCR.\n",
+				__func__, __LINE__);
+
+			for (sl = 0; sl < 10; sl++)
+				msleep(500);
+
+			outstanding = atomic_read(&instance->fw_outstanding);
+
+			fw_state = instance->instancet->read_fw_status_reg(instance->reg_set) & MFI_STATE_MASK;
+			if ((!outstanding && (fw_state == MFI_STATE_OPERATIONAL)))
+				goto no_outstanding;
 		}
 		i++;
 	} while (i <= 3);
 
-	if (atomic_read(&instance->fw_outstanding) && !kill_adapter_flag) {
-		if (instance->disableOnlineCtrlReset == 0) {
-			megasas_do_ocr(instance);
+no_outstanding:
 
-			/* wait for 5 secs to let FW finish the pending cmds */
-			for (i = 0; i < wait_time; i++) {
-				int outstanding =
-					atomic_read(&instance->fw_outstanding);
-				if (!outstanding)
-					return SUCCESS;
-				msleep(1000);
-			}
-		}
-	}
+	dev_info(&instance->pdev->dev, "%s:%d no more pending commands remain after reset handling.\n",
+		__func__, __LINE__);
+	return SUCCESS;
 
-	if (atomic_read(&instance->fw_outstanding) ||
-					(kill_adapter_flag == 2)) {
-		dev_notice(&instance->pdev->dev, "pending cmds after reset\n");
-		/*
-		 * Send signal to FW to stop processing any pending cmds.
-		 * The controller will be taken offline by the OS now.
-		 */
-		if ((instance->pdev->device ==
-			PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
-			(instance->pdev->device ==
-			PCI_DEVICE_ID_LSI_SAS0071SKINNY)) {
-			writel(MFI_STOP_ADP,
-				&instance->reg_set->doorbell);
-		} else {
-			writel(MFI_STOP_ADP,
-				&instance->reg_set->inbound_doorbell);
-		}
-		megasas_dump_pending_frames(instance);
-		spin_lock_irqsave(&instance->hba_lock, flags);
-		instance->adprecovery = MEGASAS_HW_CRITICAL_ERROR;
-		spin_unlock_irqrestore(&instance->hba_lock, flags);
-		return FAILED;
-	}
+kill_hba_and_failed:
 
-	dev_notice(&instance->pdev->dev, "no pending cmds after reset\n");
+	/* Reset not supported, kill adapter */
+	dev_info(&instance->pdev->dev, "%s:%d killing adapter scsi%d"
+		" disableOnlineCtrlReset %d fw_outstanding %d \n",
+		__func__, __LINE__, instance->host->host_no, instance->disableOnlineCtrlReset,
+		atomic_read(&instance->fw_outstanding));
+	megasas_dump_pending_frames(instance);
+	megaraid_sas_kill_hba(instance);
 
-	return SUCCESS;
+	return FAILED;
 }
 
 /**
@@ -2547,7 +2623,7 @@ static int megasas_generic_reset(struct
 	scmd_printk(KERN_NOTICE, scmd, "megasas: RESET cmd=%x retries=%x\n",
 		 scmd->cmnd[0], scmd->retries);
 
-	if (instance->adprecovery == MEGASAS_HW_CRITICAL_ERROR) {
+	if (atomic_read(&instance->adprecovery) == MEGASAS_HW_CRITICAL_ERROR) {
 		dev_err(&instance->pdev->dev, "cannot recover from previous reset failures\n");
 		return FAILED;
 	}
@@ -2575,7 +2651,7 @@ blk_eh_timer_return megasas_reset_timer(
 	unsigned long flags;
 
 	if (time_after(jiffies, scmd->jiffies_at_alloc +
-				(MEGASAS_DEFAULT_CMD_TIMEOUT * 2) * HZ)) {
+				(scmd_timeout * 2) * HZ)) {
 		return BLK_EH_NOT_HANDLED;
 	}
 
@@ -2851,6 +2927,16 @@ megasas_page_size_show(struct device *cd
 	return snprintf(buf, PAGE_SIZE, "%ld\n", (unsigned long)PAGE_SIZE - 1);
 }
 
+static ssize_t
+megasas_ldio_outstanding_show(struct device *cdev, struct device_attribute *attr,
+	char *buf)
+{
+	struct Scsi_Host *shost = class_to_shost(cdev);
+	struct megasas_instance *instance = (struct megasas_instance *)shost->hostdata;
+
+	return snprintf(buf, PAGE_SIZE, "%d\n", atomic_read(&instance->ldio_outstanding));
+}
+
 static DEVICE_ATTR(fw_crash_buffer, S_IRUGO | S_IWUSR,
 	megasas_fw_crash_buffer_show, megasas_fw_crash_buffer_store);
 static DEVICE_ATTR(fw_crash_buffer_size, S_IRUGO,
@@ -2859,12 +2945,15 @@ static DEVICE_ATTR(fw_crash_state, S_IRU
 	megasas_fw_crash_state_show, megasas_fw_crash_state_store);
 static DEVICE_ATTR(page_size, S_IRUGO,
 	megasas_page_size_show, NULL);
+static DEVICE_ATTR(ldio_outstanding, S_IRUGO,
+	megasas_ldio_outstanding_show, NULL);
 
 struct device_attribute *megaraid_host_attrs[] = {
 	&dev_attr_fw_crash_buffer_size,
 	&dev_attr_fw_crash_buffer,
 	&dev_attr_fw_crash_state,
 	&dev_attr_page_size,
+	&dev_attr_ldio_outstanding,
 	NULL,
 };
 
@@ -2878,6 +2967,7 @@ static struct scsi_host_template megasas
 	.proc_name = "megaraid_sas",
 	.slave_configure = megasas_slave_configure,
 	.slave_alloc = megasas_slave_alloc,
+	.slave_destroy = megasas_slave_destroy,
 	.queuecommand = megasas_queue_command,
 	.eh_device_reset_handler = megasas_reset_device,
 	.eh_bus_reset_handler = megasas_reset_bus_host,
@@ -3277,13 +3367,13 @@ process_fw_state_change_wq(struct work_s
 	u32 wait;
 	unsigned long flags;
 
-	if (instance->adprecovery != MEGASAS_ADPRESET_SM_INFAULT) {
+    if (atomic_read(&instance->adprecovery) != MEGASAS_ADPRESET_SM_INFAULT) {
 		dev_notice(&instance->pdev->dev, "error, recovery st %x\n",
-				instance->adprecovery);
+				atomic_read(&instance->adprecovery));
 		return ;
 	}
 
-	if (instance->adprecovery == MEGASAS_ADPRESET_SM_INFAULT) {
+	if (atomic_read(&instance->adprecovery) == MEGASAS_ADPRESET_SM_INFAULT) {
 		dev_notice(&instance->pdev->dev, "FW detected to be in fault"
 					"state, restarting it...\n");
 
@@ -3326,7 +3416,7 @@ process_fw_state_change_wq(struct work_s
 		megasas_issue_init_mfi(instance);
 
 		spin_lock_irqsave(&instance->hba_lock, flags);
-		instance->adprecovery	= MEGASAS_HBA_OPERATIONAL;
+		atomic_set(&instance->adprecovery, MEGASAS_HBA_OPERATIONAL);
 		spin_unlock_irqrestore(&instance->hba_lock, flags);
 		instance->instancet->enable_intr(instance);
 
@@ -3391,14 +3481,14 @@ megasas_deplete_reply_queue(struct megas
 
 
 			instance->instancet->disable_intr(instance);
-			instance->adprecovery	= MEGASAS_ADPRESET_SM_INFAULT;
+			atomic_set(&instance->adprecovery, MEGASAS_ADPRESET_SM_INFAULT);
 			instance->issuepend_done = 0;
 
 			atomic_set(&instance->fw_outstanding, 0);
 			megasas_internal_reset_defer_cmds(instance);
 
 			dev_notice(&instance->pdev->dev, "fwState=%x, stage:%d\n",
-					fw_state, instance->adprecovery);
+					fw_state, atomic_read(&instance->adprecovery));
 
 			schedule_work(&instance->work_init);
 			return IRQ_HANDLED;
@@ -3852,6 +3942,92 @@ int megasas_alloc_cmds(struct megasas_in
 }
 
 /*
+ * dcmd_timeout_ocr_possible -	Check if OCR is possible based on Driver/FW state.
+ * @instance:				Adapter soft state
+ *
+ * Return 0 for only Fusion adapter, if driver load/unload is not in progress
+ * or FW is not under OCR.
+ */
+inline int
+dcmd_timeout_ocr_possible(struct megasas_instance *instance) {
+
+	if (!instance->ctrl_context)
+		return KILL_ADAPTER;
+	else if (instance->unload ||
+			test_bit(MEGASAS_FUSION_IN_RESET, &instance->reset_flags))
+		return IGNORE_TIMEOUT;
+	else
+		return INITIATE_OCR;
+}
+
+static int
+megasas_get_pd_info(struct megasas_instance *instance, u16 device_id)
+{
+	int ret;
+	struct megasas_cmd *cmd;
+	struct megasas_dcmd_frame *dcmd;
+
+	cmd = megasas_get_cmd(instance);
+
+	if (!cmd) {
+		dev_err(&instance->pdev->dev, "Failed to get cmd %s\n", __func__);
+		return -ENOMEM;
+	}
+
+	dcmd = &cmd->frame->dcmd;
+
+	memset(instance->pd_info, 0, sizeof(*instance->pd_info));
+	memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE);
+
+	dcmd->mbox.s[0] = cpu_to_le16(device_id);
+	dcmd->cmd = MFI_CMD_DCMD;
+	dcmd->cmd_status = 0xFF;
+	dcmd->sge_count = 1;
+	dcmd->flags = cpu_to_le16(MFI_FRAME_DIR_READ);
+	dcmd->timeout = 0;
+	dcmd->pad_0 = 0;
+	dcmd->data_xfer_len = cpu_to_le32(sizeof(struct MR_PD_INFO));
+	dcmd->opcode = cpu_to_le32(MR_DCMD_PD_GET_INFO);
+	dcmd->sgl.sge32[0].phys_addr = cpu_to_le32(instance->pd_info_h);
+	dcmd->sgl.sge32[0].length = cpu_to_le32(sizeof(struct MR_PD_INFO));
+
+	if (instance->ctrl_context && !instance->mask_interrupts)
+		ret = megasas_issue_blocked_cmd(instance, cmd, MFI_IO_TIMEOUT_SECS);
+	else
+		ret = megasas_issue_polled(instance, cmd);
+
+	switch (ret) {
+	case DCMD_SUCCESS:
+		instance->pd_list[device_id].interface =
+				instance->pd_info->state.ddf.pdType.intf;
+		break;
+
+	case DCMD_TIMEOUT:
+
+		switch (dcmd_timeout_ocr_possible(instance)) {
+		case INITIATE_OCR:
+			cmd->flags |= DRV_DCMD_SKIP_REFIRE;
+			megasas_reset_fusion(instance->host,
+				MFI_IO_TIMEOUT_OCR);
+			break;
+		case KILL_ADAPTER:
+			megaraid_sas_kill_hba(instance);
+			break;
+		case IGNORE_TIMEOUT:
+			dev_info(&instance->pdev->dev, "Ignore DCMD timeout: %s %d\n",
+				__func__, __LINE__);
+			break;
+		}
+
+		break;
+	}
+
+	if (ret != DCMD_TIMEOUT)
+		megasas_return_cmd(instance, cmd);
+
+	return ret;
+}
+/*
  * megasas_get_pd_list_info -	Returns FW's pd_list structure
  * @instance:				Adapter soft state
  * @pd_list:				pd_list structure
@@ -3906,42 +4082,78 @@ megasas_get_pd_list(struct megasas_insta
 
 	if (instance->ctrl_context && !instance->mask_interrupts)
 		ret = megasas_issue_blocked_cmd(instance, cmd,
-			MEGASAS_BLOCKED_CMD_TIMEOUT);
+			MFI_IO_TIMEOUT_SECS);
 	else
 		ret = megasas_issue_polled(instance, cmd);
 
-	/*
-	 * the following function will get the instance PD LIST.
-	 */
+	switch (ret) {
+	case DCMD_FAILED:
+		dev_info(&instance->pdev->dev, "MR_DCMD_PD_LIST_QUERY "
+			"failed/not supported by firmware\n");
+
+		if (instance->ctrl_context)
+			megaraid_sas_kill_hba(instance);
+		else
+			instance->pd_list_not_supported = 1;
+		break;
+	case DCMD_TIMEOUT:
+
+		switch (dcmd_timeout_ocr_possible(instance)) {
+		case INITIATE_OCR:
+			cmd->flags |= DRV_DCMD_SKIP_REFIRE;
+			/*
+			 * DCMD failed from AEN path.
+			 * AEN path already hold reset_mutex to avoid PCI access
+			 * while OCR is in progress.
+			 */
+			mutex_unlock(&instance->reset_mutex);
+			megasas_reset_fusion(instance->host,
+						MFI_IO_TIMEOUT_OCR);
+			mutex_lock(&instance->reset_mutex);
+			break;
+		case KILL_ADAPTER:
+			megaraid_sas_kill_hba(instance);
+			break;
+		case IGNORE_TIMEOUT:
+			dev_info(&instance->pdev->dev, "Ignore DCMD timeout: %s %d \n",
+				__func__, __LINE__);
+			break;
+		}
+
+		break;
 
-	pd_addr = ci->addr;
+	case DCMD_SUCCESS:
+		pd_addr = ci->addr;
 
-	if (ret == 0 &&
-	     (le32_to_cpu(ci->count) <
-		  (MEGASAS_MAX_PD_CHANNELS * MEGASAS_MAX_DEV_PER_CHANNEL))) {
+		if ((le32_to_cpu(ci->count) >
+			(MEGASAS_MAX_PD_CHANNELS * MEGASAS_MAX_DEV_PER_CHANNEL)))
+			break;
 
 		memset(instance->local_pd_list, 0,
-			MEGASAS_MAX_PD * sizeof(struct megasas_pd_list));
+				MEGASAS_MAX_PD * sizeof(struct megasas_pd_list));
 
 		for (pd_index = 0; pd_index < le32_to_cpu(ci->count); pd_index++) {
-
 			instance->local_pd_list[le16_to_cpu(pd_addr->deviceId)].tid	=
-				le16_to_cpu(pd_addr->deviceId);
+					le16_to_cpu(pd_addr->deviceId);
 			instance->local_pd_list[le16_to_cpu(pd_addr->deviceId)].driveType	=
-							pd_addr->scsiDevType;
+					pd_addr->scsiDevType;
 			instance->local_pd_list[le16_to_cpu(pd_addr->deviceId)].driveState	=
-							MR_PD_STATE_SYSTEM;
+					MR_PD_STATE_SYSTEM;
 			pd_addr++;
 		}
+
 		memcpy(instance->pd_list, instance->local_pd_list,
 			sizeof(instance->pd_list));
+		break;
+
 	}
 
 	pci_free_consistent(instance->pdev,
 				MEGASAS_MAX_PD * sizeof(struct MR_PD_LIST),
 				ci, ci_h);
 
-	megasas_return_cmd(instance, cmd);
+	if (ret != DCMD_TIMEOUT)
+		megasas_return_cmd(instance, cmd);
 
 	return ret;
 }
@@ -4002,33 +4214,63 @@ megasas_get_ld_list(struct megasas_insta
 
 	if (instance->ctrl_context && !instance->mask_interrupts)
 		ret = megasas_issue_blocked_cmd(instance, cmd,
-			MEGASAS_BLOCKED_CMD_TIMEOUT);
+			MFI_IO_TIMEOUT_SECS);
 	else
 		ret = megasas_issue_polled(instance, cmd);
 
-
 	ld_count = le32_to_cpu(ci->ldCount);
 
-	/* the following function will get the instance PD LIST */
+	switch (ret) {
+	case DCMD_FAILED:
+		megaraid_sas_kill_hba(instance);
+		break;
+	case DCMD_TIMEOUT:
+
+		switch (dcmd_timeout_ocr_possible(instance)) {
+		case INITIATE_OCR:
+			cmd->flags |= DRV_DCMD_SKIP_REFIRE;
+			/*
+			 * DCMD failed from AEN path.
+			 * AEN path already hold reset_mutex to avoid PCI access
+			 * while OCR is in progress.
+			 */
+			mutex_unlock(&instance->reset_mutex);
+			megasas_reset_fusion(instance->host,
+						MFI_IO_TIMEOUT_OCR);
+			mutex_lock(&instance->reset_mutex);
+			break;
+		case KILL_ADAPTER:
+			megaraid_sas_kill_hba(instance);
+			break;
+		case IGNORE_TIMEOUT:
+			dev_info(&instance->pdev->dev, "Ignore DCMD timeout: %s %d\n",
+				__func__, __LINE__);
+			break;
+		}
+
+		break;
+
+	case DCMD_SUCCESS:
+		if (ld_count > instance->fw_supported_vd_count)
+			break;
 
-	if ((ret == 0) && (ld_count <= instance->fw_supported_vd_count)) {
 		memset(instance->ld_ids, 0xff, MAX_LOGICAL_DRIVES_EXT);
 
 		for (ld_index = 0; ld_index < ld_count; ld_index++) {
 			if (ci->ldList[ld_index].state != 0) {
 				ids = ci->ldList[ld_index].ref.targetId;
-				instance->ld_ids[ids] =
-					ci->ldList[ld_index].ref.targetId;
+				instance->ld_ids[ids] = ci->ldList[ld_index].ref.targetId;
 			}
 		}
+
+		break;
 	}
 
-	pci_free_consistent(instance->pdev,
-				sizeof(struct MR_LD_LIST),
-				ci,
-				ci_h);
+	pci_free_consistent(instance->pdev, sizeof(struct MR_LD_LIST), ci, ci_h);
+
+	if (ret != DCMD_TIMEOUT)
+		megasas_return_cmd(instance, cmd);
 
-	megasas_return_cmd(instance, cmd);
 	return ret;
 }
 
@@ -4090,26 +4332,61 @@ megasas_ld_list_query(struct megasas_ins
 	dcmd->pad_0  = 0;
 
 	if (instance->ctrl_context && !instance->mask_interrupts)
-		ret = megasas_issue_blocked_cmd(instance, cmd,
-			MEGASAS_BLOCKED_CMD_TIMEOUT);
+		ret = megasas_issue_blocked_cmd(instance, cmd, MFI_IO_TIMEOUT_SECS);
 	else
 		ret = megasas_issue_polled(instance, cmd);
 
-	tgtid_count = le32_to_cpu(ci->count);
+	switch (ret) {
+	case DCMD_FAILED:
+		dev_info(&instance->pdev->dev,
+			"DCMD not supported by firmware - %s %d\n",
+				__func__, __LINE__);
+		ret = megasas_get_ld_list(instance);
+		break;
+	case DCMD_TIMEOUT:
+		switch (dcmd_timeout_ocr_possible(instance)) {
+		case INITIATE_OCR:
+			cmd->flags |= DRV_DCMD_SKIP_REFIRE;
+			/*
+			 * DCMD failed from AEN path.
+			 * AEN path already hold reset_mutex to avoid PCI access
+			 * while OCR is in progress.
+			 */
+			mutex_unlock(&instance->reset_mutex);
+			megasas_reset_fusion(instance->host,
+						MFI_IO_TIMEOUT_OCR);
+			mutex_lock(&instance->reset_mutex);
+			break;
+		case KILL_ADAPTER:
+			megaraid_sas_kill_hba(instance);
+			break;
+		case IGNORE_TIMEOUT:
+			dev_info(&instance->pdev->dev, "Ignore DCMD timeout: %s %d\n",
+				__func__, __LINE__);
+			break;
+		}
+
+		break;
+	case DCMD_SUCCESS:
+		tgtid_count = le32_to_cpu(ci->count);
+
+		if ((tgtid_count > (instance->fw_supported_vd_count)))
+			break;
 
-	if ((ret == 0) && (tgtid_count <= (instance->fw_supported_vd_count))) {
 		memset(instance->ld_ids, 0xff, MEGASAS_MAX_LD_IDS);
 		for (ld_index = 0; ld_index < tgtid_count; ld_index++) {
 			ids = ci->targetId[ld_index];
 			instance->ld_ids[ids] = ci->targetId[ld_index];
 		}
 
+		break;
 	}
 
 	pci_free_consistent(instance->pdev, sizeof(struct MR_LD_TARGETID_LIST),
-			    ci, ci_h);
+		    ci, ci_h);
 
-	megasas_return_cmd(instance, cmd);
+	if (ret != DCMD_TIMEOUT)
+		megasas_return_cmd(instance, cmd);
 
 	return ret;
 }
@@ -4223,38 +4500,73 @@ megasas_get_ctrl_info(struct megasas_ins
 	dcmd->mbox.b[0] = 1;
 
 	if (instance->ctrl_context && !instance->mask_interrupts)
-		ret = megasas_issue_blocked_cmd(instance, cmd,
-			MEGASAS_BLOCKED_CMD_TIMEOUT);
+		ret = megasas_issue_blocked_cmd(instance, cmd, MFI_IO_TIMEOUT_SECS);
 	else
 		ret = megasas_issue_polled(instance, cmd);
 
-	if (!ret) {
+	switch (ret) {
+	case DCMD_SUCCESS:
 		memcpy(ctrl_info, ci, sizeof(struct megasas_ctrl_info));
+		/* Save required controller information in
+		 * CPU endianness format.
+		 */
 		le32_to_cpus((u32 *)&ctrl_info->properties.OnOffProperties);
 		le32_to_cpus((u32 *)&ctrl_info->adapterOperations2);
 		le32_to_cpus((u32 *)&ctrl_info->adapterOperations3);
+
+		/* Update the latest Ext VD info.
+		 * From Init path, store current firmware details.
+		 * From OCR path, detect any firmware properties changes.
+		 * in case of Firmware upgrade without system reboot.
+		 */
 		megasas_update_ext_vd_details(instance);
 		instance->use_seqnum_jbod_fp =
 			ctrl_info->adapterOperations3.useSeqNumJbodFP;
+
+		/*Check whether controller is iMR or MR */
 		instance->is_imr = (ctrl_info->memory_size ? 0 : 1);
 		dev_info(&instance->pdev->dev,
-				"controller type\t: %s(%dMB)\n",
-				instance->is_imr ? "iMR" : "MR",
-				le16_to_cpu(ctrl_info->memory_size));
+			"controller type\t: %s(%dMB)\n",
+			instance->is_imr ? "iMR" : "MR",
+			le16_to_cpu(ctrl_info->memory_size));
+
 		instance->disableOnlineCtrlReset =
 			ctrl_info->properties.OnOffProperties.disableOnlineCtrlReset;
-		dev_info(&instance->pdev->dev, "Online Controller Reset(OCR)\t: %s\n",
-			instance->disableOnlineCtrlReset ? "Disabled" : "Enabled");
 		instance->secure_jbod_support =
 			ctrl_info->adapterOperations3.supportSecurityonJBOD;
+		dev_info(&instance->pdev->dev, "Online Controller Reset(OCR)\t: %s\n",
+			instance->disableOnlineCtrlReset ? "Disabled" : "Enabled");
 		dev_info(&instance->pdev->dev, "Secure JBOD support\t: %s\n",
 			instance->secure_jbod_support ? "Yes" : "No");
+		break;
+
+	case DCMD_TIMEOUT:
+		switch (dcmd_timeout_ocr_possible(instance)) {
+		case INITIATE_OCR:
+			cmd->flags |= DRV_DCMD_SKIP_REFIRE;
+			megasas_reset_fusion(instance->host,
+				MFI_IO_TIMEOUT_OCR);
+			break;
+		case KILL_ADAPTER:
+			megaraid_sas_kill_hba(instance);
+			break;
+		case IGNORE_TIMEOUT:
+			dev_info(&instance->pdev->dev, "Ignore DCMD timeout: %s %d\n",
+				__func__, __LINE__);
+			break;
+		}
+	case DCMD_FAILED:
+		megaraid_sas_kill_hba(instance);
+		break;
+
 	}
 
 	pci_free_consistent(instance->pdev, sizeof(struct megasas_ctrl_info),
 			    ci, ci_h);
 
 	megasas_return_cmd(instance, cmd);
+
+
 	return ret;
 }
 
@@ -4304,12 +4616,28 @@ int megasas_set_crash_dump_params(struct
 	dcmd->sgl.sge32[0].length = cpu_to_le32(CRASH_DMA_BUF_SIZE);
 
 	if (instance->ctrl_context && !instance->mask_interrupts)
-		ret = megasas_issue_blocked_cmd(instance, cmd,
-			MEGASAS_BLOCKED_CMD_TIMEOUT);
+		ret = megasas_issue_blocked_cmd(instance, cmd, MFI_IO_TIMEOUT_SECS);
 	else
 		ret = megasas_issue_polled(instance, cmd);
 
-	megasas_return_cmd(instance, cmd);
+	if (ret == DCMD_TIMEOUT) {
+		switch (dcmd_timeout_ocr_possible(instance)) {
+		case INITIATE_OCR:
+			cmd->flags |= DRV_DCMD_SKIP_REFIRE;
+			megasas_reset_fusion(instance->host,
+					MFI_IO_TIMEOUT_OCR);
+			break;
+		case KILL_ADAPTER:
+			megaraid_sas_kill_hba(instance);
+			break;
+		case IGNORE_TIMEOUT:
+			dev_info(&instance->pdev->dev, "Ignore DCMD timeout: %s %d\n",
+				__func__, __LINE__);
+			break;
+		}
+	} else
+		megasas_return_cmd(instance, cmd);
+
 	return ret;
 }
 
@@ -4426,6 +4754,7 @@ megasas_init_adapter_mfi(struct megasas_
 		sema_init(&instance->ioctl_sem, (MEGASAS_MFI_IOCTL_CMDS));
 	}
 
+	instance->cur_can_queue = instance->max_scsi_cmds;
 	/*
 	 * Create a pool of commands
 	 */
@@ -4669,7 +4998,7 @@ static int megasas_init_fw(struct megasa
 	/* Find first memory bar */
 	bar_list = pci_select_bars(instance->pdev, IORESOURCE_MEM);
 	instance->bar = find_first_bit(&bar_list, sizeof(unsigned long));
-	if (pci_request_selected_regions(instance->pdev, instance->bar,
+	if (pci_request_selected_regions(instance->pdev, 1<<instance->bar,
 					 "megasas: LSI")) {
 		dev_printk(KERN_DEBUG, &instance->pdev->dev, "IO memory region busy!\n");
 		return -EBUSY;
@@ -4712,7 +5041,6 @@ static int megasas_init_fw(struct megasa
 	case PCI_DEVICE_ID_DELL_PERC5:
 	default:
 		instance->instancet = &megasas_instance_template_xscale;
-		instance->allow_fw_scan = 1;
 		break;
 	}
 
@@ -4756,6 +5084,9 @@ static int megasas_init_fw(struct megasa
 				instance->msix_vectors = ((scratch_pad_2
 					& MR_MAX_REPLY_QUEUES_EXT_OFFSET)
 					>> MR_MAX_REPLY_QUEUES_EXT_OFFSET_SHIFT) + 1;
+				if (rdpq_enable)
+					instance->is_rdpq = (scratch_pad_2 & MR_RDPQ_MODE_OFFSET) ?
+								1 : 0;
 				fw_msix_count = instance->msix_vectors;
 				/* Save 1-15 reply post index address to local memory
 				 * Index 0 is already saved from reg offset
@@ -4792,6 +5123,8 @@ static int megasas_init_fw(struct megasa
 	dev_info(&instance->pdev->dev,
 		"current msix/online cpus\t: (%d/%d)\n",
 		instance->msix_vectors, (unsigned int)num_online_cpus());
+	dev_info(&instance->pdev->dev,
+		"RDPQ mode\t: (%s)\n", instance->is_rdpq ? "enabled" : "disabled");
 
 	tasklet_init(&instance->isr_tasklet, instance->instancet->tasklet,
 		(unsigned long)instance);
@@ -4856,7 +5189,9 @@ static int megasas_init_fw(struct megasa
 
 	tmp_sectors = min_t(u32, max_sectors_1, max_sectors_2);
 
-	instance->mpio = ctrl_info->adapterOperations2.mpio;
+	instance->peerIsPresent = ctrl_info->cluster.peerIsPresent;
+	instance->passive = ctrl_info->cluster.passive;
+	memcpy(instance->clusterId, ctrl_info->clusterId, sizeof(instance->clusterId));
 	instance->UnevenSpanSupport =
 		ctrl_info->adapterOperations2.supportUnevenSpans;
 	if (instance->UnevenSpanSupport) {
@@ -4932,6 +5267,11 @@ static int megasas_init_fw(struct megasa
 		instance->throttlequeuedepth =
 				MEGASAS_THROTTLE_QUEUE_DEPTH;
 
+	if (resetwaittime > MEGASAS_RESET_WAIT_TIME)
+		resetwaittime = MEGASAS_RESET_WAIT_TIME;
+
+	if ((scmd_timeout < 10) || (scmd_timeout > MEGASAS_DEFAULT_CMD_TIMEOUT))
+		scmd_timeout = MEGASAS_DEFAULT_CMD_TIMEOUT;
 
 	/* Launch SR-IOV heartbeat timer */
 	if (instance->requestorId) {
@@ -4960,7 +5300,7 @@ fail_ready_state:
 	iounmap(instance->reg_set);
 
       fail_ioremap:
-	pci_release_selected_regions(instance->pdev, instance->bar);
+	pci_release_selected_regions(instance->pdev, 1<<instance->bar);
 
 	return -EINVAL;
 }
@@ -4981,7 +5321,7 @@ static void megasas_release_mfi(struct m
 
 	iounmap(instance->reg_set);
 
-	pci_release_selected_regions(instance->pdev, instance->bar);
+	pci_release_selected_regions(instance->pdev, 1<<instance->bar);
 }
 
 /**
@@ -5035,10 +5375,8 @@ megasas_get_seq_num(struct megasas_insta
 	dcmd->sgl.sge32[0].phys_addr = cpu_to_le32(el_info_h);
 	dcmd->sgl.sge32[0].length = cpu_to_le32(sizeof(struct megasas_evt_log_info));
 
-	if (megasas_issue_blocked_cmd(instance, cmd, 30))
-		dev_err(&instance->pdev->dev, "Command timedout"
-			"from %s\n", __func__);
-	else {
+	if (megasas_issue_blocked_cmd(instance, cmd, MFI_IO_TIMEOUT_SECS) ==
+		DCMD_SUCCESS) {
 		/*
 		 * Copy the data back into callers buffer
 		 */
@@ -5047,7 +5385,9 @@ megasas_get_seq_num(struct megasas_insta
 		eli->clear_seq_num = el_info->clear_seq_num;
 		eli->shutdown_seq_num = el_info->shutdown_seq_num;
 		eli->boot_seq_num = el_info->boot_seq_num;
-	}
+	} else
+		dev_err(&instance->pdev->dev, "DCMD failed "
+			"from %s\n", __func__);
 
 	pci_free_consistent(instance->pdev, sizeof(struct megasas_evt_log_info),
 			    el_info, el_info_h);
@@ -5262,6 +5602,8 @@ static int megasas_io_attach(struct mega
 	if (instance->ctrl_context) {
 		host->hostt->eh_device_reset_handler = NULL;
 		host->hostt->eh_bus_reset_handler = NULL;
+		host->hostt->eh_target_reset_handler = megasas_reset_target_fusion;
+		host->hostt->eh_abort_handler = megasas_task_abort_fusion;
 	}
 
 	/*
@@ -5447,7 +5789,7 @@ static int megasas_probe_one(struct pci_
 	instance->flag_ieee = 0;
 	instance->ev = NULL;
 	instance->issuepend_done = 1;
-	instance->adprecovery = MEGASAS_HBA_OPERATIONAL;
+	atomic_set(&instance->adprecovery, MEGASAS_HBA_OPERATIONAL);
 	instance->is_imr = 0;
 
 	instance->evt_detail = pci_alloc_consistent(pdev,
@@ -5461,6 +5803,12 @@ static int megasas_probe_one(struct pci_
 		goto fail_alloc_dma_buf;
 	}
 
+	instance->pd_info = pci_alloc_consistent(pdev,
+		sizeof(struct MR_PD_INFO), &instance->pd_info_h);
+
+	if (!instance->pd_info)
+		dev_err(&instance->pdev->dev, "Failed to alloc mem for pd_info\n");
+
 	/*
 	 * Initialize locks and queues
 	 */
@@ -5476,8 +5824,8 @@ static int megasas_probe_one(struct pci_
 	spin_lock_init(&instance->hba_lock);
 	spin_lock_init(&instance->completion_lock);
 
-	mutex_init(&instance->aen_mutex);
 	mutex_init(&instance->reset_mutex);
+	mutex_init(&instance->hba_mutex);
 
 	/*
 	 * Initialize PCI related and misc parameters
@@ -5592,6 +5940,10 @@ fail_alloc_dma_buf:
 				    instance->evt_detail,
 				    instance->evt_detail_h);
 
+	if (instance->pd_info)
+		pci_free_consistent(pdev, sizeof(struct MR_PD_INFO),
+					instance->pd_info,
+					instance->pd_info_h);
 	if (instance->producer)
 		pci_free_consistent(pdev, sizeof(u32), instance->producer,
 				    instance->producer_h);
@@ -5616,7 +5968,7 @@ static void megasas_flush_cache(struct m
 	struct megasas_cmd *cmd;
 	struct megasas_dcmd_frame *dcmd;
 
-	if (instance->adprecovery == MEGASAS_HW_CRITICAL_ERROR)
+	if (atomic_read(&instance->adprecovery) == MEGASAS_HW_CRITICAL_ERROR)
 		return;
 
 	cmd = megasas_get_cmd(instance);
@@ -5638,9 +5990,12 @@ static void megasas_flush_cache(struct m
 	dcmd->opcode = cpu_to_le32(MR_DCMD_CTRL_CACHE_FLUSH);
 	dcmd->mbox.b[0] = MR_FLUSH_CTRL_CACHE | MR_FLUSH_DISK_CACHE;
 
-	if (megasas_issue_blocked_cmd(instance, cmd, 30))
-		dev_err(&instance->pdev->dev, "Command timedout"
-			" from %s\n", __func__);
+	if (megasas_issue_blocked_cmd(instance, cmd, MFI_IO_TIMEOUT_SECS)
+			!= DCMD_SUCCESS) {
+		dev_err(&instance->pdev->dev,
+			"return from %s %d\n", __func__, __LINE__);
+		return;
+	}
 
 	megasas_return_cmd(instance, cmd);
 }
@@ -5656,7 +6011,7 @@ static void megasas_shutdown_controller(
 	struct megasas_cmd *cmd;
 	struct megasas_dcmd_frame *dcmd;
 
-	if (instance->adprecovery == MEGASAS_HW_CRITICAL_ERROR)
+	if (atomic_read(&instance->adprecovery) == MEGASAS_HW_CRITICAL_ERROR)
 		return;
 
 	cmd = megasas_get_cmd(instance);
@@ -5666,13 +6021,13 @@ static void megasas_shutdown_controller(
 
 	if (instance->aen_cmd)
 		megasas_issue_blocked_abort_cmd(instance,
-			instance->aen_cmd, MEGASAS_BLOCKED_CMD_TIMEOUT);
+			instance->aen_cmd, MFI_IO_TIMEOUT_SECS);
 	if (instance->map_update_cmd)
 		megasas_issue_blocked_abort_cmd(instance,
-			instance->map_update_cmd, MEGASAS_BLOCKED_CMD_TIMEOUT);
+			instance->map_update_cmd, MFI_IO_TIMEOUT_SECS);
 	if (instance->jbod_seq_cmd)
 		megasas_issue_blocked_abort_cmd(instance,
-			instance->jbod_seq_cmd, MEGASAS_BLOCKED_CMD_TIMEOUT);
+			instance->jbod_seq_cmd, MFI_IO_TIMEOUT_SECS);
 
 	dcmd = &cmd->frame->dcmd;
 
@@ -5687,9 +6042,12 @@ static void megasas_shutdown_controller(
 	dcmd->data_xfer_len = 0;
 	dcmd->opcode = cpu_to_le32(opcode);
 
-	if (megasas_issue_blocked_cmd(instance, cmd, 30))
-		dev_err(&instance->pdev->dev, "Command timedout"
-			"from %s\n", __func__);
+	if (megasas_issue_blocked_cmd(instance, cmd, MFI_IO_TIMEOUT_SECS)
+			!= DCMD_SUCCESS) {
+		dev_err(&instance->pdev->dev,
+			"return from %s %d\n", __func__, __LINE__);
+		return;
+	}
 
 	megasas_return_cmd(instance, cmd);
 }
@@ -5847,6 +6205,10 @@ fail_init_mfi:
 				instance->evt_detail,
 				instance->evt_detail_h);
 
+	if (instance->pd_info)
+		pci_free_consistent(pdev, sizeof(struct MR_PD_INFO),
+					instance->pd_info,
+					instance->pd_info_h);
 	if (instance->producer)
 		pci_free_consistent(pdev, sizeof(u32), instance->producer,
 				instance->producer_h);
@@ -5941,11 +6303,11 @@ static void megasas_detach_one(struct pc
 			if (fusion->ld_drv_map[i])
 				free_pages((ulong)fusion->ld_drv_map[i],
 					fusion->drv_map_pages);
-				if (fusion->pd_seq_sync)
-					dma_free_coherent(&instance->pdev->dev,
-						pd_seq_map_sz,
-						fusion->pd_seq_sync[i],
-						fusion->pd_seq_phys[i]);
+			if (fusion->pd_seq_sync[i])
+				dma_free_coherent(&instance->pdev->dev,
+					pd_seq_map_sz,
+					fusion->pd_seq_sync[i],
+					fusion->pd_seq_phys[i]);
 		}
 		free_pages((ulong)instance->ctrl_context,
 			instance->ctrl_context_pages);
@@ -5965,6 +6327,10 @@ static void megasas_detach_one(struct pc
 		pci_free_consistent(pdev, sizeof(struct megasas_evt_detail),
 				instance->evt_detail, instance->evt_detail_h);
 
+	if (instance->pd_info)
+		pci_free_consistent(pdev, sizeof(struct MR_PD_INFO),
+					instance->pd_info,
+					instance->pd_info_h);
 	if (instance->vf_affiliation)
 		pci_free_consistent(pdev, (MAX_LOGICAL_DRIVES + 1) *
 				    sizeof(struct MR_LD_VF_AFFILIATION),
@@ -6090,7 +6456,7 @@ static int megasas_set_crash_dump_params
 	for (i = 0; i < megasas_mgmt_info.max_index; i++) {
 		local_instance = megasas_mgmt_info.instance[i];
 		if (local_instance && local_instance->crash_dump_drv_support) {
-			if ((local_instance->adprecovery ==
+			if ((atomic_read(&local_instance->adprecovery) ==
 				MEGASAS_HBA_OPERATIONAL) &&
 				!megasas_set_crash_dump_params(local_instance,
 					crash_support)) {
@@ -6227,7 +6593,15 @@ megasas_mgmt_fw_ioctl(struct megasas_ins
 	 * cmd to the SCSI mid-layer
 	 */
 	cmd->sync_cmd = 1;
-	megasas_issue_blocked_cmd(instance, cmd, 0);
+	if (megasas_issue_blocked_cmd(instance, cmd, 0) == DCMD_NOT_FIRED) {
+		cmd->sync_cmd = 0;
+		dev_err(&instance->pdev->dev,
+			"return -EBUSY from %s %d opcode 0x%x cmd->cmd_status_drv 0x%x\n",
+			__func__, __LINE__, cmd->frame->dcmd.opcode,
+			cmd->cmd_status_drv);
+		return -EBUSY;
+	}
+
 	cmd->sync_cmd = 0;
 
 	if (instance->unload == 1) {
@@ -6282,12 +6656,13 @@ out:
 	}
 
 	for (i = 0; i < ioc->sge_count; i++) {
-		if (kbuff_arr[i])
+		if (kbuff_arr[i]) {
 			dma_free_coherent(&instance->pdev->dev,
 					  le32_to_cpu(kern_sge32[i].length),
 					  kbuff_arr[i],
 					  le32_to_cpu(kern_sge32[i].phys_addr));
 			kbuff_arr[i] = NULL;
+		}
 	}
 
 	megasas_return_cmd(instance, cmd);
@@ -6330,7 +6705,7 @@ static int megasas_mgmt_ioctl_fw(struct
 		goto out_kfree_ioc;
 	}
 
-	if (instance->adprecovery == MEGASAS_HW_CRITICAL_ERROR) {
+	if (atomic_read(&instance->adprecovery) == MEGASAS_HW_CRITICAL_ERROR) {
 		dev_err(&instance->pdev->dev, "Controller in crit error\n");
 		error = -ENODEV;
 		goto out_kfree_ioc;
@@ -6349,7 +6724,7 @@ static int megasas_mgmt_ioctl_fw(struct
 	for (i = 0; i < wait_time; i++) {
 
 		spin_lock_irqsave(&instance->hba_lock, flags);
-		if (instance->adprecovery == MEGASAS_HBA_OPERATIONAL) {
+		if (atomic_read(&instance->adprecovery) == MEGASAS_HBA_OPERATIONAL) {
 			spin_unlock_irqrestore(&instance->hba_lock, flags);
 			break;
 		}
@@ -6364,7 +6739,7 @@ static int megasas_mgmt_ioctl_fw(struct
 	}
 
 	spin_lock_irqsave(&instance->hba_lock, flags);
-	if (instance->adprecovery != MEGASAS_HBA_OPERATIONAL) {
+	if (atomic_read(&instance->adprecovery) != MEGASAS_HBA_OPERATIONAL) {
 		spin_unlock_irqrestore(&instance->hba_lock, flags);
 
 		dev_err(&instance->pdev->dev, "timed out while"
@@ -6406,7 +6781,7 @@ static int megasas_mgmt_ioctl_aen(struct
 	if (!instance)
 		return -ENODEV;
 
-	if (instance->adprecovery == MEGASAS_HW_CRITICAL_ERROR) {
+	if (atomic_read(&instance->adprecovery) == MEGASAS_HW_CRITICAL_ERROR) {
 		return -ENODEV;
 	}
 
@@ -6417,7 +6792,7 @@ static int megasas_mgmt_ioctl_aen(struct
 	for (i = 0; i < wait_time; i++) {
 
 		spin_lock_irqsave(&instance->hba_lock, flags);
-		if (instance->adprecovery == MEGASAS_HBA_OPERATIONAL) {
+		if (atomic_read(&instance->adprecovery) == MEGASAS_HBA_OPERATIONAL) {
 			spin_unlock_irqrestore(&instance->hba_lock,
 						flags);
 			break;
@@ -6434,7 +6809,7 @@ static int megasas_mgmt_ioctl_aen(struct
 	}
 
 	spin_lock_irqsave(&instance->hba_lock, flags);
-	if (instance->adprecovery != MEGASAS_HBA_OPERATIONAL) {
+	if (atomic_read(&instance->adprecovery) != MEGASAS_HBA_OPERATIONAL) {
 		spin_unlock_irqrestore(&instance->hba_lock, flags);
 		dev_err(&instance->pdev->dev, "timed out while waiting"
 				"for HBA to recover\n");
@@ -6442,10 +6817,10 @@ static int megasas_mgmt_ioctl_aen(struct
 	}
 	spin_unlock_irqrestore(&instance->hba_lock, flags);
 
-	mutex_lock(&instance->aen_mutex);
+	mutex_lock(&instance->reset_mutex);
 	error = megasas_register_aen(instance, aen.seq_num,
 				     aen.class_locale_word);
-	mutex_unlock(&instance->aen_mutex);
+	mutex_unlock(&instance->reset_mutex);
 	return error;
 }
 
@@ -6476,9 +6851,9 @@ static int megasas_mgmt_compat_ioctl_fw(
 	int i;
 	int error = 0;
 	compat_uptr_t ptr;
-	unsigned long local_raw_ptr;
 	u32 local_sense_off;
 	u32 local_sense_len;
+	u32 user_sense_off;
 
 	if (clear_user(ioc, sizeof(*ioc)))
 		return -EFAULT;
@@ -6496,17 +6871,16 @@ static int megasas_mgmt_compat_ioctl_fw(
 	 * sense_len is not null, so prepare the 64bit value under
 	 * the same condition.
 	 */
-	if (get_user(local_raw_ptr, ioc->frame.raw) ||
-		get_user(local_sense_off, &ioc->sense_off) ||
-		get_user(local_sense_len, &ioc->sense_len))
+	if (get_user(local_sense_off, &ioc->sense_off) ||
+		get_user(local_sense_len, &ioc->sense_len) ||
+		get_user(user_sense_off, &cioc->sense_off))
 		return -EFAULT;
 
-
 	if (local_sense_len) {
 		void __user **sense_ioc_ptr =
-			(void __user **)((u8*)local_raw_ptr + local_sense_off);
+			(void __user **)((u8 *)((unsigned long)&ioc->frame.raw) + local_sense_off);
 		compat_uptr_t *sense_cioc_ptr =
-			(compat_uptr_t *)(cioc->frame.raw + cioc->sense_off);
+			(compat_uptr_t *)(((unsigned long)&cioc->frame.raw) + user_sense_off);
 		if (get_user(ptr, sense_cioc_ptr) ||
 		    put_user(compat_ptr(ptr), sense_ioc_ptr))
 			return -EFAULT;
@@ -6647,6 +7021,7 @@ megasas_aen_polling(struct work_struct *
 	int     i, j, doscan = 0;
 	u32 seq_num, wait_time = MEGASAS_RESET_WAIT_TIME;
 	int error;
+	u8  dcmd_ret = DCMD_SUCCESS;
 
 	if (!instance) {
 		printk(KERN_ERR "invalid instance!\n");
@@ -6659,16 +7034,7 @@ megasas_aen_polling(struct work_struct *
 		wait_time = MEGASAS_ROUTINE_WAIT_TIME_VF;
 
 	/* Don't run the event workqueue thread if OCR is running */
-	for (i = 0; i < wait_time; i++) {
-		if (instance->adprecovery == MEGASAS_HBA_OPERATIONAL)
-			break;
-		if (!(i % MEGASAS_RESET_NOTICE_INTERVAL)) {
-			dev_notice(&instance->pdev->dev, "%s waiting for "
-			       "controller reset to finish for scsi%d\n",
-			       __func__, instance->host->host_no);
-		}
-		msleep(1000);
-	}
+	mutex_lock(&instance->reset_mutex);
 
 	instance->ev = NULL;
 	host = instance->host;
@@ -6676,212 +7042,127 @@ megasas_aen_polling(struct work_struct *
 		megasas_decode_evt(instance);
 
 		switch (le32_to_cpu(instance->evt_detail->code)) {
-		case MR_EVT_PD_INSERTED:
-			if (megasas_get_pd_list(instance) == 0) {
-			for (i = 0; i < MEGASAS_MAX_PD_CHANNELS; i++) {
-				for (j = 0;
-				j < MEGASAS_MAX_DEV_PER_CHANNEL;
-				j++) {
-
-				pd_index =
-				(i * MEGASAS_MAX_DEV_PER_CHANNEL) + j;
-
-				sdev1 = scsi_device_lookup(host, i, j, 0);
-
-				if (instance->pd_list[pd_index].driveState
-						== MR_PD_STATE_SYSTEM) {
-					if (!sdev1)
-						scsi_add_device(host, i, j, 0);
-
-					if (sdev1)
-						scsi_device_put(sdev1);
-					}
-				}
-			}
-			}
-			doscan = 0;
-			break;
 
+		case MR_EVT_PD_INSERTED:
 		case MR_EVT_PD_REMOVED:
-			if (megasas_get_pd_list(instance) == 0) {
-			for (i = 0; i < MEGASAS_MAX_PD_CHANNELS; i++) {
-				for (j = 0;
-				j < MEGASAS_MAX_DEV_PER_CHANNEL;
-				j++) {
-
-				pd_index =
-				(i * MEGASAS_MAX_DEV_PER_CHANNEL) + j;
-
-				sdev1 = scsi_device_lookup(host, i, j, 0);
-
-				if (instance->pd_list[pd_index].driveState
-					== MR_PD_STATE_SYSTEM) {
-					if (sdev1)
-						scsi_device_put(sdev1);
-				} else {
-					if (sdev1) {
-						scsi_remove_device(sdev1);
-						scsi_device_put(sdev1);
-					}
-				}
-				}
-			}
-			}
-			doscan = 0;
+			dcmd_ret = megasas_get_pd_list(instance);
+			if (dcmd_ret == DCMD_SUCCESS)
+				doscan = SCAN_PD_CHANNEL;
 			break;
 
 		case MR_EVT_LD_OFFLINE:
 		case MR_EVT_CFG_CLEARED:
 		case MR_EVT_LD_DELETED:
-			if (!instance->requestorId ||
-			    megasas_get_ld_vf_affiliation(instance, 0)) {
-				if (megasas_ld_list_query(instance,
-							  MR_LD_QUERY_TYPE_EXPOSED_TO_HOST))
-					megasas_get_ld_list(instance);
-				for (i = 0; i < MEGASAS_MAX_LD_CHANNELS; i++) {
-					for (j = 0;
-					     j < MEGASAS_MAX_DEV_PER_CHANNEL;
-					     j++) {
-
-						ld_index =
-							(i * MEGASAS_MAX_DEV_PER_CHANNEL) + j;
-
-						sdev1 = scsi_device_lookup(host, MEGASAS_MAX_PD_CHANNELS + i, j, 0);
-
-						if (instance->ld_ids[ld_index]
-						    != 0xff) {
-							if (sdev1)
-								scsi_device_put(sdev1);
-						} else {
-							if (sdev1) {
-								scsi_remove_device(sdev1);
-								scsi_device_put(sdev1);
-							}
-						}
-					}
-				}
-				doscan = 0;
-			}
-			break;
 		case MR_EVT_LD_CREATED:
 			if (!instance->requestorId ||
-			    megasas_get_ld_vf_affiliation(instance, 0)) {
-				if (megasas_ld_list_query(instance,
-							  MR_LD_QUERY_TYPE_EXPOSED_TO_HOST))
-					megasas_get_ld_list(instance);
-				for (i = 0; i < MEGASAS_MAX_LD_CHANNELS; i++) {
-					for (j = 0;
-					     j < MEGASAS_MAX_DEV_PER_CHANNEL;
-					     j++) {
-						ld_index =
-							(i * MEGASAS_MAX_DEV_PER_CHANNEL) + j;
-
-						sdev1 = scsi_device_lookup(host, MEGASAS_MAX_PD_CHANNELS + i, j, 0);
-
-						if (instance->ld_ids[ld_index]
-						    != 0xff) {
-							if (!sdev1)
-								scsi_add_device(host, MEGASAS_MAX_PD_CHANNELS + i, j, 0);
-						}
-						if (sdev1)
-							scsi_device_put(sdev1);
-					}
-				}
-				doscan = 0;
-			}
+				(instance->requestorId && megasas_get_ld_vf_affiliation(instance, 0)))
+				dcmd_ret = megasas_ld_list_query(instance, MR_LD_QUERY_TYPE_EXPOSED_TO_HOST);
+
+			if (dcmd_ret == DCMD_SUCCESS)
+				doscan = SCAN_VD_CHANNEL;
+
 			break;
+
 		case MR_EVT_CTRL_HOST_BUS_SCAN_REQUESTED:
 		case MR_EVT_FOREIGN_CFG_IMPORTED:
 		case MR_EVT_LD_STATE_CHANGE:
-			doscan = 1;
+			dcmd_ret = megasas_get_pd_list(instance);
+
+			if (dcmd_ret != DCMD_SUCCESS)
+				break;
+
+			if (!instance->requestorId ||
+				(instance->requestorId && megasas_get_ld_vf_affiliation(instance, 0)))
+				dcmd_ret = megasas_ld_list_query(instance, MR_LD_QUERY_TYPE_EXPOSED_TO_HOST);
+
+			if (dcmd_ret != DCMD_SUCCESS)
+				break;
+
+			doscan = SCAN_VD_CHANNEL | SCAN_PD_CHANNEL;
+			dev_info(&instance->pdev->dev, "scanning for scsi%d...\n",
+				instance->host->host_no);
 			break;
+
 		case MR_EVT_CTRL_PROP_CHANGED:
-			megasas_get_ctrl_info(instance);
-			break;
+				dcmd_ret = megasas_get_ctrl_info(instance);
+				break;
 		default:
 			doscan = 0;
 			break;
 		}
 	} else {
 		dev_err(&instance->pdev->dev, "invalid evt_detail!\n");
+		mutex_unlock(&instance->reset_mutex);
 		kfree(ev);
 		return;
 	}
 
-	if (doscan) {
-		dev_info(&instance->pdev->dev, "scanning for scsi%d...\n",
-		       instance->host->host_no);
-		if (megasas_get_pd_list(instance) == 0) {
-			for (i = 0; i < MEGASAS_MAX_PD_CHANNELS; i++) {
-				for (j = 0; j < MEGASAS_MAX_DEV_PER_CHANNEL; j++) {
-					pd_index = i*MEGASAS_MAX_DEV_PER_CHANNEL + j;
-					sdev1 = scsi_device_lookup(host, i, j, 0);
-					if (instance->pd_list[pd_index].driveState ==
-					    MR_PD_STATE_SYSTEM) {
-						if (!sdev1) {
-							scsi_add_device(host, i, j, 0);
-						}
-						if (sdev1)
-							scsi_device_put(sdev1);
-					} else {
-						if (sdev1) {
-							scsi_remove_device(sdev1);
-							scsi_device_put(sdev1);
-						}
+	mutex_unlock(&instance->reset_mutex);
+
+	if (doscan & SCAN_PD_CHANNEL) {
+		for (i = 0; i < MEGASAS_MAX_PD_CHANNELS; i++) {
+			for (j = 0; j < MEGASAS_MAX_DEV_PER_CHANNEL; j++) {
+				pd_index = i*MEGASAS_MAX_DEV_PER_CHANNEL + j;
+				sdev1 = scsi_device_lookup(host, i, j, 0);
+				if (instance->pd_list[pd_index].driveState ==
+							MR_PD_STATE_SYSTEM) {
+					if (!sdev1)
+						scsi_add_device(host, i, j, 0);
+					else
+						scsi_device_put(sdev1);
+				} else {
+					if (sdev1) {
+						scsi_remove_device(sdev1);
+						scsi_device_put(sdev1);
 					}
 				}
 			}
 		}
+	}
 
-		if (!instance->requestorId ||
-		    megasas_get_ld_vf_affiliation(instance, 0)) {
-			if (megasas_ld_list_query(instance,
-						  MR_LD_QUERY_TYPE_EXPOSED_TO_HOST))
-				megasas_get_ld_list(instance);
-			for (i = 0; i < MEGASAS_MAX_LD_CHANNELS; i++) {
-				for (j = 0; j < MEGASAS_MAX_DEV_PER_CHANNEL;
-				     j++) {
-					ld_index =
-						(i * MEGASAS_MAX_DEV_PER_CHANNEL) + j;
-
-					sdev1 = scsi_device_lookup(host,
-								   MEGASAS_MAX_PD_CHANNELS + i, j, 0);
-					if (instance->ld_ids[ld_index]
-					    != 0xff) {
-						if (!sdev1)
-							scsi_add_device(host, MEGASAS_MAX_PD_CHANNELS + i, j, 0);
-						else
-							scsi_device_put(sdev1);
-					} else {
-						if (sdev1) {
-							scsi_remove_device(sdev1);
-							scsi_device_put(sdev1);
-						}
+	if (doscan & SCAN_VD_CHANNEL) {
+		for (i = 0; i < MEGASAS_MAX_LD_CHANNELS; i++) {
+			for (j = 0; j < MEGASAS_MAX_DEV_PER_CHANNEL; j++) {
+				ld_index = (i * MEGASAS_MAX_DEV_PER_CHANNEL) + j;
+				sdev1 = scsi_device_lookup(host, MEGASAS_MAX_PD_CHANNELS + i, j, 0);
+				if (instance->ld_ids[ld_index] != 0xff) {
+					if (!sdev1)
+						scsi_add_device(host, MEGASAS_MAX_PD_CHANNELS + i, j, 0);
+					else
+						scsi_device_put(sdev1);
+				} else {
+					if (sdev1) {
+						scsi_remove_device(sdev1);
+						scsi_device_put(sdev1);
 					}
 				}
 			}
 		}
 	}
 
-	if (instance->aen_cmd != NULL) {
-		kfree(ev);
-		return ;
-	}
-
-	seq_num = le32_to_cpu(instance->evt_detail->seq_num) + 1;
+	if (dcmd_ret == DCMD_SUCCESS)
+		seq_num = le32_to_cpu(instance->evt_detail->seq_num) + 1;
+	else
+		seq_num = instance->last_seq_num;
 
 	/* Register AEN with FW for latest sequence number plus 1 */
 	class_locale.members.reserved = 0;
 	class_locale.members.locale = MR_EVT_LOCALE_ALL;
 	class_locale.members.class = MR_EVT_CLASS_DEBUG;
-	mutex_lock(&instance->aen_mutex);
+
+	if (instance->aen_cmd != NULL) {
+		kfree(ev);
+		return;
+	}
+
+	mutex_lock(&instance->reset_mutex);
 	error = megasas_register_aen(instance, seq_num,
 					class_locale.word);
-	mutex_unlock(&instance->aen_mutex);
-
 	if (error)
-		dev_err(&instance->pdev->dev, "register aen failed error %x\n", error);
+		dev_err(&instance->pdev->dev,
+			"register aen failed error %x\n", error);
 
+	mutex_unlock(&instance->reset_mutex);
 	kfree(ev);
 }
 
--- zfcpdump-kernel-4.4.orig/drivers/scsi/megaraid/megaraid_sas_fp.c
+++ zfcpdump-kernel-4.4/drivers/scsi/megaraid/megaraid_sas_fp.c
@@ -1020,6 +1020,8 @@ MR_BuildRaidContext(struct megasas_insta
 	/* assume this IO needs the full row - we'll adjust if not true */
 	regSize             = stripSize;
 
+	io_info->do_fp_rlbypass = raid->capability.fpBypassRegionLock;
+
 	/* Check if we can send this I/O via FastPath */
 	if (raid->capability.fpCapable) {
 		if (isRead)
--- zfcpdump-kernel-4.4.orig/drivers/scsi/megaraid/megaraid_sas_fusion.c
+++ zfcpdump-kernel-4.4/drivers/scsi/megaraid/megaraid_sas_fusion.c
@@ -91,7 +91,10 @@ void megasas_start_timer(struct megasas_
 			struct timer_list *timer,
 			 void *fn, unsigned long interval);
 extern struct megasas_mgmt_info megasas_mgmt_info;
-extern int resetwaittime;
+extern unsigned int resetwaittime;
+extern unsigned int dual_qdepth_disable;
+static void megasas_free_rdpq_fusion(struct megasas_instance *instance);
+static void megasas_free_reply_fusion(struct megasas_instance *instance);
 
 
 
@@ -201,58 +204,72 @@ megasas_fire_cmd_fusion(struct megasas_i
 		&instance->reg_set->inbound_low_queue_port);
 	writel(le32_to_cpu(req_desc->u.high),
 		&instance->reg_set->inbound_high_queue_port);
+	mmiowb();
 	spin_unlock_irqrestore(&instance->hba_lock, flags);
 #endif
 }
 
-
 /**
- * megasas_teardown_frame_pool_fusion -	Destroy the cmd frame DMA pool
- * @instance:				Adapter soft state
+ * megasas_fusion_update_can_queue -	Do all Adapter Queue depth related calculations here
+ * @instance:							Adapter soft state
+ * fw_boot_context:						Whether this function called during probe or after OCR
+ *
+ * This function is only for fusion controllers.
+ * Update host can queue, if firmware downgrade max supported firmware commands.
+ * Firmware upgrade case will be skiped because underlying firmware has
+ * more resource than exposed to the OS.
+ *
  */
-static void megasas_teardown_frame_pool_fusion(
-	struct megasas_instance *instance)
+static void
+megasas_fusion_update_can_queue(struct megasas_instance *instance, int fw_boot_context)
 {
-	int i;
-	struct fusion_context *fusion = instance->ctrl_context;
+	u16 cur_max_fw_cmds = 0;
+	u16 ldio_threshold = 0;
+	struct megasas_register_set __iomem *reg_set;
 
-	u16 max_cmd = instance->max_fw_cmds;
+	reg_set = instance->reg_set;
 
-	struct megasas_cmd_fusion *cmd;
+	cur_max_fw_cmds = readl(&instance->reg_set->outbound_scratch_pad_3) & 0x00FFFF;
 
-	if (!fusion->sg_dma_pool || !fusion->sense_dma_pool) {
-		dev_err(&instance->pdev->dev, "dma pool is null. SG Pool %p, "
-		       "sense pool : %p\n", fusion->sg_dma_pool,
-		       fusion->sense_dma_pool);
-		return;
-	}
+	if (dual_qdepth_disable || !cur_max_fw_cmds)
+		cur_max_fw_cmds = instance->instancet->read_fw_status_reg(reg_set) & 0x00FFFF;
+	else
+		ldio_threshold =
+			(instance->instancet->read_fw_status_reg(reg_set) & 0x00FFFF) - MEGASAS_FUSION_IOCTL_CMDS;
 
-	/*
-	 * Return all frames to pool
-	 */
-	for (i = 0; i < max_cmd; i++) {
+	dev_info(&instance->pdev->dev,
+			"Current firmware maximum commands: %d\t LDIO threshold: %d\n",
+			cur_max_fw_cmds, ldio_threshold);
+
+	if (fw_boot_context == OCR_CONTEXT) {
+		cur_max_fw_cmds = cur_max_fw_cmds - 1;
+		if (cur_max_fw_cmds <= instance->max_fw_cmds) {
+			instance->cur_can_queue =
+				cur_max_fw_cmds - (MEGASAS_FUSION_INTERNAL_CMDS +
+						MEGASAS_FUSION_IOCTL_CMDS);
+			instance->host->can_queue = instance->cur_can_queue;
+			instance->ldio_threshold = ldio_threshold;
+		}
+	} else {
+		instance->max_fw_cmds = cur_max_fw_cmds;
+		instance->ldio_threshold = ldio_threshold;
 
-		cmd = fusion->cmd_list[i];
+		if (!instance->is_rdpq)
+			instance->max_fw_cmds = min_t(u16, instance->max_fw_cmds, 1024);
 
-		if (cmd->sg_frame)
-			pci_pool_free(fusion->sg_dma_pool, cmd->sg_frame,
-				      cmd->sg_frame_phys_addr);
+		/*
+		* Reduce the max supported cmds by 1. This is to ensure that the
+		* reply_q_sz (1 more than the max cmd that driver may send)
+		* does not exceed max cmds that the FW can support
+		*/
+		instance->max_fw_cmds = instance->max_fw_cmds-1;
 
-		if (cmd->sense)
-			pci_pool_free(fusion->sense_dma_pool, cmd->sense,
-				      cmd->sense_phys_addr);
+		instance->max_scsi_cmds = instance->max_fw_cmds -
+				(MEGASAS_FUSION_INTERNAL_CMDS +
+				MEGASAS_FUSION_IOCTL_CMDS);
+		instance->cur_can_queue = instance->max_scsi_cmds;
 	}
-
-	/*
-	 * Now destroy the pool itself
-	 */
-	pci_pool_destroy(fusion->sg_dma_pool);
-	pci_pool_destroy(fusion->sense_dma_pool);
-
-	fusion->sg_dma_pool = NULL;
-	fusion->sense_dma_pool = NULL;
 }
-
 /**
  * megasas_free_cmds_fusion -	Free all the cmds in the free cmd pool
  * @instance:		Adapter soft state
@@ -262,55 +279,65 @@ megasas_free_cmds_fusion(struct megasas_
 {
 	int i;
 	struct fusion_context *fusion = instance->ctrl_context;
+	struct megasas_cmd_fusion *cmd;
 
-	u32 max_cmds, req_sz, reply_sz, io_frames_sz;
+	/* SG, Sense */
+	for (i = 0; i < instance->max_fw_cmds; i++) {
+		cmd = fusion->cmd_list[i];
+		if (cmd) {
+			if (cmd->sg_frame)
+				pci_pool_free(fusion->sg_dma_pool, cmd->sg_frame,
+				      cmd->sg_frame_phys_addr);
+			if (cmd->sense)
+				pci_pool_free(fusion->sense_dma_pool, cmd->sense,
+				      cmd->sense_phys_addr);
+		}
+	}
 
+	if (fusion->sg_dma_pool) {
+		pci_pool_destroy(fusion->sg_dma_pool);
+		fusion->sg_dma_pool = NULL;
+	}
+	if (fusion->sense_dma_pool) {
+		pci_pool_destroy(fusion->sense_dma_pool);
+		fusion->sense_dma_pool = NULL;
+	}
 
-	req_sz = fusion->request_alloc_sz;
-	reply_sz = fusion->reply_alloc_sz;
-	io_frames_sz = fusion->io_frames_alloc_sz;
 
-	max_cmds = instance->max_fw_cmds;
+	/* Reply Frame, Desc*/
+	if (instance->is_rdpq)
+		megasas_free_rdpq_fusion(instance);
+	else
+		megasas_free_reply_fusion(instance);
 
-	/* Free descriptors and request Frames memory */
+	/* Request Frame, Desc*/
 	if (fusion->req_frames_desc)
-		dma_free_coherent(&instance->pdev->dev, req_sz,
-				  fusion->req_frames_desc,
-				  fusion->req_frames_desc_phys);
-
-	if (fusion->reply_frames_desc) {
-		pci_pool_free(fusion->reply_frames_desc_pool,
-			      fusion->reply_frames_desc,
-			      fusion->reply_frames_desc_phys);
-		pci_pool_destroy(fusion->reply_frames_desc_pool);
-	}
-
-	if (fusion->io_request_frames) {
+		dma_free_coherent(&instance->pdev->dev,
+			fusion->request_alloc_sz, fusion->req_frames_desc,
+			fusion->req_frames_desc_phys);
+	if (fusion->io_request_frames)
 		pci_pool_free(fusion->io_request_frames_pool,
-			      fusion->io_request_frames,
-			      fusion->io_request_frames_phys);
+			fusion->io_request_frames,
+			fusion->io_request_frames_phys);
+	if (fusion->io_request_frames_pool) {
 		pci_pool_destroy(fusion->io_request_frames_pool);
+		fusion->io_request_frames_pool = NULL;
 	}
 
-	/* Free the Fusion frame pool */
-	megasas_teardown_frame_pool_fusion(instance);
 
-	/* Free all the commands in the cmd_list */
-	for (i = 0; i < max_cmds; i++)
+	/* cmd_list */
+	for (i = 0; i < instance->max_fw_cmds; i++)
 		kfree(fusion->cmd_list[i]);
 
-	/* Free the cmd_list buffer itself */
 	kfree(fusion->cmd_list);
-	fusion->cmd_list = NULL;
-
 }
 
 /**
- * megasas_create_frame_pool_fusion -	Creates DMA pool for cmd frames
+ * megasas_create_sg_sense_fusion -	Creates DMA pool for cmd frames
  * @instance:			Adapter soft state
  *
  */
-static int megasas_create_frame_pool_fusion(struct megasas_instance *instance)
+static int megasas_create_sg_sense_fusion(struct megasas_instance *instance)
 {
 	int i;
 	u32 max_cmd;
@@ -321,25 +348,17 @@ static int megasas_create_frame_pool_fus
 	max_cmd = instance->max_fw_cmds;
 
 
-	/*
-	 * Use DMA pool facility provided by PCI layer
-	 */
-
-	fusion->sg_dma_pool = pci_pool_create("sg_pool_fusion", instance->pdev,
-						instance->max_chain_frame_sz,
-						4, 0);
-	if (!fusion->sg_dma_pool) {
-		dev_printk(KERN_DEBUG, &instance->pdev->dev, "failed to setup request pool fusion\n");
-		return -ENOMEM;
-	}
-	fusion->sense_dma_pool = pci_pool_create("sense pool fusion",
-						 instance->pdev,
-						 SCSI_SENSE_BUFFERSIZE, 64, 0);
+	fusion->sg_dma_pool =
+			pci_pool_create("mr_sg", instance->pdev,
+				instance->max_chain_frame_sz, 4, 0);
+	/* SCSI_SENSE_BUFFERSIZE  = 96 bytes */
+	fusion->sense_dma_pool =
+			pci_pool_create("mr_sense", instance->pdev,
+				SCSI_SENSE_BUFFERSIZE, 64, 0);
 
-	if (!fusion->sense_dma_pool) {
-		dev_printk(KERN_DEBUG, &instance->pdev->dev, "failed to setup sense pool fusion\n");
-		pci_pool_destroy(fusion->sg_dma_pool);
-		fusion->sg_dma_pool = NULL;
+	if (!fusion->sense_dma_pool || !fusion->sg_dma_pool) {
+		dev_err(&instance->pdev->dev,
+			"Failed from %s %d\n",  __func__, __LINE__);
 		return -ENOMEM;
 	}
 
@@ -347,160 +366,280 @@ static int megasas_create_frame_pool_fus
 	 * Allocate and attach a frame to each of the commands in cmd_list
 	 */
 	for (i = 0; i < max_cmd; i++) {
-
 		cmd = fusion->cmd_list[i];
-
 		cmd->sg_frame = pci_pool_alloc(fusion->sg_dma_pool,
-					       GFP_KERNEL,
-					       &cmd->sg_frame_phys_addr);
+					GFP_KERNEL, &cmd->sg_frame_phys_addr);
 
 		cmd->sense = pci_pool_alloc(fusion->sense_dma_pool,
-					    GFP_KERNEL, &cmd->sense_phys_addr);
-		/*
-		 * megasas_teardown_frame_pool_fusion() takes care of freeing
-		 * whatever has been allocated
-		 */
+					GFP_KERNEL, &cmd->sense_phys_addr);
 		if (!cmd->sg_frame || !cmd->sense) {
-			dev_printk(KERN_DEBUG, &instance->pdev->dev, "pci_pool_alloc failed\n");
-			megasas_teardown_frame_pool_fusion(instance);
+			dev_err(&instance->pdev->dev,
+				"Failed from %s %d\n",  __func__, __LINE__);
 			return -ENOMEM;
 		}
 	}
 	return 0;
 }
 
-/**
- * megasas_alloc_cmds_fusion -	Allocates the command packets
- * @instance:		Adapter soft state
- *
- *
- * Each frame has a 32-bit field called context. This context is used to get
- * back the megasas_cmd_fusion from the frame when a frame gets completed
- * In this driver, the 32 bit values are the indices into an array cmd_list.
- * This array is used only to look up the megasas_cmd_fusion given the context.
- * The free commands themselves are maintained in a linked list called cmd_pool.
- *
- * cmds are formed in the io_request and sg_frame members of the
- * megasas_cmd_fusion. The context field is used to get a request descriptor
- * and is used as SMID of the cmd.
- * SMID value range is from 1 to max_fw_cmds.
- */
 int
-megasas_alloc_cmds_fusion(struct megasas_instance *instance)
+megasas_alloc_cmdlist_fusion(struct megasas_instance *instance)
 {
-	int i, j, count;
-	u32 max_cmd, io_frames_sz;
+	u32 max_cmd, i;
 	struct fusion_context *fusion;
-	struct megasas_cmd_fusion *cmd;
-	union MPI2_REPLY_DESCRIPTORS_UNION *reply_desc;
-	u32 offset;
-	dma_addr_t io_req_base_phys;
-	u8 *io_req_base;
 
 	fusion = instance->ctrl_context;
 
 	max_cmd = instance->max_fw_cmds;
 
+	/*
+	 * fusion->cmd_list is an array of struct megasas_cmd_fusion pointers.
+	 * Allocate the dynamic array first and then allocate individual
+	 * commands.
+	 */
+	fusion->cmd_list = kzalloc(sizeof(struct megasas_cmd_fusion *) * max_cmd,
+						GFP_KERNEL);
+	if (!fusion->cmd_list) {
+		dev_err(&instance->pdev->dev,
+			"Failed from %s %d\n",  __func__, __LINE__);
+		return -ENOMEM;
+	}
+
+	for (i = 0; i < max_cmd; i++) {
+		fusion->cmd_list[i] = kzalloc(sizeof(struct megasas_cmd_fusion),
+					      GFP_KERNEL);
+		if (!fusion->cmd_list[i]) {
+			dev_err(&instance->pdev->dev,
+				"Failed from %s %d\n",  __func__, __LINE__);
+			return -ENOMEM;
+		}
+	}
+	return 0;
+}
+int
+megasas_alloc_request_fusion(struct megasas_instance *instance)
+{
+	struct fusion_context *fusion;
+
+	fusion = instance->ctrl_context;
+
 	fusion->req_frames_desc =
 		dma_alloc_coherent(&instance->pdev->dev,
-				   fusion->request_alloc_sz,
-				   &fusion->req_frames_desc_phys, GFP_KERNEL);
-
+			fusion->request_alloc_sz,
+			&fusion->req_frames_desc_phys, GFP_KERNEL);
 	if (!fusion->req_frames_desc) {
-		dev_err(&instance->pdev->dev, "Could not allocate memory for "
-		       "request_frames\n");
-		goto fail_req_desc;
+		dev_err(&instance->pdev->dev,
+			"Failed from %s %d\n",  __func__, __LINE__);
+		return -ENOMEM;
 	}
 
+	fusion->io_request_frames_pool =
+			pci_pool_create("mr_ioreq", instance->pdev,
+				fusion->io_frames_alloc_sz, 16, 0);
+
+	if (!fusion->io_request_frames_pool) {
+		dev_err(&instance->pdev->dev,
+			"Failed from %s %d\n",  __func__, __LINE__);
+		return -ENOMEM;
+	}
+
+	fusion->io_request_frames =
+			pci_pool_alloc(fusion->io_request_frames_pool,
+				GFP_KERNEL, &fusion->io_request_frames_phys);
+	if (!fusion->io_request_frames) {
+		dev_err(&instance->pdev->dev,
+			"Failed from %s %d\n",  __func__, __LINE__);
+		return -ENOMEM;
+	}
+	return 0;
+}
+
+int
+megasas_alloc_reply_fusion(struct megasas_instance *instance)
+{
+	int i, count;
+	struct fusion_context *fusion;
+	union MPI2_REPLY_DESCRIPTORS_UNION *reply_desc;
+	fusion = instance->ctrl_context;
+
 	count = instance->msix_vectors > 0 ? instance->msix_vectors : 1;
 	fusion->reply_frames_desc_pool =
-		pci_pool_create("reply_frames pool", instance->pdev,
+			pci_pool_create("mr_reply", instance->pdev,
 				fusion->reply_alloc_sz * count, 16, 0);
 
 	if (!fusion->reply_frames_desc_pool) {
-		dev_err(&instance->pdev->dev, "Could not allocate memory for "
-		       "reply_frame pool\n");
-		goto fail_reply_desc;
+		dev_err(&instance->pdev->dev,
+			"Failed from %s %d\n",  __func__, __LINE__);
+		return -ENOMEM;
 	}
 
-	fusion->reply_frames_desc =
-		pci_pool_alloc(fusion->reply_frames_desc_pool, GFP_KERNEL,
-			       &fusion->reply_frames_desc_phys);
-	if (!fusion->reply_frames_desc) {
-		dev_err(&instance->pdev->dev, "Could not allocate memory for "
-		       "reply_frame pool\n");
-		pci_pool_destroy(fusion->reply_frames_desc_pool);
-		goto fail_reply_desc;
+	fusion->reply_frames_desc[0] =
+		pci_pool_alloc(fusion->reply_frames_desc_pool,
+			GFP_KERNEL, &fusion->reply_frames_desc_phys[0]);
+	if (!fusion->reply_frames_desc[0]) {
+		dev_err(&instance->pdev->dev,
+			"Failed from %s %d\n",  __func__, __LINE__);
+		return -ENOMEM;
 	}
-
-	reply_desc = fusion->reply_frames_desc;
+	reply_desc = fusion->reply_frames_desc[0];
 	for (i = 0; i < fusion->reply_q_depth * count; i++, reply_desc++)
 		reply_desc->Words = cpu_to_le64(ULLONG_MAX);
 
-	io_frames_sz = fusion->io_frames_alloc_sz;
+	/* This is not a rdpq mode, but driver still populate
+	 * reply_frame_desc array to use same msix index in ISR path.
+	 */
+	for (i = 0; i < (count - 1); i++)
+		fusion->reply_frames_desc[i + 1] =
+			fusion->reply_frames_desc[i] +
+			(fusion->reply_alloc_sz)/sizeof(union MPI2_REPLY_DESCRIPTORS_UNION);
 
-	fusion->io_request_frames_pool =
-		pci_pool_create("io_request_frames pool", instance->pdev,
-				fusion->io_frames_alloc_sz, 16, 0);
+	return 0;
+}
 
-	if (!fusion->io_request_frames_pool) {
-		dev_err(&instance->pdev->dev, "Could not allocate memory for "
-		       "io_request_frame pool\n");
-		goto fail_io_frames;
+int
+megasas_alloc_rdpq_fusion(struct megasas_instance *instance)
+{
+	int i, j, count;
+	struct fusion_context *fusion;
+	union MPI2_REPLY_DESCRIPTORS_UNION *reply_desc;
+
+	fusion = instance->ctrl_context;
+
+	fusion->rdpq_virt = pci_alloc_consistent(instance->pdev,
+				sizeof(struct MPI2_IOC_INIT_RDPQ_ARRAY_ENTRY) * MAX_MSIX_QUEUES_FUSION,
+				&fusion->rdpq_phys);
+	if (!fusion->rdpq_virt) {
+		dev_err(&instance->pdev->dev,
+			"Failed from %s %d\n",  __func__, __LINE__);
+		return -ENOMEM;
 	}
 
-	fusion->io_request_frames =
-		pci_pool_alloc(fusion->io_request_frames_pool, GFP_KERNEL,
-			       &fusion->io_request_frames_phys);
-	if (!fusion->io_request_frames) {
-		dev_err(&instance->pdev->dev, "Could not allocate memory for "
-		       "io_request_frames frames\n");
-		pci_pool_destroy(fusion->io_request_frames_pool);
-		goto fail_io_frames;
+	memset(fusion->rdpq_virt, 0,
+			sizeof(struct MPI2_IOC_INIT_RDPQ_ARRAY_ENTRY) * MAX_MSIX_QUEUES_FUSION);
+	count = instance->msix_vectors > 0 ? instance->msix_vectors : 1;
+	fusion->reply_frames_desc_pool = pci_pool_create("mr_rdpq",
+							 instance->pdev, fusion->reply_alloc_sz, 16, 0);
+
+	if (!fusion->reply_frames_desc_pool) {
+		dev_err(&instance->pdev->dev,
+			"Failed from %s %d\n",  __func__, __LINE__);
+		return -ENOMEM;
 	}
 
-	/*
-	 * fusion->cmd_list is an array of struct megasas_cmd_fusion pointers.
-	 * Allocate the dynamic array first and then allocate individual
-	 * commands.
-	 */
-	fusion->cmd_list = kzalloc(sizeof(struct megasas_cmd_fusion *)
-				   * max_cmd, GFP_KERNEL);
+	for (i = 0; i < count; i++) {
+		fusion->reply_frames_desc[i] =
+				pci_pool_alloc(fusion->reply_frames_desc_pool,
+					GFP_KERNEL, &fusion->reply_frames_desc_phys[i]);
+		if (!fusion->reply_frames_desc[i]) {
+			dev_err(&instance->pdev->dev,
+				"Failed from %s %d\n",  __func__, __LINE__);
+			return -ENOMEM;
+		}
 
-	if (!fusion->cmd_list) {
-		dev_printk(KERN_DEBUG, &instance->pdev->dev, "out of memory. Could not alloc "
-		       "memory for cmd_list_fusion\n");
-		goto fail_cmd_list;
+		fusion->rdpq_virt[i].RDPQBaseAddress =
+			fusion->reply_frames_desc_phys[i];
+
+		reply_desc = fusion->reply_frames_desc[i];
+		for (j = 0; j < fusion->reply_q_depth; j++, reply_desc++)
+			reply_desc->Words = cpu_to_le64(ULLONG_MAX);
 	}
+	return 0;
+}
 
-	max_cmd = instance->max_fw_cmds;
-	for (i = 0; i < max_cmd; i++) {
-		fusion->cmd_list[i] = kmalloc(sizeof(struct megasas_cmd_fusion),
-					      GFP_KERNEL);
-		if (!fusion->cmd_list[i]) {
-			dev_err(&instance->pdev->dev, "Could not alloc cmd list fusion\n");
+static void
+megasas_free_rdpq_fusion(struct megasas_instance *instance) {
 
-			for (j = 0; j < i; j++)
-				kfree(fusion->cmd_list[j]);
+	int i;
+	struct fusion_context *fusion;
 
-			kfree(fusion->cmd_list);
-			fusion->cmd_list = NULL;
-			goto fail_cmd_list;
-		}
+	fusion = instance->ctrl_context;
+
+	for (i = 0; i < MAX_MSIX_QUEUES_FUSION; i++) {
+		if (fusion->reply_frames_desc[i])
+			pci_pool_free(fusion->reply_frames_desc_pool,
+				fusion->reply_frames_desc[i],
+				fusion->reply_frames_desc_phys[i]);
 	}
 
-	/* The first 256 bytes (SMID 0) is not used. Don't add to cmd list */
-	io_req_base = fusion->io_request_frames +
-		MEGA_MPI2_RAID_DEFAULT_IO_FRAME_SIZE;
-	io_req_base_phys = fusion->io_request_frames_phys +
-		MEGA_MPI2_RAID_DEFAULT_IO_FRAME_SIZE;
+	if (fusion->reply_frames_desc_pool)
+		pci_pool_destroy(fusion->reply_frames_desc_pool);
+
+	if (fusion->rdpq_virt)
+		pci_free_consistent(instance->pdev,
+			sizeof(struct MPI2_IOC_INIT_RDPQ_ARRAY_ENTRY) * MAX_MSIX_QUEUES_FUSION,
+			fusion->rdpq_virt, fusion->rdpq_phys);
+}
+
+static void
+megasas_free_reply_fusion(struct megasas_instance *instance) {
+
+	struct fusion_context *fusion;
+
+	fusion = instance->ctrl_context;
+
+	if (fusion->reply_frames_desc[0])
+		pci_pool_free(fusion->reply_frames_desc_pool,
+			fusion->reply_frames_desc[0],
+			fusion->reply_frames_desc_phys[0]);
+
+	if (fusion->reply_frames_desc_pool)
+		pci_pool_destroy(fusion->reply_frames_desc_pool);
+
+}
+
+
+/**
+ * megasas_alloc_cmds_fusion -	Allocates the command packets
+ * @instance:		Adapter soft state
+ *
+ *
+ * Each frame has a 32-bit field called context. This context is used to get
+ * back the megasas_cmd_fusion from the frame when a frame gets completed
+ * In this driver, the 32 bit values are the indices into an array cmd_list.
+ * This array is used only to look up the megasas_cmd_fusion given the context.
+ * The free commands themselves are maintained in a linked list called cmd_pool.
+ *
+ * cmds are formed in the io_request and sg_frame members of the
+ * megasas_cmd_fusion. The context field is used to get a request descriptor
+ * and is used as SMID of the cmd.
+ * SMID value range is from 1 to max_fw_cmds.
+ */
+int
+megasas_alloc_cmds_fusion(struct megasas_instance *instance)
+{
+	int i;
+	struct fusion_context *fusion;
+	struct megasas_cmd_fusion *cmd;
+	u32 offset;
+	dma_addr_t io_req_base_phys;
+	u8 *io_req_base;
+
+
+	fusion = instance->ctrl_context;
+
+	if (megasas_alloc_cmdlist_fusion(instance))
+		goto fail_exit;
+
+	if (megasas_alloc_request_fusion(instance))
+		goto fail_exit;
+
+	if (instance->is_rdpq) {
+		if (megasas_alloc_rdpq_fusion(instance))
+			goto fail_exit;
+	} else
+		if (megasas_alloc_reply_fusion(instance))
+			goto fail_exit;
+
+
+	/* The first 256 bytes (SMID 0) is not used. Don't add to the cmd list */
+	io_req_base = fusion->io_request_frames + MEGA_MPI2_RAID_DEFAULT_IO_FRAME_SIZE;
+	io_req_base_phys = fusion->io_request_frames_phys + MEGA_MPI2_RAID_DEFAULT_IO_FRAME_SIZE;
 
 	/*
 	 * Add all the commands to command pool (fusion->cmd_pool)
 	 */
 
 	/* SMID 0 is reserved. Set SMID/index from 1 */
-	for (i = 0; i < max_cmd; i++) {
+	for (i = 0; i < instance->max_fw_cmds; i++) {
 		cmd = fusion->cmd_list[i];
 		offset = MEGA_MPI2_RAID_DEFAULT_IO_FRAME_SIZE * i;
 		memset(cmd, 0, sizeof(struct megasas_cmd_fusion));
@@ -518,35 +657,13 @@ megasas_alloc_cmds_fusion(struct megasas
 		cmd->io_request_phys_addr = io_req_base_phys + offset;
 	}
 
-	/*
-	 * Create a frame pool and assign one frame to each cmd
-	 */
-	if (megasas_create_frame_pool_fusion(instance)) {
-		dev_printk(KERN_DEBUG, &instance->pdev->dev, "Error creating frame DMA pool\n");
-		megasas_free_cmds_fusion(instance);
-		goto fail_req_desc;
-	}
+	if (megasas_create_sg_sense_fusion(instance))
+		goto fail_exit;
 
 	return 0;
 
-fail_cmd_list:
-	pci_pool_free(fusion->io_request_frames_pool, fusion->io_request_frames,
-		      fusion->io_request_frames_phys);
-	pci_pool_destroy(fusion->io_request_frames_pool);
-fail_io_frames:
-	dma_free_coherent(&instance->pdev->dev, fusion->request_alloc_sz,
-			  fusion->reply_frames_desc,
-			  fusion->reply_frames_desc_phys);
-	pci_pool_free(fusion->reply_frames_desc_pool,
-		      fusion->reply_frames_desc,
-		      fusion->reply_frames_desc_phys);
-	pci_pool_destroy(fusion->reply_frames_desc_pool);
-
-fail_reply_desc:
-	dma_free_coherent(&instance->pdev->dev, fusion->request_alloc_sz,
-			  fusion->req_frames_desc,
-			  fusion->req_frames_desc_phys);
-fail_req_desc:
+fail_exit:
+	megasas_free_cmds_fusion(instance);
 	return -ENOMEM;
 }
 
@@ -576,11 +693,12 @@ wait_and_poll(struct megasas_instance *i
 		msleep(20);
 	}
 
-	if (frame_hdr->cmd_status == 0xff)
-		return -ETIME;
-
-	return (frame_hdr->cmd_status == MFI_STAT_OK) ?
-		0 : 1;
+	if (frame_hdr->cmd_status == MFI_STAT_INVALID_STATUS)
+		return DCMD_TIMEOUT;
+	else if (frame_hdr->cmd_status == MFI_STAT_OK)
+		return DCMD_SUCCESS;
+	else
+		return DCMD_FAILED;
 }
 
 /**
@@ -593,16 +711,17 @@ int
 megasas_ioc_init_fusion(struct megasas_instance *instance)
 {
 	struct megasas_init_frame *init_frame;
-	struct MPI2_IOC_INIT_REQUEST *IOCInitMessage;
+	struct MPI2_IOC_INIT_REQUEST *IOCInitMessage = NULL;
 	dma_addr_t	ioc_init_handle;
 	struct megasas_cmd *cmd;
-	u8 ret;
+	u8 ret, cur_rdpq_mode;
 	struct fusion_context *fusion;
 	union MEGASAS_REQUEST_DESCRIPTOR_UNION req_desc;
 	int i;
 	struct megasas_header *frame_hdr;
 	const char *sys_info;
 	MFI_CAPABILITIES *drv_ops;
+	u32 scratch_pad_2;
 
 	fusion = instance->ctrl_context;
 
@@ -614,6 +733,18 @@ megasas_ioc_init_fusion(struct megasas_i
 		goto fail_get_cmd;
 	}
 
+	scratch_pad_2 = readl
+		(&instance->reg_set->outbound_scratch_pad_2);
+
+	cur_rdpq_mode = (scratch_pad_2 & MR_RDPQ_MODE_OFFSET) ? 1 : 0;
+
+	if (instance->is_rdpq && !cur_rdpq_mode) {
+		dev_err(&instance->pdev->dev, "Firmware downgrade *NOT SUPPORTED*"
+			" from RDPQ mode to non RDPQ mode\n");
+		ret = 1;
+		goto fail_fw_init;
+	}
+
 	IOCInitMessage =
 	  dma_alloc_coherent(&instance->pdev->dev,
 			     sizeof(struct MPI2_IOC_INIT_REQUEST),
@@ -635,7 +766,11 @@ megasas_ioc_init_fusion(struct megasas_i
 	IOCInitMessage->SystemRequestFrameSize = cpu_to_le16(MEGA_MPI2_RAID_DEFAULT_IO_FRAME_SIZE / 4);
 
 	IOCInitMessage->ReplyDescriptorPostQueueDepth = cpu_to_le16(fusion->reply_q_depth);
-	IOCInitMessage->ReplyDescriptorPostQueueAddress	= cpu_to_le64(fusion->reply_frames_desc_phys);
+	IOCInitMessage->ReplyDescriptorPostQueueAddress = instance->is_rdpq ?
+			cpu_to_le64(fusion->rdpq_phys) :
+			cpu_to_le64(fusion->reply_frames_desc_phys[0]);
+	IOCInitMessage->MsgFlags = instance->is_rdpq ?
+			MPI2_IOCINIT_MSGFLAG_RDPQ_ARRAY_MODE : 0;
 	IOCInitMessage->SystemRequestFrameBaseAddress = cpu_to_le64(fusion->io_request_frames_phys);
 	IOCInitMessage->HostMSIxVectors = instance->msix_vectors;
 	init_frame = (struct megasas_init_frame *)cmd->frame;
@@ -665,6 +800,11 @@ megasas_ioc_init_fusion(struct megasas_i
 	if (instance->max_chain_frame_sz > MEGASAS_CHAIN_FRAME_SZ_MIN)
 		drv_ops->mfi_capabilities.support_ext_io_size = 1;
 
+	drv_ops->mfi_capabilities.support_fp_rlbypass = 1;
+	if (!dual_qdepth_disable)
+		drv_ops->mfi_capabilities.support_ext_queue_depth = 1;
+
+	drv_ops->mfi_capabilities.support_qd_throttling = 1;
 	/* Convert capability to LE32 */
 	cpu_to_le32s((u32 *)&init_frame->driver_operations.mfi_capabilities);
 
@@ -784,7 +924,8 @@ megasas_sync_pd_seq_num(struct megasas_i
 
 	/* Below code is only for non pended DCMD */
 	if (instance->ctrl_context && !instance->mask_interrupts)
-		ret = megasas_issue_blocked_cmd(instance, cmd, 60);
+		ret = megasas_issue_blocked_cmd(instance, cmd,
+			MFI_IO_TIMEOUT_SECS);
 	else
 		ret = megasas_issue_polled(instance, cmd);
 
@@ -795,7 +936,10 @@ megasas_sync_pd_seq_num(struct megasas_i
 		ret = -EINVAL;
 	}
 
-	if (!ret)
+	if (ret == DCMD_TIMEOUT && instance->ctrl_context)
+		megaraid_sas_kill_hba(instance);
+
+	if (ret == DCMD_SUCCESS)
 		instance->pd_seq_map_id++;
 
 	megasas_return_cmd(instance, cmd);
@@ -875,10 +1019,13 @@ megasas_get_ld_map_info(struct megasas_i
 
 	if (instance->ctrl_context && !instance->mask_interrupts)
 		ret = megasas_issue_blocked_cmd(instance, cmd,
-			MEGASAS_BLOCKED_CMD_TIMEOUT);
+			MFI_IO_TIMEOUT_SECS);
 	else
 		ret = megasas_issue_polled(instance, cmd);
 
+	if (ret == DCMD_TIMEOUT && instance->ctrl_context)
+		megaraid_sas_kill_hba(instance);
+
 	megasas_return_cmd(instance, cmd);
 
 	return ret;
@@ -1072,12 +1219,7 @@ megasas_init_adapter_fusion(struct megas
 
 	reg_set = instance->reg_set;
 
-	/*
-	 * Get various operational parameters from status register
-	 */
-	instance->max_fw_cmds =
-		instance->instancet->read_fw_status_reg(reg_set) & 0x00FFFF;
-	instance->max_fw_cmds = min(instance->max_fw_cmds, (u16)1008);
+	megasas_fusion_update_can_queue(instance, PROBE_CONTEXT);
 
 	/*
 	 * Reduce the max supported cmds by 1. This is to ensure that the
@@ -1658,7 +1800,7 @@ megasas_build_ldio_fusion(struct megasas
 				   local_map_ptr, start_lba_lo);
 		io_request->Function = MPI2_FUNCTION_SCSI_IO_REQUEST;
 		cmd->request_desc->SCSIIO.RequestFlags =
-			(MPI2_REQ_DESCRIPT_FLAGS_HIGH_PRIORITY
+			(MPI2_REQ_DESCRIPT_FLAGS_FP_IO
 			 << MEGASAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT);
 		if (fusion->adapter_type == INVADER_SERIES) {
 			if (io_request->RaidContext.regLockFlags ==
@@ -1702,8 +1844,8 @@ megasas_build_ldio_fusion(struct megasas
 			(MEGASAS_REQ_DESCRIPT_FLAGS_LD_IO
 			 << MEGASAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT);
 		if (fusion->adapter_type == INVADER_SERIES) {
-			if (io_request->RaidContext.regLockFlags ==
-			    REGION_TYPE_UNUSED)
+			if (io_info.do_fp_rlbypass ||
+				(io_request->RaidContext.regLockFlags == REGION_TYPE_UNUSED))
 				cmd->request_desc->SCSIIO.RequestFlags =
 					(MEGASAS_REQ_DESCRIPT_FLAGS_NO_LOCK <<
 					MEGASAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT);
@@ -1791,7 +1933,7 @@ static void megasas_build_ld_nonrw_fusio
 
 		/* build request descriptor */
 		cmd->request_desc->SCSIIO.RequestFlags =
-			(MPI2_REQ_DESCRIPT_FLAGS_HIGH_PRIORITY <<
+			(MPI2_REQ_DESCRIPT_FLAGS_FP_IO <<
 			MEGASAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT);
 		cmd->request_desc->SCSIIO.DevHandle = devHandle;
 
@@ -1897,7 +2039,7 @@ megasas_build_syspd_fusion(struct megasa
 				cpu_to_le16(MPI25_SAS_DEVICE0_FLAGS_ENABLED_FAST_PATH);
 		}
 		cmd->request_desc->SCSIIO.RequestFlags =
-			(MPI2_REQ_DESCRIPT_FLAGS_HIGH_PRIORITY <<
+			(MPI2_REQ_DESCRIPT_FLAGS_FP_IO <<
 				MEGASAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT);
 	}
 }
@@ -2035,13 +2177,21 @@ megasas_build_and_issue_cmd_fusion(struc
 
 	fusion = instance->ctrl_context;
 
+	if ((megasas_cmd_type(scmd) == READ_WRITE_LDIO) &&
+		instance->ldio_threshold &&
+		(atomic_inc_return(&instance->ldio_outstanding) >
+		instance->ldio_threshold)) {
+		atomic_dec(&instance->ldio_outstanding);
+		return SCSI_MLQUEUE_DEVICE_BUSY;
+	}
+
 	cmd = megasas_get_cmd_fusion(instance, scmd->request->tag);
 
 	index = cmd->index;
 
 	req_desc = megasas_get_request_descriptor(instance, index-1);
 	if (!req_desc)
-		return 1;
+		return SCSI_MLQUEUE_HOST_BUSY;
 
 	req_desc->Words = 0;
 	cmd->request_desc = req_desc;
@@ -2050,7 +2200,7 @@ megasas_build_and_issue_cmd_fusion(struc
 		megasas_return_cmd_fusion(instance, cmd);
 		dev_err(&instance->pdev->dev, "Error building command\n");
 		cmd->request_desc = NULL;
-		return 1;
+		return SCSI_MLQUEUE_HOST_BUSY;
 	}
 
 	req_desc = cmd->request_desc;
@@ -2092,16 +2242,16 @@ complete_cmd_fusion(struct megasas_insta
 	struct LD_LOAD_BALANCE_INFO *lbinfo;
 	int threshold_reply_count = 0;
 	struct scsi_cmnd *scmd_local = NULL;
+	struct MR_TASK_MANAGE_REQUEST *mr_tm_req;
+	struct MPI2_SCSI_TASK_MANAGE_REQUEST *mpi_tm_req;
 
 	fusion = instance->ctrl_context;
 
-	if (instance->adprecovery == MEGASAS_HW_CRITICAL_ERROR)
+	if (atomic_read(&instance->adprecovery) == MEGASAS_HW_CRITICAL_ERROR)
 		return IRQ_HANDLED;
 
-	desc = fusion->reply_frames_desc;
-	desc += ((MSIxIndex * fusion->reply_alloc_sz)/
-		 sizeof(union MPI2_REPLY_DESCRIPTORS_UNION)) +
-		fusion->last_reply_idx[MSIxIndex];
+	desc = fusion->reply_frames_desc[MSIxIndex] +
+				fusion->last_reply_idx[MSIxIndex];
 
 	reply_desc = (struct MPI2_SCSI_IO_SUCCESS_REPLY_DESCRIPTOR *)desc;
 
@@ -2133,6 +2283,16 @@ complete_cmd_fusion(struct megasas_insta
 		extStatus = scsi_io_req->RaidContext.exStatus;
 
 		switch (scsi_io_req->Function) {
+		case MPI2_FUNCTION_SCSI_TASK_MGMT:
+			mr_tm_req = (struct MR_TASK_MANAGE_REQUEST *)
+						cmd_fusion->io_request;
+			mpi_tm_req = (struct MPI2_SCSI_TASK_MANAGE_REQUEST *)
+						&mr_tm_req->TmRequest;
+			dev_dbg(&instance->pdev->dev, "TM completion:"
+				"type: 0x%x TaskMID: 0x%x\n",
+				mpi_tm_req->TaskType, mpi_tm_req->TaskMID);
+			complete(&cmd_fusion->done);
+			break;
 		case MPI2_FUNCTION_SCSI_IO_REQUEST:  /*Fast Path IO.*/
 			/* Update load balancing info */
 			device_id = MEGASAS_DEV_INDEX(scmd_local);
@@ -2155,6 +2315,8 @@ complete_cmd_fusion(struct megasas_insta
 			map_cmd_status(cmd_fusion, status, extStatus);
 			scsi_io_req->RaidContext.status = 0;
 			scsi_io_req->RaidContext.exStatus = 0;
+			if (megasas_cmd_type(scmd_local) == READ_WRITE_LDIO)
+				atomic_dec(&instance->ldio_outstanding);
 			megasas_return_cmd_fusion(instance, cmd_fusion);
 			scsi_dma_unmap(scmd_local);
 			scmd_local->scsi_done(scmd_local);
@@ -2186,9 +2348,7 @@ complete_cmd_fusion(struct megasas_insta
 
 		/* Get the next reply descriptor */
 		if (!fusion->last_reply_idx[MSIxIndex])
-			desc = fusion->reply_frames_desc +
-				((MSIxIndex * fusion->reply_alloc_sz)/
-				 sizeof(union MPI2_REPLY_DESCRIPTORS_UNION));
+			desc = fusion->reply_frames_desc[MSIxIndex];
 		else
 			desc++;
 
@@ -2254,7 +2414,7 @@ megasas_complete_cmd_dpc_fusion(unsigned
 
 	/* If we have already declared adapter dead, donot complete cmds */
 	spin_lock_irqsave(&instance->hba_lock, flags);
-	if (instance->adprecovery == MEGASAS_HW_CRITICAL_ERROR) {
+	if (atomic_read(&instance->adprecovery) == MEGASAS_HW_CRITICAL_ERROR) {
 		spin_unlock_irqrestore(&instance->hba_lock, flags);
 		return;
 	}
@@ -2411,7 +2571,7 @@ build_mpt_cmd(struct megasas_instance *i
  * @cmd:			mfi cmd pointer
  *
  */
-void
+int
 megasas_issue_dcmd_fusion(struct megasas_instance *instance,
 			  struct megasas_cmd *cmd)
 {
@@ -2419,10 +2579,13 @@ megasas_issue_dcmd_fusion(struct megasas
 
 	req_desc = build_mpt_cmd(instance, cmd);
 	if (!req_desc) {
-		dev_err(&instance->pdev->dev, "Couldn't issue MFI pass thru cmd\n");
-		return;
+		dev_info(&instance->pdev->dev, "Failed from %s %d\n",
+					__func__, __LINE__);
+		return DCMD_NOT_FIRED;
 	}
+
 	megasas_fire_cmd_fusion(instance, req_desc);
+	return DCMD_SUCCESS;
 }
 
 /**
@@ -2437,7 +2600,7 @@ megasas_release_fusion(struct megasas_in
 
 	iounmap(instance->reg_set);
 
-	pci_release_selected_regions(instance->pdev, instance->bar);
+	pci_release_selected_regions(instance->pdev, 1<<instance->bar);
 }
 
 /**
@@ -2583,7 +2746,7 @@ megasas_check_reset_fusion(struct megasa
 
 /* This function waits for outstanding commands on fusion to complete */
 int megasas_wait_for_outstanding_fusion(struct megasas_instance *instance,
-					int iotimeout, int *convert)
+					int reason, int *convert)
 {
 	int i, outstanding, retval = 0, hb_seconds_missed = 0;
 	u32 fw_state;
@@ -2599,14 +2762,22 @@ int megasas_wait_for_outstanding_fusion(
 			retval = 1;
 			goto out;
 		}
+
+		if (reason == MFI_IO_TIMEOUT_OCR) {
+			dev_info(&instance->pdev->dev,
+				"MFI IO is timed out, initiating OCR\n");
+			retval = 1;
+			goto out;
+		}
+
 		/* If SR-IOV VF mode & heartbeat timeout, don't wait */
-		if (instance->requestorId && !iotimeout) {
+		if (instance->requestorId && !reason) {
 			retval = 1;
 			goto out;
 		}
 
 		/* If SR-IOV VF mode & I/O timeout, check for HB timeout */
-		if (instance->requestorId && iotimeout) {
+		if (instance->requestorId && reason) {
 			if (instance->hb_host_mem->HB.fwCounter !=
 			    instance->hb_host_mem->HB.driverCounter) {
 				instance->hb_host_mem->HB.driverCounter =
@@ -2655,17 +2826,18 @@ out:
 
 void  megasas_reset_reply_desc(struct megasas_instance *instance)
 {
-	int i, count;
+	int i, j, count;
 	struct fusion_context *fusion;
 	union MPI2_REPLY_DESCRIPTORS_UNION *reply_desc;
 
 	fusion = instance->ctrl_context;
 	count = instance->msix_vectors > 0 ? instance->msix_vectors : 1;
-	for (i = 0 ; i < count ; i++)
+	for (i = 0 ; i < count ; i++) {
 		fusion->last_reply_idx[i] = 0;
-	reply_desc = fusion->reply_frames_desc;
-	for (i = 0 ; i < fusion->reply_q_depth * count; i++, reply_desc++)
-		reply_desc->Words = cpu_to_le64(ULLONG_MAX);
+		reply_desc = fusion->reply_frames_desc[i];
+		for (j = 0 ; j < fusion->reply_q_depth; j++, reply_desc++)
+			reply_desc->Words = cpu_to_le64(ULLONG_MAX);
+	}
 }
 
 /*
@@ -2680,6 +2852,7 @@ void megasas_refire_mgmt_cmd(struct mega
 	struct megasas_cmd *cmd_mfi;
 	union MEGASAS_REQUEST_DESCRIPTOR_UNION *req_desc;
 	u16 smid;
+	bool refire_cmd = 0;
 
 	fusion = instance->ctrl_context;
 
@@ -2695,42 +2868,500 @@ void megasas_refire_mgmt_cmd(struct mega
 			continue;
 		req_desc = megasas_get_request_descriptor
 					(instance, smid - 1);
-		if (req_desc && ((cmd_mfi->frame->dcmd.opcode !=
+		refire_cmd = req_desc && ((cmd_mfi->frame->dcmd.opcode !=
 				cpu_to_le32(MR_DCMD_LD_MAP_GET_INFO)) &&
 				 (cmd_mfi->frame->dcmd.opcode !=
-				cpu_to_le32(MR_DCMD_SYSTEM_PD_MAP_GET_INFO))))
+				cpu_to_le32(MR_DCMD_SYSTEM_PD_MAP_GET_INFO)))
+				&& !(cmd_mfi->flags & DRV_DCMD_SKIP_REFIRE);
+		if (refire_cmd)
 			megasas_fire_cmd_fusion(instance, req_desc);
 		else
 			megasas_return_cmd(instance, cmd_mfi);
 	}
 }
 
+/*
+ * megasas_track_scsiio : Track SCSI IOs outstanding to a SCSI device
+ * @instance: per adapter struct
+ * @channel: the channel assigned by the OS
+ * @id: the id assigned by the OS
+ *
+ * Returns SUCCESS if no IOs pending to SCSI device, else return FAILED
+ */
+
+static int megasas_track_scsiio(struct megasas_instance *instance,
+		int id, int channel)
+{
+	int i, found = 0;
+	struct megasas_cmd_fusion *cmd_fusion;
+	struct fusion_context *fusion;
+	fusion = instance->ctrl_context;
+
+	for (i = 0 ; i < instance->max_scsi_cmds; i++) {
+		cmd_fusion = fusion->cmd_list[i];
+		if (cmd_fusion->scmd &&
+			(cmd_fusion->scmd->device->id == id &&
+			cmd_fusion->scmd->device->channel == channel)) {
+			dev_info(&instance->pdev->dev,
+				"SCSI commands pending to target"
+				"channel %d id %d \tSMID: 0x%x\n",
+				channel, id, cmd_fusion->index);
+			scsi_print_command(cmd_fusion->scmd);
+			found = 1;
+			break;
+		}
+	}
+
+	return found ? FAILED : SUCCESS;
+}
+
+/**
+ * megasas_tm_response_code - translation of device response code
+ * @ioc: per adapter object
+ * @mpi_reply: MPI reply returned by firmware
+ *
+ * Return nothing.
+ */
+static void
+megasas_tm_response_code(struct megasas_instance *instance,
+		struct MPI2_SCSI_TASK_MANAGE_REPLY *mpi_reply)
+{
+	char *desc;
+
+	switch (mpi_reply->ResponseCode) {
+	case MPI2_SCSITASKMGMT_RSP_TM_COMPLETE:
+		desc = "task management request completed";
+		break;
+	case MPI2_SCSITASKMGMT_RSP_INVALID_FRAME:
+		desc = "invalid frame";
+		break;
+	case MPI2_SCSITASKMGMT_RSP_TM_NOT_SUPPORTED:
+		desc = "task management request not supported";
+		break;
+	case MPI2_SCSITASKMGMT_RSP_TM_FAILED:
+		desc = "task management request failed";
+		break;
+	case MPI2_SCSITASKMGMT_RSP_TM_SUCCEEDED:
+		desc = "task management request succeeded";
+		break;
+	case MPI2_SCSITASKMGMT_RSP_TM_INVALID_LUN:
+		desc = "invalid lun";
+		break;
+	case 0xA:
+		desc = "overlapped tag attempted";
+		break;
+	case MPI2_SCSITASKMGMT_RSP_IO_QUEUED_ON_IOC:
+		desc = "task queued, however not sent to target";
+		break;
+	default:
+		desc = "unknown";
+		break;
+	}
+	dev_dbg(&instance->pdev->dev, "response_code(%01x): %s\n",
+		mpi_reply->ResponseCode, desc);
+	dev_dbg(&instance->pdev->dev,
+		"TerminationCount/DevHandle/Function/TaskType/IOCStat/IOCLoginfo"
+		" 0x%x/0x%x/0x%x/0x%x/0x%x/0x%x\n",
+		mpi_reply->TerminationCount, mpi_reply->DevHandle,
+		mpi_reply->Function, mpi_reply->TaskType,
+		mpi_reply->IOCStatus, mpi_reply->IOCLogInfo);
+}
+
+/**
+ * megasas_issue_tm - main routine for sending tm requests
+ * @instance: per adapter struct
+ * @device_handle: device handle
+ * @channel: the channel assigned by the OS
+ * @id: the id assigned by the OS
+ * @type: MPI2_SCSITASKMGMT_TASKTYPE__XXX (defined in megaraid_sas_fusion.c)
+ * @smid_task: smid assigned to the task
+ * @m_type: TM_MUTEX_ON or TM_MUTEX_OFF
+ * Context: user
+ *
+ * MegaRaid use MPT interface for Task Magement request.
+ * A generic API for sending task management requests to firmware.
+ *
+ * Return SUCCESS or FAILED.
+ */
+static int
+megasas_issue_tm(struct megasas_instance *instance, u16 device_handle,
+	uint channel, uint id, u16 smid_task, u8 type)
+{
+	struct MR_TASK_MANAGE_REQUEST *mr_request;
+	struct MPI2_SCSI_TASK_MANAGE_REQUEST *mpi_request;
+	unsigned long timeleft;
+	struct megasas_cmd_fusion *cmd_fusion;
+	struct megasas_cmd *cmd_mfi;
+	union MEGASAS_REQUEST_DESCRIPTOR_UNION *req_desc;
+	struct fusion_context *fusion;
+	struct megasas_cmd_fusion *scsi_lookup;
+	int rc;
+	struct MPI2_SCSI_TASK_MANAGE_REPLY *mpi_reply;
+
+	fusion = instance->ctrl_context;
+
+	cmd_mfi = megasas_get_cmd(instance);
+
+	if (!cmd_mfi) {
+		dev_err(&instance->pdev->dev, "Failed from %s %d\n",
+			__func__, __LINE__);
+		return -ENOMEM;
+	}
+
+	cmd_fusion = megasas_get_cmd_fusion(instance,
+			instance->max_scsi_cmds + cmd_mfi->index);
+
+	/*  Save the smid. To be used for returning the cmd */
+	cmd_mfi->context.smid = cmd_fusion->index;
+
+	req_desc = megasas_get_request_descriptor(instance,
+			(cmd_fusion->index - 1));
+	if (!req_desc) {
+		dev_err(&instance->pdev->dev, "Failed from %s %d\n",
+			__func__, __LINE__);
+		megasas_return_cmd(instance, cmd_mfi);
+		return -ENOMEM;
+	}
+
+	cmd_fusion->request_desc = req_desc;
+	req_desc->Words = 0;
+
+	scsi_lookup = fusion->cmd_list[smid_task - 1];
+
+	mr_request = (struct MR_TASK_MANAGE_REQUEST *) cmd_fusion->io_request;
+	memset(mr_request, 0, sizeof(struct MR_TASK_MANAGE_REQUEST));
+	mpi_request = (struct MPI2_SCSI_TASK_MANAGE_REQUEST *) &mr_request->TmRequest;
+	mpi_request->Function = MPI2_FUNCTION_SCSI_TASK_MGMT;
+	mpi_request->DevHandle = cpu_to_le16(device_handle);
+	mpi_request->TaskType = type;
+	mpi_request->TaskMID = cpu_to_le16(smid_task);
+	mpi_request->LUN[1] = 0;
+
+
+	req_desc = cmd_fusion->request_desc;
+	req_desc->HighPriority.SMID = cpu_to_le16(cmd_fusion->index);
+	req_desc->HighPriority.RequestFlags =
+		(MPI2_REQ_DESCRIPT_FLAGS_HIGH_PRIORITY <<
+		MEGASAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT);
+	req_desc->HighPriority.MSIxIndex =  0;
+	req_desc->HighPriority.LMID = 0;
+	req_desc->HighPriority.Reserved1 = 0;
+
+	if (channel < MEGASAS_MAX_PD_CHANNELS)
+		mr_request->tmReqFlags.isTMForPD = 1;
+	else
+		mr_request->tmReqFlags.isTMForLD = 1;
+
+	init_completion(&cmd_fusion->done);
+	megasas_fire_cmd_fusion(instance, req_desc);
+
+	timeleft = wait_for_completion_timeout(&cmd_fusion->done, 50 * HZ);
+
+	if (!timeleft) {
+		dev_err(&instance->pdev->dev,
+			"task mgmt type 0x%x timed out\n", type);
+		cmd_mfi->flags |= DRV_DCMD_SKIP_REFIRE;
+		mutex_unlock(&instance->reset_mutex);
+		rc = megasas_reset_fusion(instance->host, MFI_IO_TIMEOUT_OCR);
+		mutex_lock(&instance->reset_mutex);
+		return rc;
+	}
+
+	mpi_reply = (struct MPI2_SCSI_TASK_MANAGE_REPLY *) &mr_request->TMReply;
+	megasas_tm_response_code(instance, mpi_reply);
+
+	megasas_return_cmd(instance, cmd_mfi);
+	rc = SUCCESS;
+	switch (type) {
+	case MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK:
+		if (scsi_lookup->scmd == NULL)
+			break;
+		else {
+			instance->instancet->disable_intr(instance);
+			msleep(1000);
+			megasas_complete_cmd_dpc_fusion
+					((unsigned long)instance);
+			instance->instancet->enable_intr(instance);
+			if (scsi_lookup->scmd == NULL)
+				break;
+		}
+		rc = FAILED;
+		break;
+
+	case MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET:
+		if ((channel == 0xFFFFFFFF) && (id == 0xFFFFFFFF))
+			break;
+		instance->instancet->disable_intr(instance);
+		msleep(1000);
+		megasas_complete_cmd_dpc_fusion
+				((unsigned long)instance);
+		rc = megasas_track_scsiio(instance, id, channel);
+		instance->instancet->enable_intr(instance);
+
+		break;
+	case MPI2_SCSITASKMGMT_TASKTYPE_ABRT_TASK_SET:
+	case MPI2_SCSITASKMGMT_TASKTYPE_QUERY_TASK:
+		break;
+	default:
+		rc = FAILED;
+		break;
+	}
+
+	return rc;
+
+}
+
+/*
+ * megasas_fusion_smid_lookup : Look for fusion command correpspodning to SCSI
+ * @instance: per adapter struct
+ *
+ * Return Non Zero index, if SMID found in outstanding commands
+ */
+static u16 megasas_fusion_smid_lookup(struct scsi_cmnd *scmd)
+{
+	int i, ret = 0;
+	struct megasas_instance *instance;
+	struct megasas_cmd_fusion *cmd_fusion;
+	struct fusion_context *fusion;
+
+	instance = (struct megasas_instance *)scmd->device->host->hostdata;
+
+	fusion = instance->ctrl_context;
+
+	for (i = 0; i < instance->max_scsi_cmds; i++) {
+		cmd_fusion = fusion->cmd_list[i];
+		if (cmd_fusion->scmd && (cmd_fusion->scmd == scmd)) {
+			scmd_printk(KERN_NOTICE, scmd, "Abort request is for"
+				" SMID: %d\n", cmd_fusion->index);
+			ret = cmd_fusion->index;
+			break;
+		}
+	}
+
+	return ret;
+}
+
+/*
+* megasas_get_tm_devhandle - Get devhandle for TM request
+* @sdev-		     OS provided scsi device
+*
+* Returns-		     devhandle/targetID of SCSI device
+*/
+static u16 megasas_get_tm_devhandle(struct scsi_device *sdev)
+{
+	u16 pd_index = 0;
+	u32 device_id;
+	struct megasas_instance *instance;
+	struct fusion_context *fusion;
+	struct MR_PD_CFG_SEQ_NUM_SYNC *pd_sync;
+	u16 devhandle = (u16)ULONG_MAX;
+
+	instance = (struct megasas_instance *)sdev->host->hostdata;
+	fusion = instance->ctrl_context;
+
+	if (sdev->channel < MEGASAS_MAX_PD_CHANNELS) {
+		if (instance->use_seqnum_jbod_fp) {
+				pd_index = (sdev->channel * MEGASAS_MAX_DEV_PER_CHANNEL) +
+						sdev->id;
+				pd_sync = (void *)fusion->pd_seq_sync
+						[(instance->pd_seq_map_id - 1) & 1];
+				devhandle = pd_sync->seq[pd_index].devHandle;
+		} else
+			sdev_printk(KERN_ERR, sdev, "Firmware expose tmCapable"
+				" without JBOD MAP support from %s %d\n", __func__, __LINE__);
+	} else {
+		device_id = ((sdev->channel % 2) * MEGASAS_MAX_DEV_PER_CHANNEL)
+				+ sdev->id;
+		devhandle = device_id;
+	}
+
+	return devhandle;
+}
+
+/*
+ * megasas_task_abort_fusion : SCSI task abort function for fusion adapters
+ * @scmd : pointer to scsi command object
+ *
+ * Return SUCCESS, if command aborted else FAILED
+ */
+
+int megasas_task_abort_fusion(struct scsi_cmnd *scmd)
+{
+	struct megasas_instance *instance;
+	u16 smid, devhandle;
+	struct fusion_context *fusion;
+	int ret;
+	struct MR_PRIV_DEVICE *mr_device_priv_data;
+	mr_device_priv_data = scmd->device->hostdata;
+
+
+	instance = (struct megasas_instance *)scmd->device->host->hostdata;
+	fusion = instance->ctrl_context;
+
+	if (atomic_read(&instance->adprecovery) != MEGASAS_HBA_OPERATIONAL) {
+		dev_err(&instance->pdev->dev, "Controller is not OPERATIONAL,"
+		"SCSI host:%d\n", instance->host->host_no);
+		ret = FAILED;
+		return ret;
+	}
+
+	if (!mr_device_priv_data) {
+		sdev_printk(KERN_INFO, scmd->device, "device been deleted! "
+			"scmd(%p)\n", scmd);
+		scmd->result = DID_NO_CONNECT << 16;
+		ret = SUCCESS;
+		goto out;
+	}
+
+
+	if (!mr_device_priv_data->is_tm_capable) {
+		ret = FAILED;
+		goto out;
+	}
+
+	mutex_lock(&instance->reset_mutex);
+
+	smid = megasas_fusion_smid_lookup(scmd);
+
+	if (!smid) {
+		ret = SUCCESS;
+		scmd_printk(KERN_NOTICE, scmd, "Command for which abort is"
+			" issued is not found in oustanding commands\n");
+		mutex_unlock(&instance->reset_mutex);
+		goto out;
+	}
+
+	devhandle = megasas_get_tm_devhandle(scmd->device);
+
+	if (devhandle == (u16)ULONG_MAX) {
+		ret = SUCCESS;
+		sdev_printk(KERN_INFO, scmd->device,
+			"task abort issued for invalid devhandle\n");
+		mutex_unlock(&instance->reset_mutex);
+		goto out;
+	}
+	sdev_printk(KERN_INFO, scmd->device,
+		"attempting task abort! scmd(%p) tm_dev_handle 0x%x\n",
+		scmd, devhandle);
+
+	mr_device_priv_data->tm_busy = 1;
+	ret = megasas_issue_tm(instance, devhandle,
+			scmd->device->channel, scmd->device->id, smid,
+			MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK);
+	mr_device_priv_data->tm_busy = 0;
+
+	mutex_unlock(&instance->reset_mutex);
+out:
+	sdev_printk(KERN_INFO, scmd->device, "task abort: %s scmd(%p)\n",
+			((ret == SUCCESS) ? "SUCCESS" : "FAILED"), scmd);
+
+	return ret;
+}
+
+/*
+ * megasas_reset_target_fusion : target reset function for fusion adapters
+ * scmd: SCSI command pointer
+ *
+ * Returns SUCCESS if all commands associated with target aborted else FAILED
+ */
+
+int megasas_reset_target_fusion(struct scsi_cmnd *scmd)
+{
+
+	struct megasas_instance *instance;
+	int ret = FAILED;
+	u16 devhandle;
+	struct fusion_context *fusion;
+	struct MR_PRIV_DEVICE *mr_device_priv_data;
+	mr_device_priv_data = scmd->device->hostdata;
+
+	instance = (struct megasas_instance *)scmd->device->host->hostdata;
+	fusion = instance->ctrl_context;
+
+	if (atomic_read(&instance->adprecovery) != MEGASAS_HBA_OPERATIONAL) {
+		dev_err(&instance->pdev->dev, "Controller is not OPERATIONAL,"
+		"SCSI host:%d\n", instance->host->host_no);
+		ret = FAILED;
+		return ret;
+	}
+
+	if (!mr_device_priv_data) {
+		sdev_printk(KERN_INFO, scmd->device, "device been deleted! "
+			"scmd(%p)\n", scmd);
+		scmd->result = DID_NO_CONNECT << 16;
+		ret = SUCCESS;
+		goto out;
+	}
+
+
+	if (!mr_device_priv_data->is_tm_capable) {
+		ret = FAILED;
+		goto out;
+	}
+
+	mutex_lock(&instance->reset_mutex);
+	devhandle = megasas_get_tm_devhandle(scmd->device);
+
+	if (devhandle == (u16)ULONG_MAX) {
+		ret = SUCCESS;
+		sdev_printk(KERN_INFO, scmd->device,
+			"target reset issued for invalid devhandle\n");
+		mutex_unlock(&instance->reset_mutex);
+		goto out;
+	}
+
+	sdev_printk(KERN_INFO, scmd->device,
+		"attempting target reset! scmd(%p) tm_dev_handle 0x%x\n",
+		scmd, devhandle);
+	mr_device_priv_data->tm_busy = 1;
+	ret = megasas_issue_tm(instance, devhandle,
+			scmd->device->channel, scmd->device->id, 0,
+			MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET);
+	mr_device_priv_data->tm_busy = 0;
+	mutex_unlock(&instance->reset_mutex);
+out:
+	scmd_printk(KERN_NOTICE, scmd, "megasas: target reset %s!!\n",
+		(ret == SUCCESS) ? "SUCCESS" : "FAILED");
+
+	return ret;
+}
+
+/*SRIOV get other instance in cluster if any*/
+struct megasas_instance *megasas_get_peer_instance(struct megasas_instance *instance)
+{
+	int i;
+
+	for (i = 0; i < MAX_MGMT_ADAPTERS; i++) {
+		if (megasas_mgmt_info.instance[i] &&
+			(megasas_mgmt_info.instance[i] != instance) &&
+			 megasas_mgmt_info.instance[i]->requestorId &&
+			 megasas_mgmt_info.instance[i]->peerIsPresent &&
+			(memcmp((megasas_mgmt_info.instance[i]->clusterId),
+			instance->clusterId, MEGASAS_CLUSTER_ID_SIZE) == 0))
+			return megasas_mgmt_info.instance[i];
+	}
+	return NULL;
+}
+
 /* Check for a second path that is currently UP */
 int megasas_check_mpio_paths(struct megasas_instance *instance,
 	struct scsi_cmnd *scmd)
 {
-	int i, j, retval = (DID_RESET << 16);
+	struct megasas_instance *peer_instance = NULL;
+	int retval = (DID_RESET << 16);
 
-	if (instance->mpio && instance->requestorId) {
-		for (i = 0 ; i < MAX_MGMT_ADAPTERS ; i++)
-			for (j = 0 ; j < MAX_LOGICAL_DRIVES; j++)
-				if (megasas_mgmt_info.instance[i] &&
-				    (megasas_mgmt_info.instance[i] != instance) &&
-				    megasas_mgmt_info.instance[i]->mpio &&
-				    megasas_mgmt_info.instance[i]->requestorId
-				    &&
-				    (megasas_mgmt_info.instance[i]->ld_ids[j]
-				     == scmd->device->id)) {
-					    retval = (DID_NO_CONNECT << 16);
-					    goto out;
-				}
+	if (instance->peerIsPresent) {
+		peer_instance = megasas_get_peer_instance(instance);
+		if ((peer_instance) &&
+			(atomic_read(&peer_instance->adprecovery) ==
+			MEGASAS_HBA_OPERATIONAL))
+			retval = (DID_NO_CONNECT << 16);
 	}
-out:
 	return retval;
 }
 
 /* Core fusion reset function */
-int megasas_reset_fusion(struct Scsi_Host *shost, int iotimeout)
+int megasas_reset_fusion(struct Scsi_Host *shost, int reason)
 {
 	int retval = SUCCESS, i, convert = 0;
 	struct megasas_instance *instance;
@@ -2739,13 +3370,14 @@ int megasas_reset_fusion(struct Scsi_Hos
 	u32 abs_state, status_reg, reset_adapter;
 	u32 io_timeout_in_crash_mode = 0;
 	struct scsi_cmnd *scmd_local = NULL;
+	struct scsi_device *sdev;
 
 	instance = (struct megasas_instance *)shost->hostdata;
 	fusion = instance->ctrl_context;
 
 	mutex_lock(&instance->reset_mutex);
 
-	if (instance->adprecovery == MEGASAS_HW_CRITICAL_ERROR) {
+	if (atomic_read(&instance->adprecovery) == MEGASAS_HW_CRITICAL_ERROR) {
 		dev_warn(&instance->pdev->dev, "Hardware critical error, "
 		       "returning FAILED for scsi%d.\n",
 			instance->host->host_no);
@@ -2757,10 +3389,10 @@ int megasas_reset_fusion(struct Scsi_Hos
 
 	/* IO timeout detected, forcibly put FW in FAULT state */
 	if (abs_state != MFI_STATE_FAULT && instance->crash_dump_buf &&
-		instance->crash_dump_app_support && iotimeout) {
-		dev_info(&instance->pdev->dev, "IO timeout is detected, "
+		instance->crash_dump_app_support && reason) {
+		dev_info(&instance->pdev->dev, "IO/DCMD timeout is detected, "
 			"forcibly FAULT Firmware\n");
-		instance->adprecovery = MEGASAS_ADPRESET_SM_INFAULT;
+		atomic_set(&instance->adprecovery, MEGASAS_ADPRESET_SM_INFAULT);
 		status_reg = readl(&instance->reg_set->doorbell);
 		writel(status_reg | MFI_STATE_FORCE_OCR,
 			&instance->reg_set->doorbell);
@@ -2772,10 +3404,10 @@ int megasas_reset_fusion(struct Scsi_Hos
 			dev_dbg(&instance->pdev->dev, "waiting for [%d] "
 				"seconds for crash dump collection and OCR "
 				"to be done\n", (io_timeout_in_crash_mode * 3));
-		} while ((instance->adprecovery != MEGASAS_HBA_OPERATIONAL) &&
+		} while ((atomic_read(&instance->adprecovery) != MEGASAS_HBA_OPERATIONAL) &&
 			(io_timeout_in_crash_mode < 80));
 
-		if (instance->adprecovery == MEGASAS_HBA_OPERATIONAL) {
+		if (atomic_read(&instance->adprecovery) == MEGASAS_HBA_OPERATIONAL) {
 			dev_info(&instance->pdev->dev, "OCR done for IO "
 				"timeout case\n");
 			retval = SUCCESS;
@@ -2792,18 +3424,18 @@ int megasas_reset_fusion(struct Scsi_Hos
 	if (instance->requestorId && !instance->skip_heartbeat_timer_del)
 		del_timer_sync(&instance->sriov_heartbeat_timer);
 	set_bit(MEGASAS_FUSION_IN_RESET, &instance->reset_flags);
-	instance->adprecovery = MEGASAS_ADPRESET_SM_POLLING;
+	atomic_set(&instance->adprecovery, MEGASAS_ADPRESET_SM_POLLING);
 	instance->instancet->disable_intr(instance);
 	msleep(1000);
 
 	/* First try waiting for commands to complete */
-	if (megasas_wait_for_outstanding_fusion(instance, iotimeout,
+	if (megasas_wait_for_outstanding_fusion(instance, reason,
 						&convert)) {
-		instance->adprecovery = MEGASAS_ADPRESET_SM_INFAULT;
+		atomic_set(&instance->adprecovery, MEGASAS_ADPRESET_SM_INFAULT);
 		dev_warn(&instance->pdev->dev, "resetting fusion "
 		       "adapter scsi%d.\n", instance->host->host_no);
 		if (convert)
-			iotimeout = 0;
+			reason = 0;
 
 		/* Now return commands back to the OS */
 		for (i = 0 ; i < instance->max_scsi_cmds; i++) {
@@ -2813,6 +3445,8 @@ int megasas_reset_fusion(struct Scsi_Hos
 				scmd_local->result =
 					megasas_check_mpio_paths(instance,
 							scmd_local);
+				if (megasas_cmd_type(scmd_local) == READ_WRITE_LDIO)
+					atomic_dec(&instance->ldio_outstanding);
 				megasas_return_cmd_fusion(instance, cmd_fusion);
 				scsi_dma_unmap(scmd_local);
 				scmd_local->scsi_done(scmd_local);
@@ -2837,55 +3471,9 @@ int megasas_reset_fusion(struct Scsi_Hos
 		}
 
 		/* Let SR-IOV VF & PF sync up if there was a HB failure */
-		if (instance->requestorId && !iotimeout) {
+		if (instance->requestorId && !reason) {
 			msleep(MEGASAS_OCR_SETTLE_TIME_VF);
-			/* Look for a late HB update after VF settle time */
-			if (abs_state == MFI_STATE_OPERATIONAL &&
-			    (instance->hb_host_mem->HB.fwCounter !=
-			     instance->hb_host_mem->HB.driverCounter)) {
-					instance->hb_host_mem->HB.driverCounter =
-						instance->hb_host_mem->HB.fwCounter;
-					dev_warn(&instance->pdev->dev, "SR-IOV:"
-					       "Late FW heartbeat update for "
-					       "scsi%d.\n",
-					       instance->host->host_no);
-			} else {
-				/* In VF mode, first poll for FW ready */
-				for (i = 0;
-				     i < (MEGASAS_RESET_WAIT_TIME * 1000);
-				     i += 20) {
-					status_reg =
-						instance->instancet->
-						read_fw_status_reg(
-							instance->reg_set);
-					abs_state = status_reg &
-						MFI_STATE_MASK;
-					if (abs_state == MFI_STATE_READY) {
-						dev_warn(&instance->pdev->dev,
-						       "SR-IOV: FW was found"
-						       "to be in ready state "
-						       "for scsi%d.\n",
-						       instance->host->host_no);
-						break;
-					}
-					msleep(20);
-				}
-				if (abs_state != MFI_STATE_READY) {
-					dev_warn(&instance->pdev->dev, "SR-IOV: "
-					       "FW not in ready state after %d"
-					       " seconds for scsi%d, status_reg = "
-					       "0x%x.\n",
-					       MEGASAS_RESET_WAIT_TIME,
-					       instance->host->host_no,
-					       status_reg);
-					megaraid_sas_kill_hba(instance);
-					instance->skip_heartbeat_timer_del = 1;
-					instance->adprecovery =
-						MEGASAS_HW_CRITICAL_ERROR;
-					retval = FAILED;
-					goto out;
-				}
-			}
+			goto transition_to_ready;
 		}
 
 		/* Now try to reset the chip */
@@ -2894,23 +3482,28 @@ int megasas_reset_fusion(struct Scsi_Hos
 			if (instance->instancet->adp_reset
 				(instance, instance->reg_set))
 				continue;
-
+transition_to_ready:
 			/* Wait for FW to become ready */
 			if (megasas_transition_to_ready(instance, 1)) {
-				dev_warn(&instance->pdev->dev, "Failed to "
-				       "transition controller to ready "
-				       "for scsi%d.\n",
-				       instance->host->host_no);
-				continue;
+				dev_warn(&instance->pdev->dev,
+					"Failed to transition controller to ready for "
+					"scsi%d.\n", instance->host->host_no);
+				if (instance->requestorId && !reason)
+					goto fail_kill_adapter;
+				else
+					continue;
 			}
-
 			megasas_reset_reply_desc(instance);
+			megasas_fusion_update_can_queue(instance, OCR_CONTEXT);
+
 			if (megasas_ioc_init_fusion(instance)) {
 				dev_warn(&instance->pdev->dev,
-				       "megasas_ioc_init_fusion() failed!"
-				       " for scsi%d\n",
-				       instance->host->host_no);
-				continue;
+				       "megasas_ioc_init_fusion() failed! for "
+				       "scsi%d\n", instance->host->host_no);
+				if (instance->requestorId && !reason)
+					goto fail_kill_adapter;
+				else
+					continue;
 			}
 
 			megasas_refire_mgmt_cmd(instance);
@@ -2932,10 +3525,13 @@ int megasas_reset_fusion(struct Scsi_Hos
 
 			megasas_setup_jbod_map(instance);
 
+			shost_for_each_device(sdev, shost)
+				megasas_update_sdev_properties(sdev);
+
 			clear_bit(MEGASAS_FUSION_IN_RESET,
 				  &instance->reset_flags);
 			instance->instancet->enable_intr(instance);
-			instance->adprecovery = MEGASAS_HBA_OPERATIONAL;
+			atomic_set(&instance->adprecovery, MEGASAS_HBA_OPERATIONAL);
 
 			/* Restart SR-IOV heartbeat */
 			if (instance->requestorId) {
@@ -2964,6 +3560,7 @@ int megasas_reset_fusion(struct Scsi_Hos
 			retval = SUCCESS;
 			goto out;
 		}
+fail_kill_adapter:
 		/* Reset failed, kill the adapter */
 		dev_warn(&instance->pdev->dev, "Reset failed, killing "
 		       "adapter scsi%d.\n", instance->host->host_no);
@@ -2980,7 +3577,7 @@ int megasas_reset_fusion(struct Scsi_Hos
 		}
 		clear_bit(MEGASAS_FUSION_IN_RESET, &instance->reset_flags);
 		instance->instancet->enable_intr(instance);
-		instance->adprecovery = MEGASAS_HBA_OPERATIONAL;
+		atomic_set(&instance->adprecovery, MEGASAS_HBA_OPERATIONAL);
 	}
 out:
 	clear_bit(MEGASAS_FUSION_IN_RESET, &instance->reset_flags);
--- zfcpdump-kernel-4.4.orig/drivers/scsi/megaraid/megaraid_sas_fusion.h
+++ zfcpdump-kernel-4.4/drivers/scsi/megaraid/megaraid_sas_fusion.h
@@ -176,7 +176,9 @@ enum REGION_TYPE {
 #define MPI2_SCSIIO_EEDPFLAGS_CHECK_GUARD           (0x0100)
 #define MPI2_SCSIIO_EEDPFLAGS_INSERT_OP             (0x0004)
 #define MPI2_FUNCTION_SCSI_IO_REQUEST               (0x00) /* SCSI IO */
-#define MPI2_REQ_DESCRIPT_FLAGS_HIGH_PRIORITY           (0x06)
+#define MPI2_FUNCTION_SCSI_TASK_MGMT                (0x01)
+#define MPI2_REQ_DESCRIPT_FLAGS_HIGH_PRIORITY       (0x03)
+#define MPI2_REQ_DESCRIPT_FLAGS_FP_IO               (0x06)
 #define MPI2_REQ_DESCRIPT_FLAGS_SCSI_IO                 (0x00)
 #define MPI2_SGE_FLAGS_64_BIT_ADDRESSING        (0x02)
 #define MPI2_SCSIIO_CONTROL_WRITE               (0x01000000)
@@ -277,6 +279,100 @@ union MPI2_SCSI_IO_CDB_UNION {
 	struct MPI2_SGE_SIMPLE_UNION SGE;
 };
 
+/****************************************************************************
+*  SCSI Task Management messages
+****************************************************************************/
+
+/*SCSI Task Management Request Message */
+struct MPI2_SCSI_TASK_MANAGE_REQUEST {
+	u16 DevHandle;		/*0x00 */
+	u8 ChainOffset;		/*0x02 */
+	u8 Function;		/*0x03 */
+	u8 Reserved1;		/*0x04 */
+	u8 TaskType;		/*0x05 */
+	u8 Reserved2;		/*0x06 */
+	u8 MsgFlags;		/*0x07 */
+	u8 VP_ID;		/*0x08 */
+	u8 VF_ID;		/*0x09 */
+	u16 Reserved3;		/*0x0A */
+	u8 LUN[8];		/*0x0C */
+	u32 Reserved4[7];	/*0x14 */
+	u16 TaskMID;		/*0x30 */
+	u16 Reserved5;		/*0x32 */
+};
+
+
+/*SCSI Task Management Reply Message */
+struct MPI2_SCSI_TASK_MANAGE_REPLY {
+	u16 DevHandle;		/*0x00 */
+	u8 MsgLength;		/*0x02 */
+	u8 Function;		/*0x03 */
+	u8 ResponseCode;	/*0x04 */
+	u8 TaskType;		/*0x05 */
+	u8 Reserved1;		/*0x06 */
+	u8 MsgFlags;		/*0x07 */
+	u8 VP_ID;		/*0x08 */
+	u8 VF_ID;		/*0x09 */
+	u16 Reserved2;		/*0x0A */
+	u16 Reserved3;		/*0x0C */
+	u16 IOCStatus;		/*0x0E */
+	u32 IOCLogInfo;		/*0x10 */
+	u32 TerminationCount;	/*0x14 */
+	u32 ResponseInfo;	/*0x18 */
+};
+
+struct MR_TM_REQUEST {
+	char request[128];
+};
+
+struct MR_TM_REPLY {
+	char reply[128];
+};
+
+/* SCSI Task Management Request Message */
+struct MR_TASK_MANAGE_REQUEST {
+	/*To be type casted to struct MPI2_SCSI_TASK_MANAGE_REQUEST */
+	struct MR_TM_REQUEST         TmRequest;
+	union {
+		struct {
+#if   defined(__BIG_ENDIAN_BITFIELD)
+			u32 reserved1:30;
+			u32 isTMForPD:1;
+			u32 isTMForLD:1;
+#else
+			u32 isTMForLD:1;
+			u32 isTMForPD:1;
+			u32 reserved1:30;
+#endif
+			u32 reserved2;
+		} tmReqFlags;
+		struct MR_TM_REPLY   TMReply;
+	};
+};
+
+/* TaskType values */
+
+#define MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK           (0x01)
+#define MPI2_SCSITASKMGMT_TASKTYPE_ABRT_TASK_SET        (0x02)
+#define MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET         (0x03)
+#define MPI2_SCSITASKMGMT_TASKTYPE_LOGICAL_UNIT_RESET   (0x05)
+#define MPI2_SCSITASKMGMT_TASKTYPE_CLEAR_TASK_SET       (0x06)
+#define MPI2_SCSITASKMGMT_TASKTYPE_QUERY_TASK           (0x07)
+#define MPI2_SCSITASKMGMT_TASKTYPE_CLR_ACA              (0x08)
+#define MPI2_SCSITASKMGMT_TASKTYPE_QRY_TASK_SET         (0x09)
+#define MPI2_SCSITASKMGMT_TASKTYPE_QRY_ASYNC_EVENT      (0x0A)
+
+/* ResponseCode values */
+
+#define MPI2_SCSITASKMGMT_RSP_TM_COMPLETE               (0x00)
+#define MPI2_SCSITASKMGMT_RSP_INVALID_FRAME             (0x02)
+#define MPI2_SCSITASKMGMT_RSP_TM_NOT_SUPPORTED          (0x04)
+#define MPI2_SCSITASKMGMT_RSP_TM_FAILED                 (0x05)
+#define MPI2_SCSITASKMGMT_RSP_TM_SUCCEEDED              (0x08)
+#define MPI2_SCSITASKMGMT_RSP_TM_INVALID_LUN            (0x09)
+#define MPI2_SCSITASKMGMT_RSP_TM_OVERLAPPED_TAG         (0x0A)
+#define MPI2_SCSITASKMGMT_RSP_IO_QUEUED_ON_IOC          (0x80)
+
 /*
  * RAID SCSI IO Request Message
  * Total SGE count will be one less than  _MPI2_SCSI_IO_REQUEST
@@ -547,7 +643,9 @@ struct MR_SPAN_BLOCK_INFO {
 struct MR_LD_RAID {
 	struct {
 #if   defined(__BIG_ENDIAN_BITFIELD)
-		u32     reserved4:7;
+		u32     reserved4:5;
+		u32     fpBypassRegionLock:1;
+		u32     tmCapable:1;
 		u32	fpNonRWCapable:1;
 		u32     fpReadAcrossStripe:1;
 		u32     fpWriteAcrossStripe:1;
@@ -569,7 +667,9 @@ struct MR_LD_RAID {
 		u32     fpWriteAcrossStripe:1;
 		u32     fpReadAcrossStripe:1;
 		u32	fpNonRWCapable:1;
-		u32     reserved4:7;
+		u32     tmCapable:1;
+		u32     fpBypassRegionLock:1;
+		u32     reserved4:5;
 #endif
 	} capability;
 	__le32     reserved6;
@@ -639,7 +739,7 @@ struct IO_REQUEST_INFO {
 	u8 fpOkForIo;
 	u8 IoforUnevenSpan;
 	u8 start_span;
-	u8 reserved;
+	u8 do_fp_rlbypass;
 	u64 start_row;
 	u8  span_arm;	/* span[7:5], arm[4:0] */
 	u8  pd_after_lb;
@@ -694,6 +794,7 @@ struct megasas_cmd_fusion {
 	u32 sync_cmd_idx;
 	u32 index;
 	u8 pd_r1_lb;
+	struct completion done;
 };
 
 struct LD_LOAD_BALANCE_INFO {
@@ -807,9 +908,18 @@ struct MR_FW_RAID_MAP_EXT {
  *  * define MR_PD_CFG_SEQ structure for system PDs
  *   */
 struct MR_PD_CFG_SEQ {
-	__le16 seqNum;
-	__le16 devHandle;
-	u8  reserved[4];
+	u16 seqNum;
+	u16 devHandle;
+	struct {
+#if   defined(__BIG_ENDIAN_BITFIELD)
+		u8     reserved:7;
+		u8     tmCapable:1;
+#else
+		u8     tmCapable:1;
+		u8     reserved:7;
+#endif
+	} capability;
+	u8  reserved[3];
 } __packed;
 
 struct MR_PD_CFG_SEQ_NUM_SYNC {
@@ -818,6 +928,12 @@ struct MR_PD_CFG_SEQ_NUM_SYNC {
 	struct MR_PD_CFG_SEQ seq[1];
 } __packed;
 
+struct MPI2_IOC_INIT_RDPQ_ARRAY_ENTRY {
+	u64 RDPQBaseAddress;
+	u32 Reserved1;
+	u32 Reserved2;
+};
+
 struct fusion_context {
 	struct megasas_cmd_fusion **cmd_list;
 	dma_addr_t req_frames_desc_phys;
@@ -830,8 +946,8 @@ struct fusion_context {
 	struct dma_pool *sg_dma_pool;
 	struct dma_pool *sense_dma_pool;
 
-	dma_addr_t reply_frames_desc_phys;
-	union MPI2_REPLY_DESCRIPTORS_UNION *reply_frames_desc;
+	dma_addr_t reply_frames_desc_phys[MAX_MSIX_QUEUES_FUSION];
+	union MPI2_REPLY_DESCRIPTORS_UNION *reply_frames_desc[MAX_MSIX_QUEUES_FUSION];
 	struct dma_pool *reply_frames_desc_pool;
 
 	u16 last_reply_idx[MAX_MSIX_QUEUES_FUSION];
@@ -841,6 +957,8 @@ struct fusion_context {
 	u32 reply_alloc_sz;
 	u32 io_frames_alloc_sz;
 
+	struct MPI2_IOC_INIT_RDPQ_ARRAY_ENTRY *rdpq_virt;
+	dma_addr_t rdpq_phys;
 	u16	max_sge_in_main_msg;
 	u16	max_sge_in_chain;
 
--- zfcpdump-kernel-4.4.orig/drivers/scsi/mpt3sas/mpi/mpi2.h
+++ zfcpdump-kernel-4.4/drivers/scsi/mpt3sas/mpi/mpi2.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000-2014 LSI Corporation.
+ * Copyright 2000-2015 Avago Technologies.  All rights reserved.
  *
  *
  *          Name:  mpi2.h
@@ -8,7 +8,7 @@
  *                 scatter/gather formats.
  * Creation Date:  June 21, 2006
  *
- * mpi2.h Version:  02.00.35
+ * mpi2.h Version:  02.00.39
  *
  * NOTE: Names (typedefs, defines, etc.) beginning with an MPI25 or Mpi25
  *       prefix are for use only on MPI v2.5 products, and must not be used
@@ -92,6 +92,14 @@
  * 12-05-13  02.00.33  Bumped MPI2_HEADER_VERSION_UNIT.
  * 01-08-14  02.00.34  Bumped MPI2_HEADER_VERSION_UNIT
  * 06-13-14  02.00.35  Bumped MPI2_HEADER_VERSION_UNIT.
+ * 11-18-14  02.00.36  Updated copyright information.
+ *                     Bumped MPI2_HEADER_VERSION_UNIT.
+ * 03-16-15  02.00.37  Bumped MPI2_HEADER_VERSION_UNIT.
+ *                     Added Scratchpad registers to
+ *                     MPI2_SYSTEM_INTERFACE_REGS.
+ *                     Added MPI2_DIAG_SBR_RELOAD.
+ * 03-19-15  02.00.38  Bumped MPI2_HEADER_VERSION_UNIT.
+ * 05-25-15  02.00.39  Bumped MPI2_HEADER_VERSION_UNIT.
  * --------------------------------------------------------------------------
  */
 
@@ -124,8 +132,14 @@
 					MPI25_VERSION_MINOR)
 #define MPI2_VERSION_02_05                  (0x0205)
 
+/*minor version for MPI v2.6 compatible products */
+#define MPI26_VERSION_MINOR		    (0x06)
+#define MPI26_VERSION ((MPI2_VERSION_MAJOR << MPI2_VERSION_MAJOR_SHIFT) | \
+					MPI26_VERSION_MINOR)
+#define MPI2_VERSION_02_06		    (0x0206)
+
 /*Unit and Dev versioning for this MPI header set */
-#define MPI2_HEADER_VERSION_UNIT            (0x23)
+#define MPI2_HEADER_VERSION_UNIT            (0x27)
 #define MPI2_HEADER_VERSION_DEV             (0x00)
 #define MPI2_HEADER_VERSION_UNIT_MASK       (0xFF00)
 #define MPI2_HEADER_VERSION_UNIT_SHIFT      (8)
@@ -179,10 +193,12 @@ typedef volatile struct _MPI2_SYSTEM_INT
 	U32 HCBSize;		/*0x74 */
 	U32 HCBAddressLow;	/*0x78 */
 	U32 HCBAddressHigh;	/*0x7C */
-	U32 Reserved6[16];	/*0x80 */
+	U32 Reserved6[12];	/*0x80 */
+	U32 Scratchpad[4];	/*0xB0 */
 	U32 RequestDescriptorPostLow;	/*0xC0 */
 	U32 RequestDescriptorPostHigh;	/*0xC4 */
-	U32 Reserved7[14];	/*0xC8 */
+	U32 AtomicRequestDescriptorPost;/*0xC8 */
+	U32 Reserved7[13];	/*0xCC */
 } MPI2_SYSTEM_INTERFACE_REGS,
 	*PTR_MPI2_SYSTEM_INTERFACE_REGS,
 	Mpi2SystemInterfaceRegs_t,
@@ -224,6 +240,8 @@ typedef volatile struct _MPI2_SYSTEM_INT
  */
 #define MPI2_HOST_DIAGNOSTIC_OFFSET             (0x00000008)
 
+#define MPI2_DIAG_SBR_RELOAD                    (0x00002000)
+
 #define MPI2_DIAG_BOOT_DEVICE_SELECT_MASK       (0x00001800)
 #define MPI2_DIAG_BOOT_DEVICE_SELECT_DEFAULT    (0x00000000)
 #define MPI2_DIAG_BOOT_DEVICE_SELECT_HCDW       (0x00000800)
@@ -298,10 +316,19 @@ typedef volatile struct _MPI2_SYSTEM_INT
 #define MPI2_HCB_ADDRESS_HIGH_OFFSET            (0x0000007C)
 
 /*
- *Offsets for the Request Queue
+ *Offsets for the Scratchpad registers
+ */
+#define MPI26_SCRATCHPAD0_OFFSET                (0x000000B0)
+#define MPI26_SCRATCHPAD1_OFFSET                (0x000000B4)
+#define MPI26_SCRATCHPAD2_OFFSET                (0x000000B8)
+#define MPI26_SCRATCHPAD3_OFFSET                (0x000000BC)
+
+/*
+ *Offsets for the Request Descriptor Post Queue
  */
 #define MPI2_REQUEST_DESCRIPTOR_POST_LOW_OFFSET     (0x000000C0)
 #define MPI2_REQUEST_DESCRIPTOR_POST_HIGH_OFFSET    (0x000000C4)
+#define MPI26_ATOMIC_REQUEST_DESCRIPTOR_POST_OFFSET (0x000000C8)
 
 /*Hard Reset delay timings */
 #define MPI2_HARD_RESET_PCIE_FIRST_READ_DELAY_MICRO_SEC     (50000)
@@ -329,7 +356,8 @@ typedef struct _MPI2_DEFAULT_REQUEST_DES
 	*pMpi2DefaultRequestDescriptor_t;
 
 /*defines for the RequestFlags field */
-#define MPI2_REQ_DESCRIPT_FLAGS_TYPE_MASK               (0x0E)
+#define MPI2_REQ_DESCRIPT_FLAGS_TYPE_MASK               (0x1E)
+#define MPI2_REQ_DESCRIPT_FLAGS_TYPE_RSHIFT             (1)
 #define MPI2_REQ_DESCRIPT_FLAGS_SCSI_IO                 (0x00)
 #define MPI2_REQ_DESCRIPT_FLAGS_SCSI_TARGET             (0x02)
 #define MPI2_REQ_DESCRIPT_FLAGS_HIGH_PRIORITY           (0x06)
@@ -337,7 +365,7 @@ typedef struct _MPI2_DEFAULT_REQUEST_DES
 #define MPI2_REQ_DESCRIPT_FLAGS_RAID_ACCELERATOR        (0x0A)
 #define MPI25_REQ_DESCRIPT_FLAGS_FAST_PATH_SCSI_IO      (0x0C)
 
-#define MPI2_REQ_DESCRIPT_FLAGS_IOC_FIFO_MARKER (0x01)
+#define MPI2_REQ_DESCRIPT_FLAGS_IOC_FIFO_MARKER         (0x01)
 
 /*High Priority Request Descriptor */
 typedef struct _MPI2_HIGH_PRIORITY_REQUEST_DESCRIPTOR {
@@ -408,6 +436,33 @@ typedef union _MPI2_REQUEST_DESCRIPTOR_U
 	Mpi2RequestDescriptorUnion_t,
 	*pMpi2RequestDescriptorUnion_t;
 
+/*Atomic Request Descriptors */
+
+/*
+ * All Atomic Request Descriptors have the same format, so the following
+ * structure is used for all Atomic Request Descriptors:
+ *      Atomic Default Request Descriptor
+ *      Atomic High Priority Request Descriptor
+ *      Atomic SCSI IO Request Descriptor
+ *      Atomic SCSI Target Request Descriptor
+ *      Atomic RAID Accelerator Request Descriptor
+ *      Atomic Fast Path SCSI IO Request Descriptor
+ */
+
+/*Atomic Request Descriptor */
+typedef struct _MPI26_ATOMIC_REQUEST_DESCRIPTOR {
+	U8 RequestFlags;	/* 0x00 */
+	U8 MSIxIndex;		/* 0x01 */
+	U16 SMID;		/* 0x02 */
+} MPI26_ATOMIC_REQUEST_DESCRIPTOR,
+	*PTR_MPI26_ATOMIC_REQUEST_DESCRIPTOR,
+	Mpi26AtomicRequestDescriptor_t,
+	*pMpi26AtomicRequestDescriptor_t;
+
+/*for the RequestFlags field, use the same
+ *defines as MPI2_DEFAULT_REQUEST_DESCRIPTOR
+ */
+
 /*Reply Descriptors */
 
 /*Default Reply Descriptor */
@@ -548,6 +603,7 @@ typedef union _MPI2_REPLY_DESCRIPTORS_UN
 #define MPI2_FUNCTION_SCSI_ENCLOSURE_PROCESSOR      (0x18)
 #define MPI2_FUNCTION_SMP_PASSTHROUGH               (0x1A)
 #define MPI2_FUNCTION_SAS_IO_UNIT_CONTROL           (0x1B)
+#define MPI2_FUNCTION_IO_UNIT_CONTROL               (0x1B)
 #define MPI2_FUNCTION_SATA_PASSTHROUGH              (0x1C)
 #define MPI2_FUNCTION_DIAG_BUFFER_POST              (0x1D)
 #define MPI2_FUNCTION_DIAG_RELEASE                  (0x1E)
@@ -587,6 +643,7 @@ typedef union _MPI2_REPLY_DESCRIPTORS_UN
 #define MPI2_IOCSTATUS_INVALID_FIELD                (0x0007)
 #define MPI2_IOCSTATUS_INVALID_STATE                (0x0008)
 #define MPI2_IOCSTATUS_OP_STATE_NOT_SUPPORTED       (0x0009)
+#define MPI2_IOCSTATUS_INSUFFICIENT_POWER           (0x000A)
 
 /****************************************************************************
 * Config IOCStatus values
@@ -1045,7 +1102,7 @@ typedef union _MPI2_IEEE_SGE_CHAIN_UNION
 	Mpi2IeeeSgeChainUnion_t,
 	*pMpi2IeeeSgeChainUnion_t;
 
-/*MPI25_IEEE_SGE_CHAIN64 is for MPI v2.5 products only */
+/*MPI25_IEEE_SGE_CHAIN64 is for MPI v2.5 and later */
 typedef struct _MPI25_IEEE_SGE_CHAIN64 {
 	U64 Address;
 	U32 Length;
@@ -1098,6 +1155,11 @@ typedef union _MPI25_SGE_IO_UNION {
 #define MPI2_IEEE_SGE_FLAGS_SIMPLE_ELEMENT      (0x00)
 #define MPI2_IEEE_SGE_FLAGS_CHAIN_ELEMENT       (0x80)
 
+/*Next Segment Format */
+
+#define MPI26_IEEE_SGE_FLAGS_NSF_MASK           (0x1C)
+#define MPI26_IEEE_SGE_FLAGS_NSF_MPI_IEEE       (0x00)
+
 /*Data Location Address Space */
 
 #define MPI2_IEEE_SGE_FLAGS_ADDR_MASK           (0x03)
@@ -1108,6 +1170,7 @@ typedef union _MPI25_SGE_IO_UNION {
 #define MPI2_IEEE_SGE_FLAGS_SYSTEMPLBPCI_ADDR   (0x03)
 #define MPI2_IEEE_SGE_FLAGS_SYSTEMPLBCPI_ADDR \
 	 (MPI2_IEEE_SGE_FLAGS_SYSTEMPLBPCI_ADDR)
+#define MPI26_IEEE_SGE_FLAGS_IOCCTL_ADDR        (0x02)
 
 /****************************************************************************
 * IEEE SGE operation Macros
@@ -1166,6 +1229,7 @@ typedef union _MPI2_SGE_IO_UNION {
 #define MPI2_SGLFLAGS_SYSTEM_ADDRESS_SPACE          (0x00)
 #define MPI2_SGLFLAGS_IOCDDR_ADDRESS_SPACE          (0x04)
 #define MPI2_SGLFLAGS_IOCPLB_ADDRESS_SPACE          (0x08)
+#define MPI26_SGLFLAGS_IOCPLB_ADDRESS_SPACE         (0x08)
 #define MPI2_SGLFLAGS_IOCPLBNTA_ADDRESS_SPACE       (0x0C)
 /*values for SGL Type subfield */
 #define MPI2_SGLFLAGS_SGL_TYPE_MASK                 (0x03)
--- zfcpdump-kernel-4.4.orig/drivers/scsi/mpt3sas/mpi/mpi2_cnfg.h
+++ zfcpdump-kernel-4.4/drivers/scsi/mpt3sas/mpi/mpi2_cnfg.h
@@ -1,12 +1,12 @@
 /*
- * Copyright (c) 2000-2014 LSI Corporation.
+ * Copyright 2000-2015 Avago Technologies.  All rights reserved.
  *
  *
  *          Name:  mpi2_cnfg.h
  *         Title:  MPI Configuration messages and pages
  * Creation Date:  November 10, 2006
  *
- *   mpi2_cnfg.h Version:  02.00.29
+ *   mpi2_cnfg.h Version:  02.00.33
  *
  * NOTE: Names (typedefs, defines, etc.) beginning with an MPI25 or Mpi25
  *       prefix are for use only on MPI v2.5 products, and must not be used
@@ -178,7 +178,14 @@
  * 01-08-14  02.00.28  Added more defines for the BiosOptions field of
  *		       MPI2_CONFIG_PAGE_BIOS_1.
  * 06-13-14  02.00.29  Added SSUTimeout field to MPI2_CONFIG_PAGE_BIOS_1, and
- *		       more defines for the BiosOptions field..
+ *                     more defines for the BiosOptions field.
+ * 11-18-14  02.00.30  Updated copyright information.
+ *                     Added MPI2_BIOSPAGE1_OPTIONS_ADVANCED_CONFIG.
+ *                     Added AdapterOrderAux fields to BIOS Page 3.
+ * 03-16-15  02.00.31  Updated for MPI v2.6.
+ *                     Added new SAS Phy Event codes
+ * 05-25-15  02.00.33  Added more defines for the BiosOptions field of
+ *                     MPI2_CONFIG_PAGE_BIOS_1.
  * --------------------------------------------------------------------------
  */
 
@@ -355,7 +362,6 @@ typedef union _MPI2_CONFIG_EXT_PAGE_HEAD
 #define MPI2_ETHERNET_PGAD_IF_NUMBER_MASK           (0x000000FF)
 
 
-
 /****************************************************************************
 *  Configuration messages
 ****************************************************************************/
@@ -457,8 +463,17 @@ typedef struct _MPI2_CONFIG_REPLY {
 #define MPI25_MFGPAGE_DEVID_SAS3108_5               (0x0094)
 #define MPI25_MFGPAGE_DEVID_SAS3108_6               (0x0095)
 
-
-
+/* MPI v2.6 SAS Products */
+#define MPI26_MFGPAGE_DEVID_SAS3216                 (0x00C9)
+#define MPI26_MFGPAGE_DEVID_SAS3224                 (0x00C4)
+#define MPI26_MFGPAGE_DEVID_SAS3316_1               (0x00C5)
+#define MPI26_MFGPAGE_DEVID_SAS3316_2               (0x00C6)
+#define MPI26_MFGPAGE_DEVID_SAS3316_3               (0x00C7)
+#define MPI26_MFGPAGE_DEVID_SAS3316_4               (0x00C8)
+#define MPI26_MFGPAGE_DEVID_SAS3324_1               (0x00C0)
+#define MPI26_MFGPAGE_DEVID_SAS3324_2               (0x00C1)
+#define MPI26_MFGPAGE_DEVID_SAS3324_3               (0x00C2)
+#define MPI26_MFGPAGE_DEVID_SAS3324_4               (0x00C3)
 
 /*Manufacturing Page 0 */
 
@@ -941,8 +956,8 @@ typedef struct _MPI2_CONFIG_PAGE_IO_UNIT
 	U8
 		BoardTemperatureUnits;                  /*0x16 */
 	U8                      Reserved3;              /*0x17 */
-	U32			Reserved4;		/* 0x18 */
-	U32			Reserved5;		/* 0x1C */
+	U32			BoardPowerRequirement;	/*0x18 */
+	U32			PCISlotPowerAllocation;	/*0x1C */
 	U32			Reserved6;		/* 0x20 */
 	U32			Reserved7;		/* 0x24 */
 } MPI2_CONFIG_PAGE_IO_UNIT_7,
@@ -1151,6 +1166,62 @@ typedef struct _MPI2_CONFIG_PAGE_IO_UNIT
 #define MPI2_IOUNITPAGE10_PAGEVERSION                   (0x01)
 
 
+/* IO Unit Page 11 (for MPI v2.6 and later) */
+
+typedef struct _MPI26_IOUNIT11_SPINUP_GROUP {
+	U8          MaxTargetSpinup;            /* 0x00 */
+	U8          SpinupDelay;                /* 0x01 */
+	U8          SpinupFlags;                /* 0x02 */
+	U8          Reserved1;                  /* 0x03 */
+} MPI26_IOUNIT11_SPINUP_GROUP,
+	*PTR_MPI26_IOUNIT11_SPINUP_GROUP,
+	Mpi26IOUnit11SpinupGroup_t,
+	*pMpi26IOUnit11SpinupGroup_t;
+
+/* defines for IO Unit Page 11 SpinupFlags */
+#define MPI26_IOUNITPAGE11_SPINUP_DISABLE_FLAG          (0x01)
+
+
+/*
+ * Host code (drivers, BIOS, utilities, etc.) should leave this define set to
+ * four and check the value returned for NumPhys at runtime.
+ */
+#ifndef MPI26_IOUNITPAGE11_PHY_MAX
+#define MPI26_IOUNITPAGE11_PHY_MAX        (4)
+#endif
+
+typedef struct _MPI26_CONFIG_PAGE_IO_UNIT_11 {
+	MPI2_CONFIG_PAGE_HEADER       Header;			       /*0x00 */
+	U32                           Reserved1;                      /*0x04 */
+	MPI26_IOUNIT11_SPINUP_GROUP   SpinupGroupParameters[4];       /*0x08 */
+	U32                           Reserved2;                      /*0x18 */
+	U32                           Reserved3;                      /*0x1C */
+	U32                           Reserved4;                      /*0x20 */
+	U8                            BootDeviceWaitTime;             /*0x24 */
+	U8                            Reserved5;                      /*0x25 */
+	U16                           Reserved6;                      /*0x26 */
+	U8                            NumPhys;                        /*0x28 */
+	U8                            PEInitialSpinupDelay;           /*0x29 */
+	U8                            PEReplyDelay;                   /*0x2A */
+	U8                            Flags;                          /*0x2B */
+	U8			      PHY[MPI26_IOUNITPAGE11_PHY_MAX];/*0x2C */
+} MPI26_CONFIG_PAGE_IO_UNIT_11,
+	*PTR_MPI26_CONFIG_PAGE_IO_UNIT_11,
+	Mpi26IOUnitPage11_t,
+	*pMpi26IOUnitPage11_t;
+
+#define MPI26_IOUNITPAGE11_PAGEVERSION                  (0x00)
+
+/* defines for Flags field */
+#define MPI26_IOUNITPAGE11_FLAGS_AUTO_PORTENABLE        (0x01)
+
+/* defines for PHY field */
+#define MPI26_IOUNITPAGE11_PHY_SPINUP_GROUP_MASK        (0x03)
+
+
+
+
+
 
 /****************************************************************************
 *  IOC Config Pages
@@ -1343,6 +1414,10 @@ typedef struct _MPI2_CONFIG_PAGE_BIOS_1
 #define MPI2_BIOSPAGE1_PAGEVERSION                      (0x07)
 
 /*values for BIOS Page 1 BiosOptions field */
+#define MPI2_BIOSPAGE1_OPTIONS_BOOT_LIST_ADD_ALT_BOOT_DEVICE    (0x00008000)
+#define MPI2_BIOSPAGE1_OPTIONS_ADVANCED_CONFIG                  (0x00004000)
+
+#define MPI2_BIOSPAGE1_OPTIONS_PNS_MASK                         (0x00003800)
 #define MPI2_BIOSPAGE1_OPTIONS_PNS_MASK                         (0x00003800)
 #define MPI2_BIOSPAGE1_OPTIONS_PNS_PBDHL                        (0x00000000)
 #define MPI2_BIOSPAGE1_OPTIONS_PNS_ENCSLOSURE                   (0x00000800)
@@ -1492,6 +1567,8 @@ typedef struct _MPI2_CONFIG_PAGE_BIOS_2
 
 /*BIOS Page 3 */
 
+#define MPI2_BIOSPAGE3_NUM_ADAPTER      (4)
+
 typedef struct _MPI2_ADAPTER_INFO {
 	U8      PciBusNumber;                        /*0x00 */
 	U8      PciDeviceAndFunctionNumber;          /*0x01 */
@@ -1502,17 +1579,26 @@ typedef struct _MPI2_ADAPTER_INFO {
 #define MPI2_ADAPTER_INFO_FLAGS_EMBEDDED                (0x0001)
 #define MPI2_ADAPTER_INFO_FLAGS_INIT_STATUS             (0x0002)
 
+typedef struct _MPI2_ADAPTER_ORDER_AUX {
+	U64     WWID;					/* 0x00 */
+	U32     Reserved1;				/* 0x08 */
+	U32     Reserved2;				/* 0x0C */
+} MPI2_ADAPTER_ORDER_AUX, *PTR_MPI2_ADAPTER_ORDER_AUX,
+	Mpi2AdapterOrderAux_t, *pMpi2AdapterOrderAux_t;
+
+
 typedef struct _MPI2_CONFIG_PAGE_BIOS_3 {
 	MPI2_CONFIG_PAGE_HEADER Header;              /*0x00 */
 	U32                     GlobalFlags;         /*0x04 */
 	U32                     BiosVersion;         /*0x08 */
-	MPI2_ADAPTER_INFO       AdapterOrder[4];     /*0x0C */
+	MPI2_ADAPTER_INFO       AdapterOrder[MPI2_BIOSPAGE3_NUM_ADAPTER];
 	U32                     Reserved1;           /*0x1C */
+	MPI2_ADAPTER_ORDER_AUX  AdapterOrderAux[MPI2_BIOSPAGE3_NUM_ADAPTER];
 } MPI2_CONFIG_PAGE_BIOS_3,
 	*PTR_MPI2_CONFIG_PAGE_BIOS_3,
 	Mpi2BiosPage3_t, *pMpi2BiosPage3_t;
 
-#define MPI2_BIOSPAGE3_PAGEVERSION                      (0x00)
+#define MPI2_BIOSPAGE3_PAGEVERSION                      (0x01)
 
 /*values for BIOS Page 3 GlobalFlags */
 #define MPI2_BIOSPAGE3_FLAGS_PAUSE_ON_ERROR             (0x00000002)
@@ -2006,6 +2092,8 @@ typedef struct _MPI2_CONFIG_PAGE_SASIOUN
 #define MPI2_SASIOUNIT0_PORTFLAGS_AUTO_PORT_CONFIG          (0x01)
 
 /*values for SAS IO Unit Page 0 PhyFlags */
+#define MPI2_SASIOUNIT0_PHYFLAGS_INIT_PERSIST_CONNECT       (0x40)
+#define MPI2_SASIOUNIT0_PHYFLAGS_TARG_PERSIST_CONNECT       (0x20)
 #define MPI2_SASIOUNIT0_PHYFLAGS_ZONING_ENABLED             (0x10)
 #define MPI2_SASIOUNIT0_PHYFLAGS_PHY_DISABLED               (0x08)
 
@@ -2108,6 +2196,7 @@ typedef struct _MPI2_CONFIG_PAGE_SASIOUN
 #define MPI2_SASIOUNIT1_CONTROL_CLEAR_AFFILIATION                   (0x0001)
 
 /*values for SAS IO Unit Page 1 AdditionalControlFlags */
+#define MPI2_SASIOUNIT1_ACONTROL_DA_PERSIST_CONNECT                 (0x0100)
 #define MPI2_SASIOUNIT1_ACONTROL_MULTI_PORT_DOMAIN_ILLEGAL          (0x0080)
 #define MPI2_SASIOUNIT1_ACONTROL_SATA_ASYNCHROUNOUS_NOTIFICATION    (0x0040)
 #define MPI2_SASIOUNIT1_ACONTROL_INVALID_TOPOLOGY_CORRECTION        (0x0020)
@@ -2125,6 +2214,8 @@ typedef struct _MPI2_CONFIG_PAGE_SASIOUN
 #define MPI2_SASIOUNIT1_PORT_FLAGS_AUTO_PORT_CONFIG                 (0x01)
 
 /*values for SAS IO Unit Page 1 PhyFlags */
+#define MPI2_SASIOUNIT1_PHYFLAGS_INIT_PERSIST_CONNECT               (0x40)
+#define MPI2_SASIOUNIT1_PHYFLAGS_TARG_PERSIST_CONNECT               (0x20)
 #define MPI2_SASIOUNIT1_PHYFLAGS_ZONING_ENABLE                      (0x10)
 #define MPI2_SASIOUNIT1_PHYFLAGS_PHY_DISABLE                        (0x08)
 
@@ -2144,7 +2235,7 @@ typedef struct _MPI2_CONFIG_PAGE_SASIOUN
  *SAS IO Unit Page 1 ControllerPhyDeviceInfo values */
 
 
-/*SAS IO Unit Page 4 */
+/*SAS IO Unit Page 4 (for MPI v2.5 and earlier) */
 
 typedef struct _MPI2_SAS_IOUNIT4_SPINUP_GROUP {
 	U8          MaxTargetSpinup;            /*0x00 */
@@ -2715,6 +2806,7 @@ typedef struct _MPI2_CONFIG_PAGE_SAS_DEV
 #define MPI2_SAS_DEVICE0_FLAGS_SATA_NCQ_SUPPORTED           (0x0020)
 #define MPI2_SAS_DEVICE0_FLAGS_SATA_FUA_SUPPORTED           (0x0010)
 #define MPI2_SAS_DEVICE0_FLAGS_PORT_SELECTOR_ATTACH         (0x0008)
+#define MPI2_SAS_DEVICE0_FLAGS_PERSIST_CAPABLE              (0x0004)
 #define MPI2_SAS_DEVICE0_FLAGS_ENCL_LEVEL_VALID             (0x0002)
 #define MPI2_SAS_DEVICE0_FLAGS_DEVICE_PRESENT               (0x0001)
 
@@ -2922,6 +3014,19 @@ typedef struct _MPI2_SASPHY3_PHY_EVENT_C
 #define MPI2_SASPHY3_EVENT_CODE_MISALIGNED_MUX_PRIMITIVE    (0xD1)
 #define MPI2_SASPHY3_EVENT_CODE_RX_AIP                      (0xD2)
 
+/*Following codes are product specific and in MPI v2.6 and later */
+#define MPI2_SASPHY3_EVENT_CODE_LCARB_WAIT_TIME		    (0xD3)
+#define MPI2_SASPHY3_EVENT_CODE_RCVD_CONN_RESP_WAIT_TIME    (0xD4)
+#define MPI2_SASPHY3_EVENT_CODE_LCCONN_TIME	            (0xD5)
+#define MPI2_SASPHY3_EVENT_CODE_SSP_TX_START_TRANSMIT	    (0xD6)
+#define MPI2_SASPHY3_EVENT_CODE_SATA_TX_START	            (0xD7)
+#define MPI2_SASPHY3_EVENT_CODE_SMP_TX_START_TRANSMT	    (0xD8)
+#define MPI2_SASPHY3_EVENT_CODE_TX_SMP_BREAK_CONN	    (0xD9)
+#define MPI2_SASPHY3_EVENT_CODE_SSP_RX_START_RECEIVE	    (0xDA)
+#define MPI2_SASPHY3_EVENT_CODE_SATA_RX_START_RECEIVE	    (0xDB)
+#define MPI2_SASPHY3_EVENT_CODE_SMP_RX_START_RECEIVE	    (0xDC)
+
+
 /*values for the CounterType field */
 #define MPI2_SASPHY3_COUNTER_TYPE_WRAPPING                  (0x00)
 #define MPI2_SASPHY3_COUNTER_TYPE_SATURATING                (0x01)
--- zfcpdump-kernel-4.4.orig/drivers/scsi/mpt3sas/mpi/mpi2_init.h
+++ zfcpdump-kernel-4.4/drivers/scsi/mpt3sas/mpi/mpi2_init.h
@@ -1,12 +1,12 @@
 /*
- * Copyright (c) 2000-2014 LSI Corporation.
+ * Copyright 2000-2015 Avago Technologies.  All rights reserved.
  *
  *
  *          Name:  mpi2_init.h
  *         Title:  MPI SCSI initiator mode messages and structures
  * Creation Date:  June 23, 2006
  *
- * mpi2_init.h Version:  02.00.15
+ * mpi2_init.h Version:  02.00.17
  *
  * NOTE: Names (typedefs, defines, etc.) beginning with an MPI25 or Mpi25
  *       prefix are for use only on MPI v2.5 products, and must not be used
@@ -46,6 +46,11 @@
  * 07-10-12  02.00.14  Added MPI2_SCSIIO_CONTROL_SHIFT_DATADIRECTION.
  * 04-09-13  02.00.15  Added SCSIStatusQualifier field to MPI2_SCSI_IO_REPLY,
  *                     replacing the Reserved4 field.
+ * 11-18-14  02.00.16  Updated copyright information.
+ * 03-16-15  02.00.17  Updated for MPI v2.6.
+ *                     Added MPI26_SCSIIO_IOFLAGS_ESCAPE_PASSTHROUGH.
+ *                     Added MPI2_SEP_REQ_SLOTSTATUS_DEV_OFF and
+ *                     MPI2_SEP_REPLY_SLOTSTATUS_DEV_OFF.
  * --------------------------------------------------------------------------
  */
 
@@ -128,6 +133,7 @@ typedef struct _MPI2_SCSI_IO_REQUEST {
 #define MPI2_SCSIIO_MSGFLAGS_IOCDDR_SENSE_ADDR      (0x04)
 #define MPI2_SCSIIO_MSGFLAGS_IOCPLB_SENSE_ADDR      (0x08)
 #define MPI2_SCSIIO_MSGFLAGS_IOCPLBNTA_SENSE_ADDR   (0x0C)
+#define MPI26_SCSIIO_MSGFLAGS_IOCCTL_SENSE_ADDR     (0x08)
 
 /*SCSI IO SGLFlags bits */
 
@@ -228,7 +234,7 @@ typedef union _MPI25_SCSI_IO_CDB_UNION {
 } MPI25_SCSI_IO_CDB_UNION, *PTR_MPI25_SCSI_IO_CDB_UNION,
 	Mpi25ScsiIoCdb_t, *pMpi25ScsiIoCdb_t;
 
-/*MPI v2.5 SCSI IO Request Message */
+/*MPI v2.5/2.6 SCSI IO Request Message */
 typedef struct _MPI25_SCSI_IO_REQUEST {
 	U16 DevHandle;		/*0x00 */
 	U8 ChainOffset;		/*0x02 */
@@ -302,12 +308,14 @@ typedef struct _MPI25_SCSI_IO_REQUEST {
 #define MPI25_SCSIIO_NUM_SGLOFFSETS                 (4)
 
 /*defines for the IoFlags field */
-#define MPI25_SCSIIO_IOFLAGS_IO_PATH_MASK           (0xC000)
-#define MPI25_SCSIIO_IOFLAGS_NORMAL_PATH            (0x0000)
-#define MPI25_SCSIIO_IOFLAGS_FAST_PATH              (0x4000)
+#define MPI25_SCSIIO_IOFLAGS_IO_PATH_MASK               (0xC000)
+#define MPI25_SCSIIO_IOFLAGS_NORMAL_PATH                (0x0000)
+#define MPI25_SCSIIO_IOFLAGS_FAST_PATH                  (0x4000)
 
+#define MPI26_SCSIIO_IOFLAGS_ESCAPE_PASSTHROUGH         (0x2000)
 #define MPI25_SCSIIO_IOFLAGS_LARGE_CDB                  (0x1000)
 #define MPI25_SCSIIO_IOFLAGS_BIDIRECTIONAL              (0x0800)
+#define MPI26_SCSIIO_IOFLAGS_PORT_REQUEST               (0x0400)
 #define MPI25_SCSIIO_IOFLAGS_CDBLENGTH_MASK             (0x01FF)
 
 /*MPI v2.5 defines for the EEDPFlags bits */
@@ -512,6 +520,7 @@ typedef struct _MPI2_SEP_REQUEST {
 #define MPI2_SEP_REQ_FLAGS_ENCLOSURE_SLOT_ADDRESS       (0x01)
 
 /*SlotStatus defines */
+#define MPI2_SEP_REQ_SLOTSTATUS_DEV_OFF                 (0x00080000)
 #define MPI2_SEP_REQ_SLOTSTATUS_REQUEST_REMOVE          (0x00040000)
 #define MPI2_SEP_REQ_SLOTSTATUS_IDENTIFY_REQUEST        (0x00020000)
 #define MPI2_SEP_REQ_SLOTSTATUS_REBUILD_STOPPED         (0x00000200)
@@ -547,6 +556,7 @@ typedef struct _MPI2_SEP_REPLY {
 	Mpi2SepReply_t, *pMpi2SepReply_t;
 
 /*SlotStatus defines */
+#define MPI2_SEP_REPLY_SLOTSTATUS_DEV_OFF               (0x00080000)
 #define MPI2_SEP_REPLY_SLOTSTATUS_REMOVE_READY          (0x00040000)
 #define MPI2_SEP_REPLY_SLOTSTATUS_IDENTIFY_REQUEST      (0x00020000)
 #define MPI2_SEP_REPLY_SLOTSTATUS_REBUILD_STOPPED       (0x00000200)
--- zfcpdump-kernel-4.4.orig/drivers/scsi/mpt3sas/mpi/mpi2_ioc.h
+++ zfcpdump-kernel-4.4/drivers/scsi/mpt3sas/mpi/mpi2_ioc.h
@@ -1,12 +1,12 @@
 /*
- * Copyright (c) 2000-2014 LSI Corporation.
+ * Copyright 2000-2015 Avago Technologies.  All rights reserved.
  *
  *
  *          Name:  mpi2_ioc.h
  *         Title:  MPI IOC, Port, Event, FW Download, and FW Upload messages
  * Creation Date:  October 11, 2006
  *
- * mpi2_ioc.h Version:  02.00.24
+ * mpi2_ioc.h Version:  02.00.26
  *
  * NOTE: Names (typedefs, defines, etc.) beginning with an MPI25 or Mpi25
  *       prefix are for use only on MPI v2.5 products, and must not be used
@@ -133,6 +133,10 @@
  *			Added MPI2_FW_DOWNLOAD_ITYPE_PUBLIC_KEY.
  *			Added Encrypted Hash Extended Image.
  * 12-05-13  02.00.24  Added MPI25_HASH_IMAGE_TYPE_BIOS.
+ * 11-18-14  02.00.25  Updated copyright information.
+ * 03-16-15  02.00.26  Added MPI26_FW_HEADER_PID_FAMILY_3324_SAS and
+ *                     MPI26_FW_HEADER_PID_FAMILY_3516_SAS.
+ *                     Added MPI26_CTRL_OP_SHUTDOWN.
  * --------------------------------------------------------------------------
  */
 
@@ -165,7 +169,7 @@ typedef struct _MPI2_IOC_INIT_REQUEST {
 	U16 HeaderVersion;	/*0x0E */
 	U32 Reserved5;		/*0x10 */
 	U16 Reserved6;		/*0x14 */
-	U8 Reserved7;		/*0x16 */
+	U8 HostPageSize;	/*0x16 */
 	U8 HostMSIxVectors;	/*0x17 */
 	U16 Reserved8;		/*0x18 */
 	U16 SystemRequestFrameSize;	/*0x1A */
@@ -289,7 +293,8 @@ typedef struct _MPI2_IOC_FACTS_REPLY {
 	U16 MaxDevHandle;	/*0x38 */
 	U16 MaxPersistentEntries;	/*0x3A */
 	U16 MinDevHandle;	/*0x3C */
-	U16 Reserved4;		/*0x3E */
+	U8 CurrentHostPageSize;	/* 0x3E */
+	U8 Reserved4;		/* 0x3F */
 } MPI2_IOC_FACTS_REPLY, *PTR_MPI2_IOC_FACTS_REPLY,
 	Mpi2IOCFactsReply_t, *pMpi2IOCFactsReply_t;
 
@@ -326,6 +331,7 @@ typedef struct _MPI2_IOC_FACTS_REPLY {
 /*ProductID field uses MPI2_FW_HEADER_PID_ */
 
 /*IOCCapabilities */
+#define MPI26_IOCFACTS_CAPABILITY_ATOMIC_REQ            (0x00080000)
 #define MPI2_IOCFACTS_CAPABILITY_RDPQ_ARRAY_CAPABLE     (0x00040000)
 #define MPI25_IOCFACTS_CAPABILITY_FAST_PATH_CAPABLE     (0x00020000)
 #define MPI2_IOCFACTS_CAPABILITY_HOST_BASED_DISCOVERY   (0x00010000)
@@ -343,8 +349,8 @@ typedef struct _MPI2_IOC_FACTS_REPLY {
 #define MPI2_IOCFACTS_CAPABILITY_TASK_SET_FULL_HANDLING (0x00000004)
 
 /*ProtocolFlags */
-#define MPI2_IOCFACTS_PROTOCOL_SCSI_TARGET              (0x0001)
 #define MPI2_IOCFACTS_PROTOCOL_SCSI_INITIATOR           (0x0002)
+#define MPI2_IOCFACTS_PROTOCOL_SCSI_TARGET              (0x0001)
 
 /****************************************************************************
 * PortFacts message
@@ -1247,6 +1253,7 @@ typedef struct _MPI2_FW_UPLOAD_REQUEST {
 #define MPI2_FW_UPLOAD_ITYPE_MEGARAID           (0x09)
 #define MPI2_FW_UPLOAD_ITYPE_COMPLETE           (0x0A)
 #define MPI2_FW_UPLOAD_ITYPE_COMMON_BOOT_BLOCK  (0x0B)
+#define MPI2_FW_UPLOAD_ITYPE_CBB_BACKUP         (0x0D)
 
 /*MPI v2.0 FWUpload TransactionContext Element */
 typedef struct _MPI2_FW_UPLOAD_TCSGE {
@@ -1328,7 +1335,7 @@ typedef struct _MPI2_FW_IMAGE_HEADER {
 	U32 Reserved54;		/*0x54 */
 	U32 Reserved58;		/*0x58 */
 	U32 Reserved5C;		/*0x5C */
-	U32 Reserved60;		/*0x60 */
+	U32 BootFlags;		/*0x60 */
 	U32 FirmwareVersionNameWhat;	/*0x64 */
 	U8 FirmwareVersionName[32];	/*0x68 */
 	U32 VendorNameWhat;	/*0x88 */
@@ -1354,18 +1361,22 @@ typedef struct _MPI2_FW_IMAGE_HEADER {
 #define MPI2_FW_HEADER_SIGNATURE_OFFSET         (0x00)
 #define MPI2_FW_HEADER_SIGNATURE_MASK           (0xFF000000)
 #define MPI2_FW_HEADER_SIGNATURE                (0xEA000000)
+#define MPI26_FW_HEADER_SIGNATURE               (0xEB000000)
 
 /*Signature0 field */
 #define MPI2_FW_HEADER_SIGNATURE0_OFFSET        (0x04)
 #define MPI2_FW_HEADER_SIGNATURE0               (0x5AFAA55A)
+#define MPI26_FW_HEADER_SIGNATURE0              (0x5AEAA55A)
 
 /*Signature1 field */
 #define MPI2_FW_HEADER_SIGNATURE1_OFFSET        (0x08)
 #define MPI2_FW_HEADER_SIGNATURE1               (0xA55AFAA5)
+#define MPI26_FW_HEADER_SIGNATURE1              (0xA55AEAA5)
 
 /*Signature2 field */
 #define MPI2_FW_HEADER_SIGNATURE2_OFFSET        (0x0C)
 #define MPI2_FW_HEADER_SIGNATURE2               (0x5AA55AFA)
+#define MPI26_FW_HEADER_SIGNATURE2              (0x5AA55AEA)
 
 /*defines for using the ProductID field */
 #define MPI2_FW_HEADER_PID_TYPE_MASK            (0xF000)
@@ -1381,6 +1392,8 @@ typedef struct _MPI2_FW_IMAGE_HEADER {
 #define MPI2_FW_HEADER_PID_FAMILY_2108_SAS      (0x0013)
 #define MPI2_FW_HEADER_PID_FAMILY_2208_SAS      (0x0014)
 #define MPI25_FW_HEADER_PID_FAMILY_3108_SAS     (0x0021)
+#define MPI26_FW_HEADER_PID_FAMILY_3324_SAS     (0x0028)
+#define MPI26_FW_HEADER_PID_FAMILY_3516_SAS     (0x0031)
 
 /*use MPI2_IOCFACTS_PROTOCOL_ defines for ProtocolFlags field */
 
@@ -1388,6 +1401,7 @@ typedef struct _MPI2_FW_IMAGE_HEADER {
 
 #define MPI2_FW_HEADER_IMAGESIZE_OFFSET         (0x2C)
 #define MPI2_FW_HEADER_NEXTIMAGE_OFFSET         (0x30)
+#define MPI26_FW_HEADER_BOOTFLAGS_OFFSET        (0x60)
 #define MPI2_FW_HEADER_VERNMHWAT_OFFSET         (0x64)
 
 #define MPI2_FW_HEADER_WHAT_SIGNATURE           (0x29232840)
@@ -1493,7 +1507,9 @@ typedef struct _MPI2_FLASH_LAYOUT_DATA {
 #define MPI2_FLASH_REGION_CONFIG_1              (0x07)
 #define MPI2_FLASH_REGION_CONFIG_2              (0x08)
 #define MPI2_FLASH_REGION_MEGARAID              (0x09)
-#define MPI2_FLASH_REGION_INIT                  (0x0A)
+#define MPI2_FLASH_REGION_COMMON_BOOT_BLOCK     (0x0A)
+#define MPI2_FLASH_REGION_INIT (MPI2_FLASH_REGION_COMMON_BOOT_BLOCK)
+#define MPI2_FLASH_REGION_CBB_BACKUP            (0x0D)
 
 /*ImageRevision */
 #define MPI2_FLASH_LAYOUT_IMAGE_REVISION        (0x00)
@@ -1619,7 +1635,6 @@ typedef struct _MPI25_ENCRYPTED_HASH_DAT
 Mpi25EncryptedHashData_t, *pMpi25EncryptedHashData_t;
 
 
-
 /****************************************************************************
 * PowerManagementControl message
 ****************************************************************************/
@@ -1726,4 +1741,90 @@ typedef struct _MPI2_PWR_MGMT_CONTROL_RE
 } MPI2_PWR_MGMT_CONTROL_REPLY, *PTR_MPI2_PWR_MGMT_CONTROL_REPLY,
 	Mpi2PwrMgmtControlReply_t, *pMpi2PwrMgmtControlReply_t;
 
+/****************************************************************************
+*  IO Unit Control messages (MPI v2.6 and later only.)
+****************************************************************************/
+
+/* IO Unit Control Request Message */
+typedef struct _MPI26_IOUNIT_CONTROL_REQUEST {
+	U8                      Operation;          /* 0x00 */
+	U8                      Reserved1;          /* 0x01 */
+	U8                      ChainOffset;        /* 0x02 */
+	U8                      Function;           /* 0x03 */
+	U16                     DevHandle;          /* 0x04 */
+	U8                      IOCParameter;       /* 0x06 */
+	U8                      MsgFlags;           /* 0x07 */
+	U8                      VP_ID;              /* 0x08 */
+	U8                      VF_ID;              /* 0x09 */
+	U16                     Reserved3;          /* 0x0A */
+	U16                     Reserved4;          /* 0x0C */
+	U8                      PhyNum;             /* 0x0E */
+	U8                      PrimFlags;          /* 0x0F */
+	U32                     Primitive;          /* 0x10 */
+	U8                      LookupMethod;       /* 0x14 */
+	U8                      Reserved5;          /* 0x15 */
+	U16                     SlotNumber;         /* 0x16 */
+	U64                     LookupAddress;      /* 0x18 */
+	U32                     IOCParameterValue;  /* 0x20 */
+	U32                     Reserved7;          /* 0x24 */
+	U32                     Reserved8;          /* 0x28 */
+} MPI26_IOUNIT_CONTROL_REQUEST,
+	*PTR_MPI26_IOUNIT_CONTROL_REQUEST,
+	Mpi26IoUnitControlRequest_t,
+	*pMpi26IoUnitControlRequest_t;
+
+/* values for the Operation field */
+#define MPI26_CTRL_OP_CLEAR_ALL_PERSISTENT              (0x02)
+#define MPI26_CTRL_OP_SAS_PHY_LINK_RESET                (0x06)
+#define MPI26_CTRL_OP_SAS_PHY_HARD_RESET                (0x07)
+#define MPI26_CTRL_OP_PHY_CLEAR_ERROR_LOG               (0x08)
+#define MPI26_CTRL_OP_SAS_SEND_PRIMITIVE                (0x0A)
+#define MPI26_CTRL_OP_FORCE_FULL_DISCOVERY              (0x0B)
+#define MPI26_CTRL_OP_REMOVE_DEVICE                     (0x0D)
+#define MPI26_CTRL_OP_LOOKUP_MAPPING                    (0x0E)
+#define MPI26_CTRL_OP_SET_IOC_PARAMETER                 (0x0F)
+#define MPI26_CTRL_OP_ENABLE_FP_DEVICE                  (0x10)
+#define MPI26_CTRL_OP_DISABLE_FP_DEVICE                 (0x11)
+#define MPI26_CTRL_OP_ENABLE_FP_ALL                     (0x12)
+#define MPI26_CTRL_OP_DISABLE_FP_ALL                    (0x13)
+#define MPI26_CTRL_OP_DEV_ENABLE_NCQ                    (0x14)
+#define MPI26_CTRL_OP_DEV_DISABLE_NCQ                   (0x15)
+#define MPI26_CTRL_OP_SHUTDOWN                          (0x16)
+#define MPI26_CTRL_OP_DEV_ENABLE_PERSIST_CONNECTION     (0x17)
+#define MPI26_CTRL_OP_DEV_DISABLE_PERSIST_CONNECTION    (0x18)
+#define MPI26_CTRL_OP_DEV_CLOSE_PERSIST_CONNECTION      (0x19)
+#define MPI26_CTRL_OP_PRODUCT_SPECIFIC_MIN              (0x80)
+
+/* values for the PrimFlags field */
+#define MPI26_CTRL_PRIMFLAGS_SINGLE                     (0x08)
+#define MPI26_CTRL_PRIMFLAGS_TRIPLE                     (0x02)
+#define MPI26_CTRL_PRIMFLAGS_REDUNDANT                  (0x01)
+
+/* values for the LookupMethod field */
+#define MPI26_CTRL_LOOKUP_METHOD_WWID_ADDRESS           (0x01)
+#define MPI26_CTRL_LOOKUP_METHOD_ENCLOSURE_SLOT         (0x02)
+#define MPI26_CTRL_LOOKUP_METHOD_SAS_DEVICE_NAME        (0x03)
+
+
+/* IO Unit Control Reply Message */
+typedef struct _MPI26_IOUNIT_CONTROL_REPLY {
+	U8                      Operation;          /* 0x00 */
+	U8                      Reserved1;          /* 0x01 */
+	U8                      MsgLength;          /* 0x02 */
+	U8                      Function;           /* 0x03 */
+	U16                     DevHandle;          /* 0x04 */
+	U8                      IOCParameter;       /* 0x06 */
+	U8                      MsgFlags;           /* 0x07 */
+	U8                      VP_ID;              /* 0x08 */
+	U8                      VF_ID;              /* 0x09 */
+	U16                     Reserved3;          /* 0x0A */
+	U16                     Reserved4;          /* 0x0C */
+	U16                     IOCStatus;          /* 0x0E */
+	U32                     IOCLogInfo;         /* 0x10 */
+} MPI26_IOUNIT_CONTROL_REPLY,
+	*PTR_MPI26_IOUNIT_CONTROL_REPLY,
+	Mpi26IoUnitControlReply_t,
+	*pMpi26IoUnitControlReply_t;
+
+
 #endif
--- zfcpdump-kernel-4.4.orig/drivers/scsi/mpt3sas/mpi/mpi2_raid.h
+++ zfcpdump-kernel-4.4/drivers/scsi/mpt3sas/mpi/mpi2_raid.h
@@ -1,12 +1,12 @@
 /*
- * Copyright (c) 2000-2014 LSI Corporation.
+ * Copyright 2000-2014 Avago Technologies.  All rights reserved.
  *
  *
  *          Name:  mpi2_raid.h
  *         Title:  MPI Integrated RAID messages and structures
  * Creation Date:  April 26, 2007
  *
- *   mpi2_raid.h Version:  02.00.10
+ *   mpi2_raid.h Version:  02.00.11
  *
  * Version History
  * ---------------
@@ -31,6 +31,7 @@
  * 07-26-12  02.00.09  Added ElapsedSeconds field to MPI2_RAID_VOL_INDICATOR.
  *                     Added MPI2_RAID_VOL_FLAGS_ELAPSED_SECONDS_VALID define.
  * 04-17-13  02.00.10  Added MPI25_RAID_ACTION_ADATA_ALLOW_PI.
+ * 11-18-14  02.00.11  Updated copyright information.
  * --------------------------------------------------------------------------
  */
 
--- zfcpdump-kernel-4.4.orig/drivers/scsi/mpt3sas/mpi/mpi2_sas.h
+++ zfcpdump-kernel-4.4/drivers/scsi/mpt3sas/mpi/mpi2_sas.h
@@ -1,12 +1,12 @@
 /*
- * Copyright (c) 2000-2014 LSI Corporation.
+ * Copyright 2000-2015 Avago Technologies.  All rights reserved.
  *
  *
  *          Name:  mpi2_sas.h
  *         Title:  MPI Serial Attached SCSI structures and definitions
  * Creation Date:  February 9, 2007
  *
- * mpi2_sas.h Version:  02.00.08
+ * mpi2_sas.h Version:  02.00.10
  *
  * NOTE: Names (typedefs, defines, etc.) beginning with an MPI25 or Mpi25
  *       prefix are for use only on MPI v2.5 products, and must not be used
@@ -32,6 +32,9 @@
  *                     Passthrough Request message.
  * 08-19-13  02.00.08  Made MPI2_SAS_OP_TRANSMIT_PORT_SELECT_SIGNAL obsolete
  *			for anything newer than MPI v2.0.
+ * 11-18-14  02.00.09  Updated copyright information.
+ * 03-16-15  02.00.10  Updated for MPI v2.6.
+ *                     Added MPI2_SATA_PT_REQ_PT_FLAGS_FPDMA.
  * --------------------------------------------------------------------------
  */
 
@@ -183,6 +186,7 @@ typedef struct _MPI2_SATA_PASSTHROUGH_RE
 
 /*values for PassthroughFlags field */
 #define MPI2_SATA_PT_REQ_PT_FLAGS_EXECUTE_DIAG      (0x0100)
+#define MPI2_SATA_PT_REQ_PT_FLAGS_FPDMA             (0x0040)
 #define MPI2_SATA_PT_REQ_PT_FLAGS_DMA               (0x0020)
 #define MPI2_SATA_PT_REQ_PT_FLAGS_PIO               (0x0010)
 #define MPI2_SATA_PT_REQ_PT_FLAGS_UNSPECIFIED_VU    (0x0004)
@@ -216,6 +220,8 @@ typedef struct _MPI2_SATA_PASSTHROUGH_RE
 
 /****************************************************************************
 * SAS IO Unit Control messages
+* (MPI v2.5 and earlier only.
+* Replaced by IO Unit Control messages in MPI v2.6 and later.)
 ****************************************************************************/
 
 /*SAS IO Unit Control Request Message */
--- zfcpdump-kernel-4.4.orig/drivers/scsi/mpt3sas/mpi/mpi2_tool.h
+++ zfcpdump-kernel-4.4/drivers/scsi/mpt3sas/mpi/mpi2_tool.h
@@ -1,12 +1,12 @@
 /*
- * Copyright (c) 2000-2014 LSI Corporation.
+ * Copyright 2000-2014 Avago Technologies.  All rights reserved.
  *
  *
  *          Name:  mpi2_tool.h
  *         Title:  MPI diagnostic tool structures and definitions
  * Creation Date:  March 26, 2007
  *
- *   mpi2_tool.h Version:  02.00.12
+ *   mpi2_tool.h Version:  02.00.13
  *
  * Version History
  * ---------------
@@ -34,6 +34,7 @@
  *                     it uses MPI Chain SGE as well as MPI Simple SGE.
  * 08-19-13  02.00.11  Added MPI2_TOOLBOX_TEXT_DISPLAY_TOOL and related info.
  * 01-08-14  02.00.12  Added MPI2_TOOLBOX_CLEAN_BIT26_PRODUCT_SPECIFIC.
+ * 11-18-14  02.00.13  Updated copyright information.
  * --------------------------------------------------------------------------
  */
 
--- zfcpdump-kernel-4.4.orig/drivers/scsi/mpt3sas/mpi/mpi2_type.h
+++ zfcpdump-kernel-4.4/drivers/scsi/mpt3sas/mpi/mpi2_type.h
@@ -1,12 +1,12 @@
 /*
- *  Copyright (c) 2000-2014 LSI Corporation.
+ *  Copyright 2000-2014 Avago Technologies.  All rights reserved.
  *
  *
  *           Name:  mpi2_type.h
  *          Title:  MPI basic type definitions
  *  Creation Date:  August 16, 2006
  *
- *    mpi2_type.h Version:  02.00.00
+ *    mpi2_type.h Version:  02.00.01
  *
  *  Version History
  *  ---------------
@@ -14,6 +14,7 @@
  *  Date      Version   Description
  *  --------  --------  ------------------------------------------------------
  *  04-30-07  02.00.00  Corresponds to Fusion-MPT MPI Specification Rev A.
+ *  11-18-14  02.00.01  Updated copyright information.
  *  --------------------------------------------------------------------------
  */
 
--- zfcpdump-kernel-4.4.orig/drivers/scsi/mpt3sas/mpt3sas_base.c
+++ zfcpdump-kernel-4.4/drivers/scsi/mpt3sas/mpt3sas_base.c
@@ -83,6 +83,10 @@ static int msix_disable = -1;
 module_param(msix_disable, int, 0);
 MODULE_PARM_DESC(msix_disable, " disable msix routed interrupts (default=0)");
 
+static int smp_affinity_enable = 1;
+module_param(smp_affinity_enable, int, S_IRUGO);
+MODULE_PARM_DESC(smp_affinity_enable, "SMP affinity feature enable/disbale Default: enable(1)");
+
 static int max_msix_vectors = -1;
 module_param(max_msix_vectors, int, 0);
 MODULE_PARM_DESC(max_msix_vectors,
@@ -395,6 +399,9 @@ _base_sas_ioc_info(struct MPT3SAS_ADAPTE
 	case MPI2_IOCSTATUS_INSUFFICIENT_RESOURCES:
 		desc = "insufficient resources";
 		break;
+	case MPI2_IOCSTATUS_INSUFFICIENT_POWER:
+		desc = "insufficient power";
+		break;
 	case MPI2_IOCSTATUS_INVALID_FIELD:
 		desc = "invalid field";
 		break;
@@ -772,7 +779,7 @@ mpt3sas_base_done(struct MPT3SAS_ADAPTER
 
 	mpi_reply = mpt3sas_base_get_reply_virt_addr(ioc, reply);
 	if (mpi_reply && mpi_reply->Function == MPI2_FUNCTION_EVENT_ACK)
-		return 1;
+		return mpt3sas_check_for_pending_internal_cmds(ioc, smid);
 
 	if (ioc->base_cmds.status == MPT3_CMD_NOT_USED)
 		return 1;
@@ -803,6 +810,7 @@ _base_async_event(struct MPT3SAS_ADAPTER
 	Mpi2EventNotificationReply_t *mpi_reply;
 	Mpi2EventAckRequest_t *ack_request;
 	u16 smid;
+	struct _event_ack_list *delayed_event_ack;
 
 	mpi_reply = mpt3sas_base_get_reply_virt_addr(ioc, reply);
 	if (!mpi_reply)
@@ -816,8 +824,18 @@ _base_async_event(struct MPT3SAS_ADAPTER
 		goto out;
 	smid = mpt3sas_base_get_smid(ioc, ioc->base_cb_idx);
 	if (!smid) {
-		pr_err(MPT3SAS_FMT "%s: failed obtaining a smid\n",
-		    ioc->name, __func__);
+		delayed_event_ack = kzalloc(sizeof(*delayed_event_ack),
+					GFP_ATOMIC);
+		if (!delayed_event_ack)
+			goto out;
+		INIT_LIST_HEAD(&delayed_event_ack->list);
+		delayed_event_ack->Event = mpi_reply->Event;
+		delayed_event_ack->EventContext = mpi_reply->EventContext;
+		list_add_tail(&delayed_event_ack->list,
+				&ioc->delayed_event_ack_list);
+		dewtprintk(ioc, pr_info(MPT3SAS_FMT
+				"DELAYED: EVENT ACK: event (0x%04x)\n",
+				ioc->name, le16_to_cpu(mpi_reply->Event)));
 		goto out;
 	}
 
@@ -1348,6 +1366,7 @@ _base_build_zero_len_sge_ieee(struct MPT
 	u8 sgl_flags = (MPI2_IEEE_SGE_FLAGS_SIMPLE_ELEMENT |
 		MPI2_IEEE_SGE_FLAGS_SYSTEM_ADDR |
 		MPI25_IEEE_SGE_FLAGS_END_OF_LIST);
+
 	_base_add_sg_single_ieee(paddr, sgl_flags, 0, 0, -1);
 }
 
@@ -1797,8 +1816,10 @@ _base_free_irq(struct MPT3SAS_ADAPTER *i
 
 	list_for_each_entry_safe(reply_q, next, &ioc->reply_queue_list, list) {
 		list_del(&reply_q->list);
-		irq_set_affinity_hint(reply_q->vector, NULL);
-		free_cpumask_var(reply_q->affinity_hint);
+		if (smp_affinity_enable) {
+			irq_set_affinity_hint(reply_q->vector, NULL);
+			free_cpumask_var(reply_q->affinity_hint);
+		}
 		synchronize_irq(reply_q->vector);
 		free_irq(reply_q->vector, reply_q);
 		kfree(reply_q);
@@ -1829,9 +1850,12 @@ _base_request_irq(struct MPT3SAS_ADAPTER
 	reply_q->msix_index = index;
 	reply_q->vector = vector;
 
-	if (!alloc_cpumask_var(&reply_q->affinity_hint, GFP_KERNEL))
-		return -ENOMEM;
-	cpumask_clear(reply_q->affinity_hint);
+	if (smp_affinity_enable) {
+		if (!zalloc_cpumask_var(&reply_q->affinity_hint, GFP_KERNEL)) {
+			kfree(reply_q);
+			return -ENOMEM;
+		}
+	}
 
 	atomic_set(&reply_q->busy, 0);
 	if (ioc->msix_enable)
@@ -1845,6 +1869,7 @@ _base_request_irq(struct MPT3SAS_ADAPTER
 	if (r) {
 		pr_err(MPT3SAS_FMT "unable to allocate interrupt %d!\n",
 		    reply_q->name, vector);
+		free_cpumask_var(reply_q->affinity_hint);
 		kfree(reply_q);
 		return -EBUSY;
 	}
@@ -1894,16 +1919,17 @@ _base_assign_reply_queues(struct MPT3SAS
 
 		for (i = 0 ; i < group ; i++) {
 			ioc->cpu_msix_table[cpu] = index;
-			cpumask_or(reply_q->affinity_hint,
+			if (smp_affinity_enable)
+				cpumask_or(reply_q->affinity_hint,
 				   reply_q->affinity_hint, get_cpu_mask(cpu));
 			cpu = cpumask_next(cpu, cpu_online_mask);
 		}
-
-		if (irq_set_affinity_hint(reply_q->vector,
+		if (smp_affinity_enable)
+			if (irq_set_affinity_hint(reply_q->vector,
 					   reply_q->affinity_hint))
-			dinitprintk(ioc, pr_info(MPT3SAS_FMT
-			    "error setting affinity hint for irq vector %d\n",
-			    ioc->name, reply_q->vector));
+				dinitprintk(ioc, pr_info(MPT3SAS_FMT
+				 "Err setting affinity hint to irq vector %d\n",
+				 ioc->name, reply_q->vector));
 		index++;
 	}
 }
@@ -1961,6 +1987,9 @@ _base_enable_msix(struct MPT3SAS_ADAPTER
 	} else if (max_msix_vectors == 0)
 		goto try_ioapic;
 
+	if (ioc->msix_vector_count < ioc->cpu_count)
+		smp_affinity_enable = 0;
+
 	entries = kcalloc(ioc->reply_queue_count, sizeof(struct msix_entry),
 	    GFP_KERNEL);
 	if (!entries) {
@@ -2020,8 +2049,10 @@ mpt3sas_base_unmap_resources(struct MPT3
 	_base_free_irq(ioc);
 	_base_disable_msix(ioc);
 
-	if (ioc->msix96_vector)
+	if (ioc->msix96_vector) {
 		kfree(ioc->replyPostRegisterIndex);
+		ioc->replyPostRegisterIndex = NULL;
+	}
 
 	if (ioc->chip_phys) {
 		iounmap(ioc->chip);
@@ -2155,6 +2186,17 @@ mpt3sas_base_map_resources(struct MPT3SA
 	} else
 		ioc->msix96_vector = 0;
 
+	if (ioc->is_warpdrive) {
+		ioc->reply_post_host_index[0] = (resource_size_t __iomem *)
+		    &ioc->chip->ReplyPostHostIndex;
+
+		for (i = 1; i < ioc->cpu_msix_table_sz; i++)
+			ioc->reply_post_host_index[i] =
+			(resource_size_t __iomem *)
+			((u8 __iomem *)&ioc->chip->Doorbell + (0x4000 + ((i - 1)
+			* 4)));
+	}
+
 	list_for_each_entry(reply_q, &ioc->reply_queue_list, list)
 		pr_info(MPT3SAS_FMT "%s: IRQ %d\n",
 		    reply_q->name,  ((ioc->msix_enable) ? "PCI-MSI-X enabled" :
@@ -2229,6 +2271,12 @@ mpt3sas_base_get_reply_virt_addr(struct
 	return ioc->reply + (phys_addr - (u32)ioc->reply_dma);
 }
 
+static inline u8
+_base_get_msix_index(struct MPT3SAS_ADAPTER *ioc)
+{
+	return ioc->cpu_msix_table[raw_smp_processor_id()];
+}
+
 /**
  * mpt3sas_base_get_smid - obtain a free smid from internal queue
  * @ioc: per adapter object
@@ -2289,6 +2337,7 @@ mpt3sas_base_get_smid_scsiio(struct MPT3
 	request->scmd = scmd;
 	request->cb_idx = cb_idx;
 	smid = request->smid;
+	request->msix_io = _base_get_msix_index(ioc);
 	list_del(&request->tracker_list);
 	spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
 	return smid;
@@ -2411,12 +2460,6 @@ _base_writeq(__u64 b, volatile void __io
 }
 #endif
 
-static inline u8
-_base_get_msix_index(struct MPT3SAS_ADAPTER *ioc)
-{
-	return ioc->cpu_msix_table[raw_smp_processor_id()];
-}
-
 /**
  * mpt3sas_base_put_smid_scsi_io - send SCSI_IO request to firmware
  * @ioc: per adapter object
@@ -2470,18 +2513,19 @@ mpt3sas_base_put_smid_fast_path(struct M
  * mpt3sas_base_put_smid_hi_priority - send Task Managment request to firmware
  * @ioc: per adapter object
  * @smid: system request message index
- *
+ * @msix_task: msix_task will be same as msix of IO incase of task abort else 0.
  * Return nothing.
  */
 void
-mpt3sas_base_put_smid_hi_priority(struct MPT3SAS_ADAPTER *ioc, u16 smid)
+mpt3sas_base_put_smid_hi_priority(struct MPT3SAS_ADAPTER *ioc, u16 smid,
+	u16 msix_task)
 {
 	Mpi2RequestDescriptorUnion_t descriptor;
 	u64 *request = (u64 *)&descriptor;
 
 	descriptor.HighPriority.RequestFlags =
 	    MPI2_REQ_DESCRIPT_FLAGS_HIGH_PRIORITY;
-	descriptor.HighPriority.MSIxIndex =  0;
+	descriptor.HighPriority.MSIxIndex =  msix_task;
 	descriptor.HighPriority.SMID = cpu_to_le16(smid);
 	descriptor.HighPriority.LMID = 0;
 	descriptor.HighPriority.Reserved1 = 0;
@@ -3183,20 +3227,35 @@ _base_allocate_memory_pools(struct MPT3S
 	}
 	ioc->shost->sg_tablesize = sg_tablesize;
 
-	ioc->hi_priority_depth = facts->HighPriorityCredit;
-	ioc->internal_depth = ioc->hi_priority_depth + (5);
+	ioc->internal_depth = min_t(int, (facts->HighPriorityCredit + (5)),
+		(facts->RequestCredit / 4));
+	if (ioc->internal_depth < INTERNAL_CMDS_COUNT) {
+		if (facts->RequestCredit <= (INTERNAL_CMDS_COUNT +
+				INTERNAL_SCSIIO_CMDS_COUNT)) {
+			pr_err(MPT3SAS_FMT "IOC doesn't have enough Request \
+			    Credits, it has just %d number of credits\n",
+			    ioc->name, facts->RequestCredit);
+			return -ENOMEM;
+		}
+		ioc->internal_depth = 10;
+	}
+
+	ioc->hi_priority_depth = ioc->internal_depth - (5);
 	/* command line tunables  for max controller queue depth */
 	if (max_queue_depth != -1 && max_queue_depth != 0) {
 		max_request_credit = min_t(u16, max_queue_depth +
-		    ioc->hi_priority_depth + ioc->internal_depth,
-		    facts->RequestCredit);
+			ioc->internal_depth, facts->RequestCredit);
 		if (max_request_credit > MAX_HBA_QUEUE_DEPTH)
 			max_request_credit =  MAX_HBA_QUEUE_DEPTH;
 	} else
 		max_request_credit = min_t(u16, facts->RequestCredit,
 		    MAX_HBA_QUEUE_DEPTH);
 
-	ioc->hba_queue_depth = max_request_credit;
+	/* Firmware maintains additional facts->HighPriorityCredit number of
+	 * credits for HiPriprity Request messages, so hba queue depth will be
+	 * sum of max_request_credit and high priority queue depth.
+	 */
+	ioc->hba_queue_depth = max_request_credit + ioc->hi_priority_depth;
 
 	/* request frame size */
 	ioc->request_sz = facts->IOCRequestFrameSize * 4;
@@ -3204,6 +3263,19 @@ _base_allocate_memory_pools(struct MPT3S
 	/* reply frame size */
 	ioc->reply_sz = facts->ReplyFrameSize * 4;
 
+	/* chain segment size */
+	if (ioc->hba_mpi_version_belonged != MPI2_VERSION) {
+		if (facts->IOCMaxChainSegmentSize)
+			ioc->chain_segment_sz =
+					facts->IOCMaxChainSegmentSize *
+					MAX_CHAIN_ELEMT_SZ;
+		else
+		/* set to 128 bytes size if IOCMaxChainSegmentSize is zero */
+			ioc->chain_segment_sz = DEFAULT_NUM_FWCHAIN_ELEMTS *
+						    MAX_CHAIN_ELEMT_SZ;
+	} else
+		ioc->chain_segment_sz = ioc->request_sz;
+
 	/* calculate the max scatter element size */
 	sge_size = max_t(u16, ioc->sge_size, ioc->sge_size_ieee);
 
@@ -3215,7 +3287,7 @@ _base_allocate_memory_pools(struct MPT3S
 	ioc->max_sges_in_main_message = max_sge_elements/sge_size;
 
 	/* now do the same for a chain buffer */
-	max_sge_elements = ioc->request_sz - sge_size;
+	max_sge_elements = ioc->chain_segment_sz - sge_size;
 	ioc->max_sges_in_chain_message = max_sge_elements/sge_size;
 
 	/*
@@ -3243,7 +3315,6 @@ _base_allocate_memory_pools(struct MPT3S
 		ioc->reply_post_queue_depth += 16 -
 		(ioc->reply_post_queue_depth % 16);
 
-
 	if (ioc->reply_post_queue_depth >
 	    facts->MaxReplyDescriptorPostQueueDepth) {
 		ioc->reply_post_queue_depth =
@@ -3325,7 +3396,7 @@ _base_allocate_memory_pools(struct MPT3S
 	/* set the scsi host can_queue depth
 	 * with some internal commands that could be outstanding
 	 */
-	ioc->shost->can_queue = ioc->scsiio_depth;
+	ioc->shost->can_queue = ioc->scsiio_depth - INTERNAL_SCSIIO_CMDS_COUNT;
 	dinitprintk(ioc, pr_info(MPT3SAS_FMT
 		"scsi host: can_queue depth (%d)\n",
 		ioc->name, ioc->shost->can_queue));
@@ -3352,8 +3423,8 @@ _base_allocate_memory_pools(struct MPT3S
 		    ioc->chains_needed_per_io, ioc->request_sz, sz/1024);
 		if (ioc->scsiio_depth < MPT3SAS_SAS_QUEUE_DEPTH)
 			goto out;
-		retry_sz += 64;
-		ioc->hba_queue_depth = max_request_credit - retry_sz;
+		retry_sz = 64;
+		ioc->hba_queue_depth -= retry_sz;
 		goto retry_allocation;
 	}
 
@@ -3408,7 +3479,7 @@ _base_allocate_memory_pools(struct MPT3S
 		goto out;
 	}
 	ioc->chain_dma_pool = pci_pool_create("chain pool", ioc->pdev,
-	    ioc->request_sz, 16, 0);
+	    ioc->chain_segment_sz, 16, 0);
 	if (!ioc->chain_dma_pool) {
 		pr_err(MPT3SAS_FMT "chain_dma_pool: pci_pool_create failed\n",
 			ioc->name);
@@ -3422,13 +3493,13 @@ _base_allocate_memory_pools(struct MPT3S
 			ioc->chain_depth = i;
 			goto chain_done;
 		}
-		total_sz += ioc->request_sz;
+		total_sz += ioc->chain_segment_sz;
 	}
  chain_done:
 	dinitprintk(ioc, pr_info(MPT3SAS_FMT
 		"chain pool depth(%d), frame_size(%d), pool_size(%d kB)\n",
-		ioc->name, ioc->chain_depth, ioc->request_sz,
-		((ioc->chain_depth *  ioc->request_sz))/1024));
+		ioc->name, ioc->chain_depth, ioc->chain_segment_sz,
+		((ioc->chain_depth *  ioc->chain_segment_sz))/1024));
 
 	/* initialize hi-priority queue smid's */
 	ioc->hpr_lookup = kcalloc(ioc->hi_priority_depth,
@@ -4289,6 +4360,10 @@ _base_get_ioc_facts(struct MPT3SAS_ADAPT
 	facts->FWVersion.Word = le32_to_cpu(mpi_reply.FWVersion.Word);
 	facts->IOCRequestFrameSize =
 	    le16_to_cpu(mpi_reply.IOCRequestFrameSize);
+	if (ioc->hba_mpi_version_belonged != MPI2_VERSION) {
+		facts->IOCMaxChainSegmentSize =
+			le16_to_cpu(mpi_reply.IOCMaxChainSegmentSize);
+	}
 	facts->MaxInitiators = le16_to_cpu(mpi_reply.MaxInitiators);
 	facts->MaxTargets = le16_to_cpu(mpi_reply.MaxTargets);
 	ioc->shost->max_id = -1;
@@ -4971,6 +5046,8 @@ _base_make_ioc_operational(struct MPT3SA
 	u32 reply_address;
 	u16 smid;
 	struct _tr_list *delayed_tr, *delayed_tr_next;
+	struct _sc_list *delayed_sc, *delayed_sc_next;
+	struct _event_ack_list *delayed_event_ack, *delayed_event_ack_next;
 	u8 hide_flag;
 	struct adapter_reply_queue *reply_q;
 	long reply_post_free;
@@ -4993,6 +5070,18 @@ _base_make_ioc_operational(struct MPT3SA
 		kfree(delayed_tr);
 	}
 
+	list_for_each_entry_safe(delayed_sc, delayed_sc_next,
+	    &ioc->delayed_sc_list, list) {
+		list_del(&delayed_sc->list);
+		kfree(delayed_sc);
+	}
+
+	list_for_each_entry_safe(delayed_event_ack, delayed_event_ack_next,
+	    &ioc->delayed_event_ack_list, list) {
+		list_del(&delayed_event_ack->list);
+		kfree(delayed_event_ack);
+	}
+
 	/* initialize the scsi lookup free list */
 	spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
 	INIT_LIST_HEAD(&ioc->free_list);
@@ -5201,17 +5290,6 @@ mpt3sas_base_attach(struct MPT3SAS_ADAPT
 	if (r)
 		goto out_free_resources;
 
-	if (ioc->is_warpdrive) {
-		ioc->reply_post_host_index[0] = (resource_size_t __iomem *)
-		    &ioc->chip->ReplyPostHostIndex;
-
-		for (i = 1; i < ioc->cpu_msix_table_sz; i++)
-			ioc->reply_post_host_index[i] =
-			(resource_size_t __iomem *)
-			((u8 __iomem *)&ioc->chip->Doorbell + (0x4000 + ((i - 1)
-			* 4)));
-	}
-
 	pci_set_drvdata(ioc->pdev, ioc->shost);
 	r = _base_get_ioc_facts(ioc, CAN_SLEEP);
 	if (r)
@@ -5224,6 +5302,7 @@ mpt3sas_base_attach(struct MPT3SAS_ADAPT
 		ioc->build_zero_len_sge = &_base_build_zero_len_sge;
 		break;
 	case MPI25_VERSION:
+	case MPI26_VERSION:
 		/*
 		 * In SAS3.0,
 		 * SCSI_IO, SMP_PASSTHRU, SATA_PASSTHRU, Target Assist, and
--- zfcpdump-kernel-4.4.orig/drivers/scsi/mpt3sas/mpt3sas_base.h
+++ zfcpdump-kernel-4.4/drivers/scsi/mpt3sas/mpt3sas_base.h
@@ -73,9 +73,9 @@
 #define MPT3SAS_DRIVER_NAME		"mpt3sas"
 #define MPT3SAS_AUTHOR "Avago Technologies <MPT-FusionLinux.pdl@avagotech.com>"
 #define MPT3SAS_DESCRIPTION	"LSI MPT Fusion SAS 3.0 Device Driver"
-#define MPT3SAS_DRIVER_VERSION		"09.102.00.00"
-#define MPT3SAS_MAJOR_VERSION		9
-#define MPT3SAS_MINOR_VERSION		102
+#define MPT3SAS_DRIVER_VERSION		"12.100.00.00"
+#define MPT3SAS_MAJOR_VERSION		12
+#define MPT3SAS_MINOR_VERSION		100
 #define MPT3SAS_BUILD_VERSION		0
 #define MPT3SAS_RELEASE_VERSION	00
 
@@ -122,11 +122,16 @@
 #define  NO_SLEEP			0
 
 #define INTERNAL_CMDS_COUNT		10	/* reserved cmds */
+/* reserved for issuing internally framed scsi io cmds */
+#define INTERNAL_SCSIIO_CMDS_COUNT	3
 
 #define MPI3_HIM_MASK			0xFFFFFFFF /* mask every bit*/
 
 #define MPT3SAS_INVALID_DEVICE_HANDLE	0xFFFF
 
+#define MAX_CHAIN_ELEMT_SZ		16
+#define DEFAULT_NUM_FWCHAIN_ELEMTS	8
+
 /*
  * reset phases
  */
@@ -398,6 +403,7 @@ struct MPT3SAS_DEVICE {
 	u8	configured_lun;
 	u8	block;
 	u8	tlr_snoop_check;
+	u8	ignore_delay_remove;
 };
 
 #define MPT3_CMD_NOT_USED	0x8000	/* free */
@@ -643,6 +649,7 @@ struct chain_tracker {
  * @cb_idx: callback index
  * @direct_io: To indicate whether I/O is direct (WARPDRIVE)
  * @tracker_list: list of free request (ioc->free_list)
+ * @msix_io: IO's msix
  */
 struct scsiio_tracker {
 	u16	smid;
@@ -651,6 +658,7 @@ struct scsiio_tracker {
 	u8	direct_io;
 	struct list_head chain_list;
 	struct list_head tracker_list;
+	u16     msix_io;
 };
 
 /**
@@ -676,6 +684,25 @@ struct _tr_list {
 	u16	state;
 };
 
+/**
+ * struct _sc_list - delayed SAS_IO_UNIT_CONTROL message list
+ * @handle: device handle
+ */
+struct _sc_list {
+	struct list_head list;
+	u16     handle;
+};
+
+/**
+ * struct _event_ack_list - delayed event acknowledgment list
+ * @Event: Event ID
+ * @EventContext: used to track the event uniquely
+ */
+struct _event_ack_list {
+	struct list_head list;
+	u16     Event;
+	u32     EventContext;
+};
 
 /**
  * struct adapter_reply_queue - the reply queue struct
@@ -737,7 +764,7 @@ struct mpt3sas_facts {
 	u32			IOCCapabilities;
 	union mpi3_version_union	FWVersion;
 	u16			IOCRequestFrameSize;
-	u16			Reserved3;
+	u16			IOCMaxChainSegmentSize;
 	u16			MaxInitiators;
 	u16			MaxTargets;
 	u16			MaxSasExpanders;
@@ -884,6 +911,8 @@ typedef void (*MPT3SAS_FLUSH_RUNNING_CMD
  * @max_sges_in_chain_message: number sg elements per chain
  * @chains_needed_per_io: max chains per io
  * @chain_depth: total chains allocated
+ * @chain_segment_sz: gives the max number of
+ *			SGEs accommodate on single chain buffer
  * @hi_priority_smid:
  * @hi_priority:
  * @hi_priority_dma:
@@ -921,6 +950,8 @@ typedef void (*MPT3SAS_FLUSH_RUNNING_CMD
  * @replyPostRegisterIndex: index of next position in Reply Desc Post Queue
  * @delayed_tr_list: target reset link list
  * @delayed_tr_volume_list: volume target reset link list
+ * @delayed_sc_list:
+ * @delayed_event_ack_list:
  * @temp_sensors_count: flag to carry the number of temperature sensors
  * @pci_access_mutex: Mutex to synchronize ioctl,sysfs show path and
  *	pci resource handling. PCI resource freeing will lead to free
@@ -1089,6 +1120,7 @@ struct MPT3SAS_ADAPTER {
 	u16		max_sges_in_chain_message;
 	u16		chains_needed_per_io;
 	u32		chain_depth;
+	u16		chain_segment_sz;
 
 	/* hi-priority queue */
 	u16		hi_priority_smid;
@@ -1142,6 +1174,8 @@ struct MPT3SAS_ADAPTER {
 
 	struct list_head delayed_tr_list;
 	struct list_head delayed_tr_volume_list;
+	struct list_head delayed_sc_list;
+	struct list_head delayed_event_ack_list;
 	u8		temp_sensors_count;
 	struct mutex pci_access_mutex;
 
@@ -1213,7 +1247,8 @@ void mpt3sas_base_put_smid_scsi_io(struc
 	u16 handle);
 void mpt3sas_base_put_smid_fast_path(struct MPT3SAS_ADAPTER *ioc, u16 smid,
 	u16 handle);
-void mpt3sas_base_put_smid_hi_priority(struct MPT3SAS_ADAPTER *ioc, u16 smid);
+void mpt3sas_base_put_smid_hi_priority(struct MPT3SAS_ADAPTER *ioc,
+	u16 smid, u16 msix_task);
 void mpt3sas_base_put_smid_default(struct MPT3SAS_ADAPTER *ioc, u16 smid);
 void mpt3sas_base_initialize_callback_handler(void);
 u8 mpt3sas_base_register_callback_handler(MPT_CALLBACK cb_func);
@@ -1259,6 +1294,8 @@ void mpt3sas_scsih_clear_tm_flag(struct
 void mpt3sas_expander_remove(struct MPT3SAS_ADAPTER *ioc, u64 sas_address);
 void mpt3sas_device_remove_by_sas_address(struct MPT3SAS_ADAPTER *ioc,
 	u64 sas_address);
+u8 mpt3sas_check_for_pending_internal_cmds(struct MPT3SAS_ADAPTER *ioc,
+	u16 smid);
 
 struct _sas_node *mpt3sas_scsih_expander_find_by_handle(
 	struct MPT3SAS_ADAPTER *ioc, u16 handle);
--- zfcpdump-kernel-4.4.orig/drivers/scsi/mpt3sas/mpt3sas_ctl.c
+++ zfcpdump-kernel-4.4/drivers/scsi/mpt3sas/mpt3sas_ctl.c
@@ -401,7 +401,8 @@ mpt3sas_ctl_event_callback(struct MPT3SA
 	Mpi2EventNotificationReply_t *mpi_reply;
 
 	mpi_reply = mpt3sas_base_get_reply_virt_addr(ioc, reply);
-	mpt3sas_ctl_add_to_event_log(ioc, mpi_reply);
+	if (mpi_reply)
+		mpt3sas_ctl_add_to_event_log(ioc, mpi_reply);
 	return 1;
 }
 
@@ -410,7 +411,7 @@ mpt3sas_ctl_event_callback(struct MPT3SA
  * @ioc: per adapter object
  * @iocpp: The ioc pointer is returned in this.
  * @mpi_version: will be MPI2_VERSION for mpt2ctl ioctl device &
- *		MPI25_VERSION for mpt3ctl ioctl device.
+ * MPI25_VERSION | MPI26_VERSION for mpt3ctl ioctl device.
  *
  * Return (-1) means error, else ioc_number.
  */
@@ -419,6 +420,7 @@ _ctl_verify_adapter(int ioc_number, stru
 							int mpi_version)
 {
 	struct MPT3SAS_ADAPTER *ioc;
+	int version = 0;
 	/* global ioc lock to protect controller on list operations */
 	spin_lock(&gioc_lock);
 	list_for_each_entry(ioc, &mpt3sas_ioc_list, list) {
@@ -427,8 +429,21 @@ _ctl_verify_adapter(int ioc_number, stru
 		/* Check whether this ioctl command is from right
 		 * ioctl device or not, if not continue the search.
 		 */
-		if (ioc->hba_mpi_version_belonged != mpi_version)
-			continue;
+		version = ioc->hba_mpi_version_belonged;
+		/* MPI25_VERSION and MPI26_VERSION uses same ioctl
+		 * device.
+		 */
+		if (mpi_version == (MPI25_VERSION | MPI26_VERSION)) {
+			if ((version == MPI25_VERSION) ||
+				(version == MPI26_VERSION))
+				goto out;
+			else
+				continue;
+		} else {
+			if (version != mpi_version)
+				continue;
+		}
+out:
 		spin_unlock(&gioc_lock);
 		*iocpp = ioc;
 		return ioc_number;
@@ -817,7 +832,7 @@ _ctl_do_mpt_command(struct MPT3SAS_ADAPT
 		    tm_request->DevHandle));
 		ioc->build_sg_mpi(ioc, psge, data_out_dma, data_out_sz,
 		    data_in_dma, data_in_sz);
-		mpt3sas_base_put_smid_hi_priority(ioc, smid);
+		mpt3sas_base_put_smid_hi_priority(ioc, smid, 0);
 		break;
 	}
 	case MPI2_FUNCTION_SMP_PASSTHROUGH:
@@ -1053,6 +1068,7 @@ _ctl_getiocinfo(struct MPT3SAS_ADAPTER *
 		strcat(karg.driver_version, MPT2SAS_DRIVER_VERSION);
 		break;
 	case MPI25_VERSION:
+	case MPI26_VERSION:
 		karg.adapter_type = MPT3_IOCTL_INTERFACE_SAS3;
 		strcat(karg.driver_version, MPT3SAS_DRIVER_VERSION);
 		break;
@@ -2203,7 +2219,7 @@ _ctl_compat_mpt_command(struct MPT3SAS_A
  * @arg - user space data buffer
  * @compat - handles 32 bit applications in 64bit os
  * @mpi_version: will be MPI2_VERSION for mpt2ctl ioctl device &
- *		MPI25_VERSION for mpt3ctl ioctl device.
+ * MPI25_VERSION | MPI26_VERSION for mpt3ctl ioctl device.
  */
 static long
 _ctl_ioctl_main(struct file *file, unsigned int cmd, void __user *arg,
@@ -2341,10 +2357,12 @@ _ctl_ioctl(struct file *file, unsigned i
 {
 	long ret;
 
-	/* pass MPI25_VERSION value, to indicate that this ioctl cmd
+	/* pass MPI25_VERSION | MPI26_VERSION value,
+	 * to indicate that this ioctl cmd
 	 * came from mpt3ctl ioctl device.
 	 */
-	ret = _ctl_ioctl_main(file, cmd, (void __user *)arg, 0, MPI25_VERSION);
+	ret = _ctl_ioctl_main(file, cmd, (void __user *)arg, 0,
+		MPI25_VERSION | MPI26_VERSION);
 	return ret;
 }
 
@@ -2379,7 +2397,8 @@ _ctl_ioctl_compat(struct file *file, uns
 {
 	long ret;
 
-	ret = _ctl_ioctl_main(file, cmd, (void __user *)arg, 1, MPI25_VERSION);
+	ret = _ctl_ioctl_main(file, cmd, (void __user *)arg, 1,
+		MPI25_VERSION | MPI26_VERSION);
 	return ret;
 }
 
--- zfcpdump-kernel-4.4.orig/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+++ zfcpdump-kernel-4.4/drivers/scsi/mpt3sas/mpt3sas_scsih.c
@@ -1589,10 +1589,16 @@ scsih_get_resync(struct device *dev)
 		percent_complete = 0;
 
  out:
-	if (ioc->hba_mpi_version_belonged == MPI2_VERSION)
+
+	switch (ioc->hba_mpi_version_belonged) {
+	case MPI2_VERSION:
 		raid_set_resync(mpt2sas_raid_template, dev, percent_complete);
-	if (ioc->hba_mpi_version_belonged == MPI25_VERSION)
+		break;
+	case MPI25_VERSION:
+	case MPI26_VERSION:
 		raid_set_resync(mpt3sas_raid_template, dev, percent_complete);
+		break;
+	}
 }
 
 /**
@@ -1650,10 +1656,15 @@ scsih_get_state(struct device *dev)
 		break;
 	}
  out:
-	if (ioc->hba_mpi_version_belonged == MPI2_VERSION)
+	switch (ioc->hba_mpi_version_belonged) {
+	case MPI2_VERSION:
 		raid_set_state(mpt2sas_raid_template, dev, state);
-	if (ioc->hba_mpi_version_belonged == MPI25_VERSION)
+		break;
+	case MPI25_VERSION:
+	case MPI26_VERSION:
 		raid_set_state(mpt3sas_raid_template, dev, state);
+		break;
+	}
 }
 
 /**
@@ -1682,12 +1693,17 @@ _scsih_set_level(struct MPT3SAS_ADAPTER
 		break;
 	}
 
-	if (ioc->hba_mpi_version_belonged == MPI2_VERSION)
+	switch (ioc->hba_mpi_version_belonged) {
+	case MPI2_VERSION:
 		raid_set_level(mpt2sas_raid_template,
-			       &sdev->sdev_gendev, level);
-	if (ioc->hba_mpi_version_belonged == MPI25_VERSION)
+			&sdev->sdev_gendev, level);
+		break;
+	case MPI25_VERSION:
+	case MPI26_VERSION:
 		raid_set_level(mpt3sas_raid_template,
-			       &sdev->sdev_gendev, level);
+			&sdev->sdev_gendev, level);
+		break;
+	}
 }
 
 
@@ -1937,7 +1953,15 @@ scsih_slave_configure(struct scsi_device
 	if (sas_device->device_info & MPI2_SAS_DEVICE_INFO_SSP_TARGET) {
 		qdepth = MPT3SAS_SAS_QUEUE_DEPTH;
 		ssp_target = 1;
-		ds = "SSP";
+		if (sas_device->device_info &
+				MPI2_SAS_DEVICE_INFO_SEP) {
+			sdev_printk(KERN_WARNING, sdev,
+			"set ignore_delay_remove for handle(0x%04x)\n",
+			sas_device_priv_data->sas_target->handle);
+			sas_device_priv_data->ignore_delay_remove = 1;
+			ds = "SES";
+		} else
+			ds = "SSP";
 	} else {
 		qdepth = MPT3SAS_SATA_QUEUE_DEPTH;
 		if (sas_device->device_info & MPI2_SAS_DEVICE_INFO_STP_TARGET)
@@ -2193,6 +2217,7 @@ mpt3sas_scsih_issue_tm(struct MPT3SAS_AD
 	unsigned long timeleft;
 	struct scsiio_tracker *scsi_lookup = NULL;
 	int rc;
+	u16 msix_task = 0;
 
 	if (m_type == TM_MUTEX_ON)
 		mutex_lock(&ioc->tm_cmds.mutex);
@@ -2256,7 +2281,12 @@ mpt3sas_scsih_issue_tm(struct MPT3SAS_AD
 	int_to_scsilun(lun, (struct scsi_lun *)mpi_request->LUN);
 	mpt3sas_scsih_set_tm_flag(ioc, handle);
 	init_completion(&ioc->tm_cmds.done);
-	mpt3sas_base_put_smid_hi_priority(ioc, smid);
+	if ((type == MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK) &&
+			(scsi_lookup->msix_io < ioc->reply_queue_count))
+		msix_task = scsi_lookup->msix_io;
+	else
+		msix_task = 0;
+	mpt3sas_base_put_smid_hi_priority(ioc, smid, msix_task);
 	timeleft = wait_for_completion_timeout(&ioc->tm_cmds.done, timeout*HZ);
 	if (!(ioc->tm_cmds.status & MPT3_CMD_COMPLETE)) {
 		pr_err(MPT3SAS_FMT "%s: timeout\n",
@@ -2383,7 +2413,7 @@ _scsih_tm_display_info(struct MPT3SAS_AD
 				 (unsigned long long)
 				 sas_device->enclosure_logical_id,
 				 sas_device->slot);
-			if (sas_device->connector_name)
+			if (sas_device->connector_name[0] != '\0')
 				starget_printk(KERN_INFO, starget,
 				"enclosure level(0x%04x),connector name(%s)\n",
 				 sas_device->enclosure_level,
@@ -2927,6 +2957,12 @@ _scsih_block_io_all_device(struct MPT3SA
 			continue;
 		if (sas_device_priv_data->block)
 			continue;
+		if (sas_device_priv_data->ignore_delay_remove) {
+			sdev_printk(KERN_INFO, sdev,
+			"%s skip device_block for SES handle(0x%04x)\n",
+			__func__, sas_device_priv_data->sas_target->handle);
+			continue;
+		}
 		_scsih_internal_device_block(sdev, sas_device_priv_data);
 	}
 }
@@ -2959,6 +2995,12 @@ _scsih_block_io_device(struct MPT3SAS_AD
 			continue;
 		if (sas_device->pend_sas_rphy_add)
 			continue;
+		if (sas_device_priv_data->ignore_delay_remove) {
+			sdev_printk(KERN_INFO, sdev,
+			"%s skip device_block for SES handle(0x%04x)\n",
+			__func__, sas_device_priv_data->sas_target->handle);
+			continue;
+		}
 		_scsih_internal_device_block(sdev, sas_device_priv_data);
 	}
 
@@ -3118,7 +3160,7 @@ _scsih_tm_tr_send(struct MPT3SAS_ADAPTER
 			 " slot(%d)\n", ioc->name, (unsigned long long)
 			  sas_device->enclosure_logical_id,
 			  sas_device->slot));
-		if (sas_device->connector_name)
+		if (sas_device->connector_name[0] != '\0')
 			dewtprintk(ioc, pr_info(MPT3SAS_FMT
 			 "setting delete flag: enclosure level(0x%04x),"
 			 " connector name( %s)\n", ioc->name,
@@ -3151,7 +3193,7 @@ _scsih_tm_tr_send(struct MPT3SAS_ADAPTER
 	mpi_request->Function = MPI2_FUNCTION_SCSI_TASK_MGMT;
 	mpi_request->DevHandle = cpu_to_le16(handle);
 	mpi_request->TaskType = MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET;
-	mpt3sas_base_put_smid_hi_priority(ioc, smid);
+	mpt3sas_base_put_smid_hi_priority(ioc, smid, 0);
 	mpt3sas_trigger_master(ioc, MASTER_TRIGGER_DEVICE_REMOVAL);
 
 out:
@@ -3186,6 +3228,7 @@ _scsih_tm_tr_complete(struct MPT3SAS_ADA
 	Mpi2SasIoUnitControlRequest_t *mpi_request;
 	u16 smid_sas_ctrl;
 	u32 ioc_state;
+	struct _sc_list *delayed_sc;
 
 	if (ioc->remove_host) {
 		dewtprintk(ioc, pr_info(MPT3SAS_FMT
@@ -3228,9 +3271,16 @@ _scsih_tm_tr_complete(struct MPT3SAS_ADA
 
 	smid_sas_ctrl = mpt3sas_base_get_smid(ioc, ioc->tm_sas_control_cb_idx);
 	if (!smid_sas_ctrl) {
-		pr_err(MPT3SAS_FMT "%s: failed obtaining a smid\n",
-		    ioc->name, __func__);
-		return 1;
+		delayed_sc = kzalloc(sizeof(*delayed_sc), GFP_ATOMIC);
+		if (!delayed_sc)
+			return _scsih_check_for_pending_tm(ioc, smid);
+		INIT_LIST_HEAD(&delayed_sc->list);
+		delayed_sc->handle = mpi_request_tm->DevHandle;
+		list_add_tail(&delayed_sc->list, &ioc->delayed_sc_list);
+		dewtprintk(ioc, pr_info(MPT3SAS_FMT
+		    "DELAYED:sc:handle(0x%04x), (open)\n",
+		    ioc->name, handle));
+		return _scsih_check_for_pending_tm(ioc, smid);
 	}
 
 	dewtprintk(ioc, pr_info(MPT3SAS_FMT
@@ -3281,7 +3331,7 @@ _scsih_sas_control_complete(struct MPT3S
 		pr_err(MPT3SAS_FMT "mpi_reply not valid at %s:%d/%s()!\n",
 		    ioc->name, __FILE__, __LINE__, __func__);
 	}
-	return 1;
+	return mpt3sas_check_for_pending_internal_cmds(ioc, smid);
 }
 
 /**
@@ -3332,7 +3382,7 @@ _scsih_tm_tr_volume_send(struct MPT3SAS_
 	mpi_request->Function = MPI2_FUNCTION_SCSI_TASK_MGMT;
 	mpi_request->DevHandle = cpu_to_le16(handle);
 	mpi_request->TaskType = MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET;
-	mpt3sas_base_put_smid_hi_priority(ioc, smid);
+	mpt3sas_base_put_smid_hi_priority(ioc, smid, 0);
 }
 
 /**
@@ -3388,6 +3438,142 @@ _scsih_tm_volume_tr_complete(struct MPT3
 	return _scsih_check_for_pending_tm(ioc, smid);
 }
 
+/**
+ * _scsih_issue_delayed_event_ack - issue delayed Event ACK messages
+ * @ioc: per adapter object
+ * @smid: system request message index
+ * @event: Event ID
+ * @event_context: used to track events uniquely
+ *
+ * Context - processed in interrupt context.
+ */
+void
+_scsih_issue_delayed_event_ack(struct MPT3SAS_ADAPTER *ioc, u16 smid, u16 event,
+				u32 event_context)
+{
+	Mpi2EventAckRequest_t *ack_request;
+	int i = smid - ioc->internal_smid;
+	unsigned long flags;
+
+	/* Without releasing the smid just update the
+	 * call back index and reuse the same smid for
+	 * processing this delayed request
+	 */
+	spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
+	ioc->internal_lookup[i].cb_idx = ioc->base_cb_idx;
+	spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
+
+	dewtprintk(ioc, pr_info(MPT3SAS_FMT
+		"EVENT ACK: event(0x%04x), smid(%d), cb(%d)\n",
+		ioc->name, le16_to_cpu(event), smid,
+		ioc->base_cb_idx));
+	ack_request = mpt3sas_base_get_msg_frame(ioc, smid);
+	memset(ack_request, 0, sizeof(Mpi2EventAckRequest_t));
+	ack_request->Function = MPI2_FUNCTION_EVENT_ACK;
+	ack_request->Event = event;
+	ack_request->EventContext = event_context;
+	ack_request->VF_ID = 0;  /* TODO */
+	ack_request->VP_ID = 0;
+	mpt3sas_base_put_smid_default(ioc, smid);
+}
+
+/**
+ * _scsih_issue_delayed_sas_io_unit_ctrl - issue delayed
+ *				sas_io_unit_ctrl messages
+ * @ioc: per adapter object
+ * @smid: system request message index
+ * @handle: device handle
+ *
+ * Context - processed in interrupt context.
+ */
+void
+_scsih_issue_delayed_sas_io_unit_ctrl(struct MPT3SAS_ADAPTER *ioc,
+					u16 smid, u16 handle)
+	{
+		Mpi2SasIoUnitControlRequest_t *mpi_request;
+		u32 ioc_state;
+		int i = smid - ioc->internal_smid;
+		unsigned long flags;
+
+		if (ioc->remove_host) {
+			dewtprintk(ioc, pr_info(MPT3SAS_FMT
+			    "%s: host has been removed\n",
+			     __func__, ioc->name));
+			return;
+		} else if (ioc->pci_error_recovery) {
+			dewtprintk(ioc, pr_info(MPT3SAS_FMT
+			    "%s: host in pci error recovery\n",
+			    __func__, ioc->name));
+		return;
+	}
+	ioc_state = mpt3sas_base_get_iocstate(ioc, 1);
+	if (ioc_state != MPI2_IOC_STATE_OPERATIONAL) {
+		dewtprintk(ioc, pr_info(MPT3SAS_FMT
+		    "%s: host is not operational\n",
+		    __func__, ioc->name));
+		return;
+	}
+
+	/* Without releasing the smid just update the
+	 * call back index and reuse the same smid for
+	 * processing this delayed request
+	 */
+	spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
+	ioc->internal_lookup[i].cb_idx = ioc->tm_sas_control_cb_idx;
+	spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
+
+	dewtprintk(ioc, pr_info(MPT3SAS_FMT
+	    "sc_send:handle(0x%04x), (open), smid(%d), cb(%d)\n",
+	    ioc->name, le16_to_cpu(handle), smid,
+	    ioc->tm_sas_control_cb_idx));
+	mpi_request = mpt3sas_base_get_msg_frame(ioc, smid);
+	memset(mpi_request, 0, sizeof(Mpi2SasIoUnitControlRequest_t));
+	mpi_request->Function = MPI2_FUNCTION_SAS_IO_UNIT_CONTROL;
+	mpi_request->Operation = MPI2_SAS_OP_REMOVE_DEVICE;
+	mpi_request->DevHandle = handle;
+	mpt3sas_base_put_smid_default(ioc, smid);
+}
+
+/**
+ * _scsih_check_for_pending_internal_cmds - check for pending internal messages
+ * @ioc: per adapter object
+ * @smid: system request message index
+ *
+ * Context: Executed in interrupt context
+ *
+ * This will check delayed internal messages list, and process the
+ * next request.
+ *
+ * Return 1 meaning mf should be freed from _base_interrupt
+ *        0 means the mf is freed from this function.
+ */
+u8
+mpt3sas_check_for_pending_internal_cmds(struct MPT3SAS_ADAPTER *ioc, u16 smid)
+{
+	struct _sc_list *delayed_sc;
+	struct _event_ack_list *delayed_event_ack;
+
+	if (!list_empty(&ioc->delayed_event_ack_list)) {
+		delayed_event_ack = list_entry(ioc->delayed_event_ack_list.next,
+						struct _event_ack_list, list);
+		_scsih_issue_delayed_event_ack(ioc, smid,
+		  delayed_event_ack->Event, delayed_event_ack->EventContext);
+		list_del(&delayed_event_ack->list);
+		kfree(delayed_event_ack);
+		return 0;
+	}
+
+	if (!list_empty(&ioc->delayed_sc_list)) {
+		delayed_sc = list_entry(ioc->delayed_sc_list.next,
+						struct _sc_list, list);
+		_scsih_issue_delayed_sas_io_unit_ctrl(ioc, smid,
+						 delayed_sc->handle);
+		list_del(&delayed_sc->list);
+		kfree(delayed_sc);
+		return 0;
+	}
+	return 1;
+}
 
 /**
  * _scsih_check_for_pending_tm - check for pending task management
@@ -4084,6 +4270,9 @@ _scsih_scsi_ioc_info(struct MPT3SAS_ADAP
 	case MPI2_IOCSTATUS_EEDP_APP_TAG_ERROR:
 		desc_ioc_state = "eedp app tag error";
 		break;
+	case MPI2_IOCSTATUS_INSUFFICIENT_POWER:
+		desc_ioc_state = "insufficient power";
+		break;
 	default:
 		desc_ioc_state = "unknown";
 		break;
@@ -4609,6 +4798,7 @@ _scsih_io_done(struct MPT3SAS_ADAPTER *i
 	case MPI2_IOCSTATUS_INVALID_STATE:
 	case MPI2_IOCSTATUS_SCSI_IO_DATA_ERROR:
 	case MPI2_IOCSTATUS_SCSI_TASK_MGMT_FAILED:
+	case MPI2_IOCSTATUS_INSUFFICIENT_POWER:
 	default:
 		scmd->result = DID_SOFT_ERROR << 16;
 		break;
@@ -8391,7 +8581,8 @@ static struct raid_function_template mpt
  * @pdev: PCI device struct
  *
  * return MPI2_VERSION for SAS 2.0 HBA devices,
- *	MPI25_VERSION for SAS 3.0 HBA devices.
+ *	MPI25_VERSION for SAS 3.0 HBA devices, and
+ *	MPI26 VERSION for Cutlass & Invader SAS 3.0 HBA devices
  */
 u16
 _scsih_determine_hba_mpi_version(struct pci_dev *pdev)
@@ -8423,6 +8614,17 @@ _scsih_determine_hba_mpi_version(struct
 	case MPI25_MFGPAGE_DEVID_SAS3108_5:
 	case MPI25_MFGPAGE_DEVID_SAS3108_6:
 		return MPI25_VERSION;
+	case MPI26_MFGPAGE_DEVID_SAS3216:
+	case MPI26_MFGPAGE_DEVID_SAS3224:
+	case MPI26_MFGPAGE_DEVID_SAS3316_1:
+	case MPI26_MFGPAGE_DEVID_SAS3316_2:
+	case MPI26_MFGPAGE_DEVID_SAS3316_3:
+	case MPI26_MFGPAGE_DEVID_SAS3316_4:
+	case MPI26_MFGPAGE_DEVID_SAS3324_1:
+	case MPI26_MFGPAGE_DEVID_SAS3324_2:
+	case MPI26_MFGPAGE_DEVID_SAS3324_3:
+	case MPI26_MFGPAGE_DEVID_SAS3324_4:
+		return MPI26_VERSION;
 	}
 	return 0;
 }
@@ -8456,7 +8658,8 @@ _scsih_probe(struct pci_dev *pdev, const
 	/* Enumerate only SAS 3.0 HBA's if hbas_to_enumerate is two,
 	 * for other generation HBA's return with -ENODEV
 	 */
-	if ((hbas_to_enumerate == 2) && (hba_mpi_version !=  MPI25_VERSION))
+	if ((hbas_to_enumerate == 2) && (!(hba_mpi_version ==  MPI25_VERSION
+		|| hba_mpi_version ==  MPI26_VERSION)))
 		return -ENODEV;
 
 	switch (hba_mpi_version) {
@@ -8478,6 +8681,7 @@ _scsih_probe(struct pci_dev *pdev, const
 			ioc->mfg_pg10_hide_flag = MFG_PAGE10_EXPOSE_ALL_DISKS;
 		break;
 	case MPI25_VERSION:
+	case MPI26_VERSION:
 		/* Use mpt3sas driver host template for SAS 3.0 HBA's */
 		shost = scsi_host_alloc(&mpt3sas_driver_template,
 		  sizeof(struct MPT3SAS_ADAPTER));
@@ -8488,7 +8692,9 @@ _scsih_probe(struct pci_dev *pdev, const
 		ioc->hba_mpi_version_belonged = hba_mpi_version;
 		ioc->id = mpt3_ids++;
 		sprintf(ioc->driver_name, "%s", MPT3SAS_DRIVER_NAME);
-		if (pdev->revision >= SAS3_PCI_DEVICE_C0_REVISION)
+		if ((ioc->hba_mpi_version_belonged == MPI25_VERSION &&
+			pdev->revision >= SAS3_PCI_DEVICE_C0_REVISION) ||
+			(ioc->hba_mpi_version_belonged == MPI26_VERSION))
 			ioc->msix96_vector = 1;
 		break;
 	default:
@@ -8533,6 +8739,8 @@ _scsih_probe(struct pci_dev *pdev, const
 	INIT_LIST_HEAD(&ioc->raid_device_list);
 	INIT_LIST_HEAD(&ioc->sas_hba.sas_port_list);
 	INIT_LIST_HEAD(&ioc->delayed_tr_list);
+	INIT_LIST_HEAD(&ioc->delayed_sc_list);
+	INIT_LIST_HEAD(&ioc->delayed_event_ack_list);
 	INIT_LIST_HEAD(&ioc->delayed_tr_volume_list);
 	INIT_LIST_HEAD(&ioc->reply_queue_list);
 
@@ -8866,6 +9074,28 @@ static const struct pci_device_id mpt3sa
 		PCI_ANY_ID, PCI_ANY_ID },
 	{ MPI2_MFGPAGE_VENDORID_LSI, MPI25_MFGPAGE_DEVID_SAS3108_6,
 		PCI_ANY_ID, PCI_ANY_ID },
+	/* Cutlass ~ 3216 and 3224 */
+	{ MPI2_MFGPAGE_VENDORID_LSI, MPI26_MFGPAGE_DEVID_SAS3216,
+		PCI_ANY_ID, PCI_ANY_ID },
+	{ MPI2_MFGPAGE_VENDORID_LSI, MPI26_MFGPAGE_DEVID_SAS3224,
+		PCI_ANY_ID, PCI_ANY_ID },
+	/* Intruder ~ 3316 and 3324 */
+	{ MPI2_MFGPAGE_VENDORID_LSI, MPI26_MFGPAGE_DEVID_SAS3316_1,
+		PCI_ANY_ID, PCI_ANY_ID },
+	{ MPI2_MFGPAGE_VENDORID_LSI, MPI26_MFGPAGE_DEVID_SAS3316_2,
+		PCI_ANY_ID, PCI_ANY_ID },
+	{ MPI2_MFGPAGE_VENDORID_LSI, MPI26_MFGPAGE_DEVID_SAS3316_3,
+		PCI_ANY_ID, PCI_ANY_ID },
+	{ MPI2_MFGPAGE_VENDORID_LSI, MPI26_MFGPAGE_DEVID_SAS3316_4,
+		PCI_ANY_ID, PCI_ANY_ID },
+	{ MPI2_MFGPAGE_VENDORID_LSI, MPI26_MFGPAGE_DEVID_SAS3324_1,
+		PCI_ANY_ID, PCI_ANY_ID },
+	{ MPI2_MFGPAGE_VENDORID_LSI, MPI26_MFGPAGE_DEVID_SAS3324_2,
+		PCI_ANY_ID, PCI_ANY_ID },
+	{ MPI2_MFGPAGE_VENDORID_LSI, MPI26_MFGPAGE_DEVID_SAS3324_3,
+		PCI_ANY_ID, PCI_ANY_ID },
+	{ MPI2_MFGPAGE_VENDORID_LSI, MPI26_MFGPAGE_DEVID_SAS3324_4,
+		PCI_ANY_ID, PCI_ANY_ID },
 	{0}     /* Terminating entry */
 };
 MODULE_DEVICE_TABLE(pci, mpt3sas_pci_table);
--- zfcpdump-kernel-4.4.orig/drivers/scsi/mpt3sas/mpt3sas_transport.c
+++ zfcpdump-kernel-4.4/drivers/scsi/mpt3sas/mpt3sas_transport.c
@@ -1418,7 +1418,6 @@ _transport_expander_phy_control(struct M
 	u32 ioc_state;
 	unsigned long timeleft;
 	void *psge;
-	u32 sgl_flags;
 	u8 issue_reset = 0;
 	void *data_out = NULL;
 	dma_addr_t data_out_dma;
@@ -1507,24 +1506,10 @@ _transport_expander_phy_control(struct M
 	    cpu_to_le16(sizeof(struct phy_error_log_request));
 	psge = &mpi_request->SGL;
 
-	/* WRITE sgel first */
-	sgl_flags = (MPI2_SGE_FLAGS_SIMPLE_ELEMENT |
-	    MPI2_SGE_FLAGS_END_OF_BUFFER | MPI2_SGE_FLAGS_HOST_TO_IOC);
-	sgl_flags = sgl_flags << MPI2_SGE_FLAGS_SHIFT;
-	ioc->base_add_sg_single(psge, sgl_flags |
-	    sizeof(struct phy_control_request), data_out_dma);
-
-	/* incr sgel */
-	psge += ioc->sge_size;
-
-	/* READ sgel last */
-	sgl_flags = (MPI2_SGE_FLAGS_SIMPLE_ELEMENT |
-	    MPI2_SGE_FLAGS_LAST_ELEMENT | MPI2_SGE_FLAGS_END_OF_BUFFER |
-	    MPI2_SGE_FLAGS_END_OF_LIST);
-	sgl_flags = sgl_flags << MPI2_SGE_FLAGS_SHIFT;
-	ioc->base_add_sg_single(psge, sgl_flags |
-	    sizeof(struct phy_control_reply), data_out_dma +
-	    sizeof(struct phy_control_request));
+	ioc->build_sg(ioc, psge, data_out_dma,
+			    sizeof(struct phy_control_request),
+	    data_out_dma + sizeof(struct phy_control_request),
+	    sizeof(struct phy_control_reply));
 
 	dtransportprintk(ioc, pr_info(MPT3SAS_FMT
 		"phy_control - send to sas_addr(0x%016llx), phy(%d), opcode(%d)\n",
@@ -1615,7 +1600,7 @@ _transport_phy_reset(struct sas_phy *phy
 		    SMP_PHY_CONTROL_LINK_RESET);
 
 	/* handle hba phys */
-	memset(&mpi_request, 0, sizeof(Mpi2SasIoUnitControlReply_t));
+	memset(&mpi_request, 0, sizeof(Mpi2SasIoUnitControlRequest_t));
 	mpi_request.Function = MPI2_FUNCTION_SAS_IO_UNIT_CONTROL;
 	mpi_request.Operation = hard_reset ?
 	    MPI2_SAS_OP_PHY_HARD_RESET : MPI2_SAS_OP_PHY_LINK_RESET;
--- zfcpdump-kernel-4.4.orig/drivers/scsi/qla1280.c
+++ zfcpdump-kernel-4.4/drivers/scsi/qla1280.c
@@ -4214,7 +4214,7 @@ static struct scsi_host_template qla1280
 	.eh_bus_reset_handler	= qla1280_eh_bus_reset,
 	.eh_host_reset_handler	= qla1280_eh_adapter_reset,
 	.bios_param		= qla1280_biosparam,
-	.can_queue		= 0xfffff,
+	.can_queue		= MAX_OUTSTANDING_COMMANDS,
 	.this_id		= -1,
 	.sg_tablesize		= SG_ALL,
 	.use_clustering		= ENABLE_CLUSTERING,
--- zfcpdump-kernel-4.4.orig/drivers/scsi/qla2xxx/Kconfig
+++ zfcpdump-kernel-4.4/drivers/scsi/qla2xxx/Kconfig
@@ -18,9 +18,6 @@ config SCSI_QLA_FC
 	2322, 6322        ql2322_fw.bin
 	24xx, 54xx        ql2400_fw.bin
 	25xx              ql2500_fw.bin
-	2031              ql2600_fw.bin
-	8031              ql8300_fw.bin
-	27xx              ql2700_fw.bin
 
 	Upon request, the driver caches the firmware image until
 	the driver is unloaded.
--- zfcpdump-kernel-4.4.orig/drivers/scsi/qla2xxx/qla_attr.c
+++ zfcpdump-kernel-4.4/drivers/scsi/qla2xxx/qla_attr.c
@@ -824,6 +824,41 @@ static struct bin_attribute sysfs_reset_
 };
 
 static ssize_t
+qla2x00_issue_logo(struct file *filp, struct kobject *kobj,
+			struct bin_attribute *bin_attr,
+			char *buf, loff_t off, size_t count)
+{
+	struct scsi_qla_host *vha = shost_priv(dev_to_shost(container_of(kobj,
+	    struct device, kobj)));
+	int type;
+	int rval = 0;
+	port_id_t did;
+
+	type = simple_strtol(buf, NULL, 10);
+
+	did.b.domain = (type & 0x00ff0000) >> 16;
+	did.b.area = (type & 0x0000ff00) >> 8;
+	did.b.al_pa = (type & 0x000000ff);
+
+	ql_log(ql_log_info, vha, 0x70e3, "portid=%02x%02x%02x done\n",
+	    did.b.domain, did.b.area, did.b.al_pa);
+
+	ql_log(ql_log_info, vha, 0x70e4, "%s: %d\n", __func__, type);
+
+	rval = qla24xx_els_dcmd_iocb(vha, ELS_DCMD_LOGO, did);
+	return count;
+}
+
+static struct bin_attribute sysfs_issue_logo_attr = {
+	.attr = {
+		.name = "issue_logo",
+		.mode = S_IWUSR,
+	},
+	.size = 0,
+	.write = qla2x00_issue_logo,
+};
+
+static ssize_t
 qla2x00_sysfs_read_xgmac_stats(struct file *filp, struct kobject *kobj,
 		       struct bin_attribute *bin_attr,
 		       char *buf, loff_t off, size_t count)
@@ -937,6 +972,7 @@ static struct sysfs_entry {
 	{ "vpd", &sysfs_vpd_attr, 1 },
 	{ "sfp", &sysfs_sfp_attr, 1 },
 	{ "reset", &sysfs_reset_attr, },
+	{ "issue_logo", &sysfs_issue_logo_attr, },
 	{ "xgmac_stats", &sysfs_xgmac_stats_attr, 3 },
 	{ "dcbx_tlv", &sysfs_dcbx_tlv_attr, 3 },
 	{ NULL },
--- zfcpdump-kernel-4.4.orig/drivers/scsi/qla2xxx/qla_dbg.c
+++ zfcpdump-kernel-4.4/drivers/scsi/qla2xxx/qla_dbg.c
@@ -14,25 +14,24 @@
  * | Module Init and Probe        |       0x017f       | 0x0146         |
  * |                              |                    | 0x015b-0x0160	|
  * |                              |                    | 0x016e-0x0170  |
- * | Mailbox commands             |       0x118d       | 0x1115-0x1116	|
- * |                              |                    | 0x111a-0x111b  |
+ * | Mailbox commands             |       0x1192       |		|
+ * |                              |                    |		|
  * | Device Discovery             |       0x2016       | 0x2020-0x2022, |
  * |                              |                    | 0x2011-0x2012, |
  * |                              |                    | 0x2099-0x20a4  |
- * | Queue Command and IO tracing |       0x3075       | 0x300b         |
+ * | Queue Command and IO tracing |       0x3074       | 0x300b         |
  * |                              |                    | 0x3027-0x3028  |
  * |                              |                    | 0x303d-0x3041  |
  * |                              |                    | 0x302d,0x3033  |
  * |                              |                    | 0x3036,0x3038  |
  * |                              |                    | 0x303a		|
  * | DPC Thread                   |       0x4023       | 0x4002,0x4013  |
- * | Async Events                 |       0x508a       | 0x502b-0x502f  |
- * |                              |                    | 0x5047		|
+ * | Async Events                 |       0x5089       | 0x502b-0x502f  |
  * |                              |                    | 0x5084,0x5075	|
  * |                              |                    | 0x503d,0x5044  |
  * |                              |                    | 0x507b,0x505f	|
  * | Timer Routines               |       0x6012       |                |
- * | User Space Interactions      |       0x70e2       | 0x7018,0x702e  |
+ * | User Space Interactions      |       0x70e65      | 0x7018,0x702e  |
  * |				  |		       | 0x7020,0x7024  |
  * |                              |                    | 0x7039,0x7045  |
  * |                              |                    | 0x7073-0x7075  |
@@ -60,15 +59,11 @@
  * |                              |                    | 0xb13c-0xb140  |
  * |                              |                    | 0xb149		|
  * | MultiQ                       |       0xc00c       |		|
- * | Misc                         |       0xd300       | 0xd016-0xd017	|
- * |                              |                    | 0xd021,0xd024	|
- * |                              |                    | 0xd025,0xd029	|
- * |                              |                    | 0xd02a,0xd02e	|
- * |                              |                    | 0xd031-0xd0ff	|
+ * | Misc                         |       0xd301       | 0xd031-0xd0ff	|
  * |                              |                    | 0xd101-0xd1fe	|
  * |                              |                    | 0xd214-0xd2fe	|
  * | Target Mode		  |	  0xe080       |		|
- * | Target Mode Management	  |	  0xf096       | 0xf002		|
+ * | Target Mode Management	  |	  0xf09b       | 0xf002		|
  * |                              |                    | 0xf046-0xf049  |
  * | Target Mode Task Management  |	  0x1000d      |		|
  * ----------------------------------------------------------------------
--- zfcpdump-kernel-4.4.orig/drivers/scsi/qla2xxx/qla_def.h
+++ zfcpdump-kernel-4.4/drivers/scsi/qla2xxx/qla_def.h
@@ -259,7 +259,7 @@
 #define LOOP_DOWN_TIME			255	/* 240 */
 #define	LOOP_DOWN_RESET			(LOOP_DOWN_TIME - 30)
 
-#define DEFAULT_OUTSTANDING_COMMANDS	1024
+#define DEFAULT_OUTSTANDING_COMMANDS	4096
 #define MIN_OUTSTANDING_COMMANDS	128
 
 /* ISP request and response entry counts (37-65535) */
@@ -267,11 +267,13 @@
 #define REQUEST_ENTRY_CNT_2200		2048	/* Number of request entries. */
 #define REQUEST_ENTRY_CNT_24XX		2048	/* Number of request entries. */
 #define REQUEST_ENTRY_CNT_83XX		8192	/* Number of request entries. */
+#define RESPONSE_ENTRY_CNT_83XX		4096	/* Number of response entries.*/
 #define RESPONSE_ENTRY_CNT_2100		64	/* Number of response entries.*/
 #define RESPONSE_ENTRY_CNT_2300		512	/* Number of response entries.*/
 #define RESPONSE_ENTRY_CNT_MQ		128	/* Number of response entries.*/
 #define ATIO_ENTRY_CNT_24XX		4096	/* Number of ATIO entries. */
 #define RESPONSE_ENTRY_CNT_FX00		256     /* Number of response entries.*/
+#define EXTENDED_EXCH_ENTRY_CNT		32768   /* Entries for offload case */
 
 struct req_que;
 struct qla_tgt_sess;
@@ -309,6 +311,14 @@ struct srb_cmd {
 /* To identify if a srb is of T10-CRC type. @sp => srb_t pointer */
 #define IS_PROT_IO(sp)	(sp->flags & SRB_CRC_CTX_DSD_VALID)
 
+struct els_logo_payload {
+	uint8_t opcode;
+	uint8_t rsvd[3];
+	uint8_t s_id[3];
+	uint8_t rsvd1[1];
+	uint8_t wwpn[WWN_SIZE];
+};
+
 /*
  * SRB extensions.
  */
@@ -322,6 +332,15 @@ struct srb_iocb {
 			uint16_t data[2];
 		} logio;
 		struct {
+#define ELS_DCMD_TIMEOUT 20
+#define ELS_DCMD_LOGO 0x5
+			uint32_t flags;
+			uint32_t els_cmd;
+			struct completion comp;
+			struct els_logo_payload *els_logo_pyld;
+			dma_addr_t els_logo_pyld_dma;
+		} els_logo;
+		struct {
 			/*
 			 * Values for flags field below are as
 			 * defined in tsk_mgmt_entry struct
@@ -382,7 +401,7 @@ struct srb_iocb {
 #define SRB_FXIOCB_DCMD	10
 #define SRB_FXIOCB_BCMD	11
 #define SRB_ABT_CMD	12
-
+#define SRB_ELS_DCMD	13
 
 typedef struct srb {
 	atomic_t ref_count;
@@ -891,6 +910,7 @@ struct mbx_cmd_32 {
 #define MBC_DISABLE_VI			0x24	/* Disable VI operation. */
 #define MBC_ENABLE_VI			0x25	/* Enable VI operation. */
 #define MBC_GET_FIRMWARE_OPTION		0x28	/* Get Firmware Options. */
+#define MBC_GET_MEM_OFFLOAD_CNTRL_STAT	0x34	/* Memory Offload ctrl/Stat*/
 #define MBC_SET_FIRMWARE_OPTION		0x38	/* Set Firmware Options. */
 #define MBC_LOOP_PORT_BYPASS		0x40	/* Loop Port Bypass. */
 #define MBC_LOOP_PORT_ENABLE		0x41	/* Loop Port Enable. */
@@ -2695,11 +2715,16 @@ struct isp_operations {
 
 struct scsi_qla_host;
 
+
+#define QLA83XX_RSPQ_MSIX_ENTRY_NUMBER 1 /* refer to qla83xx_msix_entries */
+
 struct qla_msix_entry {
 	int have_irq;
 	uint32_t vector;
 	uint16_t entry;
 	struct rsp_que *rsp;
+	struct irq_affinity_notify irq_notify;
+	int cpuid;
 };
 
 #define	WATCH_INTERVAL		1       /* number of seconds */
@@ -2910,12 +2935,15 @@ struct qlt_hw_data {
 	uint32_t num_qfull_cmds_dropped;
 	spinlock_t q_full_lock;
 	uint32_t leak_exchg_thresh_hold;
+	spinlock_t sess_lock;
+	int rspq_vector_cpuid;
+	spinlock_t atio_lock ____cacheline_aligned;
 };
 
 #define MAX_QFULL_CMDS_ALLOC	8192
 #define Q_FULL_THRESH_HOLD_PERCENT 90
 #define Q_FULL_THRESH_HOLD(ha) \
-	((ha->fw_xcb_count/100) * Q_FULL_THRESH_HOLD_PERCENT)
+	((ha->cur_fw_xcb_count/100) * Q_FULL_THRESH_HOLD_PERCENT)
 
 #define LEAK_EXCHG_THRESH_HOLD_PERCENT 75	/* 75 percent */
 
@@ -2962,10 +2990,12 @@ struct qla_hw_data {
 		uint32_t	isp82xx_no_md_cap:1;
 		uint32_t	host_shutting_down:1;
 		uint32_t	idc_compl_status:1;
-
 		uint32_t        mr_reset_hdlr_active:1;
 		uint32_t        mr_intr_valid:1;
+
 		uint32_t	fawwpn_enabled:1;
+		uint32_t	exlogins_enabled:1;
+		uint32_t	exchoffld_enabled:1;
 		/* 35 bits */
 	} flags;
 
@@ -3237,6 +3267,21 @@ struct qla_hw_data {
 	void		*async_pd;
 	dma_addr_t	async_pd_dma;
 
+#define ENABLE_EXTENDED_LOGIN	BIT_7
+
+	/* Extended Logins  */
+	void		*exlogin_buf;
+	dma_addr_t	exlogin_buf_dma;
+	int		exlogin_size;
+
+#define ENABLE_EXCHANGE_OFFLD	BIT_2
+
+	/* Exchange Offload */
+	void		*exchoffld_buf;
+	dma_addr_t	exchoffld_buf_dma;
+	int		exchoffld_size;
+	int 		exchoffld_count;
+
 	void		*swl;
 
 	/* These are used by mailbox operations. */
@@ -3279,8 +3324,14 @@ struct qla_hw_data {
 #define RISC_START_ADDRESS_2100 0x1000
 #define RISC_START_ADDRESS_2300 0x800
 #define RISC_START_ADDRESS_2400 0x100000
-	uint16_t	fw_xcb_count;
-	uint16_t	fw_iocb_count;
+
+	uint16_t	orig_fw_tgt_xcb_count;
+	uint16_t	cur_fw_tgt_xcb_count;
+	uint16_t	orig_fw_xcb_count;
+	uint16_t	cur_fw_xcb_count;
+	uint16_t	orig_fw_iocb_count;
+	uint16_t	cur_fw_iocb_count;
+	uint16_t	fw_max_fcf_count;
 
 	uint32_t	fw_shared_ram_start;
 	uint32_t	fw_shared_ram_end;
@@ -3323,6 +3374,9 @@ struct qla_hw_data {
 	uint32_t	chain_offset;
 	struct dentry *dfs_dir;
 	struct dentry *dfs_fce;
+	struct dentry *dfs_tgt_counters;
+	struct dentry *dfs_fw_resource_cnt;
+
 	dma_addr_t	fce_dma;
 	void		*fce;
 	uint32_t	fce_bufs;
@@ -3480,6 +3534,18 @@ struct qla_hw_data {
 	int	allow_cna_fw_dump;
 };
 
+struct qla_tgt_counters {
+	uint64_t qla_core_sbt_cmd;
+	uint64_t core_qla_que_buf;
+	uint64_t qla_core_ret_ctio;
+	uint64_t core_qla_snd_status;
+	uint64_t qla_core_ret_sta_ctio;
+	uint64_t core_qla_free_cmd;
+	uint64_t num_q_full_sent;
+	uint64_t num_alloc_iocb_failed;
+	uint64_t num_term_xchg_sent;
+};
+
 /*
  * Qlogic scsi host structure
  */
@@ -3595,6 +3661,10 @@ typedef struct scsi_qla_host {
 	atomic_t		generation_tick;
 	/* Time when global fcport update has been scheduled */
 	int			total_fcport_update_gen;
+	/* List of pending LOGOs, protected by tgt_mutex */
+	struct list_head	logo_list;
+	/* List of pending PLOGI acks, protected by hw lock */
+	struct list_head	plogi_ack_list;
 
 	uint32_t	vp_abort_cnt;
 
@@ -3632,6 +3702,7 @@ typedef struct scsi_qla_host {
 
 	atomic_t	vref_count;
 	struct qla8044_reset_template reset_tmplt;
+	struct qla_tgt_counters tgt_counters;
 } scsi_qla_host_t;
 
 #define SET_VP_IDX	1
--- zfcpdump-kernel-4.4.orig/drivers/scsi/qla2xxx/qla_dfs.c
+++ zfcpdump-kernel-4.4/drivers/scsi/qla2xxx/qla_dfs.c
@@ -13,6 +13,85 @@ static struct dentry *qla2x00_dfs_root;
 static atomic_t qla2x00_dfs_root_count;
 
 static int
+qla_dfs_fw_resource_cnt_show(struct seq_file *s, void *unused)
+{
+	struct scsi_qla_host *vha = s->private;
+	struct qla_hw_data *ha = vha->hw;
+
+	seq_puts(s, "FW Resource count\n\n");
+	seq_printf(s, "Original TGT exchg count[%d]\n",
+	    ha->orig_fw_tgt_xcb_count);
+	seq_printf(s, "current TGT exchg count[%d]\n",
+	    ha->cur_fw_tgt_xcb_count);
+	seq_printf(s, "original Initiator Exchange count[%d]\n",
+	    ha->orig_fw_xcb_count);
+	seq_printf(s, "Current Initiator Exchange count[%d]\n",
+	    ha->cur_fw_xcb_count);
+	seq_printf(s, "Original IOCB count[%d]\n", ha->orig_fw_iocb_count);
+	seq_printf(s, "Current IOCB count[%d]\n", ha->cur_fw_iocb_count);
+	seq_printf(s, "MAX VP count[%d]\n", ha->max_npiv_vports);
+	seq_printf(s, "MAX FCF count[%d]\n", ha->fw_max_fcf_count);
+
+	return 0;
+}
+
+static int
+qla_dfs_fw_resource_cnt_open(struct inode *inode, struct file *file)
+{
+	struct scsi_qla_host *vha = inode->i_private;
+	return single_open(file, qla_dfs_fw_resource_cnt_show, vha);
+}
+
+static const struct file_operations dfs_fw_resource_cnt_ops = {
+	.open           = qla_dfs_fw_resource_cnt_open,
+	.read           = seq_read,
+	.llseek         = seq_lseek,
+	.release        = single_release,
+};
+
+static int
+qla_dfs_tgt_counters_show(struct seq_file *s, void *unused)
+{
+	struct scsi_qla_host *vha = s->private;
+
+	seq_puts(s, "Target Counters\n");
+	seq_printf(s, "qla_core_sbt_cmd = %lld\n",
+		vha->tgt_counters.qla_core_sbt_cmd);
+	seq_printf(s, "qla_core_ret_sta_ctio = %lld\n",
+		vha->tgt_counters.qla_core_ret_sta_ctio);
+	seq_printf(s, "qla_core_ret_ctio = %lld\n",
+		vha->tgt_counters.qla_core_ret_ctio);
+	seq_printf(s, "core_qla_que_buf = %lld\n",
+		vha->tgt_counters.core_qla_que_buf);
+	seq_printf(s, "core_qla_snd_status = %lld\n",
+		vha->tgt_counters.core_qla_snd_status);
+	seq_printf(s, "core_qla_free_cmd = %lld\n",
+		vha->tgt_counters.core_qla_free_cmd);
+	seq_printf(s, "num alloc iocb failed = %lld\n",
+		vha->tgt_counters.num_alloc_iocb_failed);
+	seq_printf(s, "num term exchange sent = %lld\n",
+		vha->tgt_counters.num_term_xchg_sent);
+	seq_printf(s, "num Q full sent = %lld\n",
+		vha->tgt_counters.num_q_full_sent);
+
+	return 0;
+}
+
+static int
+qla_dfs_tgt_counters_open(struct inode *inode, struct file *file)
+{
+	struct scsi_qla_host *vha = inode->i_private;
+	return single_open(file, qla_dfs_tgt_counters_show, vha);
+}
+
+static const struct file_operations dfs_tgt_counters_ops = {
+	.open           = qla_dfs_tgt_counters_open,
+	.read           = seq_read,
+	.llseek         = seq_lseek,
+	.release        = single_release,
+};
+
+static int
 qla2x00_dfs_fce_show(struct seq_file *s, void *unused)
 {
 	scsi_qla_host_t *vha = s->private;
@@ -146,6 +225,22 @@ create_dir:
 	atomic_inc(&qla2x00_dfs_root_count);
 
 create_nodes:
+	ha->dfs_fw_resource_cnt = debugfs_create_file("fw_resource_count",
+	    S_IRUSR, ha->dfs_dir, vha, &dfs_fw_resource_cnt_ops);
+	if (!ha->dfs_fw_resource_cnt) {
+		ql_log(ql_log_warn, vha, 0x00fd,
+		    "Unable to create debugFS fw_resource_count node.\n");
+		goto out;
+	}
+
+	ha->dfs_tgt_counters = debugfs_create_file("tgt_counters", S_IRUSR,
+	    ha->dfs_dir, vha, &dfs_tgt_counters_ops);
+	if (!ha->dfs_tgt_counters) {
+		ql_log(ql_log_warn, vha, 0xd301,
+		    "Unable to create debugFS tgt_counters node.\n");
+		goto out;
+	}
+
 	ha->dfs_fce = debugfs_create_file("fce", S_IRUSR, ha->dfs_dir, vha,
 	    &dfs_fce_ops);
 	if (!ha->dfs_fce) {
@@ -161,6 +256,17 @@ int
 qla2x00_dfs_remove(scsi_qla_host_t *vha)
 {
 	struct qla_hw_data *ha = vha->hw;
+
+	if (ha->dfs_fw_resource_cnt) {
+		debugfs_remove(ha->dfs_fw_resource_cnt);
+		ha->dfs_fw_resource_cnt = NULL;
+	}
+
+	if (ha->dfs_tgt_counters) {
+		debugfs_remove(ha->dfs_tgt_counters);
+		ha->dfs_tgt_counters = NULL;
+	}
+
 	if (ha->dfs_fce) {
 		debugfs_remove(ha->dfs_fce);
 		ha->dfs_fce = NULL;
--- zfcpdump-kernel-4.4.orig/drivers/scsi/qla2xxx/qla_gbl.h
+++ zfcpdump-kernel-4.4/drivers/scsi/qla2xxx/qla_gbl.h
@@ -44,6 +44,8 @@ extern int qla2x00_find_new_loop_id(scsi
 extern int qla2x00_fabric_login(scsi_qla_host_t *, fc_port_t *, uint16_t *);
 extern int qla2x00_local_device_login(scsi_qla_host_t *, fc_port_t *);
 
+extern int qla24xx_els_dcmd_iocb(scsi_qla_host_t *, int, port_id_t);
+
 extern void qla2x00_update_fcports(scsi_qla_host_t *);
 
 extern int qla2x00_abort_isp(scsi_qla_host_t *);
@@ -117,6 +119,8 @@ extern int ql2xdontresethba;
 extern uint64_t ql2xmaxlun;
 extern int ql2xmdcapmask;
 extern int ql2xmdenable;
+extern int ql2xexlogins;
+extern int ql2xexchoffld;
 
 extern int qla2x00_loop_reset(scsi_qla_host_t *);
 extern void qla2x00_abort_all_cmds(scsi_qla_host_t *, int);
@@ -135,6 +139,10 @@ extern int qla2x00_post_async_adisc_work
     uint16_t *);
 extern int qla2x00_post_async_adisc_done_work(struct scsi_qla_host *,
     fc_port_t *, uint16_t *);
+extern int qla2x00_set_exlogins_buffer(struct scsi_qla_host *);
+extern void qla2x00_free_exlogin_buffer(struct qla_hw_data *);
+extern int qla2x00_set_exchoffld_buffer(struct scsi_qla_host *);
+extern void qla2x00_free_exchoffld_buffer(struct qla_hw_data *);
 
 extern int qla81xx_restart_mpi_firmware(scsi_qla_host_t *);
 
@@ -323,8 +331,7 @@ extern int
 qla2x00_get_id_list(scsi_qla_host_t *, void *, dma_addr_t, uint16_t *);
 
 extern int
-qla2x00_get_resource_cnts(scsi_qla_host_t *, uint16_t *, uint16_t *,
-    uint16_t *, uint16_t *, uint16_t *, uint16_t *);
+qla2x00_get_resource_cnts(scsi_qla_host_t *);
 
 extern int
 qla2x00_get_fcal_position_map(scsi_qla_host_t *ha, char *pos_map);
@@ -766,4 +773,11 @@ extern int qla8044_abort_isp(scsi_qla_ho
 extern int qla8044_check_fw_alive(struct scsi_qla_host *);
 
 extern void qlt_host_reset_handler(struct qla_hw_data *ha);
+extern int qla_get_exlogin_status(scsi_qla_host_t *, uint16_t *,
+	uint16_t *);
+extern int qla_set_exlogin_mem_cfg(scsi_qla_host_t *vha, dma_addr_t phys_addr);
+extern int qla_get_exchoffld_status(scsi_qla_host_t *, uint16_t *, uint16_t *);
+extern int qla_set_exchoffld_mem_cfg(scsi_qla_host_t *, dma_addr_t);
+extern void qlt_handle_abts_recv(struct scsi_qla_host *, response_t *);
+
 #endif /* _QLA_GBL_H */
--- zfcpdump-kernel-4.4.orig/drivers/scsi/qla2xxx/qla_init.c
+++ zfcpdump-kernel-4.4/drivers/scsi/qla2xxx/qla_init.c
@@ -1766,10 +1766,10 @@ qla2x00_alloc_outstanding_cmds(struct ql
 	    (ql2xmultique_tag || ql2xmaxqueues > 1)))
 		req->num_outstanding_cmds = DEFAULT_OUTSTANDING_COMMANDS;
 	else {
-		if (ha->fw_xcb_count <= ha->fw_iocb_count)
-			req->num_outstanding_cmds = ha->fw_xcb_count;
+		if (ha->cur_fw_xcb_count <= ha->cur_fw_iocb_count)
+			req->num_outstanding_cmds = ha->cur_fw_xcb_count;
 		else
-			req->num_outstanding_cmds = ha->fw_iocb_count;
+			req->num_outstanding_cmds = ha->cur_fw_iocb_count;
 	}
 
 	req->outstanding_cmds = kzalloc(sizeof(srb_t *) *
@@ -1843,9 +1843,23 @@ qla2x00_setup_chip(scsi_qla_host_t *vha)
 			ql_dbg(ql_dbg_init, vha, 0x00ca,
 			    "Starting firmware.\n");
 
+			if (ql2xexlogins)
+				ha->flags.exlogins_enabled = 1;
+
+			if (ql2xexchoffld)
+				ha->flags.exchoffld_enabled = 1;
+
 			rval = qla2x00_execute_fw(vha, srisc_address);
 			/* Retrieve firmware information. */
 			if (rval == QLA_SUCCESS) {
+				rval = qla2x00_set_exlogins_buffer(vha);
+				if (rval != QLA_SUCCESS)
+					goto failed;
+
+				rval = qla2x00_set_exchoffld_buffer(vha);
+				if (rval != QLA_SUCCESS)
+					goto failed;
+
 enable_82xx_npiv:
 				fw_major_version = ha->fw_major_version;
 				if (IS_P3P_TYPE(ha))
@@ -1864,9 +1878,7 @@ enable_82xx_npiv:
 						ha->max_npiv_vports =
 						    MIN_MULTI_ID_FABRIC - 1;
 				}
-				qla2x00_get_resource_cnts(vha, NULL,
-				    &ha->fw_xcb_count, NULL, &ha->fw_iocb_count,
-				    &ha->max_npiv_vports, NULL);
+				qla2x00_get_resource_cnts(vha);
 
 				/*
 				 * Allocate the array of outstanding commands
@@ -2192,7 +2204,7 @@ qla2x00_init_rings(scsi_qla_host_t *vha)
 	/* Clear outstanding commands array. */
 	for (que = 0; que < ha->max_req_queues; que++) {
 		req = ha->req_q_map[que];
-		if (!req)
+		if (!req || !test_bit(que, ha->req_qid_map))
 			continue;
 		req->out_ptr = (void *)(req->ring + req->length);
 		*req->out_ptr = 0;
@@ -2209,7 +2221,7 @@ qla2x00_init_rings(scsi_qla_host_t *vha)
 
 	for (que = 0; que < ha->max_rsp_queues; que++) {
 		rsp = ha->rsp_q_map[que];
-		if (!rsp)
+		if (!rsp || !test_bit(que, ha->rsp_qid_map))
 			continue;
 		rsp->in_ptr = (void *)(rsp->ring + rsp->length);
 		*rsp->in_ptr = 0;
@@ -2248,7 +2260,7 @@ qla2x00_init_rings(scsi_qla_host_t *vha)
 	if (IS_FWI2_CAPABLE(ha)) {
 		mid_init_cb->options = cpu_to_le16(BIT_1);
 		mid_init_cb->init_cb.execution_throttle =
-		    cpu_to_le16(ha->fw_xcb_count);
+		    cpu_to_le16(ha->cur_fw_xcb_count);
 		/* D-Port Status */
 		if (IS_DPORT_CAPABLE(ha))
 			mid_init_cb->init_cb.firmware_options_1 |=
@@ -3053,6 +3065,26 @@ qla2x00_configure_loop(scsi_qla_host_t *
 			atomic_set(&vha->loop_state, LOOP_READY);
 			ql_dbg(ql_dbg_disc, vha, 0x2069,
 			    "LOOP READY.\n");
+
+			/*
+			 * Process any ATIO queue entries that came in
+			 * while we weren't online.
+			 */
+			if (qla_tgt_mode_enabled(vha)) {
+				if (IS_QLA27XX(ha) || IS_QLA83XX(ha)) {
+					spin_lock_irqsave(&ha->tgt.atio_lock,
+					    flags);
+					qlt_24xx_process_atio_queue(vha, 0);
+					spin_unlock_irqrestore(
+					    &ha->tgt.atio_lock, flags);
+				} else {
+					spin_lock_irqsave(&ha->hardware_lock,
+					    flags);
+					qlt_24xx_process_atio_queue(vha, 1);
+					spin_unlock_irqrestore(
+					    &ha->hardware_lock, flags);
+				}
+			}
 		}
 	}
 
@@ -4907,7 +4939,6 @@ qla2x00_restart_isp(scsi_qla_host_t *vha
 	struct qla_hw_data *ha = vha->hw;
 	struct req_que *req = ha->req_q_map[0];
 	struct rsp_que *rsp = ha->rsp_q_map[0];
-	unsigned long flags;
 
 	/* If firmware needs to be loaded */
 	if (qla2x00_isp_firmware(vha)) {
@@ -4929,17 +4960,6 @@ qla2x00_restart_isp(scsi_qla_host_t *vha
 			/* Issue a marker after FW becomes ready. */
 			qla2x00_marker(vha, req, rsp, 0, 0, MK_SYNC_ALL);
 
-			vha->flags.online = 1;
-
-			/*
-			 * Process any ATIO queue entries that came in
-			 * while we weren't online.
-			 */
-			spin_lock_irqsave(&ha->hardware_lock, flags);
-			if (qla_tgt_mode_enabled(vha))
-				qlt_24xx_process_atio_queue(vha);
-			spin_unlock_irqrestore(&ha->hardware_lock, flags);
-
 			set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags);
 		}
 
@@ -4961,7 +4981,7 @@ qla25xx_init_queues(struct qla_hw_data *
 
 	for (i = 1; i < ha->max_rsp_queues; i++) {
 		rsp = ha->rsp_q_map[i];
-		if (rsp) {
+		if (rsp && test_bit(i, ha->rsp_qid_map)) {
 			rsp->options &= ~BIT_0;
 			ret = qla25xx_init_rsp_que(base_vha, rsp);
 			if (ret != QLA_SUCCESS)
@@ -4976,8 +4996,8 @@ qla25xx_init_queues(struct qla_hw_data *
 	}
 	for (i = 1; i < ha->max_req_queues; i++) {
 		req = ha->req_q_map[i];
-		if (req) {
-		/* Clear outstanding commands array. */
+		if (req && test_bit(i, ha->req_qid_map)) {
+			/* Clear outstanding commands array. */
 			req->options &= ~BIT_0;
 			ret = qla25xx_init_req_que(base_vha, req);
 			if (ret != QLA_SUCCESS)
--- zfcpdump-kernel-4.4.orig/drivers/scsi/qla2xxx/qla_inline.h
+++ zfcpdump-kernel-4.4/drivers/scsi/qla2xxx/qla_inline.h
@@ -258,6 +258,8 @@ qla2x00_init_timer(srb_t *sp, unsigned l
 	if ((IS_QLAFX00(sp->fcport->vha->hw)) &&
 	    (sp->type == SRB_FXIOCB_DCMD))
 		init_completion(&sp->u.iocb_cmd.u.fxiocb.fxiocb_comp);
+	if (sp->type == SRB_ELS_DCMD)
+		init_completion(&sp->u.iocb_cmd.u.els_logo.comp);
 }
 
 static inline int
--- zfcpdump-kernel-4.4.orig/drivers/scsi/qla2xxx/qla_iocb.c
+++ zfcpdump-kernel-4.4/drivers/scsi/qla2xxx/qla_iocb.c
@@ -1868,6 +1868,7 @@ skip_cmd_array:
 	}
 
 queuing_error:
+	vha->tgt_counters.num_alloc_iocb_failed++;
 	return pkt;
 }
 
@@ -2010,6 +2011,190 @@ qla24xx_tm_iocb(srb_t *sp, struct tsk_mg
 }
 
 static void
+qla2x00_els_dcmd_sp_free(void *ptr, void *data)
+{
+	struct scsi_qla_host *vha = (scsi_qla_host_t *)ptr;
+	struct qla_hw_data *ha = vha->hw;
+	srb_t *sp = (srb_t *)data;
+	struct srb_iocb *elsio = &sp->u.iocb_cmd;
+
+	kfree(sp->fcport);
+
+	if (elsio->u.els_logo.els_logo_pyld)
+		dma_free_coherent(&ha->pdev->dev, DMA_POOL_SIZE,
+		    elsio->u.els_logo.els_logo_pyld,
+		    elsio->u.els_logo.els_logo_pyld_dma);
+
+	del_timer(&elsio->timer);
+	qla2x00_rel_sp(vha, sp);
+}
+
+static void
+qla2x00_els_dcmd_iocb_timeout(void *data)
+{
+	srb_t *sp = (srb_t *)data;
+	struct srb_iocb *lio = &sp->u.iocb_cmd;
+	fc_port_t *fcport = sp->fcport;
+	struct scsi_qla_host *vha = fcport->vha;
+	struct qla_hw_data *ha = vha->hw;
+	unsigned long flags = 0;
+
+	ql_dbg(ql_dbg_io, vha, 0x3069,
+	    "%s Timeout, hdl=%x, portid=%02x%02x%02x\n",
+	    sp->name, sp->handle, fcport->d_id.b.domain, fcport->d_id.b.area,
+	    fcport->d_id.b.al_pa);
+
+	/* Abort the exchange */
+	spin_lock_irqsave(&ha->hardware_lock, flags);
+	if (ha->isp_ops->abort_command(sp)) {
+		ql_dbg(ql_dbg_io, vha, 0x3070,
+		    "mbx abort_command failed.\n");
+	} else {
+		ql_dbg(ql_dbg_io, vha, 0x3071,
+		    "mbx abort_command success.\n");
+	}
+	spin_unlock_irqrestore(&ha->hardware_lock, flags);
+
+	complete(&lio->u.els_logo.comp);
+}
+
+static void
+qla2x00_els_dcmd_sp_done(void *data, void *ptr, int res)
+{
+	srb_t *sp = (srb_t *)ptr;
+	fc_port_t *fcport = sp->fcport;
+	struct srb_iocb *lio = &sp->u.iocb_cmd;
+	struct scsi_qla_host *vha = fcport->vha;
+
+	ql_dbg(ql_dbg_io, vha, 0x3072,
+	    "%s hdl=%x, portid=%02x%02x%02x done\n",
+	    sp->name, sp->handle, fcport->d_id.b.domain,
+	    fcport->d_id.b.area, fcport->d_id.b.al_pa);
+
+	complete(&lio->u.els_logo.comp);
+}
+
+int
+qla24xx_els_dcmd_iocb(scsi_qla_host_t *vha, int els_opcode,
+    port_id_t remote_did)
+{
+	srb_t *sp;
+	fc_port_t *fcport = NULL;
+	struct srb_iocb *elsio = NULL;
+	struct qla_hw_data *ha = vha->hw;
+	struct els_logo_payload logo_pyld;
+	int rval = QLA_SUCCESS;
+
+	fcport = qla2x00_alloc_fcport(vha, GFP_KERNEL);
+	if (!fcport) {
+	       ql_log(ql_log_info, vha, 0x70e5, "fcport allocation failed\n");
+	       return -ENOMEM;
+	}
+
+	/* Alloc SRB structure */
+	sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL);
+	if (!sp) {
+		kfree(fcport);
+		ql_log(ql_log_info, vha, 0x70e6,
+		 "SRB allocation failed\n");
+		return -ENOMEM;
+	}
+
+	elsio = &sp->u.iocb_cmd;
+	fcport->loop_id = 0xFFFF;
+	fcport->d_id.b.domain = remote_did.b.domain;
+	fcport->d_id.b.area = remote_did.b.area;
+	fcport->d_id.b.al_pa = remote_did.b.al_pa;
+
+	ql_dbg(ql_dbg_io, vha, 0x3073, "portid=%02x%02x%02x done\n",
+	    fcport->d_id.b.domain, fcport->d_id.b.area, fcport->d_id.b.al_pa);
+
+	sp->type = SRB_ELS_DCMD;
+	sp->name = "ELS_DCMD";
+	sp->fcport = fcport;
+	qla2x00_init_timer(sp, ELS_DCMD_TIMEOUT);
+	elsio->timeout = qla2x00_els_dcmd_iocb_timeout;
+	sp->done = qla2x00_els_dcmd_sp_done;
+	sp->free = qla2x00_els_dcmd_sp_free;
+
+	elsio->u.els_logo.els_logo_pyld = dma_alloc_coherent(&ha->pdev->dev,
+			    DMA_POOL_SIZE, &elsio->u.els_logo.els_logo_pyld_dma,
+			    GFP_KERNEL);
+
+	if (!elsio->u.els_logo.els_logo_pyld) {
+		sp->free(vha, sp);
+		return QLA_FUNCTION_FAILED;
+	}
+
+	memset(&logo_pyld, 0, sizeof(struct els_logo_payload));
+
+	elsio->u.els_logo.els_cmd = els_opcode;
+	logo_pyld.opcode = els_opcode;
+	logo_pyld.s_id[0] = vha->d_id.b.al_pa;
+	logo_pyld.s_id[1] = vha->d_id.b.area;
+	logo_pyld.s_id[2] = vha->d_id.b.domain;
+	host_to_fcp_swap(logo_pyld.s_id, sizeof(uint32_t));
+	memcpy(&logo_pyld.wwpn, vha->port_name, WWN_SIZE);
+
+	memcpy(elsio->u.els_logo.els_logo_pyld, &logo_pyld,
+	    sizeof(struct els_logo_payload));
+
+	rval = qla2x00_start_sp(sp);
+	if (rval != QLA_SUCCESS) {
+		sp->free(vha, sp);
+		return QLA_FUNCTION_FAILED;
+	}
+
+	ql_dbg(ql_dbg_io, vha, 0x3074,
+	    "%s LOGO sent, hdl=%x, loopid=%x, portid=%02x%02x%02x.\n",
+	    sp->name, sp->handle, fcport->loop_id, fcport->d_id.b.domain,
+	    fcport->d_id.b.area, fcport->d_id.b.al_pa);
+
+	wait_for_completion(&elsio->u.els_logo.comp);
+
+	sp->free(vha, sp);
+	return rval;
+}
+
+static void
+qla24xx_els_logo_iocb(srb_t *sp, struct els_entry_24xx *els_iocb)
+{
+	scsi_qla_host_t *vha = sp->fcport->vha;
+	struct srb_iocb *elsio = &sp->u.iocb_cmd;
+
+	els_iocb->entry_type = ELS_IOCB_TYPE;
+	els_iocb->entry_count = 1;
+	els_iocb->sys_define = 0;
+	els_iocb->entry_status = 0;
+	els_iocb->handle = sp->handle;
+	els_iocb->nport_handle = cpu_to_le16(sp->fcport->loop_id);
+	els_iocb->tx_dsd_count = 1;
+	els_iocb->vp_index = vha->vp_idx;
+	els_iocb->sof_type = EST_SOFI3;
+	els_iocb->rx_dsd_count = 0;
+	els_iocb->opcode = elsio->u.els_logo.els_cmd;
+
+	els_iocb->port_id[0] = sp->fcport->d_id.b.al_pa;
+	els_iocb->port_id[1] = sp->fcport->d_id.b.area;
+	els_iocb->port_id[2] = sp->fcport->d_id.b.domain;
+	els_iocb->control_flags = 0;
+
+	els_iocb->tx_byte_count = sizeof(struct els_logo_payload);
+	els_iocb->tx_address[0] =
+	    cpu_to_le32(LSD(elsio->u.els_logo.els_logo_pyld_dma));
+	els_iocb->tx_address[1] =
+	    cpu_to_le32(MSD(elsio->u.els_logo.els_logo_pyld_dma));
+	els_iocb->tx_len = cpu_to_le32(sizeof(struct els_logo_payload));
+
+	els_iocb->rx_byte_count = 0;
+	els_iocb->rx_address[0] = 0;
+	els_iocb->rx_address[1] = 0;
+	els_iocb->rx_len = 0;
+
+	sp->fcport->vha->qla_stats.control_requests++;
+}
+
+static void
 qla24xx_els_iocb(srb_t *sp, struct els_entry_24xx *els_iocb)
 {
 	struct fc_bsg_job *bsg_job = sp->u.bsg_job;
@@ -2623,6 +2808,9 @@ qla2x00_start_sp(srb_t *sp)
 			qlafx00_abort_iocb(sp, pkt) :
 			qla24xx_abort_iocb(sp, pkt);
 		break;
+	case SRB_ELS_DCMD:
+		qla24xx_els_logo_iocb(sp, pkt);
+		break;
 	default:
 		break;
 	}
--- zfcpdump-kernel-4.4.orig/drivers/scsi/qla2xxx/qla_isr.c
+++ zfcpdump-kernel-4.4/drivers/scsi/qla2xxx/qla_isr.c
@@ -18,6 +18,10 @@ static void qla2x00_status_entry(scsi_ql
 static void qla2x00_status_cont_entry(struct rsp_que *, sts_cont_entry_t *);
 static void qla2x00_error_entry(scsi_qla_host_t *, struct rsp_que *,
 	sts_entry_t *);
+static void qla_irq_affinity_notify(struct irq_affinity_notify *,
+    const cpumask_t *);
+static void qla_irq_affinity_release(struct kref *);
+
 
 /**
  * qla2100_intr_handler() - Process interrupts for the ISP2100 and ISP2200.
@@ -1418,6 +1422,12 @@ qla24xx_els_ct_entry(scsi_qla_host_t *vh
 	case SRB_CT_CMD:
 		type = "ct pass-through";
 		break;
+	case SRB_ELS_DCMD:
+		type = "Driver ELS logo";
+		ql_dbg(ql_dbg_user, vha, 0x5047,
+		    "Completing %s: (%p) type=%d.\n", type, sp, sp->type);
+		sp->done(vha, sp, 0);
+		return;
 	default:
 		ql_dbg(ql_dbg_user, vha, 0x503e,
 		    "Unrecognized SRB: (%p) type=%d.\n", sp, sp->type);
@@ -2542,6 +2552,14 @@ void qla24xx_process_response_queue(stru
 	if (!vha->flags.online)
 		return;
 
+	if (rsp->msix && (rsp->msix->cpuid != smp_processor_id())) {
+		/* if kernel does not notify qla of IRQ's CPU change,
+		 * then set it here.
+		 */
+		rsp->msix->cpuid = smp_processor_id();
+		ha->tgt.rspq_vector_cpuid = rsp->msix->cpuid;
+	}
+
 	while (rsp->ring_ptr->signature != RESPONSE_PROCESSED) {
 		pkt = (struct sts_entry_24xx *)rsp->ring_ptr;
 
@@ -2587,8 +2605,14 @@ process_err:
 			qla24xx_els_ct_entry(vha, rsp->req, pkt, ELS_IOCB_TYPE);
 			break;
 		case ABTS_RECV_24XX:
-			/* ensure that the ATIO queue is empty */
-			qlt_24xx_process_atio_queue(vha);
+			if (IS_QLA83XX(ha) || IS_QLA27XX(ha)) {
+				/* ensure that the ATIO queue is empty */
+				qlt_handle_abts_recv(vha, (response_t *)pkt);
+				break;
+			} else {
+				/* drop through */
+				qlt_24xx_process_atio_queue(vha, 1);
+			}
 		case ABTS_RESP_24XX:
 		case CTIO_TYPE7:
 		case NOTIFY_ACK_TYPE:
@@ -2755,13 +2779,22 @@ qla24xx_intr_handler(int irq, void *dev_
 		case INTR_RSP_QUE_UPDATE_83XX:
 			qla24xx_process_response_queue(vha, rsp);
 			break;
-		case INTR_ATIO_QUE_UPDATE:
-			qlt_24xx_process_atio_queue(vha);
+		case INTR_ATIO_QUE_UPDATE:{
+			unsigned long flags2;
+			spin_lock_irqsave(&ha->tgt.atio_lock, flags2);
+			qlt_24xx_process_atio_queue(vha, 1);
+			spin_unlock_irqrestore(&ha->tgt.atio_lock, flags2);
 			break;
-		case INTR_ATIO_RSP_QUE_UPDATE:
-			qlt_24xx_process_atio_queue(vha);
+		}
+		case INTR_ATIO_RSP_QUE_UPDATE: {
+			unsigned long flags2;
+			spin_lock_irqsave(&ha->tgt.atio_lock, flags2);
+			qlt_24xx_process_atio_queue(vha, 1);
+			spin_unlock_irqrestore(&ha->tgt.atio_lock, flags2);
+
 			qla24xx_process_response_queue(vha, rsp);
 			break;
+		}
 		default:
 			ql_dbg(ql_dbg_async, vha, 0x504f,
 			    "Unrecognized interrupt type (%d).\n", stat * 0xff);
@@ -2920,13 +2953,22 @@ qla24xx_msix_default(int irq, void *dev_
 		case INTR_RSP_QUE_UPDATE_83XX:
 			qla24xx_process_response_queue(vha, rsp);
 			break;
-		case INTR_ATIO_QUE_UPDATE:
-			qlt_24xx_process_atio_queue(vha);
+		case INTR_ATIO_QUE_UPDATE:{
+			unsigned long flags2;
+			spin_lock_irqsave(&ha->tgt.atio_lock, flags2);
+			qlt_24xx_process_atio_queue(vha, 1);
+			spin_unlock_irqrestore(&ha->tgt.atio_lock, flags2);
 			break;
-		case INTR_ATIO_RSP_QUE_UPDATE:
-			qlt_24xx_process_atio_queue(vha);
+		}
+		case INTR_ATIO_RSP_QUE_UPDATE: {
+			unsigned long flags2;
+			spin_lock_irqsave(&ha->tgt.atio_lock, flags2);
+			qlt_24xx_process_atio_queue(vha, 1);
+			spin_unlock_irqrestore(&ha->tgt.atio_lock, flags2);
+
 			qla24xx_process_response_queue(vha, rsp);
 			break;
+		}
 		default:
 			ql_dbg(ql_dbg_async, vha, 0x5051,
 			    "Unrecognized interrupt type (%d).\n", stat & 0xff);
@@ -2973,8 +3015,11 @@ qla24xx_disable_msix(struct qla_hw_data
 
 	for (i = 0; i < ha->msix_count; i++) {
 		qentry = &ha->msix_entries[i];
-		if (qentry->have_irq)
+		if (qentry->have_irq) {
+			/* un-register irq cpu affinity notification */
+			irq_set_affinity_notifier(qentry->vector, NULL);
 			free_irq(qentry->vector, qentry->rsp);
+		}
 	}
 	pci_disable_msix(ha->pdev);
 	kfree(ha->msix_entries);
@@ -3018,9 +3063,9 @@ qla24xx_enable_msix(struct qla_hw_data *
 		    "MSI-X: Failed to enable support "
 		    "-- %d/%d\n Retry with %d vectors.\n",
 		    ha->msix_count, ret, ret);
+		ha->msix_count = ret;
+		ha->max_rsp_queues = ha->msix_count - 1;
 	}
-	ha->msix_count = ret;
-	ha->max_rsp_queues = ha->msix_count - 1;
 	ha->msix_entries = kzalloc(sizeof(struct qla_msix_entry) *
 				ha->msix_count, GFP_KERNEL);
 	if (!ha->msix_entries) {
@@ -3037,6 +3082,9 @@ qla24xx_enable_msix(struct qla_hw_data *
 		qentry->entry = entries[i].entry;
 		qentry->have_irq = 0;
 		qentry->rsp = NULL;
+		qentry->irq_notify.notify  = qla_irq_affinity_notify;
+		qentry->irq_notify.release = qla_irq_affinity_release;
+		qentry->cpuid = -1;
 	}
 
 	/* Enable MSI-X vectors for the base queue */
@@ -3055,6 +3103,18 @@ qla24xx_enable_msix(struct qla_hw_data *
 		qentry->have_irq = 1;
 		qentry->rsp = rsp;
 		rsp->msix = qentry;
+
+		/* Register for CPU affinity notification. */
+		irq_set_affinity_notifier(qentry->vector, &qentry->irq_notify);
+
+		/* Schedule work (ie. trigger a notification) to read cpu
+		 * mask for this specific irq.
+		 * kref_get is required because
+		* irq_affinity_notify() will do
+		* kref_put().
+		*/
+		kref_get(&qentry->irq_notify.kref);
+		schedule_work(&qentry->irq_notify.work);
 	}
 
 	/*
@@ -3234,3 +3294,47 @@ int qla25xx_request_irq(struct rsp_que *
 	msix->rsp = rsp;
 	return ret;
 }
+
+
+/* irq_set_affinity/irqbalance will trigger notification of cpu mask update */
+static void qla_irq_affinity_notify(struct irq_affinity_notify *notify,
+	const cpumask_t *mask)
+{
+	struct qla_msix_entry *e =
+		container_of(notify, struct qla_msix_entry, irq_notify);
+	struct qla_hw_data *ha;
+	struct scsi_qla_host *base_vha;
+
+	/* user is recommended to set mask to just 1 cpu */
+	e->cpuid = cpumask_first(mask);
+
+	ha = e->rsp->hw;
+	base_vha = pci_get_drvdata(ha->pdev);
+
+	ql_dbg(ql_dbg_init, base_vha, 0xffff,
+	    "%s: host %ld : vector %d cpu %d \n", __func__,
+	    base_vha->host_no, e->vector, e->cpuid);
+
+	if (e->have_irq) {
+		if ((IS_QLA83XX(ha) || IS_QLA27XX(ha)) &&
+		    (e->entry == QLA83XX_RSPQ_MSIX_ENTRY_NUMBER)) {
+			ha->tgt.rspq_vector_cpuid = e->cpuid;
+			ql_dbg(ql_dbg_init, base_vha, 0xffff,
+			    "%s: host%ld: rspq vector %d cpu %d  runtime change\n",
+			    __func__, base_vha->host_no, e->vector, e->cpuid);
+		}
+	}
+}
+
+static void qla_irq_affinity_release(struct kref *ref)
+{
+	struct irq_affinity_notify *notify =
+		container_of(ref, struct irq_affinity_notify, kref);
+	struct qla_msix_entry *e =
+		container_of(notify, struct qla_msix_entry, irq_notify);
+	struct scsi_qla_host *base_vha = pci_get_drvdata(e->rsp->hw->pdev);
+
+	ql_dbg(ql_dbg_init, base_vha, 0xffff,
+	    "%s: host%ld: vector %d cpu %d \n", __func__,
+	    base_vha->host_no, e->vector, e->cpuid);
+}
--- zfcpdump-kernel-4.4.orig/drivers/scsi/qla2xxx/qla_mbx.c
+++ zfcpdump-kernel-4.4/drivers/scsi/qla2xxx/qla_mbx.c
@@ -489,6 +489,13 @@ qla2x00_execute_fw(scsi_qla_host_t *vha,
 			    EXTENDED_BB_CREDITS);
 		} else
 			mcp->mb[4] = 0;
+
+		if (ha->flags.exlogins_enabled)
+			mcp->mb[4] |= ENABLE_EXTENDED_LOGIN;
+
+		if (ha->flags.exchoffld_enabled)
+			mcp->mb[4] |= ENABLE_EXCHANGE_OFFLD;
+
 		mcp->out_mb |= MBX_4|MBX_3|MBX_2|MBX_1;
 		mcp->in_mb |= MBX_1;
 	} else {
@@ -521,6 +528,226 @@ qla2x00_execute_fw(scsi_qla_host_t *vha,
 }
 
 /*
+ * qla_get_exlogin_status
+ *	Get extended login status
+ *	uses the memory offload control/status Mailbox
+ *
+ * Input:
+ *	ha:		adapter state pointer.
+ *	fwopt:		firmware options
+ *
+ * Returns:
+ *	qla2x00 local function status
+ *
+ * Context:
+ *	Kernel context.
+ */
+#define	FETCH_XLOGINS_STAT	0x8
+int
+qla_get_exlogin_status(scsi_qla_host_t *vha, uint16_t *buf_sz,
+	uint16_t *ex_logins_cnt)
+{
+	int rval;
+	mbx_cmd_t	mc;
+	mbx_cmd_t	*mcp = &mc;
+
+	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x118f,
+	    "Entered %s\n", __func__);
+
+	memset(mcp->mb, 0 , sizeof(mcp->mb));
+	mcp->mb[0] = MBC_GET_MEM_OFFLOAD_CNTRL_STAT;
+	mcp->mb[1] = FETCH_XLOGINS_STAT;
+	mcp->out_mb = MBX_1|MBX_0;
+	mcp->in_mb = MBX_10|MBX_4|MBX_0;
+	mcp->tov = MBX_TOV_SECONDS;
+	mcp->flags = 0;
+
+	rval = qla2x00_mailbox_command(vha, mcp);
+	if (rval != QLA_SUCCESS) {
+		ql_dbg(ql_dbg_mbx, vha, 0x1115, "Failed=%x.\n", rval);
+	} else {
+		*buf_sz = mcp->mb[4];
+		*ex_logins_cnt = mcp->mb[10];
+
+		ql_log(ql_log_info, vha, 0x1190,
+		    "buffer size 0x%x, exchange login count=%d\n",
+		    mcp->mb[4], mcp->mb[10]);
+
+		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1116,
+		    "Done %s.\n", __func__);
+	}
+
+	return rval;
+}
+
+/*
+ * qla_set_exlogin_mem_cfg
+ *	set extended login memory configuration
+ *	Mbx needs to be issues before init_cb is set
+ *
+ * Input:
+ *	ha:		adapter state pointer.
+ *	buffer:		buffer pointer
+ *	phys_addr:	physical address of buffer
+ *	size:		size of buffer
+ *	TARGET_QUEUE_LOCK must be released
+ *	ADAPTER_STATE_LOCK must be release
+ *
+ * Returns:
+ *	qla2x00 local funxtion status code.
+ *
+ * Context:
+ *	Kernel context.
+ */
+#define CONFIG_XLOGINS_MEM	0x3
+int
+qla_set_exlogin_mem_cfg(scsi_qla_host_t *vha, dma_addr_t phys_addr)
+{
+	int		rval;
+	mbx_cmd_t	mc;
+	mbx_cmd_t	*mcp = &mc;
+	struct qla_hw_data *ha = vha->hw;
+	int configured_count;
+
+	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x111a,
+	    "Entered %s.\n", __func__);
+
+	memset(mcp->mb, 0 , sizeof(mcp->mb));
+	mcp->mb[0] = MBC_GET_MEM_OFFLOAD_CNTRL_STAT;
+	mcp->mb[1] = CONFIG_XLOGINS_MEM;
+	mcp->mb[2] = MSW(phys_addr);
+	mcp->mb[3] = LSW(phys_addr);
+	mcp->mb[6] = MSW(MSD(phys_addr));
+	mcp->mb[7] = LSW(MSD(phys_addr));
+	mcp->mb[8] = MSW(ha->exlogin_size);
+	mcp->mb[9] = LSW(ha->exlogin_size);
+	mcp->out_mb = MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
+	mcp->in_mb = MBX_11|MBX_0;
+	mcp->tov = MBX_TOV_SECONDS;
+	mcp->flags = 0;
+	rval = qla2x00_mailbox_command(vha, mcp);
+	if (rval != QLA_SUCCESS) {
+		/*EMPTY*/
+		ql_dbg(ql_dbg_mbx, vha, 0x111b, "Failed=%x.\n", rval);
+	} else {
+		configured_count = mcp->mb[11];
+		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x118c,
+		    "Done %s.\n", __func__);
+	}
+
+	return rval;
+}
+
+/*
+ * qla_get_exchoffld_status
+ *	Get exchange offload status
+ *	uses the memory offload control/status Mailbox
+ *
+ * Input:
+ *	ha:		adapter state pointer.
+ *	fwopt:		firmware options
+ *
+ * Returns:
+ *	qla2x00 local function status
+ *
+ * Context:
+ *	Kernel context.
+ */
+#define	FETCH_XCHOFFLD_STAT	0x2
+int
+qla_get_exchoffld_status(scsi_qla_host_t *vha, uint16_t *buf_sz,
+	uint16_t *ex_logins_cnt)
+{
+	int rval;
+	mbx_cmd_t	mc;
+	mbx_cmd_t	*mcp = &mc;
+
+	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1019,
+	    "Entered %s\n", __func__);
+
+	memset(mcp->mb, 0 , sizeof(mcp->mb));
+	mcp->mb[0] = MBC_GET_MEM_OFFLOAD_CNTRL_STAT;
+	mcp->mb[1] = FETCH_XCHOFFLD_STAT;
+	mcp->out_mb = MBX_1|MBX_0;
+	mcp->in_mb = MBX_10|MBX_4|MBX_0;
+	mcp->tov = MBX_TOV_SECONDS;
+	mcp->flags = 0;
+
+	rval = qla2x00_mailbox_command(vha, mcp);
+	if (rval != QLA_SUCCESS) {
+		ql_dbg(ql_dbg_mbx, vha, 0x1155, "Failed=%x.\n", rval);
+	} else {
+		*buf_sz = mcp->mb[4];
+		*ex_logins_cnt = mcp->mb[10];
+
+		ql_log(ql_log_info, vha, 0x118e,
+		    "buffer size 0x%x, exchange offload count=%d\n",
+		    mcp->mb[4], mcp->mb[10]);
+
+		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1156,
+		    "Done %s.\n", __func__);
+	}
+
+	return rval;
+}
+
+/*
+ * qla_set_exchoffld_mem_cfg
+ *	Set exchange offload memory configuration
+ *	Mbx needs to be issues before init_cb is set
+ *
+ * Input:
+ *	ha:		adapter state pointer.
+ *	buffer:		buffer pointer
+ *	phys_addr:	physical address of buffer
+ *	size:		size of buffer
+ *	TARGET_QUEUE_LOCK must be released
+ *	ADAPTER_STATE_LOCK must be release
+ *
+ * Returns:
+ *	qla2x00 local funxtion status code.
+ *
+ * Context:
+ *	Kernel context.
+ */
+#define CONFIG_XCHOFFLD_MEM	0x3
+int
+qla_set_exchoffld_mem_cfg(scsi_qla_host_t *vha, dma_addr_t phys_addr)
+{
+	int		rval;
+	mbx_cmd_t	mc;
+	mbx_cmd_t	*mcp = &mc;
+	struct qla_hw_data *ha = vha->hw;
+
+	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1157,
+	    "Entered %s.\n", __func__);
+
+	memset(mcp->mb, 0 , sizeof(mcp->mb));
+	mcp->mb[0] = MBC_GET_MEM_OFFLOAD_CNTRL_STAT;
+	mcp->mb[1] = CONFIG_XCHOFFLD_MEM;
+	mcp->mb[2] = MSW(phys_addr);
+	mcp->mb[3] = LSW(phys_addr);
+	mcp->mb[6] = MSW(MSD(phys_addr));
+	mcp->mb[7] = LSW(MSD(phys_addr));
+	mcp->mb[8] = MSW(ha->exlogin_size);
+	mcp->mb[9] = LSW(ha->exlogin_size);
+	mcp->out_mb = MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
+	mcp->in_mb = MBX_11|MBX_0;
+	mcp->tov = MBX_TOV_SECONDS;
+	mcp->flags = 0;
+	rval = qla2x00_mailbox_command(vha, mcp);
+	if (rval != QLA_SUCCESS) {
+		/*EMPTY*/
+		ql_dbg(ql_dbg_mbx, vha, 0x1158, "Failed=%x.\n", rval);
+	} else {
+		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1192,
+		    "Done %s.\n", __func__);
+	}
+
+	return rval;
+}
+
+/*
  * qla2x00_get_fw_version
  *	Get firmware version.
  *
@@ -594,6 +821,16 @@ qla2x00_get_fw_version(scsi_qla_host_t *
 		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x112f,
 		    "%s: Ext_FwAttributes Upper: 0x%x, Lower: 0x%x.\n",
 		    __func__, mcp->mb[17], mcp->mb[16]);
+
+		if (ha->fw_attributes_h & 0x4)
+			ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x118d,
+			    "%s: Firmware supports Extended Login 0x%x\n",
+			    __func__, ha->fw_attributes_h);
+
+		if (ha->fw_attributes_h & 0x8)
+			ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1191,
+			    "%s: Firmware supports Exchange Offload 0x%x\n",
+			    __func__, ha->fw_attributes_h);
 	}
 
 	if (IS_QLA27XX(ha)) {
@@ -2383,10 +2620,9 @@ qla2x00_get_id_list(scsi_qla_host_t *vha
  *	Kernel context.
  */
 int
-qla2x00_get_resource_cnts(scsi_qla_host_t *vha, uint16_t *cur_xchg_cnt,
-    uint16_t *orig_xchg_cnt, uint16_t *cur_iocb_cnt,
-    uint16_t *orig_iocb_cnt, uint16_t *max_npiv_vports, uint16_t *max_fcfs)
+qla2x00_get_resource_cnts(scsi_qla_host_t *vha)
 {
+	struct qla_hw_data *ha = vha->hw;
 	int rval;
 	mbx_cmd_t mc;
 	mbx_cmd_t *mcp = &mc;
@@ -2414,19 +2650,16 @@ qla2x00_get_resource_cnts(scsi_qla_host_
 		    mcp->mb[3], mcp->mb[6], mcp->mb[7], mcp->mb[10],
 		    mcp->mb[11], mcp->mb[12]);
 
-		if (cur_xchg_cnt)
-			*cur_xchg_cnt = mcp->mb[3];
-		if (orig_xchg_cnt)
-			*orig_xchg_cnt = mcp->mb[6];
-		if (cur_iocb_cnt)
-			*cur_iocb_cnt = mcp->mb[7];
-		if (orig_iocb_cnt)
-			*orig_iocb_cnt = mcp->mb[10];
-		if (vha->hw->flags.npiv_supported && max_npiv_vports)
-			*max_npiv_vports = mcp->mb[11];
-		if ((IS_QLA81XX(vha->hw) || IS_QLA83XX(vha->hw) ||
-		    IS_QLA27XX(vha->hw)) && max_fcfs)
-			*max_fcfs = mcp->mb[12];
+		ha->orig_fw_tgt_xcb_count =  mcp->mb[1];
+		ha->cur_fw_tgt_xcb_count = mcp->mb[2];
+		ha->cur_fw_xcb_count = mcp->mb[3];
+		ha->orig_fw_xcb_count = mcp->mb[6];
+		ha->cur_fw_iocb_count = mcp->mb[7];
+		ha->orig_fw_iocb_count = mcp->mb[10];
+		if (ha->flags.npiv_supported)
+			ha->max_npiv_vports = mcp->mb[11];
+		if (IS_QLA81XX(ha) || IS_QLA83XX(ha) || IS_QLA27XX(ha))
+			ha->fw_max_fcf_count = mcp->mb[12];
 	}
 
 	return (rval);
--- zfcpdump-kernel-4.4.orig/drivers/scsi/qla2xxx/qla_mid.c
+++ zfcpdump-kernel-4.4/drivers/scsi/qla2xxx/qla_mid.c
@@ -600,7 +600,7 @@ qla25xx_delete_queues(struct scsi_qla_ho
 	/* Delete request queues */
 	for (cnt = 1; cnt < ha->max_req_queues; cnt++) {
 		req = ha->req_q_map[cnt];
-		if (req) {
+		if (req && test_bit(cnt, ha->req_qid_map)) {
 			ret = qla25xx_delete_req_que(vha, req);
 			if (ret != QLA_SUCCESS) {
 				ql_log(ql_log_warn, vha, 0x00ea,
@@ -614,7 +614,7 @@ qla25xx_delete_queues(struct scsi_qla_ho
 	/* Delete response queues */
 	for (cnt = 1; cnt < ha->max_rsp_queues; cnt++) {
 		rsp = ha->rsp_q_map[cnt];
-		if (rsp) {
+		if (rsp && test_bit(cnt, ha->rsp_qid_map)) {
 			ret = qla25xx_delete_rsp_que(vha, rsp);
 			if (ret != QLA_SUCCESS) {
 				ql_log(ql_log_warn, vha, 0x00eb,
--- zfcpdump-kernel-4.4.orig/drivers/scsi/qla2xxx/qla_os.c
+++ zfcpdump-kernel-4.4/drivers/scsi/qla2xxx/qla_os.c
@@ -221,6 +221,18 @@ MODULE_PARM_DESC(ql2xmdenable,
 		"0 - MiniDump disabled. "
 		"1 (Default) - MiniDump enabled.");
 
+int ql2xexlogins = 0;
+module_param(ql2xexlogins, uint, S_IRUGO|S_IWUSR);
+MODULE_PARM_DESC(ql2xexlogins,
+		 "Number of extended Logins. "
+		 "0 (Default)- Disabled.");
+
+int ql2xexchoffld = 0;
+module_param(ql2xexchoffld, uint, S_IRUGO|S_IWUSR);
+MODULE_PARM_DESC(ql2xexchoffld,
+		 "Number of exchanges to offload. "
+		 "0 (Default)- Disabled.");
+
 /*
  * SCSI host template entry points
  */
@@ -397,6 +409,9 @@ static void qla2x00_free_queues(struct q
 	int cnt;
 
 	for (cnt = 0; cnt < ha->max_req_queues; cnt++) {
+		if (!test_bit(cnt, ha->req_qid_map))
+			continue;
+
 		req = ha->req_q_map[cnt];
 		qla2x00_free_req_que(ha, req);
 	}
@@ -404,6 +419,9 @@ static void qla2x00_free_queues(struct q
 	ha->req_q_map = NULL;
 
 	for (cnt = 0; cnt < ha->max_rsp_queues; cnt++) {
+		if (!test_bit(cnt, ha->rsp_qid_map))
+			continue;
+
 		rsp = ha->rsp_q_map[cnt];
 		qla2x00_free_rsp_que(ha, rsp);
 	}
@@ -2324,6 +2342,9 @@ qla2x00_probe_one(struct pci_dev *pdev,
 	ha->tgt.enable_class_2 = ql2xenableclass2;
 	INIT_LIST_HEAD(&ha->tgt.q_full_list);
 	spin_lock_init(&ha->tgt.q_full_lock);
+	spin_lock_init(&ha->tgt.sess_lock);
+	spin_lock_init(&ha->tgt.atio_lock);
+
 
 	/* Clear our data area */
 	ha->bars = bars;
@@ -2468,7 +2489,7 @@ qla2x00_probe_one(struct pci_dev *pdev,
 		ha->max_fibre_devices = MAX_FIBRE_DEVICES_2400;
 		ha->mbx_count = MAILBOX_REGISTER_COUNT;
 		req_length = REQUEST_ENTRY_CNT_83XX;
-		rsp_length = RESPONSE_ENTRY_CNT_2300;
+		rsp_length = RESPONSE_ENTRY_CNT_83XX;
 		ha->tgt.atio_q_length = ATIO_ENTRY_CNT_24XX;
 		ha->max_loop_id = SNS_LAST_LOOP_ID_2300;
 		ha->init_cb_size = sizeof(struct mid_init_cb_81xx);
@@ -2498,8 +2519,8 @@ qla2x00_probe_one(struct pci_dev *pdev,
 		ha->portnum = PCI_FUNC(ha->pdev->devfn);
 		ha->max_fibre_devices = MAX_FIBRE_DEVICES_2400;
 		ha->mbx_count = MAILBOX_REGISTER_COUNT;
-		req_length = REQUEST_ENTRY_CNT_24XX;
-		rsp_length = RESPONSE_ENTRY_CNT_2300;
+		req_length = REQUEST_ENTRY_CNT_83XX;
+		rsp_length = RESPONSE_ENTRY_CNT_83XX;
 		ha->tgt.atio_q_length = ATIO_ENTRY_CNT_24XX;
 		ha->max_loop_id = SNS_LAST_LOOP_ID_2300;
 		ha->init_cb_size = sizeof(struct mid_init_cb_81xx);
@@ -3128,6 +3149,14 @@ qla2x00_remove_one(struct pci_dev *pdev)
 
 	base_vha->flags.online = 0;
 
+	/* free DMA memory */
+	if (ha->exlogin_buf)
+		qla2x00_free_exlogin_buffer(ha);
+
+	/* free DMA memory */
+	if (ha->exchoffld_buf)
+		qla2x00_free_exchoffld_buffer(ha);
+
 	qla2x00_destroy_deferred_work(ha);
 
 	qlt_remove_target(ha, base_vha);
@@ -3587,6 +3616,140 @@ fail:
 	return -ENOMEM;
 }
 
+int
+qla2x00_set_exlogins_buffer(scsi_qla_host_t *vha)
+{
+	int rval;
+	uint16_t	size, max_cnt, temp;
+	struct qla_hw_data *ha = vha->hw;
+
+	/* Return if we don't need to alloacate any extended logins */
+	if (!ql2xexlogins)
+		return QLA_SUCCESS;
+
+	ql_log(ql_log_info, vha, 0xd021, "EXLOGIN count: %d.\n", ql2xexlogins);
+	max_cnt = 0;
+	rval = qla_get_exlogin_status(vha, &size, &max_cnt);
+	if (rval != QLA_SUCCESS) {
+		ql_log_pci(ql_log_fatal, ha->pdev, 0xd029,
+		    "Failed to get exlogin status.\n");
+		return rval;
+	}
+
+	temp = (ql2xexlogins > max_cnt) ? max_cnt : ql2xexlogins;
+	ha->exlogin_size = (size * temp);
+	ql_log(ql_log_info, vha, 0xd024,
+		"EXLOGIN: max_logins=%d, portdb=0x%x, total=%d.\n",
+		max_cnt, size, temp);
+
+	ql_log(ql_log_info, vha, 0xd025, "EXLOGIN: requested size=0x%x\n",
+		ha->exlogin_size);
+
+	/* Get consistent memory for extended logins */
+	ha->exlogin_buf = dma_alloc_coherent(&ha->pdev->dev,
+	    ha->exlogin_size, &ha->exlogin_buf_dma, GFP_KERNEL);
+	if (!ha->exlogin_buf) {
+		ql_log_pci(ql_log_fatal, ha->pdev, 0xd02a,
+		    "Failed to allocate memory for exlogin_buf_dma.\n");
+		return -ENOMEM;
+	}
+
+	/* Now configure the dma buffer */
+	rval = qla_set_exlogin_mem_cfg(vha, ha->exlogin_buf_dma);
+	if (rval) {
+		ql_log(ql_log_fatal, vha, 0x00cf,
+		    "Setup extended login buffer  ****FAILED****.\n");
+		qla2x00_free_exlogin_buffer(ha);
+	}
+
+	return rval;
+}
+
+/*
+* qla2x00_free_exlogin_buffer
+*
+* Input:
+*	ha = adapter block pointer
+*/
+void
+qla2x00_free_exlogin_buffer(struct qla_hw_data *ha)
+{
+	if (ha->exlogin_buf) {
+		dma_free_coherent(&ha->pdev->dev, ha->exlogin_size,
+		    ha->exlogin_buf, ha->exlogin_buf_dma);
+		ha->exlogin_buf = NULL;
+		ha->exlogin_size = 0;
+	}
+}
+
+int
+qla2x00_set_exchoffld_buffer(scsi_qla_host_t *vha)
+{
+	int rval;
+	uint16_t	size, max_cnt, temp;
+	struct qla_hw_data *ha = vha->hw;
+
+	/* Return if we don't need to alloacate any extended logins */
+	if (!ql2xexchoffld)
+		return QLA_SUCCESS;
+
+	ql_log(ql_log_info, vha, 0xd014,
+	    "Exchange offload count: %d.\n", ql2xexlogins);
+
+	max_cnt = 0;
+	rval = qla_get_exchoffld_status(vha, &size, &max_cnt);
+	if (rval != QLA_SUCCESS) {
+		ql_log_pci(ql_log_fatal, ha->pdev, 0xd012,
+		    "Failed to get exlogin status.\n");
+		return rval;
+	}
+
+	temp = (ql2xexchoffld > max_cnt) ? max_cnt : ql2xexchoffld;
+	ha->exchoffld_size = (size * temp);
+	ql_log(ql_log_info, vha, 0xd016,
+		"Exchange offload: max_count=%d, buffers=0x%x, total=%d.\n",
+		max_cnt, size, temp);
+
+	ql_log(ql_log_info, vha, 0xd017,
+	    "Exchange Buffers requested size = 0x%x\n", ha->exchoffld_size);
+
+	/* Get consistent memory for extended logins */
+	ha->exchoffld_buf = dma_alloc_coherent(&ha->pdev->dev,
+	    ha->exchoffld_size, &ha->exchoffld_buf_dma, GFP_KERNEL);
+	if (!ha->exchoffld_buf) {
+		ql_log_pci(ql_log_fatal, ha->pdev, 0xd013,
+		    "Failed to allocate memory for exchoffld_buf_dma.\n");
+		return -ENOMEM;
+	}
+
+	/* Now configure the dma buffer */
+	rval = qla_set_exchoffld_mem_cfg(vha, ha->exchoffld_buf_dma);
+	if (rval) {
+		ql_log(ql_log_fatal, vha, 0xd02e,
+		    "Setup exchange offload buffer ****FAILED****.\n");
+		qla2x00_free_exchoffld_buffer(ha);
+	}
+
+	return rval;
+}
+
+/*
+* qla2x00_free_exchoffld_buffer
+*
+* Input:
+*	ha = adapter block pointer
+*/
+void
+qla2x00_free_exchoffld_buffer(struct qla_hw_data *ha)
+{
+	if (ha->exchoffld_buf) {
+		dma_free_coherent(&ha->pdev->dev, ha->exchoffld_size,
+		    ha->exchoffld_buf, ha->exchoffld_buf_dma);
+		ha->exchoffld_buf = NULL;
+		ha->exchoffld_size = 0;
+	}
+}
+
 /*
 * qla2x00_free_fw_dump
 *	Frees fw dump stuff.
@@ -3766,6 +3929,8 @@ struct scsi_qla_host *qla2x00_create_hos
 	INIT_LIST_HEAD(&vha->list);
 	INIT_LIST_HEAD(&vha->qla_cmd_list);
 	INIT_LIST_HEAD(&vha->qla_sess_op_cmd_list);
+	INIT_LIST_HEAD(&vha->logo_list);
+	INIT_LIST_HEAD(&vha->plogi_ack_list);
 
 	spin_lock_init(&vha->work_lock);
 	spin_lock_init(&vha->cmd_list_lock);
@@ -5843,6 +6008,3 @@ MODULE_FIRMWARE(FW_FILE_ISP2300);
 MODULE_FIRMWARE(FW_FILE_ISP2322);
 MODULE_FIRMWARE(FW_FILE_ISP24XX);
 MODULE_FIRMWARE(FW_FILE_ISP25XX);
-MODULE_FIRMWARE(FW_FILE_ISP2031);
-MODULE_FIRMWARE(FW_FILE_ISP8031);
-MODULE_FIRMWARE(FW_FILE_ISP27XX);
--- zfcpdump-kernel-4.4.orig/drivers/scsi/qla2xxx/qla_target.c
+++ zfcpdump-kernel-4.4/drivers/scsi/qla2xxx/qla_target.c
@@ -100,12 +100,12 @@ enum fcp_resp_rsp_codes {
  */
 /* Predefs for callbacks handed to qla2xxx LLD */
 static void qlt_24xx_atio_pkt(struct scsi_qla_host *ha,
-	struct atio_from_isp *pkt);
+	struct atio_from_isp *pkt, uint8_t);
 static void qlt_response_pkt(struct scsi_qla_host *ha, response_t *pkt);
 static int qlt_issue_task_mgmt(struct qla_tgt_sess *sess, uint32_t lun,
 	int fn, void *iocb, int flags);
 static void qlt_send_term_exchange(struct scsi_qla_host *ha, struct qla_tgt_cmd
-	*cmd, struct atio_from_isp *atio, int ha_locked);
+	*cmd, struct atio_from_isp *atio, int ha_locked, int ul_abort);
 static void qlt_reject_free_srr_imm(struct scsi_qla_host *ha,
 	struct qla_tgt_srr_imm *imm, int ha_lock);
 static void qlt_abort_cmd_on_host_reset(struct scsi_qla_host *vha,
@@ -118,10 +118,13 @@ static void qlt_send_notify_ack(struct s
 	struct imm_ntfy_from_isp *ntfy,
 	uint32_t add_flags, uint16_t resp_code, int resp_code_valid,
 	uint16_t srr_flags, uint16_t srr_reject_code, uint8_t srr_explan);
+static void qlt_send_term_imm_notif(struct scsi_qla_host *vha,
+	struct imm_ntfy_from_isp *imm, int ha_locked);
 /*
  * Global Variables
  */
 static struct kmem_cache *qla_tgt_mgmt_cmd_cachep;
+static struct kmem_cache *qla_tgt_plogi_cachep;
 static mempool_t *qla_tgt_mgmt_cmd_mempool;
 static struct workqueue_struct *qla_tgt_wq;
 static DEFINE_MUTEX(qla_tgt_mutex);
@@ -226,8 +229,8 @@ static inline void qlt_decr_num_pend_cmd
 	spin_unlock_irqrestore(&vha->hw->tgt.q_full_lock, flags);
 }
 
-static void qlt_24xx_atio_pkt_all_vps(struct scsi_qla_host *vha,
-	struct atio_from_isp *atio)
+static bool qlt_24xx_atio_pkt_all_vps(struct scsi_qla_host *vha,
+	struct atio_from_isp *atio, uint8_t ha_locked)
 {
 	ql_dbg(ql_dbg_tgt, vha, 0xe072,
 		"%s: qla_target(%d): type %x ox_id %04x\n",
@@ -248,7 +251,7 @@ static void qlt_24xx_atio_pkt_all_vps(st
 			    atio->u.isp24.fcp_hdr.d_id[2]);
 			break;
 		}
-		qlt_24xx_atio_pkt(host, atio);
+		qlt_24xx_atio_pkt(host, atio, ha_locked);
 		break;
 	}
 
@@ -271,7 +274,7 @@ static void qlt_24xx_atio_pkt_all_vps(st
 				break;
 			}
 		}
-		qlt_24xx_atio_pkt(host, atio);
+		qlt_24xx_atio_pkt(host, atio, ha_locked);
 		break;
 	}
 
@@ -282,7 +285,7 @@ static void qlt_24xx_atio_pkt_all_vps(st
 		break;
 	}
 
-	return;
+	return false;
 }
 
 void qlt_response_pkt_all_vps(struct scsi_qla_host *vha, response_t *pkt)
@@ -389,6 +392,131 @@ void qlt_response_pkt_all_vps(struct scs
 
 }
 
+/*
+ * All qlt_plogi_ack_t operations are protected by hardware_lock
+ */
+
+/*
+ * This is a zero-base ref-counting solution, since hardware_lock
+ * guarantees that ref_count is not modified concurrently.
+ * Upon successful return content of iocb is undefined
+ */
+static qlt_plogi_ack_t *
+qlt_plogi_ack_find_add(struct scsi_qla_host *vha, port_id_t *id,
+		       struct imm_ntfy_from_isp *iocb)
+{
+	qlt_plogi_ack_t *pla;
+
+	list_for_each_entry(pla, &vha->plogi_ack_list, list) {
+		if (pla->id.b24 == id->b24) {
+			qlt_send_term_imm_notif(vha, &pla->iocb, 1);
+			pla->iocb = *iocb;
+			return pla;
+		}
+	}
+
+	pla = kmem_cache_zalloc(qla_tgt_plogi_cachep, GFP_ATOMIC);
+	if (!pla) {
+		ql_dbg(ql_dbg_async, vha, 0x5088,
+		       "qla_target(%d): Allocation of plogi_ack failed\n",
+		       vha->vp_idx);
+		return NULL;
+	}
+
+	pla->iocb = *iocb;
+	pla->id = *id;
+	list_add_tail(&pla->list, &vha->plogi_ack_list);
+
+	return pla;
+}
+
+static void qlt_plogi_ack_unref(struct scsi_qla_host *vha, qlt_plogi_ack_t *pla)
+{
+	BUG_ON(!pla->ref_count);
+	pla->ref_count--;
+
+	if (pla->ref_count)
+		return;
+
+	ql_dbg(ql_dbg_async, vha, 0x5089,
+	    "Sending PLOGI ACK to wwn %8phC s_id %02x:%02x:%02x loop_id %#04x"
+	    " exch %#x ox_id %#x\n", pla->iocb.u.isp24.port_name,
+	    pla->iocb.u.isp24.port_id[2], pla->iocb.u.isp24.port_id[1],
+	    pla->iocb.u.isp24.port_id[0],
+	    le16_to_cpu(pla->iocb.u.isp24.nport_handle),
+	    pla->iocb.u.isp24.exchange_address, pla->iocb.ox_id);
+	qlt_send_notify_ack(vha, &pla->iocb, 0, 0, 0, 0, 0, 0);
+
+	list_del(&pla->list);
+	kmem_cache_free(qla_tgt_plogi_cachep, pla);
+}
+
+static void
+qlt_plogi_ack_link(struct scsi_qla_host *vha, qlt_plogi_ack_t *pla,
+    struct qla_tgt_sess *sess, qlt_plogi_link_t link)
+{
+	/* Inc ref_count first because link might already be pointing at pla */
+	pla->ref_count++;
+
+	if (sess->plogi_link[link])
+		qlt_plogi_ack_unref(vha, sess->plogi_link[link]);
+
+	ql_dbg(ql_dbg_tgt_mgt, vha, 0xf097,
+	    "Linking sess %p [%d] wwn %8phC with PLOGI ACK to wwn %8phC"
+	    " s_id %02x:%02x:%02x, ref=%d\n", sess, link, sess->port_name,
+	    pla->iocb.u.isp24.port_name, pla->iocb.u.isp24.port_id[2],
+	    pla->iocb.u.isp24.port_id[1], pla->iocb.u.isp24.port_id[0],
+	    pla->ref_count);
+
+	sess->plogi_link[link] = pla;
+}
+
+typedef struct {
+	/* These fields must be initialized by the caller */
+	port_id_t id;
+	/*
+	 * number of cmds dropped while we were waiting for
+	 * initiator to ack LOGO initialize to 1 if LOGO is
+	 * triggered by a command, otherwise, to 0
+	 */
+	int cmd_count;
+
+	/* These fields are used by callee */
+	struct list_head list;
+} qlt_port_logo_t;
+
+static void
+qlt_send_first_logo(struct scsi_qla_host *vha, qlt_port_logo_t *logo)
+{
+	qlt_port_logo_t *tmp;
+	int res;
+
+	mutex_lock(&vha->vha_tgt.tgt_mutex);
+
+	list_for_each_entry(tmp, &vha->logo_list, list) {
+		if (tmp->id.b24 == logo->id.b24) {
+			tmp->cmd_count += logo->cmd_count;
+			mutex_unlock(&vha->vha_tgt.tgt_mutex);
+			return;
+		}
+	}
+
+	list_add_tail(&logo->list, &vha->logo_list);
+
+	mutex_unlock(&vha->vha_tgt.tgt_mutex);
+
+	res = qla24xx_els_dcmd_iocb(vha, ELS_DCMD_LOGO, logo->id);
+
+	mutex_lock(&vha->vha_tgt.tgt_mutex);
+	list_del(&logo->list);
+	mutex_unlock(&vha->vha_tgt.tgt_mutex);
+
+	ql_dbg(ql_dbg_tgt_mgt, vha, 0xf098,
+	    "Finished LOGO to %02x:%02x:%02x, dropped %d cmds, res = %#x\n",
+	    logo->id.b.domain, logo->id.b.area, logo->id.b.al_pa,
+	    logo->cmd_count, res);
+}
+
 static void qlt_free_session_done(struct work_struct *work)
 {
 	struct qla_tgt_sess *sess = container_of(work, struct qla_tgt_sess,
@@ -402,14 +530,21 @@ static void qlt_free_session_done(struct
 
 	ql_dbg(ql_dbg_tgt_mgt, vha, 0xf084,
 		"%s: se_sess %p / sess %p from port %8phC loop_id %#04x"
-		" s_id %02x:%02x:%02x logout %d keep %d plogi %d\n",
+		" s_id %02x:%02x:%02x logout %d keep %d els_logo %d\n",
 		__func__, sess->se_sess, sess, sess->port_name, sess->loop_id,
 		sess->s_id.b.domain, sess->s_id.b.area, sess->s_id.b.al_pa,
 		sess->logout_on_delete, sess->keep_nport_handle,
-		sess->plogi_ack_needed);
+		sess->send_els_logo);
 
 	BUG_ON(!tgt);
 
+	if (sess->send_els_logo) {
+		qlt_port_logo_t logo;
+		logo.id = sess->s_id;
+		logo.cmd_count = 0;
+		qlt_send_first_logo(vha, &logo);
+	}
+
 	if (sess->logout_on_delete) {
 		int rc;
 
@@ -455,9 +590,34 @@ static void qlt_free_session_done(struct
 
 	spin_lock_irqsave(&ha->hardware_lock, flags);
 
-	if (sess->plogi_ack_needed)
-		qlt_send_notify_ack(vha, &sess->tm_iocb,
-				    0, 0, 0, 0, 0, 0);
+	{
+		qlt_plogi_ack_t *own =
+		    sess->plogi_link[QLT_PLOGI_LINK_SAME_WWN];
+		qlt_plogi_ack_t *con =
+		    sess->plogi_link[QLT_PLOGI_LINK_CONFLICT];
+
+		if (con) {
+			ql_dbg(ql_dbg_tgt_mgt, vha, 0xf099,
+			    "se_sess %p / sess %p port %8phC is gone,"
+			    " %s (ref=%d), releasing PLOGI for %8phC (ref=%d)\n",
+			    sess->se_sess, sess, sess->port_name,
+			    own ? "releasing own PLOGI" :
+			    "no own PLOGI pending",
+			    own ? own->ref_count : -1,
+			    con->iocb.u.isp24.port_name, con->ref_count);
+			qlt_plogi_ack_unref(vha, con);
+		} else {
+			ql_dbg(ql_dbg_tgt_mgt, vha, 0xf09a,
+			    "se_sess %p / sess %p port %8phC is gone, %s (ref=%d)\n",
+			    sess->se_sess, sess, sess->port_name,
+			    own ? "releasing own PLOGI" :
+			    "no own PLOGI pending",
+			    own ? own->ref_count : -1);
+		}
+
+		if (own)
+			qlt_plogi_ack_unref(vha, own);
+	}
 
 	list_del(&sess->sess_list_entry);
 
@@ -476,7 +636,7 @@ static void qlt_free_session_done(struct
 		wake_up_all(&tgt->waitQ);
 }
 
-/* ha->hardware_lock supposed to be held on entry */
+/* ha->tgt.sess_lock supposed to be held on entry */
 void qlt_unreg_sess(struct qla_tgt_sess *sess)
 {
 	struct scsi_qla_host *vha = sess->vha;
@@ -492,7 +652,7 @@ void qlt_unreg_sess(struct qla_tgt_sess
 }
 EXPORT_SYMBOL(qlt_unreg_sess);
 
-/* ha->hardware_lock supposed to be held on entry */
+
 static int qlt_reset(struct scsi_qla_host *vha, void *iocb, int mcmd)
 {
 	struct qla_hw_data *ha = vha->hw;
@@ -502,12 +662,15 @@ static int qlt_reset(struct scsi_qla_hos
 	int res = 0;
 	struct imm_ntfy_from_isp *n = (struct imm_ntfy_from_isp *)iocb;
 	struct atio_from_isp *a = (struct atio_from_isp *)iocb;
+	unsigned long flags;
 
 	loop_id = le16_to_cpu(n->u.isp24.nport_handle);
 	if (loop_id == 0xFFFF) {
 		/* Global event */
 		atomic_inc(&vha->vha_tgt.qla_tgt->tgt_global_resets_count);
+		spin_lock_irqsave(&ha->tgt.sess_lock, flags);
 		qlt_clear_tgt_db(vha->vha_tgt.qla_tgt);
+		spin_unlock_irqrestore(&ha->tgt.sess_lock, flags);
 #if 0 /* FIXME: do we need to choose a session here? */
 		if (!list_empty(&ha->tgt.qla_tgt->sess_list)) {
 			sess = list_entry(ha->tgt.qla_tgt->sess_list.next,
@@ -534,7 +697,9 @@ static int qlt_reset(struct scsi_qla_hos
 			sess = NULL;
 #endif
 	} else {
+		spin_lock_irqsave(&ha->tgt.sess_lock, flags);
 		sess = ha->tgt.tgt_ops->find_sess_by_loop_id(vha, loop_id);
+		spin_unlock_irqrestore(&ha->tgt.sess_lock, flags);
 	}
 
 	ql_dbg(ql_dbg_tgt, vha, 0xe000,
@@ -556,7 +721,7 @@ static int qlt_reset(struct scsi_qla_hos
 	    iocb, QLA24XX_MGMT_SEND_NACK);
 }
 
-/* ha->hardware_lock supposed to be held on entry */
+/* ha->tgt.sess_lock supposed to be held on entry */
 static void qlt_schedule_sess_for_deletion(struct qla_tgt_sess *sess,
 	bool immediate)
 {
@@ -600,7 +765,7 @@ static void qlt_schedule_sess_for_deleti
 		    sess->expires - jiffies);
 }
 
-/* ha->hardware_lock supposed to be held on entry */
+/* ha->tgt.sess_lock supposed to be held on entry */
 static void qlt_clear_tgt_db(struct qla_tgt *tgt)
 {
 	struct qla_tgt_sess *sess;
@@ -636,12 +801,12 @@ static int qla24xx_get_loop_id(struct sc
 		ql_dbg(ql_dbg_tgt_mgt, vha, 0xf045,
 		    "qla_target(%d): get_id_list() failed: %x\n",
 		    vha->vp_idx, rc);
-		res = -1;
+		res = -EBUSY;
 		goto out_free_id_list;
 	}
 
 	id_iter = (char *)gid_list;
-	res = -1;
+	res = -ENOENT;
 	for (i = 0; i < entries; i++) {
 		struct gid_list_info *gid = (struct gid_list_info *)id_iter;
 		if ((gid->al_pa == s_id[2]) &&
@@ -660,7 +825,7 @@ out_free_id_list:
 	return res;
 }
 
-/* ha->hardware_lock supposed to be held on entry */
+/* ha->tgt.sess_lock supposed to be held on entry */
 static void qlt_undelete_sess(struct qla_tgt_sess *sess)
 {
 	BUG_ON(sess->deleted != QLA_SESS_DELETION_PENDING);
@@ -678,7 +843,7 @@ static void qlt_del_sess_work_fn(struct
 	struct qla_tgt_sess *sess;
 	unsigned long flags, elapsed;
 
-	spin_lock_irqsave(&ha->hardware_lock, flags);
+	spin_lock_irqsave(&ha->tgt.sess_lock, flags);
 	while (!list_empty(&tgt->del_sess_list)) {
 		sess = list_entry(tgt->del_sess_list.next, typeof(*sess),
 		    del_list_entry);
@@ -699,7 +864,7 @@ static void qlt_del_sess_work_fn(struct
 			break;
 		}
 	}
-	spin_unlock_irqrestore(&ha->hardware_lock, flags);
+	spin_unlock_irqrestore(&ha->tgt.sess_lock, flags);
 }
 
 /*
@@ -717,7 +882,7 @@ static struct qla_tgt_sess *qlt_create_s
 	unsigned char be_sid[3];
 
 	/* Check to avoid double sessions */
-	spin_lock_irqsave(&ha->hardware_lock, flags);
+	spin_lock_irqsave(&ha->tgt.sess_lock, flags);
 	list_for_each_entry(sess, &vha->vha_tgt.qla_tgt->sess_list,
 				sess_list_entry) {
 		if (!memcmp(sess->port_name, fcport->port_name, WWN_SIZE)) {
@@ -732,7 +897,7 @@ static struct qla_tgt_sess *qlt_create_s
 
 			/* Cannot undelete at this point */
 			if (sess->deleted == QLA_SESS_DELETION_IN_PROGRESS) {
-				spin_unlock_irqrestore(&ha->hardware_lock,
+				spin_unlock_irqrestore(&ha->tgt.sess_lock,
 				    flags);
 				return NULL;
 			}
@@ -749,12 +914,12 @@ static struct qla_tgt_sess *qlt_create_s
 
 			qlt_do_generation_tick(vha, &sess->generation);
 
-			spin_unlock_irqrestore(&ha->hardware_lock, flags);
+			spin_unlock_irqrestore(&ha->tgt.sess_lock, flags);
 
 			return sess;
 		}
 	}
-	spin_unlock_irqrestore(&ha->hardware_lock, flags);
+	spin_unlock_irqrestore(&ha->tgt.sess_lock, flags);
 
 	sess = kzalloc(sizeof(*sess), GFP_KERNEL);
 	if (!sess) {
@@ -799,7 +964,7 @@ static struct qla_tgt_sess *qlt_create_s
 	}
 	/*
 	 * Take an extra reference to ->sess_kref here to handle qla_tgt_sess
-	 * access across ->hardware_lock reaquire.
+	 * access across ->tgt.sess_lock reaquire.
 	 */
 	kref_get(&sess->se_sess->sess_kref);
 
@@ -807,11 +972,11 @@ static struct qla_tgt_sess *qlt_create_s
 	BUILD_BUG_ON(sizeof(sess->port_name) != sizeof(fcport->port_name));
 	memcpy(sess->port_name, fcport->port_name, sizeof(sess->port_name));
 
-	spin_lock_irqsave(&ha->hardware_lock, flags);
+	spin_lock_irqsave(&ha->tgt.sess_lock, flags);
 	list_add_tail(&sess->sess_list_entry, &vha->vha_tgt.qla_tgt->sess_list);
 	vha->vha_tgt.qla_tgt->sess_count++;
 	qlt_do_generation_tick(vha, &sess->generation);
-	spin_unlock_irqrestore(&ha->hardware_lock, flags);
+	spin_unlock_irqrestore(&ha->tgt.sess_lock, flags);
 
 	ql_dbg(ql_dbg_tgt_mgt, vha, 0xf04b,
 	    "qla_target(%d): %ssession for wwn %8phC (loop_id %d, "
@@ -842,23 +1007,23 @@ void qlt_fc_port_added(struct scsi_qla_h
 	if (qla_ini_mode_enabled(vha))
 		return;
 
-	spin_lock_irqsave(&ha->hardware_lock, flags);
+	spin_lock_irqsave(&ha->tgt.sess_lock, flags);
 	if (tgt->tgt_stop) {
-		spin_unlock_irqrestore(&ha->hardware_lock, flags);
+		spin_unlock_irqrestore(&ha->tgt.sess_lock, flags);
 		return;
 	}
 	sess = qlt_find_sess_by_port_name(tgt, fcport->port_name);
 	if (!sess) {
-		spin_unlock_irqrestore(&ha->hardware_lock, flags);
+		spin_unlock_irqrestore(&ha->tgt.sess_lock, flags);
 
 		mutex_lock(&vha->vha_tgt.tgt_mutex);
 		sess = qlt_create_sess(vha, fcport, false);
 		mutex_unlock(&vha->vha_tgt.tgt_mutex);
 
-		spin_lock_irqsave(&ha->hardware_lock, flags);
+		spin_lock_irqsave(&ha->tgt.sess_lock, flags);
 	} else if (sess->deleted == QLA_SESS_DELETION_IN_PROGRESS) {
 		/* Point of no return */
-		spin_unlock_irqrestore(&ha->hardware_lock, flags);
+		spin_unlock_irqrestore(&ha->tgt.sess_lock, flags);
 		return;
 	} else {
 		kref_get(&sess->se_sess->sess_kref);
@@ -887,7 +1052,7 @@ void qlt_fc_port_added(struct scsi_qla_h
 		sess->local = 0;
 	}
 	ha->tgt.tgt_ops->put_sess(sess);
-	spin_unlock_irqrestore(&ha->hardware_lock, flags);
+	spin_unlock_irqrestore(&ha->tgt.sess_lock, flags);
 }
 
 /*
@@ -899,6 +1064,7 @@ qlt_fc_port_deleted(struct scsi_qla_host
 {
 	struct qla_tgt *tgt = vha->vha_tgt.qla_tgt;
 	struct qla_tgt_sess *sess;
+	unsigned long flags;
 
 	if (!vha->hw->tgt.tgt_ops)
 		return;
@@ -906,15 +1072,19 @@ qlt_fc_port_deleted(struct scsi_qla_host
 	if (!tgt)
 		return;
 
+	spin_lock_irqsave(&vha->hw->tgt.sess_lock, flags);
 	if (tgt->tgt_stop) {
+		spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags);
 		return;
 	}
 	sess = qlt_find_sess_by_port_name(tgt, fcport->port_name);
 	if (!sess) {
+		spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags);
 		return;
 	}
 
 	if (max_gen - sess->generation < 0) {
+		spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags);
 		ql_dbg(ql_dbg_tgt_mgt, vha, 0xf092,
 		    "Ignoring stale deletion request for se_sess %p / sess %p"
 		    " for port %8phC, req_gen %d, sess_gen %d\n",
@@ -927,6 +1097,7 @@ qlt_fc_port_deleted(struct scsi_qla_host
 
 	sess->local = 1;
 	qlt_schedule_sess_for_deletion(sess, false);
+	spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags);
 }
 
 static inline int test_tgt_sess_count(struct qla_tgt *tgt)
@@ -984,10 +1155,10 @@ int qlt_stop_phase1(struct qla_tgt *tgt)
 	 * Lock is needed, because we still can get an incoming packet.
 	 */
 	mutex_lock(&vha->vha_tgt.tgt_mutex);
-	spin_lock_irqsave(&ha->hardware_lock, flags);
+	spin_lock_irqsave(&ha->tgt.sess_lock, flags);
 	tgt->tgt_stop = 1;
 	qlt_clear_tgt_db(tgt);
-	spin_unlock_irqrestore(&ha->hardware_lock, flags);
+	spin_unlock_irqrestore(&ha->tgt.sess_lock, flags);
 	mutex_unlock(&vha->vha_tgt.tgt_mutex);
 	mutex_unlock(&qla_tgt_mutex);
 
@@ -1040,7 +1211,7 @@ void qlt_stop_phase2(struct qla_tgt *tgt
 
 	mutex_lock(&vha->vha_tgt.tgt_mutex);
 	spin_lock_irqsave(&ha->hardware_lock, flags);
-	while (tgt->irq_cmd_count != 0) {
+	while ((tgt->irq_cmd_count != 0) || (tgt->atio_irq_cmd_count != 0)) {
 		spin_unlock_irqrestore(&ha->hardware_lock, flags);
 		udelay(2);
 		spin_lock_irqsave(&ha->hardware_lock, flags);
@@ -1309,7 +1480,7 @@ static int abort_cmd_for_tag(struct scsi
 
 	list_for_each_entry(cmd, &vha->qla_cmd_list, cmd_list) {
 		if (tag == cmd->atio.u.isp24.exchange_addr) {
-			cmd->state = QLA_TGT_STATE_ABORTED;
+			cmd->aborted = 1;
 			spin_unlock(&vha->cmd_list_lock);
 			return 1;
 		}
@@ -1351,7 +1522,7 @@ static void abort_cmds_for_lun(struct sc
 		cmd_lun = scsilun_to_int(
 			(struct scsi_lun *)&cmd->atio.u.isp24.fcp_cmnd.lun);
 		if (cmd_key == key && cmd_lun == lun)
-			cmd->state = QLA_TGT_STATE_ABORTED;
+			cmd->aborted = 1;
 	}
 	spin_unlock(&vha->cmd_list_lock);
 }
@@ -1435,6 +1606,7 @@ static void qlt_24xx_handle_abts(struct
 	uint32_t tag = abts->exchange_addr_to_abort;
 	uint8_t s_id[3];
 	int rc;
+	unsigned long flags;
 
 	if (le32_to_cpu(abts->fcp_hdr_le.parameter) & ABTS_PARAM_ABORT_SEQ) {
 		ql_dbg(ql_dbg_tgt_mgt, vha, 0xf053,
@@ -1462,6 +1634,7 @@ static void qlt_24xx_handle_abts(struct
 	s_id[1] = abts->fcp_hdr_le.s_id[1];
 	s_id[2] = abts->fcp_hdr_le.s_id[0];
 
+	spin_lock_irqsave(&ha->tgt.sess_lock, flags);
 	sess = ha->tgt.tgt_ops->find_sess_by_s_id(vha, s_id);
 	if (!sess) {
 		ql_dbg(ql_dbg_tgt_mgt, vha, 0xf012,
@@ -1469,12 +1642,17 @@ static void qlt_24xx_handle_abts(struct
 		    vha->vp_idx);
 		rc = qlt_sched_sess_work(vha->vha_tgt.qla_tgt,
 		    QLA_TGT_SESS_WORK_ABORT, abts, sizeof(*abts));
+
+		spin_unlock_irqrestore(&ha->tgt.sess_lock, flags);
+
 		if (rc != 0) {
 			qlt_24xx_send_abts_resp(vha, abts, FCP_TMF_REJECTED,
 			    false);
 		}
 		return;
 	}
+	spin_unlock_irqrestore(&ha->tgt.sess_lock, flags);
+
 
 	if (sess->deleted == QLA_SESS_DELETION_IN_PROGRESS) {
 		qlt_24xx_send_abts_resp(vha, abts, FCP_TMF_REJECTED, false);
@@ -1560,15 +1738,15 @@ void qlt_xmit_tm_rsp(struct qla_tgt_mgmt
 
 	spin_lock_irqsave(&ha->hardware_lock, flags);
 
-	if (qla2x00_reset_active(vha) || mcmd->reset_count != ha->chip_reset) {
+	if (!vha->flags.online || mcmd->reset_count != ha->chip_reset) {
 		/*
-		 * Either a chip reset is active or this request was from
+		 * Either the port is not online or this request was from
 		 * previous life, just abort the processing.
 		 */
 		ql_dbg(ql_dbg_async, vha, 0xe100,
-			"RESET-TMR active/old-count/new-count = %d/%d/%d.\n",
-			qla2x00_reset_active(vha), mcmd->reset_count,
-			ha->chip_reset);
+			"RESET-TMR online/active/old-count/new-count = %d/%d/%d/%d.\n",
+			vha->flags.online, qla2x00_reset_active(vha),
+			mcmd->reset_count, ha->chip_reset);
 		ha->tgt.tgt_ops->free_mcmd(mcmd);
 		spin_unlock_irqrestore(&ha->hardware_lock, flags);
 		return;
@@ -1578,7 +1756,7 @@ void qlt_xmit_tm_rsp(struct qla_tgt_mgmt
 		qlt_send_notify_ack(vha, &mcmd->orig_iocb.imm_ntfy,
 		    0, 0, 0, 0, 0, 0);
 	else {
-		if (mcmd->se_cmd.se_tmr_req->function == TMR_ABORT_TASK)
+		if (mcmd->orig_iocb.atio.u.raw.entry_type == ABTS_RECV_24XX)
 			qlt_24xx_send_abts_resp(vha, &mcmd->orig_iocb.abts,
 			    mcmd->fc_tm_rsp, false);
 		else
@@ -2487,7 +2665,7 @@ int qlt_xmit_response(struct qla_tgt_cmd
 			/* no need to terminate. FW already freed exchange. */
 			qlt_abort_cmd_on_host_reset(cmd->vha, cmd);
 		else
-			qlt_send_term_exchange(vha, cmd, &cmd->atio, 1);
+			qlt_send_term_exchange(vha, cmd, &cmd->atio, 1, 0);
 		spin_unlock_irqrestore(&ha->hardware_lock, flags);
 		return 0;
 	}
@@ -2510,17 +2688,22 @@ int qlt_xmit_response(struct qla_tgt_cmd
 
 	spin_lock_irqsave(&ha->hardware_lock, flags);
 
-	if (qla2x00_reset_active(vha) || cmd->reset_count != ha->chip_reset) {
+	if (xmit_type == QLA_TGT_XMIT_STATUS)
+		vha->tgt_counters.core_qla_snd_status++;
+	else
+		vha->tgt_counters.core_qla_que_buf++;
+
+	if (!vha->flags.online || cmd->reset_count != ha->chip_reset) {
 		/*
-		 * Either a chip reset is active or this request was from
+		 * Either the port is not online or this request was from
 		 * previous life, just abort the processing.
 		 */
 		cmd->state = QLA_TGT_STATE_PROCESSED;
 		qlt_abort_cmd_on_host_reset(cmd->vha, cmd);
 		ql_dbg(ql_dbg_async, vha, 0xe101,
-			"RESET-RSP active/old-count/new-count = %d/%d/%d.\n",
-			qla2x00_reset_active(vha), cmd->reset_count,
-			ha->chip_reset);
+			"RESET-RSP online/active/old-count/new-count = %d/%d/%d/%d.\n",
+			vha->flags.online, qla2x00_reset_active(vha),
+			cmd->reset_count, ha->chip_reset);
 		spin_unlock_irqrestore(&ha->hardware_lock, flags);
 		return 0;
 	}
@@ -2651,18 +2834,18 @@ int qlt_rdy_to_xfer(struct qla_tgt_cmd *
 
 	spin_lock_irqsave(&ha->hardware_lock, flags);
 
-	if (qla2x00_reset_active(vha) || (cmd->reset_count != ha->chip_reset) ||
+	if (!vha->flags.online || (cmd->reset_count != ha->chip_reset) ||
 	    (cmd->sess && cmd->sess->deleted == QLA_SESS_DELETION_IN_PROGRESS)) {
 		/*
-		 * Either a chip reset is active or this request was from
+		 * Either the port is not online or this request was from
 		 * previous life, just abort the processing.
 		 */
 		cmd->state = QLA_TGT_STATE_NEED_DATA;
 		qlt_abort_cmd_on_host_reset(cmd->vha, cmd);
 		ql_dbg(ql_dbg_async, vha, 0xe102,
-			"RESET-XFR active/old-count/new-count = %d/%d/%d.\n",
-			qla2x00_reset_active(vha), cmd->reset_count,
-			ha->chip_reset);
+			"RESET-XFR online/active/old-count/new-count = %d/%d/%d/%d.\n",
+			vha->flags.online, qla2x00_reset_active(vha),
+			cmd->reset_count, ha->chip_reset);
 		spin_unlock_irqrestore(&ha->hardware_lock, flags);
 		return 0;
 	}
@@ -2957,12 +3140,13 @@ static int __qlt_send_term_exchange(stru
 			ret = 1;
 	}
 
+	vha->tgt_counters.num_term_xchg_sent++;
 	pkt->entry_count = 1;
 	pkt->handle = QLA_TGT_SKIP_HANDLE | CTIO_COMPLETION_HANDLE_MARK;
 
 	ctio24 = (struct ctio7_to_24xx *)pkt;
 	ctio24->entry_type = CTIO_TYPE7;
-	ctio24->nport_handle = cmd ? cmd->loop_id : CTIO7_NHANDLE_UNRECOGNIZED;
+	ctio24->nport_handle = CTIO7_NHANDLE_UNRECOGNIZED;
 	ctio24->timeout = cpu_to_le16(QLA_TGT_TIMEOUT);
 	ctio24->vp_index = vha->vp_idx;
 	ctio24->initiator_id[0] = atio->u.isp24.fcp_hdr.s_id[2];
@@ -2989,7 +3173,8 @@ static int __qlt_send_term_exchange(stru
 }
 
 static void qlt_send_term_exchange(struct scsi_qla_host *vha,
-	struct qla_tgt_cmd *cmd, struct atio_from_isp *atio, int ha_locked)
+	struct qla_tgt_cmd *cmd, struct atio_from_isp *atio, int ha_locked,
+	int ul_abort)
 {
 	unsigned long flags = 0;
 	int rc;
@@ -3009,8 +3194,7 @@ static void qlt_send_term_exchange(struc
 		qlt_alloc_qfull_cmd(vha, atio, 0, 0);
 
 done:
-	if (cmd && ((cmd->state != QLA_TGT_STATE_ABORTED) ||
-	    !cmd->cmd_sent_to_fw)) {
+	if (cmd && !ul_abort && !cmd->aborted) {
 		if (cmd->sg_mapped)
 			qlt_unmap_sg(vha, cmd);
 		vha->hw->tgt.tgt_ops->free_cmd(cmd);
@@ -3028,7 +3212,7 @@ static void qlt_init_term_exchange(struc
 	struct qla_tgt_cmd *cmd, *tcmd;
 
 	vha->hw->tgt.leak_exchg_thresh_hold =
-	    (vha->hw->fw_xcb_count/100) * LEAK_EXCHG_THRESH_HOLD_PERCENT;
+	    (vha->hw->cur_fw_xcb_count/100) * LEAK_EXCHG_THRESH_HOLD_PERCENT;
 
 	cmd = tcmd = NULL;
 	if (!list_empty(&vha->hw->tgt.q_full_list)) {
@@ -3058,7 +3242,7 @@ static void qlt_chk_exch_leak_thresh_hol
 
 		ql_dbg(ql_dbg_tgt, vha, 0xe079,
 		    "Chip reset due to exchange starvation: %d/%d.\n",
-		    total_leaked, vha->hw->fw_xcb_count);
+		    total_leaked, vha->hw->cur_fw_xcb_count);
 
 		if (IS_P3P_TYPE(vha->hw))
 			set_bit(FCOE_CTX_RESET_NEEDED, &vha->dpc_flags);
@@ -3069,21 +3253,38 @@ static void qlt_chk_exch_leak_thresh_hol
 
 }
 
-void qlt_abort_cmd(struct qla_tgt_cmd *cmd)
+int qlt_abort_cmd(struct qla_tgt_cmd *cmd)
 {
 	struct qla_tgt *tgt = cmd->tgt;
 	struct scsi_qla_host *vha = tgt->vha;
 	struct se_cmd *se_cmd = &cmd->se_cmd;
+	unsigned long flags;
 
 	ql_dbg(ql_dbg_tgt_mgt, vha, 0xf014,
 	    "qla_target(%d): terminating exchange for aborted cmd=%p "
 	    "(se_cmd=%p, tag=%llu)", vha->vp_idx, cmd, &cmd->se_cmd,
 	    se_cmd->tag);
 
-	cmd->state = QLA_TGT_STATE_ABORTED;
+	spin_lock_irqsave(&cmd->cmd_lock, flags);
+	if (cmd->aborted) {
+		spin_unlock_irqrestore(&cmd->cmd_lock, flags);
+		/*
+		 * It's normal to see 2 calls in this path:
+		 *  1) XFER Rdy completion + CMD_T_ABORT
+		 *  2) TCM TMR - drain_state_list
+		 */
+	        ql_dbg(ql_dbg_tgt_mgt, vha, 0xffff,
+			"multiple abort. %p transport_state %x, t_state %x,"
+			" se_cmd_flags %x \n", cmd, cmd->se_cmd.transport_state,
+			cmd->se_cmd.t_state,cmd->se_cmd.se_cmd_flags);
+		return EIO;
+	}
+	cmd->aborted = 1;
 	cmd->cmd_flags |= BIT_6;
+	spin_unlock_irqrestore(&cmd->cmd_lock, flags);
 
-	qlt_send_term_exchange(vha, cmd, &cmd->atio, 0);
+	qlt_send_term_exchange(vha, cmd, &cmd->atio, 0, 1);
+	return 0;
 }
 EXPORT_SYMBOL(qlt_abort_cmd);
 
@@ -3098,6 +3299,9 @@ void qlt_free_cmd(struct qla_tgt_cmd *cm
 
 	BUG_ON(cmd->cmd_in_wq);
 
+	if (cmd->sg_mapped)
+		qlt_unmap_sg(cmd->vha, cmd);
+
 	if (!cmd->q_full)
 		qlt_decr_num_pend_cmds(cmd->vha);
 
@@ -3215,7 +3419,7 @@ static int qlt_term_ctio_exchange(struct
 		term = 1;
 
 	if (term)
-		qlt_send_term_exchange(vha, cmd, &cmd->atio, 1);
+		qlt_send_term_exchange(vha, cmd, &cmd->atio, 1, 0);
 
 	return term;
 }
@@ -3300,9 +3504,6 @@ qlt_abort_cmd_on_host_reset(struct scsi_
 
 		ha->tgt.tgt_ops->handle_data(cmd);
 		return;
-	} else if (cmd->state == QLA_TGT_STATE_ABORTED) {
-		ql_dbg(ql_dbg_io, vha, 0xff02,
-		    "HOST-ABORT: handle=%d, state=ABORTED.\n", handle);
 	} else {
 		ql_dbg(ql_dbg_io, vha, 0xff03,
 		    "HOST-ABORT: handle=%d, state=BAD(%d).\n", handle,
@@ -3398,13 +3599,27 @@ static void qlt_do_ctio_completion(struc
 
 		case CTIO_PORT_LOGGED_OUT:
 		case CTIO_PORT_UNAVAILABLE:
+		{
+			int logged_out =
+				(status & 0xFFFF) == CTIO_PORT_LOGGED_OUT;
+
 			ql_dbg(ql_dbg_tgt_mgt, vha, 0xf059,
-			    "qla_target(%d): CTIO with PORT LOGGED "
-			    "OUT (29) or PORT UNAVAILABLE (28) status %x "
+			    "qla_target(%d): CTIO with %s status %x "
 			    "received (state %x, se_cmd %p)\n", vha->vp_idx,
+			    logged_out ? "PORT LOGGED OUT" : "PORT UNAVAILABLE",
 			    status, cmd->state, se_cmd);
-			break;
 
+			if (logged_out && cmd->sess) {
+				/*
+				 * Session is already logged out, but we need
+				 * to notify initiator, who's not aware of this
+				 */
+				cmd->sess->logout_on_delete = 0;
+				cmd->sess->send_els_logo = 1;
+				qlt_schedule_sess_for_deletion(cmd->sess, true);
+			}
+			break;
+		}
 		case CTIO_SRR_RECEIVED:
 			ql_dbg(ql_dbg_tgt_mgt, vha, 0xf05a,
 			    "qla_target(%d): CTIO with SRR_RECEIVED"
@@ -3454,14 +3669,14 @@ static void qlt_do_ctio_completion(struc
 		}
 
 
-		/* "cmd->state == QLA_TGT_STATE_ABORTED" means
+		/* "cmd->aborted" means
 		 * cmd is already aborted/terminated, we don't
 		 * need to terminate again.  The exchange is already
 		 * cleaned up/freed at FW level.  Just cleanup at driver
 		 * level.
 		 */
 		if ((cmd->state != QLA_TGT_STATE_NEED_DATA) &&
-		    (cmd->state != QLA_TGT_STATE_ABORTED)) {
+		    (!cmd->aborted)) {
 			cmd->cmd_flags |= BIT_13;
 			if (qlt_term_ctio_exchange(vha, ctio, cmd, status))
 				return;
@@ -3479,7 +3694,7 @@ skip_term:
 
 		ha->tgt.tgt_ops->handle_data(cmd);
 		return;
-	} else if (cmd->state == QLA_TGT_STATE_ABORTED) {
+	} else if (cmd->aborted) {
 		cmd->cmd_flags |= BIT_18;
 		ql_dbg(ql_dbg_tgt_mgt, vha, 0xf01e,
 		  "Aborted command %p (tag %lld) finished\n", cmd, se_cmd->tag);
@@ -3491,7 +3706,7 @@ skip_term:
 	}
 
 	if (unlikely(status != CTIO_SUCCESS) &&
-		(cmd->state != QLA_TGT_STATE_ABORTED)) {
+		!cmd->aborted) {
 		ql_dbg(ql_dbg_tgt_mgt, vha, 0xf01f, "Finishing failed CTIO\n");
 		dump_stack();
 	}
@@ -3553,13 +3768,14 @@ static void __qlt_do_work(struct qla_tgt
 	if (tgt->tgt_stop)
 		goto out_term;
 
-	if (cmd->state == QLA_TGT_STATE_ABORTED) {
+	if (cmd->aborted) {
 		ql_dbg(ql_dbg_tgt_mgt, vha, 0xf082,
 		    "cmd with tag %u is aborted\n",
 		    cmd->atio.u.isp24.exchange_addr);
 		goto out_term;
 	}
 
+	spin_lock_init(&cmd->cmd_lock);
 	cdb = &atio->u.isp24.fcp_cmnd.cdb[0];
 	cmd->se_cmd.tag = atio->u.isp24.exchange_addr;
 	cmd->unpacked_lun = scsilun_to_int(
@@ -3589,9 +3805,9 @@ static void __qlt_do_work(struct qla_tgt
 	/*
 	 * Drop extra session reference from qla_tgt_handle_cmd_for_atio*(
 	 */
-	spin_lock_irqsave(&ha->hardware_lock, flags);
+	spin_lock_irqsave(&ha->tgt.sess_lock, flags);
 	ha->tgt.tgt_ops->put_sess(sess);
-	spin_unlock_irqrestore(&ha->hardware_lock, flags);
+	spin_unlock_irqrestore(&ha->tgt.sess_lock, flags);
 	return;
 
 out_term:
@@ -3602,12 +3818,15 @@ out_term:
 	 */
 	cmd->cmd_flags |= BIT_2;
 	spin_lock_irqsave(&ha->hardware_lock, flags);
-	qlt_send_term_exchange(vha, NULL, &cmd->atio, 1);
+	qlt_send_term_exchange(vha, NULL, &cmd->atio, 1, 0);
 
 	qlt_decr_num_pend_cmds(vha);
 	percpu_ida_free(&sess->se_sess->sess_tag_pool, cmd->se_cmd.map_tag);
-	ha->tgt.tgt_ops->put_sess(sess);
 	spin_unlock_irqrestore(&ha->hardware_lock, flags);
+
+	spin_lock_irqsave(&ha->tgt.sess_lock, flags);
+	ha->tgt.tgt_ops->put_sess(sess);
+	spin_unlock_irqrestore(&ha->tgt.sess_lock, flags);
 }
 
 static void qlt_do_work(struct work_struct *work)
@@ -3692,10 +3911,8 @@ static void qlt_create_sess_from_atio(st
 		goto out_term;
 	}
 
-	mutex_lock(&vha->vha_tgt.tgt_mutex);
 	sess = qlt_make_local_sess(vha, s_id);
 	/* sess has an extra creation ref. */
-	mutex_unlock(&vha->vha_tgt.tgt_mutex);
 
 	if (!sess)
 		goto out_term;
@@ -3723,7 +3940,7 @@ static void qlt_create_sess_from_atio(st
 
 out_term:
 	spin_lock_irqsave(&ha->hardware_lock, flags);
-	qlt_send_term_exchange(vha, NULL, &op->atio, 1);
+	qlt_send_term_exchange(vha, NULL, &op->atio, 1, 0);
 	spin_unlock_irqrestore(&ha->hardware_lock, flags);
 	kfree(op);
 
@@ -3787,13 +4004,24 @@ static int qlt_handle_cmd_for_atio(struc
 
 	cmd->cmd_in_wq = 1;
 	cmd->cmd_flags |= BIT_0;
+	cmd->se_cmd.cpuid = ha->msix_count ?
+		ha->tgt.rspq_vector_cpuid : WORK_CPU_UNBOUND;
 
 	spin_lock(&vha->cmd_list_lock);
 	list_add_tail(&cmd->cmd_list, &vha->qla_cmd_list);
 	spin_unlock(&vha->cmd_list_lock);
 
 	INIT_WORK(&cmd->work, qlt_do_work);
-	queue_work(qla_tgt_wq, &cmd->work);
+	if (ha->msix_count) {
+		if (cmd->atio.u.isp24.fcp_cmnd.rddata)
+			queue_work_on(smp_processor_id(), qla_tgt_wq,
+			    &cmd->work);
+		else
+			queue_work_on(cmd->se_cmd.cpuid, qla_tgt_wq,
+			    &cmd->work);
+	} else {
+		queue_work(qla_tgt_wq, &cmd->work);
+	}
 	return 0;
 
 }
@@ -3917,13 +4145,18 @@ static int qlt_handle_task_mgmt(struct s
 	struct qla_tgt_sess *sess;
 	uint32_t lun, unpacked_lun;
 	int fn;
+	unsigned long flags;
 
 	tgt = vha->vha_tgt.qla_tgt;
 
 	lun = a->u.isp24.fcp_cmnd.lun;
 	fn = a->u.isp24.fcp_cmnd.task_mgmt_flags;
+
+	spin_lock_irqsave(&ha->tgt.sess_lock, flags);
 	sess = ha->tgt.tgt_ops->find_sess_by_s_id(vha,
 	    a->u.isp24.fcp_hdr.s_id);
+	spin_unlock_irqrestore(&ha->tgt.sess_lock, flags);
+
 	unpacked_lun = scsilun_to_int((struct scsi_lun *)&lun);
 
 	if (!sess) {
@@ -3987,10 +4220,14 @@ static int qlt_abort_task(struct scsi_ql
 	struct qla_hw_data *ha = vha->hw;
 	struct qla_tgt_sess *sess;
 	int loop_id;
+	unsigned long flags;
 
 	loop_id = GET_TARGET_ID(ha, (struct atio_from_isp *)iocb);
 
+	spin_lock_irqsave(&ha->tgt.sess_lock, flags);
 	sess = ha->tgt.tgt_ops->find_sess_by_loop_id(vha, loop_id);
+	spin_unlock_irqrestore(&ha->tgt.sess_lock, flags);
+
 	if (sess == NULL) {
 		ql_dbg(ql_dbg_tgt_mgt, vha, 0xf025,
 		    "qla_target(%d): task abort for unexisting "
@@ -4022,15 +4259,6 @@ void qlt_logo_completion_handler(fc_port
 	}
 }
 
-static void qlt_swap_imm_ntfy_iocb(struct imm_ntfy_from_isp *a,
-    struct imm_ntfy_from_isp *b)
-{
-	struct imm_ntfy_from_isp tmp;
-	memcpy(&tmp, a, sizeof(struct imm_ntfy_from_isp));
-	memcpy(a, b, sizeof(struct imm_ntfy_from_isp));
-	memcpy(b, &tmp, sizeof(struct imm_ntfy_from_isp));
-}
-
 /*
 * ha->hardware_lock supposed to be held on entry (to protect tgt->sess_list)
 *
@@ -4040,11 +4268,13 @@ static void qlt_swap_imm_ntfy_iocb(struc
 */
 static struct qla_tgt_sess *
 qlt_find_sess_invalidate_other(struct qla_tgt *tgt, uint64_t wwn,
-    port_id_t port_id, uint16_t loop_id)
+    port_id_t port_id, uint16_t loop_id, struct qla_tgt_sess **conflict_sess)
 {
 	struct qla_tgt_sess *sess = NULL, *other_sess;
 	uint64_t other_wwn;
 
+	*conflict_sess = NULL;
+
 	list_for_each_entry(other_sess, &tgt->sess_list, sess_list_entry) {
 
 		other_wwn = wwn_to_u64(other_sess->port_name);
@@ -4072,9 +4302,10 @@ qlt_find_sess_invalidate_other(struct ql
 			} else {
 				/*
 				 * Another wwn used to have our s_id/loop_id
-				 * combo - kill the session, but don't log out
+				 * kill the session, but don't free the loop_id
 				 */
-				sess->logout_on_delete = 0;
+				other_sess->keep_nport_handle = 1;
+				*conflict_sess = other_sess;
 				qlt_schedule_sess_for_deletion(other_sess,
 				    true);
 			}
@@ -4119,7 +4350,7 @@ static int abort_cmds_for_s_id(struct sc
 	list_for_each_entry(cmd, &vha->qla_cmd_list, cmd_list) {
 		uint32_t cmd_key = sid_to_key(cmd->atio.u.isp24.fcp_hdr.s_id);
 		if (cmd_key == key) {
-			cmd->state = QLA_TGT_STATE_ABORTED;
+			cmd->aborted = 1;
 			count++;
 		}
 	}
@@ -4136,12 +4367,14 @@ static int qlt_24xx_handle_els(struct sc
 {
 	struct qla_tgt *tgt = vha->vha_tgt.qla_tgt;
 	struct qla_hw_data *ha = vha->hw;
-	struct qla_tgt_sess *sess = NULL;
+	struct qla_tgt_sess *sess = NULL, *conflict_sess = NULL;
 	uint64_t wwn;
 	port_id_t port_id;
 	uint16_t loop_id;
 	uint16_t wd3_lo;
 	int res = 0;
+	qlt_plogi_ack_t *pla;
+	unsigned long flags;
 
 	wwn = wwn_to_u64(iocb->u.isp24.port_name);
 
@@ -4165,27 +4398,20 @@ static int qlt_24xx_handle_els(struct sc
 		/* Mark all stale commands in qla_tgt_wq for deletion */
 		abort_cmds_for_s_id(vha, &port_id);
 
-		if (wwn)
+		if (wwn) {
+			spin_lock_irqsave(&tgt->ha->tgt.sess_lock, flags);
 			sess = qlt_find_sess_invalidate_other(tgt, wwn,
-			    port_id, loop_id);
+			    port_id, loop_id, &conflict_sess);
+			spin_unlock_irqrestore(&tgt->ha->tgt.sess_lock, flags);
+		}
 
-		if (!sess || IS_SW_RESV_ADDR(sess->s_id)) {
+		if (IS_SW_RESV_ADDR(port_id) || (!sess && !conflict_sess)) {
 			res = 1;
 			break;
 		}
 
-		if (sess->plogi_ack_needed) {
-			/*
-			 * Initiator sent another PLOGI before last PLOGI could
-			 * finish. Swap plogi iocbs and terminate old one
-			 * without acking, new one will get acked when session
-			 * deletion completes.
-			 */
-			ql_log(ql_log_warn, sess->vha, 0xf094,
-			    "sess %p received double plogi.\n", sess);
-
-			qlt_swap_imm_ntfy_iocb(iocb, &sess->tm_iocb);
-
+		pla = qlt_plogi_ack_find_add(vha, &port_id, iocb);
+		if (!pla) {
 			qlt_send_term_imm_notif(vha, iocb, 1);
 
 			res = 0;
@@ -4194,13 +4420,14 @@ static int qlt_24xx_handle_els(struct sc
 
 		res = 0;
 
-		/*
-		 * Save immediate Notif IOCB for Ack when sess is done
-		 * and being deleted.
-		 */
-		memcpy(&sess->tm_iocb, iocb, sizeof(sess->tm_iocb));
-		sess->plogi_ack_needed  = 1;
+		if (conflict_sess)
+			qlt_plogi_ack_link(vha, pla, conflict_sess,
+			    QLT_PLOGI_LINK_CONFLICT);
+
+		if (!sess)
+			break;
 
+		qlt_plogi_ack_link(vha, pla, sess, QLT_PLOGI_LINK_SAME_WWN);
 		 /*
 		  * Under normal circumstances we want to release nport handle
 		  * during LOGO process to avoid nport handle leaks inside FW.
@@ -4227,9 +4454,21 @@ static int qlt_24xx_handle_els(struct sc
 	case ELS_PRLI:
 		wd3_lo = le16_to_cpu(iocb->u.isp24.u.prli.wd3_lo);
 
-		if (wwn)
+		if (wwn) {
+			spin_lock_irqsave(&tgt->ha->tgt.sess_lock, flags);
 			sess = qlt_find_sess_invalidate_other(tgt, wwn, port_id,
-			    loop_id);
+			    loop_id, &conflict_sess);
+			spin_unlock_irqrestore(&tgt->ha->tgt.sess_lock, flags);
+		}
+
+		if (conflict_sess) {
+			ql_dbg(ql_dbg_tgt_mgt, vha, 0xf09b,
+			    "PRLI with conflicting sess %p port %8phC\n",
+			    conflict_sess, conflict_sess->port_name);
+			qlt_send_term_imm_notif(vha, iocb, 1);
+			res = 0;
+			break;
+		}
 
 		if (sess != NULL) {
 			if (sess->deleted) {
@@ -4554,7 +4793,7 @@ out_reject:
 		dump_stack();
 	} else {
 		cmd->cmd_flags |= BIT_9;
-		qlt_send_term_exchange(vha, cmd, &cmd->atio, 1);
+		qlt_send_term_exchange(vha, cmd, &cmd->atio, 1, 0);
 	}
 	spin_unlock_irqrestore(&ha->hardware_lock, flags);
 }
@@ -4733,7 +4972,7 @@ static void qlt_prepare_srr_imm(struct s
 				    sctio, sctio->srr_id);
 				list_del(&sctio->srr_list_entry);
 				qlt_send_term_exchange(vha, sctio->cmd,
-				    &sctio->cmd->atio, 1);
+				    &sctio->cmd->atio, 1, 0);
 				kfree(sctio);
 			}
 		}
@@ -4899,11 +5138,14 @@ static int __qlt_send_busy(struct scsi_q
 	struct qla_hw_data *ha = vha->hw;
 	request_t *pkt;
 	struct qla_tgt_sess *sess = NULL;
+	unsigned long flags;
 
+	spin_lock_irqsave(&ha->tgt.sess_lock, flags);
 	sess = ha->tgt.tgt_ops->find_sess_by_s_id(vha,
 	    atio->u.isp24.fcp_hdr.s_id);
+	spin_unlock_irqrestore(&ha->tgt.sess_lock, flags);
 	if (!sess) {
-		qlt_send_term_exchange(vha, NULL, atio, 1);
+		qlt_send_term_exchange(vha, NULL, atio, 1, 0);
 		return 0;
 	}
 	/* Sending marker isn't necessary, since we called from ISR */
@@ -4916,6 +5158,7 @@ static int __qlt_send_busy(struct scsi_q
 		return -ENOMEM;
 	}
 
+	vha->tgt_counters.num_q_full_sent++;
 	pkt->entry_count = 1;
 	pkt->handle = QLA_TGT_SKIP_HANDLE | CTIO_COMPLETION_HANDLE_MARK;
 
@@ -5129,11 +5372,12 @@ qlt_chk_qfull_thresh_hold(struct scsi_ql
 /* ha->hardware_lock supposed to be held on entry */
 /* called via callback from qla2xxx */
 static void qlt_24xx_atio_pkt(struct scsi_qla_host *vha,
-	struct atio_from_isp *atio)
+	struct atio_from_isp *atio, uint8_t ha_locked)
 {
 	struct qla_hw_data *ha = vha->hw;
 	struct qla_tgt *tgt = vha->vha_tgt.qla_tgt;
 	int rc;
+	unsigned long flags;
 
 	if (unlikely(tgt == NULL)) {
 		ql_dbg(ql_dbg_io, vha, 0x3064,
@@ -5145,7 +5389,7 @@ static void qlt_24xx_atio_pkt(struct scs
 	 * Otherwise, some commands can stuck.
 	 */
 
-	tgt->irq_cmd_count++;
+	tgt->atio_irq_cmd_count++;
 
 	switch (atio->u.raw.entry_type) {
 	case ATIO_TYPE7:
@@ -5155,7 +5399,11 @@ static void qlt_24xx_atio_pkt(struct scs
 			    "qla_target(%d): ATIO_TYPE7 "
 			    "received with UNKNOWN exchange address, "
 			    "sending QUEUE_FULL\n", vha->vp_idx);
+			if (!ha_locked)
+				spin_lock_irqsave(&ha->hardware_lock, flags);
 			qlt_send_busy(vha, atio, SAM_STAT_TASK_SET_FULL);
+			if (!ha_locked)
+				spin_unlock_irqrestore(&ha->hardware_lock, flags);
 			break;
 		}
 
@@ -5164,7 +5412,7 @@ static void qlt_24xx_atio_pkt(struct scs
 		if (likely(atio->u.isp24.fcp_cmnd.task_mgmt_flags == 0)) {
 			rc = qlt_chk_qfull_thresh_hold(vha, atio);
 			if (rc != 0) {
-				tgt->irq_cmd_count--;
+				tgt->atio_irq_cmd_count--;
 				return;
 			}
 			rc = qlt_handle_cmd_for_atio(vha, atio);
@@ -5173,11 +5421,20 @@ static void qlt_24xx_atio_pkt(struct scs
 		}
 		if (unlikely(rc != 0)) {
 			if (rc == -ESRCH) {
+				if (!ha_locked)
+					spin_lock_irqsave
+						(&ha->hardware_lock, flags);
+
 #if 1 /* With TERM EXCHANGE some FC cards refuse to boot */
 				qlt_send_busy(vha, atio, SAM_STAT_BUSY);
 #else
-				qlt_send_term_exchange(vha, NULL, atio, 1);
+				qlt_send_term_exchange(vha, NULL, atio, 1, 0);
 #endif
+
+				if (!ha_locked)
+					spin_unlock_irqrestore
+						(&ha->hardware_lock, flags);
+
 			} else {
 				if (tgt->tgt_stop) {
 					ql_dbg(ql_dbg_tgt, vha, 0xe059,
@@ -5189,7 +5446,13 @@ static void qlt_24xx_atio_pkt(struct scs
 					    "qla_target(%d): Unable to send "
 					    "command to target, sending BUSY "
 					    "status.\n", vha->vp_idx);
+					if (!ha_locked)
+						spin_lock_irqsave(
+						    &ha->hardware_lock, flags);
 					qlt_send_busy(vha, atio, SAM_STAT_BUSY);
+					if (!ha_locked)
+						spin_unlock_irqrestore(
+						    &ha->hardware_lock, flags);
 				}
 			}
 		}
@@ -5206,7 +5469,12 @@ static void qlt_24xx_atio_pkt(struct scs
 			break;
 		}
 		ql_dbg(ql_dbg_tgt, vha, 0xe02e, "%s", "IMMED_NOTIFY ATIO");
+
+		if (!ha_locked)
+			spin_lock_irqsave(&ha->hardware_lock, flags);
 		qlt_handle_imm_notify(vha, (struct imm_ntfy_from_isp *)atio);
+		if (!ha_locked)
+			spin_unlock_irqrestore(&ha->hardware_lock, flags);
 		break;
 	}
 
@@ -5217,7 +5485,7 @@ static void qlt_24xx_atio_pkt(struct scs
 		break;
 	}
 
-	tgt->irq_cmd_count--;
+	tgt->atio_irq_cmd_count--;
 }
 
 /* ha->hardware_lock supposed to be held on entry */
@@ -5277,7 +5545,7 @@ static void qlt_response_pkt(struct scsi
 #if 1 /* With TERM EXCHANGE some FC cards refuse to boot */
 				qlt_send_busy(vha, atio, 0);
 #else
-				qlt_send_term_exchange(vha, NULL, atio, 1);
+				qlt_send_term_exchange(vha, NULL, atio, 1, 0);
 #endif
 			} else {
 				if (tgt->tgt_stop) {
@@ -5286,7 +5554,7 @@ static void qlt_response_pkt(struct scsi
 					    "command to target, sending TERM "
 					    "EXCHANGE for rsp\n");
 					qlt_send_term_exchange(vha, NULL,
-					    atio, 1);
+					    atio, 1, 0);
 				} else {
 					ql_dbg(ql_dbg_tgt, vha, 0xe060,
 					    "qla_target(%d): Unable to send "
@@ -5534,12 +5802,16 @@ static struct qla_tgt_sess *qlt_make_loc
 	int rc, global_resets;
 	uint16_t loop_id = 0;
 
+	mutex_lock(&vha->vha_tgt.tgt_mutex);
+
 retry:
 	global_resets =
 	    atomic_read(&vha->vha_tgt.qla_tgt->tgt_global_resets_count);
 
 	rc = qla24xx_get_loop_id(vha, s_id, &loop_id);
 	if (rc != 0) {
+		mutex_unlock(&vha->vha_tgt.tgt_mutex);
+
 		if ((s_id[0] == 0xFF) &&
 		    (s_id[1] == 0xFC)) {
 			/*
@@ -5550,17 +5822,27 @@ retry:
 			    "Unable to find initiator with S_ID %x:%x:%x",
 			    s_id[0], s_id[1], s_id[2]);
 		} else
-			ql_dbg(ql_dbg_tgt_mgt, vha, 0xf071,
+			ql_log(ql_log_info, vha, 0xf071,
 			    "qla_target(%d): Unable to find "
 			    "initiator with S_ID %x:%x:%x",
 			    vha->vp_idx, s_id[0], s_id[1],
 			    s_id[2]);
+
+		if (rc == -ENOENT) {
+			qlt_port_logo_t logo;
+			sid_to_portid(s_id, &logo.id);
+			logo.cmd_count = 1;
+			qlt_send_first_logo(vha, &logo);
+		}
+
 		return NULL;
 	}
 
 	fcport = qlt_get_port_database(vha, loop_id);
-	if (!fcport)
+	if (!fcport) {
+		mutex_unlock(&vha->vha_tgt.tgt_mutex);
 		return NULL;
+	}
 
 	if (global_resets !=
 	    atomic_read(&vha->vha_tgt.qla_tgt->tgt_global_resets_count)) {
@@ -5575,6 +5857,8 @@ retry:
 
 	sess = qlt_create_sess(vha, fcport, true);
 
+	mutex_unlock(&vha->vha_tgt.tgt_mutex);
+
 	kfree(fcport);
 	return sess;
 }
@@ -5585,15 +5869,15 @@ static void qlt_abort_work(struct qla_tg
 	struct scsi_qla_host *vha = tgt->vha;
 	struct qla_hw_data *ha = vha->hw;
 	struct qla_tgt_sess *sess = NULL;
-	unsigned long flags;
+	unsigned long flags = 0, flags2 = 0;
 	uint32_t be_s_id;
 	uint8_t s_id[3];
 	int rc;
 
-	spin_lock_irqsave(&ha->hardware_lock, flags);
+	spin_lock_irqsave(&ha->tgt.sess_lock, flags2);
 
 	if (tgt->tgt_stop)
-		goto out_term;
+		goto out_term2;
 
 	s_id[0] = prm->abts.fcp_hdr_le.s_id[2];
 	s_id[1] = prm->abts.fcp_hdr_le.s_id[1];
@@ -5602,41 +5886,47 @@ static void qlt_abort_work(struct qla_tg
 	sess = ha->tgt.tgt_ops->find_sess_by_s_id(vha,
 	    (unsigned char *)&be_s_id);
 	if (!sess) {
-		spin_unlock_irqrestore(&ha->hardware_lock, flags);
+		spin_unlock_irqrestore(&ha->tgt.sess_lock, flags2);
 
-		mutex_lock(&vha->vha_tgt.tgt_mutex);
 		sess = qlt_make_local_sess(vha, s_id);
 		/* sess has got an extra creation ref */
-		mutex_unlock(&vha->vha_tgt.tgt_mutex);
 
-		spin_lock_irqsave(&ha->hardware_lock, flags);
+		spin_lock_irqsave(&ha->tgt.sess_lock, flags2);
 		if (!sess)
-			goto out_term;
+			goto out_term2;
 	} else {
 		if (sess->deleted == QLA_SESS_DELETION_IN_PROGRESS) {
 			sess = NULL;
-			goto out_term;
+			goto out_term2;
 		}
 
 		kref_get(&sess->se_sess->sess_kref);
 	}
 
+	spin_lock_irqsave(&ha->hardware_lock, flags);
+
 	if (tgt->tgt_stop)
 		goto out_term;
 
 	rc = __qlt_24xx_handle_abts(vha, &prm->abts, sess);
 	if (rc != 0)
 		goto out_term;
+	spin_unlock_irqrestore(&ha->hardware_lock, flags);
 
 	ha->tgt.tgt_ops->put_sess(sess);
-	spin_unlock_irqrestore(&ha->hardware_lock, flags);
+	spin_unlock_irqrestore(&ha->tgt.sess_lock, flags2);
 	return;
 
+out_term2:
+	spin_lock_irqsave(&ha->hardware_lock, flags);
+
 out_term:
 	qlt_24xx_send_abts_resp(vha, &prm->abts, FCP_TMF_REJECTED, false);
+	spin_unlock_irqrestore(&ha->hardware_lock, flags);
+
 	if (sess)
 		ha->tgt.tgt_ops->put_sess(sess);
-	spin_unlock_irqrestore(&ha->hardware_lock, flags);
+	spin_unlock_irqrestore(&ha->tgt.sess_lock, flags2);
 }
 
 static void qlt_tmr_work(struct qla_tgt *tgt,
@@ -5653,7 +5943,7 @@ static void qlt_tmr_work(struct qla_tgt
 	int fn;
 	void *iocb;
 
-	spin_lock_irqsave(&ha->hardware_lock, flags);
+	spin_lock_irqsave(&ha->tgt.sess_lock, flags);
 
 	if (tgt->tgt_stop)
 		goto out_term;
@@ -5661,14 +5951,12 @@ static void qlt_tmr_work(struct qla_tgt
 	s_id = prm->tm_iocb2.u.isp24.fcp_hdr.s_id;
 	sess = ha->tgt.tgt_ops->find_sess_by_s_id(vha, s_id);
 	if (!sess) {
-		spin_unlock_irqrestore(&ha->hardware_lock, flags);
+		spin_unlock_irqrestore(&ha->tgt.sess_lock, flags);
 
-		mutex_lock(&vha->vha_tgt.tgt_mutex);
 		sess = qlt_make_local_sess(vha, s_id);
 		/* sess has got an extra creation ref */
-		mutex_unlock(&vha->vha_tgt.tgt_mutex);
 
-		spin_lock_irqsave(&ha->hardware_lock, flags);
+		spin_lock_irqsave(&ha->tgt.sess_lock, flags);
 		if (!sess)
 			goto out_term;
 	} else {
@@ -5690,14 +5978,14 @@ static void qlt_tmr_work(struct qla_tgt
 		goto out_term;
 
 	ha->tgt.tgt_ops->put_sess(sess);
-	spin_unlock_irqrestore(&ha->hardware_lock, flags);
+	spin_unlock_irqrestore(&ha->tgt.sess_lock, flags);
 	return;
 
 out_term:
-	qlt_send_term_exchange(vha, NULL, &prm->tm_iocb2, 1);
+	qlt_send_term_exchange(vha, NULL, &prm->tm_iocb2, 1, 0);
 	if (sess)
 		ha->tgt.tgt_ops->put_sess(sess);
-	spin_unlock_irqrestore(&ha->hardware_lock, flags);
+	spin_unlock_irqrestore(&ha->tgt.sess_lock, flags);
 }
 
 static void qlt_sess_work_fn(struct work_struct *work)
@@ -6002,6 +6290,7 @@ qlt_enable_vha(struct scsi_qla_host *vha
 	struct qla_tgt *tgt = vha->vha_tgt.qla_tgt;
 	unsigned long flags;
 	scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev);
+	int rspq_ent = QLA83XX_RSPQ_MSIX_ENTRY_NUMBER;
 
 	if (!tgt) {
 		ql_dbg(ql_dbg_tgt, vha, 0xe069,
@@ -6020,6 +6309,17 @@ qlt_enable_vha(struct scsi_qla_host *vha
 		qla24xx_disable_vp(vha);
 		qla24xx_enable_vp(vha);
 	} else {
+		if (ha->msix_entries) {
+			ql_dbg(ql_dbg_tgt, vha, 0xffff,
+			    "%s: host%ld : vector %d cpu %d\n",
+			    __func__, vha->host_no,
+			    ha->msix_entries[rspq_ent].vector,
+			    ha->msix_entries[rspq_ent].cpuid);
+
+			ha->tgt.rspq_vector_cpuid =
+			    ha->msix_entries[rspq_ent].cpuid;
+		}
+
 		set_bit(ISP_ABORT_NEEDED, &base_vha->dpc_flags);
 		qla2xxx_wake_dpc(base_vha);
 		qla2x00_wait_for_hba_online(base_vha);
@@ -6131,7 +6431,7 @@ qlt_init_atio_q_entries(struct scsi_qla_
  * @ha: SCSI driver HA context
  */
 void
-qlt_24xx_process_atio_queue(struct scsi_qla_host *vha)
+qlt_24xx_process_atio_queue(struct scsi_qla_host *vha, uint8_t ha_locked)
 {
 	struct qla_hw_data *ha = vha->hw;
 	struct atio_from_isp *pkt;
@@ -6144,7 +6444,8 @@ qlt_24xx_process_atio_queue(struct scsi_
 		pkt = (struct atio_from_isp *)ha->tgt.atio_ring_ptr;
 		cnt = pkt->u.raw.entry_count;
 
-		qlt_24xx_atio_pkt_all_vps(vha, (struct atio_from_isp *)pkt);
+		qlt_24xx_atio_pkt_all_vps(vha, (struct atio_from_isp *)pkt,
+		    ha_locked);
 
 		for (i = 0; i < cnt; i++) {
 			ha->tgt.atio_ring_index++;
@@ -6265,10 +6566,21 @@ qlt_24xx_config_nvram_stage2(struct scsi
 {
 	struct qla_hw_data *ha = vha->hw;
 
+	if (!QLA_TGT_MODE_ENABLED())
+		return;
+
 	if (ha->tgt.node_name_set) {
 		memcpy(icb->node_name, ha->tgt.tgt_node_name, WWN_SIZE);
 		icb->firmware_options_1 |= cpu_to_le32(BIT_14);
 	}
+
+	/* disable ZIO at start time. */
+	if (!vha->flags.init_done) {
+		uint32_t tmp;
+		tmp = le32_to_cpu(icb->firmware_options_2);
+		tmp &= ~(BIT_3 | BIT_2 | BIT_1 | BIT_0);
+		icb->firmware_options_2 = cpu_to_le32(tmp);
+	}
 }
 
 void
@@ -6359,6 +6671,15 @@ qlt_81xx_config_nvram_stage2(struct scsi
 		memcpy(icb->node_name, ha->tgt.tgt_node_name, WWN_SIZE);
 		icb->firmware_options_1 |= cpu_to_le32(BIT_14);
 	}
+
+	/* disable ZIO at start time. */
+	if (!vha->flags.init_done) {
+		uint32_t tmp;
+		tmp = le32_to_cpu(icb->firmware_options_2);
+		tmp &= ~(BIT_3 | BIT_2 | BIT_1 | BIT_0);
+		icb->firmware_options_2 = cpu_to_le32(tmp);
+	}
+
 }
 
 void
@@ -6428,16 +6749,59 @@ qla83xx_msix_atio_q(int irq, void *dev_i
 	ha = rsp->hw;
 	vha = pci_get_drvdata(ha->pdev);
 
-	spin_lock_irqsave(&ha->hardware_lock, flags);
+	spin_lock_irqsave(&ha->tgt.atio_lock, flags);
 
-	qlt_24xx_process_atio_queue(vha);
-	qla24xx_process_response_queue(vha, rsp);
+	qlt_24xx_process_atio_queue(vha, 0);
 
-	spin_unlock_irqrestore(&ha->hardware_lock, flags);
+	spin_unlock_irqrestore(&ha->tgt.atio_lock, flags);
 
 	return IRQ_HANDLED;
 }
 
+static void
+qlt_handle_abts_recv_work(struct work_struct *work)
+{
+	struct qla_tgt_sess_op *op = container_of(work,
+		struct qla_tgt_sess_op, work);
+	scsi_qla_host_t *vha = op->vha;
+	struct qla_hw_data *ha = vha->hw;
+	unsigned long flags;
+
+	if (qla2x00_reset_active(vha) || (op->chip_reset != ha->chip_reset))
+		return;
+
+	spin_lock_irqsave(&ha->tgt.atio_lock, flags);
+	qlt_24xx_process_atio_queue(vha, 0);
+	spin_unlock_irqrestore(&ha->tgt.atio_lock, flags);
+
+	spin_lock_irqsave(&ha->hardware_lock, flags);
+	qlt_response_pkt_all_vps(vha, (response_t *)&op->atio);
+	spin_unlock_irqrestore(&ha->hardware_lock, flags);
+}
+
+void
+qlt_handle_abts_recv(struct scsi_qla_host *vha, response_t *pkt)
+{
+	struct qla_tgt_sess_op *op;
+
+	op = kzalloc(sizeof(*op), GFP_ATOMIC);
+
+	if (!op) {
+		/* do not reach for ATIO queue here.  This is best effort err
+		 * recovery at this point.
+		 */
+		qlt_response_pkt_all_vps(vha, pkt);
+		return;
+	}
+
+	memcpy(&op->atio, pkt, sizeof(*pkt));
+	op->vha = vha;
+	op->chip_reset = vha->hw->chip_reset;
+	INIT_WORK(&op->work, qlt_handle_abts_recv_work);
+	queue_work(qla_tgt_wq, &op->work);
+	return;
+}
+
 int
 qlt_mem_alloc(struct qla_hw_data *ha)
 {
@@ -6532,13 +6896,25 @@ int __init qlt_init(void)
 		return -ENOMEM;
 	}
 
+	qla_tgt_plogi_cachep = kmem_cache_create("qla_tgt_plogi_cachep",
+						 sizeof(qlt_plogi_ack_t),
+						 __alignof__(qlt_plogi_ack_t),
+						 0, NULL);
+
+	if (!qla_tgt_plogi_cachep) {
+		ql_log(ql_log_fatal, NULL, 0xe06d,
+		    "kmem_cache_create for qla_tgt_plogi_cachep failed\n");
+		ret = -ENOMEM;
+		goto out_mgmt_cmd_cachep;
+	}
+
 	qla_tgt_mgmt_cmd_mempool = mempool_create(25, mempool_alloc_slab,
 	    mempool_free_slab, qla_tgt_mgmt_cmd_cachep);
 	if (!qla_tgt_mgmt_cmd_mempool) {
 		ql_log(ql_log_fatal, NULL, 0xe06e,
 		    "mempool_create for qla_tgt_mgmt_cmd_mempool failed\n");
 		ret = -ENOMEM;
-		goto out_mgmt_cmd_cachep;
+		goto out_plogi_cachep;
 	}
 
 	qla_tgt_wq = alloc_workqueue("qla_tgt_wq", 0, 0);
@@ -6555,6 +6931,8 @@ int __init qlt_init(void)
 
 out_cmd_mempool:
 	mempool_destroy(qla_tgt_mgmt_cmd_mempool);
+out_plogi_cachep:
+	kmem_cache_destroy(qla_tgt_plogi_cachep);
 out_mgmt_cmd_cachep:
 	kmem_cache_destroy(qla_tgt_mgmt_cmd_cachep);
 	return ret;
@@ -6567,5 +6945,6 @@ void qlt_exit(void)
 
 	destroy_workqueue(qla_tgt_wq);
 	mempool_destroy(qla_tgt_mgmt_cmd_mempool);
+	kmem_cache_destroy(qla_tgt_plogi_cachep);
 	kmem_cache_destroy(qla_tgt_mgmt_cmd_cachep);
 }
--- zfcpdump-kernel-4.4.orig/drivers/scsi/qla2xxx/qla_target.h
+++ zfcpdump-kernel-4.4/drivers/scsi/qla2xxx/qla_target.h
@@ -787,7 +787,7 @@ int qla2x00_wait_for_hba_online(struct s
 #define QLA_TGT_STATE_NEED_DATA		1 /* target needs data to continue */
 #define QLA_TGT_STATE_DATA_IN		2 /* Data arrived + target processing */
 #define QLA_TGT_STATE_PROCESSED		3 /* target done processing */
-#define QLA_TGT_STATE_ABORTED		4 /* Command aborted */
+
 
 /* Special handles */
 #define QLA_TGT_NULL_HANDLE	0
@@ -835,6 +835,7 @@ struct qla_tgt {
 	 * HW lock.
 	 */
 	int irq_cmd_count;
+	int atio_irq_cmd_count;
 
 	int datasegs_per_cmd, datasegs_per_cont, sg_tablesize;
 
@@ -883,6 +884,7 @@ struct qla_tgt {
 
 struct qla_tgt_sess_op {
 	struct scsi_qla_host *vha;
+	uint32_t chip_reset;
 	struct atio_from_isp atio;
 	struct work_struct work;
 	struct list_head cmd_list;
@@ -896,6 +898,19 @@ enum qla_sess_deletion {
 	QLA_SESS_DELETION_IN_PROGRESS	= 2,
 };
 
+typedef enum {
+	QLT_PLOGI_LINK_SAME_WWN,
+	QLT_PLOGI_LINK_CONFLICT,
+	QLT_PLOGI_LINK_MAX
+} qlt_plogi_link_t;
+
+typedef struct {
+	struct list_head		list;
+	struct imm_ntfy_from_isp	iocb;
+	port_id_t			id;
+	int				ref_count;
+} qlt_plogi_ack_t;
+
 /*
  * Equivilant to IT Nexus (Initiator-Target)
  */
@@ -907,8 +922,8 @@ struct qla_tgt_sess {
 	unsigned int deleted:2;
 	unsigned int local:1;
 	unsigned int logout_on_delete:1;
-	unsigned int plogi_ack_needed:1;
 	unsigned int keep_nport_handle:1;
+	unsigned int send_els_logo:1;
 
 	unsigned char logout_completed;
 
@@ -925,11 +940,39 @@ struct qla_tgt_sess {
 	uint8_t port_name[WWN_SIZE];
 	struct work_struct free_work;
 
-	union {
-		struct imm_ntfy_from_isp tm_iocb;
-	};
+	qlt_plogi_ack_t *plogi_link[QLT_PLOGI_LINK_MAX];
 };
 
+typedef enum {
+	/*
+	 * BIT_0 - Atio Arrival / schedule to work
+	 * BIT_1 - qlt_do_work
+	 * BIT_2 - qlt_do work failed
+	 * BIT_3 - xfer rdy/tcm_qla2xxx_write_pending
+	 * BIT_4 - read respond/tcm_qla2xx_queue_data_in
+	 * BIT_5 - status respond / tcm_qla2xx_queue_status
+	 * BIT_6 - tcm request to abort/Term exchange.
+	 *	pre_xmit_response->qlt_send_term_exchange
+	 * BIT_7 - SRR received (qlt_handle_srr->qlt_xmit_response)
+	 * BIT_8 - SRR received (qlt_handle_srr->qlt_rdy_to_xfer)
+	 * BIT_9 - SRR received (qla_handle_srr->qlt_send_term_exchange)
+	 * BIT_10 - Data in - hanlde_data->tcm_qla2xxx_handle_data
+
+	 * BIT_12 - good completion - qlt_ctio_do_completion -->free_cmd
+	 * BIT_13 - Bad completion -
+	 *	qlt_ctio_do_completion --> qlt_term_ctio_exchange
+	 * BIT_14 - Back end data received/sent.
+	 * BIT_15 - SRR prepare ctio
+	 * BIT_16 - complete free
+	 * BIT_17 - flush - qlt_abort_cmd_on_host_reset
+	 * BIT_18 - completion w/abort status
+	 * BIT_19 - completion w/unknown status
+	 * BIT_20 - tcm_qla2xxx_free_cmd
+	 */
+	CMD_FLAG_DATA_WORK = BIT_11,
+	CMD_FLAG_DATA_WORK_FREE = BIT_21,
+} cmd_flags_t;
+
 struct qla_tgt_cmd {
 	struct se_cmd se_cmd;
 	struct qla_tgt_sess *sess;
@@ -939,6 +982,7 @@ struct qla_tgt_cmd {
 	/* Sense buffer that will be mapped into outgoing status */
 	unsigned char sense_buffer[TRANSPORT_SENSE_BUFFER];
 
+	spinlock_t cmd_lock;
 	/* to save extra sess dereferences */
 	unsigned int conf_compl_supported:1;
 	unsigned int sg_mapped:1;
@@ -949,6 +993,7 @@ struct qla_tgt_cmd {
 	unsigned int term_exchg:1;
 	unsigned int cmd_sent_to_fw:1;
 	unsigned int cmd_in_wq:1;
+	unsigned int aborted:1;
 
 	struct scatterlist *sg;	/* cmd data buffer SG vector */
 	int sg_cnt;		/* SG segments count */
@@ -972,30 +1017,8 @@ struct qla_tgt_cmd {
 
 	uint64_t jiffies_at_alloc;
 	uint64_t jiffies_at_free;
-	/* BIT_0 - Atio Arrival / schedule to work
-	 * BIT_1 - qlt_do_work
-	 * BIT_2 - qlt_do work failed
-	 * BIT_3 - xfer rdy/tcm_qla2xxx_write_pending
-	 * BIT_4 - read respond/tcm_qla2xx_queue_data_in
-	 * BIT_5 - status respond / tcm_qla2xx_queue_status
-	 * BIT_6 - tcm request to abort/Term exchange.
-	 *	pre_xmit_response->qlt_send_term_exchange
-	 * BIT_7 - SRR received (qlt_handle_srr->qlt_xmit_response)
-	 * BIT_8 - SRR received (qlt_handle_srr->qlt_rdy_to_xfer)
-	 * BIT_9 - SRR received (qla_handle_srr->qlt_send_term_exchange)
-	 * BIT_10 - Data in - hanlde_data->tcm_qla2xxx_handle_data
-	 * BIT_11 - Data actually going to TCM : tcm_qla2xx_handle_data_work
-	 * BIT_12 - good completion - qlt_ctio_do_completion -->free_cmd
-	 * BIT_13 - Bad completion -
-	 *	qlt_ctio_do_completion --> qlt_term_ctio_exchange
-	 * BIT_14 - Back end data received/sent.
-	 * BIT_15 - SRR prepare ctio
-	 * BIT_16 - complete free
-	 * BIT_17 - flush - qlt_abort_cmd_on_host_reset
-	 * BIT_18 - completion w/abort status
-	 * BIT_19 - completion w/unknown status
-	 */
-	uint32_t cmd_flags;
+
+	cmd_flags_t cmd_flags;
 };
 
 struct qla_tgt_sess_work_param {
@@ -1120,13 +1143,21 @@ static inline uint32_t sid_to_key(const
 	return key;
 }
 
+static inline void sid_to_portid(const uint8_t *s_id, port_id_t *p)
+{
+	memset(p, 0, sizeof(*p));
+	p->b.domain = s_id[0];
+	p->b.area = s_id[1];
+	p->b.al_pa = s_id[2];
+}
+
 /*
  * Exported symbols from qla_target.c LLD logic used by qla2xxx code..
  */
 extern void qlt_response_pkt_all_vps(struct scsi_qla_host *, response_t *);
 extern int qlt_rdy_to_xfer(struct qla_tgt_cmd *);
 extern int qlt_xmit_response(struct qla_tgt_cmd *, int, uint8_t);
-extern void qlt_abort_cmd(struct qla_tgt_cmd *);
+extern int qlt_abort_cmd(struct qla_tgt_cmd *);
 extern void qlt_xmit_tm_rsp(struct qla_tgt_mgmt_cmd *);
 extern void qlt_free_mcmd(struct qla_tgt_mgmt_cmd *);
 extern void qlt_free_cmd(struct qla_tgt_cmd *cmd);
@@ -1135,7 +1166,7 @@ extern void qlt_enable_vha(struct scsi_q
 extern void qlt_vport_create(struct scsi_qla_host *, struct qla_hw_data *);
 extern void qlt_rff_id(struct scsi_qla_host *, struct ct_sns_req *);
 extern void qlt_init_atio_q_entries(struct scsi_qla_host *);
-extern void qlt_24xx_process_atio_queue(struct scsi_qla_host *);
+extern void qlt_24xx_process_atio_queue(struct scsi_qla_host *, uint8_t);
 extern void qlt_24xx_config_rings(struct scsi_qla_host *);
 extern void qlt_24xx_config_nvram_stage1(struct scsi_qla_host *,
 	struct nvram_24xx *);
--- zfcpdump-kernel-4.4.orig/drivers/scsi/qla2xxx/qla_tmpl.c
+++ zfcpdump-kernel-4.4/drivers/scsi/qla2xxx/qla_tmpl.c
@@ -395,6 +395,10 @@ qla27xx_fwdt_entry_t263(struct scsi_qla_
 	if (ent->t263.queue_type == T263_QUEUE_TYPE_REQ) {
 		for (i = 0; i < vha->hw->max_req_queues; i++) {
 			struct req_que *req = vha->hw->req_q_map[i];
+
+			if (!test_bit(i, vha->hw->req_qid_map))
+				continue;
+
 			if (req || !buf) {
 				length = req ?
 				    req->length : REQUEST_ENTRY_CNT_24XX;
@@ -408,6 +412,10 @@ qla27xx_fwdt_entry_t263(struct scsi_qla_
 	} else if (ent->t263.queue_type == T263_QUEUE_TYPE_RSP) {
 		for (i = 0; i < vha->hw->max_rsp_queues; i++) {
 			struct rsp_que *rsp = vha->hw->rsp_q_map[i];
+
+			if (!test_bit(i, vha->hw->rsp_qid_map))
+				continue;
+
 			if (rsp || !buf) {
 				length = rsp ?
 				    rsp->length : RESPONSE_ENTRY_CNT_MQ;
@@ -634,6 +642,10 @@ qla27xx_fwdt_entry_t274(struct scsi_qla_
 	if (ent->t274.queue_type == T274_QUEUE_TYPE_REQ_SHAD) {
 		for (i = 0; i < vha->hw->max_req_queues; i++) {
 			struct req_que *req = vha->hw->req_q_map[i];
+
+			if (!test_bit(i, vha->hw->req_qid_map))
+				continue;
+
 			if (req || !buf) {
 				qla27xx_insert16(i, buf, len);
 				qla27xx_insert16(1, buf, len);
@@ -645,6 +657,10 @@ qla27xx_fwdt_entry_t274(struct scsi_qla_
 	} else if (ent->t274.queue_type == T274_QUEUE_TYPE_RSP_SHAD) {
 		for (i = 0; i < vha->hw->max_rsp_queues; i++) {
 			struct rsp_que *rsp = vha->hw->rsp_q_map[i];
+
+			if (!test_bit(i, vha->hw->rsp_qid_map))
+				continue;
+
 			if (rsp || !buf) {
 				qla27xx_insert16(i, buf, len);
 				qla27xx_insert16(1, buf, len);
--- zfcpdump-kernel-4.4.orig/drivers/scsi/qla2xxx/tcm_qla2xxx.c
+++ zfcpdump-kernel-4.4/drivers/scsi/qla2xxx/tcm_qla2xxx.c
@@ -284,6 +284,7 @@ static void tcm_qla2xxx_complete_free(st
 
 	WARN_ON(cmd->cmd_flags &  BIT_16);
 
+	cmd->vha->tgt_counters.qla_core_ret_sta_ctio++;
 	cmd->cmd_flags |= BIT_16;
 	transport_generic_free_cmd(&cmd->se_cmd, 0);
 }
@@ -295,9 +296,14 @@ static void tcm_qla2xxx_complete_free(st
  */
 static void tcm_qla2xxx_free_cmd(struct qla_tgt_cmd *cmd)
 {
+	cmd->vha->tgt_counters.core_qla_free_cmd++;
 	cmd->cmd_in_wq = 1;
+
+	BUG_ON(cmd->cmd_flags & BIT_20);
+	cmd->cmd_flags |= BIT_20;
+
 	INIT_WORK(&cmd->work, tcm_qla2xxx_complete_free);
-	queue_work(tcm_qla2xxx_free_wq, &cmd->work);
+	queue_work_on(smp_processor_id(), tcm_qla2xxx_free_wq, &cmd->work);
 }
 
 /*
@@ -342,9 +348,9 @@ static int tcm_qla2xxx_shutdown_session(
 	BUG_ON(!sess);
 	vha = sess->vha;
 
-	spin_lock_irqsave(&vha->hw->hardware_lock, flags);
+	spin_lock_irqsave(&vha->hw->tgt.sess_lock, flags);
 	target_sess_cmd_list_set_waiting(se_sess);
-	spin_unlock_irqrestore(&vha->hw->hardware_lock, flags);
+	spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags);
 
 	return 1;
 }
@@ -358,9 +364,9 @@ static void tcm_qla2xxx_close_session(st
 	BUG_ON(!sess);
 	vha = sess->vha;
 
-	spin_lock_irqsave(&vha->hw->hardware_lock, flags);
+	spin_lock_irqsave(&vha->hw->tgt.sess_lock, flags);
 	qlt_unreg_sess(sess);
-	spin_unlock_irqrestore(&vha->hw->hardware_lock, flags);
+	spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags);
 }
 
 static u32 tcm_qla2xxx_sess_get_index(struct se_session *se_sess)
@@ -372,6 +378,20 @@ static int tcm_qla2xxx_write_pending(str
 {
 	struct qla_tgt_cmd *cmd = container_of(se_cmd,
 				struct qla_tgt_cmd, se_cmd);
+
+	if (cmd->aborted) {
+		/* Cmd can loop during Q-full.  tcm_qla2xxx_aborted_task
+		 * can get ahead of this cmd. tcm_qla2xxx_aborted_task
+		 * already kick start the free.
+		 */
+		pr_debug("write_pending aborted cmd[%p] refcount %d "
+			"transport_state %x, t_state %x, se_cmd_flags %x\n",
+			cmd,cmd->se_cmd.cmd_kref.refcount.counter,
+			cmd->se_cmd.transport_state,
+			cmd->se_cmd.t_state,
+			cmd->se_cmd.se_cmd_flags);
+		return 0;
+	}
 	cmd->cmd_flags |= BIT_3;
 	cmd->bufflen = se_cmd->data_length;
 	cmd->dma_data_direction = target_reverse_dma_direction(se_cmd);
@@ -403,7 +423,7 @@ static int tcm_qla2xxx_write_pending_sta
 	    se_cmd->t_state == TRANSPORT_COMPLETE_QF_WP) {
 		spin_unlock_irqrestore(&se_cmd->t_state_lock, flags);
 		wait_for_completion_timeout(&se_cmd->t_transport_stop_comp,
-					    3 * HZ);
+						50);
 		return 0;
 	}
 	spin_unlock_irqrestore(&se_cmd->t_state_lock, flags);
@@ -442,6 +462,9 @@ static int tcm_qla2xxx_handle_cmd(scsi_q
 	if (bidi)
 		flags |= TARGET_SCF_BIDI_OP;
 
+	if (se_cmd->cpuid != WORK_CPU_UNBOUND)
+		flags |= TARGET_SCF_USE_CPUID;
+
 	sess = cmd->sess;
 	if (!sess) {
 		pr_err("Unable to locate struct qla_tgt_sess from qla_tgt_cmd\n");
@@ -454,6 +477,7 @@ static int tcm_qla2xxx_handle_cmd(scsi_q
 		return -EINVAL;
 	}
 
+	cmd->vha->tgt_counters.qla_core_sbt_cmd++;
 	return target_submit_cmd(se_cmd, se_sess, cdb, &cmd->sense_buffer[0],
 				cmd->unpacked_lun, data_length, fcp_task_attr,
 				data_dir, flags);
@@ -462,13 +486,26 @@ static int tcm_qla2xxx_handle_cmd(scsi_q
 static void tcm_qla2xxx_handle_data_work(struct work_struct *work)
 {
 	struct qla_tgt_cmd *cmd = container_of(work, struct qla_tgt_cmd, work);
+	unsigned long flags;
 
 	/*
 	 * Ensure that the complete FCP WRITE payload has been received.
 	 * Otherwise return an exception via CHECK_CONDITION status.
 	 */
 	cmd->cmd_in_wq = 0;
-	cmd->cmd_flags |= BIT_11;
+
+	spin_lock_irqsave(&cmd->cmd_lock, flags);
+	cmd->cmd_flags |= CMD_FLAG_DATA_WORK;
+	if (cmd->aborted) {
+		cmd->cmd_flags |= CMD_FLAG_DATA_WORK_FREE;
+		spin_unlock_irqrestore(&cmd->cmd_lock, flags);
+
+		tcm_qla2xxx_free_cmd(cmd);
+		return;
+	}
+	spin_unlock_irqrestore(&cmd->cmd_lock, flags);
+
+	cmd->vha->tgt_counters.qla_core_ret_ctio++;
 	if (!cmd->write_data_transferred) {
 		/*
 		 * Check if se_cmd has already been aborted via LUN_RESET, and
@@ -500,7 +537,7 @@ static void tcm_qla2xxx_handle_data(stru
 	cmd->cmd_flags |= BIT_10;
 	cmd->cmd_in_wq = 1;
 	INIT_WORK(&cmd->work, tcm_qla2xxx_handle_data_work);
-	queue_work(tcm_qla2xxx_free_wq, &cmd->work);
+	queue_work_on(smp_processor_id(), tcm_qla2xxx_free_wq, &cmd->work);
 }
 
 static void tcm_qla2xxx_handle_dif_work(struct work_struct *work)
@@ -542,6 +579,20 @@ static int tcm_qla2xxx_queue_data_in(str
 	struct qla_tgt_cmd *cmd = container_of(se_cmd,
 				struct qla_tgt_cmd, se_cmd);
 
+	if (cmd->aborted) {
+		/* Cmd can loop during Q-full.  tcm_qla2xxx_aborted_task
+		 * can get ahead of this cmd. tcm_qla2xxx_aborted_task
+		 * already kick start the free.
+		 */
+		pr_debug("queue_data_in aborted cmd[%p] refcount %d "
+			"transport_state %x, t_state %x, se_cmd_flags %x\n",
+			cmd,cmd->se_cmd.cmd_kref.refcount.counter,
+			cmd->se_cmd.transport_state,
+			cmd->se_cmd.t_state,
+			cmd->se_cmd.se_cmd_flags);
+		return 0;
+	}
+
 	cmd->cmd_flags |= BIT_4;
 	cmd->bufflen = se_cmd->data_length;
 	cmd->dma_data_direction = target_reverse_dma_direction(se_cmd);
@@ -633,17 +684,40 @@ static void tcm_qla2xxx_queue_tm_rsp(str
 	qlt_xmit_tm_rsp(mcmd);
 }
 
+
+#define DATA_WORK_NOT_FREE(_flags) \
+	(( _flags & (CMD_FLAG_DATA_WORK|CMD_FLAG_DATA_WORK_FREE)) == \
+	 CMD_FLAG_DATA_WORK)
 static void tcm_qla2xxx_aborted_task(struct se_cmd *se_cmd)
 {
 	struct qla_tgt_cmd *cmd = container_of(se_cmd,
 				struct qla_tgt_cmd, se_cmd);
-	qlt_abort_cmd(cmd);
+	unsigned long flags;
+
+	if (qlt_abort_cmd(cmd))
+		return;
+
+	spin_lock_irqsave(&cmd->cmd_lock, flags);
+	if ((cmd->state == QLA_TGT_STATE_NEW)||
+		((cmd->state == QLA_TGT_STATE_DATA_IN) &&
+		 DATA_WORK_NOT_FREE(cmd->cmd_flags)) ) {
+
+		cmd->cmd_flags |= CMD_FLAG_DATA_WORK_FREE;
+		spin_unlock_irqrestore(&cmd->cmd_lock, flags);
+		/* Cmd have not reached firmware.
+		 * Use this trigger to free it. */
+		tcm_qla2xxx_free_cmd(cmd);
+		return;
+	}
+	spin_unlock_irqrestore(&cmd->cmd_lock, flags);
+	return;
+
 }
 
 static void tcm_qla2xxx_clear_sess_lookup(struct tcm_qla2xxx_lport *,
 			struct tcm_qla2xxx_nacl *, struct qla_tgt_sess *);
 /*
- * Expected to be called with struct qla_hw_data->hardware_lock held
+ * Expected to be called with struct qla_hw_data->tgt.sess_lock held
  */
 static void tcm_qla2xxx_clear_nacl_from_fcport_map(struct qla_tgt_sess *sess)
 {
@@ -697,13 +771,13 @@ static void tcm_qla2xxx_put_sess(struct
 	if (!sess)
 		return;
 
-	assert_spin_locked(&sess->vha->hw->hardware_lock);
+	assert_spin_locked(&sess->vha->hw->tgt.sess_lock);
 	kref_put(&sess->se_sess->sess_kref, tcm_qla2xxx_release_session);
 }
 
 static void tcm_qla2xxx_shutdown_sess(struct qla_tgt_sess *sess)
 {
-	assert_spin_locked(&sess->vha->hw->hardware_lock);
+	assert_spin_locked(&sess->vha->hw->tgt.sess_lock);
 	target_sess_cmd_list_set_waiting(sess->se_sess);
 }
 
@@ -1077,7 +1151,7 @@ static struct se_portal_group *tcm_qla2x
 }
 
 /*
- * Expected to be called with struct qla_hw_data->hardware_lock held
+ * Expected to be called with struct qla_hw_data->tgt.sess_lock held
  */
 static struct qla_tgt_sess *tcm_qla2xxx_find_sess_by_s_id(
 	scsi_qla_host_t *vha,
@@ -1116,7 +1190,7 @@ static struct qla_tgt_sess *tcm_qla2xxx_
 }
 
 /*
- * Expected to be called with struct qla_hw_data->hardware_lock held
+ * Expected to be called with struct qla_hw_data->tgt.sess_lock held
  */
 static void tcm_qla2xxx_set_sess_by_s_id(
 	struct tcm_qla2xxx_lport *lport,
@@ -1182,7 +1256,7 @@ static void tcm_qla2xxx_set_sess_by_s_id
 }
 
 /*
- * Expected to be called with struct qla_hw_data->hardware_lock held
+ * Expected to be called with struct qla_hw_data->tgt.sess_lock held
  */
 static struct qla_tgt_sess *tcm_qla2xxx_find_sess_by_loop_id(
 	scsi_qla_host_t *vha,
@@ -1221,7 +1295,7 @@ static struct qla_tgt_sess *tcm_qla2xxx_
 }
 
 /*
- * Expected to be called with struct qla_hw_data->hardware_lock held
+ * Expected to be called with struct qla_hw_data->tgt.sess_lock held
  */
 static void tcm_qla2xxx_set_sess_by_loop_id(
 	struct tcm_qla2xxx_lport *lport,
@@ -1285,7 +1359,7 @@ static void tcm_qla2xxx_set_sess_by_loop
 }
 
 /*
- * Should always be called with qla_hw_data->hardware_lock held.
+ * Should always be called with qla_hw_data->tgt.sess_lock held.
  */
 static void tcm_qla2xxx_clear_sess_lookup(struct tcm_qla2xxx_lport *lport,
 		struct tcm_qla2xxx_nacl *nacl, struct qla_tgt_sess *sess)
@@ -1353,7 +1427,7 @@ static int tcm_qla2xxx_check_initiator_n
 	struct qla_tgt_sess *sess = qla_tgt_sess;
 	unsigned char port_name[36];
 	unsigned long flags;
-	int num_tags = (ha->fw_xcb_count) ? ha->fw_xcb_count :
+	int num_tags = (ha->cur_fw_xcb_count) ? ha->cur_fw_xcb_count :
 		       TCM_QLA2XXX_DEFAULT_TAGS;
 
 	lport = vha->vha_tgt.target_lport_ptr;
@@ -1401,12 +1475,12 @@ static int tcm_qla2xxx_check_initiator_n
 	 * And now setup the new se_nacl and session pointers into our HW lport
 	 * mappings for fabric S_ID and LOOP_ID.
 	 */
-	spin_lock_irqsave(&ha->hardware_lock, flags);
+	spin_lock_irqsave(&ha->tgt.sess_lock, flags);
 	tcm_qla2xxx_set_sess_by_s_id(lport, se_nacl, nacl, se_sess,
 			qla_tgt_sess, s_id);
 	tcm_qla2xxx_set_sess_by_loop_id(lport, se_nacl, nacl, se_sess,
 			qla_tgt_sess, loop_id);
-	spin_unlock_irqrestore(&ha->hardware_lock, flags);
+	spin_unlock_irqrestore(&ha->tgt.sess_lock, flags);
 	/*
 	 * Finally register the new FC Nexus with TCM
 	 */
--- zfcpdump-kernel-4.4.orig/drivers/scsi/qla4xxx/ql4_isr.c
+++ zfcpdump-kernel-4.4/drivers/scsi/qla4xxx/ql4_isr.c
@@ -385,9 +385,9 @@ static void qla4xxx_passthru_status_entr
 
 	cls_conn = ddb_entry->conn;
 	conn = cls_conn->dd_data;
-	spin_lock(&conn->session->back_lock);
+	spin_lock(&conn->session->lock);
 	task = iscsi_itt_to_task(conn, itt);
-	spin_unlock(&conn->session->back_lock);
+	spin_unlock(&conn->session->lock);
 
 	if (task == NULL) {
 		ql4_printk(KERN_ERR, ha, "%s: Task is NULL\n", __func__);
--- zfcpdump-kernel-4.4.orig/drivers/scsi/scsi_common.c
+++ zfcpdump-kernel-4.4/drivers/scsi/scsi_common.c
@@ -278,8 +278,16 @@ int scsi_set_sense_information(u8 *buf,
 		ucp[3] = 0;
 		put_unaligned_be64(info, &ucp[4]);
 	} else if ((buf[0] & 0x7f) == 0x70) {
-		buf[0] |= 0x80;
-		put_unaligned_be64(info, &buf[3]);
+		/*
+		 * Only set the 'VALID' bit if we can represent the value
+		 * correctly; otherwise just fill out the lower bytes and
+		 * clear the 'VALID' flag.
+		 */
+		if (info <= 0xffffffffUL)
+			buf[0] |= 0x80;
+		else
+			buf[0] &= 0x7f;
+		put_unaligned_be32((u32)info, &buf[3]);
 	}
 
 	return 0;
--- zfcpdump-kernel-4.4.orig/drivers/scsi/scsi_devinfo.c
+++ zfcpdump-kernel-4.4/drivers/scsi/scsi_devinfo.c
@@ -205,6 +205,7 @@ static struct {
 	{"Intel", "Multi-Flex", NULL, BLIST_NO_RSOC},
 	{"iRiver", "iFP Mass Driver", NULL, BLIST_NOT_LOCKABLE | BLIST_INQUIRY_36},
 	{"LASOUND", "CDX7405", "3.10", BLIST_MAX5LUN | BLIST_SINGLELUN},
+	{"Marvell", "Console", NULL, BLIST_SKIP_VPD_PAGES},
 	{"MATSHITA", "PD-1", NULL, BLIST_FORCELUN | BLIST_SINGLELUN},
 	{"MATSHITA", "DMC-LC5", NULL, BLIST_NOT_LOCKABLE | BLIST_INQUIRY_36},
 	{"MATSHITA", "DMC-LC40", NULL, BLIST_NOT_LOCKABLE | BLIST_INQUIRY_36},
@@ -218,6 +219,8 @@ static struct {
 	{"NAKAMICH", "MJ-5.16S", NULL, BLIST_FORCELUN | BLIST_SINGLELUN},
 	{"NEC", "PD-1 ODX654P", NULL, BLIST_FORCELUN | BLIST_SINGLELUN},
 	{"NEC", "iStorage", NULL, BLIST_REPORTLUN2},
+	{"NETAPP", "LUN C-Mode", NULL, BLIST_SYNC_ALUA},
+	{"NETAPP", "INF-01-00", NULL, BLIST_SYNC_ALUA},
 	{"NRC", "MBR-7", NULL, BLIST_FORCELUN | BLIST_SINGLELUN},
 	{"NRC", "MBR-7.4", NULL, BLIST_FORCELUN | BLIST_SINGLELUN},
 	{"PIONEER", "CD-ROM DRM-600", NULL, BLIST_FORCELUN | BLIST_SINGLELUN},
@@ -226,7 +229,9 @@ static struct {
 	{"PIONEER", "CD-ROM DRM-624X", NULL, BLIST_FORCELUN | BLIST_SINGLELUN},
 	{"Promise", "VTrak E610f", NULL, BLIST_SPARSELUN | BLIST_NO_RSOC},
 	{"Promise", "", NULL, BLIST_SPARSELUN},
+	{"QEMU", "QEMU CD-ROM", NULL, BLIST_SKIP_VPD_PAGES},
 	{"QNAP", "iSCSI Storage", NULL, BLIST_MAX_1024},
+	{"SYNOLOGY", "iSCSI Storage", NULL, BLIST_MAX_1024},
 	{"QUANTUM", "XP34301", "1071", BLIST_NOTQ},
 	{"REGAL", "CDC-4X", NULL, BLIST_MAX5LUN | BLIST_SINGLELUN},
 	{"SanDisk", "ImageMate CF-SD1", NULL, BLIST_FORCELUN},
@@ -423,7 +428,7 @@ static struct scsi_dev_info_list *scsi_d
 	 * here, and we don't know what device it is
 	 * trying to work with, leave it as-is.
 	 */
-	vmax = 8;	/* max length of vendor */
+	vmax = sizeof(devinfo->vendor);
 	vskip = vendor;
 	while (vmax > 0 && *vskip == ' ') {
 		vmax--;
@@ -433,7 +438,7 @@ static struct scsi_dev_info_list *scsi_d
 	while (vmax > 0 && vskip[vmax - 1] == ' ')
 		--vmax;
 
-	mmax = 16;	/* max length of model */
+	mmax = sizeof(devinfo->model);
 	mskip = model;
 	while (mmax > 0 && *mskip == ' ') {
 		mmax--;
@@ -449,10 +454,12 @@ static struct scsi_dev_info_list *scsi_d
 			 * Behave like the older version of get_device_flags.
 			 */
 			if (memcmp(devinfo->vendor, vskip, vmax) ||
-					devinfo->vendor[vmax])
+					(vmax < sizeof(devinfo->vendor) &&
+						devinfo->vendor[vmax]))
 				continue;
 			if (memcmp(devinfo->model, mskip, mmax) ||
-					devinfo->model[mmax])
+					(mmax < sizeof(devinfo->model) &&
+						devinfo->model[mmax]))
 				continue;
 			return devinfo;
 		} else {
--- zfcpdump-kernel-4.4.orig/drivers/scsi/scsi_error.c
+++ zfcpdump-kernel-4.4/drivers/scsi/scsi_error.c
@@ -1127,7 +1127,6 @@ static int scsi_eh_action(struct scsi_cm
  */
 void scsi_eh_finish_cmd(struct scsi_cmnd *scmd, struct list_head *done_q)
 {
-	scmd->device->host->host_failed--;
 	scmd->eh_eflags = 0;
 	list_move_tail(&scmd->eh_entry, done_q);
 }
@@ -2226,6 +2225,9 @@ int scsi_error_handler(void *data)
 		else
 			scsi_unjam_host(shost);
 
+		/* All scmds have been handled */
+		shost->host_failed = 0;
+
 		/*
 		 * Note - if the above fails completely, the action is to take
 		 * individual devices offline and flush the queue of any
--- zfcpdump-kernel-4.4.orig/drivers/scsi/scsi_lib.c
+++ zfcpdump-kernel-4.4/drivers/scsi/scsi_lib.c
@@ -23,6 +23,7 @@
 #include <linux/scatterlist.h>
 #include <linux/blk-mq.h>
 #include <linux/ratelimit.h>
+#include <asm/unaligned.h>
 
 #include <scsi/scsi.h>
 #include <scsi/scsi_cmnd.h>
@@ -910,9 +911,12 @@ void scsi_io_completion(struct scsi_cmnd
 	}
 
 	/*
-	 * If we finished all bytes in the request we are done now.
+	 * special case: failed zero length commands always need to
+	 * drop down into the retry code. Otherwise, if we finished
+	 * all bytes in the request we are done now.
 	 */
-	if (!scsi_end_request(req, error, good_bytes, 0))
+	if (!(blk_rq_bytes(req) == 0 && error) &&
+	    !scsi_end_request(req, error, good_bytes, 0))
 		return;
 
 	/*
@@ -3154,3 +3158,190 @@ void sdev_enable_disk_events(struct scsi
 	atomic_dec(&sdev->disk_events_disable_depth);
 }
 EXPORT_SYMBOL(sdev_enable_disk_events);
+
+/**
+ * scsi_vpd_lun_id - return a unique device identification
+ * @sdev: SCSI device
+ * @id:   buffer for the identification
+ * @id_len:  length of the buffer
+ *
+ * Copies a unique device identification into @id based
+ * on the information in the VPD page 0x83 of the device.
+ * The string will be formatted as a SCSI name string.
+ *
+ * Returns the length of the identification or error on failure.
+ * If the identifier is longer than the supplied buffer the actual
+ * identifier length is returned and the buffer is not zero-padded.
+ */
+int scsi_vpd_lun_id(struct scsi_device *sdev, char *id, size_t id_len)
+{
+	u8 cur_id_type = 0xff;
+	u8 cur_id_size = 0;
+	unsigned char *d, *cur_id_str;
+	unsigned char __rcu *vpd_pg83;
+	int id_size = -EINVAL;
+
+	rcu_read_lock();
+	vpd_pg83 = rcu_dereference(sdev->vpd_pg83);
+	if (!vpd_pg83) {
+		rcu_read_unlock();
+		return -ENXIO;
+	}
+
+	/*
+	 * Look for the correct descriptor.
+	 * Order of preference for lun descriptor:
+	 * - SCSI name string
+	 * - NAA IEEE Registered Extended
+	 * - EUI-64 based 16-byte
+	 * - EUI-64 based 12-byte
+	 * - NAA IEEE Registered
+	 * - NAA IEEE Extended
+	 * as longer descriptors reduce the likelyhood
+	 * of identification clashes.
+	 */
+
+	/* The id string must be at least 20 bytes + terminating NULL byte */
+	if (id_len < 21) {
+		rcu_read_unlock();
+		return -EINVAL;
+	}
+
+	memset(id, 0, id_len);
+	d = vpd_pg83 + 4;
+	while (d < vpd_pg83 + sdev->vpd_pg83_len) {
+		/* Skip designators not referring to the LUN */
+		if ((d[1] & 0x30) != 0x00)
+			goto next_desig;
+
+		switch (d[1] & 0xf) {
+		case 0x2:
+			/* EUI-64 */
+			if (cur_id_size > d[3])
+				break;
+			/* Prefer NAA IEEE Registered Extended */
+			if (cur_id_type == 0x3 &&
+			    cur_id_size == d[3])
+				break;
+			cur_id_size = d[3];
+			cur_id_str = d + 4;
+			cur_id_type = d[1] & 0xf;
+			switch (cur_id_size) {
+			case 8:
+				id_size = snprintf(id, id_len,
+						   "eui.%8phN",
+						   cur_id_str);
+				break;
+			case 12:
+				id_size = snprintf(id, id_len,
+						   "eui.%12phN",
+						   cur_id_str);
+				break;
+			case 16:
+				id_size = snprintf(id, id_len,
+						   "eui.%16phN",
+						   cur_id_str);
+				break;
+			default:
+				cur_id_size = 0;
+				break;
+			}
+			break;
+		case 0x3:
+			/* NAA */
+			if (cur_id_size > d[3])
+				break;
+			cur_id_size = d[3];
+			cur_id_str = d + 4;
+			cur_id_type = d[1] & 0xf;
+			switch (cur_id_size) {
+			case 8:
+				id_size = snprintf(id, id_len,
+						   "naa.%8phN",
+						   cur_id_str);
+				break;
+			case 16:
+				id_size = snprintf(id, id_len,
+						   "naa.%16phN",
+						   cur_id_str);
+				break;
+			default:
+				cur_id_size = 0;
+				break;
+			}
+			break;
+		case 0x8:
+			/* SCSI name string */
+			if (cur_id_size + 4 > d[3])
+				break;
+			/* Prefer others for truncated descriptor */
+			if (cur_id_size && d[3] > id_len)
+				break;
+			cur_id_size = id_size = d[3];
+			cur_id_str = d + 4;
+			cur_id_type = d[1] & 0xf;
+			if (cur_id_size >= id_len)
+				cur_id_size = id_len - 1;
+			memcpy(id, cur_id_str, cur_id_size);
+			/* Decrease priority for truncated descriptor */
+			if (cur_id_size != id_size)
+				cur_id_size = 6;
+			break;
+		default:
+			break;
+		}
+next_desig:
+		d += d[3] + 4;
+	}
+	rcu_read_unlock();
+
+	return id_size;
+}
+EXPORT_SYMBOL(scsi_vpd_lun_id);
+
+/*
+ * scsi_vpd_tpg_id - return a target port group identifier
+ * @sdev: SCSI device
+ *
+ * Returns the Target Port Group identifier from the information
+ * froom VPD page 0x83 of the device.
+ *
+ * Returns the identifier or error on failure.
+ */
+int scsi_vpd_tpg_id(struct scsi_device *sdev, int *rel_id)
+{
+	unsigned char *d;
+	unsigned char __rcu *vpd_pg83;
+	int group_id = -EAGAIN, rel_port = -1;
+
+	rcu_read_lock();
+	vpd_pg83 = rcu_dereference(sdev->vpd_pg83);
+	if (!vpd_pg83) {
+		rcu_read_unlock();
+		return -ENXIO;
+	}
+
+	d = sdev->vpd_pg83 + 4;
+	while (d < sdev->vpd_pg83 + sdev->vpd_pg83_len) {
+		switch (d[1] & 0xf) {
+		case 0x4:
+			/* Relative target port */
+			rel_port = get_unaligned_be16(&d[6]);
+			break;
+		case 0x5:
+			/* Target port group */
+			group_id = get_unaligned_be16(&d[6]);
+			break;
+		default:
+			break;
+		}
+		d += d[3] + 4;
+	}
+	rcu_read_unlock();
+
+	if (group_id >= 0 && rel_id && rel_port != -1)
+		*rel_id = rel_port;
+
+	return group_id;
+}
+EXPORT_SYMBOL(scsi_vpd_tpg_id);
--- zfcpdump-kernel-4.4.orig/drivers/scsi/scsi_scan.c
+++ zfcpdump-kernel-4.4/drivers/scsi/scsi_scan.c
@@ -314,6 +314,7 @@ static void scsi_target_destroy(struct s
 	struct Scsi_Host *shost = dev_to_shost(dev->parent);
 	unsigned long flags;
 
+	BUG_ON(starget->state == STARGET_DEL);
 	starget->state = STARGET_DEL;
 	transport_destroy_device(dev);
 	spin_lock_irqsave(shost->host_lock, flags);
@@ -961,6 +962,9 @@ static int scsi_add_lun(struct scsi_devi
 	if (*bflags & BLIST_NO_DIF)
 		sdev->no_dif = 1;
 
+	if (*bflags & BLIST_SYNC_ALUA)
+		sdev->synchronous_alua = 1;
+
 	sdev->eh_timeout = SCSI_DEFAULT_EH_TIMEOUT;
 
 	if (*bflags & BLIST_TRY_VPD_PAGES)
--- zfcpdump-kernel-4.4.orig/drivers/scsi/scsi_sysfs.c
+++ zfcpdump-kernel-4.4/drivers/scsi/scsi_sysfs.c
@@ -1058,11 +1058,12 @@ int scsi_sysfs_add_sdev(struct scsi_devi
 	}
 
 	error = scsi_dh_add_device(sdev);
-	if (error) {
+	if (error)
+		/*
+		 * device_handler is optional, so any error can be ignored
+		 */
 		sdev_printk(KERN_INFO, sdev,
 				"failed to add device handler: %d\n", error);
-		return error;
-	}
 
 	device_enable_async_suspend(&sdev->sdev_dev);
 	error = device_add(&sdev->sdev_dev);
@@ -1198,10 +1199,12 @@ void scsi_remove_target(struct device *d
 restart:
 	spin_lock_irqsave(shost->host_lock, flags);
 	list_for_each_entry(starget, &shost->__targets, siblings) {
-		if (starget->state == STARGET_DEL)
+		if (starget->state == STARGET_DEL ||
+		    starget->state == STARGET_REMOVE)
 			continue;
 		if (starget->dev.parent == dev || &starget->dev == dev) {
 			kref_get(&starget->reap_ref);
+			starget->state = STARGET_REMOVE;
 			spin_unlock_irqrestore(shost->host_lock, flags);
 			__scsi_remove_target(starget);
 			scsi_target_reap(starget);
--- zfcpdump-kernel-4.4.orig/drivers/scsi/sd.c
+++ zfcpdump-kernel-4.4/drivers/scsi/sd.c
@@ -648,7 +648,7 @@ static void sd_config_discard(struct scs
 	 */
 	if (sdkp->lbprz) {
 		q->limits.discard_alignment = 0;
-		q->limits.discard_granularity = 1;
+		q->limits.discard_granularity = logical_block_size;
 	} else {
 		q->limits.discard_alignment = sdkp->unmap_alignment *
 			logical_block_size;
@@ -1275,18 +1275,19 @@ static int sd_getgeo(struct block_device
 	struct scsi_disk *sdkp = scsi_disk(bdev->bd_disk);
 	struct scsi_device *sdp = sdkp->device;
 	struct Scsi_Host *host = sdp->host;
+	sector_t capacity = logical_to_sectors(sdp, sdkp->capacity);
 	int diskinfo[4];
 
 	/* default to most commonly used values */
-        diskinfo[0] = 0x40;	/* 1 << 6 */
-       	diskinfo[1] = 0x20;	/* 1 << 5 */
-       	diskinfo[2] = sdkp->capacity >> 11;
-	
+	diskinfo[0] = 0x40;	/* 1 << 6 */
+	diskinfo[1] = 0x20;	/* 1 << 5 */
+	diskinfo[2] = capacity >> 11;
+
 	/* override with calculated, extended default, or driver values */
 	if (host->hostt->bios_param)
-		host->hostt->bios_param(sdp, bdev, sdkp->capacity, diskinfo);
+		host->hostt->bios_param(sdp, bdev, capacity, diskinfo);
 	else
-		scsicam_bios_param(bdev, sdkp->capacity, diskinfo);
+		scsicam_bios_param(bdev, capacity, diskinfo);
 
 	geo->heads = diskinfo[0];
 	geo->sectors = diskinfo[1];
@@ -2337,14 +2338,6 @@ got_data:
 	if (sdkp->capacity > 0xffffffff)
 		sdp->use_16_for_rw = 1;
 
-	/* Rescale capacity to 512-byte units */
-	if (sector_size == 4096)
-		sdkp->capacity <<= 3;
-	else if (sector_size == 2048)
-		sdkp->capacity <<= 2;
-	else if (sector_size == 1024)
-		sdkp->capacity <<= 1;
-
 	blk_queue_physical_block_size(sdp->request_queue,
 				      sdkp->physical_block_size);
 	sdkp->device->sector_size = sector_size;
@@ -2812,11 +2805,6 @@ static int sd_try_extended_inquiry(struc
 	return 0;
 }
 
-static inline u32 logical_to_sectors(struct scsi_device *sdev, u32 blocks)
-{
-	return blocks << (ilog2(sdev->sector_size) - 9);
-}
-
 /**
  *	sd_revalidate_disk - called the first time a new disk is seen,
  *	performs disk spin up, read_capacity, etc.
@@ -2893,14 +2881,14 @@ static int sd_revalidate_disk(struct gen
 	    sdkp->opt_xfer_blocks <= SD_DEF_XFER_BLOCKS &&
 	    sdkp->opt_xfer_blocks * sdp->sector_size >= PAGE_CACHE_SIZE)
 		rw_max = q->limits.io_opt =
-			logical_to_sectors(sdp, sdkp->opt_xfer_blocks);
+			sdkp->opt_xfer_blocks * sdp->sector_size;
 	else
 		rw_max = BLK_DEF_MAX_SECTORS;
 
 	/* Combine with controller limits */
 	q->limits.max_sectors = min(rw_max, queue_max_hw_sectors(q));
 
-	set_capacity(disk, sdkp->capacity);
+	set_capacity(disk, logical_to_sectors(sdp, sdkp->capacity));
 	sd_config_write_same(sdkp);
 	kfree(buffer);
 
@@ -3268,8 +3256,8 @@ static int sd_suspend_common(struct devi
 	struct scsi_disk *sdkp = dev_get_drvdata(dev);
 	int ret = 0;
 
-	if (!sdkp)
-		return 0;	/* this can happen */
+	if (!sdkp)	/* E.g.: runtime suspend following sd_remove() */
+		return 0;
 
 	if (sdkp->WCE && sdkp->media_present) {
 		sd_printk(KERN_NOTICE, sdkp, "Synchronizing SCSI cache\n");
@@ -3308,6 +3296,9 @@ static int sd_resume(struct device *dev)
 {
 	struct scsi_disk *sdkp = dev_get_drvdata(dev);
 
+	if (!sdkp)	/* E.g.: runtime resume at the start of sd_probe() */
+		return 0;
+
 	if (!sdkp->device->manage_start_stop)
 		return 0;
 
--- zfcpdump-kernel-4.4.orig/drivers/scsi/sd.h
+++ zfcpdump-kernel-4.4/drivers/scsi/sd.h
@@ -65,7 +65,7 @@ struct scsi_disk {
 	struct device	dev;
 	struct gendisk	*disk;
 	atomic_t	openers;
-	sector_t	capacity;	/* size in 512-byte sectors */
+	sector_t	capacity;	/* size in logical blocks */
 	u32		max_xfer_blocks;
 	u32		opt_xfer_blocks;
 	u32		max_ws_blocks;
@@ -146,6 +146,11 @@ static inline int scsi_medium_access_com
 	return 0;
 }
 
+static inline sector_t logical_to_sectors(struct scsi_device *sdev, sector_t blocks)
+{
+	return blocks << (ilog2(sdev->sector_size) - 9);
+}
+
 /*
  * A DIF-capable target device can be formatted with different
  * protection schemes.  Currently 0 through 3 are defined:
--- zfcpdump-kernel-4.4.orig/drivers/scsi/sg.c
+++ zfcpdump-kernel-4.4/drivers/scsi/sg.c
@@ -652,7 +652,8 @@ sg_write(struct file *filp, const char _
 	else
 		hp->dxfer_direction = (mxsize > 0) ? SG_DXFER_FROM_DEV : SG_DXFER_NONE;
 	hp->dxfer_len = mxsize;
-	if (hp->dxfer_direction == SG_DXFER_TO_DEV)
+	if ((hp->dxfer_direction == SG_DXFER_TO_DEV) ||
+	    (hp->dxfer_direction == SG_DXFER_TO_FROM_DEV))
 		hp->dxferp = (char __user *)buf + cmd_size;
 	else
 		hp->dxferp = NULL;
@@ -1261,7 +1262,7 @@ sg_mmap(struct file *filp, struct vm_are
 	}
 
 	sfp->mmap_called = 1;
-	vma->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP;
+	vma->vm_flags |= VM_IO | VM_DONTEXPAND | VM_DONTDUMP;
 	vma->vm_private_data = sfp;
 	vma->vm_ops = &sg_mmap_vm_ops;
 	return 0;
--- zfcpdump-kernel-4.4.orig/drivers/scsi/sr.c
+++ zfcpdump-kernel-4.4/drivers/scsi/sr.c
@@ -144,6 +144,9 @@ static int sr_runtime_suspend(struct dev
 {
 	struct scsi_cd *cd = dev_get_drvdata(dev);
 
+	if (!cd)	/* E.g.: runtime suspend following sr_remove() */
+		return 0;
+
 	if (cd->media_present)
 		return -EBUSY;
 	else
@@ -985,6 +988,7 @@ static int sr_remove(struct device *dev)
 	scsi_autopm_get_device(cd->device);
 
 	del_gendisk(cd->disk);
+	dev_set_drvdata(dev, NULL);
 
 	mutex_lock(&sr_ref_mutex);
 	kref_put(&cd->kref, sr_kref_release);
--- zfcpdump-kernel-4.4.orig/drivers/scsi/storvsc_drv.c
+++ zfcpdump-kernel-4.4/drivers/scsi/storvsc_drv.c
@@ -41,6 +41,8 @@
 #include <scsi/scsi_eh.h>
 #include <scsi/scsi_devinfo.h>
 #include <scsi/scsi_dbg.h>
+#include <scsi/scsi_transport_fc.h>
+#include <scsi/scsi_transport.h>
 
 /*
  * All wire protocol details (storage protocol between the guest and the host)
@@ -92,9 +94,8 @@ enum vstor_packet_operation {
  */
 
 struct hv_fc_wwn_packet {
-	bool	primary_active;
-	u8	reserved1;
-	u8	reserved2;
+	u8	primary_active;
+	u8	reserved1[3];
 	u8	primary_port_wwn[8];
 	u8	primary_node_wwn[8];
 	u8	secondary_port_wwn[8];
@@ -164,6 +165,26 @@ static int sense_buffer_size = PRE_WIN8_
 */
 static int vmstor_proto_version;
 
+#define STORVSC_LOGGING_NONE	0
+#define STORVSC_LOGGING_ERROR	1
+#define STORVSC_LOGGING_WARN	2
+
+static int logging_level = STORVSC_LOGGING_ERROR;
+module_param(logging_level, int, S_IRUGO|S_IWUSR);
+MODULE_PARM_DESC(logging_level,
+	"Logging level, 0 - None, 1 - Error (default), 2 - Warning.");
+
+static inline bool do_logging(int level)
+{
+	return logging_level >= level;
+}
+
+#define storvsc_log(dev, level, fmt, ...)			\
+do {								\
+	if (do_logging(level))					\
+		dev_warn(&(dev)->device, fmt, ##__VA_ARGS__);	\
+} while (0)
+
 struct vmscsi_win8_extension {
 	/*
 	 * The following were added in Windows 8
@@ -370,7 +391,7 @@ module_param(storvsc_ringbuffer_size, in
 MODULE_PARM_DESC(storvsc_ringbuffer_size, "Ring buffer size (bytes)");
 
 module_param(storvsc_vcpus_per_sub_channel, int, S_IRUGO);
-MODULE_PARM_DESC(vcpus_per_sub_channel, "Ratio of VCPUs to subchannels");
+MODULE_PARM_DESC(storvsc_vcpus_per_sub_channel, "Ratio of VCPUs to subchannels");
 /*
  * Timeout in seconds for all devices managed by this driver.
  */
@@ -378,6 +399,9 @@ static int storvsc_timeout = 180;
 
 static int msft_blist_flags = BLIST_TRY_VPD_PAGES;
 
+#if IS_ENABLED(CONFIG_SCSI_FC_ATTRS)
+static struct scsi_transport_template *fc_transport_template;
+#endif
 
 static void storvsc_on_channel_callback(void *context);
 
@@ -437,6 +461,11 @@ struct storvsc_device {
 	/* Used for vsc/vsp channel reset process */
 	struct storvsc_cmd_request init_request;
 	struct storvsc_cmd_request reset_request;
+	/*
+	 * Currently active port and node names for FC devices.
+	 */
+	u64 node_name;
+	u64 port_name;
 };
 
 struct hv_host_device {
@@ -449,19 +478,18 @@ struct hv_host_device {
 struct storvsc_scan_work {
 	struct work_struct work;
 	struct Scsi_Host *host;
-	uint lun;
+	u8 lun;
+	u8 tgt_id;
 };
 
 static void storvsc_device_scan(struct work_struct *work)
 {
 	struct storvsc_scan_work *wrk;
-	uint lun;
 	struct scsi_device *sdev;
 
 	wrk = container_of(work, struct storvsc_scan_work, work);
-	lun = wrk->lun;
 
-	sdev = scsi_device_lookup(wrk->host, 0, 0, lun);
+	sdev = scsi_device_lookup(wrk->host, 0, wrk->tgt_id, wrk->lun);
 	if (!sdev)
 		goto done;
 	scsi_rescan_device(&sdev->sdev_gendev);
@@ -512,7 +540,7 @@ static void storvsc_remove_lun(struct wo
 	if (!scsi_host_get(wrk->host))
 		goto done;
 
-	sdev = scsi_device_lookup(wrk->host, 0, 0, wrk->lun);
+	sdev = scsi_device_lookup(wrk->host, 0, wrk->tgt_id, wrk->lun);
 
 	if (sdev) {
 		scsi_remove_device(sdev);
@@ -676,29 +704,36 @@ static void  handle_multichannel_storage
 	vmbus_are_subchannels_present(device->channel);
 }
 
-static int storvsc_channel_init(struct hv_device *device)
+static void cache_wwn(struct storvsc_device *stor_device,
+		      struct vstor_packet *vstor_packet)
 {
-	struct storvsc_device *stor_device;
-	struct storvsc_cmd_request *request;
-	struct vstor_packet *vstor_packet;
-	int ret, t, i;
-	int max_chns;
-	bool process_sub_channels = false;
+	/*
+	 * Cache the currently active port and node ww names.
+	 */
+	if (vstor_packet->wwn_packet.primary_active) {
+		stor_device->node_name =
+			wwn_to_u64(vstor_packet->wwn_packet.primary_node_wwn);
+		stor_device->port_name =
+			wwn_to_u64(vstor_packet->wwn_packet.primary_port_wwn);
+	} else {
+		stor_device->node_name =
+			wwn_to_u64(vstor_packet->wwn_packet.secondary_node_wwn);
+		stor_device->port_name =
+			wwn_to_u64(vstor_packet->wwn_packet.secondary_port_wwn);
+	}
+}
 
-	stor_device = get_out_stor_device(device);
-	if (!stor_device)
-		return -ENODEV;
 
-	request = &stor_device->init_request;
+static int storvsc_execute_vstor_op(struct hv_device *device,
+				    struct storvsc_cmd_request *request,
+				    bool status_check)
+{
+	struct vstor_packet *vstor_packet;
+	int ret, t;
+
 	vstor_packet = &request->vstor_packet;
 
-	/*
-	 * Now, initiate the vsc/vsp initialization protocol on the open
-	 * channel
-	 */
-	memset(request, 0, sizeof(struct storvsc_cmd_request));
 	init_completion(&request->wait_event);
-	vstor_packet->operation = VSTOR_OPERATION_BEGIN_INITIALIZATION;
 	vstor_packet->flags = REQUEST_COMPLETION_FLAG;
 
 	ret = vmbus_sendpacket(device->channel, vstor_packet,
@@ -708,27 +743,56 @@ static int storvsc_channel_init(struct h
 			       VM_PKT_DATA_INBAND,
 			       VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
 	if (ret != 0)
-		goto cleanup;
+		return ret;
 
 	t = wait_for_completion_timeout(&request->wait_event, 5*HZ);
-	if (t == 0) {
-		ret = -ETIMEDOUT;
-		goto cleanup;
-	}
+	if (t == 0)
+		return -ETIMEDOUT;
+
+	if (!status_check)
+		return ret;
 
 	if (vstor_packet->operation != VSTOR_OPERATION_COMPLETE_IO ||
-	    vstor_packet->status != 0) {
-		ret = -EINVAL;
-		goto cleanup;
-	}
+	    vstor_packet->status != 0)
+		return -EINVAL;
+
+	return ret;
+}
+
+static int storvsc_channel_init(struct hv_device *device, bool is_fc)
+{
+	struct storvsc_device *stor_device;
+	struct storvsc_cmd_request *request;
+	struct vstor_packet *vstor_packet;
+	int ret, i;
+	int max_chns;
+	bool process_sub_channels = false;
 
+	stor_device = get_out_stor_device(device);
+	if (!stor_device)
+		return -ENODEV;
+
+	request = &stor_device->init_request;
+	vstor_packet = &request->vstor_packet;
+
+	/*
+	 * Now, initiate the vsc/vsp initialization protocol on the open
+	 * channel
+	 */
+	memset(request, 0, sizeof(struct storvsc_cmd_request));
+	vstor_packet->operation = VSTOR_OPERATION_BEGIN_INITIALIZATION;
+	ret = storvsc_execute_vstor_op(device, request, true);
+	if (ret)
+		return ret;
+	/*
+	 * Query host supported protocol version.
+	 */
 
 	for (i = 0; i < ARRAY_SIZE(vmstor_protocols); i++) {
 		/* reuse the packet for version range supported */
 		memset(vstor_packet, 0, sizeof(struct vstor_packet));
 		vstor_packet->operation =
 			VSTOR_OPERATION_QUERY_PROTOCOL_VERSION;
-		vstor_packet->flags = REQUEST_COMPLETION_FLAG;
 
 		vstor_packet->version.major_minor =
 			vmstor_protocols[i].protocol_version;
@@ -737,26 +801,12 @@ static int storvsc_channel_init(struct h
 		 * The revision number is only used in Windows; set it to 0.
 		 */
 		vstor_packet->version.revision = 0;
-
-		ret = vmbus_sendpacket(device->channel, vstor_packet,
-			       (sizeof(struct vstor_packet) -
-				vmscsi_size_delta),
-			       (unsigned long)request,
-			       VM_PKT_DATA_INBAND,
-			       VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
+		ret = storvsc_execute_vstor_op(device, request, false);
 		if (ret != 0)
-			goto cleanup;
+			return ret;
 
-		t = wait_for_completion_timeout(&request->wait_event, 5*HZ);
-		if (t == 0) {
-			ret = -ETIMEDOUT;
-			goto cleanup;
-		}
-
-		if (vstor_packet->operation != VSTOR_OPERATION_COMPLETE_IO) {
-			ret = -EINVAL;
-			goto cleanup;
-		}
+		if (vstor_packet->operation != VSTOR_OPERATION_COMPLETE_IO)
+			return -EINVAL;
 
 		if (vstor_packet->status == 0) {
 			vmstor_proto_version =
@@ -772,37 +822,15 @@ static int storvsc_channel_init(struct h
 		}
 	}
 
-	if (vstor_packet->status != 0) {
-		ret = -EINVAL;
-		goto cleanup;
-	}
+	if (vstor_packet->status != 0)
+		return -EINVAL;
 
 
 	memset(vstor_packet, 0, sizeof(struct vstor_packet));
 	vstor_packet->operation = VSTOR_OPERATION_QUERY_PROPERTIES;
-	vstor_packet->flags = REQUEST_COMPLETION_FLAG;
-
-	ret = vmbus_sendpacket(device->channel, vstor_packet,
-			       (sizeof(struct vstor_packet) -
-				vmscsi_size_delta),
-			       (unsigned long)request,
-			       VM_PKT_DATA_INBAND,
-			       VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
-
+	ret = storvsc_execute_vstor_op(device, request, true);
 	if (ret != 0)
-		goto cleanup;
-
-	t = wait_for_completion_timeout(&request->wait_event, 5*HZ);
-	if (t == 0) {
-		ret = -ETIMEDOUT;
-		goto cleanup;
-	}
-
-	if (vstor_packet->operation != VSTOR_OPERATION_COMPLETE_IO ||
-	    vstor_packet->status != 0) {
-		ret = -EINVAL;
-		goto cleanup;
-	}
+		return ret;
 
 	/*
 	 * Check to see if multi-channel support is there.
@@ -818,37 +846,34 @@ static int storvsc_channel_init(struct h
 	stor_device->max_transfer_bytes =
 		vstor_packet->storage_channel_properties.max_transfer_bytes;
 
-	memset(vstor_packet, 0, sizeof(struct vstor_packet));
-	vstor_packet->operation = VSTOR_OPERATION_END_INITIALIZATION;
-	vstor_packet->flags = REQUEST_COMPLETION_FLAG;
-
-	ret = vmbus_sendpacket(device->channel, vstor_packet,
-			       (sizeof(struct vstor_packet) -
-				vmscsi_size_delta),
-			       (unsigned long)request,
-			       VM_PKT_DATA_INBAND,
-			       VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
+	if (!is_fc)
+		goto done;
 
+	/*
+	 * For FC devices retrieve FC HBA data.
+	 */
+	memset(vstor_packet, 0, sizeof(struct vstor_packet));
+	vstor_packet->operation = VSTOR_OPERATION_FCHBA_DATA;
+	ret = storvsc_execute_vstor_op(device, request, true);
 	if (ret != 0)
-		goto cleanup;
+		return ret;
 
-	t = wait_for_completion_timeout(&request->wait_event, 5*HZ);
-	if (t == 0) {
-		ret = -ETIMEDOUT;
-		goto cleanup;
-	}
+	/*
+	 * Cache the currently active port and node ww names.
+	 */
+	cache_wwn(stor_device, vstor_packet);
 
-	if (vstor_packet->operation != VSTOR_OPERATION_COMPLETE_IO ||
-	    vstor_packet->status != 0) {
-		ret = -EINVAL;
-		goto cleanup;
-	}
+done:
+
+	memset(vstor_packet, 0, sizeof(struct vstor_packet));
+	vstor_packet->operation = VSTOR_OPERATION_END_INITIALIZATION;
+	ret = storvsc_execute_vstor_op(device, request, true);
+	if (ret != 0)
+		return ret;
 
 	if (process_sub_channels)
 		handle_multichannel_storage(device, max_chns);
 
-
-cleanup:
 	return ret;
 }
 
@@ -889,8 +914,9 @@ static void storvsc_handle_error(struct
 		do_work = true;
 		process_err_fn = storvsc_remove_lun;
 		break;
-	case (SRB_STATUS_ABORTED | SRB_STATUS_AUTOSENSE_VALID):
-		if ((asc == 0x2a) && (ascq == 0x9)) {
+	case SRB_STATUS_ABORTED:
+		if (vm_srb->srb_status & SRB_STATUS_AUTOSENSE_VALID &&
+		    (asc == 0x2a) && (ascq == 0x9)) {
 			do_work = true;
 			process_err_fn = storvsc_device_scan;
 			/*
@@ -915,24 +941,22 @@ static void storvsc_handle_error(struct
 
 	wrk->host = host;
 	wrk->lun = vm_srb->lun;
+	wrk->tgt_id = vm_srb->target_id;
 	INIT_WORK(&wrk->work, process_err_fn);
 	schedule_work(&wrk->work);
 }
 
 
-static void storvsc_command_completion(struct storvsc_cmd_request *cmd_request)
+static void storvsc_command_completion(struct storvsc_cmd_request *cmd_request,
+				       struct storvsc_device *stor_dev)
 {
 	struct scsi_cmnd *scmnd = cmd_request->cmd;
-	struct hv_host_device *host_dev = shost_priv(scmnd->device->host);
 	struct scsi_sense_hdr sense_hdr;
 	struct vmscsi_request *vm_srb;
 	struct Scsi_Host *host;
-	struct storvsc_device *stor_dev;
-	struct hv_device *dev = host_dev->dev;
 	u32 payload_sz = cmd_request->payload_sz;
 	void *payload = cmd_request->payload;
 
-	stor_dev = get_in_stor_device(dev);
 	host = stor_dev->host;
 
 	vm_srb = &cmd_request->vstor_packet.vm_srb;
@@ -941,7 +965,10 @@ static void storvsc_command_completion(s
 
 	if (scmnd->result) {
 		if (scsi_normalize_sense(scmnd->sense_buffer,
-				SCSI_SENSE_BUFFERSIZE, &sense_hdr))
+				SCSI_SENSE_BUFFERSIZE, &sense_hdr) &&
+		    !(sense_hdr.sense_key == NOT_READY &&
+				 sense_hdr.asc == 0x03A) &&
+		    do_logging(STORVSC_LOGGING_ERROR))
 			scsi_print_sense_hdr(scmnd->device, "storvsc",
 					     &sense_hdr);
 	}
@@ -961,14 +988,13 @@ static void storvsc_command_completion(s
 		kfree(payload);
 }
 
-static void storvsc_on_io_completion(struct hv_device *device,
+static void storvsc_on_io_completion(struct storvsc_device *stor_device,
 				  struct vstor_packet *vstor_packet,
 				  struct storvsc_cmd_request *request)
 {
-	struct storvsc_device *stor_device;
 	struct vstor_packet *stor_pkt;
+	struct hv_device *device = stor_device->device;
 
-	stor_device = hv_get_drvdata(device);
 	stor_pkt = &request->vstor_packet;
 
 	/*
@@ -995,6 +1021,13 @@ static void storvsc_on_io_completion(str
 	stor_pkt->vm_srb.sense_info_length =
 	vstor_packet->vm_srb.sense_info_length;
 
+	if (vstor_packet->vm_srb.scsi_status != 0 ||
+	    vstor_packet->vm_srb.srb_status != SRB_STATUS_SUCCESS)
+		storvsc_log(device, STORVSC_LOGGING_WARN,
+			"cmd 0x%x scsi status 0x%x srb status 0x%x\n",
+			stor_pkt->vm_srb.cdb[0],
+			vstor_packet->vm_srb.scsi_status,
+			vstor_packet->vm_srb.srb_status);
 
 	if ((vstor_packet->vm_srb.scsi_status & 0xFF) == 0x02) {
 		/* CHECK_CONDITION */
@@ -1002,6 +1035,10 @@ static void storvsc_on_io_completion(str
 			SRB_STATUS_AUTOSENSE_VALID) {
 			/* autosense data available */
 
+			storvsc_log(device, STORVSC_LOGGING_WARN,
+				"stor pkt %p autosense data valid - len %d\n",
+				request, vstor_packet->vm_srb.sense_info_length);
+
 			memcpy(request->cmd->sense_buffer,
 			       vstor_packet->vm_srb.sense_data,
 			       vstor_packet->vm_srb.sense_info_length);
@@ -1012,7 +1049,7 @@ static void storvsc_on_io_completion(str
 	stor_pkt->vm_srb.data_transfer_length =
 	vstor_packet->vm_srb.data_transfer_length;
 
-	storvsc_command_completion(request);
+	storvsc_command_completion(request, stor_device);
 
 	if (atomic_dec_and_test(&stor_device->num_outstanding_req) &&
 		stor_device->drain_notify)
@@ -1021,21 +1058,19 @@ static void storvsc_on_io_completion(str
 
 }
 
-static void storvsc_on_receive(struct hv_device *device,
+static void storvsc_on_receive(struct storvsc_device *stor_device,
 			     struct vstor_packet *vstor_packet,
 			     struct storvsc_cmd_request *request)
 {
 	struct storvsc_scan_work *work;
-	struct storvsc_device *stor_device;
 
 	switch (vstor_packet->operation) {
 	case VSTOR_OPERATION_COMPLETE_IO:
-		storvsc_on_io_completion(device, vstor_packet, request);
+		storvsc_on_io_completion(stor_device, vstor_packet, request);
 		break;
 
 	case VSTOR_OPERATION_REMOVE_DEVICE:
 	case VSTOR_OPERATION_ENUMERATE_BUS:
-		stor_device = get_in_stor_device(device);
 		work = kmalloc(sizeof(struct storvsc_scan_work), GFP_ATOMIC);
 		if (!work)
 			return;
@@ -1045,6 +1080,13 @@ static void storvsc_on_receive(struct hv
 		schedule_work(&work->work);
 		break;
 
+	case VSTOR_OPERATION_FCHBA_DATA:
+		cache_wwn(stor_device, vstor_packet);
+#if IS_ENABLED(CONFIG_SCSI_FC_ATTRS)
+		fc_host_node_name(stor_device->host) = stor_device->node_name;
+		fc_host_port_name(stor_device->host) = stor_device->port_name;
+#endif
+		break;
 	default:
 		break;
 	}
@@ -1088,7 +1130,7 @@ static void storvsc_on_channel_callback(
 					vmscsi_size_delta));
 				complete(&request->wait_event);
 			} else {
-				storvsc_on_receive(device,
+				storvsc_on_receive(stor_device,
 						(struct vstor_packet *)packet,
 						request);
 			}
@@ -1100,7 +1142,8 @@ static void storvsc_on_channel_callback(
 	return;
 }
 
-static int storvsc_connect_to_vsp(struct hv_device *device, u32 ring_size)
+static int storvsc_connect_to_vsp(struct hv_device *device, u32 ring_size,
+				  bool is_fc)
 {
 	struct vmstorage_channel_properties props;
 	int ret;
@@ -1117,7 +1160,7 @@ static int storvsc_connect_to_vsp(struct
 	if (ret != 0)
 		return ret;
 
-	ret = storvsc_channel_init(device);
+	ret = storvsc_channel_init(device, is_fc);
 
 	return ret;
 }
@@ -1542,6 +1585,7 @@ static int storvsc_probe(struct hv_devic
 	struct Scsi_Host *host;
 	struct hv_host_device *host_dev;
 	bool dev_is_ide = ((dev_id->driver_data == IDE_GUID) ? true : false);
+	bool is_fc = ((dev_id->driver_data == SFC_GUID) ? true : false);
 	int target = 0;
 	struct storvsc_device *stor_device;
 	int max_luns_per_target;
@@ -1599,7 +1643,7 @@ static int storvsc_probe(struct hv_devic
 	hv_set_drvdata(device, stor_device);
 
 	stor_device->port_number = host->host_no;
-	ret = storvsc_connect_to_vsp(device, storvsc_ringbuffer_size);
+	ret = storvsc_connect_to_vsp(device, storvsc_ringbuffer_size, is_fc);
 	if (ret)
 		goto err_out1;
 
@@ -1611,6 +1655,9 @@ static int storvsc_probe(struct hv_devic
 		host->max_lun = STORVSC_FC_MAX_LUNS_PER_TARGET;
 		host->max_id = STORVSC_FC_MAX_TARGETS;
 		host->max_channel = STORVSC_FC_MAX_CHANNELS - 1;
+#if IS_ENABLED(CONFIG_SCSI_FC_ATTRS)
+		host->transportt = fc_transport_template;
+#endif
 		break;
 
 	case SCSI_GUID:
@@ -1633,6 +1680,11 @@ static int storvsc_probe(struct hv_devic
 	 * from the host.
 	 */
 	host->sg_tablesize = (stor_device->max_transfer_bytes >> PAGE_SHIFT);
+#if defined(CONFIG_X86_32)
+	dev_warn(&device->device, "adjusting sg_tablesize 0x%x -> 0x%x",
+			host->sg_tablesize, MAX_MULTIPAGE_BUFFER_COUNT);
+	host->sg_tablesize = MAX_MULTIPAGE_BUFFER_COUNT;
+#endif
 
 	/* Register the HBA and start the scsi bus scan */
 	ret = scsi_add_host(host, &device->device);
@@ -1650,6 +1702,12 @@ static int storvsc_probe(struct hv_devic
 			goto err_out2;
 		}
 	}
+#if IS_ENABLED(CONFIG_SCSI_FC_ATTRS)
+	if (host->transportt == fc_transport_template) {
+		fc_host_node_name(host) = stor_device->node_name;
+		fc_host_port_name(host) = stor_device->port_name;
+	}
+#endif
 	return 0;
 
 err_out2:
@@ -1675,6 +1733,10 @@ static int storvsc_remove(struct hv_devi
 	struct storvsc_device *stor_device = hv_get_drvdata(dev);
 	struct Scsi_Host *host = stor_device->host;
 
+#if IS_ENABLED(CONFIG_SCSI_FC_ATTRS)
+	if (host->transportt == fc_transport_template)
+		fc_remove_host(host);
+#endif
 	scsi_remove_host(host);
 	storvsc_dev_remove(dev);
 	scsi_host_put(host);
@@ -1689,8 +1751,16 @@ static struct hv_driver storvsc_drv = {
 	.remove = storvsc_remove,
 };
 
+#if IS_ENABLED(CONFIG_SCSI_FC_ATTRS)
+static struct fc_function_template fc_transport_functions = {
+	.show_host_node_name = 1,
+	.show_host_port_name = 1,
+};
+#endif
+
 static int __init storvsc_drv_init(void)
 {
+	int ret;
 
 	/*
 	 * Divide the ring buffer data size (which is 1 page less
@@ -1705,12 +1775,33 @@ static int __init storvsc_drv_init(void)
 		vmscsi_size_delta,
 		sizeof(u64)));
 
-	return vmbus_driver_register(&storvsc_drv);
+#if IS_ENABLED(CONFIG_SCSI_FC_ATTRS)
+	fc_transport_template = fc_attach_transport(&fc_transport_functions);
+	if (!fc_transport_template)
+		return -ENODEV;
+
+	/*
+	 * Install Hyper-V specific timeout handler.
+	 */
+	fc_transport_template->eh_timed_out = storvsc_eh_timed_out;
+#endif
+
+	ret = vmbus_driver_register(&storvsc_drv);
+
+#if IS_ENABLED(CONFIG_SCSI_FC_ATTRS)
+	if (ret)
+		fc_release_transport(fc_transport_template);
+#endif
+
+	return ret;
 }
 
 static void __exit storvsc_drv_exit(void)
 {
 	vmbus_driver_unregister(&storvsc_drv);
+#if IS_ENABLED(CONFIG_SCSI_FC_ATTRS)
+	fc_release_transport(fc_transport_template);
+#endif
 }
 
 MODULE_LICENSE("GPL");
--- zfcpdump-kernel-4.4.orig/drivers/sh/pm_runtime.c
+++ zfcpdump-kernel-4.4/drivers/sh/pm_runtime.c
@@ -34,7 +34,7 @@ static struct pm_clk_notifier_block plat
 
 static int __init sh_pm_runtime_init(void)
 {
-	if (IS_ENABLED(CONFIG_ARCH_SHMOBILE)) {
+	if (IS_ENABLED(CONFIG_OF) && IS_ENABLED(CONFIG_ARCH_SHMOBILE)) {
 		if (!of_find_compatible_node(NULL, NULL,
 					     "renesas,cpg-mstp-clocks"))
 			return 0;
--- zfcpdump-kernel-4.4.orig/drivers/soc/qcom/spm.c
+++ zfcpdump-kernel-4.4/drivers/soc/qcom/spm.c
@@ -288,7 +288,7 @@ static struct spm_driver_data *spm_get_d
 	struct spm_driver_data *drv = NULL;
 	struct device_node *cpu_node, *saw_node;
 	int cpu;
-	bool found;
+	bool found = 0;
 
 	for_each_possible_cpu(cpu) {
 		cpu_node = of_cpu_device_node_get(cpu);
--- zfcpdump-kernel-4.4.orig/drivers/soc/rockchip/pm_domains.c
+++ zfcpdump-kernel-4.4/drivers/soc/rockchip/pm_domains.c
@@ -419,6 +419,7 @@ static int rockchip_pm_domain_probe(stru
 		if (error) {
 			dev_err(dev, "failed to handle node %s: %d\n",
 				node->name, error);
+			of_node_put(node);
 			goto err_out;
 		}
 	}
--- zfcpdump-kernel-4.4.orig/drivers/spi/spi-atmel.c
+++ zfcpdump-kernel-4.4/drivers/spi/spi-atmel.c
@@ -1571,6 +1571,7 @@ static int atmel_spi_probe(struct platfo
 
 	as->use_cs_gpios = true;
 	if (atmel_spi_is_v2(as) &&
+	    pdev->dev.of_node &&
 	    !of_get_property(pdev->dev.of_node, "cs-gpios", NULL)) {
 		as->use_cs_gpios = false;
 		master->num_chipselect = 4;
--- zfcpdump-kernel-4.4.orig/drivers/spi/spi-omap2-mcspi.c
+++ zfcpdump-kernel-4.4/drivers/spi/spi-omap2-mcspi.c
@@ -1024,6 +1024,16 @@ static int omap2_mcspi_setup(struct spi_
 		spi->controller_state = cs;
 		/* Link this to context save list */
 		list_add_tail(&cs->node, &ctx->cs);
+
+		if (gpio_is_valid(spi->cs_gpio)) {
+			ret = gpio_request(spi->cs_gpio, dev_name(&spi->dev));
+			if (ret) {
+				dev_err(&spi->dev, "failed to request gpio\n");
+				return ret;
+			}
+			gpio_direction_output(spi->cs_gpio,
+					 !(spi->mode & SPI_CS_HIGH));
+		}
 	}
 
 	if (!mcspi_dma->dma_rx || !mcspi_dma->dma_tx) {
@@ -1032,15 +1042,6 @@ static int omap2_mcspi_setup(struct spi_
 			return ret;
 	}
 
-	if (gpio_is_valid(spi->cs_gpio)) {
-		ret = gpio_request(spi->cs_gpio, dev_name(&spi->dev));
-		if (ret) {
-			dev_err(&spi->dev, "failed to request gpio\n");
-			return ret;
-		}
-		gpio_direction_output(spi->cs_gpio, !(spi->mode & SPI_CS_HIGH));
-	}
-
 	ret = pm_runtime_get_sync(mcspi->dev);
 	if (ret < 0)
 		return ret;
--- zfcpdump-kernel-4.4.orig/drivers/spi/spi-pxa2xx.c
+++ zfcpdump-kernel-4.4/drivers/spi/spi-pxa2xx.c
@@ -111,7 +111,7 @@ static const struct lpss_config lpss_pla
 		.reg_general = -1,
 		.reg_ssp = 0x20,
 		.reg_cs_ctrl = 0x24,
-		.reg_capabilities = 0xfc,
+		.reg_capabilities = -1,
 		.rx_threshold = 1,
 		.tx_threshold_lo = 32,
 		.tx_threshold_hi = 56,
@@ -548,7 +548,14 @@ static void reset_sccr1(struct driver_da
 	u32 sccr1_reg;
 
 	sccr1_reg = pxa2xx_spi_read(drv_data, SSCR1) & ~drv_data->int_cr1;
-	sccr1_reg &= ~SSCR1_RFT;
+	switch (drv_data->ssp_type) {
+	case QUARK_X1000_SSP:
+		sccr1_reg &= ~QUARK_X1000_SSCR1_RFT;
+		break;
+	default:
+		sccr1_reg &= ~SSCR1_RFT;
+		break;
+	}
 	sccr1_reg |= chip->threshold;
 	pxa2xx_spi_write(drv_data, SSCR1, sccr1_reg);
 }
--- zfcpdump-kernel-4.4.orig/drivers/spi/spi-rockchip.c
+++ zfcpdump-kernel-4.4/drivers/spi/spi-rockchip.c
@@ -265,7 +265,10 @@ static inline u32 rx_max(struct rockchip
 static void rockchip_spi_set_cs(struct spi_device *spi, bool enable)
 {
 	u32 ser;
-	struct rockchip_spi *rs = spi_master_get_devdata(spi->master);
+	struct spi_master *master = spi->master;
+	struct rockchip_spi *rs = spi_master_get_devdata(master);
+
+	pm_runtime_get_sync(rs->dev);
 
 	ser = readl_relaxed(rs->regs + ROCKCHIP_SPI_SER) & SER_MASK;
 
@@ -290,6 +293,8 @@ static void rockchip_spi_set_cs(struct s
 		ser &= ~(1 << spi->chip_select);
 
 	writel_relaxed(ser, rs->regs + ROCKCHIP_SPI_SER);
+
+	pm_runtime_put_sync(rs->dev);
 }
 
 static int rockchip_spi_prepare_message(struct spi_master *master,
--- zfcpdump-kernel-4.4.orig/drivers/spi/spi-sh-msiof.c
+++ zfcpdump-kernel-4.4/drivers/spi/spi-sh-msiof.c
@@ -263,6 +263,9 @@ static void sh_msiof_spi_set_clk_regs(st
 
 	for (k = 0; k < ARRAY_SIZE(sh_msiof_spi_div_table); k++) {
 		brps = DIV_ROUND_UP(div, sh_msiof_spi_div_table[k].div);
+		/* SCR_BRDV_DIV_1 is valid only if BRPS is x 1/1 or x 1/2 */
+		if (sh_msiof_spi_div_table[k].div == 1 && brps > 2)
+			continue;
 		if (brps <= 32) /* max of brdv is 32 */
 			break;
 	}
--- zfcpdump-kernel-4.4.orig/drivers/spi/spi-sun4i.c
+++ zfcpdump-kernel-4.4/drivers/spi/spi-sun4i.c
@@ -170,13 +170,17 @@ static int sun4i_spi_transfer_one(struct
 {
 	struct sun4i_spi *sspi = spi_master_get_devdata(master);
 	unsigned int mclk_rate, div, timeout;
+	unsigned int start, end, tx_time;
 	unsigned int tx_len = 0;
 	int ret = 0;
 	u32 reg;
 
 	/* We don't support transfer larger than the FIFO */
 	if (tfr->len > SUN4I_FIFO_DEPTH)
-		return -EINVAL;
+		return -EMSGSIZE;
+
+	if (tfr->tx_buf && tfr->len >= SUN4I_FIFO_DEPTH)
+		return -EMSGSIZE;
 
 	reinit_completion(&sspi->done);
 	sspi->tx_buf = tfr->tx_buf;
@@ -269,8 +273,12 @@ static int sun4i_spi_transfer_one(struct
 	sun4i_spi_write(sspi, SUN4I_BURST_CNT_REG, SUN4I_BURST_CNT(tfr->len));
 	sun4i_spi_write(sspi, SUN4I_XMIT_CNT_REG, SUN4I_XMIT_CNT(tx_len));
 
-	/* Fill the TX FIFO */
-	sun4i_spi_fill_fifo(sspi, SUN4I_FIFO_DEPTH);
+	/*
+	 * Fill the TX FIFO
+	 * Filling the FIFO fully causes timeout for some reason
+	 * at least on spi2 on A10s
+	 */
+	sun4i_spi_fill_fifo(sspi, SUN4I_FIFO_DEPTH - 1);
 
 	/* Enable the interrupts */
 	sun4i_spi_write(sspi, SUN4I_INT_CTL_REG, SUN4I_INT_CTL_TC);
@@ -279,9 +287,16 @@ static int sun4i_spi_transfer_one(struct
 	reg = sun4i_spi_read(sspi, SUN4I_CTL_REG);
 	sun4i_spi_write(sspi, SUN4I_CTL_REG, reg | SUN4I_CTL_XCH);
 
+	tx_time = max(tfr->len * 8 * 2 / (tfr->speed_hz / 1000), 100U);
+	start = jiffies;
 	timeout = wait_for_completion_timeout(&sspi->done,
-					      msecs_to_jiffies(1000));
+					      msecs_to_jiffies(tx_time));
+	end = jiffies;
 	if (!timeout) {
+		dev_warn(&master->dev,
+			 "%s: timeout transferring %u bytes@%iHz for %i(%i)ms",
+			 dev_name(&spi->dev), tfr->len, tfr->speed_hz,
+			 jiffies_to_msecs(end - start), tx_time);
 		ret = -ETIMEDOUT;
 		goto out;
 	}
--- zfcpdump-kernel-4.4.orig/drivers/spi/spi-sun6i.c
+++ zfcpdump-kernel-4.4/drivers/spi/spi-sun6i.c
@@ -160,6 +160,7 @@ static int sun6i_spi_transfer_one(struct
 {
 	struct sun6i_spi *sspi = spi_master_get_devdata(master);
 	unsigned int mclk_rate, div, timeout;
+	unsigned int start, end, tx_time;
 	unsigned int tx_len = 0;
 	int ret = 0;
 	u32 reg;
@@ -269,9 +270,16 @@ static int sun6i_spi_transfer_one(struct
 	reg = sun6i_spi_read(sspi, SUN6I_TFR_CTL_REG);
 	sun6i_spi_write(sspi, SUN6I_TFR_CTL_REG, reg | SUN6I_TFR_CTL_XCH);
 
+	tx_time = max(tfr->len * 8 * 2 / (tfr->speed_hz / 1000), 100U);
+	start = jiffies;
 	timeout = wait_for_completion_timeout(&sspi->done,
-					      msecs_to_jiffies(1000));
+					      msecs_to_jiffies(tx_time));
+	end = jiffies;
 	if (!timeout) {
+		dev_warn(&master->dev,
+			 "%s: timeout transferring %u bytes@%iHz for %i(%i)ms",
+			 dev_name(&spi->dev), tfr->len, tfr->speed_hz,
+			 jiffies_to_msecs(end - start), tx_time);
 		ret = -ETIMEDOUT;
 		goto out;
 	}
--- zfcpdump-kernel-4.4.orig/drivers/spi/spi-ti-qspi.c
+++ zfcpdump-kernel-4.4/drivers/spi/spi-ti-qspi.c
@@ -94,6 +94,7 @@ struct ti_qspi {
 #define QSPI_FLEN(n)			((n - 1) << 0)
 #define QSPI_WLEN_MAX_BITS		128
 #define QSPI_WLEN_MAX_BYTES		16
+#define QSPI_WLEN_MASK			QSPI_WLEN(QSPI_WLEN_MAX_BITS)
 
 /* STATUS REGISTER */
 #define BUSY				0x01
@@ -224,16 +225,16 @@ static inline int ti_qspi_poll_wc(struct
 	return  -ETIMEDOUT;
 }
 
-static int qspi_write_msg(struct ti_qspi *qspi, struct spi_transfer *t)
+static int qspi_write_msg(struct ti_qspi *qspi, struct spi_transfer *t,
+			  int count)
 {
-	int wlen, count, xfer_len;
+	int wlen, xfer_len;
 	unsigned int cmd;
 	const u8 *txbuf;
 	u32 data;
 
 	txbuf = t->tx_buf;
 	cmd = qspi->cmd | QSPI_WR_SNGL;
-	count = t->len;
 	wlen = t->bits_per_word >> 3;	/* in bytes */
 	xfer_len = wlen;
 
@@ -293,9 +294,10 @@ static int qspi_write_msg(struct ti_qspi
 	return 0;
 }
 
-static int qspi_read_msg(struct ti_qspi *qspi, struct spi_transfer *t)
+static int qspi_read_msg(struct ti_qspi *qspi, struct spi_transfer *t,
+			 int count)
 {
-	int wlen, count;
+	int wlen;
 	unsigned int cmd;
 	u8 *rxbuf;
 
@@ -312,7 +314,6 @@ static int qspi_read_msg(struct ti_qspi
 		cmd |= QSPI_RD_SNGL;
 		break;
 	}
-	count = t->len;
 	wlen = t->bits_per_word >> 3;	/* in bytes */
 
 	while (count) {
@@ -343,12 +344,13 @@ static int qspi_read_msg(struct ti_qspi
 	return 0;
 }
 
-static int qspi_transfer_msg(struct ti_qspi *qspi, struct spi_transfer *t)
+static int qspi_transfer_msg(struct ti_qspi *qspi, struct spi_transfer *t,
+			     int count)
 {
 	int ret;
 
 	if (t->tx_buf) {
-		ret = qspi_write_msg(qspi, t);
+		ret = qspi_write_msg(qspi, t, count);
 		if (ret) {
 			dev_dbg(qspi->dev, "Error while writing\n");
 			return ret;
@@ -356,7 +358,7 @@ static int qspi_transfer_msg(struct ti_q
 	}
 
 	if (t->rx_buf) {
-		ret = qspi_read_msg(qspi, t);
+		ret = qspi_read_msg(qspi, t, count);
 		if (ret) {
 			dev_dbg(qspi->dev, "Error while reading\n");
 			return ret;
@@ -373,7 +375,8 @@ static int ti_qspi_start_transfer_one(st
 	struct spi_device *spi = m->spi;
 	struct spi_transfer *t;
 	int status = 0, ret;
-	int frame_length;
+	unsigned int frame_len_words, transfer_len_words;
+	int wlen;
 
 	/* setup device control reg */
 	qspi->dc = 0;
@@ -385,30 +388,38 @@ static int ti_qspi_start_transfer_one(st
 	if (spi->mode & SPI_CS_HIGH)
 		qspi->dc |= QSPI_CSPOL(spi->chip_select);
 
-	frame_length = (m->frame_length << 3) / spi->bits_per_word;
-
-	frame_length = clamp(frame_length, 0, QSPI_FRAME);
+	frame_len_words = 0;
+	list_for_each_entry(t, &m->transfers, transfer_list)
+		frame_len_words += t->len / (t->bits_per_word >> 3);
+	frame_len_words = min_t(unsigned int, frame_len_words, QSPI_FRAME);
 
 	/* setup command reg */
 	qspi->cmd = 0;
 	qspi->cmd |= QSPI_EN_CS(spi->chip_select);
-	qspi->cmd |= QSPI_FLEN(frame_length);
+	qspi->cmd |= QSPI_FLEN(frame_len_words);
 
 	ti_qspi_write(qspi, qspi->dc, QSPI_SPI_DC_REG);
 
 	mutex_lock(&qspi->list_lock);
 
 	list_for_each_entry(t, &m->transfers, transfer_list) {
-		qspi->cmd |= QSPI_WLEN(t->bits_per_word);
+		qspi->cmd = ((qspi->cmd & ~QSPI_WLEN_MASK) |
+			     QSPI_WLEN(t->bits_per_word));
+
+		wlen = t->bits_per_word >> 3;
+		transfer_len_words = min(t->len / wlen, frame_len_words);
 
-		ret = qspi_transfer_msg(qspi, t);
+		ret = qspi_transfer_msg(qspi, t, transfer_len_words * wlen);
 		if (ret) {
 			dev_dbg(qspi->dev, "transfer message failed\n");
 			mutex_unlock(&qspi->list_lock);
 			return -EINVAL;
 		}
 
-		m->actual_length += t->len;
+		m->actual_length += transfer_len_words * wlen;
+		frame_len_words -= transfer_len_words;
+		if (frame_len_words == 0)
+			break;
 	}
 
 	mutex_unlock(&qspi->list_lock);
--- zfcpdump-kernel-4.4.orig/drivers/staging/android/ion/ion.c
+++ zfcpdump-kernel-4.4/drivers/staging/android/ion/ion.c
@@ -251,8 +251,10 @@ static struct ion_buffer *ion_buffer_cre
 	 * memory coming from the heaps is ready for dma, ie if it has a
 	 * cached mapping that mapping has been invalidated
 	 */
-	for_each_sg(buffer->sg_table->sgl, sg, buffer->sg_table->nents, i)
+	for_each_sg(buffer->sg_table->sgl, sg, buffer->sg_table->nents, i) {
 		sg_dma_address(sg) = sg_phys(sg);
+		sg_dma_len(sg) = sg->length;
+	}
 	mutex_lock(&dev->buffer_lock);
 	ion_buffer_add(dev, buffer);
 	mutex_unlock(&dev->buffer_lock);
--- zfcpdump-kernel-4.4.orig/drivers/staging/android/ion/ion_test.c
+++ zfcpdump-kernel-4.4/drivers/staging/android/ion/ion_test.c
@@ -285,8 +285,8 @@ static int __init ion_test_init(void)
 {
 	ion_test_pdev = platform_device_register_simple("ion-test",
 							-1, NULL, 0);
-	if (!ion_test_pdev)
-		return -ENODEV;
+	if (IS_ERR(ion_test_pdev))
+		return PTR_ERR(ion_test_pdev);
 
 	return platform_driver_probe(&ion_test_platform_driver, ion_test_probe);
 }
--- zfcpdump-kernel-4.4.orig/drivers/staging/comedi/drivers/comedi_test.c
+++ zfcpdump-kernel-4.4/drivers/staging/comedi/drivers/comedi_test.c
@@ -56,11 +56,6 @@
 
 #define N_CHANS 8
 
-enum waveform_state_bits {
-	WAVEFORM_AI_RUNNING,
-	WAVEFORM_AO_RUNNING
-};
-
 /* Data unique to this driver */
 struct waveform_private {
 	struct timer_list ai_timer;	/* timer for AI commands */
@@ -68,7 +63,6 @@ struct waveform_private {
 	unsigned int wf_amplitude;	/* waveform amplitude in microvolts */
 	unsigned int wf_period;		/* waveform period in microseconds */
 	unsigned int wf_current;	/* current time in waveform period */
-	unsigned long state_bits;
 	unsigned int ai_scan_period;	/* AI scan period in usec */
 	unsigned int ai_convert_period;	/* AI conversion period in usec */
 	struct timer_list ao_timer;	/* timer for AO commands */
@@ -191,10 +185,6 @@ static void waveform_ai_timer(unsigned l
 	unsigned int nsamples;
 	unsigned int time_increment;
 
-	/* check command is still active */
-	if (!test_bit(WAVEFORM_AI_RUNNING, &devpriv->state_bits))
-		return;
-
 	now = ktime_to_us(ktime_get());
 	nsamples = comedi_nsamples_left(s, UINT_MAX);
 
@@ -386,11 +376,6 @@ static int waveform_ai_cmd(struct comedi
 	 */
 	devpriv->ai_timer.expires =
 		jiffies + usecs_to_jiffies(devpriv->ai_convert_period) + 1;
-
-	/* mark command as active */
-	smp_mb__before_atomic();
-	set_bit(WAVEFORM_AI_RUNNING, &devpriv->state_bits);
-	smp_mb__after_atomic();
 	add_timer(&devpriv->ai_timer);
 	return 0;
 }
@@ -400,11 +385,12 @@ static int waveform_ai_cancel(struct com
 {
 	struct waveform_private *devpriv = dev->private;
 
-	/* mark command as no longer active */
-	clear_bit(WAVEFORM_AI_RUNNING, &devpriv->state_bits);
-	smp_mb__after_atomic();
-	/* cannot call del_timer_sync() as may be called from timer routine */
-	del_timer(&devpriv->ai_timer);
+	if (in_softirq()) {
+		/* Assume we were called from the timer routine itself. */
+		del_timer(&devpriv->ai_timer);
+	} else {
+		del_timer_sync(&devpriv->ai_timer);
+	}
 	return 0;
 }
 
@@ -436,10 +422,6 @@ static void waveform_ao_timer(unsigned l
 	u64 scans_since;
 	unsigned int scans_avail = 0;
 
-	/* check command is still active */
-	if (!test_bit(WAVEFORM_AO_RUNNING, &devpriv->state_bits))
-		return;
-
 	/* determine number of scan periods since last time */
 	now = ktime_to_us(ktime_get());
 	scans_since = now - devpriv->ao_last_scan_time;
@@ -518,11 +500,6 @@ static int waveform_ao_inttrig_start(str
 	devpriv->ao_last_scan_time = ktime_to_us(ktime_get());
 	devpriv->ao_timer.expires =
 		jiffies + usecs_to_jiffies(devpriv->ao_scan_period);
-
-	/* mark command as active */
-	smp_mb__before_atomic();
-	set_bit(WAVEFORM_AO_RUNNING, &devpriv->state_bits);
-	smp_mb__after_atomic();
 	add_timer(&devpriv->ao_timer);
 
 	return 1;
@@ -608,11 +585,12 @@ static int waveform_ao_cancel(struct com
 	struct waveform_private *devpriv = dev->private;
 
 	s->async->inttrig = NULL;
-	/* mark command as no longer active */
-	clear_bit(WAVEFORM_AO_RUNNING, &devpriv->state_bits);
-	smp_mb__after_atomic();
-	/* cannot call del_timer_sync() as may be called from timer routine */
-	del_timer(&devpriv->ao_timer);
+	if (in_softirq()) {
+		/* Assume we were called from the timer routine itself. */
+		del_timer(&devpriv->ao_timer);
+	} else {
+		del_timer_sync(&devpriv->ao_timer);
+	}
 	return 0;
 }
 
--- zfcpdump-kernel-4.4.orig/drivers/staging/comedi/drivers/daqboard2000.c
+++ zfcpdump-kernel-4.4/drivers/staging/comedi/drivers/daqboard2000.c
@@ -636,7 +636,7 @@ static const void *daqboard2000_find_boa
 	const struct daq200_boardtype *board;
 	int i;
 
-	if (pcidev->subsystem_device != PCI_VENDOR_ID_IOTECH)
+	if (pcidev->subsystem_vendor != PCI_VENDOR_ID_IOTECH)
 		return NULL;
 
 	for (i = 0; i < ARRAY_SIZE(boardtypes); i++) {
--- zfcpdump-kernel-4.4.orig/drivers/staging/comedi/drivers/das1800.c
+++ zfcpdump-kernel-4.4/drivers/staging/comedi/drivers/das1800.c
@@ -567,14 +567,17 @@ static int das1800_cancel(struct comedi_
 	struct comedi_isadma_desc *desc;
 	int i;
 
-	outb(0x0, dev->iobase + DAS1800_STATUS);	/* disable conversions */
-	outb(0x0, dev->iobase + DAS1800_CONTROL_B);	/* disable interrupts and dma */
-	outb(0x0, dev->iobase + DAS1800_CONTROL_A);	/* disable and clear fifo and stop triggering */
-
-	for (i = 0; i < 2; i++) {
-		desc = &dma->desc[i];
-		if (desc->chan)
-			comedi_isadma_disable(desc->chan);
+	/* disable and stop conversions */
+	outb(0x0, dev->iobase + DAS1800_STATUS);
+	outb(0x0, dev->iobase + DAS1800_CONTROL_B);
+	outb(0x0, dev->iobase + DAS1800_CONTROL_A);
+
+	if (dma) {
+		for (i = 0; i < 2; i++) {
+			desc = &dma->desc[i];
+			if (desc->chan)
+				comedi_isadma_disable(desc->chan);
+		}
 	}
 
 	return 0;
@@ -934,13 +937,14 @@ static void das1800_ai_setup_dma(struct
 {
 	struct das1800_private *devpriv = dev->private;
 	struct comedi_isadma *dma = devpriv->dma;
-	struct comedi_isadma_desc *desc = &dma->desc[0];
+	struct comedi_isadma_desc *desc;
 	unsigned int bytes;
 
 	if ((devpriv->irq_dma_bits & DMA_ENABLED) == 0)
 		return;
 
 	dma->cur_dma = 0;
+	desc = &dma->desc[0];
 
 	/* determine a dma transfer size to fill buffer in 0.3 sec */
 	bytes = das1800_ai_transfer_size(dev, s, desc->maxsize, 300000000);
--- zfcpdump-kernel-4.4.orig/drivers/staging/comedi/drivers/ni_mio_common.c
+++ zfcpdump-kernel-4.4/drivers/staging/comedi/drivers/ni_mio_common.c
@@ -246,24 +246,24 @@ static void ni_writel(struct comedi_devi
 {
 	if (dev->mmio)
 		writel(data, dev->mmio + reg);
-
-	outl(data, dev->iobase + reg);
+	else
+		outl(data, dev->iobase + reg);
 }
 
 static void ni_writew(struct comedi_device *dev, uint16_t data, int reg)
 {
 	if (dev->mmio)
 		writew(data, dev->mmio + reg);
-
-	outw(data, dev->iobase + reg);
+	else
+		outw(data, dev->iobase + reg);
 }
 
 static void ni_writeb(struct comedi_device *dev, uint8_t data, int reg)
 {
 	if (dev->mmio)
 		writeb(data, dev->mmio + reg);
-
-	outb(data, dev->iobase + reg);
+	else
+		outb(data, dev->iobase + reg);
 }
 
 static uint32_t ni_readl(struct comedi_device *dev, int reg)
@@ -2823,7 +2823,15 @@ static int ni_ao_inttrig(struct comedi_d
 	int i;
 	static const int timeout = 1000;
 
-	if (trig_num != cmd->start_arg)
+	/*
+	 * Require trig_num == cmd->start_arg when cmd->start_src == TRIG_INT.
+	 * For backwards compatibility, also allow trig_num == 0 when
+	 * cmd->start_src != TRIG_INT (i.e. when cmd->start_src == TRIG_EXT);
+	 * in that case, the internal trigger is being used as a pre-trigger
+	 * before the external trigger.
+	 */
+	if (!(trig_num == cmd->start_arg ||
+	      (trig_num == 0 && cmd->start_src != TRIG_INT)))
 		return -EINVAL;
 
 	/* Null trig at beginning prevent ao start trigger from executing more than
@@ -5346,7 +5354,7 @@ static int ni_E_init(struct comedi_devic
 		s->maxdata	= (devpriv->is_m_series) ? 0xffffffff
 							 : 0x00ffffff;
 		s->insn_read	= ni_tio_insn_read;
-		s->insn_write	= ni_tio_insn_read;
+		s->insn_write	= ni_tio_insn_write;
 		s->insn_config	= ni_tio_insn_config;
 #ifdef PCIDMA
 		if (dev->irq && devpriv->mite) {
--- zfcpdump-kernel-4.4.orig/drivers/staging/comedi/drivers/ni_tiocmd.c
+++ zfcpdump-kernel-4.4/drivers/staging/comedi/drivers/ni_tiocmd.c
@@ -92,7 +92,7 @@ static int ni_tio_input_inttrig(struct c
 	unsigned long flags;
 	int ret = 0;
 
-	if (trig_num != cmd->start_src)
+	if (trig_num != cmd->start_arg)
 		return -EINVAL;
 
 	spin_lock_irqsave(&counter->lock, flags);
--- zfcpdump-kernel-4.4.orig/drivers/staging/fbtft/fbtft-core.c
+++ zfcpdump-kernel-4.4/drivers/staging/fbtft/fbtft-core.c
@@ -392,11 +392,11 @@ static void fbtft_update_display(struct
 
 	if (unlikely(timeit)) {
 		ts_end = ktime_get();
-		if (ktime_to_ns(par->update_time))
+		if (!ktime_to_ns(par->update_time))
 			par->update_time = ts_start;
 
-		par->update_time = ts_start;
 		fps = ktime_us_delta(ts_start, par->update_time);
+		par->update_time = ts_start;
 		fps = fps ? 1000000 / fps : 0;
 
 		throughput = ktime_us_delta(ts_end, ts_start);
--- zfcpdump-kernel-4.4.orig/drivers/staging/iio/accel/sca3000_core.c
+++ zfcpdump-kernel-4.4/drivers/staging/iio/accel/sca3000_core.c
@@ -595,7 +595,7 @@ static ssize_t sca3000_read_frequency(st
 		goto error_ret_mut;
 	ret = sca3000_read_ctrl_reg(st, SCA3000_REG_CTRL_SEL_OUT_CTRL);
 	mutex_unlock(&st->lock);
-	if (ret)
+	if (ret < 0)
 		goto error_ret;
 	val = ret;
 	if (base_freq > 0)
--- zfcpdump-kernel-4.4.orig/drivers/staging/iio/adc/ad7192.c
+++ zfcpdump-kernel-4.4/drivers/staging/iio/adc/ad7192.c
@@ -236,7 +236,7 @@ static int ad7192_setup(struct ad7192_st
 			st->mclk = pdata->ext_clk_hz;
 		else
 			st->mclk = AD7192_INT_FREQ_MHZ;
-			break;
+		break;
 	default:
 		ret = -EINVAL;
 		goto out;
--- zfcpdump-kernel-4.4.orig/drivers/staging/lustre/lustre/llite/llite_internal.h
+++ zfcpdump-kernel-4.4/drivers/staging/lustre/lustre/llite/llite_internal.h
@@ -631,8 +631,6 @@ struct ll_file_data {
 
 struct lov_stripe_md;
 
-extern spinlock_t inode_lock;
-
 extern struct dentry *llite_root;
 extern struct kset *llite_kset;
 
--- zfcpdump-kernel-4.4.orig/drivers/staging/panel/panel.c
+++ zfcpdump-kernel-4.4/drivers/staging/panel/panel.c
@@ -825,8 +825,7 @@ static void lcd_write_cmd_s(int cmd)
 	lcd_send_serial(0x1F);	/* R/W=W, RS=0 */
 	lcd_send_serial(cmd & 0x0F);
 	lcd_send_serial((cmd >> 4) & 0x0F);
-	/* the shortest command takes at least 40 us */
-	usleep_range(40, 100);
+	udelay(40);		/* the shortest command takes at least 40 us */
 	spin_unlock_irq(&pprt_lock);
 }
 
@@ -837,8 +836,7 @@ static void lcd_write_data_s(int data)
 	lcd_send_serial(0x5F);	/* R/W=W, RS=1 */
 	lcd_send_serial(data & 0x0F);
 	lcd_send_serial((data >> 4) & 0x0F);
-	/* the shortest data takes at least 40 us */
-	usleep_range(40, 100);
+	udelay(40);		/* the shortest data takes at least 40 us */
 	spin_unlock_irq(&pprt_lock);
 }
 
@@ -848,20 +846,19 @@ static void lcd_write_cmd_p8(int cmd)
 	spin_lock_irq(&pprt_lock);
 	/* present the data to the data port */
 	w_dtr(pprt, cmd);
-	/* maintain the data during 20 us before the strobe */
-	usleep_range(20, 100);
+	udelay(20);	/* maintain the data during 20 us before the strobe */
 
 	bits.e = BIT_SET;
 	bits.rs = BIT_CLR;
 	bits.rw = BIT_CLR;
 	set_ctrl_bits();
 
-	usleep_range(40, 100);	/* maintain the strobe during 40 us */
+	udelay(40);	/* maintain the strobe during 40 us */
 
 	bits.e = BIT_CLR;
 	set_ctrl_bits();
 
-	usleep_range(120, 500);	/* the shortest command takes at least 120 us */
+	udelay(120);	/* the shortest command takes at least 120 us */
 	spin_unlock_irq(&pprt_lock);
 }
 
@@ -871,20 +868,19 @@ static void lcd_write_data_p8(int data)
 	spin_lock_irq(&pprt_lock);
 	/* present the data to the data port */
 	w_dtr(pprt, data);
-	/* maintain the data during 20 us before the strobe */
-	usleep_range(20, 100);
+	udelay(20);	/* maintain the data during 20 us before the strobe */
 
 	bits.e = BIT_SET;
 	bits.rs = BIT_SET;
 	bits.rw = BIT_CLR;
 	set_ctrl_bits();
 
-	usleep_range(40, 100);	/* maintain the strobe during 40 us */
+	udelay(40);	/* maintain the strobe during 40 us */
 
 	bits.e = BIT_CLR;
 	set_ctrl_bits();
 
-	usleep_range(45, 100);	/* the shortest data takes at least 45 us */
+	udelay(45);	/* the shortest data takes at least 45 us */
 	spin_unlock_irq(&pprt_lock);
 }
 
@@ -894,7 +890,7 @@ static void lcd_write_cmd_tilcd(int cmd)
 	spin_lock_irq(&pprt_lock);
 	/* present the data to the control port */
 	w_ctr(pprt, cmd);
-	usleep_range(60, 120);
+	udelay(60);
 	spin_unlock_irq(&pprt_lock);
 }
 
@@ -904,7 +900,7 @@ static void lcd_write_data_tilcd(int dat
 	spin_lock_irq(&pprt_lock);
 	/* present the data to the data port */
 	w_dtr(pprt, data);
-	usleep_range(60, 120);
+	udelay(60);
 	spin_unlock_irq(&pprt_lock);
 }
 
@@ -947,7 +943,7 @@ static void lcd_clear_fast_s(void)
 		lcd_send_serial(0x5F);	/* R/W=W, RS=1 */
 		lcd_send_serial(' ' & 0x0F);
 		lcd_send_serial((' ' >> 4) & 0x0F);
-		usleep_range(40, 100);	/* the shortest data takes at least 40 us */
+		udelay(40);	/* the shortest data takes at least 40 us */
 	}
 	spin_unlock_irq(&pprt_lock);
 
@@ -971,7 +967,7 @@ static void lcd_clear_fast_p8(void)
 		w_dtr(pprt, ' ');
 
 		/* maintain the data during 20 us before the strobe */
-		usleep_range(20, 100);
+		udelay(20);
 
 		bits.e = BIT_SET;
 		bits.rs = BIT_SET;
@@ -979,13 +975,13 @@ static void lcd_clear_fast_p8(void)
 		set_ctrl_bits();
 
 		/* maintain the strobe during 40 us */
-		usleep_range(40, 100);
+		udelay(40);
 
 		bits.e = BIT_CLR;
 		set_ctrl_bits();
 
 		/* the shortest data takes at least 45 us */
-		usleep_range(45, 100);
+		udelay(45);
 	}
 	spin_unlock_irq(&pprt_lock);
 
@@ -1007,7 +1003,7 @@ static void lcd_clear_fast_tilcd(void)
 	for (pos = 0; pos < lcd.height * lcd.hwidth; pos++) {
 		/* present the data to the data port */
 		w_dtr(pprt, ' ');
-		usleep_range(60, 120);
+		udelay(60);
 	}
 
 	spin_unlock_irq(&pprt_lock);
--- zfcpdump-kernel-4.4.orig/drivers/staging/rdma/hfi1/TODO
+++ zfcpdump-kernel-4.4/drivers/staging/rdma/hfi1/TODO
@@ -3,4 +3,4 @@ July, 2015
 - Remove unneeded file entries in sysfs
 - Remove software processing of IB protocol and place in library for use
   by qib, ipath (if still present), hfi1, and eventually soft-roce
-
+- Replace incorrect uAPI
--- zfcpdump-kernel-4.4.orig/drivers/staging/rdma/hfi1/file_ops.c
+++ zfcpdump-kernel-4.4/drivers/staging/rdma/hfi1/file_ops.c
@@ -62,6 +62,8 @@
 #include <linux/cred.h>
 #include <linux/uio.h>
 
+#include <rdma/ib.h>
+
 #include "hfi.h"
 #include "pio.h"
 #include "device.h"
@@ -214,6 +216,10 @@ static ssize_t hfi1_file_write(struct fi
 	int uctxt_required = 1;
 	int must_be_root = 0;
 
+	/* FIXME: This interface cannot continue out of staging */
+	if (WARN_ON_ONCE(!ib_safe_file_access(fp)))
+		return -EACCES;
+
 	if (count < sizeof(cmd)) {
 		ret = -EINVAL;
 		goto bail;
--- zfcpdump-kernel-4.4.orig/drivers/staging/rdma/ipath/ipath_file_ops.c
+++ zfcpdump-kernel-4.4/drivers/staging/rdma/ipath/ipath_file_ops.c
@@ -45,6 +45,8 @@
 #include <linux/uio.h>
 #include <asm/pgtable.h>
 
+#include <rdma/ib.h>
+
 #include "ipath_kernel.h"
 #include "ipath_common.h"
 #include "ipath_user_sdma.h"
@@ -2243,6 +2245,9 @@ static ssize_t ipath_write(struct file *
 	ssize_t ret = 0;
 	void *dest;
 
+	if (WARN_ON_ONCE(!ib_safe_file_access(fp)))
+		return -EACCES;
+
 	if (count < sizeof(cmd.type)) {
 		ret = -EINVAL;
 		goto bail;
--- zfcpdump-kernel-4.4.orig/drivers/staging/speakup/selection.c
+++ zfcpdump-kernel-4.4/drivers/staging/speakup/selection.c
@@ -142,7 +142,9 @@ static void __speakup_paste_selection(st
 	struct tty_ldisc *ld;
 	DECLARE_WAITQUEUE(wait, current);
 
-	ld = tty_ldisc_ref_wait(tty);
+	ld = tty_ldisc_ref(tty);
+	if (!ld)
+		goto tty_unref;
 	tty_buffer_lock_exclusive(&vc->port);
 
 	add_wait_queue(&vc->paste_wait, &wait);
@@ -162,6 +164,7 @@ static void __speakup_paste_selection(st
 
 	tty_buffer_unlock_exclusive(&vc->port);
 	tty_ldisc_deref(ld);
+tty_unref:
 	tty_kref_put(tty);
 }
 
--- zfcpdump-kernel-4.4.orig/drivers/staging/speakup/serialio.c
+++ zfcpdump-kernel-4.4/drivers/staging/speakup/serialio.c
@@ -6,6 +6,11 @@
 #include "spk_priv.h"
 #include "serialio.h"
 
+#include <linux/serial_core.h>
+/* WARNING:  Do not change this to <linux/serial.h> without testing that
+ * SERIAL_PORT_DFNS does get defined to the appropriate value. */
+#include <asm/serial.h>
+
 #ifndef SERIAL_PORT_DFNS
 #define SERIAL_PORT_DFNS
 #endif
@@ -23,9 +28,15 @@ const struct old_serial_port *spk_serial
 	int baud = 9600, quot = 0;
 	unsigned int cval = 0;
 	int cflag = CREAD | HUPCL | CLOCAL | B9600 | CS8;
-	const struct old_serial_port *ser = rs_table + index;
+	const struct old_serial_port *ser;
 	int err;
 
+	if (index >= ARRAY_SIZE(rs_table)) {
+		pr_info("no port info for ttyS%d\n", index);
+		return NULL;
+	}
+	ser = rs_table + index;
+
 	/*	Divisor, bytesize and parity */
 	quot = ser->baud_base / baud;
 	cval = cflag & (CSIZE | CSTOPB);
--- zfcpdump-kernel-4.4.orig/drivers/target/iscsi/iscsi_target.c
+++ zfcpdump-kernel-4.4/drivers/target/iscsi/iscsi_target.c
@@ -492,7 +492,8 @@ static void iscsit_aborted_task(struct i
 	bool scsi_cmd = (cmd->iscsi_opcode == ISCSI_OP_SCSI_CMD);
 
 	spin_lock_bh(&conn->cmd_lock);
-	if (!list_empty(&cmd->i_conn_node))
+	if (!list_empty(&cmd->i_conn_node) &&
+	    !(cmd->se_cmd.transport_state & CMD_T_FABRIC_STOP))
 		list_del_init(&cmd->i_conn_node);
 	spin_unlock_bh(&conn->cmd_lock);
 
@@ -4194,6 +4195,7 @@ transport_err:
 
 static void iscsit_release_commands_from_conn(struct iscsi_conn *conn)
 {
+	LIST_HEAD(tmp_list);
 	struct iscsi_cmd *cmd = NULL, *cmd_tmp = NULL;
 	struct iscsi_session *sess = conn->sess;
 	/*
@@ -4202,18 +4204,26 @@ static void iscsit_release_commands_from
 	 * has been reset -> returned sleeping pre-handler state.
 	 */
 	spin_lock_bh(&conn->cmd_lock);
-	list_for_each_entry_safe(cmd, cmd_tmp, &conn->conn_cmd_list, i_conn_node) {
+	list_splice_init(&conn->conn_cmd_list, &tmp_list);
 
+	list_for_each_entry(cmd, &tmp_list, i_conn_node) {
+		struct se_cmd *se_cmd = &cmd->se_cmd;
+
+		if (se_cmd->se_tfo != NULL) {
+			spin_lock(&se_cmd->t_state_lock);
+			se_cmd->transport_state |= CMD_T_FABRIC_STOP;
+			spin_unlock(&se_cmd->t_state_lock);
+		}
+	}
+	spin_unlock_bh(&conn->cmd_lock);
+
+	list_for_each_entry_safe(cmd, cmd_tmp, &tmp_list, i_conn_node) {
 		list_del_init(&cmd->i_conn_node);
-		spin_unlock_bh(&conn->cmd_lock);
 
 		iscsit_increment_maxcmdsn(cmd, sess);
-
 		iscsit_free_cmd(cmd, true);
 
-		spin_lock_bh(&conn->cmd_lock);
 	}
-	spin_unlock_bh(&conn->cmd_lock);
 }
 
 static void iscsit_stop_timers_for_cmds(
--- zfcpdump-kernel-4.4.orig/drivers/target/iscsi/iscsi_target_configfs.c
+++ zfcpdump-kernel-4.4/drivers/target/iscsi/iscsi_target_configfs.c
@@ -1593,7 +1593,8 @@ static int lio_tpg_check_prot_fabric_onl
 }
 
 /*
- * Called with spin_lock_bh(struct se_portal_group->session_lock) held..
+ * Called with spin_lock_irq(struct se_portal_group->session_lock) held
+ * or not held.
  *
  * Also, this function calls iscsit_inc_session_usage_count() on the
  * struct iscsi_session in question.
@@ -1601,19 +1602,32 @@ static int lio_tpg_check_prot_fabric_onl
 static int lio_tpg_shutdown_session(struct se_session *se_sess)
 {
 	struct iscsi_session *sess = se_sess->fabric_sess_ptr;
+	struct se_portal_group *se_tpg = se_sess->se_tpg;
+	bool local_lock = false;
+
+	if (!spin_is_locked(&se_tpg->session_lock)) {
+		spin_lock_irq(&se_tpg->session_lock);
+		local_lock = true;
+	}
 
 	spin_lock(&sess->conn_lock);
 	if (atomic_read(&sess->session_fall_back_to_erl0) ||
 	    atomic_read(&sess->session_logout) ||
 	    (sess->time2retain_timer_flags & ISCSI_TF_EXPIRED)) {
 		spin_unlock(&sess->conn_lock);
+		if (local_lock)
+			spin_unlock_irq(&sess->conn_lock);
 		return 0;
 	}
 	atomic_set(&sess->session_reinstatement, 1);
 	spin_unlock(&sess->conn_lock);
 
 	iscsit_stop_time2retain_timer(sess);
+	spin_unlock_irq(&se_tpg->session_lock);
+
 	iscsit_stop_session(sess, 1, 1);
+	if (!local_lock)
+		spin_lock_irq(&se_tpg->session_lock);
 
 	return 1;
 }
--- zfcpdump-kernel-4.4.orig/drivers/target/iscsi/iscsi_target_login.c
+++ zfcpdump-kernel-4.4/drivers/target/iscsi/iscsi_target_login.c
@@ -1357,8 +1357,9 @@ static int __iscsi_target_login_thread(s
 	}
 	login->zero_tsih = zero_tsih;
 
-	conn->sess->se_sess->sup_prot_ops =
-		conn->conn_transport->iscsit_get_sup_prot_ops(conn);
+	if (conn->sess)
+		conn->sess->se_sess->sup_prot_ops =
+			conn->conn_transport->iscsit_get_sup_prot_ops(conn);
 
 	tpg = conn->tpg;
 	if (!tpg) {
--- zfcpdump-kernel-4.4.orig/drivers/target/target_core_device.c
+++ zfcpdump-kernel-4.4/drivers/target/target_core_device.c
@@ -826,6 +826,51 @@ struct se_device *target_alloc_device(st
 	return dev;
 }
 
+/*
+ * Check if the underlying struct block_device request_queue supports
+ * the QUEUE_FLAG_DISCARD bit for UNMAP/WRITE_SAME in SCSI + TRIM
+ * in ATA and we need to set TPE=1
+ */
+bool target_configure_unmap_from_queue(struct se_dev_attrib *attrib,
+				       struct request_queue *q)
+{
+	int block_size = queue_logical_block_size(q);
+
+	if (!blk_queue_discard(q))
+		return false;
+
+	attrib->max_unmap_lba_count =
+		q->limits.max_discard_sectors >> (ilog2(block_size) - 9);
+	/*
+	 * Currently hardcoded to 1 in Linux/SCSI code..
+	 */
+	attrib->max_unmap_block_desc_count = 1;
+	attrib->unmap_granularity = q->limits.discard_granularity / block_size;
+	attrib->unmap_granularity_alignment = q->limits.discard_alignment /
+								block_size;
+	return true;
+}
+EXPORT_SYMBOL(target_configure_unmap_from_queue);
+
+/*
+ * Convert from blocksize advertised to the initiator to the 512 byte
+ * units unconditionally used by the Linux block layer.
+ */
+sector_t target_to_linux_sector(struct se_device *dev, sector_t lb)
+{
+	switch (dev->dev_attrib.block_size) {
+	case 4096:
+		return lb << 3;
+	case 2048:
+		return lb << 2;
+	case 1024:
+		return lb << 1;
+	default:
+		return lb;
+	}
+}
+EXPORT_SYMBOL(target_to_linux_sector);
+
 int target_configure_device(struct se_device *dev)
 {
 	struct se_hba *hba = dev->se_hba;
--- zfcpdump-kernel-4.4.orig/drivers/target/target_core_file.c
+++ zfcpdump-kernel-4.4/drivers/target/target_core_file.c
@@ -160,25 +160,10 @@ static int fd_configure_device(struct se
 			" block_device blocks: %llu logical_block_size: %d\n",
 			dev_size, div_u64(dev_size, fd_dev->fd_block_size),
 			fd_dev->fd_block_size);
-		/*
-		 * Check if the underlying struct block_device request_queue supports
-		 * the QUEUE_FLAG_DISCARD bit for UNMAP/WRITE_SAME in SCSI + TRIM
-		 * in ATA and we need to set TPE=1
-		 */
-		if (blk_queue_discard(q)) {
-			dev->dev_attrib.max_unmap_lba_count =
-				q->limits.max_discard_sectors;
-			/*
-			 * Currently hardcoded to 1 in Linux/SCSI code..
-			 */
-			dev->dev_attrib.max_unmap_block_desc_count = 1;
-			dev->dev_attrib.unmap_granularity =
-				q->limits.discard_granularity >> 9;
-			dev->dev_attrib.unmap_granularity_alignment =
-				q->limits.discard_alignment;
+
+		if (target_configure_unmap_from_queue(&dev->dev_attrib, q))
 			pr_debug("IFILE: BLOCK Discard support available,"
-					" disabled by default\n");
-		}
+				 " disabled by default\n");
 		/*
 		 * Enable write same emulation for IBLOCK and use 0xFFFF as
 		 * the smaller WRITE_SAME(10) only has a two-byte block count.
@@ -490,9 +475,12 @@ fd_execute_unmap(struct se_cmd *cmd, sec
 	if (S_ISBLK(inode->i_mode)) {
 		/* The backend is block device, use discard */
 		struct block_device *bdev = inode->i_bdev;
+		struct se_device *dev = cmd->se_dev;
 
-		ret = blkdev_issue_discard(bdev, lba,
-				nolb, GFP_KERNEL, 0);
+		ret = blkdev_issue_discard(bdev,
+					   target_to_linux_sector(dev, lba),
+					   target_to_linux_sector(dev,  nolb),
+					   GFP_KERNEL, 0);
 		if (ret < 0) {
 			pr_warn("FILEIO: blkdev_issue_discard() failed: %d\n",
 				ret);
--- zfcpdump-kernel-4.4.orig/drivers/target/target_core_iblock.c
+++ zfcpdump-kernel-4.4/drivers/target/target_core_iblock.c
@@ -121,27 +121,10 @@ static int iblock_configure_device(struc
 	dev->dev_attrib.hw_max_sectors = queue_max_hw_sectors(q);
 	dev->dev_attrib.hw_queue_depth = q->nr_requests;
 
-	/*
-	 * Check if the underlying struct block_device request_queue supports
-	 * the QUEUE_FLAG_DISCARD bit for UNMAP/WRITE_SAME in SCSI + TRIM
-	 * in ATA and we need to set TPE=1
-	 */
-	if (blk_queue_discard(q)) {
-		dev->dev_attrib.max_unmap_lba_count =
-				q->limits.max_discard_sectors;
-
-		/*
-		 * Currently hardcoded to 1 in Linux/SCSI code..
-		 */
-		dev->dev_attrib.max_unmap_block_desc_count = 1;
-		dev->dev_attrib.unmap_granularity =
-				q->limits.discard_granularity >> 9;
-		dev->dev_attrib.unmap_granularity_alignment =
-				q->limits.discard_alignment;
-
+	if (target_configure_unmap_from_queue(&dev->dev_attrib, q))
 		pr_debug("IBLOCK: BLOCK Discard support available,"
-				" disabled by default\n");
-	}
+			 " disabled by default\n");
+
 	/*
 	 * Enable write same emulation for IBLOCK and use 0xFFFF as
 	 * the smaller WRITE_SAME(10) only has a two-byte block count.
@@ -413,9 +396,13 @@ static sense_reason_t
 iblock_execute_unmap(struct se_cmd *cmd, sector_t lba, sector_t nolb)
 {
 	struct block_device *bdev = IBLOCK_DEV(cmd->se_dev)->ibd_bd;
+	struct se_device *dev = cmd->se_dev;
 	int ret;
 
-	ret = blkdev_issue_discard(bdev, lba, nolb, GFP_KERNEL, 0);
+	ret = blkdev_issue_discard(bdev,
+				   target_to_linux_sector(dev, lba),
+				   target_to_linux_sector(dev,  nolb),
+				   GFP_KERNEL, 0);
 	if (ret < 0) {
 		pr_err("blkdev_issue_discard() failed: %d\n", ret);
 		return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
@@ -431,8 +418,10 @@ iblock_execute_write_same(struct se_cmd
 	struct scatterlist *sg;
 	struct bio *bio;
 	struct bio_list list;
-	sector_t block_lba = cmd->t_task_lba;
-	sector_t sectors = sbc_get_write_same_sectors(cmd);
+	struct se_device *dev = cmd->se_dev;
+	sector_t block_lba = target_to_linux_sector(dev, cmd->t_task_lba);
+	sector_t sectors = target_to_linux_sector(dev,
+					sbc_get_write_same_sectors(cmd));
 
 	if (cmd->prot_op) {
 		pr_err("WRITE_SAME: Protection information with IBLOCK"
@@ -613,9 +602,9 @@ iblock_alloc_bip(struct se_cmd *cmd, str
 	}
 
 	bip = bio_integrity_alloc(bio, GFP_NOIO, cmd->t_prot_nents);
-	if (!bip) {
+	if (IS_ERR(bip)) {
 		pr_err("Unable to allocate bio_integrity_payload\n");
-		return -ENOMEM;
+		return PTR_ERR(bip);
 	}
 
 	bip->bip_iter.bi_size = (cmd->data_length / dev->dev_attrib.block_size) *
@@ -646,12 +635,12 @@ iblock_execute_rw(struct se_cmd *cmd, st
 		  enum dma_data_direction data_direction)
 {
 	struct se_device *dev = cmd->se_dev;
+	sector_t block_lba = target_to_linux_sector(dev, cmd->t_task_lba);
 	struct iblock_req *ibr;
 	struct bio *bio, *bio_start;
 	struct bio_list list;
 	struct scatterlist *sg;
 	u32 sg_num = sgl_nents;
-	sector_t block_lba;
 	unsigned bio_cnt;
 	int rw = 0;
 	int i;
@@ -677,24 +666,6 @@ iblock_execute_rw(struct se_cmd *cmd, st
 		rw = READ;
 	}
 
-	/*
-	 * Convert the blocksize advertised to the initiator to the 512 byte
-	 * units unconditionally used by the Linux block layer.
-	 */
-	if (dev->dev_attrib.block_size == 4096)
-		block_lba = (cmd->t_task_lba << 3);
-	else if (dev->dev_attrib.block_size == 2048)
-		block_lba = (cmd->t_task_lba << 2);
-	else if (dev->dev_attrib.block_size == 1024)
-		block_lba = (cmd->t_task_lba << 1);
-	else if (dev->dev_attrib.block_size == 512)
-		block_lba = cmd->t_task_lba;
-	else {
-		pr_err("Unsupported SCSI -> BLOCK LBA conversion:"
-				" %u\n", dev->dev_attrib.block_size);
-		return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
-	}
-
 	ibr = kzalloc(sizeof(struct iblock_req), GFP_KERNEL);
 	if (!ibr)
 		goto fail;
--- zfcpdump-kernel-4.4.orig/drivers/target/target_core_internal.h
+++ zfcpdump-kernel-4.4/drivers/target/target_core_internal.h
@@ -148,6 +148,7 @@ sense_reason_t	target_cmd_size_check(str
 void	target_qf_do_work(struct work_struct *work);
 bool	target_check_wce(struct se_device *dev);
 bool	target_check_fua(struct se_device *dev);
+void	__target_execute_cmd(struct se_cmd *, bool);
 
 /* target_core_stat.c */
 void	target_stat_setup_dev_default_groups(struct se_device *);
--- zfcpdump-kernel-4.4.orig/drivers/target/target_core_sbc.c
+++ zfcpdump-kernel-4.4/drivers/target/target_core_sbc.c
@@ -594,7 +594,7 @@ static sense_reason_t compare_and_write_
 	cmd->transport_state |= CMD_T_ACTIVE|CMD_T_BUSY|CMD_T_SENT;
 	spin_unlock_irq(&cmd->t_state_lock);
 
-	__target_execute_cmd(cmd);
+	__target_execute_cmd(cmd, false);
 
 	kfree(buf);
 	return ret;
--- zfcpdump-kernel-4.4.orig/drivers/target/target_core_tmr.c
+++ zfcpdump-kernel-4.4/drivers/target/target_core_tmr.c
@@ -68,23 +68,25 @@ void core_tmr_release_req(struct se_tmr_
 
 	if (dev) {
 		spin_lock_irqsave(&dev->se_tmr_lock, flags);
-		list_del(&tmr->tmr_list);
+		list_del_init(&tmr->tmr_list);
 		spin_unlock_irqrestore(&dev->se_tmr_lock, flags);
 	}
 
 	kfree(tmr);
 }
 
-static void core_tmr_handle_tas_abort(
-	struct se_node_acl *tmr_nacl,
-	struct se_cmd *cmd,
-	int tas)
+static void core_tmr_handle_tas_abort(struct se_cmd *cmd, int tas)
 {
-	bool remove = true;
+	unsigned long flags;
+	bool remove = true, send_tas;
 	/*
 	 * TASK ABORTED status (TAS) bit support
 	 */
-	if ((tmr_nacl && (tmr_nacl != cmd->se_sess->se_node_acl)) && tas) {
+	spin_lock_irqsave(&cmd->t_state_lock, flags);
+	send_tas = (cmd->transport_state & CMD_T_TAS);
+	spin_unlock_irqrestore(&cmd->t_state_lock, flags);
+
+	if (send_tas) {
 		remove = false;
 		transport_send_task_abort(cmd);
 	}
@@ -107,6 +109,46 @@ static int target_check_cdb_and_preempt(
 	return 1;
 }
 
+static bool __target_check_io_state(struct se_cmd *se_cmd,
+				    struct se_session *tmr_sess, int tas)
+{
+	struct se_session *sess = se_cmd->se_sess;
+
+	assert_spin_locked(&sess->sess_cmd_lock);
+	WARN_ON_ONCE(!irqs_disabled());
+	/*
+	 * If command already reached CMD_T_COMPLETE state within
+	 * target_complete_cmd() or CMD_T_FABRIC_STOP due to shutdown,
+	 * this se_cmd has been passed to fabric driver and will
+	 * not be aborted.
+	 *
+	 * Otherwise, obtain a local se_cmd->cmd_kref now for TMR
+	 * ABORT_TASK + LUN_RESET for CMD_T_ABORTED processing as
+	 * long as se_cmd->cmd_kref is still active unless zero.
+	 */
+	spin_lock(&se_cmd->t_state_lock);
+	if (se_cmd->transport_state & (CMD_T_COMPLETE | CMD_T_FABRIC_STOP)) {
+		pr_debug("Attempted to abort io tag: %llu already complete or"
+			" fabric stop, skipping\n", se_cmd->tag);
+		spin_unlock(&se_cmd->t_state_lock);
+		return false;
+	}
+	if (sess->sess_tearing_down || se_cmd->cmd_wait_set) {
+		pr_debug("Attempted to abort io tag: %llu already shutdown,"
+			" skipping\n", se_cmd->tag);
+		spin_unlock(&se_cmd->t_state_lock);
+		return false;
+	}
+	se_cmd->transport_state |= CMD_T_ABORTED;
+
+	if ((tmr_sess != se_cmd->se_sess) && tas)
+		se_cmd->transport_state |= CMD_T_TAS;
+
+	spin_unlock(&se_cmd->t_state_lock);
+
+	return kref_get_unless_zero(&se_cmd->cmd_kref);
+}
+
 void core_tmr_abort_task(
 	struct se_device *dev,
 	struct se_tmr_req *tmr,
@@ -130,34 +172,21 @@ void core_tmr_abort_task(
 		if (tmr->ref_task_tag != ref_tag)
 			continue;
 
-		if (!kref_get_unless_zero(&se_cmd->cmd_kref))
-			continue;
-
 		printk("ABORT_TASK: Found referenced %s task_tag: %llu\n",
 			se_cmd->se_tfo->get_fabric_name(), ref_tag);
 
-		spin_lock(&se_cmd->t_state_lock);
-		if (se_cmd->transport_state & CMD_T_COMPLETE) {
-			printk("ABORT_TASK: ref_tag: %llu already complete,"
-			       " skipping\n", ref_tag);
-			spin_unlock(&se_cmd->t_state_lock);
+		if (!__target_check_io_state(se_cmd, se_sess, 0)) {
 			spin_unlock_irqrestore(&se_sess->sess_cmd_lock, flags);
-
-			target_put_sess_cmd(se_cmd);
-
 			goto out;
 		}
-		se_cmd->transport_state |= CMD_T_ABORTED;
-		spin_unlock(&se_cmd->t_state_lock);
-
 		list_del_init(&se_cmd->se_cmd_list);
 		spin_unlock_irqrestore(&se_sess->sess_cmd_lock, flags);
 
 		cancel_work_sync(&se_cmd->work);
 		transport_wait_for_tasks(se_cmd);
 
-		target_put_sess_cmd(se_cmd);
 		transport_cmd_finish_abort(se_cmd, true);
+		target_put_sess_cmd(se_cmd);
 
 		printk("ABORT_TASK: Sending TMR_FUNCTION_COMPLETE for"
 				" ref_tag: %llu\n", ref_tag);
@@ -178,9 +207,11 @@ static void core_tmr_drain_tmr_list(
 	struct list_head *preempt_and_abort_list)
 {
 	LIST_HEAD(drain_tmr_list);
+	struct se_session *sess;
 	struct se_tmr_req *tmr_p, *tmr_pp;
 	struct se_cmd *cmd;
 	unsigned long flags;
+	bool rc;
 	/*
 	 * Release all pending and outgoing TMRs aside from the received
 	 * LUN_RESET tmr..
@@ -206,17 +237,39 @@ static void core_tmr_drain_tmr_list(
 		if (target_check_cdb_and_preempt(preempt_and_abort_list, cmd))
 			continue;
 
+		sess = cmd->se_sess;
+		if (WARN_ON_ONCE(!sess))
+			continue;
+
+		spin_lock(&sess->sess_cmd_lock);
 		spin_lock(&cmd->t_state_lock);
-		if (!(cmd->transport_state & CMD_T_ACTIVE)) {
+		if (!(cmd->transport_state & CMD_T_ACTIVE) ||
+		     (cmd->transport_state & CMD_T_FABRIC_STOP)) {
 			spin_unlock(&cmd->t_state_lock);
+			spin_unlock(&sess->sess_cmd_lock);
 			continue;
 		}
 		if (cmd->t_state == TRANSPORT_ISTATE_PROCESSING) {
 			spin_unlock(&cmd->t_state_lock);
+			spin_unlock(&sess->sess_cmd_lock);
 			continue;
 		}
+		if (sess->sess_tearing_down || cmd->cmd_wait_set) {
+			spin_unlock(&cmd->t_state_lock);
+			spin_unlock(&sess->sess_cmd_lock);
+			continue;
+		}
+		cmd->transport_state |= CMD_T_ABORTED;
 		spin_unlock(&cmd->t_state_lock);
 
+		rc = kref_get_unless_zero(&cmd->cmd_kref);
+		if (!rc) {
+			printk("LUN_RESET TMR: non-zero kref_get_unless_zero\n");
+			spin_unlock(&sess->sess_cmd_lock);
+			continue;
+		}
+		spin_unlock(&sess->sess_cmd_lock);
+
 		list_move_tail(&tmr_p->tmr_list, &drain_tmr_list);
 	}
 	spin_unlock_irqrestore(&dev->se_tmr_lock, flags);
@@ -230,20 +283,26 @@ static void core_tmr_drain_tmr_list(
 			(preempt_and_abort_list) ? "Preempt" : "", tmr_p,
 			tmr_p->function, tmr_p->response, cmd->t_state);
 
+		cancel_work_sync(&cmd->work);
+		transport_wait_for_tasks(cmd);
+
 		transport_cmd_finish_abort(cmd, 1);
+		target_put_sess_cmd(cmd);
 	}
 }
 
 static void core_tmr_drain_state_list(
 	struct se_device *dev,
 	struct se_cmd *prout_cmd,
-	struct se_node_acl *tmr_nacl,
+	struct se_session *tmr_sess,
 	int tas,
 	struct list_head *preempt_and_abort_list)
 {
 	LIST_HEAD(drain_task_list);
+	struct se_session *sess;
 	struct se_cmd *cmd, *next;
 	unsigned long flags;
+	int rc;
 
 	/*
 	 * Complete outstanding commands with TASK_ABORTED SAM status.
@@ -282,6 +341,16 @@ static void core_tmr_drain_state_list(
 		if (prout_cmd == cmd)
 			continue;
 
+		sess = cmd->se_sess;
+		if (WARN_ON_ONCE(!sess))
+			continue;
+
+		spin_lock(&sess->sess_cmd_lock);
+		rc = __target_check_io_state(cmd, tmr_sess, tas);
+		spin_unlock(&sess->sess_cmd_lock);
+		if (!rc)
+			continue;
+
 		list_move_tail(&cmd->state_list, &drain_task_list);
 		cmd->state_active = false;
 	}
@@ -289,7 +358,7 @@ static void core_tmr_drain_state_list(
 
 	while (!list_empty(&drain_task_list)) {
 		cmd = list_entry(drain_task_list.next, struct se_cmd, state_list);
-		list_del(&cmd->state_list);
+		list_del_init(&cmd->state_list);
 
 		pr_debug("LUN_RESET: %s cmd: %p"
 			" ITT/CmdSN: 0x%08llx/0x%08x, i_state: %d, t_state: %d"
@@ -313,16 +382,11 @@ static void core_tmr_drain_state_list(
 		 * loop above, but we do it down here given that
 		 * cancel_work_sync may block.
 		 */
-		if (cmd->t_state == TRANSPORT_COMPLETE)
-			cancel_work_sync(&cmd->work);
-
-		spin_lock_irqsave(&cmd->t_state_lock, flags);
-		target_stop_cmd(cmd, &flags);
-
-		cmd->transport_state |= CMD_T_ABORTED;
-		spin_unlock_irqrestore(&cmd->t_state_lock, flags);
+		cancel_work_sync(&cmd->work);
+		transport_wait_for_tasks(cmd);
 
-		core_tmr_handle_tas_abort(tmr_nacl, cmd, tas);
+		core_tmr_handle_tas_abort(cmd, tas);
+		target_put_sess_cmd(cmd);
 	}
 }
 
@@ -334,6 +398,7 @@ int core_tmr_lun_reset(
 {
 	struct se_node_acl *tmr_nacl = NULL;
 	struct se_portal_group *tmr_tpg = NULL;
+	struct se_session *tmr_sess = NULL;
 	int tas;
         /*
 	 * TASK_ABORTED status bit, this is configurable via ConfigFS
@@ -352,8 +417,9 @@ int core_tmr_lun_reset(
 	 * or struct se_device passthrough..
 	 */
 	if (tmr && tmr->task_cmd && tmr->task_cmd->se_sess) {
-		tmr_nacl = tmr->task_cmd->se_sess->se_node_acl;
-		tmr_tpg = tmr->task_cmd->se_sess->se_tpg;
+		tmr_sess = tmr->task_cmd->se_sess;
+		tmr_nacl = tmr_sess->se_node_acl;
+		tmr_tpg = tmr_sess->se_tpg;
 		if (tmr_nacl && tmr_tpg) {
 			pr_debug("LUN_RESET: TMR caller fabric: %s"
 				" initiator port %s\n",
@@ -366,7 +432,7 @@ int core_tmr_lun_reset(
 		dev->transport->name, tas);
 
 	core_tmr_drain_tmr_list(dev, tmr, preempt_and_abort_list);
-	core_tmr_drain_state_list(dev, prout_cmd, tmr_nacl, tas,
+	core_tmr_drain_state_list(dev, prout_cmd, tmr_sess, tas,
 				preempt_and_abort_list);
 
 	/*
--- zfcpdump-kernel-4.4.orig/drivers/target/target_core_transport.c
+++ zfcpdump-kernel-4.4/drivers/target/target_core_transport.c
@@ -281,6 +281,17 @@ struct se_session *transport_init_sessio
 	struct se_session *se_sess;
 	int rc;
 
+	if (tag_num != 0 && !tag_size) {
+		pr_err("init_session_tags called with percpu-ida tag_num:"
+		       " %u, but zero tag_size\n", tag_num);
+		return ERR_PTR(-EINVAL);
+	}
+	if (!tag_num && tag_size) {
+		pr_err("init_session_tags called with percpu-ida tag_size:"
+		       " %u, but zero tag_num\n", tag_size);
+		return ERR_PTR(-EINVAL);
+	}
+
 	se_sess = transport_init_session(sup_prot_ops);
 	if (IS_ERR(se_sess))
 		return se_sess;
@@ -375,6 +386,51 @@ void transport_register_session(
 }
 EXPORT_SYMBOL(transport_register_session);
 
+struct se_session *
+target_alloc_session(struct se_portal_group *tpg,
+		     unsigned int tag_num, unsigned int tag_size,
+		     enum target_prot_op prot_op,
+		     const char *initiatorname, void *private,
+		     int (*callback)(struct se_portal_group *,
+				     struct se_session *, void *))
+{
+	struct se_session *sess;
+
+	/*
+	 * If the fabric driver is using percpu-ida based pre allocation
+	 * of I/O descriptor tags, go ahead and perform that setup now..
+	 */
+	if (tag_num != 0)
+		sess = transport_init_session_tags(tag_num, tag_size, prot_op);
+	else
+		sess = transport_init_session(prot_op);
+
+	if (IS_ERR(sess))
+		return sess;
+
+	sess->se_node_acl = core_tpg_check_initiator_node_acl(tpg,
+					(unsigned char *)initiatorname);
+	if (!sess->se_node_acl) {
+		transport_free_session(sess);
+		return ERR_PTR(-EACCES);
+	}
+	/*
+	 * Go ahead and perform any remaining fabric setup that is
+	 * required before transport_register_session().
+	 */
+	if (callback != NULL) {
+		int rc = callback(tpg, sess, private);
+		if (rc) {
+			transport_free_session(sess);
+			return ERR_PTR(rc);
+		}
+	}
+
+	transport_register_session(tpg, sess->se_node_acl, sess, private);
+	return sess;
+}
+EXPORT_SYMBOL(target_alloc_session);
+
 static void target_release_session(struct kref *kref)
 {
 	struct se_session *se_sess = container_of(kref,
@@ -528,9 +584,6 @@ void transport_deregister_session(struct
 }
 EXPORT_SYMBOL(transport_deregister_session);
 
-/*
- * Called with cmd->t_state_lock held.
- */
 static void target_remove_from_state_list(struct se_cmd *cmd)
 {
 	struct se_device *dev = cmd->se_dev;
@@ -555,10 +608,6 @@ static int transport_cmd_check_stop(stru
 {
 	unsigned long flags;
 
-	spin_lock_irqsave(&cmd->t_state_lock, flags);
-	if (write_pending)
-		cmd->t_state = TRANSPORT_WRITE_PENDING;
-
 	if (remove_from_lists) {
 		target_remove_from_state_list(cmd);
 
@@ -568,6 +617,10 @@ static int transport_cmd_check_stop(stru
 		cmd->se_lun = NULL;
 	}
 
+	spin_lock_irqsave(&cmd->t_state_lock, flags);
+	if (write_pending)
+		cmd->t_state = TRANSPORT_WRITE_PENDING;
+
 	/*
 	 * Determine if frontend context caller is requesting the stopping of
 	 * this command for frontend exceptions.
@@ -621,6 +674,8 @@ static void transport_lun_remove_cmd(str
 
 void transport_cmd_finish_abort(struct se_cmd *cmd, int remove)
 {
+	bool ack_kref = (cmd->se_cmd_flags & SCF_ACK_KREF);
+
 	if (cmd->se_cmd_flags & SCF_SE_LUN_CMD)
 		transport_lun_remove_cmd(cmd);
 	/*
@@ -632,7 +687,7 @@ void transport_cmd_finish_abort(struct s
 
 	if (transport_cmd_check_stop_to_fabric(cmd))
 		return;
-	if (remove)
+	if (remove && ack_kref)
 		transport_put_cmd(cmd);
 }
 
@@ -700,7 +755,7 @@ void target_complete_cmd(struct se_cmd *
 	 * Check for case where an explicit ABORT_TASK has been received
 	 * and transport_wait_for_tasks() will be waiting for completion..
 	 */
-	if (cmd->transport_state & CMD_T_ABORTED &&
+	if (cmd->transport_state & CMD_T_ABORTED ||
 	    cmd->transport_state & CMD_T_STOP) {
 		spin_unlock_irqrestore(&cmd->t_state_lock, flags);
 		complete_all(&cmd->t_transport_stop_comp);
@@ -715,7 +770,10 @@ void target_complete_cmd(struct se_cmd *
 	cmd->transport_state |= (CMD_T_COMPLETE | CMD_T_ACTIVE);
 	spin_unlock_irqrestore(&cmd->t_state_lock, flags);
 
-	queue_work(target_completion_wq, &cmd->work);
+	if (cmd->se_cmd_flags & SCF_USE_CPUID)
+		queue_work_on(cmd->cpuid, target_completion_wq, &cmd->work);
+	else
+		queue_work(target_completion_wq, &cmd->work);
 }
 EXPORT_SYMBOL(target_complete_cmd);
 
@@ -1271,23 +1329,6 @@ target_setup_cmd_from_cdb(struct se_cmd
 
 	trace_target_sequencer_start(cmd);
 
-	/*
-	 * Check for an existing UNIT ATTENTION condition
-	 */
-	ret = target_scsi3_ua_check(cmd);
-	if (ret)
-		return ret;
-
-	ret = target_alua_state_check(cmd);
-	if (ret)
-		return ret;
-
-	ret = target_check_reservation(cmd);
-	if (ret) {
-		cmd->scsi_status = SAM_STAT_RESERVATION_CONFLICT;
-		return ret;
-	}
-
 	ret = dev->transport->parse_cdb(cmd);
 	if (ret == TCM_UNSUPPORTED_SCSI_OPCODE)
 		pr_warn_ratelimited("%s/%s: Unsupported SCSI Opcode 0x%02x, sending CHECK_CONDITION.\n",
@@ -1428,6 +1469,12 @@ int target_submit_cmd_map_sgls(struct se
 	 */
 	transport_init_se_cmd(se_cmd, se_tpg->se_tpg_tfo, se_sess,
 				data_length, data_dir, task_attr, sense);
+
+	if (flags & TARGET_SCF_USE_CPUID)
+		se_cmd->se_cmd_flags |= SCF_USE_CPUID;
+	else
+		se_cmd->cpuid = WORK_CPU_UNBOUND;
+
 	if (flags & TARGET_SCF_UNKNOWN_SIZE)
 		se_cmd->unknown_data_length = 1;
 	/*
@@ -1750,20 +1797,45 @@ queue_full:
 }
 EXPORT_SYMBOL(transport_generic_request_failure);
 
-void __target_execute_cmd(struct se_cmd *cmd)
+void __target_execute_cmd(struct se_cmd *cmd, bool do_checks)
 {
 	sense_reason_t ret;
 
-	if (cmd->execute_cmd) {
-		ret = cmd->execute_cmd(cmd);
-		if (ret) {
-			spin_lock_irq(&cmd->t_state_lock);
-			cmd->transport_state &= ~(CMD_T_BUSY|CMD_T_SENT);
-			spin_unlock_irq(&cmd->t_state_lock);
+	if (!cmd->execute_cmd) {
+		ret = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
+		goto err;
+	}
+	if (do_checks) {
+		/*
+		 * Check for an existing UNIT ATTENTION condition after
+		 * target_handle_task_attr() has done SAM task attr
+		 * checking, and possibly have already defered execution
+		 * out to target_restart_delayed_cmds() context.
+		 */
+		ret = target_scsi3_ua_check(cmd);
+		if (ret)
+			goto err;
+
+		ret = target_alua_state_check(cmd);
+		if (ret)
+			goto err;
 
-			transport_generic_request_failure(cmd, ret);
+		ret = target_check_reservation(cmd);
+		if (ret) {
+			cmd->scsi_status = SAM_STAT_RESERVATION_CONFLICT;
+			goto err;
 		}
 	}
+
+	ret = cmd->execute_cmd(cmd);
+	if (!ret)
+		return;
+err:
+	spin_lock_irq(&cmd->t_state_lock);
+	cmd->transport_state &= ~(CMD_T_BUSY|CMD_T_SENT);
+	spin_unlock_irq(&cmd->t_state_lock);
+
+	transport_generic_request_failure(cmd, ret);
 }
 
 static int target_write_prot_action(struct se_cmd *cmd)
@@ -1808,6 +1880,8 @@ static bool target_handle_task_attr(stru
 	if (dev->transport->transport_flags & TRANSPORT_FLAG_PASSTHROUGH)
 		return false;
 
+	cmd->se_cmd_flags |= SCF_TASK_ATTR_SET;
+
 	/*
 	 * Check for the existence of HEAD_OF_QUEUE, and if true return 1
 	 * to allow the passed struct se_cmd list of tasks to the front of the list.
@@ -1850,19 +1924,21 @@ static bool target_handle_task_attr(stru
 	return true;
 }
 
+static int __transport_check_aborted_status(struct se_cmd *, int);
+
 void target_execute_cmd(struct se_cmd *cmd)
 {
 	/*
-	 * If the received CDB has aleady been aborted stop processing it here.
-	 */
-	if (transport_check_aborted_status(cmd, 1))
-		return;
-
-	/*
 	 * Determine if frontend context caller is requesting the stopping of
 	 * this command for frontend exceptions.
+	 *
+	 * If the received CDB has aleady been aborted stop processing it here.
 	 */
 	spin_lock_irq(&cmd->t_state_lock);
+	if (__transport_check_aborted_status(cmd, 1)) {
+		spin_unlock_irq(&cmd->t_state_lock);
+		return;
+	}
 	if (cmd->transport_state & CMD_T_STOP) {
 		pr_debug("%s:%d CMD_T_STOP for ITT: 0x%08llx\n",
 			__func__, __LINE__, cmd->tag);
@@ -1886,7 +1962,7 @@ void target_execute_cmd(struct se_cmd *c
 		return;
 	}
 
-	__target_execute_cmd(cmd);
+	__target_execute_cmd(cmd, true);
 }
 EXPORT_SYMBOL(target_execute_cmd);
 
@@ -1910,7 +1986,7 @@ static void target_restart_delayed_cmds(
 		list_del(&cmd->se_delayed_node);
 		spin_unlock(&dev->delayed_cmd_lock);
 
-		__target_execute_cmd(cmd);
+		__target_execute_cmd(cmd, true);
 
 		if (cmd->sam_task_attr == TCM_ORDERED_TAG)
 			break;
@@ -1928,6 +2004,9 @@ static void transport_complete_task_attr
 	if (dev->transport->transport_flags & TRANSPORT_FLAG_PASSTHROUGH)
 		return;
 
+	if (!(cmd->se_cmd_flags & SCF_TASK_ATTR_SET))
+		goto restart;
+
 	if (cmd->sam_task_attr == TCM_SIMPLE_TAG) {
 		atomic_dec_mb(&dev->simple_cmds);
 		dev->dev_cur_ordered_id++;
@@ -1944,7 +2023,7 @@ static void transport_complete_task_attr
 		pr_debug("Incremented dev_cur_ordered_id: %u for ORDERED\n",
 			 dev->dev_cur_ordered_id);
 	}
-
+restart:
 	target_restart_delayed_cmds(dev);
 }
 
@@ -2213,20 +2292,14 @@ static inline void transport_free_pages(
 }
 
 /**
- * transport_release_cmd - free a command
- * @cmd:       command to free
+ * transport_put_cmd - release a reference to a command
+ * @cmd:       command to release
  *
- * This routine unconditionally frees a command, and reference counting
- * or list removal must be done in the caller.
+ * This routine releases our reference to the command and frees it if possible.
  */
-static int transport_release_cmd(struct se_cmd *cmd)
+static int transport_put_cmd(struct se_cmd *cmd)
 {
 	BUG_ON(!cmd->se_tfo);
-
-	if (cmd->se_cmd_flags & SCF_SCSI_TMR_CDB)
-		core_tmr_release_req(cmd->se_tmr_req);
-	if (cmd->t_task_cdb != cmd->__t_task_cdb)
-		kfree(cmd->t_task_cdb);
 	/*
 	 * If this cmd has been setup with target_get_sess_cmd(), drop
 	 * the kref and call ->release_cmd() in kref callback.
@@ -2234,18 +2307,6 @@ static int transport_release_cmd(struct
 	return target_put_sess_cmd(cmd);
 }
 
-/**
- * transport_put_cmd - release a reference to a command
- * @cmd:       command to release
- *
- * This routine releases our reference to the command and frees it if possible.
- */
-static int transport_put_cmd(struct se_cmd *cmd)
-{
-	transport_free_pages(cmd);
-	return transport_release_cmd(cmd);
-}
-
 void *transport_kmap_data_sg(struct se_cmd *cmd)
 {
 	struct scatterlist *sg = cmd->t_data_sg;
@@ -2441,34 +2502,58 @@ static void transport_write_pending_qf(s
 	}
 }
 
-int transport_generic_free_cmd(struct se_cmd *cmd, int wait_for_tasks)
+static bool
+__transport_wait_for_tasks(struct se_cmd *, bool, bool *, bool *,
+			   unsigned long *flags);
+
+static void target_wait_free_cmd(struct se_cmd *cmd, bool *aborted, bool *tas)
 {
 	unsigned long flags;
+
+	spin_lock_irqsave(&cmd->t_state_lock, flags);
+	__transport_wait_for_tasks(cmd, true, aborted, tas, &flags);
+	spin_unlock_irqrestore(&cmd->t_state_lock, flags);
+}
+
+int transport_generic_free_cmd(struct se_cmd *cmd, int wait_for_tasks)
+{
 	int ret = 0;
+	bool aborted = false, tas = false;
 
 	if (!(cmd->se_cmd_flags & SCF_SE_LUN_CMD)) {
 		if (wait_for_tasks && (cmd->se_cmd_flags & SCF_SCSI_TMR_CDB))
-			 transport_wait_for_tasks(cmd);
+			target_wait_free_cmd(cmd, &aborted, &tas);
 
-		ret = transport_release_cmd(cmd);
+		if (!aborted || tas)
+			ret = transport_put_cmd(cmd);
 	} else {
 		if (wait_for_tasks)
-			transport_wait_for_tasks(cmd);
+			target_wait_free_cmd(cmd, &aborted, &tas);
 		/*
 		 * Handle WRITE failure case where transport_generic_new_cmd()
 		 * has already added se_cmd to state_list, but fabric has
 		 * failed command before I/O submission.
 		 */
-		if (cmd->state_active) {
-			spin_lock_irqsave(&cmd->t_state_lock, flags);
+		if (cmd->state_active)
 			target_remove_from_state_list(cmd);
-			spin_unlock_irqrestore(&cmd->t_state_lock, flags);
-		}
 
 		if (cmd->se_lun)
 			transport_lun_remove_cmd(cmd);
 
-		ret = transport_put_cmd(cmd);
+		if (!aborted || tas)
+			ret = transport_put_cmd(cmd);
+	}
+	/*
+	 * If the task has been internally aborted due to TMR ABORT_TASK
+	 * or LUN_RESET, target_core_tmr.c is responsible for performing
+	 * the remaining calls to target_put_sess_cmd(), and not the
+	 * callers of this function.
+	 */
+	if (aborted) {
+		pr_debug("Detected CMD_T_ABORTED for ITT: %llu\n", cmd->tag);
+		wait_for_completion(&cmd->cmd_wait_comp);
+		cmd->se_tfo->release_cmd(cmd);
+		ret = 1;
 	}
 	return ret;
 }
@@ -2508,26 +2593,41 @@ out:
 }
 EXPORT_SYMBOL(target_get_sess_cmd);
 
+static void target_free_cmd_mem(struct se_cmd *cmd)
+{
+	transport_free_pages(cmd);
+
+	if (cmd->se_cmd_flags & SCF_SCSI_TMR_CDB)
+		core_tmr_release_req(cmd->se_tmr_req);
+	if (cmd->t_task_cdb != cmd->__t_task_cdb)
+		kfree(cmd->t_task_cdb);
+}
+
 static void target_release_cmd_kref(struct kref *kref)
 {
 	struct se_cmd *se_cmd = container_of(kref, struct se_cmd, cmd_kref);
 	struct se_session *se_sess = se_cmd->se_sess;
 	unsigned long flags;
+	bool fabric_stop;
 
 	spin_lock_irqsave(&se_sess->sess_cmd_lock, flags);
-	if (list_empty(&se_cmd->se_cmd_list)) {
-		spin_unlock_irqrestore(&se_sess->sess_cmd_lock, flags);
-		se_cmd->se_tfo->release_cmd(se_cmd);
-		return;
-	}
-	if (se_sess->sess_tearing_down && se_cmd->cmd_wait_set) {
+
+	spin_lock(&se_cmd->t_state_lock);
+	fabric_stop = (se_cmd->transport_state & CMD_T_FABRIC_STOP) &&
+		      (se_cmd->transport_state & CMD_T_ABORTED);
+	spin_unlock(&se_cmd->t_state_lock);
+
+	if (se_cmd->cmd_wait_set || fabric_stop) {
+		list_del_init(&se_cmd->se_cmd_list);
 		spin_unlock_irqrestore(&se_sess->sess_cmd_lock, flags);
+		target_free_cmd_mem(se_cmd);
 		complete(&se_cmd->cmd_wait_comp);
 		return;
 	}
-	list_del(&se_cmd->se_cmd_list);
+	list_del_init(&se_cmd->se_cmd_list);
 	spin_unlock_irqrestore(&se_sess->sess_cmd_lock, flags);
 
+	target_free_cmd_mem(se_cmd);
 	se_cmd->se_tfo->release_cmd(se_cmd);
 }
 
@@ -2539,6 +2639,7 @@ int target_put_sess_cmd(struct se_cmd *s
 	struct se_session *se_sess = se_cmd->se_sess;
 
 	if (!se_sess) {
+		target_free_cmd_mem(se_cmd);
 		se_cmd->se_tfo->release_cmd(se_cmd);
 		return 1;
 	}
@@ -2555,6 +2656,7 @@ void target_sess_cmd_list_set_waiting(st
 {
 	struct se_cmd *se_cmd;
 	unsigned long flags;
+	int rc;
 
 	spin_lock_irqsave(&se_sess->sess_cmd_lock, flags);
 	if (se_sess->sess_tearing_down) {
@@ -2564,8 +2666,15 @@ void target_sess_cmd_list_set_waiting(st
 	se_sess->sess_tearing_down = 1;
 	list_splice_init(&se_sess->sess_cmd_list, &se_sess->sess_wait_list);
 
-	list_for_each_entry(se_cmd, &se_sess->sess_wait_list, se_cmd_list)
-		se_cmd->cmd_wait_set = 1;
+	list_for_each_entry(se_cmd, &se_sess->sess_wait_list, se_cmd_list) {
+		rc = kref_get_unless_zero(&se_cmd->cmd_kref);
+		if (rc) {
+			se_cmd->cmd_wait_set = 1;
+			spin_lock(&se_cmd->t_state_lock);
+			se_cmd->transport_state |= CMD_T_FABRIC_STOP;
+			spin_unlock(&se_cmd->t_state_lock);
+		}
+	}
 
 	spin_unlock_irqrestore(&se_sess->sess_cmd_lock, flags);
 }
@@ -2578,15 +2687,23 @@ void target_wait_for_sess_cmds(struct se
 {
 	struct se_cmd *se_cmd, *tmp_cmd;
 	unsigned long flags;
+	bool tas;
 
 	list_for_each_entry_safe(se_cmd, tmp_cmd,
 				&se_sess->sess_wait_list, se_cmd_list) {
-		list_del(&se_cmd->se_cmd_list);
-
 		pr_debug("Waiting for se_cmd: %p t_state: %d, fabric state:"
 			" %d\n", se_cmd, se_cmd->t_state,
 			se_cmd->se_tfo->get_cmd_state(se_cmd));
 
+		spin_lock_irqsave(&se_cmd->t_state_lock, flags);
+		tas = (se_cmd->transport_state & CMD_T_TAS);
+		spin_unlock_irqrestore(&se_cmd->t_state_lock, flags);
+
+		if (!target_put_sess_cmd(se_cmd)) {
+			if (tas)
+				target_put_sess_cmd(se_cmd);
+		}
+
 		wait_for_completion(&se_cmd->cmd_wait_comp);
 		pr_debug("After cmd_wait_comp: se_cmd: %p t_state: %d"
 			" fabric state: %d\n", se_cmd, se_cmd->t_state,
@@ -2608,53 +2725,75 @@ void transport_clear_lun_ref(struct se_l
 	wait_for_completion(&lun->lun_ref_comp);
 }
 
-/**
- * transport_wait_for_tasks - wait for completion to occur
- * @cmd:	command to wait
- *
- * Called from frontend fabric context to wait for storage engine
- * to pause and/or release frontend generated struct se_cmd.
- */
-bool transport_wait_for_tasks(struct se_cmd *cmd)
+static bool
+__transport_wait_for_tasks(struct se_cmd *cmd, bool fabric_stop,
+			   bool *aborted, bool *tas, unsigned long *flags)
+	__releases(&cmd->t_state_lock)
+	__acquires(&cmd->t_state_lock)
 {
-	unsigned long flags;
 
-	spin_lock_irqsave(&cmd->t_state_lock, flags);
+	assert_spin_locked(&cmd->t_state_lock);
+	WARN_ON_ONCE(!irqs_disabled());
+
+	if (fabric_stop)
+		cmd->transport_state |= CMD_T_FABRIC_STOP;
+
+	if (cmd->transport_state & CMD_T_ABORTED)
+		*aborted = true;
+
+	if (cmd->transport_state & CMD_T_TAS)
+		*tas = true;
+
 	if (!(cmd->se_cmd_flags & SCF_SE_LUN_CMD) &&
-	    !(cmd->se_cmd_flags & SCF_SCSI_TMR_CDB)) {
-		spin_unlock_irqrestore(&cmd->t_state_lock, flags);
+	    !(cmd->se_cmd_flags & SCF_SCSI_TMR_CDB))
 		return false;
-	}
 
 	if (!(cmd->se_cmd_flags & SCF_SUPPORTED_SAM_OPCODE) &&
-	    !(cmd->se_cmd_flags & SCF_SCSI_TMR_CDB)) {
-		spin_unlock_irqrestore(&cmd->t_state_lock, flags);
+	    !(cmd->se_cmd_flags & SCF_SCSI_TMR_CDB))
 		return false;
-	}
 
-	if (!(cmd->transport_state & CMD_T_ACTIVE)) {
-		spin_unlock_irqrestore(&cmd->t_state_lock, flags);
+	if (!(cmd->transport_state & CMD_T_ACTIVE))
+		return false;
+
+	if (fabric_stop && *aborted)
 		return false;
-	}
 
 	cmd->transport_state |= CMD_T_STOP;
 
-	pr_debug("wait_for_tasks: Stopping %p ITT: 0x%08llx i_state: %d, t_state: %d, CMD_T_STOP\n",
-		cmd, cmd->tag, cmd->se_tfo->get_cmd_state(cmd), cmd->t_state);
+	pr_debug("wait_for_tasks: Stopping %p ITT: 0x%08llx i_state: %d,"
+		 " t_state: %d, CMD_T_STOP\n", cmd, cmd->tag,
+		 cmd->se_tfo->get_cmd_state(cmd), cmd->t_state);
 
-	spin_unlock_irqrestore(&cmd->t_state_lock, flags);
+	spin_unlock_irqrestore(&cmd->t_state_lock, *flags);
 
 	wait_for_completion(&cmd->t_transport_stop_comp);
 
-	spin_lock_irqsave(&cmd->t_state_lock, flags);
+	spin_lock_irqsave(&cmd->t_state_lock, *flags);
 	cmd->transport_state &= ~(CMD_T_ACTIVE | CMD_T_STOP);
 
-	pr_debug("wait_for_tasks: Stopped wait_for_completion(&cmd->t_transport_stop_comp) for ITT: 0x%08llx\n",
-		cmd->tag);
+	pr_debug("wait_for_tasks: Stopped wait_for_completion(&cmd->"
+		 "t_transport_stop_comp) for ITT: 0x%08llx\n", cmd->tag);
+
+	return true;
+}
 
+/**
+ * transport_wait_for_tasks - wait for completion to occur
+ * @cmd:	command to wait
+ *
+ * Called from frontend fabric context to wait for storage engine
+ * to pause and/or release frontend generated struct se_cmd.
+ */
+bool transport_wait_for_tasks(struct se_cmd *cmd)
+{
+	unsigned long flags;
+	bool ret, aborted = false, tas = false;
+
+	spin_lock_irqsave(&cmd->t_state_lock, flags);
+	ret = __transport_wait_for_tasks(cmd, false, &aborted, &tas, &flags);
 	spin_unlock_irqrestore(&cmd->t_state_lock, flags);
 
-	return true;
+	return ret;
 }
 EXPORT_SYMBOL(transport_wait_for_tasks);
 
@@ -2836,28 +2975,49 @@ transport_send_check_condition_and_sense
 }
 EXPORT_SYMBOL(transport_send_check_condition_and_sense);
 
-int transport_check_aborted_status(struct se_cmd *cmd, int send_status)
+static int __transport_check_aborted_status(struct se_cmd *cmd, int send_status)
+	__releases(&cmd->t_state_lock)
+	__acquires(&cmd->t_state_lock)
 {
+	assert_spin_locked(&cmd->t_state_lock);
+	WARN_ON_ONCE(!irqs_disabled());
+
 	if (!(cmd->transport_state & CMD_T_ABORTED))
 		return 0;
-
 	/*
 	 * If cmd has been aborted but either no status is to be sent or it has
 	 * already been sent, just return
 	 */
-	if (!send_status || !(cmd->se_cmd_flags & SCF_SEND_DELAYED_TAS))
+	if (!send_status || !(cmd->se_cmd_flags & SCF_SEND_DELAYED_TAS)) {
+		if (send_status)
+			cmd->se_cmd_flags |= SCF_SEND_DELAYED_TAS;
 		return 1;
+	}
 
-	pr_debug("Sending delayed SAM_STAT_TASK_ABORTED status for CDB: 0x%02x ITT: 0x%08llx\n",
-		 cmd->t_task_cdb[0], cmd->tag);
+	pr_debug("Sending delayed SAM_STAT_TASK_ABORTED status for CDB:"
+		" 0x%02x ITT: 0x%08llx\n", cmd->t_task_cdb[0], cmd->tag);
 
 	cmd->se_cmd_flags &= ~SCF_SEND_DELAYED_TAS;
 	cmd->scsi_status = SAM_STAT_TASK_ABORTED;
 	trace_target_cmd_complete(cmd);
+
+	spin_unlock_irq(&cmd->t_state_lock);
 	cmd->se_tfo->queue_status(cmd);
+	spin_lock_irq(&cmd->t_state_lock);
 
 	return 1;
 }
+
+int transport_check_aborted_status(struct se_cmd *cmd, int send_status)
+{
+	int ret;
+
+	spin_lock_irq(&cmd->t_state_lock);
+	ret = __transport_check_aborted_status(cmd, send_status);
+	spin_unlock_irq(&cmd->t_state_lock);
+
+	return ret;
+}
 EXPORT_SYMBOL(transport_check_aborted_status);
 
 void transport_send_task_abort(struct se_cmd *cmd)
@@ -2879,11 +3039,17 @@ void transport_send_task_abort(struct se
 	 */
 	if (cmd->data_direction == DMA_TO_DEVICE) {
 		if (cmd->se_tfo->write_pending_status(cmd) != 0) {
-			cmd->transport_state |= CMD_T_ABORTED;
+			spin_lock_irqsave(&cmd->t_state_lock, flags);
+			if (cmd->se_cmd_flags & SCF_SEND_DELAYED_TAS) {
+				spin_unlock_irqrestore(&cmd->t_state_lock, flags);
+				goto send_abort;
+			}
 			cmd->se_cmd_flags |= SCF_SEND_DELAYED_TAS;
+			spin_unlock_irqrestore(&cmd->t_state_lock, flags);
 			return;
 		}
 	}
+send_abort:
 	cmd->scsi_status = SAM_STAT_TASK_ABORTED;
 
 	transport_lun_remove_cmd(cmd);
@@ -2900,8 +3066,17 @@ static void target_tmr_work(struct work_
 	struct se_cmd *cmd = container_of(work, struct se_cmd, work);
 	struct se_device *dev = cmd->se_dev;
 	struct se_tmr_req *tmr = cmd->se_tmr_req;
+	unsigned long flags;
 	int ret;
 
+	spin_lock_irqsave(&cmd->t_state_lock, flags);
+	if (cmd->transport_state & CMD_T_ABORTED) {
+		tmr->response = TMR_FUNCTION_REJECTED;
+		spin_unlock_irqrestore(&cmd->t_state_lock, flags);
+		goto check_stop;
+	}
+	spin_unlock_irqrestore(&cmd->t_state_lock, flags);
+
 	switch (tmr->function) {
 	case TMR_ABORT_TASK:
 		core_tmr_abort_task(dev, tmr, cmd->se_sess);
@@ -2934,9 +3109,17 @@ static void target_tmr_work(struct work_
 		break;
 	}
 
+	spin_lock_irqsave(&cmd->t_state_lock, flags);
+	if (cmd->transport_state & CMD_T_ABORTED) {
+		spin_unlock_irqrestore(&cmd->t_state_lock, flags);
+		goto check_stop;
+	}
 	cmd->t_state = TRANSPORT_ISTATE_PROCESSING;
+	spin_unlock_irqrestore(&cmd->t_state_lock, flags);
+
 	cmd->se_tfo->queue_tm_rsp(cmd);
 
+check_stop:
 	transport_cmd_check_stop_to_fabric(cmd);
 }
 
--- zfcpdump-kernel-4.4.orig/drivers/target/target_core_user.c
+++ zfcpdump-kernel-4.4/drivers/target/target_core_user.c
@@ -154,6 +154,14 @@ static struct genl_family tcmu_genl_fami
 	.n_mcgrps = ARRAY_SIZE(tcmu_mcgrps),
 };
 
+/* Sense Key = 2 (Not Ready)
+ * ASC/ASCQ = 0x0800 (Logical Unit Communication Failure)
+ */
+static const char lu_comm_failure_sense[18] = {
+	0x70, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x0a,
+	0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+	0x00, 0x00 };
+
 static struct tcmu_cmd *tcmu_alloc_cmd(struct se_cmd *se_cmd)
 {
 	struct se_device *se_dev = se_cmd->se_dev;
@@ -540,9 +548,11 @@ static void tcmu_handle_completion(struc
 		pr_warn("TCMU: Userspace set UNKNOWN_OP flag on se_cmd %p\n",
 			cmd->se_cmd);
 		entry->rsp.scsi_status = SAM_STAT_CHECK_CONDITION;
+		memcpy(se_cmd->sense_buffer, lu_comm_failure_sense,
+		       sizeof(lu_comm_failure_sense));
 	} else if (entry->rsp.scsi_status == SAM_STAT_CHECK_CONDITION) {
 		memcpy(se_cmd->sense_buffer, entry->rsp.sense_buffer,
-			       se_cmd->scsi_sense_length);
+			       TRANSPORT_SENSE_BUFFER);
 
 		UPDATE_HEAD(udev->data_tail, cmd->data_length, udev->data_size);
 	} else if (se_cmd->se_cmd_flags & SCF_BIDI) {
@@ -642,6 +652,8 @@ static int tcmu_check_expired_cmd(int id
 		return 0;
 
 	set_bit(TCMU_CMD_BIT_EXPIRED, &cmd->flags);
+	memcpy(cmd->se_cmd->sense_buffer, lu_comm_failure_sense,
+	       sizeof(lu_comm_failure_sense));
 	target_complete_cmd(cmd->se_cmd, SAM_STAT_CHECK_CONDITION);
 	cmd->se_cmd = NULL;
 
@@ -1099,6 +1111,17 @@ tcmu_parse_cdb(struct se_cmd *cmd)
 	return passthrough_parse_cdb(cmd, tcmu_pass_op);
 }
 
+static void tcmu_transport_complete(struct se_cmd *cmd, struct scatterlist *sg,
+				    unsigned char *sense_buffer)
+{
+	if (cmd->scsi_status == SAM_STAT_CHECK_CONDITION)
+		/* Setting this flag will prevent target_complete_cmd from
+		 * calling target_complete_failure_work, which would overwrite
+		 * the sense data we already set.
+		 */
+		cmd->se_cmd_flags |= SCF_TRANSPORT_TASK_SENSE;
+}
+
 static const struct target_backend_ops tcmu_ops = {
 	.name			= "user",
 	.owner			= THIS_MODULE,
@@ -1109,6 +1132,7 @@ static const struct target_backend_ops t
 	.configure_device	= tcmu_configure_device,
 	.free_device		= tcmu_free_device,
 	.parse_cdb		= tcmu_parse_cdb,
+	.transport_complete	= tcmu_transport_complete,
 	.set_configfs_dev_params = tcmu_set_configfs_dev_params,
 	.show_configfs_dev_params = tcmu_show_configfs_dev_params,
 	.get_device_type	= sbc_get_device_type,
--- zfcpdump-kernel-4.4.orig/drivers/thermal/cpu_cooling.c
+++ zfcpdump-kernel-4.4/drivers/thermal/cpu_cooling.c
@@ -377,26 +377,28 @@ static u32 cpu_power_to_freq(struct cpuf
  * get_load() - get load for a cpu since last updated
  * @cpufreq_device:	&struct cpufreq_cooling_device for this cpu
  * @cpu:	cpu number
+ * @cpu_idx:	index of the cpu in cpufreq_device->allowed_cpus
  *
  * Return: The average load of cpu @cpu in percentage since this
  * function was last called.
  */
-static u32 get_load(struct cpufreq_cooling_device *cpufreq_device, int cpu)
+static u32 get_load(struct cpufreq_cooling_device *cpufreq_device, int cpu,
+		    int cpu_idx)
 {
 	u32 load;
 	u64 now, now_idle, delta_time, delta_idle;
 
 	now_idle = get_cpu_idle_time(cpu, &now, 0);
-	delta_idle = now_idle - cpufreq_device->time_in_idle[cpu];
-	delta_time = now - cpufreq_device->time_in_idle_timestamp[cpu];
+	delta_idle = now_idle - cpufreq_device->time_in_idle[cpu_idx];
+	delta_time = now - cpufreq_device->time_in_idle_timestamp[cpu_idx];
 
 	if (delta_time <= delta_idle)
 		load = 0;
 	else
 		load = div64_u64(100 * (delta_time - delta_idle), delta_time);
 
-	cpufreq_device->time_in_idle[cpu] = now_idle;
-	cpufreq_device->time_in_idle_timestamp[cpu] = now;
+	cpufreq_device->time_in_idle[cpu_idx] = now_idle;
+	cpufreq_device->time_in_idle_timestamp[cpu_idx] = now;
 
 	return load;
 }
@@ -598,7 +600,7 @@ static int cpufreq_get_requested_power(s
 		u32 load;
 
 		if (cpu_online(cpu))
-			load = get_load(cpufreq_device, cpu);
+			load = get_load(cpufreq_device, cpu, i);
 		else
 			load = 0;
 
@@ -855,14 +857,6 @@ __cpufreq_cooling_register(struct device
 		goto free_power_table;
 	}
 
-	snprintf(dev_name, sizeof(dev_name), "thermal-cpufreq-%d",
-		 cpufreq_dev->id);
-
-	cool_dev = thermal_of_cooling_device_register(np, dev_name, cpufreq_dev,
-						      &cpufreq_cooling_ops);
-	if (IS_ERR(cool_dev))
-		goto remove_idr;
-
 	/* Fill freq-table in descending order of frequencies */
 	for (i = 0, freq = -1; i <= cpufreq_dev->max_level; i++) {
 		freq = find_next_max(table, freq);
@@ -875,6 +869,14 @@ __cpufreq_cooling_register(struct device
 			pr_debug("%s: freq:%u KHz\n", __func__, freq);
 	}
 
+	snprintf(dev_name, sizeof(dev_name), "thermal-cpufreq-%d",
+		 cpufreq_dev->id);
+
+	cool_dev = thermal_of_cooling_device_register(np, dev_name, cpufreq_dev,
+						      &cpufreq_cooling_ops);
+	if (IS_ERR(cool_dev))
+		goto remove_idr;
+
 	cpufreq_dev->clipped_freq = cpufreq_dev->freq_table[0];
 	cpufreq_dev->cool_dev = cool_dev;
 
--- zfcpdump-kernel-4.4.orig/drivers/thermal/rockchip_thermal.c
+++ zfcpdump-kernel-4.4/drivers/thermal/rockchip_thermal.c
@@ -545,15 +545,14 @@ static int rockchip_configure_from_dt(st
 			 thermal->chip->tshut_temp);
 		thermal->tshut_temp = thermal->chip->tshut_temp;
 	} else {
+		if (shut_temp > INT_MAX) {
+			dev_err(dev, "Invalid tshut temperature specified: %d\n",
+				shut_temp);
+			return -ERANGE;
+		}
 		thermal->tshut_temp = shut_temp;
 	}
 
-	if (thermal->tshut_temp > INT_MAX) {
-		dev_err(dev, "Invalid tshut temperature specified: %d\n",
-			thermal->tshut_temp);
-		return -ERANGE;
-	}
-
 	if (of_property_read_u32(np, "rockchip,hw-tshut-mode", &tshut_mode)) {
 		dev_warn(dev,
 			 "Missing tshut mode property, using default (%s)\n",
--- zfcpdump-kernel-4.4.orig/drivers/thermal/step_wise.c
+++ zfcpdump-kernel-4.4/drivers/thermal/step_wise.c
@@ -63,6 +63,19 @@ static unsigned long get_target_state(st
 	next_target = instance->target;
 	dev_dbg(&cdev->device, "cur_state=%ld\n", cur_state);
 
+	if (!instance->initialized) {
+		if (throttle) {
+			next_target = (cur_state + 1) >= instance->upper ?
+					instance->upper :
+					((cur_state + 1) < instance->lower ?
+					instance->lower : (cur_state + 1));
+		} else {
+			next_target = THERMAL_NO_TARGET;
+		}
+
+		return next_target;
+	}
+
 	switch (trend) {
 	case THERMAL_TREND_RAISING:
 		if (throttle) {
@@ -149,7 +162,7 @@ static void thermal_zone_trip_update(str
 		dev_dbg(&instance->cdev->device, "old_target=%d, target=%d\n",
 					old_target, (int)instance->target);
 
-		if (old_target == instance->target)
+		if (instance->initialized && old_target == instance->target)
 			continue;
 
 		/* Activate a passive thermal instance */
@@ -161,7 +174,7 @@ static void thermal_zone_trip_update(str
 			instance->target == THERMAL_NO_TARGET)
 			update_passive_instance(tz, trip_type, -1);
 
-
+		instance->initialized = true;
 		instance->cdev->updated = false; /* cdev needs update */
 	}
 
--- zfcpdump-kernel-4.4.orig/drivers/thermal/thermal_core.c
+++ zfcpdump-kernel-4.4/drivers/thermal/thermal_core.c
@@ -37,6 +37,7 @@
 #include <linux/of.h>
 #include <net/netlink.h>
 #include <net/genetlink.h>
+#include <linux/suspend.h>
 
 #define CREATE_TRACE_POINTS
 #include <trace/events/thermal.h>
@@ -59,6 +60,8 @@ static LIST_HEAD(thermal_governor_list);
 static DEFINE_MUTEX(thermal_list_lock);
 static DEFINE_MUTEX(thermal_governor_lock);
 
+static atomic_t in_suspend;
+
 static struct thermal_governor *def_governor;
 
 static struct thermal_governor *__find_governor(const char *name)
@@ -451,6 +454,10 @@ static void handle_thermal_trip(struct t
 {
 	enum thermal_trip_type type;
 
+	/* Ignore disabled trip points */
+	if (test_bit(trip, &tz->trips_disabled))
+		return;
+
 	tz->ops->get_trip_type(tz, trip, &type);
 
 	if (type == THERMAL_TRIP_CRITICAL || type == THERMAL_TRIP_HOT)
@@ -532,14 +539,31 @@ static void update_temperature(struct th
 	mutex_unlock(&tz->lock);
 
 	trace_thermal_temperature(tz);
-	dev_dbg(&tz->device, "last_temperature=%d, current_temperature=%d\n",
-				tz->last_temperature, tz->temperature);
+	if (tz->last_temperature == THERMAL_TEMP_INVALID)
+		dev_dbg(&tz->device, "last_temperature N/A, current_temperature=%d\n",
+			tz->temperature);
+	else
+		dev_dbg(&tz->device, "last_temperature=%d, current_temperature=%d\n",
+			tz->last_temperature, tz->temperature);
+}
+
+static void thermal_zone_device_reset(struct thermal_zone_device *tz)
+{
+	struct thermal_instance *pos;
+
+	tz->temperature = THERMAL_TEMP_INVALID;
+	tz->passive = 0;
+	list_for_each_entry(pos, &tz->thermal_instances, tz_node)
+		pos->initialized = false;
 }
 
 void thermal_zone_device_update(struct thermal_zone_device *tz)
 {
 	int count;
 
+	if (atomic_read(&in_suspend))
+		return;
+
 	if (!tz->ops->get_temp)
 		return;
 
@@ -1321,6 +1345,7 @@ int thermal_zone_bind_cooling_device(str
 	if (!result) {
 		list_add_tail(&dev->tz_node, &tz->thermal_instances);
 		list_add_tail(&dev->cdev_node, &cdev->thermal_instances);
+		atomic_set(&tz->need_update, 1);
 	}
 	mutex_unlock(&cdev->lock);
 	mutex_unlock(&tz->lock);
@@ -1430,6 +1455,7 @@ __thermal_cooling_device_register(struct
 				  const struct thermal_cooling_device_ops *ops)
 {
 	struct thermal_cooling_device *cdev;
+	struct thermal_zone_device *pos = NULL;
 	int result;
 
 	if (type && strlen(type) >= THERMAL_NAME_LENGTH)
@@ -1474,6 +1500,12 @@ __thermal_cooling_device_register(struct
 	/* Update binding information for 'this' new cdev */
 	bind_cdev(cdev);
 
+	mutex_lock(&thermal_list_lock);
+	list_for_each_entry(pos, &thermal_tz_list, node)
+		if (atomic_cmpxchg(&pos->need_update, 1, 0))
+			thermal_zone_device_update(pos);
+	mutex_unlock(&thermal_list_lock);
+
 	return cdev;
 }
 
@@ -1768,6 +1800,7 @@ struct thermal_zone_device *thermal_zone
 {
 	struct thermal_zone_device *tz;
 	enum thermal_trip_type trip_type;
+	int trip_temp;
 	int result;
 	int count;
 	int passive = 0;
@@ -1806,6 +1839,8 @@ struct thermal_zone_device *thermal_zone
 	tz->trips = trips;
 	tz->passive_delay = passive_delay;
 	tz->polling_delay = polling_delay;
+	/* A new thermal zone needs to be updated anyway. */
+	atomic_set(&tz->need_update, 1);
 
 	dev_set_name(&tz->device, "thermal_zone%d", tz->id);
 	result = device_register(&tz->device);
@@ -1837,9 +1872,15 @@ struct thermal_zone_device *thermal_zone
 		goto unregister;
 
 	for (count = 0; count < trips; count++) {
-		tz->ops->get_trip_type(tz, count, &trip_type);
+		if (tz->ops->get_trip_type(tz, count, &trip_type))
+			set_bit(count, &tz->trips_disabled);
 		if (trip_type == THERMAL_TRIP_PASSIVE)
 			passive = 1;
+		if (tz->ops->get_trip_temp(tz, count, &trip_temp))
+			set_bit(count, &tz->trips_disabled);
+		/* Check for bogus trip points */
+		if (trip_temp == 0)
+			set_bit(count, &tz->trips_disabled);
 	}
 
 	if (!passive) {
@@ -1900,7 +1941,10 @@ struct thermal_zone_device *thermal_zone
 
 	INIT_DELAYED_WORK(&(tz->poll_queue), thermal_zone_device_check);
 
-	thermal_zone_device_update(tz);
+	thermal_zone_device_reset(tz);
+	/* Update the new thermal zone and mark it as already updated. */
+	if (atomic_cmpxchg(&tz->need_update, 1, 0))
+		thermal_zone_device_update(tz);
 
 	return tz;
 
@@ -2140,6 +2184,36 @@ static void thermal_unregister_governors
 	thermal_gov_power_allocator_unregister();
 }
 
+static int thermal_pm_notify(struct notifier_block *nb,
+				unsigned long mode, void *_unused)
+{
+	struct thermal_zone_device *tz;
+
+	switch (mode) {
+	case PM_HIBERNATION_PREPARE:
+	case PM_RESTORE_PREPARE:
+	case PM_SUSPEND_PREPARE:
+		atomic_set(&in_suspend, 1);
+		break;
+	case PM_POST_HIBERNATION:
+	case PM_POST_RESTORE:
+	case PM_POST_SUSPEND:
+		atomic_set(&in_suspend, 0);
+		list_for_each_entry(tz, &thermal_tz_list, node) {
+			thermal_zone_device_reset(tz);
+			thermal_zone_device_update(tz);
+		}
+		break;
+	default:
+		break;
+	}
+	return 0;
+}
+
+static struct notifier_block thermal_pm_nb = {
+	.notifier_call = thermal_pm_notify,
+};
+
 static int __init thermal_init(void)
 {
 	int result;
@@ -2160,6 +2234,11 @@ static int __init thermal_init(void)
 	if (result)
 		goto exit_netlink;
 
+	result = register_pm_notifier(&thermal_pm_nb);
+	if (result)
+		pr_warn("Thermal: Can not register suspend notifier, return %d\n",
+			result);
+
 	return 0;
 
 exit_netlink:
@@ -2179,6 +2258,7 @@ error:
 
 static void __exit thermal_exit(void)
 {
+	unregister_pm_notifier(&thermal_pm_nb);
 	of_thermal_destroy_zones();
 	genetlink_exit();
 	class_unregister(&thermal_class);
--- zfcpdump-kernel-4.4.orig/drivers/thermal/thermal_core.h
+++ zfcpdump-kernel-4.4/drivers/thermal/thermal_core.h
@@ -41,6 +41,7 @@ struct thermal_instance {
 	struct thermal_zone_device *tz;
 	struct thermal_cooling_device *cdev;
 	int trip;
+	bool initialized;
 	unsigned long upper;	/* Highest cooling state for this trip point */
 	unsigned long lower;	/* Lowest cooling state for this trip point */
 	unsigned long target;	/* expected cooling state */
--- zfcpdump-kernel-4.4.orig/drivers/thunderbolt/eeprom.c
+++ zfcpdump-kernel-4.4/drivers/thunderbolt/eeprom.c
@@ -444,6 +444,7 @@ int tb_drom_read(struct tb_switch *sw)
 	return tb_drom_parse_entries(sw);
 err:
 	kfree(sw->drom);
+	sw->drom = NULL;
 	return -EIO;
 
 }
--- zfcpdump-kernel-4.4.orig/drivers/tty/n_gsm.c
+++ zfcpdump-kernel-4.4/drivers/tty/n_gsm.c
@@ -2045,7 +2045,9 @@ static void gsm_cleanup_mux(struct gsm_m
 		}
 	}
 	spin_unlock(&gsm_mux_lock);
-	WARN_ON(i == MAX_MUX);
+	/* open failed before registering => nothing to do */
+	if (i == MAX_MUX)
+		return;
 
 	/* In theory disconnecting DLCI 0 is sufficient but for some
 	   modems this is apparently not the case. */
--- zfcpdump-kernel-4.4.orig/drivers/tty/n_hdlc.c
+++ zfcpdump-kernel-4.4/drivers/tty/n_hdlc.c
@@ -600,7 +600,7 @@ static ssize_t n_hdlc_tty_read(struct tt
 	add_wait_queue(&tty->read_wait, &wait);
 
 	for (;;) {
-		if (test_bit(TTY_OTHER_DONE, &tty->flags)) {
+		if (test_bit(TTY_OTHER_CLOSED, &tty->flags)) {
 			ret = -EIO;
 			break;
 		}
@@ -828,7 +828,7 @@ static unsigned int n_hdlc_tty_poll(stru
 		/* set bits for operations that won't block */
 		if (n_hdlc->rx_buf_list.head)
 			mask |= POLLIN | POLLRDNORM;	/* readable */
-		if (test_bit(TTY_OTHER_DONE, &tty->flags))
+		if (test_bit(TTY_OTHER_CLOSED, &tty->flags))
 			mask |= POLLHUP;
 		if (tty_hung_up_p(filp))
 			mask |= POLLHUP;
--- zfcpdump-kernel-4.4.orig/drivers/tty/n_tty.c
+++ zfcpdump-kernel-4.4/drivers/tty/n_tty.c
@@ -258,16 +258,13 @@ static void n_tty_check_throttle(struct
 
 static void n_tty_check_unthrottle(struct tty_struct *tty)
 {
-	if (tty->driver->type == TTY_DRIVER_TYPE_PTY &&
-	    tty->link->ldisc->ops->write_wakeup == n_tty_write_wakeup) {
+	if (tty->driver->type == TTY_DRIVER_TYPE_PTY) {
 		if (chars_in_buffer(tty) > TTY_THRESHOLD_UNTHROTTLE)
 			return;
 		if (!tty->count)
 			return;
 		n_tty_kick_worker(tty);
-		n_tty_write_wakeup(tty->link);
-		if (waitqueue_active(&tty->link->write_wait))
-			wake_up_interruptible_poll(&tty->link->write_wait, POLLOUT);
+		tty_wakeup(tty->link);
 		return;
 	}
 
@@ -1958,18 +1955,6 @@ static inline int input_available_p(stru
 		return ldata->commit_head - ldata->read_tail >= amt;
 }
 
-static inline int check_other_done(struct tty_struct *tty)
-{
-	int done = test_bit(TTY_OTHER_DONE, &tty->flags);
-	if (done) {
-		/* paired with cmpxchg() in check_other_closed(); ensures
-		 * read buffer head index is not stale
-		 */
-		smp_mb__after_atomic();
-	}
-	return done;
-}
-
 /**
  *	copy_from_read_buf	-	copy read data directly
  *	@tty: terminal device
@@ -2174,7 +2159,7 @@ static ssize_t n_tty_read(struct tty_str
 	struct n_tty_data *ldata = tty->disc_data;
 	unsigned char __user *b = buf;
 	DEFINE_WAIT_FUNC(wait, woken_wake_function);
-	int c, done;
+	int c;
 	int minimum, time;
 	ssize_t retval = 0;
 	long timeout;
@@ -2242,32 +2227,35 @@ static ssize_t n_tty_read(struct tty_str
 		    ((minimum - (b - buf)) >= 1))
 			ldata->minimum_to_wake = (minimum - (b - buf));
 
-		done = check_other_done(tty);
-
 		if (!input_available_p(tty, 0)) {
-			if (done) {
-				retval = -EIO;
-				break;
-			}
-			if (tty_hung_up_p(file))
-				break;
-			if (!timeout)
-				break;
-			if (file->f_flags & O_NONBLOCK) {
-				retval = -EAGAIN;
-				break;
-			}
-			if (signal_pending(current)) {
-				retval = -ERESTARTSYS;
-				break;
-			}
 			up_read(&tty->termios_rwsem);
+			tty_buffer_flush_work(tty->port);
+			down_read(&tty->termios_rwsem);
+			if (!input_available_p(tty, 0)) {
+				if (test_bit(TTY_OTHER_CLOSED, &tty->flags)) {
+					retval = -EIO;
+					break;
+				}
+				if (tty_hung_up_p(file))
+					break;
+				if (!timeout)
+					break;
+				if (file->f_flags & O_NONBLOCK) {
+					retval = -EAGAIN;
+					break;
+				}
+				if (signal_pending(current)) {
+					retval = -ERESTARTSYS;
+					break;
+				}
+				up_read(&tty->termios_rwsem);
 
-			timeout = wait_woken(&wait, TASK_INTERRUPTIBLE,
-					     timeout);
+				timeout = wait_woken(&wait, TASK_INTERRUPTIBLE,
+						timeout);
 
-			down_read(&tty->termios_rwsem);
-			continue;
+				down_read(&tty->termios_rwsem);
+				continue;
+			}
 		}
 
 		if (ldata->icanon && !L_EXTPROC(tty)) {
@@ -2449,12 +2437,17 @@ static unsigned int n_tty_poll(struct tt
 
 	poll_wait(file, &tty->read_wait, wait);
 	poll_wait(file, &tty->write_wait, wait);
-	if (check_other_done(tty))
-		mask |= POLLHUP;
 	if (input_available_p(tty, 1))
 		mask |= POLLIN | POLLRDNORM;
+	else {
+		tty_buffer_flush_work(tty->port);
+		if (input_available_p(tty, 1))
+			mask |= POLLIN | POLLRDNORM;
+	}
 	if (tty->packet && tty->link->ctrl_status)
 		mask |= POLLPRI | POLLIN | POLLRDNORM;
+	if (test_bit(TTY_OTHER_CLOSED, &tty->flags))
+		mask |= POLLHUP;
 	if (tty_hung_up_p(file))
 		mask |= POLLHUP;
 	if (!(mask & (POLLHUP | POLLIN | POLLRDNORM))) {
--- zfcpdump-kernel-4.4.orig/drivers/tty/pty.c
+++ zfcpdump-kernel-4.4/drivers/tty/pty.c
@@ -59,7 +59,7 @@ static void pty_close(struct tty_struct
 	if (!tty->link)
 		return;
 	set_bit(TTY_OTHER_CLOSED, &tty->link->flags);
-	tty_flip_buffer_push(tty->link->port);
+	wake_up_interruptible(&tty->link->read_wait);
 	wake_up_interruptible(&tty->link->write_wait);
 	if (tty->driver->subtype == PTY_TYPE_MASTER) {
 		set_bit(TTY_OTHER_CLOSED, &tty->flags);
@@ -247,9 +247,7 @@ static int pty_open(struct tty_struct *t
 		goto out;
 
 	clear_bit(TTY_IO_ERROR, &tty->flags);
-	/* TTY_OTHER_CLOSED must be cleared before TTY_OTHER_DONE */
 	clear_bit(TTY_OTHER_CLOSED, &tty->link->flags);
-	clear_bit(TTY_OTHER_DONE, &tty->link->flags);
 	set_bit(TTY_THROTTLED, &tty->flags);
 	return 0;
 
@@ -681,7 +679,17 @@ static void pty_unix98_remove(struct tty
 /* this is called once with whichever end is closed last */
 static void pty_unix98_shutdown(struct tty_struct *tty)
 {
-	devpts_kill_index(tty->driver_data, tty->index);
+	struct pts_fs_info *fsi;
+
+	if (tty->driver->subtype == PTY_TYPE_MASTER)
+		fsi = tty->driver_data;
+	else
+		fsi = tty->link->driver_data;
+
+	if (fsi) {
+		devpts_kill_index(fsi, tty->index);
+		devpts_put_ref(fsi);
+	}
 }
 
 static const struct tty_operations ptm_unix98_ops = {
@@ -733,6 +741,7 @@ static const struct tty_operations pty_u
 
 static int ptmx_open(struct inode *inode, struct file *filp)
 {
+	struct pts_fs_info *fsi;
 	struct tty_struct *tty;
 	struct inode *slave_inode;
 	int retval;
@@ -747,35 +756,41 @@ static int ptmx_open(struct inode *inode
 	if (retval)
 		return retval;
 
+	fsi = devpts_get_ref(inode, filp);
+	retval = -ENODEV;
+	if (!fsi)
+		goto out_free_file;
+
 	/* find a device that is not in use. */
 	mutex_lock(&devpts_mutex);
-	index = devpts_new_index(inode);
-	if (index < 0) {
-		retval = index;
-		mutex_unlock(&devpts_mutex);
-		goto err_file;
-	}
-
+	index = devpts_new_index(fsi);
 	mutex_unlock(&devpts_mutex);
 
-	mutex_lock(&tty_mutex);
-	tty = tty_init_dev(ptm_driver, index);
+	retval = index;
+	if (index < 0)
+		goto out_put_ref;
 
-	if (IS_ERR(tty)) {
-		retval = PTR_ERR(tty);
-		goto out;
-	}
 
+	mutex_lock(&tty_mutex);
+	tty = tty_init_dev(ptm_driver, index);
 	/* The tty returned here is locked so we can safely
 	   drop the mutex */
 	mutex_unlock(&tty_mutex);
 
+	retval = PTR_ERR(tty);
+	if (IS_ERR(tty))
+		goto out;
+
+	/*
+	 * From here on out, the tty is "live", and the index and
+	 * fsi will be killed/put by the tty_release()
+	 */
 	set_bit(TTY_PTY_LOCK, &tty->flags); /* LOCK THE SLAVE */
-	tty->driver_data = inode;
+	tty->driver_data = fsi;
 
 	tty_add_file(tty, filp);
 
-	slave_inode = devpts_pty_new(inode,
+	slave_inode = devpts_pty_new(fsi,
 			MKDEV(UNIX98_PTY_SLAVE_MAJOR, index), index,
 			tty->link);
 	if (IS_ERR(slave_inode)) {
@@ -794,12 +809,14 @@ static int ptmx_open(struct inode *inode
 	return 0;
 err_release:
 	tty_unlock(tty);
+	// This will also put-ref the fsi
 	tty_release(inode, filp);
 	return retval;
 out:
-	mutex_unlock(&tty_mutex);
-	devpts_kill_index(inode, index);
-err_file:
+	devpts_kill_index(fsi, index);
+out_put_ref:
+	devpts_put_ref(fsi);
+out_free_file:
 	tty_free_file(filp);
 	return retval;
 }
--- zfcpdump-kernel-4.4.orig/drivers/tty/serial/8250/8250_mid.c
+++ zfcpdump-kernel-4.4/drivers/tty/serial/8250/8250_mid.c
@@ -14,6 +14,7 @@
 #include <linux/pci.h>
 
 #include <linux/dma/hsu.h>
+#include <linux/8250_pci.h>
 
 #include "8250.h"
 
@@ -24,6 +25,7 @@
 #define PCI_DEVICE_ID_INTEL_DNV_UART	0x19d8
 
 /* Intel MID Specific registers */
+#define INTEL_MID_UART_DNV_FISR		0x08
 #define INTEL_MID_UART_PS		0x30
 #define INTEL_MID_UART_MUL		0x34
 #define INTEL_MID_UART_DIV		0x38
@@ -31,6 +33,7 @@
 struct mid8250;
 
 struct mid8250_board {
+	unsigned int flags;
 	unsigned long freq;
 	unsigned int base_baud;
 	int (*setup)(struct mid8250 *, struct uart_port *p);
@@ -88,16 +91,16 @@ static int tng_setup(struct mid8250 *mid
 static int dnv_handle_irq(struct uart_port *p)
 {
 	struct mid8250 *mid = p->private_data;
-	int ret;
-
-	ret = hsu_dma_irq(&mid->dma_chip, 0);
-	ret |= hsu_dma_irq(&mid->dma_chip, 1);
+	unsigned int fisr = serial_port_in(p, INTEL_MID_UART_DNV_FISR);
+	int ret = IRQ_NONE;
 
-	/* For now, letting the HW generate separate interrupt for the UART */
-	if (ret)
-		return ret;
-
-	return serial8250_handle_irq(p, serial_port_in(p, UART_IIR));
+	if (fisr & BIT(2))
+		ret |= hsu_dma_irq(&mid->dma_chip, 1);
+	if (fisr & BIT(1))
+		ret |= hsu_dma_irq(&mid->dma_chip, 0);
+	if (fisr & BIT(0))
+		ret |= serial8250_handle_irq(p, serial_port_in(p, UART_IIR));
+	return ret;
 }
 
 #define DNV_DMA_CHAN_OFFSET 0x80
@@ -106,12 +109,13 @@ static int dnv_setup(struct mid8250 *mid
 {
 	struct hsu_dma_chip *chip = &mid->dma_chip;
 	struct pci_dev *pdev = to_pci_dev(p->dev);
+	unsigned int bar = FL_GET_BASE(mid->board->flags);
 	int ret;
 
 	chip->dev = &pdev->dev;
 	chip->irq = pdev->irq;
 	chip->regs = p->membase;
-	chip->length = pci_resource_len(pdev, 0);
+	chip->length = pci_resource_len(pdev, bar);
 	chip->offset = DNV_DMA_CHAN_OFFSET;
 
 	/* Falling back to PIO mode if DMA probing fails */
@@ -145,6 +149,9 @@ static void mid8250_set_termios(struct u
 	unsigned long w = BIT(24) - 1;
 	unsigned long mul, div;
 
+	/* Gracefully handle the B0 case: fall back to B9600 */
+	fuart = fuart ? fuart : 9600 * 16;
+
 	if (mid->board->freq < fuart) {
 		/* Find prescaler value that satisfies Fuart < Fref */
 		if (mid->board->freq > baud)
@@ -217,6 +224,7 @@ static int mid8250_probe(struct pci_dev
 {
 	struct uart_8250_port uart;
 	struct mid8250 *mid;
+	unsigned int bar;
 	int ret;
 
 	ret = pcim_enable_device(pdev);
@@ -230,6 +238,7 @@ static int mid8250_probe(struct pci_dev
 		return -ENOMEM;
 
 	mid->board = (struct mid8250_board *)id->driver_data;
+	bar = FL_GET_BASE(mid->board->flags);
 
 	memset(&uart, 0, sizeof(struct uart_8250_port));
 
@@ -242,8 +251,8 @@ static int mid8250_probe(struct pci_dev
 	uart.port.flags = UPF_SHARE_IRQ | UPF_FIXED_PORT | UPF_FIXED_TYPE;
 	uart.port.set_termios = mid8250_set_termios;
 
-	uart.port.mapbase = pci_resource_start(pdev, 0);
-	uart.port.membase = pcim_iomap(pdev, 0, 0);
+	uart.port.mapbase = pci_resource_start(pdev, bar);
+	uart.port.membase = pcim_iomap(pdev, bar, 0);
 	if (!uart.port.membase)
 		return -ENOMEM;
 
@@ -282,18 +291,21 @@ static void mid8250_remove(struct pci_de
 }
 
 static const struct mid8250_board pnw_board = {
+	.flags = FL_BASE0,
 	.freq = 50000000,
 	.base_baud = 115200,
 	.setup = pnw_setup,
 };
 
 static const struct mid8250_board tng_board = {
+	.flags = FL_BASE0,
 	.freq = 38400000,
 	.base_baud = 1843200,
 	.setup = tng_setup,
 };
 
 static const struct mid8250_board dnv_board = {
+	.flags = FL_BASE1,
 	.freq = 133333333,
 	.base_baud = 115200,
 	.setup = dnv_setup,
--- zfcpdump-kernel-4.4.orig/drivers/tty/serial/8250/8250_pci.c
+++ zfcpdump-kernel-4.4/drivers/tty/serial/8250/8250_pci.c
@@ -1379,6 +1379,9 @@ ce4100_serial_setup(struct serial_privat
 #define PCI_DEVICE_ID_INTEL_BSW_UART1	0x228a
 #define PCI_DEVICE_ID_INTEL_BSW_UART2	0x228c
 
+#define PCI_DEVICE_ID_INTEL_BDW_UART1	0x9ce3
+#define PCI_DEVICE_ID_INTEL_BDW_UART2	0x9ce4
+
 #define BYT_PRV_CLK			0x800
 #define BYT_PRV_CLK_EN			(1 << 0)
 #define BYT_PRV_CLK_M_VAL_SHIFT		1
@@ -1398,6 +1401,9 @@ byt_set_termios(struct uart_port *p, str
 	unsigned long m, n;
 	u32 reg;
 
+	/* Gracefully handle the B0 case: fall back to B9600 */
+	fuart = fuart ? fuart : 9600 * 16;
+
 	/* Get Fuart closer to Fref */
 	fuart *= rounddown_pow_of_two(fref / fuart);
 
@@ -1461,11 +1467,13 @@ byt_serial_setup(struct serial_private *
 	switch (pdev->device) {
 	case PCI_DEVICE_ID_INTEL_BYT_UART1:
 	case PCI_DEVICE_ID_INTEL_BSW_UART1:
+	case PCI_DEVICE_ID_INTEL_BDW_UART1:
 		rx_param->src_id = 3;
 		tx_param->dst_id = 2;
 		break;
 	case PCI_DEVICE_ID_INTEL_BYT_UART2:
 	case PCI_DEVICE_ID_INTEL_BSW_UART2:
+	case PCI_DEVICE_ID_INTEL_BDW_UART2:
 		rx_param->src_id = 5;
 		tx_param->dst_id = 4;
 		break;
@@ -1936,6 +1944,7 @@ pci_wch_ch38x_setup(struct serial_privat
 #define PCIE_VENDOR_ID_WCH		0x1c00
 #define PCIE_DEVICE_ID_WCH_CH382_2S1P	0x3250
 #define PCIE_DEVICE_ID_WCH_CH384_4S	0x3470
+#define PCIE_DEVICE_ID_WCH_CH382_2S	0x3253
 
 #define PCI_VENDOR_ID_PERICOM			0x12D8
 #define PCI_DEVICE_ID_PERICOM_PI7C9X7951	0x7951
@@ -1943,6 +1952,43 @@ pci_wch_ch38x_setup(struct serial_privat
 #define PCI_DEVICE_ID_PERICOM_PI7C9X7954	0x7954
 #define PCI_DEVICE_ID_PERICOM_PI7C9X7958	0x7958
 
+#define PCI_VENDOR_ID_ACCESIO			0x494f
+#define PCI_DEVICE_ID_ACCESIO_PCIE_COM_2SDB	0x1051
+#define PCI_DEVICE_ID_ACCESIO_MPCIE_COM_2S	0x1053
+#define PCI_DEVICE_ID_ACCESIO_PCIE_COM_4SDB	0x105C
+#define PCI_DEVICE_ID_ACCESIO_MPCIE_COM_4S	0x105E
+#define PCI_DEVICE_ID_ACCESIO_PCIE_COM232_2DB	0x1091
+#define PCI_DEVICE_ID_ACCESIO_MPCIE_COM232_2	0x1093
+#define PCI_DEVICE_ID_ACCESIO_PCIE_COM232_4DB	0x1099
+#define PCI_DEVICE_ID_ACCESIO_MPCIE_COM232_4	0x109B
+#define PCI_DEVICE_ID_ACCESIO_PCIE_COM_2SMDB	0x10D1
+#define PCI_DEVICE_ID_ACCESIO_MPCIE_COM_2SM	0x10D3
+#define PCI_DEVICE_ID_ACCESIO_PCIE_COM_4SMDB	0x10DA
+#define PCI_DEVICE_ID_ACCESIO_MPCIE_COM_4SM	0x10DC
+#define PCI_DEVICE_ID_ACCESIO_MPCIE_ICM485_1	0x1108
+#define PCI_DEVICE_ID_ACCESIO_MPCIE_ICM422_2	0x1110
+#define PCI_DEVICE_ID_ACCESIO_MPCIE_ICM485_2	0x1111
+#define PCI_DEVICE_ID_ACCESIO_MPCIE_ICM422_4	0x1118
+#define PCI_DEVICE_ID_ACCESIO_MPCIE_ICM485_4	0x1119
+#define PCI_DEVICE_ID_ACCESIO_PCIE_ICM_2S	0x1152
+#define PCI_DEVICE_ID_ACCESIO_PCIE_ICM_4S	0x115A
+#define PCI_DEVICE_ID_ACCESIO_PCIE_ICM232_2	0x1190
+#define PCI_DEVICE_ID_ACCESIO_MPCIE_ICM232_2	0x1191
+#define PCI_DEVICE_ID_ACCESIO_PCIE_ICM232_4	0x1198
+#define PCI_DEVICE_ID_ACCESIO_MPCIE_ICM232_4	0x1199
+#define PCI_DEVICE_ID_ACCESIO_PCIE_ICM_2SM	0x11D0
+#define PCI_DEVICE_ID_ACCESIO_PCIE_COM422_4	0x105A
+#define PCI_DEVICE_ID_ACCESIO_PCIE_COM485_4	0x105B
+#define PCI_DEVICE_ID_ACCESIO_PCIE_COM422_8	0x106A
+#define PCI_DEVICE_ID_ACCESIO_PCIE_COM485_8	0x106B
+#define PCI_DEVICE_ID_ACCESIO_PCIE_COM232_4	0x1098
+#define PCI_DEVICE_ID_ACCESIO_PCIE_COM232_8	0x10A9
+#define PCI_DEVICE_ID_ACCESIO_PCIE_COM_4SM	0x10D9
+#define PCI_DEVICE_ID_ACCESIO_PCIE_COM_8SM	0x10E9
+#define PCI_DEVICE_ID_ACCESIO_PCIE_ICM_4SM	0x11D8
+
+
+
 /* Unknown vendors/cards - this should not be in linux/pci_ids.h */
 #define PCI_SUBDEVICE_ID_UNKNOWN_0x1584	0x1584
 #define PCI_SUBDEVICE_ID_UNKNOWN_0x1588	0x1588
@@ -2062,6 +2108,20 @@ static struct pci_serial_quirk pci_seria
 		.subdevice	= PCI_ANY_ID,
 		.setup		= byt_serial_setup,
 	},
+	{
+		.vendor		= PCI_VENDOR_ID_INTEL,
+		.device		= PCI_DEVICE_ID_INTEL_BDW_UART1,
+		.subvendor	= PCI_ANY_ID,
+		.subdevice	= PCI_ANY_ID,
+		.setup		= byt_serial_setup,
+	},
+	{
+		.vendor		= PCI_VENDOR_ID_INTEL,
+		.device		= PCI_DEVICE_ID_INTEL_BDW_UART2,
+		.subvendor	= PCI_ANY_ID,
+		.subdevice	= PCI_ANY_ID,
+		.setup		= byt_serial_setup,
+	},
 	/*
 	 * ITE
 	 */
@@ -2618,6 +2678,14 @@ static struct pci_serial_quirk pci_seria
 		.subdevice	= PCI_ANY_ID,
 		.setup		= pci_wch_ch353_setup,
 	},
+	/* WCH CH382 2S card (16850 clone) */
+	{
+		.vendor         = PCIE_VENDOR_ID_WCH,
+		.device         = PCIE_DEVICE_ID_WCH_CH382_2S,
+		.subvendor      = PCI_ANY_ID,
+		.subdevice      = PCI_ANY_ID,
+		.setup          = pci_wch_ch38x_setup,
+	},
 	/* WCH CH382 2S1P card (16850 clone) */
 	{
 		.vendor         = PCIE_VENDOR_ID_WCH,
@@ -2936,6 +3004,7 @@ enum pci_board_num_t {
 	pbn_fintek_4,
 	pbn_fintek_8,
 	pbn_fintek_12,
+	pbn_wch382_2,
 	pbn_wch384_4,
 	pbn_pericom_PI7C9X7951,
 	pbn_pericom_PI7C9X7952,
@@ -3756,6 +3825,13 @@ static struct pciserial_board pci_boards
 		.base_baud	= 115200,
 		.first_offset	= 0x40,
 	},
+	[pbn_wch382_2] = {
+		.flags		= FL_BASE0,
+		.num_ports	= 2,
+		.base_baud	= 115200,
+		.uart_offset	= 8,
+		.first_offset	= 0xC0,
+	},
 	[pbn_wch384_4] = {
 		.flags		= FL_BASE0,
 		.num_ports	= 4,
@@ -5081,6 +5157,108 @@ static struct pci_device_id serial_pci_t
 		0,
 		0, pbn_pericom_PI7C9X7958 },
 	/*
+	 * ACCES I/O Products quad
+	 */
+	{	PCI_VENDOR_ID_ACCESIO, PCI_DEVICE_ID_ACCESIO_PCIE_COM_2SDB,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_pericom_PI7C9X7954 },
+	{	PCI_VENDOR_ID_ACCESIO, PCI_DEVICE_ID_ACCESIO_MPCIE_COM_2S,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_pericom_PI7C9X7954 },
+	{	PCI_VENDOR_ID_ACCESIO, PCI_DEVICE_ID_ACCESIO_PCIE_COM_4SDB,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_pericom_PI7C9X7954 },
+	{	PCI_VENDOR_ID_ACCESIO, PCI_DEVICE_ID_ACCESIO_MPCIE_COM_4S,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_pericom_PI7C9X7954 },
+	{	PCI_VENDOR_ID_ACCESIO, PCI_DEVICE_ID_ACCESIO_PCIE_COM232_2DB,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_pericom_PI7C9X7954 },
+	{	PCI_VENDOR_ID_ACCESIO, PCI_DEVICE_ID_ACCESIO_MPCIE_COM232_2,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_pericom_PI7C9X7954 },
+	{	PCI_VENDOR_ID_ACCESIO, PCI_DEVICE_ID_ACCESIO_PCIE_COM232_4DB,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_pericom_PI7C9X7954 },
+	{	PCI_VENDOR_ID_ACCESIO, PCI_DEVICE_ID_ACCESIO_MPCIE_COM232_4,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_pericom_PI7C9X7954 },
+	{	PCI_VENDOR_ID_ACCESIO, PCI_DEVICE_ID_ACCESIO_PCIE_COM_2SMDB,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_pericom_PI7C9X7954 },
+	{	PCI_VENDOR_ID_ACCESIO, PCI_DEVICE_ID_ACCESIO_MPCIE_COM_2SM,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_pericom_PI7C9X7954 },
+	{	PCI_VENDOR_ID_ACCESIO, PCI_DEVICE_ID_ACCESIO_PCIE_COM_4SMDB,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_pericom_PI7C9X7954 },
+	{	PCI_VENDOR_ID_ACCESIO, PCI_DEVICE_ID_ACCESIO_MPCIE_COM_4SM,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_pericom_PI7C9X7954 },
+	{	PCI_VENDOR_ID_ACCESIO, PCI_DEVICE_ID_ACCESIO_MPCIE_ICM485_1,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_pericom_PI7C9X7954 },
+	{	PCI_VENDOR_ID_ACCESIO, PCI_DEVICE_ID_ACCESIO_MPCIE_ICM422_2,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_pericom_PI7C9X7954 },
+	{	PCI_VENDOR_ID_ACCESIO, PCI_DEVICE_ID_ACCESIO_MPCIE_ICM485_2,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_pericom_PI7C9X7954 },
+	{	PCI_VENDOR_ID_ACCESIO, PCI_DEVICE_ID_ACCESIO_MPCIE_ICM422_4,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_pericom_PI7C9X7954 },
+	{	PCI_VENDOR_ID_ACCESIO, PCI_DEVICE_ID_ACCESIO_MPCIE_ICM485_4,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_pericom_PI7C9X7954 },
+	{	PCI_VENDOR_ID_ACCESIO, PCI_DEVICE_ID_ACCESIO_PCIE_ICM_2S,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_pericom_PI7C9X7954 },
+	{	PCI_VENDOR_ID_ACCESIO, PCI_DEVICE_ID_ACCESIO_PCIE_ICM_4S,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_pericom_PI7C9X7954 },
+	{	PCI_VENDOR_ID_ACCESIO, PCI_DEVICE_ID_ACCESIO_PCIE_ICM232_2,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_pericom_PI7C9X7954 },
+	{	PCI_VENDOR_ID_ACCESIO, PCI_DEVICE_ID_ACCESIO_MPCIE_ICM232_2,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_pericom_PI7C9X7954 },
+	{	PCI_VENDOR_ID_ACCESIO, PCI_DEVICE_ID_ACCESIO_PCIE_ICM232_4,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_pericom_PI7C9X7954 },
+	{	PCI_VENDOR_ID_ACCESIO, PCI_DEVICE_ID_ACCESIO_MPCIE_ICM232_4,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_pericom_PI7C9X7954 },
+	{	PCI_VENDOR_ID_ACCESIO, PCI_DEVICE_ID_ACCESIO_PCIE_ICM_2SM,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_pericom_PI7C9X7954 },
+	{	PCI_VENDOR_ID_ACCESIO, PCI_DEVICE_ID_ACCESIO_PCIE_COM422_4,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_pericom_PI7C9X7958 },
+	{	PCI_VENDOR_ID_ACCESIO, PCI_DEVICE_ID_ACCESIO_PCIE_COM485_4,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_pericom_PI7C9X7958 },
+	{	PCI_VENDOR_ID_ACCESIO, PCI_DEVICE_ID_ACCESIO_PCIE_COM422_8,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_pericom_PI7C9X7958 },
+	{	PCI_VENDOR_ID_ACCESIO, PCI_DEVICE_ID_ACCESIO_PCIE_COM485_8,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_pericom_PI7C9X7958 },
+	{	PCI_VENDOR_ID_ACCESIO, PCI_DEVICE_ID_ACCESIO_PCIE_COM232_4,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_pericom_PI7C9X7958 },
+	{	PCI_VENDOR_ID_ACCESIO, PCI_DEVICE_ID_ACCESIO_PCIE_COM232_8,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_pericom_PI7C9X7958 },
+	{	PCI_VENDOR_ID_ACCESIO, PCI_DEVICE_ID_ACCESIO_PCIE_COM_4SM,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_pericom_PI7C9X7958 },
+	{	PCI_VENDOR_ID_ACCESIO, PCI_DEVICE_ID_ACCESIO_PCIE_COM_8SM,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_pericom_PI7C9X7958 },
+	{	PCI_VENDOR_ID_ACCESIO, PCI_DEVICE_ID_ACCESIO_PCIE_ICM_4SM,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_pericom_PI7C9X7958 },
+	/*
 	 * Topic TP560 Data/Fax/Voice 56k modem (reported by Evan Clarke)
 	 */
 	{	PCI_VENDOR_ID_TOPIC, PCI_DEVICE_ID_TOPIC_TP560,
@@ -5506,6 +5684,16 @@ static struct pci_device_id serial_pci_t
 		PCI_CLASS_COMMUNICATION_SERIAL << 8, 0xff0000,
 		pbn_byt },
 
+	/* Intel Broadwell */
+	{	PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BDW_UART1,
+		PCI_ANY_ID,  PCI_ANY_ID,
+		PCI_CLASS_COMMUNICATION_SERIAL << 8, 0xff0000,
+		pbn_byt },
+	{	PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BDW_UART2,
+		PCI_ANY_ID,  PCI_ANY_ID,
+		PCI_CLASS_COMMUNICATION_SERIAL << 8, 0xff0000,
+		pbn_byt },
+
 	/*
 	 * Intel Quark x1000
 	 */
@@ -5545,6 +5733,10 @@ static struct pci_device_id serial_pci_t
 		PCI_ANY_ID, PCI_ANY_ID,
 		0, 0, pbn_b0_bt_2_115200 },
 
+	{	PCIE_VENDOR_ID_WCH, PCIE_DEVICE_ID_WCH_CH382_2S,
+		PCI_ANY_ID, PCI_ANY_ID,
+		0, 0, pbn_wch382_2 },
+
 	{	PCIE_VENDOR_ID_WCH, PCIE_DEVICE_ID_WCH_CH384_4S,
 		PCI_ANY_ID, PCI_ANY_ID,
 		0, 0, pbn_wch384_4 },
--- zfcpdump-kernel-4.4.orig/drivers/tty/serial/8250/8250_port.c
+++ zfcpdump-kernel-4.4/drivers/tty/serial/8250/8250_port.c
@@ -713,22 +713,16 @@ static int size_fifo(struct uart_8250_po
  */
 static unsigned int autoconfig_read_divisor_id(struct uart_8250_port *p)
 {
-	unsigned char old_dll, old_dlm, old_lcr;
-	unsigned int id;
+	unsigned char old_lcr;
+	unsigned int id, old_dl;
 
 	old_lcr = serial_in(p, UART_LCR);
 	serial_out(p, UART_LCR, UART_LCR_CONF_MODE_A);
+	old_dl = serial_dl_read(p);
+	serial_dl_write(p, 0);
+	id = serial_dl_read(p);
+	serial_dl_write(p, old_dl);
 
-	old_dll = serial_in(p, UART_DLL);
-	old_dlm = serial_in(p, UART_DLM);
-
-	serial_out(p, UART_DLL, 0);
-	serial_out(p, UART_DLM, 0);
-
-	id = serial_in(p, UART_DLL) | serial_in(p, UART_DLM) << 8;
-
-	serial_out(p, UART_DLL, old_dll);
-	serial_out(p, UART_DLM, old_dlm);
 	serial_out(p, UART_LCR, old_lcr);
 
 	return id;
--- zfcpdump-kernel-4.4.orig/drivers/tty/serial/atmel_serial.c
+++ zfcpdump-kernel-4.4/drivers/tty/serial/atmel_serial.c
@@ -277,6 +277,13 @@ static bool atmel_use_dma_rx(struct uart
 	return atmel_port->use_dma_rx;
 }
 
+static bool atmel_use_fifo(struct uart_port *port)
+{
+	struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
+
+	return atmel_port->fifo_size;
+}
+
 static unsigned int atmel_get_lines_status(struct uart_port *port)
 {
 	struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
@@ -478,19 +485,21 @@ static void atmel_start_tx(struct uart_p
 {
 	struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
 
-	if (atmel_use_pdc_tx(port)) {
-		if (atmel_uart_readl(port, ATMEL_PDC_PTSR) & ATMEL_PDC_TXTEN)
-			/* The transmitter is already running.  Yes, we
-			   really need this.*/
-			return;
+	if (atmel_use_pdc_tx(port) && (atmel_uart_readl(port, ATMEL_PDC_PTSR)
+				       & ATMEL_PDC_TXTEN))
+		/* The transmitter is already running.  Yes, we
+		   really need this.*/
+		return;
 
+	if (atmel_use_pdc_tx(port) || atmel_use_dma_tx(port))
 		if ((port->rs485.flags & SER_RS485_ENABLED) &&
 		    !(port->rs485.flags & SER_RS485_RX_DURING_TX))
 			atmel_stop_rx(port);
 
+	if (atmel_use_pdc_tx(port))
 		/* re-enable PDC transmit */
 		atmel_uart_writel(port, ATMEL_PDC_PTCR, ATMEL_PDC_TXTEN);
-	}
+
 	/* Enable interrupts */
 	atmel_uart_writel(port, ATMEL_US_IER, atmel_port->tx_done_mask);
 }
@@ -2169,7 +2178,12 @@ static void atmel_set_termios(struct uar
 		mode |= ATMEL_US_USMODE_RS485;
 	} else if (termios->c_cflag & CRTSCTS) {
 		/* RS232 with hardware handshake (RTS/CTS) */
-		mode |= ATMEL_US_USMODE_HWHS;
+		if (atmel_use_dma_rx(port) && !atmel_use_fifo(port)) {
+			dev_info(port->dev, "not enabling hardware flow control because DMA is used");
+			termios->c_cflag &= ~CRTSCTS;
+		} else {
+			mode |= ATMEL_US_USMODE_HWHS;
+		}
 	} else {
 		/* RS232 without hadware handshake */
 		mode |= ATMEL_US_USMODE_NORMAL;
--- zfcpdump-kernel-4.4.orig/drivers/tty/serial/msm_serial.c
+++ zfcpdump-kernel-4.4/drivers/tty/serial/msm_serial.c
@@ -726,7 +726,7 @@ static void msm_handle_tx(struct uart_po
 		return;
 	}
 
-	pio_count = CIRC_CNT(xmit->head, xmit->tail, UART_XMIT_SIZE);
+	pio_count = CIRC_CNT_TO_END(xmit->head, xmit->tail, UART_XMIT_SIZE);
 	dma_count = CIRC_CNT_TO_END(xmit->head, xmit->tail, UART_XMIT_SIZE);
 
 	dma_min = 1;	/* Always DMA */
--- zfcpdump-kernel-4.4.orig/drivers/tty/serial/omap-serial.c
+++ zfcpdump-kernel-4.4/drivers/tty/serial/omap-serial.c
@@ -1343,7 +1343,7 @@ static inline void serial_omap_add_conso
 
 /* Enable or disable the rs485 support */
 static int
-serial_omap_config_rs485(struct uart_port *port, struct serial_rs485 *rs485conf)
+serial_omap_config_rs485(struct uart_port *port, struct serial_rs485 *rs485)
 {
 	struct uart_omap_port *up = to_uart_omap_port(port);
 	unsigned int mode;
@@ -1356,8 +1356,12 @@ serial_omap_config_rs485(struct uart_por
 	up->ier = 0;
 	serial_out(up, UART_IER, 0);
 
+	/* Clamp the delays to [0, 100ms] */
+	rs485->delay_rts_before_send = min(rs485->delay_rts_before_send, 100U);
+	rs485->delay_rts_after_send  = min(rs485->delay_rts_after_send, 100U);
+
 	/* store new config */
-	port->rs485 = *rs485conf;
+	port->rs485 = *rs485;
 
 	/*
 	 * Just as a precaution, only allow rs485
--- zfcpdump-kernel-4.4.orig/drivers/tty/serial/samsung.c
+++ zfcpdump-kernel-4.4/drivers/tty/serial/samsung.c
@@ -1263,6 +1263,8 @@ static void s3c24xx_serial_set_termios(s
 	/* check to see if we need  to change clock source */
 
 	if (ourport->baudclk != clk) {
+		clk_prepare_enable(clk);
+
 		s3c24xx_serial_setsource(port, clk_sel);
 
 		if (!IS_ERR(ourport->baudclk)) {
@@ -1270,8 +1272,6 @@ static void s3c24xx_serial_set_termios(s
 			ourport->baudclk = ERR_PTR(-EINVAL);
 		}
 
-		clk_prepare_enable(clk);
-
 		ourport->baudclk = clk;
 		ourport->baudclk_rate = clk ? clk_get_rate(clk) : 0;
 	}
@@ -1676,7 +1676,7 @@ static int s3c24xx_serial_init_port(stru
 		return -ENODEV;
 
 	if (port->mapbase != 0)
-		return 0;
+		return -EINVAL;
 
 	/* setup info for port */
 	port->dev	= &platdev->dev;
@@ -1730,22 +1730,25 @@ static int s3c24xx_serial_init_port(stru
 		ourport->dma = devm_kzalloc(port->dev,
 					    sizeof(*ourport->dma),
 					    GFP_KERNEL);
-		if (!ourport->dma)
-			return -ENOMEM;
+		if (!ourport->dma) {
+			ret = -ENOMEM;
+			goto err;
+		}
 	}
 
 	ourport->clk	= clk_get(&platdev->dev, "uart");
 	if (IS_ERR(ourport->clk)) {
 		pr_err("%s: Controller clock not found\n",
 				dev_name(&platdev->dev));
-		return PTR_ERR(ourport->clk);
+		ret = PTR_ERR(ourport->clk);
+		goto err;
 	}
 
 	ret = clk_prepare_enable(ourport->clk);
 	if (ret) {
 		pr_err("uart: clock failed to prepare+enable: %d\n", ret);
 		clk_put(ourport->clk);
-		return ret;
+		goto err;
 	}
 
 	/* Keep all interrupts masked and cleared */
@@ -1761,7 +1764,12 @@ static int s3c24xx_serial_init_port(stru
 
 	/* reset the fifos (and setup the uart) */
 	s3c24xx_serial_resetport(port, cfg);
+
 	return 0;
+
+err:
+	port->mapbase = 0;
+	return ret;
 }
 
 /* Device driver serial port probe */
--- zfcpdump-kernel-4.4.orig/drivers/tty/serial/sh-sci.c
+++ zfcpdump-kernel-4.4/drivers/tty/serial/sh-sci.c
@@ -38,7 +38,6 @@
 #include <linux/major.h>
 #include <linux/module.h>
 #include <linux/mm.h>
-#include <linux/notifier.h>
 #include <linux/of.h>
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
@@ -116,8 +115,6 @@ struct sci_port {
 	struct timer_list		rx_timer;
 	unsigned int			rx_timeout;
 #endif
-
-	struct notifier_block		freq_transition;
 };
 
 #define SCI_NPORTS CONFIG_SERIAL_SH_SCI_NR_UARTS
@@ -1606,29 +1603,6 @@ static irqreturn_t sci_mpxed_interrupt(i
 	return ret;
 }
 
-/*
- * Here we define a transition notifier so that we can update all of our
- * ports' baud rate when the peripheral clock changes.
- */
-static int sci_notifier(struct notifier_block *self,
-			unsigned long phase, void *p)
-{
-	struct sci_port *sci_port;
-	unsigned long flags;
-
-	sci_port = container_of(self, struct sci_port, freq_transition);
-
-	if (phase == CPUFREQ_POSTCHANGE) {
-		struct uart_port *port = &sci_port->port;
-
-		spin_lock_irqsave(&port->lock, flags);
-		port->uartclk = clk_get_rate(sci_port->iclk);
-		spin_unlock_irqrestore(&port->lock, flags);
-	}
-
-	return NOTIFY_OK;
-}
-
 static const struct sci_irq_desc {
 	const char	*desc;
 	irq_handler_t	handler;
@@ -2559,9 +2533,6 @@ static int sci_remove(struct platform_de
 {
 	struct sci_port *port = platform_get_drvdata(dev);
 
-	cpufreq_unregister_notifier(&port->freq_transition,
-				    CPUFREQ_TRANSITION_NOTIFIER);
-
 	uart_remove_one_port(&sci_uart_driver, &port->port);
 
 	sci_cleanup_single(port);
@@ -2714,16 +2685,6 @@ static int sci_probe(struct platform_dev
 	if (ret)
 		return ret;
 
-	sp->freq_transition.notifier_call = sci_notifier;
-
-	ret = cpufreq_register_notifier(&sp->freq_transition,
-					CPUFREQ_TRANSITION_NOTIFIER);
-	if (unlikely(ret < 0)) {
-		uart_remove_one_port(&sci_uart_driver, &sp->port);
-		sci_cleanup_single(sp);
-		return ret;
-	}
-
 #ifdef CONFIG_SH_STANDARD_BIOS
 	sh_bios_gdb_detach();
 #endif
--- zfcpdump-kernel-4.4.orig/drivers/tty/serial/ucc_uart.c
+++ zfcpdump-kernel-4.4/drivers/tty/serial/ucc_uart.c
@@ -1478,6 +1478,9 @@ static const struct of_device_id ucc_uar
 		.type = "serial",
 		.compatible = "ucc_uart",
 	},
+	{
+		.compatible = "fsl,t1040-ucc-uart",
+	},
 	{},
 };
 MODULE_DEVICE_TABLE(of, ucc_uart_match);
--- zfcpdump-kernel-4.4.orig/drivers/tty/tty_buffer.c
+++ zfcpdump-kernel-4.4/drivers/tty/tty_buffer.c
@@ -37,29 +37,6 @@
 
 #define TTY_BUFFER_PAGE	(((PAGE_SIZE - sizeof(struct tty_buffer)) / 2) & ~0xFF)
 
-/*
- * If all tty flip buffers have been processed by flush_to_ldisc() or
- * dropped by tty_buffer_flush(), check if the linked pty has been closed.
- * If so, wake the reader/poll to process
- */
-static inline void check_other_closed(struct tty_struct *tty)
-{
-	unsigned long flags, old;
-
-	/* transition from TTY_OTHER_CLOSED => TTY_OTHER_DONE must be atomic */
-	for (flags = ACCESS_ONCE(tty->flags);
-	     test_bit(TTY_OTHER_CLOSED, &flags);
-	     ) {
-		old = flags;
-		__set_bit(TTY_OTHER_DONE, &flags);
-		flags = cmpxchg(&tty->flags, old, flags);
-		if (old == flags) {
-			wake_up_interruptible(&tty->read_wait);
-			break;
-		}
-	}
-}
-
 /**
  *	tty_buffer_lock_exclusive	-	gain exclusive access to buffer
  *	tty_buffer_unlock_exclusive	-	release exclusive access
@@ -254,8 +231,6 @@ void tty_buffer_flush(struct tty_struct
 	if (ld && ld->ops->flush_buffer)
 		ld->ops->flush_buffer(tty);
 
-	check_other_closed(tty);
-
 	atomic_dec(&buf->priority);
 	mutex_unlock(&buf->lock);
 }
@@ -505,10 +480,8 @@ static void flush_to_ldisc(struct work_s
 		 */
 		count = smp_load_acquire(&head->commit) - head->read;
 		if (!count) {
-			if (next == NULL) {
-				check_other_closed(tty);
+			if (next == NULL)
 				break;
-			}
 			buf->head = next;
 			tty_buffer_free(port, head);
 			continue;
@@ -597,3 +570,8 @@ bool tty_buffer_cancel_work(struct tty_p
 {
 	return cancel_work_sync(&port->buf.work);
 }
+
+void tty_buffer_flush_work(struct tty_port *port)
+{
+	flush_work(&port->buf.work);
+}
--- zfcpdump-kernel-4.4.orig/drivers/tty/tty_io.c
+++ zfcpdump-kernel-4.4/drivers/tty/tty_io.c
@@ -1462,13 +1462,13 @@ static int tty_reopen(struct tty_struct
 {
 	struct tty_driver *driver = tty->driver;
 
-	if (!tty->count)
-		return -EIO;
-
 	if (driver->type == TTY_DRIVER_TYPE_PTY &&
 	    driver->subtype == PTY_TYPE_MASTER)
 		return -EIO;
 
+	if (!tty->count)
+		return -EAGAIN;
+
 	if (test_bit(TTY_EXCLUSIVE, &tty->flags) && !capable(CAP_SYS_ADMIN))
 		return -EBUSY;
 
@@ -2069,7 +2069,12 @@ retry_open:
 
 		if (tty) {
 			mutex_unlock(&tty_mutex);
-			tty_lock(tty);
+			retval = tty_lock_interruptible(tty);
+			if (retval) {
+				if (retval == -EINTR)
+					retval = -ERESTARTSYS;
+				goto err_unref;
+			}
 			/* safe to drop the kref from tty_driver_lookup_tty() */
 			tty_kref_put(tty);
 			retval = tty_reopen(tty);
@@ -2087,7 +2092,11 @@ retry_open:
 
 	if (IS_ERR(tty)) {
 		retval = PTR_ERR(tty);
-		goto err_file;
+		if (retval != -EAGAIN || signal_pending(current))
+			goto err_file;
+		tty_free_file(filp);
+		schedule();
+		goto retry_open;
 	}
 
 	tty_add_file(tty, filp);
@@ -2156,6 +2165,7 @@ retry_open:
 	return 0;
 err_unlock:
 	mutex_unlock(&tty_mutex);
+err_unref:
 	/* after locks to avoid deadlock */
 	if (!IS_ERR_OR_NULL(driver))
 		tty_driver_kref_put(driver);
@@ -2653,6 +2663,28 @@ static int tiocsetd(struct tty_struct *t
 }
 
 /**
+ *	tiocgetd	-	get line discipline
+ *	@tty: tty device
+ *	@p: pointer to user data
+ *
+ *	Retrieves the line discipline id directly from the ldisc.
+ *
+ *	Locking: waits for ldisc reference (in case the line discipline
+ *		is changing or the tty is being hungup)
+ */
+
+static int tiocgetd(struct tty_struct *tty, int __user *p)
+{
+	struct tty_ldisc *ld;
+	int ret;
+
+	ld = tty_ldisc_ref_wait(tty);
+	ret = put_user(ld->ops->num, p);
+	tty_ldisc_deref(ld);
+	return ret;
+}
+
+/**
  *	send_break	-	performed time break
  *	@tty: device to break on
  *	@duration: timeout in mS
@@ -2878,7 +2910,7 @@ long tty_ioctl(struct file *file, unsign
 	case TIOCGSID:
 		return tiocgsid(tty, real_tty, p);
 	case TIOCGETD:
-		return put_user(tty->ldisc->ops->num, (int __user *)p);
+		return tiocgetd(tty, p);
 	case TIOCSETD:
 		return tiocsetd(tty, p);
 	case TIOCVHANGUP:
--- zfcpdump-kernel-4.4.orig/drivers/tty/tty_mutex.c
+++ zfcpdump-kernel-4.4/drivers/tty/tty_mutex.c
@@ -22,6 +22,14 @@ void __lockfunc tty_lock(struct tty_stru
 }
 EXPORT_SYMBOL(tty_lock);
 
+int tty_lock_interruptible(struct tty_struct *tty)
+{
+	if (WARN(tty->magic != TTY_MAGIC, "L Bad %p\n", tty))
+		return -EIO;
+	tty_kref_get(tty);
+	return mutex_lock_interruptible(&tty->legacy_mutex);
+}
+
 void __lockfunc tty_unlock(struct tty_struct *tty)
 {
 	if (tty->magic != TTY_MAGIC) {
--- zfcpdump-kernel-4.4.orig/drivers/tty/vt/keyboard.c
+++ zfcpdump-kernel-4.4/drivers/tty/vt/keyboard.c
@@ -366,34 +366,22 @@ static void to_utf8(struct vc_data *vc,
 
 static void do_compute_shiftstate(void)
 {
-	unsigned int i, j, k, sym, val;
+	unsigned int k, sym, val;
 
 	shift_state = 0;
 	memset(shift_down, 0, sizeof(shift_down));
 
-	for (i = 0; i < ARRAY_SIZE(key_down); i++) {
-
-		if (!key_down[i])
+	for_each_set_bit(k, key_down, min(NR_KEYS, KEY_CNT)) {
+		sym = U(key_maps[0][k]);
+		if (KTYP(sym) != KT_SHIFT && KTYP(sym) != KT_SLOCK)
 			continue;
 
-		k = i * BITS_PER_LONG;
-
-		for (j = 0; j < BITS_PER_LONG; j++, k++) {
-
-			if (!test_bit(k, key_down))
-				continue;
-
-			sym = U(key_maps[0][k]);
-			if (KTYP(sym) != KT_SHIFT && KTYP(sym) != KT_SLOCK)
-				continue;
-
-			val = KVAL(sym);
-			if (val == KVAL(K_CAPSSHIFT))
-				val = KVAL(K_SHIFT);
+		val = KVAL(sym);
+		if (val == KVAL(K_CAPSSHIFT))
+			val = KVAL(K_SHIFT);
 
-			shift_down[val]++;
-			shift_state |= (1 << val);
-		}
+		shift_down[val]++;
+		shift_state |= BIT(val);
 	}
 }
 
--- zfcpdump-kernel-4.4.orig/drivers/tty/vt/vt.c
+++ zfcpdump-kernel-4.4/drivers/tty/vt/vt.c
@@ -102,6 +102,7 @@
 #include <linux/uaccess.h>
 #include <linux/kdb.h>
 #include <linux/ctype.h>
+#include <linux/screen_info.h>
 
 #define MAX_NR_CON_DRIVER 16
 
@@ -146,7 +147,7 @@ static const struct consw *con_driver_ma
 
 static int con_open(struct tty_struct *, struct file *);
 static void vc_init(struct vc_data *vc, unsigned int rows,
-		    unsigned int cols, int do_clear);
+		    unsigned int cols, int do_clear, int mode);
 static void gotoxy(struct vc_data *vc, int new_x, int new_y);
 static void save_cur(struct vc_data *vc);
 static void reset_terminal(struct vc_data *vc, int do_clear);
@@ -170,6 +171,9 @@ module_param(global_cursor_default, int,
 static int cur_default = CUR_DEFAULT;
 module_param(cur_default, int, S_IRUGO | S_IWUSR);
 
+int vt_handoff = 0;
+module_param_named(handoff, vt_handoff, int, S_IRUGO | S_IWUSR);
+
 /*
  * ignore_poke: don't unblank the screen when things are typed.  This is
  * mainly for the privacy of braille terminal users.
@@ -684,6 +688,13 @@ void redraw_screen(struct vc_data *vc, i
 		}
 		if (tty0dev)
 			sysfs_notify(&tty0dev->kobj, NULL, "active");
+		/*
+		 * If we are switching away from a transparent VT the contents
+		 * will be lost, convert it into a blank text console then
+		 * it will be repainted blank if we ever switch back.
+		 */
+		if (old_vc->vc_mode == KD_TRANSPARENT)
+			old_vc->vc_mode = KD_TEXT;
 	} else {
 		hide_cursor(vc);
 		redraw = 1;
@@ -750,6 +761,7 @@ static void visual_init(struct vc_data *
 	vc->vc_complement_mask = 0;
 	vc->vc_can_do_color = 0;
 	vc->vc_panic_force_write = false;
+	vc->vc_cur_blink_ms = DEFAULT_CURSOR_BLINK_MS;
 	vc->vc_sw->con_init(vc, init);
 	if (!vc->vc_complement_mask)
 		vc->vc_complement_mask = vc->vc_can_do_color ? 0x7700 : 0x0800;
@@ -799,7 +811,7 @@ int vc_allocate(unsigned int currcons)	/
 	    if (global_cursor_default == -1)
 		    global_cursor_default = 1;
 
-	    vc_init(vc, vc->vc_rows, vc->vc_cols, 1);
+	    vc_init(vc, vc->vc_rows, vc->vc_cols, 1, KD_TEXT);
 	    vcs_make_sysfs(currcons);
 	    atomic_notifier_call_chain(&vt_notifier_list, VT_ALLOCATE, &param);
 	}
@@ -2927,7 +2939,7 @@ module_param_named(italic, default_itali
 module_param_named(underline, default_underline_color, int, S_IRUGO | S_IWUSR);
 
 static void vc_init(struct vc_data *vc, unsigned int rows,
-		    unsigned int cols, int do_clear)
+		    unsigned int cols, int do_clear, int mode)
 {
 	int j, k ;
 
@@ -2938,7 +2950,7 @@ static void vc_init(struct vc_data *vc,
 
 	set_origin(vc);
 	vc->vc_pos = vc->vc_origin;
-	reset_vc(vc);
+	reset_vc(vc, mode);
 	for (j=k=0; j<16; j++) {
 		vc->vc_palette[k++] = default_red[j] ;
 		vc->vc_palette[k++] = default_grn[j] ;
@@ -2995,16 +3007,32 @@ static int __init con_init(void)
 		mod_timer(&console_timer, jiffies + (blankinterval * HZ));
 	}
 
+	if (vt_handoff > 0 && vt_handoff <= MAX_NR_CONSOLES) {
+		currcons = vt_handoff - 1;
+		vc_cons[currcons].d = vc = kzalloc(sizeof(struct vc_data), GFP_NOWAIT);
+		INIT_WORK(&vc_cons[currcons].SAK_work, vc_SAK);
+		tty_port_init(&vc->port);
+		visual_init(vc, currcons, 1);
+		vc->vc_screenbuf = kzalloc(vc->vc_screenbuf_size, GFP_NOWAIT);
+		vc_init(vc, vc->vc_rows, vc->vc_cols, 0, KD_TRANSPARENT);
+	}
 	for (currcons = 0; currcons < MIN_NR_CONSOLES; currcons++) {
+		if (currcons == vt_handoff - 1)
+			continue;
 		vc_cons[currcons].d = vc = kzalloc(sizeof(struct vc_data), GFP_NOWAIT);
 		INIT_WORK(&vc_cons[currcons].SAK_work, vc_SAK);
 		tty_port_init(&vc->port);
 		visual_init(vc, currcons, 1);
 		vc->vc_screenbuf = kzalloc(vc->vc_screenbuf_size, GFP_NOWAIT);
 		vc_init(vc, vc->vc_rows, vc->vc_cols,
-			currcons || !vc->vc_sw->con_save_screen);
+			currcons || !vc->vc_sw->con_save_screen, KD_TEXT);
 	}
 	currcons = fg_console = 0;
+	if (vt_handoff > 0) {
+		printk(KERN_INFO "vt handoff: transparent VT on vt#%d\n",
+								vt_handoff);
+		currcons = fg_console = vt_handoff - 1;
+	}
 	master_display_fg = vc = vc_cons[currcons].d;
 	set_origin(vc);
 	save_screen(vc);
@@ -3583,9 +3611,10 @@ static int do_register_con_driver(const
 		goto err;
 
 	desc = csw->con_startup();
-
-	if (!desc)
+	if (!desc) {
+		retval = -ENODEV;
 		goto err;
+	}
 
 	retval = -EINVAL;
 
--- zfcpdump-kernel-4.4.orig/drivers/tty/vt/vt_ioctl.c
+++ zfcpdump-kernel-4.4/drivers/tty/vt/vt_ioctl.c
@@ -1046,9 +1046,9 @@ out:
 	return ret;
 }
 
-void reset_vc(struct vc_data *vc)
+void reset_vc(struct vc_data *vc, int mode)
 {
-	vc->vc_mode = KD_TEXT;
+	vc->vc_mode = mode;
 	vt_reset_unicode(vc->vc_num);
 	vc->vt_mode.mode = VT_AUTO;
 	vc->vt_mode.waitv = 0;
@@ -1080,7 +1080,7 @@ void vc_SAK(struct work_struct *work)
 		 */
 		if (tty)
 			__do_SAK(tty);
-		reset_vc(vc);
+		reset_vc(vc, KD_TEXT);
 	}
 	console_unlock();
 }
@@ -1337,7 +1337,7 @@ static void complete_change_console(stru
 		 * this outside of VT_PROCESS but there is no single process
 		 * to account for and tracking tty count may be undesirable.
 		 */
-			reset_vc(vc);
+			reset_vc(vc, KD_TEXT);
 
 			if (old_vc_mode != vc->vc_mode) {
 				if (vc->vc_mode == KD_TEXT)
@@ -1409,7 +1409,7 @@ void change_console(struct vc_data *new_
 		 * this outside of VT_PROCESS but there is no single process
 		 * to account for and tracking tty count may be undesirable.
 		 */
-		reset_vc(vc);
+		reset_vc(vc, KD_TEXT);
 
 		/*
 		 * Fall through to normal (VT_AUTO) handling of the switch...
--- zfcpdump-kernel-4.4.orig/drivers/usb/chipidea/otg.c
+++ zfcpdump-kernel-4.4/drivers/usb/chipidea/otg.c
@@ -158,7 +158,7 @@ static void ci_otg_work(struct work_stru
 int ci_hdrc_otg_init(struct ci_hdrc *ci)
 {
 	INIT_WORK(&ci->work, ci_otg_work);
-	ci->wq = create_singlethread_workqueue("ci_otg");
+	ci->wq = create_freezable_workqueue("ci_otg");
 	if (!ci->wq) {
 		dev_err(ci->dev, "can't create workqueue\n");
 		return -ENODEV;
--- zfcpdump-kernel-4.4.orig/drivers/usb/chipidea/udc.c
+++ zfcpdump-kernel-4.4/drivers/usb/chipidea/udc.c
@@ -939,6 +939,15 @@ static int isr_setup_status_phase(struct
 	int retval;
 	struct ci_hw_ep *hwep;
 
+	/*
+	 * Unexpected USB controller behavior, caused by bad signal integrity
+	 * or ground reference problems, can lead to isr_setup_status_phase
+	 * being called with ci->status equal to NULL.
+	 * If this situation occurs, you should review your USB hardware design.
+	 */
+	if (WARN_ON_ONCE(!ci->status))
+		return -EPIPE;
+
 	hwep = (ci->ep0_dir == TX) ? ci->ep0out : ci->ep0in;
 	ci->status->context = ci;
 	ci->status->complete = isr_setup_status_complete;
@@ -1585,8 +1594,11 @@ static int ci_udc_pullup(struct usb_gadg
 {
 	struct ci_hdrc *ci = container_of(_gadget, struct ci_hdrc, gadget);
 
-	/* Data+ pullup controlled by OTG state machine in OTG fsm mode */
-	if (ci_otg_is_fsm_mode(ci))
+	/*
+	 * Data+ pullup controlled by OTG state machine in OTG fsm mode;
+	 * and don't touch Data+ in host mode for dual role config.
+	 */
+	if (ci_otg_is_fsm_mode(ci) || ci->role == CI_ROLE_HOST)
 		return 0;
 
 	pm_runtime_get_sync(&ci->gadget.dev);
--- zfcpdump-kernel-4.4.orig/drivers/usb/class/cdc-acm.c
+++ zfcpdump-kernel-4.4/drivers/usb/class/cdc-acm.c
@@ -428,7 +428,8 @@ static void acm_read_bulk_callback(struc
 		set_bit(rb->index, &acm->read_urbs_free);
 		dev_dbg(&acm->data->dev, "%s - non-zero urb status: %d\n",
 							__func__, status);
-		return;
+		if ((status != -ENOENT) || (urb->actual_length == 0))
+			return;
 	}
 
 	usb_mark_last_busy(acm->dev);
@@ -1113,6 +1114,9 @@ static int acm_probe(struct usb_interfac
 	if (quirks == NO_UNION_NORMAL) {
 		data_interface = usb_ifnum_to_if(usb_dev, 1);
 		control_interface = usb_ifnum_to_if(usb_dev, 0);
+		/* we would crash */
+		if (!data_interface || !control_interface)
+			return -ENODEV;
 		goto skip_normal_probe;
 	}
 
@@ -1332,7 +1336,6 @@ made_compressed_probe:
 	spin_lock_init(&acm->write_lock);
 	spin_lock_init(&acm->read_lock);
 	mutex_init(&acm->mutex);
-	acm->rx_endpoint = usb_rcvbulkpipe(usb_dev, epread->bEndpointAddress);
 	acm->is_int_ep = usb_endpoint_xfer_int(epread);
 	if (acm->is_int_ep)
 		acm->bInterval = epread->bInterval;
@@ -1372,14 +1375,14 @@ made_compressed_probe:
 		urb->transfer_dma = rb->dma;
 		if (acm->is_int_ep) {
 			usb_fill_int_urb(urb, acm->dev,
-					 acm->rx_endpoint,
+					 usb_rcvintpipe(usb_dev, epread->bEndpointAddress),
 					 rb->base,
 					 acm->readsize,
 					 acm_read_bulk_callback, rb,
 					 acm->bInterval);
 		} else {
 			usb_fill_bulk_urb(urb, acm->dev,
-					  acm->rx_endpoint,
+					  usb_rcvbulkpipe(usb_dev, epread->bEndpointAddress),
 					  rb->base,
 					  acm->readsize,
 					  acm_read_bulk_callback, rb);
@@ -1404,6 +1407,8 @@ made_compressed_probe:
 				usb_sndbulkpipe(usb_dev, epwrite->bEndpointAddress),
 				NULL, acm->writesize, acm_write_bulk, snd);
 		snd->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+		if (quirks & SEND_ZERO_PACKET)
+			snd->urb->transfer_flags |= URB_ZERO_PACKET;
 		snd->instance = acm;
 	}
 
@@ -1838,6 +1843,11 @@ static const struct usb_device_id acm_id
 	},
 #endif
 
+	/*Samsung phone in firmware update mode */
+	{ USB_DEVICE(0x04e8, 0x685d),
+	.driver_info = IGNORE_DEVICE,
+	},
+
 	/* Exclude Infineon Flash Loader utility */
 	{ USB_DEVICE(0x058b, 0x0041),
 	.driver_info = IGNORE_DEVICE,
@@ -1861,6 +1871,10 @@ static const struct usb_device_id acm_id
 	{ USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ACM,
 		USB_CDC_ACM_PROTO_AT_CDMA) },
 
+	{ USB_DEVICE(0x1519, 0x0452), /* Intel 7260 modem */
+	.driver_info = SEND_ZERO_PACKET,
+	},
+
 	{ }
 };
 
--- zfcpdump-kernel-4.4.orig/drivers/usb/class/cdc-acm.h
+++ zfcpdump-kernel-4.4/drivers/usb/class/cdc-acm.h
@@ -95,7 +95,6 @@ struct acm {
 	struct urb *read_urbs[ACM_NR];
 	struct acm_rb read_buffers[ACM_NR];
 	int rx_buflimit;
-	int rx_endpoint;
 	spinlock_t read_lock;
 	int write_used;					/* number of non-empty write buffers */
 	int transmitting;
@@ -134,3 +133,4 @@ struct acm {
 #define IGNORE_DEVICE			BIT(5)
 #define QUIRK_CONTROL_LINE_STATE	BIT(6)
 #define CLEAR_HALT_CONDITIONS		BIT(7)
+#define SEND_ZERO_PACKET		BIT(8)
--- zfcpdump-kernel-4.4.orig/drivers/usb/class/usbtmc.c
+++ zfcpdump-kernel-4.4/drivers/usb/class/usbtmc.c
@@ -121,6 +121,7 @@ static void usbtmc_delete(struct kref *k
 	struct usbtmc_device_data *data = to_usbtmc_data(kref);
 
 	usb_put_dev(data->usb_dev);
+	kfree(data);
 }
 
 static int usbtmc_open(struct inode *inode, struct file *filp)
@@ -1104,7 +1105,7 @@ static int usbtmc_probe(struct usb_inter
 
 	dev_dbg(&intf->dev, "%s called\n", __func__);
 
-	data = devm_kzalloc(&intf->dev, sizeof(*data), GFP_KERNEL);
+	data = kmalloc(sizeof(*data), GFP_KERNEL);
 	if (!data)
 		return -ENOMEM;
 
--- zfcpdump-kernel-4.4.orig/drivers/usb/common/common.c
+++ zfcpdump-kernel-4.4/drivers/usb/common/common.c
@@ -50,6 +50,7 @@ static const char *const speed_names[] =
 	[USB_SPEED_HIGH] = "high-speed",
 	[USB_SPEED_WIRELESS] = "wireless",
 	[USB_SPEED_SUPER] = "super-speed",
+	[USB_SPEED_SUPER_PLUS] = "super-speed-plus",
 };
 
 const char *usb_speed_string(enum usb_device_speed speed)
--- zfcpdump-kernel-4.4.orig/drivers/usb/common/usb-otg-fsm.c
+++ zfcpdump-kernel-4.4/drivers/usb/common/usb-otg-fsm.c
@@ -21,6 +21,7 @@
  * 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
+#include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/types.h>
 #include <linux/mutex.h>
@@ -365,3 +366,4 @@ int otg_statemachine(struct otg_fsm *fsm
 	return state_changed;
 }
 EXPORT_SYMBOL_GPL(otg_statemachine);
+MODULE_LICENSE("GPL");
--- zfcpdump-kernel-4.4.orig/drivers/usb/core/config.c
+++ zfcpdump-kernel-4.4/drivers/usb/core/config.c
@@ -43,6 +43,27 @@ static int find_next_descriptor(unsigned
 	return buffer - buffer0;
 }
 
+static void usb_parse_ssp_isoc_endpoint_companion(struct device *ddev,
+		int cfgno, int inum, int asnum, struct usb_host_endpoint *ep,
+		unsigned char *buffer, int size)
+{
+	struct usb_ssp_isoc_ep_comp_descriptor *desc;
+
+	/*
+	 * The SuperSpeedPlus Isoc endpoint companion descriptor immediately
+	 * follows the SuperSpeed Endpoint Companion descriptor
+	 */
+	desc = (struct usb_ssp_isoc_ep_comp_descriptor *) buffer;
+	if (desc->bDescriptorType != USB_DT_SSP_ISOC_ENDPOINT_COMP ||
+	    size < USB_DT_SSP_ISOC_EP_COMP_SIZE) {
+		dev_warn(ddev, "Invalid SuperSpeedPlus isoc endpoint companion"
+			 "for config %d interface %d altsetting %d ep %d.\n",
+			 cfgno, inum, asnum, ep->desc.bEndpointAddress);
+		return;
+	}
+	memcpy(&ep->ssp_isoc_ep_comp, desc, USB_DT_SSP_ISOC_EP_COMP_SIZE);
+}
+
 static void usb_parse_ss_endpoint_companion(struct device *ddev, int cfgno,
 		int inum, int asnum, struct usb_host_endpoint *ep,
 		unsigned char *buffer, int size)
@@ -54,6 +75,7 @@ static void usb_parse_ss_endpoint_compan
 	 * be the first thing immediately following the endpoint descriptor.
 	 */
 	desc = (struct usb_ss_ep_comp_descriptor *) buffer;
+
 	if (desc->bDescriptorType != USB_DT_SS_ENDPOINT_COMP ||
 			size < USB_DT_SS_EP_COMP_SIZE) {
 		dev_warn(ddev, "No SuperSpeed endpoint companion for config %d "
@@ -76,7 +98,8 @@ static void usb_parse_ss_endpoint_compan
 					ep->desc.wMaxPacketSize;
 		return;
 	}
-
+	buffer += desc->bLength;
+	size -= desc->bLength;
 	memcpy(&ep->ss_ep_comp, desc, USB_DT_SS_EP_COMP_SIZE);
 
 	/* Check the various values */
@@ -112,6 +135,7 @@ static void usb_parse_ss_endpoint_compan
 				cfgno, inum, asnum, ep->desc.bEndpointAddress);
 		ep->ss_ep_comp.bmAttributes = 16;
 	} else if (usb_endpoint_xfer_isoc(&ep->desc) &&
+		   !USB_SS_SSP_ISOC_COMP(desc->bmAttributes) &&
 		   USB_SS_MULT(desc->bmAttributes) > 3) {
 		dev_warn(ddev, "Isoc endpoint has Mult of %d in "
 				"config %d interface %d altsetting %d ep %d: "
@@ -140,8 +164,38 @@ static void usb_parse_ss_endpoint_compan
 				max_tx);
 		ep->ss_ep_comp.wBytesPerInterval = cpu_to_le16(max_tx);
 	}
+	/* Parse a possible SuperSpeedPlus isoc ep companion descriptor */
+	if (usb_endpoint_xfer_isoc(&ep->desc) &&
+	    USB_SS_SSP_ISOC_COMP(desc->bmAttributes))
+		usb_parse_ssp_isoc_endpoint_companion(ddev, cfgno, inum, asnum,
+							ep, buffer, size);
 }
 
+static const unsigned short low_speed_maxpacket_maxes[4] = {
+	[USB_ENDPOINT_XFER_CONTROL] = 8,
+	[USB_ENDPOINT_XFER_ISOC] = 0,
+	[USB_ENDPOINT_XFER_BULK] = 0,
+	[USB_ENDPOINT_XFER_INT] = 8,
+};
+static const unsigned short full_speed_maxpacket_maxes[4] = {
+	[USB_ENDPOINT_XFER_CONTROL] = 64,
+	[USB_ENDPOINT_XFER_ISOC] = 1023,
+	[USB_ENDPOINT_XFER_BULK] = 64,
+	[USB_ENDPOINT_XFER_INT] = 64,
+};
+static const unsigned short high_speed_maxpacket_maxes[4] = {
+	[USB_ENDPOINT_XFER_CONTROL] = 64,
+	[USB_ENDPOINT_XFER_ISOC] = 1024,
+	[USB_ENDPOINT_XFER_BULK] = 512,
+	[USB_ENDPOINT_XFER_INT] = 1024,
+};
+static const unsigned short super_speed_maxpacket_maxes[4] = {
+	[USB_ENDPOINT_XFER_CONTROL] = 512,
+	[USB_ENDPOINT_XFER_ISOC] = 1024,
+	[USB_ENDPOINT_XFER_BULK] = 1024,
+	[USB_ENDPOINT_XFER_INT] = 1024,
+};
+
 static int usb_parse_endpoint(struct device *ddev, int cfgno, int inum,
     int asnum, struct usb_host_interface *ifp, int num_ep,
     unsigned char *buffer, int size)
@@ -150,6 +204,8 @@ static int usb_parse_endpoint(struct dev
 	struct usb_endpoint_descriptor *d;
 	struct usb_host_endpoint *endpoint;
 	int n, i, j, retval;
+	unsigned int maxp;
+	const unsigned short *maxpacket_maxes;
 
 	d = (struct usb_endpoint_descriptor *) buffer;
 	buffer += d->bLength;
@@ -184,22 +240,27 @@ static int usb_parse_endpoint(struct dev
 	memcpy(&endpoint->desc, d, n);
 	INIT_LIST_HEAD(&endpoint->urb_list);
 
-	/* Fix up bInterval values outside the legal range. Use 32 ms if no
-	 * proper value can be guessed. */
+	/*
+	 * Fix up bInterval values outside the legal range.
+	 * Use 10 or 8 ms if no proper value can be guessed.
+	 */
 	i = 0;		/* i = min, j = max, n = default */
 	j = 255;
 	if (usb_endpoint_xfer_int(d)) {
 		i = 1;
 		switch (to_usb_device(ddev)->speed) {
+		case USB_SPEED_SUPER_PLUS:
 		case USB_SPEED_SUPER:
 		case USB_SPEED_HIGH:
-			/* Many device manufacturers are using full-speed
+			/*
+			 * Many device manufacturers are using full-speed
 			 * bInterval values in high-speed interrupt endpoint
-			 * descriptors. Try to fix those and fall back to a
-			 * 32 ms default value otherwise. */
+			 * descriptors. Try to fix those and fall back to an
+			 * 8-ms default value otherwise.
+			 */
 			n = fls(d->bInterval*8);
 			if (n == 0)
-				n = 9;	/* 32 ms = 2^(9-1) uframes */
+				n = 7;	/* 8 ms = 2^(7-1) uframes */
 			j = 16;
 
 			/*
@@ -214,10 +275,12 @@ static int usb_parse_endpoint(struct dev
 			}
 			break;
 		default:		/* USB_SPEED_FULL or _LOW */
-			/* For low-speed, 10 ms is the official minimum.
+			/*
+			 * For low-speed, 10 ms is the official minimum.
 			 * But some "overclocked" devices might want faster
-			 * polling so we'll allow it. */
-			n = 32;
+			 * polling so we'll allow it.
+			 */
+			n = 10;
 			break;
 		}
 	} else if (usb_endpoint_xfer_isoc(d)) {
@@ -225,10 +288,10 @@ static int usb_parse_endpoint(struct dev
 		j = 16;
 		switch (to_usb_device(ddev)->speed) {
 		case USB_SPEED_HIGH:
-			n = 9;		/* 32 ms = 2^(9-1) uframes */
+			n = 7;		/* 8 ms = 2^(7-1) uframes */
 			break;
 		default:		/* USB_SPEED_FULL */
-			n = 6;		/* 32 ms = 2^(6-1) frames */
+			n = 4;		/* 8 ms = 2^(4-1) frames */
 			break;
 		}
 	}
@@ -256,6 +319,42 @@ static int usb_parse_endpoint(struct dev
 			endpoint->desc.wMaxPacketSize = cpu_to_le16(8);
 	}
 
+	/* Validate the wMaxPacketSize field */
+	maxp = usb_endpoint_maxp(&endpoint->desc);
+
+	/* Find the highest legal maxpacket size for this endpoint */
+	i = 0;		/* additional transactions per microframe */
+	switch (to_usb_device(ddev)->speed) {
+	case USB_SPEED_LOW:
+		maxpacket_maxes = low_speed_maxpacket_maxes;
+		break;
+	case USB_SPEED_FULL:
+		maxpacket_maxes = full_speed_maxpacket_maxes;
+		break;
+	case USB_SPEED_HIGH:
+		/* Bits 12..11 are allowed only for HS periodic endpoints */
+		if (usb_endpoint_xfer_int(d) || usb_endpoint_xfer_isoc(d)) {
+			i = maxp & (BIT(12) | BIT(11));
+			maxp &= ~i;
+		}
+		/* fallthrough */
+	default:
+		maxpacket_maxes = high_speed_maxpacket_maxes;
+		break;
+	case USB_SPEED_SUPER:
+	case USB_SPEED_SUPER_PLUS:
+		maxpacket_maxes = super_speed_maxpacket_maxes;
+		break;
+	}
+	j = maxpacket_maxes[usb_endpoint_type(&endpoint->desc)];
+
+	if (maxp > j) {
+		dev_warn(ddev, "config %d interface %d altsetting %d endpoint 0x%X has invalid maxpacket %d, setting to %d\n",
+		    cfgno, inum, asnum, d->bEndpointAddress, maxp, j);
+		maxp = j;
+		endpoint->desc.wMaxPacketSize = cpu_to_le16(i | maxp);
+	}
+
 	/*
 	 * Some buggy high speed devices have bulk endpoints using
 	 * maxpacket sizes other than 512.  High speed HCDs may not
@@ -263,9 +362,6 @@ static int usb_parse_endpoint(struct dev
 	 */
 	if (to_usb_device(ddev)->speed == USB_SPEED_HIGH
 			&& usb_endpoint_xfer_bulk(d)) {
-		unsigned maxp;
-
-		maxp = usb_endpoint_maxp(&endpoint->desc) & 0x07ff;
 		if (maxp != 512)
 			dev_warn(ddev, "config %d interface %d altsetting %d "
 				"bulk endpoint 0x%X has invalid maxpacket %d\n",
@@ -274,7 +370,7 @@ static int usb_parse_endpoint(struct dev
 	}
 
 	/* Parse a possible SuperSpeed endpoint companion descriptor */
-	if (to_usb_device(ddev)->speed == USB_SPEED_SUPER)
+	if (to_usb_device(ddev)->speed >= USB_SPEED_SUPER)
 		usb_parse_ss_endpoint_companion(ddev, cfgno,
 				inum, asnum, endpoint, buffer, size);
 
@@ -862,6 +958,9 @@ int usb_get_bos_descriptor(struct usb_de
 			dev->bos->ss_id =
 				(struct usb_ss_container_id_descriptor *)buffer;
 			break;
+		case USB_PTM_CAP_TYPE:
+			dev->bos->ptm_cap =
+				(struct usb_ptm_cap_descriptor *)buffer;
 		default:
 			break;
 		}
--- zfcpdump-kernel-4.4.orig/drivers/usb/core/devices.c
+++ zfcpdump-kernel-4.4/drivers/usb/core/devices.c
@@ -221,7 +221,7 @@ static char *usb_dump_endpoint_descripto
 		break;
 	case USB_ENDPOINT_XFER_INT:
 		type = "Int.";
-		if (speed == USB_SPEED_HIGH || speed == USB_SPEED_SUPER)
+		if (speed == USB_SPEED_HIGH || speed >= USB_SPEED_SUPER)
 			interval = 1 << (desc->bInterval - 1);
 		else
 			interval = desc->bInterval;
@@ -230,7 +230,7 @@ static char *usb_dump_endpoint_descripto
 		return start;
 	}
 	interval *= (speed == USB_SPEED_HIGH ||
-		     speed == USB_SPEED_SUPER) ? 125 : 1000;
+		     speed >= USB_SPEED_SUPER) ? 125 : 1000;
 	if (interval % 1000)
 		unit = 'u';
 	else {
@@ -322,7 +322,7 @@ static char *usb_dump_config_descriptor(
 
 	if (start > end)
 		return start;
-	if (speed == USB_SPEED_SUPER)
+	if (speed >= USB_SPEED_SUPER)
 		mul = 8;
 	else
 		mul = 2;
@@ -534,6 +534,8 @@ static ssize_t usb_device_dump(char __us
 		speed = "480"; break;
 	case USB_SPEED_SUPER:
 		speed = "5000"; break;
+	case USB_SPEED_SUPER_PLUS:
+		speed = "10000"; break;
 	default:
 		speed = "??";
 	}
@@ -553,7 +555,7 @@ static ssize_t usb_device_dump(char __us
 
 		/* super/high speed reserves 80%, full/low reserves 90% */
 		if (usbdev->speed == USB_SPEED_HIGH ||
-		    usbdev->speed == USB_SPEED_SUPER)
+		    usbdev->speed >= USB_SPEED_SUPER)
 			max = 800;
 		else
 			max = FRAME_TIME_MAX_USECS_ALLOC;
--- zfcpdump-kernel-4.4.orig/drivers/usb/core/devio.c
+++ zfcpdump-kernel-4.4/drivers/usb/core/devio.c
@@ -1203,10 +1203,11 @@ static int proc_getdriver(struct usb_dev
 
 static int proc_connectinfo(struct usb_dev_state *ps, void __user *arg)
 {
-	struct usbdevfs_connectinfo ci = {
-		.devnum = ps->dev->devnum,
-		.slow = ps->dev->speed == USB_SPEED_LOW
-	};
+	struct usbdevfs_connectinfo ci;
+
+	memset(&ci, 0, sizeof(ci));
+	ci.devnum = ps->dev->devnum;
+	ci.slow = ps->dev->speed == USB_SPEED_LOW;
 
 	if (copy_to_user(arg, &ci, sizeof(ci)))
 		return -EFAULT;
@@ -1529,11 +1530,17 @@ static int proc_do_submiturb(struct usb_
 	as->urb->start_frame = uurb->start_frame;
 	as->urb->number_of_packets = number_of_packets;
 	as->urb->stream_id = stream_id;
-	if (uurb->type == USBDEVFS_URB_TYPE_ISO ||
-			ps->dev->speed == USB_SPEED_HIGH)
-		as->urb->interval = 1 << min(15, ep->desc.bInterval - 1);
-	else
-		as->urb->interval = ep->desc.bInterval;
+
+	if (ep->desc.bInterval) {
+		if (uurb->type == USBDEVFS_URB_TYPE_ISO ||
+				ps->dev->speed == USB_SPEED_HIGH ||
+				ps->dev->speed >= USB_SPEED_SUPER)
+			as->urb->interval = 1 <<
+					min(15, ep->desc.bInterval - 1);
+		else
+			as->urb->interval = ep->desc.bInterval;
+	}
+
 	as->urb->context = as;
 	as->urb->complete = async_completed;
 	for (totlen = u = 0; u < number_of_packets; u++) {
--- zfcpdump-kernel-4.4.orig/drivers/usb/core/driver.c
+++ zfcpdump-kernel-4.4/drivers/usb/core/driver.c
@@ -284,7 +284,7 @@ static int usb_probe_interface(struct de
 	struct usb_device *udev = interface_to_usbdev(intf);
 	const struct usb_device_id *id;
 	int error = -ENODEV;
-	int lpm_disable_error;
+	int lpm_disable_error = -ENODEV;
 
 	dev_dbg(dev, "%s\n", __func__);
 
@@ -336,12 +336,14 @@ static int usb_probe_interface(struct de
 	 * setting during probe, that should also be fine.  usb_set_interface()
 	 * will attempt to disable LPM, and fail if it can't disable it.
 	 */
-	lpm_disable_error = usb_unlocked_disable_lpm(udev);
-	if (lpm_disable_error && driver->disable_hub_initiated_lpm) {
-		dev_err(&intf->dev, "%s Failed to disable LPM for driver %s\n.",
-				__func__, driver->name);
-		error = lpm_disable_error;
-		goto err;
+	if (driver->disable_hub_initiated_lpm) {
+		lpm_disable_error = usb_unlocked_disable_lpm(udev);
+		if (lpm_disable_error) {
+			dev_err(&intf->dev, "%s Failed to disable LPM for driver %s\n.",
+					__func__, driver->name);
+			error = lpm_disable_error;
+			goto err;
+		}
 	}
 
 	/* Carry out a deferred switch to altsetting 0 */
@@ -391,7 +393,8 @@ static int usb_unbind_interface(struct d
 	struct usb_interface *intf = to_usb_interface(dev);
 	struct usb_host_endpoint *ep, **eps = NULL;
 	struct usb_device *udev;
-	int i, j, error, r, lpm_disable_error;
+	int i, j, error, r;
+	int lpm_disable_error = -ENODEV;
 
 	intf->condition = USB_INTERFACE_UNBINDING;
 
@@ -399,12 +402,13 @@ static int usb_unbind_interface(struct d
 	udev = interface_to_usbdev(intf);
 	error = usb_autoresume_device(udev);
 
-	/* Hub-initiated LPM policy may change, so attempt to disable LPM until
+	/* If hub-initiated LPM policy may change, attempt to disable LPM until
 	 * the driver is unbound.  If LPM isn't disabled, that's fine because it
 	 * wouldn't be enabled unless all the bound interfaces supported
 	 * hub-initiated LPM.
 	 */
-	lpm_disable_error = usb_unlocked_disable_lpm(udev);
+	if (driver->disable_hub_initiated_lpm)
+		lpm_disable_error = usb_unlocked_disable_lpm(udev);
 
 	/*
 	 * Terminate all URBs for this interface unless the driver
@@ -502,11 +506,15 @@ static int usb_unbind_interface(struct d
 int usb_driver_claim_interface(struct usb_driver *driver,
 				struct usb_interface *iface, void *priv)
 {
-	struct device *dev = &iface->dev;
+	struct device *dev;
 	struct usb_device *udev;
 	int retval = 0;
-	int lpm_disable_error;
+	int lpm_disable_error = -ENODEV;
 
+	if (!iface)
+		return -ENODEV;
+
+	dev = &iface->dev;
 	if (dev->driver)
 		return -EBUSY;
 
@@ -522,12 +530,14 @@ int usb_driver_claim_interface(struct us
 
 	iface->condition = USB_INTERFACE_BOUND;
 
-	/* Disable LPM until this driver is bound. */
-	lpm_disable_error = usb_unlocked_disable_lpm(udev);
-	if (lpm_disable_error && driver->disable_hub_initiated_lpm) {
-		dev_err(&iface->dev, "%s Failed to disable LPM for driver %s\n.",
-				__func__, driver->name);
-		return -ENOMEM;
+	/* See the comment about disabling LPM in usb_probe_interface(). */
+	if (driver->disable_hub_initiated_lpm) {
+		lpm_disable_error = usb_unlocked_disable_lpm(udev);
+		if (lpm_disable_error) {
+			dev_err(&iface->dev, "%s Failed to disable LPM for driver %s\n.",
+					__func__, driver->name);
+			return -ENOMEM;
+		}
 	}
 
 	/* Claimed interfaces are initially inactive (suspended) and
--- zfcpdump-kernel-4.4.orig/drivers/usb/core/hcd-pci.c
+++ zfcpdump-kernel-4.4/drivers/usb/core/hcd-pci.c
@@ -74,6 +74,15 @@ static void for_each_companion(struct pc
 		if (companion->bus != pdev->bus ||
 				PCI_SLOT(companion->devfn) != slot)
 			continue;
+
+		/*
+		 * Companion device should be either UHCI,OHCI or EHCI host
+		 * controller, otherwise skip.
+		 */
+		if (companion->class != CL_UHCI && companion->class != CL_OHCI &&
+				companion->class != CL_EHCI)
+			continue;
+
 		companion_hcd = pci_get_drvdata(companion);
 		if (!companion_hcd || !companion_hcd->self.root_hub)
 			continue;
@@ -197,7 +206,7 @@ int usb_hcd_pci_probe(struct pci_dev *de
 	 * The xHCI driver has its own irq management
 	 * make sure irq setup is not touched for xhci in generic hcd code
 	 */
-	if ((driver->flags & HCD_MASK) != HCD_USB3) {
+	if ((driver->flags & HCD_MASK) < HCD_USB3) {
 		if (!dev->irq) {
 			dev_err(&dev->dev,
 			"Found HC with no IRQ. Check BIOS/PCI %s setup!\n",
--- zfcpdump-kernel-4.4.orig/drivers/usb/core/hcd.c
+++ zfcpdump-kernel-4.4/drivers/usb/core/hcd.c
@@ -128,6 +128,27 @@ static inline int is_root_hub(struct usb
 #define KERNEL_REL	bin2bcd(((LINUX_VERSION_CODE >> 16) & 0x0ff))
 #define KERNEL_VER	bin2bcd(((LINUX_VERSION_CODE >> 8) & 0x0ff))
 
+/* usb 3.1 root hub device descriptor */
+static const u8 usb31_rh_dev_descriptor[18] = {
+	0x12,       /*  __u8  bLength; */
+	USB_DT_DEVICE, /* __u8 bDescriptorType; Device */
+	0x10, 0x03, /*  __le16 bcdUSB; v3.1 */
+
+	0x09,	    /*  __u8  bDeviceClass; HUB_CLASSCODE */
+	0x00,	    /*  __u8  bDeviceSubClass; */
+	0x03,       /*  __u8  bDeviceProtocol; USB 3 hub */
+	0x09,       /*  __u8  bMaxPacketSize0; 2^9 = 512 Bytes */
+
+	0x6b, 0x1d, /*  __le16 idVendor; Linux Foundation 0x1d6b */
+	0x03, 0x00, /*  __le16 idProduct; device 0x0003 */
+	KERNEL_VER, KERNEL_REL, /*  __le16 bcdDevice */
+
+	0x03,       /*  __u8  iManufacturer; */
+	0x02,       /*  __u8  iProduct; */
+	0x01,       /*  __u8  iSerialNumber; */
+	0x01        /*  __u8  bNumConfigurations; */
+};
+
 /* usb 3.0 root hub device descriptor */
 static const u8 usb3_rh_dev_descriptor[18] = {
 	0x12,       /*  __u8  bLength; */
@@ -557,6 +578,8 @@ static int rh_call_control (struct usb_h
 		case USB_DT_DEVICE << 8:
 			switch (hcd->speed) {
 			case HCD_USB31:
+				bufp = usb31_rh_dev_descriptor;
+				break;
 			case HCD_USB3:
 				bufp = usb3_rh_dev_descriptor;
 				break;
@@ -645,9 +668,15 @@ nongeneric:
 		/* non-generic request */
 		switch (typeReq) {
 		case GetHubStatus:
-		case GetPortStatus:
 			len = 4;
 			break;
+		case GetPortStatus:
+			if (wValue == HUB_PORT_STATUS)
+				len = 4;
+			else
+				/* other port status types return 8 bytes */
+				len = 8;
+			break;
 		case GetHubDescriptor:
 			len = sizeof (struct usb_hub_descriptor);
 			break;
@@ -966,9 +995,9 @@ static void usb_bus_init (struct usb_bus
 	bus->bandwidth_allocated = 0;
 	bus->bandwidth_int_reqs  = 0;
 	bus->bandwidth_isoc_reqs = 0;
-	mutex_init(&bus->usb_address0_mutex);
 
 	INIT_LIST_HEAD (&bus->bus_list);
+	mutex_init(&bus->devnum_next_mutex);
 }
 
 /*-------------------------------------------------------------------------*/
@@ -1078,7 +1107,7 @@ static int register_root_hub(struct usb_
 		retval = usb_get_bos_descriptor(usb_dev);
 		if (!retval) {
 			usb_dev->lpm_capable = usb_device_supports_lpm(usb_dev);
-		} else if (usb_dev->speed == USB_SPEED_SUPER) {
+		} else if (usb_dev->speed >= USB_SPEED_SUPER) {
 			mutex_unlock(&usb_bus_list_lock);
 			dev_dbg(parent_dev, "can't read %s bos descriptor %d\n",
 					dev_name(&usb_dev->dev), retval);
@@ -2112,7 +2141,7 @@ int usb_alloc_streams(struct usb_interfa
 	hcd = bus_to_hcd(dev->bus);
 	if (!hcd->driver->alloc_streams || !hcd->driver->free_streams)
 		return -EINVAL;
-	if (dev->speed != USB_SPEED_SUPER)
+	if (dev->speed < USB_SPEED_SUPER)
 		return -EINVAL;
 	if (dev->state < USB_STATE_CONFIGURED)
 		return -ENODEV;
@@ -2160,7 +2189,7 @@ int usb_free_streams(struct usb_interfac
 
 	dev = interface_to_usbdev(interface);
 	hcd = bus_to_hcd(dev->bus);
-	if (dev->speed != USB_SPEED_SUPER)
+	if (dev->speed < USB_SPEED_SUPER)
 		return -EINVAL;
 
 	/* Double-free is not allowed */
@@ -2497,6 +2526,14 @@ struct usb_hcd *usb_create_shared_hcd(co
 		return NULL;
 	}
 	if (primary_hcd == NULL) {
+		hcd->address0_mutex = kmalloc(sizeof(*hcd->address0_mutex),
+				GFP_KERNEL);
+		if (!hcd->address0_mutex) {
+			kfree(hcd);
+			dev_dbg(dev, "hcd address0 mutex alloc failed\n");
+			return NULL;
+		}
+		mutex_init(hcd->address0_mutex);
 		hcd->bandwidth_mutex = kmalloc(sizeof(*hcd->bandwidth_mutex),
 				GFP_KERNEL);
 		if (!hcd->bandwidth_mutex) {
@@ -2508,6 +2545,7 @@ struct usb_hcd *usb_create_shared_hcd(co
 		dev_set_drvdata(dev, hcd);
 	} else {
 		mutex_lock(&usb_port_peer_mutex);
+		hcd->address0_mutex = primary_hcd->address0_mutex;
 		hcd->bandwidth_mutex = primary_hcd->bandwidth_mutex;
 		hcd->primary_hcd = primary_hcd;
 		primary_hcd->primary_hcd = primary_hcd;
@@ -2564,24 +2602,23 @@ EXPORT_SYMBOL_GPL(usb_create_hcd);
  * Don't deallocate the bandwidth_mutex until the last shared usb_hcd is
  * deallocated.
  *
- * Make sure to only deallocate the bandwidth_mutex when the primary HCD is
- * freed.  When hcd_release() is called for either hcd in a peer set
- * invalidate the peer's ->shared_hcd and ->primary_hcd pointers to
- * block new peering attempts
+ * Make sure to deallocate the bandwidth_mutex only when the last HCD is
+ * freed.  When hcd_release() is called for either hcd in a peer set,
+ * invalidate the peer's ->shared_hcd and ->primary_hcd pointers.
  */
 static void hcd_release(struct kref *kref)
 {
 	struct usb_hcd *hcd = container_of (kref, struct usb_hcd, kref);
 
 	mutex_lock(&usb_port_peer_mutex);
-	if (usb_hcd_is_primary_hcd(hcd))
-		kfree(hcd->bandwidth_mutex);
 	if (hcd->shared_hcd) {
 		struct usb_hcd *peer = hcd->shared_hcd;
 
 		peer->shared_hcd = NULL;
-		if (peer->primary_hcd == hcd)
-			peer->primary_hcd = NULL;
+		peer->primary_hcd = NULL;
+	} else {
+		kfree(hcd->address0_mutex);
+		kfree(hcd->bandwidth_mutex);
 	}
 	mutex_unlock(&usb_port_peer_mutex);
 	kfree(hcd);
@@ -2778,9 +2815,11 @@ int usb_add_hcd(struct usb_hcd *hcd,
 		rhdev->speed = USB_SPEED_WIRELESS;
 		break;
 	case HCD_USB3:
-	case HCD_USB31:
 		rhdev->speed = USB_SPEED_SUPER;
 		break;
+	case HCD_USB31:
+		rhdev->speed = USB_SPEED_SUPER_PLUS;
+		break;
 	default:
 		retval = -EINVAL;
 		goto err_set_rh_speed;
--- zfcpdump-kernel-4.4.orig/drivers/usb/core/hub.c
+++ zfcpdump-kernel-4.4/drivers/usb/core/hub.c
@@ -298,7 +298,7 @@ static void usb_set_lpm_parameters(struc
 	unsigned int hub_u1_del;
 	unsigned int hub_u2_del;
 
-	if (!udev->lpm_capable || udev->speed != USB_SPEED_SUPER)
+	if (!udev->lpm_capable || udev->speed < USB_SPEED_SUPER)
 		return;
 
 	hub = usb_hub_to_struct_hub(udev->parent);
@@ -537,29 +537,34 @@ static int get_hub_status(struct usb_dev
 
 /*
  * USB 2.0 spec Section 11.24.2.7
+ * USB 3.1 takes into use the wValue and wLength fields, spec Section 10.16.2.6
  */
 static int get_port_status(struct usb_device *hdev, int port1,
-		struct usb_port_status *data)
+			   void *data, u16 value, u16 length)
 {
 	int i, status = -ETIMEDOUT;
 
 	for (i = 0; i < USB_STS_RETRIES &&
 			(status == -ETIMEDOUT || status == -EPIPE); i++) {
 		status = usb_control_msg(hdev, usb_rcvctrlpipe(hdev, 0),
-			USB_REQ_GET_STATUS, USB_DIR_IN | USB_RT_PORT, 0, port1,
-			data, sizeof(*data), USB_STS_TIMEOUT);
+			USB_REQ_GET_STATUS, USB_DIR_IN | USB_RT_PORT, value,
+			port1, data, length, USB_STS_TIMEOUT);
 	}
 	return status;
 }
 
-static int hub_port_status(struct usb_hub *hub, int port1,
-		u16 *status, u16 *change)
+static int hub_ext_port_status(struct usb_hub *hub, int port1, int type,
+			       u16 *status, u16 *change, u32 *ext_status)
 {
 	int ret;
+	int len = 4;
+
+	if (type != HUB_PORT_STATUS)
+		len = 8;
 
 	mutex_lock(&hub->status_mutex);
-	ret = get_port_status(hub->hdev, port1, &hub->status->port);
-	if (ret < 4) {
+	ret = get_port_status(hub->hdev, port1, &hub->status->port, type, len);
+	if (ret < len) {
 		if (ret != -ENODEV)
 			dev_err(hub->intfdev,
 				"%s failed (err = %d)\n", __func__, ret);
@@ -568,13 +573,22 @@ static int hub_port_status(struct usb_hu
 	} else {
 		*status = le16_to_cpu(hub->status->port.wPortStatus);
 		*change = le16_to_cpu(hub->status->port.wPortChange);
-
+		if (type != HUB_PORT_STATUS && ext_status)
+			*ext_status = le32_to_cpu(
+				hub->status->port.dwExtPortStatus);
 		ret = 0;
 	}
 	mutex_unlock(&hub->status_mutex);
 	return ret;
 }
 
+static int hub_port_status(struct usb_hub *hub, int port1,
+		u16 *status, u16 *change)
+{
+	return hub_ext_port_status(hub, port1, HUB_PORT_STATUS,
+				   status, change, NULL);
+}
+
 static void kick_hub_wq(struct usb_hub *hub)
 {
 	struct usb_interface *intf;
@@ -1036,14 +1050,11 @@ static void hub_activate(struct usb_hub
 
 	/* Continue a partial initialization */
 	if (type == HUB_INIT2 || type == HUB_INIT3) {
-		device_lock(hub->intfdev);
+		device_lock(&hdev->dev);
 
 		/* Was the hub disconnected while we were waiting? */
-		if (hub->disconnected) {
-			device_unlock(hub->intfdev);
-			kref_put(&hub->kref, hub_release);
-			return;
-		}
+		if (hub->disconnected)
+			goto disconnected;
 		if (type == HUB_INIT2)
 			goto init2;
 		goto init3;
@@ -1246,7 +1257,7 @@ static void hub_activate(struct usb_hub
 			queue_delayed_work(system_power_efficient_wq,
 					&hub->init_work,
 					msecs_to_jiffies(delay));
-			device_unlock(hub->intfdev);
+			device_unlock(&hdev->dev);
 			return;		/* Continues at init3: below */
 		} else {
 			msleep(delay);
@@ -1265,12 +1276,12 @@ static void hub_activate(struct usb_hub
 	/* Scan all ports that need attention */
 	kick_hub_wq(hub);
 
-	/* Allow autosuspend if it was suppressed */
-	if (type <= HUB_INIT3)
+	if (type == HUB_INIT2 || type == HUB_INIT3) {
+		/* Allow autosuspend if it was suppressed */
+ disconnected:
 		usb_autopm_put_interface_async(to_usb_interface(hub->intfdev));
-
-	if (type == HUB_INIT2 || type == HUB_INIT3)
-		device_unlock(hub->intfdev);
+		device_unlock(&hdev->dev);
+	}
 
 	kref_put(&hub->kref, hub_release);
 }
@@ -1299,8 +1310,6 @@ static void hub_quiesce(struct usb_hub *
 	struct usb_device *hdev = hub->hdev;
 	int i;
 
-	cancel_delayed_work_sync(&hub->init_work);
-
 	/* hub_wq and related activity won't re-trigger */
 	hub->quiescing = 1;
 
@@ -2066,7 +2075,7 @@ static void choose_devnum(struct usb_dev
 	struct usb_bus	*bus = udev->bus;
 
 	/* be safe when more hub events are proceed in parallel */
-	mutex_lock(&bus->usb_address0_mutex);
+	mutex_lock(&bus->devnum_next_mutex);
 	if (udev->wusb) {
 		devnum = udev->portnum + 1;
 		BUG_ON(test_bit(devnum, bus->devmap.devicemap));
@@ -2084,7 +2093,7 @@ static void choose_devnum(struct usb_dev
 		set_bit(devnum, bus->devmap.devicemap);
 		udev->devnum = devnum;
 	}
-	mutex_unlock(&bus->usb_address0_mutex);
+	mutex_unlock(&bus->devnum_next_mutex);
 }
 
 static void release_devnum(struct usb_device *udev)
@@ -2612,6 +2621,32 @@ out_authorized:
 	return result;
 }
 
+/*
+ * Return 1 if port speed is SuperSpeedPlus, 0 otherwise
+ * check it from the link protocol field of the current speed ID attribute.
+ * current speed ID is got from ext port status request. Sublink speed attribute
+ * table is returned with the hub BOS SSP device capability descriptor
+ */
+static int port_speed_is_ssp(struct usb_device *hdev, int speed_id)
+{
+	int ssa_count;
+	u32 ss_attr;
+	int i;
+	struct usb_ssp_cap_descriptor *ssp_cap = hdev->bos->ssp_cap;
+
+	if (!ssp_cap)
+		return 0;
+
+	ssa_count = le32_to_cpu(ssp_cap->bmAttributes) &
+		USB_SSP_SUBLINK_SPEED_ATTRIBS;
+
+	for (i = 0; i <= ssa_count; i++) {
+		ss_attr = le32_to_cpu(ssp_cap->bmSublinkSpeedAttr[i]);
+		if (speed_id == (ss_attr & USB_SSP_SUBLINK_SPEED_SSID))
+			return !!(ss_attr & USB_SSP_SUBLINK_SPEED_LP);
+	}
+	return 0;
+}
 
 /* Returns 1 if @hub is a WUSB root hub, 0 otherwise */
 static unsigned hub_is_wusb(struct usb_hub *hub)
@@ -2645,7 +2680,7 @@ static unsigned hub_is_wusb(struct usb_h
  */
 static bool use_new_scheme(struct usb_device *udev, int retry)
 {
-	if (udev->speed == USB_SPEED_SUPER)
+	if (udev->speed >= USB_SPEED_SUPER)
 		return false;
 
 	return USE_NEW_SCHEME(retry);
@@ -2676,6 +2711,7 @@ static int hub_port_wait_reset(struct us
 	int delay_time, ret;
 	u16 portstatus;
 	u16 portchange;
+	u32 ext_portstatus = 0;
 
 	for (delay_time = 0;
 			delay_time < HUB_RESET_TIMEOUT;
@@ -2684,7 +2720,14 @@ static int hub_port_wait_reset(struct us
 		msleep(delay);
 
 		/* read and decode port status */
-		ret = hub_port_status(hub, port1, &portstatus, &portchange);
+		if (hub_is_superspeedplus(hub->hdev))
+			ret = hub_ext_port_status(hub, port1,
+						  HUB_EXT_PORT_STATUS,
+						  &portstatus, &portchange,
+						  &ext_portstatus);
+		else
+			ret = hub_port_status(hub, port1, &portstatus,
+					      &portchange);
 		if (ret < 0)
 			return ret;
 
@@ -2727,6 +2770,10 @@ static int hub_port_wait_reset(struct us
 
 	if (hub_is_wusb(hub))
 		udev->speed = USB_SPEED_WIRELESS;
+	else if (hub_is_superspeedplus(hub->hdev) &&
+		 port_speed_is_ssp(hub->hdev, ext_portstatus &
+				   USB_EXT_PORT_STAT_RX_SPEED_ID))
+		udev->speed = USB_SPEED_SUPER_PLUS;
 	else if (hub_is_superspeed(hub->hdev))
 		udev->speed = USB_SPEED_SUPER;
 	else if (portstatus & USB_PORT_STAT_HIGH_SPEED)
@@ -3895,17 +3942,30 @@ static void usb_enable_link_state(struct
 		return;
 	}
 
-	if (usb_set_lpm_timeout(udev, state, timeout))
+	if (usb_set_lpm_timeout(udev, state, timeout)) {
 		/* If we can't set the parent hub U1/U2 timeout,
 		 * device-initiated LPM won't be allowed either, so let the xHCI
 		 * host know that this link state won't be enabled.
 		 */
 		hcd->driver->disable_usb3_lpm_timeout(hcd, udev, state);
+	} else {
+		/* Only a configured device will accept the Set Feature
+		 * U1/U2_ENABLE
+		 */
+		if (udev->actconfig)
+			usb_set_device_initiated_lpm(udev, state, true);
 
-	/* Only a configured device will accept the Set Feature U1/U2_ENABLE */
-	else if (udev->actconfig)
-		usb_set_device_initiated_lpm(udev, state, true);
-
+		/* As soon as usb_set_lpm_timeout(timeout) returns 0, the
+		 * hub-initiated LPM is enabled. Thus, LPM is enabled no
+		 * matter the result of usb_set_device_initiated_lpm().
+		 * The only difference is whether device is able to initiate
+		 * LPM.
+		 */
+		if (state == USB3_LPM_U1)
+			udev->usb3_lpm_u1_enabled = 1;
+		else if (state == USB3_LPM_U2)
+			udev->usb3_lpm_u2_enabled = 1;
+	}
 }
 
 /*
@@ -3945,6 +4005,18 @@ static int usb_disable_link_state(struct
 		dev_warn(&udev->dev, "Could not disable xHCI %s timeout, "
 				"bus schedule bandwidth may be impacted.\n",
 				usb3_lpm_names[state]);
+
+	/* As soon as usb_set_lpm_timeout(0) return 0, hub initiated LPM
+	 * is disabled. Hub will disallows link to enter U1/U2 as well,
+	 * even device is initiating LPM. Hence LPM is disabled if hub LPM
+	 * timeout set to 0, no matter device-initiated LPM is disabled or
+	 * not.
+	 */
+	if (state == USB3_LPM_U1)
+		udev->usb3_lpm_u1_enabled = 0;
+	else if (state == USB3_LPM_U2)
+		udev->usb3_lpm_u2_enabled = 0;
+
 	return 0;
 }
 
@@ -3960,7 +4032,7 @@ int usb_disable_lpm(struct usb_device *u
 	struct usb_hcd *hcd;
 
 	if (!udev || !udev->parent ||
-			udev->speed != USB_SPEED_SUPER ||
+			udev->speed < USB_SPEED_SUPER ||
 			!udev->lpm_capable ||
 			udev->state < USB_STATE_DEFAULT)
 		return 0;
@@ -3979,8 +4051,6 @@ int usb_disable_lpm(struct usb_device *u
 	if (usb_disable_link_state(hcd, udev, USB3_LPM_U2))
 		goto enable_lpm;
 
-	udev->usb3_lpm_enabled = 0;
-
 	return 0;
 
 enable_lpm:
@@ -4019,7 +4089,7 @@ void usb_enable_lpm(struct usb_device *u
 	struct usb_hcd *hcd;
 
 	if (!udev || !udev->parent ||
-			udev->speed != USB_SPEED_SUPER ||
+			udev->speed < USB_SPEED_SUPER ||
 			!udev->lpm_capable ||
 			udev->state < USB_STATE_DEFAULT)
 		return;
@@ -4038,8 +4108,6 @@ void usb_enable_lpm(struct usb_device *u
 
 	usb_enable_link_state(hcd, udev, USB3_LPM_U1);
 	usb_enable_link_state(hcd, udev, USB3_LPM_U2);
-
-	udev->usb3_lpm_enabled = 1;
 }
 EXPORT_SYMBOL_GPL(usb_enable_lpm);
 
@@ -4256,7 +4324,7 @@ hub_port_init(struct usb_hub *hub, struc
 {
 	struct usb_device	*hdev = hub->hdev;
 	struct usb_hcd		*hcd = bus_to_hcd(hdev->bus);
-	int			i, j, retval;
+	int			retries, operations, retval, i;
 	unsigned		delay = HUB_SHORT_RESET_TIME;
 	enum usb_device_speed	oldspeed = udev->speed;
 	const char		*speed;
@@ -4276,7 +4344,7 @@ hub_port_init(struct usb_hub *hub, struc
 	if (oldspeed == USB_SPEED_LOW)
 		delay = HUB_LONG_RESET_TIME;
 
-	mutex_lock(&hdev->bus->usb_address0_mutex);
+	mutex_lock(hcd->address0_mutex);
 
 	/* Reset the device; full speed may morph to high speed */
 	/* FIXME a USB 2.0 device may morph into SuperSpeed on reset. */
@@ -4287,7 +4355,9 @@ hub_port_init(struct usb_hub *hub, struc
 
 	retval = -ENODEV;
 
-	if (oldspeed != USB_SPEED_UNKNOWN && oldspeed != udev->speed) {
+	/* Don't allow speed changes at reset, except usb 3.0 to faster */
+	if (oldspeed != USB_SPEED_UNKNOWN && oldspeed != udev->speed &&
+	    !(oldspeed == USB_SPEED_SUPER && udev->speed > oldspeed)) {
 		dev_dbg(&udev->dev, "device reset changed speed!\n");
 		goto fail;
 	}
@@ -4299,6 +4369,7 @@ hub_port_init(struct usb_hub *hub, struc
 	 * reported as 0xff in the device descriptor). WUSB1.0[4.8.1].
 	 */
 	switch (udev->speed) {
+	case USB_SPEED_SUPER_PLUS:
 	case USB_SPEED_SUPER:
 	case USB_SPEED_WIRELESS:	/* fixed at 512 */
 		udev->ep0.desc.wMaxPacketSize = cpu_to_le16(512);
@@ -4325,7 +4396,7 @@ hub_port_init(struct usb_hub *hub, struc
 	else
 		speed = usb_speed_string(udev->speed);
 
-	if (udev->speed != USB_SPEED_SUPER)
+	if (udev->speed < USB_SPEED_SUPER)
 		dev_info(&udev->dev,
 				"%s %s USB device number %d using %s\n",
 				(udev->config) ? "reset" : "new", speed,
@@ -4358,7 +4429,7 @@ hub_port_init(struct usb_hub *hub, struc
 	 * first 8 bytes of the device descriptor to get the ep0 maxpacket
 	 * value.
 	 */
-	for (i = 0; i < GET_DESCRIPTOR_TRIES; (++i, msleep(100))) {
+	for (retries = 0; retries < GET_DESCRIPTOR_TRIES; (++retries, msleep(100))) {
 		bool did_new_scheme = false;
 
 		if (use_new_scheme(udev, retry_counter)) {
@@ -4385,7 +4456,7 @@ hub_port_init(struct usb_hub *hub, struc
 			 * 255 is for WUSB devices, we actually need to use
 			 * 512 (WUSB1.0[4.8.1]).
 			 */
-			for (j = 0; j < 3; ++j) {
+			for (operations = 0; operations < 3; ++operations) {
 				buf->bMaxPacketSize0 = 0;
 				r = usb_control_msg(udev, usb_rcvaddr0pipe(),
 					USB_REQ_GET_DESCRIPTOR, USB_DIR_IN,
@@ -4405,7 +4476,13 @@ hub_port_init(struct usb_hub *hub, struc
 						r = -EPROTO;
 					break;
 				}
-				if (r == 0)
+				/*
+				 * Some devices time out if they are powered on
+				 * when already connected. They need a second
+				 * reset. But only on the first attempt,
+				 * lest we get into a time out/reset loop
+				 */
+				if (r == 0  || (r == -ETIMEDOUT && retries == 0))
 					break;
 			}
 			udev->descriptor.bMaxPacketSize0 =
@@ -4437,7 +4514,7 @@ hub_port_init(struct usb_hub *hub, struc
 		 * authorization will assign the final address.
 		 */
 		if (udev->wusb == 0) {
-			for (j = 0; j < SET_ADDRESS_TRIES; ++j) {
+			for (operations = 0; operations < SET_ADDRESS_TRIES; ++operations) {
 				retval = hub_set_address(udev, devnum);
 				if (retval >= 0)
 					break;
@@ -4449,11 +4526,12 @@ hub_port_init(struct usb_hub *hub, struc
 							devnum, retval);
 				goto fail;
 			}
-			if (udev->speed == USB_SPEED_SUPER) {
+			if (udev->speed >= USB_SPEED_SUPER) {
 				devnum = udev->devnum;
 				dev_info(&udev->dev,
-						"%s SuperSpeed USB device number %d using %s\n",
+						"%s SuperSpeed%s USB device number %d using %s\n",
 						(udev->config) ? "reset" : "new",
+					 (udev->speed == USB_SPEED_SUPER_PLUS) ? "Plus" : "",
 						devnum, udev->bus->controller->driver->name);
 			}
 
@@ -4492,7 +4570,7 @@ hub_port_init(struct usb_hub *hub, struc
 	 * got from those devices show they aren't superspeed devices. Warm
 	 * reset the port attached by the devices can fix them.
 	 */
-	if ((udev->speed == USB_SPEED_SUPER) &&
+	if ((udev->speed >= USB_SPEED_SUPER) &&
 			(le16_to_cpu(udev->descriptor.bcdUSB) < 0x0300)) {
 		dev_err(&udev->dev, "got a wrong device descriptor, "
 				"warm reset device\n");
@@ -4503,7 +4581,7 @@ hub_port_init(struct usb_hub *hub, struc
 	}
 
 	if (udev->descriptor.bMaxPacketSize0 == 0xff ||
-			udev->speed == USB_SPEED_SUPER)
+			udev->speed >= USB_SPEED_SUPER)
 		i = 512;
 	else
 		i = udev->descriptor.bMaxPacketSize0;
@@ -4552,7 +4630,7 @@ fail:
 		hub_port_disable(hub, port1, 0);
 		update_devnum(udev, devnum);	/* for disconnect processing */
 	}
-	mutex_unlock(&hdev->bus->usb_address0_mutex);
+	mutex_unlock(hcd->address0_mutex);
 	return retval;
 }
 
@@ -4713,7 +4791,7 @@ static void hub_port_connect(struct usb_
 		udev->level = hdev->level + 1;
 		udev->wusb = hub_is_wusb(hub);
 
-		/* Only USB 3.0 devices are connected to SuperSpeed hubs. */
+		/* Devices connected to SuperSpeed hubs are USB 3.0 or later */
 		if (hub_is_superspeed(hub->hdev))
 			udev->speed = USB_SPEED_SUPER;
 		else
--- zfcpdump-kernel-4.4.orig/drivers/usb/core/hub.h
+++ zfcpdump-kernel-4.4/drivers/usb/core/hub.h
@@ -136,6 +136,13 @@ static inline int hub_is_superspeed(stru
 	return hdev->descriptor.bDeviceProtocol == USB_HUB_PR_SS;
 }
 
+static inline int hub_is_superspeedplus(struct usb_device *hdev)
+{
+	return (hdev->descriptor.bDeviceProtocol == USB_HUB_PR_SS &&
+		le16_to_cpu(hdev->descriptor.bcdUSB) >= 0x0310 &&
+		hdev->bos->ssp_cap);
+}
+
 static inline unsigned hub_power_on_good_delay(struct usb_hub *hub)
 {
 	unsigned delay = hub->descriptor->bPwrOn2PwrGood * 2;
--- zfcpdump-kernel-4.4.orig/drivers/usb/core/quirks.c
+++ zfcpdump-kernel-4.4/drivers/usb/core/quirks.c
@@ -44,6 +44,9 @@ static const struct usb_device_id usb_qu
 	/* Creative SB Audigy 2 NX */
 	{ USB_DEVICE(0x041e, 0x3020), .driver_info = USB_QUIRK_RESET_RESUME },
 
+	/* USB3503 */
+	{ USB_DEVICE(0x0424, 0x3503), .driver_info = USB_QUIRK_RESET_RESUME },
+
 	/* Microsoft Wireless Laser Mouse 6000 Receiver */
 	{ USB_DEVICE(0x045e, 0x00e1), .driver_info = USB_QUIRK_RESET_RESUME },
 
@@ -125,6 +128,9 @@ static const struct usb_device_id usb_qu
 	{ USB_DEVICE(0x04f3, 0x016f), .driver_info =
 			USB_QUIRK_DEVICE_QUALIFIER },
 
+	{ USB_DEVICE(0x04f3, 0x0381), .driver_info =
+			USB_QUIRK_NO_LPM },
+
 	{ USB_DEVICE(0x04f3, 0x21b8), .driver_info =
 			USB_QUIRK_DEVICE_QUALIFIER },
 
@@ -173,6 +179,10 @@ static const struct usb_device_id usb_qu
 	/* MAYA44USB sound device */
 	{ USB_DEVICE(0x0a92, 0x0091), .driver_info = USB_QUIRK_RESET_RESUME },
 
+	/* ASUS Base Station(T100) */
+	{ USB_DEVICE(0x0b05, 0x17e0), .driver_info =
+			USB_QUIRK_IGNORE_REMOTE_WAKEUP },
+
 	/* Action Semiconductor flash disk */
 	{ USB_DEVICE(0x10d6, 0x2200), .driver_info =
 			USB_QUIRK_STRING_FETCH_255 },
@@ -188,26 +198,22 @@ static const struct usb_device_id usb_qu
 	{ USB_DEVICE(0x1908, 0x1315), .driver_info =
 			USB_QUIRK_HONOR_BNUMINTERFACES },
 
-	/* INTEL VALUE SSD */
-	{ USB_DEVICE(0x8086, 0xf1a5), .driver_info = USB_QUIRK_RESET_RESUME },
-
-	/* USB3503 */
-	{ USB_DEVICE(0x0424, 0x3503), .driver_info = USB_QUIRK_RESET_RESUME },
-
-	/* ASUS Base Station(T100) */
-	{ USB_DEVICE(0x0b05, 0x17e0), .driver_info =
-			USB_QUIRK_IGNORE_REMOTE_WAKEUP },
-
 	/* Protocol and OTG Electrical Test Device */
 	{ USB_DEVICE(0x1a0a, 0x0200), .driver_info =
 			USB_QUIRK_LINEAR_UFRAME_INTR_BINTERVAL },
 
+	/* Acer C120 LED Projector */
+	{ USB_DEVICE(0x1de1, 0xc102), .driver_info = USB_QUIRK_NO_LPM },
+
 	/* Blackmagic Design Intensity Shuttle */
 	{ USB_DEVICE(0x1edb, 0xbd3b), .driver_info = USB_QUIRK_NO_LPM },
 
 	/* Blackmagic Design UltraStudio SDI */
 	{ USB_DEVICE(0x1edb, 0xbd4f), .driver_info = USB_QUIRK_NO_LPM },
 
+	/* INTEL VALUE SSD */
+	{ USB_DEVICE(0x8086, 0xf1a5), .driver_info = USB_QUIRK_RESET_RESUME },
+
 	{ }  /* terminating entry must be last */
 };
 
--- zfcpdump-kernel-4.4.orig/drivers/usb/core/sysfs.c
+++ zfcpdump-kernel-4.4/drivers/usb/core/sysfs.c
@@ -141,6 +141,9 @@ static ssize_t speed_show(struct device
 	case USB_SPEED_SUPER:
 		speed = "5000";
 		break;
+	case USB_SPEED_SUPER_PLUS:
+		speed = "10000";
+		break;
 	default:
 		speed = "unknown";
 	}
@@ -531,7 +534,26 @@ static ssize_t usb2_lpm_besl_store(struc
 }
 static DEVICE_ATTR_RW(usb2_lpm_besl);
 
-static ssize_t usb3_hardware_lpm_show(struct device *dev,
+static ssize_t usb3_hardware_lpm_u1_show(struct device *dev,
+				      struct device_attribute *attr, char *buf)
+{
+	struct usb_device *udev = to_usb_device(dev);
+	const char *p;
+
+	usb_lock_device(udev);
+
+	if (udev->usb3_lpm_u1_enabled)
+		p = "enabled";
+	else
+		p = "disabled";
+
+	usb_unlock_device(udev);
+
+	return sprintf(buf, "%s\n", p);
+}
+static DEVICE_ATTR_RO(usb3_hardware_lpm_u1);
+
+static ssize_t usb3_hardware_lpm_u2_show(struct device *dev,
 				      struct device_attribute *attr, char *buf)
 {
 	struct usb_device *udev = to_usb_device(dev);
@@ -539,7 +561,7 @@ static ssize_t usb3_hardware_lpm_show(st
 
 	usb_lock_device(udev);
 
-	if (udev->usb3_lpm_enabled)
+	if (udev->usb3_lpm_u2_enabled)
 		p = "enabled";
 	else
 		p = "disabled";
@@ -548,7 +570,7 @@ static ssize_t usb3_hardware_lpm_show(st
 
 	return sprintf(buf, "%s\n", p);
 }
-static DEVICE_ATTR_RO(usb3_hardware_lpm);
+static DEVICE_ATTR_RO(usb3_hardware_lpm_u2);
 
 static struct attribute *usb2_hardware_lpm_attr[] = {
 	&dev_attr_usb2_hardware_lpm.attr,
@@ -562,7 +584,8 @@ static struct attribute_group usb2_hardw
 };
 
 static struct attribute *usb3_hardware_lpm_attr[] = {
-	&dev_attr_usb3_hardware_lpm.attr,
+	&dev_attr_usb3_hardware_lpm_u1.attr,
+	&dev_attr_usb3_hardware_lpm_u2.attr,
 	NULL,
 };
 static struct attribute_group usb3_hardware_lpm_attr_group = {
@@ -592,7 +615,8 @@ static int add_power_attributes(struct d
 		if (udev->usb2_hw_lpm_capable == 1)
 			rc = sysfs_merge_group(&dev->kobj,
 					&usb2_hardware_lpm_attr_group);
-		if (udev->lpm_capable == 1)
+		if (udev->speed == USB_SPEED_SUPER &&
+				udev->lpm_capable == 1)
 			rc = sysfs_merge_group(&dev->kobj,
 					&usb3_hardware_lpm_attr_group);
 	}
--- zfcpdump-kernel-4.4.orig/drivers/usb/core/urb.c
+++ zfcpdump-kernel-4.4/drivers/usb/core/urb.c
@@ -401,7 +401,7 @@ int usb_submit_urb(struct urb *urb, gfp_
 		/* SuperSpeed isoc endpoints have up to 16 bursts of up to
 		 * 3 packets each
 		 */
-		if (dev->speed == USB_SPEED_SUPER) {
+		if (dev->speed >= USB_SPEED_SUPER) {
 			int     burst = 1 + ep->ss_ep_comp.bMaxBurst;
 			int     mult = USB_SS_MULT(ep->ss_ep_comp.bmAttributes);
 			max *= burst;
@@ -499,6 +499,7 @@ int usb_submit_urb(struct urb *urb, gfp_
 		}
 		/* too big? */
 		switch (dev->speed) {
+		case USB_SPEED_SUPER_PLUS:
 		case USB_SPEED_SUPER:	/* units are 125us */
 			/* Handle up to 2^(16-1) microframes */
 			if (urb->interval > (1 << 15))
--- zfcpdump-kernel-4.4.orig/drivers/usb/core/usb.h
+++ zfcpdump-kernel-4.4/drivers/usb/core/usb.h
@@ -45,7 +45,7 @@ static inline unsigned usb_get_max_power
 		struct usb_host_config *c)
 {
 	/* SuperSpeed power is in 8 mA units; others are in 2 mA units */
-	unsigned mul = (udev->speed == USB_SPEED_SUPER ? 8 : 2);
+	unsigned mul = (udev->speed >= USB_SPEED_SUPER ? 8 : 2);
 
 	return c->desc.bMaxPower * mul;
 }
--- zfcpdump-kernel-4.4.orig/drivers/usb/dwc2/core.h
+++ zfcpdump-kernel-4.4/drivers/usb/dwc2/core.h
@@ -44,6 +44,17 @@
 #include <linux/usb/phy.h>
 #include "hw.h"
 
+#ifdef CONFIG_MIPS
+/*
+ * There are some MIPS machines that can run in either big-endian
+ * or little-endian mode and that use the dwc2 register without
+ * a byteswap in both ways.
+ * Unlike other architectures, MIPS apparently does not require a
+ * barrier before the __raw_writel() to synchronize with DMA but does
+ * require the barrier after the __raw_writel() to serialize a set of
+ * writes. This set of operations was added specifically for MIPS and
+ * should only be used there.
+ */
 static inline u32 dwc2_readl(const void __iomem *addr)
 {
 	u32 value = __raw_readl(addr);
@@ -70,6 +81,22 @@ static inline void dwc2_writel(u32 value
 	pr_info("INFO:: wrote %08x to %p\n", value, addr);
 #endif
 }
+#else
+/* Normal architectures just use readl/write */
+static inline u32 dwc2_readl(const void __iomem *addr)
+{
+	return readl(addr);
+}
+
+static inline void dwc2_writel(u32 value, void __iomem *addr)
+{
+	writel(value, addr);
+
+#ifdef DWC2_LOG_WRITES
+	pr_info("info:: wrote %08x to %p\n", value, addr);
+#endif
+}
+#endif
 
 /* Maximum number of Endpoints/HostChannels */
 #define MAX_EPS_CHANNELS	16
--- zfcpdump-kernel-4.4.orig/drivers/usb/dwc3/core.h
+++ zfcpdump-kernel-4.4/drivers/usb/dwc3/core.h
@@ -853,7 +853,6 @@ struct dwc3 {
 	unsigned		pullups_connected:1;
 	unsigned		resize_fifos:1;
 	unsigned		setup_packet_pending:1;
-	unsigned		start_config_issued:1;
 	unsigned		three_stage_setup:1;
 	unsigned		usb3_lpm_capable:1;
 
--- zfcpdump-kernel-4.4.orig/drivers/usb/dwc3/dwc3-exynos.c
+++ zfcpdump-kernel-4.4/drivers/usb/dwc3/dwc3-exynos.c
@@ -128,12 +128,6 @@ static int dwc3_exynos_probe(struct plat
 
 	platform_set_drvdata(pdev, exynos);
 
-	ret = dwc3_exynos_register_phys(exynos);
-	if (ret) {
-		dev_err(dev, "couldn't register PHYs\n");
-		return ret;
-	}
-
 	exynos->dev	= dev;
 
 	exynos->clk = devm_clk_get(dev, "usbdrd30");
@@ -183,20 +177,29 @@ static int dwc3_exynos_probe(struct plat
 		goto err3;
 	}
 
+	ret = dwc3_exynos_register_phys(exynos);
+	if (ret) {
+		dev_err(dev, "couldn't register PHYs\n");
+		goto err4;
+	}
+
 	if (node) {
 		ret = of_platform_populate(node, NULL, NULL, dev);
 		if (ret) {
 			dev_err(dev, "failed to add dwc3 core\n");
-			goto err4;
+			goto err5;
 		}
 	} else {
 		dev_err(dev, "no device node, failed to add dwc3 core\n");
 		ret = -ENODEV;
-		goto err4;
+		goto err5;
 	}
 
 	return 0;
 
+err5:
+	platform_device_unregister(exynos->usb2_phy);
+	platform_device_unregister(exynos->usb3_phy);
 err4:
 	regulator_disable(exynos->vdd10);
 err3:
--- zfcpdump-kernel-4.4.orig/drivers/usb/dwc3/dwc3-pci.c
+++ zfcpdump-kernel-4.4/drivers/usb/dwc3/dwc3-pci.c
@@ -36,6 +36,7 @@
 #define PCI_DEVICE_ID_INTEL_SPTH		0xa130
 #define PCI_DEVICE_ID_INTEL_BXT			0x0aaa
 #define PCI_DEVICE_ID_INTEL_APL			0x5aaa
+#define PCI_DEVICE_ID_INTEL_KBP			0xa2b0
 
 static const struct acpi_gpio_params reset_gpios = { 0, 0, false };
 static const struct acpi_gpio_params cs_gpios = { 1, 0, false };
@@ -214,6 +215,7 @@ static const struct pci_device_id dwc3_p
 	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_SPTH), },
 	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BXT), },
 	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_APL), },
+	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_KBP), },
 	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_NL_USB), },
 	{  }	/* Terminating Entry */
 };
--- zfcpdump-kernel-4.4.orig/drivers/usb/dwc3/ep0.c
+++ zfcpdump-kernel-4.4/drivers/usb/dwc3/ep0.c
@@ -555,7 +555,6 @@ static int dwc3_ep0_set_config(struct dw
 	int ret;
 	u32 reg;
 
-	dwc->start_config_issued = false;
 	cfg = le16_to_cpu(ctrl->wValue);
 
 	switch (state) {
@@ -737,10 +736,6 @@ static int dwc3_ep0_std_request(struct d
 		dwc3_trace(trace_dwc3_ep0, "USB_REQ_SET_ISOCH_DELAY");
 		ret = dwc3_ep0_set_isoch_delay(dwc, ctrl);
 		break;
-	case USB_REQ_SET_INTERFACE:
-		dwc3_trace(trace_dwc3_ep0, "USB_REQ_SET_INTERFACE");
-		dwc->start_config_issued = false;
-		/* Fall through */
 	default:
 		dwc3_trace(trace_dwc3_ep0, "Forwarding to gadget driver");
 		ret = dwc3_ep0_delegate_req(dwc, ctrl);
--- zfcpdump-kernel-4.4.orig/drivers/usb/dwc3/gadget.c
+++ zfcpdump-kernel-4.4/drivers/usb/dwc3/gadget.c
@@ -388,24 +388,66 @@ static void dwc3_free_trb_pool(struct dw
 	dep->trb_pool_dma = 0;
 }
 
+static int dwc3_gadget_set_xfer_resource(struct dwc3 *dwc, struct dwc3_ep *dep);
+
+/**
+ * dwc3_gadget_start_config - Configure EP resources
+ * @dwc: pointer to our controller context structure
+ * @dep: endpoint that is being enabled
+ *
+ * The assignment of transfer resources cannot perfectly follow the
+ * data book due to the fact that the controller driver does not have
+ * all knowledge of the configuration in advance. It is given this
+ * information piecemeal by the composite gadget framework after every
+ * SET_CONFIGURATION and SET_INTERFACE. Trying to follow the databook
+ * programming model in this scenario can cause errors. For two
+ * reasons:
+ *
+ * 1) The databook says to do DEPSTARTCFG for every SET_CONFIGURATION
+ * and SET_INTERFACE (8.1.5). This is incorrect in the scenario of
+ * multiple interfaces.
+ *
+ * 2) The databook does not mention doing more DEPXFERCFG for new
+ * endpoint on alt setting (8.1.6).
+ *
+ * The following simplified method is used instead:
+ *
+ * All hardware endpoints can be assigned a transfer resource and this
+ * setting will stay persistent until either a core reset or
+ * hibernation. So whenever we do a DEPSTARTCFG(0) we can go ahead and
+ * do DEPXFERCFG for every hardware endpoint as well. We are
+ * guaranteed that there are as many transfer resources as endpoints.
+ *
+ * This function is called for each endpoint when it is being enabled
+ * but is triggered only when called for EP0-out, which always happens
+ * first, and which should only happen in one of the above conditions.
+ */
 static int dwc3_gadget_start_config(struct dwc3 *dwc, struct dwc3_ep *dep)
 {
 	struct dwc3_gadget_ep_cmd_params params;
 	u32			cmd;
+	int			i;
+	int			ret;
+
+	if (dep->number)
+		return 0;
 
 	memset(&params, 0x00, sizeof(params));
+	cmd = DWC3_DEPCMD_DEPSTARTCFG;
 
-	if (dep->number != 1) {
-		cmd = DWC3_DEPCMD_DEPSTARTCFG;
-		/* XferRscIdx == 0 for ep0 and 2 for the remaining */
-		if (dep->number > 1) {
-			if (dwc->start_config_issued)
-				return 0;
-			dwc->start_config_issued = true;
-			cmd |= DWC3_DEPCMD_PARAM(2);
-		}
+	ret = dwc3_send_gadget_ep_cmd(dwc, 0, cmd, &params);
+	if (ret)
+		return ret;
 
-		return dwc3_send_gadget_ep_cmd(dwc, 0, cmd, &params);
+	for (i = 0; i < DWC3_ENDPOINTS_NUM; i++) {
+		struct dwc3_ep *dep = dwc->eps[i];
+
+		if (!dep)
+			continue;
+
+		ret = dwc3_gadget_set_xfer_resource(dwc, dep);
+		if (ret)
+			return ret;
 	}
 
 	return 0;
@@ -519,10 +561,6 @@ static int __dwc3_gadget_ep_enable(struc
 		struct dwc3_trb	*trb_st_hw;
 		struct dwc3_trb	*trb_link;
 
-		ret = dwc3_gadget_set_xfer_resource(dwc, dep);
-		if (ret)
-			return ret;
-
 		dep->endpoint.desc = desc;
 		dep->comp_desc = comp_desc;
 		dep->type = usb_endpoint_type(desc);
@@ -1604,8 +1642,6 @@ static int dwc3_gadget_start(struct usb_
 	}
 	dwc3_writel(dwc->regs, DWC3_DCFG, reg);
 
-	dwc->start_config_issued = false;
-
 	/* Start with SuperSpeed Default */
 	dwc3_gadget_ep0_desc.wMaxPacketSize = cpu_to_le16(512);
 
@@ -1856,14 +1892,6 @@ static int __dwc3_cleanup_done_trbs(stru
 			s_pkt = 1;
 	}
 
-	/*
-	 * We assume here we will always receive the entire data block
-	 * which we should receive. Meaning, if we program RX to
-	 * receive 4K but we receive only 2K, we assume that's all we
-	 * should receive and we simply bounce the request back to the
-	 * gadget driver for further processing.
-	 */
-	req->request.actual += req->request.length - count;
 	if (s_pkt)
 		return 1;
 	if ((event->status & DEPEVT_STATUS_LST) &&
@@ -1883,6 +1911,7 @@ static int dwc3_cleanup_done_reqs(struct
 	struct dwc3_trb		*trb;
 	unsigned int		slot;
 	unsigned int		i;
+	int			count = 0;
 	int			ret;
 
 	do {
@@ -1899,6 +1928,8 @@ static int dwc3_cleanup_done_reqs(struct
 				slot++;
 			slot %= DWC3_TRB_NUM;
 			trb = &dep->trb_pool[slot];
+			count += trb->size & DWC3_TRB_SIZE_MASK;
+
 
 			ret = __dwc3_cleanup_done_trbs(dwc, dep, req, trb,
 					event, status);
@@ -1906,6 +1937,14 @@ static int dwc3_cleanup_done_reqs(struct
 				break;
 		} while (++i < req->request.num_mapped_sgs);
 
+		/*
+		 * We assume here we will always receive the entire data block
+		 * which we should receive. Meaning, if we program RX to
+		 * receive 4K but we receive only 2K, we assume that's all we
+		 * should receive and we simply bounce the request back to the
+		 * gadget driver for further processing.
+		 */
+		req->request.actual += req->request.length - count;
 		dwc3_gadget_giveback(dep, req, status);
 
 		if (ret)
@@ -1929,6 +1968,10 @@ static int dwc3_cleanup_done_reqs(struct
 		return 1;
 	}
 
+	if (usb_endpoint_xfer_isoc(dep->endpoint.desc))
+		if ((event->status & DEPEVT_STATUS_IOC) &&
+				(trb->ctrl & DWC3_TRB_CTRL_IOC))
+			return 0;
 	return 1;
 }
 
@@ -2202,7 +2245,6 @@ static void dwc3_gadget_disconnect_inter
 	dwc3_writel(dwc->regs, DWC3_DCTL, reg);
 
 	dwc3_disconnect_gadget(dwc);
-	dwc->start_config_issued = false;
 
 	dwc->gadget.speed = USB_SPEED_UNKNOWN;
 	dwc->setup_packet_pending = false;
@@ -2253,7 +2295,6 @@ static void dwc3_gadget_reset_interrupt(
 
 	dwc3_stop_active_transfers(dwc);
 	dwc3_clear_stall_all_ep(dwc);
-	dwc->start_config_issued = false;
 
 	/* Reset device address to zero */
 	reg = dwc3_readl(dwc->regs, DWC3_DCFG);
--- zfcpdump-kernel-4.4.orig/drivers/usb/gadget/function/f_fs.c
+++ zfcpdump-kernel-4.4/drivers/usb/gadget/function/f_fs.c
@@ -646,24 +646,23 @@ static void ffs_user_copy_worker(struct
 						   work);
 	int ret = io_data->req->status ? io_data->req->status :
 					 io_data->req->actual;
+	bool kiocb_has_eventfd = io_data->kiocb->ki_flags & IOCB_EVENTFD;
 
 	if (io_data->read && ret > 0) {
 		use_mm(io_data->mm);
 		ret = copy_to_iter(io_data->buf, ret, &io_data->data);
-		if (iov_iter_count(&io_data->data))
+		if (ret != io_data->req->actual && iov_iter_count(&io_data->data))
 			ret = -EFAULT;
 		unuse_mm(io_data->mm);
 	}
 
 	io_data->kiocb->ki_complete(io_data->kiocb, ret, ret);
 
-	if (io_data->ffs->ffs_eventfd &&
-	    !(io_data->kiocb->ki_flags & IOCB_EVENTFD))
+	if (io_data->ffs->ffs_eventfd && !kiocb_has_eventfd)
 		eventfd_signal(io_data->ffs->ffs_eventfd, 1);
 
 	usb_ep_free_request(io_data->ep, io_data->req);
 
-	io_data->kiocb->private = NULL;
 	if (io_data->read)
 		kfree(io_data->to_free);
 	kfree(io_data->buf);
@@ -2741,6 +2740,7 @@ static int _ffs_func_bind(struct usb_con
 		func->ffs->ss_descs_count;
 
 	int fs_len, hs_len, ss_len, ret, i;
+	struct ffs_ep *eps_ptr;
 
 	/* Make it a single chunk, less management later on */
 	vla_group(d);
@@ -2789,12 +2789,9 @@ static int _ffs_func_bind(struct usb_con
 	       ffs->raw_descs_length);
 
 	memset(vla_ptr(vlabuf, d, inums), 0xff, d_inums__sz);
-	for (ret = ffs->eps_count; ret; --ret) {
-		struct ffs_ep *ptr;
-
-		ptr = vla_ptr(vlabuf, d, eps);
-		ptr[ret].num = -1;
-	}
+	eps_ptr = vla_ptr(vlabuf, d, eps);
+	for (i = 0; i < ffs->eps_count; i++)
+		eps_ptr[i].num = -1;
 
 	/* Save pointers
 	 * d_eps == vlabuf, func->eps used to kfree vlabuf later
--- zfcpdump-kernel-4.4.orig/drivers/usb/gadget/function/f_mass_storage.c
+++ zfcpdump-kernel-4.4/drivers/usb/gadget/function/f_mass_storage.c
@@ -2977,25 +2977,6 @@ void fsg_common_set_inquiry_string(struc
 }
 EXPORT_SYMBOL_GPL(fsg_common_set_inquiry_string);
 
-int fsg_common_run_thread(struct fsg_common *common)
-{
-	common->state = FSG_STATE_IDLE;
-	/* Tell the thread to start working */
-	common->thread_task =
-		kthread_create(fsg_main_thread, common, "file-storage");
-	if (IS_ERR(common->thread_task)) {
-		common->state = FSG_STATE_TERMINATED;
-		return PTR_ERR(common->thread_task);
-	}
-
-	DBG(common, "I/O thread pid: %d\n", task_pid_nr(common->thread_task));
-
-	wake_up_process(common->thread_task);
-
-	return 0;
-}
-EXPORT_SYMBOL_GPL(fsg_common_run_thread);
-
 static void fsg_common_release(struct kref *ref)
 {
 	struct fsg_common *common = container_of(ref, struct fsg_common, ref);
@@ -3005,6 +2986,7 @@ static void fsg_common_release(struct kr
 	if (common->state != FSG_STATE_TERMINATED) {
 		raise_exception(common, FSG_STATE_EXIT);
 		wait_for_completion(&common->thread_notifier);
+		common->thread_task = NULL;
 	}
 
 	for (i = 0; i < ARRAY_SIZE(common->luns); ++i) {
@@ -3050,9 +3032,21 @@ static int fsg_bind(struct usb_configura
 		if (ret)
 			return ret;
 		fsg_common_set_inquiry_string(fsg->common, NULL, NULL);
-		ret = fsg_common_run_thread(fsg->common);
-		if (ret)
+	}
+
+	if (!common->thread_task) {
+		common->state = FSG_STATE_IDLE;
+		common->thread_task =
+			kthread_create(fsg_main_thread, common, "file-storage");
+		if (IS_ERR(common->thread_task)) {
+			int ret = PTR_ERR(common->thread_task);
+			common->thread_task = NULL;
+			common->state = FSG_STATE_TERMINATED;
 			return ret;
+		}
+		DBG(common, "I/O thread pid: %d\n",
+		    task_pid_nr(common->thread_task));
+		wake_up_process(common->thread_task);
 	}
 
 	fsg->gadget = gadget;
--- zfcpdump-kernel-4.4.orig/drivers/usb/gadget/function/f_mass_storage.h
+++ zfcpdump-kernel-4.4/drivers/usb/gadget/function/f_mass_storage.h
@@ -153,8 +153,6 @@ int fsg_common_create_luns(struct fsg_co
 void fsg_common_set_inquiry_string(struct fsg_common *common, const char *vn,
 				   const char *pn);
 
-int fsg_common_run_thread(struct fsg_common *common);
-
 void fsg_config_from_params(struct fsg_config *cfg,
 			    const struct fsg_module_parameters *params,
 			    unsigned int fsg_num_buffers);
--- zfcpdump-kernel-4.4.orig/drivers/usb/gadget/function/f_uac2.c
+++ zfcpdump-kernel-4.4/drivers/usb/gadget/function/f_uac2.c
@@ -1291,6 +1291,7 @@ in_rq_cur(struct usb_function *fn, const
 
 	if (control_selector == UAC2_CS_CONTROL_SAM_FREQ) {
 		struct cntrl_cur_lay3 c;
+		memset(&c, 0, sizeof(struct cntrl_cur_lay3));
 
 		if (entity_id == USB_IN_CLK_ID)
 			c.dCUR = p_srate;
--- zfcpdump-kernel-4.4.orig/drivers/usb/gadget/legacy/acm_ms.c
+++ zfcpdump-kernel-4.4/drivers/usb/gadget/legacy/acm_ms.c
@@ -133,10 +133,6 @@ static int acm_ms_do_config(struct usb_c
 	if (status < 0)
 		goto put_msg;
 
-	status = fsg_common_run_thread(opts->common);
-	if (status)
-		goto remove_acm;
-
 	status = usb_add_function(c, f_msg);
 	if (status)
 		goto remove_acm;
--- zfcpdump-kernel-4.4.orig/drivers/usb/gadget/legacy/inode.c
+++ zfcpdump-kernel-4.4/drivers/usb/gadget/legacy/inode.c
@@ -541,7 +541,7 @@ static ssize_t ep_aio(struct kiocb *iocb
 	 */
 	spin_lock_irq(&epdata->dev->lock);
 	value = -ENODEV;
-	if (unlikely(epdata->ep))
+	if (unlikely(epdata->ep == NULL))
 		goto fail;
 
 	req = usb_ep_alloc_request(epdata->ep, GFP_ATOMIC);
@@ -937,8 +937,11 @@ ep0_read (struct file *fd, char __user *
 			struct usb_ep		*ep = dev->gadget->ep0;
 			struct usb_request	*req = dev->req;
 
-			if ((retval = setup_req (ep, req, 0)) == 0)
-				retval = usb_ep_queue (ep, req, GFP_ATOMIC);
+			if ((retval = setup_req (ep, req, 0)) == 0) {
+				spin_unlock_irq (&dev->lock);
+				retval = usb_ep_queue (ep, req, GFP_KERNEL);
+				spin_lock_irq (&dev->lock);
+			}
 			dev->state = STATE_DEV_CONNECTED;
 
 			/* assume that was SET_CONFIGURATION */
@@ -1456,8 +1459,11 @@ delegate:
 							w_length);
 				if (value < 0)
 					break;
+
+				spin_unlock (&dev->lock);
 				value = usb_ep_queue (gadget->ep0, dev->req,
-							GFP_ATOMIC);
+							GFP_KERNEL);
+				spin_lock (&dev->lock);
 				if (value < 0) {
 					clean_req (gadget->ep0, dev->req);
 					break;
@@ -1480,11 +1486,14 @@ delegate:
 	if (value >= 0 && dev->state != STATE_DEV_SETUP) {
 		req->length = value;
 		req->zero = value < w_length;
-		value = usb_ep_queue (gadget->ep0, req, GFP_ATOMIC);
+
+		spin_unlock (&dev->lock);
+		value = usb_ep_queue (gadget->ep0, req, GFP_KERNEL);
 		if (value < 0) {
 			DBG (dev, "ep_queue --> %d\n", value);
 			req->status = 0;
 		}
+		return value;
 	}
 
 	/* device stalls when value < 0 */
--- zfcpdump-kernel-4.4.orig/drivers/usb/gadget/legacy/mass_storage.c
+++ zfcpdump-kernel-4.4/drivers/usb/gadget/legacy/mass_storage.c
@@ -132,10 +132,6 @@ static int msg_do_config(struct usb_conf
 	if (IS_ERR(f_msg))
 		return PTR_ERR(f_msg);
 
-	ret = fsg_common_run_thread(opts->common);
-	if (ret)
-		goto put_func;
-
 	ret = usb_add_function(c, f_msg);
 	if (ret)
 		goto put_func;
--- zfcpdump-kernel-4.4.orig/drivers/usb/gadget/legacy/multi.c
+++ zfcpdump-kernel-4.4/drivers/usb/gadget/legacy/multi.c
@@ -137,7 +137,6 @@ static struct usb_function *f_msg_rndis;
 
 static int rndis_do_config(struct usb_configuration *c)
 {
-	struct fsg_opts *fsg_opts;
 	int ret;
 
 	if (gadget_is_otg(c->cdev->gadget)) {
@@ -169,11 +168,6 @@ static int rndis_do_config(struct usb_co
 		goto err_fsg;
 	}
 
-	fsg_opts = fsg_opts_from_func_inst(fi_msg);
-	ret = fsg_common_run_thread(fsg_opts->common);
-	if (ret)
-		goto err_run;
-
 	ret = usb_add_function(c, f_msg_rndis);
 	if (ret)
 		goto err_run;
@@ -225,7 +219,6 @@ static struct usb_function *f_msg_multi;
 
 static int cdc_do_config(struct usb_configuration *c)
 {
-	struct fsg_opts *fsg_opts;
 	int ret;
 
 	if (gadget_is_otg(c->cdev->gadget)) {
@@ -258,11 +251,6 @@ static int cdc_do_config(struct usb_conf
 		goto err_fsg;
 	}
 
-	fsg_opts = fsg_opts_from_func_inst(fi_msg);
-	ret = fsg_common_run_thread(fsg_opts->common);
-	if (ret)
-		goto err_run;
-
 	ret = usb_add_function(c, f_msg_multi);
 	if (ret)
 		goto err_run;
--- zfcpdump-kernel-4.4.orig/drivers/usb/gadget/legacy/nokia.c
+++ zfcpdump-kernel-4.4/drivers/usb/gadget/legacy/nokia.c
@@ -152,7 +152,6 @@ static int nokia_bind_config(struct usb_
 	struct usb_function *f_ecm;
 	struct usb_function *f_obex2 = NULL;
 	struct usb_function *f_msg;
-	struct fsg_opts *fsg_opts;
 	int status = 0;
 	int obex1_stat = -1;
 	int obex2_stat = -1;
@@ -222,12 +221,6 @@ static int nokia_bind_config(struct usb_
 		goto err_ecm;
 	}
 
-	fsg_opts = fsg_opts_from_func_inst(fi_msg);
-
-	status = fsg_common_run_thread(fsg_opts->common);
-	if (status)
-		goto err_msg;
-
 	status = usb_add_function(c, f_msg);
 	if (status)
 		goto err_msg;
--- zfcpdump-kernel-4.4.orig/drivers/usb/gadget/udc/fsl_qe_udc.c
+++ zfcpdump-kernel-4.4/drivers/usb/gadget/udc/fsl_qe_udc.c
@@ -1878,11 +1878,8 @@ static int qe_get_frame(struct usb_gadge
 
 	tmp = in_be16(&udc->usb_param->frame_n);
 	if (tmp & 0x8000)
-		tmp = tmp & 0x07ff;
-	else
-		tmp = -EINVAL;
-
-	return (int)tmp;
+		return tmp & 0x07ff;
+	return -EINVAL;
 }
 
 static int fsl_qe_start(struct usb_gadget *gadget,
@@ -2053,7 +2050,7 @@ static void setup_received_handle(struct
 			struct qe_ep *ep;
 
 			if (wValue != 0 || wLength != 0
-				|| pipe > USB_MAX_ENDPOINTS)
+				|| pipe >= USB_MAX_ENDPOINTS)
 				break;
 			ep = &udc->eps[pipe];
 
--- zfcpdump-kernel-4.4.orig/drivers/usb/gadget/udc/udc-core.c
+++ zfcpdump-kernel-4.4/drivers/usb/gadget/udc/udc-core.c
@@ -71,7 +71,7 @@ int usb_gadget_map_request(struct usb_ga
 		mapped = dma_map_sg(dev, req->sg, req->num_sgs,
 				is_in ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
 		if (mapped == 0) {
-			dev_err(&gadget->dev, "failed to map SGs\n");
+			dev_err(dev, "failed to map SGs\n");
 			return -EFAULT;
 		}
 
--- zfcpdump-kernel-4.4.orig/drivers/usb/host/ehci-hcd.c
+++ zfcpdump-kernel-4.4/drivers/usb/host/ehci-hcd.c
@@ -332,11 +332,11 @@ static void ehci_turn_off_all_ports(stru
 	int	port = HCS_N_PORTS(ehci->hcs_params);
 
 	while (port--) {
-		ehci_writel(ehci, PORT_RWC_BITS,
-				&ehci->regs->port_status[port]);
 		spin_unlock_irq(&ehci->lock);
 		ehci_port_power(ehci, port, false);
 		spin_lock_irq(&ehci->lock);
+		ehci_writel(ehci, PORT_RWC_BITS,
+				&ehci->regs->port_status[port]);
 	}
 }
 
--- zfcpdump-kernel-4.4.orig/drivers/usb/host/ehci-tegra.c
+++ zfcpdump-kernel-4.4/drivers/usb/host/ehci-tegra.c
@@ -89,7 +89,7 @@ static int tegra_reset_usb_controller(st
 	if (!usb1_reset_attempted) {
 		struct reset_control *usb1_reset;
 
-		usb1_reset = of_reset_control_get(phy_np, "usb");
+		usb1_reset = of_reset_control_get(phy_np, "utmi-pads");
 		if (IS_ERR(usb1_reset)) {
 			dev_warn(&pdev->dev,
 				 "can't get utmi-pads reset from the PHY\n");
--- zfcpdump-kernel-4.4.orig/drivers/usb/host/ohci-q.c
+++ zfcpdump-kernel-4.4/drivers/usb/host/ohci-q.c
@@ -183,7 +183,6 @@ static int ed_schedule (struct ohci_hcd
 {
 	int	branch;
 
-	ed->state = ED_OPER;
 	ed->ed_prev = NULL;
 	ed->ed_next = NULL;
 	ed->hwNextED = 0;
@@ -259,6 +258,8 @@ static int ed_schedule (struct ohci_hcd
 	/* the HC may not see the schedule updates yet, but if it does
 	 * then they'll be properly ordered.
 	 */
+
+	ed->state = ED_OPER;
 	return 0;
 }
 
--- zfcpdump-kernel-4.4.orig/drivers/usb/host/xhci-hub.c
+++ zfcpdump-kernel-4.4/drivers/usb/host/xhci-hub.c
@@ -50,14 +50,18 @@ static u8 usb_bos_descriptor [] = {
 	0x00,				/* bU1DevExitLat, set later. */
 	0x00, 0x00,			/* __le16 bU2DevExitLat, set later. */
 	/* Second device capability, SuperSpeedPlus */
-	0x0c,				/* bLength 12, will be adjusted later */
+	0x1c,				/* bLength 28, will be adjusted later */
 	USB_DT_DEVICE_CAPABILITY,	/* Device Capability */
 	USB_SSP_CAP_TYPE,		/* bDevCapabilityType SUPERSPEED_PLUS */
 	0x00,				/* bReserved 0 */
-	0x00, 0x00, 0x00, 0x00,		/* bmAttributes, get from xhci psic */
-	0x00, 0x00,			/* wFunctionalitySupport */
+	0x23, 0x00, 0x00, 0x00,		/* bmAttributes, SSAC=3 SSIC=1 */
+	0x01, 0x00,			/* wFunctionalitySupport */
 	0x00, 0x00,			/* wReserved 0 */
-	/* Sublink Speed Attributes are added in xhci_create_usb3_bos_desc() */
+	/* Default Sublink Speed Attributes, overwrite if custom PSI exists */
+	0x34, 0x00, 0x05, 0x00,		/* 5Gbps, symmetric, rx, ID = 4 */
+	0xb4, 0x00, 0x05, 0x00,		/* 5Gbps, symmetric, tx, ID = 4 */
+	0x35, 0x40, 0x0a, 0x00,		/* 10Gbps, SSP, symmetric, rx, ID = 5 */
+	0xb5, 0x40, 0x0a, 0x00,		/* 10Gbps, SSP, symmetric, tx, ID = 5 */
 };
 
 static int xhci_create_usb3_bos_desc(struct xhci_hcd *xhci, char *buf,
@@ -72,10 +76,14 @@ static int xhci_create_usb3_bos_desc(str
 	ssp_cap_size = sizeof(usb_bos_descriptor) - desc_size;
 
 	/* does xhci support USB 3.1 Enhanced SuperSpeed */
-	if (xhci->usb3_rhub.min_rev >= 0x01 && xhci->usb3_rhub.psi_uid_count) {
-		/* two SSA entries for each unique PSI ID, one RX and one TX */
-		ssa_count = xhci->usb3_rhub.psi_uid_count * 2;
-		ssa_size = ssa_count * sizeof(u32);
+	if (xhci->usb3_rhub.min_rev >= 0x01) {
+		/* does xhci provide a PSI table for SSA speed attributes? */
+		if (xhci->usb3_rhub.psi_count) {
+			/* two SSA entries for each unique PSI ID, RX and TX */
+			ssa_count = xhci->usb3_rhub.psi_uid_count * 2;
+			ssa_size = ssa_count * sizeof(u32);
+			ssp_cap_size -= 16; /* skip copying the default SSA */
+		}
 		desc_size += ssp_cap_size;
 		usb3_1 = true;
 	}
@@ -102,7 +110,8 @@ static int xhci_create_usb3_bos_desc(str
 		put_unaligned_le16(HCS_U2_LATENCY(temp), &buf[13]);
 	}
 
-	if (usb3_1) {
+	/* If PSI table exists, add the custom speed attributes from it */
+	if (usb3_1 && xhci->usb3_rhub.psi_count) {
 		u32 ssp_cap_base, bm_attrib, psi;
 		int offset;
 
@@ -377,6 +386,9 @@ static int xhci_stop_device(struct xhci_
 
 	ret = 0;
 	virt_dev = xhci->devs[slot_id];
+	if (!virt_dev)
+		return -ENODEV;
+
 	cmd = xhci_alloc_command(xhci, false, true, GFP_NOIO);
 	if (!cmd) {
 		xhci_dbg(xhci, "Couldn't allocate command structure.\n");
--- zfcpdump-kernel-4.4.orig/drivers/usb/host/xhci-mem.c
+++ zfcpdump-kernel-4.4/drivers/usb/host/xhci-mem.c
@@ -1072,7 +1072,7 @@ static u32 xhci_find_real_port_number(st
 	struct usb_device *top_dev;
 	struct usb_hcd *hcd;
 
-	if (udev->speed == USB_SPEED_SUPER)
+	if (udev->speed >= USB_SPEED_SUPER)
 		hcd = xhci->shared_hcd;
 	else
 		hcd = xhci->main_hcd;
@@ -1107,6 +1107,10 @@ int xhci_setup_addressable_virt_dev(stru
 	/* 3) Only the control endpoint is valid - one endpoint context */
 	slot_ctx->dev_info |= cpu_to_le32(LAST_CTX(1) | udev->route);
 	switch (udev->speed) {
+	case USB_SPEED_SUPER_PLUS:
+		slot_ctx->dev_info |= cpu_to_le32(SLOT_SPEED_SSP);
+		max_packets = MAX_PACKET(512);
+		break;
 	case USB_SPEED_SUPER:
 		slot_ctx->dev_info |= cpu_to_le32(SLOT_SPEED_SS);
 		max_packets = MAX_PACKET(512);
@@ -1294,6 +1298,7 @@ static unsigned int xhci_get_endpoint_in
 		}
 		/* Fall through - SS and HS isoc/int have same decoding */
 
+	case USB_SPEED_SUPER_PLUS:
 	case USB_SPEED_SUPER:
 		if (usb_endpoint_xfer_int(&ep->desc) ||
 		    usb_endpoint_xfer_isoc(&ep->desc)) {
@@ -1323,7 +1328,7 @@ static unsigned int xhci_get_endpoint_in
 	default:
 		BUG();
 	}
-	return EP_INTERVAL(interval);
+	return interval;
 }
 
 /* The "Mult" field in the endpoint context is only set for SuperSpeed isoc eps.
@@ -1334,39 +1339,42 @@ static unsigned int xhci_get_endpoint_in
 static u32 xhci_get_endpoint_mult(struct usb_device *udev,
 		struct usb_host_endpoint *ep)
 {
-	if (udev->speed != USB_SPEED_SUPER ||
+	if (udev->speed < USB_SPEED_SUPER ||
 			!usb_endpoint_xfer_isoc(&ep->desc))
 		return 0;
 	return ep->ss_ep_comp.bmAttributes;
 }
 
+static u32 xhci_get_endpoint_max_burst(struct usb_device *udev,
+				       struct usb_host_endpoint *ep)
+{
+	/* Super speed and Plus have max burst in ep companion desc */
+	if (udev->speed >= USB_SPEED_SUPER)
+		return ep->ss_ep_comp.bMaxBurst;
+
+	if (udev->speed == USB_SPEED_HIGH &&
+	    (usb_endpoint_xfer_isoc(&ep->desc) ||
+	     usb_endpoint_xfer_int(&ep->desc)))
+		return (usb_endpoint_maxp(&ep->desc) & 0x1800) >> 11;
+
+	return 0;
+}
+
 static u32 xhci_get_endpoint_type(struct usb_host_endpoint *ep)
 {
 	int in;
-	u32 type;
 
 	in = usb_endpoint_dir_in(&ep->desc);
-	if (usb_endpoint_xfer_control(&ep->desc)) {
-		type = EP_TYPE(CTRL_EP);
-	} else if (usb_endpoint_xfer_bulk(&ep->desc)) {
-		if (in)
-			type = EP_TYPE(BULK_IN_EP);
-		else
-			type = EP_TYPE(BULK_OUT_EP);
-	} else if (usb_endpoint_xfer_isoc(&ep->desc)) {
-		if (in)
-			type = EP_TYPE(ISOC_IN_EP);
-		else
-			type = EP_TYPE(ISOC_OUT_EP);
-	} else if (usb_endpoint_xfer_int(&ep->desc)) {
-		if (in)
-			type = EP_TYPE(INT_IN_EP);
-		else
-			type = EP_TYPE(INT_OUT_EP);
-	} else {
-		type = 0;
-	}
-	return type;
+
+	if (usb_endpoint_xfer_control(&ep->desc))
+		return CTRL_EP;
+	if (usb_endpoint_xfer_bulk(&ep->desc))
+		return in ? BULK_IN_EP : BULK_OUT_EP;
+	if (usb_endpoint_xfer_isoc(&ep->desc))
+		return in ? ISOC_IN_EP : ISOC_OUT_EP;
+	if (usb_endpoint_xfer_int(&ep->desc))
+		return in ? INT_IN_EP : INT_OUT_EP;
+	return 0;
 }
 
 /* Return the maximum endpoint service interval time (ESIT) payload.
@@ -1384,7 +1392,12 @@ static u32 xhci_get_max_esit_payload(str
 			usb_endpoint_xfer_bulk(&ep->desc))
 		return 0;
 
-	if (udev->speed == USB_SPEED_SUPER)
+	/* SuperSpeedPlus Isoc ep sending over 48k per esit */
+	if ((udev->speed >= USB_SPEED_SUPER_PLUS) &&
+	    USB_SS_SSP_ISOC_COMP(ep->ss_ep_comp.bmAttributes))
+		return le32_to_cpu(ep->ssp_isoc_ep_comp.dwBytesPerInterval);
+	/* SuperSpeed or SuperSpeedPlus Isoc ep with less than 48k per esit */
+	else if (udev->speed >= USB_SPEED_SUPER)
 		return le16_to_cpu(ep->ss_ep_comp.wBytesPerInterval);
 
 	max_packet = GET_MAX_PACKET(usb_endpoint_maxp(&ep->desc));
@@ -1406,10 +1419,14 @@ int xhci_endpoint_init(struct xhci_hcd *
 	struct xhci_ep_ctx *ep_ctx;
 	struct xhci_ring *ep_ring;
 	unsigned int max_packet;
-	unsigned int max_burst;
-	enum xhci_ring_type type;
+	enum xhci_ring_type ring_type;
 	u32 max_esit_payload;
 	u32 endpoint_type;
+	unsigned int max_burst;
+	unsigned int interval;
+	unsigned int mult;
+	unsigned int avg_trb_len;
+	unsigned int err_count = 0;
 
 	ep_index = xhci_get_endpoint_index(&ep->desc);
 	ep_ctx = xhci_get_ep_ctx(xhci, virt_dev->in_ctx, ep_index);
@@ -1417,12 +1434,11 @@ int xhci_endpoint_init(struct xhci_hcd *
 	endpoint_type = xhci_get_endpoint_type(ep);
 	if (!endpoint_type)
 		return -EINVAL;
-	ep_ctx->ep_info2 = cpu_to_le32(endpoint_type);
 
-	type = usb_endpoint_type(&ep->desc);
+	ring_type = usb_endpoint_type(&ep->desc);
 	/* Set up the endpoint ring */
 	virt_dev->eps[ep_index].new_ring =
-		xhci_ring_alloc(xhci, 2, 1, type, mem_flags);
+		xhci_ring_alloc(xhci, 2, 1, ring_type, mem_flags);
 	if (!virt_dev->eps[ep_index].new_ring) {
 		/* Attempt to use the ring cache */
 		if (virt_dev->num_rings_cached == 0)
@@ -1432,80 +1448,52 @@ int xhci_endpoint_init(struct xhci_hcd *
 			virt_dev->ring_cache[virt_dev->num_rings_cached];
 		virt_dev->ring_cache[virt_dev->num_rings_cached] = NULL;
 		xhci_reinit_cached_ring(xhci, virt_dev->eps[ep_index].new_ring,
-					1, type);
+					1, ring_type);
 	}
 	virt_dev->eps[ep_index].skip = false;
 	ep_ring = virt_dev->eps[ep_index].new_ring;
-	ep_ctx->deq = cpu_to_le64(ep_ring->first_seg->dma | ep_ring->cycle_state);
 
-	ep_ctx->ep_info = cpu_to_le32(xhci_get_endpoint_interval(udev, ep)
-				      | EP_MULT(xhci_get_endpoint_mult(udev, ep)));
+	/*
+	 * Get values to fill the endpoint context, mostly from ep descriptor.
+	 * The average TRB buffer lengt for bulk endpoints is unclear as we
+	 * have no clue on scatter gather list entry size. For Isoc and Int,
+	 * set it to max available. See xHCI 1.1 spec 4.14.1.1 for details.
+	 */
+	max_esit_payload = xhci_get_max_esit_payload(udev, ep);
+	interval = xhci_get_endpoint_interval(udev, ep);
+	mult = xhci_get_endpoint_mult(udev, ep);
+	max_packet = GET_MAX_PACKET(usb_endpoint_maxp(&ep->desc));
+	max_burst = xhci_get_endpoint_max_burst(udev, ep);
+	avg_trb_len = max_esit_payload;
 
 	/* FIXME dig Mult and streams info out of ep companion desc */
 
-	/* Allow 3 retries for everything but isoc;
-	 * CErr shall be set to 0 for Isoch endpoints.
-	 */
+	/* Allow 3 retries for everything but isoc, set CErr = 3 */
 	if (!usb_endpoint_xfer_isoc(&ep->desc))
-		ep_ctx->ep_info2 |= cpu_to_le32(ERROR_COUNT(3));
-	else
-		ep_ctx->ep_info2 |= cpu_to_le32(ERROR_COUNT(0));
-
-	/* Set the max packet size and max burst */
-	max_packet = GET_MAX_PACKET(usb_endpoint_maxp(&ep->desc));
-	max_burst = 0;
-	switch (udev->speed) {
-	case USB_SPEED_SUPER:
-		/* dig out max burst from ep companion desc */
-		max_burst = ep->ss_ep_comp.bMaxBurst;
-		break;
-	case USB_SPEED_HIGH:
-		/* Some devices get this wrong */
-		if (usb_endpoint_xfer_bulk(&ep->desc))
-			max_packet = 512;
-		/* bits 11:12 specify the number of additional transaction
-		 * opportunities per microframe (USB 2.0, section 9.6.6)
-		 */
-		if (usb_endpoint_xfer_isoc(&ep->desc) ||
-				usb_endpoint_xfer_int(&ep->desc)) {
-			max_burst = (usb_endpoint_maxp(&ep->desc)
-				     & 0x1800) >> 11;
-		}
-		break;
-	case USB_SPEED_FULL:
-	case USB_SPEED_LOW:
-		break;
-	default:
-		BUG();
-	}
-	ep_ctx->ep_info2 |= cpu_to_le32(MAX_PACKET(max_packet) |
-			MAX_BURST(max_burst));
-	max_esit_payload = xhci_get_max_esit_payload(udev, ep);
-	ep_ctx->tx_info = cpu_to_le32(MAX_ESIT_PAYLOAD_FOR_EP(max_esit_payload));
-
-	/*
-	 * XXX no idea how to calculate the average TRB buffer length for bulk
-	 * endpoints, as the driver gives us no clue how big each scatter gather
-	 * list entry (or buffer) is going to be.
-	 *
-	 * For isochronous and interrupt endpoints, we set it to the max
-	 * available, until we have new API in the USB core to allow drivers to
-	 * declare how much bandwidth they actually need.
-	 *
-	 * Normally, it would be calculated by taking the total of the buffer
-	 * lengths in the TD and then dividing by the number of TRBs in a TD,
-	 * including link TRBs, No-op TRBs, and Event data TRBs.  Since we don't
-	 * use Event Data TRBs, and we don't chain in a link TRB on short
-	 * transfers, we're basically dividing by 1.
-	 *
-	 * xHCI 1.0 and 1.1 specification indicates that the Average TRB Length
-	 * should be set to 8 for control endpoints.
-	 */
+		err_count = 3;
+	/* Some devices get this wrong */
+	if (usb_endpoint_xfer_bulk(&ep->desc) && udev->speed == USB_SPEED_HIGH)
+		max_packet = 512;
+	/* xHCI 1.0 and 1.1 indicates that ctrl ep avg TRB Length should be 8 */
 	if (usb_endpoint_xfer_control(&ep->desc) && xhci->hci_version >= 0x100)
-		ep_ctx->tx_info |= cpu_to_le32(AVG_TRB_LENGTH_FOR_EP(8));
-	else
-		ep_ctx->tx_info |=
-			 cpu_to_le32(AVG_TRB_LENGTH_FOR_EP(max_esit_payload));
+		avg_trb_len = 8;
+	/* xhci 1.1 with LEC support doesn't use mult field, use RsvdZ */
+	if ((xhci->hci_version > 0x100) && HCC2_LEC(xhci->hcc_params2))
+		mult = 0;
+
+	/* Fill the endpoint context */
+	ep_ctx->ep_info = cpu_to_le32(EP_MAX_ESIT_PAYLOAD_HI(max_esit_payload) |
+				      EP_INTERVAL(interval) |
+				      EP_MULT(mult));
+	ep_ctx->ep_info2 = cpu_to_le32(EP_TYPE(endpoint_type) |
+				       MAX_PACKET(max_packet) |
+				       MAX_BURST(max_burst) |
+				       ERROR_COUNT(err_count));
+	ep_ctx->deq = cpu_to_le64(ep_ring->first_seg->dma |
+				  ep_ring->cycle_state);
+
+	ep_ctx->tx_info = cpu_to_le32(EP_MAX_ESIT_PAYLOAD_LO(max_esit_payload) |
+				      EP_AVG_TRB_LENGTH(avg_trb_len));
 
 	/* FIXME Debug endpoint context */
 	return 0;
@@ -1875,6 +1863,12 @@ no_bw:
 	kfree(xhci->rh_bw);
 	kfree(xhci->ext_caps);
 
+	xhci->usb2_ports = NULL;
+	xhci->usb3_ports = NULL;
+	xhci->port_array = NULL;
+	xhci->rh_bw = NULL;
+	xhci->ext_caps = NULL;
+
 	xhci->page_size = 0;
 	xhci->page_shift = 0;
 	xhci->bus_state[0].bus_suspended = 0;
--- zfcpdump-kernel-4.4.orig/drivers/usb/host/xhci-pci.c
+++ zfcpdump-kernel-4.4/drivers/usb/host/xhci-pci.c
@@ -28,13 +28,16 @@
 #include "xhci.h"
 #include "xhci-trace.h"
 
-#define PORT2_SSIC_CONFIG_REG2	0x883c
+#define SSIC_PORT_NUM		2
+#define SSIC_PORT_CFG2		0x880c
+#define SSIC_PORT_CFG2_OFFSET	0x30
 #define PROG_DONE		(1 << 30)
 #define SSIC_PORT_UNUSED	(1 << 31)
 
 /* Device for a quirk */
 #define PCI_VENDOR_ID_FRESCO_LOGIC	0x1b73
 #define PCI_DEVICE_ID_FRESCO_LOGIC_PDK	0x1000
+#define PCI_DEVICE_ID_FRESCO_LOGIC_FL1009	0x1009
 #define PCI_DEVICE_ID_FRESCO_LOGIC_FL1400	0x1400
 
 #define PCI_VENDOR_ID_ETRON		0x1b6f
@@ -45,6 +48,8 @@
 #define PCI_DEVICE_ID_INTEL_CHERRYVIEW_XHCI		0x22b5
 #define PCI_DEVICE_ID_INTEL_SUNRISEPOINT_H_XHCI		0xa12f
 #define PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_XHCI	0x9d2f
+#define PCI_DEVICE_ID_INTEL_BROXTON_M_XHCI		0x0aa8
+#define PCI_DEVICE_ID_INTEL_BROXTON_B_XHCI		0x1aa8
 
 static const char hcd_name[] = "xhci_hcd";
 
@@ -111,6 +116,10 @@ static void xhci_pci_quirks(struct devic
 		xhci->quirks |= XHCI_TRUST_TX_LENGTH;
 	}
 
+	if (pdev->vendor == PCI_VENDOR_ID_FRESCO_LOGIC &&
+			pdev->device == PCI_DEVICE_ID_FRESCO_LOGIC_FL1009)
+		xhci->quirks |= XHCI_BROKEN_STREAMS;
+
 	if (pdev->vendor == PCI_VENDOR_ID_NEC)
 		xhci->quirks |= XHCI_NEC_HOST;
 
@@ -152,7 +161,9 @@ static void xhci_pci_quirks(struct devic
 	if (pdev->vendor == PCI_VENDOR_ID_INTEL &&
 		(pdev->device == PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_XHCI ||
 		 pdev->device == PCI_DEVICE_ID_INTEL_SUNRISEPOINT_H_XHCI ||
-		 pdev->device == PCI_DEVICE_ID_INTEL_CHERRYVIEW_XHCI)) {
+		 pdev->device == PCI_DEVICE_ID_INTEL_CHERRYVIEW_XHCI ||
+		 pdev->device == PCI_DEVICE_ID_INTEL_BROXTON_M_XHCI ||
+		 pdev->device == PCI_DEVICE_ID_INTEL_BROXTON_B_XHCI)) {
 		xhci->quirks |= XHCI_PME_STUCK_QUIRK;
 	}
 	if (pdev->vendor == PCI_VENDOR_ID_ETRON &&
@@ -295,15 +306,17 @@ static void xhci_pci_remove(struct pci_d
 	struct xhci_hcd *xhci;
 
 	xhci = hcd_to_xhci(pci_get_drvdata(dev));
+	xhci->xhc_state |= XHCI_STATE_REMOVING;
 	if (xhci->shared_hcd) {
 		usb_remove_hcd(xhci->shared_hcd);
 		usb_put_hcd(xhci->shared_hcd);
 	}
-	usb_hcd_pci_remove(dev);
 
 	/* Workaround for spurious wakeups at shutdown with HSW */
 	if (xhci->quirks & XHCI_SPURIOUS_WAKEUP)
 		pci_set_power_state(dev, PCI_D3hot);
+
+	usb_hcd_pci_remove(dev);
 }
 
 #ifdef CONFIG_PM
@@ -322,28 +335,36 @@ static void xhci_pme_quirk(struct usb_hc
 	struct pci_dev		*pdev = to_pci_dev(hcd->self.controller);
 	u32 val;
 	void __iomem *reg;
+	int i;
 
 	if (pdev->vendor == PCI_VENDOR_ID_INTEL &&
 		 pdev->device == PCI_DEVICE_ID_INTEL_CHERRYVIEW_XHCI) {
 
-		reg = (void __iomem *) xhci->cap_regs + PORT2_SSIC_CONFIG_REG2;
-
-		/* Notify SSIC that SSIC profile programming is not done */
-		val = readl(reg) & ~PROG_DONE;
-		writel(val, reg);
-
-		/* Mark SSIC port as unused(suspend) or used(resume) */
-		val = readl(reg);
-		if (suspend)
-			val |= SSIC_PORT_UNUSED;
-		else
-			val &= ~SSIC_PORT_UNUSED;
-		writel(val, reg);
-
-		/* Notify SSIC that SSIC profile programming is done */
-		val = readl(reg) | PROG_DONE;
-		writel(val, reg);
-		readl(reg);
+		for (i = 0; i < SSIC_PORT_NUM; i++) {
+			reg = (void __iomem *) xhci->cap_regs +
+					SSIC_PORT_CFG2 +
+					i * SSIC_PORT_CFG2_OFFSET;
+
+			/*
+			 * Notify SSIC that SSIC profile programming
+			 * is not done.
+			 */
+			val = readl(reg) & ~PROG_DONE;
+			writel(val, reg);
+
+			/* Mark SSIC port as unused(suspend) or used(resume) */
+			val = readl(reg);
+			if (suspend)
+				val |= SSIC_PORT_UNUSED;
+			else
+				val &= ~SSIC_PORT_UNUSED;
+			writel(val, reg);
+
+			/* Notify SSIC that SSIC profile programming is done */
+			val = readl(reg) | PROG_DONE;
+			writel(val, reg);
+			readl(reg);
+		}
 	}
 
 	reg = (void __iomem *) xhci->cap_regs + 0x80a4;
--- zfcpdump-kernel-4.4.orig/drivers/usb/host/xhci-plat.c
+++ zfcpdump-kernel-4.4/drivers/usb/host/xhci-plat.c
@@ -132,6 +132,9 @@ static int xhci_plat_probe(struct platfo
 		ret = clk_prepare_enable(clk);
 		if (ret)
 			goto put_hcd;
+	} else if (PTR_ERR(clk) == -EPROBE_DEFER) {
+		ret = -EPROBE_DEFER;
+		goto put_hcd;
 	}
 
 	if (of_device_is_compatible(pdev->dev.of_node,
--- zfcpdump-kernel-4.4.orig/drivers/usb/host/xhci-ring.c
+++ zfcpdump-kernel-4.4/drivers/usb/host/xhci-ring.c
@@ -289,6 +289,14 @@ static int xhci_abort_cmd_ring(struct xh
 
 	temp_64 = xhci_read_64(xhci, &xhci->op_regs->cmd_ring);
 	xhci->cmd_ring_state = CMD_RING_STATE_ABORTED;
+
+	/*
+	 * Writing the CMD_RING_ABORT bit should cause a cmd completion event,
+	 * however on some host hw the CMD_RING_RUNNING bit is correctly cleared
+	 * but the completion event in never sent. Use the cmd timeout timer to
+	 * handle those cases. Use twice the time to cover the bit polling retry
+	 */
+	mod_timer(&xhci->cmd_timer, jiffies + (2 * XHCI_CMD_DEFAULT_TIMEOUT));
 	xhci_write_64(xhci, temp_64 | CMD_RING_ABORT,
 			&xhci->op_regs->cmd_ring);
 
@@ -313,6 +321,7 @@ static int xhci_abort_cmd_ring(struct xh
 
 		xhci_err(xhci, "Stopped the command ring failed, "
 				"maybe the host is dead\n");
+		del_timer(&xhci->cmd_timer);
 		xhci->xhc_state |= XHCI_STATE_DYING;
 		xhci_quiesce(xhci);
 		xhci_halt(xhci);
@@ -837,6 +846,10 @@ void xhci_stop_endpoint_command_watchdog
 	spin_lock_irqsave(&xhci->lock, flags);
 
 	ep->stop_cmds_pending--;
+	if (xhci->xhc_state & XHCI_STATE_REMOVING) {
+		spin_unlock_irqrestore(&xhci->lock, flags);
+		return;
+	}
 	if (xhci->xhc_state & XHCI_STATE_DYING) {
 		xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb,
 				"Stop EP timer ran, but another timer marked "
@@ -890,7 +903,7 @@ void xhci_stop_endpoint_command_watchdog
 	spin_unlock_irqrestore(&xhci->lock, flags);
 	xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb,
 			"Calling usb_hc_died()");
-	usb_hc_died(xhci_to_hcd(xhci)->primary_hcd);
+	usb_hc_died(xhci_to_hcd(xhci));
 	xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb,
 			"xHCI host controller is dead.");
 }
@@ -1252,22 +1265,21 @@ void xhci_handle_command_timeout(unsigne
 	int ret;
 	unsigned long flags;
 	u64 hw_ring_state;
-	struct xhci_command *cur_cmd = NULL;
+	bool second_timeout = false;
 	xhci = (struct xhci_hcd *) data;
 
 	/* mark this command to be cancelled */
 	spin_lock_irqsave(&xhci->lock, flags);
 	if (xhci->current_cmd) {
-		cur_cmd = xhci->current_cmd;
-		cur_cmd->status = COMP_CMD_ABORT;
+		if (xhci->current_cmd->status == COMP_CMD_ABORT)
+			second_timeout = true;
+		xhci->current_cmd->status = COMP_CMD_ABORT;
 	}
 
-
 	/* Make sure command ring is running before aborting it */
 	hw_ring_state = xhci_read_64(xhci, &xhci->op_regs->cmd_ring);
 	if ((xhci->cmd_ring_state & CMD_RING_STATE_RUNNING) &&
 	    (hw_ring_state & CMD_RING_RUNNING))  {
-
 		spin_unlock_irqrestore(&xhci->lock, flags);
 		xhci_dbg(xhci, "Command timeout\n");
 		ret = xhci_abort_cmd_ring(xhci);
@@ -1279,6 +1291,15 @@ void xhci_handle_command_timeout(unsigne
 		}
 		return;
 	}
+
+	/* command ring failed to restart, or host removed. Bail out */
+	if (second_timeout || xhci->xhc_state & XHCI_STATE_REMOVING) {
+		spin_unlock_irqrestore(&xhci->lock, flags);
+		xhci_dbg(xhci, "command timed out twice, ring start fail?\n");
+		xhci_cleanup_command_queue(xhci);
+		return;
+	}
+
 	/* command timeout on stopped ring, ring can't be aborted */
 	xhci_dbg(xhci, "Command timeout on stopped ring\n");
 	xhci_handle_stopped_cmd_ring(xhci, xhci->current_cmd);
@@ -1314,12 +1335,6 @@ static void handle_cmd_completion(struct
 
 	cmd = list_entry(xhci->cmd_list.next, struct xhci_command, cmd_list);
 
-	if (cmd->command_trb != xhci->cmd_ring->dequeue) {
-		xhci_err(xhci,
-			 "Command completion event does not match command\n");
-		return;
-	}
-
 	del_timer(&xhci->cmd_timer);
 
 	trace_xhci_cmd_completion(cmd_trb, (struct xhci_generic_trb *) event);
@@ -1331,6 +1346,13 @@ static void handle_cmd_completion(struct
 		xhci_handle_stopped_cmd_ring(xhci, cmd);
 		return;
 	}
+
+	if (cmd->command_trb != xhci->cmd_ring->dequeue) {
+		xhci_err(xhci,
+			 "Command completion event does not match command\n");
+		return;
+	}
+
 	/*
 	 * Host aborted the command ring, check if the current command was
 	 * supposed to be aborted, otherwise continue normally.
@@ -2192,10 +2214,6 @@ static int process_bulk_intr_td(struct x
 		}
 	/* Fast path - was this the last TRB in the TD for this URB? */
 	} else if (event_trb == td->last_trb) {
-		if (td->urb_length_set && trb_comp_code == COMP_SHORT_TX)
-			return finish_td(xhci, td, event_trb, event, ep,
-					 status, false);
-
 		if (EVENT_TRB_LEN(le32_to_cpu(event->transfer_len)) != 0) {
 			td->urb->actual_length =
 				td->urb->transfer_buffer_length -
@@ -2247,12 +2265,6 @@ static int process_bulk_intr_td(struct x
 			td->urb->actual_length +=
 				TRB_LEN(le32_to_cpu(cur_trb->generic.field[2])) -
 				EVENT_TRB_LEN(le32_to_cpu(event->transfer_len));
-
-		if (trb_comp_code == COMP_SHORT_TX) {
-			xhci_dbg(xhci, "mid bulk/intr SP, wait for last TRB event\n");
-			td->urb_length_set = true;
-			return 0;
-		}
 	}
 
 	return finish_td(xhci, td, event_trb, event, ep, status, false);
@@ -2749,6 +2761,8 @@ hw_died:
 		spin_unlock(&xhci->lock);
 
 		return IRQ_HANDLED;
+	} else if (xhci->xhc_state & XHCI_STATE_HALTED) {
+		xhci_dbg(xhci, "xHCI halted, handling interrupt.\n");
 	}
 
 	event_ring_deq = xhci->event_ring->dequeue;
@@ -3562,12 +3576,11 @@ static int count_isoc_trbs_needed(struct
  * zero.  Only xHCI 1.0 host controllers support this field.
  */
 static unsigned int xhci_get_burst_count(struct xhci_hcd *xhci,
-		struct usb_device *udev,
 		struct urb *urb, unsigned int total_packet_count)
 {
 	unsigned int max_burst;
 
-	if (xhci->hci_version < 0x100 || udev->speed != USB_SPEED_SUPER)
+	if (xhci->hci_version < 0x100 || urb->dev->speed < USB_SPEED_SUPER)
 		return 0;
 
 	max_burst = urb->ep->ss_ep_comp.bMaxBurst;
@@ -3583,7 +3596,6 @@ static unsigned int xhci_get_burst_count
  * contain 1 to (bMaxBurst + 1) packets.
  */
 static unsigned int xhci_get_last_burst_packet_count(struct xhci_hcd *xhci,
-		struct usb_device *udev,
 		struct urb *urb, unsigned int total_packet_count)
 {
 	unsigned int max_burst;
@@ -3592,8 +3604,7 @@ static unsigned int xhci_get_last_burst_
 	if (xhci->hci_version < 0x100)
 		return 0;
 
-	switch (udev->speed) {
-	case USB_SPEED_SUPER:
+	if (urb->dev->speed >= USB_SPEED_SUPER) {
 		/* bMaxBurst is zero based: 0 means 1 packet per burst */
 		max_burst = urb->ep->ss_ep_comp.bMaxBurst;
 		residue = total_packet_count % (max_burst + 1);
@@ -3603,11 +3614,10 @@ static unsigned int xhci_get_last_burst_
 		if (residue == 0)
 			return max_burst;
 		return residue - 1;
-	default:
-		if (total_packet_count == 0)
-			return 0;
-		return total_packet_count - 1;
 	}
+	if (total_packet_count == 0)
+		return 0;
+	return total_packet_count - 1;
 }
 
 /*
@@ -3718,6 +3728,7 @@ static int xhci_queue_isoc_tx(struct xhc
 	int i, j;
 	bool more_trbs_coming;
 	struct xhci_virt_ep *xep;
+	int frame_id;
 
 	xep = &xhci->devs[slot_id]->eps[ep_index];
 	ep_ring = xhci->devs[slot_id]->eps[ep_index].ring;
@@ -3727,33 +3738,31 @@ static int xhci_queue_isoc_tx(struct xhc
 		xhci_dbg(xhci, "Isoc URB with zero packets?\n");
 		return -EINVAL;
 	}
-
 	start_addr = (u64) urb->transfer_dma;
 	start_trb = &ep_ring->enqueue->generic;
 	start_cycle = ep_ring->cycle_state;
 
 	urb_priv = urb->hcpriv;
-	/* Queue the first TRB, even if it's zero-length */
+	/* Queue the TRBs for each TD, even if they are zero-length */
 	for (i = 0; i < num_tds; i++) {
-		unsigned int total_packet_count;
-		unsigned int burst_count;
-		unsigned int residue;
+		unsigned int total_pkt_count, max_pkt;
+		unsigned int burst_count, last_burst_pkt_count;
+		u32 sia_frame_id;
 
 		first_trb = true;
 		running_total = 0;
 		addr = start_addr + urb->iso_frame_desc[i].offset;
 		td_len = urb->iso_frame_desc[i].length;
 		td_remain_len = td_len;
-		total_packet_count = DIV_ROUND_UP(td_len,
-				GET_MAX_PACKET(
-					usb_endpoint_maxp(&urb->ep->desc)));
+		max_pkt = GET_MAX_PACKET(usb_endpoint_maxp(&urb->ep->desc));
+		total_pkt_count = DIV_ROUND_UP(td_len, max_pkt);
+
 		/* A zero-length transfer still involves at least one packet. */
-		if (total_packet_count == 0)
-			total_packet_count++;
-		burst_count = xhci_get_burst_count(xhci, urb->dev, urb,
-				total_packet_count);
-		residue = xhci_get_last_burst_packet_count(xhci,
-				urb->dev, urb, total_packet_count);
+		if (total_pkt_count == 0)
+			total_pkt_count++;
+		burst_count = xhci_get_burst_count(xhci, urb, total_pkt_count);
+		last_burst_pkt_count = xhci_get_last_burst_packet_count(xhci,
+							urb, total_pkt_count);
 
 		trbs_per_td = count_isoc_trbs_needed(xhci, urb, i);
 
@@ -3764,68 +3773,57 @@ static int xhci_queue_isoc_tx(struct xhc
 				return ret;
 			goto cleanup;
 		}
-
 		td = urb_priv->td[i];
+
+		/* use SIA as default, if frame id is used overwrite it */
+		sia_frame_id = TRB_SIA;
+		if (!(urb->transfer_flags & URB_ISO_ASAP) &&
+		    HCC_CFC(xhci->hcc_params)) {
+			frame_id = xhci_get_isoc_frame_id(xhci, urb, i);
+			if (frame_id >= 0)
+				sia_frame_id = TRB_FRAME_ID(frame_id);
+		}
+		/*
+		 * Set isoc specific data for the first TRB in a TD.
+		 * Prevent HW from getting the TRBs by keeping the cycle state
+		 * inverted in the first TDs isoc TRB.
+		 */
+		field = TRB_TYPE(TRB_ISOC) |
+			TRB_TLBPC(last_burst_pkt_count) |
+			sia_frame_id |
+			(i ? ep_ring->cycle_state : !start_cycle);
+
+		/* xhci 1.1 with ETE uses TD_Size field for TBC, old is Rsvdz */
+		if (!xep->use_extended_tbc)
+			field |= TRB_TBC(burst_count);
+
+		/* fill the rest of the TRB fields, and remaining normal TRBs */
 		for (j = 0; j < trbs_per_td; j++) {
-			int frame_id = 0;
 			u32 remainder = 0;
-			field = 0;
 
-			if (first_trb) {
-				field = TRB_TBC(burst_count) |
-					TRB_TLBPC(residue);
-				/* Queue the isoc TRB */
-				field |= TRB_TYPE(TRB_ISOC);
-
-				/* Calculate Frame ID and SIA fields */
-				if (!(urb->transfer_flags & URB_ISO_ASAP) &&
-						HCC_CFC(xhci->hcc_params)) {
-					frame_id = xhci_get_isoc_frame_id(xhci,
-									  urb,
-									  i);
-					if (frame_id >= 0)
-						field |= TRB_FRAME_ID(frame_id);
-					else
-						field |= TRB_SIA;
-				} else
-					field |= TRB_SIA;
-
-				if (i == 0) {
-					if (start_cycle == 0)
-						field |= 0x1;
-				} else
-					field |= ep_ring->cycle_state;
-				first_trb = false;
-			} else {
-				/* Queue other normal TRBs */
-				field |= TRB_TYPE(TRB_NORMAL);
-				field |= ep_ring->cycle_state;
-			}
+			/* only first TRB is isoc, overwrite otherwise */
+			if (!first_trb)
+				field = TRB_TYPE(TRB_NORMAL) |
+					ep_ring->cycle_state;
 
 			/* Only set interrupt on short packet for IN EPs */
 			if (usb_urb_dir_in(urb))
 				field |= TRB_ISP;
 
-			/* Chain all the TRBs together; clear the chain bit in
-			 * the last TRB to indicate it's the last TRB in the
-			 * chain.
-			 */
+			/* Set the chain bit for all except the last TRB  */
 			if (j < trbs_per_td - 1) {
-				field |= TRB_CHAIN;
 				more_trbs_coming = true;
+				field |= TRB_CHAIN;
 			} else {
+				more_trbs_coming = false;
 				td->last_trb = ep_ring->enqueue;
 				field |= TRB_IOC;
-				if (xhci->hci_version == 0x100 &&
-						!(xhci->quirks &
-							XHCI_AVOID_BEI)) {
-					/* Set BEI bit except for the last td */
-					if (i < num_tds - 1)
-						field |= TRB_BEI;
-				}
-				more_trbs_coming = false;
+				/* set BEI, except for the last TD */
+				if (xhci->hci_version >= 0x100 &&
+				    !(xhci->quirks & XHCI_AVOID_BEI) &&
+				    i < num_tds - 1)
+					field |= TRB_BEI;
 			}
-
 			/* Calculate TRB length */
 			trb_buff_len = TRB_MAX_BUFF_SIZE -
 				(addr & ((1 << TRB_MAX_BUFF_SHIFT) - 1));
@@ -3838,9 +3836,15 @@ static int xhci_queue_isoc_tx(struct xhc
 						   urb, trbs_per_td - j - 1);
 
 			length_field = TRB_LEN(trb_buff_len) |
-				TRB_TD_SIZE(remainder) |
 				TRB_INTR_TARGET(0);
 
+			/* xhci 1.1 with ETE uses TD Size field for TBC */
+			if (first_trb && xep->use_extended_tbc)
+				length_field |= TRB_TD_SIZE_TBC(burst_count);
+			else
+				length_field |= TRB_TD_SIZE(remainder);
+			first_trb = false;
+
 			queue_trb(xhci, ep_ring, more_trbs_coming,
 				lower_32_bits(addr),
 				upper_32_bits(addr),
@@ -4018,7 +4022,8 @@ static int queue_command(struct xhci_hcd
 	int reserved_trbs = xhci->cmd_ring_reserved_trbs;
 	int ret;
 
-	if (xhci->xhc_state) {
+	if ((xhci->xhc_state & XHCI_STATE_DYING) ||
+		(xhci->xhc_state & XHCI_STATE_HALTED)) {
 		xhci_dbg(xhci, "xHCI dying or halted, can't queue_command\n");
 		return -ESHUTDOWN;
 	}
--- zfcpdump-kernel-4.4.orig/drivers/usb/host/xhci.c
+++ zfcpdump-kernel-4.4/drivers/usb/host/xhci.c
@@ -146,7 +146,8 @@ static int xhci_start(struct xhci_hcd *x
 				"waited %u microseconds.\n",
 				XHCI_MAX_HALT_USEC);
 	if (!ret)
-		xhci->xhc_state &= ~(XHCI_STATE_HALTED | XHCI_STATE_DYING);
+		/* clear state flags. Including dying, halted or removing */
+		xhci->xhc_state = 0;
 
 	return ret;
 }
@@ -679,20 +680,23 @@ void xhci_stop(struct usb_hcd *hcd)
 	u32 temp;
 	struct xhci_hcd *xhci = hcd_to_xhci(hcd);
 
-	if (xhci->xhc_state & XHCI_STATE_HALTED)
-		return;
-
 	mutex_lock(&xhci->mutex);
-	spin_lock_irq(&xhci->lock);
-	xhci->xhc_state |= XHCI_STATE_HALTED;
-	xhci->cmd_ring_state = CMD_RING_STATE_STOPPED;
 
-	/* Make sure the xHC is halted for a USB3 roothub
-	 * (xhci_stop() could be called as part of failed init).
-	 */
-	xhci_halt(xhci);
-	xhci_reset(xhci);
-	spin_unlock_irq(&xhci->lock);
+	if (!(xhci->xhc_state & XHCI_STATE_HALTED)) {
+		spin_lock_irq(&xhci->lock);
+
+		xhci->xhc_state |= XHCI_STATE_HALTED;
+		xhci->cmd_ring_state = CMD_RING_STATE_STOPPED;
+		xhci_halt(xhci);
+		xhci_reset(xhci);
+
+		spin_unlock_irq(&xhci->lock);
+	}
+
+	if (!usb_hcd_is_primary_hcd(hcd)) {
+		mutex_unlock(&xhci->mutex);
+		return;
+	}
 
 	xhci_cleanup_msix(xhci);
 
@@ -1103,8 +1107,8 @@ int xhci_resume(struct xhci_hcd *xhci, b
 		/* Resume root hubs only when have pending events. */
 		status = readl(&xhci->op_regs->status);
 		if (status & STS_EINT) {
-			usb_hcd_resume_root_hub(hcd);
 			usb_hcd_resume_root_hub(xhci->shared_hcd);
+			usb_hcd_resume_root_hub(hcd);
 		}
 	}
 
@@ -1119,10 +1123,10 @@ int xhci_resume(struct xhci_hcd *xhci, b
 
 	/* Re-enable port polling. */
 	xhci_dbg(xhci, "%s: starting port polling.\n", __func__);
-	set_bit(HCD_FLAG_POLL_RH, &hcd->flags);
-	usb_hcd_poll_rh_status(hcd);
 	set_bit(HCD_FLAG_POLL_RH, &xhci->shared_hcd->flags);
 	usb_hcd_poll_rh_status(xhci->shared_hcd);
+	set_bit(HCD_FLAG_POLL_RH, &hcd->flags);
+	usb_hcd_poll_rh_status(hcd);
 
 	return retval;
 }
@@ -1549,7 +1553,9 @@ int xhci_urb_dequeue(struct usb_hcd *hcd
 		xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb,
 				"HW died, freeing TD.");
 		urb_priv = urb->hcpriv;
-		for (i = urb_priv->td_cnt; i < urb_priv->length; i++) {
+		for (i = urb_priv->td_cnt;
+		     i < urb_priv->length && xhci->devs[urb->dev->slot_id];
+		     i++) {
 			td = urb_priv->td[i];
 			if (!list_empty(&td->td_list))
 				list_del_init(&td->td_list);
@@ -2067,6 +2073,7 @@ static unsigned int xhci_get_block_size(
 	case USB_SPEED_HIGH:
 		return HS_BLOCK;
 	case USB_SPEED_SUPER:
+	case USB_SPEED_SUPER_PLUS:
 		return SS_BLOCK;
 	case USB_SPEED_UNKNOWN:
 	case USB_SPEED_WIRELESS:
@@ -2192,7 +2199,7 @@ static int xhci_check_bw_table(struct xh
 	unsigned int packets_remaining = 0;
 	unsigned int i;
 
-	if (virt_dev->udev->speed == USB_SPEED_SUPER)
+	if (virt_dev->udev->speed >= USB_SPEED_SUPER)
 		return xhci_check_ss_bw(xhci, virt_dev);
 
 	if (virt_dev->udev->speed == USB_SPEED_HIGH) {
@@ -2393,7 +2400,7 @@ void xhci_drop_ep_from_interval_table(st
 	if (xhci_is_async_ep(ep_bw->type))
 		return;
 
-	if (udev->speed == USB_SPEED_SUPER) {
+	if (udev->speed >= USB_SPEED_SUPER) {
 		if (xhci_is_sync_in_ep(ep_bw->type))
 			xhci->devs[udev->slot_id]->bw_table->ss_bw_in -=
 				xhci_get_ss_bw_consumed(ep_bw);
@@ -2431,6 +2438,7 @@ void xhci_drop_ep_from_interval_table(st
 		interval_bw->overhead[HS_OVERHEAD_TYPE] -= 1;
 		break;
 	case USB_SPEED_SUPER:
+	case USB_SPEED_SUPER_PLUS:
 	case USB_SPEED_UNKNOWN:
 	case USB_SPEED_WIRELESS:
 		/* Should never happen because only LS/FS/HS endpoints will get
@@ -2490,6 +2498,7 @@ static void xhci_add_ep_to_interval_tabl
 		interval_bw->overhead[HS_OVERHEAD_TYPE] += 1;
 		break;
 	case USB_SPEED_SUPER:
+	case USB_SPEED_SUPER_PLUS:
 	case USB_SPEED_UNKNOWN:
 	case USB_SPEED_WIRELESS:
 		/* Should never happen because only LS/FS/HS endpoints will get
@@ -2751,7 +2760,8 @@ int xhci_check_bandwidth(struct usb_hcd
 	if (ret <= 0)
 		return ret;
 	xhci = hcd_to_xhci(hcd);
-	if (xhci->xhc_state & XHCI_STATE_DYING)
+	if ((xhci->xhc_state & XHCI_STATE_DYING) ||
+		(xhci->xhc_state & XHCI_STATE_REMOVING))
 		return -ENODEV;
 
 	xhci_dbg(xhci, "%s called for udev %p\n", __func__, udev);
@@ -3798,7 +3808,7 @@ static int xhci_setup_device(struct usb_
 
 	mutex_lock(&xhci->mutex);
 
-	if (xhci->xhc_state)	/* dying or halted */
+	if (xhci->xhc_state)	/* dying, removing or halted */
 		goto out;
 
 	if (!udev->slot_id) {
@@ -4878,6 +4888,7 @@ int xhci_gen_setup(struct usb_hcd *hcd,
 		if (xhci->sbrn == 0x31) {
 			xhci_info(xhci, "Host supports USB 3.1 Enhanced SuperSpeed\n");
 			hcd->speed = HCD_USB31;
+			hcd->self.root_hub->speed = USB_SPEED_SUPER_PLUS;
 		}
 		/* xHCI private pointer was set in xhci_pci_probe for the second
 		 * registered roothub.
@@ -5059,6 +5070,10 @@ static int __init xhci_hcd_init(void)
 	BUILD_BUG_ON(sizeof(struct xhci_intr_reg) != 8*32/8);
 	/* xhci_run_regs has eight fields and embeds 128 xhci_intr_regs */
 	BUILD_BUG_ON(sizeof(struct xhci_run_regs) != (8+8*128)*32/8);
+
+	if (usb_disabled())
+		return -ENODEV;
+
 	return 0;
 }
 
--- zfcpdump-kernel-4.4.orig/drivers/usb/host/xhci.h
+++ zfcpdump-kernel-4.4/drivers/usb/host/xhci.h
@@ -232,7 +232,9 @@ struct xhci_op_regs {
  * disabled, or powered-off state.
  */
 #define CMD_PM_INDEX	(1 << 11)
-/* bits 12:31 are reserved (and should be preserved on writes). */
+/* bit 14 Extended TBC Enable, changes Isoc TRB fields to support larger TBC */
+#define CMD_ETE		(1 << 14)
+/* bits 15:31 are reserved (and should be preserved on writes). */
 
 /* IMAN - Interrupt Management Register */
 #define IMAN_IE		(1 << 1)
@@ -343,6 +345,7 @@ struct xhci_op_regs {
 #define	SLOT_SPEED_LS		(XDEV_LS << 10)
 #define	SLOT_SPEED_HS		(XDEV_HS << 10)
 #define	SLOT_SPEED_SS		(XDEV_SS << 10)
+#define	SLOT_SPEED_SSP		(XDEV_SSP << 10)
 /* Port Indicator Control */
 #define PORT_LED_OFF	(0 << 14)
 #define PORT_LED_AMBER	(1 << 14)
@@ -748,8 +751,9 @@ struct xhci_ep_ctx {
 #define GET_MAX_PACKET(p)	((p) & 0x7ff)
 
 /* tx_info bitmasks */
-#define AVG_TRB_LENGTH_FOR_EP(p)	((p) & 0xffff)
-#define MAX_ESIT_PAYLOAD_FOR_EP(p)	(((p) & 0xffff) << 16)
+#define EP_AVG_TRB_LENGTH(p)		((p) & 0xffff)
+#define EP_MAX_ESIT_PAYLOAD_LO(p)	(((p) & 0xffff) << 16)
+#define EP_MAX_ESIT_PAYLOAD_HI(p)	((((p) >> 16) & 0xff) << 24)
 #define CTX_TO_MAX_ESIT_PAYLOAD(p)	(((p) >> 16) & 0xffff)
 
 /* deq bitmasks */
@@ -941,6 +945,8 @@ struct xhci_virt_ep {
 	struct list_head	bw_endpoint_list;
 	/* Isoch Frame ID checking storage */
 	int			next_frame_id;
+	/* Use new Isoch TRB layout needed for extended TBC support */
+	bool			use_extended_tbc;
 };
 
 enum xhci_overhead_type {
@@ -1182,9 +1188,12 @@ enum xhci_setup_dev {
 #define	TRB_LEN(p)		((p) & 0x1ffff)
 /* TD Size, packets remaining in this TD, bits 21:17 (5 bits, so max 31) */
 #define TRB_TD_SIZE(p)          (min((p), (u32)31) << 17)
+/* xhci 1.1 uses the TD_SIZE field for TBC if Extended TBC is enabled (ETE) */
+#define TRB_TD_SIZE_TBC(p)      (min((p), (u32)31) << 17)
 /* Interrupter Target - which MSI-X vector to target the completion event at */
 #define TRB_INTR_TARGET(p)	(((p) & 0x3ff) << 22)
 #define GET_INTR_TARGET(p)	(((p) >> 22) & 0x3ff)
+/* Total burst count field, Rsvdz on xhci 1.1 with Extended TBC enabled (ETE) */
 #define TRB_TBC(p)		(((p) & 0x3) << 7)
 #define TRB_TLBPC(p)		(((p) & 0xf) << 16)
 
@@ -1596,6 +1605,7 @@ struct xhci_hcd {
  */
 #define XHCI_STATE_DYING	(1 << 0)
 #define XHCI_STATE_HALTED	(1 << 1)
+#define XHCI_STATE_REMOVING	(1 << 2)
 	/* Statistics */
 	int			error_bitmask;
 	unsigned int		quirks;
--- zfcpdump-kernel-4.4.orig/drivers/usb/misc/iowarrior.c
+++ zfcpdump-kernel-4.4/drivers/usb/misc/iowarrior.c
@@ -787,6 +787,12 @@ static int iowarrior_probe(struct usb_in
 	iface_desc = interface->cur_altsetting;
 	dev->product_id = le16_to_cpu(udev->descriptor.idProduct);
 
+	if (iface_desc->desc.bNumEndpoints < 1) {
+		dev_err(&interface->dev, "Invalid number of endpoints\n");
+		retval = -EINVAL;
+		goto error;
+	}
+
 	/* set up the endpoint information */
 	for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
 		endpoint = &iface_desc->endpoint[i].desc;
--- zfcpdump-kernel-4.4.orig/drivers/usb/misc/legousbtower.c
+++ zfcpdump-kernel-4.4/drivers/usb/misc/legousbtower.c
@@ -898,24 +898,6 @@ static int tower_probe (struct usb_inter
 	dev->interrupt_in_interval = interrupt_in_interval ? interrupt_in_interval : dev->interrupt_in_endpoint->bInterval;
 	dev->interrupt_out_interval = interrupt_out_interval ? interrupt_out_interval : dev->interrupt_out_endpoint->bInterval;
 
-	/* we can register the device now, as it is ready */
-	usb_set_intfdata (interface, dev);
-
-	retval = usb_register_dev (interface, &tower_class);
-
-	if (retval) {
-		/* something prevented us from registering this driver */
-		dev_err(idev, "Not able to get a minor for this device.\n");
-		usb_set_intfdata (interface, NULL);
-		goto error;
-	}
-	dev->minor = interface->minor;
-
-	/* let the user know what node this device is now attached to */
-	dev_info(&interface->dev, "LEGO USB Tower #%d now attached to major "
-		 "%d minor %d\n", (dev->minor - LEGO_USB_TOWER_MINOR_BASE),
-		 USB_MAJOR, dev->minor);
-
 	/* get the firmware version and log it */
 	result = usb_control_msg (udev,
 				  usb_rcvctrlpipe(udev, 0),
@@ -936,6 +918,23 @@ static int tower_probe (struct usb_inter
 		 get_version_reply.minor,
 		 le16_to_cpu(get_version_reply.build_no));
 
+	/* we can register the device now, as it is ready */
+	usb_set_intfdata (interface, dev);
+
+	retval = usb_register_dev (interface, &tower_class);
+
+	if (retval) {
+		/* something prevented us from registering this driver */
+		dev_err(idev, "Not able to get a minor for this device.\n");
+		usb_set_intfdata (interface, NULL);
+		goto error;
+	}
+	dev->minor = interface->minor;
+
+	/* let the user know what node this device is now attached to */
+	dev_info(&interface->dev, "LEGO USB Tower #%d now attached to major "
+		 "%d minor %d\n", (dev->minor - LEGO_USB_TOWER_MINOR_BASE),
+		 USB_MAJOR, dev->minor);
 
 exit:
 	return retval;
--- zfcpdump-kernel-4.4.orig/drivers/usb/misc/usbtest.c
+++ zfcpdump-kernel-4.4/drivers/usb/misc/usbtest.c
@@ -505,6 +505,7 @@ static struct scatterlist *
 alloc_sglist(int nents, int max, int vary, struct usbtest_dev *dev, int pipe)
 {
 	struct scatterlist	*sg;
+	unsigned int		n_size = 0;
 	unsigned		i;
 	unsigned		size = max;
 	unsigned		maxpacket =
@@ -537,7 +538,8 @@ alloc_sglist(int nents, int max, int var
 			break;
 		case 1:
 			for (j = 0; j < size; j++)
-				*buf++ = (u8) ((j % maxpacket) % 63);
+				*buf++ = (u8) (((j + n_size) % maxpacket) % 63);
+			n_size += size;
 			break;
 		}
 
@@ -556,7 +558,6 @@ static void sg_timeout(unsigned long _re
 {
 	struct usb_sg_request	*req = (struct usb_sg_request *) _req;
 
-	req->status = -ETIMEDOUT;
 	usb_sg_cancel(req);
 }
 
@@ -587,8 +588,10 @@ static int perform_sglist(
 		mod_timer(&sg_timer, jiffies +
 				msecs_to_jiffies(SIMPLE_IO_TIMEOUT));
 		usb_sg_wait(req);
-		del_timer_sync(&sg_timer);
-		retval = req->status;
+		if (!del_timer_sync(&sg_timer))
+			retval = -ETIMEDOUT;
+		else
+			retval = req->status;
 
 		/* FIXME check resulting data pattern */
 
--- zfcpdump-kernel-4.4.orig/drivers/usb/musb/musb_core.c
+++ zfcpdump-kernel-4.4/drivers/usb/musb/musb_core.c
@@ -2401,7 +2401,8 @@ static void musb_restore_context(struct
 	musb_writew(musb_base, MUSB_INTRTXE, musb->intrtxe);
 	musb_writew(musb_base, MUSB_INTRRXE, musb->intrrxe);
 	musb_writeb(musb_base, MUSB_INTRUSBE, musb->context.intrusbe);
-	musb_writeb(musb_base, MUSB_DEVCTL, musb->context.devctl);
+	if (musb->context.devctl & MUSB_DEVCTL_SESSION)
+		musb_writeb(musb_base, MUSB_DEVCTL, musb->context.devctl);
 
 	for (i = 0; i < musb->config->num_eps; ++i) {
 		struct musb_hw_ep	*hw_ep;
--- zfcpdump-kernel-4.4.orig/drivers/usb/musb/musb_host.c
+++ zfcpdump-kernel-4.4/drivers/usb/musb/musb_host.c
@@ -594,14 +594,13 @@ musb_rx_reinit(struct musb *musb, struct
 		musb_writew(ep->regs, MUSB_TXCSR, 0);
 
 	/* scrub all previous state, clearing toggle */
-	} else {
-		csr = musb_readw(ep->regs, MUSB_RXCSR);
-		if (csr & MUSB_RXCSR_RXPKTRDY)
-			WARNING("rx%d, packet/%d ready?\n", ep->epnum,
-				musb_readw(ep->regs, MUSB_RXCOUNT));
-
-		musb_h_flush_rxfifo(ep, MUSB_RXCSR_CLRDATATOG);
 	}
+	csr = musb_readw(ep->regs, MUSB_RXCSR);
+	if (csr & MUSB_RXCSR_RXPKTRDY)
+		WARNING("rx%d, packet/%d ready?\n", ep->epnum,
+			musb_readw(ep->regs, MUSB_RXCOUNT));
+
+	musb_h_flush_rxfifo(ep, MUSB_RXCSR_CLRDATATOG);
 
 	/* target addr and (for multipoint) hub addr/port */
 	if (musb->is_multipoint) {
@@ -662,7 +661,7 @@ static int musb_tx_dma_set_mode_mentor(s
 		csr &= ~(MUSB_TXCSR_AUTOSET | MUSB_TXCSR_DMAMODE);
 		csr |= MUSB_TXCSR_DMAENAB; /* against programmer's guide */
 	}
-	channel->desired_mode = mode;
+	channel->desired_mode = *mode;
 	musb_writew(epio, MUSB_TXCSR, csr);
 
 	return 0;
@@ -995,9 +994,15 @@ static void musb_bulk_nak_timeout(struct
 	if (is_in) {
 		dma = is_dma_capable() ? ep->rx_channel : NULL;
 
-		/* clear nak timeout bit */
+		/*
+		 * Need to stop the transaction by clearing REQPKT first
+		 * then the NAK Timeout bit ref MUSBMHDRC USB 2.0 HIGH-SPEED
+		 * DUAL-ROLE CONTROLLER Programmer's Guide, section 9.2.2
+		 */
 		rx_csr = musb_readw(epio, MUSB_RXCSR);
 		rx_csr |= MUSB_RXCSR_H_WZC_BITS;
+		rx_csr &= ~MUSB_RXCSR_H_REQPKT;
+		musb_writew(epio, MUSB_RXCSR, rx_csr);
 		rx_csr &= ~MUSB_RXCSR_DATAERROR;
 		musb_writew(epio, MUSB_RXCSR, rx_csr);
 
@@ -1551,7 +1556,7 @@ static int musb_rx_dma_iso_cppi41(struct
 				  struct urb *urb,
 				  size_t len)
 {
-	struct dma_channel *channel = hw_ep->tx_channel;
+	struct dma_channel *channel = hw_ep->rx_channel;
 	void __iomem *epio = hw_ep->regs;
 	dma_addr_t *buf;
 	u32 length, res;
@@ -2003,10 +2008,8 @@ void musb_host_rx(struct musb *musb, u8
 				qh->offset,
 				urb->transfer_buffer_length);
 
-			done = musb_rx_dma_in_inventra_cppi41(c, hw_ep, qh,
-							      urb, xfer_len,
-							      iso_err);
-			if (done)
+			if (musb_rx_dma_in_inventra_cppi41(c, hw_ep, qh, urb,
+							   xfer_len, iso_err))
 				goto finish;
 			else
 				dev_err(musb->controller, "error: rx_dma failed\n");
--- zfcpdump-kernel-4.4.orig/drivers/usb/phy/phy-fsl-usb.c
+++ zfcpdump-kernel-4.4/drivers/usb/phy/phy-fsl-usb.c
@@ -75,7 +75,7 @@ static struct fsl_otg_config fsl_otg_ini
 	.otg_port = 1,
 };
 
-#ifdef CONFIG_PPC32
+#ifdef CONFIG_PPC
 static u32 _fsl_readl_be(const unsigned __iomem *p)
 {
 	return in_be32(p);
@@ -105,7 +105,7 @@ static void (*_fsl_writel)(u32 v, unsign
 #else
 #define fsl_readl(addr)		readl(addr)
 #define fsl_writel(val, addr)	writel(val, addr)
-#endif /* CONFIG_PPC32 */
+#endif /* CONFIG_PPC */
 
 int write_ulpi(u8 addr, u8 data)
 {
@@ -879,6 +879,7 @@ int usb_otg_start(struct platform_device
 	if (pdata->init && pdata->init(pdev) != 0)
 		return -EINVAL;
 
+#ifdef CONFIG_PPC
 	if (pdata->big_endian_mmio) {
 		_fsl_readl = _fsl_readl_be;
 		_fsl_writel = _fsl_writel_be;
@@ -886,6 +887,7 @@ int usb_otg_start(struct platform_device
 		_fsl_readl = _fsl_readl_le;
 		_fsl_writel = _fsl_writel_le;
 	}
+#endif
 
 	/* request irq */
 	p_otg->irq = platform_get_irq(pdev, 0);
--- zfcpdump-kernel-4.4.orig/drivers/usb/phy/phy-msm-usb.c
+++ zfcpdump-kernel-4.4/drivers/usb/phy/phy-msm-usb.c
@@ -1599,6 +1599,8 @@ static int msm_otg_read_dt(struct platfo
 						&motg->id.nb);
 		if (ret < 0) {
 			dev_err(&pdev->dev, "register ID notifier failed\n");
+			extcon_unregister_notifier(motg->vbus.extcon,
+						   EXTCON_USB, &motg->vbus.nb);
 			return ret;
 		}
 
@@ -1660,15 +1662,6 @@ static int msm_otg_probe(struct platform
 	if (!motg)
 		return -ENOMEM;
 
-	pdata = dev_get_platdata(&pdev->dev);
-	if (!pdata) {
-		if (!np)
-			return -ENXIO;
-		ret = msm_otg_read_dt(pdev, motg);
-		if (ret)
-			return ret;
-	}
-
 	motg->phy.otg = devm_kzalloc(&pdev->dev, sizeof(struct usb_otg),
 				     GFP_KERNEL);
 	if (!motg->phy.otg)
@@ -1710,6 +1703,15 @@ static int msm_otg_probe(struct platform
 	if (!motg->regs)
 		return -ENOMEM;
 
+	pdata = dev_get_platdata(&pdev->dev);
+	if (!pdata) {
+		if (!np)
+			return -ENXIO;
+		ret = msm_otg_read_dt(pdev, motg);
+		if (ret)
+			return ret;
+	}
+
 	/*
 	 * NOTE: The PHYs can be multiplexed between the chipidea controller
 	 * and the dwc3 controller, using a single bit. It is important that
@@ -1717,8 +1719,10 @@ static int msm_otg_probe(struct platform
 	 */
 	if (motg->phy_number) {
 		phy_select = devm_ioremap_nocache(&pdev->dev, USB2_PHY_SEL, 4);
-		if (!phy_select)
-			return -ENOMEM;
+		if (!phy_select) {
+			ret = -ENOMEM;
+			goto unregister_extcon;
+		}
 		/* Enable second PHY with the OTG port */
 		writel(0x1, phy_select);
 	}
@@ -1728,7 +1732,8 @@ static int msm_otg_probe(struct platform
 	motg->irq = platform_get_irq(pdev, 0);
 	if (motg->irq < 0) {
 		dev_err(&pdev->dev, "platform_get_irq failed\n");
-		return motg->irq;
+		ret = motg->irq;
+		goto unregister_extcon;
 	}
 
 	regs[0].supply = "vddcx";
@@ -1737,7 +1742,7 @@ static int msm_otg_probe(struct platform
 
 	ret = devm_regulator_bulk_get(motg->phy.dev, ARRAY_SIZE(regs), regs);
 	if (ret)
-		return ret;
+		goto unregister_extcon;
 
 	motg->vddcx = regs[0].consumer;
 	motg->v3p3  = regs[1].consumer;
@@ -1834,6 +1839,12 @@ disable_clks:
 	clk_disable_unprepare(motg->clk);
 	if (!IS_ERR(motg->core_clk))
 		clk_disable_unprepare(motg->core_clk);
+unregister_extcon:
+	extcon_unregister_notifier(motg->id.extcon,
+				   EXTCON_USB_HOST, &motg->id.nb);
+	extcon_unregister_notifier(motg->vbus.extcon,
+				   EXTCON_USB, &motg->vbus.nb);
+
 	return ret;
 }
 
--- zfcpdump-kernel-4.4.orig/drivers/usb/renesas_usbhs/fifo.c
+++ zfcpdump-kernel-4.4/drivers/usb/renesas_usbhs/fifo.c
@@ -190,7 +190,8 @@ static int usbhsf_pkt_handler(struct usb
 		goto __usbhs_pkt_handler_end;
 	}
 
-	ret = func(pkt, &is_done);
+	if (likely(func))
+		ret = func(pkt, &is_done);
 
 	if (is_done)
 		__usbhsf_pkt_del(pkt);
@@ -807,20 +808,27 @@ static void xfer_work(struct work_struct
 {
 	struct usbhs_pkt *pkt = container_of(work, struct usbhs_pkt, work);
 	struct usbhs_pipe *pipe = pkt->pipe;
-	struct usbhs_fifo *fifo = usbhs_pipe_to_fifo(pipe);
+	struct usbhs_fifo *fifo;
 	struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
 	struct dma_async_tx_descriptor *desc;
-	struct dma_chan *chan = usbhsf_dma_chan_get(fifo, pkt);
+	struct dma_chan *chan;
 	struct device *dev = usbhs_priv_to_dev(priv);
 	enum dma_transfer_direction dir;
+	unsigned long flags;
+
+	usbhs_lock(priv, flags);
+	fifo = usbhs_pipe_to_fifo(pipe);
+	if (!fifo)
+		goto xfer_work_end;
 
+	chan = usbhsf_dma_chan_get(fifo, pkt);
 	dir = usbhs_pipe_is_dir_in(pipe) ? DMA_DEV_TO_MEM : DMA_MEM_TO_DEV;
 
 	desc = dmaengine_prep_slave_single(chan, pkt->dma + pkt->actual,
 					pkt->trans, dir,
 					DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
 	if (!desc)
-		return;
+		goto xfer_work_end;
 
 	desc->callback		= usbhsf_dma_complete;
 	desc->callback_param	= pipe;
@@ -828,7 +836,7 @@ static void xfer_work(struct work_struct
 	pkt->cookie = dmaengine_submit(desc);
 	if (pkt->cookie < 0) {
 		dev_err(dev, "Failed to submit dma descriptor\n");
-		return;
+		goto xfer_work_end;
 	}
 
 	dev_dbg(dev, "  %s %d (%d/ %d)\n",
@@ -839,6 +847,9 @@ static void xfer_work(struct work_struct
 	usbhs_pipe_set_trans_count_if_bulk(pipe, pkt->trans);
 	dma_async_issue_pending(chan);
 	usbhs_pipe_enable(pipe);
+
+xfer_work_end:
+	usbhs_unlock(priv, flags);
 }
 
 /*
@@ -858,7 +869,7 @@ static int usbhsf_dma_prepare_push(struc
 
 	/* use PIO if packet is less than pio_dma_border or pipe is DCP */
 	if ((len < usbhs_get_dparam(priv, pio_dma_border)) ||
-	    usbhs_pipe_is_dcp(pipe))
+	    usbhs_pipe_type_is(pipe, USB_ENDPOINT_XFER_ISOC))
 		goto usbhsf_pio_prepare_push;
 
 	/* check data length if this driver don't use USB-DMAC */
@@ -889,6 +900,7 @@ static int usbhsf_dma_prepare_push(struc
 
 	pkt->trans = len;
 
+	usbhsf_tx_irq_ctrl(pipe, 0);
 	INIT_WORK(&pkt->work, xfer_work);
 	schedule_work(&pkt->work);
 
@@ -962,7 +974,7 @@ static int usbhsf_dma_prepare_pop_with_u
 
 	/* use PIO if packet is less than pio_dma_border or pipe is DCP */
 	if ((pkt->length < usbhs_get_dparam(priv, pio_dma_border)) ||
-	    usbhs_pipe_is_dcp(pipe))
+	    usbhs_pipe_type_is(pipe, USB_ENDPOINT_XFER_ISOC))
 		goto usbhsf_pio_prepare_pop;
 
 	fifo = usbhsf_get_dma_fifo(priv, pkt);
--- zfcpdump-kernel-4.4.orig/drivers/usb/renesas_usbhs/mod.c
+++ zfcpdump-kernel-4.4/drivers/usb/renesas_usbhs/mod.c
@@ -282,9 +282,16 @@ static irqreturn_t usbhs_interrupt(int i
 	if (usbhs_mod_is_host(priv))
 		usbhs_write(priv, INTSTS1, ~irq_state.intsts1 & INTSTS1_MAGIC);
 
-	usbhs_write(priv, BRDYSTS, ~irq_state.brdysts);
+	/*
+	 * The driver should not clear the xxxSTS after the line of
+	 * "call irq callback functions" because each "if" statement is
+	 * possible to call the callback function for avoiding any side effects.
+	 */
+	if (irq_state.intsts0 & BRDY)
+		usbhs_write(priv, BRDYSTS, ~irq_state.brdysts);
 	usbhs_write(priv, NRDYSTS, ~irq_state.nrdysts);
-	usbhs_write(priv, BEMPSTS, ~irq_state.bempsts);
+	if (irq_state.intsts0 & BEMP)
+		usbhs_write(priv, BEMPSTS, ~irq_state.bempsts);
 
 	/*
 	 * call irq callback functions
--- zfcpdump-kernel-4.4.orig/drivers/usb/renesas_usbhs/mod_gadget.c
+++ zfcpdump-kernel-4.4/drivers/usb/renesas_usbhs/mod_gadget.c
@@ -158,10 +158,14 @@ static void usbhsg_queue_done(struct usb
 	struct usbhs_pipe *pipe = pkt->pipe;
 	struct usbhsg_uep *uep = usbhsg_pipe_to_uep(pipe);
 	struct usbhsg_request *ureq = usbhsg_pkt_to_ureq(pkt);
+	unsigned long flags;
 
 	ureq->req.actual = pkt->actual;
 
-	usbhsg_queue_pop(uep, ureq, 0);
+	usbhs_lock(priv, flags);
+	if (uep)
+		__usbhsg_queue_pop(uep, ureq, 0);
+	usbhs_unlock(priv, flags);
 }
 
 static void usbhsg_queue_push(struct usbhsg_uep *uep,
@@ -582,6 +586,9 @@ static int usbhsg_ep_enable(struct usb_e
 	struct usbhs_priv *priv = usbhsg_gpriv_to_priv(gpriv);
 	struct usbhs_pipe *pipe;
 	int ret = -EIO;
+	unsigned long flags;
+
+	usbhs_lock(priv, flags);
 
 	/*
 	 * if it already have pipe,
@@ -590,7 +597,8 @@ static int usbhsg_ep_enable(struct usb_e
 	if (uep->pipe) {
 		usbhs_pipe_clear(uep->pipe);
 		usbhs_pipe_sequence_data0(uep->pipe);
-		return 0;
+		ret = 0;
+		goto usbhsg_ep_enable_end;
 	}
 
 	pipe = usbhs_pipe_malloc(priv,
@@ -610,14 +618,20 @@ static int usbhsg_ep_enable(struct usb_e
 		 * use dmaengine if possible.
 		 * It will use pio handler if impossible.
 		 */
-		if (usb_endpoint_dir_in(desc))
+		if (usb_endpoint_dir_in(desc)) {
 			pipe->handler = &usbhs_fifo_dma_push_handler;
-		else
+		} else {
 			pipe->handler = &usbhs_fifo_dma_pop_handler;
+			usbhs_xxxsts_clear(priv, BRDYSTS,
+					   usbhs_pipe_number(pipe));
+		}
 
 		ret = 0;
 	}
 
+usbhsg_ep_enable_end:
+	usbhs_unlock(priv, flags);
+
 	return ret;
 }
 
@@ -1061,7 +1075,7 @@ int usbhs_mod_gadget_probe(struct usbhs_
 
 	gpriv->transceiver = usb_get_phy(USB_PHY_TYPE_UNDEFINED);
 	dev_info(dev, "%stransceiver found\n",
-		 gpriv->transceiver ? "" : "no ");
+		 !IS_ERR(gpriv->transceiver) ? "" : "no ");
 
 	/*
 	 * CAUTION
--- zfcpdump-kernel-4.4.orig/drivers/usb/serial/cp210x.c
+++ zfcpdump-kernel-4.4/drivers/usb/serial/cp210x.c
@@ -98,6 +98,7 @@ static const struct usb_device_id id_tab
 	{ USB_DEVICE(0x10C4, 0x81AC) }, /* MSD Dash Hawk */
 	{ USB_DEVICE(0x10C4, 0x81AD) }, /* INSYS USB Modem */
 	{ USB_DEVICE(0x10C4, 0x81C8) }, /* Lipowsky Industrie Elektronik GmbH, Baby-JTAG */
+	{ USB_DEVICE(0x10C4, 0x81D7) }, /* IAI Corp. RCB-CV-USB USB to RS485 Adaptor */
 	{ USB_DEVICE(0x10C4, 0x81E2) }, /* Lipowsky Industrie Elektronik GmbH, Baby-LIN */
 	{ USB_DEVICE(0x10C4, 0x81E7) }, /* Aerocomm Radio */
 	{ USB_DEVICE(0x10C4, 0x81E8) }, /* Zephyr Bioharness */
@@ -107,6 +108,7 @@ static const struct usb_device_id id_tab
 	{ USB_DEVICE(0x10C4, 0x826B) }, /* Cygnal Integrated Products, Inc., Fasttrax GPS demonstration module */
 	{ USB_DEVICE(0x10C4, 0x8281) }, /* Nanotec Plug & Drive */
 	{ USB_DEVICE(0x10C4, 0x8293) }, /* Telegesis ETRX2USB */
+	{ USB_DEVICE(0x10C4, 0x82F4) }, /* Starizona MicroTouch */
 	{ USB_DEVICE(0x10C4, 0x82F9) }, /* Procyon AVS */
 	{ USB_DEVICE(0x10C4, 0x8341) }, /* Siemens MC35PU GPRS Modem */
 	{ USB_DEVICE(0x10C4, 0x8382) }, /* Cygnal Integrated Products, Inc. */
@@ -115,7 +117,9 @@ static const struct usb_device_id id_tab
 	{ USB_DEVICE(0x10C4, 0x8411) }, /* Kyocera GPS Module */
 	{ USB_DEVICE(0x10C4, 0x8418) }, /* IRZ Automation Teleport SG-10 GSM/GPRS Modem */
 	{ USB_DEVICE(0x10C4, 0x846E) }, /* BEI USB Sensor Interface (VCP) */
+	{ USB_DEVICE(0x10C4, 0x8470) }, /* Juniper Networks BX Series System Console */
 	{ USB_DEVICE(0x10C4, 0x8477) }, /* Balluff RFID */
+	{ USB_DEVICE(0x10C4, 0x84B6) }, /* Starizona Hyperion */
 	{ USB_DEVICE(0x10C4, 0x85EA) }, /* AC-Services IBUS-IF */
 	{ USB_DEVICE(0x10C4, 0x85EB) }, /* AC-Services CIS-IBUS */
 	{ USB_DEVICE(0x10C4, 0x85F8) }, /* Virtenio Preon32 */
@@ -139,6 +143,8 @@ static const struct usb_device_id id_tab
 	{ USB_DEVICE(0x10C4, 0xF004) }, /* Elan Digital Systems USBcount50 */
 	{ USB_DEVICE(0x10C5, 0xEA61) }, /* Silicon Labs MobiData GPRS USB Modem */
 	{ USB_DEVICE(0x10CE, 0xEA6A) }, /* Silicon Labs MobiData GPRS USB Modem 100EU */
+	{ USB_DEVICE(0x12B8, 0xEC60) }, /* Link G4 ECU */
+	{ USB_DEVICE(0x12B8, 0xEC62) }, /* Link G4+ ECU */
 	{ USB_DEVICE(0x13AD, 0x9999) }, /* Baltech card reader */
 	{ USB_DEVICE(0x1555, 0x0004) }, /* Owen AC4 USB-RS485 Converter */
 	{ USB_DEVICE(0x166A, 0x0201) }, /* Clipsal 5500PACA C-Bus Pascal Automation Controller */
@@ -160,6 +166,11 @@ static const struct usb_device_id id_tab
 	{ USB_DEVICE(0x17F4, 0xAAAA) }, /* Wavesense Jazz blood glucose meter */
 	{ USB_DEVICE(0x1843, 0x0200) }, /* Vaisala USB Instrument Cable */
 	{ USB_DEVICE(0x18EF, 0xE00F) }, /* ELV USB-I2C-Interface */
+	{ USB_DEVICE(0x18EF, 0xE025) }, /* ELV Marble Sound Board 1 */
+	{ USB_DEVICE(0x1901, 0x0190) }, /* GE B850 CP2105 Recorder interface */
+	{ USB_DEVICE(0x1901, 0x0193) }, /* GE B650 CP2104 PMC interface */
+	{ USB_DEVICE(0x1901, 0x0194) },	/* GE Healthcare Remote Alarm Box */
+	{ USB_DEVICE(0x19CF, 0x3000) }, /* Parrot NMEA GPS Flight Recorder */
 	{ USB_DEVICE(0x1ADB, 0x0001) }, /* Schweitzer Engineering C662 Cable */
 	{ USB_DEVICE(0x1B1C, 0x1C00) }, /* Corsair USB Dongle */
 	{ USB_DEVICE(0x1BA4, 0x0002) },	/* Silicon Labs 358x factory default */
@@ -774,7 +785,7 @@ static void cp210x_set_termios(struct tt
 		} else {
 			modem_ctl[0] &= ~0x7B;
 			modem_ctl[0] |= 0x01;
-			modem_ctl[1] |= 0x40;
+			modem_ctl[1] = 0x40;
 			dev_dbg(dev, "%s - flow control = NONE\n", __func__);
 		}
 
--- zfcpdump-kernel-4.4.orig/drivers/usb/serial/cypress_m8.c
+++ zfcpdump-kernel-4.4/drivers/usb/serial/cypress_m8.c
@@ -447,6 +447,11 @@ static int cypress_generic_port_probe(st
 	struct usb_serial *serial = port->serial;
 	struct cypress_private *priv;
 
+	if (!port->interrupt_out_urb || !port->interrupt_in_urb) {
+		dev_err(&port->dev, "required endpoint is missing\n");
+		return -ENODEV;
+	}
+
 	priv = kzalloc(sizeof(struct cypress_private), GFP_KERNEL);
 	if (!priv)
 		return -ENOMEM;
@@ -606,12 +611,6 @@ static int cypress_open(struct tty_struc
 		cypress_set_termios(tty, port, &priv->tmp_termios);
 
 	/* setup the port and start reading from the device */
-	if (!port->interrupt_in_urb) {
-		dev_err(&port->dev, "%s - interrupt_in_urb is empty!\n",
-			__func__);
-		return -1;
-	}
-
 	usb_fill_int_urb(port->interrupt_in_urb, serial->dev,
 		usb_rcvintpipe(serial->dev, port->interrupt_in_endpointAddress),
 		port->interrupt_in_urb->transfer_buffer,
--- zfcpdump-kernel-4.4.orig/drivers/usb/serial/digi_acceleport.c
+++ zfcpdump-kernel-4.4/drivers/usb/serial/digi_acceleport.c
@@ -1251,8 +1251,27 @@ static int digi_port_init(struct usb_ser
 
 static int digi_startup(struct usb_serial *serial)
 {
+	struct device *dev = &serial->interface->dev;
 	struct digi_serial *serial_priv;
 	int ret;
+	int i;
+
+	/* check whether the device has the expected number of endpoints */
+	if (serial->num_port_pointers < serial->type->num_ports + 1) {
+		dev_err(dev, "OOB endpoints missing\n");
+		return -ENODEV;
+	}
+
+	for (i = 0; i < serial->type->num_ports + 1 ; i++) {
+		if (!serial->port[i]->read_urb) {
+			dev_err(dev, "bulk-in endpoint missing\n");
+			return -ENODEV;
+		}
+		if (!serial->port[i]->write_urb) {
+			dev_err(dev, "bulk-out endpoint missing\n");
+			return -ENODEV;
+		}
+	}
 
 	serial_priv = kzalloc(sizeof(*serial_priv), GFP_KERNEL);
 	if (!serial_priv)
--- zfcpdump-kernel-4.4.orig/drivers/usb/serial/ftdi_sio.c
+++ zfcpdump-kernel-4.4/drivers/usb/serial/ftdi_sio.c
@@ -648,6 +648,8 @@ static const struct usb_device_id id_tab
 	{ USB_DEVICE(FTDI_VID, FTDI_ELV_TFD128_PID) },
 	{ USB_DEVICE(FTDI_VID, FTDI_ELV_FM3RX_PID) },
 	{ USB_DEVICE(FTDI_VID, FTDI_ELV_WS777_PID) },
+	{ USB_DEVICE(FTDI_VID, FTDI_PALMSENS_PID) },
+	{ USB_DEVICE(FTDI_VID, FTDI_IVIUM_XSTAT_PID) },
 	{ USB_DEVICE(FTDI_VID, LINX_SDMUSBQSS_PID) },
 	{ USB_DEVICE(FTDI_VID, LINX_MASTERDEVEL2_PID) },
 	{ USB_DEVICE(FTDI_VID, LINX_FUTURE_0_PID) },
@@ -824,6 +826,7 @@ static const struct usb_device_id id_tab
 	{ USB_DEVICE(FTDI_VID, FTDI_TURTELIZER_PID),
 		.driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
 	{ USB_DEVICE(RATOC_VENDOR_ID, RATOC_PRODUCT_ID_USB60F) },
+	{ USB_DEVICE(RATOC_VENDOR_ID, RATOC_PRODUCT_ID_SCU18) },
 	{ USB_DEVICE(FTDI_VID, FTDI_REU_TINY_PID) },
 
 	/* Papouch devices based on FTDI chip */
@@ -1003,6 +1006,11 @@ static const struct usb_device_id id_tab
 	{ USB_DEVICE(FTDI_VID, CHETCO_SEASMART_DISPLAY_PID) },
 	{ USB_DEVICE(FTDI_VID, CHETCO_SEASMART_LITE_PID) },
 	{ USB_DEVICE(FTDI_VID, CHETCO_SEASMART_ANALOG_PID) },
+	/* ICP DAS I-756xU devices */
+	{ USB_DEVICE(ICPDAS_VID, ICPDAS_I7560U_PID) },
+	{ USB_DEVICE(ICPDAS_VID, ICPDAS_I7561U_PID) },
+	{ USB_DEVICE(ICPDAS_VID, ICPDAS_I7563U_PID) },
+	{ USB_DEVICE(WICED_VID, WICED_USB20706V2_PID) },
 	{ }					/* Terminating entry */
 };
 
--- zfcpdump-kernel-4.4.orig/drivers/usb/serial/ftdi_sio_ids.h
+++ zfcpdump-kernel-4.4/drivers/usb/serial/ftdi_sio_ids.h
@@ -406,6 +406,12 @@
 #define FTDI_4N_GALAXY_DE_3_PID	0xF3C2
 
 /*
+ * Ivium Technologies product IDs
+ */
+#define FTDI_PALMSENS_PID	0xf440
+#define FTDI_IVIUM_XSTAT_PID	0xf441
+
+/*
  * Linx Technologies product ids
  */
 #define LINX_SDMUSBQSS_PID	0xF448	/* Linx SDM-USB-QS-S */
@@ -615,6 +621,7 @@
  */
 #define RATOC_VENDOR_ID		0x0584
 #define RATOC_PRODUCT_ID_USB60F	0xb020
+#define RATOC_PRODUCT_ID_SCU18	0xb03a
 
 /*
  * Infineon Technologies
@@ -672,6 +679,12 @@
 #define INTREPID_NEOVI_PID	0x0701
 
 /*
+ * WICED USB UART
+ */
+#define WICED_VID		0x0A5C
+#define WICED_USB20706V2_PID	0x6422
+
+/*
  * Definitions for ID TECH (www.idt-net.com) devices
  */
 #define IDTECH_VID		0x0ACD	/* ID TECH Vendor ID */
@@ -871,6 +884,14 @@
 #define NOVITUS_BONO_E_PID		0x6010
 
 /*
+ * ICPDAS I-756*U devices
+ */
+#define ICPDAS_VID			0x1b5c
+#define ICPDAS_I7560U_PID		0x0103
+#define ICPDAS_I7561U_PID		0x0104
+#define ICPDAS_I7563U_PID		0x0105
+
+/*
  * RT Systems programming cables for various ham radios
  */
 #define RTSYSTEMS_VID		0x2100	/* Vendor ID */
--- zfcpdump-kernel-4.4.orig/drivers/usb/serial/io_edgeport.c
+++ zfcpdump-kernel-4.4/drivers/usb/serial/io_edgeport.c
@@ -2856,14 +2856,16 @@ static int edge_startup(struct usb_seria
 				/* not set up yet, so do it now */
 				edge_serial->interrupt_read_urb =
 						usb_alloc_urb(0, GFP_KERNEL);
-				if (!edge_serial->interrupt_read_urb)
-					return -ENOMEM;
+				if (!edge_serial->interrupt_read_urb) {
+					response = -ENOMEM;
+					break;
+				}
 
 				edge_serial->interrupt_in_buffer =
 					kmalloc(buffer_size, GFP_KERNEL);
 				if (!edge_serial->interrupt_in_buffer) {
-					usb_free_urb(edge_serial->interrupt_read_urb);
-					return -ENOMEM;
+					response = -ENOMEM;
+					break;
 				}
 				edge_serial->interrupt_in_endpoint =
 						endpoint->bEndpointAddress;
@@ -2891,14 +2893,16 @@ static int edge_startup(struct usb_seria
 				/* not set up yet, so do it now */
 				edge_serial->read_urb =
 						usb_alloc_urb(0, GFP_KERNEL);
-				if (!edge_serial->read_urb)
-					return -ENOMEM;
+				if (!edge_serial->read_urb) {
+					response = -ENOMEM;
+					break;
+				}
 
 				edge_serial->bulk_in_buffer =
 					kmalloc(buffer_size, GFP_KERNEL);
 				if (!edge_serial->bulk_in_buffer) {
-					usb_free_urb(edge_serial->read_urb);
-					return -ENOMEM;
+					response = -ENOMEM;
+					break;
 				}
 				edge_serial->bulk_in_endpoint =
 						endpoint->bEndpointAddress;
@@ -2924,9 +2928,22 @@ static int edge_startup(struct usb_seria
 			}
 		}
 
-		if (!interrupt_in_found || !bulk_in_found || !bulk_out_found) {
-			dev_err(ddev, "Error - the proper endpoints were not found!\n");
-			return -ENODEV;
+		if (response || !interrupt_in_found || !bulk_in_found ||
+							!bulk_out_found) {
+			if (!response) {
+				dev_err(ddev, "expected endpoints not found\n");
+				response = -ENODEV;
+			}
+
+			usb_free_urb(edge_serial->interrupt_read_urb);
+			kfree(edge_serial->interrupt_in_buffer);
+
+			usb_free_urb(edge_serial->read_urb);
+			kfree(edge_serial->bulk_in_buffer);
+
+			kfree(edge_serial);
+
+			return response;
 		}
 
 		/* start interrupt read for this edgeport this interrupt will
@@ -2949,16 +2966,9 @@ static void edge_disconnect(struct usb_s
 {
 	struct edgeport_serial *edge_serial = usb_get_serial_data(serial);
 
-	/* stop reads and writes on all ports */
-	/* free up our endpoint stuff */
 	if (edge_serial->is_epic) {
 		usb_kill_urb(edge_serial->interrupt_read_urb);
-		usb_free_urb(edge_serial->interrupt_read_urb);
-		kfree(edge_serial->interrupt_in_buffer);
-
 		usb_kill_urb(edge_serial->read_urb);
-		usb_free_urb(edge_serial->read_urb);
-		kfree(edge_serial->bulk_in_buffer);
 	}
 }
 
@@ -2971,6 +2981,16 @@ static void edge_release(struct usb_seri
 {
 	struct edgeport_serial *edge_serial = usb_get_serial_data(serial);
 
+	if (edge_serial->is_epic) {
+		usb_kill_urb(edge_serial->interrupt_read_urb);
+		usb_free_urb(edge_serial->interrupt_read_urb);
+		kfree(edge_serial->interrupt_in_buffer);
+
+		usb_kill_urb(edge_serial->read_urb);
+		usb_free_urb(edge_serial->read_urb);
+		kfree(edge_serial->bulk_in_buffer);
+	}
+
 	kfree(edge_serial);
 }
 
--- zfcpdump-kernel-4.4.orig/drivers/usb/serial/keyspan.c
+++ zfcpdump-kernel-4.4/drivers/usb/serial/keyspan.c
@@ -2376,6 +2376,10 @@ static void keyspan_release(struct usb_s
 
 	s_priv = usb_get_serial_data(serial);
 
+	/* Make sure to unlink the URBs submitted in attach. */
+	usb_kill_urb(s_priv->instat_urb);
+	usb_kill_urb(s_priv->indat_urb);
+
 	usb_free_urb(s_priv->instat_urb);
 	usb_free_urb(s_priv->indat_urb);
 	usb_free_urb(s_priv->glocont_urb);
--- zfcpdump-kernel-4.4.orig/drivers/usb/serial/mct_u232.c
+++ zfcpdump-kernel-4.4/drivers/usb/serial/mct_u232.c
@@ -376,14 +376,21 @@ static void mct_u232_msr_to_state(struct
 
 static int mct_u232_port_probe(struct usb_serial_port *port)
 {
+	struct usb_serial *serial = port->serial;
 	struct mct_u232_private *priv;
 
+	/* check first to simplify error handling */
+	if (!serial->port[1] || !serial->port[1]->interrupt_in_urb) {
+		dev_err(&port->dev, "expected endpoint missing\n");
+		return -ENODEV;
+	}
+
 	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
 	if (!priv)
 		return -ENOMEM;
 
 	/* Use second interrupt-in endpoint for reading. */
-	priv->read_urb = port->serial->port[1]->interrupt_in_urb;
+	priv->read_urb = serial->port[1]->interrupt_in_urb;
 	priv->read_urb->context = port;
 
 	spin_lock_init(&priv->lock);
--- zfcpdump-kernel-4.4.orig/drivers/usb/serial/mos7720.c
+++ zfcpdump-kernel-4.4/drivers/usb/serial/mos7720.c
@@ -1252,7 +1252,7 @@ static int mos7720_write(struct tty_stru
 
 	if (urb->transfer_buffer == NULL) {
 		urb->transfer_buffer = kmalloc(URB_TRANSFER_BUFFER_SIZE,
-					       GFP_KERNEL);
+					       GFP_ATOMIC);
 		if (!urb->transfer_buffer)
 			goto exit;
 	}
@@ -2007,6 +2007,7 @@ static void mos7720_release(struct usb_s
 				    urblist_entry)
 			usb_unlink_urb(urbtrack->urb);
 		spin_unlock_irqrestore(&mos_parport->listlock, flags);
+		parport_del_port(mos_parport->pp);
 
 		kref_put(&mos_parport->ref_count, destroy_mos_parport);
 	}
--- zfcpdump-kernel-4.4.orig/drivers/usb/serial/mos7840.c
+++ zfcpdump-kernel-4.4/drivers/usb/serial/mos7840.c
@@ -1340,8 +1340,8 @@ static int mos7840_write(struct tty_stru
 	}
 
 	if (urb->transfer_buffer == NULL) {
-		urb->transfer_buffer =
-		    kmalloc(URB_TRANSFER_BUFFER_SIZE, GFP_KERNEL);
+		urb->transfer_buffer = kmalloc(URB_TRANSFER_BUFFER_SIZE,
+					       GFP_ATOMIC);
 		if (!urb->transfer_buffer)
 			goto exit;
 	}
--- zfcpdump-kernel-4.4.orig/drivers/usb/serial/mxuport.c
+++ zfcpdump-kernel-4.4/drivers/usb/serial/mxuport.c
@@ -1259,6 +1259,15 @@ static int mxuport_attach(struct usb_ser
 	return 0;
 }
 
+static void mxuport_release(struct usb_serial *serial)
+{
+	struct usb_serial_port *port0 = serial->port[0];
+	struct usb_serial_port *port1 = serial->port[1];
+
+	usb_serial_generic_close(port1);
+	usb_serial_generic_close(port0);
+}
+
 static int mxuport_open(struct tty_struct *tty, struct usb_serial_port *port)
 {
 	struct mxuport_port *mxport = usb_get_serial_port_data(port);
@@ -1361,6 +1370,7 @@ static struct usb_serial_driver mxuport_
 	.probe			= mxuport_probe,
 	.port_probe		= mxuport_port_probe,
 	.attach			= mxuport_attach,
+	.release		= mxuport_release,
 	.calc_num_ports		= mxuport_calc_num_ports,
 	.open			= mxuport_open,
 	.close			= mxuport_close,
--- zfcpdump-kernel-4.4.orig/drivers/usb/serial/option.c
+++ zfcpdump-kernel-4.4/drivers/usb/serial/option.c
@@ -268,8 +268,18 @@ static void option_instat_callback(struc
 #define TELIT_PRODUCT_CC864_SINGLE		0x1006
 #define TELIT_PRODUCT_DE910_DUAL		0x1010
 #define TELIT_PRODUCT_UE910_V2			0x1012
+#define TELIT_PRODUCT_LE922_USBCFG0		0x1042
+#define TELIT_PRODUCT_LE922_USBCFG3		0x1043
+#define TELIT_PRODUCT_LE922_USBCFG5		0x1045
 #define TELIT_PRODUCT_LE920			0x1200
 #define TELIT_PRODUCT_LE910			0x1201
+#define TELIT_PRODUCT_LE910_USBCFG4		0x1206
+#define TELIT_PRODUCT_LE920A4_1207		0x1207
+#define TELIT_PRODUCT_LE920A4_1208		0x1208
+#define TELIT_PRODUCT_LE920A4_1211		0x1211
+#define TELIT_PRODUCT_LE920A4_1212		0x1212
+#define TELIT_PRODUCT_LE920A4_1213		0x1213
+#define TELIT_PRODUCT_LE920A4_1214		0x1214
 
 /* ZTE PRODUCTS */
 #define ZTE_VENDOR_ID				0x19d2
@@ -313,6 +323,7 @@ static void option_instat_callback(struc
 #define TOSHIBA_PRODUCT_G450			0x0d45
 
 #define ALINK_VENDOR_ID				0x1e0e
+#define SIMCOM_PRODUCT_SIM7100E			0x9001 /* Yes, ALINK_VENDOR_ID */
 #define ALINK_PRODUCT_PH300			0x9100
 #define ALINK_PRODUCT_3GU			0x9200
 
@@ -371,18 +382,22 @@ static void option_instat_callback(struc
 #define HAIER_PRODUCT_CE81B			0x10f8
 #define HAIER_PRODUCT_CE100			0x2009
 
-/* Cinterion (formerly Siemens) products */
-#define SIEMENS_VENDOR_ID				0x0681
-#define CINTERION_VENDOR_ID				0x1e2d
+/* Gemalto's Cinterion products (formerly Siemens) */
+#define SIEMENS_VENDOR_ID			0x0681
+#define CINTERION_VENDOR_ID			0x1e2d
+#define CINTERION_PRODUCT_HC25_MDMNET		0x0040
 #define CINTERION_PRODUCT_HC25_MDM		0x0047
-#define CINTERION_PRODUCT_HC25_MDMNET	0x0040
+#define CINTERION_PRODUCT_HC28_MDMNET		0x004A /* same for HC28J */
 #define CINTERION_PRODUCT_HC28_MDM		0x004C
-#define CINTERION_PRODUCT_HC28_MDMNET	0x004A /* same for HC28J */
 #define CINTERION_PRODUCT_EU3_E			0x0051
 #define CINTERION_PRODUCT_EU3_P			0x0052
 #define CINTERION_PRODUCT_PH8			0x0053
 #define CINTERION_PRODUCT_AHXX			0x0055
 #define CINTERION_PRODUCT_PLXX			0x0060
+#define CINTERION_PRODUCT_PH8_2RMNET		0x0082
+#define CINTERION_PRODUCT_PH8_AUDIO		0x0083
+#define CINTERION_PRODUCT_AHXX_2RMNET		0x0084
+#define CINTERION_PRODUCT_AHXX_AUDIO		0x0085
 
 /* Olivetti products */
 #define OLIVETTI_VENDOR_ID			0x0b3c
@@ -510,6 +525,12 @@ static void option_instat_callback(struc
 #define VIATELECOM_VENDOR_ID			0x15eb
 #define VIATELECOM_PRODUCT_CDS7			0x0001
 
+/* WeTelecom products */
+#define WETELECOM_VENDOR_ID			0x22de
+#define WETELECOM_PRODUCT_WMD200		0x6801
+#define WETELECOM_PRODUCT_6802			0x6802
+#define WETELECOM_PRODUCT_WMD300		0x6803
+
 struct option_blacklist_info {
 	/* bitmask of interface numbers blacklisted for send_setup */
 	const unsigned long sendsetup;
@@ -605,6 +626,10 @@ static const struct option_blacklist_inf
 	.reserved = BIT(3) | BIT(4),
 };
 
+static const struct option_blacklist_info simcom_sim7100e_blacklist = {
+	.reserved = BIT(5) | BIT(6),
+};
+
 static const struct option_blacklist_info telit_le910_blacklist = {
 	.sendsetup = BIT(0),
 	.reserved = BIT(1) | BIT(2),
@@ -615,6 +640,25 @@ static const struct option_blacklist_inf
 	.reserved = BIT(1) | BIT(5),
 };
 
+static const struct option_blacklist_info telit_le920a4_blacklist_1 = {
+	.sendsetup = BIT(0),
+	.reserved = BIT(1),
+};
+
+static const struct option_blacklist_info telit_le922_blacklist_usbcfg0 = {
+	.sendsetup = BIT(2),
+	.reserved = BIT(0) | BIT(1) | BIT(3),
+};
+
+static const struct option_blacklist_info telit_le922_blacklist_usbcfg3 = {
+	.sendsetup = BIT(0),
+	.reserved = BIT(1) | BIT(2) | BIT(3),
+};
+
+static const struct option_blacklist_info cinterion_rmnet2_blacklist = {
+	.reserved = BIT(4) | BIT(5),
+};
+
 static const struct usb_device_id option_ids[] = {
 	{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) },
 	{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA) },
@@ -1110,9 +1154,13 @@ static const struct usb_device_id option
 	{ USB_DEVICE(KYOCERA_VENDOR_ID, KYOCERA_PRODUCT_KPC650) },
 	{ USB_DEVICE(KYOCERA_VENDOR_ID, KYOCERA_PRODUCT_KPC680) },
 	{ USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6000)}, /* ZTE AC8700 */
+	{ USB_DEVICE_AND_INTERFACE_INFO(QUALCOMM_VENDOR_ID, 0x6001, 0xff, 0xff, 0xff), /* 4G LTE usb-modem U901 */
+	  .driver_info = (kernel_ulong_t)&net_intf3_blacklist },
 	{ USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6613)}, /* Onda H600/ZTE MF330 */
 	{ USB_DEVICE(QUALCOMM_VENDOR_ID, 0x0023)}, /* ONYX 3G device */
 	{ USB_DEVICE(QUALCOMM_VENDOR_ID, 0x9000)}, /* SIMCom SIM5218 */
+	{ USB_DEVICE(QUALCOMM_VENDOR_ID, 0x9003), /* Quectel UC20 */
+	  .driver_info = (kernel_ulong_t)&net_intf4_blacklist },
 	{ USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6001) },
 	{ USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CMU_300) },
 	{ USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6003),
@@ -1160,10 +1208,28 @@ static const struct usb_device_id option
 	{ USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_CC864_SINGLE) },
 	{ USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_DE910_DUAL) },
 	{ USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_UE910_V2) },
+	{ USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE922_USBCFG0),
+		.driver_info = (kernel_ulong_t)&telit_le922_blacklist_usbcfg0 },
+	{ USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE922_USBCFG3),
+		.driver_info = (kernel_ulong_t)&telit_le922_blacklist_usbcfg3 },
+	{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, TELIT_PRODUCT_LE922_USBCFG5, 0xff),
+		.driver_info = (kernel_ulong_t)&telit_le922_blacklist_usbcfg0 },
 	{ USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE910),
 		.driver_info = (kernel_ulong_t)&telit_le910_blacklist },
+	{ USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE910_USBCFG4),
+		.driver_info = (kernel_ulong_t)&telit_le922_blacklist_usbcfg3 },
 	{ USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE920),
 		.driver_info = (kernel_ulong_t)&telit_le920_blacklist },
+	{ USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE920A4_1207) },
+	{ USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE920A4_1208),
+		.driver_info = (kernel_ulong_t)&telit_le920a4_blacklist_1 },
+	{ USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE920A4_1211),
+		.driver_info = (kernel_ulong_t)&telit_le922_blacklist_usbcfg3 },
+	{ USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE920A4_1212),
+		.driver_info = (kernel_ulong_t)&telit_le920a4_blacklist_1 },
+	{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, TELIT_PRODUCT_LE920A4_1213, 0xff) },
+	{ USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE920A4_1214),
+		.driver_info = (kernel_ulong_t)&telit_le922_blacklist_usbcfg3 },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MF622, 0xff, 0xff, 0xff) }, /* ZTE WCDMA products */
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0002, 0xff, 0xff, 0xff),
 		.driver_info = (kernel_ulong_t)&net_intf1_blacklist },
@@ -1574,7 +1640,79 @@ static const struct usb_device_id option
 		.driver_info = (kernel_ulong_t)&net_intf3_blacklist },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0178, 0xff, 0xff, 0xff),
 		.driver_info = (kernel_ulong_t)&net_intf3_blacklist },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffe9, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff42, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff43, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff44, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff45, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff46, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff47, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff48, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff49, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff4a, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff4b, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff4c, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff4d, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff4e, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff4f, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff50, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff51, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff52, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff53, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff54, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff55, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff56, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff57, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff58, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff59, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff5a, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff5b, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff5c, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff5d, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff5e, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff5f, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff60, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff61, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff62, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff63, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff64, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff65, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff66, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff67, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff68, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff69, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff6a, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff6b, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff6c, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff6d, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff6e, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff6f, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff70, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff71, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff72, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff73, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff74, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff75, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff76, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff77, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff78, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff79, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff7a, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff7b, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff7c, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff7d, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff7e, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff7f, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff80, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff81, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff82, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff83, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff84, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff85, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff86, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff87, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff88, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff89, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff8a, 0xff, 0xff, 0xff) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff8b, 0xff, 0xff, 0xff) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff8c, 0xff, 0xff, 0xff) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff8d, 0xff, 0xff, 0xff) },
@@ -1585,6 +1723,61 @@ static const struct usb_device_id option
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff92, 0xff, 0xff, 0xff) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff93, 0xff, 0xff, 0xff) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff94, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff9f, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffa0, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffa1, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffa2, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffa3, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffa4, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffa5, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffa6, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffa7, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffa8, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffa9, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffaa, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffab, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffac, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffae, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffaf, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffb0, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffb1, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffb2, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffb3, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffb4, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffb5, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffb6, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffb7, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffb8, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffb9, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffba, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffbb, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffbc, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffbd, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffbe, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffbf, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffc0, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffc1, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffc2, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffc3, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffc4, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffc5, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffc6, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffc7, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffc8, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffc9, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffca, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffcb, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffcc, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffcd, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffce, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffcf, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffd0, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffd1, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffd2, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffd3, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffd4, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffd5, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffe9, 0xff, 0xff, 0xff) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffec, 0xff, 0xff, 0xff) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffee, 0xff, 0xff, 0xff) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xfff6, 0xff, 0xff, 0xff) },
@@ -1629,6 +1822,8 @@ static const struct usb_device_id option
 	{ USB_DEVICE(ALINK_VENDOR_ID, 0x9000) },
 	{ USB_DEVICE(ALINK_VENDOR_ID, ALINK_PRODUCT_PH300) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ALINK_VENDOR_ID, ALINK_PRODUCT_3GU, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE(ALINK_VENDOR_ID, SIMCOM_PRODUCT_SIM7100E),
+	  .driver_info = (kernel_ulong_t)&simcom_sim7100e_blacklist },
 	{ USB_DEVICE(ALCATEL_VENDOR_ID, ALCATEL_PRODUCT_X060S_X200),
 	  .driver_info = (kernel_ulong_t)&alcatel_x200_blacklist
 	},
@@ -1679,10 +1874,16 @@ static const struct usb_device_id option
 	{ USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_EU3_P) },
 	{ USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_PH8),
 		.driver_info = (kernel_ulong_t)&net_intf4_blacklist },
-	{ USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_AHXX) },
+	{ USB_DEVICE_INTERFACE_CLASS(CINTERION_VENDOR_ID, CINTERION_PRODUCT_AHXX, 0xff) },
 	{ USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_PLXX),
 		.driver_info = (kernel_ulong_t)&net_intf4_blacklist },
-	{ USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_HC28_MDM) }, 
+	{ USB_DEVICE_INTERFACE_CLASS(CINTERION_VENDOR_ID, CINTERION_PRODUCT_PH8_2RMNET, 0xff),
+		.driver_info = (kernel_ulong_t)&cinterion_rmnet2_blacklist },
+	{ USB_DEVICE_INTERFACE_CLASS(CINTERION_VENDOR_ID, CINTERION_PRODUCT_PH8_AUDIO, 0xff),
+		.driver_info = (kernel_ulong_t)&net_intf4_blacklist },
+	{ USB_DEVICE_INTERFACE_CLASS(CINTERION_VENDOR_ID, CINTERION_PRODUCT_AHXX_2RMNET, 0xff) },
+	{ USB_DEVICE_INTERFACE_CLASS(CINTERION_VENDOR_ID, CINTERION_PRODUCT_AHXX_AUDIO, 0xff) },
+	{ USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_HC28_MDM) },
 	{ USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_HC28_MDMNET) },
 	{ USB_DEVICE(SIEMENS_VENDOR_ID, CINTERION_PRODUCT_HC25_MDM) },
 	{ USB_DEVICE(SIEMENS_VENDOR_ID, CINTERION_PRODUCT_HC25_MDMNET) },
@@ -1788,11 +1989,17 @@ static const struct usb_device_id option
 	{ USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x7d02, 0xff, 0x00, 0x00) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x7d03, 0xff, 0x02, 0x01) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x7d03, 0xff, 0x00, 0x00) },
+	{ USB_DEVICE_INTERFACE_CLASS(0x2001, 0x7e19, 0xff),			/* D-Link DWM-221 B1 */
+	  .driver_info = (kernel_ulong_t)&net_intf4_blacklist },
 	{ USB_DEVICE_AND_INTERFACE_INFO(0x07d1, 0x3e01, 0xff, 0xff, 0xff) }, /* D-Link DWM-152/C1 */
 	{ USB_DEVICE_AND_INTERFACE_INFO(0x07d1, 0x3e02, 0xff, 0xff, 0xff) }, /* D-Link DWM-156/C1 */
+	{ USB_DEVICE_AND_INTERFACE_INFO(0x07d1, 0x7e11, 0xff, 0xff, 0xff) }, /* D-Link DWM-156/A3 */
 	{ USB_DEVICE_INTERFACE_CLASS(0x2020, 0x4000, 0xff) },                /* OLICARD300 - MT6225 */
 	{ USB_DEVICE(INOVIA_VENDOR_ID, INOVIA_SEW858) },
 	{ USB_DEVICE(VIATELECOM_VENDOR_ID, VIATELECOM_PRODUCT_CDS7) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(WETELECOM_VENDOR_ID, WETELECOM_PRODUCT_WMD200, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(WETELECOM_VENDOR_ID, WETELECOM_PRODUCT_6802, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(WETELECOM_VENDOR_ID, WETELECOM_PRODUCT_WMD300, 0xff, 0xff, 0xff) },
 	{ } /* Terminating entry */
 };
 MODULE_DEVICE_TABLE(usb, option_ids);
--- zfcpdump-kernel-4.4.orig/drivers/usb/serial/qcserial.c
+++ zfcpdump-kernel-4.4/drivers/usb/serial/qcserial.c
@@ -157,14 +157,17 @@ static const struct usb_device_id id_tab
 	{DEVICE_SWI(0x1199, 0x9056)},	/* Sierra Wireless Modem */
 	{DEVICE_SWI(0x1199, 0x9060)},	/* Sierra Wireless Modem */
 	{DEVICE_SWI(0x1199, 0x9061)},	/* Sierra Wireless Modem */
-	{DEVICE_SWI(0x1199, 0x9070)},	/* Sierra Wireless MC74xx/EM74xx */
-	{DEVICE_SWI(0x1199, 0x9071)},	/* Sierra Wireless MC74xx/EM74xx */
+	{DEVICE_SWI(0x1199, 0x9070)},	/* Sierra Wireless MC74xx */
+	{DEVICE_SWI(0x1199, 0x9071)},	/* Sierra Wireless MC74xx */
+	{DEVICE_SWI(0x1199, 0x9078)},	/* Sierra Wireless EM74xx */
+	{DEVICE_SWI(0x1199, 0x9079)},	/* Sierra Wireless EM74xx */
 	{DEVICE_SWI(0x413c, 0x81a2)},	/* Dell Wireless 5806 Gobi(TM) 4G LTE Mobile Broadband Card */
 	{DEVICE_SWI(0x413c, 0x81a3)},	/* Dell Wireless 5570 HSPA+ (42Mbps) Mobile Broadband Card */
 	{DEVICE_SWI(0x413c, 0x81a4)},	/* Dell Wireless 5570e HSPA+ (42Mbps) Mobile Broadband Card */
 	{DEVICE_SWI(0x413c, 0x81a8)},	/* Dell Wireless 5808 Gobi(TM) 4G LTE Mobile Broadband Card */
 	{DEVICE_SWI(0x413c, 0x81a9)},	/* Dell Wireless 5808e Gobi(TM) 4G LTE Mobile Broadband Card */
 	{DEVICE_SWI(0x413c, 0x81b1)},	/* Dell Wireless 5809e Gobi(TM) 4G LTE Mobile Broadband Card */
+	{DEVICE_SWI(0x413c, 0x81b3)},	/* Dell Wireless 5809e Gobi(TM) 4G LTE Mobile Broadband Card (rev3) */
 
 	/* Huawei devices */
 	{DEVICE_HWI(0x03f0, 0x581d)},	/* HP lt4112 LTE/HSPA+ Gobi 4G Modem (Huawei me906e) */
--- zfcpdump-kernel-4.4.orig/drivers/usb/serial/quatech2.c
+++ zfcpdump-kernel-4.4/drivers/usb/serial/quatech2.c
@@ -141,6 +141,7 @@ static void qt2_release(struct usb_seria
 
 	serial_priv = usb_get_serial_data(serial);
 
+	usb_kill_urb(serial_priv->read_urb);
 	usb_free_urb(serial_priv->read_urb);
 	kfree(serial_priv->read_buffer);
 	kfree(serial_priv);
--- zfcpdump-kernel-4.4.orig/drivers/usb/serial/usb-serial-simple.c
+++ zfcpdump-kernel-4.4/drivers/usb/serial/usb-serial-simple.c
@@ -54,7 +54,8 @@ DEVICE(funsoft, FUNSOFT_IDS);
 /* Infineon Flashloader driver */
 #define FLASHLOADER_IDS()		\
 	{ USB_DEVICE_INTERFACE_CLASS(0x058b, 0x0041, USB_CLASS_CDC_DATA) }, \
-	{ USB_DEVICE(0x8087, 0x0716) }
+	{ USB_DEVICE(0x8087, 0x0716) }, \
+	{ USB_DEVICE(0x8087, 0x0801) }
 DEVICE(flashloader, FLASHLOADER_IDS);
 
 /* Google Serial USB SubClass */
--- zfcpdump-kernel-4.4.orig/drivers/usb/serial/usb-serial.c
+++ zfcpdump-kernel-4.4/drivers/usb/serial/usb-serial.c
@@ -1432,7 +1432,7 @@ int usb_serial_register_drivers(struct u
 
 	rc = usb_register(udriver);
 	if (rc)
-		return rc;
+		goto failed_usb_register;
 
 	for (sd = serial_drivers; *sd; ++sd) {
 		(*sd)->usb_driver = udriver;
@@ -1450,6 +1450,8 @@ int usb_serial_register_drivers(struct u
 	while (sd-- > serial_drivers)
 		usb_serial_deregister(*sd);
 	usb_deregister(udriver);
+failed_usb_register:
+	kfree(udriver);
 	return rc;
 }
 EXPORT_SYMBOL_GPL(usb_serial_register_drivers);
--- zfcpdump-kernel-4.4.orig/drivers/usb/serial/visor.c
+++ zfcpdump-kernel-4.4/drivers/usb/serial/visor.c
@@ -544,6 +544,11 @@ static int treo_attach(struct usb_serial
 		(serial->num_interrupt_in == 0))
 		return 0;
 
+	if (serial->num_bulk_in < 2 || serial->num_interrupt_in < 2) {
+		dev_err(&serial->interface->dev, "missing endpoints\n");
+		return -ENODEV;
+	}
+
 	/*
 	* It appears that Treos and Kyoceras want to use the
 	* 1st bulk in endpoint to communicate with the 2nd bulk out endpoint,
@@ -597,8 +602,10 @@ static int clie_5_attach(struct usb_seri
 	 */
 
 	/* some sanity check */
-	if (serial->num_ports < 2)
-		return -1;
+	if (serial->num_bulk_out < 2) {
+		dev_err(&serial->interface->dev, "missing bulk out endpoints\n");
+		return -ENODEV;
+	}
 
 	/* port 0 now uses the modified endpoint Address */
 	port = serial->port[0];
--- zfcpdump-kernel-4.4.orig/drivers/usb/storage/uas.c
+++ zfcpdump-kernel-4.4/drivers/usb/storage/uas.c
@@ -2,7 +2,7 @@
  * USB Attached SCSI
  * Note that this is not the same as the USB Mass Storage driver
  *
- * Copyright Hans de Goede <hdegoede@redhat.com> for Red Hat, Inc. 2013 - 2014
+ * Copyright Hans de Goede <hdegoede@redhat.com> for Red Hat, Inc. 2013 - 2016
  * Copyright Matthew Wilcox for Intel Corp, 2010
  * Copyright Sarah Sharp for Intel Corp, 2010
  *
@@ -757,6 +757,17 @@ static int uas_eh_bus_reset_handler(stru
 	return SUCCESS;
 }
 
+static int uas_target_alloc(struct scsi_target *starget)
+{
+	struct uas_dev_info *devinfo = (struct uas_dev_info *)
+			dev_to_shost(starget->dev.parent)->hostdata;
+
+	if (devinfo->flags & US_FL_NO_REPORT_LUNS)
+		starget->no_report_luns = 1;
+
+	return 0;
+}
+
 static int uas_slave_alloc(struct scsi_device *sdev)
 {
 	struct uas_dev_info *devinfo =
@@ -808,11 +819,12 @@ static struct scsi_host_template uas_hos
 	.module = THIS_MODULE,
 	.name = "uas",
 	.queuecommand = uas_queuecommand,
+	.target_alloc = uas_target_alloc,
 	.slave_alloc = uas_slave_alloc,
 	.slave_configure = uas_slave_configure,
 	.eh_abort_handler = uas_eh_abort_handler,
 	.eh_bus_reset_handler = uas_eh_bus_reset_handler,
-	.can_queue = 65536,	/* Is there a limit on the _host_ ? */
+	.can_queue = MAX_CMNDS,
 	.this_id = -1,
 	.sg_tablesize = SG_NONE,
 	.skip_settle_delay = 1,
@@ -932,6 +944,12 @@ static int uas_probe(struct usb_interfac
 	if (result)
 		goto set_alt0;
 
+	/*
+	 * 1 tag is reserved for untagged commands +
+	 * 1 tag to avoid off by one errors in some bridge firmwares
+	 */
+	shost->can_queue = devinfo->qdepth - 2;
+
 	usb_set_intfdata(intf, shost);
 	result = scsi_add_host(shost, &intf->dev);
 	if (result)
--- zfcpdump-kernel-4.4.orig/drivers/usb/storage/unusual_devs.h
+++ zfcpdump-kernel-4.4/drivers/usb/storage/unusual_devs.h
@@ -1262,6 +1262,13 @@ UNUSUAL_DEV(  0x0af0, 0x6971, 0x0000, 0x
 		USB_SC_DEVICE, USB_PR_DEVICE, option_ms_init,
 		0),
 
+/* Reported by Timo Aaltonen <tjaalton@ubuntu.com> */
+UNUSUAL_DEV( 0x0af0, 0x7011, 0x0000, 0x9999,
+		"Option",
+		"Mass Storage",
+		USB_SC_DEVICE, USB_PR_DEVICE, option_ms_init,
+		0 ),
+
 /* Reported by F. Aben <f.aben@option.com>
  * This device (wrongly) has a vendor-specific device descriptor.
  * The entry is needed so usb-storage can bind to it's mass-storage
--- zfcpdump-kernel-4.4.orig/drivers/usb/storage/unusual_uas.h
+++ zfcpdump-kernel-4.4/drivers/usb/storage/unusual_uas.h
@@ -64,6 +64,13 @@ UNUSUAL_DEV(0x0bc2, 0x3312, 0x0000, 0x99
 		USB_SC_DEVICE, USB_PR_DEVICE, NULL,
 		US_FL_NO_ATA_1X),
 
+/* Reported-by: David Webb <djw@noc.ac.uk> */
+UNUSUAL_DEV(0x0bc2, 0x331a, 0x0000, 0x9999,
+		"Seagate",
+		"Expansion Desk",
+		USB_SC_DEVICE, USB_PR_DEVICE, NULL,
+		US_FL_NO_REPORT_LUNS),
+
 /* Reported-by: Hans de Goede <hdegoede@redhat.com> */
 UNUSUAL_DEV(0x0bc2, 0x3320, 0x0000, 0x9999,
 		"Seagate",
--- zfcpdump-kernel-4.4.orig/drivers/usb/storage/usb.c
+++ zfcpdump-kernel-4.4/drivers/usb/storage/usb.c
@@ -482,7 +482,7 @@ void usb_stor_adjust_quirks(struct usb_d
 			US_FL_NO_READ_DISC_INFO | US_FL_NO_READ_CAPACITY_16 |
 			US_FL_INITIAL_READ10 | US_FL_WRITE_CACHE |
 			US_FL_NO_ATA_1X | US_FL_NO_REPORT_OPCODES |
-			US_FL_MAX_SECTORS_240);
+			US_FL_MAX_SECTORS_240 | US_FL_NO_REPORT_LUNS);
 
 	p = quirks;
 	while (*p) {
@@ -532,6 +532,9 @@ void usb_stor_adjust_quirks(struct usb_d
 		case 'i':
 			f |= US_FL_IGNORE_DEVICE;
 			break;
+		case 'j':
+			f |= US_FL_NO_REPORT_LUNS;
+			break;
 		case 'l':
 			f |= US_FL_NOT_LOCKABLE;
 			break;
--- zfcpdump-kernel-4.4.orig/drivers/usb/usbip/usbip_common.c
+++ zfcpdump-kernel-4.4/drivers/usb/usbip/usbip_common.c
@@ -741,6 +741,17 @@ int usbip_recv_xbuff(struct usbip_device
 	if (!(size > 0))
 		return 0;
 
+	if (size > urb->transfer_buffer_length) {
+		/* should not happen, probably malicious packet */
+		if (ud->side == USBIP_STUB) {
+			usbip_event_add(ud, SDEV_EVENT_ERROR_TCP);
+			return 0;
+		} else {
+			usbip_event_add(ud, VDEV_EVENT_ERROR_TCP);
+			return -EPIPE;
+		}
+	}
+
 	ret = usbip_recv(ud->tcp_socket, urb->transfer_buffer, size);
 	if (ret != size) {
 		dev_err(&urb->dev->dev, "recv xbuf, %d\n", ret);
--- zfcpdump-kernel-4.4.orig/drivers/vfio/pci/vfio_pci.c
+++ zfcpdump-kernel-4.4/drivers/vfio/pci/vfio_pci.c
@@ -446,7 +446,8 @@ static long vfio_pci_ioctl(void *device_
 		info.num_regions = VFIO_PCI_NUM_REGIONS;
 		info.num_irqs = VFIO_PCI_NUM_IRQS;
 
-		return copy_to_user((void __user *)arg, &info, minsz);
+		return copy_to_user((void __user *)arg, &info, minsz) ?
+			-EFAULT : 0;
 
 	} else if (cmd == VFIO_DEVICE_GET_REGION_INFO) {
 		struct pci_dev *pdev = vdev->pdev;
@@ -520,7 +521,8 @@ static long vfio_pci_ioctl(void *device_
 			return -EINVAL;
 		}
 
-		return copy_to_user((void __user *)arg, &info, minsz);
+		return copy_to_user((void __user *)arg, &info, minsz) ?
+			-EFAULT : 0;
 
 	} else if (cmd == VFIO_DEVICE_GET_IRQ_INFO) {
 		struct vfio_irq_info info;
@@ -555,7 +557,8 @@ static long vfio_pci_ioctl(void *device_
 		else
 			info.flags |= VFIO_IRQ_INFO_NORESIZE;
 
-		return copy_to_user((void __user *)arg, &info, minsz);
+		return copy_to_user((void __user *)arg, &info, minsz) ?
+			-EFAULT : 0;
 
 	} else if (cmd == VFIO_DEVICE_SET_IRQS) {
 		struct vfio_irq_set hdr;
--- zfcpdump-kernel-4.4.orig/drivers/vfio/pci/vfio_pci_intrs.c
+++ zfcpdump-kernel-4.4/drivers/vfio/pci/vfio_pci_intrs.c
@@ -563,67 +563,80 @@ static int vfio_pci_set_msi_trigger(stru
 }
 
 static int vfio_pci_set_ctx_trigger_single(struct eventfd_ctx **ctx,
-					   uint32_t flags, void *data)
+					   unsigned int count, uint32_t flags,
+					   void *data)
 {
-	int32_t fd = *(int32_t *)data;
-
-	if (!(flags & VFIO_IRQ_SET_DATA_TYPE_MASK))
-		return -EINVAL;
-
 	/* DATA_NONE/DATA_BOOL enables loopback testing */
 	if (flags & VFIO_IRQ_SET_DATA_NONE) {
-		if (*ctx)
-			eventfd_signal(*ctx, 1);
-		return 0;
+		if (*ctx) {
+			if (count) {
+				eventfd_signal(*ctx, 1);
+			} else {
+				eventfd_ctx_put(*ctx);
+				*ctx = NULL;
+			}
+			return 0;
+		}
 	} else if (flags & VFIO_IRQ_SET_DATA_BOOL) {
-		uint8_t trigger = *(uint8_t *)data;
+		uint8_t trigger;
+
+		if (!count)
+			return -EINVAL;
+
+		trigger = *(uint8_t *)data;
 		if (trigger && *ctx)
 			eventfd_signal(*ctx, 1);
-		return 0;
-	}
 
-	/* Handle SET_DATA_EVENTFD */
-	if (fd == -1) {
-		if (*ctx)
-			eventfd_ctx_put(*ctx);
-		*ctx = NULL;
 		return 0;
-	} else if (fd >= 0) {
-		struct eventfd_ctx *efdctx;
-		efdctx = eventfd_ctx_fdget(fd);
-		if (IS_ERR(efdctx))
-			return PTR_ERR(efdctx);
-		if (*ctx)
-			eventfd_ctx_put(*ctx);
-		*ctx = efdctx;
+	} else if (flags & VFIO_IRQ_SET_DATA_EVENTFD) {
+		int32_t fd;
+
+		if (!count)
+			return -EINVAL;
+
+		fd = *(int32_t *)data;
+		if (fd == -1) {
+			if (*ctx)
+				eventfd_ctx_put(*ctx);
+			*ctx = NULL;
+		} else if (fd >= 0) {
+			struct eventfd_ctx *efdctx;
+
+			efdctx = eventfd_ctx_fdget(fd);
+			if (IS_ERR(efdctx))
+				return PTR_ERR(efdctx);
+
+			if (*ctx)
+				eventfd_ctx_put(*ctx);
+
+			*ctx = efdctx;
+		}
 		return 0;
-	} else
-		return -EINVAL;
+	}
+
+	return -EINVAL;
 }
 
 static int vfio_pci_set_err_trigger(struct vfio_pci_device *vdev,
 				    unsigned index, unsigned start,
 				    unsigned count, uint32_t flags, void *data)
 {
-	if (index != VFIO_PCI_ERR_IRQ_INDEX)
+	if (index != VFIO_PCI_ERR_IRQ_INDEX || start != 0 || count > 1)
 		return -EINVAL;
 
-	/*
-	 * We should sanitize start & count, but that wasn't caught
-	 * originally, so this IRQ index must forever ignore them :-(
-	 */
-
-	return vfio_pci_set_ctx_trigger_single(&vdev->err_trigger, flags, data);
+	return vfio_pci_set_ctx_trigger_single(&vdev->err_trigger,
+					       count, flags, data);
 }
 
 static int vfio_pci_set_req_trigger(struct vfio_pci_device *vdev,
 				    unsigned index, unsigned start,
 				    unsigned count, uint32_t flags, void *data)
 {
-	if (index != VFIO_PCI_REQ_IRQ_INDEX || start != 0 || count != 1)
+	if (index != VFIO_PCI_REQ_IRQ_INDEX || start != 0 || count > 1)
 		return -EINVAL;
 
-	return vfio_pci_set_ctx_trigger_single(&vdev->req_trigger, flags, data);
+	return vfio_pci_set_ctx_trigger_single(&vdev->req_trigger,
+					       count, flags, data);
 }
 
 int vfio_pci_set_irqs_ioctl(struct vfio_pci_device *vdev, uint32_t flags,
--- zfcpdump-kernel-4.4.orig/drivers/vfio/platform/vfio_platform_common.c
+++ zfcpdump-kernel-4.4/drivers/vfio/platform/vfio_platform_common.c
@@ -219,7 +219,8 @@ static long vfio_platform_ioctl(void *de
 		info.num_regions = vdev->num_regions;
 		info.num_irqs = vdev->num_irqs;
 
-		return copy_to_user((void __user *)arg, &info, minsz);
+		return copy_to_user((void __user *)arg, &info, minsz) ?
+			-EFAULT : 0;
 
 	} else if (cmd == VFIO_DEVICE_GET_REGION_INFO) {
 		struct vfio_region_info info;
@@ -240,7 +241,8 @@ static long vfio_platform_ioctl(void *de
 		info.size = vdev->regions[info.index].size;
 		info.flags = vdev->regions[info.index].flags;
 
-		return copy_to_user((void __user *)arg, &info, minsz);
+		return copy_to_user((void __user *)arg, &info, minsz) ?
+			-EFAULT : 0;
 
 	} else if (cmd == VFIO_DEVICE_GET_IRQ_INFO) {
 		struct vfio_irq_info info;
@@ -259,7 +261,8 @@ static long vfio_platform_ioctl(void *de
 		info.flags = vdev->irqs[info.index].flags;
 		info.count = vdev->irqs[info.index].count;
 
-		return copy_to_user((void __user *)arg, &info, minsz);
+		return copy_to_user((void __user *)arg, &info, minsz) ?
+			-EFAULT : 0;
 
 	} else if (cmd == VFIO_DEVICE_SET_IRQS) {
 		struct vfio_irq_set hdr;
--- zfcpdump-kernel-4.4.orig/drivers/vfio/vfio_iommu_type1.c
+++ zfcpdump-kernel-4.4/drivers/vfio/vfio_iommu_type1.c
@@ -999,7 +999,8 @@ static long vfio_iommu_type1_ioctl(void
 
 		info.iova_pgsizes = vfio_pgsize_bitmap(iommu);
 
-		return copy_to_user((void __user *)arg, &info, minsz);
+		return copy_to_user((void __user *)arg, &info, minsz) ?
+			-EFAULT : 0;
 
 	} else if (cmd == VFIO_IOMMU_MAP_DMA) {
 		struct vfio_iommu_type1_dma_map map;
@@ -1032,7 +1033,8 @@ static long vfio_iommu_type1_ioctl(void
 		if (ret)
 			return ret;
 
-		return copy_to_user((void __user *)arg, &unmap, minsz);
+		return copy_to_user((void __user *)arg, &unmap, minsz) ?
+			-EFAULT : 0;
 	}
 
 	return -ENOTTY;
--- zfcpdump-kernel-4.4.orig/drivers/vhost/scsi.c
+++ zfcpdump-kernel-4.4/drivers/vhost/scsi.c
@@ -88,7 +88,7 @@ struct vhost_scsi_cmd {
 	struct scatterlist *tvc_prot_sgl;
 	struct page **tvc_upages;
 	/* Pointer to response header iovec */
-	struct iovec *tvc_resp_iov;
+	struct iovec tvc_resp_iov;
 	/* Pointer to vhost_scsi for our device */
 	struct vhost_scsi *tvc_vhost;
 	/* Pointer to vhost_virtqueue for the cmd */
@@ -557,7 +557,7 @@ static void vhost_scsi_complete_cmd_work
 		memcpy(v_rsp.sense, cmd->tvc_sense_buf,
 		       se_cmd->scsi_sense_length);
 
-		iov_iter_init(&iov_iter, READ, cmd->tvc_resp_iov,
+		iov_iter_init(&iov_iter, READ, &cmd->tvc_resp_iov,
 			      cmd->tvc_in_iovs, sizeof(v_rsp));
 		ret = copy_to_iter(&v_rsp, sizeof(v_rsp), &iov_iter);
 		if (likely(ret == sizeof(v_rsp))) {
@@ -1054,7 +1054,7 @@ vhost_scsi_handle_vq(struct vhost_scsi *
 		}
 		cmd->tvc_vhost = vs;
 		cmd->tvc_vq = vq;
-		cmd->tvc_resp_iov = &vq->iov[out];
+		cmd->tvc_resp_iov = vq->iov[out];
 		cmd->tvc_in_iovs = in;
 
 		pr_debug("vhost_scsi got command opcode: %#02x, lun: %d\n",
--- zfcpdump-kernel-4.4.orig/drivers/video/console/fbcon.c
+++ zfcpdump-kernel-4.4/drivers/video/console/fbcon.c
@@ -709,6 +709,7 @@ static int con2fb_acquire_newinfo(struct
 	}
 
 	if (!err) {
+		ops->cur_blink_jiffies = HZ / 5;
 		info->fbcon_par = ops;
 
 		if (vc)
@@ -956,6 +957,7 @@ static const char *fbcon_startup(void)
 	ops->currcon = -1;
 	ops->graphics = 1;
 	ops->cur_rotate = -1;
+	ops->cur_blink_jiffies = HZ / 5;
 	info->fbcon_par = ops;
 	p->con_rotate = initial_rotation;
 	set_blitting_type(vc, info);
--- zfcpdump-kernel-4.4.orig/drivers/video/fbdev/Kconfig
+++ zfcpdump-kernel-4.4/drivers/video/fbdev/Kconfig
@@ -2249,7 +2249,6 @@ config XEN_FBDEV_FRONTEND
 	select FB_SYS_IMAGEBLIT
 	select FB_SYS_FOPS
 	select FB_DEFERRED_IO
-	select INPUT_XEN_KBDDEV_FRONTEND if INPUT_MISC
 	select XEN_XENBUS_FRONTEND
 	default y
 	help
--- zfcpdump-kernel-4.4.orig/drivers/video/fbdev/da8xx-fb.c
+++ zfcpdump-kernel-4.4/drivers/video/fbdev/da8xx-fb.c
@@ -209,8 +209,7 @@ static struct fb_videomode known_lcd_pan
 		.lower_margin   = 2,
 		.hsync_len      = 0,
 		.vsync_len      = 0,
-		.sync           = FB_SYNC_CLK_INVERT |
-			FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+		.sync           = FB_SYNC_CLK_INVERT,
 	},
 	/* Sharp LK043T1DG01 */
 	[1] = {
@@ -224,7 +223,7 @@ static struct fb_videomode known_lcd_pan
 		.lower_margin   = 2,
 		.hsync_len      = 41,
 		.vsync_len      = 10,
-		.sync           = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+		.sync           = 0,
 		.flag           = 0,
 	},
 	[2] = {
@@ -239,7 +238,7 @@ static struct fb_videomode known_lcd_pan
 		.lower_margin   = 10,
 		.hsync_len      = 10,
 		.vsync_len      = 10,
-		.sync           = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+		.sync           = 0,
 		.flag           = 0,
 	},
 	[3] = {
--- zfcpdump-kernel-4.4.orig/drivers/video/fbdev/hyperv_fb.c
+++ zfcpdump-kernel-4.4/drivers/video/fbdev/hyperv_fb.c
@@ -743,7 +743,7 @@ static int hvfb_getmem(struct hv_device
 err3:
 	iounmap(fb_virt);
 err2:
-	release_mem_region(par->mem->start, screen_fb_size);
+	vmbus_free_mmio(par->mem->start, screen_fb_size);
 	par->mem = NULL;
 err1:
 	if (!gen2vm)
@@ -758,7 +758,7 @@ static void hvfb_putmem(struct fb_info *
 	struct hvfb_par *par = info->par;
 
 	iounmap(info->screen_base);
-	release_mem_region(par->mem->start, screen_fb_size);
+	vmbus_free_mmio(par->mem->start, screen_fb_size);
 	par->mem = NULL;
 }
 
--- zfcpdump-kernel-4.4.orig/drivers/video/fbdev/vesafb.c
+++ zfcpdump-kernel-4.4/drivers/video/fbdev/vesafb.c
@@ -51,7 +51,7 @@ static struct fb_fix_screeninfo vesafb_f
 };
 
 static int   inverse    __read_mostly;
-static int   mtrr       __read_mostly;		/* disable mtrr */
+static int   mtrr       __read_mostly = 3;	/* enable mtrr write-comb. */
 static int   vram_remap;			/* Set amount of memory to be used */
 static int   vram_total;			/* Set total amount of memory */
 static int   pmi_setpal __read_mostly = 1;	/* pmi for palette changes ??? */
--- zfcpdump-kernel-4.4.orig/drivers/virtio/virtio_balloon.c
+++ zfcpdump-kernel-4.4/drivers/virtio/virtio_balloon.c
@@ -30,6 +30,7 @@
 #include <linux/balloon_compaction.h>
 #include <linux/oom.h>
 #include <linux/wait.h>
+#include <linux/mm.h>
 
 /*
  * Balloon device works in 4K page units.  So each page is pointed to by
@@ -73,7 +74,7 @@ struct virtio_balloon {
 
 	/* The array of pfns we tell the Host about. */
 	unsigned int num_pfns;
-	u32 pfns[VIRTIO_BALLOON_ARRAY_PFNS_MAX];
+	__virtio32 pfns[VIRTIO_BALLOON_ARRAY_PFNS_MAX];
 
 	/* Memory statistics */
 	int need_stats_update;
@@ -125,14 +126,16 @@ static void tell_host(struct virtio_ball
 	wait_event(vb->acked, virtqueue_get_buf(vq, &len));
 }
 
-static void set_page_pfns(u32 pfns[], struct page *page)
+static void set_page_pfns(struct virtio_balloon *vb,
+			  __virtio32 pfns[], struct page *page)
 {
 	unsigned int i;
 
 	/* Set balloon pfns pointing at this page.
 	 * Note that the first pfn points at start of the page. */
 	for (i = 0; i < VIRTIO_BALLOON_PAGES_PER_PAGE; i++)
-		pfns[i] = page_to_balloon_pfn(page) + i;
+		pfns[i] = cpu_to_virtio32(vb->vdev,
+					  page_to_balloon_pfn(page) + i);
 }
 
 static void fill_balloon(struct virtio_balloon *vb, size_t num)
@@ -155,7 +158,7 @@ static void fill_balloon(struct virtio_b
 			msleep(200);
 			break;
 		}
-		set_page_pfns(vb->pfns + vb->num_pfns, page);
+		set_page_pfns(vb, vb->pfns + vb->num_pfns, page);
 		vb->num_pages += VIRTIO_BALLOON_PAGES_PER_PAGE;
 		if (!virtio_has_feature(vb->vdev,
 					VIRTIO_BALLOON_F_DEFLATE_ON_OOM))
@@ -171,10 +174,12 @@ static void fill_balloon(struct virtio_b
 static void release_pages_balloon(struct virtio_balloon *vb)
 {
 	unsigned int i;
+	struct page *page;
 
 	/* Find pfns pointing at start of each page, get pages and free them. */
 	for (i = 0; i < vb->num_pfns; i += VIRTIO_BALLOON_PAGES_PER_PAGE) {
-		struct page *page = balloon_pfn_to_page(vb->pfns[i]);
+		page = balloon_pfn_to_page(virtio32_to_cpu(vb->vdev,
+							   vb->pfns[i]));
 		if (!virtio_has_feature(vb->vdev,
 					VIRTIO_BALLOON_F_DEFLATE_ON_OOM))
 			adjust_managed_page_count(page, 1);
@@ -192,12 +197,14 @@ static unsigned leak_balloon(struct virt
 	num = min(num, ARRAY_SIZE(vb->pfns));
 
 	mutex_lock(&vb->balloon_lock);
+	/* We can't release more pages than taken */
+	num = min(num, (size_t)vb->num_pages);
 	for (vb->num_pfns = 0; vb->num_pfns < num;
 	     vb->num_pfns += VIRTIO_BALLOON_PAGES_PER_PAGE) {
 		page = balloon_page_dequeue(vb_dev_info);
 		if (!page)
 			break;
-		set_page_pfns(vb->pfns + vb->num_pfns, page);
+		set_page_pfns(vb, vb->pfns + vb->num_pfns, page);
 		vb->num_pages -= VIRTIO_BALLOON_PAGES_PER_PAGE;
 	}
 
@@ -209,8 +216,8 @@ static unsigned leak_balloon(struct virt
 	 */
 	if (vb->num_pfns != 0)
 		tell_host(vb, vb->deflate_vq);
-	mutex_unlock(&vb->balloon_lock);
 	release_pages_balloon(vb);
+	mutex_unlock(&vb->balloon_lock);
 	return num_freed_pages;
 }
 
@@ -229,10 +236,13 @@ static void update_balloon_stats(struct
 	unsigned long events[NR_VM_EVENT_ITEMS];
 	struct sysinfo i;
 	int idx = 0;
+	long available;
 
 	all_vm_events(events);
 	si_meminfo(&i);
 
+	available = si_mem_available();
+
 	update_stat(vb, idx++, VIRTIO_BALLOON_S_SWAP_IN,
 				pages_to_bytes(events[PSWPIN]));
 	update_stat(vb, idx++, VIRTIO_BALLOON_S_SWAP_OUT,
@@ -243,6 +253,8 @@ static void update_balloon_stats(struct
 				pages_to_bytes(i.freeram));
 	update_stat(vb, idx++, VIRTIO_BALLOON_S_MEMTOT,
 				pages_to_bytes(i.totalram));
+	update_stat(vb, idx++, VIRTIO_BALLOON_S_AVAIL,
+				pages_to_bytes(available));
 }
 
 /*
@@ -465,13 +477,13 @@ static int virtballoon_migratepage(struc
 	__count_vm_event(BALLOON_MIGRATE);
 	spin_unlock_irqrestore(&vb_dev_info->pages_lock, flags);
 	vb->num_pfns = VIRTIO_BALLOON_PAGES_PER_PAGE;
-	set_page_pfns(vb->pfns, newpage);
+	set_page_pfns(vb, vb->pfns, newpage);
 	tell_host(vb, vb->inflate_vq);
 
 	/* balloon's page migration 2nd step -- deflate "page" */
 	balloon_page_delete(page);
 	vb->num_pfns = VIRTIO_BALLOON_PAGES_PER_PAGE;
-	set_page_pfns(vb->pfns, page);
+	set_page_pfns(vb, vb->pfns, page);
 	tell_host(vb, vb->deflate_vq);
 
 	mutex_unlock(&vb->balloon_lock);
--- zfcpdump-kernel-4.4.orig/drivers/virtio/virtio_pci_common.c
+++ zfcpdump-kernel-4.4/drivers/virtio/virtio_pci_common.c
@@ -545,6 +545,7 @@ err_enable_device:
 static void virtio_pci_remove(struct pci_dev *pci_dev)
 {
 	struct virtio_pci_device *vp_dev = pci_get_drvdata(pci_dev);
+	struct device *dev = get_device(&vp_dev->vdev.dev);
 
 	unregister_virtio_device(&vp_dev->vdev);
 
@@ -554,6 +555,7 @@ static void virtio_pci_remove(struct pci
 		virtio_pci_modern_remove(vp_dev);
 
 	pci_disable_device(pci_dev);
+	put_device(dev);
 }
 
 static struct pci_driver virtio_pci_driver = {
--- zfcpdump-kernel-4.4.orig/drivers/virtio/virtio_pci_modern.c
+++ zfcpdump-kernel-4.4/drivers/virtio/virtio_pci_modern.c
@@ -17,6 +17,7 @@
  *
  */
 
+#include <linux/delay.h>
 #define VIRTIO_PCI_NO_LEGACY
 #include "virtio_pci_common.h"
 
@@ -271,9 +272,13 @@ static void vp_reset(struct virtio_devic
 	struct virtio_pci_device *vp_dev = to_vp_device(vdev);
 	/* 0 status means a reset. */
 	vp_iowrite8(0, &vp_dev->common->device_status);
-	/* Flush out the status write, and flush in device writes,
-	 * including MSI-X interrupts, if any. */
-	vp_ioread8(&vp_dev->common->device_status);
+	/* After writing 0 to device_status, the driver MUST wait for a read of
+	 * device_status to return 0 before reinitializing the device.
+	 * This will flush out the status write, and flush in device writes,
+	 * including MSI-X interrupts, if any.
+	 */
+	while (vp_ioread8(&vp_dev->common->device_status))
+		msleep(1);
 	/* Flush pending VQ/configuration callbacks. */
 	vp_synchronize_vectors(vdev);
 }
--- zfcpdump-kernel-4.4.orig/drivers/virtio/virtio_ring.c
+++ zfcpdump-kernel-4.4/drivers/virtio/virtio_ring.c
@@ -202,6 +202,8 @@ static inline int virtqueue_add(struct v
 		 * host should service the ring ASAP. */
 		if (out_sgs)
 			vq->notify(&vq->vq);
+		if (indirect)
+			kfree(desc);
 		END_USE(vq);
 		return -ENOSPC;
 	}
--- zfcpdump-kernel-4.4.orig/drivers/w1/masters/omap_hdq.c
+++ zfcpdump-kernel-4.4/drivers/w1/masters/omap_hdq.c
@@ -390,8 +390,6 @@ static int hdq_read_byte(struct hdq_data
 		goto out;
 	}
 
-	hdq_data->hdq_irqstatus = 0;
-
 	if (!(hdq_data->hdq_irqstatus & OMAP_HDQ_INT_STATUS_RXCOMPLETE)) {
 		hdq_reg_merge(hdq_data, OMAP_HDQ_CTRL_STATUS,
 			OMAP_HDQ_CTRL_STATUS_DIR | OMAP_HDQ_CTRL_STATUS_GO,
--- zfcpdump-kernel-4.4.orig/drivers/watchdog/rc32434_wdt.c
+++ zfcpdump-kernel-4.4/drivers/watchdog/rc32434_wdt.c
@@ -237,7 +237,7 @@ static long rc32434_wdt_ioctl(struct fil
 			return -EINVAL;
 		/* Fall through */
 	case WDIOC_GETTIMEOUT:
-		return copy_to_user(argp, &timeout, sizeof(int));
+		return copy_to_user(argp, &timeout, sizeof(int)) ? -EFAULT : 0;
 	default:
 		return -ENOTTY;
 	}
--- zfcpdump-kernel-4.4.orig/drivers/xen/balloon.c
+++ zfcpdump-kernel-4.4/drivers/xen/balloon.c
@@ -247,6 +247,19 @@ static enum bp_state update_schedule(enu
 }
 
 #ifdef CONFIG_XEN_BALLOON_MEMORY_HOTPLUG
+static void release_memory_resource(struct resource *resource)
+{
+	if (!resource)
+		return;
+
+	/*
+	 * No need to reset region to identity mapped since we now
+	 * know that no I/O can be in this region
+	 */
+	release_resource(resource);
+	kfree(resource);
+}
+
 static struct resource *additional_memory_resource(phys_addr_t size)
 {
 	struct resource *res;
@@ -268,20 +281,21 @@ static struct resource *additional_memor
 		return NULL;
 	}
 
-	return res;
-}
-
-static void release_memory_resource(struct resource *resource)
-{
-	if (!resource)
-		return;
+#ifdef CONFIG_SPARSEMEM
+	{
+		unsigned long limit = 1UL << (MAX_PHYSMEM_BITS - PAGE_SHIFT);
+		unsigned long pfn = res->start >> PAGE_SHIFT;
+
+		if (pfn > limit) {
+			pr_err("New System RAM resource outside addressable RAM (%lu > %lu)\n",
+			       pfn, limit);
+			release_memory_resource(res);
+			return NULL;
+		}
+	}
+#endif
 
-	/*
-	 * No need to reset region to identity mapped since we now
-	 * know that no I/O can be in this region
-	 */
-	release_resource(resource);
-	kfree(resource);
+	return res;
 }
 
 static enum bp_state reserve_additional_memory(void)
--- zfcpdump-kernel-4.4.orig/drivers/xen/events/events_base.c
+++ zfcpdump-kernel-4.4/drivers/xen/events/events_base.c
@@ -484,9 +484,20 @@ static void eoi_pirq(struct irq_data *da
 	struct physdev_eoi eoi = { .irq = pirq_from_irq(data->irq) };
 	int rc = 0;
 
-	irq_move_irq(data);
+	if (!VALID_EVTCHN(evtchn))
+		return;
 
-	if (VALID_EVTCHN(evtchn))
+	if (unlikely(irqd_is_setaffinity_pending(data)) &&
+	    likely(!irqd_irq_disabled(data))) {
+		int masked = test_and_set_mask(evtchn);
+
+		clear_evtchn(evtchn);
+
+		irq_move_masked_irq(data);
+
+		if (!masked)
+			unmask_evtchn(evtchn);
+	} else
 		clear_evtchn(evtchn);
 
 	if (pirq_needs_eoi(data->irq)) {
@@ -1357,9 +1368,20 @@ static void ack_dynirq(struct irq_data *
 {
 	int evtchn = evtchn_from_irq(data->irq);
 
-	irq_move_irq(data);
+	if (!VALID_EVTCHN(evtchn))
+		return;
 
-	if (VALID_EVTCHN(evtchn))
+	if (unlikely(irqd_is_setaffinity_pending(data)) &&
+	    likely(!irqd_irq_disabled(data))) {
+		int masked = test_and_set_mask(evtchn);
+
+		clear_evtchn(evtchn);
+
+		irq_move_masked_irq(data);
+
+		if (!masked)
+			unmask_evtchn(evtchn);
+	} else
 		clear_evtchn(evtchn);
 }
 
--- zfcpdump-kernel-4.4.orig/drivers/xen/evtchn.c
+++ zfcpdump-kernel-4.4/drivers/xen/evtchn.c
@@ -316,7 +316,6 @@ static int evtchn_resize_ring(struct per
 {
 	unsigned int new_size;
 	evtchn_port_t *new_ring, *old_ring;
-	unsigned int p, c;
 
 	/*
 	 * Ensure the ring is large enough to capture all possible
@@ -346,20 +345,17 @@ static int evtchn_resize_ring(struct per
 	/*
 	 * Copy the old ring contents to the new ring.
 	 *
-	 * If the ring contents crosses the end of the current ring,
-	 * it needs to be copied in two chunks.
+	 * To take care of wrapping, a full ring, and the new index
+	 * pointing into the second half, simply copy the old contents
+	 * twice.
 	 *
 	 * +---------+    +------------------+
-	 * |34567  12| -> |       1234567    |
-	 * +-----p-c-+    +------------------+
+	 * |34567  12| -> |34567  1234567  12|
+	 * +-----p-c-+    +-------c------p---+
 	 */
-	p = evtchn_ring_offset(u, u->ring_prod);
-	c = evtchn_ring_offset(u, u->ring_cons);
-	if (p < c) {
-		memcpy(new_ring + c, u->ring + c, (u->ring_size - c) * sizeof(*u->ring));
-		memcpy(new_ring + u->ring_size, u->ring, p * sizeof(*u->ring));
-	} else
-		memcpy(new_ring + c, u->ring + c, (p - c) * sizeof(*u->ring));
+	memcpy(new_ring, old_ring, u->ring_size * sizeof(*u->ring));
+	memcpy(new_ring + u->ring_size, old_ring,
+	       u->ring_size * sizeof(*u->ring));
 
 	u->ring = new_ring;
 	u->ring_size = new_size;
--- zfcpdump-kernel-4.4.orig/drivers/xen/xen-acpi-processor.c
+++ zfcpdump-kernel-4.4/drivers/xen/xen-acpi-processor.c
@@ -423,36 +423,7 @@ upload:
 
 	return 0;
 }
-static int __init check_prereq(void)
-{
-	struct cpuinfo_x86 *c = &cpu_data(0);
-
-	if (!xen_initial_domain())
-		return -ENODEV;
-
-	if (!acpi_gbl_FADT.smi_command)
-		return -ENODEV;
 
-	if (c->x86_vendor == X86_VENDOR_INTEL) {
-		if (!cpu_has(c, X86_FEATURE_EST))
-			return -ENODEV;
-
-		return 0;
-	}
-	if (c->x86_vendor == X86_VENDOR_AMD) {
-		/* Copied from powernow-k8.h, can't include ../cpufreq/powernow
-		 * as we get compile warnings for the static functions.
-		 */
-#define CPUID_FREQ_VOLT_CAPABILITIES    0x80000007
-#define USE_HW_PSTATE                   0x00000080
-		u32 eax, ebx, ecx, edx;
-		cpuid(CPUID_FREQ_VOLT_CAPABILITIES, &eax, &ebx, &ecx, &edx);
-		if ((edx & USE_HW_PSTATE) != USE_HW_PSTATE)
-			return -ENODEV;
-		return 0;
-	}
-	return -ENODEV;
-}
 /* acpi_perf_data is a pointer to percpu data. */
 static struct acpi_processor_performance __percpu *acpi_perf_data;
 
@@ -509,10 +480,10 @@ struct notifier_block xen_acpi_processor
 static int __init xen_acpi_processor_init(void)
 {
 	unsigned int i;
-	int rc = check_prereq();
+	int rc;
 
-	if (rc)
-		return rc;
+	if (!xen_initial_domain())
+		return -ENODEV;
 
 	nr_acpi_bits = get_max_acpi_id() + 1;
 	acpi_ids_done = kcalloc(BITS_TO_LONGS(nr_acpi_bits), sizeof(unsigned long), GFP_KERNEL);
--- zfcpdump-kernel-4.4.orig/drivers/xen/xen-pciback/conf_space.c
+++ zfcpdump-kernel-4.4/drivers/xen/xen-pciback/conf_space.c
@@ -183,8 +183,7 @@ int xen_pcibk_config_read(struct pci_dev
 		field_start = OFFSET(cfg_entry);
 		field_end = OFFSET(cfg_entry) + field->size;
 
-		if ((req_start >= field_start && req_start < field_end)
-		    || (req_end > field_start && req_end <= field_end)) {
+		 if (req_end > field_start && field_end > req_start) {
 			err = conf_space_read(dev, cfg_entry, field_start,
 					      &tmp_val);
 			if (err)
@@ -230,8 +229,7 @@ int xen_pcibk_config_write(struct pci_de
 		field_start = OFFSET(cfg_entry);
 		field_end = OFFSET(cfg_entry) + field->size;
 
-		if ((req_start >= field_start && req_start < field_end)
-		    || (req_end > field_start && req_end <= field_end)) {
+		 if (req_end > field_start && field_end > req_start) {
 			tmp_val = 0;
 
 			err = xen_pcibk_config_read(dev, field_start,
--- zfcpdump-kernel-4.4.orig/drivers/xen/xen-pciback/pciback_ops.c
+++ zfcpdump-kernel-4.4/drivers/xen/xen-pciback/pciback_ops.c
@@ -227,8 +227,9 @@ int xen_pcibk_enable_msix(struct xen_pci
 	/*
 	 * PCI_COMMAND_MEMORY must be enabled, otherwise we may not be able
 	 * to access the BARs where the MSI-X entries reside.
+	 * But VF devices are unique in which the PF needs to be checked.
 	 */
-	pci_read_config_word(dev, PCI_COMMAND, &cmd);
+	pci_read_config_word(pci_physfn(dev), PCI_COMMAND, &cmd);
 	if (dev->msi_enabled || !(cmd & PCI_COMMAND_MEMORY))
 		return -ENXIO;
 
@@ -332,6 +333,9 @@ void xen_pcibk_do_op(struct work_struct
 	struct xen_pcibk_dev_data *dev_data = NULL;
 	struct xen_pci_op *op = &pdev->op;
 	int test_intx = 0;
+#ifdef CONFIG_PCI_MSI
+	unsigned int nr = 0;
+#endif
 
 	*op = pdev->sh_info->op;
 	barrier();
@@ -360,6 +364,7 @@ void xen_pcibk_do_op(struct work_struct
 			op->err = xen_pcibk_disable_msi(pdev, dev, op);
 			break;
 		case XEN_PCI_OP_enable_msix:
+			nr = op->value;
 			op->err = xen_pcibk_enable_msix(pdev, dev, op);
 			break;
 		case XEN_PCI_OP_disable_msix:
@@ -382,7 +387,7 @@ void xen_pcibk_do_op(struct work_struct
 	if (op->cmd == XEN_PCI_OP_enable_msix && op->err == 0) {
 		unsigned int i;
 
-		for (i = 0; i < op->value; i++)
+		for (i = 0; i < nr; i++)
 			pdev->sh_info->op.msix_entries[i].vector =
 				op->msix_entries[i].vector;
 	}
--- zfcpdump-kernel-4.4.orig/drivers/xen/xen-scsiback.c
+++ zfcpdump-kernel-4.4/drivers/xen/xen-scsiback.c
@@ -939,12 +939,12 @@ out:
 	spin_unlock_irqrestore(&info->v2p_lock, flags);
 
 out_free:
-	mutex_lock(&tpg->tv_tpg_mutex);
-	tpg->tv_tpg_fe_count--;
-	mutex_unlock(&tpg->tv_tpg_mutex);
-
-	if (err)
+	if (err) {
+		mutex_lock(&tpg->tv_tpg_mutex);
+		tpg->tv_tpg_fe_count--;
+		mutex_unlock(&tpg->tv_tpg_mutex);
 		kfree(new);
+	}
 
 	return err;
 }
--- zfcpdump-kernel-4.4.orig/drivers/xen/xenbus/xenbus_dev_frontend.c
+++ zfcpdump-kernel-4.4/drivers/xen/xenbus/xenbus_dev_frontend.c
@@ -316,11 +316,18 @@ static int xenbus_write_transaction(unsi
 			rc = -ENOMEM;
 			goto out;
 		}
+	} else if (msg_type == XS_TRANSACTION_END) {
+		list_for_each_entry(trans, &u->transactions, list)
+			if (trans->handle.id == u->u.msg.tx_id)
+				break;
+		if (&trans->list == &u->transactions)
+			return -ESRCH;
 	}
 
 	reply = xenbus_dev_request_and_reply(&u->u.msg);
 	if (IS_ERR(reply)) {
-		kfree(trans);
+		if (msg_type == XS_TRANSACTION_START)
+			kfree(trans);
 		rc = PTR_ERR(reply);
 		goto out;
 	}
@@ -333,12 +340,7 @@ static int xenbus_write_transaction(unsi
 			list_add(&trans->list, &u->transactions);
 		}
 	} else if (u->u.msg.type == XS_TRANSACTION_END) {
-		list_for_each_entry(trans, &u->transactions, list)
-			if (trans->handle.id == u->u.msg.tx_id)
-				break;
-		BUG_ON(&trans->list == &u->transactions);
 		list_del(&trans->list);
-
 		kfree(trans);
 	}
 
--- zfcpdump-kernel-4.4.orig/drivers/xen/xenbus/xenbus_probe.c
+++ zfcpdump-kernel-4.4/drivers/xen/xenbus/xenbus_probe.c
@@ -826,7 +826,7 @@ static int __init xenbus_init(void)
 	 * Create xenfs mountpoint in /proc for compatibility with
 	 * utilities that expect to find "xenbus" under "/proc/xen".
 	 */
-	proc_mkdir("xen", NULL);
+	proc_create_mount_point("xen");
 #endif
 
 out_error:
--- zfcpdump-kernel-4.4.orig/drivers/xen/xenbus/xenbus_xs.c
+++ zfcpdump-kernel-4.4/drivers/xen/xenbus/xenbus_xs.c
@@ -250,9 +250,6 @@ void *xenbus_dev_request_and_reply(struc
 
 	mutex_unlock(&xs_state.request_mutex);
 
-	if (IS_ERR(ret))
-		return ret;
-
 	if ((msg->type == XS_TRANSACTION_END) ||
 	    ((req_msg.type == XS_TRANSACTION_START) &&
 	     (msg->type == XS_ERROR)))
--- /dev/null
+++ zfcpdump-kernel-4.4/dropped.txt
@@ -0,0 +1,11 @@
+UBUNTU: SAUCE: (no-up) dell-wmi: Demote unknown WMI event message to pr_debug
+UBUNTU: SAUCE: (no-up) arm64: dts: Add X-Gene reboot driver dts node
+UBUNTU: SAUCE: (no-up) Add documentation for generic SYSCON reboot driver.
+UBUNTU: SAUCE: fix perf_regs definitions for arm64
+UBUNTU: SAUCE: aufs3 -- (no-up) aufs3-mmap.patch
+Revert "UBUNTU: SAUCE: aufs3 -- (no-up) aufs3-mmap.patch"
+UBUNTU: SAUCE: aufs3 -- (no-up) aufs3-mmap.patch
+UBUNTU: SAUCE: aufs3 -- avoid aufs3-mmap.patch include hell for arm64
+UBUNTU: SAUCE: (no-up) irqchip:gic: change access of gicc_ctrl register to read modify write.
+UBUNTU: SAUCE: (no-up) PCI: Increase BAR size quirk for IBM ipr SAS Crocodile adapters
+
--- zfcpdump-kernel-4.4.orig/firmware/Makefile
+++ zfcpdump-kernel-4.4/firmware/Makefile
@@ -20,80 +20,32 @@ fw-external-y := $(subst $(quote),,$(CON
 # accurate. In the latter case it doesn't matter -- it'll use $(fw-shipped-all).
 # But be aware that the config file might not be included at all.
 
-ifdef CONFIG_ACENIC_OMIT_TIGON_I
-acenic-objs := acenic/tg2.bin
-fw-shipped- += acenic/tg1.bin
-else
-acenic-objs := acenic/tg1.bin acenic/tg2.bin
-endif
-fw-shipped-$(CONFIG_ACENIC) += $(acenic-objs)
-fw-shipped-$(CONFIG_ADAPTEC_STARFIRE) += adaptec/starfire_rx.bin \
-					 adaptec/starfire_tx.bin
-fw-shipped-$(CONFIG_ATARI_DSP56K) += dsp56k/bootstrap.bin
-fw-shipped-$(CONFIG_ATM_AMBASSADOR) += atmsar11.fw
-fw-shipped-$(CONFIG_BNX2X) += bnx2x/bnx2x-e1-6.2.9.0.fw \
-			      bnx2x/bnx2x-e1h-6.2.9.0.fw \
-			      bnx2x/bnx2x-e2-6.2.9.0.fw
-fw-shipped-$(CONFIG_BNX2) += bnx2/bnx2-mips-09-6.2.1a.fw \
-			     bnx2/bnx2-rv2p-09-6.0.17.fw \
-			     bnx2/bnx2-rv2p-09ax-6.0.17.fw \
-			     bnx2/bnx2-mips-06-6.2.1.fw \
-			     bnx2/bnx2-rv2p-06-6.0.15.fw
-fw-shipped-$(CONFIG_CASSINI) += sun/cassini.bin
-fw-shipped-$(CONFIG_CHELSIO_T3) += cxgb3/t3b_psram-1.1.0.bin \
-				   cxgb3/t3c_psram-1.1.0.bin \
-				   cxgb3/ael2005_opt_edc.bin \
-				   cxgb3/ael2005_twx_edc.bin \
-				   cxgb3/ael2020_twx_edc.bin
-fw-shipped-$(CONFIG_DRM_MGA) += matrox/g200_warp.fw matrox/g400_warp.fw
-fw-shipped-$(CONFIG_DRM_R128) += r128/r128_cce.bin
-fw-shipped-$(CONFIG_DRM_RADEON) += radeon/R100_cp.bin radeon/R200_cp.bin \
-				   radeon/R300_cp.bin radeon/R420_cp.bin \
-				   radeon/RS690_cp.bin radeon/RS600_cp.bin \
-				   radeon/R520_cp.bin \
-				   radeon/R600_pfp.bin radeon/R600_me.bin \
-				   radeon/RV610_pfp.bin radeon/RV610_me.bin \
-				   radeon/RV630_pfp.bin radeon/RV630_me.bin \
-				   radeon/RV620_pfp.bin radeon/RV620_me.bin \
-				   radeon/RV635_pfp.bin radeon/RV635_me.bin \
-				   radeon/RV670_pfp.bin radeon/RV670_me.bin \
-				   radeon/RS780_pfp.bin radeon/RS780_me.bin \
-				   radeon/RV770_pfp.bin radeon/RV770_me.bin \
-				   radeon/RV730_pfp.bin radeon/RV730_me.bin \
-				   radeon/RV710_pfp.bin radeon/RV710_me.bin
-fw-shipped-$(CONFIG_DVB_AV7110) += av7110/bootcode.bin
-fw-shipped-$(CONFIG_DVB_TTUSB_BUDGET) += ttusb-budget/dspbootcode.bin
+fw-shipped-$(CONFIG_BNX2X) += bnx2x/bnx2x-e1-7.12.30.0.fw \
+			      bnx2x/bnx2x-e1h-7.12.30.0.fw \
+			      bnx2x/bnx2x-e2-7.12.30.0.fw
+fw-shipped-$(CONFIG_BNX2) += 	bnx2/bnx2-mips-09-6.2.1b.fw \
+				bnx2/bnx2-rv2p-06-6.0.15.fw \
+				bnx2/bnx2-mips-06-6.2.3.fw \
+				bnx2/bnx2-rv2p-09-6.0.17.fw \
+				bnx2/bnx2-rv2p-09ax-6.0.17.fw
 fw-shipped-$(CONFIG_E100) += e100/d101m_ucode.bin e100/d101s_ucode.bin \
 			     e100/d102e_ucode.bin
-fw-shipped-$(CONFIG_MYRI_SBUS) += myricom/lanai.bin
-fw-shipped-$(CONFIG_PCMCIA_PCNET) += cis/LA-PCM.cis cis/PCMLM28.cis \
-				     cis/DP83903.cis cis/NE2K.cis \
-				     cis/tamarack.cis cis/PE-200.cis \
-				     cis/PE520.cis
-fw-shipped-$(CONFIG_PCMCIA_3C589) += cis/3CXEM556.cis
-fw-shipped-$(CONFIG_PCMCIA_3C574) += cis/3CCFEM556.cis
-fw-shipped-$(CONFIG_SERIAL_8250_CS) += cis/MT5634ZLX.cis cis/RS-COM-2P.cis \
-				       cis/COMpad2.cis cis/COMpad4.cis \
-				       cis/SW_555_SER.cis cis/SW_7xx_SER.cis \
-				       cis/SW_8xx_SER.cis
-fw-shipped-$(CONFIG_PCMCIA_SMC91C92) += ositech/Xilinx7OD.bin
-fw-shipped-$(CONFIG_SCSI_ADVANSYS) += advansys/mcode.bin advansys/38C1600.bin \
-				      advansys/3550.bin advansys/38C0800.bin
+fw-shipped-$(CONFIG_PCMCIA_PCNET) += 
+				     
+fw-shipped-$(CONFIG_PCMCIA_3C589) += 
+fw-shipped-$(CONFIG_PCMCIA_3C574) += 
+fw-shipped-$(CONFIG_SERIAL_8250_CS) +=
+				       
 fw-shipped-$(CONFIG_SCSI_QLOGIC_1280) += qlogic/1040.bin qlogic/1280.bin \
 					 qlogic/12160.bin
 fw-shipped-$(CONFIG_SCSI_QLOGICPTI) += qlogic/isp1000.bin
 fw-shipped-$(CONFIG_INFINIBAND_QIB) += qlogic/sd7220.fw
 fw-shipped-$(CONFIG_SND_KORG1212) += korg/k1212.dsp
-fw-shipped-$(CONFIG_SND_MAESTRO3) += ess/maestro3_assp_kernel.fw \
-				     ess/maestro3_assp_minisrc.fw
 fw-shipped-$(CONFIG_SND_SB16_CSP) += sb16/mulaw_main.csp sb16/alaw_main.csp \
 				     sb16/ima_adpcm_init.csp \
 				     sb16/ima_adpcm_playback.csp \
 				     sb16/ima_adpcm_capture.csp
-fw-shipped-$(CONFIG_SND_YMFPCI) += yamaha/ds1_ctrl.fw yamaha/ds1_dsp.fw \
-				   yamaha/ds1e_ctrl.fw
 fw-shipped-$(CONFIG_SND_WAVEFRONT) += yamaha/yss225_registers.bin
-fw-shipped-$(CONFIG_TEHUTI) += tehuti/bdx.bin
 fw-shipped-$(CONFIG_TIGON3) += tigon/tg3.bin tigon/tg3_tso.bin \
 			       tigon/tg3_tso5.bin
 fw-shipped-$(CONFIG_TYPHOON) += 3com/typhoon.bin
@@ -101,40 +53,8 @@ fw-shipped-$(CONFIG_USB_EMI26) += emi26/
 				  emi26/bitstream.fw
 fw-shipped-$(CONFIG_USB_EMI62) += emi62/loader.fw emi62/bitstream.fw \
 				  emi62/spdif.fw emi62/midi.fw
-fw-shipped-$(CONFIG_USB_KAWETH) += kaweth/new_code.bin kaweth/trigger_code.bin \
-				   kaweth/new_code_fix.bin \
-				   kaweth/trigger_code_fix.bin
-ifdef CONFIG_FIRMWARE_IN_KERNEL
-fw-shipped-$(CONFIG_USB_SERIAL_KEYSPAN_MPR) += keyspan/mpr.fw
-fw-shipped-$(CONFIG_USB_SERIAL_KEYSPAN_USA18X) += keyspan/usa18x.fw
-fw-shipped-$(CONFIG_USB_SERIAL_KEYSPAN_USA19) += keyspan/usa19.fw
-fw-shipped-$(CONFIG_USB_SERIAL_KEYSPAN_USA19QI) += keyspan/usa19qi.fw
-fw-shipped-$(CONFIG_USB_SERIAL_KEYSPAN_USA19QW) += keyspan/usa19qw.fw
-fw-shipped-$(CONFIG_USB_SERIAL_KEYSPAN_USA19W) += keyspan/usa19w.fw
-fw-shipped-$(CONFIG_USB_SERIAL_KEYSPAN_USA28) += keyspan/usa28.fw
-fw-shipped-$(CONFIG_USB_SERIAL_KEYSPAN_USA28XA) += keyspan/usa28xa.fw
-fw-shipped-$(CONFIG_USB_SERIAL_KEYSPAN_USA28XB) += keyspan/usa28xb.fw
-fw-shipped-$(CONFIG_USB_SERIAL_KEYSPAN_USA28X) += keyspan/usa28x.fw
-fw-shipped-$(CONFIG_USB_SERIAL_KEYSPAN_USA49W) += keyspan/usa49w.fw
-fw-shipped-$(CONFIG_USB_SERIAL_KEYSPAN_USA49WLC) += keyspan/usa49wlc.fw
-else
-fw-shipped- += keyspan/mpr.fw keyspan/usa18x.fw keyspan/usa19.fw	\
-	keyspan/usa19qi.fw keyspan/usa19qw.fw keyspan/usa19w.fw		\
-	keyspan/usa28.fw keyspan/usa28xa.fw keyspan/usa28xb.fw		\
-	keyspan/usa28x.fw keyspan/usa49w.fw keyspan/usa49wlc.fw
-endif
-fw-shipped-$(CONFIG_USB_SERIAL_TI) += ti_3410.fw ti_5052.fw \
-				      mts_cdma.fw mts_gsm.fw mts_edge.fw
-fw-shipped-$(CONFIG_USB_SERIAL_EDGEPORT) += edgeport/boot.fw edgeport/boot2.fw \
-					    edgeport/down.fw edgeport/down2.fw
-fw-shipped-$(CONFIG_USB_SERIAL_EDGEPORT_TI) += edgeport/down3.bin
 fw-shipped-$(CONFIG_USB_SERIAL_WHITEHEAT) += whiteheat_loader.fw whiteheat.fw \
 					   # whiteheat_loader_debug.fw
-fw-shipped-$(CONFIG_USB_SERIAL_KEYSPAN_PDA) += keyspan_pda/keyspan_pda.fw
-fw-shipped-$(CONFIG_USB_SERIAL_XIRCOM) += keyspan_pda/xircom_pgs.fw
-fw-shipped-$(CONFIG_USB_VICAM) += vicam/firmware.fw
-fw-shipped-$(CONFIG_VIDEO_CPIA2) += cpia2/stv0672_vp4.bin
-fw-shipped-$(CONFIG_YAM) += yam/1200.bin yam/9600.bin
 
 fw-shipped-all := $(fw-shipped-y) $(fw-shipped-m) $(fw-shipped-)
 
--- zfcpdump-kernel-4.4.orig/firmware/WHENCE
+++ zfcpdump-kernel-4.4/firmware/WHENCE
@@ -619,16 +619,6 @@ Found in hex form in kernel source.
 
 --------------------------------------------------------------------------
 
-Driver: MYRI_SBUS - MyriCOM Gigabit Ethernet
-
-File: myricom/lanai.bin
-
-Licence: Unknown
-
-Found in hex form in kernel source.
-
---------------------------------------------------------------------------
-
 Driver: bnx2x: Broadcom Everest
 
 File: bnx2x/bnx2x-e1-6.2.9.0.fw
--- zfcpdump-kernel-4.4.orig/firmware/acenic/tg1.bin.ihex
+++ /dev/null
@@ -1,4573 +0,0 @@
-:100000000C040B0000004000000040001000000342
-:10001000000000000000000D0000000D3C1D00016C
-:100020008FBD5C5403A0F0213C100000261040005E
-:100030000C00100C000000000000000D27BDFFD8D0
-:100040003C1CC0003C1B0013377BD8000000D021B3
-:100050003C17001336F7541802E02021340583E8DA
-:10006000AFBF00240C002488AFB000200C0023E8B0
-:10007000000000003C040001248451A42405000178
-:1000800002E03021000038213C10000126107E5093
-:10009000AFB000100C002403AFBB00143C02000FF3
-:1000A0003442FFFF020210240362102B10400009AB
-:1000B000240500033C040001248451B002003021D7
-:1000C000036038213C020010AFA200100C00240392
-:1000D000AFA00014000020213405C0003C01000145
-:1000E00000370821A02083B03C010001003708211F
-:1000F000A02083B23C01000100370821A02083B377
-:100100003C01000100370821AC2083B4A2E004D8F0
-:10011000000418C02484000100771021AC40727CD8
-:1001200000771021AC40728002E31021A445727C5C
-:100130002C8200201440FFF7000418C0000020218A
-:100140003405C000000418C0248400010077102189
-:10015000AC40737C00771021AC40738002E3102127
-:10016000A445737C2C8200805440FFF7000418C023
-:10017000AF800054AF80011C8F82004434420040A5
-:10018000AF8200448F82004434420020AF8200449A
-:100190008F420218304200021040000900000000A7
-:1001A0008F4202203C030002346300040043102508
-:1001B000AEE204C48F42021C0800107434420004F2
-:1001C0008F4202203C0300023463000600431025E6
-:1001D000AEE204C48F42021C34420006AEE204CCFC
-:1001E0008F420218304200101040000A0000000048
-:1001F0008F42021C34420004AEE204C88F42022047
-:100200003C03000A34630004004310250800108AF0
-:10021000AEE204C08F4202203C03000A34630006B1
-:1002200000431025AEE204C08F42021C3442000697
-:10023000AEE204C88F4202183042020010400003B0
-:100240002402000108001091A2E27248A2E0724864
-:1002500024020001AF8200A0AF8200B08F8300545F
-:100260008F82005408001099246300648F82005428
-:10027000006210232C4200651440FFFC00000000C7
-:10028000AF8000448F4202088F43020CAEE20010A0
-:10029000AEE300148EE400108EE5001426E2003078
-:1002A000AEE2002824020490AEE20018AF84009071
-:1002B000AF8500948EE20028AF8200B496E2001A67
-:1002C000AF82009C8F8200B08EE304CC00431025E7
-:1002D000AF8200B08F8200B0304200041440FFFDB6
-:1002E000000000008EE204508EE30454AEE304FCF0
-:1002F0008EE204FC2442E0002C4220011440000D58
-:1003000026E400308EE204508EE304543C040001E5
-:10031000248451BC3C050001AFA00010AFA0001424
-:100320008EE704FC34A5F0000C00240300603021AB
-:1003300026E400300C0024882405040027440080B3
-:100340000C0024882405008026E4777C0C00248897
-:10035000240504008F42025C26E40094AEE20060B3
-:100360008F4202602745020024060008AEE20068C2
-:10037000240200060C00249AAEE200643C023B9A80
-:100380003442CA000000202124030002AEE30074BE
-:10039000AEE30070AEE2006C240203E8AEE20104BA
-:1003A00024020001AEE30100AEE2010C3C030001B7
-:1003B0000064182190635C2002E410212484000171
-:1003C000A043009C2C82000F1440FFF800000000A6
-:1003D0008F82004002E418212484000100021702E9
-:1003E00024420030A062009C02E41021A040009C46
-:1003F00096E2046A30420003144000090000000045
-:1004000096E2047A30420003504001313C03080078
-:1004100096E2046A304200031040002A3C020700C2
-:1004200096E2047A30420003104000263C020700A6
-:1004300096E3047A96E2046A146200223C02070002
-:100440008EE204C024030001A2E34E2034420E00D9
-:10045000AEE204C08F420218304201001040000595
-:10046000000000003C0200012442E1680800111D68
-:10047000000211003C0200012442D35C0002110082
-:10048000000211823C030800004310253C010001DA
-:10049000AC2212383C0200012442F6800002110016
-:1004A000000211823C030800004310253C010001BA
-:1004B000AC2212788EE2000034424000080012386C
-:1004C000AEE2000034423000AFA200188EE206080F
-:1004D0008F43022824420001304900FF512300E2EB
-:1004E000AFA000108EE20608000210C000571021D5
-:1004F0008FA300188FA4001CAC43060CAC4406105C
-:100500008F8701202762380024E800200102102B89
-:1005100050400001276830008F820128110200043A
-:10052000000000008F820124150200070000102146
-:100530008EE201A40000302124420001AEE201A4B9
-:10054000080011A08EE201A48EE40608000420C079
-:10055000008018218EE404308EE5043400A32821A5
-:1005600000A3302B0082202100862021ACE4000073
-:10057000ACE500048EE3060824020008A4E2000EA5
-:100580002402000DACE20018ACE9001C000318C006
-:100590002463060C02E31021ACE200088EE204C4DE
-:1005A000ACE20010AF88012092E24E2014400037E8
-:1005B000240600018EE24E30000210C02442503862
-:1005C00002E220218C830000240200071462001F35
-:1005D000000000008EE34E308EE24E341062001BAD
-:1005E000240300408C82000424420001AC820004F9
-:1005F0008EE24E348EE54E30244200011043000757
-:10060000000000008EE24E342442000110A20005DA
-:10061000000000000800118A0000000014A000057E
-:10062000000000008F82012824420020AF820128B0
-:100630008F8201288C8200042C420011504000134C
-:10064000AC800000080011A0000000008EE24E30D7
-:100650002403004024420001504300030000102105
-:100660008EE24E3024420001AEE24E308EE24E3039
-:10067000000210C02442503802E220212402000768
-:10068000AC82000024020001AC82000454C0000CC3
-:10069000AEE906083C040001248451C8AFA0001054
-:1006A000AFA000148EE606088F4702283C0500091B
-:1006B0000C00240334A5F000080012230000000001
-:1006C0008F830120276238002466002000C2102B8F
-:1006D00050400001276630008F82012810C20004BC
-:1006E000000000008F82012414C2000700000000F7
-:1006F0008EE201A40000302124420001AEE201A4F8
-:10070000080012078EE201A48EE20608AC62001C0B
-:100710008EE404A08EE504A42462001CAC620008F0
-:1007200024020008A462000E24020011AC6200182A
-:10073000AC640000AC6500048EE204C4AC6200103E
-:10074000AF86012092E24E201440003724060001BB
-:100750008EE24E30000210C02442503802E22021C6
-:100760008C830000240200121462001F00000000AD
-:100770008EE34E308EE24E341062001B24030040A4
-:100780008C82000424420001AC8200048EE24E34CC
-:100790008EE54E30244200011043000700000000A7
-:1007A0008EE24E342442000110A200050000000039
-:1007B000080011F10000000014A000050000000076
-:1007C0008F82012824420020AF8201288F820128D5
-:1007D0008C8200042C42001150400013AC800000B9
-:1007E00008001207000000008EE24E302403004093
-:1007F0002442000150430003000010218EE24E30DD
-:1008000024420001AEE24E308EE24E30000210C0B3
-:100810002442503802E2202124020012AC8200005F
-:1008200024020001AC82000414C0001B0000000080
-:100830003C040001248451D0AFA00010AFA00014EC
-:100840008EE606088F4702283C0500090C002403A9
-:1008500034A5F0018EE201B024420001AEE201B005
-:10086000080012238EE201B03C040001248451DC14
-:10087000AFA000148EE606088F4702283C05000949
-:100880000C00240334A5F0058EE201AC24420001E3
-:10089000AEE201AC8EE201AC8EE201603C040001EC
-:1008A000248451E83405F00124420001AEE20160E5
-:1008B0008EE201600000302100003821AFA000105E
-:1008C0000C002403AFA00014080012380000000040
-:1008D0003C0200012442F5A800021100000211822E
-:1008E000004310253C010001AC22127896E2045A24
-:1008F00030420003104000253C050FFF8EE204C883
-:1009000034A5FFFF34420A00AEE204C88EE304C8F7
-:100910003C040001248451F424020001A2E204EC0E
-:10092000A2E204ED3C020002006218253C02000134
-:100930002442A3900045102400021082AEE304C8B4
-:100940003C030800004310253C010001AC221220AA
-:100950003C0200012442ADD4004510240002108264
-:10096000004310253C010001AC22128096E6045A97
-:100970000000382124050011AFA000100C00240352
-:10098000AFA0001408001268000000003C02000143
-:100990002442A9D400021100000211823C03080085
-:1009A000004310253C010001AC22128096E2046A4B
-:1009B00030420010144000090000000096E2047A62
-:1009C00030420010104001120000000096E2046A5C
-:1009D00030420010104000053C02070096E2047A05
-:1009E00030420010144001023C0207003442300043
-:1009F000AFA200188EE206088F43022824420001AD
-:100A0000304900FF512300E2AFA000108EE206083B
-:100A1000000210C0005710218FA300188FA4001CE3
-:100A2000AC43060CAC4406108F87012027623800C7
-:100A300024E800200102102B5040000127683000FC
-:100A40008F82012811020004000000008F8201241F
-:100A500015020007000010218EE201A400003021E1
-:100A600024420001AEE201A4080012EA8EE201A4D1
-:100A70008EE40608000420C0008018218EE40430B3
-:100A80008EE5043400A3282100A3302B008220210E
-:100A900000862021ACE40000ACE500048EE30608EB
-:100AA00024020008A4E2000E2402000DACE20018AB
-:100AB000ACE9001C000318C02463060C02E31021FB
-:100AC000ACE200088EE204C4ACE20010AF88012062
-:100AD00092E24E2014400037240600018EE24E3090
-:100AE000000210C02442503802E220218C83000012
-:100AF000240200071462001F000000008EE34E3045
-:100B00008EE24E341062001B240300408C820004ED
-:100B100024420001AC8200048EE24E348EE54E3059
-:100B20002442000110430007000000008EE24E3412
-:100B30002442000110A2000500000000080012D4A9
-:100B40000000000014A00005000000008F820128B2
-:100B500024420020AF8201288F8201288C82000469
-:100B60002C42001150400013AC800000080012EA33
-:100B7000000000008EE24E302403004024420001B9
-:100B800050430003000010218EE24E302442000149
-:100B9000AEE24E308EE24E30000210C02442503899
-:100BA00002E2202124020007AC820000240200019E
-:100BB000AC82000454C0000CAEE906083C040001FD
-:100BC000248451C8AFA00010AFA000148EE6060820
-:100BD0008F4702283C0500090C00240334A5F000CF
-:100BE0000800136D000000008F8301202762380089
-:100BF0002466002000C2102B504000012766300000
-:100C00008F82012810C20004000000008F8201249E
-:100C100014C20007000000008EE201A40000302191
-:100C200024420001AEE201A4080013518EE201A4A7
-:100C30008EE20608AC62001C8EE404A08EE504A4DB
-:100C40002462001CAC62000824020008A462000EAA
-:100C500024020011AC620018AC640000AC65000412
-:100C60008EE204C4AC620010AF86012092E24E20F6
-:100C700014400037240600018EE24E30000210C0FE
-:100C80002442503802E220218C830000240200120A
-:100C90001462001F000000008EE34E308EE24E34DE
-:100CA0001062001B240300408C82000424420001D7
-:100CB000AC8200048EE24E348EE54E3024420001B8
-:100CC00010430007000000008EE24E342442000171
-:100CD00010A20005000000000800133B0000000007
-:100CE00014A00005000000008F820128244200208B
-:100CF000AF8201288F8201288C8200042C420011CF
-:100D000050400013AC8000000800135100000000A8
-:100D10008EE24E3024030040244200015043000381
-:100D2000000010218EE24E3024420001AEE24E302F
-:100D30008EE24E30000210C02442503802E22021E0
-:100D400024020012AC82000024020001AC820004E4
-:100D500014C0001B000000003C040001248451D09A
-:100D6000AFA00010AFA000148EE606088F4702283F
-:100D70003C0500090C00240334A5F0018EE201B00B
-:100D800024420001AEE201B00800136D8EE201B012
-:100D90003C040001248451DCAFA000148EE6060858
-:100DA0008F4702283C0500090C00240334A5F005F8
-:100DB0008EE201AC24420001AEE201AC8EE201AC55
-:100DC0008EE201603C040001248451E83405F00205
-:100DD00024420001AEE201608EE201600000302199
-:100DE00000003821AFA000100C002403AFA00014B5
-:100DF00096E6047A96E7046A3C04000124845200D3
-:100E000024050012AFA000100C002403AFA00014B2
-:100E10000C004500000000000C002318000000003A
-:100E20003C06000134C63800AEE00608AF40022898
-:100E3000AF40022C96E304588EE400003C0512D823
-:100E400034A5C35827623800AEE2725827623800D2
-:100E5000AEE2726027623800AEE27264036610216F
-:100E6000AEE272702402FFFFAEE004D4AEE004E014
-:100E7000AEE004E4AEE004F0A2E004F4AEE00E0C58
-:100E8000AEE00E18AEE00E10AEE00E14AEE00E1C9A
-:100E9000AEE0724CAEE05244AEE05240AEE0523CA6
-:100EA000AEE07250AEE07254AEE0725CAEE07268DA
-:100EB000AEE004D02463FFFF00852025AEE304F8F4
-:100EC000AEE40000AF800060AF8200643C0201002D
-:100ED000AFA200188EE206088F43022824420001C8
-:100EE000304900FF512300E2AFA000108EE2060857
-:100EF000000210C0005710218FA300188FA4001CFF
-:100F0000AC43060CAC4406108F87012027623800E2
-:100F100024E800200102102B504000012768300017
-:100F20008F82012811020004000000008F8201243A
-:100F300015020007000010218EE201A400003021FC
-:100F400024420001AEE201A4080014228EE201A4B2
-:100F50008EE40608000420C0008018218EE40430CE
-:100F60008EE5043400A3282100A3302B0082202129
-:100F700000862021ACE40000ACE500048EE3060806
-:100F800024020008A4E2000E2402000DACE20018C6
-:100F9000ACE9001C000318C02463060C02E3102116
-:100FA000ACE200088EE204C4ACE20010AF8801207D
-:100FB00092E24E2014400037240600018EE24E30AB
-:100FC000000210C02442503802E220218C8300002D
-:100FD000240200071462001F000000008EE34E3060
-:100FE0008EE24E341062001B240300408C82000409
-:100FF00024420001AC8200048EE24E348EE54E3075
-:101000002442000110430007000000008EE24E342D
-:101010002442000110A20005000000000800140C8A
-:101020000000000014A00005000000008F820128CD
-:1010300024420020AF8201288F8201288C82000484
-:101040002C42001150400013AC8000000800142214
-:10105000000000008EE24E302403004024420001D4
-:1010600050430003000010218EE24E302442000164
-:10107000AEE24E308EE24E30000210C024425038B4
-:1010800002E2202124020007AC82000024020001B9
-:10109000AC82000454C0000CAEE906083C04000118
-:1010A000248451C8AFA00010AFA000148EE606083B
-:1010B0008F4702283C0500090C00240334A5F000EA
-:1010C000080014A5000000008F830120276238006B
-:1010D0002466002000C2102B50400001276630001B
-:1010E0008F82012810C20004000000008F820124BA
-:1010F00014C20007000000008EE201A400003021AD
-:1011000024420001AEE201A4080014898EE201A489
-:101110008EE20608AC62001C8EE404A08EE504A4F6
-:101120002462001CAC62000824020008A462000EC5
-:1011300024020011AC620018AC640000AC6500042D
-:101140008EE204C4AC620010AF86012092E24E2011
-:1011500014400037240600018EE24E30000210C019
-:101160002442503802E220218C8300002402001225
-:101170001462001F000000008EE34E308EE24E34F9
-:101180001062001B240300408C82000424420001F2
-:10119000AC8200048EE24E348EE54E3024420001D3
-:1011A00010430007000000008EE24E34244200018C
-:1011B00010A20005000000000800147300000000E9
-:1011C00014A00005000000008F82012824420020A6
-:1011D000AF8201288F8201288C8200042C420011EA
-:1011E00050400013AC80000008001489000000008B
-:1011F0008EE24E302403004024420001504300039D
-:10120000000010218EE24E3024420001AEE24E304A
-:101210008EE24E30000210C02442503802E22021FB
-:1012200024020012AC82000024020001AC820004FF
-:1012300014C0001B000000003C040001248451D0B5
-:10124000AFA00010AFA000148EE606088F4702285A
-:101250003C0500090C00240334A5F0018EE201B026
-:1012600024420001AEE201B0080014A58EE201B0F4
-:101270003C040001248451DCAFA000148EE6060873
-:101280008F4702283C0500090C00240334A5F00513
-:101290008EE201AC24420001AEE201AC8EE201AC70
-:1012A0008EE2015424420001AEE201540C0014DC31
-:1012B0008EE201548F8200A0304200041440FFFDF2
-:1012C000000000008F8200403042000114400008FE
-:1012D000000000008F43010424020001106200049A
-:1012E000000000008F420264104000060000000071
-:1012F0008EE2017C24420001AEE2017C080014C5AC
-:101300008EE2017C8F82004434420004AF820044AC
-:101310008EE2017824420001AEE201788EE201788B
-:101320008F8200D88F8300D400431023AEE2726C0A
-:101330008EE2726C1C4000033C030001004310214C
-:10134000AEE2726C0C004064000000000C004440EF
-:10135000AF8002288FBF00248FB0002003E0000878
-:1013600027BD002803E000080000000003E000089B
-:101370000000000000000000000000002402002C1B
-:10138000AF820050AEE072748F420238AEE27278E3
-:101390008F82005424420067AF820058AEE07B8801
-:1013A000AEE07B8CAEE07B843C010001003708217D
-:1013B000AC2083BC3C0100010037082103E0000899
-:1013C000A02083B927BDFFD8AFBF0024AFB0002055
-:1013D0008F8200543C0300018C635CD82442006778
-:1013E0001060000DAF8200583C0200010057102130
-:1013F000904283B8104000053C0302003C0100010C
-:101400000037082108001503A02083B88EE20000F1
-:1014100000431025AEE200008F4202183042010066
-:10142000104000C6000000008F8200B0304200046F
-:10143000104000C2000000003C03000100771821AA
-:101440008C6383D08F820104146200B4000000001A
-:101450003C030001007718218C6383D48F8200B491
-:10146000146200AE000000008F8200B03C030080D8
-:10147000004310241040000D000000008F82011C6A
-:1014800034420002AF82011C8F8200B02403FFFBB4
-:1014900000431024AF8200B08F82011C2403FFFDA3
-:1014A00000431024080015CCAF82011C3C0300014E
-:1014B000007718218C6383D08F820104146200822C
-:1014C000000000003C030001007718218C6383D4E6
-:1014D0008F8200B41462007C000000003C07000111
-:1014E00000F738218CE783D08F8200B03C040001E4
-:1014F00024845270AFA00014AFA200108F8600B0F9
-:101500003C0500050C00240334A509008F82011C52
-:1015100034420002AF82011C8F8301048F8200B02D
-:1015200034420001AF8200B0AF8301048F830120F9
-:10153000276238002466002000C2102B50400001B2
-:10154000276630008F82012810C2000400000000CE
-:101550008F82012414C20006000000008EE201A464
-:1015600024420001AEE201A4080015A08EE201A40D
-:101570008F4402088F45020C26E20030AC6200085E
-:1015800024020400A462000E2402000FAC620018C2
-:10159000AC60001CAC640000AC6500048EE204C4C6
-:1015A000AC620010AF86012092E24E20144000375A
-:1015B000000000008EE24E30000210C0244250387D
-:1015C00002E220218C830000240200071462001F25
-:1015D000000000008EE34E308EE24E341062001B9D
-:1015E000240300408C82000424420001AC820004E9
-:1015F0008EE24E348EE54E30244200011043000747
-:10160000000000008EE24E342442000110A20005CA
-:10161000000000000800158A0000000014A000056A
-:10162000000000008F82012824420020AF820128A0
-:101630008F8201288C8200042C420011504000133C
-:10164000AC800000080015A0000000008EE24E30C3
-:1016500024030040244200015043000300001021F5
-:101660008EE24E3024420001AEE24E308EE24E3029
-:10167000000210C02442503802E220212402000758
-:10168000AC82000024020001AC8200048F82011CA5
-:101690002403FFFD00431024AF82011C8EE201E40D
-:1016A0003C07000100F738218CE783D02442000179
-:1016B000AEE201E48EE201E43C0400012484527CA9
-:1016C000080015BDAFA000108F8201043C0100018D
-:1016D00000370821AC2283D08F8200B43C07000180
-:1016E00000F738218CE783D03C0400012484528425
-:1016F0003C01000100370821AC2283D4AFA00010C8
-:10170000AFA000148F8600B03C0500050C00240338
-:1017100034A50900080015CC000000008F820104E8
-:101720003C01000100370821AC2283D08F8200B435
-:101730003C01000100370821AC2283D48EE2727490
-:1017400092E304F42442006714600006AEE272746F
-:101750008EE272748F4302340043102B1440007BDE
-:10176000000000008EE304E48EE204F8146200043A
-:101770000000000092E204F450400074A2E004F47F
-:101780008F830120276238002466002000C2102BBE
-:1017900050400001276630008F82012810C20004EB
-:1017A000000000008F82012414C200070000000026
-:1017B0008EE201A40000802124420001AEE201A4D7
-:1017C000080016378EE201A48EE204E4AC62001C2D
-:1017D0008EE404B08EE504B42462001CAC62000800
-:1017E00024020008A462000E24020011AC6200185A
-:1017F000AC640000AC6500048EE204C4AC6200106E
-:10180000AF86012092E24E201440003724100001E0
-:101810008EE24E30000210C02442503802E22021F5
-:101820008C830000240200121462001F00000000DC
-:101830008EE34E308EE24E341062001B24030040D3
-:101840008C82000424420001AC8200048EE24E34FB
-:101850008EE54E30244200011043000700000000D6
-:101860008EE24E342442000110A200050000000068
-:10187000080016210000000014A000050000000070
-:101880008F82012824420020AF8201288F82012804
-:101890008C8200042C42001150400013AC800000E8
-:1018A00008001637000000008EE24E30240300408E
-:1018B0002442000150430003000010218EE24E300C
-:1018C00024420001AEE24E308EE24E30000210C0E3
-:1018D0002442503802E2202124020012AC8200008F
-:1018E00024020001AC8200045600000B2410000109
-:1018F0008EE204E43C0400012484528CAFA0001466
-:10190000AFA200108EE606088F4702283C050009AA
-:101910000C00240334A5F006160000032402000185
-:1019200008001650A2E204F48EE201702442000185
-:10193000AEE201708EE201708EE204E4A2E004F4F3
-:10194000AEE004F0AEE07274AEE204F88EE20E1C7B
-:101950001040006D000000008F83012027623800D6
-:101960002466002000C2102B504000012766300082
-:101970008F82012810C20004000000008F82012421
-:1019800014C20007000000008EE201A400008021C4
-:1019900024420001AEE201A4080016AD8EE201A4CB
-:1019A0008EE2724CAC62001C8EE404A88EE504AC9E
-:1019B0002462001CAC62000824020008A462000E2D
-:1019C00024020011AC620018AC640000AC65000495
-:1019D0008EE204C4AC620010AF86012092E24E2079
-:1019E00014400037241000018EE24E30000210C077
-:1019F0002442503802E220218C830000240200128D
-:101A00001462001F000000008EE34E308EE24E3460
-:101A10001062001B240300408C8200042442000159
-:101A2000AC8200048EE24E348EE54E30244200013A
-:101A300010430007000000008EE24E3424420001F3
-:101A400010A200050000000008001697000000002A
-:101A500014A00005000000008F820128244200200D
-:101A6000AF8201288F8201288C8200042C42001151
-:101A700050400013AC800000080016AD00000000CC
-:101A80008EE24E3024030040244200015043000304
-:101A9000000010218EE24E3024420001AEE24E30B2
-:101AA0008EE24E30000210C02442503802E2202163
-:101AB00024020012AC82000024020001AC82000467
-:101AC0005600000B241000018EE2724C3C04000111
-:101AD00024845298AFA00014AFA200108EE6724C7E
-:101AE0008F4702803C0500090C00240334A5F00850
-:101AF00056000001AEE00E1C8EE20174244200018B
-:101B0000AEE201748EE201748EE24E2410400019A0
-:101B100000000000AEE04E248F8200403042000101
-:101B200014400008000000008F430104240200015B
-:101B300010620004000000008F42026410400006A2
-:101B4000000000008EE2017C24420001AEE2017C34
-:101B5000080016DA8EE2017C8F82004434420004D1
-:101B6000AF8200448EE2017824420001AEE20178A7
-:101B70008EE201788EE272782442FF99AEE27278AA
-:101B80008EE272781C4002AD000000008F420238E5
-:101B9000104002AA000000003C0200010057102182
-:101BA000904283E0144002A5000000008F420080B4
-:101BB000AEE2004C8F4200C0AEE200488F4200848B
-:101BC000AEE200388F420084AEE202448F420088C9
-:101BD000AEE202488F42008CAEE2024C8F4200908F
-:101BE000AEE202508F420094AEE202548F4200985F
-:101BF000AEE202588F42009CAEE2025C8F4200A02F
-:101C0000AEE202608F4200A4AEE202648F4200A8FE
-:101C1000AEE202688F4200ACAEE2026C8F4200B0CE
-:101C2000AEE202708F4200B4AEE202748F4200B89E
-:101C3000AEE202788F4200BC24040001AEE2027CD6
-:101C4000AEE0003C00041080005710218EE3003C01
-:101C50008C42024424840001006218212C82000F6F
-:101C6000AEE3003C1440FFF8000410808F4200CC2B
-:101C7000AEE200508F4200D0AEE200548F830120CC
-:101C8000276238002466002000C2102B504000015B
-:101C9000276630008F82012810C200040000000077
-:101CA0008F82012414C20007000000008EE201A40C
-:101CB0000000802124420001AEE201A40800177553
-:101CC0008EE201A48F4402088F45020C26E2003008
-:101CD000AC62000824020400A462000E2402000F7B
-:101CE000AC620018AC60001CAC640000AC65000481
-:101CF0008EE204C4AC620010AF86012092E24E2056
-:101D000014400037241000018EE24E30000210C053
-:101D10002442503802E220218C8300002402000774
-:101D20001462001F000000008EE34E308EE24E343D
-:101D30001062001B240300408C8200042442000136
-:101D4000AC8200048EE24E348EE54E302442000117
-:101D500010430007000000008EE24E3424420001D0
-:101D600010A20005000000000800175F000000003E
-:101D700014A00005000000008F82012824420020EA
-:101D8000AF8201288F8201288C8200042C4200112E
-:101D900050400013AC8000000800177500000000E0
-:101DA0008EE24E30240300402442000150430003E1
-:101DB000000010218EE24E3024420001AEE24E308F
-:101DC0008EE24E30000210C02442503802E2202140
-:101DD00024020007AC82000024020001AC8200044F
-:101DE000120002123C020400AFA200183C020001E3
-:101DF00000571021904283B01040010B00000000FA
-:101E00008EE206088F43022824420001304A00FF78
-:101E1000514300FDAFA000108EE20608000210C082
-:101E2000005710218FA300188FA4001CAC43060C90
-:101E3000AC4406108F8300548F8200542469003212
-:101E4000012210232C4200331040006A0000582168
-:101E500024180008240F000D240D0007240C004056
-:101E6000240E00018F8701202762380024E800201B
-:101E70000102102B50400001276830008F8201289A
-:101E800011020004000000008F82012415020007E7
-:101E9000000010218EE201A40000802124420001F4
-:101EA000AEE201A4080017F38EE201A48EE4060856
-:101EB000000420C0008018218EE404308EE5043434
-:101EC00000A3282100A3302B00822021008620219E
-:101ED000ACE40000ACE500048EE20608A4F8000EB5
-:101EE000ACEF0018ACEA001C000210C02442060C43
-:101EF00002E21021ACE200088EE204C4ACE2001061
-:101F0000AF88012092E24E201440003324100001DB
-:101F10008EE24E30000210C02442503802E22021EE
-:101F20008C820000144D001F000000008EE34E3034
-:101F30008EE24E341062001B000000008C82000410
-:101F400024420001AC8200048EE24E348EE34E3017
-:101F500024420001104C0007000000008EE24E34C5
-:101F6000244200011062000500000000080017E094
-:101F70000000000014600005000000008F820128AE
-:101F800024420020AF8201288F8201288C82000425
-:101F90002C42001150400010AC800000080017F3E4
-:101FA000000000008EE24E3024420001504C00033D
-:101FB000000010218EE24E3024420001AEE24E308D
-:101FC0008EE24E30000210C02442503802E220213E
-:101FD000AC8D0000AC8E000456000006240B0001FE
-:101FE0008F820054012210232C4200331440FF9DA5
-:101FF00000000000316300FF24020001146200773A
-:102000003C050009AEEA06088F8300548F82005415
-:1020100024690032012210232C4200331040006159
-:1020200000005821240D0008240C0011240800127F
-:1020300024070040240A00018F8301202762380012
-:102040002466002000C2102B50400001276630009B
-:102050008F82012810C20004000000008F8201243A
-:1020600014C20007000000008EE201A400008021DD
-:1020700024420001AEE201A40800185F8EE201A430
-:102080008EE20608AC62001C8EE404A08EE504A477
-:102090002462001CAC620008A46D000EAC6C001839
-:1020A000AC640000AC6500048EE204C4AC620010B5
-:1020B000AF86012092E24E2014400033241000012C
-:1020C0008EE24E30000210C02442503802E220213D
-:1020D0008C8200001448001F000000008EE34E3088
-:1020E0008EE24E341062001B000000008C8200045F
-:1020F00024420001AC8200048EE24E348EE34E3066
-:102100002442000110470007000000008EE24E3418
-:102110002442000110620005000000000800184C75
-:102120000000000014600005000000008F820128FC
-:1021300024420020AF8201288F8201288C82000473
-:102140002C42001150400010AC8000000800185FC5
-:10215000000000008EE24E30244200015047000390
-:10216000000010218EE24E3024420001AEE24E30DB
-:102170008EE24E30000210C02442503802E220218C
-:10218000AC880000AC8A000456000006240B000155
-:102190008F820054012210232C4200331440FFA6EA
-:1021A00000000000316300FF2402000114620003FC
-:1021B0003C0500090800197C241000013C040001C2
-:1021C000248452A4AFA00010AFA000148F86012079
-:1021D0008F8701240800187B34A5F0113C0400010E
-:1021E000248452B0AFA00010AFA000148F8601204D
-:1021F0008F87012434A5F0100C00240300008021F7
-:102200000800197C000000003C040001248452BC3A
-:10221000AFA000148EE606088F4702283C0500098F
-:102220000800197534A5F00F8EE206088F430228C6
-:1022300024420001304900FF512300E2AFA000100A
-:102240008EE20608000210C0005710218FA300186C
-:102250008FA4001CAC43060CAC4406108F870120F1
-:102260002762380024E800200102102B50400001B2
-:10227000276830008F82012811020004000000004E
-:102280008F82012415020007000010218EE201A4B4
-:102290000000802124420001AEE201A4080018F7EA
-:1022A0008EE201A48EE40608000420C000801821FC
-:1022B0008EE404308EE5043400A3282100A3302BE3
-:1022C0000082202100862021ACE40000ACE500045F
-:1022D0008EE3060824020008A4E2000E2402000D8A
-:1022E000ACE20018ACE9001C000318C02463060C23
-:1022F00002E31021ACE200088EE204C4ACE200105C
-:10230000AF88012092E24E201440003724100001D3
-:102310008EE24E30000210C02442503802E22021EA
-:102320008C830000240200071462001F00000000DC
-:102330008EE34E308EE24E341062001B24030040C8
-:102340008C82000424420001AC8200048EE24E34F0
-:102350008EE54E30244200011043000700000000CB
-:102360008EE24E342442000110A20005000000005D
-:10237000080018E10000000014A0000500000000A3
-:102380008F82012824420020AF8201288F820128F9
-:102390008C8200042C42001150400013AC800000DD
-:1023A000080018F7000000008EE24E3024030040C1
-:1023B0002442000150430003000010218EE24E3001
-:1023C00024420001AEE24E308EE24E30000210C0D8
-:1023D0002442503802E2202124020007AC8200008F
-:1023E00024020001AC8200045600000CAEE906088D
-:1023F0003C040001248452C8AFA00010AFA0001418
-:102400008EE606088F4702283C0500090C002403CD
-:1024100034A5F0000800197C000000008F83012023
-:10242000276238002466002000C2102B50400001B3
-:10243000276630008F82012810C2000400000000CF
-:102440008F82012414C20007000000008EE201A464
-:102450000000802124420001AEE201A40800195EC0
-:102460008EE201A48EE20608AC62001C8EE404A099
-:102470008EE504A42462001CAC620008240200085B
-:10248000A462000E24020011AC620018AC640000CB
-:10249000AC6500048EE204C4AC620010AF8601207B
-:1024A00092E24E2014400037241000018EE24E309C
-:1024B000000210C02442503802E220218C83000028
-:1024C000240200121462001F000000008EE34E3050
-:1024D0008EE24E341062001B240300408C82000404
-:1024E00024420001AC8200048EE24E348EE54E3070
-:1024F0002442000110430007000000008EE24E3429
-:102500002442000110A20005000000000800194844
-:102510000000000014A00005000000008F820128C8
-:1025200024420020AF8201288F8201288C8200047F
-:102530002C42001150400013AC8000000800195ECE
-:10254000000000008EE24E302403004024420001CF
-:1025500050430003000010218EE24E30244200015F
-:10256000AEE24E308EE24E30000210C024425038AF
-:1025700002E2202124020012AC82000024020001A9
-:10258000AC8200045600001D241000013C04000130
-:10259000248452D0AFA00010AFA000148EE606082D
-:1025A0008F4702283C0500090C00240334A5F001E4
-:1025B0008EE201B024420001AEE201B00800197CB5
-:1025C0008EE201B03C040001248452DCAFA0001470
-:1025D0008EE606088F4702283C05000934A5F00561
-:1025E0000C002403000000008EE201AC00008021FA
-:1025F00024420001AEE201AC8EE201AC1200000CFC
-:10260000240200013C01000100370821A02083B012
-:102610008F4202388EE3015824630001AEE3015873
-:102620008EE301580800198CAEE272782402000192
-:102630003C01000100370821A02283B03C020001C8
-:102640008C425CD810400187000000008EE27B8441
-:1026500024430001284200C9144001A4AEE37B8456
-:102660008EE204D43042000214400119AEE07B84B3
-:102670008EE204D43C0306003463100034420002AE
-:10268000AEE204D4AFA300188EE206088F430228FE
-:1026900024420001304A00FF514300FDAFA000106A
-:1026A0008EE20608000210C0005710218FA3001808
-:1026B0008FA4001CAC43060CAC4406108F8300545E
-:1026C0008F82005424690032012210232C420033EF
-:1026D0001040006A0000582124180008240F000D43
-:1026E000240D0007240C0040240E00018F870120D8
-:1026F0002762380024E800200102102B504000011E
-:10270000276830008F8201281102000400000000B9
-:102710008F82012415020007000010218EE201A41F
-:102720000000802124420001AEE201A408001A1535
-:102730008EE201A48EE40608000420C00080182167
-:102740008EE404308EE5043400A3282100A3302B4E
-:102750000082202100862021ACE40000ACE50004CA
-:102760008EE20608A4F8000EACEF0018ACEA001CDC
-:10277000000210C02442060C02E21021ACE2000864
-:102780008EE204C4ACE20010AF88012092E24E2039
-:1027900014400033241000018EE24E30000210C0BD
-:1027A0002442503802E220218C820000144D001F88
-:1027B000000000008EE34E308EE24E341062001BAB
-:1027C000000000008C82000424420001AC8200045E
-:1027D0008EE24E348EE34E3024420001104C00074E
-:1027E000000000008EE24E34244200011062000519
-:1027F0000000000008001A0200000000146000053C
-:10280000000000008F82012824420020AF820128AE
-:102810008F8201288C8200042C420011504000104D
-:10282000AC80000008001A15000000008EE24E3057
-:1028300024420001504C0003000010218EE24E3073
-:1028400024420001AEE24E308EE24E30000210C053
-:102850002442503802E22021AC8D0000AC8E0004EE
-:1028600056000006240B00018F8200540122102321
-:102870002C4200331440FF9D00000000316300FF34
-:102880002402000154620078AFA00010AEEA0608EE
-:102890008F8300548F820054246900320122102358
-:1028A0002C4200331040006100005821240D000824
-:1028B000240C00112408001224070040240A0001FF
-:1028C0008F830120276238002466002000C2102B6D
-:1028D00050400001276630008F82012810C200049A
-:1028E000000000008F82012414C2000700000000D5
-:1028F0008EE201A40000802124420001AEE201A486
-:1029000008001A818EE201A48EE20608AC62001C67
-:102910008EE404A08EE504A42462001CAC620008CE
-:10292000A46D000EAC6C0018AC640000AC65000433
-:102930008EE204C4AC620010AF86012092E24E2009
-:1029400014400033241000018EE24E30000210C00B
-:102950002442503802E220218C8200001448001FDB
-:10296000000000008EE34E308EE24E341062001BF9
-:10297000000000008C82000424420001AC820004AC
-:102980008EE24E348EE34E302442000110470007A1
-:10299000000000008EE24E34244200011062000567
-:1029A0000000000008001A6E00000000146000051E
-:1029B000000000008F82012824420020AF820128FD
-:1029C0008F8201288C8200042C420011504000109C
-:1029D000AC80000008001A81000000008EE24E303A
-:1029E0002442000150470003000010218EE24E30C7
-:1029F00024420001AEE24E308EE24E30000210C0A2
-:102A00002442503802E22021AC880000AC8A000445
-:102A100056000006240B00018F820054012210236F
-:102A20002C4200331440FFA600000000316300FF79
-:102A30002402000110620022000000003C0400019A
-:102A4000248452A4AFA00010AFA000148F860120F0
-:102A50008F8701243C0500090C00240334A5F011E4
-:102A600008001AAD000000003C040001248452B0AC
-:102A7000AFA000148F8601208F8701243C05000938
-:102A80000C00240334A5F01008001AAD000000006B
-:102A90003C040001248452BCAFA000148EE606085A
-:102AA0008F4702283C0500090C00240334A5F00FD1
-:102AB0008EE201AC24420001AEE201AC8EE201AC38
-:102AC0008EE2015C24420001AEE2015C8EE2015C18
-:102AD0008EE204D430420001104000550000000096
-:102AE0008F42021830420080104000290000000090
-:102AF0008F82004434420040AF8200448EE27B7CEF
-:102B0000004028218EE200C08EE300C424060000AD
-:102B10002407FFFF00002021004610241444000D6C
-:102B2000006718241465000B000000008EE27B8013
-:102B3000004028218EE200E08EE300E40000202126
-:102B40000046102414440003006718241065000B8D
-:102B5000000000008EE200C08EE300C48EE400E0BE
-:102B60008EE500E4AEE37B7CAEE57B808F820044A3
-:102B70003842002008001B38AF8200448F82004496
-:102B80002403FFDF0043102408001B38AF820044F9
-:102B90008F8200442403FFDF00431024AF820044EF
-:102BA0008EE27B7C004028218EE200C08EE300C4D0
-:102BB000240600002407FFFF000020210046102407
-:102BC0001444000D006718241465000B0000000079
-:102BD0008EE27B80004028218EE200E08EE300E45C
-:102BE000000020210046102414440003006718242C
-:102BF0001065000B000000008EE200C08EE300C4F0
-:102C00008EE400E08EE500E4AEE37B7CAEE57B8005
-:102C10008F8200443842004008001B38AF820044D5
-:102C20008F8200443442004008001B38AF820044C9
-:102C30008F82004434420040AF8200448EE27B8C9D
-:102C4000244300012842001514400028AEE37B8C89
-:102C50008F82004438420020AF82004408001B38B5
-:102C6000AEE07B8C8EE204D43042000110400011B3
-:102C7000000000008F42021830420080104000091E
-:102C8000000000008F82004434420020AF820044E4
-:102C90008F8200442403FFBF0043102408001B362A
-:102CA000AF8200448F8200443442006008001B362B
-:102CB000AF8200448F82004434420040AF8200441F
-:102CC0008EE27B88244300012842138914400005CA
-:102CD000AEE37B888F82004438420020AF820044FC
-:102CE000AEE07B880C004603000000008FBF00248C
-:102CF0008FB0002003E0000827BD002827BDFFB8E3
-:102D0000AFBF0044AFB60040AFB5003CAFB4003831
-:102D1000AFB30034AFB20030AFB1002CAFB0002879
-:102D20008F96006432C200041040000C240200049C
-:102D3000AF8200648F420114AEE204E08F82006033
-:102D400034420008AF8200608EE2016C2442000130
-:102D5000AEE2016C080022F48EE2016C32C2000186
-:102D60001040000424020001AF820064080022F435
-:102D70000000000032C200021440000C3C050003B9
-:102D80003C0400012484535434A5000102C03021C6
-:102D900000003821AFA000100C002403AFA00014E5
-:102DA0002402FFF8080022F4AF8200648F43022C53
-:102DB0008F42010C5062000CAFA000108F42022C19
-:102DC00000021080005A10218C420300AFA20020A4
-:102DD0008F42022C24070001244200013042003FB0
-:102DE00008001B80AF42022C3C0400012484536085
-:102DF000AFA000148F46022C8F47010C3C05000346
-:102E00000C00240334A5F01F0000382114E0000357
-:102E100000000000080022EDAF96006493A200209D
-:102E20002443FFFF2C62001110400658000310805D
-:102E30003C010001002208218C22541800400008A7
-:102E4000000000008FA2002030420FFFAEE20E0C07
-:102E50008F82006034420200AF8200608EE201186F
-:102E600024420001AEE20118080022E88EE20118B7
-:102E70008FA20020240300013C010001003708213B
-:102E8000A02383B130420FFFAEE252388F82006040
-:102E900034420100AF8200608EE20144244200010E
-:102EA000AEE20144080022E88EE201448FA2002035
-:102EB0000002120000022502240200011082000517
-:102EC00024020002108200092402FFFE08001BC930
-:102ED000AFA000108EE204D4AEE40070AEE4007443
-:102EE0003442000108001BBDAEE204D48EE304D4DA
-:102EF000AEE40070AEE4007400621824AEE304D4C3
-:102F00008F8400540004144200041C8200431021EA
-:102F100000041CC20043102300041D0200431021C2
-:102F200000041D420043102308001BD0AEE20078CD
-:102F30003C0400012484536CAFA000148FA6002031
-:102F40003C0500030C00240334A500048EE20110AC
-:102F500024420001AEE20110080022E88EE20110D6
-:102F6000274402120C0022FE240500063049001FEF
-:102F7000000920C002E410219442727C30424000DB
-:102F80001040000A0097102197430212A443727E5A
-:102F90008F43021400971021AC43728002E4182181
-:102FA0003402800008001C79A462727C9443727E13
-:102FB000974202121462000602E4102100971021C9
-:102FC0008C4372808F4202141062009F02E4102131
-:102FD0009442727C304280001040002A2406FFFF99
-:102FE00000002021000410C002E210219442737CF2
-:102FF000304240005440000500803021248400010C
-:103000002C8200801440FFF8000410C004C100109E
-:10301000000618C0000610C0005718218C63737C8E
-:1030200000571021AFA300108C4273803C040001B4
-:1030300024845378AFA200148F4702143C05000388
-:103040000C00240334A5001308001C903C02080067
-:103050009744021200771021A444737E8F44021417
-:103060000077102102E31821AC4473803402800001
-:10307000A462737C000910C002E2102108001C79D0
-:10308000A446727C02E410219445727C08001C2E38
-:10309000000510C09443737E97420212146200062A
-:1030A000000510C0009710218C4373808F420214DA
-:1030B00010620065000510C002E210219445737C87
-:1030C000000510C002E210219442737C304280005F
-:1030D0001040FFF000971021000520C0009710213C
-:1030E0009443737E97420212146200062406FFFF87
-:1030F000009710218C4373808F420214106200539A
-:103100003C02080000002021000410C002E210214F
-:103110009442737C304240005440000500803021CE
-:10312000248400012C8200801440FFF8000410C0A9
-:1031300004C10023000618C0000910C00057182160
-:103140008C63727C00571021AFA300108C427280F8
-:103150003C04000124845384AFA200148F4702145E
-:103160003C0500030C00240334A5F01708001C9054
-:103170003C0208008F43021000B71021AC43777C5B
-:103180008F43021400B71021AC4377803C0200014A
-:10319000005710218C4283B4244200013C010001FD
-:1031A00000370821AC2283B43C03000100771821CA
-:1031B0008C6383B402E5102108001C82A443777C51
-:1031C0009744021200771021A444737E8F440214A6
-:1031D0000077102102E31821AC4473803402800090
-:1031E000A462737C000510C002E21021A446737C27
-:1031F00000002021000428C002E510219442777CC1
-:103200001040FFDC248400012C8200805440FFFA2F
-:10321000000428C092E204D81040000624020001F5
-:103220008EE304DC012210040062182508001C8FC4
-:10323000AEE304DC8F830228240200010122100483
-:1032400000621825AF8302283C02080034421000B7
-:10325000AFA200188EE206088F4302282442000124
-:10326000304A00FF514300FDAFA000108EE2060877
-:10327000000210C0005710218FA300188FA4001C5B
-:10328000AC43060CAC4406108F8300548F8200546C
-:1032900024690032012210232C4200331040006ABE
-:1032A0000000582124100008240F000D240D0007F1
-:1032B000240C0040240E00018F8701202762380073
-:1032C00024E800200102102B504000012768300044
-:1032D0008F82012811020004000000008F82012467
-:1032E00015020007000010218EE201A40000382121
-:1032F00024420001AEE201A408001D088EE201A4F0
-:103300008EE40608000420C0008018218EE40430FA
-:103310008EE5043400A3282100A3302B0082202155
-:1033200000862021ACE40000ACE500048EE2060833
-:10333000A4F0000EACEF0018ACEA001C000210C0B4
-:103340002442060C02E21021ACE200088EE204C422
-:10335000ACE20010AF88012092E24E20144000330E
-:10336000240700018EE24E30000210C02442503883
-:1033700002E220218C820000144D001F000000009A
-:103380008EE34E308EE24E341062001B00000000CF
-:103390008C82000424420001AC8200048EE24E3490
-:1033A0008EE34E3024420001104C00070000000064
-:1033B0008EE24E342442000110620005000000003D
-:1033C00008001CF50000000014600005000000006B
-:1033D0008F82012824420020AF8201288F82012899
-:1033E0008C8200042C42001150400010AC80000080
-:1033F00008001D08000000008EE24E30244200014B
-:10340000504C0003000010218EE24E302442000197
-:10341000AEE24E308EE24E30000210C024425038F0
-:1034200002E22021AC8D0000AC8E000454E00006C6
-:10343000240B00018F820054012210232C42003300
-:103440001440FF9D00000000316300FF24020001D2
-:1034500054620078AFA00010AEEA06088F830054D3
-:103460008F82005424690032012210232C42003341
-:103470001040006100005821240E0008240D0011A6
-:10348000240A001224080040240C00018F8301202C
-:10349000276238002466002000C2102B5040000133
-:1034A000276630008F82012810C20004000000004F
-:1034B0008F82012414C20007000000008EE201A4E4
-:1034C0000000382124420001AEE201A408001D746E
-:1034D0008EE201A48EE20608AC62001C8EE404A019
-:1034E0008EE504A42462001CAC620008A46E000EE9
-:1034F000AC6D0018AC640000AC6500048EE204C43E
-:10350000AC620010AF86012092E24E2014400033DE
-:10351000240700018EE24E30000210C024425038D1
-:1035200002E220218C820000144A001F00000000EB
-:103530008EE34E308EE24E341062001B000000001D
-:103540008C82000424420001AC8200048EE24E34DE
-:103550008EE34E30244200011048000700000000B6
-:103560008EE24E342442000110620005000000008B
-:1035700008001D610000000014600005000000004C
-:103580008F82012824420020AF8201288F820128E7
-:103590008C8200042C42001150400010AC800000CE
-:1035A00008001D74000000008EE24E30244200012D
-:1035B00050480003000010218EE24E3024420001EA
-:1035C000AEE24E308EE24E30000210C0244250383F
-:1035D00002E22021AC8A0000AC8C000454E000061A
-:1035E000240B00018F820054012210232C4200334F
-:1035F0001440FFA600000000316300FF2402000118
-:1036000010620022000000003C040001248453905A
-:10361000AFA00010AFA000148F8601208F87012477
-:103620003C0500090C00240334A5F01108001DA07E
-:10363000000000003C0400012484539CAFA000144F
-:103640008F8601208F8701243C0500090C0024038C
-:1036500034A5F01008001DA0000000003C0400018B
-:10366000248453A8AFA000148EE606088F470228D2
-:103670003C0500090C00240334A5F00F8EE201ACD8
-:1036800024420001AEE201AC8EE201AC8EE20124E4
-:1036900024420001AEE2012408001F978EE20124BB
-:1036A000274402120C0022FE240500063049001FA8
-:1036B000000928C002E510219442727C304280004B
-:1036C0001040002F02E510219442727C30424000ED
-:1036D0001440001C00B710219443727E97420212DE
-:1036E0001462001800B710218C4372808F420214BC
-:1036F00054620016AFA2001092E204D810400007F6
-:10370000240200018EE304DC0122100400021027D1
-:103710000062182408001DC9AEE304DC8F83022870
-:10372000012210040002102700621824AF8302282F
-:10373000000910C002E218213402C00008001E4E29
-:10374000A462727C8F420214AFA20010000910C064
-:10375000005710218C42727C3C040001248453B435
-:103760003C050003AFA200148F47021034A5F01CE3
-:103770000C0024030120302108001E833C020800B5
-:1037800000B710219443727E97420212146200190E
-:10379000000918C000B710218C4372808F420214B8
-:1037A00014620014000918C002E510219447727CCD
-:1037B000000720C0009710219443737E00B71021AA
-:1037C000A443727E009710218C43738000B71021B0
-:1037D000AC43728002E410219443737C02E5102113
-:1037E000A443727C02E418213402C00008001E4E7B
-:1037F000A462737C02E310219447727C00003021A4
-:10380000000720C002E410219442737C0000402194
-:10381000304280001440002500E028210060502143
-:10382000340BC000009710219443737E974202121C
-:103830005462001500E02821009710218C4373800A
-:103840008F4202145462001000E02821110000068B
-:1038500002E410219443737C000510C002E21021A1
-:1038600008001E1AA443737C9443737C02EA10215F
-:10387000A443727C000710C002E21021A44B737CA9
-:1038800008001E2824060001000510C002E21021D5
-:103890009447737C000720C002E410219442737C9B
-:1038A000304280001040FFDF2508000130C200FFD9
-:1038B0001440002500002021000720C0009710219F
-:1038C0009443737E974202121462000F000910C0E5
-:1038D000009710218C4373808F4202141462000AF7
-:1038E000000910C002E418213402C00015000015C0
-:1038F000A462737C000910C002E218213402800027
-:1039000008001E4EA462727C005710218C42727C0B
-:103910003C040001248453C03C050003AFA2001006
-:10392000000710C0005710218C42737C34A5001E84
-:10393000012030210C002403AFA2001408001E83D4
-:103940003C02080000002021000428C000B710211C
-:103950009443777E974202125462002B2484000124
-:1039600000B710218C4377808F42021454620026E6
-:10397000248400013C020001005710218C4283B4D2
-:103980002442FFFF3C01000100370821AC2283B430
-:103990003C020001005710218C4283B4008090212A
-:1039A0000242102B1040000E24B1777C24B07784A3
-:1039B00002F0202102F128210C00249024060008A6
-:1039C000263100083C020001005710218C4283B4CC
-:1039D000265200010242102B1440FFF52610000869
-:1039E0003C040001009720218C8483B42405000846
-:1039F000000420C02484777C0C00248802E4202169
-:103A000008001E833C0208002C8200801440FFCF77
-:103A1000000428C03C02080034422000AFA2001875
-:103A20008EE206088F43022824420001304A00FF3C
-:103A3000514300FDAFA000108EE20608000210C046
-:103A4000005710218FA300188FA4001CAC43060C54
-:103A5000AC4406108F8300548F82005424690032D6
-:103A6000012210232C4200331040006A000058212C
-:103A700024100008240F000D240D0007240C004022
-:103A8000240E00018F8701202762380024E80020DF
-:103A90000102102B50400001276830008F8201285E
-:103AA00011020004000000008F82012415020007AB
-:103AB000000010218EE201A4000038212442000100
-:103AC000AEE201A408001EFB8EE201A48EE406080B
-:103AD000000420C0008018218EE404308EE50434F8
-:103AE00000A3282100A3302B008220210086202162
-:103AF000ACE40000ACE500048EE20608A4F0000E81
-:103B0000ACEF0018ACEA001C000210C02442060C06
-:103B100002E21021ACE200088EE204C4ACE2001024
-:103B2000AF88012092E24E201440003324070001A8
-:103B30008EE24E30000210C02442503802E22021B2
-:103B40008C820000144D001F000000008EE34E30F8
-:103B50008EE24E341062001B000000008C820004D4
-:103B600024420001AC8200048EE24E348EE34E30DB
-:103B700024420001104C0007000000008EE24E3489
-:103B800024420001106200050000000008001EE849
-:103B90000000000014600005000000008F82012872
-:103BA00024420020AF8201288F8201288C820004E9
-:103BB0002C42001150400010AC80000008001EFB99
-:103BC000000000008EE24E3024420001504C000301
-:103BD000000010218EE24E3024420001AEE24E3051
-:103BE0008EE24E30000210C02442503802E2202102
-:103BF000AC8D0000AC8E000454E00006240B0001E4
-:103C00008F820054012210232C4200331440FF9D68
-:103C100000000000316300FF2402000154620078BC
-:103C2000AFA00010AEEA06088F8300548F820054C4
-:103C300024690032012210232C420033104000611D
-:103C400000005821240E0008240D0011240A00123F
-:103C500024080040240C00018F83012027623800D3
-:103C60002466002000C2102B50400001276630005F
-:103C70008F82012810C20004000000008F820124FE
-:103C800014C20007000000008EE201A400003821E9
-:103C900024420001AEE201A408001F678EE201A4E5
-:103CA0008EE20608AC62001C8EE404A08EE504A43B
-:103CB0002462001CAC620008A46E000EAC6D0018FB
-:103CC000AC640000AC6500048EE204C4AC62001079
-:103CD000AF86012092E24E201440003324070001F9
-:103CE0008EE24E30000210C02442503802E2202101
-:103CF0008C820000144A001F000000008EE34E304A
-:103D00008EE24E341062001B000000008C82000422
-:103D100024420001AC8200048EE24E348EE34E3029
-:103D20002442000110480007000000008EE24E34DB
-:103D300024420001106200050000000008001F542A
-:103D40000000000014600005000000008F820128C0
-:103D500024420020AF8201288F8201288C82000437
-:103D60002C42001150400010AC80000008001F677A
-:103D7000000000008EE24E30244200015048000353
-:103D8000000010218EE24E3024420001AEE24E309F
-:103D90008EE24E30000210C02442503802E2202150
-:103DA000AC8A0000AC8C000454E00006240B000137
-:103DB0008F820054012210232C4200331440FFA6AE
-:103DC00000000000316300FF2402000110620022A5
-:103DD000000000003C04000124845390AFA00010B8
-:103DE000AFA000148F8601208F8701243C050009B5
-:103DF0000C00240334A5F01108001F9300000000FC
-:103E00003C0400012484539CAFA000148F86012041
-:103E10008F8701243C0500090C00240334A5F01011
-:103E200008001F93000000003C040001248453A8F4
-:103E3000AFA000148EE606088F4702283C05000953
-:103E40000C00240334A5F00F8EE201AC24420001E3
-:103E5000AEE201AC8EE201AC8EE201282442000108
-:103E6000AEE201288EE201288EE2016424420001C4
-:103E7000AEE20164080022E88EE201648FA2002015
-:103E80000002120000021D0224020001106200055F
-:103E9000240200021062000D0000000008001FB79D
-:103EA000AFA0001092E204D81440000624020001E2
-:103EB0008F820228AEE204DC2402FFFFAF820228D8
-:103EC0002402000108001FBEA2E204D892E204D836
-:103ED0005040000CA2E004D88EE204DCAF8202283D
-:103EE00008001FBEA2E004D83C040001248453C88B
-:103EF000AFA000148FA600203C0500030C00240393
-:103F000034A5F0098EE2013C24420001AEE2013CFE
-:103F1000080022E88EE2013C8FA20020000212007D
-:103F20000002250224020001108200052402000282
-:103F30001082000F0000000008001FE3AFA0001077
-:103F40008F8202203C0308FF3463FFFF00431024EC
-:103F500034420008AF820220240200013C0100012B
-:103F600000370821A02283B208001FEAAEE401084E
-:103F70008F8202203C0308FF3463FFF700431024C4
-:103F8000AF8202203C01000100370821A02083B24B
-:103F900008001FEAAEE401083C040001248453D465
-:103FA000AFA000148FA600203C0500030C002403E2
-:103FB00034A5F00A8EE2012C24420001AEE2012C6D
-:103FC000080022E88EE2012C8FA2002000021200DD
-:103FD00000021D02240200011062000524020002FA
-:103FE0001062000E0000000008002011AFA00010B9
-:103FF0008F8202203C0308FF3463FFFF004310243C
-:1040000034420008AF820220240200013C0100017A
-:104010000037082108002018A02283B33C020001C9
-:1040200000571021904283B23C0100010037082163
-:104030001440000EA02083B38F8202203C0308FFAF
-:104040003463FFF70043102408002018AF820220D9
-:104050003C040001248453E0AFA000148FA600208C
-:104060003C0500030C00240334A5F00B8EE2011480
-:1040700024420001AEE20114080022E88EE201149D
-:1040800027840208274502000C00249A2406000811
-:1040900026E40094274502000C00249A2406000818
-:1040A0008EE2013424420001AEE20134080022E82D
-:1040B0008EE201348F460248000020210C00510896
-:1040C000240500048EE2013024420001AEE20130FA
-:1040D000080022E88EE201308EF301CC8EF401D08C
-:1040E0008EF501D88EE2014026E400302442000122
-:1040F000AEE201408EF001408EF100748EF200704D
-:104100000C00248824050400AEF301CCAEF401D0E9
-:10411000AEF501D8AEF00140AEF10074AEF2007021
-:104120008F42025C26E40094AEE200608F4202609F
-:104130002745020024060008AEE2006824020006BB
-:104140000C00249AAEE200643C023B9A3442CA005E
-:10415000AEE2006C240203E8240400022403000100
-:10416000AEE20104AEE40100AEE3010C8F82022056
-:10417000304200081040000400000000AEE30108D7
-:104180000800206100002021AEE401080000202189
-:104190003C0300010064182190635C3002E41021AC
-:1041A00024840001A043009C2C82000F1440FFF8DF
-:1041B000000000008F82004002E4182124840001E6
-:1041C0000002170224420030A062009C02E4102189
-:1041D000080022E8A040009C240200013C010001EC
-:1041E00000370821A02283E0240B040024080014D7
-:1041F000240A0040240900018F8301002762300057
-:104200002466002000C2102B5040000127662800C1
-:104210008F82010810C20004000000008F82010498
-:1042200014C2000726E200308EE201A80000382107
-:1042300024420001AEE201A8080020A88EE201A8F5
-:104240008EE404B88EE504BCAC620008A46B000EDA
-:10425000AC680018AC60001CAC640000AC650004E5
-:104260008EE204CCAC620010AF86010092E204EC56
-:104270001440000E240700018EE24E282442000163
-:10428000504A0003000010218EE24E282442000113
-:10429000AEE24E288EE24E28000210C024424E3874
-:1042A00002E21021AC480000AC49000410E0FFD24B
-:1042B00000000000080022E8000000003C020900A5
-:1042C000AEE05238AEE0523CAEE05240AEE0524476
-:1042D000AEE001D03C01000100370821A02083B1ED
-:1042E000AFA200188EE206088F4302282442000184
-:1042F000304A00FF514300FDAFA000108EE20608D7
-:10430000000210C0005710218FA300188FA4001CBA
-:10431000AC43060CAC4406108F8300548F820054CB
-:1043200024690032012210232C4200331040006A1D
-:104330000000582124100008240F000D240D000750
-:10434000240C0040240E00018F87012027623800D2
-:1043500024E800200102102B5040000127683000A3
-:104360008F82012811020004000000008F820124C6
-:1043700015020007000010218EE201A40000382180
-:1043800024420001AEE201A40800212C8EE201A427
-:104390008EE40608000420C0008018218EE404305A
-:1043A0008EE5043400A3282100A3302B00822021B5
-:1043B00000862021ACE40000ACE500048EE2060893
-:1043C000A4F0000EACEF0018ACEA001C000210C014
-:1043D0002442060C02E21021ACE200088EE204C482
-:1043E000ACE20010AF88012092E24E20144000336E
-:1043F000240700018EE24E30000210C024425038E3
-:1044000002E220218C820000144D001F00000000F9
-:104410008EE34E308EE24E341062001B000000002E
-:104420008C82000424420001AC8200048EE24E34EF
-:104430008EE34E3024420001104C000700000000C3
-:104440008EE24E342442000110620005000000009C
-:1044500008002119000000001460000500000000A1
-:104460008F82012824420020AF8201288F820128F8
-:104470008C8200042C42001150400010AC800000DF
-:104480000800212C000000008EE24E302442000182
-:10449000504C0003000010218EE24E3024420001F7
-:1044A000AEE24E308EE24E30000210C02442503850
-:1044B00002E22021AC8D0000AC8E000454E0000626
-:1044C000240B00018F820054012210232C42003360
-:1044D0001440FF9D00000000316300FF2402000132
-:1044E00054620078AFA00010AEEA06088F83005433
-:1044F0008F82005424690032012210232C420033A1
-:104500001040006100005821240E0008240D001105
-:10451000240A001224080040240C00018F8301208B
-:10452000276238002466002000C2102B5040000192
-:10453000276630008F82012810C2000400000000AE
-:104540008F82012414C20007000000008EE201A443
-:104550000000382124420001AEE201A408002198A5
-:104560008EE201A48EE20608AC62001C8EE404A078
-:104570008EE504A42462001CAC620008A46E000E48
-:10458000AC6D0018AC640000AC6500048EE204C49D
-:10459000AC620010AF86012092E24E20144000333E
-:1045A000240700018EE24E30000210C02442503831
-:1045B00002E220218C820000144A001F000000004B
-:1045C0008EE34E308EE24E341062001B000000007D
-:1045D0008C82000424420001AC8200048EE24E343E
-:1045E0008EE34E3024420001104800070000000016
-:1045F0008EE24E34244200011062000500000000EB
-:104600000800218500000000146000050000000083
-:104610008F82012824420020AF8201288F82012846
-:104620008C8200042C42001150400010AC8000002D
-:1046300008002198000000008EE24E302442000164
-:1046400050480003000010218EE24E302442000149
-:10465000AEE24E308EE24E30000210C0244250389E
-:1046600002E22021AC8A0000AC8C000454E0000679
-:10467000240B00018F820054012210232C420033AE
-:104680001440FFA600000000316300FF2402000177
-:1046900010620022000000003C04000124845390BA
-:1046A000AFA00010AFA000148F8601208F870124D7
-:1046B0003C0500090C00240334A5F011080021C4B6
-:1046C000000000003C0400012484539CAFA00014AF
-:1046D0008F8601208F8701243C0500090C002403EC
-:1046E00034A5F010080021C4000000003C040001C3
-:1046F000248453A8AFA000148EE606088F47022832
-:104700003C0500090C00240334A5F00F8EE201AC37
-:1047100024420001AEE201AC8EE201AC8EE2012047
-:1047200024420001AEE201208EE201208EE2016807
-:1047300024420001AEE20168080022E88EE201682E
-:104740008F42025C26E40094AEE200608F42026079
-:1047500027450200240600080C00249AAEE20068F7
-:104760008F8202203042000814400002240200011F
-:1047700024020002AEE201088EE2011C2442000184
-:10478000AEE2011C080022E88EE2011C3C0400019C
-:10479000248453ECAFA00010AFA000148FA600201B
-:1047A0003C0500030C00240334A5F00F93A2002065
-:1047B0003C0307003463100000431025AFA200182B
-:1047C0008EE206088F43022824420001304900FF90
-:1047D000512300E2AFA000108EE20608000210C0D4
-:1047E000005710218FA300188FA4001CAC43060CA7
-:1047F000AC4406108F8701202762380024E800208F
-:104800000102102B50400001276830008F820128E0
-:1048100011020004000000008F820124150200072D
-:10482000000010218EE201A4000038212442000182
-:10483000AEE201A40800225D8EE201A48EE4060827
-:10484000000420C0008018218EE404308EE504347A
-:1048500000A3282100A3302B0082202100862021E4
-:10486000ACE40000ACE500048EE306082402000876
-:10487000A4E2000E2402000DACE20018ACE9001C1A
-:10488000000318C02463060C02E31021ACE2000808
-:104890008EE204C4ACE20010AF88012092E24E2008
-:1048A00014400037240700018EE24E30000210C091
-:1048B0002442503802E220218C83000024020007A9
-:1048C0001462001F000000008EE34E308EE24E3472
-:1048D0001062001B240300408C820004244200016B
-:1048E000AC8200048EE24E348EE54E30244200014C
-:1048F00010430007000000008EE24E342442000105
-:1049000010A200050000000008002247000000007F
-:1049100014A00005000000008F820128244200201E
-:10492000AF8201288F8201288C8200042C42001162
-:1049300050400013AC8000000800225D0000000021
-:104940008EE24E3024030040244200015043000315
-:10495000000010218EE24E3024420001AEE24E30C3
-:104960008EE24E30000210C02442503802E2202174
-:1049700024020007AC82000024020001AC82000483
-:1049800054E0000CAEE906083C040001248453F412
-:10499000AFA00010AFA000148EE606088F470228D3
-:1049A0003C0500090C00240334A5F000080022E0B7
-:1049B000000000008F830120276238002466002059
-:1049C00000C2102B50400001276630008F82012862
-:1049D00010C20004000000008F82012414C20007EE
-:1049E000000000008EE201A40000382124420001F2
-:1049F000AEE201A4080022C48EE201A48EE2060801
-:104A0000AC62001C8EE404A08EE504A42462001CA9
-:104A1000AC62000824020008A462000E2402001107
-:104A2000AC620018AC640000AC6500048EE204C403
-:104A3000AC620010AF86012092E24E201440003795
-:104A4000240700018EE24E30000210C0244250388C
-:104A500002E220218C830000240200121462001F55
-:104A6000000000008EE34E308EE24E341062001BD8
-:104A7000240300408C82000424420001AC82000424
-:104A80008EE24E348EE54E30244200011043000782
-:104A9000000000008EE24E342442000110A2000506
-:104AA00000000000080022AE0000000014A0000575
-:104AB000000000008F82012824420020AF820128DC
-:104AC0008F8201288C8200042C4200115040001378
-:104AD000AC800000080022C4000000008EE24E30CE
-:104AE0002403004024420001504300030000102131
-:104AF0008EE24E3024420001AEE24E308EE24E3065
-:104B0000000210C02442503802E220212402001288
-:104B1000AC82000024020001AC82000414E0001BFF
-:104B2000000000003C040001248453FCAFA00010EE
-:104B3000AFA000148EE606088F4702283C05000946
-:104B40000C00240334A5F0018EE201B024420001E0
-:104B5000AEE201B0080022E08EE201B03C040001A8
-:104B600024845408AFA000148EE606088F4702285C
-:104B70003C0500090C00240334A5F0058EE201ACCD
-:104B800024420001AEE201AC8EE201AC8EE20150A3
-:104B900024420001AEE201508EE201508EE201603B
-:104BA00024420001AEE201608EE201608F43022CDC
-:104BB0008F42010C1462000924020002AF820064DB
-:104BC0008F82006414400005000000008F43022C17
-:104BD0008F42010C1462F875000000008FBF004482
-:104BE0008FB600408FB5003C8FB400388FB30034CF
-:104BF0008FB200308FB1002C8FB0002803E0000886
-:104C000027BD004827BDFFF82408FFFF10A00014AF
-:104C1000000048213C0AEDB8354A83209087000007
-:104C200024840001000030210107102630420001D9
-:104C30001040000200081842006A18260060402157
-:104C400024C600012CC200081440FFF700073842B8
-:104C5000252900010125102B1440FFF00000000061
-:104C60000100102103E0000827BD000827BDFFE870
-:104C700027642800AFBF00100C0024882405100012
-:104C800024020021AF800100AF800104AF80010841
-:104C9000AF800110AF800114AF800118AF800120F8
-:104CA000AF800124AF800128AF800130AF80013494
-:104CB000AF800138AEE04E28AEE04E2CAEE04E3074
-:104CC000AEE04E34AF82011C8F42021830420040E9
-:104CD00010400004000000008F82011C34420004D8
-:104CE000AF82011C8FBF001003E0000827BD001831
-:104CF00027BDFFE0AFBF00188F820104AFA20010F4
-:104D00008F8201003C050002AFA200148F8600B024
-:104D10008F87011C3C040001248454C00C00240330
-:104D200034A5F0008F8300B03C027F00006218249D
-:104D30003C020400106200290043102B14400008BC
-:104D40003C0220003C020100106200243C020200F0
-:104D50001062001100000000080023740000000031
-:104D6000106200083C0240001462001C00000000B9
-:104D70008EE2019024420001AEE20190080023740B
-:104D80008EE201908EE2018C24420001AEE2018CA1
-:104D9000080023748EE2018C8F82011C34420002D1
-:104DA000AF82011C8F8301048F8200B03442000166
-:104DB000AF8200B0AF8301048F82011C2403FFFD8A
-:104DC00000431024AF82011C8EE201A024420001A6
-:104DD000AEE201A0080023778EE201A08F8200B02E
-:104DE00034420001AF8200B08FBF001803E000081A
-:104DF00027BD002027BDFFE0AFBF001CAFB00018EB
-:104E00008F820120AFA200108F8201243C05000197
-:104E1000AFA200148F8600A08F87011C3C04000104
-:104E2000248454CC0C00240334A5F0008F8300A00C
-:104E30003C027F00006218243C0204001062005310
-:104E4000000080210043102B144000083C04200087
-:104E50003C0201001062004D3C0202001062003A68
-:104E600000000000080023E00000000010640003C0
-:104E70003C02400014620045000000008F8200A048
-:104E80000044102410400006000000008EE201944F
-:104E900024420001AEE20194080023A98EE20194AD
-:104EA0008EE2019824420001AEE201988EE2019860
-:104EB0008F82011C34420002AF82011C8F82011CD0
-:104EC000304202001040001B000000008F8300A051
-:104ED0008F8401248F8200AC14400007240200015B
-:104EE0003C0200013442F0000062102450400001F6
-:104EF00024100001240200011200000DAF8200A066
-:104F00008F8201242442FFE0AF8201248F8201249A
-:104F10008F820124276330000043102B10400005CE
-:104F2000276237E0AF820124080023CA0000000096
-:104F3000AF8401248F82011C2403FFFD0043102451
-:104F4000080023E3AF82011C8F82011C344200025F
-:104F5000AF82011C8F8301248F8200A034420001A4
-:104F6000AF8200A0AF8301248F82011C2403FFFDC8
-:104F700000431024AF82011C8EE2019C24420001F8
-:104F8000AEE2019C080023E38EE2019C8F8200A028
-:104F900034420001AF8200A08FBF001C8FB0001808
-:104FA00003E0000827BD0020000000003C020001D3
-:104FB0008C425C5827BDFFE8AFBF001414400012BC
-:104FC000AFB000103C10000126105DD0020020217F
-:104FD0000C0024882405200026021FE03C0100016B
-:104FE000AC225D943C010001AC225D90AF420250C6
-:104FF00024022000AF500254AF42025824020001A4
-:105000003C010001AC225C588FBF00148FB000102F
-:1050100003E0000827BD00183C0300018C635D9489
-:105020008C8200008FA800108FA90014AC620000D1
-:105030003C0200018C425D948C830004AC4300046C
-:10504000AC4500088F8400542443FFE0AC460010B8
-:10505000AC470014AC480018AC49001C3C010001EE
-:10506000AC235D94AC44000C3C02000124425DD0B2
-:105070000062182B10600005000000003C020001D7
-:105080008C425D903C010001AC225D943C03000128
-:105090008C635D943C0200018C425C40AC62000079
-:1050A0003C0300018C635D943C0200018C425C4037
-:1050B000AC62000403E00008AF4302503C0300016F
-:1050C0008C635D943C0200018C425C4027BDFFD0A4
-:1050D000AFB400208FB40040AFB00010008080213A
-:1050E000AFB500248FB500448FA40048AFB10014C1
-:1050F00000A08821AFBF0028AFB3001CAFB20018DA
-:10510000AC6200003C0500018CA55D943C020001EE
-:105110008C425C4000C0902100E098211080000685
-:10512000ACA2000424A500080C002490240600185A
-:105130000800244E0000000024A400080C0024886D
-:10514000240500183C0200018C425D943C050001DE
-:1051500024A55DD02442FFE03C010001AC225D9417
-:105160000045102B10400005000000003C0200012B
-:105170008C425D903C010001AC225D943C03000137
-:105180008C635D948E020000AC6200003C03000161
-:105190008C635D948E020004AC620004AC71000864
-:1051A0008F8400542462FFE03C010001AC225D9436
-:1051B0000045102BAC720010AC730014AC740018D6
-:1051C000AC75001C10400005AC64000C3C020001F2
-:1051D0008C425D903C010001AC225D943C030001D7
-:1051E0008C635D943C0200018C425C40AC62000028
-:1051F0003C0300018C635D943C0200018C425C40E6
-:10520000AC620004AF4302508FBF00288FB500246A
-:105210008FB400208FB3001C8FB200188FB1001420
-:105220008FB0001003E0000827BD003010A000057B
-:1052300000000000AC80000024A5FFFC14A0FFFDCE
-:105240002484000403E000080000000010C00007F0
-:10525000000000008C8200002484000424C6FFFCAF
-:10526000ACA2000014C0FFFB24A5000403E000086A
-:105270000000000010C00007000000008CA2000029
-:1052800024A5000424C6FFFCAC82000014C0FFFB70
-:105290002484000403E000080000000003E000088C
-:1052A0000000000027BDFFD8AFBF00208EE304E45C
-:1052B0008EE204E010620436000000008EE204E496
-:1052C0008EE304FC00021100006260219587000853
-:1052D0008D8A00008D8B0004958D000A8EE2725C31
-:1052E0008EE3726C30E4FFFF004410210062182B43
-:1052F0001060001531A200048F8200D88EE372582E
-:1053000000431023AEE2726C8EE2726C1C4000030C
-:105310003C03000100431021AEE2726C8EE2725C2D
-:105320008EE3726C004410210062182B106000069E
-:1053300031A200048EE201B824420001AEE201B8BD
-:10534000080028E18EE201B81040024031A20200BC
-:105350001040014D0000482196E2045A30420010EE
-:1053600010400149000000008F84010027623000D6
-:105370002485002000A2102B504000012765280042
-:105380008F82010810A20004000000008F82010437
-:1053900014A200062402000C8EE201A8244200019F
-:1053A000AEE201A80800252C8EE201A8AC8A00001C
-:1053B000AC8B00048EE3726424060005A482000E08
-:1053C000AC860018AC8300088EE204E4AC82001CBA
-:1053D0008EE204C8AC820010AF85010092E204ECBA
-:1053E00014400036240900018EE24E28000210C04D
-:1053F00024424E3802E220218C8200001446001F15
-:10540000000000008EE34E288EE24E2C1062001B3E
-:10541000240300408C82000424420001AC8200047A
-:105420008EE24E2C8EE54E282442000110430007E8
-:10543000000000008EE24E2C2442000110A2000564
-:1054400000000000080025160000000014A0000560
-:10545000000000008F82010824420020AF82010872
-:105460008F8201088C8200042C42001150400013EE
-:10547000AC8000000800252C000000008EE24E28C1
-:105480002403004024420001504300030000102187
-:105490008EE24E2824420001AEE24E288EE24E28D3
-:1054A000000210C024424E3802E2202124020005EE
-:1054B000AC82000024020001AC8200041520000A26
-:1054C0003C040001AFAB00108EE272643C040001AA
-:1054D000248457303C050004AFA200148EE604E497
-:1054E000080028BE34A5F1148EE2726434843800BA
-:1054F00003641821244200100043102B1440007351
-:10550000000000008EE27264244800100364102141
-:105510000102102B144000023C02FFFF0102402157
-:105520008F8501002762300024A6002000C2102BC6
-:1055300050400001276628008F82010810C2000435
-:10554000000000008F82010414C200072563000CD4
-:105550008EE201A80000482124420001AEE201A829
-:10556000080025A08EE201A82C64000C0144102143
-:10557000ACA20000ACA3000424E2FFF4A4A2000E3D
-:1055800024020006ACA80008ACA200188EE204E4D5
-:10559000ACA2001C8EE204C83C03000200431025AC
-:1055A000ACA20010AF86010092E204EC1440003778
-:1055B000240900018EE24E28000210C024424E3819
-:1055C00002E220218C830000240200051462001FE7
-:1055D000000000008EE34E288EE24E2C1062001B6D
-:1055E000240300408C82000424420001AC820004A9
-:1055F0008EE24E2C8EE54E28244200011043000717
-:10560000000000008EE24E2C2442000110A2000592
-:10561000000000000800258A0000000014A000051A
-:10562000000000008F82010824420020AF820108A0
-:105630008F8201088C8200042C420011504000131C
-:10564000AC800000080025A0000000008EE24E287B
-:1056500024030040244200015043000300001021B5
-:105660008EE24E2824420001AEE24E288EE24E2801
-:10567000000210C024424E3802E22021240200051C
-:10568000AC82000024020001AC8200041520000A54
-:105690002508FFFCAFAB00108EE272643C040001F1
-:1056A000248457303C050004AFA200148EE604E4C5
-:1056B000080028BE34A5F12534028100A5020000AF
-:1056C0009582000E0800261DA50200028F850100AC
-:1056D0002762300024A6002000C2102B5040000199
-:1056E000276628008F82010810C200040000000015
-:1056F0008F82010414C200072563000C8EE201A80A
-:105700000000482124420001AEE201A80800260D55
-:105710008EE201A82C64000C01441021ACA2000010
-:10572000ACA300048EE3726424E2FFF4A4A2000E92
-:1057300024020006ACA2001824630010ACA30008E9
-:105740008EE204E4ACA2001C8EE204C83C0300021A
-:1057500000431025ACA20010AF86010092E204ECD9
-:1057600014400037240900018EE24E28000210C0C8
-:1057700024424E3802E220218C83000024020005DE
-:105780001462001F000000008EE34E288EE24E2CB3
-:105790001062001B240300408C820004244200019C
-:1057A000AC8200048EE24E2C8EE54E28244200018D
-:1057B00010430007000000008EE24E2C244200013E
-:1057C00010A2000500000000080025F700000000FE
-:1057D00014A00005000000008F8201082442002070
-:1057E000AF8201088F8201088C8200042C420011D4
-:1057F00050400013AC8000000800260D000000009F
-:105800008EE24E282403004024420001504300034E
-:10581000000010218EE24E2824420001AEE24E2804
-:105820008EE24E28000210C024424E3802E22021AF
-:1058300024020005AC82000024020001AC820004B6
-:105840001520000A34028100AFAB00108EE27264B2
-:105850003C040001248457303C050004AFA200142E
-:105860008EE604E4080028BE34A5F0158EE37264C9
-:10587000A462000C8EE372649582000EA462000E96
-:105880000800268124E700048F840100276230008D
-:105890002485002000A2102B50400001276528001D
-:1058A0008F82010810A20004000000008F82010412
-:1058B00014A20007240200068EE201A8000048217D
-:1058C00024420001AEE201A8080026778EE201A87A
-:1058D000AC8A0000AC8B00048EE37264A487000ED7
-:1058E000AC820018AC8300088EE204E4AC82001C99
-:1058F0008EE204C83C03000200431025AC82001075
-:10590000AF85010092E204EC144000372409000145
-:105910008EE24E28000210C024424E3802E22021BE
-:105920008C830000240200051462001F00000000A8
-:105930008EE34E288EE24E2C1062001B24030040A2
-:105940008C82000424420001AC8200048EE24E2CC2
-:105950008EE54E282442000110430007000000009D
-:105960008EE24E2C2442000110A20005000000002F
-:10597000080026610000000014A0000500000000DF
-:105980008F82010824420020AF8201088F82010823
-:105990008C8200042C42001150400013AC800000A7
-:1059A00008002677000000008EE24E282403004005
-:1059B0002442000150430003000010218EE24E28D3
-:1059C00024420001AEE24E288EE24E28000210C0B2
-:1059D00024424E3802E2202124020005AC8200005D
-:1059E00024020001AC820004152000093C050004DB
-:1059F000AFAB00108EE272643C0400012484573087
-:105A0000AFA200148EE604E4080028BE34A5F0041A
-:105A10008EE2725C30E7FFFF00471021AEE2725C5D
-:105A20008EE204E48EE304FC8EE47258000211005E
-:105A300000431021AC44000C8EE27258AFA2001853
-:105A40008EE3725CAFA3001C8EE2725C2C42003CC1
-:105A500010400004246200012403FFFE00431024D0
-:105A6000AFA2001C8EE272643C06000134C638000E
-:105A70008EE3725C2405FFF80047102124420007E2
-:105A80000045102424630007AEE272588EE2726C67
-:105A90008EE472580065182400431023AEE2726C45
-:105AA000036610210082202B148000043C03FFFFBA
-:105AB0008EE2725800431021AEE272588EE27258A4
-:105AC000AEE272648F8200F024470008276218005B
-:105AD00000E2102B50400001276710008F8200F475
-:105AE00014E20007000000008EE201B4000048212B
-:105AF00024420001AEE201B4080026C48EE201B4E3
-:105B00008F8200F0240900018FA300188FA4001CCD
-:105B1000AC430000AC440004AF8700F01520001235
-:105B2000000D11428F8200F0AFA200108F8200F4AE
-:105B30003C0400012484573CAFA200148FA6001837
-:105B40008FA7001C3C0500040C00240334A5F005BD
-:105B50008EE2008824420001AEE200888EE20088D6
-:105B6000080028D3AEE0725C304300032402000238
-:105B70001062001628620003104000052402000194
-:105B80001062000800000000080027030000000069
-:105B90002402000310620017000000000800270321
-:105BA000000000008EE200E88EE300EC24630001B8
-:105BB0002C64000100441021AEE200E8AEE300ECEA
-:105BC0008EE200E8080027038EE300EC8EE200F08E
-:105BD0008EE300F4246300012C64000100441021D2
-:105BE000AEE200F0AEE300F48EE200F0080027031E
-:105BF0008EE300F48EE200F88EE300FC24630001E3
-:105C00002C64000100441021AEE200F8AEE300FC79
-:105C10008EE200F88EE300FC8EE2725C8EE400E01F
-:105C20008EE500E4004018210000102100A3282187
-:105C300000A3302B0082202100862021AEE400E06A
-:105C4000AEE500E4080028D3AEE0725C30E2FFFF6E
-:105C5000104001C131A202001040014D0000482156
-:105C600096E2045A30420010104001490000000042
-:105C70008F840100276230002485002000A2102BB1
-:105C800050400001276528008F82010810A20004FF
-:105C9000000000008F82010414A200062402000C00
-:105CA0008EE201A824420001AEE201A80800276E9E
-:105CB0008EE201A8AC8A0000AC8B00048EE3726413
-:105CC00024060005A482000EAC860018AC830008F0
-:105CD0008EE204E4AC82001C8EE204C8AC820010A8
-:105CE000AF85010092E204EC144000362409000163
-:105CF0008EE24E28000210C024424E3802E22021DB
-:105D00008C8200001446001F000000008EE34E2825
-:105D10008EE24E2C1062001B240300408C82000493
-:105D200024420001AC8200048EE24E2C8EE54E2807
-:105D30002442000110430007000000008EE24E2CB8
-:105D40002442000110A200050000000008002758AE
-:105D50000000000014A00005000000008F82010870
-:105D600024420020AF8201088F8201088C82000447
-:105D70002C42001150400013AC8000000800276E38
-:105D8000000000008EE24E2824030040244200015F
-:105D900050430003000010218EE24E2824420001EF
-:105DA000AEE24E288EE24E28000210C024424E3849
-:105DB00002E2202124020005AC820000240200013E
-:105DC000AC8200041520000A3C040001AFAB0010B7
-:105DD0008EE272643C040001248457303C050004C8
-:105DE000AFA200148EE604E4080028BE34A5F01427
-:105DF0008EE2726434843800036418212442001057
-:105E00000043102B14400073000000008EE2726407
-:105E100024480010036410210102102B14400002DA
-:105E20003C02FFFF010240218F8501002762300004
-:105E300024A6002000C2102B504000012766280035
-:105E40008F82010810C20004000000008F8201044C
-:105E500014C200072563000C8EE201A8000048214F
-:105E600024420001AEE201A8080027E28EE201A868
-:105E70002C64000C01441021ACA20000ACA300046F
-:105E800024E2FFF4A4A2000E24020006ACA800083D
-:105E9000ACA200188EE204E4ACA2001C8EE204C89E
-:105EA0003C03000200431025ACA20010AF860100A5
-:105EB00092E204EC14400037240900018EE24E28DF
-:105EC000000210C024424E3802E220218C830000E0
-:105ED000240200051462001F000000008EE34E281B
-:105EE0008EE24E2C1062001B240300408C820004C2
-:105EF00024420001AC8200048EE24E2C8EE54E2836
-:105F00002442000110430007000000008EE24E2CE6
-:105F10002442000110A2000500000000080027CC68
-:105F20000000000014A00005000000008F8201089E
-:105F300024420020AF8201088F8201088C82000475
-:105F40002C42001150400013AC800000080027E2F2
-:105F5000000000008EE24E2824030040244200018D
-:105F600050430003000010218EE24E28244200011D
-:105F7000AEE24E288EE24E28000210C024424E3877
-:105F800002E2202124020005AC820000240200016C
-:105F9000AC8200041520000A2508FFFCAFAB0010FE
-:105FA0008EE272643C040001248457303C050004F6
-:105FB000AFA200148EE604E4080028BE34A5F01554
-:105FC00034028100A50200009582000E0800285FBF
-:105FD000A50200028F8501002762300024A6002060
-:105FE00000C2102B50400001276628008F82010854
-:105FF00010C20004000000008F82010414C20007D8
-:106000002563000C8EE201A8000048212442000113
-:10601000AEE201A80800284F8EE201A82C64000C13
-:1060200001441021ACA20000ACA300048EE3726412
-:1060300024E2FFF4A4A2000E24020006ACA2001881
-:1060400024630010ACA300088EE204E4ACA2001CA0
-:106050008EE204C83C03000200431025ACA20010ED
-:10606000AF86010092E204EC1440003724090001DD
-:106070008EE24E28000210C024424E3802E2202157
-:106080008C830000240200051462001F0000000041
-:106090008EE34E288EE24E2C1062001B240300403B
-:1060A0008C82000424420001AC8200048EE24E2C5B
-:1060B0008EE54E2824420001104300070000000036
-:1060C0008EE24E2C2442000110A2000500000000C8
-:1060D000080028390000000014A00005000000009E
-:1060E0008F82010824420020AF8201088F820108BC
-:1060F0008C8200042C42001150400013AC80000040
-:106100000800284F000000008EE24E2824030040C3
-:106110002442000150430003000010218EE24E286B
-:1061200024420001AEE24E288EE24E28000210C04A
-:1061300024424E3802E2202124020005AC820000F5
-:1061400024020001AC8200041520000A3402810000
-:10615000AFAB00108EE272643C040001248457301F
-:106160003C050004AFA200148EE604E4080028BE3B
-:1061700034A5F0168EE37264A462000C8EE37264A0
-:106180009582000EA462000E080028C224E70004D5
-:106190008F83010027623000246400200082102BCE
-:1061A00050400001276428008F82010810820004FB
-:1061B000000000008F8201041482000724050005FE
-:1061C0008EE201A80000482124420001AEE201A8AD
-:1061D000080028B68EE201A8AC6A0000AC6B00048F
-:1061E0008EE27264A467000EAC650018AC62000811
-:1061F0008EE204E4AC62001C8EE204C8AC620010C3
-:10620000AF84010092E204EC14400036240900013E
-:106210008EE24E28000210C024424E3802E22021B5
-:106220008C8200001445001F000000008EE34E2801
-:106230008EE24E2C1062001B240300408C8200046E
-:1062400024420001AC8200048EE24E2C8EE54E28E2
-:106250002442000110430007000000008EE24E2C93
-:106260002442000110A2000500000000080028A040
-:106270000000000014A00005000000008F8201084B
-:1062800024420020AF8201088F8201088C82000422
-:106290002C42001150400013AC800000080028B6CA
-:1062A000000000008EE24E2824030040244200013A
-:1062B00050430003000010218EE24E2824420001CA
-:1062C000AEE24E288EE24E28000210C024424E3824
-:1062D00002E2202124020005AC8200002402000119
-:1062E000AC8200041520000B3C0500043C040001B6
-:1062F00024845748AFAB0010AFA000148EE604E42E
-:1063000034A5F0170C00240330E7FFFF080028E154
-:10631000000000008EE272643C05000130E4FFFFE3
-:1063200000441021AEE272648EE2725C8EE372640D
-:1063300034A5380000441021AEE2725C03651021E0
-:106340000062182B146000043C03FFFF8EE27264AD
-:1063500000431021AEE272648EE304E496E2045836
-:10636000246300012442FFFF00621824AEE304E42A
-:106370008EE304E48EE204E01462000500000000F5
-:106380008F8200602403FFF700431024AF82006077
-:106390008FBF002003E0000827BD002827BDFFE0D5
-:1063A000AFBF00188EE304E88EE204E010620189BA
-:1063B000000000008EE204E88EE304FC00021100FD
-:1063C000006218219467000892E204ED8C680000D6
-:1063D0008C69000410400023946A000A8EE204C80D
-:1063E00034460400314202001040001F000000004B
-:1063F00096E2045A304200101040001B3C0280001C
-:106400003C01000100370821AC2283D88EE272647F
-:106410009464000E3C05000134A5380024420004B9
-:10642000AEE272648EE372640004240003651021FE
-:106430003C01000100370821AC2483DC0062182BEA
-:106440001460000524E700048EE272643C03FFFF41
-:1064500000431021AEE272648EE2726408002917D4
-:10646000AEE272588EE604C88EE2726C30E4FFFF32
-:106470000044102A10400015000000008F8200D850
-:106480008EE3725800431023AEE2726C8EE2726C9F
-:106490001C4000070044102A8EE2726C3C0300018D
-:1064A00000431021AEE2726C8EE2726C0044102A3E
-:1064B00010400006000000008EE201B824420001F6
-:1064C000AEE201B808002A728EE201B83C02000177
-:1064D000005710218C4283D85440000124E7FFFC70
-:1064E00031420004104000B930E2FFFF3C020001DD
-:1064F000005710218C4283D81040002F00005021FB
-:106500008F840100276230002485002000A2102B18
-:1065100050400001276528008F82010810A2003238
-:10652000000000008F82010410A2002F2402001539
-:10653000AC880000AC8900048EE37264A487000E6E
-:10654000AC820018AC8300088EE204E83C03000132
-:10655000007718218C6383DCAC8600100043102583
-:10656000AC82001CAF85010092E204EC144000668E
-:10657000240A00018EE24E28240300402442000138
-:1065800050430003000010218EE24E2824420001F7
-:10659000AEE24E288EE24E28000210C024424E3851
-:1065A00002E2182124020015AC620000240200015E
-:1065B000080029BFAC6200048F840100276230000C
-:1065C0002485002000A2102B5040000127652800E0
-:1065D0008F82010810A20004000000008F820104D5
-:1065E00014A20006240200068EE201A82442000143
-:1065F000AEE201A8080029BF8EE201A8AC88000025
-:10660000AC8900048EE37264A487000EAC8200188B
-:10661000AC8300088EE204E8AC860010AC82001C5B
-:10662000AF85010092E204EC14400037240A000117
-:106630008EE24E28000210C024424E3802E2202191
-:106640008C830000240200051462001F000000007B
-:106650008EE34E288EE24E2C1062001B2403004075
-:106660008C82000424420001AC8200048EE24E2C95
-:106670008EE54E2824420001104300070000000070
-:106680008EE24E2C2442000110A200050000000002
-:10669000080029A90000000014A000050000000067
-:1066A0008F82010824420020AF8201088F820108F6
-:1066B0008C8200042C42001150400013AC8000007A
-:1066C000080029BF000000008EE24E28240300408D
-:1066D0002442000150430003000010218EE24E28A6
-:1066E00024420001AEE24E288EE24E28000210C085
-:1066F00024424E3802E2202124020005AC82000030
-:1067000024020001AC8200041540000A24020001AA
-:10671000AFA900108EE272643C040001248457305B
-:106720003C050004AFA200148EE604E408002A4FE2
-:1067300034A5F204A2E204ED8EE204E88EE304FC48
-:106740008EE472583C06000134C638003C0100015A
-:1067500000370821AC2083D83C0100010037082114
-:10676000AC2083DC0002110000431021AC44000C7B
-:106770008EE272642405FFF830E3FFFF004310212E
-:10678000244200070045102424630007AEE272583B
-:106790008EE2726C8EE47258006518240043102358
-:1067A000AEE2726C036610210082202B148000047C
-:1067B0003C03FFFF8EE2725800431021AEE2725894
-:1067C0008EE2725808002A64AEE2726410400073D0
-:1067D000000000008F830100276230002464002045
-:1067E0000082102B14400002000050212764280072
-:1067F0008F82010810820004000000008F820104D3
-:1068000014820006240500058EE201A8244200013E
-:10681000AEE201A808002A468EE201A8AC6800009A
-:10682000AC6900048EE27264A467000EAC650018C7
-:10683000AC6200088EE204E8AC660010AC62001C9A
-:10684000AF84010092E204EC14400036240A0001F7
-:106850008EE24E28000210C024424E3802E220216F
-:106860008C8200001445001F000000008EE34E28BB
-:106870008EE24E2C1062001B240300408C82000428
-:1068800024420001AC8200048EE24E2C8EE54E289C
-:106890002442000110430007000000008EE24E2C4D
-:1068A0002442000110A200050000000008002A3068
-:1068B0000000000014A00005000000008F82010805
-:1068C00024420020AF8201088F8201088C820004DC
-:1068D0002C42001150400013AC80000008002A46F2
-:1068E000000000008EE24E282403004024420001F4
-:1068F00050430003000010218EE24E282442000184
-:10690000AEE24E288EE24E28000210C024424E38DD
-:1069100002E2202124020005AC82000024020001D2
-:10692000AC8200041540000C30E5FFFF3C04000180
-:10693000248457483C050004AFA90010AFA0001400
-:106940008EE604E434A5F2370C00240330E7FFFFA1
-:1069500008002A72000000008EE2726400451021D7
-:10696000AEE272648EE2726C8EE372643C040001EB
-:1069700034843800A2E004ED00451023AEE2726CCE
-:10698000036410210062182B146000043C03FFFF15
-:106990008EE2726400431021AEE272648EE304E87A
-:1069A00096E20458246300012442FFFF0062182489
-:1069B000AEE304E88EE304E88EE204E0146200052E
-:1069C000000000008F8200602403FFF700431024C2
-:1069D000AF8200608FBF001803E0000827BD0020D1
-:1069E00027BDFFE0AFBF001CAFB000188F820100D1
-:1069F0008EE34E2C8F8201048F8501082402004013
-:106A00002463000150620003000010218EE24E2C2E
-:106A100024420001AEE24E2C8EE24E2C8EE34E2C30
-:106A2000000210C024424E3802E220218EE24E289D
-:106A30008C8700041462000700A030218F820108B7
-:106A400024420020AF8201088F82010808002AA298
-:106A5000AC8000008EE24E2C240300402442000152
-:106A600050430003000010218EE24E2C244200010E
-:106A7000000210C024424E3802E220218C82000421
-:106A80008F8301080002114000621821AF830108C2
-:106A9000AC8000008CC200182443FFFE2C6200135F
-:106AA000104000C1000310803C01000100220821B9
-:106AB0008C22577000400008000000008EE204F0B5
-:106AC00000471021AEE204F08EE204F08F43023C56
-:106AD0000043102B144000BE000000008EE304E4CD
-:106AE0008EE204F8506200BAA2E004F48F83012021
-:106AF000276238002466002000C2102B504000019D
-:106B0000276630008F82012810C2000400000000B8
-:106B10008F82012414C20007000000008EE201A44D
-:106B20000000802124420001AEE201A408002B12E3
-:106B30008EE201A48EE204E4AC62001C8EE404B098
-:106B40008EE504B42462001CAC6200082402000834
-:106B5000A462000E24020011AC620018AC640000B4
-:106B6000AC6500048EE204C4AC620010AF86012064
-:106B700092E24E2014400037241000018EE24E3085
-:106B8000000210C02442503802E220218C83000011
-:106B9000240200121462001F000000008EE34E3039
-:106BA0008EE24E341062001B240300408C820004ED
-:106BB00024420001AC8200048EE24E348EE54E3059
-:106BC0002442000110430007000000008EE24E3412
-:106BD0002442000110A200050000000008002AFC69
-:106BE0000000000014A00005000000008F820128B2
-:106BF00024420020AF8201288F8201288C82000469
-:106C00002C42001150400013AC80000008002B12F1
-:106C1000000000008EE24E302403004024420001B8
-:106C200050430003000010218EE24E302442000148
-:106C3000AEE24E308EE24E30000210C02442503898
-:106C400002E2202124020012AC8200002402000192
-:106C5000AC8200045600000B241000018EE204E414
-:106C60003C04000124845754AFA00014AFA20010CC
-:106C70008EE606088F4702283C0500090C00240315
-:106C800034A5F006160000032402000108002B7151
-:106C9000A2E204F48EE2017024420001AEE201702F
-:106CA0008EE201708EE204E4A2E004F4AEE004F0AF
-:106CB000AEE204F88F42023C50400045AEE07274F0
-:106CC0008EE2018424420001AEE201848EE201845E
-:106CD00008002B71AEE072748EE2050424030040BC
-:106CE0002442000150430003000010218EE20504FD
-:106CF00024420001AEE205048EE205048CC30018B4
-:106D000000021080005710218C4405082402000363
-:106D10001462000F000000003C0200010057102127
-:106D2000904283B110400014000000008EE201D0B8
-:106D30008EE3524000441021AEE201D08EE201D831
-:106D400000641821306300FF08002B59AEE3524065
-:106D50008EE201CC8EE30E1000441021AEE201CC95
-:106D60008EE201D800641821306301FFAEE30E10FB
-:106D700000441021AEE201D88EE20000344200400F
-:106D800008002B71AEE200008EE2014C3C010001D4
-:106D900000370821A02083E024420001AEE2014C2C
-:106DA00008002B718EE2014C94C7000E8CC2001CAF
-:106DB0003C04000124845760AFA60014AFA2001069
-:106DC0008CC600183C0500080C00240334A50910EB
-:106DD0008FBF001C8FB0001803E0000827BD002003
-:106DE00027BDFF98AFBF0060AFBE005CAFB60058D4
-:106DF000AFB50054AFB40050AFB3004CAFB20048D1
-:106E0000AFB10044AFB000408F8301088F8201040E
-:106E1000AFA00024106203E7AFA0002C3C1E0001CD
-:106E200037DE38003C0BFFFF8F9301088E6200189D
-:106E30008F8301042443FFFE2C620014104003CF13
-:106E4000000310803C010001002208218C2257C061
-:106E500000400008000000009663000E8EE2725CA5
-:106E60008EE404F000431021AEE2725C8E63001CDD
-:106E700096E2045824840001AEE404F02463000187
-:106E80002442FFFF00621824AEE304E48F42023C78
-:106E90000082202B148003B9000000008F830120A2
-:106EA000276238002466002000C2102B50400001E9
-:106EB000276630008F82012810C200040000000005
-:106EC0008F82012414C20007000000008EE201A49A
-:106ED0000000802124420001AEE201A408002BFE44
-:106EE0008EE201A48EE204E4AC62001C8EE404B0E5
-:106EF0008EE504B42462001CAC6200082402000881
-:106F0000A462000E24020011AC620018AC64000000
-:106F1000AC6500048EE204C4AC620010AF860120B0
-:106F200092E24E2014400037241000018EE24E30D1
-:106F3000000210C02442503802E220218C8300005D
-:106F4000240200121462001F000000008EE34E3085
-:106F50008EE24E341062001B240C00408C82000430
-:106F600024420001AC8200048EE24E348EE34E30A7
-:106F700024420001104C0007000000008EE24E3455
-:106F800024420001106200050000000008002BE808
-:106F90000000000014600005000000008F8201283E
-:106FA00024420020AF8201288F8201288C820004B5
-:106FB0002C42001150400013AC80000008002BFE52
-:106FC000000000008EE24E30240C004024420001FC
-:106FD000504C0003000010218EE24E30244200018C
-:106FE000AEE24E308EE24E30000210C024425038E5
-:106FF00002E2202124020012240C0001AC820000D5
-:10700000AC8C00045600000D241000018EE204E454
-:107010003C04000124845754AFA00014AFA2001018
-:107020008EE606088F4702283C05000934A5F006C5
-:107030000C002403AFAB00388FAB00381200030AFA
-:10704000240C000108002F1900000000966C001CA1
-:10705000AFAC002C9662001E3C0C8000AFAC00244C
-:10706000AE62001C8E75001C8EE204FC8EE404FCF3
-:1070700000151900006210218C52000C92E27B98DE
-:10708000006418219476000A1440000332C2000202
-:10709000AEF27BA4AEF57B9C1040004B000080213B
-:1070A00096E2045A304200021040004700000000FF
-:1070B0008E63001C8EE204FC00032100008210217C
-:1070C0008C42000C037E1821244200220043102B26
-:1070D0001440000A240500148EE204FC00821021F2
-:1070E0008C44000CAFAB00380C002F752484000ECC
-:1070F0008FAB003808002C523050FFFF8EE204FCAA
-:10710000008210218C42000C9450000E9443001019
-:10711000944400129445001402038021020480214B
-:107120000205802194430016944400189445001AE7
-:107130000203802102048021020580219443001C67
-:107140009444001E94420020020380210204802106
-:107150000202802100101C023202FFFF0062802127
-:107160008E63001C8EE204FC001024020003290040
-:1071700000A210218C43000C3202FFFF008280210C
-:10718000037E1021246300180062182B146000098C
-:10719000000000008EE204FC00A210218C43000CD1
-:1071A000001010273C01FFFF0023082108002C6F6E
-:1071B000A42200188EE204FC00A210218C43000CD3
-:1071C00000101027A462001896E2045A00008821DB
-:1071D00030420008144000630000A0218E63001CB0
-:1071E0008EE204FC0003310000C210218C42000C2E
-:1071F000037E1821244200220043102B1440003546
-:10720000000000008EE204FC00C210218C42000C41
-:1072100024470010037E102100E2102B5040000193
-:1072200000EB38218EE204FC94F1000000C2102132
-:107230008C42000C24470016037E102100E2102B24
-:10724000144000022634FFEC00EB38218EE204FCEF
-:1072500090E3000100C210218C42000C2447001A68
-:10726000037E102100E2102B1440000202838821CB
-:1072700000EB382194E2000024E70002022288217A
-:10728000037E102100E2102B5040000100EB38215A
-:1072900094E2000024E7000202228821037E1021EC
-:1072A00000E2102B5040000100EB382194E2000076
-:1072B00024E7000202228821037E102100E2102B25
-:1072C0005040000100EB382194E2000008002CD06F
-:1072D000022288218EE204FC00C210218C43000CA3
-:1072E0008EE204FC947100108EE304FC00C21021B5
-:1072F0008C44000C00C318218C62000C2634FFEC77
-:10730000908400178EE304FC9442001A02848821C2
-:1073100000C318218C65000C8EE304FC0222882136
-:107320008EE204FC00C3182100C210218C44000C22
-:107330008C62000C94A3001C9484001E94420020D4
-:1073400002238821022488210222882100111C02A4
-:107350003222FFFF0062882100111C023222FFFF4F
-:107360000062882132C20001104000B2000000001B
-:1073700096E2045A30420001104000AE32C2008052
-:10738000104000080000000092E27B9814400005C5
-:1073900000000000240C0001A2EC7B98AEF57B9C61
-:1073A000AEF27BA48EE304FC001511000043102113
-:1073B0008C47000C037E182124E2000E0043102BA2
-:1073C0001440000800E020212405000E0C002F7559
-:1073D000AFAB00383042FFFF8FAB003808002D09FB
-:1073E0000202802194E6000024E7000294E50000F8
-:1073F00024E7000294E3000024E7000294E2000086
-:1074000024E7000294E4000024E700020206802141
-:1074100002058021020380210202802194E2000003
-:1074200094E30002020480210202802102038021F1
-:1074300000101C023202FFFF0062802100101C02BB
-:107440003202FFFF8EE47B9C0062802114950004D1
-:107450003205FFFF9662001608002D17005120210B
-:107460009662001600542021000414023083FFFFAE
-:1074700000432021008520230004140200822021E3
-:107480003084FFFF508000013404FFFF8EE27BA4B4
-:1074900024430017037E10210062102B504000018E
-:1074A000006B182190630000240200111462003167
-:1074B000240200068EE27BA4037E182124420028C9
-:1074C0000043102B14400018000000008EE27B9C4B
-:1074D00012A2000A32C201008EE27BA43C01FFFF2F
-:1074E00000220821942200280082202100041C028E
-:1074F0003082FFFF0062202132C2010014400004EC
-:107500000004102792E27B98144000020004102728
-:107510003044FFFF8EE27BA43C01FFFF00220821E4
-:1075200008002D8AA42400288EE27B9C12A2000869
-:1075300032C201008EE27BA4944200280082202106
-:1075400000041C023082FFFF0062202132C20100D1
-:10755000144000040004102792E27B9814400002BB
-:10756000000410273044FFFF8EE27BA408002D8A20
-:10757000A44400281462002F037E18218EE27BA40D
-:10758000244200320043102B144000180000000079
-:107590008EE27B9C12A2000A32C201008EE27BA422
-:1075A0003C01FFFF002208219422003200822021AA
-:1075B00000041C023082FFFF0062202132C2010061
-:1075C000144000040004102792E27B98144000024B
-:1075D000000410273044FFFF8EE27BA43C01FFFF34
-:1075E0000022082108002D8AA42400328EE27B9C10
-:1075F00012A2000832C201008EE27BA49442003243
-:107600000082202100041C023082FFFF0062202142
-:1076100032C20100144000040004102792E27B985B
-:1076200014400002000410273044FFFF8EE27BA4C8
-:10763000A44400328FAC00241180002C037E18215A
-:107640008E420000AE42FFFC2642000A0043102B8F
-:107650001440001B3403810026430004037E1021E4
-:107660000062102B1440000300602021006B1821E1
-:10767000006020218C62000024630004AE42000000
-:10768000037E10210062102B50400001006B182176
-:107690008C620000AC82000034028100A462000011
-:1076A00024630002037E10210062102B5040000171
-:1076B000006B182197AC002E08002DB4A46C0000BC
-:1076C0008E4200048E440008A643000897AC002EAA
-:1076D000A64C000AAE420000AE4400049662000EC2
-:1076E0002652FFFC24420004A662000E9662000EA1
-:1076F0008EE3725C00621821AEE3725CAFB20018D8
-:107700008EE3725CAFA3001C8EE2725C2C42003CE4
-:1077100010400004246200012403FFFE00431024F3
-:10772000AFA2001C32C200801040000C32C2010027
-:107730008EE27BA824430001000210C000571021F4
-:10774000AEE37BA88FA300188FA4001CAC437BACD6
-:10775000AC447BB008002EA0AEE0725C104000721A
-:10776000000000008EE27BA824430001000210C04C
-:1077700000571021AEE37BA88FA300188FA4001C34
-:10778000AC437BACAC447BB08EE27BA81040006382
-:1077900000004821000050218F8200F0244800089A
-:1077A000276218000102102B5040000127681000CA
-:1077B0008F8200F415020007000000008EE201B481
-:1077C0000000802124420001AEE201B408002DFA3D
-:1077D0008EE201B48F8300F02410000101571021C4
-:1077E0008C447BAC8C457BB0AC640000AC65000481
-:1077F000AF8800F01600000602EA10218EE2008831
-:1078000024420001AEE2008808002E3F8EE200888C
-:107810008C427BB08EE400E08EE500E48EE67B9C3B
-:10782000004018210000102100A3282100A3382BBC
-:1078300000822021008720218EE204FC00C9302133
-:1078400000063100AEE400E0AEE500E400C2302105
-:1078500094C2000A240C00020002114230430003CB
-:10786000106C00162862000310400005240C000173
-:10787000106C00080000000008002E3F000000000F
-:10788000240C0003106C00170000000008002E3FBD
-:10789000000000008EE200E88EE300EC24630001AB
-:1078A0002C64000100441021AEE200E8AEE300ECDD
-:1078B0008EE200E808002E3F8EE300EC8EE200F03E
-:1078C0008EE300F4246300012C64000100441021C5
-:1078D000AEE200F0AEE300F48EE200F008002E3FCE
-:1078E0008EE300F48EE200F88EE300FC24630001D6
-:1078F0002C64000100441021AEE200F8AEE300FC6D
-:107900008EE200F88EE300FC8EE27BA825290001C0
-:107910000122102B1440FFA0254A0008A2E07B980A
-:1079200008002E9FAEE07BA88F8200F0244700085D
-:107930002762180000E2102B50400001276710005A
-:107940008F8200F414E20007000000008EE201B410
-:107950000000802124420001AEE201B408002E5D47
-:107960008EE201B48F8200F0241000018FA3001872
-:107970008FA4001CAC430000AC440004AF8700F0AF
-:1079800016000007000000008EE20088244200017B
-:10799000AEE200888EE2008808002EA0AEE0725CA5
-:1079A0008EE2725C8EE400E08EE500E4240C0002BE
-:1079B000004018210000102100A3282100A3302B33
-:1079C000008220210086202100161142304300034E
-:1079D000AEE400E0AEE500E4106C00172C6200039A
-:1079E00010400005240C0001106C0008000000008D
-:1079F00008002EA0AEE0725C240C0003106C00198D
-:107A00000000000008002EA0AEE0725C8EE200E8EC
-:107A10008EE300EC246300012C640001004410217B
-:107A2000AEE200E8AEE300EC8EE200E88EE300ECAC
-:107A300008002EA0AEE0725C8EE200F08EE300F44F
-:107A4000246300012C64000100441021AEE200F028
-:107A5000AEE300F48EE200F08EE300F408002EA006
-:107A6000AEE0725C8EE200F88EE300FC246300015D
-:107A70002C64000100441021AEE200F8AEE300FCEB
-:107A80008EE200F88EE300FCAEE0725C8E62001CB9
-:107A900096E304588EE404F0244200012463FFFFBF
-:107AA0000043102424840001AEE204E4AEE404F0B8
-:107AB0008F42023C0082202B148000B000000000A6
-:107AC0008F830120276238002466002000C2102B1B
-:107AD00050400001276630008F82012810C2000448
-:107AE000000000008F82012414C200070000000083
-:107AF0008EE201A40000802124420001AEE201A434
-:107B000008002F078EE201A48EE204E4AC62001CA0
-:107B10008EE404B08EE504B42462001CAC6200085C
-:107B200024020008A462000E24020011AC620018B6
-:107B3000AC640000AC6500048EE204C4AC620010CA
-:107B4000AF86012092E24E2014400037241000013D
-:107B50008EE24E30000210C02442503802E2202152
-:107B60008C830000240200121462001F0000000039
-:107B70008EE34E308EE24E341062001B240C004027
-:107B80008C82000424420001AC8200048EE24E3458
-:107B90008EE34E3024420001104C0007000000002C
-:107BA0008EE24E3424420001106200050000000005
-:107BB00008002EF100000000146000050000000025
-:107BC0008F82012824420020AF8201288F82012861
-:107BD0008C8200042C42001150400013AC80000045
-:107BE00008002F07000000008EE24E30240C0040F9
-:107BF00024420001504C0003000010218EE24E3060
-:107C000024420001AEE24E308EE24E30000210C03F
-:107C10002442503802E2202124020012240C0001E8
-:107C2000AC820000AC8C00045600000D2410000152
-:107C30008EE204E43C04000124845754AFA00014F5
-:107C4000AFA200108EE606088F4702283C05000907
-:107C500034A5F0060C002403AFAB00388FAB00381E
-:107C600016000003240C000108002F5CA2EC04F4B1
-:107C70008EE2017024420001AEE201708EE20170DA
-:107C80008EE204E4A2E004F4AEE004F0AEE072742C
-:107C9000AEE204F88F42023C1040003800000000C1
-:107CA0008EE2018424420001AEE2018408002F5CD0
-:107CB0008EE201848EE20504240C0040244200017F
-:107CC000504C0003000010218EE205042442000104
-:107CD000AEE205048EE205048E630018240C000356
-:107CE0000002108000571021146C000F8C4405080E
-:107CF0003C02000100571021904283B11040001453
-:107D0000000000008EE201D08EE3524000441021BA
-:107D1000AEE201D08EE201D800641821306300FF8A
-:107D200008002F4FAEE352408EE201CC8EE30E10DE
-:107D300000441021AEE201CC8EE201D8006418218B
-:107D4000306301FFAEE30E1000441021AEE201D813
-:107D50008EE200003442004008002F5CAEE20000DA
-:107D60008EE2014C3C01000100370821A02083E095
-:107D700024420001AEE2014C8EE2014C8F820108E8
-:107D800024420020AF8201088F8201088F820108FF
-:107D9000276330000043102B1440000227622800A4
-:107DA000AF8201088F8301088F8201041462FC1ED8
-:107DB000000000008FBF00608FBE005C8FB60058CF
-:107DC0008FB500548FB400508FB3004C8FB2004871
-:107DD0008FB100448FB0004003E0000827BD006869
-:107DE0000005284310A0000D000030213C030001D5
-:107DF000346338003C07FFFF036310210082102B1F
-:107E00005040000100872021948200002484000259
-:107E100024A5FFFF14A0FFF800C2302100061C02B9
-:107E200030C2FFFF0062302100061C0230C2FFFF9B
-:107E30000062302103E0000830C2FFFF27BDFF8849
-:107E4000240F0001AFBF0070AFBE006CAFB600687A
-:107E5000AFB50064AFB40060AFB3005CAFB2005820
-:107E6000AFB10054AFB00050A3A00027AFAF002CBB
-:107E70008EE204D400008021304200011440002A28
-:107E8000A3A000378F8700E08F8800C48F8200E8AE
-:107E900000E220232C8210005040000124841000B6
-:107EA000000420C2008018218EE400C88EE500CCBA
-:107EB0000000102100A3282100A3302B00822021E4
-:107EC00000862021AEE400C8AEE500CC8F8300C858
-:107ED0003C02000A3442EFFF010320230044102B30
-:107EE000104000033C02000A3442F00000822021CE
-:107EF000008018218EE400C08EE500C4000010212F
-:107F000000A3282100A3302B0082202100862021FD
-:107F1000AEE400C0AEE500C4AF8800C8AF8700E49F
-:107F2000080034CCAF8700E83C0200010057102164
-:107F3000904283C01040000B000000003C14000180
-:107F40000297A0218E9483C43C13000102779821EC
-:107F50008E7383C83C1200010257902108003193B0
-:107F60008E5283CC8F8300E08F8200E410430007A1
-:107F7000000088218F8200E4241100018C4300005E
-:107F80008C440004AFA30018AFA4001C1620000E00
-:107F90003C02FFFF8F8200C4AFA200108F8200C896
-:107FA0003C04000124845870AFA200148F8600E0C6
-:107FB0008F8700E43C0500060C00240334A5F00084
-:107FC000080034CC000000008FA3001C8FB2001802
-:107FD0003074FFFF2694FFFC00621024104000580C
-:107FE000024098213C020080006210241040000AE8
-:107FF0003C0400408EE2007C24420001AEE2007CA2
-:108000008EE2007C8EE201FC24420001AEE201FC23
-:10801000080034C68EE201FC3C0600043C0B000163
-:108020003C0A00023C0500103C0900088EE200807A
-:108030003C0800203407800024420001AEE20080AA
-:108040008EE200808FA2001C0044182410660021DC
-:1080500000C3102B1440000700000000106B00113B
-:1080600000000000106A0015000000000800304900
-:10807000000420421065002300A3102B14400005CB
-:1080800000000000106900190000000008003049DD
-:108090000004204210680021000000000800304960
-:1080A000000420428EE2003424420001AEE200349B
-:1080B0008EE2003408003049000420428EE201ECD8
-:1080C00024420001AEE201EC8EE201EC08003049EE
-:1080D000000420428EE201F024420001AEE201F0F1
-:1080E0008EE201F008003049000420428EE201F4E3
-:1080F00024420001AEE201F48EE201F408003049AE
-:10810000000420428EE2003024420001AEE2003042
-:108110008EE2003008003049000420428EE201F86F
-:1081200024420001AEE201F88EE201F80004204290
-:108130001087047C000000000800300E00000000E2
-:108140003C02000100571021904283B21440008489
-:10815000240200013C03000100771821906383B3DF
-:108160001462007F3C0201008E4300000062102474
-:108170001040006F2402FFFF14620005241000016C
-:10818000964300043402FFFF1062007500000000F7
-:1081900092E204D814400072000000003C0200018A
-:1081A000005710218C4283B4284200051040002063
-:1081B000000038213C020001005710218C4283B49A
-:1081C000184000160000282196660000000520C017
-:1081D000009710219442777E1446000900971021E1
-:1081E0009443778096620002146200050097102184
-:1081F00094437782966200045062000824070001CD
-:108200003C020001005710218C4283B424A50001D8
-:1082100000A2102A5440FFEE000520C030E200FF0B
-:108220001040044000000000080030D500000000AD
-:10823000024020210C0022FE240500063044001FCD
-:10824000000428C002E510219442727C30424000B4
-:108250001440043400B710219443727E96620000EB
-:108260001462000B000418C000B710219443728000
-:108270009662000214620006000418C000B71021C4
-:10828000944372829662000410620035000418C0A4
-:1082900002E310219442727C304280001440042199
-:1082A00002E31021944B727C96670000000B28C0FB
-:1082B00000B710219442737E080030B700003021CF
-:1082C000000420C002E410219443737C02E41021D6
-:1082D000944B737C3063800014600010000B28C046
-:1082E00000B710219442737E1447FFF501602021EE
-:1082F00000B7102194437380966200025462FFF12C
-:10830000000420C000B710219443738296620004D9
-:108310005462FFEC000420C02406000130C200FFBC
-:108320001040040000000000080030D500000000EC
-:108330009743020296420000146203FA0000000014
-:108340009743020496420002146203F60000000004
-:108350009743020696420004146203F200000000F4
-:10836000924200003A030001304200010043102411
-:10837000104000742402FFFF8E63000014620004AA
-:108380003402FFFF966300041062006F240F0002A6
-:108390003C02000100571021904283B21440006A51
-:1083A000240F000392E204D854400068AFAF002CC1
-:1083B0003C020001005710218C4283B42842000582
-:1083C00010400020000038213C020001005710211D
-:1083D0008C4283B4184000160000282196660000E5
-:1083E000000520C0009710219442777E14460009B2
-:1083F0000097102194437780966200021462000572
-:10840000009710219443778296620004506200081E
-:10841000240700013C020001005710218C4283B464
-:1084200024A5000100A2102A5440FFEE000520C040
-:1084300030E200FF14400044240F0003080034C65B
-:1084400000000000024020210C0022FE240500064E
-:108450003044001F000428C002E510219442727CC1
-:1084600030424000144003AF00B710219443727EA5
-:10847000966200001462000B000418C000B71021BF
-:10848000944372809662000214620006000418C0D1
-:1084900000B7102194437282966200041062002794
-:1084A000000418C002E310219442727C3042800024
-:1084B0001440039C02E31021944B727C96670000E9
-:1084C000000B28C000B710219442737E0800313C95
-:1084D00000003021000420C002E410219443737C8A
-:1084E00002E41021944B737C306380001460001010
-:1084F000000B28C000B710219442737E1447FFF58B
-:108500000160202100B7102194437380966200021D
-:108510005462FFF1000420C000B71021944373821D
-:10852000966200045462FFEC000420C0240600019F
-:1085300030C200FF1040037B000000000800314FF4
-:10854000240F0003240F0001AFAF002C8F42026004
-:108550000054102B1040003A000000008F8300E40C
-:108560008F8200E01062000324630008AF8300E400
-:10857000AF8300E88EE400C08EE500C402801821BD
-:108580000000102100A3282100A3302B008220210D
-:1085900000862021AEE400C0AEE500C48EE20058A3
-:1085A00024420001AEE200588EE200588EE2007CC8
-:1085B00024420001AEE2007C8EE2007C8F8200E06B
-:1085C000AFA200108F8200E43C040001248458789C
-:1085D000AFA200148FA600188FA7001C3C05000650
-:1085E0000C00240334A5F003080034CC0000000084
-:1085F0008EE25240AFA200108EE252443C040001D1
-:1086000024845884AFA200148EE60E108EE70E1854
-:108610003C0500060C00240334A5F0028EE201C0E4
-:1086200024420001AEE201C08EE200008EE301C0F0
-:108630002403FFBF0043102408003470AEE20000A2
-:1086400096E204680054102B104000030000000064
-:10865000240F0001A3AF0027128003012416000796
-:1086600024150040241E0001240E00128EE2724CDC
-:108670008F43028024420001304207FF106202D380
-:108680000000000093A2002710400014000000002A
-:108690008EE352408EE252441062000926ED5244AD
-:1086A0008EE652448EE35244000211402442524866
-:1086B00002E2802124630001080031BF306B00FF1B
-:1086C00092E272481440FFCA000000008EE201E00E
-:1086D00024420001AEE201E08EE201E08EE30E10E2
-:1086E0008EE20E181062FFC226ED0E188EE60E18EE
-:1086F0008EE30E180002114024420E2002E2802177
-:1087000024630001306B01FF96E2046A30420010DE
-:1087100010400019000000009642000C340F810048
-:10872000144F0015000000003C020001005710210A
-:10873000904283C014400010000000009642000EDA
-:10874000A60200168E4200088E4300048E440000EC
-:108750002694FFFCAE42000CAE430008AE44000479
-:108760009602000E26730004240F0001A3AF003709
-:1087700034420200A602000E8E0200008E030004A6
-:108780003C04000134843800306A0007026A9823F0
-:10879000036410210262102B10400005028AA02100
-:1087A00002641023036218233C0200200043982334
-:1087B000268200072404FFF89603000A0044602480
-:1087C000006A1821006C102B104000020180382133
-:1087D00000603821AE1300188F88012024E20007C2
-:1087E0000044382427623800250900200122102B7C
-:1087F00050400001276930008F82012811220004B7
-:10880000000000008F82012415220007014018217A
-:108810008EE201A40000882124420001AEE201A4FE
-:108820000800324C8EE201A48E0400008E05000484
-:1088300000001021AD130008A507000EAD160018AA
-:10884000AD06001C00A3302B00A3282300822023A8
-:1088500000862023AD040000AD0500048EE204C0B4
-:10886000AD020010AF89012092E24E201440003387
-:10887000241100018EE24E30000210C02442503814
-:1088800002E220218C8200001456001F000000002C
-:108890008EE34E308EE24E341062001B000000006A
-:1088A0008C82000424420001AC8200048EE24E342B
-:1088B0008EE34E30244200011055000700000000F6
-:1088C0008EE24E34244200011062000500000000D8
-:1088D00008003239000000001460000500000000AC
-:1088E0008F82012824420020AF8201288F82012834
-:1088F0008C8200042C42001150400010AC8000001B
-:108900000800324C000000008EE24E30244200018C
-:1089100050550003000010218EE24E302442000129
-:10892000AEE24E308EE24E30000210C0244250388B
-:1089300002E22021AC960000AC9E00041620001834
-:108940003C0500068E0200183C0400012484589067
-:10895000AFA200108E0200008E03000434A5F009BF
-:10896000020030210C002403AFA3001493A20037AF
-:1089700010400216340F81008E4200048E4300081E
-:108980008E44000CA64F000CAE420000AE43000423
-:10899000AE4400089602001608003470A642000E8D
-:1089A00014EC0168028A1823960C000A9603000E44
-:1089B000028A1023A602000A34620004A602000EF6
-:1089C0008F88012027623800250900200122102B02
-:1089D00014400002306AFFFF276930008F820128AF
-:1089E00011220004000000008F82012415220007DC
-:1089F000240400208EE201A400008821244200010A
-:108A0000AEE201A4080032CA8EE201A48EE5724CE7
-:108A10008EE604908EE70494A504000E240400045E
-:108A2000AD100008AD0400180005294000A0182171
-:108A30000000102100E3382100E3202B00C2302188
-:108A400000C43021AD060000AD0700048EE2724C78
-:108A5000AD02001C8EE204C4AD020010AF890120FB
-:108A600092E24E2014400033241100018EE24E3079
-:108A7000000210C02442503802E220218C82000003
-:108A80001456001F000000008EE34E308EE24E347C
-:108A90001062001B000000008C82000424420001D0
-:108AA000AC8200048EE24E348EE34E30244200014C
-:108AB00010550007000000008EE24E3424420001F1
-:108AC0001062000500000000080032B7000000003E
-:108AD00014600005000000008F820128244200205D
-:108AE000AF8201288F8201288C8200042C42001161
-:108AF00050400010AC800000080032CA00000000A6
-:108B00008EE24E3024420001505500030000102137
-:108B10008EE24E3024420001AEE24E308EE24E3004
-:108B2000000210C02442503802E22021AC9600001E
-:108B3000AC9E00041620000D00000000A60C000AE8
-:108B4000A60A000E8F820100AFA200108F820104DE
-:108B50003C0400012484589C3C050006AFA200148C
-:108B60008EE6724C0800343B34A5F00B3C0100014A
-:108B700000370821A02083C0ADAB00008EE201D8F1
-:108B80008EE3724C2442FFFFAEE201D88EE201D8A0
-:108B900024630001306307FF26E2524415A2000659
-:108BA000AEE3724C8EE201D02442FFFFAEE201D070
-:108BB000080032EF8EE201D08EE201CC2442FFFFAA
-:108BC000AEE201CC8EE201CC8F4202401040007335
-:108BD000000000008EE20E1C24420001AEE20E1CDA
-:108BE0008F4302400043102B144001760000A02167
-:108BF0008F830120276238002466002000C2102BDA
-:108C000050400001276630008F82012810C2000406
-:108C1000000000008F82012414C200070000000041
-:108C20008EE201A40000882124420001AEE201A4EA
-:108C30000800334F8EE201A48EE2724CAC62001C3D
-:108C40008EE404A88EE504AC2462001CAC6200082B
-:108C500024020008A462000E24020011AC62001875
-:108C6000AC640000AC6500048EE204C4AC62001089
-:108C7000AF86012092E24E201440003324110001FF
-:108C80008EE24E30000210C02442503802E2202111
-:108C90008C820000144E001F000000008EE34E3056
-:108CA0008EE24E341062001B000000008C82000433
-:108CB00024420001AC8200048EE24E348EE34E303A
-:108CC0002442000110550007000000008EE24E34DF
-:108CD0002442000110620005000000000800333C3F
-:108CE0000000000014600005000000008F820128D1
-:108CF00024420020AF8201288F8201288C82000448
-:108D00002C42001150400010AC8000000800334F8E
-:108D1000000000008EE24E30244200015055000356
-:108D2000000010218EE24E3024420001AEE24E30AF
-:108D30008EE24E30000210C02442503802E2202160
-:108D4000AC8E0000AC9E00045620000D24110001E2
-:108D50008EE2724C3C040001248458A8AFA0001499
-:108D6000AFA200108EE6724C8F4702803C050009CE
-:108D700034A5F0080C002403AFAE00488FAE0048C5
-:108D800056200001AEE00E1C8EE201882442000154
-:108D9000AEE20188080033C88EE201888F8301208B
-:108DA000276238002466002000C2102B50400001CA
-:108DB000276630008F82012810C2000400000000E6
-:108DC0008F82012414C20007000000008EE201A47B
-:108DD0000000882124420001AEE201A4080033BA59
-:108DE0008EE201A48EE2724CAC62001C8EE404A8F8
-:108DF0008EE504AC2462001CAC620008240200086A
-:108E0000A462000E24020011AC620018AC640000E1
-:108E1000AC6500048EE204C4AC620010AF86012091
-:108E200092E24E2014400033241100018EE24E30B5
-:108E3000000210C02442503802E220218C8200003F
-:108E4000144E001F000000008EE34E308EE24E34C0
-:108E50001062001B000000008C820004244200010C
-:108E6000AC8200048EE24E348EE34E302442000188
-:108E700010550007000000008EE24E34244200012D
-:108E80001062000500000000080033A70000000089
-:108E900014600005000000008F8201282442002099
-:108EA000AF8201288F8201288C8200042C4200119D
-:108EB00050400010AC800000080033BA00000000F1
-:108EC0008EE24E3024420001505500030000102174
-:108ED0008EE24E3024420001AEE24E308EE24E3041
-:108EE000000210C02442503802E22021AC8E000063
-:108EF000AC9E00041620000D000000008EE2724CB3
-:108F00003C040001248458A8AFA00014AFA20010B4
-:108F10008EE6724C8F4702803C05000934A5F008AC
-:108F20000C002403AFAE00488FAE00488EE20174FF
-:108F300024420001AEE201748EE201740800346E36
-:108F40000000A021960C000A0183102B5440000160
-:108F500001801821A603000A8F88012027623800AB
-:108F6000250900200122102B504000012769300004
-:108F70008F82012811220004000000008F8201244A
-:108F800015220007240400208EE201A4000088219D
-:108F900024420001AEE201A40800342F8EE201A4B5
-:108FA0008EE5724C8EE604908EE70494A504000EC4
-:108FB00024040004AD100008AD0400180005294089
-:108FC00000A018210000102100E3382100E3202B2D
-:108FD00000C2302100C43021AD060000AD070004FE
-:108FE0008EE2724CAD02001C8EE204C4AD02001091
-:108FF000AF89012092E24E20144000332411000179
-:109000008EE24E30000210C02442503802E220218D
-:109010008C8200001456001F000000008EE34E30CA
-:109020008EE24E341062001B000000008C820004AF
-:1090300024420001AC8200048EE24E348EE34E30B6
-:109040002442000110550007000000008EE24E345B
-:109050002442000110620005000000000800341CDA
-:109060000000000014600005000000008F8201284D
-:1090700024420020AF8201288F8201288C820004C4
-:109080002C42001150400010AC8000000800342F2A
-:10909000000000008EE24E302442000150550003D3
-:1090A000000010218EE24E3024420001AEE24E302C
-:1090B0008EE24E30000210C02442503802E22021DD
-:1090C000AC960000AC9E00041620001D00000000BD
-:1090D000A60C000A8F820100AFA200108F8201044B
-:1090E0003C0400012484589C3C050006AFA20014F7
-:1090F0008EE6724C34A5F00D0C00240302003821DA
-:1091000093A2003710400031340F81008E420004DA
-:109110008E4300088E44000CA64F000CAE420000A7
-:10912000AE430004AE44000896020016A642000EAC
-:109130009602000E3042FDFF08003470A602000EB9
-:109140008EE201D82442FFFFAEE201D88EE201D8C0
-:109150008EE201CC3C04001F3C01000100370821D5
-:10916000A03E83C02442FFFFAEE201CC9603000A7A
-:109170003484FFFF8EE201CC006A1821026398213B
-:109180000093202B108000033C02FFF534421000B6
-:1091900002629821ADAB00008EE2724C24420001C5
-:1091A000304207FFAEE2724C8F4202401040000492
-:1091B0000283A0238EE20E1C24420001AEE20E1CAC
-:1091C000A3A000271680FD290000000012800024C3
-:1091D000000000003C01000100370821AC3483C4CA
-:1091E0003C01000100370821AC3383C83C01000179
-:1091F00000370821AC3283CC93A20037104000081E
-:10920000000000003C020001005710218C4283CC7A
-:10921000244200043C01000100370821AC2283CC29
-:109220008EE2724C8F43028024420001304207FFDD
-:1092300014620006000000008EE201C42442000116
-:10924000AEE201C4080034CC8EE201C48EE201BC5F
-:1092500024420001AEE201BC080034CC8EE201BC25
-:1092600097A4001E2484FFFC008018218EE400C017
-:109270008EE500C40000102100A3282100A3302B9C
-:109280000082202100862021AEE400C0AEE500C4AB
-:109290008FAF002C2402000211E2000F29E200032C
-:1092A000144000172402000315E20015000000001E
-:1092B0008EE200D08EE300D4246300012C64000110
-:1092C00000441021AEE200D0AEE300D48EE200D024
-:1092D000080034C68EE300D48EE200D88EE300DCB2
-:1092E000246300012C64000100441021AEE200D888
-:1092F000AEE300DC8EE200D8080034C68EE300DC6A
-:109300008EE200C88EE300CC246300012C640001CF
-:1093100000441021AEE200C8AEE300CC8EE200C8EB
-:109320008EE300CC8F8300E48F8200E010620003A4
-:1093300024630008AF8300E4AF8300E88FBF0070B0
-:109340008FBE006C8FB600688FB500648FB400606C
-:109350008FB3005C8FB200588FB100548FB00050B3
-:1093600003E0000827BD007827BDFFB0AFB500447B
-:109370000000A821AFB0003000008021AFBF004C3A
-:10938000AFB60048AFB40040AFB3003CAFB2003856
-:10939000AFB100348EE204D4241400013042000145
-:1093A0001440002A0000B0218F8700E08F8800C49D
-:1093B0008F8200E800E220232C8210005040000140
-:1093C00024841000000420C2008018218EE400C80C
-:1093D0008EE500CC0000102100A3282100A3302B33
-:1093E0000082202100862021AEE400C8AEE500CC3A
-:1093F0008F8300C83C02000A3442EFFF01032023A0
-:109400000044102B104000033C02000A3442F000DC
-:1094100000822021008018218EE400C08EE500C467
-:109420000000102100A3282100A3302B008220215E
-:1094300000862021AEE400C0AEE500C4AF8800C8BD
-:10944000AF8700E408003850AF8700E83C02000115
-:1094500000571021904283C01040000B0000000014
-:109460003C130001027798218E7383C43C110001E4
-:10947000023788218E3183C83C12000102579021A7
-:10948000080036E88E5283CC8F8300E08F8200E4A0
-:1094900010430007000048218F8200E424090001E6
-:1094A0008C4300008C440004AFA30018AFA4001C40
-:1094B0001520000E3C02FFFF8F8200C4AFA20010F7
-:1094C0008F8200C83C04000124845870AFA20014AD
-:1094D0008F8600E08F8700E43C0500060C00240323
-:1094E00034A5F00008003850000000008FA3001CD5
-:1094F0008FB200183073FFFF2673FFFC0062102448
-:1095000010400058024088213C0200800062102474
-:109510001040000A3C0400408EE2007C244200011E
-:10952000AEE2007C8EE2007C8EE201FC244200016F
-:10953000AEE201FC0800384A8EE201FC3C06000461
-:109540003C0B00013C0A00023C0500103C090008ED
-:109550008EE200803C080020340780002442000195
-:10956000AEE200808EE200808FA2001C004418242E
-:109570001066002100C3102B1440000700000000FB
-:10958000106B001100000000106A001500000000C0
-:1095900008003592000420421065002300A3102B20
-:1095A00014400005000000001069001900000000D0
-:1095B00008003592000420421068002100000000DD
-:1095C00008003592000420428EE20034244200015B
-:1095D000AEE200348EE200340800359200042042EE
-:1095E0008EE201EC24420001AEE201EC8EE201ECDD
-:1095F00008003592000420428EE201F0244200016E
-:10960000AEE201F08EE201F0080035920004204243
-:109610008EE201F424420001AEE201F48EE201F494
-:1096200008003592000420428EE2003024420001FE
-:10963000AEE200308EE20030080035920004204295
-:109640008EE201F824420001AEE201F88EE201F858
-:1096500000042042108702B70000000008003557C0
-:10966000000000003C02000100571021904283B22C
-:1096700014400084240200013C03000100771821FB
-:10968000906383B31462007F3C0201008E430000AC
-:10969000006210241040006F2402FFFF14620005D6
-:1096A00024100001964300043402FFFF106200758D
-:1096B0000000000092E204D8144000720000000094
-:1096C0003C020001005710218C4283B4284200055F
-:1096D00010400020000038213C02000100571021FA
-:1096E0008C4283B418400016000028219626000002
-:1096F000000520C0009710219442777E144600098F
-:10970000009710219443778096220002146200058E
-:10971000009710219443778296220004506200083B
-:10972000240700013C020001005710218C4283B441
-:1097300024A5000100A2102A5440FFEE000520C01D
-:1097400030E200FF1040027B000000000800361EDF
-:1097500000000000024020210C0022FE240500062B
-:109760003044001F000428C002E510219442727C9E
-:10977000304240001440026F00B710219443727EC3
-:10978000962200001462000B000418C000B71021DC
-:10979000944372809622000214620006000418C0EE
-:1097A00000B71021944372829622000410620035A3
-:1097B000000418C002E310219442727C3042800001
-:1097C0001440025C02E310219448727C962700004A
-:1097D000000828C000B710219442737E08003600AC
-:1097E00000003021000420C002E410219443737C67
-:1097F00002E410219448737C3063800014600010F0
-:10980000000828C000B710219442737E1447FFF56A
-:109810000100202100B7102194437380962200029A
-:109820005462FFF1000420C000B7102194437382FA
-:10983000962200045462FFEC000420C024060001BC
-:1098400030C200FF1040023B000000000800361E3E
-:1098500000000000974302029642000014620235A5
-:109860000000000097430204964200021462023195
-:109870000000000097430206964200041462022D85
-:1098800000000000924200003A0300013042000153
-:1098900000431024104000742402FFFF8E230000B8
-:1098A000146200043402FFFF962300041062006F6C
-:1098B000241400023C02000100571021904283B2A0
-:1098C0001440006A2414000392E204D81440006794
-:1098D000000000003C020001005710218C4283B4BC
-:1098E0002842000510400020000038213C02000101
-:1098F000005710218C4283B4184000160000282124
-:1099000096260000000520C0009710219442777E23
-:109910001446000900971021944377809622000294
-:109920001462000500971021944377829622000468
-:1099300050620008240700013C020001005710217A
-:109940008C4283B424A5000100A2102A5440FFEEEB
-:10995000000520C030E200FF14400044241400033E
-:109960000800384A00000000024020210C0022FEBE
-:10997000240500063044001F000428C002E5102121
-:109980009442727C30424000144001EA00B710213A
-:109990009443727E962200001462000B000418C0EB
-:1099A00000B71021944372809622000214620006D0
-:1099B000000418C000B7102194437282962200045C
-:1099C00010620027000418C002E310219442727C48
-:1099D00030428000144001D702E310219448727C89
-:1099E00096270000000828C000B710219442737E1B
-:1099F0000800368500003021000420C002E4102158
-:109A00009443737C02E410219448737C306380009B
-:109A100014600010000828C000B710219442737E23
-:109A20001447FFF50100202100B7102194437380F3
-:109A3000962200025462FFF1000420C000B71021FA
-:109A400094437382962200045462FFEC000420C009
-:109A50002406000130C200FF104001B600000000E3
-:109A60000800369824140003241400018F42026079
-:109A70000053102B10400049000000008F8300E4C9
-:109A80008F8200E01062000324630008AF8300E4CB
-:109A9000AF8300E88EE400C08EE500C402601821A8
-:109AA0000000102100A3282100A3302B00822021D8
-:109AB00000862021AEE400C0AEE500C48EE200586E
-:109AC00024420001AEE200588EE200588EE2007C93
-:109AD00024420001AEE2007C8EE2007C8F8200E036
-:109AE000AFA200108F8200E43C0400012484587867
-:109AF000AFA200148FA600188FA7001C3C0500061B
-:109B00000C00240334A5F0030800385000000000C6
-:109B10008EE25240AFA200108EE252443C0400019B
-:109B200024845884AFA200148EE60E108EE70E181F
-:109B30000C00240334A5F0028EE201C0244200018F
-:109B4000AEE201C08EE200008EE301C02403FFBF3D
-:109B500000431024080037F8AEE200008EE25240C5
-:109B6000AFA200108EE252443C04000124845884C9
-:109B7000AFA200148EE60E108EE70E183C0500060C
-:109B80000C00240334A5F0028EE201C0244200013F
-:109B9000AEE201C0080037F88EE201C096E2046828
-:109BA0000053102B544000013C158000126001311D
-:109BB0003C0C001F358CFFFF8EE2724C8F430280FD
-:109BC00024420001304207FF10620108000000003B
-:109BD00012A00014000000008EE352408EE25244B6
-:109BE0001062000926EE52448EEB52448EE352443A
-:109BF000000211402442524802E280212463000105
-:109C000008003712306800FF92E272481440FFC02B
-:109C10003C0500068EE201E024420001AEE201E0D4
-:109C20008EE201E08EE30E108EE20E181062FFCB82
-:109C300026EE0E188EEB0E180000A8218EE30E18EB
-:109C40000002114024420E2002E280212463000120
-:109C5000306801FF96E2046A30420010104000179D
-:109C6000340281009643000C1462001400000000CE
-:109C70003C02000100571021904283C01440000FA5
-:109C8000000000009642000EA60200168E42000858
-:109C90008E4300048E4400002673FFFCAE42000C8D
-:109CA000AE430008AE4400049602000E26310004C4
-:109CB0002416000134420200A602000E9603000A98
-:109CC000026050210073102B1040000202606821D6
-:109CD000006050212D42003D1040002A0000382134
-:109CE0009623000C2402080054620027AE110018CD
-:109CF0003C02000100571021904283C054400022D2
-:109D0000AE110018262200170182102B10400013FC
-:109D1000000000003C02FFF5005110219042101796
-:109D2000384300062C630001384200112C42000128
-:109D30000062182510600013262200100182102BEB
-:109D40001040000E000000003C07FFF500F1382134
-:109D500094E710100800375E24E7000E92220017E7
-:109D6000384300062C630001384200112C420001E8
-:109D70000062182550600004AE11001896270010EC
-:109D800024E7000EAE1100183C020001005710211C
-:109D9000904283C00002102B14E0000200024EC06B
-:109DA000014038218F83012027623800246600207B
-:109DB00000C2102B50400001276630008F8201281E
-:109DC00010C20004000000008F82012414C20007AA
-:109DD0002402000B8EE201A400004821244200016D
-:109DE000AEE201A4080037BF8EE201A48E04000099
-:109DF0008E050004AC62001801751025004910257D
-:109E0000AC710008A467000EAC62001CAC640000DA
-:109E1000AC6500048EE204C0AC620010AF86012085
-:109E200092E24E2014400038240900018EE24E30A8
-:109E3000000210C02442503802E220218C8300002E
-:109E40002402000714620020000000008EE34E3060
-:109E50008EE24E341062001C000000008C82000470
-:109E600024420001AC8200048EE34E348EE54E3075
-:109E7000240200402463000110620007000000007B
-:109E80008EE24E342442000110A2000500000000C2
-:109E9000080037A90000000014A000050000000021
-:109EA0008F82012824420020AF8201288F8201285E
-:109EB0008C8200042C42001150400013AC80000042
-:109EC000080037BF000000008EE24E30240300403F
-:109ED0002442000150430003000010218EE24E3066
-:109EE00024420001AEE24E308EE24E30000210C03D
-:109EF0002442503802E2202124020007AC820000F4
-:109F000024020001AC820004152000183C05000664
-:109F10008E0200183C04000124845890AFA2001067
-:109F20008E0200008E03000434A5F00902003021E7
-:109F30000C002403AFA3001432C200FF1040002B1A
-:109F4000340281008E4300048E4400088E45000CCC
-:109F5000A642000CAE430000AE440004AE4500082B
-:109F600096020016080037F8A642000E154D000AAA
-:109F7000000000009602000EA613000A34420004FE
-:109F8000A602000E3C01000100370821A02083C07A
-:109F9000080037F6000098219604000A0093102B61
-:109FA00010400002026018210080182124020001E4
-:109FB000A603000A3C01000100370821A02283C04B
-:109FC0009604000A022488210191102B10400003FE
-:109FD0003C02FFF5344210000222882102649823DB
-:109FE0000000A8211660FEF4ADC800001260002138
-:109FF00032C200FF3C01000100370821AC3383C4AA
-:10A000003C01000100370821AC3183C83C0100014C
-:10A010000037082110400008AC3283CC3C0200011C
-:10A02000005710218C4283CC244200043C010001E3
-:10A0300000370821AC2283CC8EE2724C8F43028021
-:10A040002442000114620006000000008EE201C4F8
-:10A0500024420001AEE201C4080038508EE201C47F
-:10A060008EE201BC24420001AEE201BC080038507F
-:10A070008EE201BC97A4001E2484FFFC00801821FE
-:10A080008EE400C08EE500C40000102100A328214A
-:10A0900000A3302B00822021008620212402000210
-:10A0A000AEE400C0AEE500C41282000F2A820003B5
-:10A0B000144000172402000316820015000000005F
-:10A0C0008EE200D08EE300D4246300012C640001F2
-:10A0D00000441021AEE200D0AEE300D48EE200D006
-:10A0E0000800384A8EE300D48EE200D88EE300DC0C
-:10A0F000246300012C64000100441021AEE200D86A
-:10A10000AEE300DC8EE200D80800384A8EE300DCC3
-:10A110008EE200C88EE300CC246300012C640001B1
-:10A1200000441021AEE200C8AEE300CC8EE200C8CD
-:10A130008EE300CC8F8300E48F8200E01062000386
-:10A1400024630008AF8300E4AF8300E88FBF004CB6
-:10A150008FB600488FB500448FB400408FB3003CE9
-:10A160008FB200388FB100348FB0003003E00008A8
-:10A1700027BD005027BDFF90AFB600600000B021A2
-:10A18000AFBF0068AFBE0064AFB5005CAFB40058AD
-:10A19000AFB30054AFB20050AFB1004CAFB0004805
-:10A1A0008EE204D400008821241500013042000111
-:10A1B0001440002AA3A0002F8F8700E08F8800C4DE
-:10A1C0008F8200E800E220232C8210005040000122
-:10A1D00024841000000420C2008018218EE400C8EE
-:10A1E0008EE500CC0000102100A3282100A3302B15
-:10A1F0000082202100862021AEE400C8AEE500CC1C
-:10A200008F8300C83C02000A3442EFFF0103202381
-:10A210000044102B104000033C02000A3442F000BE
-:10A2200000822021008018218EE400C08EE500C449
-:10A230000000102100A3282100A3302B0082202140
-:10A2400000862021AEE400C0AEE500C4AF8800C89F
-:10A25000AF8700E408003C5BAF8700E83C020001E8
-:10A2600000571021904283C01040000B00000000F6
-:10A270003C130001027798218E7383C43C100001C7
-:10A28000021780218E1083C83C12000102579021D2
-:10A2900008003A598E5283CC8F8300E08F8200E40D
-:10A2A00010430007000038218F8200E424070001DA
-:10A2B0008C4300008C440004AFA30018AFA4001C22
-:10A2C00014E0000E3C02FFFF8F8200C4AFA200101A
-:10A2D0008F8200C83C040001248458B4AFA200144B
-:10A2E0008F8600E08F8700E43C0500060C00240305
-:10A2F00034A5F20008003C5B000000008FA3001CA6
-:10A300008FB200183073FFFF2673FFFC0062102429
-:10A3100010400058024080213C020080006210245E
-:10A320001040000A3C0400408EE2007C2442000100
-:10A33000AEE2007C8EE2007C8EE201FC2442000151
-:10A34000AEE201FC08003C558EE201FC3C06000434
-:10A350003C0B00013C0A00023C0500103C090008CF
-:10A360008EE200803C080020340780002442000177
-:10A37000AEE200808EE200808FA2001C0044182410
-:10A380001066002100C3102B1440000700000000DD
-:10A39000106B001100000000106A001500000000A2
-:10A3A00008003916000420421065002300A3102B7A
-:10A3B00014400005000000001069001900000000B2
-:10A3C0000800391600042042106800210000000037
-:10A3D00008003916000420428EE2003424420001B5
-:10A3E000AEE200348EE20034080039160004204248
-:10A3F0008EE201EC24420001AEE201EC8EE201ECBF
-:10A4000008003916000420428EE201F024420001C7
-:10A41000AEE201F08EE201F008003916000420429D
-:10A420008EE201F424420001AEE201F48EE201F476
-:10A4300008003916000420428EE200302442000158
-:10A44000AEE200308EE200300800391600042042EF
-:10A450008EE201F824420001AEE201F88EE201F83A
-:10A46000000420421087033E00000000080038DB93
-:10A47000000000003C02000100571021904283B20E
-:10A4800014400084240200013C03000100771821DD
-:10A49000906383B31462007F3C0201008E4300008E
-:10A4A000006210241040006F2402FFFF14620005B8
-:10A4B00024110001964300043402FFFF106200756E
-:10A4C0000000000092E204D8144000720000000076
-:10A4D0003C020001005710218C4283B42842000541
-:10A4E00010400020000038213C02000100571021DC
-:10A4F0008C4283B418400016000028219606000004
-:10A50000000520C0009710219442777E1446000970
-:10A510000097102194437780960200021462000590
-:10A52000009710219443778296020004506200083D
-:10A53000240700013C020001005710218C4283B423
-:10A5400024A5000100A2102A5440FFEE000520C0FF
-:10A5500030E200FF1040030200000000080039A2B2
-:10A5600000000000024020210C0022FE240500060D
-:10A570003044001F000428C002E510219442727C80
-:10A5800030424000144002F600B710219443727E1E
-:10A59000960200001462000B000418C000B71021DE
-:10A5A000944372809602000214620006000418C0F0
-:10A5B00000B71021944372829602000410620035A5
-:10A5C000000418C002E310219442727C30428000E3
-:10A5D000144002E302E31021944D727C96070000C0
-:10A5E000000D28C000B710219442737E0800398402
-:10A5F00000003021000420C002E410219443737C49
-:10A6000002E41021944D737C3063800014600010CC
-:10A61000000D28C000B710219442737E1447FFF547
-:10A6200001A0202100B710219443738096020002FC
-:10A630005462FFF1000420C000B7102194437382DC
-:10A64000960200045462FFEC000420C024060001BE
-:10A6500030C200FF104002C200000000080039A212
-:10A66000000000009743020296420000146202BC00
-:10A67000000000009743020496420002146202B8F0
-:10A68000000000009743020696420004146202B4E0
-:10A6900000000000924200003A2300013042000115
-:10A6A00000431024104000742402FFFF8E030000BA
-:10A6B000146200043402FFFF960300041062006F6E
-:10A6C000241500023C02000100571021904283B281
-:10A6D0001440006A2415000392E204D81440006775
-:10A6E000000000003C020001005710218C4283B49E
-:10A6F0002842000510400020000038213C020001E3
-:10A70000005710218C4283B4184000160000282105
-:10A7100096060000000520C0009710219442777E25
-:10A720001446000900971021944377809602000296
-:10A73000146200050097102194437782960200046A
-:10A7400050620008240700013C020001005710215C
-:10A750008C4283B424A5000100A2102A5440FFEECD
-:10A76000000520C030E200FF14400044241500031F
-:10A7700008003C5500000000024020210C0022FE91
-:10A78000240500063044001F000428C002E5102103
-:10A790009442727C304240001440027100B7102194
-:10A7A0009443727E960200001462000B000418C0ED
-:10A7B00000B71021944372809602000214620006D2
-:10A7C000000418C000B7102194437282960200045E
-:10A7D00010620027000418C002E310219442727C2A
-:10A7E000304280001440025E02E31021944D727CDE
-:10A7F00096070000000D28C000B710219442737E18
-:10A8000008003A0900003021000420C002E41021B1
-:10A810009443737C02E41021944D737C3063800078
-:10A8200014600010000D28C000B710219442737E00
-:10A830001447FFF501A0202100B710219443738035
-:10A84000960200025462FFF1000420C000B71021FC
-:10A8500094437382960200045462FFEC000420C00B
-:10A860002406000130C200FF1040023D000000003D
-:10A8700008003A1C24150003241500018F420260D1
-:10A880000053102B10400036000000008F8300E4BE
-:10A890008F8200E01062000324630008AF8300E4AD
-:10A8A000AF8300E88EE400C08EE500C4026018218A
-:10A8B0000000102100A3282100A3302B00822021BA
-:10A8C00000862021AEE400C0AEE500C48EE2005850
-:10A8D00024420001AEE200588EE200588EE2007C75
-:10A8E00024420001AEE2007C8EE2007C8F8200E018
-:10A8F000AFA200108F8200E43C040001248458C001
-:10A90000AFA200148FA600188FA7001C3C050006FC
-:10A910000C00240334A5F20308003C5B0000000097
-:10A920008EE25240AFA200108EE252443C0400017D
-:10A93000248458CCAFA200148EE60E108EE70E18B9
-:10A940003C0500060C00240334A5F2028EE201C08F
-:10A9500024420001AEE201C008003C028EE201C0C8
-:10A9600096E204680053102B544000013C1680000E
-:10A97000126001CB3C0E001F35CEFFFF3C0FFFF5F0
-:10A9800035EF1000241E00408EE2724C8F4302808F
-:10A9900024420001304207FF1062019E00000000C7
-:10A9A00012C00012000000008EE352408EE25244BA
-:10A9B0001062000A26F852448EF45244AFB80024C4
-:10A9C0008EE35244000211402442524802E28821A0
-:10A9D0002463000108003A85306D00FF8EE201E03B
-:10A9E00024420001AEE201E08EE201E08EE30E10AF
-:10A9F0008EE20E181062FFCA26F80E188EF40E189A
-:10AA00000000B021AFB800248EE30E180002114000
-:10AA100024420E2002E2882124630001306D01FFF0
-:10AA200096E2046A3042001010400018340281009F
-:10AA30009643000C14620015000000003C02000167
-:10AA400000571021904283C0144000100000000005
-:10AA50009642000EA62200168E4200088E43000485
-:10AA60008E4400002673FFFCAE42000CAE4300088B
-:10AA7000AE4400049622000E2610000424180001A3
-:10AA8000A3B8002F34420200A622000E8E2200003E
-:10AA90008E2300043C04000134843800020030217D
-:10AAA000306A0007020A8023036410210202102B7F
-:10AAB00010400005026A9821020410230362182343
-:10AAC0003C02002000438023266200079623000AF0
-:10AAD0002418FFF80058C824006A18210079102BA8
-:10AAE00010400002032060210060602101801821D5
-:10AAF000246200072418FFF800586024026C102B11
-:10AB000014400004019328230183282308003AC33A
-:10AB100000C3102100D31021004A202301C4102BB0
-:10AB200054400001008F202125420040004C102B92
-:10AB3000144000350000582194C3000C2402080082
-:10AB400054620032AE2600183C020001005710216A
-:10AB5000904283C05440002DAE26001824C2001736
-:10AB600001C2102B10400013000000003C02FFF552
-:10AB70000046102190421017384300062C63000154
-:10AB8000384200112C4200010062182510600014A8
-:10AB900024C2001001C2102B1040000E0000000063
-:10ABA0003C0BFFF501665821956B101008003AF434
-:10ABB0002562000E90C20017384300062C63000186
-:10ABC000384200112C420001006218251060000577
-:10ABD0000160182194CB00102562000E004A582114
-:10ABE00001601821246200072418FFF80058582437
-:10ABF00000C31021004A202301C4102B1040000282
-:10AC000001632823008F2021AE2600183C0200019A
-:10AC100000571021904283C00002102B000216C082
-:10AC200015600002AFA2004401805821308200016B
-:10AC3000104000070000402190880000248400019B
-:10AC400001C4102B1040000224A5FFFF008F20211B
-:10AC500050A0001200081C022CA20002544000095F
-:10AC600024A5FFFF948200002484000201024021F9
-:10AC700001C4102B1040000624A5FFFE08003B2154
-:10AC8000008F20219082000000021200010240216A
-:10AC900014A0FFF22CA2000200081C023102FFFFE8
-:10ACA000006240213108FFFF0140282111400011BE
-:10ACB000020020212CA200025440000924A5FFFF1D
-:10ACC00094820000248400020102402101C4102B60
-:10ACD0001040000624A5FFFE08003B38008F20210D
-:10ACE00090820000000212000102402114A0FFF235
-:10ACF0002CA2000200081C023102FFFF006240216A
-:10AD000000081C023102FFFF8F89012000624021F0
-:10AD100027623800252300200062102B1440000217
-:10AD20003108FFFF276330008F8201281062000482
-:10AD3000000000008F8201241462000701402821D6
-:10AD40008EE201A40000382124420001AEE201A4F9
-:10AD500008003BC98EE201A48E2600008E27000465
-:10AD6000000814003448000BAD300008A52B000E7D
-:10AD7000AD2800188FB8004400002021029610254D
-:10AD800000581025AD22001C00E5102B00E53823EB
-:10AD900000C4302300C23023AD260000AD270004DC
-:10ADA0008EE204C0AD220010AF83012092E24E205B
-:10ADB0001440005F240700012502FFEE2C42000230
-:10ADC00014400003240200111502002400000000BA
-:10ADD0008EE24E30000210C02442503802E22021A0
-:10ADE0008C830000240200121462000F0000000097
-:10ADF0008EE34E308EE24E341062000B00000000F5
-:10AE00008C82000424420001AC8200048EE24E34A5
-:10AE10008EE34E3024420001105E002A0000000044
-:10AE200008003BA8000000008EE24E3024420001E2
-:10AE3000505E0003000010218EE24E3024420001DB
-:10AE4000AEE24E308EE24E30000210C02442503846
-:10AE500002E2202108003BC6240200128EE24E309E
-:10AE6000000210C02442503802E220218C830000EE
-:10AE7000240200071462001F000000008EE34E3021
-:10AE80008EE24E341062001B000000008C82000431
-:10AE900024420001AC8200048EE24E348EE34E3038
-:10AEA00024420001105E0007000000008EE24E34D4
-:10AEB00024420001106200050000000008003BB4BD
-:10AEC0000000000014600005000000008F820128CF
-:10AED00024420020AF8201288F8201288C82000446
-:10AEE0002C42001150400012AC80000008003BC909
-:10AEF000000000008EE24E3024420001505E00034C
-:10AF0000000010218EE24E3024420001AEE24E30AD
-:10AF10008EE24E30000210C02442503802E220215E
-:10AF200024020007AC82000024020001AC8200046D
-:10AF300014E000193C0500063C04000124845890EC
-:10AF40008E22001834A5F209AFA200108E22000054
-:10AF50008E23000402203021016038210C002403DC
-:10AF6000AFA3001493A2002F1040002A34028100E6
-:10AF70008E4300048E4400088E45000CA642000C4F
-:10AF8000AE430000AE440004AE4500089622001611
-:10AF900008003C02A642000E1599000A026A182316
-:10AFA0009622000EA623000A34420004A622000EB8
-:10AFB0003C01000100370821A02083C008003BFFAE
-:10AFC000000098219624000A0083102B54400001B1
-:10AFD0000080182124020001A623000A3C01000180
-:10AFE00000370821A02283C09622000A004A1821B7
-:10AFF0000203802101D0102B54400001020F802158
-:10B00000026398230000B0218FB800241660FE5E12
-:10B01000AF0D000012600022000000003C010001A2
-:10B0200000370821AC3383C43C01000100370821FC
-:10B03000AC3083C83C01000100370821AC3283CC1E
-:10B0400093A2002F10400008000000003C02000105
-:10B05000005710218C4283CC244200043C010001A3
-:10B0600000370821AC2283CC8F4302808EE2724CE1
-:10B0700014620006000000008EE201C424420001B8
-:10B08000AEE201C408003C5B8EE201C48EE201BC6A
-:10B0900024420001AEE201BC08003C5B8EE201BC30
-:10B0A00097A4001E2484FFFC008018218EE400C0B9
-:10B0B0008EE500C40000102100A3282100A3302B3E
-:10B0C000008220210086202124020002AEE400C07C
-:10B0D000AEE500C412A2000F2AA20003144000171C
-:10B0E0002402000316A20015000000008EE200D02A
-:10B0F0008EE300D4246300012C640001004410217D
-:10B10000AEE200D0AEE300D48EE200D008003C55A1
-:10B110008EE300D48EE200D88EE300DC24630001CD
-:10B120002C64000100441021AEE200D8AEE300DC44
-:10B130008EE200D808003C558EE300DC8EE200C8A9
-:10B140008EE300CC246300012C6400010044102134
-:10B15000AEE200C8AEE300CC8EE200C88EE300CCC5
-:10B160008F8300E48F8200E01062000324630008F4
-:10B17000AF8300E4AF8300E88FBF00688FBE006438
-:10B180008FB600608FB5005C8FB400588FB3005449
-:10B190008FB200508FB1004C8FB0004803E0000820
-:10B1A00027BD007027BDFFE0AFBF00188EE30E146F
-:10B1B0008EE20E0C10620074000000008EE30E0C94
-:10B1C0008EE20E1400622023048200012484020017
-:10B1D0008EE30E188EE20E140043102B1440000470
-:10B1E000240202008EE30E1408003C7D0043182365
-:10B1F0008EE20E188EE30E14004310232443FFFF4B
-:10B20000008048210069102A544000010060482154
-:10B210008F8701002762300024E800200102102BF4
-:10B2200050400001276828008F82010811020004A5
-:10B23000000000008F8201041502000700001021A9
-:10B240008EE201A80000202124420001AEE201A804
-:10B2500008003CBF8EE201A88EE40E1400042140D9
-:10B26000008018218EE404608EE5046400A3282188
-:10B2700000A3302B0082202100862021ACE40000B6
-:10B28000ACE500048EE30E1400091140A4E2000EA8
-:10B2900024020002ACE200180003194024630E20CF
-:10B2A00002E31021ACE200088EE20E14ACE2001CB6
-:10B2B0008EE204CCACE20010AF88010092E204EC14
-:10B2C00014400011240400018EE24E2824030040A3
-:10B2D0002442000150430003000010218EE24E285A
-:10B2E00024420001AEE24E288EE24E28000210C039
-:10B2F00024424E3802E2182124020002AC6200000F
-:10B3000024020001AC6200041480000E24030040FB
-:10B310008EE20E14AFA200108EE20E183C0500075C
-:10B32000AFA200148EE60E0C8EE70E103C04000156
-:10B33000248458D40C00240334A5F00108003CDD1B
-:10B34000000000008EE2050024420001504300038B
-:10B35000000010218EE2050024420001AEE205004B
-:10B360008EE205000002108000571021AC4905084C
-:10B370008EE20E1400491021304201FFAEE20E149D
-:10B380008EE30E148EE20E0C146200050000000025
-:10B390008F8200602403FDFF00431024AF82006011
-:10B3A0008FBF001803E0000827BD002027BDFFE085
-:10B3B000AFBF00188EE3523C8EE252381062007428
-:10B3C000000000008EE352388EE2523C00622023DF
-:10B3D00004820001248401008EE352448EE2523C38
-:10B3E0000043102B14400004240201008EE3523C61
-:10B3F00008003CFF004318238EE252448EE3523C87
-:10B40000004310232443FFFF008048210069102AD5
-:10B4100054400001006048218F87010027623000FE
-:10B4200024E800200102102B50400001276828006A
-:10B430008F82010811020004000000008F820104C5
-:10B4400015020007000010218EE201A80000202153
-:10B4500024420001AEE201A808003D418EE201A8AD
-:10B460008EE4523C00042140008018218EE40470D8
-:10B470008EE5047400A3282100A3302B0082202134
-:10B4800000862021ACE40000ACE500048EE3523CD1
-:10B4900000091140A4E2000E24020003ACE20018EF
-:10B4A000000319402463524802E31021ACE2000873
-:10B4B0008EE2523CACE2001C8EE204CCACE2001006
-:10B4C000AF88010092E204EC144000112404000152
-:10B4D0008EE24E2824030040244200015043000322
-:10B4E000000010218EE24E2824420001AEE24E28D8
-:10B4F0008EE24E28000210C024424E3802E218218B
-:10B5000024020003AC62000024020001AC620004CB
-:10B510001480000E240300408EE2523CAFA20010C3
-:10B520008EE252443C050007AFA200148EE652386A
-:10B530008EE752403C040001248458E00C002403B0
-:10B5400034A5F01008003D5F000000008EE2050009
-:10B550002442000150430003000010218EE2050048
-:10B5600024420001AEE205008EE2050000021080D8
-:10B5700000571021AC4905088EE2523C00491021C9
-:10B58000304200FFAEE2523C8EE3523C8EE2523833
-:10B5900014620005000000008F8200602403FEFF9B
-:10B5A00000431024AF8200608FBF001803E0000842
-:10B5B00027BD00208F8201208EE34E348F8201242C
-:10B5C0008F8601282402004024630001506200039A
-:10B5D000000010218EE24E3424420001AEE24E34CF
-:10B5E0008EE24E348EE44E348EE34E30000210C0B4
-:10B5F000244250381483000702E228218F82012858
-:10B6000024420020AF8201288F82012808003D9249
-:10B61000ACA000008EE24E3424030040244200011E
-:10B6200050430003000010218EE24E3424420001FA
-:10B63000000210C02442503802E228218CA20004EB
-:10B640008F8301280002114000621821AF83012876
-:10B65000ACA000008CC200182443FFFE2C62001234
-:10B6600010400008000310803C0100010022082166
-:10B670008C2258F000400008000000002402000165
-:10B68000AEE24E2403E000080000000027BDFFC822
-:10B69000AFBF0030AFB5002CAFB40028AFB300246B
-:10B6A000AFB20020AFB1001CAFB000188F830128EB
-:10B6B0008F820124106202B0000098213C11001F0B
-:10B6C0003631FFFF3C12FFF53652100024150012F0
-:10B6D000241400408F8C01288F82012824420020EE
-:10B6E000AF8201289182001B8F8301282443FFFE33
-:10B6F0002C6200121040029C000310803C010001EB
-:10B70000002208218C225948004000080000000057
-:10B710008F42021830420100104000070000000074
-:10B720009583001695820018006218230003140206
-:10B7300000431021A58200168D82001C3C0380006E
-:10B740003044FFFF004368243C03080000431824F2
-:10B7500011A00004AD84001C0004114008003DD875
-:10B76000244252480004114024420E2002E2582193
-:10B770009562000E3042FFFC10600004A562000ECE
-:10B780009584001608003EC0000000008D69001876
-:10B7900000004021952A000025290002952700007D
-:10B7A0002529000295260000252900029525000084
-:10B7B0002529000295240000252900029523000078
-:10B7C0002529000295220000252900020147502169
-:10B7D000014650210145502101445021014350218F
-:10B7E00001425021000A1C023142FFFF0062502139
-:10B7F000000A1C023142FFFF0062502196E2046AF7
-:10B80000314EFFFF30420002104000440000502142
-:10B81000252200140222102B1040001401201821B0
-:10B820002405000A000020210223102B54400001AF
-:10B8300000721821946200002463000224A5FFFF17
-:10B8400014A0FFF90082202100041C023082FFFFB7
-:10B8500000622021000414023083FFFF0043102106
-:10B860003042FFFF08003E3301425021952A00007C
-:10B8700025290002952800002529000295270000AF
-:10B8800025290002952600002529000295250000A3
-:10B890002529000295230000252900029522000099
-:10B8A0002529000295240000252900020148502185
-:10B8B00001475021014650210145502101435021AB
-:10B8C000014250219522000095230002014450219D
-:10B8D0000142502101435021000A1C023142FFFF66
-:10B8E00000625021000A1C023142FFFF0062502119
-:10B8F0003148FFFF510000013408FFFF8D6200183E
-:10B900009443000C2402080054620005A56800104E
-:10B910009562000E34420002A562000EA568001078
-:10B9200096E2046A000028213042000814400056C4
-:10B93000000030218D630018246200240222102BA5
-:10B9400010400034246900100229102B54400001DB
-:10B950000132482195250000246900140229102B8A
-:10B960001040000224A5FFEC01324821952200007E
-:10B9700030420FFF144000032529000208003E60FA
-:10B98000241300010000982100A030210229102B6F
-:10B990005440000101324821912200012529000272
-:10B9A00000A228210229102B544000010132482115
-:10B9B000252900020229102B5440000101324821A0
-:10B9C000952200002529000200A228210229102B1F
-:10B9D000544000010132482195220000252900022F
-:10B9E00000A228210229102B5440000101324821D5
-:10B9F000952200002529000200A228210229102BEF
-:10BA000054400001013248219522000008003E996F
-:10BA100000A2282194650010946200142469001685
-:10BA200030420FFF1440000324A5FFEC08003E8CB9
-:10BA3000241300010000982100A03021912300016F
-:10BA400025290004952200002529000295240000E4
-:10BA50002529000200A3282100A228219522000008
-:10BA60009523000200A4282100A2282100A3282158
-:10BA700000051C0230A2FFFF0062282100051C0205
-:10BA800030A2FFFF0062282196E2046A30420001E2
-:10BA90001040001E0000202195820016004E202339
-:10BAA0000004140200822021326200FF5040000294
-:10BAB000008620210085202100041402008220211C
-:10BAC0003084FFFF508000013404FFFF8D620018B6
-:10BAD000244300170223102B544000010072182148
-:10BAE00090620000384300112C63000138420006C8
-:10BAF0002C420001006218251060000400000000C4
-:10BB00009562000E34420001A562000E9562000E9F
-:10BB1000240A00023042000410400002A564001212
-:10BB2000240A00048F88012027623800250900209C
-:10BB30000122102B50400001276930008F8201281C
-:10BB400011220004000000008F820124152200074A
-:10BB5000240400208EE201A4000080212442000180
-:10BB6000AEE201A408003F4F8EE201A48EE5724CC4
-:10BB70008EE604908EE70494AD0B0008A504000E39
-:10BB8000AD0A00180005294000A01821000010216E
-:10BB900000E3382100E3202B00C2302100C4302113
-:10BBA000AD060000AD0700048EE2724C004D10257A
-:10BBB000AD02001C8EE204C4AD020010AF8901206A
-:10BBC00092E24E2014400060241000012543FFEE55
-:10BBD0002C630002394200112C420001006218253A
-:10BBE00010600024000000008EE24E30000210C001
-:10BBF0002442503802E220218C8200001455000FAC
-:10BC0000000000008EE34E308EE24E341062000BD6
-:10BC1000000000008C82000424420001AC82000479
-:10BC20008EE24E348EE34E30244200011054002B3D
-:10BC30000000000008003F2E000000008EE24E30A1
-:10BC40002442000150540003000010218EE24E30C7
-:10BC500024420001AEE24E308EE24E30000210C0AF
-:10BC60002442503802E220212402000108003F4E05
-:10BC7000AC9500008EE24E30000210C024425038D5
-:10BC800002E220218C830000240200071462001FBE
-:10BC9000000000008EE34E308EE24E341062001B36
-:10BCA000000000008C82000424420001AC820004E9
-:10BCB0008EE24E348EE34E302442000110540007D1
-:10BCC000000000008EE24E342442000110620005A4
-:10BCD0000000000008003F3A00000000146000056A
-:10BCE000000000008F82012824420020AF8201283A
-:10BCF0008F8201288C8200042C42001150400012D7
-:10BD0000AC80000008003F4F000000008EE24E3083
-:10BD10002442000150540003000010218EE24E30F6
-:10BD200024420001AEE24E308EE24E30000210C0DE
-:10BD30002442503802E2202124020007AC82000095
-:10BD400024020001AC8200041600000D0000000077
-:10BD50008F8201203C04000124845938AFA00014D4
-:10BD6000AFA200108D86001C8F8701243C050008BF
-:10BD70000C00240334A50001080040570000000017
-:10BD80008EE2724C24420001304207FF11A00006EF
-:10BD9000AEE2724C8EE201D02442FFFFAEE201D04F
-:10BDA00008003F6B8EE201D08EE201CC2442FFFFFF
-:10BDB000AEE201CC8EE201CC8EE201D82442FFFF3C
-:10BDC000AEE201D8080040578EE201D88F4202400F
-:10BDD000104000E5000000008EE20E1C244200012D
-:10BDE00008004057AEE20E1C9582001EAD82001C7A
-:10BDF0008F42024010400072000000008EE20E1CD4
-:10BE000024420001AEE20E1C8F4302400043102B7F
-:10BE1000144000D5000000008F8301202762380005
-:10BE20002466002000C2102B50400001276630001D
-:10BE30008F82012810C20004000000008F820124BC
-:10BE400014C20007000000008EE201A4000080215F
-:10BE500024420001AEE201A408003FDA8EE201A410
-:10BE60008EE2724CAC62001C8EE404A88EE504AC39
-:10BE70002462001CAC62000824020008A462000EC8
-:10BE800024020011AC620018AC640000AC65000430
-:10BE90008EE204C4AC620010AF86012092E24E2014
-:10BEA00014400034241000018EE24E30000210C015
-:10BEB0002442503802E220218C8200001455001FD9
-:10BEC000000000008EE34E308EE24E341062001B04
-:10BED000000000008C82000424420001AC820004B7
-:10BEE0008EE24E348EE34E3024420001105400079F
-:10BEF000000000008EE24E34244200011062000572
-:10BF00000000000008003FC60000000014600005AB
-:10BF1000000000008F82012824420020AF82012807
-:10BF20008F8201288C8200042C42001150400011A5
-:10BF3000AC80000008003FDA000000008EE24E30C6
-:10BF40002442000150540003000010218EE24E30C4
-:10BF500024420001AEE24E308EE24E30000210C0AC
-:10BF60002442503802E2202124020001AC95000056
-:10BF7000AC8200045600000B241000018EE2724CCB
-:10BF80003C040001248458A8AFA00014AFA2001004
-:10BF90008EE6724C8F4702803C0500090C0024039A
-:10BFA00034A5F00856000001AEE00E1C8EE20188B8
-:10BFB00024420001AEE20188080040508EE2018870
-:10BFC0008F830120276238002466002000C2102BD6
-:10BFD00050400001276630008F82012810C2000403
-:10BFE000000000008F82012414C20007000000003E
-:10BFF0008EE201A40000802124420001AEE201A4EF
-:10C00000080040448EE201A48EE2724CAC62001C37
-:10C010008EE404A88EE504AC2462001CAC62000827
-:10C0200024020008A462000E24020011AC62001871
-:10C03000AC640000AC6500048EE204C4AC62001085
-:10C04000AF86012092E24E201440003424100001FB
-:10C050008EE24E30000210C02442503802E220210D
-:10C060008C8200001455001F000000008EE34E304B
-:10C070008EE24E341062001B000000008C8200042F
-:10C0800024420001AC8200048EE24E348EE34E3036
-:10C090002442000110540007000000008EE24E34DC
-:10C0A000244200011062000500000000080040303A
-:10C0B0000000000014600005000000008F820128CD
-:10C0C00024420020AF8201288F8201288C82000444
-:10C0D0002C42001150400011AC8000000800404488
-:10C0E000000000008EE24E30244200015054000354
-:10C0F000000010218EE24E3024420001AEE24E30AC
-:10C100008EE24E30000210C02442503802E220215C
-:10C1100024020001AC950000AC8200041600000B64
-:10C12000000000008EE2724C3C040001248458A8F8
-:10C13000AFA00014AFA200108EE6724C8F470280B1
-:10C140003C0500090C00240334A5F0088EE20174BC
-:10C1500024420001AEE20174080040578EE20174EF
-:10C1600024020001AEE24E248F8301288F82012435
-:10C170001462FD58000000008FBF00308FB5002C06
-:10C180008FB400288FB300248FB200208FB1001C21
-:10C190008FB0001803E0000827BD003827BDFFE876
-:10C1A000278402082745020024060008AFBF0014B8
-:10C1B0000C00249AAFB000100000202124100001D0
-:10C1C0002402241FAF900210AF900200AF8002043F
-:10C1D000AF8202148F460248240300043C02004050
-:10C1E0003C010001AC235CC43C010001AC235CC8F1
-:10C1F0003C010001AC205D9C3C010001AC225CC014
-:10C200003C010001AC235CC80C005108240500046B
-:10C210000C004822000000008EE200003C03FEFFFC
-:10C220003463FFFD00431024AEE200003C023C00FA
-:10C23000AF82021C3C01000100370821AC3083AC06
-:10C240008FBF00148FB0001003E0000827BD001856
-:10C2500027BDFFE03C05000834A50400AFBF00186F
-:10C26000AFA00010AFA000148F8602003C040001B4
-:10C27000248459F00C002403000038218EE202804F
-:10C2800024420001AEE202808EE202808F8302002F
-:10C290003C023F00006218248FBF00183C020400DB
-:10C2A00003E0000827BD002027BDFFD8AFBF002056
-:10C2B000AFB1001CAFB000188F9002208EE20214C4
-:10C2C0000000382124420001AEE202148EE2021482
-:10C2D0003C02030002021024104000273C1104001D
-:10C2E0000C00429B000000003C02010002021024EE
-:10C2F00010400007000000008EE2021824420001F6
-:10C30000AEE202188EE20218080040C63C03FDFFB0
-:10C310008EE2021C24420001AEE2021C8EE2021CEC
-:10C320003C03FDFF3463FFFF3C0808FF3508FFFFB7
-:10C330008EE200003C040001248459FC3C05000806
-:10C340000200302100431024AEE200008F82022060
-:10C35000000038213C03030000481024004310254E
-:10C36000AF820220AFA000100C002403AFA0001485
-:10C370000800429600000000021110241040001F27
-:10C380003C0240008F830224240214021462000B3A
-:10C390003C03FDFF3C04000124845A083C050008CE
-:10C3A000AFA00010AFA000148F86022434A5FFFFB9
-:10C3B0000C002403000038213C03FDFF8EE2000046
-:10C3C0003463FFFF02002021004310240C004E5470
-:10C3D000AEE200008EE2022024420001AEE2022022
-:10C3E0008EE202208F8202203C0308FF3463FFFFAD
-:10C3F0000043102408004295005110250202102429
-:10C4000010400142000000008EE2022C2442000194
-:10C41000AEE2022C8EE2022C8F8202203C0308FF47
-:10C420003463FFFF0043102434420004AF82022033
-:10C430008F8300548F8200540800410E2463000251
-:10C440008F820054006210232C4200031440FFFC32
-:10C45000000000008F8600E08F8400E430C20007F7
-:10C4600010400012000000008F8300E42402FFF857
-:10C4700000C210241043000D000000008F82005401
-:10C480008F8300E014C30009244400508F820054BD
-:10C49000008210232C4200511040000400000000D4
-:10C4A0008F8200E010C2FFF9000000008F8202209E
-:10C4B0003C0308FF3463FFFD00431024AF820220D9
-:10C4C0008F8600E030C20007104000032402FFF80E
-:10C4D00000C23024AF8600E08F8300C43C02001FFE
-:10C4E0003442FFFF246800080048102B104000036E
-:10C4F0003C02FFF534421000010240218F8B00C83E
-:10C500008F8501208F8401240800414500006021AF
-:10C51000276238000082102B504000012764300051
-:10C5200010A40010318200FF8C82001838430007ED
-:10C530002C6300013842000B2C42000100621825D8
-:10C540005060FFF3248400208EE20240240C00019E
-:10C5500024420001AEE202408EE202408C8B0008D1
-:10C56000318200FF14400065000000003C02000121
-:10C5700000571021904283C014400060000000006A
-:10C580008F8400E400C41023000218C30462000179
-:10C59000246302008F8900C410600005240200019A
-:10C5A0001062000900000000080041870000000040
-:10C5B0008EE202300120582124420001AEE2023016
-:10C5C000080041BC8EE202308EE202343C05000AD3
-:10C5D00024420001AEE202348C8B000034A5F0004E
-:10C5E0008EE20234012B182300A3102B54400001CB
-:10C5F000006518212C62233F144000400000000019
-:10C600008F8200E824420008AF8200E88F8200E8B1
-:10C610008F8200E40120582124420008AF8200E408
-:10C62000080041BC8F8200E48EE202383C03000A1D
-:10C6300024420001AEE202388C8400003463F00032
-:10C640008EE20238008838230067102B5440000126
-:10C6500000E338213C02000334420D400047102B18
-:10C660001040000300000000080041BC0080582179
-:10C670008F8200E424440008AF8400E48F8400E447
-:10C68000108600183C05000A34A5F0003C0A00039F
-:10C69000354A0D408EE2007C24420001AEE2007C6F
-:10C6A0008C8300008EE2007C0068382300A7102BEA
-:10C6B0005440000100E538210147102B5440000789
-:10C6C000006058218F8200E424440008AF8400E415
-:10C6D0008F8400E41486FFEF00000000148600053C
-:10C6E0000000000001205821AF8600E4080041BC92
-:10C6F000AF8600E8AF8400E4AF8400E88F8200C812
-:10C700003C03000A3463F000004838230067102B14
-:10C710005440000100E338213C02000334420D3F45
-:10C720000047102B544000070000602101683823A7
-:10C730000067102B5440000300E33821080041CF6C
-:10C740003C0200033C02000334420D3F0047102B23
-:10C7500014400016318200FF144000060000000063
-:10C760003C02000100571021904283C01040000F8E
-:10C77000000000008EE2023C3C04FDFF8EE300005E
-:10C780003484FFFF24420001AEE2023C8EE2023C10
-:10C7900024020001006418243C0100010037082134
-:10C7A000A02283B80800422CAEE30000AF8B00C883
-:10C7B0008F8300C88F8200C43C04000A3484F000D8
-:10C7C000006238230087102B5440000100E4382118
-:10C7D0003C02000334420D400047102B2CE30001C3
-:10C7E0000043102510400008000000008F82022046
-:10C7F0003C0308FF3463FFFF004310243C03400068
-:10C8000000431025AF8202208F8600E08F8400E471
-:10C8100010C4002A000000008EE2007C24420001C7
-:10C82000AEE2007C8EE2007C24C2FFF8AF8200E022
-:10C830003C0200018C427E303C0300088F8600E001
-:10C84000004310241040001D0000000010C4001B15
-:10C85000240DFFF83C0A000A354AF0003C0C008029
-:10C86000248500082762280050A2000127651800CF
-:10C870008C8800048C8200008CA900003103FFFF2B
-:10C8800000431021004D102424430010006B102B96
-:10C8900054400001006A1821012B102B5440000164
-:10C8A000012A482110690002010C1025AC82000405
-:10C8B00000A0202114C4FFEB248500088F820220F1
-:10C8C0003C0308FF3463FFFF00431024344200029E
-:10C8D000AF8202208F8300548F82005408004237B9
-:10C8E000246300018F820054006210232C42000256
-:10C8F0001440FFFC000000008F8202203C0308FF70
-:10C900003463FFFB00431024AF8202200601005570
-:10C91000000000008EE2022824420001AEE202285C
-:10C920008EE202288F8202203C0308FF3463FFFF5F
-:10C930000043102434420004AF8202208F8300544D
-:10C940008F82005408004251246300028F820054F9
-:10C95000006210232C4200031440FFFC0000000082
-:10C960008F8600E030C20007104000120000000077
-:10C970008F8300E42402FFF800C210241043000D4E
-:10C98000000000008F8200548F8300E014C3000970
-:10C99000244400328F820054008210232C42003342
-:10C9A00010400004000000008F8200E010C2FFF978
-:10C9B000000000008F8202203C0308FF3463FFFD6B
-:10C9C00000431024AF8202208F8600E030C20007AF
-:10C9D000104000032402FFF800C23024AF8600E0BC
-:10C9E000240301F58F8200E800673823000718C090
-:10C9F00000431021AF8200E88F8200E8AF8200E49C
-:10CA00008EE2007C3C0408FF3484FFFF00471021C5
-:10CA1000AEE2007C8F8202203C038000346300027F
-:10CA20000044102400431025AF8202208F8300545D
-:10CA30008F8200540800428D246300018F820054CD
-:10CA4000006210232C4200021440FFFC0000000092
-:10CA50008F8202203C0308FF3463FFFB0043102455
-:10CA6000AF8202208FBF00208FB1001C8FB0001852
-:10CA700003E0000827BD00283C0200018C425CD87E
-:10CA800027BDFFD810400012AFBF00203C040001BA
-:10CA900024845A143C050008240200013C010001D2
-:10CAA00000370821AC2283ACAFA00010AFA0001467
-:10CAB0008F86022034A504983C010001AC205CD88C
-:10CAC0003C010001AC225CCC0C00240300003821A6
-:10CAD0008F4202683C037FFF3463FFFF0043102452
-:10CAE000AF4202688EE204D08EE404D42403FFFE39
-:10CAF00000431024308400021080011EAEE204D0F6
-:10CB00008EE204D42403FFFD00431024AEE204D4DB
-:10CB10008F8200443C03060034632000344200202E
-:10CB2000AF820044AFA300188EE206088F430228AC
-:10CB300024420001304A00FF514300FEAFA0001024
-:10CB40008EE20608000210C0005710218FA30018C3
-:10CB50008FA4001CAC43060CAC4406108F83005419
-:10CB60008F82005424690032012210232C420033AA
-:10CB70001040006A0000582124180008240F000DFE
-:10CB8000240D0007240C0040240E00018F87012093
-:10CB90002762380024E800200102102B50400001D9
-:10CBA000276830008F820128110200040000000075
-:10CBB0008F82012415020007000010218EE201A4DB
-:10CBC0000000282124420001AEE201A40800433DF8
-:10CBD0008EE201A48EE40608000420C00080182123
-:10CBE0008EE404308EE5043400A3282100A3302B0A
-:10CBF0000082202100862021ACE40000ACE5000486
-:10CC00008EE20608A4F8000EACEF0018ACEA001C97
-:10CC1000000210C02442060C02E21021ACE200081F
-:10CC20008EE204C4ACE20010AF88012092E24E20F4
-:10CC300014400033240500018EE24E30000210C083
-:10CC40002442503802E220218C820000144D001F43
-:10CC5000000000008EE34E308EE24E341062001B66
-:10CC6000000000008C82000424420001AC82000419
-:10CC70008EE24E348EE34E3024420001104C000709
-:10CC8000000000008EE24E342442000110620005D4
-:10CC9000000000000800432A0000000014600005A6
-:10CCA000000000008F82012824420020AF8201286A
-:10CCB0008F8201288C8200042C4200115040001009
-:10CCC000AC8000000800433D000000008EE24E30C2
-:10CCD00024420001504C0003000010218EE24E302F
-:10CCE00024420001AEE24E308EE24E30000210C00F
-:10CCF0002442503802E22021AC8D0000AC8E0004AA
-:10CD000054A00006240B00018F820054012210233E
-:10CD10002C4200331440FF9D00000000316300FFEF
-:10CD20002402000154620079AFA00010AEEA0608A8
-:10CD30008F8300548F820054246900320122102313
-:10CD40002C4200331040006100005821240D0008DF
-:10CD5000240C00112408001224070040240A0001BA
-:10CD60008F830120276238002466002000C2102B28
-:10CD700050400001276630008F82012810C2000455
-:10CD8000000000008F82012414C200070000000090
-:10CD90008EE201A40000282124420001AEE201A499
-:10CDA000080043A98EE201A48EE20608AC62001CD2
-:10CDB0008EE404A08EE504A42462001CAC6200088A
-:10CDC000A46D000EAC6C0018AC640000AC650004EF
-:10CDD0008EE204C4AC620010AF86012092E24E20C5
-:10CDE00014400033240500018EE24E30000210C0D2
-:10CDF0002442503802E220218C8200001448001F97
-:10CE0000000000008EE34E308EE24E341062001BB4
-:10CE1000000000008C82000424420001AC82000467
-:10CE20008EE24E348EE34E3024420001104700075C
-:10CE3000000000008EE24E34244200011062000522
-:10CE40000000000008004396000000001460000588
-:10CE5000000000008F82012824420020AF820128B8
-:10CE60008F8201288C8200042C4200115040001057
-:10CE7000AC800000080043A9000000008EE24E30A4
-:10CE80002442000150470003000010218EE24E3082
-:10CE900024420001AEE24E308EE24E30000210C05D
-:10CEA0002442503802E22021AC880000AC8A000401
-:10CEB00054A00006240B00018F820054012210238D
-:10CEC0002C4200331440FFA600000000316300FF35
-:10CED0002402000154620003AFA00010080043D6F2
-:10CEE000000000003C04000124845A20AFA000147C
-:10CEF0008F8601208F8701243C0500090C00240344
-:10CF000034A5F011080043D6000000003C040001E5
-:10CF100024845A2CAFA000148F8601208F8701240F
-:10CF20003C0500090C00240334A5F010080043D68A
-:10CF3000000000003C04000124845A38AFA0001413
-:10CF40008EE606088F4702283C0500090C002403E2
-:10CF500034A5F00F8EE201AC24420001AEE201AC38
-:10CF60008EE201AC8EE2015C24420001AEE2015C83
-:10CF70008EE2015C8FBF002003E0000827BD00287F
-:10CF80003C0200018C425CD827BDFFE01440000D3C
-:10CF9000AFBF00183C04000124845A443C0500083B
-:10CFA000AFA00010AFA000148F86022034A5049912
-:10CFB000240200013C010001AC225CD80C002403D7
-:10CFC000000038218EE204D03C03000100771821D4
-:10CFD000946383B23442000110600007AEE204D0D3
-:10CFE0008F8202203C0308FF3463FFFF00431024BC
-:10CFF00034420008AF820220000020210C0052A21F
-:10D0000024050004AF4202688FBF001803E0000847
-:10D0100027BD00200000000000000000000000000C
-:10D020000000000000000000000000000000000000
-:10D0300000000000000000000000000000000000F0
-:10D0400000000000000000000000000000000000E0
-:10D0500000000000000000000000000000000000D0
-:10D0600000000000000000000000000000000000C0
-:10D0700000000000000000000000000000000000B0
-:10D0800000000000000000000000000000000000A0
-:10D090000000000000000000000000000000000090
-:10D0A0000000000000000000000000000000000080
-:10D0B0000000000000000000000000000000000070
-:10D0C0000000000000000000000000000000000060
-:10D0D0000000000000000000000000000000000050
-:10D0E0000000000000000000000000000000000040
-:10D0F0000000000000000000000000000000000030
-:10D100000000000000000000000000003C120001D0
-:10D11000265212003C1400018E945C503C10000119
-:10D12000261011203C15C00036B500608E8A000024
-:10D130008EB30000026A400B0248000A0200F82188
-:10D14000000000000000000D0000000000000000D2
-:10D1500000000000000000000000000000000000CF
-:10D1600000000000000000000000000000000000BF
-:10D1700000000000000000000000000000000000AF
-:10D18000000000000000000000000000000000009F
-:10D19000000000000000000000000000000000008F
-:10D1A000000000000000000000000000000000007F
-:10D1B000000000000000000000000000000000006F
-:10D1C000000000000000000000000000000000005F
-:10D1D000000000000000000000000000000000004F
-:10D1E000000000000000000000000000000000003F
-:10D1F000000000000000000000000000000000002F
-:10D20000000000000000000000000000080014D62C
-:10D2100000000000080014D83C0A0001080014D8DF
-:10D220003C0A0002080014D800000000080024A6F0
-:10D2300000000000080014D83C0A0003080014D8BD
-:10D240003C0A000408002F8C00000000080014D8DD
-:10D250003C0A000508003CE80000000008003C66AD
-:10D2600000000000080014D83C0A0006080014D88A
-:10D270003C0A0007080014D800000000080014D879
-:10D2800000000000080014D80000000008002A7503
-:10D2900000000000080014D83C0A000B080014D855
-:10D2A0003C0A000C080014D83C0A000D0800237A40
-:10D2B000000000000800233900000000080014D816
-:10D2C0003C0A000E08001B3C00000000080024A4DB
-:10D2D00000000000080014D83C0A000F080040A716
-:10D2E000000000000800409100000000080014D871
-:10D2F0003C0A0010080014EE00000000080014D8DA
-:10D300003C0A0011080014D83C0A0012080014D886
-:10D310003C0A0013000000000000000000000000B4
-:10D3200000000000000000000000000000000000FD
-:10D3300000000000000000000000000000000000ED
-:10D3400000000000000000000000000000000000DD
-:10D3500000000000000000000000000000000000CD
-:10D3600000000000000000000000000000000000BD
-:10D3700000000000000000000000000000000000AD
-:10D38000000000000000000000000000000000009D
-:10D39000000000000000000000000000000000008D
-:10D3A000000000000000000000000000000000007D
-:10D3B000000000000000000000000000000000006D
-:10D3C000000000000000000000000000000000005D
-:10D3D000000000000000000000000000000000004D
-:10D3E000000000000000000000000000000000003D
-:10D3F000000000000000000000000000000000002D
-:10D400000000000000000000000000003C030001DC
-:10D4100034633800240500802404001F2406FFFF25
-:10D4200024020001AF80021CAF820200AF82022002
-:10D4300003631021AF8200C003631021AF8200C4D8
-:10D4400003631021AF8200C827623800AF8200D08A
-:10D4500027623800AF8200D427623800AF8200D83C
-:10D4600027621800AF8200E027621800AF8200E454
-:10D4700027621800AF8200E827621000AF8200F038
-:10D4800027621000AF8200F427621000AF8200F81C
-:10D49000ACA000002484FFFF1486FFFD24A5000437
-:10D4A0008F8300403C02F000006218243C025000D0
-:10D4B0001062000C0043102B144000063C02600078
-:10D4C0003C024000106200082402080008004539B0
-:10D4D0000000000010620004240208000800453922
-:10D4E00000000000240207003C010001AC225CDCCB
-:10D4F00003E000080000000027BDFFD8AFBF0024F4
-:10D50000AFB000208F8300548F8200543C01000193
-:10D51000AC205CC408004545246300648F8200543D
-:10D52000006210232C4200651440FFFC0000000044
-:10D530000C004D71000000002404000100002821AF
-:10D5400027A60018340280000C00498EA7A20018FC
-:10D550008F8300548F820054080045562463006472
-:10D560008F820054006210232C4200651440FFFC9F
-:10D5700024040001240500010C00494C27A60018D2
-:10D580008F8300548F820054080045622463006436
-:10D590008F820054006210232C4200651440FFFC6F
-:10D5A00024040001240500010C00494C27A60018A2
-:10D5B0008F8300548F8200540800456E24630064FA
-:10D5C0008F820054006210232C4200651440FFFC3F
-:10D5D000240400013C06000124C65DA00C00494C57
-:10D5E000240500028F8300548F8200540800457B7D
-:10D5F000246300648F820054006210232C42006573
-:10D600001440FFFC24040001240500033C10000129
-:10D6100026105DA20C00494C0200302197A600188C
-:10D620003C07000194E75DA03C04000124845AB04B
-:10D63000AFA00014960200003C05000D34A50100C7
-:10D640000C002403AFA2001097A200181040004C59
-:10D6500024036040960200003042FFF01443000AA9
-:10D66000240200203C03000194635DA05462000981
-:10D6700024027830240200033C010001AC225CC487
-:10D68000080045AC240200053C03000194635DA042
-:10D69000240278301462000F240300103C020001C1
-:10D6A00094425DA23042FFF01443000A24020003BA
-:10D6B0003C010001AC225CC4240200063C010001D4
-:10D6C000AC225DB03C010001AC225DBC080045E627
-:10D6D0003C09FFF03C0200018C425CC43C030001A9
-:10D6E00094635DA0344200013C010001AC225CC4A3
-:10D6F000240200151462000F000000003C0200012B
-:10D7000094425DA23042FFF03843F4202C630001C4
-:10D710003842F4302C4200010062182510600005E8
-:10D72000240200033C010001AC225DBC080045E678
-:10D730003C09FFF03C03000194635DA024027810D3
-:10D740001462000B240200023C02000194425DA21C
-:10D750003042FFF0144000062402000224020004BC
-:10D760003C010001AC225DBC080045E63C09FFF02D
-:10D770003C010001AC225DBC080045E63C09FFF01D
-:10D780003C0200018C425CC4240300013C01000106
-:10D79000AC235DBC344200043C010001AC225CC4FB
-:10D7A0003C09FFF03529BDC03C0600018CC65CC4B5
-:10D7B0003C04000124845AB0240200013C01000111
-:10D7C000AC225CCC8F8200543C0700018CE75DBC2E
-:10D7D0003C03000194635DA03C08000195085DA234
-:10D7E0003C05000D34A501003C010001AC205CC8E3
-:10D7F000004910213C010001AC225DACAFA3001038
-:10D800000C002403AFA800148FBF00248FB00020A9
-:10D8100003E0000827BD002827BDFFE83C05000104
-:10D820008CA55CC8240600042402000114A2001484
-:10D83000AFBF00103C0200018C427E3C30428000B1
-:10D84000104000053C04000F3C0300018C635DBCEC
-:10D8500008004617348442403C0400043C030001A5
-:10D860008C635DBC348493E02402000514620016CE
-:10D87000000000003C04003D0800462F34840900ED
-:10D880003C0200018C427E3830428000104000058E
-:10D890003C04001E3C0300018C635DBC0800462A6A
-:10D8A000348484803C04000F3C0300018C635DBC25
-:10D8B000348442402402000514620003000000008A
-:10D8C0003C04007A348412003C0200018C425DACBE
-:10D8D0008F83005400441021004310230044102B78
-:10D8E00014400037000000003C0200018C425CD074
-:10D8F00014400033000000003C01000110C000256E
-:10D90000AC205CE03C0900018D295CC424070001C7
-:10D910003C0440003C08000125087E3C250AFFFC31
-:10D920000005284214A0000224C6FFFF24050008B9
-:10D9300000A91024104000100000000014A70008E7
-:10D94000000000008D020000004410241040000A76
-:10D95000000000003C0100010800465BAC255CE0D3
-:10D960008D4200000044102410400003000000001D
-:10D970003C010001AC275CE03C0200018C425CE011
-:10D980000006182B2C420001004310245440FFE5F0
-:10D99000000528428F8200543C0300018C635CE048
-:10D9A0003C010001AC225DAC1060002A24020001A1
-:10D9B0003C010001AC255CC83C010001AC225CCC00
-:10D9C0003C0200018C425CE010400022000000009C
-:10D9D0003C0200018C425CCC1040000A2402000191
-:10D9E0003C010001AC205CCC3C0100010037082167
-:10D9F000AC2283AC3C010001AC205D4C3C01000139
-:10DA0000AC225D043C030001007718218C6383ACD9
-:10DA10002402000810620005240200010C00469553
-:10DA20000000000008004692000000003C030001D6
-:10DA30008C635CC8106200072402000E3C030001E6
-:10DA40008C637DD010620003000000000C004E5477
-:10DA50008F8402208FBF001003E0000827BD00184C
-:10DA600027BDFFE03C02FDFFAFBF00188EE30000C2
-:10DA70003C0500018CA55CC83C0400018C845CF072
-:10DA80003442FFFF0062182414A40008AEE3000033
-:10DA90003C030001007718218C6383AC3C02000139
-:10DAA0008C425CF410620008000000003C0200019F
-:10DAB000005710218C4283AC3C010001AC255CF086
-:10DAC0003C010001AC225CF43C0300018C635CC8A7
-:10DAD00024020002106201692C620003104000055C
-:10DAE0002402000110620008000000000800481C29
-:10DAF0000000000024020004106200B124020001B2
-:10DB00000800481D000000003C02000100571021E1
-:10DB10008C4283AC2443FFFF2C6200081040015A62
-:10DB2000000310803C010001002208218C225AC809
-:10DB300000400008000000003C0300018C635DBC55
-:10DB40002402000514620014000000003C020001E1
-:10DB50008C425CD41040000A240200030C004822CE
-:10DB600000000000240200023C01000100370821EF
-:10DB7000AC2283AC3C010001080046E0AC205CD440
-:10DB80003C01000100370821AC2283AC3C010001BC
-:10DB90000800481FAC205C600C0048220000000018
-:10DBA0003C0200018C425CD43C010001AC205C6072
-:10DBB000104000DD240200023C0100010037082172
-:10DBC000AC2283AC3C0100010800481FAC205CD4AF
-:10DBD0003C0300018C635DBC240200051462000359
-:10DBE000240200013C010001AC225D000C0049CF81
-:10DBF000000000003C0300018C635D000800478EBC
-:10DC0000240200113C0500018CA55CC83C06000103
-:10DC10008CC67E3C0C005108000020212402000527
-:10DC20003C010001AC205CD43C010001003708211C
-:10DC30000800481FAC2283AC3C04000124845ABC79
-:10DC40003C05000F34A50100000030210000382100
-:10DC5000AFA000100C002403AFA000140800481F60
-:10DC6000000000008F8202203C03F70000431025D3
-:10DC7000080047B7AF8202208F8202203C030004D5
-:10DC800000431024144000A9240200078F8300548D
-:10DC90003C0200018C425DA42463D8F000431023B1
-:10DCA0002C422710144000F8240200010800481DEF
-:10DCB000000000003C0500018CA55CC80C0052A2CD
-:10DCC000000020210C005386000020213C030001AD
-:10DCD0008C637E34046100EA240200013C020008E7
-:10DCE0000062102410400006000000008F82021421
-:10DCF0003C03FFFF00431024080047413442251F26
-:10DD00008F8202143C03FFFF004310243442241F7F
-:10DD1000AF8202148EE200003C0302000043102593
-:10DD2000AEE200008F8202202403FFFB0043102498
-:10DD3000AF8202208F82022034420002AF82022092
-:10DD4000240200083C01000100370821AC2283AC0A
-:10DD50008F8202203C03000400431024144000057D
-:10DD6000000000008F8202203C03F70000431025D2
-:10DD7000AF8202203C0300018C635DBC24020005DD
-:10DD80001462000A000000003C02000194425DA2FF
-:10DD900024429FBC2C4200041040000424040018BC
-:10DDA000240500020C004D93240600200C0043DDE6
-:10DDB000000000003C0100010800481FAC205D503D
-:10DDC0003C020001005710218C4283AC2443FFFF2A
-:10DDD0002C620008104000AC000310803C010001E0
-:10DDE000002208218C225AE80040000800000000B0
-:10DDF0000C00429B000000003C010001AC205CCC08
-:10DE0000AF8002043C0100010C004822AC207E20BF
-:10DE1000240200013C010001AC225CE42402000267
-:10DE20003C010001003708210800481FAC2283ACE8
-:10DE30000C00489F000000003C0300018C635CE480
-:10DE40002402000914620090240200033C01000136
-:10DE5000003708210800481FAC2283AC3C020001B7
-:10DE60008C427E3830424000104000050000000027
-:10DE70008F8200443C03FFFF0800479F34637FFF0D
-:10DE80008F8200442403FF7F00431024AF820044AC
-:10DE90008F830054080047B9240200048F83005484
-:10DEA0003C0200018C425DA42463D8F0004310239F
-:10DEB0002C42271014400074240200053C0100018C
-:10DEC000003708210800481FAC2283AC8F82022053
-:10DED0003C03F70000431025AF820220AF8002040C
-:10DEE0003C010001AC207E208F83005424020006F8
-:10DEF0003C01000100370821AC2283AC3C01000149
-:10DF00000800481FAC235DA48F8300543C0200012D
-:10DF10008C425DA42463FFF6004310232C42000AC8
-:10DF20001440005900000000240200073C010001D9
-:10DF3000003708210800481FAC2283AC8F820220E2
-:10DF40003C04F70000441025AF8202208F8202209B
-:10DF50003C03030000431024144000050000182176
-:10DF60008F8202202403000100441025AF8202208A
-:10DF700010600043240200018F8202143C03FFFF63
-:10DF80003C0400018C845D98004310243442251F1A
-:10DF9000AF820214240200083C010001003708216E
-:10DFA0001080000BAC2283AC3C0200018C425D74FB
-:10DFB00014400007240200013C010001AC227DD086
-:10DFC0000C004E548F8402200800480C0000000012
-:10DFD0008F8202203C0300080043102414400017E5
-:10DFE0002402000E3C010001AC227DD08EE2000034
-:10DFF000000020213C030200004310250C00538642
-:10E00000AEE200008F8202202403FFFB00431024B5
-:10E01000AF8202208F820220344200020C0043DDD6
-:10E02000AF8202203C0500018CA55CC80C0052A206
-:10E03000000020210800481F000000003C020001F1
-:10E040008C425D7410400010000000003C02000192
-:10E050008C425D702442FFFF3C010001AC225D70E8
-:10E0600014400009240200023C010001AC205D7450
-:10E070003C0100010800481FAC225D702402000131
-:10E080003C010001AC225CCC8FBF001803E000080B
-:10E0900027BD00208F8202008F8202208F82022003
-:10E0A00034420004AF8202208F8202003C0600014D
-:10E0B0008CC65CC834420004AF8202002402000215
-:10E0C00010C2003A2CC200031040000524020001D7
-:10E0D00010C20008000000000800486800000000AE
-:10E0E0002402000410C20013240200010800486842
-:10E0F000000000003C0300018C635CB83C0200019E
-:10E100008C425CC03C0400018C845CDC3C0500015A
-:10E110008CA55CBCAF860200AF860220346300226F
-:10E1200000441025004510253442000208004867CD
-:10E13000AF8302003C0300018C635D98AF82020054
-:10E1400010600009AF8202203C0200018C425D7425
-:10E15000144000053C033F003C0200018C425CB0CF
-:10E160000800485B346300E03C0200018C425CB074
-:10E170003C033F00346300E200431025AF820200FD
-:10E180003C0300018C635CB43C04F7003C020001DA
-:10E190008C425CC03C0500018CA55CDC0064182549
-:10E1A0000043102500451025AF82022003E000083F
-:10E1B000000000008F8202203C0300018C635CC8D9
-:10E1C00034420004AF820220240200011062000FDA
-:10E1D000000000008F8300548F82005424630002EB
-:10E1E000006210232C4200031040001100000000C8
-:10E1F0008F820054006210232C4200031040000C58
-:10E200000000000008004879000000008F830054DF
-:10E210008F82005408004885246300078F820054D1
-:10E22000006210232C4200081440FFFC0000000094
-:10E230008F8400E0308200071040000D00000000D5
-:10E240008F8200548F8300E014830009244500323C
-:10E250008F82005400A210232C420033104000048F
-:10E26000000000008F8200E01082FFF90000000033
-:10E270008F8202202403FFFD00431024AF8202207E
-:10E2800003E00008000000003C0300018C635CE434
-:10E290003C0200018C425CE8506200042463FFFFF2
-:10E2A0003C010001AC235CE82463FFFF2C62000901
-:10E2B0001040009D000310803C0100010022082155
-:10E2C0008C225B0800400008000000008F820044A0
-:10E2D00034428080AF8200448F8300540800493864
-:10E2E000240200028F8300543C0200018C425DA88E
-:10E2F0002463D8F0004310232C4227101440008AD6
-:10E300002402000308004945000000008F820044F9
-:10E310003C03FFFF34637FFF00431024AF820044BF
-:10E320008F83005408004938240200048F8300546E
-:10E330003C0200018C425DA82463FFF600431023D9
-:10E340002C42000A144000782402000508004945C8
-:10E35000000000008F8202203C03F70000431025DC
-:10E36000AF8202208F8202202403FFFB004310248F
-:10E37000AF8202208F82022034420002AF8202204C
-:10E380003C023F00344200E0AF8202008F82020074
-:10E390002403FFFD00431024AF8202002404000187
-:10E3A0003405FFFFAF8402048F8300548F82005432
-:10E3B000080048EC246300018F820054006210239F
-:10E3C0002C4200021440FFFC000000008F82022457
-:10E3D0000004204000A4102B1040FFF200000000B9
-:10E3E0008F8202203C03F70000431025AF820220F9
-:10E3F0008F8202143C03FFFF004310243442251F88
-:10E40000AF8202148F8202202403FFFB00431024FA
-:10E41000AF8202208F8202203C04F700348400087F
-:10E4200034420002AF8202208F8202203C033F0070
-:10E43000346300E200441025AF820220AF83020063
-:10E440008F8400F0276217F81482000224850008E8
-:10E45000276510008F8200F410A200073C038000A3
-:10E46000346300403C02000124425C70AC82000036
-:10E47000AC830004AF8500F08F8300540800493856
-:10E48000240200068F8300543C0200018C425DA8E8
-:10E490002463FFF6004310232C42000A144000229C
-:10E4A0002402000708004945000000008F8200E0B8
-:10E4B000AF8200E48F8200E0AF8200E88F8202200A
-:10E4C00034420004AF8202208F8202202403FFF72F
-:10E4D00000431024AF8202208F82004434428080A7
-:10E4E000AF8200448F830054240200083C010001E5
-:10E4F000AC225CE43C01000108004947AC235DA864
-:10E500008F8300543C0200018C425DA82463D8F044
-:10E51000004310232C42271014400003240200095A
-:10E520003C010001AC225CE403E0000800000000B4
-:10E5300000000000000000000000000027BDFFD820
-:10E54000AFB2001800809021AFB3001C00A098214A
-:10E55000AFB1001400C08821AFB0001000008021CE
-:10E56000AFBF0020A62000000C004D4B240400018A
-:10E57000261000012E0200201440FFFB00000000C6
-:10E580000C004D4B000020210C004D4B24040001D9
-:10E590000C004D4B240400010C004D4B00002021C9
-:10E5A000241000100250102410400002000020210E
-:10E5B000240400010C004D4B001080421600FFFAAD
-:10E5C0000250102424100010027010241040000289
-:10E5D00000002021240400010C004D4B001080425B
-:10E5E0001600FFFA027010240C004D7134108000E8
-:10E5F0000C004D71000000000C004D2B00000000CD
-:10E600005040000500108042962200000050102566
-:10E61000A6220000001080421600FFF70000000054
-:10E620000C004D71000000008FBF00208FB3001C54
-:10E630008FB200188FB100148FB0001003E00008F3
-:10E6400027BD002827BDFFD8AFB100140080882166
-:10E65000AFB2001800A09021AFB3001C00C09821F9
-:10E66000AFB0001000008021AFBF00200C004D4B68
-:10E6700024040001261000012E0200201440FFFB9C
-:10E68000000000000C004D4B000020210C004D4B01
-:10E69000240400010C004D4B000020210C004D4BC8
-:10E6A0002404000124100010023010241040000245
-:10E6B00000002021240400010C004D4B001080427A
-:10E6C0001600FFFA0230102424100010025010240B
-:10E6D0001040000200002021240400010C004D4BDA
-:10E6E000001080421600FFFA025010240C004D4B1F
-:10E6F000240400010C004D4B000020213410800048
-:10E7000096620000005010241040000200002021FA
-:10E71000240400010C004D4B001080421600FFF84D
-:10E72000000000000C004D71000000008FBF0020B1
-:10E730008FB3001C8FB200188FB100148FB000107F
-:10E7400003E0000827BD00283C0300018C635D0046
-:10E750003C0200018C425D4827BDFFD8AFBF0020BE
-:10E76000AFB1001C10620003AFB000183C01000103
-:10E77000AC235D482463FFFF2C6200131040034963
-:10E78000000310803C010001002208218C225B3034
-:10E7900000400008000000000C004D7100008021C6
-:10E7A00034028000A7A2001027B100100C004D4BCE
-:10E7B00024040001261000012E0200201440FFFB5B
-:10E7C000000000000C004D4B000020210C004D4BC0
-:10E7D000240400010C004D4B000020210C004D4B87
-:10E7E0002404000124100010320200011040000235
-:10E7F00000002021240400010C004D4B0010804239
-:10E800001600FFFA32020001241000100C004D4BDC
-:10E8100000002021001080421600FFFC00000000D4
-:10E820000C004D4B240400010C004D4B0000202136
-:10E830003410800096220000005010241040000286
-:10E8400000002021240400010C004D4B00108042E8
-:10E850001600FFF8000000000C004D7100000000E1
-:10E8600008004D242402000227B10010A7A00010C8
-:10E87000000080210C004D4B2404000126100001F3
-:10E880002E0200201440FFFB000000000C004D4B46
-:10E89000000020210C004D4B240400010C004D4BC6
-:10E8A000240400010C004D4B000020212410001016
-:10E8B0003202000110400002000020212404000167
-:10E8C0000C004D4B001080421600FFFA320200018E
-:10E8D000241000100C004D4B00002021001080423D
-:10E8E0001600FFFC000000000C004D713410800089
-:10E8F0000C004D71000000000C004D2B00000000CA
-:10E900005040000500108042962200000050102563
-:10E91000A6220000001080421600FFF70000000051
-:10E920000C004D710000000097A2001030428000E2
-:10E93000144002DC2402000308004D240000000003
-:10E9400024021200A7A2001027B1001000008021AD
-:10E950000C004D4B24040001261000012E02002063
-:10E960001440FFFB000000000C004D4B0000202174
-:10E970000C004D4B240400010C004D4B00002021E5
-:10E980000C004D4B24040001241000103202000141
-:10E990001040000200002021240400010C004D4B17
-:10E9A000001080421600FFFA32020001241000100D
-:10E9B0000C004D4B00002021001080421600FFFC8F
-:10E9C000000000000C004D4B240400010C004D4BD6
-:10E9D00000002021341080009622000000501024F6
-:10E9E0001040000200002021240400010C004D4BC7
-:10E9F000001080421600FFF8000000000C004D716E
-:10EA0000000000008F83005408004D16240200040B
-:10EA10008F8300543C0200018C425DB82463FF9C4C
-:10EA2000004310232C4200641440029E2402000282
-:10EA30003C0300018C635DBC106202972C620003F2
-:10EA40001440029624020011240200031062000503
-:10EA500024020004106202912402000F08004D24D9
-:10EA60002402001108004D24240200052402001491
-:10EA7000A7A2001027B10010000080210C004D4B10
-:10EA800024040001261000012E0200201440FFFB88
-:10EA9000000000000C004D4B000020210C004D4BED
-:10EAA000240400010C004D4B000020210C004D4BB4
-:10EAB0002404000124100010320200011040000262
-:10EAC00000002021240400010C004D4B0010804266
-:10EAD0001600FFFA32020001241000103202001268
-:10EAE0001040000200002021240400010C004D4BC6
-:10EAF000001080421600FFFA320200120C004D4B4B
-:10EB0000240400010C004D4B000020213410800033
-:10EB10009622000000501024104000020000202126
-:10EB2000240400010C004D4B001080421600FFF839
-:10EB3000000000000C004D71000000008F830054A5
-:10EB400008004D16240200068F8300543C02000189
-:10EB50008C425DB82463FF9C004310232C42006468
-:10EB6000144002502402000708004D240000000059
-:10EB700024020006A7A2001027B100100000802187
-:10EB80000C004D4B24040001261000012E02002031
-:10EB90001440FFFB000000000C004D4B0000202142
-:10EBA0000C004D4B240400010C004D4B00002021B3
-:10EBB0000C004D4B2404000124100010320200010F
-:10EBC0001040000200002021240400010C004D4BE5
-:10EBD000001080421600FFFA3202000124100010DB
-:10EBE0003202001310400002000020212404000122
-:10EBF0000C004D4B001080421600FFFA3202001349
-:10EC00000C004D4B240400010C004D4B0000202152
-:10EC100034108000962200000050102410400002A2
-:10EC200000002021240400010C004D4B0010804204
-:10EC30001600FFF8000000000C004D7100000000FD
-:10EC40008F83005408004D16240200088F8300545F
-:10EC50003C0200018C425DB82463FF9C00431023FA
-:10EC60002C4200641440020F2402000908004D24C5
-:10EC70000000000027B10010A7A0001000008021B4
-:10EC80000C004D4B24040001261000012E02002030
-:10EC90001440FFFB000000000C004D4B0000202141
-:10ECA0000C004D4B240400010C004D4B24040001CA
-:10ECB0000C004D4B000020212410001032020001F6
-:10ECC0001040000200002021240400010C004D4BE4
-:10ECD000001080421600FFFA3202000124100010DA
-:10ECE000320200181040000200002021240400011C
-:10ECF0000C004D4B001080421600FFFA3202001843
-:10ED00000C004D71341080000C004D7100000000AB
-:10ED10000C004D2B00000000504000050010804208
-:10ED20009622000000501025A6220000001080420C
-:10ED30001600FFF7000000000C004D71000080215C
-:10ED400097A2001027B1001034420001A7A20010C2
-:10ED50000C004D4B24040001261000012E0200205F
-:10ED60001440FFFB000000000C004D4B0000202170
-:10ED70000C004D4B240400010C004D4B00002021E1
-:10ED80000C004D4B2404000124100010320200013D
-:10ED90001040000200002021240400010C004D4B13
-:10EDA000001080421600FFFA320200012410001009
-:10EDB000320200181040000200002021240400014B
-:10EDC0000C004D4B001080421600FFFA3202001872
-:10EDD0000C004D4B240400010C004D4B0000202181
-:10EDE00034108000962200000050102410400002D1
-:10EDF00000002021240400010C004D4B0010804233
-:10EE00001600FFF8000000000C004D71000000002B
-:10EE10008F83005408004D162402000A8F8300548B
-:10EE20003C0200018C425DB82463FF9C0043102328
-:10EE30002C4200641440019B2402000B08004D2466
-:10EE40000000000027B10010A7A0001000008021E2
-:10EE50000C004D4B24040001261000012E0200205E
-:10EE60001440FFFB000000000C004D4B000020216F
-:10EE70000C004D4B240400010C004D4B24040001F8
-:10EE80000C004D4B00002021241000103202000124
-:10EE90001040000200002021240400010C004D4B12
-:10EEA000001080421600FFFA320200012410001008
-:10EEB000320200171040000200002021240400014B
-:10EEC0000C004D4B001080421600FFFA3202001772
-:10EED0000C004D71341080000C004D7100000000DA
-:10EEE0000C004D2B00000000504000050010804237
-:10EEF0009622000000501025A6220000001080423B
-:10EF00001600FFF7000000000C004D71000080218A
-:10EF100097A2001027B1001034420700A7A20010EA
-:10EF20000C004D4B24040001261000012E0200208D
-:10EF30001440FFFB000000000C004D4B000020219E
-:10EF40000C004D4B240400010C004D4B000020210F
-:10EF50000C004D4B2404000124100010320200016B
-:10EF60001040000200002021240400010C004D4B41
-:10EF7000001080421600FFFA320200012410001037
-:10EF8000320200171040000200002021240400017A
-:10EF90000C004D4B001080421600FFFA32020017A1
-:10EFA0000C004D4B240400010C004D4B00002021AF
-:10EFB00034108000962200000050102410400002FF
-:10EFC00000002021240400010C004D4B0010804261
-:10EFD0001600FFF8000000000C004D71000000005A
-:10EFE0008F83005408004D162402000C8F830054B8
-:10EFF0003C0200018C425DB82463FF9C0043102357
-:10F000002C420064144001272402001208004D2401
-:10F010000000000027B10010A7A000100000802110
-:10F020000C004D4B24040001261000012E0200208C
-:10F030001440FFFB000000000C004D4B000020219D
-:10F040000C004D4B240400010C004D4B2404000126
-:10F050000C004D4B00002021241000103202000152
-:10F060001040000200002021240400010C004D4B40
-:10F07000001080421600FFFA320200012410001036
-:10F08000320200141040000200002021240400017C
-:10F090000C004D4B001080421600FFFA32020014A3
-:10F0A0000C004D71341080000C004D710000000008
-:10F0B0000C004D2B00000000504000050010804265
-:10F0C0009622000000501025A62200000010804269
-:10F0D0001600FFF7000000000C004D7100008021B9
-:10F0E00097A2001027B1001034420010A7A2001010
-:10F0F0000C004D4B24040001261000012E020020BC
-:10F100001440FFFB000000000C004D4B00002021CC
-:10F110000C004D4B240400010C004D4B000020213D
-:10F120000C004D4B24040001241000103202000199
-:10F130001040000200002021240400010C004D4B6F
-:10F14000001080421600FFFA320200012410001065
-:10F1500032020014104000020000202124040001AB
-:10F160000C004D4B001080421600FFFA32020014D2
-:10F170000C004D4B240400010C004D4B00002021DD
-:10F18000341080009622000000501024104000022D
-:10F1900000002021240400010C004D4B001080428F
-:10F1A0001600FFF8000000000C004D710000000088
-:10F1B0008F83005408004D16240200138F830054DF
-:10F1C0003C0200018C425DB82463FF9C0043102385
-:10F1D0002C420064144000B32402000D08004D24AA
-:10F1E0000000000027B10010A7A00010000080213F
-:10F1F0000C004D4B24040001261000012E020020BB
-:10F200001440FFFB000000000C004D4B00002021CB
-:10F210000C004D4B240400010C004D4B2404000154
-:10F220000C004D4B00002021241000103202000180
-:10F230001040000200002021240400010C004D4B6E
-:10F24000001080421600FFFA320200012410001064
-:10F2500032020018104000020000202124040001A6
-:10F260000C004D4B001080421600FFFA32020018CD
-:10F270000C004D71341080000C004D710000000036
-:10F280000C004D2B00000000504000050010804293
-:10F290009622000000501025A62200000010804297
-:10F2A0001600FFF7000000000C004D7100008021E7
-:10F2B00097A2001027B100103042FFFEA7A2001055
-:10F2C0000C004D4B24040001261000012E020020EA
-:10F2D0001440FFFB000000000C004D4B00002021FB
-:10F2E0000C004D4B240400010C004D4B000020216C
-:10F2F0000C004D4B240400012410001032020001C8
-:10F300001040000200002021240400010C004D4B9D
-:10F31000001080421600FFFA320200012410001093
-:10F3200032020018104000020000202124040001D5
-:10F330000C004D4B001080421600FFFA32020018FC
-:10F340000C004D4B240400010C004D4B000020210B
-:10F35000341080009622000000501024104000025B
-:10F3600000002021240400010C004D4B00108042BD
-:10F370001600FFF8000000000C004D7100000000B6
-:10F380008F83005408004D162402000E240208400A
-:10F39000A7A2001027B10010000080210C004D4BE7
-:10F3A00024040001261000012E0200201440FFFB5F
-:10F3B000000000000C004D4B000020210C004D4BC4
-:10F3C000240400010C004D4B000020210C004D4B8B
-:10F3D0002404000124100010320200011040000239
-:10F3E00000002021240400010C004D4B001080423D
-:10F3F0001600FFFA3202000124100010320200133E
-:10F400001040000200002021240400010C004D4B9C
-:10F41000001080421600FFFA320200130C004D4B20
-:10F42000240400010C004D4B00002021341080000A
-:10F4300096220000005010241040000200002021FD
-:10F44000240400010C004D4B001080421600FFF810
-:10F45000000000000C004D71000000008F8300547C
-:10F46000240200103C010001AC225D003C010001BF
-:10F4700008004D26AC235DB88F8300543C02000188
-:10F480008C425DB82463FF9C004310232C4200642F
-:10F490001440000400000000240200113C0100019F
-:10F4A000AC225D008FBF00208FB1001C8FB0001810
-:10F4B00003E0000827BD00288F8500448F820044A8
-:10F4C0003C030001004310253C030008AF820044C8
-:10F4D0008F8400548F82005400A3282408004D37E5
-:10F4E000248400018F820054008210232C420002E9
-:10F4F0001440FFFC000000008F8200443C03FFFE2C
-:10F500003463FFFF00431024AF8200448F83005414
-:10F510008F82005408004D45246300018F820054FF
-:10F52000006210232C4200021440FFFC0000000087
-:10F5300003E0000800A010218F8300443C02FFF08C
-:10F540003442FFFF00042480006218243C020002C1
-:10F550000082202500641825AF8300448F82004478
-:10F560003C03FFFE3463FFFF00431024AF820044DE
-:10F570008F8300548F82005408004D5E2463000185
-:10F580008F820054006210232C4200021440FFFCC2
-:10F59000000000008F8200443C030001004310255E
-:10F5A000AF8200448F8300548F82005408004D6B5B
-:10F5B000246300018F820054006210232C42000259
-:10F5C0001440FFFC0000000003E000080000000001
-:10F5D0008F8200443C03FFF03463FFFF004310249C
-:10F5E000AF8200448F8200443C0300010043102599
-:10F5F000AF8200448F8300548F82005408004D7FF7
-:10F60000246300018F820054006210232C42000208
-:10F610001440FFFC000000008F8200443C03FFFE0A
-:10F620003463FFFF00431024AF8200448F830054F3
-:10F630008F82005408004D8D246300018F82005496
-:10F64000006210232C4200021440FFFC0000000066
-:10F6500003E000080000000027BDFFC8AFB300248E
-:10F6600000809821AFB5002C00A0A821AFB20020E7
-:10F6700000C0902132A2FFFFAFBF0030AFB400281E
-:10F68000AFB1001CAFB0001814400034A7B2001096
-:10F690003271FFFF27B20010000080210C004D4B9B
-:10F6A00024040001261000012E0200201440FFFB5C
-:10F6B000000000000C004D4B000020210C004D4BC1
-:10F6C000240400010C004D4B000020210C004D4B88
-:10F6D0002404000124100010320200011040000236
-:10F6E00000002021240400010C004D4B001080423A
-:10F6F0001600FFFA3202000124100010023010241C
-:10F700001040000200002021240400010C004D4B99
-:10F71000001080421600FFFA023010240C004D4BFE
-:10F72000240400010C004D4B000020213410800007
-:10F7300096420000005010241040000200002021DA
-:10F74000240400010C004D4B001080421200007593
-:10F750000000000008004DC9000000003274FFFFE7
-:10F7600027B10010A7A00010000080210C004D4B15
-:10F7700024040001261000012E0200201440FFFB8B
-:10F78000000000000C004D4B000020210C004D4BF0
-:10F79000240400010C004D4B240400010C004D4BCF
-:10F7A000000020212410001032020001104000024D
-:10F7B00000002021240400010C004D4B0010804269
-:10F7C0001600FFFA320200012410001002901024EB
-:10F7D0001040000200002021240400010C004D4BC9
-:10F7E000001080421600FFFA029010240C004D71A8
-:10F7F000341080000C004D71000000000C004D2BF7
-:10F8000000000000504000050010804296220000D9
-:10F8100000501025A6220000001080421600FFF7BD
-:10F82000000000000C004D710000000032A5FFFF39
-:10F830002402000154A200042402000297A2001036
-:10F8400008004E140052102514A200063271FFFF6A
-:10F8500097A200100012182700431024A7A200103E
-:10F860003271FFFF27B20010000080210C004D4BC9
-:10F8700024040001261000012E0200201440FFFB8A
-:10F88000000000000C004D4B000020210C004D4BEF
-:10F89000240400010C004D4B000020210C004D4BB6
-:10F8A0002404000124100010320200011040000264
-:10F8B00000002021240400010C004D4B0010804268
-:10F8C0001600FFFA3202000124100010023010244A
-:10F8D0001040000200002021240400010C004D4BC8
-:10F8E000001080421600FFFA023010240C004D4B2D
-:10F8F000240400010C004D4B000020213410800036
-:10F900009642000000501024104000020000202108
-:10F91000240400010C004D4B001080421600FFF83B
-:10F92000000000000C004D71000000008FBF00308F
-:10F930008FB5002C8FB400288FB300248FB2002025
-:10F940008FB1001C8FB0001803E0000827BD0038FD
-:10F9500000000000000000000000000027BDFFE8DC
-:10F96000AFBF00103C030001007718218C6383AC0B
-:10F97000240200081462022C008030213C020001A5
-:10F980008C425D9814400033000000008F850224F3
-:10F9900038A300202C63000138A200102C42000183
-:10F9A000006218251460000D38A300302C6300019C
-:10F9B00038A204002C4200010062182514600007E0
-:10F9C00038A304022C63000138A204042C42000175
-:10F9D0000062182510600005000000000C00429B2A
-:10F9E0000000000008004E8D2402000E0C0043DDD4
-:10F9F000000000003C0500018CA55CC80C0052A270
-:10FA0000000020213C0300018C635CC82402000438
-:10FA1000146200052403FFFB3C0200018C425CC41D
-:10FA200008004E892403FFF73C0200018C425CC4AD
-:10FA3000004310243C010001AC225CC42402000EEF
-:10FA40003C0100010C00429BAC227DD00800508795
-:10FA5000000000008F8202203C03040000431024B9
-:10FA6000104000272403FFBF8F8502243C020001C1
-:10FA70008C427DDC00A32024004310241482000C5F
-:10FA8000000000003C0200018C427DE024420001A5
-:10FA90003C010001AC227DE02C4200021440000831
-:10FAA000240200013C01000108004EADAC227E00A2
-:10FAB0003C010001AC207DE03C010001AC207E0057
-:10FAC0003C0200018C427E001040000630A2004043
-:10FAD00010400004240200013C01000108004EB85F
-:10FAE000AC227E043C010001AC207E043C010001FC
-:10FAF000AC257DDC3C01000108004EC8AC207E1026
-:10FB0000240200013C010001AC227E103C010001F6
-:10FB1000AC207E003C010001AC207DE03C010001F6
-:10FB2000AC207E043C010001AC207DDC3C030001E4
-:10FB30008C637DD03C0200018C427DD410620003B6
-:10FB40003C0202003C010001AC237DD400C2102421
-:10FB5000104000072463FFFF8F820220240300016E
-:10FB60003C010001AC235CCC080050853C03F7004D
-:10FB70002C62000E104001A8000310803C0100011F
-:10FB8000002208218C225B80004000080000000059
-:10FB90003C010001AC207E003C010001AC207DE076
-:10FBA0003C010001AC207DDC3C010001AC207E0466
-:10FBB0003C010001AC207DF83C010001AC207DF04F
-:10FBC0000C00486AAF800224240200023C010001BC
-:10FBD000AC227DD03C0200018C427E1014400056C5
-:10FBE0003C03FDFF8EE200003463FFFF004310245E
-:10FBF0000C00429BAEE20000AF8002048F82020044
-:10FC00002403FFFD00431024AF8202003C010001E9
-:10FC1000AC207E208F8300543C0200018C427DF892
-:10FC2000240400013C010001AC247E0C24420001AC
-:10FC30003C010001AC227DF82C4200043C01000193
-:10FC4000AC237DF414400006240200033C010001B3
-:10FC5000AC245CCC3C01000108005083AC207DF852
-:10FC60003C01000108005083AC227DD08F830054FA
-:10FC70003C0200018C427DF42463D8F00043102341
-:10FC80002C42271014400003240200043C01000110
-:10FC9000AC227DD03C0200018C427E101440002634
-:10FCA0003C03FDFF8EE200003463FFFF004310249D
-:10FCB00008005083AEE200003C0400018C845D9C8F
-:10FCC0003C0100010C00508AAC207DE83C020001A0
-:10FCD0008C427E1CAF8202043C0200018C427E10EA
-:10FCE000144000153C03FDFF8EE200003463FFFF6B
-:10FCF00000431024AEE200008F8202043042003044
-:10FD00001440013C240200023C0300018C637E1C71
-:10FD1000240200053C010001AC227DD03C01000121
-:10FD200008005083AC237E203C0200018C427E10F0
-:10FD3000104000103C03FDFF3C0200018C425D6C52
-:10FD4000244200013C010001AC225D6C2C42000207
-:10FD500014400131240200013C010001AC225D7419
-:10FD60003C010001AC205D6C3C01000108005083A7
-:10FD7000AC225CCC8EE200003463FFFF0043102411
-:10FD8000AEE200003C0200018C427E0010400122E5
-:10FD9000000000003C0200018C427DDC1040011E8E
-:10FDA000000000003C010001AC227E082402000398
-:10FDB0003C010001AC227DE0080050242402000632
-:10FDC0003C010001AC207DE88F82020434420040F7
-:10FDD000AF8202043C0200018C427E202403000713
-:10FDE0003C010001AC237DD0344200403C010001C5
-:10FDF000AC227E203C0200018C427E0010400005B7
-:10FE0000000000003C0200018C427DDC104000F943
-:10FE1000240200023C05000124A57DE08CA2000024
-:10FE20002C424E21104000F3240200023C0200014B
-:10FE30008C427E04104000F82404FFBF3C02000105
-:10FE40008C427DDC3C0300018C637E08004410245E
-:10FE50000064182410430004240200013C01000146
-:10FE600008005083AC227DD024020003ACA2000025
-:10FE7000240200083C010001AC227DD03C020001BC
-:10FE80008C427E0C1040000C240200013C04000156
-:10FE90000C0050978C847DDC3C0200018C427E2853
-:10FEA00014400005240200013C0200018C427E2423
-:10FEB00010400006240200013C010001AC225CCC91
-:10FEC0003C01000108005083AC207DF83C02000199
-:10FED0008C427DF03C0300018C637DDC2C420001F0
-:10FEE000000210C0306300083C010001AC227DF02C
-:10FEF0003C010001AC237DEC8F83005424020009F7
-:10FF00003C010001AC227DD03C010001080050837F
-:10FF1000AC237DF48F8300543C0200018C427DF4BD
-:10FF20002463D8F0004310232C422710144000A86B
-:10FF3000000000003C0200018C427E0010400005E1
-:10FF4000000000003C0200018C427DDC104000A952
-:10FF5000240200023C03000124637DE08C62000067
-:10FF60002C424E21104000A3240200023C0200015A
-:10FF70008C427E0C1040000E000000003C0200018C
-:10FF80008C427DDC3C010001AC207E0C30420080C4
-:10FF90001040002F2402000C8F82020430420080A7
-:10FFA0001440000C24020003080050112402000C2D
-:10FFB0003C0200018C427DDC304200801440000590
-:10FFC000240200038F820204304200801040001F90
-:10FFD00024020003AC6200002402000A3C0100017C
-:10FFE000AC227DD03C04000124847E188C82000069
-:10FFF0003C0300018C637DF000431025AF820204B6
-:020000021000EC
-:100000008C8300003C0400018C847DF02402000BF2
-:100010003C010001AC227DD0006418253C010001A8
-:10002000AC237E203C05000124A57DE08CA20000CD
-:100030002C424E211040006F240200023C020001BD
-:100040008C427E1010400005000000002402000CCD
-:100050003C01000108005083AC227DD03C0200012D
-:100060008C427E001040006C000000003C04000147
-:100070008C847DDC1080005E308200083C0300012F
-:100080008C637DEC10620064240200033C010001DB
-:10009000AC247E08ACA20000240200063C01000152
-:1000A00008005083AC227DD08F82020034420002CF
-:1000B000AF8202008F8300542402000D3C01000136
-:1000C000AC227DD03C010001AC237DF48F83005431
-:1000D0003C0200018C427DF42463D8F000431023DD
-:1000E0002C4227101440003A000000003C0200019E
-:1000F0008C427E10104000292402000E3C030001B7
-:100100008C637E243C01000114600015AC227DD07C
-:100110000C0043DD000000003C0500018CA55CC81C
-:100120000C0052A2000020213C0300018C635CC83B
-:1001300024020004146200052403FFFB3C020001BA
-:100140008C425CC4080050522403FFF73C020001BB
-:100150008C425CC4004310243C010001AC225CC40E
-:100160008EE200003C03020000431025AEE20000D6
-:100170008F8202243C010001AC227E2C8F8202205F
-:100180002403FFFB00431024AF8202208F82022051
-:100190003442000208005083AF8202203C0200017A
-:1001A0008C427E0010400005000000003C0200016F
-:1001B0008C427DDC1040000F240200023C02000152
-:1001C0008C427DE02C424E211040000A24020002A5
-:1001D0003C0200018C427E001040000F0000000035
-:1001E0003C0200018C427DDC1440000B000000004A
-:1001F000240200023C01000108005083AC227DD0A3
-:100200003C0200018C427E00104000030000000010
-:100210000C00429B000000008F8202203C03F7008C
-:1002200000431025AF8202208FBF001003E00008BA
-:1002300027BD00183C03000124637E288C62000067
-:1002400010400005344220003C010001AC227E1C1D
-:1002500008005095AC6000003C010001AC247E1CFD
-:1002600003E000080000000027BDFFE030820030FE
-:10027000AFBF00183C010001AC227E24144000678F
-:100280003C02FFFF34421F0E008210241440006124
-:1002900024020030308220001040005D3083800056
-:1002A00000031A0230820001000212003C04000127
-:1002B0008C845D9C00621825000331C23C03000160
-:1002C00024635D78308280000002120230840001D5
-:1002D0000004220000441025000239C200061080EC
-:1002E0000043102100471021904300002402000128
-:1002F00010620025000000001060000724020002C8
-:1003000010620013240200031062002C3C05000F51
-:10031000080050F9000000008F8202002403FEFF55
-:1003200000431024AF8202008F8202203C03FFFEB4
-:100330003463FFFF00431024AF8202203C01000120
-:10034000AC207E443C01000108005104AC207E4CEE
-:100350008F82020034420100AF8202008F820220AD
-:100360003C03FFFE3463FFFF00431024AF820220F2
-:10037000240201003C010001AC227E443C0100014A
-:1003800008005104AC207E4C8F8202002403FEFF43
-:1003900000431024AF8202008F8202203C03000140
-:1003A00000431025AF8202203C010001AC207E44B6
-:1003B0003C01000108005104AC237E4C8F820200F6
-:1003C00034420100AF8202008F8202203C03000110
-:1003D00000431025AF820220240201003C010001ED
-:1003E000AC227E443C01000108005104AC237E4C49
-:1003F00034A5FFFF3C04000124845BB8AFA30010C8
-:100400000C002403AFA000140800510400000000F9
-:10041000240200303C010001AC227E288FBF00186E
-:1004200003E0000827BD00200000000027BDFFC832
-:10043000AFB2002800809021AFB3002C00A098211B
-:10044000AFB0002000C080213C04000124845BD0B8
-:100450003C0500093C0200018C425CC834A59001B7
-:100460000240302102603821AFBF0030AFB100241C
-:10047000A7A0001AAFB000140C002403AFA2001014
-:1004800024020002126200832E6200031040000565
-:10049000240200011262000A000000000800529BC2
-:1004A0000000000024020004126200FA2402000886
-:1004B000126200F93C02FFEC0800529B00000000B1
-:1004C0003C0200018C425CC4304200021440000433
-:1004D000001289403C02FFFB3442FFFF02028024ED
-:1004E0003C01000100310821AC307E3C3C02400060
-:1004F000020210241040004E001023C2308400304D
-:10050000001013823042001C3C03000124635D088C
-:1005100000431021008238213C02002002021024F6
-:1005200010400006240201003C01000100310821B6
-:10053000AC227E40080051503C0200803C0100018A
-:1005400000310821AC207E403C02008002021024D1
-:1005500010400006001219403C0200013C0100015D
-:10056000002308210800515CAC227E480012114093
-:100570003C01000100220821AC207E4894E40000E8
-:100580003C0300018C635DBC240200051062001076
-:10059000A7A400183202400010400002348240003C
-:1005A000A7A200182404000194E20002240500041C
-:1005B00024E60002344200010C00498EA4E200024D
-:1005C00024040001000028210C00498E27A60018F1
-:1005D0003C0200018C425CC8241100013C01000176
-:1005E000AC315CD414530004320280000C00429BF6
-:1005F00000000000320280001040011F00000000D7
-:100600000C00429B000000003C0300018C635DBCB9
-:100610002402000510620118240200023C010001BE
-:10062000AC315CCC3C0100010800529BAC225CC8A0
-:10063000240400012405000427B0001A0C00498E90
-:100640000200302124040001000028210C00498E02
-:10065000020030213C020001005110218C427E3406
-:100660003C0400018C845CC83C03BFFF3463FFFF83
-:100670003C010001AC335CD4004310243C01000178
-:1006800000310821109300FAAC227E340800529BFE
-:10069000000000003C02200002021024104000056F
-:1006A000240200013C010001AC225D98080051AD1C
-:1006B000001289403C010001AC205D980012894085
-:1006C0003C01000100310821AC307E383C02400082
-:1006D0000202102414400016000000003C02000139
-:1006E0008C425D9810400008240400042405000199
-:1006F0000C004D9324062000240200013C0100015F
-:1007000000370821AC2283AC3C02000100511021CB
-:100710008C427E303C03BFFF3463FFFF0043102454
-:100720003C0100010031082108005299AC227E30C2
-:100730003C0200018C425D98104000283C0300A060
-:10074000020310245443000D3C0200203C0200012F
-:100750008C425D9C240301003C0100010031082112
-:10076000AC237E443C0300013C0100010031082120
-:10077000AC237E4C080051F03442040002021024E5
-:1007800010400008240301003C0200018C425D9CE3
-:100790003C01000100310821AC237E44080051F0E7
-:1007A000344208003C020080020210241040002E57
-:1007B0003C0300013C0200018C425D9C3C010001B5
-:1007C00000310821AC237E4C34420C003C01000176
-:1007D000AC225D9C08005218240400013C02002059
-:1007E0000202102410400006240201003C01000116
-:1007F00000310821AC227E44080052013C020080F6
-:100800003C01000100310821AC207E443C02008004
-:100810000202102410400007001219403C0200019F
-:100820003C01000100230821AC227E4C0800520F3D
-:1008300024040001001211403C01000100220821A3
-:10084000AC207E4C240400010000282127B0001EAB
-:100850000C00494C02003021240400010000282132
-:100860000C00494C02003021240400012405000141
-:1008700027B0001C0C00494C020030212404000168
-:10088000240500010C00494C020030210800529957
-:10089000000000003C02FFEC3442FFFF0202802413
-:1008A0003C02000802028025001211403C010001B8
-:1008B00000220821AC307E383C02200002021024C5
-:1008C00010400009000000003C0200018C425D74F1
-:1008D00014400005240200013C010001AC225D9897
-:1008E0000800523A3C0240003C010001AC205D98F7
-:1008F0003C024000020210241440001E00000000D0
-:100900003C0200018C425D983C010001AC205CE09F
-:1009100010400007240220203C010001AC225D9C15
-:10092000240200013C01000100370821AC2283AC05
-:100930003C04BFFF001219403C020001004310219B
-:100940008C427E303C0500018CA55CC83484FFFFDE
-:10095000004410243C01000100230821AC227E3019
-:100960002402000110A20044000000000800529977
-:10097000000000003C0200018C425D981040001C09
-:10098000240220003C010001AC225D9C3C0300A03D
-:100990000203102414430005001211403402A00089
-:1009A0003C01000108005294AC225D9C3C03000114
-:1009B000006218218C637E383C0200200062102403
-:1009C00010400004240220013C0100010800529460
-:1009D000AC225D9C3C020080006210241040001F8D
-:1009E0003402A0013C01000108005294AC225D9C3D
-:1009F0003C0200200202102410400007001219409F
-:100A0000240201003C01000100230821AC227E44A5
-:100A1000080052883C020080001211403C01000195
-:100A200000220821AC207E443C02008002021024F7
-:100A300010400006001219403C0200013C01000178
-:100A40000023082108005294AC227E4C0012114071
-:100A50003C01000100220821AC207E4C3C03000137
-:100A60008C635CC8240200011062000300000000D7
-:100A70000C00429B000000008FBF00308FB3002CA1
-:100A80008FB200288FB100248FB0002003E000084F
-:100A900027BD003827BDFFD8AFB2002000809021CD
-:100AA000AFB1001C0000882124020002AFBF002467
-:100AB000AFB00018A7A0001210A200D3A7A000108A
-:100AC0002CA20003104000052402000110A2000A1D
-:100AD00000128140080053800220102124020004EB
-:100AE00010A2007D2402000810A2007C0012294000
-:100AF00008005380022010213C03000100701821DF
-:100B00008C637E3C3C0240000062102414400009CB
-:100B1000240400013C027FFF3442FFFF006288246E
-:100B20003C01000100300821AC317E3408005380C4
-:100B300002201021240500010C00494C27A60010BA
-:100B400024040001240500010C00494C27A60010D4
-:100B500097A2001030420004104000343C114000C5
-:100B60003C0200018C425DBC2443FFFF2C62000666
-:100B700010400034000310803C01000100220821D5
-:100B80008C225BE00040000800000000240400010B
-:100B90002405001127B000120C00494C020030213E
-:100BA00024040001240500110C00494C02003021EE
-:100BB00097A5001230A24000104000023C04001033
-:100BC0003C0400083C0300010800530130A28000EF
-:100BD000240400012405001427B000120C00494C25
-:100BE0000200302124040001240500140C00494CAB
-:100BF0000200302197A5001230A210001040000220
-:100C00003C0400103C0400083C03000130A2080032
-:100C1000544000013C0300023C02800002221025E7
-:100C2000006418250800530E004388253C1100017C
-:100C3000023088218E317E3C3C027FFF3442FFFF30
-:100C4000022288243C0200018C425CD81040001D26
-:100C5000001211403C0200018C425D9810400002DD
-:100C60003C02200002228825001211403C010001B4
-:100C7000002208218C227E40104000033C0200200C
-:100C800008005322022288253C02FFDF3442FFFF86
-:100C900002228824001211403C0100010022082198
-:100CA0008C227E48104000033C0200800800532D37
-:100CB000022288253C02FF7F3442FFFF0222882463
-:100CC000001211403C01000100220821AC317E34A9
-:100CD0000800538002201021001229403C0300012B
-:100CE000006518218C637E383C02400000621024AD
-:100CF000144000083C027FFF3442FFFF006288245A
-:100D00003C01000100250821AC317E3008005380F1
-:100D1000022010213C0200018C425CD810400033BC
-:100D20003C11C00C3C0200018C425D743C04C00CC0
-:100D3000348420003C0300018C635D980002102B7A
-:100D40000002102300441024106000030051882585
-:100D50003C022000022288253C02000100451021AF
-:100D60008C427E44104000033C0200200800535D8A
-:100D7000022288253C02FFDF3442FFFF0222882442
-:100D8000001211403C010001002208218C227E4CFF
-:100D9000104000033C0200800800536802228825AE
-:100DA0003C02FF7F3442FFFF022288243C02000104
-:100DB0008C425D60104000023C020800022288253F
-:100DC0003C0200018C425D64104000023C020400C1
-:100DD000022288253C0200018C425D68104000061A
-:100DE0003C0201000800537B022288253C027FFF61
-:100DF0003442FFFF00628824001211403C010001D0
-:100E000000220821AC317E30022010218FBF002447
-:100E10008FB200208FB1001C8FB0001803E00008D3
-:100E200027BD002827BDFFD8AFB400200080A02137
-:100E3000AFBF0024AFB3001CAFB20018AFB10014B5
-:100E4000AFB000108F9002003C0300018C635CC8BF
-:100E50008F93022024020002106200632C620003C0
-:100E600010400005240200011062000A001419401D
-:100E70000800544800000000240200041062005AD8
-:100E800024020008106200590014914008005448E0
-:100E9000000000003C040001008320218C847E3C83
-:100EA0003C110001022388218E317E343C02400037
-:100EB000008210241040003E3C0200080222102450
-:100EC00010400020361000023C02000100431021B7
-:100ED0008C427E4010400005361000203610010084
-:100EE0003C020020080053BD022288252402FEFF98
-:100EF000020280243C02FFDF3442FFFF02228824EA
-:100F0000001411403C010001002208218C227E487F
-:100F1000104000053C020001026298253C0200805E
-:100F2000080053DC022288253C02FFFE3442FFFF0A
-:100F3000026298243C02FF7F3442FFFF080053DC2A
-:100F4000022288242402FEDF020280243C02FFFEEB
-:100F50003442FFFF026298243C02FF5F3442FFFFED
-:100F6000022288243C01000100230821AC207E409D
-:100F70003C01000100230821AC207E480C00486A97
-:100F800000000000AF900200AF9302208F82022089
-:100F90002403FFFB00431024AF8202208F82022033
-:100FA00034420002AF820220080053F300141140C3
-:100FB0008F8202002403FFFD004310240C00486AC6
-:100FC000AF8202003C02BFFF3442FFFF0C00429B95
-:100FD00002228824001411403C0100010022082153
-:100FE00008005448AC317E34001491403C040001A8
-:100FF000009220218C847E383C110001023288212D
-:101000008E317E303C0240000082102414400011DA
-:10101000000000003C0200018C425D981440000674
-:101020003C02BFFF8F820200344200020C00486A7B
-:10103000AF8202003C02BFFF3442FFFF0C00429B24
-:10104000022288243C010001003208210800544893
-:10105000AC317E303C0200018C425D9810400005AE
-:101060003C0200203C0200018C425D741040002BC9
-:101070003C0200200082102410400007361000209F
-:10108000240201003C01000100320821AC227E4410
-:1010900008005428361001003C01000100320821EC
-:1010A000AC207E442402FEFF020280243C02008029
-:1010B0000082102410400007001419403C02000177
-:1010C0003C01000100230821AC227E4C0800543969
-:1010D00002629825001411403C0100010022082101
-:1010E000AC207E4C3C02FFFE3442FFFF026298249B
-:1010F0000C00486A00000000AF900200AF9302208D
-:101100008F8202202403FFFB00431024AF820220C1
-:101110008F82022034420002AF820220001411406C
-:101120003C01000100220821AC317E308FBF002439
-:101130008FB400208FB3001C8FB200188FB1001441
-:101140008FB0001003E0000827BD00282448656127
-:101150006465723A202F70726F6A656374732F72C0
-:1011600063732F73772F67652F2E2F6E69632F663A
-:10117000772F636F6D6D6F6E2F66776D61696E2E61
-:10118000632C7620312E312E322E313120313939F7
-:10119000382F30342F32372032323A31333A34322A
-:1011A00020736875616E6720457870202400000008
-:1011B0007468655F4441574E00000000535441433A
-:1011C0004B5F312000000000426164536E64526E38
-:1011D000670000003F456E71457674003F6E6F51A9
-:1011E00064457650000000006576526E6746756C67
-:1011F0006C000000496C6C436F6E66527800000012
-:1012000053656E64436B53756D00000052656376E1
-:10121000566C616E0000000000000000244865610B
-:101220006465723A202F70726F6A656374732F72EF
-:1012300063732F73772F67652F2E2F6E69632F6669
-:10124000772F636F6D6D6F6E2F74696D65722E638E
-:101250002C7620312E312E322E3820313939382F4C
-:1012600030372F33312031373A35383A343520731F
-:101270006875616E6720457870202400542D446D98
-:101280006152643100000000542D446D61424200FF
-:10129000542D446D613200003F6E6F5164547845A7
-:1012A000000000003F6E6F5164527845000000005E
-:1012B000656E714D4576504661696C00656E714D85
-:1012C00045764661696C00006661696C456E454D06
-:1012D000000000003F456E71457674003F6E6F510F
-:1012E00064457650000000006576526E6746756C66
-:1012F0006C00000000000000000000002448656150
-:101300006465723A202F70726F6A656374732F720E
-:1013100063732F73772F67652F2E2F6E69632F6688
-:10132000772F636F6D6D6F6E2F636F6D6D616E6480
-:101330002E632C7620312E312E322E313020313951
-:1013400039382F31312F31382031373A31313A3174
-:101350003820736875616E6720457870202400001E
-:101360003F4D626F78457674000000004E4F636F0A
-:101370006D616E6400000000687374655F455252D1
-:1013800000000000412D45727242756300000000AC
-:101390004552524F522D416464000000656E714DFC
-:1013A0004576504661696C00656E714D45764661C3
-:1013B000696C00006661696C456E454D0000000077
-:1013C000442D4572724C617374000000442D4572C7
-:1013D000723200006D4373744D6445525200000038
-:1013E00070726F6D4D6445525200000046696C7416
-:1013F0004D64455252000000636D645F45525200D7
-:101400003F456E71457674003F6E6F51644576506E
-:10141000000000006576526E6746756C6C00000037
-:101420000000000000006EA000007FBC00006E38CD
-:1014300000008734000082B00000878000008780B1
-:1014400000006F540000769400007F0C000080A81C
-:10145000000080740000878000007E70000080CC57
-:1014600000006E64000081CC00000000244865612B
-:101470006465723A202F70726F6A656374732F729D
-:1014800063732F73772F67652F2E2F6E69632F6617
-:10149000772F636F6D6D6F6E2F646D612E632C7689
-:1014A00020312E312E322E3320313939382F30343D
-:1014B0002F32372032323A31333A34312073687563
-:1014C000616E67204578702024000000646D6172B1
-:1014D0006441544E00000000646D61777241544EC7
-:1014E00000000000000000000000000024486561CA
-:1014F0006465723A202F70726F6A656374732F721D
-:1015000063732F73772F67652F2E2F6E69632F6696
-:10151000772F636F6D6D6F6E2F74726163652E63CD
-:101520002C7620312E312E322E3220313939382F7F
-:1015300030342F32372032323A31333A353020735B
-:101540006875616E672045787020240024486561C5
-:101550006465723A202F70726F6A656374732F72BC
-:1015600063732F73772F67652F2E2F6E69632F6636
-:10157000772F636F6D6D6F6E2F646174612E632CB6
-:101580007620312E312E322E3220313939382F301B
-:10159000342F32372032323A31333A3430207368C4
-:1015A00075616E67204578702024000046575F56AD
-:1015B000455253494F4E3A2023312046726920410B
-:1015C000707220372031373A35353A34382050445C
-:1015D000542032303030000046575F434F4D504961
-:1015E0004C455F54494D453A2031373A35353A3408
-:1015F0003800000046575F434F4D50494C455F420D
-:10160000593A2064657672637300000046575F4361
-:101610004F4D50494C455F484F53543A20636F6DCE
-:10162000707574650000000046575F434F4D504988
-:101630004C455F444F4D41494E3A20656E672E61DF
-:101640006374656F6E2E636F6D00000046575F43D5
-:101650004F4D50494C45523A20676363207665727E
-:1016600073696F6E20322E372E32000000000000AA
-:101670000000000000000000000000002448656138
-:101680006465723A202F70726F6A656374732F728B
-:1016900063732F73772F67652F2E2F6E69632F6605
-:1016A000772F636F6D6D6F6E2F6D656D2E632C766A
-:1016B00020312E312E322E3220313939382F30342C
-:1016C0002F32372032323A31333A3434207368754E
-:1016D000616E672045787020240000002448656111
-:1016E0006465723A202F70726F6A656374732F722B
-:1016F00063732F73772F67652F2E2F6E69632F66A5
-:10170000772F636F6D6D6F6E2F73656E642E632C14
-:101710007620312E312E322E313120313939382F89
-:1017200031322F32322031373A31373A3535207362
-:101730006875616E6720457870202400736E64645C
-:10174000654E6F51200000006E6F454E515F54583A
-:1017500000000000736E6464744E6F51200000003E
-:101760003F6E6F516454784500000000756E6B72D7
-:101770006474797065000000000000000000ACCCCB
-:101780000000ACCC0000AD9C0000AAB00000AAB0E4
-:101790000000AD9C0000AD9C0000AD9C0000AD9C25
-:1017A0000000AD9C0000AD9C0000AD9C0000AD9C15
-:1017B0000000AD9C0000AD9C0000AD9C0000AD9C05
-:1017C0000000AD9C0000AD7C000000000000BCA843
-:1017D0000000BCA80000BD700000AE4C0000B05876
-:1017E0000000BD700000BD700000BD700000BD7045
-:1017F0000000BD700000BD700000BD700000BD7035
-:101800000000BD700000BD700000BD700000BD7024
-:101810000000BD700000BD540000B0402448656168
-:101820006465723A202F70726F6A656374732F72E9
-:1018300063732F73772F67652F2E2F6E69632F6663
-:10184000772F636F6D6D6F6E2F726563762E632CCD
-:101850007620312E312E322E313920313939382F40
-:1018600030372F32342032313A33303A303520732A
-:101870006875616E6720457870202400706B52781F
-:101880004552520066726D324C617267650000000D
-:1018900072784E6F527842640000000072785144B2
-:1018A0006D61444600000000727851446D6142460B
-:1018B000000000003F6E6F51645278450000000048
-:1018C000706B5278455252730000000066726D32A0
-:1018D0004C7267530000000072784E6F42645300F0
-:1018E0003F724264446D6146000000003F724A420C
-:1018F00064446D4600000000000000000000F6781F
-:101900000000F6780000F6780000F6780000F6781F
-:101910000000F6780000F6780000F6780000F6780F
-:101920000000F6780000F6780000F6780000F678FF
-:101930000000F6780000F6780000F6700000F670FF
-:101940000000F670572D444D41456E4600000000E2
-:10195000000000000000FDC00001015C0000FDDC93
-:101960000001015C0001015C0001015C0001015CFF
-:101970000001015C0001015C0000F7040001015C52
-:101980000001015C0001015C0001015C0001015CDF
-:101990000001015400010154000101542448656113
-:1019A0006465723A202F70726F6A656374732F7268
-:1019B00063732F73772F67652F2E2F6E69632F66E2
-:1019C000772F636F6D6D6F6E2F6D61632E632C7655
-:1019D00020312E312E322E313220313939382F300C
-:1019E000342F32372032323A31333A34322073686E
-:1019F00075616E6720457870202400006D61637406
-:101A00007841544E000000004E7453796E264C6BA2
-:101A10000000000072656D61737372740000000055
-:101A20006C696E6B444F574E00000000656E714D3F
-:101A30004576504661696C00656E714D457646612C
-:101A4000696C00006661696C456E454D00000000E0
-:101A50006C696E6B55500000000000002448656101
-:101A60006465723A202F70726F6A656374732F72A7
-:101A700063732F73772F67652F2E2F6E69632F6621
-:101A8000772F636F6D6D6F6E2F636B73756D2E6344
-:101A90002C7620312E312E322E3220313939382F0A
-:101AA00030342F32372032323A31333A33392073DF
-:101AB0006875616E672045787020240050726F62EF
-:101AC00065506879000000006C6E6B4153535254AE
-:101AD0000000000000011B2C00011BC400011BF8CA
-:101AE00000011C2C00011C5800011C6C00011CA8EA
-:101AF0000001207C00011DE400011E2400011E5095
-:101B000000011E9000011EC000011EFC00011F30DC
-:101B10000001207C000122C0000122D80001230026
-:101B2000000123200001234800012478000124A0A3
-:101B3000000124F40001251C000000000001278C96
-:101B40000001285C0001293400012A0400012A60F8
-:101B500000012B3C00012B6400012C4000012C688B
-:101B600000012E1000012E3800012FE0000131D8B5
-:101B70000001346C000133800001346C00013498A2
-:101B800000013008000131B00000000000013B847A
-:101B900000013BC800013C6000013CAC00013D1C61
-:101BA00000013DB400013DE800013E7000013F0826
-:101BB00000013FD8000140180001409C000140C0D6
-:101BC000000141F4646F42617365506700000000DA
-:101BD00000000000000000000000000073746D6150
-:101BE000634C4E4B000000000000000000014C3828
-:101BF00000014C3800014B8000014BC400014C38FF
-:101C000000014C380000000000000000000000004F
-:101C100000000000000000000000000000000000C4
-:101C2000000000000000000000000000416C74652E
-:101C30006F6E204163654E4943205600416C7465C8
-:101C40006F6E204163654E49432056004242424236
-:101C50000000000000000000000000000013541805
-:101C60000013E7FC0000000000000000000000007E
-:101C70000000000000000000000000000060CF0035
-:101C800000000060CF000000000000000000000025
-:101C90000000000000000000000000000000000044
-:101CA0000000000000000000000000000000000034
-:101CB0000000000000000000000000000000000024
-:101CC0000000000000000000000000000000000014
-:101CD0000000000000000000000000030000000001
-:101CE00000000001000000000000000000000000F3
-:101CF00000000001000000000000000100000000E2
-:101D000000000000000000000000000000000001D2
-:101D100000000001000000000000000000000000C2
-:101D20000000000000000000010000002100000091
-:101D30001200014000000000000000002000000030
-:101D4000120000A0000000001200006012000180DC
-:101D5000120001E000000000000000000000000090
-:101D60000000000100000000000000000000000072
-:101D70000000000000000000000000000000000261
-:101D8000000000000000000000030001000000014E
-:0C1D900000030201000000000000000041
-:00000001FF
-/* tg1 firmware v12.4.11 */
--- zfcpdump-kernel-4.4.orig/firmware/acenic/tg2.bin.ihex
+++ /dev/null
@@ -1,4844 +0,0 @@
-:100000000C040B0000004000000040000000000055
-:1000100010000003000000000000000D0000000DB3
-:100020003C1D00018FBD6D2003A0F0213C1000009D
-:10003000261040000C0010C0000000000000000D61
-:100040003C1D00018FBD6D2403A0F0213C10000079
-:10005000261040000C0017E0000000000000000D1A
-:100060000000000000000000000000000000000090
-:100070000000000000000000000000000000000080
-:100080000000000000000000000000000000000070
-:100090000000000000000000000000000000000060
-:1000A0000000000000000000000000000000000050
-:1000B0000000000000000000000000000000000040
-:1000C0000000000000000000000000000000000030
-:1000D0000000000000000000000000000000000020
-:1000E0000000000000000000000000000000000010
-:1000F0000000000000000000000000000000000000
-:1001000000000000000000000000000002000008E5
-:10011000000000000800172F3C0A00010800172FFC
-:100120003C0A00020800172F0000000008002CAC59
-:100130000000000008002C4F000000000800172FEE
-:100140003C0A00040800328A0000000008001A522D
-:10015000000000000800394D00000000080038F4DD
-:10016000000000000800172F3C0A0006080039BBF9
-:100170003C0A00070800172F3C0A00080800172F48
-:100180003C0A000908003A130000000008002EA6EF
-:10019000000000000800172F3C0A000B0800172F72
-:1001A0003C0A000C0800172F3C0A000D080028FB31
-:1001B0000000000008002890000000000800172F31
-:1001C0003C0A000E0800208C0000000008001964A2
-:1001D0000000000008001A040000000008003CA60F
-:1001E0000000000008003C94000000000800172FE9
-:1001F000000000000800191A000000000800172F76
-:10020000000000000800172F3C0A00130800172FF9
-:100210003C0A001400000000000000000000000084
-:1002200000000000000000000000000000000000CE
-:1002300000000000000000000000000000000000BE
-:1002400000000000000000000000000000000000AE
-:10025000000000000000000000000000000000009E
-:10026000000000000000000000000000000000008E
-:10027000000000000000000000000000000000007E
-:10028000000000000000000000000000000000006E
-:10029000000000000000000000000000000000005E
-:1002A000000000000000000000000000000000004E
-:1002B000000000000000000000000000000000003E
-:1002C000000000000000000000000000000000002E
-:1002D000000000000000000000000000000000001E
-:1002E000000000000000000000000000000000000E
-:1002F00000000000000000000000000000000000FE
-:1003000000000000000000000000000027BDFFE02A
-:100310003C1CC000AFBF001CAFB000188F82014072
-:1003200024030003AF8300EC344200040C002B20B4
-:10033000AF8201403C0100C00C001763AC203FFCC1
-:10034000004018213C0200103C010001AC236E9CCF
-:10035000106200110043102B144000023C020020E8
-:100360003C0200081062000C240501003C0600015C
-:100370008CC66E9C3C04000124845C74000038210F
-:10038000AFA000100C002B3BAFA000143C020020DB
-:100390003C010001AC226E9C240200083C010001DB
-:1003A000AC226EB42402001F3C010001AC226EC4DA
-:1003B000240200163C010001AC226E983C05FFFEB1
-:1003C00034A56F083C0200018C426E9C3C03000285
-:1003D000246390103C0400018C846CC400431023FF
-:1003E00014800002004580212610FA382402F00013
-:1003F000020280240C00178502002021020228231B
-:100400003C0400200082182300651823247BB000E0
-:100410003C03FFFE3463BF080363B8213C0600BF02
-:1004200034C6F0003C0700018CE76CC03C0300BF01
-:100430003463E000008520233C010001AC246EA859
-:10044000008220233C010001AC256E90000528426B
-:100450003C010001AC226E8427620FFC3C010001CC
-:10046000AC226D2027621FFC00DB3023007B1823A9
-:100470003C010001AC246E883C010001AC256EAC4F
-:100480003C010001AC226D24AF86015010E0001148
-:10049000AF8302503C1D00018FBD6CCC03A0F02146
-:1004A0000C001749000000003C0200018C426CD097
-:1004B0003C0300018C636CD42442FE0024630200E0
-:1004C0003C010001AC226CD03C0100011000000492
-:1004D000AC236CD43C1D00018FBD6D2003A0F02126
-:1004E0003C0200018C426CC41040000D26FAFA3820
-:1004F0003C0200018C426CD03C0300018C636CD444
-:100500003C1A00018F5A6CD42442FA38246305C87F
-:100510003C010001AC226CD03C010001AC236CD446
-:100520003C0200018C426CC8144000030000000033
-:100530003C010001AC206CD00C0011510000000007
-:100540008FBF001C8FB0001803E0000827BD0020FB
-:100550003C0200018C426CD03C0300018C636CD4E3
-:1005600027BDFF98AFB000483C1000018E1066B860
-:10057000AFB200503C12000026524100AFBF0060F5
-:10058000AFBE005CAFB50058AFB30054AFB1004C84
-:10059000AFA20034AFA30030AFA00010AFA0001492
-:1005A0008F8600403C04000124845C802405020006
-:1005B0003C010001AC326E800C002B3B0200382164
-:1005C0008F8300403C02F000006218243C0260006F
-:1005D0001062000BA3A0003F240E00013C040001A8
-:1005E00024845C88A3AE003FAFA00010AFA000142D
-:1005F0008F860040240503000C002B3B02003821AD
-:100600008F8202403C03000100431025AF8202406C
-:10061000AF8000488F8200481440000500000000B1
-:10062000AF8000488F8200481040000400000000A6
-:10063000AF8000481000000302E02021AF80004C92
-:1006400002E020213C0500010C002BA834A540F855
-:10065000034020210C002BA8240505C83C02000102
-:100660008C426EA83C0D00018DAD6E883C030001EC
-:100670008C636E843C0800018D086E903C0900017B
-:100680008D296EAC3C0A00018D4A6EB43C0B000112
-:100690008D6B6EC43C0C00018D8C6E983C04000187
-:1006A00024845C9424050400AF42013C8F42013C49
-:1006B0002406000124070001AF400000AF4D0138BF
-:1006C000AF430144AF480148AF49014CAF4A015024
-:1006D000AF4B0154AF4C01582442FF80AF42014060
-:1006E00024020001AFA200100C002B3BAFA00014AD
-:1006F0008F420138AFA200108F42013CAFA200141C
-:100700008F4601448F4701483C04000124845CA0CB
-:100710000C002B3B24050500AFB70010AFBA001446
-:100720008F46014C8F4701503C04000124845CAC8F
-:100730000C002B3B240506003C0200018C426E9C01
-:10074000036038213C06000224C690102448FFFFB5
-:100750000106182400E810240043102B1040000666
-:10076000240509003C04000124845CB8AFA80010F3
-:100770000C002B3BAFA000148F82000CAFA2001026
-:100780008F82003CAFA200148F8600008F87000488
-:100790003C04000124845CC40C002B3B24051000A5
-:1007A0008C0202208C0302248C0602188C07021C87
-:1007B0003C04000124845CCC24051100AFA200108D
-:1007C0000C002B3BAFA30014AF800054AF80011C82
-:1007D0008C020218304200021040000900000000A4
-:1007E0008C0202203C030002346300040043102505
-:1007F000AF42000C8C02021C1000000834420004BE
-:100800008C0202203C0300023463000600431025E2
-:10081000AF42000C8C02021C34420006AF420014AE
-:100820008C020218304200101040000A0000000044
-:100830008C02021C34420004AF4200108C020220E1
-:100840003C03000A34630004004310251000000933
-:10085000AF4200088C0202203C03000A3463000609
-:1008600000431025AF4200088C02021C34420006EF
-:10087000AF42001024020001AF8200A0AF8200B09E
-:100880008F8300548F820054AF8000D0AF8000C0AF
-:1008900010000002246300648F8200540062102361
-:1008A0002C4200651440FFFC000000008C0402088C
-:1008B0008C05020C26E20028AEE2002024020490FF
-:1008C000AEE20010AEE40008AEE5000C26E400083D
-:1008D0008C8200008C830004AF820090AF83009470
-:1008E0008C820018AF8200B49482000AAF82009C10
-:1008F0008F420014AF8200B08F8200B030420004FB
-:100900001440FFFD000000008F8200B03C03EF00A8
-:100910000043102410400021000000008F8200B42A
-:10092000AFA200108F8200908F8300943C040001DE
-:1009300024845CD4AFA300148F8600B08F87009C02
-:100940003C0500010C002B3B34A5200D3C040001AC
-:1009500024845CE0240203C0AFA20010AFA0001406
-:100960008F8601443C07000124E75CE80C002B3B28
-:100970003405DEAD8F82011C34420002AF82011CBF
-:100980008F82022034420004AF8202208F82014015
-:100990003C03000100431025AF82014096E204723F
-:1009A00096E6045296E70462AFA2001096E2048233
-:1009B0003C04000124845D14240512000C002B3B30
-:1009C000AFA2001496F0045232020001104000025F
-:1009D0000000B02124160001320200025440000140
-:1009E00036D60002320200085440000136D6000418
-:1009F000320200105440000136D6000832020020B6
-:100A00005440000136D6001032020040544000012C
-:100A100036D60020320200805440000136D6004015
-:100A200096E6048230C202005440000136D64000EF
-:100A300096E304723062020010400003306201004D
-:100A40001000000336D620005440000136D61000B6
-:100A500096F0046232C24000144000043207009B4A
-:100A600030C2009B14E20007240E000132C22000B5
-:100A70001440000D320200013062009B10E20009B8
-:100A8000240E00013C04000124845D202405130091
-:100A900002003821A3AE003FAFA300100C002B3B97
-:100AA000AFA00014320200015440000136D600808D
-:100AB000320200025440000136D601003202000822
-:100AC0005440000136D602003202001054400001AA
-:100AD00036D60400320200805440000136D60800A9
-:100AE0008C02021830420200104000023C02000852
-:100AF00002C2B0258C0202183042080010400002E9
-:100B00003C02008002C2B0258C0202183042040070
-:100B1000104000023C02010002C2B0258C02021803
-:100B200030420100104000023C02020002C2B02527
-:100B30008C02021830420080104000023C02040087
-:100B400002C2B0258C020218304220001040000280
-:100B50003C02001002C2B0258C0202183042400054
-:100B6000104000023C02002002C2B0258C02021894
-:100B700030421000104000023C02004002C2B0258A
-:100B80008EE204988EE3049CAF420160AF4301649F
-:100B90008EE204A08EE304A4AF420168AF43016C6F
-:100BA0008EE204A88EE304ACAF420170AF4301743F
-:100BB0008EE204288EE3042CAF420178AF43017C1F
-:100BC0008EE204488EE3044CAF420180AF430184BF
-:100BD0008EE204588EE3045CAF420188AF43018C7F
-:100BE0008EE204688EE3046CAF420190AF4301943F
-:100BF0008EE204788EE3047CAF420198AF43019CFF
-:100C00008EE204888EE3048CAF4201A0AF4301A4BE
-:100C10008EE204B08EE304B424040080AF4201A845
-:100C2000AF4301AC0C002BA8240500808C02025CB1
-:100C300027440224AF4201F08C0202602405020026
-:100C4000240600080C002BBFAF4201F83C043B9A7D
-:100C50003484CA0000003821240200062403000264
-:100C6000AF4201F4240203E8AF430204AF430200A1
-:100C7000AF4401FCAF42029424020001AF43029052
-:100C8000AF42029C3C0300010067182190636CD8BE
-:100C90000347102124E70001A043022C2CE2000F9F
-:100CA0001440FFF80347182124E700013C08000125
-:100CB000350840F88F8200403C04000124845D2CFC
-:100CC000240514000002170224420030A062022C06
-:100CD00003471021A040022C8C07021802C03021CB
-:100CE000240205C8AFA200100C002B3BAFA80014D3
-:100CF0003C04000124845D383C05000024A55C8090
-:100D00002406001027B100300220382127B3003418
-:100D10000C0017A3AFB300103C0300018C636CC838
-:100D20001060000A004080218FA300302405FF00DE
-:100D30008FA20034246400FF008520240083182340
-:100D400000431023AFA20034AFA400303C040001E4
-:100D500024845D443C05000024A5410024060108CC
-:100D6000022038210C0017A3AFB3001000409021DF
-:100D700032C200033C010001AC326E8010400045DD
-:100D8000022038218F8200503C03001000431024C1
-:100D900010400016000000008C0202183042004093
-:100DA0001040000F240200018F8200508C030218B3
-:100DB000240E00013C04000124845D50A3AE003FDA
-:100DC000AFA20010AFA300148F87004024051500C8
-:100DD0000C002B3B02C0302110000004000000007A
-:100DE0003C01000100370821A02240F43C0400012E
-:100DF00024845D5C3C05000124A55B403C060001A9
-:100E000024C65BAC00C530238F42001027B30030EE
-:100E10000260382127B1003434420A00AF4200108A
-:100E20000C0017A3AFB100103C04000124845D70D6
-:100E30003C05000124A5B7143C06000124C6BA9065
-:100E400000C5302302603821AF4201080C0017A30F
-:100E5000AFB100103C04000124845D8C3C0500010E
-:100E600024A5BE583C06000124C6C90000C5302395
-:100E7000026038213C010001AC226EF40C0017A383
-:100E8000AFB100103C04000124845DA410000024D4
-:100E9000240516003C04000124845DAC3C050001DF
-:100EA00024A5A10C3C06000124C6A23800C53023AD
-:100EB0000C0017A3AFB300103C04000124845DBCF8
-:100EC0003C05000124A5B2B03C06000124C6B70CC5
-:100ED00000C5302302203821AF4201080C0017A3BF
-:100EE000AFB300103C04000124845DD03C05000138
-:100EF00024A5BA983C06000124C6BE5000C5302384
-:100F0000022038213C010001AC226EF40C0017A332
-:100F1000AFB300103C04000124845DE424051650A6
-:100F200002C03021000038213C010001AC226EF8E3
-:100F3000AFA000100C002B3BAFA0001432C2002069
-:100F40001040002127A700303C04000124845DF0FC
-:100F50003C05000124A5B13C3C06000124C6B2A812
-:100F600000C5302324022000AF42001C27A2003419
-:100F70000C0017A3AFA20010000219000003198291
-:100F80003C04080000641825AE4300282403001028
-:100F9000AF43003C96E30450AF4300408F43004012
-:100FA0003C04000124845E04AFA00014AFA3001031
-:100FB0008F47001C240516603C010001AC226EF036
-:100FC0001000002532C600208EE204488EE3044C57
-:100FD000AF43001C8F42001C2442E0002C42200141
-:100FE0001440000A240E00013C04000124845E1019
-:100FF000A3AE003FAFA00010AFA000148F46001CAE
-:10100000240517000C002B3B000038213C02000097
-:1010100024425CBC00021100000211823C03080063
-:1010200000431025AE42002824020008AF42003CD5
-:1010300096E20450AF4200408F4200403C04000161
-:1010400024845E1CAFA00014AFA200108F47001CC8
-:101050002405180032C600200C002B3B00000000C5
-:101060003C050FFF3C0300018C636EF434A5FFFFC9
-:10107000024030213C0200018C426EF83C04080022
-:101080000065182400031882006418250045102408
-:101090000002108200441025ACC2008032C20180E0
-:1010A00010400056ACC300208F82005C3C030080DF
-:1010B000004310241040000D000000008F820050FB
-:1010C000AFA200108F82005C240E00013C040001DE
-:1010D00024845E28A3AE003FAFA200148F87004097
-:1010E000240519000C002B3B02C030218F820050D8
-:1010F0003C030010004310241040001600000000C4
-:101100008C020218304200401040000F24020001FF
-:101110008F8200508C030218240E00013C04000151
-:1011200024845D50A3AE003FAFA20010AFA3001413
-:101130008F870040240520000C002B3B02C030218B
-:1011400010000004000000003C01000100370821ED
-:10115000A02240F43C04000124845E343C050001DC
-:1011600024A55AC03C06000124C65B3800C53023C4
-:101170008F42000827B300300260382127B10034C5
-:1011800034420E00AF4200080C0017A3AFB10010AC
-:101190003C04000124845E4C3C05000124A5D8B425
-:1011A0003C06000124C6E3C800C530230260382194
-:1011B000AF42010C0C0017A3AFB100103C040001BA
-:1011C00024845E643C05000124A5E9AC3C060001D2
-:1011D00024C6F0F000C53023026038213C01000134
-:1011E000AC226F040C0017A3AFB100103C04000147
-:1011F00024845E7C10000027240521003C040001AB
-:1012000024845E843C05000124A59FC83C0600019F
-:1012100024C6A10400C5302327B1003002203821A4
-:1012200027B300340C0017A3AFB300103C04000137
-:1012300024845E943C05000124A5CAD43C06000128
-:1012400024C6D8AC00C5302302203821AF42010C9F
-:101250000C0017A3AFB300103C04000124845EA46B
-:101260003C05000124A5E84C3C06000124C6E9A485
-:1012700000C53023022038213C010001AC226F045C
-:101280000C0017A3AFB300103C04000124845EB827
-:101290002405215002C03021000038213C0100010A
-:1012A000AC226F10AFA000100C002B3BAFA00014BD
-:1012B0003C110FFF3C0300018C636F043631FFFFCC
-:1012C000024098213C0200018C426F103C0E080045
-:1012D0000071182400031882006E18250051102494
-:1012E00000021082004E1025AE630038AE62007816
-:1012F0008C02021830420040144000042402000115
-:101300003C01000100370821A02240F43C04000108
-:1013100024845EC43C05000124A5E3D03C06000102
-:1013200024C6E52C00C5302327BE003003C0382179
-:1013300027B500340C0017A3AFB500103C01000125
-:10134000AC226EFC00511024000210823C0E0800FA
-:10135000004E1025AE62005032C220001040000640
-:1013600003C038213C02000024425CBC022210244D
-:101370001000000F000210823C04000124845ED89B
-:101380003C05000124A5E5343C06000124C6E6E442
-:1013900000C530230C0017A3AFB500103C010001BD
-:1013A000AC226F1400511024000210823C0E080081
-:1013B000004E1025AE62004832C2400010400005C9
-:1013C00027A700303C02000024425CBC1000000E45
-:1013D000000211003C04000124845EF03C05000181
-:1013E00024A5E6EC3C06000124C6E84400C53023F1
-:1013F00027A200340C0017A3AFA200103C0100018B
-:10140000AC226F0800021100000211823C030800A8
-:1014100000431025AE4200603C04000124845F08B4
-:101420003C05000124A582303C06000124C68650FC
-:1014300000C5302327B100300220382127B3003403
-:101440000C0017A3AFB300103C0E0FFF35CEFFFF0B
-:101450003C04000124845F143C05000024A564685A
-:101460003C06000024C6658800C5302302203821D0
-:101470000240F0213C010001AC226EDC004E102441
-:10148000000210823C15080000551025AFAE004444
-:10149000AFC200B80C0017A3AFB300103C040001AA
-:1014A00024845F203C05000024A565903C060000D4
-:1014B00024C668088FAE004400C5302302203821BE
-:1014C0003C010001AC226ED0004E102400021082BC
-:1014D00000551025AFC200E80C0017A3AFB30010F1
-:1014E0003C04000124845F383C05000024A56810FA
-:1014F0003C06000024C669408FAE004400C530237E
-:10150000022038213C010001AC226EC8004E10249C
-:101510000002108200551025AFC200C00C0017A3B6
-:10152000AFB300103C04000124845F503C0500016F
-:1015300024A5FAD03C06000124C6FBA88FAE0044C7
-:1015400000C53023022038213C010001AC226ED4BA
-:10155000004E10240002108200551025AFC200C8B2
-:101560000C0017A3AFB300103C04000124845F5C9F
-:101570003C05000124A5C93C3C06000124C6CA2044
-:1015800000C5302302203821AF4201100C0017A300
-:10159000AFB300103C04000124845F6C3C050001E3
-:1015A00024A5C9103C06000124C6C93400C5302357
-:1015B00002203821AF4201240C0017A3AFB3001062
-:1015C0003C04000124845F7C3C05000124A55A8072
-:1015D0003C06000124C65AAC00C530230220382145
-:1015E000AF420120AF4201140C0017A3AFB30010AB
-:1015F0003C04000124845F883C05000124A5F29886
-:101600003C06000124C6F6B400C530230220382170
-:10161000AF4201180C0017A3AFB300108FAE004407
-:101620003C010001AC226F18004E10240002108211
-:10163000005510250C003FC3AFC200D00C003C4049
-:10164000000000000C0027A800000000AC000228E9
-:10165000AC00022C96E204502442FFFFAF42003857
-:1016600096E20460AF42008032C2400014400003A2
-:101670000000000096E20480AF42008496E70490E8
-:1016800050E000012407080024E2FFFFAF42008879
-:10169000AF42007C2402080010E2000F32C240007A
-:1016A000104000032402040010E2000B00000000C0
-:1016B000240E00013C04000124845F98A3AE003F87
-:1016C00096E604902405217002C03821AFA00010D6
-:1016D0000C002B3BAFA000148F4301388F4401381E
-:1016E00024020001A34205C2AF430094AF44009816
-:1016F000AFA00010AFA000148F4600808F47008479
-:101700003C04000124845FA40C002B3B2405220030
-:101710000C0024A43C1108003C1433D83694CB5858
-:101720003C020800344200803C04000124845FB085
-:101730003C05000024A55D003C06000024C65D1C9D
-:1017400000C5302327A70030AF8200602402FFFFCE
-:10175000AF82006427A200340C0017A3AFA20010D0
-:101760003C010001AC226EB800021100000211829F
-:10177000005110250C0018FCAE4200008F82024080
-:101780003C03000100431025AF8202403C020000F0
-:1017900024424034AF820244AF8002408F82006016
-:1017A00000511024144000053C0308008F820060A3
-:1017B000004310241040FFFD000000000C003C4DD1
-:1017C000000088213C020100AFA200208F530018C6
-:1017D000240200FF56620001267100018C020228DB
-:1017E0001622000E001330C08F42033C2442000139
-:1017F000AF42033C8F42033C8C0202283C040001B0
-:1018000024845C243C050009AFA00014AFA20010A2
-:101810008FA600201000003F34A5010000D7102142
-:101820008FA300208FA40024AC4304C0AC4404C4A4
-:1018300000C018218F4401788F45017C00001021E1
-:1018400024070004AFA70010AFB100148F48000CAC
-:1018500024C604C002E63021AFA800188F48010C4E
-:101860002407000800A3282100A3482B0082202180
-:101870000100F809008920211440000B240700080A
-:101880008F820120AFA200108F8201243C0400014E
-:1018900024845C2C3C050009AFA200148FA6002014
-:1018A0001000001C34A502008F4401608F450164C4
-:1018B0008F43000CAF5100188F86012024020010C6
-:1018C000AFA20010AFB10014AFA300188F42010CFB
-:1018D0000040F80924C6001C14400010000000005D
-:1018E0008F42034024420001AF4203408F42034035
-:1018F0008F820120AFA200108F8201243C040001DE
-:1019000024845C343C050009AFA200148FA600209B
-:1019100034A503000C002B3B026038218F4202E407
-:1019200024420001AF4202E48F4202E493A2003F4E
-:10193000104000693C02070034423000AFA200288A
-:101940008F530018240200FF126200020000882159
-:10195000267100018C0202281622000E001330C0EE
-:101960008F42033C24420001AF42033C8F42033CC0
-:101970008C0202283C04000124845C243C050009FC
-:10198000AFA00014AFA200108FA600281000003FE7
-:1019900034A5010000D710218FA300288FA4002CAC
-:1019A000AC4304C0AC4404C400C018218F44017887
-:1019B0008F45017C0000102124070004AFA7001010
-:1019C000AFB100148F48000C24C604C002E63021D9
-:1019D000AFA800188F48010C2407000800A3282195
-:1019E00000A3482B008220210100F8090089202152
-:1019F0001440000B240700088F820120AFA20010C2
-:101A00008F8201243C04000124845C2C3C050009E5
-:101A1000AFA200148FA600281000001C34A50200FD
-:101A20008F4401608F4501648F43000CAF51001853
-:101A30008F86012024020010AFA20010AFB1001465
-:101A4000AFA300188F42010C0040F80924C6001C07
-:101A500014400010000000008F42034024420001A7
-:101A6000AF4203408F4203408F820120AFA200109B
-:101A70008F8201243C04000124845C343C0500096D
-:101A8000AFA200148FA6002834A503000C002B3B46
-:101A9000026038218F4202F024420001AF4202F07E
-:101AA0008F4202F03C04000124845FC0AFA000100C
-:101AB000AFA000148FA60028240523000C002B3BA8
-:101AC0000000382110000004000000008C020264B5
-:101AD00010400005000000008F8200A0304200048A
-:101AE0001440FFFA000000008F82004434420004DA
-:101AF000AF8200448F42030824420001AF42030832
-:101B00008F4203088F8200D88F8300D400431023B4
-:101B10002442FF80AF4200908F4200902842FF8114
-:101B200010400006240200018F4200908F430144C0
-:101B300000431021AF42009024020001AF42008C0C
-:101B400032C2000810400006000000008F8202141C
-:101B50003C0381003042FFFF00431025AF82021496
-:101B60003C0300018C636D94306200021040000958
-:101B7000306200013C04000124845FCC3C0500007D
-:101B800024A56D503C06000024C671C81000001248
-:101B900000C5302310400009000000003C04000193
-:101BA00024845FDC3C05000024A571D03C060000C5
-:101BB00024C676781000000800C530233C040001DC
-:101BC00024845FEC3C05000024A569483C06000025
-:101BD00024C66D4800C5302327A7003027A2003453
-:101BE0000C0017A3AFA200103C010001AC226ECC88
-:101BF0003C0200018C426ECC3C0308000002110044
-:101C00000002118200431025AE4200408F8200A0E6
-:101C1000AFA200108F8200B0AFA200148F86005CCC
-:101C20008F87011C3C04000124845FFC3C010001FF
-:101C3000AC366EA43C010001AC206E943C01000166
-:101C4000AC3C6E8C3C010001AC3B6EBC3C01000125
-:101C5000AC376EC03C010001AC3A6EA00C002B3BCF
-:101C6000240524008F820200AFA200108F82022080
-:101C7000AFA200148F8600448F8700503C040001FF
-:101C8000248460080C002B3B240525008F83006012
-:101C90000074100B0242000A0200F821000000004C
-:101CA0000000000D8FBF00608FBE005C8FB5005834
-:101CB0008FB300548FB200508FB1004C8FB00048EA
-:101CC00003E0000827BD006827BDFFE03C040001D9
-:101CD00024846014240526000000302100003821EF
-:101CE000AFBF0018AFA000100C002B3BAFA000143A
-:101CF0008FBF001803E0000827BD002003E00008A4
-:101D00000000000003E000080000000000000000E8
-:101D100000000000000000000000000000000000C3
-:101D200003E000080000000003E0000800000000DD
-:101D300027BDFDE027A500183C04DEAD3484BEEFCE
-:101D4000AFBF02188F8201503C03001F3463FFFFB6
-:101D5000AFA4001800A2282300A328248CA200000E
-:101D60001044000A00000000AFA500108CA2000083
-:101D7000AFA200148F8601508F8702503C040001EF
-:101D80002484601C0C002B3B240527008FBF021805
-:101D900003E0000827BD022027BDFFE03C06ABBAE8
-:101DA00034C6BABEAFB000183C1000043C07007F38
-:101DB00034E7FFFFAFBF001C001028408E04000076
-:101DC0008CA30000ACA00000AE0600008CA20000B6
-:101DD000ACA3000010460005AE04000000A0802166
-:101DE00000F0102B1040FFF5001028403C040001CB
-:101DF00024846028240528000200302100003821B6
-:101E0000AFA000100C002B3BAFA00014020010216B
-:101E10008FBF001C8FB0001803E0000827BD002012
-:101E20008C0202243047003F10E000100080302177
-:101E3000000028212403002000E3102410400002A9
-:101E40000006304200A62821000318421460FFFB60
-:101E500000E310242402F00000A228243402FFFF33
-:101E60000045102B144000033C0200011000000844
-:101E70003C0200013442FFFF008518230043102B71
-:101E80001440000300A010213C02FFFE008210213C
-:101E900003E000080000000027BDFFD0AFB5002818
-:101EA0008FB50040AFB2002000A09021AFB1001C60
-:101EB00024C60003AFBF002CAFB30024AFB000189E
-:101EC0008EA200002403FFFC00C380240050102BCE
-:101ED0001440001B00E088218E330000AFB00010DA
-:101EE0008EA20000AFA200148E270000240530004F
-:101EF0000C002B3B024030218E230000007020217B
-:101F00000064102B10400007024028218CA2000022
-:101F1000AC620000246300040064102B1440FFFB3B
-:101F200024A500048EA2000000501023AEA20000E1
-:101F30008E220000005010211000000BAE22000085
-:101F40002402002DA0820000AFB000108EA200007D
-:101F500002409821AFA200148E2700002405310012
-:101F60000C002B3B02603021026010218FBF002C3F
-:101F70008FB500288FB300248FB200208FB1001CD2
-:101F80008FB0001803E0000827BD003027BDFFE830
-:101F90003C1CC0003C05FFFE3C0300018C636E84CA
-:101FA0003C0400018C846E9034A5BF0824021FFC01
-:101FB0003C010001AC226CD03C0200C03C0100019D
-:101FC000AC226CD43C020020AFBF00103C0100C02A
-:101FD000AC201FFC0043102300441023245BB000FE
-:101FE0000365B8213C1D00018FBD6CCC03A0F0211E
-:101FF0003C0400C0348402003C1A00C03C0300C012
-:10200000346307C824021DFC3C010001AC226CD0E3
-:10201000240218343C010001AC246CD43C010001C2
-:10202000AC226CD03C010001AC236CD40C00180D28
-:10203000375A02008FBF001003E0000827BD0018C8
-:1020400027BDFFC83C04000124846034240532000D
-:102050003C0200018C426CD03C0300018C636CD4C8
-:102060000000302103603821AFBF0030AFB3002C37
-:10207000AFB20028AFB10024AFB00020AFA2001C67
-:10208000AFA30018AFB700100C002B3BAFBA001481
-:102090000C001916000000008F8202403442000438
-:1020A000AF82024024020001AF4200003C02000166
-:1020B00000571021904240F4104000922403FFFC8E
-:1020C0003C1000012610AC733C1200012652A84CB3
-:1020D00002121023004380248FA3001C3C04000143
-:1020E000248460400070102B1440001A27B300189D
-:1020F0008FB100182405300002403021AFB000102D
-:10210000AFA300140C002B3B022038218FA3001832
-:10211000007020210064102B104000070240302185
-:102120008CC20000AC620000246300040064102B29
-:102130001440FFFB24C600048FA2001C0050102393
-:10214000AFA2001C8E620000005010211000000A97
-:10215000AE6200000240882124053100AFB00010BB
-:10216000AFA300148FA70018022030212402002DF5
-:102170000C002B3BA0820000240700208FA3001C32
-:102180003C0400012484605C241200203C01000116
-:10219000AC316EB02C6200201440001D27B1001835
-:1021A0008FB00018240530003C06000124C66F5093
-:1021B000AFA70010AFA300140C002B3B0200382186
-:1021C0008FA300183C04000124846F502465002074
-:1021D0000065102B10400007000000008C820000FA
-:1021E000AC620000246300040065102B1440FFFB68
-:1021F000248400048FA2001C00521023AFA2001CF4
-:102200008E220000005210211000000BAE220000B0
-:102210003C10000126106F5024053100AFA70010BC
-:10222000AFA300148FA70018020030212402002D54
-:102230000C002B3BA0820000240700203C0400017E
-:10224000248460708FA3001C241200203C01000134
-:10225000AC306EE42C6200201440001D27B1001841
-:102260008FB00018240530003C06000124C66F70B2
-:10227000AFA70010AFA300140C002B3B02003821C5
-:102280008FA300183C04000124846F702465002093
-:102290000065102B10400007000000008C82000039
-:1022A000AC620000246300040065102B1440FFFBA7
-:1022B000248400048FA2001C00521023AFA2001C33
-:1022C0008E220000005210211000000BAE220000F0
-:1022D0003C10000126106F7024053100AFA70010DC
-:1022E000AFA300148FA70018020030212402002D94
-:1022F0000C002B3BA08200003C01000110000031CB
-:10230000AC306EE03C1000012610821F3C12000130
-:102310002652809C02121023004380248FA3001CAD
-:102320003C040001248460840070102B1440001AC7
-:1023300027B300188FB10018240530000240302167
-:10234000AFB00010AFA300140C002B3B02203821CB
-:102350008FA30018007020210064102B104000078C
-:10236000024030218CC20000AC62000024630004F3
-:102370000064102B1440FFFB24C600048FA2001C35
-:1023800000501023AFA2001C8E62000000501021EC
-:102390001000000AAE6200000240882124053100CE
-:1023A000AFB00010AFA300148FA700180220302197
-:1023B0002402002D0C002B3BA08200003C010001F8
-:1023C000AC316EB03C0300018C636EB0240204009B
-:1023D0000060F809AF8200708FBF00308FB3002C0F
-:1023E0008FB200288FB100248FB0002003E00008D6
-:1023F00027BD003800000000000000008F82004070
-:102400003C03F000004310243C036000144300062A
-:10241000000000008F8200502403FF80004310243E
-:1024200034420055AF8200508F820054244203E8AA
-:10243000AF820058240201F4AF4200E024020004FD
-:10244000AF4200E824020002AF4001B0AF4000E418
-:10245000AF4200DCAF4000D8AF4000D403E000083A
-:10246000AF4000D08F8200542442000503E00008F2
-:10247000AF82007827BDFFE8AFBF00108F82005405
-:10248000244203E8AF8200583C02080002C2102434
-:10249000104000043C02F7FF3442FFFF02C2B024A8
-:1024A000369400403C0200018C426DA81040001799
-:1024B0003C0202003C0300018C636F1C106000169C
-:1024C0000282A0253C0200018C426E44144000129E
-:1024D0003C0202003C0200018C426D943042000339
-:1024E0001440000D3C0202008F8302243C020002D3
-:1024F0008C428FEC106200083C0202000C003DAFE1
-:1025000000000000100000043C0202000C00419694
-:10251000000000003C02020002C210241040000330
-:10252000000000000C001F4B000000008F4200D88C
-:102530008F4300DC24420001AF4200D80043102B3F
-:102540001440000300000000AF4000D83694008023
-:102550008C0302381060000C000000008F4201B0B4
-:10256000244203E8AF4201B00043102B14400006A0
-:1025700000000000934205C5144000030000000065
-:102580000C001DA0000000008FBF001003E0000839
-:1025900027BD001803E000080000000027BDFFD899
-:1025A000AFBF00208F43002C8F42003810620059CB
-:1025B000000000003C02000100571021904240F052
-:1025C00010400026240700088F4401708F450174D5
-:1025D0008F48000C8F86012024020020AFA200103B
-:1025E000AFA30014AFA800188F42010C0040F809F7
-:1025F00024C6001C14400011240200013C0100010B
-:1026000000370821A02240F08F820124AFA20010E1
-:102610008F8201283C04000124846128AFA20014A9
-:102620008F46002C8F8701203C0500090C002B3BB6
-:1026300034A509001000005C000000008F42030078
-:1026400024420001AF4203008F4203008F42002C5E
-:10265000A34005C110000027AF4200388F4401702D
-:102660008F4501748F43002C8F48000C8F8601200A
-:1026700024020080AFA20010AFA30014AFA800187E
-:102680008F42010C0040F80924C6001C14400011C0
-:10269000240200013C01000100370821A02240F182
-:1026A0008F820124AFA200108F8201283C04000118
-:1026B00024846134AFA200148F46002C8F87012040
-:1026C0003C0500090C002B3B34A51100100000361E
-:1026D000000000008F4203008F43002C24420001C1
-:1026E000AF4203008F42030024020001A34205C150
-:1026F000AF4300383C01000100370821A02040F121
-:102700003C01000100370821A02040F01000002605
-:10271000AF400034934205C11040001D000000008E
-:10272000A34005C18F8200403042000114400008E0
-:10273000000020218C0301042402000150620005E6
-:10274000240400018C020264104000030080102168
-:102750002404000100801021104000060000000049
-:102760008F42030C24420001AF42030C100000080A
-:102770008F42030C8F82004434420004AF82004435
-:102780008F42030824420001AF4203088F4203082E
-:102790003C01000100370821A02040F03C0100016D
-:1027A00000370821A02040F18F42000010400007B0
-:1027B00000000000AF80004C8F82004C1040FFFDF5
-:1027C000000000001000000500000000AF8000487D
-:1027D0008F8200481040FFFD000000008F820060E3
-:1027E0003C03FF7F3463FFFF00431024AF8200608F
-:1027F0008F420000104000030000000010000002A3
-:10280000AF80004CAF8000488FBF002003E000087D
-:1028100027BD002803E000080000000027BDFFD806
-:10282000AFBF00208F4300448F42007C106200291C
-:10283000240700088F4401688F45016C8F48000C05
-:102840008F86012024020040AFA20010AFA3001425
-:10285000AFA800188F42010C0040F80924C6001CE4
-:1028600014400011240200013C010001003708213E
-:10287000A02240F28F820124AFA200108F82012893
-:102880003C0400012484613CAFA200148F46004444
-:102890008F8701203C0500090C002B3B34A5130059
-:1028A0001000000F000000008F42030424420001CA
-:1028B000AF4203048F4203048F420044AF42007CC6
-:1028C0003C01000100370821A02040F21000000464
-:1028D000AF4000783C01000100370821A02040F201
-:1028E0008F4200001040000700000000AF80004C45
-:1028F0008F82004C1040FFFD00000000100000051A
-:1029000000000000AF8000488F8200481040FFFDAB
-:10291000000000008F8200603C03FEFF3463FFFF75
-:1029200000431024AF8200608F420000104000037B
-:102930000000000010000002AF80004CAF80004893
-:102940008FBF002003E0000827BD002803E0000837
-:10295000000000003C0200018C426DA827BDFFA8CA
-:10296000AFBF0050AFBE004CAFB50048AFB300449E
-:10297000AFB20040AFB1003CAFB00038104000D55E
-:102980008F9000448F4200D0244300012842000B66
-:10299000144000E4AF4300D08F42000430420002F4
-:1029A0001440009CAF4000D08F4200043C03000163
-:1029B0008C636D9834420002AF420004240200018F
-:1029C000146200033C020600100000023442300092
-:1029D00034421000AFA200208F4A0018AFAA003482
-:1029E00027AA0020AFAA002C8FAA0034240200FFDF
-:1029F0001142000200001821254300018C02022828
-:102A0000006098211662000E3C0500098F42033CCD
-:102A100024420001AF42033C8F42033C8C02022857
-:102A20008FA700343C0400012484610CAFA0001483
-:102A3000AFA200108FA600201000007034A5050082
-:102A40008FAA0034000A38C000F710218FA300209D
-:102A50008FA40024AC4304C0AC4404C48F8300544E
-:102A60008F820054247103E8022210232C4203E9D0
-:102A70001040001B0000A82100E09021265E04C049
-:102A80008F4401788F45017C02401821240A0004FC
-:102A9000AFAA0010AFB300148F48000C0000102143
-:102AA00002FE3021AFA800188F48010C240700084F
-:102AB00000A3282100A3482B008220210100F8094F
-:102AC0000089202154400006241500018F82005403
-:102AD000022210232C4203E91440FFE90000000009
-:102AE00032A200FF54400018AF5300188F42037801
-:102AF00024420001AF4203788F4203788F82012085
-:102B00008FAA002C8FA70034AFA200108F8201245F
-:102B10003C04000124846118AFA200148D4600001B
-:102B20003C0500091000003534A506008F4203085B
-:102B30002415000124420001AF4203088F4203081C
-:102B40001000001E32A200FF8F8300548F820054B9
-:102B5000247103E8022210232C4203E910400016DE
-:102B60000000A8213C1E0020241200108F42000CFF
-:102B70008F4401608F4501648F860120AFB2001041
-:102B8000AFB30014005E1025AFA200188F42010CF5
-:102B9000240700080040F80924C6001C1440FFE385
-:102BA000000000008F820054022210232C4203E90F
-:102BB0001440FFEE0000000032A200FF144000119C
-:102BC0003C0500098F42037824420001AF4203789C
-:102BD0008F4203788F8201208FAA002C8FA70034A8
-:102BE000AFA200108F8201243C04000124846120E4
-:102BF000AFA200148D46000034A507000C002B3B4B
-:102C0000000000008F4202EC24420001AF4202ECBF
-:102C10008F4202EC8F4200043042000150400029F4
-:102C2000361000403C02040002C210241040001381
-:102C30002404FFDF8F4202508F4302548F4401B4BB
-:102C400014640006361000408F4202708F430274F5
-:102C50008F4401B8106400072402FFDF8F42025046
-:102C60008F4302548F4402708F450274100000128B
-:102C70003A1000201000002B020280248F420250E4
-:102C80008F4302548F4501B414650006020480246A
-:102C90008F4202708F4302748F4401B85064002148
-:102CA000361000408F4202508F4302548F4402700E
-:102CB0008F4502743A100040AF4301B41000001970
-:102CC000AF4501B88F4200D4244300011000001129
-:102CD000284200338F4200043042000110400009B6
-:102CE0003C02040002C21024104000042402FFDF52
-:102CF000020280241000000B361000401000000972
-:102D0000361000608F4200D436100040244300018A
-:102D1000284201F514400003AF4300D4AF4000D473
-:102D20003A100020AF9000442402FF7F0282A024CA
-:102D30008FBF00508FBE004C8FB500488FB300444A
-:102D40008FB200408FB1003C8FB0003803E0000824
-:102D500027BD005803E00008000000003C0200010D
-:102D60008C426DA827BDFFB0AFBF0048AFBE004486
-:102D7000AFB50040AFB3003CAFB20038AFB10034E4
-:102D8000104000C7AFB000308F4200D02443000194
-:102D90002842000B144000DAAF4300D08F420004F9
-:102DA0003042000214400097AF4000D08F42000430
-:102DB0003C0300018C636D9834420002AF42000472
-:102DC00024020001146200033C020600100000020D
-:102DD0003442300034421000AFA20020000018211D
-:102DE0008F5E001827AA0020240200FF13C20002F1
-:102DF000AFAA002C27C300018C020228006090219A
-:102E00001642000E001E38C08F42033C24420001CF
-:102E1000AF42033C8F42033C8C0202283C04000179
-:102E20002484610C3C050009AFA00014AFA200107F
-:102E30008FA600201000006D34A5050000F71021BA
-:102E40008FA300208FA40024AC4304C0AC4404C46E
-:102E50008F8300548F820054247003E802021023F1
-:102E60002C4203E91040001B0000982100E088215B
-:102E7000263504C08F4401788F45017C022018213B
-:102E8000240A0004AFAA0010AFB200148F48000C4F
-:102E90000000102102F53021AFA800188F48010C66
-:102EA0002407000800A3282100A3482B008220212A
-:102EB0000100F80900892021544000062413000174
-:102EC0008F820054020210232C4203E91440FFE9D0
-:102ED00000000000326200FF54400017AF5200189B
-:102EE0008F42037824420001AF4203788F42037877
-:102EF0008F8201208FAA002CAFA200108F820124A4
-:102F00003C040001248461183C050009AFA20014B0
-:102F10008D4600001000003534A506008F420308DE
-:102F20002413000124420001AF4203088F4203082A
-:102F30001000001E326200FF8F8300548F82005405
-:102F4000247003E8020210232C4203E9104000160B
-:102F5000000098213C150020241100108F42000C25
-:102F60008F4401608F4501648F860120AFB100104E
-:102F7000AFB2001400551025AFA200188F42010C0B
-:102F8000240700080040F80924C6001C1440FFE391
-:102F9000000000008F820054020210232C4203E93B
-:102FA0001440FFEE00000000326200FF14400011E8
-:102FB000000000008F42037824420001AF420378F2
-:102FC0008F4203788F8201208FAA002CAFA20010BD
-:102FD0008F8201243C040001248461203C05000907
-:102FE000AFA200148D46000034A507000C002B3B57
-:102FF00003C038218F4202EC24420001AF4202ECB0
-:103000008F4202EC8F420004304200011040001851
-:10301000240400018F4202508F4302548F4501B4B3
-:103020003C01000114650006A0246CF18F4202707F
-:103030008F4302748F4401B8106400210000000027
-:103040008F4202508F4302543C04000190846CF084
-:103050008F4602708F47027438840001AF4301B479
-:10306000AF4701B83C01000110000025A0246CF01E
-:103070008F4200D43C010001A0206CF024430001E9
-:10308000284200331440001EAF4300D43C0200012C
-:1030900090426CF1AF4000D410000017384200019C
-:1030A0008F42000430420001104000080000000080
-:1030B0000C00565A000020213C010001A0206CF1B8
-:1030C0003C0100011000000EA0206CF08F4200D4E3
-:1030D0003C010001A0206CF024430001284201F5CE
-:1030E00014400007AF4300D43C02000190426CF151
-:1030F000AF4000D4004210263C010001A0226CF138
-:103100003C0300018C636D98240200021462000CE1
-:103110003C0300023C03000190636CF124020001B7
-:103120005462001F000020213C02000190426CF01C
-:103130001443001B24040005100000192404000699
-:103140003C0200028C428FF4004310241040000B1C
-:10315000240200013C03000190636CF154620010F2
-:10316000000020213C02000190426CF01443000C4E
-:10317000240400031000000A240400043C0300019E
-:1031800090636CF114620006000020213C020001F3
-:1031900090426CF024040001504400012404000219
-:1031A0000C00565A000000002402FF7F0282A02477
-:1031B0008FBF00488FBE00448FB500408FB3003CE6
-:1031C0008FB200388FB100348FB0003003E00008B8
-:1031D00027BD005003E00008000000003C02000191
-:1031E0008C426DA827BDFFB0AFBF0048AFBE004402
-:1031F000AFB50040AFB3003CAFB20038AFB1003460
-:10320000104000DEAFB000308F4200D03C0400011F
-:103210008C846D98244300012842000BAF4400E8E1
-:10322000144000FEAF4300D08F4200043042000241
-:1032300014400095AF4000D08F4200043442000299
-:10324000AF42000424020001148200033C02060085
-:10325000100000023442300034421000AFA20020BF
-:10326000000018218F5E001827AA0020240200FF0A
-:1032700013C20002AFAA002C27C300018C0202284F
-:10328000006090211642000E001E38C08F42033CA1
-:1032900024420001AF42033C8F42033C8C020228CF
-:1032A0003C0400012484610C3C050009AFA000141B
-:1032B000AFA200108FA600201000006D34A50500FD
-:1032C00000F710218FA300208FA40024AC4304C07A
-:1032D000AC4404C48F8300548F820054247003E8EC
-:1032E000020210232C4203E91040001B0000982129
-:1032F00000E08821263504C08F4401788F45017C89
-:1033000002201821240A0004AFAA0010AFB2001452
-:103310008F48000C0000102102F53021AFA80018E2
-:103320008F48010C2407000800A3282100A3482B84
-:10333000008220210100F809008920215440000664
-:10334000241300018F820054020210232C4203E94F
-:103350001440FFE900000000326200FF54400017F3
-:10336000AF5200188F42037824420001AF42037825
-:103370008F4203788F8201208FAA002CAFA2001009
-:103380008F8201243C040001248461183C0500095B
-:10339000AFA200148D4600001000003534A50600D1
-:1033A0008F4203082413000124420001AF420308A6
-:1033B0008F4203081000001E326200FF8F8300540A
-:1033C0008F820054247003E8020210232C4203E988
-:1033D00010400016000098213C1500202411001018
-:1033E0008F42000C8F4401608F4501648F8601205D
-:1033F000AFB10010AFB2001400551025AFA20018F5
-:103400008F42010C240700080040F80924C6001C64
-:103410001440FFE3000000008F82005402021023DA
-:103420002C4203E91440FFEE00000000326200FF6E
-:1034300014400011000000008F4203782442000174
-:10344000AF4203788F4203788F8201208FAA002C2D
-:10345000AFA200108F8201243C040001248461206B
-:103460003C050009AFA200148D46000034A50700FA
-:103470000C002B3B03C038218F4202EC2442000198
-:10348000AF4202EC8F4202EC8F4200043042000156
-:10349000104000333C02040002C210241040001708
-:1034A00000000000934205C08F4402508F45025433
-:1034B0008F4301B43442002014A30006A34205C088
-:1034C0008F4202708F4302748F4401B81064000869
-:1034D000000000008F4202508F430254934405C005
-:1034E0008F4602708F470274100000163884004027
-:1034F000934205C010000048304200BF934205C00F
-:103500008F4402508F4502548F4301B4304200BFB4
-:1035100014A30006A34205C08F4202708F430274B9
-:103520008F4401B81064000B000000008F4202506D
-:103530008F430254934405C08F4602708F47027434
-:1035400038840020AF4301B4AF4701B81000003306
-:10355000A34405C0934205C01000002F3442002050
-:10356000934205C08F4300D434420020A34205C0DB
-:103570002462000110000023286300338F4200E41E
-:103580008F4300E024420001AF4200E40043102AD0
-:1035900014400006240300018F4200E81443000297
-:1035A000AF4000E424030004AF4300E88F4200046E
-:1035B000304200011040000D3C02040002C2102401
-:1035C0001040000700000000934205C03442004054
-:1035D000A34205C0934205C01000000F304200DF37
-:1035E000934205C01000000C34420060934205C0B5
-:1035F0008F4300D434420020A34205C0246200015E
-:10360000286300FB14600005AF4200D4934205C05C
-:10361000AF4000D438420040A34205C0934205C0E9
-:103620008F4300E83042007FA34205C0240200011E
-:103630001462000500000000934405C0000421024C
-:1036400010000003348400F0934405C03484000F5C
-:103650000C005640000000002402FF7F0282A024DC
-:103660008FBF00488FBE00448FB500408FB3003C31
-:103670008FB200388FB100348FB0003003E0000803
-:1036800027BD005003E000080000000027BDFFB088
-:10369000274401C026E30028246504000065102BA0
-:1036A000AFBF0048AFBE0044AFB50040AFB3003C71
-:1036B000AFB20038AFB1003410400007AFB00030F7
-:1036C0008C820000AC620000246300040065102BB3
-:1036D0001440FFFB248400048C020080AEE200440E
-:1036E0008C0200C0AEE200408C020084AEE20030EA
-:1036F0008C020084AEE2023C8C020088AEE2024002
-:103700008C02008CAEE202448C020090AEE20248D1
-:103710008C020094AEE2024C8C020098AEE20250A1
-:103720008C02009CAEE202548C0200A0AEE2025871
-:103730008C0200A4AEE2025C8C0200A8AEE2026041
-:103740008C0200ACAEE202648C0200B0AEE2026811
-:103750008C0200B4AEE2026C8C0200B8AEE20270E1
-:103760008C0200BC24040001AEE20274AEE000341E
-:1037700000041080005710218EE300348C42023C7C
-:1037800024840001006218212C82000FAEE3003473
-:103790001440FFF8000410808C0200CCAEE2004818
-:1037A0008C0200D0AEE2004C8C0200E0AEE201F8E8
-:1037B0008C0200E4AEE201FC8C0200E8AEE2020002
-:1037C0008C0200ECAEE202048C0200F0AEE20208D1
-:1037D0008EE400C08EE500C48C0200FC0045102B76
-:1037E0001040000B000000008EE200C08EE300C419
-:1037F0002404000124050000006518210065302B19
-:103800000044102100461021AEE200C0AEE300C427
-:103810008C0200FC8EE400C08EE500C42408FFFF8B
-:1038200024090000004018210000102100882024F5
-:1038300000A928240082202500A32825AEE400C08A
-:10384000AEE500C48EE400D08EE500D48C0200F416
-:103850000045102B1040000B000000008EE200D04D
-:103860008EE300D424040001240500000065182123
-:103870000065302B0044102100461021AEE200D03C
-:10388000AEE300D48C0200F48EE400D08EE500D4C8
-:1038900000401821000010210088202400A92824BD
-:1038A0000082202500A32825AEE400D0AEE500D498
-:1038B0008EE400C88EE500CC8C0200F80045102B89
-:1038C0001040000B000000008EE200C88EE300CC28
-:1038D0002404000124050000006518210065302B38
-:1038E0000044102100461021AEE200C8AEE300CC37
-:1038F0008C0200F88EE400C88EE500CC0040182150
-:10390000000010210088202400A9282400822025FE
-:1039100000A3282524020008AEE400C8AEE500CCD0
-:10392000AFA20010AFA000148F42000C8C0402085C
-:103930008C05020CAFA200188F42010C26E600286D
-:103940000040F80924070400104000F03C02040085
-:10395000AFA20020934205C6104000890000182144
-:103960008F5E001827AA0020240200FF13C2000265
-:10397000AFAA002C27C300018C020228006090210E
-:103980001642000E001E38C08F42033C2442000144
-:10399000AF42033C8F42033C8C0202283C040001EE
-:1039A0002484610C3C050009AFA00014AFA20010F4
-:1039B0008FA600201000006B34A5050000F7102131
-:1039C0008FA300208FA40024AC4304C0AC4404C4E3
-:1039D0008F8300548F820054247003E80202102366
-:1039E0002C4203E91040001B0000982100E08821D0
-:1039F000263504C08F4401788F45017C02201821B0
-:103A0000240A0004AFAA0010AFB200148F48000CC3
-:103A10000000102102F53021AFA800188F48010CDA
-:103A20002407000800A3282100A3482B008220219E
-:103A30000100F809008920215440000624130001E8
-:103A40008F820054020210232C4203E91440FFE944
-:103A500000000000326200FF54400017AF5200180F
-:103A60008F42037824420001AF4203788F420378EB
-:103A70008F8201208FAA002CAFA200108F82012418
-:103A80003C040001248461183C050009AFA2001425
-:103A90008D4600001000003334A506008F42030855
-:103AA0002413000124420001AF4203088F4203089F
-:103AB0001000001C326200FF8F8300548F8200547C
-:103AC000247003E8020210232C4203E91040001482
-:103AD00000009821241100108F42000C8F440160D7
-:103AE0008F4501648F860120AFB10010AFB2001482
-:103AF000AFA200188F42010C240700080040F8090B
-:103B000024C6001C1440FFE5000000008F82005412
-:103B1000020210232C4203E91440FFEF00000000D2
-:103B2000326200FF54400012240200018F420378E9
-:103B300024420001AF4203788F4203788F82012034
-:103B40008FAA002CAFA200108F8201243C04000138
-:103B5000248461203C050009AFA200148D460000BA
-:103B600034A507000C002B3B03C0382100001021B6
-:103B70001440005B240200011000006500000000FA
-:103B80008F510018240200FF122200020000802141
-:103B9000263000018C0202281602000E001130C0EF
-:103BA0008F42033C24420001AF42033C8F42033C5E
-:103BB0008C0202283C040001248460F43C050009C6
-:103BC000AFA00014AFA200108FA600201000003F8D
-:103BD00034A5010000D710218FA300208FA400245A
-:103BE000AC4304C0AC4404C400C018218F44017825
-:103BF0008F45017C0000102124070004AFA70010AE
-:103C0000AFB000148F48000C24C604C002E6302177
-:103C1000AFA800188F48010C2407000800A3282132
-:103C200000A3482B008220210100F80900892021EF
-:103C30001440000B240700088F820120AFA200105F
-:103C40008F8201243C040001248460FC3C050009AF
-:103C5000AFA200148FA600201000001C34A50200A3
-:103C60008F4401608F4501648F43000CAF500018F2
-:103C70008F86012024020010AFA20010AFB0001404
-:103C8000AFA300188F42010C0040F80924C6001CA5
-:103C900054400011240200018F42034024420001DD
-:103CA000AF4203408F4203408F820120AFA2001039
-:103CB0008F8201243C040001248461043C05000936
-:103CC000AFA200148FA6002034A503000C002B3BEC
-:103CD00002203821000010211040000D24020001B4
-:103CE0008F4202E8A34005C6AF4001B02442000164
-:103CF000AF4202E88F4202E88EE201502442000106
-:103D0000AEE20150100000038EE2015024020001D7
-:103D1000A34205C68FBF00488FBE00448FB5004048
-:103D20008FB3003C8FB200388FB100348FB00030B9
-:103D300003E0000827BD005027BDFFD8AFBF00201B
-:103D40008F8200B030420004104000680000000084
-:103D50008F4301288F8201041462000500000000D7
-:103D60008F4301308F8200B4106200060000000013
-:103D70008F820104AF4201288F8200B41000005BE3
-:103D8000AF4201308F8200B03C030080004310241A
-:103D90001040000D000000008F82011C3442000220
-:103DA000AF82011C8F8200B02403FFFB004310246C
-:103DB000AF8200B08F82011C2403FFFD004310245A
-:103DC0001000004AAF82011C8F4301288F8201043A
-:103DD00014620005000000008F4301308F8200B4A0
-:103DE00010620010000000008F820104AF42012821
-:103DF0008F8200B48F430128AF420130AFA300107F
-:103E00008F4201303C04000124846144AFA20014BD
-:103E10008F86011C8F8700B03C0500051000003123
-:103E200034A509008F420128AFA200108F42013053
-:103E30003C04000124846150AFA200148F86011C51
-:103E40008F8700B03C0500050C002B3B34A510000B
-:103E50008F82011C34420002AF82011C8F83010457
-:103E60008F8200B034420001AF8200B0240200080B
-:103E7000AF830104AFA20010AFA000148F42000C6A
-:103E80008C0402088C05020CAFA200188F42010CB2
-:103E900026E600280040F809240704008F82011C50
-:103EA0002403FFFD00431024AF82011C8EE201DCDD
-:103EB00024420001AEE201DC8EE201DC8F420128E7
-:103EC000AFA200108F4201303C0400012484615CE9
-:103ED000AFA200148F86011C8F8700B03C0500053F
-:103EE00034A511000C002B3B000000008F8200A0C5
-:103EF0003042000410400069000000008F43012C94
-:103F00008F82012414620005000000008F430134F9
-:103F10008F8200A410620006000000008F8201243E
-:103F2000AF42012C8F8200A41000005CAF4201342C
-:103F30008F8200A03C030080004310241040000D3D
-:103F4000000000008F82011C34420002AF82011C7D
-:103F50008F8200A02403FFFB00431024AF8200A047
-:103F60008F82011C2403FFFD004310241000004B2E
-:103F7000AF82011C8F43012C8F8201241462000543
-:103F8000000000008F4301348F8200A410620010F3
-:103F9000000000008F820124AF42012C8F8200A418
-:103FA0008F43012CAF420134AFA300108F42013484
-:103FB0003C04000124846168AFA200148F86011CB8
-:103FC0008F8700A03C0500051000003234A51200C8
-:103FD0008F42012CAFA200108F4201343C0400013B
-:103FE00024846174AFA200148F86011C8F8700A007
-:103FF0003C0500050C002B3B34A513008F82011CEF
-:1040000034420002AF82011C8F8301248F8200A002
-:1040100034420001AF8200A024020080AF8301245B
-:10402000AFA20010AFA000148F4200148C0402084D
-:104030008C05020CAFA200188F4201083C0600015B
-:1040400024C66ED80040F809240700048F82011CA2
-:104050002403FFFD00431024AF82011C8EE201DC2B
-:1040600024420001AEE201DC8EE201DC8F42012C31
-:10407000AFA200108F4201343C040001248461800F
-:10408000AFA200148F86011C8F8700A03C0500059D
-:1040900034A514000C002B3B000000008FBF002053
-:1040A00003E0000827BD00283C0810002407000199
-:1040B0003C0600803C0501008F82007000481024FF
-:1040C0001040FFFD000000008F82005424420005D4
-:1040D000AF8200788C040234108000160000182192
-:1040E0003C020001005710218C4240E824420005A8
-:1040F0003C01000100370821AC2240E83C020001ED
-:10410000005710218C4240E80044102B1440000955
-:10411000000000003C0300803C0100010037082142
-:10412000AC2040E83C010001003708211000000BE2
-:10413000A02740F03C02000100571021904240F0BF
-:1041400054400006006618253C020001005710216B
-:10415000904240F154400001006618258C04023062
-:1041600010800013000000003C02000100571021E5
-:104170008C4240EC244200053C010001003708213C
-:10418000AC2240EC3C020001005710218C4240EC74
-:104190000044102B14400006000000003C01000108
-:1041A00000370821AC2040EC1000000600651825FF
-:1041B0003C02000100571021904240F2544000019F
-:1041C000006518251060FFBC000000008F42000051
-:1041D0001040000700000000AF80004C8F82004CB0
-:1041E0001040FFFD0000000010000005000000006E
-:1041F000AF8000488F8200481040FFFD00000000A3
-:104200008F82006000431025AF8200608F42000063
-:1042100010400003000000001000FFA7AF80004C1A
-:104220001000FFA5AF80004803E000080000000078
-:1042300000000000000000000000000027BDFFE0BB
-:10424000AFBF00188F86006430C200041040002504
-:10425000240400048C020114AF420020AF840064E7
-:104260008F4202FC24420001AF4202FC8F4202FC5A
-:104270008F820064304200041440000500000000FA
-:104280008C0301148F4200201462FFF20000000032
-:104290008F420000104000078F43003CAF80004C6D
-:1042A0008F82004C1040FFFD000000001000000550
-:1042B00000000000AF8000488F8200481040FFFDE2
-:1042C000000000008F82006000431025AF82006074
-:1042D0008F42000010400073000000001000006FCB
-:1042E0000000000030C20008104000202404000834
-:1042F0008C02011CAF420048AF8400648F4202A8C8
-:1043000024420001AF4202A88F4202A88F820064BB
-:104310003042000814400005000000008C03011C1E
-:104320008F4200481462FFF2000000008F4200003C
-:104330001040000700000000AF80004C8F82004C4E
-:104340001040FFFD0000000010000005000000000C
-:10435000AF8000488F8200481040FFFD0000000041
-:104360008F8200601000FFD93442020030C200206A
-:1043700010400023240400208C02012CAF4200686E
-:10438000AF8400648F4202D824420001AF4202D8B9
-:104390008F4202D88F820064304200201440000512
-:1043A00032C240008C03012C8F4200681462FFF27D
-:1043B00032C24000144000023C02000102C2B0259B
-:1043C0008F4200001040000700000000AF80004C4A
-:1043D0008F82004C1040FFFD00000000100000051F
-:1043E00000000000AF8000488F8200481040FFFDB1
-:1043F000000000008F8200601000FFB4344208000B
-:1044000030C2001010400029240400108C02012446
-:10441000AF420058AF8400648F4202D424420001AE
-:10442000AF4202D48F4202D48F8200643042001027
-:104430001440000532C220008C0301248F42005832
-:104440001462FFF232C220005040000136D68000D4
-:104450008F4200001040000700000000AF80004CB9
-:104460008F82004C1040FFFD00000000100000058E
-:1044700000000000AF8000488F8200481040FFFD20
-:10448000000000008F82006034420100AF820060B3
-:104490008F42000010400003000000001000006C7C
-:1044A000AF80004C1000006AAF80004830C20001AD
-:1044B0001040000424020001AF8200641000006478
-:1044C0000000000030C200021440000B3C05000355
-:1044D0003C0400012484624434A505000000382116
-:1044E000AFA000100C002B3BAFA000142402FFC0B3
-:1044F00010000057AF8200648C05022C8C02010C66
-:1045000010A20048000510808C46030024A2000180
-:104510003045003F24020003AC05022C00061E02B9
-:1045200010620005240200101062001D30C20FFF4F
-:1045300010000039000000008F4302A88F440000E3
-:1045400030C20FFFAF42004824630001AF4302A80E
-:10455000108000078F4202A8AF80004C8F82004C71
-:104560001040FFFD000000001000000500000000EA
-:10457000AF8000488F8200481040FFFD000000001F
-:104580008F82006034420200AF8200608F420000E0
-:104590001040001F000000001000001B0000000081
-:1045A000AF42005832C220005040000136D6800091
-:1045B0008F4202D48F43000024420001AF4202D454
-:1045C000106000078F4202D4AF80004C8F82004CF5
-:1045D0001040FFFD0000000010000005000000007A
-:1045E000AF8000488F8200481040FFFD00000000AF
-:1045F0008F82006034420100AF8200608F42000071
-:10460000104000030000000010000006AF80004CC6
-:1046100010000004AF8000480C00219600C020214B
-:10462000004028218C02010C14A200022402000286
-:10463000AF8200648F8200643042000214400004A4
-:10464000000000008C02010C14A2FFAC000000006E
-:104650008FBF001803E0000827BD002003E000081A
-:104660000000000027BDFFA0AFB000400080802107
-:10467000001016022442FFFF304300FF2C6200139B
-:10468000AFBF0058AFBE0054AFB50050AFB3004C41
-:10469000AFB20048AFB10044104001F3AFA5003401
-:1046A000000310803C010001002208218C22628856
-:1046B00000400008000000000010130230440FFF0B
-:1046C0002402000110820005240200021082000C66
-:1046D0002402FFFE100000243C0500038F43000469
-:1046E0003C0200018C426F04AF440200AF4402045C
-:1046F0003C0400018C846E801000000934630001CA
-:104700008F430004AF440200AF4402043C040001A4
-:104710008C846E80006218243C0200012442CA2866
-:104720000002110000021182AF4300043C030800A4
-:1047300000431025AC8200388F84005400041442DA
-:1047400000041C820043102100041CC200431023FB
-:1047500000041D020043102100041D4200431023E9
-:1047600010000009AF4202083C040001248462509A
-:1047700034A510000200302100003821AFA0001045
-:104780000C002B3BAFA000148F4202A0244200017A
-:10479000AF4202A01000021F8F4202A027B00028E3
-:1047A00002002021240502100C002BBF2406000863
-:1047B0000C00251802002021100002160000000045
-:1047C0008FAA003427A40028000A1880254200017F
-:1047D0003042003FAFA200348C6503008FAA003442
-:1047E000000210808C430300254200013042003F4C
-:1047F000AFA20034AC02022CAFA500280C00251893
-:10480000AFA3002C100002030000000027B0002816
-:1048100002002021240502100C002BBF24060008F2
-:104820000C00265702002021100001FA00000000B1
-:104830008FAA003427A40028000A1880254200010E
-:104840003042003FAFA200348C6503008FAA0034D1
-:10485000000210808C430300254200013042003FDB
-:10486000AFA20034AC02022CAFA500280C002657E2
-:10487000AFA3002C100001E700000000001013029D
-:1048800030430FFF240200011062000524020002E1
-:104890001062001E3C020002100000333C050003C1
-:1048A0003C03000202C310245440003702C3B02569
-:1048B0008F8202283C01000100370821AC2238D841
-:1048C0008F82022C3C01000100370821AC2238DC29
-:1048D0008F8202303C01000100370821AC2238E011
-:1048E0008F8202343C01000100370821AC2238E4F9
-:1048F0002402FFFFAF820228AF82022CAF82023077
-:10490000AF8202341000002002C3B02502C210247E
-:10491000104000123C02FFFD3C0200010057102134
-:104920008C4238D8AF8202283C0200010057102187
-:104930008C4238DCAF82022C3C020001005710216F
-:104940008C4238E0AF8202303C0200010057102157
-:104950008C4238E4AF8202343C02FFFD3442FFFF58
-:104960001000000902C2B0243C0400012484625CEF
-:1049700034A511000200302100003821AFA0001042
-:104980000C002B3BAFA000148F4202CC244200014C
-:10499000AF4202CC1000019F8F4202CC00101302E4
-:1049A00030450FFF2402000110A20005240200027E
-:1049B00010A2000D3C0408FF100000143C05000389
-:1049C0003C0208FF3442FFFF8F8302203C040004B6
-:1049D00002C4B0250062182434630008AF830220AB
-:1049E00010000012AF4502983484FFF73C03FFFB30
-:1049F0008F8202203463FFFF02C3B02400441024DE
-:104A0000AF82022010000009AF4502983C0400016B
-:104A10002484626834A5120002003021000038218D
-:104A2000AFA000100C002B3BAFA000148F4202BCC3
-:104A300024420001AF4202BC100001768F4202BC4A
-:104A400027840208240502000C002BBF240600085E
-:104A500027440224240502000C002BBF2406000872
-:104A60008F4202C424420001AF4202C41000016917
-:104A70008F4202C40010130230430FFF24020001D2
-:104A8000106200112862000250400005240200025A
-:104A90001060000700000000100000170000000078
-:104AA0001062000F00000000100000130000000062
-:104AB0008C060248000020210C005104240500044B
-:104AC00010000007000000008C06024800002021B2
-:104AD0000C00510424050004100000100000000028
-:104AE0008C06024C000020210C005104240500011A
-:104AF0001000000A000000003C04000124846274DD
-:104B00003C05000334A513000200302100003821C9
-:104B1000AFA000100C002B3BAFA000148F4202C0CE
-:104B200024420001AF4202C01000013A8F4202C08D
-:104B30000C002426000000001000013600000000D8
-:104B400024020001A34205C5241001008F4401A8DE
-:104B50008F4501ACAFB00010AFA000148F4200141D
-:104B6000AFA200188F42010826E600280040F8098D
-:104B7000240704001040FFF500000000100001258C
-:104B8000000000003C03FFFF34637FFF8F42036897
-:104B90008F44036002C3B02400001821AF400058C6
-:104BA000AF40005CAF400060AF40006400441023A1
-:104BB000AF4203683C020900AF400360AFA200208F
-:104BC0008F5E001827AA0020240200FF13C20002F3
-:104BD000AFAA003C27C300018C020228006090218C
-:104BE0001642000E001E38C08F42033C24420001D2
-:104BF000AF42033C8F42033C8C0202283C0400017C
-:104C00002484620C3C050009AFA00014AFA2001080
-:104C10008FA600201000006B34A5050000F71021BE
-:104C20008FA300208FA40024AC4304C0AC4404C470
-:104C30008F8300548F820054247003E802021023F3
-:104C40002C4203E91040001B0000982100E088215D
-:104C5000263504C08F4401788F45017C022018213D
-:104C6000240A0004AFAA0010AFB200148F48000C51
-:104C70000000102102F53021AFA800188F48010C68
-:104C80002407000800A3282100A3482B008220212C
-:104C90000100F80900892021544000062413000176
-:104CA0008F820054020210232C4203E91440FFE9D2
-:104CB00000000000326200FF54400017AF5200189D
-:104CC0008F42037824420001AF4203788F42037879
-:104CD0008F8201208FAA003CAFA200108F82012496
-:104CE0003C040001248462183C050009AFA20014B2
-:104CF0008D4600001000003334A506008F420308E3
-:104D00002413000124420001AF4203088F4203082C
-:104D10001000001C326200FF8F8300548F82005409
-:104D2000247003E8020210232C4203E9104000140F
-:104D300000009821241100108F42000C8F44016064
-:104D40008F4501648F860120AFB10010AFB200140F
-:104D5000AFA200188F42010C240700080040F80998
-:104D600024C6001C1440FFE5000000008F820054A0
-:104D7000020210232C4203E91440FFEF0000000060
-:104D8000326200FF14400011000000008F420378DF
-:104D900024420001AF4203788F4203788F820120C2
-:104DA0008FAA003CAFA200108F8201243C040001B6
-:104DB000248462203C050009AFA200148D46000047
-:104DC00034A507000C002B3B03C038218F4202B0F2
-:104DD00024420001AF4202B08F4202B08F4202F87B
-:104DE00024420001AF4202F81000008A8F4202F80C
-:104DF0008C02025C27440224AF4201F08C02026064
-:104E000024050200240600080C002BBFAF4201F865
-:104E10008F82022030420008144000022402000168
-:104E200024020002AF4202988F4202AC24420001E9
-:104E3000AF4202AC100000778F4202AC3C0200FF90
-:104E40003442FFFF0202182432C2018014400006DF
-:104E50003402FFFB0043102B14400003000000004D
-:104E60001000006CAF4300BC3C040001248462804D
-:104E70003C05000334A51500020030210000382154
-:104E8000AFA000100C002B3BAFA000143C020700A9
-:104E90003442100000101E0200621825AFA300204B
-:104EA0008F510018240200FF12220002000080210E
-:104EB000263000018C0202281602000E001130C0BC
-:104EC0008F42033C24420001AF42033C8F42033C2B
-:104ED0008C0202283C040001248461F43C05000992
-:104EE000AFA00014AFA200108FA600201000003F5A
-:104EF00034A5010000D710218FA300208FA4002427
-:104F0000AC4304C0AC4404C400C018218F440178F1
-:104F10008F45017C0000102124070004AFA700107A
-:104F2000AFB000148F48000C24C604C002E6302144
-:104F3000AFA800188F48010C2407000800A32821FF
-:104F400000A3482B008220210100F80900892021BC
-:104F50001440000B240700088F820120AFA200102C
-:104F60008F8201243C040001248461FC3C0500097B
-:104F7000AFA200148FA600201000001C34A5020070
-:104F80008F4401608F4501648F43000CAF500018BF
-:104F90008F86012024020010AFA20010AFB00014D1
-:104FA000AFA300188F42010C0040F80924C6001C72
-:104FB00014400010000000008F4203402442000112
-:104FC000AF4203408F4203408F820120AFA2001006
-:104FD0008F8201243C040001248462043C05000902
-:104FE000AFA200148FA6002034A503000C002B3BB9
-:104FF000022038218F4202E024420001AF4202E049
-:105000008F4202E08F4202F024420001AF4202F0E0
-:105010008F4202F08FA200348FBF00588FBE005421
-:105020008FB500508FB3004C8FB200488FB1004451
-:105030008FB0004003E0000827BD006027BDFFF8E7
-:105040002408FFFF10A00014000048213C0AEDB81E
-:10505000354A83209087000024840001000030211D
-:1050600001071026304200011040000200081842DB
-:10507000006A18260060402124C600012CC20008E6
-:105080001440FFF700073842252900010125102BA5
-:105090001440FFF0000000000100102103E00008B0
-:1050A00027BD000827BDFFB0AFBF0048AFBE00441A
-:1050B000AFB50040AFB3003CAFB20038AFB1003481
-:1050C000AFB000308F870220AFA700248F87020087
-:1050D000AFA7002C8F8202203C0308FF3463FFFF40
-:1050E0000043102434420004AF8202208F82020069
-:1050F0003C03C0FF3463FFFF00431024344200042C
-:10510000AF8202008F5303588F55035C8F5E03609C
-:105110008F470364AFA700148F470368AFA7001C35
-:105120008F4202D0274401C024420001AF4202D086
-:105130008F5002D08F5102048F5202000C002BA816
-:1051400024050400AF530358AF55035CAF5E036002
-:105150008FA70014AF4703648FA7001CAF470368F5
-:10516000AF5002D0AF510204AF5202008C02025C79
-:1051700027440224AF4201F08C02026024050200A1
-:1051800024060008AF4201F8240200060C002BBFE1
-:10519000AF4201F43C023B9A3442CA00AF4201FCE8
-:1051A000240203E82404000224030001AF42029415
-:1051B000AF440290AF43029C8F820220304200082D
-:1051C0001040000400000000AF43029810000003EC
-:1051D00000003021AF440298000030213C03000160
-:1051E0000066182190636D000346102124C600015B
-:1051F000A043022C2CC2000F1440FFF803461821D4
-:1052000024C600018F820040240400802405008011
-:105210000002170224420030A062022C0346102133
-:105220000C002BA8A040022C8FA7002430E2000421
-:1052300014400006000000008F8202203C0308FF9B
-:105240003463FFFB00431024AF8202208FA7002CA1
-:1052500030E2000414400006000000008F820200CB
-:105260003C03C0FF3463FFFB00431024AF82020005
-:105270008FBF00488FBE00448FB500408FB3003C05
-:105280008FB200388FB100348FB0003003E00008D7
-:1052900027BD00500000000000000000AF400104E6
-:1052A00024040001000410C002E21821248200013D
-:1052B0003C01000100230821A42234D00040202119
-:1052C0002C8200801440FFF8000410C0240200016A
-:1052D0003C01000100370821A42038D0AF42010072
-:1052E000AF800228AF80022CAF800230AF80023442
-:1052F00003E000080000000027BDFFE8AFBF001476
-:10530000AFB000108F420104284200051040002673
-:10531000008080213C0200018F430104344230D0E0
-:1053200002E22021000318C00062182102E31821C4
-:105330000083102B1040001500001021960700007C
-:1053400024840006246600069482FFFC14470009AA
-:10535000000028219483FFFE9602000214620006DA
-:1053600000A0102194820000960300040043102640
-:105370002C45000100A010211440000924840008DD
-:105380000086102B1440FFF000001021304200FF77
-:1053900014400030240200011000002E00001021F3
-:1053A0001000FFFA24020001020020210C00240C4E
-:1053B000240500063042007F000218C002E31021DD
-:1053C0003C01000100220821942230D01040FFF25D
-:1053D00002E310213C06000100C2302194C630D007
-:1053E00010C0FFED3C080001350834D296070000DC
-:1053F000000610C000572021008820219482000060
-:10540000144700090000282194830002960200023C
-:105410001462000600A01021948200049603000488
-:10542000004310262C45000100A010211440000765
-:10543000000610C002E210213C06000100C230212B
-:1054400094C634D014C0FFEB000610C010C0FFD2C9
-:10545000240200018FBF00148FB0001003E0000889
-:1054600027BD001803E000080000000027BDFFB0C2
-:1054700000801021AFB00030245000020200202133
-:1054800024050006AFB1003400408821AFBF0048BA
-:10549000AFBE0044AFB50040AFB3003C0C00240CDD
-:1054A000AFB200383047007F000710C002E2102181
-:1054B0003C05000100A2282194A530D050A0001C7A
-:1054C00000A030213C090001352934D29628000281
-:1054D000000510C00057202100892021948200007F
-:1054E0001448000900003021948300029602000253
-:1054F0001462000600C01021948200049603000488
-:10550000004310262C46000100C010211440000763
-:10551000000510C002E210213C05000100A2282174
-:1055200094A534D014A0FFEB000510C000A03021DA
-:1055300010C00014000610C0005718213C010001E3
-:10554000002308218C2334D000571021AFA3001072
-:105550003C010001002208218C2234D43C040001CB
-:1055600024846394AFA200148E2600008E270004CA
-:105570003C0500040C002B3B34A504001000006324
-:105580003C0208008F45010010A00006000510C075
-:1055900002E210213C01000100220821942234D0B3
-:1055A000AF42010000A0302114C00011000628C045
-:1055B000000710C002E21021AFA700103C0100015B
-:1055C00000220821942230D03C040001248463A0EE
-:1055D000AFA200148E2600008E2700043C050004B4
-:1055E0000C002B3B34A50500100000483C020800CD
-:1055F00000B718213C02000196040000344234D266
-:1056000000621821A46400008E020002000720C07E
-:10561000AC62000202E410213C0300010062182188
-:10562000946330D002E510213C01000100220821E2
-:10563000A42334D002E410213C01000100220821FF
-:10564000A42630D08F420104244200012842008069
-:105650001040000F3C0200028F4201043C04000194
-:10566000348430D296030000000210C0005710218D
-:1056700000441021A44300008E030002AC4300024A
-:105680008F42010424420001AF4201043C020002A7
-:1056900002C2102410400011000721423C03000107
-:1056A000346338D824020003004410230002108021
-:1056B0000057202100832021005710210043102192
-:1056C00030E5001F8C4300002402000100A21004FA
-:1056D000006218251000000CAC83000024020003B7
-:1056E0000044102300021080005C2821005C10217F
-:1056F00030E4001F8C4302282402000100821004C1
-:1057000000621825ACA302283C02080034421000B5
-:1057100000001821AFA200208F5E001827AA0020E9
-:10572000240200FF13C20002AFAA002C27C300010D
-:105730008C020228006090211642000E001E38C024
-:105740008F42033C24420001AF42033C8F42033CA2
-:105750008C0202283C0400012484635C3C0500099F
-:10576000AFA00014AFA200108FA600201000006BA5
-:1057700034A5050000F710218FA300208FA400247A
-:10578000AC4304C0AC4404C48F8300548F820054E3
-:10579000247003E8020210232C4203E91040001B8E
-:1057A0000000982100E08821263504C08F4401784C
-:1057B0008F45017C02201821240A0004AFAA0010A2
-:1057C000AFB200148F48000C0000102102F5302108
-:1057D000AFA800188F48010C2407000800A3282157
-:1057E00000A3482B008220210100F8090089202114
-:1057F00054400006241300018F820054020210233B
-:105800002C4203E91440FFE900000000326200FF6F
-:1058100054400017AF5200188F4203782442000111
-:10582000AF4203788F4203788F8201208FAA002C29
-:10583000AFA200108F8201243C040001248463681D
-:105840003C050009AFA200148D4600001000003393
-:1058500034A506008F4203082413000124420001EE
-:10586000AF4203088F4203081000001C326200FFA1
-:105870008F8300548F820054247003E802021023A7
-:105880002C4203E91040001400009821241100105C
-:105890008F42000C8F4401608F4501648F86012088
-:1058A000AFB10010AFB20014AFA200188F42010CCC
-:1058B000240700080040F80924C6001C1440FFE536
-:1058C000000000008F820054020210232C4203E9E2
-:1058D0001440FFEF00000000326200FF144000118E
-:1058E000000000008F42037824420001AF42037899
-:1058F0008F4203788F8201208FAA002CAFA2001064
-:105900008F8201243C040001248463703C0500095B
-:10591000AFA200148D46000034A507000C002B3BFD
-:1059200003C038218F4202B424420001AF4202B4C6
-:105930008F4202B48F4202F424420001AF4202F4CB
-:105940008F4202F48FBF00488FBE00448FB50040E5
-:105950008FB3003C8FB200388FB100348FB000306D
-:1059600003E0000827BD005027BDFFA000801021E4
-:10597000AFB00040245000020200202124050006A0
-:10598000AFB1004400408821AFBF0058AFBE005403
-:10599000AFB50050AFB3004C0C00240CAFB20048C0
-:1059A0003048007F000810C002E210213C060001D0
-:1059B00000C2302194C630D010C0001C0000382135
-:1059C0003C0A0001354A34D296290002000610C074
-:1059D00000572021008A20219482000014490009E8
-:1059E000000028219483000296020002146200063F
-:1059F00000A01021948200049603000400431026A6
-:105A00002C45000100A0102114400008000610C021
-:105A100000C0382102E210213C06000100C2302102
-:105A200094C634D014C0FFEA000610C014C00011A0
-:105A3000AFA70028000810C002E21021AFA8001094
-:105A40003C01000100220821942230D03C040001D6
-:105A5000248463ACAFA200148E2600008E270004BD
-:105A60003C0500040C002B3B34A509001000007518
-:105A70003C02080010E0000C000610C002E21021F9
-:105A80003C03000100621821946334D0000710C069
-:105A900002E210213C01000100220821A42334D09D
-:105AA0001000000B3C04000102E210213C03000145
-:105AB00000621821946334D0000810C002E2102163
-:105AC0003C01000100220821A42330D03C04000145
-:105AD000348430D08F430100000610C002E2102150
-:105AE0003C01000100220821A42334D08F4201048C
-:105AF00002E438210000282118400029AF460100A7
-:105B000024E6000694C3FFFC96020000146200091C
-:105B10000000202194C3FFFE9602000214620006DA
-:105B20000080102194C20000960300040043102658
-:105B30002C440001008010215040001424A50001D5
-:105B40008F4201042442FFFF00A2102A1040000BE4
-:105B500024E40004948200068C830008A482FFFEE3
-:105B6000AC8300008F42010424A500012442FFFF02
-:105B700000A2102A1440FFF7248400088F42010479
-:105B80002442FFFF10000006AF4201048F420104CF
-:105B900024C6000800A2102A1440FFDA24E70008F7
-:105BA000000810C002E210213C010001002208217F
-:105BB000942230D0144000233C0208003C02000232
-:105BC00002C2102410400012000821423C030001D0
-:105BD000346338D8240200030044102300021080EC
-:105BE000005720210083202100571021004310215D
-:105BF0003105001F240300018C42000000A318049B
-:105C000000031827004310241000000DAC82000090
-:105C1000240200030044102300021080005C2821AD
-:105C2000005C10213104001F240300018C42022873
-:105C3000008318040003182700431024ACA2022894
-:105C40003C0208003442200000001821AFA20020CE
-:105C50008F5E001827AB0020240200FF13C2000251
-:105C6000AFAB003427C300018C02022800609021F2
-:105C70001642000E001E38C08F42033C2442000131
-:105C8000AF42033C8F42033C8C0202283C040001DB
-:105C90002484635C3C050009AFA00014AFA200108F
-:105CA0008FA600201000006B34A5050000F710211E
-:105CB0008FA300208FA40024AC4304C0AC4404C4D0
-:105CC0008F8300548F820054247003E80202102353
-:105CD0002C4203E91040001B0000982100E08821BD
-:105CE000263504C08F4401788F45017C022018219D
-:105CF000240B0004AFAB0010AFB200148F48000CAF
-:105D00000000102102F53021AFA800188F48010CC7
-:105D10002407000800A3282100A3482B008220218B
-:105D20000100F809008920215440000624130001D5
-:105D30008F820054020210232C4203E91440FFE931
-:105D400000000000326200FF54400017AF520018FC
-:105D50008F42037824420001AF4203788F420378D8
-:105D60008F8201208FAB0034AFA200108F820124FC
-:105D70003C040001248463683C050009AFA20014C0
-:105D80008D6600001000003334A506008F42030822
-:105D90002413000124420001AF4203088F4203088C
-:105DA0001000001C326200FF8F8300548F82005469
-:105DB000247003E8020210232C4203E9104000146F
-:105DC00000009821241100108F42000C8F440160C4
-:105DD0008F4501648F860120AFB10010AFB200146F
-:105DE000AFA200188F42010C240700080040F809F8
-:105DF00024C6001C1440FFE5000000008F82005400
-:105E0000020210232C4203E91440FFEF00000000BF
-:105E1000326200FF14400011000000008F4203783E
-:105E200024420001AF4203788F4203788F82012021
-:105E30008FAB0034AFA200108F8201243C0400011C
-:105E4000248463703C050009AFA200148D66000035
-:105E500034A507000C002B3B03C038218F4202B849
-:105E600024420001AF4202B88F4202B88F4202F4CE
-:105E700024420001AF4202F48F4202F48FBF005867
-:105E80008FBE00548FB500508FB3004C8FB20048C6
-:105E90008FB100448FB0004003E0000827BD0060D0
-:105EA00000000000000000000000000027BDFFE02F
-:105EB00027644000AFBF00180C002BA82405100079
-:105EC0003C03000134632CC03C04000134842EC820
-:105ED00024020020AF82011C02E31021AF800100E8
-:105EE000AF800104AF800108AF800110AF800114C2
-:105EF000AF800118AF800120AF800124AF8001285E
-:105F0000AF800130AF800134AF800138AF4200EC88
-:105F100002E31021AF4200F002E41021AF4200F48E
-:105F200002E41021AF4200F83C02000100571021AA
-:105F3000904240F41440001C3C0500018F82011C7B
-:105F40003C040001248464703C05000134420001DB
-:105F5000AF82011CAFA00010AFA000148F86011CFF
-:105F600034A501000C002B3B000038218C020218E4
-:105F70003042004010400014000000008F82011CDD
-:105F80003C0400012484647C3C050001344200048C
-:105F9000AF82011CAFA00010AFA000148F86011CBF
-:105FA0001000000734A502003C040001248464842E
-:105FB000AFA00010AFA000148F86011C34A5030011
-:105FC0000C002B3B000038218FBF001803E00008B5
-:105FD00027BD00208FA900108F83012C8FAA0014E9
-:105FE0008FAB00181060000A27624FE014620002B5
-:105FF00024680020276848008F82012811020004CD
-:10600000000000008F82012415020007000000003C
-:106010008F4303340000102124630001AF43033495
-:10602000100000398F430334AC640000AC650004F9
-:10603000AC660008A467000EAC690018AC6A001CCE
-:10604000AC6B0010AC620014AF8801208F4200FCE2
-:106050008F4400F42442FFFFAF4200FC8C8200001A
-:10606000104900053042FF8F104000193122FF8F88
-:10607000104000183C0200018C8300042C620010C8
-:10608000104000133C02000124630001AC830004B3
-:106090008F4300F8344230C802E2102154620004F9
-:1060A000246200083C02000134422EC802E21021A2
-:1060B00014440015240200018F820128244200208C
-:1060C000AF8201288F8201281000000F24020001F6
-:1060D0003C020001344230C802E210215482000424
-:1060E000248200083C02000134422EC802E2102142
-:1060F0000040202124020001AF4400F4AC890000DC
-:10610000AC8200042402000103E00008000000004B
-:1061100003E00008000000008FA900108F83010C2D
-:106120008FAA00148FAB00181060000A276247E0A6
-:106130001462000224680020276840008F82010852
-:1061400011020004000000008F8201041502000704
-:10615000000000008F430338000010212463000179
-:10616000AF430338100000358F430338AC640000A0
-:10617000AC650004AC660008A467000EAC690018AA
-:10618000AC6A001CAC6B0010AC620014AF8801005C
-:106190008F4400EC8C820000304200061040001951
-:1061A00031220006104000183C0200018C830004DC
-:1061B0002C620010104000133C0200012463000117
-:1061C000AC8300048F4300F034422EC002E2102161
-:1061D00054620004246200083C02000134422CC0D6
-:1061E00002E2102114440015240200018F820108EC
-:1061F00024420020AF8201088F8201081000000FA6
-:10620000240200013C02000134422EC002E21021AF
-:1062100054820004248200083C02000134422CC055
-:1062200002E210210040202124020001AF4400ECD2
-:10623000AC890000AC8200042402000103E00008E5
-:106240000000000003E000080000000027BDFFD8A8
-:106250003C0400012484648C3C050001AFBF002491
-:10626000AFB20020AFB1001CAFB000188F90010496
-:106270008F9100B08F92011C34A525008F82010000
-:106280000240302102203821AFA200100C002B3B2D
-:10629000AFB000148E020008AFA200108E02000CF6
-:1062A0003C04000124846498AFA200148E06000010
-:1062B0008E0700043C0500010C002B3B34A5251083
-:1062C0008E020018AFA200108E02001C3C040001D8
-:1062D000248464A4AFA200148E0600108E0700145C
-:1062E0003C0500010C002B3B34A525203C027F001F
-:1062F000022210243C030800544300163C03020011
-:106300008F82009C3042FFFF144000123C030200C9
-:106310003C040001248464B03C05000234A5F03044
-:10632000000030210000382136420002AF82011CFB
-:1063300036220001AF8200B0AF900104AF92011C81
-:10634000AFA000100C002B3BAFA0001410000024E5
-:106350000000000002C310241040000D022310248E
-:106360001040000B36420002AF82011C36220001B1
-:10637000AF8200B0AF900104AF92011C8F42033096
-:1063800024420001AF420330100000158F42033059
-:106390003C040001248464B8240202A9AFA20010C6
-:1063A000AFA000148F8601443C07000124E764C0BD
-:1063B0000C002B3B3405DEAD8F82011C3442000201
-:1063C000AF82011C8F82022034420004AF8202207F
-:1063D0008F8201403C03000100431025AF82014041
-:1063E0008FBF00248FB200208FB1001C8FB0001827
-:1063F00003E0000827BD002827BDFFD83C040001AA
-:10640000248464E83C050001AFBF0024AFB2002043
-:10641000AFB1001CAFB000188F9001248F9100A085
-:106420008F92011C34A526008F820120024030216A
-:1064300002203821AFA200100C002B3BAFB000149B
-:106440008E020008AFA200108E02000C3C04000176
-:10645000248464F4AFA200148E0600008E070004AA
-:106460003C0500010C002B3B34A526108E020018C1
-:10647000AFA200108E02001C3C04000124846500C1
-:10648000AFA200148E0600108E0700143C05000118
-:106490000C002B3B34A526203C027F000222102456
-:1064A0003C030800544300163C0302008F8200ACFA
-:1064B0003042FFFF144000123C0302003C04000184
-:1064C0002484650C3C05000134A5F0300000302127
-:1064D0000000382136420002AF82011C3622000142
-:1064E000AF8200A0AF900124AF92011CAFA00010BA
-:1064F0000C002B3BAFA00014100000240000000093
-:1065000002C310241040000D022310241040000B81
-:1065100036420002AF82011C36220001AF8200A089
-:10652000AF900124AF92011C8F42032C2442000142
-:10653000AF42032C100000158F42032C3C040001D5
-:10654000248464B8240202E2AFA20010AFA00014B9
-:106550008F8601443C07000124E764C00C002B3BFC
-:106560003405DEAD8F82011C34420002AF82011C73
-:106570008F82022034420004AF8202208F820140C9
-:106580003C03000100431025AF8201408FBF00246F
-:106590008FB200208FB1001C8FB0001803E00008FC
-:1065A00027BD00280000602100005021000030219C
-:1065B0000000282100006821000048210000782107
-:1065C000000070218F8801248F8701041580002E20
-:1065D0008F8B011C11A00014316208008F820120F2
-:1065E00010460029000000003C0400018C846EE489
-:1065F0008CC200008CC30004AC820000AC83000499
-:106600008CC20008AC82000894C2000EA482000E66
-:106610008CC20010240C0001AC8200108CC200144B
-:106620001000001224C600201040001700000000D7
-:106630003C0400018C846EE48D0200008D03000494
-:10664000AC820000AC8300048D020008AC8200081C
-:106650009502000EA482000E8D0200102506002077
-:10666000AC8200108D020014240C000100C018211F
-:10667000AC82001427624FE00043102B544000010D
-:1066800027634800006030211540002F316201006F
-:1066900011200014316280008F8201001045002A11
-:1066A000316201003C0400018C846EE08CA2000089
-:1066B0008CA30004AC820000AC8300048CA2000810
-:1066C000AC82000894A2000EA482000E8CA20010DE
-:1066D000240A0001AC8200108CA2001410000012E9
-:1066E00024A5002010400018316201003C04000184
-:1066F0008C846EE08CE200008CE30004AC8200002D
-:10670000AC8300048CE20008AC82000894E2000E26
-:10671000A482000E8CE2001024E50020AC82001060
-:106720008CE20014240A000100A01821AC8200149D
-:10673000276247E00043102B5440000127634000CC
-:1067400000602821316201005440001D31621000B8
-:1067500011A0000931A20800104000042502002009
-:106760008F8200A8A5E2000025020020AF8201244C
-:106770008F8801240000682111800011316210000F
-:106780003C0400018C846EE48C8200008C83000445
-:10679000AF820080AF8300848C820008AF8200A4A7
-:1067A0009482000EAF8200AC8C8200100000602149
-:1067B000AF8200A08C8D00108C8F0014316210000D
-:1067C0001440FF82000000001120000F3122080059
-:1067D000104000043C0200028F8200B8A5C20000F5
-:1067E0003C020002012210241040000424E2002098
-:1067F0008F8200B4AF8200D424E20020AF82010473
-:106800008F870104000048211140FF700000000044
-:106810003C0400018C846EE08C8200008C830004B8
-:10682000AF820090AF8300948C820008AF8200B4E6
-:106830009482000EAF82009C8C82001000005021D8
-:10684000AF8200B08C8900101000FF608C8E0014A5
-:1068500003E0000800000000000060210000582153
-:106860000000302100002821000068210000502194
-:1068700000007821000070218F8801248F87010497
-:106880003C1801001580002E8F89011C11A00014F6
-:10689000312208008F8201201046002900000000EC
-:1068A0003C0400018C846EE48CC200008CC30004A4
-:1068B000AC820000AC8300048CC20008AC820008EB
-:1068C00094C2000EA482000E8CC20010240C0001A1
-:1068D000AC8200108CC200141000001224C60020EC
-:1068E00010400017000000003C0400018C846EE49E
-:1068F0008D0200008D030004AC820000AC83000414
-:106900008D020008AC8200089502000EA482000EE1
-:106910008D02001025060020AC8200108D020014AC
-:10692000240C000100C01821AC82001427624FE043
-:106930000043102B544000012763480000603021C1
-:106940001560002F31220100114000143122800017
-:106950008F8201001045002A312201003C04000111
-:106960008C846EE08CA200008CA30004AC8200003A
-:10697000AC8300048CA20008AC82000894A2000E34
-:10698000A482000E8CA20010240B0001AC82001027
-:106990008CA200141000001224A500201040001842
-:1069A000312201003C0400018C846EE08CE2000086
-:1069B0008CE30004AC820000AC8300048CE200088D
-:1069C000AC82000894E2000EA482000E8CE200105B
-:1069D00024E50020AC8200108CE20014240B00019E
-:1069E00000A01821AC820014276247E00043102B5E
-:1069F000544000012763400000602821312201003B
-:106A00005440001D3122100011A0000931A20800DD
-:106A100010400004250200208F8200A8A5E200009B
-:106A200025020020AF8201248F8801240000682104
-:106A300011800011312210003C0400018C846EE4AE
-:106A40008C8200008C830004AF820080AF830084BE
-:106A50008C820008AF8200A49482000EAF8200AC4A
-:106A60008C82001000006021AF8200A08C8D00108D
-:106A70008C8F00143122100014400022000000000E
-:106A80001140000F31420800104000043C02000297
-:106A90008F8200B8A5C200003C020002014210240F
-:106AA0001040000424E200208F8200B4AF8200D4A2
-:106AB00024E20020AF8201048F87010400005021EE
-:106AC00011600010000000003C0400018C846EE0A6
-:106AD0008C8200008C830004AF820090AF8300940E
-:106AE0008C820008AF8200B49482000EAF82009CBA
-:106AF0008C82001000005821AF8200B08C8A0010F8
-:106B00008C8E00148F8200703C0310000043102410
-:106B10001040FF5C000000008F82005424420005FA
-:106B2000AF8200788C040234108000160000182117
-:106B30003C020001005710218C4240E8244200052D
-:106B40003C01000100370821AC2240E83C02000172
-:106B5000005710218C4240E80044102B14400009DB
-:106B6000240200013C0300803C01000100370821A1
-:106B7000AC2040E83C010001003708211000000C67
-:106B8000A02240F03C02000100571021904240F04A
-:106B9000144000063C0200803C0200010057102116
-:106BA000904240F1104000023C0200800062182533
-:106BB0008C04023010800013000000003C02000131
-:106BC000005710218C4240EC244200053C0100019A
-:106BD00000370821AC2240EC3C0200010057102194
-:106BE0008C4240EC0044102B1440000600000000D2
-:106BF0003C01000100370821AC2040EC10000006E9
-:106C0000007818253C02000100571021904240F204
-:106C100054400001007818251060FF1A00000000A1
-:106C20008F4200001040000700000000AF80004CC1
-:106C30008F82004C1040FFFD000000001000000596
-:106C400000000000AF8000488F8200481040FFFD28
-:106C5000000000008F82006000431025AF820060BA
-:106C60008F42000010400003000000001000FF05EC
-:106C7000AF80004C1000FF03AF80004803E0000825
-:106C80000000000000000000000000003C020001C5
-:106C90008C426D2827BDFFE8AFBF001414400012DE
-:106CA000AFB000103C10000126106F9002002021B0
-:106CB0000C002BA82405200026021FE03C01000147
-:106CC000AC226EEC3C010001AC226EE8AC0202503A
-:106CD00024022000AC100254AC020258240200012D
-:106CE0003C010001AC226D288FBF00148FB0001052
-:106CF00003E0000827BD00183C0900018D296EEC57
-:106D00008C8200008FA300108FA80014AD22000019
-:106D10008C820004AD250008AD2200048F8200544F
-:106D2000AD260010AD270014AD230018AD28001CBF
-:106D3000AD22000C2529FFE03C02000124426F90A7
-:106D40000122102B10400003000000003C0900014C
-:106D50008D296EE83C0200018C426D10AD220000CE
-:106D60003C0200018C426D103C010001AC296EEC2C
-:106D7000AD220004AC09025003E00008000000004E
-:106D800027BDFFD0AFB000103C1000018E106EEC9C
-:106D90003C0200018C426D10AFB1001400808821CC
-:106DA000AFBE00248FBE00408FA40048AFB20018D1
-:106DB00000A09021AFBF0028AFB50020AFB3001CEA
-:106DC000AE0200003C0200018C426D1000C0982110
-:106DD00000E0A82110800006AE020004260500088D
-:106DE0000C002BB324060018100000052610FFE04D
-:106DF000260400080C002BA8240500182610FFE02C
-:106E00003C03000124636F900203102B1040000329
-:106E1000000000003C1000018E106EE88E22000081
-:106E2000AE0200008E220004AE120008AE02000482
-:106E30008F820054AE130010AE150014AE1E001861
-:106E40008FA80044AE08001CAE02000C2610FFE024
-:106E50000203102B10400003000000003C10000152
-:106E60008E106EE83C0200018C426D10AE020000F4
-:106E70003C0200018C426D103C010001AC306EEC14
-:106E8000AE020004AC1002508FBF00288FBE002459
-:106E90008FB500208FB3001C8FB200188FB1001483
-:106EA0008FB0001003E0000827BD003000851821D6
-:106EB0000083102B1040000600000000AC80000092
-:106EC000248400040083102B5440FFFDAC8000009C
-:106ED00003E000080000000000A6182100A3102B0A
-:106EE00010400007000000008C820000ACA20000EF
-:106EF00024A5000400A3102B1440FFFB24840004ED
-:106F000003E0000800000000008618210083102B19
-:106F100010400007000000008CA20000AC820000BE
-:106F2000248400040083102B1440FFFB24A50004DC
-:106F300003E00008000000000006308000861821F1
-:106F40000083102B1040000600000000AC850000FC
-:106F5000248400040083102B5440FFFDAC85000006
-:106F600003E00008000000000000000026E5002803
-:106F700000A03021274301C08F4D03588F47035C89
-:106F80008F4803608F4903648F4A03688F4B020464
-:106F90008F4C0200246404000064102B1040000891
-:106FA0003C0208FF8CC20000AC62000024630004B5
-:106FB0000064102B1440FFFB24C600043C0208FFB1
-:106FC0003442FFFF3C03C0FFAF4D0358AF47035CA3
-:106FD000AF480360AF490364AF4A0368AF4B020494
-:106FE000AF4C02008F8402203463FFFF8F860200C3
-:106FF000008210243442000400C3182434630004C7
-:10700000AF820220AF8302008CA20214AC02008483
-:107010008CA20218AC0200888CA2021CAC02008C6C
-:107020008CA20220AC0200908CA20224AC0200943C
-:107030008CA20228AC0200988CA2022CAC02009C0C
-:107040008CA20230AC0200A08CA20234AC0200A4DC
-:107050008CA20238AC0200A88CA2023CAC0200ACAC
-:107060008CA20240AC0200B08CA20244AC0200B47C
-:107070008CA20248AC0200B88CA2024CAC0200BC4C
-:107080008CA2001CAC0200808CA20018AC0200C0D4
-:107090008CA20020AC0200CC8CA20024AC0200D058
-:1070A0008CA201D0AC0200E08CA201D4AC0200E4BE
-:1070B0008CA201D8AC0200E88CA201DCAC0200EC8E
-:1070C0008CA201E0AC0200F08CA200988CA3009C82
-:1070D000AC0300FC8CA200A88CA300ACAC0300F4B1
-:1070E0008CA200A08CA300A430840004AC0300F8A0
-:1070F0001480000730C200048F8202203C0308FF86
-:107100003463FFFB00431024AF82022030C200042E
-:1071100014400006000000008F8202003C03C0FF04
-:107120003463FFFB00431024AF8202008F4202DC75
-:10713000A34005C524420001AF4202DC8F4202DCBD
-:1071400003E000080000000027BDFFD8AFBF002407
-:10715000AFB000208F4300248F420020106200381F
-:10716000000000008F4300208F4200240062202393
-:1071700004810003000000008F42004000822021B3
-:107180008F4300308F4200240043102B1440000531
-:10719000000000008F4300408F42002410000005D3
-:1071A000006210238F4200308F43002400431023DD
-:1071B0002442FFFF00406021008C102A544000014F
-:1071C000008060218F4A00248F4900408F480024AE
-:1071D0008F4401808F4501848F4600248F4B001C13
-:1071E00024070001AFA7001000084100010018218A
-:1071F000014C50212529FFFF01498024AFB0001424
-:107200008F4700140000102100063100AFA70018BE
-:1072100000A3282100A3382B0082202100872021F1
-:107220008F420108016630210040F809000C390046
-:1072300054400001AF5000248F4300248F420020AF
-:1072400014620018000000008F4200001040000788
-:1072500000000000AF80004C8F82004C1040FFFD0A
-:10726000000000001000000500000000AF80004892
-:107270008F8200481040FFFD000000008F820060F8
-:107280002403FFEF00431024AF8200608F42000010
-:10729000104000030000000010000002AF80004C0E
-:1072A000AF8000488FBF00248FB0002003E00008AB
-:1072B00027BD002803E000080000000027BDFFC034
-:1072C00032C20020AFBF0038AFB30034AFB20030DD
-:1072D000AFB1002C10400004AFB000288F5300283D
-:1072E00010000002000000008F5300208F42003089
-:1072F000105300EB000211008F43001C006280213C
-:107300008E0400008E050004961200088F42009043
-:107310009611000A3246FFFF0046102A104000175F
-:10732000000000008F8200D88F4300980043102394
-:107330002442DCBEAF4200908F4200902842DCBF66
-:1073400010400005000000008F4200908F43014470
-:1073500000431021AF4200908F4200900046102A57
-:1073600010400006000000008F4203482442000144
-:10737000AF420348100000E18F4203488F8200FCB7
-:1073800014400006000000008F4203442442000124
-:10739000AF420344100000D98F420344934205C218
-:1073A0001040000B32C200081040000832220200D8
-:1073B000104000063C0340009602000EAF4300ACB4
-:1073C0000002140010000002AF4200B0AF4000AC59
-:1073D000322200041040007F3222080010400003D7
-:1073E0003247FFFF100000022402002024020004A4
-:1073F000AFA200108F420030AFA200148F420010E5
-:107400003C03000200431025AFA200188F460098ED
-:107410008F4201080040F80900000000104000B74A
-:10742000000000008F42009C8F4300940242102114
-:10743000AF42009CAE03000C8F4200AC104000082D
-:107440003C0340008F42009400431025AFA200206F
-:107450008F42009C8F4300B01000000400431025B1
-:107460008F420094AFA200208F42009CAFA2002464
-:107470008F8200FC8FA300208FA40024AC43000067
-:10748000AC44000424420008AF8200F08F42009C0C
-:107490008F4402708F4502740040182100001021B3
-:1074A00000A3282100A3302B008220210086202168
-:1074B0003223006024020040AF440270AF450274E2
-:1074C000106200172C6200411040000524020020C9
-:1074D00010620008240200011000002600000000D5
-:1074E0002402006010620019240200011000002133
-:1074F000000000008F4202788F43027C2463000169
-:107500002C64000100441021AF420278AF43027C9A
-:107510008F4202788F43027C100000162402000183
-:107520008F4202808F430284246300012C64000197
-:1075300000441021AF420280AF4302848F42028098
-:107540008F4302841000000B240200018F42028846
-:107550008F43028C246300012C640001004410213D
-:10756000AF420288AF43028C8F4202888F43028C65
-:1075700024020001A34205C28F4200983244FFFF5B
-:107580002406FFF88F45013C0044102124420007E7
-:107590000046102424840007AF4200948F420090DC
-:1075A0008F43009400862024004410230065182B8C
-:1075B00014600005AF4200908F4200948F43014455
-:1075C00000431023AF4200948F4200941000002328
-:1075D000AF40009C3247FFFF50E0002232C2002043
-:1075E000144000022402001024020002AFA2001086
-:1075F0008F420030AFA200148F420010AFA20018DB
-:107600008F4600988F4201080040F80900000000F2
-:107610001040003A3245FFFF8F4200988F430090A0
-:107620008F46013C00451021AF4200988F42009CDC
-:107630008F440098A34005C200651823AF43009013
-:10764000004510210086202B14800005AF42009CCD
-:107650008F4200988F43014400431023AF420098AB
-:1076600032C2002010400005000000008F42035885
-:107670002442FFFFAF4203588F4203588F4200302D
-:107680008F430040244200012463FFFF0043102485
-:10769000AF4200308F420030145300180000000049
-:1076A0008F4200001040000700000000AF80004C37
-:1076B0008F82004C1040FFFD00000000100000050C
-:1076C00000000000AF8000488F8200481040FFFD9E
-:1076D000000000008F8200602403FFF700431024A5
-:1076E000AF8200608F4200001040000300000000E5
-:1076F00010000002AF80004CAF8000488FBF003800
-:107700008FB300348FB200308FB1002C8FB00028BF
-:1077100003E0000827BD004003E00008000000006F
-:1077200027BDFFD032C20020AFBF002CAFB200286F
-:10773000AFB1002410400004AFB000208F520028E9
-:1077400010000002000000008F5200208F42003025
-:10775000105200B5000211008F43001C006280210E
-:107760008E0400008E050004961100088F420090E0
-:107770009607000A3226FFFF0046102A1040001725
-:10778000000000008F8200D88F4300980043102330
-:107790002442DC46AF4200908F4200902842DC47F2
-:1077A00010400005000000008F4200908F4301440C
-:1077B00000431021AF4200908F4200900046102AF3
-:1077C00010400006000000008F42034824420001E0
-:1077D000AF420348100000AB8F4203488F8600FC85
-:1077E00010C0000C000000008F8200F42403FFF89A
-:1077F0000043102400461023000218C35860000103
-:10780000246301008F42008C0043102B14400006BB
-:10781000000712C28F42034424420001AF420344D6
-:10782000100000988F420344934305C21060000F7C
-:10783000304600018F4200103448040032C2000874
-:107840001040000830E20200104000063C034000F7
-:107850009602000EAF4300AC0002140010000004BA
-:10786000AF4200B010000002AF4000AC8F480010E3
-:1078700030E20004104000453227FFFF8F4900AC82
-:107880001120000530C200FF144000062402004011
-:10789000100000042402000814400002240200200A
-:1078A00024020004AFA200108F4300301120000416
-:1078B000AFA300148F4200B000621025AFA20014E5
-:1078C0003C02000201021025AFA200188F4600986A
-:1078D0008F4201080040F8090000000010400069D4
-:1078E0003224FFFF8F42008C8F430094244200011A
-:1078F000AF42008C24020001AE03000CA34205C27B
-:107900008F4200982406FFF88F45013C0044102167
-:10791000244200070046102424840007AF4200944C
-:107920008F4200908F43009400862024004410234F
-:107930000065182B14600005AF4200908F42009440
-:107940008F43014400431023AF4200948F430094BF
-:107950008F4201400043102B10400009000000003E
-:107960008F43013C8F4400948F4200908F45013833
-:107970000064182300431023AF420090AF450094E9
-:107980008F4200941000001FAF42009810E0001DCD
-:1079900030C200FF14400002240200102402000242
-:1079A000AFA200108F420030AFA80018AFA20014A1
-:1079B0008F4600988F4201080040F809000000003F
-:1079C000104000303225FFFF8F4200988F44013C69
-:1079D00000451021AF4200988F4200908F430098DD
-:1079E000A34005C2004510230064182B1460000555
-:1079F000AF4200908F4200988F4301440043102310
-:107A0000AF4200988F4200308F4300402442000173
-:107A10002463FFFF00431024AF4200308F42003048
-:107A200014520018000000008F42000010400007B0
-:107A300000000000AF80004C8F82004C1040FFFD22
-:107A4000000000001000000500000000AF800048AA
-:107A50008F8200481040FFFD000000008F82006010
-:107A60002403FFF700431024AF8200608F42000020
-:107A7000104000030000000010000002AF80004C26
-:107A8000AF8000488FBF002C8FB200288FB1002438
-:107A90008FB0002003E0000827BD003003E000089D
-:107AA0000000000027BDFFD83C02000134422EC078
-:107AB000AFBF00208F4300F08F84010802E2102145
-:107AC00054620004246200083C02000134422CC0CD
-:107AD00002E2102100401821AF4300F0AC6000002A
-:107AE0008F4200EC8C660004146200043C0200012A
-:107AF000248200201000000FAF8201088F4300F0A5
-:107B000034422EC002E210215462000424620008B4
-:107B10003C02000134422CC002E210210040182136
-:107B20008C6200040002114000821021AF82010823
-:107B3000AC6000008C85001830A200361040006C4C
-:107B400030A200018C82001C8F4300408F4400341F
-:107B5000244200012463FFFF0043102400862021FB
-:107B6000AF42002C30A2003014400006AF44003475
-:107B70008F4200348C03023C0043102B144000B4AD
-:107B80000000000032C20010104000282407000846
-:107B90008F4401708F4501748F43002C8F48000C77
-:107BA0008F86012024020080AFA20010AFA3001432
-:107BB000AFA800188F42010C0040F80924C6001C31
-:107BC00014400011240200013C010001003708218B
-:107BD000A02240F18F820124AFA200108F820128E1
-:107BE0003C040001248467C4AFA200148F46002C1B
-:107BF0008F8701203C0500090C002B3B34A51100A8
-:107C000010000036000000008F4203008F43002C5C
-:107C100024420001AF4203008F420300240200010E
-:107C2000A34205C110000026AF4300388F44017005
-:107C30008F4501748F43002C8F48000C8F860120E4
-:107C400024020020AFA20010AFA30014AFA80018B8
-:107C50008F42010C0040F80924C6001C144000119A
-:107C6000240200013C01000100370821A02240F05D
-:107C70008F820124AFA200108F8201283C040001F2
-:107C8000248467B8AFA200148F46002C8F87012090
-:107C90003C0500090C002B3B34A509001000000F27
-:107CA000000000008F42030024420001AF420300A5
-:107CB0008F4203008F42002CA34005C1AF42003821
-:107CC0003C01000100370821A02040F13C010001E7
-:107CD00000370821A02040F0AF4000348F42031449
-:107CE00024420001AF420314100000598F420314D4
-:107CF0001040002230A270008C85001C8F420028AA
-:107D000000A2202304810003000000008F420040F5
-:107D1000008220218F4203588F430000AF45002886
-:107D20000044102110600007AF420358AF80004CA0
-:107D30008F82004C1040FFFD000000001000000585
-:107D400000000000AF8000488F8200481040FFFD17
-:107D5000000000008F82006034420008AF820060A3
-:107D60008F420000104000030000000010000038A7
-:107D7000AF80004C10000036AF8000481040002F4C
-:107D800030A210001040000C30A240008C83001C78
-:107D90008F420050006220230482000124840200EC
-:107DA0008F42035C00441021AF42035C8F420368A2
-:107DB0001000001AAF4300501040000C32C2800087
-:107DC0008C83001C8F42007000622023048200011B
-:107DD000248404008F42036400441021AF420364F2
-:107DE0008F4203681000000DAF4300701040000E7A
-:107DF0003C0208008C83001C8F420060006220233C
-:107E000004820001248401008F4203600044102199
-:107E1000AF4203608F420368AF430060004410210B
-:107E2000AF4203683C02080002C210245040000820
-:107E300036940040100000060000000030A201004F
-:107E400010400003000000000C002BD800000000D0
-:107E50008FBF002003E0000827BD002803E00008D2
-:107E60000000000027BDFFA8AFBF0050AFBE004C10
-:107E7000AFB50048AFB30044AFB20040AFB1003C73
-:107E8000AFB000388F91010826220020AF82010890
-:107E90008E3200180000A82132420024104001BA9E
-:107EA0000000F0218E26001C8F43001C00061100EC
-:107EB000006218218C70000C9604000C962D0016A0
-:107EC0009473000A2C8305DD388288702C420001EF
-:107ED00000621825106000150000282132C2004001
-:107EE00010400015240208009603001414620012CA
-:107EF0003402AAAA9603000E146200070000202193
-:107F00009603001024020300146200040080102174
-:107F1000960200122C4400010080102154400006FB
-:107F200024050016100000040000000024020800D0
-:107F3000508200012405000E934205C3144000083E
-:107F400000005821240B000132620180AF4500A8D7
-:107F5000AF5000A010400002AF4600A4A34B05C3E1
-:107F600010A0008502054021910200000000382188
-:107F70003042000F0002508032C200021040001256
-:107F8000010A1821326200021040001032C20001C2
-:107F900001002021948200002484000200E23821A4
-:107FA0000083102B1440FFFB30E2FFFF00071C0290
-:107FB0000062382100071C0230E2FFFF0062382116
-:107FC00000071027A502000A32C200011040006A13
-:107FD0003262000110400068000000008F4200A8DB
-:107FE00010400065000000008F4200A08F4300A8F1
-:107FF00000431021904C0009318900FF392300060D
-:108000000003182B392200110002102B00621824E3
-:108010001060000C3C0500068F4200A43C040001E7
-:10802000248467D4AFA200108F4200A034A546007C
-:10803000012038210C002B3BAFA200141000004E91
-:108040000000000032C20004144000130000282188
-:10805000316200FF1440000400000000950200029D
-:108060001000000D004A28239505000C9502000E13
-:108070009503001000A2282100A3282195030012D7
-:10808000910400099502000200A3282100A42821E0
-:10809000004A102300A2282102002021948200001F
-:1080A0002484000200E238210088102B1440FFFBDA
-:1080B00000071C0230E2FFFF0062382100071C02AB
-:1080C00030E2FFFF0062382101A5282100051C02D3
-:1080D00030A2FFFF0062282100051C0230A2FFFF32
-:1080E0000062282100A728230005140200A22821ED
-:1080F00030A5FFFF50A000013405FFFF316200FFF3
-:1081000014400008318300FF8F4300A08F4200A875
-:1081100000624021910200003042000F00025080B6
-:10812000318300FF2402000614620003010A1021BB
-:10813000100000022444001024440006316200FFB5
-:1081400014400006000000009482000000A22821D4
-:1081500000051C0230A2FFFF00622821934205C3E4
-:10816000104000033262010050400003A48500006B
-:1081700000052827A48500009622000E8F43009C4E
-:108180000062182132A200FF10400007AF43009C9C
-:108190003C02400002021025AFA200208F42009C4A
-:1081A00010000003005E1025AFB000208F42009C3D
-:1081B000AFA2002432620080104000103262010041
-:1081C0008F4200B424430001000210C00057102168
-:1081D000AF4300B48FA300208FA400243C01000112
-:1081E00000220821AC2338E83C01000100220821CC
-:1081F000AC2438EC100000A532C20020104000640E
-:10820000000000008F4200B424430001000210C0AF
-:1082100000571021AF4300B48FA300208FA4002487
-:108220003C01000100220821AC2338E83C01000198
-:1082300000220821AC2438EC8F4200B410400051D9
-:10824000000038213C090001352938E83C08001FAE
-:108250003508FFFF240BFFFF340AFFFF000710C0A3
-:1082600000571021004910218C4300008C44000469
-:10827000AFA30028AFA4002C8F8200FC8FA300289E
-:108280008FA4002CAC430000AC440004244200083E
-:10829000AF8200F08F42008C2442FFFFAF42008C7F
-:1082A00097A2002E8F4402708F450274004018215F
-:1082B0000000102100A3282100A3302B00822021E0
-:1082C00000862021AF440270AF4502748FA20028BF
-:1082D0000048102490430000306300011460000B3C
-:1082E000004020218F4202788F43027C24630001EA
-:1082F0002C64000100441021AF420278AF43027C9D
-:108300008F4202781000001A8F43027C8C8200009A
-:10831000144B000E0000000094820004144A000B6D
-:10832000000000008F4202888F43028C246300010A
-:108330002C64000100441021AF420288AF43028C3C
-:108340008F4202881000000A8F43028C8F42028005
-:108350008F430284246300012C6400010044102137
-:10836000AF420280AF4302848F4202808F43028477
-:108370008F4200B424E7000100E2102B1440FFB844
-:10838000000710C0A34005C31000003FAF4000B479
-:108390008F8200FC8FA300208FA40024AC43000038
-:1083A000AC44000424420008AF8200F08F42009CDD
-:1083B0008F46008C8F4402708F4502740040182154
-:1083C0000000102124C6FFFFAF46008C00A3282127
-:1083D00000A3302B0082202100862021AF440270B0
-:1083E000AF45027492020000304200011440000CBC
-:1083F0002402FFFF8F4202788F43027C2463000136
-:108400002C64000100441021AF420278AF43027C8B
-:108410008F4202788F43027C1000001C32C2002081
-:108420008E0300001462000F3402FFFF9603000465
-:108430001462000C000000008F4202888F43028CFF
-:10844000246300012C64000100441021AF42028823
-:10845000AF43028C8F4202888F43028C1000000BC6
-:1084600032C200208F4202808F43028424630001C5
-:108470002C64000100441021AF420280AF4302840B
-:108480008F4202808F43028432C2002010400005D8
-:10849000AF40009C8F4203582442FFFFAF42035875
-:1084A0008F4203588E22001C8F430040244200015B
-:1084B0002463FFFF00431024AF42002C32420060CF
-:1084C0001440000832C200108F42003424420001E0
-:1084D000AF4200348C03023C0043102B14400102D5
-:1084E00032C2001010400018240700088F440170A9
-:1084F0008F4501748F43002C8F48000C8F8601201C
-:1085000024020080AFA20010AFA30014AFA800188F
-:108510008F42010C0040F80924C6001C104000479F
-:10852000240200018F4203008F43002C24420001EB
-:10853000AF4203008F42030024020001A34205C1A1
-:108540001000007CAF4300388F4401708F450174E8
-:108550008F43002C8F48000C8F86012024020020BE
-:10856000AFA20010AFA30014AFA800188F42010CF7
-:108570000040F80924C6001C1040005724020001E6
-:10858000100000650000000032420012104000752B
-:10859000324200019622000E8F43009C0062182197
-:1085A00032C2002010400005AF43009C8F420358A8
-:1085B0002442FFFFAF4203588F4203588E22001C13
-:1085C0008F430040244200012463FFFF0043102436
-:1085D000AF42002C324200101440000832C200109A
-:1085E0008F42003424420001AF4200348C03023C2D
-:1085F0000043102B144000BC32C200101040002871
-:10860000240700088F4401708F4501748F43002CAC
-:108610008F48000C8F86012024020080AFA200103A
-:10862000AFA30014AFA800188F42010C0040F80956
-:1086300024C6001C14400011240200013C0100016A
-:1086400000370821A02240F18F820124AFA2001040
-:108650008F8201283C040001248467C4AFA2001467
-:108660008F46002C8F8701203C0500090C002B3B16
-:1086700034A5110010000036000000008F420300F6
-:108680008F43002C24420001AF4203008F420300BD
-:1086900024020001A34205C110000026AF430038A8
-:1086A0008F4401708F4501748F43002C8F48000C5C
-:1086B0008F86012024020020AFA20010AFA3001477
-:1086C000AFA800188F42010C0040F80924C6001C16
-:1086D00014400011240200013C0100010037082170
-:1086E000A02240F08F820124AFA200108F820128C7
-:1086F0003C040001248467B8AFA200148F46002C0C
-:108700008F8701203C0500090C002B3B34A5090094
-:108710001000000F000000008F42030024420001FF
-:10872000AF4203008F4203008F42002CA34005C1DB
-:10873000AF4200383C01000100370821A02040F181
-:108740003C01000100370821A02040F0AF40003478
-:108750008F42031424420001AF4203141000006250
-:108760008F42031410400022324270008E25001CFC
-:108770008F42002800A22023048100030000000093
-:108780008F420040008220218F4203588F43000017
-:10879000AF4500280044102110600007AF42035885
-:1087A000AF80004C8F82004C1040FFFD00000000A5
-:1087B0001000000500000000AF8000488F820048D4
-:1087C0001040FFFD000000008F820060344200086E
-:1087D000AF8200608F4200001040000300000000E4
-:1087E00010000041AF80004C1000003FAF800048F7
-:1087F0001040002F324210001040000C3242400066
-:108800008E23001C8F42005000622023048200014E
-:10881000248402008F42035C00441021AF42035CB9
-:108820008F4203681000001AAF4300501040000C44
-:1088300032C280008E23001C8F4200700062202311
-:1088400004820001248404008F4203640044102148
-:10885000AF4203648F4203681000000DAF43007005
-:108860001040000E3C0208008E23001C8F42006066
-:108870000062202304820001248401008F420360EF
-:1088800000441021AF4203608F420368AF43006091
-:1088900000441021AF4203683C02080002C21024C9
-:1088A00050400011369400401000000F00000000FE
-:1088B0003242004810400007241500018E22001C9F
-:1088C0003C03FFFF0043F0243042FFFF1000FD7522
-:1088D000AE22001C324201001040000300000000E4
-:1088E0000C002BD8000000008FBF00508FBE004C42
-:1088F0008FB500488FB300448FB200408FB1003C69
-:108900008FB0003803E0000827BD005803E00008DE
-:108910000000000000000000000000008F8300E461
-:108920008F8200E02404FFF8004410240062102627
-:108930000002102B0002102303E000080062102444
-:1089400003E000080000000027BDFFE0AFBF001CEF
-:10895000AFB000188F8600C48F8400E08F8500E4DC
-:108960002402FFF80082182410A3000927623FF8B0
-:1089700014A2000224A200082762300000408021D7
-:1089800016030005308200041040000400C02021BE
-:1089900010000022000010218E0400008F42011CF4
-:1089A00014A20003000000008F420120AF42011416
-:1089B0008CA300008F420148008318230043102B32
-:1089C00010400003000000008F420148006218219F
-:1089D00094A20006244200500062102B1440000FA5
-:1089E00000A01021AFA40010AFA300148CA60000BB
-:1089F0008CA700043C0400010C002B3B24846894E9
-:108A00008F42020C24420001AF42020C8F42020C42
-:108A100000001021AF9000E8AF9000E48FBF001C71
-:108A20008FB0001803E0000827BD002003E0000815
-:108A3000000000008F8400E08F8800C48F8300E86E
-:108A40002402FFF80082382400E320232C82100047
-:108A50005040000124841000000420C2008018212E
-:108A60008F4402588F45025C0000102100A328218A
-:108A700000A3302B0082202100862021AF44025821
-:108A8000AF45025C8F8300C88F4201480103202359
-:108A90000082102B14400004008018218F420148EE
-:108AA00000822021008018218F4402508F450254FB
-:108AB0000000102100A3282100A3302B00822021D8
-:108AC00000862021AF440250AF450254AF8800C851
-:108AD000AF8700E4AF8700E803E000080000000073
-:108AE00027BDFF30240A0001AFBF00C8AFBE00C4DD
-:108AF000AFB500C0AFB300BCAFB200B8AFB100B407
-:108B0000AFB000B0A3A00097AFA00044AFAA005C34
-:108B1000934205C4A7A0008E1040000AA7A00086BB
-:108B20008F4B00C4AFAB00648F4A00C0AFAA006C8B
-:108B30008F4B00CCAFAB00748F4A00C810000129E6
-:108B4000AFAA007C8F4201140040F8090000000029
-:108B50000040302110C0034F000000008CC2000014
-:108B60008CC30004AFA20020AFA300248FAB00246D
-:108B70008FAA00203162FFFF2442FFFCAFA2006CED
-:108B80003C02000602C21024AFAB007C144000156A
-:108B9000AFAA006491420000304200011040001171
-:108BA0002402FFFF8D430000146200043402FFFF23
-:108BB000954300041062000B000000000C0024BB71
-:108BC0008FA40064304200FF144000060000000043
-:108BD0008F4201180040F809000000001000032D2A
-:108BE000000000008FA200243C03FFBF3463FFFF9E
-:108BF000004310243C03FFFF0043182414600003CB
-:108C0000AFA2002410000040000018213C020080A8
-:108C10000062102410400007000000008F42038C07
-:108C200024420001AF42038C8F42038C10000036B7
-:108C3000240300018F42021024420001AF420210BF
-:108C40008F4202103C020001006210241040000616
-:108C50003C0200028F4201C424420001AF4201C421
-:108C60008F4201C43C020002006210241040000642
-:108C70003C0200048F42037C24420001AF42037C8B
-:108C80008F42037C3C020004006210241040000666
-:108C90003C0200088F42038024420001AF4203805F
-:108CA0008F4203803C02000800621024104000063E
-:108CB0003C0200108F42038424420001AF4203842F
-:108CC0008F4203843C020010006210241040000612
-:108CD0003C0200208F4201C024420001AF4201C08B
-:108CE0008F4201C03C0200200062102410400006A8
-:108CF000240300018F42038824420001AF4203880D
-:108D00008F420388240300018C0202608FAB006C49
-:108D1000004B102B10400014307000FF8F4201E810
-:108D200024420001AF4201E88F4201E88FAA007C93
-:108D30008F8200E0354A0100AFAA007CAFA200108C
-:108D40008F8200E4241000013C040001248468A008
-:108D5000AFA200148FA600208FA700243C050007B7
-:108D60000C002B3B34A50800120000103C020080D0
-:108D700002C210241440000E32C204008FAB007CEB
-:108D80003C020080344201000162102410400005C2
-:108D9000000000008F42020C24420001AF42020C8E
-:108DA0008F42020C100002B08FA3006C32C204008C
-:108DB00010400015340281008FAA00649543000C16
-:108DC000146200123C020100240B0200A7AB008ECB
-:108DD0009542000E8D4300088D4400048D4500002F
-:108DE0008FAA006C8FAB0064254AFFFCAFAA006C11
-:108DF000A7A20086AD63000CAD640008AD65000459
-:108E0000256B0004AFAB00643C02010002C21024D9
-:108E100010400004000000008FAA006C254A0004E6
-:108E2000AFAA006C8F4200BC5040000AAFA0007493
-:108E30008FAB006C004B102B50400006AFA00074AD
-:108E40008F4200BC01621023AFA200748F4A00BCA5
-:108E5000AFAA006C8F4200808FAB006C004B102BD0
-:108E60001040005632C280001040005E240A000309
-:108E700032C210001040005BAFAA005C1000005826
-:108E8000240B00048F4203502403FFBF0283A0245D
-:108E900024420001AF4203501000024F8F420350A2
-:108EA00002C2B0252402FFBF0282A0248F830128C2
-:108EB0003C040001248468D026620001AFA20014A3
-:108EC000AFA300108F8601208F8701243C05000787
-:108ED0000C002B3B34A522501000023F0000000084
-:108EE00002C2B0252402FFBF0282A0248F83012882
-:108EF0003C040001248468D024020002AFA20014C4
-:108F0000AFA300108F8601208F8701243C05000746
-:108F10000C002B3B34A524501000022F0000000051
-:108F20008EA200008EA300043C040001248468E8A3
-:108F3000AFB00010AFBE00148EA7001834A52800F3
-:108F40000C002B3B006030211000022300000000C9
-:108F5000A6B1000A8F8201243C040001248468F039
-:108F6000AFBE0014AFA200108F4600448F870120CF
-:108F70003C0500070C002B3B34A530001000021606
-:108F800000000000A6B1000AA6B2000E8F820124E4
-:108F90003C040001248468FCAFBE0014AFA20010A2
-:108FA0008F4600448F8701203C0500070C002B3BB7
-:108FB00034A5320010000208000000008F42008437
-:108FC0008FAA006C004A102B144000073C020001DD
-:108FD00002C210241040000400000000240B000214
-:108FE000AFAB005C8FAA006C1140021B27AB0020C6
-:108FF000AFAB00A43C0A001F354AFFFFAFAA009C9C
-:109000008FAB005C240A0001556A0021240A00028B
-:109010008F4300548F4200501062000B274B0054C6
-:109020008F5E00543403ECC0AFAB004C27C200018C
-:10903000304201FFAFA20054001E11400043102136
-:109040001000006B02E2A8218F4200448FAA006C3E
-:109050003C040001248468ACAFAA0014AFA2001045
-:109060008F4600548F4700503C0500070C002B3BF7
-:1090700034A513008F4303502402FFBF0282A024B3
-:1090800024630001AF430350100001D38F4203500B
-:10909000156A001D000000008F4300748F420070AD
-:1090A0001062000A274B00748F5E0074AFAB004C57
-:1090B00027C20001304203FFAFA20054001E11403E
-:1090C00024426CC01000004A02E2A8218F420044F2
-:1090D0008FAA006C3C040001248468B83C0500079A
-:1090E000AFAA0014AFA200108F4600748F47007023
-:1090F00034A51500240B00010C002B3BAFAB005C2A
-:109100001000FFC3000000008F4300648F42006026
-:109110001062001A274A00648F5E00648FAB005C07
-:10912000AFAA004C27C20001304200FFAFA200549A
-:10913000240200041562000E001E1140001E118062
-:1091400024420CC002E21021AFA200449442002A43
-:109150008FAA00448FAB006C004B102B10400024F2
-:1091600025550020240A000110000021A3AA009721
-:1091700024424CC01000001E02E2A8218F4200448D
-:109180008FAB006C3C040001248468C4AFAB0014B6
-:10919000AFA200108F4600648F4700603C050007B7
-:1091A0000C002B3B34A518003C02000802C210241E
-:1091B0001440FF34000000008F420370240A0001B5
-:1091C000AFAA005C24420001AF4203701000FF9080
-:1091D0008F42037027A3003600131040006218214D
-:1091E000946200000044102110000020A4620000DE
-:1091F0008FAB0064AEAB001893A2009710400072D2
-:10920000000098218FAA00448FA4006C8FA300A4B3
-:1092100025420020AFA2002825420008AFA200305E
-:1092200025420010AFAA002CAFA200349542002ABC
-:10923000A7A2003895420018A7A2003A9542001A4A
-:10924000A7A2003C9542001CA7A2003E9462001811
-:1092500024630002008220231880FFDE26730001B1
-:109260002E6200041440FFF9000000008F4200FC51
-:109270002665000100A2102A1440002B24030001DF
-:109280008F83012C10600023000000008F820124D6
-:109290000043102300022143588000012484004031
-:1092A0008F820128004310230002194358600001F7
-:1092B000246300400064102A544000010060202113
-:1092C000AF4400FC8F4200FC00A2102A10400011A5
-:1092D0002403000110000015306200FF8FAB006412
-:1092E00096070018AFAB00108E2200083C04000166
-:1092F000248468DC8C4300048C42000034A52400E4
-:10930000024030210C002B3BAFA300141000002BB7
-:10931000000000008F4203340000182124420001A5
-:10932000AF4203348F420334306200FF5040FEDC12
-:109330003C02080012600021000090218FB100A4BF
-:10934000022080218E220008960700188FA6006454
-:109350008C4400008C450004240A0001AFAA0010D0
-:10936000AFBE00148F420008AFA200188F42010C5C
-:109370000040F809000000001040FFD83C0500073D
-:10938000960200188FAB00648FAA009C01625821DE
-:10939000014B102B10400004AFAB00648F4201481A
-:1093A00001625823AFAB0064261000022652000170
-:1093B0000253102B1440FFE3263100048FB0006CE1
-:1093C0001000003697B100388F4200FC24050002DF
-:1093D00000A2102A1440001B240300018F83012CDB
-:1093E00010600013000000008F820124004310234E
-:1093F0000002214358800001248400408F8201280C
-:109400000043102300021943586000012463004008
-:109410000064102A5440000100602021AF4400FC89
-:109420008F4200FC00A2102A144000062403000111
-:109430008F4203340000182124420001AF4203345C
-:109440008F420334306200FF1040FEA53C0208004A
-:1094500096B1000A8FB0006C3223FFFF0070102B12
-:1094600054400001006080218EA400008EA50004FD
-:10947000240B0001AFAB0010AFBE00148F420008F8
-:109480008FA60064AFA200188F42010C0040F809BB
-:10949000020038211040FEA23C05000796A3000EF2
-:1094A00097AA008E1140000700609021934205C4E6
-:1094B000144000040000000097AB0086006A1825E5
-:1094C000A6AB00168FAA007C3C02FFFF01421024CD
-:1094D00010400003000A140234630400A6A2001422
-:1094E0008FAB006C560B0072A6A3000E3462000412
-:1094F000A6A2000E8FAA0074016A1021A6A2000A7B
-:109500008F4300448F4401A08F4501A434028000A2
-:10951000AFA200108F42004402A030212407002097
-:10952000AFA200148F42000C0003194000604821D4
-:10953000AFA200188F42010C0000402100A9282191
-:1095400000A9182B008820210040F8090083202161
-:109550005040FE7FA6B2000E8F420368AFA0006CA1
-:10956000A34005C42442FFFFAF4203688FAB005CF9
-:10957000240A00018F420368156A0006240A0002CB
-:109580008F42035C2442FFFFAF42035C1000000CDB
-:109590008F42035C156A0006000000008F420364DE
-:1095A0002442FFFFAF420364100000058F420364B2
-:1095B0008F4203602442FFFFAF4203608F4203608B
-:1095C0008FAA00548FAB004CAD6A00008F4200445C
-:1095D0008F4400888F430078244200010044102407
-:1095E00024630001AF420044AF4300788C02024084
-:1095F0000062182B14600075240700088F4401686E
-:109600008F45016C8F4300448F48000C8F860120EA
-:1096100024020040AFA20010AFA30014AFA80018AE
-:109620008F42010C0040F80924C6001C14400011B0
-:10963000240B00013C01000100370821A02B40F25F
-:109640008F820124AFA200108F8201283C04000108
-:109650002484688CAFA200148F4600448F870120B9
-:109660003C0500090C002B3B34A513001000000B37
-:10967000000000008F42030424420001AF420304B3
-:109680008F4203048F420044AF42007C3C01000142
-:1096900000370821A02040F2AF4000788F42031825
-:1096A00024420001AF420318100000488F42031803
-:1096B000A6B0000A8F4300448F4401A08F4501A447
-:1096C00034028000AFA200108F42004402A030217B
-:1096D00024070020AFA200148F42000C00031940A1
-:1096E00000604821AFA200188F42010C0000402109
-:1096F00000A9282100A9182B008820210040F80982
-:10970000008320211040FE1F240A0001A34A05C443
-:109710008FAB006C8FAA006401705823AFAB006C54
-:109720008FAB009C01505021016A102B10400004A7
-:10973000AFAA00648F42014801425023AFAA0064DF
-:109740008F4203682442FFFFAF4203688FAA005C88
-:10975000240B00018F420368154B0006240B000206
-:109760008F42035C2442FFFFAF42035C1000000CF9
-:109770008F42035C114B0006000000008F42036023
-:109780002442FFFFAF420360100000058F420360D8
-:109790008F4203642442FFFFAF4203648F4203649D
-:1097A0008FAB00548FAA004CAD4B00008F42004499
-:1097B0008F4400888F430078244200010044102425
-:1097C00024630001AF420044AF4300788FAA006CCD
-:1097D0001540FE0B000000008FAB006C1160001EF6
-:1097E00000000000934205C4104000090000000082
-:1097F0008FAA0064AF4A00C4AF4B00C08FAB007C9F
-:10980000AF4B00C88FAA00741000000EAF4A00CC06
-:1098100097AB008E1160000B340381008FA20020F3
-:109820008C46000CA443000C97AA00868C440004CC
-:109830008C450008A44A000EAC440000AC4500046E
-:10984000AC4600088F42034C24420001AF42034C57
-:10985000100000108F42034C8FAB007C3164FFFF7F
-:109860002484FFFC008018218F4402508F4502544D
-:109870008F4601180000102100A3282100A3382BD7
-:109880000082202100872021AF44025000C0F80947
-:10989000AF4502548FBF00C88FBE00C48FB500C053
-:1098A0008FB300BC8FB200B88FB100B48FB000B0DE
-:1098B00003E0000827BD00D003E00008000000001E
-:1098C00027BDFF38240B0001AFBF00C0AFBE00BCF6
-:1098D000AFB500B8AFB300B4AFB200B0AFB100AC39
-:1098E000AFB000A8A3A00087AFA00044AFAB005C5E
-:1098F000934205C4A7A0007610400007A7A0007EF1
-:109900008F4C00C0AFAC00648F4B00C88F5E00C4AA
-:1099100010000130AFAB006C8F4201140040F80919
-:10992000000000000040302110C002A10000000033
-:109930008CC200008CC30004AFA20020AFA300249F
-:109940008FAC00248FBE00203182FFFF2442FFFC39
-:10995000AFA200643C02000602C2102414400015AD
-:10996000AFAC006C93C20000304200011040001107
-:109970002402FFFF8FC30000146200043402FFFFC3
-:1099800097C300041062000B000000000C0024BB11
-:1099900003C02021304200FF1440000600000000F8
-:1099A0008F4201180040F8090000000010000280FA
-:1099B000000000008FA200243C03FFBF3463FFFFC0
-:1099C000004310243C03FFFF0043182414600003ED
-:1099D000AFA2002410000040000080213C02008063
-:1099E0000062102410400007000000008F42038C2A
-:1099F00024420001AF42038C8F42038C10000036DA
-:109A0000241000018F42021024420001AF420210D4
-:109A10008F4202103C020001006210241040000638
-:109A20003C0200028F4201C424420001AF4201C443
-:109A30008F4201C43C020002006210241040000664
-:109A40003C0200048F42037C24420001AF42037CAD
-:109A50008F42037C3C020004006210241040000688
-:109A60003C0200088F42038024420001AF42038081
-:109A70008F4203803C020008006210241040000660
-:109A80003C0200108F42038424420001AF42038451
-:109A90008F4203843C020010006210241040000634
-:109AA0003C0200208F4201C024420001AF4201C0AD
-:109AB0008F4201C03C0200200062102410400006CA
-:109AC000241000018F42038824420001AF42038822
-:109AD0008F420388241000018C0202608FAB006467
-:109AE000004B102B10400015320200FF8F4201E89E
-:109AF00024420001AF4201E88F4201E88FAC006CC4
-:109B00008F8200E0358C0100AFAC006CAFA200107A
-:109B10008F8200E4241000013C040001248468A02A
-:109B2000AFA200148FA600208FA700243C050007D9
-:109B30000C002B3B34A53600320200FF1040001011
-:109B40003C02008002C210241440000E32C2040005
-:109B50008FAB006C3C020080344201000162102493
-:109B600010400005000000008F42020C244200015A
-:109B7000AF42020C8F42020C100002028FA300645D
-:109B800032C20400104000123402810097C3000C5E
-:109B90001462000F00000000240C0200A7AC007645
-:109BA00097C2000E8FC300088FC400048FAB0064FF
-:109BB0008FC50000256BFFFCAFAB0064A7A2007E41
-:109BC000AFC3000CAFC40008AFC5000427DE00041B
-:109BD0008FA70064320200FF144000343C020100F1
-:109BE00097C4000C2C8305DD388288702C4200015C
-:109BF00000621825106000150000282132C20800FC
-:109C0000104000152402080097C3001414620012CB
-:109C10003402AAAA97C3000E146200070000202194
-:109C200097C3001024020300146200040080102176
-:109C300097C200122C4400010080102154400006FD
-:109C40002405001610000004000000002402080093
-:109C5000508200012405000E10A0001303C520212E
-:109C6000248300093C02001F3442FFFF0043102BF5
-:109C700010400003000000008F42014800621823DA
-:109C800090620000384300062C6300013842001146
-:109C90002C42000100621825106000043C02010003
-:109CA00094820002004538213C02010002C21024C7
-:109CB0005040000EAFA700648FAC006410EC0008A9
-:109CC0003C0500073C040001248469088FA6006459
-:109CD00034A54000AFA000100C002B3BAFA0001437
-:109CE0008FAB0064256B0004AFAB00648F42008033
-:109CF0008FAC0064004C102B1040002C32C280004E
-:109D000010400034240B000332C210001040003118
-:109D1000AFAB005C1000002E240C00048F420350F7
-:109D20002403FFBF0283A02424420001AF4203505A
-:109D3000100001738F4203503C02080002C2B0259C
-:109D40002402FFBF0282A0248F8301283C0400016B
-:109D5000248468D026620001AFA20014AFA30010D3
-:109D60008F8601208F8701243C0500070C002B3BC8
-:109D700034A5530010000162000000008EA2000014
-:109D80008EA300043C040001248468E8AFB00010F6
-:109D9000AFB100148EA7001834A559000C002B3B5E
-:109DA0000060302110000156000000008F42008446
-:109DB0008FAB0064004B102B144000073C020001E5
-:109DC00002C210241040000400000000240C000215
-:109DD000AFAC005C8FAB00641160016627AC002063
-:109DE000AFAC008C8FAB005C240C0001556C0021E3
-:109DF000240C00028F4300548F4200501062000B6D
-:109E0000274B00548F5100543403ECC0AFAB004CCF
-:109E100026220001304201FFAFA200540011114080
-:109E2000004310211000006B02E2A8218F42004481
-:109E30008FAC00643C040001248468ACAFAC001417
-:109E4000AFA200108F4600548F4700503C0500071A
-:109E50000C002B3B34A543008F4303502402FFBF6B
-:109E60000282A02424630001AF43035010000124A8
-:109E70008F420350156C001D000000008F430074DA
-:109E80008F4200701062000A274B00748F510074DB
-:109E9000AFAB004C26220001304203FFAFA20054BA
-:109EA0000011114024426CC01000004A02E2A821B7
-:109EB0008F4200448FAC00643C040001248468B8E5
-:109EC0003C050007AFAC0014AFA200108F46007431
-:109ED0008F47007034A54500240B00010C002B3B7C
-:109EE000AFAB005C1000FFC3000000008F430064B4
-:109EF0008F4200601062001A274C00648F5100648A
-:109F00008FAB005CAFAC004C26220001304200FF5A
-:109F1000AFA20054240200041562000E001111408B
-:109F20000011118024420CC002E21021AFA20044B3
-:109F30009442002A8FAC00448FAB0064004B102B7E
-:109F40001040002425950020240C00011000002161
-:109F5000A3AC008724424CC01000001E02E2A821DE
-:109F60008F4200448FAB00643C040001248468C429
-:109F7000AFAB0014AFA200108F4600648F470060A3
-:109F80003C0500070C002B3B34A548003C020008B0
-:109F900002C210241440FF61000000008F420370D1
-:109FA000240C0001AFAC005C24420001AF420370FE
-:109FB0001000FF908F42037027A30036001310405B
-:109FC0000062182194620000004410211000001F5C
-:109FD000A4620000AEBE001893A200871040008467
-:109FE000000098218FAB00448FA400648FA3008CE5
-:109FF00025620020AFA2002825620008AFA2003031
-:10A0000025620010AFAB002CAFA200349562002A8D
-:10A01000A7A2003895620018A7A2003A9562001A1C
-:10A02000A7A2003C9562001CA7A2003E9462001803
-:10A0300024630002008220231880FFDF26730001C2
-:10A040002E6200041440FFF9000000008F4200FC63
-:10A050000262102A14400030240300018F83012C77
-:10A0600010600028000000008F82012400431023AC
-:10A070000002214358800001248400408F8201287F
-:10A08000004310230002194358600001246300407C
-:10A090000064102A5440000100602021AF4400FCFD
-:10A0A0008F4200FC0262102A1040001624030001B7
-:10A0B0001000001A306200FF8FAC008C00101040BE
-:10A0C000004C10219447001800101080004C102103
-:10A0D000AFBE00108C4200083C040001248468DC00
-:10A0E0003C0500078C4300048C42000034A5550059
-:10A0F000020030210C002B3BAFA3001410000039EC
-:10A10000000000008F4203340000182124420001A7
-:10A11000AF4203348F420334306200FF1040FF0629
-:10A12000000080218F4300082402FBFF1260002DF5
-:10A13000006250243C0B4000022B40258FB1008C64
-:10A140002669FFFF022090218E4200089627001802
-:10A150008C4400008C45000456090004240B0001C7
-:10A16000240C000210000002AFAC0010AFAB0010D6
-:10A1700016000004AFA800148F420008100000026F
-:10A18000AFA20018AFAA00188F42010C03C0302103
-:10A19000AFA80098AFA9009C0040F809AFAA00A0A2
-:10A1A0008FA800988FA9009C8FAA00A01040FFC222
-:10A1B0003C02001F962300183442FFFF03C3F02126
-:10A1C000005E102B10400003263100028F42014830
-:10A1D00003C2F023261000010213102B1440FFDAF3
-:10A1E000265200048FB000641000001A0000000026
-:10A1F00096A3000A8FB000640070102B5440000139
-:10A20000006080218EA400008EA500048FAB005C4E
-:10A21000240C0002AFAC0010934305C4000B1700E0
-:10A2200010600003022230253C02080000C23025E5
-:10A23000AFA600148F420008AFA200188F42010C95
-:10A2400003C030210040F809020038211040FECB45
-:10A250003C05000797AC00761180000796A3000E1E
-:10A26000934205C4144000040000000097AB007E38
-:10A27000006C1825A6AB00168FAC006C3C02FFFFEB
-:10A280000182102410400003000C14023463040007
-:10A29000A6A20014A6B0000A8FAB0064560B0006FD
-:10A2A00003D0F02134620004AFA00064A6A2000E27
-:10A2B0001000000DA34005C48FAC00643C02001FD9
-:10A2C0003442FFFF005E102B01906023AFAC0064AE
-:10A2D000A6A3000E240B000110400003A34B05C4ED
-:10A2E0008F42014803C2F0238FAB00548FAC004C67
-:10A2F000AD8B00008FAC00641580FEBA000000003A
-:10A300008FAB00641160001B00000000934205C485
-:10A310001040000600000000AF5E00C4AF4B00C05C
-:10A320008FAC006C1000000EAF4C00C897AB0076ED
-:10A330001160000B340381008FA200208C46000CBA
-:10A34000A443000C97AC007E8C4400048C450008AC
-:10A35000A44C000EAC440000AC450004AC46000820
-:10A360008F42034C24420001AF42034C1000001006
-:10A370008F42034C8FAB006C3164FFFF2484FFFCE1
-:10A38000008018218F4402508F4502548F460118D7
-:10A390000000102100A3282100A3382B00822021D7
-:10A3A00000872021AF44025000C0F809AF45025495
-:10A3B0008FBF00C08FBE00BC8FB500B88FB300B494
-:10A3C0008FB200B08FB100AC8FB000A803E00008DE
-:10A3D00027BD00C803E000080000000027BDFFD82B
-:10A3E000AFBF0024AFB000208F43004C8F42004825
-:10A3F00010620034000000008F4300488F42004C80
-:10A400000062202304820001248402008F43005450
-:10A410008F42004C0043102B144000042402020021
-:10A420008F43004C10000005004310238F4200545E
-:10A430008F43004C004310232442FFFF0040502173
-:10A44000008A102A54400001008050218F49004C9E
-:10A450008F48004C8F4401888F45018C8F46004CFB
-:10A4600024071000AFA70010000841400100182188
-:10A47000012A4821313001FFAFB000148F4700148A
-:10A480000000102100063140AFA7001800A32821CA
-:10A4900000A3382B00822021008720213402ECC049
-:10A4A00000C230218F42010802E630210040F80945
-:10A4B000000A394054400001AF50004C8F43004C1B
-:10A4C0008F42004814620018000000008F42000014
-:10A4D0001040000700000000AF80004C8F82004C4D
-:10A4E0001040FFFD0000000010000005000000000B
-:10A4F000AF8000488F8200481040FFFD0000000040
-:10A500008F8200602403FDFF00431024AF820060AF
-:10A510008F42000010400003000000001000000205
-:10A52000AF80004CAF8000488FBF00248FB0002068
-:10A5300003E0000827BD002803E000080000000039
-:10A5400027BDFFD8AFBF0024AFB000208F43005C11
-:10A550008F42005810620049000000008F430058ED
-:10A560008F42005C006220230482000124840100E9
-:10A570008F4300648F42005C0043102B14400004A2
-:10A58000240201008F43005C1000000500431023EB
-:10A590008F4200648F43005C004310232442FFFF7E
-:10A5A000004038210087102A5440000100803821E3
-:10A5B0008F42005C00471021305000FF32C2100073
-:10A5C00010400015240820008F49005C8F44019042
-:10A5D0008F4501948F46005C00073980AFA80010BA
-:10A5E000AFB000148F4800140009498001201821E1
-:10A5F0000000102100A3282100A3482B0082202165
-:10A600000089202100063180AFA800188F42010880
-:10A610001000001424C60CC08F49005C8F440190C8
-:10A620008F4501948F46005C00073940AFA80010A9
-:10A63000AFB000148F4800140009494001201821D0
-:10A640000000102100A3282100A3482B0082202114
-:10A650000089202100063140AFA800188F42010870
-:10A6600024C64CC00040F80902E6302154400001E5
-:10A67000AF50005C8F43005C8F420058146200189A
-:10A68000000000008F4200001040000700000000A2
-:10A69000AF80004C8F82004C1040FFFD0000000096
-:10A6A0001000000500000000AF8000488F820048C5
-:10A6B0001040FFFD000000008F8200602403FEFFB9
-:10A6C00000431024AF8200608F420000104000035E
-:10A6D0000000000010000002AF80004CAF80004876
-:10A6E0008FBF00248FB0002003E0000827BD0028A2
-:10A6F00003E000080000000027BDFFD8AFBF002422
-:10A70000AFB000208F43006C8F42006810620033AE
-:10A71000000000008F4300688F42006C006220231D
-:10A7200004820001248404008F4300748F42006C73
-:10A730000043102B14400004240204008F43006CDB
-:10A7400010000005004310238F4200748F43006CFB
-:10A75000004310232442FFFF00405021008A102AAA
-:10A7600054400001008050218F49006C8F48006CDC
-:10A770008F4401988F45019C8F46006C2407400050
-:10A78000AFA700100008414001001821012A48210C
-:10A79000313003FFAFB000148F47001400001021C8
-:10A7A0000006314024C66CC0AFA7001800A32821C2
-:10A7B00000A3382B00822021008720218F4201082E
-:10A7C00002E630210040F809000A394054400001F7
-:10A7D000AF50006C8F43006C8F4200681462001809
-:10A7E000000000008F420000104000070000000041
-:10A7F000AF80004C8F82004C1040FFFD0000000035
-:10A800001000000500000000AF8000488F82004863
-:10A810001040FFFD000000008F8200602403F7FF5E
-:10A8200000431024AF8200608F42000010400003FC
-:10A830000000000010000002AF80004CAF80004814
-:10A840008FBF00248FB0002003E0000827BD002840
-:10A8500003E00008000000008F4200FC3C03000100
-:10A860008F4400F8346330C824420001AF4200FC3A
-:10A870008F85012802E310215482000424820008FD
-:10A880003C02000134422EC802E21021004018218F
-:10A89000AF4300F8AC6000008F4200F41462000483
-:10A8A0003C02000124A200201000000FAF8201280A
-:10A8B0008F4300F8344230C802E210215462000491
-:10A8C000246200083C02000134422EC802E210213A
-:10A8D000004018218C6200040002114000A21021E7
-:10A8E000AF820128AC6000008CA3001830620070B9
-:10A8F0001040002D30620020104000043C02001087
-:10A9000002C210241040000D000000003062004020
-:10A91000104000043C02002002C210241040000736
-:10A9200000000000306200101040001F3C02004098
-:10A9300002C210241440001C000000008F8200405E
-:10A940003042000114400008000020218C03010463
-:10A950002402000150620005240400018C020264FC
-:10A960001040000300801021240400010080102109
-:10A9700010400006000000008F42030C244200013A
-:10A98000AF42030C100000088F42030C8F8200447A
-:10A9900034420004AF8200448F4203082442000185
-:10A9A000AF4203088F42030803E0000800000000E4
-:10A9B00003E000080000000027BDFF98AFBF006063
-:10A9C000AFBE005CAFB50058AFB30054AFB200509B
-:10A9D000AFB1004CAFB000488F4200FC24420001F0
-:10A9E000AF4200FC8F88012825020020AF82012899
-:10A9F0008D030018306200701040002E306200207D
-:10AA0000104000043C02001002C210241040000D4F
-:10AA10000000000030620040104000043C020020B2
-:10AA200002C2102410400007000000003062001035
-:10AA3000104001A93C02004002C21024144001A6AB
-:10AA4000000000008F8200403042000114400008E6
-:10AA5000000020218C030104240200015062000543
-:10AA6000240400018C0202641040000300801021C5
-:10AA700024040001008010211040000600000000A6
-:10AA80008F42030C24420001AF42030C10000192DC
-:10AA90008F42030C8F82004434420004AF82004492
-:10AAA0008F42030824420001AF4203081000018ACC
-:10AAB0008F420308306200021040014B3C02080044
-:10AAC0008D1E001C001E5702AFAA0034950A001606
-:10AAD00003C22024AFAA00248FAA0034240200015C
-:10AAE0001542000633DEFFFF001E11403403ECC0A8
-:10AAF000004310211000001002E2A82124020002ED
-:10AB00001542000524020003001E114024426CC0BF
-:10AB10001000000902E2A82115420005001E118064
-:10AB2000001E114024424CC01000000302E2A82184
-:10AB30000057102124550CE096A2000E304AFFFC6D
-:10AB40003042040010400003AFAA002C100000E1C6
-:10AB500000008821108000040000882197B10026A1
-:10AB6000100000DDA6B100128EB30018966A000C2A
-:10AB7000A7AA003E97A5003E2CA305DD38A2887049
-:10AB80002C420001006218251060001500002021F1
-:10AB900032C2080010400015240208009663001419
-:10ABA000146200123402AAAA9663000E146200070F
-:10ABB00000002821966300102402030014620004A0
-:10ABC00000A01021966200122C45000100A0102167
-:10ABD0005440000624040016100000040000000089
-:10ABE0002402080050A200012404000E108000B9C5
-:10ABF00002649021924200003042000F00028080E7
-:10AC000032C2010010400020025018213C020020F6
-:10AC10000043102B1440000E024020210000282188
-:10AC2000948200002484000200A228210083102BBB
-:10AC30001440FFFB30A2FFFF00051C020062282128
-:10AC400000051C0230A2FFFF10000009006228214D
-:10AC50008F4701488F420110001028423C06002017
-:10AC60000040F809AFA800403045FFFF8FA8004022
-:10AC700050A000013405FFFF8FAA002C354A0002C6
-:10AC800010000002AFAA002C0000282132C2008070
-:10AC900010400090A6A50010264300093C02001FAA
-:10ACA0003442FFFF0043102B10400003000000005F
-:10ACB0008F420148006218239066000030C200FFF6
-:10ACC000384300062C630001384200112C42000179
-:10ACD000006218251060007F24020800000088210F
-:10ACE00097A3003E1462000F0260202196710000BD
-:10ACF0009662000296630004966400060222882190
-:10AD00000223882102248821966200089663000AA3
-:10AD10009664000C0222882102238821100000077B
-:10AD200002248821948200002484000202228821C7
-:10AD30000092102B1440FFFB0000000000111C02C9
-:10AD40003222FFFF0062882100111C023222FFFF25
-:10AD50000062882132C2020010400003264400062F
-:10AD60001000003E000080213C05001F34A5FFFFBD
-:10AD700000A4102B10400003000000008F42014887
-:10AD8000008220239482000030421FFF1040000404
-:10AD90002644000C96420002100000300050802330
-:10ADA0009642000226430014005080233C020020FB
-:10ADB0000043102B1440000A00D080219642000C62
-:10ADC000020280219642000E964300109644001223
-:10ADD0000202802102038021100000200204802151
-:10ADE00000A4102B10400003000000008F42014817
-:10ADF0000082202394820000248400020202802129
-:10AE000000A4102B10400003000000008F420148F6
-:10AE10000082202394820000248400020202802108
-:10AE200000A4102B10400003000000008F420148D6
-:10AE300000822023948200002484000202028021E8
-:10AE400000A4102B10400003000000008F420148B6
-:10AE50000082202394820000020280213C02010033
-:10AE600002C210241040000E000000008FAA002C27
-:10AE7000314200041040000A000000009504000E5A
-:10AE8000026420210C003EEC2484FFFC3042FFFFD2
-:10AE90000222882100111C023222FFFF0062882159
-:10AEA0008FAA002401518823001114020222882154
-:10AEB0000230882100111402022288213231FFFF62
-:10AEC000522000013411FFFF8FAA002C354A0001E7
-:10AED000AFAA002CA6B1001297AA002EA6AA000EB7
-:10AEE0008FAA002C314200041040000224091000F7
-:10AEF000340980008F4800448F4401A08F4501A48D
-:10AF0000AFA900108F4900440008414001001821FA
-:10AF1000AFA900148F48000C02A0302124070020A4
-:10AF2000AFA800188F48010C0000102100A32821B1
-:10AF300000A3482B008220210100F809008920216C
-:10AF40001440000B000000008F8201283C04000127
-:10AF500024846914AFBE0014AFA200108F860124B0
-:10AF60008F8701203C0500070C002B3B34A599205E
-:10AF70008F4203682442FFFFAF4203688F420044C0
-:10AF80008F4300882442000100431024AF42004454
-:10AF90008FAA00348F440368240200011542000682
-:10AFA000240200028F42035C2442FFFFAF42035C95
-:10AFB000100000498F42035C1542000600000000AB
-:10AFC0008F4203642442FFFFAF420364100000423B
-:10AFD0008F4203648F4203602442FFFFAF4203604D
-:10AFE0001000003D8F4203603062100010400005E9
-:10AFF000306280008F420078244200011000003649
-:10B00000AF42007810400034000000008F4200780A
-:10B0100024420001AF4200788C0302400043102B11
-:10B020001440002D240700088F4401688F45016CEF
-:10B030008F4300448F48000C8F860120240200407B
-:10B04000AFA20010AFA30014AFA800188F42010CEC
-:10B050000040F80924C6001C14400011240200011D
-:10B060003C01000100370821A02240F28F82012418
-:10B07000AFA200108F8201283C0400012484688C58
-:10B08000AFA200148F4600448F8701203C050009C1
-:10B090000C002B3B34A513001000000B0000000037
-:10B0A0008F42030424420001AF4203048F42030491
-:10B0B0008F420044AF42007C3C0100010037082170
-:10B0C000A02040F2AF4000788F42031824420001D4
-:10B0D000AF4203188F4203188FBF00608FBE005C21
-:10B0E0008FB500588FB300548FB200508FB1004C11
-:10B0F0008FB0004803E0000827BD006803E00008A7
-:10B100000000000000000000000000008F42013C31
-:10B11000AF8200C08F42013CAF8200C48F42013C2D
-:10B12000AF8200C88F420138AF8200D08F42013811
-:10B13000AF8200D48F42013803E00008AF8200D80C
-:10B1400027BDFFE02784020824050200AFBF0018D6
-:10B150000C002BBF240600088C0202040C004012D5
-:10B16000AF8202103C0200018C426D94304200021A
-:10B170001040000E000020218C060248240200022C
-:10B180003C010001AC226D980C0051042405000222
-:10B19000000020218C060248240200013C0100012D
-:10B1A000AC226D9810000011240500018C060248A5
-:10B1B000240200043C010001AC226D980C005104F3
-:10B1C000240500043C0200018C426D9430420001D1
-:10B1D00010400008240200013C010001AC226D98DF
-:10B1E00000002021240500013C06601B0C005104D6
-:10B1F000000000003C040001248469D08F4201500B
-:10B200008F4301543C0500088F4601580002164048
-:10B21000000319403463040300431025000633C0C3
-:10B2200000461025AF82021CAFA00010AFA0001492
-:10B230008F86021C34A502000C002B3B0000382135
-:10B240003C010001AC206D903C010001AC206DA8D8
-:10B250008FBF001803E0000827BD002027BDFFE0D6
-:10B260003C05000834A50300AFBF0018AFA00010D4
-:10B27000AFA000148F8602003C040001248469DC26
-:10B280000C002B3B000038218F42041024420001A7
-:10B29000AF4204108F4204108FBF001803E0000873
-:10B2A00027BD002027BDFFD8AFBF0020AFB1001CD5
-:10B2B000AFB000188F4203A424420001AF4203A4A0
-:10B2C0008F4203A48F9002208F8200E0AFA2001073
-:10B2D0008F8200E4AFA200148F8600C48F8700C85D
-:10B2E0003C040001248469E80C002B3B0200282167
-:10B2F0003C04400002041024504000B43C0401000F
-:10B300008F4203BC24420001AF4203BC8F4203BC06
-:10B310008F8700C48F8300C88F42014800671823BD
-:10B320000043102B10400003000000008F42014832
-:10B330000062182110600005000000008F42014CDF
-:10B340000043102B1040000B000000008F8200E033
-:10B350008F430124AF42011CAF4301148F820220AE
-:10B360003C0308FF3463FFFB00431024100000CEB1
-:10B37000004410258F8202203C0308FF3463FFFF46
-:10B380000043102434420004AF8202208F8200E088
-:10B390008F430124AF42011CAF4301148F8600C8C4
-:10B3A0008F8401208F8301241000000500002821D4
-:10B3B0001462000224620020276248000040182125
-:10B3C0001064000C30A200FF8C62001830420003B1
-:10B3D0001040FFF727624FE08F4203D024050001A1
-:10B3E00024420001AF4203D08F4203D08C66000894
-:10B3F00030A200FF1440005800000000934205C432
-:10B4000014400055000000008F8700C48F8800E0C2
-:10B410008F8400E42402FFF8010240240104102379
-:10B42000000218C3046200012463020010600005DA
-:10B430002402000110620009000000001000001F3B
-:10B44000000000008F4203C000E0302124420001D0
-:10B45000AF4203C0100000408F4203C08F4203C4BC
-:10B4600024420001AF4203C48C8600008F42014891
-:10B470008F4303C400E618230043102B1040000440
-:10B480002C62233F8F420148006218212C62233F27
-:10B4900014400031000000008F42020C24420001E1
-:10B4A000AF42020C8F42020C00E0302124820008DF
-:10B4B000AF8200E410000028AF8200E88F4203C88A
-:10B4C00024420001AF4203C88F4203C88C850000AC
-:10B4D0008F42014800A718230043102B104000039F
-:10B4E000000000008F420148006218218F42014C89
-:10B4F0000043102B5440000A00A030218F42020C60
-:10B5000024420001AF42020C8F42020C2482000848
-:10B51000AF8200E48F8400E41488FFECAF8400E87D
-:10B520001488000D27623000148200022482FFF884
-:10B5300027623FF8944300063C02001F3442FFFF9D
-:10B5400000C330210046102B104000030000000013
-:10B550008F42014800C23023AF8600C88F8300C4E9
-:10B560008F42014800C318230043102B10400003F2
-:10B57000000000008F4201480062182110600005A1
-:10B58000000000008F42014C0043102B5040000887
-:10B590003C02FDFF8F8202203C0308FF3463FFFB67
-:10B5A000004310243C0340001000003F00431025DE
-:10B5B0008F4303CC3442FFFF0282A02424630001A6
-:10B5C000AF4303CC100000398F4203CC0204102497
-:10B5D0001040000E3C1102008F4203A824420001DB
-:10B5E000AF4203A88F4203A88F8202203C0308FFCA
-:10B5F0003463FFFF00431024004410250C003DAFCE
-:10B60000AF82022010000029000000000211102467
-:10B61000504000083C1104008F4203AC244200015A
-:10B62000AF4203AC0C003DAF8F4203AC10000019D9
-:10B6300000000000021110241040001C0000000057
-:10B640008F83022424021402146200093C050008BE
-:10B650003C040001248469F4AFA00010AFA00014E2
-:10B660008F86022434A505000C002B3B00003821F6
-:10B670008F4203B024420001AF4203B08F4203B0B7
-:10B680008F82022002002021344200020C004E9CD6
-:10B69000AF8202208F8202203C0308FF3463FFFF49
-:10B6A0000043102400511025AF8202208FBF0020DC
-:10B6B0008FB1001C8FB0001803E0000827BD0028E0
-:10B6C00003E00008000000003C0200018C426DA86D
-:10B6D00027BDFFB0AFBF0048AFBE0044AFB50040CC
-:10B6E000AFB3003CAFB20038AFB100341040000F30
-:10B6F000AFB000303C04000124846A003C0500081F
-:10B70000AFA00010AFA000148F86022034A5060061
-:10B71000240200013C010001AC206DA83C010001A5
-:10B72000AC226D9C0C002B3B000038213C037FFFBA
-:10B730008C0202683463FFFF3C04FDFF00431024C9
-:10B74000AC0202688F4200043484FFFF30420002E2
-:10B75000104000920284A0243C040600348420009F
-:10B760008F420004000028212403FFFD0043102421
-:10B77000AF420004AFA400208F5E001827AA00206B
-:10B78000240200FF13C20002AFAA002C27C500014B
-:10B790008C02022800A090211642000E001E38C024
-:10B7A0008F42033C24420001AF42033C8F42033CE2
-:10B7B0008C0202283C040001248469983C0500099D
-:10B7C000AFA00014AFA200108FA600201000006DE3
-:10B7D00034A5050000F710218FA300208FA40024BA
-:10B7E000AC4304C0AC4404C48F8300548F82005423
-:10B7F000247003E8020210232C4203E91040001BCE
-:10B800000000982100E08821263504C08F4401788B
-:10B810008F45017C02201821240A0004AFAA0010E1
-:10B82000AFB200148F48000C0000102102F5302147
-:10B83000AFA800188F48010C2407000800A3282196
-:10B8400000A3482B008220210100F8090089202153
-:10B8500054400006241300018F820054020210237A
-:10B860002C4203E91440FFE900000000326200FFAF
-:10B8700054400017AF5200188F4203782442000151
-:10B88000AF4203788F4203788F8201208FAA002C69
-:10B89000AFA200108F8201243C040001248469A41B
-:10B8A0003C050009AFA200148D46000010000035D1
-:10B8B00034A506008F42030824130001244200012E
-:10B8C000AF4203088F4203081000001E326200FFDF
-:10B8D0008F8300548F820054247003E802021023E7
-:10B8E0002C4203E910400016000098213C1500206E
-:10B8F000241100108F42000C8F4401608F450164B9
-:10B900008F860120AFB10010AFB200140055102592
-:10B91000AFA200188F42010C240700080040F8096C
-:10B9200024C6001C1440FFE3000000008F82005476
-:10B93000020210232C4203E91440FFEE0000000035
-:10B94000326200FF14400011000000008F420378B3
-:10B9500024420001AF4203788F4203788F82012096
-:10B960008FAA002CAFA200108F8201243C0400019A
-:10B97000248469AC3C050009AFA200148D46000088
-:10B9800034A507000C002B3B03C038218F4202EC8A
-:10B9900024420001AF4202EC8F4202EC8FBF00480C
-:10B9A0008FBE00448FB500408FB3003C8FB200388B
-:10B9B0008FB100348FB0003003E0000827BD005085
-:10B9C0003C0200018C426DA827BDFFE01440000D31
-:10B9D000AFBF00183C04000124846A0C3C05000839
-:10B9E000AFA00010AFA000148F86022034A507007E
-:10B9F000240200013C010001AC226DA80C002B3B8D
-:10BA0000000038213C02000402C21024104000074C
-:10BA1000000000008F8202203C0308FF3463FFFF18
-:10BA20000043102434420008AF8202203C0500018C
-:10BA30008CA56D982402000114A2000700002021AB
-:10BA40000C00529B24050001AC02026C8C03026CBA
-:10BA5000100000063C0200070C00529B0000202151
-:10BA6000AC0202688C0302683C02000700621824E2
-:10BA70003C0200025062000D3C0205F50043102B11
-:10BA8000144000063C0200043C0200011062000960
-:10BA90003C0200981000000B000000001462000936
-:10BAA0003C023B9A100000043442CA00100000021D
-:10BAB0003442E10034429680AF4201FC8F4201FCE7
-:10BAC000AEE200648FBF001803E0000827BD00202D
-:10BAD0000000000000000000000000000086102BA5
-:10BAE000504000010087202300C410230002484377
-:10BAF0000125102B1040001B00091040008240213E
-:10BB00000088102B104000070000182194820000CC
-:10BB100024840002006218210088102B1440FFFBCF
-:10BB2000000000000060202100C7302300A910237E
-:10BB30000002104000C2282100C5102B1040000751
-:10BB40000000182194C2000024C6000200621821DF
-:10BB500000C5102B1440FFFB000000001000000D7A
-:10BB60000083202100051040008228210085102B31
-:10BB70001040000700001821948200002484000275
-:10BB8000006218210085102B1440FFFB000000000C
-:10BB90000060202100041C023082FFFF006220218F
-:10BBA00000041C023082FFFF0062202103E0000835
-:10BBB0003082FFFF03E00008000000000080282121
-:10BBC00030A200011040002B3C03001F3463FFFF34
-:10BBD00024A200040062102B544000070065102BC3
-:10BBE00090A2000190A4000390A3000090A5000281
-:10BBF0001000002A00441021104000030000000043
-:10BC00008F42014800A2282390A4000024A500012F
-:10BC10000065102B10400003000000008F42014817
-:10BC200000A2282390A2000024A500010002120017
-:10BC3000008220210065102B10400003000000004E
-:10BC40008F42014800A2282390A2000024A50001F1
-:10BC5000008220210065102B10400003000000002E
-:10BC60008F42014800A2282390A200001000002D5E
-:10BC7000000212003463FFFF24A200040062102BB4
-:10BC80005440000A0065102B90A2000090A400020E
-:10BC900090A3000190A500030044102100021200AF
-:10BCA00000651821100000200043202110400003EF
-:10BCB000000000008F42014800A2282390A200004B
-:10BCC00024A50001000222000065102B1040000393
-:10BCD000000000008F42014800A2282390A200002B
-:10BCE00024A50001008220210065102B10400003D4
-:10BCF000000000008F42014800A2282390A200000B
-:10BD000024A5000100021200008220210065102BF2
-:10BD100010400003000000008F42014800A22823C9
-:10BD200090A200000082202100041C023082FFFF4C
-:10BD30000062202100041C023082FFFF00622021EB
-:10BD400003E000083082FFFF000000008F82022025
-:10BD500034420002AF8202203C0200028C428FF883
-:10BD60003042400010400054240400018F82020041
-:10BD700024067FFF8F830200304500022402FFFD6E
-:10BD800000621824AF830200AF8402048F83005442
-:10BD90008F82005410000002246300018F8200543F
-:10BDA000006210232C4200021440FFFC000000003F
-:10BDB0008F8202241444004D0004204000C4102B44
-:10BDC0001040FFF1000000008F82020000451025A6
-:10BDD000AF8202008F82022034428000AF820220B4
-:10BDE0008F8300548F8200541000000224630001EE
-:10BDF0008F820054006210232C4200021440FFFC8A
-:10BE0000000000008F8202203C0300040043102445
-:10BE10001440000F000000008F8202203C03FFFF4F
-:10BE200034637FFF00431024AF8202208F830054CD
-:10BE30008F82005410000002246300018F8200549E
-:10BE4000006210232C4200021440FFFC000000009E
-:10BE50008F8202203C030004004310241440000D94
-:10BE6000000000008F82022034428000AF82022056
-:10BE70008F8300548F82005410000002246300015D
-:10BE80008F820054006210232C4200021440FFFCF9
-:10BE9000000000008F8202203C03000400431024B5
-:10BEA0001040001B000010218F830220240200019B
-:10BEB000100000153C04F7008F8202203C04F700BC
-:10BEC00000441025AF8202208F8202202403FFFD50
-:10BED00000431024AF8202208F8202203C03030023
-:10BEE000004310241440000300000000100000086C
-:10BEF000000010218F82022034420002AF82022013
-:10BF00008F8302202402000100641825AF830220E1
-:10BF100003E0000800000000000020213C050100B3
-:10BF200024020001AF80021CAF820200AF82022017
-:10BF300027625000AF8200C027625000AF8200C469
-:10BF400027625000AF8200C827625000AF8200D045
-:10BF500027625000AF8200D427625000AF8200D821
-:10BF600027623000AF8200E027623000AF8200E439
-:10BF700027623000AF8200E827622800AF8200F01D
-:10BF800027622800AF8200F427622800AF8200F801
-:10BF9000000418C02484000103631021AC45300460
-:10BFA00003631021AC403000288202001440FFF9E6
-:10BFB000000418C000002021000418C024840001DF
-:10BFC00003631021AC40280403631021AC40280017
-:10BFD000288201001440FFF9000418C0AF80023C21
-:10BFE0002403008024040100AC60000024630004EA
-:10BFF0000064102B5440FFFDAC6000008F830040B4
-:10C000003C02F000006218243C0250001062000C58
-:10C010000043102B144000063C0260003C0240002C
-:10C020001062000824020800100000080000000050
-:10C030001062000424020800100000040000000048
-:10C04000240207003C010001AC226DAC03E00008B3
-:10C05000000000003C0200018C426DBC27BDFFD0F7
-:10C06000AFBF002CAFB20028AFB10024AFB00020AA
-:10C070003C01000110400005AC206D940C004D9E69
-:10C08000000000003C010001AC206DBC8F83005417
-:10C090008F82005410000002246300648F820054D9
-:10C0A000006210232C4200651440FFFC00000000D9
-:10C0B0000C004DB9000000002404000100002821FC
-:10C0C00027A60018340280000C0045BEA7A2001865
-:10C0D0008F8300548F820054100000022463006498
-:10C0E0008F820054006210232C4200651440FFFC34
-:10C0F00024040001240500010C00457C27A600183B
-:10C100008F8300548F820054100000022463006467
-:10C110008F820054006210232C4200651440FFFC03
-:10C1200024040001240500010C00457C27A600180A
-:10C130008F8300548F820054100000022463006437
-:10C140008F820054006210232C4200651440FFFCD3
-:10C15000240400013C06000124C66F240C00457C29
-:10C16000240500028F8300548F82005410000002C7
-:10C17000246300648F820054006210232C42006507
-:10C180001440FFFC24040001240500033C100001BE
-:10C1900026106F260C00457C0200302197A600185F
-:10C1A0003C07000194E76F243C04000124846AE00A
-:10C1B000AFA00014960200003C05000D34A501005C
-:10C1C0000C002B3BAFA2001097A200181040004DAE
-:10C1D00024036040960200003042FFF01443000C3C
-:10C1E000240200203C03000194636F241462000BBE
-:10C1F00024027830240200033C010001AC226D943B
-:10C20000240200053C0100011000003FAC226F3405
-:10C210003C03000194636F24240278301462000C04
-:10C22000240300103C02000194426F263042FFF0CC
-:10C2300014430007240200033C010001AC226D946A
-:10C24000240200063C0100011000002FAC226F34D4
-:10C250003C0200018C426D943C03000194636F2406
-:10C26000344200013C010001AC226D94240200150F
-:10C270001462000B000000003C02000194426F2693
-:10C280003042FFF03843F4202C6300013842F43090
-:10C290002C420001006218251460001B24020003D8
-:10C2A0003C03000194636F2424027810146200168A
-:10C2B000240200023C02000194426F263042FFF04B
-:10C2C00014400011240200021000000F2402000498
-:10C2D0003C0200018C426D94344200083C01000194
-:10C2E000AC226D941000005E240200043C020001A8
-:10C2F0008C426D94344200043C010001100000AFF8
-:10C30000AC226D94240200013C010001AC226F407C
-:10C310003C0200018C426D9430420002144000B295
-:10C320003C09FFF024020E00AF8202388F840054D3
-:10C330008F820054240300083C010001AC236D9857
-:10C3400010000002248401F48F8200540082102324
-:10C350002C4201F51440FFFC3C0200C8344201FBB2
-:10C36000AF8202388F8300548F8200541000000285
-:10C37000246301F48F820054006210232C4201F5E3
-:10C380001440FFFC00008021241200012411000948
-:10C390000C004482000000003C010001AC326DB48E
-:10C3A0000C004547000000003C0200018C426DB4C7
-:10C3B0001451FFFB3C0200C8344201F6AF82023840
-:10C3C0008F8300548F820054100000022463000AFF
-:10C3D0008F820054006210232C42000B1440FFFC9B
-:10C3E000000000008F820220240400013442000279
-:10C3F000AF8202208F83020024057FFF2402FFFD0D
-:10C4000000621824AF830200AF8402048F830054BB
-:10C410008F82005410000002246300018F820054B8
-:10C42000006210232C4200021440FFFC00000000B8
-:10C430008F8202241444000534028000000420404E
-:10C4400000A4102B1040FFF0340280001082FFA0E7
-:10C45000261000012E0200141440FFCD2402000417
-:10C460003C010001AC226D980000802124120009DB
-:10C470003C11FFFF36313F7F0C004482000000007A
-:10C48000240200013C010001AC226DB40C004547C0
-:10C49000000000003C0200018C426DB41452FFFB0E
-:10C4A000000000008F82004400511024344250806C
-:10C4B000AF8200448F8300548F820054100000022A
-:10C4C0002463000A8F820054006210232C42000B68
-:10C4D0001440FFFC000000008F8200440051102433
-:10C4E0003442F080AF8200448F8300548F82005426
-:10C4F000100000022463000A8F820054006210239F
-:10C500002C42000B1440FFFC000000008F82022030
-:10C510003C03F70000431025AF8202208F830054B4
-:10C520008F82005410000002246300648F82005444
-:10C53000006210232C4200651440FFFC0000000044
-:10C540008F8202202404000134420002AF820220C4
-:10C550008F83020024057FFF2402FFFD0062182460
-:10C56000AF830200AF8402048F8300548F82005493
-:10C5700010000002246300018F8200540062102327
-:10C580002C4200021440FFFC000000008F820224B5
-:10C5900014440005340280000004204000A4102B45
-:10C5A0001040FFF0340280001082FF50261000017E
-:10C5B0002E0200641440FFB0000000003C020001A5
-:10C5C0008C426D9430420004144000073C09FFF097
-:10C5D0008F8200443C03FFFF34633F7F00431024FD
-:10C5E000AF8200443C09FFF03529BDC03C06000184
-:10C5F0008CC66D943C04000124846AE0240200018E
-:10C600003C010001AC226D9C8F8200543C0700016C
-:10C610008CE76F403C03000194636F243C080001E9
-:10C6200095086F263C05000D34A501003C01000172
-:10C63000AC206D98004910213C010001AC226F3004
-:10C64000AFA300100C002B3BAFA800148FBF002C31
-:10C650008FB200288FB100248FB0002003E00008C3
-:10C6600027BD003027BDFFE83C0500018CA56D9873
-:10C67000240600042402000114A20014AFBF00101D
-:10C680003C0200028C428FFC3042800010400005CA
-:10C690003C04000F3C0300018C636F401000000558
-:10C6A000348442403C0400043C0300018C636F402E
-:10C6B000348493E024020005146200160000000098
-:10C6C0003C04003D10000013348409003C020002C9
-:10C6D0008C428FF830428000104000053C04001E60
-:10C6E0003C0300018C636F4010000005348484809B
-:10C6F0003C04000F3C0300018C636F4034844240D3
-:10C700002402000514620003000000003C04007ACB
-:10C71000348412003C0200018C426F308F8300543D
-:10C7200000441021004310230044102B1440004CFF
-:10C73000000000003C0200018C426DA01440004843
-:10C74000000000003C01000110C00025AC206DB0CD
-:10C750003C0900018D296D94240700013C04400030
-:10C760003C08000225088FFC250AFFFC0005284232
-:10C7700014A0000224C6FFFF2405000800A910240D
-:10C78000104000100000000014A700080000000086
-:10C790008D020000004410241040000A0000000038
-:10C7A0003C01000110000007AC256DB08D42000077
-:10C7B0000044102410400003000000003C01000170
-:10C7C000AC276DB03C0200018C426DB00006182B06
-:10C7D0002C420001004310245440FFE5000528428C
-:10C7E0008F8200543C0300018C636DB03C0100015A
-:10C7F000AC226F301060003B240200053C030001B6
-:10C800008C636F403C010001AC256D9814620012EE
-:10C81000240200013C0200028C428FF83C032000FD
-:10C820003463500000431024144000062402000129
-:10C830003C010001AC206F1C3C010001AC226D9852
-:10C84000240200013C010001AC226E243C010001E5
-:10C85000AC226DA4240200013C010001AC226D9CBD
-:10C860003C0200018C426DB01040001E0000000030
-:10C870003C0200018C426D9C104000082402000123
-:10C880003C010001AC206D9CAEE204B83C0100010B
-:10C89000AC206E1C3C010001AC226DD48EE304B8C8
-:10C8A0002402000810620005240200010C00423935
-:10C8B000000000001000000B000000003C0300011D
-:10C8C0008C636D98106200072402000E3C03000286
-:10C8D0008C638F9010620003000000000C004E9CDF
-:10C8E0008F8402208FBF001003E0000827BD0018CE
-:10C8F00027BDFFE03C03FDFF3C0400018C846D98E4
-:10C900003C0200018C426DC03463FFFF0283A0240F
-:10C9100014820006AFBF00188EE304B83C02000189
-:10C920008C426DC410620006000000008EE204B864
-:10C930003C010001AC246DC03C010001AC226DC47F
-:10C940003C0300018C636D98240200021062019C7C
-:10C950002C62000310400005240200011062000A4E
-:10C960000000000010000226000000002402000465
-:10C97000106200B6240200081062010A24020001BD
-:10C980001000021F000000008EE204B82443FFFFE5
-:10C990002C6200081040021C000310803C010001C2
-:10C9A000002208218C226AF80040000800000000E4
-:10C9B0003C0300018C636F402402000514620010E8
-:10C9C000000000003C0200018C426DA410400008F1
-:10C9D000240200030C004482000000002402000234
-:10C9E000AEE204B83C01000110000002AC206DA4CE
-:10C9F000AEE204B83C01000110000203AC206D302F
-:10CA00000C004482000000003C0200018C426DA436
-:10CA10003C010001AC206D301440017A2402000278
-:10CA20001000019D240200073C0300018C636F404D
-:10CA30002402000514620003240200013C010001ED
-:10CA4000AC226DD00C0045FF000000003C0300014B
-:10CA50008C636DD010000174240200113C050001AC
-:10CA60008CA56D983C0600028CC68FFC0C0051040E
-:10CA700000002021240200053C010001AC206DA42F
-:10CA8000100001E1AEE204B83C04000124846AEC29
-:10CA90003C05000F34A501000000302100003821C2
-:10CAA000AFA000100C002B3BAFA00014100001D66B
-:10CAB000000000008F8202203C0300040043102489
-:10CAC00014400175240200078F8300543C020001CA
-:10CAD0008C426F282463D8F0004310232C42271087
-:10CAE00014400003240200013C010001AC226D9CB3
-:10CAF0003C0200028C428FFC30425000104001C2C8
-:10CB0000000000008F820220304280001040017D32
-:10CB10000000000010000175000000003C0500014D
-:10CB20008CA56D980C00529B000020210C00551B19
-:10CB3000000020213C0300028C638FF4046101B0EB
-:10CB4000240200013C02000800621024104000068C
-:10CB5000000000008F8202143C03FFFF00431024FA
-:10CB6000100000053442251F8F8202143C03FFFF92
-:10CB7000004310243442241FAF8202148F8202200B
-:10CB80003C03020034420002AF820220240200086B
-:10CB9000AEE204B88F8202200283A0253C03000489
-:10CBA0000043102414400016000000003C02000264
-:10CBB0008C428FFC304250001040000D00000000FD
-:10CBC0008F820220304280001040000600000000EA
-:10CBD0008F8202203C03FFFF34637FFF10000003BD
-:10CBE000004310248F82022034428000AF82022052
-:10CBF0008F8202203C03F70000431025AF82022001
-:10CC00003C0300018C636F40240200051462000A9B
-:10CC1000000000003C02000194426F2624429FBCA9
-:10CC20002C420004104000042404001824050002D3
-:10CC30000C004DDB240600200C003E6D00000000BF
-:10CC40003C01000110000170AC206E208EE204B89F
-:10CC50002443FFFF2C6200081040016B000310808A
-:10CC60003C010001002208218C226B1800400008C2
-:10CC7000000000000C004547000000003C030001DC
-:10CC80008C636DB4100000E8240200093C0200022D
-:10CC90008C428FF830424000104000040000000039
-:10CCA0008F820044100000063442F0808F820044DE
-:10CCB0003C03FFFF34633F7F004310243442A080D5
-:10CCC000AF8200448F830054100000EA2402000465
-:10CCD0008F8300543C0200018C426F282463D8F0FB
-:10CCE000004310232C422710144001472402000562
-:10CCF000100000D8000000008F8202203C03F700E3
-:10CD000000431025AF820220AF8002043C010002E4
-:10CD1000100000D6AC208FE08F8300543C0200014D
-:10CD20008C426F282463FFF6004310232C42000A34
-:10CD30001440013524020007100000D70000000055
-:10CD40000C003F50000000001040012D24020001A3
-:10CD50008F8202143C03FFFF3C0400018C846F1C93
-:10CD6000004310243442251FAF820214240200081D
-:10CD700010800005AEE204B83C0200018C426E4413
-:10CD800010400064240200018F8202203C0300084E
-:10CD9000004310241040006A3C020200100000789A
-:10CDA000000000008EE204B82443FFFF2C6200075D
-:10CDB00010400115000310803C01000100220821F1
-:10CDC0008C226B3800400008000000000C003DAFD2
-:10CDD000000000003C010001AC206D9CAF8002040B
-:10CDE0003C0100020C004482AC208FE024020001D0
-:10CDF0003C010001AC226DB42402000210000102CB
-:10CE0000AEE204B80C004547000000003C030001FE
-:10CE10008C636DB410000084240200093C020002FF
-:10CE20008C428FF830424000104000033C0200C8A2
-:10CE300010000002344201F6344201FEAF82023893
-:10CE40008F8300541000008B240200048F83005451
-:10CE50003C0200018C426F282463D8F00043102369
-:10CE60002C422710144000E824020005100000792D
-:10CE7000000000008F8202203C03F70000431025D1
-:10CE8000AF820220AF8002043C0100021000007754
-:10CE9000AC208FE08F8300543C0200018C426F284D
-:10CEA0002463FFF6004310232C42000A144000D6EE
-:10CEB0002402000710000078000000000C003F5022
-:10CEC00000000000104000CE240200018F820214F6
-:10CED0003C03FFFF3C0400018C846F1C00431024C2
-:10CEE0003442251FAF820214240200081080000F74
-:10CEF000AEE204B83C0200018C426E441440000BC8
-:10CF0000000000008F82022034420002AF82022023
-:10CF1000240200013C010002AC228F900C004E9CC8
-:10CF20008F84022010000016000000008F82022073
-:10CF30003C03000800431024144000113C0202008E
-:10CF40000282A0252402000E3C010002AC228F9038
-:10CF50000C00551B000020218F8202203442000269
-:10CF60000C003E6DAF8202203C0500018CA56D983F
-:10CF70000C00529B00002021100000A300000000C4
-:10CF80003C0200018C426E441040009F00000000F3
-:10CF90003C0200018C426E402442FFFF3C01000134
-:10CFA000AC226E4014400098240200023C010001B3
-:10CFB000AC206E443C01000110000093AC226E4096
-:10CFC0008EE204B82443FFFF2C6200071040008E5D
-:10CFD000000310803C010001002208218C226B58C4
-:10CFE00000400008000000003C0200018C426DA4DB
-:10CFF00010400018240200050C00448200000000CC
-:10D0000024020002AEE204B83C0100011000007EE0
-:10D01000AC206DA40C004963000000003C0300013B
-:10D020008C636DD42402000614620077240200038E
-:10D0300010000075AEE204B83C0500018CA56D98A7
-:10D040003C0600028CC68FF80C0051040000202121
-:10D05000240200051000006CAEE204B88F820220AA
-:10D060003C03F70000431025AF8202208F83005459
-:10D0700024020006AEE204B83C0100011000006288
-:10D08000AC236F288F8202203C030004004310244D
-:10D0900010400003240200071000005BAEE204B859
-:10D0A0008F8300543C0200018C426F282463D8F027
-:10D0B000004310232C4227101440000324020001D7
-:10D0C0003C010001AC226D9C3C0200028C428FF8B6
-:10D0D000304250001040004C000000008F820220BF
-:10D0E0003042800010400007000000008F820220C4
-:10D0F0003C03FFFF34637FFF004310241000004215
-:10D10000AF8202208F820220344280001000003E55
-:10D11000AF8202203C0500018CA56D980C00529B4B
-:10D12000000020210C00551B000020213C020002C1
-:10D130008C428FF004410032240200018F820214DD
-:10D140003C03FFFF004310243442251FAF8202142A
-:10D1500024020008AEE204B88F82022034420002AA
-:10D16000AF8202208F8202203C030004004310247F
-:10D1700014400016000000003C0200028C428FF8B0
-:10D18000304250001040000D000000008F8202204D
-:10D190003042800010400006000000008F82022014
-:10D1A0003C03FFFF34637FFF1000000300431024A3
-:10D1B0008F82022034428000AF8202208F820220C0
-:10D1C0003C03F70000431025AF8202203C0200011F
-:10D1D00094426F2624429FBC2C420004104000045D
-:10D1E00024040018240500020C004DDB2406002056
-:10D1F0000C003E6D00000000100000030000000065
-:10D200003C010001AC226D9C8FBF001803E00008B8
-:10D2100027BD00208F8202008F8202208F82022091
-:10D2200034420004AF8202208F8202003C050001DC
-:10D230008CA56D9834420004AF82020024020002E3
-:10D2400010A2004B2CA20003104000052402000194
-:10D2500010A2000A00000000100000B10000000051
-:10D260002402000410A200722402000810A200850B
-:10D270003C02F0FF100000AA000000008F83005065
-:10D280003C02F0FF3442FFFF3C0400018C846F40FD
-:10D29000006218243C0207000062182524020E00D8
-:10D2A0002484FFFB2C840002AF830050AF85020072
-:10D2B000AF85022014800006AF8202388F820044BE
-:10D2C0003C03FFFF34633F7F00431024AF820044E0
-:10D2D0003C0300018C636F402402000514620004CB
-:10D2E000000000008F82004434425000AF820044AE
-:10D2F0003C0200018C426D883C0300018C636F404E
-:10D30000344200222463FFFC2C6300021460000CF2
-:10D31000AF8202003C0200018C426DAC3C03000174
-:10D320008C636D903C0400018C846D8C34428000D1
-:10D3300000621825006418251000000A34620002FB
-:10D340003C0200018C426D903C0300018C636DAC8B
-:10D350003C0400018C846D8C004310250044102592
-:10D3600034420002AF8202201000002F240200018C
-:10D3700024020E01AF8202388F8300503C02F0FF7E
-:10D380003442FFFF3C0400018C846F1C00621824AF
-:10D390003C020D000062182524020001AF830050FA
-:10D3A000AF820200AF820220108000053C033F00E4
-:10D3B0003C0200018C426D80100000043463007058
-:10D3C0003C0200018C426D803463007200431025E2
-:10D3D000AF8202003C0300018C636D843C02F700C5
-:10D3E000006218253C0200018C426D903C04000153
-:10D3F0008C846DAC3C0500018CA56F40004310256A
-:10D4000000441025AF8202202402000514A2000669
-:10D41000240200018F8200442403AFFF0043102444
-:10D42000AF820044240200011000003DAF820238A8
-:10D430008F8300503C02F0FF3442FFFF3C040001A8
-:10D440008C846F1C006218243C020A0000621825BC
-:10D4500024020001AF830050AF8202001080001E42
-:10D46000AF8202203C0200018C426E441440001A3C
-:10D470003C033F003C0200018C426D801000001A0A
-:10D48000346300E08F8300503C0400018C846F1CE7
-:10D490003442FFFF006218241080000FAF83005059
-:10D4A0003C0200018C426E441440000B3C043F00DF
-:10D4B0003C0300018C636D80348400E02402000191
-:10D4C000AF820200AF82022000641825AF83020001
-:10D4D000100000083C05F7003C0200018C426D8002
-:10D4E0003C033F00346300E200431025AF8202009A
-:10D4F0003C05F70034A580003C0300018C636D847B
-:10D500003C0200018C426D903C0400018C846DACA7
-:10D51000006518250043102500441025AF82022025
-:10D5200003E00008000000003C0300018C636DB4C0
-:10D530003C0200018C426DB810620003240200021C
-:10D540003C010001AC236DB81062001D2C62000389
-:10D55000104000252402000114620023240200046C
-:10D560003C0300018C636D981062000624020008E1
-:10D570001462000C3C0200C8344201FB1000000998
-:10D58000AF82023824020E01AF8202388F8200443B
-:10D590003C03FFFF34633F7F00431024344200808C
-:10D5A000AF8200448F830054240200023C0100013A
-:10D5B000AC226DB43C0100011000000BAC236F2CB9
-:10D5C0008F8300543C0200018C426F2C2463D8F0FE
-:10D5D000004310232C4227101440000324020009AA
-:10D5E0003C010001AC226DB403E000080000000023
-:10D5F00000000000000000000000000027BDFFD870
-:10D60000AFB2001800809021AFB3001C00A0982199
-:10D61000AFB1001400C08821AFB00010000080211D
-:10D62000AFBF0020A62000000C004D7824040001AC
-:10D63000261000012E0200201440FFFB0000000015
-:10D640000C004D78000020210C004D7824040001CE
-:10D650000C004D78240400010C004D7800002021BE
-:10D66000241000100250102410400002000020215D
-:10D67000240400010C004D78001080421600FFFACF
-:10D6800002501024241000100270102410400002D8
-:10D6900000002021240400010C004D78001080427D
-:10D6A0001600FFFA027010240C004DB934108000EF
-:10D6B0000C004DB9000000000C004D5800000000A7
-:10D6C00050400005001080429622000000501025B6
-:10D6D000A6220000001080421600FFF700000000A4
-:10D6E0000C004DB9000000008FBF00208FB3001C5C
-:10D6F0008FB200188FB100148FB0001003E0000843
-:10D7000027BD002827BDFFD8AFB1001400808821B5
-:10D71000AFB2001800A09021AFB3001C00C0982148
-:10D72000AFB0001000008021AFBF00200C004D788A
-:10D7300024040001261000012E0200201440FFFBEB
-:10D74000000000000C004D78000020210C004D78F6
-:10D75000240400010C004D78000020210C004D78BD
-:10D760002404000124100010023010241040000294
-:10D7700000002021240400010C004D78001080429C
-:10D780001600FFFA0230102424100010025010245A
-:10D790001040000200002021240400010C004D78FC
-:10D7A000001080421600FFFA025010240C004D7841
-:10D7B000240400010C004D7800002021341080006A
-:10D7C000966200000050102410400002000020214A
-:10D7D000240400010C004D78001080421600FFF870
-:10D7E000000000000C004DB9000000008FBF0020B9
-:10D7F0008FB3001C8FB200188FB100148FB00010CF
-:10D8000003E0000827BD00283C0400018C846DD093
-:10D810003C0200018C426E1827BDFFD8AFBF00202C
-:10D82000AFB1001C10820003AFB000183C01000132
-:10D83000AC246E183C0300018C636F402402000589
-:10D84000146200052483FFFF0C0049630000000000
-:10D850001000034C000000002C620013104003492C
-:10D86000000310803C010001002208218C226B8003
-:10D8700000400008000000000C004DB900008021AD
-:10D8800034028000A7A2001027B100100C004D78D0
-:10D8900024040001261000012E0200201440FFFB8A
-:10D8A000000000000C004D78000020210C004D7895
-:10D8B000240400010C004D78000020210C004D785C
-:10D8C0002404000124100010320200011040000264
-:10D8D00000002021240400010C004D78001080423B
-:10D8E0001600FFFA32020001241000100C004D78DF
-:10D8F00000002021001080421600FFFC0000000004
-:10D900000C004D78240400010C004D78000020210B
-:10D9100034108000962200000050102410400002B5
-:10D9200000002021240400010C004D7800108042EA
-:10D930001600FFF8000000000C004DB900000000C8
-:10D940001000030E2402000227B10010A7A000104F
-:10D95000000080210C004D782404000126100001F5
-:10D960002E0200201440FFFB000000000C004D7848
-:10D97000000020210C004D78240400010C004D789B
-:10D98000240400010C004D78000020212410001018
-:10D990003202000110400002000020212404000196
-:10D9A0000C004D78001080421600FFFA3202000190
-:10D9B000241000100C004D7800002021001080423F
-:10D9C0001600FFFC000000000C004DB93410800070
-:10D9D0000C004DB9000000000C004D580000000084
-:10D9E0005040000500108042962200000050102593
-:10D9F000A6220000001080421600FFF70000000081
-:10DA00000C004DB90000000097A2001030428000C9
-:10DA1000144002DC24020003100002D800000000C1
-:10DA200024021200A7A2001027B1001000008021DC
-:10DA30000C004D7824040001261000012E02002065
-:10DA40001440FFFB000000000C004D780000202176
-:10DA50000C004D78240400010C004D7800002021BA
-:10DA60000C004D7824040001241000103202000143
-:10DA70001040000200002021240400010C004D7819
-:10DA8000001080421600FFFA32020001241000103C
-:10DA90000C004D7800002021001080421600FFFC91
-:10DAA000000000000C004D78240400010C004D78AB
-:10DAB0000000202134108000962200000050102425
-:10DAC0001040000200002021240400010C004D78C9
-:10DAD000001080421600FFF8000000000C004DB955
-:10DAE000000000008F8300541000029624020004FE
-:10DAF0008F8300543C0200018C426F3C2463FF9CE6
-:10DB0000004310232C4200641440029E24020002B1
-:10DB10003C0300018C636F40106202972C6200038B
-:10DB20001440029624020011240200031062000532
-:10DB300024020004106202912402000F1000028FE0
-:10DB4000240200111000028D24020005240200149A
-:10DB5000A7A2001027B10010000080210C004D7812
-:10DB600024040001261000012E0200201440FFFBB7
-:10DB7000000000000C004D78000020210C004D78C2
-:10DB8000240400010C004D78000020210C004D7889
-:10DB90002404000124100010320200011040000291
-:10DBA00000002021240400010C004D780010804268
-:10DBB0001600FFFA32020001241000103202001297
-:10DBC0001040000200002021240400010C004D78C8
-:10DBD000001080421600FFFA320200120C004D784D
-:10DBE000240400010C004D78000020213410800036
-:10DBF0009622000000501024104000020000202156
-:10DC0000240400010C004D78001080421600FFF83B
-:10DC1000000000000C004DB9000000008F8300548C
-:10DC200010000248240200068F8300543C020001C9
-:10DC30008C426F3C2463FF9C004310232C42006401
-:10DC400014400250240200071000024C00000000A3
-:10DC500024020006A7A2001027B1001000008021B6
-:10DC60000C004D7824040001261000012E02002033
-:10DC70001440FFFB000000000C004D780000202144
-:10DC80000C004D78240400010C004D780000202188
-:10DC90000C004D7824040001241000103202000111
-:10DCA0001040000200002021240400010C004D78E7
-:10DCB000001080421600FFFA32020001241000100A
-:10DCC0003202001310400002000020212404000151
-:10DCD0000C004D78001080421600FFFA320200134B
-:10DCE0000C004D78240400010C004D780000202128
-:10DCF00034108000962200000050102410400002D2
-:10DD000000002021240400010C004D780010804206
-:10DD10001600FFF8000000000C004DB900000000E4
-:10DD20008F83005410000207240200088F830054E0
-:10DD30003C0200018C426F3C2463FF9C0043102393
-:10DD40002C4200641440020F240200091000020B50
-:10DD50000000000027B10010A7A0001000008021E3
-:10DD60000C004D7824040001261000012E02002032
-:10DD70001440FFFB000000000C004D780000202143
-:10DD80000C004D78240400010C004D78240400019F
-:10DD90000C004D78000020212410001032020001F8
-:10DDA0001040000200002021240400010C004D78E6
-:10DDB000001080421600FFFA320200012410001009
-:10DDC000320200181040000200002021240400014B
-:10DDD0000C004D78001080421600FFFA3202001845
-:10DDE0000C004DB9341080000C004DB9000000004B
-:10DDF0000C004D580000000050400005001080420B
-:10DE00009622000000501025A6220000001080423B
-:10DE10001600FFF7000000000C004DB90000802143
-:10DE200097A2001027B1001034420001A7A20010F1
-:10DE30000C004D7824040001261000012E02002061
-:10DE40001440FFFB000000000C004D780000202172
-:10DE50000C004D78240400010C004D7800002021B6
-:10DE60000C004D782404000124100010320200013F
-:10DE70001040000200002021240400010C004D7815
-:10DE8000001080421600FFFA320200012410001038
-:10DE9000320200181040000200002021240400017A
-:10DEA0000C004D78001080421600FFFA3202001874
-:10DEB0000C004D78240400010C004D780000202156
-:10DEC0003410800096220000005010241040000200
-:10DED00000002021240400010C004D780010804235
-:10DEE0001600FFF8000000000C004DB90000000013
-:10DEF0008F830054100001932402000A8F83005482
-:10DF00003C0200018C426F3C2463FF9C00431023C1
-:10DF10002C4200641440019B2402000B1000019766
-:10DF20000000000027B10010A7A000100000802111
-:10DF30000C004D7824040001261000012E02002060
-:10DF40001440FFFB000000000C004D780000202171
-:10DF50000C004D78240400010C004D7824040001CD
-:10DF60000C004D7800002021241000103202000126
-:10DF70001040000200002021240400010C004D7814
-:10DF8000001080421600FFFA320200012410001037
-:10DF9000320200171040000200002021240400017A
-:10DFA0000C004D78001080421600FFFA3202001774
-:10DFB0000C004DB9341080000C004DB90000000079
-:10DFC0000C004D5800000000504000050010804239
-:10DFD0009622000000501025A6220000001080426A
-:10DFE0001600FFF7000000000C004DB90000802172
-:10DFF00097A2001027B1001034420700A7A200101A
-:10E000000C004D7824040001261000012E0200208F
-:10E010001440FFFB000000000C004D7800002021A0
-:10E020000C004D78240400010C004D7800002021E4
-:10E030000C004D782404000124100010320200016D
-:10E040001040000200002021240400010C004D7843
-:10E05000001080421600FFFA320200012410001066
-:10E0600032020017104000020000202124040001A9
-:10E070000C004D78001080421600FFFA32020017A3
-:10E080000C004D78240400010C004D780000202184
-:10E09000341080009622000000501024104000022E
-:10E0A00000002021240400010C004D780010804263
-:10E0B0001600FFF8000000000C004DB90000000041
-:10E0C0008F8300541000011F2402000C8F83005422
-:10E0D0003C0200018C426F3C2463FF9C00431023F0
-:10E0E0002C42006414400127240200121000012376
-:10E0F0000000000027B10010A7A000100000802140
-:10E100000C004D7824040001261000012E0200208E
-:10E110001440FFFB000000000C004D78000020219F
-:10E120000C004D78240400010C004D7824040001FB
-:10E130000C004D7800002021241000103202000154
-:10E140001040000200002021240400010C004D7842
-:10E15000001080421600FFFA320200012410001065
-:10E1600032020014104000020000202124040001AB
-:10E170000C004D78001080421600FFFA32020014A5
-:10E180000C004DB9341080000C004DB900000000A7
-:10E190000C004D5800000000504000050010804267
-:10E1A0009622000000501025A62200000010804298
-:10E1B0001600FFF7000000000C004DB900008021A0
-:10E1C00097A2001027B1001034420010A7A200103F
-:10E1D0000C004D7824040001261000012E020020BE
-:10E1E0001440FFFB000000000C004D7800002021CF
-:10E1F0000C004D78240400010C004D780000202113
-:10E200000C004D782404000124100010320200019B
-:10E210001040000200002021240400010C004D7871
-:10E22000001080421600FFFA320200012410001094
-:10E2300032020014104000020000202124040001DA
-:10E240000C004D78001080421600FFFA32020014D4
-:10E250000C004D78240400010C004D7800002021B2
-:10E26000341080009622000000501024104000025C
-:10E2700000002021240400010C004D780010804291
-:10E280001600FFF8000000000C004DB9000000006F
-:10E290008F830054100000AB240200138F830054BE
-:10E2A0003C0200018C426F3C2463FF9C004310231E
-:10E2B0002C420064144000B32402000D100000AF93
-:10E2C0000000000027B10010A7A00010000080216E
-:10E2D0000C004D7824040001261000012E020020BD
-:10E2E0001440FFFB000000000C004D7800002021CE
-:10E2F0000C004D78240400010C004D78240400012A
-:10E300000C004D7800002021241000103202000182
-:10E310001040000200002021240400010C004D7870
-:10E32000001080421600FFFA320200012410001093
-:10E3300032020018104000020000202124040001D5
-:10E340000C004D78001080421600FFFA32020018CF
-:10E350000C004DB9341080000C004DB900000000D5
-:10E360000C004D5800000000504000050010804295
-:10E370009622000000501025A622000000108042C6
-:10E380001600FFF7000000000C004DB900008021CE
-:10E3900097A2001027B100103042FFFEA7A2001084
-:10E3A0000C004D7824040001261000012E020020EC
-:10E3B0001440FFFB000000000C004D7800002021FD
-:10E3C0000C004D78240400010C004D780000202141
-:10E3D0000C004D78240400012410001032020001CA
-:10E3E0001040000200002021240400010C004D78A0
-:10E3F000001080421600FFFA3202000124100010C3
-:10E400003202001810400002000020212404000104
-:10E410000C004D78001080421600FFFA32020018FE
-:10E420000C004D78240400010C004D7800002021E0
-:10E43000341080009622000000501024104000028A
-:10E4400000002021240400010C004D7800108042BF
-:10E450001600FFF8000000000C004DB9000000009D
-:10E460008F830054100000372402000E240208405D
-:10E47000A7A2001027B10010000080210C004D78E9
-:10E4800024040001261000012E0200201440FFFB8E
-:10E49000000000000C004D78000020210C004D7899
-:10E4A000240400010C004D78000020210C004D7860
-:10E4B0002404000124100010320200011040000268
-:10E4C00000002021240400010C004D78001080423F
-:10E4D0001600FFFA3202000124100010320200136D
-:10E4E0001040000200002021240400010C004D789F
-:10E4F000001080421600FFFA320200130C004D7823
-:10E50000240400010C004D7800002021341080000C
-:10E51000962200000050102410400002000020212C
-:10E52000240400010C004D78001080421600FFF812
-:10E53000000000000C004DB9000000008F83005463
-:10E54000240200103C010001AC226DD03C0100010E
-:10E550001000000CAC236F3C8F8300543C02000180
-:10E560008C426F3C2463FF9C004310232C420064C8
-:10E570001440000400000000240200113C010001CE
-:10E58000AC226DD08FBF00208FB1001C8FB000185F
-:10E5900003E0000827BD00283C0300018C636D9850
-:10E5A00027BDFFC824020002AFBF0034AFB2003065
-:10E5B000AFB1002C14620004AFB000283C1200027E
-:10E5C000100000038E528FF83C1200028E528FFC16
-:10E5D0003C0300018C636DD43C0200018C426E1C34
-:10E5E000506200042463FFFF3C010001AC236E1C59
-:10E5F0002463FFFF2C6200061040037700031080A5
-:10E600003C010001002208218C226BD80040000848
-:10E610000000000000002021000028210C004DDB3C
-:10E6200034068000240400102405000224060002A1
-:10E63000240200020C004DDBA7A2001824020002F5
-:10E640003C01000110000364AC226DD427B1001816
-:10E65000A7A00018000080210C004D7824040001C0
-:10E66000261000012E0200201440FFFB00000000D5
-:10E670000C004D78000020210C004D78240400018E
-:10E680000C004D78240400010C004D78000020217E
-:10E69000241000103202000110400002000020216E
-:10E6A000240400010C004D78001080421600FFFA8F
-:10E6B00032020001241000100C004D7800002021CF
-:10E6C000001080421600FFFC000000000C004DB955
-:10E6D000341080000C004DB9000000000C004D58B3
-:10E6E000000000005040000500108042962200000B
-:10E6F00000501025A6220000001080421600FFF7EF
-:10E70000000000000C004DB90000000097A20018A6
-:10E710003042800014400004240200033C01000148
-:10E72000AC226DD4240200033C0100011000032A36
-:10E73000AC226DD42404001024050002240600023B
-:10E74000240200020C004DDBA7A200183C030001CC
-:10E750008C636E2024020001146201E1000080211C
-:10E7600027B10018A7A000180C004D782404000160
-:10E77000261000012E0200201440FFFB00000000C4
-:10E780000C004D78000020210C004D78240400017D
-:10E790000C004D78240400010C004D78000020216D
-:10E7A000241000103202000110400002000020215D
-:10E7B000240400010C004D78001080421600FFFA7E
-:10E7C0003202000124100010320200181040000232
-:10E7D00000002021240400010C004D78001080422C
-:10E7E0001600FFFA320200180C004DB934108000F8
-:10E7F0000C004DB9000000000C004D580000000056
-:10E800005040000500108042962200000050102564
-:10E81000A6220000001080421600FFF70000000052
-:10E820000C004DB90000802127B10018A7A00018E6
-:10E830000C004D7824040001261000012E02002057
-:10E840001440FFFB000000000C004D780000202168
-:10E850000C004D78240400010C004D7824040001C4
-:10E860000C004D780000202124100010320200011D
-:10E870001040000200002021240400010C004D780B
-:10E88000001080421600FFFA32020001241000102E
-:10E890003202001810400002000020212404000170
-:10E8A0000C004D78001080421600FFFA320200186A
-:10E8B0000C004DB9341080000C004DB90000000070
-:10E8C0000C004D5800000000504000050010804230
-:10E8D0009622000000501025A62200000010804261
-:10E8E0001600FFF7000000000C004DB90000802169
-:10E8F00024040018000028210C004DDB2406040429
-:10E90000A7A0001A0C004D78240400012610000175
-:10E910002E0200201440FFFB000000000C004D7888
-:10E92000000020210C004D78240400010C004D78DB
-:10E93000240400010C004D78000020212410001058
-:10E9400032020001104000020000202124040001D6
-:10E950000C004D78001080421600FFFA32020001D0
-:10E960002410001032020018104000020000202184
-:10E97000240400010C004D78001080421600FFFABC
-:10E98000320200180C004DB9341080000C004DB953
-:10E99000000000000C004D58000000005040000531
-:10E9A0000010804297A2001A00501025A7A2001A5A
-:10E9B000001080421600FFF7000000000C004DB967
-:10E9C00000008021A7A0001A0C004D78240400014B
-:10E9D000261000012E0200201440FFFB0000000062
-:10E9E0000C004D78000020210C004D78240400011B
-:10E9F0000C004D78240400010C004D78000020210B
-:10EA000024100010320200011040000200002021FA
-:10EA1000240400010C004D78001080421600FFFA1B
-:10EA200032020001241000103202001810400002CF
-:10EA300000002021240400010C004D7800108042C9
-:10EA40001600FFFA320200180C004DB93410800095
-:10EA50000C004DB9000000000C004D5800000000F3
-:10EA6000504000050010804297A2001A0050102567
-:10EA7000A7A2001A001080421600FFF70000000055
-:10EA80000C004DB900008021A7A0001C0C004D789F
-:10EA900024040001261000012E0200201440FFFB78
-:10EAA000000000000C004D78000020210C004D7883
-:10EAB000240400010C004D78240400010C004D7862
-:10EAC00000002021241000100C004D7800002021AF
-:10EAD000001080421600FFFC00000000241000100F
-:10EAE0003202001E10400002000020212404000118
-:10EAF0000C004D78001080421600FFFA3202001E12
-:10EB00000C004DB9341080000C004DB9000000001D
-:10EB10000C004D58000000005040000500108042DD
-:10EB200097A2001C00501025A7A2001C00108042D4
-:10EB30001600FFF7000000000C004DB90000802116
-:10EB4000A7A0001C0C004D78240400012610000131
-:10EB50002E0200201440FFFB000000000C004D7846
-:10EB6000000020210C004D78240400010C004D7899
-:10EB7000240400010C004D78000020212410001016
-:10EB80000C004D7800002021001080421600FFFC90
-:10EB900000000000241000103202001E104000028D
-:10EBA00000002021240400010C004D780010804258
-:10EBB0001600FFFA3202001E0C004DB9341080001E
-:10EBC0000C004DB9000000000C004D580000000082
-:10EBD000504000050010804297A2001C00501025F4
-:10EBE000A7A2001C001080421600FFF700000000E2
-:10EBF0000C004DB90000802124020002A7A2001ED3
-:10EC00000C004D7824040001261000012E02002083
-:10EC10001440FFFB000000000C004D780000202194
-:10EC20000C004D78240400010C004D7800002021D8
-:10EC30000C004D7824040001241000100C004D78C5
-:10EC400000002021001080421600FFFC00000000A0
-:10EC5000241000103202001E10400002000020218B
-:10EC6000240400010C004D78001080421600FFFAC9
-:10EC70003202001E0C004D78240400010C004D7877
-:10EC8000000020213410800097A2001E00501024A4
-:10EC90001040000200002021240400010C004D78E7
-:10ECA000001080421600FFF8000000000C004DB973
-:10ECB00000008021A7A000200C004D782404000152
-:10ECC000261000012E0200201440FFFB000000006F
-:10ECD0000C004D78000020210C004D782404000128
-:10ECE0000C004D78240400010C004D780000202118
-:10ECF000241000100C004D780000202100108042EC
-:10ED00001600FFFC00000000241000103202001E5C
-:10ED10001040000200002021240400010C004D7866
-:10ED2000001080421600FFFA3202001E0C004DB99E
-:10ED3000341080000C004DB9000000000C004D584C
-:10ED400000000000504000050010804297A2002003
-:10ED500000501025A7A20020001080421600FFF7E7
-:10ED6000000000000C004DB900008021A7A0002089
-:10ED70000C004D7824040001261000012E02002012
-:10ED80001440FFFB000000000C004D780000202123
-:10ED90000C004D78240400010C004D78240400017F
-:10EDA0000C004D7800002021241000100C004D783C
-:10EDB00000002021001080421600FFFC000000002F
-:10EDC000241000103202001E10400002000020211A
-:10EDD000240400010C004D78001080421600FFFA58
-:10EDE0003202001E0C004DB9341080000C004DB9E9
-:10EDF000000000000C004D580000000050400005CD
-:10EE00000010804297A2002000501025A7A20020E9
-:10EE1000001080421600FFF7000000000C004DB902
-:10EE200000008021A7A000220C004D7824040001DE
-:10EE3000261000012E0200201440FFFB00000000FD
-:10EE40000C004D78000020210C004D7824040001B6
-:10EE50000C004D78000020210C004D7824040001A6
-:10EE6000241000100C004D7800002021001080427A
-:10EE70001600FFFC00000000241000100C004D786C
-:10EE800000002021001080421600FFFC000000005E
-:10EE90000C004D78240400010C004D780000202166
-:10EEA0003410800097A2002200501024104000026D
-:10EEB00000002021240400010C004D780010804245
-:10EEC0001600FFF8000000000C004DB90000000023
-:10EED00024040018240500020C004DDB2406000465
-:10EEE0003C1000018E106E24240200011602011D48
-:10EEF000000000003C02000194426F263C0100012A
-:10EF0000AC206E2424429FBC2C4200041040000C14
-:10EF100024040009240500010C004DDB2406040034
-:10EF200024040018240500010C004DDB24060020F9
-:10EF300024040018240500010C004DDB24062000E9
-:10EF40003C02400002421024104001233C022000F9
-:10EF50000242102410400004000000003C010001A7
-:10EF600010000003AC306F1C3C010001AC206F1C92
-:10EF70003C0300018C636F3424020005146200F925
-:10EF8000000000003C0200018C426F1C1040006732
-:10EF90003C0200040242102410400011A7A00018F7
-:10EFA0003C02000802421024104000022402020029
-:10EFB000A7A200183C0200100242102410400004D6
-:10EFC0000000000097A2001834420100A7A2001818
-:10EFD00097A600182404000910000004000028214E
-:10EFE0002404000900002821000030210C004DDB22
-:10EFF0000000000024020001A7A2001A3C02000841
-:10F00000024210241040000C3C0200020242102474
-:10F010001040000224020101A7A2001A3C020001D4
-:10F0200002421024104000053C02001097A2001A72
-:10F0300034420040A7A2001A3C02001002421024F1
-:10F040001040000E3C020002024210241040000555
-:10F050003C02000197A2001A34420080A7A2001AC5
-:10F060003C02000102421024104000053C0300A0B5
-:10F0700097A2001A34420020A7A2001A3C0300A065
-:10F0800002431024544300043C02002097A2001ABB
-:10F090001000000C344204000242102450400004CE
-:10F0A0003C02008097A2001A1000000634420800BB
-:10F0B00002421024104000040000000097A2001A31
-:10F0C00034420C00A7A2001A97A6001A24040004D8
-:10F0D0000C004DDB000028213C02000402421024F9
-:10F0E00010400004A7A0001C32425000144000044D
-:10F0F00000000000324240001040000500002021C6
-:10F100000C004CF902402021100000960000000085
-:10F1100097A6001C0000282134C612000C004DDB0D
-:10F12000A7A6001C1000008F00000000024210245F
-:10F1300010400004A7A00018324250001440000400
-:10F140000000000032424000104000053C02001068
-:10F150000C004CF90240202110000019A7A0001A51
-:10F1600002421024104000040000000097A2001882
-:10F1700010000004A7A2001897A200183442010052
-:10F18000A7A200183C020001024210241040000413
-:10F190000000000097A2001810000004A7A20018A9
-:10F1A00097A2001834422000A7A2001897A60018C2
-:10F1B000000020210C004DDB00002821A7A0001A30
-:10F1C000000080210C004D7824040001261000016D
-:10F1D0002E0200201440FFFB000000000C004D78C0
-:10F1E000000020210C004D78240400010C004D7813
-:10F1F000240400010C004D78000020212410001090
-:10F20000320200011040000200002021240400010D
-:10F210000C004D78001080421600FFFA3202000107
-:10F22000241000100C004D780000202100108042B6
-:10F230001600FFFC000000000C004DB934108000E7
-:10F240000C004DB9000000000C004D5800000000FB
-:10F25000504000050010804297A2001A005010256F
-:10F26000A7A2001A001080421600FFF7000000005D
-:10F270000C004DB900008021A7A0001A0C004D78A9
-:10F2800024040001261000012E0200201440FFFB80
-:10F29000000000000C004D78000020210C004D788B
-:10F2A000240400010C004D78240400010C004D786A
-:10F2B0000000202124100010320200011040000242
-:10F2C00000002021240400010C004D780010804231
-:10F2D0001600FFFA32020001241000100C004D78D5
-:10F2E00000002021001080421600FFFC00000000FA
-:10F2F0000C004DB9341080000C004DB90000000026
-:10F300000C004D58000000005040000500108042E5
-:10F3100097A2001A00501025A7A2001A00108042E0
-:10F320001600FFF7000000000C004DB900000000BF
-:10F330003C04000124846BCC97A6001897A7001A00
-:10F340003C0200018C426D983C0300018C636F1CF1
-:10F350003C05000D34A50205AFA200100C002B3BAC
-:10F36000AFA300148F830054240200043C01000169
-:10F37000AC226DD43C01000110000017AC236F38A3
-:10F380008F8300543C0200018C426F382463FF9C41
-:10F39000004310232C4200641440000F00000000C2
-:10F3A0008F820220240300053C010001AC236DD4B0
-:10F3B0003C03F7000043102510000007AF82022035
-:10F3C000240200063C010001AC226DD4240200118D
-:10F3D0003C010001AC226DD08FBF00348FB20030F1
-:10F3E0008FB1002C8FB0002803E0000827BD003843
-:10F3F00027BDFFD8AFB0001800808021AFB1001C3E
-:10F40000000088213202400010400013AFBF0020EE
-:10F410003C020010020210242C42000100021023C2
-:10F42000304341003C020001020210241440000657
-:10F43000347140003C020002020210241440000219
-:10F440003471600034714040000020210000282108
-:10F45000100000360220302132021000104000352A
-:10F4600000002021000028210C004DDB2406004074
-:10F4700024040018000028210C004DDB24060C0099
-:10F4800024040017000028210C004DDB2406040092
-:10F4900024040016000028210C004DDB2406000681
-:10F4A00024040017000028210C004DDB2406250051
-:10F4B00024040016000028210C004DDB2406000661
-:10F4C00024040017000028210C004DDB2406460010
-:10F4D00024040016000028210C004DDB2406000641
-:10F4E00024040017000028210C004DDB24066700CF
-:10F4F00024040016000028210C004DDB2406000621
-:10F500002404001F000028210C004DDB24060010FD
-:10F5100024040009000028210C004DDB24061500FE
-:10F52000240400090000282124061D000C004DDBE6
-:10F53000000000003C04000124846BF03C05000E38
-:10F5400034A501000200302102203821AFA00010B4
-:10F550000C002B3BAFA000148FBF00208FB1001C0C
-:10F560008FB0001803E0000827BD00288F850044F5
-:10F570008F8200443C030001004310253C03000837
-:10F58000AF8200448F8400548F82005400A328244B
-:10F5900010000002248400018F8200540082102396
-:10F5A0002C4200021440FFFC000000008F82004447
-:10F5B0003C03FFFE3463FFFF00431024AF8200448E
-:10F5C0008F8300548F8200541000000224630001D6
-:10F5D0008F820054006210232C4200021440FFFC72
-:10F5E0000000000003E0000800A010218F83004409
-:10F5F0003C02FFF03442FFFF000424800062182424
-:10F600003C0200020082202500641825AF830044DC
-:10F610008F8200443C03FFFE3463FFFF004310244D
-:10F62000AF8200448F8300548F8200541000000288
-:10F63000246300018F820054006210232C420002D8
-:10F640001440FFFC000000008F8200443C030001D6
-:10F6500000431025AF8200448F8300548F820054F2
-:10F6600010000002246300018F8200540062102306
-:10F670002C4200021440FFFC0000000003E00008E0
-:10F68000000000008F8200442403FF7F0043102409
-:10F69000AF8200448F8300548F8200541000000218
-:10F6A000246300018F820054006210232C42000268
-:10F6B0001440FFFC000000008F82004434420080B0
-:10F6C000AF8200448F8300548F82005410000002E8
-:10F6D000246300018F820054006210232C42000238
-:10F6E0001440FFFC0000000003E0000800000000E0
-:10F6F0008F8200443C03FFF03463FFFF004310247B
-:10F70000AF8200448F8200443C0300010043102577
-:10F71000AF8200448F8300548F8200541000000297
-:10F72000246300018F820054006210232C420002E7
-:10F730001440FFFC000000008F8200443C03FFFEE9
-:10F740003463FFFF00431024AF8200448F830054D2
-:10F750008F82005410000002246300018F82005445
-:10F76000006210232C4200021440FFFC0000000045
-:10F7700003E000080000000027BDFFC8AFB300246D
-:10F7800000809821AFBE002C00A0F021AFB2002075
-:10F7900000C0902133C2FFFFAFBF0030AFB50028DB
-:10F7A000AFB1001CAFB0001814400034A7B2001075
-:10F7B0003271FFFF27B20010000080210C004D784D
-:10F7C00024040001261000012E0200201440FFFB3B
-:10F7D000000000000C004D78000020210C004D7846
-:10F7E000240400010C004D78000020210C004D780D
-:10F7F0002404000124100010320200011040000215
-:10F8000000002021240400010C004D7800108042EB
-:10F810001600FFFA320200012410001002301024FA
-:10F820001040000200002021240400010C004D784B
-:10F83000001080421600FFFA023010240C004D78B0
-:10F84000240400010C004D780000202134108000B9
-:10F8500096420000005010241040000200002021B9
-:10F86000240400010C004D78001080421200007545
-:10F87000000000001000FFF6000000003275FFFFDE
-:10F8800027B10010A7A00010000080210C004D78C7
-:10F8900024040001261000012E0200201440FFFB6A
-:10F8A000000000000C004D78000020210C004D7875
-:10F8B000240400010C004D78240400010C004D7854
-:10F8C000000020212410001032020001104000022C
-:10F8D00000002021240400010C004D78001080421B
-:10F8E0001600FFFA320200012410001002B01024AA
-:10F8F0001040000200002021240400010C004D787B
-:10F90000001080421600FFFA02B010240C004DB91E
-:10F91000341080000C004DB9000000000C004D5860
-:10F9200000000000504000050010804296220000B8
-:10F9300000501025A6220000001080421600FFF79C
-:10F94000000000000C004DB90000000033C5FFFFAF
-:10F950002402000154A200042402000297A2001015
-:10F96000100000060052102514A200063271FFFF9D
-:10F9700097A200100012182700431024A7A200101D
-:10F980003271FFFF27B20010000080210C004D787B
-:10F9900024040001261000012E0200201440FFFB69
-:10F9A000000000000C004D78000020210C004D7874
-:10F9B000240400010C004D78000020210C004D783B
-:10F9C0002404000124100010320200011040000243
-:10F9D00000002021240400010C004D78001080421A
-:10F9E0001600FFFA32020001241000100230102429
-:10F9F0001040000200002021240400010C004D787A
-:10FA0000001080421600FFFA023010240C004D78DE
-:10FA1000240400010C004D780000202134108000E7
-:10FA200096420000005010241040000200002021E7
-:10FA3000240400010C004D78001080421600FFF8ED
-:10FA4000000000000C004DB9000000008FBF003026
-:10FA50008FBE002C8FB500288FB300248FB20020FA
-:10FA60008FB1001C8FB0001803E0000827BD0038DC
-:10FA700000000000000000000000000027BDFFE8BB
-:10FA8000AFBF00108EE304B824020008146201E046
-:10FA9000000000003C0200018C426F1C1440000575
-:10FAA000000000000C003DAF8F840224100001D83C
-:10FAB000000000008F8202203C0300080043102455
-:10FAC00010400026240200018F8402248F8202202D
-:10FAD0003C03040000431024104000060000000016
-:10FAE0003C010002AC208FA03C0100021000000B82
-:10FAF000AC208FC03C03000224638FA08C62000006
-:10FB000024420001AC6200002C42000214400003B9
-:10FB1000240200013C010002AC228FC03C02000222
-:10FB20008C428FC01040000630820040104000041C
-:10FB3000240200013C01000210000003AC228FC42B
-:10FB40003C010002AC208FC43C010002AC248F9C1D
-:10FB50003C0100021000000BAC208FD03C010002E1
-:10FB6000AC228FD03C010002AC208FC03C010002CF
-:10FB7000AC208FA03C010002AC208FC43C010002ED
-:10FB8000AC208F9C3C0300028C638F903C020002EF
-:10FB90008C428F94506200042463FFFF3C010002FA
-:10FBA000AC238F942463FFFF2C62000E104001945D
-:10FBB000000310803C010001002208218C226C000F
-:10FBC0000040000800000000240200023C01000286
-:10FBD000AC208FC03C010002AC208FA03C01000291
-:10FBE000AC208F9C3C010002AC208FC43C01000281
-:10FBF000AC208FB83C010002AC208FB0AF80022453
-:10FC00003C010002AC228F903C0200028C428FD05B
-:10FC10001440004F3C02FDFF3442FFFF0C003DAF9B
-:10FC20000282A024AF8002048F8202002403FFFD21
-:10FC300000431024AF8202003C010002AC208FE0A0
-:10FC40008F8300543C0200028C428FB824040001D0
-:10FC50003C010002AC248FCC244200013C01000294
-:10FC6000AC228FB82C4200043C010002AC238FB4BC
-:10FC700014400006240200033C010001AC246D9CEA
-:10FC80003C0100021000015EAC208FB83C01000274
-:10FC90001000015BAC228F908F8300543C02000265
-:10FCA0008C428FB42463D8F0004310232C422710D9
-:10FCB00014400003240200043C010002AC228F9097
-:10FCC0003C0200028C428FD0144000213C02FDFF18
-:10FCD0003442FFFF1000014A0282A0243C040001CC
-:10FCE0008C846F203C0100020C005084AC208FA853
-:10FCF0003C0200028C428FDCAF8202043C02000214
-:10FD00008C428FD0144000123C03FDFF8F8202040E
-:10FD10003463FFFF304200301440012F0283A024DF
-:10FD20003C0300028C638FDC240200053C010002CE
-:10FD3000AC228F903C01000210000131AC238FE017
-:10FD40003C0200028C428FD0104000103C02FDFFAC
-:10FD50003C0200018C426E3C244200013C01000147
-:10FD6000AC226E3C2C42000214400125240200010A
-:10FD70003C010001AC226E443C010001AC206E3C11
-:10FD80003C0100011000011EAC226D9C3C030002EE
-:10FD90008C638FC03442FFFF106001190282A024DF
-:10FDA0003C0200028C428F9C1040011500000000B4
-:10FDB0003C010002AC228FC8240200033C01000277
-:10FDC000AC228FA0100000B8240200063C01000203
-:10FDD000AC208FA88F82020434420040AF8202041C
-:10FDE0003C0200028C428FE0240300073C01000229
-:10FDF000AC238F90344200403C010002AC228FE0E3
-:10FE00003C0200028C428FC0104000050000000040
-:10FE10003C0200028C428F9C104000F02402000241
-:10FE20003C05000224A58FA08CA200002C424E218C
-:10FE3000104000EA240200023C0200028C428FC4FF
-:10FE4000104000EF2404FFBF3C0200028C428F9C54
-:10FE50003C0300028C638FC8004410240064182403
-:10FE600010430004240200013C010002100000E4E1
-:10FE7000AC228F9024020003ACA2000024020008F0
-:10FE80003C010002AC228F903C0200028C428FCCDD
-:10FE90001040000C240200013C0400020C005091B0
-:10FEA0008C848F9C3C0200028C428FE81440000539
-:10FEB000240200013C0200028C428FE41040000644
-:10FEC000240200013C010001AC226D9C3C010002B7
-:10FED000100000CBAC208FB83C0200028C428FB0E7
-:10FEE0003C0300028C638F9C2C420001000210C076
-:10FEF000306300083C010002AC228FB03C010002DC
-:10FF0000AC238FAC8F830054240200093C01000213
-:10FF1000AC228F903C010002100000B9AC238FB4DA
-:10FF20008F8300543C0200028C428FB42463D8F0CB
-:10FF3000004310232C4227101440009F00000000B3
-:10FF40003C0200028C428FC01040000500000000FF
-:10FF50003C0200028C428F9C104000A02402000250
-:10FF60003C03000224638FA08C6200002C424E21CF
-:10FF70001040009A240200023C0200028C428FCC06
-:10FF80001040000E000000003C0200028C428F9CDA
-:10FF90003C010002AC208FCC304200801040002F8A
-:10FFA0002402000C8F820204304200801440000CB6
-:10FFB00024020003100000292402000C3C0200026D
-:10FFC0008C428F9C304200801440000524020003C4
-:10FFD0008F820204304200801040001F2402000380
-:10FFE000AC6200002402000A3C010002AC228F90A7
-:10FFF0003C04000224848FD88C8200003C03000261
-:020000021000EC
-:100000008C638FB000431025AF8202048C83000004
-:100010003C0400028C848FB02402000B3C010002DF
-:10002000AC228F90006418253C010002AC238FE0C5
-:100030003C05000224A58FA08CA200002C424E217A
-:1000400010400066240200023C0200028C428FD065
-:1000500010400005000000002402000C3C010002DA
-:1000600010000067AC228F903C0200028C428FC0CF
-:1000700010400063000000003C0400028C848F9C50
-:1000800010800055308200083C0300028C638FAC66
-:100090001062005B240200033C010002AC248FC804
-:1000A000ACA20000240200063C0100021000005433
-:1000B000AC228F908F82020034420002AF82020095
-:1000C0008F8300542402000D3C010002AC228F906B
-:1000D0003C010002AC238FB48F8300543C02000229
-:1000E0008C428FB42463D8F0004310232C42271095
-:1000F00014400031000000003C0200028C428FD00E
-:10010000104000202402000E3C0300028C638FE4A8
-:100110003C01000214600015AC228F900C003E6D73
-:10012000000000003C0500018CA56D980C00529B5E
-:10013000000020213C0300018C636D982402000420
-:10014000146200052403FFFB3C0200018C426D9405
-:10015000100000032403FFF73C0200018C426D9461
-:10016000004310243C010001AC226D948F830224D3
-:100170003C0202003C010002AC238FEC1000002086
-:100180000282A0253C0200028C428FC01040000574
-:10019000000000003C0200028C428F9C1040000FC7
-:1001A000240200023C0200028C428FA02C424E210D
-:1001B0001040000A240200023C0200028C428FC060
-:1001C0001040000F000000003C0200028C428F9C97
-:1001D0001440000B00000000240200023C01000259
-:1001E00010000007AC228F903C0200028C428FC0AE
-:1001F00010400003000000000C003DAF00000000B4
-:100200008F8202203C03F70000431025AF820220BA
-:100210008FBF001003E0000827BD00183C03000258
-:1002200024638FE88C6200001040000534422000F7
-:100230003C010002AC228FDC10000003AC60000027
-:100240003C010002AC248FDC03E000080000000049
-:1002500027BDFFE030820030AFBF00183C01000234
-:10026000AC228FE4144000673C02FFFF34421F0EB3
-:1002700000821024144000612402003030822000EB
-:100280001040005D3083800000031A0230820001BC
-:10029000000212003C0400018C846F2000621825CB
-:1002A000000331C23C03000124636E4830828000A9
-:1002B00000021202308400010004220000441025D4
-:1002C000000239C2000610800043102100471021AF
-:1002D000904300002402000110620025000000008D
-:1002E00010600007240200021062001324020003C1
-:1002F0001062002C3C05000F1000003700000000C9
-:100300008F8202002403FEFF00431024AF8202000C
-:100310008F8202203C03FFFE3463FFFF0043102462
-:10032000AF8202203C010002AC2090043C0100029C
-:1003300010000034AC20900C8F8202003442010087
-:10034000AF8202008F8202203C03FFFE3463FFFF76
-:1003500000431024AF820220240201003C0100026D
-:10036000AC2290043C01000210000026AC20900C4E
-:100370008F8202002403FEFF00431024AF8202009C
-:100380008F8202203C03000100431025AF8202202F
-:100390003C010002AC2090043C0100021000001956
-:1003A000AC23900C8F82020034420100AF82020025
-:1003B0008F8202203C03000100431025AF820220FF
-:1003C000240201003C010002AC2290043C01000226
-:1003D0001000000CAC23900C34A5FFFF3C0400017E
-:1003E00024846C38AFA300100C002B3BAFA000148A
-:1003F0001000000400000000240200303C01000254
-:10040000AC228FE88FBF001803E0000827BD002052
-:1004100000000000000000000000000027BDFFC831
-:10042000AFB2002800809021AFB3002C00A098212B
-:10043000AFB0002000C080213C04000124846C5037
-:100440003C0500093C0200018C426D9834A59001E6
-:100450000240302102603821AFBF0030AFB100242C
-:10046000A7A0001AAFB000140C002B3BAFA20010E5
-:1004700024020002126200832E6200031040000575
-:10048000240200011262000A000000001000017343
-:100490000000000024020004126200F82402000898
-:1004A000126200F73C02FFEC1000016C000000003B
-:1004B0003C0200018C426D94304200021440000462
-:1004C000001289403C02FFFB3442FFFF02028024FD
-:1004D0003C01000200310821AC308FFC3C0240009E
-:1004E000020210241040004E001023C2308400305D
-:1004F000001013823042001C3C03000124636DD8BD
-:1005000000431021008238213C0200200202102406
-:1005100010400006240201003C01000200310821C5
-:10052000AC229000100000053C0200803C0100025B
-:1005300000310821AC2090003C020080020210240F
-:1005400010400006001219403C0200013C0100026C
-:100550000023082110000005AC2290080012114071
-:100560003C01000200220821AC20900894E4000025
-:100570003C0300018C636F402402000510620010F0
-:10058000A7A400183202400010400002348240004C
-:10059000A7A200182404000194E20002240500042C
-:1005A00024E60002344200010C0045BEA4E2000231
-:1005B00024040001000028210C0045BE27A60018D5
-:1005C0003C0200018C426D98241100013C010001A5
-:1005D000AC316DA414530004320280000C003DAF16
-:1005E00000000000320280001040011C00000000EA
-:1005F0000C003DAF000000003C0300018C636F4025
-:100600002402000510620115240200023C010001D1
-:10061000AC316D9C3C01000110000110AC226D98C2
-:10062000240400012405000427B0001A0C0045BE74
-:100630000200302124040001000028210C0045BEE6
-:10064000020030213C020002005110218C428FF444
-:100650003C0400018C846D983C03BFFF3463FFFFB2
-:100660003C010001AC336DA4004310243C010002A6
-:1006700000310821109300F7AC228FF4100000F72E
-:10068000000000003C02200002021024104000057F
-:10069000240200013C010001AC226F1C1000000488
-:1006A000001289403C010001AC206F1C00128940FF
-:1006B0003C01000200310821AC308FF83C024000C0
-:1006C0000202102414400014000000003C0200014B
-:1006D0008C426F1C10400006240400042405000115
-:1006E0000C004DDB2406200024020001AEE204B819
-:1006F0003C020002005110218C428FF03C03BFFFEE
-:100700003463FFFF004310243C0100020031082144
-:10071000100000D0AC228FF03C0200018C426F1C14
-:10072000104000283C0300A0020310245443000D95
-:100730003C0200203C0200018C426F202403010097
-:100740003C01000200310821AC2390043C0300016D
-:100750003C01000200310821AC23900C1000001570
-:100760003442040002021024104000082403010057
-:100770003C0200018C426F203C0100020031082144
-:10078000AC2390041000000B344208003C020080AF
-:10079000020210241040002E3C0300013C02000124
-:1007A0008C426F203C01000200310821AC23900CE8
-:1007B00034420C003C010001AC226F2010000025E7
-:1007C000240400013C020020020210241040000614
-:1007D000240201003C01000200310821AC229004F7
-:1007E000100000053C0200803C010002003108219D
-:1007F000AC2090043C02008002021024104000074C
-:10080000001219403C0200013C01000200230821B3
-:10081000AC22900C100000062404000100121140CC
-:100820003C01000200220821AC20900C24040001AD
-:100830000000282127B0001E0C00457C020030215A
-:1008400024040001000028210C00457C0200302116
-:10085000240400012405000127B0001C0C00457C85
-:100860000200302124040001240500010C00457C15
-:100870000200302110000077000000003C02FFEC75
-:100880003442FFFF020280243C020008020280255D
-:10089000001211403C01000200220821AC308FF808
-:1008A0003C02200002021024104000090000000059
-:1008B0003C0200018C426E441440000524020001F9
-:1008C0003C010001AC226F1C100000043C024000FF
-:1008D0003C010001AC206F1C3C02400002021024CD
-:1008E0001440001D24020E013C0300018C636F1CA8
-:1008F000AF8202383C010001AC206DB010600005F1
-:10090000240220203C010001AC226F2024020001BF
-:10091000AEE204B83C04BFFF001219403C020002E2
-:10092000004310218C428FF03C0500018CA56D988E
-:100930003484FFFF004410243C01000200230821FE
-:10094000AC228FF02402000110A20044000000003D
-:1009500010000040000000003C0200018C426F1CAF
-:100960001040001C240220003C010001AC226F203A
-:100970003C0300A0020310241443000500121140A0
-:100980003402A0003C0100011000002DAC226F20B9
-:100990003C030002006218218C638FF83C020020A7
-:1009A0000062102410400004240220013C010001D8
-:1009B00010000023AC226F203C0200800062102453
-:1009C0001040001F3402A0013C0100011000001C77
-:1009D000AC226F203C0200200202102410400007CD
-:1009E00000121940240201003C01000200230821EA
-:1009F000AC229004100000063C020080001211405E
-:100A00003C01000200220821AC2090043C0200803E
-:100A10000202102410400006001219403C0200019E
-:100A20003C0100020023082110000005AC22900CBC
-:100A3000001211403C01000200220821AC20900C61
-:100A40003C0300018C636D982402000110620003D6
-:100A5000000000000C003DAF000000008FBF003020
-:100A60008FB3002C8FB200288FB100248FB00020EC
-:100A700003E0000827BD003827BDFFB0AFB3003C3E
-:100A800000009821AFB500400000A821AFB10034AC
-:100A90000000882124020002AFBF0048AFBE00441E
-:100AA000AFB20038AFB00030AFA4002CA7A0001A3E
-:100AB000A7A00018A7A00020A7A0001EA7A00022A2
-:100AC00010A20130A7A0001C2CA2000310400005BA
-:100AD0002402000110A2000A3C0240001000025D46
-:100AE000022010212402000410A2020A240200089D
-:100AF00010A202080220102110000256000000007F
-:100B00008FA8002C000881403C03000200701821CF
-:100B10008C638FFC0062102414400009240400013F
-:100B20003C027FFF3442FFFF006288243C01000248
-:100B300000300821AC318FF4100002460220102151
-:100B4000240500010C00457C27A6001824040001A0
-:100B5000240500010C00457C27A6001897A2001868
-:100B600030420004104000D93C1140003C0200011A
-:100B70008C426F402443FFFF2C620006104000D9D6
-:100B8000000310803C010001002208218C226C68C7
-:100B900000400008000000002404000124050011AA
-:100BA00027B0001A0C00457C02003021240400010B
-:100BB000240500110C00457C0200302197A3001A87
-:100BC00030624000104000023C1500103C15000847
-:100BD00030628000104000AA3C130001100000A801
-:100BE0003C130002240400012405001427B0001A5D
-:100BF0000C00457C0200302124040001240500146F
-:100C00000C00457C0200302197A3001A30621000CE
-:100C1000104000023C1500103C150008306208002E
-:100C2000104000973C130001100000953C13000297
-:100C3000240400012405001927B0001C0C00457C89
-:100C40000200302124040001240500190C00457C19
-:100C50000200302197A2001C304307002402040048
-:100C600010620027286204011040000E24020200D6
-:100C70001062001F286202011040000524020100DA
-:100C80005062001E3C1300011000001E24040001ED
-:100C900024020300506200193C13000210000019E6
-:100CA00024040001240206001062000D28620601DF
-:100CB00010400005240205005062000B3C130002A6
-:100CC0001000001024040001240207001462000D2B
-:100CD000240400013C1300041000000A3C15000825
-:100CE000100000063C130004100000053C1500082D
-:100CF0003C130001100000023C1500083C150010D8
-:100D0000240400012405001827B0001E0C00457CB7
-:100D10000200302124040001240500180C00457C49
-:100D2000020030218FA8002C97A7001E0008114058
-:100D30003C06000200C230218CC68FF497A200222C
-:100D40003C10000126106C5C02002021AFA20010B4
-:100D500097A2001C3C05000C34A503030C002B3BA0
-:100D6000AFA200143C020004166200103C02000115
-:100D70008F84005424030001240200023C0100017E
-:100D8000AC236D9C3C010001AC226D983C0100013C
-:100D9000AC236DA43C010001AC236E243C01000196
-:100DA000AC246F301000004F02B388251662003962
-:100DB0003C0280003C0200018C426E201440001E68
-:100DC0002404001800002021000028210C004DDB25
-:100DD000340680008F8300548F82005402B388252C
-:100DE00010000002246300328F820054006210233E
-:100DF0002C4200331440FFFC000000008F8300549D
-:100E0000240200013C010001AC226E203C010001E3
-:100E1000AC226D9C3C010001AC226D983C010001AC
-:100E2000AC226DA43C010001AC226E243C01000107
-:100E30001000002CAC236F30000028210C004DDB8B
-:100E400024060404000020212405001E27A6001803
-:100E5000240200020C0045BEA7A2001800002021B9
-:100E60000000282127A600180C0045BEA7A00018E6
-:100E700024040018240500020C004DDB24060004A5
-:100E80003C0280000222102502B318251000001534
-:100E90000043882502221025027518250043882565
-:100EA0000200202197A6001C3C0700018CE76D98EA
-:100EB0003C05000C34A50326AFB300100C002B3BFF
-:100EC000AFB1001410000007000000003C11000248
-:100ED000023088218E318FFC3C027FFF3442FFFFBD
-:100EE000022288243C0200018C426DA81040001EA2
-:100EF000000000003C0200018C426F1C1040000208
-:100F00003C022000022288258FA8002C00081140F6
-:100F10003C010002002208218C22900010400003B6
-:100F20003C02002010000005022288253C02FFDF61
-:100F30003442FFFF022288248FA8002C00081140B1
-:100F40003C010002002208218C229008104000037E
-:100F50003C02008010000004022288253C02FF7F32
-:100F60003442FFFF022288248FA8002C0008114081
-:100F70003C01000200220821AC318FF41000013541
-:100F8000022010218FA8002C0008F1403C03000231
-:100F9000007E18218C638FF83C0240000062102410
-:100FA00014400009240400013C027FFF3442FFFF8B
-:100FB000006288243C010002003E0821AC318FF021
-:100FC0001000012402201021000028210C00457C83
-:100FD00027A6001824040001000028210C00457CED
-:100FE00027A60018240400012405000127B20020D0
-:100FF0000C00457C0240302124040001240500013E
-:101000000C00457C0240302124040001240500042A
-:1010100027B1001E0C00457C022030212404000171
-:10102000240500040C00457C02203021240400012A
-:101030002405000527B000220C00457C0200302169
-:1010400024040001240500050C00457C0200302129
-:1010500024040001240500100C00457C27A600187C
-:1010600024040001240500100C00457C27A600186C
-:10107000240400012405000A0C00457C02403021B4
-:10108000240400012405000A0C00457C02403021A4
-:1010900024040001240500180C00457C02203021A6
-:1010A00024040001240500180C00457C0220302196
-:1010B00024040001240500010C00457C27A600182B
-:1010C00024040001240500010C00457C27A600181B
-:1010D00097A2001830420004104000663C11400006
-:1010E0003C0300018C636F34240200051462006726
-:1010F000240400012405001927B0001C0C00457CC5
-:101100000200302124040001240500190C00457C54
-:101110000200302197A2001C304307002402040083
-:1011200010620027286204011040000E2402020011
-:101130001062001F28620201104000052402010015
-:101140005062001E3C1300011000001E3C0200040F
-:1011500024020300506200193C1300021000001921
-:101160003C020004240206001062000D2862060101
-:1011700010400005240205005062000B3C130002E1
-:10118000100000103C020004240207001462000D4D
-:101190003C0200043C1300041000000A3C15000847
-:1011A000100000063C130004100000053C15000868
-:1011B0003C130001100000023C1500083C15001013
-:1011C0003C020004126200173C0280008F8200542F
-:1011D000241000013C010001AC306D9C3C01000179
-:1011E000AC306D983C010001AC306DA43C010001B5
-:1011F000AC306E243C010001AC226F303C02000197
-:101200001662002202758825000020210000282196
-:101210000C004DDB340680003C0100011000001B77
-:10122000AC306E200222102502B318250043882519
-:1012300097A6001C3C0200018C426F1C3C07000179
-:101240008CE76D983C04000124846C5CAFA2001014
-:1012500097A2001E3C05000C34A503233C010001AD
-:10126000AC206E200C002B3BAFA200141000000736
-:10127000000000003C110002023E88218E318FF0F8
-:101280003C027FFF3442FFFF022288243C0200011F
-:101290008C426DA810400069000000003C02000173
-:1012A0008C426F1C104000023C0220000222882564
-:1012B0008FA8002C000811403C01000200220821E8
-:1012C0008C229004104000033C0200201000000516
-:1012D000022288253C02FFDF3442FFFF02228824DD
-:1012E0008FA8002C000811403C01000200220821B8
-:1012F0008C22900C104000033C0200801000004F34
-:10130000022288253C02FF7F3442FFFF1000004B81
-:10131000022288248FA8002C000829403C030002E8
-:10132000006518218C638FF83C0240000062102495
-:10133000144000083C027FFF3442FFFF0062882413
-:101340003C01000200250821AC318FF01000004163
-:10135000022010213C0200018C426DA81040003494
-:101360003C11C00C3C0200018C426E443C04C00C99
-:10137000348420003C0300018C636F1C0002102B9E
-:10138000000210230044102410600003005188253F
-:101390003C022000022288253C0200020045102168
-:1013A0008C429004104000033C0200201000000416
-:1013B000022288253C02FFDF3442FFFF02228824FC
-:1013C0008FA8002C000811403C01000200220821D7
-:1013D0008C22900C104000033C020080100000049E
-:1013E000022288253C02FF7F3442FFFF022288242C
-:1013F0003C0200018C426E30104000023C020800AA
-:10140000022288253C0200018C426E34104000020A
-:101410003C020400022288253C0200018C426E3806
-:10142000104000063C020100100000040222882542
-:101430003C027FFF3442FFFF006288248FA8002C0B
-:10144000000811403C01000200220821AC318FF05D
-:10145000022010218FBF00488FBE00448FB500408E
-:101460008FB3003C8FB200388FB100348FB00030A2
-:1014700003E0000827BD005027BDFFD0AFB2002811
-:1014800000809021AFBF002CAFB10024AFB000208E
-:101490008F8402003C1000018E106D988F86022010
-:1014A000240200021202005C2E020003104000051C
-:1014B000240200011202000A001219401000010C5F
-:1014C0000000000024020004120200BF24020008F1
-:1014D000120200BE00128940100001050000000049
-:1014E0003C05000200A328218CA58FFC3C100002C3
-:1014F000020380218E108FF43C02400000A21024D1
-:10150000104000383C020008020210241040002065
-:10151000348400023C020002004310218C429000FF
-:101520001040000534840020348401003C02002077
-:1015300010000006020280252402FEFF0082202403
-:101540003C02FFDF3442FFFF020280240012114000
-:101550003C010002002208218C2290081040000566
-:101560003C02000100C230253C0200801000001641
-:10157000020280253C02FFFE3442FFFF00C23024FD
-:101580003C02FF7F3442FFFF1000000F0202802464
-:101590002402FEDF008220243C02FFFE3442FFFFD3
-:1015A00000C230243C02FF5F3442FFFF020280246D
-:1015B0003C01000200230821AC2090003C01000205
-:1015C00000230821AC209008AF840200AF860220DF
-:1015D0008F82022034420002AF8202201000000AF3
-:1015E000001211403C02BFFF3442FFFF8F83020014
-:1015F000020280242402FFFD006218240C003DAF8B
-:10160000AF830200001211403C01000200220821B9
-:10161000100000B7AC308FF43C0200018C426F1C0C
-:101620001040006924050004240400010C00457CDE
-:1016300027A6001824040001240500050C00457CA1
-:1016400027A6001A97A3001897A2001A3C040001CD
-:1016500024846E4830630C0000031A8230420C0070
-:1016600000021282A7A2001A00021080004410217A
-:1016700000431021A7A30018904800002402000195
-:101680003103FFFF106200292862000210400005AC
-:101690000000000010600009000000001000003D84
-:1016A0000000000010700013240200031062002CE0
-:1016B0000000000010000037000000008F820200D0
-:1016C0002403FEFF00431024AF8202008F82022019
-:1016D0003C03FFFE3463FFFF00431024AF8202206F
-:1016E0003C010002AC2090043C01000210000032DA
-:1016F000AC20900C8F82020034420100AF820200C5
-:101700008F8202203C03FFFE3463FFFF004310245E
-:10171000AF820220240201003C010002AC229004AE
-:101720003C01000210000024AC20900C8F820200CB
-:101730002403FEFF00431024AF8202008F820220A8
-:101740003C03000100431025AF8202203C0100024F
-:10175000AC2090043C01000210000017AC23900C58
-:101760008F82020034420100AF8202008F82022089
-:101770003C03000100431025AF8202202402010037
-:101780003C010002AC2290043C0100021000000A5F
-:10179000AC23900C3C04000124846C8097A6001AB2
-:1017A00097A700183C05000134A5FFFFAFA8001063
-:1017B0000C002B3BAFA000148F82020034420002C9
-:1017C0001000004BAF820200001289403C0500026D
-:1017D00000B128218CA58FF83C1000020211802155
-:1017E0008E108FF03C02400000A210241440001024
-:1017F000000000003C0200018C426F1C14400005F8
-:101800003C02BFFF8F82020034420002AF8202001E
-:101810003C02BFFF3442FFFF0C003DAF02028024B8
-:101820003C0100020031082110000031AC308FF083
-:101830003C0200018C426F1C104000053C0200205D
-:101840003C0200018C426E44104000253C02002006
-:1018500000A210241040000734840020240201005C
-:101860003C01000200310821AC2290041000000667
-:10187000348401003C01000200310821AC209004B6
-:101880002402FEFF008220243C02008000A21024DB
-:1018900010400007001219403C0200013C01000208
-:1018A00000230821AC22900C1000000800C2302553
-:1018B000001211403C01000200220821AC20900CD3
-:1018C0003C02FFFE3442FFFF00C23024AF8402001E
-:1018D000AF8602208F82022034420002AF820220B3
-:1018E000001211403C01000200220821AC308FF0B0
-:1018F0008FBF002C8FB200288FB100248FB0002042
-:1019000003E0000827BD003000000000000018219F
-:10191000308400FF2405FFDF2406FFBF00641007AA
-:101920003042000110400004000000008F8200449B
-:1019300010000003344200408F820044004610240F
-:10194000AF8200448F82004434420020AF820044C2
-:101950008F82004400451024AF82004424630001BC
-:10196000286200085440FFEE0064100703E00008FE
-:10197000000000002C8200081040001B0000000046
-:101980002405FFDF2406FFBF000418803C0200018D
-:1019900024426E60006218212464000490620000FA
-:1019A00010400004000000008F820044100000037B
-:1019B000344200408F82004400461024AF8200442D
-:1019C0008F82004434420020AF8200448F82004462
-:1019D00000451024AF820044246300010064102BF2
-:1019E0001440FFEE0000000003E0000800000000CB
-:1019F0000000000000000000000000008F8400C410
-:101A00008F8600E08F8700E42402FFF800C22824BC
-:101A100010E5001A27623FF814E2000224E80008EB
-:101A200027683000550500048D0A000030C200040C
-:101A300014400012008050218CE900008F42013CCC
-:101A4000014948230049182B94EB0006106000025E
-:101A500025630050004948210123182B5040000302
-:101A60008F4201FC03E0000800E01021AF8800E88D
-:101A700024420001AF4201FCAF8800E403E000080B
-:101A80000000102103E00008000000008F8300E444
-:101A900027623FF81062000424620008AF8200E869
-:101AA00003E00008AF8200E427623000AF8200E864
-:101AB00003E00008AF8200E403E00008000000003B
-:101AC0000000000000000000000000008F880120DE
-:101AD00027624FE08F8301281502000225090020AC
-:101AE00027694800112300128FA20010AD040000E6
-:101AF000AD050004AD060008A507000E8FA3001475
-:101B0000AD0200188FA20018AD03001C25030016BB
-:101B1000AD020010AD030014AF8901208F4300FC1B
-:101B2000240200012463FFFF03E00008AF4300FC30
-:101B30008F430324000010212463000103E0000808
-:101B4000AF43032403E00008000000008F88010079
-:101B5000276247E08F830108150200022509002053
-:101B6000276940001123000F8FA20010AD04000070
-:101B7000AD050004AD060008A507000E8FA30014F4
-:101B8000AD0200188FA20018AD03001C250300163B
-:101B9000AD020010AD030014AF89010003E000089E
-:101BA000240200018F430328000010212463000158
-:101BB00003E00008AF43032803E000080000000032
-:101BC00000000000000000000000000024486561E3
-:101BD0006465723A202F70726F6A656374732F7236
-:101BE00063732F73772F67652F2E2F6E69632F66B0
-:101BF00077322F636F6D6D6F6E2F66776D61696ED3
-:101C00002E632C7620312E312E322E343520313970
-:101C100039392F30312F32342030303A31303A35A3
-:101C20003520736875616E67204578702024000048
-:101C3000657674526E674600516576744600000002
-:101C400051657674505F46004D657674526E6746F6
-:101C5000000000004D516576744600004D516576D8
-:101C6000505F46005173436F6E495F4600000000AD
-:101C70005173436F6E734600517250726F64460029
-:101C80006261644D656D537A0000000068775665A7
-:101C900072000000626164487756657200000000BF
-:101CA0002A2A4441574E5F41000000007478527860
-:101CB0004266537A00000000626641746E4D726B9A
-:101CC000000000007265645A6F6E6531000000000C
-:101CD000706369436F6E660067656E436F6E660082
-:101CE0002A646D615244666C000000002A50414E27
-:101CF00049432A002E2E2F2E2E2F2E2E2F2E2E2F02
-:101D00002E2E2F7372632F6E69632F6677322F63C7
-:101D10006F6D6D6F6E2F66776D61696E2E6300005B
-:101D2000726362466C616773000000006261645216
-:101D30007852636200000000676C6F62466C6773E4
-:101D4000000000002B5F646973705F6C6F6F700040
-:101D50002B65765F68616E646C65720063616E749A
-:101D600031446D61000000002B715F646D615F7430
-:101D70006F5F6E69635F636B73756D002B685F7374
-:101D8000656E645F646174615F72656164795F63ED
-:101D90006B73756D000000002B685F646D615F728E
-:101DA000645F6173736973745F636B73756D000057
-:101DB00074436B736D4F6E002B715F646D615F7464
-:101DC0006F5F6E69630000002B685F73656E645F10
-:101DD000646174615F726561647900002B685F649F
-:101DE0006D615F72645F61737369737400000000FA
-:101DF00074436B736D4F6666000000002B685F7361
-:101E0000656E645F62645F72656164790000000002
-:101E10006873745352696E67000000006261645316
-:101E200052696E67000000006E69635352696E6705
-:101E30000000000077446D61416C6C4100000000BF
-:101E40002B715F646D615F746F5F686F73745F6344
-:101E50006B73756D000000002B685F6D61635F72CE
-:101E6000785F636F6D705F636B73756D000000006A
-:101E70002B685F646D615F77725F61737369737400
-:101E80005F636B73756D000072436B736D4F6E0013
-:101E90002B715F646D615F746F5F686F73740000B6
-:101EA0002B685F6D61635F72785F636F6D700000B8
-:101EB0002B685F646D615F77725F617373697374C0
-:101EC0000000000072436B736D4F666600000000F7
-:101ED0002B685F726563765F62645F7265616479C7
-:101EE000000000002B685F726563765F6A756D6243
-:101EF0006F5F62645F726561647900002B685F7276
-:101F00006563765F6D696E695F62645F7265616467
-:101F1000790000002B6D685F636F6D6D616E64000A
-:101F20002B685F74696D6572000000002B685F6448
-:101F30006F5F7570646174655F74785F636F6E73F3
-:101F4000000000002B685F646F5F757064617465EA
-:101F50005F72785F70726F64000000002B636B73B8
-:101F6000756D3136000000002B7065656B5F6D612B
-:101F7000635F72785F7761002B7065656B5F6D6181
-:101F8000635F7278000000002B6465715F6D6163B0
-:101F90005F7278002B685F6D61635F72785F617458
-:101FA000746E0000626164526574537A0000000030
-:101FB000727842644266537A000000002B6E756CA2
-:101FC0006C5F68616E646C657200000066774F70CC
-:101FD0004661696C000000002B685F757064617475
-:101FE000655F6C65643400002B685F7570646174B4
-:101FF000655F6C65643600002B685F7570646174A2
-:10200000655F6C6564320000696E74537461746559
-:10201000000000002A2A696E697443700000000005
-:102020002373637265616D0069537461636B4572FC
-:102030000000000070726F62654D656D0000000069
-:102040002A2A4441574E5F42000000002B73775FFD
-:10205000646D615F6173736973745F706C75735FD6
-:1020600074696D65720000002B267072656C6F617B
-:10207000645F77725F646573637200002B26707211
-:10208000656C6F61645F72645F64657363720000A6
-:102090002B685F68665F74696D65720024486561CE
-:1020A0006465723A202F70726F6A656374732F7261
-:1020B00063732F73772F67652F2E2F6E69632F66DB
-:1020C00077322F636F6D6D6F6E2F74696D65722E31
-:1020D000632C7620312E312E322E33352031393992
-:1020E000392F30312F32372031393A30393A3530C3
-:1020F0002068617965732045787020240000000015
-:10210000657674526E67460051657674460000002D
-:1021100051657674505F46004D657674526E674621
-:10212000000000004D516576744600004D51657603
-:10213000505F46005173436F6E495F4600000000D8
-:102140005173436F6E734600517250726F64460054
-:10215000542D446D6152643200000000542D446DD2
-:102160006152643100000000542D446D615264429C
-:1021700000000000542D446D6157723200000000D1
-:10218000542D446D6157723100000000542D446D90
-:1021900061577242000000000000000024486561A1
-:1021A0006465723A202F70726F6A656374732F7260
-:1021B00063732F73772F67652F2E2F6E69632F66DA
-:1021C00077322F636F6D6D6F6E2F636F6D6D616E04
-:1021D000642E632C7620312E312E322E323820316F
-:1021E0003939392F30312F32302031393A34393AB8
-:1021F000343920736875616E67204578702024003B
-:10220000657674526E67460051657674460000002C
-:1022100051657674505F46004D657674526E674620
-:10222000000000004D516576744600004D51657602
-:10223000505F46005173436F6E495F4600000000D7
-:102240005173436F6E734600517250726F64460053
-:102250003F48636D644D6278000000003F636D6429
-:1022600048737453000000003F636D644D634D6418
-:10227000000000003F636D6450726F6D000000004D
-:102280003F636D644C696E6B000000003F636D64DA
-:1022900045727200000086AC00008E5C00008E5C0F
-:1022A00000008DE400008B7800008E3000008E5C12
-:1022B00000008790000088000000899000008A6874
-:1022C00000008A3400008E5C0000887000008B24BF
-:1022D00000008E5C00008B34000087B4000088246E
-:1022E00000000000000000000000000024486561BC
-:1022F0006465723A202F70726F6A656374732F720F
-:1023000063732F73772F67652F2E2F6E69632F6688
-:1023100077322F636F6D6D6F6E2F6D636173742EE7
-:10232000632C7620312E312E322E38203139393837
-:102330002F31322F30382030323A33363A3336208C
-:10234000736875616E672045787020240000000076
-:10235000657674526E6746005165767446000000DB
-:1023600051657674505F46004D657674526E6746CF
-:10237000000000004D516576744600004D516576B1
-:10238000505F46005173436F6E495F460000000086
-:102390005173436F6E734600517250726F64460002
-:1023A0006164644D63447570000000006164644DB5
-:1023B0006346756C0000000064656C4D634E6F45AC
-:1023C00000000000000000000000000024486561DB
-:1023D0006465723A202F70726F6A656374732F722E
-:1023E00063732F73772F67652F2E2F6E69632F66A8
-:1023F00077322F636F6D6D6F6E2F646D612E632C5E
-:102400007620312E312E322E323420313939382F88
-:1024100031322F32312030303A33333A3039207371
-:102420006875616E67204578702024006576745267
-:102430006E674600516576744600000051657674FB
-:10244000505F46004D657674526E6746000000008E
-:102450004D516576744600004D516576505F4600DB
-:102460005173436F6E495F46000000005173436F24
-:102470006E734600517250726F6446007377446DFC
-:10248000614F66660000000031446D614F6E0000D0
-:102490007377446D614F6E002372446D6141544EF9
-:1024A0000000000072446D6141544E300000000095
-:1024B00072446D6141544E310000000072446D6100
-:1024C000344762002A50414E49432A002E2E2F2EB7
-:1024D0002E2F2E2E2F2E2E2F2E2E2F7372632F6E19
-:1024E00069632F6677322F636F6D6D6F6E2F646D2A
-:1024F000612E63002377446D6141544E000000005B
-:1025000077446D6141544E300000000077446D61A6
-:1025100041544E310000000077446D613447620041
-:102520000000000000000000000000002448656179
-:102530006465723A202F70726F6A656374732F72CC
-:1025400063732F73772F67652F2E2F6E69632F6646
-:1025500077322F636F6D6D6F6E2F74726163652EAE
-:10256000632C7620312E312E322E352031393938F8
-:102570002F30392F33302031383A35303A32382045
-:10258000736875616E672045787020240000000034
-:102590000000000000000000000000002448656109
-:1025A0006465723A202F70726F6A656374732F725C
-:1025B00063732F73772F67652F2E2F6E69632F66D6
-:1025C00077322F636F6D6D6F6E2F646174612E6350
-:1025D0002C7620312E312E322E31322031393939BC
-:1025E0002F30312F32302031393A34393A353120D9
-:1025F000736875616E6720457870202400000000C4
-:1026000046575F56455253494F4E3A202331204694
-:1026100072692041707220372031373A35373A35A8
-:1026200032205044542032303030000046575F434F
-:102630004F4D50494C455F54494D453A2031373A4A
-:1026400035373A353200000046575F434F4D504909
-:102650004C455F42593A206465767263730000000E
-:1026600046575F434F4D50494C455F484F53543A8E
-:1026700020636F6D707574650000000046575F43FE
-:102680004F4D50494C455F444F4D41494E3A2065AE
-:102690006E672E616374656F6E2E636F6D00000050
-:1026A00046575F434F4D50494C45523A206763634C
-:1026B0002076657273696F6E20322E372E320000DD
-:1026C00000000000120411000000000024486561B1
-:1026D0006465723A202F70726F6A656374732F722B
-:1026E00063732F73772F67652F2E2F6E69632F66A5
-:1026F00077322F636F6D6D6F6E2F6D656D2E632C4E
-:102700007620312E312E322E3520313939382F3086
-:10271000392F33302031383A35303A303820736829
-:1027200075616E672045787020240000244865613B
-:102730006465723A202F70726F6A656374732F72CA
-:1027400063732F73772F67652F2E2F6E69632F6644
-:1027500077322F636F6D6D6F6E2F73656E642E63AE
-:102760002C7620312E312E322E3434203139393826
-:102770002F31322F32312030303A33333A31382052
-:10278000736875616E672045787020240000000032
-:10279000657674526E674600516576744600000097
-:1027A00051657674505F46004D657674526E67468B
-:1027B000000000004D516576744600004D5165766D
-:1027C000505F46005173436F6E495F460000000042
-:1027D0005173436F6E734600517250726F644600BE
-:1027E00069736E745463705500000000244865617D
-:1027F0006465723A202F70726F6A656374732F720A
-:1028000063732F73772F67652F2E2F6E69632F6683
-:1028100077322F636F6D6D6F6E2F726563762E63E7
-:102820002C7620312E312E322E3533203139393964
-:102830002F30312F31362030323A35353A3433208B
-:10284000736875616E672045787020240000000071
-:10285000657674526E6746005165767446000000D6
-:1028600051657674505F46004D657674526E6746CA
-:10287000000000004D516576744600004D516576AC
-:10288000505F46005173436F6E495F460000000081
-:102890005173436F6E734600517250726F644600FD
-:1028A000724D616343686B300000000072784672BD
-:1028B0006D324C670000000072784E6F53744264B2
-:1028C0000000000072784E6F4D6942640000000005
-:1028D00072784E6F4A6D4264000000007278436B5C
-:1028E000446D614600000000727851446D457846A1
-:1028F00000000000727851446D61460072785144C6
-:102900004C42644600000000727851446D426446B7
-:1029100000000000727843726350616400000000A0
-:1029200072536D51446D614600000000244865619A
-:102930006465723A202F70726F6A656374732F72C8
-:1029400063732F73772F67652F2E2F6E69632F6642
-:1029500077322F636F6D6D6F6E2F6D61632E632CF9
-:102960007620312E312E322E323220313939382F25
-:1029700031322F30382030323A33363A3330207308
-:102980006875616E67204578702024006576745202
-:102990006E67460051657674460000005165767496
-:1029A000505F46004D657674526E67460000000029
-:1029B0004D516576744600004D516576505F460076
-:1029C0005173436F6E495F46000000005173436FBF
-:1029D0006E734600517250726F6446006D616354AD
-:1029E000687265730000000023744D616341544EAA
-:1029F0000000000023724D616341544E000000004E
-:102A000072656D4173737274000000006C696E6BC7
-:102A1000444F574E000000006C696E6B555000002B
-:102A20000000000000000000000000002448656174
-:102A30006465723A202F70726F6A656374732F72C7
-:102A400063732F73772F67652F2E2F6E69632F6641
-:102A500077322F636F6D6D6F6E2F636B73756D2E95
-:102A6000632C7620312E312E322E392031393939EE
-:102A70002F30312F31342030303A30333A3438204F
-:102A8000736875616E67204578702024000000002F
-:102A9000657674526E674600516576744600000094
-:102AA00051657674505F46004D657674526E674688
-:102AB000000000004D516576744600004D5165766A
-:102AC000505F46005173436F6E495F46000000003F
-:102AD0005173436F6E734600517250726F644600BB
-:102AE00000000000000000000000000050726F6253
-:102AF00065506879000000006C6E6B41535352546E
-:102B000000000000000109A400010A1C00010A5095
-:102B100000010A7C0001105000010AA800010B10FE
-:102B2000000111FC00010DC000010C6800010C80C7
-:102B300000010CC400010CEC00010D0C00010D346F
-:102B4000000111FC00010DC000010DF800010E1084
-:102B500000010E4000010E6800010E8800010EB059
-:102B60000000000000010FDC000110080001102C23
-:102B7000000111FC00011050000110780001110843
-:102B80000000000000000000000000000001186CC0
-:102B90000001193C00011A1400011AE400011B4055
-:102BA00000011C1C00011C4400011D2000011D48E7
-:102BB00000011EF000011F18000120C0000122B812
-:102BC0000001254C000124600001254C00012578FE
-:102BD000000120E8000122907273745F676D6969DB
-:102BE00000000000000126080001264000012728FF
-:102BF00000013374000133B4000133CC7365746C8D
-:102C00006F6F7000000000000000000000013BBC7E
-:102C100000013BFC00013C8C00013CD000013D3434
-:102C200000013DC000013DF400013E7C00013F1465
-:102C300000013FE400014024000140A8000140CC15
-:102C4000000141DC646F4261736550670000000061
-:102C500000000000000000000000000073746D61BF
-:102C6000634C4E4B000000006765746D636C6E6BC7
-:102C70000000000000014ED800014ED800014B8C2E
-:102C800000014BD800014C2400014ED87365746DCF
-:102C90006163616374000000000000000000000038
-:102CA0000000000000000000000000000000000024
-:102CB0000000000000000000000000000000000014
-:102CC0000000000000000000000000000000000103
-:102CD000000000010000000100C001FC00003FFCFA
-:102CE00000C00000416C74656F6E204163654E4901
-:102CF000432056000000000000000000000000001B
-:102D0000000000000000000000000000416C74653D
-:102D10006F6E204163654E49432056004242424255
-:102D2000000000000000000000000000001FFFFC89
-:102D3000001FFF7C000000000000000000000000F9
-:102D40000000000000000000000000000060CF0054
-:102D500000000060CF000000000000000000000044
-:102D60000000000000000000000000000000000063
-:102D70000000000000000000000000000000000053
-:102D80000000000000000000000000000000000043
-:102D90000000000000000000000000000000000033
-:102DA0000000000000000000000000030000000020
-:102DB0000000000100000000000000000000000012
-:102DC0000000000100000000000000010000000001
-:102DD00000000000000000000000000000000001F2
-:102DE00000000001000000000000000000000000E2
-:102DF00000000000000000000100000021000000B1
-:102E0000120001400000000000000000200000004F
-:102E1000120000A0000000001200006012000180FB
-:102E2000120001E0000000000000000000000000AF
-:102E30000000000100000000000000000000000091
-:102E40000000000000000000000000000000000280
-:102E5000000000000000000000030001000000016D
-:102E60000003020100000000000000000101010158
-:102E70000101010000010100010100010001000148
-:0C2E800001000101000001010000000041
-:00000001FF
-/* tg2 firmware v12.4.11 */
--- zfcpdump-kernel-4.4.orig/firmware/adaptec/starfire_rx.bin.ihex
+++ /dev/null
@@ -1,53 +0,0 @@
-:10000000010003DC00000000040004210000008661
-:10001000800000150000180E8100001500006664C5
-:100020001A0040AB00000B06142000110000000075
-:10003000142040220000AAAA14204022000003003D
-:1000400014204022000000001A0040AB00000B14F6
-:1000500014200011000000008300001500000002C1
-:10006000040000210000000000000010000000005B
-:1000700004000421000000870000001000000000C0
-:1000800000000010000000000000801500000000CB
-:100090000000003E00000000000000100000000012
-:1000A0008200001500004000009E8050000000000B
-:1000B000030080150000000086008015000000008D
-:1000C00082000015000080000100001C00000000FC
-:1000D000000050A00000010C4E20D011000060086C
-:1000E0001420D012000040080000F09000007000C2
-:1000F0000000C8B0000030000000404000000000D8
-:10010000001080150000000000A2C1500000400057
-:1001100000A400B000000014000000200000000057
-:100120002500400D0000252500047220000031004C
-:10013000009340700000000000000020000000005C
-:1001400000924460000001842B20C01100000000D8
-:100150000000C42000000540360140180000422D78
-:100160001420001100000000009244600000018390
-:100170003200001F0000003402AC00150000000235
-:1001800000A601100000000842200011000000003D
-:1001900000924060000001030000001E000000000B
-:1001A00000000020000001000000001E0000000010
-:1001B00000924460000000860000408000000000C3
-:1001C0000092C0700000000000924060000001003A
-:1001D0000000C8900000500000A6C1100000000000
-:1001E00000B0C09000000012021C001500000000CA
-:1001F0003200001F0000003400924460000005102F
-:100200004421001100000000420000110000000025
-:1002100083000015000000400092446000000508C3
-:100220004501401800004545008080500000000056
-:10023000622080120000000082000015000008000B
-:100240001520001100000000000000100000000058
-:10025000000000100000000000000010000000007E
-:10026000000000100000000000000010000000006E
-:10027000800000150000EEA4810000150000005F62
-:1002800000000060000000000000412000000000AD
-:1002900000004A000000400000924460000001900D
-:1002A0005601401A000059561400001100000000C9
-:1002B0000093405000000018009300500000001808
-:1002C0003601403A0000002D000643A9000000005E
-:1002D0000000C420000001405601401A0000595699
-:1002E00014000011000000000000001000000000D9
-:1002F0000000001000000000000642A900000000FD
-:1003000000024420000001835601401A00005956A3
-:1003100082000015000020001520001100000000E0
-:1003200082000015000000101520001100000000E0
-:1003300082000015000000101520001100000000D0
-:00000001FF
--- zfcpdump-kernel-4.4.orig/firmware/adaptec/starfire_tx.bin.ihex
+++ /dev/null
@@ -1,53 +0,0 @@
-:10000000010003DC00000000040004210000008661
-:10001000800000150000180E8100001500006664C5
-:100020001A0040AB00000B06142000110000000075
-:10003000142040220000AAAA14204022000003003D
-:1000400014204022000000001A0040AB00000B14F6
-:1000500014200011000000008300001500000002C1
-:10006000040000210000000000000010000000005B
-:1000700004000421000000870000001000000000C0
-:1000800000000010000000000000801500000000CB
-:100090000000003E00000000000000100000000012
-:1000A0008200001500004000009E8050000000000B
-:1000B000030080150000000086008015000000008D
-:1000C00082000015000080000100001C00000000FC
-:1000D000000050A00000010C4E20D011000060086C
-:1000E0001420D012000040080000F09000007000C2
-:1000F0000000C8B0000030000000404000000000D8
-:10010000001080150000000000A2C1500000400057
-:1001100000A400B000000014000000200000000057
-:100120002500400D0000252500047220000031004C
-:10013000009340700000000000000020000000005C
-:1001400000924460000001842B20C01100000000D8
-:100150000000C42000000540360140180000422D78
-:100160001420001100000000009244600000018390
-:100170003200001F0000003402AC00150000000235
-:1001800000A601100000000842200011000000003D
-:1001900000924060000001030000001E000000000B
-:1001A00000000020000001000000001E0000000010
-:1001B00000924460000000860000408000000000C3
-:1001C0000092C0700000000000924060000001003A
-:1001D0000000C8900000500000A6C1100000000000
-:1001E00000B0C09000000012021C001500000000CA
-:1001F0003200001F0000003400924460000005102F
-:100200004421001100000000420000110000000025
-:1002100083000015000000400092446000000508C3
-:100220004501401800004545008080500000000056
-:10023000622080120000000082000015000008000B
-:100240001520001100000000000000100000000058
-:10025000000000100000000000000010000000007E
-:10026000000000100000000000000010000000006E
-:10027000800000150000EEA4810000150000005F62
-:1002800000000060000000000000412000000000AD
-:1002900000004A000000400000924460000001900D
-:1002A0005601401A000059561400001100000000C9
-:1002B0000093405000000018009300500000001808
-:1002C0003601403A0000002D000643A9000000005E
-:1002D0000000C420000001405601401A0000595699
-:1002E00014000011000000000000001000000000D9
-:1002F0000000001000000000000642A900000000FD
-:1003000000024420000001835601401A00005956A3
-:1003100082000015000020001520001100000000E0
-:1003200082000015000000101520001100000000E0
-:1003300082000015000000101520001100000000D0
-:00000001FF
--- zfcpdump-kernel-4.4.orig/firmware/advansys/3550.bin.ihex
+++ /dev/null
@@ -1,317 +0,0 @@
-:10000000DD2DD504000000F200F0001618E400FC1D
-:10001000010048E4BE18188003F6020000FAFFFF52
-:10002000280E9EE7FF0082E700EA00F601E609E7F6
-:1000300055F001F601FA08000300040018F410005E
-:1000400000EC85F0BC00D5F08E0C385400E61EF0B4
-:1000500086F0B4009857D0010C1C3E1C0C00BB006D
-:10006000AA18028032F001FC880CC6120213184054
-:10007000005701EA3C006C016E0104123E570080FB
-:1000800003E6B600C00001013E01DA0F221008129B
-:10009000024AB95403581B8030E44BE4200032007C
-:1000A0003E00800024013C0168016A017001720178
-:1000B000740176017801620A920C2C102E1006133E
-:1000C0004C1CBB553C5604804AE402EE5BF0B1F098
-:1000D00003F706F703FC0F004000BE000001B00864
-:1000E00030136415321C381C4E1C10440248004C5E
-:1000F00004EA5DF004F602FC0500340036009800C6
-:10010000CC0020014E014E0B1E0E0C100A120413DF
-:100110004013301C004EBD56068300DC05F009F08C
-:1001200059F0A7F0B8F00EF70600190033009B0055
-:10013000A400B500BA00D000E100E700DE03560AD3
-:10014000140E021004100A1036100A131213521360
-:1001500010151415AC16201C341C361C08443844E9
-:1001600091440A454846014868548355B0570158A0
-:10017000835905E60BF00CF05CF04BF404F805F83D
-:1001800002FA03FA04FC05FC07000A000D001C003B
-:100190009E00A800AA00B900E00022012601790112
-:1001A0007A01C001C2017C025A03EA04E807680828
-:1001B0006908BA08E909060B3A0E00101A10ED108A
-:1001C000F11006120C1316131E1382134214D614C8
-:1001D0008A15C617D2176B18121C461C9C32004099
-:1001E0000E47484741488948804C00544455E555DE
-:1001F00014567757BF57405C0680089003A1FE9CB9
-:10020000F02902FEB80CFF100000D0FECC1800CF81
-:10021000FE8001FF030000FE9315FE0F05FF38006E
-:1002200000FE572400FE48004FFF04000010FF09A5
-:100230000000FF080101FF08FFFFFF270000FF107B
-:10024000FFFFFF0F0000FE7856FE3412FF21000072
-:10025000FE04F7CF2A670B01FECE0EFE04F7CF6730
-:100260000B3C2AFE3DF0FE0202FE20F09CFE91F0C7
-:10027000FEF001FE90F0FEF001FE8FF09C05513B78
-:1002800002FED40C01FE440DFEDD12FEFC10FE2821
-:100290001C05FEA600FED3124718FEA600B5FE48B8
-:1002A000F0FE8602FE49F0FEA002FE4AF0FEBE020B
-:1002B000FE46F0FE5002FE47F0FE5602FE43F0FE00
-:1002C0004402FE44F0FE4802FE45F0FE4C02170BCD
-:1002D000A0170618960229FE001CDEFE021CDDFE99
-:1002E0001E1CFEE91001FE2017FEE710FE06FCC7EB
-:1002F0000A6B019E0229144D379701FE640F0A6BA9
-:100300000182FEBD100A6B0182FEAD10FE161CFEBE
-:10031000581C170618962A2529FE3DF0FE020221D8
-:10032000FE9402FE5A1CEAFE141C14FE300037979D
-:1003300001FE540F1706189602D01E20071034FE37
-:10034000691017061896FE04EC20463D1220FE05A3
-:10035000F6C701FE5216094A4C35112D3C8A01E6BA
-:1003600002290A40010E07005D016FFE1810FE41D0
-:10037000580A99010EFEC85464FE0C0301E60229D6
-:100380002A46FE02E827F8FE9E43F7FE27F0FEDC31
-:1003900001FE074BFE20F09CFE401C25D2FE26F0FD
-:1003A000FE5603FEA0F0FE4403FE11F09CFEEF108B
-:1003B000FE9FF0FE6403EB0FFE1100025A2AFE4876
-:1003C0001CEB09041DFE1813231E98AC12980A405A
-:1003D000010EAC7501FEBC1511CA25D2FE01F0D28A
-:1003E000FE82F0FE9203EC11FEE40065FEA40325FC
-:1003F000321FFEB4030143FE06F0FEC4038D81FEEE
-:100400000AF0FE7A060222056B2816FEF604142C6A
-:1004100001338FFE660202D1EB2A671AFE671BF8D2
-:10042000F7FE481C70016E870A40010E070016D3C4
-:100430000ACA010E7460597627056B28FE10121443
-:100440002C01338FFE660202D1BC7DBD7F25226563
-:10045000FE3C041FFE380468FEA000FE9B57FE4EC3
-:10046000122BFF02001001081FFEE0042B01081FE1
-:1004700022302ED5FE4C44FE4C1260FE4448132C14
-:10048000FE4C5464D3467627FAEFFE621309041D2E
-:10049000FE2A132F077EA5FE2010132CFE4C546459
-:1004A000D3FAEF8609041DFE08132F077E6E090498
-:1004B0001DFE1C1214920904063B14C401338FFE66
-:1004C000700C02222B11FEE600FE1C90F903149220
-:1004D00001330229FE425B671AFE4659F8F7FE8790
-:1004E00080FE31E44F09040BFE7813FE2080071ACA
-:1004F000FE7012490406FE601305FEA2002816FED7
-:100500008005FE31E46A49040BFE4A1305FEA00093
-:1005100028FE42125E01082532F1010826FE9805E8
-:1005200011FEE3002349FE4AF0FE6A05FE49F0FE93
-:1005300064058324FE2100A124FE2200A0244CFE99
-:100540000948010826FE9805FEE2084904C53B015A
-:1005500086240612CC37FE270109041DFE2212470D
-:1005600001A714920904063B14C401338FFE700CDA
-:10057000022205FE9C0028FE3E12055028FE36137E
-:100580004701A726FE08060A06490419FE02125F63
-:1005900001FEAA141FFEFE05119A014311FEE5009B
-:1005A0000550B40C5005C628FE6212053F28FE5ABD
-:1005B0001301FE141801FE6618FE4348B719136CA8
-:1005C000FF020057488B1C3D85B7694701A726FEEF
-:1005D000720649041BDF890A4D01FED8141FFE680C
-:1005E00006119A014311FEE500053FB40C3F1706C2
-:1005F00001A7EC7270016E8711FEE200010825323E
-:10060000FE0AF0FEA6068CFE5C07FE06F0FE6407FE
-:100610008D81022209040BFE2E12151A0108150005
-:1006200001081500010815000108FE99A40108152C
-:100630000002FE320861041BFE381209041B6E150D
-:10064000FE1B000108150001081500010815000136
-:100650000815060108150002D9664CFE3A555FFEE2
-:100660009A814B1DBAFE32070A1DFE096FAFFECA02
-:1006700045FE3212622C85667B01082532FE0AF0A7
-:10068000FE32078D818CFE5C070222014302FE8A46
-:1006900006151902FE8A06FE9CF7D4FE2C90FEAECB
-:1006A0009077FECA070C541855094A6A351E200770
-:1006B00010FE0E1274FE808037206327FE0610FEA7
-:1006C00083E7C4A1FE0340094A4F3501A8ADFE1FD0
-:1006D00040125801A5FE0850FE8A50FE4451FEC645
-:1006E0005183FBFE8A900C521853FE0C90FE8E90A4
-:1006F000FE4050FEC2500C39183AFE4A1009046AF6
-:10070000FE2A12FE2C90FEAE900C54185509044F90
-:100710008501A8FE1F801258FE4490FEC6900C561C
-:100720001857FBFE8A900C521853FE4090FEC29060
-:100730000C39183A0C38184E094A19352A13FE4E4E
-:100740001165FE4808FE9EF0FE5C08B116322A7361
-:10075000DDB8FE8008B9FE9E088CFE7408FE06F027
-:10076000FE7A088D8102220143FEC9101519FEC9C7
-:1007700010610406FE101261040B4509040BFE68AB
-:1007800012FE2E1C02FE240A6104064561040BFEC3
-:100790005212FE2C1CFEAAF0FE1E09FEACF0FEBE9C
-:1007A00008FE8A10AAFEF310FEADF0FECA0802FE93
-:1007B000240AABFEE710FE2BF09DE91CFE00FEFEB6
-:1007C0001C12B5FED2F09DFE76181C1A169D05CBA4
-:1007D0001C06169DB86DB96DAAABFEB110705E2BEC
-:1007E000149201330FFE3500FE01F05A0F7C025ABD
-:1007F000FE74181CFE00F8166D671B01FE440D3BCD
-:1008000001E61E2774671A026D09040B21FE060A11
-:1008100009046AFE8212090419FE66131E58ACFC14
-:10082000FE8380FEC844FE2E13FE0491FE86916373
-:1008300027FE4059FEC15977D7055431550C7B1816
-:100840007CBE54BF5501A8AD63271258C038C14EB5
-:1008500079566857F4F5FE04FA38FE05FA4E01A5FC
-:10086000A2230C7B0C7C79566857FE1210090419E0
-:1008700016D77939683A0904FEF700350552315325
-:10088000FE1058FE9158FE1459FE9559026D090448
-:100890001916D70904FEF70035FE3A55FE19815F97
-:1008A000FE1090FE9290FED7102F079B16FEC608F2
-:1008B000119B09040BFE14130539313A77FEC60863
-:1008C000FE0C58FE8D58026D2347FE1980DE090488
-:1008D0000BFE1A12FE6C19FE1941E9B5FED1F0D9D2
-:1008E000147A01330FFE4400FE8E10FE6C19BE39DF
-:1008F000FEED19BF3AFE0C51FE8E51E91CFE00FFC1
-:1009000034FE7410B5FED2F0FEB20AFE76181C1A40
-:100910008405CB1C06FE08130FFE1600025AFED1FA
-:10092000F0FEC40A147A01330FFE1700FE4210FED7
-:10093000CEF0FECA0AFE3C10FECDF0FED60A0FFE37
-:100940002200025AFECBF0FEE20A0FFE2400025AF9
-:10095000FED0F0FEEC0A0F93DCFECFF0FEF60A0F9D
-:100960004CFE1010FECCF0D96104193B0FFE1200B2
-:100970002A13FE4E1165FE0C0BFE9EF0FE200BB1FD
-:1009800016322A73DDB822B9222AEC65FE2C0B251B
-:10099000328CFE480B8D81B8D4B9D402220143FEBB
-:1009A000DB1011FEE800AAAB70BC7DBD7FFE89F0B4
-:1009B00022302ED8BC7DBD7F01081F22302ED6B13B
-:1009C000450FFE4200025A7806FE814916FE380C99
-:1009D00009040BFE44130F004B0BFE54124BFE2870
-:1009E0000021FEA60C0A40010E07005D3EFE280015
-:1009F000FEE21001E701E80A9901FE320E59112DBD
-:100A0000016F02290FFE44004B0BDF3E0BFEB410BA
-:100A100001863E0BFEAA100186FE1982FE3446A313
-:100A20003E0B0FFE4300FE9610094A0B3501E7010D
-:100A3000E859112D016F670B593C8A02FE2A030900
-:100A4000040B843E0B0F00FE5C1061041BFE581269
-:100A500009041BFE5013FE1C1CFE9DF0FE5C0CFEE8
-:100A60001C1CFE9DF0FE620C094A1B35FEA9100FEE
-:100A7000FE1500FE04E60B5F5C0FFE1300FE101077
-:100A80000FFE4700A10FFE4100A00FFE240087AA21
-:100A9000AB70056B2821D15FFE04E61BFE9D41FE75
-:100AA0001C425901DA0229EA140B3795A914FE31C8
-:100AB00000379701FE540F02D03CFE06ECC9EE3E13
-:100AC0001DFECE45343CFE06EAC9FE474B89FE7545
-:100AD000570551FE9856FE38120A42010EFE444850
-:100AE0004609041DFE1A130A40010E47FE41580A2A
-:100AF00099010EFE49548EFE2A0D02FE2A030A5168
-:100B0000FEEE14EE3E1DFECE45343CFECE47FEAD5D
-:100B10001302291E200710FE9E1223124D1294125A
-:100B2000CE1E2D47372DB1E0FEBCF0FEEC0D1306B6
-:100B3000124D01FEE21505FE380131FE3A0177FE45
-:100B4000F00DFE02ECCE62005DFE04EC2046FE05D8
-:100B5000F6FE340101FE5216FBFE48F40DFE18139A
-:100B6000AFFE02EACE627AFEC513141B3795A95C6C
-:100B700005FE38011CFEF0FF0CFE600105FE3A0187
-:100B80000CFE62013D12202406122D112D8A13063F
-:100B90000323031E4DFEF7121E94AC1294077AFE37
-:100BA0007113FE241C141A3795A9FED910B6FE0342
-:100BB000DCFE7357FE805D03B6FE03DCFE5B57FE72
-:100BC000805D03FE0357B623FE00CC03FE0357B639
-:100BD000750309044CFE2213FE1C800706FE1A133F
-:100BE000FE1E80E1FE1D80A4FE0C90FE0E13FE0E84
-:100BF00090A3FE3C90FE30F40BFE3C50A001FE8220
-:100C0000162F072DE001FEBC1509041D4501E70163
-:100C1000E811FEE90009044CFE2C1301FE1416FE37
-:100C20001E1CFE1490FE96900CFE640118FE6601D8
-:100C300009044FFE1212FE038074FE01EC20FE80B8
-:100C4000401220632711C8591E20ED762003FE08AC
-:100C50001C05FEAC00FE065805FEAE00FE0758055A
-:100C6000FEB000FE085805FEB200FE0958FE0A1C40
-:100C7000246912C9230C500C3F1340485F171DFE16
-:100C8000904DFE915421FE080F3E10134248174C20
-:100C9000FE904DFE915421FE1E0F24101220782C40
-:100CA000461E20ED762011C8F6FED6F0FE320FEA81
-:100CB00070FE141CFE101CFE181C033CFE0C14EEEF
-:100CC000FE07E61DFECE47FEF513030186782C468F
-:100CD000FAEFFE42132F072DFE34130A42010EB025
-:100CE000FE3612F0FE454801E3FE00CCB0FEF313E1
-:100CF0003D750710A30A80010EFE805C016FFE0E99
-:100D000010077E45F6FED6F0FE6C0F03FE445874C5
-:100D1000FE01EC97FE9E40FE9DE700FE9CE71B76E1
-:100D20002701DAFEDD102ABC7DBD7F302ED5071BE2
-:100D3000FE4812070BFE5612071AFE301207C216A3
-:100D4000FE3E1107FE230016FE4A11070616FEA8F6
-:100D5000110719FE12120700162214C201339F2B2D
-:100D600001088C43032BFE62080ACA01FE320E11F1
-:100D70007E02292B2F079BFED9137939683A77FE1B
-:100D8000FC1009046AFE7212C038C14EF4F58EFEE2
-:100D9000C6101E58FE2613057B317C77FE820C0C94
-:100DA000541855230C7B0C7C01A82469731258013C
-:100DB000A5C038C14EFE0455FEA555FE04FA38FE06
-:100DC00005FA4EFE911005563157FE4056FEE1568B
-:100DD0000C56185783C038C14EF4F505523153FEF6
-:100DE0000056FEA1560C52185309046AFE1E121E2C
-:100DF00058FE1F4005543155FE2C50FEAE5005568E
-:100E00003157FE4450FEC65005523153FE0850FE85
-:100E10008A500539313AFE4050FEC250025C240629
-:100E200012CD025B2B01081F44302ED5070621444A
-:100E30002F079B215B016E1C3D164409040BE279D0
-:100E400039683AFE0A5534FE8B55BE39BF3AFE0C5E
-:100E500051FE8E51025BFE1981AFFE1941025B2BE0
-:100E6000010825321FA2302ED84B1AFEA6124B0BBA
-:100E70003B0244010825321FA2302ED6071A214416
-:100E800001081FA2302EFEE809FEC2496005FE9C43
-:100E9000002884490419349FFEBB454B00453E069B
-:100EA000783DFEDA14016E87FE4B45E22F079AE18A
-:100EB00005C62884053F28345E025BFEC05DFEF84F
-:100EC00014FE03170550B40C505E2B0108265C017C
-:100ED000FEAA14025C010825321F44302ED60706F4
-:100EE000214401FE8E13FE4258FE8214FEA4148794
-:100EF000FE4AF40B1644FE4AF406FE0C122F079A23
-:100F000085025B053FB40C3F5E2B0108265C01FEA9
-:100F1000D814025C130665FECA1226FEE01272F1B6
-:100F200001082372038FFEDC1225FEDC121FFECAAD
-:100F3000125E2B0108FED510136CFF020057488B80
-:100F40001CFEFF7FFE3056FE005C03136CFF0200A8
-:100F500057488B1C3DFE3056FE005C03136CFF02AD
-:100F60000057488B03136CFF020057488BFE0B5849
-:100F7000030A5001820A3F018203FC1C10FF030098
-:100F800054FE00F41948FE007DFE017DFE027DFE48
-:100F9000037C63270C521853BE56BF5703FE6208EA
-:100FA000FE824AFEE11AFE835A740301FE1418FE03
-:100FB00042485F608901081FFEA214302ED8010844
-:100FC0001FFEA214302EFEE80AFEC15905C628FEF7
-:100FD000CC1249041BFEC41323621BE24BC364FE04
-:100FE000E8133B130617C378DBFE7810FF02835526
-:100FF000A1FF028355621AA4BBFE30008EE4172CB9
-:101000001306FE5610620BE1BBFE64008EE40AFE7E
-:10101000640017931306FE28106206FE6013BBFEE1
-:10102000C8008EE40AFEC800174D130683BBFE906D
-:1010300001BAFE4E1489FE1210FE43F494FE56F0DF
-:10104000FE6014FE04F46CFE43F493FEF310F90109
-:10105000FE22131C3DFE1013FE0017FE4DE469BA7C
-:10106000FE9C14B769FE1C10FE0017FE4DE419BA71
-:10107000FE9C14B719836023FE4DF400DF8913062C
-:10108000FEB456FEC3580360130B03150601082671
-:10109000E5150B010826E5151A010826E572FE89FB
-:1010A000490108031506010826A6151A010826A6F7
-:1010B0001506010826A6FE8949010826A672FE89A2
-:1010C0004A01080360031ECC0706FE4413AD12CC90
-:1010D000FE49F4003B729F5EFE01ECFE2701F10128
-:1010E000082F07FEE300FE20131FFE5A152312CD22
-:1010F00001431ECD070645094A0635030A42010E83
-:10110000ED880710A40A80010E880A51019E030A87
-:1011100080010E88FE80E710071084FE455801E329
-:1011200088030A42010E880A51019E030A42010EF9
-:10113000FE8080F2FE49E410A40A80010EF20A51FA
-:1011400001820317107166FE6001FE18DFFE19DED2
-:10115000FE241CFE1DF71D90FEF61501FEFC16E098
-:10116000911D66FE2C01FE2F1903AE21FEE615FE31
-:10117000DA1017107105FE6401FE00F419FE18580C
-:1011800005FE6601FE19589119FE3C90FE30F406EA
-:10119000FE3C5066FE3800FE0F79FE1CF71990FEEB
-:1011A0004016FEB6143403AE21FE1816FE9C10172E
-:1011B0001071FE835AFE18DFFE19DEFE1DF738900F
-:1011C000FE6216FE9414FE10139138661BFEAF19D2
-:1011D000FE98E70003AE21FE5616FE6C1017107144
-:1011E000FE30BCFEB2BC91C5661BFE0F79FE1CF73B
-:1011F000C590FE9A16FE5C143403AE21FE8616FEE0
-:101200004210FE02F61071FE18FE54FE19FE55FC47
-:10121000FE1DF74F90FEC016FE3614FE1C13914FB4
-:1012200047FE8358FEAF19FE80E710FE81E71011DC
-:10123000FEDD006327036327FE124521FEB016146E
-:10124000063795A90229FE39F0FE04172303FE7E16
-:10125000181C1A5D130D037105CB1C06FEEF12FE60
-:10126000E110782C462F072DFE3C13FE8214FE421F
-:10127000133C8A0A42010EB0FE3E12F0FE454801C0
-:10128000E3FE00CCB0FEF3133D750710A30A800106
-:101290000EF2016FFE1610077E85FE4014FE24122A
-:1012A000F6FED6F0FE2417170B03FE9CE70B0FFE8D
-:1012B000150059762701DA1706033C8A094A1D35BD
-:1012C000112D016F170603FE3890FEBA9079C7689A
-:1012D000C8FE485534FEC955031E98731298030A78
-:1012E00099010EF00A40010EFE494416FEF01773F4
-:1012F00075030A42010E0710450A51019E0A40017A
-:101300000E737503FE4EE41A64FE241805FE900069
-:10131000FE3A455BFE4EE4C264FE361805FE9200BE
-:10132000FE02E61BDCFE4EE4FE0B0064FE481805E0
-:10133000FE9400FE02E619FE081005FE9600FE026D
-:10134000E62CFE4E45FE0C12AFFF046854DE1C690D
-:1013500003077AFE5AF0FE741824FE0900FE3410CA
-:10136000071BFE5AF0FE821824C3FE2610071A5DE2
-:10137000242CDC070B5D2493FE0E1007065D244D24
-:101380009FAD0314FE09000133FE04FE7D057FF9C5
-:101390000325FECA18FE14F00865FEC61803FF1ADE
-:0213A00000004B
-:00000001FF
-/* Microcode buffer is kept after initialization for error recovery. */
--- zfcpdump-kernel-4.4.orig/firmware/advansys/38C0800.bin.ihex
+++ /dev/null
@@ -1,336 +0,0 @@
-:10000000D83F0D05000000F200F000FC001618E4D7
-:10001000010048E4188003F60200CE1900FAFFFF41
-:100020001C0F00F69EE7FF0082E700EA01FA01E6F6
-:1000300009E755F001F60300040010001EF085F0FA
-:1000400018F40800BC00385400ECD5F0820D00E62E
-:1000500086F0B1F0985701FCB400D4010C1C3E1C92
-:100060003C00BB000010BA19028032F07C0D021374
-:10007000BA131840005701EA02FC03FC3E006C0171
-:100080006E0174017601B9543E57008003E6B60054
-:10009000C00001013E017A01CA08CE1016110412F7
-:1000A0000812024ABB553C5603581B8030E44BE40F
-:1000B0005DF002FA200032004000800024013C0183
-:1000C00068016A017001720178017C01620A860D83
-:1000D00006134C1C04804AE402EE5BF003F70C00AC
-:1000E0000F004700BE00000120115C16321C381CB6
-:1000F0004E1C1044004C04EA5CF0A7F004F603FA2E
-:100100000500340036009800CC0020014E014A0B57
-:10011000420C120F0C1022110A120413301C024858
-:10012000004E42544455BD56068300DC05F009F0EC
-:1001300059F0B8F04BF406F70EF704FC05FC060086
-:10014000190033009B00A400B500BA00D000E10004
-:10015000E700E203080F021004100A100A130C1340
-:1001600012132414341404160816A417201C341C6B
-:10017000361C0844384491440A45484601486854AE
-:100180003A558355E555B0570158835905E60BF0AC
-:100190000CF004F805F807000A001C001E009E0081
-:1001A000A800AA00B900E0002201260179017E0121
-:1001B000C401C60180025E03EE049A06F8076208D5
-:1001C00068086908D608E909FA0B2E0F12101A10F0
-:1001D000ED10F1102A1106120C123E121013161314
-:1001E0001E134614761482143615CA156B18BE18E1
-:1001F000CA18E619121C461C9C3200400E47FE9C91
-:10020000F02B02FEAC0DFF100000D7FEE81900D65F
-:10021000FE8401FF030000FE9315FE0F05FF38006A
-:1002200000FE572400FE4C005BFF04000011FF0994
-:100230000000FF080101FF08FFFFFF270000FF107B
-:10024000FFFFFF110000FE7856FE3412FF21000070
-:10025000FE04F7D62C990A01FEC20FFE04F7D699C8
-:100260000A422CFE3DF0FE0602FE20F0A7FE91F0B1
-:10027000FEF401FE90F0FEF401FE8FF0A7035D4D49
-:1002800002FEC80D01FE380EFEDD12FEFC10FE2837
-:100290001C03FEA600FED3124114FEA600C2FE48B7
-:1002A000F0FE8A02FE49F0FEA402FE4AF0FEC202FF
-:1002B000FE46F0FE5402FE47F0FE5A02FE43F0FEF8
-:1002C0004802FE44F0FE4C02FE45F0FE5002180AC1
-:1002D000AA180614A1022BFE001CE7FE021CE6FE73
-:1002E0001E1CFEE91001FE1818FEE710FE06FCCEEB
-:1002F000097001A8022B155939A201FE5810097086
-:100300000187FEBD1009700187FEAD10FE161CFEB0
-:10031000581C180614A12C1C2BFE3DF0FE060223CF
-:10032000FE9802FE5A1CF8FE141C15FE300039A27D
-:1003300001FE4810180614A102D72220071135FE2D
-:100340006910180614A1FE04EC204F431320FE058B
-:10035000F6CE01FE4A1708545837122F429201FE7A
-:100360008216022B0946010E0700660173FE181063
-:10037000FE415809A4010EFEC8546BFE100301FE95
-:100380008216022B2C4FFE02E82AFEBF57FE9E4328
-:10039000FE7757FE27F0FEE001FE074BFE20F0A798
-:1003A000FE401C1CD9FE26F0FE5A03FEA0F0FE48BB
-:1003B00003FE11F0A7FEEF10FE9FF0FE6803F91098
-:1003C000FE110002652CFE481CF908051BFE1813DF
-:1003D0002122A3B713A30946010EB77801FEB41674
-:1003E00012D11CD9FE01F0D9FE82F0FE9603FA125A
-:1003F000FEE40027FEA8031C341DFEB803014BFEDB
-:1004000006F0FEC8039586FE0AF0FE8A0602240363
-:10041000702817FEFA04156D01367BFE6A0202D8B9
-:10042000F92C9919FE671BFEBF57FE7757FE481C33
-:100430007401AF8C0946010E070017DA09D1010ECD
-:100440008D5164792A037028FE1012156D01367BD8
-:10045000FE6A0202D8C781C8831C2427FE40041DFF
-:10046000FE3C043BFEA000FE9B57FE4E122DFF02F9
-:100470000010010B1DFEE4042D010B1D243331DEA1
-:10048000FE4C44FE4C1251FE44480F6FFE4C546B20
-:10049000DA4F792AFE0680FE4847FE621308051BE4
-:1004A000FE2A13320782FE5213FE20100F6FFE4CFD
-:1004B000546BDAFE0680FE4847FE401308051BFE1B
-:1004C0000813320782FE301308051BFE1C12159D0F
-:1004D0000805064D15FE0D0001367BFE640D022455
-:1004E0002D12FEE600FE1C90FE405C04159D0136B8
-:1004F000022BFE425B9919FE4659FEBF57FE775705
-:10050000FE8780FE31E45B08050AFE8413FE20802E
-:100510000719FE7C12530506FE6C1303FEA2002889
-:1005200017FE9005FE31E45A53050AFE561303FEEA
-:10053000A00028FE4E1267FF02001027FE48051C8F
-:1005400034FE8948FF02001027FE560526FEA80546
-:1005500012FEE3002153FE4AF0FE7605FE49F0FE4E
-:1005600070058825FE2100AB25FE2200AA2558FE35
-:100570000948FF02001027FE860526FEA805FEE2B8
-:10058000085305CB4D01B0250613D339FE270108CA
-:10059000051BFE22124101B2159D0805064D15FEF0
-:1005A0000D0001367BFE640D022403FE9C0028EB47
-:1005B000035C28FE36134101B226FE1806090653D5
-:1005C000051FFE02125001FE9E151DFE0E0612A50D
-:1005D000014B12FEE500035CC10C5C03CD28FE62FA
-:1005E00012034528FE5A1301FE0C1901FE7619FE6E
-:1005F0004348C4CC0F71FF02005752931E438BC473
-:100600006E4101B226FE820653051AE9910959018D
-:10061000FECC151DFE780612A5014B12FEE5000367
-:1006200045C10C45180601B2FA767401AF8C12FE72
-:10063000E20027DB1C34FE0AF0FEB60694FE6C07CF
-:10064000FE06F0FE74079586022408050AFE2E12A7
-:100650001619010B1600010B1600010B1600010BF9
-:10066000FE99A4010B160002FE420868051AFE3826
-:100670001208051AFE301316FE1B00010B160001AE
-:100680000B1600010B1600010B1606010B160002DB
-:10069000E26C58BE50FE9A81551B7AFE4207091B38
-:1006A000FE096FBAFECA45FE3212696D8B6C7F2758
-:1006B000FE54071C34FE0AF0FE4207958694FE6C39
-:1006C000070224014B02DB161F02DBFE9CF7DCFE57
-:1006D0002C90FEAE9056FEDA070C60146108545A56
-:1006E0003722200711FE0E128DFE808039206A2AE3
-:1006F000FE0610FE83E7FE4800ABFE034008545B95
-:100700003701B3B8FE1F40136201EFFE0850FE8AA6
-:1007100050FE4451FEC65188FE0890FE8A900C5E41
-:10072000145FFE0C90FE8E90FE4050FEC2500C3DB9
-:10073000143EFE4A1008055AFE2A12FE2C90FEAE08
-:10074000900C60146108055B8B01B3FE1F8013627F
-:10075000FE4490FEC6900C3F1440FE0890FE8A9026
-:100760000C5E145FFE4090FEC2900C3D143E0C2EB9
-:10077000143C210C490C6308541F372C0FFE4E11FA
-:1007800027DDFE9EF0FE7608BC17342C77E6C5FE0A
-:100790009A08C6FEB80894FE8E08FE06F0FE94087D
-:1007A00095860224014BFEC910161FFEC91068056C
-:1007B00006FE101268050A4E08050AFE9012FE2E6B
-:1007C0001C02FE180B6805064E68050AFE7A12FE2A
-:1007D0002C1CFEAAF0FED209FEACF0FE000902FEBF
-:1007E000DE09FEB7F0FEFC08FE02F61A50FE701895
-:1007F000FEF118FE4055FEE155FE1058FE9158FEE0
-:100800001459FE95591C85FE8CF0FEFC08FEACF0D8
-:10081000FEF008B5FECB10FEADF0FE0C0902FE188E
-:100820000BB6FEBF10FE2BF085F41EFE00FEFE1C74
-:1008300012C2FED2F085FE76181E19178503D21E4D
-:10084000061785C54AC64AB5B6FE891074672D15C8
-:100850009D013610FE3500FE01F06510800265FE38
-:100860009880FE19E40AFE1A1251FE1982FE6C18D5
-:10087000FE4454BEFE1981FE74188F9017FECE08F8
-:10088000024A08055AEC032E293C0C3F14409B2ECB
-:100890009C3CFE6C18FEED18FE4454FEE5543A3FB5
-:1008A0003B40034929638FFEE354FE7418FEF5189C
-:1008B0008FFEE35490C056FECE08024AFE37F0FE8B
-:1008C000DA09FE8BF0FE6009024A08050A23FEFAE7
-:1008D0000A3A493B6356FE3E0A0FFEC007419800A4
-:1008E000ADFE0159FE52F0FE0C0A8F7AFE240A3A40
-:1008F000498FFEE35457497D63FE1458FE95580214
-:100900004A3A493B63FE1459FE9559BE574957630D
-:10091000024A08055AFE821208051FFE661322626B
-:10092000B7FE03A1FE8380FEC844FE2E13FE049191
-:10093000FE86916A2AFE4059FEC15956E00360299D
-:10094000610C7F148057607D6101B3B86A2A13621D
-:100950009B2E9C3C3A3F3B4090C0FE04FA2EFE0585
-:10096000FA3C01EFFE3610210C7F0C803A3F3B40F1
-:10097000E408051F17E03A3D3B3E0805FEF7003747
-:10098000035E295FFE1058FE915857497D6302FEB1
-:10099000F40908051F17E00805FEF70037BEFE1929
-:1009A0008150FE1090FE9290FED3103207A617FEE3
-:1009B000080912A608050AFE1413033D293E56FE37
-:1009C0000809FE0C58FE8D58024A2141FE1980E7A5
-:1009D00008050AFE1A12FE6C19FE1941F4C2FED176
-:1009E000F0E2157E013610FE4400FE8E10FE6C19FA
-:1009F000573DFEED197D3EFE0C51FE8E51F41EFE5C
-:100A000000FF35FE7410C2FED2F0FEA60BFE761873
-:100A10001E198A03D21E06FE081310FE1600026578
-:100A2000FED1F0FEB80B157E013610FE1700FE4217
-:100A300010FECEF0FEBE0BFE3C10FECDF0FECA0B4B
-:100A400010FE22000265FECBF0FED60B10FE240045
-:100A50000265FED0F0FEE00B109EE5FECFF0FEEA50
-:100A60000B1058FE1010FECCF0E268051F4D10FE72
-:100A700012002C0FFE4E1127FE000CFE9EF0FE14FD
-:100A80000CBC17342C77E6C524C6242CFA27FE208C
-:100A90000C1C3494FE3C0C9586C5DCC6DC0224019B
-:100AA0004BFEDB1012FEE800B5B674C781C883FEAA
-:100AB00089F0243331E1C781C88327FE660C1D24E9
-:100AC0003331DFBC4E10FE420002657C06FE8149D8
-:100AD00017FE2C0D08050AFE44131000550AFE549B
-:100AE0001255FE280023FE9A0D0946010E070066E6
-:100AF00044FE2800FEE21001F501F609A401FE26DD
-:100B00000F64122F0173022B10FE4400550AE944B2
-:100B10000AFEB41001B0440AFEAA1001B0FE198208
-:100B2000FE3446AC440A10FE4300FE961008540AF8
-:100B30003701F501F664122F0173990A644292029B
-:100B4000FE2E0308050A8A440A1000FE5C106805A0
-:100B50001AFE581208051AFE5013FE1C1CFE9DF0CA
-:100B6000FE500DFE1C1CFE9DF0FE560D08541A375B
-:100B7000FEA91010FE1500FE04E60A50FE2E10100D
-:100B8000FE1300FE1010106FAB10FE4100AA10FE05
-:100B900024008CB5B67403702823D850FE04E61ADE
-:100BA000FE9D41FE1C426401E3022BF8150A39A0A8
-:100BB000B415FE310039A201FE481002D742FE06EC
-:100BC000ECD0FC441BFECE453542FE06EAD0FE4783
-:100BD0004B91FE7557035DFE9856FE381209480189
-:100BE0000EFE44484F08051BFE1A130946010E412C
-:100BF000FE415809A4010EFE495496FE1E0E02FE47
-:100C00002E03095DFEEE14FC441BFECE453542FE6C
-:100C1000CE47FEAD13022B22200711FE9E12211398
-:100C200059139F13D5222F41392FBCADFEBCF0FEC6
-:100C3000E00E0F06135901FEDA1603FE380129FEF5
-:100C40003A0156FEE40EFE02ECD5690066FE04ECA5
-:100C5000204FFE05F6FE340101FE4A17FE0890FE05
-:100C600048F40DFE1813BAFE02EAD5697EFEC513DC
-:100C7000151A39A0B4FE2E1003FE38011EFEF0FF37
-:100C80000CFE600103FE3A010CFE620143132025B5
-:100C900006132F122F920F060421042259FEF71279
-:100CA000229FB7139F077EFE7113FE241C1519396E
-:100CB000A0B4FED910C3FE03DCFE7357FE805D04B2
-:100CC000C3FE03DCFE5B57FE805D04FE0357C321B9
-:100CD000FE00CC04FE0357C37804080558FE221317
-:100CE000FE1C800706FE1A13FE1E80EDFE1D80AE60
-:100CF000FE0C90FE0E13FE0E90ACFE3C90FE30F407
-:100D00000AFE3C50AA01FE7A1732072FAD01FEB44D
-:100D10001608051B4E01F501F612FEE900080558FC
-:100D2000FE2C1301FE0C17FE1E1CFE1490FE969066
-:100D30000CFE640114FE660108055BFE1212FE0340
-:100D4000808DFE01EC20FE804013206A2A12CF64C1
-:100D50002220FB792004FE081C03FEAC00FE06588E
-:100D600003FEAE00FE075803FEB000FE085803FE67
-:100D7000B200FE0958FE0A1C256E13D0210C5C0C33
-:100D8000450F465250181BFE904DFE915423FEFC19
-:100D90000F44110F48521858FE904DFE915423E411
-:100DA000251113207C6F4F2220FB792012CFFE14D7
-:100DB00056FED6F0FE2610F874FE141CFE101CFE23
-:100DC000181C0442FE0C14FCFE07E61BFECE47FE78
-:100DD000F5130401B07C6F4FFE0680FE4847FE42CB
-:100DE0001332072FFE34130948010EBBFE3612FEE4
-:100DF0004148FE454801F0FE00CCBBFEF3134378AA
-:100E00000711AC0984010EFE805C0173FE0E100711
-:100E1000824EFE1456FED6F0FE601004FE44588D3D
-:100E2000FE01ECA2FE9E40FE9DE700FE9CE71A79C3
-:100E30002A01E3FEDD102CC781C8833331DE071A97
-:100E4000FE4812070AFE56120719FE301207C9178C
-:100E5000FE321207FE230017EB070617FE9C12074F
-:100E60001FFE12120700172415C90136A92D010B08
-:100E7000944B042DDD09D101FE260F1282022B2D89
-:100E80003207A6FED9133A3D3B3E56FEF011080547
-:100E90005AFE72129B2E9C3C90C096FEBA112262A2
-:100EA000FE2613037F298056FE760D0C6014612107
-:100EB0000C7F0C8001B3256E77136201EF9B2E9C93
-:100EC0003CFE0455FEA555FE04FA2EFE05FA3CFE36
-:100ED0009110033F2940FE4056FEE1560C3F14405E
-:100EE000889B2E9C3C90C0035E295FFE0056FEA1AD
-:100EF000560C5E145F08055AFE1E122262FE1F4049
-:100F000003602961FE2C50FEAE50033F2940FE4491
-:100F100050FEC650035E295FFE0850FE8A50033D16
-:100F2000293EFE4050FEC2500289250613D40272AB
-:100F30002D010B1D4C3331DE0706234C3207A6234F
-:100F40007201AF1E43174C08050AEE3A3D3B3EFEC8
-:100F50000A5535FE8B55573D7D3EFE0C51FE8E5198
-:100F60000272FE1981BAFE194102722D010B1C3466
-:100F70001DE83331E15519FEA612550A4D024C0108
-:100F80000B1C341DE83331DF0719234C010B1DE81E
-:100F90003331FEE809FEC2495103FE9C00288A5302
-:100FA000051F35A9FEBB4555004E44067C43FEDABD
-:100FB0001401AF8CFE4B45EE3207A5ED03CD288A18
-:100FC00003452835670272FEC05DFEF814FE031764
-:100FD000035CC10C5C672D010B268901FE9E150286
-:100FE00089010B1C341D4C3331DF0706234C01F102
-:100FF000FE4258F1FEA4148CFE4AF40A174CFE4A35
-:10100000F406EA3207A58B02720345C10C45672D31
-:10101000010B268901FECC1502890F0627FEBE139F
-:1010200026FED41376FE8948010B2176047BFED080
-:10103000131CFED0131DFEBE13672D010BFED51031
-:101040000F71FF02005752931EFEFF7FFE3056FEC7
-:10105000005C040F71FF02005752931E43FE30568E
-:10106000FE005C040F71FF0200575293040F71FFE2
-:101070000200575293FE0B5804095C018709450191
-:101080008704FE03A11E11FF030054FE00F41F524B
-:10109000FE007DFE017DFE027DFE037C6A2A0C5E61
-:1010A000145F573F7D4004DDFE824AFEE11AFE8355
-:1010B0005A8D0401FE0C19FE4248505191010B1D3E
-:1010C000FE96153331E1010B1DFE96153331FEE816
-:1010D0000AFEC15903CD28FECC1253051AFEC413D3
-:1010E00021691AEE55CA6BFEDC144D0F0618CA7C36
-:1010F00030FE7810FF028355ABFF0283556919AEAD
-:1011000098FE300096F2186D0F06FE5610690AED33
-:1011100098FE640096F209FE6400189E0F06FE28F1
-:10112000106906FE601398FEC80096F209FEC8001A
-:1011300018590F068898FE90017AFE421591E4FE38
-:1011400043F49FFE56F0FE5415FE04F471FE43F482
-:101150009EFEF310FE405C01FE16141E43ECFE00E2
-:1011600017FE4DE46E7AFE9015C46EFE1C10FE0054
-:1011700017FE4DE4CC7AFE9015C4CC885121FE4D6B
-:10118000F400E9910F06FEB456FEC35804510F0A4D
-:10119000041606010B26F3160A010B26F316190195
-:1011A0000B26F376FE8949010B041606010B26B1C6
-:1011B0001619010B26B11606010B26B1FE8949014D
-:1011C0000B26B176FE894A010B04510422D307068F
-:1011D000FE4813B813D3FE49F4004D76A967FE010B
-:1011E000ECFE2701FE8948FF02001027FE2E163272
-:1011F00007FEE300FE20131DFE52162113D4014BFF
-:1012000022D407064E08540637040948010EFB8E07
-:101210000711AE0984010E8E095D01A8040984013D
-:101220000E8EFE80E71107118AFE455801F08E04EC
-:101230000948010E8E095D01A8040948010EFE80CF
-:1012400080FE804CFE49E411AE0984010EFE804C04
-:10125000095D0187041811756CFE6001FE18DFFE40
-:1012600019DEFE241CFE1DF71B97FEEE1601FEF490
-:1012700017AD9A1B6CFE2C01FE2F1904B923FEDE5C
-:1012800016FEDA1018117503FE6401FE00F41FFE4D
-:10129000185803FE6601FE19589A1FFE3C90FE3056
-:1012A000F406FE3C506CFE3800FE0F79FE1CF71F62
-:1012B00097FE3817FEB6143504B923FE1017FE9CAE
-:1012C00010181175FE835AFE18DFFE19DEFE1DF799
-:1012D0002E97FE5A17FE9414EC9A2E6C1AFEAF1934
-:1012E000FE98E70004B923FE4E17FE6C1018117526
-:1012F000FE30BCFEB2BC9ACB6C1AFE0F79FE1CF716
-:10130000CB97FE9217FE5C143504B923FE7E17FEC0
-:101310004210FE02F61175FE18FE60FE19FE61FE17
-:1013200003A1FE1DF75B97FEB817FE3614FE1C13D3
-:101330009A5B41FE8358FEAF19FE80E711FE81E7FC
-:101340001112FEDD006A2A046A2AFE124523FEA855
-:1013500017150639A0B4022BFE39F0FEFC17210444
-:10136000FE7E181E19660F0D047503D21E06FEEFD1
-:1013700012FEE1107C6F4F32072FFE3C13F1FE424C
-:101380001342920948010EBBEBFE4148FE4548015D
-:10139000F0FE00CCBBFEF31343780711AC098401C7
-:1013A0000EFE804C0173FE161007828BFE4014FE69
-:1013B0002412FE1456FED6F0FE1C18180A04FE9CD9
-:1013C000E70A10FE150064792A01E3180604429228
-:1013D00008541B37122F0173180604FE3890FEBA0A
-:1013E000903ACE3BCFFE485535FEC9550422A3772F
-:1013F00013A30409A4010EFE41480946010EFE494B
-:101400004417FEE8187778040948010E07114E09C1
-:101410005D01A80946010E777804FE4EE4196BFEC3
-:101420001C1903FE9000FE3A45FE2C10FE4EE4C946
-:101430006BFE2E1903FE9200FE02E61AE5FE4EE454
-:10144000FE0B006BFE401903FE9400FE02E61FFE39
-:10145000081003FE9600FE02E66DFE4E45EABAFF56
-:10146000046854E71E6EFE081CFE6719FE0A1CFE87
-:101470001AF4FE0004EAFE48F4197AFE74190F19F2
-:1014800004077EFE5AF0FE841925FE0900FE341082
-:10149000071AFE5AF0FE921925CAFE261007196691
-:1014A000256DE5070A66259EFE0E1007066625597E
-:1014B000A9B80415FE09000136FE04FE810383FE6F
-:1014C000405C041CF7FE14F00B27FED6191CF77BBA
-:0C14D000F7FE82F0FEDA1904FFCC0000E9
-:00000001FF
-/* Microcode buffer is kept after initialization for error recovery. */
--- zfcpdump-kernel-4.4.orig/firmware/advansys/38C1600.bin.ihex
+++ /dev/null
@@ -1,398 +0,0 @@
-:1000000077EF0406000000F2001600FC001000F07C
-:1000100018E40100041E48E403F6F7132E1E020044
-:100020000717C05F00FAFFFF040000F609E782E748
-:1000300085F086F04E109EE7FF0055F001F60300B4
-:10004000985701E600EA00EC01FA18F40800F01DE8
-:10005000385432F01000C20E1EF0D5F0BC004BE454
-:1000600000E6B1F0B40002133E1CC8473E00D801C0
-:1000700006130C1C5E1E0057C85701FCBC0EA212D2
-:10008000B9540080620A5A12C8153E1E1840BD5667
-:1000900003E601EA5CF00F0020006C016E0104121F
-:1000A0000413BB553C563E5703584AE44000B60083
-:1000B000BB00C000000101013E01580A44100A12B1
-:1000C0004C1C4E1C024A30E405E60C003C0080004B
-:1000D00024013C0168016A0170017201740176011A
-:1000E00078017C01C60E0C10AC12AE12161A321C2E
-:1000F0006E1E02483A55C95702EE5BF003F706F749
-:1001000003FC06001E00BE00E1000C12181A701A53
-:10011000301C381C1044004CB057405C4DE404EADD
-:100120005DF0A7F004F602FC05000900190032009A
-:1001300033003400360098009E00CC0020014E01B0
-:1001400079013C09680D021004103A1008120A13D4
-:100150004016501600174A19004E0054015800DC92
-:1001600005F009F059F0B8F048F40EF70A009B00CA
-:100170009C00A400B500BA00D000E700F0036908B5
-:10018000E9095C0CB612BC19D81B201C341C361CA7
-:10019000421D0844384491440A45484689486854F9
-:1001A0008355835931E402E607F008F00BF00CF0B8
-:1001B0004BF404F805F802FA03FA04FC05FC070006
-:1001C000A800AA00B900E000E500220126016001B4
-:1001D0007A018201C801CA0186026A031805B207C2
-:1001E0006808100D06100A100E1012106010ED10A5
-:1001F000F310061210121E120C130E131013FE9C95
-:10020000F03505FEEC0EFF100000E9FE341F00E89B
-:10021000FE8801FF030000FE9315FE0F05FF380066
-:1002200000FE572400FE4C0065FF0400001AFF0981
-:100230000000FF080101FF08FFFFFF270000FF107B
-:10024000FFFFFF130000FE7856FE3412FF2100006E
-:10025000FE04F7E8377D0D01FE4A11FE04F7E87D44
-:100260000D5137FE3DF0FE0C02FE20F0BCFE91F079
-:10027000FEF801FE90F0FEF801FE8FF0BC03674D22
-:1002800005FE080F01FE780FFEDD1205FE0E03FECF
-:10029000281C03FEA600FED1123E22FEA600ACFEE4
-:1002A00048F0FE9002FE49F0FEAA02FE4AF0FEC8A7
-:1002B00002FE46F0FE5A02FE47F0FE6002FE43F0E8
-:1002C000FE4E02FE44F0FE5202FE45F0FE56021CB7
-:1002D0000DA21C0722B70535FE001CFEF110FE0220
-:1002E0001CF5FE1E1CFEE910015FFEE710FE06FC79
-:1002F000DE0A8101A305351F9547B801FEE4110A06
-:1003000081015CFEBD100A81015CFEAD10FE161C71
-:10031000FE581C1C0722B7372A35FE3DF0FE0C02A2
-:100320002BFE9E02FE5A1CFE121CFE141C1FFE30E9
-:100330000047B801FED4111C0722B705E9212C099A
-:100340001A31FE69101C0722B7FE04EC2C6001FE76
-:100350001E1E202CFE05F6DE01FE621B010C614A0A
-:100360004415565101FE9E1E01FE961A05350A5788
-:1003700001180900360185FE1810FE41580ABA011D
-:1003800018FEC8547BFE1C0301FE961A0535376023
-:10039000FE02E830FEBF57FE9E43FE7757FE27F071
-:1003A000FEE401FE074BFE20F0BCFE401C2AEBFEE3
-:1003B00026F0FE6603FEA0F0FE5403FE11F0BCFE24
-:1003C000EF10FE9FF0FE7403FE461C19FE1100059F
-:1003D0007037FE481CFE461C010C0628FE1813262A
-:1003E00021B9C720B90A570118C78901FEC81A15D3
-:1003F000E12AEBFE01F0EBFE82F0FEA403FE9C324C
-:1004000015FEE4002FFEB6032A3C16FEC60301418A
-:10041000FE06F0FED603AFA0FE0AF0FEA2070529F5
-:1004200003811E1BFE24051F6301428FFE7002051F
-:10043000EAFE461C377D1DFE671BFEBF57FE775741
-:10044000FE481C7501A6860A57011809001BEC0A14
-:10045000E101187750408D3003811EF81F6301427F
-:100460008FFE700205EAD799D89C2A292FFE4E04E8
-:1004700016FE4A047EFEA000FE9B57FE541232FF79
-:10048000020010010816FE02053201081629272570
-:10049000EEFE4C44FE581250FE44481334FE4C54B9
-:1004A0007BEC608D3001FE4E1EFE4847FE7C130142
-:1004B0000C0628FE32130143099BFE6813FE26102A
-:1004C0001334FE4C547BEC01FE4E1EFE4847FE5496
-:1004D00013010C0628A50143099BFE4013010C06DD
-:1004E00028F91F7F010C06074D1FFE0D0001428FEA
-:1004F000FEA40E05293215FEE6000FFE1C9004FE38
-:100500009C933A0B0E8B021F7F01420535FE425B26
-:100510007D1DFE4659FEBF57FE77570FFE878004AC
-:10052000FE8783FEC9470B0ED065010C060DFE98B1
-:10053000130FFE208004FEA083330B0E091DFE84E2
-:100540001201380607FE701303FEA2001E1BFEDA1E
-:1005500005D0540138060DFE581303FEA0001EFE00
-:1005600050125EFF0200102FFE90052A3CCCFF02C5
-:1005700000102FFE9E0517FEF40515FEE300260170
-:1005800038FE4AF0FEC005FE49F0FEBA05712EFEA7
-:100590002100F12EFE2200A22E4AFE0948FF020091
-:1005A000102FFED00517FEF405FEE208013806FE06
-:1005B0001C004D01A72E0720E447FE2701010C0671
-:1005C00028FE24123E01841F7F010C06074D1FFEEA
-:1005D0000D0001428FFEA40E052903E61EFECA137C
-:1005E00003B61EFE401203661EFE38133E0184173A
-:1005F000FE72060A0701380624FE02124F01FE565B
-:100600001916FE68061582014115E203668A106616
-:10061000039A1EFE701203551EFE681301C60912CE
-:1006200048FE92062E1201FEAC1DFE434862801366
-:1006300058FF02005752AD233F4E62493E018417D6
-:10064000FEEA0601380612F7450A9501FE841916DE
-:10065000FEE0061582014115E203558A10551C077C
-:100660000184FEAE10036F1EFE9E133E0184039AAA
-:100670001EFE1A1201380612FC01C601FEAC1DFE58
-:1006800043486280F0450A9503B61EF801380624F7
-:1006900036FE02F60771788C004D62493E2D934E6E
-:1006A000D00D17FE9A0701FEC01916FE90072620EE
-:1006B0009E1582014115E2219E0907FB03E6FE58C3
-:1006C0005710E605FE2A06036F8A106F1C07018487
-:1006D000FE9C325F7501A68615FEE2002FED2A3CD6
-:1006E000FE0AF0FECE07AEFE9608FE06F0FE9E085D
-:1006F000AFA00529010C060DFE2E12141D010814D1
-:100700000001081400010814000108FE99A4010862
-:10071000140005FEC60901760612FE3A12010C0607
-:1007200012FE301314FE1B0001081400010814000F
-:1007300001081400010814070108140005EF7C4AA1
-:10074000784F0FFE9A8104FE9A83FECB470B0E2D45
-:100750002848FE6C080A28FE096FCAFECA45FE3208
-:100760001253634E7C972FFE7E082A3CFE0AF0FE51
-:100770006C08AFA0AEFE96080529014105ED1424D2
-:1007800005EDFE9CF79F01FEAE1EFE185801FEBE51
-:100790001EFE9958FE7818FEF9188EFE1609106A8A
-:1007A000226B010C615444212C091AF87701FE7E5A
-:1007B0001E472C7A30F0FE83E7FE3F0071FE0340B7
-:1007C000010C61654401C2C8FE1F40206E01FE6A33
-:1007D00016FE0850FE8A50FE4451FEC651FE10100F
-:1007E00001FECE1E01FEDE1E1068226901FEEE1E15
-:1007F00001FEFE1EFE4050FEC250104B224CFE8AEF
-:1008000010010C0654FE501201FEAE1E01FEBE1E6B
-:10081000106A226B010C06654E01C20FFE1F800498
-:10082000FE9F83330B0E206E0FFE449004FEC49394
-:100830003A0BFEC69004FEC693790B0E106C226D27
-:1008400001FECE1E01FEDE1E106822690FFE4090E2
-:1008500004FEC0933A0BFEC29004FEC293790B0EC5
-:10086000104B224C10642234010C6124443713FED7
-:100870004E112FFEDE09FE9EF0FEF209FE01481B1E
-:100880003C3788F5D4FE1E0AD5FE420AD2FE1E0A67
-:10089000D3FE420AAEFE120AFE06F0FE180AAFA010
-:1008A00005290141FEC1101424FEC110017606077E
-:1008B000FE14120176060D5D010C060DFE7412FE8B
-:1008C0002E1C05FE1A0C017606075D0176060D4109
-:1008D000FE2C1CFEAAF0FECE0AFEACF0FE660AFE5E
-:1008E0009210C4F6FEADF0FE720A05FE1A0CC5FEAB
-:1008F000E710FE2BF0BFFE6B1823FE00FEFE1C125D
-:10090000ACFED2F0BFFE7618231D1BBF03E3230706
-:100910001BBFD45BD55BD25BD35BC4C5FEA910758E
-:100920005E321F7F014219FE3500FE01F0701998FA
-:100930000570FE741823FE00F81B5B7D1201FE7823
-:100940000F4D01FE961A2130777D1D055B010C06C7
-:100950000D2BFEE20B010C0654FEA612010C062420
-:10096000FE8813216EC701FE1E1F0FFE838004FE4A
-:100970008383FEC9470B0EFEC844FE42130FFE04DC
-:100980009104FE8493FECA570BFE869104FE869363
-:10099000FECB570B0E7A30FE4059FEC1598E4003F4
-:1009A0006A3B6B10972298D96ADA6B01C2C87A3019
-:1009B000206EDB64DC34916C7E6DFE4455FEE555A3
-:1009C000FE04FA64FE05FA3401FE6A16A3261097A7
-:1009D0001098916C7E6DFE1410010C06241B409142
-:1009E0004B7E4C010C06FEF7004403683B69FE1089
-:1009F00058FE9158FE1459FE9559055B010C0624CA
-:100A00001B40010C06FEF700447801FE8E1E4F0FBE
-:100A1000FE109004FE90933A0BFE929004FE929387
-:100A2000790B0EFEBD10014309BB1BFE6E0A15BB00
-:100A3000010C060DFE1413034B3B4C8EFE6E0AFE9A
-:100A40000C58FE8D58055B263E0FFE198004FE995A
-:100A500083330B0EFEE510010C060DFE1A12FE6C20
-:100A600019FE1941FE6B18ACFED1F0EF1F92014246
-:100A700019FE4400FE9010FE6C19D94BFEED19DAF8
-:100A80004CFE0C51FE8E51FE6B1823FE00FF31FE12
-:100A90007610ACFED2F0FEBA0CFE7618231D5D0374
-:100AA000E32307FE081319FE16000570FED1F0FEC1
-:100AB000CC0C1F92014219FE17005CFECEF0FED254
-:100AC0000CFE3E10FECDF0FEDE0C19FE220005707D
-:100AD000FECBF0FEEA0C19FE24000570FED0F0FEFD
-:100AE000F40C1994FE1C10FECFF0FEFE0C194AF314
-:100AF000FECCF0EF017606244D19FE12003713FEEE
-:100B00004E112FFE160DFE9EF0FE2A0DFE01481B13
-:100B10003C3788F5D429D529D229D32937FE9C32F0
-:100B20002FFE3E0D2A3CAEFE620DAFA0D49FD59F96
-:100B3000D29FD39F05290141FED31015FEE800C4C2
-:100B4000C575D799D89CFE89F0292725BED799D895
-:100B50009C2FFE8C0D16292725BDFE0148A419FEE9
-:100B6000420005709007FE81491BFE640E010C06D1
-:100B70000DFE441319002D0DFE54122DFE28002BDE
-:100B8000FEDA0E0A57011809003646FE2800FEFA62
-:100B90001001FEF41C01FE001D0ABA01FE581040AF
-:100BA00015560185053519FE44002D0DF7460DFE3D
-:100BB000CC1001A7460DFEC21001A70FFE1982043A
-:100BC000FE9983FECC470B0EFE3446A5460D19FE5A
-:100BD0004300FEA210010C610D4401FEF41C01FE55
-:100BE000001D40155601857D0D405101FE9E1E05DC
-:100BF000FE3A03010C060D5D460D1900FE62100160
-:100C0000760612FE5C12010C0612FE5213FE1C1C2C
-:100C1000FE9DF0FE8E0EFE1C1CFE9DF0FE940E014D
-:100C20000C611244FE9F1019FE1500FE04E60D4FE4
-:100C3000FE2E1019FE1300FE101019FE4700F119C8
-:100C4000FE4100A219FE240086C4C57503811E2B37
-:100C5000EA4FFE04E612FE9D41FE1C424001F405EF
-:100C600035FE121C1F0D47B5C31FFE310047B801EA
-:100C7000FED41105E951FE06ECE0FE0E474628FEC3
-:100C8000CE453151FE06EAE0FE474B45FE7557035F
-:100C900067FE9856FE38120A5A0118FE4448600151
-:100CA0000C0628FE18130A5701183EFE41580ABACE
-:100CB000FEFA14FE4954B0FE5E0F05FE3A030A67C1
-:100CC000FEE014FE0E474628FECE453151FECE47CB
-:100CD000FEAD130535212C091AFE98122620962008
-:100CE000E7FE081CFE7C19FEFD19FE0A1C03E5FE4A
-:100CF0004855A53BFE6201FEC95531FE741001FE48
-:100D0000F01A03FE38013BFE3A018EFE1E10FE0271
-:100D1000ECE7530036FE04EC2C60FE05F6FE3401D1
-:100D200001FE621B01FECE1EB211FE1813CAFE02A6
-:100D3000EAE75392FEC3131F1247B5C3FE2A1003FE
-:100D4000FE380123FEF0FF10E503FE3A0110FE62BB
-:100D50000101FE1E1E202C155601FE9E1E130702C9
-:100D600026022196C720960992FE79131F1D47B5CA
-:100D7000C3FEE110CFFE03DCFE7357FE805D02CFA1
-:100D8000FE03DCFE5B57FE805D02FE0357CF26FEAE
-:100D900000CC02FE0357CF8902010C064AFE4E1317
-:100DA0000FFE1C8004FE9C83330B0E0907FE3A13D2
-:100DB0000FFE1E8004FE9E83330B0EFE2A130FFED1
-:100DC0001D8004FE9D83FEF9130EFE1C1301FEEE32
-:100DD0001EACFE141301FEFE1EFE8158FA01FE0E2B
-:100DE0001FFE30F40DFE3C50A201FE921B01430990
-:100DF00056FB01FEC81A010C0628A401FEF41C01D2
-:100E0000FE001D15FEE900010C064AFE4E1301FE10
-:100E1000221BFE1E1C0FFE149004FE94933A0BFE40
-:100E2000969004FE9693790B0E10FE640122FE66E6
-:100E300001010C0665F90FFE038004FE8383330B6A
-:100E40000E77FE01EC2CFE8040202C7A3015DF401E
-:100E5000212CFE00408D2C02FE081C03FEAC00FE7F
-:100E6000065803FEAE00FE075803FEB000FE085809
-:100E700003FEB200FE0958FE0A1C2E4920E026108F
-:100E8000661055106F1357524F1C28FE904DFE915F
-:100E9000542BFE8811461A135A521C4AFE904DFEDE
-:100EA00091542BFE9E112E1A202C903460212CFE82
-:100EB00000408D2C15DFFE1456FED6F0FEB211FE5A
-:100EC000121C75FE141CFE101CFE181C0251FE0C98
-:100ED00014FE0E47FE07E628FECE47FEF51302017C
-:100EE000A7903460FE0680FE4847FE4213FE028053
-:100EF0000956FE34130A5A0118CBFE3612FE414839
-:100F0000FE454801FEB216FE00CCCBFEF3133F892E
-:100F1000091AA50A9D0118FE805C0185F2099BA4AF
-:100F2000FE1456FED6F0FEEC1102FE445877FE0188
-:100F3000ECB8FE9E40FE9DE700FE9CE7128D30015E
-:100F4000F4FEDD1037D799D89C2725EE0912FE480C
-:100F500012090DFE5612091DFE301209DD1BFEC4DA
-:100F60001309FE23001BFED01309071BFE341409CE
-:100F700024FE121209001B291FDD0142A1320108C3
-:100F8000AE410232FE62080AE101FE5810159B05CF
-:100F90003532014309BBFED713914B7E4C8EFE8048
-:100FA00013010C0654FE7212DB64DC34FE4455FE61
-:100FB000E555B0FE4A13216EFE261303973B988E2B
-:100FC000FEB60E106A226B261097109801C22E49A9
-:100FD00088206E01FE6A16DB64DC34FE0455FEA533
-:100FE00055FE04FA64FE05FA34FE8F10036C3B6D67
-:100FF000FE4056FEE156106C226D71DB64DC34FE5F
-:101000004455FEE55503683B69FE0056FEA15610A7
-:10101000682269010C0654F9216EFE1F40036A3BE9
-:101020006BFE2C50FEAE50036C3B6DFE4450FEC672
-:101030005003683B69FE0850FE8A50034B3B4CFE50
-:101040004050FEC25005732E07209E0572320108E3
-:10105000163D2725EE09072B3D014309BB2B7201E5
-:10106000A6233F1B3D010C060DFE1E13914B7E4C2B
-:10107000FE0A5531FE8B55D94BDA4CFE0C51FE8ED3
-:1010800051057201FE8E1ECAFE1941057232010819
-:101090002A3C16C02725BE2D1DC02D0D832D7F1B7C
-:1010A000FE6615053D01082A3C16C02725BD091D11
-:1010B0002B3D010816C02725FEE809FEC249500352
-:1010C000B61E830138062431A1FEBB452D00A4467F
-:1010D00007903F01FEF81501A686FE4B45FE201342
-:1010E00001430982FE1613039A1E5D03551E315EED
-:1010F0000572FEC05D01A7FE031703668A10665ED7
-:10110000320108177301FE5619057301082A3C16AF
-:101110003D2725BD09072B3D01FEBE16FE4258FEA8
-:10112000E81401A686FE4AF40D1B3DFE4AF407FEB4
-:101130000E12014309824E057203558A10555E3224
-:101140000108177301FE8419057301082A3C163D36
-:101150002725BD09122B3D01FEE8178BFEAA14FEC0
-:10116000B61486A8B20D1B3DB207FE0E120143094C
-:10117000824E0572036F8A106F5E32010817730189
-:10118000FEC019057313072FFECC1517FEE2155F7D
-:10119000CC0108265F028FFEDE152AFEDE1516FE44
-:1011A000CC155E320108FED5101358FF02005752CD
-:1011B000AD23FEFF7FFE3056FE005C021358FF0297
-:1011C000005752AD233FFE3056FE005C021358FF1D
-:1011D00002005752AD021358FF02005752FE005E44
-:1011E000021358FF02005752ADFE0B58020A660167
-:1011F0005C0A55015C0A6F015C0201FE1E1F231A86
-:10120000FF030054FE00F424520FFE007C04FE078E
-:101210007C3A0B0EFE0071FEF918FE7A19FEFB19DE
-:10122000FE1AF700FE1BF7007A3010682269D96CAD
-:10123000DA6D02FE6208FE824AFEE11AFE835A77E8
-:101240000201C6FE42484F5045010816FEE017272E
-:1012500025BE010816FEE0172725FEE80AFEC15943
-:10126000039A1EFEDA1201380612FED0132653121C
-:1012700048FE0817D1125312FE1E132DB47BFE2612
-:10128000174D13071CB49004FE7810FF028355F12C
-:10129000FF028355531DFE1213D6FE3000B0FE80B0
-:1012A000171C631307FE5610530DFE1613D6FE646B
-:1012B00000B0FE80170AFE64001C941307FE28107D
-:1012C0005307FE6013D6FEC800B0FE80170AFEC8A2
-:1012D000001C95130771D6FE900148FE8C1745F34C
-:1012E000FE43F496FE56F0FE9E17FE04F458FE43AD
-:1012F000F494F68B01FE2416233FFCA88C4948FE8B
-:10130000DA176249FE1C10A88C8048FEDA1762804A
-:10131000715026FE4DF400F7451307FEB456FEC388
-:10132000580250130D02503E784F45010816A92768
-:1013300025BEFE03EAFE7E01010816A92725FEE967
-:101340000A010816A92725FEE90AFE05EAFE7F0123
-:10135000010816A92725FE6909FE02EAFE8001019F
-:101360000816A92725FEE80847FE810103B61E835B
-:101370000138062431A278F2530736FE34F43FA137
-:1013800078039A1E830138061231F04F45FE901003
-:10139000FE405A233FFB8C4948FEAA186249718CD3
-:1013A0008048FEAA186280FEB456FE405D01C60168
-:1013B000FEAC1DFE0217FEC845FE5AF0FEC018FE28
-:1013C00043482D9336FE34F4FE0011FE40102DB438
-:1013D00036FE34F404FE34102DFE0B00364663FE58
-:1013E0002810FEC049FF020054B2FE900148FEFAE8
-:1013F0001845FE1CF43FF3FE40F496FE56F0FE0C3A
-:1014000019FE04F458FE40F494F63E2D934ED00D90
-:1014100021FE7F01FEC846FE24138C005D2621FEBE
-:101420007E01FEC845FE141321FE8001FE4845FAE8
-:1014300021FE8101FEC8444E260213070278455062
-:10144000130D021407010817FE8219140D01081765
-:10145000FE8219141D010817FE82195FFE894901D9
-:1014600008021407010817C1141D010817C1140749
-:10147000010817C1FE8949010817C15FFE894A01A9
-:1014800008025002140701081774147F010817742A
-:10149000141201081774FE89490108177414000119
-:1014A000081774FE894A01081774FE0949010817D4
-:1014B000745FCC01080221E40907FE4C13C820E444
-:1014C000FE49F4004D5FA15EFE01ECFE2701CCFF5A
-:1014D0000200102FFE3E1A014309FEE300FE221314
-:1014E00016FE641A26209E0141219E09075D010C0B
-:1014F000610744020A5A0118FE0040AA091AFE12A6
-:10150000130A9D0118AA0A6701A3020A9D0118AADD
-:10151000FE80E71A091A5DFE455801FEB216AA02BE
-:101520000A5A0118AA0A6701A3020A5A011801FE01
-:101530007E1EFE804CFE49E41AFE12130A9D01181D
-:10154000FE804C0A67015C021C1A877CE5FE18DFEE
-:10155000FE19DEFE241CFE1DF728B1FE041B01FE51
-:101560002A1CFAB3287CFE2C01FE2F1902C92BFE7F
-:10157000F41AFEFA101C1A8703FE6401FE00F4241C
-:10158000FE185803FE6601FE1958B32401FE0E1F13
-:10159000FE30F407FE3C507CFE3800FE0F79FE1C46
-:1015A000F724B1FE501BFED4143102C92BFE261BBA
-:1015B000FEBA101C1A87FE835AFE18DFFE19DEFEE3
-:1015C0001DF754B1FE721BFEB214FCB3547C12FE24
-:1015D000AF19FE98E70002C92BFE661BFE8A101C9D
-:1015E0001A878B0FFE309004FEB0933A0BFE18580A
-:1015F000FE329004FEB2933A0BFE19580EA8B34A7D
-:101600007C12FE0F79FE1CF74AB1FEC61BFE5E146B
-:101610003102C92BFE961B5CFE02F61A87FE18FEED
-:101620006AFE19FE6B01FE1E1FFE1DF765B1FEEE80
-:101630001BFE3614FE1C13B3653EFE8358FEAF1925
-:10164000FE80E71AFE81E71A15FEDD007A30027A85
-:1016500030FE12452BFEDC1B1F0747B5C30535FEC8
-:1016600039F0752602FE7E18231D361311028703FA
-:10167000E32307FEEF12FEE110903460FE028009C2
-:1016800056FE3C13FE8214FE421351FE06830A5A94
-:101690000118CBFE3E12FE4148FE454801FEB2163F
-:1016A000FE00CCCBFEF3133F89091AA50A9D011851
-:1016B000FE804C0185FE1610099B4EFE4014FE2450
-:1016C00012FE1456FED6F0FE521C1C0D02FE9CE7C4
-:1016D0000D19FE1500408D3001F41C070251FE0665
-:1016E00083FE1880612844155601851C0702FE38C8
-:1016F00090FEBA9091DE7EDFFE485531FEC955025C
-:1017000021B98820B9020ABA0118FE41480A5701D6
-:1017100018FE49441BFE1E1D8889020A5A01180939
-:101720001AA40A6701A30A570118888902FE4EE429
-:101730001D7BFE521D03FE9000FE3A45FE2C10FE5E
-:101740004EE4DD7BFE641D03FE9200D112FE1A10F2
-:10175000FE4EE4FE0B007BFE761D03FE9400D124BA
-:10176000FE081003FE9600D163FE4E4583CAFF04B7
-:101770006854FEF1102349FE081CFE6719FE0A1C7E
-:10178000FE1AF4FE000483B21D48FEAA1D131D02BA
-:101790000992FE5AF0FEBA1D2E93FE34100912FE75
-:1017A0005AF0FEC81D2EB4FE2610091D362E63FE0B
-:1017B0001A10090D362E94F20907362E95A1C8028B
-:1017C0001F930142FE04FE99039C8B022AFE1C1EFD
-:1017D000FE14F0082FFE0C1E2AFE1C1E8FFE1C1E7F
-:1017E000FE82F0FE101E020F3F04FE8083330B0EBC
-:1017F000020FFE188004FE9883330B0E020FFE02C8
-:101800008004FE8283330B0E020FFE068004FE86E8
-:1018100083330B0E020FFE1B8004FE9B83330B0EE3
-:10182000020FFE048004FE8483330B0E020FFE8041
-:101830008004FE8083FEC9470B0E020FFE1981044F
-:10184000FE9983FECA470B0E020FFE068304FE8636
-:1018500083FECE470B0E020FFE2C9004FEAC933A93
-:101860000B0E020FFEAE9004FEAE93790B0E020F2C
-:10187000FE089004FE88933A0B0E020FFE8A900435
-:10188000FE8A93790B0E020FFE0C9004FE8C933AA5
-:101890000B0E020FFE8E9004FE8E93790B0E020F3C
-:1018A000FE3C9004FEBC933A0B0E028B0FFE0380AD
-:0E18B00004FE8383330B770EA802FF66000050
-:00000001FF
-/* Microcode buffer is kept after initialization for error recovery. */
--- zfcpdump-kernel-4.4.orig/firmware/advansys/mcode.bin.ihex
+++ /dev/null
@@ -1,147 +0,0 @@
-:100000003F452C01010301190F0000000000000012
-:10001000000000000F0F0F0F0F0F0F0F0000000068
-:1000200000000000000000000000000000000000D0
-:1000300000000000000000000000000000000000C0
-:100040000000000000000000C3120D0501000000C8
-:1000500000FF000000000000FF80FFFF0100000023
-:10006000000000000000002300000000000700FF67
-:1000700000000000FFFFFF00000000000000E48817
-:100080000000000080734804360000A2C2008073A4
-:1000900003233640B600360005D60CD212DA00A291
-:1000A000C20092801E985000F5004898DF23366009
-:1000B000B60092804F00F5004898EF233660B600F6
-:1000C000928080629280004615EE13EA020109D800
-:1000D000CD044D0000A3D600A6977F2304618401C0
-:1000E000E684D2C18073CD044D0000A3DA01A69747
-:1000F000C681C28880738077000101A1FE004F0095
-:10010000849707A6080100330300C288030301DEB9
-:10011000C288CE006960CE0002034A6000A2780166
-:10012000806307A62401788103038063E20007A6A9
-:10013000340100330400C2880307020104CA0D23FE
-:1001400068984D04048505D80D236898CD041523BF
-:10015000F888FB23026182018063020306A3620127
-:1001600000330A00C2884E0007A36E0100330B0063
-:10017000C288CD04362D00331A00C288500488810D
-:1001800006AB820188814E0007A39201500000A3B4
-:100190003C0100057C814697020105C60423A001AD
-:1001A0001523A101BE81FD23026182010ADA4A0002
-:1001B000066100A0B4018063CD04362D00331B001E
-:1001C000C28806236898CD04E684060100A2D40103
-:1001D000576000A0DA01E6848023A001E6848073E2
-:1001E0004B00066100A2000204010CDE020103CCF8
-:1001F0004F008497FC810823024182014F006297DF
-:1002000048048480F0970046560003C00123E800AC
-:1002100081730629034206E203EE6BEB1123F88893
-:100220000498F0808073807707A42A027C9506A644
-:10023000340203A64C044682040103D8B4986A969B
-:100240004682FE95806783038063B62D02A66C020A
-:1002500007A65A0206A65E0203A66202C2887C9521
-:100260004882609648820423A0011423A1013C84A3
-:1002700004010CDCE0232561EF0014014F04A80108
-:100280006F00A5010323A40106239C01242B1C015C
-:1002900002A6AA0207A65A0206A65E0203A6200428
-:1002A00001A6B40200A6B40200331200C288000EF8
-:1002B0008063004300A08C024D0404010BDCE723A3
-:1002C00004618401103112351401EC006C38003FD8
-:1002D0000000EA821823046118A0E2020401A2C807
-:1002E00000331F00C28808310A350C390E3D7E9854
-:1002F000B62D01A6140300A6140307A60C0306A638
-:10030000100303A6200402A66C0200333300C28847
-:100310007C95EE826096EE82829880427E9864E4BC
-:1003200004012DC83105070100A2540300438701D1
-:10033000050586987E9800A6160307A64C0303A61B
-:100340003C0406A6500301A6160300332500C2880C
-:100350007C95328360963283040110CE07C8050570
-:10036000EB0400330020C020816272830001050588
-:10037000FFA27A03B1010823B2012E8305051501FE
-:1003800000A29A03EC006E0095016C38003F00005B
-:1003900001A6960300A69603108480427E9801A6CB
-:1003A000A40300A6BC031084A898804201A6A4035D
-:1003B00007A6B203D4837C95A88300332F00C2889C
-:1003C000A898804200A6BC0307A6CA03D4837C95E4
-:1003D000C08300332600C288382B80328036042345
-:1003E000A0011223A101108407F006A4F403806B7E
-:1003F000806705238303806303A60E0407A6060413
-:1004000006A60A0400331700C2887C95F483609620
-:10041000F483208407F006A42004806B8067052302
-:1004200083038063B62D03A63C0407A6340406A606
-:10043000380400333000C2887C9520846096208484
-:100440001D0106CC00330084C0200023EA00816235
-:10045000A20D806307A65A0400331800C288030364
-:100460008063A30107A46404230100A286040AA0F8
-:100470007604E00000331D00C2880BA08204E00077
-:1004800000331E00C2884223F888002322A3E6041A
-:10049000082322A3A204282322A3AE04022322A31A
-:1004A000C4044223F8884A00066100A0AE04452334
-:1004B000F888049800A2C004B49800330082C020D9
-:1004C0008162E8814723F88804010BDE0498B49820
-:1004D00000330081C0208162140100A00002432388
-:1004E000F8880423A0014423A10180734D0003A3D5
-:1004F000F40400332700C288040104DC0223A201B3
-:100500000423A001049826954B00F6004F044F00E9
-:1005100000A3220500057600066100A21C050A85DD
-:100520004697CD04248548048480020103DA8023A1
-:10053000820134850223A0014A00066100A2400521
-:100540001D0104D6FF2386414B60CB00FF238001B1
-:1005500049008101040102C830018001F704030150
-:1005600049048001C90000050001FFA0600577046F
-:100570000123EA005D00FEC700620023EA00006379
-:1005800007A4F805030302A08E05F48500332D00AF
-:10059000C28804A0B80580630023DF004A0006611A
-:1005A00000A2A4051D0106D60223024182015000CB
-:1005B00062970485042302418201048508A0BE05D8
-:1005C000F48503A0C405F48501A0CE0588008063EE
-:1005D000CC8607A0EE055F00002BDF0800A2E60531
-:1005E0008067806301A27A067C8506236898482389
-:1005F000F88807238000068780637C850023DF005E
-:1006000000634A00066100A236061D0116D4C0230D
-:1006100007418303806306A61C0600333700C288A7
-:100620001D0101D620236360830380630223DF0062
-:1006300007A67C05EF046F0000634B000641CB006A
-:100640005200066100A24E061D0103CAC0230741E5
-:1006500000631D0104CC00330083C020816280232D
-:1006600007410063806708238303806300630123DD
-:10067000DF0006A6840607A67C058067806300333A
-:100680000040C020816200630000FE958303806308
-:1006900006A6940607A67C05000001A01407002BFF
-:1006A000400E8063010006A6AA0607A67C05400E40
-:1006B0008063004300A0A20606A6BC0607A67C0530
-:1006C0008067400E806307A67C050023DF0000637F
-:1006D00007A6D60600332A00C28803038063890078
-:1006E0000A2B07A6E80600332900C288004300A2AF
-:1006F000F406C00E8063DE86C00E00330080C0208A
-:100700008162040102DA80637C85807B806306A6B7
-:100710008C0600332C00C2880CA22E07FE958303A2
-:10072000806306A62C0707A67C0500333D00C2881F
-:1007300000008067830380630CA0440707A67C0544
-:10074000BF2304618401E6840063F0040101F10029
-:100750000001F20001058001720471008101700442
-:10076000800581050063F004F20072040101F100CC
-:1007700070008101700471008101720080017104B8
-:100780007000800170040063F004F2007204000144
-:10079000F10070008001700471008001720081011D
-:1007A000710470008101700400630023B3018305AC
-:1007B000A301A201A1010123A0010001C80003A11E
-:1007C000C40700330700C28880058105040111C8F1
-:1007D0004800B001B1010823B201050148040043FB
-:1007E00000A2E4070005DA870001C800FF238001AA
-:1007F00005050063F7041A09F6086E040002804339
-:100800007608800277040063F7041A09F6086E047C
-:10081000000200A0140816880043760880027704BE
-:100820000063F3040023F40074008043F400CF401D
-:1008300000A2440874040201F7C9F6D9000101A11D
-:10084000240804982695248873040063F30475042F
-:100850005A88020104D84697049826954A8875005C
-:1008600000A3640800054E8873040063807B8063E6
-:1008700006A6760800333E00C28880678303806343
-:100880000063382B9C88382B928832093105929866
-:100890000505B209006300320036003A003E0063ED
-:1008A00080328036803A803EB43D0063382B40323F
-:1008B0004036403A403E00635A20C94000A0B40888
-:1008C0005D00FEC300638073E6200223E8008273AC
-:1008D000FFFD80731323F8886620C0200423A00145
-:1008E000A123A1018162E28880738077680000A261
-:1008F000800003C2F1C74123F8881123A10104231A
-:04090000A001E684E8
-:00000001FF
-/* Microcode buffer is kept after initialization for error recovery. */
--- zfcpdump-kernel-4.4.orig/firmware/atmsar11.HEX
+++ /dev/null
@@ -1,204 +0,0 @@
-:04000000A0D0F0009C
-:2C008000401A680000000000335B007C13600005335B10003C1AA0C0375A018003400008000000001760FFFB335B400020
-:2C00AC00401A700013600003241B0FC0AF9B45002508000803400008420000108F810C9032220002104000033C03A0D174
-:2C00D8002463F8100060F809242100011000001AAF810C9082020011AF900C480441000A34420080967D000296020012A4
-:2C01040000000000105D00110000000004110161A66200021000000DAE62000C34848000A20200114D01FFFF000000005E
-:2C0130008F834C0000000000AF830FEC00E0F80903E03821000414000440FFF700000000AF80460C8E1000084D01FFFF36
-:2C015C00000000008F834C004900001DAF830FEC8F820CBC8F9D0C4C2442000197BE0000AF820CBC13C00009ACA200D872
-:2C018800A7A000003C0100D1003E08259422002C0411013FA4220002AC22000CAC2000108F9E0C5427BD000217BE00028C
-:2C01B4008CA200C08F9D0C508F970FC8AF9D0C4C12E20005878040023C02A0D12442F94C0040F8090000000000E0F8094A
-:2C01E00003E038214500FFDC8E11000C3C1300D1001111022C4304001060FFB900021180026298218E76003C32220008C1
-:2C020C001440FFB78E7700348E7500303C03CFB016C0000302D5102B041100BE000000001040FFA6007018264D01FFFFE5
-:2C023800000000008F824C00AF974C00AF820FECAC7600100260902132220002104000078F944A009602003A3484000492
-:2C02640014400003AF820FBC3C029000AF820FBC8E10000832943F008E11000C2694FF00128000733C1300D14901007162
-:2C0290003237000816E0006F001111022C4304001060006C0002B980000417400440003A027798211272002326D60030E0
-:2C02BC00AE56003C8E76003C8E7700348E7500303C03CFB016C0000302D5102B0411009100000000104000602E8210006B
-:2C02E80014400009007018264D01FFFF000000008F824C00AF974C00AC760010AE4200341000FFD0AF80460C00E0F8090D
-:2C03140003E038213C03CFB000701826AE4600344D01FFFF000000008F824C00AF974C00AF820FECAC7600101000FFC382
-:2C034000AF80460C02D5102B104000423C17CFB02E8210001440000602F0B8264D01FFFF00000000AEF600101000FFB8E9
-:2C036C00AF80460C00E0F80903E038214D01FFFF000000008F824C00AF864C00AEF60010AF820FEC1000FFAEAF80460C7F
-:2C0398003084FFFB8E5700383242FFC000021182A7820FB8AF970FB4865D002A865E0008A79D0FBA279D0F1833DE00604B
-:2C03C40003BEE821001EF0C203BEE8218F970C584D01FFFF000000008F834C008FA2001C12E300033C030C403C1EC0008B
-:2C03F000AF9E0FBCAC620FB48FA300182442000C14430002AF80460C8FA20014AE40003CAFA2001C8E76003C8E7700340D
-:2C041C008E7500303C03CFB016C0000302D5102B0411003C00000000007018264D01FFFF00000000ACA500E410400032D6
-:2C044800AF974C001000FF7FAC760010000417400440000726D60030AE56003C00E0F80903E03821AF80460C1000FF393E
-:2C047400AE4600348E5700383242FFC000021182A7820FB8AF970FB48F970C5800E0F80903E0382112E600033C030C4029
-:2C04A0003C02C000AF820FBC865D002A865E0008A79D0FBA279D0F1833DE006003BEE821001EF0C203BEE8218FA2001C23
-:2C04CC004D01FFFF000000008F974C00AC620FB43084FFFB8FA300182442000C14430002AF80460C8FA20014AE40003CC2
-:2C04F800AFA2001C4D01FFFF00000000ACA500E41000FF13AF974C0000E0F80903E038211000FF0F000000001040005B50
-:2C052400867E0008279D0F1833DE006003BEE821001E10C203A2E8218FB700088FA2000C8EF6000412E2002886620008BC
-:2C05500082030010000217400441001924630001106000173C02D1B0005010264D01FFFF000000008F9E4C00AC56001008
-:2C057C0026D6FFFE860200103C03CFB034632000A662002A8EE2000026F70008AE6200388FA20020AFB700082417FFFF46
-:2C05A80002C2A8214D01FFFF00000000AF9E4C0003E00008AE7500308EE2000026F70008AE6200388FA20020AFB70008DB
-:2C05D4002417FFFFA677002A02C2A8213C03CFB003E00008AE750030001E18C2006518218C6300C88FA200100000000064
-:2C0600000062B0231EC000038FA1000412C0001B0022B0232EC30041146000023C1500402416004000161E80000318829E
-:2C062C00007518254D01FFFF000000008F954C00001EB84000771821AC624D00005610211441000227830D008FA200004D
-:2C06580002E3B821AFA2001002D71821AFA3000C4D01FFFF000000008EF600041000FFB5AF954C003C16DEADAE76003C82
-:2C068400AE60003826D5FFFF0000102103E00008AE7500302C430AB2106000052C4324B21000000424020AB210000002AF
-:2C06B000240224B11060FFFD304301FF000318403C1DA0D127BDD6CC007D1821946300000002EA4200031C0027BDFFFBC1
-:2C06DC0003E0000803A3100624030FC0AF83450010000002012060213C0CCFB011E000560189602685FE00000000000089
-:2C07080013C000473C02CFB007C0002D001E1F8004610034001E1FC0046000093C02D3B000E0F80903E038214D01FFFF10
-:2C073400000000008F864C008F990FEC1000000BAF994C0001E2782600E0F80903E038214D01FFFF000000008F864C001B
-:2C076000AF994C00ADEF20103C02D3B001E278268F820FC08F830FC4AF824D008DE20004A5E00000AC6200008C62000094
-:2C078C0024020380AF824D008F824D008F820F1424630004146200022419FFFF8F830F10ACA500E4AF830FC44D01FFFF93
-:2C07B800000000008F824C801000001FADE2003C00E0F80903E038214D01FFFF00000000A5E000008F864C001580002238
-:2C07E400AF8F45401000001701E2782600E0F80903E038214D01FFFF000000008F864C00AF994C00ADEF20103C02CFB097
-:2C08100001E27826A5E000004D01FFFF00000000100000078F994C0000E0F80903E038214D01FFFF000000008F864C0015
-:2C083C008F990FEC1580000AAF8F45000000782110000014AF19001400E0F80903E038214D01FFFF000000001180FFF8C1
-:2C0868008F864C0085220000012078210440000A8D290008130B0004000C1602AF1900148D7900140160C021AF994C0084
-:2C089400AD8E40103042003F01C27021000417800440018B8F824A0030818000304200041440FF8D8D4B00001020000C47
-:2C08C00030847FFF8F820C480120F021244300348C5D000C24420004AFDD000C1462FFFC27DE0004A52100001000FF82E0
-:2C08EC00250800081160005800000000857D00088D63000C9562000A8D41000407A1002600621821A563000A00031C026D
-:2C091800041101A0000318C0001D16C00441001F27A2008000021CC00461000E0040E82127BD0080956200009563000293
-:2C0944003442000CAD22000C24020100A52200109562002CA5230014A5220012A520001634028000A5220000A57D0008D2
-:2C09700007A0000C8F820C4C8F830C502441FFE80023F02B13C000020020102124420400945E00002441FFFE17C0FFF994
-:2C099C00AD620010A44B0000142B001CAD400000AD400004254A00083142007F1440000E00041780044100038F820FE03A
-:2C09C800100000063484000134840002244200083442100038421000AF820FE0354A0100394A010039420080AF820FE4B9
-:2C09F400001D14C00441000333A2EFFF1000FF3CA562000807A0009F33A2FFFE10000021A56200088D620024001D1CC01D
-:2C0A200004610004AD42000033A3EFFF1000FF31A563000807A0000533A3FFFEA56300088D4B00001000FFAA000000001E
-:2C0A4C001000008E25080008254A00083142007F1440000E00041780044100038F820FE010000006348400013484000274
-:2C0A7800244200083442100038421000AF820FE0354A0100394A010039420080AF820FE4110000038D4B00001000FF9303
-:2C0AA4002508FFF88F820FD88F830FDC8F810FD41062001D246200084D01FFFF000000008F8C4C00847F00003C1E00D11C
-:2C0AD00033FD03FF001D5980017E5821857E0008001DE900001E0F0003E1F82507E00003AF820FDC879E0CA0278B0C986E
-:2C0AFC0007C100423C0208403C01F7B08D62002000230826AC2200008C620004946300022442FFF8004310211000004E12
-:2C0B2800AD6200208F820FD087830CA014220007278B0C98410000513C018000ACA100E08CA100C4000000001022004C4E
-:2C0B54000022E8238F9F0F0C07A10002AF810FD403E2E8232FA30041146000023C1E0040241D0040001D1E800003188256
-:2C0B8000007E18254D01FFFF000000008F8C4C00AC624CC0005D1021145F000227830CC08F820F0803A3F021AF820FD059
-:2C0BAC00AF9E0FD84D01FFFF000000001000FFC3246200088D63000C8D7D0010A563000A13A0000200031C02A7A00000F8
-:2C0BD800000318C0041100EF006818214D01FFFF000000008F820C448F830C40AD620010A5630004A563000610000021FC
-:2C0C0400AF8C4C00A57D00008C7D000494630002AC5D4C4027A20008AD62001803A3E82127BDFFF4AD7D001C27BD0004D4
-:2C0C3000AD7D002037C18001001E17C00441FFE0A56100084D01FFFF000000008F820C448F830C40AD620010A563000478
-:2C0C5C00A56300068F820FD88F830FDC4D01FFFF000000001462FF9524620008AF8C4C0087830CA0278B0C980461FE97F8
-:2C0C88000004170004400005956200001178000600000000AF0E0010A70D00043084FFF7956D00048D6E001025ADFFD075
-:2C0CB40005A1FE8FAD22000C3C0CFFB001896026000D182225AD00308D7E00188D61001C4D01FFFF00000000103E0036B9
-:2C0CE0008F9D4C003C010840AC3E4C4027DE000811A00017AD7E0018000DF600019E60254D01FFFF00000000AD8E40105F
-:2C0D0C008F8D0C40957E00068F8E0C4403CDF021A57E0006000CF782000C0E0203C1F021001E0F80000C6200000C6202C2
-:2C0D38000181602533DE003C019E60213401000110000008A5210000957E00064D01FFFF000000008F8D0C408F8E0C44CD
-:2C0D640003CDF021A57E00064D01FFFF0000000001A3F02B17C000080003F60001A36823019E6025018960264D01FFF7CF
-:2C0D9000000000001000FE58AF9D4C008D7E00188D61001C00000000143EFFCE006D18234D01FFFF000000002C61000864
-:2C0DBC001020001795610008000000000001FF8007E0000B34210002006D182100031E000183602501896026240D002CC0
-:2C0DE800A56100084D01FFFF000000001000FE40AF9D4C003C1F0C40AFFE4FA83021FFFDA56100083C0CD3CF358CE0006E
-:2C0E140010000008340300023C1F0C40AFFE4FA811A0FFF9000DF60034030003019E6025018960263484000834420002C4
-:2C0E4000AD22000C95620006A5230000AD2200384D01FFFF00000000857E00088F820FA897830FACAD22000433C17FFFA6
-:2C0E6C00AD600010A56100081060FE20AF9D4C00A57E00080003190030633FF0A56300008F820FB03C030840AC624C4007
-:2C0E980024430008AD63001897830FAE2442FFF400621821AD63001C4D01FFFF000000008F8D0C408F830C44A56D000474
-:2C0EC400A56D0006AD6300101000FE0AAF9D4C008F820FE000040FC08C4300000421001B8F9F0FE48C5D0004AC4000043A
-:2C0EF0001060000EAC400000000000009462002800000000005F10208C4100040000000010200003AC43000410000002B6
-:2C0F1C00AC230024AC43000017A3FFF48C6300248F820FE03BFF0080244200083442100038421000AF820FE0AF9F0FE46E
-:2C0F48001000FE573084FFFE1060001000000000947D00280000000003BFE8208FA10004AFA30004102000038C5E000439
-:2C0F740010000002AC230024AFA300008C61002417C3FE48AC410000AC400004AC4000001000FE443084FFFD2C6201006F
-:2C0FA0001440000E006A10213143007F01431823004318233062007FA562002800621823000319028F820FE02463FFF8BF
-:2C0FCC000062182134631000100000033863100034430100386301008C6200040000000010400003AC6B000403E000089A
-:0C0FF800AC4B002403E00008AC6B0000D0
-:02000004A0D08A
-:2CD5000000000002A0D0E00000000000000010000000000600000008000000000000000800000002A0D0D64800000000F7
-:2CD52C00000008880000000000000000000000000000000024313200243132002431320000000000244D43522420436FB2
-:2CD558007079726967687420286329204D61646765204E6574776F726B73204C746420313939352E20416C6C207269674C
-:2CD584006874732072657365727665642E004D6164676520416D6261737361646F722076312E303100000000000000012C
-:2CD5B00000000001000000000000000000000000000000000000000000000000000000000000000000000000000000004E
-:2CD5DC00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000023
-:2CD608000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000F6
-:0CD6340000000000FFF0400000000000BB
-:2CF000000C343E2D000000003C1CA0D1279C56383C1DA0D127BDDFD03C08A0D12508DFD0AF8780080C343C1300000000E4
-:2CF02C00240400030097000D3C08BFC0350802308D08000000000000010000080000000027BDFFD0AFBF001CAFB1001864
-:2CF05800AFB000143C11FFF0000080213C18005637183B7926190200172000020319001A0007000D2401FFFF172100056B
-:2CF08400000000003C01800017010002000000000006000D00001012001018403C05A0D124A5D6CC00A32021A4820000C5
-:2CF0B000261000012A0102001420FFEA000000003C06A0D124C6F9E43C07A0D124E7D648ACE600003C08A0D12508FB14D9
-:2CF0DC00ACE800043C09A0D12529FC94ACE900083C0AA0D1254AFCD4ACEA000C3C0BA0D1256BFBA8ACEB00103C0CA0D15C
-:2CF10800258CFBC4ACEC00143C0DA0D125ADFBE0ACED00183C0EA0D125CEFBFCACEE001C3C0FA0D125EFFC18ACEF0020AD
-:2CF134003C18A0D12718FC34ACF800243C19A0D12739FC50ACF900283C02A0D12442FC60ACE2002C3C03A0D12463FC70A6
-:2CF16000ACE300303C04A0D12484FC80ACE400343C05A0D124A5FCB4ACE500383C06A0D124C6FE08ACE6003C3C08A0D111
-:2CF18C002508FE90ACE800403C09A0D12529FA38ACE900443C0AA0D1254AFA74ACEA0048241000133C0BA0D1256BF9D8E7
-:2CF1B800001060803C0EA0D125CED64801CC6821ADAB0000261000012A0100201420FFF6000000008F988000000000006F
-:2CF1E400AF0001008F828000241903FFA4590202000080218F86800024030FFF0010204024C7038000E42821A4A30000C1
-:2CF21000261000012A0100081420FFF7000000008F89800034089C40AD2803A08F8B80003C0A00FF354AFFFFAD6A03A4FC
-:2CF23C00000080218F8F8000240C0FFF0010684025F80300030D7021A5CC0000261000012A0100081420FFF700000000AB
-:2CF268008F82800034199C40AC5903208F8480003C0300FF3463FFFFAC8303248F868000240502FFA4C502023C08A0C00C
-:2CF29400350801803C09A0D12529D5B8250A00288D0B00008D0C0004AD2B0000AD2C000425080008150AFFFA252900081B
-:2CF2C0004002600000000000AFA20028240300223C04A0E034840014AC8300008FA500280000000034A6100100C01021CB
-:2CF2EC00AFA600283C07FFBF34E7FFFF00C7382400E01021AFA7002840876000000000003C0800023508D8903C09FFFE59
-:2CF3180035290130AD2800008FAA00283C0BF000014B582501601021AFAB002801606021408C6000000000000000802141
-:2CF3440000107080022E7821ADE00000261000012A0104001420FFFA00000000241800013C19A0E8AF380000240200117C
-:2CF370003C03A0F034630017A06200003C04F0EB348400703C05FFF034A54A00ACA400003C06FCEB34C60070ACA6000027
-:2CF39C003C07FFF034E74700ACE00000000080213C08FFF035080FC03C09FFF035294500AD280000261000012A01000433
-:2CF3C8001420FFF800000000000080213C0ADEAD001059803C0100D1002B0821AC2A003C3C0100D1002B0821AC200030C1
-:2CF3F4003C0100D1002B0821AC200038240DFFFF3C0100D1002B0821AC2D0014001071003C0100D1002B0821A42E000054
-:2CF420003C0100D1002B0821A4200004241800203C0100D1002B0821A43800083C0100D1002B0821AC200010261000017F
-:2CF44C002A0104001420FFE00000000000008021001018C03C05A0D124A5E00000A32021AC8000003C07A0D124E7E000BF
-:2CF4780024E8000401033021ACC00000261000012A0100091420FFF300000000240903803C0AFFF0354A4D00AD4900005F
-:2CF4A4003C0CA080358C009CAD8000003C0DA08035AD00A0ADA000003C0E11003C0FA08035EF00A8ADEE000041010003A0
-:2CF4D000000000004100FFFF000000003C18A080371800E08F1900003C01A0D1AC39D6C80C343D43032020218FB00014DE
-:2CF4FC008FBF001C8FB1001803E0000827BD00300080B8213C1CFFF0A3800C84A3800C888F90440000002021AF800CBC7E
-:2CF52800240200A827830F002C5D004017A0000C3C1DFFB003A3E826AFB740000000000000000000000000004D01FFFFF6
-:2CF55400000000002442FFC0246300401000FFF326F700401040000D000000000002EE003C01004003A1E8253C01FFF099
-:2CF5800003A1E82603A3E826AFB740000000000000000000000000004D01FFFF000000003C05A0808F820F08000000007E
-:2CF5AC00AF820FD4AF820FD0ACA200C48F820F100000000000021D82AF830FC000031D80004310233C01A0800041102542
-:2CF5D800AF820FC4AF820F108F820F1400000000004310233C01A08000411025AF820F1424030003279D0F1824BE00C823
-:2CF6040027810D008FA2000000000000AFA20010AFC20000AFA10008AFA1000C8FA2001400000000AFA2001C27BD0024B4
-:2CF6300027DE0004242100401460FFF32463FFFF8F820F0000000000AF820FC8ACA200C0278208002403000FAC4000002C
-:2CF65C00244200041460FFFD2463FFFF8F830FC000000000AF834D008F834D008F830F148F820F102463FFFCAC40000091
-:2CF688001443FFFE2442000424020380AF824D00279D0F1827A100908FA200148FA3001800000000006218232C7F004017
-:2CF6B40017E000093C1F004037FF080003A0F0214D01FFFF00000000AFE20000244200401000FFF62463FFC01060000659
-:2CF6E00037FF080000031E0003E3F8254D01FFFF00000000AFE2000027BD002417A1FFE800000000000038218FC200145A
-:2CF70C008FC3001800000000006218232C7F004013E000043C1F004000030E001000000203E1F8252403004037FF080084
-:2CF73800241E03E7000008214D01FFFF00000000AFE20000002308214900FFFB000000008780400217C0FFF827DEFFFFCA
-:2CF7640014E0000434E7400003E7F8251000FFF0AF810C60AF810C5C3C01A0D18C22D6C8000000003C01A080AC2200E0E7
-:2CF790003C01A0808C2000E0AF800FB4A7800FB8A7800FBAA7800FBCA7800FBE27820CC0AF820FDCAF820FD83C02A0D156
-:2CF7BC002442DACCAF820C4CAF820C5024420400AF820C542402001E3C03FFF0247D0040AC7D000803A018211440FFFC55
-:2CF7E8002442FFFF3C1DFFF0AC7D00083C02C7043442DD7BAF820C583C07000024E7015808343FA9000000008E620038B9
-:2CF8140000000000144000058F830C9412A000222463000110000020AF830C94AF820FB43262FFC0000211828663002A70
-:2CF84000A7820FB83C02A000AF820FBCA7830FBA867E0008279D0F1833DE006003BEE821001EF0C203BEE8218FA2001CC6
-:2CF86C003C030C404D01FFFF000000008F974C00AC620FB48FA300182442000C14430003000000008FA2001400000000FB
-:2CF89800AFA2001C4D01FFFF00000000ACA500E4AF974C0003E00008AE60003C3C0DA0D125ADD50011A00021000000005C
-:2CF8C4008DA90000000000001120001D000000008DAA00048DAB00088DAC000C0009474005010004000000003C08A0D185
-:2CF8F0002508D638014850210009478005010007000000001180000D00000000AD400000254A00041000FFFB258CFFFC66
-:2CF91C0011800007000000008D6E0000256B0004AD4E0000254A00041000FFF9258CFFFC1000FFE125AD001003E00008B9
-:2CF94800000000003C021040AC574FF0000000000000000000000000000000004D01FFFF000000008F820FFC000000005B
-:2CF974003042001F000210803C17A0D102E2B82126F7D6488EF700000000000002E00008000000002402FFFFAF820FFCB9
-:2CF9A0008F970FC83C021040AC570FF08F820F0426F7001016E20004AF970FC88F970F0000000000AF970FC84D01FFFFA6
-:2CF9CC000000000003E00008000000003C1FA0D127FFF02C1000FFED8F970FF03C0200D132F703FF0017B98002E2B825AA
-:2CF9F800AEE0003C2402FFFFAEE20030AEE2001497830FF497820FF83C1D000027BD0698A6E30008A6E20002AF9F0FE819
-:2CFA240003A0F809A6E2002C8F9F0FE81000FFD9AEE2000C8F970FF03C0200D132F703FF0017B98002E2B82597820FF429
-:2CFA50003C03000024630698A6E20002AF9F0FE80060F809A6E2002C8F9F0FE81000FFCAAEE2000C8F970FF03C0200D174
-:2CFA7C0032F703FF0017B98002E2B82597820FF40000000096E30008A6E2000800431026304200601040FFBD8EE2003CF2
-:2CFAA800AEE0003C1040FFBA3C028800AF820FBC8EE20038AEE0003830630060279D0F1803A3E821000318C203A3E82116
-:2CFAD4008FA3001C1040FFAFAF820FB43C020C40AC430FB48FA200182463000C14430003000000008FA30014000000000E
-:2CFB0000AFA3001C4D01FFFF000000001000FFA2000000008F970FF03C0200D1A7970FB80017B98032F7FFC002E2B82140
-:2CFB2C00AEE000303C02DEAD8EE3003CAEE2003C8EE200381060FF95AEE000383C038800AF830FBC86E3000827970F1821
-:2CFB58003063006002E3B821000318C202E3B8218EE3001C1040FF8AAF820FB43C020C40AC430FB48EE200182463000C84
-:2CFB840014430003000000008EE3001400000000AEE3001C4D01FFFF000000001000FF7D000000008F820FF08F970FF4B8
-:2CFBB0009041000000000000003708251000FF76A04100008F820FF08F970FF49441000000000000003708251000FF6F9E
-:2CFBDC00A44100008F820FF08F970FF48C41000000000000003708251000FF68AC4100008F820FF08F970FF49041000040
-:2CFC080002E0B827003708241000FF61A04100008F820FF08F970FF49441000002E0B827003708241000FF5AA4410000DB
-:2CFC34008F820FF08F970FF48C41000002E0B827003708241000FF53AC4100008F820FF08F970FF41000FF4FA05700009D
-:2CFC60008F820FF08F970FF41000FF4BA45700008F820FF08F970FF41000FF47AC5700008F820FF0000000008C4200007A
-:2CFC8C001000FF42AF820FF43C01A0C28C22C00000000000AF820FF03C01A0C28C22C0041000FF3AAF820FF43C01A0D14E
-:2CFCB8008C22D5AC00000000AF820FF03C01A0D18C22D5B01000FF32AF820FF43C02A0F0AC400000905701530000000076
-:2CFCE400A3970C809057015700000000A3970C819057015B00000000A3970C879057015F00000000A3970C8690570163BA
-:2CFD10000000000032F70007A3970C859057019300000000A3970C8B9057019700000000A3970C8A9057019B00000000AE
-:2CFD3C0032F70007A3970C899057000B0000000032F700E000170942905700470000000032F700780037082590570067BE
-:2CFD68000000000032F7000F0017B9C000370825905700C70000000032F7002F0017BAC000370825905701470000000019
-:2CFD940032F7001E0017BC0000370825905701830000000032F700600017BC0000370825AF810C8C3C0218408F970FC83F
-:2CFDC000000000008F970FF000000000AC570C800000000000000000000000000000000000000000000000004D01FFFF17
-:2CFDEC00000000003C02A0D12442F998AF800C90AF800C94004000080000000087970FF03C1300D1A67700083C030000C2
-:2CFE180024630520AF9F0FE80060F809240200018F9F0FE81040FEDA97970FF027830F18007718210017B8C202E3B821FB
-:2CFE44003C028800AF820FBC8E620038A7800FB8AF820FB48EE3001C3C020C40AC430FB48EE200182463000C1443000487
-:2CFE7000AEE3001C8EE3001400000000AEE3001C4D01FFFF000000001000FFDF000000008F820C5C8F830C60AF820FF026
-:2CFE9C001000FEBEAF830FF423890800012018212402000F206C0040AC6C0008018018211440FFFC2042FFFFAC69000884
-:2CFEC800278B0C98A56000002403FFFFAD6300143402000134420020A5620008278A0E000140102100001821AC40000038
-:2CFEF400246300042C6C01001580FFFC244200043C02A0D12442E000AF820FE03C1800D1012060210000682100007821C6
-:28FF20000000582100004021400260000000000034424001408260003C020000244206F800400008000000007A
-:00000001FF
-/*
-  Madge Ambassador ATM Adapter microcode.
-  Copyright (C) 1995-1999  Madge Networks Ltd.
-
-  This microcode data is placed under the terms of the GNU General
-  Public License. The GPL is contained in /usr/doc/copyright/GPL on a
-  Debian system and in the file COPYING in the Linux kernel source.
-
-  We would prefer you not to distribute modified versions without
-  consultation and not to ask for assembly/other microcode source.
-*/
-
-First record is start address in a __be32.
--- zfcpdump-kernel-4.4.orig/firmware/av7110/Boot.S
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
-   Boot.S: boot loader for Siemens DVB-S card
-
-   Copyright (C) 2001 Convergence integrated media GmbH
-	              Written by Ralph Metzler
-		                 <rjkm@convergence.de>
-   Copyright (C) 2006 Matthieu CASTET <castet.mattheiu@free.fr>
-
-   This program is free software; you can redistribute it and/or
-   modify it under the terms of the GNU General Public License
-   as published by the Free Software Foundation; either version 2
-   of the License, or (at your option) any later version.
-
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA.
-
-*/
-
-/*
-	check AV711x_3_1.pdf for some hardware infos
-	build it with :
-	$ cc -mbig-endian -c Boot.S
-	$ ld -Ttext 0x2c000000 -EB -o Boot Boot.o
-	$ objcopy -Obinary Boot
-*/
-
-	.text
-	.align
-	.globl _start
-_start:
-	b reset			// reset vector
-	movs  pc, r14           // undefined
-	subs  pc, r14, #4       // SWI
-	subs  pc, r14, #4       // prefetch abort
-	subs  pc, r14, #8       // data abort
-	subs  pc, r14, #4       // reserved
-	subs  pc, r14, #4       // IRQ
-	subs  pc, r14, #4       // FIQ
-
-	.word tbl               // table needed by firmware ROM
-tbl:	.word (endtbl - tbl)
-	.word 0
-  	.word conf
-endtbl:	.word 0
-conf:	.word 0xa5a55a5a
-	.word 0x001f1555
-	.word 0x00000009
-
-reset:	ldr	r13, buffer
-	ldr	r4, flag
-	mov	r0, #0
-	str	r0, [r4]
-	str	r0, [r4, #4]
-
-	ldr		r1, wait_address
-	ldr		r2, flag_address
-	ldr		r3, sram
-
-copycode: // copy the code HW Sram
-	ldmia	r1!, {r5-r12}
-	stmia	r3!, {r5-r12}
-	cmp		r1, r2
-	ble 	copycode
-	ldr		pc, sram // jump to the copied code
-
-wait:	ldrh	r1, [r4]        // wait for flag!=0
- 	cmp	r1, #0
-	beq	wait
-
-	mov	r1, r13         // buffer address
- 	ldr	r3, [r4,#4]     // destaddr
-
- 	ldrh	r2, [r4,#2]     // get segment length
-	add     r2, r2, #63     // round length to next 64 bytes
-	movs	r2, r2, lsr #6  // and divide by 64
-	moveq	r0, #2          // if 0, set flag to 2, else signal
-	strh	r0, [r4]        // that buffer is accepted by setting to 0
-        beq wait
-	
-copyloop:
-	ldmia	r1!, {r5-r12}
-	stmia	r3!, {r5-r12}
-	ldmia	r1!, {r5-r12}
-	stmia	r3!, {r5-r12}
- 	subs	r2, r2, #1
- 	bne	copyloop
-
-	eor     r13, r13, #0x1400    // switch to other buffer
-	b	wait
-
-// flag is stored at 0x2c0003f8, length at 0x2c0003fa,
-// destaddr at 0x2c0003fc
-
-flag:	.word	0x2c0003f8
-
-
-// buffer 1 is at 0x2c000400, buffer 2 at 0x2c001000
-
-buffer:	.word	0x2c000400
-
-sram: .word   0x9e000800
-wait_address: .word   wait
-flag_address: .word   flag
--- zfcpdump-kernel-4.4.orig/firmware/av7110/bootcode.bin.ihex
+++ /dev/null
@@ -1,15 +0,0 @@
-:10000000EA00000EE1B0F00EE25EF004E25EF00401
-:10001000E25EF008E25EF004E25EF004E25EF0040C
-:100020002C0000240000000C000000002C00003414
-:1000300000000000A5A55A5A001F15550000000930
-:10004000E59FD07CE59F4074E3A00000E5840000BC
-:10005000E5840004E59F1070E59F2070E59F306403
-:10006000E8B11FE0E8A31FE0E1510002DAFFFFFB67
-:10007000E59FF050E1D410B0E35100000AFFFFFC0F
-:10008000E1A0100DE5943004E1D420B2E282203FDB
-:10009000E1B0232203A00002E1C400B00AFFFFF494
-:1000A000E8B11FE0E8A31FE0E8B11FE0E8A31FE00C
-:1000B000E25220011AFFFFF9E22DDB05EAFFFFEC17
-:1000C0002C0003F82C0004009E0008002C00007493
-:0400D0002C0000C040
-:00000001FF
--- zfcpdump-kernel-4.4.orig/firmware/bnx2/bnx2-mips-06-6.2.1.fw.ihex
+++ /dev/null
@@ -1,5818 +0,0 @@
-:10000000080001180800000000004A68000000C84D
-:1000100000000000000000000000000008004A6826
-:100020000000001400004B30080000A00800000091
-:100030000000569400004B44080058200000008443
-:100040000000A1D808005694000001580000A25CEE
-:100050000800321008000000000072D00000A3B4B5
-:10006000000000000000000000000000080072D046
-:100070000000002400011684080004900800040019
-:10008000000017D4000116A80000000000000000C6
-:100090000000000000000000000000000000000060
-:1000A000080000A80800000000003BFC00012E7CB6
-:1000B0000000000000000000000000000000000040
-:0800C000000000000000000038
-:0800C8000A00004600000000E0
-:1000D000000000000000000D636F6D362E322E31DF
-:1000E0000000000006020102000000000000000302
-:1000F000000000C800000032000000030000000003
-:1001000000000000000000000000000000000000EF
-:1001100000000010000001360000EA600000000549
-:1001200000000000000000000000000000000008C7
-:1001300000000000000000000000000000000000BF
-:1001400000000000000000000000000000000000AF
-:10015000000000000000000000000000000000009F
-:10016000000000020000000000000000000000008D
-:10017000000000000000000000000000000000007F
-:10018000000000000000000000000010000000005F
-:10019000000000000000000000000000000000005F
-:1001A000000000000000000000000000000000004F
-:1001B000000000000000000000000000000000003F
-:1001C000000000000000000000000000000000002F
-:1001D000000000000000000000000000000000001F
-:1001E0000000000010000003000000000000000DEF
-:1001F0000000000D3C02080024424AA03C03080015
-:1002000024634B9CAC4000000043202B1480FFFD76
-:10021000244200043C1D080037BD7FFC03A0F021F0
-:100220003C100800261001183C1C0800279C4AA01E
-:100230000E000168000000000000000D27470100CB
-:1002400090E3000B2402001A94E5000814620028D1
-:10025000000020218CE200003C0308008C63004475
-:1002600094E60014000211C20002104030A4000203
-:10027000005A10212463000130A50004A446008028
-:100280003C010800AC23004410A000190004202BFE
-:100290008F4202B804410008240400013C02080017
-:1002A0008C420060244200013C010800AC22006046
-:1002B00003E00008008010218CE2002094E3001687
-:1002C00000002021AF4202808CE20004A743028498
-:1002D000AF4202883C021000AF4202B83C02080064
-:1002E0008C42005C244200013C010800AC22005C0E
-:1002F00003E00008008010212747010090E3000B75
-:100300002402000394E50008146200280000202164
-:100310008CE200003C0308008C63004494E6001467
-:10032000000211C20002104030A40002005A102145
-:100330002463000130A50004A44600803C010800AD
-:10034000AC23004410A000190004202B8F4202B8F7
-:1003500004410008240400013C0208008C420060B3
-:10036000244200013C010800AC22006003E00008C8
-:10037000008010218CE2002094E300160000202170
-:10038000AF4202808CE20004A7430284AF4202889D
-:100390003C021000AF4202B83C0208008C42005CF4
-:1003A000244200013C010800AC22005C03E000088C
-:1003B000008010218F4301002402010050620003DD
-:1003C000000311C20000000D000311C20002104022
-:1003D000005A1021A440008003E000080000102112
-:1003E0009362000003E00008AF80000003E0000813
-:1003F0000000102103E00008000010212402010089
-:1004000014820008000000003C0208008C4200FC3E
-:10041000244200013C010800AC2200FC0A0000DD7F
-:1004200030A200203C0208008C42008424420001DB
-:100430003C010800AC22008430A2002010400008DB
-:1004400030A300103C0208008C4201082442000145
-:100450003C010800AC22010803E000080000000095
-:1004600010600008000000003C0208008C420104FB
-:10047000244200013C010800AC22010403E0000812
-:10048000000000003C0208008C42010024420001F0
-:100490003C010800AC22010003E00008000000005D
-:1004A00027BDFFE8AFBF0010274401009483000878
-:1004B000306200041040001B306600028F4202B818
-:1004C00004410008240500013C0208008C42006041
-:1004D000244200013C010800AC2200600A0001290E
-:1004E0008FBF00108C82002094830016000028210A
-:1004F000AF4202808C820004A7430284AF4202888C
-:100500003C021000AF4202B83C0208008C42005C82
-:10051000244200013C010800AC22005C0A000129D1
-:100520008FBF001010C00006006028218F4401001A
-:100530000E0000CD000000000A0001282405000183
-:100540008F8200088F4301045043000700002821D8
-:100550008F4401000E0000CD000000008F42010416
-:10056000AF820008000028218FBF001000A01021DA
-:1005700003E0000827BD001827BDFFE8AFBF001447
-:10058000AFB00010974201083043700024022000F1
-:100590001062000B286220011440002F000010217F
-:1005A00024024000106200250000000024026000C8
-:1005B00010620026000010210A0001658FBF0014A0
-:1005C00027500100920200091040001A2403000184
-:1005D0003C0208008C420020104000160000182148
-:1005E0000E00049300000000960300083C0608007B
-:1005F00094C64B5E8E0400188F8200209605000C76
-:1006000000031C0000661825AC440000AC45000443
-:1006100024040001AC400008AC40000CAC400010C9
-:10062000AC400014AC4000180E0004B8AC43001CF1
-:10063000000018210A000164006010210E0003254B
-:10064000000000000A000164000010210E000EE905
-:1006500000000000000010218FBF00148FB00010B8
-:1006600003E0000827BD001827BDFFE0AFB2001867
-:100670003C036010AFBF001CAFB10014AFB000105E
-:100680008C6450002402FF7F3C1A800000822024EA
-:100690003484380C24020037AC6450003C1208004B
-:1006A00026524AD8AF42000824020C80AF420024F0
-:1006B0003C1B80083C06080024C60324024010218D
-:1006C0002404001D2484FFFFAC4600000481FFFDCC
-:1006D000244200043C020800244204B03C0108000B
-:1006E000AC224AE03C020800244202303C010800EF
-:1006F000AC224AE43C020800244201743C03080096
-:100700002463032C3C040800248403D83C0508001F
-:1007100024A538F03C010800AC224B403C02080004
-:10072000244202EC3C010800AC264B243C010800AA
-:10073000AC254B343C010800AC234B3C3C01080089
-:10074000AC244B443C010800AC224B483C0108005F
-:10075000AC234ADC3C010800AC204AE83C0108001C
-:10076000AC204AEC3C010800AC204AF03C010800F7
-:10077000AC204AF43C010800AC204AF83C010800D7
-:10078000AC204AFC3C010800AC204B003C010800B6
-:10079000AC244B043C010800AC204B083C01080091
-:1007A000AC204B0C3C010800AC204B103C01080075
-:1007B000AC204B143C010800AC204B183C01080055
-:1007C000AC264B1C3C010800AC264B203C01080029
-:1007D000AC254B303C010800AC234B380E000623FF
-:1007E000000000003C028000344200708C42000097
-:1007F000AF8200143C0308008C6300208F82000449
-:10080000104300043C0280000E00045BAF83000430
-:100810003C028000344600703C0308008C6300A05A
-:100820003C0208008C4200A4104300048F84001492
-:100830003C010800AC2300A4A743009E8CCA000022
-:100840003C0308008C6300BC3C0208008C4200B8EA
-:100850000144202300641821000040210064202B63
-:1008600000481021004410213C010800AC2300BCCA
-:100870003C010800AC2200B88F5100003222000772
-:100880001040FFDCAF8A00148CC600003C05080055
-:100890008CA500BC3C0408008C8400B800CA30233E
-:1008A00000A628210000102100A6302B0082202164
-:1008B00000862021322700013C010800AC2500BC45
-:1008C0003C010800AC2400B810E0001F32220002F6
-:1008D0008F420100AF4200208F420104AF4200A8C6
-:1008E0009342010B0E0000C6305000FF2E02001E86
-:1008F00054400004001010800E0000C90A000213CA
-:1009000000000000005210218C4200000040F80955
-:1009100000000000104000053C0240008F4301042D
-:100920003C026020AC4300143C024000AF4201385E
-:100930003C0208008C420034244200013C010800C3
-:10094000AC220034322200021040000E3222000499
-:100950008F4201400E0000C6AF4200200E000295FB
-:10096000000000003C024000AF4201783C02080059
-:100970008C420038244200013C010800AC220038BF
-:10098000322200041040FF983C0280008F42018018
-:100990000E0000C6AF4200208F43018024020F00EA
-:1009A00014620005000000008F420188A742009CED
-:1009B0000A0002483C0240009362000024030050F9
-:1009C000304200FF144300083C0240000E00027B4E
-:1009D00000000000544000043C0240000E000D7571
-:1009E000000000003C024000AF4201B83C02080099
-:1009F0008C42003C244200013C010800AC22003C37
-:100A00000A0001C83C0280003C0290003442000110
-:100A100000822025AF4400208F4200200440FFFECA
-:100A20000000000003E00008000000003C0280001D
-:100A3000344200010082202503E00008AF4400207A
-:100A400027BDFFE0AFB10014AFB0001000808821D7
-:100A5000AFBF00180E00025030B000FF9362007D5F
-:100A60000220202102028025A370007D8F70007477
-:100A70003C0280000E000259020280241600000988
-:100A80008FBF00188F4201F80440FFFE24020002CD
-:100A9000AF5101C0A34201C43C021000AF4201F8B3
-:100AA0008FBF00188FB100148FB0001003E0000852
-:100AB00027BD002027BDFFE8AFBF0010974201848B
-:100AC0008F440188304202001040000500002821B8
-:100AD0000E000FAA000000000A00028D240500018C
-:100AE0003C02FF0004800005008218243C02040040
-:100AF000506200019362003E240500018FBF001088
-:100B000000A0102103E0000827BD0018A360002208
-:100B10008F4401400A00025E2405000127BDFFE862
-:100B2000AFBF0014AFB0001093620000304400FF6C
-:100B300038830020388200300003182B0002102B6D
-:100B40000062182410600003240200501482008008
-:100B50008FBF001493620005304200011040007CFA
-:100B60008FBF0014934201482443FFFF2C6200050D
-:100B7000104000788FB00010000310803C03080084
-:100B800024634A68004310218C42000000400008A2
-:100B9000000000000E0002508F4401408F70000CD6
-:100BA0008F4201441602000224020001AF62000CD1
-:100BB0000E0002598F4401408F420144145000043A
-:100BC0008FBF00148FB000100A000F2027BD00183F
-:100BD0008F62000C0A0003040000000097620010FE
-:100BE0008F4301443042FFFF1462001A00000000EE
-:100BF00024020001A76200108F4202380443001053
-:100C00008F4201403C02003F3446F0003C0560004A
-:100C10003C04FFC08CA22BBC0044182400461024C6
-:100C20000002130200031D82106200390000000060
-:100C30008F4202380440FFF7000000008F4201405D
-:100C4000AF4202003C021000AF4202380A00032209
-:100C50008FBF0014976200100A0003040000000018
-:100C60000E0002508F440140976200128F430144EE
-:100C70003050FFFF1603000224020001A762001299
-:100C80000E0002598F4401408F42014416020004B5
-:100C90008FBF00148FB000100A00029127BD00180A
-:100CA000976200120A00030400000000976200141B
-:100CB0008F4301443042FFFF14620006240200010A
-:100CC0008FBF00148FB00010A76200140A00124AF0
-:100CD00027BD0018976200141440001D8FBF001438
-:100CE0000A00031C00000000976200168F430144B5
-:100CF0003042FFFF1462000B240200018FBF00147A
-:100D00008FB00010A76200160A000B1227BD001852
-:100D10009742007824420004A76200100A000322D0
-:100D20008FBF001497620016240300013042FFFFBA
-:100D3000144300078FBF00143C0208008C4200706F
-:100D4000244200013C010800AC2200708FBF001457
-:100D50008FB0001003E0000827BD001827BDFFE892
-:100D6000AFBF0014AFB000108F50010093620000BD
-:100D700093430109304400FF2402001F106200A5C4
-:100D80002862002010400018240200382862000A5F
-:100D90001040000C2402000B286200081040002CB8
-:100DA00000000000046000E52862000214400028F2
-:100DB00024020006106200268FBF00140A00041FE0
-:100DC0008FB000101062005E2862000B144000DC3F
-:100DD0008FBF00142402000E106200738FB0001049
-:100DE0000A00041F00000000106200C028620039E1
-:100DF0001040000A2402008024020036106200CA5B
-:100E000028620037104000B424020035106200C18F
-:100E10008FBF00140A00041F8FB000101062002B57
-:100E20002862008110400006240200C82402003914
-:100E3000106200B48FBF00140A00041F8FB00010AE
-:100E4000106200998FBF00140A00041F8FB00010B9
-:100E50003C0208008C420020104000B98FBF0014F3
-:100E60000E000493000000008F4201008F830020D9
-:100E70009745010C97460108AC6200008F420104BF
-:100E80003C04080094844B5E00052C00AC62000416
-:100E90008F4201180006340000C43025AC620008FF
-:100EA0008F42011C24040001AC62000C9342010A31
-:100EB00000A22825AC650010AC600014AC600018DE
-:100EC000AC66001C0A0003F58FBF00143C0208004A
-:100ED0008C4200201040009A8FBF00140E00049333
-:100EE00000000000974401083C03080094634B5E37
-:100EF0009745010C000422029746010E8F820020C4
-:100F0000000426000083202500052C003C030080FF
-:100F100000A6282500832025AC400000AC4000043A
-:100F2000AC400008AC40000CAC450010AC400014D4
-:100F3000AC400018AC44001C0A0003F42404000177
-:100F40009742010C14400015000000009362000558
-:100F50003042001014400011000000000E0002504A
-:100F6000020020219362000502002021344200107B
-:100F70000E000259A36200059362000024030020C2
-:100F8000304200FF1043006D020020218FBF00148B
-:100F90008FB000100A000FC027BD00180000000D20
-:100FA0000A00041E8FBF00143C0208008C4200207F
-:100FB000104000638FBF00140E0004930000000077
-:100FC0008F4201048F8300209744010C3C050800E8
-:100FD00094A54B5EAC6200009762002C00042400D4
-:100FE0003042FFFF008220253C02400E00A228254F
-:100FF000AC640004AC600008AC60000CAC60001095
-:10100000AC600014AC600018AC65001C0A0003F46E
-:10101000240400010E00025002002021A7600008F5
-:101020000E00025902002021020020210E00025E63
-:10103000240500013C0208008C42002010400040C2
-:101040008FBF00140E000493000000009742010CB3
-:101050008F8300203C05080094A54B5E000214001D
-:10106000AC700000AC620004AC6000088F64004CFF
-:101070003C02401F00A22825AC64000C8F62005087
-:1010800024040001AC6200108F620054AC620014B2
-:10109000AC600018AC65001C8FBF00148FB000104E
-:1010A0000A0004B827BD0018240200205082002541
-:1010B0008FB000100E000F0A020020211040002007
-:1010C0008FBF0014020020218FB0001000002821E3
-:1010D0000A00025E27BD0018020020218FBF001405
-:1010E0008FB000100A00058027BD00189745010C3D
-:1010F000020020218FBF00148FB000100A0005A04D
-:1011000027BD0018020020218FB000100A0005C57D
-:1011100027BD00189345010D020020218FB000105B
-:101120000A00060F27BD0018020020218FBF0014FF
-:101130008FB000100A0005EB27BD00188FBF001408
-:101140008FB0001003E0000827BD00188F4202781E
-:101150000440FFFE2402000234840080AF440240B9
-:10116000A34202443C02100003E00008AF420278B0
-:101170003C04080094844B6A3C0208008C424B7487
-:101180003083FFFF000318C000431021AF42003C32
-:101190003C0208008C424B70AF4200383C020050C9
-:1011A00034420008AF4200300000000000000000A0
-:1011B000000000008F420000304200201040FFFD80
-:1011C000000000008F4204003C010800AC224B608C
-:1011D0008F4204043C010800AC224B643C02002016
-:1011E000AF420030000000003C02080094424B680F
-:1011F0003C03080094634B6C3C05080094A54B6EBF
-:1012000024840001004310213083FFFF3C010800CB
-:10121000A4224B683C010800A4244B6A1465000317
-:10122000000000003C010800A4204B6A03E0000815
-:10123000000000003C05000A27BDFFE80345282107
-:101240003C04080024844B50AFBF00100E00051D65
-:101250002406000A3C02080094424B523C0308005A
-:1012600094634B6E3042000F244200030043180485
-:1012700024027FFF0043102B10400002AF83001CAC
-:101280000000000D0E00042A000000003C020800CF
-:1012900094424B5A8FBF001027BD001803E000088E
-:1012A000A74200A23C02000A034210219443000618
-:1012B0003C02080094424B5A3C010800A4234B56C0
-:1012C000004310238F83001C00021400000214034B
-:1012D0000043102B03E000083842000127BDFFE85F
-:1012E000AFBF00103C02000A0342102194420006E6
-:1012F0003C010800A4224B560E00047700000000B9
-:101300005440FFF93C02000A8FBF001003E00008C0
-:1013100027BD001827BDFFE8AFBF00100E000477FF
-:101320000000000010400003000000000E000485D3
-:10133000000000003C0208008C424B608FBF001090
-:1013400027430400AF4200383C0208008C424B6443
-:1013500027BD0018AF830020AF42003C3C020005CF
-:10136000AF42003003E00008AF8000188F82001801
-:101370003C0300060002114000431025AF4200303C
-:101380000000000000000000000000008F4200008C
-:10139000304200101040FFFD27420400AF820020C1
-:1013A00003E00008AF8000183C0608008CC64B64C0
-:1013B0008F8500188F8300203C02080094424B5A0E
-:1013C00027BDFFE024A50001246300202442000182
-:1013D00024C70020AFB10014AFB00010AFBF001899
-:1013E000AF850018AF8300203C010800A4224B5AAF
-:1013F000309000FF3C010800AC274B6404C100089A
-:101400000000882104E00006000000003C02080003
-:101410008C424B60244200013C010800AC224B602E
-:101420003C02080094424B5A3C03080094634B680A
-:101430000010202B004310262C42000100441025F0
-:10144000144000048F830018240200101462000F5F
-:10145000000000000E0004A9241100013C03080054
-:1014600094634B5A3C02080094424B681462000398
-:10147000000000000E00042A000000001600000317
-:10148000000000000E000493000000003C03080070
-:1014900094634B5E3C02080094424B5C2463000161
-:1014A0003064FFFF3C010800A4234B5E148200035C
-:1014B000000000003C010800A4204B5E1200000662
-:1014C000000000003C02080094424B5AA74200A2D0
-:1014D0000A00050B022010210E0004770000000016
-:1014E00010400004022010210E00048500000000BE
-:1014F000022010218FBF00188FB100148FB0001090
-:1015000003E0000827BD00203084FFFF30A5FFFF67
-:101510000000182110800007000000003082000148
-:101520001040000200042042006518210A00051343
-:101530000005284003E000080060102110C00006EC
-:1015400024C6FFFF8CA2000024A50004AC8200008A
-:101550000A00051D2484000403E0000800000000C8
-:1015600010A0000824A3FFFFAC86000000000000CC
-:10157000000000002402FFFF2463FFFF1462FFFA53
-:101580002484000403E0000800000000240200019D
-:10159000AF62000CA7620010A7620012A7620014DD
-:1015A00003E00008A76200163082007F034210218A
-:1015B0003C08000E004818213C0208008C42002024
-:1015C00027BDFFD82407FF80AFB3001CAFB20018BF
-:1015D000AFB10014AFB00010AFBF00200080802179
-:1015E00030B100FF0087202430D200FF1040002FD0
-:1015F00000009821AF44002C9062000024030050AA
-:10160000304200FF1443000E000000003C020800BE
-:101610008C4200E00202102100471024AF42002C4F
-:101620003C0208008C4200E0020210213042007FA0
-:101630000342102100481021944200D43053FFFF90
-:101640000E000493000000003C02080094424B5E30
-:101650008F8300200011340000C2302500122C00BE
-:101660003C02400000C2302534A50001AC700000EF
-:101670008FBF0020AC6000048FB20018AC7300086C
-:101680008FB10014AC60000C8FB3001CAC6500106F
-:101690008FB00010AC60001424040001AC6000188E
-:1016A00027BD00280A0004B8AC66001C8FBF0020CC
-:1016B0008FB3001C8FB200188FB100148FB00010D0
-:1016C00003E0000827BD00289343010F2402001007
-:1016D0001062000E2865001110A0000724020012FD
-:1016E000240200082405003A1062000600003021A0
-:1016F00003E0000800000000240500351462FFFC30
-:10170000000030210A000538000000008F420074FC
-:1017100024420FA003E00008AF62000C27BDFFE8E1
-:10172000AFBF00100E00025E240500018FBF001045
-:1017300024020001A762001227BD00182402000144
-:1017400003E00008A360002227BDFFE0AFB1001452
-:10175000AFB00010AFBF001830B1FFFF0E00025055
-:10176000008080219362003F24030004304200FF88
-:101770001443000C02002021122000082402000A59
-:101780000E00053100000000936200052403FFFEF7
-:1017900000431024A362000524020012A362003F4C
-:1017A000020020210E000259A360008116200003D0
-:1017B000020020210E0005950000000002002021FB
-:1017C000322600FF8FBF00188FB100148FB00010B9
-:1017D000240500380A00053827BD002027BDFFE09A
-:1017E000AFBF001CAFB20018AFB10014AFB0001013
-:1017F0000E000250008080210E0005310000000024
-:101800009362003F24120018305100FF123200038F
-:101810000200202124020012A362003F936200050F
-:101820002403FFFE004310240E000259A3620005AA
-:10183000020020212405002016320007000030217C
-:101840008FBF001C8FB200188FB100148FB0001032
-:101850000A00025E27BD00208FBF001C8FB2001857
-:101860008FB100148FB00010240500390A0005382C
-:1018700027BD002027BDFFE8AFB00010AFBF0014A8
-:101880009742010C2405003600808021144000108E
-:10189000304600FF0E00025000000000240200123B
-:1018A000A362003F93620005344200100E00053130
-:1018B000A36200050E00025902002021020020212F
-:1018C0000E00025E240500200A000604000000004D
-:1018D0000E000538000000000E000250020020211A
-:1018E000936200232403FF9F020020210043102461
-:1018F0008FBF00148FB00010A36200230A000259AA
-:1019000027BD001827BDFFE0AFBF0018AFB100141E
-:10191000AFB0001030B100FF0E00025000808021F7
-:10192000240200120E000531A362003F0E0002598E
-:101930000200202102002021022030218FBF001848
-:101940008FB100148FB00010240500350A0005384F
-:1019500027BD0020A380002C03E00008A380002DF9
-:101960008F4202780440FFFE8F820034AF42024073
-:1019700024020002A34202443C02100003E00008DB
-:10198000AF4202783C0360008C6254003042000891
-:101990001440FFFD000000008C625408AF82000C70
-:1019A00024020052AC605408AC645430AC6254342D
-:1019B0002402000803E00008AC6254003C0260000E
-:1019C0008C42540030420008104000053C03600087
-:1019D0008C625400304200081440FFFD00000000FB
-:1019E0008F83000C3C02600003E00008AC43540805
-:1019F00090A3000024020005008040213063003FD6
-:101A000000004821146200050000502190A2001C33
-:101A100094A3001E304900FF306AFFFFAD00000CA8
-:101A2000AD000010AD000024950200148D05001CCF
-:101A30008D0400183042FFFF0049102300021100FE
-:101A4000000237C3004038210086202300A2102B5B
-:101A50000082202300A72823AD05001CAD04001838
-:101A6000A5090014A5090020A50A001603E0000836
-:101A7000A50A00228F4201F80440FFFE2402000262
-:101A8000AF4401C0A34201C43C02100003E00008BF
-:101A9000AF4201F83C0208008C4200B427BDFFE8C9
-:101AA000AFBF001424420001AFB000103C01080099
-:101AB000AC2200B48F4300243C02001F30AA00FF78
-:101AC0003442FF8030D800FF006280240080F8217B
-:101AD00030EF00FF1158003B01405821240CFF80DB
-:101AE0003C19000A3163007F000310C00003194055
-:101AF000006218213C0208008C4200DC25680001CD
-:101B0000310D007F03E21021004310213043007F9C
-:101B100003431821004C102400794821AF420024CF
-:101B20008D220024016C1824006C7026AD22000C5C
-:101B30008D220024310800FFAD22001095220014F0
-:101B4000952300208D27001C3042FFFF3063FFFFEC
-:101B50008D2600180043102300021100000227C345
-:101B60000040282100C4302300E2102B00C23023A3
-:101B700000E53823AD27001CAD2600189522002073
-:101B8000A522001495220022154B000AA52200165A
-:101B90008D2300248D220008254600013145008058
-:101BA0001462000430C4007F108F000238AA008045
-:101BB00000C0502151AF000131C800FF1518FFC906
-:101BC000010058218F8400343082007F03421821A5
-:101BD0003C02000A006218212402FF8000822024B7
-:101BE000AF440024A06A0079A06A00838C62005090
-:101BF0008F840034AC6200708C6500743C027FFFFF
-:101C00003442FFFF00A228240E00066BAC6500746E
-:101C1000AF5000248FBF00148FB0001003E0000805
-:101C200027BD001827BDFFC0AFBE0038AFB70034D6
-:101C3000AFB5002CAFB20020AFB1001CAFB00018A0
-:101C4000AFBF003CAFB60030AFB40028AFB3002444
-:101C50008F4500248F4600288F43002C3C02001F34
-:101C60003442FF800062182400C230240080A82182
-:101C7000AFA3001400A2F0240E00062FAFA60010A0
-:101C80003C0208008C4200E02410FF8003608821A1
-:101C900002A2102100501024AF4200243C02080090
-:101CA0008C4200E002A210213042007F0342182142
-:101CB0003C02000A00629021924200D293630084A9
-:101CC000305700FF306300FF24020001106200342F
-:101CD000036020212402000214620036000000008C
-:101CE0000E001216024028219223008392220083C4
-:101CF0003063007F3042007F000210C000031940B3
-:101D0000006218213C0208008C4200DC02A2102173
-:101D10000043382100F01024AF42002892250078BB
-:101D20009224008330E2007F034218213C02000C21
-:101D300014850007006280212402FFFFA24200F107
-:101D40002402FFFFA64200F20A0007272402FFFF39
-:101D500096020020A24200F196020022A64200F262
-:101D60008E020024AE4200F492220083A24200F0D0
-:101D70008E4200C8AE4200FC8E4200C4AE4200F863
-:101D80008E220050AE4201008E4200CCAE420104D1
-:101D9000922200853042003F0A0007823442004010
-:101DA0000E00123902402821922200850A00078283
-:101DB0003042003F936200852403FFDF3042003F42
-:101DC000A36200859362008500431024A36200850E
-:101DD0009363008393620078307400FF304200FF09
-:101DE00010540036240AFF803C0C000C3283007F24
-:101DF000000310C000031940006218213C020800D3
-:101E00008C4200DC268800013109007F02A21021EB
-:101E10000043382130E2007F0342182100EA1024F9
-:101E2000AF420028006C80218E020024028A182410
-:101E3000006A5826AE02000C8E020024310800FF12
-:101E4000AE02001096020014960300208E07001CBC
-:101E50003042FFFF3063FFFF8E060018004310235F
-:101E600000021100000227C30040282100C43023D3
-:101E700000E2102B00C2302300E53823AE07001C1F
-:101E8000AE06001896020020A60200149602002258
-:101E9000A602001692220079304200FF105400077B
-:101EA0000000000051370001316800FF92220078E5
-:101EB000304200FF1448FFCD0100A0219222008390
-:101EC000A22200798E2200500A0007E2AE220070A2
-:101ED000A22200858E22004C2405FF80AE42010C18
-:101EE0009222008534420020A2220085924200D135
-:101EF0003C0308008C6300DC305400FF3C02080007
-:101F00008C4200E400143140001420C002A31821C8
-:101F100000C4202102A210210064382100461021B3
-:101F20000045182400E52824AF450028AF43002CC5
-:101F30003042007F924400D030E3007F03422821EA
-:101F4000034318213C02000C006280213C02000E79
-:101F5000309600FF00A298211296002A000000008F
-:101F60008E02000C02002021026028211040002572
-:101F7000261000280E00064A000000009262000DA4
-:101F800026830001307400FF3042007FA262000D02
-:101F90002404FF801697FFF0267300203C020800FF
-:101FA0008C4200DC0000A02102A210210044102479
-:101FB000AF4200283C0208008C4200E43C030800C9
-:101FC0008C6300DC02A2102100441024AF42002CDC
-:101FD0003C0208008C4200E402A318213063007F19
-:101FE00002A210213042007F034220210343182126
-:101FF0003C02000C006280213C02000E0A0007A493
-:10200000008298218E4200D8AE2200508E4200D825
-:10201000AE22007092250083924600D19223008365
-:10202000924400D12402FF8000A228243063007F64
-:10203000308400FF00A628250064182A10600002E2
-:1020400030A500FF38A50080A2250083A2250079D5
-:102050000E00063D000000009222007E02A020211A
-:10206000A222007A8E2300743C027FFF3442FFFFDD
-:10207000006218240E00066BAE2300748FA20010BD
-:10208000AF5E00248FBF003CAF4200288FBE0038F7
-:102090008FA200148FB700348FB600308FB5002C9C
-:1020A0008FB400288FB300248FB200208FB1001CA2
-:1020B0008FB0001827BD004003E00008AF42002C9D
-:1020C00090A2000024420001A0A200003C030800EE
-:1020D0008C6300F4304200FF1443000F0080302175
-:1020E000A0A000003C0208008C4200E48F84003471
-:1020F000008220213082007F034218213C02000C24
-:10210000006218212402FF8000822024ACC300005A
-:1021100003E00008AF4400288C8200002442002025
-:1021200003E00008AC82000094C200003C080800F4
-:10213000950800CA30E7FFFF008048210102102106
-:10214000A4C2000094C200003042FFFF00E2102B46
-:1021500054400001A4C7000094A200003C03080002
-:102160008C6300CC24420001A4A2000094A20000D1
-:102170003042FFFF544300078F8600280107102BD1
-:10218000A4A000005440000101003821A4C70000B1
-:102190008F8600288CC4001CAF44003C94A2000031
-:1021A0008F43003C3042FFFF000210C00062182144
-:1021B000AF43003C8F42003C008220231880000483
-:1021C000000000008CC200180A00084324420001ED
-:1021D0008CC20018AF4200383C020050344200105C
-:1021E000AF420030000000000000000000000000CE
-:1021F0008F420000304200201040FFFD0000000030
-:102200008F420404AD2200048F420400AD2200007E
-:102210003C020020AF42003003E000080000000054
-:1022200027BDFFE0AFB20018AFB10014AFB000108F
-:10223000AFBF001C94C2000000C080213C12080007
-:10224000965200C624420001A60200009603000038
-:1022500094E2000000E03021144300058FB100300B
-:102260000E000818024038210A000875000000001E
-:102270008C8300048C820004244200400461000727
-:10228000AC8200048C8200040440000400000000C2
-:102290008C82000024420001AC8200009602000003
-:1022A0003042FFFF50520001A600000096220000BD
-:1022B00024420001A62200008F82002896230000FD
-:1022C00094420016144300048FBF001C2402000136
-:1022D000A62200008FBF001C8FB200188FB100141F
-:1022E0008FB0001003E0000827BD00208F89002870
-:1022F00027BDFFE0AFBF00188D220028274804004B
-:1023000030E700FFAF4200388D22002CAF8800304C
-:10231000AF42003C3C020005AF420030000000002C
-:1023200000000000000000000000000000000000AD
-:10233000000000008C82000C8C82000CAD020000BA
-:102340008C820010AD0200048C820018AD020008DF
-:102350008C82001CAD02000C8CA20014AD02001097
-:102360008C820020AD02001490820005304200FFF4
-:1023700000021200AD0200188CA20018AD02001C71
-:102380008CA2000CAD0200208CA20010AD02002433
-:102390008CA2001CAD0200288CA20020AD02002CF3
-:1023A000AD060030AD000034978300263402FFFFF5
-:1023B00014620002006020213404FFFF10E00011CD
-:1023C000AD04003895230036952400362402000120
-:1023D0003063FFFF000318C20069182190650040B8
-:1023E000308400070082100400451025A0620040E0
-:1023F0008F820028944200563042FFFF0A0008DC1A
-:10240000AD02003C952300369524003624020001DD
-:102410003063FFFF000318C2006918219065004077
-:1024200030840007008210040002102700451024A9
-:10243000A0620040AD00003C000000000000000071
-:10244000000000003C02000634420040AF42003071
-:102450000000000000000000000000008F420000AB
-:10246000304200101040FFFD8F860028AF880030FA
-:1024700024C2005624C7003C24C4002824C50032CE
-:1024800024C600360E000856AFA200108FBF0018F9
-:1024900003E0000827BD00208F8300243C060800CD
-:1024A0008CC600E88F82003430633FFF0003198040
-:1024B00000461021004310212403FF803046007F96
-:1024C00000431024AF420028034618213C02000CB0
-:1024D0000062302190C2000D30A500FF00003821BD
-:1024E00034420010A0C2000D8F8900288F8A00247A
-:1024F00095230036000A13823048000324020001AD
-:10250000A4C3000E1102000B2902000210400005B6
-:10251000240200021100000C240300010A0009201B
-:102520000000182111020006000000000A00092026
-:10253000000018218CC2002C0A000920244300014D
-:102540008CC20014244300018CC200180043102BDD
-:1025500050400009240700012402002714A20003B0
-:10256000000000000A00092C240700019522003E0B
-:1025700024420001A522003E000A138230430003DA
-:102580002C62000210400009008028211460000421
-:102590000000000094C200360A00093C3046FFFFEC
-:1025A0008CC600380A00093C008028210000302138
-:1025B0003C04080024844B780A00088900000000CD
-:1025C000274901008D22000C9523000601202021BF
-:1025D000000216023046003F3063FFFF240200274E
-:1025E00000C0282128C7002810C2000EAF83002495
-:1025F00010E00008240200312402002110C200096A
-:102600002402002510C200079382002D0A00095BF6
-:102610000000000010C200059382002D0A00095B33
-:10262000000000000A0008F4000000000A0006266E
-:102630000000000095230006912400058D25000C64
-:102640008D2600108D2700188D28001C8D29002054
-:10265000244200013C010800A4234B7E3C010800F9
-:10266000A0244B7D3C010800AC254B843C010800B4
-:10267000AC264B883C010800AC274B903C0108007D
-:10268000AC284B943C010800AC294B9803E00008AF
-:10269000A382002D8F87002827BDFFC0AFB3003471
-:1026A000AFB20030AFB1002CAFB00028AFBF0038E0
-:1026B0003C0208008C4200D094E3003030B0FFFFB1
-:1026C000005010073045FFFF3063FFFF00C0982126
-:1026D000A7A200103C110800963100C614A3000602
-:1026E0003092FFFF8CE2002424420030AF42003CD5
-:1026F0000A0009948CE2002094E200323042FFFF8D
-:1027000054A2000827A400188CE2002C24420030B8
-:10271000AF42003C8CE20028AF4200380A0009A218
-:102720008F84002827A5001027A60020022038212A
-:102730000E000818A7A000208FA200182442003025
-:10274000AF4200388FA2001CAF42003C8F840028AB
-:102750003C020005AF42003094820034274304005D
-:102760003042FFFF0202102B14400007AF830030FD
-:1027700094820054948300340202102100431023F9
-:102780000A0009B63043FFFF94830054948200345A
-:102790000223182100501023006218233063FFFF2A
-:1027A000948200163042FFFF144300030000000033
-:1027B0000A0009C424030001948200163042FFFF7E
-:1027C0000043102B104000058F82003094820016C9
-:1027D000006210233043FFFF8F820030AC530000B3
-:1027E000AC400004AC520008AC43000C3C020006B4
-:1027F00034420010AF420030000000000000000032
-:10280000000000008F420000304200101040FFFD29
-:10281000001018C2006418219065004032040007BF
-:10282000240200018FBF00388FB300348FB2003014
-:102830008FB1002C8FB000280082100400451025B5
-:1028400027BD004003E00008A062004027BDFFA8AC
-:10285000AFB60050AFB5004CAFB40048AFB30044C2
-:10286000AFB1003CAFBF0054AFB20040AFB00038D2
-:102870008C9000003C0208008C4200E88F860034F7
-:10288000960300022413FF8000C2302130633FFF13
-:102890000003198000C3382100F3102490B2000017
-:1028A000AF42002C9203000230E2007F034230214D
-:1028B0003C02000E00C28821306300C024020040A8
-:1028C0000080A82100A0B021146200260000A021F1
-:1028D0008E3400388E2200181440000224020001B9
-:1028E000AE2200189202000D304200201440001564
-:1028F0008F8200343C0308008C6300DC001238C077
-:10290000001231400043102100C730210046382119
-:1029100030E300073C02008030E6007800C230253A
-:102920000343182100F31024AF4208002463090078
-:10293000AF4608108E2200188C6300080043102157
-:10294000AE2200188E22002C8E2300182442000193
-:102950000062182B1060003D000000000A000A7899
-:1029600000000000920300022402FFC00043102474
-:10297000304200FF1440000524020001AE2200187E
-:10298000962200360A000A613054FFFF8E2200149E
-:1029900024420001AE22001892020000000216003C
-:1029A0000002160304410029000000009602000204
-:1029B00027A4001000802821A7A20016960200027A
-:1029C00024070001000030213042FFFFAF820024C5
-:1029D0000E000889AFA0001C960300023C0408000A
-:1029E0008C8400E88F82003430633FFF000319803D
-:1029F00000441021004310213043007F3C05000CAF
-:102A00000053102403431821AF4200280065182109
-:102A10009062000D001221403042007FA062000D44
-:102A20003C0308008C6300E48F82003400431021D3
-:102A30000044382130E2007F03421021004510217C
-:102A400000F31824AF430028AEA200009222000D2C
-:102A5000304200101040001302A020218F83002874
-:102A60008EA40000028030219462003E2442FFFFC9
-:102A7000A462003E948400029625000E3084FFFF7D
-:102A80000E00097330A5FFFF8F82002894430034A5
-:102A90009622000E1443000302A02021240200010C
-:102AA000A382002C02C028210E0007FE00000000B7
-:102AB0008FBF00548FB600508FB5004C8FB40048C4
-:102AC0008FB300448FB200408FB1003C8FB000380C
-:102AD00003E0000827BD00588F82002827BDFFD0E3
-:102AE000AFB40028AFB20020AFBF002CAFB30024BA
-:102AF000AFB1001CAFB00018904400D0904300D19B
-:102B00000000A021309200FFA3A30010306300FF5B
-:102B10008C5100D88C5300DC1072002B2402000171
-:102B20003C0308008C6300E493A400108F820034FF
-:102B30002406FF800004214000431021004410219E
-:102B40003043007F00461024AF4200280343182181
-:102B50003C02000C006218218C62000427A40014BF
-:102B600027A50010022280210270102304400015C6
-:102B7000AFA300149062000D00C21024304200FF89
-:102B800014400007020088219062000D344200408A
-:102B90000E0007FEA062000D0A000ABD93A20010FD
-:102BA0000E0009E1241400018F830028AC7000D8C6
-:102BB00093A20010A06200D193A200101452FFD87B
-:102BC0000000000024020001168200048FBF002CC8
-:102BD0000E000626000000008FBF002C8FB40028D6
-:102BE0008FB300248FB200208FB1001C8FB000186B
-:102BF00003E0000827BD003027BDFFD8AFB3001C9D
-:102C0000AFB20018AFB10014AFB00010AFBF0020DA
-:102C10000080982100E0802130B1FFFF0E00049376
-:102C200030D200FF000000000000000000000000A3
-:102C30008F820020AC510000AC520004AC5300085D
-:102C4000AC40000CAC400010AC400014AC4000188C
-:102C50003C03080094634B5E02038025AC50001CCB
-:102C6000000000000000000000000000240400013B
-:102C70008FBF00208FB3001C8FB200188FB10014DB
-:102C80008FB000100A0004B827BD002827BDFFE858
-:102C9000AFB00010AFBF001430A5FFFF30C600FF7B
-:102CA0000080802124020C80AF420024000000003C
-:102CB0000000000000000000000000000000000014
-:102CC0000E000ACC000000003C040800248400E050
-:102CD0008C8200002403FF808FBF001402021021A9
-:102CE00000431024AF4200248C8200003C03000A01
-:102CF000020280213210007F035010218FB000109B
-:102D00000043102127BD001803E00008AF8200280F
-:102D100027BDFFE8AFBF00108F4401403C0308000F
-:102D20008C6300E02402FF80AF840034008318210C
-:102D300000621024AF4200243C02000803424021FC
-:102D4000950500023063007F3C02000A034318210E
-:102D50000062182130A5FFFF3402FFFF0000302180
-:102D60003C07602010A20006AF8300282402FFFF6A
-:102D7000A5020002946500D40E000AF130A5FFFF01
-:102D80008FBF001024020C8027BD001803E000084C
-:102D9000AF4200243C020008034240219502000299
-:102DA0003C0A0800954A00C63046FFFF14C00007E1
-:102DB0003402FFFF8F8200288F8400343C0760209C
-:102DC000944500D40A000B5A30A5FFFF10C200241E
-:102DD0008F87002894E2005494E400163045FFFFEA
-:102DE00000A6102300A6182B3089FFFF10600004F6
-:102DF0003044FFFF00C51023012210233044FFFFA1
-:102E0000008A102B1040000C012A1023240200011C
-:102E1000A50200162402FFFFA502000294E500D4DB
-:102E20008F8400340000302130A5FFFF3C07602074
-:102E30000A000AF1000000000044102A10400008B7
-:102E4000000000009502001630420001104000040E
-:102E5000000000009742007E24420014A5020016E4
-:102E600003E00008000000008F84002827BDFFE079
-:102E7000AFBF0018948200349483003E1060001AA3
-:102E80003048FFFF9383002C2402000114620027C6
-:102E90008FBF00188F820028000818C23108000771
-:102EA000006218212447003A244900542444002099
-:102EB000244500302446003490620040304200FF38
-:102EC0000102100730420001104000168FBF0018A9
-:102ED0000E000856AFA900108F82002894420034DB
-:102EE0000A000B733048FFFF94830036948200344D
-:102EF0001043000E8FBF001894820036A482003465
-:102F000094820056A48200548C82002CAC8200244F
-:102F100094820032A48200309482003CA482003A61
-:102F20008FBF00180A000B3327BD002003E0000804
-:102F300027BD002027BDFFE8AFBF00108F4A01006A
-:102F40003C0508008CA500E03C02080090424B8440
-:102F50003C0C0800958C4B7E01452821304B003FEE
-:102F600030A2007F03424021396900323C02000A4E
-:102F70003963003F2C630001010240212D2900012B
-:102F80002402FF8000A2282401234825AF8A0034B0
-:102F900000801821AF450024000030210080282146
-:102FA00024070001AF8800283C04080024844B78E3
-:102FB000AF8C002415200007A380002D24020020E0
-:102FC0005562000F006020213402FFFF5582000C83
-:102FD000006020212402002015620005000000008E
-:102FE0008C6300142402FFFF106200070000000041
-:102FF0000E000889000000000A000BD0000000004D
-:103000000E0008F4016028210E000B68000000008B
-:103010008FBF001024020C8027BD001803E00008B9
-:10302000AF4200243C0208008C4200E027BDFFA014
-:10303000AFB1003C008210212411FF80AFBE0058C8
-:10304000AFB70054AFB20040AFB00038AFBF005CC4
-:10305000AFB60050AFB5004CAFB40048AFB30044BA
-:10306000005110248F4800248F4900288F470028E2
-:10307000AF4200243C0208008C4200E00080902116
-:1030800024060006008210213042007F03421821EE
-:103090003C02000A006280213C02001F3442FF8093
-:1030A00000E2382427A40010260500F00122F024B5
-:1030B0000102B8240E00051DAFA700308FA2001832
-:1030C000AE0200C48FA2001CAE0200C88FA2002472
-:1030D000AE0200CC93A40010920300D12402FF8022
-:1030E0000082102400431025304900FF3083007F08
-:1030F0003122007F0062102A10400004000310C03B
-:1031000001311026304900FF000310C000031940B0
-:10311000006218213C0208008C4200DC920400D2BC
-:10312000024210210043102100511024AF42002818
-:1031300093A300103063007F000310C00003194008
-:10314000006218213C0208008C4200DC024210217F
-:10315000004310213042007F034218213C02000C42
-:10316000006240218FA300142402FFFF1062003090
-:10317000309500FF93A2001195030014304400FF26
-:103180003063FFFF0064182B1060000D000000008A
-:10319000950400148D07001C8D0600183084FFFF75
-:1031A00000442023000421000000102100E4382105
-:1031B00000E4202B00C230210A000C4A00C4302158
-:1031C000950400148D07001C8D0600183084FFFF45
-:1031D000008220230004210000001021008018211B
-:1031E00000C2302300E4202B00C4302300E3382346
-:1031F000AD07001CAD06001893A20011A502001433
-:1032000097A20012A50200168FA20014AD020010B2
-:103210008FA20014AD02000C93A20011A5020020A1
-:1032200097A20012A50200228FA20014AD02002472
-:103230002406FF80024610243256007FAF4200244D
-:10324000035618213C02000A006280218E02004CC5
-:103250008FA200203124007F000428C0AE0200505D
-:103260008FA200200004214000852821AE020070BA
-:1032700093A2001001208821A202008393A20010D3
-:10328000A2020079920200853042003FA20200852E
-:103290003C0208008C4200DC024210210045102153
-:1032A00000461024AF42002C3C0208008C4200E48F
-:1032B0003C0308008C6300DC024210210044102112
-:1032C00000461024AF4200283C0208008C4200E473
-:1032D00002431821006518210242102100441021E8
-:1032E0003042007F3063007F93A50010034220210D
-:1032F000034318213C02000E006240213C02000CF6
-:1033000010B1008C008248213233007F1660001912
-:103310002404FF803C0208008C4200DC02421021A1
-:1033200000441024AF42002C3C0208008C4200E410
-:103330003C0308008C6300DC02421021004410248E
-:10334000AF4200283C0208008C4200E402431821EE
-:103350003063007F024210213042007F034220216F
-:10336000034318213C02000E006240213C02000C85
-:10337000008248219124000D2414FF8000001021B8
-:1033800000942025A124000D950400029505001449
-:103390008D07001C3084FFFF30A5FFFF8D0600184D
-:1033A000008520230004210000E4382100C23021E0
-:1033B00000E4202B00C43021AD07001CAD0600182E
-:1033C00095020002A5020014A50000168D02000857
-:1033D000AD0200108D020008AD02000C9502000243
-:1033E000A5020020A50000228D020008AD020024E5
-:1033F0009122000D30420040104000422622000180
-:103400003C0208008C4200E0A3B300283C10000AF4
-:103410000242102100541024AF4200243C02080054
-:103420008C4200E0A380002C27A4002C0242102133
-:103430003042007F03421821007018218C6200D8AE
-:103440008D26000427A50028AFA9002C00461021D6
-:10345000AC6200D80E0009E1AF83002893A30028D6
-:103460008F8200280E000626A04300D10E000B68B4
-:103470000000000002541024AF4200243C02080067
-:103480008C4200DC00132940001320C000A420213E
-:10349000024210210044102100541024AF42002C9D
-:1034A0003C0208008C4200E43C0308008C6300DC12
-:1034B00003563021024210210045102100541024EF
-:1034C000AF4200283C0208008C4200E4024318216D
-:1034D0000064182102421021004510213042007F73
-:1034E0003063007F03422021034318213C02000E79
-:1034F000006240213C02000C00D080210082482163
-:10350000262200013043007F14750005304400FF7F
-:103510002403FF800223102400431026304400FFC0
-:1035200093A2001000808821250800281444FF760B
-:103530002529002093A400108FA300142402FFFF6C
-:103540001062000A308900FF2482000124830001F8
-:103550003042007F14550005306900FF2403FF80CE
-:103560000083102400431026304900FF92020078A7
-:10357000305300FF11330032012088213C02080043
-:103580008C4200DC3225007F000520C00005294068
-:1035900000A42021024210212406FF8000441021B3
-:1035A00000461024AF42002C3C0308008C6300DC72
-:1035B0003C0208008C4200E4024318210242102120
-:1035C0000045102100641821004610243063007F5C
-:1035D000AF420028034318213C02000E0062402144
-:1035E0003C0208008C4200E48D06000C0100202102
-:1035F00002421021004510213042007F0342182171
-:103600003C02000C0062482110C0000D012028215E
-:103610000E00064A000000002402FF800222182447
-:1036200026240001006228263082007F1455000203
-:10363000308300FF30A300FF1473FFD000608821A7
-:103640008E0300743C027FFF3442FFFF00621824A7
-:10365000AE0300740E00066B02402021AF57002419
-:103660008FA20030AF5E00288FBF005C8FBE005875
-:103670008FB700548FB600508FB5004C8FB4004800
-:103680008FB300448FB200408FB1003C8FB0003840
-:1036900027BD006003E00008AF42002C27BDFFD823
-:1036A000AFB1001CAFBF0020AFB000182751018898
-:1036B000922200032408FF803C03000A3047007F69
-:1036C000A3A700108F4601803C0208008C4200E056
-:1036D000AF86003400C2282100A81024AF42002485
-:1036E0009224000030A2007F0342102100431021E9
-:1036F000AF8200283084007F24020002148200255B
-:10370000000719403C0208008C4200E400C210216E
-:103710000043282130A2007F0342182100A8102472
-:10372000AF4200283C02000C006218219062000D9C
-:10373000AFA3001400481025A062000D8FA3001451
-:103740009062000D304200405040006A8FBF002060
-:103750008F860028A380002C27A400148CC200D8D8
-:103760008C63000427A50010004310210E0009E11E
-:10377000ACC200D893A300108F8200280E0006264A
-:10378000A04300D10E000B68000000000A000E0BE1
-:103790008FBF00200E00062F00C020210E00063D26
-:1037A000000000003C020008034280219223000137
-:1037B0009202007B1443004F8FBF00209222000032
-:1037C0003044007F24020004108200172882000584
-:1037D00010400006240200052402000310820007A6
-:1037E0008FB1001C0A000E0C0000000010820012B5
-:1037F0008FBF00200A000E0C8FB1001C92050083C1
-:10380000920600788E0700748F84003430A500FF84
-:1038100000073E0230C600FF0E00067330E7007F4F
-:103820000A000E0B8FBF00200E000BD78F840034D0
-:103830000A000E0B8FBF002024020C80AF42002430
-:103840009202003E30420040104000200000000084
-:103850009202003E00021600000216030441000618
-:10386000000000008F8400340E0005A024050093A2
-:103870000A000E0B8FBF00209202003F24030018A5
-:10388000304200FF1443000C8F84003424050039BB
-:103890000E000538000030210E0002508F840034E5
-:1038A00024020012A202003F0E0002598F8400344D
-:1038B0000A000E0B8FBF0020240500360E000538CD
-:1038C000000030210A000E0B8FBF00200E000250B6
-:1038D0008F8400349202000534420020A2020005C9
-:1038E0000E0002598F8400340E000FC08F84003404
-:1038F0008FBF00208FB1001C8FB0001824020C80F5
-:1039000027BD002803E00008AF42002427BDFFE8E0
-:10391000AFB00010AFBF001427430100946200084D
-:103920000002140000021403044100020000802180
-:103930002410000194620008304200801040001AF8
-:10394000020010219462000830422000104000164E
-:10395000020010218C6300183C021C2D344219ED2A
-:10396000240600061062000F3C0760213C0208009C
-:103970008C4200D4104000078F8200288F830028DB
-:10398000906200623042000F34420040A062006248
-:103990008F8200288F840034944500D40E000AF1F1
-:1039A00030A5FFFF020010218FBF00148FB0001060
-:1039B00003E0000827BD001827BDFFE0AFB10014E9
-:1039C000AFB00010A380002CAFBF00188F450100DE
-:1039D0003C0308008C6300E02402FF80AF850034C4
-:1039E00000A318213064007F0344202100621824C2
-:1039F0003C02000A00822021AF430024275001002E
-:103A00008E0200148C8300DCAF8400280043102356
-:103A100018400004000088218E0200140E000A8461
-:103A2000AC8200DC9202000B24030002304200FF53
-:103A30001443002F0000000096020008304300FFEE
-:103A40002402008214620005240200840E00093E54
-:103A5000000000000A000E97000000001462000938
-:103A6000240200818F8200288F8400343C0760216B
-:103A7000944500D49206000530A5FFFF0A000E868B
-:103A800030C600FF14620027000000009202000A06
-:103A9000304300FF306200201040000430620040DC
-:103AA0008F8400340A000E82240600401040000477
-:103AB000000316008F8400340A000E8224060041A1
-:103AC00000021603044100178F84003424060042CC
-:103AD0008F8200283C076019944500D430A5FFFF71
-:103AE0000E000AF1000000000A000E97000000001E
-:103AF0009202000B24030016304200FF1043000620
-:103B0000000000009202000B24030017304200FF67
-:103B100014430004000000000E000E11000000001D
-:103B2000004088210E000B68000000009202000A8D
-:103B3000304200081040000624020C808F850028C7
-:103B40003C0400080E0011EE0344202124020C80E6
-:103B5000AF4200248FBF0018022010218FB0001048
-:103B60008FB1001403E0000827BD002027BDFFE847
-:103B7000AFBF0014AFB000108F5000243C0308000A
-:103B80008C6300E08F4501002402FF8000A3182110
-:103B90003064007F03442021006218243C02000AA4
-:103BA00000822021AF850034AF4300249082006260
-:103BB000AF8400283042000F34420050A0820062DF
-:103BC0003C02001F3442FF800E00062602028024C1
-:103BD000AF5000248FBF00148FB0001003E0000826
-:103BE00027BD00183C0208008C4200201040001D38
-:103BF0002745010090A300093C0200080342202150
-:103C000024020018546200033C0200080A000ED887
-:103C10002402000803422021240200161462000539
-:103C20002402001724020012A082003F0A000EE2C4
-:103C300094A700085462000694A700089362000548
-:103C40002403FFFE00431024A362000594A700088C
-:103C500090A6001B8CA4000094A500060A000ACCC4
-:103C600000073C0003E000080000000027440100BA
-:103C700094820008304500FF38A3008238A20084F7
-:103C80002C6300012C420001006218251060000620
-:103C9000240200839382002D1040000D00000000DC
-:103CA0000A000B9B0000000014A2000524A2FF8064
-:103CB0008F4301043C02602003E00008AC43001481
-:103CC000304200FF2C420002104000032402002278
-:103CD0000A000E3C0000000014A2000300000000D7
-:103CE0000A000EA9000000000A000EC70000000034
-:103CF0009363007E9362007A144300090000202140
-:103D00009362000024030050304200FF144300047B
-:103D1000240400019362007E24420001A362007E1D
-:103D200003E00008008010218F4201F80440FFFEEC
-:103D300024020002AF4401C0A34201C43C021000AF
-:103D400003E00008AF4201F827BDFFE8AFBF001055
-:103D50009362003F2403000A304200FF14430046F0
-:103D6000000000008F6300548F62004C1062007DE1
-:103D7000036030219362000024030050304200FFB2
-:103D80001443002F000000008F4401403C02080053
-:103D90008C4200E02403FF800082102100431024A5
-:103DA000AF4200243C0208008C4200E08F650054C2
-:103DB0003C03000A008220213084007F034410214C
-:103DC00000431021AC4501089762003C8F63004C12
-:103DD0003042FFFF0002104000621821AF63005C18
-:103DE0008F6300548F64004C9762003C006418237A
-:103DF0003042FFFF00031843000210400043102A26
-:103E000010400006000000008F6200548F63004CD9
-:103E1000004310230A000F58000210439762003C31
-:103E20003042FFFF00021040ACC2006424020001D7
-:103E3000A0C0007CA0C2008424020C80AF420024F9
-:103E40000E000F0A8F440140104000478FBF001042
-:103E50008F4301408F4201F80440FFFE240200021C
-:103E6000AF4301C0A34201C43C021000AF4201F8BD
-:103E70000A000FA88FBF00109362003F24030010B8
-:103E8000304200FF14430004000000008F44014052
-:103E90000A000F94000028219362003F24030016BB
-:103EA000304200FF1443000424020014A362003FC8
-:103EB0000A000FA2000000008F62004C8F630050C8
-:103EC00000431023044100288FBF0010936200813B
-:103ED00024420001A3620081936200812C4200040D
-:103EE00014400010000000009362003F240300040F
-:103EF000304200FF14430006000000008F440140E0
-:103F00008FBF0010240500930A0005A027BD0018EC
-:103F10008F440140240500938FBF00100A00060F54
-:103F200027BD00188F4401400E0002500000000021
-:103F30008F6200542442FFFFAF6200548F62005032
-:103F40002442FFFFAF6200500E0002598F4401402F
-:103F50008F4401408FBF0010240500040A00025E58
-:103F600027BD00188FBF001003E0000827BD001810
-:103F70008F4201889363007E00021402304400FFE8
-:103F8000306300FF1464000D0000000093620080A5
-:103F9000304200FF1044000900000000A3640080CC
-:103FA0009362000024030050304200FF14430004D9
-:103FB000000000000A0006D78F440180A36400803F
-:103FC00003E000080000000027BDFFE8AFB00010CC
-:103FD000AFBF00149362000524030030304200306C
-:103FE00014430089008080213C0208008C4200209C
-:103FF00010400080020020210E0004930000000009
-:104000008F850020ACB000009362003E9363003FB8
-:10401000304200FF00021200306300FF0043102511
-:10402000ACA2000493620082000216000002160394
-:1040300004410005000000003C0308008C630048B8
-:104040000A000FE6000000009362003E304200408C
-:10405000144000030000182193620081304300FFE8
-:104060009362008200031E00304200FF0002140031
-:1040700000621825ACA300088F620040ACA2000CBF
-:104080008F620048ACA200108F62004CACA20014FA
-:104090008F6200508F63004C0043102304410003E3
-:1040A000000000000A000FFA8F62004C8F6200507F
-:1040B000ACA200183C02080094424B5E3C03C00BCB
-:1040C00000002021004310250E0004B8ACA2001C03
-:1040D0008F6200548F840020AC8200008F620058F1
-:1040E000AC8200048F62005CAC8200088F620060CA
-:1040F0008F43007400431021AC82000C8F62006477
-:10410000AC820010976300689762006A00031C008D
-:104110003042FFFF00621825AC83001493620082D6
-:1041200024030080304200FF14430003000000001D
-:104130000A00102EAC8000188F63000C24020001CE
-:104140001062000E2402FFFF9362003E30420040E6
-:104150001440000A2402FFFF8F63000C8F4200749A
-:10416000006218233C020800006210241440000280
-:10417000000028210060282100051043AC820018AF
-:104180003C02080094424B5E3C03C00C000020211E
-:10419000004310258F8300200E0004B8AC62001C81
-:1041A0008F6200188F8300203C05080094A54B5EA9
-:1041B00024040001AC620000AC6000048F66006C57
-:1041C0003C02400D00A22825AC6600088F6200DC8E
-:1041D000AC62000CAC600010936200050002160097
-:1041E000AC620014AC6000180E0004B8AC65001C92
-:1041F000020020218FBF00148FB00010A3600005C3
-:104200000A00042127BD00188FBF00148FB00010D2
-:1042100003E0000827BD00189742007C30C600FF6D
-:10422000A08600843047FFFF2402000514C2000B63
-:1042300024E3465090A201122C42000710400007D0
-:1042400024E30A0090A30112240200140062100467
-:1042500000E210210A0010663047FFFF3067FFFFC1
-:1042600003E00008A4870014AC87004C8CA201086E
-:104270000080402100A0482100E2102330C600FF4A
-:104280001840000393AA001324E2FFFCACA201082B
-:1042900030C2000110400008000000008D020050F4
-:1042A00000E2102304410013240600058D0200548F
-:1042B00010E20010000000008D02005414E2001A09
-:1042C000000000003C0208008C4200D83042002070
-:1042D0001040000A2402000191030078910200833B
-:1042E000144300062402000101002021012028219E
-:1042F000240600040A00105400000000A1000084FD
-:1043000011400009A50200148F4301008F4201F8FB
-:104310000440FFFE24020002AF4301C0A34201C4D7
-:104320003C021000AF4201F803E00008000000006A
-:1043300027BDFFE88FA90028AFBF001000804021F3
-:1043400000E918231860007330C600FFA080007CCD
-:10435000A08000818CA2010800E210230440004DDF
-:10436000000000008C8200509483003C8C84006428
-:10437000004748233063FFFF012318210083202BCF
-:1043800010800004000000008D0200640A0010B7D5
-:1043900000E210219502003C3042FFFF0122102173
-:1043A00000E21021AD02005C9502003C8D03005C30
-:1043B0003042FFFF0002104000E210210043102BAA
-:1043C00010400003000000000A0010C68D02005CCF
-:1043D0009502003C3042FFFF0002104000E2102135
-:1043E000AD02005CA1000084AD07004C8CA2010866
-:1043F00000E210231840000224E2FFFCACA20108F6
-:1044000030C200011040000A000000008D02005080
-:1044100000E2102304410004010020218D02005419
-:1044200014E20003000000000A0010E82406000562
-:104430008D02005414E200478FBF00103C020800B8
-:104440008C4200D8304200201040000A24020001B3
-:1044500091030078910200831443000624020001B6
-:1044600001002021240600048FBF00100A00105410
-:1044700027BD0018A1000084A50200148F4301008D
-:104480008F4201F80440FFFE240200020A00110DD1
-:10449000000000008C82005C004910230043102BB8
-:1044A00054400001AC87005C9502003C3042FFFFA5
-:1044B0000062102B14400007240200029502003C09
-:1044C0008D03005C3042FFFF00621821AD03005CE9
-:1044D00024020002AD07004CA10200840E000F0A66
-:1044E0008F4401001040001B8FBF00108F4301005C
-:1044F0008F4201F80440FFFE24020002AF4301C0D6
-:10450000A34201C43C021000AF4201F80A0011238B
-:104510008FBF001030C200101040000E8FBF00107F
-:104520008C83005C9482003C006918233042FFFFBA
-:10453000006218213C023FFF3444FFFF0083102B30
-:10454000544000010080182101231021AD02005CBD
-:104550008FBF001003E0000827BD001827BDFFE84B
-:104560008FAA0028AFBF00100080402100EA482336
-:104570001920002130C600FF8C83005C8C8200640F
-:10458000006A18230043102B5040001000691821C6
-:1045900094A2011001221021A4A2011094A20110E2
-:1045A0003042FFFF0043102B1440000A3C023FFF43
-:1045B00094A2011000431023A4A201109482003C95
-:1045C0003042FFFF0A00114200621821A4A001102E
-:1045D0003C023FFF3444FFFF0083102B5440000196
-:1045E0000080182100671021AD02005CA100007C52
-:1045F0000A00118AA100008130C200101040003C66
-:10460000000000008C820050004A1023184000383F
-:10461000000000009082007C24420001A082007C07
-:104620009082007C3C0308008C630024304200FF31
-:104630000043102B1440005C8FBF00108CA20108B7
-:1046400000E2102318400058000000008C83005442
-:104650009482003C006A18233042FFFF0003184395
-:10466000000210400043102A104000050000000026
-:104670008C820054004A10230A001171000210437A
-:104680009482003C3042FFFF00021040AD02006403
-:104690009502003C8D0400649503003C3042FFFF0E
-:1046A00000021040008220213063FFFF00831821A8
-:1046B00001431021AD02005C8D020054ACA2010840
-:1046C00024020002A10200840E000F0A8F440100A0
-:1046D000104000358FBF00108F4301008F4201F85A
-:1046E0000440FFFE240200020A0011B30000000093
-:1046F000AD07004C8CA2010800E210231840000214
-:1047000024E2FFFCACA2010830C200011040000A04
-:10471000000000008D02005000E21023044100045C
-:10472000010020218D02005414E20003000000006B
-:104730000A0011AA240600058D02005414E2001A92
-:104740008FBF00103C0208008C4200D8304200208D
-:104750001040000A240200019103007891020083B6
-:104760001443000624020001010020212406000455
-:104770008FBF00100A00105427BD0018A10000844C
-:10478000A50200148F4301008F4201F80440FFFE90
-:1047900024020002AF4301C0A34201C43C02100046
-:1047A000AF4201F88FBF001003E0000827BD0018DA
-:1047B0008FAA00108C8200500080402130C600FF7C
-:1047C000004A102300A048211840000700E01821EB
-:1047D00024020001A0800084A0A00112A482001481
-:1047E0000A001125AFAA0010A0800081AD07004C7F
-:1047F0008CA2010800E210231840000224E2FFFC12
-:10480000ACA2010830C20001104000080000000006
-:104810008D0200500062102304410013240600059D
-:104820008D02005410620010000000008D02005440
-:1048300014620011000000003C0208008C4200D805
-:10484000304200201040000A240200019103007849
-:10485000910200831443000624020001010020217C
-:1048600001202821240600040A0010540000000042
-:10487000A1000084A502001403E00008000000006D
-:1048800027BDFFE0AFBF0018274201009046000A95
-:104890008C4800148C8B004C9082008430C900FF3F
-:1048A00001681823304A00FF1C60001A2D460006DC
-:1048B000240200010142100410C00016304300031E
-:1048C000012030210100382114600007304C000C19
-:1048D00015800009304200301440000B8FBF0018D3
-:1048E0000A001214000000000E001125AFAB0010EA
-:1048F0000A0012148FBF00180E00109AAFAB001000
-:104900000A0012148FBF0018AFAB00100E0011BACE
-:10491000AFAA00148FBF001803E0000827BD0020D5
-:1049200024020003A08200848C82005403E000086B
-:10493000ACA201083C0200080342182190620081E9
-:10494000240600433C07601924420001A062008154
-:10495000906300813C0208008C4200C0306300FF7D
-:10496000146200102403FF803C0208008C4200E027
-:104970000082102100431024AF4200243C020800B2
-:104980008C4200E03C03000A008210213042007F8C
-:104990000342102100431021944500D40A000AF17B
-:1049A00030A5FFFF03E000080000000027BDFFE086
-:1049B000AFBF0018AFB10014AFB000108F4201803C
-:1049C0000080802100A088210E00121B00402021C1
-:1049D000A20000848E0200548FBF00188FB0001018
-:1049E000AE2201088FB1001403E0000827BD0020AB
-:1049F00027BDFFE03C020008AFB00010AFBF0018B9
-:104A0000AFB10014034280218F5101409203008412
-:104A10008E0400508E02004C14820040306600FF6D
-:104A20003C0208008C4200E02403FF800222102197
-:104A300000431024AF4200243C0208008C4200E0F6
-:104A40009744007C92050081022210213042007FB1
-:104A5000034218213C02000A0062182114A0000B36
-:104A60003084FFFF2402000554C20014248205DCB8
-:104A70009062011224420001A062011224020C8003
-:104A8000AF4200240A00127324020005A060011244
-:104A90002402000514C20009248205DC9202008170
-:104AA0002C4200075040000524820A009203008136
-:104AB0002402001400621004008210213044FFFF21
-:104AC000A60400140E00121B022020219602003CB6
-:104AD0008E03004C022020213042FFFF00021040D4
-:104AE000006218210E000250AE03005C9202007DAD
-:104AF00002202021344200400E000259A202007D13
-:104B00008F4201F80440FFFE24020002AF5101C0B1
-:104B1000A34201C43C021000AF4201F88FBF00184D
-:104B20008FB100148FB0001003E0000827BD0020F3
-:104B300008000ACC08000B1408000B9808000BE4CE
-:044B400008000C203D
-:0C4B44000A000028000000000000000033
-:104B50000000000D6370362E322E31000000000080
-:104B60000602010400000000000000000000000038
-:104B70000000000000000000000000000000000035
-:104B80000000000000000000000000000000002005
-:104B90000000000000000000000000000000000015
-:104BA0000000000000000000000000000000000005
-:104BB00000000000000000000000000000000001F4
-:104BC0000000002B000000000000000400030D4066
-:104BD00000000000000000000000000000000000D5
-:104BE00000000000000000001000000300000000B2
-:104BF0000000000D0000000D3C020800244258A4F3
-:104C00003C03080024635F70AC4000000043202B8D
-:104C10001480FFFD244200043C1D080037BD7FFCCA
-:104C200003A0F0213C100800261000A03C1C080046
-:104C3000279C58A40E0001AC000000000000000DED
-:104C400027BDFFE83C096018AFBF00108D2C500055
-:104C5000240DFF7F24080031018D5824356A380C5B
-:104C600024070C003C1A8000AD2A50003C04800A46
-:104C7000AF4800083C1B8008AF4700240E00091510
-:104C8000AF8400100E0008D8000000000E000825B8
-:104C9000000000000E001252000000003C046016EC
-:104CA0008C8500003C06FFFF3C02535300A61824ED
-:104CB0001062004734867C0094C201F2A780002C69
-:104CC00010400003A78000CC38581E1EA798002C67
-:104CD00094C201F810400004978300CC38591E1E7E
-:104CE000A79900CC978300CC2C7F006753E000018C
-:104CF000240300669784002C2C82040114400002D7
-:104D000000602821240404003C0760008CE904387A
-:104D10002403103C3128FFFF1103001F30B9FFFFAF
-:104D200057200010A38000CE24020050A38200CEA2
-:104D3000939F00CE53E0000FA78500CCA78000CC46
-:104D4000978500CC8FBF0010A780002CA78000346F
-:104D5000A78000E63C010800AC25008003E00008C5
-:104D600027BD0018939F00CE57E0FFF5A78000CC29
-:104D7000A78500CC978500CC8FBF0010A784002C9E
-:104D8000A7800034A78000E63C010800AC25008025
-:104D900003E0000827BD0018A38000CE8CCB003CA8
-:104DA000316A00011140000E0000000030A7FFFF33
-:104DB00010E0FFDE240200508CCC00C831860001D8
-:104DC00014C0FFDC939F00CE0A00007A2402005139
-:104DD0008C8F00043C0E60000A00005D01EE302163
-:104DE0008CEF0808240D5708000F740211CD000441
-:104DF00030B8FFFF240500660A00007B240404008D
-:104E00001700FFCC939F00CE0A00007A24020050C6
-:104E10008F8600103089FFFF000939408CC30010D5
-:104E20003C08005000E82025AF4300388CC5001432
-:104E300027420400AF82001CAF45003CAF44003065
-:104E40000000000000000000000000000000000062
-:104E50000000000000000000000000000000000052
-:104E60008F4B0000316A00201140FFFD0000000060
-:104E700003E00008000000008F840010948A001AEC
-:104E80008C8700243149FFFF000940C000E8302131
-:104E9000AF46003C8C8500248F43003C00A31023C8
-:104EA00018400029000000008C8B002025620001C2
-:104EB0003C0D005035AC0008AF420038AF4C00301C
-:104EC00000000000000000000000000000000000E2
-:104ED00000000000000000000000000000000000D2
-:104EE0008F4F000031EE002011C0FFFD00000000D8
-:104EF0008F4A04003C080020AC8A00108F4904044B
-:104F0000AC890014AF4800300000000094860018FF
-:104F10009487001C00C71821A48300189485001AE8
-:104F200024A20001A482001A9498001A9499001EE9
-:104F3000133800030000000003E000080000000038
-:104F400003E00008A480001A8C8200200A0000DC24
-:104F50003C0D00500A0000CD000000003C0308009A
-:104F60008C6300208F82001827BDFFE810620008C4
-:104F7000AFBF00100E000104AF8300183C0308000F
-:104F80008C63002024040001106400048F89001049
-:104F90008FBF001003E0000827BD00188FBF00106E
-:104FA0003C076012A520000A9528000A34E500108D
-:104FB00027BD00183106FFFF03E00008ACA60090F3
-:104FC0003C0208008C42002027BDFFC8AFBF003460
-:104FD000AFBE0030AFB7002CAFB60028AFB500248D
-:104FE000AFB40020AFB3001CAFB20018AFB10014D3
-:104FF00010400050AFB000108F840010948600065F
-:105000009483000A00C3282330B6FFFF12C0004A71
-:105010008FBF003494890018948A000A012A402323
-:105020003102FFFF02C2382B14E0000202C020212F
-:10503000004020212C8C0005158000020080A0215A
-:10504000241400040E0000B3028020218F8700107A
-:1050500002809821AF80001494ED000A028088211C
-:105060001280004E31B2FFFF3C1770003C1540002B
-:105070003C1E60008F8F001C8DEE000001D71824AD
-:10508000507500500220202102A3802B160000350D
-:105090003C182000507800470220202124100001F5
-:1050A0008F83001414600039029158230230F823D2
-:1050B0000250C82133F1FFFF1620FFEE3332FFFF0D
-:1050C0008F8700103C110020AF510030000000001D
-:1050D00094E6000A3C1E601237D5001002662821B3
-:1050E000A4E5000A94E2000A94F2000A94F400187D
-:1050F0003057FFFF1292003BAEB700908CED0014CA
-:105100008CE400100013714001AE4021000E5FC31B
-:10511000010E502B008B4821012A1821ACE8001405
-:10512000ACE3001002D3382330F6FFFF16C0FFB9FE
-:105130008F8400108FBF00348FBE00308FB7002CDB
-:105140008FB600288FB500248FB400208FB3001CC9
-:105150008FB200188FB100148FB0001003E0000868
-:1051600027BD0038107E001B000000001477FFCC24
-:10517000241000010E00159B000000008F83001416
-:105180001060FFCB0230F823029158238F87001064
-:10519000017020210A0001973093FFFF8F830014D4
-:1051A0001460FFCB3C110020AF5100300A000163B6
-:1051B000000000000E00077D024028210A00015770
-:1051C000004080210E00033A024028210A000157C6
-:1051D000004080210E001463022020210A000157A4
-:1051E000004080210E0000CD000000000A0001797F
-:1051F00002D3382327BDFFE8AFB00010AFBF0014C3
-:105200000E00003F000000003C028000345000709F
-:105210000A0001BA8E0600008F4F000039EE00012F
-:1052200031C20001104000248F8600A88E070000C4
-:105230003C0C08008D8C003C3C0908008D2900388E
-:1052400000E66823018D28210000502100AD302B9D
-:10525000012A4021010620213C010800AC25003C28
-:10526000AF8700A83C010800AC2400380E000106FE
-:10527000000000003C0308008C6300701060FFE633
-:10528000006020213C0508008CA500683C06080051
-:105290008CC6006C0E00152A000000003C010800BE
-:1052A000AC2000708F4F000039EE000131C20001C8
-:1052B0001440FFDE8F8600A88E0A00008F8B00A8A6
-:1052C0003C0508008CA5003C3C0408008C84003898
-:1052D000014B482300A938210082182100E9402B06
-:1052E000006810213C010800AC27003C3C0108008C
-:1052F000AC2200388F5F01002419FF0024180C0035
-:1053000003F9202410980012AF840000AF4400205D
-:10531000936D0000240C002031A600FF10CC001279
-:10532000240E005010CE00043C194000AF59013843
-:105330000A0001B3000000000E0011C800000000C8
-:105340003C194000AF5901380A0001B300000000C9
-:105350000E00011F000000003C194000AF59013849
-:105360000A0001B3000000008F58010000802821CE
-:10537000330F00FF01E020210E0002F1AF8F000487
-:105380003C194000AF5901380A0001B30000000089
-:1053900000A4102B2403000110400009000030215C
-:1053A0000005284000A4102B04A0000300031840AF
-:1053B0005440FFFC000528405060000A0004182BF0
-:1053C0000085382B54E000040003184200C3302548
-:1053D00000852023000318421460FFF900052842CD
-:1053E0000004182B03E0000800C310218F4201B80D
-:1053F0000440FFFE00000000AF4401803C031000A9
-:1054000024040040AF450184A3440188A3460189D8
-:10541000A747018A03E00008AF4301B83084FFFFCB
-:105420000080382130A5FFFF000020210A00022A59
-:10543000240600803087FFFF8CA40000240600387B
-:105440000A00022A000028218F8300388F8600304E
-:105450001066000B008040213C07080024E75A1822
-:10546000000328C000A710218C4400002463000121
-:10547000108800053063000F5466FFFA000328C04F
-:1054800003E00008000010213C07080024E75A1C34
-:1054900000A7302103E000088CC200003C0390000C
-:1054A0003462000100822025AF4400208F45002097
-:1054B00004A0FFFE0000000003E000080000000060
-:1054C0003C038000346200010082202503E00008D4
-:1054D000AF44002027BDFFE0AFB100143091FFFFC3
-:1054E000AFB00010AFBF00181220001300A0802141
-:1054F0008CA2000024040002240601401040000F8A
-:10550000004028210E000C5C00000000000010216B
-:10551000AE000000022038218FBF00188FB10014A8
-:105520008FB0001000402021000028210000302111
-:105530000A00022A27BD00208CA200000220382188
-:105540008FBF00188FB100148FB0001000402021D1
-:1055500000002821000030210A00022A27BD002077
-:1055600000A010213087FFFF8CA500048C440000B0
-:105570000A00022A2406000627BDFFE0AFB0001093
-:10558000AFBF0018AFB100149363003E00808021CC
-:105590000080282130620040000020211040000FD0
-:1055A0008E1100000E000851022020219367000098
-:1055B0002404005030E500FF50A400128E0F0000BC
-:1055C000022020218FBF00188FB100148FB000106F
-:1055D000A762013C0A00091127BD00200E000287C6
-:1055E000000000000E0008510220202193670000F7
-:1055F0002404005030E500FF14A4FFF20220202113
-:105600008E0F00003C1008008E1000503C0D000C66
-:10561000240BFF8001F05021314E007F01DA602120
-:10562000018D4021014B4824AF4900280220202150
-:105630008FBF00188FB100148FB00010A50200D6E4
-:1056400027BD00200A000911AF8800D027BDFFE068
-:10565000AFBF0018AFB10014AFB0001093660001E7
-:10566000008080210E00025630D1000493640005B2
-:10567000001029C2A765000034830040A363000521
-:105680000E00025F020020210E00091302002021FB
-:1056900024020001AF62000C02002821A762001062
-:1056A00024040002A762001224060140A76200142D
-:1056B0000E000C5CA76200161620000F8FBF0018AA
-:1056C000978C00343C0B08008D6B00782588FFFF19
-:1056D0003109FFFF256A0001012A382B10E000067E
-:1056E000A78800343C0F6006240E001635ED00102C
-:1056F000ADAE00508FBF00188FB100148FB00010F6
-:1057000003E0000827BD002027BDFFE0AFB1001473
-:10571000AFBF0018AFB0001000A088211080000AB1
-:105720003C03600024020080108200120000000090
-:105730000000000D8FBF00188FB100148FB0001053
-:1057400003E0000827BD00208C682BF80500FFFE51
-:1057500000000000AC712BC08FBF00188FB1001487
-:105760008FB000103C09100027BD002003E00008A6
-:10577000AC692BF80E00025600A0202193650005AD
-:10578000022020210E00025F30B000FF2403003E03
-:105790001603FFE7000000008F4401780480FFFE3D
-:1057A000240700073C061000AF51014002202021D1
-:1057B000A34701448FBF00188FB100148FB00010B1
-:1057C000AF4601780A0002C227BD002027BDFFE8CE
-:1057D000AFBF0014AFB000108F50002000000000D9
-:1057E0000E000913AF440020AF5000208FBF0014FB
-:1057F0008FB0001003E0000827BD00183084FFFFC1
-:10580000008038212406003500A020210A00022A49
-:10581000000028213084FFFF008038212406003654
-:1058200000A020210A00022A0000282127BDFFD065
-:10583000AFB3001C3093FFFFAFB50024AFB2001828
-:10584000AFBF0028AFB40020AFB10014AFB000105C
-:1058500030B5FFFF12600027000090218F90001CE0
-:105860008E0300003C0680002402004000033E023C
-:1058700000032C0230E4007F006688241482001D9F
-:1058800030A500FF8F8300282C68000A510000100B
-:105890008F910014000358803C0C0800258C56940E
-:1058A000016C50218D49000001200008000000001B
-:1058B00002B210213045FFFF0E000236240400849E
-:1058C000162000028F90001CAF8000288F910014DA
-:1058D000260C002026430001018080213072FFFF4A
-:1058E00016200004AF8C001C0253502B1540FFDC27
-:1058F00000000000024010218FBF00288FB5002457
-:105900008FB400208FB3001C8FB200188FB1001429
-:105910008FB0001003E0000827BD0030240E0034D3
-:1059200014AE00F9000000009203000E241F168040
-:105930003C07000CA36300219202000D0347C8211D
-:105940003C066000A3620020961100123C0A7FFF13
-:10595000354CFFFFA771003C960B00102403000597
-:105960003168FFFFAF6800848E05001CAF5F002820
-:105970008F3800008CC4444803057826008F3021FE
-:10598000AF66004C8F69004C24CE00013C057F00BF
-:10599000AF6900508F740050AF740054AF66007050
-:1059A000AF6E00588F6D005824140050AF6D005C2E
-:1059B000A3600023AF6C0064A36300378E02001461
-:1059C000AF6200488F710048AF7100248E0B001841
-:1059D000AF6B006C9208000CA3680036937F003E0A
-:1059E00037F90020A379003E8F78007403058024E6
-:1059F000360F4000AF6F007493640000308900FFE1
-:105A0000513402452404FF803C04080024845A9841
-:105A10000E00028D000000003C1008008E105A9805
-:105A20000E00025602002021240600042407000173
-:105A3000A366007D020020210E00025FA36700051F
-:105A40008F5F017807E0FFFE240B0002AF5001409A
-:105A5000A34B01448F90001C3C081000AF48017814
-:105A60000A000362AF8000282CAD003751A0FF98D8
-:105A70008F9100140005A0803C180800271856BC20
-:105A8000029878218DEE000001C00008000000009F
-:105A90002418000614B80011000000003C0808009B
-:105AA0008D085A9824040005AF4800208E1F001866
-:105AB000AF7F00188F79004CAF79001C8F650050C4
-:105AC000122000C0AF6500700A000362AF84002896
-:105AD0002406000710A60083240300063C050800E6
-:105AE00024A55A980E000264240400818F90001CA3
-:105AF0000011102B0A000362AF8200282407000463
-:105B000014A7FFF6240500503C1808008F185A9877
-:105B1000AF5800208E0F0008AF6F00408E090008BC
-:105B2000AF6900448E14000CAF7400488E0E001054
-:105B3000AF6E004C8E0D0010AF6D00848E0A001405
-:105B4000AF6A00508E0C0018AF6C00548E04001C1D
-:105B5000AF64005893630000306B00FF116501D8FB
-:105B6000000000008F7400488F6900400289702394
-:105B700005C000042404008C1620FFDE240200036C
-:105B8000240400823C05080024A55A980E000287D0
-:105B9000000000008F90001C000010210A0003622A
-:105BA000AF820028240F000514AFFFCC240520008D
-:105BB0003C0708008CE75A98AF4700208E06000487
-:105BC000AF66005C9208000824100008A36800215A
-:105BD0008F9F001C93F90009A37900208F86001C79
-:105BE00090D8000A330400FF10900011000000005C
-:105BF0002885000914A0006924020002240A00205C
-:105C0000108A000B34058000288D002115A00008A3
-:105C100024054000240E0040108E00053C050001C4
-:105C200024140080109400023C050002240540006A
-:105C30008F7800743C19FF00031980240205782531
-:105C4000AF6F007490C4000BA36400818F84001CAC
-:105C50009489000C11200192000000009490000C27
-:105C60002406FFBF24050004A770003C908F000E9F
-:105C7000A36F003E8F84001C9089000FA369003F32
-:105C80008F8B001C8D6E00108F54007401D468231C
-:105C9000AF6D00608D6A0014AF6A0064956C0018E7
-:105CA000A76C00689563001AA763006A8D62001CE8
-:105CB000AF62006C9167000EA367003E9368003EE0
-:105CC0000106F8241220014BA37F003E8F90001C98
-:105CD0000A000362AF8500282407002214A7FF7F73
-:105CE000240300073C0B08008D6B5A981220000C0F
-:105CF000AF4B00200A000362AF830028240C00335E
-:105D000010AC0014240A00283C05080024A55A9869
-:105D10000E00023C240400810A0003EB8F90001C5B
-:105D20003C04080024845A980E00028D00000000F4
-:105D30009363000024110050306200FF10510135C0
-:105D4000000000008F90001C000018210A00036270
-:105D5000AF8300283C0D08008DAD5A9824040081C3
-:105D6000AF4D00203C05080024A55A980E00023CC7
-:105D7000A36A00348F90001C240200090A00036209
-:105D8000AF82002802B288213225FFFF0E000236C2
-:105D9000240400840A0003628F90001C1082FFA478
-:105DA00024050400288B000311600170240C0004FA
-:105DB000240300015483FF9E240540000A00043B95
-:105DC000240501003C04080024845A988F62004C8A
-:105DD0000E00028D8F6300508F90001C0000202168
-:105DE0000A000362AF8400288E1000042404008A95
-:105DF000AF50002093790005333800021700015F8F
-:105E0000020028219368002302002821311F00206E
-:105E100017E0015A2404008D9367003F2406001206
-:105E200030E200FF10460155240400810E000256A6
-:105E30000200202193630023240500040200202196
-:105E4000346B0042A36B00230E00025FA365007D4C
-:105E50008F4401780480FFFE240A0002AF50014005
-:105E6000A34A01448F90001C3C0C1000AF4C0178F9
-:105E70000A0003EC0011102B8E1000042404008A89
-:105E8000AF500020936E000531CD000215A0001622
-:105E900002002821936F003F2414000402002821EF
-:105EA00031E900FF11340010240400810E00025675
-:105EB000020020219362002324080012241FFFFE09
-:105EC00034460020A3660023A368003F93790005B1
-:105ED00002002021033FC0240E00025FA3780005CA
-:105EE00002002821000020210E00033400000000E1
-:105EF0000A0003EB8F90001C8E1000043C03000886
-:105F00000343A021AF500020928B000024050050D5
-:105F1000316400FF10850161240700880200202100
-:105F2000000028210E00022A2406000E928D000097
-:105F3000240EFF800200282101AE8025A2900000DF
-:105F4000240400040E000C5C240600300A0003EB5D
-:105F50008F90001C8E0800043C14080026945A9868
-:105F60003C010800AC285A98AF480020921F00035B
-:105F700033F9000413200002240200122402000658
-:105F8000A362003F920B001B2404FFC03165003F59
-:105F900000A43825A367003E9206000330C200012A
-:105FA00014400132000000008E020008AE8200089A
-:105FB0003C0208008C425AA010400131000249C244
-:105FC000A76900088E14000C240C0001240300149F
-:105FD000AF74002C8E0E0010AF6E0030960D0016C0
-:105FE000A76D0038960A0014A76A003AAF6C000C3F
-:105FF000A76C0010A76C0012A76C0014A76C001609
-:1060000012200136A3630034920F000331F0000226
-:106010002E1100018F90001C262200080A00036246
-:10602000AF8200288E0400043C0E0008034E30218D
-:10603000AF4400208E05000890CD0000240C0050D5
-:1060400031AA00FF114C00862407008824060009AD
-:106050000E00022A000000000A0003EB8F90001CD3
-:106060008E04001C0E00024100000000104000F4ED
-:10607000004050218F89001C240700890140202105
-:106080008D25001C240600010E00022A00000000DD
-:106090000A0003EB8F90001C960D00023C140800D0
-:1060A00026945A9831AA0004514000B83C10600070
-:1060B0008E0E001C3C010800AC2E5A98AF4E0020FA
-:1060C000920700102408001430E200FF144800D6A4
-:1060D00000000000960B00023163000114600165AE
-:1060E000000000008E020004AE8200083C1408008C
-:1060F0008E945AA01280015B000000008F7400741F
-:106100003C0380002404000102835825AF6B007417
-:10611000A3600005AF64000C3C0708008CE75AA0A0
-:106120008F86001CA7640010000711C2A76400122C
-:10613000A7640014A7640016A76200088CC80008B2
-:1061400024040002AF68002C8CC5000CAF65003041
-:1061500090DF0010A37F00348F99001C9330001152
-:10616000A37000358F98001C930F0012A36F0036A8
-:106170008F89001C912E0013A36E00378F90001C96
-:10618000960D0014A76D0038960A0016A76A003A0B
-:106190008E0C0018AF6C00245620FDCCAF84002874
-:1061A0003C05080024A55A980E0002640000202136
-:1061B0008F90001C0A0004A7000020218E1000040C
-:1061C00024070081AF500020936900233134001070
-:1061D000128000170000000002002021000028218A
-:1061E0002406001F0E00022A000000000A0003EB34
-:1061F0008F90001C3C05080024A55A980E000287C9
-:10620000240400828F90001C000028210A000362F1
-:10621000AF8500283C0408008C845A980E0014E8CE
-:10622000000000008F90001C0A000482000018216A
-:106230000E00025602002021937800230200202144
-:10624000370F00100E00025FA36F002300003821FB
-:1062500002002021000028210A0005A82406001FB2
-:10626000920F000C31E90001112000030000000032
-:106270009618000EA4D8002C921F000C33F90002CF
-:1062800013200005000038218E0200149608001229
-:10629000ACC2001CA4C8001A0A0005432406000969
-:1062A0003C05080024A55A980E0002872404008BA0
-:1062B0008F90001C0011282B0A000362AF85002874
-:1062C000AF6000843C0A08008D4A5A983C0D0800D3
-:1062D0008DAD0050240CFF803C02000C014D1821B4
-:1062E000006C2024AF4400288E070014306B007F20
-:1062F000017A282100A2C821AF2700D88E060014F9
-:10630000AF9900D0AF2600DC8E080010251FFFFEDD
-:106310000A000408AF3F01083C0508008CA55A9804
-:106320003C1908008F39005024CCFFFE00B9C02171
-:1063300003047824AF4F00283C1408008E945A9828
-:106340003C0908008D2900500289702131CD007F61
-:1063500001BA502101478021AE0600D8AF9000D08D
-:10636000AE0000DC0A0003B1AE0C0108548CFE3014
-:10637000240540000A00043B240510000E00032EF3
-:10638000000000000A0003EB8F90001C8E0F442CCD
-:106390003C186C62370979703C010800AC205A98AF
-:1063A00015E9000824050140979F00349786002CCA
-:1063B0000280282103E6C82B132000112404009238
-:1063C000240501400E000C7A240400023C01080060
-:1063D000AC225A98AF4200203C0508008CA55A9880
-:1063E00010A00005240400830E00084500000000F2
-:1063F00010400009240400833C05080024A55A9895
-:106400000E000264000000008F90001C0011202B81
-:106410000A000362AF8400280E0008490000000053
-:106420000A00055F8F90001C0E00084D0000000060
-:106430003C05080024A55A980A00062F2404008B66
-:10644000240400040E000C7A240500301440002AB5
-:10645000004050218F89001C240700830140202127
-:106460008D25001C0A000551240600018E04000839
-:106470000E000241000000000A00051BAE82000869
-:106480003C05080024A55A980E00023C240400870D
-:106490008F90001C0A0005360011102B8F830038E6
-:1064A0008F8600301066FE9D000038213C070800F2
-:1064B00024E75A1C000320C0008728218CAC000070
-:1064C00011900061246A00013143000F5466FFFA05
-:1064D000000320C00A0004F6000038213C05080033
-:1064E00024A55A980E000287240400828F90001C75
-:1064F0000A000536000010213C0B0008034B202148
-:106500002403005024070001AF420020A0830000B4
-:10651000A08700018F82001C90480004A08800180A
-:106520008F85001C90A60005A08600198F9F001C77
-:1065300093F90006A099001A8F90001C921800078A
-:10654000A098001B8F94001C928F0008A08F001C45
-:106550008F89001C912E0009A08E001D8F8D001CBC
-:1065600091AC000AA08C001E8F8B001C3C0C080014
-:10657000258C5A1C9163000B3C0B0800256B5A18A4
-:10658000A083001F8F87001C90E8000CA0880020CB
-:106590008F82001C9045000D24024646A0850021F4
-:1065A0008F86001C90DF000EA09F00228F99001C98
-:1065B0009330000FA09000238F98001C93140010BC
-:1065C000A09400248F8F001C91E90011A089002560
-:1065D0008F89001C8F8E00308F900038952D00140D
-:1065E000000E18C025C80001A48D002895270016AC
-:1065F000006C3021006BC821A487002A9525001863
-:106600003108000FA485002CA482002E8D3F001CB1
-:10661000ACCA0000AF88003011100006AF3F000088
-:10662000000038218D25001C014020210A00055161
-:1066300024060001250C00013184000F00003821E0
-:106640000A0006B8AF8400383C07080024E75A184F
-:106650000087302100003821ACA000000A0004F6B9
-:10666000ACC000003C05080024A55A980A00062F7B
-:10667000240400878E0400040E0002410000000084
-:106680000A00056AAE8200083084FFFF30C600FFB2
-:106690008F4201B80440FFFE00064400010430258B
-:1066A0003C07200000C720253C031000AF400180BC
-:1066B000AF450184AF44018803E00008AF4301B84F
-:1066C00027BDFFE8AFB00010AFBF00143C0760006B
-:1066D000240600021080000600A080210010102B6C
-:1066E0008FBF00148FB0001003E0000827BD001812
-:1066F0003C09600EAD2000348CE5201C8F82001C0C
-:106700002408FFFC00A81824ACE3201C0E0006D1CE
-:106710008C45000C0010102B8FBF00148FB00010A0
-:1067200003E0000827BD00183C02600E344701005A
-:1067300024090018274A040000000000000000009F
-:10674000000000003C06005034C30200AF44003893
-:10675000AF45003CAF430030014018218F4B000093
-:10676000316800201100FFFD2406007F2408FFFF90
-:106770008C6C000024C6FFFF24630004ACEC000016
-:1067800014C8FFFB24E70004000000000000000024
-:10679000000000003C0F0020AF4F00300000000060
-:1067A00024AD020001A5702B2529FFFF008E2021BA
-:1067B0001520FFE101A0282103E0000800000000EF
-:1067C00027BDFFE0AFB10014AFBF0018AFB000109D
-:1067D0003C05600E8CA20034008088211440000625
-:1067E0003C0460008C87201C2408FFFC00E8302457
-:1067F00034C30001AC83201C8F8B001C24090001D2
-:10680000ACA90034956900028D6500148D70000CF0
-:106810002D2400818D6700048D660008108000071C
-:106820008D6A00102D2C00041580000E30CE00075C
-:10683000312D000311A0000B000000002404008B88
-:10684000020028210E0006D1240600030011102B9F
-:106850008FBF00188FB100148FB0001003E0000844
-:1068600027BD002015C0FFF62404008B3C03002048
-:10687000AF4300300000000024020001AF8200148A
-:106880000000000000000000000000003C1F01505C
-:10689000013FC825253800033C0F600EAF47003884
-:1068A00000181882AF46003C35E8003CAF59003074
-:1068B000274704008F4400003086002010C0FFFDF1
-:1068C00000000000106000082466FFFF2403FFFFA3
-:1068D0008CEB000024C6FFFF24E70004AD0B000092
-:1068E00014C3FFFB250800043C08600EAD09003806
-:1068F0000000000000000000000000003C07002035
-:10690000AF470030000000000E0006F901402021D2
-:1069100002002821000020210E0006D124060003D9
-:106920000011102B8FBF00188FB100148FB0001012
-:1069300003E0000827BD002027BDFFE0AFB200182C
-:106940003092FFFFAFB10014AFBF001CAFB000101A
-:106950001640000D000088210A0007AA022010211D
-:1069600024050001508500278CE5000C0000000D77
-:10697000262300013071FFFF24E200200232382B71
-:1069800010E00019AF82001C8F8200141440001622
-:106990008F87001C3C0670003C0320008CE5000043
-:1069A00000A62024148300108F84003C00054402BC
-:1069B0003C09800000A980241480FFE9310600FF13
-:1069C0002CCA00095140FFEB262300010006688015
-:1069D0003C0E080025CE579801AE60218D8B00003B
-:1069E0000160000800000000022010218FBF001C81
-:1069F0008FB200188FB100148FB0001003E00008B0
-:106A000027BD00200E0006D1240400841600FFD804
-:106A10008F87001C0A00078BAF80003C90EF0002BC
-:106A200000002021240600090E0006D1000F2E00D0
-:106A30008F87001C0010102B0A00078BAF82003CD0
-:106A4000020028210E0006DF240400018F87001CAD
-:106A50000A00078BAF82003C020028210E0006DFEF
-:106A6000000020210A0007C38F87001C0E00071FAB
-:106A7000020020210A0007C38F87001C30B0FFFFEF
-:106A8000001019C08F5801B80700FFFE3C1F2004FA
-:106A90003C191000AF430180AF400184AF5F018813
-:106AA000AF5901B80A00078C262300013082FFFF8E
-:106AB00014400003000018210004240224030010E5
-:106AC000308500FF14A000053087000F2466000801
-:106AD0000004220230C300FF3087000F14E00005DD
-:106AE000308900032468000400042102310300FF00
-:106AF0003089000315200005388B0001246A00024C
-:106B000000042082314300FF388B00013164000112
-:106B100010800002246C0001318300FF03E00008B4
-:106B200000601021308BFFFF000B394230E600FF80
-:106B30003C09080025295998000640800109602178
-:106B40008D8700003164001F240A0001008A1804A8
-:106B500030A500FF00E3202514A000020003102749
-:106B600000E22024240F000100CF700401096821F5
-:106B7000000E282714800005ADA400008F86000CAD
-:106B800000A6102403E00008AF82000C8F88000CE0
-:106B900001C8102503E00008AF82000C3C06001F6E
-:106BA0003C0360003084FFFF34C5FF8024020020D6
-:106BB000AC602008AC60200CAC602010AC652014E8
-:106BC000AC642018AC62200000000000000000004F
-:106BD00003E000080000000027BDFFE82402FFFFDB
-:106BE000AFBF0010AF82000C000020213C0608005F
-:106BF00024C659982405FFFF248900010004408021
-:106C00003124FFFF010618212C87002014E0FFFA31
-:106C1000AC6500000E0008160000202124020001CF
-:106C20003C04600024050020AC822018AC852000C4
-:106C3000000000000000000000000000244A0001E5
-:106C40003142FFFF2C46040014C0FFF78FBF001035
-:106C500003E0000827BD00188F8300082C620400A1
-:106C600003E00008384200018F830008246200011D
-:106C700003E00008AF8200088F8300082462FFFF52
-:106C800003E00008AF82000827BDFFE0AFB10014A9
-:106C9000AFBF0018AFB000108F6B00303C06600033
-:106CA00000808821ACCB20088F6A002C3C02800039
-:106CB00024030008ACCA200C9769003A9768003892
-:106CC00000092C003107FFFF00A72025ACC42010CD
-:106CD000ACC22014ACC32000000000000000000083
-:106CE000000000003C0360008C6D200031AC000807
-:106CF0001580FFF9000000008C6E201405C00020F4
-:106D0000000000000E0007DA8F84000C00024080B3
-:106D10003C09080025295998010938218CE4000014
-:106D20000E0007DA00028140020220213090FFFFAE
-:106D3000020020210E0007F8000028213C0C8000F2
-:106D4000022C58253210FFFF3C116000240A00205D
-:106D5000AE2B2014AE302018AE2A20000000000018
-:106D60000000000000000000020010218FBF00188A
-:106D70008FB100148FB0001003E0000827BD002081
-:106D80008C6620143C02001F3443FF803C1FFFE848
-:106D900000C3C02437F9080003198021001079C20C
-:106DA0003C0C8000022C582531F0FFFF3C116000A4
-:106DB000240A0020AE2B2014AE302018AE2A20006A
-:106DC0000000000000000000000000000200102190
-:106DD0008FBF00188FB100148FB0001003E00008BF
-:106DE00027BD002027BDFFE8AFB000103402FFFF31
-:106DF0003090FFFFAFBF00141202000602002021F6
-:106E00000E00081600000000020020210E0007F806
-:106E1000240500018F8400088FBF00148FB000107C
-:106E20002483FFFF27BD001803E00008AF8300089C
-:106E3000000439C230E6003F00043B42000718401E
-:106E4000240210002CC4002024C8FFE0AF42002C14
-:106E5000246300011480000330A900FF00071840DC
-:106E6000310600FF0003608024080001019A5821C8
-:106E70003C0A000E00C82804016A382111200005D0
-:106E8000000530278CE900000125302503E00008CB
-:106E9000ACE600008CEE000001C6682403E00008A8
-:106EA000ACED000027BDFFE8AFBF0014AFB000108D
-:106EB0003C0460008C8508083403F00030A2F00028
-:106EC00050430006240200018C8708083404E000C7
-:106ED00030E6F00010C4001E24020002AF82004021
-:106EE0003C1060003C0A0200AE0A0814240910009D
-:106EF0003C08000E8E03440003482021AF49002CBB
-:106F0000240501200E000CC0000030218F830040BA
-:106F1000106000043C021691240B0001106B000E5F
-:106F20003C023D2C344F0090AE0F44088FBF00143C
-:106F30008FB000103C0C6000240E10003C0D0200CD
-:106F400027BD0018AD8E442003E00008AD8D081069
-:106F50000A0008E7AF8000403C0218DA344F009086
-:106F6000AE0F44088FBF00148FB000103C0C6000BF
-:106F7000240E10003C0D020027BD0018AD8E4420E9
-:106F800003E00008AD8D08100A0008BB24050001CD
-:106F90000A0008BB000028213C08080025085DA461
-:106FA0002404FFFF010018212402001E2442FFFFD9
-:106FB000AC6400000441FFFD246300043C070800AA
-:106FC00024E75E208CE5FFFC2404001C240600015D
-:106FD000308A001F0146480424840001000910275C
-:106FE0002C8300201460FFFA00A22824ACE5FFFCEB
-:106FF0003C05666634A4616E3C06080024C65EE06B
-:10700000AF840058AF88009C2404FFFF00C0182103
-:107010002402001F2442FFFFAC6400000441FFFD76
-:10702000246300043C0766663C05080024A55EA0B6
-:10703000AF86004834E6616EAF8600982404FFFFF7
-:1070400000A018212402000F2442FFFFAC640000BE
-:107050000441FFFD246300043C0B66663C06080007
-:1070600024C65E203568616EAF8500A4AF880070CD
-:107070002404FFFF00C018212402001F2442FFFF48
-:10708000AC6400000441FFFD246300043C0D66660F
-:107090003C0A0800254A5F6035AC616EAF860090FF
-:1070A000AF8C005C2404FFFF014018212402000380
-:1070B0002442FFFFAC6400000441FFFD2463000490
-:1070C0003C09080025295F708D27FFFC2404000679
-:1070D000240500013099001F0325C0042484000109
-:1070E000001878272C8E002015C0FFFA00EF3824F6
-:1070F000AD27FFFC3C09666624030400240403DC7E
-:1071000024050200240600663522616E3C08080052
-:1071100025085AA4AF820074AF830044AF83006C8B
-:10712000AF830050AF830084AF8A008CAF840064CB
-:10713000AF85004CAF860054AF840078AF85006007
-:10714000AF86008001001821240200022442FFFFC4
-:10715000AC6000000441FFFD24630004240400032C
-:107160002403000C3C0A0800254A5AB0AF8A006884
-:107170000A00098E2405FFFF000418802484000102
-:10718000006858212C8700C014E0FFFBAD650000AB
-:107190003C0E666635CD616E240C17A024081800DD
-:1071A000AF8D0088AF8C009403E00008AF88007CAE
-:1071B0002484007F000421C200004021000030210F
-:1071C00000003821000028210A0009A5AF8400A092
-:1071D0001060000624E7000100C4302124A500014E
-:1071E0002CC20BF51440FFFA2CA300663C090800E2
-:1071F00025295F6001201821240200032442FFFF9B
-:10720000AC6000000441FFFD2463000410E0001A9C
-:1072100024E3FFFF0003294210A0000A0000202100
-:107220002406FFFF3C03080024635F602484000100
-:107230000085502BAC660000250800011540FFFBBF
-:107240002463000430E2001F10400008000868803A
-:10725000240C0001004C38040008588001692821E2
-:1072600024E6FFFF03E00008ACA6000001A94021CE
-:107270002409FFFFAD09000003E000080000000042
-:10728000AF4400283C04000C034420210005288260
-:107290000A000CC000003021000421803C03600083
-:1072A000AC6410080000000000052980AC65100CDB
-:1072B0000000000003E000088C62100C27BDFFE80E
-:1072C0000080282124040038AFBF00140E0009D527
-:1072D000AFB0001024040E00AF4400283C10000C96
-:1072E00003502021240500100E000CC000003021A6
-:1072F00003501021AC400000AC40000424040038CE
-:107300008FBF00148FB0001024053FFF27BD001869
-:107310000A0009D58C430000000421803C03600072
-:10732000AC641008000000008C62100C03E0000840
-:107330000002118227BDFFC8AFB400208F940068FF
-:10734000AFBE0030AFB7002CAFB600280000B821A8
-:107350000080B021241E00C0AFBF0034AFB50024B0
-:10736000AFB3001CAFB20018AFB10014AFB0001043
-:107370000A000A12AFA5003C504000018F9400683B
-:1073800027DEFFFF13C00028269400048E92000021
-:107390003C03080024635DA01240FFF70283102B1A
-:1073A0003C04080024845AA4028410230002A8C0CC
-:1073B000000098210A000A212411000100118840D0
-:1073C000122000260000000002B380210251282470
-:1073D0000200202110A0FFF9267300010E0009DE33
-:1073E000000000000016684032EC000101AC2021D2
-:1073F0000E0009D5020028218F89009426F700018C
-:107400008FA6003C3AEB0001316A00012528FFFFFE
-:107410000011382702CAB021AF88009416E6FFE7B2
-:1074200002479024AE92000002E010218FBF00348A
-:107430008FBE00308FB7002C8FB600288FB5002488
-:107440008FB400208FB3001C8FB200188FB10014CE
-:107450008FB0001003E0000827BD00383C0E080084
-:1074600025CE5DA0028E102B0A000A0DAE92000000
-:1074700027BDFFD8AFB10014AFB00010AFBF0020E0
-:10748000AFB3001CAFB2001800A0882110A0001FED
-:10749000000480403C13080026735AA40A000A5ACC
-:1074A0002412000112200019261000010E0009F517
-:1074B00002002021000231422444FFA0000618806F
-:1074C0003045001F2C8217A1007318212631FFFFC1
-:1074D0001040FFF400B230048C690000020020214B
-:1074E00024053FFF012640241500FFEE0126382524
-:1074F0000E0009D5AC6700008F8A009426100001A9
-:10750000254700011620FFE9AF8700948FBF0020B8
-:107510008FB3001C8FB200188FB100148FB0001011
-:1075200003E0000827BD00288F85009C00805821BB
-:107530000000402100004821240A001F3C0C0800E4
-:10754000258C5E1C3C0D080025AD5DA48CA60000BA
-:1075500050C000140000402100AD1023000238C0CC
-:10756000240300010A000A930000202115000003F3
-:1075700000E410212448202400004821252900018E
-:10758000512B00132506DFDC106000062484000167
-:1075900000C3702415C0FFF5000318400A000A91CB
-:1075A0000000402110AC002624A300040060282124
-:1075B000254AFFFF1540FFE5AF85009C512B0004D5
-:1075C0002506DFDC0000402103E000080100102157
-:1075D0000006614230C5001F000C50803C070800C7
-:1075E00024E75DA424040001014730211120000F8D
-:1075F00000A420043C05080024A55E20148000059A
-:107600002529FFFF24C6000410C50011000000005A
-:10761000240400018CCF00000004C0270004204097
-:1076200001F868241520FFF5ACCD00008F99007893
-:1076300001001021032B482303E00008AF890078E4
-:107640003C05080024A55DA40A000A9B0000402117
-:107650003C06080024C65DA40A000AB42404000104
-:10766000308800FF240200021102000A24030003F4
-:107670001103005C8F8900A4240400041104005F3E
-:1076800024050005110500670000182103E000082B
-:10769000006010218F8900483C0C0800258C5EE0BA
-:1076A0003C04080024845F60240300201060000F65
-:1076B00000005821240D0002240E00033C0F080096
-:1076C00025EF5EE08D27000014E0000B30F9FFFF8E
-:1076D000252900040124C02B53000001018048210A
-:1076E0002463FFFF5460FFF88D270000016018211C
-:1076F00003E0000800601021132000323C0500FF69
-:1077000030E200FF004030211040004200005021D4
-:1077100024050001000020210005C84000A6C02467
-:1077200017000003332500FF14A0FFFB2484000191
-:10773000012CC023001828C000AA6021008C502111
-:107740003144001F240C0001008C18040003102792
-:1077500000E23024110D0041AD260000110E004C56
-:10776000000A1840110D00368F87006C510E00562C
-:107770008F8C0060240D0004110D005A8F8E008440
-:10778000240E0005150EFFDA01601821240B1430B9
-:1077900011400006000018218F8400A0246300011E
-:1077A000006A402B1500FFFD016458218F8A00807C
-:1077B000AF89008C016018212549FFFF0A000AEB00
-:1077C000AF89008000E52024000736021080FFD03A
-:1077D000240A001800075402314600FF0A000AF389
-:1077E000240A00103C0C0800258C5EA03C04080014
-:1077F00024845EE00A000ADA240300103C0C08002E
-:10780000258C5E203C04080024845EA00A000AD96E
-:107810008F89009000071A02306600FF0A000AF301
-:10782000240A00088F89008C3C0C0800258C5F60BE
-:107830003C04080024845F700A000ADA2403000470
-:10784000000A4080250B003024E6FFFF016018216C
-:10785000AF8900480A000AEBAF86006C000AC982B3
-:10786000001978803C07080024E75EA001E720218A
-:10787000000A18428C8F00003079001F032C380456
-:107880000007C02701F860240A000B08AC8C000038
-:10789000000331420006288000AF28213062001F1B
-:1078A0008CB8000024630001004CC804000321428E
-:1078B000001938270004108003073024004F2021CE
-:1078C0000A000B4CACA60000000A68C025AB0032D1
-:1078D000258AFFFF01601821AF8900A40A000AEB86
-:1078E000AF8A0060254B1030AF89009001601821ED
-:1078F00025C9FFFF0A000AEBAF8900843086000724
-:107900002CC2000610400014000000000006408059
-:107910003C030800246357BC010338218CE40000B9
-:1079200000800008000000002409000310A9000ED8
-:1079300000000000240A000510AA000B000000004F
-:10794000240B000110AB0008000000008F8C00A089
-:1079500010AC00050000000003E00008000010214A
-:107960000A000A7900A020210A000AC700C02021CD
-:1079700027BDFFE8308400FF240300021083000BC2
-:10798000AFBF0010240600031086003A240800044C
-:1079900010880068240E0005108E007F2CAF143074
-:1079A0008FBF001003E0000827BD00182CA2003094
-:1079B0001440FFFC8FBF001024A5FFD0000531C28A
-:1079C000000668803C07080024E75EE001A730213C
-:1079D0008CC900000005288230AC001F240B000178
-:1079E000018B50048F840048012A4025ACC8000058
-:1079F0008C83000050600001AF8600488F98006CB7
-:107A000030AE000124A6FFFF270F000115C00002C1
-:107A1000AF8F006C24A600010006414200082080C0
-:107A2000008718218C79000030C2001F2406000155
-:107A30000046F804033F382410E0FFDA8FBF00103F
-:107A40000005C182001870803C0F080025EF5EA081
-:107A500001CF48218D2B00000005684231A5001F91
-:107A600000A66004016C502527BD001803E0000843
-:107A7000AD2A00002CA7003014E0FFCA8FBF001011
-:107A800030B900071723FFC724A8FFCE00086A02F9
-:107A9000000D60803C0B0800256B5EA0018B30213F
-:107AA0008CC40000000828C230AA001F240800016E
-:107AB000014848048F8200A400891825ACC3000047
-:107AC0008C5F000053E00001AF8600A40005704009
-:107AD000000E7942000F28803C04080024845EE0F8
-:107AE00000A418218C6B000025DF000131CD001FA0
-:107AF000001F514201A86004016C4825000A108053
-:107B0000AC690000004428218CA600008F9800601A
-:107B100033F9001F8FBF00100328380400C77825F1
-:107B2000270E000127BD0018ACAF000003E00008DD
-:107B3000AF8E006024A5EFD02CB804001300FF998D
-:107B40008FBF001000053142000658803C0A080033
-:107B5000254A5E20016A30218CC4000030A3001F3A
-:107B600024090001006910048F9900900082F82513
-:107B7000ACDF00008F27000050E00001AF860090CE
-:107B80008F8D00848FBF001027BD001825AC000129
-:107B900003E00008AF8C008415E0FF828FBF001067
-:107BA0008F8600A0000610400046F821001F21002B
-:107BB00003E4C8210019384024F8143000B8402BE1
-:107BC0001100FF788FBF001024A4EBD00E00021329
-:107BD00000C0282100027942000F70803C0D08008F
-:107BE00025AD5F6001CD20218C8B0000304C001F43
-:107BF00024060001018618048F89008C016350253A
-:107C0000AC8A00008D25000050A00001AF84008CDC
-:107C10008F9800808FBF001027BD00182708000133
-:107C200003E00008AF88008030A5000724030003AC
-:107C300010A3001028A2000414400008240700022A
-:107C40002403000410A300152408000510A8000F49
-:107C50008F8500A003E000080000000014A7FFFDCE
-:107C60000080282114C3FFFB240400020A000B8BB0
-:107C700000000000240900050080282110C9FFFB36
-:107C80002404000303E000080000000014C5FFF115
-:107C9000008028210A000B8B24040005240A00011F
-:107CA0000080282110CAFFF12404000403E000082A
-:107CB0000000000027BDFFE0AFB00010000581C24A
-:107CC0002603FFD024C5003F2C6223D024C6007FAA
-:107CD000AFB20018AFB10014AFBF001C309100FF6D
-:107CE000000691C2000529820200202110400008F0
-:107CF0002403FFFF0E000A4B0000000002002021B9
-:107D0000022028210E000C390240302100001821E9
-:107D10008FBF001C8FB200188FB100148FB00010FD
-:107D20000060102103E0000827BD002027BDFFD818
-:107D300024A2007FAFB3001CAFB20018000299C2AA
-:107D4000309200FF24A3003F02402021026028213E
-:107D5000AFB10014AFB00010AFBF00200E000B6E2B
-:107D60000003898200408021004020210220282138
-:107D700014400009000018218FBF00208FB3001CA1
-:107D80008FB200188FB100148FB000100060102166
-:107D900003E0000827BD00280E0009FC00000000D9
-:107DA00000402821020020211051FFF3001019C0CB
-:107DB0000E000A4B00000000020020210240282192
-:107DC0000E000C39026030218FBF00208FB3001CE1
-:107DD0008FB200188FB100148FB00010000018216E
-:107DE0000060102103E0000827BD00283084FFFF59
-:107DF00030A5FFFF1080000700001821308200012D
-:107E00001040000200042042006518211480FFFB8E
-:107E10000005284003E000080060102110C00007A2
-:107E2000000000008CA2000024C6FFFF24A500046F
-:107E3000AC82000014C0FFFB2484000403E00008AF
-:107E40000000000010A0000824A3FFFFAC86000083
-:107E500000000000000000002402FFFF2463FFFF79
-:107E60001462FFFA2484000403E00008000000000C
-:107E700030A5FFFF8F4201B80440FFFE3C076015AC
-:107E800000A730253C031000AF440180AF400184BF
-:107E9000AF46018803E00008AF4301B88F8500D0EA
-:107EA0002C864000008018218CA700840087102BAE
-:107EB00014400010000000008CA800842D06400033
-:107EC00050C0000F240340008CAA0084008A482B75
-:107ED000512000018CA3008400035A42000B208033
-:107EE0003C05080024A558200085182103E000085F
-:107EF0008C62000014C0FFF4000000002403400066
-:107F000000035A42000B20803C05080024A558209D
-:107F10000085182103E000088C6200008F8300D0E8
-:107F2000906600D024C50001A06500D08F8500D0E8
-:107F3000906400D090A200D210440017000000000E
-:107F4000936C00788F8B00BC318A00FFA16A000C13
-:107F500025490001938700C4312200FF3048007F8B
-:107F60001107000B00026827A36200788F4E01788A
-:107F700005C0FFFE8F9900B0241800023C0F1000CE
-:107F8000AF590140A358014403E00008AF4F017806
-:107F90000A000D0931A20080A0A000D00A000CFF49
-:107FA000000000008F8700D027BDFFC8AFBF0030A2
-:107FB000AFB7002CAFB60028AFB50024AFB4002097
-:107FC000AFB3001CAFB20018AFB10014AFB00010D7
-:107FD00094E300E094E200E2104300D72405FFFFA1
-:107FE0003C047FFF3497FFFF2415FF800A000DF04B
-:107FF0003C16000E108A00D18FBF00308F9100B068
-:108000003C1808008F18005C001230C0001291402C
-:108010000311702101D57824AF4F002C94EC00E2BD
-:1080200031CD007F01BA5821318A7FFF0176482186
-:10803000000A804002091021945300003C08080007
-:108040008D0800580246C02132733FFF001319808B
-:10805000010320210224282130BF007F03FAC82118
-:1080600000B5A024AF54002C0336A0218E87001049
-:108070008E8F003003785821256D008800EF702323
-:10808000240C0002AE8E0010AF8D00ACA16C0088F5
-:10809000976A003C8E8400308F9100AC0E000CD6A5
-:1080A0003150FFFF00024B80020940253C02420094
-:1080B00001022025AE2400048E8300048F8D00ACC5
-:1080C0008E860000240E0008ADA3001CADA600188B
-:1080D000ADA0000CADA00010929F000A33F900FF84
-:1080E000A5B90014968500083C1F000CA5A5001634
-:1080F0009298000A331100FFA5B100209690000865
-:1081000024180005A5B00022ADA00024928F000B1A
-:108110002410C00031E700FFA5A70002A1AE0001B6
-:108120008E8C00308F8B00AC8F8400B0AD6C00085B
-:108130003C0A08008D4A005401444821013540247E
-:10814000AF4800283C0208008C4200540044302113
-:1081500030C3007F007AC821033F282102458821CF
-:10816000AF9100BCAF8500C0A23800008F8A00BC70
-:108170002403FFBF2418FFDF954F000201F03824CD
-:1081800000F37025A54E0002914D000231AC003F76
-:10819000358B0040A14B00028F8600BC8F8900D038
-:1081A000ACC000048D28007C3C098000ACC80008ED
-:1081B00090C4000D3082007FA0C2000D8F8500BCEE
-:1081C00090BF000D03E3C824A0B9000D8F9100BC3F
-:1081D0009233000D02789024A232000D8E9000346C
-:1081E0008F8B00BCAD7000108E87002C8E8F0030FE
-:1081F00000EF7023AD6E0014916D001831AC007F5C
-:10820000A16C00188F9F00BC8E8A00308FE8001888
-:10821000015720240109302400C41025AFE20018C2
-:108220009283000AA3E3001C969900088F8500BC86
-:108230008F9800D0A4B9001E8E9000308E8400303C
-:108240000E0002138F0500848F8500D0000291403C
-:108250000002990090AF00BC0253882100403021F9
-:1082600031E7000210E0000302118021000290803B
-:108270000212802190B900BC3327000410E00002F4
-:108280000006F880021F80218E9800308F8B00BC82
-:1082900024068000330F0003000F702331CD00034C
-:1082A000020D6021AD6C000494A400E294AA00E2E7
-:1082B00094B000E231497FFF2522000130537FFF57
-:1082C0000206182400734025A4A800E294A400E24A
-:1082D0003C1408008E94006030917FFF123400221D
-:1082E000000000000E000CF6000000008F8700D098
-:1082F0000000282194F300E094F000E21213000F34
-:108300008FBF003090E900D090E800D1313200FFFB
-:10831000310400FF0244302B14C0FF36264A00010E
-:1083200090EE00D2264B000131CD00FF008D602180
-:10833000158BFF338F9100B08FBF00308FB7002CAB
-:108340008FB600288FB500248FB400208FB3001C97
-:108350008FB200188FB100148FB0001000A0102150
-:1083600003E0000827BD003894A300E20066402423
-:10837000A4A800E290A400E290B900E2309100FFCE
-:108380000011A1C20014F827001F39C03332007F4A
-:10839000024730250A000DE8A0A600E23084FFFF66
-:1083A00030A5FFFFAF440018AF45001C03E00008F4
-:1083B0008F42001427BDFFB8AFB000208F9000D0CF
-:1083C0003084FFFFAFA40010AFBF0044AFBE004039
-:1083D000AFB7003CAFB60038AFB50034AFB4003033
-:1083E000AFB3002CAFB20028AFB10024A7A0001893
-:1083F000920600D1920500D030C400FF30A300FFE8
-:108400000064102B10400122AFA00014920900D08C
-:108410008FB50010312800FF0088382324F4FFFFB7
-:108420000014882B0015982B02339024524001260B
-:108430008FB40014961E0012961F00108FB7001004
-:1084400003DFC823001714000019C400000224032E
-:108450000018140302E2B02A52C00001004020219B
-:108460000284282B10A0000200801821028018210D
-:1084700000033C0000071C033064FFFF2C8600094A
-:1084800014C000020060B821241700088E0A0008FA
-:10849000001769808E09000C31ABFFFF3C0C001007
-:1084A000016C402527520400AF4A0038AF9200B853
-:1084B000AF49003CAF480030000000000000000061
-:1084C00000000000000000000000000000000000AC
-:1084D00000000000000000008F4F000031EE00207F
-:1084E00011C0FFFD0017982A027110240A000E83A4
-:1084F0000000B02155E001019258000131130080C5
-:10850000126001CF012020219655001232A5FFFFF5
-:108510000E000CCBA7B500188F9000D00291A023BD
-:1085200026CD00018F9100B8000DB4000016B403F1
-:108530002638004002D7582A0014882B2405000151
-:108540000300902101711024AF9800B8AFA500146A
-:10855000104001BC8F8900B03C0C08008D8C005489
-:10856000240BFF80921E00D001895021014B28244A
-:10857000921900D0AF4500288E4700103C08080033
-:108580008D0800583C1808008F18005430E33FFF56
-:108590000003218001043021012658212402FF809C
-:1085A0000162F824920C00D0AF5F002C92480000CA
-:1085B00033D100FF333500FF0309982100117140CA
-:1085C000001578C0326D007F01CF382101BA282113
-:1085D000318300FF3164007F3C0A000C00AA88212F
-:1085E0000367F02100033140009A10213108003F59
-:1085F0003C1F000E00D1C021005F982127D90088C0
-:108600002D150008AF9100C0AF9900ACAF9800BC29
-:10861000AF9300B412A0018A00008821240E00014B
-:10862000010E4004310D005D11A0FFB2310F0002B8
-:108630008E4A00283C0300803C04FFEFAE6A000035
-:108640008E450024A260000A3488FFFFAE65000456
-:108650009247002C3C1FFF9F37FEFFFFA267000CD4
-:108660008E62000C3C180040A267000B00433025CE
-:1086700000C8C824033E88240238A825AE75000C23
-:108680008E490004AE6000183C0F00FFAE69001474
-:108690008E4D002C35EEFFFF8F8B00B001AE6024B5
-:1086A000AE6C00108E470008A660000896450012C8
-:1086B000AE6700208E42000C30B03FFF00105180AA
-:1086C000AE6200248E5E0014014B182130A400011C
-:1086D000AE7E00288E590018000331C2000443808A
-:1086E000AE79002C8E51001C00C8F821A67F001C1A
-:1086F000AE710030965800028E550020A678001EFC
-:10870000AE75003492490033313000045600000544
-:10871000925000008F8C00D08D8B007CAE6B0030AF
-:10872000925000008F8F00BCA1F00000924E0033E9
-:1087300031CD000251A00007925E00018F8900BC7C
-:108740002418FF80913100000311A825A1350000F5
-:10875000925E00018F9900BC2409FFBF240BFFDF4C
-:10876000A33E00018F9500BC92B8000D3311007F2D
-:10877000A2B1000D8F8E00BC91D0000D02097824AB
-:10878000A1CF000D8F8800BC8E6D0014910A000DE2
-:108790002DAC0001000C2940014B382400E51825C0
-:1087A000A103000D964200128F8800BC8F8700D075
-:1087B000A50200028E45000490FF00BC30A4000317
-:1087C0000004302330DE000300BE102133F9000224
-:1087D00017200002244400342444003090E200BCFE
-:1087E00000A2302430DF000417E0000224830004DC
-:1087F000008018218F8F00AC24090002AD03000413
-:10880000A1E90000924E003F8F8D00ACA1AE0001A7
-:108810008F9500AC924C003F8E440004A6AC000241
-:10882000976B003C0E000CD63170FFFF00025380A6
-:10883000020A38253C05420000E51825AEA30004D5
-:108840008F8600AC8E480038ACC800188E440034C7
-:10885000ACC4001CACC0000CACC00010A4C0001420
-:10886000A4C00016A4C00020A4C00022ACC00024F4
-:108870008E6400145080000124040001ACC4000880
-:108880000E000CF6241100010A000E768F9000D025
-:10889000920F00D2920E00D08FB5001031EB00FF86
-:1088A00031CD00FF008D6023016C50212554FFFF66
-:1088B0000014882B0015982B023390241640FEDDFF
-:1088C000000000008FB400148FBF00448FBE004032
-:1088D0003A8200018FB7003C8FB600388FB5003464
-:1088E0008FB400308FB3002C8FB200288FB10024DA
-:1088F0008FB0002003E0000827BD0048331100209E
-:10890000122000EF24150001921E00BC241F00015C
-:108910000000A82133D900011320000DAFBF001CB7
-:108920008E4400148E0800840088102B144000022E
-:10893000008030218E0600848E03006400C3A82BC3
-:1089400016A0000200C020218E0400640080A8212F
-:108950008E4700148E05006400E5302B14C0000221
-:1089600000E020218E0400640095F02313C0000471
-:108970008FAC001C240A0002AFAA001C8FAC001CA4
-:10898000028C582B156000A8000018218E4F00386B
-:108990008E6D000C3C0E0080AE6F00008E4A0034DD
-:1089A0003C10FF9F01AE5825AE6A00049246003F7E
-:1089B000360CFFFF016C38243C0500203C03FFEF20
-:1089C000A266000B00E510253468FFFF8F8700B812
-:1089D0000048F8243C04000803E4C825AE79000CE4
-:1089E0008CF80014AE60001802BE7821AE78001436
-:1089F0008CF10018AE71001C8CE90008AE690024EF
-:108A00008CEE000CAE6F002CAE600028AE6E002025
-:108A1000A6600038A660003A8CED001401B58023F2
-:108A2000021E902312400011AE72001090EA003D29
-:108A30008E6500048E640000000A310000A6C82183
-:108A4000000010210326402B0082F82103E8C021FA
-:108A5000AE790004AE78000090F1003DA271000AEA
-:108A60008F8900B895320006A67200088F9800AC76
-:108A70002419000202A02021A31900009769003CDC
-:108A80008F9200AC0E000CD63131FFFF00027B80CC
-:108A90008F8500B8022F68253C0E420001AE80256C
-:108AA000AE5000048F8400AC8CAC0038AC8C001845
-:108AB0008CAB0034AC8B001CAC80000CAC80001084
-:108AC000A4800014A4800016A4800020A4800022AA
-:108AD000AC80002490A7003FA487000212A00135BB
-:108AE0002403000153C0000290A2003D90A2003E6A
-:108AF00024480001A08800018F9F00ACAFF500085A
-:108B00008F8300D024070034906600BC30C500027B
-:108B100050A00001240700308F9200B88F8A00BC5B
-:108B2000906D00BC924B00002412C00032A50003DF
-:108B3000A14B00008F8600B88F8800BC240200047F
-:108B400090C400010045182330790003A1040001FE
-:108B50008F8A00BC8F9F00B800F53821955800021D
-:108B600097E9001200F9382103128824312F3FFFC2
-:108B7000022F7025A54E00029150000231A800047A
-:108B8000320C003F358B0040A14B000212A00002C6
-:108B90008F8500BC00E838218F8E00D0ACA7000480
-:108BA000240BFFBF8DCD007C2EA400012403FFDF2A
-:108BB000ACAD000890B0000D00044140320C007FC5
-:108BC000A0AC000D8F8600BC90CA000D014B102494
-:108BD000A0C2000D8F8700BC90E5000D00A3F82413
-:108BE00003E8C825A0F9000D8F9100B88F8D00BC57
-:108BF0008E380020ADB800108E290024ADA90014D5
-:108C00008E2F0028ADAF00188E2E002C0E000CF613
-:108C1000ADAE001C8FB0001C240C0002120C00EE44
-:108C20008F9000D08FA3001C006088211460000288
-:108C30000060A8210000A02156A0FE390291A023C7
-:108C40000014882B8FA90010960700103C1E0020EE
-:108C50000136402302C750213112FFFFA60A00103F
-:108C6000AFB20010AF5E0030000000009617001099
-:108C7000961300121277008F000000008E05000C82
-:108C80008E0B00080016698000AD7021000DC7C36F
-:108C900001CDA82B0178782101F56021AE0E000CE2
-:108CA000AE0C00088FB300100013B82B02378024DD
-:108CB0001200FF048F9000D00A000E3C000000005C
-:108CC0008E4D0038A6600008240B0003AE6D000036
-:108CD0008E500034A260000A8F9800B8AE70000475
-:108CE0003C0500809311003FA26B000C8E6F000CBE
-:108CF0003C0EFF9FA271000B01E5102535CCFFFF54
-:108D00003C03FFEF8F9200B8004C30243464FFFF27
-:108D100000C4F824AE7F000C8E590014964800124F
-:108D20008F8A00B0AE7900108E490014AE60001832
-:108D3000AE600020AE690014AE6000248E470018BB
-:108D400031093FFF0009F180AE6700288E4D000811
-:108D500003CA802131180001AE6D00308E4F000C27
-:108D60008F8C00AC001089C200185B80022B282178
-:108D7000240E0002A665001CA6600036AE6F002C13
-:108D8000A18E00009763003C8F8A00AC3C04420037
-:108D90003062FFFF00443025AD4600048F9F00B8CD
-:108DA000240700012411C0008FF30038240600348A
-:108DB000AD5300188FF90034AD59001CAD40000CC4
-:108DC000AD400010A5400014A5400016A5400020AD
-:108DD000A5400022AD400024A5550002A147000196
-:108DE0008F9E00AC8F8800B88F9200BCAFD5000872
-:108DF000910D0000A24D00008F9000B88F8B00BC39
-:108E000092180001A17800018F8400BC94850002B3
-:108E100000B1782401E97025A48E0002908C000234
-:108E20003183003FA08300028F8300D08F8400BC79
-:108E3000906200BC305300025260000124060030F2
-:108E4000AC8600048C6F007C2403FFBF02A0882145
-:108E5000AC8F0008908E000D31CC007FA08C000DEF
-:108E60008F8600BC90C2000D00432024A0C4000DDA
-:108E70008F8900BC913F000D37F90020A139000D0A
-:108E80008F8800B88F9300BC8D070020AE6700105C
-:108E90008D0A0024AE6A00148D1E0028AE7E0018D4
-:108EA0008D12002C0E000CF6AE72001C0A00103D54
-:108EB0008F9000D0960E00148E03000431CCFFFF7B
-:108EC000000C10C000622021AF44003C8E1F000443
-:108ED0008F46003C03E6C8231B20003C0000000036
-:108EE0008E0F000025E200013C05001034B500089B
-:108EF000AF420038AF550030000000000000000015
-:108F00000000000000000000000000000000000061
-:108F100000000000000000008F580000330B00200C
-:108F20001160FFFD000000008F5304003C0D002085
-:108F3000AE1300088F570404AE17000CAF4D00307D
-:108F4000000000003C0608008CC600442416000106
-:108F500010D600BD00000000961F00123C0508005E
-:108F60008CA5004000BFC821A61900129609001464
-:108F700025270001A6070014960A00143144FFFFBC
-:108F80005486FF498FB30010A60000140E000E1681
-:108F900030A5FFFF3C0408008C84002496030012D7
-:108FA0000044102300623023A60600120A00105964
-:108FB0008FB30010A08300018F8200AC2404000155
-:108FC000AC4400080A000FF08F8300D08E0200002E
-:108FD0000A0010EA3C0500108F8200C08FA7001C19
-:108FE000921800D0920B00D0920E00D0331100FFE7
-:108FF000316900FF00117940000928C001E56021B6
-:1090000031C300FF036C50210003314000C2C8216E
-:10901000255F0088AF9F00ACAF9900BCA1470088D6
-:109020009768003C03C020218F9100AC0E000CD645
-:109030003110FFFF00026B80020DC0253C0442008E
-:109040008F8D00B803045825AE2B00048DA900387D
-:109050008F8B00AC0000882100118100AD690018E1
-:109060008DAF00343C087FFF3504FFFFAD6F001C5F
-:1090700091AC003E8D65001C8D660018000C190037
-:10908000000C770200A33821020E102500E3F82B14
-:1090900000C2C821033F5021AD67001CAD6A001813
-:1090A000AD60000CAD60001091B8003E24050005D5
-:1090B00003C45024A578001495A9000403C02021FE
-:1090C000A569001691AF003EA56F002095B1000480
-:1090D000A5710022AD60002491AE003FA56E000294
-:1090E00091B0003E91AC003D01901023244300015B
-:1090F000A16300018F8600AC8F9F00BCACDE00082E
-:10910000A3E500008F9000BC8F9900B82405FFBF35
-:1091100096070002973800120247782433093FFF70
-:1091200001E98825A6110002921200022418FFDF2F
-:10913000324E003F35CD0040A20D00028F8600BCAC
-:109140008F8C00D02412FFFFACC000048D8B007CFC
-:109150003C0C8000ACCB000890C2000D3043007F77
-:10916000A0C3000D8F8700BC90FF000D03E5C8244D
-:10917000A0F9000D8F9100BC9229000D01387824D0
-:10918000A22F000D8F9000BCAE120010AE1500147F
-:10919000920E00182415FF8002AE6825A20D00185B
-:1091A0008F8500BC8F8300B88CAB0018016C102435
-:1091B000004A3025ACA600189068003EA0A8001C0C
-:1091C0008F9F00B88F8700BC8F9800D097F900045C
-:1091D000A4F9001E0E0002138F0500848F8600D0B4
-:1091E000000279400002490090D200BC01E98821C8
-:1091F000004028213255000212A0000303D1202193
-:109200000002A8800095202190CD00BC31B200045E
-:109210001240000333DF0003000540800088202156
-:10922000240600048F9E00BC00DFC8233327000300
-:1092300000875021AFCA00040E000CF6A665003866
-:109240000A0010388F9000D0961E00123C080800CB
-:109250008D080024011E9021A61200120A00105948
-:109260008FB3001027BDFFE03C1808008F18005096
-:10927000AFB00010AFBF0018AFB10014AF8400B0A2
-:1092800093710074030478212410FF8031EE007F75
-:109290003225007F01F0582401DA68213C0C000AD5
-:1092A000A38500C401AC2821AF4B002494A9001071
-:1092B0009768000690A600620080382124020030E2
-:1092C0000109202330C300F0AF8500D010620019DF
-:1092D0003090FFFF90AE0062240DFFF0240A005092
-:1092E00001AE6024318B00FF116A002F00000000E6
-:1092F00016000007241F0C00AF5F00248FB100147C
-:109300008FBF00188FB0001003E0000827BD0020B9
-:109310000E000E1C02002021241F0C00AF5F002451
-:109320008FB100148FBF00188FB0001003E0000849
-:1093300027BD002094A200E094A400E290BF011396
-:10934000008218263079FFFF33E700C014E00009DF
-:109350002F31000116000038000000005620FFE603
-:10936000241F0C000E000D18000000000A0011ED73
-:10937000241F0C001620FFDE000000000E000D1858
-:10938000000000001440FFDC241F0C001600002227
-:109390008F8300D0906901133122003FA062011336
-:1093A0000A0011ED241F0C0094AF00D48F8600D466
-:1093B00000E02821240400050E000C5C31F0FFFFC2
-:1093C0001440000524030003979100E600001821D3
-:1093D0002625FFFFA78500E68F5801B80700FFFE8E
-:1093E0003C196013AF400180241F0C00AF50018472
-:1093F000007938253C101000AF4701888FB1001468
-:10940000AF5001B8AF5F00248FB000108FBF0018BD
-:1094100003E0000827BD00200E000E1C02002021E2
-:109420005040FFB5241F0C008F8300D090690113BA
-:109430000A0012163122003F0E000E1C02002021ED
-:109440001440FFAD241F0C00122000078F8300D0B2
-:10945000906801133106003F34C20040A06201133E
-:109460000A0011ED241F0C000E000D180000000072
-:109470005040FFA1241F0C008F8300D0906801137F
-:109480003106003F0A00124634C20040AF9B00C8BC
-:1094900003E00008AF8000EC3089FFFF0009404284
-:1094A0002D020041000921801440000200095040B3
-:1094B00024080040000830C0000811400046582130
-:1094C000256701A800E2C821272F007F2418FF800C
-:1094D00001F818240064302100CA702125CC00FF57
-:1094E000240DFF00018D202425650088240A0088B2
-:1094F0003C010800AC2A004C3C010800AC2500509F
-:10950000AF8400D43C010800AC2900603C01080095
-:10951000AC2800643C010800AC2700543C01080062
-:10952000AC2300583C010800AC26005C03E00008B6
-:1095300000000000308300FF30C6FFFF30E400FF72
-:109540008F4201B80440FFFE00034C00012438257F
-:109550003C08600000E820253C031000AF45018076
-:10956000AF460184AF44018803E00008AF4301B86F
-:109570008F86001C3C096012352700108CCB00043C
-:109580003C0C600E35850010316A00062D48000144
-:10959000ACE800C48CC40004ACA431808CC20008C8
-:1095A00094C30002ACA2318403E00008A78300E466
-:1095B0003C0308008C6300508F8400E88F86001CF9
-:1095C0002402FF800064C0210302C824AF59002890
-:1095D0008CCD00043305007F00BA78213C0E000CCE
-:1095E00001EE2821ACAD00588CC80008AF8500D032
-:1095F0003C076012ACA8005C8CCC001034E8001072
-:10960000ACAC000C8CCB000CACAB000894AA0014E2
-:109610003C0208008C42004425490001A4A9001422
-:1096200094A400143083FFFF106200178F8400D0D1
-:109630003C0A08008D4A0040A4AA00128CCE0018F3
-:10964000AC8E00248CCD0014AC8D00208CC700188B
-:10965000AC87002C8CCC001424060001AC8C0028B4
-:109660008D0B00BC5166001A8D0200B48D0200B84B
-:10967000A482003A948F003AA48F003C948800D4CE
-:1096800003E000083102FFFF3C0908008D29002497
-:10969000A4A000148F8400D0A4A900128CCE0018BE
-:1096A000AC8E00248CCD0014AC8D00208CC700182B
-:1096B000AC87002C8CCC001424060001AC8C002854
-:1096C0008D0B00BC5566FFEA8D0200B88D0200B418
-:1096D000A482003A948F003AA48F003C948800D46E
-:1096E00003E000083102FFFF8F86001C3C0C0800DD
-:1096F0008D8C0050240BFF808CCD00083C03000CA7
-:10970000000D51C0018A4021010B4824AF8A00E8B6
-:10971000AF49002890C700073105007F00BA10212B
-:109720000043282130E4000410800039AF8500D0C8
-:1097300090CF000731EE000811C000380000000093
-:109740008CD9000C8CC400140324C02B13000030EF
-:10975000000000008CC2000CACA200648CCD00188C
-:109760002402FFF8ACAD00688CCC0010ACAC0080DB
-:109770008CCB000CACAB00848CCA001CACAA007C67
-:1097800090A900BC01224024A0A800BC90C30007FF
-:109790003067000810E000048F8500D090AF00BC57
-:1097A00035EE0001A0AE00BC90D9000733380001AF
-:1097B000130000088F8300D08F8700D0240400346A
-:1097C00090E800BC35030002A0E300BC8F8300D00A
-:1097D000AC6400C090C900073126000210C000052B
-:1097E00000000000906A00BC35420004A06200BC8A
-:1097F0008F8300D09065011330AD003FA06D011341
-:109800008F8C00D0958B00D403E000083162FFFFFD
-:109810008CC200140A001305000000000A001306A1
-:10982000ACA0006427BDFFD8AFB000108F90001C23
-:10983000AFBF0024AFB40020AFB20018AFB1001426
-:10984000AFB3001C9613000E3C07600A3C14600680
-:109850003264FFFF369300100E00125534F40410EA
-:109860008F8400D43C11600E0E00099B363100102D
-:10987000920E00153C0708008CE700603C12601255
-:1098800031CD000FA38D00F08E0E00048E0D000868
-:1098900096080012961F00109619001A9618001EBE
-:1098A000960F001C310CFFFF33EBFFFF332AFFFF45
-:1098B0003309FFFF31E6FFFF3C010800AC2B0040FD
-:1098C0003C010800AC2C00243C010800AC2A0044F8
-:1098D000AE293178AE26317C92020015960300162F
-:1098E00036520010304400FF3065FFFF3C06080090
-:1098F0008CC60064AE243188AE4500B492080014D2
-:1099000096190018241F0001011FC004332FFFFF08
-:109910003C0508008CA50058AE5800B8AE4F00BCFE
-:10992000920C0014AF8E00D8AF8D00DC318B00FF9D
-:10993000AE4B00C0920A0015AE670048AE66004C00
-:10994000314900FFAE4900C8AE65007C3C03080009
-:109950008C6300503C0408008C84004C3C080800D8
-:109960008D0800543C0208008C42005C8FBF00242C
-:10997000AE6300808FB00010AE8300748FB3001C04
-:10998000AE22319CAE4200DCAE2731A0AE2631A41F
-:10999000AE24318CAE233190AE283194AE2531986F
-:1099A000AE870050AE860054AE8500708FB10014B3
-:1099B000AE4700E0AE4600E4AE4400CCAE4300D07B
-:1099C000AE4800D4AE4500D88FB400208FB2001846
-:1099D00003E0000827BD002827BDFFE0AFB1001459
-:1099E000AFBF0018241100010E000845AFB00010F1
-:1099F00010510005978400E6978300CC0083102B5C
-:109A0000144000088F8500D4240700028FBF00187F
-:109A10008FB100148FB0001000E0102103E00008A7
-:109A200027BD00200E000C7A24040005AF8200E858
-:109A30001040FFF6240700020E0008498F90001C1A
-:109A4000979F00E68F9900E88F8D00C827EF0001EF
-:109A5000240E0050AF590020A78F00E6A1AE0000F1
-:109A60003C0C08008D8C00648F8600C8240A80009E
-:109A7000000C5E00ACCB0074A4C0000694C9000AC0
-:109A8000241FFF803C0D000C012AC024A4D8000A2A
-:109A900090C8000A24182000011F1825A0C3000A3E
-:109AA0008F8700C8A0E000788F8500C800003821AB
-:109AB000A0A000833C0208008C4200508F8400E884
-:109AC0000044782101FFC824AF590028960B0002FA
-:109AD00031EE007F01DA6021018D3021A4CB00D46A
-:109AE000960A0002AF8600D03C0E000425492401EE
-:109AF000A4C900E68E080004ACC800048E03000868
-:109B0000ACC30000A4C00010A4C00014A0C000D0CA
-:109B10008F8500D02403FFBFA0A000D13C04080023
-:109B20008C8400648F8200D0A04400D28E1F000C71
-:109B30008F8A00D0978F00E4AD5F001C8E19001053
-:109B400024100030AD590018A5400030A551005434
-:109B5000A5510056A54F0016AD4E0068AD580080C7
-:109B6000AD580084914D006231AC000F358B001070
-:109B7000A14B00628F8600D090C900633128007F1E
-:109B8000A0C800638F8400D02406FFFF9085006387
-:109B900000A31024A08200638F9100D000E0102168
-:109BA000923F00BC37F90001A23900BC8F8A00D077
-:109BB000938F00F0AD580064AD5000C0914E00D3BB
-:109BC000000F690031CC000F018D5825A14B00D347
-:109BD0008F8500D08F8900DCACA900E88F8800D881
-:109BE0008FBF00188FB100148FB0001027BD002068
-:109BF000ACA800ECA4A600D6A4A000E0A4A000E2BB
-:109C000003E000080000000027BDFFE0AFB0001037
-:109C10008F90001CAFB10014AFBF00188E19000464
-:109C20003C1808008F180050240FFF80001989C0CD
-:109C30000238702131CD007F01CF602401BA50215C
-:109C40003C0B000CAF4C0028014B4021950900D47F
-:109C5000950400D68E0700043131FFFFAF8800D095
-:109C60000E000913000721C08E0600048F8300C870
-:109C7000000629C0AF4500209064003E30820040BD
-:109C8000144000068F8400D0341FFFFF948300D659
-:109C90003062FFFF145F000400000000948400D6CF
-:109CA0000E0008A83084FFFF8E050004022030213A
-:109CB0008FBF00188FB100148FB000102404002251
-:109CC00000003821000529C00A00127C27BD0020B1
-:109CD00027BDFFE0AFB100143091FFFFAFB000101F
-:109CE000AFBF00181220001D000080218F86001CCD
-:109CF0008CC500002403000600053F020005140285
-:109D000030E4000714830015304500FF2CA800063E
-:109D10001100004D000558803C0C0800258C57D4DC
-:109D2000016C50218D490000012000080000000056
-:109D30008F8E00EC240D000111CD005900000000B1
-:109D4000260B00013170FFFF24CA00200211202BD6
-:109D5000014030211480FFE6AF8A001C0200102170
-:109D60008FBF00188FB100148FB0001003E00008FF
-:109D700027BD0020938700CE14E00038240400148F
-:109D80000E001338000000008F86001C2402000122
-:109D90000A00147FAF8200EC8F8900EC24080002D7
-:109DA0001128003B2404001300002821000030216A
-:109DB000240700010E00127C000000000A00147F3E
-:109DC0008F86001C8F8700EC2405000214E5FFF647
-:109DD000240400120E0012E9000000008F8500E844
-:109DE00000403021240400120E00127C00003821B3
-:109DF0000A00147F8F86001C8F8300EC241F000351
-:109E0000147FFFD0260B00010E00129B0000000003
-:109E10008F8500E800403021240200022404001055
-:109E200000003821AF8200EC0E00127C0000000020
-:109E30000A00147F8F86001C8F8F00EC240600021E
-:109E400011E6000B0000000024040010000028218F
-:109E5000000030210A00149C240700010000282182
-:109E60000E00127C000030210A00147F8F86001C37
-:109E70000E0013A500000000144000128F99001C72
-:109E80008F86001C240200030A00147FAF8200ECBE
-:109E90000E001431000000000A00147F8F86001CA1
-:109EA0000E00128B000000002402000224040014A3
-:109EB0000000282100003021000038210A0014B9D8
-:109EC000AF8200EC004038212404001097380002D3
-:109ED000000028210E00127C3306FFFF0A00147FC9
-:109EE0008F86001C8F8400C83C077FFF34E6FFFF8D
-:109EF0008C8500742402000100A61824AC83007431
-:109F000003E00008A082000510A000362CA200800B
-:109F1000274A04003C0B000524090080104000077C
-:109F20002408008030A6000F00C540212D030081C9
-:109F30001460000200A0482124080080AF4B0030CC
-:109F400000000000000000000000000011000009F7
-:109F500000003821014030218C8D000024E70004EE
-:109F600000E8602BACCD0000248400041580FFFACB
-:109F700024C60004000000000000000000000000F3
-:109F80003C0E0006010E3825AF47003000000000EF
-:109F900000000000000000008F4F000031E80010BA
-:109FA0001100FFFD000000008F42003C8F43003C89
-:109FB0000049C8210323C02B130000040000000047
-:109FC0008F4C003825860001AF4600388F47003C93
-:109FD00000A9282300E96821AF4D003C14A0FFCE62
-:109FE0002CA2008003E000080000000027BDFFD085
-:109FF0003C020002AFB100143C11000CAF45003828
-:10A00000AFB3001CAF46003C00809821AF42003047
-:10A0100024050088AF44002803512021AFBF002849
-:10A02000AFB50024AFB40020AFB200180E0014F199
-:10A03000AFB000103C1F08008FFF004C3C18080018
-:10A040008F1800642410FF8003F3A82132B9007F29
-:10A0500002B078240018A0C0033A70210018914083
-:10A0600001D12021AF4F00280E0014F10254282105
-:10A070003C0D08008DAD00502405012001B358218E
-:10A08000316C007F01705024019A48210131202158
-:10A090000E0014F1AF4A00283C0808008D08005457
-:10A0A0003C0508008CA500640113382130E6007FD0
-:10A0B00000F0182400DA202100912021AF4300286D
-:10A0C0000E0014F1000529403C0208008C420058A3
-:10A0D0003C1008008E1000601200001C0053882104
-:10A0E0002415FF800A0015743C14000C3226007FF2
-:10A0F0000235182400DA202102402821AF4300282D
-:10A10000009420210E0014F12610FFC01200000F51
-:10A11000023288212E05004110A0FFF42412100005
-:10A120003226007F001091800235182400DA2021A9
-:10A1300002402821AF430028009420210E0014F192
-:10A14000000080211600FFF3023288213C0B08003A
-:10A150008D6B005C240AFF802405000201734021FE
-:10A16000010A4824AF4900283C0408009484006296
-:10A170003110007F021A88213C07000C0E000CAA47
-:10A180000227982100402821026020218FBF00284B
-:10A190008FB500248FB400208FB3001C8FB200183D
-:10A1A0008FB100148FB000100A0014F127BD0030E9
-:10A1B0008F83001C8C62000410400003000000002C
-:10A1C00003E00008000000008C6400108C650008AB
-:08A1D0000A00152A8C66000C40
-:08A1D800000000000000001B64
-:10A1E0000000000F0000000A000000080000000648
-:10A1F000000000050000000500000004000000044D
-:10A200000000000300000003000000030000000342
-:10A210000000000300000002000000020000000235
-:10A220000000000200000002000000020000000226
-:10A230000000000200000002000000020000000216
-:10A240000000000200000002000000020000000206
-:0CA25000000000010000000100000001FF
-:04A25C0008000F24C3
-:10A2600008000D6C08000FB80800106008000F4CC3
-:10A2700008000F8C0800119408000D88080011B820
-:10A2800008000DD8080015540800151C08000D889A
-:10A2900008000D8808000D880800124008001240D0
-:10A2A00008000D8808000D88080014E008000D88DB
-:10A2B00008000D8808000D8808000D88080013B4F8
-:10A2C00008000D8808000D8808000D8808000D881A
-:10A2D00008000D8808000D8808000D8808000D880A
-:10A2E00008000D8808000D8808000D8808000D88FA
-:10A2F00008000D8808000D8808000FAC08000D88C4
-:10A3000008000D880800167808000D8808000D88E0
-:10A3100008000D8808000D8808000D8808000D88C9
-:10A3200008000D8808000D8808000D8808000D88B9
-:10A3300008000D8808000D8808000D8808000D88A9
-:10A3400008000D8808000D8808000D88080014100A
-:10A3500008000D8808000D8808001334080012A4B6
-:10A3600008001E2C08001EFC08001F1408001F28EF
-:10A3700008001F3808001E2C08001E2C08001E2C88
-:10A3800008001ED808002E1408002E1C08002DE41A
-:10A3900008002DF008002DFC08002E08080052F4DB
-:10A3A000080052B40800528008005254080052308D
-:04A3B000080051EC64
-:0CA3B4000A000C84000000000000000003
-:10A3C0000000000D727870362E322E310000000031
-:10A3D0000602010300000000000000010000000070
-:10A3E000000000000000000000000000000000006D
-:10A3F000000000000000000000000000000000005D
-:10A40000000000000000000000000000000000004C
-:10A41000000000000000000000000000000000003C
-:10A42000000000000000000000000000000000002C
-:10A43000000000000000000000000000000000001C
-:10A44000000000000000000000000000000000000C
-:10A4500000000000000000000000000000000000FC
-:10A4600000000000000000000000000000000000EC
-:10A4700000000000000000000000000000000000DC
-:10A4800000000000000000000000000000000000CC
-:10A4900000000000000000000000000000000000BC
-:10A4A00000000000000000000000000000000000AC
-:10A4B000000000000000000000000000000000009C
-:10A4C000000000000000000000000000000000008C
-:10A4D000000000000000000000000000000000007C
-:10A4E000000000000000000000000000000000006C
-:10A4F000000000000000000000000000000000005C
-:10A50000000000000000000000000000000000004B
-:10A51000000000000000000000000000000000003B
-:10A52000000000000000000000000000000000002B
-:10A53000000000000000000000000000000000001B
-:10A54000000000000000000000000000000000000B
-:10A5500000000000000000000000000000000000FB
-:10A5600000000000000000000000000000000000EB
-:10A5700000000000000000000000000000000000DB
-:10A5800000000000000000000000000000000000CB
-:10A5900000000000000000000000000000000000BB
-:10A5A00000000000000000000000000000000000AB
-:10A5B000000000000000000000000000000000009B
-:10A5C000000000000000000000000000000000008B
-:10A5D000000000000000000000000000000000007B
-:10A5E000000000000000000000000000000000006B
-:10A5F000000000000000000000000000000000005B
-:10A60000000000000000000000000000000000004A
-:10A61000000000000000000000000000000000003A
-:10A62000000000000000000000000000000000002A
-:10A63000000000000000000000000000000000001A
-:10A64000000000000000000000000000000000000A
-:10A6500000000000000000000000000000000000FA
-:10A6600000000000000000000000000000000000EA
-:10A6700000000000000000000000000000000000DA
-:10A6800000000000000000000000000000000000CA
-:10A6900000000000000000000000000000000000BA
-:10A6A00000000000000000000000000000000000AA
-:10A6B000000000000000000000000000000000009A
-:10A6C000000000000000000000000000000000008A
-:10A6D000000000000000000000000000000000007A
-:10A6E000000000000000000000000000000000006A
-:10A6F000000000000000000000000000000000005A
-:10A700000000000000000000000000000000000049
-:10A710000000000000000000000000000000000039
-:10A720000000000000000000000000000000000029
-:10A730000000000000000000000000000000000019
-:10A740000000000000000000000000000000000009
-:10A7500000000000000000000000000000000000F9
-:10A7600000000000000000000000000000000000E9
-:10A7700000000000000000000000000000000000D9
-:10A7800000000000000000000000000000000000C9
-:10A7900000000000000000000000000000000000B9
-:10A7A00000000000000000000000000000000000A9
-:10A7B0000000000000000000000000000000000099
-:10A7C0000000000000000000000000000000000089
-:10A7D0000000000000000000000000000000000079
-:10A7E0000000000000000000000000000000000069
-:10A7F0000000000000000000000000000000000059
-:10A800000000000000000000000000000000000048
-:10A810000000000000000000000000000000000038
-:10A820000000000000000000000000000000000028
-:10A830000000000000000000000000000000000018
-:10A840000000000000000000000000000000000008
-:10A8500000000000000000000000000000000000F8
-:10A8600000000000000000000000000000000000E8
-:10A8700000000000000000000000000000000000D8
-:10A8800000000000000000000000000000000000C8
-:10A8900000000000000000000000000000000000B8
-:10A8A00000000000000000000000000000000000A8
-:10A8B0000000000000000000000000000000000098
-:10A8C0000000000000000000000000000000000088
-:10A8D0000000000000000000000000000000000078
-:10A8E0000000000000000000000000000000000068
-:10A8F0000000000000000000000000000000000058
-:10A900000000000000000000000000000000000047
-:10A910000000000000000000000000000000000037
-:10A920000000000000000000000000000000000027
-:10A930000000000000000000000000000000000017
-:10A940000000000000000000000000000000000007
-:10A9500000000000000000000000000000000000F7
-:10A9600000000000000000000000000000000000E7
-:10A9700000000000000000000000000000000000D7
-:10A9800000000000000000000000000000000000C7
-:10A9900000000000000000000000000000000000B7
-:10A9A00000000000000000000000000000000000A7
-:10A9B0000000000000000000000000000000000097
-:10A9C0000000000000000000000000000000000087
-:10A9D0000000000000000000000000000000000077
-:10A9E0000000000000000000000000000000000067
-:10A9F0000000000000000000000000000000000057
-:10AA00000000000000000000000000000000000046
-:10AA10000000000000000000000000000000000036
-:10AA20000000000000000000000000000000000026
-:10AA30000000000000000000000000000000000016
-:10AA40000000000000000000000000000000000006
-:10AA500000000000000000000000000000000000F6
-:10AA600000000000000000000000000000000000E6
-:10AA700000000000000000000000000000000000D6
-:10AA800000000000000000000000000000000000C6
-:10AA900000000000000000000000000000000000B6
-:10AAA00000000000000000000000000000000000A6
-:10AAB0000000000000000000000000000000000096
-:10AAC0000000000000000000000000000000000086
-:10AAD0000000000000000000000000000000000076
-:10AAE0000000000000000000000000000000000066
-:10AAF0000000000000000000000000000000000056
-:10AB00000000000000000000000000000000000045
-:10AB10000000000000000000000000000000000035
-:10AB20000000000000000000000000000000000025
-:10AB30000000000000000000000000000000000015
-:10AB40000000000000000000000000000000000005
-:10AB500000000000000000000000000000000000F5
-:10AB600000000000000000000000000000000000E5
-:10AB700000000000000000000000000000000000D5
-:10AB800000000000000000000000000000000000C5
-:10AB900000000000000000000000000000000000B5
-:10ABA00000000000000000000000000000000000A5
-:10ABB0000000000000000000000000000000000095
-:10ABC0000000000000000000000000000000000085
-:10ABD0000000000000000000000000000000000075
-:10ABE0000000000000000000000000000000000065
-:10ABF0000000000000000000000000000000000055
-:10AC00000000000000000000000000000000000044
-:10AC10000000000000000000000000000000000034
-:10AC20000000000000000000000000000000000024
-:10AC30000000000000000000000000000000000014
-:10AC40000000000000000000000000000000000004
-:10AC500000000000000000000000000000000000F4
-:10AC600000000000000000000000000000000000E4
-:10AC700000000000000000000000000000000000D4
-:10AC800000000000000000000000000000000000C4
-:10AC900000000000000000000000000000000000B4
-:10ACA00000000000000000000000000000000000A4
-:10ACB0000000000000000000000000000000000094
-:10ACC0000000000000000000000000000000000084
-:10ACD0000000000000000000000000000000000074
-:10ACE0000000000000000000000000000000000064
-:10ACF0000000000000000000000000000000000054
-:10AD00000000000000000000000000000000000043
-:10AD10000000000000000000000000000000000033
-:10AD20000000000000000000000000000000000023
-:10AD30000000000000000000000000000000000013
-:10AD40000000000000000000000000000000000003
-:10AD500000000000000000000000000000000000F3
-:10AD600000000000000000000000000000000000E3
-:10AD700000000000000000000000000000000000D3
-:10AD800000000000000000000000000000000000C3
-:10AD900000000000000000000000000000000000B3
-:10ADA00000000000000000000000000000000000A3
-:10ADB0000000000000000000000000000000000093
-:10ADC0000000000000000000000000000000000083
-:10ADD0000000000000000000000000000000000073
-:10ADE0000000000000000000000000000000000063
-:10ADF0000000000000000000000000000000000053
-:10AE00000000000000000000000000000000000042
-:10AE10000000000000000000000000000000000032
-:10AE20000000000000000000000000000000000022
-:10AE30000000000000000000000000000000000012
-:10AE40000000000000000000000000000000000002
-:10AE500000000000000000000000000000000000F2
-:10AE600000000000000000000000000000000000E2
-:10AE700000000000000000000000000000000000D2
-:10AE800000000000000000000000000000000000C2
-:10AE900000000000000000000000000000000000B2
-:10AEA00000000000000000000000000000000000A2
-:10AEB0000000000000000000000000000000000092
-:10AEC0000000000000000000000000000000000082
-:10AED0000000000000000000000000000000000072
-:10AEE0000000000000000000000000000000000062
-:10AEF0000000000000000000000000000000000052
-:10AF00000000000000000000000000000000000041
-:10AF10000000000000000000000000000000000031
-:10AF20000000000000000000000000000000000021
-:10AF30000000000000000000000000000000000011
-:10AF40000000000000000000000000000000000001
-:10AF500000000000000000000000000000000000F1
-:10AF600000000000000000000000000000000000E1
-:10AF700000000000000000000000000000000000D1
-:10AF800000000000000000000000000000000000C1
-:10AF900000000000000000000000000000000000B1
-:10AFA00000000000000000000000000000000000A1
-:10AFB0000000000000000000000000000000000091
-:10AFC0000000000000000000000000000000000081
-:10AFD0000000000000000000000000000000000071
-:10AFE0000000000000000000000000000000000061
-:10AFF0000000000000000000000000000000000051
-:10B000000000000000000000000000000000000040
-:10B010000000000000000000000000000000000030
-:10B020000000000000000000000000000000000020
-:10B030000000000000000000000000000000000010
-:10B040000000000000000000000000000000000000
-:10B0500000000000000000000000000000000000F0
-:10B0600000000000000000000000000000000000E0
-:10B0700000000000000000000000000000000000D0
-:10B0800000000000000000000000000000000000C0
-:10B0900000000000000000000000000000000000B0
-:10B0A00000000000000000000000000000000000A0
-:10B0B0000000000000000000000000000000000090
-:10B0C0000000000000000000000000000000000080
-:10B0D0000000000000000000000000000000000070
-:10B0E0000000000000000000000000000000000060
-:10B0F0000000000000000000000000000000000050
-:10B10000000000000000000000000000000000003F
-:10B11000000000000000000000000000000000002F
-:10B12000000000000000000000000000000000001F
-:10B13000000000000000000000000000000000000F
-:10B1400000000000000000000000000000000000FF
-:10B1500000000000000000000000000000000000EF
-:10B1600000000000000000000000000000000000DF
-:10B1700000000000000000000000000000000000CF
-:10B1800000000000000000000000000000000000BF
-:10B1900000000000000000000000000000000000AF
-:10B1A000000000000000000000000000000000009F
-:10B1B000000000000000000000000000000000008F
-:10B1C000000000000000000000000000000000007F
-:10B1D000000000000000000000000000000000006F
-:10B1E000000000000000000000000000000000005F
-:10B1F000000000000000000000000000000000004F
-:10B20000000000000000000000000000000000003E
-:10B21000000000000000000000000000000000002E
-:10B22000000000000000000000000000000000001E
-:10B23000000000000000000000000000000000000E
-:10B2400000000000000000000000000000000000FE
-:10B2500000000000000000000000000000000000EE
-:10B2600000000000000000000000000000000000DE
-:10B2700000000000000000000000000000000000CE
-:10B2800000000000000000000000000000000000BE
-:10B2900000000000000000000000000000000000AE
-:10B2A000000000000000000000000000000000009E
-:10B2B000000000000000000000000000000000008E
-:10B2C000000000000000000000000000000000007E
-:10B2D000000000000000000000000000000000006E
-:10B2E000000000000000000000000000000000005E
-:10B2F000000000000000000000000000000000004E
-:10B30000000000000000000000000000000000003D
-:10B31000000000000000000000000000000000002D
-:10B32000000000000000000000000000000000001D
-:10B33000000000000000000000000000000000000D
-:10B3400000000000000000000000000000000000FD
-:10B3500000000000000000000000000000000000ED
-:10B3600000000000000000000000000000000000DD
-:10B3700000000000000000000000000000000000CD
-:10B3800000000000000000000000000000000000BD
-:10B3900000000000000000000000000000000000AD
-:10B3A000000000000000000000000000000000009D
-:10B3B000000000000000000000000000000000008D
-:10B3C000000000000000000000000000000000007D
-:10B3D000000000000000000000000000000000006D
-:10B3E000000000000000000000000000000000005D
-:10B3F000000000000000000000000000000000004D
-:10B40000000000000000000000000000000000003C
-:10B41000000000000000000000000000000000002C
-:10B42000000000000000000000000000000000001C
-:10B43000000000000000000000000000000000000C
-:10B4400000000000000000000000000000000000FC
-:10B4500000000000000000000000000000000000EC
-:10B4600000000000000000000000000000000000DC
-:10B4700000000000000000000000000000000000CC
-:10B4800000000000000000000000000000000000BC
-:10B4900000000000000000000000000000000000AC
-:10B4A000000000000000000000000000000000009C
-:10B4B000000000000000000000000000000000008C
-:10B4C000000000000000000000000000000000007C
-:10B4D000000000000000000000000000000000006C
-:10B4E000000000000000000000000000000000005C
-:10B4F000000000000000000000000000000000004C
-:10B50000000000000000000000000000000000003B
-:10B51000000000000000000000000000000000002B
-:10B52000000000000000000000000000000000001B
-:10B53000000000000000000000000000000000000B
-:10B5400000000000000000000000000000000000FB
-:10B5500000000000000000000000000000000000EB
-:10B5600000000000000000000000000000000000DB
-:10B5700000000000000000000000000000000000CB
-:10B5800000000000000000000000000000000000BB
-:10B5900000000000000000000000000000000000AB
-:10B5A000000000000000000000000000000000009B
-:10B5B000000000000000000000000000000000008B
-:10B5C000000000000000000000000000000000007B
-:10B5D000000000000000000000000000000000006B
-:10B5E000000000000000000000000000000000005B
-:10B5F000000000000000000000000000000000004B
-:10B60000000000000000000000000000000000003A
-:10B61000000000000000000000000000000000002A
-:10B62000000000000000000000000000000000001A
-:10B63000000000000000000000000000000000000A
-:10B6400000000000000000000000000000000000FA
-:10B6500000000000000000000000000000000000EA
-:10B6600000000000000000000000000000000000DA
-:10B6700000000000000000000000000000000000CA
-:10B6800000000000000000000000000000000000BA
-:10B6900000000000000000000000000000000000AA
-:10B6A000000000000000000000000000000000009A
-:10B6B000000000000000000000000000000000008A
-:10B6C000000000000000000000000000000000007A
-:10B6D000000000000000000000000000000000006A
-:10B6E000000000000000000000000000000000005A
-:10B6F000000000000000000000000000000000004A
-:10B700000000000000000000000000000000000039
-:10B710000000000000000000000000000000000029
-:10B720000000000000000000000000000000000019
-:10B730000000000000000000000000000000000009
-:10B7400000000000000000000000000000000000F9
-:10B7500000000000000000000000000000000000E9
-:10B7600000000000000000000000000000000000D9
-:10B7700000000000000000000000000000000000C9
-:10B7800000000000000000000000000000000000B9
-:10B7900000000000000000000000000000000000A9
-:10B7A0000000000000000000000000000000000099
-:10B7B0000000000000000000000000000000000089
-:10B7C0000000000000000000000000000000000079
-:10B7D0000000000000000000000000000000000069
-:10B7E0000000000000000000000000000000000059
-:10B7F0000000000000000000000000000000000049
-:10B800000000000000000000000000000000000038
-:10B810000000000000000000000000000000000028
-:10B820000000000000000000000000000000000018
-:10B830000000000000000000000000000000000008
-:10B8400000000000000000000000000000000000F8
-:10B8500000000000000000000000000000000000E8
-:10B8600000000000000000000000000000000000D8
-:10B8700000000000000000000000000000000000C8
-:10B8800000000000000000000000000000000000B8
-:10B8900000000000000000000000000000000000A8
-:10B8A0000000000000000000000000000000000098
-:10B8B0000000000000000000000000000000000088
-:10B8C0000000000000000000000000000000000078
-:10B8D0000000000000000000000000000000000068
-:10B8E0000000000000000000000000000000000058
-:10B8F0000000000000000000000000000000000048
-:10B900000000000000000000000000000000000037
-:10B910000000000000000000000000000000000027
-:10B920000000000000000000000000000000000017
-:10B930000000000000000000000000000000000007
-:10B9400000000000000000000000000000000000F7
-:10B9500000000000000000000000000000000000E7
-:10B9600000000000000000000000000000000000D7
-:10B9700000000000000000000000000000000000C7
-:10B9800000000000000000000000000000000000B7
-:10B9900000000000000000000000000000000000A7
-:10B9A0000000000000000000000000000000000097
-:10B9B0000000000000000000000000000000000087
-:10B9C0000000000000000000000000000000000077
-:10B9D0000000000000000000000000000000000067
-:10B9E0000000000000000000000000000000000057
-:10B9F0000000000000000000000000000000000047
-:10BA00000000000000000000000000000000000036
-:10BA10000000000000000000000000000000000026
-:10BA20000000000000000000000000000000000016
-:10BA30000000000000000000000000000000000006
-:10BA400000000000000000000000000000000000F6
-:10BA500000000000000000000000000000000000E6
-:10BA600000000000000000000000000000000000D6
-:10BA700000000000000000000000000000000000C6
-:10BA800000000000000000000000000000000000B6
-:10BA900000000000000000000000000000000000A6
-:10BAA0000000000000000000000000000000000096
-:10BAB0000000000000000000000000000000000086
-:10BAC0000000000000000000000000000000000076
-:10BAD0000000000000000000000000000000000066
-:10BAE0000000000000000000000000000000000056
-:10BAF0000000000000000000000000000000000046
-:10BB00000000000000000000000000000000000035
-:10BB10000000000000000000000000000000000025
-:10BB20000000000000000000000000000000000015
-:10BB30000000000000000000000000000000000005
-:10BB400000000000000000000000000000000000F5
-:10BB500000000000000000000000000000000000E5
-:10BB600000000000000000000000000000000000D5
-:10BB700000000000000000000000000000000000C5
-:10BB800000000000000000000000000000000000B5
-:10BB900000000000000000000000000000000000A5
-:10BBA0000000000000000000000000000000000095
-:10BBB0000000000000000000000000000000000085
-:10BBC0000000000000000000000000000000000075
-:10BBD0000000000000000000000000000000000065
-:10BBE0000000000000000000000000000000000055
-:10BBF0000000000000000000000000000000000045
-:10BC00000000000000000000000000000000000034
-:10BC10000000000000000000000000000000000024
-:10BC20000000000000000000000000000000000014
-:10BC30000000000000000000000000000000000004
-:10BC400000000000000000000000000000000000F4
-:10BC500000000000000000000000000000000000E4
-:10BC600000000000000000000000000000000000D4
-:10BC700000000000000000000000000000000000C4
-:10BC800000000000000000000000000000000000B4
-:10BC900000000000000000000000000000000000A4
-:10BCA0000000000000000000000000000000000094
-:10BCB0000000000000000000000000000000000084
-:10BCC0000000000000000000000000000000000074
-:10BCD0000000000000000000000000000000000064
-:10BCE0000000000000000000000000000000000054
-:10BCF0000000000000000000000000000000000044
-:10BD00000000000000000000000000000000000033
-:10BD10000000000000000000000000000000000023
-:10BD20000000000000000000000000000000000013
-:10BD30000000000000000000000000000000000003
-:10BD400000000000000000000000000000000000F3
-:10BD500000000000000000000000000000000000E3
-:10BD600000000000000000000000000000000000D3
-:10BD700000000000000000000000000000000000C3
-:10BD800000000000000000000000000000000000B3
-:10BD900000000000000000000000000000000000A3
-:10BDA0000000000000000000000000000000000093
-:10BDB0000000000000000000000000000000000083
-:10BDC0000000000000000000000000000000000073
-:10BDD0000000000000000000000000000000000063
-:10BDE0000000000000000000000000000000000053
-:10BDF0000000000000000000000000000000000043
-:10BE00000000000000000000000000000000000032
-:10BE10000000000000000000000000000000000022
-:10BE20000000000000000000000000000000000012
-:10BE30000000000000000000000000000000000002
-:10BE400000000000000000000000000000000000F2
-:10BE500000000000000000000000000000000000E2
-:10BE600000000000000000000000000000000000D2
-:10BE700000000000000000000000000000000000C2
-:10BE800000000000000000000000000000000000B2
-:10BE900000000000000000000000000000000000A2
-:10BEA0000000000000000000000000000000000092
-:10BEB0000000000000000000000000000000000082
-:10BEC0000000000000000000000000000000000072
-:10BED0000000000000000000000000000000000062
-:10BEE0000000000000000000000000000000000052
-:10BEF0000000000000000000000000000000000042
-:10BF00000000000000000000000000000000000031
-:10BF10000000000000000000000000000000000021
-:10BF20000000000000000000000000000000000011
-:10BF30000000000000000000000000000000000001
-:10BF400000000000000000000000000000000000F1
-:10BF500000000000000000000000000000000000E1
-:10BF600000000000000000000000000000000000D1
-:10BF700000000000000000000000000000000000C1
-:10BF800000000000000000000000000000000000B1
-:10BF900000000000000000000000000000000000A1
-:10BFA0000000000000000000000000000000000091
-:10BFB0000000000000000000000000000000000081
-:10BFC0000000000000000000000000000000000071
-:10BFD0000000000000000000000000000000000061
-:10BFE0000000000000000000000000000000000051
-:10BFF0000000000000000000000000000000000041
-:10C000000000000000000000000000000000000030
-:10C010000000000000000000000000000000000020
-:10C020000000000000000000000000000000000010
-:10C030000000000000000000000000000000000000
-:10C0400000000000000000000000000000000000F0
-:10C0500000000000000000000000000000000000E0
-:10C0600000000000000000000000000000000000D0
-:10C0700000000000000000000000000000000000C0
-:10C0800000000000000000000000000000000000B0
-:10C0900000000000000000000000000000000000A0
-:10C0A0000000000000000000000000000000000090
-:10C0B0000000000000000000000000000000000080
-:10C0C0000000000000000000000000000000000070
-:10C0D0000000000000000000000000000000000060
-:10C0E0000000000000000000000000000000000050
-:10C0F0000000000000000000000000000000000040
-:10C10000000000000000000000000000000000002F
-:10C11000000000000000000000000000000000001F
-:10C12000000000000000000000000000000000000F
-:10C1300000000000000000000000000000000000FF
-:10C1400000000000000000000000000000000000EF
-:10C1500000000000000000000000000000000000DF
-:10C1600000000000000000000000000000000000CF
-:10C1700000000000000000000000000000000000BF
-:10C1800000000000000000000000000000000000AF
-:10C19000000000000000000000000000000000009F
-:10C1A000000000000000000000000000000000008F
-:10C1B000000000000000000000000000000000007F
-:10C1C000000000000000000000000000000000006F
-:10C1D000000000000000000000000000000000005F
-:10C1E000000000000000000000000000000000004F
-:10C1F000000000000000000000000000000000003F
-:10C20000000000000000000000000000000000002E
-:10C21000000000000000000000000000000000001E
-:10C22000000000000000000000000000000000000E
-:10C2300000000000000000000000000000000000FE
-:10C2400000000000000000000000000000000000EE
-:10C2500000000000000000000000000000000000DE
-:10C2600000000000000000000000000000000000CE
-:10C2700000000000000000000000000000000000BE
-:10C2800000000000000000000000000000000000AE
-:10C29000000000000000000000000000000000009E
-:10C2A000000000000000000000000000000000008E
-:10C2B000000000000000000000000000000000007E
-:10C2C000000000000000000000000000000000006E
-:10C2D000000000000000000000000000000000005E
-:10C2E000000000000000000000000000000000004E
-:10C2F000000000000000000000000000000000003E
-:10C30000000000000000000000000000000000002D
-:10C31000000000000000000000000000000000001D
-:10C32000000000000000000000000000000000000D
-:10C3300000000000000000000000000000000000FD
-:10C3400000000000000000000000000000000000ED
-:10C3500000000000000000000000000000000000DD
-:10C3600000000000000000000000000000000000CD
-:10C3700000000000000000000000000000000000BD
-:10C3800000000000000000000000000000000000AD
-:10C39000000000000000000000000000000000009D
-:10C3A000000000000000000000000000000000008D
-:10C3B000000000000000000000000000000000007D
-:10C3C000000000000000000000000000000000006D
-:10C3D000000000000000000000000000000000005D
-:10C3E000000000000000000000000000000000004D
-:10C3F000000000000000000000000000000000003D
-:10C40000000000000000000000000000000000002C
-:10C41000000000000000000000000000000000001C
-:10C42000000000000000000000000000000000000C
-:10C4300000000000000000000000000000000000FC
-:10C4400000000000000000000000000000000000EC
-:10C4500000000000000000000000000000000000DC
-:10C4600000000000000000000000000000000000CC
-:10C4700000000000000000000000000000000000BC
-:10C4800000000000000000000000000000000000AC
-:10C49000000000000000000000000000000000009C
-:10C4A000000000000000000000000000000000008C
-:10C4B000000000000000000000000000000000007C
-:10C4C000000000000000000000000000000000006C
-:10C4D000000000000000000000000000000000005C
-:10C4E000000000000000000000000000000000004C
-:10C4F000000000000000000000000000000000003C
-:10C50000000000000000000000000000000000002B
-:10C51000000000000000000000000000000000001B
-:10C52000000000000000000000000000000000000B
-:10C5300000000000000000000000000000000000FB
-:10C5400000000000000000000000000000000000EB
-:10C5500000000000000000000000000000000000DB
-:10C5600000000000000000000000000000000000CB
-:10C5700000000000000000000000000000000000BB
-:10C5800000000000000000000000000000000000AB
-:10C59000000000000000000000000000000000009B
-:10C5A000000000000000000000000000000000008B
-:10C5B000000000000000000000000000000000007B
-:10C5C000000000000000000000000000000000006B
-:10C5D000000000000000000000000000000000005B
-:10C5E000000000000000000000000000000000004B
-:10C5F000000000000000000000000000000000003B
-:10C60000000000000000000000000000000000002A
-:10C61000000000000000000000000000000000001A
-:10C62000000000000000000000000000000000000A
-:10C6300000000000000000000000000000000000FA
-:10C6400000000000000000000000000000000000EA
-:10C6500000000000000000000000000000000000DA
-:10C6600000000000000000000000000000000000CA
-:10C6700000000000000000000000000000000000BA
-:10C6800000000000000000000000000000000000AA
-:10C69000000000000000000000000000000000009A
-:10C6A000000000000000000000000000000000008A
-:10C6B000000000000000000000000000000000007A
-:10C6C000000000000000000000000000000000006A
-:10C6D000000000000000000000000000000000005A
-:10C6E000000000000000000000000000000000004A
-:10C6F000000000000000000000000000000000003A
-:10C700000000000000000000000000000000000029
-:10C710000000000000000000000000000000000019
-:10C720000000000000000000000000000000000009
-:10C7300000000000000000000000000000000000F9
-:10C7400000000000000000000000000000000000E9
-:10C7500000000000000000000000000000000000D9
-:10C7600000000000000000000000000000000000C9
-:10C7700000000000000000000000000000000000B9
-:10C7800000000000000000000000000000000000A9
-:10C790000000000000000000000000000000000099
-:10C7A0000000000000000000000000000000000089
-:10C7B0000000000000000000000000000000000079
-:10C7C0000000000000000000000000000000000069
-:10C7D0000000000000000000000000000000000059
-:10C7E0000000000000000000000000000000000049
-:10C7F0000000000000000000000000000000000039
-:10C800000000000000000000000000000000000028
-:10C810000000000000000000000000000000000018
-:10C820000000000000000000000000000000000008
-:10C8300000000000000000000000000000000000F8
-:10C8400000000000000000000000000000000000E8
-:10C8500000000000000000000000000000000000D8
-:10C8600000000000000000000000000000000000C8
-:10C8700000000000000000000000000000000000B8
-:10C8800000000000000000000000000000000000A8
-:10C890000000000000000000000000000000000098
-:10C8A0000000000000000000000000000000000088
-:10C8B0000000000000000000000000000000000078
-:10C8C0000000000000000000000000000000000068
-:10C8D0000000000000000000000000000000000058
-:10C8E0000000000000000000000000000000000048
-:10C8F0000000000000000000000000000000000038
-:10C900000000000000000000000000000000000027
-:10C910000000000000000000000000000000000017
-:10C920000000000000000000000000000000000007
-:10C9300000000000000000000000000000000000F7
-:10C9400000000000000000000000000000000000E7
-:10C9500000000000000000000000000000000000D7
-:10C9600000000000000000000000000000000000C7
-:10C9700000000000000000000000000000000000B7
-:10C9800000000000000000000000000000000000A7
-:10C990000000000000000000000000000000000097
-:10C9A0000000000000000000000000000000000087
-:10C9B0000000000000000000000000000000000077
-:10C9C0000000000000000000000000000000000067
-:10C9D0000000000000000000000000000000000057
-:10C9E0000000000000000000000000000000000047
-:10C9F0000000000000000000000000000000000037
-:10CA00000000000000000000000000000000000026
-:10CA10000000000000000000000000000000000016
-:10CA20000000000000000000000000000000000006
-:10CA300000000000000000000000000000000000F6
-:10CA400000000000000000000000000000000000E6
-:10CA500000000000000000000000000000000000D6
-:10CA600000000000000000000000000000000000C6
-:10CA700000000000000000000000000000000000B6
-:10CA800000000000000000000000000000000000A6
-:10CA90000000000000000000000000000000000096
-:10CAA0000000000000000000000000000000000086
-:10CAB0000000000000000000000000000000000076
-:10CAC0000000000000000000000000000000000066
-:10CAD0000000000000000000000000000000000056
-:10CAE0000000000000000000000000000000000046
-:10CAF0000000000000000000000000000000000036
-:10CB00000000000000000000000000000000000025
-:10CB10000000000000000000000000000000000015
-:10CB20000000000000000000000000000000000005
-:10CB300000000000000000000000000000000000F5
-:10CB400000000000000000000000000000000000E5
-:10CB500000000000000000000000000000000000D5
-:10CB600000000000000000000000000000000000C5
-:10CB700000000000000000000000000000000000B5
-:10CB800000000000000000000000000000000000A5
-:10CB90000000000000000000000000000000000095
-:10CBA0000000000000000000000000000000000085
-:10CBB0000000000000000000000000000000000075
-:10CBC0000000000000000000000000000000000065
-:10CBD0000000000000000000000000000000000055
-:10CBE0000000000000000000000000000000000045
-:10CBF0000000000000000000000000000000000035
-:10CC00000000000000000000000000000000000024
-:10CC10000000000000000000000000000000000014
-:10CC20000000000000000000000000000000000004
-:10CC300000000000000000000000000000000000F4
-:10CC400000000000000000000000000000000000E4
-:10CC500000000000000000000000000000000000D4
-:10CC600000000000000000000000000000000000C4
-:10CC700000000000000000000000000000000000B4
-:10CC800000000000000000000000000000000000A4
-:10CC90000000000000000000000000000000000094
-:10CCA0000000000000000000000000000000000084
-:10CCB0000000000000000000000000000000000074
-:10CCC0000000000000000000000000000000000064
-:10CCD0000000000000000000000000000000000054
-:10CCE0000000000000000000000000000000000044
-:10CCF0000000000000000000000000000000000034
-:10CD00000000000000000000000000000000000023
-:10CD10000000000000000000000000000000000013
-:10CD20000000000000000000000000000000000003
-:10CD300000000000000000000000000000000000F3
-:10CD400000000000000000000000000000000000E3
-:10CD500000000000000000000000000000000000D3
-:10CD600000000000000000000000000000000000C3
-:10CD700000000000000000000000000000000000B3
-:10CD800000000000000000000000000000000000A3
-:10CD90000000000000000000000000000000000093
-:10CDA0000000000000000000000000000000000083
-:10CDB0000000000000000000000000000000000073
-:10CDC0000000000000000000000000000000000063
-:10CDD0000000000000000000000000000000000053
-:10CDE0000000000000000000000000000000000043
-:10CDF0000000000000000000000000000000000033
-:10CE00000000000000000000000000000000000022
-:10CE10000000000000000000000000000000000012
-:10CE20000000000000000000000000000000000002
-:10CE300000000000000000000000000000000000F2
-:10CE400000000000000000000000000000000000E2
-:10CE500000000000000000000000000000000000D2
-:10CE600000000000000000000000000000000000C2
-:10CE700000000000000000000000000000000000B2
-:10CE800000000000000000000000000000000000A2
-:10CE90000000000000000000000000000000000092
-:10CEA0000000000000000000000000000000000082
-:10CEB0000000000000000000000000000000000072
-:10CEC0000000000000000000000000000000000062
-:10CED0000000000000000000000000000000000052
-:10CEE0000000000000000000000000000000000042
-:10CEF0000000000000000000000000000000000032
-:10CF00000000000000000000000000000000000021
-:10CF10000000000000000000000000000000000011
-:10CF20000000000000000000000000000000000001
-:10CF300000000000000000000000000000000000F1
-:10CF400000000000000000000000000000000000E1
-:10CF500000000000000000000000000000000000D1
-:10CF600000000000000000000000000000000000C1
-:10CF700000000000000000000000000000000000B1
-:10CF800000000000000000000000000000000000A1
-:10CF90000000000000000000000000000000000091
-:10CFA0000000000000000000000000000000000081
-:10CFB0000000000000000000000000000000000071
-:10CFC0000000000000000000000000000000000061
-:10CFD0000000000000000000000000000000000051
-:10CFE0000000000000000000000000000000000041
-:10CFF0000000000000000000000000000000000031
-:10D000000000000000000000000000000000000020
-:10D010000000000000000000000000000000000010
-:10D020000000000000000000000000000000000000
-:10D0300000000000000000000000000000000000F0
-:10D0400000000000000000000000000000000000E0
-:10D0500000000000000000000000000000000000D0
-:10D0600000000000000000000000000000000000C0
-:10D0700000000000000000000000000000000000B0
-:10D0800000000000000000000000000000000000A0
-:10D090000000000000000000000000000000000090
-:10D0A0000000000000000000000000000000000080
-:10D0B0000000000000000000000000000000000070
-:10D0C0000000000000000000000000000000000060
-:10D0D0000000000000000000000000000000000050
-:10D0E0000000000000000000000000000000000040
-:10D0F0000000000000000000000000000000000030
-:10D10000000000000000000000000000000000001F
-:10D11000000000000000000000000000000000000F
-:10D1200000000000000000000000000000000000FF
-:10D1300000000000000000000000000000000000EF
-:10D1400000000000000000000000000000000000DF
-:10D1500000000000000000000000000000000000CF
-:10D1600000000000000000000000000000000000BF
-:10D1700000000000000000000000000000000000AF
-:10D18000000000000000000000000000000000009F
-:10D19000000000000000000000000000000000008F
-:10D1A000000000000000000000000000000000007F
-:10D1B000000000000000000000000000000000006F
-:10D1C000000000000000000000000000000000005F
-:10D1D000000000000000000000000000000000004F
-:10D1E000000000000000000000000000000000003F
-:10D1F000000000000000000000000000000000002F
-:10D20000000000000000000000000000000000001E
-:10D21000000000000000000000000000000000000E
-:10D2200000000000000000000000000000000000FE
-:10D2300000000000000000000000000000000000EE
-:10D2400000000000000000000000000000000000DE
-:10D2500000000000000000000000000000000000CE
-:10D2600000000000000000000000000000000000BE
-:10D2700000000000000000000000000000000000AE
-:10D28000000000000000000000000000000000009E
-:10D29000000000000000000000000000000000008E
-:10D2A000000000000000000000000000000000007E
-:10D2B000000000000000000000000000000000006E
-:10D2C000000000000000000000000000000000005E
-:10D2D000000000000000000000000000000000004E
-:10D2E000000000000000000000000000000000003E
-:10D2F000000000000000000000000000000000002E
-:10D30000000000000000000000000000000000001D
-:10D31000000000000000000000000000000000000D
-:10D3200000000000000000000000000000000000FD
-:10D3300000000000000000000000000000000000ED
-:10D3400000000000000000000000000000000000DD
-:10D3500000000000000000000000000000000000CD
-:10D3600000000000000000000000000000000000BD
-:10D3700000000000000000000000000000000000AD
-:10D38000000000000000000000000000000000009D
-:10D39000000000000000000000000000000000008D
-:10D3A000000000000000000000000000000000007D
-:10D3B000000000000000000000000000000000006D
-:10D3C000000000000000000000000000000000005D
-:10D3D000000000000000000000000000000000004D
-:10D3E000000000000000000000000000000000003D
-:10D3F000000000000000000000000000000000002D
-:10D40000000000000000000000000000000000001C
-:10D41000000000000000000000000000000000000C
-:10D4200000000000000000000000000000000000FC
-:10D4300000000000000000000000000000000000EC
-:10D4400000000000000000000000000000000000DC
-:10D4500000000000000000000000000000000000CC
-:10D4600000000000000000000000000000000000BC
-:10D4700000000000000000000000000000000000AC
-:10D48000000000000000000000000000000000009C
-:10D49000000000000000000000000000000000008C
-:10D4A000000000000000000000000000000000007C
-:10D4B000000000000000000000000000000000006C
-:10D4C000000000000000000000000000000000005C
-:10D4D000000000000000000000000000000000004C
-:10D4E000000000000000000000000000000000003C
-:10D4F000000000000000000000000000000000002C
-:10D50000000000000000000000000000000000001B
-:10D51000000000000000000000000000000000000B
-:10D5200000000000000000000000000000000000FB
-:10D5300000000000000000000000000000000000EB
-:10D5400000000000000000000000000000000000DB
-:10D5500000000000000000000000000000000000CB
-:10D5600000000000000000000000000000000000BB
-:10D5700000000000000000000000000000000000AB
-:10D58000000000000000000000000000000000009B
-:10D59000000000000000008000000000000000000B
-:10D5A000000000000000000000000000000000007B
-:10D5B00000000000000000000000000A0000000061
-:10D5C0000000000000000000100000030000000048
-:10D5D0000000000D0000000D3C02080024427320F2
-:10D5E0003C030800246377ACAC4000000043202BD0
-:10D5F0001480FFFD244200043C1D080037BD7FFC61
-:10D6000003A0F0213C100800261032103C1C08003A
-:10D61000279C73200E0010FE000000000000000D8B
-:10D6200030A5FFFF30C600FF274301808F4201B8BD
-:10D630000440FFFE24020002AC640000A465000860
-:10D64000A066000AA062000B3C021000AC67001844
-:10D6500003E00008AF4201B83C0360008C624FF861
-:10D660000440FFFE3C020200AC644FC0AC624FC4F9
-:10D670003C02100003E00008AC624FF89482000CFA
-:10D680002486001400A0382100021302000210803A
-:10D690000082402100C8102B1040005700000000FD
-:10D6A00090C300002C6200095040005190C200015C
-:10D6B000000310803C030800246372D00043102153
-:10D6C0008C420000004000080000000090C30001F0
-:10D6D0002402000A1462003A000000000106102330
-:10D6E0002C42000A1440003624C600028CE20000DE
-:10D6F00034420100ACE2000090C2000090C300017F
-:10D7000090C4000290C5000300031C000002160034
-:10D710000043102500042200004410250045102578
-:10D7200024C60004ACE2000490C2000090C30001D3
-:10D7300090C4000290C500030002160000031C0004
-:10D740000043102500042200004410250045102548
-:10D7500024C600040A000CB8ACE2000890C3000123
-:10D76000240200041462001624C6000290C20000C5
-:10D7700090C400018CE30000000212000044102558
-:10D780003463000424C60002ACE2000C0A000CB8AA
-:10D79000ACE3000090C300012402000314620008FF
-:10D7A00024C600028CE2000090C3000024C60001E1
-:10D7B00034420008A0E300100A000CB8ACE20000FC
-:10D7C00003E000082402000190C3000124020002CB
-:10D7D0001062000224C40002010020210A000CB8DB
-:10D7E000008030210A000CB824C6000190C200015C
-:10D7F0000A000CB800C2302103E00008000010212C
-:10D8000027BDFFE8AFBF0014AFB000100E00130239
-:10D8100000808021936200052403FFFE0200202186
-:10D82000004310248FBF00148FB00010A3620005C6
-:10D830000A00130B27BD001827BDFFE8AFB000108A
-:10D84000AFBF00140E000F3C0080802193620000E7
-:10D8500024030050304200FF14430004240201005E
-:10D86000AF4201800A000D3002002021AF4001804C
-:10D87000020020218FBF00148FB000100A000FE7B4
-:10D8800027BD001827BDFF80AFBE0078AFB700747A
-:10D89000AFB20060AFBF007CAFB60070AFB5006C38
-:10D8A000AFB40068AFB30064AFB1005CAFB0005874
-:10D8B0008F5001283C0208008C4231A02403FF80D5
-:10D8C0009365003F0202102100431024AF42002460
-:10D8D0003C0208008C4231A09364000530B200FF86
-:10D8E000020210213042007F034218210004202749
-:10D8F0003C02000A0062182130840001AF8300144A
-:10D900000000F0210000B82114800053AFA00050A7
-:10D9100093430116934401128F450104306300FFC5
-:10D920003C020001308400FF00A2282403431021A0
-:10D9300003441821245640002467400014A001CD60
-:10D940002402000193620000304300FF2402002003
-:10D950001062000524020050106200060000000062
-:10D960000A000D74000000000000000D0A000D7D8B
-:10D97000AFA000303C1E080027DE736C0A000D7D4E
-:10D98000AFA000303C0208008C4200DC24420001C1
-:10D990003C010800AC2200DC0E00139F00000000D8
-:10D9A0000A000F318FBF007C8F4201043C0300202E
-:10D9B00092D3000D004310240002202B00042140CC
-:10D9C000AFA400308F4301043C02004000621824E1
-:10D9D000146000023485004000802821326200205B
-:10D9E000AFA500301440000234A6008000A0302112
-:10D9F00010C0000BAFA6003093C500088F67004C25
-:10DA00000200202100052B0034A5008130A5F08103
-:10DA10000E000C9B30C600FF0A000F2E0000000015
-:10DA20009362003E304200401040000F2402000488
-:10DA300056420007240200120200202100E02821A3
-:10DA40000E0013F702C030210A000F318FBF007C97
-:10DA500016420005000000000E000D2100002021EC
-:10DA60000A000F318FBF007C9743011A96C4000E45
-:10DA700093620035326500043075FFFF00442004D6
-:10DA8000AFA400548ED1000410A000158ED400085D
-:10DA90009362003E3042004010400007000000004A
-:10DAA0000E0013E0022020211040000D00000000B5
-:10DAB0000A000F2E000000008F6200440222102393
-:10DAC0000440016A000000008F6200480222102317
-:10DAD00004410166240400160A000E218FC20004CE
-:10DAE0008F6200480222102304400008000000005A
-:10DAF0003C0208008C423100244200013C01080035
-:10DB0000AC2231000A000F23000000008F620040A9
-:10DB100002221023184000128F8400143C020800D7
-:10DB20008C423100327300FC0000A8212442000125
-:10DB30003C010800AC2231008F6300409482011C3C
-:10DB4000022318233042FFFF0043102A50400010E8
-:10DB50002402000C8F6200400A000DF20222102302
-:10DB60009483011C9762003C0043102B1040000678
-:10DB7000000000009482011C00551023A482011CA7
-:10DB80000A000DF72402000CA480011C2402000CE2
-:10DB9000AFA200308F620040005120231880000D9A
-:10DBA00002A4102A1440012600000000149500066B
-:10DBB00002A410233A620001304200011440012007
-:10DBC0000000000002A41023022488210A000E098C
-:10DBD0003055FFFF00002021326200021040001A81
-:10DBE000326200109362003E30420040504000110B
-:10DBF0008FC200040E00130202002021240200182C
-:10DC0000A362003F936200052403FFFE020020216F
-:10DC1000004310240E00130BA362000524040039F6
-:10DC2000000028210E0013C9240600180A000F3036
-:10DC300024020001240400170040F809000000003D
-:10DC40000A000F302402000110400108000000000B
-:10DC50008F63004C8F620054028210231C4001032A
-:10DC600002831023044200010060A021AFA4001829
-:10DC7000AFB10010AFB50014934201208F65004092
-:10DC80009763003C304200FF034210210044102102
-:10DC90008FA400543063FFFF244240000083182B00
-:10DCA0008FA40030AFA20020AFA50028008320255C
-:10DCB000AFA40030AFA50024AFA0002CAFB4003457
-:10DCC0009362003E30420008504000118FC20000B5
-:10DCD00002C0202127A500380E000CB2AFA00038EA
-:10DCE0005440000B8FC200008FA200383042010068
-:10DCF000504000078FC200008FA3003C8F6200607D
-:10DD00000062102304430001AF6300608FC2000073
-:10DD10000040F80927A400108FA200303042000212
-:10DD200054400001327300FE9362003E30420040D6
-:10DD3000104000378FA200248F6200541682001A10
-:10DD40003262000124020014124200102A4200151F
-:10DD500010400006240200162402000C12420007A4
-:10DD6000326200010A000E7D000000001242000530
-:10DD7000326200010A000E7D000000000A000E78E9
-:10DD80002417000E0A000E78241700100A000E7CDB
-:10DD900024170012936200232403FFBD00431024C4
-:10DDA000A362002332620001104000198FA20024F8
-:10DDB0002402000C1242000E2A42000D1040000600
-:10DDC0002402000E2402000A124200078FA200243F
-:10DDD0000A000E9524420001124200088FA200247E
-:10DDE0000A000E95244200010A000E932417000831
-:10DDF0002402000E16E20002241700162417001059
-:10DE00008FA2002424420001AFA200248FA200248C
-:10DE10008FA300148F76004000431021AF620040B2
-:10DE20008F8200149442011C104000090000000081
-:10DE30008F6200488F6400409763003C00441023C9
-:10DE40003063FFFF0043102A104000088FA20054E7
-:10DE5000936400368F6300403402FFFC008210049C
-:10DE600000621821AF6300488FA200548FA60030D3
-:10DE70000282902130C200081040000E0000000015
-:10DE80008F6200581642000430C600FF9742011A04
-:10DE90005040000134C6001093C500088FA700341D
-:10DEA0000200202100052B0034A500800E000C9BF1
-:10DEB00030A5F0808F620040005610231840001BF0
-:10DEC0008FA200183C0208008C42319830420010AA
-:10DED0001040000D24020001976200681440000AFF
-:10DEE000240200018F8200149442011C1440000699
-:10DEF00024020001A76200689742007A244200646D
-:10DF00000A000EE9A7620012A76200120E001302B7
-:10DF1000020020219362007D2403000102002021E1
-:10DF2000344200010A000EE7AFA300501840000A77
-:10DF3000000000000E001302020020219362007D09
-:10DF40002403000102002021AFA30050344200044A
-:10DF50000E00130BA362007D9362003E304200402E
-:10DF60001440000C326200011040000A0000000062
-:10DF70008F6300408FC20004240400182463000152
-:10DF80000040F809AF6300408FA200300A000F3054
-:10DF9000304200048F620058105200100000000050
-:10DFA0008F620018022210231C4000082404000184
-:10DFB0008F62001816220009000000008F62001C0A
-:10DFC000028210230440000500000000AF720058D8
-:10DFD000AFA40050AF710018AF74001C12E0000B2A
-:10DFE0008FA200500E00130202002021A377003FF1
-:10DFF0000E00130B0200202102E030212404003720
-:10E000000E0013C9000028218FA200501040000309
-:10E01000000000000E000CA90200202112A0000543
-:10E02000000018218FA2003030420004504000113F
-:10E0300000601021240300010A000F30006010214D
-:10E040000E001302020020219362007D02002021B5
-:10E05000344200040E00130BA362007D0E000CA9D5
-:10E06000020020210A000F3024020001AF400044CA
-:10E07000240200018FBF007C8FBE00788FB7007430
-:10E080008FB600708FB5006C8FB400688FB30064DA
-:10E090008FB200608FB1005C8FB0005803E00008C1
-:10E0A00027BD00808F4201B80440FFFE2402080013
-:10E0B000AF4201B803E00008000000003C02000885
-:10E0C00003421021944200483084FFFF2484001250
-:10E0D0003045FFFF10A0001700A4102B10400016C1
-:10E0E00024020003934201202403001AA343018B5E
-:10E0F000304200FF2446FFFE8F82000000A6182B4E
-:10E100003863000100021382004310241040000510
-:10E110008F84000434820001A746019403E00008C4
-:10E12000AF8200042402FFFE0082102403E00008F6
-:10E13000AF8200042402000303E00008A342018B25
-:10E1400027BDFFE0AFB10014AFB00010AFBF0018A3
-:10E1500030B0FFFF30D1FFFF8F4201B80440FFFE17
-:10E1600000000000AF440180AF4400200E000F42C9
-:10E17000020020218F8300008F840004A750019AA1
-:10E18000A750018EA74301908F8300083082800042
-:10E19000AF4301A8A75101881040000E8F820004F0
-:10E1A00093420116304200FC24420004005A102120
-:10E1B0008C4240003042FFFF144000068F82000472
-:10E1C0003C02FFFF34427FFF00821024AF82000434
-:10E1D0008F8200042403BFFF00431024A74201A63E
-:10E1E0009743010C8F42010400031C003042FFFFE3
-:10E1F00000621825AF4301AC3C021000AF4201B8E9
-:10E200008FBF00188FB100148FB0001003E000081A
-:10E2100027BD00208F470070934201128F830000BA
-:10E2200027BDFFF0304200FF00022882306201006B
-:10E23000000030211040004324A40003306240005D
-:10E24000104000103062200000041080005A10219D
-:10E250008C43400024A4000400041080AFA30000FD
-:10E26000005A10218C424000AFA2000493420116D4
-:10E27000304200FC005A10218C4240000A000FC0BE
-:10E28000AFA200081040002F0000302100041080D1
-:10E29000005A10218C43400024A400040004108084
-:10E2A000AFA30000005A10218C424000AFA000082C
-:10E2B000AFA200048FA80008000030210000202138
-:10E2C000240A00083C0908002529010003A41021A4
-:10E2D000148A000300042A001100000A0000000054
-:10E2E00090420000248400012C83000C00A2102125
-:10E2F00000021080004910218C4200001460FFF3DE
-:10E3000000C230263C0408008C8431048F42007027
-:10E310002C83002010600009004738233C030800CC
-:10E32000246331080004108000431021248300017D
-:10E33000AC4700003C010800AC233104AF86000864
-:10E340002406000100C0102103E0000827BD0010D2
-:10E350003C0208008C42003827BDFFD0AFB5002436
-:10E36000AFB40020AFB10014AFBF0028AFB3001CA2
-:10E37000AFB20018AFB00010000088213C150800B3
-:10E3800026B50038144000022454FFFF0000A021ED
-:10E390009742010E8F8400003042FFFF308340001F
-:10E3A0001060000A245200043C0200200082102465
-:10E3B00050400007308280008F8200042403BFFF9A
-:10E3C000008318240A0010103442100030828000AC
-:10E3D0001040000A3C020020008210241040000778
-:10E3E0008F8200043C03FFFF34637FFF0083182407
-:10E3F00034428000AF820004AF8300000E000F980B
-:10E400000000000014400007000000009743011EB8
-:10E410009742011C3063FFFF0002140000621825C0
-:10E42000AF8300089742010C8F4340003045FFFF47
-:10E430003402FFFF14620003000000000A001028ED
-:10E44000241100208F42400030420100544000015E
-:10E45000241100108F8400003082100050400014FE
-:10E4600036310001308200201440000B3C021000C5
-:10E47000008210245040000E363100013C030E0093
-:10E480003C020DFF008318243442FFFF0043102B91
-:10E4900050400007363100013C0208008C42002C3D
-:10E4A000244200013C010800AC22002C363100055A
-:10E4B0003C0608008CC6003454C000238F85000041
-:10E4C0008F820004304240005440001F8F850000BE
-:10E4D0003C021F01008210243C0310005443001A28
-:10E4E0008F85000030A20200144000178F850000C5
-:10E4F0003250FFFF363100028F4201B80440FFFE68
-:10E5000000000000AF400180020020210E000F42F9
-:10E51000AF4000208F8300042402BFFFA750019A60
-:10E52000006218248F820000A750018EA751018835
-:10E53000A74301A6A74201903C021000AF4201B8D8
-:10E540000A0010F5000010213C02100000A2102467
-:10E550001040003A0000000010C0000F0000000052
-:10E5600030A201001040000C3C0302003C020F00EE
-:10E5700000A2102410430008000000008F82000851
-:10E58000005410240055102190420004244200043D
-:10E590000A00109F000221C00000000000051602C2
-:10E5A0003050000F3A0300022E4203EF38420001C0
-:10E5B0002C6300010062182414600073240200011F
-:10E5C0003C0308008C6300D02E06000C386200016A
-:10E5D0002C4200010046102414400015001021C0F8
-:10E5E0002602FFFC2C4200045440001100002021B0
-:10E5F000386200022C420001004610241040000343
-:10E60000000512420A00109F000020210010182B64
-:10E610000043102450400006001021C000002021BB
-:10E620003245FFFF0E000F633226FFFB001021C0B2
-:10E630003245FFFF0A0010F2362600028F424000EA
-:10E640003C0308008C630024304201001040004667
-:10E6500030620001322200043070000D14400002CC
-:10E660002413000424130002000512C238420001E2
-:10E670002E4303EF304200013863000100431025B0
-:10E68000104000033231FFFB2402FFFB0202802412
-:10E6900010C000183202000130A201001040001525
-:10E6A000320200013C020F0000A210243C030200D1
-:10E6B0001043000F8F8200082403FFFE0203802412
-:10E6C00000541024005510219042000402333025DC
-:10E6D0002442000412000002000221C03226FFFF83
-:10E6E0000E000F633245FFFF1200002700001021CB
-:10E6F000320200011040000D320200042402000129
-:10E7000012020002023330253226FFFF00002021D2
-:10E710000E000F633245FFFF2402FFFE0202802439
-:10E7200012000019000010213202000410400016EF
-:10E7300024020001240200041202000202333025E8
-:10E740003226FFFF3245FFFF0E000F632404010055
-:10E750002402FFFB020280241200000B00001021A3
-:10E760000A0010F5240200011040000700001021EB
-:10E770003245FFFF36260002000020210E000F6305
-:10E7800000000000000010218FBF00288FB500247A
-:10E790008FB400208FB3001C8FB200188FB100140B
-:10E7A0008FB0001003E0000827BD003027BDFFD068
-:10E7B000AFB000103C04600CAFBF002CAFB6002817
-:10E7C000AFB50024AFB40020AFB3001CAFB2001847
-:10E7D000AFB100148C8250002403FF7F3C1A8000EC
-:10E7E000004310243442380CAC8250002402000351
-:10E7F0003C106000AF4200088E0208083C1B8008F5
-:10E800003C010800AC2000203042FFF038420010EC
-:10E810002C4200010E001B85AF8200183C04FFFF54
-:10E820003C020400348308063442000CAE0219484E
-:10E83000AE03194C3C0560168E0219808CA30000B3
-:10E840003442020000641824AE0219803C02535383
-:10E850001462000334A47C008CA200040050202128
-:10E860008C82007C8C830078AF820010AF83000C18
-:10E870008F55000032A200031040FFFD32A20001BC
-:10E880001040013D32A200028F420128AF42002019
-:10E890008F4201048F430100AF8200000E000F3C45
-:10E8A000AF8300043C0208008C4200C01040000806
-:10E8B0008F8400003C0208008C4200C42442000106
-:10E8C0003C010800AC2200C40A00126900000000EC
-:10E8D0003C020010008210241440010C8F830004BD
-:10E8E0003C0208008C4200203C0308008C63003886
-:10E8F00000008821244200013C010800AC220020D5
-:10E900003C16080026D60038146000022474FFFF6D
-:10E910000000A0219742010E308340003042FFFFEB
-:10E920001060000A245200043C02002000821024DF
-:10E9300050400007308280008F8200042403BFFF14
-:10E94000008318240A0011703442100030828000C5
-:10E950001040000A3C0200200082102410400007F2
-:10E960008F8200043C03FFFF34637FFF0083182481
-:10E9700034428000AF820004AF8300000E000F9885
-:10E980000000000014400007000000009743011E33
-:10E990009742011C3063FFFF00021400006218253B
-:10E9A000AF8300089742010C8F4340003045FFFFC2
-:10E9B0003402FFFF14620003000000000A00118807
-:10E9C000241100208F4240003042010054400001D9
-:10E9D000241100108F840000308210005040001479
-:10E9E00036310001308200201440000B3C02100040
-:10E9F000008210245040000E363100013C030E000E
-:10EA00003C020DFF008318243442FFFF0043102B0B
-:10EA100050400007363100013C0208008C42002CB7
-:10EA2000244200013C010800AC22002C36310005D4
-:10EA30003C0608008CC6003454C000238F850000BB
-:10EA40008F820004304240005440001F8F85000038
-:10EA50003C021F01008210243C0310005443001AA2
-:10EA60008F85000030A20200144000178F8500003F
-:10EA70003250FFFF363100028F4201B80440FFFEE2
-:10EA800000000000AF400180020020210E000F4274
-:10EA9000AF4000208F8300042402BFFFA750019ADB
-:10EAA000006218248F820000A750018EA7510188B0
-:10EAB000A74301A6A74201903C021000AF4201B853
-:10EAC0000A001267000010213C02100000A210246E
-:10EAD0001040003A0000000010C0000F00000000CD
-:10EAE00030A201001040000C3C0302003C020F0069
-:10EAF00000A2102410430008000000008F820008CC
-:10EB000000541024005610219042000424420004B6
-:10EB10000A0011FF000221C00000000000051602DB
-:10EB20003050000F3A0300022E4203EF384200013A
-:10EB30002C63000100621824146000852402000187
-:10EB40003C0308008C6300D02E06000C38620001E4
-:10EB50002C4200010046102414400015001021C072
-:10EB60002602FFFC2C42000454400011000020212A
-:10EB7000386200022C42000100461024504000037D
-:10EB8000000512420A0011FF000020210010182B7E
-:10EB90000043102450400006001021C00000202136
-:10EBA0003245FFFF0E000F633226FFFB001021C02D
-:10EBB0003245FFFF0A001252362600028F42400003
-:10EBC0003C0308008C6300243042010010400046E2
-:10EBD00030620001322200043070000D1440000247
-:10EBE0002413000424130002000512C2384200015D
-:10EBF0002E4303EF3042000138630001004310252B
-:10EC0000104000033231FFFB2402FFFB020280248C
-:10EC100010C000183202000130A20100104000159F
-:10EC2000320200013C020F0000A210243C0302004B
-:10EC30001043000F8F8200082403FFFE020380248C
-:10EC40000054102400561021904200040233302555
-:10EC50002442000412000002000221C03226FFFFFD
-:10EC60000E000F633245FFFF120000390000102133
-:10EC7000320200011040000D3202000424020001A3
-:10EC800012020002023330253226FFFF000020214D
-:10EC90000E000F633245FFFF2402FFFE02028024B4
-:10ECA0001200002B00001021320200041040002846
-:10ECB0002402000124020004120200020233302563
-:10ECC0003226FFFF3245FFFF0E000F6324040100D0
-:10ECD0002402FFFB020280241200001D000010210C
-:10ECE0000A001267240200015040001900001021A0
-:10ECF0003245FFFF36260002000020210E000F6380
-:10ED0000000000000A001267000010212402BFFF6B
-:10ED1000006210241040000800000000240287FF59
-:10ED200000621024144000083C020060008210249D
-:10ED300010400005000000000E000D34000000002F
-:10ED40000A001267000000000E0012C70000000059
-:10ED5000104000063C0240008F4301243C0260202A
-:10ED6000AC430014000000003C024000AF420138F8
-:10ED70000000000032A200021040FEBD00000000B2
-:10ED80008F4201403C044000AF4200208F430148C5
-:10ED90003C02700000621824106400420000000071
-:10EDA0000083102B144000063C0260003C0220004F
-:10EDB000106200073C0240000A0012C3000000007D
-:10EDC0001062003C3C0240000A0012C30000000038
-:10EDD0008F4501408F4601448F42014800021402D2
-:10EDE000304300FF240200041462000A274401801B
-:10EDF0008F4201B80440FFFE2402001CAC850000D5
-:10EE0000A082000B3C021000AF4201B80A0012C3FE
-:10EE10003C0240002402000914620012000616029F
-:10EE2000000229C0AF4500208F4201B80440FFFE18
-:10EE30002402000124030003AF450180A343018B9A
-:10EE4000A740018EA740019AA7400190AF4001A8BA
-:10EE5000A7420188A74201A6AF4001AC3C021000C6
-:10EE6000AF4201B88F4201B80440FFFE000000002D
-:10EE7000AC8500008F42014800021402A482000801
-:10EE800024020002A082000B8F420148A4820010DD
-:10EE90003C021000AC860024AF4201B80A0012C345
-:10EEA0003C0240000E001310000000000A0012C3D4
-:10EEB0003C0240000E001BBA000000003C02400073
-:10EEC000AF420178000000000A00112F000000008E
-:10EED0008F4201003042003E144000112402000124
-:10EEE000AF4000488F420100304207C0104000058B
-:10EEF00000000000AF40004CAF40005003E00008AD
-:10EF000024020001AF400054AF4000408F42010096
-:10EF10003042380054400001AF4000442402000158
-:10EF200003E00008000000008F4201B80440FFFE2B
-:10EF300024020001AF440180AF400184A74501884D
-:10EF4000A342018A24020002A342018B9742014A94
-:10EF500014C00004A7420190AF4001A40A0012EFC0
-:10EF60003C0210008F420144AF4201A43C02100059
-:10EF7000AF4001A803E00008AF4201B88F4201B8DA
-:10EF80000440FFFE24020002AF440180AF4401842C
-:10EF9000A7450188A342018AA342018B9742014AF7
-:10EFA000A7420190AF4001A48F420144AF4201A8A3
-:10EFB0003C02100003E00008AF4201B83C029000A0
-:10EFC0003442000100822025AF4400208F420020FF
-:10EFD0000440FFFE0000000003E000080000000005
-:10EFE0003C028000344200010082202503E000083A
-:10EFF000AF44002027BDFFE8AFBF0014AFB0001042
-:10F000008F50014093430149934201489344014882
-:10F01000306300FF304200FF00021200006228252A
-:10F020002402001910620076308400802862001AE1
-:10F030001040001C24020020240200081062007707
-:10F04000286200091040000E2402000B2402000177
-:10F0500010620034286200025040000524020006BD
-:10F0600050600034020020210A00139A00000000C2
-:10F0700010620030020020210A00139A00000000F4
-:10F080001062003B2862000C504000022402000E77
-:10F090002402000910620056020020210A00139A7F
-:10F0A0000000000010620056286200211040000F8E
-:10F0B000240200382402001C106200582862001D3F
-:10F0C000104000062402001F2402001B1062004CA6
-:10F0D000000000000A00139A000000001062004ABD
-:10F0E000020020210A00139A00000000106200456F
-:10F0F0002862003910400007240200802462FFCB00
-:10F100002C42000210400045020020210A00139604
-:10F110000000302110620009000000000A00139A6C
-:10F12000000000001480003D020020210A0013901E
-:10F130008FBF00140A001396240600018F4201B805
-:10F140000440FFFE24020002A342018BA745018870
-:10F150009742014AA74201908F420144A74201927F
-:10F160003C021000AF4201B80A00139C8FBF00148C
-:10F170009742014A144000290000000093620005F4
-:10F180003042000414400025000000000E0013026D
-:10F190000200202193620005020020213442000475
-:10F1A0000E00130BA36200059362000530420004B9
-:10F1B00014400002000000000000000D93620000F7
-:10F1C00024030020304200FF14430014000000001C
-:10F1D0008F4201B80440FFFE24020005AF500180B9
-:10F1E000A342018B3C0210000A00139AAF4201B8FF
-:10F1F0008FBF00148FB000100A0012F227BD001854
-:10F200000000000D02002021000030218FBF0014FB
-:10F210008FB000100A0012DD27BD00180000000D9D
-:10F220008FBF00148FB0001003E0000827BD001846
-:10F2300027BDFFE8AFBF00100E000F3C000000002C
-:10F24000AF4001808FBF0010000020210A000FE7AF
-:10F2500027BD00183084FFFF30A5FFFF00001821F4
-:10F260001080000700000000308200011040000202
-:10F2700000042042006518210A0013AB0005284055
-:10F2800003E000080060102110C0000624C6FFFF44
-:10F290008CA2000024A50004AC8200000A0013B573
-:10F2A0002484000403E000080000000010A000080F
-:10F2B00024A3FFFFAC860000000000000000000057
-:10F2C0002402FFFF2463FFFF1462FFFA248400047A
-:10F2D00003E0000800000000308300FF30A500FFBD
-:10F2E00030C600FF274701808F4201B80440FFFE6F
-:10F2F000000000008F42012834634000ACE20000AF
-:10F3000024020001ACE00004A4E30008A0E2000A2B
-:10F3100024020002A0E2000B3C021000A4E5001051
-:10F32000ACE00024ACE00028A4E6001203E00008F2
-:10F33000AF4201B827BDFFE8AFBF00109362003FA6
-:10F3400024030012304200FF1043000D00803021E2
-:10F350008F620044008210230440000A8FBF001017
-:10F360008F620048240400390000282100C21023C5
-:10F3700004410004240600120E0013C9000000001E
-:10F380008FBF00102402000103E0000827BD001811
-:10F3900027BDFFC8AFB20030AFB1002CAFBF003403
-:10F3A000AFB0002890C5000D0080902130A400105F
-:10F3B0001080000B00C088218CC300088F620054AD
-:10F3C0001062000730A20005144000B524040001BB
-:10F3D0000E000D21000020210A0014BB0040202156
-:10F3E00030A200051040000930A30012108000ACCC
-:10F3F000240400018E2300088F620054146200A9C7
-:10F400008FBF00340A00142C240400382402001298
-:10F41000146200A3240400010220202127A500106B
-:10F420000E000CB2AFA000101040001102402021CD
-:10F430008E220008AF620084AF6000400E0013020D
-:10F44000000000009362007D024020213442002031
-:10F450000E00130BA362007D0E000CA902402021B8
-:10F46000240400382405008D0A0014B82406001274
-:10F470009362003E304200081040000F8FA200103F
-:10F4800030420100104000078FA300148F6200601B
-:10F490000062102304430008AF6300600A001441B7
-:10F4A00000000000AF6000609362003E2403FFF79D
-:10F4B00000431024A362003E9362003E30420008E5
-:10F4C000144000022406000300003021936200343F
-:10F4D000936300378F640084304200FF306300FF85
-:10F4E00000661821000318800043282100A4202B67
-:10F4F0001080000B000000009763003C8F620084C6
-:10F500003063FFFF004510230062182B14600004D5
-:10F51000000000008F6200840A00145D0045802313
-:10F520009762003C3050FFFF8FA300103062000450
-:10F5300010400004000628808FA2001C0A001465F9
-:10F540000202102B2E02021850400003240202185F
-:10F550000A00146E020510233063000410600003DB
-:10F56000004510238FA2001C00451023004080217D
-:10F570002C42008054400001241000800E00130231
-:10F580000240202124020001AF62000C9362003E81
-:10F59000001020403042007FA362003E8E22000413
-:10F5A00024420001AF620040A770003C8F6200500F
-:10F5B0009623000E00431021AF6200588F62005066
-:10F5C00000441021AF62005C8E220004AF6200187C
-:10F5D0008E220008AF62001C8FA20010304200088B
-:10F5E0005440000A93A20020A360003693620036C4
-:10F5F0002403FFDFA36200359362003E0043102422
-:10F60000A362003E0A0014988E220008A36200350F
-:10F610008E220008AF62004C8F6200248F6300408E
-:10F6200000431021AF6200489362000024030050A1
-:10F63000304200FF144300122403FF803C02080004
-:10F640008C4231A00242102100431024AF42002816
-:10F650003C0208008C4231A08E2400083C03000CC0
-:10F66000024210213042007F03421021004310214A
-:10F67000AC4400D88E230008AF820014AC4300DCF9
-:10F680000E00130B02402021240400380000282122
-:10F690002406000A0E0013C9000000002404000123
-:10F6A0008FBF00348FB200308FB1002C8FB0002894
-:10F6B0000080102103E0000827BD003827BDFFF8B7
-:10F6C00027420180AFA20000308A00FF8F4201B8BC
-:10F6D0000440FFFE000000008F4601283C020800A5
-:10F6E0008C4231A02403FF80AF86004800C2102165
-:10F6F00000431024AF4200243C0208008C4231A099
-:10F700008FA900008FA8000000C210213042007FA6
-:10F71000034218213C02000A00621821946400D4BC
-:10F720008FA700008FA5000024020002AF83001401
-:10F73000A0A2000B8FA30000354260003084FFFFC1
-:10F74000A4E200083C021000AD260000AD04000455
-:10F75000AC60002427BD0008AF4201B803E00008F8
-:10F76000240200018F88003C938200288F830014BC
-:10F770003C07080024E7777800481023304200FF58
-:10F78000304900FC246500888F860040304A000321
-:10F790001120000900002021248200048CA3000015
-:10F7A000304400FF0089102AACE3000024A50004C7
-:10F7B0001440FFF924E70004114000090000202153
-:10F7C0002482000190A30000304400FF008A102B27
-:10F7D000A0E3000024A500011440FFF924E7000184
-:10F7E00030C20003144000048F85003C3102000346
-:10F7F0001040000D0000000010A0000900002021B2
-:10F800002482000190C30000304400FF0085102BCB
-:10F81000A0E3000024C600011440FFF924E7000122
-:10F8200003E00008000000001100FFFD000020219F
-:10F83000248200048CC30000304400FF0088102B99
-:10F84000ACE3000024C600041440FFF924E70004E0
-:10F8500003E00008000000008F83003C9382002832
-:10F8600030C600FF30A500FF00431023304300FFE7
-:10F870008F820014008038210043102114C0000240
-:10F88000244800880083382130E20003144000053A
-:10F8900030A2000314400003306200031040000D4A
-:10F8A0000000000010A000090000202124820001B7
-:10F8B00090E30000304400FF0085102BA1030000FE
-:10F8C00024E700011440FFF92508000103E00008C7
-:10F8D0000000000010A0FFFD000020212482000491
-:10F8E0008CE30000304400FF0085102BAD030000C6
-:10F8F00024E700041440FFF92508000403E0000891
-:10F90000000000000080482130AAFFFF30C600FF41
-:10F9100030E7FFFF274801808F4201B80440FFFE17
-:10F920008F820048AD0200008F420124AD02000426
-:10F930008D220020A5070008A102000A240200165B
-:10F94000A102000B934301208D2200088D240004A6
-:10F95000306300FF004310219783003A00441021D8
-:10F960008D250024004310233C0308008C6331A044
-:10F970008F840014A502000C246300E82402FFFF1A
-:10F98000A50A000EA5030010A5060012AD0500187B
-:10F99000AD020024948201142403FFF73042FFFFDC
-:10F9A000AD0200288C820118AD02002C3C02100030
-:10F9B000AD000030AF4201B88D220020004310247A
-:10F9C00003E00008AD2200208F82001430E7FFFF23
-:10F9D00000804821904200D330A5FFFF30C600FFD1
-:10F9E0000002110030420F0000E238252748018054
-:10F9F0008F4201B80440FFFE8F820048AD02000034
-:10FA00008F420124AD0200048D220020A5070008CA
-:10FA1000A102000A24020017A102000B9343012057
-:10FA20008D2200088D240004306300FF0043102164
-:10FA30009783003A004410218F8400140043102360
-:10FA40003C0308008C6331A0A502000CA505000E44
-:10FA5000246300E8A5030010A5060012AD00001401
-:10FA60008D220024AD0200188C82005CAD02001CC7
-:10FA70008C820058AD0200202402FFFFAD0200245A
-:10FA8000948200E63042FFFFAD02002894820060BD
-:10FA9000948300BE30427FFF3063FFFF00021200FC
-:10FAA00000431021AD02002C3C021000AD000030DC
-:10FAB000AF4201B8948200BE2403FFF700A21021D8
-:10FAC000A48200BE8D2200200043102403E0000821
-:10FAD000AD220020274301808F4201B80440FFFE81
-:10FAE0008F8200249442001C3042FFFF000211C0AC
-:10FAF000AC62000024020019A062000B3C0210005E
-:10FB0000AC60003003E00008AF4201B88F87002CE2
-:10FB100030C300FF8F4201B80440FFFE8F820048CF
-:10FB200034636000ACA2000093820044A0A20005F0
-:10FB30008CE20010A4A20006A4A300088C8200207E
-:10FB40002403FFF7A0A2000A24020002A0A2000BD7
-:10FB50008CE20000ACA200108CE20004ACA2001405
-:10FB60008CE2001CACA200248CE20020ACA2002895
-:10FB70008CE2002CACA2002C8C820024ACA20018D9
-:10FB80003C021000AF4201B88C82002000431024D8
-:10FB900003E00008AC8200208F86001427BDFFE838
-:10FBA000AFBF0014AFB0001090C20063304200201D
-:10FBB0001040000830A500FF8CC2007C2403FFDF4A
-:10FBC00024420001ACC2007C90C2006300431024B8
-:10FBD000A0C2006310A000238F830014275001806F
-:10FBE000020028210E0015D6240600828F82001400
-:10FBF000904200633042004050400019A38000440E
-:10FC00008F83002C8F4201B80440FFFE8F82004892
-:10FC1000AE02000024026082A60200082402000254
-:10FC2000A202000B8C620008AE0200108C62000C75
-:10FC3000AE0200148C620014AE0200188C62001830
-:10FC4000AE0200248C620024AE0200288C620028E0
-:10FC5000AE02002C3C021000AF4201B8A380004469
-:10FC60008F8300148FBF00148FB000109062006368
-:10FC700027BD00183042007FA06200639782003ADF
-:10FC80008F86003C8F850014938300280046102344
-:10FC9000A782003AA4A000E490A400638F820040F1
-:10FCA000AF83003C2403FFBF0046102100832024C3
-:10FCB000AF820040A0A400638F820014A04000BD6A
-:10FCC0008F82001403E00008A44000BE8F8A001455
-:10FCD00027BDFFE0AFB10014AFB000108F88003C2B
-:10FCE000AFBF00189389001C954200E430D100FF9B
-:10FCF0000109182B0080802130AC00FF3047FFFF46
-:10FD00000000582114600003310600FF012030215B
-:10FD1000010958239783003A0068102B1440003CD7
-:10FD20000000000014680007240200018E02002079
-:10FD30002403FFFB34E7800000431024AE020020C0
-:10FD40002402000134E70880158200053165FFFFB9
-:10FD50000E001554020020210A00169102002021F5
-:10FD60000E001585020020218F8400482743018062
-:10FD70008F4201B80440FFFE24020018AC6400006A
-:10FD8000A062000B8F840014948200E6A46200102D
-:10FD90003C021000AC600030AF4201B894820060B9
-:10FDA00024420001A4820060948200603C030800A9
-:10FDB0008C63318830427FFF5443000F02002021C2
-:10FDC000948200602403800000431024A482006019
-:10FDD0009082006090830060304200FF000211C2F8
-:10FDE00000021027000211C03063007F0062182556
-:10FDF000A083006002002021022028218FBF00186C
-:10FE00008FB100148FB000100A0015F927BD002033
-:10FE1000914200632403FF8000431025A142006348
-:10FE20009782003A3048FFFF110000209383001CA6
-:10FE30008F840014004B1023304600FF948300E4AD
-:10FE40002402EFFF0168282B00621824A48300E439
-:10FE500014A000038E020020010058210000302170
-:10FE60002403FFFB34E7800000431024AE0200208F
-:10FE700024020001158200053165FFFF0E001554B4
-:10FE8000020020210A0016B99783003A0E0015855A
-:10FE9000020020219783003A8F82003CA780003A1D
-:10FEA00000431023AF82003C9383001C8F82001418
-:10FEB0008FBF00188FB100148FB0001027BD002035
-:10FEC00003E00008A04300BD938200442403000126
-:10FED00027BDFFE8004330042C420020AFB00010E3
-:10FEE000AFBF00142410FFFE10400005274501801D
-:10FEF0003C0208008C4231900A0016D600461024BD
-:10FF00003C0208008C423194004610241440000743
-:10FF1000240600848F8300142410FFFF9062006287
-:10FF20003042000F34420040A06200620E0015D63D
-:10FF300000000000020010218FBF00148FB00010DD
-:10FF400003E0000827BD00188F83002427BDFFE0D1
-:10FF5000AFB20018AFB10014AFB00010AFBF001CBB
-:10FF60009062000D00A0902130D100FF3042007F50
-:10FF7000A062000D8F8500148E4300180080802140
-:10FF80008CA2007C146200052402000E90A2006383
-:10FF9000344200200A0016FFA0A200630E0016C51E
-:10FFA000A38200442403FFFF104300472404FFFF03
-:10FFB00052200045000020218E4300003C0200102A
-:10FFC00000621024504000043C020008020020217E
-:10FFD0000A00170E24020015006210245040000988
-:10FFE0008E45000002002021240200140E0016C5D8
-:10FFF000A38200442403FFFF104300332404FFFFC7
-:020000040001F9
-:100000008E4500003C02000200A2102410400016A1
-:100010003C0200048F8600248CC200148CC30010A4
-:100020008CC40014004310230044102B50400005E2
-:10003000020020218E43002C8CC2001010620003AD
-:10004000020020210A00173F240200123C02000493
-:1000500000A210245040001C00002021020020219A
-:100060000A00173F2402001300A2102410400006CB
-:100070008F8300248C620010504000130000202168
-:100080000A001739020020218C6200105040000441
-:100090008E42002C020020210A00173F240200118A
-:1000A00050400009000020210200202124020017F6
-:1000B0000E0016C5A38200442403FFFF1043000274
-:1000C0002404FFFF000020218FBF001C8FB2001806
-:1000D0008FB100148FB000100080102103E00008E1
-:1000E00027BD00208F83001427BDFFD8AFB40020A8
-:1000F000AFB3001CAFB20018AFB10014AFB0001026
-:10010000AFBF0024906200638F91002C2412FFFF88
-:100110003442004092250000A06200638E2200104D
-:100120000080982130B0003F105200060360A021EB
-:100130002402000D0E0016C5A38200441052005484
-:100140002404FFFF8F8300148E2200188C63007C30
-:1001500010430007026020212402000E0E0016C585
-:10016000A38200442403FFFF104300492404FFFF3F
-:1001700024040020120400048F83001490620063A2
-:1001800034420020A06200638F85003410A000205C
-:1001900000000000560400048F8200140260202139
-:1001A0000A0017902402000A9683000A9442006015
-:1001B0003042FFFF144300048F8200202404FFFD1F
-:1001C0000A0017B7AF82003C3C0208008C42318C19
-:1001D0000045102B14400006026020210000282159
-:1001E0000E001646240600010A0017B70000202161
-:1001F0002402002D0E0016C5A38200442403FFFF35
-:10020000104300232404FFFF0A0017B70000202139
-:10021000160400058F8400148E2300142402FFFFAF
-:100220005062001802602021948200602442000184
-:10023000A4820060948200603C0308008C633188D3
-:1002400030427FFF5443000F0260202194820060FF
-:100250002403800000431024A48200609082006088
-:1002600090830060304200FF000211C2000210279C
-:10027000000211C03063007F00621825A083006077
-:10028000026020210E0015F9240500010000202144
-:100290008FBF00248FB400208FB3001C8FB20018D2
-:1002A0008FB100148FB000100080102103E000080F
-:1002B00027BD00288F83001427BDFFE8AFB00010D2
-:1002C000AFBF0014906200638F87002C00808021F4
-:1002D000344200408CE60010A06200633C0308003A
-:1002E0008C6331B030C23FFF0043102B1040004EF2
-:1002F0008F8500302402FF8090A3000D004310245E
-:10030000304200FF504000490200202100061382C5
-:10031000304800032402000255020044020020215C
-:1003200094A2001C8F85001424030023A4A20114AE
-:100330008CE60000000616023042003F1043001019
-:100340003C0300838CE300188CA2007C1062000642
-:100350002402000E0E0016C5A38200442403FFFFF2
-:10036000104300382404FFFF8F8300149062006361
-:1003700034420020A06200630A0017FC8F8300242F
-:1003800000C31024144300078F83002490A200624E
-:100390003042000F34420020A0A20062A38800383F
-:1003A0008F8300249062000D3042007FA062000D18
-:1003B0008F83003410600018020020218F840030E9
-:1003C0008C8200100043102B1040000924020018FA
-:1003D000020020210E0016C5A38200442403FFFF63
-:1003E000104300182404FFFF0A00182400002021F5
-:1003F0008C820010240500010200202100431023FC
-:100400008F830024240600010E001646AC62001003
-:100410000A001824000020210E0015F9240500010F
-:100420000A00182400002021020020212402000DCF
-:100430008FBF00148FB0001027BD00180A0016C52A
-:10044000A38200448FBF00148FB0001000801021E1
-:1004500003E0000827BD001827BDFFC8AFB2002089
-:10046000AFBF0034AFB60030AFB5002CAFB400283A
-:10047000AFB30024AFB1001CAFB000188F46012805
-:100480003C0308008C6331A02402FF80AF86004843
-:1004900000C318213065007F03452821006218241D
-:1004A0003C02000AAF43002400A2282190A200626F
-:1004B00000809021AF850014304200FF000211023D
-:1004C000A382003890A200BC304200021440000217
-:1004D00024030034240300308F820014A3830028F7
-:1004E000938300388C4200C0A3800044AF82003C5C
-:1004F00024020004106203148F84003C8E44000424
-:10050000508003118F84003C8E4200103083FFFF27
-:10051000A784003A106002F7AF8200408F84001475
-:100520002403FF809082006300621024304200FFA9
-:10053000144002C79785003A9383003824020002D2
-:1005400030B6FFFF14620005000088219382002866
-:100550002403FFFD0A001B11AF82003C8F82003C88
-:1005600002C2102B144002998F8400400E0014EC3C
-:1005700000000000938300283C040800248477785E
-:10058000240200341462002EAF84002C3C0A0800C0
-:100590008D4A77A82402FFFFAFA200100080382107
-:1005A0002405002F3C09080025297378240800FF42
-:1005B0002406FFFF90E2000024A3FFFF00062202B2
-:1005C00000C21026304200FF0002108000491021B6
-:1005D0008C420000306500FF24E7000114A8FFF5FD
-:1005E0000082302600061027AFA20014AFA2001030
-:1005F0000000282127A7001027A6001400C51023FB
-:100600009044000324A2000100A71821304500FFF8
-:100610002CA200041440FFF9A06400008FA2001077
-:100620001142000724020005024020210E0016C5D9
-:10063000A38200442403FFFF104300642404FFFF4F
-:100640003C0208009042777C104000098F82001421
-:10065000024020212402000C0E0016C5A382004493
-:100660002403FFFF104300592404FFFF8F8200146E
-:10067000A380001C3C0308008C63777C8C440080C2
-:100680003C0200FF3442FFFF006218240083202B4D
-:1006900010800008AF83003402402021240200199A
-:1006A0000E0016C5A38200442403FFFF1043004739
-:1006B0002404FFFF8F87003C9782003A8F85003427
-:1006C000AF8700200047202310A0003BA784003AFA
-:1006D0008F86001430A200030002102390C300BCD8
-:1006E0003050000300B0282100031882307300014D
-:1006F0000013108000A228213C0308008C6331A065
-:100700008F8200483084FFFF0085202B004310219A
-:1007100010800011244200888F84002C1082000E6B
-:100720003C033F013C0208008C42777800431024D0
-:100730003C0325001443000630E500FF8C820000D6
-:10074000ACC200888C8200100A0018E9ACC2009884
-:100750000E001529000030219382001C8F850014A3
-:100760008F830040020238218F82003CA387001C47
-:1007700094A400E4006218218F82003434841000B5
-:10078000AF83004000503021A4A400E41260000EAA
-:10079000AF86003C24E20004A382001C94A200E483
-:1007A00024C30004AF83003C34422000A4A200E430
-:1007B0000A001906000020218F820040AF80003C13
-:1007C00000471021AF820040000020212414FFFFC9
-:1007D000109402092403FFFF3C0808008D08778865
-:1007E0003C0208008C4231B03C03080090637778EB
-:1007F00031043FFF0082102B1040001B3067003F88
-:100800003C0208008C4231A88F83004800042180FC
-:1008100000621821006418213062007F0342282101
-:100820003C02000C00A228213C020080344200015E
-:100830003066007800C230252402FF800062102458
-:10084000AF42002830640007AF4208048F820014D2
-:100850000344202124840940AF460814AF850024B6
-:10086000AF840030AC4301189383003824020003A6
-:10087000146201C7240200012402002610E201C90B
-:1008800028E2002710400013240200322402002234
-:1008900010E201C428E200231040000824020024D2
-:1008A0002402002010E201B02402002110E2013FE6
-:1008B000024020210A001AF32402000B10E201B9C1
-:1008C0002402002510E20010024020210A001AF341
-:1008D0002402000B10E201A628E2003310400006BB
-:1008E0002402003F2402003110E200920240202145
-:1008F0000A001AF32402000B10E2019D024020219D
-:100900000A001AF32402000B8F90002C3C0308000D
-:100910008C6331B08F8500308E0400100000A82158
-:100920008CB3001430823FFF0043102B8CB10020A9
-:10093000504001870240202190A3000D2402FF8037
-:1009400000431024304200FF50400181024020212A
-:1009500000041382304200031440017D0240202134
-:1009600094A3001C8F8200148E040028A443011459
-:100970008CA20010026218231064000302402021A0
-:100980000A00197C2402001F8F82003400621021AB
-:100990000262102B104000088F83002402402021A7
-:1009A000240200180E0016C5A38200441054016CE6
-:1009B0002404FFFF8F8300248F8400348C62001096
-:1009C0000224882100441023AC6200108F8200149E
-:1009D000AC7100208C4200680051102B10400009BF
-:1009E0008F830030024020212402001D0E0016C516
-:1009F000A38200442403FFFF104301592404FFFF96
-:100A00008F8300308E0200248C6300241043000783
-:100A1000024020212402001C0E0016C5A3820044BF
-:100A20002403FFFF1043014E2404FFFF8F840024A2
-:100A30008C82002424420001AC8200241233000482
-:100A40008F8200148C4200685622000E8E02000035
-:100A50008E0200003C030080004310241440000D6F
-:100A60002402001A024020210E0016C5A382004471
-:100A70002403FFFF1043013A2404FFFF0A0019BAC0
-:100A80008E0200143C0300800043102450400003F9
-:100A90008E020014AC8000208E0200142411FFFF8F
-:100AA000105100062402001B024020210E0016C532
-:100AB000A38200441051012A2404FFFF8E0300008A
-:100AC0003C02000100621024104000123C02008031
-:100AD0000062102414400008024020212402001A61
-:100AE0000E0016C5A38200442403FFFF1043011C1F
-:100AF0002404FFFF02402021020028210E0016E5F9
-:100B0000240600012403FFFF104301152404FFFF06
-:100B1000241500018F83002402A0302102402021EF
-:100B20009462003624050001244200010A001AD70D
-:100B3000A46200368F90002C3C0308008C6331B017
-:100B40008E13001032623FFF0043102B10400089CB
-:100B50008F8400302402FF809083000D0043102416
-:100B6000304200FF104000842402000D0013138265
-:100B700030420003240300011443007F2402000DCF
-:100B80009082000D30420008544000048F820034EF
-:100B9000024020210A001A082402002450400004C8
-:100BA0008E03000C024020210A001A0824020027AC
-:100BB0008C82002054620006024020218E0300082F
-:100BC0008C820024506200098E0200140240202111
-:100BD000240200200E0016C5A382004410540071A8
-:100BE0002403FFFF0A001A3D8F8400242411FFFF15
-:100BF000145100048F860014024020210A001A3884
-:100C0000240200258E0300188CC2007C10620003B1
-:100C10002402000E0A001A38024020218E0300240C
-:100C20008C82002810620003240200210A001A3876
-:100C3000024020218E0500288C82002C10A2000387
-:100C40002402001F0A001A38024020218E03002CC3
-:100C500014600003240200230A001A3802402021F5
-:100C60008CC200680043102B1040000324020026B1
-:100C70000A001A38024020218C82001400651821D5
-:100C80000043102B104000088F84002402402021D4
-:100C9000240200220E0016C5A38200441051004118
-:100CA0002403FFFF8F8400242403FFF79082000DAC
-:100CB00000431024A082000D8F8600143C0308001E
-:100CC0008C6331AC8F82004894C400E08F8500248F
-:100CD0000043102130847FFF000420400044102195
-:100CE0003043007F034320213C03000E008320217A
-:100CF0002403FF8000431024AF42002CA493000083
-:100D00008CA2002824420001ACA200288CA2002C56
-:100D10008E03002C00431021ACA2002C8E02002C6C
-:100D2000ACA200308E020014ACA2003494A2003AAF
-:100D300024420001A4A2003A94C600E03C0208004C
-:100D40008C4231B024C4000130837FFF1462000F55
-:100D500000803021240280000082302430C2FFFF56
-:100D6000000213C2304200FF000210270A001A7668
-:100D7000000233C02402000D024020210E0016C5DF
-:100D8000A38200440A001A7C004018218F820014BC
-:100D900002402021240500010E0015F9A44600E0C0
-:100DA000000018210A001B0E006088218F90002C83
-:100DB0003C0308008C6331B08E05001030A23FFF69
-:100DC0000043102B104000612402FF808F8400300C
-:100DD0009083000D00431024304200FF5040005C1F
-:100DE000024020218F8200341040000B0005138246
-:100DF0008F8200149763000A944200603042FFFF24
-:100E000014430005000513828F8200202404FFFD97
-:100E10000A001AEBAF82003C304200031440000E7F
-:100E20000000000092020002104000058E03002422
-:100E300050600015920300030A001AA70240202107
-:100E40008C82002450620010920300030240202193
-:100E50000A001AAF2402000F9082000D30420008F1
-:100E60005440000992030003024020212402001094
-:100E70000E0016C5A38200442403FFFF1043003870
-:100E80002404FFFF92030003240200025462000CBA
-:100E9000920200038F820034544000099202000342
-:100EA000024020212402002C0E0016C5A38200441B
-:100EB0002403FFFF1043002A2404FFFF92020003D3
-:100EC0000200282102402021384600102CC60001D3
-:100ED0002C4200010E0016E5004630252410FFFFCD
-:100EE0001050001F2404FFFF8F8300341060001394
-:100EF000024020213C0208008C42318C0043102B20
-:100F00001440000700000000000028212406000112
-:100F10000E001646000000000A001AEB0000202117
-:100F20002402002D0E0016C5A38200441050000CB0
-:100F30002404FFFF0A001AEB000020210E0015F91F
-:100F4000240500010A001AEB0000202102402021A4
-:100F50002402000D0E0016C5A3820044004020218B
-:100F60000A001B0E008088211514000E00000000EE
-:100F70000E00174C024020210A001B0E0040882161
-:100F80000E0016C5A38200440A001B0E00408821F3
-:100F900014620017022018212402002314E2000525
-:100FA0002402000B0E0017C0024020210A001B0E75
-:100FB0000040882102402021A38200440E0016C573
-:100FC0002411FFFF0A001B0F0220182130A500FF8B
-:100FD0000E001529240600019783003A8F82003CF9
-:100FE000A780003A00431023AF82003C0220182162
-:100FF0001220003E9782003A2402FFFD5462003E18
-:101000008E4300208E4200048F830014005610236C
-:10101000AE420004906200633042007FA062006331
-:101020008E4200208F840014A780003A34420002D0
-:10103000AE420020A48000E4908200632403FFBF3E
-:1010400000431024A08200630A001B518E4300203D
-:101050009082006300621024304200FF10400023A1
-:101060009782003A90820088908300BD2485008892
-:101070003042003F2444FFE02C820020A383001C68
-:1010800010400019AF85002C2402000100821804D2
-:10109000306200191440000C3C028000344200020F
-:1010A000006210241440000B306200201040000F3A
-:1010B0009782003A90A600010240202124050001F9
-:1010C0000A001B4B30C60001024020210A001B4AC7
-:1010D00024050001024020210000282124060001EF
-:1010E0000E001646000000009782003A1440FD0CE6
-:1010F0008F8400148E4300203062000410400012E0
-:101100008F84003C2402FFFB00621024AE420020CA
-:10111000274301808F4201B80440FFFE8F820048C0
-:10112000AC6200008F420124AC62000424026083A0
-:10113000A462000824020002A062000B3C0210001E
-:10114000AF4201B88F84003C8F8300148FBF0034FE
-:101150008FB600308FB5002C8FB400288FB30024D9
-:101160008FB200208FB1001C8FB000182402000144
-:1011700027BD003803E00008AC6400C030A500FFC4
-:101180002403000124A900010069102B1040000C69
-:1011900000004021240A000100A31023004A380463
-:1011A00024630001308200010069302B10400002EE
-:1011B000000420420107402554C0FFF800A310237B
-:1011C00003E00008010010213C020800244260A452
-:1011D0003C010800AC22736C3C0208002442530816
-:1011E0003C010800AC2273702402000627BDFFE01A
-:1011F0003C010800A02273743C021EDCAFB2001850
-:10120000AFB10014AFBF001CAFB0001034526F413B
-:1012100000008821240500080E001B7202202021F6
-:10122000001180803C07080024E773780002160054
-:1012300002071821AC6200000000282124A200014E
-:101240003045FFFF8C6200002CA60008044100021C
-:10125000000220400092202614C0FFF8AC64000079
-:10126000020780218E0400000E001B72240500205E
-:10127000262300013071FFFF2E2301001460FFE5DB
-:10128000AE0200008FBF001C8FB200188FB1001497
-:101290008FB0001003E0000827BD002027BDFFD855
-:1012A000AFB3001CAFB20018AFBF0020AFB1001445
-:1012B000AFB000108F5101408F48014800089402E0
-:1012C000324300FF311300FF8F4201B80440FFFE9C
-:1012D00027500180AE1100008F420144AE0200048D
-:1012E00024020002A6120008A202000B240200142D
-:1012F000AE1300241062002528620015104000087B
-:101300002402001524020010106200302402001292
-:10131000106200098FBF00200A001CAD8FB3001CB3
-:101320001062007024020022106200378FBF00207C
-:101330000A001CAD8FB3001C3C0208008C4231A097
-:101340002403FF800222102100431024AF42002416
-:101350003C0208008C4231A0022210213042007F62
-:10136000034218213C02000A00621821166000BCEA
-:10137000AF830014906200623042000F34420030AC
-:10138000A06200620A001CAC8FBF00203C04600019
-:101390008C832C083C02F0033442FFFF00621824C7
-:1013A000AC832C083C0208008C4231A08C832C08B2
-:1013B000244200740002108200021480006218258A
-:1013C000AC832C080A001CAC8FBF00203C02080034
-:1013D0008C4231A02403FF800222102100431024FC
-:1013E000AF4200243C0208008C4231A03C03000ABA
-:1013F000022210213042007F0342102100431021BD
-:101400000A001CABAF8200143C0208008C4231A0E1
-:101410002405FF800222102100451024AF42002441
-:101420003C0208008C4231A0022210213042007F91
-:10143000034218213C02000A0062182190620063F6
-:1014400000A21024304200FF10400085AF8300143A
-:1014500024620088944300123C0208008C4231A8A8
-:1014600030633FFF00031980022210210043102146
-:101470003043007F03432021004510243C03000C2F
-:1014800000832021AF4200289082000D00A210248A
-:10149000304200FF10400072AF8400249082000DA3
-:1014A000304200101440006F8FBF00200E0015C89E
-:1014B000000000008F4201B80440FFFE0000000061
-:1014C000AE1100008F420144AE020004240200026B
-:1014D000A6120008A202000BAE1300240A001CACE6
-:1014E0008FBF00202406FF8002261024AF42002078
-:1014F0003C0208008C4231A031043FFF00042180EF
-:101500000222102100461024AF4200243C030800B0
-:101510008C6331A83C0208008C4231A03227007F46
-:101520000223182102221021006418213042007F7A
-:101530003064007F034228213C02000A0066182420
-:1015400000A22821034420213C02000C008220211B
-:10155000AF4300283C020008034718210062902195
-:10156000AF850014AF8400240E0015C8010080214F
-:101570008F4201B80440FFFE8F8200248F84001444
-:10158000274501809042000DACB10000A4B00006D8
-:10159000000216000002160300021027000237C2E4
-:1015A00014C00016248200889442001232033FFFC8
-:1015B00030423FFF14430012240260829083006394
-:1015C0002402FF8000431024304200FF5040000CF2
-:1015D00024026082908200623042000F3442004058
-:1015E000A082006224026084A4A200082402000DEC
-:1015F000A0A200050A001C963C022700240260827B
-:10160000A4A20008A0A000053C02270000061C00C0
-:101610000062182524020002A0A2000BACA3001057
-:10162000ACA00014ACA00024ACA00028ACA0002CFE
-:101630008E42004C8F840024ACA200189083000DD1
-:101640002402FF8000431024304200FF10400005B8
-:101650008FBF00209082000D3042007FA082000DDD
-:101660008FBF00208FB3001C8FB200188FB1001401
-:101670008FB000103C02100027BD002803E00008D6
-:04168000AF4201B8BC
-:0C1684000800343008003430080033A89F
-:10169000080033E0080034140800343808003438F7
-:0816A00008003438080033187B
-:0816A8000A000124000000000B
-:1016B000000000000000000D747061362E322E31E3
-:1016C0000000000006020101000000000000000010
-:1016D000000000000000000000000000000000000A
-:1016E00000000000000000000000000000000000FA
-:1016F00000000000000000000000000000000000EA
-:1017000000000000000000000000000000000000D9
-:1017100000000000000000000000000000000000C9
-:1017200000000000000000000000000000000000B9
-:101730000000000000000000000000001000000396
-:10174000000000000000000D0000000D3C02080039
-:1017500024421C003C03080024632094AC40000099
-:101760000043202B1480FFFD244200043C1D080090
-:1017700037BD2FFC03A0F0213C1008002610049078
-:101780003C1C0800279C1C000E00015C00000000AF
-:101790000000000D3084FFFF308200078F850018A5
-:1017A00010400002248300073064FFF800853021D8
-:1017B00030C41FFF03441821247B4000AF85001C68
-:1017C000AF84001803E00008AF4400843084FFFFBA
-:1017D000308200078F8500208F860028104000028D
-:1017E000248300073064FFF8008520210086182B31
-:1017F00014600002AF8500240086202303442821C2
-:1018000034068000AF840020AF44008000A6202171
-:1018100003E00008AF84003827BDFFD8AFB3001C39
-:10182000AFB20018AFB00010AFBF0024AFB40020BB
-:10183000AFB100143C0860088D1450002418FF7FDD
-:101840003C1A8000029898243672380CAD12500071
-:101850008F5100083C07601C3C08600036300001D6
-:10186000AF500008AF800018AF400080AF40008448
-:101870008CE600088D0F08083C0760168CEC000011
-:1018800031EEFFF039CA00103C0DFFFF340B800031
-:101890003C030080034B48212D440001018D282486
-:1018A0003C0253533C010800AC230420AF890038AC
-:1018B000AF860028AF840010275B400014A200030D
-:1018C00034E37C008CF90004032818218C7F007C11
-:1018D0008C6500783C0280003C0B08008D6B048C0A
-:1018E0003C0A08008D4A048834520070AF85003CE1
-:1018F000AF9F00403C13080026731C440240A02107
-:101900008E4800008F46000038C30001306400019B
-:1019100010800017AF880034028048218D2F00000E
-:101920003C0508008CA5045C3C1808008F1804587E
-:1019300001E8102300A280210000C8210202402BF0
-:1019400003198821022838213C010800AC30045CCE
-:101950003C010800AC2704588F4E000039CD00012F
-:1019600031AC00011580FFED01E04021AF8F003464
-:101970008E5100003C0708008CE7045C3C0D080019
-:101980008DAD04580228802300F0602100007021F2
-:101990000190302B01AE1821006620213C01080087
-:1019A000AC2C045C3C010800AC2404588F460108B0
-:1019B0008F47010030C92000AF860000AF87000CC0
-:1019C0001120000A00C040213C1808008F18042C88
-:1019D000270800013C010800AC28042C3C184000FA
-:1019E000AF5801380A000196000000009749010431
-:1019F00000002821014550213122FFFF01625821BA
-:101A00000162F82B015F502130D902003C0108002F
-:101A1000AC2B048C3C010800AC2A0488172000156C
-:101A200024040F0010E400130000000024080D003F
-:101A300010E8023B30CD000611A0FFE93C18400041
-:101A4000936E00002409001031C400F01089027167
-:101A500024020070108202E58F880014250F000117
-:101A6000AF8F00143C184000AF5801380A000196AF
-:101A700000000000974C01041180FFD93C18400081
-:101A800030C34000146000A1000000008F460178C0
-:101A900004C0FFFE8F87003824100800240F0008C0
-:101AA0008CE30008AF500178A74F0140A7400142E6
-:101AB000974E01048F86000031C9FFFF30CD000131
-:101AC00011A002E1012040212531FFFE241800026F
-:101AD000A75801463228FFFFA75101483C190800CA
-:101AE0008F39043C172002D08F8C000C30DF00208F
-:101AF00017E00002240400092404000130C20C0095
-:101B0000240504005045000134840004A744014A20
-:101B10003C1108008E3104203C1800483C100001A4
-:101B20000238182530CF00020070282511E000048B
-:101B3000000018213C19010000B9282524030001E8
-:101B400030DF000453E00005AF8300083C060010BE
-:101B500000A6282524030001AF830008AF4510002C
-:101B60000000000000000000000000000000000075
-:101B70008F83000810600023000000008F451000D4
-:101B800004A1FFFE000000001060001E0000000025
-:101B90008F4410003C0C0020008C102410400019D1
-:101BA0008F8E000031CD000211A000160000000051
-:101BB000974F101415E0001300000000975910080B
-:101BC0003338FFFF27110006001118820003308010
-:101BD00000C7282132300001322300031200032CF9
-:101BE0008CA200000000000D00C7F821AFE2000049
-:101BF0003C0508008CA5043024A600013C01080027
-:101C0000AC2604308F6D00003402FFFFAF8D00045E
-:101C10008CEC0000118202A6000020218CED000057
-:101C200031AC01001180028A000000003C02080073
-:101C30008C4204743C0308008C63044C3C1F080075
-:101C40008FFF04703C1808008F18044800483821A2
-:101C50000068802100E8282B03E430210208402B93
-:101C60000304882100C57021022878213C01080066
-:101C7000AC30044C3C010800AC2F04483C01080087
-:101C8000AC2704743C010800AC2E04708F8400184B
-:101C90000120302131290007249F000833F91FFF5C
-:101CA00003594021AF84001CAF990018251B400048
-:101CB000AF590084112000038F83002024C2000745
-:101CC0003046FFF88F84002800C3282100A4302B61
-:101CD00014C00002AF83002400A428230345602120
-:101CE000340D8000018D10213C0F1000AF850020C5
-:101CF000AF820038AF450080AF4F01788F88001465
-:101D0000250F00010A0001EFAF8F00148F62000859
-:101D10008F670000240500300007760231C300F011
-:101D2000106500A7240F0040546FFF4C8F880014EB
-:101D30008F4B01780560FFFE0000000030CA0200F2
-:101D400015400003000612820000000D00061282FA
-:101D5000304D0003000D4900012D18210003808043
-:101D6000020D402100086080019380218E1F000039
-:101D700017E00002000000000000000D8F6E00045C
-:101D800005C202BD92070006920E000592020004F1
-:101D90003C090001000E18800070F8218FED00183A
-:101DA000277100082448000501A96021000830823D
-:101DB000AFEC0018022020210E00059E260500141D
-:101DC000920A00068F7900043C0B7FFF000A2080F6
-:101DD000009178218DF800043566FFFF0326282442
-:101DE00003053821ADE70004920E0005920D0004B2
-:101DF000960C0008000E10800051C8218F230000AF
-:101E0000974901043C07FFFF006758243128FFFF72
-:101E1000010DF82103EC50233144FFFF016430250C
-:101E2000AF26000092030007241800011078027505
-:101E3000240F0003106F0285000000008E050010C3
-:101E40002419000AA7590140A7450142921800042D
-:101E50008F860000240F0001A7580144A7400146C7
-:101E60009747010430D100023C050041A7470148D3
-:101E700000001821A74F014A1220000330CB0004B4
-:101E80003C0501412403000151600005AF830008B7
-:101E90003C06001000A6282524030001AF8300089B
-:101EA000AF4510000000000000000000000000002E
-:101EB000000000008F8A00081140000400000000AC
-:101EC0008F4410000481FFFE000000008F6B0000B3
-:101ED000920800043C1108008E310444AF8B0004CA
-:101EE00097590104311800FF3C0E08008DCE0440C4
-:101EF0003325FFFF03053821022760210000102150
-:101F0000250F000A31E8FFFF0187482B01C2682135
-:101F100001A9F821311000073C010800AC2C044451
-:101F20003C010800AC3F0440120000038F8C0018F5
-:101F30002506000730C8FFF8010C682131BF1FFFDC
-:101F4000AF8C001CAF9F0018AF5F00849744010462
-:101F5000035F80213084FFFF308A000711400003B7
-:101F6000261B4000248900073124FFF88F820020BF
-:101F70008F850028008220210085702B15C000026B
-:101F8000AF820024008520233C0B08008D6B048C5D
-:101F90003C0A08008D4A04880344882134038000E9
-:101FA000022310213C0F1000AF840020AF820038C4
-:101FB000AF440080AF4F01780A0002968F8800146A
-:101FC0008F5001780600FFFE30D10200162000037A
-:101FD000000612820000000D00061282305F00032E
-:101FE000001F1900007F302100062080009FC821BB
-:101FF00000194880013380218E1800001300000270
-:10200000000000000000000D8F6C000C058001FB3B
-:102010008F870038240E0001AE0E00008CE300080C
-:10202000A20000078F65000400055402314D00FF37
-:1020300025A80005000830822CCB00411560000265
-:10204000A20A00040000000D8F7800043C03FFFF8B
-:1020500000E02821330BFFFF256C000B000C1082E1
-:1020600000022080008748218D3F000026040014D4
-:10207000A618000803E3C8240E00059EAD39000031
-:102080008F4F01083C11100001F1382410E001AB22
-:1020900000000000974D01049208000725AAFFECFC
-:1020A000350600023144FFFFA2060007960600082D
-:1020B0002CC7001354E0000592030007921100079B
-:1020C000362F0001A20F0007920300072418000119
-:1020D000107801C224090003106901D58F880038E7
-:1020E00030CBFFFF257100020011788331E400FF3F
-:1020F00000042880A20F000500A848218D2D0000B3
-:10210000974A01043C0EFFFF01AEF8243143FFFF64
-:10211000006B1023244CFFFE03ECC825AD390000F2
-:10212000920600053C03FFF63462FFFF30D800FF43
-:102130000018388000F08821922F00143C04FF7FA3
-:102140003487FFFF31EE000F01C65821316500FFD3
-:1021500000055080015068218DAC00200148F82115
-:10216000A20B00060182C824AE0C000CAFF9000CD3
-:10217000920900068E11000C032778240009C08004
-:102180000310702195C60026030828210227202469
-:10219000AE04000CADCF0020ADC60024ACA60010EC
-:1021A0008F8800003C0B08008D6B048C3C0A0800F3
-:1021B0008D4A0488241F001024190002A75F0140E3
-:1021C000A7400142A7400144A7590146974901048D
-:1021D00024070001310600022538FFFEA7580148F8
-:1021E0003C050009A747014A10C000030000182160
-:1021F0003C05010924030001310C00045180000555
-:10220000AF8300083C08001000A828252403000123
-:10221000AF830008AF451000000000000000000080
-:1022200000000000000000009205000424AE00023F
-:1022300031CD0007000D182330620007AE020010F8
-:102240008F90000812000004000000008F4F100063
-:1022500005E1FFFE000000008F7100008F8E001866
-:102260003C0308008C630444AF91000497450104CB
-:1022700025CF001031E61FFF30A2FFFFAF8E001CFC
-:10228000AF860018AF4600842449FFFE3C0C0800CE
-:102290008D8C0440974D010401208021000947C323
-:1022A0000070C02131A9FFFF0310F82B0188C8215D
-:1022B000033F202103463821313100073C0108004B
-:1022C000AC3804443C010800AC2404401220000354
-:1022D00024FB40002527000730E9FFF88F86002007
-:1022E0008F8400280126382100E4C02B170000024B
-:1022F000AF86002400E438230347202134198000EE
-:10230000009910213C0F1000AF870020AF820038E9
-:10231000AF470080AF4F01780A0002968F88001403
-:102320009747010410E0FDAE3C1840008F5801783B
-:102330000700FFFE30C5400010A000033C1F00084E
-:102340000000000D3C1F0008AF5F01402410080092
-:102350008F860000AF5001789744010430D9000106
-:10236000132000ED3086FFFF24CCFFFE240D000279
-:10237000A74D0146A74C01488F9100182408000D75
-:10238000A748014A8F630000262F000831E21FFF93
-:102390000342702130C90007AF830004AF91001CD5
-:1023A000AF82001800C03821AF4200841120000322
-:1023B00025DB400024D800073307FFF88F85002075
-:1023C0008F84002800E5302100C4382B14E000027F
-:1023D000AF85002400C430238F8400140346F82105
-:1023E000340C8000AF86002003EC8021AF460080D3
-:1023F000249900013C0610003C184000AF460178CB
-:10240000AF900038AF990014AF5801380A00019618
-:10241000000000008F630000975101043067FFFF48
-:102420003228FFFF8F4F017805E0FFFE30EC0007F8
-:10243000000CF82333F0000724F9FFFE2404000AFF
-:10244000A7440140A7500142A7590144A7400146B3
-:10245000A74801488F45010830B800201700000246
-:10246000240300092403000130CD0002A743014AE0
-:102470003C04004111A00003000018213C0401416C
-:102480002403000130C9000451200005AF83000877
-:102490003C0600100086202524030001AF830008BD
-:1024A000AF44100000000000000000000000000029
-:1024B000000000008F8E000811C000040000000022
-:1024C0008F4210000441FFFE000000008F7F0000DB
-:1024D000276400088F91003CAF9F0004948500089A
-:1024E0009490000A9499000C30AFFFFF0010C400D4
-:1024F0003323FFFF11F100A6030320253C0E080043
-:102500008DCE04443C0C08008D8C044000E88821EA
-:102510002626FFFE01C628210000682100A6F82B10
-:10252000018D2021009F80213C010800AC2504443E
-:102530003C010800AC30044024E200083042FFFFB8
-:102540003047000710E000038F830018244F000776
-:1025500031E2FFF83106FFFF30C800070043802159
-:1025600032191FFF0359C021AF83001CAF99001817
-:10257000271B4000AF590084110000038F8C0020FE
-:1025800024C5000730A6FFF88F84002800CC28213E
-:1025900000A4F82B17E00002AF8C002400A428232D
-:1025A000AF850020AF4500803C0408008C840434D3
-:1025B00003454821340E8000012E6821108000055B
-:1025C000AF8D0038939100172406000E12260011DB
-:1025D0002407043F3C021000AF4201788F880014AA
-:1025E000250F00010A0001EFAF8F00140E0005C493
-:1025F00000E020218F8800143C0B08008D6B048CB8
-:102600003C0A08008D4A0488250F00010A0001EFEA
-:10261000AF8F00143C021000A7470148AF42017879
-:102620000A0004CE8F88001424040F001184003D9A
-:1026300030CE002015C0000224030009240300014D
-:102640000A00021AA743014A0A00020DA7400146E8
-:1026500094EF000894F1000A94F0000C8F8C003C79
-:10266000001174003207FFFF31EDFFFF11AC00379E
-:1026700001C720253C1808008F1804443C0F0800AF
-:102680008DEF0440000080210308682101A8382B49
-:1026900001F0702101C760213C010800AC2D044409
-:1026A0003C010800AC2C04400A00027A8F84001818
-:1026B0003C0208008C42047C3C0308008C630454F8
-:1026C0003C1F08008FFF04783C1808008F18045046
-:1026D000004838210068802100E8282B03E43021DD
-:1026E0000208402B0304882100C5702102287821AC
-:1026F0003C010800AC3004543C010800AC2F0450ED
-:102700003C010800AC27047C3C010800AC2E047896
-:102710000A00027A8F840018A74001460A00043597
-:102720008F91001830CD002015A0FFC52403000DA7
-:10273000240300050A00021AA743014A974E010428
-:1027400025C5FFF00A00038130A4FFFF8F980040E9
-:102750001498FFC8000010213C0508008CA5046CEB
-:102760003C1F08008FFF046800A8C8210328302BF5
-:1027700003E22021008640213C010800AC39046CB2
-:102780003C010800AC2804680A00027A8F84001813
-:102790008F8C0040148CFF5900E8C8213C180800B9
-:1027A0008F18046C3C1108008E3104682723FFFE4B
-:1027B00003034821000010210123302B0222702145
-:1027C00001C668213C010800AC29046C3C010800EA
-:1027D000AC2D04680A0004A524E200088F880038A4
-:1027E0003C03FFFF8D02000C0043F82403E4C825DE
-:1027F000AD19000C0A00038F30CBFFFF0A0003C3A2
-:10280000AE000000974A0104920400048E26000CDA
-:10281000014458212579FFF200C7C0243325FFFF6A
-:1028200003053825AE27000C0A0002E68E050010CD
-:102830003C0DFFFF8D0A0010014D582401646025F6
-:10284000AD0C00100A00038F30CBFFFF974301044B
-:10285000920E00048E290010006E1021244DFFEE10
-:102860000127602431A8FFFF0188F825AE3F001042
-:102870000A0002E68E0500108E0F000CAE0000006C
-:1028800000078880023028210A0002B8ACAF00207F
-:102890001460000D3058FFFF3C04FFFF0044682423
-:1028A00001A47026000E602B000D102B004CF824A4
-:1028B00013E00002000000000000000D8CAF0000DB
-:1028C0000A00025001E410253B03FFFF0003882BA0
-:1028D0000018802B0211202410800002000000004C
-:1028E0000000000D8CB900000A0002503722FFFFE3
-:1028F0003084FFFF30A5FFFF108000070000182183
-:1029000030820001104000020004204200651821BE
-:102910001480FFFB0005284003E000080060102140
-:1029200010C00007000000008CA2000024C6FFFFBA
-:1029300024A50004AC82000014C0FFFB2484000422
-:1029400003E000080000000010A0000824A3FFFF1F
-:10295000AC86000000000000000000002402FFFF21
-:102960002463FFFF1462FFFA2484000403E00008DC
-:1029700000000000308EFFFF30D8FFFF00057C0014
-:1029800001F8602539CDFFFF01AC5021014C582BD7
-:10299000014B4821000944023127FFFF00E83021A4
-:1029A0000006240230C5FFFF00A418213862FFFF93
-:1029B00003E000083042FFFF3C0C08008D8C0484CB
-:1029C000240BFF8027BDFFD001845021014B4824F8
-:1029D000AF4900203C0808008D080484AFB20020F5
-:1029E000AFB00018AFBF0028AFB30024AFB1001CD8
-:1029F000936600040104382130E4007F009A10211E
-:102A00003C0300080043902130C500200360802172
-:102A10003C080111277B000814A000022646007024
-:102A20002646006C9213000497510104920F000493
-:102A30003267000F322EFFFF31ED004001C728231F
-:102A400011A0000500004821925900BC3338000451
-:102A50001700009000000000924300BC307F00048B
-:102A600013E0000F0000000010A0000D00000000A7
-:102A7000960E0002240AFF8000A7602125CDFFFEEC
-:102A8000A74D1016920B0004014B2024308200FF4A
-:102A900010400085010C40253C0F0400010F40252B
-:102AA0008F5301780660FFFE2404000AA74401400A
-:102AB000960D00022404000931AC0007000C5823D5
-:102AC000316A0007A74A0142960200022443FFFE32
-:102AD000A7430144A7400146975F0104A75F01484F
-:102AE0008F590108333800205300000124040001ED
-:102AF000920F000431EE001015C000023483001064
-:102B000000801821A743014A0000000000000000D7
-:102B10000000000000000000AF48100000000000AE
-:102B20000000000000000000000000008F511000B5
-:102B30000621FFFE3113FFFF1260000300000000BA
-:102B40008F481018ACC8000096030006307FFFFFC6
-:102B500027F900020019988200138880023B302177
-:102B60008CD800001520005700183402920300048E
-:102B70002405FF8000A3F82433F100FF1220002C6D
-:102B800000000000924700BC30F200021240002812
-:102B900000000000974B100C2562FFFEA7421016A4
-:102BA000000000003C0A040035490030AF49100025
-:102BB0000000000000000000000000000000000015
-:102BC0008F4C10000581FFFE000000009749100C9B
-:102BD0008F51101C00C020213127FFFF24F200304C
-:102BE000001218820003288000BBF8213226FFFF64
-:102BF000AFF100000E0005B300112C020013C880D5
-:102C0000033B98218E78000000027400AFB80010DA
-:102C10008FA80010310FFFFFAFAF00108FA400107E
-:102C200001C46825AFAD00108FA60010AE6600008D
-:102C300097730008976D000A9766000C8F8A003C16
-:102C4000000D5C0030CCFFFF3262FFFF104A0036FF
-:102C5000016C2025960600023C10100024D30008C9
-:102C60000E00013B3264FFFF974C01040E00014946
-:102C70003184FFFFAF5001788FBF00288FB300244D
-:102C80008FB200208FB1001C8FB0001803E0000845
-:102C900027BD003010A0FF700000000024A5FFFC3D
-:102CA0000A0005EC240900048CD10000AF51101873
-:102CB0008F5301780660FF7A2404000A0A00060197
-:102CC0000000000000A7C8218F8800388F4E101C1C
-:102CD0000019C0820018788001E82021AC8E000025
-:102CE000000E2C0200C020210E0005B331C6FFFFEC
-:102CF000023B28218CAD000000025400004030212E
-:102D0000AFAD00108FAC0010318BFFFFAFAB0010E8
-:102D10008FA2001001424825AFA900108FA7001014
-:102D20000A000631ACA700008F8F0040148FFFC946
-:102D30000000000097420104960B00023C050800C9
-:102D40008CA5046C3049FFFF316AFFFF3C1108007D
-:102D50008E310468012A382124F2FFFE00B240219E
-:102D60000012FFC30112C82B023FC021031920210A
-:102D70003C010800AC28046C3C010800AC24046849
-:102D80000A00066B0000000000A4102B1040000990
-:102D9000240300010005284000A4102B04A0000318
-:102DA000000318405440FFFC000528401060000755
-:102DB000000000000085302B14C000020003184200
-:102DC000008520231460FFFB0005284203E0000873
-:102DD000008010218F85002C27BDFFE800053027DB
-:102DE0002CC300012CA40002008310251040000316
-:102DF000AFBF00102405007FAF85002C00052827F9
-:102E000030A5FFFF0E000592240426F58F830030C5
-:102E1000240402BD004030210083382B10E000095B
-:102E200024050001000420400083102B04800003CF
-:102E3000000528405440FFFC0004204010A000087A
-:102E400000C350210064402B1500000200052842F9
-:102E50000064182314A0FFFB0004204200C350218B
-:102E60008FBF0010000A4C02312200FF27BD00185E
-:0C2E7000AF8A002C03E00008AF8900309E
-:042E7C000A00002A1E
-:102E800000000000000000000000000D74787036A3
-:102E90002E322E310000000006020100000000006A
-:102EA000000001360000EA600000000000000000A1
-:102EB0000000000000000000000000000000000012
-:102EC0000000000000000000000000000000000002
-:102ED00000000000000000000000000000000016DC
-:102EE00000000000000000000000000000000000E2
-:102EF00000000000000000000000000000000000D2
-:102F000000000000000000000000000000000000C1
-:102F1000000000000000138800000000000005DC35
-:102F2000000000000000000010000003000000008E
-:102F30000000000D0000000D3C02080024423C206F
-:102F40003C03080024633DD4AC4000000043202B28
-:102F50001480FFFD244200043C1D080037BD7FFCA7
-:102F600003A0F0213C100800261000A83C1C08001B
-:102F7000279C3C200E0002BA000000000000000D5B
-:102F80008F8300383C088000350700708CE5000016
-:102F9000008330253C02900000C22025AF85003020
-:102FA000AF4400208F4900200520FFFE3C03800035
-:102FB000346200708C4500008F8600303C19080098
-:102FC0008F39007C3C0E08008DCE007800A62023AF
-:102FD00003245821000078210164682B01CF60216F
-:102FE000018D50213C010800AC2B007C3C01080005
-:102FF000AC2A007803E00008000000000A0000414D
-:10300000240400018F8400383C05800034A20001B4
-:103010000082182503E00008AF43002003E0000809
-:10302000000010213084FFFF30A5FFFF1080000753
-:1030300000001821308200011040000200042042EC
-:10304000006518211480FFFB0005284003E00008FC
-:103050000060102110C00007000000008CA20000DA
-:1030600024C6FFFF24A50004AC82000014C0FFFBAF
-:103070002484000403E000080000000010A0000801
-:1030800024A3FFFFAC860000000000000000000049
-:103090002402FFFF2463FFFF1462FFFA248400046C
-:1030A00003E0000800000000308AFFFF93A800132F
-:1030B000A74A014497490E1630C600FF3C02100093
-:1030C000A7490146AF450148A3460152A748015A06
-:1030D000AF4701608FA400188FA30014A7440158C4
-:1030E000AF43015403E00008AF42017803E0000859
-:1030F000000000003C038000346200708C49000036
-:103100008F8800002484000727BDFFF83084FFF873
-:10311000AF890030974D008A31ACFFFFAFAC0000A3
-:103120008FAB0000016850232547FFFF30E61FFFEB
-:1031300000C4282B14A0FFF73C0C8000358B0070D6
-:103140008D6A00003C0708008CE700843C060800FC
-:103150008CC6008000081082014918230002788084
-:1031600000E370210000202101C3C82B00C4C0214E
-:1031700001FA4021031948212502400027BD00081B
-:103180003C010800AC2E00843C010800AC29008002
-:1031900003E00008000000008F8200002486000782
-:1031A00030C5FFF800A2182130641FFF03E00008BB
-:1031B000AF8400008F8700388F8A004027BDFFB89A
-:1031C0008F860044AFB60040AFBF0044AFB5003CAF
-:1031D000AFB40038AFB30034AFB20030AFB1002CA1
-:1031E000AFB000288F4501048D4900ACAF47008087
-:1031F0008CC8002000A938230000B021AF480E1071
-:103200008F440E1000004821AF440E148CC20024DD
-:10321000AF420E188F430E18AF430E1C10E001256D
-:103220002D230001936B0008116000D40000000002
-:10323000976E001031CDFFFF00ED602B158000CFA1
-:103240000000000097700010320FFFFFAF4F0E001C
-:103250008F520000325100081220FFFD00000000D4
-:1032600097540E088F460E043285FFFF30B30001DD
-:1032700012600132000000000000000D30B8A040D4
-:1032800024150040131500C030A9A0001120012D05
-:1032900000000000937F000813E000080000000019
-:1032A00097630010306BFFFF00CB402B1100000331
-:1032B00030AC00401180012300000000A785003CD5
-:1032C000AF8600349366000800E02821AFA70020F5
-:1032D00014C0012427B30020AF60000C9782003C8B
-:1032E0003047400014E00002240300162403000EBF
-:1032F00024194007A363000AAF790014938A003EA3
-:103300008F740014315800070018AA4002959025C8
-:10331000AF7200149784003C8F700014309100103D
-:1033200002117825AF6F0014978E003C31CD000854
-:1033300011A00147000028218F6700143C021000F3
-:103340003C0C810000E22825AF65001497460E0A68
-:103350002408000E3405FFFC30C3FFFF006C582525
-:10336000AF6B0004A3680002937F000A27E9000402
-:10337000A369000A9786003C9363000A30CC1F00C3
-:10338000000C598301634021251F0028A37F0009F9
-:1033900097490E0CA769001093790009272A0002AB
-:1033A000315800070018A82332B10007A371000BA1
-:1033B00093740009976400108F910034978F003C3C
-:1033C000329200FF024480210205702131ED00405D
-:1033D00011A0000531C4FFFF0091282B3C12800092
-:1033E00010A000140000A0210224382B14E0011BBF
-:1033F0008FA500208F4D0E14AF4D0E108F420E1C66
-:10340000AF420E18AF440E008F4F000031EE00089F
-:1034100011C0FFFD0000000097540E0800808821B5
-:1034200000009021A794003C8F500E04241400014A
-:10343000AF900034976400103095FFFF8E68000055
-:103440000111F82317E00009AE7F00008F6500141A
-:103450008F8B004434A60040AF6600148F4C0E10D2
-:10346000AD6C00208F430E18AD63002493670008F5
-:1034700014E000D2000000000E00009E24040010A2
-:103480008F8900483C08320000402821312600FF87
-:103490000006FC0003E8502525390001AF990048DB
-:1034A000AC4A0000937800099370000A330400FFCF
-:1034B00000047400320F00FF01CF6825AC4D0004FA
-:1034C0008F820048064000EAACA20008ACA0000CC5
-:1034D0009783003C306B0008156000022628000628
-:1034E00026280002974E0E148F450E1C8F6700048D
-:1034F000936D000231C4FFFF31A200FFAFA20010A4
-:103500008F6C0014AFA800180E00008BAFAC001435
-:10351000240400100E0000C7000000008E7200009E
-:1035200016400005000000008F6400142405FFBF52
-:1035300000859824AF7300148F79000C033538216F
-:10354000AF67000C9375000816A00008000000008B
-:1035500012800006000000008F7F00143C0BEFFF7C
-:103560003568FFFE03E84824AF690014A37400081F
-:103570008FA500200A00024602202021AF470E003E
-:103580000A0000F5000000008F5901780720FFFEB7
-:10359000241F08008F840000AF5F0178974B008ADA
-:1035A000316AFFFF014448232528FFFF31021FFF36
-:1035B0002C4300081460FFF9000000008F8E0048C3
-:1035C0008F8D003800C048210344202125C600010A
-:1035D000240C0F00AF86004800E938232486400001
-:1035E00031CA00FF11AC0005240800019391003E90
-:1035F0003230000700107A4035E80001000AAC00C4
-:103600003C18010002B8A025AC9440008F930048FC
-:1036100030B2003630A40008ACD30004108000970C
-:1036200001123025974E0E0A8F8D00003C0281005A
-:1036300031CCFFFF25AB0008018240253C03100080
-:1036400031651FFF25390006241F000EAF480160B9
-:1036500000C33025A75F015AAF850000A759015864
-:1036600014E0000A8F93003824120F0052720002F7
-:103670002416000134C600408F580E108F94004469
-:10368000AE9800208F550E18AE9500248F450E146D
-:10369000AF4501448F590E1CAF590148A34A01524E
-:1036A0003C0A1000AF460154AF4A017814E0FEDD39
-:1036B0002D2300010076A025128000178FBF004443
-:1036C0008F84003824160F0010960084000000003C
-:1036D0008F45017804A0FFFE24150F001095006EA1
-:1036E000000000008F470E14240202403C1F10000F
-:1036F000AF4701448F440E1CAF440148A340015220
-:10370000A740015AAF400160A7400158AF420154A1
-:10371000AF5F01788FBF00448FB600408FB5003C8B
-:103720008FB400388FB300348FB200308FB1002CCB
-:103730008FB0002803E0000827BD004814C0FED069
-:1037400030B8A0408F420E148F84004400004821FE
-:10375000AC8200208F510E1CAC9100240A00020E96
-:103760002D2300018F910034978A003C3C12800089
-:103770000220A821315800401700FF300000A0218E
-:10378000976900108F9200343139FFFF13320035F2
-:1037900000002021008048211480FEA000A03821D4
-:1037A0008F420E148F840044AC8200208F510E1C77
-:1037B000AC9100240A00020E2D230001936A000937
-:1037C0009378000B315000FF330F00FF020F702180
-:1037D00025C2000A3050FFFF0E00009E020020218B
-:1037E0008F8600483C1F410024CD0001AF8D00486A
-:1037F000936C000930C600FF00064400318300FFCF
-:10380000246B0002010B4825013FC825AC5900007C
-:103810008F67000C97440E1400F22825AC45000475
-:103820008F450E1C8F670004936A00023084FFFFEF
-:10383000315800FFAFB800108F6F0014AFB10018FF
-:103840000E00008BAFAF00140A0001A60200202179
-:10385000AF6000040A00013EA36000020A000246B5
-:1038600000002021000090210A00017024140001B2
-:103870003C1280000A000195ACB2000C8F91000050
-:1038800025240002A744015826300008320F1FFFEC
-:103890000A0001F9AF8F0000AF40014C1120002C4D
-:1038A000000000008F590E10AF5901448F430E18CD
-:1038B000240200403C1F1000AF430148A3400152C6
-:1038C000A740015AAF400160A7400158AF420154E0
-:1038D000AF5F01780A0002278FBF00441120000665
-:1038E0000000000097460E0830CC00401580000212
-:1038F000000000000000000D8F4D017805A0FFFEC4
-:103900000000000097530E103C120500240E20000A
-:10391000326AFFFF0152C025AF58014C8F4F0E1481
-:103920003C021000AF4F01448F500E1CAF500148B5
-:10393000A34001528F840038A740015AAF40016074
-:10394000A7400158AF4E01540A000215AF4201785A
-:103950008F490E14AF4901448F430E1C0A00028E9A
-:10396000240200403C0E20FF27BDFFE03C1A8000EF
-:103970003C0F800835CDFFFDAFBF001CAFB2001873
-:10398000AFB10014AFB00010AF8F0040AF4D0E00CC
-:103990000000000000000000000000000000000027
-:1039A000000000003C0C00FF358BFFFDAF4B0E000C
-:1039B0003C0660048CC95000240AFF7F3C11600063
-:1039C000012A40243507380CACC750008E24043837
-:1039D00024050009AF4500083083FFFF38622F71CE
-:1039E0002450C0B3AF8000480E000068AF800000D4
-:1039F00052000001AE20442C0E0004353C11800022
-:103A00000E000ED9363000708F8A00403C1208003C
-:103A100026523C88020088218E0800008F5F00003B
-:103A20003BF900013338000113000017AF88003064
-:103A3000022048218D2700003C0F08008DEF006C0C
-:103A40003C0C08008D8C006800E8C02301F8282198
-:103A50000000682100B8302B018D582101664021FB
-:103A60003C010800AC25006C3C010800AC28006853
-:103A70008F44000038830001306200011440FFEDE4
-:103A800000E04021AF8700308E0C00003C050800AC
-:103A90008CA5006C3C0408008C84006801883023ED
-:103AA00000A638210000102100E6402B00821821DA
-:103AB0000068F8213C010800AC27006C3C010800BC
-:103AC000AC3F00688F49010025590088AF99004438
-:103AD000AF890038AF4900208E070000AF87003063
-:103AE0008F4D017805A0FFFE000000008E0600004B
-:103AF0003C0B08008D6B00743C0408008C84007043
-:103B000000C728230165F8210000102103E5402BA0
-:103B10000082382100E8C821240908003C0108007F
-:103B2000AC3F00743C010800AC390070AF4901782B
-:103B300093580108A398003E938F003E31EE000198
-:103B400015C000158F830038240E0D00106E00196B
-:103B5000240F0F00106F001D00000000915900009D
-:103B600024180050332900FF113800043C1F400086
-:103B7000AF5F01380A0002E7000000000E00090EE6
-:103B8000000000008F8A00403C1F4000AF5F0138FA
-:103B90000A0002E700000000938D003E31AC0006F1
-:103BA000000C51000E0000CE0152D8210A00034340
-:103BB0008F8A00403C1B0800277B3D080E0000CE8A
-:103BC000000000000A0003438F8A00403C1B0800ED
-:103BD000277B3D280E0000CE000000000A000343B2
-:103BE0008F8A004090AA00018FAB00108CAC0010AF
-:103BF0003C0300FF8D680004AD6C00208CAD001408
-:103C000000E060213462FFFFAD6D00248CA7001836
-:103C10003C09FF000109C024AD6700288CAE001CE0
-:103C20000182C82403197825AD6F0004AD6E002C05
-:103C30008CAD0008314A00FFAD6D001C94A9000254
-:103C40003128FFFFAD68001090A70000A5600002BA
-:103C5000A1600004A167000090A30002306200FF91
-:103C60000002198210600005240500011065000E95
-:103C70000000000003E00008A16A00018CD80028C1
-:103C8000354A0080AD7800188CCF0014AD6F001459
-:103C90008CCE0030AD6E00088CC4002CA16A0001EF
-:103CA00003E00008AD64000C8CCD001CAD6D001865
-:103CB0008CC90014AD6900148CC80024AD680008DC
-:103CC0008CC70020AD67000C8CC200148C8300648C
-:103CD0000043C82B13200007000000008CC2001412
-:103CE000144CFFE400000000354A008003E00008A7
-:103CF000A16A00018C8200640A00039900000000A0
-:103D000090AA000027BDFFF88FA9001CA3AA0000FD
-:103D10008FAE00003C0FFF808FA8001835E2FFFF38
-:103D20008CCD002C01C26024AFAC0000A1200004A7
-:103D300000E06021A7A000028FB800008D270004DA
-:103D40000188182100A0582100C05021006D2826AC
-:103D50003C06FF7F3C0F00FF2CAD000135EEFFFF5E
-:103D600034D9FFFF3C02FF0003193024000D1DC0B1
-:103D7000010EC82400E2C02400C370250319782571
-:103D8000AD2E0000AD2F00048D450024AFAE000025
-:103D9000AD2500088D4D00202405FFFFAD2D000C42
-:103DA000956800023107FFFFAD27001091660018EB
-:103DB00030C200FF000219C2506000018D4500347E
-:103DC000AD2500148D67000827BD0008AD27001C35
-:103DD0008C8B00CCAD2C0028AD20002CAD2B00240A
-:103DE000AD20001803E00008AD20002027BDFFE053
-:103DF000AFB20018AFB10014AFB00010AFBF001CDD
-:103E00009098000000C088213C0D00FF330F007F18
-:103E1000A0CF0000908E000135ACFFFF3C0AFF00F0
-:103E2000A0CE000194A6001EA22000048CAB0014BA
-:103E30008E29000400A08021016C2824012A40243E
-:103E40000080902101052025A6260002AE24000452
-:103E500026050020262400080E0000762406000215
-:103E600092470000260500282624001400071E00A3
-:103E70000003160324060004044000032403FFFF8C
-:103E8000965900023323FFFF0E000076AE23001088
-:103E9000262400248FBF001C8FB200188FB100149D
-:103EA0008FB0001024050003000030210A000080BC
-:103EB00027BD002027BDFFD8AFB1001CAFB0001850
-:103EC000AFBF002090A80000240200018FB0003C8A
-:103ED0003103003F00808821106200148FAA00384F
-:103EE000240B0005506B0016AFAA001000A0202183
-:103EF00000C028210E0003DC02003021922400BC07
-:103F0000308300021060000326060030ACC00000C1
-:103F100024C600048FBF00208FB1001C8FB0001892
-:103F200000C0102103E0000827BD0028014038210F
-:103F30000E00035AAFB000100A0004200000000079
-:103F40000E0003A1AFB000140A000420000000001E
-:103F50003C02000A034218213C04080024843D6C02
-:103F60002405001A000030210A000080AF830054AD
-:103F70003C038000346200708C48000000A058218F
-:103F800000C04821308A00FFAF8800308F4401789C
-:103F90000480FFFE3C0C8000358600708CC500005C
-:103FA0003C0308008C6300743C1808008F180070F4
-:103FB00000A82023006468210000C82101A4782BF8
-:103FC0000319702101CF60213C010800AC2D007461
-:103FD0003C010800AC2C00708F480E14AF4801441F
-:103FE000AF47014CA34A0152A74B01589346010821
-:103FF00030C5000854A0000135291000934B09007A
-:1040000024070050316A00FF11470007000000003C
-:104010008F450E1CAF450148AF4901543C091000C3
-:1040200003E00008AF490178934D010831A800086A
-:104030001100001000000000934F010831EE001045
-:1040400051C00001352900083C04080090843DD08F
-:10405000A34401508F4309A4AF4301488F4209A0F4
-:10406000AF420144AF4901543C09100003E000088D
-:10407000AF4901783C1908008F393D8C333800086E
-:104080005700FFF1352900080A0004730000000002
-:1040900024070040AF470814AF4008108F4209447E
-:1040A0008F4309508F4409548F45095C8F46094C52
-:1040B000AF820064AF830050AF84004CAF85005CDA
-:1040C00003E00008AF8600609346010930C5007F19
-:1040D000000518C0000521400083102103E00008FE
-:1040E000244200883C09080091293D9124A800023F
-:1040F0003C05110000093C0000E8302500C51825EA
-:1041000024820008AC83000003E00008AC800004B7
-:104110009347010B8F4A002C974F09083C18000E5B
-:104120000358482131EEFFFF000E41C0AF48002C7C
-:1041300097430908952C001A0080402124030001B0
-:10414000318BFFFFAC8B00008D2D001C00A058218F
-:1041500000C06021AC8D00048D24002030E70040B9
-:10416000AD04000891220019304400031083004878
-:104170002885000214A00062240600021086005662
-:1041800024190003109900660000000010E0003AB6
-:10419000000000003C07080094E73D8624E200018F
-:1041A000934F0934934709219525002A31EE00FFEA
-:1041B000000E488230ED00FF978700580009360056
-:1041C000000D1C003044FFFF00C310250044C02533
-:1041D00000A778213C19400003197025000F4C00FE
-:1041E000AD090004AD0E0000934D09203C0300060C
-:1041F00025090014000D360000C32025AD04000879
-:104200008F59092C24E5000130A27FFFAD19000C65
-:104210008F580930A782005825020028AD180010D9
-:104220008F4F0938AD0F0014AD2B00048F4E09409D
-:10423000AD2E0008934D09373C05080090A53D9030
-:104240008F4409488F46094031A700FF00EC182130
-:10425000008678230003C7000005CC000319602501
-:1042600031E8FFFC01885825AD2B000CAD20001073
-:1042700003E00008AF4A002C3C0D080095AD3D86D8
-:104280003C0E080095CE3D800A0004C901AE102105
-:104290003C05080094A53D8A3C06080094C63D8074
-:1042A0003C18080097183D7C952E002400A6782124
-:1042B00001F86823000E240025A2FFF200821825D1
-:1042C00024190800AD03000CAD190014AD00001056
-:1042D0000A0004C425080018952600249525002806
-:1042E0000006C40000057C00370E810035ED080093
-:1042F000AD0E000CAD0D00100A0004C4250800141A
-:104300001480FFA200000000952400240004140083
-:1043100034430800AD03000C0A0004C42508001053
-:104320003C03080094633D8A3C05080094A53D8049
-:104330003C06080094C63D7C953900249538002839
-:10434000006520210086782300196C000018740095
-:1043500025E2FFEE01C2202535A3810024190800C3
-:10436000AD03000CAD040010AD190018AD00001431
-:104370000A0004C42508001C03E00008240201F41C
-:1043800027BDFFE8AFB00010AFBF00140E00006003
-:104390000080802124050040AF4508148F83005021
-:1043A0008F84004C8F85005C0070182100641023FE
-:1043B00018400004AF830050AF6300548F66005470
-:1043C000AF86004C1200000C000000008F44007407
-:1043D000936800813409FA002D07000710E00005FA
-:1043E00000891021936C0081240B01F4018B50048F
-:1043F00001441021AF62000C8F4E095C01C5682397
-:1044000019A000048FBF00148F4F095CAF8F005CB0
-:104410008FBF00148FB000100A00006227BD001883
-:104420008F8400648F8300508F82004CAF640044FF
-:10443000AF63005003E00008AF6200543C0380000B
-:10444000346200708C43000027BDFFF8308700FF06
-:1044500030A900FF30C800FFAF8300308F440178DF
-:104460000480FFFE3C028000345900708F38000049
-:10447000A3A700033C0708008CE700748FAC000082
-:104480003C0608008CC60070030378233C0E7FFFB7
-:1044900000EFC82135CDFFFF00005021018D2824F9
-:1044A00000CA1821000847C0032F202B00A81025A0
-:1044B0000064C021AFA200003C010800AC390074C8
-:1044C0003C010800AC380070934F010AA3A0000221
-:1044D0003C0E80FFA3AF00018FAC0000312B007FAA
-:1044E00035CDFFFF018D4824000B5600012A4025E1
-:1044F000240730002406FF803C05100027BD00087B
-:10450000AF48014CAF470154A7400158A3460152A0
-:1045100003E00008AF45017827BDFFE8AFBF0014F6
-:10452000AFB000108F6500743C068000309000FF33
-:1045300000A620250E000060AF64007493630005A0
-:10454000346200080E000062A36200050200202110
-:104550008FBF00148FB00010240500052406000151
-:104560000A00057027BD001827BDFFE03C0380004E
-:10457000AFB00010AFBF0018AFB1001434620070CC
-:104580008C470000309000FF30A800FFAF8700305C
-:104590008F4401780480FFFE3C18800037110070C2
-:1045A0008E2F00003C0D08008DAD00743C0A080001
-:1045B0008D4A007001E7702301AE282100005821C8
-:1045C00000AE302B014B4821012638213C01080068
-:1045D000AC250074000088213C010800AC27007065
-:1045E0001100000F000000008F6200742619FFFF09
-:1045F0003208007F0002FE0233E5007F150000064E
-:10460000332200FF2407FF800207202624A3FFFF98
-:1046100000838025320200FF004080212411100811
-:104620000E000060000000008F49081831250004CA
-:1046300014A0FFFD3218007F001878C000187140E8
-:1046400001CF682125AC0088AF4C0818274A0980A3
-:104650008D4B0020AF4B01448D460024AF460148EE
-:10466000A35001500E000062A74001580220102103
-:104670008FBF00188FB100148FB0001003E0000846
-:1046800027BD002027BDFFE8308400FFAFBF00102A
-:104690000E0005BB30A500FF8F8300508FBF0010B8
-:1046A000344500402404FF903C02100027BD001850
-:1046B000AF43014CA3440152AF45015403E000084D
-:1046C000AF4201789343093E306200081040000D6C
-:1046D0003C0901013528080AAC8800008F470074A6
-:1046E000AC8700043C06080090C63D9030C5001021
-:1046F00050A00006AC8000088F6A0060AC8A0008F9
-:104700002484000C03E00008008010210A00062227
-:104710002484000C27BDFFE8AFBF0014AFB0001029
-:104720009346093F00A050210005288000853823CA
-:1047300030C200FF240300063C09080095293D868D
-:1047400024E8FFD8240500041043003724060002A3
-:104750009750093C3C0F020400063400320EFFFF64
-:1047600001CF6825AC8D0000934C093E318B0020B1
-:104770001160000800000000934309363C02010369
-:10478000345F0300307900FF033FC0252405000893
-:10479000AC98000493430934935909210005F88229
-:1047A000306200FF0002C082332F00FF00186E004D
-:1047B000000F740001AE6025018920253C094000EE
-:1047C00000898025ACF0FFD8934309378F4F094803
-:1047D0008F580940306200FF004AC821033F702112
-:1047E00001F86023000E6F0001A650253185FFFC03
-:1047F000001F58800145482501683821AD09002077
-:104800000E00006024F00028240400040E00006262
-:10481000A364003F020010218FBF00148FB000106E
-:1048200003E0000827BD00180A0006352406001220
-:1048300027BDFFD024090010AFB60028AFB5002473
-:10484000AFB40020AFB10014AFB000103C010800BD
-:10485000A0293D90AFBF002CAFB3001CAFB2001831
-:1048600097480908309400FF3C02000E3107FFFF13
-:10487000000731C0AF46002C974409089344010B50
-:1048800030B500FF03428021308300300000B021AA
-:104890001060012500008821240C00043C01080060
-:1048A000A02C3D90934B093E000B5600000A2E03AE
-:1048B00004A0016000000000AF400048934F010BCE
-:1048C00031EE002011C00006000000009358093EA0
-:1048D00000189E00001396030640018900000000A6
-:1048E0009344010B30830040106000038F9300500D
-:1048F0008F8200502453FFFF9347093E30E60008A3
-:1049000014C0000224120003000090219619002C0C
-:1049100093580934934F0937A7990058330C00FF77
-:1049200031EE00FF024E6821000D5880016C5021CD
-:10493000015140213C010800A4283D869205001841
-:1049400030A900FF010918213C010800A4233D887B
-:104950009211001816200002000000000000000D57
-:104960003C010800A4233D8A3C010800A4203D80AE
-:104970003C010800A4203D7C935F010B3063FFFFE6
-:1049800033F00040120000022464000A2464000B8B
-:104990003091FFFF0E00009E022020219358010B52
-:1049A0003C08080095083D8A0040202100185982E3
-:1049B000316700010E00049A01072821934C010B76
-:1049C0008F4B002C974E09083C0F000E034F4021DF
-:1049D00031CDFFFF000D51C0AF4A002C97430908AD
-:1049E0009505001A004038212404000130A9FFFF7A
-:1049F000AC4900008D06001C00404821318A00406F
-:104A0000AC4600048D020020ACE2000891030019BE
-:104A100030630003106400EC2879000217200118AD
-:104A2000241000021070010C241F0003107F011ECF
-:104A300000000000114000DE000000003C090800FA
-:104A400095293D8625220001935F0934934E092163
-:104A50009504002A33F900FF0019C08231CF00FF0E
-:104A6000978E005800184600000F6C00010D80253D
-:104A70003045FFFF02051025008E50213C03400009
-:104A800000433025000A6400ACEC0004ACE60000F2
-:104A9000935F09203C19000624EC0014001FC60097
-:104AA00003197825ACEF00088F48092C25CD0001AB
-:104AB00031A57FFFACE8000C8F500930A785005866
-:104AC00024E80028ACF000108F4409380100802150
-:104AD000ACE40014AD9300048F530940AD9300087B
-:104AE000934A09373C19080093393D908F43094890
-:104AF0008F460940314200FF0052F82100667023C2
-:104B0000001F7F000019C40001F8282531CDFFFCEB
-:104B100000AD2025AD84000CAD800010AF4B002C03
-:104B2000934B093E317300081260000D3C060101F1
-:104B300034CC080AACEC00288F530074AD13000489
-:104B40003C0B0800916B3D903167001050E0000372
-:104B5000AD0000088F6A0060AD0A00082510000C47
-:104B600012C0003D000000009343093F24160006D8
-:104B700024060004306200FF105600C9240700021A
-:104B80009758093C3C0F0204330DFFFF01AF40254D
-:104B9000AE0800009345093E30A4002010800008B4
-:104BA00000000000935309363C0B0103357F0300DE
-:104BB000327900FF033F7025AE0E00042406000882
-:104BC000934F093493480921312AFFFF31ED00FF4B
-:104BD000000D1082310300FF0002B60000032C001C
-:104BE00002C56025018A9825001220803C094000FA
-:104BF0000204502302695825AD4BFFD8935F093753
-:104C00008F4F09488F58094033F900FF0332702154
-:104C10000006B08201D668210007440001F828236D
-:104C2000000D1F000068302530A2FFFC2547FFD88B
-:104C300000C260250016808002074821ACEC0020ED
-:104C4000253000280E00006024120004A372003FEB
-:104C50000E000062000000009347010B30F200409C
-:104C6000124000053C1900FF8E180000372EFFFF90
-:104C7000030E3024AE0600000E0000C702202021E3
-:104C80003C10080092103D90321100031220000FDA
-:104C900002A028218F89005025330001AF930050D6
-:104CA000AF7300508F6B00540173F8231BE00002B8
-:104CB000026020218F640054AF6400548F4C007454
-:104CC000258401F4AF64000C02A028210280202179
-:104CD000A76000680E0005BB3C1410008F850050D3
-:104CE00034550006AF45014C8F8A00488FBF002C19
-:104CF0008FB3001C25560001AF9600488FB20018F4
-:104D0000A34A01528FB60028AF5501548FB1001449
-:104D1000AF5401788FB500248FB400208FB00010FD
-:104D200003E0000827BD00309358093E00189E009C
-:104D3000001396030642003624110002934409230F
-:104D4000308300021060FEDD8F8600608F8200508D
-:104D500014C2FEDA000000000E0000600000000037
-:104D60009369003F24070016312800FF1107000C4B
-:104D7000240500083C0C0800918C3D90358B000107
-:104D80003C010800A02B3D90936A003F314300FF97
-:104D900010650065240D000A106D005E2402000CF1
-:104DA0000E000062000000000A00069000000000F3
-:104DB0003C09080095293D863C0A0800954A3D803B
-:104DC0000A0006F3012A10213C09080095293D8AB2
-:104DD0003C04080094843D803C06080094C63D7C59
-:104DE00095030024012410210046F8230003CC0081
-:104DF00027F0FFF20330C025240F0800ACF8000CA8
-:104E0000ACEF0014ACE000100A0006EE24E7001836
-:104E10003C010800A0313D90935F093E241600013B
-:104E200033F900201720FEA5241100080A0006907F
-:104E3000241100048F6E00848F4D094011A0FE9E46
-:104E4000AF8E0050240F00143C010800A02F3D90AD
-:104E50000A00068F00000000950E0024950D002822
-:104E6000000E6400000D2C003589810034A6080076
-:104E7000ACE9000CACE600100A0006EE24E70014D2
-:104E80001460FEEC000000009502002400021C00EB
-:104E900034640800ACE4000C0A0006EE24E70010BD
-:104EA0000A000741240700123C02080094423D8A90
-:104EB0003C06080094C63D803C03080094633D7C9A
-:104EC00095100024951900280046F82103E3C0231B
-:104ED00000106C0000197400270FFFEE01CF282589
-:104EE00035AC8100ACEC000CACE5001024070800E8
-:104EF000AD2700182527001C0A0006EEAD2000147F
-:104F00008F7F004CAF7F00548F7900540A000699C0
-:104F1000AF790050A362003F0E0000620000000065
-:104F20000A00069000000000240200140A0008276E
-:104F3000A362003F27BDFFE8308400FFAFBF001031
-:104F40000E0005BB30A500FF9378007E9379007FAB
-:104F5000936E00809368007A332F00FF001866007C
-:104F6000000F6C0031CB00FF018D4825000B520073
-:104F70008FBF0010012A3825310600FF344470002D
-:104F800000E628252402FF813C03100027BD0018FD
-:104F9000AF45014CAF440154A342015203E0000865
-:104FA000AF43017827BDFFD8AFB20018AFB10014EE
-:104FB000AFB00010AFBF0020AFB3001C9342010997
-:104FC000308600FF30B000FF000618C23204000235
-:104FD0003071000114800005305200FF9367000516
-:104FE00030E5000810A0000D30C80010024020215C
-:104FF0000E0005A702202821240400018FBF0020F5
-:105000008FB3001C8FB200188FB100148FB0001046
-:105010000080102103E0000827BD002815000032A1
-:105020000000000093430109000028213062007F46
-:10503000000220C00002F94003E49821267900888C
-:10504000033B98218E7800248E6F0008130F0046D2
-:10505000000000008F640084241800020004FD8218
-:1050600033F900031338007C0000000093660083CE
-:10507000934A0109514600043205007C10A00060EB
-:10508000000000003205007C14A0005302402021E3
-:1050900016200006320400018E7F00248F5901047F
-:1050A00017F9FFD600002021320400011080000A09
-:1050B000024020218F4209408F9300641053000664
-:1050C000000000000E00066D022028218F430940D9
-:1050D000AF630044024020210E0006020220282176
-:1050E0000A000860240400013C0908008D290064BE
-:1050F000252600013C010800AC26006416000012C1
-:10510000000000008F6D00843C0E00C001AE6024E2
-:1051100015800005024020210E00082E02202821C3
-:105120000A00086024040001240500040E00057034
-:1051300024060001024020210E00082E0220282112
-:105140000A000860240400010E000041240400014C
-:10515000936B007D020B50250E000062A36A007D58
-:105160000A0008A38F6D00848F6600748F480104C5
-:105170008E67002400064E021507FFB63126007F19
-:10518000936B008326440001308A007F1146004360
-:10519000316300FF5464FFB08F6400842645000132
-:1051A00030B1007F30A200FF122600042405000168
-:1051B000004090210A00087624110001240FFF808E
-:1051C000024F702401CF9026324200FF0040902110
-:1051D0000A000876241100010E00066D0220282125
-:1051E000321800301300FFAA321000820240202142
-:1051F0000E0005A7022028210A00086024040001EF
-:105200008F6E00743C0F80002405000301CF9025B1
-:10521000AF72007493710083240600010E000570C4
-:10522000322400FF0E00004124040001936D007D34
-:10523000020D60250E000062A36C007D3C0B08008F
-:105240008D6B0054257000013C010800AC30005407
-:105250000A000860240400018F6800743C09800083
-:105260002405000401093825AF67007493630083A7
-:10527000240600010E000570306400FF0E0000419E
-:10528000240400019362007D020298250E00006252
-:10529000A373007D0A00086024040001324D0080E1
-:1052A00039AC0080546CFF6C8F6400840A0008C91C
-:1052B0002645000127BDFFC83C0A0008AFBF0030EB
-:1052C000AFB5002CAFB40028AFB30024AFB20020BC
-:1052D000AFB1001CAFB00018034AD8212409004028
-:1052E000AF490814AF4008108F4209448F4309505A
-:1052F0008F4609548F47095C8F48094C9344010835
-:105300009345010BAF820064308400FF30A500FF9D
-:10531000AF830050AF86004CAF87005C0E00084A98
-:10532000AF8800601440017D8FBF0030A760006827
-:10533000934D0900240B00503C15080026B53D484C
-:1053400031AC00FF3C12080026523D58118B00037F
-:10535000000000000000A8210000902193510109E5
-:105360008F9F005024040010322E007F000E68C072
-:10537000000E6140018D282124B40088AF54081824
-:105380008F4901048F4A09A43C0B000E034BC02136
-:10539000012A10233C010800AC223D6C8F430958C0
-:1053A0003C010800A0243D9097470908007F302366
-:1053B0003C010800AC263D7030E8FFFF0008C9C082
-:1053C0003C010800AC3F3D94AF59002C97420908BE
-:1053D0009710002C8EB10000930F001803749821D1
-:1053E000A7900058AF9300440220F80931F000FF65
-:1053F000304E000215C001B2304F000111E0014FE4
-:10540000000000009343093E3066000814C000020B
-:10541000241400030000A0218F5809A424130001C4
-:105420003C010800AC383D98934F0934935109373B
-:1054300031EC00FF322E00FF028E6821000D288023
-:1054400000AC5021015058213C010800A42B3D889C
-:105450003C010800A42A3D8693490934312200FF0B
-:1054600002022021249000103C010800A4303D8459
-:10547000240700068F9F00503C010800AC273D8C9C
-:105480008F88005C8F59095800008021011F282354
-:1054900004A00149033F20230480014700A4302BCE
-:1054A00010C00149000000003C010800AC253D701F
-:1054B0008E4200000040F809000000003043000266
-:1054C000146000F80040882130440001548000102E
-:1054D0008E4200043C0908008D293D743C0AC0003E
-:1054E000012A8025AF500E008F45000030AB000828
-:1054F0001160FFFD00000000974D0E082410000110
-:10550000A78D003C8F4C0E04AF8C00348E420004FB
-:105510000040F8090000000002228825322E000217
-:1055200015C00180000000003C09080095293D7C61
-:105530003C06080094C63D883C0A0800954A3D7E1A
-:105540003C1908008F393D74012660213C18080081
-:105550008F183D983C03080094633D92018A2021F6
-:105560008F4E09400329F821248F000203E32821EC
-:10557000031968213C010800A42C3D8AAF8E006409
-:105580003C010800AC2D3D983C010800A4253D805D
-:105590000E00009E31E4FFFF8F870048004020216D
-:1055A0003C010800A0273D918E42000824E800013C
-:1055B000AF8800480040F809000000009344010B48
-:1055C0008F4C002C974A09083C0B000E034B4021DE
-:1055D0003149FFFF000919C08F8B0050AF43002CE9
-:1055E000974309089506001A00403821308A004088
-:1055F00030DFFFFFAC5F00008D19001C0040482128
-:10560000AC5900048D180020AC580008910F001907
-:1056100031E30003107300F0000000002862000274
-:105620001440010924050002106500FD240D00034B
-:10563000106D010D00000000114000D900000000B5
-:105640003C0A0800954A3D8625420001934D0934E5
-:1056500093580921950E002A31A300FF00032082F0
-:10566000331F00FF9798005800047E00001FCC00F5
-:1056700001F940253049FFFF0109102501D83021EB
-:105680003C0540000045502500066C00ACED0004D0
-:10569000ACEA0000934309203C04000624ED00140A
-:1056A0000003FE0003E4C825ACF900088F49092C6B
-:1056B000270F000131EE7FFFACE9000C8F48093065
-:1056C000A78E005824E90028ACE800108F4509385F
-:1056D00001204021ACE50014ADAB00048F4209402D
-:1056E000ADA20008934B09373C1F080093FF3D9083
-:1056F0008F4309488F4A0940316600FF00D42021BA
-:10570000006A78230004C700001FCC000319282575
-:1057100031EEFFFC00AE1025ADA2000CADA00010D4
-:10572000AF4C002C934C093E318B00085160000FA8
-:105730008E58000C3C06010134CA080AACEA002865
-:105740008F4B0074AD2B00043C0C0800918C3D90F5
-:105750003187001050E00003AD2000088F62006028
-:10576000AD2200082528000C8E58000C0300F80913
-:10577000010020213C19080097393D8A3C1F080090
-:1057800097FF3D7E033F782125E900020E0000C708
-:105790003124FFFF3C0E08008DCE3D6C3C08080014
-:1057A0008D083D7401C828233C010800AC253D6CE0
-:1057B00014A00006000000003C0308008C633D8C30
-:1057C000346400403C010800AC243D8C12000070A1
-:1057D0008F8C00448F470E108F900044AE0700203E
-:1057E0008F4D0E18AE0D00243C10080096103D8021
-:1057F0000E0000600000000024020040AF420814C8
-:105800008F8600508F8A004C00D01821006A5823E0
-:1058100019600004AF830050AF6300548F650054DB
-:10582000AF85004C1200000C000000008F44007493
-:10583000936800813409FA002D0E000711C000059D
-:1058400000891821937F0081241901F403F9780459
-:1058500001E41821AF63000C8F44095C8F83005C66
-:105860000083C0231B000003000000008F50095C70
-:10587000AF90005C0E000062000000008F8C0050B2
-:105880008E4700103C010800AC2C3D9400E0F80964
-:10589000000000003C0D08008DAD3D6C55A0FEF5EC
-:1058A000240700068F450024975909088F8B006450
-:1058B0008F9400503C0F001F978200588F86005431
-:1058C0008F93004C3328FFFF35E9FF8000A9502457
-:1058D000000871C032320100AF4E0024A4C2002C77
-:1058E000AF4A0024AF6B0044AF740050AF73005454
-:1058F0001640008032380010570000868EA4000445
-:10590000322300405460001B8EB100088EB0000CA2
-:105910000200F809000000008FBF00308FB5002C96
-:105920008FB400288FB300248FB200208FB1001CE9
-:105930008FB0001803E0000827BD00389347010925
-:105940008F8800380007FE0003E8C825AF590080A3
-:105950008F5809A08F5309A4AFB80010AF580E1488
-:105960008FB40010AF540E10AF530E1C0A00096222
-:10597000AF530E180220F809000000008EB0000C92
-:105980000200F809000000000A000AA88FBF0030DA
-:10599000A5800020A59300220A000A5BAD93002495
-:1059A0003C09080095293D863C06080094C63D80C8
-:1059B0000A0009F4012610213C010800AC203D70CA
-:1059C0000A00098E8E4200003C010800AC243D70A4
-:1059D0000A00098E8E4200003C03080094633D8A51
-:1059E0003C04080094843D803C1F080097FF3D7CE8
-:1059F000951800240064C821033F782300186C0028
-:105A000025EEFFF201AE2825AC45000C240208006B
-:105A1000ACE20014ACE000100A0009EF24E7001823
-:105A200095060024950900280006240000091C00A2
-:105A3000349F810034790800ACFF000CACF90010F1
-:105A40000A0009EF24E700141460FEFB00000000C8
-:105A50009518002400187C0035EE0800ACEE000C10
-:105A60000A0009EF24E700103C07080094E73D8096
-:105A70003C04080094843D8A3C03080094633D7C08
-:105A800095190024951800280087F82103E378234E
-:105A90002407080000192C0000186C0025EEFFEE0A
-:105AA00001AE302534A28100AD2700182527001C47
-:105AB000AD22000CAD2600100A0009EFAD20001445
-:105AC00093520109000028210E000602324400FF13
-:105AD0008FBF00308FB5002C8FB400288FB3002407
-:105AE0008FB200208FB1001C8FB0001803E00008B7
-:105AF00027BD0038935F010933E400FF0E00066DF7
-:105B000000002821323800105300FF7E322300406D
-:105B10008EA400040080F809000000000A000AA218
-:105B2000322300401200FF5F000000008F540E146B
-:105B30008F920044AE5400208F530E1C0A000A8A34
-:105B4000AE5300248F82001C008040213C040100E1
-:105B50009047008530E3002010600009000000003D
-:105B60003C0708008CE73D948F83001800E3202356
-:105B7000048000089389000414E30003010020213D
-:105B800003E00008008010213C04010003E000084D
-:105B9000008010211120000B006738238F8C00201B
-:105BA00024090034918B00BC316A0002514000018D
-:105BB0002409003000E9682B15A0FFF10100202125
-:105BC00000E938232419FFFC00B9C02400F9782427
-:105BD00000F8702B15C0FFEA01E8202130C2000355
-:105BE0000002182314C000123069000300003021A5
-:105BF00000A9702101C6682100ED602B1180FFE033
-:105C00003C0401002D2F00010006482B010538211E
-:105C100001E9302414C0FFDA24E4FFFC2419FFFC5E
-:105C200000B9C0240308202103E0000800801021EF
-:105C30008F8B002024060004916A00BC31440004CC
-:105C40001480FFEC00A970210A000B5E00003021D7
-:105C500027BDFFE8AFBF00108F460100934A01093E
-:105C60003C1F08008FFF00902407FF80314F00FF8A
-:105C700031E8007F0008614003E6C821032CC02101
-:105C800027090120012770243C010800A02F3DD0E6
-:105C9000AF4E080C3C0D08008DAD00903C04008018
-:105CA0003482000301A65821016C182124650120CB
-:105CB00030AA007801424025AF48081C3C1F08006C
-:105CC0008FFF00908F88004003E6C0213319000742
-:105CD00003074824033A7821AF49002825E909C081
-:105CE000952E00023C0D08008DAD008C3C0A08008A
-:105CF0008D4A009031CC3FFF01A61821000C59803D
-:105D0000006B282100A72024AF44002C952200021C
-:105D10003C1F08008FFF008C9107008530593FFF22
-:105D200003E678210019C1800146702101F868213D
-:105D300031CC007F31AB007F019A2821017A5021BC
-:105D40003C03000C3C04000E00A328210144102158
-:105D500030E6002027470980AF82002CAF88001C66
-:105D6000AF890024AF85002010C00006AF8700284F
-:105D70008D0200508CA4010C0044302318C0007721
-:105D800000000000910C0085240DFFDF018D3824F8
-:105D9000A10700858F8B001C8F8900248F87002826
-:105DA0008D65004CAF850018912F000D31EE00205D
-:105DB00011C000170000000024090001A38900049D
-:105DC000AF80000C8CE400248F85000C240A0008AE
-:105DD000AF800008AF8000103C010800A42A3D7E7F
-:105DE0003C010800A4203D920E000B32000030213F
-:105DF0008F8500248FBF0010AF82001490A8000D83
-:105E000027BD00180008394203E0000830E2000115
-:105E1000913F00022418000133F900FF001921828C
-:105E200010980039240800021088005B8F86002C2F
-:105E30008CE5002414A0001B8F9F002091220000FD
-:105E4000240A00053046003F10CA00472404000120
-:105E50008F860008A3840004AF860010AF86000C74
-:105E60008CE400248F85000C240A00083C01080003
-:105E7000A42A3D7E3C010800A4203D920E000B3276
-:105E8000000000008F8500248FBF0010AF82001437
-:105E900090A8000D27BD00180008394203E0000853
-:105EA00030E200018CF800088CF900248FEE00C469
-:105EB000A38000048CE40024AF8E000C8F85000CBE
-:105EC0008F86000803197823240A0008AF8F00107A
-:105ED0003C010800A42A3D7E3C010800A4203D921C
-:105EE0000E000B32000000008F8500248FBF0010D1
-:105EF000AF82001490A8000D27BD00180008394299
-:105F000003E0000830E20001912300003062003F0E
-:105F1000104400278F8500208CE400241480002189
-:105F2000000000008D2E00183C187FFF8F85002098
-:105F3000370FFFFF01CF1824AF8300088F9F0008A1
-:105F40008CA8008403E8C82B1720000203E020215E
-:105F50008CA400840A000BEDAF8400088CA3010C14
-:105F60000A000BCBAF8300188D2C00188F86000819
-:105F70003C0D7FFF8F89002035A3FFFF018358244C
-:105F800024040001AF8B0010AD2000CCA3840004DA
-:105F90000A000BF9AF86000C8CCA00140A000BED46
-:105FA000AF8A00088CA300C80A000C30AF83000839
-:105FB0008F84002C8CAC00648C8D0014018D582BC8
-:105FC00011600004000000008CA200640A000C3084
-:105FD000AF8200088C8200140A000C30AF820008E7
-:105FE0008F85000C27BDFFE0AFBF0018AFB10014D4
-:105FF00014A00007AFB000108F8600242402000513
-:1060000090C400003083003F106200B68F840020EF
-:106010008F91000800A080218F8C00283C0508008B
-:106020008CA53D708D8B000431663FFF00C5502B61
-:106030005540000100C02821938D000411A0007379
-:1060400000B0F82B8F98002024040034930F00BC7C
-:1060500031EE000251C000012404003000A4C82B1E
-:10606000172000D10000000000A4282300B0F82B66
-:106070003C010800A4243D7C17E0006802002021B8
-:106080003C0308008C633D6C0083102B54400001DE
-:10609000008018218F8800243C010800AC233D7447
-:1060A000000048219104000D308300205060000161
-:1060B0008F490E188F8300140123382B10E00059EC
-:1060C000000000003C0408008C843D7400895821C5
-:1060D000006B502B114000560090602B006930235C
-:1060E00000C020213C010800AC263D7412000003D2
-:1060F000241FFFFC1090008A32270003009FC82451
-:106100003C010800AC393D743C010800A4203D92DC
-:106110008F84000C120400078F830020AF910008C9
-:10612000020020218C7100CCAF90000C26300001C1
-:10613000AC7000CC3C0208008C423D748F8A001089
-:10614000240700180082202301422823AF84000C7A
-:1061500010800002AF850010240700108F86001CFD
-:106160003C010800A0273D902407004090CC00850A
-:10617000318B00C0116700408F8D001414A00015F2
-:1061800000002021934A01098F420974314500FF24
-:106190000002260224A300013090007F3071007FAE
-:1061A0001230007A2407FF80A0C300833C09080056
-:1061B0008D293D8C8F880024240D0002352C000889
-:1061C0003C010800A02D3DD13C010800AC2C3D8CC9
-:1061D00024040010910E000D31C6002010C00005EF
-:1061E00000801821240800013C010800AC283D74FF
-:1061F000348300018FBF00188FB100148FB00010DE
-:106200000060102103E0000827BD00203C010800C9
-:10621000A4203D7C13E0FF9A020020210A000C819B
-:1062200000A020213C0408008C843D740090602B69
-:106230001180FFAE000000003C0F080095EF3D7C90
-:1062400001E4702101C6682B11A000072C82000414
-:106250003C1F60008FF954043338003F1700FFE5FE
-:10626000240300422C8200041040FFA024030042BB
-:106270000A000CDF8FBF0018152DFFC000000000C2
-:106280008CDF00743C0380002405FF8003E3C825F5
-:10629000ACD9007490D80085240E000424040010AA
-:1062A000330F003F01E54025A0C800858F880024FA
-:1062B0003C010800A02E3DD1240300019106000DF1
-:1062C00030C9002015200003000000003C03080036
-:1062D0008C633D743C010800AC233D6C0A000CD675
-:1062E000000000008F8700108C88008400E8282BB5
-:1062F00014A0000200E088218C9100842409000190
-:10630000A38900048F440E18022028210E000B32AE
-:1063100002203021022080210A000C67AF82001485
-:1063200000071823306600033C010800A4263D92B4
-:10633000122000058F8C0020918B00BC316A000474
-:106340001540001524CD00043C0F080095EF3D9248
-:1063500001E4702100AE302B50C0FF6E8F84000C22
-:106360002C85000514A0FFA32403004230980003ED
-:1063700017000002009818232483FFFC3C0108004A
-:10638000AC233D740A000CA30000000000A75824B1
-:106390000A000CCB016718263C010800A42D3D9291
-:1063A0000A000D33000000003C010800AC203D74E1
-:1063B0000A000CDE240300428F83001014600007E3
-:1063C000000010218F88002424050005910600009C
-:1063D00030C400FF108500030000000003E0000847
-:1063E00000000000910A0018314900FF000939C27D
-:1063F00014E0FFFA8F85001C3C04080094843D7C67
-:106400003C0308008C633D943C1908008F393D74AF
-:106410003C0F080095EF3D920064C0218CAD005404
-:106420000319702101CF6021018D58231960001DCF
-:1064300000000000910E001C8F8C002C974B0E105A
-:1064400031CD00FF8D850004016D30238D88000063
-:1064500030CEFFFF000E510000AAC82100003821F5
-:1064600001072021032A182B0083C021AD990004C5
-:10647000AD980000918F000A01CF6821A18D000A1C
-:106480008F88002C974B0E12A50B0008950A003838
-:1064900025490001A50900389107000D34E60008E0
-:1064A000A106000D03E000080000000027BDFFE08A
-:1064B000938700048F8F00248FAD00143C0E7FFF64
-:1064C0008F89000C35C8FFFFAFBF001CAFB00018AC
-:1064D00001A8182491EA000D000717C03C1FBFFF58
-:1064E000006258252D2E00018F90001837F9FFFF0C
-:1064F0003C1808008F183D943C0F080095EF3D8A2A
-:1065000001796824000E47803C07EFFF3C05F0FF4F
-:1065100001A818253149002034E2FFFF34ACFFFF09
-:106520000310582327A500102406000225EA0002C4
-:106530000062182400808021152000020000402104
-:106540008F480E1CA7AA0012056000372407000020
-:1065500030FF00FF001FCF008F8B001C0079382513
-:10656000AFA70014916F00853C08080091083D9189
-:106570003C18DFFF31EE00C0370AFFFF000E182B7A
-:106580003C1F080097FF3D8400EA6824A3A800117F
-:106590000003174001A248258FB90010AFA90014CD
-:1065A0003C0A0800914A3D93A7BF00168FA800142B
-:1065B000032CC0243C0B01003C0F0FFF030B1825DC
-:1065C0003147000335EEFFFF010C68240007160079
-:1065D000006EF8243C09700001A2C82503E9582583
-:1065E000AFB90014AFAB00100E000076A3A00015E9
-:1065F0008F8C0024260200089186000D30C40020F4
-:10660000108000068FBF001C3C05080094A53D804B
-:1066100024B0FFFF3C010800A4303D808FB000187B
-:1066200003E0000827BD00208F9800140118502BAC
-:106630005540FFC7240700010A000DB630FF00FFD8
-:106640009382000427BDFFE0AFBF00181040000F89
-:10665000008050218F880024240B00058F890008BA
-:10666000910700008F8400200100282130E3003FC3
-:106670008F86002C106B000800003821AFA9001095
-:106680000E00040EAFAA0014A38000048FBF0018F0
-:1066900003E0000827BD00208D1900183C0F0800FA
-:1066A0008DEF3D748F9800103C027FFF8D08001421
-:1066B000345FFFFF033F682401F8702101AE6023BF
-:1066C00001883821AFA900100E00040EAFAA0014F3
-:1066D0000A000E04A38000048F8700243C050800F4
-:1066E00094A53D923C0208008C423D8C90E6000D42
-:1066F0000005240030C300201060002C0044402519
-:106700008F85001C00006021240B000190A30085F0
-:1067100000004821240A00013C0F800035EE007083
-:106720008DC70000AF8700308F5801780700FFFE4B
-:106730003C038000347900708F3800003C0508006D
-:106740008CA500743C0D08008DAD00700307782304
-:1067500000AF38210000102100EF302B01A22021D2
-:10676000008618213C010800AC2700743C01080099
-:10677000AC230070AF4B01483C1908008F393D94A1
-:10678000A7490144A74A0146AF59014C3C0B0800F8
-:10679000916B3D91A34B0152AF4801543C0810004E
-:1067A000A74C015803E00008AF4801788F4B0E1C3E
-:1067B0003C0A08008D4A3D7497490E16974D0E14F9
-:1067C00001456021312AFFFF0A000E2731A9FFFF92
-:1067D0008F8300249064000D308200201040002937
-:1067E000000000000000482100005021000040216E
-:1067F0003C07800034EB00708D670000AF870030ED
-:106800008F4C01780580FFFE3C0D800035AC007098
-:106810008D8B00003C0508008CA500743C0408002A
-:106820008C8400700167302300A6782100001021BD
-:1068300001E6C82B0082C021031970213C01080029
-:10684000AC2F00743C010800AC2E0070AF49014829
-:106850003C0D08008DAD3D94A7480144240900403B
-:10686000A74A01463C081000240AFF91AF4D014C95
-:10687000A34A0152AF490154A740015803E0000860
-:10688000AF4801788F490E1897460E1297450E10A3
-:1068900030CAFFFF0A000E5D30A8FFFF8F8300247F
-:1068A00027BDFFF89064000D308200201040003AB0
-:1068B00000000000240B000100004821240A000110
-:1068C0003C088000350700708CE30000AF83003087
-:1068D0008F4C01780580FFFE3C0E80003C040800D0
-:1068E00090843DD035C700708CEC00003C0508005A
-:1068F0008CA50074A3A400033C1908008F39007014
-:106900008FAD00000183302300A638210000102144
-:106910000322782100E6C02B01F8602101AE40255A
-:10692000AFA800003C010800AC2700743C0108003F
-:10693000AC2C00709346010A3C04080090843DD1C1
-:10694000A3A00002A3A600018FA300003C0580FFC6
-:106950003099007F34A2FFFF006278240019C6003E
-:1069600001F87025240D3000AF4E014C27BD000802
-:10697000AF4D0154A7400158AF4B0148A74901440E
-:10698000A74A01463C091000240AFF80A34A01528D
-:1069900003E00008AF4901788F4B0E1897460E129E
-:1069A00097450E1030CAFFFF0A000E9130A9FFFF75
-:1069B0008F85001C2402008090A40085308300C0D5
-:1069C000106200058F8600208F8800088F87000CDA
-:1069D000ACC800C8ACC700C403E000080000000059
-:1069E0003C0A0800254A39543C09080025293A2068
-:1069F0003C08080025082DD43C07080024E73B3458
-:106A00003C06080024C637C43C05080024A5353CD4
-:106A10003C040800248431643C0308002463385C8F
-:106A20003C020800244236303C010800AC2A3D50AC
-:106A30003C010800AC293D4C3C010800AC283D4815
-:106A40003C010800AC273D543C010800AC263D64E5
-:106A50003C010800AC253D5C3C010800AC243D58DD
-:106A60003C010800AC233D683C010800AC223D60BD
-:086A700003E000080000000033
-:00000001FF
-/*
- * This file contains firmware data derived from proprietary unpublished
- * source code, Copyright (c) 2004 - 2009 Broadcom Corporation.
- *
- * Permission is hereby granted for the distribution of this firmware data
- * in hexadecimal or equivalent format, provided this copyright notice is
- * accompanying it.
- */
--- /dev/null
+++ zfcpdump-kernel-4.4/firmware/bnx2/bnx2-mips-06-6.2.3.fw.ihex
@@ -0,0 +1,5804 @@
+:10000000080001180800000000004A68000000C84D
+:1000100000000000000000000000000008004A6826
+:100020000000001400004B30080000A00800000091
+:100030000000569400004B44080058200000008443
+:100040000000A1D808005694000001580000A25CEE
+:100050000800321008000000000072F00000A3B495
+:10006000000000000000000000000000080072F026
+:1000700000000024000116A40800049008000400F9
+:10008000000017D4000116C80000000000000000A6
+:100090000000000000000000000000000000000060
+:1000A000080000A80800000000003BFC00012E9C96
+:1000B0000000000000000000000000000000000040
+:1000C00000000000000000000A00004600000000E0
+:1000D000000000000000000D636F6D362E322E33DD
+:1000E0000000000006020302000000000000000300
+:1000F000000000C800000032000000030000000003
+:1001000000000000000000000000000000000000EF
+:1001100000000010000001360000EA600000000549
+:1001200000000000000000000000000000000008C7
+:1001300000000000000000000000000000000000BF
+:1001400000000000000000000000000000000000AF
+:10015000000000000000000000000000000000009F
+:10016000000000020000000000000000000000008D
+:10017000000000000000000000000000000000007F
+:10018000000000000000000000000010000000005F
+:10019000000000000000000000000000000000005F
+:1001A000000000000000000000000000000000004F
+:1001B000000000000000000000000000000000003F
+:1001C000000000000000000000000000000000002F
+:1001D000000000000000000000000000000000001F
+:1001E0000000000010000003000000000000000DEF
+:1001F0000000000D3C02080024424AA03C03080015
+:1002000024634B9CAC4000000043202B1480FFFD76
+:10021000244200043C1D080037BD7FFC03A0F021F0
+:100220003C100800261001183C1C0800279C4AA01E
+:100230000E000168000000000000000D27470100CB
+:1002400090E3000B2402001A94E5000814620028D1
+:10025000000020218CE200003C0308008C63004475
+:1002600094E60014000211C20002104030A4000203
+:10027000005A10212463000130A50004A446008028
+:100280003C010800AC23004410A000190004202BFE
+:100290008F4202B804410008240400013C02080017
+:1002A0008C420060244200013C010800AC22006046
+:1002B00003E00008008010218CE2002094E3001687
+:1002C00000002021AF4202808CE20004A743028498
+:1002D000AF4202883C021000AF4202B83C02080064
+:1002E0008C42005C244200013C010800AC22005C0E
+:1002F00003E00008008010212747010090E3000B75
+:100300002402000394E50008146200280000202164
+:100310008CE200003C0308008C63004494E6001467
+:10032000000211C20002104030A40002005A102145
+:100330002463000130A50004A44600803C010800AD
+:10034000AC23004410A000190004202B8F4202B8F7
+:1003500004410008240400013C0208008C420060B3
+:10036000244200013C010800AC22006003E00008C8
+:10037000008010218CE2002094E300160000202170
+:10038000AF4202808CE20004A7430284AF4202889D
+:100390003C021000AF4202B83C0208008C42005CF4
+:1003A000244200013C010800AC22005C03E000088C
+:1003B000008010218F4301002402010050620003DD
+:1003C000000311C20000000D000311C20002104022
+:1003D000005A1021A440008003E000080000102112
+:1003E0009362000003E00008AF80000003E0000813
+:1003F0000000102103E00008000010212402010089
+:1004000014820008000000003C0208008C4200FC3E
+:10041000244200013C010800AC2200FC0A0000DD7F
+:1004200030A200203C0208008C42008424420001DB
+:100430003C010800AC22008430A2002010400008DB
+:1004400030A300103C0208008C4201082442000145
+:100450003C010800AC22010803E000080000000095
+:1004600010600008000000003C0208008C420104FB
+:10047000244200013C010800AC22010403E0000812
+:10048000000000003C0208008C42010024420001F0
+:100490003C010800AC22010003E00008000000005D
+:1004A00027BDFFE8AFBF0010274401009483000878
+:1004B000306200041040001B306600028F4202B818
+:1004C00004410008240500013C0208008C42006041
+:1004D000244200013C010800AC2200600A0001290E
+:1004E0008FBF00108C82002094830016000028210A
+:1004F000AF4202808C820004A7430284AF4202888C
+:100500003C021000AF4202B83C0208008C42005C82
+:10051000244200013C010800AC22005C0A000129D1
+:100520008FBF001010C00006006028218F4401001A
+:100530000E0000CD000000000A0001282405000183
+:100540008F8200088F4301045043000700002821D8
+:100550008F4401000E0000CD000000008F42010416
+:10056000AF820008000028218FBF001000A01021DA
+:1005700003E0000827BD001827BDFFE8AFBF001447
+:10058000AFB00010974201083043700024022000F1
+:100590001062000B286220011440002F000010217F
+:1005A00024024000106200250000000024026000C8
+:1005B00010620026000010210A0001658FBF0014A0
+:1005C00027500100920200091040001A2403000184
+:1005D0003C0208008C420020104000160000182148
+:1005E0000E00049300000000960300083C0608007B
+:1005F00094C64B5E8E0400188F8200209605000C76
+:1006000000031C0000661825AC440000AC45000443
+:1006100024040001AC400008AC40000CAC400010C9
+:10062000AC400014AC4000180E0004B8AC43001CF1
+:10063000000018210A000164006010210E0003254B
+:10064000000000000A000164000010210E000EE905
+:1006500000000000000010218FBF00148FB00010B8
+:1006600003E0000827BD001827BDFFE0AFB2001867
+:100670003C036010AFBF001CAFB10014AFB000105E
+:100680008C6450002402FF7F3C1A800000822024EA
+:100690003484380C24020037AC6450003C1208004B
+:1006A00026524AD8AF42000824020C80AF420024F0
+:1006B0003C1B80083C06080024C60324024010218D
+:1006C0002404001D2484FFFFAC4600000481FFFDCC
+:1006D000244200043C020800244204B03C0108000B
+:1006E000AC224AE03C020800244202303C010800EF
+:1006F000AC224AE43C020800244201743C03080096
+:100700002463032C3C040800248403D83C0508001F
+:1007100024A538F03C010800AC224B403C02080004
+:10072000244202EC3C010800AC264B243C010800AA
+:10073000AC254B343C010800AC234B3C3C01080089
+:10074000AC244B443C010800AC224B483C0108005F
+:10075000AC234ADC3C010800AC204AE83C0108001C
+:10076000AC204AEC3C010800AC204AF03C010800F7
+:10077000AC204AF43C010800AC204AF83C010800D7
+:10078000AC204AFC3C010800AC204B003C010800B6
+:10079000AC244B043C010800AC204B083C01080091
+:1007A000AC204B0C3C010800AC204B103C01080075
+:1007B000AC204B143C010800AC204B183C01080055
+:1007C000AC264B1C3C010800AC264B203C01080029
+:1007D000AC254B303C010800AC234B380E000623FF
+:1007E000000000003C028000344200708C42000097
+:1007F000AF8200143C0308008C6300208F82000449
+:10080000104300043C0280000E00045BAF83000430
+:100810003C028000344600703C0308008C6300A05A
+:100820003C0208008C4200A4104300048F84001492
+:100830003C010800AC2300A4A743009E8CCA000022
+:100840003C0308008C6300BC3C0208008C4200B8EA
+:100850000144202300641821000040210064202B63
+:1008600000481021004410213C010800AC2300BCCA
+:100870003C010800AC2200B88F5100003222000772
+:100880001040FFDCAF8A00148CC600003C05080055
+:100890008CA500BC3C0408008C8400B800CA30233E
+:1008A00000A628210000102100A6302B0082202164
+:1008B00000862021322700013C010800AC2500BC45
+:1008C0003C010800AC2400B810E0001F32220002F6
+:1008D0008F420100AF4200208F420104AF4200A8C6
+:1008E0009342010B0E0000C6305000FF2E02001E86
+:1008F00054400004001010800E0000C90A000213CA
+:1009000000000000005210218C4200000040F80955
+:1009100000000000104000053C0240008F4301042D
+:100920003C026020AC4300143C024000AF4201385E
+:100930003C0208008C420034244200013C010800C3
+:10094000AC220034322200021040000E3222000499
+:100950008F4201400E0000C6AF4200200E000295FB
+:10096000000000003C024000AF4201783C02080059
+:100970008C420038244200013C010800AC220038BF
+:10098000322200041040FF983C0280008F42018018
+:100990000E0000C6AF4200208F43018024020F00EA
+:1009A00014620005000000008F420188A742009CED
+:1009B0000A0002483C0240009362000024030050F9
+:1009C000304200FF144300083C0240000E00027B4E
+:1009D00000000000544000043C0240000E000D7571
+:1009E000000000003C024000AF4201B83C02080099
+:1009F0008C42003C244200013C010800AC22003C37
+:100A00000A0001C83C0280003C0290003442000110
+:100A100000822025AF4400208F4200200440FFFECA
+:100A20000000000003E00008000000003C0280001D
+:100A3000344200010082202503E00008AF4400207A
+:100A400027BDFFE0AFB10014AFB0001000808821D7
+:100A5000AFBF00180E00025030B000FF9362007D5F
+:100A60000220202102028025A370007D8F70007477
+:100A70003C0280000E000259020280241600000988
+:100A80008FBF00188F4201F80440FFFE24020002CD
+:100A9000AF5101C0A34201C43C021000AF4201F8B3
+:100AA0008FBF00188FB100148FB0001003E0000852
+:100AB00027BD002027BDFFE8AFBF0010974201848B
+:100AC0008F440188304202001040000500002821B8
+:100AD0000E000FAA000000000A00028D240500018C
+:100AE0003C02FF0004800005008218243C02040040
+:100AF000506200019362003E240500018FBF001088
+:100B000000A0102103E0000827BD0018A360002208
+:100B10008F4401400A00025E2405000127BDFFE862
+:100B2000AFBF0014AFB0001093620000304400FF6C
+:100B300038830020388200300003182B0002102B6D
+:100B40000062182410600003240200501482008008
+:100B50008FBF001493620005304200011040007CFA
+:100B60008FBF0014934201482443FFFF2C6200050D
+:100B7000104000788FB00010000310803C03080084
+:100B800024634A68004310218C42000000400008A2
+:100B9000000000000E0002508F4401408F70000CD6
+:100BA0008F4201441602000224020001AF62000CD1
+:100BB0000E0002598F4401408F420144145000043A
+:100BC0008FBF00148FB000100A000F2027BD00183F
+:100BD0008F62000C0A0003040000000097620010FE
+:100BE0008F4301443042FFFF1462001A00000000EE
+:100BF00024020001A76200108F4202380443001053
+:100C00008F4201403C02003F3446F0003C0560004A
+:100C10003C04FFC08CA22BBC0044182400461024C6
+:100C20000002130200031D82106200390000000060
+:100C30008F4202380440FFF7000000008F4201405D
+:100C4000AF4202003C021000AF4202380A00032209
+:100C50008FBF0014976200100A0003040000000018
+:100C60000E0002508F440140976200128F430144EE
+:100C70003050FFFF1603000224020001A762001299
+:100C80000E0002598F4401408F42014416020004B5
+:100C90008FBF00148FB000100A00029127BD00180A
+:100CA000976200120A00030400000000976200141B
+:100CB0008F4301443042FFFF14620006240200010A
+:100CC0008FBF00148FB00010A76200140A00124AF0
+:100CD00027BD0018976200141440001D8FBF001438
+:100CE0000A00031C00000000976200168F430144B5
+:100CF0003042FFFF1462000B240200018FBF00147A
+:100D00008FB00010A76200160A000B1227BD001852
+:100D10009742007824420004A76200100A000322D0
+:100D20008FBF001497620016240300013042FFFFBA
+:100D3000144300078FBF00143C0208008C4200706F
+:100D4000244200013C010800AC2200708FBF001457
+:100D50008FB0001003E0000827BD001827BDFFE892
+:100D6000AFBF0014AFB000108F50010093620000BD
+:100D700093430109304400FF2402001F106200A5C4
+:100D80002862002010400018240200382862000A5F
+:100D90001040000C2402000B286200081040002CB8
+:100DA00000000000046000E52862000214400028F2
+:100DB00024020006106200268FBF00140A00041FE0
+:100DC0008FB000101062005E2862000B144000DC3F
+:100DD0008FBF00142402000E106200738FB0001049
+:100DE0000A00041F00000000106200C028620039E1
+:100DF0001040000A2402008024020036106200CA5B
+:100E000028620037104000B424020035106200C18F
+:100E10008FBF00140A00041F8FB000101062002B57
+:100E20002862008110400006240200C82402003914
+:100E3000106200B48FBF00140A00041F8FB00010AE
+:100E4000106200998FBF00140A00041F8FB00010B9
+:100E50003C0208008C420020104000B98FBF0014F3
+:100E60000E000493000000008F4201008F830020D9
+:100E70009745010C97460108AC6200008F420104BF
+:100E80003C04080094844B5E00052C00AC62000416
+:100E90008F4201180006340000C43025AC620008FF
+:100EA0008F42011C24040001AC62000C9342010A31
+:100EB00000A22825AC650010AC600014AC600018DE
+:100EC000AC66001C0A0003F58FBF00143C0208004A
+:100ED0008C4200201040009A8FBF00140E00049333
+:100EE00000000000974401083C03080094634B5E37
+:100EF0009745010C000422029746010E8F820020C4
+:100F0000000426000083202500052C003C030080FF
+:100F100000A6282500832025AC400000AC4000043A
+:100F2000AC400008AC40000CAC450010AC400014D4
+:100F3000AC400018AC44001C0A0003F42404000177
+:100F40009742010C14400015000000009362000558
+:100F50003042001014400011000000000E0002504A
+:100F6000020020219362000502002021344200107B
+:100F70000E000259A36200059362000024030020C2
+:100F8000304200FF1043006D020020218FBF00148B
+:100F90008FB000100A000FC027BD00180000000D20
+:100FA0000A00041E8FBF00143C0208008C4200207F
+:100FB000104000638FBF00140E0004930000000077
+:100FC0008F4201048F8300209744010C3C050800E8
+:100FD00094A54B5EAC6200009762002C00042400D4
+:100FE0003042FFFF008220253C02400E00A228254F
+:100FF000AC640004AC600008AC60000CAC60001095
+:10100000AC600014AC600018AC65001C0A0003F46E
+:10101000240400010E00025002002021A7600008F5
+:101020000E00025902002021020020210E00025E63
+:10103000240500013C0208008C42002010400040C2
+:101040008FBF00140E000493000000009742010CB3
+:101050008F8300203C05080094A54B5E000214001D
+:10106000AC700000AC620004AC6000088F64004CFF
+:101070003C02401F00A22825AC64000C8F62005087
+:1010800024040001AC6200108F620054AC620014B2
+:10109000AC600018AC65001C8FBF00148FB000104E
+:1010A0000A0004B827BD0018240200205082002541
+:1010B0008FB000100E000F0A020020211040002007
+:1010C0008FBF0014020020218FB0001000002821E3
+:1010D0000A00025E27BD0018020020218FBF001405
+:1010E0008FB000100A00058027BD00189745010C3D
+:1010F000020020218FBF00148FB000100A0005A04D
+:1011000027BD0018020020218FB000100A0005C57D
+:1011100027BD00189345010D020020218FB000105B
+:101120000A00060F27BD0018020020218FBF0014FF
+:101130008FB000100A0005EB27BD00188FBF001408
+:101140008FB0001003E0000827BD00188F4202781E
+:101150000440FFFE2402000234840080AF440240B9
+:10116000A34202443C02100003E00008AF420278B0
+:101170003C04080094844B6A3C0208008C424B7487
+:101180003083FFFF000318C000431021AF42003C32
+:101190003C0208008C424B70AF4200383C020050C9
+:1011A00034420008AF4200300000000000000000A0
+:1011B000000000008F420000304200201040FFFD80
+:1011C000000000008F4204003C010800AC224B608C
+:1011D0008F4204043C010800AC224B643C02002016
+:1011E000AF420030000000003C02080094424B680F
+:1011F0003C03080094634B6C3C05080094A54B6EBF
+:1012000024840001004310213083FFFF3C010800CB
+:10121000A4224B683C010800A4244B6A1465000317
+:10122000000000003C010800A4204B6A03E0000815
+:10123000000000003C05000A27BDFFE80345282107
+:101240003C04080024844B50AFBF00100E00051D65
+:101250002406000A3C02080094424B523C0308005A
+:1012600094634B6E3042000F244200030043180485
+:1012700024027FFF0043102B10400002AF83001CAC
+:101280000000000D0E00042A000000003C020800CF
+:1012900094424B5A8FBF001027BD001803E000088E
+:1012A000A74200A23C02000A034210219443000618
+:1012B0003C02080094424B5A3C010800A4234B56C0
+:1012C000004310238F83001C00021400000214034B
+:1012D0000043102B03E000083842000127BDFFE85F
+:1012E000AFBF00103C02000A0342102194420006E6
+:1012F0003C010800A4224B560E00047700000000B9
+:101300005440FFF93C02000A8FBF001003E00008C0
+:1013100027BD001827BDFFE8AFBF00100E000477FF
+:101320000000000010400003000000000E000485D3
+:10133000000000003C0208008C424B608FBF001090
+:1013400027430400AF4200383C0208008C424B6443
+:1013500027BD0018AF830020AF42003C3C020005CF
+:10136000AF42003003E00008AF8000188F82001801
+:101370003C0300060002114000431025AF4200303C
+:101380000000000000000000000000008F4200008C
+:10139000304200101040FFFD27420400AF820020C1
+:1013A00003E00008AF8000183C0608008CC64B64C0
+:1013B0008F8500188F8300203C02080094424B5A0E
+:1013C00027BDFFE024A50001246300202442000182
+:1013D00024C70020AFB10014AFB00010AFBF001899
+:1013E000AF850018AF8300203C010800A4224B5AAF
+:1013F000309000FF3C010800AC274B6404C100089A
+:101400000000882104E00006000000003C02080003
+:101410008C424B60244200013C010800AC224B602E
+:101420003C02080094424B5A3C03080094634B680A
+:101430000010202B004310262C42000100441025F0
+:10144000144000048F830018240200101462000F5F
+:10145000000000000E0004A9241100013C03080054
+:1014600094634B5A3C02080094424B681462000398
+:10147000000000000E00042A000000001600000317
+:10148000000000000E000493000000003C03080070
+:1014900094634B5E3C02080094424B5C2463000161
+:1014A0003064FFFF3C010800A4234B5E148200035C
+:1014B000000000003C010800A4204B5E1200000662
+:1014C000000000003C02080094424B5AA74200A2D0
+:1014D0000A00050B022010210E0004770000000016
+:1014E00010400004022010210E00048500000000BE
+:1014F000022010218FBF00188FB100148FB0001090
+:1015000003E0000827BD00203084FFFF30A5FFFF67
+:101510000000182110800007000000003082000148
+:101520001040000200042042006518210A00051343
+:101530000005284003E000080060102110C00006EC
+:1015400024C6FFFF8CA2000024A50004AC8200008A
+:101550000A00051D2484000403E0000800000000C8
+:1015600010A0000824A3FFFFAC86000000000000CC
+:10157000000000002402FFFF2463FFFF1462FFFA53
+:101580002484000403E0000800000000240200019D
+:10159000AF62000CA7620010A7620012A7620014DD
+:1015A00003E00008A76200163082007F034210218A
+:1015B0003C08000E004818213C0208008C42002024
+:1015C00027BDFFD82407FF80AFB3001CAFB20018BF
+:1015D000AFB10014AFB00010AFBF00200080802179
+:1015E00030B100FF0087202430D200FF1040002FD0
+:1015F00000009821AF44002C9062000024030050AA
+:10160000304200FF1443000E000000003C020800BE
+:101610008C4200E00202102100471024AF42002C4F
+:101620003C0208008C4200E0020210213042007FA0
+:101630000342102100481021944200D43053FFFF90
+:101640000E000493000000003C02080094424B5E30
+:101650008F8300200011340000C2302500122C00BE
+:101660003C02400000C2302534A50001AC700000EF
+:101670008FBF0020AC6000048FB20018AC7300086C
+:101680008FB10014AC60000C8FB3001CAC6500106F
+:101690008FB00010AC60001424040001AC6000188E
+:1016A00027BD00280A0004B8AC66001C8FBF0020CC
+:1016B0008FB3001C8FB200188FB100148FB00010D0
+:1016C00003E0000827BD00289343010F2402001007
+:1016D0001062000E2865001110A0000724020012FD
+:1016E000240200082405003A1062000600003021A0
+:1016F00003E0000800000000240500351462FFFC30
+:10170000000030210A000538000000008F420074FC
+:1017100024420FA003E00008AF62000C27BDFFE8E1
+:10172000AFBF00100E00025E240500018FBF001045
+:1017300024020001A762001227BD00182402000144
+:1017400003E00008A360002227BDFFE0AFB1001452
+:10175000AFB00010AFBF001830B1FFFF0E00025055
+:10176000008080219362003F24030004304200FF88
+:101770001443000C02002021122000082402000A59
+:101780000E00053100000000936200052403FFFEF7
+:1017900000431024A362000524020012A362003F4C
+:1017A000020020210E000259A360008116200003D0
+:1017B000020020210E0005950000000002002021FB
+:1017C000322600FF8FBF00188FB100148FB00010B9
+:1017D000240500380A00053827BD002027BDFFE09A
+:1017E000AFBF001CAFB20018AFB10014AFB0001013
+:1017F0000E000250008080210E0005310000000024
+:101800009362003F24120018305100FF123200038F
+:101810000200202124020012A362003F936200050F
+:101820002403FFFE004310240E000259A3620005AA
+:10183000020020212405002016320007000030217C
+:101840008FBF001C8FB200188FB100148FB0001032
+:101850000A00025E27BD00208FBF001C8FB2001857
+:101860008FB100148FB00010240500390A0005382C
+:1018700027BD002027BDFFE8AFB00010AFBF0014A8
+:101880009742010C2405003600808021144000108E
+:10189000304600FF0E00025000000000240200123B
+:1018A000A362003F93620005344200100E00053130
+:1018B000A36200050E00025902002021020020212F
+:1018C0000E00025E240500200A000604000000004D
+:1018D0000E000538000000000E000250020020211A
+:1018E000936200232403FF9F020020210043102461
+:1018F0008FBF00148FB00010A36200230A000259AA
+:1019000027BD001827BDFFE0AFBF0018AFB100141E
+:10191000AFB0001030B100FF0E00025000808021F7
+:10192000240200120E000531A362003F0E0002598E
+:101930000200202102002021022030218FBF001848
+:101940008FB100148FB00010240500350A0005384F
+:1019500027BD0020A380002C03E00008A380002DF9
+:101960008F4202780440FFFE8F820034AF42024073
+:1019700024020002A34202443C02100003E00008DB
+:10198000AF4202783C0360008C6254003042000891
+:101990001440FFFD000000008C625408AF82000C70
+:1019A00024020052AC605408AC645430AC6254342D
+:1019B0002402000803E00008AC6254003C0260000E
+:1019C0008C42540030420008104000053C03600087
+:1019D0008C625400304200081440FFFD00000000FB
+:1019E0008F83000C3C02600003E00008AC43540805
+:1019F00090A3000024020005008040213063003FD6
+:101A000000004821146200050000502190A2001C33
+:101A100094A3001E304900FF306AFFFFAD00000CA8
+:101A2000AD000010AD000024950200148D05001CCF
+:101A30008D0400183042FFFF0049102300021100FE
+:101A4000000237C3004038210086202300A2102B5B
+:101A50000082202300A72823AD05001CAD04001838
+:101A6000A5090014A5090020A50A001603E0000836
+:101A7000A50A00228F4201F80440FFFE2402000262
+:101A8000AF4401C0A34201C43C02100003E00008BF
+:101A9000AF4201F83C0208008C4200B427BDFFE8C9
+:101AA000AFBF001424420001AFB000103C01080099
+:101AB000AC2200B48F4300243C02001F30AA00FF78
+:101AC0003442FF8030D800FF006280240080F8217B
+:101AD00030EF00FF1158003B01405821240CFF80DB
+:101AE0003C19000A3163007F000310C00003194055
+:101AF000006218213C0208008C4200DC25680001CD
+:101B0000310D007F03E21021004310213043007F9C
+:101B100003431821004C102400794821AF420024CF
+:101B20008D220024016C1824006C7026AD22000C5C
+:101B30008D220024310800FFAD22001095220014F0
+:101B4000952300208D27001C3042FFFF3063FFFFEC
+:101B50008D2600180043102300021100000227C345
+:101B60000040282100C4302300E2102B00C23023A3
+:101B700000E53823AD27001CAD2600189522002073
+:101B8000A522001495220022154B000AA52200165A
+:101B90008D2300248D220008254600013145008058
+:101BA0001462000430C4007F108F000238AA008045
+:101BB00000C0502151AF000131C800FF1518FFC906
+:101BC000010058218F8400343082007F03421821A5
+:101BD0003C02000A006218212402FF8000822024B7
+:101BE000AF440024A06A0079A06A00838C62005090
+:101BF0008F840034AC6200708C6500743C027FFFFF
+:101C00003442FFFF00A228240E00066BAC6500746E
+:101C1000AF5000248FBF00148FB0001003E0000805
+:101C200027BD001827BDFFC0AFBE0038AFB70034D6
+:101C3000AFB5002CAFB20020AFB1001CAFB00018A0
+:101C4000AFBF003CAFB60030AFB40028AFB3002444
+:101C50008F4500248F4600288F43002C3C02001F34
+:101C60003442FF800062182400C230240080A82182
+:101C7000AFA3001400A2F0240E00062FAFA60010A0
+:101C80003C0208008C4200E02410FF8003608821A1
+:101C900002A2102100501024AF4200243C02080090
+:101CA0008C4200E002A210213042007F0342182142
+:101CB0003C02000A00629021924200D293630084A9
+:101CC000305700FF306300FF24020001106200342F
+:101CD000036020212402000214620036000000008C
+:101CE0000E001216024028219223008392220083C4
+:101CF0003063007F3042007F000210C000031940B3
+:101D0000006218213C0208008C4200DC02A2102173
+:101D10000043382100F01024AF42002892250078BB
+:101D20009224008330E2007F034218213C02000C21
+:101D300014850007006280212402FFFFA24200F107
+:101D40002402FFFFA64200F20A0007272402FFFF39
+:101D500096020020A24200F196020022A64200F262
+:101D60008E020024AE4200F492220083A24200F0D0
+:101D70008E4200C8AE4200FC8E4200C4AE4200F863
+:101D80008E220050AE4201008E4200CCAE420104D1
+:101D9000922200853042003F0A0007823442004010
+:101DA0000E00123902402821922200850A00078283
+:101DB0003042003F936200852403FFDF3042003F42
+:101DC000A36200859362008500431024A36200850E
+:101DD0009363008393620078307400FF304200FF09
+:101DE00010540036240AFF803C0C000C3283007F24
+:101DF000000310C000031940006218213C020800D3
+:101E00008C4200DC268800013109007F02A21021EB
+:101E10000043382130E2007F0342182100EA1024F9
+:101E2000AF420028006C80218E020024028A182410
+:101E3000006A5826AE02000C8E020024310800FF12
+:101E4000AE02001096020014960300208E07001CBC
+:101E50003042FFFF3063FFFF8E060018004310235F
+:101E600000021100000227C30040282100C43023D3
+:101E700000E2102B00C2302300E53823AE07001C1F
+:101E8000AE06001896020020A60200149602002258
+:101E9000A602001692220079304200FF105400077B
+:101EA0000000000051370001316800FF92220078E5
+:101EB000304200FF1448FFCD0100A0219222008390
+:101EC000A22200798E2200500A0007E2AE220070A2
+:101ED000A22200858E22004C2405FF80AE42010C18
+:101EE0009222008534420020A2220085924200D135
+:101EF0003C0308008C6300DC305400FF3C02080007
+:101F00008C4200E400143140001420C002A31821C8
+:101F100000C4202102A210210064382100461021B3
+:101F20000045182400E52824AF450028AF43002CC5
+:101F30003042007F924400D030E3007F03422821EA
+:101F4000034318213C02000C006280213C02000E79
+:101F5000309600FF00A298211296002A000000008F
+:101F60008E02000C02002021026028211040002572
+:101F7000261000280E00064A000000009262000DA4
+:101F800026830001307400FF3042007FA262000D02
+:101F90002404FF801697FFF0267300203C020800FF
+:101FA0008C4200DC0000A02102A210210044102479
+:101FB000AF4200283C0208008C4200E43C030800C9
+:101FC0008C6300DC02A2102100441024AF42002CDC
+:101FD0003C0208008C4200E402A318213063007F19
+:101FE00002A210213042007F034220210343182126
+:101FF0003C02000C006280213C02000E0A0007A493
+:10200000008298218E4200D8AE2200508E4200D825
+:10201000AE22007092250083924600D19223008365
+:10202000924400D12402FF8000A228243063007F64
+:10203000308400FF00A628250064182A10600002E2
+:1020400030A500FF38A50080A2250083A2250079D5
+:102050000E00063D000000009222007E02A020211A
+:10206000A222007A8E2300743C027FFF3442FFFFDD
+:10207000006218240E00066BAE2300748FA20010BD
+:10208000AF5E00248FBF003CAF4200288FBE0038F7
+:102090008FA200148FB700348FB600308FB5002C9C
+:1020A0008FB400288FB300248FB200208FB1001CA2
+:1020B0008FB0001827BD004003E00008AF42002C9D
+:1020C00090A2000024420001A0A200003C030800EE
+:1020D0008C6300F4304200FF1443000F0080302175
+:1020E000A0A000003C0208008C4200E48F84003471
+:1020F000008220213082007F034218213C02000C24
+:10210000006218212402FF8000822024ACC300005A
+:1021100003E00008AF4400288C8200002442002025
+:1021200003E00008AC82000094C200003C080800F4
+:10213000950800CA30E7FFFF008048210102102106
+:10214000A4C2000094C200003042FFFF00E2102B46
+:1021500054400001A4C7000094A200003C03080002
+:102160008C6300CC24420001A4A2000094A20000D1
+:102170003042FFFF544300078F8600280107102BD1
+:10218000A4A000005440000101003821A4C70000B1
+:102190008F8600288CC4001CAF44003C94A2000031
+:1021A0008F43003C3042FFFF000210C00062182144
+:1021B000AF43003C8F42003C008220231880000483
+:1021C000000000008CC200180A00084324420001ED
+:1021D0008CC20018AF4200383C020050344200105C
+:1021E000AF420030000000000000000000000000CE
+:1021F0008F420000304200201040FFFD0000000030
+:102200008F420404AD2200048F420400AD2200007E
+:102210003C020020AF42003003E000080000000054
+:1022200027BDFFE0AFB20018AFB10014AFB000108F
+:10223000AFBF001C94C2000000C080213C12080007
+:10224000965200C624420001A60200009603000038
+:1022500094E2000000E03021144300058FB100300B
+:102260000E000818024038210A000875000000001E
+:102270008C8300048C820004244200400461000727
+:10228000AC8200048C8200040440000400000000C2
+:102290008C82000024420001AC8200009602000003
+:1022A0003042FFFF50520001A600000096220000BD
+:1022B00024420001A62200008F82002896230000FD
+:1022C00094420016144300048FBF001C2402000136
+:1022D000A62200008FBF001C8FB200188FB100141F
+:1022E0008FB0001003E0000827BD00208F89002870
+:1022F00027BDFFE0AFBF00188D220028274804004B
+:1023000030E700FFAF4200388D22002CAF8800304C
+:10231000AF42003C3C020005AF420030000000002C
+:1023200000000000000000000000000000000000AD
+:10233000000000008C82000C8C82000CAD020000BA
+:102340008C820010AD0200048C820018AD020008DF
+:102350008C82001CAD02000C8CA20014AD02001097
+:102360008C820020AD02001490820005304200FFF4
+:1023700000021200AD0200188CA20018AD02001C71
+:102380008CA2000CAD0200208CA20010AD02002433
+:102390008CA2001CAD0200288CA20020AD02002CF3
+:1023A000AD060030AD000034978300263402FFFFF5
+:1023B00014620002006020213404FFFF10E00011CD
+:1023C000AD04003895230036952400362402000120
+:1023D0003063FFFF000318C20069182190650040B8
+:1023E000308400070082100400451025A0620040E0
+:1023F0008F820028944200563042FFFF0A0008DC1A
+:10240000AD02003C952300369524003624020001DD
+:102410003063FFFF000318C2006918219065004077
+:1024200030840007008210040002102700451024A9
+:10243000A0620040AD00003C000000000000000071
+:10244000000000003C02000634420040AF42003071
+:102450000000000000000000000000008F420000AB
+:10246000304200101040FFFD8F860028AF880030FA
+:1024700024C2005624C7003C24C4002824C50032CE
+:1024800024C600360E000856AFA200108FBF0018F9
+:1024900003E0000827BD00208F8300243C060800CD
+:1024A0008CC600E88F82003430633FFF0003198040
+:1024B00000461021004310212403FF803046007F96
+:1024C00000431024AF420028034618213C02000CB0
+:1024D0000062302190C2000D30A500FF00003821BD
+:1024E00034420010A0C2000D8F8900288F8A00247A
+:1024F00095230036000A13823048000324020001AD
+:10250000A4C3000E1102000B2902000210400005B6
+:10251000240200021100000C240300010A0009201B
+:102520000000182111020006000000000A00092026
+:10253000000018218CC2002C0A000920244300014D
+:102540008CC20014244300018CC200180043102BDD
+:1025500050400009240700012402002714A20003B0
+:10256000000000000A00092C240700019522003E0B
+:1025700024420001A522003E000A138230430003DA
+:102580002C62000210400009008028211460000421
+:102590000000000094C200360A00093C3046FFFFEC
+:1025A0008CC600380A00093C008028210000302138
+:1025B0003C04080024844B780A00088900000000CD
+:1025C000274901008D22000C9523000601202021BF
+:1025D000000216023046003F3063FFFF240200274E
+:1025E00000C0282128C7002810C2000EAF83002495
+:1025F00010E00008240200312402002110C200096A
+:102600002402002510C200079382002D0A00095BF6
+:102610000000000010C200059382002D0A00095B33
+:10262000000000000A0008F4000000000A0006266E
+:102630000000000095230006912400058D25000C64
+:102640008D2600108D2700188D28001C8D29002054
+:10265000244200013C010800A4234B7E3C010800F9
+:10266000A0244B7D3C010800AC254B843C010800B4
+:10267000AC264B883C010800AC274B903C0108007D
+:10268000AC284B943C010800AC294B9803E00008AF
+:10269000A382002D8F87002827BDFFC0AFB3003471
+:1026A000AFB20030AFB1002CAFB00028AFBF0038E0
+:1026B0003C0208008C4200D094E3003030B0FFFFB1
+:1026C000005010073045FFFF3063FFFF00C0982126
+:1026D000A7A200103C110800963100C614A3000602
+:1026E0003092FFFF8CE2002424420030AF42003CD5
+:1026F0000A0009948CE2002094E200323042FFFF8D
+:1027000054A2000827A400188CE2002C24420030B8
+:10271000AF42003C8CE20028AF4200380A0009A218
+:102720008F84002827A5001027A60020022038212A
+:102730000E000818A7A000208FA200182442003025
+:10274000AF4200388FA2001CAF42003C8F840028AB
+:102750003C020005AF42003094820034274304005D
+:102760003042FFFF0202102B14400007AF830030FD
+:1027700094820054948300340202102100431023F9
+:102780000A0009B63043FFFF94830054948200345A
+:102790000223182100501023006218233063FFFF2A
+:1027A000948200163042FFFF144300030000000033
+:1027B0000A0009C424030001948200163042FFFF7E
+:1027C0000043102B104000058F82003094820016C9
+:1027D000006210233043FFFF8F820030AC530000B3
+:1027E000AC400004AC520008AC43000C3C020006B4
+:1027F00034420010AF420030000000000000000032
+:10280000000000008F420000304200101040FFFD29
+:10281000001018C2006418219065004032040007BF
+:10282000240200018FBF00388FB300348FB2003014
+:102830008FB1002C8FB000280082100400451025B5
+:1028400027BD004003E00008A062004027BDFFA8AC
+:10285000AFB60050AFB5004CAFB40048AFB30044C2
+:10286000AFB1003CAFBF0054AFB20040AFB00038D2
+:102870008C9000003C0208008C4200E88F860034F7
+:10288000960300022413FF8000C2302130633FFF13
+:102890000003198000C3382100F3102490B2000017
+:1028A000AF42002C9203000230E2007F034230214D
+:1028B0003C02000E00C28821306300C024020040A8
+:1028C0000080A82100A0B021146200260000A021F1
+:1028D0008E3400388E2200181440000224020001B9
+:1028E000AE2200189202000D304200201440001564
+:1028F0008F8200343C0308008C6300DC001238C077
+:10290000001231400043102100C730210046382119
+:1029100030E300073C02008030E6007800C230253A
+:102920000343182100F31024AF4208002463090078
+:10293000AF4608108E2200188C6300080043102157
+:10294000AE2200188E22002C8E2300182442000193
+:102950000062182B1060003D000000000A000A7899
+:1029600000000000920300022402FFC00043102474
+:10297000304200FF1440000524020001AE2200187E
+:10298000962200360A000A613054FFFF8E2200149E
+:1029900024420001AE22001892020000000216003C
+:1029A0000002160304410029000000009602000204
+:1029B00027A4001000802821A7A20016960200027A
+:1029C00024070001000030213042FFFFAF820024C5
+:1029D0000E000889AFA0001C960300023C0408000A
+:1029E0008C8400E88F82003430633FFF000319803D
+:1029F00000441021004310213043007F3C05000CAF
+:102A00000053102403431821AF4200280065182109
+:102A10009062000D001221403042007FA062000D44
+:102A20003C0308008C6300E48F82003400431021D3
+:102A30000044382130E2007F03421021004510217C
+:102A400000F31824AF430028AEA200009222000D2C
+:102A5000304200101040001302A020218F83002874
+:102A60008EA40000028030219462003E2442FFFFC9
+:102A7000A462003E948400029625000E3084FFFF7D
+:102A80000E00097330A5FFFF8F82002894430034A5
+:102A90009622000E1443000302A02021240200010C
+:102AA000A382002C02C028210E0007FE00000000B7
+:102AB0008FBF00548FB600508FB5004C8FB40048C4
+:102AC0008FB300448FB200408FB1003C8FB000380C
+:102AD00003E0000827BD00588F82002827BDFFD0E3
+:102AE000AFB40028AFB20020AFBF002CAFB30024BA
+:102AF000AFB1001CAFB00018904400D0904300D19B
+:102B00000000A021309200FFA3A30010306300FF5B
+:102B10008C5100D88C5300DC1072002B2402000171
+:102B20003C0308008C6300E493A400108F820034FF
+:102B30002406FF800004214000431021004410219E
+:102B40003043007F00461024AF4200280343182181
+:102B50003C02000C006218218C62000427A40014BF
+:102B600027A50010022280210270102304400015C6
+:102B7000AFA300149062000D00C21024304200FF89
+:102B800014400007020088219062000D344200408A
+:102B90000E0007FEA062000D0A000ABD93A20010FD
+:102BA0000E0009E1241400018F830028AC7000D8C6
+:102BB00093A20010A06200D193A200101452FFD87B
+:102BC0000000000024020001168200048FBF002CC8
+:102BD0000E000626000000008FBF002C8FB40028D6
+:102BE0008FB300248FB200208FB1001C8FB000186B
+:102BF00003E0000827BD003027BDFFD8AFB3001C9D
+:102C0000AFB20018AFB10014AFB00010AFBF0020DA
+:102C10000080982100E0802130B1FFFF0E00049376
+:102C200030D200FF000000000000000000000000A3
+:102C30008F820020AC510000AC520004AC5300085D
+:102C4000AC40000CAC400010AC400014AC4000188C
+:102C50003C03080094634B5E02038025AC50001CCB
+:102C6000000000000000000000000000240400013B
+:102C70008FBF00208FB3001C8FB200188FB10014DB
+:102C80008FB000100A0004B827BD002827BDFFE858
+:102C9000AFB00010AFBF001430A5FFFF30C600FF7B
+:102CA0000080802124020C80AF420024000000003C
+:102CB0000000000000000000000000000000000014
+:102CC0000E000ACC000000003C040800248400E050
+:102CD0008C8200002403FF808FBF001402021021A9
+:102CE00000431024AF4200248C8200003C03000A01
+:102CF000020280213210007F035010218FB000109B
+:102D00000043102127BD001803E00008AF8200280F
+:102D100027BDFFE8AFBF00108F4401403C0308000F
+:102D20008C6300E02402FF80AF840034008318210C
+:102D300000621024AF4200243C02000803424021FC
+:102D4000950500023063007F3C02000A034318210E
+:102D50000062182130A5FFFF3402FFFF0000302180
+:102D60003C07602010A20006AF8300282402FFFF6A
+:102D7000A5020002946500D40E000AF130A5FFFF01
+:102D80008FBF001024020C8027BD001803E000084C
+:102D9000AF4200243C020008034240219502000299
+:102DA0003C0A0800954A00C63046FFFF14C00007E1
+:102DB0003402FFFF8F8200288F8400343C0760209C
+:102DC000944500D40A000B5A30A5FFFF10C200241E
+:102DD0008F87002894E2005494E400163045FFFFEA
+:102DE00000A6102300A6182B3089FFFF10600004F6
+:102DF0003044FFFF00C51023012210233044FFFFA1
+:102E0000008A102B1040000C012A1023240200011C
+:102E1000A50200162402FFFFA502000294E500D4DB
+:102E20008F8400340000302130A5FFFF3C07602074
+:102E30000A000AF1000000000044102A10400008B7
+:102E4000000000009502001630420001104000040E
+:102E5000000000009742007E24420014A5020016E4
+:102E600003E00008000000008F84002827BDFFE079
+:102E7000AFBF0018948200349483003E1060001AA3
+:102E80003048FFFF9383002C2402000114620027C6
+:102E90008FBF00188F820028000818C23108000771
+:102EA000006218212447003A244900542444002099
+:102EB000244500302446003490620040304200FF38
+:102EC0000102100730420001104000168FBF0018A9
+:102ED0000E000856AFA900108F82002894420034DB
+:102EE0000A000B733048FFFF94830036948200344D
+:102EF0001043000E8FBF001894820036A482003465
+:102F000094820056A48200548C82002CAC8200244F
+:102F100094820032A48200309482003CA482003A61
+:102F20008FBF00180A000B3327BD002003E0000804
+:102F300027BD002027BDFFE8AFBF00108F4A01006A
+:102F40003C0508008CA500E03C02080090424B8440
+:102F50003C0C0800958C4B7E01452821304B003FEE
+:102F600030A2007F03424021396900323C02000A4E
+:102F70003963003F2C630001010240212D2900012B
+:102F80002402FF8000A2282401234825AF8A0034B0
+:102F900000801821AF450024000030210080282146
+:102FA00024070001AF8800283C04080024844B78E3
+:102FB000AF8C002415200007A380002D24020020E0
+:102FC0005562000F006020213402FFFF5582000C83
+:102FD000006020212402002015620005000000008E
+:102FE0008C6300142402FFFF106200070000000041
+:102FF0000E000889000000000A000BD0000000004D
+:103000000E0008F4016028210E000B68000000008B
+:103010008FBF001024020C8027BD001803E00008B9
+:10302000AF4200243C0208008C4200E027BDFFA014
+:10303000AFB1003C008210212411FF80AFBE0058C8
+:10304000AFB70054AFB20040AFB00038AFBF005CC4
+:10305000AFB60050AFB5004CAFB40048AFB30044BA
+:10306000005110248F4800248F4900288F470028E2
+:10307000AF4200243C0208008C4200E00080902116
+:1030800024060006008210213042007F03421821EE
+:103090003C02000A006280213C02001F3442FF8093
+:1030A00000E2382427A40010260500F00122F024B5
+:1030B0000102B8240E00051DAFA700308FA2001832
+:1030C000AE0200C48FA2001CAE0200C88FA2002472
+:1030D000AE0200CC93A40010920300D12402FF8022
+:1030E0000082102400431025304900FF3083007F08
+:1030F0003122007F0062102A10400004000310C03B
+:1031000001311026304900FF000310C000031940B0
+:10311000006218213C0208008C4200DC920400D2BC
+:10312000024210210043102100511024AF42002818
+:1031300093A300103063007F000310C00003194008
+:10314000006218213C0208008C4200DC024210217F
+:10315000004310213042007F034218213C02000C42
+:10316000006240218FA300142402FFFF1062003090
+:10317000309500FF93A2001195030014304400FF26
+:103180003063FFFF0064182B1060000D000000008A
+:10319000950400148D07001C8D0600183084FFFF75
+:1031A00000442023000421000000102100E4382105
+:1031B00000E4202B00C230210A000C4A00C4302158
+:1031C000950400148D07001C8D0600183084FFFF45
+:1031D000008220230004210000001021008018211B
+:1031E00000C2302300E4202B00C4302300E3382346
+:1031F000AD07001CAD06001893A20011A502001433
+:1032000097A20012A50200168FA20014AD020010B2
+:103210008FA20014AD02000C93A20011A5020020A1
+:1032200097A20012A50200228FA20014AD02002472
+:103230002406FF80024610243256007FAF4200244D
+:10324000035618213C02000A006280218E02004CC5
+:103250008FA200203124007F000428C0AE0200505D
+:103260008FA200200004214000852821AE020070BA
+:1032700093A2001001208821A202008393A20010D3
+:10328000A2020079920200853042003FA20200852E
+:103290003C0208008C4200DC024210210045102153
+:1032A00000461024AF42002C3C0208008C4200E48F
+:1032B0003C0308008C6300DC024210210044102112
+:1032C00000461024AF4200283C0208008C4200E473
+:1032D00002431821006518210242102100441021E8
+:1032E0003042007F3063007F93A50010034220210D
+:1032F000034318213C02000E006240213C02000CF6
+:1033000010B1008C008248213233007F1660001912
+:103310002404FF803C0208008C4200DC02421021A1
+:1033200000441024AF42002C3C0208008C4200E410
+:103330003C0308008C6300DC02421021004410248E
+:10334000AF4200283C0208008C4200E402431821EE
+:103350003063007F024210213042007F034220216F
+:10336000034318213C02000E006240213C02000C85
+:10337000008248219124000D2414FF8000001021B8
+:1033800000942025A124000D950400029505001449
+:103390008D07001C3084FFFF30A5FFFF8D0600184D
+:1033A000008520230004210000E4382100C23021E0
+:1033B00000E4202B00C43021AD07001CAD0600182E
+:1033C00095020002A5020014A50000168D02000857
+:1033D000AD0200108D020008AD02000C9502000243
+:1033E000A5020020A50000228D020008AD020024E5
+:1033F0009122000D30420040104000422622000180
+:103400003C0208008C4200E0A3B300283C10000AF4
+:103410000242102100541024AF4200243C02080054
+:103420008C4200E0A380002C27A4002C0242102133
+:103430003042007F03421821007018218C6200D8AE
+:103440008D26000427A50028AFA9002C00461021D6
+:10345000AC6200D80E0009E1AF83002893A30028D6
+:103460008F8200280E000626A04300D10E000B68B4
+:103470000000000002541024AF4200243C02080067
+:103480008C4200DC00132940001320C000A420213E
+:10349000024210210044102100541024AF42002C9D
+:1034A0003C0208008C4200E43C0308008C6300DC12
+:1034B00003563021024210210045102100541024EF
+:1034C000AF4200283C0208008C4200E4024318216D
+:1034D0000064182102421021004510213042007F73
+:1034E0003063007F03422021034318213C02000E79
+:1034F000006240213C02000C00D080210082482163
+:10350000262200013043007F14750005304400FF7F
+:103510002403FF800223102400431026304400FFC0
+:1035200093A2001000808821250800281444FF760B
+:103530002529002093A400108FA300142402FFFF6C
+:103540001062000A308900FF2482000124830001F8
+:103550003042007F14550005306900FF2403FF80CE
+:103560000083102400431026304900FF92020078A7
+:10357000305300FF11330032012088213C02080043
+:103580008C4200DC3225007F000520C00005294068
+:1035900000A42021024210212406FF8000441021B3
+:1035A00000461024AF42002C3C0308008C6300DC72
+:1035B0003C0208008C4200E4024318210242102120
+:1035C0000045102100641821004610243063007F5C
+:1035D000AF420028034318213C02000E0062402144
+:1035E0003C0208008C4200E48D06000C0100202102
+:1035F00002421021004510213042007F0342182171
+:103600003C02000C0062482110C0000D012028215E
+:103610000E00064A000000002402FF800222182447
+:1036200026240001006228263082007F1455000203
+:10363000308300FF30A300FF1473FFD000608821A7
+:103640008E0300743C027FFF3442FFFF00621824A7
+:10365000AE0300740E00066B02402021AF57002419
+:103660008FA20030AF5E00288FBF005C8FBE005875
+:103670008FB700548FB600508FB5004C8FB4004800
+:103680008FB300448FB200408FB1003C8FB0003840
+:1036900027BD006003E00008AF42002C27BDFFD823
+:1036A000AFB1001CAFBF0020AFB000182751018898
+:1036B000922200032408FF803C03000A3047007F69
+:1036C000A3A700108F4601803C0208008C4200E056
+:1036D000AF86003400C2282100A81024AF42002485
+:1036E0009224000030A2007F0342102100431021E9
+:1036F000AF8200283084007F24020002148200255B
+:10370000000719403C0208008C4200E400C210216E
+:103710000043282130A2007F0342182100A8102472
+:10372000AF4200283C02000C006218219062000D9C
+:10373000AFA3001400481025A062000D8FA3001451
+:103740009062000D304200405040006A8FBF002060
+:103750008F860028A380002C27A400148CC200D8D8
+:103760008C63000427A50010004310210E0009E11E
+:10377000ACC200D893A300108F8200280E0006264A
+:10378000A04300D10E000B68000000000A000E0BE1
+:103790008FBF00200E00062F00C020210E00063D26
+:1037A000000000003C020008034280219223000137
+:1037B0009202007B1443004F8FBF00209222000032
+:1037C0003044007F24020004108200172882000584
+:1037D00010400006240200052402000310820007A6
+:1037E0008FB1001C0A000E0C0000000010820012B5
+:1037F0008FBF00200A000E0C8FB1001C92050083C1
+:10380000920600788E0700748F84003430A500FF84
+:1038100000073E0230C600FF0E00067330E7007F4F
+:103820000A000E0B8FBF00200E000BD78F840034D0
+:103830000A000E0B8FBF002024020C80AF42002430
+:103840009202003E30420040104000200000000084
+:103850009202003E00021600000216030441000618
+:10386000000000008F8400340E0005A024050093A2
+:103870000A000E0B8FBF00209202003F24030018A5
+:10388000304200FF1443000C8F84003424050039BB
+:103890000E000538000030210E0002508F840034E5
+:1038A00024020012A202003F0E0002598F8400344D
+:1038B0000A000E0B8FBF0020240500360E000538CD
+:1038C000000030210A000E0B8FBF00200E000250B6
+:1038D0008F8400349202000534420020A2020005C9
+:1038E0000E0002598F8400340E000FC08F84003404
+:1038F0008FBF00208FB1001C8FB0001824020C80F5
+:1039000027BD002803E00008AF42002427BDFFE8E0
+:10391000AFB00010AFBF001427430100946200084D
+:103920000002140000021403044100020000802180
+:103930002410000194620008304200801040001AF8
+:10394000020010219462000830422000104000164E
+:10395000020010218C6300183C021C2D344219ED2A
+:10396000240600061062000F3C0760213C0208009C
+:103970008C4200D4104000078F8200288F830028DB
+:10398000906200623042000F34420040A062006248
+:103990008F8200288F840034944500D40E000AF1F1
+:1039A00030A5FFFF020010218FBF00148FB0001060
+:1039B00003E0000827BD001827BDFFE0AFB10014E9
+:1039C000AFB00010A380002CAFBF00188F450100DE
+:1039D0003C0308008C6300E02402FF80AF850034C4
+:1039E00000A318213064007F0344202100621824C2
+:1039F0003C02000A00822021AF430024275001002E
+:103A00008E0200148C8300DCAF8400280043102356
+:103A100018400004000088218E0200140E000A8461
+:103A2000AC8200DC9202000B24030002304200FF53
+:103A30001443002F0000000096020008304300FFEE
+:103A40002402008214620005240200840E00093E54
+:103A5000000000000A000E97000000001462000938
+:103A6000240200818F8200288F8400343C0760216B
+:103A7000944500D49206000530A5FFFF0A000E868B
+:103A800030C600FF14620027000000009202000A06
+:103A9000304300FF306200201040000430620040DC
+:103AA0008F8400340A000E82240600401040000477
+:103AB000000316008F8400340A000E8224060041A1
+:103AC00000021603044100178F84003424060042CC
+:103AD0008F8200283C076019944500D430A5FFFF71
+:103AE0000E000AF1000000000A000E97000000001E
+:103AF0009202000B24030016304200FF1043000620
+:103B0000000000009202000B24030017304200FF67
+:103B100014430004000000000E000E11000000001D
+:103B2000004088210E000B68000000009202000A8D
+:103B3000304200081040000624020C808F850028C7
+:103B40003C0400080E0011EE0344202124020C80E6
+:103B5000AF4200248FBF0018022010218FB0001048
+:103B60008FB1001403E0000827BD002027BDFFE847
+:103B7000AFBF0014AFB000108F5000243C0308000A
+:103B80008C6300E08F4501002402FF8000A3182110
+:103B90003064007F03442021006218243C02000AA4
+:103BA00000822021AF850034AF4300249082006260
+:103BB000AF8400283042000F34420050A0820062DF
+:103BC0003C02001F3442FF800E00062602028024C1
+:103BD000AF5000248FBF00148FB0001003E0000826
+:103BE00027BD00183C0208008C4200201040001D38
+:103BF0002745010090A300093C0200080342202150
+:103C000024020018546200033C0200080A000ED887
+:103C10002402000803422021240200161462000539
+:103C20002402001724020012A082003F0A000EE2C4
+:103C300094A700085462000694A700089362000548
+:103C40002403FFFE00431024A362000594A700088C
+:103C500090A6001B8CA4000094A500060A000ACCC4
+:103C600000073C0003E000080000000027440100BA
+:103C700094820008304500FF38A3008238A20084F7
+:103C80002C6300012C420001006218251060000620
+:103C9000240200839382002D1040000D00000000DC
+:103CA0000A000B9B0000000014A2000524A2FF8064
+:103CB0008F4301043C02602003E00008AC43001481
+:103CC000304200FF2C420002104000032402002278
+:103CD0000A000E3C0000000014A2000300000000D7
+:103CE0000A000EA9000000000A000EC70000000034
+:103CF0009363007E9362007A144300090000202140
+:103D00009362000024030050304200FF144300047B
+:103D1000240400019362007E24420001A362007E1D
+:103D200003E00008008010218F4201F80440FFFEEC
+:103D300024020002AF4401C0A34201C43C021000AF
+:103D400003E00008AF4201F827BDFFE8AFBF001055
+:103D50009362003F2403000A304200FF14430046F0
+:103D6000000000008F6300548F62004C1062007DE1
+:103D7000036030219362000024030050304200FFB2
+:103D80001443002F000000008F4401403C02080053
+:103D90008C4200E02403FF800082102100431024A5
+:103DA000AF4200243C0208008C4200E08F650054C2
+:103DB0003C03000A008220213084007F034410214C
+:103DC00000431021AC4501089762003C8F63004C12
+:103DD0003042FFFF0002104000621821AF63005C18
+:103DE0008F6300548F64004C9762003C006418237A
+:103DF0003042FFFF00031843000210400043102A26
+:103E000010400006000000008F6200548F63004CD9
+:103E1000004310230A000F58000210439762003C31
+:103E20003042FFFF00021040ACC2006424020001D7
+:103E3000A0C0007CA0C2008424020C80AF420024F9
+:103E40000E000F0A8F440140104000478FBF001042
+:103E50008F4301408F4201F80440FFFE240200021C
+:103E6000AF4301C0A34201C43C021000AF4201F8BD
+:103E70000A000FA88FBF00109362003F24030010B8
+:103E8000304200FF14430004000000008F44014052
+:103E90000A000F94000028219362003F24030016BB
+:103EA000304200FF1443000424020014A362003FC8
+:103EB0000A000FA2000000008F62004C8F630050C8
+:103EC00000431023044100288FBF0010936200813B
+:103ED00024420001A3620081936200812C4200040D
+:103EE00014400010000000009362003F240300040F
+:103EF000304200FF14430006000000008F440140E0
+:103F00008FBF0010240500930A0005A027BD0018EC
+:103F10008F440140240500938FBF00100A00060F54
+:103F200027BD00188F4401400E0002500000000021
+:103F30008F6200542442FFFFAF6200548F62005032
+:103F40002442FFFFAF6200500E0002598F4401402F
+:103F50008F4401408FBF0010240500040A00025E58
+:103F600027BD00188FBF001003E0000827BD001810
+:103F70008F4201889363007E00021402304400FFE8
+:103F8000306300FF1464000D0000000093620080A5
+:103F9000304200FF1044000900000000A3640080CC
+:103FA0009362000024030050304200FF14430004D9
+:103FB000000000000A0006D78F440180A36400803F
+:103FC00003E000080000000027BDFFE8AFB00010CC
+:103FD000AFBF00149362000524030030304200306C
+:103FE00014430089008080213C0208008C4200209C
+:103FF00010400080020020210E0004930000000009
+:104000008F850020ACB000009362003E9363003FB8
+:10401000304200FF00021200306300FF0043102511
+:10402000ACA2000493620082000216000002160394
+:1040300004410005000000003C0308008C630048B8
+:104040000A000FE6000000009362003E304200408C
+:10405000144000030000182193620081304300FFE8
+:104060009362008200031E00304200FF0002140031
+:1040700000621825ACA300088F620040ACA2000CBF
+:104080008F620048ACA200108F62004CACA20014FA
+:104090008F6200508F63004C0043102304410003E3
+:1040A000000000000A000FFA8F62004C8F6200507F
+:1040B000ACA200183C02080094424B5E3C03C00BCB
+:1040C00000002021004310250E0004B8ACA2001C03
+:1040D0008F6200548F840020AC8200008F620058F1
+:1040E000AC8200048F62005CAC8200088F620060CA
+:1040F0008F43007400431021AC82000C8F62006477
+:10410000AC820010976300689762006A00031C008D
+:104110003042FFFF00621825AC83001493620082D6
+:1041200024030080304200FF14430003000000001D
+:104130000A00102EAC8000188F63000C24020001CE
+:104140001062000E2402FFFF9362003E30420040E6
+:104150001440000A2402FFFF8F63000C8F4200749A
+:10416000006218233C020800006210241440000280
+:10417000000028210060282100051043AC820018AF
+:104180003C02080094424B5E3C03C00C000020211E
+:10419000004310258F8300200E0004B8AC62001C81
+:1041A0008F6200188F8300203C05080094A54B5EA9
+:1041B00024040001AC620000AC6000048F66006C57
+:1041C0003C02400D00A22825AC6600088F6200DC8E
+:1041D000AC62000CAC600010936200050002160097
+:1041E000AC620014AC6000180E0004B8AC65001C92
+:1041F000020020218FBF00148FB00010A3600005C3
+:104200000A00042127BD00188FBF00148FB00010D2
+:1042100003E0000827BD00189742007C30C600FF6D
+:10422000A08600843047FFFF2402000514C2000B63
+:1042300024E3465090A201122C42000710400007D0
+:1042400024E30A0090A30112240200140062100467
+:1042500000E210210A0010663047FFFF3067FFFFC1
+:1042600003E00008A4870014AC87004C8CA201086E
+:104270000080402100A0482100E2102330C600FF4A
+:104280001840000393AA001324E2FFFCACA201082B
+:1042900030C2000110400008000000008D020050F4
+:1042A00000E2102304410013240600058D0200548F
+:1042B00010E20010000000008D02005414E2001A09
+:1042C000000000003C0208008C4200D83042002070
+:1042D0001040000A2402000191030078910200833B
+:1042E000144300062402000101002021012028219E
+:1042F000240600040A00105400000000A1000084FD
+:1043000011400009A50200148F4301008F4201F8FB
+:104310000440FFFE24020002AF4301C0A34201C4D7
+:104320003C021000AF4201F803E00008000000006A
+:1043300027BDFFE88FA90028AFBF001000804021F3
+:1043400000E918231860007330C600FFA080007CCD
+:10435000A08000818CA2010800E210230440004DDF
+:10436000000000008C8200509483003C8C84006428
+:10437000004748233063FFFF012318210083202BCF
+:1043800010800004000000008D0200640A0010B7D5
+:1043900000E210219502003C3042FFFF0122102173
+:1043A00000E21021AD02005C9502003C8D03005C30
+:1043B0003042FFFF0002104000E210210043102BAA
+:1043C00010400003000000000A0010C68D02005CCF
+:1043D0009502003C3042FFFF0002104000E2102135
+:1043E000AD02005CA1000084AD07004C8CA2010866
+:1043F00000E210231840000224E2FFFCACA20108F6
+:1044000030C200011040000A000000008D02005080
+:1044100000E2102304410004010020218D02005419
+:1044200014E20003000000000A0010E82406000562
+:104430008D02005414E200478FBF00103C020800B8
+:104440008C4200D8304200201040000A24020001B3
+:1044500091030078910200831443000624020001B6
+:1044600001002021240600048FBF00100A00105410
+:1044700027BD0018A1000084A50200148F4301008D
+:104480008F4201F80440FFFE240200020A00110DD1
+:10449000000000008C82005C004910230043102BB8
+:1044A00054400001AC87005C9502003C3042FFFFA5
+:1044B0000062102B14400007240200029502003C09
+:1044C0008D03005C3042FFFF00621821AD03005CE9
+:1044D00024020002AD07004CA10200840E000F0A66
+:1044E0008F4401001040001B8FBF00108F4301005C
+:1044F0008F4201F80440FFFE24020002AF4301C0D6
+:10450000A34201C43C021000AF4201F80A0011238B
+:104510008FBF001030C200101040000E8FBF00107F
+:104520008C83005C9482003C006918233042FFFFBA
+:10453000006218213C023FFF3444FFFF0083102B30
+:10454000544000010080182101231021AD02005CBD
+:104550008FBF001003E0000827BD001827BDFFE84B
+:104560008FAA0028AFBF00100080402100EA482336
+:104570001920002130C600FF8C83005C8C8200640F
+:10458000006A18230043102B5040001000691821C6
+:1045900094A2011001221021A4A2011094A20110E2
+:1045A0003042FFFF0043102B1440000A3C023FFF43
+:1045B00094A2011000431023A4A201109482003C95
+:1045C0003042FFFF0A00114200621821A4A001102E
+:1045D0003C023FFF3444FFFF0083102B5440000196
+:1045E0000080182100671021AD02005CA100007C52
+:1045F0000A00118AA100008130C200101040003C66
+:10460000000000008C820050004A1023184000383F
+:10461000000000009082007C24420001A082007C07
+:104620009082007C3C0308008C630024304200FF31
+:104630000043102B1440005C8FBF00108CA20108B7
+:1046400000E2102318400058000000008C83005442
+:104650009482003C006A18233042FFFF0003184395
+:10466000000210400043102A104000050000000026
+:104670008C820054004A10230A001171000210437A
+:104680009482003C3042FFFF00021040AD02006403
+:104690009502003C8D0400649503003C3042FFFF0E
+:1046A00000021040008220213063FFFF00831821A8
+:1046B00001431021AD02005C8D020054ACA2010840
+:1046C00024020002A10200840E000F0A8F440100A0
+:1046D000104000358FBF00108F4301008F4201F85A
+:1046E0000440FFFE240200020A0011B30000000093
+:1046F000AD07004C8CA2010800E210231840000214
+:1047000024E2FFFCACA2010830C200011040000A04
+:10471000000000008D02005000E21023044100045C
+:10472000010020218D02005414E20003000000006B
+:104730000A0011AA240600058D02005414E2001A92
+:104740008FBF00103C0208008C4200D8304200208D
+:104750001040000A240200019103007891020083B6
+:104760001443000624020001010020212406000455
+:104770008FBF00100A00105427BD0018A10000844C
+:10478000A50200148F4301008F4201F80440FFFE90
+:1047900024020002AF4301C0A34201C43C02100046
+:1047A000AF4201F88FBF001003E0000827BD0018DA
+:1047B0008FAA00108C8200500080402130C600FF7C
+:1047C000004A102300A048211840000700E01821EB
+:1047D00024020001A0800084A0A00112A482001481
+:1047E0000A001125AFAA0010A0800081AD07004C7F
+:1047F0008CA2010800E210231840000224E2FFFC12
+:10480000ACA2010830C20001104000080000000006
+:104810008D0200500062102304410013240600059D
+:104820008D02005410620010000000008D02005440
+:1048300014620011000000003C0208008C4200D805
+:10484000304200201040000A240200019103007849
+:10485000910200831443000624020001010020217C
+:1048600001202821240600040A0010540000000042
+:10487000A1000084A502001403E00008000000006D
+:1048800027BDFFE0AFBF0018274201009046000A95
+:104890008C4800148C8B004C9082008430C900FF3F
+:1048A00001681823304A00FF1C60001A2D460006DC
+:1048B000240200010142100410C00016304300031E
+:1048C000012030210100382114600007304C000C19
+:1048D00015800009304200301440000B8FBF0018D3
+:1048E0000A001214000000000E001125AFAB0010EA
+:1048F0000A0012148FBF00180E00109AAFAB001000
+:104900000A0012148FBF0018AFAB00100E0011BACE
+:10491000AFAA00148FBF001803E0000827BD0020D5
+:1049200024020003A08200848C82005403E000086B
+:10493000ACA201083C0200080342182190620081E9
+:10494000240600433C07601924420001A062008154
+:10495000906300813C0208008C4200C0306300FF7D
+:10496000146200102403FF803C0208008C4200E027
+:104970000082102100431024AF4200243C020800B2
+:104980008C4200E03C03000A008210213042007F8C
+:104990000342102100431021944500D40A000AF17B
+:1049A00030A5FFFF03E000080000000027BDFFE086
+:1049B000AFBF0018AFB10014AFB000108F4201803C
+:1049C0000080802100A088210E00121B00402021C1
+:1049D000A20000848E0200548FBF00188FB0001018
+:1049E000AE2201088FB1001403E0000827BD0020AB
+:1049F00027BDFFE03C020008AFB00010AFBF0018B9
+:104A0000AFB10014034280218F5101409203008412
+:104A10008E0400508E02004C14820040306600FF6D
+:104A20003C0208008C4200E02403FF800222102197
+:104A300000431024AF4200243C0208008C4200E0F6
+:104A40009744007C92050081022210213042007FB1
+:104A5000034218213C02000A0062182114A0000B36
+:104A60003084FFFF2402000554C20014248205DCB8
+:104A70009062011224420001A062011224020C8003
+:104A8000AF4200240A00127324020005A060011244
+:104A90002402000514C20009248205DC9202008170
+:104AA0002C4200075040000524820A009203008136
+:104AB0002402001400621004008210213044FFFF21
+:104AC000A60400140E00121B022020219602003CB6
+:104AD0008E03004C022020213042FFFF00021040D4
+:104AE000006218210E000250AE03005C9202007DAD
+:104AF00002202021344200400E000259A202007D13
+:104B00008F4201F80440FFFE24020002AF5101C0B1
+:104B1000A34201C43C021000AF4201F88FBF00184D
+:104B20008FB100148FB0001003E0000827BD0020F3
+:104B300008000ACC08000B1408000B9808000BE4CE
+:104B400008000C200A0000280000000000000000FF
+:104B50000000000D6370362E322E3300000000007E
+:104B60000602030400000000000000000000000036
+:104B70000000000000000000000000000000000035
+:104B80000000000000000000000000000000002005
+:104B90000000000000000000000000000000000015
+:104BA0000000000000000000000000000000000005
+:104BB00000000000000000000000000000000001F4
+:104BC0000000002B000000000000000400030D4066
+:104BD00000000000000000000000000000000000D5
+:104BE00000000000000000001000000300000000B2
+:104BF0000000000D0000000D3C020800244258A4F3
+:104C00003C03080024635F70AC4000000043202B8D
+:104C10001480FFFD244200043C1D080037BD7FFCCA
+:104C200003A0F0213C100800261000A03C1C080046
+:104C3000279C58A40E0001AC000000000000000DED
+:104C400027BDFFE83C096018AFBF00108D2C500055
+:104C5000240DFF7F24080031018D5824356A380C5B
+:104C600024070C003C1A8000AD2A50003C04800A46
+:104C7000AF4800083C1B8008AF4700240E00091510
+:104C8000AF8400100E0008D8000000000E000825B8
+:104C9000000000000E001252000000003C046016EC
+:104CA0008C8500003C06FFFF3C02535300A61824ED
+:104CB0001062004734867C0094C201F2A780002C69
+:104CC00010400003A78000CC38581E1EA798002C67
+:104CD00094C201F810400004978300CC38591E1E7E
+:104CE000A79900CC978300CC2C7F006753E000018C
+:104CF000240300669784002C2C82040114400002D7
+:104D000000602821240404003C0760008CE904387A
+:104D10002403103C3128FFFF1103001F30B9FFFFAF
+:104D200057200010A38000CE24020050A38200CEA2
+:104D3000939F00CE53E0000FA78500CCA78000CC46
+:104D4000978500CC8FBF0010A780002CA78000346F
+:104D5000A78000E63C010800AC25008003E00008C5
+:104D600027BD0018939F00CE57E0FFF5A78000CC29
+:104D7000A78500CC978500CC8FBF0010A784002C9E
+:104D8000A7800034A78000E63C010800AC25008025
+:104D900003E0000827BD0018A38000CE8CCB003CA8
+:104DA000316A00011140000E0000000030A7FFFF33
+:104DB00010E0FFDE240200508CCC00C831860001D8
+:104DC00014C0FFDC939F00CE0A00007A2402005139
+:104DD0008C8F00043C0E60000A00005D01EE302163
+:104DE0008CEF0808240D5708000F740211CD000441
+:104DF00030B8FFFF240500660A00007B240404008D
+:104E00001700FFCC939F00CE0A00007A24020050C6
+:104E10008F8600103089FFFF000939408CC30010D5
+:104E20003C08005000E82025AF4300388CC5001432
+:104E300027420400AF82001CAF45003CAF44003065
+:104E40000000000000000000000000000000000062
+:104E50000000000000000000000000000000000052
+:104E60008F4B0000316A00201140FFFD0000000060
+:104E700003E00008000000008F840010948A001AEC
+:104E80008C8700243149FFFF000940C000E8302131
+:104E9000AF46003C8C8500248F43003C00A31023C8
+:104EA00018400029000000008C8B002025620001C2
+:104EB0003C0D005035AC0008AF420038AF4C00301C
+:104EC00000000000000000000000000000000000E2
+:104ED00000000000000000000000000000000000D2
+:104EE0008F4F000031EE002011C0FFFD00000000D8
+:104EF0008F4A04003C080020AC8A00108F4904044B
+:104F0000AC890014AF4800300000000094860018FF
+:104F10009487001C00C71821A48300189485001AE8
+:104F200024A20001A482001A9498001A9499001EE9
+:104F3000133800030000000003E000080000000038
+:104F400003E00008A480001A8C8200200A0000DC24
+:104F50003C0D00500A0000CD000000003C0308009A
+:104F60008C6300208F82001827BDFFE810620008C4
+:104F7000AFBF00100E000104AF8300183C0308000F
+:104F80008C63002024040001106400048F89001049
+:104F90008FBF001003E0000827BD00188FBF00106E
+:104FA0003C076012A520000A9528000A34E500108D
+:104FB00027BD00183106FFFF03E00008ACA60090F3
+:104FC0003C0208008C42002027BDFFC8AFBF003460
+:104FD000AFBE0030AFB7002CAFB60028AFB500248D
+:104FE000AFB40020AFB3001CAFB20018AFB10014D3
+:104FF00010400050AFB000108F840010948600065F
+:105000009483000A00C3282330B6FFFF12C0004A71
+:105010008FBF003494890018948A000A012A402323
+:105020003102FFFF02C2382B14E0000202C020212F
+:10503000004020212C8C0005158000020080A0215A
+:10504000241400040E0000B3028020218F8700107A
+:1050500002809821AF80001494ED000A028088211C
+:105060001280004E31B2FFFF3C1770003C1540002B
+:105070003C1E60008F8F001C8DEE000001D71824AD
+:10508000507500500220202102A3802B160000350D
+:105090003C182000507800470220202124100001F5
+:1050A0008F83001414600039029158230230F823D2
+:1050B0000250C82133F1FFFF1620FFEE3332FFFF0D
+:1050C0008F8700103C110020AF510030000000001D
+:1050D00094E6000A3C1E601237D5001002662821B3
+:1050E000A4E5000A94E2000A94F2000A94F400187D
+:1050F0003057FFFF1292003BAEB700908CED0014CA
+:105100008CE400100013714001AE4021000E5FC31B
+:10511000010E502B008B4821012A1821ACE8001405
+:10512000ACE3001002D3382330F6FFFF16C0FFB9FE
+:105130008F8400108FBF00348FBE00308FB7002CDB
+:105140008FB600288FB500248FB400208FB3001CC9
+:105150008FB200188FB100148FB0001003E0000868
+:1051600027BD0038107E001B000000001477FFCC24
+:10517000241000010E00159B000000008F83001416
+:105180001060FFCB0230F823029158238F87001064
+:10519000017020210A0001973093FFFF8F830014D4
+:1051A0001460FFCB3C110020AF5100300A000163B6
+:1051B000000000000E00077D024028210A00015770
+:1051C000004080210E00033A024028210A000157C6
+:1051D000004080210E001463022020210A000157A4
+:1051E000004080210E0000CD000000000A0001797F
+:1051F00002D3382327BDFFE8AFB00010AFBF0014C3
+:105200000E00003F000000003C028000345000709F
+:105210000A0001BA8E0600008F4F000039EE00012F
+:1052200031C20001104000248F8600A88E070000C4
+:105230003C0C08008D8C003C3C0908008D2900388E
+:1052400000E66823018D28210000502100AD302B9D
+:10525000012A4021010620213C010800AC25003C28
+:10526000AF8700A83C010800AC2400380E000106FE
+:10527000000000003C0308008C6300701060FFE633
+:10528000006020213C0508008CA500683C06080051
+:105290008CC6006C0E00152A000000003C010800BE
+:1052A000AC2000708F4F000039EE000131C20001C8
+:1052B0001440FFDE8F8600A88E0A00008F8B00A8A6
+:1052C0003C0508008CA5003C3C0408008C84003898
+:1052D000014B482300A938210082182100E9402B06
+:1052E000006810213C010800AC27003C3C0108008C
+:1052F000AC2200388F5F01002419FF0024180C0035
+:1053000003F9202410980012AF840000AF4400205D
+:10531000936D0000240C002031A600FF10CC001279
+:10532000240E005010CE00043C194000AF59013843
+:105330000A0001B3000000000E0011C800000000C8
+:105340003C194000AF5901380A0001B300000000C9
+:105350000E00011F000000003C194000AF59013849
+:105360000A0001B3000000008F58010000802821CE
+:10537000330F00FF01E020210E0002F1AF8F000487
+:105380003C194000AF5901380A0001B30000000089
+:1053900000A4102B2403000110400009000030215C
+:1053A0000005284000A4102B04A0000300031840AF
+:1053B0005440FFFC000528405060000A0004182BF0
+:1053C0000085382B54E000040003184200C3302548
+:1053D00000852023000318421460FFF900052842CD
+:1053E0000004182B03E0000800C310218F4201B80D
+:1053F0000440FFFE00000000AF4401803C031000A9
+:1054000024040040AF450184A3440188A3460189D8
+:10541000A747018A03E00008AF4301B83084FFFFCB
+:105420000080382130A5FFFF000020210A00022A59
+:10543000240600803087FFFF8CA40000240600387B
+:105440000A00022A000028218F8300388F8600304E
+:105450001066000B008040213C07080024E75A1822
+:10546000000328C000A710218C4400002463000121
+:10547000108800053063000F5466FFFA000328C04F
+:1054800003E00008000010213C07080024E75A1C34
+:1054900000A7302103E000088CC200003C0390000C
+:1054A0003462000100822025AF4400208F45002097
+:1054B00004A0FFFE0000000003E000080000000060
+:1054C0003C038000346200010082202503E00008D4
+:1054D000AF44002027BDFFE0AFB100143091FFFFC3
+:1054E000AFB00010AFBF00181220001300A0802141
+:1054F0008CA2000024040002240601401040000F8A
+:10550000004028210E000C5C00000000000010216B
+:10551000AE000000022038218FBF00188FB10014A8
+:105520008FB0001000402021000028210000302111
+:105530000A00022A27BD00208CA200000220382188
+:105540008FBF00188FB100148FB0001000402021D1
+:1055500000002821000030210A00022A27BD002077
+:1055600000A010213087FFFF8CA500048C440000B0
+:105570000A00022A2406000627BDFFE0AFB0001093
+:10558000AFBF0018AFB100149363003E00808021CC
+:105590000080282130620040000020211040000FD0
+:1055A0008E1100000E000851022020219367000098
+:1055B0002404005030E500FF50A400128E0F0000BC
+:1055C000022020218FBF00188FB100148FB000106F
+:1055D000A762013C0A00091127BD00200E000287C6
+:1055E000000000000E0008510220202193670000F7
+:1055F0002404005030E500FF14A4FFF20220202113
+:105600008E0F00003C1008008E1000503C0D000C66
+:10561000240BFF8001F05021314E007F01DA602120
+:10562000018D4021014B4824AF4900280220202150
+:105630008FBF00188FB100148FB00010A50200D6E4
+:1056400027BD00200A000911AF8800D027BDFFE068
+:10565000AFBF0018AFB10014AFB0001093660001E7
+:10566000008080210E00025630D1000493640005B2
+:10567000001029C2A765000034830040A363000521
+:105680000E00025F020020210E00091302002021FB
+:1056900024020001AF62000C02002821A762001062
+:1056A00024040002A762001224060140A76200142D
+:1056B0000E000C5CA76200161620000F8FBF0018AA
+:1056C000978C00343C0B08008D6B00782588FFFF19
+:1056D0003109FFFF256A0001012A382B10E000067E
+:1056E000A78800343C0F6006240E001635ED00102C
+:1056F000ADAE00508FBF00188FB100148FB00010F6
+:1057000003E0000827BD002027BDFFE0AFB1001473
+:10571000AFBF0018AFB0001000A088211080000AB1
+:105720003C03600024020080108200120000000090
+:105730000000000D8FBF00188FB100148FB0001053
+:1057400003E0000827BD00208C682BF80500FFFE51
+:1057500000000000AC712BC08FBF00188FB1001487
+:105760008FB000103C09100027BD002003E00008A6
+:10577000AC692BF80E00025600A0202193650005AD
+:10578000022020210E00025F30B000FF2403003E03
+:105790001603FFE7000000008F4401780480FFFE3D
+:1057A000240700073C061000AF51014002202021D1
+:1057B000A34701448FBF00188FB100148FB00010B1
+:1057C000AF4601780A0002C227BD002027BDFFE8CE
+:1057D000AFBF0014AFB000108F50002000000000D9
+:1057E0000E000913AF440020AF5000208FBF0014FB
+:1057F0008FB0001003E0000827BD00183084FFFFC1
+:10580000008038212406003500A020210A00022A49
+:10581000000028213084FFFF008038212406003654
+:1058200000A020210A00022A0000282127BDFFD065
+:10583000AFB3001C3093FFFFAFB50024AFB2001828
+:10584000AFBF0028AFB40020AFB10014AFB000105C
+:1058500030B5FFFF12600027000090218F90001CE0
+:105860008E0300003C0680002402004000033E023C
+:1058700000032C0230E4007F006688241482001D9F
+:1058800030A500FF8F8300282C68000A510000100B
+:105890008F910014000358803C0C0800258C56940E
+:1058A000016C50218D49000001200008000000001B
+:1058B00002B210213045FFFF0E000236240400849E
+:1058C000162000028F90001CAF8000288F910014DA
+:1058D000260C002026430001018080213072FFFF4A
+:1058E00016200004AF8C001C0253502B1540FFDC27
+:1058F00000000000024010218FBF00288FB5002457
+:105900008FB400208FB3001C8FB200188FB1001429
+:105910008FB0001003E0000827BD0030240E0034D3
+:1059200014AE00F9000000009203000E241F168040
+:105930003C07000CA36300219202000D0347C8211D
+:105940003C066000A3620020961100123C0A7FFF13
+:10595000354CFFFFA771003C960B00102403000597
+:105960003168FFFFAF6800848E05001CAF5F002820
+:105970008F3800008CC4444803057826008F3021FE
+:10598000AF66004C8F69004C24CE00013C057F00BF
+:10599000AF6900508F740050AF740054AF66007050
+:1059A000AF6E00588F6D005824140050AF6D005C2E
+:1059B000A3600023AF6C0064A36300378E02001461
+:1059C000AF6200488F710048AF7100248E0B001841
+:1059D000AF6B006C9208000CA3680036937F003E0A
+:1059E00037F90020A379003E8F78007403058024E6
+:1059F000360F4000AF6F007493640000308900FFE1
+:105A0000513402452404FF803C04080024845A9841
+:105A10000E00028D000000003C1008008E105A9805
+:105A20000E00025602002021240600042407000173
+:105A3000A366007D020020210E00025FA36700051F
+:105A40008F5F017807E0FFFE240B0002AF5001409A
+:105A5000A34B01448F90001C3C081000AF48017814
+:105A60000A000362AF8000282CAD003751A0FF98D8
+:105A70008F9100140005A0803C180800271856BC20
+:105A8000029878218DEE000001C00008000000009F
+:105A90002418000614B80011000000003C0808009B
+:105AA0008D085A9824040005AF4800208E1F001866
+:105AB000AF7F00188F79004CAF79001C8F650050C4
+:105AC000122000C0AF6500700A000362AF84002896
+:105AD0002406000710A60083240300063C050800E6
+:105AE00024A55A980E000264240400818F90001CA3
+:105AF0000011102B0A000362AF8200282407000463
+:105B000014A7FFF6240500503C1808008F185A9877
+:105B1000AF5800208E0F0008AF6F00408E090008BC
+:105B2000AF6900448E14000CAF7400488E0E001054
+:105B3000AF6E004C8E0D0010AF6D00848E0A001405
+:105B4000AF6A00508E0C0018AF6C00548E04001C1D
+:105B5000AF64005893630000306B00FF116501D8FB
+:105B6000000000008F7400488F6900400289702394
+:105B700005C000042404008C1620FFDE240200036C
+:105B8000240400823C05080024A55A980E000287D0
+:105B9000000000008F90001C000010210A0003622A
+:105BA000AF820028240F000514AFFFCC240520008D
+:105BB0003C0708008CE75A98AF4700208E06000487
+:105BC000AF66005C9208000824100008A36800215A
+:105BD0008F9F001C93F90009A37900208F86001C79
+:105BE00090D8000A330400FF10900011000000005C
+:105BF0002885000914A0006924020002240A00205C
+:105C0000108A000B34058000288D002115A00008A3
+:105C100024054000240E0040108E00053C050001C4
+:105C200024140080109400023C050002240540006A
+:105C30008F7800743C19FF00031980240205782531
+:105C4000AF6F007490C4000BA36400818F84001CAC
+:105C50009489000C11200192000000009490000C27
+:105C60002406FFBF24050004A770003C908F000E9F
+:105C7000A36F003E8F84001C9089000FA369003F32
+:105C80008F8B001C8D6E00108F54007401D468231C
+:105C9000AF6D00608D6A0014AF6A0064956C0018E7
+:105CA000A76C00689563001AA763006A8D62001CE8
+:105CB000AF62006C9167000EA367003E9368003EE0
+:105CC0000106F8241220014BA37F003E8F90001C98
+:105CD0000A000362AF8500282407002214A7FF7F73
+:105CE000240300073C0B08008D6B5A981220000C0F
+:105CF000AF4B00200A000362AF830028240C00335E
+:105D000010AC0014240A00283C05080024A55A9869
+:105D10000E00023C240400810A0003EB8F90001C5B
+:105D20003C04080024845A980E00028D00000000F4
+:105D30009363000024110050306200FF10510135C0
+:105D4000000000008F90001C000018210A00036270
+:105D5000AF8300283C0D08008DAD5A9824040081C3
+:105D6000AF4D00203C05080024A55A980E00023CC7
+:105D7000A36A00348F90001C240200090A00036209
+:105D8000AF82002802B288213225FFFF0E000236C2
+:105D9000240400840A0003628F90001C1082FFA478
+:105DA00024050400288B000311600170240C0004FA
+:105DB000240300015483FF9E240540000A00043B95
+:105DC000240501003C04080024845A988F62004C8A
+:105DD0000E00028D8F6300508F90001C0000202168
+:105DE0000A000362AF8400288E1000042404008A95
+:105DF000AF50002093790005333800021700015F8F
+:105E0000020028219368002302002821311F00206E
+:105E100017E0015A2404008D9367003F2406001206
+:105E200030E200FF10460155240400810E000256A6
+:105E30000200202193630023240500040200202196
+:105E4000346B0042A36B00230E00025FA365007D4C
+:105E50008F4401780480FFFE240A0002AF50014005
+:105E6000A34A01448F90001C3C0C1000AF4C0178F9
+:105E70000A0003EC0011102B8E1000042404008A89
+:105E8000AF500020936E000531CD000215A0001622
+:105E900002002821936F003F2414000402002821EF
+:105EA00031E900FF11340010240400810E00025675
+:105EB000020020219362002324080012241FFFFE09
+:105EC00034460020A3660023A368003F93790005B1
+:105ED00002002021033FC0240E00025FA3780005CA
+:105EE00002002821000020210E00033400000000E1
+:105EF0000A0003EB8F90001C8E1000043C03000886
+:105F00000343A021AF500020928B000024050050D5
+:105F1000316400FF10850161240700880200202100
+:105F2000000028210E00022A2406000E928D000097
+:105F3000240EFF800200282101AE8025A2900000DF
+:105F4000240400040E000C5C240600300A0003EB5D
+:105F50008F90001C8E0800043C14080026945A9868
+:105F60003C010800AC285A98AF480020921F00035B
+:105F700033F9000413200002240200122402000658
+:105F8000A362003F920B001B2404FFC03165003F59
+:105F900000A43825A367003E9206000330C200012A
+:105FA00014400132000000008E020008AE8200089A
+:105FB0003C0208008C425AA010400131000249C244
+:105FC000A76900088E14000C240C0001240300149F
+:105FD000AF74002C8E0E0010AF6E0030960D0016C0
+:105FE000A76D0038960A0014A76A003AAF6C000C3F
+:105FF000A76C0010A76C0012A76C0014A76C001609
+:1060000012200136A3630034920F000331F0000226
+:106010002E1100018F90001C262200080A00036246
+:10602000AF8200288E0400043C0E0008034E30218D
+:10603000AF4400208E05000890CD0000240C0050D5
+:1060400031AA00FF114C00862407008824060009AD
+:106050000E00022A000000000A0003EB8F90001CD3
+:106060008E04001C0E00024100000000104000F4ED
+:10607000004050218F89001C240700890140202105
+:106080008D25001C240600010E00022A00000000DD
+:106090000A0003EB8F90001C960D00023C140800D0
+:1060A00026945A9831AA0004514000B83C10600070
+:1060B0008E0E001C3C010800AC2E5A98AF4E0020FA
+:1060C000920700102408001430E200FF144800D6A4
+:1060D00000000000960B00023163000114600165AE
+:1060E000000000008E020004AE8200083C1408008C
+:1060F0008E945AA01280015B000000008F7400741F
+:106100003C0380002404000102835825AF6B007417
+:10611000A3600005AF64000C3C0708008CE75AA0A0
+:106120008F86001CA7640010000711C2A76400122C
+:10613000A7640014A7640016A76200088CC80008B2
+:1061400024040002AF68002C8CC5000CAF65003041
+:1061500090DF0010A37F00348F99001C9330001152
+:10616000A37000358F98001C930F0012A36F0036A8
+:106170008F89001C912E0013A36E00378F90001C96
+:10618000960D0014A76D0038960A0016A76A003A0B
+:106190008E0C0018AF6C00245620FDCCAF84002874
+:1061A0003C05080024A55A980E0002640000202136
+:1061B0008F90001C0A0004A7000020218E1000040C
+:1061C00024070081AF500020936900233134001070
+:1061D000128000170000000002002021000028218A
+:1061E0002406001F0E00022A000000000A0003EB34
+:1061F0008F90001C3C05080024A55A980E000287C9
+:10620000240400828F90001C000028210A000362F1
+:10621000AF8500283C0408008C845A980E0014E8CE
+:10622000000000008F90001C0A000482000018216A
+:106230000E00025602002021937800230200202144
+:10624000370F00100E00025FA36F002300003821FB
+:1062500002002021000028210A0005A82406001FB2
+:10626000920F000C31E90001112000030000000032
+:106270009618000EA4D8002C921F000C33F90002CF
+:1062800013200005000038218E0200149608001229
+:10629000ACC2001CA4C8001A0A0005432406000969
+:1062A0003C05080024A55A980E0002872404008BA0
+:1062B0008F90001C0011282B0A000362AF85002874
+:1062C000AF6000843C0A08008D4A5A983C0D0800D3
+:1062D0008DAD0050240CFF803C02000C014D1821B4
+:1062E000006C2024AF4400288E070014306B007F20
+:1062F000017A282100A2C821AF2700D88E060014F9
+:10630000AF9900D0AF2600DC8E080010251FFFFEDD
+:106310000A000408AF3F01083C0508008CA55A9804
+:106320003C1908008F39005024CCFFFE00B9C02171
+:1063300003047824AF4F00283C1408008E945A9828
+:106340003C0908008D2900500289702131CD007F61
+:1063500001BA502101478021AE0600D8AF9000D08D
+:10636000AE0000DC0A0003B1AE0C0108548CFE3014
+:10637000240540000A00043B240510000E00032EF3
+:10638000000000000A0003EB8F90001C8E0F442CCD
+:106390003C186C62370979703C010800AC205A98AF
+:1063A00015E9000824050140979F00349786002CCA
+:1063B0000280282103E6C82B132000112404009238
+:1063C000240501400E000C7A240400023C01080060
+:1063D000AC225A98AF4200203C0508008CA55A9880
+:1063E00010A00005240400830E00084500000000F2
+:1063F00010400009240400833C05080024A55A9895
+:106400000E000264000000008F90001C0011202B81
+:106410000A000362AF8400280E0008490000000053
+:106420000A00055F8F90001C0E00084D0000000060
+:106430003C05080024A55A980A00062F2404008B66
+:10644000240400040E000C7A240500301440002AB5
+:10645000004050218F89001C240700830140202127
+:106460008D25001C0A000551240600018E04000839
+:106470000E000241000000000A00051BAE82000869
+:106480003C05080024A55A980E00023C240400870D
+:106490008F90001C0A0005360011102B8F830038E6
+:1064A0008F8600301066FE9D000038213C070800F2
+:1064B00024E75A1C000320C0008728218CAC000070
+:1064C00011900061246A00013143000F5466FFFA05
+:1064D000000320C00A0004F6000038213C05080033
+:1064E00024A55A980E000287240400828F90001C75
+:1064F0000A000536000010213C0B0008034B202148
+:106500002403005024070001AF420020A0830000B4
+:10651000A08700018F82001C90480004A08800180A
+:106520008F85001C90A60005A08600198F9F001C77
+:1065300093F90006A099001A8F90001C921800078A
+:10654000A098001B8F94001C928F0008A08F001C45
+:106550008F89001C912E0009A08E001D8F8D001CBC
+:1065600091AC000AA08C001E8F8B001C3C0C080014
+:10657000258C5A1C9163000B3C0B0800256B5A18A4
+:10658000A083001F8F87001C90E8000CA0880020CB
+:106590008F82001C9045000D24024646A0850021F4
+:1065A0008F86001C90DF000EA09F00228F99001C98
+:1065B0009330000FA09000238F98001C93140010BC
+:1065C000A09400248F8F001C91E90011A089002560
+:1065D0008F89001C8F8E00308F900038952D00140D
+:1065E000000E18C025C80001A48D002895270016AC
+:1065F000006C3021006BC821A487002A9525001863
+:106600003108000FA485002CA482002E8D3F001CB1
+:10661000ACCA0000AF88003011100006AF3F000088
+:10662000000038218D25001C014020210A00055161
+:1066300024060001250C00013184000F00003821E0
+:106640000A0006B8AF8400383C07080024E75A184F
+:106650000087302100003821ACA000000A0004F6B9
+:10666000ACC000003C05080024A55A980A00062F7B
+:10667000240400878E0400040E0002410000000084
+:106680000A00056AAE8200083084FFFF30C600FFB2
+:106690008F4201B80440FFFE00064400010430258B
+:1066A0003C07200000C720253C031000AF400180BC
+:1066B000AF450184AF44018803E00008AF4301B84F
+:1066C00027BDFFE8AFB00010AFBF00143C0760006B
+:1066D000240600021080000600A080210010102B6C
+:1066E0008FBF00148FB0001003E0000827BD001812
+:1066F0003C09600EAD2000348CE5201C8F82001C0C
+:106700002408FFFC00A81824ACE3201C0E0006D1CE
+:106710008C45000C0010102B8FBF00148FB00010A0
+:1067200003E0000827BD00183C02600E344701005A
+:1067300024090018274A040000000000000000009F
+:10674000000000003C06005034C30200AF44003893
+:10675000AF45003CAF430030014018218F4B000093
+:10676000316800201100FFFD2406007F2408FFFF90
+:106770008C6C000024C6FFFF24630004ACEC000016
+:1067800014C8FFFB24E70004000000000000000024
+:10679000000000003C0F0020AF4F00300000000060
+:1067A00024AD020001A5702B2529FFFF008E2021BA
+:1067B0001520FFE101A0282103E0000800000000EF
+:1067C00027BDFFE0AFB10014AFBF0018AFB000109D
+:1067D0003C05600E8CA20034008088211440000625
+:1067E0003C0460008C87201C2408FFFC00E8302457
+:1067F00034C30001AC83201C8F8B001C24090001D2
+:10680000ACA90034956900028D6500148D70000CF0
+:106810002D2400818D6700048D660008108000071C
+:106820008D6A00102D2C00041580000E30CE00075C
+:10683000312D000311A0000B000000002404008B88
+:10684000020028210E0006D1240600030011102B9F
+:106850008FBF00188FB100148FB0001003E0000844
+:1068600027BD002015C0FFF62404008B3C03002048
+:10687000AF4300300000000024020001AF8200148A
+:106880000000000000000000000000003C1F01505C
+:10689000013FC825253800033C0F600EAF47003884
+:1068A00000181882AF46003C35E8003CAF59003074
+:1068B000274704008F4400003086002010C0FFFDF1
+:1068C00000000000106000082466FFFF2403FFFFA3
+:1068D0008CEB000024C6FFFF24E70004AD0B000092
+:1068E00014C3FFFB250800043C08600EAD09003806
+:1068F0000000000000000000000000003C07002035
+:10690000AF470030000000000E0006F901402021D2
+:1069100002002821000020210E0006D124060003D9
+:106920000011102B8FBF00188FB100148FB0001012
+:1069300003E0000827BD002027BDFFE0AFB200182C
+:106940003092FFFFAFB10014AFBF001CAFB000101A
+:106950001640000D000088210A0007AA022010211D
+:1069600024050001508500278CE5000C0000000D77
+:10697000262300013071FFFF24E200200232382B71
+:1069800010E00019AF82001C8F8200141440001622
+:106990008F87001C3C0670003C0320008CE5000043
+:1069A00000A62024148300108F84003C00054402BC
+:1069B0003C09800000A980241480FFE9310600FF13
+:1069C0002CCA00095140FFEB262300010006688015
+:1069D0003C0E080025CE579801AE60218D8B00003B
+:1069E0000160000800000000022010218FBF001C81
+:1069F0008FB200188FB100148FB0001003E00008B0
+:106A000027BD00200E0006D1240400841600FFD804
+:106A10008F87001C0A00078BAF80003C90EF0002BC
+:106A200000002021240600090E0006D1000F2E00D0
+:106A30008F87001C0010102B0A00078BAF82003CD0
+:106A4000020028210E0006DF240400018F87001CAD
+:106A50000A00078BAF82003C020028210E0006DFEF
+:106A6000000020210A0007C38F87001C0E00071FAB
+:106A7000020020210A0007C38F87001C30B0FFFFEF
+:106A8000001019C08F5801B80700FFFE3C1F2004FA
+:106A90003C191000AF430180AF400184AF5F018813
+:106AA000AF5901B80A00078C262300013082FFFF8E
+:106AB00014400003000018210004240224030010E5
+:106AC000308500FF14A000053087000F2466000801
+:106AD0000004220230C300FF3087000F14E00005DD
+:106AE000308900032468000400042102310300FF00
+:106AF0003089000315200005388B0001246A00024C
+:106B000000042082314300FF388B00013164000112
+:106B100010800002246C0001318300FF03E00008B4
+:106B200000601021308BFFFF000B394230E600FF80
+:106B30003C09080025295998000640800109602178
+:106B40008D8700003164001F240A0001008A1804A8
+:106B500030A500FF00E3202514A000020003102749
+:106B600000E22024240F000100CF700401096821F5
+:106B7000000E282714800005ADA400008F86000CAD
+:106B800000A6102403E00008AF82000C8F88000CE0
+:106B900001C8102503E00008AF82000C3C06001F6E
+:106BA0003C0360003084FFFF34C5FF8024020020D6
+:106BB000AC602008AC60200CAC602010AC652014E8
+:106BC000AC642018AC62200000000000000000004F
+:106BD00003E000080000000027BDFFE82402FFFFDB
+:106BE000AFBF0010AF82000C000020213C0608005F
+:106BF00024C659982405FFFF248900010004408021
+:106C00003124FFFF010618212C87002014E0FFFA31
+:106C1000AC6500000E0008160000202124020001CF
+:106C20003C04600024050020AC822018AC852000C4
+:106C3000000000000000000000000000244A0001E5
+:106C40003142FFFF2C46040014C0FFF78FBF001035
+:106C500003E0000827BD00188F8300082C620400A1
+:106C600003E00008384200018F830008246200011D
+:106C700003E00008AF8200088F8300082462FFFF52
+:106C800003E00008AF82000827BDFFE0AFB10014A9
+:106C9000AFBF0018AFB000108F6B00303C06600033
+:106CA00000808821ACCB20088F6A002C3C02800039
+:106CB00024030008ACCA200C9769003A9768003892
+:106CC00000092C003107FFFF00A72025ACC42010CD
+:106CD000ACC22014ACC32000000000000000000083
+:106CE000000000003C0360008C6D200031AC000807
+:106CF0001580FFF9000000008C6E201405C00020F4
+:106D0000000000000E0007DA8F84000C00024080B3
+:106D10003C09080025295998010938218CE4000014
+:106D20000E0007DA00028140020220213090FFFFAE
+:106D3000020020210E0007F8000028213C0C8000F2
+:106D4000022C58253210FFFF3C116000240A00205D
+:106D5000AE2B2014AE302018AE2A20000000000018
+:106D60000000000000000000020010218FBF00188A
+:106D70008FB100148FB0001003E0000827BD002081
+:106D80008C6620143C02001F3443FF803C1FFFE848
+:106D900000C3C02437F9080003198021001079C20C
+:106DA0003C0C8000022C582531F0FFFF3C116000A4
+:106DB000240A0020AE2B2014AE302018AE2A20006A
+:106DC0000000000000000000000000000200102190
+:106DD0008FBF00188FB100148FB0001003E00008BF
+:106DE00027BD002027BDFFE8AFB000103402FFFF31
+:106DF0003090FFFFAFBF00141202000602002021F6
+:106E00000E00081600000000020020210E0007F806
+:106E1000240500018F8400088FBF00148FB000107C
+:106E20002483FFFF27BD001803E00008AF8300089C
+:106E3000000439C230E6003F00043B42000718401E
+:106E4000240210002CC4002024C8FFE0AF42002C14
+:106E5000246300011480000330A900FF00071840DC
+:106E6000310600FF0003608024080001019A5821C8
+:106E70003C0A000E00C82804016A382111200005D0
+:106E8000000530278CE900000125302503E00008CB
+:106E9000ACE600008CEE000001C6682403E00008A8
+:106EA000ACED000027BDFFE8AFBF0014AFB000108D
+:106EB0003C0460008C8508083403F00030A2F00028
+:106EC00050430006240200018C8708083404E000C7
+:106ED00030E6F00010C4001E24020002AF82004021
+:106EE0003C1060003C0A0200AE0A0814240910009D
+:106EF0003C08000E8E03440003482021AF49002CBB
+:106F0000240501200E000CC0000030218F830040BA
+:106F1000106000043C021691240B0001106B000E5F
+:106F20003C023D2C344F0090AE0F44088FBF00143C
+:106F30008FB000103C0C6000240E10003C0D0200CD
+:106F400027BD0018AD8E442003E00008AD8D081069
+:106F50000A0008E7AF8000403C0218DA344F009086
+:106F6000AE0F44088FBF00148FB000103C0C6000BF
+:106F7000240E10003C0D020027BD0018AD8E4420E9
+:106F800003E00008AD8D08100A0008BB24050001CD
+:106F90000A0008BB000028213C08080025085DA461
+:106FA0002404FFFF010018212402001E2442FFFFD9
+:106FB000AC6400000441FFFD246300043C070800AA
+:106FC00024E75E208CE5FFFC2404001C240600015D
+:106FD000308A001F0146480424840001000910275C
+:106FE0002C8300201460FFFA00A22824ACE5FFFCEB
+:106FF0003C05666634A4616E3C06080024C65EE06B
+:10700000AF840058AF88009C2404FFFF00C0182103
+:107010002402001F2442FFFFAC6400000441FFFD76
+:10702000246300043C0766663C05080024A55EA0B6
+:10703000AF86004834E6616EAF8600982404FFFFF7
+:1070400000A018212402000F2442FFFFAC640000BE
+:107050000441FFFD246300043C0B66663C06080007
+:1070600024C65E203568616EAF8500A4AF880070CD
+:107070002404FFFF00C018212402001F2442FFFF48
+:10708000AC6400000441FFFD246300043C0D66660F
+:107090003C0A0800254A5F6035AC616EAF860090FF
+:1070A000AF8C005C2404FFFF014018212402000380
+:1070B0002442FFFFAC6400000441FFFD2463000490
+:1070C0003C09080025295F708D27FFFC2404000679
+:1070D000240500013099001F0325C0042484000109
+:1070E000001878272C8E002015C0FFFA00EF3824F6
+:1070F000AD27FFFC3C09666624030400240403DC7E
+:1071000024050200240600663522616E3C08080052
+:1071100025085AA4AF820074AF830044AF83006C8B
+:10712000AF830050AF830084AF8A008CAF840064CB
+:10713000AF85004CAF860054AF840078AF85006007
+:10714000AF86008001001821240200022442FFFFC4
+:10715000AC6000000441FFFD24630004240400032C
+:107160002403000C3C0A0800254A5AB0AF8A006884
+:107170000A00098E2405FFFF000418802484000102
+:10718000006858212C8700C014E0FFFBAD650000AB
+:107190003C0E666635CD616E240C17A024081800DD
+:1071A000AF8D0088AF8C009403E00008AF88007CAE
+:1071B0002484007F000421C200004021000030210F
+:1071C00000003821000028210A0009A5AF8400A092
+:1071D0001060000624E7000100C4302124A500014E
+:1071E0002CC20BF51440FFFA2CA300663C090800E2
+:1071F00025295F6001201821240200032442FFFF9B
+:10720000AC6000000441FFFD2463000410E0001A9C
+:1072100024E3FFFF0003294210A0000A0000202100
+:107220002406FFFF3C03080024635F602484000100
+:107230000085502BAC660000250800011540FFFBBF
+:107240002463000430E2001F10400008000868803A
+:10725000240C0001004C38040008588001692821E2
+:1072600024E6FFFF03E00008ACA6000001A94021CE
+:107270002409FFFFAD09000003E000080000000042
+:10728000AF4400283C04000C034420210005288260
+:107290000A000CC000003021000421803C03600083
+:1072A000AC6410080000000000052980AC65100CDB
+:1072B0000000000003E000088C62100C27BDFFE80E
+:1072C0000080282124040038AFBF00140E0009D527
+:1072D000AFB0001024040E00AF4400283C10000C96
+:1072E00003502021240500100E000CC000003021A6
+:1072F00003501021AC400000AC40000424040038CE
+:107300008FBF00148FB0001024053FFF27BD001869
+:107310000A0009D58C430000000421803C03600072
+:10732000AC641008000000008C62100C03E0000840
+:107330000002118227BDFFC8AFB400208F940068FF
+:10734000AFBE0030AFB7002CAFB600280000B821A8
+:107350000080B021241E00C0AFBF0034AFB50024B0
+:10736000AFB3001CAFB20018AFB10014AFB0001043
+:107370000A000A12AFA5003C504000018F9400683B
+:1073800027DEFFFF13C00028269400048E92000021
+:107390003C03080024635DA01240FFF70283102B1A
+:1073A0003C04080024845AA4028410230002A8C0CC
+:1073B000000098210A000A212411000100118840D0
+:1073C000122000260000000002B380210251282470
+:1073D0000200202110A0FFF9267300010E0009DE33
+:1073E000000000000016684032EC000101AC2021D2
+:1073F0000E0009D5020028218F89009426F700018C
+:107400008FA6003C3AEB0001316A00012528FFFFFE
+:107410000011382702CAB021AF88009416E6FFE7B2
+:1074200002479024AE92000002E010218FBF00348A
+:107430008FBE00308FB7002C8FB600288FB5002488
+:107440008FB400208FB3001C8FB200188FB10014CE
+:107450008FB0001003E0000827BD00383C0E080084
+:1074600025CE5DA0028E102B0A000A0DAE92000000
+:1074700027BDFFD8AFB10014AFB00010AFBF0020E0
+:10748000AFB3001CAFB2001800A0882110A0001FED
+:10749000000480403C13080026735AA40A000A5ACC
+:1074A0002412000112200019261000010E0009F517
+:1074B00002002021000231422444FFA0000618806F
+:1074C0003045001F2C8217A1007318212631FFFFC1
+:1074D0001040FFF400B230048C690000020020214B
+:1074E00024053FFF012640241500FFEE0126382524
+:1074F0000E0009D5AC6700008F8A009426100001A9
+:10750000254700011620FFE9AF8700948FBF0020B8
+:107510008FB3001C8FB200188FB100148FB0001011
+:1075200003E0000827BD00288F85009C00805821BB
+:107530000000402100004821240A001F3C0C0800E4
+:10754000258C5E1C3C0D080025AD5DA48CA60000BA
+:1075500050C000140000402100AD1023000238C0CC
+:10756000240300010A000A930000202115000003F3
+:1075700000E410212448202400004821252900018E
+:10758000512B00132506DFDC106000062484000167
+:1075900000C3702415C0FFF5000318400A000A91CB
+:1075A0000000402110AC002624A300040060282124
+:1075B000254AFFFF1540FFE5AF85009C512B0004D5
+:1075C0002506DFDC0000402103E000080100102157
+:1075D0000006614230C5001F000C50803C070800C7
+:1075E00024E75DA424040001014730211120000F8D
+:1075F00000A420043C05080024A55E20148000059A
+:107600002529FFFF24C6000410C50011000000005A
+:10761000240400018CCF00000004C0270004204097
+:1076200001F868241520FFF5ACCD00008F99007893
+:1076300001001021032B482303E00008AF890078E4
+:107640003C05080024A55DA40A000A9B0000402117
+:107650003C06080024C65DA40A000AB42404000104
+:10766000308800FF240200021102000A24030003F4
+:107670001103005C8F8900A4240400041104005F3E
+:1076800024050005110500670000182103E000082B
+:10769000006010218F8900483C0C0800258C5EE0BA
+:1076A0003C04080024845F60240300201060000F65
+:1076B00000005821240D0002240E00033C0F080096
+:1076C00025EF5EE08D27000014E0000B30F9FFFF8E
+:1076D000252900040124C02B53000001018048210A
+:1076E0002463FFFF5460FFF88D270000016018211C
+:1076F00003E0000800601021132000323C0500FF69
+:1077000030E200FF004030211040004200005021D4
+:1077100024050001000020210005C84000A6C02467
+:1077200017000003332500FF14A0FFFB2484000191
+:10773000012CC023001828C000AA6021008C502111
+:107740003144001F240C0001008C18040003102792
+:1077500000E23024110D0041AD260000110E004C56
+:10776000000A1840110D00368F87006C510E00562C
+:107770008F8C0060240D0004110D005A8F8E008440
+:10778000240E0005150EFFDA01601821240B1430B9
+:1077900011400006000018218F8400A0246300011E
+:1077A000006A402B1500FFFD016458218F8A00807C
+:1077B000AF89008C016018212549FFFF0A000AEB00
+:1077C000AF89008000E52024000736021080FFD03A
+:1077D000240A001800075402314600FF0A000AF389
+:1077E000240A00103C0C0800258C5EA03C04080014
+:1077F00024845EE00A000ADA240300103C0C08002E
+:10780000258C5E203C04080024845EA00A000AD96E
+:107810008F89009000071A02306600FF0A000AF301
+:10782000240A00088F89008C3C0C0800258C5F60BE
+:107830003C04080024845F700A000ADA2403000470
+:10784000000A4080250B003024E6FFFF016018216C
+:10785000AF8900480A000AEBAF86006C000AC982B3
+:10786000001978803C07080024E75EA001E720218A
+:10787000000A18428C8F00003079001F032C380456
+:107880000007C02701F860240A000B08AC8C000038
+:10789000000331420006288000AF28213062001F1B
+:1078A0008CB8000024630001004CC804000321428E
+:1078B000001938270004108003073024004F2021CE
+:1078C0000A000B4CACA60000000A68C025AB0032D1
+:1078D000258AFFFF01601821AF8900A40A000AEB86
+:1078E000AF8A0060254B1030AF89009001601821ED
+:1078F00025C9FFFF0A000AEBAF8900843086000724
+:107900002CC2000610400014000000000006408059
+:107910003C030800246357BC010338218CE40000B9
+:1079200000800008000000002409000310A9000ED8
+:1079300000000000240A000510AA000B000000004F
+:10794000240B000110AB0008000000008F8C00A089
+:1079500010AC00050000000003E00008000010214A
+:107960000A000A7900A020210A000AC700C02021CD
+:1079700027BDFFE8308400FF240300021083000BC2
+:10798000AFBF0010240600031086003A240800044C
+:1079900010880068240E0005108E007F2CAF143074
+:1079A0008FBF001003E0000827BD00182CA2003094
+:1079B0001440FFFC8FBF001024A5FFD0000531C28A
+:1079C000000668803C07080024E75EE001A730213C
+:1079D0008CC900000005288230AC001F240B000178
+:1079E000018B50048F840048012A4025ACC8000058
+:1079F0008C83000050600001AF8600488F98006CB7
+:107A000030AE000124A6FFFF270F000115C00002C1
+:107A1000AF8F006C24A600010006414200082080C0
+:107A2000008718218C79000030C2001F2406000155
+:107A30000046F804033F382410E0FFDA8FBF00103F
+:107A40000005C182001870803C0F080025EF5EA081
+:107A500001CF48218D2B00000005684231A5001F91
+:107A600000A66004016C502527BD001803E0000843
+:107A7000AD2A00002CA7003014E0FFCA8FBF001011
+:107A800030B900071723FFC724A8FFCE00086A02F9
+:107A9000000D60803C0B0800256B5EA0018B30213F
+:107AA0008CC40000000828C230AA001F240800016E
+:107AB000014848048F8200A400891825ACC3000047
+:107AC0008C5F000053E00001AF8600A40005704009
+:107AD000000E7942000F28803C04080024845EE0F8
+:107AE00000A418218C6B000025DF000131CD001FA0
+:107AF000001F514201A86004016C4825000A108053
+:107B0000AC690000004428218CA600008F9800601A
+:107B100033F9001F8FBF00100328380400C77825F1
+:107B2000270E000127BD0018ACAF000003E00008DD
+:107B3000AF8E006024A5EFD02CB804001300FF998D
+:107B40008FBF001000053142000658803C0A080033
+:107B5000254A5E20016A30218CC4000030A3001F3A
+:107B600024090001006910048F9900900082F82513
+:107B7000ACDF00008F27000050E00001AF860090CE
+:107B80008F8D00848FBF001027BD001825AC000129
+:107B900003E00008AF8C008415E0FF828FBF001067
+:107BA0008F8600A0000610400046F821001F21002B
+:107BB00003E4C8210019384024F8143000B8402BE1
+:107BC0001100FF788FBF001024A4EBD00E00021329
+:107BD00000C0282100027942000F70803C0D08008F
+:107BE00025AD5F6001CD20218C8B0000304C001F43
+:107BF00024060001018618048F89008C016350253A
+:107C0000AC8A00008D25000050A00001AF84008CDC
+:107C10008F9800808FBF001027BD00182708000133
+:107C200003E00008AF88008030A5000724030003AC
+:107C300010A3001028A2000414400008240700022A
+:107C40002403000410A300152408000510A8000F49
+:107C50008F8500A003E000080000000014A7FFFDCE
+:107C60000080282114C3FFFB240400020A000B8BB0
+:107C700000000000240900050080282110C9FFFB36
+:107C80002404000303E000080000000014C5FFF115
+:107C9000008028210A000B8B24040005240A00011F
+:107CA0000080282110CAFFF12404000403E000082A
+:107CB0000000000027BDFFE0AFB00010000581C24A
+:107CC0002603FFD024C5003F2C6223D024C6007FAA
+:107CD000AFB20018AFB10014AFBF001C309100FF6D
+:107CE000000691C2000529820200202110400008F0
+:107CF0002403FFFF0E000A4B0000000002002021B9
+:107D0000022028210E000C390240302100001821E9
+:107D10008FBF001C8FB200188FB100148FB00010FD
+:107D20000060102103E0000827BD002027BDFFD818
+:107D300024A2007FAFB3001CAFB20018000299C2AA
+:107D4000309200FF24A3003F02402021026028213E
+:107D5000AFB10014AFB00010AFBF00200E000B6E2B
+:107D60000003898200408021004020210220282138
+:107D700014400009000018218FBF00208FB3001CA1
+:107D80008FB200188FB100148FB000100060102166
+:107D900003E0000827BD00280E0009FC00000000D9
+:107DA00000402821020020211051FFF3001019C0CB
+:107DB0000E000A4B00000000020020210240282192
+:107DC0000E000C39026030218FBF00208FB3001CE1
+:107DD0008FB200188FB100148FB00010000018216E
+:107DE0000060102103E0000827BD00283084FFFF59
+:107DF00030A5FFFF1080000700001821308200012D
+:107E00001040000200042042006518211480FFFB8E
+:107E10000005284003E000080060102110C00007A2
+:107E2000000000008CA2000024C6FFFF24A500046F
+:107E3000AC82000014C0FFFB2484000403E00008AF
+:107E40000000000010A0000824A3FFFFAC86000083
+:107E500000000000000000002402FFFF2463FFFF79
+:107E60001462FFFA2484000403E00008000000000C
+:107E700030A5FFFF8F4201B80440FFFE3C076015AC
+:107E800000A730253C031000AF440180AF400184BF
+:107E9000AF46018803E00008AF4301B88F8500D0EA
+:107EA0002C864000008018218CA700840087102BAE
+:107EB00014400010000000008CA800842D06400033
+:107EC00050C0000F240340008CAA0084008A482B75
+:107ED000512000018CA3008400035A42000B208033
+:107EE0003C05080024A558200085182103E000085F
+:107EF0008C62000014C0FFF4000000002403400066
+:107F000000035A42000B20803C05080024A558209D
+:107F10000085182103E000088C6200008F8300D0E8
+:107F2000906600D024C50001A06500D08F8500D0E8
+:107F3000906400D090A200D210440017000000000E
+:107F4000936C00788F8B00BC318A00FFA16A000C13
+:107F500025490001938700C4312200FF3048007F8B
+:107F60001107000B00026827A36200788F4E01788A
+:107F700005C0FFFE8F9900B0241800023C0F1000CE
+:107F8000AF590140A358014403E00008AF4F017806
+:107F90000A000D0931A20080A0A000D00A000CFF49
+:107FA000000000008F8700D027BDFFC8AFBF0030A2
+:107FB000AFB7002CAFB60028AFB50024AFB4002097
+:107FC000AFB3001CAFB20018AFB10014AFB00010D7
+:107FD00094E300E094E200E2104300D72405FFFFA1
+:107FE0003C047FFF3497FFFF2415FF800A000DF04B
+:107FF0003C16000E108A00D18FBF00308F9100B068
+:108000003C1808008F18005C001230C0001291402C
+:108010000311702101D57824AF4F002C94EC00E2BD
+:1080200031CD007F01BA5821318A7FFF0176482186
+:10803000000A804002091021945300003C08080007
+:108040008D0800580246C02132733FFF001319808B
+:10805000010320210224282130BF007F03FAC82118
+:1080600000B5A024AF54002C0336A0218E87001049
+:108070008E8F003003785821256D008800EF702323
+:10808000240C0002AE8E0010AF8D00ACA16C0088F5
+:10809000976A003C8E8400308F9100AC0E000CD6A5
+:1080A0003150FFFF00024B80020940253C02420094
+:1080B00001022025AE2400048E8300048F8D00ACC5
+:1080C0008E860000240E0008ADA3001CADA600188B
+:1080D000ADA0000CADA00010929F000A33F900FF84
+:1080E000A5B90014968500083C1F000CA5A5001634
+:1080F0009298000A331100FFA5B100209690000865
+:1081000024180005A5B00022ADA00024928F000B1A
+:108110002410C00031E700FFA5A70002A1AE0001B6
+:108120008E8C00308F8B00AC8F8400B0AD6C00085B
+:108130003C0A08008D4A005401444821013540247E
+:10814000AF4800283C0208008C4200540044302113
+:1081500030C3007F007AC821033F282102458821CF
+:10816000AF9100BCAF8500C0A23800008F8A00BC70
+:108170002403FFBF2418FFDF954F000201F03824CD
+:1081800000F37025A54E0002914D000231AC003F76
+:10819000358B0040A14B00028F8600BC8F8900D038
+:1081A000ACC000048D28007C3C098000ACC80008ED
+:1081B00090C4000D3082007FA0C2000D8F8500BCEE
+:1081C00090BF000D03E3C824A0B9000D8F9100BC3F
+:1081D0009233000D02789024A232000D8E9000346C
+:1081E0008F8B00BCAD7000108E87002C8E8F0030FE
+:1081F00000EF7023AD6E0014916D001831AC007F5C
+:10820000A16C00188F9F00BC8E8A00308FE8001888
+:10821000015720240109302400C41025AFE20018C2
+:108220009283000AA3E3001C969900088F8500BC86
+:108230008F9800D0A4B9001E8E9000308E8400303C
+:108240000E0002138F0500848F8500D0000291403C
+:108250000002990090AF00BC0253882100403021F9
+:1082600031E7000210E0000302118021000290803B
+:108270000212802190B900BC3327000410E00002F4
+:108280000006F880021F80218E9800308F8B00BC82
+:1082900024068000330F0003000F702331CD00034C
+:1082A000020D6021AD6C000494A400E294AA00E2E7
+:1082B00094B000E231497FFF2522000130537FFF57
+:1082C0000206182400734025A4A800E294A400E24A
+:1082D0003C1408008E94006030917FFF123400221D
+:1082E000000000000E000CF6000000008F8700D098
+:1082F0000000282194F300E094F000E21213000F34
+:108300008FBF003090E900D090E800D1313200FFFB
+:10831000310400FF0244302B14C0FF36264A00010E
+:1083200090EE00D2264B000131CD00FF008D602180
+:10833000158BFF338F9100B08FBF00308FB7002CAB
+:108340008FB600288FB500248FB400208FB3001C97
+:108350008FB200188FB100148FB0001000A0102150
+:1083600003E0000827BD003894A300E20066402423
+:10837000A4A800E290A400E290B900E2309100FFCE
+:108380000011A1C20014F827001F39C03332007F4A
+:10839000024730250A000DE8A0A600E23084FFFF66
+:1083A00030A5FFFFAF440018AF45001C03E00008F4
+:1083B0008F42001427BDFFB8AFB000208F9000D0CF
+:1083C0003084FFFFAFA40010AFBF0044AFBE004039
+:1083D000AFB7003CAFB60038AFB50034AFB4003033
+:1083E000AFB3002CAFB20028AFB10024A7A0001893
+:1083F000920600D1920500D030C400FF30A300FFE8
+:108400000064102B10400122AFA00014920900D08C
+:108410008FB50010312800FF0088382324F4FFFFB7
+:108420000014882B0015982B02339024524001260B
+:108430008FB40014961E0012961F00108FB7001004
+:1084400003DFC823001714000019C400000224032E
+:108450000018140302E2B02A52C00001004020219B
+:108460000284282B10A0000200801821028018210D
+:1084700000033C0000071C033064FFFF2C8600094A
+:1084800014C000020060B821241700088E0A0008FA
+:10849000001769808E09000C31ABFFFF3C0C001007
+:1084A000016C402527520400AF4A0038AF9200B853
+:1084B000AF49003CAF480030000000000000000061
+:1084C00000000000000000000000000000000000AC
+:1084D00000000000000000008F4F000031EE00207F
+:1084E00011C0FFFD0017982A027110240A000E83A4
+:1084F0000000B02155E001019258000131130080C5
+:10850000126001CF012020219655001232A5FFFFF5
+:108510000E000CCBA7B500188F9000D00291A023BD
+:1085200026CD00018F9100B8000DB4000016B403F1
+:108530002638004002D7582A0014882B2405000151
+:108540000300902101711024AF9800B8AFA500146A
+:10855000104001BC8F8900B03C0C08008D8C005489
+:10856000240BFF80921E00D001895021014B28244A
+:10857000921900D0AF4500288E4700103C08080033
+:108580008D0800583C1808008F18005430E33FFF56
+:108590000003218001043021012658212402FF809C
+:1085A0000162F824920C00D0AF5F002C92480000CA
+:1085B00033D100FF333500FF0309982100117140CA
+:1085C000001578C0326D007F01CF382101BA282113
+:1085D000318300FF3164007F3C0A000C00AA88212F
+:1085E0000367F02100033140009A10213108003F59
+:1085F0003C1F000E00D1C021005F982127D90088C0
+:108600002D150008AF9100C0AF9900ACAF9800BC29
+:10861000AF9300B412A0018A00008821240E00014B
+:10862000010E4004310D005D11A0FFB2310F0002B8
+:108630008E4A00283C0300803C04FFEFAE6A000035
+:108640008E450024A260000A3488FFFFAE65000456
+:108650009247002C3C1FFF9F37FEFFFFA267000CD4
+:108660008E62000C3C180040A267000B00433025CE
+:1086700000C8C824033E88240238A825AE75000C23
+:108680008E490004AE6000183C0F00FFAE69001474
+:108690008E4D002C35EEFFFF8F8B00B001AE6024B5
+:1086A000AE6C00108E470008A660000896450012C8
+:1086B000AE6700208E42000C30B03FFF00105180AA
+:1086C000AE6200248E5E0014014B182130A400011C
+:1086D000AE7E00288E590018000331C2000443808A
+:1086E000AE79002C8E51001C00C8F821A67F001C1A
+:1086F000AE710030965800028E550020A678001EFC
+:10870000AE75003492490033313000045600000544
+:10871000925000008F8C00D08D8B007CAE6B0030AF
+:10872000925000008F8F00BCA1F00000924E0033E9
+:1087300031CD000251A00007925E00018F8900BC7C
+:108740002418FF80913100000311A825A1350000F5
+:10875000925E00018F9900BC2409FFBF240BFFDF4C
+:10876000A33E00018F9500BC92B8000D3311007F2D
+:10877000A2B1000D8F8E00BC91D0000D02097824AB
+:10878000A1CF000D8F8800BC8E6D0014910A000DE2
+:108790002DAC0001000C2940014B382400E51825C0
+:1087A000A103000D964200128F8800BC8F8700D075
+:1087B000A50200028E45000490FF00BC30A4000317
+:1087C0000004302330DE000300BE102133F9000224
+:1087D00017200002244400342444003090E200BCFE
+:1087E00000A2302430DF000417E0000224830004DC
+:1087F000008018218F8F00AC24090002AD03000413
+:10880000A1E90000924E003F8F8D00ACA1AE0001A7
+:108810008F9500AC924C003F8E440004A6AC000241
+:10882000976B003C0E000CD63170FFFF00025380A6
+:10883000020A38253C05420000E51825AEA30004D5
+:108840008F8600AC8E480038ACC800188E440034C7
+:10885000ACC4001CACC0000CACC00010A4C0001420
+:10886000A4C00016A4C00020A4C00022ACC00024F4
+:108870008E6400145080000124040001ACC4000880
+:108880000E000CF6241100010A000E768F9000D025
+:10889000920F00D2920E00D08FB5001031EB00FF86
+:1088A00031CD00FF008D6023016C50212554FFFF66
+:1088B0000014882B0015982B023390241640FEDDFF
+:1088C000000000008FB400148FBF00448FBE004032
+:1088D0003A8200018FB7003C8FB600388FB5003464
+:1088E0008FB400308FB3002C8FB200288FB10024DA
+:1088F0008FB0002003E0000827BD0048331100209E
+:10890000122000EF24150001921E00BC241F00015C
+:108910000000A82133D900011320000DAFBF001CB7
+:108920008E4400148E0800840088102B144000022E
+:10893000008030218E0600848E03006400C3A82BC3
+:1089400016A0000200C020218E0400640080A8212F
+:108950008E4700148E05006400E5302B14C0000221
+:1089600000E020218E0400640095F02313C0000471
+:108970008FAC001C240A0002AFAA001C8FAC001CA4
+:10898000028C582B156000A8000018218E4F00386B
+:108990008E6D000C3C0E0080AE6F00008E4A0034DD
+:1089A0003C10FF9F01AE5825AE6A00049246003F7E
+:1089B000360CFFFF016C38243C0500203C03FFEF20
+:1089C000A266000B00E510253468FFFF8F8700B812
+:1089D0000048F8243C04000803E4C825AE79000CE4
+:1089E0008CF80014AE60001802BE7821AE78001436
+:1089F0008CF10018AE71001C8CE90008AE690024EF
+:108A00008CEE000CAE6F002CAE600028AE6E002025
+:108A1000A6600038A660003A8CED001401B58023F2
+:108A2000021E902312400011AE72001090EA003D29
+:108A30008E6500048E640000000A310000A6C82183
+:108A4000000010210326402B0082F82103E8C021FA
+:108A5000AE790004AE78000090F1003DA271000AEA
+:108A60008F8900B895320006A67200088F9800AC76
+:108A70002419000202A02021A31900009769003CDC
+:108A80008F9200AC0E000CD63131FFFF00027B80CC
+:108A90008F8500B8022F68253C0E420001AE80256C
+:108AA000AE5000048F8400AC8CAC0038AC8C001845
+:108AB0008CAB0034AC8B001CAC80000CAC80001084
+:108AC000A4800014A4800016A4800020A4800022AA
+:108AD000AC80002490A7003FA487000212A00135BB
+:108AE0002403000153C0000290A2003D90A2003E6A
+:108AF00024480001A08800018F9F00ACAFF500085A
+:108B00008F8300D024070034906600BC30C500027B
+:108B100050A00001240700308F9200B88F8A00BC5B
+:108B2000906D00BC924B00002412C00032A50003DF
+:108B3000A14B00008F8600B88F8800BC240200047F
+:108B400090C400010045182330790003A1040001FE
+:108B50008F8A00BC8F9F00B800F53821955800021D
+:108B600097E9001200F9382103128824312F3FFFC2
+:108B7000022F7025A54E00029150000231A800047A
+:108B8000320C003F358B0040A14B000212A00002C6
+:108B90008F8500BC00E838218F8E00D0ACA7000480
+:108BA000240BFFBF8DCD007C2EA400012403FFDF2A
+:108BB000ACAD000890B0000D00044140320C007FC5
+:108BC000A0AC000D8F8600BC90CA000D014B102494
+:108BD000A0C2000D8F8700BC90E5000D00A3F82413
+:108BE00003E8C825A0F9000D8F9100B88F8D00BC57
+:108BF0008E380020ADB800108E290024ADA90014D5
+:108C00008E2F0028ADAF00188E2E002C0E000CF613
+:108C1000ADAE001C8FB0001C240C0002120C00EE44
+:108C20008F9000D08FA3001C006088211460000288
+:108C30000060A8210000A02156A0FE390291A023C7
+:108C40000014882B8FA90010960700103C1E0020EE
+:108C50000136402302C750213112FFFFA60A00103F
+:108C6000AFB20010AF5E0030000000009617001099
+:108C7000961300121277008F000000008E05000C82
+:108C80008E0B00080016698000AD7021000DC7C36F
+:108C900001CDA82B0178782101F56021AE0E000CE2
+:108CA000AE0C00088FB300100013B82B02378024DD
+:108CB0001200FF048F9000D00A000E3C000000005C
+:108CC0008E4D0038A6600008240B0003AE6D000036
+:108CD0008E500034A260000A8F9800B8AE70000475
+:108CE0003C0500809311003FA26B000C8E6F000CBE
+:108CF0003C0EFF9FA271000B01E5102535CCFFFF54
+:108D00003C03FFEF8F9200B8004C30243464FFFF27
+:108D100000C4F824AE7F000C8E590014964800124F
+:108D20008F8A00B0AE7900108E490014AE60001832
+:108D3000AE600020AE690014AE6000248E470018BB
+:108D400031093FFF0009F180AE6700288E4D000811
+:108D500003CA802131180001AE6D00308E4F000C27
+:108D60008F8C00AC001089C200185B80022B282178
+:108D7000240E0002A665001CA6600036AE6F002C13
+:108D8000A18E00009763003C8F8A00AC3C04420037
+:108D90003062FFFF00443025AD4600048F9F00B8CD
+:108DA000240700012411C0008FF30038240600348A
+:108DB000AD5300188FF90034AD59001CAD40000CC4
+:108DC000AD400010A5400014A5400016A5400020AD
+:108DD000A5400022AD400024A5550002A147000196
+:108DE0008F9E00AC8F8800B88F9200BCAFD5000872
+:108DF000910D0000A24D00008F9000B88F8B00BC39
+:108E000092180001A17800018F8400BC94850002B3
+:108E100000B1782401E97025A48E0002908C000234
+:108E20003183003FA08300028F8300D08F8400BC79
+:108E3000906200BC305300025260000124060030F2
+:108E4000AC8600048C6F007C2403FFBF02A0882145
+:108E5000AC8F0008908E000D31CC007FA08C000DEF
+:108E60008F8600BC90C2000D00432024A0C4000DDA
+:108E70008F8900BC913F000D37F90020A139000D0A
+:108E80008F8800B88F9300BC8D070020AE6700105C
+:108E90008D0A0024AE6A00148D1E0028AE7E0018D4
+:108EA0008D12002C0E000CF6AE72001C0A00103D54
+:108EB0008F9000D0960E00148E03000431CCFFFF7B
+:108EC000000C10C000622021AF44003C8E1F000443
+:108ED0008F46003C03E6C8231B20003C0000000036
+:108EE0008E0F000025E200013C05001034B500089B
+:108EF000AF420038AF550030000000000000000015
+:108F00000000000000000000000000000000000061
+:108F100000000000000000008F580000330B00200C
+:108F20001160FFFD000000008F5304003C0D002085
+:108F3000AE1300088F570404AE17000CAF4D00307D
+:108F4000000000003C0608008CC600442416000106
+:108F500010D600BD00000000961F00123C0508005E
+:108F60008CA5004000BFC821A61900129609001464
+:108F700025270001A6070014960A00143144FFFFBC
+:108F80005486FF498FB30010A60000140E000E1681
+:108F900030A5FFFF3C0408008C84002496030012D7
+:108FA0000044102300623023A60600120A00105964
+:108FB0008FB30010A08300018F8200AC2404000155
+:108FC000AC4400080A000FF08F8300D08E0200002E
+:108FD0000A0010EA3C0500108F8200C08FA7001C19
+:108FE000921800D0920B00D0920E00D0331100FFE7
+:108FF000316900FF00117940000928C001E56021B6
+:1090000031C300FF036C50210003314000C2C8216E
+:10901000255F0088AF9F00ACAF9900BCA1470088D6
+:109020009768003C03C020218F9100AC0E000CD645
+:109030003110FFFF00026B80020DC0253C0442008E
+:109040008F8D00B803045825AE2B00048DA900387D
+:109050008F8B00AC0000882100118100AD690018E1
+:109060008DAF00343C087FFF3504FFFFAD6F001C5F
+:1090700091AC003E8D65001C8D660018000C190037
+:10908000000C770200A33821020E102500E3F82B14
+:1090900000C2C821033F5021AD67001CAD6A001813
+:1090A000AD60000CAD60001091B8003E24050005D5
+:1090B00003C45024A578001495A9000403C02021FE
+:1090C000A569001691AF003EA56F002095B1000480
+:1090D000A5710022AD60002491AE003FA56E000294
+:1090E00091B0003E91AC003D01901023244300015B
+:1090F000A16300018F8600AC8F9F00BCACDE00082E
+:10910000A3E500008F9000BC8F9900B82405FFBF35
+:1091100096070002973800120247782433093FFF70
+:1091200001E98825A6110002921200022418FFDF2F
+:10913000324E003F35CD0040A20D00028F8600BCAC
+:109140008F8C00D02412FFFFACC000048D8B007CFC
+:109150003C0C8000ACCB000890C2000D3043007F77
+:10916000A0C3000D8F8700BC90FF000D03E5C8244D
+:10917000A0F9000D8F9100BC9229000D01387824D0
+:10918000A22F000D8F9000BCAE120010AE1500147F
+:10919000920E00182415FF8002AE6825A20D00185B
+:1091A0008F8500BC8F8300B88CAB0018016C102435
+:1091B000004A3025ACA600189068003EA0A8001C0C
+:1091C0008F9F00B88F8700BC8F9800D097F900045C
+:1091D000A4F9001E0E0002138F0500848F8600D0B4
+:1091E000000279400002490090D200BC01E98821C8
+:1091F000004028213255000212A0000303D1202193
+:109200000002A8800095202190CD00BC31B200045E
+:109210001240000333DF0003000540800088202156
+:10922000240600048F9E00BC00DFC8233327000300
+:1092300000875021AFCA00040E000CF6A665003866
+:109240000A0010388F9000D0961E00123C080800CB
+:109250008D080024011E9021A61200120A00105948
+:109260008FB3001027BDFFE03C1808008F18005096
+:10927000AFB00010AFBF0018AFB10014AF8400B0A2
+:1092800093710074030478212410FF8031EE007F75
+:109290003225007F01F0582401DA68213C0C000AD5
+:1092A000A38500C401AC2821AF4B002494A9001071
+:1092B0009768000690A600620080382124020030E2
+:1092C0000109202330C300F0AF8500D010620019DF
+:1092D0003090FFFF90AE0062240DFFF0240A005092
+:1092E00001AE6024318B00FF116A002F00000000E6
+:1092F00016000007241F0C00AF5F00248FB100147C
+:109300008FBF00188FB0001003E0000827BD0020B9
+:109310000E000E1C02002021241F0C00AF5F002451
+:109320008FB100148FBF00188FB0001003E0000849
+:1093300027BD002094A200E094A400E290BF011396
+:10934000008218263079FFFF33E700C014E00009DF
+:109350002F31000116000038000000005620FFE603
+:10936000241F0C000E000D18000000000A0011ED73
+:10937000241F0C001620FFDE000000000E000D1858
+:10938000000000001440FFDC241F0C001600002227
+:109390008F8300D0906901133122003FA062011336
+:1093A0000A0011ED241F0C0094AF00D48F8600D466
+:1093B00000E02821240400050E000C5C31F0FFFFC2
+:1093C0001440000524030003979100E600001821D3
+:1093D0002625FFFFA78500E68F5801B80700FFFE8E
+:1093E0003C196013AF400180241F0C00AF50018472
+:1093F000007938253C101000AF4701888FB1001468
+:10940000AF5001B8AF5F00248FB000108FBF0018BD
+:1094100003E0000827BD00200E000E1C02002021E2
+:109420005040FFB5241F0C008F8300D090690113BA
+:109430000A0012163122003F0E000E1C02002021ED
+:109440001440FFAD241F0C00122000078F8300D0B2
+:10945000906801133106003F34C20040A06201133E
+:109460000A0011ED241F0C000E000D180000000072
+:109470005040FFA1241F0C008F8300D0906801137F
+:109480003106003F0A00124634C20040AF9B00C8BC
+:1094900003E00008AF8000EC3089FFFF0009404284
+:1094A0002D020041000921801440000200095040B3
+:1094B00024080040000830C0000811400046582130
+:1094C000256701A800E2C821272F007F2418FF800C
+:1094D00001F818240064302100CA702125CC00FF57
+:1094E000240DFF00018D202425650088240A0088B2
+:1094F0003C010800AC2A004C3C010800AC2500509F
+:10950000AF8400D43C010800AC2900603C01080095
+:10951000AC2800643C010800AC2700543C01080062
+:10952000AC2300583C010800AC26005C03E00008B6
+:1095300000000000308300FF30C6FFFF30E400FF72
+:109540008F4201B80440FFFE00034C00012438257F
+:109550003C08600000E820253C031000AF45018076
+:10956000AF460184AF44018803E00008AF4301B86F
+:109570008F86001C3C096012352700108CCB00043C
+:109580003C0C600E35850010316A00062D48000144
+:10959000ACE800C48CC40004ACA431808CC20008C8
+:1095A00094C30002ACA2318403E00008A78300E466
+:1095B0003C0308008C6300508F8400E88F86001CF9
+:1095C0002402FF800064C0210302C824AF59002890
+:1095D0008CCD00043305007F00BA78213C0E000CCE
+:1095E00001EE2821ACAD00588CC80008AF8500D032
+:1095F0003C076012ACA8005C8CCC001034E8001072
+:10960000ACAC000C8CCB000CACAB000894AA0014E2
+:109610003C0208008C42004425490001A4A9001422
+:1096200094A400143083FFFF106200178F8400D0D1
+:109630003C0A08008D4A0040A4AA00128CCE0018F3
+:10964000AC8E00248CCD0014AC8D00208CC700188B
+:10965000AC87002C8CCC001424060001AC8C0028B4
+:109660008D0B00BC5166001A8D0200B48D0200B84B
+:10967000A482003A948F003AA48F003C948800D4CE
+:1096800003E000083102FFFF3C0908008D29002497
+:10969000A4A000148F8400D0A4A900128CCE0018BE
+:1096A000AC8E00248CCD0014AC8D00208CC700182B
+:1096B000AC87002C8CCC001424060001AC8C002854
+:1096C0008D0B00BC5566FFEA8D0200B88D0200B418
+:1096D000A482003A948F003AA48F003C948800D46E
+:1096E00003E000083102FFFF8F86001C3C0C0800DD
+:1096F0008D8C0050240BFF808CCD00083C03000CA7
+:10970000000D51C0018A4021010B4824AF8A00E8B6
+:10971000AF49002890C700073105007F00BA10212B
+:109720000043282130E4000410800039AF8500D0C8
+:1097300090CF000731EE000811C000380000000093
+:109740008CD9000C8CC400140324C02B13000030EF
+:10975000000000008CC2000CACA200648CCD00188C
+:109760002402FFF8ACAD00688CCC0010ACAC0080DB
+:109770008CCB000CACAB00848CCA001CACAA007C67
+:1097800090A900BC01224024A0A800BC90C30007FF
+:109790003067000810E000048F8500D090AF00BC57
+:1097A00035EE0001A0AE00BC90D9000733380001AF
+:1097B000130000088F8300D08F8700D0240400346A
+:1097C00090E800BC35030002A0E300BC8F8300D00A
+:1097D000AC6400C090C900073126000210C000052B
+:1097E00000000000906A00BC35420004A06200BC8A
+:1097F0008F8300D09065011330AD003FA06D011341
+:109800008F8C00D0958B00D403E000083162FFFFFD
+:109810008CC200140A001305000000000A001306A1
+:10982000ACA0006427BDFFD8AFB000108F90001C23
+:10983000AFBF0024AFB40020AFB20018AFB1001426
+:10984000AFB3001C9613000E3C07600A3C14600680
+:109850003264FFFF369300100E00125534F40410EA
+:109860008F8400D43C11600E0E00099B363100102D
+:10987000920E00153C0708008CE700603C12601255
+:1098800031CD000FA38D00F08E0E00048E0D000868
+:1098900096080012961F00109619001A9618001EBE
+:1098A000960F001C310CFFFF33EBFFFF332AFFFF45
+:1098B0003309FFFF31E6FFFF3C010800AC2B0040FD
+:1098C0003C010800AC2C00243C010800AC2A0044F8
+:1098D000AE293178AE26317C92020015960300162F
+:1098E00036520010304400FF3065FFFF3C06080090
+:1098F0008CC60064AE243188AE4500B492080014D2
+:1099000096190018241F0001011FC004332FFFFF08
+:109910003C0508008CA50058AE5800B8AE4F00BCFE
+:10992000920C0014AF8E00D8AF8D00DC318B00FF9D
+:10993000AE4B00C0920A0015AE670048AE66004C00
+:10994000314900FFAE4900C8AE65007C3C03080009
+:109950008C6300503C0408008C84004C3C080800D8
+:109960008D0800543C0208008C42005C8FBF00242C
+:10997000AE6300808FB00010AE8300748FB3001C04
+:10998000AE22319CAE4200DCAE2731A0AE2631A41F
+:10999000AE24318CAE233190AE283194AE2531986F
+:1099A000AE870050AE860054AE8500708FB10014B3
+:1099B000AE4700E0AE4600E4AE4400CCAE4300D07B
+:1099C000AE4800D4AE4500D88FB400208FB2001846
+:1099D00003E0000827BD002827BDFFE0AFB1001459
+:1099E000AFBF0018241100010E000845AFB00010F1
+:1099F00010510005978400E6978300CC0083102B5C
+:109A0000144000088F8500D4240700028FBF00187F
+:109A10008FB100148FB0001000E0102103E00008A7
+:109A200027BD00200E000C7A24040005AF8200E858
+:109A30001040FFF6240700020E0008498F90001C1A
+:109A4000979F00E68F9900E88F8D00C827EF0001EF
+:109A5000240E0050AF590020A78F00E6A1AE0000F1
+:109A60003C0C08008D8C00648F8600C8240A80009E
+:109A7000000C5E00ACCB0074A4C0000694C9000AC0
+:109A8000241FFF803C0D000C012AC024A4D8000A2A
+:109A900090C8000A24182000011F1825A0C3000A3E
+:109AA0008F8700C8A0E000788F8500C800003821AB
+:109AB000A0A000833C0208008C4200508F8400E884
+:109AC0000044782101FFC824AF590028960B0002FA
+:109AD00031EE007F01DA6021018D3021A4CB00D46A
+:109AE000960A0002AF8600D03C0E000425492401EE
+:109AF000A4C900E68E080004ACC800048E03000868
+:109B0000ACC30000A4C00010A4C00014A0C000D0CA
+:109B10008F8500D02403FFBFA0A000D13C04080023
+:109B20008C8400648F8200D0A04400D28E1F000C71
+:109B30008F8A00D0978F00E4AD5F001C8E19001053
+:109B400024100030AD590018A5400030A551005434
+:109B5000A5510056A54F0016AD4E0068AD580080C7
+:109B6000AD580084914D006231AC000F358B001070
+:109B7000A14B00628F8600D090C900633128007F1E
+:109B8000A0C800638F8400D02406FFFF9085006387
+:109B900000A31024A08200638F9100D000E0102168
+:109BA000923F00BC37F90001A23900BC8F8A00D077
+:109BB000938F00F0AD580064AD5000C0914E00D3BB
+:109BC000000F690031CC000F018D5825A14B00D347
+:109BD0008F8500D08F8900DCACA900E88F8800D881
+:109BE0008FBF00188FB100148FB0001027BD002068
+:109BF000ACA800ECA4A600D6A4A000E0A4A000E2BB
+:109C000003E000080000000027BDFFE0AFB0001037
+:109C10008F90001CAFB10014AFBF00188E19000464
+:109C20003C1808008F180050240FFF80001989C0CD
+:109C30000238702131CD007F01CF602401BA50215C
+:109C40003C0B000CAF4C0028014B4021950900D47F
+:109C5000950400D68E0700043131FFFFAF8800D095
+:109C60000E000913000721C08E0600048F8300C870
+:109C7000000629C0AF4500209064003E30820040BD
+:109C8000144000068F8400D0341FFFFF948300D659
+:109C90003062FFFF145F000400000000948400D6CF
+:109CA0000E0008A83084FFFF8E050004022030213A
+:109CB0008FBF00188FB100148FB000102404002251
+:109CC00000003821000529C00A00127C27BD0020B1
+:109CD00027BDFFE0AFB100143091FFFFAFB000101F
+:109CE000AFBF00181220001D000080218F86001CCD
+:109CF0008CC500002403000600053F020005140285
+:109D000030E4000714830015304500FF2CA800063E
+:109D10001100004D000558803C0C0800258C57D4DC
+:109D2000016C50218D490000012000080000000056
+:109D30008F8E00EC240D000111CD005900000000B1
+:109D4000260B00013170FFFF24CA00200211202BD6
+:109D5000014030211480FFE6AF8A001C0200102170
+:109D60008FBF00188FB100148FB0001003E00008FF
+:109D700027BD0020938700CE14E00038240400148F
+:109D80000E001338000000008F86001C2402000122
+:109D90000A00147FAF8200EC8F8900EC24080002D7
+:109DA0001128003B2404001300002821000030216A
+:109DB000240700010E00127C000000000A00147F3E
+:109DC0008F86001C8F8700EC2405000214E5FFF647
+:109DD000240400120E0012E9000000008F8500E844
+:109DE00000403021240400120E00127C00003821B3
+:109DF0000A00147F8F86001C8F8300EC241F000351
+:109E0000147FFFD0260B00010E00129B0000000003
+:109E10008F8500E800403021240200022404001055
+:109E200000003821AF8200EC0E00127C0000000020
+:109E30000A00147F8F86001C8F8F00EC240600021E
+:109E400011E6000B0000000024040010000028218F
+:109E5000000030210A00149C240700010000282182
+:109E60000E00127C000030210A00147F8F86001C37
+:109E70000E0013A500000000144000128F99001C72
+:109E80008F86001C240200030A00147FAF8200ECBE
+:109E90000E001431000000000A00147F8F86001CA1
+:109EA0000E00128B000000002402000224040014A3
+:109EB0000000282100003021000038210A0014B9D8
+:109EC000AF8200EC004038212404001097380002D3
+:109ED000000028210E00127C3306FFFF0A00147FC9
+:109EE0008F86001C8F8400C83C077FFF34E6FFFF8D
+:109EF0008C8500742402000100A61824AC83007431
+:109F000003E00008A082000510A000362CA200800B
+:109F1000274A04003C0B000524090080104000077C
+:109F20002408008030A6000F00C540212D030081C9
+:109F30001460000200A0482124080080AF4B0030CC
+:109F400000000000000000000000000011000009F7
+:109F500000003821014030218C8D000024E70004EE
+:109F600000E8602BACCD0000248400041580FFFACB
+:109F700024C60004000000000000000000000000F3
+:109F80003C0E0006010E3825AF47003000000000EF
+:109F900000000000000000008F4F000031E80010BA
+:109FA0001100FFFD000000008F42003C8F43003C89
+:109FB0000049C8210323C02B130000040000000047
+:109FC0008F4C003825860001AF4600388F47003C93
+:109FD00000A9282300E96821AF4D003C14A0FFCE62
+:109FE0002CA2008003E000080000000027BDFFD085
+:109FF0003C020002AFB100143C11000CAF45003828
+:10A00000AFB3001CAF46003C00809821AF42003047
+:10A0100024050088AF44002803512021AFBF002849
+:10A02000AFB50024AFB40020AFB200180E0014F199
+:10A03000AFB000103C1F08008FFF004C3C18080018
+:10A040008F1800642410FF8003F3A82132B9007F29
+:10A0500002B078240018A0C0033A70210018914083
+:10A0600001D12021AF4F00280E0014F10254282105
+:10A070003C0D08008DAD00502405012001B358218E
+:10A08000316C007F01705024019A48210131202158
+:10A090000E0014F1AF4A00283C0808008D08005457
+:10A0A0003C0508008CA500640113382130E6007FD0
+:10A0B00000F0182400DA202100912021AF4300286D
+:10A0C0000E0014F1000529403C0208008C420058A3
+:10A0D0003C1008008E1000601200001C0053882104
+:10A0E0002415FF800A0015743C14000C3226007FF2
+:10A0F0000235182400DA202102402821AF4300282D
+:10A10000009420210E0014F12610FFC01200000F51
+:10A11000023288212E05004110A0FFF42412100005
+:10A120003226007F001091800235182400DA2021A9
+:10A1300002402821AF430028009420210E0014F192
+:10A14000000080211600FFF3023288213C0B08003A
+:10A150008D6B005C240AFF802405000201734021FE
+:10A16000010A4824AF4900283C0408009484006296
+:10A170003110007F021A88213C07000C0E000CAA47
+:10A180000227982100402821026020218FBF00284B
+:10A190008FB500248FB400208FB3001C8FB200183D
+:10A1A0008FB100148FB000100A0014F127BD0030E9
+:10A1B0008F83001C8C62000410400003000000002C
+:10A1C00003E00008000000008C6400108C650008AB
+:10A1D0000A00152A8C66000C000000000000001B1D
+:10A1E0000000000F0000000A000000080000000648
+:10A1F000000000050000000500000004000000044D
+:10A200000000000300000003000000030000000342
+:10A210000000000300000002000000020000000235
+:10A220000000000200000002000000020000000226
+:10A230000000000200000002000000020000000216
+:10A240000000000200000002000000020000000206
+:10A2500000000001000000010000000108000F24C0
+:10A2600008000D6C08000FB80800106008000F4CC3
+:10A2700008000F8C0800119408000D88080011B820
+:10A2800008000DD8080015540800151C08000D889A
+:10A2900008000D8808000D880800124008001240D0
+:10A2A00008000D8808000D88080014E008000D88DB
+:10A2B00008000D8808000D8808000D88080013B4F8
+:10A2C00008000D8808000D8808000D8808000D881A
+:10A2D00008000D8808000D8808000D8808000D880A
+:10A2E00008000D8808000D8808000D8808000D88FA
+:10A2F00008000D8808000D8808000FAC08000D88C4
+:10A3000008000D880800167808000D8808000D88E0
+:10A3100008000D8808000D8808000D8808000D88C9
+:10A3200008000D8808000D8808000D8808000D88B9
+:10A3300008000D8808000D8808000D8808000D88A9
+:10A3400008000D8808000D8808000D88080014100A
+:10A3500008000D8808000D8808001334080012A4B6
+:10A3600008001E2C08001EFC08001F1408001F28EF
+:10A3700008001F3808001E2C08001E2C08001E2C88
+:10A3800008001ED808002E1408002E1C08002DE41A
+:10A3900008002DF008002DFC08002E08080052F4DB
+:10A3A000080052B40800528008005254080052308D
+:10A3B000080051EC0A000C840000000000000000BE
+:10A3C0000000000D727870362E322E33000000002F
+:10A3D000060203030000000000000001000000006E
+:10A3E000000000000000000000000000000000006D
+:10A3F000000000000000000000000000000000005D
+:10A40000000000000000000000000000000000004C
+:10A41000000000000000000000000000000000003C
+:10A42000000000000000000000000000000000002C
+:10A43000000000000000000000000000000000001C
+:10A44000000000000000000000000000000000000C
+:10A4500000000000000000000000000000000000FC
+:10A4600000000000000000000000000000000000EC
+:10A4700000000000000000000000000000000000DC
+:10A4800000000000000000000000000000000000CC
+:10A4900000000000000000000000000000000000BC
+:10A4A00000000000000000000000000000000000AC
+:10A4B000000000000000000000000000000000009C
+:10A4C000000000000000000000000000000000008C
+:10A4D000000000000000000000000000000000007C
+:10A4E000000000000000000000000000000000006C
+:10A4F000000000000000000000000000000000005C
+:10A50000000000000000000000000000000000004B
+:10A51000000000000000000000000000000000003B
+:10A52000000000000000000000000000000000002B
+:10A53000000000000000000000000000000000001B
+:10A54000000000000000000000000000000000000B
+:10A5500000000000000000000000000000000000FB
+:10A5600000000000000000000000000000000000EB
+:10A5700000000000000000000000000000000000DB
+:10A5800000000000000000000000000000000000CB
+:10A5900000000000000000000000000000000000BB
+:10A5A00000000000000000000000000000000000AB
+:10A5B000000000000000000000000000000000009B
+:10A5C000000000000000000000000000000000008B
+:10A5D000000000000000000000000000000000007B
+:10A5E000000000000000000000000000000000006B
+:10A5F000000000000000000000000000000000005B
+:10A60000000000000000000000000000000000004A
+:10A61000000000000000000000000000000000003A
+:10A62000000000000000000000000000000000002A
+:10A63000000000000000000000000000000000001A
+:10A64000000000000000000000000000000000000A
+:10A6500000000000000000000000000000000000FA
+:10A6600000000000000000000000000000000000EA
+:10A6700000000000000000000000000000000000DA
+:10A6800000000000000000000000000000000000CA
+:10A6900000000000000000000000000000000000BA
+:10A6A00000000000000000000000000000000000AA
+:10A6B000000000000000000000000000000000009A
+:10A6C000000000000000000000000000000000008A
+:10A6D000000000000000000000000000000000007A
+:10A6E000000000000000000000000000000000006A
+:10A6F000000000000000000000000000000000005A
+:10A700000000000000000000000000000000000049
+:10A710000000000000000000000000000000000039
+:10A720000000000000000000000000000000000029
+:10A730000000000000000000000000000000000019
+:10A740000000000000000000000000000000000009
+:10A7500000000000000000000000000000000000F9
+:10A7600000000000000000000000000000000000E9
+:10A7700000000000000000000000000000000000D9
+:10A7800000000000000000000000000000000000C9
+:10A7900000000000000000000000000000000000B9
+:10A7A00000000000000000000000000000000000A9
+:10A7B0000000000000000000000000000000000099
+:10A7C0000000000000000000000000000000000089
+:10A7D0000000000000000000000000000000000079
+:10A7E0000000000000000000000000000000000069
+:10A7F0000000000000000000000000000000000059
+:10A800000000000000000000000000000000000048
+:10A810000000000000000000000000000000000038
+:10A820000000000000000000000000000000000028
+:10A830000000000000000000000000000000000018
+:10A840000000000000000000000000000000000008
+:10A8500000000000000000000000000000000000F8
+:10A8600000000000000000000000000000000000E8
+:10A8700000000000000000000000000000000000D8
+:10A8800000000000000000000000000000000000C8
+:10A8900000000000000000000000000000000000B8
+:10A8A00000000000000000000000000000000000A8
+:10A8B0000000000000000000000000000000000098
+:10A8C0000000000000000000000000000000000088
+:10A8D0000000000000000000000000000000000078
+:10A8E0000000000000000000000000000000000068
+:10A8F0000000000000000000000000000000000058
+:10A900000000000000000000000000000000000047
+:10A910000000000000000000000000000000000037
+:10A920000000000000000000000000000000000027
+:10A930000000000000000000000000000000000017
+:10A940000000000000000000000000000000000007
+:10A9500000000000000000000000000000000000F7
+:10A9600000000000000000000000000000000000E7
+:10A9700000000000000000000000000000000000D7
+:10A9800000000000000000000000000000000000C7
+:10A9900000000000000000000000000000000000B7
+:10A9A00000000000000000000000000000000000A7
+:10A9B0000000000000000000000000000000000097
+:10A9C0000000000000000000000000000000000087
+:10A9D0000000000000000000000000000000000077
+:10A9E0000000000000000000000000000000000067
+:10A9F0000000000000000000000000000000000057
+:10AA00000000000000000000000000000000000046
+:10AA10000000000000000000000000000000000036
+:10AA20000000000000000000000000000000000026
+:10AA30000000000000000000000000000000000016
+:10AA40000000000000000000000000000000000006
+:10AA500000000000000000000000000000000000F6
+:10AA600000000000000000000000000000000000E6
+:10AA700000000000000000000000000000000000D6
+:10AA800000000000000000000000000000000000C6
+:10AA900000000000000000000000000000000000B6
+:10AAA00000000000000000000000000000000000A6
+:10AAB0000000000000000000000000000000000096
+:10AAC0000000000000000000000000000000000086
+:10AAD0000000000000000000000000000000000076
+:10AAE0000000000000000000000000000000000066
+:10AAF0000000000000000000000000000000000056
+:10AB00000000000000000000000000000000000045
+:10AB10000000000000000000000000000000000035
+:10AB20000000000000000000000000000000000025
+:10AB30000000000000000000000000000000000015
+:10AB40000000000000000000000000000000000005
+:10AB500000000000000000000000000000000000F5
+:10AB600000000000000000000000000000000000E5
+:10AB700000000000000000000000000000000000D5
+:10AB800000000000000000000000000000000000C5
+:10AB900000000000000000000000000000000000B5
+:10ABA00000000000000000000000000000000000A5
+:10ABB0000000000000000000000000000000000095
+:10ABC0000000000000000000000000000000000085
+:10ABD0000000000000000000000000000000000075
+:10ABE0000000000000000000000000000000000065
+:10ABF0000000000000000000000000000000000055
+:10AC00000000000000000000000000000000000044
+:10AC10000000000000000000000000000000000034
+:10AC20000000000000000000000000000000000024
+:10AC30000000000000000000000000000000000014
+:10AC40000000000000000000000000000000000004
+:10AC500000000000000000000000000000000000F4
+:10AC600000000000000000000000000000000000E4
+:10AC700000000000000000000000000000000000D4
+:10AC800000000000000000000000000000000000C4
+:10AC900000000000000000000000000000000000B4
+:10ACA00000000000000000000000000000000000A4
+:10ACB0000000000000000000000000000000000094
+:10ACC0000000000000000000000000000000000084
+:10ACD0000000000000000000000000000000000074
+:10ACE0000000000000000000000000000000000064
+:10ACF0000000000000000000000000000000000054
+:10AD00000000000000000000000000000000000043
+:10AD10000000000000000000000000000000000033
+:10AD20000000000000000000000000000000000023
+:10AD30000000000000000000000000000000000013
+:10AD40000000000000000000000000000000000003
+:10AD500000000000000000000000000000000000F3
+:10AD600000000000000000000000000000000000E3
+:10AD700000000000000000000000000000000000D3
+:10AD800000000000000000000000000000000000C3
+:10AD900000000000000000000000000000000000B3
+:10ADA00000000000000000000000000000000000A3
+:10ADB0000000000000000000000000000000000093
+:10ADC0000000000000000000000000000000000083
+:10ADD0000000000000000000000000000000000073
+:10ADE0000000000000000000000000000000000063
+:10ADF0000000000000000000000000000000000053
+:10AE00000000000000000000000000000000000042
+:10AE10000000000000000000000000000000000032
+:10AE20000000000000000000000000000000000022
+:10AE30000000000000000000000000000000000012
+:10AE40000000000000000000000000000000000002
+:10AE500000000000000000000000000000000000F2
+:10AE600000000000000000000000000000000000E2
+:10AE700000000000000000000000000000000000D2
+:10AE800000000000000000000000000000000000C2
+:10AE900000000000000000000000000000000000B2
+:10AEA00000000000000000000000000000000000A2
+:10AEB0000000000000000000000000000000000092
+:10AEC0000000000000000000000000000000000082
+:10AED0000000000000000000000000000000000072
+:10AEE0000000000000000000000000000000000062
+:10AEF0000000000000000000000000000000000052
+:10AF00000000000000000000000000000000000041
+:10AF10000000000000000000000000000000000031
+:10AF20000000000000000000000000000000000021
+:10AF30000000000000000000000000000000000011
+:10AF40000000000000000000000000000000000001
+:10AF500000000000000000000000000000000000F1
+:10AF600000000000000000000000000000000000E1
+:10AF700000000000000000000000000000000000D1
+:10AF800000000000000000000000000000000000C1
+:10AF900000000000000000000000000000000000B1
+:10AFA00000000000000000000000000000000000A1
+:10AFB0000000000000000000000000000000000091
+:10AFC0000000000000000000000000000000000081
+:10AFD0000000000000000000000000000000000071
+:10AFE0000000000000000000000000000000000061
+:10AFF0000000000000000000000000000000000051
+:10B000000000000000000000000000000000000040
+:10B010000000000000000000000000000000000030
+:10B020000000000000000000000000000000000020
+:10B030000000000000000000000000000000000010
+:10B040000000000000000000000000000000000000
+:10B0500000000000000000000000000000000000F0
+:10B0600000000000000000000000000000000000E0
+:10B0700000000000000000000000000000000000D0
+:10B0800000000000000000000000000000000000C0
+:10B0900000000000000000000000000000000000B0
+:10B0A00000000000000000000000000000000000A0
+:10B0B0000000000000000000000000000000000090
+:10B0C0000000000000000000000000000000000080
+:10B0D0000000000000000000000000000000000070
+:10B0E0000000000000000000000000000000000060
+:10B0F0000000000000000000000000000000000050
+:10B10000000000000000000000000000000000003F
+:10B11000000000000000000000000000000000002F
+:10B12000000000000000000000000000000000001F
+:10B13000000000000000000000000000000000000F
+:10B1400000000000000000000000000000000000FF
+:10B1500000000000000000000000000000000000EF
+:10B1600000000000000000000000000000000000DF
+:10B1700000000000000000000000000000000000CF
+:10B1800000000000000000000000000000000000BF
+:10B1900000000000000000000000000000000000AF
+:10B1A000000000000000000000000000000000009F
+:10B1B000000000000000000000000000000000008F
+:10B1C000000000000000000000000000000000007F
+:10B1D000000000000000000000000000000000006F
+:10B1E000000000000000000000000000000000005F
+:10B1F000000000000000000000000000000000004F
+:10B20000000000000000000000000000000000003E
+:10B21000000000000000000000000000000000002E
+:10B22000000000000000000000000000000000001E
+:10B23000000000000000000000000000000000000E
+:10B2400000000000000000000000000000000000FE
+:10B2500000000000000000000000000000000000EE
+:10B2600000000000000000000000000000000000DE
+:10B2700000000000000000000000000000000000CE
+:10B2800000000000000000000000000000000000BE
+:10B2900000000000000000000000000000000000AE
+:10B2A000000000000000000000000000000000009E
+:10B2B000000000000000000000000000000000008E
+:10B2C000000000000000000000000000000000007E
+:10B2D000000000000000000000000000000000006E
+:10B2E000000000000000000000000000000000005E
+:10B2F000000000000000000000000000000000004E
+:10B30000000000000000000000000000000000003D
+:10B31000000000000000000000000000000000002D
+:10B32000000000000000000000000000000000001D
+:10B33000000000000000000000000000000000000D
+:10B3400000000000000000000000000000000000FD
+:10B3500000000000000000000000000000000000ED
+:10B3600000000000000000000000000000000000DD
+:10B3700000000000000000000000000000000000CD
+:10B3800000000000000000000000000000000000BD
+:10B3900000000000000000000000000000000000AD
+:10B3A000000000000000000000000000000000009D
+:10B3B000000000000000000000000000000000008D
+:10B3C000000000000000000000000000000000007D
+:10B3D000000000000000000000000000000000006D
+:10B3E000000000000000000000000000000000005D
+:10B3F000000000000000000000000000000000004D
+:10B40000000000000000000000000000000000003C
+:10B41000000000000000000000000000000000002C
+:10B42000000000000000000000000000000000001C
+:10B43000000000000000000000000000000000000C
+:10B4400000000000000000000000000000000000FC
+:10B4500000000000000000000000000000000000EC
+:10B4600000000000000000000000000000000000DC
+:10B4700000000000000000000000000000000000CC
+:10B4800000000000000000000000000000000000BC
+:10B4900000000000000000000000000000000000AC
+:10B4A000000000000000000000000000000000009C
+:10B4B000000000000000000000000000000000008C
+:10B4C000000000000000000000000000000000007C
+:10B4D000000000000000000000000000000000006C
+:10B4E000000000000000000000000000000000005C
+:10B4F000000000000000000000000000000000004C
+:10B50000000000000000000000000000000000003B
+:10B51000000000000000000000000000000000002B
+:10B52000000000000000000000000000000000001B
+:10B53000000000000000000000000000000000000B
+:10B5400000000000000000000000000000000000FB
+:10B5500000000000000000000000000000000000EB
+:10B5600000000000000000000000000000000000DB
+:10B5700000000000000000000000000000000000CB
+:10B5800000000000000000000000000000000000BB
+:10B5900000000000000000000000000000000000AB
+:10B5A000000000000000000000000000000000009B
+:10B5B000000000000000000000000000000000008B
+:10B5C000000000000000000000000000000000007B
+:10B5D000000000000000000000000000000000006B
+:10B5E000000000000000000000000000000000005B
+:10B5F000000000000000000000000000000000004B
+:10B60000000000000000000000000000000000003A
+:10B61000000000000000000000000000000000002A
+:10B62000000000000000000000000000000000001A
+:10B63000000000000000000000000000000000000A
+:10B6400000000000000000000000000000000000FA
+:10B6500000000000000000000000000000000000EA
+:10B6600000000000000000000000000000000000DA
+:10B6700000000000000000000000000000000000CA
+:10B6800000000000000000000000000000000000BA
+:10B6900000000000000000000000000000000000AA
+:10B6A000000000000000000000000000000000009A
+:10B6B000000000000000000000000000000000008A
+:10B6C000000000000000000000000000000000007A
+:10B6D000000000000000000000000000000000006A
+:10B6E000000000000000000000000000000000005A
+:10B6F000000000000000000000000000000000004A
+:10B700000000000000000000000000000000000039
+:10B710000000000000000000000000000000000029
+:10B720000000000000000000000000000000000019
+:10B730000000000000000000000000000000000009
+:10B7400000000000000000000000000000000000F9
+:10B7500000000000000000000000000000000000E9
+:10B7600000000000000000000000000000000000D9
+:10B7700000000000000000000000000000000000C9
+:10B7800000000000000000000000000000000000B9
+:10B7900000000000000000000000000000000000A9
+:10B7A0000000000000000000000000000000000099
+:10B7B0000000000000000000000000000000000089
+:10B7C0000000000000000000000000000000000079
+:10B7D0000000000000000000000000000000000069
+:10B7E0000000000000000000000000000000000059
+:10B7F0000000000000000000000000000000000049
+:10B800000000000000000000000000000000000038
+:10B810000000000000000000000000000000000028
+:10B820000000000000000000000000000000000018
+:10B830000000000000000000000000000000000008
+:10B8400000000000000000000000000000000000F8
+:10B8500000000000000000000000000000000000E8
+:10B8600000000000000000000000000000000000D8
+:10B8700000000000000000000000000000000000C8
+:10B8800000000000000000000000000000000000B8
+:10B8900000000000000000000000000000000000A8
+:10B8A0000000000000000000000000000000000098
+:10B8B0000000000000000000000000000000000088
+:10B8C0000000000000000000000000000000000078
+:10B8D0000000000000000000000000000000000068
+:10B8E0000000000000000000000000000000000058
+:10B8F0000000000000000000000000000000000048
+:10B900000000000000000000000000000000000037
+:10B910000000000000000000000000000000000027
+:10B920000000000000000000000000000000000017
+:10B930000000000000000000000000000000000007
+:10B9400000000000000000000000000000000000F7
+:10B9500000000000000000000000000000000000E7
+:10B9600000000000000000000000000000000000D7
+:10B9700000000000000000000000000000000000C7
+:10B9800000000000000000000000000000000000B7
+:10B9900000000000000000000000000000000000A7
+:10B9A0000000000000000000000000000000000097
+:10B9B0000000000000000000000000000000000087
+:10B9C0000000000000000000000000000000000077
+:10B9D0000000000000000000000000000000000067
+:10B9E0000000000000000000000000000000000057
+:10B9F0000000000000000000000000000000000047
+:10BA00000000000000000000000000000000000036
+:10BA10000000000000000000000000000000000026
+:10BA20000000000000000000000000000000000016
+:10BA30000000000000000000000000000000000006
+:10BA400000000000000000000000000000000000F6
+:10BA500000000000000000000000000000000000E6
+:10BA600000000000000000000000000000000000D6
+:10BA700000000000000000000000000000000000C6
+:10BA800000000000000000000000000000000000B6
+:10BA900000000000000000000000000000000000A6
+:10BAA0000000000000000000000000000000000096
+:10BAB0000000000000000000000000000000000086
+:10BAC0000000000000000000000000000000000076
+:10BAD0000000000000000000000000000000000066
+:10BAE0000000000000000000000000000000000056
+:10BAF0000000000000000000000000000000000046
+:10BB00000000000000000000000000000000000035
+:10BB10000000000000000000000000000000000025
+:10BB20000000000000000000000000000000000015
+:10BB30000000000000000000000000000000000005
+:10BB400000000000000000000000000000000000F5
+:10BB500000000000000000000000000000000000E5
+:10BB600000000000000000000000000000000000D5
+:10BB700000000000000000000000000000000000C5
+:10BB800000000000000000000000000000000000B5
+:10BB900000000000000000000000000000000000A5
+:10BBA0000000000000000000000000000000000095
+:10BBB0000000000000000000000000000000000085
+:10BBC0000000000000000000000000000000000075
+:10BBD0000000000000000000000000000000000065
+:10BBE0000000000000000000000000000000000055
+:10BBF0000000000000000000000000000000000045
+:10BC00000000000000000000000000000000000034
+:10BC10000000000000000000000000000000000024
+:10BC20000000000000000000000000000000000014
+:10BC30000000000000000000000000000000000004
+:10BC400000000000000000000000000000000000F4
+:10BC500000000000000000000000000000000000E4
+:10BC600000000000000000000000000000000000D4
+:10BC700000000000000000000000000000000000C4
+:10BC800000000000000000000000000000000000B4
+:10BC900000000000000000000000000000000000A4
+:10BCA0000000000000000000000000000000000094
+:10BCB0000000000000000000000000000000000084
+:10BCC0000000000000000000000000000000000074
+:10BCD0000000000000000000000000000000000064
+:10BCE0000000000000000000000000000000000054
+:10BCF0000000000000000000000000000000000044
+:10BD00000000000000000000000000000000000033
+:10BD10000000000000000000000000000000000023
+:10BD20000000000000000000000000000000000013
+:10BD30000000000000000000000000000000000003
+:10BD400000000000000000000000000000000000F3
+:10BD500000000000000000000000000000000000E3
+:10BD600000000000000000000000000000000000D3
+:10BD700000000000000000000000000000000000C3
+:10BD800000000000000000000000000000000000B3
+:10BD900000000000000000000000000000000000A3
+:10BDA0000000000000000000000000000000000093
+:10BDB0000000000000000000000000000000000083
+:10BDC0000000000000000000000000000000000073
+:10BDD0000000000000000000000000000000000063
+:10BDE0000000000000000000000000000000000053
+:10BDF0000000000000000000000000000000000043
+:10BE00000000000000000000000000000000000032
+:10BE10000000000000000000000000000000000022
+:10BE20000000000000000000000000000000000012
+:10BE30000000000000000000000000000000000002
+:10BE400000000000000000000000000000000000F2
+:10BE500000000000000000000000000000000000E2
+:10BE600000000000000000000000000000000000D2
+:10BE700000000000000000000000000000000000C2
+:10BE800000000000000000000000000000000000B2
+:10BE900000000000000000000000000000000000A2
+:10BEA0000000000000000000000000000000000092
+:10BEB0000000000000000000000000000000000082
+:10BEC0000000000000000000000000000000000072
+:10BED0000000000000000000000000000000000062
+:10BEE0000000000000000000000000000000000052
+:10BEF0000000000000000000000000000000000042
+:10BF00000000000000000000000000000000000031
+:10BF10000000000000000000000000000000000021
+:10BF20000000000000000000000000000000000011
+:10BF30000000000000000000000000000000000001
+:10BF400000000000000000000000000000000000F1
+:10BF500000000000000000000000000000000000E1
+:10BF600000000000000000000000000000000000D1
+:10BF700000000000000000000000000000000000C1
+:10BF800000000000000000000000000000000000B1
+:10BF900000000000000000000000000000000000A1
+:10BFA0000000000000000000000000000000000091
+:10BFB0000000000000000000000000000000000081
+:10BFC0000000000000000000000000000000000071
+:10BFD0000000000000000000000000000000000061
+:10BFE0000000000000000000000000000000000051
+:10BFF0000000000000000000000000000000000041
+:10C000000000000000000000000000000000000030
+:10C010000000000000000000000000000000000020
+:10C020000000000000000000000000000000000010
+:10C030000000000000000000000000000000000000
+:10C0400000000000000000000000000000000000F0
+:10C0500000000000000000000000000000000000E0
+:10C0600000000000000000000000000000000000D0
+:10C0700000000000000000000000000000000000C0
+:10C0800000000000000000000000000000000000B0
+:10C0900000000000000000000000000000000000A0
+:10C0A0000000000000000000000000000000000090
+:10C0B0000000000000000000000000000000000080
+:10C0C0000000000000000000000000000000000070
+:10C0D0000000000000000000000000000000000060
+:10C0E0000000000000000000000000000000000050
+:10C0F0000000000000000000000000000000000040
+:10C10000000000000000000000000000000000002F
+:10C11000000000000000000000000000000000001F
+:10C12000000000000000000000000000000000000F
+:10C1300000000000000000000000000000000000FF
+:10C1400000000000000000000000000000000000EF
+:10C1500000000000000000000000000000000000DF
+:10C1600000000000000000000000000000000000CF
+:10C1700000000000000000000000000000000000BF
+:10C1800000000000000000000000000000000000AF
+:10C19000000000000000000000000000000000009F
+:10C1A000000000000000000000000000000000008F
+:10C1B000000000000000000000000000000000007F
+:10C1C000000000000000000000000000000000006F
+:10C1D000000000000000000000000000000000005F
+:10C1E000000000000000000000000000000000004F
+:10C1F000000000000000000000000000000000003F
+:10C20000000000000000000000000000000000002E
+:10C21000000000000000000000000000000000001E
+:10C22000000000000000000000000000000000000E
+:10C2300000000000000000000000000000000000FE
+:10C2400000000000000000000000000000000000EE
+:10C2500000000000000000000000000000000000DE
+:10C2600000000000000000000000000000000000CE
+:10C2700000000000000000000000000000000000BE
+:10C2800000000000000000000000000000000000AE
+:10C29000000000000000000000000000000000009E
+:10C2A000000000000000000000000000000000008E
+:10C2B000000000000000000000000000000000007E
+:10C2C000000000000000000000000000000000006E
+:10C2D000000000000000000000000000000000005E
+:10C2E000000000000000000000000000000000004E
+:10C2F000000000000000000000000000000000003E
+:10C30000000000000000000000000000000000002D
+:10C31000000000000000000000000000000000001D
+:10C32000000000000000000000000000000000000D
+:10C3300000000000000000000000000000000000FD
+:10C3400000000000000000000000000000000000ED
+:10C3500000000000000000000000000000000000DD
+:10C3600000000000000000000000000000000000CD
+:10C3700000000000000000000000000000000000BD
+:10C3800000000000000000000000000000000000AD
+:10C39000000000000000000000000000000000009D
+:10C3A000000000000000000000000000000000008D
+:10C3B000000000000000000000000000000000007D
+:10C3C000000000000000000000000000000000006D
+:10C3D000000000000000000000000000000000005D
+:10C3E000000000000000000000000000000000004D
+:10C3F000000000000000000000000000000000003D
+:10C40000000000000000000000000000000000002C
+:10C41000000000000000000000000000000000001C
+:10C42000000000000000000000000000000000000C
+:10C4300000000000000000000000000000000000FC
+:10C4400000000000000000000000000000000000EC
+:10C4500000000000000000000000000000000000DC
+:10C4600000000000000000000000000000000000CC
+:10C4700000000000000000000000000000000000BC
+:10C4800000000000000000000000000000000000AC
+:10C49000000000000000000000000000000000009C
+:10C4A000000000000000000000000000000000008C
+:10C4B000000000000000000000000000000000007C
+:10C4C000000000000000000000000000000000006C
+:10C4D000000000000000000000000000000000005C
+:10C4E000000000000000000000000000000000004C
+:10C4F000000000000000000000000000000000003C
+:10C50000000000000000000000000000000000002B
+:10C51000000000000000000000000000000000001B
+:10C52000000000000000000000000000000000000B
+:10C5300000000000000000000000000000000000FB
+:10C5400000000000000000000000000000000000EB
+:10C5500000000000000000000000000000000000DB
+:10C5600000000000000000000000000000000000CB
+:10C5700000000000000000000000000000000000BB
+:10C5800000000000000000000000000000000000AB
+:10C59000000000000000000000000000000000009B
+:10C5A000000000000000000000000000000000008B
+:10C5B000000000000000000000000000000000007B
+:10C5C000000000000000000000000000000000006B
+:10C5D000000000000000000000000000000000005B
+:10C5E000000000000000000000000000000000004B
+:10C5F000000000000000000000000000000000003B
+:10C60000000000000000000000000000000000002A
+:10C61000000000000000000000000000000000001A
+:10C62000000000000000000000000000000000000A
+:10C6300000000000000000000000000000000000FA
+:10C6400000000000000000000000000000000000EA
+:10C6500000000000000000000000000000000000DA
+:10C6600000000000000000000000000000000000CA
+:10C6700000000000000000000000000000000000BA
+:10C6800000000000000000000000000000000000AA
+:10C69000000000000000000000000000000000009A
+:10C6A000000000000000000000000000000000008A
+:10C6B000000000000000000000000000000000007A
+:10C6C000000000000000000000000000000000006A
+:10C6D000000000000000000000000000000000005A
+:10C6E000000000000000000000000000000000004A
+:10C6F000000000000000000000000000000000003A
+:10C700000000000000000000000000000000000029
+:10C710000000000000000000000000000000000019
+:10C720000000000000000000000000000000000009
+:10C7300000000000000000000000000000000000F9
+:10C7400000000000000000000000000000000000E9
+:10C7500000000000000000000000000000000000D9
+:10C7600000000000000000000000000000000000C9
+:10C7700000000000000000000000000000000000B9
+:10C7800000000000000000000000000000000000A9
+:10C790000000000000000000000000000000000099
+:10C7A0000000000000000000000000000000000089
+:10C7B0000000000000000000000000000000000079
+:10C7C0000000000000000000000000000000000069
+:10C7D0000000000000000000000000000000000059
+:10C7E0000000000000000000000000000000000049
+:10C7F0000000000000000000000000000000000039
+:10C800000000000000000000000000000000000028
+:10C810000000000000000000000000000000000018
+:10C820000000000000000000000000000000000008
+:10C8300000000000000000000000000000000000F8
+:10C8400000000000000000000000000000000000E8
+:10C8500000000000000000000000000000000000D8
+:10C8600000000000000000000000000000000000C8
+:10C8700000000000000000000000000000000000B8
+:10C8800000000000000000000000000000000000A8
+:10C890000000000000000000000000000000000098
+:10C8A0000000000000000000000000000000000088
+:10C8B0000000000000000000000000000000000078
+:10C8C0000000000000000000000000000000000068
+:10C8D0000000000000000000000000000000000058
+:10C8E0000000000000000000000000000000000048
+:10C8F0000000000000000000000000000000000038
+:10C900000000000000000000000000000000000027
+:10C910000000000000000000000000000000000017
+:10C920000000000000000000000000000000000007
+:10C9300000000000000000000000000000000000F7
+:10C9400000000000000000000000000000000000E7
+:10C9500000000000000000000000000000000000D7
+:10C9600000000000000000000000000000000000C7
+:10C9700000000000000000000000000000000000B7
+:10C9800000000000000000000000000000000000A7
+:10C990000000000000000000000000000000000097
+:10C9A0000000000000000000000000000000000087
+:10C9B0000000000000000000000000000000000077
+:10C9C0000000000000000000000000000000000067
+:10C9D0000000000000000000000000000000000057
+:10C9E0000000000000000000000000000000000047
+:10C9F0000000000000000000000000000000000037
+:10CA00000000000000000000000000000000000026
+:10CA10000000000000000000000000000000000016
+:10CA20000000000000000000000000000000000006
+:10CA300000000000000000000000000000000000F6
+:10CA400000000000000000000000000000000000E6
+:10CA500000000000000000000000000000000000D6
+:10CA600000000000000000000000000000000000C6
+:10CA700000000000000000000000000000000000B6
+:10CA800000000000000000000000000000000000A6
+:10CA90000000000000000000000000000000000096
+:10CAA0000000000000000000000000000000000086
+:10CAB0000000000000000000000000000000000076
+:10CAC0000000000000000000000000000000000066
+:10CAD0000000000000000000000000000000000056
+:10CAE0000000000000000000000000000000000046
+:10CAF0000000000000000000000000000000000036
+:10CB00000000000000000000000000000000000025
+:10CB10000000000000000000000000000000000015
+:10CB20000000000000000000000000000000000005
+:10CB300000000000000000000000000000000000F5
+:10CB400000000000000000000000000000000000E5
+:10CB500000000000000000000000000000000000D5
+:10CB600000000000000000000000000000000000C5
+:10CB700000000000000000000000000000000000B5
+:10CB800000000000000000000000000000000000A5
+:10CB90000000000000000000000000000000000095
+:10CBA0000000000000000000000000000000000085
+:10CBB0000000000000000000000000000000000075
+:10CBC0000000000000000000000000000000000065
+:10CBD0000000000000000000000000000000000055
+:10CBE0000000000000000000000000000000000045
+:10CBF0000000000000000000000000000000000035
+:10CC00000000000000000000000000000000000024
+:10CC10000000000000000000000000000000000014
+:10CC20000000000000000000000000000000000004
+:10CC300000000000000000000000000000000000F4
+:10CC400000000000000000000000000000000000E4
+:10CC500000000000000000000000000000000000D4
+:10CC600000000000000000000000000000000000C4
+:10CC700000000000000000000000000000000000B4
+:10CC800000000000000000000000000000000000A4
+:10CC90000000000000000000000000000000000094
+:10CCA0000000000000000000000000000000000084
+:10CCB0000000000000000000000000000000000074
+:10CCC0000000000000000000000000000000000064
+:10CCD0000000000000000000000000000000000054
+:10CCE0000000000000000000000000000000000044
+:10CCF0000000000000000000000000000000000034
+:10CD00000000000000000000000000000000000023
+:10CD10000000000000000000000000000000000013
+:10CD20000000000000000000000000000000000003
+:10CD300000000000000000000000000000000000F3
+:10CD400000000000000000000000000000000000E3
+:10CD500000000000000000000000000000000000D3
+:10CD600000000000000000000000000000000000C3
+:10CD700000000000000000000000000000000000B3
+:10CD800000000000000000000000000000000000A3
+:10CD90000000000000000000000000000000000093
+:10CDA0000000000000000000000000000000000083
+:10CDB0000000000000000000000000000000000073
+:10CDC0000000000000000000000000000000000063
+:10CDD0000000000000000000000000000000000053
+:10CDE0000000000000000000000000000000000043
+:10CDF0000000000000000000000000000000000033
+:10CE00000000000000000000000000000000000022
+:10CE10000000000000000000000000000000000012
+:10CE20000000000000000000000000000000000002
+:10CE300000000000000000000000000000000000F2
+:10CE400000000000000000000000000000000000E2
+:10CE500000000000000000000000000000000000D2
+:10CE600000000000000000000000000000000000C2
+:10CE700000000000000000000000000000000000B2
+:10CE800000000000000000000000000000000000A2
+:10CE90000000000000000000000000000000000092
+:10CEA0000000000000000000000000000000000082
+:10CEB0000000000000000000000000000000000072
+:10CEC0000000000000000000000000000000000062
+:10CED0000000000000000000000000000000000052
+:10CEE0000000000000000000000000000000000042
+:10CEF0000000000000000000000000000000000032
+:10CF00000000000000000000000000000000000021
+:10CF10000000000000000000000000000000000011
+:10CF20000000000000000000000000000000000001
+:10CF300000000000000000000000000000000000F1
+:10CF400000000000000000000000000000000000E1
+:10CF500000000000000000000000000000000000D1
+:10CF600000000000000000000000000000000000C1
+:10CF700000000000000000000000000000000000B1
+:10CF800000000000000000000000000000000000A1
+:10CF90000000000000000000000000000000000091
+:10CFA0000000000000000000000000000000000081
+:10CFB0000000000000000000000000000000000071
+:10CFC0000000000000000000000000000000000061
+:10CFD0000000000000000000000000000000000051
+:10CFE0000000000000000000000000000000000041
+:10CFF0000000000000000000000000000000000031
+:10D000000000000000000000000000000000000020
+:10D010000000000000000000000000000000000010
+:10D020000000000000000000000000000000000000
+:10D0300000000000000000000000000000000000F0
+:10D0400000000000000000000000000000000000E0
+:10D0500000000000000000000000000000000000D0
+:10D0600000000000000000000000000000000000C0
+:10D0700000000000000000000000000000000000B0
+:10D0800000000000000000000000000000000000A0
+:10D090000000000000000000000000000000000090
+:10D0A0000000000000000000000000000000000080
+:10D0B0000000000000000000000000000000000070
+:10D0C0000000000000000000000000000000000060
+:10D0D0000000000000000000000000000000000050
+:10D0E0000000000000000000000000000000000040
+:10D0F0000000000000000000000000000000000030
+:10D10000000000000000000000000000000000001F
+:10D11000000000000000000000000000000000000F
+:10D1200000000000000000000000000000000000FF
+:10D1300000000000000000000000000000000000EF
+:10D1400000000000000000000000000000000000DF
+:10D1500000000000000000000000000000000000CF
+:10D1600000000000000000000000000000000000BF
+:10D1700000000000000000000000000000000000AF
+:10D18000000000000000000000000000000000009F
+:10D19000000000000000000000000000000000008F
+:10D1A000000000000000000000000000000000007F
+:10D1B000000000000000000000000000000000006F
+:10D1C000000000000000000000000000000000005F
+:10D1D000000000000000000000000000000000004F
+:10D1E000000000000000000000000000000000003F
+:10D1F000000000000000000000000000000000002F
+:10D20000000000000000000000000000000000001E
+:10D21000000000000000000000000000000000000E
+:10D2200000000000000000000000000000000000FE
+:10D2300000000000000000000000000000000000EE
+:10D2400000000000000000000000000000000000DE
+:10D2500000000000000000000000000000000000CE
+:10D2600000000000000000000000000000000000BE
+:10D2700000000000000000000000000000000000AE
+:10D28000000000000000000000000000000000009E
+:10D29000000000000000000000000000000000008E
+:10D2A000000000000000000000000000000000007E
+:10D2B000000000000000000000000000000000006E
+:10D2C000000000000000000000000000000000005E
+:10D2D000000000000000000000000000000000004E
+:10D2E000000000000000000000000000000000003E
+:10D2F000000000000000000000000000000000002E
+:10D30000000000000000000000000000000000001D
+:10D31000000000000000000000000000000000000D
+:10D3200000000000000000000000000000000000FD
+:10D3300000000000000000000000000000000000ED
+:10D3400000000000000000000000000000000000DD
+:10D3500000000000000000000000000000000000CD
+:10D3600000000000000000000000000000000000BD
+:10D3700000000000000000000000000000000000AD
+:10D38000000000000000000000000000000000009D
+:10D39000000000000000000000000000000000008D
+:10D3A000000000000000000000000000000000007D
+:10D3B000000000000000000000000000000000006D
+:10D3C000000000000000000000000000000000005D
+:10D3D000000000000000000000000000000000004D
+:10D3E000000000000000000000000000000000003D
+:10D3F000000000000000000000000000000000002D
+:10D40000000000000000000000000000000000001C
+:10D41000000000000000000000000000000000000C
+:10D4200000000000000000000000000000000000FC
+:10D4300000000000000000000000000000000000EC
+:10D4400000000000000000000000000000000000DC
+:10D4500000000000000000000000000000000000CC
+:10D4600000000000000000000000000000000000BC
+:10D4700000000000000000000000000000000000AC
+:10D48000000000000000000000000000000000009C
+:10D49000000000000000000000000000000000008C
+:10D4A000000000000000000000000000000000007C
+:10D4B000000000000000000000000000000000006C
+:10D4C000000000000000000000000000000000005C
+:10D4D000000000000000000000000000000000004C
+:10D4E000000000000000000000000000000000003C
+:10D4F000000000000000000000000000000000002C
+:10D50000000000000000000000000000000000001B
+:10D51000000000000000000000000000000000000B
+:10D5200000000000000000000000000000000000FB
+:10D5300000000000000000000000000000000000EB
+:10D5400000000000000000000000000000000000DB
+:10D5500000000000000000000000000000000000CB
+:10D5600000000000000000000000000000000000BB
+:10D5700000000000000000000000000000000000AB
+:10D58000000000000000000000000000000000009B
+:10D59000000000000000008000000000000000000B
+:10D5A000000000000000000000000000000000007B
+:10D5B00000000000000000000000000A0000000061
+:10D5C0000000000000000000100000030000000048
+:10D5D0000000000D0000000D3C02080024427340D2
+:10D5E0003C030800246377CCAC4000000043202BB0
+:10D5F0001480FFFD244200043C1D080037BD7FFC61
+:10D6000003A0F0213C100800261032103C1C08003A
+:10D61000279C73400E0010FE000000000000000D6B
+:10D6200030A5FFFF30C600FF274301808F4201B8BD
+:10D630000440FFFE24020002AC640000A465000860
+:10D64000A066000AA062000B3C021000AC67001844
+:10D6500003E00008AF4201B83C0360008C624FF861
+:10D660000440FFFE3C020200AC644FC0AC624FC4F9
+:10D670003C02100003E00008AC624FF89482000CFA
+:10D680002486001400A0382100021302000210803A
+:10D690000082402100C8102B1040005700000000FD
+:10D6A00090C300002C6200095040005190C200015C
+:10D6B000000310803C030800246372F00043102133
+:10D6C0008C420000004000080000000090C30001F0
+:10D6D0002402000A1462003A000000000106102330
+:10D6E0002C42000A1440003624C600028CE20000DE
+:10D6F00034420100ACE2000090C2000090C300017F
+:10D7000090C4000290C5000300031C000002160034
+:10D710000043102500042200004410250045102578
+:10D7200024C60004ACE2000490C2000090C30001D3
+:10D7300090C4000290C500030002160000031C0004
+:10D740000043102500042200004410250045102548
+:10D7500024C600040A000CB8ACE2000890C3000123
+:10D76000240200041462001624C6000290C20000C5
+:10D7700090C400018CE30000000212000044102558
+:10D780003463000424C60002ACE2000C0A000CB8AA
+:10D79000ACE3000090C300012402000314620008FF
+:10D7A00024C600028CE2000090C3000024C60001E1
+:10D7B00034420008A0E300100A000CB8ACE20000FC
+:10D7C00003E000082402000190C3000124020002CB
+:10D7D0001062000224C40002010020210A000CB8DB
+:10D7E000008030210A000CB824C6000190C200015C
+:10D7F0000A000CB800C2302103E00008000010212C
+:10D8000027BDFFE8AFBF0014AFB000100E00130239
+:10D8100000808021936200052403FFFE0200202186
+:10D82000004310248FBF00148FB00010A3620005C6
+:10D830000A00130B27BD001827BDFFE8AFB000108A
+:10D84000AFBF00140E000F3C0080802193620000E7
+:10D8500024030050304200FF14430004240201005E
+:10D86000AF4201800A000D3002002021AF4001804C
+:10D87000020020218FBF00148FB000100A000FE7B4
+:10D8800027BD001827BDFF80AFBE0078AFB700747A
+:10D89000AFB20060AFBF007CAFB60070AFB5006C38
+:10D8A000AFB40068AFB30064AFB1005CAFB0005874
+:10D8B0008F5001283C0208008C4231A02403FF80D5
+:10D8C0009365003F0202102100431024AF42002460
+:10D8D0003C0208008C4231A09364000530B200FF86
+:10D8E000020210213042007F034218210004202749
+:10D8F0003C02000A0062182130840001AF8300144A
+:10D900000000F0210000B82114800053AFA00050A7
+:10D9100093430116934401128F450104306300FFC5
+:10D920003C020001308400FF00A2282403431021A0
+:10D9300003441821245640002467400014A001CD60
+:10D940002402000193620000304300FF2402002003
+:10D950001062000524020050106200060000000062
+:10D960000A000D74000000000000000D0A000D7D8B
+:10D97000AFA000303C1E080027DE738C0A000D7D2E
+:10D98000AFA000303C0208008C4200DC24420001C1
+:10D990003C010800AC2200DC0E00139F00000000D8
+:10D9A0000A000F318FBF007C8F4201043C0300202E
+:10D9B00092D3000D004310240002202B00042140CC
+:10D9C000AFA400308F4301043C02004000621824E1
+:10D9D000146000023485004000802821326200205B
+:10D9E000AFA500301440000234A6008000A0302112
+:10D9F00010C0000BAFA6003093C500088F67004C25
+:10DA00000200202100052B0034A5008130A5F08103
+:10DA10000E000C9B30C600FF0A000F2E0000000015
+:10DA20009362003E304200401040000F2402000488
+:10DA300056420007240200120200202100E02821A3
+:10DA40000E0013F702C030210A000F318FBF007C97
+:10DA500016420005000000000E000D2100002021EC
+:10DA60000A000F318FBF007C9743011A96C4000E45
+:10DA700093620035326500043075FFFF00442004D6
+:10DA8000AFA400548ED1000410A000158ED400085D
+:10DA90009362003E3042004010400007000000004A
+:10DAA0000E0013E0022020211040000D00000000B5
+:10DAB0000A000F2E000000008F6200440222102393
+:10DAC0000440016A000000008F6200480222102317
+:10DAD00004410166240400160A000E218FC20004CE
+:10DAE0008F6200480222102304400008000000005A
+:10DAF0003C0208008C423100244200013C01080035
+:10DB0000AC2231000A000F23000000008F620040A9
+:10DB100002221023184000128F8400143C020800D7
+:10DB20008C423100327300FC0000A8212442000125
+:10DB30003C010800AC2231008F6300409482011C3C
+:10DB4000022318233042FFFF0043102A50400010E8
+:10DB50002402000C8F6200400A000DF20222102302
+:10DB60009483011C9762003C0043102B1040000678
+:10DB7000000000009482011C00551023A482011CA7
+:10DB80000A000DF72402000CA480011C2402000CE2
+:10DB9000AFA200308F620040005120231880000D9A
+:10DBA00002A4102A1440012600000000149500066B
+:10DBB00002A410233A620001304200011440012007
+:10DBC0000000000002A41023022488210A000E098C
+:10DBD0003055FFFF00002021326200021040001A81
+:10DBE000326200109362003E30420040504000110B
+:10DBF0008FC200040E00130202002021240200182C
+:10DC0000A362003F936200052403FFFE020020216F
+:10DC1000004310240E00130BA362000524040039F6
+:10DC2000000028210E0013C9240600180A000F3036
+:10DC300024020001240400170040F809000000003D
+:10DC40000A000F302402000110400108000000000B
+:10DC50008F63004C8F620054028210231C4001032A
+:10DC600002831023044200010060A021AFA4001829
+:10DC7000AFB10010AFB50014934201208F65004092
+:10DC80009763003C304200FF034210210044102102
+:10DC90008FA400543063FFFF244240000083182B00
+:10DCA0008FA40030AFA20020AFA50028008320255C
+:10DCB000AFA40030AFA50024AFA0002CAFB4003457
+:10DCC0009362003E30420008504000118FC20000B5
+:10DCD00002C0202127A500380E000CB2AFA00038EA
+:10DCE0005440000B8FC200008FA200383042010068
+:10DCF000504000078FC200008FA3003C8F6200607D
+:10DD00000062102304430001AF6300608FC2000073
+:10DD10000040F80927A400108FA200303042000212
+:10DD200054400001327300FE9362003E30420040D6
+:10DD3000104000378FA200248F6200541682001A10
+:10DD40003262000124020014124200102A4200151F
+:10DD500010400006240200162402000C12420007A4
+:10DD6000326200010A000E7D000000001242000530
+:10DD7000326200010A000E7D000000000A000E78E9
+:10DD80002417000E0A000E78241700100A000E7CDB
+:10DD900024170012936200232403FFBD00431024C4
+:10DDA000A362002332620001104000198FA20024F8
+:10DDB0002402000C1242000E2A42000D1040000600
+:10DDC0002402000E2402000A124200078FA200243F
+:10DDD0000A000E9524420001124200088FA200247E
+:10DDE0000A000E95244200010A000E932417000831
+:10DDF0002402000E16E20002241700162417001059
+:10DE00008FA2002424420001AFA200248FA200248C
+:10DE10008FA300148F76004000431021AF620040B2
+:10DE20008F8200149442011C104000090000000081
+:10DE30008F6200488F6400409763003C00441023C9
+:10DE40003063FFFF0043102A104000088FA20054E7
+:10DE5000936400368F6300403402FFFC008210049C
+:10DE600000621821AF6300488FA200548FA60030D3
+:10DE70000282902130C200081040000E0000000015
+:10DE80008F6200581642000430C600FF9742011A04
+:10DE90005040000134C6001093C500088FA700341D
+:10DEA0000200202100052B0034A500800E000C9BF1
+:10DEB00030A5F0808F620040005610231840001BF0
+:10DEC0008FA200183C0208008C42319830420010AA
+:10DED0001040000D24020001976200681440000AFF
+:10DEE000240200018F8200149442011C1440000699
+:10DEF00024020001A76200689742007A244200646D
+:10DF00000A000EE9A7620012A76200120E001302B7
+:10DF1000020020219362007D2403000102002021E1
+:10DF2000344200010A000EE7AFA300501840000A77
+:10DF3000000000000E001302020020219362007D09
+:10DF40002403000102002021AFA30050344200044A
+:10DF50000E00130BA362007D9362003E304200402E
+:10DF60001440000C326200011040000A0000000062
+:10DF70008F6300408FC20004240400182463000152
+:10DF80000040F809AF6300408FA200300A000F3054
+:10DF9000304200048F620058105200100000000050
+:10DFA0008F620018022210231C4000082404000184
+:10DFB0008F62001816220009000000008F62001C0A
+:10DFC000028210230440000500000000AF720058D8
+:10DFD000AFA40050AF710018AF74001C12E0000B2A
+:10DFE0008FA200500E00130202002021A377003FF1
+:10DFF0000E00130B0200202102E030212404003720
+:10E000000E0013C9000028218FA200501040000309
+:10E01000000000000E000CA90200202112A0000543
+:10E02000000018218FA2003030420004504000113F
+:10E0300000601021240300010A000F30006010214D
+:10E040000E001302020020219362007D02002021B5
+:10E05000344200040E00130BA362007D0E000CA9D5
+:10E06000020020210A000F3024020001AF400044CA
+:10E07000240200018FBF007C8FBE00788FB7007430
+:10E080008FB600708FB5006C8FB400688FB30064DA
+:10E090008FB200608FB1005C8FB0005803E00008C1
+:10E0A00027BD00808F4201B80440FFFE2402080013
+:10E0B000AF4201B803E00008000000003C02000885
+:10E0C00003421021944200483084FFFF2484001250
+:10E0D0003045FFFF10A0001700A4102B10400016C1
+:10E0E00024020003934201202403001AA343018B5E
+:10E0F000304200FF2446FFFE8F82000000A6182B4E
+:10E100003863000100021382004310241040000510
+:10E110008F84000434820001A746019403E00008C4
+:10E12000AF8200042402FFFE0082102403E00008F6
+:10E13000AF8200042402000303E00008A342018B25
+:10E1400027BDFFE0AFB10014AFB00010AFBF0018A3
+:10E1500030B0FFFF30D1FFFF8F4201B80440FFFE17
+:10E1600000000000AF440180AF4400200E000F42C9
+:10E17000020020218F8300008F840004A750019AA1
+:10E18000A750018EA74301908F8300083082800042
+:10E19000AF4301A8A75101881040000E8F820004F0
+:10E1A00093420116304200FC24420004005A102120
+:10E1B0008C4240003042FFFF144000068F82000472
+:10E1C0003C02FFFF34427FFF00821024AF82000434
+:10E1D0008F8200042403BFFF00431024A74201A63E
+:10E1E0009743010C8F42010400031C003042FFFFE3
+:10E1F00000621825AF4301AC3C021000AF4201B8E9
+:10E200008FBF00188FB100148FB0001003E000081A
+:10E2100027BD00208F470070934201128F830000BA
+:10E2200027BDFFF0304200FF00022882306201006B
+:10E23000000030211040004324A40003306240005D
+:10E24000104000103062200000041080005A10219D
+:10E250008C43400024A4000400041080AFA30000FD
+:10E26000005A10218C424000AFA2000493420116D4
+:10E27000304200FC005A10218C4240000A000FC0BE
+:10E28000AFA200081040002F0000302100041080D1
+:10E29000005A10218C43400024A400040004108084
+:10E2A000AFA30000005A10218C424000AFA000082C
+:10E2B000AFA200048FA80008000030210000202138
+:10E2C000240A00083C0908002529010003A41021A4
+:10E2D000148A000300042A001100000A0000000054
+:10E2E00090420000248400012C83000C00A2102125
+:10E2F00000021080004910218C4200001460FFF3DE
+:10E3000000C230263C0408008C8431048F42007027
+:10E310002C83002010600009004738233C030800CC
+:10E32000246331080004108000431021248300017D
+:10E33000AC4700003C010800AC233104AF86000864
+:10E340002406000100C0102103E0000827BD0010D2
+:10E350003C0208008C42003827BDFFD0AFB5002436
+:10E36000AFB40020AFB10014AFBF0028AFB3001CA2
+:10E37000AFB20018AFB00010000088213C150800B3
+:10E3800026B50038144000022454FFFF0000A021ED
+:10E390009742010E8F8400003042FFFF308340001F
+:10E3A0001060000A245200043C0200200082102465
+:10E3B00050400007308280008F8200042403BFFF9A
+:10E3C000008318240A0010103442100030828000AC
+:10E3D0001040000A3C020020008210241040000778
+:10E3E0008F8200043C03FFFF34637FFF0083182407
+:10E3F00034428000AF820004AF8300000E000F980B
+:10E400000000000014400007000000009743011EB8
+:10E410009742011C3063FFFF0002140000621825C0
+:10E42000AF8300089742010C8F4340003045FFFF47
+:10E430003402FFFF14620003000000000A001028ED
+:10E44000241100208F42400030420100544000015E
+:10E45000241100108F8400003082100050400014FE
+:10E4600036310001308200201440000B3C021000C5
+:10E47000008210245040000E363100013C030E0093
+:10E480003C020DFF008318243442FFFF0043102B91
+:10E4900050400007363100013C0208008C42002C3D
+:10E4A000244200013C010800AC22002C363100055A
+:10E4B0003C0608008CC6003454C000238F85000041
+:10E4C0008F820004304240005440001F8F850000BE
+:10E4D0003C021F01008210243C0310005443001A28
+:10E4E0008F85000030A20200144000178F850000C5
+:10E4F0003250FFFF363100028F4201B80440FFFE68
+:10E5000000000000AF400180020020210E000F42F9
+:10E51000AF4000208F8300042402BFFFA750019A60
+:10E52000006218248F820000A750018EA751018835
+:10E53000A74301A6A74201903C021000AF4201B8D8
+:10E540000A0010F5000010213C02100000A2102467
+:10E550001040003A0000000010C0000F0000000052
+:10E5600030A201001040000C3C0302003C020F00EE
+:10E5700000A2102410430008000000008F82000851
+:10E58000005410240055102190420004244200043D
+:10E590000A00109F000221C00000000000051602C2
+:10E5A0003050000F3A0300022E4203EF38420001C0
+:10E5B0002C6300010062182414600073240200011F
+:10E5C0003C0308008C6300D02E06000C386200016A
+:10E5D0002C4200010046102414400015001021C0F8
+:10E5E0002602FFFC2C4200045440001100002021B0
+:10E5F000386200022C420001004610241040000343
+:10E60000000512420A00109F000020210010182B64
+:10E610000043102450400006001021C000002021BB
+:10E620003245FFFF0E000F633226FFFB001021C0B2
+:10E630003245FFFF0A0010F2362600028F424000EA
+:10E640003C0308008C630024304201001040004667
+:10E6500030620001322200043070000D14400002CC
+:10E660002413000424130002000512C238420001E2
+:10E670002E4303EF304200013863000100431025B0
+:10E68000104000033231FFFB2402FFFB0202802412
+:10E6900010C000183202000130A201001040001525
+:10E6A000320200013C020F0000A210243C030200D1
+:10E6B0001043000F8F8200082403FFFE0203802412
+:10E6C00000541024005510219042000402333025DC
+:10E6D0002442000412000002000221C03226FFFF83
+:10E6E0000E000F633245FFFF1200002700001021CB
+:10E6F000320200011040000D320200042402000129
+:10E7000012020002023330253226FFFF00002021D2
+:10E710000E000F633245FFFF2402FFFE0202802439
+:10E7200012000019000010213202000410400016EF
+:10E7300024020001240200041202000202333025E8
+:10E740003226FFFF3245FFFF0E000F632404010055
+:10E750002402FFFB020280241200000B00001021A3
+:10E760000A0010F5240200011040000700001021EB
+:10E770003245FFFF36260002000020210E000F6305
+:10E7800000000000000010218FBF00288FB500247A
+:10E790008FB400208FB3001C8FB200188FB100140B
+:10E7A0008FB0001003E0000827BD003027BDFFD068
+:10E7B000AFB000103C04600CAFBF002CAFB6002817
+:10E7C000AFB50024AFB40020AFB3001CAFB2001847
+:10E7D000AFB100148C8250002403FF7F3C1A8000EC
+:10E7E000004310243442380CAC8250002402000351
+:10E7F0003C106000AF4200088E0208083C1B8008F5
+:10E800003C010800AC2000203042FFF038420010EC
+:10E810002C4200010E001B8DAF8200183C04FFFF4C
+:10E820003C020400348308063442000CAE0219484E
+:10E83000AE03194C3C0560168E0219808CA30000B3
+:10E840003442020000641824AE0219803C02535383
+:10E850001462000334A47C008CA200040050202128
+:10E860008C82007C8C830078AF820010AF83000C18
+:10E870008F55000032A200031040FFFD32A20001BC
+:10E880001040013D32A200028F420128AF42002019
+:10E890008F4201048F430100AF8200000E000F3C45
+:10E8A000AF8300043C0208008C4200C01040000806
+:10E8B0008F8400003C0208008C4200C42442000106
+:10E8C0003C010800AC2200C40A00126900000000EC
+:10E8D0003C020010008210241440010C8F830004BD
+:10E8E0003C0208008C4200203C0308008C63003886
+:10E8F00000008821244200013C010800AC220020D5
+:10E900003C16080026D60038146000022474FFFF6D
+:10E910000000A0219742010E308340003042FFFFEB
+:10E920001060000A245200043C02002000821024DF
+:10E9300050400007308280008F8200042403BFFF14
+:10E94000008318240A0011703442100030828000C5
+:10E950001040000A3C0200200082102410400007F2
+:10E960008F8200043C03FFFF34637FFF0083182481
+:10E9700034428000AF820004AF8300000E000F9885
+:10E980000000000014400007000000009743011E33
+:10E990009742011C3063FFFF00021400006218253B
+:10E9A000AF8300089742010C8F4340003045FFFFC2
+:10E9B0003402FFFF14620003000000000A00118807
+:10E9C000241100208F4240003042010054400001D9
+:10E9D000241100108F840000308210005040001479
+:10E9E00036310001308200201440000B3C02100040
+:10E9F000008210245040000E363100013C030E000E
+:10EA00003C020DFF008318243442FFFF0043102B0B
+:10EA100050400007363100013C0208008C42002CB7
+:10EA2000244200013C010800AC22002C36310005D4
+:10EA30003C0608008CC6003454C000238F850000BB
+:10EA40008F820004304240005440001F8F85000038
+:10EA50003C021F01008210243C0310005443001AA2
+:10EA60008F85000030A20200144000178F8500003F
+:10EA70003250FFFF363100028F4201B80440FFFEE2
+:10EA800000000000AF400180020020210E000F4274
+:10EA9000AF4000208F8300042402BFFFA750019ADB
+:10EAA000006218248F820000A750018EA7510188B0
+:10EAB000A74301A6A74201903C021000AF4201B853
+:10EAC0000A001267000010213C02100000A210246E
+:10EAD0001040003A0000000010C0000F00000000CD
+:10EAE00030A201001040000C3C0302003C020F0069
+:10EAF00000A2102410430008000000008F820008CC
+:10EB000000541024005610219042000424420004B6
+:10EB10000A0011FF000221C00000000000051602DB
+:10EB20003050000F3A0300022E4203EF384200013A
+:10EB30002C63000100621824146000852402000187
+:10EB40003C0308008C6300D02E06000C38620001E4
+:10EB50002C4200010046102414400015001021C072
+:10EB60002602FFFC2C42000454400011000020212A
+:10EB7000386200022C42000100461024504000037D
+:10EB8000000512420A0011FF000020210010182B7E
+:10EB90000043102450400006001021C00000202136
+:10EBA0003245FFFF0E000F633226FFFB001021C02D
+:10EBB0003245FFFF0A001252362600028F42400003
+:10EBC0003C0308008C6300243042010010400046E2
+:10EBD00030620001322200043070000D1440000247
+:10EBE0002413000424130002000512C2384200015D
+:10EBF0002E4303EF3042000138630001004310252B
+:10EC0000104000033231FFFB2402FFFB020280248C
+:10EC100010C000183202000130A20100104000159F
+:10EC2000320200013C020F0000A210243C0302004B
+:10EC30001043000F8F8200082403FFFE020380248C
+:10EC40000054102400561021904200040233302555
+:10EC50002442000412000002000221C03226FFFFFD
+:10EC60000E000F633245FFFF120000390000102133
+:10EC7000320200011040000D3202000424020001A3
+:10EC800012020002023330253226FFFF000020214D
+:10EC90000E000F633245FFFF2402FFFE02028024B4
+:10ECA0001200002B00001021320200041040002846
+:10ECB0002402000124020004120200020233302563
+:10ECC0003226FFFF3245FFFF0E000F6324040100D0
+:10ECD0002402FFFB020280241200001D000010210C
+:10ECE0000A001267240200015040001900001021A0
+:10ECF0003245FFFF36260002000020210E000F6380
+:10ED0000000000000A001267000010212402BFFF6B
+:10ED1000006210241040000800000000240287FF59
+:10ED200000621024144000083C020060008210249D
+:10ED300010400005000000000E000D34000000002F
+:10ED40000A001267000000000E0012C70000000059
+:10ED5000104000063C0240008F4301243C0260202A
+:10ED6000AC430014000000003C024000AF420138F8
+:10ED70000000000032A200021040FEBD00000000B2
+:10ED80008F4201403C044000AF4200208F430148C5
+:10ED90003C02700000621824106400420000000071
+:10EDA0000083102B144000063C0260003C0220004F
+:10EDB000106200073C0240000A0012C3000000007D
+:10EDC0001062003C3C0240000A0012C30000000038
+:10EDD0008F4501408F4601448F42014800021402D2
+:10EDE000304300FF240200041462000A274401801B
+:10EDF0008F4201B80440FFFE2402001CAC850000D5
+:10EE0000A082000B3C021000AF4201B80A0012C3FE
+:10EE10003C0240002402000914620012000616029F
+:10EE2000000229C0AF4500208F4201B80440FFFE18
+:10EE30002402000124030003AF450180A343018B9A
+:10EE4000A740018EA740019AA7400190AF4001A8BA
+:10EE5000A7420188A74201A6AF4001AC3C021000C6
+:10EE6000AF4201B88F4201B80440FFFE000000002D
+:10EE7000AC8500008F42014800021402A482000801
+:10EE800024020002A082000B8F420148A4820010DD
+:10EE90003C021000AC860024AF4201B80A0012C345
+:10EEA0003C0240000E001310000000000A0012C3D4
+:10EEB0003C0240000E001BC2000000003C0240006B
+:10EEC000AF420178000000000A00112F000000008E
+:10EED0008F4201003042003E144000112402000124
+:10EEE000AF4000488F420100304207C0104000058B
+:10EEF00000000000AF40004CAF40005003E00008AD
+:10EF000024020001AF400054AF4000408F42010096
+:10EF10003042380054400001AF4000442402000158
+:10EF200003E00008000000008F4201B80440FFFE2B
+:10EF300024020001AF440180AF400184A74501884D
+:10EF4000A342018A24020002A342018B9742014A94
+:10EF500014C00004A7420190AF4001A40A0012EFC0
+:10EF60003C0210008F420144AF4201A43C02100059
+:10EF7000AF4001A803E00008AF4201B88F4201B8DA
+:10EF80000440FFFE24020002AF440180AF4401842C
+:10EF9000A7450188A342018AA342018B9742014AF7
+:10EFA000A7420190AF4001A48F420144AF4201A8A3
+:10EFB0003C02100003E00008AF4201B83C029000A0
+:10EFC0003442000100822025AF4400208F420020FF
+:10EFD0000440FFFE0000000003E000080000000005
+:10EFE0003C028000344200010082202503E000083A
+:10EFF000AF44002027BDFFE8AFBF0014AFB0001042
+:10F000008F50014093430149934201489344014882
+:10F01000306300FF304200FF00021200006228252A
+:10F020002402001910620076308400802862001AE1
+:10F030001040001C24020020240200081062007707
+:10F04000286200091040000E2402000B2402000177
+:10F0500010620034286200025040000524020006BD
+:10F0600050600034020020210A00139A00000000C2
+:10F0700010620030020020210A00139A00000000F4
+:10F080001062003B2862000C504000022402000E77
+:10F090002402000910620056020020210A00139A7F
+:10F0A0000000000010620056286200211040000F8E
+:10F0B000240200382402001C106200582862001D3F
+:10F0C000104000062402001F2402001B1062004CA6
+:10F0D000000000000A00139A000000001062004ABD
+:10F0E000020020210A00139A00000000106200456F
+:10F0F0002862003910400007240200802462FFCB00
+:10F100002C42000210400045020020210A00139604
+:10F110000000302110620009000000000A00139A6C
+:10F12000000000001480003D020020210A0013901E
+:10F130008FBF00140A001396240600018F4201B805
+:10F140000440FFFE24020002A342018BA745018870
+:10F150009742014AA74201908F420144A74201927F
+:10F160003C021000AF4201B80A00139C8FBF00148C
+:10F170009742014A144000290000000093620005F4
+:10F180003042000414400025000000000E0013026D
+:10F190000200202193620005020020213442000475
+:10F1A0000E00130BA36200059362000530420004B9
+:10F1B00014400002000000000000000D93620000F7
+:10F1C00024030020304200FF14430014000000001C
+:10F1D0008F4201B80440FFFE24020005AF500180B9
+:10F1E000A342018B3C0210000A00139AAF4201B8FF
+:10F1F0008FBF00148FB000100A0012F227BD001854
+:10F200000000000D02002021000030218FBF0014FB
+:10F210008FB000100A0012DD27BD00180000000D9D
+:10F220008FBF00148FB0001003E0000827BD001846
+:10F2300027BDFFE8AFBF00100E000F3C000000002C
+:10F24000AF4001808FBF0010000020210A000FE7AF
+:10F2500027BD00183084FFFF30A5FFFF00001821F4
+:10F260001080000700000000308200011040000202
+:10F2700000042042006518210A0013AB0005284055
+:10F2800003E000080060102110C0000624C6FFFF44
+:10F290008CA2000024A50004AC8200000A0013B573
+:10F2A0002484000403E000080000000010A000080F
+:10F2B00024A3FFFFAC860000000000000000000057
+:10F2C0002402FFFF2463FFFF1462FFFA248400047A
+:10F2D00003E0000800000000308300FF30A500FFBD
+:10F2E00030C600FF274701808F4201B80440FFFE6F
+:10F2F000000000008F42012834634000ACE20000AF
+:10F3000024020001ACE00004A4E30008A0E2000A2B
+:10F3100024020002A0E2000B3C021000A4E5001051
+:10F32000ACE00024ACE00028A4E6001203E00008F2
+:10F33000AF4201B827BDFFE8AFBF00109362003FA6
+:10F3400024030012304200FF1043000D00803021E2
+:10F350008F620044008210230440000A8FBF001017
+:10F360008F620048240400390000282100C21023C5
+:10F3700004410004240600120E0013C9000000001E
+:10F380008FBF00102402000103E0000827BD001811
+:10F3900027BDFFC8AFB20030AFB1002CAFBF003403
+:10F3A000AFB0002890C5000D0080902130A400105F
+:10F3B0001080000B00C088218CC300088F620054AD
+:10F3C0001062000730A20005144000B524040001BB
+:10F3D0000E000D21000020210A0014BB0040202156
+:10F3E00030A200051040000930A30012108000ACCC
+:10F3F000240400018E2300088F620054146200A9C7
+:10F400008FBF00340A00142C240400382402001298
+:10F41000146200A3240400010220202127A500106B
+:10F420000E000CB2AFA000101040001102402021CD
+:10F430008E220008AF620084AF6000400E0013020D
+:10F44000000000009362007D024020213442002031
+:10F450000E00130BA362007D0E000CA902402021B8
+:10F46000240400382405008D0A0014B82406001274
+:10F470009362003E304200081040000F8FA200103F
+:10F4800030420100104000078FA300148F6200601B
+:10F490000062102304430008AF6300600A001441B7
+:10F4A00000000000AF6000609362003E2403FFF79D
+:10F4B00000431024A362003E9362003E30420008E5
+:10F4C000144000022406000300003021936200343F
+:10F4D000936300378F640084304200FF306300FF85
+:10F4E00000661821000318800043282100A4202B67
+:10F4F0001080000B000000009763003C8F620084C6
+:10F500003063FFFF004510230062182B14600004D5
+:10F51000000000008F6200840A00145D0045802313
+:10F520009762003C3050FFFF8FA300103062000450
+:10F5300010400004000628808FA2001C0A001465F9
+:10F540000202102B2E02021850400003240202185F
+:10F550000A00146E020510233063000410600003DB
+:10F56000004510238FA2001C00451023004080217D
+:10F570002C42008054400001241000800E00130231
+:10F580000240202124020001AF62000C9362003E81
+:10F59000001020403042007FA362003E8E22000413
+:10F5A00024420001AF620040A770003C8F6200500F
+:10F5B0009623000E00431021AF6200588F62005066
+:10F5C00000441021AF62005C8E220004AF6200187C
+:10F5D0008E220008AF62001C8FA20010304200088B
+:10F5E0005440000A93A20020A360003693620036C4
+:10F5F0002403FFDFA36200359362003E0043102422
+:10F60000A362003E0A0014988E220008A36200350F
+:10F610008E220008AF62004C8F6200248F6300408E
+:10F6200000431021AF6200489362000024030050A1
+:10F63000304200FF144300122403FF803C02080004
+:10F640008C4231A00242102100431024AF42002816
+:10F650003C0208008C4231A08E2400083C03000CC0
+:10F66000024210213042007F03421021004310214A
+:10F67000AC4400D88E230008AF820014AC4300DCF9
+:10F680000E00130B02402021240400380000282122
+:10F690002406000A0E0013C9000000002404000123
+:10F6A0008FBF00348FB200308FB1002C8FB0002894
+:10F6B0000080102103E0000827BD003827BDFFF8B7
+:10F6C00027420180AFA20000308A00FF8F4201B8BC
+:10F6D0000440FFFE000000008F4601283C020800A5
+:10F6E0008C4231A02403FF80AF86004800C2102165
+:10F6F00000431024AF4200243C0208008C4231A099
+:10F700008FA900008FA8000000C210213042007FA6
+:10F71000034218213C02000A00621821946400D4BC
+:10F720008FA700008FA5000024020002AF83001401
+:10F73000A0A2000B8FA30000354260003084FFFFC1
+:10F74000A4E200083C021000AD260000AD04000455
+:10F75000AC60002427BD0008AF4201B803E00008F8
+:10F76000240200018F88003C938200288F830014BC
+:10F770003C07080024E7779800481023304200FF38
+:10F78000304900FC246500888F860040304A000321
+:10F790001120000900002021248200048CA3000015
+:10F7A000304400FF0089102AACE3000024A50004C7
+:10F7B0001440FFF924E70004114000090000202153
+:10F7C0002482000190A30000304400FF008A102B27
+:10F7D000A0E3000024A500011440FFF924E7000184
+:10F7E00030C20003144000048F85003C3102000346
+:10F7F0001040000D0000000010A0000900002021B2
+:10F800002482000190C30000304400FF0085102BCB
+:10F81000A0E3000024C600011440FFF924E7000122
+:10F8200003E00008000000001100FFFD000020219F
+:10F83000248200048CC30000304400FF0088102B99
+:10F84000ACE3000024C600041440FFF924E70004E0
+:10F8500003E00008000000008F83003C9382002832
+:10F8600030C600FF30A500FF00431023304300FFE7
+:10F870008F820014008038210043102114C0000240
+:10F88000244800880083382130E20003144000053A
+:10F8900030A2000314400003306200031040000D4A
+:10F8A0000000000010A000090000202124820001B7
+:10F8B00090E30000304400FF0085102BA1030000FE
+:10F8C00024E700011440FFF92508000103E00008C7
+:10F8D0000000000010A0FFFD000020212482000491
+:10F8E0008CE30000304400FF0085102BAD030000C6
+:10F8F00024E700041440FFF92508000403E0000891
+:10F90000000000000080482130AAFFFF30C600FF41
+:10F9100030E7FFFF274801808F4201B80440FFFE17
+:10F920008F820048AD0200008F420124AD02000426
+:10F930008D220020A5070008A102000A240200165B
+:10F94000A102000B934301208D2200088D240004A6
+:10F95000306300FF004310219783003A00441021D8
+:10F960008D250024004310233C0308008C6331A044
+:10F970008F840014A502000C246300E82402FFFF1A
+:10F98000A50A000EA5030010A5060012AD0500187B
+:10F99000AD020024948201142403FFF73042FFFFDC
+:10F9A000AD0200288C820118AD02002C3C02100030
+:10F9B000AD000030AF4201B88D220020004310247A
+:10F9C00003E00008AD2200208F82001430E7FFFF23
+:10F9D00000804821904200D330A5FFFF30C600FFD1
+:10F9E0000002110030420F0000E238252748018054
+:10F9F0008F4201B80440FFFE8F820048AD02000034
+:10FA00008F420124AD0200048D220020A5070008CA
+:10FA1000A102000A24020017A102000B9343012057
+:10FA20008D2200088D240004306300FF0043102164
+:10FA30009783003A004410218F8400140043102360
+:10FA40003C0308008C6331A0A502000CA505000E44
+:10FA5000246300E8A5030010A5060012AD00001401
+:10FA60008D220024AD0200188C82005CAD02001CC7
+:10FA70008C820058AD0200202402FFFFAD0200245A
+:10FA8000948200E63042FFFFAD02002894820060BD
+:10FA9000948300BE30427FFF3063FFFF00021200FC
+:10FAA00000431021AD02002C3C021000AD000030DC
+:10FAB000AF4201B8948200BE2403FFF700A21021D8
+:10FAC000A48200BE8D2200200043102403E0000821
+:10FAD000AD220020274301808F4201B80440FFFE81
+:10FAE0008F8200249442001C3042FFFF000211C0AC
+:10FAF000AC62000024020019A062000B3C0210005E
+:10FB0000AC60003003E00008AF4201B88F87002CE2
+:10FB100030C300FF8F4201B80440FFFE8F820048CF
+:10FB200034636000ACA2000093820044A0A20005F0
+:10FB30008CE20010A4A20006A4A300088C8200207E
+:10FB40002403FFF7A0A2000A24020002A0A2000BD7
+:10FB50008CE20000ACA200108CE20004ACA2001405
+:10FB60008CE2001CACA200248CE20020ACA2002895
+:10FB70008CE2002CACA2002C8C820024ACA20018D9
+:10FB80003C021000AF4201B88C82002000431024D8
+:10FB900003E00008AC8200208F86001427BDFFE838
+:10FBA000AFBF0014AFB0001090C20063304200201D
+:10FBB0001040000830A500FF8CC2007C2403FFDF4A
+:10FBC00024420001ACC2007C90C2006300431024B8
+:10FBD000A0C2006310A000238F830014275001806F
+:10FBE000020028210E0015D6240600828F82001400
+:10FBF000904200633042004050400019A38000440E
+:10FC00008F83002C8F4201B80440FFFE8F82004892
+:10FC1000AE02000024026082A60200082402000254
+:10FC2000A202000B8C620008AE0200108C62000C75
+:10FC3000AE0200148C620014AE0200188C62001830
+:10FC4000AE0200248C620024AE0200288C620028E0
+:10FC5000AE02002C3C021000AF4201B8A380004469
+:10FC60008F8300148FBF00148FB000109062006368
+:10FC700027BD00183042007FA06200639782003ADF
+:10FC80008F86003C8F850014938300280046102344
+:10FC9000A782003AA4A000E490A400638F820040F1
+:10FCA000AF83003C2403FFBF0046102100832024C3
+:10FCB000AF820040A0A400638F820014A04000BD6A
+:10FCC0008F82001403E00008A44000BE8F8A001455
+:10FCD00027BDFFE0AFB10014AFB000108F88003C2B
+:10FCE000AFBF00189389001C954200E430D100FF9B
+:10FCF0000109182B0080802130AC00FF3047FFFF46
+:10FD00000000582114600003310600FF012030215B
+:10FD1000010958239783003A0068102B1440003CD7
+:10FD20000000000014680007240200018E02002079
+:10FD30002403FFFB34E7800000431024AE020020C0
+:10FD40002402000134E70880158200053165FFFFB9
+:10FD50000E001554020020210A00169102002021F5
+:10FD60000E001585020020218F8400482743018062
+:10FD70008F4201B80440FFFE24020018AC6400006A
+:10FD8000A062000B8F840014948200E6A46200102D
+:10FD90003C021000AC600030AF4201B894820060B9
+:10FDA00024420001A4820060948200603C030800A9
+:10FDB0008C63318830427FFF5443000F02002021C2
+:10FDC000948200602403800000431024A482006019
+:10FDD0009082006090830060304200FF000211C2F8
+:10FDE00000021027000211C03063007F0062182556
+:10FDF000A083006002002021022028218FBF00186C
+:10FE00008FB100148FB000100A0015F927BD002033
+:10FE1000914200632403FF8000431025A142006348
+:10FE20009782003A3048FFFF110000209383001CA6
+:10FE30008F840014004B1023304600FF948300E4AD
+:10FE40002402EFFF0168282B00621824A48300E439
+:10FE500014A000038E020020010058210000302170
+:10FE60002403FFFB34E7800000431024AE0200208F
+:10FE700024020001158200053165FFFF0E001554B4
+:10FE8000020020210A0016B99783003A0E0015855A
+:10FE9000020020219783003A8F82003CA780003A1D
+:10FEA00000431023AF82003C9383001C8F82001418
+:10FEB0008FBF00188FB100148FB0001027BD002035
+:10FEC00003E00008A04300BD938200442403000126
+:10FED00027BDFFE8004330042C420020AFB00010E3
+:10FEE000AFBF00142410FFFE10400005274501801D
+:10FEF0003C0208008C4231900A0016D600461024BD
+:10FF00003C0208008C423194004610241440000743
+:10FF1000240600848F8300142410FFFF9062006287
+:10FF20003042000F34420040A06200620E0015D63D
+:10FF300000000000020010218FBF00148FB00010DD
+:10FF400003E0000827BD00188F83002427BDFFE0D1
+:10FF5000AFB20018AFB10014AFB00010AFBF001CBB
+:10FF60009062000D00A0902130D100FF3042007F50
+:10FF7000A062000D8F8500148E4300180080802140
+:10FF80008CA2007C146200052402000E90A2006383
+:10FF9000344200200A0016FFA0A200630E0016C51E
+:10FFA000A38200442403FFFF104300472404FFFF03
+:10FFB00052200045000020218E4300003C0200102A
+:10FFC00000621024504000043C020008020020217E
+:10FFD0000A00170E24020015006210245040000988
+:10FFE0008E45000002002021240200140E0016C5D8
+:10FFF000A38200442403FFFF104300332404FFFFC7
+:020000021000EC
+:100000008E4500003C02000200A2102410400016A1
+:100010003C0200048F8600248CC200148CC30010A4
+:100020008CC40014004310230044102B50400005E2
+:10003000020020218E43002C8CC2001010620003AD
+:10004000020020210A00173F240200123C02000493
+:1000500000A210245040001C00002021020020219A
+:100060000A00173F2402001300A2102410400006CB
+:100070008F8300248C620010504000130000202168
+:100080000A001739020020218C6200105040000441
+:100090008E42002C020020210A00173F240200118A
+:1000A00050400009000020210200202124020017F6
+:1000B0000E0016C5A38200442403FFFF1043000274
+:1000C0002404FFFF000020218FBF001C8FB2001806
+:1000D0008FB100148FB000100080102103E00008E1
+:1000E00027BD00208F83001427BDFFD8AFB40020A8
+:1000F000AFB3001CAFB20018AFB10014AFB0001026
+:10010000AFBF0024906200638F91002C2412FFFF88
+:100110003442004092250000A06200638E2200104D
+:100120000080982130B0003F105200060360A021EB
+:100130002402000D0E0016C5A38200441052005484
+:100140002404FFFF8F8300148E2200188C63007C30
+:1001500010430007026020212402000E0E0016C585
+:10016000A38200442403FFFF104300492404FFFF3F
+:1001700024040020120400048F83001490620063A2
+:1001800034420020A06200638F85003410A000205C
+:1001900000000000560400048F8200140260202139
+:1001A0000A0017902402000A9683000A9442006015
+:1001B0003042FFFF144300048F8200202404FFFD1F
+:1001C0000A0017B7AF82003C3C0208008C42318C19
+:1001D0000045102B14400006026020210000282159
+:1001E0000E001646240600010A0017B70000202161
+:1001F0002402002D0E0016C5A38200442403FFFF35
+:10020000104300232404FFFF0A0017B70000202139
+:10021000160400058F8400148E2300142402FFFFAF
+:100220005062001802602021948200602442000184
+:10023000A4820060948200603C0308008C633188D3
+:1002400030427FFF5443000F0260202194820060FF
+:100250002403800000431024A48200609082006088
+:1002600090830060304200FF000211C2000210279C
+:10027000000211C03063007F00621825A083006077
+:10028000026020210E0015F9240500010000202144
+:100290008FBF00248FB400208FB3001C8FB20018D2
+:1002A0008FB100148FB000100080102103E000080F
+:1002B00027BD00288F83001427BDFFE8AFB00010D2
+:1002C000AFBF0014906200638F87002C00808021F4
+:1002D000344200408CE60010A06200633C0308003A
+:1002E0008C6331B030C23FFF0043102B1040004EF2
+:1002F0008F8500302402FF8090A3000D004310245E
+:10030000304200FF504000490200202100061382C5
+:10031000304800032402000255020044020020215C
+:1003200094A2001C8F85001424030023A4A20114AE
+:100330008CE60000000616023042003F1043001019
+:100340003C0300838CE300188CA2007C1062000642
+:100350002402000E0E0016C5A38200442403FFFFF2
+:10036000104300382404FFFF8F8300149062006361
+:1003700034420020A06200630A0017FC8F8300242F
+:1003800000C31024144300078F83002490A200624E
+:100390003042000F34420020A0A20062A38800383F
+:1003A0008F8300249062000D3042007FA062000D18
+:1003B0008F83003410600018020020218F840030E9
+:1003C0008C8200100043102B1040000924020018FA
+:1003D000020020210E0016C5A38200442403FFFF63
+:1003E000104300182404FFFF0A00182400002021F5
+:1003F0008C820010240500010200202100431023FC
+:100400008F830024240600010E001646AC62001003
+:100410000A001824000020210E0015F9240500010F
+:100420000A00182400002021020020212402000DCF
+:100430008FBF00148FB0001027BD00180A0016C52A
+:10044000A38200448FBF00148FB0001000801021E1
+:1004500003E0000827BD001827BDFFC8AFB2002089
+:10046000AFBF0034AFB60030AFB5002CAFB400283A
+:10047000AFB30024AFB1001CAFB000188F46012805
+:100480003C0308008C6331A02402FF80AF86004843
+:1004900000C318213065007F03452821006218241D
+:1004A0003C02000AAF43002400A2282190A200626F
+:1004B00000809021AF850014304200FF000211023D
+:1004C000A382003890A200BC304200021440000217
+:1004D00024030034240300308F820014A3830028F7
+:1004E000938300388C4200C0A3800044AF82003C5C
+:1004F000240200041062031C8F84003C8E4400041C
+:10050000508003198F84003C8E4200103083FFFF1F
+:10051000A784003A106002FFAF8200408F8400146D
+:100520002403FF809082006300621024304200FFA9
+:10053000144002CF9785003A9383003824020002CA
+:1005400030B6FFFF14620005000088219382002866
+:100550002403FFFD0A001B19AF82003C8F82003C80
+:1005600002C2102B144002A18F8400400E0014EC34
+:1005700000000000938300283C040800248477983E
+:10058000240200341462002EAF84002C3C0A0800C0
+:100590008D4A77C82402FFFFAFA2001000803821E7
+:1005A0002405002F3C09080025297398240800FF22
+:1005B0002406FFFF90E2000024A3FFFF00062202B2
+:1005C00000C21026304200FF0002108000491021B6
+:1005D0008C420000306500FF24E7000114A8FFF5FD
+:1005E0000082302600061027AFA20014AFA2001030
+:1005F0000000282127A7001027A6001400C51023FB
+:100600009044000324A2000100A71821304500FFF8
+:100610002CA200041440FFF9A06400008FA2001077
+:100620001142000724020005024020210E0016C5D9
+:10063000A38200442403FFFF104300642404FFFF4F
+:100640003C0208009042779C104000098F82001401
+:10065000024020212402000C0E0016C5A382004493
+:100660002403FFFF104300592404FFFF8F8200146E
+:10067000A380001C3C0308008C63779C8C440080A2
+:100680003C0200FF3442FFFF006218240083202B4D
+:1006900010800008AF83003402402021240200199A
+:1006A0000E0016C5A38200442403FFFF1043004739
+:1006B0002404FFFF8F87003C9782003A8F85003427
+:1006C000AF8700200047202310A0003BA784003AFA
+:1006D0008F86001430A200030002102390C300BCD8
+:1006E0003050000300B0282100031882307300014D
+:1006F0000013108000A228213C0308008C6331A065
+:100700008F8200483084FFFF0085202B004310219A
+:1007100010800011244200888F84002C1082000E6B
+:100720003C033F013C0208008C42779800431024B0
+:100730003C0325001443000630E500FF8C820000D6
+:10074000ACC200888C8200100A0018E9ACC2009884
+:100750000E001529000030219382001C8F850014A3
+:100760008F830040020238218F82003CA387001C47
+:1007700094A400E4006218218F82003434841000B5
+:10078000AF83004000503021A4A400E41260000EAA
+:10079000AF86003C24E20004A382001C94A200E483
+:1007A00024C30004AF83003C34422000A4A200E430
+:1007B0000A001906000020218F820040AF80003C13
+:1007C00000471021AF820040000020212414FFFFC9
+:1007D000109402112403FFFF3C0808008D0877A83D
+:1007E0003C0208008C4231B03C03080090637798CB
+:1007F00031043FFF0082102B1040001B3067003F88
+:100800003C0208008C4231A88F83004800042180FC
+:1008100000621821006418213062007F0342282101
+:100820003C02000C00A228213C020080344200015E
+:100830003066007800C230252402FF800062102458
+:10084000AF42002830640007AF4208048F820014D2
+:100850000344202124840940AF460814AF850024B6
+:10086000AF840030AC4301189383003824020003A6
+:10087000146201CF240200012402002610E201D1FB
+:1008800028E2002710400013240200322402002234
+:1008900010E201CC28E200231040000824020024CA
+:1008A0002402002010E201B82402002110E20147D6
+:1008B000024020210A001AFB2402000B10E201C1B1
+:1008C0002402002510E20010024020210A001AFB39
+:1008D0002402000B10E201AE28E2003310400006B3
+:1008E0002402003F2402003110E2009A024020213D
+:1008F0000A001AFB2402000B10E201A5024020218D
+:100900000A001AFB2402000B8F90002C3C03080005
+:100910008C6331B08F8500308E0400100000A82158
+:100920008CB3001430823FFF0043102B8CB10020A9
+:100930005040018F0240202190A3000D2402FF802F
+:1009400000431024304200FF504001890240202122
+:10095000000413823042000314400185024020212C
+:1009600094A3001C8F8200148E040028A443011459
+:100970008CA20010026218231064000302402021A0
+:100980000A00197C2402001F8F82003400621021AB
+:100990000262102B104000088F83002402402021A7
+:1009A000240200180E0016C5A382004410540174DE
+:1009B0002404FFFF8F8300248F8400348C62001096
+:1009C0000224882100441023AC6200108F8200149E
+:1009D000AC7100208C4200680051102B10400009BF
+:1009E0008F830030024020212402001D0E0016C516
+:1009F000A38200442403FFFF104301612404FFFF8E
+:100A00008F8300308E0200248C6300241043000783
+:100A1000024020212402001C0E0016C5A3820044BF
+:100A20002403FFFF104301562404FFFF8F8400249A
+:100A30008C82002424420001AC8200241233000482
+:100A40008F8200148C4200685622000E8E02000035
+:100A50008E0200003C030080004310241440000D6F
+:100A60002402001A024020210E0016C5A382004471
+:100A70002403FFFF104301422404FFFF0A0019BAB8
+:100A80008E0200143C0300800043102450400003F9
+:100A90008E020014AC8000208E0200142411FFFF8F
+:100AA0001051000E3C0308003C0208008C423190BB
+:100AB000004310242403001B14400007A3830044B8
+:100AC0000E0016C5024020211051012D2404FFFF05
+:100AD0000A0019CB8E030000A38000448E0300009F
+:100AE0003C02000100621024104000123C02008011
+:100AF0000062102414400008024020212402001A41
+:100B00000E0016C5A38200442403FFFF1043011CFE
+:100B10002404FFFF02402021020028210E0016E5D8
+:100B2000240600012403FFFF104301152404FFFFE6
+:100B3000241500018F83002402A0302102402021CF
+:100B40009462003624050001244200010A001ADFE5
+:100B5000A46200368F90002C3C0308008C6331B0F7
+:100B60008E13001032623FFF0043102B10400089AB
+:100B70008F8400302402FF809083000D00431024F6
+:100B8000304200FF104000842402000D0013138245
+:100B900030420003240300011443007F2402000DAF
+:100BA0009082000D30420008544000048F820034CF
+:100BB000024020210A001A102402002450400004A0
+:100BC0008E03000C024020210A001A102402002784
+:100BD0008C82002054620006024020218E0300080F
+:100BE0008C820024506200098E02001402402021F1
+:100BF000240200200E0016C5A38200441054007188
+:100C00002403FFFF0A001A458F8400242411FFFFEC
+:100C1000145100048F860014024020210A001A405B
+:100C2000240200258E0300188CC2007C1062000391
+:100C30002402000E0A001A40024020218E030024E4
+:100C40008C82002810620003240200210A001A404E
+:100C5000024020218E0500288C82002C10A2000367
+:100C60002402001F0A001A40024020218E03002C9B
+:100C700014600003240200230A001A4002402021CD
+:100C80008CC200680043102B104000032402002691
+:100C90000A001A40024020218C82001400651821AD
+:100CA0000043102B104000088F84002402402021B4
+:100CB000240200220E0016C5A382004410510041F8
+:100CC0002403FFFF8F8400242403FFF79082000D8C
+:100CD00000431024A082000D8F8600143C030800FE
+:100CE0008C6331AC8F82004894C400E08F8500246F
+:100CF0000043102130847FFF000420400044102175
+:100D00003043007F034320213C03000E0083202159
+:100D10002403FF8000431024AF42002CA493000062
+:100D20008CA2002824420001ACA200288CA2002C36
+:100D30008E03002C00431021ACA2002C8E02002C4C
+:100D4000ACA200308E020014ACA2003494A2003A8F
+:100D500024420001A4A2003A94C600E03C0208002C
+:100D60008C4231B024C4000130837FFF1462000F35
+:100D700000803021240280000082302430C2FFFF36
+:100D8000000213C2304200FF000210270A001A7E40
+:100D9000000233C02402000D024020210E0016C5BF
+:100DA000A38200440A001A84004018218F82001494
+:100DB00002402021240500010E0015F9A44600E0A0
+:100DC000000018210A001B16006088218F90002C5B
+:100DD0003C0308008C6331B08E05001030A23FFF49
+:100DE0000043102B104000612402FF808F840030EC
+:100DF0009083000D00431024304200FF5040005CFF
+:100E0000024020218F8200341040000B0005138225
+:100E10008F8200149763000A944200603042FFFF03
+:100E200014430005000513828F8200202404FFFD77
+:100E30000A001AF3AF82003C304200031440000E57
+:100E40000000000092020002104000058E03002402
+:100E500050600015920300030A001AAF02402021DF
+:100E60008C82002450620010920300030240202173
+:100E70000A001AB72402000F9082000D30420008C9
+:100E80005440000992030003024020212402001074
+:100E90000E0016C5A38200442403FFFF1043003850
+:100EA0002404FFFF92030003240200025462000C9A
+:100EB000920200038F820034544000099202000322
+:100EC000024020212402002C0E0016C5A3820044FB
+:100ED0002403FFFF1043002A2404FFFF92020003B3
+:100EE0000200282102402021384600102CC60001B3
+:100EF0002C4200010E0016E5004630252410FFFFAD
+:100F00001050001F2404FFFF8F8300341060001373
+:100F1000024020213C0208008C42318C0043102BFF
+:100F200014400007000000000000282124060001F2
+:100F30000E001646000000000A001AF300002021EF
+:100F40002402002D0E0016C5A38200441050000C90
+:100F50002404FFFF0A001AF3000020210E0015F9F7
+:100F6000240500010A001AF300002021024020217C
+:100F70002402000D0E0016C5A3820044004020216B
+:100F80000A001B16008088211514000E00000000C6
+:100F90000E00174C024020210A001B160040882139
+:100FA0000E0016C5A38200440A001B1600408821CB
+:100FB00014620017022018212402002314E2000505
+:100FC0002402000B0E0017C0024020210A001B164D
+:100FD0000040882102402021A38200440E0016C553
+:100FE0002411FFFF0A001B170220182130A500FF63
+:100FF0000E001529240600019783003A8F82003CD9
+:10100000A780003A00431023AF82003C0220182141
+:101010001220003E9782003A2402FFFD5462003EF7
+:101020008E4300208E4200048F830014005610234C
+:10103000AE420004906200633042007FA062006311
+:101040008E4200208F840014A780003A34420002B0
+:10105000AE420020A48000E4908200632403FFBF1E
+:1010600000431024A08200630A001B598E43002015
+:101070009082006300621024304200FF1040002381
+:101080009782003A90820088908300BD2485008872
+:101090003042003F2444FFE02C820020A383001C48
+:1010A00010400019AF85002C2402000100821804B2
+:1010B000306200191440000C3C02800034420002EF
+:1010C000006210241440000B306200201040000F1A
+:1010D0009782003A90A600010240202124050001D9
+:1010E0000A001B5330C60001024020210A001B5297
+:1010F00024050001024020210000282124060001CF
+:101100000E001646000000009782003A1440FD04CD
+:101110008F8400148E4300203062000410400012BF
+:101120008F84003C2402FFFB00621024AE420020AA
+:10113000274301808F4201B80440FFFE8F820048A0
+:10114000AC6200008F420124AC6200042402608380
+:10115000A462000824020002A062000B3C021000FE
+:10116000AF4201B88F84003C8F8300148FBF0034DE
+:101170008FB600308FB5002C8FB400288FB30024B9
+:101180008FB200208FB1001C8FB000182402000124
+:1011900027BD003803E00008AC6400C030A500FFA4
+:1011A0002403000124A900010069102B1040000C49
+:1011B00000004021240A000100A31023004A380443
+:1011C00024630001308200010069302B10400002CE
+:1011D000000420420107402554C0FFF800A310235B
+:1011E00003E00008010010213C020800244260A432
+:1011F0003C010800AC22738C3C02080024425308D6
+:101200003C010800AC2273902402000627BDFFE0D9
+:101210003C010800A02273943C021EDCAFB200180F
+:10122000AFB10014AFBF001CAFB0001034526F411B
+:1012300000008821240500080E001B7A02202021CE
+:10124000001180803C07080024E773980002160014
+:1012500002071821AC6200000000282124A200012E
+:101260003045FFFF8C6200002CA6000804410002FC
+:10127000000220400092202614C0FFF8AC64000059
+:10128000020780218E0400000E001B7A2405002036
+:10129000262300013071FFFF2E2301001460FFE5BB
+:1012A000AE0200008FBF001C8FB200188FB1001477
+:1012B0008FB0001003E0000827BD002027BDFFD835
+:1012C000AFB3001CAFB20018AFBF0020AFB1001425
+:1012D000AFB000108F5101408F48014800089402C0
+:1012E000324300FF311300FF8F4201B80440FFFE7C
+:1012F00027500180AE1100008F420144AE0200046D
+:1013000024020002A6120008A202000B240200140C
+:10131000AE1300241062002528620015104000085A
+:101320002402001524020010106200302402001272
+:10133000106200098FBF00200A001CB58FB3001C8B
+:101340001062007024020022106200378FBF00205C
+:101350000A001CB58FB3001C3C0208008C4231A06F
+:101360002403FF800222102100431024AF420024F6
+:101370003C0208008C4231A0022210213042007F42
+:10138000034218213C02000A00621821166000BCCA
+:10139000AF830014906200623042000F344200308C
+:1013A000A06200620A001CB48FBF00203C046000F1
+:1013B0008C832C083C02F0033442FFFF00621824A7
+:1013C000AC832C083C0208008C4231A08C832C0892
+:1013D000244200740002108200021480006218256A
+:1013E000AC832C080A001CB48FBF00203C0208000C
+:1013F0008C4231A02403FF800222102100431024DC
+:10140000AF4200243C0208008C4231A03C03000A99
+:10141000022210213042007F03421021004310219C
+:101420000A001CB3AF8200143C0208008C4231A0B9
+:101430002405FF800222102100451024AF42002421
+:101440003C0208008C4231A0022210213042007F71
+:10145000034218213C02000A0062182190620063D6
+:1014600000A21024304200FF10400085AF8300141A
+:1014700024620088944300123C0208008C4231A888
+:1014800030633FFF00031980022210210043102126
+:101490003043007F03432021004510243C03000C0F
+:1014A00000832021AF4200289082000D00A210246A
+:1014B000304200FF10400072AF8400249082000D83
+:1014C000304200101440006F8FBF00200E0015C87E
+:1014D000000000008F4201B80440FFFE0000000041
+:1014E000AE1100008F420144AE020004240200024B
+:1014F000A6120008A202000BAE1300240A001CB4BE
+:101500008FBF00202406FF8002261024AF42002057
+:101510003C0208008C4231A031043FFF00042180CE
+:101520000222102100461024AF4200243C03080090
+:101530008C6331A83C0208008C4231A03227007F26
+:101540000223182102221021006418213042007F5A
+:101550003064007F034228213C02000A0066182400
+:1015600000A22821034420213C02000C00822021FB
+:10157000AF4300283C020008034718210062902175
+:10158000AF850014AF8400240E0015C8010080212F
+:101590008F4201B80440FFFE8F8200248F84001424
+:1015A000274501809042000DACB10000A4B00006B8
+:1015B000000216000002160300021027000237C2C4
+:1015C00014C00016248200889442001232033FFFA8
+:1015D00030423FFF14430012240260829083006374
+:1015E0002402FF8000431024304200FF5040000CD2
+:1015F00024026082908200623042000F3442004038
+:10160000A082006224026084A4A200082402000DCB
+:10161000A0A200050A001C9E3C0227002402608252
+:10162000A4A20008A0A000053C02270000061C00A0
+:101630000062182524020002A0A2000BACA3001037
+:10164000ACA00014ACA00024ACA00028ACA0002CDE
+:101650008E42004C8F840024ACA200189083000DB1
+:101660002402FF8000431024304200FF1040000598
+:101670008FBF00209082000D3042007FA082000DBD
+:101680008FBF00208FB3001C8FB200188FB10014E1
+:101690008FB000103C02100027BD002803E00008B6
+:1016A000AF4201B80800343008003430080033A8D5
+:1016B000080033E0080034140800343808003438D7
+:1016C00008003438080033180A0001240000000024
+:1016D000000000000000000D747061362E322E33C1
+:1016E00000000000060203010000000000000000EE
+:1016F00000000000000000000000000000000000EA
+:1017000000000000000000000000000000000000D9
+:1017100000000000000000000000000000000000C9
+:1017200000000000000000000000000000000000B9
+:1017300000000000000000000000000000000000A9
+:101740000000000000000000000000000000000099
+:101750000000000000000000000000001000000376
+:10176000000000000000000D0000000D3C02080019
+:1017700024421C003C03080024632094AC40000079
+:101780000043202B1480FFFD244200043C1D080070
+:1017900037BD2FFC03A0F0213C1008002610049058
+:1017A0003C1C0800279C1C000E00015C000000008F
+:1017B0000000000D3084FFFF308200078F85001885
+:1017C00010400002248300073064FFF800853021B8
+:1017D00030C41FFF03441821247B4000AF85001C48
+:1017E000AF84001803E00008AF4400843084FFFF9A
+:1017F000308200078F8500208F860028104000026D
+:10180000248300073064FFF8008520210086182B10
+:1018100014600002AF8500240086202303442821A1
+:1018200034068000AF840020AF44008000A6202151
+:1018300003E00008AF84003827BDFFD8AFB3001C19
+:10184000AFB20018AFB00010AFBF0024AFB400209B
+:10185000AFB100143C0860088D1450002418FF7FBD
+:101860003C1A8000029898243672380CAD12500051
+:101870008F5100083C07601C3C08600036300001B6
+:10188000AF500008AF800018AF400080AF40008428
+:101890008CE600088D0F08083C0760168CEC0000F1
+:1018A00031EEFFF039CA00103C0DFFFF340B800011
+:1018B0003C030080034B48212D440001018D282466
+:1018C0003C0253533C010800AC230420AF8900388C
+:1018D000AF860028AF840010275B400014A20003ED
+:1018E00034E37C008CF90004032818218C7F007CF1
+:1018F0008C6500783C0280003C0B08008D6B048CEA
+:101900003C0A08008D4A048834520070AF85003CC0
+:10191000AF9F00403C13080026731C440240A021E6
+:101920008E4800008F46000038C30001306400017B
+:1019300010800017AF880034028048218D2F0000EE
+:101940003C0508008CA5045C3C1808008F1804585E
+:1019500001E8102300A280210000C8210202402BD0
+:1019600003198821022838213C010800AC30045CAE
+:101970003C010800AC2704588F4E000039CD00010F
+:1019800031AC00011580FFED01E04021AF8F003444
+:101990008E5100003C0708008CE7045C3C0D0800F9
+:1019A0008DAD04580228802300F0602100007021D2
+:1019B0000190302B01AE1821006620213C01080067
+:1019C000AC2C045C3C010800AC2404588F46010890
+:1019D0008F47010030C92000AF860000AF87000CA0
+:1019E0001120000A00C040213C1808008F18042C68
+:1019F000270800013C010800AC28042C3C184000DA
+:101A0000AF5801380A000196000000009749010410
+:101A100000002821014550213122FFFF0162582199
+:101A20000162F82B015F502130D902003C0108000F
+:101A3000AC2B048C3C010800AC2A0488172000154C
+:101A400024040F0010E400130000000024080D001F
+:101A500010E8023B30CD000611A0FFE93C18400021
+:101A6000936E00002409001031C400F01089027147
+:101A700024020070108202E58F880014250F0001F7
+:101A8000AF8F00143C184000AF5801380A0001968F
+:101A900000000000974C01041180FFD93C18400061
+:101AA00030C34000146000A1000000008F460178A0
+:101AB00004C0FFFE8F87003824100800240F0008A0
+:101AC0008CE30008AF500178A74F0140A7400142C6
+:101AD000974E01048F86000031C9FFFF30CD000111
+:101AE00011A002E1012040212531FFFE241800024F
+:101AF000A75801463228FFFFA75101483C190800AA
+:101B00008F39043C172002D08F8C000C30DF00206E
+:101B100017E00002240400092404000130C20C0074
+:101B2000240504005045000134840004A744014A00
+:101B30003C1108008E3104203C1800483C10000184
+:101B40000238182530CF00020070282511E000046B
+:101B5000000018213C19010000B9282524030001C8
+:101B600030DF000453E00005AF8300083C0600109E
+:101B700000A6282524030001AF830008AF4510000C
+:101B80000000000000000000000000000000000055
+:101B90008F83000810600023000000008F451000B4
+:101BA00004A1FFFE000000001060001E0000000005
+:101BB0008F4410003C0C0020008C102410400019B1
+:101BC0008F8E000031CD000211A000160000000031
+:101BD000974F101415E000130000000097591008EB
+:101BE0003338FFFF271100060011188200033080F0
+:101BF00000C7282132300001322300031200032CD9
+:101C00008CA200000000000D00C7F821AFE2000028
+:101C10003C0508008CA5043024A600013C01080006
+:101C2000AC2604308F6D00003402FFFFAF8D00043E
+:101C30008CEC0000118202A6000020218CED000037
+:101C400031AC01001180028A000000003C02080053
+:101C50008C4204743C0308008C63044C3C1F080055
+:101C60008FFF04703C1808008F1804480048382182
+:101C70000068802100E8282B03E430210208402B73
+:101C80000304882100C57021022878213C01080046
+:101C9000AC30044C3C010800AC2F04483C01080067
+:101CA000AC2704743C010800AC2E04708F8400182B
+:101CB0000120302131290007249F000833F91FFF3C
+:101CC00003594021AF84001CAF990018251B400028
+:101CD000AF590084112000038F83002024C2000725
+:101CE0003046FFF88F84002800C3282100A4302B41
+:101CF00014C00002AF83002400A428230345602100
+:101D0000340D8000018D10213C0F1000AF850020A4
+:101D1000AF820038AF450080AF4F01788F88001444
+:101D2000250F00010A0001EFAF8F00148F62000839
+:101D30008F670000240500300007760231C300F0F1
+:101D4000106500A7240F0040546FFF4C8F880014CB
+:101D50008F4B01780560FFFE0000000030CA0200D2
+:101D600015400003000612820000000D00061282DA
+:101D7000304D0003000D4900012D18210003808023
+:101D8000020D402100086080019380218E1F000019
+:101D900017E00002000000000000000D8F6E00043C
+:101DA00005C202BD92070006920E000592020004D1
+:101DB0003C090001000E18800070F8218FED00181A
+:101DC000277100082448000501A96021000830821D
+:101DD000AFEC0018022020210E00059E26050014FD
+:101DE000920A00068F7900043C0B7FFF000A2080D6
+:101DF000009178218DF800043566FFFF0326282422
+:101E000003053821ADE70004920E0005920D000491
+:101E1000960C0008000E10800051C8218F2300008E
+:101E2000974901043C07FFFF006758243128FFFF52
+:101E3000010DF82103EC50233144FFFF01643025EC
+:101E4000AF260000920300072418000110780275E5
+:101E5000240F0003106F0285000000008E050010A3
+:101E60002419000AA7590140A7450142921800040D
+:101E70008F860000240F0001A7580144A7400146A7
+:101E80009747010430D100023C050041A7470148B3
+:101E900000001821A74F014A1220000330CB000494
+:101EA0003C0501412403000151600005AF83000897
+:101EB0003C06001000A6282524030001AF8300087B
+:101EC000AF4510000000000000000000000000000E
+:101ED000000000008F8A000811400004000000008C
+:101EE0008F4410000481FFFE000000008F6B000093
+:101EF000920800043C1108008E310444AF8B0004AA
+:101F000097590104311800FF3C0E08008DCE0440A3
+:101F10003325FFFF0305382102276021000010212F
+:101F2000250F000A31E8FFFF0187482B01C2682115
+:101F300001A9F821311000073C010800AC2C044431
+:101F40003C010800AC3F0440120000038F8C0018D5
+:101F50002506000730C8FFF8010C682131BF1FFFBC
+:101F6000AF8C001CAF9F0018AF5F00849744010442
+:101F7000035F80213084FFFF308A00071140000397
+:101F8000261B4000248900073124FFF88F8200209F
+:101F90008F850028008220210085702B15C000024B
+:101FA000AF820024008520233C0B08008D6B048C3D
+:101FB0003C0A08008D4A04880344882134038000C9
+:101FC000022310213C0F1000AF840020AF820038A4
+:101FD000AF440080AF4F01780A0002968F8800144A
+:101FE0008F5001780600FFFE30D10200162000035A
+:101FF000000612820000000D00061282305F00030E
+:10200000001F1900007F302100062080009FC8219A
+:1020100000194880013380218E180000130000024F
+:10202000000000000000000D8F6C000C058001FB1B
+:102030008F870038240E0001AE0E00008CE30008EC
+:10204000A20000078F65000400055402314D00FF17
+:1020500025A80005000830822CCB00411560000245
+:10206000A20A00040000000D8F7800043C03FFFF6B
+:1020700000E02821330BFFFF256C000B000C1082C1
+:1020800000022080008748218D3F000026040014B4
+:10209000A618000803E3C8240E00059EAD39000011
+:1020A0008F4F01083C11100001F1382410E001AB02
+:1020B00000000000974D01049208000725AAFFECDC
+:1020C000350600023144FFFFA2060007960600080D
+:1020D0002CC7001354E0000592030007921100077B
+:1020E000362F0001A20F00079203000724180001F9
+:1020F000107801C224090003106901D58F880038C7
+:1021000030CBFFFF257100020011788331E400FF1E
+:1021100000042880A20F000500A848218D2D000092
+:10212000974A01043C0EFFFF01AEF8243143FFFF44
+:10213000006B1023244CFFFE03ECC825AD390000D2
+:10214000920600053C03FFF63462FFFF30D800FF23
+:102150000018388000F08821922F00143C04FF7F83
+:102160003487FFFF31EE000F01C65821316500FFB3
+:1021700000055080015068218DAC00200148F821F5
+:10218000A20B00060182C824AE0C000CAFF9000CB3
+:10219000920900068E11000C032778240009C080E4
+:1021A0000310702195C60026030828210227202449
+:1021B000AE04000CADCF0020ADC60024ACA60010CC
+:1021C0008F8800003C0B08008D6B048C3C0A0800D3
+:1021D0008D4A0488241F001024190002A75F0140C3
+:1021E000A7400142A7400144A7590146974901046D
+:1021F00024070001310600022538FFFEA7580148D8
+:102200003C050009A747014A10C00003000018213F
+:102210003C05010924030001310C00045180000534
+:10222000AF8300083C08001000A828252403000103
+:10223000AF830008AF451000000000000000000060
+:1022400000000000000000009205000424AE00021F
+:1022500031CD0007000D182330620007AE020010D8
+:102260008F90000812000004000000008F4F100043
+:1022700005E1FFFE000000008F7100008F8E001846
+:102280003C0308008C630444AF91000497450104AB
+:1022900025CF001031E61FFF30A2FFFFAF8E001CDC
+:1022A000AF860018AF4600842449FFFE3C0C0800AE
+:1022B0008D8C0440974D010401208021000947C303
+:1022C0000070C02131A9FFFF0310F82B0188C8213D
+:1022D000033F202103463821313100073C0108002B
+:1022E000AC3804443C010800AC2404401220000334
+:1022F00024FB40002527000730E9FFF88F860020E7
+:102300008F8400280126382100E4C02B170000022A
+:10231000AF86002400E438230347202134198000CD
+:10232000009910213C0F1000AF870020AF820038C9
+:10233000AF470080AF4F01780A0002968F880014E3
+:102340009747010410E0FDAE3C1840008F5801781B
+:102350000700FFFE30C5400010A000033C1F00082E
+:102360000000000D3C1F0008AF5F01402410080072
+:102370008F860000AF5001789744010430D90001E6
+:10238000132000ED3086FFFF24CCFFFE240D000259
+:10239000A74D0146A74C01488F9100182408000D55
+:1023A000A748014A8F630000262F000831E21FFF73
+:1023B0000342702130C90007AF830004AF91001CB5
+:1023C000AF82001800C03821AF4200841120000302
+:1023D00025DB400024D800073307FFF88F85002055
+:1023E0008F84002800E5302100C4382B14E000025F
+:1023F000AF85002400C430238F8400140346F821E5
+:10240000340C8000AF86002003EC8021AF460080B2
+:10241000249900013C0610003C184000AF460178AA
+:10242000AF900038AF990014AF5801380A000196F8
+:10243000000000008F630000975101043067FFFF28
+:102440003228FFFF8F4F017805E0FFFE30EC0007D8
+:10245000000CF82333F0000724F9FFFE2404000ADF
+:10246000A7440140A7500142A7590144A740014693
+:10247000A74801488F45010830B800201700000226
+:10248000240300092403000130CD0002A743014AC0
+:102490003C04004111A00003000018213C0401414C
+:1024A0002403000130C9000451200005AF83000857
+:1024B0003C0600100086202524030001AF8300089D
+:1024C000AF44100000000000000000000000000009
+:1024D000000000008F8E000811C000040000000002
+:1024E0008F4210000441FFFE000000008F7F0000BB
+:1024F000276400088F91003CAF9F0004948500087A
+:102500009490000A9499000C30AFFFFF0010C400B3
+:102510003323FFFF11F100A6030320253C0E080022
+:102520008DCE04443C0C08008D8C044000E88821CA
+:102530002626FFFE01C628210000682100A6F82BF0
+:10254000018D2021009F80213C010800AC2504441E
+:102550003C010800AC30044024E200083042FFFF98
+:102560003047000710E000038F830018244F000756
+:1025700031E2FFF83106FFFF30C800070043802139
+:1025800032191FFF0359C021AF83001CAF990018F7
+:10259000271B4000AF590084110000038F8C0020DE
+:1025A00024C5000730A6FFF88F84002800CC28211E
+:1025B00000A4F82B17E00002AF8C002400A428230D
+:1025C000AF850020AF4500803C0408008C840434B3
+:1025D00003454821340E8000012E6821108000053B
+:1025E000AF8D0038939100172406000E12260011BB
+:1025F0002407043F3C021000AF4201788F8800148A
+:10260000250F00010A0001EFAF8F00140E0005C472
+:1026100000E020218F8800143C0B08008D6B048C97
+:102620003C0A08008D4A0488250F00010A0001EFCA
+:10263000AF8F00143C021000A7470148AF42017859
+:102640000A0004CE8F88001424040F001184003D7A
+:1026500030CE002015C0000224030009240300012D
+:102660000A00021AA743014A0A00020DA7400146C8
+:1026700094EF000894F1000A94F0000C8F8C003C59
+:10268000001174003207FFFF31EDFFFF11AC00377E
+:1026900001C720253C1808008F1804443C0F08008F
+:1026A0008DEF0440000080210308682101A8382B29
+:1026B00001F0702101C760213C010800AC2D0444E9
+:1026C0003C010800AC2C04400A00027A8F840018F8
+:1026D0003C0208008C42047C3C0308008C630454D8
+:1026E0003C1F08008FFF04783C1808008F18045026
+:1026F000004838210068802100E8282B03E43021BD
+:102700000208402B0304882100C57021022878218B
+:102710003C010800AC3004543C010800AC2F0450CC
+:102720003C010800AC27047C3C010800AC2E047876
+:102730000A00027A8F840018A74001460A00043577
+:102740008F91001830CD002015A0FFC52403000D87
+:10275000240300050A00021AA743014A974E010408
+:1027600025C5FFF00A00038130A4FFFF8F980040C9
+:102770001498FFC8000010213C0508008CA5046CCB
+:102780003C1F08008FFF046800A8C8210328302BD5
+:1027900003E22021008640213C010800AC39046C92
+:1027A0003C010800AC2804680A00027A8F840018F3
+:1027B0008F8C0040148CFF5900E8C8213C18080099
+:1027C0008F18046C3C1108008E3104682723FFFE2B
+:1027D00003034821000010210123302B0222702125
+:1027E00001C668213C010800AC29046C3C010800CA
+:1027F000AC2D04680A0004A524E200088F88003884
+:102800003C03FFFF8D02000C0043F82403E4C825BD
+:10281000AD19000C0A00038F30CBFFFF0A0003C381
+:10282000AE000000974A0104920400048E26000CBA
+:10283000014458212579FFF200C7C0243325FFFF4A
+:1028400003053825AE27000C0A0002E68E050010AD
+:102850003C0DFFFF8D0A0010014D582401646025D6
+:10286000AD0C00100A00038F30CBFFFF974301042B
+:10287000920E00048E290010006E1021244DFFEEF0
+:102880000127602431A8FFFF0188F825AE3F001022
+:102890000A0002E68E0500108E0F000CAE0000004C
+:1028A00000078880023028210A0002B8ACAF00205F
+:1028B0001460000D3058FFFF3C04FFFF0044682403
+:1028C00001A47026000E602B000D102B004CF82484
+:1028D00013E00002000000000000000D8CAF0000BB
+:1028E0000A00025001E410253B03FFFF0003882B80
+:1028F0000018802B0211202410800002000000002C
+:102900000000000D8CB900000A0002503722FFFFC2
+:102910003084FFFF30A5FFFF108000070000182162
+:10292000308200011040000200042042006518219E
+:102930001480FFFB0005284003E000080060102120
+:1029400010C00007000000008CA2000024C6FFFF9A
+:1029500024A50004AC82000014C0FFFB2484000402
+:1029600003E000080000000010A0000824A3FFFFFF
+:10297000AC86000000000000000000002402FFFF01
+:102980002463FFFF1462FFFA2484000403E00008BC
+:1029900000000000308EFFFF30D8FFFF00057C00F4
+:1029A00001F8602539CDFFFF01AC5021014C582BB7
+:1029B000014B4821000944023127FFFF00E8302184
+:1029C0000006240230C5FFFF00A418213862FFFF73
+:1029D00003E000083042FFFF3C0C08008D8C0484AB
+:1029E000240BFF8027BDFFD001845021014B4824D8
+:1029F000AF4900203C0808008D080484AFB20020D5
+:102A0000AFB00018AFBF0028AFB30024AFB1001CB7
+:102A1000936600040104382130E4007F009A1021FD
+:102A20003C0300080043902130C500200360802152
+:102A30003C080111277B000814A000022646007004
+:102A40002646006C9213000497510104920F000473
+:102A50003267000F322EFFFF31ED004001C72823FF
+:102A600011A0000500004821925900BC3338000431
+:102A70001700009000000000924300BC307F00046B
+:102A800013E0000F0000000010A0000D0000000087
+:102A9000960E0002240AFF8000A7602125CDFFFECC
+:102AA000A74D1016920B0004014B2024308200FF2A
+:102AB00010400085010C40253C0F0400010F40250B
+:102AC0008F5301780660FFFE2404000AA7440140EA
+:102AD000960D00022404000931AC0007000C5823B5
+:102AE000316A0007A74A0142960200022443FFFE12
+:102AF000A7430144A7400146975F0104A75F01482F
+:102B00008F590108333800205300000124040001CC
+:102B1000920F000431EE001015C000023483001043
+:102B200000801821A743014A0000000000000000B7
+:102B30000000000000000000AF481000000000008E
+:102B40000000000000000000000000008F51100095
+:102B50000621FFFE3113FFFF12600003000000009A
+:102B60008F481018ACC8000096030006307FFFFFA6
+:102B700027F900020019988200138880023B302157
+:102B80008CD800001520005700183402920300046E
+:102B90002405FF8000A3F82433F100FF1220002C4D
+:102BA00000000000924700BC30F2000212400028F2
+:102BB00000000000974B100C2562FFFEA742101684
+:102BC000000000003C0A040035490030AF49100005
+:102BD00000000000000000000000000000000000F5
+:102BE0008F4C10000581FFFE000000009749100C7B
+:102BF0008F51101C00C020213127FFFF24F200302C
+:102C0000001218820003288000BBF8213226FFFF43
+:102C1000AFF100000E0005B300112C020013C880B4
+:102C2000033B98218E78000000027400AFB80010BA
+:102C30008FA80010310FFFFFAFAF00108FA400105E
+:102C400001C46825AFAD00108FA60010AE6600006D
+:102C500097730008976D000A9766000C8F8A003CF6
+:102C6000000D5C0030CCFFFF3262FFFF104A0036DF
+:102C7000016C2025960600023C10100024D30008A9
+:102C80000E00013B3264FFFF974C01040E00014926
+:102C90003184FFFFAF5001788FBF00288FB300242D
+:102CA0008FB200208FB1001C8FB0001803E0000825
+:102CB00027BD003010A0FF700000000024A5FFFC1D
+:102CC0000A0005EC240900048CD10000AF51101853
+:102CD0008F5301780660FF7A2404000A0A00060177
+:102CE0000000000000A7C8218F8800388F4E101CFC
+:102CF0000019C0820018788001E82021AC8E000005
+:102D0000000E2C0200C020210E0005B331C6FFFFCB
+:102D1000023B28218CAD000000025400004030210D
+:102D2000AFAD00108FAC0010318BFFFFAFAB0010C8
+:102D30008FA2001001424825AFA900108FA70010F4
+:102D40000A000631ACA700008F8F0040148FFFC926
+:102D50000000000097420104960B00023C050800A9
+:102D60008CA5046C3049FFFF316AFFFF3C1108005D
+:102D70008E310468012A382124F2FFFE00B240217E
+:102D80000012FFC30112C82B023FC02103192021EA
+:102D90003C010800AC28046C3C010800AC24046829
+:102DA0000A00066B0000000000A4102B1040000970
+:102DB000240300010005284000A4102B04A00003F8
+:102DC000000318405440FFFC000528401060000735
+:102DD000000000000085302B14C0000200031842E0
+:102DE000008520231460FFFB0005284203E0000853
+:102DF000008010218F85002C27BDFFE800053027BB
+:102E00002CC300012CA400020083102510400003F5
+:102E1000AFBF00102405007FAF85002C00052827D8
+:102E200030A5FFFF0E000592240426F58F830030A5
+:102E3000240402BD004030210083382B10E000093B
+:102E400024050001000420400083102B04800003AF
+:102E5000000528405440FFFC0004204010A000085A
+:102E600000C350210064402B1500000200052842D9
+:102E70000064182314A0FFFB0004204200C350216B
+:102E80008FBF0010000A4C02312200FF27BD00183E
+:102E9000AF8A002C03E00008AF8900300A00002A46
+:102EA00000000000000000000000000D7478703683
+:102EB0002E322E3300000000060203000000000046
+:102EC000000001360000EA60000000000000000081
+:102ED00000000000000000000000000000000000F2
+:102EE00000000000000000000000000000000000E2
+:102EF00000000000000000000000000000000016BC
+:102F000000000000000000000000000000000000C1
+:102F100000000000000000000000000000000000B1
+:102F200000000000000000000000000000000000A1
+:102F3000000000000000138800000000000005DC15
+:102F4000000000000000000010000003000000006E
+:102F50000000000D0000000D3C02080024423C204F
+:102F60003C03080024633DD4AC4000000043202B08
+:102F70001480FFFD244200043C1D080037BD7FFC87
+:102F800003A0F0213C100800261000A83C1C0800FB
+:102F9000279C3C200E0002BA000000000000000D3B
+:102FA0008F8300383C088000350700708CE50000F6
+:102FB000008330253C02900000C22025AF85003000
+:102FC000AF4400208F4900200520FFFE3C03800015
+:102FD000346200708C4500008F8600303C19080078
+:102FE0008F39007C3C0E08008DCE007800A620238F
+:102FF00003245821000078210164682B01CF60214F
+:10300000018D50213C010800AC2B007C3C010800E4
+:10301000AC2A007803E00008000000000A0000412C
+:10302000240400018F8400383C05800034A2000194
+:103030000082182503E00008AF43002003E00008E9
+:10304000000010213084FFFF30A5FFFF1080000733
+:1030500000001821308200011040000200042042CC
+:10306000006518211480FFFB0005284003E00008DC
+:103070000060102110C00007000000008CA20000BA
+:1030800024C6FFFF24A50004AC82000014C0FFFB8F
+:103090002484000403E000080000000010A00008E1
+:1030A00024A3FFFFAC860000000000000000000029
+:1030B0002402FFFF2463FFFF1462FFFA248400044C
+:1030C00003E0000800000000308AFFFF93A800130F
+:1030D000A74A014497490E1630C600FF3C02100073
+:1030E000A7490146AF450148A3460152A748015AE6
+:1030F000AF4701608FA400188FA30014A7440158A4
+:10310000AF43015403E00008AF42017803E0000838
+:10311000000000003C038000346200708C49000015
+:103120008F8800002484000727BDFFF83084FFF853
+:10313000AF890030974D008A31ACFFFFAFAC000083
+:103140008FAB0000016850232547FFFF30E61FFFCB
+:1031500000C4282B14A0FFF73C0C8000358B0070B6
+:103160008D6A00003C0708008CE700843C060800DC
+:103170008CC6008000081082014918230002788064
+:1031800000E370210000202101C3C82B00C4C0212E
+:1031900001FA4021031948212502400027BD0008FB
+:1031A0003C010800AC2E00843C010800AC290080E2
+:1031B00003E00008000000008F8200002486000762
+:1031C00030C5FFF800A2182130641FFF03E000089B
+:1031D000AF8400008F8700388F8A004027BDFFB87A
+:1031E0008F860044AFB60040AFBF0044AFB5003C8F
+:1031F000AFB40038AFB30034AFB20030AFB1002C81
+:10320000AFB000288F4501048D4900ACAF47008066
+:103210008CC8002000A938230000B021AF480E1050
+:103220008F440E1000004821AF440E148CC20024BD
+:10323000AF420E188F430E18AF430E1C10E001254D
+:103240002D230001936B0008116000D400000000E2
+:10325000976E001031CDFFFF00ED602B158000CF81
+:103260000000000097700010320FFFFFAF4F0E00FC
+:103270008F520000325100081220FFFD00000000B4
+:1032800097540E088F460E043285FFFF30B30001BD
+:1032900012600132000000000000000D30B8A040B4
+:1032A00024150040131500C030A9A0001120012DE5
+:1032B00000000000937F000813E0000800000000F9
+:1032C00097630010306BFFFF00CB402B1100000311
+:1032D00030AC00401180012300000000A785003CB5
+:1032E000AF8600349366000800E02821AFA70020D5
+:1032F00014C0012427B30020AF60000C9782003C6B
+:103300003047400014E00002240300162403000E9E
+:1033100024194007A363000AAF790014938A003E82
+:103320008F740014315800070018AA4002959025A8
+:10333000AF7200149784003C8F700014309100101D
+:1033400002117825AF6F0014978E003C31CD000834
+:1033500011A00147000028218F6700143C021000D3
+:103360003C0C810000E22825AF65001497460E0A48
+:103370002408000E3405FFFC30C3FFFF006C582505
+:10338000AF6B0004A3680002937F000A27E90004E2
+:10339000A369000A9786003C9363000A30CC1F00A3
+:1033A000000C598301634021251F0028A37F0009D9
+:1033B00097490E0CA769001093790009272A00028B
+:1033C000315800070018A82332B10007A371000B81
+:1033D00093740009976400108F910034978F003C1C
+:1033E000329200FF024480210205702131ED00403D
+:1033F00011A0000531C4FFFF0091282B3C12800072
+:1034000010A000140000A0210224382B14E0011B9E
+:103410008FA500208F4D0E14AF4D0E108F420E1C45
+:10342000AF420E18AF440E008F4F000031EE00087F
+:1034300011C0FFFD0000000097540E080080882195
+:1034400000009021A794003C8F500E04241400012A
+:10345000AF900034976400103095FFFF8E68000035
+:103460000111F82317E00009AE7F00008F650014FA
+:103470008F8B004434A60040AF6600148F4C0E10B2
+:10348000AD6C00208F430E18AD63002493670008D5
+:1034900014E000D2000000000E00009E2404001082
+:1034A0008F8900483C08320000402821312600FF67
+:1034B0000006FC0003E8502525390001AF990048BB
+:1034C000AC4A0000937800099370000A330400FFAF
+:1034D00000047400320F00FF01CF6825AC4D0004DA
+:1034E0008F820048064000EAACA20008ACA0000CA5
+:1034F0009783003C306B0008156000022628000608
+:1035000026280002974E0E148F450E1C8F6700046C
+:10351000936D000231C4FFFF31A200FFAFA2001083
+:103520008F6C0014AFA800180E00008BAFAC001415
+:10353000240400100E0000C7000000008E7200007E
+:1035400016400005000000008F6400142405FFBF32
+:1035500000859824AF7300148F79000C033538214F
+:10356000AF67000C9375000816A00008000000006B
+:1035700012800006000000008F7F00143C0BEFFF5C
+:103580003568FFFE03E84824AF690014A3740008FF
+:103590008FA500200A00024602202021AF470E001E
+:1035A0000A0000F5000000008F5901780720FFFE97
+:1035B000241F08008F840000AF5F0178974B008ABA
+:1035C000316AFFFF014448232528FFFF31021FFF16
+:1035D0002C4300081460FFF9000000008F8E0048A3
+:1035E0008F8D003800C048210344202125C60001EA
+:1035F000240C0F00AF86004800E9382324864000E1
+:1036000031CA00FF11AC0005240800019391003E6F
+:103610003230000700107A4035E80001000AAC00A3
+:103620003C18010002B8A025AC9440008F930048DC
+:1036300030B2003630A40008ACD3000410800097EC
+:1036400001123025974E0E0A8F8D00003C0281003A
+:1036500031CCFFFF25AB0008018240253C03100060
+:1036600031651FFF25390006241F000EAF48016099
+:1036700000C33025A75F015AAF850000A759015844
+:1036800014E0000A8F93003824120F0052720002D7
+:103690002416000134C600408F580E108F94004449
+:1036A000AE9800208F550E18AE9500248F450E144D
+:1036B000AF4501448F590E1CAF590148A34A01522E
+:1036C0003C0A1000AF460154AF4A017814E0FEDD19
+:1036D0002D2300010076A025128000178FBF004423
+:1036E0008F84003824160F0010960084000000001C
+:1036F0008F45017804A0FFFE24150F001095006E81
+:10370000000000008F470E14240202403C1F1000EE
+:10371000AF4701448F440E1CAF440148A3400152FF
+:10372000A740015AAF400160A7400158AF42015481
+:10373000AF5F01788FBF00448FB600408FB5003C6B
+:103740008FB400388FB300348FB200308FB1002CAB
+:103750008FB0002803E0000827BD004814C0FED049
+:1037600030B8A0408F420E148F84004400004821DE
+:10377000AC8200208F510E1CAC9100240A00020E76
+:103780002D2300018F910034978A003C3C12800069
+:103790000220A821315800401700FF300000A0216E
+:1037A000976900108F9200343139FFFF13320035D2
+:1037B00000002021008048211480FEA000A03821B4
+:1037C0008F420E148F840044AC8200208F510E1C57
+:1037D000AC9100240A00020E2D230001936A000917
+:1037E0009378000B315000FF330F00FF020F702160
+:1037F00025C2000A3050FFFF0E00009E020020216B
+:103800008F8600483C1F410024CD0001AF8D004849
+:10381000936C000930C600FF00064400318300FFAE
+:10382000246B0002010B4825013FC825AC5900005C
+:103830008F67000C97440E1400F22825AC45000455
+:103840008F450E1C8F670004936A00023084FFFFCF
+:10385000315800FFAFB800108F6F0014AFB10018DF
+:103860000E00008BAFAF00140A0001A60200202159
+:10387000AF6000040A00013EA36000020A00024695
+:1038800000002021000090210A0001702414000192
+:103890003C1280000A000195ACB2000C8F91000030
+:1038A00025240002A744015826300008320F1FFFCC
+:1038B0000A0001F9AF8F0000AF40014C1120002C2D
+:1038C000000000008F590E10AF5901448F430E18AD
+:1038D000240200403C1F1000AF430148A3400152A6
+:1038E000A740015AAF400160A7400158AF420154C0
+:1038F000AF5F01780A0002278FBF00441120000645
+:103900000000000097460E0830CC004015800002F1
+:10391000000000000000000D8F4D017805A0FFFEA3
+:103920000000000097530E103C120500240E2000EA
+:10393000326AFFFF0152C025AF58014C8F4F0E1461
+:103940003C021000AF4F01448F500E1CAF50014895
+:10395000A34001528F840038A740015AAF40016054
+:10396000A7400158AF4E01540A000215AF4201783A
+:103970008F490E14AF4901448F430E1C0A00028E7A
+:10398000240200403C0E20FF27BDFFE03C1A8000CF
+:103990003C0F800835CDFFFDAFBF001CAFB2001853
+:1039A000AFB10014AFB00010AF8F0040AF4D0E00AC
+:1039B0000000000000000000000000000000000007
+:1039C000000000003C0C00FF358BFFFDAF4B0E00EC
+:1039D0003C0660048CC95000240AFF7F3C11600043
+:1039E000012A40243507380CACC750008E24043817
+:1039F00024050009AF4500083083FFFF38622F71AE
+:103A00002450C0B3AF8000480E000068AF800000B3
+:103A100052000001AE20442C0E0004353C11800001
+:103A20000E000ED9363000708F8A00403C1208001C
+:103A300026523C88020088218E0800008F5F00001B
+:103A40003BF900013338000113000017AF88003044
+:103A5000022048218D2700003C0F08008DEF006CEC
+:103A60003C0C08008D8C006800E8C02301F8282178
+:103A70000000682100B8302B018D582101664021DB
+:103A80003C010800AC25006C3C010800AC28006833
+:103A90008F44000038830001306200011440FFEDC4
+:103AA00000E04021AF8700308E0C00003C0508008C
+:103AB0008CA5006C3C0408008C84006801883023CD
+:103AC00000A638210000102100E6402B00821821BA
+:103AD0000068F8213C010800AC27006C3C0108009C
+:103AE000AC3F00688F49010025590088AF99004418
+:103AF000AF890038AF4900208E070000AF87003043
+:103B00008F4D017805A0FFFE000000008E0600002A
+:103B10003C0B08008D6B00743C0408008C84007022
+:103B200000C728230165F8210000102103E5402B80
+:103B30000082382100E8C821240908003C0108005F
+:103B4000AC3F00743C010800AC390070AF4901780B
+:103B500093580108A398003E938F003E31EE000178
+:103B600015C000158F830038240E0D00106E00194B
+:103B7000240F0F00106F001D00000000915900007D
+:103B800024180050332900FF113800043C1F400066
+:103B9000AF5F01380A0002E7000000000E00090EC6
+:103BA000000000008F8A00403C1F4000AF5F0138DA
+:103BB0000A0002E700000000938D003E31AC0006D1
+:103BC000000C51000E0000CE0152D8210A00034320
+:103BD0008F8A00403C1B0800277B3D080E0000CE6A
+:103BE000000000000A0003438F8A00403C1B0800CD
+:103BF000277B3D280E0000CE000000000A00034392
+:103C00008F8A004090AA00018FAB00108CAC00108E
+:103C10003C0300FF8D680004AD6C00208CAD0014E7
+:103C200000E060213462FFFFAD6D00248CA7001816
+:103C30003C09FF000109C024AD6700288CAE001CC0
+:103C40000182C82403197825AD6F0004AD6E002CE5
+:103C50008CAD0008314A00FFAD6D001C94A9000234
+:103C60003128FFFFAD68001090A70000A56000029A
+:103C7000A1600004A167000090A30002306200FF71
+:103C80000002198210600005240500011065000E75
+:103C90000000000003E00008A16A00018CD80028A1
+:103CA000354A0080AD7800188CCF0014AD6F001439
+:103CB0008CCE0030AD6E00088CC4002CA16A0001CF
+:103CC00003E00008AD64000C8CCD001CAD6D001845
+:103CD0008CC90014AD6900148CC80024AD680008BC
+:103CE0008CC70020AD67000C8CC200148C8300646C
+:103CF0000043C82B13200007000000008CC20014F2
+:103D0000144CFFE400000000354A008003E0000886
+:103D1000A16A00018C8200640A000399000000007F
+:103D200090AA000027BDFFF88FA9001CA3AA0000DD
+:103D30008FAE00003C0FFF808FA8001835E2FFFF18
+:103D40008CCD002C01C26024AFAC0000A120000487
+:103D500000E06021A7A000028FB800008D270004BA
+:103D60000188182100A0582100C05021006D28268C
+:103D70003C06FF7F3C0F00FF2CAD000135EEFFFF3E
+:103D800034D9FFFF3C02FF0003193024000D1DC091
+:103D9000010EC82400E2C02400C370250319782551
+:103DA000AD2E0000AD2F00048D450024AFAE000005
+:103DB000AD2500088D4D00202405FFFFAD2D000C22
+:103DC000956800023107FFFFAD27001091660018CB
+:103DD00030C200FF000219C2506000018D4500345E
+:103DE000AD2500148D67000827BD0008AD27001C15
+:103DF0008C8B00CCAD2C0028AD20002CAD2B0024EA
+:103E0000AD20001803E00008AD20002027BDFFE032
+:103E1000AFB20018AFB10014AFB00010AFBF001CBC
+:103E20009098000000C088213C0D00FF330F007FF8
+:103E3000A0CF0000908E000135ACFFFF3C0AFF00D0
+:103E4000A0CE000194A6001EA22000048CAB00149A
+:103E50008E29000400A08021016C2824012A40241E
+:103E60000080902101052025A6260002AE24000432
+:103E700026050020262400080E00007624060002F5
+:103E800092470000260500282624001400071E0083
+:103E90000003160324060004044000032403FFFF6C
+:103EA000965900023323FFFF0E000076AE23001068
+:103EB000262400248FBF001C8FB200188FB100147D
+:103EC0008FB0001024050003000030210A0000809C
+:103ED00027BD002027BDFFD8AFB1001CAFB0001830
+:103EE000AFBF002090A80000240200018FB0003C6A
+:103EF0003103003F00808821106200148FAA00382F
+:103F0000240B0005506B0016AFAA001000A0202162
+:103F100000C028210E0003DC02003021922400BCE6
+:103F2000308300021060000326060030ACC00000A1
+:103F300024C600048FBF00208FB1001C8FB0001872
+:103F400000C0102103E0000827BD002801403821EF
+:103F50000E00035AAFB000100A0004200000000059
+:103F60000E0003A1AFB000140A00042000000000FE
+:103F70003C02000A034218213C04080024843D6CE2
+:103F80002405001A000030210A000080AF8300548D
+:103F90003C038000346200708C48000000A058216F
+:103FA00000C04821308A00FFAF8800308F4401787C
+:103FB0000480FFFE3C0C8000358600708CC500003C
+:103FC0003C0308008C6300743C1808008F180070D4
+:103FD00000A82023006468210000C82101A4782BD8
+:103FE0000319702101CF60213C010800AC2D007441
+:103FF0003C010800AC2C00708F480E14AF480144FF
+:10400000AF47014CA34A0152A74B01589346010800
+:1040100030C5000854A0000135291000934B090059
+:1040200024070050316A00FF11470007000000001C
+:104030008F450E1CAF450148AF4901543C091000A3
+:1040400003E00008AF490178934D010831A800084A
+:104050001100001000000000934F010831EE001025
+:1040600051C00001352900083C04080090843DD06F
+:10407000A34401508F4309A4AF4301488F4209A0D4
+:10408000AF420144AF4901543C09100003E000086D
+:10409000AF4901783C1908008F393D8C333800084E
+:1040A0005700FFF1352900080A00047300000000E2
+:1040B00024070040AF470814AF4008108F4209445E
+:1040C0008F4309508F4409548F45095C8F46094C32
+:1040D000AF820064AF830050AF84004CAF85005CBA
+:1040E00003E00008AF8600609346010930C5007FF9
+:1040F000000518C0000521400083102103E00008DE
+:10410000244200883C09080091293D9124A800021E
+:104110003C05110000093C0000E8302500C51825C9
+:1041200024820008AC83000003E00008AC80000497
+:104130009347010B8F4A002C974F09083C18000E3B
+:104140000358482131EEFFFF000E41C0AF48002C5C
+:1041500097430908952C001A008040212403000190
+:10416000318BFFFFAC8B00008D2D001C00A058216F
+:1041700000C06021AC8D00048D24002030E7004099
+:10418000AD04000891220019304400031083004858
+:104190002885000214A00062240600021086005642
+:1041A00024190003109900660000000010E0003A96
+:1041B000000000003C07080094E73D8624E200016F
+:1041C000934F0934934709219525002A31EE00FFCA
+:1041D000000E488230ED00FF978700580009360036
+:1041E000000D1C003044FFFF00C310250044C02513
+:1041F00000A778213C19400003197025000F4C00DE
+:10420000AD090004AD0E0000934D09203C030006EB
+:1042100025090014000D360000C32025AD04000858
+:104220008F59092C24E5000130A27FFFAD19000C45
+:104230008F580930A782005825020028AD180010B9
+:104240008F4F0938AD0F0014AD2B00048F4E09407D
+:10425000AD2E0008934D09373C05080090A53D9010
+:104260008F4409488F46094031A700FF00EC182110
+:10427000008678230003C7000005CC0003196025E1
+:1042800031E8FFFC01885825AD2B000CAD20001053
+:1042900003E00008AF4A002C3C0D080095AD3D86B8
+:1042A0003C0E080095CE3D800A0004C901AE1021E5
+:1042B0003C05080094A53D8A3C06080094C63D8054
+:1042C0003C18080097183D7C952E002400A6782104
+:1042D00001F86823000E240025A2FFF200821825B1
+:1042E00024190800AD03000CAD190014AD00001036
+:1042F0000A0004C4250800189526002495250028E6
+:104300000006C40000057C00370E810035ED080072
+:10431000AD0E000CAD0D00100A0004C425080014F9
+:104320001480FFA200000000952400240004140063
+:1043300034430800AD03000C0A0004C42508001033
+:104340003C03080094633D8A3C05080094A53D8029
+:104350003C06080094C63D7C953900249538002819
+:10436000006520210086782300196C000018740075
+:1043700025E2FFEE01C2202535A3810024190800A3
+:10438000AD03000CAD040010AD190018AD00001411
+:104390000A0004C42508001C03E00008240201F4FC
+:1043A00027BDFFE8AFB00010AFBF00140E000060E3
+:1043B0000080802124050040AF4508148F83005001
+:1043C0008F84004C8F85005C0070182100641023DE
+:1043D00018400004AF830050AF6300548F66005450
+:1043E000AF86004C1200000C000000008F440074E7
+:1043F000936800813409FA002D07000710E00005DA
+:1044000000891021936C0081240B01F4018B50046E
+:1044100001441021AF62000C8F4E095C01C5682376
+:1044200019A000048FBF00148F4F095CAF8F005C90
+:104430008FBF00148FB000100A00006227BD001863
+:104440008F8400648F8300508F82004CAF640044DF
+:10445000AF63005003E00008AF6200543C038000EB
+:10446000346200708C43000027BDFFF8308700FFE6
+:1044700030A900FF30C800FFAF8300308F440178BF
+:104480000480FFFE3C028000345900708F38000029
+:10449000A3A700033C0708008CE700748FAC000062
+:1044A0003C0608008CC60070030378233C0E7FFF97
+:1044B00000EFC82135CDFFFF00005021018D2824D9
+:1044C00000CA1821000847C0032F202B00A8102580
+:1044D0000064C021AFA200003C010800AC390074A8
+:1044E0003C010800AC380070934F010AA3A0000201
+:1044F0003C0E80FFA3AF00018FAC0000312B007F8A
+:1045000035CDFFFF018D4824000B5600012A4025C0
+:10451000240730002406FF803C05100027BD00085A
+:10452000AF48014CAF470154A7400158A346015280
+:1045300003E00008AF45017827BDFFE8AFBF0014D6
+:10454000AFB000108F6500743C068000309000FF13
+:1045500000A620250E000060AF6400749363000580
+:10456000346200080E000062A362000502002021F0
+:104570008FBF00148FB00010240500052406000131
+:104580000A00057027BD001827BDFFE03C0380002E
+:10459000AFB00010AFBF0018AFB1001434620070AC
+:1045A0008C470000309000FF30A800FFAF8700303C
+:1045B0008F4401780480FFFE3C18800037110070A2
+:1045C0008E2F00003C0D08008DAD00743C0A0800E1
+:1045D0008D4A007001E7702301AE282100005821A8
+:1045E00000AE302B014B4821012638213C01080048
+:1045F000AC250074000088213C010800AC27007045
+:104600001100000F000000008F6200742619FFFFE8
+:104610003208007F0002FE0233E5007F150000062D
+:10462000332200FF2407FF800207202624A3FFFF78
+:1046300000838025320200FF0040802124111008F1
+:104640000E000060000000008F49081831250004AA
+:1046500014A0FFFD3218007F001878C000187140C8
+:1046600001CF682125AC0088AF4C0818274A098083
+:104670008D4B0020AF4B01448D460024AF460148CE
+:10468000A35001500E000062A740015802201021E3
+:104690008FBF00188FB100148FB0001003E0000826
+:1046A00027BD002027BDFFE8308400FFAFBF00100A
+:1046B0000E0005BB30A500FF8F8300508FBF001098
+:1046C000344500402404FF903C02100027BD001830
+:1046D000AF43014CA3440152AF45015403E000082D
+:1046E000AF4201789343093E306200081040000D4C
+:1046F0003C0901013528080AAC8800008F47007486
+:10470000AC8700043C06080090C63D9030C5001000
+:1047100050A00006AC8000088F6A0060AC8A0008D8
+:104720002484000C03E00008008010210A00062207
+:104730002484000C27BDFFE8AFBF0014AFB0001009
+:104740009346093F00A050210005288000853823AA
+:1047500030C200FF240300063C09080095293D866D
+:1047600024E8FFD824050004104300372406000283
+:104770009750093C3C0F020400063400320EFFFF44
+:1047800001CF6825AC8D0000934C093E318B002091
+:104790001160000800000000934309363C02010349
+:1047A000345F0300307900FF033FC0252405000873
+:1047B000AC98000493430934935909210005F88209
+:1047C000306200FF0002C082332F00FF00186E002D
+:1047D000000F740001AE6025018920253C094000CE
+:1047E00000898025ACF0FFD8934309378F4F0948E3
+:1047F0008F580940306200FF004AC821033F7021F2
+:1048000001F86023000E6F0001A650253185FFFCE2
+:10481000001F58800145482501683821AD09002056
+:104820000E00006024F00028240400040E00006242
+:10483000A364003F020010218FBF00148FB000104E
+:1048400003E0000827BD00180A0006352406001200
+:1048500027BDFFD024090010AFB60028AFB5002453
+:10486000AFB40020AFB10014AFB000103C0108009D
+:10487000A0293D90AFBF002CAFB3001CAFB2001811
+:1048800097480908309400FF3C02000E3107FFFFF3
+:10489000000731C0AF46002C974409089344010B30
+:1048A00030B500FF03428021308300300000B0218A
+:1048B0001060012500008821240C00043C01080040
+:1048C000A02C3D90934B093E000B5600000A2E038E
+:1048D00004A0016000000000AF400048934F010BAE
+:1048E00031EE002011C00006000000009358093E80
+:1048F00000189E0000139603064001890000000086
+:104900009344010B30830040106000038F930050EC
+:104910008F8200502453FFFF9347093E30E6000882
+:1049200014C0000224120003000090219619002CEC
+:1049300093580934934F0937A7990058330C00FF57
+:1049400031EE00FF024E6821000D5880016C5021AD
+:10495000015140213C010800A4283D869205001821
+:1049600030A900FF010918213C010800A4233D885B
+:104970009211001816200002000000000000000D37
+:104980003C010800A4233D8A3C010800A4203D808E
+:104990003C010800A4203D7C935F010B3063FFFFC6
+:1049A00033F00040120000022464000A2464000B6B
+:1049B0003091FFFF0E00009E022020219358010B32
+:1049C0003C08080095083D8A0040202100185982C3
+:1049D000316700010E00049A01072821934C010B56
+:1049E0008F4B002C974E09083C0F000E034F4021BF
+:1049F00031CDFFFF000D51C0AF4A002C974309088D
+:104A00009505001A004038212404000130A9FFFF59
+:104A1000AC4900008D06001C00404821318A00404E
+:104A2000AC4600048D020020ACE20008910300199E
+:104A300030630003106400EC28790002172001188D
+:104A4000241000021070010C241F0003107F011EAF
+:104A500000000000114000DE000000003C090800DA
+:104A600095293D8625220001935F0934934E092143
+:104A70009504002A33F900FF0019C08231CF00FFEE
+:104A8000978E005800184600000F6C00010D80251D
+:104A90003045FFFF02051025008E50213C034000E9
+:104AA00000433025000A6400ACEC0004ACE60000D2
+:104AB000935F09203C19000624EC0014001FC60077
+:104AC00003197825ACEF00088F48092C25CD00018B
+:104AD00031A57FFFACE8000C8F500930A785005846
+:104AE00024E80028ACF000108F4409380100802130
+:104AF000ACE40014AD9300048F530940AD9300085B
+:104B0000934A09373C19080093393D908F4309486F
+:104B10008F460940314200FF0052F82100667023A1
+:104B2000001F7F000019C40001F8282531CDFFFCCB
+:104B300000AD2025AD84000CAD800010AF4B002CE3
+:104B4000934B093E317300081260000D3C060101D1
+:104B500034CC080AACEC00288F530074AD13000469
+:104B60003C0B0800916B3D903167001050E0000352
+:104B7000AD0000088F6A0060AD0A00082510000C27
+:104B800012C0003D000000009343093F24160006B8
+:104B900024060004306200FF105600C924070002FA
+:104BA0009758093C3C0F0204330DFFFF01AF40252D
+:104BB000AE0800009345093E30A400201080000894
+:104BC00000000000935309363C0B0103357F0300BE
+:104BD000327900FF033F7025AE0E00042406000862
+:104BE000934F093493480921312AFFFF31ED00FF2B
+:104BF000000D1082310300FF0002B60000032C00FC
+:104C000002C56025018A9825001220803C094000D9
+:104C10000204502302695825AD4BFFD8935F093732
+:104C20008F4F09488F58094033F900FF0332702134
+:104C30000006B08201D668210007440001F828234D
+:104C4000000D1F000068302530A2FFFC2547FFD86B
+:104C500000C260250016808002074821ACEC0020CD
+:104C6000253000280E00006024120004A372003FCB
+:104C70000E000062000000009347010B30F200407C
+:104C8000124000053C1900FF8E180000372EFFFF70
+:104C9000030E3024AE0600000E0000C702202021C3
+:104CA0003C10080092103D90321100031220000FBA
+:104CB00002A028218F89005025330001AF930050B6
+:104CC000AF7300508F6B00540173F8231BE0000298
+:104CD000026020218F640054AF6400548F4C007434
+:104CE000258401F4AF64000C02A028210280202159
+:104CF000A76000680E0005BB3C1410008F850050B3
+:104D000034550006AF45014C8F8A00488FBF002CF8
+:104D10008FB3001C25560001AF9600488FB20018D3
+:104D2000A34A01528FB60028AF5501548FB1001429
+:104D3000AF5401788FB500248FB400208FB00010DD
+:104D400003E0000827BD00309358093E00189E007C
+:104D500000139603064200362411000293440923EF
+:104D6000308300021060FEDD8F8600608F8200506D
+:104D700014C2FEDA000000000E0000600000000017
+:104D80009369003F24070016312800FF1107000C2B
+:104D9000240500083C0C0800918C3D90358B0001E7
+:104DA0003C010800A02B3D90936A003F314300FF77
+:104DB00010650065240D000A106D005E2402000CD1
+:104DC0000E000062000000000A00069000000000D3
+:104DD0003C09080095293D863C0A0800954A3D801B
+:104DE0000A0006F3012A10213C09080095293D8A92
+:104DF0003C04080094843D803C06080094C63D7C39
+:104E000095030024012410210046F8230003CC0060
+:104E100027F0FFF20330C025240F0800ACF8000C87
+:104E2000ACEF0014ACE000100A0006EE24E7001816
+:104E30003C010800A0313D90935F093E241600011B
+:104E400033F900201720FEA5241100080A0006905F
+:104E5000241100048F6E00848F4D094011A0FE9E26
+:104E6000AF8E0050240F00143C010800A02F3D908D
+:104E70000A00068F00000000950E0024950D002802
+:104E8000000E6400000D2C003589810034A6080056
+:104E9000ACE9000CACE600100A0006EE24E70014B2
+:104EA0001460FEEC000000009502002400021C00CB
+:104EB00034640800ACE4000C0A0006EE24E700109D
+:104EC0000A000741240700123C02080094423D8A70
+:104ED0003C06080094C63D803C03080094633D7C7A
+:104EE00095100024951900280046F82103E3C023FB
+:104EF00000106C0000197400270FFFEE01CF282569
+:104F000035AC8100ACEC000CACE5001024070800C7
+:104F1000AD2700182527001C0A0006EEAD2000145E
+:104F20008F7F004CAF7F00548F7900540A000699A0
+:104F3000AF790050A362003F0E0000620000000045
+:104F40000A00069000000000240200140A0008274E
+:104F5000A362003F27BDFFE8308400FFAFBF001011
+:104F60000E0005BB30A500FF9378007E9379007F8B
+:104F7000936E00809368007A332F00FF001866005C
+:104F8000000F6C0031CB00FF018D4825000B520053
+:104F90008FBF0010012A3825310600FF344470000D
+:104FA00000E628252402FF813C03100027BD0018DD
+:104FB000AF45014CAF440154A342015203E0000845
+:104FC000AF43017827BDFFD8AFB20018AFB10014CE
+:104FD000AFB00010AFBF0020AFB3001C9342010977
+:104FE000308600FF30B000FF000618C23204000215
+:104FF0003071000114800005305200FF93670005F6
+:1050000030E5000810A0000D30C80010024020213B
+:105010000E0005A702202821240400018FBF0020D4
+:105020008FB3001C8FB200188FB100148FB0001026
+:105030000080102103E0000827BD00281500003281
+:105040000000000093430109000028213062007F26
+:10505000000220C00002F94003E49821267900886C
+:10506000033B98218E7800248E6F0008130F0046B2
+:10507000000000008F640084241800020004FD82F8
+:1050800033F900031338007C0000000093660083AE
+:10509000934A0109514600043205007C10A00060CB
+:1050A000000000003205007C14A0005302402021C3
+:1050B00016200006320400018E7F00248F5901045F
+:1050C00017F9FFD600002021320400011080000AE9
+:1050D000024020218F4209408F9300641053000644
+:1050E000000000000E00066D022028218F430940B9
+:1050F000AF630044024020210E0006020220282156
+:105100000A000860240400013C0908008D2900649D
+:10511000252600013C010800AC26006416000012A0
+:10512000000000008F6D00843C0E00C001AE6024C2
+:1051300015800005024020210E00082E02202821A3
+:105140000A00086024040001240500040E00057014
+:1051500024060001024020210E00082E02202821F2
+:105160000A000860240400010E000041240400012C
+:10517000936B007D020B50250E000062A36A007D38
+:105180000A0008A38F6D00848F6600748F480104A5
+:105190008E67002400064E021507FFB63126007FF9
+:1051A000936B008326440001308A007F1146004340
+:1051B000316300FF5464FFB08F6400842645000112
+:1051C00030B1007F30A200FF122600042405000148
+:1051D000004090210A00087624110001240FFF806E
+:1051E000024F702401CF9026324200FF00409021F0
+:1051F0000A000876241100010E00066D0220282105
+:10520000321800301300FFAA321000820240202121
+:105210000E0005A7022028210A00086024040001CE
+:105220008F6E00743C0F80002405000301CF902591
+:10523000AF72007493710083240600010E000570A4
+:10524000322400FF0E00004124040001936D007D14
+:10525000020D60250E000062A36C007D3C0B08006F
+:105260008D6B0054257000013C010800AC300054E7
+:105270000A000860240400018F6800743C09800063
+:105280002405000401093825AF6700749363008387
+:10529000240600010E000570306400FF0E0000417E
+:1052A000240400019362007D020298250E00006232
+:1052B000A373007D0A00086024040001324D0080C1
+:1052C00039AC0080546CFF6C8F6400840A0008C9FC
+:1052D0002645000127BDFFC83C0A0008AFBF0030CB
+:1052E000AFB5002CAFB40028AFB30024AFB200209C
+:1052F000AFB1001CAFB00018034AD8212409004008
+:10530000AF490814AF4008108F4209448F43095039
+:105310008F4609548F47095C8F48094C9344010814
+:105320009345010BAF820064308400FF30A500FF7D
+:10533000AF830050AF86004CAF87005C0E00084A78
+:10534000AF8800601440017D8FBF0030A760006807
+:10535000934D0900240B00503C15080026B53D482C
+:1053600031AC00FF3C12080026523D58118B00035F
+:10537000000000000000A8210000902193510109C5
+:105380008F9F005024040010322E007F000E68C052
+:10539000000E6140018D282124B40088AF54081804
+:1053A0008F4901048F4A09A43C0B000E034BC02116
+:1053B000012A10233C010800AC223D6C8F430958A0
+:1053C0003C010800A0243D9097470908007F302346
+:1053D0003C010800AC263D7030E8FFFF0008C9C062
+:1053E0003C010800AC3F3D94AF59002C974209089E
+:1053F0009710002C8EB10000930F001803749821B1
+:10540000A7900058AF9300440220F80931F000FF44
+:10541000304E000215C001B2304F000111E0014FC3
+:10542000000000009343093E3066000814C00002EB
+:10543000241400030000A0218F5809A424130001A4
+:105440003C010800AC383D98934F0934935109371B
+:1054500031EC00FF322E00FF028E6821000D288003
+:1054600000AC5021015058213C010800A42B3D887C
+:105470003C010800A42A3D8693490934312200FFEB
+:1054800002022021249000103C010800A4303D8439
+:10549000240700068F9F00503C010800AC273D8C7C
+:1054A0008F88005C8F59095800008021011F282334
+:1054B00004A00149033F20230480014700A4302BAE
+:1054C00010C00149000000003C010800AC253D70FF
+:1054D0008E4200000040F809000000003043000246
+:1054E000146000F80040882130440001548000100E
+:1054F0008E4200043C0908008D293D743C0AC0001E
+:10550000012A8025AF500E008F45000030AB000807
+:105510001160FFFD00000000974D0E0824100001EF
+:10552000A78D003C8F4C0E04AF8C00348E420004DB
+:105530000040F8090000000002228825322E0002F7
+:1055400015C00180000000003C09080095293D7C41
+:105550003C06080094C63D883C0A0800954A3D7EFA
+:105560003C1908008F393D74012660213C18080061
+:105570008F183D983C03080094633D92018A2021D6
+:105580008F4E09400329F821248F000203E32821CC
+:10559000031968213C010800A42C3D8AAF8E0064E9
+:1055A0003C010800AC2D3D983C010800A4253D803D
+:1055B0000E00009E31E4FFFF8F870048004020214D
+:1055C0003C010800A0273D918E42000824E800011C
+:1055D000AF8800480040F809000000009344010B28
+:1055E0008F4C002C974A09083C0B000E034B4021BE
+:1055F0003149FFFF000919C08F8B0050AF43002CC9
+:10560000974309089506001A00403821308A004067
+:1056100030DFFFFFAC5F00008D19001C0040482107
+:10562000AC5900048D180020AC580008910F0019E7
+:1056300031E30003107300F0000000002862000254
+:105640001440010924050002106500FD240D00032B
+:10565000106D010D00000000114000D90000000095
+:105660003C0A0800954A3D8625420001934D0934C5
+:1056700093580921950E002A31A300FF00032082D0
+:10568000331F00FF9798005800047E00001FCC00D5
+:1056900001F940253049FFFF0109102501D83021CB
+:1056A0003C0540000045502500066C00ACED0004B0
+:1056B000ACEA0000934309203C04000624ED0014EA
+:1056C0000003FE0003E4C825ACF900088F49092C4B
+:1056D000270F000131EE7FFFACE9000C8F48093045
+:1056E000A78E005824E90028ACE800108F4509383F
+:1056F00001204021ACE50014ADAB00048F4209400D
+:10570000ADA20008934B09373C1F080093FF3D9062
+:105710008F4309488F4A0940316600FF00D4202199
+:10572000006A78230004C700001FCC000319282555
+:1057300031EEFFFC00AE1025ADA2000CADA00010B4
+:10574000AF4C002C934C093E318B00085160000F88
+:105750008E58000C3C06010134CA080AACEA002845
+:105760008F4B0074AD2B00043C0C0800918C3D90D5
+:105770003187001050E00003AD2000088F62006008
+:10578000AD2200082528000C8E58000C0300F809F3
+:10579000010020213C19080097393D8A3C1F080070
+:1057A00097FF3D7E033F782125E900020E0000C7E8
+:1057B0003124FFFF3C0E08008DCE3D6C3C080800F4
+:1057C0008D083D7401C828233C010800AC253D6CC0
+:1057D00014A00006000000003C0308008C633D8C10
+:1057E000346400403C010800AC243D8C1200007081
+:1057F0008F8C00448F470E108F900044AE0700201E
+:105800008F4D0E18AE0D00243C10080096103D8000
+:105810000E0000600000000024020040AF420814A7
+:105820008F8600508F8A004C00D01821006A5823C0
+:1058300019600004AF830050AF6300548F650054BB
+:10584000AF85004C1200000C000000008F44007473
+:10585000936800813409FA002D0E000711C000057D
+:1058600000891821937F0081241901F403F9780439
+:1058700001E41821AF63000C8F44095C8F83005C46
+:105880000083C0231B000003000000008F50095C50
+:10589000AF90005C0E000062000000008F8C005092
+:1058A0008E4700103C010800AC2C3D9400E0F80944
+:1058B000000000003C0D08008DAD3D6C55A0FEF5CC
+:1058C000240700068F450024975909088F8B006430
+:1058D0008F9400503C0F001F978200588F86005411
+:1058E0008F93004C3328FFFF35E9FF8000A9502437
+:1058F000000871C032320100AF4E0024A4C2002C57
+:10590000AF4A0024AF6B0044AF740050AF73005433
+:105910001640008032380010570000868EA4000424
+:10592000322300405460001B8EB100088EB0000C82
+:105930000200F809000000008FBF00308FB5002C76
+:105940008FB400288FB300248FB200208FB1001CC9
+:105950008FB0001803E0000827BD00389347010905
+:105960008F8800380007FE0003E8C825AF59008083
+:105970008F5809A08F5309A4AFB80010AF580E1468
+:105980008FB40010AF540E10AF530E1C0A00096202
+:10599000AF530E180220F809000000008EB0000C72
+:1059A0000200F809000000000A000AA88FBF0030BA
+:1059B000A5800020A59300220A000A5BAD93002475
+:1059C0003C09080095293D863C06080094C63D80A8
+:1059D0000A0009F4012610213C010800AC203D70AA
+:1059E0000A00098E8E4200003C010800AC243D7084
+:1059F0000A00098E8E4200003C03080094633D8A31
+:105A00003C04080094843D803C1F080097FF3D7CC7
+:105A1000951800240064C821033F782300186C0007
+:105A200025EEFFF201AE2825AC45000C240208004B
+:105A3000ACE20014ACE000100A0009EF24E7001803
+:105A400095060024950900280006240000091C0082
+:105A5000349F810034790800ACFF000CACF90010D1
+:105A60000A0009EF24E700141460FEFB00000000A8
+:105A70009518002400187C0035EE0800ACEE000CF0
+:105A80000A0009EF24E700103C07080094E73D8076
+:105A90003C04080094843D8A3C03080094633D7CE8
+:105AA00095190024951800280087F82103E378232E
+:105AB0002407080000192C0000186C0025EEFFEEEA
+:105AC00001AE302534A28100AD2700182527001C27
+:105AD000AD22000CAD2600100A0009EFAD20001425
+:105AE00093520109000028210E000602324400FFF3
+:105AF0008FBF00308FB5002C8FB400288FB30024E7
+:105B00008FB200208FB1001C8FB0001803E0000896
+:105B100027BD0038935F010933E400FF0E00066DD6
+:105B200000002821323800105300FF7E322300404D
+:105B30008EA400040080F809000000000A000AA2F8
+:105B4000322300401200FF5F000000008F540E144B
+:105B50008F920044AE5400208F530E1C0A000A8A14
+:105B6000AE5300248F82001C008040213C040100C1
+:105B70009047008530E3002010600009000000001D
+:105B80003C0708008CE73D948F83001800E3202336
+:105B9000048000089389000414E30003010020211D
+:105BA00003E00008008010213C04010003E000082D
+:105BB000008010211120000B006738238F8C0020FB
+:105BC00024090034918B00BC316A0002514000016D
+:105BD0002409003000E9682B15A0FFF10100202105
+:105BE00000E938232419FFFC00B9C02400F9782407
+:105BF00000F8702B15C0FFEA01E8202130C2000335
+:105C00000002182314C00012306900030000302184
+:105C100000A9702101C6682100ED602B1180FFE012
+:105C20003C0401002D2F00010006482B01053821FE
+:105C300001E9302414C0FFDA24E4FFFC2419FFFC3E
+:105C400000B9C0240308202103E0000800801021CF
+:105C50008F8B002024060004916A00BC31440004AC
+:105C60001480FFEC00A970210A000B5E00003021B7
+:105C700027BDFFE8AFBF00108F460100934A01091E
+:105C80003C1F08008FFF00902407FF80314F00FF6A
+:105C900031E8007F0008614003E6C821032CC021E1
+:105CA00027090120012770243C010800A02F3DD0C6
+:105CB000AF4E080C3C0D08008DAD00903C040080F8
+:105CC0003482000301A65821016C182124650120AB
+:105CD00030AA007801424025AF48081C3C1F08004C
+:105CE0008FFF00908F88004003E6C0213319000722
+:105CF00003074824033A7821AF49002825E909C061
+:105D0000952E00023C0D08008DAD008C3C0A080069
+:105D10008D4A009031CC3FFF01A61821000C59801C
+:105D2000006B282100A72024AF44002C95220002FC
+:105D30003C1F08008FFF008C9107008530593FFF02
+:105D400003E678210019C1800146702101F868211D
+:105D500031CC007F31AB007F019A2821017A50219C
+:105D60003C03000C3C04000E00A328210144102138
+:105D700030E6002027470980AF82002CAF88001C46
+:105D8000AF890024AF85002010C00006AF8700282F
+:105D90008D0200508CA4010C0044302318C0007701
+:105DA00000000000910C0085240DFFDF018D3824D8
+:105DB000A10700858F8B001C8F8900248F87002806
+:105DC0008D65004CAF850018912F000D31EE00203D
+:105DD00011C000170000000024090001A38900047D
+:105DE000AF80000C8CE400248F85000C240A00088E
+:105DF000AF800008AF8000103C010800A42A3D7E5F
+:105E00003C010800A4203D920E000B32000030211E
+:105E10008F8500248FBF0010AF82001490A8000D62
+:105E200027BD00180008394203E0000830E20001F5
+:105E3000913F00022418000133F900FF001921826C
+:105E400010980039240800021088005B8F86002C0F
+:105E50008CE5002414A0001B8F9F002091220000DD
+:105E6000240A00053046003F10CA00472404000100
+:105E70008F860008A3840004AF860010AF86000C54
+:105E80008CE400248F85000C240A00083C010800E3
+:105E9000A42A3D7E3C010800A4203D920E000B3256
+:105EA000000000008F8500248FBF0010AF82001417
+:105EB00090A8000D27BD00180008394203E0000833
+:105EC00030E200018CF800088CF900248FEE00C449
+:105ED000A38000048CE40024AF8E000C8F85000C9E
+:105EE0008F86000803197823240A0008AF8F00105A
+:105EF0003C010800A42A3D7E3C010800A4203D92FC
+:105F00000E000B32000000008F8500248FBF0010B0
+:105F1000AF82001490A8000D27BD00180008394278
+:105F200003E0000830E20001912300003062003FEE
+:105F3000104400278F8500208CE400241480002169
+:105F4000000000008D2E00183C187FFF8F85002078
+:105F5000370FFFFF01CF1824AF8300088F9F000881
+:105F60008CA8008403E8C82B1720000203E020213E
+:105F70008CA400840A000BEDAF8400088CA3010CF4
+:105F80000A000BCBAF8300188D2C00188F860008F9
+:105F90003C0D7FFF8F89002035A3FFFF018358242C
+:105FA00024040001AF8B0010AD2000CCA3840004BA
+:105FB0000A000BF9AF86000C8CCA00140A000BED26
+:105FC000AF8A00088CA300C80A000C30AF83000819
+:105FD0008F84002C8CAC00648C8D0014018D582BA8
+:105FE00011600004000000008CA200640A000C3064
+:105FF000AF8200088C8200140A000C30AF820008C7
+:106000008F85000C27BDFFE0AFBF0018AFB10014B3
+:1060100014A00007AFB000108F86002424020005F2
+:1060200090C400003083003F106200B68F840020CF
+:106030008F91000800A080218F8C00283C0508006B
+:106040008CA53D708D8B000431663FFF00C5502B41
+:106050005540000100C02821938D000411A0007359
+:1060600000B0F82B8F98002024040034930F00BC5C
+:1060700031EE000251C000012404003000A4C82BFE
+:10608000172000D10000000000A4282300B0F82B46
+:106090003C010800A4243D7C17E000680200202198
+:1060A0003C0308008C633D6C0083102B54400001BE
+:1060B000008018218F8800243C010800AC233D7427
+:1060C000000048219104000D308300205060000141
+:1060D0008F490E188F8300140123382B10E00059CC
+:1060E000000000003C0408008C843D7400895821A5
+:1060F000006B502B114000560090602B006930233C
+:1061000000C020213C010800AC263D7412000003B1
+:10611000241FFFFC1090008A32270003009FC82430
+:106120003C010800AC393D743C010800A4203D92BC
+:106130008F84000C120400078F830020AF910008A9
+:10614000020020218C7100CCAF90000C26300001A1
+:10615000AC7000CC3C0208008C423D748F8A001069
+:10616000240700180082202301422823AF84000C5A
+:1061700010800002AF850010240700108F86001CDD
+:106180003C010800A0273D902407004090CC0085EA
+:10619000318B00C0116700408F8D001414A00015D2
+:1061A00000002021934A01098F420974314500FF04
+:1061B0000002260224A300013090007F3071007F8E
+:1061C0001230007A2407FF80A0C300833C09080036
+:1061D0008D293D8C8F880024240D0002352C000869
+:1061E0003C010800A02D3DD13C010800AC2C3D8CA9
+:1061F00024040010910E000D31C6002010C00005CF
+:1062000000801821240800013C010800AC283D74DE
+:10621000348300018FBF00188FB100148FB00010BD
+:106220000060102103E0000827BD00203C010800A9
+:10623000A4203D7C13E0FF9A020020210A000C817B
+:1062400000A020213C0408008C843D740090602B49
+:106250001180FFAE000000003C0F080095EF3D7C70
+:1062600001E4702101C6682B11A000072C820004F4
+:106270003C1F60008FF954043338003F1700FFE5DE
+:10628000240300422C8200041040FFA0240300429B
+:106290000A000CDF8FBF0018152DFFC000000000A2
+:1062A0008CDF00743C0380002405FF8003E3C825D5
+:1062B000ACD9007490D80085240E0004240400108A
+:1062C000330F003F01E54025A0C800858F880024DA
+:1062D0003C010800A02E3DD1240300019106000DD1
+:1062E00030C9002015200003000000003C03080016
+:1062F0008C633D743C010800AC233D6C0A000CD655
+:10630000000000008F8700108C88008400E8282B94
+:1063100014A0000200E088218C910084240900016F
+:10632000A38900048F440E18022028210E000B328E
+:1063300002203021022080210A000C67AF82001465
+:1063400000071823306600033C010800A4263D9294
+:10635000122000058F8C0020918B00BC316A000454
+:106360001540001524CD00043C0F080095EF3D9228
+:1063700001E4702100AE302B50C0FF6E8F84000C02
+:106380002C85000514A0FFA32403004230980003CD
+:1063900017000002009818232483FFFC3C0108002A
+:1063A000AC233D740A000CA30000000000A7582491
+:1063B0000A000CCB016718263C010800A42D3D9271
+:1063C0000A000D33000000003C010800AC203D74C1
+:1063D0000A000CDE240300428F83001014600007C3
+:1063E000000010218F88002424050005910600007C
+:1063F00030C400FF108500030000000003E0000827
+:1064000000000000910A0018314900FF000939C25C
+:1064100014E0FFFA8F85001C3C04080094843D7C46
+:106420003C0308008C633D943C1908008F393D748F
+:106430003C0F080095EF3D920064C0218CAD0054E4
+:106440000319702101CF6021018D58231960001DAF
+:1064500000000000910E001C8F8C002C974B0E103A
+:1064600031CD00FF8D850004016D30238D88000043
+:1064700030CEFFFF000E510000AAC82100003821D5
+:1064800001072021032A182B0083C021AD990004A5
+:10649000AD980000918F000A01CF6821A18D000AFC
+:1064A0008F88002C974B0E12A50B0008950A003818
+:1064B00025490001A50900389107000D34E60008C0
+:1064C000A106000D03E000080000000027BDFFE06A
+:1064D000938700048F8F00248FAD00143C0E7FFF44
+:1064E0008F89000C35C8FFFFAFBF001CAFB000188C
+:1064F00001A8182491EA000D000717C03C1FBFFF38
+:10650000006258252D2E00018F90001837F9FFFFEB
+:106510003C1808008F183D943C0F080095EF3D8A09
+:1065200001796824000E47803C07EFFF3C05F0FF2F
+:1065300001A818253149002034E2FFFF34ACFFFFE9
+:106540000310582327A500102406000225EA0002A4
+:1065500000621824008080211520000200004021E4
+:106560008F480E1CA7AA0012056000372407000000
+:1065700030FF00FF001FCF008F8B001C00793825F3
+:10658000AFA70014916F00853C08080091083D9169
+:106590003C18DFFF31EE00C0370AFFFF000E182B5A
+:1065A0003C1F080097FF3D8400EA6824A3A800115F
+:1065B0000003174001A248258FB90010AFA90014AD
+:1065C0003C0A0800914A3D93A7BF00168FA800140B
+:1065D000032CC0243C0B01003C0F0FFF030B1825BC
+:1065E0003147000335EEFFFF010C68240007160059
+:1065F000006EF8243C09700001A2C82503E9582563
+:10660000AFB90014AFAB00100E000076A3A00015C8
+:106610008F8C0024260200089186000D30C40020D3
+:10662000108000068FBF001C3C05080094A53D802B
+:1066300024B0FFFF3C010800A4303D808FB000185B
+:1066400003E0000827BD00208F9800140118502B8C
+:106650005540FFC7240700010A000DB630FF00FFB8
+:106660009382000427BDFFE0AFBF00181040000F69
+:10667000008050218F880024240B00058F8900089A
+:10668000910700008F8400200100282130E3003FA3
+:106690008F86002C106B000800003821AFA9001075
+:1066A0000E00040EAFAA0014A38000048FBF0018D0
+:1066B00003E0000827BD00208D1900183C0F0800DA
+:1066C0008DEF3D748F9800103C027FFF8D08001401
+:1066D000345FFFFF033F682401F8702101AE60239F
+:1066E00001883821AFA900100E00040EAFAA0014D3
+:1066F0000A000E04A38000048F8700243C050800D4
+:1067000094A53D923C0208008C423D8C90E6000D21
+:106710000005240030C300201060002C00444025F8
+:106720008F85001C00006021240B000190A30085D0
+:1067300000004821240A00013C0F800035EE007063
+:106740008DC70000AF8700308F5801780700FFFE2B
+:106750003C038000347900708F3800003C0508004D
+:106760008CA500743C0D08008DAD007003077823E4
+:1067700000AF38210000102100EF302B01A22021B2
+:10678000008618213C010800AC2700743C01080079
+:10679000AC230070AF4B01483C1908008F393D9481
+:1067A000A7490144A74A0146AF59014C3C0B0800D8
+:1067B000916B3D91A34B0152AF4801543C0810002E
+:1067C000A74C015803E00008AF4801788F4B0E1C1E
+:1067D0003C0A08008D4A3D7497490E16974D0E14D9
+:1067E00001456021312AFFFF0A000E2731A9FFFF72
+:1067F0008F8300249064000D308200201040002917
+:10680000000000000000482100005021000040214D
+:106810003C07800034EB00708D670000AF870030CC
+:106820008F4C01780580FFFE3C0D800035AC007078
+:106830008D8B00003C0508008CA500743C0408000A
+:106840008C8400700167302300A67821000010219D
+:1068500001E6C82B0082C021031970213C01080009
+:10686000AC2F00743C010800AC2E0070AF49014809
+:106870003C0D08008DAD3D94A7480144240900401B
+:10688000A74A01463C081000240AFF91AF4D014C75
+:10689000A34A0152AF490154A740015803E0000840
+:1068A000AF4801788F490E1897460E1297450E1083
+:1068B00030CAFFFF0A000E5D30A8FFFF8F8300245F
+:1068C00027BDFFF89064000D308200201040003A90
+:1068D00000000000240B000100004821240A0001F0
+:1068E0003C088000350700708CE30000AF83003067
+:1068F0008F4C01780580FFFE3C0E80003C040800B0
+:1069000090843DD035C700708CEC00003C05080039
+:106910008CA50074A3A400033C1908008F390070F3
+:106920008FAD00000183302300A638210000102124
+:106930000322782100E6C02B01F8602101AE40253A
+:10694000AFA800003C010800AC2700743C0108001F
+:10695000AC2C00709346010A3C04080090843DD1A1
+:10696000A3A00002A3A600018FA300003C0580FFA6
+:106970003099007F34A2FFFF006278240019C6001E
+:1069800001F87025240D3000AF4E014C27BD0008E2
+:10699000AF4D0154A7400158AF4B0148A7490144EE
+:1069A000A74A01463C091000240AFF80A34A01526D
+:1069B00003E00008AF4901788F4B0E1897460E127E
+:1069C00097450E1030CAFFFF0A000E9130A9FFFF55
+:1069D0008F85001C2402008090A40085308300C0B5
+:1069E000106200058F8600208F8800088F87000CBA
+:1069F000ACC800C8ACC700C403E000080000000039
+:106A00003C0A0800254A39543C09080025293A2047
+:106A10003C08080025082DD43C07080024E73B3437
+:106A20003C06080024C637C43C05080024A5353CB4
+:106A30003C040800248431643C0308002463385C6F
+:106A40003C020800244236303C010800AC2A3D508C
+:106A50003C010800AC293D4C3C010800AC283D48F5
+:106A60003C010800AC273D543C010800AC263D64C5
+:106A70003C010800AC253D5C3C010800AC243D58BD
+:106A80003C010800AC233D683C010800AC223D609D
+:086A900003E000080000000013
+:00000001FF
--- zfcpdump-kernel-4.4.orig/firmware/bnx2/bnx2-mips-09-6.2.1a.fw.ihex
+++ /dev/null
@@ -1,6512 +0,0 @@
-:10000000080001180800000000005594000000C816
-:1000100000000000000000000000000008005594EF
-:10002000000000380000565C080000A00800000036
-:100030000000574400005694080059200000008436
-:100040000000ADD808005744000001C00000AE5CBD
-:100050000800321008000000000092340000B01CBC
-:1000600000000000000000000000000008009234C2
-:100070000000033C00014250080004900800040006
-:10008000000012FC0001458C000000000000000090
-:1000900000000000080016FC000000040001588861
-:1000A000080000A80800000000003D000001588C76
-:1000B00000000000000000000000000008003D00FB
-:0800C000000000300001958CE6
-:0800C8000A00004600000000E0
-:1000D000000000000000000D636F6D362E322E31DF
-:1000E00061000000060201020000000000000003A1
-:1000F000000000C800000032000000030000000003
-:1001000000000000000000000000000000000000EF
-:1001100000000010000001360000EA600000000549
-:1001200000000000000000000000000000000008C7
-:1001300000000000000000000000000000000000BF
-:1001400000000000000000000000000000000000AF
-:10015000000000000000000000000000000000009F
-:10016000000000020000000000000000000000008D
-:10017000000000000000000000000000000000007F
-:10018000000000000000000000000010000000005F
-:10019000000000000000000000000000000000005F
-:1001A000000000000000000000000000000000004F
-:1001B000000000000000000000000000000000003F
-:1001C000000000000000000000000000000000002F
-:1001D000000000000000000000000000000000001F
-:1001E0000000000010000003000000000000000DEF
-:1001F0000000000D3C020800244256083C030800A1
-:1002000024635754AC4000000043202B1480FFFDB2
-:10021000244200043C1D080037BD9FFC03A0F021D0
-:100220003C100800261001183C1C0800279C5608AA
-:100230000E000256000000000000000D27BDFFB4B4
-:10024000AFA10000AFA20004AFA30008AFA4000C50
-:10025000AFA50010AFA60014AFA70018AFA8001CF0
-:10026000AFA90020AFAA0024AFAB0028AFAC002C90
-:10027000AFAD0030AFAE0034AFAF0038AFB8003C28
-:10028000AFB90040AFBC0044AFBF00480E001544FA
-:10029000000000008FBF00488FBC00448FB90040B1
-:1002A0008FB8003C8FAF00388FAE00348FAD003078
-:1002B0008FAC002C8FAB00288FAA00248FA90020C0
-:1002C0008FA8001C8FA700188FA600148FA5001000
-:1002D0008FA4000C8FA300088FA200048FA1000040
-:1002E00027BD004C3C1B60108F7A5030377B502864
-:1002F00003400008AF7A00008F82002427BDFFE092
-:10030000AFB00010AFBF0018AFB100148C42000CAA
-:100310003C1080008E110100104000348FBF001887
-:100320000E000D84000000008F85002024047FFF54
-:100330000091202BACB100008E030104960201084D
-:1003400000031C003042FFFF00621825ACA300042C
-:100350009202010A96030114304200FF3063FFFF4E
-:100360000002140000431025ACA200089603010C03
-:100370009602010E00031C003042FFFF00621825A8
-:10038000ACA3000C960301109602011200031C009E
-:100390003042FFFF00621825ACA300108E02011846
-:1003A000ACA200148E02011CACA20018148000083C
-:1003B0008F820024978200003C0420050044182509
-:1003C00024420001ACA3001C0A0000C6A782000062
-:1003D0003C0340189442001E00431025ACA2001CB0
-:1003E0000E000DB8240400018FBF00188FB1001457
-:1003F0008FB000100000102103E0000827BD00208E
-:100400003C0780008CE202B834E50100044100089A
-:10041000240300013C0208008C42006024420001D9
-:100420003C010800AC22006003E0000800601021DD
-:100430003C0208008C42005C8CA4002094A30016AF
-:100440008CA6000494A5000E24420001ACE40280B6
-:100450002463FFFC3C010800AC22005C3C0210005D
-:10046000A4E30284A4E5028600001821ACE6028819
-:10047000ACE202B803E000080060102127BDFFE0F5
-:100480003C028000AFB0001034420100AFBF001C3E
-:10049000AFB20018AFB100148C43000094450008BF
-:1004A0002462FE002C42038110400003000381C23D
-:1004B0000A00010226100004240201001462000553
-:1004C0003C1180003C02800890420004305000FF44
-:1004D0003C11800036320100964300143202000FB6
-:1004E00000021500004310253C0308008C63004403
-:1004F00030A40004AE220080246300013C01080007
-:10050000AC2300441080000730A200028FBF001C03
-:100510008FB200188FB100148FB000100A0000CE07
-:1005200027BD00201040002D0000182130A20080BF
-:1005300010400005362200708E44001C0E000C672F
-:10054000240500A0362200708C4400008F82000C2D
-:10055000008210232C43012C10600004AF82001095
-:10056000240300010A000145AF84000C8E42000400
-:100570003C036020AF84000CAC6200143C02080015
-:100580008C42005850400015000018218C62000475
-:10059000240301FE304203FF144300100000182121
-:1005A0002E020004104000032E0200080A00014041
-:1005B0000000802114400003000000000A000140F8
-:1005C0002610FFF90000000D2402000202021004B0
-:1005D0003C036000AC626914000018218FBF001C4E
-:1005E0008FB200188FB100148FB00010006010217E
-:1005F00003E0000827BD00203C0480008C8301003C
-:1006000024020100506200033C0280080000000D3B
-:100610003C02800890430004000010213063000F6A
-:1006200000031D0003E00008AC8300800004188074
-:100630002782FF9C00621821000410C00044102390
-:100640008C640000000210C03C030800246356E4E0
-:10065000004310213C038000AC64009003E00008DC
-:10066000AF8200243C0208008C42011410400019A3
-:100670003084400030A2007F000231C03C02020002
-:100680001080001400A218253C026020AC43001426
-:100690003C0408008C8456B83C0308008C630110AD
-:1006A0003C02800024050900AC4500200086202182
-:1006B000246300013C028008AC4400643C01080053
-:1006C000AC2301103C010800AC2456B803E000083C
-:1006D000000000003C02602003E00008AC4500146C
-:1006E00003E000080000102103E0000800001021D2
-:1006F00030A2000810400008240201003C0208005B
-:100700008C42010C244200013C010800AC22010C87
-:1007100003E0000800000000148200080000000050
-:100720003C0208008C4200FC244200013C0108000D
-:10073000AC2200FC0A0001A330A200203C02080009
-:100740008C420084244200013C010800AC22008459
-:1007500030A200201040000830A200103C02080027
-:100760008C420108244200013C010800AC2201082F
-:1007700003E0000800000000104000080000000036
-:100780003C0208008C420104244200013C010800A4
-:10079000AC22010403E00008000000003C02080055
-:1007A0008C420100244200013C010800AC220100FF
-:1007B00003E000080000000027BDFFE0AFB1001417
-:1007C0003C118000AFB20018AFBF001CAFB00010EA
-:1007D0003632010096500008320200041040000733
-:1007E000320300028FBF001C8FB200188FB10014BB
-:1007F0008FB000100A0000CE27BD00201060000B53
-:10080000020028218E2401000E00018A0000000051
-:100810003202008010400003240500A10E000C6786
-:100820008E44001C0A0001E3240200018E2301040F
-:100830008F82000810430006020028218E24010048
-:100840000E00018A000000008E220104AF82000821
-:10085000000010218FBF001C8FB200188FB1001450
-:100860008FB0001003E0000827BD00202C82000498
-:1008700014400002000018212483FFFD240200021E
-:10088000006210043C03600003E00008AC626914DD
-:1008900027BDFFE0AFBF001CAFB20018AFB100141E
-:1008A000AFB000103C048000948201083043700017
-:1008B000240220001062000A2862200154400052E5
-:1008C0008FBF001C24024000106200482402600018
-:1008D0001062004A8FBF001C0A0002518FB200183C
-:1008E00034820100904300098C5000189451000C90
-:1008F000240200091062001C0000902128620009F7
-:10090000144000218F8200242402000A5062001249
-:10091000323100FF2402000B1062000F00000000C3
-:100920002402000C146200188F8200243C0208008C
-:100930008C4256B824030900AC83002000501021DB
-:100940003C038008AC6200643C010800AC2256B84D
-:100950000A0002508FBF001C0E0001E900102602A1
-:100960000A0002308F8200240E0001E900102602E6
-:100970003C0380089462001A8C72000C3042FFFF26
-:10098000020280258F8200248C42000C5040001E01
-:100990008FBF001C0E000D84000000003C02800090
-:1009A00034420100944300088F82002400031C009D
-:1009B0009444001E8F82002000641825AC50000073
-:1009C00024040001AC510004AC520008AC40000CFF
-:1009D000AC400010AC400014AC4000180E000DB844
-:1009E000AC43001C0A0002508FBF001C0E000440E4
-:1009F000000000000A0002508FBF001C0E000C9F78
-:100A0000000000008FBF001C8FB200188FB10014CF
-:100A10008FB000100000102103E0000827BD002067
-:100A200027BDFFD8AFB400203C036010AFBF002447
-:100A3000AFB3001CAFB20018AFB10014AFB00010DC
-:100A40008C6450002402FF7F3C1408002694563822
-:100A5000008220243484380CAC6450003C028000B6
-:100A6000240300370E0014B0AC4300083C07080014
-:100A700024E70618028010212404001D2484FFFFAF
-:100A8000AC4700000481FFFD244200043C02080042
-:100A9000244207C83C010800AC2256403C02080032
-:100AA000244202303C030800246306203C04080072
-:100AB000248403B43C05080024A506F03C06080085
-:100AC00024C62C9C3C010800AC2256803C02080045
-:100AD000244205303C010800AC2756843C01080044
-:100AE000AC2656943C010800AC23569C3C010800FF
-:100AF000AC2456A03C010800AC2556A43C010800DB
-:100B0000AC2256A83C010800AC23563C3C0108002E
-:100B1000AC2456443C010800AC2056603C0108005F
-:100B2000AC2556643C010800AC2056703C0108001E
-:100B3000AC27567C3C010800AC2656903C010800CE
-:100B4000AC2356980E00056E00000000AF80000C2C
-:100B50003C0280008C5300008F8300043C0208009C
-:100B60008C420020106200213262000700008821C0
-:100B70002792FF9C3C100800261056E43C02080017
-:100B80008C42002024050001022518040043202483
-:100B90008F820004004310245044000C26310001D1
-:100BA00010800008AF9000248E4300003C028000BB
-:100BB000AC4300900E000D4BAE05000C0A0002C1C4
-:100BC00026310001AE00000C263100012E22000269
-:100BD000261000381440FFE9265200043C020800A9
-:100BE0008C420020AF820004326200071040FFD91F
-:100BF0003C028000326200011040002D326200028F
-:100C00003C0580008CA2010000002021ACA2002045
-:100C10008CA301042C42078110400008ACA300A85B
-:100C200094A2010824032000304270001443000302
-:100C30003C02800890420005304400FF0E0001593C
-:100C4000000000003C0280009042010B304300FF96
-:100C50002C62001E54400004000310800E00018628
-:100C60000A0002EC00000000005410218C42000039
-:100C70000040F80900000000104000043C02800021
-:100C80008C4301043C026020AC4300143C02080089
-:100C90008C4200343C0440003C03800024420001AC
-:100CA000AC6401383C010800AC220034326200021E
-:100CB00010400010326200043C1080008E0201409F
-:100CC000000020210E000159AE0200200E00038317
-:100CD000000000003C024000AE0201783C02080027
-:100CE0008C420038244200013C010800AC2200384C
-:100CF000326200041040FF973C0280003C108000EC
-:100D00008E020180000020210E000159AE02002059
-:100D10008E03018024020F00546200073C02800809
-:100D20008E0201883C0300E03042FFFF00431025A3
-:100D30000A000328AE020080344200809042000086
-:100D400024030050304200FF14430007000000005D
-:100D50000E000362000000001440000300000000C9
-:100D60000E000971000000003C0208008C42003CAB
-:100D70003C0440003C03800024420001AC6401B804
-:100D80003C010800AC22003C0A0002A33C028000A7
-:100D90003C02900034420001008220253C02800089
-:100DA000AC4400203C0380008C6200200440FFFE25
-:100DB0000000000003E00008000000003C0280008A
-:100DC000344300010083202503E00008AC440020E8
-:100DD00027BDFFE0AFB10014AFB000100080882144
-:100DE000AFBF00180E00033230B000FF8F83FF94B6
-:100DF000022020219062002502028025A07000259B
-:100E00008C7000183C0280000E00033D020280241A
-:100E10001600000B8FBF00183C0480008C8201F884
-:100E20000440FFFE348201C024030002AC510000E4
-:100E3000A04300043C021000AC8201F88FBF0018F0
-:100E40008FB100148FB0001003E0000827BD002010
-:100E500027BDFFE83C028000AFBF00103442018094
-:100E6000944300048C4400083063020010600005C5
-:100E7000000028210E00100C000000000A0003787A
-:100E8000240500013C02FF000480000700821824B2
-:100E90003C02040014620004240500018F82FF94C8
-:100EA00090420008240500018FBF001000A010210F
-:100EB00003E0000827BD00188F82FF982405000179
-:100EC000A040001A3C028000344201400A00034264
-:100ED0008C4400008F85FF9427BDFFE0AFBF001C4E
-:100EE000AFB20018AFB10014AFB0001090A2000074
-:100EF000304400FF38830020388200300003182B74
-:100F00000002102B0062182410600003240200501D
-:100F1000148200A88FBF001C90A20005304200017F
-:100F2000104000A48FBF001C3C02800034420140EE
-:100F3000904200082443FFFF2C6200051040009EF1
-:100F40008FB20018000310803C030800246355ACE6
-:100F5000004310218C420000004000080000000007
-:100F60003C028000345101400E0003328E24000008
-:100F70008F92FF948E2200048E50000C1602000205
-:100F800024020001AE42000C0E00033D8E2400003E
-:100F90008E220004145000068FBF001C8FB2001870
-:100FA0008FB100148FB000100A000F7827BD002009
-:100FB0008E42000C0A000419000000003C0480006E
-:100FC0003482014094A300108C4200043063FFFF80
-:100FD0001443001C0000000024020001A4A2001021
-:100FE0008C8202380441000F3C0380003C02003F29
-:100FF0003448F0003C0760003C06FFC08CE22BBC8C
-:1010000000461824004810240002130200031D8229
-:10101000106200583C0280008C8202380440FFF7C6
-:101020003C038000346201408C44000034620200C2
-:10103000AC4400003C021000AC6202380A00043BE1
-:101040008FBF001C94A200100A00041900000000C9
-:10105000240200201482000F3C0280003C03800028
-:1010600094A20012346301408C6300043042FFFFFD
-:10107000146200050000000024020001A4A2001276
-:101080000A0004028FBF001C94A200120A00041977
-:1010900000000000345101400E0003328E24000095
-:1010A0008F92FF948E230004964200123050FFFF6F
-:1010B0001603000224020001A64200120E00033DA6
-:1010C0008E2400008E220004160200068FBF001C32
-:1010D0008FB200188FB100148FB000100A00037C8B
-:1010E00027BD0020964200120A00041900000000EB
-:1010F0003C03800094A20014346301408C6300041C
-:101100003042FFFF14620008240200018FBF001C60
-:101110008FB200188FB100148FB00010A4A2001479
-:101120000A00146327BD002094A20014144000217B
-:101130008FBF001C0A000435000000003C03800043
-:1011400094A20016346301408C6300043042FFFF18
-:101150001462000D240200018FBF001C8FB2001822
-:101160008FB100148FB00010A4A200160A000B1457
-:1011700027BD00209442007824420004A4A200105D
-:101180000A00043B8FBF001C94A200162403000138
-:101190003042FFFF144300078FBF001C3C020800D1
-:1011A0008C420070244200013C010800AC22007017
-:1011B0008FBF001C8FB200188FB100148FB00010C9
-:1011C00003E0000827BD002027BDFFD8AFB20018FC
-:1011D0008F92FF94AFB10014AFBF0020AFB3001CDB
-:1011E000AFB000103C028000345101008C5001006F
-:1011F0009242000092230009304400FF2402001FA5
-:10120000106200AB28620020104000192402003850
-:101210002862000A1040000D2402000B286200081A
-:101220001040002E8F820024046001042862000216
-:101230001440002A8F820024240200061062002637
-:101240008FBF00200A00055F8FB3001C1062006092
-:101250002862000B144000FA8FBF00202402000E09
-:10126000106200788F8200240A00055F8FB3001C93
-:10127000106200D2286200391040000A2402008067
-:1012800024020036106200E528620037104000C3D7
-:1012900024020035106200D98FBF00200A00055FCC
-:1012A0008FB3001C1062002D2862008110400006E0
-:1012B000240200C824020039106200C98FBF002038
-:1012C0000A00055F8FB3001C106200A28FBF0020D0
-:1012D0000A00055F8FB3001C8F8200248C42000C33
-:1012E000104000D78FBF00200E000D8400000000CA
-:1012F0003C038000346301008C6200008F85002075
-:10130000946700089466000CACA200008C64000492
-:101310008F82002400063400ACA400049448001E10
-:101320008C62001800073C0000E83825ACA20008D9
-:101330008C62001C24040001ACA2000C9062000A24
-:1013400000C23025ACA60010ACA00014ACA0001860
-:10135000ACA7001C0A00051D8FBF00208F8200244F
-:101360008C42000C104000B68FBF00200E000D8490
-:10137000000000008F820024962400089625000CAF
-:101380009443001E000422029626000E8F82002045
-:10139000000426000083202500052C003C0300806B
-:1013A00000A6282500832025AC400000AC400004A6
-:1013B000AC400008AC40000CAC450010AC40001440
-:1013C000AC400018AC44001C0A00051C24040001B9
-:1013D0009622000C14400018000000009242000504
-:1013E0003042001014400014000000000E000332D0
-:1013F0000200202192420005020020213442001008
-:101400000E00033DA242000592420000240300208A
-:10141000304200FF10430089020020218FBF0020CE
-:101420008FB3001C8FB200188FB100148FB0001062
-:101430000A00107527BD00280000000D0A00055E97
-:101440008FBF00208C42000C1040007D8FBF002019
-:101450000E000D84000000008E2200048F84002006
-:101460009623000CAC8200003C0280089445002CBE
-:101470008F82002400031C0030A5FFFF9446001E4D
-:101480003C02400E0065182500C23025AC830004E4
-:10149000AC800008AC80000CAC800010AC80001464
-:1014A000AC800018AC86001C0A00051C2404000156
-:1014B0000E000332020020218F93FF9802002021AA
-:1014C0000E00033DA660000C020020210E00034226
-:1014D000240500018F8200248C42000C104000582B
-:1014E0008FBF00200E000D84000000009622000C2B
-:1014F0008F83002000021400AC700000AC62000476
-:10150000AC6000088E4400388F820024AC64000C6C
-:101510008E46003C9445001E3C02401FAC66001005
-:1015200000A228258E62000424040001AC6200148D
-:10153000AC600018AC65001C8FBF00208FB3001C8E
-:101540008FB200188FB100148FB000100A000DB8D0
-:1015500027BD0028240200201082003A8FB3001C0F
-:101560000E000F5E00000000104000358FBF00200D
-:101570003C0480008C8201F80440FFFE348201C0EC
-:1015800024030002AC500000A04300043C02100001
-:10159000AC8201F80A00055E8FBF00200200202106
-:1015A0008FBF00208FB3001C8FB200188FB10014C2
-:1015B0008FB000100A000EA727BD00289625000C4A
-:1015C000020020218FBF00208FB3001C8FB20018B3
-:1015D0008FB100148FB000100A000ECC27BD002878
-:1015E000020020218FB3001C8FB200188FB10014AD
-:1015F0008FB000100A000EF727BD00289225000DBD
-:10160000020020218FB3001C8FB200188FB100148C
-:101610008FB000100A000F4827BD002802002021CB
-:101620008FBF00208FB3001C8FB200188FB1001441
-:101630008FB000100A000F1F27BD00288FBF0020A9
-:101640008FB3001C8FB200188FB100148FB0001040
-:1016500003E0000827BD00283C0580008CA202782A
-:101660000440FFFE34A2024024030002AC44000008
-:10167000A04300043C02100003E00008ACA2027882
-:10168000A380001803E00008A38000193C03800039
-:101690008C6202780440FFFE8F82001CAC62024024
-:1016A00024020002A06202443C02100003E0000891
-:1016B000AC6202783C02600003E000088C425404F3
-:1016C0009083003024020005008040213063003FF9
-:1016D0000000482114620005000050219082004C57
-:1016E0009483004E304900FF306AFFFFAD00000CCC
-:1016F000AD000010AD000024950200148D05001C03
-:101700008D0400183042FFFF004910230002110031
-:10171000000237C3004038210086202300A2102B8E
-:101720000082202300A72823AD05001CAD0400186B
-:10173000A5090014A5090020A50A001603E0000869
-:10174000A50A002203E000080000000027BDFFD822
-:10175000AFB200183C128008AFB40020AFB3001C39
-:10176000AFB10014AFBF0024AFB00010365101007C
-:101770003C0260008C4254049222000C3C1408008D
-:10178000929400F7304300FF2402000110620032FF
-:101790000080982124020002146200353650008037
-:1017A0000E00143D000000009202004C2403FF8054
-:1017B0003C0480003042007F000211C024420240FD
-:1017C0000262102100431824AC8300949245000863
-:1017D0009204004C3042007F3C03800614850007D1
-:1017E000004380212402FFFFA22200112402FFFFF8
-:1017F000A62200120A0005D22402FFFF9602002052
-:10180000A222001196020022A62200128E020024BB
-:101810003C048008AE2200143485008090A2004C65
-:1018200034830100A06200108CA2003CAC6200185E
-:101830008C820068AC6200F48C820064AC6200F0C0
-:101840008C82006CAC6200F824020001A0A2006847
-:101850000A0005EE3C0480080E001456000000004B
-:1018600036420080A04000680A0005EE3C04800873
-:10187000A2000068A20000690A0006293C02800854
-:10188000348300808C62003834850100AC62006CC7
-:1018900024020001A062006990A200D59083000894
-:1018A000305100FF3072007F12320019001111C058
-:1018B00024420240026210212403FF8000431824C6
-:1018C0003C048000AC8300943042007F3C038006DF
-:1018D000004380218E02000C1040000D02002021E8
-:1018E0000E00057E0000000026220001305100FF9E
-:1018F0009203003C023410260002102B0002102339
-:101900003063007F022288240A0005F8A203003C0D
-:101910003C088008350401008C8200E03507008017
-:10192000ACE2003C8C8200E0AD02000090E5004C8F
-:10193000908600D590E3004C908400D52402FF806F
-:1019400000A228243063007F308400FF00A62825F1
-:101950000064182A1060000230A500FF38A500803E
-:10196000A0E5004CA10500093C0280089043000E50
-:10197000344400803C058000A043000A8C8300189A
-:101980003C027FFF3442FFFF00621824AC83001842
-:101990008CA201F80440FFFE00000000ACB301C0BF
-:1019A0008FBF00248FB400208FB3001C8FB20018AB
-:1019B0008FB100148FB0001024020002A0A201C455
-:1019C00027BD00283C02100003E00008ACA201F88B
-:1019D00090A2000024420001A0A200003C030800E5
-:1019E0008C6300F4304200FF144300020080302179
-:1019F000A0A0000090A200008F84001C000211C073
-:101A00002442024024830040008220212402FF80DF
-:101A1000008220243063007F3C02800A006218218B
-:101A20003C028000AC44002403E00008ACC300008A
-:101A300094820006908300058C85000C8C86001033
-:101A40008C8700188C88001C8C8400203C010800C6
-:101A5000A42256C63C010800A02356C53C0108003C
-:101A6000AC2556CC3C010800AC2656D03C01080001
-:101A7000AC2756D83C010800AC2856DC3C010800D5
-:101A8000AC2456E003E00008000000003C0280089F
-:101A9000344201008C4400343C038000346504006F
-:101AA000AC6400388C420038AF850028AC62003C42
-:101AB0003C020005AC6200300000000000000000A5
-:101AC00003E00008000000003C020006308400FF34
-:101AD000008220253C028000AC4400300000000061
-:101AE00000000000000000003C0380008C62000049
-:101AF000304200101040FFFD3462040003E0000893
-:101B0000AF82002894C200003C080800950800CA73
-:101B100030E7FFFF0080482101021021A4C200002D
-:101B200094C200003042FFFF00E2102B544000013D
-:101B3000A4C7000094A200003C0308008C6300CC02
-:101B400024420001A4A2000094A200003042FFFF42
-:101B5000144300073C0280080107102BA4A00000DA
-:101B60005440000101003821A4C700003C02800855
-:101B7000344601008CC3002894A200003C0480007D
-:101B80003042FFFE000210C000621021AC82003C17
-:101B90008C82003C006218231860000400000000E2
-:101BA0008CC200240A0006BA244200018CC2002420
-:101BB000AC8200383C020050344200103C038000EC
-:101BC000AC620030000000000000000000000000D7
-:101BD0008C620000304200201040FFFD0000000039
-:101BE00094A200003C04800030420001000210C0BA
-:101BF000004410218C430400AD2300008C420404F7
-:101C0000AD2200043C02002003E00008AC8200305A
-:101C100027BDFFE0AFB20018AFB10014AFB00010A5
-:101C2000AFBF001C94C2000000C080213C1208001D
-:101C3000965200C624420001A6020000960300004E
-:101C400094E2000000E03021144300058FB1003021
-:101C50000E00068F024038210A0006F10000000045
-:101C60008C8300048C82000424420040046100073D
-:101C7000AC8200048C8200040440000400000000D8
-:101C80008C82000024420001AC8200009602000019
-:101C90003042FFFF50520001A600000096220000D3
-:101CA00024420001A62200003C02800834420100C8
-:101CB000962300009442003C144300048FBF001C94
-:101CC00024020001A62200008FBF001C8FB2001862
-:101CD0008FB100148FB0001003E0000827BD002072
-:101CE00027BDFFE03C028008AFBF0018344201006E
-:101CF0008C4800343C03800034690400AC68003830
-:101D00008C42003830E700FFAF890028AC62003C0D
-:101D10003C020005AC620030000000000000000042
-:101D200000000000000000000000000000000000B3
-:101D30008C82000C8C82000C97830016AD22000070
-:101D40008C82001000604021AD2200048C820018BB
-:101D5000AD2200088C82001CAD22000C8CA2001465
-:101D6000AD2200108C820020AD220014908200056C
-:101D7000304200FF00021200AD2200188CA20018B1
-:101D8000AD22001C8CA2000CAD2200208CA2001001
-:101D9000AD2200248CA2001CAD2200288CA20020C1
-:101DA000AD22002C3402FFFFAD260030AD20003400
-:101DB000506200013408FFFFAD28003850E00011E8
-:101DC0003C0280083C048008348401009482005066
-:101DD0003042FFFFAD22003C9483004494850044D0
-:101DE000240200013063FFFF000318C200641821C1
-:101DF0009064006430A5000700A210040A00075C8C
-:101E00000044102534420100AD20003C94430044BE
-:101E1000944400443063FFFF000318C2006218219D
-:101E200030840007906500642402000100821004E1
-:101E30000002102700451024A0620064000000008A
-:101E400000000000000000003C0200063442004098
-:101E50003C038000AC620030000000000000000085
-:101E6000000000008C620000304200101040FFFDB6
-:101E70003C06800834C201503463040034C7014A70
-:101E800034C4013434C5014034C60144AFA200104B
-:101E90000E0006D2AF8300288FBF001803E00008B1
-:101EA00027BD00208F8300143C0608008CC600E884
-:101EB0008F82001C30633FFF000319800046102111
-:101EC000004310212403FF80004318243C068000B7
-:101ED000ACC300283042007F3C03800C004330211B
-:101EE00090C2000D30A500FF0000382134420010E0
-:101EF000A0C2000D8F8900143C028008344201000A
-:101F00009443004400091382304800032402000176
-:101F1000A4C3000E1102000B2902000210400005AC
-:101F2000240200021100000C240300010A0007A48F
-:101F30000000182111020006000000000A0007A49A
-:101F4000000018218CC2002C0A0007A424430001C1
-:101F50008CC20014244300018CC200180043102BD3
-:101F60005040000A240700012402002714A20003A5
-:101F70003C0380080A0007B1240700013463010014
-:101F80009462004C24420001A462004C00091382B8
-:101F9000304300032C620002104000090080282119
-:101FA000146000040000000094C200340A0007C15D
-:101FB0003046FFFF8CC600380A0007C10080282188
-:101FC000000030213C040800248456C00A000706A3
-:101FD0000000000027BDFF90AFB60068AFB50064F9
-:101FE000AFB40060AFB3005CAFB20058AFB1005403
-:101FF000AFBF006CAFB000508C9000000080B021EB
-:102000003C0208008C4200E8960400328F83001CDA
-:102010002414FF8030843FFF0062182100042180D7
-:1020200000641821007410243C13800000A090214B
-:1020300090A50000AE620028920400323C02800CA1
-:102040003063007F00628821308400C02402004099
-:10205000148200320000A8218E3500388E2200182C
-:102060001440000224020001AE2200189202003C3B
-:10207000304200201440000E8F83001C000511C068
-:102080002442024000621821306400783C02008043
-:102090000082202500741824AE630800AE64081086
-:1020A0008E2200188E03000800431021AE22001873
-:1020B0008E22002C8E230018244200010062182B6F
-:1020C0001060004300000000924200002442000122
-:1020D000A24200003C0308008C6300F4304200FF81
-:1020E00050430001A2400000924200008F84001C77
-:1020F000000211C024420240248300403063007F6C
-:10210000008220213C02800A0094202400621821D1
-:10211000AE6400240A0008D2AEC30000920300326D
-:102120002402FFC000431024304200FF1440000589
-:1021300024020001AE220018962200340A00084250
-:102140003055FFFF8E22001424420001AE220018F9
-:102150009202003000021600000216030441001C27
-:10216000000000009602003227A400100080282101
-:10217000A7A20016960200320000302124070001B9
-:102180003042FFFFAF8200140E000706AFA0001C14
-:10219000960200328F83001C3C0408008C8400E807
-:1021A00030423FFF000211800064182100621821B4
-:1021B00000741024AE62002C3063007F3C02800E5D
-:1021C000006218219062000D3042007FA062000D75
-:1021D0009222000D304200105040007892420000E0
-:1021E0003C028008344401009482004C8EC30000FD
-:1021F0003C130800967300C62442FFFFA482004CE3
-:10220000946200329623000E3054FFFF3070FFFFBF
-:102210003C0308008C6300D000701807A7A30038A7
-:102220009482003E3063FFFF3042FFFF14620007DC
-:10223000000000008C8200303C038000244200300B
-:10224000AC62003C0A00086A8C82002C9482004038
-:102250003042FFFF5462000927A400408C820038FE
-:102260003C03800024420030AC62003C8C8200348D
-:10227000AC6200380A0008793C03800027A50038CA
-:1022800027A60048026038210E00068FA7A000484C
-:102290008FA300403C02800024630030AC43003830
-:1022A0008FA30044AC43003C3C0380003C0200058B
-:1022B000AC6200303C028008344401009482004249
-:1022C000346304003042FFFF0202102B1440000769
-:1022D000AF8300289482004E9483004202021021B2
-:1022E000004310230A00088F3043FFFF9483004E01
-:1022F00094820042026318210050102300621823C8
-:102300003063FFFF3C028008344401009482003CAB
-:102310003042FFFF14430003000000000A00089F42
-:10232000240300019482003C3042FFFF0062102B26
-:10233000144000058F8200289482003C0062102324
-:102340003043FFFF8F820028AC550000AC400004F2
-:10235000AC540008AC43000C3C02000634420010B0
-:102360003C038000AC620030000000000000000070
-:10237000000000008C620000304200101040FFFDA1
-:102380003C04800834840100001018C20064182145
-:102390009065006432020007240600010046100424
-:1023A00000451025A0620064948300429622000E2E
-:1023B00050430001A386001892420000244200010D
-:1023C000A24200003C0308008C6300F4304200FF8E
-:1023D00050430001A2400000924200008F84001C84
-:1023E000000211C0244202402483004000822021C8
-:1023F0002402FF80008220243063007F3C02800A98
-:10240000006218213C028000AC440024AEC30000EE
-:102410008FBF006C8FB600688FB500648FB400600A
-:102420008FB3005C8FB200588FB100548FB0005052
-:1024300003E0000827BD007027BDFFD8AFB3001C24
-:10244000AFB20018AFB10014AFB00010AFBF0020A2
-:102450000080982100E0802130B1FFFF0E000D8444
-:1024600030D200FF0000000000000000000000006B
-:102470008F8200208F830024AC510000AC520004F6
-:10248000AC530008AC40000CAC400010AC40001451
-:10249000AC4000189463001E02038025AC50001C61
-:1024A0000000000000000000000000002404000103
-:1024B0008FBF00208FB3001C8FB200188FB10014A3
-:1024C0008FB000100A000DB827BD002830A5FFFF0F
-:1024D0000A0008DC30C600FF3C02800834430100DB
-:1024E0009462000E3C080800950800C63046FFFFC5
-:1024F00014C000043402FFFF946500EA0A000929B1
-:102500008F84001C10C20027000000009462004E5F
-:102510009464003C3045FFFF00A6102300A6182B52
-:102520003087FFFF106000043044FFFF00C5102318
-:1025300000E210233044FFFF0088102B1040000EF3
-:1025400000E810233C028008344401002403000109
-:1025500034420080A44300162402FFFFA482000E30
-:10256000948500EA8F84001C0000302130A5FFFF15
-:102570000A0009013C0760200044102A10400009AD
-:102580003C0280083443008094620016304200010F
-:10259000104000043C0280009442007E244200145B
-:1025A000A462001603E000080000000027BDFFE061
-:1025B0003C028008AFBF001CAFB0001834420100DD
-:1025C000944300429442004C104000193068FFFFD1
-:1025D0009383001824020001146200298FBF001C9D
-:1025E0003C06800834D00100000810C200501021C1
-:1025F000904200643103000734C70148304200FFB5
-:10260000006210073042000134C9014E34C4012C6D
-:1026100034C5013E1040001634C601420E0006D2F9
-:10262000AFA90010960200420A0009463048FFFF99
-:102630003C028008344401009483004494820042A8
-:102640001043000F8FBF001C94820044A4820042FC
-:1026500094820050A482004E8C820038AC820030FC
-:1026600094820040A482003E9482004AA4820048E2
-:102670008FBF001C8FB000180A00090427BD00207E
-:102680008FB0001803E0000827BD002027BDFFA081
-:10269000AFB1004C3C118000AFBF0058AFB3005445
-:1026A000AFB20050AFB000483626018890C2000398
-:1026B0003044007FA3A400108E32018090C200003D
-:1026C0003043007F240200031062003BAF92001CE5
-:1026D00028620004104000062402000424020002C4
-:1026E000106200098FBF00580A000B0F8FB300540F
-:1026F0001062004D240200051062014E8FBF005889
-:102700000A000B0F8FB30054000411C002421021C5
-:102710002404FF8024420240004410242643004049
-:10272000AE2200243063007F3C02800A0062182140
-:102730009062003CAFA3003C00441025A062003C26
-:102740008FA3003C9062003C304200401040016C7E
-:102750008FBF00583C108008A3800018361001007D
-:102760008E0200E08C63003427A4003C27A50010F3
-:10277000004310210E0007C3AE0200E093A2001038
-:102780003C038000A20200D58C6202780440FFFE68
-:102790008F82001CAC62024024020002A06202444C
-:1027A0003C021000AC6202780E0009390000000003
-:1027B0000A000B0E8FBF00583C05800890C3000133
-:1027C00090A2000B1443014E8FBF005834A4008028
-:1027D0008C8200189082004C90A200083C0260009D
-:1027E0008C4254048C8300183C027FFF3442FFFF6C
-:1027F000006218243C0208008C4200B4AC8300182C
-:102800003C038000244200013C010800AC2200B4DB
-:102810008C6201F80440FFFE8F82001CAC6201C094
-:102820000A000AD6240200023C10800890C300016E
-:102830009202000B144301328FBF005827A40018E6
-:1028400036050110240600033C0260008C4254044B
-:102850000E000E470000000027A40028360501F0F6
-:102860000E000E47240600038FA200283603010045
-:10287000AE0200648FA2002CAE0200688FA200306E
-:10288000AE02006C93A40018906300D52402FF8070
-:102890000082102400431025304900FF3084007F5F
-:1028A0003122007F0082102A544000013929008023
-:1028B000000411C0244202402403FF800242102180
-:1028C00000431024AE220094264200403042007F94
-:1028D0003C038006004340218FA3001C2402FFFF1D
-:1028E000AFA800403C130800927300F71062003359
-:1028F00093A2001995030014304400FF3063FFFFDA
-:102900000064182B106000100000000095040014F3
-:102910008D07001C8D0600183084FFFF0044202323
-:102920000004210000E438210000102100E4202BE5
-:1029300000C2302100C43021AD07001CAD060018D4
-:102940000A000A2F93A20019950400148D07001C99
-:102950008D0600183084FFFF008220230004210030
-:10296000000010210080182100C2302300E4202B39
-:1029700000C4302300E33823AD07001CAD06001867
-:1029800093A200198FA30040A462001497A2001A1A
-:10299000A46200168FA2001CAC6200108FA2001C63
-:1029A000AC62000C93A20019A462002097A2001A46
-:1029B000A46200228FA2001CAC6200243C048008A8
-:1029C000348300808C6200388FA20020012088218F
-:1029D000AC62003C8FA20020AC82000093A20018E1
-:1029E000A062004C93A20018A0820009A0600068B9
-:1029F00093A20018105100512407FF803229007F54
-:102A0000000911C024420240024210213046007FDA
-:102A10003C03800000471024AC6200943C02800616
-:102A200000C2302190C2003CAFA60040000020212F
-:102A300000471025A0C2003C8FA80040950200026C
-:102A4000950300148D07001C3042FFFF3063FFFF29
-:102A50008D060018004310230002110000E2382107
-:102A600000E2102B00C4302100C23021AD07001C51
-:102A7000AD06001895020002A5020014A50000167C
-:102A80008D020008AD0200108D020008AD02000C9E
-:102A900095020002A5020020A50000228D02000878
-:102AA000AD0200249102003C304200401040001A68
-:102AB000262200013C108008A3A90038A38000183A
-:102AC000361001008E0200E08D03003427A4004080
-:102AD00027A50038004310210E0007C3AE0200E016
-:102AE00093A200383C038000A20200D58C620278D9
-:102AF0000440FFFE8F82001CAC62024024020002F0
-:102B0000A06202443C021000AC6202780E00093957
-:102B100000000000262200013043007F14730004EF
-:102B2000004020212403FF8002231024004320269C
-:102B300093A200180A000A4B309100FF93A40018DA
-:102B40008FA3001C2402FFFF1062000A308900FFDF
-:102B500024820001248300013042007F14530005C9
-:102B6000306900FF2403FF800083102400431026F7
-:102B7000304900FF3C028008904200080120882173
-:102B8000305000FF123000193222007F000211C0C5
-:102B900002421021244202402403FF8000431824F3
-:102BA0003C048000AC8300943042007F3C038006EC
-:102BB000004310218C43000C004020211060000BCA
-:102BC000AFA200400E00057E000000002623000199
-:102BD0002405FF803062007F145300020225202468
-:102BE000008518260A000AAF307100FF3C048008F7
-:102BF000348400808C8300183C027FFF3442FFFF46
-:102C000000621824AC8300183C0380008C6201F839
-:102C10000440FFFE00000000AC7201C0240200026C
-:102C2000A06201C43C021000AC6201F80A000B0E65
-:102C30008FBF00583C04800890C300019082000BB5
-:102C40001443002F8FBF0058349000809202000878
-:102C500030420040104000200000000092020008B6
-:102C60000002160000021603044100050240202164
-:102C70000E000ECC240500930A000B0E8FBF0058E7
-:102C80009202000924030018304200FF1443000D93
-:102C900002402021240500390E000E64000030217E
-:102CA0000E0003328F84001C8F82FF9424030012D5
-:102CB000A04300090E00033D8F84001C0A000B0E88
-:102CC0008FBF0058240500360E000E64000030212E
-:102CD0000A000B0E8FBF00580E0003320240202165
-:102CE000920200058F84001C344200200E00033D38
-:102CF000A20200050E0010758F84001C8FBF0058C3
-:102D00008FB300548FB200508FB1004C8FB0004889
-:102D100003E0000827BD00603C0280083445010044
-:102D20003C0280008C42014094A3000E0000302140
-:102D300000402021AF82001C3063FFFF3402FFFF00
-:102D4000106200063C0760202402FFFFA4A2000ED0
-:102D500094A500EA0A00090130A5FFFF03E000087E
-:102D60000000000027BDFFC83C0280003C06800830
-:102D7000AFB5002CAFB1001CAFBF0030AFB400281E
-:102D8000AFB30024AFB20020AFB00018345101003F
-:102D900034C501008C4301008E2200148CA400E491
-:102DA0000000A821AF83001C0044102318400052EB
-:102DB000A38000188E22001400005021ACA200E471
-:102DC00090C3000890A200D53073007FA3A200102A
-:102DD0008CB200E08CB400E4304200FF1053003BA2
-:102DE00093A200108F83001C2407FF80000211C0F3
-:102DF0000062102124420240246300400047102456
-:102E00003063007F3C0980003C08800A006818217C
-:102E1000AD2200248C62003427A4001427A50010E2
-:102E2000024280210290102304400028AFA3001426
-:102E30009062003C00E21024304200FF1440001970
-:102E4000020090219062003C34420040A062003CAD
-:102E50008F86001C93A3001024C200403042007FE4
-:102E6000004828213C0208008C4200F42463000141
-:102E7000306400FF14820002A3A30010A3A000107E
-:102E800093A20010AFA50014000211C0244202401A
-:102E900000C2102100471024AD2200240A000B4577
-:102EA00093A200100E0007C3000000003C0280083F
-:102EB00034420100AC5000E093A30010240A00014A
-:102EC000A04300D50A000B4593A200102402000184
-:102ED000154200093C0380008C6202780440FFFE2A
-:102EE0008F82001CAC62024024020002A0620244F5
-:102EF0003C021000AC6202789222000B2403000214
-:102F0000304200FF144300720000000096220008C7
-:102F1000304300FF24020082146200402402008437
-:102F20003C028000344901008D22000C95230006EC
-:102F3000000216023063FFFF3045003F24020027E5
-:102F400010A2000FAF83001428A200281040000830
-:102F5000240200312402002110A2000924020025CD
-:102F600010A20007938200190A000BBD00000000A8
-:102F700010A20007938200190A000BBD0000000098
-:102F80000E000777012020210A000C3D0000000000
-:102F90003C0380008C6202780440FFFE8F82001C9C
-:102FA000AC62024024020002A06202443C02100013
-:102FB000AC6202780A000C3D000000009523000678
-:102FC000912400058D25000C8D2600108D270018FA
-:102FD0008D28001C8D290020244200013C0108009E
-:102FE000A42356C63C010800A02456C53C01080095
-:102FF000AC2556CC3C010800AC2656D03C0108005C
-:10300000AC2756D83C010800AC2856DC3C0108002F
-:10301000AC2956E00A000C3DA38200191462000A94
-:10302000240200813C02800834420100944500EAF9
-:10303000922600058F84001C30A5FFFF30C600FFDC
-:103040000A000BFE3C0760211462005C00000000D7
-:103050009222000A304300FF306200201040000737
-:10306000306200403C02800834420100944500EA8E
-:103070008F84001C0A000BFC24060040104000074F
-:10308000000316003C02800834420100944500EA27
-:103090008F84001C0A000BFC24060041000216036A
-:1030A000044100463C02800834420100944500EA95
-:1030B0008F84001C2406004230A5FFFF3C076019E6
-:1030C0000E000901000000000A000C3D0000000095
-:1030D0009222000B24040016304200FF1044000628
-:1030E0003C0680009222000B24030017304200FFB0
-:1030F000144300320000000034C5010090A2000B10
-:10310000304200FF1444000B000080218CA20020FC
-:103110008CA400202403FF800043102400021140EF
-:103120003084007F004410253C032000004310251C
-:10313000ACC2083094A2000800021400000214037C
-:10314000044200012410000194A2000830420080D3
-:103150005040001A0200A82194A20008304220002A
-:10316000504000160200A8218CA300183C021C2D20
-:10317000344219ED106200110200A8213C0208003F
-:103180008C4200D4104000053C0280082403000457
-:1031900034420100A04300FC3C028008344201009C
-:1031A000944500EA8F84001C2406000630A5FFFF2A
-:1031B0000E0009013C0760210200A8210E00093918
-:1031C000000000009222000A304200081040000473
-:1031D00002A010210E0013790000000002A01021AF
-:1031E0008FBF00308FB5002C8FB400288FB3002420
-:1031F0008FB200208FB1001C8FB0001803E00008D0
-:1032000027BD00382402FF80008220243C02900069
-:1032100034420007008220253C028000AC4400209C
-:103220003C0380008C6200200440FFFE0000000090
-:1032300003E00008000000003C0380002402FF803F
-:10324000008220243462000700822025AC64002024
-:103250008C6200200440FFFE0000000003E0000834
-:103260000000000027BDFFD8AFB3001CAFB10014B1
-:10327000AFB00010AFBF0020AFB200183C1180000B
-:103280003C0280088E32002034530100AE2400201E
-:10329000966300EA000514003C074000004738250B
-:1032A00000A08021000030210E0009013065FFFFE1
-:1032B000240200A1160200022402FFFFA2620009FC
-:1032C000AE3200208FBF00208FB3001C8FB20018D9
-:1032D0008FB100148FB0001003E0000827BD002854
-:1032E0003C0280082403000527BDFFE834420100AA
-:1032F000A04300FCAFBF00103C0280008C420100E4
-:10330000240500A1004020210E000C67AF82001CA4
-:103310003C0380008C6202780440FFFE8F82001C18
-:103320008FBF001027BD0018AC62024024020002CB
-:10333000A06202443C021000AC62027803E0000884
-:103340000000000027BDFFE83C068000AFBF001072
-:1033500034C7010094E20008304400FF3883008243
-:10336000388200842C6300012C4200010062182581
-:103370001060002D24020083938200195040003B0E
-:103380008FBF00103C020800904256CC8CC4010054
-:103390003C06080094C656C63045003F38A30032AC
-:1033A00038A2003F2C6300012C4200010062182566
-:1033B000AF84001CAF860014A380001914600007BE
-:1033C00000E020212402002014A2001200000000CE
-:1033D0003402FFFF14C2000F00000000240200208E
-:1033E00014A2000500E028218CE300142402FFFF52
-:1033F0005062000B8FBF00103C040800248456C0AC
-:10340000000030210E000706240700010A000CD638
-:103410008FBF00100E000777000000008FBF001064
-:103420000A00093927BD001814820004240200850F
-:103430008CC501040A000CE1000020211482000662
-:103440002482FF808CC50104240440008FBF00103B
-:103450000A00016727BD0018304200FF2C4200021D
-:1034600010400004240200228FBF00100A000B2726
-:1034700027BD0018148200048F8200248FBF001023
-:103480000A000C8627BD00188C42000C1040001E5C
-:1034900000E0282190E300092402001814620003D0
-:1034A000240200160A000CFC240300081462000722
-:1034B00024020017240300123C02800834420080DA
-:1034C000A04300090A000D0994A7000854620007F0
-:1034D00094A700088F82FF942404FFFE9043000508
-:1034E00000641824A043000594A7000890A6001BC0
-:1034F0008CA4000094A500068FBF001000073C00BC
-:103500000A0008DC27BD00188FBF001003E0000888
-:1035100027BD00188F8500243C04800094A2002A57
-:103520008CA30034000230C02402FFF000C210243B
-:1035300000621821AC83003C8CA200303C03800068
-:10354000AC8200383C02005034420010AC620030C3
-:103550000000000000000000000000008C6200007D
-:10356000304200201040FFFD30C20008104000062D
-:103570003C0280008C620408ACA200208C62040C27
-:103580000A000D34ACA200248C430400ACA300203C
-:103590008C420404ACA200243C0300203C028000C6
-:1035A000AC4300303C0480008C8200300043102487
-:1035B0001440FFFD8F8600243C020040AC820030A6
-:1035C00094C3002A94C2002894C4002C94C5002EF1
-:1035D00024630001004410213064FFFFA4C20028CE
-:1035E00014850002A4C3002AA4C0002A03E0000836
-:1035F000000000008F84002427BDFFE83C05800404
-:1036000024840010AFBF00100E000E472406000AED
-:103610008F840024948200129483002E3042000F85
-:10362000244200030043180424027FFF0043102BB0
-:1036300010400002AC8300000000000D0E000D13CE
-:10364000000000008F8300248FBF001027BD0018EA
-:10365000946200149463001A3042000F00021500B7
-:10366000006218253C02800003E00008AC4300A083
-:103670008F8300243C028004944400069462001A64
-:103680008C650000A4640016004410233042FFFF44
-:103690000045102B03E00008384200018F8400240D
-:1036A0003C0780049486001A8C85000094E2000692
-:1036B000A482001694E3000600C310233042FFFFEB
-:1036C0000045102B384200011440FFF8A483001677
-:1036D00003E00008000000008F8400243C02800406
-:1036E000944200069483001A8C850000A482001680
-:1036F000006210233042FFFF0045102B38420001CA
-:103700005040000D8F850024006030213C0780046C
-:1037100094E20006A482001694E3000600C310237E
-:103720003042FFFF0045102B384200011440FFF8E3
-:10373000A48300168F8500243C03800034620400BB
-:103740008CA40020AF820020AC6400388CA200243E
-:10375000AC62003C3C020005AC62003003E00008B3
-:10376000ACA000048F8400243C0300068C8200047B
-:1037700000021140004310253C038000AC62003081
-:103780000000000000000000000000008C6200004B
-:10379000304200101040FFFD34620400AC80000491
-:1037A00003E00008AF8200208F86002427BDFFE0E1
-:1037B000AFB10014AFB00010AFBF00188CC300044D
-:1037C0008CC500248F820020309000FF94C4001A22
-:1037D00024630001244200202484000124A7002047
-:1037E000ACC30004AF820020A4C4001AACC70024FC
-:1037F00004A100060000882104E2000594C2001A1A
-:103800008CC2002024420001ACC2002094C2001AE5
-:1038100094C300282E040001004310262C4200010E
-:10382000004410245040000594C2001A24020001F4
-:10383000ACC2000894C2001A94C300280010202BC8
-:10384000004310262C4200010044102514400007BC
-:10385000000000008CC20008144000042402001084
-:103860008CC300041462000F8F8500240E000DA786
-:10387000241100018F820024944300289442001AEE
-:1038800014430003000000000E000D1300000000B0
-:10389000160000048F8500240E000D840000000037
-:1038A0008F85002494A2001E94A4001C24420001D1
-:1038B0003043FFFF14640002A4A2001EA4A0001E57
-:1038C0001200000A3C02800494A2001494A3001A7F
-:1038D0003042000F00021500006218253C028000F3
-:1038E000AC4300A00A000E1EACA0000894420006E3
-:1038F00094A3001A8CA40000A4A200160062102356
-:103900003042FFFF0044102B384200011040000DF0
-:1039100002201021006030213C07800494E2000660
-:10392000A4A2001694E3000600C310233042FFFF58
-:103930000044102B384200011440FFF8A4A30016E5
-:10394000022010218FBF00188FB100148FB000101B
-:1039500003E0000827BD002003E00008000000008D
-:103960008F82002C3C03000600021140004310250A
-:103970003C038000AC62003000000000000000004A
-:10398000000000008C620000304200101040FFFD7B
-:1039900034620400AF82002803E00008AF80002CEE
-:1039A00003E000080000102103E000080000000010
-:1039B0003084FFFF30A5FFFF0000182110800007B2
-:1039C000000000003082000110400002000420428C
-:1039D000006518210A000E3D0005284003E000089C
-:1039E0000060102110C0000624C6FFFF8CA200005A
-:1039F00024A50004AC8200000A000E4724840004C1
-:103A000003E000080000000010A0000824A3FFFF4E
-:103A1000AC86000000000000000000002402FFFF50
-:103A20002463FFFF1462FFFA2484000403E000080B
-:103A3000000000003C0280083442008024030001A2
-:103A4000AC43000CA4430010A4430012A443001490
-:103A500003E00008A44300168F82002427BDFFD88E
-:103A6000AFB3001CAFB20018AFB10014AFB000107C
-:103A7000AFBF00208C47000C248200802409FF8007
-:103A80003C08800E3043007F008080213C0A80008B
-:103A9000004920240068182130B100FF30D200FF17
-:103AA00010E000290000982126020100AD44002CFE
-:103AB000004928243042007F004820219062000005
-:103AC00024030050304200FF1443000400000000B3
-:103AD000AD45002C948200EA3053FFFF0E000D84A8
-:103AE000000000008F8200248F83002000112C0032
-:103AF0009442001E001224003484000100A22825F4
-:103B00003C02400000A22825AC7000008FBF0020BE
-:103B1000AC6000048FB20018AC7300088FB10014C1
-:103B2000AC60000C8FB3001CAC6400108FB00010B0
-:103B3000AC60001424040001AC60001827BD00280C
-:103B40000A000DB8AC65001C8FBF00208FB3001CAD
-:103B50008FB200188FB100148FB0001003E000087E
-:103B600027BD00283C06800034C201009043000FAE
-:103B7000240200101062000E2865001110A000073A
-:103B800024020012240200082405003A10620006F4
-:103B90000000302103E0000800000000240500358B
-:103BA0001462FFFC000030210A000E6400000000D7
-:103BB0008CC200748F83FF9424420FA003E000089E
-:103BC000AC62000C27BDFFE8AFBF00100E0003423F
-:103BD000240500013C0480088FBF0010240200016E
-:103BE00034830080A462001227BD00182402000163
-:103BF00003E00008A080001A27BDFFE0AFB2001864
-:103C0000AFB10014AFB00010AFBF001C30B2FFFF67
-:103C10000E000332008088213C028008345000806E
-:103C20009202000924030004304200FF1443000CF8
-:103C30003C028008124000082402000A0E000E5BBD
-:103C400000000000920200052403FFFE0043102440
-:103C5000A202000524020012A20200093C02800810
-:103C600034420080022020210E00033DA0400027A6
-:103C700016400003022020210E000EBF00000000AD
-:103C800002202021324600FF8FBF001C8FB2001897
-:103C90008FB100148FB00010240500380A000E64A4
-:103CA00027BD002027BDFFE0AFBF001CAFB200184A
-:103CB000AFB10014AFB000100E00033200808021BD
-:103CC0000E000E5B000000003C02800834450080BE
-:103CD00090A2000924120018305100FF1232000394
-:103CE0000200202124020012A0A2000990A20005D7
-:103CF0002403FFFE004310240E00033DA0A2000594
-:103D00000200202124050020163200070000302187
-:103D10008FBF001C8FB200188FB100148FB000103D
-:103D20000A00034227BD00208FBF001C8FB200187D
-:103D30008FB100148FB00010240500390A000E6402
-:103D400027BD002027BDFFE83C028000AFB0001077
-:103D5000AFBF0014344201009442000C2405003629
-:103D60000080802114400012304600FF0E00033214
-:103D7000000000003C02800834420080240300124E
-:103D8000A043000990430005346300100E000E5B51
-:103D9000A04300050E00033D020020210200202167
-:103DA0000E000342240500200A000F3C0000000022
-:103DB0000E000E64000000000E00033202002021FD
-:103DC0003C0280089043001B2405FF9F0200202135
-:103DD000006518248FBF00148FB00010A043001B93
-:103DE0000A00033D27BD001827BDFFE0AFBF001844
-:103DF000AFB10014AFB0001030B100FF0E000332BD
-:103E0000008080213C02800824030012344200809C
-:103E10000E000E5BA04300090E00033D02002021AE
-:103E200002002021022030218FBF00188FB1001422
-:103E30008FB00010240500350A000E6427BD002055
-:103E40003C0480089083000E9082000A1443000B0B
-:103E5000000028218F82FF942403005024050001D4
-:103E600090420000304200FF1443000400000000B4
-:103E70009082000E24420001A082000E03E00008A0
-:103E800000A010213C0380008C6201F80440FFFE7A
-:103E900024020002AC6401C0A06201C43C02100014
-:103EA00003E00008AC6201F827BDFFE0AFB20018E4
-:103EB0003C128008AFB10014AFBF001CAFB00010BF
-:103EC00036510080922200092403000A304200FF8C
-:103ED0001443003E000000008E4300048E22003890
-:103EE000506200808FBF001C92220000240300500B
-:103EF000304200FF144300253C0280008C42014008
-:103F00008E4300043642010002202821AC43001CED
-:103F10009622005C8E2300383042FFFF00021040E2
-:103F200000621821AE23001C8E4300048E2400384A
-:103F30009622005C006418233042FFFF0003184300
-:103F4000000210400043102A10400006000000004C
-:103F50008E4200048E230038004310230A000FAA6B
-:103F6000000220439622005C3042FFFF0002204006
-:103F70003C0280083443010034420080ACA4002C91
-:103F8000A040002424020001A062000C0E000F5E7D
-:103F900000000000104000538FBF001C3C02800056
-:103FA0008C4401403C0380008C6201F80440FFFE19
-:103FB00024020002AC6401C0A06201C43C021000F3
-:103FC000AC6201F80A0010078FBF001C92220009A2
-:103FD00024030010304200FF144300043C02800020
-:103FE0008C4401400A000FEE0000282192220009B3
-:103FF00024030016304200FF14430006240200147C
-:10400000A22200093C0280008C4401400A001001F9
-:104010008FBF001C8E2200388E23003C00431023EB
-:10402000044100308FBF001C92220027244200016F
-:10403000A2220027922200272C42000414400016DE
-:104040003C1080009222000924030004304200FF4B
-:10405000144300093C0280008C4401408FBF001CC7
-:104060008FB200188FB100148FB000102405009398
-:104070000A000ECC27BD00208C440140240500938B
-:104080008FBF001C8FB200188FB100148FB00010CA
-:104090000A000F4827BD00208E0401400E000332A5
-:1040A000000000008E4200042442FFFFAE420004E4
-:1040B0008E22003C2442FFFFAE22003C0E00033D56
-:1040C0008E0401408E0401408FBF001C8FB2001887
-:1040D0008FB100148FB00010240500040A000342C1
-:1040E00027BD00208FB200188FB100148FB00010D0
-:1040F00003E0000827BD00203C0680008CC2018838
-:104100003C038008346500809063000E00021402B6
-:10411000304400FF306300FF1464000E3C0280084E
-:1041200090A20026304200FF104400098F82FF94C5
-:10413000A0A400262403005090420000304200FF5B
-:1041400014430006000000000A0005A18CC4018091
-:104150003C02800834420080A044002603E00008AE
-:104160000000000027BDFFE030E700FFAFB20018FD
-:10417000AFBF001CAFB10014AFB0001000809021A1
-:1041800014E0000630C600FF000000000000000D33
-:10419000000000000A001060240001163C038008A3
-:1041A0009062000E304200FF14460023346200800B
-:1041B00090420026304200FF1446001F000000001D
-:1041C0009062000F304200FF1446001B0000000008
-:1041D0009062000A304200FF144600038F90FF9463
-:1041E0000000000D8F90FF948F82FF983C1180009B
-:1041F000AE05003CAC450000A066000A0E0003328C
-:104200008E240100A20000240E00033D8E24010034
-:104210003C0380008C6201F80440FFFE240200028F
-:10422000AC7201C0A06201C43C021000AC6201F893
-:104230000A0010618FBF001C000000000000000D8C
-:10424000000000002400013F8FBF001C8FB2001847
-:104250008FB100148FB0001003E0000827BD0020CC
-:104260008F83FF943C0280008C44010034420100A3
-:104270008C65003C9046001B0A00102724070001B3
-:104280003C0280089043000E9042000A0043102632
-:10429000304200FF03E000080002102B27BDFFE0C2
-:1042A0003C028008AFB10014AFB00010AFBF0018DF
-:1042B0003450008092020005240300303042003068
-:1042C00014430085008088218F8200248C42000CDA
-:1042D000104000828FBF00180E000D840000000007
-:1042E0008F860020ACD100009202000892030009E2
-:1042F000304200FF00021200306300FF004310252F
-:10430000ACC200049202004D000216000002160327
-:1043100004410005000000003C0308008C630048D5
-:104320000A00109F3C1080089202000830420040B2
-:10433000144000030000182192020027304300FFC0
-:104340003C108008361100809222004D00031E00B0
-:10435000304200FF0002140000621825ACC30008C0
-:104360008E2400308F820024ACC4000C8E250034D3
-:104370009443001E3C02C00BACC50010006218251F
-:104380008E22003800002021ACC200148E22003C96
-:10439000ACC200180E000DB8ACC3001C8E020004A5
-:1043A0008F8400203C058000AC8200008E2200201B
-:1043B000AC8200048E22001CAC8200088E220058C1
-:1043C0008CA3007400431021AC82000C8E22002CC0
-:1043D000AC8200108E2200408E23004400021400A4
-:1043E00000431025AC8200149222004D240300806B
-:1043F000304200FF1443000400000000AC800018AD
-:104400000A0010E38F8200248E23000C2402000196
-:104410001062000E2402FFFF92220008304200408A
-:104420001440000A2402FFFF8E23000C8CA20074AB
-:10443000006218233C0208000062102414400002AD
-:10444000000028210060282100051043AC820018DC
-:104450008F820024000020219443001E3C02C00CE7
-:10446000006218258F8200200E000DB8AC43001C9E
-:104470003C038008346201008C4200008F850020DC
-:10448000346300808FBF0018ACA20000ACA0000411
-:104490008C6400488F8200248FB10014ACA4000803
-:1044A000ACA0000CACA00010906300059446001E68
-:1044B0003C02400D00031E0000C23025ACA30014D6
-:1044C0008FB00010ACA0001824040001ACA6001CA2
-:1044D0000A000DB827BD00208FBF00188FB100144F
-:1044E0008FB0001003E0000827BD00203C028000D0
-:1044F0009443007C3C02800834460100308400FF75
-:104500003065FFFF2402000524A34650A0C4000C20
-:104510005482000C3065FFFF90C2000D2C42000752
-:104520001040000724A30A0090C3000D24020014C9
-:104530000062100400A210210A00111F3045FFFF85
-:104540003065FFFF3C0280083442008003E0000831
-:10455000A44500143C03800834680080AD05003891
-:10456000346701008CE2001C308400FF00A210239D
-:104570001840000330C600FF24A2FFFCACE2001C80
-:1045800030820001504000083C0380088D02003C4E
-:1045900000A2102304410012240400058C620004D0
-:1045A00010A2000F3C0380088C62000414A2001EBD
-:1045B000000000003C0208008C4200D8304200207D
-:1045C000104000093C0280083462008090630008BB
-:1045D0009042004C144300043C0280082404000470
-:1045E0000A00110900000000344300803442010039
-:1045F000A040000C24020001A462001410C0000AB4
-:104600003C0280008C4401003C0380008C6201F875
-:104610000440FFFE24020002AC6401C0A06201C499
-:104620003C021000AC6201F803E00008000000004A
-:1046300027BDFFE800A61823AFBF00101860008058
-:10464000308800FF3C02800834470080A0E000244E
-:1046500034440100A0E000278C82001C00A210233B
-:1046600004400056000000008CE2003C94E3005C33
-:104670008CE4002C004530233063FFFF00C3182179
-:104680000083202B1080000400E018218CE2002C15
-:104690000A00117800A2102194E2005C3042FFFF72
-:1046A00000C2102100A21021AC62001C3C02800854
-:1046B000344400809482005C8C83001C3042FFFFF5
-:1046C0000002104000A210210043102B10400004F3
-:1046D000000000008C82001C0A00118B3C06800840
-:1046E0009482005C3042FFFF0002104000A21021C3
-:1046F0003C06800834C3010034C70080AC82001C33
-:10470000A060000CACE500388C62001C00A21023F5
-:104710001840000224A2FFFCAC62001C3102000120
-:10472000104000083C0380088CE2003C00A21023EB
-:1047300004410012240400058CC2000410A20010E1
-:104740008FBF00108C62000414A2004F8FBF0010B6
-:104750003C0208008C4200D8304200201040000A81
-:104760003C02800834620080906300089042004C54
-:10477000144300053C028008240400048FBF00108D
-:104780000A00110927BD001834430080344201009B
-:10479000A040000C24020001A46200143C0280002E
-:1047A0008C4401003C0380008C6201F80440FFFE51
-:1047B000240200020A0011D8000000008CE2001C54
-:1047C000004610230043102B54400001ACE5001CB0
-:1047D00094E2005C3042FFFF0062102B144000079F
-:1047E0002402000294E2005C8CE3001C3042FFFFD4
-:1047F00000621821ACE3001C24020002ACE5003882
-:104800000E000F5EA082000C1040001F8FBF001032
-:104810003C0280008C4401003C0380008C6201F863
-:104820000440FFFE24020002AC6401C0A06201C487
-:104830003C021000AC6201F80A0011F08FBF0010BA
-:1048400031020010104000108FBF00103C028008A1
-:10485000344500808CA3001C94A2005C00661823E1
-:104860003042FFFF006218213C023FFF3444FFFF4B
-:104870000083102B544000010080182100C3102138
-:10488000ACA2001C8FBF001003E0000827BD001879
-:1048900027BDFFE800C0402100A63023AFBF0010B5
-:1048A00018C00026308A00FF3C028008344900808E
-:1048B0008D24001C8D23002C008820230064182BDD
-:1048C0001060000F344701008CE2002000461021E8
-:1048D000ACE200208CE200200044102B1440000BBE
-:1048E0003C023FFF8CE2002000441023ACE2002099
-:1048F0009522005C3042FFFF0A0012100082202146
-:10490000ACE00020008620213C023FFF3443FFFF43
-:104910000064102B54400001006020213C028008FC
-:104920003442008000851821AC43001CA0400024C4
-:10493000A04000270A0012623C03800831420010A8
-:10494000104000433C0380083C06800834C40080CB
-:104950008C82003C004810235840003E34660080A2
-:104960009082002424420001A0820024908200242E
-:104970003C0308008C630024304200FF0043102BEE
-:10498000144000688FBF001034C201008C42001C2C
-:1049900000A2102318400063000000008CC3000434
-:1049A0009482005C006818233042FFFF0003184324
-:1049B000000210400043102A1040000500000000D3
-:1049C0008CC20004004810230A0012450002104364
-:1049D0009482005C3042FFFF000210403C068008D9
-:1049E000AC82002C34C5008094A2005C8CA4002C06
-:1049F00094A3005C3042FFFF00021040008220219F
-:104A00003063FFFF0083202101041021ACA2001CB1
-:104A10008CC2000434C60100ACC2001C2402000297
-:104A20000E000F5EA0C2000C1040003E8FBF0010B1
-:104A30003C0280008C4401003C0380008C6201F841
-:104A40000440FFFE240200020A001292000000004F
-:104A500034660080ACC50038346401008C82001CD0
-:104A600000A210231840000224A2FFFCAC82001C0C
-:104A7000314200015040000A3C0380088CC2003CD7
-:104A800000A2102304430014240400058C620004D7
-:104A900014A200033C0380080A00128424040005C9
-:104AA0008C62000414A2001F8FBF00103C0208009B
-:104AB0008C4200D8304200201040000A3C0280089E
-:104AC00034620080906300089042004C144300055B
-:104AD0003C028008240400048FBF00100A00110962
-:104AE00027BD00183443008034420100A040000C70
-:104AF00024020001A46200143C0280008C440100E6
-:104B00003C0380008C6201F80440FFFE2402000296
-:104B1000AC6401C0A06201C43C021000AC6201F8A8
-:104B20008FBF001003E0000827BD001827BDFFE875
-:104B30003C0A8008AFBF0010354900808D22003C40
-:104B400000C04021308400FF004610231840009D23
-:104B500030E700FF354701002402000100A63023A2
-:104B6000A0E0000CA0E0000DA522001418C0002455
-:104B7000308200108D23001C8D22002C0068182329
-:104B80000043102B1040000F000000008CE20020BA
-:104B900000461021ACE200208CE200200043102BE4
-:104BA0001440000B3C023FFF8CE200200043102326
-:104BB000ACE200209522005C3042FFFF0A0012C1E7
-:104BC00000621821ACE00020006618213C023FFF83
-:104BD0003446FFFF00C3102B5440000100C01821D1
-:104BE0003C0280083442008000651821AC43001C60
-:104BF000A0400024A04000270A00130F3C038008B7
-:104C0000104000403C0380088D22003C00481023E7
-:104C10005840003D34670080912200242442000166
-:104C2000A1220024912200243C0308008C6300246C
-:104C3000304200FF0043102B1440009A8FBF001039
-:104C40008CE2001C00A21023184000960000000017
-:104C50008D4300049522005C006818233042FFFF5A
-:104C600000031843000210400043102A10400005C2
-:104C7000012020218D420004004810230A0012F276
-:104C8000000210439522005C3042FFFF00021040FA
-:104C90003C068008AC82002C34C5008094A2005CE5
-:104CA0008CA4002C94A3005C3042FFFF0002104053
-:104CB000008220213063FFFF0083182101031021AF
-:104CC000ACA2001C8CC2000434C60100ACC2001CA3
-:104CD000240200020E000F5EA0C2000C1040007102
-:104CE0008FBF00103C0280008C4401003C03800018
-:104CF0008C6201F80440FFFE240200020A0013390E
-:104D00000000000034670080ACE500383466010024
-:104D10008CC2001C00A210231840000224A2FFFC39
-:104D2000ACC2001C30820001504000083C038008E7
-:104D30008CE2003C00A2102304430051240400052F
-:104D40008C62000410A2003E3C0380088C620004C8
-:104D500054A200548FBF00103C0208008C4200D8BF
-:104D600030420020104000063C028008346200807F
-:104D7000906300089042004C104300403C028008C1
-:104D80003443008034420100A040000C24020001A2
-:104D9000A46200143C0280008C4401003C038000AB
-:104DA0008C6201F80440FFFE24020002AC6401C0E2
-:104DB000A06201C43C021000AC6201F80A00137743
-:104DC0008FBF001024020005A120002714E2000A72
-:104DD0003C038008354301009062000D2C42000620
-:104DE000504000053C0380089062000D2442000101
-:104DF000A062000D3C03800834670080ACE50038F9
-:104E0000346601008CC2001C00A21023184000026E
-:104E100024A2FFFCACC2001C308200015040000AFA
-:104E20003C0380088CE2003C00A2102304410014E3
-:104E3000240400058C62000414A200033C038008D3
-:104E40000A00136E240400058C62000414A20015ED
-:104E50008FBF00103C0208008C4200D83042002076
-:104E60001040000A3C028008346200809063000811
-:104E70009042004C144300053C02800824040004C6
-:104E80008FBF00100A00110927BD001834430080AD
-:104E900034420100A040000C24020001A46200146E
-:104EA0008FBF001003E0000827BD00183C0B8008EE
-:104EB00027BDFFE83C028000AFBF00103442010074
-:104EC000356A00809044000A356901008C45001461
-:104ED0008D4800389123000C308400FF0105102319
-:104EE0001C4000B3306700FF2CE20006504000B1C8
-:104EF0008FBF00102402000100E2300430C2000322
-:104F00005440000800A8302330C2000C144000A117
-:104F100030C20030144000A38FBF00100A00143BC1
-:104F20000000000018C00024308200108D43001CD7
-:104F30008D42002C006818230043102B1040000FF6
-:104F4000000000008D22002000461021AD2200202C
-:104F50008D2200200043102B1440000B3C023FFF29
-:104F60008D22002000431023AD2200209542005CDA
-:104F70003042FFFF0A0013AF00621821AD2000206D
-:104F8000006618213C023FFF3446FFFF00C3102B90
-:104F90005440000100C018213C02800834420080C7
-:104FA00000651821AC43001CA0400024A04000274D
-:104FB0000A0013FD3C038008104000403C038008B9
-:104FC0008D42003C004810231840003D34670080AB
-:104FD0009142002424420001A14200249142002475
-:104FE0003C0308008C630024304200FF0043102B78
-:104FF000144000708FBF00108D22001C00A21023EF
-:105000001840006C000000008D6300049542005CB5
-:10501000006818233042FFFF0003184300021040CD
-:105020000043102A10400005014020218D62000439
-:10503000004810230A0013E0000210439542005C70
-:105040003042FFFF000210403C068008AC82002C7A
-:1050500034C5008094A2005C8CA4002C94A3005C56
-:105060003042FFFF00021040008220213063FFFF2A
-:105070000083182101031021ACA2001C8CC2000483
-:1050800034C60100ACC2001C240200020E000F5EF8
-:10509000A0C2000C104000478FBF00103C028000EF
-:1050A0008C4401003C0380008C6201F80440FFFE48
-:1050B000240200020A00142D000000003467008062
-:1050C000ACE50038346601008CC2001C00A210233D
-:1050D0001840000224A2FFFCACC2001C3082000178
-:1050E0005040000A3C0380088CE2003C00A21023E0
-:1050F00004430014240400058C62000414A200037D
-:105100003C0380080A00141F240400058C6200047C
-:1051100014A200288FBF00103C0208008C4200D867
-:10512000304200201040000A3C02800834620080B7
-:10513000906300089042004C144300053C02800834
-:10514000240400048FBF00100A00110927BD0018B5
-:105150003443008034420100A040000C24020001CE
-:10516000A46200143C0280008C4401003C038000D7
-:105170008C6201F80440FFFE24020002AC6401C00E
-:10518000A06201C43C021000AC6201F80A00143BAA
-:105190008FBF00108FBF0010010030210A00115A8C
-:1051A00027BD0018010030210A00129927BD001800
-:1051B0008FBF001003E0000827BD00183C038008E3
-:1051C0003464010024020003A082000C8C620004FD
-:1051D00003E00008AC82001C3C05800834A300807A
-:1051E0009062002734A501002406004324420001F8
-:1051F000A0620027906300273C0208008C42004810
-:10520000306300FF146200043C07602194A500EAAB
-:105210000A00090130A5FFFF03E0000800000000BC
-:1052200027BDFFE8AFBF00103C0280000E00144411
-:105230008C4401803C02800834430100A060000CD3
-:105240008C4200048FBF001027BD001803E0000847
-:10525000AC62001C27BDFFE03C028008AFBF001815
-:10526000AFB10014AFB000103445008034460100E7
-:105270003C0880008D09014090C3000C8CA4003CC8
-:105280008CA200381482003B306700FF9502007C3E
-:1052900090A30027146000093045FFFF2402000599
-:1052A00054E200083C04800890C2000D2442000132
-:1052B000A0C2000D0A00147F3C048008A0C0000DAD
-:1052C0003C048008348201009042000C2403000555
-:1052D000304200FF1443000A24A205DC348300801E
-:1052E000906200272C4200075040000524A20A00CB
-:1052F00090630027240200140062100400A2102111
-:105300003C108008361000803045FFFF012020212E
-:105310000E001444A60500149602005C8E030038AB
-:105320003C1180003042FFFF000210400062182153
-:10533000AE03001C0E0003328E24014092020025B1
-:1053400034420040A20200250E00033D8E2401409D
-:105350008E2401403C0380008C6201F80440FFFE73
-:1053600024020002AC6401C0A06201C43C0210002F
-:10537000AC6201F88FBF00188FB100148FB000101D
-:1053800003E0000827BD00203C0360103C02080039
-:1053900024420174AC62502C8C6250003C048000AA
-:1053A00034420080AC6250003C0208002442547C2D
-:1053B0003C010800AC2256003C020800244254384C
-:1053C0003C010800AC2256043C020002AC840008F8
-:1053D000AC82000C03E000082402000100A0302190
-:1053E0003C1C0800279C56083C0200023C050400B7
-:1053F00000852826008220260004102B2CA5000101
-:105400002C840001000210803C0308002463560035
-:105410000085202500431821108000030000102182
-:10542000AC6600002402000103E000080000000058
-:105430003C1C0800279C56083C0200023C05040066
-:1054400000852826008220260004102B2CA50001B0
-:105450002C840001000210803C03080024635600E5
-:105460000085202500431821108000050000102130
-:105470003C02080024425438AC62000024020001BF
-:1054800003E00008000000003C0200023C030400AE
-:1054900000821026008318262C4200012C63000194
-:1054A000004310251040000B000028213C1C080080
-:1054B000279C56083C0380008C62000824050001EC
-:1054C00000431025AC6200088C62000C00441025DB
-:1054D000AC62000C03E0000800A010213C1C080096
-:1054E000279C56083C0580008CA3000C0004202754
-:1054F000240200010064182403E00008ACA3000C9F
-:105500003C020002148200063C0560008CA208D018
-:105510002403FFFE0043102403E00008ACA208D0DF
-:105520003C02040014820005000000008CA208D098
-:105530002403FFFD00431024ACA208D003E00008C0
-:10554000000000003C02601A344200108C430080CE
-:1055500027BDFFF88C440084AFA3000093A3000094
-:10556000240200041462001AAFA4000493A20001F4
-:105570001040000797A300023062FFFC3C0380004C
-:10558000004310218C4200000A001536AFA200042F
-:105590003062FFFC3C03800000431021AC4400005B
-:1055A000A3A000003C0560008CA208D02403FFFEED
-:1055B0003C04601A00431024ACA208D08FA300045E
-:1055C0008FA2000034840010AC830084AC82008081
-:1055D00003E0000827BD000827BDFFE8AFBF0010AB
-:1055E0003C1C0800279C56083C0280008C43000CA1
-:1055F0008C420004004318243C0200021060001496
-:10560000006228243C0204003C04000210A00005B3
-:10561000006210243C0208008C4256000A00155B10
-:1056200000000000104000073C0404003C02080099
-:105630008C4256040040F809000000000A00156082
-:10564000000000000000000D3C1C0800279C5608CC
-:0C5650008FBF001003E0000827BD001809
-:04565C008008024080
-:1056600080080100800800808008000000000C8095
-:105670000000320008000E9808000EF408000F88A1
-:1056800008001028080010748008010080080080BD
-:04569000800800008E
-:0C5694000A0000280000000000000000D8
-:1056A0000000000D6370362E322E316100000000C4
-:1056B00006020104000000000000000000000000DD
-:1056C000000000000000000038003C000000000066
-:1056D00000000000000000000000000000000020AA
-:1056E00000000000000000000000000000000000BA
-:1056F00000000000000000000000000000000000AA
-:10570000000000000000000021003800000000013F
-:105710000000002B000000000000000400030D400A
-:105720000000000000000000000000000000000079
-:105730000000000000000000100000030000000056
-:105740000000000D0000000D3C020800244259AC8E
-:105750003C03080024635BF4AC4000000043202BB2
-:105760001480FFFD244200043C1D080037BD9FFC4F
-:1057700003A0F0213C100800261000A03C1C0800EB
-:10578000279C59AC0E0002F6000000000000000D3E
-:1057900027BDFFB4AFA10000AFA20004AFA3000873
-:1057A000AFA4000CAFA50010AFA60014AFA700185F
-:1057B000AFA8001CAFA90020AFAA0024AFAB0028FF
-:1057C000AFAC002CAFAD0030AFAE0034AFAF00389F
-:1057D000AFB8003CAFB90040AFBC0044AFBF004819
-:1057E0000E000820000000008FBF00488FBC00445E
-:1057F0008FB900408FB8003C8FAF00388FAE0034B7
-:105800008FAD00308FAC002C8FAB00288FAA002406
-:105810008FA900208FA8001C8FA700188FA6001446
-:105820008FA500108FA4000C8FA300088FA2000486
-:105830008FA1000027BD004C3C1B60188F7A5030B0
-:10584000377B502803400008AF7A000000A01821E1
-:1058500000801021008028213C0460003C0760008B
-:105860002406000810600006348420788C42000072
-:10587000ACE220088C63000003E00008ACE3200CDD
-:105880000A000F8100000000240300403C02600079
-:1058900003E00008AC4320003C0760008F86000452
-:1058A0008CE520740086102100A2182B14600007DC
-:1058B000000028218F8AFDA024050001A1440013C7
-:1058C0008F89000401244021AF88000403E0000810
-:1058D00000A010218F84FDA08F8500049086001306
-:1058E00030C300FF00A31023AF82000403E00008D0
-:1058F000A08000138F84FDA027BDFFE8AFB000108B
-:10590000AFBF001490890011908700112402002875
-:10591000312800FF3906002830E300FF2485002CE1
-:105920002CD00001106200162484001C0E00006EB2
-:10593000000000008F8FFDA03C05600024020204DF
-:1059400095EE003E95ED003C000E5C0031ACFFFF93
-:10595000016C5025ACAA2010520000012402000462
-:10596000ACA22000000000000000000000000000C9
-:105970008FBF00148FB0001003E0000827BD00188F
-:105980000A0000A6000028218F85FDA027BDFFD8B2
-:10599000AFBF0020AFB3001CAFB20018AFB100140E
-:1059A000AFB000100080982190A4001124B0001C1A
-:1059B00024B1002C308300FF386200280E000090D4
-:1059C0002C5200010E00009800000000020020216F
-:1059D0001240000202202821000028210E00006E43
-:1059E000000000008F8DFDA03C0880003C05600099
-:1059F00095AC003E95AB003C02683025000C4C0095
-:105A0000316AFFFF012A3825ACA7201024020202C8
-:105A1000ACA6201452400001240200028FBF0020D7
-:105A20008FB3001C8FB200188FB100148FB000101C
-:105A300027BD002803E00008ACA2200027BDFFE03E
-:105A4000AFB20018AFB10014AFB00010AFBF001C70
-:105A50003C1160008E2320748F82000430D0FFFF41
-:105A600030F2FFFF1062000C2406008F0E00006E63
-:105A7000000000003C06801F0010440034C5FF00F9
-:105A80000112382524040002AE2720100000302126
-:105A9000AE252014AE2420008FBF001C8FB200184A
-:105AA0008FB100148FB0001000C0102103E0000877
-:105AB00027BD002027BDFFE0AFB0001030D0FFFFB2
-:105AC000AFBF0018AFB100140E00006E30F1FFFF41
-:105AD00000102400009180253C036000AC70201071
-:105AE0008FBF00188FB100148FB000102402000483
-:105AF000AC62200027BD002003E000080000102158
-:105B000027BDFFE03C046018AFBF0018AFB1001420
-:105B1000AFB000108C8850002403FF7F34028071E6
-:105B20000103382434E5380C241F00313C1980006F
-:105B3000AC8550003C11800AAC8253BCAF3F0008DA
-:105B40000E00054CAF9100400E00050A3C116000AC
-:105B50000E00007D000000008E3008083C0F570941
-:105B60002418FFF00218602435EEE00035EDF00057
-:105B7000018E5026018D58262D4600012D69000109
-:105B8000AF86004C0E000D09AF8900503C06601630
-:105B90008CC700003C0860148D0500A03C03FFFF8B
-:105BA00000E320243C02535300052FC2108200550D
-:105BB00034D07C00960201F2A780006C10400003F4
-:105BC000A780007C384B1E1EA78B006C960201F844
-:105BD000104000048F8D0050384C1E1EA78C007C96
-:105BE0008F8D005011A000058F83004C240E0020E3
-:105BF000A78E007CA78E006C8F83004C1060000580
-:105C00009785007C240F0020A78F007CA78F006C55
-:105C10009785007C2CB8008153000001240500808A
-:105C20009784006C2C91040152200001240404008C
-:105C30001060000B3C0260008FBF00188FB1001491
-:105C40008FB0001027BD0020A784006CA785007CC2
-:105C5000A380007EA780007403E00008A780009264
-:105C60008C4704382419103C30FFFFFF13F9000360
-:105C700030A8FFFF1100004624030050A380007EDF
-:105C80009386007E50C00024A785007CA780007CFE
-:105C90009798007CA780006CA7800074A780009272
-:105CA0003C010800AC3800800E00078700000000AF
-:105CB0003C0F60008DED0808240EFFF03C0B600ED9
-:105CC000260C0388356A00100000482100002821B6
-:105CD00001AE20243C105709AF8C0010AF8A004859
-:105CE000AF89001810900023AF8500148FBF0018F3
-:105CF0008FB100148FB0001027BD002003E0000812
-:105D0000AF80005400055080014648218D260004D4
-:105D10000A00014800D180219798007CA784006C7C
-:105D2000A7800074A78000923C010800AC38008076
-:105D30000E000787000000003C0F60008DED080892
-:105D4000240EFFF03C0B600E260C0388356A001011
-:105D5000000048210000282101AE20243C105709F2
-:105D6000AF8C0010AF8A0048AF8900181490FFDF95
-:105D7000AF85001424110001AF9100548FBF0018AB
-:105D80008FB100148FB0001003E0000827BD002081
-:105D90000A00017BA383007E3083FFFF8F880040D1
-:105DA0008F87003C000321403C0580003C020050EE
-:105DB000008248253C0660003C0A010034AC040027
-:105DC0008CCD08E001AA58241160000500000000F5
-:105DD0008CCF08E024E7000101EA7025ACCE08E092
-:105DE0008D19001001805821ACB900388D180014AD
-:105DF000ACB8003CACA9003000000000000000007E
-:105E00000000000000000000000000000000000092
-:105E100000000000000000003C0380008C640000D3
-:105E2000308200201040FFFD3C0F60008DED08E047
-:105E30003C0E010001AE18241460FFE100000000D8
-:105E4000AF87003C03E00008AF8B00588F8500400F
-:105E5000240BFFF03C06800094A7001A8CA90024B4
-:105E600030ECFFFF000C38C000EB5024012A402129
-:105E7000ACC8003C8CA400248CC3003C00831023DD
-:105E800018400033000000008CAD002025A2000166
-:105E90003C0F0050ACC2003835EE00103C068000CC
-:105EA000ACCE003000000000000000000000000048
-:105EB00000000000000000000000000000000000E2
-:105EC000000000003C0480008C9900003338002062
-:105ED0001300FFFD30E20008104000173C0980006D
-:105EE0008C880408ACA800108C83040CACA30014AC
-:105EF0003C1900203C188000AF19003094AE001807
-:105F000094AF001C01CF3021A4A6001894AD001A54
-:105F100025A70001A4A7001A94AB001A94AC001E98
-:105F2000118B00030000000003E0000800000000E7
-:105F300003E00008A4A0001A8D2A0400ACAA0010F7
-:105F40008D240404ACA400140A0002183C1900209B
-:105F50008CA200200A0002003C0F00500A0001EE53
-:105F60000000000027BDFFE8AFBF00100E000232A6
-:105F7000000000008F8900408FBF00103C038000AC
-:105F8000A520000A9528000A9527000427BD0018BF
-:105F90003105FFFF30E6000F0006150000A22025A6
-:105FA00003E00008AC6400803C0508008CA50020DC
-:105FB0008F83000C27BDFFE8AFB00010AFBF001407
-:105FC00010A300100000802124040001020430040A
-:105FD00000A6202400C3102450440006261000010F
-:105FE000001018802787FDA41480000A006718217C
-:105FF000261000012E0900025520FFF38F83000CAC
-:10600000AF85000C8FBF00148FB0001003E00008B4
-:1060100027BD00188C6800003C058000ACA8002457
-:106020000E000234261000013C0508008CA500205B
-:106030000A0002592E0900022405000100851804F7
-:106040003C0408008C84002027BDFFC8AFBF00348B
-:1060500000831024AFBE0030AFB7002CAFB60028CD
-:10606000AFB50024AFB40020AFB3001CAFB200182E
-:10607000AFB1001410400051AFB000108F84004049
-:10608000948700069488000A00E8302330D5FFFF8B
-:1060900012A0004B8FBF0034948B0018948C000A20
-:1060A000016C50233142FFFF02A2482B1520000251
-:1060B00002A02021004020212C8F000515E00002C5
-:1060C00000809821241300040E0001C102602021E9
-:1060D0008F87004002609021AF80004494F4000A52
-:1060E000026080211260004E3291FFFF3C1670006A
-:1060F0003C1440003C1E20003C1760008F99005863
-:106100008F380000031618241074004F0283F82BF8
-:1061100017E0003600000000107E00478F86004424
-:1061200014C0003A2403000102031023022320219B
-:106130003050FFFF1600FFF13091FFFF8F870040C6
-:106140003C1100203C108000AE11003094EB000A9E
-:106150003C178000024B5021A4EA000A94E9000A8F
-:1061600094E800043123FFFF3106000F00062D00E4
-:106170000065F025AEFE008094F3000A94F6001846
-:1061800012D30036001221408CFF00148CF4001052
-:1061900003E468210000C02101A4782B029870213B
-:1061A00001CF6021ACED0014ACEC001002B238233A
-:1061B00030F5FFFF16A0FFB88F8400408FBF00347A
-:1061C0008FBE00308FB7002C8FB600288FB500240B
-:1061D0008FB400208FB3001C8FB200188FB1001451
-:1061E0008FB0001003E0000827BD00381477FFCC03
-:1061F0008F8600440E000EE202002021004018218C
-:106200008F86004410C0FFC9020310230270702360
-:106210008F87004001C368210A0002E431B2FFFF0A
-:106220008F86004414C0FFC93C1100203C10800040
-:106230000A0002AEAE1100300E00046602002021FA
-:106240000A0002DB00401821020020210E0009395B
-:10625000022028210A0002DB004018210E0001EE76
-:10626000000000000A0002C702B2382327BDFFC8A1
-:10627000AFB7002CAFB60028AFB50024AFB40020F4
-:10628000AFB3001CAFB20018AFB10014AFB0001034
-:10629000AFBF00300E00011B241300013C047FFF40
-:1062A0003C0380083C0220003C010800AC20007048
-:1062B0003496FFFF34770080345200033C1512C03F
-:1062C000241400013C1080002411FF800E000245C0
-:1062D000000000008F8700488F8B00188F89001402
-:1062E0008CEA00EC8CE800E8014B302B01092823F4
-:1062F00000A6102314400006014B18231440000E82
-:106300003C05800002A3602B1180000B0000000000
-:106310003C0560008CEE00EC8CED00E88CA4180CC1
-:10632000AF8E001804800053AF8D00148F8F0010C3
-:10633000ADF400003C0580008CBF00003BF900017B
-:10634000333800011700FFE13C0380008C6201003C
-:1063500024060C0010460009000000008C680100B3
-:106360002D043080548000103C0480008C690100B2
-:106370002D2331811060000C3C0480008CAA0100A8
-:1063800011460004000020218CA6010024C5FF81D5
-:1063900030A400FF8E0B01000E000269AE0B00243A
-:1063A0000A00034F3C0480008C8D01002DAC3300AB
-:1063B00011800022000000003C0708008CE70098D4
-:1063C00024EE00013C010800AC2E00983C04800043
-:1063D0008C8201001440000300000000566000148D
-:1063E0003C0440008C9F01008C9801000000982123
-:1063F00003F1C82400193940330F007F00EF7025E6
-:1064000001D26825AC8D08308C8C01008C85010090
-:10641000258B0100017130240006514030A3007F1C
-:106420000143482501324025AC8808303C04400037
-:10643000AE0401380A00030E000000008C99010030
-:10644000240F0020AC99002092F80000330300FFD5
-:10645000106F000C241F0050547FFFDD3C048000AF
-:106460008C8401000E00154E000000000A00034F4E
-:106470003C04800000963824ACA7180C0A000327BF
-:106480008F8F00108C8501000E0008F72404008017
-:106490000A00034F3C04800000A4102B24030001D9
-:1064A00010400009000030210005284000A4102BF6
-:1064B00004A00003000318405440FFFC00052840DE
-:1064C0005060000A0004182B0085382B54E00004AB
-:1064D0000003184200C33025008520230003184222
-:1064E0001460FFF9000528420004182B03E000089F
-:1064F00000C310213084FFFF30C600FF3C0780003E
-:106500008CE201B80440FFFE00064C000124302557
-:106510003C08200000C820253C031000ACE00180AE
-:10652000ACE50184ACE4018803E00008ACE301B809
-:106530003C0660008CC5201C2402FFF03083020062
-:10654000308601001060000E00A2282434A500014E
-:106550003087300010E0000530830C0034A50004C3
-:106560003C04600003E00008AC85201C1060FFFDC7
-:106570003C04600034A5000803E00008AC85201C42
-:1065800054C0FFF334A500020A0003B03087300086
-:1065900027BDFFE8AFB00010AFBF00143C0760009C
-:1065A000240600021080001100A080218F83005873
-:1065B0000E0003A78C6400188F8200580000202171
-:1065C000240600018C45000C0E000398000000001A
-:1065D0001600000224020003000010218FBF0014E7
-:1065E0008FB0001003E0000827BD00188CE8201CC5
-:1065F0002409FFF001092824ACE5201C8F870058EE
-:106600000A0003CD8CE5000C3C02600E00804021A6
-:1066100034460100240900180000000000000000BA
-:10662000000000003C0A00503C0380003547020097
-:10663000AC68003834640400AC65003CAC670030E2
-:106640008C6C0000318B00201160FFFD2407FFFFE0
-:106650002403007F8C8D00002463FFFF248400044A
-:10666000ACCD00001467FFFB24C60004000000004E
-:10667000000000000000000024A402000085282B78
-:106680003C0300203C0E80002529FFFF010540212E
-:10669000ADC300301520FFE00080282103E0000892
-:1066A000000000008F82005827BDFFD8AFB3001C48
-:1066B000AFBF0020AFB20018AFB10014AFB00010F0
-:1066C00094460002008098218C5200182CC300814F
-:1066D0008C4800048C4700088C51000C8C49001039
-:1066E000106000078C4A00142CC4000414800013AE
-:1066F00030EB000730C5000310A0001000000000C0
-:106700002410008B02002021022028210E00039873
-:10671000240600031660000224020003000010217A
-:106720008FBF00208FB3001C8FB200188FB10014F0
-:106730008FB0001003E0000827BD00281560FFF1AE
-:106740002410008B3C0C80003C030020241F00011F
-:10675000AD830030AF9F0044000000000000000047
-:10676000000000002419FFF024D8000F031978243A
-:106770003C1000D0AD88003801F0702524CD000316
-:106780003C08600EAD87003C35850400AD8E0030BE
-:10679000000D38823504003C3C0380008C6B000007
-:1067A000316200201040FFFD0000000010E00008F2
-:1067B00024E3FFFF2407FFFF8CA800002463FFFFF2
-:1067C00024A50004AC8800001467FFFB24840004A7
-:1067D0003C05600EACA60038000000000000000080
-:1067E000000000008F8600543C0400203C0780001D
-:1067F000ACE4003054C000060120202102402021DA
-:106800000E0003A7000080210A00041D02002021C1
-:106810000E0003DD01402821024020210E0003A7C5
-:10682000000080210A00041D0200202127BDFFE096
-:10683000AFB200183092FFFFAFB10014AFBF001C21
-:10684000AFB000101640000D000088210A0004932C
-:106850000220102124050003508500278CE5000C40
-:106860000000000D262800013111FFFF24E2002066
-:106870000232802B12000019AF8200588F82004430
-:10688000144000168F8700583C0670003C0320001F
-:106890008CE5000000A62024148300108F84006083
-:1068A000000544023C09800000A980241480FFE90F
-:1068B000310600FF2CCA000B5140FFEB26280001D7
-:1068C000000668803C0E080025CE575801AE6021B6
-:1068D0008D8B0000016000080000000002201021E4
-:1068E0008FBF001C8FB200188FB100148FB0001042
-:1068F00003E0000827BD00200E0003982404008454
-:106900001600FFD88F8700580A000474AF8000601B
-:10691000020028210E0003BF240400018F870058C5
-:106920000A000474AF820060020028210E0003BF39
-:10693000000020210A0004A38F8700580E000404E1
-:10694000020020218F8700580A000474AF82006083
-:1069500030AFFFFF000F19C03C0480008C9001B8DD
-:106960000600FFFE3C1920043C181000AC83018097
-:10697000AC800184AC990188AC9801B80A00047518
-:106980002628000190E2000390E30002000020218D
-:106990000002FE0000033A0000FF2825240600083C
-:1069A0000E000398000000001600FFDC2402000324
-:1069B0008F870058000010210A000474AF82006025
-:1069C00090E8000200002021240600090A0004C308
-:1069D00000082E0090E4000C240900FF308500FF21
-:1069E00010A900150000302190F9000290F8000372
-:1069F000308F00FF94EB000400196E000018740043
-:106A0000000F62000186202501AE5025014B28258C
-:106A10003084FF8B0A0004C32406000A90E30002BE
-:106A200090FF0004000020210003360000DF28252D
-:106A30000A0004C32406000B0A0004D52406008BB8
-:106A4000000449C23127003F000443423C02800059
-:106A500000082040240316802CE60020AC43002CC4
-:106A600024EAFFE02482000114C0000330A900FFE3
-:106A700000801021314700FF000260803C0D800043
-:106A8000240A0001018D20213C0B000E00EA28049D
-:106A9000008B302111200005000538278CCE000026
-:106AA00001C5382503E00008ACC700008CD8000001
-:106AB0000307782403E00008ACCF000027BDFFE007
-:106AC000AFB10014AFB00010AFBF00183C076000BA
-:106AD0008CE408083402F0003C1160003083F000C0
-:106AE000240501C03C04800E000030211062000625
-:106AF000241000018CEA08083149F0003928E00030
-:106B00000008382B000780403C0D0200AE2D081411
-:106B1000240C16803C0B80008E2744000E000F8B47
-:106B2000AD6C002C120000043C02169124050001FB
-:106B3000120500103C023D2C345800E0AE384408E9
-:106B40003C1108008E31007C8FBF00183C066000AD
-:106B500000118540360F16808FB100148FB00010E1
-:106B60003C0E020027BD0020ACCF442003E000080B
-:106B7000ACCE08103C0218DA345800E0AE384408B5
-:106B80003C1108008E31007C8FBF00183C0660006D
-:106B900000118540360F16808FB100148FB00010A1
-:106BA0003C0E020027BD0020ACCF442003E00008CB
-:106BB000ACCE08100A0004EB240500010A0004EB27
-:106BC0000000282124020400A7820024A780001CC2
-:106BD000000020213C06080024C65A582405FFFF67
-:106BE00024890001000440803124FFFF01061821A0
-:106BF0002C87002014E0FFFAAC6500002404040098
-:106C0000A7840026A780001E000020213C06080063
-:106C100024C65AD82405FFFF248D0001000460809B
-:106C200031A4FFFF018658212C8A00201540FFFA6D
-:106C3000AD650000A7800028A7800020A780002263
-:106C4000000020213C06080024C65B582405FFFFF5
-:106C5000249900010004C0803324FFFF030678213B
-:106C60002C8E000415C0FFFAADE500003C05600065
-:106C70008CA73D002403E08F00E31024344601403C
-:106C800003E00008ACA63D002487007F000731C266
-:106C900024C5FFFF000518C2246400013082FFFFF5
-:106CA000000238C0A78400303C010800AC27003047
-:106CB000AF80002C0000282100002021000030219E
-:106CC0002489000100A728213124FFFF2CA81701E7
-:106CD000110000032C8300801460FFF924C600011A
-:106CE00000C02821AF86002C10C0001DA786002AF6
-:106CF00024CAFFFF000A11423C08080025085B581F
-:106D00001040000A00002021004030212407FFFF2E
-:106D1000248E00010004688031C4FFFF01A86021B7
-:106D20000086582B1560FFFAAD87000030A2001FC7
-:106D30005040000800043080240300010043C804D0
-:106D400000041080004878212738FFFF03E0000886
-:106D5000ADF8000000C820212405FFFFAC8500002D
-:106D600003E000080000000030A5FFFF30C6FFFF71
-:106D700030A8001F0080602130E700FF0005294295
-:106D80000000502110C0001D24090001240B000147
-:106D900025180001010B2004330800FF0126782686
-:106DA000390E00202DED00012DC2000101A2182591
-:106DB0001060000D014450250005C880032C4021BF
-:106DC0000100182110E0000F000A20278D040000A8
-:106DD000008A1825AD03000024AD00010000402109
-:106DE0000000502131A5FFFF252E000131C9FFFF12
-:106DF00000C9102B1040FFE72518000103E0000830
-:106E0000000000008D0A0000014440240A0005D162
-:106E1000AC68000027BDFFE830A5FFFF30C6FFFFCC
-:106E2000AFB00010AFBF001430E7FFFF00005021EB
-:106E30003410FFFF0000602124AF001F00C0482174
-:106E4000241800012419002005E0001601E010219B
-:106E50000002F943019F682A0009702B01AE40240B
-:106E600011000017000C18800064102110E00005CC
-:106E70008C4B000000F840040008382301675824B8
-:106E800000003821154000410000402155600016E7
-:106E90003169FFFF258B0001316CFFFF05E1FFEC3D
-:106EA00001E0102124A2003E0002F943019F682A5C
-:106EB0000009702B01AE40241500FFEB000C188078
-:106EC000154600053402FFFF020028210E0005B51B
-:106ED00000003821020010218FBF00148FB0001075
-:106EE00003E0000827BD00181520000301601821E9
-:106EF000000B1C0224080010306A00FF154000053A
-:106F0000306E000F250D000800031A0231A800FFA3
-:106F1000306E000F15C00005307F000325100004FF
-:106F200000031902320800FF307F000317E000055C
-:106F3000386900012502000200031882304800FF72
-:106F4000386900013123000110600004310300FFA3
-:106F5000250A0001314800FF310300FF000C6940A1
-:106F600001A34021240A000110CAFFD53110FFFF00
-:106F7000246E000131C800FF1119FFC638C9000195
-:106F80002D1F002053E0001C258B0001240D000163
-:106F90000A000648240E002051460017258B0001E8
-:106FA00025090001312800FF2D0900205120001281
-:106FB000258B000125430001010D5004014B1024D5
-:106FC000250900011440FFF4306AFFFF3127FFFF5D
-:106FD00010EE000C2582FFFF304CFFFF0000502117
-:106FE0003410FFFF312800FF2D0900205520FFF24B
-:106FF00025430001258B0001014648260A000602B0
-:10700000316CFFFF00003821000050210A000654B7
-:107010003410FFFF27BDFFD8AFB0001030F0FFFFE6
-:10702000AFB10014001039423211FFE000071080A8
-:10703000AFB3001C00B1282330D3FFFFAFB200185C
-:1070400030A5FFFF00809021026030210044202104
-:10705000AFBF00200E0005E03207001F022288218A
-:107060003403FFFF0240202102002821026030216A
-:1070700000003821104300093231FFFF02201021A7
-:107080008FBF00208FB3001C8FB200188FB1001487
-:107090008FB0001003E0000827BD00280E0005E0B7
-:1070A0000000000000408821022010218FBF002036
-:1070B0008FB3001C8FB200188FB100148FB0001076
-:1070C00003E0000827BD0028000424003C03600002
-:1070D000AC603D0810A00002348210063482101605
-:1070E00003E00008AC623D0427BDFFE0AFB0001034
-:1070F000309000FF2E020006AFBF001810400008BD
-:10710000AFB10014001030803C03080024635784A2
-:1071100000C328218CA400000080000800000000AB
-:10712000000020218FBF00188FB100148FB0001015
-:107130000080102103E0000827BD00209791002A5D
-:1071400016200051000020213C020800904200332C
-:107150000A0006BB00000000978D002615A0003134
-:10716000000020210A0006BB2402000897870024A3
-:1071700014E0001A00001821006020212402000100
-:107180001080FFE98FBF0018000429C2004530219C
-:1071900000A6582B1160FFE43C0880003C0720004B
-:1071A000000569C001A76025AD0C00203C038008E4
-:1071B0002402001F2442FFFFAC6000000441FFFDD9
-:1071C0002463000424A5000100A6702B15C0FFF560
-:1071D000000569C00A0006A58FBF00189787001C2C
-:1071E0003C04080024845A58240504000E0006605C
-:1071F00024060001978B002424440001308AFFFFFD
-:107200002569FFFF2D48040000402821150000409B
-:10721000A789002424AC3800000C19C00A0006B964
-:10722000A780001C9787001E3C04080024845AD8BD
-:10723000240504000E00066024060001979900262C
-:10724000244400013098FFFF272FFFFF2F0E04007A
-:107250000040882115C0002CA78F0026A780001EA3
-:107260003A020003262401003084FFFF0E00068D41
-:107270002C4500010011F8C027F00100001021C0CA
-:107280000A0006BB240200089785002E978700227B
-:107290003C04080024845B580E00066024060001AC
-:1072A0009787002A8F89002C2445000130A8FFFF12
-:1072B00024E3FFFF0109302B0040802114C0001897
-:1072C000A783002AA7800022978500300E000F7543
-:1072D00002002021244A05003144FFFF0E00068DE4
-:1072E000240500013C05080094A500320E000F752E
-:1072F00002002021244521003C0208009042003376
-:107300000A0006BB000521C00A0006F3A784001E80
-:1073100024AC3800000C19C00A0006B9A784001C70
-:107320000A00070DA7850022308400FF27BDFFE873
-:107330002C820006AFBF0014AFB000101040001543
-:1073400000A03821000440803C0308002463579CBF
-:10735000010328218CA40000008000080000000028
-:1073600024CC007F000751C2000C59C23170FFFFCE
-:107370002547C40030E5FFFF2784001C02003021B0
-:107380000E0005B52407000197860028020620217B
-:10739000A78400288FBF00148FB0001003E00008FE
-:1073A00027BD00183C0508008CA50030000779C2F5
-:1073B0000E00038125E4DF003045FFFF3C04080098
-:1073C00024845B58240600010E0005B52407000143
-:1073D000978E002A8FBF00148FB0001025CD0001BA
-:1073E00027BD001803E00008A78D002A0007C9C2C6
-:1073F0002738FF00001878C231F0FFFF3C04080076
-:1074000024845AD802002821240600010E0005B564
-:1074100024070001978D0026260E0100000E84002F
-:1074200025AC00013C0B6000A78C0026AD603D0838
-:1074300036040006000030213C0760008CE23D0469
-:10744000305F000617E0FFFD24C9000100061B00A5
-:10745000312600FF006440252CC50004ACE83D0443
-:1074600014A0FFF68FBF00148FB0001003E00008D7
-:1074700027BD0018000751C22549C8002406000195
-:10748000240700013C04080024845A580E0005B566
-:107490003125FFFF978700248FBF00148FB00010A5
-:1074A00024E6000127BD001803E00008A786002499
-:1074B0003C0660183C090800252900FCACC9502C8A
-:1074C0008CC850003C0580003C020002350700805B
-:1074D000ACC750003C04080024841FE03C030800B3
-:1074E00024631F98ACA50008ACA2000C3C01080066
-:1074F000AC2459A43C010800AC2359A803E00008BF
-:107500002402000100A030213C1C0800279C59AC3B
-:107510003C0C04003C0B0002008B3826008C4026FB
-:107520002CE200010007502B2D050001000A4880C5
-:107530003C030800246359A4004520250123182199
-:107540001080000300001021AC660000240200013E
-:1075500003E00008000000003C1C0800279C59AC18
-:107560003C0B04003C0A0002008A3026008B3826BF
-:107570002CC200010006482B2CE5000100094080C8
-:107580003C030800246359A4004520250103182169
-:1075900010800005000010213C0C0800258C1F986D
-:1075A000AC6C00002402000103E0000800000000B1
-:1075B0003C0900023C080400008830260089382677
-:1075C0002CC30001008028212CE400010083102539
-:1075D0001040000B000030213C1C0800279C59ACD7
-:1075E0003C0A80008D4E00082406000101CA68256F
-:1075F000AD4D00088D4C000C01855825AD4B000C9D
-:1076000003E0000800C010213C1C0800279C59AC76
-:107610003C0580008CA6000C0004202724020001F9
-:1076200000C4182403E00008ACA3000C3C020002D4
-:107630001082000B3C0560003C070400108700032B
-:107640000000000003E00008000000008CA908D042
-:10765000240AFFFD012A402403E00008ACA808D05A
-:107660008CA408D02406FFFE0086182403E000083E
-:10767000ACA308D03C05601A34A600108CC300806F
-:1076800027BDFFF88CC50084AFA3000093A40000C1
-:107690002402001010820003AFA5000403E00008DC
-:1076A00027BD000893A7000114E0001497AC000266
-:1076B00097B800023C0F8000330EFFFC01CF682119
-:1076C000ADA50000A3A000003C0660008CC708D058
-:1076D0002408FFFE3C04601A00E82824ACC508D04A
-:1076E0008FA300048FA200003499001027BD00086A
-:1076F000AF22008003E00008AF2300843C0B800031
-:10770000318AFFFC014B48218D2800000A00080C3B
-:10771000AFA8000427BDFFE8AFBF00103C1C080065
-:10772000279C59AC3C0580008CA4000C8CA2000462
-:107730003C0300020044282410A0000A00A31824DF
-:107740003C0604003C0400021460000900A610245A
-:107750001440000F3C0404000000000D3C1C080015
-:10776000279C59AC8FBF001003E0000827BD00180C
-:107770003C0208008C4259A40040F80900000000B7
-:107780003C1C0800279C59AC0A0008358FBF00102C
-:107790003C0208008C4259A80040F8090000000093
-:1077A0000A00083B000000003C0880008D0201B880
-:1077B0000440FFFE35090180AD2400003C031000A9
-:1077C00024040040AD250004A1240008A1260009DE
-:1077D000A527000A03E00008AD0301B83084FFFFCD
-:1077E0000080382130A5FFFF000020210A00084555
-:1077F000240600803087FFFF8CA400002406003898
-:107800000A000845000028218F8300788F860070C9
-:107810001066000B008040213C07080024E75B68ED
-:10782000000328C000A710218C440000246300013D
-:10783000108800053063000F5466FFFA000328C06B
-:1078400003E00008000010213C07080024E75B6CFF
-:1078500000A7302103E000088CC200003C03900028
-:1078600034620001008220253C038000AC640020CB
-:107870008C65002004A0FFFE0000000003E000086B
-:10788000000000003C0280003443000100832025FA
-:1078900003E00008AC44002027BDFFE0AFB10014B6
-:1078A0003091FFFFAFB00010AFBF001812200013DF
-:1078B00000A080218CA20000240400022406020003
-:1078C0001040000F004028210E0007250000000096
-:1078D00000001021AE000000022038218FBF0018E8
-:1078E0008FB100148FB0001000402021000028212B
-:1078F000000030210A00084527BD00208CA20000AE
-:10790000022038218FBF00188FB100148FB00010F3
-:107910000040202100002821000030210A000845F5
-:1079200027BD002000A010213087FFFF8CA5000498
-:107930008C4400000A000845240600068F83FD9C45
-:1079400027BDFFE8AFBF0014AFB00010906700087C
-:10795000008010210080282130E600400000202116
-:1079600010C000088C5000000E0000BD0200202155
-:10797000020020218FBF00148FB000100A000548BC
-:1079800027BD00180E0008A4000000000E0000BD76
-:1079900002002021020020218FBF00148FB00010B0
-:1079A0000A00054827BD001827BDFFE0AFB0001052
-:1079B0008F90FD9CAFBF001CAFB20018AFB1001498
-:1079C00092060001008088210E00087230D2000467
-:1079D00092040005001129C2A6050000348300406E
-:1079E000A20300050E00087C022020210E00054A9B
-:1079F0000220202124020001AE02000C02202821D6
-:107A0000A602001024040002A602001224060200AE
-:107A1000A60200140E000725A60200161640000F4D
-:107A20008FBF001C978C00743C0B08008D6B007896
-:107A30002588FFFF3109FFFF256A0001012A382B45
-:107A400010E00006A78800743C0F6006240E0016A4
-:107A500035ED0010ADAE00508FBF001C8FB2001886
-:107A60008FB100148FB0001003E0000827BD002084
-:107A700027BDFFE0AFB10014AFBF0018AFB00010DA
-:107A80001080000400A088212402008010820007DA
-:107A9000000000000000000D8FBF00188FB100141F
-:107AA0008FB0001003E0000827BD00200E00087210
-:107AB00000A020218F86FD9C0220202190C500057A
-:107AC0000E00087C30B000FF2403003E1603FFF1D7
-:107AD0003C0680008CC401780480FFFE34C801405D
-:107AE000240900073C071000AD11000002202021EE
-:107AF000A10900048FBF00188FB100148FB00010CF
-:107B0000ACC701780A0008C527BD002027BDFFE0EB
-:107B1000AFB00010AFBF0018AFB100143C10800030
-:107B20008E110020000000000E00054AAE04002067
-:107B3000AE1100208FBF00188FB100148FB000105D
-:107B400003E0000827BD00203084FFFF00803821BB
-:107B50002406003500A020210A0008450000282145
-:107B60003084FFFF008038212406003600A0202149
-:107B70000A0008450000282127BDFFD0AFB500242A
-:107B80003095FFFFAFB60028AFB40020AFBF002C88
-:107B9000AFB3001CAFB20018AFB10014AFB000100B
-:107BA00030B6FFFF12A000270000A0218F920058DE
-:107BB0008E4300003C0680002402004000033E0289
-:107BC00000032C0230E4007F006698241482001D1C
-:107BD00030A500FF8F8300682C68000A1100001098
-:107BE0008F8D0044000358803C0C0800258C57B84A
-:107BF000016C50218D4900000120000800000000A8
-:107C000002D4302130C5FFFF0E0008522404008446
-:107C1000166000028F920058AF8000688F8D00447C
-:107C20002659002026980001032090213314FFFFDD
-:107C300015A00004AF9900580295202B1480FFDC9A
-:107C400000000000028010218FBF002C8FB600289A
-:107C50008FB500248FB400208FB3001C8FB20018A2
-:107C60008FB100148FB0001003E0000827BD003072
-:107C70002407003414A70149000000009247000EB9
-:107C80008F9FFDA08F90FD9C24181600A3E700197C
-:107C90009242000D3C0880003C07800CA3E20018D3
-:107CA000964A00123C0D60003C117FFFA60A005C62
-:107CB000964400103623FFFF240200053099FFFF91
-:107CC000AE1900548E46001CAD1800288CEF000041
-:107CD0008DAE444801E6482601C93021AE06003881
-:107CE0008E05003824CB00013C0E7F00AE05003C21
-:107CF0008E0C003CAFEC0004AE0B00208E13002075
-:107D0000AE13001CA3E0001BAE03002CA3E2001284
-:107D10008E4A001424130050AE0A00348E0400343E
-:107D2000AFE400148E590018AE1900489258000CA8
-:107D3000A218004E920D000835AF0020A20F0008D7
-:107D40008E090018012E282434AC4000AE0C001817
-:107D5000920B0000317200FF1253027F2403FF8058
-:107D60003C04080024845BE80E0008AA0000000020
-:107D70003C1108008E315BE80E00087202202021C1
-:107D80002405000424080001A2050025022020216A
-:107D90000E00087CA20800053C0580008CB001782C
-:107DA0000600FFFE8F92005834AE0140240F0002FF
-:107DB0003C091000ADD10000A1CF0004ACA90178AE
-:107DC0000A000962AF8000682CAD003751A0FF9413
-:107DD0008F8D0044000580803C110800263157E05B
-:107DE000021178218DEE000001C0000800000000A3
-:107DF0002411000414B1008C3C0780003C080800EA
-:107E00008D085BE88F86FD9CACE800208E4500085D
-:107E10008F99FDA0240D0050ACC500308E4C000899
-:107E2000ACCC00508E4B000CACCB00348E43001019
-:107E3000ACC300388E4A0010ACCA00548E42001405
-:107E4000ACC2003C8E5F0018AF3F00048E50001C97
-:107E5000ACD0002090C40000309800FF130D024AFF
-:107E6000000000008CC400348CD00030009030231F
-:107E700004C000F12404008C126000EE2402000310
-:107E80000A000962AF8200682419000514B900666F
-:107E90003C0580003C0808008D085BE88F86FD9C4F
-:107EA000ACA800208E4C00048F8AFDA0240720007F
-:107EB000ACCC001C924B000824120008A14B001906
-:107EC0008F82005890430009A14300188F85005805
-:107ED00090BF000A33E400FF1092001028890009C7
-:107EE000152000BA240E0002240D0020108D000B76
-:107EF000340780002898002117000008240740005C
-:107F000024100040109000053C0700012419008057
-:107F1000109900023C070002240740008CC20018A0
-:107F20003C03FF00004350240147F825ACDF001854
-:107F300090B2000BA0D200278F8300589464000CED
-:107F4000108001FE000000009467000C3C1F8000C0
-:107F50002405FFBFA4C7005C9063000E2407000443
-:107F6000A0C300088F820058904A000FA0CA0009E1
-:107F70008F8900588D3200108FE400740244C823AA
-:107F8000ACD900588D300014ACD0002C95380018B6
-:107F9000330DFFFFACCD00409531001A322FFFFFAB
-:107FA000ACCF00448D2E001CACCE00489128000EB2
-:107FB000A0C8000890CC000801855824126001B6C2
-:107FC000A0CB00088F9200580A000962AF870068B2
-:107FD0002406000614A600143C0E80003C0F080086
-:107FE0008DEF5BE88F85FD98ADCF00208E4900189E
-:107FF0008F86FD9C8F8BFDA0ACA900008CC800383B
-:1080000024040005ACA800048CCC003C1260008164
-:10801000AD6C00000A000962AF84006824110007FB
-:1080200010B1004B240400063C05080024A55BE8C1
-:108030000E000881240400818F9200580013102B39
-:108040000A000962AF820068241F002314BFFFF6F4
-:108050003C0C80003C0508008CA55BE88F8BFDA0E4
-:10806000AD8500208F91FD9C8E4600042564002084
-:1080700026450014AE260028240600030E000F81BA
-:10808000257000308F87005802002021240600034D
-:108090000E000F8124E500083C04080024845BE8FE
-:1080A0000E0008AA0000000092230000240A0050DD
-:1080B000306200FF544AFFE18F9200580E000F6CAF
-:1080C000000000000A000A6A8F920058240800335A
-:1080D00014A800323C0380003C1108008E315BE89C
-:1080E0008F8FFDA0AC7100208E420008240D002867
-:1080F0008F89FD9CADE200308E4A000C24060009F9
-:10810000ADEA00348E5F0010ADFF00388E440014DD
-:10811000ADE400208E590018ADF900248E58001CE3
-:10812000ADF80028A1ED00118E4E00041260003160
-:10813000AD2E00288F9200580A000962AF860068B1
-:10814000240D002214ADFFB8000000002404000735
-:108150003C1008008E105BE83C188000AF10002037
-:108160005660FEAEAF8400683C04080024845BE8DF
-:108170000E0008AA241300508F84FD9C90920000EA
-:10818000325900FF1333014B000000008F9200585A
-:10819000000020210A000962AF8400683C05080045
-:1081A00024A55BE80E000858240400810A000A6A2E
-:1081B0008F92005802D498213265FFFF0E000852BA
-:1081C000240400840A0009628F920058108EFF5325
-:1081D000240704002887000310E00179241100041B
-:1081E000240F0001548FFF4D240740000A000A228B
-:1081F000240701003C05080024A55BE80E0008A444
-:10820000240400828F920058000030210A00096285
-:10821000AF8600683C04080024845BE88CC2003808
-:108220000E0008AA8CC3003C8F9200580A000AC0B6
-:1082300000002021240400823C05080024A55BE8FE
-:108240000E0008A4000000008F92005800001021CA
-:108250000A000962AF8200688E5000048F91FD9C75
-:108260003C078000ACF00020922C00050200282181
-:10827000318B0002156001562404008A8F92FDA004
-:108280002404008D9245001B30A6002014C001502C
-:1082900002002821922E00092408001231C900FF93
-:1082A0001128014B240400810E00087202002021D5
-:1082B0009258001B240F000402002021370D0042B9
-:1082C000A24D001B0E00087CA22F00253C0580005B
-:1082D0008CA401780480FFFE34B90140241F000201
-:1082E000AF300000A33F00048F9200583C101000F4
-:1082F000ACB001780A000A6B0013102B8E500004FA
-:108300008F91FD9C3C038000AC700020922A0005F8
-:108310000200282131420002144000172404008A80
-:10832000922C00092412000402002821318B00FF46
-:1083300011720011240400810E0008720200202135
-:108340008F89FDA0240800122405FFFE912F001B39
-:108350000200202135EE0020A12E001BA2280009DA
-:108360009226000500C538240E00087CA2270005CF
-:1083700002002821000020210E0009330000000027
-:108380000A000A6A8F9200588E4C00043C07800055
-:108390003C10080026105BE8ACEC00203C01080013
-:1083A000AC2C5BE8924B0003317100041220013BBE
-:1083B0008F84FD9C24020006A0820009924F001BBE
-:1083C000240EFFC031E9003F012E4025A08800089F
-:1083D0009245000330A6000114C0013200000000E5
-:1083E0008E420008AE0200083C0208008C425BF09E
-:1083F000104001318F90FDA0000219C28F8DFD9CAD
-:10840000A603000C8E4A000C24180001240400145A
-:10841000AE0A002C8E420010AE02001C965F0016C1
-:10842000A61F003C96590014A619003EADB8000CDA
-:10843000A5B80010A5B80012A5B80014A5B800167C
-:1084400012600144A2040011925100033232000272
-:108450002E5300018F920058266200080A0009621C
-:10846000AF8200688E4400043C1980003C068008FE
-:10847000AF2400208E45000890D80000240D005045
-:10848000331100FF122D009C2407008824060009E8
-:108490000E000845000000000A000A6A8F9200588A
-:1084A0008E5000043C0980003C118008AD30002053
-:1084B0009228000024050050310400FF10850110AF
-:1084C0002407008802002021000028210E00084512
-:1084D0002406000E922D00002418FF80020028219F
-:1084E00001B8802524040004240600300E0007256E
-:1084F000A23000000A000A6A8F9200588E500004D1
-:108500008F91FDA03C028000AC500020923F001BE8
-:1085100033F900101320006C240700810200202191
-:10852000000028212406001F0E000845000000005E
-:108530000A000A6A8F9200588E44001C0E00085DE3
-:1085400000000000104000E3004048218F880058E0
-:1085500024070089012020218D05001C240600012C
-:108560000E000845000000000A000A6A8F920058B9
-:10857000964900023C10080026105BE831280004F0
-:10858000110000973C0460008E4E001C3C0F8000E0
-:10859000ADEE00203C010800AC2E5BE896470002DF
-:1085A00030E40001148000E6000000008E42000468
-:1085B000AE0200083C1008008E105BF0120000ECC8
-:1085C0003C0F80008F92FD9C241000018E4E0018FD
-:1085D0008F8DFDA08F9FFD9801CF4825AE490018D3
-:1085E000A2400005AE50000C3C0808008D085BF06E
-:1085F0008F840058A6500010000839C2A6500012FF
-:10860000A6500014A6500016A5A7000C8C8C0008DC
-:108610008F8B00588F8A0058ADAC002C8D63000CF6
-:1086200024070002ADA3001C91460010A1A6001172
-:108630008F82005890450011A3E500088F990058DB
-:1086400093380012A258004E8F910058922F0013B9
-:10865000A1AF00128F920058964E0014A5AE003CB8
-:1086600096490016A5A9003E8E480018ADA8001432
-:108670005660FD6AAF8700683C05080024A55BE8EA
-:108680000E000881000020218F9200580000382140
-:108690000A000962AF8700683C05080024A55BE872
-:1086A0000E0008A4240400828F9200580A000A4D8C
-:1086B000000038210E000F6C000000008F9200585F
-:1086C0000A000AC0000020210E00087202002021CA
-:1086D0009223001B02002021346A00100E00087C47
-:1086E000A22A001B000038210200202100002821BE
-:1086F0000A000BA52406001F9242000C305F000107
-:1087000013E0000300000000964A000EA4CA002CEB
-:10871000924B000C316300025060000600003821CB
-:108720008E470014964C0012ACC7001CA4CC001A53
-:10873000000038210A000B7F240600093C050800D0
-:1087400024A55BE80E0008A42404008B8F92005837
-:108750000A000A4D0013382B3C0C08008D8C5BE896
-:1087600024DFFFFE25930100326B007F016790211B
-:1087700002638824AD110028AE4600E0AE4000E45C
-:108780000A0009B3AE5F001CACC000543C0D0800E9
-:108790008DAD5BE83C18800C37090100ACED00287A
-:1087A0008E510014AD3100E08E4F0014AD2F00E467
-:1087B0008E4E001025C7FFFE0A0009F4AD27001CED
-:1087C0005491FDD6240740000A000A222407100015
-:1087D0000E00092D000000000A000A6A8F9200585E
-:1087E0008C83442C3C12DEAD3651BEEF3C010800B8
-:1087F000AC205BE810710062000000003C196C6264
-:1088000037387970147800082404000297850074C2
-:108810009782006C2404009200A2F82B13E0001948
-:1088200002002821240400020E00069524050200FF
-:108830003C068000ACC200203C010800AC225BE892
-:108840001040000D8F8C0058240A002824040003D7
-:10885000918B0010316300FF546A00012404000171
-:108860000E0000810000000010400004240400837A
-:108870000A000BC28F920058240400833C050800B4
-:1088800024A55BE80E000881000000008F920058CC
-:108890000013382B0A000962AF8700680A000B49F1
-:1088A000240200128E4400080E00085D0000000043
-:1088B0000A000B55AE0200083C05080024A55BE841
-:1088C0000E000858240400878F9200580A000B728B
-:1088D0000013102B240400040E000695240500301C
-:1088E0001440002A004048218F8800582407008344
-:1088F000012020218D05001C0A000BB32406000175
-:108900008F8300788F8600701066FEEE000038219D
-:108910003C07080024E75B6C000320C00087282187
-:108920008CAE000011D0005D246F000131E3000F18
-:108930005466FFFA000320C00A000B8C00003821A7
-:108940008E4400040E00085D000000000A000BC801
-:10895000AE0200083C05080024A55BE80E0008A450
-:10896000240400828F9200580A000B72000010212C
-:108970003C05080024A55BE80A000C7C2404008761
-:108980008C83442C0A000C5B3C196C628F88005865
-:108990003C0780083C0C8000240B0050240A000196
-:1089A000AD820020A0EB0000A0EA000191030004CA
-:1089B000A0E3001891040005A0E400199106000648
-:1089C0003C04080024845B6CA0E6001A91020007B6
-:1089D0003C06080024C65B68A0E2001B9105000865
-:1089E000A0E5001C911F0009A0FF001D9119000ABD
-:1089F000A0F9001E9118000BA0F8001F9112000CA6
-:108A0000A0F200209111000DA0F100219110000EA4
-:108A1000A0F00022910F000FA0EF0023910E001094
-:108A2000A0EE0024910D0011A0ED0025950C00147E
-:108A3000A4EC0028950B00168F8A00708F920078A6
-:108A4000A4EB002A95030018000A10C02545000178
-:108A5000A4E3002C8D1F001C0044C0210046C82147
-:108A600030A5000FAF3F0000AF09000010B20006B4
-:108A7000AF850070000038218D05001C01202021E9
-:108A80000A000BB32406000124AD000131A7000F3A
-:108A9000AF8700780A000CF9000038213C06080076
-:108AA00024C65B680086902100003821ACA000003D
-:108AB0000A000B8CAE4000003C0482013C036000C5
-:108AC00034820E02AC603D68AF80009803E000087D
-:108AD000AC623D6C27BDFFE8AFB000103090FFFFE7
-:108AE000001018422C620041AFBF00141440000275
-:108AF00024040080240300403C010800AC300060E6
-:108B00003C010800AC2300640E000F7500602821B2
-:108B1000244802BF2409FF8001092824001039805D
-:108B2000001030408FBF00148FB0001000A720212C
-:108B300000861821AF8300803C010800AC25005856
-:108B40003C010800AC24005C03E0000827BD0018CD
-:108B5000308300FF30C6FFFF30E400FF3C08800098
-:108B60008D0201B80440FFFE000354000144382583
-:108B70003C09600000E920253C031000AD050180A0
-:108B8000AD060184AD04018803E00008AD0301B81F
-:108B90008F8500583C0A6012354800108CAC0004E8
-:108BA0003C0D600E35A60010318B00062D690001CA
-:108BB000AD0900C48CA70004ACC731808CA20008AA
-:108BC00094A40002ACC231848CA3001C0460000396
-:108BD000A784009003E00008000000008CAF00189C
-:108BE000ACCF31D08CAE001C03E00008ACCE31D449
-:108BF0008F8500588F87FF288F86FF308CAE00044A
-:108C00003C0F601235E80010ACEE00788CAD000827
-:108C1000ACED007C8CAC0010ACCC004C8CAB000CF0
-:108C2000ACCB004894CA00543C0208008C4200447B
-:108C300025490001A4C9005494C400543083FFFFA7
-:108C400010620017000000003C0208008C42004047
-:108C5000A4C200528CA30018ACE300308CA2001414
-:108C6000ACE2002C8CB90018ACF900388CB80014B8
-:108C700024050001ACF800348D0600BC50C5001975
-:108C80008D0200B48D0200B8A4E2004894E40048CC
-:108C9000A4E4004A94E800EA03E000083102FFFF80
-:108CA0003C0208008C420024A4C00054A4C200521C
-:108CB0008CA30018ACE300308CA20014ACE2002CB2
-:108CC0008CB90018ACF900388CB8001424050001E8
-:108CD000ACF800348D0600BC54C5FFEB8D0200B823
-:108CE0008D0200B4A4E2004894E40048A4E4004AE1
-:108CF00094E800EA03E000083102FFFF8F86005885
-:108D00003C0480008CC900088CC80008000929C0F8
-:108D1000000839C0AC87002090C30007306200040F
-:108D20001040003EAF85009490CB0007316A0008E8
-:108D30001140003D8F87FF2C8CCD000C8CCE001491
-:108D400001AE602B11800036000000008CC2000CC8
-:108D5000ACE200708CCB00188F85FF288F88FF3025
-:108D6000ACEB00748CCA00102402FFF8ACAA00D847
-:108D70008CC9000CAD0900608CC4001CACA400D0F0
-:108D800090E3007C0062C824A0F9007C90D8000722
-:108D9000330F000811E000040000000090ED007C9B
-:108DA00035AC0001A0EC007C90CF000731EE000153
-:108DB00011C000060000000090E3007C241800347D
-:108DC00034790002A0F9007CACB800DC90C2000746
-:108DD0003046000210C000040000000090E8007C53
-:108DE00035040004A0E4007C90ED007D3C0B600E97
-:108DF000356A001031AC003FA0EC007D8D4931D4C4
-:108E00003127000110E00002240E0001A0AE00098D
-:108E100094AF00EA03E0000831E2FFFF8F87FF2CE8
-:108E20000A000DAF8CC200140A000DB0ACE0007057
-:108E30008F8C005827BDFFD8AFB3001CAFB200180D
-:108E4000AFB00010AFBF0020AFB10014918F00157C
-:108E50003C13600E3673001031EB000FA38B009CA7
-:108E60008D8F00048D8B0008959F0012959900103E
-:108E70009584001A9598001E958E001C33EDFFFF17
-:108E8000332AFFFF3089FFFF3308FFFF31C7FFFFA1
-:108E90003C010800AC2D00243C010800AC29004432
-:108EA0003C010800AC2A0040AE683178AE67317CE6
-:108EB00091850015959100163C12601236520010F3
-:108EC00030A200FF3230FFFFAE623188AE5000B4F6
-:108ED00091830014959F0018240600010066C804C1
-:108EE00033F8FFFFAE5900B8AE5800BC918E0014A5
-:108EF000AF8F00843C08600631CD00FFAE4D00C04E
-:108F0000918A00159584000E3C07600A314900FFE4
-:108F1000AF8B00883084FFFFAE4900C835110010C8
-:108F20000E000D1034F004103C0208008C4200606A
-:108F30003C0308008C6300643C0608008CC60058A3
-:108F40003C0508008CA5005C8F8400808FBF00204A
-:108F5000AE23004CAE65319CAE030054AE4500DC40
-:108F6000AE6231A0AE6331A4AE663198AE22004845
-:108F70008FB3001CAE0200508FB10014AE4200E06F
-:108F8000AE4300E4AE4600D88FB000108FB2001898
-:108F90000A00057D27BD0028978500929783007CF5
-:108FA00027BDFFE8AFB0001000A3102BAFBF001427
-:108FB000240400058F900058104000552409000239
-:108FC0000E0006958F850080AF8200942404000374
-:108FD0001040004F240900023C0680000E00008172
-:108FE000ACC2002024070001240820001040004DDE
-:108FF00024040005978E00928F8AFF2C24090050CC
-:1090000025C50001A7850092A14900003C0D08007C
-:109010008DAD0064240380008F84FF28000D66005E
-:10902000AD4C0018A5400006954B000A8F85FF3017
-:109030002402FF8001633024A546000A915F000AE4
-:109040000000482103E2C825A159000AA0A0000899
-:10905000A140004CA08000D5961800029783009094
-:109060003C020004A49800EA960F00022418FFBFF7
-:1090700025EE2401A48E00BE8E0D0004ACAD00448C
-:109080008E0C0008ACAC0040A4A00050A4A000547A
-:109090008E0B000C240C0030AC8B00288E060010C8
-:1090A000AC860024A480003EA487004EA487005014
-:1090B000A483003CAD420074AC8800D8ACA800602A
-:1090C000A08700FC909F00D433F9007FA09900D4C2
-:1090D000909000D402187824A08F00D4914E007C88
-:1090E00035CD0001A14D007C938B009CAD480070F4
-:1090F000AC8C00DCA08B00D68F8800888F87008422
-:10910000AC8800C4AC8700C8A5400078A540007AB0
-:109110008FBF00148FB000100120102103E0000861
-:1091200027BD00188F8500940E0007258F860080CC
-:109130000A000E9F2409000227BDFFE0AFB0001017
-:109140008F900058AFB10014AFBF00188E09000413
-:109150000E00054A000921C08E0800048F84FF28F4
-:109160008F82FF30000839C03C068000ACC7002069
-:10917000948500EA904300131460001C30B1FFFF97
-:109180008F8CFF2C918B0008316A00401540000B3A
-:10919000000000008E0D0004022030218FBF001857
-:1091A0008FB100148FB00010240400220000382179
-:1091B000000D29C00A000D2F27BD00200E000098C9
-:1091C000000000008E0D0004022030218FBF001827
-:1091D0008FB100148FB00010240400220000382149
-:1091E000000D29C00A000D2F27BD00200E000090A1
-:1091F000000000008E0D0004022030218FBF0018F7
-:109200008FB100148FB00010240400220000382118
-:10921000000D29C00A000D2F27BD002027BDFFE04B
-:10922000AFB200183092FFFFAFB00010AFBF001C0C
-:10923000AFB100141240001E000080218F8600583C
-:109240008CC500002403000600053F02000514023F
-:1092500030E4000714830016304500FF2CA80006F8
-:1092600011000040000558803C0C0800258C58BCBB
-:10927000016C50218D490000012000080000000011
-:109280008F8E0098240D000111CD005024020002A1
-:10929000AF820098260900013130FFFF24C800206A
-:1092A0000212202B010030211480FFE5AF88005806
-:1092B000020010218FBF001C8FB200188FB1001464
-:1092C0008FB0001003E0000827BD00209387007EC8
-:1092D00054E00034000030210E000DE700000000D3
-:1092E0008F8600580A000EFF240200018F87009825
-:1092F0002405000210E50031240400130000282199
-:1093000000003021240700010E000D2F0000000096
-:109310000A000F008F8600588F83009824020002F5
-:109320001462FFF6240400120E000D9A00000000E3
-:109330008F85009400403021240400120E000D2F70
-:10934000000038210A000F008F8600588F83009894
-:109350002411000310710029241F0002107FFFCE8A
-:1093600026090001240400100000282100003021FB
-:109370000A000F1D240700018F91009824060002A7
-:109380001626FFF9240400100E000E410000000014
-:10939000144000238F9800588F8600580A000EFF53
-:1093A00024020003240400140E000D2F00002821C5
-:1093B0008F8600580A000EFF240200020E000EA93C
-:1093C000000000000A000F008F8600580E000D3FBD
-:1093D00000000000241900022404001400002821C9
-:1093E0000000302100003821AF9900980E000D2FA9
-:1093F000000000000A000F008F8600580E000D5775
-:10940000000000008F8500942419000200403021E4
-:1094100024040010000038210A000F56AF9900986C
-:109420000040382124040010970F0002000028217A
-:109430000E000D2F31E6FFFF8F8600580A000F0047
-:10944000AF9100988F84FF2C3C077FFF34E6FFFF2D
-:109450008C8500182402000100A61824AC83001893
-:1094600003E00008A08200053084FFFF30A5FFFF65
-:109470001080000700001821308200011040000217
-:1094800000042042006518211480FFFB00052840DD
-:1094900003E000080060102110C000070000000079
-:1094A0008CA2000024C6FFFF24A50004AC820000AB
-:1094B00014C0FFFB2484000403E000080000000047
-:1094C00010A0000824A3FFFFAC86000000000000ED
-:1094D000000000002402FFFF2463FFFF1462FFFA74
-:1094E0002484000403E0000800000000000411C010
-:1094F00003E000082442024027BDFFE8AFB000109F
-:1095000000808021AFBF00140E000F9600A0202124
-:1095100000504821240AFF808FBF00148FB0001034
-:10952000012A30243127007F3C08800A3C042100B6
-:1095300000E8102100C428253C03800027BD001846
-:10954000AC650024AF820038AC400000AC6500245C
-:1095500003E00008AC4000403C0D08008DAD005811
-:1095600000056180240AFF8001A45821016C482174
-:10957000012A30243127007F3C08800C3C04210064
-:1095800000E8102100C428253C038000AC650028B9
-:10959000AF82003403E00008AC40002430A5FFFF98
-:1095A0003C0680008CC201B80440FFFE3C086015F8
-:1095B00000A838253C031000ACC40180ACC0018475
-:1095C000ACC7018803E00008ACC301B83C0D08003B
-:1095D0008DAD005800056180240AFF8001A4582148
-:1095E000016C4021010A4824000931403107007F05
-:1095F00000C728253C04200000A418253C02800058
-:10960000AC43083003E00008AF80003427BDFFE81A
-:10961000AFB0001000808021AFBF00140E000F9685
-:1096200000A0202100504821240BFF80012B502452
-:10963000000A39403128007F3C0620008FBF00140B
-:109640008FB0001000E8282534C2000100A21825C0
-:109650003C04800027BD0018AC83083003E00008FC
-:10966000AF8000383C0580088CA700603C0680086D
-:109670000087102B144000112C8340008CA8006040
-:109680002D0340001060000F240340008CC90060CF
-:109690000089282B14A00002008018218CC30060D0
-:1096A00000035A42000B30803C0A0800254A59202A
-:1096B00000CA202103E000088C8200001460FFF340
-:1096C0002403400000035A42000B30803C0A08008B
-:1096D000254A592000CA202103E000088C8200009E
-:1096E0003C05800890A60008938400AB24C20001CA
-:1096F000304200FF3043007F1064000C0002382726
-:10970000A0A200083C0480008C85017804A0FFFE24
-:109710008F8A00A0240900023C081000AC8A014096
-:10972000A089014403E00008AC8801780A00101BFE
-:1097300030E2008027BDFFD8AFB200188F9200A49E
-:10974000AFBF0020AFB3001CAFB00010AFB100142A
-:109750008F9300348E5900283C1000803C0EFFEFA0
-:10976000AE7900008E580024A260000A35CDFFFFBC
-:10977000AE7800049251002C3C0BFF9F356AFFFF2E
-:10978000A271000C8E6F000C3C080040A271000B0F
-:1097900001F06025018D4824012A382400E8302595
-:1097A000AE66000C8E450004AE6000183C0400FF5D
-:1097B000AE6500148E43002C3482FFFFA6600008C3
-:1097C0000062F824AE7F00108E5900088F9000A030
-:1097D000964E0012AE7900208E51000C31D83FFF1A
-:1097E00000187980AE7100248E4D001401F06021C4
-:1097F00031CB0001AE6D00288E4A0018000C41C22A
-:10980000000B4B80AE6A002C8E46001C01093821EB
-:10981000A667001CAE660030964500028E4400200C
-:10982000A665001EAE64003492430033306200042B
-:1098300054400006924700003C0280083443010077
-:109840008C7F00D0AE7F0030924700008F860038BA
-:10985000A0C700309245003330A4000250800007BA
-:10986000925100018F880038240BFF80910A00304C
-:10987000014B4825A1090030925100018F9000381A
-:10988000240CFFBF2404FFDFA21100318F8D0038AC
-:109890003C1880083711008091AF003C31EE007F0A
-:1098A000A1AE003C8F890038912B003C016C502404
-:1098B000A12A003C8F9F00388E68001493E6003C7C
-:1098C0002D0700010007114000C4282400A218251C
-:1098D000A3E3003C8F87003896590012A4F90032A8
-:1098E0008E450004922E007C30B0000300107823D7
-:1098F00031ED000300AD102131CC000215800002D3
-:1099000024460034244600303C0280083443008062
-:10991000907F007C00BFC824333800041700000289
-:1099200024C2000400C010218F98003824190002BE
-:10993000ACE20034A3190000924F003F8F8E003834
-:109940003C0C8008358B0080A1CF00018F9100383E
-:10995000924D003F8E440004A62D0002956A005CE3
-:109960000E000FF43150FFFF00024B800209382532
-:109970003C08420000E82825AE2500048E4400384B
-:109980008F850038ACA400188E460034ACA6001CAD
-:10999000ACA0000CACA00010A4A00014A4A0001661
-:1099A000A4A00020A4A00022ACA000248E62001479
-:1099B00050400001240200018FBF00208FB3001C23
-:1099C0008FB200188FB100148FB00010ACA2000845
-:1099D0000A00101327BD002827BDFFC83C058008DA
-:1099E00034A40080AFBF0034AFBE0030AFB7002C4E
-:1099F000AFB60028AFB50024AFB40020AFB3001C51
-:109A0000AFB20018AFB10014AFB00010948300786B
-:109A10009482007A104300512405FFFF0080F0215A
-:109A20000A0011230080B821108B004D8FBF003435
-:109A30008F8600A03C1808008F18005C2411FF805E
-:109A40003C1680000306782101F18024AED0002C62
-:109A500096EE007A31EC007F3C0D800E31CB7FFF1B
-:109A6000018D5021000B4840012AA82196A4000036
-:109A70003C0808008D0800582405FF8030953FFF02
-:109A800001061821001539800067C8210325F82434
-:109A90003C02010003E290253338007F3C11800C2A
-:109AA000AED20028031190219250000D320F000415
-:109AB00011E0003702E0982196E3007A96E8007AF8
-:109AC00096E5007A2404800031077FFF24E300013B
-:109AD00030627FFF00A4F82403E2C825A6F9007ACB
-:109AE00096E6007A3C1408008E94006030D67FFF22
-:109AF00012D400C1000000008E5800188F8400A00E
-:109B000002A028212713FFFF0E000FCEAE53002C1A
-:109B100097D5007897D4007A12950010000028217C
-:109B20003C098008352401003C0A8008914800085F
-:109B3000908700D53114007F30E400FF0284302B81
-:109B400014C0FFB9268B0001938E00AB268C000158
-:109B5000008E682115ACFFB78F8600A08FBF003440
-:109B60008FBE00308FB7002C8FB600288FB5002431
-:109B70008FB400208FB3001C8FB200188FB1001477
-:109B80008FB0001000A0102103E0000827BD0038AE
-:109B900000C020210E000F99028028218E4B00105A
-:109BA0008E4C00308F84003824090002016C502351
-:109BB000AE4A0010A089000096E3005C8E4400309D
-:109BC0008F9100380E000FF43070FFFF00024380C9
-:109BD000020838253C02420000E22825AE25000498
-:109BE0008E5F00048F8A00388E590000240B000815
-:109BF000AD5F001CAD590018AD40000CAD40001029
-:109C00009246000A240400052408C00030D000FF5A
-:109C1000A550001496580008A55800169251000A45
-:109C20003C188008322F00FFA54F0020964E0008F8
-:109C300037110100A54E0022AD400024924D000BCB
-:109C400031AC00FFA54C0002A14B00018E49003051
-:109C50008F830038240BFFBFAC690008A06400307C
-:109C60008F9000382403FFDF9607003200E8282495
-:109C700000B51025A6020032921F003233F9003FD2
-:109C800037260040A20600328F8C0038AD800034A9
-:109C90008E2F00D0AD8F0038918E003C3C0F7FFF9F
-:109CA00031CD007FA18D003C8F84003835EEFFFF61
-:109CB000908A003C014B4824A089003C8F850038E5
-:109CC00090A8003C01033824A0A7003C8E42003439
-:109CD0008F9100383C038008AE2200408E59002C42
-:109CE0008E5F0030033F3023AE26004492300048A0
-:109CF0003218007FA23800488F8800388E4D00301F
-:109D00008D0C004801AE582401965024014B482583
-:109D1000AD0900489244000AA104004C964700088F
-:109D20008F850038A4A7004E8E5000308E4400303E
-:109D30000E0003818C65006092F9007C0002F940FE
-:109D4000004028210002110003E2302133360002D6
-:109D500012C00003020680210005B0800216802197
-:109D6000926D007C31B30004126000020005708027
-:109D7000020E80218E4B00308F8800382405800031
-:109D8000316A0003000A4823312400030204182129
-:109D9000AD03003496E4007A96F0007A96F1007AEA
-:109DA00032027FFF2447000130FF7FFF0225C824D5
-:109DB000033F3025A6E6007A96F8007A3C120800A8
-:109DC0008E520060330F7FFF11F200180000000078
-:109DD0008F8400A00E000FCE02A028218F8400A047
-:109DE0000E000FDE028028210E001013000000007C
-:109DF0000A00111F0000000096F1007A022480245E
-:109E0000A6F0007A92EF007A92EB007A31EE00FF32
-:109E1000000E69C2000D6027000C51C03169007F3F
-:109E2000012A20250A001119A2E4007A96E6007A98
-:109E300000C5C024A6F8007A92EF007A92F3007A67
-:109E400031F200FF001271C2000E6827000DB1C090
-:109E5000326C007F01962825A2E5007A0A0011D015
-:109E60008F8400A03C0380003084FFFF30A5FFFFFB
-:109E7000AC640018AC65001C03E000088C620014A0
-:109E800027BDFFA03C068008AFBF005CAFBE0058F6
-:109E9000AFB70054AFB60050AFB5004CAFB40048F8
-:109EA000AFB30044AFB20040AFB1003CAFB0003838
-:109EB00034C80100910500D590C700083084FFFF29
-:109EC00030A500FF30E2007F0045182AAFA4001043
-:109ED000A7A00018A7A0002610600055AFA000148E
-:109EE00090CA00083149007F00A9302324D3FFFF26
-:109EF0000013802B8FB400100014902B02128824C2
-:109F0000522000888FB300143C03800894790052DB
-:109F1000947E00508FB60010033EC0230018BC0092
-:109F2000001714030016FC0002C2A82A16A00002A3
-:109F3000001F2C030040282100133C0000072403CD
-:109F400000A4102A5440000100A020212885000907
-:109F500014A000020080A021241400083C0C8008FA
-:109F60008D860048001459808D88004C3C03800089
-:109F70003169FFFF3C0A0010012A202534710400DA
-:109F8000AC660038AF9100A4AC68003CAC64003013
-:109F900000000000000000000000000000000000C1
-:109FA00000000000000000000000000000000000B1
-:109FB0008C6E000031CD002011A0FFFD0014782A26
-:109FC00001F01024104000390000A8213C16800840
-:109FD00092D700083C1280008E44010032F6007FC8
-:109FE0000E000F9902C028218E3900108E44010006
-:109FF0000000902133373FFF0E000FB102E028210F
-:10A00000923800003302003F2C500008520000102C
-:10A0100000008821000210803C030800246358E4FB
-:10A020000043F8218FFE000003C00008000000007C
-:10A0300090CF0008938C00AB31EE007F00AE682318
-:10A04000018D58210A0012172573FFFF0000882197
-:10A050003C1E80008FC401000E000FCE02E02821BC
-:10A060008FC401000E000FDE02C028211220000F55
-:10A070000013802B8F8B00A426A400010004AC00E9
-:10A08000027298230015AC032578004002B4B02A70
-:10A090000013802B241700010300882102D0102414
-:10A0A000AF9800A41440FFC9AFB700143C07800864
-:10A0B00094E200508FAE00103C05800002A288217F
-:10A0C0003C060020A4F10050ACA6003094F40050EF
-:10A0D00094EF005201D51823306CFFFF11F4001EDD
-:10A0E000AFAC00108CEF004C001561808CF500487F
-:10A0F00001EC28210000202100AC582B02A4C02133
-:10A10000030BB021ACE5004CACF600488FB4001056
-:10A110000014902B021288241620FF7C3C03800838
-:10A120008FB300148FBF005C8FBE00583A620001ED
-:10A130008FB700548FB600508FB5004C8FB40048D5
-:10A140008FB300448FB200408FB1003C8FB0003815
-:10A1500003E0000827BD006094FE00548CF2004428
-:10A1600033C9FFFE0009C8C00259F821ACBF003C4A
-:10A170008CE800448CAD003C010D50231940003B9D
-:10A18000000000008CF7004026E20001ACA200387D
-:10A190003C05005034A700103C038000AC67003041
-:10A1A00000000000000000000000000000000000AF
-:10A1B000000000000000000000000000000000009F
-:10A1C0008C7800003316002012C0FFFD3C1180087F
-:10A1D000962200543C1580003C068008304E000159
-:10A1E000000E18C0007578218DEC04003C070800B3
-:10A1F0008CE700443C040020ACCC00488DF40404FF
-:10A20000240B0001ACD4004C10EB0260AEA4003073
-:10A21000963900523C0508008CA5004000B99021F9
-:10A22000A6320052963F005427ED0001A62D00549F
-:10A230009626005430C4FFFF5487FF2F8FB40010C0
-:10A2400030A5FFFF0E0011F4A62000543C070800C3
-:10A250008CE70024963E00520047B82303D74823DA
-:10A26000A62900520A0012198FB400108CE2004097
-:10A270000A0012BE00000000922400012407000121
-:10A280003085007F14A7001C97AD00268E2B00148C
-:10A29000240CC000316A3FFF01AC48243C06080092
-:10A2A0008CC60060012A402531043FFF0086882BC0
-:10A2B00012200011A7A800263C0508008CA5005814
-:10A2C0008F9100A0000439802402FF8000B1182182
-:10A2D0000067F82103E2F02433F8007F3C1280008D
-:10A2E0003C19800EAE5E002C0319702191D0000D38
-:10A2F000360F0004A1CF000D0E001028241200011B
-:10A30000241100013C1E80008FC401000E000FCEFE
-:10A3100002E028218FC401000E000FDE02C02821B8
-:10A320001620FF558F8B00A40A0012860013802B85
-:10A330008F8600A490C80001310400201080019194
-:10A34000241000013C048008348B0080916A007C5A
-:10A350008F9E0034AFA0002C314900011120000F66
-:10A36000AFB000288CCD00148C8E006001AE602B45
-:10A370001580000201A038218C8700603C188008FD
-:10A38000370300808C70007000F0782B15E000021D
-:10A3900000E020218C640070AFA4002C3C028008F7
-:10A3A000344500808CD200148CBF0070025FC82B33
-:10A3B00017200002024020218CA400708FA7002CDF
-:10A3C0000087182310600003AFA3003024050002AB
-:10A3D000AFA500288FA400280264882B162000BA9D
-:10A3E000000018218CD000388FCE000C3C0F00806C
-:10A3F000AFD000008CCD00343C0CFF9F01CF58251E
-:10A40000AFCD000490CA003F3586FFFF01662024CF
-:10A410003C0900203C08FFEFA3CA000B0089382547
-:10A420003511FFFF00F118243C0500088F8700A4B8
-:10A430000065C825AFD9000C8CE20014AFC000182D
-:10A440008FA60030AFC200148CF800188FB0002C1B
-:10A450003C1FFFFBAFD8001C8CEF000837F2FFFF5A
-:10A4600003326824AFCF00248CEC000C020670216C
-:10A47000AFCD000CA7C00038A7C0003AAFCE002C6B
-:10A48000AFCC0020AFC000288CEA00148FAB002CAA
-:10A49000014B48230126402311000011AFC80010D2
-:10A4A00090EB003D8FC900048FC80000000B5100E5
-:10A4B000012A28210000102100AA882B010218215E
-:10A4C0000071F821AFC50004AFDF000090F2003D3D
-:10A4D000A3D2000A8F9900A497380006A7D80008D5
-:10A4E0008F910038240800023C038008A228000055
-:10A4F0003465008094BF005C8FA4002C33F0FFFF14
-:10A500000E000FF48F9200380002CB808F8500A4DC
-:10A51000021978253C18420001F87025AE4E00045F
-:10A520008F8400388CAD0038AC8D00188CAC0034B2
-:10A53000AC8C001CAC80000CAC800010A48000141B
-:10A54000A4800016A4800020A4800022AC800024F7
-:10A5500090A6003F8FA7002CA486000250E0019235
-:10A56000240700018FA200305040000290A2003D5D
-:10A5700090A2003E244A0001A08A00018F84003886
-:10A580008FA9002CAC8900083C128008364D008051
-:10A5900091AC007C3186000214C000022407003414
-:10A5A000240700308F8500A43C198008373F0080C5
-:10A5B00090B0000093F9007C240E0004A0900030BD
-:10A5C0008F8F00A48FB8002C8F8D003891F200017E
-:10A5D0003304000301C46023A1B200318F8E003820
-:10A5E0008F8600A42402C00095CA003294C90012CC
-:10A5F0008FAB002C0142402431233FFF010388250B
-:10A60000A5D1003291D000323185000300EBF82152
-:10A610003218003F370F0040A1CF00328FA4002C2A
-:10A6200003E5382133280004108000028F850038AC
-:10A6300000E838213C0A8008ACA700343549010005
-:10A640008D2800D08FA3002C2419FFBFACA80038A0
-:10A6500090B1003C2C640001240FFFDF3227007F03
-:10A66000A0A7003C8F98003800049140931F003C45
-:10A6700003F98024A310003C8F8C0038918E003C9D
-:10A6800001CF682401B23025A186003C8F8900A447
-:10A690008F8800388D2B0020AD0B00408D220024C8
-:10A6A000AD0200448D2A0028AD0A00488D23002CFD
-:10A6B0000E001013AD03004C8FB1002824070002D8
-:10A6C000122700118FA300280003282B00058023E8
-:10A6D0000270982400608021006090210A00126FAF
-:10A6E0000010882B962900128F8400A00000902172
-:10A6F0003125FFFFA7A900180E000FC22411000189
-:10A700000A00131D3C1E80003C0B80003C12800898
-:10A710008D640100924900088F92FF340E000F995A
-:10A720003125007F8F9900388FA700288FA4003033
-:10A73000A3270000965F005C33F0FFFF0E000FF4CC
-:10A740008F91003800026B80020D80253C0842008A
-:10A750008F8D00A402085025AE2A00048DA5003874
-:10A760008F8A003800007821000F1100AD450018D5
-:10A770008DB800343C047FFF3488FFFFAD58001CC7
-:10A7800091A6003E8D4C001C8D4900180006190052
-:10A79000000677020183C821004E58250323882B29
-:10A7A000012B382100F1F821AD59001CAD5F0018D4
-:10A7B000AD40000CAD40001091B0003E8FA40030C1
-:10A7C00024090005A550001495A500042419C00013
-:10A7D00000884024A545001691B8003EA5580020E9
-:10A7E00095AF0004A54F0022AD40002491AE003F7C
-:10A7F000A54E000291A6003E91AC003D01861023BB
-:10A80000244B0001A14B00018F9100388FA3003031
-:10A810003C028008344B0100AE230008A22900301E
-:10A820008F8C00388F8700A4959F003294F000121F
-:10A830002407FFBF033FC02432053FFF03057825EF
-:10A84000A58F0032918E00322418FFDF31CD003FFA
-:10A8500035A60040A18600328F910038240DFFFFFD
-:10A86000240CFF80AE2000348D6A00D0AE2A003860
-:10A870009223003C3069007FA229003C8F90003871
-:10A880003C0380009219003C0327F824A21F003CDF
-:10A890008F8E003891C5003C00B87824A1CF003CD1
-:10A8A0008F8A00383C0E8008AD4D00408FA6002CEA
-:10A8B000AD46004491420048004C5825A14B004849
-:10A8C0008F9000388F9900A48E09004801238824B6
-:10A8D00002283825AE070048933F003EA21F004CD7
-:10A8E0008F9800A48F8F003897050004A5E5004ECF
-:10A8F0000E0003818DC500609246007C8FAC003055
-:10A9000000026940000291000040282130CB000283
-:10A9100001B21021156000AA018230213C0E80088E
-:10A9200035C20080904C007C31830004106000032D
-:10A930008FB900300005788000CF3021241F00043B
-:10A940008F910038332D000303ED8023320800037C
-:10A9500000C85021AE2A00343C188000A7C500383A
-:10A960003C0680088F04010090DE00080E000FDE18
-:10A9700033C5007F0E001013000000000A00140D04
-:10A980008FA300288F9800348CC90038241F00033F
-:10A99000A7000008AF0900008CC50034A300000A1E
-:10A9A0008F9900A4AF0500043C080080932D003F60
-:10A9B000A31F000C8F0A000C3C02FF9FA30D000B8D
-:10A9C0000148F0253451FFFF3C12FFEF8F9900A49E
-:10A9D00003D170243646FFFF01C61824AF03000CD4
-:10A9E0008F2C0014972900128F8400A0AF0C001048
-:10A9F0008F2F0014AF000018AF000020AF0F00141D
-:10AA0000AF0000248F270018312F3FFF000F59801F
-:10AA1000AF0700288F2500080164F821312D0001BF
-:10AA2000AF0500308F31000C8F920038001F51C2EB
-:10AA3000000D438001481021241E00023C068008BE
-:10AA4000A702001CA7000034AF11002CA25E00007A
-:10AA500034D20080964E005C8F9900383C0342004F
-:10AA600031CCFFFF01833825AF2700048F8B00A472
-:10AA7000240500012402C0008D640038240700343E
-:10AA8000AF2400188D690034AF29001CAF20000CE2
-:10AA9000AF200010A7200014A7200016A720002038
-:10AAA000A7200022AF200024A7300002A325000128
-:10AAB0008F8800388F9F00A4AD10000893ED000030
-:10AAC000A10D00308F8A00A48F98003891510001A9
-:10AAD000A31100318F8B0038957E003203C27024A1
-:10AAE00001CF6025A56C0032916300323064003FD5
-:10AAF000A16400329249007C3125000214A00002BA
-:10AB00008F840038240700303C198008AC8700345B
-:10AB1000373201008E5F00D0240AFFBF020090216F
-:10AB2000AC9F0038908D003C31A8007FA088003C8D
-:10AB30008F9E003893C2003C004A8824A3D1003C79
-:10AB40008F8300380010882B9066003C34CE0020A4
-:10AB5000A06E003C8F8400A48F9800388C8C00205D
-:10AB6000AF0C00408C8F0024AF0F00448C8700286E
-:10AB7000AF0700488C8B002CAF0B004C0E0010135D
-:10AB80003C1E80000A0012700000000094C80052B1
-:10AB90003C0A08008D4A002401488821A4D10052B3
-:10ABA0000A0012198FB40010A08700018F840038AA
-:10ABB000240B0001AC8B00080A0013BE3C12800875
-:10ABC000000520800A0014A200C4302127BDFFE048
-:10ABD0003C0D8008AFB20018AFB00010AFBF001C32
-:10ABE000AFB1001435B200808E4C001835A80100BA
-:10ABF000964B000695A70050910900FC000C5602E8
-:10AC0000016728233143007F312600FF240200031F
-:10AC1000AF8300A8AF8400A010C2001B30B0FFFFBC
-:10AC2000910600FC2412000530C200FF10520033D0
-:10AC300000000000160000098FBF001C8FB2001832
-:10AC40008FB100148FB00010240D0C003C0C80005C
-:10AC500027BD002003E00008AD8D00240E0011FB8D
-:10AC6000020020218FBF001C8FB200188FB100148A
-:10AC70008FB00010240D0C003C0C800027BD00207C
-:10AC800003E00008AD8D0024965800789651007AB4
-:10AC9000924E007D0238782631E8FFFF31C400C0B3
-:10ACA000148000092D11000116000037000000007B
-:10ACB0005620FFE28FBF001C0E0010D100000000E4
-:10ACC0000A00156A8FBF001C1620FFDA0000000082
-:10ACD0000E0010D1000000001440FFD88FBF001CF0
-:10ACE0001600002200000000925F007D33E2003F6A
-:10ACF000A242007D0A00156A8FBF001C950900EA78
-:10AD00008F86008000802821240400050E0007257E
-:10AD10003130FFFF978300923C0480002465FFFFE1
-:10AD2000A78500928C8A01B80540FFFE0000000054
-:10AD3000AC8001808FBF001CAC9001848FB20018E2
-:10AD40008FB100148FB000103C0760133C0B100053
-:10AD5000240D0C003C0C800027BD0020AC8701882E
-:10AD6000AC8B01B803E00008AD8D00240E0011FB90
-:10AD7000020020215040FFB18FBF001C925F007D78
-:10AD80000A00159733E2003F0E0011FB020020215C
-:10AD90001440FFAA8FBF001C122000070000000013
-:10ADA0009259007D3330003F36020040A242007DC0
-:10ADB0000A00156A8FBF001C0E0010D100000000B1
-:10ADC0005040FF9E8FBF001C9259007D3330003FE2
-:08ADD0000A0015C6360200401E
-:08ADD800000000000000001B58
-:10ADE0000000000F0000000A00000008000000063C
-:10ADF0000000000500000005000000040000000441
-:10AE00000000000300000003000000030000000336
-:10AE10000000000300000002000000020000000229
-:10AE2000000000020000000200000002000000021A
-:10AE3000000000020000000200000002000000020A
-:10AE400000000002000000020000000200000002FA
-:0CAE5000000000010000000100000001F3
-:04AE5C008008010069
-:10AE6000800800808008000000000C000000308096
-:10AE7000080011D00800127C08001294080012A8E3
-:10AE8000080012BC080011D0080011D0080012F010
-:10AE90000800132C080013400800138808001A8CBF
-:10AEA00008001A8C08001AC408001AC408001AD82E
-:10AEB00008001AA808001D0008001CCC08001D5836
-:10AEC00008001D5808001DE008001D108008024001
-:10AED000080027340800256C0800275C080027F4C8
-:10AEE0000800293C0800298808002AAC080029B479
-:10AEF00008002A38080025DC08002EDC08002EA4F3
-:10AF000008002588080025880800258808002B20CF
-:10AF100008002B20080025880800258808002DD06F
-:10AF2000080025880800258808002588080025884D
-:10AF300008002E0C080025880800258808002588B0
-:10AF4000080025880800258808002588080025882D
-:10AF5000080025880800258808002588080025881D
-:10AF6000080025880800258808002588080029A8E9
-:10AF7000080025880800258808002E680800258814
-:10AF800008002588080025880800258808002588ED
-:10AF900008002588080025880800258808002588DD
-:10AFA00008002588080025880800258808002588CD
-:10AFB00008002588080025880800258808002588BD
-:10AFC00008002CF4080025880800258808002C6853
-:10AFD00008002BC408003CE408003CB808003C848E
-:10AFE00008003C5808003C3808003BEC8008010091
-:10AFF00080080080800800008008008008004C6401
-:10B0000008004C9C08004BE408004C6408004C64A9
-:0CB01000080049B808004C6408005050CB
-:04B01C000A000C8496
-:10B0200000000000000000000000000D7278703683
-:10B030002E322E31610000000602010300000000E4
-:10B0400000000001000000000000000000000000FF
-:10B0500000000000000000000000000000000000F0
-:10B0600000000000000000000000000000000000E0
-:10B0700000000000000000000000000000000000D0
-:10B0800000000000000000000000000000000000C0
-:10B0900000000000000000000000000000000000B0
-:10B0A00000000000000000000000000000000000A0
-:10B0B0000000000000000000000000000000000090
-:10B0C0000000000000000000000000000000000080
-:10B0D0000000000000000000000000000000000070
-:10B0E0000000000000000000000000000000000060
-:10B0F0000000000000000000000000000000000050
-:10B10000000000000000000000000000000000003F
-:10B11000000000000000000000000000000000002F
-:10B12000000000000000000000000000000000001F
-:10B13000000000000000000000000000000000000F
-:10B1400000000000000000000000000000000000FF
-:10B1500000000000000000000000000000000000EF
-:10B1600000000000000000000000000000000000DF
-:10B1700000000000000000000000000000000000CF
-:10B1800000000000000000000000000000000000BF
-:10B1900000000000000000000000000000000000AF
-:10B1A000000000000000000000000000000000009F
-:10B1B000000000000000000000000000000000008F
-:10B1C000000000000000000000000000000000007F
-:10B1D000000000000000000000000000000000006F
-:10B1E000000000000000000000000000000000005F
-:10B1F000000000000000000000000000000000004F
-:10B20000000000000000000000000000000000003E
-:10B21000000000000000000000000000000000002E
-:10B22000000000000000000000000000000000001E
-:10B23000000000000000000000000000000000000E
-:10B2400000000000000000000000000000000000FE
-:10B2500000000000000000000000000000000000EE
-:10B2600000000000000000000000000000000000DE
-:10B2700000000000000000000000000000000000CE
-:10B2800000000000000000000000000000000000BE
-:10B2900000000000000000000000000000000000AE
-:10B2A000000000000000000000000000000000009E
-:10B2B000000000000000000000000000000000008E
-:10B2C000000000000000000000000000000000007E
-:10B2D000000000000000000000000000000000006E
-:10B2E000000000000000000000000000000000005E
-:10B2F000000000000000000000000000000000004E
-:10B30000000000000000000000000000000000003D
-:10B31000000000000000000000000000000000002D
-:10B32000000000000000000000000000000000001D
-:10B33000000000000000000000000000000000000D
-:10B3400000000000000000000000000000000000FD
-:10B3500000000000000000000000000000000000ED
-:10B3600000000000000000000000000000000000DD
-:10B3700000000000000000000000000000000000CD
-:10B3800000000000000000000000000000000000BD
-:10B3900000000000000000000000000000000000AD
-:10B3A000000000000000000000000000000000009D
-:10B3B000000000000000000000000000000000008D
-:10B3C000000000000000000000000000000000007D
-:10B3D000000000000000000000000000000000006D
-:10B3E000000000000000000000000000000000005D
-:10B3F000000000000000000000000000000000004D
-:10B40000000000000000000000000000000000003C
-:10B41000000000000000000000000000000000002C
-:10B42000000000000000000000000000000000001C
-:10B43000000000000000000000000000000000000C
-:10B4400000000000000000000000000000000000FC
-:10B4500000000000000000000000000000000000EC
-:10B4600000000000000000000000000000000000DC
-:10B4700000000000000000000000000000000000CC
-:10B4800000000000000000000000000000000000BC
-:10B4900000000000000000000000000000000000AC
-:10B4A000000000000000000000000000000000009C
-:10B4B000000000000000000000000000000000008C
-:10B4C000000000000000000000000000000000007C
-:10B4D000000000000000000000000000000000006C
-:10B4E000000000000000000000000000000000005C
-:10B4F000000000000000000000000000000000004C
-:10B50000000000000000000000000000000000003B
-:10B51000000000000000000000000000000000002B
-:10B52000000000000000000000000000000000001B
-:10B53000000000000000000000000000000000000B
-:10B5400000000000000000000000000000000000FB
-:10B5500000000000000000000000000000000000EB
-:10B5600000000000000000000000000000000000DB
-:10B5700000000000000000000000000000000000CB
-:10B5800000000000000000000000000000000000BB
-:10B5900000000000000000000000000000000000AB
-:10B5A000000000000000000000000000000000009B
-:10B5B000000000000000000000000000000000008B
-:10B5C000000000000000000000000000000000007B
-:10B5D000000000000000000000000000000000006B
-:10B5E000000000000000000000000000000000005B
-:10B5F000000000000000000000000000000000004B
-:10B60000000000000000000000000000000000003A
-:10B61000000000000000000000000000000000002A
-:10B62000000000000000000000000000000000001A
-:10B63000000000000000000000000000000000000A
-:10B6400000000000000000000000000000000000FA
-:10B6500000000000000000000000000000000000EA
-:10B6600000000000000000000000000000000000DA
-:10B6700000000000000000000000000000000000CA
-:10B6800000000000000000000000000000000000BA
-:10B6900000000000000000000000000000000000AA
-:10B6A000000000000000000000000000000000009A
-:10B6B000000000000000000000000000000000008A
-:10B6C000000000000000000000000000000000007A
-:10B6D000000000000000000000000000000000006A
-:10B6E000000000000000000000000000000000005A
-:10B6F000000000000000000000000000000000004A
-:10B700000000000000000000000000000000000039
-:10B710000000000000000000000000000000000029
-:10B720000000000000000000000000000000000019
-:10B730000000000000000000000000000000000009
-:10B7400000000000000000000000000000000000F9
-:10B7500000000000000000000000000000000000E9
-:10B7600000000000000000000000000000000000D9
-:10B7700000000000000000000000000000000000C9
-:10B7800000000000000000000000000000000000B9
-:10B7900000000000000000000000000000000000A9
-:10B7A0000000000000000000000000000000000099
-:10B7B0000000000000000000000000000000000089
-:10B7C0000000000000000000000000000000000079
-:10B7D0000000000000000000000000000000000069
-:10B7E0000000000000000000000000000000000059
-:10B7F0000000000000000000000000000000000049
-:10B800000000000000000000000000000000000038
-:10B810000000000000000000000000000000000028
-:10B820000000000000000000000000000000000018
-:10B830000000000000000000000000000000000008
-:10B8400000000000000000000000000000000000F8
-:10B8500000000000000000000000000000000000E8
-:10B8600000000000000000000000000000000000D8
-:10B8700000000000000000000000000000000000C8
-:10B8800000000000000000000000000000000000B8
-:10B8900000000000000000000000000000000000A8
-:10B8A0000000000000000000000000000000000098
-:10B8B0000000000000000000000000000000000088
-:10B8C0000000000000000000000000000000000078
-:10B8D0000000000000000000000000000000000068
-:10B8E0000000000000000000000000000000000058
-:10B8F0000000000000000000000000000000000048
-:10B900000000000000000000000000000000000037
-:10B910000000000000000000000000000000000027
-:10B920000000000000000000000000000000000017
-:10B930000000000000000000000000000000000007
-:10B9400000000000000000000000000000000000F7
-:10B9500000000000000000000000000000000000E7
-:10B9600000000000000000000000000000000000D7
-:10B9700000000000000000000000000000000000C7
-:10B9800000000000000000000000000000000000B7
-:10B9900000000000000000000000000000000000A7
-:10B9A0000000000000000000000000000000000097
-:10B9B0000000000000000000000000000000000087
-:10B9C0000000000000000000000000000000000077
-:10B9D0000000000000000000000000000000000067
-:10B9E0000000000000000000000000000000000057
-:10B9F0000000000000000000000000000000000047
-:10BA00000000000000000000000000000000000036
-:10BA10000000000000000000000000000000000026
-:10BA20000000000000000000000000000000000016
-:10BA30000000000000000000000000000000000006
-:10BA400000000000000000000000000000000000F6
-:10BA500000000000000000000000000000000000E6
-:10BA600000000000000000000000000000000000D6
-:10BA700000000000000000000000000000000000C6
-:10BA800000000000000000000000000000000000B6
-:10BA900000000000000000000000000000000000A6
-:10BAA0000000000000000000000000000000000096
-:10BAB0000000000000000000000000000000000086
-:10BAC0000000000000000000000000000000000076
-:10BAD0000000000000000000000000000000000066
-:10BAE0000000000000000000000000000000000056
-:10BAF0000000000000000000000000000000000046
-:10BB00000000000000000000000000000000000035
-:10BB10000000000000000000000000000000000025
-:10BB20000000000000000000000000000000000015
-:10BB30000000000000000000000000000000000005
-:10BB400000000000000000000000000000000000F5
-:10BB500000000000000000000000000000000000E5
-:10BB600000000000000000000000000000000000D5
-:10BB700000000000000000000000000000000000C5
-:10BB800000000000000000000000000000000000B5
-:10BB900000000000000000000000000000000000A5
-:10BBA0000000000000000000000000000000000095
-:10BBB0000000000000000000000000000000000085
-:10BBC0000000000000000000000000000000000075
-:10BBD0000000000000000000000000000000000065
-:10BBE0000000000000000000000000000000000055
-:10BBF0000000000000000000000000000000000045
-:10BC00000000000000000000000000000000000034
-:10BC10000000000000000000000000000000000024
-:10BC20000000000000000000000000000000000014
-:10BC30000000000000000000000000000000000004
-:10BC400000000000000000000000000000000000F4
-:10BC500000000000000000000000000000000000E4
-:10BC600000000000000000000000000000000000D4
-:10BC700000000000000000000000000000000000C4
-:10BC800000000000000000000000000000000000B4
-:10BC900000000000000000000000000000000000A4
-:10BCA0000000000000000000000000000000000094
-:10BCB0000000000000000000000000000000000084
-:10BCC0000000000000000000000000000000000074
-:10BCD0000000000000000000000000000000000064
-:10BCE0000000000000000000000000000000000054
-:10BCF0000000000000000000000000000000000044
-:10BD00000000000000000000000000000000000033
-:10BD10000000000000000000000000000000000023
-:10BD20000000000000000000000000000000000013
-:10BD30000000000000000000000000000000000003
-:10BD400000000000000000000000000000000000F3
-:10BD500000000000000000000000000000000000E3
-:10BD600000000000000000000000000000000000D3
-:10BD700000000000000000000000000000000000C3
-:10BD800000000000000000000000000000000000B3
-:10BD900000000000000000000000000000000000A3
-:10BDA0000000000000000000000000000000000093
-:10BDB0000000000000000000000000000000000083
-:10BDC0000000000000000000000000000000000073
-:10BDD0000000000000000000000000000000000063
-:10BDE0000000000000000000000000000000000053
-:10BDF0000000000000000000000000000000000043
-:10BE00000000000000000000000000000000000032
-:10BE10000000000000000000000000000000000022
-:10BE20000000000000000000000000000000000012
-:10BE30000000000000000000000000000000000002
-:10BE400000000000000000000000000000000000F2
-:10BE500000000000000000000000000000000000E2
-:10BE600000000000000000000000000000000000D2
-:10BE700000000000000000000000000000000000C2
-:10BE800000000000000000000000000000000000B2
-:10BE900000000000000000000000000000000000A2
-:10BEA0000000000000000000000000000000000092
-:10BEB0000000000000000000000000000000000082
-:10BEC0000000000000000000000000000000000072
-:10BED0000000000000000000000000000000000062
-:10BEE0000000000000000000000000000000000052
-:10BEF0000000000000000000000000000000000042
-:10BF00000000000000000000000000000000000031
-:10BF10000000000000000000000000000000000021
-:10BF20000000000000000000000000000000000011
-:10BF30000000000000000000000000000000000001
-:10BF400000000000000000000000000000000000F1
-:10BF500000000000000000000000000000000000E1
-:10BF600000000000000000000000000000000000D1
-:10BF700000000000000000000000000000000000C1
-:10BF800000000000000000000000000000000000B1
-:10BF900000000000000000000000000000000000A1
-:10BFA0000000000000000000000000000000000091
-:10BFB0000000000000000000000000000000000081
-:10BFC0000000000000000000000000000000000071
-:10BFD0000000000000000000000000000000000061
-:10BFE0000000000000000000000000000000000051
-:10BFF0000000000000000000000000000000000041
-:10C000000000000000000000000000000000000030
-:10C010000000000000000000000000000000000020
-:10C020000000000000000000000000000000000010
-:10C030000000000000000000000000000000000000
-:10C0400000000000000000000000000000000000F0
-:10C0500000000000000000000000000000000000E0
-:10C0600000000000000000000000000000000000D0
-:10C0700000000000000000000000000000000000C0
-:10C0800000000000000000000000000000000000B0
-:10C0900000000000000000000000000000000000A0
-:10C0A0000000000000000000000000000000000090
-:10C0B0000000000000000000000000000000000080
-:10C0C0000000000000000000000000000000000070
-:10C0D0000000000000000000000000000000000060
-:10C0E0000000000000000000000000000000000050
-:10C0F0000000000000000000000000000000000040
-:10C10000000000000000000000000000000000002F
-:10C11000000000000000000000000000000000001F
-:10C12000000000000000000000000000000000000F
-:10C1300000000000000000000000000000000000FF
-:10C1400000000000000000000000000000000000EF
-:10C1500000000000000000000000000000000000DF
-:10C1600000000000000000000000000000000000CF
-:10C1700000000000000000000000000000000000BF
-:10C1800000000000000000000000000000000000AF
-:10C19000000000000000000000000000000000009F
-:10C1A000000000000000000000000000000000008F
-:10C1B000000000000000000000000000000000007F
-:10C1C000000000000000000000000000000000006F
-:10C1D000000000000000000000000000000000005F
-:10C1E000000000000000000000000000000000004F
-:10C1F000000000000000000000000000000000003F
-:10C20000000000000000000000000000000000002E
-:10C21000000000000000000000000000000000001E
-:10C22000000000000000000000000000000000000E
-:10C2300000000000000000000000000000000000FE
-:10C2400000000000000000000000000000000000EE
-:10C2500000000000000000000000000000000000DE
-:10C2600000000000000000000000000000000000CE
-:10C2700000000000000000000000000000000000BE
-:10C2800000000000000000000000000000000000AE
-:10C29000000000000000000000000000000000009E
-:10C2A000000000000000000000000000000000008E
-:10C2B000000000000000000000000000000000007E
-:10C2C000000000000000000000000000000000006E
-:10C2D000000000000000000000000000000000005E
-:10C2E000000000000000000000000000000000004E
-:10C2F000000000000000000000000000000000003E
-:10C30000000000000000000000000000000000002D
-:10C31000000000000000000000000000000000001D
-:10C32000000000000000000000000000000000000D
-:10C3300000000000000000000000000000000000FD
-:10C3400000000000000000000000000000000000ED
-:10C3500000000000000000000000000000000000DD
-:10C3600000000000000000000000000000000000CD
-:10C3700000000000000000000000000000000000BD
-:10C3800000000000000000000000000000000000AD
-:10C39000000000000000000000000000000000009D
-:10C3A000000000000000000000000000000000008D
-:10C3B000000000000000000000000000000000007D
-:10C3C000000000000000000000000000000000006D
-:10C3D000000000000000000000000000000000005D
-:10C3E000000000000000000000000000000000004D
-:10C3F000000000000000000000000000000000003D
-:10C40000000000000000000000000000000000002C
-:10C41000000000000000000000000000000000001C
-:10C42000000000000000000000000000000000000C
-:10C4300000000000000000000000000000000000FC
-:10C4400000000000000000000000000000000000EC
-:10C4500000000000000000000000000000000000DC
-:10C4600000000000000000000000000000000000CC
-:10C4700000000000000000000000000000000000BC
-:10C4800000000000000000000000000000000000AC
-:10C49000000000000000000000000000000000009C
-:10C4A000000000000000000000000000000000008C
-:10C4B000000000000000000000000000000000007C
-:10C4C000000000000000000000000000000000006C
-:10C4D000000000000000000000000000000000005C
-:10C4E000000000000000000000000000000000004C
-:10C4F000000000000000000000000000000000003C
-:10C50000000000000000000000000000000000002B
-:10C51000000000000000000000000000000000001B
-:10C52000000000000000000000000000000000000B
-:10C5300000000000000000000000000000000000FB
-:10C5400000000000000000000000000000000000EB
-:10C5500000000000000000000000000000000000DB
-:10C5600000000000000000000000000000000000CB
-:10C5700000000000000000000000000000000000BB
-:10C5800000000000000000000000000000000000AB
-:10C59000000000000000000000000000000000009B
-:10C5A000000000000000000000000000000000008B
-:10C5B000000000000000000000000000000000007B
-:10C5C000000000000000000000000000000000006B
-:10C5D000000000000000000000000000000000005B
-:10C5E000000000000000000000000000000000004B
-:10C5F000000000000000000000000000000000003B
-:10C60000000000000000000000000000000000002A
-:10C61000000000000000000000000000000000001A
-:10C62000000000000000000000000000000000000A
-:10C6300000000000000000000000000000000000FA
-:10C6400000000000000000000000000000000000EA
-:10C6500000000000000000000000000000000000DA
-:10C6600000000000000000000000000000000000CA
-:10C6700000000000000000000000000000000000BA
-:10C6800000000000000000000000000000000000AA
-:10C69000000000000000000000000000000000009A
-:10C6A000000000000000000000000000000000008A
-:10C6B000000000000000000000000000000000007A
-:10C6C000000000000000000000000000000000006A
-:10C6D000000000000000000000000000000000005A
-:10C6E000000000000000000000000000000000004A
-:10C6F000000000000000000000000000000000003A
-:10C700000000000000000000000000000000000029
-:10C710000000000000000000000000000000000019
-:10C720000000000000000000000000000000000009
-:10C7300000000000000000000000000000000000F9
-:10C7400000000000000000000000000000000000E9
-:10C7500000000000000000000000000000000000D9
-:10C7600000000000000000000000000000000000C9
-:10C7700000000000000000000000000000000000B9
-:10C7800000000000000000000000000000000000A9
-:10C790000000000000000000000000000000000099
-:10C7A0000000000000000000000000000000000089
-:10C7B0000000000000000000000000000000000079
-:10C7C0000000000000000000000000000000000069
-:10C7D0000000000000000000000000000000000059
-:10C7E0000000000000000000000000000000000049
-:10C7F0000000000000000000000000000000000039
-:10C800000000000000000000000000000000000028
-:10C810000000000000000000000000000000000018
-:10C820000000000000000000000000000000000008
-:10C8300000000000000000000000000000000000F8
-:10C8400000000000000000000000000000000000E8
-:10C8500000000000000000000000000000000000D8
-:10C8600000000000000000000000000000000000C8
-:10C8700000000000000000000000000000000000B8
-:10C8800000000000000000000000000000000000A8
-:10C890000000000000000000000000000000000098
-:10C8A0000000000000000000000000000000000088
-:10C8B0000000000000000000000000000000000078
-:10C8C0000000000000000000000000000000000068
-:10C8D0000000000000000000000000000000000058
-:10C8E0000000000000000000000000000000000048
-:10C8F0000000000000000000000000000000000038
-:10C900000000000000000000000000000000000027
-:10C910000000000000000000000000000000000017
-:10C920000000000000000000000000000000000007
-:10C9300000000000000000000000000000000000F7
-:10C9400000000000000000000000000000000000E7
-:10C9500000000000000000000000000000000000D7
-:10C9600000000000000000000000000000000000C7
-:10C9700000000000000000000000000000000000B7
-:10C9800000000000000000000000000000000000A7
-:10C990000000000000000000000000000000000097
-:10C9A0000000000000000000000000000000000087
-:10C9B0000000000000000000000000000000000077
-:10C9C0000000000000000000000000000000000067
-:10C9D0000000000000000000000000000000000057
-:10C9E0000000000000000000000000000000000047
-:10C9F0000000000000000000000000000000000037
-:10CA00000000000000000000000000000000000026
-:10CA10000000000000000000000000000000000016
-:10CA20000000000000000000000000000000000006
-:10CA300000000000000000000000000000000000F6
-:10CA400000000000000000000000000000000000E6
-:10CA500000000000000000000000000000000000D6
-:10CA600000000000000000000000000000000000C6
-:10CA700000000000000000000000000000000000B6
-:10CA800000000000000000000000000000000000A6
-:10CA90000000000000000000000000000000000096
-:10CAA0000000000000000000000000000000000086
-:10CAB0000000000000000000000000000000000076
-:10CAC0000000000000000000000000000000000066
-:10CAD0000000000000000000000000000000000056
-:10CAE0000000000000000000000000000000000046
-:10CAF0000000000000000000000000000000000036
-:10CB00000000000000000000000000000000000025
-:10CB10000000000000000000000000000000000015
-:10CB20000000000000000000000000000000000005
-:10CB300000000000000000000000000000000000F5
-:10CB400000000000000000000000000000000000E5
-:10CB500000000000000000000000000000000000D5
-:10CB600000000000000000000000000000000000C5
-:10CB700000000000000000000000000000000000B5
-:10CB800000000000000000000000000000000000A5
-:10CB90000000000000000000000000000000000095
-:10CBA0000000000000000000000000000000000085
-:10CBB0000000000000000000000000000000000075
-:10CBC0000000000000000000000000000000000065
-:10CBD0000000000000000000000000000000000055
-:10CBE0000000000000000000000000000000000045
-:10CBF0000000000000000000000000000000000035
-:10CC00000000000000000000000000000000000024
-:10CC10000000000000000000000000000000000014
-:10CC20000000000000000000000000000000000004
-:10CC300000000000000000000000000000000000F4
-:10CC400000000000000000000000000000000000E4
-:10CC500000000000000000000000000000000000D4
-:10CC600000000000000000000000000000000000C4
-:10CC700000000000000000000000000000000000B4
-:10CC800000000000000000000000000000000000A4
-:10CC90000000000000000000000000000000000094
-:10CCA0000000000000000000000000000000000084
-:10CCB0000000000000000000000000000000000074
-:10CCC0000000000000000000000000000000000064
-:10CCD0000000000000000000000000000000000054
-:10CCE0000000000000000000000000000000000044
-:10CCF0000000000000000000000000000000000034
-:10CD00000000000000000000000000000000000023
-:10CD10000000000000000000000000000000000013
-:10CD20000000000000000000000000000000000003
-:10CD300000000000000000000000000000000000F3
-:10CD400000000000000000000000000000000000E3
-:10CD500000000000000000000000000000000000D3
-:10CD600000000000000000000000000000000000C3
-:10CD700000000000000000000000000000000000B3
-:10CD800000000000000000000000000000000000A3
-:10CD90000000000000000000000000000000000093
-:10CDA0000000000000000000000000000000000083
-:10CDB0000000000000000000000000000000000073
-:10CDC0000000000000000000000000000000000063
-:10CDD0000000000000000000000000000000000053
-:10CDE0000000000000000000000000000000000043
-:10CDF0000000000000000000000000000000000033
-:10CE00000000000000000000000000000000000022
-:10CE10000000000000000000000000000000000012
-:10CE20000000000000000000000000000000000002
-:10CE300000000000000000000000000000000000F2
-:10CE400000000000000000000000000000000000E2
-:10CE500000000000000000000000000000000000D2
-:10CE600000000000000000000000000000000000C2
-:10CE700000000000000000000000000000000000B2
-:10CE800000000000000000000000000000000000A2
-:10CE90000000000000000000000000000000000092
-:10CEA0000000000000000000000000000000000082
-:10CEB0000000000000000000000000000000000072
-:10CEC0000000000000000000000000000000000062
-:10CED0000000000000000000000000000000000052
-:10CEE0000000000000000000000000000000000042
-:10CEF0000000000000000000000000000000000032
-:10CF00000000000000000000000000000000000021
-:10CF10000000000000000000000000000000000011
-:10CF20000000000000000000000000000000000001
-:10CF300000000000000000000000000000000000F1
-:10CF400000000000000000000000000000000000E1
-:10CF500000000000000000000000000000000000D1
-:10CF600000000000000000000000000000000000C1
-:10CF700000000000000000000000000000000000B1
-:10CF800000000000000000000000000000000000A1
-:10CF90000000000000000000000000000000000091
-:10CFA0000000000000000000000000000000000081
-:10CFB0000000000000000000000000000000000071
-:10CFC0000000000000000000000000000000000061
-:10CFD0000000000000000000000000000000000051
-:10CFE0000000000000000000000000000000000041
-:10CFF0000000000000000000000000000000000031
-:10D000000000000000000000000000000000000020
-:10D010000000000000000000000000000000000010
-:10D020000000000000000000000000000000000000
-:10D0300000000000000000000000000000000000F0
-:10D0400000000000000000000000000000000000E0
-:10D0500000000000000000000000000000000000D0
-:10D0600000000000000000000000000000000000C0
-:10D0700000000000000000000000000000000000B0
-:10D0800000000000000000000000000000000000A0
-:10D090000000000000000000000000000000000090
-:10D0A0000000000000000000000000000000000080
-:10D0B0000000000000000000000000000000000070
-:10D0C0000000000000000000000000000000000060
-:10D0D0000000000000000000000000000000000050
-:10D0E0000000000000000000000000000000000040
-:10D0F0000000000000000000000000000000000030
-:10D10000000000000000000000000000000000001F
-:10D11000000000000000000000000000000000000F
-:10D1200000000000000000000000000000000000FF
-:10D1300000000000000000000000000000000000EF
-:10D1400000000000000000000000000000000000DF
-:10D1500000000000000000000000000000000000CF
-:10D1600000000000000000000000000000000000BF
-:10D1700000000000000000000000000000000000AF
-:10D18000000000000000000000000000000000009F
-:10D19000000000000000000000000000000000008F
-:10D1A000000000000000000000000000000000007F
-:10D1B000000000000000000000000000000000006F
-:10D1C000000000000000000000000000000000005F
-:10D1D000000000000000000000000000000000004F
-:10D1E000000000000000000000000000000000003F
-:10D1F000000000000000000000000000000000002F
-:10D20000000000000000000000000000000000001E
-:10D21000000000000000000000000000000000000E
-:10D2200000000000000000000000000000000000FE
-:10D2300000000000000000000000000000000000EE
-:10D2400000000000000000000000000000000000DE
-:10D2500000000000000000000000000000000000CE
-:10D2600000000000000000000000000000000000BE
-:10D2700000000000000000000000000000000000AE
-:10D28000000000000000000000000000000000009E
-:10D29000000000000000000000000000000000008E
-:10D2A000000000000000000000000000000000007E
-:10D2B000000000000000000000000000000000006E
-:10D2C000000000000000000000000000000000005E
-:10D2D000000000000000000000000000000000004E
-:10D2E000000000000000000000000000000000003E
-:10D2F000000000000000000000000000000000002E
-:10D30000000000000000000000000000000000001D
-:10D31000000000000000000000000000000000000D
-:10D3200000000000000000000000000000000000FD
-:10D3300000000000000000000000000000000000ED
-:10D3400000000000000000000000000000000000DD
-:10D3500000000000000000000000000000000000CD
-:10D3600000000000000000000000000000000000BD
-:10D3700000000000000000000000000000000000AD
-:10D38000000000000000000000000000000000009D
-:10D39000000000000000000000000000000000008D
-:10D3A000000000000000000000000000000000007D
-:10D3B000000000000000000000000000000000006D
-:10D3C000000000000000000000000000000000005D
-:10D3D000000000000000000000000000000000004D
-:10D3E000000000000000000000000000000000003D
-:10D3F000000000000000000000000000000000002D
-:10D40000000000000000000000000000000000001C
-:10D41000000000000000000000000000000000000C
-:10D4200000000000000000000000000000000000FC
-:10D4300000000000000000000000000000000000EC
-:10D4400000000000000000000000000000000000DC
-:10D4500000000000000000000000000000000000CC
-:10D4600000000000000000000000000000000000BC
-:10D4700000000000000000000000000000000000AC
-:10D48000000000000000000000000000000000009C
-:10D49000000000000000000000000000000000008C
-:10D4A000000000000000000000000000000000007C
-:10D4B000000000000000000000000000000000006C
-:10D4C000000000000000000000000000000000005C
-:10D4D000000000000000000000000000000000004C
-:10D4E000000000000000000000000000000000003C
-:10D4F000000000000000000000000000000000002C
-:10D50000000000000000000000000000000000001B
-:10D51000000000000000000000000000000000000B
-:10D5200000000000000000000000000000000000FB
-:10D5300000000000000000000000000000000000EB
-:10D5400000000000000000000000000000000000DB
-:10D5500000000000000000000000000000000000CB
-:10D5600000000000000000000000000000000000BB
-:10D5700000000000000000000000000000000000AB
-:10D58000000000000000000000000000000000009B
-:10D59000000000000000000000000000000000008B
-:10D5A000000000000000000000000000000000007B
-:10D5B000000000000000000000000000000000006B
-:10D5C000000000000000000000000000000000005B
-:10D5D000000000000000000000000000000000004B
-:10D5E000000000000000000000000000000000003B
-:10D5F000000000000000000000000000000000002B
-:10D60000000000000000000000000000000000001A
-:10D61000000000000000000000000000000000000A
-:10D6200000000000000000000000000000000000FA
-:10D6300000000000000000000000000000000000EA
-:10D6400000000000000000000000000000000000DA
-:10D6500000000000000000000000000000000000CA
-:10D6600000000000000000000000000000000000BA
-:10D6700000000000000000000000000000000000AA
-:10D68000000000000000000000000000000000009A
-:10D69000000000000000000000000000000000008A
-:10D6A000000000000000000000000000000000007A
-:10D6B000000000000000000000000000000000006A
-:10D6C000000000000000000000000000000000005A
-:10D6D000000000000000000000000000000000004A
-:10D6E000000000000000000000000000000000003A
-:10D6F000000000000000000000000000000000002A
-:10D700000000000000000000000000000000000019
-:10D710000000000000000000000000000000000009
-:10D7200000000000000000000000000000000000F9
-:10D7300000000000000000000000000000000000E9
-:10D7400000000000000000000000000000000000D9
-:10D7500000000000000000000000000000000000C9
-:10D7600000000000000000000000000000000000B9
-:10D7700000000000000000000000000000000000A9
-:10D780000000000000000000000000000000000099
-:10D790000000000000000000000000000000000089
-:10D7A0000000000000000000000000000000000079
-:10D7B0000000000000000000000000000000000069
-:10D7C0000000000000000000000000000000000059
-:10D7D0000000000000000000000000000000000049
-:10D7E0000000000000000000000000000000000039
-:10D7F0000000000000000000000000000000000029
-:10D800000000000000000000000000000000000018
-:10D810000000000000000000000000000000000008
-:10D8200000000000000000000000000000000000F8
-:10D8300000000000000000000000000000000000E8
-:10D8400000000000000000000000000000000000D8
-:10D8500000000000000000000000000000000000C8
-:10D8600000000000000000000000000000000000B8
-:10D8700000000000000000000000000000000000A8
-:10D880000000000000000000000000000000000098
-:10D890000000000000000000000000000000000088
-:10D8A0000000000000000000000000000000000078
-:10D8B0000000000000000000000000000000000068
-:10D8C0000000000000000000000000000000000058
-:10D8D0000000000000000000000000000000000048
-:10D8E0000000000000000000000000000000000038
-:10D8F0000000000000000000000000000000000028
-:10D900000000000000000000000000000000000017
-:10D910000000000000000000000000000000000007
-:10D9200000000000000000000000000000000000F7
-:10D9300000000000000000000000000000000000E7
-:10D9400000000000000000000000000000000000D7
-:10D9500000000000000000000000000000000000C7
-:10D9600000000000000000000000000000000000B7
-:10D9700000000000000000000000000000000000A7
-:10D980000000000000000000000000000000000097
-:10D990000000000000000000000000000000000087
-:10D9A0000000000000000000000000000000000077
-:10D9B0000000000000000000000000000000000067
-:10D9C0000000000000000000000000000000000057
-:10D9D0000000000000000000000000000000000047
-:10D9E0000000000000000000000000000000000037
-:10D9F0000000000000000000000000000000000027
-:10DA00000000000000000000000000000000000016
-:10DA10000000000000000000000000000000000006
-:10DA200000000000000000000000000000000000F6
-:10DA300000000000000000000000000000000000E6
-:10DA400000000000000000000000000000000000D6
-:10DA500000000000000000000000000000000000C6
-:10DA600000000000000000000000000000000000B6
-:10DA700000000000000000000000000000000000A6
-:10DA80000000000000000000000000000000000096
-:10DA90000000000000000000000000000000000086
-:10DAA0000000000000000000000000000000000076
-:10DAB0000000000000000000000000000000000066
-:10DAC0000000000000000000000000000000000056
-:10DAD0000000000000000000000000000000000046
-:10DAE0000000000000000000000000000000000036
-:10DAF0000000000000000000000000000000000026
-:10DB00000000000000000000000000000000000015
-:10DB10000000000000000000000000000000000005
-:10DB200000000000000000000000000000000000F5
-:10DB300000000000000000000000000000000000E5
-:10DB400000000000000000000000000000000000D5
-:10DB500000000000000000000000000000000000C5
-:10DB600000000000000000000000000000000000B5
-:10DB700000000000000000000000000000000000A5
-:10DB80000000000000000000000000000000000095
-:10DB90000000000000000000000000000000000085
-:10DBA0000000000000000000000000000000000075
-:10DBB0000000000000000000000000000000000065
-:10DBC0000000000000000000000000000000000055
-:10DBD0000000000000000000000000000000000045
-:10DBE0000000000000000000000000000000000035
-:10DBF0000000000000000000000000000000000025
-:10DC00000000000000000000000000000000000014
-:10DC10000000000000000000000000000000000004
-:10DC200000000000000000000000000000000000F4
-:10DC300000000000000000000000000000000000E4
-:10DC400000000000000000000000000000000000D4
-:10DC500000000000000000000000000000000000C4
-:10DC600000000000000000000000000000000000B4
-:10DC700000000000000000000000000000000000A4
-:10DC80000000000000000000000000000000000094
-:10DC90000000000000000000000000000000000084
-:10DCA0000000000000000000000000000000000074
-:10DCB0000000000000000000000000000000000064
-:10DCC0000000000000000000000000000000000054
-:10DCD0000000000000000000000000000000000044
-:10DCE0000000000000000000000000000000000034
-:10DCF0000000000000000000000000000000000024
-:10DD00000000000000000000000000000000000013
-:10DD10000000000000000000000000000000000003
-:10DD200000000000000000000000000000000000F3
-:10DD300000000000000000000000000000000000E3
-:10DD400000000000000000000000000000000000D3
-:10DD500000000000000000000000000000000000C3
-:10DD600000000000000000000000000000000000B3
-:10DD700000000000000000000000000000000000A3
-:10DD80000000000000000000000000000000000093
-:10DD90000000000000000000000000000000000083
-:10DDA0000000000000000000000000000000000073
-:10DDB0000000000000000000000000000000000063
-:10DDC0000000000000000000000000000000000053
-:10DDD0000000000000000000000000000000000043
-:10DDE0000000000000000000000000000000000033
-:10DDF0000000000000000000000000000000000023
-:10DE00000000000000000000000000000000000012
-:10DE10000000000000000000000000000000000002
-:10DE200000000000000000000000000000000000F2
-:10DE300000000000000000000000000000000000E2
-:10DE400000000000000000000000000000000000D2
-:10DE500000000000000000000000000000000000C2
-:10DE600000000000000000000000000000000000B2
-:10DE700000000000000000000000000000000000A2
-:10DE80000000000000000000000000000000000092
-:10DE90000000000000000000000000000000000082
-:10DEA0000000000000000000000000000000000072
-:10DEB0000000000000000000000000000000000062
-:10DEC0000000000000000000000000000000000052
-:10DED0000000000000000000000000000000000042
-:10DEE0000000000000000000000000000000000032
-:10DEF0000000000000000000000000000000000022
-:10DF00000000000000000000000000000000000011
-:10DF10000000000000000000000000000000000001
-:10DF200000000000000000000000000000000000F1
-:10DF300000000000000000000000000000000000E1
-:10DF400000000000000000000000000000000000D1
-:10DF500000000000000000000000000000000000C1
-:10DF600000000000000000000000000000000000B1
-:10DF700000000000000000000000000000000000A1
-:10DF80000000000000000000000000000000000091
-:10DF90000000000000000000000000000000000081
-:10DFA0000000000000000000000000000000000071
-:10DFB0000000000000000000000000000000000061
-:10DFC0000000000000000000000000000000000051
-:10DFD0000000000000000000000000000000000041
-:10DFE0000000000000000000000000000000000031
-:10DFF0000000000000000000000000000000000021
-:10E000000000000000000000000000000000000010
-:10E010000000000000000000000000000000000000
-:10E0200000000000000000000000000000000000F0
-:10E0300000000000000000000000000000000000E0
-:10E0400000000000000000000000000000000000D0
-:10E0500000000000000000000000000000000000C0
-:10E0600000000000000000000000000000000000B0
-:10E0700000000000000000000000000000000000A0
-:10E080000000000000000000000000000000000090
-:10E090000000000000000000000000000000000080
-:10E0A0000000000000000000000000000000000070
-:10E0B0000000000000000000000000000000000060
-:10E0C0000000000000000000000000000000000050
-:10E0D0000000000000000000000000000000000040
-:10E0E0000000000000000000000000000000000030
-:10E0F0000000000000000000000000000000000020
-:10E10000000000000000000000000000000000000F
-:10E1100000000000000000000000000000000000FF
-:10E1200000000000000000000000000000000000EF
-:10E1300000000000000000000000000000000000DF
-:10E1400000000000000000000000000000000000CF
-:10E1500000000000000000000000000000000000BF
-:10E1600000000000000000000000000000000000AF
-:10E17000000000000000000000000000000000009F
-:10E18000000000000000000000000000000000008F
-:10E19000000000000000000000000000000000007F
-:10E1A000000000000000000000000000000000006F
-:10E1B000000000000000000000000000000000005F
-:10E1C000000000000000000000000000000000004F
-:10E1D000000000000000000000000000000000003F
-:10E1E000000000000000000000000000000000002F
-:10E1F000000000000000000000000000000000809F
-:10E20000000000000000000000000000000000000E
-:10E2100000000000000000000000000000000000FE
-:10E220000000000A000000000000000000000000E4
-:10E2300010000003000000000000000D0000000DB1
-:10E240003C020801244295A03C030801246397DCAA
-:10E25000AC4000000043202B1480FFFD244200044A
-:10E260003C1D080037BD9FFC03A0F0213C100800B6
-:10E27000261032103C1C0801279C95A00E0012BEEF
-:10E28000000000000000000D3C02800030A5FFFFF0
-:10E2900030C600FF344301803C0880008D0901B87E
-:10E2A0000520FFFE00000000AC6400002404000212
-:10E2B000A4650008A066000AA064000BAC67001803
-:10E2C0003C03100003E00008AD0301B83C0560000A
-:10E2D0008CA24FF80440FFFE00000000ACA44FC029
-:10E2E0003C0310003C040200ACA44FC403E000084F
-:10E2F000ACA34FF89486000C00A050212488001491
-:10E3000000062B0200051080004448210109182B4B
-:10E310001060001100000000910300002C6400094F
-:10E320005080000991190001000360803C0D080134
-:10E3300025AD9234018D58218D67000000E0000862
-:10E340000000000091190001011940210109302B42
-:10E3500054C0FFF29103000003E000080000102108
-:10E360000A000CCC25080001910F0001240E000AC0
-:10E3700015EE00400128C8232F38000A1700003D81
-:10E38000250D00028D580000250F0006370E0100F4
-:10E39000AD4E0000910C000291AB000191A400026F
-:10E3A00091A60003000C2E00000B3C0000A71025D6
-:10E3B00000041A000043C8250326C025AD580004F8
-:10E3C000910E000691ED000191E7000291E5000336
-:10E3D000000E5E00000D6400016C30250007220075
-:10E3E00000C41025004518252508000A0A000CCC99
-:10E3F000AD430008910F000125040002240800022B
-:10E4000055E80001012020210A000CCC00804021A9
-:10E41000910C0001240B0003158B00160000000076
-:10E420008D580000910E000225080003370D0008EA
-:10E43000A14E00100A000CCCAD4D00009119000156
-:10E44000240F0004172F000B0000000091070002AA
-:10E45000910400038D43000000072A0000A410254A
-:10E460003466000425080004AD42000C0A000CCC00
-:10E47000AD46000003E000082402000127BDFFE8CC
-:10E48000AFBF0014AFB000100E00164E0080802108
-:10E490003C0480083485008090A600052403FFFE1C
-:10E4A0000200202100C310248FBF00148FB0001081
-:10E4B000A0A200050A00165827BD001827BDFFE8D6
-:10E4C000AFB00010AFBF00140E000FD40080802149
-:10E4D0003C06800834C5008090A40000240200504F
-:10E4E000308300FF106200073C09800002002021F9
-:10E4F0008FBF00148FB00010AD2001800A00108F74
-:10E5000027BD0018240801003C07800002002021DC
-:10E510008FBF00148FB00010ACE801800A00108F8C
-:10E5200027BD001827BDFF783C058008AFBE0080DE
-:10E53000AFB7007CAFB3006CAFB10064AFBF008475
-:10E54000AFB60078AFB50074AFB40070AFB200687A
-:10E55000AFB0006034A600803C0580008CB201287A
-:10E5600090C400098CA701043C020001309100FF17
-:10E5700000E218240000B8210000F021106000071C
-:10E58000000098213C0908008D2931F02413000176
-:10E59000252800013C010800AC2831F0ACA0008423
-:10E5A00090CC0005000C5827316A0001154000721C
-:10E5B000AFA0005090CD00002406002031A400FF41
-:10E5C00010860018240E0050108E009300000000EA
-:10E5D0003C1008008E1000DC260F00013C010800F2
-:10E5E000AC2F00DC0E0016C7000000000040182110
-:10E5F0008FBF00848FBE00808FB7007C8FB60078FD
-:10E600008FB500748FB400708FB3006C8FB2006848
-:10E610008FB100648FB000600060102103E000083B
-:10E6200027BD00880000000D3C1F8000AFA0003017
-:10E6300097E501168FE201043C04002030B9FFFF8A
-:10E64000004438240007182B00033140AFA60030E7
-:10E650008FF5010437F80C003C1600400338802188
-:10E6600002B6A02434C40040128000479215000D69
-:10E6700032A800201500000234860080008030217E
-:10E6800014C0009FAFA600303C0D800835A6008066
-:10E6900090CC0008318B0040516000063C06800899
-:10E6A000240E0004122E00A8240F0012122F003294
-:10E6B0003C06800834C401003C0280009447011AE3
-:10E6C0009619000E909F00088E18000830E3FFFF97
-:10E6D00003F9B00432B40004AFB6005CAFA3005835
-:10E6E0008E1600041280002EAFB8005434C3008090
-:10E6F000906800083105004014A0002500000000CB
-:10E700008C70005002D090230640000500000000ED
-:10E710008C71003402D1A82306A201678EE20008A2
-:10E72000126000063C1280003C1508008EB531F4E2
-:10E7300026B600013C010800AC3631F4AE4000447E
-:10E74000240300018FBF00848FBE00808FB7007C40
-:10E750008FB600788FB500748FB400708FB3006CE3
-:10E760008FB200688FB100648FB00060006010212C
-:10E7700003E0000827BD00880E000D2800002021BE
-:10E780000A000D75004018210A000D9500C02021D7
-:10E790000E00171702C020211440FFE10000000006
-:10E7A0003C0B8008356400808C8A003402CA482300
-:10E7B0000520001D000000003C1E08008FDE310017
-:10E7C00027D700013C010800AC3731001260000679
-:10E7D000024020213C1408008E9431F42690000160
-:10E7E0003C010800AC3031F40E00164E3C1E80088F
-:10E7F00037CD008091B700250240202136EE00047D
-:10E800000E001658A1AE00250E000CAC02402021CF
-:10E810000A000DCA240300013C17080126F796A040
-:10E820000A000D843C1F80008C86003002C66023E5
-:10E830001980000C2419000C908F004F3C14080024
-:10E840008E94310032B500FC35ED0001268E0001BA
-:10E850003C010800AC2E3100A08D004FAFA0005845
-:10E860002419000CAFB900308C9800300316A02397
-:10E870001A80010B8FA300580074F82A17E0FFD309
-:10E88000000000001074002A8FA5005802D4B021A7
-:10E8900000B410233044FFFFAFA4005832A8000298
-:10E8A0001100002E32AB00103C15800836B00080FD
-:10E8B0009216000832D30040526000FB8EE200083E
-:10E8C0000E00164E02402021240A0018A20A000958
-:10E8D000921100052409FFFE024020210229902404
-:10E8E0000E001658A2120005240400390000282149
-:10E8F0000E0016F2240600180A000DCA24030001B7
-:10E9000092FE000C3C0A800835490080001EBB00C6
-:10E910008D27003836F10081024020213225F08118
-:10E920000E000C9B30C600FF0A000DC10000000065
-:10E930003AA7000130E300011460FFA402D4B02123
-:10E940000A000E1D00000000024020210E001734B6
-:10E95000020028210A000D75004018211160FF7087
-:10E960003C0F80083C0D800835EE00808DC40038D7
-:10E970008FA300548DA60004006660231D80FF68ED
-:10E98000000000000064C02307020001AFA400548F
-:10E990003C1F08008FFF31E433F9000113200015FC
-:10E9A0008FAC00583C07800094E3011A10600012FD
-:10E9B0003C0680080E002161024020213C03080132
-:10E9C000906396D13064000214800145000000007D
-:10E9D000306C0004118000078FAC0058306600FBDB
-:10E9E0003C010801A02696D132B500FCAFA000582A
-:10E9F0008FAC00583C06800834D30080AFB40018B8
-:10EA0000AFB60010AFAC00143C088000950B01209D
-:10EA10008E6F0030966A005C8FA3005C8FBF003061
-:10EA20003169FFFF3144FFFF8FAE005401341021E4
-:10EA3000350540000064382B0045C82103E7C02598
-:10EA4000AFB90020AFAF0028AFB80030AFAF00249F
-:10EA5000AFA0002CAFAE0034926D000831B40008B6
-:10EA6000168000BB020020218EE200040040F8095D
-:10EA700027A400108FAF003031F300025660000170
-:10EA800032B500FE3C048008349F008093F90008F2
-:10EA900033380040530000138FA400248C850004F9
-:10EAA0008FA7005410A700D52404001432B0000131
-:10EAB0001200000C8FA400242414000C1234011A3C
-:10EAC0002A2D000D11A001022413000E240E000AAD
-:10EAD000522E0001241E00088FAF002425E40001FF
-:10EAE000AFA400248FAA00143C0B80083565008079
-:10EAF000008A48218CB10030ACA9003090A4004EAF
-:10EB00008CA700303408FFFF0088180400E3F821C8
-:10EB1000ACBF00348FA600308FB900548FB8005CB2
-:10EB200030C200081040000B033898218CAC002044
-:10EB3000119300D330C600FF92EE000C8FA7003473
-:10EB400002402021000E6B0035B400800E000C9BAB
-:10EB50003285F0803C028008345000808E0F0030F7
-:10EB600001F1302318C00097264800803C070800B8
-:10EB70008CE731E42404FF80010418243118007F5D
-:10EB80003C1F80003C19800430F10001AFE300908D
-:10EB900012200006031928213C030801906396D136
-:10EBA00030690008152000C6306A00F73C10800864
-:10EBB00036040080908C004F318B000115600042BC
-:10EBC000000000003C0608008CC6319830CE0010D2
-:10EBD00051C0004230F9000190AF006B55E0003F9A
-:10EBE00030F9000124180001A0B8006B3C1180002E
-:10EBF0009622007A24470064A48700123C0D800806
-:10EC000035A5008090B40008329000401600000442
-:10EC10003C03800832AE000115C0008B00000000EC
-:10EC2000346400808C86002010D3000A3463010015
-:10EC30008C67000002C7782319E000978FBF00544B
-:10EC4000AC93002024130001AC760000AFB3005059
-:10EC5000AC7F000417C0004E000000008FA90050D8
-:10EC60001520000B000000003C030801906396D1C2
-:10EC7000306A00011140002E8FAB0058306400FE56
-:10EC80003C010801A02496D10A000D75000018214E
-:10EC90000E000CAC024020210A000F1300000000FF
-:10ECA0000A000E200000A0210040F80924040017EB
-:10ECB0000A000DCA240300010040F80924040016CC
-:10ECC0000A000DCA240300019094004F240DFFFE9A
-:10ECD000028D2824A085004F30F900011320000682
-:10ECE0003C0480083C030801906396D1307F0010FB
-:10ECF00017E00051306800EF34900080240A0001D2
-:10ED0000024020210E00164EA60A00129203002592
-:10ED100024090001AFA90050346200010240202103
-:10ED20000E001658A20200250A000EF93C0D8008BC
-:10ED30001160FE83000018218FA5003030AC000464
-:10ED40001180FE2C8FBF00840A000DCB240300012C
-:10ED500027A500380E000CB6AFA000385440FF4382
-:10ED60008EE200048FB40038329001005200FF3F61
-:10ED70008EE200048FA3003C8E6E0058006E682364
-:10ED800005A3FF39AE6300580A000E948EE200041A
-:10ED90000E00164E024020213C038008346800809B
-:10EDA000024020210E001658A11E000903C0302188
-:10EDB000240400370E0016F2000028210A000F116B
-:10EDC0008FA900508FAB00185960FF8D3C0D800853
-:10EDD0000E00164E02402021920C00252405000151
-:10EDE000AFA5005035820004024020210E001658C5
-:10EDF000A20200250A000EF93C0D800812240059D9
-:10EE00002A2300151060004D240900162408000C68
-:10EE10005628FF2732B000013C0A8008914C001BA5
-:10EE20002406FFBD241E000E01865824A14B001BA2
-:10EE30000A000EA532B000013C010801A02896D1BD
-:10EE40000A000EF93C0D80088CB500308EFE0008DB
-:10EE50002404001826B6000103C0F809ACB600303F
-:10EE60003C030801906396D13077000116E0FF81E2
-:10EE7000306A00018FB200300A000D753243000481
-:10EE80003C1080009605011A50A0FF2B34C60010DC
-:10EE90000A000EC892EE000C8C6200001456FF6D42
-:10EEA000000000008C7800048FB9005403388823D8
-:10EEB0000621FF638FBF00540A000F0E0000000000
-:10EEC0003C010801A02A96D10A000F3030F9000158
-:10EED0001633FF028FAF00240A000EB0241E00106C
-:10EEE0000E00164E024020213C0B80083568008041
-:10EEF00091090025240A0001AFAA0050353300040F
-:10EF0000024020210E001658A11300253C050801DF
-:10EF100090A596D130A200FD3C010801A02296D117
-:10EF20000A000E6D004018212411000E53D1FEEA94
-:10EF3000241E00100A000EAF241E00165629FEDC07
-:10EF400032B000013C0A8008914C001B2406FFBD32
-:10EF5000241E001001865824A14B001B0A000EA598
-:10EF600032B000010A000EA4241E00123C038000EF
-:10EF70008C6201B80440FFFE24040800AC6401B8B0
-:10EF800003E000080000000030A5FFFF30C6FFFFCF
-:10EF90003C0780008CE201B80440FFFE34EA0180A7
-:10EFA000AD440000ACE400203C0480089483004899
-:10EFB0003068FFFF11000016AF88000824AB001274
-:10EFC000010B482B512000133C04800034EF01005A
-:10EFD00095EE00208F890000240D001A31CCFFFF30
-:10EFE00031274000A14D000B10E000362583FFFEC5
-:10EFF0000103C02B170000348F9900048F88000490
-:10F00000A5430014350700010A001003AF87000470
-:10F010003C04800024030003348201808F890000B7
-:10F020008F870004A043000B3C088000350C018052
-:10F03000A585000EA585001A8F85000C30EB800099
-:10F04000A5890010AD850028A58600081160000F75
-:10F050008F85001435190100972A00163158FFFCDE
-:10F06000270F000401E870218DCD400031A6FFFF7D
-:10F0700014C000072403BFFF3C02FFFF34487FFF9A
-:10F0800000E83824AF8700048F8500142403BFFFF5
-:10F090003C04800000E3582434830180A46B0026E4
-:10F0A000AC69002C10A0000300054C02A465001000
-:10F0B000A46900263C071000AC8701B803E00008F3
-:10F0C000000000008F990004240AFFFE032A382460
-:10F0D0000A001003AF87000427BDFFE88FA20028B5
-:10F0E00030A5FFFF30C6FFFFAFBF0010AF87000C99
-:10F0F000AF820014AF8000040E000FDBAF80000071
-:10F100008FBF001027BD001803E00008AF80001477
-:10F110003C06800034C4007034C701008C8A0000B3
-:10F1200090E500128F84000027BDFFF030A300FFA0
-:10F13000000318823082400010400037246500032D
-:10F140000005C8800326C0218F0E4000246F0004F4
-:10F15000000F6880AFAE000001A660218D8B4000DB
-:10F16000AFAB000494E900163128FFFC01063821FA
-:10F170008CE64000AFA600088FA9000800003021EF
-:10F18000000028213C07080024E701000A0010675E
-:10F19000240800089059000024A500012CAC000CA4
-:10F1A0000079C0210018788001E770218DCD000022
-:10F1B0001180000600CD302603A5102114A8FFF50C
-:10F1C00000051A005520FFF4905900003C0480000F
-:10F1D000348700703C0508008CA531048CE30000E6
-:10F1E0002CA2002010400009006A38230005488046
-:10F1F0003C0B0800256B3108012B402124AA00019B
-:10F20000AD0700003C010800AC2A310400C0102109
-:10F2100003E0000827BD0010308220001040000BE2
-:10F2200000055880016648218D24400024680004B0
-:10F2300000083880AFA4000000E618218C6540006B
-:10F24000AFA000080A001057AFA500040000000D91
-:10F250000A0010588FA9000827BDFFE03C07800076
-:10F2600034E60100AFBF001CAFB20018AFB100140C
-:10F27000AFB0001094C5000E8F87000030A4FFFFD0
-:10F280002483000430E2400010400010AF830028C7
-:10F290003C09002000E940241100000D30EC800002
-:10F2A0008F8A0004240BBFFF00EB38243543100085
-:10F2B000AF87000030F220001640000B3C1900041C
-:10F2C000241FFFBF0A0010B7007F102430EC80001D
-:10F2D000158000423C0E002030F220001240FFF862
-:10F2E0008F8300043C19000400F9C0241300FFF5CB
-:10F2F000241FFFBF34620040AF82000430E20100EF
-:10F300001040001130F010008F83002C10600006B8
-:10F310003C0F80003C05002000E52024148000C044
-:10F320003C0800043C0F800035EE010095CD001E26
-:10F3300095CC001C31AAFFFF000C5C00014B482556
-:10F34000AF89000C30F010001200000824110001F9
-:10F3500030F100201620008B3C18100000F890249B
-:10F36000164000823C040C002411000130E801002A
-:10F370001500000B3C0900018F85000430A94000F6
-:10F38000152000073C0900013C0C1F0100EC58242B
-:10F390003C0A1000116A01183C1080003C09000171
-:10F3A00000E9302410C000173C0B10003C18080086
-:10F3B0008F1800243307000214E0014024030001E9
-:10F3C0008FBF001C8FB200188FB100148FB00010D7
-:10F3D0000060102103E0000827BD002000EE682433
-:10F3E00011A0FFBE30F220008F8F00043C11FFFF00
-:10F3F00036307FFF00F0382435E380000A0010A685
-:10F40000AF87000000EB102450400065AF8000245F
-:10F410008F8C002C3C0D0F0000ED18241580008807
-:10F42000AF83001030E8010011000086938F0010B8
-:10F430003C0A0200106A00833C1280003650010032
-:10F44000920500139789002A3626000230AF00FF8C
-:10F4500025EE0004000E19C03C0480008C9801B811
-:10F460000700FFFE34880180AD0300003C198008CE
-:10F47000AC830020973100483225FFFF10A0015CCB
-:10F48000AF8500082523001200A3F82B53E0015993
-:10F490008F850004348D010095AC00202402001AF1
-:10F4A00030E44000318BFFFFA102000B108001927D
-:10F4B0002563FFFE00A3502B154001908F8F0004A1
-:10F4C000A50300148F88000435050001AF850004F2
-:10F4D0003C08800035190180A729000EA729001AD1
-:10F4E0008F89000C30B18000A7270010AF290028B9
-:10F4F000A72600081220000E3C04800035020100FF
-:10F50000944C0016318BFFFC256400040088182100
-:10F510008C7F400033E6FFFF14C000053C048000F0
-:10F520003C0AFFFF354D7FFF00AD2824AF85000466
-:10F53000240EBFFF00AE402434850180A4A800261D
-:10F54000ACA7002C3C071000AC8701B800001821C4
-:10F550008FBF001C8FB200188FB100148FB0001045
-:10F560000060102103E0000827BD00203C020BFFD3
-:10F5700000E41824345FFFFF03E3C82B5320FF7B14
-:10F58000241100013C0608008CC6002C24C5000193
-:10F590003C010800AC25002C0A0010D42411000501
-:10F5A0008F85002410A0002FAF80001090A30000D2
-:10F5B000146000792419000310A0002A30E601002D
-:10F5C00010C000CC8F860010241F000210DF00C97D
-:10F5D0008F8B000C3C0708008CE7003824E4FFFF09
-:10F5E00014E0000201641824000018213C0D0800FA
-:10F5F00025AD0038006D1021904C00048F85002847
-:10F6000025830004000321C030A5FFFF3626000239
-:10F610000E000FDB000000000A00114D0000182151
-:10F6200000E8302414C0FF403C0F80000E00103D65
-:10F63000000000008F8700000A0010CAAF82000C93
-:10F64000938F00103C18080127189620000F90C0D7
-:10F6500002588021AF9000248F85002414A0FFD38E
-:10F66000AF8F00103C0480008C86400030C5010044
-:10F6700010A000BC322300043C0C08008D8C002438
-:10F6800024120004106000C23190000D3C04800080
-:10F690008C8D40003402FFFF11A201003231FFFBCC
-:10F6A0008C884000310A01005540000124110010EF
-:10F6B00030EE080011C000BE2419FFFB8F9800280F
-:10F6C0002F0F03EF51E000010219802430E90100FF
-:10F6D00011200014320800018F87002C14E000FB79
-:10F6E0008F8C000C3C05800034AB0100917F00132F
-:10F6F00033E300FF246A00042403FFFE0203802496
-:10F70000000A21C012000002023230253226FFFF1B
-:10F710000E000FDB9785002A1200FF290000182138
-:10F72000320800011100000D32180004240E0001FF
-:10F73000120E0002023230253226FFFF9785002A82
-:10F740000E000FDB00002021240FFFFE020F80249B
-:10F750001200FF1B00001821321800045300FF188C
-:10F760002403000102323025241200045612000145
-:10F770003226FFFF9785002A0E000FDB24040100CC
-:10F780002419FFFB021988241220FF0D0000182104
-:10F790000A0010E9240300011079009C00003021C8
-:10F7A00090AD00012402000211A200BE30EA004028
-:10F7B00090B90001241800011338007F30E900409F
-:10F7C0008CA600049785002A00C020210E000FDBC4
-:10F7D0003626000200004021010018218FBF001CC6
-:10F7E0008FB200188FB100148FB00010006010218C
-:10F7F00003E0000827BD0020360F010095EE000C45
-:10F8000031CD020015A0FEE63C0900013C1880083D
-:10F81000971200489789002A362600023248FFFFD7
-:10F82000AF8800083C0380008C7101B80620FFFE01
-:10F83000346A0180AD4000001100008E3C0F800052
-:10F84000253F0012011FC82B1320008B240E00033C
-:10F85000346C0100958B00202402001A30E4400033
-:10F860003163FFFFA142000B108000A72463FFFE5D
-:10F870000103682B15A000A52408FFFE34A5000194
-:10F88000A5430014AF8500043C0480002412BFFF90
-:10F8900000B2802434850180A4A9000EA4A9001A16
-:10F8A000A4A60008A4B00026A4A700103C071000DE
-:10F8B000AC8701B80A00114D000018213C038000FC
-:10F8C00034640100949F000E3C1908008F3900D861
-:10F8D0002404008033E5FFFF273100013C010800CC
-:10F8E000AC3100D80E000FDB240600030A00114DD6
-:10F8F00000001821240A000210CA00598F85002830
-:10F900003C0308008C6300D0240E0001106E005EE2
-:10F910002CCF000C24D2FFFC2E5000041600002136
-:10F9200000002021241800021078001B2CD9000CA4
-:10F9300024DFFFF82FE900041520FF330000202109
-:10F9400030EB020051600004000621C054C00022C8
-:10F9500030A5FFFF000621C030A5FFFF0A00117D82
-:10F96000362600023C0908008D29002431300001B0
-:10F970005200FEF7000018219785002A3626000263
-:10F980000E000FDB000020210A00114D000018219D
-:10F990000A00119C241200021320FFE624DFFFF866
-:10F9A0000000202130A5FFFF0A00117D362600024D
-:10F9B0000A0011AC021980245120FF828CA6000499
-:10F9C0003C05080190A5962110A0FF7E24080001A7
-:10F9D0000A0011F0010018210E000FDB3226000191
-:10F9E0008F8600108F8500280A00124F000621C064
-:10F9F0008F8500043C18800024120003371001801A
-:10FA0000A212000B0A00112E3C08800090A30001F6
-:10FA1000241100011071FF70240800012409000264
-:10FA20005069000430E60040240800010A0011F08B
-:10FA30000100182150C0FFFD240800013C0C80008B
-:10FA4000358B01009563001094A40002307FFFFF06
-:10FA5000509FFF62010018210A001284240800014F
-:10FA60002CA803EF1100FE56240300010A001239EE
-:10FA700000000000240E000335EA0180A14E000BB7
-:10FA80000A00121C3C04800011E0FFA2000621C005
-:10FA900030A5FFFF0A00117D362600020A0011A5DD
-:10FAA000241100201140FFC63C1280003650010096
-:10FAB000960F001094AE000231E80FFF15C8FFC08A
-:10FAC000000000000A0011E690B900013C060800A1
-:10FAD0008CC6003824C4FFFF14C00002018418241F
-:10FAE000000018213C0D080025AD0038006D1021E4
-:10FAF0000A0011B6904300048F8F0004240EFFFE0D
-:10FB00000A00112C01EE28242408FFFE0A00121A14
-:10FB100000A8282427BDFFC8AFB00010AFBF003435
-:10FB20003C10600CAFBE0030AFB7002CAFB6002861
-:10FB3000AFB50024AFB40020AFB3001CAFB20018C3
-:10FB4000AFB100148E0E5000240FFF7F3C068000E2
-:10FB500001CF682435AC380C240B0003AE0C5000E8
-:10FB6000ACCB00083C010800AC2000200E001819A6
-:10FB7000000000003C0A0010354980513C06601628
-:10FB8000AE09537C8CC700003C0860148D0500A0B2
-:10FB90003C03FFFF00E320243C02535300051FC237
-:10FBA0001482000634C57C000003A08002869821E0
-:10FBB0008E7200043C116000025128218CBF007C31
-:10FBC0008CA200783C1E600037C420203C05080150
-:10FBD00024A59264AF820018AF9F001C0E0016DDB2
-:10FBE0002406000A3C190001273996203C01080030
-:10FBF000AC3931DC0E0020D4AF8000148FD7080858
-:10FC00002418FFF03C15570902F8B02412D502F56C
-:10FC100024040001AF80002C3C1480003697018042
-:10FC20003C1E080127DE9624369301008E900000CA
-:10FC30003205000310A0FFFD3207000110E000882C
-:10FC4000320600028E7100283C048000AE91002034
-:10FC50008E6500048E66000000A0382100C040219F
-:10FC60008C8301B80460FFFE3C0B0010240A0800DE
-:10FC700000AB4824AC8A01B8552000E0240BBFFF3C
-:10FC80009675000E3C1208008E52002030AC4000E9
-:10FC900032AFFFFF264E000125ED00043C010800B5
-:10FCA000AC2E0020118000E8AF8D00283C18002009
-:10FCB00000B8B02412C000E530B980002408BFFFAE
-:10FCC00000A8382434C81000AF87000030E62000B8
-:10FCD00010C000E92409FFBF3C03000400E328240E
-:10FCE00010A00002010910243502004030EA010092
-:10FCF00011400010AF8200048F8B002C11600007B0
-:10FD00003C0D002000ED6024118000043C0F000435
-:10FD100000EF702411C00239000000009668001E38
-:10FD20009678001C3115FFFF0018B40002B690252C
-:10FD3000AF92000C30F910001320001324150001BD
-:10FD400030FF002017E0000A3C04100000E41024FB
-:10FD50001040000D3C0A0C003C090BFF00EA18247F
-:10FD60003525FFFF00A3302B10C0000830ED010047
-:10FD70003C0C08008D8C002C24150005258B0001FF
-:10FD80003C010800AC2B002C30ED010015A0000B4D
-:10FD90003C0500018F85000430AE400055C00007CF
-:10FDA0003C0500013C161F0100F690243C0F10009A
-:10FDB000124F01CE000000003C05000100E5302498
-:10FDC00010C000AF3C0C10003C1F08008FFF002447
-:10FDD00033E90002152000712403000100601021A6
-:10FDE000104000083C0680003C08800035180100E7
-:10FDF0008F0F00243C056020ACAF00140000000011
-:10FE00003C0680003C194000ACD9013800000000DD
-:10FE10005220001332060002262B0140262C0080BF
-:10FE2000240EFF80016E2024018E6824000D1940ED
-:10FE3000318A007F0004A9403172007F3C16200007
-:10FE400036C20002006A482502B2382500E2882541
-:10FE50000122F825ACDF0830ACD1083032060002B0
-:10FE600010C0FF723C188000370501408CA80000CC
-:10FE700024100040AF08002090AF000831E300706C
-:10FE8000107000D428790041532000082405006038
-:10FE9000241100201071000E3C0A40003C09800033
-:10FEA000AD2A01780A001304000000001465FFFB6E
-:10FEB0003C0A40000E001FF1000000003C0A400018
-:10FEC0003C098000AD2A01780A00130400000000FC
-:10FED00090A90009241F00048CA70000312800FF0E
-:10FEE000111F01B22503FFFA2C7200061240001404
-:10FEF0003C0680008CA9000494A4000A310500FF90
-:10FF000000095E022D6A00083086FFFF15400002DE
-:10FF10002567000424070003240C000910AC01FA33
-:10FF200028AD000A11A001DE2410000A240E0008EA
-:10FF300010AE0028000731C000C038213C06800008
-:10FF40008CD501B806A0FFFE34D20180AE47000078
-:10FF500034CB0140916E0008240300023C0A4000AB
-:10FF600031C400FF00046A0001A86025A64C000807
-:10FF7000A243000B9562000A3C0810003C09800077
-:10FF8000A64200108D670004AE470024ACC801B83B
-:10FF9000AD2A01780A001304000000003C0A80002A
-:10FFA000354401009483000E3C0208008C4200D8C6
-:10FFB000240400803065FFFF245500013C01080047
-:10FFC000AC3500D80E000FDB240600030A001370C6
-:10FFD000000018210009320230D900FF2418000166
-:10FFE0001738FFD5000731C08F910020262200016D
-:10FFF000AF8200200A0013C800C0382100CB2024A3
-:020000040001F9
-:10000000AF85000010800008AF860004240D87FF34
-:1000100000CD6024158000083C0E006000AE302446
-:1000200010C00005000000000E000D42000000009E
-:100030000A001371000000000E0016050000000009
-:100040000A0013710000000030B980005320FF1F28
-:10005000AF8500003C02002000A2F82453E0FF1B03
-:10006000AF8500003C07FFFF34E47FFF00A4382485
-:100070000A00132B34C880000A001334010910242D
-:1000800000EC58245160005AAF8000248F8D002C62
-:100090003C0E0F0000EE182415A00075AF83001071
-:1000A00030EF010011E00073939800103C12020041
-:1000B000107200703C06800034D9010093280013B0
-:1000C0009789002A36A60002311800FF271600047F
-:1000D000001619C03C0480008C8501B804A0FFFE06
-:1000E00034880180AD0300003C158008AC830020FB
-:1000F00096BF004833E5FFFF10A001BCAF850008A4
-:100100002523001200A3102B504001B98F85000455
-:10011000348D010095AC0020240B001A30E440001F
-:10012000318AFFFFA10B000B108001BA2543FFFEAF
-:1001300000A3702B15C001B88F9600048F8F0004A8
-:10014000A503001435E50001AF8500043C088000DC
-:1001500035150180A6A9000EA6A9001A8F89000CEA
-:1001600030BF8000A6A70010AEA90028A6A60008F0
-:1001700013E0000F3C0F8000350C0100958B00163A
-:10018000316AFFFC25440004008818218C6240007D
-:100190003046FFFF14C000072416BFFF3C0EFFFFD0
-:1001A00035CD7FFF00AD2824AF8500043C0F8000D3
-:1001B0002416BFFF00B6902435E50180A4B20026C6
-:1001C000ACA7002C3C071000ADE701B80A00137083
-:1001D000000018210E00165D000000003C0A4000DF
-:1001E0003C098000AD2A01780A00130400000000D9
-:1001F0008F85002410A00027AF80001090A300007E
-:10020000106000742409000310690101000030210E
-:1002100090AE0001240D000211CD014230EF0040EC
-:1002200090A90001241F0001113F000930E20040A5
-:100230008CA600049785002A00C020210E000FDB49
-:1002400036A60002000040210A00137001001821A8
-:100250005040FFF88CA600043C07080190E7962167
-:1002600010E0FFF4240800010A00137001001821B7
-:10027000939800103C1F080127FF96200018C8C063
-:10028000033F4021AF8800248F85002414A0FFDBAA
-:10029000AF9800103C0480008C86400030C50100FF
-:1002A00010A0008732AB00043C0C08008D8C0024A9
-:1002B00024160004156000033192000D241600027C
-:1002C0003C0480008C8E4000340DFFFF11CD0113E3
-:1002D00032B5FFFB8C984000330F010055E0000160
-:1002E0002415001030E80800110000382409FFFB35
-:1002F0008F9F00282FF903EF53200001024990241B
-:1003000030E2010010400014325F00018F87002CA2
-:1003100014E0010E8F8C000C3C0480003486010038
-:1003200090C5001330AA00FF25430004000321C03C
-:100330002419FFFE025990241240000202B6302513
-:1003400032A6FFFF0E000FDB9785002A1240FEA3A6
-:1003500000001821325F000113E0000D3247000455
-:10036000240900011249000202B6302532A6FFFF1F
-:100370009785002A0E000FDB000020212402FFFEDB
-:10038000024290241240FE950000182132470004DA
-:1003900050E0FE922403000102B63025241600042A
-:1003A0005656000132A6FFFF9785002A0E000FDB8C
-:1003B000240401002403FFFB0243A82412A0FE87AB
-:1003C000000018210A001370240300010A0014B968
-:1003D0000249902410A0FFAF30E5010010A00017E3
-:1003E0008F8600102403000210C300148F84000CB9
-:1003F0003C0608008CC6003824CAFFFF14C0000267
-:10040000008A1024000010213C0E080025CE003880
-:10041000004E682191AC00048F850028258B0004D4
-:10042000000B21C030A5FFFF36A600020E000FDB37
-:10043000000000000A00137000001821240F0002C1
-:1004400010CF0088241600013C0308008C6300D004
-:100450001076008D8F85002824D9FFFC2F280004FA
-:100460001500006300002021241F0002107F005DA2
-:100470002CC9000C24C3FFF82C6200041440FFE9CF
-:100480000000202130EA020051400004000621C093
-:1004900054C0000530A5FFFF000621C030A5FFFFB6
-:1004A0000A00150436A600020E000FDB32A600017A
-:1004B0008F8600108F8500280A001520000621C0B5
-:1004C0003C0A08008D4A0024315200015240FE438C
-:1004D000000018219785002A36A600020E000FDBC7
-:1004E000000020210A001370000018219668000CFB
-:1004F000311802005700FE313C0500013C1F800806
-:1005000097F900489789002A36A600023328FFFF92
-:10051000AF8800083C0380008C7501B806A0FFFE80
-:100520003C04800034820180AC400000110000B621
-:1005300024180003252A0012010A182B106000B2AB
-:1005400000000000966F00203C0E8000240D001A71
-:1005500031ECFFFF35CA018030EB4000A14D000BAC
-:10056000116000B02583FFFE0103902B164000AE02
-:100570002416FFFE34A50001A5430014AF85000436
-:100580002419BFFF00B94024A6E9000EA6E9001A0D
-:10059000A6E60008A6E80026A6E700103C07100023
-:1005A000AE8701B80A001370000018213C048000D7
-:1005B0008C8201B80440FFFE349601802415001C93
-:1005C000AEC70000A2D5000B3C071000AC8701B8F5
-:1005D0003C0A40003C098000AD2A01780A0013045F
-:1005E000000000005120FFA424C3FFF800002021D8
-:1005F00030A5FFFF0A00150436A600020E00103DCC
-:10060000000000008F8700000A001346AF82000C34
-:1006100090A30001241500011075FF0B24080001B0
-:10062000240600021066000430E2004024080001A5
-:100630000A001370010018215040FFFD240800013A
-:100640003C0C8000358B0100956A001094A40002D8
-:100650003143FFFF5083FDE1010018210A00158599
-:10066000240800018F8500282CB203EF1240FDDB27
-:10067000240300013C0308008C6300D02416000111
-:100680001476FF7624D9FFFC2CD8000C1300FF72DF
-:10069000000621C030A5FFFF0A00150436A600029F
-:1006A00010B00037240F000B14AFFE23000731C039
-:1006B000312600FF00065600000A4E0305220047BF
-:1006C00030C6007F0006F8C03C16080126D69620EA
-:1006D00003F68021A2000001A20000003C0F600090
-:1006E0008DF918202405000100C588040011302769
-:1006F0000326C024000731C000C03821ADF81820FF
-:100700000A0013C8A60000028F850020000731C030
-:1007100024A2FFFF0A0013F6AF8200200A0014B2E1
-:100720002415002011E0FECC3C1980003728010080
-:100730009518001094B6000233120FFF16D2FEC6B1
-:10074000000000000A00148290A900013C0B080080
-:100750008D6B0038256DFFFF15600002018D1024A0
-:10076000000010213C080800250800380048C0217E
-:10077000930F000425EE00040A0014C5000E21C0EA
-:1007800000065202241F00FF115FFDEB000731C07D
-:10079000000A20C03C0E080125CE9620008EA8211C
-:1007A000009E602100095C02240D00013C076000EE
-:1007B000A2AD0000AD860000A2AB00018CF21820B3
-:1007C00024030001014310040242B025ACF61820B6
-:1007D00000C038210A0013C8A6A900020A0015AA01
-:1007E000AF8000200A0012FFAF84002C8F85000428
-:1007F0003C1980002408000337380180A308000B4F
-:100800000A00144D3C088000A2F8000B0A00155A9B
-:100810002419BFFF8F9600042412FFFE0A00144B18
-:1008200002D228242416FFFE0A00155800B62824F8
-:100830003C038000346401008C85000030A2003E3F
-:100840001440000800000000AC6000488C870000E5
-:1008500030E607C010C0000500000000AC60004C8E
-:10086000AC60005003E0000824020001AC600054BA
-:10087000AC6000408C880000310438001080FFF923
-:10088000000000002402000103E00008AC60004406
-:100890003C0380008C6201B80440FFFE3467018095
-:1008A000ACE4000024080001ACE00004A4E500086A
-:1008B00024050002A0E8000A34640140A0E5000B12
-:1008C0009483000A14C00008A4E30010ACE00024E4
-:1008D0003C07800034E901803C041000AD20002872
-:1008E00003E00008ACE401B88C8600043C0410006E
-:1008F000ACE600243C07800034E90180AD200028EC
-:1009000003E00008ACE401B83C0680008CC201B8EA
-:100910000440FFFE34C7018024090002ACE400005B
-:10092000ACE40004A4E50008A0E9000A34C50140D5
-:10093000A0E9000B94A8000A3C041000A4E80010F1
-:10094000ACE000248CA30004ACE3002803E0000822
-:10095000ACC401B83C039000346200010082202541
-:100960003C038000AC6400208C65002004A0FFFEE6
-:100970000000000003E00008000000003C028000CE
-:10098000344300010083202503E00008AC4400202C
-:1009900027BDFFE03C098000AFBF0018AFB10014D5
-:1009A000AFB00010352801408D10000091040009FF
-:1009B0009107000891050008308400FF30E600FF31
-:1009C00000061A002C820081008330251040002A86
-:1009D00030A50080000460803C0D080125AD928C9C
-:1009E000018D58218D6A00000140000800000000C0
-:1009F0003C038000346201409445000A14A0001EAC
-:100A00008F91FCBC9227000530E6000414C0001A48
-:100A1000000000000E00164E02002021922A000560
-:100A200002002021354900040E001658A2290005B5
-:100A30009228000531040004148000020000000028
-:100A40000000000D922D0000240B002031AC00FFAF
-:100A5000158B00093C0580008CAE01B805C0FFFE77
-:100A600034B10180AE3000003C0F100024100005AE
-:100A7000A230000BACAF01B80000000D8FBF001812
-:100A80008FB100148FB0001003E0000827BD0020D4
-:100A90000200202100C028218FBF00188FB1001450
-:100AA0008FB00010240600010A00161D27BD00208B
-:100AB0000000000D0200202100C028218FBF001877
-:100AC0008FB100148FB00010000030210A00161DF5
-:100AD00027BD002014A0FFE8000000000200202134
-:100AE0008FBF00188FB100148FB0001000C02821F4
-:100AF0000A00163B27BD00203C0780008CEE01B8A1
-:100B000005C0FFFE34F00180241F0002A21F000B6D
-:100B100034F80140A60600089719000A3C0F10009F
-:100B2000A61900108F110004A6110012ACEF01B835
-:100B30000A0016998FBF001827BDFFE8AFBF00104D
-:100B40000E000FD4000000003C0280008FBF001098
-:100B500000002021AC4001800A00108F27BD001842
-:100B60003084FFFF30A5FFFF108000070000182130
-:100B7000308200011040000200042042006518216C
-:100B80001480FFFB0005284003E0000800601021EE
-:100B900010C00007000000008CA2000024C6FFFF68
-:100BA00024A50004AC82000014C0FFFB24840004D0
-:100BB00003E000080000000010A0000824A3FFFFCD
-:100BC000AC86000000000000000000002402FFFFCF
-:100BD0002463FFFF1462FFFA2484000403E000088A
-:100BE000000000003C03800027BDFFF83462018054
-:100BF000AFA20000308C00FF30AD00FF30CE00FF10
-:100C00003C0B80008D6401B80480FFFE00000000F2
-:100C10008FA900008D6801288FAA00008FA700000F
-:100C20008FA400002405000124020002A085000A10
-:100C30008FA30000359940003C051000A062000B16
-:100C40008FB800008FAC00008FA600008FAF0000AF
-:100C500027BD0008AD280000AD400004AD80002491
-:100C6000ACC00028A4F90008A70D0010A5EE0012E2
-:100C700003E00008AD6501B83C06800827BDFFE829
-:100C800034C50080AFBF001090A7000924020012F5
-:100C900030E300FF1062000B008030218CA8005070
-:100CA00000882023048000088FBF00108CAA003425
-:100CB000240400390000282100CA4823052000052B
-:100CC000240600128FBF00102402000103E0000878
-:100CD00027BD00180E0016F2000000008FBF0010A4
-:100CE0002402000103E0000827BD001827BDFFC84B
-:100CF000AFB20030AFB00028AFBF0034AFB1002CAE
-:100D000000A0802190A5000D30A6001010C000109A
-:100D1000008090213C0280088C4400048E0300086F
-:100D20001064000C30A7000530A6000510C0009329
-:100D3000240400018FBF00348FB200308FB1002C2B
-:100D40008FB000280080102103E0000827BD003884
-:100D500030A7000510E0000F30AB001210C00006F5
-:100D6000240400013C0980088E0800088D25000439
-:100D70005105009C240400388FBF00348FB200302E
-:100D80008FB1002C8FB000280080102103E00008F4
-:100D900027BD0038240A0012156AFFE6240400016A
-:100DA0000200202127A500100E000CB6AFA00010F5
-:100DB0001440007C3C19800837240080909800087B
-:100DC000331100081220000A8FA7001030FF010025
-:100DD00013E000A48FA300148C8600580066102333
-:100DE000044000043C0A8008AC8300588FA7001020
-:100DF0003C0A800835480080910900083124000829
-:100E00001480000224080003000040213C1F8008D9
-:100E100093F1001193F9001237E600808CCC005456
-:100E2000333800FF03087821322D00FF000F708057
-:100E300001AE282100AC582B1160006F00000000AB
-:100E400094CA005C8CC900543144FFFF0125102373
-:100E50000082182B14600068000000008CCB005446
-:100E60000165182330EC00041180006C000830800C
-:100E70008FA8001C0068102B1040006230ED0004A9
-:100E8000006610232C46008010C00002004088211C
-:100E9000241100800E00164E024020213C0D8008D7
-:100EA00035A6008024070001ACC7000C90C80008DC
-:100EB0000011484035A70100310C007FA0CC00088C
-:100EC0008E05000424AB0001ACCB0030A4D1005C43
-:100ED0008CCA003C9602000E01422021ACC40020C6
-:100EE0008CC3003C0069F821ACDF001C8E190004A3
-:100EF000ACF900008E180008ACF800048FB10010A7
-:100F0000322F000855E0004793A60020A0C0004EF5
-:100F100090D8004E2411FFDFA0F8000890CF000801
-:100F200001F17024A0CE00088E0500083C0B80085B
-:100F300035690080AD2500388D6A00148D2200309F
-:100F40002419005001422021AD24003491230000D7
-:100F5000307F00FF13F90036264F01000E001658AF
-:100F60000240202124040038000028210E0016F23F
-:100F70002406000A0A001757240400010E000D2859
-:100F8000000020218FBF00348FB200308FB1002CC1
-:100F90008FB00028004020210080102103E00008CD
-:100FA00027BD00388E0E00083C0F800835F0008009
-:100FB000AE0E005402402021AE0000300E00164E4E
-:100FC00000000000920D00250240202135AC0020D9
-:100FD0000E001658A20C00250E000CAC0240202179
-:100FE000240400382405008D0E0016F22406001299
-:100FF0000A0017572404000194C5005C0A001792E8
-:1010000030A3FFFF2407021811A0FF9E00E6102363
-:101010008FAE001C0A00179A01C610230A0017970A
-:101020002C620218A0E600080A0017C48E0500080A
-:101030002406FF8001E6C0243C118000AE38002861
-:101040008E0D000831E7007F3C0E800C00EE602121
-:10105000AD8D00E08E080008AF8C00380A0017D074
-:10106000AD8800E4AC800058908500082403FFF7A9
-:1010700000A33824A08700080A0017758FA7001066
-:101080003C05080024A560A83C04080024846FF4F3
-:101090003C020800244260B0240300063C01080121
-:1010A000AC2596A03C010801AC2496A43C010801A3
-:1010B000AC2296A83C010801A02396AC03E00008EE
-:1010C0000000000003E00008240200013C02800050
-:1010D000308800FF344701803C0680008CC301B893
-:1010E0000460FFFE000000008CC501282418FF806A
-:1010F0003C0D800A24AF010001F8702431EC007F20
-:10110000ACCE0024018D2021ACE50000948B00EAD8
-:101110003509600024080002316AFFFFACEA0004D0
-:1011200024020001A4E90008A0E8000BACE00024C0
-:101130003C071000ACC701B8AF84003803E00008DA
-:10114000AF85006C938800488F8900608F820038DB
-:1011500030C600FF0109382330E900FF01221821C1
-:1011600030A500FF2468008810C000020124382147
-:101170000080382130E400031480000330AA00030B
-:101180001140000D312B000310A0000900001021B8
-:1011900090ED0000244E000131C200FF0045602B9D
-:1011A000A10D000024E700011580FFF925080001CA
-:1011B00003E00008000000001560FFF300000000DD
-:1011C00010A0FFFB000010218CF80000245900043F
-:1011D000332200FF0045782BAD18000024E70004FF
-:1011E00015E0FFF92508000403E0000800000000F6
-:1011F00093850048938800588F8700600004320070
-:101200003103007F00E5102B30C47F001040000F39
-:10121000006428258F8400383C0980008C8A00EC0B
-:10122000AD2A00A43C03800000A35825AC6B00A0AD
-:101230008C6C00A00580FFFE000000008C6D00ACEF
-:10124000AC8D00EC03E000088C6200A80A00188254
-:101250008F840038938800593C0280000080502120
-:10126000310300FEA383005930ABFFFF30CC00FFF9
-:1012700030E7FFFF344801803C0980008D2401B82D
-:101280000480FFFE8F8D006C24180016AD0D000049
-:101290008D2201248F8D0038AD0200048D5900206D
-:1012A000A5070008240201C4A119000AA118000B17
-:1012B000952F01208D4E00088D4700049783005C18
-:1012C0008D59002401CF302100C7282100A32023FD
-:1012D0002418FFFFA504000CA50B000EA5020010AA
-:1012E000A50C0012AD190018AD18002495AF00E848
-:1012F0003C0B10002407FFF731EEFFFFAD0E002876
-:101300008DAC0084AD0C002CAD2B01B88D460020B7
-:1013100000C7282403E00008AD4500208F8800386E
-:101320000080582130E7FFFF910900D63C02800081
-:1013300030A5FFFF312400FF00041A00006750258C
-:1013400030C600FF344701803C0980008D2C01B875
-:101350000580FFFE8F82006C240F0017ACE20000B6
-:101360008D390124ACF900048D780020A4EA00082E
-:10137000241901C4A0F8000AA0EF000B9523012056
-:101380008D6E00088D6D00049784005C01C35021B0
-:10139000014D602101841023A4E2000CA4E5000E9D
-:1013A000A4F90010A4E60012ACE000148D7800242B
-:1013B000240DFFFFACF800188D0F007CACEF001C73
-:1013C0008D0E00783C0F1000ACEE0020ACED002438
-:1013D000950A00BE240DFFF73146FFFFACE600285A
-:1013E000950C00809504008231837FFF0003CA00C2
-:1013F0003082FFFF0322C021ACF8002CAD2F01B8D2
-:10140000950E00828D6A002000AE3021014D282407
-:10141000A506008203E00008AD6500203C028000C4
-:10142000344501803C0480008C8301B80460FFFED9
-:101430008F8A0044240600199549001C3128FFFFBB
-:10144000000839C0ACA70000A0A6000B3C051000A6
-:1014500003E00008AC8501B88F87004C0080402174
-:1014600030C400FF3C0680008CC201B80440FFFE7F
-:101470008F89006C9383006834996000ACA90000E8
-:10148000A0A300058CE20010240F00022403FFF744
-:10149000A4A20006A4B900088D180020A0B8000A74
-:1014A000A0AF000B8CEE0000ACAE00108CED000481
-:1014B000ACAD00148CEC001CACAC00248CEB002018
-:1014C000ACAB00288CEA002C3C071000ACAA002C26
-:1014D0008D090024ACA90018ACC701B88D05002007
-:1014E00000A3202403E00008AD0400208F8600380C
-:1014F00027BDFFE0AFB10014AFBF0018AFB00010C0
-:1015000090C300D430A500FF3062002010400008D6
-:10151000008088218CCB00D02409FFDF256A0001E0
-:10152000ACCA00D090C800D401093824A0C700D4A8
-:1015300014A000403C0C80008F840038908700D4B9
-:101540002418FFBF2406FFEF30E3007FA08300D400
-:10155000979F005C8F8200608F8D003803E2C82364
-:10156000A799005CA5A000BC91AF00D401F870243D
-:10157000A1AE00D48F8C0038A18000D78F8A0038AC
-:10158000A5400082AD4000EC914500D400A658244F
-:10159000A14B00D48F9000348F8400609786005C4C
-:1015A0000204282110C0000FAF850034A38000582A
-:1015B0003C0780008E2C000894ED01208E2B000447
-:1015C000018D5021014B8021020620233086FFFF30
-:1015D00030C8000F3909000131310001162000091F
-:1015E000A3880058938600488FBF00188FB100145D
-:1015F0008FB0001027BD0020AF85006403E0000815
-:10160000AF86006000C870238FBF00189386004823
-:101610008FB100148FB0001034EF0C00010F28219F
-:1016200027BD0020ACEE0084AF85006403E0000815
-:10163000AF86006035900180020028210E00190F4E
-:10164000240600828F840038908600D430C5004084
-:1016500050A0FFBAA38000688F85004C3C06800034
-:101660008CCD01B805A0FFFE8F89006C2408608234
-:1016700024070002AE090000A6080008A207000B1C
-:101680008CA300083C0E1000AE0300108CA2000CCE
-:10169000AE0200148CBF0014AE1F00188CB90018E5
-:1016A000AE1900248CB80024AE1800288CAF002896
-:1016B000AE0F002CACCE01B80A001948A380006818
-:1016C0008F8A003827BDFFE0AFB10014AFB0001023
-:1016D0008F880060AFBF00189389003C954200BC22
-:1016E00030D100FF0109182B0080802130AC00FFB1
-:1016F0003047FFFF0000582114600003310600FF4F
-:1017000001203021010958239783005C0068202BB9
-:101710001480002700000000106800562419000102
-:101720001199006334E708803165FFFF0E0018C08F
-:10173000020020218F83006C3C07800034E601808A
-:101740003C0580008CAB01B80560FFFE240A001840
-:101750008F840038ACC30000A0CA000B948900BE7F
-:101760003C081000A4C90010ACC00030ACA801B8FF
-:101770009482008024430001A4830080949F008011
-:101780003C0608008CC6318833EC7FFF1186005E72
-:101790000000000002002021022028218FBF001835
-:1017A0008FB100148FB000100A00193427BD00203B
-:1017B000914400D42403FF8000838825A15100D4E4
-:1017C0009784005C3088FFFF51000023938C003C1D
-:1017D0008F8500382402EFFF008B782394AE00BC85
-:1017E0000168502B31E900FF01C26824A4AD00BCA0
-:1017F00051400039010058213C1F800037E60100AC
-:101800008CD800043C190001031940245500000144
-:1018100034E740008E0A00202403FFFB241100015E
-:1018200001432024AE0400201191002D34E78000F4
-:1018300002002021012030210E0018C03165FFFF79
-:101840009787005C8F890060A780005C0127802358
-:10185000AF900060938C003C8F8B00388FBF0018D6
-:101860008FB100148FB0001027BD002003E00008E6
-:10187000A16C00D73C0D800035AA01008D48000402
-:101880003C0900010109282454A0000134E740006C
-:101890008E0F00202418FFFB34E7800001F870242D
-:1018A00024190001AE0E00201599FF9F34E708802F
-:1018B000020020210E00188E3165FFFF020020215A
-:1018C000022028218FBF00188FB100148FB00010A4
-:1018D0000A00193427BD00200A0019F7000048212A
-:1018E00002002021012030210E00188E3165FFFFFB
-:1018F0009787005C8F890060A780005C01278023A8
-:101900000A001A0EAF900060948C0080241F8000A3
-:10191000019F3024A4860080908B0080908F0080EF
-:10192000316700FF0007C9C20019C027001871C045
-:1019300031ED007F01AE2825A08500800A0019DF67
-:1019400002002021938500682403000127BDFFE8E1
-:1019500000A330042CA20020AFB00010AFBF0014D1
-:1019600000C01821104000132410FFFE3C0708009F
-:101970008CE7319000E610243C088000350501809A
-:1019800014400005240600848F890038240A0004CE
-:101990002410FFFFA12A00FC0E00190F0000000018
-:1019A000020010218FBF00148FB0001003E0000868
-:1019B00027BD00183C0608008CC631940A001A574F
-:1019C00000C310248F87004427BDFFE0AFB200188A
-:1019D000AFB10014AFB00010AFBF001C30D000FF9B
-:1019E00090E6000D00A088210080902130C5007F86
-:1019F000A0E5000D8F8500388E2300188CA200D042
-:101A00001062002E240A000E0E001A4AA38A0068F3
-:101A10002409FFFF104900222404FFFF5200002088
-:101A2000000020218E2600003C0C001000CC582421
-:101A3000156000393C0E000800CE682455A0003F18
-:101A4000024020213C18000200D880241200001F10
-:101A50003C0A00048F8700448CE200148CE30010E1
-:101A60008CE500140043F82303E5C82B1320000580
-:101A7000024020218E24002C8CF1001010910031A6
-:101A80000240202124020012A38200680E001A4A9C
-:101A90002412FFFF105200022404FFFF0000202147
-:101AA0008FBF001C8FB200188FB100148FB00010D0
-:101AB0000080102103E0000827BD002090A800D47A
-:101AC000350400200A001A80A0A400D400CA4824CB
-:101AD0001520000B8F8B00448F8D00448DAC0010BF
-:101AE0001580000B024020218E2E002C51C0FFECEF
-:101AF00000002021024020210A001A9B2402001726
-:101B00008D66001050C0FFE6000020210240202119
-:101B10000A001A9B24020011024020212402001511
-:101B20000E001A4AA3820068240FFFFF104FFFDC4B
-:101B30002404FFFF0A001A8A8E2600000A001AC138
-:101B4000240200143C08000400C8382450E0FFD4EC
-:101B500000002021024020210A001A9B24020013C9
-:101B60008F85003827BDFFD8AFB3001CAFB2001877
-:101B7000AFB10014AFB00010AFBF002090A700D4E9
-:101B80008F90004C2412FFFF34E2004092060000C8
-:101B9000A0A200D48E0300100080982110720006CD
-:101BA00030D1003F2408000D0E001A4AA3880068B7
-:101BB000105200252404FFFF8F8A00388E09001878
-:101BC0008D4400D01124000702602021240C000E57
-:101BD0000E001A4AA38C0068240BFFFF104B001A5A
-:101BE0002404FFFF24040020122400048F8D0038F9
-:101BF00091AF00D435EE0020A1AE00D48F85005403
-:101C000010A00019000000001224004A8F9800382C
-:101C10008F92FCBC971000809651000A5230004809
-:101C20008F9300403C1F08008FFF318C03E5C82BC9
-:101C30001720001E02602021000028210E0019A993
-:101C400024060001000020218FBF00208FB3001C5C
-:101C50008FB200188FB100148FB0001000801021D7
-:101C600003E0000827BD00285224002A8E05001436
-:101C70008F840038948A008025490001A48900805F
-:101C8000948800803C0208008C42318831077FFF35
-:101C900010E2000E00000000026020210E00193446
-:101CA000240500010A001B0B000020212402002D46
-:101CB0000E001A4AA38200682403FFFF1443FFE1C9
-:101CC0002404FFFF0A001B0C8FBF002094990080A2
-:101CD000241F800024050001033FC024A498008035
-:101CE00090920080908E0080325100FF001181C2DE
-:101CF00000107827000F69C031CC007F018D582576
-:101D0000A08B00800E001934026020210A001B0BFA
-:101D1000000020212406FFFF54A6FFD68F84003840
-:101D2000026020210E001934240500010A001B0B5B
-:101D300000002021026020210A001B252402000A45
-:101D40002404FFFD0A001B0BAF9300608F8800384E
-:101D500027BDFFE8AFB00010AFBF0014910A00D458
-:101D60008F87004C00808021354900408CE60010B0
-:101D7000A10900D43C0208008C4231B030C53FFFBD
-:101D800000A2182B106000078F850050240DFF80E3
-:101D900090AE000D01AE6024318B00FF156000088D
-:101DA0000006C382020020212403000D8FBF00140F
-:101DB0008FB0001027BD00180A001A4AA3830068DC
-:101DC00033060003240F000254CFFFF70200202146
-:101DD00094A2001C8F85003824190023A4A200E8D7
-:101DE0008CE8000000081E02307F003F13F9003528
-:101DF0003C0A00838CE800188CA600D0110600086D
-:101E0000000000002405000E0E001A4AA385006899
-:101E10002407FFFF104700182404FFFF8F850038B8
-:101E200090A900D435240020A0A400D48F8C0044B5
-:101E3000918E000D31CD007FA18D000D8F83005458
-:101E40001060001C020020218F8400508C9800102C
-:101E50000303782B11E0000D241900180200202143
-:101E6000A39900680E001A4A2410FFFF10500002C8
-:101E70002404FFFF000020218FBF00148FB000104A
-:101E80000080102103E0000827BD00188C86001098
-:101E90008F9F00440200202100C31023AFE20010F6
-:101EA000240500010E0019A9240600010A001B9751
-:101EB000000020210E001934240500010A001B97A0
-:101EC00000002021010A5824156AFFD98F8C004494
-:101ED000A0A600FC0A001B84A386005A30A500FFC0
-:101EE0002406000124A9000100C9102B1040000C99
-:101EF00000004021240A000100A61823308B0001B5
-:101F000024C60001006A3804000420421160000267
-:101F100000C9182B010740251460FFF800A61823FC
-:101F200003E000080100102127BDFFD8AFB0001862
-:101F30008F90004CAFB1001CAFBF00202403FFFF07
-:101F40002411002FAFA30010920600002405000802
-:101F500026100001006620260E001BB0308400FF12
-:101F600000021E003C021EDC34466F410A001BD8F2
-:101F70000000102110A00009008018212445000154
-:101F800030A2FFFF2C4500080461FFFA0003204047
-:101F90000086202614A0FFF9008018210E001BB037
-:101FA000240500208FA300102629FFFF313100FFF8
-:101FB00000034202240700FF1627FFE20102182651
-:101FC00000035027AFAA0014AFAA00100000302170
-:101FD00027A8001027A7001400E6782391ED00033E
-:101FE00024CE000100C8602131C600FF2CCB0004C4
-:101FF0001560FFF9A18D00008FA200108FBF002097
-:102000008FB1001C8FB0001803E0000827BD002826
-:1020100027BDFFD0AFB3001CAFB00010AFBF00288A
-:10202000AFB50024AFB40020AFB20018AFB10014B8
-:102030003C0C80008D880128240FFF803C06800A1C
-:1020400025100100250B0080020F68243205007F57
-:10205000016F7024AD8E009000A62821AD8D002464
-:1020600090A600FC3169007F3C0A8004012A1821F7
-:10207000A386005A9067007C00809821AF830030CF
-:1020800030E20002AF88006CAF85003800A0182154
-:10209000144000022404003424040030A3840048C7
-:1020A0008C7200DC30D100FF24040004AF92006089
-:1020B00012240004A38000688E7400041680001EA1
-:1020C0003C0880009386005930C7000150E0000FA3
-:1020D0008F8600608CA400848CA800842413FF8069
-:1020E00000936024000C49403110007F01307825B6
-:1020F0003C19200001F9682530DF00FE3C03800018
-:10210000AC6D0830A39F00598F8600608FBF0028F8
-:102110008FB500248FB400208FB3001C8FB200183D
-:102120008FB100148FB000102402000127BD0030D1
-:1021300003E00008ACA600DC8E7F000895020120B9
-:102140008E67001003E2C8213326FFFF30D8000F4E
-:1021500033150001AF87003416A00058A39800582B
-:1021600035090C000309382100D81823AD03008479
-:10217000AF8700648E6A00043148FFFF1100007EC3
-:10218000A78A005C90AC00D42407FF8000EC3024C8
-:1021900030CB00FF1560004B9786005C938E005A91
-:1021A000240D000230D5FFFF11CD02A20000A021B6
-:1021B0008F85006002A5802B160000BC9388004824
-:1021C0003C11800096240120310400FF1485008812
-:1021D0008F8400648F9800343312000356400085CA
-:1021E00030A500FF8F900064310C00FF24060034FE
-:1021F00011860095AF90004C9204000414800119E0
-:102200008F8E0038A380003C8E0D00048DC800D84E
-:102210003C0600FF34CCFFFF01AC30240106182B34
-:1022200014600121AF8600548F8700609798005C8E
-:10223000AF8700400307402310C000C7A788005C99
-:102240008F91003030C3000300035823922A007C92
-:102250003171000302261021000A20823092000111
-:102260000012488000492821311FFFFF03E5C82BD9
-:10227000132001208F8800388F8500348F880064F8
-:102280001105025A3C0E3F018E0600003C0C250051
-:1022900000CE682411AC01638F84004C30E500FF50
-:1022A0000E00184A000030218F8800388F870060A8
-:1022B0008F8500340A001DB78F8600540A001C5613
-:1022C000AF87006490AC00D400EC2024309000FF75
-:1022D000120000169386005990B5008890B400D77C
-:1022E00024A8008832A2003F2446FFE02CD1002021
-:1022F000A394003C1220000CAF88004C240E000177
-:1023000000CE2004308A00191540012B3C068000C5
-:1023100034D80002009858241560022E3092002014
-:1023200016400234000000009386005930CE0001B0
-:1023300011C0000F9788005C8CA900848CAF0084CA
-:102340002410FF800130C8240019194031ED007FAE
-:10235000006D38253C1F200000FF902530CB00FE8B
-:102360003C188000AF120830A38B00599788005C9E
-:102370001500FF84000000008E630020306C000414
-:102380001180FF51938600592404FFFB0064302420
-:102390003C038000AE660020346601808C7301B877
-:1023A0000660FFFE8F8E006C346A01003C15000150
-:1023B000ACCE00008C62012424076085ACC200040E
-:1023C0008D54000402958824522000012407608364
-:1023D000241200023C1810003C0B8000A4C7000827
-:1023E000A0D2000BAD7801B80A001C2B93860059CF
-:1023F00030A500FF0E00184A240600018F88006CEB
-:102400003C05800034A90900250201889388004812
-:10241000304A0007304B00783C0340802407FF809F
-:102420000163C825014980210047F824310C00FFD1
-:1024300024060034ACBF0800AF90004CACB90810C3
-:102440005586FF6E920400048F8400388E11003090
-:10245000908E00D431CD001015A000108F83006045
-:102460002C6F000515E000E400000000909800D4F7
-:102470002465FFFC331200101640000830A400FF52
-:102480008F9F00648F99003413F90004388700018E
-:1024900030E20001144001C8000000000E001BC320
-:1024A000000000000A001DF8000000008F84006496
-:1024B00030C500FF0E00184A24060001938E004824
-:1024C000240A003411CA00A08F8500388F8600606E
-:1024D0009783005C3062FFFF00C28823AF910060E9
-:1024E000A780005C1280FF90028018212414FFFD59
-:1024F0005474FFA28E6300208E6900042403FFBF82
-:10250000240BFFEF0135C823AE79000490AF00D44F
-:1025100031ED007FA0AD00D48E6600208F9800388A
-:10252000A780005C34DF0002AE7F0020A70000BC63
-:10253000931200D402434024A30800D48F9500389E
-:10254000AEA000EC92AE00D401CB5024A2AA00D4DD
-:102550000A001CD78F8500388F910034AF8000604F
-:1025600002275821AF8B0034000020212403FFFFF5
-:10257000108301B48F8500388E0C00103C0D0800CC
-:102580008DAD31B09208000031843FFF008D802B6B
-:1025900012000023310D003F3C1908008F3931A88B
-:1025A0008F9F006C000479802408FF80033F202166
-:1025B000008FC821938500590328F8243C06008029
-:1025C0003C0F800034D80001001F91403331007F60
-:1025D0008F8600380251502535EE0940332B0078A4
-:1025E000333000073C0310003C02800C017890253A
-:1025F000020E48210143C0250222382134AE0001D9
-:10260000ADFF0804AF890050ADF20814AF87004455
-:10261000ADFF0028ACD90084ADF80830A38E005976
-:102620009383005A240700035067002825A3FFE086
-:10263000240C0001146CFFAB8F850038241100239B
-:1026400011B10084000000002402000B0260202170
-:102650000E001A4AA38200680040A0210A001D3221
-:102660008F85003802602021240B000C0E001A4ACE
-:10267000A38B0068240AFFFF104AFFBC2404FFFF5D
-:102680008F8E0038A380003C8E0D00048DC800D8CA
-:102690003C0600FF34CCFFFF01AC30240106182BB0
-:1026A0001060FEE1AF860054026020212412001960
-:1026B0000E001A4AA3920068240FFFFF104FFFABD1
-:1026C0002404FFFF0A001C838F8600542C74002012
-:1026D0001280FFDE2402000B000328803C11080159
-:1026E0002631949000B148218D2D000001A00008F2
-:1026F000000000008F85003400A710219385003C66
-:10270000AF82003402251821A383003C951F00BC32
-:102710000226282137F91000A51900BC5240FF926B
-:10272000AF850060246A0004A38A003C950900BCC0
-:1027300024A40004AF84006035322000A51200BC40
-:102740000A001D54000020218F8600602CCB00055C
-:102750001560FF609783005C3072FFFF00D240235A
-:102760002D18000513000003306400FF24DFFFFC78
-:1027700033E400FF8F8500648F86003410A60004C8
-:10278000388F000131ED000115A001380000000074
-:102790008F840038908C00D435870010A08700D437
-:1027A0008F8500388F8600609783005CACA000ECBA
-:1027B0000A001D2F3062FFFF8CAA00848CB50084B4
-:1027C0003C041000014710240002894032B4007F0D
-:1027D0000234302500C460253C0880002405000137
-:1027E00002602021240600010E0019A9AD0C08305A
-:1027F0000A001CC38F8500388C8200EC1222FE7EFA
-:102800000260202124090005A38900680E001A4AED
-:102810002411FFFF1451FE782404FFFF0A001D5508
-:102820002403FFFF8F8F004C8F8800388DF8000045
-:10283000AD1800888DE70010AD0700988F87006005
-:102840000A001DB78F8600542407FFFF118700057B
-:10285000000000000E001B4C026020210A001D90A9
-:102860000040A0210E001AD1026020210A001D9014
-:102870000040A0218F90004C3C0908008D2931B008
-:102880008E11001032323FFF0249682B11A0000C5C
-:10289000240AFF808F85005090AE000D014E102459
-:1028A000304C00FF11800007026020210011C3821C
-:1028B00033030003240B0001106B0105000000002E
-:1028C000026020212418000D0E001A4AA398006807
-:1028D000004020218F8500380A001D320080A02191
-:1028E0008F90004C3C0A08008D4A31B08F85005013
-:1028F0008E0400100000A0218CB1001430823FFF34
-:10290000004A602B8CB200205180FFEE0260202133
-:1029100090B8000D240BFF800178702431C300FFB4
-:102920005060FFE80260202100044382310600036A
-:1029300014C0FFE40260202194BF001C8F9900386E
-:102940008E060028A73F00E88CAF0010022F20233E
-:1029500014C40139026020218F83005400C3682110
-:10296000022D382B14E00135240200188F8A004410
-:102970008F820030024390218D4B00100163702341
-:10298000AD4E0010AD5200208C4C00740192282BEB
-:1029900014A00156026020218F8400508E0800246C
-:1029A0008C86002411060007026020212419001CD7
-:1029B0000E001A4AA3990068240FFFFF104FFFC5AD
-:1029C0002404FFFF8F8400448C87002424FF00012F
-:1029D000AC9F0024125101338F8D00308DB10074F3
-:1029E000123201303C0B00808E0E000001CB5024CF
-:1029F00015400075000000008E0300142411FFFF35
-:102A000010710006026020212418001B0E001A4AD3
-:102A1000A39800681051FFAF2404FFFF8E0300004D
-:102A20003C0800010068302410C000133C04008002
-:102A30000064A024168000090200282102602021E1
-:102A40002419001A0E001A4AA3990068240FFFFFE8
-:102A5000104FFFA02404FFFF020028210260202164
-:102A60000E001A6A240600012410FFFF1050FF997F
-:102A70002404FFFF241400018F9F004402602021E2
-:102A80000280302197F1003424050001262700013F
-:102A9000A7E700340E0019A9000000000000202163
-:102AA0008F8500380A001D320080A0218F90004CD5
-:102AB0003C1408008E9431B08E07001030E83FFFC0
-:102AC0000114302B10C000618F860050241FFF803E
-:102AD00090C5000D03E52024309200FF5240005CB9
-:102AE000026020218F8D005411A0000700078B8207
-:102AF0008F8500388F89FCBC94AF00809539000A1F
-:102B0000132F00F68F870040322C000315800063DE
-:102B10000000000092020002104000D700000000F8
-:102B20008E0A0024154000D8026020219204000380
-:102B300024060002308800FF15060005308500FFDE
-:102B40008F940054528000F202602021308500FFF3
-:102B500038AD00102DA400012CBF000103E4302586
-:102B6000020028210E001A6A026020212410FFFFB3
-:102B7000105000BE8F8500388F830054106000C451
-:102B8000240500013C1908008F39318C0323782B70
-:102B900015E000B12409002D026020210000282149
-:102BA0000E0019A9240600018F85003800001821A5
-:102BB0000A001D320060A0210E0018750000000000
-:102BC0000A001DF800000000AC8000200A001E78FA
-:102BD0008E03001400002821026020210E0019A994
-:102BE000240600010A001CC38F8500380A001DB7A7
-:102BF0008F8800388CB000848CB900843C031000AE
-:102C00000207482400096940332F007F01AFF825EF
-:102C100003E32825ACC50830910700012405000115
-:102C2000026020210E0019A930E600010A001CC331
-:102C30008F850038938F00482403FFFD0A001D3460
-:102C4000AF8F00600A001D342403FFFF02602021C3
-:102C50002410000D0E001A4AA390006800401821AD
-:102C60008F8500380A001D320060A0210E00187503
-:102C7000000000009783005C8F8600603070FFFFCB
-:102C800000D048232D3900051320FE128F8500380F
-:102C9000ACA200EC0A001D2F3062FFFF90C3000DB4
-:102CA000307800085700FFA2920400030260202140
-:102CB000240200100E001A4AA38200682403FFFFBA
-:102CC0005443FF9B920400030A001F128F850038B3
-:102CD00090A8000D3106000810C000958F94005494
-:102CE0001680009E026020218E0F000C8CA4002014
-:102CF00055E40005026020218E1F00088CB90024D5
-:102D000013F9003A02602021240200200E001A4A22
-:102D1000A38200682405FFFF1045FEEE2404FFFF98
-:102D20008F8F0044240CFFF72403FF8091E9000DEE
-:102D30003C14800E3C0B8000012CC824A1F9000D2E
-:102D40008F8F00303C0708008CE731AC8F8D006C12
-:102D500095E500788F99004400ED902130BF7FFF0A
-:102D6000001F20400244302130C8007F00C3C0242F
-:102D700001147021AD78002CA5D100008F2A002805
-:102D800025420001AF2200288F29002C8E0C002C38
-:102D9000012C6821AF2D002C8E07002CAF270030AE
-:102DA0008E050014AF250034973F003A27E4000158
-:102DB000A724003A95F200783C1008008E1031B03C
-:102DC0002643000130717FFF1230005C006030212B
-:102DD0008F83003002602021240500010E00193489
-:102DE000A46600780A001EA1000020218E070014AE
-:102DF0002412FFFF10F200638F8C00388E09001838
-:102E00008D8D00D0152D005D026020218E0A0024DA
-:102E10008CA2002811420053240200210E001A4AFD
-:102E2000A38200681452FFBE2404FFFF8F85003880
-:102E30000A001D320080A0212402001F0E001A4A41
-:102E4000A38200682409FFFF1049FEA22404FFFFAB
-:102E50000A001E548F830054026020210E001A4A7B
-:102E6000A38900681450FF518F8500382403FFFFA9
-:102E70000A001D320060A0218CCE00248E0B00249D
-:102E8000116EFF2A026020210A001F262402000F73
-:102E90000E001934026020218F8500380A001EE5DB
-:102EA000000018218E0900003C05008001259024B7
-:102EB0001640FF452402001A026020210E001A4A23
-:102EC000A3820068240CFFFF144CFECB2404FFFFF8
-:102ED0008F8500380A001D320080A0212403FFFDE9
-:102EE0000060A0210A001D32AF8700602418001D79
-:102EF0000E001A4AA39800682403FFFF1443FEA69D
-:102F00002404FFFF8F8500380A001D320080A021B5
-:102F10002412002C0E001A4AA39200682403FFFF1B
-:102F20001043FF508F8500380A001ECC9204000326
-:102F3000026020210A001F3C24020024240B800090
-:102F4000006B702431CAFFFF000A13C2305100FF2A
-:102F5000001180270A001F6D001033C00A001F3CBB
-:102F6000240200278E0600288CAE002C10CE00080C
-:102F7000026020210A001F802402001F0A001F8017
-:102F80002402000E026020210A001F802402002576
-:102F90008E04002C1080000D8F8300308C7800741C
-:102FA0000304582B5560000C026020218CA80014EB
-:102FB0000086A0210114302B10C0FF5A8F8F0044CF
-:102FC000026020210A001F802402002202602021CA
-:102FD0000A001F80240200230A001F80240200260A
-:102FE00027BDFFD8AFB3001CAFB10014AFBF0020A6
-:102FF000AFB20018AFB000103C0280008C5201400C
-:103000008C4B01483C048000000B8C02322300FFF3
-:10301000317300FF8C8501B804A0FFFE349001805D
-:10302000AE1200008C8701442464FFF024060002E5
-:103030002C830013AE070004A6110008A206000BA3
-:10304000AE1300241060004F8FBF002000044880A2
-:103050003C0A0801254A9510012A40218D040000F0
-:1030600000800008000000003C0308008C6331A8C9
-:1030700031693FFF0009998000728021021370219D
-:103080002405FF80264D0100264C00803C02800074
-:1030900031B1007F3198007F31CA007F3C1F800A28
-:1030A0003C1980043C0F800C01C5202401A530246C
-:1030B00001853824014F1821AC460024023F4021ED
-:1030C00003194821AC470090AC440028AF8300446A
-:1030D000AF880038AF8900300E00190001608021F0
-:1030E0003C0380008C6B01B80560FFFE8F870044B5
-:1030F0008F8600383465018090E8000DACB2000086
-:10310000A4B0000600082600000416030002902761
-:10311000001227C21080008124C20088241F608210
-:10312000A4BF0008A0A0000524020002A0A2000B7A
-:103130008F8B0030000424003C0827000088902575
-:10314000ACB20010ACA00014ACA00024ACA00028CD
-:10315000ACA0002C8D6900382413FF80ACA90018A6
-:1031600090E3000D02638024320500FF10A00005EB
-:103170008FBF002090ED000D31AC007FA0EC000D62
-:103180008FBF00208FB3001C8FB200188FB10014C6
-:103190008FB000103C0A10003C0E800027BD0028B4
-:1031A00003E00008ADCA01B8265F01002405FF80D6
-:1031B00033F8007F3C06800003E578243C19800A40
-:1031C00003192021ACCF0024908E00D400AE6824D7
-:1031D00031AC00FF11800024AF840038248E0088B9
-:1031E00095CD00123C0C08008D8C31A831AB3FFF0F
-:1031F00001924821000B5180012A40210105202421
-:10320000ACC400283107007F3C06800C00E620217A
-:103210009083000D00A31024304500FF10A0FFD8BC
-:10322000AF8400449098000D330F001015E0FFD5D7
-:103230008FBF00200E001900000000003C0380003A
-:103240008C7901B80720FFFE00000000AE120000DC
-:103250008C7F0144AE1F0004A61100082411000257
-:10326000A211000BAE1300243C130801927396D0F8
-:10327000327000015200FFC38FBF00200E00213DBD
-:10328000024020210A00205A8FBF00203C1260001B
-:103290008E452C083C03F0033462FFFF00A2F824A3
-:1032A000AE5F2C088E582C083C1901C003199825D4
-:1032B000AE532C080A00205A8FBF0020264D010073
-:1032C00031AF007F3C10800A240EFF8001F02821DE
-:1032D00001AE60243C0B8000AD6C00241660FFA89A
-:1032E000AF85003824110003A0B100FC0A00205A69
-:1032F0008FBF002026480100310A007F3C0B800A66
-:103300002409FF80014B3021010920243C07800063
-:10331000ACE400240A002059AF860038944E001215
-:10332000320C3FFF31CD3FFF15ACFF7D241F608283
-:1033300090D900D42418FF800319782431EA00FFC3
-:103340001140FF770000000024070004A0C700FC24
-:103350008F870044241160842406000DA4B1000866
-:10336000A0A600050A002044240200023C0400013B
-:10337000248496BC24030014240200FE3C010800AF
-:10338000AC2431EC3C010800AC2331E83C010801DD
-:10339000A42296D83C040801248496D80000182161
-:1033A00000643021A0C30004246300012C6500FFE9
-:1033B00054A0FFFC006430213C07080024E7010012
-:1033C00003E00008AF87007800A058210080482162
-:1033D0000000102114A00012000050210A00213921
-:1033E000000000003C010801A42096D83C0508011B
-:1033F00094A596D88F8200783C0C0801258C96D82D
-:1034000000E2182100AC2021014B302BA0890004E0
-:1034100000001021A460000810C0003901004821FC
-:103420008F8600780009384000E940210008388084
-:1034300000E6282190A8000B90B9000A000820405F
-:1034400000881021000218800066C021A319000A1C
-:103450008F85007800E5782191EE000A91E6000B57
-:10346000000E684001AE6021000C20800085102114
-:10347000A046000B3C030801906396D21060002226
-:103480002462FFFF8F8300383C010801A02296D2FE
-:10349000906C00FF1180000400000000906E00FF9F
-:1034A00025CDFFFFA06D00FF3C190801973996D884
-:1034B000272300013078FFFF2F0F00FF11E0FFC925
-:1034C000254A00013C010801A42396D83C050801C7
-:1034D00094A596D88F8200783C0C0801258C96D84C
-:1034E00000E2182100AC2021014B302BA089000400
-:1034F00000001021A460000814C0FFC90100482189
-:1035000003E000080000000003E0000824020002BD
-:1035100027BDFFE0248501002407FF80AFB0001025
-:10352000AFBF0018AFB1001400A718243C108000F2
-:1035300030A4007F3C06800A008628218E110024DA
-:10354000AE03002490A200FF14400008AF850038AD
-:10355000A0A000098FBF0018AE1100248FB1001485
-:103560008FB0001003E0000827BD002090A900FDE7
-:1035700090A800FF312400FF0E0020EB310500FF72
-:103580008F8500388FBF0018A0A00009AE1100245D
-:103590008FB100148FB0001003E0000827BD002099
-:1035A00027BDFFD0AFB20020AFB1001CAFB00018F4
-:1035B000AFBF002CAFB40028AFB300243C0980009B
-:1035C0009533011635320C00952F011A3271FFFF29
-:1035D000023280218E08000431EEFFFF248B0100AF
-:1035E000010E6821240CFF8025A5FFFF016C5024EB
-:1035F0003166007F3C07800AAD2A002400C73021D5
-:10360000AF850074AF8800703C010801A02096D1FE
-:1036100090C300090200D02100809821306300FF90
-:103620002862000510400048AF8600382864000278
-:103630001480008E24140001240D00053C010801B3
-:10364000A02D96B590CC00FD3C010801A02096B6B7
-:103650003C010801A02096B790CB000A240AFF8005
-:10366000318500FF014B4824312700FF10E0000C9A
-:10367000000058213C128008365100808E2F003007
-:103680008CD0005C01F0702305C0018E8F87007024
-:1036900090D4000A3284007FA0C4000A8F860038CC
-:1036A0003C118008363000808E0F00308F8700700C
-:1036B00000EF702319C000EE0000000090D4000954
-:1036C00024120002328400FF109202470000000022
-:1036D0008CC2005800E2F82327F9FFFF1B200130BD
-:1036E0000000000090C500092408000430A300FF7A
-:1036F00010680057240A00013C010801A02A96B571
-:1037000090C900FF252700013C010801A02796B4BD
-:103710003C030801906396B5240600051066006A14
-:103720002C780005130000C4000090210003F880ED
-:103730003C0408012484955C03E4C8218F25000023
-:1037400000A0000800000000241800FF1078005CB2
-:103750000000000090CC000A90CA00093C08080153
-:10376000910896D13187008000EA48253C01080184
-:10377000A02996BC90C500FD3C140801929496D2F5
-:10378000311100013C010801A02596BD90DF00FE2B
-:103790003C010801A03F96BE90D200FF3C01080109
-:1037A000A03296BF8CD900543C010801AC3996C0B8
-:1037B0008CD000583C010801AC3096C48CC3005C2E
-:1037C0003C010801AC3496CC3C010801AC2396C8FE
-:1037D000162000088FBF002C8FB400288FB3002460
-:1037E0008FB200208FB1001C8FB0001803E00008DA
-:1037F00027BD00303C1180009624010E0E000FD42E
-:103800003094FFFF3C0B08018D6B96D40260382189
-:1038100002802821AE2B01803C1308018E7396B4E0
-:1038200001602021240600830E00102FAFB300108A
-:103830008FBF002C8FB400288FB300248FB20020DC
-:103840008FB1001C8FB0001803E0000827BD0030C6
-:103850003C1808008F1831FC270F00013C010800BC
-:10386000AC2F31FC0A0021CE000000001474FFB917
-:1038700000000000A0C000FF3C0508008CA531E45A
-:103880003C0308008C6331E03C0208008C423204A7
-:103890008F99003834A80001241F00023C01080160
-:1038A000AC2396D43C010801A02896D03C01080125
-:1038B000A02296D3A33F00090A0021878F860038F3
-:1038C0000E00213D000000000A0021CE8F86003846
-:1038D0003C1F080193FF96B42419000113F9022933
-:1038E0008F8700703C100801921096B83C060801C2
-:1038F00090C696B610C000050200A0213C04080145
-:10390000908496B9109001E48F8700780010884069
-:103910008F9F0078023048210009C880033F702142
-:1039200095D80008270F0001A5CF00083C04080126
-:10393000908496B93C05080190A596B60E0020EB40
-:10394000000000008F8700780230202100043080C2
-:1039500000C720218C8500048F82007400A24023C0
-:1039600005020006AC8200048C8A00008F83007080
-:10397000014310235C400001AC8300008F860038B7
-:1039800090CB00FF2D6C00025580002D2414000107
-:103990000230F821001F40800107282190B9000B58
-:1039A0008CAE00040019C04003197821000F188064
-:1039B000006710218C4D000001AE88232630FFFFE8
-:1039C0005E00001F241400018C4400048CAA000037
-:1039D000008A482319200019240E00043C01080124
-:1039E000A02E96B590AD000B8CAB0004000D884066
-:1039F000022D802100101080004710218C4400040B
-:103A000001646023058202009443000890DF00FEF9
-:103A100090B9000B33E500FF54B900040107A02161
-:103A2000A0D400FE8F8700780107A0219284000BAC
-:103A30000E0020EB240500018F86003824140001BD
-:103A4000125400962E500001160000423C08FFFF61
-:103A5000241900021659FF3F00000000A0C000FF1B
-:103A60008F860038A0D200090A0021CE8F86003848
-:103A700090C700092404000230E300FF1064016FC6
-:103A800024090004106901528F8800748CCE005400
-:103A9000010E682325B100010620017524180004D9
-:103AA0003C010801A03896B53C010801A02096B45D
-:103AB00090D400FD90D200FF2E4F000215E0FF14BD
-:103AC000328400FF000438408F89007890DF00FFC7
-:103AD00000E41021000220800089C8212FE50002A7
-:103AE0009324000B14A0FF0A2407000200041840CE
-:103AF0000064802100105880016928218CAC0004EA
-:103B0000010C50230540FF02000000003C030801A7
-:103B1000906396B614600005246F00013C01080113
-:103B2000A02496B93C010801A02796B73C010801E2
-:103B3000A02F96B690CE00FF24E7000131CD00FF04
-:103B400001A7882B1220FFE990A4000B0A0021BDD9
-:103B5000000000003C0508018CA596B43C1200044E
-:103B600000A8F82413F20006240200053C0908010D
-:103B7000912996B5152000022402000324020005B5
-:103B80003C010801A02296D190C700FF14E001205B
-:103B900024020002A0C200090A0021CE8F8600384C
-:103BA00090CC00FF1180FEDA240A00018F8C007493
-:103BB0008F890078240F0003018068211160001EA6
-:103BC000240E0002000540400105A02100142080C1
-:103BD000008990218E510004019180230600FECCC3
-:103BE000000000003C020801904296B61440000517
-:103BF000245800013C010801A02A96B73C010801A5
-:103C0000A02596B93C010801A03896B690DF00FFC8
-:103C1000010510210002C88033E500FF254A00019C
-:103C20000329202100AA402B1500FEB99085000B26
-:103C30001560FFE5000540400005404001051821E2
-:103C4000000310803C010801A02A96B43C01080141
-:103C5000A02596B8004918218C64000400E4F823DC
-:103C600027F9FFFF1F20FFE9000000008C63000020
-:103C700000E358230560013A01A3882310E30117EC
-:103C80000184C0231B00FEA2000000003C010801CB
-:103C9000A02E96B50A0022FC240B0001240E00047D
-:103CA000A0CE00093C0D08008DAD31F88F8600389C
-:103CB00025A200013C010800AC2231F80A0021CE07
-:103CC000000000008CD9005C00F9C0231F00FE7BBF
-:103CD000000000008CDF005C10FFFF658F84007423
-:103CE0008CC3005C00834023250200011C40FF6060
-:103CF000000000008CC9005C2487000100E9282B2B
-:103D000010A0FE943C0D80008DAB01043C0C000122
-:103D1000016C50241140FE8F240200103C01080168
-:103D2000A02296D10A0021CE000000008F910074DD
-:103D30008F86003826220001ACC2005C0A0022896E
-:103D4000241400018F8700382404FF80000088219C
-:103D500090E9000A2414000101243025A0E6000A9D
-:103D60003C05080190A596B63C040801908496B9DC
-:103D70000E0020EB000000008F8600388F85007851
-:103D800090C800FD310700FF000740400107F821FF
-:103D9000001FC0800305C8219323000BA0C300FDB2
-:103DA0008F8500788F86003803056021918F000B86
-:103DB000000F704001CF6821000D808002051021A6
-:103DC0008C4B0000ACCB00548D8400048F830074B6
-:103DD0000064502319400002248200012462000183
-:103DE00001074821ACC2005C0009308000C54021B9
-:103DF00000E02021240500010E0020EB9110000BB3
-:103E00008F86003890C500FF10A0FF0C0010704096
-:103E10008F85007801D06821000D10800045582161
-:103E20008D6400008F8C00740184502325470001AD
-:103E300004E0FF02263100013C030801906396B6BE
-:103E40002E2F0002247800013C010801A03896B60C
-:103E50003C010801A03496B711E0FEF802003821B9
-:103E60000A00235C000740408F8400388F83007471
-:103E70008C85005800A340230502FE9AAC830058AD
-:103E80000A002232000000003C07080190E796D2A9
-:103E9000240200FF10E200BE8F8600383C110801AA
-:103EA000963196DA3C030801246396D82625000152
-:103EB0003230FFFF30ABFFFF020360212D6A00FFAD
-:103EC0001540008D918700043C010801A42096DA7A
-:103ED0008F8800380007484001272821911800FFEB
-:103EE000000530802405000127140001A11400FF03
-:103EF0003C120801925296D28F8800788F8E007003
-:103F0000264F000100C820213C010801A02F96D2B5
-:103F1000AC8E00008F8D0074A4850008AC8D000469
-:103F20003C030801906396B4146000770000902170
-:103F30003C010801A02596B4A087000B8F8C007867
-:103F400000CC5021A147000A8F820038A04700FD15
-:103F50008F840038A08700FE8F8600388F9F007006
-:103F6000ACDF00548F990074ACD900588F8D007865
-:103F70000127C02100185880016DA021928F000AEE
-:103F8000000F704001CF182100038880022D80218E
-:103F9000A207000B8F86007801666021918A000BD2
-:103FA000000A1040004A20210004288000A6402179
-:103FB000A107000A3C07800834E900808D22003008
-:103FC0008F860038ACC2005C0A00228924140001EC
-:103FD00090CA00FF1540FEAD8F880074A0C4000990
-:103FE0000A0021CE8F860038A0C000FD8F980038CF
-:103FF00024060001A30000FE3C010801A02696B59E
-:104000003C010801A02096B40A0021BD0000000078
-:1040100090CB00FF3C040801908496D3316C00FFE4
-:104020000184502B1540000F2402000324020004D9
-:10403000A0C200090A0021CE8F86003890C3000A72
-:104040002410FF8002035824316C00FF1180FDC151
-:10405000000000003C010801A02096B50A0021BD27
-:1040600000000000A0C200090A0021CE8F8600389F
-:1040700090D4000A2412FF8002544824312800FF03
-:104080001500FFF4240200083C010801A02296D18B
-:104090000A0021CE00000000001088408F8B0070C5
-:1040A000023018210003688001A72021AC8B00009A
-:1040B0008F8A0074240C0001A48C0008AC8A0004D0
-:1040C0003C05080190A596B62402000110A2FE1E30
-:1040D00024A5FFFF0A0022489084000B0184A0233E
-:1040E0001A80FD8B000000003C010801A02E96B54F
-:1040F0000A0022FC240B00013C010801A42596DAE9
-:104100000A0023AE8F880038240B0001106B0022B8
-:104110008F9800388F85003890BF00FF33F900FF7B
-:104120001079002B000000003C1F080193FF96B897
-:10413000001FC840033FC0210018A08002887821DA
-:1041400091EE000AA08E000A8F8D00783C030801D2
-:10415000906396B800CD88210A0023D4A223000BD7
-:10416000263000010600003101A490230640002BF8
-:10417000240200033C010801A02F96B50A0022FC8E
-:10418000240B00018F8900380A002232AD27005429
-:104190000A00228824120001931400FDA094000B51
-:1041A0008F8800388F8F0078910E00FE00CF682135
-:1041B000A1AE000A8F910038A22700FD8F83007006
-:1041C0008F900038AE0300540A0023D58F8D0078FD
-:1041D00090B000FEA090000A8F8B00388F8C007882
-:1041E000916A00FD00CC1021A04A000B8F8400389A
-:1041F000A08700FE8F8600748F850038ACA600581B
-:104200000A0023D58F8D007894B80008ACA4000470
-:10421000030378210A00227CA4AF00083C010801B6
-:10422000A02296B50A0021BD0000000090CF000931
-:10423000240D000431EE00FF11CDFD8524020001A4
-:104240003C010801A02296B50A0021BD0000000033
-:10425000080033440800334408003420080033F4D5
-:10426000080033D808003328080033280800332812
-:104270000800334C8008010080080080800800009E
-:104280005F865437E4AC62CC50103A4536621985EB
-:10429000BF14C0E81BC27A1E84F4B556094EA6FEB0
-:1042A0007DDA01E7C04D748108005A7408005AB8DD
-:1042B00008005A5C08005A5C08005A5C08005A5C06
-:1042C00008005A7408005A5C08005A5C08005AC07A
-:1042D00008005A5C080059D408005A5C08005A5C6F
-:1042E00008005AC008005A5C08005A5C08005A5C72
-:1042F00008005A5C08005A5C08005A5C08005A5CC6
-:1043000008005A5C08005A5C08005A5C08005A947D
-:1043100008005A5C08005A9408005A5C08005A5C6D
-:1043200008005A5C08005A9808005A9408005A5C21
-:1043300008005A5C08005A5C08005A5C08005A5C85
-:1043400008005A5C08005A5C08005A5C08005A5C75
-:1043500008005A5C08005A5C08005A5C08005A5C65
-:1043600008005A5C08005A5C08005A5C08005A5C55
-:1043700008005A5C08005A5C08005A5C08005A9809
-:1043800008005A9808005A5C08005A9808005A5CBD
-:1043900008005A5C08005A5C08005A5C08005A5C25
-:1043A00008005A5C08005A5C08005A5C08005A5C15
-:1043B00008005A5C08005A5C08005A5C08005A5C05
-:1043C00008005A5C08005A5C08005A5C08005A5CF5
-:1043D00008005A5C08005A5C08005A5C08005A5CE5
-:1043E00008005A5C08005A5C08005A5C08005A5CD5
-:1043F00008005A5C08005A5C08005A5C08005A5CC5
-:1044000008005A5C08005A5C08005A5C08005A5CB4
-:1044100008005A5C08005A5C08005A5C08005A5CA4
-:1044200008005A5C08005A5C08005A5C08005A5C94
-:1044300008005A5C08005A5C08005A5C08005A5C84
-:1044400008005A5C08005A5C08005A5C08005A5C74
-:1044500008005A5C08005A5C08005A5C08005A5C64
-:1044600008005A5C08005A5C08005A5C08005A5C54
-:1044700008005A5C08005A5C08005A5C08005A5C44
-:1044800008005A5C08005A5C08005A5C08005A5C34
-:1044900008005A5C08005A5C08005A5C08005A5C24
-:1044A00008005A5C08005A5C08005ADC0800782CA6
-:1044B00008007A90080078380800762C08007838D0
-:1044C000080078C4080078380800762C0800762C9C
-:1044D0000800762C0800762C0800762C0800762C34
-:1044E0000800762C0800762C0800762C0800762C24
-:1044F00008007858080078480800762C0800762CC8
-:104500000800762C0800762C0800762C0800762C03
-:104510000800762C0800762C0800762C0800762CF3
-:104520000800762C0800762C08007848080082D80D
-:1045300008008164080082A008008164080082707D
-:104540000800804C080081640800816408008164D0
-:1045500008008164080081640800816408008164A7
-:104560000800816408008164080081640800816497
-:10457000080081640800818C08008D1008008E6C92
-:0C45800008008E4C080088B408008D284C
-:04458C000A000124FC
-:1045900000000000000000000000000D7470613693
-:1045A0002E322E31610000000602010100000000E1
-:1045B00000000000000000000000000000000000FB
-:1045C00000000000000000000000000000000000EB
-:1045D00000000000000000000000000000000000DB
-:1045E00000000000000000000000000000000000CB
-:1045F00000000000000000000000000000000000BB
-:1046000000000000000000000000000000000000AA
-:10461000000000000000000000000000000000009A
-:1046200010000003000000000000000D0000000D5D
-:104630003C020800244217203C03080024632A108F
-:10464000AC4000000043202B1480FFFD24420004F6
-:104650003C1D080037BD2FFC03A0F0213C100800D2
-:10466000261004903C1C0800279C17200E000262B4
-:10467000000000000000000D2402FF8027BDFFE0C5
-:1046800000821024AFB00010AF420020AFBF00186E
-:10469000AFB10014936500043084007F03441821F7
-:1046A0003C0200080062182130A500200360802130
-:1046B0003C080111277B000814A000022466005C5E
-:1046C00024660058920200049743010492040004F7
-:1046D0003047000F3063FFFF30840040006728231D
-:1046E00010800009000048219202000530420004B9
-:1046F000104000050000000010A0000300000000B2
-:1047000024A5FFFC240900049202000530420004A5
-:10471000104000120000000010A000100000000077
-:104720009602000200A72021010440252442FFFE3A
-:10473000A7421016920300042402FF8000431024B5
-:10474000304200FF104000033C0204000A000174E4
-:10475000010240258CC20000AF4210188F42017840
-:104760000440FFFE2402000AA74201409602000214
-:1047700024040009304200070002102330420007E1
-:10478000A7420142960200022442FFFEA7420144D2
-:10479000A740014697420104A74201488F42010801
-:1047A0003042002050400001240400019202000425
-:1047B00030420010144000023483001000801821A1
-:1047C000A743014A000000000000000000000000B4
-:1047D00000000000AF4810000000000000000000D2
-:1047E00000000000000000008F4210000441FFFEA6
-:1047F0003102FFFF10400007000000009202000499
-:104800003042004014400003000000008F421018A6
-:10481000ACC20000960200063042FFFF24420002B4
-:10482000000210430002104003628821962200001B
-:104830001120000D3044FFFF00A710218F830038A6
-:104840008F45101C000210820002108000431021CE
-:10485000AC45000030A6FFFF0E00058D00052C02C0
-:1048600000402021A6220000920300042402FF80C1
-:1048700000431024304200FF1040001F00000000E1
-:1048800092020005304200021040001B00000000B0
-:104890009742100C2442FFFEA742101600000000B1
-:1048A0003C02040034420030AF421000000000001F
-:1048B0000000000000000000000000008F42100017
-:1048C0000441FFFE000000009742100C8F45101CB1
-:1048D0003042FFFF244200300002108200021080AC
-:1048E000005B1021AC45000030A6FFFF0E00058DD7
-:1048F00000052C02A6220000960400022484000871
-:104900000E0001E93084FFFF974401040E0001F717
-:104910003084FFFF8FBF00188FB100148FB00010DC
-:104920003C02100027BD002003E00008AF420178E0
-:104930003084FFFF308200078F8500241040000282
-:10494000248300073064FFF800A4102130421FFFC9
-:1049500003421821247B4000AF850028AF82002449
-:1049600003E00008AF4200843084FFFF3082000F74
-:104970008F85002C8F860034104000022483000FA6
-:104980003064FFF000A410210046182BAF850030E2
-:104990000046202314600002AF82002CAF84002C5C
-:1049A0008F82002C340480000342182100641821F7
-:1049B000AF83003803E00008AF4200808F8200140C
-:1049C000104000088F8200048F82FFDC1440000535
-:1049D0008F8200043C02FFBF3442FFFF008220248C
-:1049E0008F82000430430006240200021062000F90
-:1049F0003C0201012C620003504000052402000427
-:104A00001060000F3C0200010A00023000000000AC
-:104A100010620005240200061462000C3C02011121
-:104A20000A000229008210253C0200110082102594
-:104A3000AF421000240200010A000230AF82000CD5
-:104A400000821025AF421000AF80000C0000000073
-:104A5000000000000000000003E00008000000006B
-:104A60008F82000C10400004000000008F421000F4
-:104A70000441FFFE0000000003E000080000000009
-:104A80008F8200102443F800000231C224C2FFF0DC
-:104A90002C63030110600003000210420A00025759
-:104AA000AC8200008F85001800C5102B1440000B4D
-:104AB0000000182100C51023244700018F82001C2C
-:104AC00000A210212442FFFF0046102B5440000496
-:104AD0002402FFFF0A000257AC8700002402FFFFF8
-:104AE0000A000260AC8200008C82000000021940C3
-:104AF000006218210003188000621821000318804A
-:104B00003C0208002442175C0062182103E0000800
-:104B10000060102127BDFFD8AFBF0020AFB1001C3F
-:104B2000AFB000183C0460088C8250002403FF7F63
-:104B30003C066000004310243442380CAC82500024
-:104B40008CC24C1C3C1A8000000216023042000F3E
-:104B500010400007AF82001C8CC34C1C3C02001F9D
-:104B60003442FC0000621824000319C2AF8300180D
-:104B70008F420008275B400034420001AF4200082A
-:104B8000AF8000243C02601CAF400080AF40008436
-:104B90008C4500088CC308083402800003422021A1
-:104BA0002402FFF0006218243C0200803C0108004F
-:104BB000AC2204203C025709AF8400381462000480
-:104BC000AF850034240200010A000292AF82001473
-:104BD000AF8000148F4200003842000130420001D3
-:104BE0001440FFFC8F8200141040001600000000EB
-:104BF00097420104104000058F83000014600007F5
-:104C00002462FFFF0A0002A72C62000A2C62001037
-:104C1000504000048F83000024620001AF82000036
-:104C20008F8300002C62000A144000032C620007EE
-:104C30000A0002AEAF80FFDC104000022402000137
-:104C4000AF82FFDC8F4301088F44010030622000F7
-:104C5000AF83000410400008AF8400103C0208003D
-:104C60008C42042C244200013C010800AC22042C9C
-:104C70000A00058A3C0240003065020014A00003CF
-:104C800024020F001482026024020D0097420104E6
-:104C9000104002C83C02400030624000144000ADA9
-:104CA0008F8200388C4400088F4201780440FFFE58
-:104CB00024020800AF42017824020008A742014004
-:104CC000A7400142974201048F8400043051FFFF46
-:104CD0003082000110400007022080212623FFFEC1
-:104CE000240200023070FFFFA74201460A0002DBE7
-:104CF000A7430148A74001463C0208008C42043CFF
-:104D00001440000D8F8300103082002014400002F8
-:104D10002403000924030001006020218F83001078
-:104D2000240209005062000134840004A744014AAF
-:104D30000A0002F60000000024020F0014620005C1
-:104D400030820020144000062403000D0A0002F502
-:104D50002403000514400002240300092403000179
-:104D6000A743014A3C0208008C4204203C0400484E
-:104D70000E00020C004420250E0002350000000049
-:104D80008F82000C1040003E000000008F42100097
-:104D90003C03002000431024104000398F8200049F
-:104DA000304200021040003600000000974210140C
-:104DB0001440003300000000974210088F8800382C
-:104DC0003042FFFF244200060002188200033880B0
-:104DD00000E83021304300018CC400001060000462
-:104DE000304200030000000D0A00033700E81021E4
-:104DF000544000103084FFFF3C05FFFF0085202455
-:104E0000008518260003182B0004102B00431024E3
-:104E10001040000500000000000000000000000D30
-:104E200000000000240002228CC200000A000336A9
-:104E3000004520253883FFFF0003182B0004102BAA
-:104E40000043102410400005000000000000000096
-:104E50000000000D000000002400022B8CC20000A6
-:104E60003444FFFF00E81021AC4400003C0208007D
-:104E70008C420430244200013C010800AC22043082
-:104E80008F6200008F840038AF8200088C8300009E
-:104E90003402FFFF1462000F000010213C050800DF
-:104EA0008CA504543C0408008C84045000B02821D4
-:104EB00000B0302B00822021008620213C01080018
-:104EC000AC2504543C010800AC2404500A000580C1
-:104ED000240400088C820000304201001040000FC2
-:104EE000000010213C0508008CA5044C3C0408007F
-:104EF0008C84044800B0282100B0302B008220218F
-:104F0000008620213C010800AC25044C3C0108002F
-:104F1000AC2404480A000580240400083C0508006D
-:104F20008CA504443C0408008C84044000B0282173
-:104F300000B0302B00822021008620213C01080097
-:104F4000AC2504443C010800AC2404400A00058060
-:104F5000240400088F6200088F620000000216021D
-:104F6000304300F0240200301062000524020040AB
-:104F7000106200E08F8200200A00058824420001B0
-:104F800014A0000500000000000000000000000D5B
-:104F900000000000240002568F4201780440FFFE0A
-:104FA000000000000E00023D27A400101440000580
-:104FB00000408021000000000000000D0000000003
-:104FC0002400025D8E020000104000050000000079
-:104FD000000000000000000D00000000240002603E
-:104FE0008F62000C04430003240200010A00042E17
-:104FF000AE000000AE0200008F8200388C4800082E
-:10500000A20000078F65000C8F64000430A3FFFF2F
-:105010000004240200852023308200FF0043102179
-:1050200024420005000230832CC20081A605000A3C
-:1050300014400005A2040004000000000000000D60
-:1050400000000000240002788F8500380E0005ABB8
-:10505000260400148F6200048F430108A602000892
-:105060003C021000006218241060000800000000DC
-:1050700097420104920300072442FFEC34630002CC
-:105080003045FFFF0A0003C3A20300079742010453
-:105090002442FFF03045FFFF960600082CC20013A3
-:1050A00054400005920300079202000734420001B9
-:1050B000A20200079203000724020001106200050B
-:1050C000240200031062000B8F8200380A0003E004
-:1050D00030C6FFFF8F8200383C04FFFF8C43000C7A
-:1050E0000064182400651825AC43000C0A0003E096
-:1050F00030C6FFFF3C04FFFF8C43001000641824FF
-:1051000000651825AC43001030C6FFFF24C2000222
-:1051100000021083A20200058F830038304200FF96
-:1051200000021080004328218CA800008CA20000FF
-:1051300024030004000217021443001200000000C0
-:10514000974201043C03FFFF010318243042FFFF94
-:10515000004610232442FFFE00624025ACA8000058
-:1051600092030005306200FF000210800050102101
-:10517000904200143042000F004310210A00041531
-:10518000A20200068CA40004974201049603000AC0
-:105190003088FFFF3042FFFF004610232442FFD635
-:1051A0000002140001024025ACA80004920200078E
-:1051B000920400052463002800031883006418216A
-:1051C00034420004A2030006A20200078F820004FA
-:1051D0002403FFFB3442000200431024AF8200048A
-:1051E000920300068F87003800031880007010219A
-:1051F0008C4400203C02FFF63442FFFF0082402432
-:1052000000671821AE04000CAC68000C9205000683
-:105210003C03FF7F8E02000C0005288000B0202197
-:105220003463FFFF010330249488002600A728215F
-:1052300000431024AE02000CAC860020AC88002491
-:10524000ACA8001024020010A74201402402000272
-:10525000A7400142A7400144A742014697420104EA
-:105260003C0400082442FFFEA7420148240200013A
-:105270000E00020CA742014A9603000A92020004A3
-:105280000043102124420002304200070002102394
-:10529000304200070E000235AE0200108F6200009F
-:1052A0003C0308008C63044424040010AF8200080F
-:1052B000974201043042FFFF2442FFFE00403821A4
-:1052C000000237C33C0208008C42044000671821EA
-:1052D0000067282B00461021004510213C010800E2
-:1052E000AC2304443C010800AC2204400A0005152C
-:1052F0000000000014A000050000000000000000F5
-:105300000000000D000000002400030A8F42017815
-:105310000440FFFE000000000E00023D27A4001420
-:105320001440000500408021000000000000000D36
-:1053300000000000240003118E020000544000060B
-:1053400092020007000000000000000D00000000B5
-:105350002400031C920200073042000410400005A4
-:105360008F8200042403FFFB344200020043102418
-:10537000AF8200048F620004044300089202000719
-:10538000920200068E03000CAE00000000021080A6
-:1053900000501021AC43002092020007304200046C
-:1053A000544000099602000A920200053C030001E5
-:1053B00000021080005010218C46001800C33021DC
-:1053C000AC4600189602000A9206000427710008F5
-:1053D0000220202100C2302124C600052605001429
-:1053E0000E0005AB00063082920400068F650004B3
-:1053F0003C027FFF00042080009120218C83000468
-:105400003442FFFF00A2282400651821AC83000469
-:105410009202000792040005920300043042000447
-:105420001040001496070008308400FF000420801C
-:10543000009120218C860004974201049605000A01
-:10544000306300FF3042FFFF004310210045102170
-:1054500030E3FFFF004310232442FFD830C6FFFF94
-:105460000002140000C23025AC8600040A0004C902
-:1054700092030007308500FF0005288000B1282135
-:105480008CA4000097420104306300FF3042FFFF0C
-:1054900000431021004710233C03FFFF008320241A
-:1054A0003042FFFF00822025ACA4000092030007D9
-:1054B0002402000110620006000000002402000324
-:1054C00010620011000000000A0004EC8E030010BE
-:1054D00097420104920300049605000A8E24000CF2
-:1054E00000431021004510212442FFF23C03FFFF3E
-:1054F000008320243042FFFF00822025AE24000CD0
-:105500000A0004EC8E030010974201049203000489
-:105510009605000A8E24001000431021004510213A
-:105520002442FFEE3C03FFFF008320243042FFFFB4
-:1055300000822025AE2400108E0300102402000AF1
-:10554000A7420140A74301429603000A92020004C9
-:105550003C04004000431021A7420144A7400146FB
-:1055600097420104A7420148240200010E00020CE8
-:10557000A742014A0E000235000000008F620000C1
-:105580009203000400002021AF820008974201042A
-:105590009606000A3042FFFF0062182100602821B1
-:1055A0003C0308008C6304443C0208008C42044025
-:1055B00000651821004410210065382B0047102198
-:1055C0003C010800AC2304443C010800AC22044028
-:1055D00092040004008620212484000A3084FFFF06
-:1055E0000E0001E900000000974401043084FFFF31
-:1055F0000E0001F7000000003C021000AF420178ED
-:105600000A0005878F82002014820027306200067E
-:1056100097420104104000673C02400030624000A5
-:105620001040000500000000000000000000000D18
-:1056300000000000240004208F4201780440FFFE97
-:1056400024020800AF42017824020008A74201406A
-:10565000A74001428F8200049743010430420001B9
-:10566000104000073070FFFF2603FFFE24020002F7
-:10567000A7420146A74301480A00053F2402000D46
-:10568000A74001462402000DA742014A8F62000094
-:1056900024040008AF8200080E0001E900000000A9
-:1056A0000A00051902002021104000423C0240007F
-:1056B00093620000304300F02402001010620005E5
-:1056C00024020070106200358F8200200A000588D5
-:1056D000244200018F620000974301043050FFFF15
-:1056E0003071FFFF8F4201780440FFFE3202000755
-:1056F00000021023304200072403000A2604FFFEA4
-:10570000A7430140A7420142A7440144A7400146E4
-:10571000A75101488F420108304200201440000286
-:105720002403000924030001A743014A0E00020CD0
-:105730003C0400400E000235000000003C07080059
-:105740008CE70444021110212442FFFE3C060800AD
-:105750008CC604400040182100E3382100001021CD
-:105760008F65000000E3402B00C2302126040008B2
-:1057700000C830213084FFFFAF8500083C010800DD
-:10578000AC2704443C010800AC2604400E0001E9AB
-:10579000000000000A000519022020210E00013B34
-:1057A000000000008F82002024420001AF82002010
-:1057B0003C024000AF4201380A00029200000000A3
-:1057C0003084FFFF30C6FFFF00052C0000A628250F
-:1057D0003882FFFF004510210045282B004510218D
-:1057E00000021C023042FFFF0043102100021C0295
-:1057F0003042FFFF004310213842FFFF03E0000862
-:105800003042FFFF3084FFFF30A5FFFF000018216A
-:1058100010800007000000003082000110400002EC
-:1058200000042042006518210A0005A10005284057
-:1058300003E000080060102110C0000624C6FFFF2E
-:105840008CA2000024A50004AC8200000A0005AB75
-:105850002484000403E000080000000010A00008F9
-:1058600024A3FFFFAC860000000000000000000041
-:105870002402FFFF2463FFFF1462FFFA2484000464
-:0858800003E000080000000035
-:04588800000000011B
-:04588C000A00002AE4
-:1058900000000000000000000000000D7478703669
-:1058A0002E322E31610000000602010000000000CF
-:1058B000000001360000EA60000000000000000067
-:1058C00000000000000000000000000000000000D8
-:1058D00000000000000000000000000000000000C8
-:1058E00000000000000000000000000000000016A2
-:1058F00000000000000000000000000000000000A8
-:105900000000000000000000000000000000000097
-:105910000000000000000000000000000000000087
-:10592000000000000000138800000000000005DCFB
-:105930000000000000000000100000030000000054
-:105940000000000D0000000D3C02080024423D68EC
-:105950003C0308002463401CAC4000000043202BA3
-:105960001480FFFD244200043C1D080037BD7FFC6D
-:1059700003A0F0213C100800261000A83C1C0800E1
-:10598000279C3D680E00044E000000000000000D42
-:1059900027BDFFB4AFA10000AFA20004AFA3000871
-:1059A000AFA4000CAFA50010AFA60014AFA700185D
-:1059B000AFA8001CAFA90020AFAA0024AFAB0028FD
-:1059C000AFAC002CAFAD0030AFAE0034AFAF00389D
-:1059D000AFB8003CAFB90040AFBC0044AFBF004817
-:1059E0000E000591000000008FBF00488FBC0044EE
-:1059F0008FB900408FB8003C8FAF00388FAE0034B5
-:105A00008FAD00308FAC002C8FAB00288FAA002404
-:105A10008FA900208FA8001C8FA700188FA6001444
-:105A20008FA500108FA4000C8FA300088FA2000484
-:105A30008FA1000027BD004C3C1B60048F7A5030C2
-:105A4000377B502803400008AF7A00008F86003C67
-:105A50003C0390003C0280000086282500A32025FE
-:105A6000AC4400203C0380008C67002004E0FFFE73
-:105A70000000000003E00008000000000A000070C1
-:105A8000240400018F85003C3C0480003483000125
-:105A900000A3102503E00008AC82002003E000080A
-:105AA000000010213084FFFF30A5FFFF10800007A9
-:105AB0000000182130820001104000020004204242
-:105AC000006518211480FFFB0005284003E0000852
-:105AD0000060102110C00007000000008CA2000030
-:105AE00024C6FFFF24A50004AC82000014C0FFFB05
-:105AF0002484000403E000080000000010A0000857
-:105B000024A3FFFFAC86000000000000000000009E
-:105B10002402FFFF2463FFFF1462FFFA24840004C1
-:105B200003E000080000000090AA00318FAB0010D5
-:105B30008CAC00403C0300FF8D680004AD6C00207D
-:105B40008CAD004400E060213462FFFFAD6D0024A5
-:105B50008CA700483C09FF000109C024AD6700285C
-:105B60008CAE004C0182C82403197825AD6F000467
-:105B7000AD6E002C8CAD0038314A00FFAD6D001CBD
-:105B800094A900323128FFFFAD68001090A70030C3
-:105B9000A5600002A1600004A167000090A300328C
-:105BA000306200FF00021982106000052405000128
-:105BB0001065000E0000000003E00008A16A00016B
-:105BC0008CD80028354A0080AD7800188CCF00149E
-:105BD000AD6F00148CCE0030AD6E00088CC4002C6C
-:105BE000A16A000103E00008AD64000C8CCD001C2C
-:105BF000AD6D00188CC90014AD6900148CC8002468
-:105C0000AD6800088CC70020AD67000C8CC2001482
-:105C10008C8300700043C82B132000070000000095
-:105C20008CC20014144CFFE400000000354A0080D0
-:105C300003E00008A16A00018C8200700A0000E6FF
-:105C4000000000009089003027BDFFF88FA8001CDD
-:105C5000A3A900008FA300003C0DFF8035A2FFFF29
-:105C60008CAC002C00625824AFAB0000A1000004F3
-:105C700000C05821A7A000028D06000400A0482102
-:105C80000167C8218FA50000008050213C18FF7FCC
-:105C9000032C20263C0E00FF2C8C0001370FFFFF49
-:105CA00035CDFFFF3C02FF0000AFC82400EDC0244B
-:105CB00000C27824000C1DC00323682501F870255C
-:105CC000AD0D0000AD0E00048D240024AFAD00002A
-:105CD000AD0400088D2C00202404FFFFAD0C000C47
-:105CE0009547003230E6FFFFAD06001091450048B1
-:105CF00030A200FF000219C2506000018D24003460
-:105D0000AD0400148D4700388FAA001827BD000885
-:105D1000AD0B0028AD0A0024AD07001CAD00002C1F
-:105D2000AD00001803E00008AD00002027BDFFE033
-:105D3000AFB20018AFB10014AFB00010AFBF001C7D
-:105D40009098003000C088213C0D00FF330F007F89
-:105D5000A0CF0000908E003135ACFFFF3C0AFF0061
-:105D6000A0CE000194A6001EA22000048CAB00145B
-:105D70008E29000400A08021016C2824012A4024DF
-:105D80000080902101052025A6260002AE240004F3
-:105D900026050020262400080E000092240600029A
-:105DA00092470030260500282624001400071E0014
-:105DB0000003160324060004044000032403FFFF2D
-:105DC000965900323323FFFF0E000092AE230010DD
-:105DD000262400248FBF001C8FB200188FB100143E
-:105DE0008FB0001024050003000030210A00009C41
-:105DF00027BD002027BDFFD8AFB1001CAFB00018F1
-:105E0000AFBF002090A900302402000100E0502123
-:105E10003123003F00A040218FB000400080882146
-:105E200000C04821106200148FA70038240B000521
-:105E300000A0202100C02821106B00130200302197
-:105E40000E000128000000009225007C30A4000212
-:105E50001080000326030030AE000030260300341B
-:105E60008FBF00208FB1001C8FB000180060102180
-:105E700003E0000827BD00280E0000A7AFB0001007
-:105E80000A00016F000000008FA3003C01002021E8
-:105E90000120282101403021AFA300100E0000EEA8
-:105EA000AFB000140A00016F000000003C06800043
-:105EB00034C20E008C4400108F850044ACA4002036
-:105EC0008C43001803E00008ACA300243C068000CB
-:105ED00034C20E008C4400148F850044ACA4002012
-:105EE0008C43001C03E00008ACA300249382000C48
-:105EF0001040001B2483000F2404FFF000643824AA
-:105F000010E00019978B00109784000E9389000D04
-:105F10003C0A601C0A0001AC0164402301037021AB
-:105F2000006428231126000231C2FFFF30A2FFFFC8
-:105F30000047302B50C0000E00E448218D4D000C6E
-:105F400031A3FFFF00036400000C2C0304A1FFF346
-:105F50000000302130637FFF0A0001A42406000105
-:105F600003E00008000000009784000E00E44821D0
-:105F70003123FFFF3168FFFF0068382B54E0FFF842
-:105F8000A783000E938A000D11400005240F000125
-:105F9000006BC023A380000D03E00008A798000E4B
-:105FA000006BC023A38F000D03E00008A798000E2C
-:105FB00003E000080000000027BDFFE8AFB00010BC
-:105FC0003C10800036030140308BFFFF93AA002B6A
-:105FD000AFBF0014A46B000436040E0094880016B2
-:105FE00030C600FF8FA90030A4680006AC65000829
-:105FF000A0660012A46A001AAC6700208FA5002CCE
-:10600000A4690018012020210E000198AC6500143D
-:106010003C021000AE0201788FBF00148FB0001058
-:1060200003E0000827BD00188F85000024840007C6
-:1060300027BDFFF83084FFF83C06800094CB008A2F
-:10604000316AFFFFAFAA00008FA90000012540239D
-:106050002507FFFF30E31FFF0064102B1440FFF7FC
-:1060600000056882000D288034CC400000AC10216F
-:1060700003E0000827BD00088F8200002486000787
-:1060800030C5FFF800A2182130641FFF03E00008AC
-:10609000AF8400008F87003C8F84004427BDFFB091
-:1060A000AFB70044AFB40038AFB1002CAFBF004869
-:1060B000AFB60040AFB5003CAFB30034AFB2003074
-:1060C000AFB000283C0B80008C860024AD670080B8
-:1060D0008C8A002035670E0035690100ACEA00109B
-:1060E0008C8800248D2500040000B821ACE800183D
-:1060F0008CE3001000A688230000A021ACE300146C
-:106100008CE20018ACE2001C122000FE00E0B0217E
-:10611000936C0008118000F400000000976F0010DD
-:1061200031EEFFFF022E682B15A000EF00000000EB
-:10613000977200103250FFFFAED000003C03800089
-:106140008C740000329300081260FFFD0000000014
-:1061500096D800088EC700043305FFFF30B5000154
-:1061600012A000E4000000000000000D30BFA040BD
-:106170002419004013F9011B30B4A000128000DF85
-:106180000000000093730008126000080000000087
-:10619000976D001031ACFFFF00EC202B1080000346
-:1061A00030AE004011C000D500000000A7850040BF
-:1061B000AF8700389363000802202821AFB1002088
-:1061C000146000F527B40020AF60000C978F0040EA
-:1061D00031F1400016200002240300162403000EB3
-:1061E00024054007A363000AAF650014938A0042A8
-:1061F0008F7000143155000100151240020248252D
-:10620000AF690014979F00408F78001433F9001095
-:1062100003194025AF6800149792004032470008E8
-:1062200010E0016E000000008F6700143C121000A7
-:106230003C11800000F27825AF6F001436230E0069
-:10624000946E000A3C0D81002406000E31CCFFFF45
-:10625000018D2025AF640004A36600029373000A39
-:106260003406FFFC266B0004A36B000A97980040DD
-:10627000330820001100015F000000003C05800091
-:1062800034A90E00979900409538000C978700407C
-:10629000001940423312C0003103000300127B0397
-:1062A00030F11000006F68250011720301AE602507
-:1062B000000C20C0A764001297930040936A000A64
-:1062C000001359823175003C02AA10212450003C71
-:1062D000A3700009953F000C33F93FFFA779001028
-:1062E00097700012936900090130F82127E5000238
-:1062F00030B900070019C02333080007A368000B5A
-:106300009371000997720012976F0010322700FFF7
-:106310008F910038978D004000F21821006F702196
-:1063200001C6602131A6004010C000053185FFFF85
-:1063300000B1102B3C128000104000170000982183
-:106340000225A82B56A0013E8FA500203C0480000A
-:10635000348A0E008D5300143C068000AD530010AB
-:106360008D4B001CAD4B0018AD4500008CCD0000DE
-:1063700031AC00081180FFFD34CE0E0095C300083B
-:1063800000A0882100009021A78300408DC6000452
-:1063900024130001AF860038976F001031F5FFFF1E
-:1063A0008E9F000003F1282310A0011FAE8500007E
-:1063B00093620008144000DD000000000E0001E7B9
-:1063C000240400108F900048004028213C02320035
-:1063D000320600FF000654000142F825260900019C
-:1063E000AF890048ACBF000093790009977800128C
-:1063F000936F000A332800FF3303FFFF01033821A6
-:1064000000076C0031EE00FF01AE6025ACAC00046B
-:106410008F840048978B0040316A20001140010AA8
-:10642000ACA4000897640012308BFFFF06400108FF
-:10643000ACAB000C978E004031C5000814A00002E0
-:1064400026280006262800023C1F800037E70E00A1
-:1064500094F900148CE5001C8F6700049378000207
-:106460003324FFFF330300FFAFA300108F6F00142E
-:10647000AFA800180E0001CBAFAF00142404001029
-:106480000E0001FB000000008E9200001640000587
-:10649000000000008F7800142403FFBF0303A02432
-:1064A000AF7400148F67000C00F5C821AF79000CA1
-:1064B0009375000816A00008000000001260000696
-:1064C000000000008F6800143C0AEFFF3549FFFE12
-:1064D0000109F824AF7F0014A37300088FA50020E2
-:1064E0000A00034F02202021AED100000A00022D35
-:1064F0003C03800014E0FF1E30BFA0400E0001905E
-:106500000000A0212E9100010237B02512C0001812
-:106510008FBF00488F87003C24170F0010F700D46E
-:106520003C0680008CD901780720FFFE241F0F0055
-:1065300010FF00F634CA0E008D56001434C7014017
-:1065400024080240ACF600048D49001C3C141000E5
-:10655000ACE90008A0E00012A4E0001AACE00020C2
-:10656000A4E00018ACE80014ACD401788FBF004858
-:106570008FB700448FB600408FB5003C8FB4003811
-:106580008FB300348FB200308FB1002C8FB0002851
-:1065900003E0000827BD00508F9100389788004025
-:1065A0003C1280000220A8213107004014E0FF7C4B
-:1065B00000009821977900108F9200383338FFFF40
-:1065C000131200A8000020210080A021108000F3F9
-:1065D00000A088211620FECE000000000A00031F44
-:1065E0002E9100013C0380008C6201780440FFFE84
-:1065F000240808008F860000AC6801783C03800006
-:10660000946D008A31ACFFFF01865823256AFFFF95
-:1066100031441FFF2C8900081520FFF900000000FD
-:106620008F8F0048347040008F83003C00E0A02131
-:10663000240E0F0025E70001AF87004800D030216D
-:10664000023488233C08800031F500FF106E0005FD
-:106650002407000193980042331300010013924075
-:1066600036470001001524003C0A0100008A482535
-:10667000ACC900008F82004830BF003630B9000836
-:10668000ACC200041320009900FF982535120E00BB
-:106690009650000A8F8700003C0F81003203FFFFF5
-:1066A00024ED000835060140006F60253C0E100007
-:1066B00031AB1FFF269200062405000EACCC002053
-:1066C000026E9825A4C5001AAF8B0000A4D2001852
-:1066D000162000083C1080008F89003C24020F0027
-:1066E0005122000224170001367300400E00018879
-:1066F0003C10800036060E008CCB0014360A014098
-:1067000002402021AD4B00048CC5001CAD450008A3
-:10671000A1550012AD5300140E0001983C15100055
-:10672000AE1501780A00035200000000936F0009C3
-:10673000976E0012936D000B31E500FF00AE202133
-:1067400031AC00FF008C80212602000A3050FFFF90
-:106750000E0001E7020020218F8600483C03410023
-:106760003C05800024CB0001AF8B0048936A0009F0
-:106770009769001230C600FF315F00FF3128FFFF2C
-:1067800003E8382124F900020006C4000319782523
-:1067900001E37025AC4E00008F6D000C34A40E0098
-:1067A000948B001401B26025AC4C00048C85001C55
-:1067B0008F670004936A00023164FFFF314900FFD4
-:1067C000AFA900108F680014AFB100180E0001CB04
-:1067D000AFA800140A0002FD02002021AF600004EF
-:1067E000A360000297980040330820001500FEA324
-:1067F00000003021A760001297840040936B000ACC
-:106800003C10800030931F0000135183014BA821DE
-:1068100026A20028A362000936090E00953F000C4D
-:106820000A000295A77F00108F70001436090040FF
-:106830000E000188AF6900140A0002C900000000C0
-:106840000A00034F000020210641FEFAACA0000C14
-:106850008CAC000C3C0D8000018D90250A0002EAF2
-:10686000ACB2000C000090210A0002C52413000104
-:10687000128000073C028000344B0E009566000831
-:1068800030D3004012600049000000003C06800048
-:106890008CD001780600FFFE34C50E0094B50010C0
-:1068A0003C03050034CC014032B8FFFF03039025C0
-:1068B000AD92000C8CAF0014240D20003C0410009D
-:1068C000AD8F00048CAE001CAD8E0008A1800012BC
-:1068D000A580001AAD800020A5800018AD8D0014A1
-:1068E000ACC401780A0003263C0680008F9F00009C
-:1068F000351801402692000227F9000833281FFFAF
-:10690000A71200180A000391AF8800003C02800023
-:1069100034450140ACA0000C1280001B34530E0023
-:1069200034510E008E370010ACB700048E240018CE
-:106930003C0B8000ACA400083570014024040040EA
-:10694000A20000128FBF0048A600001A8FB70044B3
-:10695000AE0000208FB60040A60000188FB5003CA6
-:10696000AE0400148FB400388FB300348FB20030FF
-:106970008FB1002C8FB000283C02100027BD0050C2
-:1069800003E00008AD6201788E660014ACA6000436
-:106990008E64001C0A00042A3C0B80000E0001904B
-:1069A0002E9100010A0003200237B02500000000EC
-:1069B0000000000D00000000240003690A0004012B
-:1069C0003C06800027BDFFD8AFBF00203C098000F7
-:1069D0003C1F20FFAFB200183C07600035320E00AC
-:1069E0002402001037F9FFFDACE23008AFB3001C01
-:1069F000AFB10014AFB00010AE59000000000000AD
-:106A00000000000000000000000000000000000086
-:106A10003C1800FF3713FFFDAE5300003C0B600431
-:106A20008D7050002411FF7F3C0E0002021178246B
-:106A300035EC380C35CD0109ACED4C18240A0009B1
-:106A4000AD6C50008CE80438AD2A0008AD2000146D
-:106A50008CE54C1C3106FFFF38C42F7100051E0267
-:106A60003062000F2486C0B310400007AF820008D8
-:106A70008CE54C1C3C09001F3528FC0000A818249C
-:106A8000000321C2AF8400048CF108083C0F5709B1
-:106A90002412F0000232702435F0001001D060267C
-:106AA00001CF68262DAA00012D8B0001014B38254E
-:106AB00050E00009A380000C3C1F601C8FF8000808
-:106AC00024190001A399000C33137C00A793001034
-:106AD000A780000EA380000DAF80004814C0000303
-:106AE000AF8000003C066000ACC0442C0E0005B92D
-:106AF0003C1080000E000F1A361101003C120800F5
-:106B000026523DD03C13080026733E508E030000F1
-:106B100038640001308200011440FFFC3C0B800A05
-:106B20008E2600002407FF8024C90240312A007FFE
-:106B3000014B402101272824AE060020AF880044E5
-:106B4000AE0500243C048000AF86003C8C8C0178AC
-:106B50000580FFFE24180800922F0008AC980178E9
-:106B6000A38F0042938E004231CD000111A0000F8F
-:106B700024050D0024DFF8002FF903011320001C69
-:106B8000000629C224A4FFF0000410420002314094
-:106B90000E00020200D2D8213C0240003C068000D8
-:106BA000ACC201380A0004A00000000010C5002398
-:106BB000240D0F0010CD00273C1F800837F90080FE
-:106BC00093380000240E0050330F00FF15EEFFF342
-:106BD0003C0240000E000A36000000003C0240006B
-:106BE0003C068000ACC201380A0004A0000000008E
-:106BF0008F83000400A3402B1500000B8F8B00082F
-:106C0000006B50212547FFFF00E5482B15200006AB
-:106C100000A36023000C19400E0002020073D8216B
-:106C20000A0004C43C0240000000000D0E000202F5
-:106C3000000000000A0004C43C0240003C1B0800A5
-:106C4000277B3F500E000202000000000A0004C42F
-:106C50003C0240003C1B0800277B3F700E000202F4
-:106C6000000000000A0004C43C0240003C0660042E
-:106C70003C09080025290104ACC9502C8CC85000DF
-:106C80003C0580003C02000235070080ACC7500084
-:106C90003C040800248415A43C0308002463155C0C
-:106CA000ACA50008ACA2000C3C010800AC243D607F
-:106CB0003C010800AC233D6403E00008240200010D
-:106CC00000A030213C1C0800279C3D683C0C0400BF
-:106CD0003C0B0002008B3826008C40262CE2000181
-:106CE0000007502B2D050001000A48803C030800D6
-:106CF00024633D60004520250123182110800003F6
-:106D000000001021AC6600002402000103E000082E
-:106D1000000000003C1C0800279C3D683C0B040060
-:106D20003C0A0002008A3026008B38262CC2000163
-:106D30000006482B2CE50001000940803C030800B8
-:106D400024633D60004520250103182110800005C3
-:106D5000000010213C0C0800258C155CAC6C000078
-:106D60002402000103E00008000000003C090002CA
-:106D70003C08040000883026008938262CC3000116
-:106D8000008028212CE40001008310251040000B16
-:106D9000000030213C1C0800279C3D683C0A800014
-:106DA0008D4E00082406000101CA6825AD4D00087B
-:106DB0008D4C000C01855825AD4B000C03E00008FC
-:106DC00000C010213C1C0800279C3D683C05800049
-:106DD0008CA6000C000420272402000100C4182403
-:106DE00003E00008ACA3000C3C0200021082000B80
-:106DF0003C0560003C070400108700030000000011
-:106E000003E00008000000008CA908D0240AFFFD60
-:106E1000012A402403E00008ACA808D08CA408D0C4
-:106E20002406FFFE0086182403E00008ACA308D067
-:106E30003C05601A34A600108CC3008027BDFFF803
-:106E40008CC50084AFA3000093A4000024020001BD
-:106E500010820003AFA5000403E0000827BD00086E
-:106E600093A7000114E0001497AC000297B8000249
-:106E70003C0F8000330EFFFC01CF6821ADA5000060
-:106E8000A3A000003C0660008CC708D02408FFFEC9
-:106E90003C04601A00E82824ACC508D08FA3000485
-:106EA0008FA200003499001027BD0008AF22008097
-:106EB00003E00008AF2300843C0B8000318AFFFC14
-:106EC000014B48218D2800000A00057DAFA8000471
-:106ED00027BDFFE8AFBF00103C1C0800279C3D68A1
-:106EE0003C0580008CA4000C8CA200043C03000232
-:106EF0000044282410A0000A00A318243C06040023
-:106F00003C0400021460000900A610241440000F85
-:106F10003C0404000000000D3C1C0800279C3D6858
-:106F20008FBF001003E0000827BD00183C020800D6
-:106F30008C423D600040F809000000003C1C080045
-:106F4000279C3D680A0005A68FBF00103C02080080
-:106F50008C423D640040F809000000000A0005ACC6
-:106F600000000000000411C003E0000824420240B9
-:106F70003C04080024843FB42405001A0A00009C45
-:106F80000000302127BDFFE0AFB000103C108000B2
-:106F9000AFBF0018AFB100143611010092220009F2
-:106FA0000E0005B63044007F8E3F00008F89003C04
-:106FB0003C0F008003E26021258800400049F82151
-:106FC000240DFF80310E00783198007835F90001EA
-:106FD00035F100020319382501D14825010D30246F
-:106FE00003ED5824018D2824240A00402404008045
-:106FF000240300C0AE0B0024AE000810AE0A081433
-:10700000AE040818AE03081CAE050804AE0708203D
-:10701000AE060808AE090824360909009539000CA7
-:107020003605098033ED007F3338FFFF001889C033
-:10703000AE110800AE0F0828952C000C8FBF001869
-:107040008FB10014318BFFFF000B51C0AE0A002C32
-:107050008CA400508FB000108CA3003C8D2700043E
-:107060008CA8001C8CA600383C0E800A01AE1021B2
-:1070700027BD0020AF820044AF840050AF8300548E
-:10708000AF87004CAF88005C03E00008AF8600606B
-:107090003C09080091293FD924A800023C051100B1
-:1070A00000093C0000E8302500C5182524820008AE
-:1070B000AC83000003E00008AC8000043C098000C1
-:1070C000352309009128010B906A00112402002841
-:1070D00000804821314700FF00A0702100C06821D6
-:1070E0003108004010E20002340C86DD240C080058
-:1070F0003C0A800035420A9A94470000354B0A9CAE
-:1071000035460AA030F9FFFFAD3900008D78000048
-:10711000354B0A8024040001AD3800048CCF0000F8
-:10712000AD2F00089165001930A300031064009092
-:1071300028640002148000AF240500021065009E40
-:10714000240F0003106F00B435450AA4240A080078
-:10715000118A0048000000005100003D3C0B8000F7
-:107160003C048000348309009067001230E200FF85
-:10717000004D7821000FC880272400013C0A8000C0
-:10718000354F090091E50019354C09808D8700289D
-:1071900030A300FF00031500004758250004C40079
-:1071A0003C19600001793025370806FFAD26000044
-:1071B000AD2800048DEA002C25280028AD2A0008FF
-:1071C0008DEC0030AD2C000C8DE50034AD250010A9
-:1071D0008DE400383C05800034AC093CAD2400143B
-:1071E0008DE3001CAD2300188DE70020AD27001CA7
-:1071F0008DE20024AD2200208DF9002834A2010088
-:10720000AD3900248D830000AD0E000434B90900AF
-:10721000AD0300008C47000C25020014AD070008E8
-:10722000932B00123C04080090843FD8AD0000105E
-:10723000317800FF030D302100064F0000047C0070
-:10724000012F702535CDFFFC03E00008AD0D000CCB
-:1072500035780900930600123C05080094A53FC844
-:1072600030C800FF010D5021000A60800A00063C72
-:10727000018520211500005B000000003C0808008B
-:1072800095083FCE3C06080094C63FC80106102171
-:107290003C0B80003579090093380011932A0019BE
-:1072A00035660A80330800FF94CF002A0008608208
-:1072B000314500FF978A0058000C1E00000524008D
-:1072C0003047FFFF006410250047C02501EA302148
-:1072D0003C0B4000030B402500066400AD28000075
-:1072E000AD2C0004932500183C030006252800144B
-:1072F00000053E0000E31025AD2200088F24002C7D
-:107300003C05800034AC093CAD24000C8F38001CD7
-:1073100034A20100254F0001AD3800108D8300001C
-:10732000AD0E000431EB7FFFAD0300008C47000C75
-:1073300034B90900A78B0058AD070008932B001241
-:107340003C04080090843FD825020014317800FFE7
-:10735000030D302100064F0000047C00012F702532
-:1073600035CDFFFCAD00001003E00008AD0D000CB2
-:107370003C02080094423FD23C05080094A53FC857
-:1073800035440AA43C07080094E73FC4948B0000EE
-:107390000045C8210327C023000B1C002706FFF26D
-:1073A00000665025AD2A000CAD200010AD2C001455
-:1073B0000A00063025290018354F0AA495E500007B
-:1073C000956400280005140000043C003459810035
-:1073D00000EC5825AD39000CAD2B00100A0006302A
-:1073E000252900143C0C0800958C3FCE0A0006812C
-:1073F000258200015460FF56240A080035580AA46B
-:107400009706000000061C00006C5025AD2A000CF9
-:107410000A000630252900103C03080094633FD27F
-:107420003C07080094E73FC83C0F080095EF3FC4B5
-:1074300094A400009579002800671021004F58237C
-:1074400000041C00001934002578FFEE00D87825D0
-:10745000346A8100AD2A000CAD2F0010AD2000145D
-:10746000AD2C00180A0006302529001C03E0000896
-:10747000240207D027BDFFE0AFB20018AFB100145F
-:10748000AFB00010AFBF001C0E00007C0080882150
-:107490008F8800548F87004C3C05800834B20080F0
-:1074A000011128213C10800024020080240300C028
-:1074B00000A72023AE0208183C068008AE03081C73
-:1074C00018800004AF850054ACC500048CC90004CA
-:1074D000AF89004C12200009360409800E0006F81E
-:1074E00000000000924C00278E0B007401825004B3
-:1074F000014B3021AE46000C360409808C8E001CF6
-:107500008F8F005C01CF682319A000048FBF001C7F
-:107510008C90001CAF90005C8FBF001C8FB20018D5
-:107520008FB100148FB000100A00007E27BD00202C
-:107530008F8600508F8300548F82004C3C0580085A
-:1075400034A40080AC860050AC83003C03E000080B
-:10755000ACA200043C0308008C63005427BDFFF874
-:10756000308400FF2462000130A500FF3C010800C8
-:10757000AC22005430C600FF3C0780008CE8017844
-:107580000500FFFE3C0C7FFFA3A400038FAA0000B0
-:10759000358BFFFF014B4824000627C001244025FE
-:1075A000AFA8000034E201009043000AA3A000024B
-:1075B0003C1980FFA3A300018FAF000030AE007F15
-:1075C0003738FFFF01F86024000E6E003C0A0020EF
-:1075D00034E50140018D5825354920002406FF80FF
-:1075E0003C04100027BD0008ACAB000CACA9001493
-:1075F000A4A00018A0A6001203E00008ACE40178E3
-:10760000308800FF30A700FF3C0380008C620178C7
-:107610000440FFFE3C0C8000358A0A008D4B0020A0
-:107620003584014035850980AC8B00048D490024E8
-:107630000007302B00061540AC890008A088001018
-:1076400090A3004CA083002D03E00008A480001844
-:1076500027BDFFE8308400FFAFBF00100E00075DBC
-:1076600030A500FF8F8300548FBF00103C068000C0
-:1076700034C50140344700402404FF903C02100010
-:1076800027BD0018ACA3000CA0A40012ACA70014E6
-:1076900003E00008ACC2017827BDFFE03C08800889
-:1076A000AFBF001CAFB20018AFB10014AFB00010F4
-:1076B000351000808E0600183C078000309200FFD5
-:1076C00000C72025AE0400180E00007C30B100FF7A
-:1076D00092030005346200080E00007EA20200053D
-:1076E000024020210E0007710220282102402021A3
-:1076F0008FBF001C8FB200188FB100148FB0001024
-:1077000024050005240600010A00073227BD0020D9
-:107710003C05800034A309809066000830C2000850
-:107720001040000F3C0A01013549080AAC890000ED
-:107730008CA80074AC8800043C07080090E73FD890
-:1077400030E5001050A00008AC8000083C0D800817
-:1077500035AC00808D8B0058AC8B00082484000C65
-:1077600003E00008008010210A0007B52484000C03
-:1077700027BDFFE83C098000AFB00010AFBF001488
-:107780003526098090C800092402000600A058216F
-:10779000310300FF35270900008080212405000403
-:1077A0001062007B2408000294CF005C3C0E0204AF
-:1077B00031EDFFFF01AE6025AE0C000090CA00085D
-:1077C00031440020108000080000000090C2004EEC
-:1077D0003C1F010337F90300305800FF031930251F
-:1077E00024050008AE06000490F9001190E600128E
-:1077F00090E40011333800FF0018708230CF00FF92
-:1078000001CF5021014B6821308900FF31AAFFFFD1
-:1078100039230028000A60801460002C020C4823E1
-:1078200090E400123C198000372F0100308C00FFDB
-:10783000018B1821000310800045F821001F8400EF
-:10784000360706FFAD270004373F090093EC00110F
-:1078500093EE0012372609800005C0828DE4000CEB
-:107860008CC5003431CD00FF01AB10210058182128
-:1078700000A4F8230008840000033F0000F0302536
-:1078800033F9FFFF318F00FC00D97025015820210A
-:1078900001E9682100045080ADAE000C0E00007CB0
-:1078A000012A80213C088008240B00043505008053
-:1078B0000E00007EA0AB0009020010218FBF001453
-:1078C0008FB0001003E0000827BD001890EC0011F5
-:1078D00090E300193C18080097183FCE318200FF52
-:1078E0000002F882307000FF001FCE0000103C0044
-:1078F0000327302500D870253C0F400001CF6825B4
-:107900003C198000AD2D0000373F090093EC0011B9
-:1079100093EE0012372F0100372609800005C08240
-:107920008DE4000C8CC5003431CD00FF01AB10217B
-:107930000058182100A4F8230008840000033F0029
-:1079400000F0302533F9FFFF318F00FC00D970259E
-:107950000158202101E9682100045080ADAE000CDF
-:107960000E00007C012A80213C088008240B0004C2
-:10797000350500800E00007EA0AB0009020010213A
-:107980008FBF00148FB0001003E0000827BD00185F
-:107990000A0007C72408001227BDFFD03C0380005F
-:1079A000AFB60028AFB50024AFB40020AFB10014CB
-:1079B000AFBF002CAFB3001CAFB20018AFB00010C7
-:1079C0003467010090E6000B309400FF30B500FFF3
-:1079D00030C200300000B021104000990000882122
-:1079E000346409809088000800082E0000051E03FA
-:1079F000046000C0240400048F8600543C01080089
-:107A0000A0243FD83C0C8000AD8000483C0480009E
-:107A1000348E010091CD000B31A5002010A000078D
-:107A20003C0780003493098092720008001286009F
-:107A300000107E0305E000C43C1F800834EC010008
-:107A4000918A000B34EB09809169000831440040B1
-:107A50000004402B3123000800C898231460000262
-:107A600024120003000090213C10800036180A8088
-:107A700036040900970E002C9083001190890012A3
-:107A800093050018307F00FF312800FF02481021C5
-:107A90000002C880930D0018033F782101F13021C6
-:107AA00030B100FF00D11821A78E00583C0108001A
-:107AB000A4263FCE3C010800A4233FD015A000021D
-:107AC000000000000000000D920B010B3065FFFF6D
-:107AD0003C010800A4233FD2316A00403C01080069
-:107AE000A4203FC83C010800A4203FC4114000026C
-:107AF00024A4000A24A4000B3091FFFF0E0001E72C
-:107B0000022020219206010B3C0C0800958C3FD2EC
-:107B1000004020210006698231A700010E00060105
-:107B20000187282100402021026028210E00060C38
-:107B3000024030210E0007A10040202116C000693C
-:107B4000004020219212010B3256004012C0000565
-:107B50003C0500FF8C93000034AEFFFF026E8024D2
-:107B6000AC9000000E0001FB022020213C0F080019
-:107B700091EF3FD831F10003122000163C1380082A
-:107B80008F8200543C09800835280080245F000162
-:107B9000AD1F003C3C0580088CB9000403E02021A7
-:107BA000033FC0231B000002AF9F00548CA40004BD
-:107BB0000E0006F8ACA400043C0780008CEB0074B7
-:107BC0003C04800834830080004B5021AC6A000CD8
-:107BD0003C138008367000800280202102A02821FA
-:107BE000A200006B0E00075D3C1480008F920054D1
-:107BF000368C0140AD92000C8F8600483C15100079
-:107C0000344D000624D60001AF9600488FBF002CEB
-:107C1000A18600128FB60028AD8D00148FB3001C12
-:107C2000AE9501788FB200188FB500248FB4002074
-:107C30008FB100148FB0001003E0000827BD0030A2
-:107C400034640980908F0008000F7600000E6E03E8
-:107C500005A00033347F090093F8001B241900109D
-:107C60003C010800A0393FD8331300021260FF67BF
-:107C70008F8600548F8200601446FF653C048000AC
-:107C80000E00007C000000003C0480083485008069
-:107C900090A8000924060016310300FF1066000DAD
-:107CA0000000000090AB00093C07080090E73FD8B7
-:107CB00024090008316400FF34EA00013C01080097
-:107CC000A02A3FD81089002F240C000A108C00280D
-:107CD0002402000C0E00007E000000000A00086074
-:107CE0008F8600540E0007B9024028210A0008AE12
-:107CF000004020213C0B8008356A00808D460054EE
-:107D00008CE9000C1120FF3DAF86005424070014BD
-:107D10003C010800A0273FD80A00085F3C0C800007
-:107D200090910008241200023C010800A0323FD8C4
-:107D3000323000201200000B241600018F86005400
-:107D40000A0008602411000837F800808F0200380C
-:107D5000AFE200048FF90004AF19003C0A00086C80
-:107D60003C0780008F8600540A000860241100043C
-:107D7000A0A200090E00007E000000000A000860BA
-:107D80008F860054240200140A00093AA0A20009B8
-:107D900027BDFFE8AFB000103C108000AFBF00145B
-:107DA00036020100904400090E00075D2405000121
-:107DB0003C0480089099000E34830080909F000F4F
-:107DC000906F00269089000A33F800FF00196E00BA
-:107DD0000018740031EC00FF01AE5025000C5A0071
-:107DE000014B3825312800FF36030140344560003F
-:107DF00000E830252402FF813C041000AC66000C32
-:107E00008FBF0014AC650014A0620012AE040178AC
-:107E10008FB0001003E0000827BD001827BDFFE861
-:107E2000308400FFAFBF00100E00075D30A500FFDB
-:107E30003C05800034A40140344700402406FF92F2
-:107E4000AC870014A08600128F8300548FBF0010EF
-:107E50003C02100027BD0018AC83000C03E00008B2
-:107E6000ACA2017827BDFFD8AFB00010308400FF6E
-:107E700030B000FF3C058000AFB10014AFBF002060
-:107E8000AFB3001CAFB20018000410C234A601004A
-:107E900032030002305100011460000790D2000943
-:107EA0003C098008353300809268000531070008DE
-:107EB00010E0000C308A0010024020210E000783E1
-:107EC00002202821240200018FBF00208FB3001C54
-:107ED0008FB200188FB100148FB0001003E00008BB
-:107EE00027BD00281540003434A50A008CB80024B2
-:107EF0008CAF0008130F004B000038213C0D8008A8
-:107F000035B30080926C006824060002318B00FFBC
-:107F1000116600843C06800034C201009263004C6C
-:107F200090590009307F00FF53F900043213007CA0
-:107F300010E00069000000003213007C5660005C15
-:107F40000240202116200009320D00013C0C800067
-:107F500035840100358B0A008D6500248C86000471
-:107F600014A6FFD900001021320D000111A0000E4F
-:107F7000024020213C188000371001008E0F000CB9
-:107F80008F8E005011EE0008000000000E00084324
-:107F9000022028218E19000C3C1F800837F0008039
-:107FA000AE190050024020210E0007710220282146
-:107FB0000A00098F240200013C0508008CA500641A
-:107FC00024A400013C010800AC2400641600000D4C
-:107FD00000000000022028210E000771024020212D
-:107FE000926E0068240C000231CD00FF11AC00221B
-:107FF000024020210E000941000000000A00098F04
-:10800000240200010E00007024040001926B002580
-:10801000020B30250E00007EA26600250A0009D35F
-:10802000022028218E6200188CDF00048CB9002405
-:1080300000021E0217F9FFB13065007F9268004C04
-:10804000264400013093007F12650040310300FF99
-:108050001464FFAB3C0D80082647000130F1007F1F
-:1080600030E200FF1225000B2407000100409021A0
-:108070000A00099C24110001240500040E000732A7
-:10808000240600010E000941000000000A00098FCB
-:10809000240200012405FF8002452024008590264B
-:1080A000324200FF004090210A00099C2411000187
-:1080B0000E000843022028213207003010E0FFA103
-:1080C00032100082024020210E0007830220282166
-:1080D0000A00098F240200018E6900180240202145
-:1080E00002202821012640250E000964AE680018F0
-:1080F0009264004C24050003240600010E000732A0
-:10810000308400FF0E0000702404000192710025ED
-:10811000021150250E00007EA26A00250A00098F78
-:10812000240200018E6F00183C18800002402021BC
-:1081300001F87025022028210E000771AE6E00188C
-:108140009264004C0A000A1B24050004324A008095
-:10815000394900801469FF6A3C0D80080A0009F45F
-:108160002647000127BDFFC0AFB000183C108000BB
-:10817000AFBF0038AFB70034AFB60030AFB5002C9A
-:10818000AFB40028AFB30024AFB200200E0005BE8C
-:10819000AFB1001C360201009045000B0E000976BD
-:1081A00090440008144000E78FBF00383C08800866
-:1081B00035070080A0E0006B3606098090C50000FE
-:1081C000240300503C17080026F73F9030A400FF1E
-:1081D0003C13080026733FA0108300033C1080006E
-:1081E0000000B82100009821241F00103611010062
-:1081F00036120A00361509808E5800248E34000489
-:108200008EAF00208F8C00543C010800A03F3FD867
-:1082100036190A80972B002C8EF60000932A00183E
-:108220000298702301EC68233C010800AC2E3FB497
-:108230003C010800AC2D3FB83C010800AC2C3FDCF1
-:10824000A78B005802C0F809315400FF30490002E2
-:10825000152000E930420001504000C49227000977
-:1082600092A9000831280008150000022415000317
-:108270000000A8213C0A80003543090035440A006B
-:108280008C8D00249072001190700012907F00116C
-:10829000325900FF321100FF02B110210002C080EC
-:1082A00033EF00FF0319B021028F702102D4602147
-:1082B00025CB00103C010800A4363FCE3C0108004D
-:1082C000AC2D3FE03C010800A42C3FD03C0108004D
-:1082D000A42B3FCC355601003554098035510E0092
-:1082E0008F8700548F89005C8E850020240800064B
-:1082F000012730233C010800AC283FD400A72823E5
-:1083000004C000B50000902104A000B300C5502BAC
-:10831000114000B5000000003C010800AC263FB849
-:108320008E6200000040F8090000000030460002A4
-:1083300014C0007400408021304B000155600011D2
-:108340008E6200043C0D08008DAD3FBC3C0EC000A9
-:108350003C04800001AE6025AE2C00008C9800002B
-:10836000330F000811E0FFFD00000000963F0008F9
-:1083700024120001A79F00408E390004AF990038F5
-:108380008E6200040040F80900000000020280250F
-:1083900032030002146000B3000000003C09080032
-:1083A00095293FC43C06080094C63FD03C0A08000B
-:1083B000954A3FC63C0708008CE73FBC0126702168
-:1083C0003C0308008C633FE03C08080095083FDA56
-:1083D00001CA20218ED9000C00E92821249F000227
-:1083E00000A878210067C02133E4FFFFAF99005057
-:1083F0003C010800AC383FE03C010800A42F3FC816
-:108400003C010800A42E3FD20E0001E7000000004E
-:108410008F8D0048004020213C010800A02D3FD94D
-:108420008E62000825AC0001AF8C00480040F809BE
-:10843000000000008F85005402A030210E00060CC1
-:10844000004020210E0007A1004020218E6B000C6F
-:108450000160F809004020213C0A0800954A3FD2FB
-:108460003C06080094C63FC6014648212528000264
-:108470000E0001FB3104FFFF3C0508008CA53FB452
-:108480003C0708008CE73FBC00A720233C01080004
-:10849000AC243FB414800006000000003C02080039
-:1084A0008C423FD4344B00403C010800AC2B3FD4FD
-:1084B000124000438F8E00448E2D00108F92004496
-:1084C000AE4D00208E2C0018AE4C00243C04080059
-:1084D00094843FC80E0006FA000000008F9F0054ED
-:1084E0008E6700103C010800AC3F3FDC00E0F8095B
-:1084F000000000003C1908008F393FB41720FF79B5
-:108500008F870054979300583C11800E321601005B
-:108510000E000729A633002C16C0004532030010B8
-:108520005460004C8EE50004320800405500001DE8
-:108530008EF000088EE4000C0080F80900000000B6
-:108540008FBF00388FB700348FB600308FB5002C46
-:108550008FB400288FB300248FB200208FB1001C8D
-:108560008FB0001803E0000827BD00408F86003C54
-:1085700036110E0000072E0000A62025AE04008054
-:108580008E4300208E500024AFA30010AE230014B1
-:108590008FB20010AE320010AE30001C0A000A7517
-:1085A000AE3000180200F809000000008EE4000C54
-:1085B0000080F809000000000A000B2E8FBF003871
-:1085C00024180001240F0001A5C00020A5D8002216
-:1085D0000A000B10ADCF00243C010800AC203FB8CE
-:1085E0000A000AA68E6200003C010800AC253FB8D4
-:1085F0000A000AA68E620000922400090E0007718C
-:10860000000028218FBF00388FB700348FB60030AC
-:108610008FB5002C8FB400288FB300248FB20020B8
-:108620008FB1001C8FB0001803E0000827BD004088
-:108630003C14800092950109000028210E00084397
-:1086400032A400FF320300105060FFB8320800402F
-:108650008EE5000400A0F809000000000A000B28C5
-:10866000320800405240FFA8979300588E340014FF
-:108670008F930044AE7400208E35001CAE7500242C
-:108680000A000B1F979300588F820014000421806A
-:1086900003E00008008210213C07800834E20080DB
-:1086A0009043006900804021106000093C040100F3
-:1086B0003C0708008CE73FDC8F83003000E3202379
-:1086C000048000089389001C14E3000301002021AA
-:1086D00003E00008008010213C04010003E00008D2
-:1086E000008010211120000B006738233C0D800012
-:1086F00035AC0980918B007C316A0002114000206A
-:108700002409003400E9702B15C0FFF1010020217D
-:1087100000E938232403FFFC00A3C82400E3C0249D
-:1087200000F9782B15E0FFEA0308202130C400038C
-:108730000004102314C0001430490003000030214D
-:1087400000A9782101E6702100EE682B11A0FFE05E
-:108750003C0401002D3800010006C82B010548210A
-:108760000319382414E0FFDA2524FFFC2402FFFC5F
-:1087700000A218240068202103E0000800801021D6
-:108780000A000B9E240900303C0C800035860980CD
-:1087900090CB007C316A00041540FFE924060004F8
-:1087A0000A000BAD000030213C0308008C63005C24
-:1087B0008F82001827BDFFE0AFBF0018AFB10014D3
-:1087C00010620005AFB00010000329C024A402808D
-:1087D000AF840014AF8300183C10800036020A00FA
-:1087E00094450032361101000E000B7F30A43FFF8C
-:1087F0008E240000241FFF803C1100800082C021D5
-:10880000031F60243309007F000CC9400329402561
-:10881000330E0078362F00033C0D1000010D50255B
-:1088200001CF5825AE0C002836080980AE0C080C84
-:10883000AE0B082CAE0A0830910300693C06800C90
-:108840000126382110600006AF8700348D09003CF6
-:108850008D03006C0123382318E000820000000023
-:108860003C0B8008356A00803C108000A140006904
-:10887000360609808CC200383C06800034C50A00E8
-:1088800090A8003C310C00201180001AAF8200300B
-:10889000240D00013C0E800035D10A00A38D001C80
-:1088A000AF8000248E2400248F850024240D00082E
-:1088B000AF800020AF8000283C010800A42D3FC6F7
-:1088C0003C010800A4203FDA0E000B830000302199
-:1088D0009228003C8FBF00188FB100148FB0001099
-:1088E00000086142AF82002C27BD002003E0000891
-:1088F0003182000190B80032240E0001330F00FFD6
-:10890000000F2182108E004124190002109900648A
-:1089100034C40AC03C03800034640A008C8F0024F5
-:1089200015E0001E34660900909F003024180005F1
-:1089300033F9003F1338004E240300018F860020D6
-:10894000A383001CAF860028AF8600243C0E800065
-:1089500035D10A008E2400248F850024240D0008C0
-:108960003C010800A42D3FC63C010800A4203FDACA
-:108970000E000B83000000009228003C8FBF0018FF
-:108980008FB100148FB0001000086142AF82002C3C
-:1089900027BD002003E00008318200018C8A000816
-:1089A0008C8B00248CD000643C0E800035D10A00F2
-:1089B000014B2823AF900024A380001CAF85002822
-:1089C0008E2400248F8600208F850024240D00082B
-:1089D0003C010800A42D3FC63C010800A4203FDA5A
-:1089E0000E000B83000000009228003C8FBF00188F
-:1089F0008FB100148FB0001000086142AF82002CCC
-:108A000027BD002003E000083182000190A2003061
-:108A10003051003F5224002834C50AC08CB00024D5
-:108A20001600002234CB09008CA600483C0A7FFFC8
-:108A30003545FFFF00C510243C0E8000AF820020AA
-:108A400035C509008F8800208CAD0060010D602BBA
-:108A500015800002010020218CA400600A000C2275
-:108A6000AF8400208D02006C0A000BFC3C068000E5
-:108A70008C8200488F8600203C097FFF3527FFFF4E
-:108A8000004788243C04800824030001AF9100289B
-:108A9000AC80006CA383001C0A000C30AF8600245D
-:108AA0008C9F00140A000C22AF9F00208D6200688A
-:108AB0000A000C6C3C0E800034C409808C89007064
-:108AC0008CA300140123382B10E0000400000000E8
-:108AD0008C8200700A000C6C3C0E80008CA200148A
-:108AE0000A000C6C3C0E80008F85002427BDFFE03F
-:108AF000AFBF0018AFB1001414A00008AFB0001051
-:108B00003C04800034870A0090E60030240200050F
-:108B100030C3003F106200B9348409008F910020F7
-:108B200000A080213C048000348E0A008DCD00041A
-:108B30003C0608008CC63FB831A73FFF00E6602B1B
-:108B40005580000100E03021938F001C11E0007877
-:108B500000D0282B349F098093F9007C3338000221
-:108B6000130000792403003400C3102B144000D9F3
-:108B70000000000000C3302300D0282B3C01080077
-:108B8000A4233FC414A0006E020018213C04080076
-:108B90008C843FB40064402B55000001006020210C
-:108BA0003C05800034A90A00912A003C3C010800E1
-:108BB000AC243FBC31430020146000030000482176
-:108BC00034AB0E008D6900188F88002C0128202BF3
-:108BD0001080005F000000003C0508008CA53FBC31
-:108BE00000A96821010D602B1180005C00B0702B82
-:108BF0000109382300E028213C010800AC273FBCD4
-:108C000012000003240AFFFC10B0008D3224000380
-:108C100000AA18243C010800A4203FDA3C01080007
-:108C2000AC233FBC006028218F840024120400067E
-:108C30003C0B80088D6C006C02002021AF9100205D
-:108C400025900001AD70006C8F8D00280085882371
-:108C5000AF91002401A52023AF8400281220000238
-:108C600024070018240700103C18800837060080ED
-:108C700090CF00683C010800A0273FD824070001DE
-:108C800031EE00FF11C700470000000014800018FB
-:108C9000000028213C06800034D1098034CD010039
-:108CA00091A600098E2C001824C40001000C860235
-:108CB0003205007F308B007F1165007F2407FF8025
-:108CC0003C19800837290080A124004C3C0808008A
-:108CD0008D083FD4241800023C010800A038401938
-:108CE000350F00083C010800AC2F3FD424050010CC
-:108CF0003C02800034440A009083003C307F002016
-:108D000013E0000500A02021240A00013C01080016
-:108D1000AC2A3FBC34A400018FBF00188FB10014EF
-:108D20008FB000100080102103E0000827BD002054
-:108D30003C010800A4203FC410A0FF9402001821A9
-:108D40000A000CC000C018210A000CB72403003030
-:108D50003C0508008CA53FBC00B0702B11C0FFA8DB
-:108D6000000000003C19080097393FC40325C021CA
-:108D70000307782B11E000072CAA00043C036000D5
-:108D80008C625404305F003F17E0FFE3240400428C
-:108D90002CAA00041140FF9A240400420A000D246A
-:108DA0008FBF00181528FFB9000000008CCA0018FA
-:108DB0003C1F800024020002015F1825ACC300188C
-:108DC00037F90A00A0C200689329003C240400047B
-:108DD00000A01021312800203C010800A0244019E7
-:108DE0001100000224050010240200013C010800CB
-:108DF000AC223FB40A000D1A3C0280008F88002884
-:108E00008C8900600109282B14A000020100882130
-:108E10008C9100603C048000348B0E008D6400183F
-:108E2000240A00010220282102203021A38A001CEC
-:108E30000E000B83022080210A000CA6AF82002CBA
-:108E40000004582312200007316400033C0E800008
-:108E500035C7098090ED007C31AC00041580001905
-:108E6000248F00043C010800A4243FDA3C1F0800C2
-:108E700097FF3FDA03E5C82100D9C02B1300FF6B31
-:108E80008F8400242CA6000514C0FFA324040042F4
-:108E900030A200031440000200A2182324A3FFFC08
-:108EA0003C010800AC233FBC3C010800A4203FDA91
-:108EB0000A000CE70060282100C770240A000D0D8D
-:108EC00001C720263C010800A42F3FDA0A000D78D4
-:108ED000000000003C010800AC203FBC0A000D234C
-:108EE000240400428F8300283C05800034AA0A0035
-:108EF0001460000600001021914700302406000590
-:108F000030E400FF108600030000000003E00008CA
-:108F100000000000914B0048316900FF000941C288
-:108F20001500FFFA3C0680083C04080094843FC406
-:108F30003C0308008C633FDC3C1908008F393FBCC0
-:108F40003C0F080095EF3FDA0064C0218CCD00048F
-:108F50000319702101CF602134AB0E00018D28234D
-:108F600018A0001D00000000914F004C8F8C0034B1
-:108F7000956D001031EE00FF8D89000401AE3023A5
-:108F80008D8A000030CEFFFF000E29000125C82188
-:108F900000003821014720210325182B0083C02120
-:108FA000AD990004AD980000918F000A01CF6821AF
-:108FB000A18D000A956500128F8A0034A54500082E
-:108FC000954B003825690001A54900389148000DEE
-:108FD00035070008A147000D03E00008000000006D
-:108FE00027BDFFD8AFB000189388001C8FB00014C5
-:108FF0003C0A80003C197FFF8F8700243738FFFF31
-:10900000AFBF0020AFB1001C355F0A000218182462
-:1090100093EB003C00087FC03C02BFFF006F60255F
-:109020002CF000013449FFFF3C1F08008FFF3FDC9C
-:109030008F9900303C18080097183FD20189782496
-:10904000001047803C07EFFF3C05F0FF01E81825C2
-:109050003C1180003169002034E2FFFF34ADFFFF96
-:10906000362E098027A500102406000203F960238C
-:10907000270B0002354A0E00006218240080802170
-:1090800015200002000040218D48001CA7AB0012F3
-:10909000058000392407000030E800FF00083F0089
-:1090A000006758253C028008AFAB0014344F0080A5
-:1090B00091EA00683C08080091083FD93C09DFFFAD
-:1090C000352CFFFF000AF82B3C02080094423FCCED
-:1090D000A3A80011016CC024001FCF40031918255C
-:1090E0008FA70010AFA300143C0C0800918C3FDB4D
-:1090F000A7A200168FAB001400ED48243C0F01001E
-:109100003C0A0FFF012FC82531980003355FFFFF90
-:10911000016D40243C027000033F382400181E00FB
-:1091200000E2482501037825AFAF0014AFA9001075
-:1091300091CC007C0E000092A3AC0015362D0A00E5
-:1091400091A6003C30C400201080000626020008D2
-:109150003C11080096313FC8262EFFFF3C01080055
-:10916000A42E3FC88FBF00208FB1001C8FB0001805
-:1091700003E0000827BD00288F8B002C010B502B2B
-:109180005540FFC5240700010A000E0430E800FF27
-:109190009383001C3C02800027BDFFD834480A009E
-:1091A00000805021AFBF002034460AC001002821B2
-:1091B0001060000E3444098091070030240B000534
-:1091C0008F89002030EC003F118B000B000038210C
-:1091D000AFA900103C0B80088D69006CAFAA001885
-:1091E0000E00015AAFA90014A380001C8FBF0020FD
-:1091F00003E0000827BD00288D1F00483C18080028
-:109200008F183FBC8F9900283C027FFF8D080044D7
-:109210003443FFFFAFA900103C0B80088D69006C40
-:1092200003E370240319782101CF682301A83821B2
-:10923000AFAA00180E00015AAFA900140A000E5878
-:10924000A380001C3C05800034A60A0090C7003CA7
-:109250003C06080094C63FDA3C0208008C423FD42A
-:1092600030E30020000624001060001E0044382572
-:109270003C0880083505008090A300680000482164
-:109280002408000100002821240400013C0680007D
-:109290008CCD017805A0FFFE34CF0140ADE8000879
-:1092A0003C0208008C423FDCA5E50004A5E4000672
-:1092B000ADE2000C3C04080090843FD93C038008D8
-:1092C00034790080A1E40012ADE70014A5E900188C
-:1092D0009338004C3C0E1000A1F8002D03E000086C
-:1092E000ACCE017834A90E008D28001C3C0C08007F
-:1092F0008D8C3FBC952B0016952A001401864821C1
-:109300003164FFFF0A000E803145FFFF3C048000FE
-:1093100034830A009065003C30A200201040001900
-:1093200034870E0000004021000038210000202179
-:109330003C0680008CC901780520FFFE34CA01403C
-:1093400034CF010091EB0009AD4800083C0E080045
-:109350008DCE3FDC240DFF91240C00403C08100012
-:10936000A5440004A5470006AD4E000CA14D001217
-:10937000AD4C0014A5400018A14B002D03E00008DF
-:10938000ACC801788CE8001894E6001294E4001050
-:1093900030C7FFFF0A000EA93084FFFF3C048000A5
-:1093A00034830A009065003C30A200201040002762
-:1093B00027BDFFF82409000100003821240800011E
-:1093C0003C0680008CCA01780540FFFE3C0280FF0D
-:1093D00034C40100908D00093C0C0800918C4019A8
-:1093E000A3AD00038FAB00003185007F3459FFFF30
-:1093F00001665025AFAA00009083000AA3A00002D6
-:1094000000057E00A3A300018FB8000034CB01400B
-:10941000240C30000319702401CF6825AD6D000CB9
-:1094200027BD0008AD6C0014A5600018AD690008E8
-:10943000A56700042409FF80A56800063C08100009
-:10944000A169001203E00008ACC8017834870E005F
-:109450008CE9001894E6001294E4001030C8FFFF75
-:109460000A000ECD3087FFFF27BDFFE0AFB100142B
-:109470003C118000AFB00010AFBF001836380A00B2
-:10948000970F0032363001000E000B7F31E43FFFB2
-:109490008E0E0000240DFF803C04200001C25821E4
-:1094A000016D6024000C4940316A007F012A40258B
-:1094B000010438253C048008AE270830348600803B
-:1094C00090C500682403000230A200FF104300048E
-:1094D0008F9F00208F990024AC9F0068AC99006496
-:1094E0008FBF00188FB100148FB0001003E0000888
-:1094F00027BD00203C0A0800254A3A803C090800A4
-:1095000025293B103C08080025082F1C3C070800B3
-:1095100024E73BDC3C06080024C639043C0508006F
-:1095200024A536583C0408002484325C3C0308001F
-:10953000246339B83C020800244237543C01080037
-:10954000AC2A3F983C010800AC293F943C0108003C
-:10955000AC283F903C010800AC273F9C3C01080030
-:10956000AC263FAC3C010800AC253FA43C01080000
-:10957000AC243FA03C010800AC233FB03C010800F4
-:0C958000AC223FA803E00008000000003F
-:04958C008000094012
-:109590008000090080080100800800808008000029
-:1095A000800E0000800800808008000080000A8093
-:0C95B00080000A00800009808000090093
-:00000001FF
-/*
- * This file contains firmware data derived from proprietary unpublished
- * source code, Copyright (c) 2004 - 2009 Broadcom Corporation.
- *
- * Permission is hereby granted for the distribution of this firmware data
- * in hexadecimal or equivalent format, provided this copyright notice is
- * accompanying it.
- */
--- /dev/null
+++ zfcpdump-kernel-4.4/firmware/bnx2/bnx2-mips-09-6.2.1b.fw.ihex
@@ -0,0 +1,6496 @@
+:10000000080001180800000000005594000000C816
+:1000100000000000000000000000000008005594EF
+:10002000000000380000565C080000A00800000036
+:100030000000574400005694080059200000008436
+:100040000000ADD808005744000001C00000AE5CBD
+:100050000800321008000000000092580000B01C98
+:10006000000000000000000000000000080092589E
+:100070000000033C000142740800049008000400E2
+:10008000000012FC000145B000000000000000006C
+:1000900000000000080016FC00000004000158AC3D
+:1000A000080000A80800000000003D00000158B052
+:1000B00000000000000000000000000008003D00FB
+:1000C00000000030000195B00A000046000000006A
+:1000D000000000000000000D636F6D362E322E31DF
+:1000E00062000000060201020000000000000003A0
+:1000F000000000C800000032000000030000000003
+:1001000000000000000000000000000000000000EF
+:1001100000000010000001360000EA600000000549
+:1001200000000000000000000000000000000008C7
+:1001300000000000000000000000000000000000BF
+:1001400000000000000000000000000000000000AF
+:10015000000000000000000000000000000000009F
+:10016000000000020000000000000000000000008D
+:10017000000000000000000000000000000000007F
+:10018000000000000000000000000010000000005F
+:10019000000000000000000000000000000000005F
+:1001A000000000000000000000000000000000004F
+:1001B000000000000000000000000000000000003F
+:1001C000000000000000000000000000000000002F
+:1001D000000000000000000000000000000000001F
+:1001E0000000000010000003000000000000000DEF
+:1001F0000000000D3C020800244256083C030800A1
+:1002000024635754AC4000000043202B1480FFFDB2
+:10021000244200043C1D080037BD9FFC03A0F021D0
+:100220003C100800261001183C1C0800279C5608AA
+:100230000E000256000000000000000D27BDFFB4B4
+:10024000AFA10000AFA20004AFA30008AFA4000C50
+:10025000AFA50010AFA60014AFA70018AFA8001CF0
+:10026000AFA90020AFAA0024AFAB0028AFAC002C90
+:10027000AFAD0030AFAE0034AFAF0038AFB8003C28
+:10028000AFB90040AFBC0044AFBF00480E001544FA
+:10029000000000008FBF00488FBC00448FB90040B1
+:1002A0008FB8003C8FAF00388FAE00348FAD003078
+:1002B0008FAC002C8FAB00288FAA00248FA90020C0
+:1002C0008FA8001C8FA700188FA600148FA5001000
+:1002D0008FA4000C8FA300088FA200048FA1000040
+:1002E00027BD004C3C1B60108F7A5030377B502864
+:1002F00003400008AF7A00008F82002427BDFFE092
+:10030000AFB00010AFBF0018AFB100148C42000CAA
+:100310003C1080008E110100104000348FBF001887
+:100320000E000D84000000008F85002024047FFF54
+:100330000091202BACB100008E030104960201084D
+:1003400000031C003042FFFF00621825ACA300042C
+:100350009202010A96030114304200FF3063FFFF4E
+:100360000002140000431025ACA200089603010C03
+:100370009602010E00031C003042FFFF00621825A8
+:10038000ACA3000C960301109602011200031C009E
+:100390003042FFFF00621825ACA300108E02011846
+:1003A000ACA200148E02011CACA20018148000083C
+:1003B0008F820024978200003C0420050044182509
+:1003C00024420001ACA3001C0A0000C6A782000062
+:1003D0003C0340189442001E00431025ACA2001CB0
+:1003E0000E000DB8240400018FBF00188FB1001457
+:1003F0008FB000100000102103E0000827BD00208E
+:100400003C0780008CE202B834E50100044100089A
+:10041000240300013C0208008C42006024420001D9
+:100420003C010800AC22006003E0000800601021DD
+:100430003C0208008C42005C8CA4002094A30016AF
+:100440008CA6000494A5000E24420001ACE40280B6
+:100450002463FFFC3C010800AC22005C3C0210005D
+:10046000A4E30284A4E5028600001821ACE6028819
+:10047000ACE202B803E000080060102127BDFFE0F5
+:100480003C028000AFB0001034420100AFBF001C3E
+:10049000AFB20018AFB100148C43000094450008BF
+:1004A0002462FE002C42038110400003000381C23D
+:1004B0000A00010226100004240201001462000553
+:1004C0003C1180003C02800890420004305000FF44
+:1004D0003C11800036320100964300143202000FB6
+:1004E00000021500004310253C0308008C63004403
+:1004F00030A40004AE220080246300013C01080007
+:10050000AC2300441080000730A200028FBF001C03
+:100510008FB200188FB100148FB000100A0000CE07
+:1005200027BD00201040002D0000182130A20080BF
+:1005300010400005362200708E44001C0E000C672F
+:10054000240500A0362200708C4400008F82000C2D
+:10055000008210232C43012C10600004AF82001095
+:10056000240300010A000145AF84000C8E42000400
+:100570003C036020AF84000CAC6200143C02080015
+:100580008C42005850400015000018218C62000475
+:10059000240301FE304203FF144300100000182121
+:1005A0002E020004104000032E0200080A00014041
+:1005B0000000802114400003000000000A000140F8
+:1005C0002610FFF90000000D2402000202021004B0
+:1005D0003C036000AC626914000018218FBF001C4E
+:1005E0008FB200188FB100148FB00010006010217E
+:1005F00003E0000827BD00203C0480008C8301003C
+:1006000024020100506200033C0280080000000D3B
+:100610003C02800890430004000010213063000F6A
+:1006200000031D0003E00008AC8300800004188074
+:100630002782FF9C00621821000410C00044102390
+:100640008C640000000210C03C030800246356E4E0
+:10065000004310213C038000AC64009003E00008DC
+:10066000AF8200243C0208008C42011410400019A3
+:100670003084400030A2007F000231C03C02020002
+:100680001080001400A218253C026020AC43001426
+:100690003C0408008C8456B83C0308008C630110AD
+:1006A0003C02800024050900AC4500200086202182
+:1006B000246300013C028008AC4400643C01080053
+:1006C000AC2301103C010800AC2456B803E000083C
+:1006D000000000003C02602003E00008AC4500146C
+:1006E00003E000080000102103E0000800001021D2
+:1006F00030A2000810400008240201003C0208005B
+:100700008C42010C244200013C010800AC22010C87
+:1007100003E0000800000000148200080000000050
+:100720003C0208008C4200FC244200013C0108000D
+:10073000AC2200FC0A0001A330A200203C02080009
+:100740008C420084244200013C010800AC22008459
+:1007500030A200201040000830A200103C02080027
+:100760008C420108244200013C010800AC2201082F
+:1007700003E0000800000000104000080000000036
+:100780003C0208008C420104244200013C010800A4
+:10079000AC22010403E00008000000003C02080055
+:1007A0008C420100244200013C010800AC220100FF
+:1007B00003E000080000000027BDFFE0AFB1001417
+:1007C0003C118000AFB20018AFBF001CAFB00010EA
+:1007D0003632010096500008320200041040000733
+:1007E000320300028FBF001C8FB200188FB10014BB
+:1007F0008FB000100A0000CE27BD00201060000B53
+:10080000020028218E2401000E00018A0000000051
+:100810003202008010400003240500A10E000C6786
+:100820008E44001C0A0001E3240200018E2301040F
+:100830008F82000810430006020028218E24010048
+:100840000E00018A000000008E220104AF82000821
+:10085000000010218FBF001C8FB200188FB1001450
+:100860008FB0001003E0000827BD00202C82000498
+:1008700014400002000018212483FFFD240200021E
+:10088000006210043C03600003E00008AC626914DD
+:1008900027BDFFE0AFBF001CAFB20018AFB100141E
+:1008A000AFB000103C048000948201083043700017
+:1008B000240220001062000A2862200154400052E5
+:1008C0008FBF001C24024000106200482402600018
+:1008D0001062004A8FBF001C0A0002518FB200183C
+:1008E00034820100904300098C5000189451000C90
+:1008F000240200091062001C0000902128620009F7
+:10090000144000218F8200242402000A5062001249
+:10091000323100FF2402000B1062000F00000000C3
+:100920002402000C146200188F8200243C0208008C
+:100930008C4256B824030900AC83002000501021DB
+:100940003C038008AC6200643C010800AC2256B84D
+:100950000A0002508FBF001C0E0001E900102602A1
+:100960000A0002308F8200240E0001E900102602E6
+:100970003C0380089462001A8C72000C3042FFFF26
+:10098000020280258F8200248C42000C5040001E01
+:100990008FBF001C0E000D84000000003C02800090
+:1009A00034420100944300088F82002400031C009D
+:1009B0009444001E8F82002000641825AC50000073
+:1009C00024040001AC510004AC520008AC40000CFF
+:1009D000AC400010AC400014AC4000180E000DB844
+:1009E000AC43001C0A0002508FBF001C0E000440E4
+:1009F000000000000A0002508FBF001C0E000C9F78
+:100A0000000000008FBF001C8FB200188FB10014CF
+:100A10008FB000100000102103E0000827BD002067
+:100A200027BDFFD8AFB400203C036010AFBF002447
+:100A3000AFB3001CAFB20018AFB10014AFB00010DC
+:100A40008C6450002402FF7F3C1408002694563822
+:100A5000008220243484380CAC6450003C028000B6
+:100A6000240300370E0014B0AC4300083C07080014
+:100A700024E70618028010212404001D2484FFFFAF
+:100A8000AC4700000481FFFD244200043C02080042
+:100A9000244207C83C010800AC2256403C02080032
+:100AA000244202303C030800246306203C04080072
+:100AB000248403B43C05080024A506F03C06080085
+:100AC00024C62C9C3C010800AC2256803C02080045
+:100AD000244205303C010800AC2756843C01080044
+:100AE000AC2656943C010800AC23569C3C010800FF
+:100AF000AC2456A03C010800AC2556A43C010800DB
+:100B0000AC2256A83C010800AC23563C3C0108002E
+:100B1000AC2456443C010800AC2056603C0108005F
+:100B2000AC2556643C010800AC2056703C0108001E
+:100B3000AC27567C3C010800AC2656903C010800CE
+:100B4000AC2356980E00056E00000000AF80000C2C
+:100B50003C0280008C5300008F8300043C0208009C
+:100B60008C420020106200213262000700008821C0
+:100B70002792FF9C3C100800261056E43C02080017
+:100B80008C42002024050001022518040043202483
+:100B90008F820004004310245044000C26310001D1
+:100BA00010800008AF9000248E4300003C028000BB
+:100BB000AC4300900E000D4BAE05000C0A0002C1C4
+:100BC00026310001AE00000C263100012E22000269
+:100BD000261000381440FFE9265200043C020800A9
+:100BE0008C420020AF820004326200071040FFD91F
+:100BF0003C028000326200011040002D326200028F
+:100C00003C0580008CA2010000002021ACA2002045
+:100C10008CA301042C42078110400008ACA300A85B
+:100C200094A2010824032000304270001443000302
+:100C30003C02800890420005304400FF0E0001593C
+:100C4000000000003C0280009042010B304300FF96
+:100C50002C62001E54400004000310800E00018628
+:100C60000A0002EC00000000005410218C42000039
+:100C70000040F80900000000104000043C02800021
+:100C80008C4301043C026020AC4300143C02080089
+:100C90008C4200343C0440003C03800024420001AC
+:100CA000AC6401383C010800AC220034326200021E
+:100CB00010400010326200043C1080008E0201409F
+:100CC000000020210E000159AE0200200E00038317
+:100CD000000000003C024000AE0201783C02080027
+:100CE0008C420038244200013C010800AC2200384C
+:100CF000326200041040FF973C0280003C108000EC
+:100D00008E020180000020210E000159AE02002059
+:100D10008E03018024020F00546200073C02800809
+:100D20008E0201883C0300E03042FFFF00431025A3
+:100D30000A000328AE020080344200809042000086
+:100D400024030050304200FF14430007000000005D
+:100D50000E000362000000001440000300000000C9
+:100D60000E000971000000003C0208008C42003CAB
+:100D70003C0440003C03800024420001AC6401B804
+:100D80003C010800AC22003C0A0002A33C028000A7
+:100D90003C02900034420001008220253C02800089
+:100DA000AC4400203C0380008C6200200440FFFE25
+:100DB0000000000003E00008000000003C0280008A
+:100DC000344300010083202503E00008AC440020E8
+:100DD00027BDFFE0AFB10014AFB000100080882144
+:100DE000AFBF00180E00033230B000FF8F83FF94B6
+:100DF000022020219062002502028025A07000259B
+:100E00008C7000183C0280000E00033D020280241A
+:100E10001600000B8FBF00183C0480008C8201F884
+:100E20000440FFFE348201C024030002AC510000E4
+:100E3000A04300043C021000AC8201F88FBF0018F0
+:100E40008FB100148FB0001003E0000827BD002010
+:100E500027BDFFE83C028000AFBF00103442018094
+:100E6000944300048C4400083063020010600005C5
+:100E7000000028210E00100C000000000A0003787A
+:100E8000240500013C02FF000480000700821824B2
+:100E90003C02040014620004240500018F82FF94C8
+:100EA00090420008240500018FBF001000A010210F
+:100EB00003E0000827BD00188F82FF982405000179
+:100EC000A040001A3C028000344201400A00034264
+:100ED0008C4400008F85FF9427BDFFE0AFBF001C4E
+:100EE000AFB20018AFB10014AFB0001090A2000074
+:100EF000304400FF38830020388200300003182B74
+:100F00000002102B0062182410600003240200501D
+:100F1000148200A88FBF001C90A20005304200017F
+:100F2000104000A48FBF001C3C02800034420140EE
+:100F3000904200082443FFFF2C6200051040009EF1
+:100F40008FB20018000310803C030800246355ACE6
+:100F5000004310218C420000004000080000000007
+:100F60003C028000345101400E0003328E24000008
+:100F70008F92FF948E2200048E50000C1602000205
+:100F800024020001AE42000C0E00033D8E2400003E
+:100F90008E220004145000068FBF001C8FB2001870
+:100FA0008FB100148FB000100A000F7827BD002009
+:100FB0008E42000C0A000419000000003C0480006E
+:100FC0003482014094A300108C4200043063FFFF80
+:100FD0001443001C0000000024020001A4A2001021
+:100FE0008C8202380441000F3C0380003C02003F29
+:100FF0003448F0003C0760003C06FFC08CE22BBC8C
+:1010000000461824004810240002130200031D8229
+:10101000106200583C0280008C8202380440FFF7C6
+:101020003C038000346201408C44000034620200C2
+:10103000AC4400003C021000AC6202380A00043BE1
+:101040008FBF001C94A200100A00041900000000C9
+:10105000240200201482000F3C0280003C03800028
+:1010600094A20012346301408C6300043042FFFFFD
+:10107000146200050000000024020001A4A2001276
+:101080000A0004028FBF001C94A200120A00041977
+:1010900000000000345101400E0003328E24000095
+:1010A0008F92FF948E230004964200123050FFFF6F
+:1010B0001603000224020001A64200120E00033DA6
+:1010C0008E2400008E220004160200068FBF001C32
+:1010D0008FB200188FB100148FB000100A00037C8B
+:1010E00027BD0020964200120A00041900000000EB
+:1010F0003C03800094A20014346301408C6300041C
+:101100003042FFFF14620008240200018FBF001C60
+:101110008FB200188FB100148FB00010A4A2001479
+:101120000A00146327BD002094A20014144000217B
+:101130008FBF001C0A000435000000003C03800043
+:1011400094A20016346301408C6300043042FFFF18
+:101150001462000D240200018FBF001C8FB2001822
+:101160008FB100148FB00010A4A200160A000B1457
+:1011700027BD00209442007824420004A4A200105D
+:101180000A00043B8FBF001C94A200162403000138
+:101190003042FFFF144300078FBF001C3C020800D1
+:1011A0008C420070244200013C010800AC22007017
+:1011B0008FBF001C8FB200188FB100148FB00010C9
+:1011C00003E0000827BD002027BDFFD8AFB20018FC
+:1011D0008F92FF94AFB10014AFBF0020AFB3001CDB
+:1011E000AFB000103C028000345101008C5001006F
+:1011F0009242000092230009304400FF2402001FA5
+:10120000106200AB28620020104000192402003850
+:101210002862000A1040000D2402000B286200081A
+:101220001040002E8F820024046001042862000216
+:101230001440002A8F820024240200061062002637
+:101240008FBF00200A00055F8FB3001C1062006092
+:101250002862000B144000FA8FBF00202402000E09
+:10126000106200788F8200240A00055F8FB3001C93
+:10127000106200D2286200391040000A2402008067
+:1012800024020036106200E528620037104000C3D7
+:1012900024020035106200D98FBF00200A00055FCC
+:1012A0008FB3001C1062002D2862008110400006E0
+:1012B000240200C824020039106200C98FBF002038
+:1012C0000A00055F8FB3001C106200A28FBF0020D0
+:1012D0000A00055F8FB3001C8F8200248C42000C33
+:1012E000104000D78FBF00200E000D8400000000CA
+:1012F0003C038000346301008C6200008F85002075
+:10130000946700089466000CACA200008C64000492
+:101310008F82002400063400ACA400049448001E10
+:101320008C62001800073C0000E83825ACA20008D9
+:101330008C62001C24040001ACA2000C9062000A24
+:1013400000C23025ACA60010ACA00014ACA0001860
+:10135000ACA7001C0A00051D8FBF00208F8200244F
+:101360008C42000C104000B68FBF00200E000D8490
+:10137000000000008F820024962400089625000CAF
+:101380009443001E000422029626000E8F82002045
+:10139000000426000083202500052C003C0300806B
+:1013A00000A6282500832025AC400000AC400004A6
+:1013B000AC400008AC40000CAC450010AC40001440
+:1013C000AC400018AC44001C0A00051C24040001B9
+:1013D0009622000C14400018000000009242000504
+:1013E0003042001014400014000000000E000332D0
+:1013F0000200202192420005020020213442001008
+:101400000E00033DA242000592420000240300208A
+:10141000304200FF10430089020020218FBF0020CE
+:101420008FB3001C8FB200188FB100148FB0001062
+:101430000A00107527BD00280000000D0A00055E97
+:101440008FBF00208C42000C1040007D8FBF002019
+:101450000E000D84000000008E2200048F84002006
+:101460009623000CAC8200003C0280089445002CBE
+:101470008F82002400031C0030A5FFFF9446001E4D
+:101480003C02400E0065182500C23025AC830004E4
+:10149000AC800008AC80000CAC800010AC80001464
+:1014A000AC800018AC86001C0A00051C2404000156
+:1014B0000E000332020020218F93FF9802002021AA
+:1014C0000E00033DA660000C020020210E00034226
+:1014D000240500018F8200248C42000C104000582B
+:1014E0008FBF00200E000D84000000009622000C2B
+:1014F0008F83002000021400AC700000AC62000476
+:10150000AC6000088E4400388F820024AC64000C6C
+:101510008E46003C9445001E3C02401FAC66001005
+:1015200000A228258E62000424040001AC6200148D
+:10153000AC600018AC65001C8FBF00208FB3001C8E
+:101540008FB200188FB100148FB000100A000DB8D0
+:1015500027BD0028240200201082003A8FB3001C0F
+:101560000E000F5E00000000104000358FBF00200D
+:101570003C0480008C8201F80440FFFE348201C0EC
+:1015800024030002AC500000A04300043C02100001
+:10159000AC8201F80A00055E8FBF00200200202106
+:1015A0008FBF00208FB3001C8FB200188FB10014C2
+:1015B0008FB000100A000EA727BD00289625000C4A
+:1015C000020020218FBF00208FB3001C8FB20018B3
+:1015D0008FB100148FB000100A000ECC27BD002878
+:1015E000020020218FB3001C8FB200188FB10014AD
+:1015F0008FB000100A000EF727BD00289225000DBD
+:10160000020020218FB3001C8FB200188FB100148C
+:101610008FB000100A000F4827BD002802002021CB
+:101620008FBF00208FB3001C8FB200188FB1001441
+:101630008FB000100A000F1F27BD00288FBF0020A9
+:101640008FB3001C8FB200188FB100148FB0001040
+:1016500003E0000827BD00283C0580008CA202782A
+:101660000440FFFE34A2024024030002AC44000008
+:10167000A04300043C02100003E00008ACA2027882
+:10168000A380001803E00008A38000193C03800039
+:101690008C6202780440FFFE8F82001CAC62024024
+:1016A00024020002A06202443C02100003E0000891
+:1016B000AC6202783C02600003E000088C425404F3
+:1016C0009083003024020005008040213063003FF9
+:1016D0000000482114620005000050219082004C57
+:1016E0009483004E304900FF306AFFFFAD00000CCC
+:1016F000AD000010AD000024950200148D05001C03
+:101700008D0400183042FFFF004910230002110031
+:10171000000237C3004038210086202300A2102B8E
+:101720000082202300A72823AD05001CAD0400186B
+:10173000A5090014A5090020A50A001603E0000869
+:10174000A50A002203E000080000000027BDFFD822
+:10175000AFB200183C128008AFB40020AFB3001C39
+:10176000AFB10014AFBF0024AFB00010365101007C
+:101770003C0260008C4254049222000C3C1408008D
+:10178000929400F7304300FF2402000110620032FF
+:101790000080982124020002146200353650008037
+:1017A0000E00143D000000009202004C2403FF8054
+:1017B0003C0480003042007F000211C024420240FD
+:1017C0000262102100431824AC8300949245000863
+:1017D0009204004C3042007F3C03800614850007D1
+:1017E000004380212402FFFFA22200112402FFFFF8
+:1017F000A62200120A0005D22402FFFF9602002052
+:10180000A222001196020022A62200128E020024BB
+:101810003C048008AE2200143485008090A2004C65
+:1018200034830100A06200108CA2003CAC6200185E
+:101830008C820068AC6200F48C820064AC6200F0C0
+:101840008C82006CAC6200F824020001A0A2006847
+:101850000A0005EE3C0480080E001456000000004B
+:1018600036420080A04000680A0005EE3C04800873
+:10187000A2000068A20000690A0006293C02800854
+:10188000348300808C62003834850100AC62006CC7
+:1018900024020001A062006990A200D59083000894
+:1018A000305100FF3072007F12320019001111C058
+:1018B00024420240026210212403FF8000431824C6
+:1018C0003C048000AC8300943042007F3C038006DF
+:1018D000004380218E02000C1040000D02002021E8
+:1018E0000E00057E0000000026220001305100FF9E
+:1018F0009203003C023410260002102B0002102339
+:101900003063007F022288240A0005F8A203003C0D
+:101910003C088008350401008C8200E03507008017
+:10192000ACE2003C8C8200E0AD02000090E5004C8F
+:10193000908600D590E3004C908400D52402FF806F
+:1019400000A228243063007F308400FF00A62825F1
+:101950000064182A1060000230A500FF38A500803E
+:10196000A0E5004CA10500093C0280089043000E50
+:10197000344400803C058000A043000A8C8300189A
+:101980003C027FFF3442FFFF00621824AC83001842
+:101990008CA201F80440FFFE00000000ACB301C0BF
+:1019A0008FBF00248FB400208FB3001C8FB20018AB
+:1019B0008FB100148FB0001024020002A0A201C455
+:1019C00027BD00283C02100003E00008ACA201F88B
+:1019D00090A2000024420001A0A200003C030800E5
+:1019E0008C6300F4304200FF144300020080302179
+:1019F000A0A0000090A200008F84001C000211C073
+:101A00002442024024830040008220212402FF80DF
+:101A1000008220243063007F3C02800A006218218B
+:101A20003C028000AC44002403E00008ACC300008A
+:101A300094820006908300058C85000C8C86001033
+:101A40008C8700188C88001C8C8400203C010800C6
+:101A5000A42256C63C010800A02356C53C0108003C
+:101A6000AC2556CC3C010800AC2656D03C01080001
+:101A7000AC2756D83C010800AC2856DC3C010800D5
+:101A8000AC2456E003E00008000000003C0280089F
+:101A9000344201008C4400343C038000346504006F
+:101AA000AC6400388C420038AF850028AC62003C42
+:101AB0003C020005AC6200300000000000000000A5
+:101AC00003E00008000000003C020006308400FF34
+:101AD000008220253C028000AC4400300000000061
+:101AE00000000000000000003C0380008C62000049
+:101AF000304200101040FFFD3462040003E0000893
+:101B0000AF82002894C200003C080800950800CA73
+:101B100030E7FFFF0080482101021021A4C200002D
+:101B200094C200003042FFFF00E2102B544000013D
+:101B3000A4C7000094A200003C0308008C6300CC02
+:101B400024420001A4A2000094A200003042FFFF42
+:101B5000144300073C0280080107102BA4A00000DA
+:101B60005440000101003821A4C700003C02800855
+:101B7000344601008CC3002894A200003C0480007D
+:101B80003042FFFE000210C000621021AC82003C17
+:101B90008C82003C006218231860000400000000E2
+:101BA0008CC200240A0006BA244200018CC2002420
+:101BB000AC8200383C020050344200103C038000EC
+:101BC000AC620030000000000000000000000000D7
+:101BD0008C620000304200201040FFFD0000000039
+:101BE00094A200003C04800030420001000210C0BA
+:101BF000004410218C430400AD2300008C420404F7
+:101C0000AD2200043C02002003E00008AC8200305A
+:101C100027BDFFE0AFB20018AFB10014AFB00010A5
+:101C2000AFBF001C94C2000000C080213C1208001D
+:101C3000965200C624420001A6020000960300004E
+:101C400094E2000000E03021144300058FB1003021
+:101C50000E00068F024038210A0006F10000000045
+:101C60008C8300048C82000424420040046100073D
+:101C7000AC8200048C8200040440000400000000D8
+:101C80008C82000024420001AC8200009602000019
+:101C90003042FFFF50520001A600000096220000D3
+:101CA00024420001A62200003C02800834420100C8
+:101CB000962300009442003C144300048FBF001C94
+:101CC00024020001A62200008FBF001C8FB2001862
+:101CD0008FB100148FB0001003E0000827BD002072
+:101CE00027BDFFE03C028008AFBF0018344201006E
+:101CF0008C4800343C03800034690400AC68003830
+:101D00008C42003830E700FFAF890028AC62003C0D
+:101D10003C020005AC620030000000000000000042
+:101D200000000000000000000000000000000000B3
+:101D30008C82000C8C82000C97830016AD22000070
+:101D40008C82001000604021AD2200048C820018BB
+:101D5000AD2200088C82001CAD22000C8CA2001465
+:101D6000AD2200108C820020AD220014908200056C
+:101D7000304200FF00021200AD2200188CA20018B1
+:101D8000AD22001C8CA2000CAD2200208CA2001001
+:101D9000AD2200248CA2001CAD2200288CA20020C1
+:101DA000AD22002C3402FFFFAD260030AD20003400
+:101DB000506200013408FFFFAD28003850E00011E8
+:101DC0003C0280083C048008348401009482005066
+:101DD0003042FFFFAD22003C9483004494850044D0
+:101DE000240200013063FFFF000318C200641821C1
+:101DF0009064006430A5000700A210040A00075C8C
+:101E00000044102534420100AD20003C94430044BE
+:101E1000944400443063FFFF000318C2006218219D
+:101E200030840007906500642402000100821004E1
+:101E30000002102700451024A0620064000000008A
+:101E400000000000000000003C0200063442004098
+:101E50003C038000AC620030000000000000000085
+:101E6000000000008C620000304200101040FFFDB6
+:101E70003C06800834C201503463040034C7014A70
+:101E800034C4013434C5014034C60144AFA200104B
+:101E90000E0006D2AF8300288FBF001803E00008B1
+:101EA00027BD00208F8300143C0608008CC600E884
+:101EB0008F82001C30633FFF000319800046102111
+:101EC000004310212403FF80004318243C068000B7
+:101ED000ACC300283042007F3C03800C004330211B
+:101EE00090C2000D30A500FF0000382134420010E0
+:101EF000A0C2000D8F8900143C028008344201000A
+:101F00009443004400091382304800032402000176
+:101F1000A4C3000E1102000B2902000210400005AC
+:101F2000240200021100000C240300010A0007A48F
+:101F30000000182111020006000000000A0007A49A
+:101F4000000018218CC2002C0A0007A424430001C1
+:101F50008CC20014244300018CC200180043102BD3
+:101F60005040000A240700012402002714A20003A5
+:101F70003C0380080A0007B1240700013463010014
+:101F80009462004C24420001A462004C00091382B8
+:101F9000304300032C620002104000090080282119
+:101FA000146000040000000094C200340A0007C15D
+:101FB0003046FFFF8CC600380A0007C10080282188
+:101FC000000030213C040800248456C00A000706A3
+:101FD0000000000027BDFF90AFB60068AFB50064F9
+:101FE000AFB40060AFB3005CAFB20058AFB1005403
+:101FF000AFBF006CAFB000508C9000000080B021EB
+:102000003C0208008C4200E8960400328F83001CDA
+:102010002414FF8030843FFF0062182100042180D7
+:1020200000641821007410243C13800000A090214B
+:1020300090A50000AE620028920400323C02800CA1
+:102040003063007F00628821308400C02402004099
+:10205000148200320000A8218E3500388E2200182C
+:102060001440000224020001AE2200189202003C3B
+:10207000304200201440000E8F83001C000511C068
+:102080002442024000621821306400783C02008043
+:102090000082202500741824AE630800AE64081086
+:1020A0008E2200188E03000800431021AE22001873
+:1020B0008E22002C8E230018244200010062182B6F
+:1020C0001060004300000000924200002442000122
+:1020D000A24200003C0308008C6300F4304200FF81
+:1020E00050430001A2400000924200008F84001C77
+:1020F000000211C024420240248300403063007F6C
+:10210000008220213C02800A0094202400621821D1
+:10211000AE6400240A0008D2AEC30000920300326D
+:102120002402FFC000431024304200FF1440000589
+:1021300024020001AE220018962200340A00084250
+:102140003055FFFF8E22001424420001AE220018F9
+:102150009202003000021600000216030441001C27
+:10216000000000009602003227A400100080282101
+:10217000A7A20016960200320000302124070001B9
+:102180003042FFFFAF8200140E000706AFA0001C14
+:10219000960200328F83001C3C0408008C8400E807
+:1021A00030423FFF000211800064182100621821B4
+:1021B00000741024AE62002C3063007F3C02800E5D
+:1021C000006218219062000D3042007FA062000D75
+:1021D0009222000D304200105040007892420000E0
+:1021E0003C028008344401009482004C8EC30000FD
+:1021F0003C130800967300C62442FFFFA482004CE3
+:10220000946200329623000E3054FFFF3070FFFFBF
+:102210003C0308008C6300D000701807A7A30038A7
+:102220009482003E3063FFFF3042FFFF14620007DC
+:10223000000000008C8200303C038000244200300B
+:10224000AC62003C0A00086A8C82002C9482004038
+:102250003042FFFF5462000927A400408C820038FE
+:102260003C03800024420030AC62003C8C8200348D
+:10227000AC6200380A0008793C03800027A50038CA
+:1022800027A60048026038210E00068FA7A000484C
+:102290008FA300403C02800024630030AC43003830
+:1022A0008FA30044AC43003C3C0380003C0200058B
+:1022B000AC6200303C028008344401009482004249
+:1022C000346304003042FFFF0202102B1440000769
+:1022D000AF8300289482004E9483004202021021B2
+:1022E000004310230A00088F3043FFFF9483004E01
+:1022F00094820042026318210050102300621823C8
+:102300003063FFFF3C028008344401009482003CAB
+:102310003042FFFF14430003000000000A00089F42
+:10232000240300019482003C3042FFFF0062102B26
+:10233000144000058F8200289482003C0062102324
+:102340003043FFFF8F820028AC550000AC400004F2
+:10235000AC540008AC43000C3C02000634420010B0
+:102360003C038000AC620030000000000000000070
+:10237000000000008C620000304200101040FFFDA1
+:102380003C04800834840100001018C20064182145
+:102390009065006432020007240600010046100424
+:1023A00000451025A0620064948300429622000E2E
+:1023B00050430001A386001892420000244200010D
+:1023C000A24200003C0308008C6300F4304200FF8E
+:1023D00050430001A2400000924200008F84001C84
+:1023E000000211C0244202402483004000822021C8
+:1023F0002402FF80008220243063007F3C02800A98
+:10240000006218213C028000AC440024AEC30000EE
+:102410008FBF006C8FB600688FB500648FB400600A
+:102420008FB3005C8FB200588FB100548FB0005052
+:1024300003E0000827BD007027BDFFD8AFB3001C24
+:10244000AFB20018AFB10014AFB00010AFBF0020A2
+:102450000080982100E0802130B1FFFF0E000D8444
+:1024600030D200FF0000000000000000000000006B
+:102470008F8200208F830024AC510000AC520004F6
+:10248000AC530008AC40000CAC400010AC40001451
+:10249000AC4000189463001E02038025AC50001C61
+:1024A0000000000000000000000000002404000103
+:1024B0008FBF00208FB3001C8FB200188FB10014A3
+:1024C0008FB000100A000DB827BD002830A5FFFF0F
+:1024D0000A0008DC30C600FF3C02800834430100DB
+:1024E0009462000E3C080800950800C63046FFFFC5
+:1024F00014C000043402FFFF946500EA0A000929B1
+:102500008F84001C10C20027000000009462004E5F
+:102510009464003C3045FFFF00A6102300A6182B52
+:102520003087FFFF106000043044FFFF00C5102318
+:1025300000E210233044FFFF0088102B1040000EF3
+:1025400000E810233C028008344401002403000109
+:1025500034420080A44300162402FFFFA482000E30
+:10256000948500EA8F84001C0000302130A5FFFF15
+:102570000A0009013C0760200044102A10400009AD
+:102580003C0280083443008094620016304200010F
+:10259000104000043C0280009442007E244200145B
+:1025A000A462001603E000080000000027BDFFE061
+:1025B0003C028008AFBF001CAFB0001834420100DD
+:1025C000944300429442004C104000193068FFFFD1
+:1025D0009383001824020001146200298FBF001C9D
+:1025E0003C06800834D00100000810C200501021C1
+:1025F000904200643103000734C70148304200FFB5
+:10260000006210073042000134C9014E34C4012C6D
+:1026100034C5013E1040001634C601420E0006D2F9
+:10262000AFA90010960200420A0009463048FFFF99
+:102630003C028008344401009483004494820042A8
+:102640001043000F8FBF001C94820044A4820042FC
+:1026500094820050A482004E8C820038AC820030FC
+:1026600094820040A482003E9482004AA4820048E2
+:102670008FBF001C8FB000180A00090427BD00207E
+:102680008FB0001803E0000827BD002027BDFFA081
+:10269000AFB1004C3C118000AFBF0058AFB3005445
+:1026A000AFB20050AFB000483626018890C2000398
+:1026B0003044007FA3A400108E32018090C200003D
+:1026C0003043007F240200031062003BAF92001CE5
+:1026D00028620004104000062402000424020002C4
+:1026E000106200098FBF00580A000B0F8FB300540F
+:1026F0001062004D240200051062014E8FBF005889
+:102700000A000B0F8FB30054000411C002421021C5
+:102710002404FF8024420240004410242643004049
+:10272000AE2200243063007F3C02800A0062182140
+:102730009062003CAFA3003C00441025A062003C26
+:102740008FA3003C9062003C304200401040016C7E
+:102750008FBF00583C108008A3800018361001007D
+:102760008E0200E08C63003427A4003C27A50010F3
+:10277000004310210E0007C3AE0200E093A2001038
+:102780003C038000A20200D58C6202780440FFFE68
+:102790008F82001CAC62024024020002A06202444C
+:1027A0003C021000AC6202780E0009390000000003
+:1027B0000A000B0E8FBF00583C05800890C3000133
+:1027C00090A2000B1443014E8FBF005834A4008028
+:1027D0008C8200189082004C90A200083C0260009D
+:1027E0008C4254048C8300183C027FFF3442FFFF6C
+:1027F000006218243C0208008C4200B4AC8300182C
+:102800003C038000244200013C010800AC2200B4DB
+:102810008C6201F80440FFFE8F82001CAC6201C094
+:102820000A000AD6240200023C10800890C300016E
+:102830009202000B144301328FBF005827A40018E6
+:1028400036050110240600033C0260008C4254044B
+:102850000E000E470000000027A40028360501F0F6
+:102860000E000E47240600038FA200283603010045
+:10287000AE0200648FA2002CAE0200688FA200306E
+:10288000AE02006C93A40018906300D52402FF8070
+:102890000082102400431025304900FF3084007F5F
+:1028A0003122007F0082102A544000013929008023
+:1028B000000411C0244202402403FF800242102180
+:1028C00000431024AE220094264200403042007F94
+:1028D0003C038006004340218FA3001C2402FFFF1D
+:1028E000AFA800403C130800927300F71062003359
+:1028F00093A2001995030014304400FF3063FFFFDA
+:102900000064182B106000100000000095040014F3
+:102910008D07001C8D0600183084FFFF0044202323
+:102920000004210000E438210000102100E4202BE5
+:1029300000C2302100C43021AD07001CAD060018D4
+:102940000A000A2F93A20019950400148D07001C99
+:102950008D0600183084FFFF008220230004210030
+:10296000000010210080182100C2302300E4202B39
+:1029700000C4302300E33823AD07001CAD06001867
+:1029800093A200198FA30040A462001497A2001A1A
+:10299000A46200168FA2001CAC6200108FA2001C63
+:1029A000AC62000C93A20019A462002097A2001A46
+:1029B000A46200228FA2001CAC6200243C048008A8
+:1029C000348300808C6200388FA20020012088218F
+:1029D000AC62003C8FA20020AC82000093A20018E1
+:1029E000A062004C93A20018A0820009A0600068B9
+:1029F00093A20018105100512407FF803229007F54
+:102A0000000911C024420240024210213046007FDA
+:102A10003C03800000471024AC6200943C02800616
+:102A200000C2302190C2003CAFA60040000020212F
+:102A300000471025A0C2003C8FA80040950200026C
+:102A4000950300148D07001C3042FFFF3063FFFF29
+:102A50008D060018004310230002110000E2382107
+:102A600000E2102B00C4302100C23021AD07001C51
+:102A7000AD06001895020002A5020014A50000167C
+:102A80008D020008AD0200108D020008AD02000C9E
+:102A900095020002A5020020A50000228D02000878
+:102AA000AD0200249102003C304200401040001A68
+:102AB000262200013C108008A3A90038A38000183A
+:102AC000361001008E0200E08D03003427A4004080
+:102AD00027A50038004310210E0007C3AE0200E016
+:102AE00093A200383C038000A20200D58C620278D9
+:102AF0000440FFFE8F82001CAC62024024020002F0
+:102B0000A06202443C021000AC6202780E00093957
+:102B100000000000262200013043007F14730004EF
+:102B2000004020212403FF8002231024004320269C
+:102B300093A200180A000A4B309100FF93A40018DA
+:102B40008FA3001C2402FFFF1062000A308900FFDF
+:102B500024820001248300013042007F14530005C9
+:102B6000306900FF2403FF800083102400431026F7
+:102B7000304900FF3C028008904200080120882173
+:102B8000305000FF123000193222007F000211C0C5
+:102B900002421021244202402403FF8000431824F3
+:102BA0003C048000AC8300943042007F3C038006EC
+:102BB000004310218C43000C004020211060000BCA
+:102BC000AFA200400E00057E000000002623000199
+:102BD0002405FF803062007F145300020225202468
+:102BE000008518260A000AAF307100FF3C048008F7
+:102BF000348400808C8300183C027FFF3442FFFF46
+:102C000000621824AC8300183C0380008C6201F839
+:102C10000440FFFE00000000AC7201C0240200026C
+:102C2000A06201C43C021000AC6201F80A000B0E65
+:102C30008FBF00583C04800890C300019082000BB5
+:102C40001443002F8FBF0058349000809202000878
+:102C500030420040104000200000000092020008B6
+:102C60000002160000021603044100050240202164
+:102C70000E000ECC240500930A000B0E8FBF0058E7
+:102C80009202000924030018304200FF1443000D93
+:102C900002402021240500390E000E64000030217E
+:102CA0000E0003328F84001C8F82FF9424030012D5
+:102CB000A04300090E00033D8F84001C0A000B0E88
+:102CC0008FBF0058240500360E000E64000030212E
+:102CD0000A000B0E8FBF00580E0003320240202165
+:102CE000920200058F84001C344200200E00033D38
+:102CF000A20200050E0010758F84001C8FBF0058C3
+:102D00008FB300548FB200508FB1004C8FB0004889
+:102D100003E0000827BD00603C0280083445010044
+:102D20003C0280008C42014094A3000E0000302140
+:102D300000402021AF82001C3063FFFF3402FFFF00
+:102D4000106200063C0760202402FFFFA4A2000ED0
+:102D500094A500EA0A00090130A5FFFF03E000087E
+:102D60000000000027BDFFC83C0280003C06800830
+:102D7000AFB5002CAFB1001CAFBF0030AFB400281E
+:102D8000AFB30024AFB20020AFB00018345101003F
+:102D900034C501008C4301008E2200148CA400E491
+:102DA0000000A821AF83001C0044102318400052EB
+:102DB000A38000188E22001400005021ACA200E471
+:102DC00090C3000890A200D53073007FA3A200102A
+:102DD0008CB200E08CB400E4304200FF1053003BA2
+:102DE00093A200108F83001C2407FF80000211C0F3
+:102DF0000062102124420240246300400047102456
+:102E00003063007F3C0980003C08800A006818217C
+:102E1000AD2200248C62003427A4001427A50010E2
+:102E2000024280210290102304400028AFA3001426
+:102E30009062003C00E21024304200FF1440001970
+:102E4000020090219062003C34420040A062003CAD
+:102E50008F86001C93A3001024C200403042007FE4
+:102E6000004828213C0208008C4200F42463000141
+:102E7000306400FF14820002A3A30010A3A000107E
+:102E800093A20010AFA50014000211C0244202401A
+:102E900000C2102100471024AD2200240A000B4577
+:102EA00093A200100E0007C3000000003C0280083F
+:102EB00034420100AC5000E093A30010240A00014A
+:102EC000A04300D50A000B4593A200102402000184
+:102ED000154200093C0380008C6202780440FFFE2A
+:102EE0008F82001CAC62024024020002A0620244F5
+:102EF0003C021000AC6202789222000B2403000214
+:102F0000304200FF144300720000000096220008C7
+:102F1000304300FF24020082146200402402008437
+:102F20003C028000344901008D22000C95230006EC
+:102F3000000216023063FFFF3045003F24020027E5
+:102F400010A2000FAF83001428A200281040000830
+:102F5000240200312402002110A2000924020025CD
+:102F600010A20007938200190A000BBD00000000A8
+:102F700010A20007938200190A000BBD0000000098
+:102F80000E000777012020210A000C3D0000000000
+:102F90003C0380008C6202780440FFFE8F82001C9C
+:102FA000AC62024024020002A06202443C02100013
+:102FB000AC6202780A000C3D000000009523000678
+:102FC000912400058D25000C8D2600108D270018FA
+:102FD0008D28001C8D290020244200013C0108009E
+:102FE000A42356C63C010800A02456C53C01080095
+:102FF000AC2556CC3C010800AC2656D03C0108005C
+:10300000AC2756D83C010800AC2856DC3C0108002F
+:10301000AC2956E00A000C3DA38200191462000A94
+:10302000240200813C02800834420100944500EAF9
+:10303000922600058F84001C30A5FFFF30C600FFDC
+:103040000A000BFE3C0760211462005C00000000D7
+:103050009222000A304300FF306200201040000737
+:10306000306200403C02800834420100944500EA8E
+:103070008F84001C0A000BFC24060040104000074F
+:10308000000316003C02800834420100944500EA27
+:103090008F84001C0A000BFC24060041000216036A
+:1030A000044100463C02800834420100944500EA95
+:1030B0008F84001C2406004230A5FFFF3C076019E6
+:1030C0000E000901000000000A000C3D0000000095
+:1030D0009222000B24040016304200FF1044000628
+:1030E0003C0680009222000B24030017304200FFB0
+:1030F000144300320000000034C5010090A2000B10
+:10310000304200FF1444000B000080218CA20020FC
+:103110008CA400202403FF800043102400021140EF
+:103120003084007F004410253C032000004310251C
+:10313000ACC2083094A2000800021400000214037C
+:10314000044200012410000194A2000830420080D3
+:103150005040001A0200A82194A20008304220002A
+:10316000504000160200A8218CA300183C021C2D20
+:10317000344219ED106200110200A8213C0208003F
+:103180008C4200D4104000053C0280082403000457
+:1031900034420100A04300FC3C028008344201009C
+:1031A000944500EA8F84001C2406000630A5FFFF2A
+:1031B0000E0009013C0760210200A8210E00093918
+:1031C000000000009222000A304200081040000473
+:1031D00002A010210E0013790000000002A01021AF
+:1031E0008FBF00308FB5002C8FB400288FB3002420
+:1031F0008FB200208FB1001C8FB0001803E00008D0
+:1032000027BD00382402FF80008220243C02900069
+:1032100034420007008220253C028000AC4400209C
+:103220003C0380008C6200200440FFFE0000000090
+:1032300003E00008000000003C0380002402FF803F
+:10324000008220243462000700822025AC64002024
+:103250008C6200200440FFFE0000000003E0000834
+:103260000000000027BDFFD8AFB3001CAFB10014B1
+:10327000AFB00010AFBF0020AFB200183C1180000B
+:103280003C0280088E32002034530100AE2400201E
+:10329000966300EA000514003C074000004738250B
+:1032A00000A08021000030210E0009013065FFFFE1
+:1032B000240200A1160200022402FFFFA2620009FC
+:1032C000AE3200208FBF00208FB3001C8FB20018D9
+:1032D0008FB100148FB0001003E0000827BD002854
+:1032E0003C0280082403000527BDFFE834420100AA
+:1032F000A04300FCAFBF00103C0280008C420100E4
+:10330000240500A1004020210E000C67AF82001CA4
+:103310003C0380008C6202780440FFFE8F82001C18
+:103320008FBF001027BD0018AC62024024020002CB
+:10333000A06202443C021000AC62027803E0000884
+:103340000000000027BDFFE83C068000AFBF001072
+:1033500034C7010094E20008304400FF3883008243
+:10336000388200842C6300012C4200010062182581
+:103370001060002D24020083938200195040003B0E
+:103380008FBF00103C020800904256CC8CC4010054
+:103390003C06080094C656C63045003F38A30032AC
+:1033A00038A2003F2C6300012C4200010062182566
+:1033B000AF84001CAF860014A380001914600007BE
+:1033C00000E020212402002014A2001200000000CE
+:1033D0003402FFFF14C2000F00000000240200208E
+:1033E00014A2000500E028218CE300142402FFFF52
+:1033F0005062000B8FBF00103C040800248456C0AC
+:10340000000030210E000706240700010A000CD638
+:103410008FBF00100E000777000000008FBF001064
+:103420000A00093927BD001814820004240200850F
+:103430008CC501040A000CE1000020211482000662
+:103440002482FF808CC50104240440008FBF00103B
+:103450000A00016727BD0018304200FF2C4200021D
+:1034600010400004240200228FBF00100A000B2726
+:1034700027BD0018148200048F8200248FBF001023
+:103480000A000C8627BD00188C42000C1040001E5C
+:1034900000E0282190E300092402001814620003D0
+:1034A000240200160A000CFC240300081462000722
+:1034B00024020017240300123C02800834420080DA
+:1034C000A04300090A000D0994A7000854620007F0
+:1034D00094A700088F82FF942404FFFE9043000508
+:1034E00000641824A043000594A7000890A6001BC0
+:1034F0008CA4000094A500068FBF001000073C00BC
+:103500000A0008DC27BD00188FBF001003E0000888
+:1035100027BD00188F8500243C04800094A2002A57
+:103520008CA30034000230C02402FFF000C210243B
+:1035300000621821AC83003C8CA200303C03800068
+:10354000AC8200383C02005034420010AC620030C3
+:103550000000000000000000000000008C6200007D
+:10356000304200201040FFFD30C20008104000062D
+:103570003C0280008C620408ACA200208C62040C27
+:103580000A000D34ACA200248C430400ACA300203C
+:103590008C420404ACA200243C0300203C028000C6
+:1035A000AC4300303C0480008C8200300043102487
+:1035B0001440FFFD8F8600243C020040AC820030A6
+:1035C00094C3002A94C2002894C4002C94C5002EF1
+:1035D00024630001004410213064FFFFA4C20028CE
+:1035E00014850002A4C3002AA4C0002A03E0000836
+:1035F000000000008F84002427BDFFE83C05800404
+:1036000024840010AFBF00100E000E472406000AED
+:103610008F840024948200129483002E3042000F85
+:10362000244200030043180424027FFF0043102BB0
+:1036300010400002AC8300000000000D0E000D13CE
+:10364000000000008F8300248FBF001027BD0018EA
+:10365000946200149463001A3042000F00021500B7
+:10366000006218253C02800003E00008AC4300A083
+:103670008F8300243C028004944400069462001A64
+:103680008C650000A4640016004410233042FFFF44
+:103690000045102B03E00008384200018F8400240D
+:1036A0003C0780049486001A8C85000094E2000692
+:1036B000A482001694E3000600C310233042FFFFEB
+:1036C0000045102B384200011440FFF8A483001677
+:1036D00003E00008000000008F8400243C02800406
+:1036E000944200069483001A8C850000A482001680
+:1036F000006210233042FFFF0045102B38420001CA
+:103700005040000D8F850024006030213C0780046C
+:1037100094E20006A482001694E3000600C310237E
+:103720003042FFFF0045102B384200011440FFF8E3
+:10373000A48300168F8500243C03800034620400BB
+:103740008CA40020AF820020AC6400388CA200243E
+:10375000AC62003C3C020005AC62003003E00008B3
+:10376000ACA000048F8400243C0300068C8200047B
+:1037700000021140004310253C038000AC62003081
+:103780000000000000000000000000008C6200004B
+:10379000304200101040FFFD34620400AC80000491
+:1037A00003E00008AF8200208F86002427BDFFE0E1
+:1037B000AFB10014AFB00010AFBF00188CC300044D
+:1037C0008CC500248F820020309000FF94C4001A22
+:1037D00024630001244200202484000124A7002047
+:1037E000ACC30004AF820020A4C4001AACC70024FC
+:1037F00004A100060000882104E2000594C2001A1A
+:103800008CC2002024420001ACC2002094C2001AE5
+:1038100094C300282E040001004310262C4200010E
+:10382000004410245040000594C2001A24020001F4
+:10383000ACC2000894C2001A94C300280010202BC8
+:10384000004310262C4200010044102514400007BC
+:10385000000000008CC20008144000042402001084
+:103860008CC300041462000F8F8500240E000DA786
+:10387000241100018F820024944300289442001AEE
+:1038800014430003000000000E000D1300000000B0
+:10389000160000048F8500240E000D840000000037
+:1038A0008F85002494A2001E94A4001C24420001D1
+:1038B0003043FFFF14640002A4A2001EA4A0001E57
+:1038C0001200000A3C02800494A2001494A3001A7F
+:1038D0003042000F00021500006218253C028000F3
+:1038E000AC4300A00A000E1EACA0000894420006E3
+:1038F00094A3001A8CA40000A4A200160062102356
+:103900003042FFFF0044102B384200011040000DF0
+:1039100002201021006030213C07800494E2000660
+:10392000A4A2001694E3000600C310233042FFFF58
+:103930000044102B384200011440FFF8A4A30016E5
+:10394000022010218FBF00188FB100148FB000101B
+:1039500003E0000827BD002003E00008000000008D
+:103960008F82002C3C03000600021140004310250A
+:103970003C038000AC62003000000000000000004A
+:10398000000000008C620000304200101040FFFD7B
+:1039900034620400AF82002803E00008AF80002CEE
+:1039A00003E000080000102103E000080000000010
+:1039B0003084FFFF30A5FFFF0000182110800007B2
+:1039C000000000003082000110400002000420428C
+:1039D000006518210A000E3D0005284003E000089C
+:1039E0000060102110C0000624C6FFFF8CA200005A
+:1039F00024A50004AC8200000A000E4724840004C1
+:103A000003E000080000000010A0000824A3FFFF4E
+:103A1000AC86000000000000000000002402FFFF50
+:103A20002463FFFF1462FFFA2484000403E000080B
+:103A3000000000003C0280083442008024030001A2
+:103A4000AC43000CA4430010A4430012A443001490
+:103A500003E00008A44300168F82002427BDFFD88E
+:103A6000AFB3001CAFB20018AFB10014AFB000107C
+:103A7000AFBF00208C47000C248200802409FF8007
+:103A80003C08800E3043007F008080213C0A80008B
+:103A9000004920240068182130B100FF30D200FF17
+:103AA00010E000290000982126020100AD44002CFE
+:103AB000004928243042007F004820219062000005
+:103AC00024030050304200FF1443000400000000B3
+:103AD000AD45002C948200EA3053FFFF0E000D84A8
+:103AE000000000008F8200248F83002000112C0032
+:103AF0009442001E001224003484000100A22825F4
+:103B00003C02400000A22825AC7000008FBF0020BE
+:103B1000AC6000048FB20018AC7300088FB10014C1
+:103B2000AC60000C8FB3001CAC6400108FB00010B0
+:103B3000AC60001424040001AC60001827BD00280C
+:103B40000A000DB8AC65001C8FBF00208FB3001CAD
+:103B50008FB200188FB100148FB0001003E000087E
+:103B600027BD00283C06800034C201009043000FAE
+:103B7000240200101062000E2865001110A000073A
+:103B800024020012240200082405003A10620006F4
+:103B90000000302103E0000800000000240500358B
+:103BA0001462FFFC000030210A000E6400000000D7
+:103BB0008CC200748F83FF9424420FA003E000089E
+:103BC000AC62000C27BDFFE8AFBF00100E0003423F
+:103BD000240500013C0480088FBF0010240200016E
+:103BE00034830080A462001227BD00182402000163
+:103BF00003E00008A080001A27BDFFE0AFB2001864
+:103C0000AFB10014AFB00010AFBF001C30B2FFFF67
+:103C10000E000332008088213C028008345000806E
+:103C20009202000924030004304200FF1443000CF8
+:103C30003C028008124000082402000A0E000E5BBD
+:103C400000000000920200052403FFFE0043102440
+:103C5000A202000524020012A20200093C02800810
+:103C600034420080022020210E00033DA0400027A6
+:103C700016400003022020210E000EBF00000000AD
+:103C800002202021324600FF8FBF001C8FB2001897
+:103C90008FB100148FB00010240500380A000E64A4
+:103CA00027BD002027BDFFE0AFBF001CAFB200184A
+:103CB000AFB10014AFB000100E00033200808021BD
+:103CC0000E000E5B000000003C02800834450080BE
+:103CD00090A2000924120018305100FF1232000394
+:103CE0000200202124020012A0A2000990A20005D7
+:103CF0002403FFFE004310240E00033DA0A2000594
+:103D00000200202124050020163200070000302187
+:103D10008FBF001C8FB200188FB100148FB000103D
+:103D20000A00034227BD00208FBF001C8FB200187D
+:103D30008FB100148FB00010240500390A000E6402
+:103D400027BD002027BDFFE83C028000AFB0001077
+:103D5000AFBF0014344201009442000C2405003629
+:103D60000080802114400012304600FF0E00033214
+:103D7000000000003C02800834420080240300124E
+:103D8000A043000990430005346300100E000E5B51
+:103D9000A04300050E00033D020020210200202167
+:103DA0000E000342240500200A000F3C0000000022
+:103DB0000E000E64000000000E00033202002021FD
+:103DC0003C0280089043001B2405FF9F0200202135
+:103DD000006518248FBF00148FB00010A043001B93
+:103DE0000A00033D27BD001827BDFFE0AFBF001844
+:103DF000AFB10014AFB0001030B100FF0E000332BD
+:103E0000008080213C02800824030012344200809C
+:103E10000E000E5BA04300090E00033D02002021AE
+:103E200002002021022030218FBF00188FB1001422
+:103E30008FB00010240500350A000E6427BD002055
+:103E40003C0480089083000E9082000A1443000B0B
+:103E5000000028218F82FF942403005024050001D4
+:103E600090420000304200FF1443000400000000B4
+:103E70009082000E24420001A082000E03E00008A0
+:103E800000A010213C0380008C6201F80440FFFE7A
+:103E900024020002AC6401C0A06201C43C02100014
+:103EA00003E00008AC6201F827BDFFE0AFB20018E4
+:103EB0003C128008AFB10014AFBF001CAFB00010BF
+:103EC00036510080922200092403000A304200FF8C
+:103ED0001443003E000000008E4300048E22003890
+:103EE000506200808FBF001C92220000240300500B
+:103EF000304200FF144300253C0280008C42014008
+:103F00008E4300043642010002202821AC43001CED
+:103F10009622005C8E2300383042FFFF00021040E2
+:103F200000621821AE23001C8E4300048E2400384A
+:103F30009622005C006418233042FFFF0003184300
+:103F4000000210400043102A10400006000000004C
+:103F50008E4200048E230038004310230A000FAA6B
+:103F6000000220439622005C3042FFFF0002204006
+:103F70003C0280083443010034420080ACA4002C91
+:103F8000A040002424020001A062000C0E000F5E7D
+:103F900000000000104000538FBF001C3C02800056
+:103FA0008C4401403C0380008C6201F80440FFFE19
+:103FB00024020002AC6401C0A06201C43C021000F3
+:103FC000AC6201F80A0010078FBF001C92220009A2
+:103FD00024030010304200FF144300043C02800020
+:103FE0008C4401400A000FEE0000282192220009B3
+:103FF00024030016304200FF14430006240200147C
+:10400000A22200093C0280008C4401400A001001F9
+:104010008FBF001C8E2200388E23003C00431023EB
+:10402000044100308FBF001C92220027244200016F
+:10403000A2220027922200272C42000414400016DE
+:104040003C1080009222000924030004304200FF4B
+:10405000144300093C0280008C4401408FBF001CC7
+:104060008FB200188FB100148FB000102405009398
+:104070000A000ECC27BD00208C440140240500938B
+:104080008FBF001C8FB200188FB100148FB00010CA
+:104090000A000F4827BD00208E0401400E000332A5
+:1040A000000000008E4200042442FFFFAE420004E4
+:1040B0008E22003C2442FFFFAE22003C0E00033D56
+:1040C0008E0401408E0401408FBF001C8FB2001887
+:1040D0008FB100148FB00010240500040A000342C1
+:1040E00027BD00208FB200188FB100148FB00010D0
+:1040F00003E0000827BD00203C0680008CC2018838
+:104100003C038008346500809063000E00021402B6
+:10411000304400FF306300FF1464000E3C0280084E
+:1041200090A20026304200FF104400098F82FF94C5
+:10413000A0A400262403005090420000304200FF5B
+:1041400014430006000000000A0005A18CC4018091
+:104150003C02800834420080A044002603E00008AE
+:104160000000000027BDFFE030E700FFAFB20018FD
+:10417000AFBF001CAFB10014AFB0001000809021A1
+:1041800014E0000630C600FF000000000000000D33
+:10419000000000000A001060240001163C038008A3
+:1041A0009062000E304200FF14460023346200800B
+:1041B00090420026304200FF1446001F000000001D
+:1041C0009062000F304200FF1446001B0000000008
+:1041D0009062000A304200FF144600038F90FF9463
+:1041E0000000000D8F90FF948F82FF983C1180009B
+:1041F000AE05003CAC450000A066000A0E0003328C
+:104200008E240100A20000240E00033D8E24010034
+:104210003C0380008C6201F80440FFFE240200028F
+:10422000AC7201C0A06201C43C021000AC6201F893
+:104230000A0010618FBF001C000000000000000D8C
+:10424000000000002400013F8FBF001C8FB2001847
+:104250008FB100148FB0001003E0000827BD0020CC
+:104260008F83FF943C0280008C44010034420100A3
+:104270008C65003C9046001B0A00102724070001B3
+:104280003C0280089043000E9042000A0043102632
+:10429000304200FF03E000080002102B27BDFFE0C2
+:1042A0003C028008AFB10014AFB00010AFBF0018DF
+:1042B0003450008092020005240300303042003068
+:1042C00014430085008088218F8200248C42000CDA
+:1042D000104000828FBF00180E000D840000000007
+:1042E0008F860020ACD100009202000892030009E2
+:1042F000304200FF00021200306300FF004310252F
+:10430000ACC200049202004D000216000002160327
+:1043100004410005000000003C0308008C630048D5
+:104320000A00109F3C1080089202000830420040B2
+:10433000144000030000182192020027304300FFC0
+:104340003C108008361100809222004D00031E00B0
+:10435000304200FF0002140000621825ACC30008C0
+:104360008E2400308F820024ACC4000C8E250034D3
+:104370009443001E3C02C00BACC50010006218251F
+:104380008E22003800002021ACC200148E22003C96
+:10439000ACC200180E000DB8ACC3001C8E020004A5
+:1043A0008F8400203C058000AC8200008E2200201B
+:1043B000AC8200048E22001CAC8200088E220058C1
+:1043C0008CA3007400431021AC82000C8E22002CC0
+:1043D000AC8200108E2200408E23004400021400A4
+:1043E00000431025AC8200149222004D240300806B
+:1043F000304200FF1443000400000000AC800018AD
+:104400000A0010E38F8200248E23000C2402000196
+:104410001062000E2402FFFF92220008304200408A
+:104420001440000A2402FFFF8E23000C8CA20074AB
+:10443000006218233C0208000062102414400002AD
+:10444000000028210060282100051043AC820018DC
+:104450008F820024000020219443001E3C02C00CE7
+:10446000006218258F8200200E000DB8AC43001C9E
+:104470003C038008346201008C4200008F850020DC
+:10448000346300808FBF0018ACA20000ACA0000411
+:104490008C6400488F8200248FB10014ACA4000803
+:1044A000ACA0000CACA00010906300059446001E68
+:1044B0003C02400D00031E0000C23025ACA30014D6
+:1044C0008FB00010ACA0001824040001ACA6001CA2
+:1044D0000A000DB827BD00208FBF00188FB100144F
+:1044E0008FB0001003E0000827BD00203C028000D0
+:1044F0009443007C3C02800834460100308400FF75
+:104500003065FFFF2402000524A34650A0C4000C20
+:104510005482000C3065FFFF90C2000D2C42000752
+:104520001040000724A30A0090C3000D24020014C9
+:104530000062100400A210210A00111F3045FFFF85
+:104540003065FFFF3C0280083442008003E0000831
+:10455000A44500143C03800834680080AD05003891
+:10456000346701008CE2001C308400FF00A210239D
+:104570001840000330C600FF24A2FFFCACE2001C80
+:1045800030820001504000083C0380088D02003C4E
+:1045900000A2102304410012240400058C620004D0
+:1045A00010A2000F3C0380088C62000414A2001EBD
+:1045B000000000003C0208008C4200D8304200207D
+:1045C000104000093C0280083462008090630008BB
+:1045D0009042004C144300043C0280082404000470
+:1045E0000A00110900000000344300803442010039
+:1045F000A040000C24020001A462001410C0000AB4
+:104600003C0280008C4401003C0380008C6201F875
+:104610000440FFFE24020002AC6401C0A06201C499
+:104620003C021000AC6201F803E00008000000004A
+:1046300027BDFFE800A61823AFBF00101860008058
+:10464000308800FF3C02800834470080A0E000244E
+:1046500034440100A0E000278C82001C00A210233B
+:1046600004400056000000008CE2003C94E3005C33
+:104670008CE4002C004530233063FFFF00C3182179
+:104680000083202B1080000400E018218CE2002C15
+:104690000A00117800A2102194E2005C3042FFFF72
+:1046A00000C2102100A21021AC62001C3C02800854
+:1046B000344400809482005C8C83001C3042FFFFF5
+:1046C0000002104000A210210043102B10400004F3
+:1046D000000000008C82001C0A00118B3C06800840
+:1046E0009482005C3042FFFF0002104000A21021C3
+:1046F0003C06800834C3010034C70080AC82001C33
+:10470000A060000CACE500388C62001C00A21023F5
+:104710001840000224A2FFFCAC62001C3102000120
+:10472000104000083C0380088CE2003C00A21023EB
+:1047300004410012240400058CC2000410A20010E1
+:104740008FBF00108C62000414A2004F8FBF0010B6
+:104750003C0208008C4200D8304200201040000A81
+:104760003C02800834620080906300089042004C54
+:10477000144300053C028008240400048FBF00108D
+:104780000A00110927BD001834430080344201009B
+:10479000A040000C24020001A46200143C0280002E
+:1047A0008C4401003C0380008C6201F80440FFFE51
+:1047B000240200020A0011D8000000008CE2001C54
+:1047C000004610230043102B54400001ACE5001CB0
+:1047D00094E2005C3042FFFF0062102B144000079F
+:1047E0002402000294E2005C8CE3001C3042FFFFD4
+:1047F00000621821ACE3001C24020002ACE5003882
+:104800000E000F5EA082000C1040001F8FBF001032
+:104810003C0280008C4401003C0380008C6201F863
+:104820000440FFFE24020002AC6401C0A06201C487
+:104830003C021000AC6201F80A0011F08FBF0010BA
+:1048400031020010104000108FBF00103C028008A1
+:10485000344500808CA3001C94A2005C00661823E1
+:104860003042FFFF006218213C023FFF3444FFFF4B
+:104870000083102B544000010080182100C3102138
+:10488000ACA2001C8FBF001003E0000827BD001879
+:1048900027BDFFE800C0402100A63023AFBF0010B5
+:1048A00018C00026308A00FF3C028008344900808E
+:1048B0008D24001C8D23002C008820230064182BDD
+:1048C0001060000F344701008CE2002000461021E8
+:1048D000ACE200208CE200200044102B1440000BBE
+:1048E0003C023FFF8CE2002000441023ACE2002099
+:1048F0009522005C3042FFFF0A0012100082202146
+:10490000ACE00020008620213C023FFF3443FFFF43
+:104910000064102B54400001006020213C028008FC
+:104920003442008000851821AC43001CA0400024C4
+:10493000A04000270A0012623C03800831420010A8
+:10494000104000433C0380083C06800834C40080CB
+:104950008C82003C004810235840003E34660080A2
+:104960009082002424420001A0820024908200242E
+:104970003C0308008C630024304200FF0043102BEE
+:10498000144000688FBF001034C201008C42001C2C
+:1049900000A2102318400063000000008CC3000434
+:1049A0009482005C006818233042FFFF0003184324
+:1049B000000210400043102A1040000500000000D3
+:1049C0008CC20004004810230A0012450002104364
+:1049D0009482005C3042FFFF000210403C068008D9
+:1049E000AC82002C34C5008094A2005C8CA4002C06
+:1049F00094A3005C3042FFFF00021040008220219F
+:104A00003063FFFF0083202101041021ACA2001CB1
+:104A10008CC2000434C60100ACC2001C2402000297
+:104A20000E000F5EA0C2000C1040003E8FBF0010B1
+:104A30003C0280008C4401003C0380008C6201F841
+:104A40000440FFFE240200020A001292000000004F
+:104A500034660080ACC50038346401008C82001CD0
+:104A600000A210231840000224A2FFFCAC82001C0C
+:104A7000314200015040000A3C0380088CC2003CD7
+:104A800000A2102304430014240400058C620004D7
+:104A900014A200033C0380080A00128424040005C9
+:104AA0008C62000414A2001F8FBF00103C0208009B
+:104AB0008C4200D8304200201040000A3C0280089E
+:104AC00034620080906300089042004C144300055B
+:104AD0003C028008240400048FBF00100A00110962
+:104AE00027BD00183443008034420100A040000C70
+:104AF00024020001A46200143C0280008C440100E6
+:104B00003C0380008C6201F80440FFFE2402000296
+:104B1000AC6401C0A06201C43C021000AC6201F8A8
+:104B20008FBF001003E0000827BD001827BDFFE875
+:104B30003C0A8008AFBF0010354900808D22003C40
+:104B400000C04021308400FF004610231840009D23
+:104B500030E700FF354701002402000100A63023A2
+:104B6000A0E0000CA0E0000DA522001418C0002455
+:104B7000308200108D23001C8D22002C0068182329
+:104B80000043102B1040000F000000008CE20020BA
+:104B900000461021ACE200208CE200200043102BE4
+:104BA0001440000B3C023FFF8CE200200043102326
+:104BB000ACE200209522005C3042FFFF0A0012C1E7
+:104BC00000621821ACE00020006618213C023FFF83
+:104BD0003446FFFF00C3102B5440000100C01821D1
+:104BE0003C0280083442008000651821AC43001C60
+:104BF000A0400024A04000270A00130F3C038008B7
+:104C0000104000403C0380088D22003C00481023E7
+:104C10005840003D34670080912200242442000166
+:104C2000A1220024912200243C0308008C6300246C
+:104C3000304200FF0043102B1440009A8FBF001039
+:104C40008CE2001C00A21023184000960000000017
+:104C50008D4300049522005C006818233042FFFF5A
+:104C600000031843000210400043102A10400005C2
+:104C7000012020218D420004004810230A0012F276
+:104C8000000210439522005C3042FFFF00021040FA
+:104C90003C068008AC82002C34C5008094A2005CE5
+:104CA0008CA4002C94A3005C3042FFFF0002104053
+:104CB000008220213063FFFF0083182101031021AF
+:104CC000ACA2001C8CC2000434C60100ACC2001CA3
+:104CD000240200020E000F5EA0C2000C1040007102
+:104CE0008FBF00103C0280008C4401003C03800018
+:104CF0008C6201F80440FFFE240200020A0013390E
+:104D00000000000034670080ACE500383466010024
+:104D10008CC2001C00A210231840000224A2FFFC39
+:104D2000ACC2001C30820001504000083C038008E7
+:104D30008CE2003C00A2102304430051240400052F
+:104D40008C62000410A2003E3C0380088C620004C8
+:104D500054A200548FBF00103C0208008C4200D8BF
+:104D600030420020104000063C028008346200807F
+:104D7000906300089042004C104300403C028008C1
+:104D80003443008034420100A040000C24020001A2
+:104D9000A46200143C0280008C4401003C038000AB
+:104DA0008C6201F80440FFFE24020002AC6401C0E2
+:104DB000A06201C43C021000AC6201F80A00137743
+:104DC0008FBF001024020005A120002714E2000A72
+:104DD0003C038008354301009062000D2C42000620
+:104DE000504000053C0380089062000D2442000101
+:104DF000A062000D3C03800834670080ACE50038F9
+:104E0000346601008CC2001C00A21023184000026E
+:104E100024A2FFFCACC2001C308200015040000AFA
+:104E20003C0380088CE2003C00A2102304410014E3
+:104E3000240400058C62000414A200033C038008D3
+:104E40000A00136E240400058C62000414A20015ED
+:104E50008FBF00103C0208008C4200D83042002076
+:104E60001040000A3C028008346200809063000811
+:104E70009042004C144300053C02800824040004C6
+:104E80008FBF00100A00110927BD001834430080AD
+:104E900034420100A040000C24020001A46200146E
+:104EA0008FBF001003E0000827BD00183C0B8008EE
+:104EB00027BDFFE83C028000AFBF00103442010074
+:104EC000356A00809044000A356901008C45001461
+:104ED0008D4800389123000C308400FF0105102319
+:104EE0001C4000B3306700FF2CE20006504000B1C8
+:104EF0008FBF00102402000100E2300430C2000322
+:104F00005440000800A8302330C2000C144000A117
+:104F100030C20030144000A38FBF00100A00143BC1
+:104F20000000000018C00024308200108D43001CD7
+:104F30008D42002C006818230043102B1040000FF6
+:104F4000000000008D22002000461021AD2200202C
+:104F50008D2200200043102B1440000B3C023FFF29
+:104F60008D22002000431023AD2200209542005CDA
+:104F70003042FFFF0A0013AF00621821AD2000206D
+:104F8000006618213C023FFF3446FFFF00C3102B90
+:104F90005440000100C018213C02800834420080C7
+:104FA00000651821AC43001CA0400024A04000274D
+:104FB0000A0013FD3C038008104000403C038008B9
+:104FC0008D42003C004810231840003D34670080AB
+:104FD0009142002424420001A14200249142002475
+:104FE0003C0308008C630024304200FF0043102B78
+:104FF000144000708FBF00108D22001C00A21023EF
+:105000001840006C000000008D6300049542005CB5
+:10501000006818233042FFFF0003184300021040CD
+:105020000043102A10400005014020218D62000439
+:10503000004810230A0013E0000210439542005C70
+:105040003042FFFF000210403C068008AC82002C7A
+:1050500034C5008094A2005C8CA4002C94A3005C56
+:105060003042FFFF00021040008220213063FFFF2A
+:105070000083182101031021ACA2001C8CC2000483
+:1050800034C60100ACC2001C240200020E000F5EF8
+:10509000A0C2000C104000478FBF00103C028000EF
+:1050A0008C4401003C0380008C6201F80440FFFE48
+:1050B000240200020A00142D000000003467008062
+:1050C000ACE50038346601008CC2001C00A210233D
+:1050D0001840000224A2FFFCACC2001C3082000178
+:1050E0005040000A3C0380088CE2003C00A21023E0
+:1050F00004430014240400058C62000414A200037D
+:105100003C0380080A00141F240400058C6200047C
+:1051100014A200288FBF00103C0208008C4200D867
+:10512000304200201040000A3C02800834620080B7
+:10513000906300089042004C144300053C02800834
+:10514000240400048FBF00100A00110927BD0018B5
+:105150003443008034420100A040000C24020001CE
+:10516000A46200143C0280008C4401003C038000D7
+:105170008C6201F80440FFFE24020002AC6401C00E
+:10518000A06201C43C021000AC6201F80A00143BAA
+:105190008FBF00108FBF0010010030210A00115A8C
+:1051A00027BD0018010030210A00129927BD001800
+:1051B0008FBF001003E0000827BD00183C038008E3
+:1051C0003464010024020003A082000C8C620004FD
+:1051D00003E00008AC82001C3C05800834A300807A
+:1051E0009062002734A501002406004324420001F8
+:1051F000A0620027906300273C0208008C42004810
+:10520000306300FF146200043C07602194A500EAAB
+:105210000A00090130A5FFFF03E0000800000000BC
+:1052200027BDFFE8AFBF00103C0280000E00144411
+:105230008C4401803C02800834430100A060000CD3
+:105240008C4200048FBF001027BD001803E0000847
+:10525000AC62001C27BDFFE03C028008AFBF001815
+:10526000AFB10014AFB000103445008034460100E7
+:105270003C0880008D09014090C3000C8CA4003CC8
+:105280008CA200381482003B306700FF9502007C3E
+:1052900090A30027146000093045FFFF2402000599
+:1052A00054E200083C04800890C2000D2442000132
+:1052B000A0C2000D0A00147F3C048008A0C0000DAD
+:1052C0003C048008348201009042000C2403000555
+:1052D000304200FF1443000A24A205DC348300801E
+:1052E000906200272C4200075040000524A20A00CB
+:1052F00090630027240200140062100400A2102111
+:105300003C108008361000803045FFFF012020212E
+:105310000E001444A60500149602005C8E030038AB
+:105320003C1180003042FFFF000210400062182153
+:10533000AE03001C0E0003328E24014092020025B1
+:1053400034420040A20200250E00033D8E2401409D
+:105350008E2401403C0380008C6201F80440FFFE73
+:1053600024020002AC6401C0A06201C43C0210002F
+:10537000AC6201F88FBF00188FB100148FB000101D
+:1053800003E0000827BD00203C0360103C02080039
+:1053900024420174AC62502C8C6250003C048000AA
+:1053A00034420080AC6250003C0208002442547C2D
+:1053B0003C010800AC2256003C020800244254384C
+:1053C0003C010800AC2256043C020002AC840008F8
+:1053D000AC82000C03E000082402000100A0302190
+:1053E0003C1C0800279C56083C0200023C050400B7
+:1053F00000852826008220260004102B2CA5000101
+:105400002C840001000210803C0308002463560035
+:105410000085202500431821108000030000102182
+:10542000AC6600002402000103E000080000000058
+:105430003C1C0800279C56083C0200023C05040066
+:1054400000852826008220260004102B2CA50001B0
+:105450002C840001000210803C03080024635600E5
+:105460000085202500431821108000050000102130
+:105470003C02080024425438AC62000024020001BF
+:1054800003E00008000000003C0200023C030400AE
+:1054900000821026008318262C4200012C63000194
+:1054A000004310251040000B000028213C1C080080
+:1054B000279C56083C0380008C62000824050001EC
+:1054C00000431025AC6200088C62000C00441025DB
+:1054D000AC62000C03E0000800A010213C1C080096
+:1054E000279C56083C0580008CA3000C0004202754
+:1054F000240200010064182403E00008ACA3000C9F
+:105500003C020002148200063C0560008CA208D018
+:105510002403FFFE0043102403E00008ACA208D0DF
+:105520003C02040014820005000000008CA208D098
+:105530002403FFFD00431024ACA208D003E00008C0
+:10554000000000003C02601A344200108C430080CE
+:1055500027BDFFF88C440084AFA3000093A3000094
+:10556000240200041462001AAFA4000493A20001F4
+:105570001040000797A300023062FFFC3C0380004C
+:10558000004310218C4200000A001536AFA200042F
+:105590003062FFFC3C03800000431021AC4400005B
+:1055A000A3A000003C0560008CA208D02403FFFEED
+:1055B0003C04601A00431024ACA208D08FA300045E
+:1055C0008FA2000034840010AC830084AC82008081
+:1055D00003E0000827BD000827BDFFE8AFBF0010AB
+:1055E0003C1C0800279C56083C0280008C43000CA1
+:1055F0008C420004004318243C0200021060001496
+:10560000006228243C0204003C04000210A00005B3
+:10561000006210243C0208008C4256000A00155B10
+:1056200000000000104000073C0404003C02080099
+:105630008C4256040040F809000000000A00156082
+:10564000000000000000000D3C1C0800279C5608CC
+:105650008FBF001003E0000827BD0018800802403B
+:1056600080080100800800808008000000000C8095
+:105670000000320008000E9808000EF408000F88A1
+:1056800008001028080010748008010080080080BD
+:10569000800800000A000028000000000000000050
+:1056A0000000000D6370362E322E316200000000C3
+:1056B00006020104000000000000000000000000DD
+:1056C000000000000000000038003C000000000066
+:1056D00000000000000000000000000000000020AA
+:1056E00000000000000000000000000000000000BA
+:1056F00000000000000000000000000000000000AA
+:10570000000000000000000021003800000000013F
+:105710000000002B000000000000000400030D400A
+:105720000000000000000000000000000000000079
+:105730000000000000000000100000030000000056
+:105740000000000D0000000D3C020800244259AC8E
+:105750003C03080024635BF4AC4000000043202BB2
+:105760001480FFFD244200043C1D080037BD9FFC4F
+:1057700003A0F0213C100800261000A03C1C0800EB
+:10578000279C59AC0E0002F6000000000000000D3E
+:1057900027BDFFB4AFA10000AFA20004AFA3000873
+:1057A000AFA4000CAFA50010AFA60014AFA700185F
+:1057B000AFA8001CAFA90020AFAA0024AFAB0028FF
+:1057C000AFAC002CAFAD0030AFAE0034AFAF00389F
+:1057D000AFB8003CAFB90040AFBC0044AFBF004819
+:1057E0000E000820000000008FBF00488FBC00445E
+:1057F0008FB900408FB8003C8FAF00388FAE0034B7
+:105800008FAD00308FAC002C8FAB00288FAA002406
+:105810008FA900208FA8001C8FA700188FA6001446
+:105820008FA500108FA4000C8FA300088FA2000486
+:105830008FA1000027BD004C3C1B60188F7A5030B0
+:10584000377B502803400008AF7A000000A01821E1
+:1058500000801021008028213C0460003C0760008B
+:105860002406000810600006348420788C42000072
+:10587000ACE220088C63000003E00008ACE3200CDD
+:105880000A000F8100000000240300403C02600079
+:1058900003E00008AC4320003C0760008F86000452
+:1058A0008CE520740086102100A2182B14600007DC
+:1058B000000028218F8AFDA024050001A1440013C7
+:1058C0008F89000401244021AF88000403E0000810
+:1058D00000A010218F84FDA08F8500049086001306
+:1058E00030C300FF00A31023AF82000403E00008D0
+:1058F000A08000138F84FDA027BDFFE8AFB000108B
+:10590000AFBF001490890011908700112402002875
+:10591000312800FF3906002830E300FF2485002CE1
+:105920002CD00001106200162484001C0E00006EB2
+:10593000000000008F8FFDA03C05600024020204DF
+:1059400095EE003E95ED003C000E5C0031ACFFFF93
+:10595000016C5025ACAA2010520000012402000462
+:10596000ACA22000000000000000000000000000C9
+:105970008FBF00148FB0001003E0000827BD00188F
+:105980000A0000A6000028218F85FDA027BDFFD8B2
+:10599000AFBF0020AFB3001CAFB20018AFB100140E
+:1059A000AFB000100080982190A4001124B0001C1A
+:1059B00024B1002C308300FF386200280E000090D4
+:1059C0002C5200010E00009800000000020020216F
+:1059D0001240000202202821000028210E00006E43
+:1059E000000000008F8DFDA03C0880003C05600099
+:1059F00095AC003E95AB003C02683025000C4C0095
+:105A0000316AFFFF012A3825ACA7201024020202C8
+:105A1000ACA6201452400001240200028FBF0020D7
+:105A20008FB3001C8FB200188FB100148FB000101C
+:105A300027BD002803E00008ACA2200027BDFFE03E
+:105A4000AFB20018AFB10014AFB00010AFBF001C70
+:105A50003C1160008E2320748F82000430D0FFFF41
+:105A600030F2FFFF1062000C2406008F0E00006E63
+:105A7000000000003C06801F0010440034C5FF00F9
+:105A80000112382524040002AE2720100000302126
+:105A9000AE252014AE2420008FBF001C8FB200184A
+:105AA0008FB100148FB0001000C0102103E0000877
+:105AB00027BD002027BDFFE0AFB0001030D0FFFFB2
+:105AC000AFBF0018AFB100140E00006E30F1FFFF41
+:105AD00000102400009180253C036000AC70201071
+:105AE0008FBF00188FB100148FB000102402000483
+:105AF000AC62200027BD002003E000080000102158
+:105B000027BDFFE03C046018AFBF0018AFB1001420
+:105B1000AFB000108C8850002403FF7F34028071E6
+:105B20000103382434E5380C241F00313C1980006F
+:105B3000AC8550003C11800AAC8253BCAF3F0008DA
+:105B40000E00054CAF9100400E00050A3C116000AC
+:105B50000E00007D000000008E3008083C0F570941
+:105B60002418FFF00218602435EEE00035EDF00057
+:105B7000018E5026018D58262D4600012D69000109
+:105B8000AF86004C0E000D09AF8900503C06601630
+:105B90008CC700003C0860148D0500A03C03FFFF8B
+:105BA00000E320243C02535300052FC2108200550D
+:105BB00034D07C00960201F2A780006C10400003F4
+:105BC000A780007C384B1E1EA78B006C960201F844
+:105BD000104000048F8D0050384C1E1EA78C007C96
+:105BE0008F8D005011A000058F83004C240E0020E3
+:105BF000A78E007CA78E006C8F83004C1060000580
+:105C00009785007C240F0020A78F007CA78F006C55
+:105C10009785007C2CB8008153000001240500808A
+:105C20009784006C2C91040152200001240404008C
+:105C30001060000B3C0260008FBF00188FB1001491
+:105C40008FB0001027BD0020A784006CA785007CC2
+:105C5000A380007EA780007403E00008A780009264
+:105C60008C4704382419103C30FFFFFF13F9000360
+:105C700030A8FFFF1100004624030050A380007EDF
+:105C80009386007E50C00024A785007CA780007CFE
+:105C90009798007CA780006CA7800074A780009272
+:105CA0003C010800AC3800800E00078700000000AF
+:105CB0003C0F60008DED0808240EFFF03C0B600ED9
+:105CC000260C0388356A00100000482100002821B6
+:105CD00001AE20243C105709AF8C0010AF8A004859
+:105CE000AF89001810900023AF8500148FBF0018F3
+:105CF0008FB100148FB0001027BD002003E0000812
+:105D0000AF80005400055080014648218D260004D4
+:105D10000A00014800D180219798007CA784006C7C
+:105D2000A7800074A78000923C010800AC38008076
+:105D30000E000787000000003C0F60008DED080892
+:105D4000240EFFF03C0B600E260C0388356A001011
+:105D5000000048210000282101AE20243C105709F2
+:105D6000AF8C0010AF8A0048AF8900181490FFDF95
+:105D7000AF85001424110001AF9100548FBF0018AB
+:105D80008FB100148FB0001003E0000827BD002081
+:105D90000A00017BA383007E3083FFFF8F880040D1
+:105DA0008F87003C000321403C0580003C020050EE
+:105DB000008248253C0660003C0A010034AC040027
+:105DC0008CCD08E001AA58241160000500000000F5
+:105DD0008CCF08E024E7000101EA7025ACCE08E092
+:105DE0008D19001001805821ACB900388D180014AD
+:105DF000ACB8003CACA9003000000000000000007E
+:105E00000000000000000000000000000000000092
+:105E100000000000000000003C0380008C640000D3
+:105E2000308200201040FFFD3C0F60008DED08E047
+:105E30003C0E010001AE18241460FFE100000000D8
+:105E4000AF87003C03E00008AF8B00588F8500400F
+:105E5000240BFFF03C06800094A7001A8CA90024B4
+:105E600030ECFFFF000C38C000EB5024012A402129
+:105E7000ACC8003C8CA400248CC3003C00831023DD
+:105E800018400033000000008CAD002025A2000166
+:105E90003C0F0050ACC2003835EE00103C068000CC
+:105EA000ACCE003000000000000000000000000048
+:105EB00000000000000000000000000000000000E2
+:105EC000000000003C0480008C9900003338002062
+:105ED0001300FFFD30E20008104000173C0980006D
+:105EE0008C880408ACA800108C83040CACA30014AC
+:105EF0003C1900203C188000AF19003094AE001807
+:105F000094AF001C01CF3021A4A6001894AD001A54
+:105F100025A70001A4A7001A94AB001A94AC001E98
+:105F2000118B00030000000003E0000800000000E7
+:105F300003E00008A4A0001A8D2A0400ACAA0010F7
+:105F40008D240404ACA400140A0002183C1900209B
+:105F50008CA200200A0002003C0F00500A0001EE53
+:105F60000000000027BDFFE8AFBF00100E000232A6
+:105F7000000000008F8900408FBF00103C038000AC
+:105F8000A520000A9528000A9527000427BD0018BF
+:105F90003105FFFF30E6000F0006150000A22025A6
+:105FA00003E00008AC6400803C0508008CA50020DC
+:105FB0008F83000C27BDFFE8AFB00010AFBF001407
+:105FC00010A300100000802124040001020430040A
+:105FD00000A6202400C3102450440006261000010F
+:105FE000001018802787FDA41480000A006718217C
+:105FF000261000012E0900025520FFF38F83000CAC
+:10600000AF85000C8FBF00148FB0001003E00008B4
+:1060100027BD00188C6800003C058000ACA8002457
+:106020000E000234261000013C0508008CA500205B
+:106030000A0002592E0900022405000100851804F7
+:106040003C0408008C84002027BDFFC8AFBF00348B
+:1060500000831024AFBE0030AFB7002CAFB60028CD
+:10606000AFB50024AFB40020AFB3001CAFB200182E
+:10607000AFB1001410400051AFB000108F84004049
+:10608000948700069488000A00E8302330D5FFFF8B
+:1060900012A0004B8FBF0034948B0018948C000A20
+:1060A000016C50233142FFFF02A2482B1520000251
+:1060B00002A02021004020212C8F000515E00002C5
+:1060C00000809821241300040E0001C102602021E9
+:1060D0008F87004002609021AF80004494F4000A52
+:1060E000026080211260004E3291FFFF3C1670006A
+:1060F0003C1440003C1E20003C1760008F99005863
+:106100008F380000031618241074004F0283F82BF8
+:1061100017E0003600000000107E00478F86004424
+:1061200014C0003A2403000102031023022320219B
+:106130003050FFFF1600FFF13091FFFF8F870040C6
+:106140003C1100203C108000AE11003094EB000A9E
+:106150003C178000024B5021A4EA000A94E9000A8F
+:1061600094E800043123FFFF3106000F00062D00E4
+:106170000065F025AEFE008094F3000A94F6001846
+:1061800012D30036001221408CFF00148CF4001052
+:1061900003E468210000C02101A4782B029870213B
+:1061A00001CF6021ACED0014ACEC001002B238233A
+:1061B00030F5FFFF16A0FFB88F8400408FBF00347A
+:1061C0008FBE00308FB7002C8FB600288FB500240B
+:1061D0008FB400208FB3001C8FB200188FB1001451
+:1061E0008FB0001003E0000827BD00381477FFCC03
+:1061F0008F8600440E000EE202002021004018218C
+:106200008F86004410C0FFC9020310230270702360
+:106210008F87004001C368210A0002E431B2FFFF0A
+:106220008F86004414C0FFC93C1100203C10800040
+:106230000A0002AEAE1100300E00046602002021FA
+:106240000A0002DB00401821020020210E0009395B
+:10625000022028210A0002DB004018210E0001EE76
+:10626000000000000A0002C702B2382327BDFFC8A1
+:10627000AFB7002CAFB60028AFB50024AFB40020F4
+:10628000AFB3001CAFB20018AFB10014AFB0001034
+:10629000AFBF00300E00011B241300013C047FFF40
+:1062A0003C0380083C0220003C010800AC20007048
+:1062B0003496FFFF34770080345200033C1512C03F
+:1062C000241400013C1080002411FF800E000245C0
+:1062D000000000008F8700488F8B00188F89001402
+:1062E0008CEA00EC8CE800E8014B302B01092823F4
+:1062F00000A6102314400006014B18231440000E82
+:106300003C05800002A3602B1180000B0000000000
+:106310003C0560008CEE00EC8CED00E88CA4180CC1
+:10632000AF8E001804800053AF8D00148F8F0010C3
+:10633000ADF400003C0580008CBF00003BF900017B
+:10634000333800011700FFE13C0380008C6201003C
+:1063500024060C0010460009000000008C680100B3
+:106360002D043080548000103C0480008C690100B2
+:106370002D2331811060000C3C0480008CAA0100A8
+:1063800011460004000020218CA6010024C5FF81D5
+:1063900030A400FF8E0B01000E000269AE0B00243A
+:1063A0000A00034F3C0480008C8D01002DAC3300AB
+:1063B00011800022000000003C0708008CE70098D4
+:1063C00024EE00013C010800AC2E00983C04800043
+:1063D0008C8201001440000300000000566000148D
+:1063E0003C0440008C9F01008C9801000000982123
+:1063F00003F1C82400193940330F007F00EF7025E6
+:1064000001D26825AC8D08308C8C01008C85010090
+:10641000258B0100017130240006514030A3007F1C
+:106420000143482501324025AC8808303C04400037
+:10643000AE0401380A00030E000000008C99010030
+:10644000240F0020AC99002092F80000330300FFD5
+:10645000106F000C241F0050547FFFDD3C048000AF
+:106460008C8401000E00154E000000000A00034F4E
+:106470003C04800000963824ACA7180C0A000327BF
+:106480008F8F00108C8501000E0008F72404008017
+:106490000A00034F3C04800000A4102B24030001D9
+:1064A00010400009000030210005284000A4102BF6
+:1064B00004A00003000318405440FFFC00052840DE
+:1064C0005060000A0004182B0085382B54E00004AB
+:1064D0000003184200C33025008520230003184222
+:1064E0001460FFF9000528420004182B03E000089F
+:1064F00000C310213084FFFF30C600FF3C0780003E
+:106500008CE201B80440FFFE00064C000124302557
+:106510003C08200000C820253C031000ACE00180AE
+:10652000ACE50184ACE4018803E00008ACE301B809
+:106530003C0660008CC5201C2402FFF03083020062
+:10654000308601001060000E00A2282434A500014E
+:106550003087300010E0000530830C0034A50004C3
+:106560003C04600003E00008AC85201C1060FFFDC7
+:106570003C04600034A5000803E00008AC85201C42
+:1065800054C0FFF334A500020A0003B03087300086
+:1065900027BDFFE8AFB00010AFBF00143C0760009C
+:1065A000240600021080001100A080218F83005873
+:1065B0000E0003A78C6400188F8200580000202171
+:1065C000240600018C45000C0E000398000000001A
+:1065D0001600000224020003000010218FBF0014E7
+:1065E0008FB0001003E0000827BD00188CE8201CC5
+:1065F0002409FFF001092824ACE5201C8F870058EE
+:106600000A0003CD8CE5000C3C02600E00804021A6
+:1066100034460100240900180000000000000000BA
+:10662000000000003C0A00503C0380003547020097
+:10663000AC68003834640400AC65003CAC670030E2
+:106640008C6C0000318B00201160FFFD2407FFFFE0
+:106650002403007F8C8D00002463FFFF248400044A
+:10666000ACCD00001467FFFB24C60004000000004E
+:10667000000000000000000024A402000085282B78
+:106680003C0300203C0E80002529FFFF010540212E
+:10669000ADC300301520FFE00080282103E0000892
+:1066A000000000008F82005827BDFFD8AFB3001C48
+:1066B000AFBF0020AFB20018AFB10014AFB00010F0
+:1066C00094460002008098218C5200182CC300814F
+:1066D0008C4800048C4700088C51000C8C49001039
+:1066E000106000078C4A00142CC4000414800013AE
+:1066F00030EB000730C5000310A0001000000000C0
+:106700002410008B02002021022028210E00039873
+:10671000240600031660000224020003000010217A
+:106720008FBF00208FB3001C8FB200188FB10014F0
+:106730008FB0001003E0000827BD00281560FFF1AE
+:106740002410008B3C0C80003C030020241F00011F
+:10675000AD830030AF9F0044000000000000000047
+:10676000000000002419FFF024D8000F031978243A
+:106770003C1000D0AD88003801F0702524CD000316
+:106780003C08600EAD87003C35850400AD8E0030BE
+:10679000000D38823504003C3C0380008C6B000007
+:1067A000316200201040FFFD0000000010E00008F2
+:1067B00024E3FFFF2407FFFF8CA800002463FFFFF2
+:1067C00024A50004AC8800001467FFFB24840004A7
+:1067D0003C05600EACA60038000000000000000080
+:1067E000000000008F8600543C0400203C0780001D
+:1067F000ACE4003054C000060120202102402021DA
+:106800000E0003A7000080210A00041D02002021C1
+:106810000E0003DD01402821024020210E0003A7C5
+:10682000000080210A00041D0200202127BDFFE096
+:10683000AFB200183092FFFFAFB10014AFBF001C21
+:10684000AFB000101640000D000088210A0004932C
+:106850000220102124050003508500278CE5000C40
+:106860000000000D262800013111FFFF24E2002066
+:106870000232802B12000019AF8200588F82004430
+:10688000144000168F8700583C0670003C0320001F
+:106890008CE5000000A62024148300108F84006083
+:1068A000000544023C09800000A980241480FFE90F
+:1068B000310600FF2CCA000B5140FFEB26280001D7
+:1068C000000668803C0E080025CE575801AE6021B6
+:1068D0008D8B0000016000080000000002201021E4
+:1068E0008FBF001C8FB200188FB100148FB0001042
+:1068F00003E0000827BD00200E0003982404008454
+:106900001600FFD88F8700580A000474AF8000601B
+:10691000020028210E0003BF240400018F870058C5
+:106920000A000474AF820060020028210E0003BF39
+:10693000000020210A0004A38F8700580E000404E1
+:10694000020020218F8700580A000474AF82006083
+:1069500030AFFFFF000F19C03C0480008C9001B8DD
+:106960000600FFFE3C1920043C181000AC83018097
+:10697000AC800184AC990188AC9801B80A00047518
+:106980002628000190E2000390E30002000020218D
+:106990000002FE0000033A0000FF2825240600083C
+:1069A0000E000398000000001600FFDC2402000324
+:1069B0008F870058000010210A000474AF82006025
+:1069C00090E8000200002021240600090A0004C308
+:1069D00000082E0090E4000C240900FF308500FF21
+:1069E00010A900150000302190F9000290F8000372
+:1069F000308F00FF94EB000400196E000018740043
+:106A0000000F62000186202501AE5025014B28258C
+:106A10003084FF8B0A0004C32406000A90E30002BE
+:106A200090FF0004000020210003360000DF28252D
+:106A30000A0004C32406000B0A0004D52406008BB8
+:106A4000000449C23127003F000443423C02800059
+:106A500000082040240316802CE60020AC43002CC4
+:106A600024EAFFE02482000114C0000330A900FFE3
+:106A700000801021314700FF000260803C0D800043
+:106A8000240A0001018D20213C0B000E00EA28049D
+:106A9000008B302111200005000538278CCE000026
+:106AA00001C5382503E00008ACC700008CD8000001
+:106AB0000307782403E00008ACCF000027BDFFE007
+:106AC000AFB10014AFB00010AFBF00183C076000BA
+:106AD0008CE408083402F0003C1160003083F000C0
+:106AE000240501C03C04800E000030211062000625
+:106AF000241000018CEA08083149F0003928E00030
+:106B00000008382B000780403C0D0200AE2D081411
+:106B1000240C16803C0B80008E2744000E000F8B47
+:106B2000AD6C002C120000043C02169124050001FB
+:106B3000120500103C023D2C345800E0AE384408E9
+:106B40003C1108008E31007C8FBF00183C066000AD
+:106B500000118540360F16808FB100148FB00010E1
+:106B60003C0E020027BD0020ACCF442003E000080B
+:106B7000ACCE08103C0218DA345800E0AE384408B5
+:106B80003C1108008E31007C8FBF00183C0660006D
+:106B900000118540360F16808FB100148FB00010A1
+:106BA0003C0E020027BD0020ACCF442003E00008CB
+:106BB000ACCE08100A0004EB240500010A0004EB27
+:106BC0000000282124020400A7820024A780001CC2
+:106BD000000020213C06080024C65A582405FFFF67
+:106BE00024890001000440803124FFFF01061821A0
+:106BF0002C87002014E0FFFAAC6500002404040098
+:106C0000A7840026A780001E000020213C06080063
+:106C100024C65AD82405FFFF248D0001000460809B
+:106C200031A4FFFF018658212C8A00201540FFFA6D
+:106C3000AD650000A7800028A7800020A780002263
+:106C4000000020213C06080024C65B582405FFFFF5
+:106C5000249900010004C0803324FFFF030678213B
+:106C60002C8E000415C0FFFAADE500003C05600065
+:106C70008CA73D002403E08F00E31024344601403C
+:106C800003E00008ACA63D002487007F000731C266
+:106C900024C5FFFF000518C2246400013082FFFFF5
+:106CA000000238C0A78400303C010800AC27003047
+:106CB000AF80002C0000282100002021000030219E
+:106CC0002489000100A728213124FFFF2CA81701E7
+:106CD000110000032C8300801460FFF924C600011A
+:106CE00000C02821AF86002C10C0001DA786002AF6
+:106CF00024CAFFFF000A11423C08080025085B581F
+:106D00001040000A00002021004030212407FFFF2E
+:106D1000248E00010004688031C4FFFF01A86021B7
+:106D20000086582B1560FFFAAD87000030A2001FC7
+:106D30005040000800043080240300010043C804D0
+:106D400000041080004878212738FFFF03E0000886
+:106D5000ADF8000000C820212405FFFFAC8500002D
+:106D600003E000080000000030A5FFFF30C6FFFF71
+:106D700030A8001F0080602130E700FF0005294295
+:106D80000000502110C0001D24090001240B000147
+:106D900025180001010B2004330800FF0126782686
+:106DA000390E00202DED00012DC2000101A2182591
+:106DB0001060000D014450250005C880032C4021BF
+:106DC0000100182110E0000F000A20278D040000A8
+:106DD000008A1825AD03000024AD00010000402109
+:106DE0000000502131A5FFFF252E000131C9FFFF12
+:106DF00000C9102B1040FFE72518000103E0000830
+:106E0000000000008D0A0000014440240A0005D162
+:106E1000AC68000027BDFFE830A5FFFF30C6FFFFCC
+:106E2000AFB00010AFBF001430E7FFFF00005021EB
+:106E30003410FFFF0000602124AF001F00C0482174
+:106E4000241800012419002005E0001601E010219B
+:106E50000002F943019F682A0009702B01AE40240B
+:106E600011000017000C18800064102110E00005CC
+:106E70008C4B000000F840040008382301675824B8
+:106E800000003821154000410000402155600016E7
+:106E90003169FFFF258B0001316CFFFF05E1FFEC3D
+:106EA00001E0102124A2003E0002F943019F682A5C
+:106EB0000009702B01AE40241500FFEB000C188078
+:106EC000154600053402FFFF020028210E0005B51B
+:106ED00000003821020010218FBF00148FB0001075
+:106EE00003E0000827BD00181520000301601821E9
+:106EF000000B1C0224080010306A00FF154000053A
+:106F0000306E000F250D000800031A0231A800FFA3
+:106F1000306E000F15C00005307F000325100004FF
+:106F200000031902320800FF307F000317E000055C
+:106F3000386900012502000200031882304800FF72
+:106F4000386900013123000110600004310300FFA3
+:106F5000250A0001314800FF310300FF000C6940A1
+:106F600001A34021240A000110CAFFD53110FFFF00
+:106F7000246E000131C800FF1119FFC638C9000195
+:106F80002D1F002053E0001C258B0001240D000163
+:106F90000A000648240E002051460017258B0001E8
+:106FA00025090001312800FF2D0900205120001281
+:106FB000258B000125430001010D5004014B1024D5
+:106FC000250900011440FFF4306AFFFF3127FFFF5D
+:106FD00010EE000C2582FFFF304CFFFF0000502117
+:106FE0003410FFFF312800FF2D0900205520FFF24B
+:106FF00025430001258B0001014648260A000602B0
+:10700000316CFFFF00003821000050210A000654B7
+:107010003410FFFF27BDFFD8AFB0001030F0FFFFE6
+:10702000AFB10014001039423211FFE000071080A8
+:10703000AFB3001C00B1282330D3FFFFAFB200185C
+:1070400030A5FFFF00809021026030210044202104
+:10705000AFBF00200E0005E03207001F022288218A
+:107060003403FFFF0240202102002821026030216A
+:1070700000003821104300093231FFFF02201021A7
+:107080008FBF00208FB3001C8FB200188FB1001487
+:107090008FB0001003E0000827BD00280E0005E0B7
+:1070A0000000000000408821022010218FBF002036
+:1070B0008FB3001C8FB200188FB100148FB0001076
+:1070C00003E0000827BD0028000424003C03600002
+:1070D000AC603D0810A00002348210063482101605
+:1070E00003E00008AC623D0427BDFFE0AFB0001034
+:1070F000309000FF2E020006AFBF001810400008BD
+:10710000AFB10014001030803C03080024635784A2
+:1071100000C328218CA400000080000800000000AB
+:10712000000020218FBF00188FB100148FB0001015
+:107130000080102103E0000827BD00209791002A5D
+:1071400016200051000020213C020800904200332C
+:107150000A0006BB00000000978D002615A0003134
+:10716000000020210A0006BB2402000897870024A3
+:1071700014E0001A00001821006020212402000100
+:107180001080FFE98FBF0018000429C2004530219C
+:1071900000A6582B1160FFE43C0880003C0720004B
+:1071A000000569C001A76025AD0C00203C038008E4
+:1071B0002402001F2442FFFFAC6000000441FFFDD9
+:1071C0002463000424A5000100A6702B15C0FFF560
+:1071D000000569C00A0006A58FBF00189787001C2C
+:1071E0003C04080024845A58240504000E0006605C
+:1071F00024060001978B002424440001308AFFFFFD
+:107200002569FFFF2D48040000402821150000409B
+:10721000A789002424AC3800000C19C00A0006B964
+:10722000A780001C9787001E3C04080024845AD8BD
+:10723000240504000E00066024060001979900262C
+:10724000244400013098FFFF272FFFFF2F0E04007A
+:107250000040882115C0002CA78F0026A780001EA3
+:107260003A020003262401003084FFFF0E00068D41
+:107270002C4500010011F8C027F00100001021C0CA
+:107280000A0006BB240200089785002E978700227B
+:107290003C04080024845B580E00066024060001AC
+:1072A0009787002A8F89002C2445000130A8FFFF12
+:1072B00024E3FFFF0109302B0040802114C0001897
+:1072C000A783002AA7800022978500300E000F7543
+:1072D00002002021244A05003144FFFF0E00068DE4
+:1072E000240500013C05080094A500320E000F752E
+:1072F00002002021244521003C0208009042003376
+:107300000A0006BB000521C00A0006F3A784001E80
+:1073100024AC3800000C19C00A0006B9A784001C70
+:107320000A00070DA7850022308400FF27BDFFE873
+:107330002C820006AFBF0014AFB000101040001543
+:1073400000A03821000440803C0308002463579CBF
+:10735000010328218CA40000008000080000000028
+:1073600024CC007F000751C2000C59C23170FFFFCE
+:107370002547C40030E5FFFF2784001C02003021B0
+:107380000E0005B52407000197860028020620217B
+:10739000A78400288FBF00148FB0001003E00008FE
+:1073A00027BD00183C0508008CA50030000779C2F5
+:1073B0000E00038125E4DF003045FFFF3C04080098
+:1073C00024845B58240600010E0005B52407000143
+:1073D000978E002A8FBF00148FB0001025CD0001BA
+:1073E00027BD001803E00008A78D002A0007C9C2C6
+:1073F0002738FF00001878C231F0FFFF3C04080076
+:1074000024845AD802002821240600010E0005B564
+:1074100024070001978D0026260E0100000E84002F
+:1074200025AC00013C0B6000A78C0026AD603D0838
+:1074300036040006000030213C0760008CE23D0469
+:10744000305F000617E0FFFD24C9000100061B00A5
+:10745000312600FF006440252CC50004ACE83D0443
+:1074600014A0FFF68FBF00148FB0001003E00008D7
+:1074700027BD0018000751C22549C8002406000195
+:10748000240700013C04080024845A580E0005B566
+:107490003125FFFF978700248FBF00148FB00010A5
+:1074A00024E6000127BD001803E00008A786002499
+:1074B0003C0660183C090800252900FCACC9502C8A
+:1074C0008CC850003C0580003C020002350700805B
+:1074D000ACC750003C04080024841FE03C030800B3
+:1074E00024631F98ACA50008ACA2000C3C01080066
+:1074F000AC2459A43C010800AC2359A803E00008BF
+:107500002402000100A030213C1C0800279C59AC3B
+:107510003C0C04003C0B0002008B3826008C4026FB
+:107520002CE200010007502B2D050001000A4880C5
+:107530003C030800246359A4004520250123182199
+:107540001080000300001021AC660000240200013E
+:1075500003E00008000000003C1C0800279C59AC18
+:107560003C0B04003C0A0002008A3026008B3826BF
+:107570002CC200010006482B2CE5000100094080C8
+:107580003C030800246359A4004520250103182169
+:1075900010800005000010213C0C0800258C1F986D
+:1075A000AC6C00002402000103E0000800000000B1
+:1075B0003C0900023C080400008830260089382677
+:1075C0002CC30001008028212CE400010083102539
+:1075D0001040000B000030213C1C0800279C59ACD7
+:1075E0003C0A80008D4E00082406000101CA68256F
+:1075F000AD4D00088D4C000C01855825AD4B000C9D
+:1076000003E0000800C010213C1C0800279C59AC76
+:107610003C0580008CA6000C0004202724020001F9
+:1076200000C4182403E00008ACA3000C3C020002D4
+:107630001082000B3C0560003C070400108700032B
+:107640000000000003E00008000000008CA908D042
+:10765000240AFFFD012A402403E00008ACA808D05A
+:107660008CA408D02406FFFE0086182403E000083E
+:10767000ACA308D03C05601A34A600108CC300806F
+:1076800027BDFFF88CC50084AFA3000093A40000C1
+:107690002402001010820003AFA5000403E00008DC
+:1076A00027BD000893A7000114E0001497AC000266
+:1076B00097B800023C0F8000330EFFFC01CF682119
+:1076C000ADA50000A3A000003C0660008CC708D058
+:1076D0002408FFFE3C04601A00E82824ACC508D04A
+:1076E0008FA300048FA200003499001027BD00086A
+:1076F000AF22008003E00008AF2300843C0B800031
+:10770000318AFFFC014B48218D2800000A00080C3B
+:10771000AFA8000427BDFFE8AFBF00103C1C080065
+:10772000279C59AC3C0580008CA4000C8CA2000462
+:107730003C0300020044282410A0000A00A31824DF
+:107740003C0604003C0400021460000900A610245A
+:107750001440000F3C0404000000000D3C1C080015
+:10776000279C59AC8FBF001003E0000827BD00180C
+:107770003C0208008C4259A40040F80900000000B7
+:107780003C1C0800279C59AC0A0008358FBF00102C
+:107790003C0208008C4259A80040F8090000000093
+:1077A0000A00083B000000003C0880008D0201B880
+:1077B0000440FFFE35090180AD2400003C031000A9
+:1077C00024040040AD250004A1240008A1260009DE
+:1077D000A527000A03E00008AD0301B83084FFFFCD
+:1077E0000080382130A5FFFF000020210A00084555
+:1077F000240600803087FFFF8CA400002406003898
+:107800000A000845000028218F8300788F860070C9
+:107810001066000B008040213C07080024E75B68ED
+:10782000000328C000A710218C440000246300013D
+:10783000108800053063000F5466FFFA000328C06B
+:1078400003E00008000010213C07080024E75B6CFF
+:1078500000A7302103E000088CC200003C03900028
+:1078600034620001008220253C038000AC640020CB
+:107870008C65002004A0FFFE0000000003E000086B
+:10788000000000003C0280003443000100832025FA
+:1078900003E00008AC44002027BDFFE0AFB10014B6
+:1078A0003091FFFFAFB00010AFBF001812200013DF
+:1078B00000A080218CA20000240400022406020003
+:1078C0001040000F004028210E0007250000000096
+:1078D00000001021AE000000022038218FBF0018E8
+:1078E0008FB100148FB0001000402021000028212B
+:1078F000000030210A00084527BD00208CA20000AE
+:10790000022038218FBF00188FB100148FB00010F3
+:107910000040202100002821000030210A000845F5
+:1079200027BD002000A010213087FFFF8CA5000498
+:107930008C4400000A000845240600068F83FD9C45
+:1079400027BDFFE8AFBF0014AFB00010906700087C
+:10795000008010210080282130E600400000202116
+:1079600010C000088C5000000E0000BD0200202155
+:10797000020020218FBF00148FB000100A000548BC
+:1079800027BD00180E0008A4000000000E0000BD76
+:1079900002002021020020218FBF00148FB00010B0
+:1079A0000A00054827BD001827BDFFE0AFB0001052
+:1079B0008F90FD9CAFBF001CAFB20018AFB1001498
+:1079C00092060001008088210E00087230D2000467
+:1079D00092040005001129C2A6050000348300406E
+:1079E000A20300050E00087C022020210E00054A9B
+:1079F0000220202124020001AE02000C02202821D6
+:107A0000A602001024040002A602001224060200AE
+:107A1000A60200140E000725A60200161640000F4D
+:107A20008FBF001C978C00743C0B08008D6B007896
+:107A30002588FFFF3109FFFF256A0001012A382B45
+:107A400010E00006A78800743C0F6006240E0016A4
+:107A500035ED0010ADAE00508FBF001C8FB2001886
+:107A60008FB100148FB0001003E0000827BD002084
+:107A700027BDFFE0AFB10014AFBF0018AFB00010DA
+:107A80001080000400A088212402008010820007DA
+:107A9000000000000000000D8FBF00188FB100141F
+:107AA0008FB0001003E0000827BD00200E00087210
+:107AB00000A020218F86FD9C0220202190C500057A
+:107AC0000E00087C30B000FF2403003E1603FFF1D7
+:107AD0003C0680008CC401780480FFFE34C801405D
+:107AE000240900073C071000AD11000002202021EE
+:107AF000A10900048FBF00188FB100148FB00010CF
+:107B0000ACC701780A0008C527BD002027BDFFE0EB
+:107B1000AFB00010AFBF0018AFB100143C10800030
+:107B20008E110020000000000E00054AAE04002067
+:107B3000AE1100208FBF00188FB100148FB000105D
+:107B400003E0000827BD00203084FFFF00803821BB
+:107B50002406003500A020210A0008450000282145
+:107B60003084FFFF008038212406003600A0202149
+:107B70000A0008450000282127BDFFD0AFB500242A
+:107B80003095FFFFAFB60028AFB40020AFBF002C88
+:107B9000AFB3001CAFB20018AFB10014AFB000100B
+:107BA00030B6FFFF12A000270000A0218F920058DE
+:107BB0008E4300003C0680002402004000033E0289
+:107BC00000032C0230E4007F006698241482001D1C
+:107BD00030A500FF8F8300682C68000A1100001098
+:107BE0008F8D0044000358803C0C0800258C57B84A
+:107BF000016C50218D4900000120000800000000A8
+:107C000002D4302130C5FFFF0E0008522404008446
+:107C1000166000028F920058AF8000688F8D00447C
+:107C20002659002026980001032090213314FFFFDD
+:107C300015A00004AF9900580295202B1480FFDC9A
+:107C400000000000028010218FBF002C8FB600289A
+:107C50008FB500248FB400208FB3001C8FB20018A2
+:107C60008FB100148FB0001003E0000827BD003072
+:107C70002407003414A70149000000009247000EB9
+:107C80008F9FFDA08F90FD9C24181600A3E700197C
+:107C90009242000D3C0880003C07800CA3E20018D3
+:107CA000964A00123C0D60003C117FFFA60A005C62
+:107CB000964400103623FFFF240200053099FFFF91
+:107CC000AE1900548E46001CAD1800288CEF000041
+:107CD0008DAE444801E6482601C93021AE06003881
+:107CE0008E05003824CB00013C0E7F00AE05003C21
+:107CF0008E0C003CAFEC0004AE0B00208E13002075
+:107D0000AE13001CA3E0001BAE03002CA3E2001284
+:107D10008E4A001424130050AE0A00348E0400343E
+:107D2000AFE400148E590018AE1900489258000CA8
+:107D3000A218004E920D000835AF0020A20F0008D7
+:107D40008E090018012E282434AC4000AE0C001817
+:107D5000920B0000317200FF1253027F2403FF8058
+:107D60003C04080024845BE80E0008AA0000000020
+:107D70003C1108008E315BE80E00087202202021C1
+:107D80002405000424080001A2050025022020216A
+:107D90000E00087CA20800053C0580008CB001782C
+:107DA0000600FFFE8F92005834AE0140240F0002FF
+:107DB0003C091000ADD10000A1CF0004ACA90178AE
+:107DC0000A000962AF8000682CAD003751A0FF9413
+:107DD0008F8D0044000580803C110800263157E05B
+:107DE000021178218DEE000001C0000800000000A3
+:107DF0002411000414B1008C3C0780003C080800EA
+:107E00008D085BE88F86FD9CACE800208E4500085D
+:107E10008F99FDA0240D0050ACC500308E4C000899
+:107E2000ACCC00508E4B000CACCB00348E43001019
+:107E3000ACC300388E4A0010ACCA00548E42001405
+:107E4000ACC2003C8E5F0018AF3F00048E50001C97
+:107E5000ACD0002090C40000309800FF130D024AFF
+:107E6000000000008CC400348CD00030009030231F
+:107E700004C000F12404008C126000EE2402000310
+:107E80000A000962AF8200682419000514B900666F
+:107E90003C0580003C0808008D085BE88F86FD9C4F
+:107EA000ACA800208E4C00048F8AFDA0240720007F
+:107EB000ACCC001C924B000824120008A14B001906
+:107EC0008F82005890430009A14300188F85005805
+:107ED00090BF000A33E400FF1092001028890009C7
+:107EE000152000BA240E0002240D0020108D000B76
+:107EF000340780002898002117000008240740005C
+:107F000024100040109000053C0700012419008057
+:107F1000109900023C070002240740008CC20018A0
+:107F20003C03FF00004350240147F825ACDF001854
+:107F300090B2000BA0D200278F8300589464000CED
+:107F4000108001FE000000009467000C3C1F8000C0
+:107F50002405FFBFA4C7005C9063000E2407000443
+:107F6000A0C300088F820058904A000FA0CA0009E1
+:107F70008F8900588D3200108FE400740244C823AA
+:107F8000ACD900588D300014ACD0002C95380018B6
+:107F9000330DFFFFACCD00409531001A322FFFFFAB
+:107FA000ACCF00448D2E001CACCE00489128000EB2
+:107FB000A0C8000890CC000801855824126001B6C2
+:107FC000A0CB00088F9200580A000962AF870068B2
+:107FD0002406000614A600143C0E80003C0F080086
+:107FE0008DEF5BE88F85FD98ADCF00208E4900189E
+:107FF0008F86FD9C8F8BFDA0ACA900008CC800383B
+:1080000024040005ACA800048CCC003C1260008164
+:10801000AD6C00000A000962AF84006824110007FB
+:1080200010B1004B240400063C05080024A55BE8C1
+:108030000E000881240400818F9200580013102B39
+:108040000A000962AF820068241F002314BFFFF6F4
+:108050003C0C80003C0508008CA55BE88F8BFDA0E4
+:10806000AD8500208F91FD9C8E4600042564002084
+:1080700026450014AE260028240600030E000F81BA
+:10808000257000308F87005802002021240600034D
+:108090000E000F8124E500083C04080024845BE8FE
+:1080A0000E0008AA0000000092230000240A0050DD
+:1080B000306200FF544AFFE18F9200580E000F6CAF
+:1080C000000000000A000A6A8F920058240800335A
+:1080D00014A800323C0380003C1108008E315BE89C
+:1080E0008F8FFDA0AC7100208E420008240D002867
+:1080F0008F89FD9CADE200308E4A000C24060009F9
+:10810000ADEA00348E5F0010ADFF00388E440014DD
+:10811000ADE400208E590018ADF900248E58001CE3
+:10812000ADF80028A1ED00118E4E00041260003160
+:10813000AD2E00288F9200580A000962AF860068B1
+:10814000240D002214ADFFB8000000002404000735
+:108150003C1008008E105BE83C188000AF10002037
+:108160005660FEAEAF8400683C04080024845BE8DF
+:108170000E0008AA241300508F84FD9C90920000EA
+:10818000325900FF1333014B000000008F9200585A
+:10819000000020210A000962AF8400683C05080045
+:1081A00024A55BE80E000858240400810A000A6A2E
+:1081B0008F92005802D498213265FFFF0E000852BA
+:1081C000240400840A0009628F920058108EFF5325
+:1081D000240704002887000310E00179241100041B
+:1081E000240F0001548FFF4D240740000A000A228B
+:1081F000240701003C05080024A55BE80E0008A444
+:10820000240400828F920058000030210A00096285
+:10821000AF8600683C04080024845BE88CC2003808
+:108220000E0008AA8CC3003C8F9200580A000AC0B6
+:1082300000002021240400823C05080024A55BE8FE
+:108240000E0008A4000000008F92005800001021CA
+:108250000A000962AF8200688E5000048F91FD9C75
+:108260003C078000ACF00020922C00050200282181
+:10827000318B0002156001562404008A8F92FDA004
+:108280002404008D9245001B30A6002014C001502C
+:1082900002002821922E00092408001231C900FF93
+:1082A0001128014B240400810E00087202002021D5
+:1082B0009258001B240F000402002021370D0042B9
+:1082C000A24D001B0E00087CA22F00253C0580005B
+:1082D0008CA401780480FFFE34B90140241F000201
+:1082E000AF300000A33F00048F9200583C101000F4
+:1082F000ACB001780A000A6B0013102B8E500004FA
+:108300008F91FD9C3C038000AC700020922A0005F8
+:108310000200282131420002144000172404008A80
+:10832000922C00092412000402002821318B00FF46
+:1083300011720011240400810E0008720200202135
+:108340008F89FDA0240800122405FFFE912F001B39
+:108350000200202135EE0020A12E001BA2280009DA
+:108360009226000500C538240E00087CA2270005CF
+:1083700002002821000020210E0009330000000027
+:108380000A000A6A8F9200588E4C00043C07800055
+:108390003C10080026105BE8ACEC00203C01080013
+:1083A000AC2C5BE8924B0003317100041220013BBE
+:1083B0008F84FD9C24020006A0820009924F001BBE
+:1083C000240EFFC031E9003F012E4025A08800089F
+:1083D0009245000330A6000114C0013200000000E5
+:1083E0008E420008AE0200083C0208008C425BF09E
+:1083F000104001318F90FDA0000219C28F8DFD9CAD
+:10840000A603000C8E4A000C24180001240400145A
+:10841000AE0A002C8E420010AE02001C965F0016C1
+:10842000A61F003C96590014A619003EADB8000CDA
+:10843000A5B80010A5B80012A5B80014A5B800167C
+:1084400012600144A2040011925100033232000272
+:108450002E5300018F920058266200080A0009621C
+:10846000AF8200688E4400043C1980003C068008FE
+:10847000AF2400208E45000890D80000240D005045
+:10848000331100FF122D009C2407008824060009E8
+:108490000E000845000000000A000A6A8F9200588A
+:1084A0008E5000043C0980003C118008AD30002053
+:1084B0009228000024050050310400FF10850110AF
+:1084C0002407008802002021000028210E00084512
+:1084D0002406000E922D00002418FF80020028219F
+:1084E00001B8802524040004240600300E0007256E
+:1084F000A23000000A000A6A8F9200588E500004D1
+:108500008F91FDA03C028000AC500020923F001BE8
+:1085100033F900101320006C240700810200202191
+:10852000000028212406001F0E000845000000005E
+:108530000A000A6A8F9200588E44001C0E00085DE3
+:1085400000000000104000E3004048218F880058E0
+:1085500024070089012020218D05001C240600012C
+:108560000E000845000000000A000A6A8F920058B9
+:10857000964900023C10080026105BE831280004F0
+:10858000110000973C0460008E4E001C3C0F8000E0
+:10859000ADEE00203C010800AC2E5BE896470002DF
+:1085A00030E40001148000E6000000008E42000468
+:1085B000AE0200083C1008008E105BF0120000ECC8
+:1085C0003C0F80008F92FD9C241000018E4E0018FD
+:1085D0008F8DFDA08F9FFD9801CF4825AE490018D3
+:1085E000A2400005AE50000C3C0808008D085BF06E
+:1085F0008F840058A6500010000839C2A6500012FF
+:10860000A6500014A6500016A5A7000C8C8C0008DC
+:108610008F8B00588F8A0058ADAC002C8D63000CF6
+:1086200024070002ADA3001C91460010A1A6001172
+:108630008F82005890450011A3E500088F990058DB
+:1086400093380012A258004E8F910058922F0013B9
+:10865000A1AF00128F920058964E0014A5AE003CB8
+:1086600096490016A5A9003E8E480018ADA8001432
+:108670005660FD6AAF8700683C05080024A55BE8EA
+:108680000E000881000020218F9200580000382140
+:108690000A000962AF8700683C05080024A55BE872
+:1086A0000E0008A4240400828F9200580A000A4D8C
+:1086B000000038210E000F6C000000008F9200585F
+:1086C0000A000AC0000020210E00087202002021CA
+:1086D0009223001B02002021346A00100E00087C47
+:1086E000A22A001B000038210200202100002821BE
+:1086F0000A000BA52406001F9242000C305F000107
+:1087000013E0000300000000964A000EA4CA002CEB
+:10871000924B000C316300025060000600003821CB
+:108720008E470014964C0012ACC7001CA4CC001A53
+:10873000000038210A000B7F240600093C050800D0
+:1087400024A55BE80E0008A42404008B8F92005837
+:108750000A000A4D0013382B3C0C08008D8C5BE896
+:1087600024DFFFFE25930100326B007F016790211B
+:1087700002638824AD110028AE4600E0AE4000E45C
+:108780000A0009B3AE5F001CACC000543C0D0800E9
+:108790008DAD5BE83C18800C37090100ACED00287A
+:1087A0008E510014AD3100E08E4F0014AD2F00E467
+:1087B0008E4E001025C7FFFE0A0009F4AD27001CED
+:1087C0005491FDD6240740000A000A222407100015
+:1087D0000E00092D000000000A000A6A8F9200585E
+:1087E0008C83442C3C12DEAD3651BEEF3C010800B8
+:1087F000AC205BE810710062000000003C196C6264
+:1088000037387970147800082404000297850074C2
+:108810009782006C2404009200A2F82B13E0001948
+:1088200002002821240400020E00069524050200FF
+:108830003C068000ACC200203C010800AC225BE892
+:108840001040000D8F8C0058240A002824040003D7
+:10885000918B0010316300FF546A00012404000171
+:108860000E0000810000000010400004240400837A
+:108870000A000BC28F920058240400833C050800B4
+:1088800024A55BE80E000881000000008F920058CC
+:108890000013382B0A000962AF8700680A000B49F1
+:1088A000240200128E4400080E00085D0000000043
+:1088B0000A000B55AE0200083C05080024A55BE841
+:1088C0000E000858240400878F9200580A000B728B
+:1088D0000013102B240400040E000695240500301C
+:1088E0001440002A004048218F8800582407008344
+:1088F000012020218D05001C0A000BB32406000175
+:108900008F8300788F8600701066FEEE000038219D
+:108910003C07080024E75B6C000320C00087282187
+:108920008CAE000011D0005D246F000131E3000F18
+:108930005466FFFA000320C00A000B8C00003821A7
+:108940008E4400040E00085D000000000A000BC801
+:10895000AE0200083C05080024A55BE80E0008A450
+:10896000240400828F9200580A000B72000010212C
+:108970003C05080024A55BE80A000C7C2404008761
+:108980008C83442C0A000C5B3C196C628F88005865
+:108990003C0780083C0C8000240B0050240A000196
+:1089A000AD820020A0EB0000A0EA000191030004CA
+:1089B000A0E3001891040005A0E400199106000648
+:1089C0003C04080024845B6CA0E6001A91020007B6
+:1089D0003C06080024C65B68A0E2001B9105000865
+:1089E000A0E5001C911F0009A0FF001D9119000ABD
+:1089F000A0F9001E9118000BA0F8001F9112000CA6
+:108A0000A0F200209111000DA0F100219110000EA4
+:108A1000A0F00022910F000FA0EF0023910E001094
+:108A2000A0EE0024910D0011A0ED0025950C00147E
+:108A3000A4EC0028950B00168F8A00708F920078A6
+:108A4000A4EB002A95030018000A10C02545000178
+:108A5000A4E3002C8D1F001C0044C0210046C82147
+:108A600030A5000FAF3F0000AF09000010B20006B4
+:108A7000AF850070000038218D05001C01202021E9
+:108A80000A000BB32406000124AD000131A7000F3A
+:108A9000AF8700780A000CF9000038213C06080076
+:108AA00024C65B680086902100003821ACA000003D
+:108AB0000A000B8CAE4000003C0482013C036000C5
+:108AC00034820E02AC603D68AF80009803E000087D
+:108AD000AC623D6C27BDFFE8AFB000103090FFFFE7
+:108AE000001018422C620041AFBF00141440000275
+:108AF00024040080240300403C010800AC300060E6
+:108B00003C010800AC2300640E000F7500602821B2
+:108B1000244802BF2409FF8001092824001039805D
+:108B2000001030408FBF00148FB0001000A720212C
+:108B300000861821AF8300803C010800AC25005856
+:108B40003C010800AC24005C03E0000827BD0018CD
+:108B5000308300FF30C6FFFF30E400FF3C08800098
+:108B60008D0201B80440FFFE000354000144382583
+:108B70003C09600000E920253C031000AD050180A0
+:108B8000AD060184AD04018803E00008AD0301B81F
+:108B90008F8500583C0A6012354800108CAC0004E8
+:108BA0003C0D600E35A60010318B00062D690001CA
+:108BB000AD0900C48CA70004ACC731808CA20008AA
+:108BC00094A40002ACC231848CA3001C0460000396
+:108BD000A784009003E00008000000008CAF00189C
+:108BE000ACCF31D08CAE001C03E00008ACCE31D449
+:108BF0008F8500588F87FF288F86FF308CAE00044A
+:108C00003C0F601235E80010ACEE00788CAD000827
+:108C1000ACED007C8CAC0010ACCC004C8CAB000CF0
+:108C2000ACCB004894CA00543C0208008C4200447B
+:108C300025490001A4C9005494C400543083FFFFA7
+:108C400010620017000000003C0208008C42004047
+:108C5000A4C200528CA30018ACE300308CA2001414
+:108C6000ACE2002C8CB90018ACF900388CB80014B8
+:108C700024050001ACF800348D0600BC50C5001975
+:108C80008D0200B48D0200B8A4E2004894E40048CC
+:108C9000A4E4004A94E800EA03E000083102FFFF80
+:108CA0003C0208008C420024A4C00054A4C200521C
+:108CB0008CA30018ACE300308CA20014ACE2002CB2
+:108CC0008CB90018ACF900388CB8001424050001E8
+:108CD000ACF800348D0600BC54C5FFEB8D0200B823
+:108CE0008D0200B4A4E2004894E40048A4E4004AE1
+:108CF00094E800EA03E000083102FFFF8F86005885
+:108D00003C0480008CC900088CC80008000929C0F8
+:108D1000000839C0AC87002090C30007306200040F
+:108D20001040003EAF85009490CB0007316A0008E8
+:108D30001140003D8F87FF2C8CCD000C8CCE001491
+:108D400001AE602B11800036000000008CC2000CC8
+:108D5000ACE200708CCB00188F85FF288F88FF3025
+:108D6000ACEB00748CCA00102402FFF8ACAA00D847
+:108D70008CC9000CAD0900608CC4001CACA400D0F0
+:108D800090E3007C0062C824A0F9007C90D8000722
+:108D9000330F000811E000040000000090ED007C9B
+:108DA00035AC0001A0EC007C90CF000731EE000153
+:108DB00011C000060000000090E3007C241800347D
+:108DC00034790002A0F9007CACB800DC90C2000746
+:108DD0003046000210C000040000000090E8007C53
+:108DE00035040004A0E4007C90ED007D3C0B600E97
+:108DF000356A001031AC003FA0EC007D8D4931D4C4
+:108E00003127000110E00002240E0001A0AE00098D
+:108E100094AF00EA03E0000831E2FFFF8F87FF2CE8
+:108E20000A000DAF8CC200140A000DB0ACE0007057
+:108E30008F8C005827BDFFD8AFB3001CAFB200180D
+:108E4000AFB00010AFBF0020AFB10014918F00157C
+:108E50003C13600E3673001031EB000FA38B009CA7
+:108E60008D8F00048D8B0008959F0012959900103E
+:108E70009584001A9598001E958E001C33EDFFFF17
+:108E8000332AFFFF3089FFFF3308FFFF31C7FFFFA1
+:108E90003C010800AC2D00243C010800AC29004432
+:108EA0003C010800AC2A0040AE683178AE67317CE6
+:108EB00091850015959100163C12601236520010F3
+:108EC00030A200FF3230FFFFAE623188AE5000B4F6
+:108ED00091830014959F0018240600010066C804C1
+:108EE00033F8FFFFAE5900B8AE5800BC918E0014A5
+:108EF000AF8F00843C08600631CD00FFAE4D00C04E
+:108F0000918A00159584000E3C07600A314900FFE4
+:108F1000AF8B00883084FFFFAE4900C835110010C8
+:108F20000E000D1034F004103C0208008C4200606A
+:108F30003C0308008C6300643C0608008CC60058A3
+:108F40003C0508008CA5005C8F8400808FBF00204A
+:108F5000AE23004CAE65319CAE030054AE4500DC40
+:108F6000AE6231A0AE6331A4AE663198AE22004845
+:108F70008FB3001CAE0200508FB10014AE4200E06F
+:108F8000AE4300E4AE4600D88FB000108FB2001898
+:108F90000A00057D27BD0028978500929783007CF5
+:108FA00027BDFFE8AFB0001000A3102BAFBF001427
+:108FB000240400058F900058104000552409000239
+:108FC0000E0006958F850080AF8200942404000374
+:108FD0001040004F240900023C0680000E00008172
+:108FE000ACC2002024070001240820001040004DDE
+:108FF00024040005978E00928F8AFF2C24090050CC
+:1090000025C50001A7850092A14900003C0D08007C
+:109010008DAD0064240380008F84FF28000D66005E
+:10902000AD4C0018A5400006954B000A8F85FF3017
+:109030002402FF8001633024A546000A915F000AE4
+:109040000000482103E2C825A159000AA0A0000899
+:10905000A140004CA08000D5961800029783009094
+:109060003C020004A49800EA960F00022418FFBFF7
+:1090700025EE2401A48E00BE8E0D0004ACAD00448C
+:109080008E0C0008ACAC0040A4A00050A4A000547A
+:109090008E0B000C240C0030AC8B00288E060010C8
+:1090A000AC860024A480003EA487004EA487005014
+:1090B000A483003CAD420074AC8800D8ACA800602A
+:1090C000A08700FC909F00D433F9007FA09900D4C2
+:1090D000909000D402187824A08F00D4914E007C88
+:1090E00035CD0001A14D007C938B009CAD480070F4
+:1090F000AC8C00DCA08B00D68F8800888F87008422
+:10910000AC8800C4AC8700C8A5400078A540007AB0
+:109110008FBF00148FB000100120102103E0000861
+:1091200027BD00188F8500940E0007258F860080CC
+:109130000A000E9F2409000227BDFFE0AFB0001017
+:109140008F900058AFB10014AFBF00188E09000413
+:109150000E00054A000921C08E0800048F84FF28F4
+:109160008F82FF30000839C03C068000ACC7002069
+:10917000948500EA904300131460001C30B1FFFF97
+:109180008F8CFF2C918B0008316A00401540000B3A
+:10919000000000008E0D0004022030218FBF001857
+:1091A0008FB100148FB00010240400220000382179
+:1091B000000D29C00A000D2F27BD00200E000098C9
+:1091C000000000008E0D0004022030218FBF001827
+:1091D0008FB100148FB00010240400220000382149
+:1091E000000D29C00A000D2F27BD00200E000090A1
+:1091F000000000008E0D0004022030218FBF0018F7
+:109200008FB100148FB00010240400220000382118
+:10921000000D29C00A000D2F27BD002027BDFFE04B
+:10922000AFB200183092FFFFAFB00010AFBF001C0C
+:10923000AFB100141240001E000080218F8600583C
+:109240008CC500002403000600053F02000514023F
+:1092500030E4000714830016304500FF2CA80006F8
+:1092600011000040000558803C0C0800258C58BCBB
+:10927000016C50218D490000012000080000000011
+:109280008F8E0098240D000111CD005024020002A1
+:10929000AF820098260900013130FFFF24C800206A
+:1092A0000212202B010030211480FFE5AF88005806
+:1092B000020010218FBF001C8FB200188FB1001464
+:1092C0008FB0001003E0000827BD00209387007EC8
+:1092D00054E00034000030210E000DE700000000D3
+:1092E0008F8600580A000EFF240200018F87009825
+:1092F0002405000210E50031240400130000282199
+:1093000000003021240700010E000D2F0000000096
+:109310000A000F008F8600588F83009824020002F5
+:109320001462FFF6240400120E000D9A00000000E3
+:109330008F85009400403021240400120E000D2F70
+:10934000000038210A000F008F8600588F83009894
+:109350002411000310710029241F0002107FFFCE8A
+:1093600026090001240400100000282100003021FB
+:109370000A000F1D240700018F91009824060002A7
+:109380001626FFF9240400100E000E410000000014
+:10939000144000238F9800588F8600580A000EFF53
+:1093A00024020003240400140E000D2F00002821C5
+:1093B0008F8600580A000EFF240200020E000EA93C
+:1093C000000000000A000F008F8600580E000D3FBD
+:1093D00000000000241900022404001400002821C9
+:1093E0000000302100003821AF9900980E000D2FA9
+:1093F000000000000A000F008F8600580E000D5775
+:10940000000000008F8500942419000200403021E4
+:1094100024040010000038210A000F56AF9900986C
+:109420000040382124040010970F0002000028217A
+:109430000E000D2F31E6FFFF8F8600580A000F0047
+:10944000AF9100988F84FF2C3C077FFF34E6FFFF2D
+:109450008C8500182402000100A61824AC83001893
+:1094600003E00008A08200053084FFFF30A5FFFF65
+:109470001080000700001821308200011040000217
+:1094800000042042006518211480FFFB00052840DD
+:1094900003E000080060102110C000070000000079
+:1094A0008CA2000024C6FFFF24A50004AC820000AB
+:1094B00014C0FFFB2484000403E000080000000047
+:1094C00010A0000824A3FFFFAC86000000000000ED
+:1094D000000000002402FFFF2463FFFF1462FFFA74
+:1094E0002484000403E0000800000000000411C010
+:1094F00003E000082442024027BDFFE8AFB000109F
+:1095000000808021AFBF00140E000F9600A0202124
+:1095100000504821240AFF808FBF00148FB0001034
+:10952000012A30243127007F3C08800A3C042100B6
+:1095300000E8102100C428253C03800027BD001846
+:10954000AC650024AF820038AC400000AC6500245C
+:1095500003E00008AC4000403C0D08008DAD005811
+:1095600000056180240AFF8001A45821016C482174
+:10957000012A30243127007F3C08800C3C04210064
+:1095800000E8102100C428253C038000AC650028B9
+:10959000AF82003403E00008AC40002430A5FFFF98
+:1095A0003C0680008CC201B80440FFFE3C086015F8
+:1095B00000A838253C031000ACC40180ACC0018475
+:1095C000ACC7018803E00008ACC301B83C0D08003B
+:1095D0008DAD005800056180240AFF8001A4582148
+:1095E000016C4021010A4824000931403107007F05
+:1095F00000C728253C04200000A418253C02800058
+:10960000AC43083003E00008AF80003427BDFFE81A
+:10961000AFB0001000808021AFBF00140E000F9685
+:1096200000A0202100504821240BFF80012B502452
+:10963000000A39403128007F3C0620008FBF00140B
+:109640008FB0001000E8282534C2000100A21825C0
+:109650003C04800027BD0018AC83083003E00008FC
+:10966000AF8000383C0580088CA700603C0680086D
+:109670000087102B144000112C8340008CA8006040
+:109680002D0340001060000F240340008CC90060CF
+:109690000089282B14A00002008018218CC30060D0
+:1096A00000035A42000B30803C0A0800254A59202A
+:1096B00000CA202103E000088C8200001460FFF340
+:1096C0002403400000035A42000B30803C0A08008B
+:1096D000254A592000CA202103E000088C8200009E
+:1096E0003C05800890A60008938400AB24C20001CA
+:1096F000304200FF3043007F1064000C0002382726
+:10970000A0A200083C0480008C85017804A0FFFE24
+:109710008F8A00A0240900023C081000AC8A014096
+:10972000A089014403E00008AC8801780A00101BFE
+:1097300030E2008027BDFFD8AFB200188F9200A49E
+:10974000AFBF0020AFB3001CAFB00010AFB100142A
+:109750008F9300348E5900283C1000803C0EFFEFA0
+:10976000AE7900008E580024A260000A35CDFFFFBC
+:10977000AE7800049251002C3C0BFF9F356AFFFF2E
+:10978000A271000C8E6F000C3C080040A271000B0F
+:1097900001F06025018D4824012A382400E8302595
+:1097A000AE66000C8E450004AE6000183C0400FF5D
+:1097B000AE6500148E43002C3482FFFFA6600008C3
+:1097C0000062F824AE7F00108E5900088F9000A030
+:1097D000964E0012AE7900208E51000C31D83FFF1A
+:1097E00000187980AE7100248E4D001401F06021C4
+:1097F00031CB0001AE6D00288E4A0018000C41C22A
+:10980000000B4B80AE6A002C8E46001C01093821EB
+:10981000A667001CAE660030964500028E4400200C
+:10982000A665001EAE64003492430033306200042B
+:1098300054400006924700003C0280083443010077
+:109840008C7F00D0AE7F0030924700008F860038BA
+:10985000A0C700309245003330A4000250800007BA
+:10986000925100018F880038240BFF80910A00304C
+:10987000014B4825A1090030925100018F9000381A
+:10988000240CFFBF2404FFDFA21100318F8D0038AC
+:109890003C1880083711008091AF003C31EE007F0A
+:1098A000A1AE003C8F890038912B003C016C502404
+:1098B000A12A003C8F9F00388E68001493E6003C7C
+:1098C0002D0700010007114000C4282400A218251C
+:1098D000A3E3003C8F87003896590012A4F90032A8
+:1098E0008E450004922E007C30B0000300107823D7
+:1098F00031ED000300AD102131CC000215800002D3
+:1099000024460034244600303C0280083443008062
+:10991000907F007C00BFC824333800041700000289
+:1099200024C2000400C010218F98003824190002BE
+:10993000ACE20034A3190000924F003F8F8E003834
+:109940003C0C8008358B0080A1CF00018F9100383E
+:10995000924D003F8E440004A62D0002956A005CE3
+:109960000E000FF43150FFFF00024B800209382532
+:109970003C08420000E82825AE2500048E4400384B
+:109980008F850038ACA400188E460034ACA6001CAD
+:10999000ACA0000CACA00010A4A00014A4A0001661
+:1099A000A4A00020A4A00022ACA000248E62001479
+:1099B00050400001240200018FBF00208FB3001C23
+:1099C0008FB200188FB100148FB00010ACA2000845
+:1099D0000A00101327BD002827BDFFC83C058008DA
+:1099E00034A40080AFBF0034AFBE0030AFB7002C4E
+:1099F000AFB60028AFB50024AFB40020AFB3001C51
+:109A0000AFB20018AFB10014AFB00010948300786B
+:109A10009482007A104300512405FFFF0080F0215A
+:109A20000A0011230080B821108B004D8FBF003435
+:109A30008F8600A03C1808008F18005C2411FF805E
+:109A40003C1680000306782101F18024AED0002C62
+:109A500096EE007A31EC007F3C0D800E31CB7FFF1B
+:109A6000018D5021000B4840012AA82196A4000036
+:109A70003C0808008D0800582405FF8030953FFF02
+:109A800001061821001539800067C8210325F82434
+:109A90003C02010003E290253338007F3C11800C2A
+:109AA000AED20028031190219250000D320F000415
+:109AB00011E0003702E0982196E3007A96E8007AF8
+:109AC00096E5007A2404800031077FFF24E300013B
+:109AD00030627FFF00A4F82403E2C825A6F9007ACB
+:109AE00096E6007A3C1408008E94006030D67FFF22
+:109AF00012D400C1000000008E5800188F8400A00E
+:109B000002A028212713FFFF0E000FCEAE53002C1A
+:109B100097D5007897D4007A12950010000028217C
+:109B20003C098008352401003C0A8008914800085F
+:109B3000908700D53114007F30E400FF0284302B81
+:109B400014C0FFB9268B0001938E00AB268C000158
+:109B5000008E682115ACFFB78F8600A08FBF003440
+:109B60008FBE00308FB7002C8FB600288FB5002431
+:109B70008FB400208FB3001C8FB200188FB1001477
+:109B80008FB0001000A0102103E0000827BD0038AE
+:109B900000C020210E000F99028028218E4B00105A
+:109BA0008E4C00308F84003824090002016C502351
+:109BB000AE4A0010A089000096E3005C8E4400309D
+:109BC0008F9100380E000FF43070FFFF00024380C9
+:109BD000020838253C02420000E22825AE25000498
+:109BE0008E5F00048F8A00388E590000240B000815
+:109BF000AD5F001CAD590018AD40000CAD40001029
+:109C00009246000A240400052408C00030D000FF5A
+:109C1000A550001496580008A55800169251000A45
+:109C20003C188008322F00FFA54F0020964E0008F8
+:109C300037110100A54E0022AD400024924D000BCB
+:109C400031AC00FFA54C0002A14B00018E49003051
+:109C50008F830038240BFFBFAC690008A06400307C
+:109C60008F9000382403FFDF9607003200E8282495
+:109C700000B51025A6020032921F003233F9003FD2
+:109C800037260040A20600328F8C0038AD800034A9
+:109C90008E2F00D0AD8F0038918E003C3C0F7FFF9F
+:109CA00031CD007FA18D003C8F84003835EEFFFF61
+:109CB000908A003C014B4824A089003C8F850038E5
+:109CC00090A8003C01033824A0A7003C8E42003439
+:109CD0008F9100383C038008AE2200408E59002C42
+:109CE0008E5F0030033F3023AE26004492300048A0
+:109CF0003218007FA23800488F8800388E4D00301F
+:109D00008D0C004801AE582401965024014B482583
+:109D1000AD0900489244000AA104004C964700088F
+:109D20008F850038A4A7004E8E5000308E4400303E
+:109D30000E0003818C65006092F9007C0002F940FE
+:109D4000004028210002110003E2302133360002D6
+:109D500012C00003020680210005B0800216802197
+:109D6000926D007C31B30004126000020005708027
+:109D7000020E80218E4B00308F8800382405800031
+:109D8000316A0003000A4823312400030204182129
+:109D9000AD03003496E4007A96F0007A96F1007AEA
+:109DA00032027FFF2447000130FF7FFF0225C824D5
+:109DB000033F3025A6E6007A96F8007A3C120800A8
+:109DC0008E520060330F7FFF11F200180000000078
+:109DD0008F8400A00E000FCE02A028218F8400A047
+:109DE0000E000FDE028028210E001013000000007C
+:109DF0000A00111F0000000096F1007A022480245E
+:109E0000A6F0007A92EF007A92EB007A31EE00FF32
+:109E1000000E69C2000D6027000C51C03169007F3F
+:109E2000012A20250A001119A2E4007A96E6007A98
+:109E300000C5C024A6F8007A92EF007A92F3007A67
+:109E400031F200FF001271C2000E6827000DB1C090
+:109E5000326C007F01962825A2E5007A0A0011D015
+:109E60008F8400A03C0380003084FFFF30A5FFFFFB
+:109E7000AC640018AC65001C03E000088C620014A0
+:109E800027BDFFA03C068008AFBF005CAFBE0058F6
+:109E9000AFB70054AFB60050AFB5004CAFB40048F8
+:109EA000AFB30044AFB20040AFB1003CAFB0003838
+:109EB00034C80100910500D590C700083084FFFF29
+:109EC00030A500FF30E2007F0045182AAFA4001043
+:109ED000A7A00018A7A0002610600055AFA000148E
+:109EE00090CA00083149007F00A9302324D3FFFF26
+:109EF0000013802B8FB400100014902B02128824C2
+:109F0000522000888FB300143C03800894790052DB
+:109F1000947E00508FB60010033EC0230018BC0092
+:109F2000001714030016FC0002C2A82A16A00002A3
+:109F3000001F2C030040282100133C0000072403CD
+:109F400000A4102A5440000100A020212885000907
+:109F500014A000020080A021241400083C0C8008FA
+:109F60008D860048001459808D88004C3C03800089
+:109F70003169FFFF3C0A0010012A202534710400DA
+:109F8000AC660038AF9100A4AC68003CAC64003013
+:109F900000000000000000000000000000000000C1
+:109FA00000000000000000000000000000000000B1
+:109FB0008C6E000031CD002011A0FFFD0014782A26
+:109FC00001F01024104000390000A8213C16800840
+:109FD00092D700083C1280008E44010032F6007FC8
+:109FE0000E000F9902C028218E3900108E44010006
+:109FF0000000902133373FFF0E000FB102E028210F
+:10A00000923800003302003F2C500008520000102C
+:10A0100000008821000210803C030800246358E4FB
+:10A020000043F8218FFE000003C00008000000007C
+:10A0300090CF0008938C00AB31EE007F00AE682318
+:10A04000018D58210A0012172573FFFF0000882197
+:10A050003C1E80008FC401000E000FCE02E02821BC
+:10A060008FC401000E000FDE02C028211220000F55
+:10A070000013802B8F8B00A426A400010004AC00E9
+:10A08000027298230015AC032578004002B4B02A70
+:10A090000013802B241700010300882102D0102414
+:10A0A000AF9800A41440FFC9AFB700143C07800864
+:10A0B00094E200508FAE00103C05800002A288217F
+:10A0C0003C060020A4F10050ACA6003094F40050EF
+:10A0D00094EF005201D51823306CFFFF11F4001EDD
+:10A0E000AFAC00108CEF004C001561808CF500487F
+:10A0F00001EC28210000202100AC582B02A4C02133
+:10A10000030BB021ACE5004CACF600488FB4001056
+:10A110000014902B021288241620FF7C3C03800838
+:10A120008FB300148FBF005C8FBE00583A620001ED
+:10A130008FB700548FB600508FB5004C8FB40048D5
+:10A140008FB300448FB200408FB1003C8FB0003815
+:10A1500003E0000827BD006094FE00548CF2004428
+:10A1600033C9FFFE0009C8C00259F821ACBF003C4A
+:10A170008CE800448CAD003C010D50231940003B9D
+:10A18000000000008CF7004026E20001ACA200387D
+:10A190003C05005034A700103C038000AC67003041
+:10A1A00000000000000000000000000000000000AF
+:10A1B000000000000000000000000000000000009F
+:10A1C0008C7800003316002012C0FFFD3C1180087F
+:10A1D000962200543C1580003C068008304E000159
+:10A1E000000E18C0007578218DEC04003C070800B3
+:10A1F0008CE700443C040020ACCC00488DF40404FF
+:10A20000240B0001ACD4004C10EB0260AEA4003073
+:10A21000963900523C0508008CA5004000B99021F9
+:10A22000A6320052963F005427ED0001A62D00549F
+:10A230009626005430C4FFFF5487FF2F8FB40010C0
+:10A2400030A5FFFF0E0011F4A62000543C070800C3
+:10A250008CE70024963E00520047B82303D74823DA
+:10A26000A62900520A0012198FB400108CE2004097
+:10A270000A0012BE00000000922400012407000121
+:10A280003085007F14A7001C97AD00268E2B00148C
+:10A29000240CC000316A3FFF01AC48243C06080092
+:10A2A0008CC60060012A402531043FFF0086882BC0
+:10A2B00012200011A7A800263C0508008CA5005814
+:10A2C0008F9100A0000439802402FF8000B1182182
+:10A2D0000067F82103E2F02433F8007F3C1280008D
+:10A2E0003C19800EAE5E002C0319702191D0000D38
+:10A2F000360F0004A1CF000D0E001028241200011B
+:10A30000241100013C1E80008FC401000E000FCEFE
+:10A3100002E028218FC401000E000FDE02C02821B8
+:10A320001620FF558F8B00A40A0012860013802B85
+:10A330008F8600A490C80001310400201080019194
+:10A34000241000013C048008348B0080916A007C5A
+:10A350008F9E0034AFA0002C314900011120000F66
+:10A36000AFB000288CCD00148C8E006001AE602B45
+:10A370001580000201A038218C8700603C188008FD
+:10A38000370300808C70007000F0782B15E000021D
+:10A3900000E020218C640070AFA4002C3C028008F7
+:10A3A000344500808CD200148CBF0070025FC82B33
+:10A3B00017200002024020218CA400708FA7002CDF
+:10A3C0000087182310600003AFA3003024050002AB
+:10A3D000AFA500288FA400280264882B162000BA9D
+:10A3E000000018218CD000388FCE000C3C0F00806C
+:10A3F000AFD000008CCD00343C0CFF9F01CF58251E
+:10A40000AFCD000490CA003F3586FFFF01662024CF
+:10A410003C0900203C08FFEFA3CA000B0089382547
+:10A420003511FFFF00F118243C0500088F8700A4B8
+:10A430000065C825AFD9000C8CE20014AFC000182D
+:10A440008FA60030AFC200148CF800188FB0002C1B
+:10A450003C1FFFFBAFD8001C8CEF000837F2FFFF5A
+:10A4600003326824AFCF00248CEC000C020670216C
+:10A47000AFCD000CA7C00038A7C0003AAFCE002C6B
+:10A48000AFCC0020AFC000288CEA00148FAB002CAA
+:10A49000014B48230126402311000011AFC80010D2
+:10A4A00090EB003D8FC900048FC80000000B5100E5
+:10A4B000012A28210000102100AA882B010218215E
+:10A4C0000071F821AFC50004AFDF000090F2003D3D
+:10A4D000A3D2000A8F9900A497380006A7D80008D5
+:10A4E0008F910038240800023C038008A228000055
+:10A4F0003465008094BF005C8FA4002C33F0FFFF14
+:10A500000E000FF48F9200380002CB808F8500A4DC
+:10A51000021978253C18420001F87025AE4E00045F
+:10A520008F8400388CAD0038AC8D00188CAC0034B2
+:10A53000AC8C001CAC80000CAC800010A48000141B
+:10A54000A4800016A4800020A4800022AC800024F7
+:10A5500090A6003F8FA7002CA486000250E0019235
+:10A56000240700018FA200305040000290A2003D5D
+:10A5700090A2003E244A0001A08A00018F84003886
+:10A580008FA9002CAC8900083C128008364D008051
+:10A5900091AC007C3186000214C000022407003414
+:10A5A000240700308F8500A43C198008373F0080C5
+:10A5B00090B0000093F9007C240E0004A0900030BD
+:10A5C0008F8F00A48FB8002C8F8D003891F200017E
+:10A5D0003304000301C46023A1B200318F8E003820
+:10A5E0008F8600A42402C00095CA003294C90012CC
+:10A5F0008FAB002C0142402431233FFF010388250B
+:10A60000A5D1003291D000323185000300EBF82152
+:10A610003218003F370F0040A1CF00328FA4002C2A
+:10A6200003E5382133280004108000028F850038AC
+:10A6300000E838213C0A8008ACA700343549010005
+:10A640008D2800D08FA3002C2419FFBFACA80038A0
+:10A6500090B1003C2C640001240FFFDF3227007F03
+:10A66000A0A7003C8F98003800049140931F003C45
+:10A6700003F98024A310003C8F8C0038918E003C9D
+:10A6800001CF682401B23025A186003C8F8900A447
+:10A690008F8800388D2B0020AD0B00408D220024C8
+:10A6A000AD0200448D2A0028AD0A00488D23002CFD
+:10A6B0000E001013AD03004C8FB1002824070002D8
+:10A6C000122700118FA300280003282B00058023E8
+:10A6D0000270982400608021006090210A00126FAF
+:10A6E0000010882B962900128F8400A00000902172
+:10A6F0003125FFFFA7A900180E000FC22411000189
+:10A700000A00131D3C1E80003C0B80003C12800898
+:10A710008D640100924900088F92FF340E000F995A
+:10A720003125007F8F9900388FA700288FA4003033
+:10A73000A3270000965F005C33F0FFFF0E000FF4CC
+:10A740008F91003800026B80020D80253C0842008A
+:10A750008F8D00A402085025AE2A00048DA5003874
+:10A760008F8A003800007821000F1100AD450018D5
+:10A770008DB800343C047FFF3488FFFFAD58001CC7
+:10A7800091A6003E8D4C001C8D4900180006190052
+:10A79000000677020183C821004E58250323882B29
+:10A7A000012B382100F1F821AD59001CAD5F0018D4
+:10A7B000AD40000CAD40001091B0003E8FA40030C1
+:10A7C00024090005A550001495A500042419C00013
+:10A7D00000884024A545001691B8003EA5580020E9
+:10A7E00095AF0004A54F0022AD40002491AE003F7C
+:10A7F000A54E000291A6003E91AC003D01861023BB
+:10A80000244B0001A14B00018F9100388FA3003031
+:10A810003C028008344B0100AE230008A22900301E
+:10A820008F8C00388F8700A4959F003294F000121F
+:10A830002407FFBF033FC02432053FFF03057825EF
+:10A84000A58F0032918E00322418FFDF31CD003FFA
+:10A8500035A60040A18600328F910038240DFFFFFD
+:10A86000240CFF80AE2000348D6A00D0AE2A003860
+:10A870009223003C3069007FA229003C8F90003871
+:10A880003C0380009219003C0327F824A21F003CDF
+:10A890008F8E003891C5003C00B87824A1CF003CD1
+:10A8A0008F8A00383C0E8008AD4D00408FA6002CEA
+:10A8B000AD46004491420048004C5825A14B004849
+:10A8C0008F9000388F9900A48E09004801238824B6
+:10A8D00002283825AE070048933F003EA21F004CD7
+:10A8E0008F9800A48F8F003897050004A5E5004ECF
+:10A8F0000E0003818DC500609246007C8FAC003055
+:10A9000000026940000291000040282130CB000283
+:10A9100001B21021156000AA018230213C0E80088E
+:10A9200035C20080904C007C31830004106000032D
+:10A930008FB900300005788000CF3021241F00043B
+:10A940008F910038332D000303ED8023320800037C
+:10A9500000C85021AE2A00343C188000A7C500383A
+:10A960003C0680088F04010090DE00080E000FDE18
+:10A9700033C5007F0E001013000000000A00140D04
+:10A980008FA300288F9800348CC90038241F00033F
+:10A99000A7000008AF0900008CC50034A300000A1E
+:10A9A0008F9900A4AF0500043C080080932D003F60
+:10A9B000A31F000C8F0A000C3C02FF9FA30D000B8D
+:10A9C0000148F0253451FFFF3C12FFEF8F9900A49E
+:10A9D00003D170243646FFFF01C61824AF03000CD4
+:10A9E0008F2C0014972900128F8400A0AF0C001048
+:10A9F0008F2F0014AF000018AF000020AF0F00141D
+:10AA0000AF0000248F270018312F3FFF000F59801F
+:10AA1000AF0700288F2500080164F821312D0001BF
+:10AA2000AF0500308F31000C8F920038001F51C2EB
+:10AA3000000D438001481021241E00023C068008BE
+:10AA4000A702001CA7000034AF11002CA25E00007A
+:10AA500034D20080964E005C8F9900383C0342004F
+:10AA600031CCFFFF01833825AF2700048F8B00A472
+:10AA7000240500012402C0008D640038240700343E
+:10AA8000AF2400188D690034AF29001CAF20000CE2
+:10AA9000AF200010A7200014A7200016A720002038
+:10AAA000A7200022AF200024A7300002A325000128
+:10AAB0008F8800388F9F00A4AD10000893ED000030
+:10AAC000A10D00308F8A00A48F98003891510001A9
+:10AAD000A31100318F8B0038957E003203C27024A1
+:10AAE00001CF6025A56C0032916300323064003FD5
+:10AAF000A16400329249007C3125000214A00002BA
+:10AB00008F840038240700303C198008AC8700345B
+:10AB1000373201008E5F00D0240AFFBF020090216F
+:10AB2000AC9F0038908D003C31A8007FA088003C8D
+:10AB30008F9E003893C2003C004A8824A3D1003C79
+:10AB40008F8300380010882B9066003C34CE0020A4
+:10AB5000A06E003C8F8400A48F9800388C8C00205D
+:10AB6000AF0C00408C8F0024AF0F00448C8700286E
+:10AB7000AF0700488C8B002CAF0B004C0E0010135D
+:10AB80003C1E80000A0012700000000094C80052B1
+:10AB90003C0A08008D4A002401488821A4D10052B3
+:10ABA0000A0012198FB40010A08700018F840038AA
+:10ABB000240B0001AC8B00080A0013BE3C12800875
+:10ABC000000520800A0014A200C4302127BDFFE048
+:10ABD0003C0D8008AFB20018AFB00010AFBF001C32
+:10ABE000AFB1001435B200808E4C001835A80100BA
+:10ABF000964B000695A70050910900FC000C5602E8
+:10AC0000016728233143007F312600FF240200031F
+:10AC1000AF8300A8AF8400A010C2001B30B0FFFFBC
+:10AC2000910600FC2412000530C200FF10520033D0
+:10AC300000000000160000098FBF001C8FB2001832
+:10AC40008FB100148FB00010240D0C003C0C80005C
+:10AC500027BD002003E00008AD8D00240E0011FB8D
+:10AC6000020020218FBF001C8FB200188FB100148A
+:10AC70008FB00010240D0C003C0C800027BD00207C
+:10AC800003E00008AD8D0024965800789651007AB4
+:10AC9000924E007D0238782631E8FFFF31C400C0B3
+:10ACA000148000092D11000116000037000000007B
+:10ACB0005620FFE28FBF001C0E0010D100000000E4
+:10ACC0000A00156A8FBF001C1620FFDA0000000082
+:10ACD0000E0010D1000000001440FFD88FBF001CF0
+:10ACE0001600002200000000925F007D33E2003F6A
+:10ACF000A242007D0A00156A8FBF001C950900EA78
+:10AD00008F86008000802821240400050E0007257E
+:10AD10003130FFFF978300923C0480002465FFFFE1
+:10AD2000A78500928C8A01B80540FFFE0000000054
+:10AD3000AC8001808FBF001CAC9001848FB20018E2
+:10AD40008FB100148FB000103C0760133C0B100053
+:10AD5000240D0C003C0C800027BD0020AC8701882E
+:10AD6000AC8B01B803E00008AD8D00240E0011FB90
+:10AD7000020020215040FFB18FBF001C925F007D78
+:10AD80000A00159733E2003F0E0011FB020020215C
+:10AD90001440FFAA8FBF001C122000070000000013
+:10ADA0009259007D3330003F36020040A242007DC0
+:10ADB0000A00156A8FBF001C0E0010D100000000B1
+:10ADC0005040FF9E8FBF001C9259007D3330003FE2
+:10ADD0000A0015C636020040000000000000001BFB
+:10ADE0000000000F0000000A00000008000000063C
+:10ADF0000000000500000005000000040000000441
+:10AE00000000000300000003000000030000000336
+:10AE10000000000300000002000000020000000229
+:10AE2000000000020000000200000002000000021A
+:10AE3000000000020000000200000002000000020A
+:10AE400000000002000000020000000200000002FA
+:10AE50000000000100000001000000018008010066
+:10AE6000800800808008000000000C000000308096
+:10AE7000080011D00800127C08001294080012A8E3
+:10AE8000080012BC080011D0080011D0080012F010
+:10AE90000800132C080013400800138808001A8CBF
+:10AEA00008001A8C08001AC408001AC408001AD82E
+:10AEB00008001AA808001D0008001CCC08001D5836
+:10AEC00008001D5808001DE008001D108008024001
+:10AED000080027340800256C0800275C080027F4C8
+:10AEE0000800293C0800298808002AAC080029B479
+:10AEF00008002A38080025DC08002EDC08002EA4F3
+:10AF000008002588080025880800258808002B20CF
+:10AF100008002B20080025880800258808002DD06F
+:10AF2000080025880800258808002588080025884D
+:10AF300008002E0C080025880800258808002588B0
+:10AF4000080025880800258808002588080025882D
+:10AF5000080025880800258808002588080025881D
+:10AF6000080025880800258808002588080029A8E9
+:10AF7000080025880800258808002E680800258814
+:10AF800008002588080025880800258808002588ED
+:10AF900008002588080025880800258808002588DD
+:10AFA00008002588080025880800258808002588CD
+:10AFB00008002588080025880800258808002588BD
+:10AFC00008002CF4080025880800258808002C6853
+:10AFD00008002BC408003CE408003CB808003C848E
+:10AFE00008003C5808003C3808003BEC8008010091
+:10AFF00080080080800800008008008008004C6401
+:10B0000008004C9C08004BE408004C6408004C64A9
+:10B01000080049B808004C64080050500A000C842D
+:10B0200000000000000000000000000D7278703683
+:10B030002E322E31620000000602010300000000E3
+:10B0400000000001000000000000000000000000FF
+:10B0500000000000000000000000000000000000F0
+:10B0600000000000000000000000000000000000E0
+:10B0700000000000000000000000000000000000D0
+:10B0800000000000000000000000000000000000C0
+:10B0900000000000000000000000000000000000B0
+:10B0A00000000000000000000000000000000000A0
+:10B0B0000000000000000000000000000000000090
+:10B0C0000000000000000000000000000000000080
+:10B0D0000000000000000000000000000000000070
+:10B0E0000000000000000000000000000000000060
+:10B0F0000000000000000000000000000000000050
+:10B10000000000000000000000000000000000003F
+:10B11000000000000000000000000000000000002F
+:10B12000000000000000000000000000000000001F
+:10B13000000000000000000000000000000000000F
+:10B1400000000000000000000000000000000000FF
+:10B1500000000000000000000000000000000000EF
+:10B1600000000000000000000000000000000000DF
+:10B1700000000000000000000000000000000000CF
+:10B1800000000000000000000000000000000000BF
+:10B1900000000000000000000000000000000000AF
+:10B1A000000000000000000000000000000000009F
+:10B1B000000000000000000000000000000000008F
+:10B1C000000000000000000000000000000000007F
+:10B1D000000000000000000000000000000000006F
+:10B1E000000000000000000000000000000000005F
+:10B1F000000000000000000000000000000000004F
+:10B20000000000000000000000000000000000003E
+:10B21000000000000000000000000000000000002E
+:10B22000000000000000000000000000000000001E
+:10B23000000000000000000000000000000000000E
+:10B2400000000000000000000000000000000000FE
+:10B2500000000000000000000000000000000000EE
+:10B2600000000000000000000000000000000000DE
+:10B2700000000000000000000000000000000000CE
+:10B2800000000000000000000000000000000000BE
+:10B2900000000000000000000000000000000000AE
+:10B2A000000000000000000000000000000000009E
+:10B2B000000000000000000000000000000000008E
+:10B2C000000000000000000000000000000000007E
+:10B2D000000000000000000000000000000000006E
+:10B2E000000000000000000000000000000000005E
+:10B2F000000000000000000000000000000000004E
+:10B30000000000000000000000000000000000003D
+:10B31000000000000000000000000000000000002D
+:10B32000000000000000000000000000000000001D
+:10B33000000000000000000000000000000000000D
+:10B3400000000000000000000000000000000000FD
+:10B3500000000000000000000000000000000000ED
+:10B3600000000000000000000000000000000000DD
+:10B3700000000000000000000000000000000000CD
+:10B3800000000000000000000000000000000000BD
+:10B3900000000000000000000000000000000000AD
+:10B3A000000000000000000000000000000000009D
+:10B3B000000000000000000000000000000000008D
+:10B3C000000000000000000000000000000000007D
+:10B3D000000000000000000000000000000000006D
+:10B3E000000000000000000000000000000000005D
+:10B3F000000000000000000000000000000000004D
+:10B40000000000000000000000000000000000003C
+:10B41000000000000000000000000000000000002C
+:10B42000000000000000000000000000000000001C
+:10B43000000000000000000000000000000000000C
+:10B4400000000000000000000000000000000000FC
+:10B4500000000000000000000000000000000000EC
+:10B4600000000000000000000000000000000000DC
+:10B4700000000000000000000000000000000000CC
+:10B4800000000000000000000000000000000000BC
+:10B4900000000000000000000000000000000000AC
+:10B4A000000000000000000000000000000000009C
+:10B4B000000000000000000000000000000000008C
+:10B4C000000000000000000000000000000000007C
+:10B4D000000000000000000000000000000000006C
+:10B4E000000000000000000000000000000000005C
+:10B4F000000000000000000000000000000000004C
+:10B50000000000000000000000000000000000003B
+:10B51000000000000000000000000000000000002B
+:10B52000000000000000000000000000000000001B
+:10B53000000000000000000000000000000000000B
+:10B5400000000000000000000000000000000000FB
+:10B5500000000000000000000000000000000000EB
+:10B5600000000000000000000000000000000000DB
+:10B5700000000000000000000000000000000000CB
+:10B5800000000000000000000000000000000000BB
+:10B5900000000000000000000000000000000000AB
+:10B5A000000000000000000000000000000000009B
+:10B5B000000000000000000000000000000000008B
+:10B5C000000000000000000000000000000000007B
+:10B5D000000000000000000000000000000000006B
+:10B5E000000000000000000000000000000000005B
+:10B5F000000000000000000000000000000000004B
+:10B60000000000000000000000000000000000003A
+:10B61000000000000000000000000000000000002A
+:10B62000000000000000000000000000000000001A
+:10B63000000000000000000000000000000000000A
+:10B6400000000000000000000000000000000000FA
+:10B6500000000000000000000000000000000000EA
+:10B6600000000000000000000000000000000000DA
+:10B6700000000000000000000000000000000000CA
+:10B6800000000000000000000000000000000000BA
+:10B6900000000000000000000000000000000000AA
+:10B6A000000000000000000000000000000000009A
+:10B6B000000000000000000000000000000000008A
+:10B6C000000000000000000000000000000000007A
+:10B6D000000000000000000000000000000000006A
+:10B6E000000000000000000000000000000000005A
+:10B6F000000000000000000000000000000000004A
+:10B700000000000000000000000000000000000039
+:10B710000000000000000000000000000000000029
+:10B720000000000000000000000000000000000019
+:10B730000000000000000000000000000000000009
+:10B7400000000000000000000000000000000000F9
+:10B7500000000000000000000000000000000000E9
+:10B7600000000000000000000000000000000000D9
+:10B7700000000000000000000000000000000000C9
+:10B7800000000000000000000000000000000000B9
+:10B7900000000000000000000000000000000000A9
+:10B7A0000000000000000000000000000000000099
+:10B7B0000000000000000000000000000000000089
+:10B7C0000000000000000000000000000000000079
+:10B7D0000000000000000000000000000000000069
+:10B7E0000000000000000000000000000000000059
+:10B7F0000000000000000000000000000000000049
+:10B800000000000000000000000000000000000038
+:10B810000000000000000000000000000000000028
+:10B820000000000000000000000000000000000018
+:10B830000000000000000000000000000000000008
+:10B8400000000000000000000000000000000000F8
+:10B8500000000000000000000000000000000000E8
+:10B8600000000000000000000000000000000000D8
+:10B8700000000000000000000000000000000000C8
+:10B8800000000000000000000000000000000000B8
+:10B8900000000000000000000000000000000000A8
+:10B8A0000000000000000000000000000000000098
+:10B8B0000000000000000000000000000000000088
+:10B8C0000000000000000000000000000000000078
+:10B8D0000000000000000000000000000000000068
+:10B8E0000000000000000000000000000000000058
+:10B8F0000000000000000000000000000000000048
+:10B900000000000000000000000000000000000037
+:10B910000000000000000000000000000000000027
+:10B920000000000000000000000000000000000017
+:10B930000000000000000000000000000000000007
+:10B9400000000000000000000000000000000000F7
+:10B9500000000000000000000000000000000000E7
+:10B9600000000000000000000000000000000000D7
+:10B9700000000000000000000000000000000000C7
+:10B9800000000000000000000000000000000000B7
+:10B9900000000000000000000000000000000000A7
+:10B9A0000000000000000000000000000000000097
+:10B9B0000000000000000000000000000000000087
+:10B9C0000000000000000000000000000000000077
+:10B9D0000000000000000000000000000000000067
+:10B9E0000000000000000000000000000000000057
+:10B9F0000000000000000000000000000000000047
+:10BA00000000000000000000000000000000000036
+:10BA10000000000000000000000000000000000026
+:10BA20000000000000000000000000000000000016
+:10BA30000000000000000000000000000000000006
+:10BA400000000000000000000000000000000000F6
+:10BA500000000000000000000000000000000000E6
+:10BA600000000000000000000000000000000000D6
+:10BA700000000000000000000000000000000000C6
+:10BA800000000000000000000000000000000000B6
+:10BA900000000000000000000000000000000000A6
+:10BAA0000000000000000000000000000000000096
+:10BAB0000000000000000000000000000000000086
+:10BAC0000000000000000000000000000000000076
+:10BAD0000000000000000000000000000000000066
+:10BAE0000000000000000000000000000000000056
+:10BAF0000000000000000000000000000000000046
+:10BB00000000000000000000000000000000000035
+:10BB10000000000000000000000000000000000025
+:10BB20000000000000000000000000000000000015
+:10BB30000000000000000000000000000000000005
+:10BB400000000000000000000000000000000000F5
+:10BB500000000000000000000000000000000000E5
+:10BB600000000000000000000000000000000000D5
+:10BB700000000000000000000000000000000000C5
+:10BB800000000000000000000000000000000000B5
+:10BB900000000000000000000000000000000000A5
+:10BBA0000000000000000000000000000000000095
+:10BBB0000000000000000000000000000000000085
+:10BBC0000000000000000000000000000000000075
+:10BBD0000000000000000000000000000000000065
+:10BBE0000000000000000000000000000000000055
+:10BBF0000000000000000000000000000000000045
+:10BC00000000000000000000000000000000000034
+:10BC10000000000000000000000000000000000024
+:10BC20000000000000000000000000000000000014
+:10BC30000000000000000000000000000000000004
+:10BC400000000000000000000000000000000000F4
+:10BC500000000000000000000000000000000000E4
+:10BC600000000000000000000000000000000000D4
+:10BC700000000000000000000000000000000000C4
+:10BC800000000000000000000000000000000000B4
+:10BC900000000000000000000000000000000000A4
+:10BCA0000000000000000000000000000000000094
+:10BCB0000000000000000000000000000000000084
+:10BCC0000000000000000000000000000000000074
+:10BCD0000000000000000000000000000000000064
+:10BCE0000000000000000000000000000000000054
+:10BCF0000000000000000000000000000000000044
+:10BD00000000000000000000000000000000000033
+:10BD10000000000000000000000000000000000023
+:10BD20000000000000000000000000000000000013
+:10BD30000000000000000000000000000000000003
+:10BD400000000000000000000000000000000000F3
+:10BD500000000000000000000000000000000000E3
+:10BD600000000000000000000000000000000000D3
+:10BD700000000000000000000000000000000000C3
+:10BD800000000000000000000000000000000000B3
+:10BD900000000000000000000000000000000000A3
+:10BDA0000000000000000000000000000000000093
+:10BDB0000000000000000000000000000000000083
+:10BDC0000000000000000000000000000000000073
+:10BDD0000000000000000000000000000000000063
+:10BDE0000000000000000000000000000000000053
+:10BDF0000000000000000000000000000000000043
+:10BE00000000000000000000000000000000000032
+:10BE10000000000000000000000000000000000022
+:10BE20000000000000000000000000000000000012
+:10BE30000000000000000000000000000000000002
+:10BE400000000000000000000000000000000000F2
+:10BE500000000000000000000000000000000000E2
+:10BE600000000000000000000000000000000000D2
+:10BE700000000000000000000000000000000000C2
+:10BE800000000000000000000000000000000000B2
+:10BE900000000000000000000000000000000000A2
+:10BEA0000000000000000000000000000000000092
+:10BEB0000000000000000000000000000000000082
+:10BEC0000000000000000000000000000000000072
+:10BED0000000000000000000000000000000000062
+:10BEE0000000000000000000000000000000000052
+:10BEF0000000000000000000000000000000000042
+:10BF00000000000000000000000000000000000031
+:10BF10000000000000000000000000000000000021
+:10BF20000000000000000000000000000000000011
+:10BF30000000000000000000000000000000000001
+:10BF400000000000000000000000000000000000F1
+:10BF500000000000000000000000000000000000E1
+:10BF600000000000000000000000000000000000D1
+:10BF700000000000000000000000000000000000C1
+:10BF800000000000000000000000000000000000B1
+:10BF900000000000000000000000000000000000A1
+:10BFA0000000000000000000000000000000000091
+:10BFB0000000000000000000000000000000000081
+:10BFC0000000000000000000000000000000000071
+:10BFD0000000000000000000000000000000000061
+:10BFE0000000000000000000000000000000000051
+:10BFF0000000000000000000000000000000000041
+:10C000000000000000000000000000000000000030
+:10C010000000000000000000000000000000000020
+:10C020000000000000000000000000000000000010
+:10C030000000000000000000000000000000000000
+:10C0400000000000000000000000000000000000F0
+:10C0500000000000000000000000000000000000E0
+:10C0600000000000000000000000000000000000D0
+:10C0700000000000000000000000000000000000C0
+:10C0800000000000000000000000000000000000B0
+:10C0900000000000000000000000000000000000A0
+:10C0A0000000000000000000000000000000000090
+:10C0B0000000000000000000000000000000000080
+:10C0C0000000000000000000000000000000000070
+:10C0D0000000000000000000000000000000000060
+:10C0E0000000000000000000000000000000000050
+:10C0F0000000000000000000000000000000000040
+:10C10000000000000000000000000000000000002F
+:10C11000000000000000000000000000000000001F
+:10C12000000000000000000000000000000000000F
+:10C1300000000000000000000000000000000000FF
+:10C1400000000000000000000000000000000000EF
+:10C1500000000000000000000000000000000000DF
+:10C1600000000000000000000000000000000000CF
+:10C1700000000000000000000000000000000000BF
+:10C1800000000000000000000000000000000000AF
+:10C19000000000000000000000000000000000009F
+:10C1A000000000000000000000000000000000008F
+:10C1B000000000000000000000000000000000007F
+:10C1C000000000000000000000000000000000006F
+:10C1D000000000000000000000000000000000005F
+:10C1E000000000000000000000000000000000004F
+:10C1F000000000000000000000000000000000003F
+:10C20000000000000000000000000000000000002E
+:10C21000000000000000000000000000000000001E
+:10C22000000000000000000000000000000000000E
+:10C2300000000000000000000000000000000000FE
+:10C2400000000000000000000000000000000000EE
+:10C2500000000000000000000000000000000000DE
+:10C2600000000000000000000000000000000000CE
+:10C2700000000000000000000000000000000000BE
+:10C2800000000000000000000000000000000000AE
+:10C29000000000000000000000000000000000009E
+:10C2A000000000000000000000000000000000008E
+:10C2B000000000000000000000000000000000007E
+:10C2C000000000000000000000000000000000006E
+:10C2D000000000000000000000000000000000005E
+:10C2E000000000000000000000000000000000004E
+:10C2F000000000000000000000000000000000003E
+:10C30000000000000000000000000000000000002D
+:10C31000000000000000000000000000000000001D
+:10C32000000000000000000000000000000000000D
+:10C3300000000000000000000000000000000000FD
+:10C3400000000000000000000000000000000000ED
+:10C3500000000000000000000000000000000000DD
+:10C3600000000000000000000000000000000000CD
+:10C3700000000000000000000000000000000000BD
+:10C3800000000000000000000000000000000000AD
+:10C39000000000000000000000000000000000009D
+:10C3A000000000000000000000000000000000008D
+:10C3B000000000000000000000000000000000007D
+:10C3C000000000000000000000000000000000006D
+:10C3D000000000000000000000000000000000005D
+:10C3E000000000000000000000000000000000004D
+:10C3F000000000000000000000000000000000003D
+:10C40000000000000000000000000000000000002C
+:10C41000000000000000000000000000000000001C
+:10C42000000000000000000000000000000000000C
+:10C4300000000000000000000000000000000000FC
+:10C4400000000000000000000000000000000000EC
+:10C4500000000000000000000000000000000000DC
+:10C4600000000000000000000000000000000000CC
+:10C4700000000000000000000000000000000000BC
+:10C4800000000000000000000000000000000000AC
+:10C49000000000000000000000000000000000009C
+:10C4A000000000000000000000000000000000008C
+:10C4B000000000000000000000000000000000007C
+:10C4C000000000000000000000000000000000006C
+:10C4D000000000000000000000000000000000005C
+:10C4E000000000000000000000000000000000004C
+:10C4F000000000000000000000000000000000003C
+:10C50000000000000000000000000000000000002B
+:10C51000000000000000000000000000000000001B
+:10C52000000000000000000000000000000000000B
+:10C5300000000000000000000000000000000000FB
+:10C5400000000000000000000000000000000000EB
+:10C5500000000000000000000000000000000000DB
+:10C5600000000000000000000000000000000000CB
+:10C5700000000000000000000000000000000000BB
+:10C5800000000000000000000000000000000000AB
+:10C59000000000000000000000000000000000009B
+:10C5A000000000000000000000000000000000008B
+:10C5B000000000000000000000000000000000007B
+:10C5C000000000000000000000000000000000006B
+:10C5D000000000000000000000000000000000005B
+:10C5E000000000000000000000000000000000004B
+:10C5F000000000000000000000000000000000003B
+:10C60000000000000000000000000000000000002A
+:10C61000000000000000000000000000000000001A
+:10C62000000000000000000000000000000000000A
+:10C6300000000000000000000000000000000000FA
+:10C6400000000000000000000000000000000000EA
+:10C6500000000000000000000000000000000000DA
+:10C6600000000000000000000000000000000000CA
+:10C6700000000000000000000000000000000000BA
+:10C6800000000000000000000000000000000000AA
+:10C69000000000000000000000000000000000009A
+:10C6A000000000000000000000000000000000008A
+:10C6B000000000000000000000000000000000007A
+:10C6C000000000000000000000000000000000006A
+:10C6D000000000000000000000000000000000005A
+:10C6E000000000000000000000000000000000004A
+:10C6F000000000000000000000000000000000003A
+:10C700000000000000000000000000000000000029
+:10C710000000000000000000000000000000000019
+:10C720000000000000000000000000000000000009
+:10C7300000000000000000000000000000000000F9
+:10C7400000000000000000000000000000000000E9
+:10C7500000000000000000000000000000000000D9
+:10C7600000000000000000000000000000000000C9
+:10C7700000000000000000000000000000000000B9
+:10C7800000000000000000000000000000000000A9
+:10C790000000000000000000000000000000000099
+:10C7A0000000000000000000000000000000000089
+:10C7B0000000000000000000000000000000000079
+:10C7C0000000000000000000000000000000000069
+:10C7D0000000000000000000000000000000000059
+:10C7E0000000000000000000000000000000000049
+:10C7F0000000000000000000000000000000000039
+:10C800000000000000000000000000000000000028
+:10C810000000000000000000000000000000000018
+:10C820000000000000000000000000000000000008
+:10C8300000000000000000000000000000000000F8
+:10C8400000000000000000000000000000000000E8
+:10C8500000000000000000000000000000000000D8
+:10C8600000000000000000000000000000000000C8
+:10C8700000000000000000000000000000000000B8
+:10C8800000000000000000000000000000000000A8
+:10C890000000000000000000000000000000000098
+:10C8A0000000000000000000000000000000000088
+:10C8B0000000000000000000000000000000000078
+:10C8C0000000000000000000000000000000000068
+:10C8D0000000000000000000000000000000000058
+:10C8E0000000000000000000000000000000000048
+:10C8F0000000000000000000000000000000000038
+:10C900000000000000000000000000000000000027
+:10C910000000000000000000000000000000000017
+:10C920000000000000000000000000000000000007
+:10C9300000000000000000000000000000000000F7
+:10C9400000000000000000000000000000000000E7
+:10C9500000000000000000000000000000000000D7
+:10C9600000000000000000000000000000000000C7
+:10C9700000000000000000000000000000000000B7
+:10C9800000000000000000000000000000000000A7
+:10C990000000000000000000000000000000000097
+:10C9A0000000000000000000000000000000000087
+:10C9B0000000000000000000000000000000000077
+:10C9C0000000000000000000000000000000000067
+:10C9D0000000000000000000000000000000000057
+:10C9E0000000000000000000000000000000000047
+:10C9F0000000000000000000000000000000000037
+:10CA00000000000000000000000000000000000026
+:10CA10000000000000000000000000000000000016
+:10CA20000000000000000000000000000000000006
+:10CA300000000000000000000000000000000000F6
+:10CA400000000000000000000000000000000000E6
+:10CA500000000000000000000000000000000000D6
+:10CA600000000000000000000000000000000000C6
+:10CA700000000000000000000000000000000000B6
+:10CA800000000000000000000000000000000000A6
+:10CA90000000000000000000000000000000000096
+:10CAA0000000000000000000000000000000000086
+:10CAB0000000000000000000000000000000000076
+:10CAC0000000000000000000000000000000000066
+:10CAD0000000000000000000000000000000000056
+:10CAE0000000000000000000000000000000000046
+:10CAF0000000000000000000000000000000000036
+:10CB00000000000000000000000000000000000025
+:10CB10000000000000000000000000000000000015
+:10CB20000000000000000000000000000000000005
+:10CB300000000000000000000000000000000000F5
+:10CB400000000000000000000000000000000000E5
+:10CB500000000000000000000000000000000000D5
+:10CB600000000000000000000000000000000000C5
+:10CB700000000000000000000000000000000000B5
+:10CB800000000000000000000000000000000000A5
+:10CB90000000000000000000000000000000000095
+:10CBA0000000000000000000000000000000000085
+:10CBB0000000000000000000000000000000000075
+:10CBC0000000000000000000000000000000000065
+:10CBD0000000000000000000000000000000000055
+:10CBE0000000000000000000000000000000000045
+:10CBF0000000000000000000000000000000000035
+:10CC00000000000000000000000000000000000024
+:10CC10000000000000000000000000000000000014
+:10CC20000000000000000000000000000000000004
+:10CC300000000000000000000000000000000000F4
+:10CC400000000000000000000000000000000000E4
+:10CC500000000000000000000000000000000000D4
+:10CC600000000000000000000000000000000000C4
+:10CC700000000000000000000000000000000000B4
+:10CC800000000000000000000000000000000000A4
+:10CC90000000000000000000000000000000000094
+:10CCA0000000000000000000000000000000000084
+:10CCB0000000000000000000000000000000000074
+:10CCC0000000000000000000000000000000000064
+:10CCD0000000000000000000000000000000000054
+:10CCE0000000000000000000000000000000000044
+:10CCF0000000000000000000000000000000000034
+:10CD00000000000000000000000000000000000023
+:10CD10000000000000000000000000000000000013
+:10CD20000000000000000000000000000000000003
+:10CD300000000000000000000000000000000000F3
+:10CD400000000000000000000000000000000000E3
+:10CD500000000000000000000000000000000000D3
+:10CD600000000000000000000000000000000000C3
+:10CD700000000000000000000000000000000000B3
+:10CD800000000000000000000000000000000000A3
+:10CD90000000000000000000000000000000000093
+:10CDA0000000000000000000000000000000000083
+:10CDB0000000000000000000000000000000000073
+:10CDC0000000000000000000000000000000000063
+:10CDD0000000000000000000000000000000000053
+:10CDE0000000000000000000000000000000000043
+:10CDF0000000000000000000000000000000000033
+:10CE00000000000000000000000000000000000022
+:10CE10000000000000000000000000000000000012
+:10CE20000000000000000000000000000000000002
+:10CE300000000000000000000000000000000000F2
+:10CE400000000000000000000000000000000000E2
+:10CE500000000000000000000000000000000000D2
+:10CE600000000000000000000000000000000000C2
+:10CE700000000000000000000000000000000000B2
+:10CE800000000000000000000000000000000000A2
+:10CE90000000000000000000000000000000000092
+:10CEA0000000000000000000000000000000000082
+:10CEB0000000000000000000000000000000000072
+:10CEC0000000000000000000000000000000000062
+:10CED0000000000000000000000000000000000052
+:10CEE0000000000000000000000000000000000042
+:10CEF0000000000000000000000000000000000032
+:10CF00000000000000000000000000000000000021
+:10CF10000000000000000000000000000000000011
+:10CF20000000000000000000000000000000000001
+:10CF300000000000000000000000000000000000F1
+:10CF400000000000000000000000000000000000E1
+:10CF500000000000000000000000000000000000D1
+:10CF600000000000000000000000000000000000C1
+:10CF700000000000000000000000000000000000B1
+:10CF800000000000000000000000000000000000A1
+:10CF90000000000000000000000000000000000091
+:10CFA0000000000000000000000000000000000081
+:10CFB0000000000000000000000000000000000071
+:10CFC0000000000000000000000000000000000061
+:10CFD0000000000000000000000000000000000051
+:10CFE0000000000000000000000000000000000041
+:10CFF0000000000000000000000000000000000031
+:10D000000000000000000000000000000000000020
+:10D010000000000000000000000000000000000010
+:10D020000000000000000000000000000000000000
+:10D0300000000000000000000000000000000000F0
+:10D0400000000000000000000000000000000000E0
+:10D0500000000000000000000000000000000000D0
+:10D0600000000000000000000000000000000000C0
+:10D0700000000000000000000000000000000000B0
+:10D0800000000000000000000000000000000000A0
+:10D090000000000000000000000000000000000090
+:10D0A0000000000000000000000000000000000080
+:10D0B0000000000000000000000000000000000070
+:10D0C0000000000000000000000000000000000060
+:10D0D0000000000000000000000000000000000050
+:10D0E0000000000000000000000000000000000040
+:10D0F0000000000000000000000000000000000030
+:10D10000000000000000000000000000000000001F
+:10D11000000000000000000000000000000000000F
+:10D1200000000000000000000000000000000000FF
+:10D1300000000000000000000000000000000000EF
+:10D1400000000000000000000000000000000000DF
+:10D1500000000000000000000000000000000000CF
+:10D1600000000000000000000000000000000000BF
+:10D1700000000000000000000000000000000000AF
+:10D18000000000000000000000000000000000009F
+:10D19000000000000000000000000000000000008F
+:10D1A000000000000000000000000000000000007F
+:10D1B000000000000000000000000000000000006F
+:10D1C000000000000000000000000000000000005F
+:10D1D000000000000000000000000000000000004F
+:10D1E000000000000000000000000000000000003F
+:10D1F000000000000000000000000000000000002F
+:10D20000000000000000000000000000000000001E
+:10D21000000000000000000000000000000000000E
+:10D2200000000000000000000000000000000000FE
+:10D2300000000000000000000000000000000000EE
+:10D2400000000000000000000000000000000000DE
+:10D2500000000000000000000000000000000000CE
+:10D2600000000000000000000000000000000000BE
+:10D2700000000000000000000000000000000000AE
+:10D28000000000000000000000000000000000009E
+:10D29000000000000000000000000000000000008E
+:10D2A000000000000000000000000000000000007E
+:10D2B000000000000000000000000000000000006E
+:10D2C000000000000000000000000000000000005E
+:10D2D000000000000000000000000000000000004E
+:10D2E000000000000000000000000000000000003E
+:10D2F000000000000000000000000000000000002E
+:10D30000000000000000000000000000000000001D
+:10D31000000000000000000000000000000000000D
+:10D3200000000000000000000000000000000000FD
+:10D3300000000000000000000000000000000000ED
+:10D3400000000000000000000000000000000000DD
+:10D3500000000000000000000000000000000000CD
+:10D3600000000000000000000000000000000000BD
+:10D3700000000000000000000000000000000000AD
+:10D38000000000000000000000000000000000009D
+:10D39000000000000000000000000000000000008D
+:10D3A000000000000000000000000000000000007D
+:10D3B000000000000000000000000000000000006D
+:10D3C000000000000000000000000000000000005D
+:10D3D000000000000000000000000000000000004D
+:10D3E000000000000000000000000000000000003D
+:10D3F000000000000000000000000000000000002D
+:10D40000000000000000000000000000000000001C
+:10D41000000000000000000000000000000000000C
+:10D4200000000000000000000000000000000000FC
+:10D4300000000000000000000000000000000000EC
+:10D4400000000000000000000000000000000000DC
+:10D4500000000000000000000000000000000000CC
+:10D4600000000000000000000000000000000000BC
+:10D4700000000000000000000000000000000000AC
+:10D48000000000000000000000000000000000009C
+:10D49000000000000000000000000000000000008C
+:10D4A000000000000000000000000000000000007C
+:10D4B000000000000000000000000000000000006C
+:10D4C000000000000000000000000000000000005C
+:10D4D000000000000000000000000000000000004C
+:10D4E000000000000000000000000000000000003C
+:10D4F000000000000000000000000000000000002C
+:10D50000000000000000000000000000000000001B
+:10D51000000000000000000000000000000000000B
+:10D5200000000000000000000000000000000000FB
+:10D5300000000000000000000000000000000000EB
+:10D5400000000000000000000000000000000000DB
+:10D5500000000000000000000000000000000000CB
+:10D5600000000000000000000000000000000000BB
+:10D5700000000000000000000000000000000000AB
+:10D58000000000000000000000000000000000009B
+:10D59000000000000000000000000000000000008B
+:10D5A000000000000000000000000000000000007B
+:10D5B000000000000000000000000000000000006B
+:10D5C000000000000000000000000000000000005B
+:10D5D000000000000000000000000000000000004B
+:10D5E000000000000000000000000000000000003B
+:10D5F000000000000000000000000000000000002B
+:10D60000000000000000000000000000000000001A
+:10D61000000000000000000000000000000000000A
+:10D6200000000000000000000000000000000000FA
+:10D6300000000000000000000000000000000000EA
+:10D6400000000000000000000000000000000000DA
+:10D6500000000000000000000000000000000000CA
+:10D6600000000000000000000000000000000000BA
+:10D6700000000000000000000000000000000000AA
+:10D68000000000000000000000000000000000009A
+:10D69000000000000000000000000000000000008A
+:10D6A000000000000000000000000000000000007A
+:10D6B000000000000000000000000000000000006A
+:10D6C000000000000000000000000000000000005A
+:10D6D000000000000000000000000000000000004A
+:10D6E000000000000000000000000000000000003A
+:10D6F000000000000000000000000000000000002A
+:10D700000000000000000000000000000000000019
+:10D710000000000000000000000000000000000009
+:10D7200000000000000000000000000000000000F9
+:10D7300000000000000000000000000000000000E9
+:10D7400000000000000000000000000000000000D9
+:10D7500000000000000000000000000000000000C9
+:10D7600000000000000000000000000000000000B9
+:10D7700000000000000000000000000000000000A9
+:10D780000000000000000000000000000000000099
+:10D790000000000000000000000000000000000089
+:10D7A0000000000000000000000000000000000079
+:10D7B0000000000000000000000000000000000069
+:10D7C0000000000000000000000000000000000059
+:10D7D0000000000000000000000000000000000049
+:10D7E0000000000000000000000000000000000039
+:10D7F0000000000000000000000000000000000029
+:10D800000000000000000000000000000000000018
+:10D810000000000000000000000000000000000008
+:10D8200000000000000000000000000000000000F8
+:10D8300000000000000000000000000000000000E8
+:10D8400000000000000000000000000000000000D8
+:10D8500000000000000000000000000000000000C8
+:10D8600000000000000000000000000000000000B8
+:10D8700000000000000000000000000000000000A8
+:10D880000000000000000000000000000000000098
+:10D890000000000000000000000000000000000088
+:10D8A0000000000000000000000000000000000078
+:10D8B0000000000000000000000000000000000068
+:10D8C0000000000000000000000000000000000058
+:10D8D0000000000000000000000000000000000048
+:10D8E0000000000000000000000000000000000038
+:10D8F0000000000000000000000000000000000028
+:10D900000000000000000000000000000000000017
+:10D910000000000000000000000000000000000007
+:10D9200000000000000000000000000000000000F7
+:10D9300000000000000000000000000000000000E7
+:10D9400000000000000000000000000000000000D7
+:10D9500000000000000000000000000000000000C7
+:10D9600000000000000000000000000000000000B7
+:10D9700000000000000000000000000000000000A7
+:10D980000000000000000000000000000000000097
+:10D990000000000000000000000000000000000087
+:10D9A0000000000000000000000000000000000077
+:10D9B0000000000000000000000000000000000067
+:10D9C0000000000000000000000000000000000057
+:10D9D0000000000000000000000000000000000047
+:10D9E0000000000000000000000000000000000037
+:10D9F0000000000000000000000000000000000027
+:10DA00000000000000000000000000000000000016
+:10DA10000000000000000000000000000000000006
+:10DA200000000000000000000000000000000000F6
+:10DA300000000000000000000000000000000000E6
+:10DA400000000000000000000000000000000000D6
+:10DA500000000000000000000000000000000000C6
+:10DA600000000000000000000000000000000000B6
+:10DA700000000000000000000000000000000000A6
+:10DA80000000000000000000000000000000000096
+:10DA90000000000000000000000000000000000086
+:10DAA0000000000000000000000000000000000076
+:10DAB0000000000000000000000000000000000066
+:10DAC0000000000000000000000000000000000056
+:10DAD0000000000000000000000000000000000046
+:10DAE0000000000000000000000000000000000036
+:10DAF0000000000000000000000000000000000026
+:10DB00000000000000000000000000000000000015
+:10DB10000000000000000000000000000000000005
+:10DB200000000000000000000000000000000000F5
+:10DB300000000000000000000000000000000000E5
+:10DB400000000000000000000000000000000000D5
+:10DB500000000000000000000000000000000000C5
+:10DB600000000000000000000000000000000000B5
+:10DB700000000000000000000000000000000000A5
+:10DB80000000000000000000000000000000000095
+:10DB90000000000000000000000000000000000085
+:10DBA0000000000000000000000000000000000075
+:10DBB0000000000000000000000000000000000065
+:10DBC0000000000000000000000000000000000055
+:10DBD0000000000000000000000000000000000045
+:10DBE0000000000000000000000000000000000035
+:10DBF0000000000000000000000000000000000025
+:10DC00000000000000000000000000000000000014
+:10DC10000000000000000000000000000000000004
+:10DC200000000000000000000000000000000000F4
+:10DC300000000000000000000000000000000000E4
+:10DC400000000000000000000000000000000000D4
+:10DC500000000000000000000000000000000000C4
+:10DC600000000000000000000000000000000000B4
+:10DC700000000000000000000000000000000000A4
+:10DC80000000000000000000000000000000000094
+:10DC90000000000000000000000000000000000084
+:10DCA0000000000000000000000000000000000074
+:10DCB0000000000000000000000000000000000064
+:10DCC0000000000000000000000000000000000054
+:10DCD0000000000000000000000000000000000044
+:10DCE0000000000000000000000000000000000034
+:10DCF0000000000000000000000000000000000024
+:10DD00000000000000000000000000000000000013
+:10DD10000000000000000000000000000000000003
+:10DD200000000000000000000000000000000000F3
+:10DD300000000000000000000000000000000000E3
+:10DD400000000000000000000000000000000000D3
+:10DD500000000000000000000000000000000000C3
+:10DD600000000000000000000000000000000000B3
+:10DD700000000000000000000000000000000000A3
+:10DD80000000000000000000000000000000000093
+:10DD90000000000000000000000000000000000083
+:10DDA0000000000000000000000000000000000073
+:10DDB0000000000000000000000000000000000063
+:10DDC0000000000000000000000000000000000053
+:10DDD0000000000000000000000000000000000043
+:10DDE0000000000000000000000000000000000033
+:10DDF0000000000000000000000000000000000023
+:10DE00000000000000000000000000000000000012
+:10DE10000000000000000000000000000000000002
+:10DE200000000000000000000000000000000000F2
+:10DE300000000000000000000000000000000000E2
+:10DE400000000000000000000000000000000000D2
+:10DE500000000000000000000000000000000000C2
+:10DE600000000000000000000000000000000000B2
+:10DE700000000000000000000000000000000000A2
+:10DE80000000000000000000000000000000000092
+:10DE90000000000000000000000000000000000082
+:10DEA0000000000000000000000000000000000072
+:10DEB0000000000000000000000000000000000062
+:10DEC0000000000000000000000000000000000052
+:10DED0000000000000000000000000000000000042
+:10DEE0000000000000000000000000000000000032
+:10DEF0000000000000000000000000000000000022
+:10DF00000000000000000000000000000000000011
+:10DF10000000000000000000000000000000000001
+:10DF200000000000000000000000000000000000F1
+:10DF300000000000000000000000000000000000E1
+:10DF400000000000000000000000000000000000D1
+:10DF500000000000000000000000000000000000C1
+:10DF600000000000000000000000000000000000B1
+:10DF700000000000000000000000000000000000A1
+:10DF80000000000000000000000000000000000091
+:10DF90000000000000000000000000000000000081
+:10DFA0000000000000000000000000000000000071
+:10DFB0000000000000000000000000000000000061
+:10DFC0000000000000000000000000000000000051
+:10DFD0000000000000000000000000000000000041
+:10DFE0000000000000000000000000000000000031
+:10DFF0000000000000000000000000000000000021
+:10E000000000000000000000000000000000000010
+:10E010000000000000000000000000000000000000
+:10E0200000000000000000000000000000000000F0
+:10E0300000000000000000000000000000000000E0
+:10E0400000000000000000000000000000000000D0
+:10E0500000000000000000000000000000000000C0
+:10E0600000000000000000000000000000000000B0
+:10E0700000000000000000000000000000000000A0
+:10E080000000000000000000000000000000000090
+:10E090000000000000000000000000000000000080
+:10E0A0000000000000000000000000000000000070
+:10E0B0000000000000000000000000000000000060
+:10E0C0000000000000000000000000000000000050
+:10E0D0000000000000000000000000000000000040
+:10E0E0000000000000000000000000000000000030
+:10E0F0000000000000000000000000000000000020
+:10E10000000000000000000000000000000000000F
+:10E1100000000000000000000000000000000000FF
+:10E1200000000000000000000000000000000000EF
+:10E1300000000000000000000000000000000000DF
+:10E1400000000000000000000000000000000000CF
+:10E1500000000000000000000000000000000000BF
+:10E1600000000000000000000000000000000000AF
+:10E17000000000000000000000000000000000009F
+:10E18000000000000000000000000000000000008F
+:10E19000000000000000000000000000000000007F
+:10E1A000000000000000000000000000000000006F
+:10E1B000000000000000000000000000000000005F
+:10E1C000000000000000000000000000000000004F
+:10E1D000000000000000000000000000000000003F
+:10E1E000000000000000000000000000000000002F
+:10E1F000000000000000000000000000000000809F
+:10E20000000000000000000000000000000000000E
+:10E2100000000000000000000000000000000000FE
+:10E220000000000A000000000000000000000000E4
+:10E2300010000003000000000000000D0000000DB1
+:10E240003C020801244295C03C030801246397FC6A
+:10E25000AC4000000043202B1480FFFD244200044A
+:10E260003C1D080037BD9FFC03A0F0213C100800B6
+:10E27000261032103C1C0801279C95C00E0012BECF
+:10E28000000000000000000D3C02800030A5FFFFF0
+:10E2900030C600FF344301803C0880008D0901B87E
+:10E2A0000520FFFE00000000AC6400002404000212
+:10E2B000A4650008A066000AA064000BAC67001803
+:10E2C0003C03100003E00008AD0301B83C0560000A
+:10E2D0008CA24FF80440FFFE00000000ACA44FC029
+:10E2E0003C0310003C040200ACA44FC403E000084F
+:10E2F000ACA34FF89486000C00A050212488001491
+:10E3000000062B0200051080004448210109182B4B
+:10E310001060001100000000910300002C6400094F
+:10E320005080000991190001000360803C0D080134
+:10E3300025AD9258018D58218D67000000E000083E
+:10E340000000000091190001011940210109302B42
+:10E3500054C0FFF29103000003E000080000102108
+:10E360000A000CCC25080001910F0001240E000AC0
+:10E3700015EE00400128C8232F38000A1700003D81
+:10E38000250D00028D580000250F0006370E0100F4
+:10E39000AD4E0000910C000291AB000191A400026F
+:10E3A00091A60003000C2E00000B3C0000A71025D6
+:10E3B00000041A000043C8250326C025AD580004F8
+:10E3C000910E000691ED000191E7000291E5000336
+:10E3D000000E5E00000D6400016C30250007220075
+:10E3E00000C41025004518252508000A0A000CCC99
+:10E3F000AD430008910F000125040002240800022B
+:10E4000055E80001012020210A000CCC00804021A9
+:10E41000910C0001240B0003158B00160000000076
+:10E420008D580000910E000225080003370D0008EA
+:10E43000A14E00100A000CCCAD4D00009119000156
+:10E44000240F0004172F000B0000000091070002AA
+:10E45000910400038D43000000072A0000A410254A
+:10E460003466000425080004AD42000C0A000CCC00
+:10E47000AD46000003E000082402000127BDFFE8CC
+:10E48000AFBF0014AFB000100E00164E0080802108
+:10E490003C0480083485008090A600052403FFFE1C
+:10E4A0000200202100C310248FBF00148FB0001081
+:10E4B000A0A200050A00165827BD001827BDFFE8D6
+:10E4C000AFB00010AFBF00140E000FD40080802149
+:10E4D0003C06800834C5008090A40000240200504F
+:10E4E000308300FF106200073C09800002002021F9
+:10E4F0008FBF00148FB00010AD2001800A00108F74
+:10E5000027BD0018240801003C07800002002021DC
+:10E510008FBF00148FB00010ACE801800A00108F8C
+:10E5200027BD001827BDFF783C058008AFBE0080DE
+:10E53000AFB7007CAFB3006CAFB10064AFBF008475
+:10E54000AFB60078AFB50074AFB40070AFB200687A
+:10E55000AFB0006034A600803C0580008CB201287A
+:10E5600090C400098CA701043C020001309100FF17
+:10E5700000E218240000B8210000F021106000071C
+:10E58000000098213C0908008D2931F02413000176
+:10E59000252800013C010800AC2831F0ACA0008423
+:10E5A00090CC0005000C5827316A0001154000721C
+:10E5B000AFA0005090CD00002406002031A400FF41
+:10E5C00010860018240E0050108E009300000000EA
+:10E5D0003C1008008E1000DC260F00013C010800F2
+:10E5E000AC2F00DC0E0016C7000000000040182110
+:10E5F0008FBF00848FBE00808FB7007C8FB60078FD
+:10E600008FB500748FB400708FB3006C8FB2006848
+:10E610008FB100648FB000600060102103E000083B
+:10E6200027BD00880000000D3C1F8000AFA0003017
+:10E6300097E501168FE201043C04002030B9FFFF8A
+:10E64000004438240007182B00033140AFA60030E7
+:10E650008FF5010437F80C003C1600400338802188
+:10E6600002B6A02434C40040128000479215000D69
+:10E6700032A800201500000234860080008030217E
+:10E6800014C0009FAFA600303C0D800835A6008066
+:10E6900090CC0008318B0040516000063C06800899
+:10E6A000240E0004122E00A8240F0012122F003294
+:10E6B0003C06800834C401003C0280009447011AE3
+:10E6C0009619000E909F00088E18000830E3FFFF97
+:10E6D00003F9B00432B40004AFB6005CAFA3005835
+:10E6E0008E1600041280002EAFB8005434C3008090
+:10E6F000906800083105004014A0002500000000CB
+:10E700008C70005002D090230640000500000000ED
+:10E710008C71003402D1A82306A201678EE20008A2
+:10E72000126000063C1280003C1508008EB531F4E2
+:10E7300026B600013C010800AC3631F4AE4000447E
+:10E74000240300018FBF00848FBE00808FB7007C40
+:10E750008FB600788FB500748FB400708FB3006CE3
+:10E760008FB200688FB100648FB00060006010212C
+:10E7700003E0000827BD00880E000D2800002021BE
+:10E780000A000D75004018210A000D9500C02021D7
+:10E790000E00171702C020211440FFE10000000006
+:10E7A0003C0B8008356400808C8A003402CA482300
+:10E7B0000520001D000000003C1E08008FDE310017
+:10E7C00027D700013C010800AC3731001260000679
+:10E7D000024020213C1408008E9431F42690000160
+:10E7E0003C010800AC3031F40E00164E3C1E80088F
+:10E7F00037CD008091B700250240202136EE00047D
+:10E800000E001658A1AE00250E000CAC02402021CF
+:10E810000A000DCA240300013C17080126F796C020
+:10E820000A000D843C1F80008C86003002C66023E5
+:10E830001980000C2419000C908F004F3C14080024
+:10E840008E94310032B500FC35ED0001268E0001BA
+:10E850003C010800AC2E3100A08D004FAFA0005845
+:10E860002419000CAFB900308C9800300316A02397
+:10E870001A80010B8FA300580074F82A17E0FFD309
+:10E88000000000001074002A8FA5005802D4B021A7
+:10E8900000B410233044FFFFAFA4005832A8000298
+:10E8A0001100002E32AB00103C15800836B00080FD
+:10E8B0009216000832D30040526000FB8EE200083E
+:10E8C0000E00164E02402021240A0018A20A000958
+:10E8D000921100052409FFFE024020210229902404
+:10E8E0000E001658A2120005240400390000282149
+:10E8F0000E0016F2240600180A000DCA24030001B7
+:10E9000092FE000C3C0A800835490080001EBB00C6
+:10E910008D27003836F10081024020213225F08118
+:10E920000E000C9B30C600FF0A000DC10000000065
+:10E930003AA7000130E300011460FFA402D4B02123
+:10E940000A000E1D00000000024020210E001734B6
+:10E95000020028210A000D75004018211160FF7087
+:10E960003C0F80083C0D800835EE00808DC40038D7
+:10E970008FA300548DA60004006660231D80FF68ED
+:10E98000000000000064C02307020001AFA400548F
+:10E990003C1F08008FFF31E433F9000113200015FC
+:10E9A0008FAC00583C07800094E3011A10600012FD
+:10E9B0003C0680080E00216A024020213C03080129
+:10E9C000906396F13064000214800145000000005D
+:10E9D000306C0004118000078FAC0058306600FBDB
+:10E9E0003C010801A02696F132B500FCAFA000580A
+:10E9F0008FAC00583C06800834D30080AFB40018B8
+:10EA0000AFB60010AFAC00143C088000950B01209D
+:10EA10008E6F0030966A005C8FA3005C8FBF003061
+:10EA20003169FFFF3144FFFF8FAE005401341021E4
+:10EA3000350540000064382B0045C82103E7C02598
+:10EA4000AFB90020AFAF0028AFB80030AFAF00249F
+:10EA5000AFA0002CAFAE0034926D000831B40008B6
+:10EA6000168000BB020020218EE200040040F8095D
+:10EA700027A400108FAF003031F300025660000170
+:10EA800032B500FE3C048008349F008093F90008F2
+:10EA900033380040530000138FA400248C850004F9
+:10EAA0008FA7005410A700D52404001432B0000131
+:10EAB0001200000C8FA400242414000C1234011A3C
+:10EAC0002A2D000D11A001022413000E240E000AAD
+:10EAD000522E0001241E00088FAF002425E40001FF
+:10EAE000AFA400248FAA00143C0B80083565008079
+:10EAF000008A48218CB10030ACA9003090A4004EAF
+:10EB00008CA700303408FFFF0088180400E3F821C8
+:10EB1000ACBF00348FA600308FB900548FB8005CB2
+:10EB200030C200081040000B033898218CAC002044
+:10EB3000119300D330C600FF92EE000C8FA7003473
+:10EB400002402021000E6B0035B400800E000C9BAB
+:10EB50003285F0803C028008345000808E0F0030F7
+:10EB600001F1302318C00097264800803C070800B8
+:10EB70008CE731E42404FF80010418243118007F5D
+:10EB80003C1F80003C19800430F10001AFE300908D
+:10EB900012200006031928213C030801906396F116
+:10EBA00030690008152000C6306A00F73C10800864
+:10EBB00036040080908C004F318B000115600042BC
+:10EBC000000000003C0608008CC6319830CE0010D2
+:10EBD00051C0004230F9000190AF006B55E0003F9A
+:10EBE00030F9000124180001A0B8006B3C1180002E
+:10EBF0009622007A24470064A48700123C0D800806
+:10EC000035A5008090B40008329000401600000442
+:10EC10003C03800832AE000115C0008B00000000EC
+:10EC2000346400808C86002010D3000A3463010015
+:10EC30008C67000002C7782319E000978FBF00544B
+:10EC4000AC93002024130001AC760000AFB3005059
+:10EC5000AC7F000417C0004E000000008FA90050D8
+:10EC60001520000B000000003C030801906396F1A2
+:10EC7000306A00011140002E8FAB0058306400FE56
+:10EC80003C010801A02496F10A000D75000018212E
+:10EC90000E000CAC024020210A000F1300000000FF
+:10ECA0000A000E200000A0210040F80924040017EB
+:10ECB0000A000DCA240300010040F80924040016CC
+:10ECC0000A000DCA240300019094004F240DFFFE9A
+:10ECD000028D2824A085004F30F900011320000682
+:10ECE0003C0480083C030801906396F1307F0010DB
+:10ECF00017E00051306800EF34900080240A0001D2
+:10ED0000024020210E00164EA60A00129203002592
+:10ED100024090001AFA90050346200010240202103
+:10ED20000E001658A20200250A000EF93C0D8008BC
+:10ED30001160FE83000018218FA5003030AC000464
+:10ED40001180FE2C8FBF00840A000DCB240300012C
+:10ED500027A500380E000CB6AFA000385440FF4382
+:10ED60008EE200048FB40038329001005200FF3F61
+:10ED70008EE200048FA3003C8E6E0058006E682364
+:10ED800005A3FF39AE6300580A000E948EE200041A
+:10ED90000E00164E024020213C038008346800809B
+:10EDA000024020210E001658A11E000903C0302188
+:10EDB000240400370E0016F2000028210A000F116B
+:10EDC0008FA900508FAB00185960FF8D3C0D800853
+:10EDD0000E00164E02402021920C00252405000151
+:10EDE000AFA5005035820004024020210E001658C5
+:10EDF000A20200250A000EF93C0D800812240059D9
+:10EE00002A2300151060004D240900162408000C68
+:10EE10005628FF2732B000013C0A8008914C001BA5
+:10EE20002406FFBD241E000E01865824A14B001BA2
+:10EE30000A000EA532B000013C010801A02896F19D
+:10EE40000A000EF93C0D80088CB500308EFE0008DB
+:10EE50002404001826B6000103C0F809ACB600303F
+:10EE60003C030801906396F13077000116E0FF81C2
+:10EE7000306A00018FB200300A000D753243000481
+:10EE80003C1080009605011A50A0FF2B34C60010DC
+:10EE90000A000EC892EE000C8C6200001456FF6D42
+:10EEA000000000008C7800048FB9005403388823D8
+:10EEB0000621FF638FBF00540A000F0E0000000000
+:10EEC0003C010801A02A96F10A000F3030F9000138
+:10EED0001633FF028FAF00240A000EB0241E00106C
+:10EEE0000E00164E024020213C0B80083568008041
+:10EEF00091090025240A0001AFAA0050353300040F
+:10EF0000024020210E001658A11300253C050801DF
+:10EF100090A596F130A200FD3C010801A02296F1D7
+:10EF20000A000E6D004018212411000E53D1FEEA94
+:10EF3000241E00100A000EAF241E00165629FEDC07
+:10EF400032B000013C0A8008914C001B2406FFBD32
+:10EF5000241E001001865824A14B001B0A000EA598
+:10EF600032B000010A000EA4241E00123C038000EF
+:10EF70008C6201B80440FFFE24040800AC6401B8B0
+:10EF800003E000080000000030A5FFFF30C6FFFFCF
+:10EF90003C0780008CE201B80440FFFE34EA0180A7
+:10EFA000AD440000ACE400203C0480089483004899
+:10EFB0003068FFFF11000016AF88000824AB001274
+:10EFC000010B482B512000133C04800034EF01005A
+:10EFD00095EE00208F890000240D001A31CCFFFF30
+:10EFE00031274000A14D000B10E000362583FFFEC5
+:10EFF0000103C02B170000348F9900048F88000490
+:10F00000A5430014350700010A001003AF87000470
+:10F010003C04800024030003348201808F890000B7
+:10F020008F870004A043000B3C088000350C018052
+:10F03000A585000EA585001A8F85000C30EB800099
+:10F04000A5890010AD850028A58600081160000F75
+:10F050008F85001435190100972A00163158FFFCDE
+:10F06000270F000401E870218DCD400031A6FFFF7D
+:10F0700014C000072403BFFF3C02FFFF34487FFF9A
+:10F0800000E83824AF8700048F8500142403BFFFF5
+:10F090003C04800000E3582434830180A46B0026E4
+:10F0A000AC69002C10A0000300054C02A465001000
+:10F0B000A46900263C071000AC8701B803E00008F3
+:10F0C000000000008F990004240AFFFE032A382460
+:10F0D0000A001003AF87000427BDFFE88FA20028B5
+:10F0E00030A5FFFF30C6FFFFAFBF0010AF87000C99
+:10F0F000AF820014AF8000040E000FDBAF80000071
+:10F100008FBF001027BD001803E00008AF80001477
+:10F110003C06800034C4007034C701008C8A0000B3
+:10F1200090E500128F84000027BDFFF030A300FFA0
+:10F13000000318823082400010400037246500032D
+:10F140000005C8800326C0218F0E4000246F0004F4
+:10F15000000F6880AFAE000001A660218D8B4000DB
+:10F16000AFAB000494E900163128FFFC01063821FA
+:10F170008CE64000AFA600088FA9000800003021EF
+:10F18000000028213C07080024E701000A0010675E
+:10F19000240800089059000024A500012CAC000CA4
+:10F1A0000079C0210018788001E770218DCD000022
+:10F1B0001180000600CD302603A5102114A8FFF50C
+:10F1C00000051A005520FFF4905900003C0480000F
+:10F1D000348700703C0508008CA531048CE30000E6
+:10F1E0002CA2002010400009006A38230005488046
+:10F1F0003C0B0800256B3108012B402124AA00019B
+:10F20000AD0700003C010800AC2A310400C0102109
+:10F2100003E0000827BD0010308220001040000BE2
+:10F2200000055880016648218D24400024680004B0
+:10F2300000083880AFA4000000E618218C6540006B
+:10F24000AFA000080A001057AFA500040000000D91
+:10F250000A0010588FA9000827BDFFE03C07800076
+:10F2600034E60100AFBF001CAFB20018AFB100140C
+:10F27000AFB0001094C5000E8F87000030A4FFFFD0
+:10F280002483000430E2400010400010AF830028C7
+:10F290003C09002000E940241100000D30EC800002
+:10F2A0008F8A0004240BBFFF00EB38243543100085
+:10F2B000AF87000030F220001640000B3C1900041C
+:10F2C000241FFFBF0A0010B7007F102430EC80001D
+:10F2D000158000423C0E002030F220001240FFF862
+:10F2E0008F8300043C19000400F9C0241300FFF5CB
+:10F2F000241FFFBF34620040AF82000430E20100EF
+:10F300001040001130F010008F83002C10600006B8
+:10F310003C0F80003C05002000E52024148000C044
+:10F320003C0800043C0F800035EE010095CD001E26
+:10F3300095CC001C31AAFFFF000C5C00014B482556
+:10F34000AF89000C30F010001200000824110001F9
+:10F3500030F100201620008B3C18100000F890249B
+:10F36000164000823C040C002411000130E801002A
+:10F370001500000B3C0900018F85000430A94000F6
+:10F38000152000073C0900013C0C1F0100EC58242B
+:10F390003C0A1000116A01183C1080003C09000171
+:10F3A00000E9302410C000173C0B10003C18080086
+:10F3B0008F1800243307000214E0014024030001E9
+:10F3C0008FBF001C8FB200188FB100148FB00010D7
+:10F3D0000060102103E0000827BD002000EE682433
+:10F3E00011A0FFBE30F220008F8F00043C11FFFF00
+:10F3F00036307FFF00F0382435E380000A0010A685
+:10F40000AF87000000EB102450400065AF8000245F
+:10F410008F8C002C3C0D0F0000ED18241580008807
+:10F42000AF83001030E8010011000086938F0010B8
+:10F430003C0A0200106A00833C1280003650010032
+:10F44000920500139789002A3626000230AF00FF8C
+:10F4500025EE0004000E19C03C0480008C9801B811
+:10F460000700FFFE34880180AD0300003C198008CE
+:10F47000AC830020973100483225FFFF10A0015CCB
+:10F48000AF8500082523001200A3F82B53E0015993
+:10F490008F850004348D010095AC00202402001AF1
+:10F4A00030E44000318BFFFFA102000B108001927D
+:10F4B0002563FFFE00A3502B154001908F8F0004A1
+:10F4C000A50300148F88000435050001AF850004F2
+:10F4D0003C08800035190180A729000EA729001AD1
+:10F4E0008F89000C30B18000A7270010AF290028B9
+:10F4F000A72600081220000E3C04800035020100FF
+:10F50000944C0016318BFFFC256400040088182100
+:10F510008C7F400033E6FFFF14C000053C048000F0
+:10F520003C0AFFFF354D7FFF00AD2824AF85000466
+:10F53000240EBFFF00AE402434850180A4A800261D
+:10F54000ACA7002C3C071000AC8701B800001821C4
+:10F550008FBF001C8FB200188FB100148FB0001045
+:10F560000060102103E0000827BD00203C020BFFD3
+:10F5700000E41824345FFFFF03E3C82B5320FF7B14
+:10F58000241100013C0608008CC6002C24C5000193
+:10F590003C010800AC25002C0A0010D42411000501
+:10F5A0008F85002410A0002FAF80001090A30000D2
+:10F5B000146000792419000310A0002A30E601002D
+:10F5C00010C000CC8F860010241F000210DF00C97D
+:10F5D0008F8B000C3C0708008CE7003824E4FFFF09
+:10F5E00014E0000201641824000018213C0D0800FA
+:10F5F00025AD0038006D1021904C00048F85002847
+:10F6000025830004000321C030A5FFFF3626000239
+:10F610000E000FDB000000000A00114D0000182151
+:10F6200000E8302414C0FF403C0F80000E00103D65
+:10F63000000000008F8700000A0010CAAF82000C93
+:10F64000938F00103C18080127189640000F90C0B7
+:10F6500002588021AF9000248F85002414A0FFD38E
+:10F66000AF8F00103C0480008C86400030C5010044
+:10F6700010A000BC322300043C0C08008D8C002438
+:10F6800024120004106000C23190000D3C04800080
+:10F690008C8D40003402FFFF11A201003231FFFBCC
+:10F6A0008C884000310A01005540000124110010EF
+:10F6B00030EE080011C000BE2419FFFB8F9800280F
+:10F6C0002F0F03EF51E000010219802430E90100FF
+:10F6D00011200014320800018F87002C14E000FB79
+:10F6E0008F8C000C3C05800034AB0100917F00132F
+:10F6F00033E300FF246A00042403FFFE0203802496
+:10F70000000A21C012000002023230253226FFFF1B
+:10F710000E000FDB9785002A1200FF290000182138
+:10F72000320800011100000D32180004240E0001FF
+:10F73000120E0002023230253226FFFF9785002A82
+:10F740000E000FDB00002021240FFFFE020F80249B
+:10F750001200FF1B00001821321800045300FF188C
+:10F760002403000102323025241200045612000145
+:10F770003226FFFF9785002A0E000FDB24040100CC
+:10F780002419FFFB021988241220FF0D0000182104
+:10F790000A0010E9240300011079009C00003021C8
+:10F7A00090AD00012402000211A200BE30EA004028
+:10F7B00090B90001241800011338007F30E900409F
+:10F7C0008CA600049785002A00C020210E000FDBC4
+:10F7D0003626000200004021010018218FBF001CC6
+:10F7E0008FB200188FB100148FB00010006010218C
+:10F7F00003E0000827BD0020360F010095EE000C45
+:10F8000031CD020015A0FEE63C0900013C1880083D
+:10F81000971200489789002A362600023248FFFFD7
+:10F82000AF8800083C0380008C7101B80620FFFE01
+:10F83000346A0180AD4000001100008E3C0F800052
+:10F84000253F0012011FC82B1320008B240E00033C
+:10F85000346C0100958B00202402001A30E4400033
+:10F860003163FFFFA142000B108000A72463FFFE5D
+:10F870000103682B15A000A52408FFFE34A5000194
+:10F88000A5430014AF8500043C0480002412BFFF90
+:10F8900000B2802434850180A4A9000EA4A9001A16
+:10F8A000A4A60008A4B00026A4A700103C071000DE
+:10F8B000AC8701B80A00114D000018213C038000FC
+:10F8C00034640100949F000E3C1908008F3900D861
+:10F8D0002404008033E5FFFF273100013C010800CC
+:10F8E000AC3100D80E000FDB240600030A00114DD6
+:10F8F00000001821240A000210CA00598F85002830
+:10F900003C0308008C6300D0240E0001106E005EE2
+:10F910002CCF000C24D2FFFC2E5000041600002136
+:10F9200000002021241800021078001B2CD9000CA4
+:10F9300024DFFFF82FE900041520FF330000202109
+:10F9400030EB020051600004000621C054C00022C8
+:10F9500030A5FFFF000621C030A5FFFF0A00117D82
+:10F96000362600023C0908008D29002431300001B0
+:10F970005200FEF7000018219785002A3626000263
+:10F980000E000FDB000020210A00114D000018219D
+:10F990000A00119C241200021320FFE624DFFFF866
+:10F9A0000000202130A5FFFF0A00117D362600024D
+:10F9B0000A0011AC021980245120FF828CA6000499
+:10F9C0003C05080190A5964110A0FF7E2408000187
+:10F9D0000A0011F0010018210E000FDB3226000191
+:10F9E0008F8600108F8500280A00124F000621C064
+:10F9F0008F8500043C18800024120003371001801A
+:10FA0000A212000B0A00112E3C08800090A30001F6
+:10FA1000241100011071FF70240800012409000264
+:10FA20005069000430E60040240800010A0011F08B
+:10FA30000100182150C0FFFD240800013C0C80008B
+:10FA4000358B01009563001094A40002307FFFFF06
+:10FA5000509FFF62010018210A001284240800014F
+:10FA60002CA803EF1100FE56240300010A001239EE
+:10FA700000000000240E000335EA0180A14E000BB7
+:10FA80000A00121C3C04800011E0FFA2000621C005
+:10FA900030A5FFFF0A00117D362600020A0011A5DD
+:10FAA000241100201140FFC63C1280003650010096
+:10FAB000960F001094AE000231E80FFF15C8FFC08A
+:10FAC000000000000A0011E690B900013C060800A1
+:10FAD0008CC6003824C4FFFF14C00002018418241F
+:10FAE000000018213C0D080025AD0038006D1021E4
+:10FAF0000A0011B6904300048F8F0004240EFFFE0D
+:10FB00000A00112C01EE28242408FFFE0A00121A14
+:10FB100000A8282427BDFFC8AFB00010AFBF003435
+:10FB20003C10600CAFBE0030AFB7002CAFB6002861
+:10FB3000AFB50024AFB40020AFB3001CAFB20018C3
+:10FB4000AFB100148E0E5000240FFF7F3C068000E2
+:10FB500001CF682435AC380C240B0003AE0C5000E8
+:10FB6000ACCB00083C010800AC2000200E001819A6
+:10FB7000000000003C0A0010354980513C06601628
+:10FB8000AE09537C8CC700003C0860148D0500A0B2
+:10FB90003C03FFFF00E320243C02535300051FC237
+:10FBA0001482000634C57C000003A08002869821E0
+:10FBB0008E7200043C116000025128218CBF007C31
+:10FBC0008CA200783C1E600037C420203C05080150
+:10FBD00024A59288AF820018AF9F001C0E0016DD8E
+:10FBE0002406000A3C190001273996403C01080010
+:10FBF000AC3931DC0E0020DDAF8000148FD708084F
+:10FC00002418FFF03C15570902F8B02412D502F56C
+:10FC100024040001AF80002C3C1480003697018042
+:10FC20003C1E080127DE9644369301008E900000AA
+:10FC30003205000310A0FFFD3207000110E000882C
+:10FC4000320600028E7100283C048000AE91002034
+:10FC50008E6500048E66000000A0382100C040219F
+:10FC60008C8301B80460FFFE3C0B0010240A0800DE
+:10FC700000AB4824AC8A01B8552000E0240BBFFF3C
+:10FC80009675000E3C1208008E52002030AC4000E9
+:10FC900032AFFFFF264E000125ED00043C010800B5
+:10FCA000AC2E0020118000E8AF8D00283C18002009
+:10FCB00000B8B02412C000E530B980002408BFFFAE
+:10FCC00000A8382434C81000AF87000030E62000B8
+:10FCD00010C000E92409FFBF3C03000400E328240E
+:10FCE00010A00002010910243502004030EA010092
+:10FCF00011400010AF8200048F8B002C11600007B0
+:10FD00003C0D002000ED6024118000043C0F000435
+:10FD100000EF702411C00239000000009668001E38
+:10FD20009678001C3115FFFF0018B40002B690252C
+:10FD3000AF92000C30F910001320001324150001BD
+:10FD400030FF002017E0000A3C04100000E41024FB
+:10FD50001040000D3C0A0C003C090BFF00EA18247F
+:10FD60003525FFFF00A3302B10C0000830ED010047
+:10FD70003C0C08008D8C002C24150005258B0001FF
+:10FD80003C010800AC2B002C30ED010015A0000B4D
+:10FD90003C0500018F85000430AE400055C00007CF
+:10FDA0003C0500013C161F0100F690243C0F10009A
+:10FDB000124F01CE000000003C05000100E5302498
+:10FDC00010C000AF3C0C10003C1F08008FFF002447
+:10FDD00033E90002152000712403000100601021A6
+:10FDE000104000083C0680003C08800035180100E7
+:10FDF0008F0F00243C056020ACAF00140000000011
+:10FE00003C0680003C194000ACD9013800000000DD
+:10FE10005220001332060002262B0140262C0080BF
+:10FE2000240EFF80016E2024018E6824000D1940ED
+:10FE3000318A007F0004A9403172007F3C16200007
+:10FE400036C20002006A482502B2382500E2882541
+:10FE50000122F825ACDF0830ACD1083032060002B0
+:10FE600010C0FF723C188000370501408CA80000CC
+:10FE700024100040AF08002090AF000831E300706C
+:10FE8000107000D428790041532000082405006038
+:10FE9000241100201071000E3C0A40003C09800033
+:10FEA000AD2A01780A001304000000001465FFFB6E
+:10FEB0003C0A40000E001FFA000000003C0A40000F
+:10FEC0003C098000AD2A01780A00130400000000FC
+:10FED00090A90009241F00048CA70000312800FF0E
+:10FEE000111F01B22503FFFA2C7200061240001404
+:10FEF0003C0680008CA9000494A4000A310500FF90
+:10FF000000095E022D6A00083086FFFF15400002DE
+:10FF10002567000424070003240C000910AC01FA33
+:10FF200028AD000A11A001DE2410000A240E0008EA
+:10FF300010AE0028000731C000C038213C06800008
+:10FF40008CD501B806A0FFFE34D20180AE47000078
+:10FF500034CB0140916E0008240300023C0A4000AB
+:10FF600031C400FF00046A0001A86025A64C000807
+:10FF7000A243000B9562000A3C0810003C09800077
+:10FF8000A64200108D670004AE470024ACC801B83B
+:10FF9000AD2A01780A001304000000003C0A80002A
+:10FFA000354401009483000E3C0208008C4200D8C6
+:10FFB000240400803065FFFF245500013C01080047
+:10FFC000AC3500D80E000FDB240600030A001370C6
+:10FFD000000018210009320230D900FF2418000166
+:10FFE0001738FFD5000731C08F910020262200016D
+:10FFF000AF8200200A0013C800C0382100CB2024A3
+:020000021000EC
+:10000000AF85000010800008AF860004240D87FF34
+:1000100000CD6024158000083C0E006000AE302446
+:1000200010C00005000000000E000D42000000009E
+:100030000A001371000000000E0016050000000009
+:100040000A0013710000000030B980005320FF1F28
+:10005000AF8500003C02002000A2F82453E0FF1B03
+:10006000AF8500003C07FFFF34E47FFF00A4382485
+:100070000A00132B34C880000A001334010910242D
+:1000800000EC58245160005AAF8000248F8D002C62
+:100090003C0E0F0000EE182415A00075AF83001071
+:1000A00030EF010011E00073939800103C12020041
+:1000B000107200703C06800034D9010093280013B0
+:1000C0009789002A36A60002311800FF271600047F
+:1000D000001619C03C0480008C8501B804A0FFFE06
+:1000E00034880180AD0300003C158008AC830020FB
+:1000F00096BF004833E5FFFF10A001BCAF850008A4
+:100100002523001200A3102B504001B98F85000455
+:10011000348D010095AC0020240B001A30E440001F
+:10012000318AFFFFA10B000B108001BA2543FFFEAF
+:1001300000A3702B15C001B88F9600048F8F0004A8
+:10014000A503001435E50001AF8500043C088000DC
+:1001500035150180A6A9000EA6A9001A8F89000CEA
+:1001600030BF8000A6A70010AEA90028A6A60008F0
+:1001700013E0000F3C0F8000350C0100958B00163A
+:10018000316AFFFC25440004008818218C6240007D
+:100190003046FFFF14C000072416BFFF3C0EFFFFD0
+:1001A00035CD7FFF00AD2824AF8500043C0F8000D3
+:1001B0002416BFFF00B6902435E50180A4B20026C6
+:1001C000ACA7002C3C071000ADE701B80A00137083
+:1001D000000018210E00165D000000003C0A4000DF
+:1001E0003C098000AD2A01780A00130400000000D9
+:1001F0008F85002410A00027AF80001090A300007E
+:10020000106000742409000310690101000030210E
+:1002100090AE0001240D000211CD014230EF0040EC
+:1002200090A90001241F0001113F000930E20040A5
+:100230008CA600049785002A00C020210E000FDB49
+:1002400036A60002000040210A00137001001821A8
+:100250005040FFF88CA600043C07080190E7964147
+:1002600010E0FFF4240800010A00137001001821B7
+:10027000939800103C1F080127FF96400018C8C043
+:10028000033F4021AF8800248F85002414A0FFDBAA
+:10029000AF9800103C0480008C86400030C50100FF
+:1002A00010A0008732AB00043C0C08008D8C0024A9
+:1002B00024160004156000033192000D241600027C
+:1002C0003C0480008C8E4000340DFFFF11CD0113E3
+:1002D00032B5FFFB8C984000330F010055E0000160
+:1002E0002415001030E80800110000382409FFFB35
+:1002F0008F9F00282FF903EF53200001024990241B
+:1003000030E2010010400014325F00018F87002CA2
+:1003100014E0010E8F8C000C3C0480003486010038
+:1003200090C5001330AA00FF25430004000321C03C
+:100330002419FFFE025990241240000202B6302513
+:1003400032A6FFFF0E000FDB9785002A1240FEA3A6
+:1003500000001821325F000113E0000D3247000455
+:10036000240900011249000202B6302532A6FFFF1F
+:100370009785002A0E000FDB000020212402FFFEDB
+:10038000024290241240FE950000182132470004DA
+:1003900050E0FE922403000102B63025241600042A
+:1003A0005656000132A6FFFF9785002A0E000FDB8C
+:1003B000240401002403FFFB0243A82412A0FE87AB
+:1003C000000018210A001370240300010A0014B968
+:1003D0000249902410A0FFAF30E5010010A00017E3
+:1003E0008F8600102403000210C300148F84000CB9
+:1003F0003C0608008CC6003824CAFFFF14C0000267
+:10040000008A1024000010213C0E080025CE003880
+:10041000004E682191AC00048F850028258B0004D4
+:10042000000B21C030A5FFFF36A600020E000FDB37
+:10043000000000000A00137000001821240F0002C1
+:1004400010CF0088241600013C0308008C6300D004
+:100450001076008D8F85002824D9FFFC2F280004FA
+:100460001500006300002021241F0002107F005DA2
+:100470002CC9000C24C3FFF82C6200041440FFE9CF
+:100480000000202130EA020051400004000621C093
+:1004900054C0000530A5FFFF000621C030A5FFFFB6
+:1004A0000A00150436A600020E000FDB32A600017A
+:1004B0008F8600108F8500280A001520000621C0B5
+:1004C0003C0A08008D4A0024315200015240FE438C
+:1004D000000018219785002A36A600020E000FDBC7
+:1004E000000020210A001370000018219668000CFB
+:1004F000311802005700FE313C0500013C1F800806
+:1005000097F900489789002A36A600023328FFFF92
+:10051000AF8800083C0380008C7501B806A0FFFE80
+:100520003C04800034820180AC400000110000B621
+:1005300024180003252A0012010A182B106000B2AB
+:1005400000000000966F00203C0E8000240D001A71
+:1005500031ECFFFF35CA018030EB4000A14D000BAC
+:10056000116000B02583FFFE0103902B164000AE02
+:100570002416FFFE34A50001A5430014AF85000436
+:100580002419BFFF00B94024A6E9000EA6E9001A0D
+:10059000A6E60008A6E80026A6E700103C07100023
+:1005A000AE8701B80A001370000018213C048000D7
+:1005B0008C8201B80440FFFE349601802415001C93
+:1005C000AEC70000A2D5000B3C071000AC8701B8F5
+:1005D0003C0A40003C098000AD2A01780A0013045F
+:1005E000000000005120FFA424C3FFF800002021D8
+:1005F00030A5FFFF0A00150436A600020E00103DCC
+:10060000000000008F8700000A001346AF82000C34
+:1006100090A30001241500011075FF0B24080001B0
+:10062000240600021066000430E2004024080001A5
+:100630000A001370010018215040FFFD240800013A
+:100640003C0C8000358B0100956A001094A40002D8
+:100650003143FFFF5083FDE1010018210A00158599
+:10066000240800018F8500282CB203EF1240FDDB27
+:10067000240300013C0308008C6300D02416000111
+:100680001476FF7624D9FFFC2CD8000C1300FF72DF
+:10069000000621C030A5FFFF0A00150436A600029F
+:1006A00010B00037240F000B14AFFE23000731C039
+:1006B000312600FF00065600000A4E0305220047BF
+:1006C00030C6007F0006F8C03C16080126D69640CA
+:1006D00003F68021A2000001A20000003C0F600090
+:1006E0008DF918202405000100C588040011302769
+:1006F0000326C024000731C000C03821ADF81820FF
+:100700000A0013C8A60000028F850020000731C030
+:1007100024A2FFFF0A0013F6AF8200200A0014B2E1
+:100720002415002011E0FECC3C1980003728010080
+:100730009518001094B6000233120FFF16D2FEC6B1
+:10074000000000000A00148290A900013C0B080080
+:100750008D6B0038256DFFFF15600002018D1024A0
+:10076000000010213C080800250800380048C0217E
+:10077000930F000425EE00040A0014C5000E21C0EA
+:1007800000065202241F00FF115FFDEB000731C07D
+:10079000000A20C03C0E080125CE9640008EA821FC
+:1007A000009E602100095C02240D00013C076000EE
+:1007B000A2AD0000AD860000A2AB00018CF21820B3
+:1007C00024030001014310040242B025ACF61820B6
+:1007D00000C038210A0013C8A6A900020A0015AA01
+:1007E000AF8000200A0012FFAF84002C8F85000428
+:1007F0003C1980002408000337380180A308000B4F
+:100800000A00144D3C088000A2F8000B0A00155A9B
+:100810002419BFFF8F9600042412FFFE0A00144B18
+:1008200002D228242416FFFE0A00155800B62824F8
+:100830003C038000346401008C85000030A2003E3F
+:100840001440000800000000AC6000488C870000E5
+:1008500030E607C010C0000500000000AC60004C8E
+:10086000AC60005003E0000824020001AC600054BA
+:10087000AC6000408C880000310438001080FFF923
+:10088000000000002402000103E00008AC60004406
+:100890003C0380008C6201B80440FFFE3467018095
+:1008A000ACE4000024080001ACE00004A4E500086A
+:1008B00024050002A0E8000A34640140A0E5000B12
+:1008C0009483000A14C00008A4E30010ACE00024E4
+:1008D0003C07800034E901803C041000AD20002872
+:1008E00003E00008ACE401B88C8600043C0410006E
+:1008F000ACE600243C07800034E90180AD200028EC
+:1009000003E00008ACE401B83C0680008CC201B8EA
+:100910000440FFFE34C7018024090002ACE400005B
+:10092000ACE40004A4E50008A0E9000A34C50140D5
+:10093000A0E9000B94A8000A3C041000A4E80010F1
+:10094000ACE000248CA30004ACE3002803E0000822
+:10095000ACC401B83C039000346200010082202541
+:100960003C038000AC6400208C65002004A0FFFEE6
+:100970000000000003E00008000000003C028000CE
+:10098000344300010083202503E00008AC4400202C
+:1009900027BDFFE03C098000AFBF0018AFB10014D5
+:1009A000AFB00010352801408D10000091040009FF
+:1009B0009107000891050008308400FF30E600FF31
+:1009C00000061A002C820081008330251040002A86
+:1009D00030A50080000460803C0D080125AD92B078
+:1009E000018D58218D6A00000140000800000000C0
+:1009F0003C038000346201409445000A14A0001EAC
+:100A00008F91FCC09227000530E6000414C0001A44
+:100A1000000000000E00164E02002021922A000560
+:100A200002002021354900040E001658A2290005B5
+:100A30009228000531040004148000020000000028
+:100A40000000000D922D0000240B002031AC00FFAF
+:100A5000158B00093C0580008CAE01B805C0FFFE77
+:100A600034B10180AE3000003C0F100024100005AE
+:100A7000A230000BACAF01B80000000D8FBF001812
+:100A80008FB100148FB0001003E0000827BD0020D4
+:100A90000200202100C028218FBF00188FB1001450
+:100AA0008FB00010240600010A00161D27BD00208B
+:100AB0000000000D0200202100C028218FBF001877
+:100AC0008FB100148FB00010000030210A00161DF5
+:100AD00027BD002014A0FFE8000000000200202134
+:100AE0008FBF00188FB100148FB0001000C02821F4
+:100AF0000A00163B27BD00203C0780008CEE01B8A1
+:100B000005C0FFFE34F00180241F0002A21F000B6D
+:100B100034F80140A60600089719000A3C0F10009F
+:100B2000A61900108F110004A6110012ACEF01B835
+:100B30000A0016998FBF001827BDFFE8AFBF00104D
+:100B40000E000FD4000000003C0280008FBF001098
+:100B500000002021AC4001800A00108F27BD001842
+:100B60003084FFFF30A5FFFF108000070000182130
+:100B7000308200011040000200042042006518216C
+:100B80001480FFFB0005284003E0000800601021EE
+:100B900010C00007000000008CA2000024C6FFFF68
+:100BA00024A50004AC82000014C0FFFB24840004D0
+:100BB00003E000080000000010A0000824A3FFFFCD
+:100BC000AC86000000000000000000002402FFFFCF
+:100BD0002463FFFF1462FFFA2484000403E000088A
+:100BE000000000003C03800027BDFFF83462018054
+:100BF000AFA20000308C00FF30AD00FF30CE00FF10
+:100C00003C0B80008D6401B80480FFFE00000000F2
+:100C10008FA900008D6801288FAA00008FA700000F
+:100C20008FA400002405000124020002A085000A10
+:100C30008FA30000359940003C051000A062000B16
+:100C40008FB800008FAC00008FA600008FAF0000AF
+:100C500027BD0008AD280000AD400004AD80002491
+:100C6000ACC00028A4F90008A70D0010A5EE0012E2
+:100C700003E00008AD6501B83C06800827BDFFE829
+:100C800034C50080AFBF001090A7000924020012F5
+:100C900030E300FF1062000B008030218CA8005070
+:100CA00000882023048000088FBF00108CAA003425
+:100CB000240400390000282100CA4823052000052B
+:100CC000240600128FBF00102402000103E0000878
+:100CD00027BD00180E0016F2000000008FBF0010A4
+:100CE0002402000103E0000827BD001827BDFFC84B
+:100CF000AFB20030AFB00028AFBF0034AFB1002CAE
+:100D000000A0802190A5000D30A6001010C000109A
+:100D1000008090213C0280088C4400048E0300086F
+:100D20001064000C30A7000530A6000510C0009329
+:100D3000240400018FBF00348FB200308FB1002C2B
+:100D40008FB000280080102103E0000827BD003884
+:100D500030A7000510E0000F30AB001210C00006F5
+:100D6000240400013C0980088E0800088D25000439
+:100D70005105009C240400388FBF00348FB200302E
+:100D80008FB1002C8FB000280080102103E00008F4
+:100D900027BD0038240A0012156AFFE6240400016A
+:100DA0000200202127A500100E000CB6AFA00010F5
+:100DB0001440007C3C19800837240080909800087B
+:100DC000331100081220000A8FA7001030FF010025
+:100DD00013E000A48FA300148C8600580066102333
+:100DE000044000043C0A8008AC8300588FA7001020
+:100DF0003C0A800835480080910900083124000829
+:100E00001480000224080003000040213C1F8008D9
+:100E100093F1001193F9001237E600808CCC005456
+:100E2000333800FF03087821322D00FF000F708057
+:100E300001AE282100AC582B1160006F00000000AB
+:100E400094CA005C8CC900543144FFFF0125102373
+:100E50000082182B14600068000000008CCB005446
+:100E60000165182330EC00041180006C000830800C
+:100E70008FA8001C0068102B1040006230ED0004A9
+:100E8000006610232C46008010C00002004088211C
+:100E9000241100800E00164E024020213C0D8008D7
+:100EA00035A6008024070001ACC7000C90C80008DC
+:100EB0000011484035A70100310C007FA0CC00088C
+:100EC0008E05000424AB0001ACCB0030A4D1005C43
+:100ED0008CCA003C9602000E01422021ACC40020C6
+:100EE0008CC3003C0069F821ACDF001C8E190004A3
+:100EF000ACF900008E180008ACF800048FB10010A7
+:100F0000322F000855E0004793A60020A0C0004EF5
+:100F100090D8004E2411FFDFA0F8000890CF000801
+:100F200001F17024A0CE00088E0500083C0B80085B
+:100F300035690080AD2500388D6A00148D2200309F
+:100F40002419005001422021AD24003491230000D7
+:100F5000307F00FF13F90036264F01000E001658AF
+:100F60000240202124040038000028210E0016F23F
+:100F70002406000A0A001757240400010E000D2859
+:100F8000000020218FBF00348FB200308FB1002CC1
+:100F90008FB00028004020210080102103E00008CD
+:100FA00027BD00388E0E00083C0F800835F0008009
+:100FB000AE0E005402402021AE0000300E00164E4E
+:100FC00000000000920D00250240202135AC0020D9
+:100FD0000E001658A20C00250E000CAC0240202179
+:100FE000240400382405008D0E0016F22406001299
+:100FF0000A0017572404000194C5005C0A001792E8
+:1010000030A3FFFF2407021811A0FF9E00E6102363
+:101010008FAE001C0A00179A01C610230A0017970A
+:101020002C620218A0E600080A0017C48E0500080A
+:101030002406FF8001E6C0243C118000AE38002861
+:101040008E0D000831E7007F3C0E800C00EE602121
+:10105000AD8D00E08E080008AF8C00380A0017D074
+:10106000AD8800E4AC800058908500082403FFF7A9
+:1010700000A33824A08700080A0017758FA7001066
+:101080003C05080024A560A83C04080024846FF4F3
+:101090003C020800244260B0240300063C01080121
+:1010A000AC2596C03C010801AC2496C43C01080163
+:1010B000AC2296C83C010801A02396CC03E00008AE
+:1010C0000000000003E00008240200013C02800050
+:1010D000308800FF344701803C0680008CC301B893
+:1010E0000460FFFE000000008CC501282418FF806A
+:1010F0003C0D800A24AF010001F8702431EC007F20
+:10110000ACCE0024018D2021ACE50000948B00EAD8
+:101110003509600024080002316AFFFFACEA0004D0
+:1011200024020001A4E90008A0E8000BACE00024C0
+:101130003C071000ACC701B8AF84003803E00008DA
+:10114000AF85006C938800488F8900608F820038DB
+:1011500030C600FF0109382330E900FF01221821C1
+:1011600030A500FF2468008810C000020124382147
+:101170000080382130E400031480000330AA00030B
+:101180001140000D312B000310A0000900001021B8
+:1011900090ED0000244E000131C200FF0045602B9D
+:1011A000A10D000024E700011580FFF925080001CA
+:1011B00003E00008000000001560FFF300000000DD
+:1011C00010A0FFFB000010218CF80000245900043F
+:1011D000332200FF0045782BAD18000024E70004FF
+:1011E00015E0FFF92508000403E0000800000000F6
+:1011F00093850048938800588F8700600004320070
+:101200003103007F00E5102B30C47F001040000F39
+:10121000006428258F8400383C0980008C8A00EC0B
+:10122000AD2A00A43C03800000A35825AC6B00A0AD
+:101230008C6C00A00580FFFE000000008C6D00ACEF
+:10124000AC8D00EC03E000088C6200A80A00188254
+:101250008F840038938800593C0280000080502120
+:10126000310300FEA383005930ABFFFF30CC00FFF9
+:1012700030E7FFFF344801803C0980008D2401B82D
+:101280000480FFFE8F8D006C24180016AD0D000049
+:101290008D2201248F8D0038AD0200048D5900206D
+:1012A000A5070008240201C4A119000AA118000B17
+:1012B000952F01208D4E00088D4700049783005C18
+:1012C0008D59002401CF302100C7282100A32023FD
+:1012D0002418FFFFA504000CA50B000EA5020010AA
+:1012E000A50C0012AD190018AD18002495AF00E848
+:1012F0003C0B10002407FFF731EEFFFFAD0E002876
+:101300008DAC0084AD0C002CAD2B01B88D460020B7
+:1013100000C7282403E00008AD4500208F8800386E
+:101320000080582130E7FFFF910900D63C02800081
+:1013300030A5FFFF312400FF00041A00006750258C
+:1013400030C600FF344701803C0980008D2C01B875
+:101350000580FFFE8F82006C240F0017ACE20000B6
+:101360008D390124ACF900048D780020A4EA00082E
+:10137000241901C4A0F8000AA0EF000B9523012056
+:101380008D6E00088D6D00049784005C01C35021B0
+:10139000014D602101841023A4E2000CA4E5000E9D
+:1013A000A4F90010A4E60012ACE000148D7800242B
+:1013B000240DFFFFACF800188D0F007CACEF001C73
+:1013C0008D0E00783C0F1000ACEE0020ACED002438
+:1013D000950A00BE240DFFF73146FFFFACE600285A
+:1013E000950C00809504008231837FFF0003CA00C2
+:1013F0003082FFFF0322C021ACF8002CAD2F01B8D2
+:10140000950E00828D6A002000AE3021014D282407
+:10141000A506008203E00008AD6500203C028000C4
+:10142000344501803C0480008C8301B80460FFFED9
+:101430008F8A0044240600199549001C3128FFFFBB
+:10144000000839C0ACA70000A0A6000B3C051000A6
+:1014500003E00008AC8501B88F87004C0080402174
+:1014600030C400FF3C0680008CC201B80440FFFE7F
+:101470008F89006C9383006834996000ACA90000E8
+:10148000A0A300058CE20010240F00022403FFF744
+:10149000A4A20006A4B900088D180020A0B8000A74
+:1014A000A0AF000B8CEE0000ACAE00108CED000481
+:1014B000ACAD00148CEC001CACAC00248CEB002018
+:1014C000ACAB00288CEA002C3C071000ACAA002C26
+:1014D0008D090024ACA90018ACC701B88D05002007
+:1014E00000A3202403E00008AD0400208F8600380C
+:1014F00027BDFFE0AFB10014AFBF0018AFB00010C0
+:1015000090C300D430A500FF3062002010400008D6
+:10151000008088218CCB00D02409FFDF256A0001E0
+:10152000ACCA00D090C800D401093824A0C700D4A8
+:1015300014A000403C0C80008F840038908700D4B9
+:101540002418FFBF2406FFEF30E3007FA08300D400
+:10155000979F005C8F8200608F8D003803E2C82364
+:10156000A799005CA5A000BC91AF00D401F870243D
+:10157000A1AE00D48F8C0038A18000D78F8A0038AC
+:10158000A5400082AD4000EC914500D400A658244F
+:10159000A14B00D48F9000348F8400609786005C4C
+:1015A0000204282110C0000FAF850034A38000582A
+:1015B0003C0780008E2C000894ED01208E2B000447
+:1015C000018D5021014B8021020620233086FFFF30
+:1015D00030C8000F3909000131310001162000091F
+:1015E000A3880058938600488FBF00188FB100145D
+:1015F0008FB0001027BD0020AF85006403E0000815
+:10160000AF86006000C870238FBF00189386004823
+:101610008FB100148FB0001034EF0C00010F28219F
+:1016200027BD0020ACEE0084AF85006403E0000815
+:10163000AF86006035900180020028210E00190F4E
+:10164000240600828F840038908600D430C5004084
+:1016500050A0FFBAA38000688F85004C3C06800034
+:101660008CCD01B805A0FFFE8F89006C2408608234
+:1016700024070002AE090000A6080008A207000B1C
+:101680008CA300083C0E1000AE0300108CA2000CCE
+:10169000AE0200148CBF0014AE1F00188CB90018E5
+:1016A000AE1900248CB80024AE1800288CAF002896
+:1016B000AE0F002CACCE01B80A001948A380006818
+:1016C0008F8A003827BDFFE0AFB10014AFB0001023
+:1016D0008F880060AFBF00189389003C954200BC22
+:1016E00030D100FF0109182B0080802130AC00FFB1
+:1016F0003047FFFF0000582114600003310600FF4F
+:1017000001203021010958239783005C0068202BB9
+:101710001480002700000000106800562419000102
+:101720001199006334E708803165FFFF0E0018C08F
+:10173000020020218F83006C3C07800034E601808A
+:101740003C0580008CAB01B80560FFFE240A001840
+:101750008F840038ACC30000A0CA000B948900BE7F
+:101760003C081000A4C90010ACC00030ACA801B8FF
+:101770009482008024430001A4830080949F008011
+:101780003C0608008CC6318833EC7FFF1186005E72
+:101790000000000002002021022028218FBF001835
+:1017A0008FB100148FB000100A00193427BD00203B
+:1017B000914400D42403FF8000838825A15100D4E4
+:1017C0009784005C3088FFFF51000023938C003C1D
+:1017D0008F8500382402EFFF008B782394AE00BC85
+:1017E0000168502B31E900FF01C26824A4AD00BCA0
+:1017F00051400039010058213C1F800037E60100AC
+:101800008CD800043C190001031940245500000144
+:1018100034E740008E0A00202403FFFB241100015E
+:1018200001432024AE0400201191002D34E78000F4
+:1018300002002021012030210E0018C03165FFFF79
+:101840009787005C8F890060A780005C0127802358
+:10185000AF900060938C003C8F8B00388FBF0018D6
+:101860008FB100148FB0001027BD002003E00008E6
+:10187000A16C00D73C0D800035AA01008D48000402
+:101880003C0900010109282454A0000134E740006C
+:101890008E0F00202418FFFB34E7800001F870242D
+:1018A00024190001AE0E00201599FF9F34E708802F
+:1018B000020020210E00188E3165FFFF020020215A
+:1018C000022028218FBF00188FB100148FB00010A4
+:1018D0000A00193427BD00200A0019F7000048212A
+:1018E00002002021012030210E00188E3165FFFFFB
+:1018F0009787005C8F890060A780005C01278023A8
+:101900000A001A0EAF900060948C0080241F8000A3
+:10191000019F3024A4860080908B0080908F0080EF
+:10192000316700FF0007C9C20019C027001871C045
+:1019300031ED007F01AE2825A08500800A0019DF67
+:1019400002002021938500682403000127BDFFE8E1
+:1019500000A330042CA20020AFB00010AFBF0014D1
+:1019600000C01821104000132410FFFE3C0708009F
+:101970008CE7319000E610243C088000350501809A
+:1019800014400005240600848F890038240A0004CE
+:101990002410FFFFA12A00FC0E00190F0000000018
+:1019A000020010218FBF00148FB0001003E0000868
+:1019B00027BD00183C0608008CC631940A001A574F
+:1019C00000C310248F87004427BDFFE0AFB200188A
+:1019D000AFB10014AFB00010AFBF001C30D000FF9B
+:1019E00090E6000D00A088210080902130C5007F86
+:1019F000A0E5000D8F8500388E2300188CA200D042
+:101A00001062002E240A000E0E001A4AA38A0068F3
+:101A10002409FFFF104900222404FFFF5200002088
+:101A2000000020218E2600003C0C001000CC582421
+:101A3000156000393C0E000800CE682455A0003F18
+:101A4000024020213C18000200D880241200001F10
+:101A50003C0A00048F8700448CE200148CE30010E1
+:101A60008CE500140043F82303E5C82B1320000580
+:101A7000024020218E24002C8CF1001010910031A6
+:101A80000240202124020012A38200680E001A4A9C
+:101A90002412FFFF105200022404FFFF0000202147
+:101AA0008FBF001C8FB200188FB100148FB00010D0
+:101AB0000080102103E0000827BD002090A800D47A
+:101AC000350400200A001A80A0A400D400CA4824CB
+:101AD0001520000B8F8B00448F8D00448DAC0010BF
+:101AE0001580000B024020218E2E002C51C0FFECEF
+:101AF00000002021024020210A001A9B2402001726
+:101B00008D66001050C0FFE6000020210240202119
+:101B10000A001A9B24020011024020212402001511
+:101B20000E001A4AA3820068240FFFFF104FFFDC4B
+:101B30002404FFFF0A001A8A8E2600000A001AC138
+:101B4000240200143C08000400C8382450E0FFD4EC
+:101B500000002021024020210A001A9B24020013C9
+:101B60008F85003827BDFFD8AFB3001CAFB2001877
+:101B7000AFB10014AFB00010AFBF002090A700D4E9
+:101B80008F90004C2412FFFF34E2004092060000C8
+:101B9000A0A200D48E0300100080982110720006CD
+:101BA00030D1003F2408000D0E001A4AA3880068B7
+:101BB000105200252404FFFF8F8A00388E09001878
+:101BC0008D4400D01124000702602021240C000E57
+:101BD0000E001A4AA38C0068240BFFFF104B001A5A
+:101BE0002404FFFF24040020122400048F8D0038F9
+:101BF00091AF00D435EE0020A1AE00D48F85005403
+:101C000010A00019000000001224004A8F9800382C
+:101C10008F92FCC0971000809651000A5230004805
+:101C20008F9300403C1F08008FFF318C03E5C82BC9
+:101C30001720001E02602021000028210E0019A993
+:101C400024060001000020218FBF00208FB3001C5C
+:101C50008FB200188FB100148FB0001000801021D7
+:101C600003E0000827BD00285224002A8E05001436
+:101C70008F840038948A008025490001A48900805F
+:101C8000948800803C0208008C42318831077FFF35
+:101C900010E2000E00000000026020210E00193446
+:101CA000240500010A001B0B000020212402002D46
+:101CB0000E001A4AA38200682403FFFF1443FFE1C9
+:101CC0002404FFFF0A001B0C8FBF002094990080A2
+:101CD000241F800024050001033FC024A498008035
+:101CE00090920080908E0080325100FF001181C2DE
+:101CF00000107827000F69C031CC007F018D582576
+:101D0000A08B00800E001934026020210A001B0BFA
+:101D1000000020212406FFFF54A6FFD68F84003840
+:101D2000026020210E001934240500010A001B0B5B
+:101D300000002021026020210A001B252402000A45
+:101D40002404FFFD0A001B0BAF9300608F8800384E
+:101D500027BDFFE8AFB00010AFBF0014910A00D458
+:101D60008F87004C00808021354900408CE60010B0
+:101D7000A10900D43C0208008C4231B030C53FFFBD
+:101D800000A2182B106000078F850050240DFF80E3
+:101D900090AE000D01AE6024318B00FF156000088D
+:101DA0000006C382020020212403000D8FBF00140F
+:101DB0008FB0001027BD00180A001A4AA3830068DC
+:101DC00033060003240F000254CFFFF70200202146
+:101DD00094A2001C8F85003824190023A4A200E8D7
+:101DE0008CE8000000081E02307F003F13F9003528
+:101DF0003C0A00838CE800188CA600D0110600086D
+:101E0000000000002405000E0E001A4AA385006899
+:101E10002407FFFF104700182404FFFF8F850038B8
+:101E200090A900D435240020A0A400D48F8C0044B5
+:101E3000918E000D31CD007FA18D000D8F83005458
+:101E40001060001C020020218F8400508C9800102C
+:101E50000303782B11E0000D241900180200202143
+:101E6000A39900680E001A4A2410FFFF10500002C8
+:101E70002404FFFF000020218FBF00148FB000104A
+:101E80000080102103E0000827BD00188C86001098
+:101E90008F9F00440200202100C31023AFE20010F6
+:101EA000240500010E0019A9240600010A001B9751
+:101EB000000020210E001934240500010A001B97A0
+:101EC00000002021010A5824156AFFD98F8C004494
+:101ED000A0A600FC0A001B84A386005A30A500FFC0
+:101EE0002406000124A9000100C9102B1040000C99
+:101EF00000004021240A000100A61823308B0001B5
+:101F000024C60001006A3804000420421160000267
+:101F100000C9182B010740251460FFF800A61823FC
+:101F200003E000080100102127BDFFD8AFB0001862
+:101F30008F90004CAFB1001CAFBF00202403FFFF07
+:101F40002411002FAFA30010920600002405000802
+:101F500026100001006620260E001BB0308400FF12
+:101F600000021E003C021EDC34466F410A001BD8F2
+:101F70000000102110A00009008018212445000154
+:101F800030A2FFFF2C4500080461FFFA0003204047
+:101F90000086202614A0FFF9008018210E001BB037
+:101FA000240500208FA300102629FFFF313100FFF8
+:101FB00000034202240700FF1627FFE20102182651
+:101FC00000035027AFAA0014AFAA00100000302170
+:101FD00027A8001027A7001400E6782391ED00033E
+:101FE00024CE000100C8602131C600FF2CCB0004C4
+:101FF0001560FFF9A18D00008FA200108FBF002097
+:102000008FB1001C8FB0001803E0000827BD002826
+:1020100027BDFFD0AFB3001CAFB00010AFBF00288A
+:10202000AFB50024AFB40020AFB20018AFB10014B8
+:102030003C0C80008D880128240FFF803C06800A1C
+:1020400025100100250B0080020F68243205007F57
+:10205000016F7024AD8E009000A62821AD8D002464
+:1020600090A600FC3169007F3C0A8004012A1821F7
+:10207000A386005A9067007C00809821AF830030CF
+:1020800030E20002AF88006CAF85003800A0182154
+:10209000144000022404003424040030A3840048C7
+:1020A0008C7200DC30D100FF24040004AF92006089
+:1020B00012240004A38000688E7400041680001EA1
+:1020C0003C0880009386005930C7000110E0000FE3
+:1020D0008F9300608CB000848CA800842404FF805F
+:1020E000020410240002F940310A007F03EA482567
+:1020F0003C0C2000012C902530CD00FE3C038000DC
+:10210000AC720830A38D00598F9300608FBF0028F8
+:102110008FB50024ACB300DC8FB400208FB3001C5B
+:102120008FB200188FB100148FB00010240200018C
+:1021300003E0000827BD00308E7F000895020120D3
+:102140008E67001003E2C8213326FFFF30D8000F4E
+:1021500033150001AF87003416A00058A39800582B
+:1021600035090C000309382100D81823AD03008479
+:10217000AF8700648E6A00043148FFFF1100007EC3
+:10218000A78A005C90AC00D42407FF8000EC3024C8
+:1021900030CB00FF1560004B9786005C938E005A91
+:1021A000240D000230D5FFFF11CD02A20000A021B6
+:1021B0008F85006002A5802B160000BC9388004824
+:1021C0003C11800096240120310400FF1485008812
+:1021D0008F8400648F9800343312000356400085CA
+:1021E00030A500FF8F900064310C00FF24060034FE
+:1021F00011860095AF90004C9204000414800118E1
+:102200008F8E0038A380003C8E0D00048DC800D84E
+:102210003C0600FF34CCFFFF01AC30240106182B34
+:1022200014600120AF8600548F8700609798005C8F
+:10223000AF8700400307402310C000C7A788005C99
+:102240008F91003030C3000300035823922A007C92
+:102250003171000302261021000A20823092000111
+:102260000012488000492821311FFFFF03E5C82BD9
+:10227000132001208F8800388F8500348F880064F8
+:102280001105025A3C0E3F018E0600003C0C250051
+:1022900000CE682411AC01638F84004C30E500FF50
+:1022A0000E00184A000030218F8800388F870060A8
+:1022B0008F8500340A001DB78F8600540A001C5613
+:1022C000AF87006490A400D400E48024320200FFB1
+:1022D000104000169386005990A6008890AE00D753
+:1022E00024A8008830D4003F2686FFE02CD10020AF
+:1022F000A38E003C1220000CAF88004C240B000180
+:1023000000CB20043095001916A0012B3C0680005C
+:1023100034CF0002008FC0241700022E3099002015
+:1023200017200234000000009386005930CB0001D2
+:102330001160000F9788005C8CBF00848CA900841A
+:10234000240AFF8003EA6024000C19403132007F28
+:10235000007238253C0D200000EDC82530D800FE65
+:102360003C0F8000ADF90830A39800599788005CB5
+:102370001500FF84000000008E630020306200041E
+:102380001040FF51938600592404FFFB0064802411
+:102390003C038000AE700020346601808C7301B86D
+:1023A0000660FFFE8F98006C347501003C1400013C
+:1023B000ACD800008C6B012424076085ACCB0004F2
+:1023C0008EAE000401D488245220000124076083CB
+:1023D00024190002A4C700083C0F1000A0D9000B6C
+:1023E0003C068000ACCF01B80A001C2B9386005934
+:1023F00030A500FF0E00184A240600018F88006CEB
+:102400003C05800034A90900250201889388004812
+:10241000304A0007304B00783C0340802407FF809F
+:102420000163C825014980210047F824310C00FFD1
+:1024300024060034ACBF0800AF90004CACB90810C3
+:102440005586FF6E920400048F8400388E11003090
+:10245000908E00D431CD001015A000108F83006045
+:102460002C6F000515E000E400000000909800D4F7
+:102470002465FFFC331200101640000830A400FF52
+:102480008F9F00648F99003413F90004388700018E
+:1024900030E20001144001C8000000000E001BC320
+:1024A000000000000A001DF8000000008F84006496
+:1024B00030C500FF0E00184A24060001939800481A
+:1024C000240B0034130B00A08F8500388F8600602A
+:1024D0009783005C306EFFFF00CE8823AF910060D1
+:1024E000A780005C1280FF90028018212414FFFD59
+:1024F0005474FFA28E6300208E6A00042403FFBF81
+:102500002408FFEF0155F823AE7F000490AC00D4FF
+:102510003189007FA0A900D48E7200208F8F0038EF
+:10252000A780005C364D0002AE6D0020A5E000BC27
+:1025300091E500D400A3C824A1F900D48F950038F8
+:10254000AEA000EC92B800D403085824A2AB00D48B
+:102550000A001CD78F8500388F910034AF8000604F
+:1025600002275821AF8B0034000020212403FFFFF5
+:10257000108301B48F8500388E0C00103C0D0800CC
+:102580008DAD31B09208000031843FFF008D802B6B
+:1025900012000023310D003F3C1908008F3931A88B
+:1025A0008F9F006C000479802408FF80033F202166
+:1025B000008FC821938500590328F8243C06008029
+:1025C0003C0F800034D80001001F91403331007F60
+:1025D0008F8600380251502535EE0940332B0078A4
+:1025E000333000073C0310003C02800C017890253A
+:1025F000020E48210143C0250222382134AE0001D9
+:10260000ADFF0804AF890050ADF20814AF87004455
+:10261000ADFF0028ACD90084ADF80830A38E005976
+:102620009383005A24070003106700272407000142
+:102630001467FFAC8F8500382411002311B1008589
+:1026400000000000240E000B026020210E001A4A38
+:10265000A38E00680040A0210A001D328F8500383B
+:1026600002602021240B000C0E001A4AA38B006884
+:10267000240AFFFF104AFFBD2404FFFF8F8E00389D
+:10268000A380003C8E0D00048DC800D83C0600FFDE
+:1026900034CCFFFF01AC30240106182B1060FEE2A1
+:1026A000AF86005402602021241200190E001A4A3D
+:1026B000A3920068240FFFFF104FFFAC2404FFFF1C
+:1026C0000A001C838F86005425A3FFE02C74002091
+:1026D0001280FFDD240E000B000328803C1108014E
+:1026E000263194B400B148218D2D000001A00008CE
+:1026F000000000008F85003400A710219385003C66
+:10270000AF82003402251821A383003C951F00BC32
+:102710000226282137F91000A51900BC5240FF926B
+:10272000AF850060246A0004A38A003C950900BCC0
+:1027300024A40004AF84006035322000A51200BC40
+:102740000A001D54000020218F8600602CC800055F
+:102750001500FF609783005C3065FFFF00C5C8234C
+:102760002F2F000511E00003306400FF24CDFFFC93
+:1027700031A400FF8F8900648F920034113200046D
+:10278000389F000133EC0001158001380000000083
+:102790008F840038908700D434E60010A08600D4DF
+:1027A0008F8500388F8600609783005CACA000ECBA
+:1027B0000A001D2F306EFFFF8CB500848CB400849E
+:1027C0003C04100002A7302400068940328E007FAE
+:1027D000022E8025020410253C08800024050001FB
+:1027E00002602021240600010E0019A9AD02083064
+:1027F0000A001CC38F8500388C8200EC1222FE7EFA
+:102800000260202124090005A38900680E001A4AED
+:102810002411FFFF1451FE782404FFFF0A001D5508
+:102820002403FFFF8F8F004C8F8800388DF8000045
+:10283000AD1800888DE70010AD0700988F87006005
+:102840000A001DB78F8600542406FFFF118600057D
+:10285000000000000E001B4C026020210A001D8FAA
+:102860000040A0210E001AD1026020210A001D8F15
+:102870000040A0218F90004C3C0208008C4231B0F7
+:102880008E110010322C3FFF0182282B10A0000C6B
+:10289000240BFF808F85005090A3000D01637024EE
+:1028A00031CA00FF1140000702602021001143825D
+:1028B000310600032418000110D8010600000000B2
+:1028C000026020212403000D0E001A4AA383006831
+:1028D000004020218F8500380A001D320080A02191
+:1028E0008F90004C3C0A08008D4A31B08F85005013
+:1028F0008E0400100000A0218CB1001430823FFF34
+:10290000004A602B8CB200205180FFEE0260202133
+:1029100090B8000D240BFF800178702431C300FFB4
+:102920005060FFE80260202100044382310600036A
+:1029300014C0FFE40260202194BF001C8F9900386E
+:102940008E060028A73F00E88CAF0010022F20233E
+:1029500014C4013A026020218F83005400C368210F
+:10296000022D382B14E00136240200188F8A00440F
+:102970008F820030024390218D4B00100163702341
+:10298000AD4E0010AD5200208C4C00740192282BEB
+:1029900014A0015F026020218F8400508E08002463
+:1029A0008C86002411060007026020212419001CD7
+:1029B0000E001A4AA3990068240FFFFF104FFFC5AD
+:1029C0002404FFFF8F8400448C87002424FF00012F
+:1029D000AC9F00241251012F8F8D00308DB10074F7
+:1029E0001232012C3C0B00808E0E000001CB5024D3
+:1029F00015400075000000008E0300142411FFFF35
+:102A0000107100073C0808003C0608008CC6319095
+:102A100000C8C0241300015202602021A380006876
+:102A20008E0300003C19000100792024108000135F
+:102A30003C1F0080007FA02416800009020028218E
+:102A4000026020212411001A0E001A4AA391006886
+:102A50002407FFFF1047FF9F2404FFFF02002821E7
+:102A6000026020210E001A6A240600012410FFFFD4
+:102A70001050FF982404FFFF241400018F8D0044A0
+:102A8000026020210280302195A900342405000134
+:102A9000253200010E0019A9A5B200340000202142
+:102AA0008F8500380A001D320080A0218F90004CD5
+:102AB0003C1408008E9431B08E07001030E53FFFC3
+:102AC00000B4C82B132000618F8600502412FF80B1
+:102AD00090C9000D0249682431A400FF5080005CB9
+:102AE000026020218F8C00541180000700078B8228
+:102AF0008F8500388F82FCC094BF0080944A000A02
+:102B0000515F00F78F8600403227000314E0006415
+:102B100000000000920E000211C000D8000000006A
+:102B20008E0B0024156000D902602021920400035E
+:102B300024190002308500FF14B90005308900FF18
+:102B40008F940054128000EA240D002C308900FF7D
+:102B5000392C00102D8400012D3200010244302553
+:102B6000020028210E001A6A026020212410FFFFB3
+:102B7000105000BF8F8500388F830054106000D341
+:102B8000240500013C0A08008D4A318C0143F82BD2
+:102B900017E000B22402002D02602021000028214D
+:102BA0000E0019A9240600018F85003800001821A5
+:102BB0000A001D320060A0210E0018750000000000
+:102BC0000A001DF800000000AC8000200A001E78FA
+:102BD0008E03001400002821026020210E0019A994
+:102BE000240600010A001CC38F8500380A001DB7A7
+:102BF0008F8800388CAA00848CAC00843C031000C1
+:102C00000147F824001F91403189007F024968255F
+:102C100001A32825ACC50830910700012405000157
+:102C2000026020210E0019A930E600010A001CC331
+:102C30008F850038938F00482403FFFD0A001D3460
+:102C4000AF8F00600A001D342403FFFF02602021C3
+:102C50002410000D0E001A4AA390006800401821AD
+:102C60008F8500380A001D320060A0210E00187503
+:102C7000000000009783005C8F86006000402021E8
+:102C80003070FFFF00D010232C4A00051140FE11C8
+:102C90008F850038ACA400EC0A001D2F306EFFFFBA
+:102CA00090CF000D31E300085460FFA192040003AF
+:102CB00002602021240200100E001A4AA38200683C
+:102CC0002403FFFF5443FF9A920400030A001F12DB
+:102CD0008F85003890A4000D308F000811E000951A
+:102CE0008F990054572000A6026020218E1F000CEF
+:102CF0008CB4002057F40005026020218E0D0008DE
+:102D00008CA7002411A7003A026020212402002091
+:102D1000A38200680E001A4A2412FFFF1052FEED33
+:102D20002404FFFF8F9F00442402FFF73C14800E11
+:102D300093EA000D2419FF803C03800001423824EF
+:102D4000A3E7000D8F9F00303C0908008D2931ACAE
+:102D50008F8C006C97F200788F870044012C302113
+:102D6000324D7FFF000D204000C4782131E5007F07
+:102D700000B4C02101F94024AC68002CA711000068
+:102D80008CEB0028256E0001ACEE00288CEA002CAC
+:102D90008E02002C01426021ACEC002C8E09002C2C
+:102DA000ACE900308E120014ACF2003494ED003A1D
+:102DB00025A40001A4E4003A97E600783C1108003D
+:102DC0008E3131B024C3000130707FFF1211005CDE
+:102DD000006030218F8F0030026020212405000127
+:102DE0000E001934A5E600780A001EA1000020217B
+:102DF0008E0900142412FFFF1132006B8F8A0038F5
+:102E00008E0200188D4C00D0144C00650260202109
+:102E10008E0B00248CAE0028116E005B2402002172
+:102E20000E001A4AA38200681452FFBE2404FFFF5A
+:102E30008F8500380A001D320080A0212402001F67
+:102E40000E001A4AA38200682409FFFF1049FEA160
+:102E50002404FFFF0A001E548F83005402602021C7
+:102E60000E001A4AA38200681450FF508F85003864
+:102E70002403FFFF0A001D320060A0218CD800242B
+:102E80008E0800241118FF29026020210A001F2744
+:102E90002402000F8E0900003C05008001259024CB
+:102EA0001640FF492402001A026020210E001A4A2F
+:102EB000A3820068240CFFFF144CFECF2404FFFF04
+:102EC0008F8500380A001D320080A0210E001934C1
+:102ED000026020218F8500380A001EE500001821BD
+:102EE0002403FFFD0060A0210A001D32AF860060B0
+:102EF000026020210E001A4AA38D00682403FFFF00
+:102F00001043FF588F8500380A001ECC920400033E
+:102F10002418001D0E001A4AA39800682403FFFF1E
+:102F20001443FE9D2404FFFF8F8500380A001D32E4
+:102F30000080A021026020210A001F3D24020024FD
+:102F4000240880000068C024330BFFFF000B73C20D
+:102F500031D000FF001088270A001F6E001133C017
+:102F6000240F001B0E001A4AA38F00681451FEACF8
+:102F70002404FFFF8F8500380A001D320080A02145
+:102F80000A001F3D240200278E0600288CA3002C77
+:102F900010C30008026020210A001F812402001FC4
+:102FA0000A001F812402000E026020210A001F81F6
+:102FB000240200258E04002C1080000D8F8F00301D
+:102FC0008DE800740104C02B5700000C0260202122
+:102FD0008CB900140086A0210334282B10A0FF52C6
+:102FE0008F9F0044026020210A001F8124020022DA
+:102FF000026020210A001F81240200230A001F8191
+:103000002402002627BDFFD8AFB3001CAFB10014C7
+:10301000AFBF0020AFB20018AFB000103C0280007C
+:103020008C5201408C4B01483C048000000B8C0208
+:10303000322300FF317300FF8C8501B804A0FFFE2E
+:1030400034900180AE1200008C8701442464FFF0AC
+:10305000240600022C830013AE070004A61100080A
+:10306000A206000BAE1300241060004F8FBF00209B
+:10307000000448803C0A0801254A9534012A402171
+:103080008D04000000800008000000003C030800E0
+:103090008C6331A831693FFF00099980007280215B
+:1030A000021370212405FF80264D0100264C00806C
+:1030B0003C02800031B1007F3198007F31CA007F2F
+:1030C0003C1F800A3C1980043C0F800C01C5202461
+:1030D00001A5302401853824014F1821AC46002475
+:1030E000023F402103194821AC470090AC4400281E
+:1030F000AF830044AF880038AF8900300E0019005C
+:10310000016080213C0380008C6B01B80560FFFEEC
+:103110008F8700448F8600383465018090E8000D69
+:10312000ACB20000A4B0000600082600000416039C
+:1031300000029027001227C21080008124C200885C
+:10314000241F6082A4BF0008A0A000052402000282
+:10315000A0A2000B8F8B0030000424003C08270045
+:1031600000889025ACB20010ACA00014ACA00024E4
+:10317000ACA00028ACA0002C8D6900382413FF807F
+:10318000ACA9001890E3000D02638024320500FF13
+:1031900010A000058FBF002090ED000D31AC007F26
+:1031A000A0EC000D8FBF00208FB3001C8FB2001861
+:1031B0008FB100148FB000103C0A10003C0E80004C
+:1031C00027BD002803E00008ADCA01B8265F010052
+:1031D0002405FF8033F8007F3C06800003E5782457
+:1031E0003C19800A03192021ACCF0024908E00D412
+:1031F00000AE682431AC00FF11800024AF84003899
+:10320000248E008895CD00123C0C08008D8C31A8CE
+:1032100031AB3FFF01924821000B5180012A402130
+:1032200001052024ACC400283107007F3C06800C37
+:1032300000E620219083000D00A31024304500FFFC
+:1032400010A0FFD8AF8400449098000D330F0010F9
+:1032500015E0FFD58FBF00200E0019000000000010
+:103260003C0380008C7901B80720FFFE00000000BD
+:10327000AE1200008C7F0144AE1F0004A6110008AE
+:1032800024110002A211000BAE1300243C1308010C
+:10329000927396F0327000015200FFC38FBF00207E
+:1032A0000E002146024020210A0020638FBF00202B
+:1032B0003C1260008E452C083C03F0033462FFFF93
+:1032C00000A2F824AE5F2C088E582C083C1901C0CF
+:1032D00003199825AE532C080A0020638FBF0020E5
+:1032E000264D010031AF007F3C10800A240EFF8084
+:1032F00001F0282101AE60243C0B8000AD6C00245D
+:103300001660FFA8AF85003824110003A0B100FCAF
+:103310000A0020638FBF002026480100310A007F89
+:103320003C0B800A2409FF80014B30210109202435
+:103330003C078000ACE400240A002062AF8600381D
+:10334000944E0012320C3FFF31CD3FFF15ACFF7D94
+:10335000241F608290D900D42418FF800319782498
+:1033600031EA00FF1140FF7700000000240700044D
+:10337000A0C700FC8F870044241160842406000D40
+:10338000A4B10008A0A600050A00204D24020002F6
+:103390003C040001248496DC24030014240200FE73
+:1033A0003C010800AC2431EC3C010800AC2331E8BE
+:1033B0003C010801A42296F83C040801248496F8F4
+:1033C0000000182100643021A0C300042463000120
+:1033D0002C6500FF54A0FFFC006430213C0708006E
+:1033E00024E7010003E00008AF87007800A058211F
+:1033F000008048210000102114A00012000050217C
+:103400000A002142000000003C010801A42096F8B7
+:103410003C05080194A596F88F8200783C0C0801C1
+:10342000258C96F800E2182100AC2021014B302BAE
+:10343000A089000400001021A460000810C0003919
+:10344000010048218F8600780009384000E94021BA
+:103450000008388000E6282190A8000B90B9000AE7
+:103460000008204000881021000218800066C0215A
+:10347000A319000A8F85007800E5782191EE000AF3
+:1034800091E6000B000E684001AE6021000C208028
+:1034900000851021A046000B3C030801906396F2C2
+:1034A000106000222462FFFF8F8300383C01080176
+:1034B000A02296F2906C00FF118000040000000032
+:1034C000906E00FF25CDFFFFA06D00FF3C190801A5
+:1034D000973996F8272300013078FFFF2F0F00FF60
+:1034E00011E0FFC9254A00013C010801A42396F818
+:1034F0003C05080194A596F88F8200783C0C0801E1
+:10350000258C96F800E2182100AC2021014B302BCD
+:10351000A089000400001021A460000814C0FFC9A5
+:103520000100482103E000080000000003E000085B
+:103530002402000227BDFFE0248501002407FF804C
+:10354000AFB00010AFBF0018AFB1001400A718242F
+:103550003C10800030A4007F3C06800A00862821B1
+:103560008E110024AE03002490A200FF1440000836
+:10357000AF850038A0A000098FBF0018AE1100244D
+:103580008FB100148FB0001003E0000827BD0020A9
+:1035900090A900FD90A800FF312400FF0E0020F448
+:1035A000310500FF8F8500388FBF0018A0A00009EB
+:1035B000AE1100248FB100148FB0001003E000089A
+:1035C00027BD002027BDFFD0AFB20020AFB1001C47
+:1035D000AFB00018AFBF002CAFB40028AFB30024C9
+:1035E0003C0980009533011635320C00952F011AE5
+:1035F0003271FFFF023280218E08000431EEFFFF9E
+:10360000248B0100010E6821240CFF8025A5FFFFFB
+:10361000016C50243166007F3C07800AAD2A0024EB
+:1036200000C73021AF850074AF8800703C010801ED
+:10363000A02096F190C300090200D02100809821BB
+:10364000306300FF2862000510400048AF86003854
+:10365000286400021480008E24140001240D00054B
+:103660003C010801A02D96D590CC00FD3C0108013D
+:10367000A02096D63C010801A02096D790CB000A46
+:10368000240AFF80318500FF014B4824312700FFC9
+:1036900010E0000C000058213C12800836510080D8
+:1036A0008E2F00308CD0005C01F0702305C0018E9D
+:1036B0008F87007090D4000A3284007FA0C4000A73
+:1036C0008F8600383C118008363000808E0F003025
+:1036D0008F87007000EF702319C000EE000000001B
+:1036E00090D4000924120002328400FF1092024795
+:1036F000000000008CC2005800E2F82327F9FFFF09
+:103700001B2001300000000090C5000924080004BF
+:1037100030A300FF10680057240A00013C01080193
+:10372000A02A96D590C900FF252700013C01080179
+:10373000A02796D43C030801906396D52406000583
+:103740001066006A2C780005130000C40000902168
+:103750000003F8803C0408012484958003E4C82118
+:103760008F25000000A0000800000000241800FFC2
+:103770001078005C0000000090CC000A90CA00099C
+:103780003C080801910896F13187008000EA48253D
+:103790003C010801A02996DC90C500FD3C140801FD
+:1037A000929496F2311100013C010801A02596DDAA
+:1037B00090DF00FE3C010801A03F96DE90D200FFA2
+:1037C0003C010801A03296DF8CD900543C0108016D
+:1037D000AC3996E08CD000583C010801AC3096E43E
+:1037E0008CC3005C3C010801AC3496EC3C01080140
+:1037F000AC2396E8162000088FBF002C8FB4002859
+:103800008FB300248FB200208FB1001C8FB000183E
+:1038100003E0000827BD00303C1180009624010E13
+:103820000E000FD43094FFFF3C0B08018D6B96F413
+:103830000260382102802821AE2B01803C13080150
+:103840008E7396D401602021240600830E00102F71
+:10385000AFB300108FBF002C8FB400288FB30024AB
+:103860008FB200208FB1001C8FB0001803E0000859
+:1038700027BD00303C1808008F1831FC270F0001CD
+:103880003C010800AC2F31FC0A0021D700000000E9
+:103890001474FFB900000000A0C000FF3C05080040
+:1038A0008CA531E43C0308008C6331E03C02080045
+:1038B0008C4232048F99003834A80001241F000282
+:1038C0003C010801AC2396F43C010801A02896F0C5
+:1038D0003C010801A02296F3A33F00090A002190B1
+:1038E0008F8600380E002146000000000A0021D714
+:1038F0008F8600383C1F080193FF96D424190001DD
+:1039000013F902298F8700703C100801921096D895
+:103910003C06080190C696D610C000050200A02102
+:103920003C040801908496D9109001E48F870078B8
+:10393000001088408F9F0078023048210009C8801D
+:10394000033F702195D80008270F0001A5CF00087C
+:103950003C040801908496D93C05080190A596D6B0
+:103960000E0020F4000000008F8700780230202134
+:103970000004308000C720218C8500048F820074F1
+:1039800000A2402305020006AC8200048C8A0000DD
+:103990008F830070014310235C400001AC83000062
+:1039A0008F86003890CB00FF2D6C00025580002DD3
+:1039B000241400010230F821001F40800107282153
+:1039C00090B9000B8CAE00040019C0400319782197
+:1039D000000F1880006710218C4D000001AE882375
+:1039E0002630FFFF5E00001F241400018C440004F9
+:1039F0008CAA0000008A482319200019240E000414
+:103A00003C010801A02E96D590AD000B8CAB0004B4
+:103A1000000D8840022D80210010108000471021E9
+:103A20008C44000401646023058202009443000872
+:103A300090DF00FE90B9000B33E500FF54B900049D
+:103A40000107A021A0D400FE8F8700780107A021E4
+:103A50009284000B0E0020F4240500018F860038AC
+:103A600024140001125400962E500001160000424A
+:103A70003C08FFFF241900021659FF3F0000000018
+:103A8000A0C000FF8F860038A0D200090A0021D70D
+:103A90008F86003890C700092404000230E300FF3D
+:103AA0001064016F24090004106901528F880074AA
+:103AB0008CCE0054010E682325B10001062001754B
+:103AC000241800043C010801A03896D53C010801E7
+:103AD000A02096D490D400FD90D200FF2E4F00027B
+:103AE00015E0FF14328400FF000438408F8900780D
+:103AF00090DF00FF00E41021000220800089C8212F
+:103B00002FE500029324000B14A0FF0A24070002F3
+:103B100000041840006480210010588001692821A9
+:103B20008CAC0004010C50230540FF020000000093
+:103B30003C030801906396D614600005246F0001D1
+:103B40003C010801A02496D93C010801A02796D782
+:103B50003C010801A02F96D690CE00FF24E700017B
+:103B600031CD00FF01A7882B1220FFE990A4000BA4
+:103B70000A0021C6000000003C0508018CA596D46F
+:103B80003C12000400A8F82413F2000624020005E9
+:103B90003C090801912996D5152000022402000352
+:103BA000240200053C010801A02296F190C700FF05
+:103BB00014E0012024020002A0C200090A0021D75B
+:103BC0008F86003890CC00FF1180FEDA240A0001B5
+:103BD0008F8C00748F890078240F00030180682186
+:103BE0001160001E240E0002000540400105A021C6
+:103BF00000142080008990218E51000401918023BF
+:103C00000600FECC000000003C020801904296D65F
+:103C100014400005245800013C010801A02A96D751
+:103C20003C010801A02596D93C010801A03896D690
+:103C300090DF00FF010510210002C88033E500FF7E
+:103C4000254A00010329202100AA402B1500FEB9B6
+:103C50009085000B1560FFE50005404000054040E1
+:103C600001051821000310803C010801A02A96D408
+:103C70003C010801A02596D8004918218C64000455
+:103C800000E4F82327F9FFFF1F20FFE900000000F0
+:103C90008C63000000E358230560013A01A38823E8
+:103CA00010E301170184C0231B00FEA200000000E6
+:103CB0003C010801A02E96D50A002305240B000123
+:103CC000240E0004A0CE00093C0D08008DAD31F893
+:103CD0008F86003825A200013C010800AC2231F893
+:103CE0000A0021D7000000008CD9005C00F9C02335
+:103CF0001F00FE7B000000008CDF005C10FFFF65F2
+:103D00008F8400748CC3005C008340232502000173
+:103D10001C40FF60000000008CC9005C248700018B
+:103D200000E9282B10A0FE943C0D80008DAB01040F
+:103D30003C0C0001016C50241140FE8F2402001045
+:103D40003C010801A02296F10A0021D700000000E2
+:103D50008F9100748F86003826220001ACC2005C6F
+:103D60000A002292241400018F8700382404FF8067
+:103D70000000882190E9000A241400010124302564
+:103D8000A0E6000A3C05080190A596D63C0408016F
+:103D9000908496D90E0020F4000000008F86003831
+:103DA0008F85007890C800FD310700FF0007404074
+:103DB0000107F821001FC0800305C8219323000BD1
+:103DC000A0C300FD8F8500788F8600380305602131
+:103DD000918F000B000F704001CF6821000D808093
+:103DE000020510218C4B0000ACCB00548D840004E4
+:103DF0008F83007400645023194000022482000164
+:103E00002462000101074821ACC2005C0009308037
+:103E100000C5402100E02021240500010E0020F40F
+:103E20009110000B8F86003890C500FF10A0FF0C8A
+:103E3000001070408F85007801D06821000D10803F
+:103E4000004558218D6400008F8C0074018450233C
+:103E50002547000104E0FF02263100013C03080170
+:103E6000906396D62E2F0002247800013C010801B1
+:103E7000A03896D63C010801A03496D711E0FEF890
+:103E8000020038210A002365000740408F84003873
+:103E90008F8300748C85005800A340230502FE9A8E
+:103EA000AC8300580A00223B000000003C070801D8
+:103EB00090E796F2240200FF10E200BE8F860038E1
+:103EC0003C110801963196FA3C030801246396F8E8
+:103ED000262500013230FFFF30ABFFFF02036021D7
+:103EE0002D6A00FF1540008D918700043C010801F8
+:103EF000A42096FA8F88003800074840012728211F
+:103F0000911800FF000530802405000127140001EE
+:103F1000A11400FF3C120801925296F28F8800789B
+:103F20008F8E0070264F000100C820213C0108013F
+:103F3000A02F96F2AC8E00008F8D0074A48500082F
+:103F4000AC8D00043C030801906396D414600077A4
+:103F5000000090213C010801A02596D4A087000B09
+:103F60008F8C007800CC5021A147000A8F82003846
+:103F7000A04700FD8F840038A08700FE8F860038A0
+:103F80008F9F0070ACDF00548F990074ACD900583B
+:103F90008F8D00780127C02100185880016DA02165
+:103FA000928F000A000F704001CF18210003888013
+:103FB000022D8021A207000B8F8600780166602108
+:103FC000918A000B000A1040004A2021000428803A
+:103FD00000A64021A107000A3C07800834E90080C0
+:103FE0008D2200308F860038ACC2005C0A0022921D
+:103FF0002414000190CA00FF1540FEAD8F880074A4
+:10400000A0C400090A0021D78F860038A0C000FD97
+:104010008F98003824060001A30000FE3C0108012F
+:10402000A02696D53C010801A02096D40A0021C6FE
+:104030000000000090CB00FF3C040801908496F340
+:10404000316C00FF0184502B1540000F2402000347
+:1040500024020004A0C200090A0021D78F8600387C
+:1040600090C3000A2410FF8002035824316C00FF23
+:104070001180FDC1000000003C010801A02096D580
+:104080000A0021C600000000A0C200090A0021D7D2
+:104090008F86003890D4000A2412FF8002544824EE
+:1040A000312800FF1500FFF4240200083C0108013C
+:1040B000A02296F10A0021D70000000000108840DD
+:1040C0008F8B0070023018210003688001A7202127
+:1040D000AC8B00008F8A0074240C0001A48C0008B3
+:1040E000AC8A00043C05080190A596D62402000184
+:1040F00010A2FE1E24A5FFFF0A0022519084000B8F
+:104100000184A0231A80FD8B000000003C010801FF
+:10411000A02E96D50A002305240B00013C010801BE
+:10412000A42596FA0A0023B78F880038240B0001D3
+:10413000106B00228F9800388F85003890BF00FFE9
+:1041400033F900FF1079002B000000003C1F08012C
+:1041500093FF96D8001FC840033FC0210018A080DD
+:104160000288782191EE000AA08E000A8F8D0078D7
+:104170003C030801906396D800CD88210A0023DD16
+:10418000A223000B263000010600003101A4902379
+:104190000640002B240200033C010801A02F96D505
+:1041A0000A002305240B00018F8900380A00223BF6
+:1041B000AD2700540A00229124120001931400FD3F
+:1041C000A094000B8F8800388F8F0078910E00FE2E
+:1041D00000CF6821A1AE000A8F910038A22700FD10
+:1041E0008F8300708F900038AE0300540A0023DEE6
+:1041F0008F8D007890B000FEA090000A8F8B003861
+:104200008F8C0078916A00FD00CC1021A04A000B31
+:104210008F840038A08700FE8F8600748F85003859
+:10422000ACA600580A0023DE8F8D007894B80008F1
+:10423000ACA40004030378210A002285A4AF00087F
+:104240003C010801A02296D50A0021C6000000000A
+:1042500090CF0009240D000431EE00FF11CDFD8543
+:10426000240200013C010801A02296D50A0021C6C3
+:1042700000000000080033440800334408003420E4
+:10428000080033F4080033D8080033280800332826
+:10429000080033280800334C8008010080080080A3
+:1042A000800800005F865437E4AC62CC50103A4579
+:1042B00036621985BF14C0E81BC27A1E84F4B55655
+:1042C000094EA6FE7DDA01E7C04D748108005A74DC
+:1042D00008005AB808005A5C08005A5C08005A5C8A
+:1042E00008005A5C08005A7408005A5C08005A5CBE
+:1042F00008005AC008005A5C080059D408005A5CEB
+:1043000008005A5C08005AC008005A5C08005A5C51
+:1043100008005A5C08005A5C08005A5C08005A5CA5
+:1043200008005A5C08005A5C08005A5C08005A5C95
+:1043300008005A9408005A5C08005A9408005A5C15
+:1043400008005A5C08005A5C08005A9808005A9401
+:1043500008005A5C08005A5C08005A5C08005A5C65
+:1043600008005A5C08005A5C08005A5C08005A5C55
+:1043700008005A5C08005A5C08005A5C08005A5C45
+:1043800008005A5C08005A5C08005A5C08005A5C35
+:1043900008005A5C08005A5C08005A5C08005A5C25
+:1043A00008005A9808005A9808005A5C08005A9861
+:1043B00008005A5C08005A5C08005A5C08005A5C05
+:1043C00008005A5C08005A5C08005A5C08005A5CF5
+:1043D00008005A5C08005A5C08005A5C08005A5CE5
+:1043E00008005A5C08005A5C08005A5C08005A5CD5
+:1043F00008005A5C08005A5C08005A5C08005A5CC5
+:1044000008005A5C08005A5C08005A5C08005A5CB4
+:1044100008005A5C08005A5C08005A5C08005A5CA4
+:1044200008005A5C08005A5C08005A5C08005A5C94
+:1044300008005A5C08005A5C08005A5C08005A5C84
+:1044400008005A5C08005A5C08005A5C08005A5C74
+:1044500008005A5C08005A5C08005A5C08005A5C64
+:1044600008005A5C08005A5C08005A5C08005A5C54
+:1044700008005A5C08005A5C08005A5C08005A5C44
+:1044800008005A5C08005A5C08005A5C08005A5C34
+:1044900008005A5C08005A5C08005A5C08005A5C24
+:1044A00008005A5C08005A5C08005A5C08005A5C14
+:1044B00008005A5C08005A5C08005A5C08005A5C04
+:1044C00008005A5C08005A5C08005A5C08005ADC74
+:1044D0000800782C08007A900800783808007628C0
+:1044E00008007838080078C4080078380800762872
+:1044F0000800762808007628080076280800762824
+:104500000800762808007628080076280800762813
+:1045100008007628080078580800784808007628AF
+:1045200008007628080076280800762808007628F3
+:1045300008007628080076280800762808007628E3
+:1045400008007628080076280800762808007848B1
+:10455000080082FC08008188080082C40800818865
+:104560000800829408008070080081880800818813
+:1045700008008188080081880800818808008188F7
+:1045800008008188080081880800818808008188E7
+:104590000800818808008188080081B008008D34F7
+:1045A00008008E9008008E70080088D808008D4C96
+:1045B0000A00012400000000000000000000000DBF
+:1045C000747061362E322E31620000000602010145
+:1045D00000000000000000000000000000000000DB
+:1045E00000000000000000000000000000000000CB
+:1045F00000000000000000000000000000000000BB
+:1046000000000000000000000000000000000000AA
+:10461000000000000000000000000000000000009A
+:10462000000000000000000000000000000000008A
+:10463000000000000000000000000000000000007A
+:104640000000000010000003000000000000000D4A
+:104650000000000D3C020800244217203C03080023
+:1046600024632A10AC4000000043202B1480FFFD7F
+:10467000244200043C1D080037BD2FFC03A0F0219C
+:104680003C100800261004903C1C0800279C1720B2
+:104690000E000262000000000000000D2402FF80F6
+:1046A00027BDFFE000821024AFB00010AF42002011
+:1046B000AFBF0018AFB10014936500043084007FD1
+:1046C000034418213C0200080062182130A5002094
+:1046D000036080213C080111277B000814A0000220
+:1046E0002466005C2466005892020004974301048B
+:1046F000920400043047000F3063FFFF3084004015
+:10470000006728231080000900004821920200055C
+:1047100030420004104000050000000010A000031B
+:104720000000000024A5FFFC2409000492020005FB
+:1047300030420004104000120000000010A00010E1
+:10474000000000009602000200A72021010440257D
+:104750002442FFFEA7421016920300042402FF80A9
+:1047600000431024304200FF104000033C020400CC
+:104770000A000174010240258CC20000AF421018EB
+:104780008F4201780440FFFE2402000AA742014044
+:1047900096020002240400093042000700021023A0
+:1047A00030420007A7420142960200022442FFFE67
+:1047B000A7420144A740014697420104A74201488D
+:1047C0008F420108304200205040000124040001C3
+:1047D00092020004304200101440000234830010A2
+:1047E00000801821A743014A0000000000000000DB
+:1047F0000000000000000000AF48100000000000B2
+:104800000000000000000000000000008F421000C7
+:104810000441FFFE3102FFFF1040000700000000CE
+:1048200092020004304200401440000300000000E7
+:104830008F421018ACC20000960200063042FFFF03
+:10484000244200020002104300021040036288214B
+:10485000962200001120000D3044FFFF00A7102118
+:104860008F8300388F45101C0002108200021080D8
+:1048700000431021AC45000030A6FFFF0E00058D5F
+:1048800000052C0200402021A62200009203000413
+:104890002402FF8000431024304200FF1040001F1C
+:1048A0000000000092020005304200021040001B90
+:1048B000000000009742100C2442FFFEA742101691
+:1048C000000000003C02040034420030AF421000FF
+:1048D00000000000000000000000000000000000D8
+:1048E0008F4210000441FFFE000000009742100CB0
+:1048F0008F45101C3042FFFF24420030000210821E
+:1049000000021080005B1021AC45000030A6FFFFC4
+:104910000E00058D00052C02A62200009604000260
+:10492000248400080E0001E93084FFFF974401044D
+:104930000E0001F73084FFFF8FBF00188FB1001405
+:104940008FB000103C02100027BD002003E00008DB
+:10495000AF4201783084FFFF308200078F8500244A
+:1049600010400002248300073064FFF800A41021E7
+:1049700030421FFF03421821247B4000AF850028EE
+:10498000AF82002403E00008AF4200843084FFFFC0
+:104990003082000F8F85002C8F860034104000027B
+:1049A0002483000F3064FFF000A410210046182B70
+:1049B000AF8500300046202314600002AF82002C37
+:1049C000AF84002C8F82002C340480000342182115
+:1049D00000641821AF83003803E00008AF42008074
+:1049E0008F820014104000088F8200048F82FFDC49
+:1049F000144000058F8200043C02FFBF3442FFFFD9
+:104A0000008220248F82000430430006240200022A
+:104A10001062000F3C0201012C62000350400005AF
+:104A2000240200041060000F3C0200010A00023062
+:104A30000000000010620005240200061462000C51
+:104A40003C0201110A000229008210253C020011DB
+:104A500000821025AF421000240200010A0002303B
+:104A6000AF82000C00821025AF421000AF80000C16
+:104A700000000000000000000000000003E000084B
+:104A8000000000008F82000C1040000400000000B5
+:104A90008F4210000441FFFE0000000003E0000808
+:104AA000000000008F8200102443F800000231C291
+:104AB00024C2FFF02C6303011060000300021042C7
+:104AC0000A000257AC8200008F85001800C5102B29
+:104AD0001440000B0000182100C5102324470001DA
+:104AE0008F82001C00A210212442FFFF0046102BE1
+:104AF000544000042402FFFF0A000257AC87000064
+:104B00002402FFFF0A000260AC8200008C820000D9
+:104B10000002194000621821000318800062182169
+:104B2000000318803C0208002442175C0062182130
+:104B300003E000080060102127BDFFD8AFBF0020B0
+:104B4000AFB1001CAFB000183C0460088C8250006C
+:104B50002403FF7F3C066000004310243442380CDD
+:104B6000AC8250008CC24C1C3C1A80000002160221
+:104B70003042000F10400007AF82001C8CC34C1C59
+:104B80003C02001F3442FC0000621824000319C2DA
+:104B9000AF8300188F420008275B400034420001B9
+:104BA000AF420008AF8000243C02601CAF40008090
+:104BB000AF4000848C4500088CC308083402800094
+:104BC000034220212402FFF0006218243C020080EE
+:104BD0003C010800AC2204203C025709AF84003895
+:104BE00014620004AF850034240200010A0002921E
+:104BF000AF820014AF8000148F42000038420001E1
+:104C0000304200011440FFFC8F8200141040001657
+:104C10000000000097420104104000058F8300004F
+:104C2000146000072462FFFF0A0002A72C62000A3A
+:104C30002C620010504000048F83000024620001A9
+:104C4000AF8200008F8300002C62000A1440000332
+:104C50002C6200070A0002AEAF80FFDC10400002A9
+:104C600024020001AF82FFDC8F4301088F44010062
+:104C700030622000AF83000410400008AF840010B1
+:104C80003C0208008C42042C244200013C01080034
+:104C9000AC22042C0A00058A3C0240003065020068
+:104CA00014A0000324020F001482026024020D00ED
+:104CB00097420104104002C83C02400030624000AC
+:104CC000144000AD8F8200388C4400088F42017878
+:104CD0000440FFFE24020800AF42017824020008CD
+:104CE000A7420140A7400142974201048F8400047B
+:104CF0003051FFFF30820001104000070220802168
+:104D00002623FFFE240200023070FFFFA742014667
+:104D10000A0002DBA7430148A74001463C02080005
+:104D20008C42043C1440000D8F8300103082002020
+:104D30001440000224030009240300010060202124
+:104D40008F830010240209005062000134840004A3
+:104D5000A744014A0A0002F60000000024020F00E6
+:104D60001462000530820020144000062403000D68
+:104D70000A0002F524030005144000022403000980
+:104D800024030001A743014A3C0208008C4204208E
+:104D90003C0400480E00020C004420250E000235A1
+:104DA000000000008F82000C1040003E0000000058
+:104DB0008F4210003C0300200043102410400039B3
+:104DC0008F820004304200021040003600000000D4
+:104DD000974210141440003300000000974210085E
+:104DE0008F8800383042FFFF2442000600021882FC
+:104DF0000003388000E83021304300018CC40000FB
+:104E000010600004304200030000000D0A00033768
+:104E100000E81021544000103084FFFF3C05FFFFE4
+:104E200000852024008518260003182B0004102B71
+:104E300000431024104000050000000000000000A6
+:104E40000000000D00000000240002228CC20000BF
+:104E50000A000336004520253883FFFF0003182B86
+:104E60000004102B00431024104000050000000037
+:104E7000000000000000000D000000002400022BD4
+:104E80008CC200003444FFFF00E81021AC44000055
+:104E90003C0208008C420430244200013C0108001E
+:104EA000AC2204308F6200008F840038AF8200088B
+:104EB0008C8300003402FFFF1462000F00001021F9
+:104EC0003C0508008CA504543C0408008C84045064
+:104ED00000B0282100B0302B008220210086202144
+:104EE0003C010800AC2504543C010800AC240450EB
+:104EF0000A000580240400088C8200003042010072
+:104F00001040000F000010213C0508008CA5044C47
+:104F10003C0408008C84044800B0282100B0302BE9
+:104F200000822021008620213C010800AC25044C91
+:104F30003C010800AC2404480A0005802404000851
+:104F40003C0508008CA504443C0408008C84044003
+:104F500000B0282100B0302B0082202100862021C3
+:104F60003C010800AC2504443C010800AC2404408A
+:104F70000A000580240400088F6200088F62000088
+:104F800000021602304300F02402003010620005D7
+:104F900024020040106200E08F8200200A00058891
+:104FA0002442000114A000050000000000000000E1
+:104FB0000000000D00000000240002568F4201781E
+:104FC0000440FFFE000000000E00023D27A4001078
+:104FD0001440000500408021000000000000000D8A
+:104FE000000000002400025D8E0200001040000559
+:104FF00000000000000000000000000D00000000A4
+:10500000240002608F62000C0443000324020001AC
+:105010000A00042EAE000000AE0200008F820038AD
+:105020008C480008A20000078F65000C8F64000404
+:1050300030A3FFFF0004240200852023308200FFFC
+:105040000043102124420005000230832CC200815D
+:10505000A605000A14400005A20400040000000098
+:105060000000000D00000000240002788F85003849
+:105070000E0005AB260400148F6200048F43010864
+:10508000A60200083C02100000621824106000080C
+:105090000000000097420104920300072442FFEC45
+:1050A000346300023045FFFF0A0003C3A203000778
+:1050B000974201042442FFF03045FFFF96060008A6
+:1050C0002CC200135440000592030007920200070F
+:1050D00034420001A20200079203000724020001EB
+:1050E00010620005240200031062000B8F8200385A
+:1050F0000A0003E030C6FFFF8F8200383C04FFFF48
+:105100008C43000C0064182400651825AC43000C87
+:105110000A0003E030C6FFFF3C04FFFF8C43001091
+:105120000064182400651825AC43001030C6FFFF4A
+:1051300024C2000200021083A20200058F830038FF
+:10514000304200FF00021080004328218CA800009C
+:105150008CA2000024030004000217021443001272
+:1051600000000000974201043C03FFFF01031824E4
+:105170003042FFFF004610232442FFFE006240251C
+:10518000ACA8000092030005306200FF000210800E
+:1051900000501021904200143042000F00431021B3
+:1051A0000A000415A20200068CA400049742010420
+:1051B0009603000A3088FFFF3042FFFF00461023AD
+:1051C0002442FFD60002140001024025ACA80004CE
+:1051D000920200079204000524630028000318834C
+:1051E0000064182134420004A2030006A202000752
+:1051F0008F8200042403FFFB34420002004310248A
+:10520000AF820004920300068F87003800031880E5
+:10521000007010218C4400203C02FFF63442FFFF56
+:105220000082402400671821AE04000CAC68000C1A
+:10523000920500063C03FF7F8E02000C00052880CB
+:1052400000B020213463FFFF01033024948800263E
+:1052500000A7282100431024AE02000CAC860020D9
+:10526000AC880024ACA8001024020010A742014022
+:1052700024020002A7400142A7400144A742014680
+:10528000974201043C0400082442FFFEA742014863
+:10529000240200010E00020CA742014A9603000AF4
+:1052A0009202000400431021244200023042000711
+:1052B00000021023304200070E000235AE0200103B
+:1052C0008F6200003C0308008C6304442404001037
+:1052D000AF820008974201043042FFFF2442FFFEE4
+:1052E00000403821000237C33C0208008C420440D1
+:1052F000006718210067282B004610210045102167
+:105300003C010800AC2304443C010800AC220440EA
+:105310000A0005150000000014A0000500000000B0
+:10532000000000000000000D000000002400030A3F
+:105330008F4201780440FFFE000000000E00023D95
+:1053400027A4001414400005004080210000000044
+:105350000000000D00000000240003118E02000078
+:105360005440000692020007000000000000000DFB
+:10537000000000002400031C9202000730420004D9
+:10538000104000058F8200042403FFFB344200021A
+:1053900000431024AF8200048F620004044300081D
+:1053A00092020007920200068E03000CAE0000007D
+:1053B0000002108000501021AC4300209202000730
+:1053C00030420004544000099602000A920200058F
+:1053D0003C03000100021080005010218C46001890
+:1053E00000C33021AC4600189602000A9206000461
+:1053F000277100080220202100C2302124C60005A8
+:10540000260500140E0005AB00063082920400064B
+:105410008F6500043C027FFF000420800091202162
+:105420008C8300043442FFFF00A228240065182169
+:10543000AC8300049202000792040005920300046A
+:10544000304200041040001496070008308400FF2A
+:1054500000042080009120218C86000497420104E2
+:105460009605000A306300FF3042FFFF0043102121
+:105470000045102130E3FFFF004310232442FFD8F2
+:1054800030C6FFFF0002140000C23025AC860004C5
+:105490000A0004C992030007308500FF0005288038
+:1054A00000B128218CA4000097420104306300FF62
+:1054B0003042FFFF00431021004710233C03FFFF51
+:1054C000008320243042FFFF00822025ACA400008E
+:1054D0009203000724020001106200060000000091
+:1054E0002402000310620011000000000A0004EC16
+:1054F0008E03001097420104920300049605000AEF
+:105500008E24000C00431021004510212442FFF29C
+:105510003C03FFFF008320243042FFFF0082202550
+:10552000AE24000C0A0004EC8E0300109742010424
+:10553000920300049605000A8E24001000431021F7
+:10554000004510212442FFEE3C03FFFF008320248E
+:105550003042FFFF00822025AE2400108E03001091
+:105560002402000AA7420140A74301429603000A11
+:10557000920200043C04004000431021A742014471
+:10558000A740014697420104A742014824020001B6
+:105590000E00020CA742014A0E0002350000000076
+:1055A0008F6200009203000400002021AF820008F7
+:1055B000974201049606000A3042FFFF006218215C
+:1055C000006028213C0308008C6304443C0208006E
+:1055D0008C42044000651821004410210065382BDE
+:1055E000004710213C010800AC2304443C010800A2
+:1055F000AC22044092040004008620212484000A86
+:105600003084FFFF0E0001E9000000009744010410
+:105610003084FFFF0E0001F7000000003C02100084
+:10562000AF4201780A0005878F820020148200278C
+:105630003062000697420104104000673C024000BF
+:105640003062400010400005000000000000000033
+:105650000000000D00000000240004208F420178AB
+:105660000440FFFE24020800AF4201782402000833
+:10567000A7420140A74001428F82000497430104E2
+:1056800030420001104000073070FFFF2603FFFE8C
+:1056900024020002A7420146A74301480A00053F31
+:1056A0002402000DA74001462402000DA742014A32
+:1056B0008F62000024040008AF8200080E0001E998
+:1056C000000000000A0005190200202110400042DD
+:1056D0003C02400093620000304300F024020010BE
+:1056E0001062000524020070106200358F820020D5
+:1056F0000A000588244200018F62000097430104DC
+:105700003050FFFF3071FFFF8F4201780440FFFEF1
+:105710003202000700021023304200072403000A6F
+:105720002604FFFEA7430140A7420142A7440144CB
+:10573000A7400146A75101488F420108304200208E
+:10574000144000022403000924030001A743014A76
+:105750000E00020C3C0400400E0002350000000068
+:105760003C0708008CE70444021110212442FFFE8C
+:105770003C0608008CC604400040182100E3382194
+:10578000000010218F65000000E3402B00C2302193
+:105790002604000800C830213084FFFFAF850008D0
+:1057A0003C010800AC2704443C010800AC2604403E
+:1057B0000E0001E9000000000A0005190220202166
+:1057C0000E00013B000000008F82002024420001F7
+:1057D000AF8200203C024000AF4201380A00029232
+:1057E000000000003084FFFF30C6FFFF00052C00E2
+:1057F00000A628253882FFFF004510210045282BF0
+:105800000045102100021C023042FFFF004310211E
+:1058100000021C023042FFFF004310213842FFFF0C
+:1058200003E000083042FFFF3084FFFF30A5FFFF98
+:1058300000001821108000070000000030820001E5
+:105840001040000200042042006518210A0005A152
+:105850000005284003E000080060102110C0000689
+:1058600024C6FFFF8CA2000024A50004AC82000027
+:105870000A0005AB2484000403E0000800000000D7
+:1058800010A0000824A3FFFFAC8600000000000069
+:10589000000000002402FFFF2463FFFF1462FFFAF0
+:1058A0002484000403E00008000000000000000160
+:1058B0000A00002A00000000000000000000000DA7
+:1058C000747870362E322E3162000000060201001C
+:1058D00000000000000001360000EA600000000047
+:1058E00000000000000000000000000000000000B8
+:1058F00000000000000000000000000000000000A8
+:105900000000000000000000000000000000000097
+:105910000000001600000000000000000000000071
+:105920000000000000000000000000000000000077
+:105930000000000000000000000000000000000067
+:1059400000000000000000000000138800000000BC
+:10595000000005DC00000000000000001000000353
+:10596000000000000000000D0000000D3C020800D7
+:1059700024423D683C0308002463401CAC40000006
+:105980000043202B1480FFFD244200043C1D08002E
+:1059900037BD7FFC03A0F0213C100800261000A8B2
+:1059A0003C1C0800279C3D680E00044E00000000CF
+:1059B0000000000D27BDFFB4AFA10000AFA200049E
+:1059C000AFA30008AFA4000CAFA50010AFA6001451
+:1059D000AFA70018AFA8001CAFA90020AFAA0024F1
+:1059E000AFAB0028AFAC002CAFAD0030AFAE003491
+:1059F000AFAF0038AFB8003CAFB90040AFBC004417
+:105A0000AFBF00480E000591000000008FBF0048A6
+:105A10008FBC00448FB900408FB8003C8FAF003876
+:105A20008FAE00348FAD00308FAC002C8FAB0028D0
+:105A30008FAA00248FA900208FA8001C8FA7001810
+:105A40008FA600148FA500108FA4000C8FA3000850
+:105A50008FA200048FA1000027BD004C3C1B6004F6
+:105A60008F7A5030377B502803400008AF7A00000F
+:105A70008F86003C3C0390003C0280000086282575
+:105A800000A32025AC4400203C0380008C6700204C
+:105A900004E0FFFE0000000003E00008000000003A
+:105AA0000A000070240400018F85003C3C04800043
+:105AB0003483000100A3102503E00008AC8200201D
+:105AC00003E00008000010213084FFFF30A5FFFF35
+:105AD00010800007000018213082000110400002F1
+:105AE00000042042006518211480FFFB00052840B7
+:105AF00003E000080060102110C000070000000053
+:105B00008CA2000024C6FFFF24A50004AC82000084
+:105B100014C0FFFB2484000403E000080000000020
+:105B200010A0000824A3FFFFAC86000000000000C6
+:105B3000000000002402FFFF2463FFFF1462FFFA4D
+:105B40002484000403E000080000000090AA003153
+:105B50008FAB00108CAC00403C0300FF8D6800044C
+:105B6000AD6C00208CAD004400E060213462FFFF8A
+:105B7000AD6D00248CA700483C09FF000109C0243A
+:105B8000AD6700288CAE004C0182C824031978252B
+:105B9000AD6F0004AD6E002C8CAD0038314A00FFB3
+:105BA000AD6D001C94A900323128FFFFAD680010D4
+:105BB00090A70030A5600002A1600004A16700006A
+:105BC00090A30032306200FF0002198210600005CD
+:105BD000240500011065000E0000000003E000082D
+:105BE000A16A00018CD80028354A0080AD780018E1
+:105BF0008CCF0014AD6F00148CCE0030AD6E000859
+:105C00008CC4002CA16A000103E00008AD64000C04
+:105C10008CCD001CAD6D00188CC90014AD6900144A
+:105C20008CC80024AD6800088CC70020AD67000C4C
+:105C30008CC200148C8300700043C82B1320000713
+:105C4000000000008CC20014144CFFE400000000AF
+:105C5000354A008003E00008A16A00018C820070D0
+:105C60000A0000E6000000009089003027BDFFF820
+:105C70008FA8001CA3A900008FA300003C0DFF808B
+:105C800035A2FFFF8CAC002C00625824AFAB0000A3
+:105C9000A100000400C05821A7A000028D06000446
+:105CA00000A048210167C8218FA500000080502175
+:105CB0003C18FF7F032C20263C0E00FF2C8C00019B
+:105CC000370FFFFF35CDFFFF3C02FF0000AFC824B8
+:105CD00000EDC02400C27824000C1DC003236825F9
+:105CE00001F87025AD0D0000AD0E00048D240024D8
+:105CF000AFAD0000AD0400088D2C00202404FFFF90
+:105D0000AD0C000C9547003230E6FFFFAD060010E9
+:105D10009145004830A200FF000219C25060000106
+:105D20008D240034AD0400148D4700388FAA00186C
+:105D300027BD0008AD0B0028AD0A0024AD07001CEC
+:105D4000AD00002CAD00001803E00008AD000020FD
+:105D500027BDFFE0AFB20018AFB10014AFB0001024
+:105D6000AFBF001C9098003000C088213C0D00FFA0
+:105D7000330F007FA0CF0000908E003135ACFFFFC5
+:105D80003C0AFF00A0CE000194A6001EA220000441
+:105D90008CAB00148E29000400A08021016C282403
+:105DA000012A40240080902101052025A62600021A
+:105DB000AE24000426050020262400080E000092D0
+:105DC00024060002924700302605002826240014ED
+:105DD00000071E000003160324060004044000030D
+:105DE0002403FFFF965900323323FFFF0E00009279
+:105DF000AE230010262400248FBF001C8FB2001891
+:105E00008FB100148FB00010240500030000302172
+:105E10000A00009C27BD002027BDFFD8AFB1001CA1
+:105E2000AFB00018AFBF002090A9003024020001DD
+:105E300000E050213123003F00A040218FB00040FE
+:105E40000080882100C04821106200148FA700380C
+:105E5000240B000500A0202100C02821106B001396
+:105E6000020030210E000128000000009225007C75
+:105E700030A400021080000326030030AE00003082
+:105E8000260300348FBF00208FB1001C8FB0001894
+:105E90000060102103E0000827BD00280E0000A7C5
+:105EA000AFB000100A00016F000000008FA3003C9B
+:105EB000010020210120282101403021AFA3001042
+:105EC0000E0000EEAFB000140A00016F00000000E9
+:105ED0003C06800034C20E008C4400108F850044C4
+:105EE000ACA400208C43001803E00008ACA30024FD
+:105EF0003C06800034C20E008C4400148F850044A0
+:105F0000ACA400208C43001C03E00008ACA30024D8
+:105F10009382000C1040001B2483000F2404FFF028
+:105F20000064382410E00019978B00109784000E4D
+:105F30009389000D3C0A601C0A0001AC01644023F7
+:105F400001037021006428231126000231C2FFFFE3
+:105F500030A2FFFF0047302B50C0000E00E4482164
+:105F60008D4D000C31A3FFFF00036400000C2C03D7
+:105F700004A1FFF30000302130637FFF0A0001A479
+:105F80002406000103E00008000000009784000ED2
+:105F900000E448213123FFFF3168FFFF0068382B00
+:105FA00054E0FFF8A783000E938A000D114000050E
+:105FB000240F0001006BC023A380000D03E0000844
+:105FC000A798000E006BC023A38F000D03E000080C
+:105FD000A798000E03E000080000000027BDFFE8BE
+:105FE000AFB000103C10800036030140308BFFFF43
+:105FF00093AA002BAFBF0014A46B000436040E005C
+:106000009488001630C600FF8FA90030A4680006EF
+:10601000AC650008A0660012A46A001AAC670020F4
+:106020008FA5002CA4690018012020210E000198E2
+:10603000AC6500143C021000AE0201788FBF001462
+:106040008FB0001003E0000827BD00188F85000006
+:106050002484000727BDFFF83084FFF83C06800049
+:1060600094CB008A316AFFFFAFAA00008FA900001D
+:10607000012540232507FFFF30E31FFF0064102B9D
+:106080001440FFF700056882000D288034CC4000E2
+:1060900000AC102103E0000827BD00088F8200003B
+:1060A0002486000730C5FFF800A2182130641FFFC6
+:1060B00003E00008AF8400008F87003C8F84004419
+:1060C00027BDFFB0AFB70044AFB40038AFB1002C6C
+:1060D000AFBF0048AFB60040AFB5003CAFB300342F
+:1060E000AFB20030AFB000283C0B80008C8600249B
+:1060F000AD6700808C8A002035670E00356901008D
+:10610000ACEA00108C8800248D2500040000B82122
+:10611000ACE800188CE3001000A688230000A02142
+:10612000ACE300148CE20018ACE2001C122000FE6C
+:1061300000E0B021936C0008118000F40000000022
+:10614000976F001031EEFFFF022E682B15A000EFB5
+:1061500000000000977200103250FFFFAED0000028
+:106160003C0380008C740000329300081260FFFD35
+:106170000000000096D800088EC700043305FFFF1A
+:1061800030B5000112A000E4000000000000000D86
+:1061900030BFA0402419004013F9011B30B4A00007
+:1061A000128000DF000000009373000812600008F6
+:1061B00000000000976D001031ACFFFF00EC202BB9
+:1061C0001080000330AE004011C000D50000000078
+:1061D000A7850040AF87003893630008022028217C
+:1061E000AFB10020146000F527B40020AF60000CB0
+:1061F000978F004031F14000162000022403001662
+:106200002403000E24054007A363000AAF650014B1
+:10621000938A00428F70001431550001001512401E
+:1062200002024825AF690014979F00408F78001440
+:1062300033F9001003194025AF680014979200400D
+:106240003247000810E0016E000000008F67001464
+:106250003C1210003C11800000F27825AF6F001452
+:1062600036230E00946E000A3C0D81002406000EB9
+:1062700031CCFFFF018D2025AF640004A36600022E
+:106280009373000A3406FFFC266B0004A36B000A1C
+:1062900097980040330820001100015F00000000C3
+:1062A0003C05800034A90E00979900409538000CF9
+:1062B00097870040001940423312C00031030003A9
+:1062C00000127B0330F11000006F6825001172038B
+:1062D00001AE6025000C20C0A76400129793004017
+:1062E000936A000A001359823175003C02AA1021FA
+:1062F0002450003CA3700009953F000C33F93FFF88
+:10630000A779001097700012936900090130F821F5
+:1063100027E5000230B900070019C0233308000741
+:10632000A368000B9371000997720012976F001019
+:10633000322700FF8F910038978D004000F218211E
+:10634000006F702101C6602131A6004010C0000519
+:106350003185FFFF00B1102B3C1280001040001768
+:10636000000098210225A82B56A0013E8FA50020F1
+:106370003C048000348A0E008D5300143C068000DB
+:10638000AD5300108D4B001CAD4B0018AD45000007
+:106390008CCD000031AC00081180FFFD34CE0E0022
+:1063A00095C3000800A0882100009021A783004029
+:1063B0008DC6000424130001AF860038976F0010CB
+:1063C00031F5FFFF8E9F000003F1282310A0011F6D
+:1063D000AE85000093620008144000DD000000005C
+:1063E0000E0001E7240400108F900048004028218F
+:1063F0003C023200320600FF000654000142F8253C
+:1064000026090001AF890048ACBF0000937900095C
+:1064100097780012936F000A332800FF3303FFFFC1
+:106420000103382100076C0031EE00FF01AE60254A
+:10643000ACAC00048F840048978B0040316A200088
+:106440001140010AACA4000897640012308BFFFFD2
+:1064500006400108ACAB000C978E004031C5000827
+:1064600014A0000226280006262800023C1F8000F7
+:1064700037E70E0094F900148CE5001C8F670004C8
+:10648000937800023324FFFF330300FFAFA3001013
+:106490008F6F0014AFA800180E0001CBAFAF00142F
+:1064A000240400100E0001FB000000008E9200008A
+:1064B00016400005000000008F7800142403FFBF81
+:1064C0000303A024AF7400148F67000C00F5C821EB
+:1064D000AF79000C9375000816A0000800000000BA
+:1064E00012600006000000008F6800143C0AEFFFF5
+:1064F0003549FFFE0109F824AF7F0014A37300089B
+:106500008FA500200A00034F02202021AED10000F9
+:106510000A00022D3C03800014E0FF1E30BFA040A3
+:106520000E0001900000A0212E9100010237B0253D
+:1065300012C000188FBF00488F87003C24170F003F
+:1065400010F700D43C0680008CD901780720FFFEAC
+:10655000241F0F0010FF00F634CA0E008D560014E1
+:1065600034C7014024080240ACF600048D49001CE9
+:106570003C141000ACE90008A0E00012A4E0001AEE
+:10658000ACE00020A4E00018ACE80014ACD4017822
+:106590008FBF00488FB700448FB600408FB5003CD6
+:1065A0008FB400388FB300348FB200308FB1002C1D
+:1065B0008FB0002803E0000827BD00508F910038FD
+:1065C000978800403C1280000220A821310700403B
+:1065D00014E0FF7C00009821977900108F9200381A
+:1065E0003338FFFF131200A8000020210080A021F3
+:1065F000108000F300A088211620FECE00000000CD
+:106600000A00031F2E9100013C0380008C62017878
+:106610000440FFFE240808008F860000AC68017863
+:106620003C038000946D008A31ACFFFF0186582343
+:10663000256AFFFF31441FFF2C8900081520FFF950
+:10664000000000008F8F0048347040008F83003CB2
+:1066500000E0A021240E0F0025E70001AF870048CD
+:1066600000D03021023488233C08800031F500FF3F
+:10667000106E0005240700019398004233130001B7
+:106680000013924036470001001524003C0A010027
+:10669000008A4825ACC900008F82004830BF003610
+:1066A00030B90008ACC200041320009900FF9825FF
+:1066B00035120E009650000A8F8700003C0F8100B3
+:1066C0003203FFFF24ED000835060140006F60250E
+:1066D0003C0E100031AB1FFF269200062405000E71
+:1066E000ACCC0020026E9825A4C5001AAF8B000028
+:1066F000A4D20018162000083C1080008F89003CAE
+:1067000024020F00512200022417000136730040BA
+:106710000E0001883C10800036060E008CCB001461
+:10672000360A014002402021AD4B00048CC5001CFC
+:10673000AD450008A1550012AD5300140E0001989C
+:106740003C151000AE1501780A000352000000004D
+:10675000936F0009976E0012936D000B31E500FFF7
+:1067600000AE202131AC00FF008C80212602000AFF
+:106770003050FFFF0E0001E7020020218F86004805
+:106780003C0341003C05800024CB0001AF8B004856
+:10679000936A00099769001230C600FF315F00FF5D
+:1067A0003128FFFF03E8382124F900020006C40065
+:1067B0000319782501E37025AC4E00008F6D000CA5
+:1067C00034A40E00948B001401B26025AC4C00047C
+:1067D0008C85001C8F670004936A00023164FFFF00
+:1067E000314900FFAFA900108F680014AFB1001845
+:1067F0000E0001CBAFA800140A0002FD0200202108
+:10680000AF600004A36000029798004033082000A6
+:106810001500FEA300003021A760001297840040FD
+:10682000936B000A3C10800030931F0000135183CB
+:10683000014BA82126A20028A362000936090E00F8
+:10684000953F000C0A000295A77F00108F7000147E
+:10685000360900400E000188AF6900140A0002C921
+:10686000000000000A00034F000020210641FEFA4C
+:10687000ACA0000C8CAC000C3C0D8000018D902570
+:106880000A0002EAACB2000C000090210A0002C526
+:1068900024130001128000073C028000344B0E00DC
+:1068A0009566000830D300401260004900000000E7
+:1068B0003C0680008CD001780600FFFE34C50E0037
+:1068C00094B500103C03050034CC014032B8FFFF02
+:1068D00003039025AD92000C8CAF0014240D200012
+:1068E0003C041000AD8F00048CAE001CAD8E00087F
+:1068F000A1800012A580001AAD800020A58000189C
+:10690000AD8D0014ACC401780A0003263C0680005B
+:106910008F9F0000351801402692000227F90008D9
+:1069200033281FFFA71200180A000391AF88000048
+:106930003C02800034450140ACA0000C1280001BDA
+:1069400034530E0034510E008E370010ACB70004E3
+:106950008E2400183C0B8000ACA400083570014068
+:1069600024040040A20000128FBF0048A600001AB5
+:106970008FB70044AE0000208FB60040A60000187C
+:106980008FB5003CAE0400148FB400388FB30034D0
+:106990008FB200308FB1002C8FB000283C02100065
+:1069A00027BD005003E00008AD6201788E66001438
+:1069B000ACA600048E64001C0A00042A3C0B800074
+:1069C0000E0001902E9100010A0003200237B0252D
+:1069D000000000000000000D00000000240003691A
+:1069E0000A0004013C06800027BDFFD8AFBF00208D
+:1069F0003C0980003C1F20FFAFB200183C0760003C
+:106A000035320E002402001037F9FFFDACE23008E9
+:106A1000AFB3001CAFB10014AFB00010AE5900000E
+:106A20000000000000000000000000000000000066
+:106A3000000000003C1800FF3713FFFDAE530000BC
+:106A40003C0B60048D7050002411FF7F3C0E00024F
+:106A50000211782435EC380C35CD0109ACED4C1819
+:106A6000240A0009AD6C50008CE80438AD2A0008F7
+:106A7000AD2000148CE54C1C3106FFFF38C42F718B
+:106A800000051E023062000F2486C0B310400007CC
+:106A9000AF8200088CE54C1C3C09001F3528FC0027
+:106AA00000A81824000321C2AF8400048CF1080858
+:106AB0003C0F57092412F0000232702435F0001008
+:106AC00001D0602601CF68262DAA00012D8B000180
+:106AD000014B382550E00009A380000C3C1F601CCE
+:106AE0008FF8000824190001A399000C33137C00CF
+:106AF000A7930010A780000EA380000DAF80004870
+:106B000014C00003AF8000003C066000ACC0442C01
+:106B10000E0005B93C1080000E000F1A361101005E
+:106B20003C12080026523DD03C13080026733E500C
+:106B30008E03000038640001308200011440FFFC25
+:106B40003C0B800A8E2600002407FF8024C90240E7
+:106B5000312A007F014B402101272824AE06002066
+:106B6000AF880044AE0500243C048000AF86003CA2
+:106B70008C8C01780580FFFE24180800922F0008F5
+:106B8000AC980178A38F0042938E004231CD000172
+:106B900011A0000F24050D0024DFF8002FF90301D8
+:106BA0001320001C000629C224A4FFF00004104298
+:106BB000000231400E00020200D2D8213C02400007
+:106BC0003C068000ACC201380A0004A000000000AE
+:106BD00010C50023240D0F0010CD00273C1F800896
+:106BE00037F9008093380000240E0050330F00FF67
+:106BF00015EEFFF33C0240000E000A3600000000D4
+:106C00003C0240003C068000ACC201380A0004A0EF
+:106C1000000000008F83000400A3402B1500000B30
+:106C20008F8B0008006B50212547FFFF00E5482BA4
+:106C30001520000600A36023000C19400E0002027C
+:106C40000073D8210A0004C43C0240000000000D7B
+:106C50000E000202000000000A0004C43C024000D2
+:106C60003C1B0800277B3F500E0002020000000082
+:106C70000A0004C43C0240003C1B0800277B3F7014
+:106C80000E000202000000000A0004C43C024000A2
+:106C90003C0660043C09080025290104ACC9502CBD
+:106CA0008CC850003C0580003C0200023507008083
+:106CB000ACC750003C040800248415A43C03080021
+:106CC0002463155CACA50008ACA2000C3C010800D4
+:106CD000AC243D603C010800AC233D6403E00008A7
+:106CE0002402000100A030213C1C0800279C3D68C4
+:106CF0003C0C04003C0B0002008B3826008C402624
+:106D00002CE200010007502B2D050001000A4880ED
+:106D10003C03080024633D60004520250123182121
+:106D20001080000300001021AC6600002402000166
+:106D300003E00008000000003C1C0800279C3D68A0
+:106D40003C0B04003C0A0002008A3026008B3826E7
+:106D50002CC200010006482B2CE5000100094080F0
+:106D60003C03080024633D600045202501031821F1
+:106D700010800005000010213C0C0800258C155CDB
+:106D8000AC6C00002402000103E0000800000000D9
+:106D90003C0900023C08040000883026008938269F
+:106DA0002CC30001008028212CE400010083102561
+:106DB0001040000B000030213C1C0800279C3D685F
+:106DC0003C0A80008D4E00082406000101CA682597
+:106DD000AD4D00088D4C000C01855825AD4B000CC5
+:106DE00003E0000800C010213C1C0800279C3D68FF
+:106DF0003C0580008CA6000C000420272402000122
+:106E000000C4182403E00008ACA3000C3C020002FC
+:106E10001082000B3C0560003C0704001087000353
+:106E20000000000003E00008000000008CA908D06A
+:106E3000240AFFFD012A402403E00008ACA808D082
+:106E40008CA408D02406FFFE0086182403E0000866
+:106E5000ACA308D03C05601A34A600108CC3008097
+:106E600027BDFFF88CC50084AFA3000093A40000E9
+:106E70002402000110820003AFA5000403E0000813
+:106E800027BD000893A7000114E0001497AC00028E
+:106E900097B800023C0F8000330EFFFC01CF682141
+:106EA000ADA50000A3A000003C0660008CC708D080
+:106EB0002408FFFE3C04601A00E82824ACC508D072
+:106EC0008FA300048FA200003499001027BD000892
+:106ED000AF22008003E00008AF2300843C0B800059
+:106EE000318AFFFC014B48218D2800000A00057DF6
+:106EF000AFA8000427BDFFE8AFBF00103C1C08008E
+:106F0000279C3D683C0580008CA4000C8CA20004EA
+:106F10003C0300020044282410A0000A00A3182407
+:106F20003C0604003C0400021460000900A6102482
+:106F30001440000F3C0404000000000D3C1C08003D
+:106F4000279C3D688FBF001003E0000827BD001894
+:106F50003C0208008C423D600040F809000000003F
+:106F60003C1C0800279C3D680A0005A68FBF001046
+:106F70003C0208008C423D640040F809000000001B
+:106F80000A0005AC00000000000411C003E0000886
+:106F9000244202403C04080024843FB42405001A23
+:106FA0000A00009C0000302127BDFFE0AFB00010B8
+:106FB0003C108000AFBF0018AFB1001436110100C3
+:106FC000922200090E0005B63044007F8E3F00007B
+:106FD0008F89003C3C0F008003E26021258800403F
+:106FE0000049F821240DFF80310E00783198007897
+:106FF00035F9000135F100020319382501D1482582
+:10700000010D302403ED5824018D2824240A00406A
+:1070100024040080240300C0AE0B0024AE0008103E
+:10702000AE0A0814AE040818AE03081CAE05080426
+:10703000AE070820AE060808AE0908243609090084
+:107040009539000C3605098033ED007F3338FFFF9A
+:10705000001889C0AE110800AE0F0828952C000C4E
+:107060008FBF00188FB10014318BFFFF000B51C090
+:10707000AE0A002C8CA400508FB000108CA3003CF2
+:107080008D2700048CA8001C8CA600383C0E800ABA
+:1070900001AE102127BD0020AF820044AF84005014
+:1070A000AF830054AF87004CAF88005C03E000085A
+:1070B000AF8600603C09080091293FD924A800024E
+:1070C0003C05110000093C0000E8302500C51825EA
+:1070D00024820008AC83000003E00008AC800004B8
+:1070E0003C098000352309009128010B906A0011AA
+:1070F0002402002800804821314700FF00A07021B1
+:1071000000C068213108004010E20002340C86DD26
+:10711000240C08003C0A800035420A9A944700007B
+:10712000354B0A9C35460AA030F9FFFFAD39000007
+:107130008D780000354B0A8024040001AD3800042E
+:107140008CCF0000AD2F00089165001930A300031B
+:107150001064009028640002148000AF240500022F
+:107160001065009E240F0003106F00B435450AA47B
+:10717000240A0800118A0048000000005100003D68
+:107180003C0B80003C0480003483090090670012AF
+:1071900030E200FF004D7821000FC8802724000155
+:1071A0003C0A8000354F090091E50019354C0980F3
+:1071B0008D87002830A300FF0003150000475825E5
+:1071C0000004C4003C19600001793025370806FF2F
+:1071D000AD260000AD2800048DEA002C25280028EB
+:1071E000AD2A00088DEC0030AD2C000C8DE500348C
+:1071F000AD2500108DE400383C05800034AC093C1E
+:10720000AD2400148DE3001CAD2300188DE7002091
+:10721000AD27001C8DE20024AD2200208DF900284E
+:1072200034A20100AD3900248D830000AD0E0004AE
+:1072300034B90900AD0300008C47000C250200148E
+:10724000AD070008932B00123C04080090843FD83F
+:10725000AD000010317800FF030D302100064F0013
+:1072600000047C00012F702535CDFFFC03E00008F1
+:10727000AD0D000C35780900930600123C0508009E
+:1072800094A53FC830C800FF010D5021000A60805E
+:107290000A00063C018520211500005B000000006B
+:1072A0003C08080095083FCE3C06080094C63FC83D
+:1072B000010610213C0B800035790900933800113C
+:1072C000932A001935660A80330800FF94CF002AFC
+:1072D00000086082314500FF978A0058000C1E00AC
+:1072E000000524003047FFFF006410250047C0253B
+:1072F00001EA30213C0B4000030B402500066400EE
+:10730000AD280000AD2C0004932500183C030006B6
+:107310002528001400053E0000E31025AD220008DA
+:107320008F24002C3C05800034AC093CAD24000CBB
+:107330008F38001C34A20100254F0001AD38001029
+:107340008D830000AD0E000431EB7FFFAD03000024
+:107350008C47000C34B90900A78B0058AD07000812
+:10736000932B00123C04080090843FD8250200149F
+:10737000317800FF030D302100064F0000047C002F
+:10738000012F702535CDFFFCAD00001003E0000893
+:10739000AD0D000C3C02080094423FD23C050800B1
+:1073A00094A53FC835440AA43C07080094E73FC4AD
+:1073B000948B00000045C8210327C023000B1C004C
+:1073C0002706FFF200665025AD2A000CAD20001004
+:1073D000AD2C00140A00063025290018354F0AA4E8
+:1073E00095E50000956400280005140000043C00A9
+:1073F0003459810000EC5825AD39000CAD2B00103C
+:107400000A000630252900143C0C0800958C3FCE5C
+:107410000A000681258200015460FF56240A0800F4
+:1074200035580AA49706000000061C00006C502581
+:10743000AD2A000C0A000630252900103C03080084
+:1074400094633FD23C07080094E73FC83C0F080014
+:1074500095EF3FC494A4000095790028006710219F
+:10746000004F582300041C00001934002578FFEE5B
+:1074700000D87825346A8100AD2A000CAD2F0010A9
+:10748000AD200014AD2C00180A0006302529001C80
+:1074900003E00008240207D027BDFFE0AFB20018C8
+:1074A000AFB10014AFB00010AFBF001C0E00007CE5
+:1074B000008088218F8800548F87004C3C0580080D
+:1074C00034B20080011128213C1080002402008089
+:1074D000240300C000A72023AE0208183C06800841
+:1074E000AE03081C18800004AF850054ACC500042E
+:1074F0008CC90004AF89004C1220000936040980B1
+:107500000E0006F800000000924C00278E0B00745D
+:1075100001825004014B3021AE46000C3604098034
+:107520008C8E001C8F8F005C01CF682319A0000493
+:107530008FBF001C8C90001CAF90005C8FBF001CA4
+:107540008FB200188FB100148FB000100A00007EB7
+:1075500027BD00208F8600508F8300548F82004CFF
+:107560003C05800834A40080AC860050AC83003C0D
+:1075700003E00008ACA200043C0308008C63005444
+:1075800027BDFFF8308400FF2462000130A500FF12
+:107590003C010800AC22005430C600FF3C078000CC
+:1075A0008CE801780500FFFE3C0C7FFFA3A40003DC
+:1075B0008FAA0000358BFFFF014B4824000627C02F
+:1075C00001244025AFA8000034E201009043000AE6
+:1075D000A3A000023C1980FFA3A300018FAF00000D
+:1075E00030AE007F3738FFFF01F86024000E6E00D8
+:1075F0003C0A002034E50140018D58253549200022
+:107600002406FF803C04100027BD0008ACAB000C32
+:10761000ACA90014A4A00018A0A6001203E0000862
+:10762000ACE40178308800FF30A700FF3C03800005
+:107630008C6201780440FFFE3C0C8000358A0A0011
+:107640008D4B00203584014035850980AC8B0004CA
+:107650008D4900240007302B00061540AC89000836
+:10766000A088001090A3004CA083002D03E0000828
+:10767000A480001827BDFFE8308400FFAFBF0010D2
+:107680000E00075D30A500FF8F8300548FBF0010F0
+:107690003C06800034C50140344700402404FF907C
+:1076A0003C02100027BD0018ACA3000CA0A40012DF
+:1076B000ACA7001403E00008ACC2017827BDFFE0CE
+:1076C0003C088008AFBF001CAFB20018AFB1001477
+:1076D000AFB00010351000808E0600183C07800007
+:1076E000309200FF00C72025AE0400180E00007C79
+:1076F00030B100FF92030005346200080E00007EE6
+:10770000A2020005024020210E000771022028215C
+:10771000024020218FBF001C8FB200188FB10014CF
+:107720008FB0001024050005240600010A0007326E
+:1077300027BD00203C05800034A309809066000826
+:1077400030C200081040000F3C0A01013549080A08
+:10775000AC8900008CA80074AC8800043C070800C9
+:1077600090E73FD830E5001050A00008AC8000083A
+:107770003C0D800835AC00808D8B0058AC8B000828
+:107780002484000C03E00008008010210A0007B5E3
+:107790002484000C27BDFFE83C098000AFB0001036
+:1077A000AFBF00143526098090C8000924020006E6
+:1077B00000A05821310300FF3527090000808021F7
+:1077C000240500041062007B2408000294CF005CB2
+:1077D0003C0E020431EDFFFF01AE6025AE0C00004F
+:1077E00090CA00083144002010800008000000000A
+:1077F00090C2004E3C1F010337F90300305800FFD0
+:107800000319302524050008AE06000490F9001184
+:1078100090E6001290E40011333800FF00187082E7
+:1078200030CF00FF01CF5021014B6821308900FF8C
+:1078300031AAFFFF39230028000A60801460002C61
+:10784000020C482390E400123C198000372F0100FD
+:10785000308C00FF018B1821000310800045F821B7
+:10786000001F8400360706FFAD270004373F0900DC
+:1078700093EC001193EE0012372609800005C082B8
+:107880008DE4000C8CC5003431CD00FF01AB10211C
+:107890000058182100A4F8230008840000033F00CA
+:1078A00000F0302533F9FFFF318F00FC00D970253F
+:1078B0000158202101E9682100045080ADAE000C80
+:1078C0000E00007C012A80213C088008240B000463
+:1078D000350500800E00007EA0AB000902001021DB
+:1078E0008FBF00148FB0001003E0000827BD001800
+:1078F00090EC001190E300193C18080097183FCE57
+:10790000318200FF0002F882307000FF001FCE00BD
+:1079100000103C000327302500D870253C0F4000A4
+:1079200001CF68253C198000AD2D0000373F0900CC
+:1079300093EC001193EE0012372F010037260980D7
+:107940000005C0828DE4000C8CC5003431CD00FFF1
+:1079500001AB10210058182100A4F823000884006E
+:1079600000033F0000F0302533F9FFFF318F00FCAA
+:1079700000D970250158202101E9682100045080B8
+:10798000ADAE000C0E00007C012A80213C0880086E
+:10799000240B0004350500800E00007EA0AB00091A
+:1079A000020010218FBF00148FB0001003E0000808
+:1079B00027BD00180A0007C72408001227BDFFD002
+:1079C0003C038000AFB60028AFB50024AFB4002060
+:1079D000AFB10014AFBF002CAFB3001CAFB20018A2
+:1079E000AFB000103467010090E6000B309400FF48
+:1079F00030B500FF30C200300000B02110400099C7
+:107A000000008821346409809088000800082E0056
+:107A100000051E03046000C0240400048F86005487
+:107A20003C010800A0243FD83C0C8000AD800048F9
+:107A30003C048000348E010091CD000B31A5002064
+:107A400010A000073C078000349309809272000860
+:107A50000012860000107E0305E000C43C1F800871
+:107A600034EC0100918A000B34EB09809169000825
+:107A7000314400400004402B3123000800C8982303
+:107A80001460000224120003000090213C108000CA
+:107A900036180A8036040900970E002C90830011D6
+:107AA0009089001293050018307F00FF312800FFF5
+:107AB000024810210002C880930D0018033F78216E
+:107AC00001F1302130B100FF00D11821A78E0058FC
+:107AD0003C010800A4263FCE3C010800A4233FD06F
+:107AE00015A00002000000000000000D920B010B29
+:107AF0003065FFFF3C010800A4233FD2316A0040FB
+:107B00003C010800A4203FC83C010800A4203FC459
+:107B10001140000224A4000A24A4000B3091FFFFAE
+:107B20000E0001E7022020219206010B3C0C080008
+:107B3000958C3FD2004020210006698231A70001C8
+:107B40000E00060101872821004020210260282123
+:107B50000E00060C024030210E0007A1004020213B
+:107B600016C00069004020219212010B32560040DD
+:107B700012C000053C0500FF8C93000034AEFFFFEF
+:107B8000026E8024AC9000000E0001FB0220202138
+:107B90003C0F080091EF3FD831F10003122000168E
+:107BA0003C1380088F8200543C09800835280080EF
+:107BB000245F0001AD1F003C3C0580088CB9000427
+:107BC00003E02021033FC0231B000002AF9F0054AD
+:107BD0008CA400040E0006F8ACA400043C0780004E
+:107BE0008CEB00743C04800834830080004B5021EF
+:107BF000AC6A000C3C1380083670008002802021A3
+:107C000002A02821A200006B0E00075D3C1480003A
+:107C10008F920054368C0140AD92000C8F86004844
+:107C20003C151000344D000624D60001AF960048E4
+:107C30008FBF002CA18600128FB60028AD8D0014D6
+:107C40008FB3001CAE9501788FB200188FB5002459
+:107C50008FB400208FB100148FB0001003E0000833
+:107C600027BD003034640980908F0008000F760033
+:107C7000000E6E0305A00033347F090093F8001B4B
+:107C8000241900103C010800A0393FD8331300022A
+:107C90001260FF678F8600548F8200601446FF6574
+:107CA0003C0480000E00007C000000003C048008C2
+:107CB0003485008090A8000924060016310300FFD7
+:107CC0001066000D0000000090AB00093C070800A2
+:107CD00090E73FD824090008316400FF34EA00012E
+:107CE0003C010800A02A3FD81089002F240C000A6C
+:107CF000108C00282402000C0E00007E0000000002
+:107D00000A0008608F8600540E0007B9024028213F
+:107D10000A0008AE004020213C0B8008356A008034
+:107D20008D4600548CE9000C1120FF3DAF860054B5
+:107D3000240700143C010800A0273FD80A00085F70
+:107D40003C0C800090910008241200023C010800C5
+:107D5000A0323FD8323000201200000B2416000160
+:107D60008F8600540A0008602411000837F800804C
+:107D70008F020038AFE200048FF90004AF19003C15
+:107D80000A00086C3C0780008F8600540A000860D7
+:107D900024110004A0A200090E00007E00000000D3
+:107DA0000A0008608F860054240200140A00093A71
+:107DB000A0A2000927BDFFE8AFB000103C10800072
+:107DC000AFBF001436020100904400090E00075DA9
+:107DD000240500013C0480089099000E3483008043
+:107DE000909F000F906F00269089000A33F800FFE3
+:107DF00000196E000018740031EC00FF01AE502530
+:107E0000000C5A00014B3825312800FF3603014091
+:107E10003445600000E830252402FF813C04100056
+:107E2000AC66000C8FBF0014AC650014A062001299
+:107E3000AE0401788FB0001003E0000827BD0018E1
+:107E400027BDFFE8308400FFAFBF00100E00075DC4
+:107E500030A500FF3C05800034A4014034470040B9
+:107E60002406FF92AC870014A08600128F83005472
+:107E70008FBF00103C02100027BD0018AC83000C1F
+:107E800003E00008ACA2017827BDFFD8AFB0001016
+:107E9000308400FF30B000FF3C058000AFB100141B
+:107EA000AFBF0020AFB3001CAFB20018000410C277
+:107EB00034A60100320300023051000114600007B3
+:107EC00090D200093C098008353300809268000593
+:107ED0003107000810E0000C308A00100240202119
+:107EE0000E00078302202821240200018FBF0020FA
+:107EF0008FB3001C8FB200188FB100148FB0001028
+:107F000003E0000827BD00281540003434A50A000E
+:107F10008CB800248CAF0008130F004B00003821F0
+:107F20003C0D800835B30080926C00682406000286
+:107F3000318B00FF116600843C06800034C20100D2
+:107F40009263004C90590009307F00FF53F9000400
+:107F50003213007C10E00069000000003213007C46
+:107F60005660005C0240202116200009320D0001FD
+:107F70003C0C800035840100358B0A008D6500249F
+:107F80008C86000414A6FFD900001021320D0001D8
+:107F900011A0000E024020213C1880003710010083
+:107FA0008E0F000C8F8E005011EE000800000000B4
+:107FB0000E000843022028218E19000C3C1F800867
+:107FC00037F00080AE190050024020210E000771EA
+:107FD000022028210A00098F240200013C05080024
+:107FE0008CA5006424A400013C010800AC240064BA
+:107FF0001600000D00000000022028210E0007716D
+:1080000002402021926E0068240C000231CD00FF56
+:1080100011AC0022024020210E00094100000000A6
+:108020000A00098F240200010E00007024040001E0
+:10803000926B0025020B30250E00007EA266002503
+:108040000A0009D3022028218E6200188CDF000468
+:108050008CB9002400021E0217F9FFB13065007FC1
+:108060009268004C264400013093007F1265004066
+:10807000310300FF1464FFAB3C0D8008264700016C
+:1080800030F1007F30E200FF1225000B24070001D1
+:10809000004090210A00099C2411000124050004DD
+:1080A0000E000732240600010E0009410000000006
+:1080B0000A00098F240200012405FF8002452024C4
+:1080C00000859026324200FF004090210A00099C62
+:1080D000241100010E00084302202821320700303D
+:1080E00010E0FFA132100082024020210E00078321
+:1080F000022028210A00098F240200018E6900183D
+:108100000240202102202821012640250E0009647A
+:10811000AE6800189264004C240500032406000198
+:108120000E000732308400FF0E00007024040001AE
+:1081300092710025021150250E00007EA26A0025D2
+:108140000A00098F240200018E6F00183C1880007D
+:108150000240202101F87025022028210E0007711D
+:10816000AE6E00189264004C0A000A1B240500043D
+:10817000324A0080394900801469FF6A3C0D80084A
+:108180000A0009F42647000127BDFFC0AFB0001860
+:108190003C108000AFBF0038AFB70034AFB600303E
+:1081A000AFB5002CAFB40028AFB30024AFB20020AD
+:1081B0000E0005BEAFB1001C360201009045000B59
+:1081C0000E00097690440008144000E78FBF003885
+:1081D0003C08800835070080A0E0006B3606098067
+:1081E00090C50000240300503C17080026F73F907C
+:1081F00030A400FF3C13080026733FA01083000347
+:108200003C1080000000B82100009821241F0010BD
+:108210003611010036120A00361509808E580024E6
+:108220008E3400048EAF00208F8C00543C01080077
+:10823000A03F3FD836190A80972B002C8EF60000FD
+:10824000932A00180298702301EC68233C0108006F
+:10825000AC2E3FB43C010800AC2D3FB83C010800F7
+:10826000AC2C3FDCA78B005802C0F809315400FF4A
+:1082700030490002152000E930420001504000C49E
+:108280009227000992A90008312800081500000271
+:10829000241500030000A8213C0A80003543090092
+:1082A00035440A008C8D00249072001190700012E9
+:1082B000907F0011325900FF321100FF02B11021EE
+:1082C0000002C08033EF00FF0319B021028F70213C
+:1082D00002D4602125CB00103C010800A4363FCE1B
+:1082E0003C010800AC2D3FE03C010800A42C3FD02D
+:1082F0003C010800A42B3FCC3556010035540980C1
+:1083000035510E008F8700548F89005C8E850020C8
+:1083100024080006012730233C010800AC283FD484
+:1083200000A7282304C000B50000902104A000B3DA
+:1083300000C5502B114000B5000000003C010800B2
+:10834000AC263FB88E6200000040F8090000000033
+:108350003046000214C0007400408021304B000100
+:10836000556000118E6200043C0D08008DAD3FBCCD
+:108370003C0EC0003C04800001AE6025AE2C000025
+:108380008C980000330F000811E0FFFD0000000092
+:10839000963F000824120001A79F00408E39000478
+:1083A000AF9900388E6200040040F8090000000018
+:1083B0000202802532030002146000B300000000B6
+:1083C0003C09080095293FC43C06080094C63FD0EC
+:1083D0003C0A0800954A3FC63C0708008CE73FBCB2
+:1083E000012670213C0308008C633FE03C08080034
+:1083F00095083FDA01CA20218ED9000C00E9282116
+:10840000249F000200A878210067C02133E4FFFF09
+:10841000AF9900503C010800AC383FE03C01080037
+:10842000A42F3FC83C010800A42E3FD20E0001E754
+:10843000000000008F8D0048004020213C01080012
+:10844000A02D3FD98E62000825AC0001AF8C0048FA
+:108450000040F809000000008F85005402A0302180
+:108460000E00060C004020210E0007A10040202134
+:108470008E6B000C0160F809004020213C0A0800C6
+:10848000954A3FD23C06080094C63FC601464821A3
+:10849000252800020E0001FB3104FFFF3C05080007
+:1084A0008CA53FB43C0708008CE73FBC00A7202305
+:1084B0003C010800AC243FB414800006000000001A
+:1084C0003C0208008C423FD4344B00403C01080081
+:1084D000AC2B3FD4124000438F8E00448E2D0010F1
+:1084E0008F920044AE4D00208E2C0018AE4C00241C
+:1084F0003C04080094843FC80E0006FA0000000007
+:108500008F9F00548E6700103C010800AC3F3FDC99
+:1085100000E0F809000000003C1908008F393FB462
+:108520001720FF798F870054979300583C11800ED5
+:10853000321601000E000729A633002C16C0004594
+:10854000320300105460004C8EE5000432080040F5
+:108550005500001D8EF000088EE4000C0080F80924
+:10856000000000008FBF00388FB700348FB6003096
+:108570008FB5002C8FB400288FB300248FB2002059
+:108580008FB1001C8FB0001803E0000827BD004029
+:108590008F86003C36110E0000072E0000A6202515
+:1085A000AE0400808E4300208E500024AFA3001044
+:1085B000AE2300148FB20010AE320010AE30001C9B
+:1085C0000A000A75AE3000180200F8090000000029
+:1085D0008EE4000C0080F809000000000A000B2E59
+:1085E0008FBF003824180001240F0001A5C000200F
+:1085F000A5D800220A000B10ADCF00243C010800D2
+:10860000AC203FB80A000AA68E6200003C010800B8
+:10861000AC253FB80A000AA68E6200009224000929
+:108620000E000771000028218FBF00388FB700347B
+:108630008FB600308FB5002C8FB400288FB3002484
+:108640008FB200208FB1001C8FB0001803E000082B
+:1086500027BD00403C1480009295010900002821AC
+:108660000E00084332A400FF320300105060FFB830
+:10867000320800408EE5000400A0F8090000000068
+:108680000A000B28320800405240FFA89793005878
+:108690008E3400148F930044AE7400208E35001C7D
+:1086A000AE7500240A000B1F979300588F820014A8
+:1086B0000004218003E00008008210213C078008AC
+:1086C00034E200809043006900804021106000097E
+:1086D0003C0401003C0708008CE73FDC8F8300303E
+:1086E00000E32023048000089389001C14E30003A6
+:1086F0000100202103E00008008010213C0401005B
+:1087000003E00008008010211120000B00673823CF
+:108710003C0D800035AC0980918B007C316A0002F1
+:10872000114000202409003400E9702B15C0FFF12E
+:108730000100202100E938232403FFFC00A3C82402
+:1087400000E3C02400F9782B15E0FFEA030820219C
+:1087500030C400030004102314C000143049000387
+:108760000000302100A9782101E6702100EE682B7D
+:1087700011A0FFE03C0401002D3800010006C82BC9
+:10878000010548210319382414E0FFDA2524FFFCF1
+:108790002402FFFC00A218240068202103E0000846
+:1087A000008010210A000B9E240900303C0C800040
+:1087B0003586098090CB007C316A00041540FFE9C2
+:1087C000240600040A000BAD000030213C03080021
+:1087D0008C63005C8F82001827BDFFE0AFBF0018DC
+:1087E000AFB1001410620005AFB00010000329C043
+:1087F00024A40280AF840014AF8300183C108000D2
+:1088000036020A0094450032361101000E000B7F3B
+:1088100030A43FFF8E240000241FFF803C11008005
+:108820000082C021031F60243309007F000CC9406F
+:1088300003294025330E0078362F00033C0D10002D
+:10884000010D502501CF5825AE0C002836080980AF
+:10885000AE0C080CAE0B082CAE0A08309103006970
+:108860003C06800C0126382110600006AF870034DA
+:108870008D09003C8D03006C0123382318E0008231
+:10888000000000003C0B8008356A00803C1080002E
+:10889000A1400069360609808CC200383C06800081
+:1088A00034C50A0090A8003C310C00201180001A49
+:1088B000AF820030240D00013C0E800035D10A004B
+:1088C000A38D001CAF8000248E2400248F850024FB
+:1088D000240D0008AF800020AF8000283C01080074
+:1088E000A42D3FC63C010800A4203FDA0E000B83F4
+:1088F000000030219228003C8FBF00188FB1001477
+:108900008FB0001000086142AF82002C27BD00200C
+:1089100003E000083182000190B80032240E00010B
+:10892000330F00FF000F2182108E00412419000236
+:108930001099006434C40AC03C03800034640A0007
+:108940008C8F002415E0001E34660900909F0030D3
+:108950002418000533F9003F1338004E24030001AA
+:108960008F860020A383001CAF860028AF860024DA
+:108970003C0E800035D10A008E2400248F8500240F
+:10898000240D00083C010800A42D3FC63C0108004E
+:10899000A4203FDA0E000B83000000009228003C68
+:1089A0008FBF00188FB100148FB000100008614213
+:1089B000AF82002C27BD002003E0000831820001B7
+:1089C0008C8A00088C8B00248CD000643C0E8000C4
+:1089D00035D10A00014B2823AF900024A380001C4E
+:1089E000AF8500288E2400248F8600208F850024E8
+:1089F000240D00083C010800A42D3FC63C010800DE
+:108A0000A4203FDA0E000B83000000009228003CF7
+:108A10008FBF00188FB100148FB0001000086142A2
+:108A2000AF82002C27BD002003E000083182000146
+:108A300090A200303051003F5224002834C50AC0B3
+:108A40008CB000241600002234CB09008CA600480C
+:108A50003C0A7FFF3545FFFF00C510243C0E800017
+:108A6000AF82002035C509008F8800208CAD0060E2
+:108A7000010D602B15800002010020218CA40060F4
+:108A80000A000C22AF8400208D02006C0A000BFC4F
+:108A90003C0680008C8200488F8600203C097FFFC6
+:108AA0003527FFFF004788243C0480082403000189
+:108AB000AF910028AC80006CA383001C0A000C302E
+:108AC000AF8600248C9F00140A000C22AF9F002068
+:108AD0008D6200680A000C6C3C0E800034C4098072
+:108AE0008C8900708CA300140123382B10E0000443
+:108AF000000000008C8200700A000C6C3C0E8000AC
+:108B00008CA200140A000C6C3C0E80008F8500249F
+:108B100027BDFFE0AFBF0018AFB1001414A00008DC
+:108B2000AFB000103C04800034870A0090E60030AB
+:108B30002402000530C3003F106200B934840900EC
+:108B40008F91002000A080213C048000348E0A0018
+:108B50008DCD00043C0608008CC63FB831A73FFF0E
+:108B600000E6602B5580000100E03021938F001C4F
+:108B700011E0007800D0282B349F098093F9007C05
+:108B800033380002130000792403003400C3102B93
+:108B9000144000D90000000000C3302300D0282B6F
+:108BA0003C010800A4233FC414A0006E0200182159
+:108BB0003C0408008C843FB40064402B5500000145
+:108BC000006020213C05800034A90A00912A003C65
+:108BD0003C010800AC243FBC31430020146000037A
+:108BE0000000482134AB0E008D6900188F88002CDE
+:108BF0000128202B1080005F000000003C050800C9
+:108C00008CA53FBC00A96821010D602B1180005C80
+:108C100000B0702B0109382300E028213C01080036
+:108C2000AC273FBC12000003240AFFFC10B0008DEB
+:108C30003224000300AA18243C010800A4203FDAD3
+:108C40003C010800AC233FBC006028218F84002435
+:108C5000120400063C0B80088D6C006C0200202181
+:108C6000AF91002025900001AD70006C8F8D002821
+:108C700000858823AF91002401A52023AF8400281C
+:108C80001220000224070018240700103C18800856
+:108C90003706008090CF00683C010800A0273FD82D
+:108CA0002407000131EE00FF11C70047000000005B
+:108CB00014800018000028213C06800034D109806F
+:108CC00034CD010091A600098E2C001824C40001A7
+:108CD000000C86023205007F308B007F1165007F1B
+:108CE0002407FF803C19800837290080A124004C0C
+:108CF0003C0808008D083FD4241800023C010800FD
+:108D0000A0384019350F00083C010800AC2F3FD4B3
+:108D1000240500103C02800034440A009083003C8B
+:108D2000307F002013E0000500A02021240A00016C
+:108D30003C010800AC2A3FBC34A400018FBF0018DE
+:108D40008FB100148FB000100080102103E00008E4
+:108D500027BD00203C010800A4203FC410A0FF94C0
+:108D6000020018210A000CC000C018210A000CB72C
+:108D7000240300303C0508008CA53FBC00B0702BDC
+:108D800011C0FFA8000000003C19080097393FC43B
+:108D90000325C0210307782B11E000072CAA00044B
+:108DA0003C0360008C625404305F003F17E0FFE337
+:108DB000240400422CAA00041140FF9A240400421B
+:108DC0000A000D248FBF00181528FFB9000000000D
+:108DD0008CCA00183C1F800024020002015F182585
+:108DE000ACC3001837F90A00A0C200689329003C00
+:108DF0002404000400A01021312800203C010800B8
+:108E0000A0244019110000022405001024020001D2
+:108E10003C010800AC223FB40A000D1A3C0280005D
+:108E20008F8800288C8900600109282B14A000027B
+:108E3000010088218C9100603C048000348B0E007E
+:108E40008D640018240A000102202821022030210C
+:108E5000A38A001C0E000B83022080210A000CA6AE
+:108E6000AF82002C00045823122000073164000355
+:108E70003C0E800035C7098090ED007C31AC0004C9
+:108E800015800019248F00043C010800A4243FDA57
+:108E90003C1F080097FF3FDA03E5C82100D9C02B2B
+:108EA0001300FF6B8F8400242CA6000514C0FFA3C1
+:108EB0002404004230A200031440000200A2182340
+:108EC00024A3FFFC3C010800AC233FBC3C0108008C
+:108ED000A4203FDA0A000CE70060282100C77024B4
+:108EE0000A000D0D01C720263C010800A42F3FDA1F
+:108EF0000A000D78000000003C010800AC203FBCD7
+:108F00000A000D23240400428F8300283C058000C2
+:108F100034AA0A00146000060000102191470030B6
+:108F20002406000530E400FF108600030000000066
+:108F300003E0000800000000914B0048316900FF89
+:108F4000000941C21500FFFA3C0680083C040800F5
+:108F500094843FC43C0308008C633FDC3C19080048
+:108F60008F393FBC3C0F080095EF3FDA0064C02109
+:108F70008CCD00040319702101CF602134AB0E00A9
+:108F8000018D282318A0001D00000000914F004C07
+:108F90008F8C0034956D001031EE00FF8D89000438
+:108FA00001AE30238D8A000030CEFFFF000E290075
+:108FB0000125C82100003821014720210325182B55
+:108FC0000083C021AD990004AD980000918F000A84
+:108FD00001CF6821A18D000A956500128F8A0034A7
+:108FE000A5450008954B003825690001A5490038C2
+:108FF0009148000D35070008A147000D03E0000867
+:109000000000000027BDFFD8AFB000189388001CF7
+:109010008FB000143C0A80003C197FFF8F8700242A
+:109020003738FFFFAFBF0020AFB1001C355F0A002B
+:109030000218182493EB003C00087FC03C02BFFFDD
+:10904000006F60252CF000013449FFFF3C1F080031
+:109050008FFF3FDC8F9900303C18080097183FD2F3
+:1090600001897824001047803C07EFFF3C05F0FFA2
+:1090700001E818253C1180003169002034E2FFFF2F
+:1090800034ADFFFF362E098027A50010240600020C
+:1090900003F96023270B0002354A0E0000621824F2
+:1090A0000080802115200002000040218D48001C16
+:1090B000A7AB0012058000392407000030E800FF4C
+:1090C00000083F00006758253C028008AFAB001441
+:1090D000344F008091EA00683C08080091083FD9AD
+:1090E0003C09DFFF352CFFFF000AF82B3C0208008B
+:1090F00094423FCCA3A80011016CC024001FCF40B4
+:10910000031918258FA70010AFA300143C0C08000A
+:10911000918C3FDBA7A200168FAB001400ED482412
+:109120003C0F01003C0A0FFF012FC82531980003B6
+:10913000355FFFFF016D40243C027000033F38247F
+:1091400000181E0000E2482501037825AFAF001487
+:10915000AFA9001091CC007C0E000092A3AC0015CA
+:10916000362D0A0091A6003C30C400201080000675
+:10917000260200083C11080096313FC8262EFFFF4A
+:109180003C010800A42E3FC88FBF00208FB1001CF7
+:109190008FB0001803E0000827BD00288F8B002C3B
+:1091A000010B502B5540FFC5240700010A000E0497
+:1091B00030E800FF9383001C3C02800027BDFFD8ED
+:1091C00034480A0000805021AFBF002034460AC056
+:1091D000010028211060000E3444098091070030FE
+:1091E000240B00058F89002030EC003F118B000B11
+:1091F00000003821AFA900103C0B80088D69006C7D
+:10920000AFAA00180E00015AAFA90014A380001CD9
+:109210008FBF002003E0000827BD00288D1F0048F5
+:109220003C1808008F183FBC8F9900283C027FFF34
+:109230008D0800443443FFFFAFA900103C0B8008A9
+:109240008D69006C03E370240319782101CF682332
+:1092500001A83821AFAA00180E00015AAFA90014C6
+:109260000A000E58A380001C3C05800034A60A00AA
+:1092700090C7003C3C06080094C63FDA3C02080058
+:109280008C423FD430E30020000624001060001E12
+:10929000004438253C0880083505008090A300680C
+:1092A00000004821240800010000282124040001B6
+:1092B0003C0680008CCD017805A0FFFE34CF014034
+:1092C000ADE800083C0208008C423FDCA5E5000444
+:1092D000A5E40006ADE2000C3C04080090843FD9F0
+:1092E0003C03800834790080A1E40012ADE700144B
+:1092F000A5E900189338004C3C0E1000A1F8002D91
+:1093000003E00008ACCE017834A90E008D28001CC3
+:109310003C0C08008D8C3FBC952B0016952A001440
+:10932000018648213164FFFF0A000E803145FFFFAE
+:109330003C04800034830A009065003C30A2002089
+:109340001040001934870E00000040210000382131
+:10935000000020213C0680008CC901780520FFFE1A
+:1093600034CA014034CF010091EB0009AD48000838
+:109370003C0E08008DCE3FDC240DFF91240C0040F4
+:109380003C081000A5440004A5470006AD4E000CA3
+:10939000A14D0012AD4C0014A5400018A14B002DAA
+:1093A00003E00008ACC801788CE8001894E60012CD
+:1093B00094E4001030C7FFFF0A000EA93084FFFFBD
+:1093C0003C04800034830A009065003C30A20020F9
+:1093D0001040002727BDFFF82409000100003821B4
+:1093E000240800013C0680008CCA01780540FFFE7D
+:1093F0003C0280FF34C40100908D00093C0C080041
+:10940000918C4019A3AD00038FAB00003185007F24
+:109410003459FFFF01665025AFAA00009083000A6F
+:10942000A3A0000200057E00A3A300018FB80000E6
+:1094300034CB0140240C30000319702401CF68257F
+:10944000AD6D000C27BD0008AD6C0014A5600018C0
+:10945000AD690008A56700042409FF80A56800061F
+:109460003C081000A169001203E00008ACC80178B4
+:1094700034870E008CE9001894E6001294E4001082
+:1094800030C8FFFF0A000ECD3087FFFF27BDFFE089
+:10949000AFB100143C118000AFB00010AFBF001896
+:1094A00036380A00970F0032363001000E000B7F6D
+:1094B00031E43FFF8E0E0000240DFF803C042000AD
+:1094C00001C25821016D6024000C4940316A007FBF
+:1094D000012A4025010438253C048008AE270830C5
+:1094E0003486008090C500682403000230A200FF8B
+:1094F000104300048F9F00208F990024AC9F0068C8
+:10950000AC9900648FBF00188FB100148FB00010A9
+:1095100003E0000827BD00203C0A0800254A3A80E5
+:109520003C09080025293B103C08080025082F1C91
+:109530003C07080024E73BDC3C06080024C639044D
+:109540003C05080024A536583C0408002484325CFD
+:109550003C030800246339B83C0208002442375415
+:109560003C010800AC2A3F983C010800AC293F941C
+:109570003C010800AC283F903C010800AC273F9C10
+:109580003C010800AC263FAC3C010800AC253FA4E0
+:109590003C010800AC243FA03C010800AC233FB0D4
+:1095A0003C010800AC223FA803E0000800000000D6
+:1095B00080000940800009008008010080080080C8
+:1095C00080080000800E00008008008080080000F5
+:1095D00080000A8080000A00800009808000090065
+:00000001FF
--- zfcpdump-kernel-4.4.orig/firmware/bnx2/bnx2-rv2p-09-6.0.17.fw.ihex
+++ zfcpdump-kernel-4.4/firmware/bnx2/bnx2-rv2p-09-6.0.17.fw.ihex
@@ -3,8 +3,7 @@
 :1000200000000000000000000000000000000000D0
 :1000300000000E88000009500000000500000000CC
 :1000400000000000000000000000000000000000B0
-:080050000000000000000000A8
-:0800580000000010B180000659
+:10005000000000000000000000000010B180000659
 :100060000000001F05060011000000080500FFFF4A
 :10007000000000180002000000000008050000FF5A
 :10008000000000180002000000000008AC000001A1
@@ -382,11 +381,3 @@
 :1017C0000000000C2980000000000010001F000035
 :0817D000000000188000FE3546
 :00000001FF
-/*
- * This file contains firmware data derived from proprietary unpublished
- * source code, Copyright (c) 2004 - 2009 Broadcom Corporation.
- *
- * Permission is hereby granted for the distribution of this firmware data
- * in hexadecimal or equivalent format, provided this copyright notice is
- * accompanying it.
- */
--- zfcpdump-kernel-4.4.orig/firmware/bnx2/bnx2-rv2p-09ax-6.0.17.fw.ihex
+++ zfcpdump-kernel-4.4/firmware/bnx2/bnx2-rv2p-09ax-6.0.17.fw.ihex
@@ -3,8 +3,7 @@
 :1000200000000000000000000000000000000000D0
 :1000300000001010000009C80000000500000000CA
 :1000400000000000000000000000000000000000B0
-:080050000000000000000000A8
-:0800580000000010B180000659
+:10005000000000000000000000000010B180000659
 :100060000000001F03060011000000080500FFFF4C
 :10007000000000180002000000000008050000FF5A
 :10008000000000180002000000000008AC000001A1
@@ -155,8 +154,7 @@
 :100990000000001091D40000000000080500005580
 :1009A000000000188000FF360000000C29800001C4
 :1009B0000000000C1F800001000000082A00000752
-:0809C000000000188000FEDEBB
-:0809C80000000010B1800004E2
+:1009C000000000188000FEDE00000010B18000046E
 :1009D0000000001F0306001100000008050000FFD2
 :1009E0000000001800020000000000002A000000C3
 :1009F00000000010B1D400000000001091DE0000E3
@@ -415,11 +413,3 @@
 :1019C00000000010001F00000000000C6BD7000199
 :0819D000000000188000FE0475
 :00000001FF
-/*
- * This file contains firmware data derived from proprietary unpublished
- * source code, Copyright (c) 2004 - 2009 Broadcom Corporation.
- *
- * Permission is hereby granted for the distribution of this firmware data
- * in hexadecimal or equivalent format, provided this copyright notice is
- * accompanying it.
- */
--- zfcpdump-kernel-4.4.orig/firmware/bnx2x/bnx2x-e1-6.2.9.0.fw.ihex
+++ /dev/null
@@ -1,9484 +0,0 @@
-:1000000000003BB0000000680000070C00003C202E
-:1000100000001AF8000043300000007C00005E3051
-:1000200000007A2C00005EB0000000B00000D8E0B4
-:10003000000080200000D99800000088000159C00D
-:100040000000398800015A5000000090000193E040
-:100050000000AC040001947800000FFC0002408016
-:100060000000000400025080020400480000000F5D
-:100070000204005400000045020400580000000083
-:100080000204005C0000000602040070000000048E
-:1000900002040078000000000204007C1217000037
-:1000A00002040080221700000204008432170000BE
-:1000B00006040088000000050204009C12150000E0
-:1000C000020400A022150000020400A43215000062
-:1000D000060400A800000004020400B8021000009A
-:1000E000020400BC00100000020400C01010000058
-:1000F000020400C420100000020400C830100000F8
-:10010000060400CC00000004020400DC0010000023
-:10011000020400E012140000020400E422140000B3
-:10012000020400E832140000060400EC00000004A1
-:100130000104012400000000010401280000000067
-:100140000104012C00000000010401300000000047
-:1001500002040004000000FF02040008000000FF89
-:100160000204000C000000FF02040010000000FF69
-:1001700002040014000000FF02040018000000FF49
-:100180000204001C000000FF02040020000000FF29
-:10019000020400240000003E0204002800000000C9
-:1001A0000204002C0000003F020400300000003F69
-:1001B000020400340000003F020400380000000088
-:1001C0000204003C0000003F020400400000003F29
-:1001D000020400440000003F020420080000021155
-:1001E0000204200C0000020002042010000002049F
-:1001F00002042014000002190204201C0000FFFF6A
-:10020000020420200000FFFF020420240000FFFF62
-:10021000020420280000FFFF0604203800000080B0
-:100220000204223807FFFFFF0204223C0000003FC7
-:100230000204224007FFFFFF020422440000000FD7
-:1002400001042248000000000104224C00000000CC
-:1002500001042250000000000104225400000000AC
-:1002600001042258000000000104225C000000008C
-:10027000010422600000000001042264000000006C
-:1002800001042268000000000104226C000000004C
-:10029000010422700000000001042274000000002C
-:1002A00001042278000000000104227C000000000C
-:1002B000020424BC000000010C042000000003E83C
-:1002C0000A042000000000010B0420000000000AC6
-:1002D0000605400000000D0002050044000000205B
-:1002E00002050048000000320205009002150020BF
-:1002F000020500940215002002050098000000305D
-:100300000205009C08100000020500A00000003358
-:10031000020500A400000030020500A80000003122
-:10032000020500AC00000002020500B0000000055C
-:10033000020500B400000006020500B8000000023B
-:10034000020500BC00000002020500C00000000021
-:10035000020500C400000005020500C800000002FC
-:10036000020500CC00000002020500D000000002DF
-:10037000020500D400000001020501140000000184
-:100380000205011C0000000102050120000000021E
-:1003900002050204000000010205020C00000040FA
-:1003A00002050210000000400205021C00000020AF
-:1003B00002050220000000130205022400000020B4
-:1003C000060502400000000A04050280002000002B
-:1003D000020500500000000702050054000000075D
-:1003E00002050058000000000205005C0000000843
-:1003F0000605006000000004020500D800000006A9
-:10040000020500E00000000D020500E40000002DE0
-:10041000020500E800000000020500EC00000020DA
-:10042000020500F000000000020500F400000020BA
-:10043000020500F800000000020500FC000000209A
-:100440000205000400000001020500080000000190
-:100450000205000C00000001020500100000000170
-:100460000205001400000001020500180000000150
-:100470000205001C00000001020500200000000130
-:100480000205002400000001020500280000000110
-:100490000205002C000000010205003000000001F0
-:1004A00002050034000000010205003800000001D0
-:1004B0000205003C000000010205004000000001B0
-:1004C0000406100002000020020600DC000000010B
-:1004D000010600D80000000004060200000302200C
-:1004E000020600DC0000000002060068000000B800
-:1004F0000206007800000114010600B800000000A8
-:10050000010600C8000000000206006C000000B8F0
-:100510000206007C00000114010600BC000000007F
-:10052000010600CC0000000007180400007B00005A
-:100530000818076000140223071C00002A040000AA
-:10054000071C800032110A82071D00001E0C1707CD
-:10055000081D4550575602250118000000000000F4
-:10056000011800040000000001180008000000004D
-:100570000118000C0000000001180010000000002D
-:100580000118001400000000021800200000000103
-:1005900002180024000000020218002800000003D6
-:1005A0000218002C000000000218003000000004B7
-:1005B000021800340000000102180038000000009A
-:1005C0000218003C00000001021800400000000476
-:1005D000021800440000000002180048000000015A
-:1005E0000218004C00000003021800500000000038
-:1005F0000218005400000001021800580000000416
-:100600000218005C000000000218006000000001F9
-:1006100002180064000000030218006800000000D7
-:100620000218006C000000010218007000000004B5
-:100630000218007400000000021800780000000496
-:100640000218007C00000003061800800000000271
-:10065000021800A400003FFF021800A8000003FFDA
-:1006600002180224000000000218023400000000FA
-:100670000218024C00000000021802E4000000FF13
-:100680000618100000000400021B8BC000000001CF
-:10069000021B800000000034021B80400000001894
-:1006A000021B80800000000C021B80C000000020A4
-:1006B0000C1B83000007A1200A1B830000000138E7
-:1006C0000B1B8300000013880A1B834000000000FE
-:1006D0000C1B8340000001F40B1B8340000000054D
-:1006E000021B83800007A120021B83C0000001F4CD
-:1006F000061A100000000273041A19CC0001022728
-:10070000061A2008000000C8061A20000000000297
-:10071000041A499800040228061A2E280000000234
-:10072000061A2E2000000002061A0800000000022F
-:10073000061A080800000004061A08180000000243
-:10074000041A08B00002022C061A2FD0000000067E
-:10075000041A2FE80002022E041A2FC000040230EF
-:10076000041A300000010234061A300400000003AD
-:10077000041A301000010235061A3014000000037C
-:10078000041A302000010236061A3024000000034B
-:10079000041A303000010237061A3034000000031A
-:1007A000041A304000010238061A304400000003E9
-:1007B000041A305000010239061A305400000003B8
-:1007C000041A30600001023A061A30640000000387
-:1007D000041A30700001023B061A30740000000356
-:1007E000041A30800001023C061A30840000000325
-:1007F000041A30900001023D061A309400000003F4
-:10080000041A30A00001023E061A30A400000003C2
-:10081000041A30B00001023F061A30B40000000391
-:10082000041A30C000010240061A30C40000000360
-:10083000041A30D000010241061A30D4000000032F
-:10084000041A30E000010242061A30E400000003FE
-:10085000041A30F000010243061A30F400000003CD
-:10086000041A310000010244061A3104000000039A
-:10087000041A311000010245061A31140000000369
-:10088000041A312000010246061A31240000000338
-:10089000041A313000010247061A31340000000307
-:1008A000041A314000010248061A314400000003D6
-:1008B000041A315000010249061A315400000003A5
-:1008C000041A31600001024A061A31640000000374
-:1008D000041A31700001024B061A31740000000343
-:1008E000041A31800001024C061A31840000000312
-:1008F000041A31900001024D061A319400000003E1
-:10090000041A31A00001024E061A31A400000003AF
-:10091000041A31B00001024F061A31B4000000037E
-:10092000041A31C000010250061A31C4000000034D
-:10093000041A31D000010251061A31D4000000031C
-:10094000041A31E000010252061A31E400000003EB
-:10095000041A31F000010253061A31F400000003BA
-:10096000041A320000010254061A32040000000387
-:10097000041A321000010255061A32140000000356
-:10098000041A322000010256061A32240000000325
-:10099000041A323000010257061A323400000003F4
-:1009A000041A324000010258061A324400000003C3
-:1009B000041A325000010259061A32540000000392
-:1009C000041A32600001025A061A32640000000361
-:1009D000041A32700001025B061A32740000000330
-:1009E000041A32800001025C061A328400000003FF
-:1009F000041A32900001025D061A329400000003CE
-:100A0000041A32A00001025E061A32A4000000039C
-:100A1000041A32B00001025F061A32B4000000036B
-:100A2000041A32C000010260061A32C4000000033A
-:100A3000041A32D000010261061A32D40000000309
-:100A4000041A32E000010262061A32E400000003D8
-:100A5000041A32F000010263061A32F400000003A7
-:100A6000041A330000010264061A33040000000374
-:100A7000041A331000010265061A33140000000343
-:100A8000041A332000010266061A33240000000312
-:100A9000041A333000010267061A333400000003E1
-:100AA000041A334000010268061A334400000003B0
-:100AB000041A335000010269061A3354000000037F
-:100AC000041A33600001026A061A3364000000034E
-:100AD000041A33700001026B061A3374000000031D
-:100AE000041A33800001026C061A338400000003EC
-:100AF000041A33900001026D061A339400000003BB
-:100B0000041A33A00001026E061A33A40000000389
-:100B1000041A33B00001026F061A33B40000000358
-:100B2000041A33C000010270061A33C40000000327
-:100B3000041A33D000010271061A33D400000003F6
-:100B4000041A33E000010272061A33E400000003C5
-:100B5000041A33F000010273061A33F40000000394
-:100B6000041A340000010274061A34040000000361
-:100B7000041A341000010275061A34140000000330
-:100B8000041A342000010276061A342400000003FF
-:100B9000041A343000010277061A343400000003CE
-:100BA000041A344000010278061A3444000000039D
-:100BB000041A345000010279061A3454000000036C
-:100BC000041A34600001027A061A3464000000033B
-:100BD000041A34700001027B061A3474000000030A
-:100BE000041A34800001027C061A348400000003D9
-:100BF000041A34900001027D061A349400000003A8
-:100C0000041A34A00001027E061A34A40000000376
-:100C1000041A34B00001027F061A34B40000000345
-:100C2000041A34C000010280061A34C40000000314
-:100C3000041A34D000010281061A34D400000003E3
-:100C4000041A34E000010282061A34E400000003B2
-:100C5000041A34F000010283061A34F40000000381
-:100C6000041A350000010284061A3504000000034E
-:100C7000041A351000010285061A3514000000031D
-:100C8000041A352000010286061A352400000003EC
-:100C9000041A353000010287061A353400000003BB
-:100CA000041A354000010288061A3544000000038A
-:100CB000041A355000010289061A35540000000359
-:100CC000041A35600001028A061A35640000000328
-:100CD000041A35700001028B061A357400000003F7
-:100CE000041A35800001028C061A358400000003C6
-:100CF000041A35900001028D061A35940000000395
-:100D0000041A35A00001028E061A35A40000000363
-:100D1000041A35B00001028F061A35B40000000332
-:100D2000041A35C000010290061A35C40000000301
-:100D3000041A35D000010291061A35D400000003D0
-:100D4000041A35E000010292061A35E4000000039F
-:100D5000041A35F000010293061A35F4000000036E
-:100D6000041A360000010294061A3604000000033B
-:100D7000041A361000010295061A3614000000030A
-:100D8000041A362000010296061A362400000003D9
-:100D9000041A363000010297061A363400000003A8
-:100DA000041A364000010298061A36440000000377
-:100DB000041A365000010299061A36540000000346
-:100DC000041A36600001029A061A36640000000315
-:100DD000041A36700001029B061A367400000003E4
-:100DE000041A36800001029C061A368400000003B3
-:100DF000041A36900001029D061A36940000000382
-:100E0000041A36A00001029E061A36A40000000350
-:100E1000041A36B00001029F061A36B4000000031F
-:100E2000041A36C0000102A0061A36C400000003EE
-:100E3000041A36D0000102A1061A36D400000003BD
-:100E4000041A36E0000102A2061A36E4000000038C
-:100E5000041A36F0000102A3061A36F4000000035B
-:100E6000041A3700000102A4061A37040000000328
-:100E7000041A3710000102A5061A371400000003F7
-:100E8000041A3720000102A6061A372400000003C6
-:100E9000041A3730000102A7061A37340000000395
-:100EA000041A3740000102A8061A37440000000364
-:100EB000041A3750000102A9061A37540000000333
-:100EC000041A3760000102AA061A37640000000302
-:100ED000041A3770000102AB061A377400000003D1
-:100EE000041A3780000102AC061A378400000003A0
-:100EF000041A3790000102AD061A3794000000036F
-:100F0000041A37A0000102AE061A37A4000000033D
-:100F1000041A37B0000102AF061A37B4000000030C
-:100F2000041A37C0000102B0061A37C400000003DB
-:100F3000041A37D0000102B1061A37D400000003AA
-:100F4000041A37E0000102B2061A37E40000000379
-:100F5000041A37F0000102B3061A37F40000000348
-:100F6000041A3800000102B4061A38040000000315
-:100F7000041A3810000102B5061A381400000003E4
-:100F8000041A3820000102B6061A382400000003B3
-:100F9000041A3830000102B7061A38340000000382
-:100FA000041A3840000102B8061A38440000000351
-:100FB000041A3850000102B9061A38540000000320
-:100FC000041A3860000102BA061A386400000003EF
-:100FD000041A3870000102BB061A387400000003BE
-:100FE000041A3880000102BC061A3884000000038D
-:100FF000041A3890000102BD061A3894000000035C
-:10100000041A38A0000102BE061A38A4000000032A
-:10101000041A38B0000102BF061A38B400000003F9
-:10102000041A38C0000102C0061A38C400000003C8
-:10103000041A38D0000102C1061A38D40000000397
-:10104000041A38E0000102C2061A38E40000000366
-:10105000041A38F0000102C3061A38F40000000335
-:10106000041A3900000102C4061A39040000000302
-:10107000041A3910000102C5061A391400000003D1
-:10108000041A3920000102C6061A392400000003A0
-:10109000041A3930000102C7061A3934000000036F
-:1010A000041A3940000102C8061A3944000000033E
-:1010B000041A3950000102C9061A3954000000030D
-:1010C000041A3960000102CA061A396400000003DC
-:1010D000041A3970000102CB061A397400000003AB
-:1010E000041A3980000102CC061A3984000000037A
-:1010F000041A3990000102CD061A39940000000349
-:10110000041A39A0000102CE061A39A40000000317
-:10111000041A39B0000102CF061A39B400000003E6
-:10112000041A39C0000102D0061A39C400000003B5
-:10113000041A39D0000102D1061A39D40000000384
-:10114000041A39E0000102D2061A39E40000000353
-:10115000041A39F0000102D3061A39F40000000322
-:10116000041A3A00000102D4061A3A0400000003EF
-:10117000041A3A10000102D5061A3A1400000003BE
-:10118000041A3A20000102D6061A3A24000000038D
-:10119000041A3A30000102D7061A3A34000000035C
-:1011A000041A3A40000102D8061A3A44000000032B
-:1011B000041A3A50000102D9061A3A5400000003FA
-:1011C000041A3A60000102DA061A3A6400000003C9
-:1011D000041A3A70000102DB061A3A740000000398
-:1011E000041A3A80000102DC061A3A840000000367
-:1011F000041A3A90000102DD061A3A940000000336
-:10120000041A3AA0000102DE061A3AA40000000304
-:10121000041A3AB0000102DF061A3AB400000003D3
-:10122000041A3AC0000102E0061A3AC400000003A2
-:10123000041A3AD0000102E1061A3AD40000000371
-:10124000041A3AE0000102E2061A3AE40000000340
-:10125000041A3AF0000102E3061A3AF4000000030F
-:10126000041A3B00000102E4061A3B0400000003DC
-:10127000041A3B10000102E5061A3B1400000003AB
-:10128000041A3B20000102E6061A3B24000000037A
-:10129000041A3B30000102E7061A3B340000000349
-:1012A000041A3B40000102E8061A3B440000000318
-:1012B000041A3B50000102E9061A3B5400000003E7
-:1012C000041A3B60000102EA061A3B6400000003B6
-:1012D000041A3B70000102EB061A3B740000000385
-:1012E000041A3B80000102EC061A3B840000000354
-:1012F000041A3B90000102ED061A3B940000000323
-:10130000041A3BA0000102EE061A3BA400000003F1
-:10131000041A3BB0000102EF061A3BB400000003C0
-:10132000041A3BC0000102F0061A3BC4000000038F
-:10133000041A3BD0000102F1061A3BD4000000035E
-:10134000041A3BE0000102F2061A3BE4000000032D
-:10135000041A3BF0000102F3061A3BF400000003FC
-:10136000041A3C00000102F4061A3C0400000003C9
-:10137000041A3C10000102F5061A3C140000000398
-:10138000041A3C20000102F6061A3C240000000367
-:10139000041A3C30000102F7061A3C340000000336
-:1013A000041A3C40000102F8061A3C440000000305
-:1013B000041A3C50000102F9061A3C5400000003D4
-:1013C000041A3C60000102FA061A3C6400000003A3
-:1013D000041A3C70000102FB061A3C740000000372
-:1013E000041A3C80000102FC061A3C840000000341
-:1013F000041A3C90000102FD061A3C940000000310
-:10140000041A3CA0000102FE061A3CA400000003DE
-:10141000041A3CB0000102FF061A3CB400000003AD
-:10142000041A3CC000010300061A3CC4000000037B
-:10143000041A3CD000010301061A3CD4000000034A
-:10144000041A3CE000010302061A3CE40000000319
-:10145000041A3CF000010303061A3CF400000003E8
-:10146000041A3D0000010304061A3D0400000003B5
-:10147000041A3D1000010305061A3D140000000384
-:10148000041A3D2000010306061A3D240000000353
-:10149000041A3D3000010307061A3D340000000322
-:1014A000041A3D4000010308061A3D4400000003F1
-:1014B000041A3D5000010309061A3D5400000003C0
-:1014C000041A3D600001030A061A3D64000000038F
-:1014D000041A3D700001030B061A3D74000000035E
-:1014E000041A3D800001030C061A3D84000000032D
-:1014F000041A3D900001030D061A3D9400000003FC
-:10150000041A3DA00001030E061A3DA400000003CA
-:10151000041A3DB00001030F061A3DB40000000399
-:10152000041A3DC000010310061A3DC40000000368
-:10153000041A3DD000010311061A3DD40000000337
-:10154000041A3DE000010312061A3DE40000000306
-:10155000041A3DF000010313061A3DF400000003D5
-:10156000041A3E0000010314061A3E0400000003A2
-:10157000041A3E1000010315061A3E140000000371
-:10158000041A3E2000010316061A3E240000000340
-:10159000041A3E3000010317061A3E34000000030F
-:1015A000041A3E4000010318061A3E4400000003DE
-:1015B000041A3E5000010319061A3E5400000003AD
-:1015C000041A3E600001031A061A3E64000000037C
-:1015D000041A3E700001031B061A3E74000000034B
-:1015E000041A3E800001031C061A3E84000000031A
-:1015F000041A3E900001031D061A3E9400000003E9
-:10160000041A3EA00001031E061A3EA400000003B7
-:10161000041A3EB00001031F061A3EB40000000386
-:10162000041A3EC000010320061A3EC40000000355
-:10163000041A3ED000010321061A3ED40000000324
-:10164000041A3EE000010322061A3EE400000003F3
-:10165000041A3EF000010323061A3EF400000003C2
-:10166000041A3F0000010324061A3F04000000038F
-:10167000041A3F1000010325061A3F14000000035E
-:10168000041A3F2000010326061A3F24000000032D
-:10169000041A3F3000010327061A3F3400000003FC
-:1016A000041A3F4000010328061A3F4400000003CB
-:1016B000041A3F5000010329061A3F54000000039A
-:1016C000041A3F600001032A061A3F640000000369
-:1016D000041A3F700001032B061A3F740000000338
-:1016E000041A3F800001032C061A3F840000000307
-:1016F000041A3F900001032D061A3F9400000003D6
-:10170000041A3FA00001032E061A3FA400000003A4
-:10171000041A3FB00001032F061A3FB40000000373
-:10172000041A3FC000010330061A3FC40000000342
-:10173000041A3FD000010331061A3FD40000000311
-:10174000041A3FE000010332061A3FE400000007DC
-:10175000041A4CB000080333061A400000000124AC
-:10176000021A492000000000061A2500000000109F
-:10177000061A258000000012061A09C00000004861
-:10178000061A080000000002061A082000000012D5
-:10179000041A2FB00002033B041A4CF00002033D70
-:1017A000061A500000000004061A449000000124AC
-:1017B000021A492400000000061A2540000000100B
-:1017C000061A25C800000012061A0AE000000048A8
-:1017D000061A081000000002061A0868000000122D
-:1017E000041A2FB80002033F041A4CF80002034108
-:1017F000061A5010000000040200A468000AFFDC72
-:101800000200A280000000010200A294071D29111D
-:101810000200A298000000000200A29C009C042488
-:101820000200A2A0000000000200A2A40000020921
-:101830000200A4FCFF000000020100B4000000014F
-:10184000020100B800000001020100DC00000001FC
-:10185000020101000000000102010104000000017A
-:101860000201007C0030000002010084000000281A
-:101870000201008C000000000201013000000004A1
-:101880000201025C000000010201032800000000C8
-:101890000201055400000030020100C400000001F4
-:1018A000020100CC00000001020100F8000000016C
-:1018B000020100F000000001020100800030000081
-:1018C00002010088000000280201009000000000D2
-:1018D0000201013400000004020102DC00000001EA
-:1018E0000201032C0000000002010564000000302A
-:1018F000020100C800000001020100D00000000148
-:10190000020100FC00000001020100F400000001DF
-:10191000020C100000000028020C200800000A1130
-:10192000020C200C00000A00020C201000000A0427
-:10193000020C201C0000FFFF020C20200000FFFF13
-:10194000020C20240000FFFF020C20280000FFFFF3
-:10195000020C203800000020020C203C0000002176
-:10196000020C204000000022020C20440000002352
-:10197000020C204800000024020C204C000000252E
-:10198000020C205000000026020C2054000000270A
-:10199000020C205800000028020C205C00000029E6
-:1019A000020C20600000002A020C20640000002BC2
-:1019B000020C20680000002C020C206C0000002D9E
-:1019C000020C20700000002E020C20740000002F7A
-:1019D000020C207800000010060C207C0000004F54
-:1019E000020C21B800000001020C21BC0000000123
-:1019F000020C21C000000001020C21C40000000103
-:101A0000020C21C800000001020C21CC00000001E2
-:101A1000020C21D000000001020C21D400000001C2
-:101A2000020C21D800000001020C21DC00000001A2
-:101A3000020C21E000000001020C21E40000000182
-:101A4000020C21E800000001020C21EC0000000162
-:101A5000020C21F000000001020C21F40000000142
-:101A6000020C21F800000001060C21FC0000000F10
-:101A7000020C223807FFFFFF020C223C0000003F4F
-:101A8000020C224007FFFFFF020C22440000000F5F
-:101A9000010C224800000000010C224C0000000054
-:101AA000010C225000000000010C22540000000034
-:101AB000010C225800000000010C225C0000000014
-:101AC000010C226000000000010C226400000000F4
-:101AD000010C226800000000010C226C00000000D4
-:101AE000010C227000000000010C227400000000B4
-:101AF000010C227800000000010C227C0000000094
-:101B0000020C24BC000000010C0C2000000003E8C3
-:101B10000A0C2000000000010B0C20000000000A4D
-:101B2000020C400800000562020C400C0000055148
-:101B3000020C401000000555020C40140000057214
-:101B4000020C401C0000FFFF020C40200000FFFFC1
-:101B5000020C40240000FFFF020C40280000FFFFA1
-:101B6000020C403800000046020C403C0000000C13
-:101B7000060C40400000005E020C41B8000000016D
-:101B8000060C41BC0000001F020C423807FFFFFF9B
-:101B9000020C423C0000003F020C424007FFFFFFE6
-:101BA000020C42440000000F010C424800000000FB
-:101BB000010C424C00000000010C425000000000EB
-:101BC000010C425400000000010C425800000000CB
-:101BD000010C425C00000000010C426000000000AB
-:101BE000010C426400000000010C4268000000008B
-:101BF000010C426C00000000010C4270000000006B
-:101C0000010C427400000000010C4278000000004A
-:101C1000010C427C00000000010C4280000000002A
-:101C2000020C44C0000000010C0C4000000003E85E
-:101C30000A0C4000000000010B0C40000000000AEC
-:101C4000060D400000000A00020D004400000032B2
-:101C5000020D008C02150020020D009002150020DC
-:101C6000020D009408100000020D009800000033DF
-:101C7000020D009C00000002020D00A00000000008
-:101C8000020D00A400000005020D00A800000005E0
-:101C9000060D00AC00000002020D00B400000002BE
-:101CA000020D00B800000003020D00BC000000029D
-:101CB000020D00C000000001020D00C8000000027B
-:101CC000020D00CC00000002020D015C00000001CA
-:101CD000020D016400000001020D01680000000215
-:101CE000020D020400000001020D020C00000020A1
-:101CF000020D021000000040020D0214000000401E
-:101D0000020D022000000003020D02240000001852
-:101D1000060D028000000012040D030000180343AA
-:101D2000060D03600000000C020D004C00000001D5
-:101D3000020D005000000002020D005400000000DF
-:101D4000020D005800000008060D005C00000004B1
-:101D5000020D00C400000004020D0114000000097F
-:101D6000020D011800000029020D011C0000000AEC
-:101D7000020D01200000002A020D012400000000D5
-:101D8000020D012800000020020D012C00000000BF
-:101D9000020D013000000020020D0134000000009F
-:101DA000020D013800000020020D013C000000007F
-:101DB000020D014000000020020D0144000000005F
-:101DC000020D014800000020020D00040000000187
-:101DD000020D000800000001020D000C00000001CF
-:101DE000020D001000000001020D001400000001AF
-:101DF000020D001800000001020D001C000000018F
-:101E0000020D002000000001020D0024000000016E
-:101E1000020D002800000001020D002C000000014E
-:101E2000020D003000000001020D0034000000012E
-:101E3000020D003800000001020D003C000000010E
-:101E4000060E200000000800020E004C00000032C8
-:101E5000020E009402150020020E009802150020C8
-:101E6000020E009C00000030020E00A008100000CE
-:101E7000020E00A400000033020E00A80000003093
-:101E8000020E00AC00000031020E00B000000002A3
-:101E9000020E00B400000004020E00B800000000B2
-:101EA000020E00BC00000002020E00C00000000292
-:101EB000020E00C400000000020E00C80000000274
-:101EC000020E00CC00000007020E00D0000000024D
-:101ED000020E00D400000002020E00D80000000133
-:101EE000020E014400000001020E014C000000013E
-:101EF000020E015000000002020E02040000000168
-:101F0000020E020C00000040020E02100000004011
-:101F1000020E021C00000004020E0220000000203D
-:101F2000020E02240000000E020E02280000001B18
-:101F3000060E030000000012040E0280001B035B6B
-:101F4000060E02EC00000005020E00540000000C1A
-:101F5000020E00580000000C020E005C00000000A1
-:101F6000020E006000000010060E00640000000475
-:101F7000020E00DC00000003020E01100000000F42
-:101F8000020E01140000002F020E011800000000D4
-:101F9000020E011C00000020020E000400000001DF
-:101FA000020E000800000001020E000C00000001FB
-:101FB000020E001000000001020E001400000001DB
-:101FC000020E001800000001020E001C00000001BB
-:101FD000020E002000000001020E0024000000019B
-:101FE000020E002800000001020E002C000000017B
-:101FF000020E003000000001020E0034000000015B
-:10200000020E003800000001020E003C000000013A
-:10201000020E004000000001020E0044000000011A
-:102020000730040000AF0000083007680013037693
-:10203000073400003305000007348000327F0CC2F3
-:10204000073500001A951962083539E058C403783D
-:10205000013000000000000001300004000000001A
-:1020600001300008000000000130000C00000000FA
-:1020700001300010000000000130001400000000DA
-:1020800002300020000000010230002400000002A5
-:1020900002300028000000030230002C0000000085
-:1020A0000230003000000004023000340000000163
-:1020B00002300038000000000230003C0000000147
-:1020C0000230004000000004023000440000000024
-:1020D00002300048000000010230004C0000000304
-:1020E00002300050000000000230005400000001E7
-:1020F00002300058000000040230005C00000000C4
-:1021000002300060000000010230006400000003A3
-:1021100002300068000000000230006C0000000186
-:102120000230007000000004023000740000000063
-:1021300002300078000000040230007C0000000340
-:102140000630008000000002023000A400003FFFC3
-:10215000023000A8000003FF02300224000000004B
-:1021600002300234000000000230024C0000000087
-:10217000023002E40000FFFF0630200000000800EB
-:1021800002338BC000000001023380000000001AFF
-:10219000023380400000004E0233808000000010B7
-:1021A000023380C0000000200C3383000007A12010
-:1021B0000A338300000001380B33830000001388CA
-:1021C0000A338340000000000C338340000001F418
-:1021D0000B33834000000005023383800007A120F9
-:1021E000023383C0000001F406322A88000000C2D6
-:1021F00006322008000000C806322000000000025D
-:10220000063223E80000004004322E580004037A0E
-:10221000063250A000000004063250B80000000250
-:102220000632508000000006043250980002037EFF
-:10223000063250000000002006323000000004008A
-:1022400006321C0000000004043218300002038033
-:10225000063224E8000000B402322DB00000000075
-:1022600006324000000000B40632300000000020BA
-:10227000063231000000002006323200000000204B
-:102280000632330000000020063234000000002037
-:102290000632350000000020063236000000002023
-:1022A000063237000000002006323800000000200F
-:1022B000063239000000002006323A0000000020FB
-:1022C00006323B000000002006323C0000000020E7
-:1022D00006323D000000002006323E0000000020D3
-:1022E00006323F000000002006321C1000000002F1
-:1022F000063245A000000024063227B8000000B4D2
-:1023000002322DB400000000063242D0000000B4BA
-:1023100006323080000000200632318000000020AC
-:102320000632328000000020063233800000002098
-:102330000632348000000020063235800000002084
-:102340000632368000000020063237800000002070
-:10235000063238800000002006323980000000205C
-:1023600006323A800000002006323B800000002048
-:1023700006323C800000002006323D800000002034
-:1023800006323E800000002006323F800000002020
-:1023900006321C20000000020632463000000024F5
-:1023A0000720040000870000082007800010038237
-:1023B000072400003165000007248000081D0C5A26
-:1023C00008248EB06C9003840120000000000000FF
-:1023D00001200004000000000120000800000000AF
-:1023E0000120000C0000000001200010000000008F
-:1023F0000120001400000000022000200000000165
-:102400000220002400000002022000280000000337
-:102410000220002C00000000022000300000000418
-:1024200002200034000000010220003800000000FB
-:102430000220003C000000010220004000000004D7
-:1024400002200044000000000220004800000001BB
-:102450000220004C00000003022000500000000099
-:102460000220005400000001022000580000000477
-:102470000220005C0000000002200060000000015B
-:102480000220006400000003022000680000000039
-:102490000220006C00000001022000700000000417
-:1024A00002200074000000000220007800000004F8
-:1024B0000220007C000000030620008000000002D3
-:1024C000022000A400003FFF022000A8000003FF3C
-:1024D000022002240000000002200234000000005C
-:1024E0000220024C00000000022002E40000FFFF76
-:1024F000062020000000080002238BC0000000011D
-:10250000022380000000001002238040000000121F
-:102510000223808000000030022380C00000000EF3
-:102520000C2383000007A1200A2383000000013848
-:102530000B238300000013880A238340000000005F
-:102540000C238340000001F40B23834000000005AE
-:10255000022383800007A120022383C0000001F42E
-:10256000062250000000004206222008000000C899
-:10257000062220000000000206224000000000C6E3
-:1025800004224318000503860622432C0000000B9A
-:10259000042243580005038B0622436C0000000B05
-:1025A0000422439800050390062243AC0000000B70
-:1025B000042243D800050395062243EC0000000BDB
-:1025C000042244180005039A0622442C0000000B44
-:1025D000042244580005039F0622446C0000000BAF
-:1025E00004224498000503A4062244AC0000000B1A
-:1025F000042244D8000503A9062244EC0000000B85
-:1026000004224518000503AE0622452C0000000BED
-:1026100004224558000503B30622456C0000000B58
-:1026200004224598000503B8062245AC0000000BC3
-:10263000042245D8000503BD062245EC0000000B2E
-:1026400004224618000503C20622462C0000000B97
-:1026500004224658000503C70622466C0000000B02
-:1026600004224698000503CC062246AC0000000B6D
-:10267000042246D8000503D1062246EC0000000BD8
-:1026800004224718000503D60622472C0000000B41
-:1026900004224758000503DB0622476C0000000BAC
-:1026A00004224798000503E0062247AC0000000B17
-:1026B000042247D8000503E5062247EC0000000B82
-:1026C00004224818000503EA0622482C0000000BEB
-:1026D00004224858000503EF0622486C0000000B56
-:1026E00004224898000503F4062248AC0000000BC1
-:1026F000042248D8000503F9062248EC0000000B2C
-:1027000004224918000503FE0622492C0000000B94
-:1027100004224958000504030622496C0000000BFE
-:102720000422499800050408062249AC0000000B69
-:10273000042249D80005040D062249EC0000000BD4
-:1027400004224A180005041206224A2C0000000B3D
-:1027500004224A580005041706224A6C0000000BA8
-:1027600004224A980005041C06224AAC0000000B13
-:1027700004224AD80005042106224AEC0000000584
-:1027800006224B000000001704224B5C00010426C7
-:1027900006224B600000000304224B6C000104275A
-:1027A000062238000000004006223000000002002F
-:1027B000042251C00004042806221000000000C0BA
-:1027C000062215C00000024004221EC80008042C86
-:1027D0000622390000000008022251180000000003
-:1027E000062251D00000000606221300000000025D
-:1027F00006221410000000300622392000000008D4
-:102800000222511C00000000062251E800000006D0
-:102810000622130800000002062214D00000003037
-:102820000216100000000028021700080000000235
-:102830000217002C000000030217003C00000004F7
-:1028400002170044000000000217004800000002C8
-:102850000217004C0000009002170050000000908A
-:102860000217005400800090021700580810000062
-:10287000021700600000008A021700640000008058
-:1028800002170068000000810217006C0000008041
-:10289000021700700000000602170078000007D041
-:1028A0000217007C0000076C02170038007C10043F
-:1028B000021700040000000F06164024000000026A
-:1028C000021640700000001C0216420800000001C1
-:1028D0000216421000000001021642200000000112
-:1028E00002164228000000010216423000000001DA
-:1028F000021642380000000102164260000000018A
-:102900000C16401C0003D0900A16401C0000009CCE
-:102910000B16401C000009C40216403000000008DD
-:10292000021640340000000C02164038000000106F
-:102930000216404400000020021640000000000182
-:10294000021640D8000000010216400800000001F5
-:102950000216400C000000010216401000000001A9
-:10296000021642400000000002164248000000002B
-:1029700006164270000000020216425000000000DD
-:1029800002164258000000000616428000000002B5
-:1029900002166008000006140216600C0000060013
-:1029A00002166010000006040216601C0000FFFF03
-:1029B000021660200000FFFF021660240000FFFFE7
-:1029C000021660280000FFFF021660380000002099
-:1029D0000216603C00000020061660400000000265
-:1029E00002166048000000230216604C000000241C
-:1029F00002166050000000250216605400000026F8
-:102A000002166058000000270216605C00000029D2
-:102A1000021660600000002A021660640000002BAD
-:102A2000021660680000002C0216606C0000002D89
-:102A30000616607000000012021660B80000000167
-:102A4000021660BC00000001061660C00000003ED7
-:102A5000021661B800000001061661BC0000001FEC
-:102A60000216623807FFFFFF0216623C0000003FBB
-:102A70000216624007FFFFFF021662440000000FCB
-:102A800001166248000000000116624C00000000C0
-:102A900001166250000000000116625400000000A0
-:102AA00001166258000000000116625C0000000080
-:102AB0000116626000000000011662640000000060
-:102AC00001166268000000000116626C0000000040
-:102AD0000116627000000000011662740000000020
-:102AE00001166278000000000116627C0000000000
-:102AF000021664BC000000010C166000000003E830
-:102B00000A166000000000010B1660000000000AB9
-:102B100002168040000000060216804400000005F6
-:102B2000021680480000000A0216804C00000005D2
-:102B30000216805400000002021680CC000000043F
-:102B4000021680D000000004021680D400000004A9
-:102B5000021680D800000004021680DC0000000489
-:102B6000021680E000000004021680E40000000469
-:102B7000021680E800000004021688040000000429
-:102B8000021680300000007C021680340000003DF8
-:102B9000021680380000003F0216803C0000009CB6
-:102BA000021680F000000007061680F40000000501
-:102BB0000216880C010101010216810800000000C4
-:102BC0000216810C000000040216811000000004AF
-:102BD0000216811400000002021688100801200469
-:102BE00002168118000000050216811C0000000575
-:102BF0000216812000000005021681240000000555
-:102C00000216882C200810010216812800000008F6
-:102C10000216812C00000006021681300000000719
-:102C200002168134000000000216883001010120E4
-:102C300006168138000000040216883401010101E3
-:102C400006168148000000040216883801010101BF
-:102C500006168158000000040216883C010101019B
-:102C6000061681680000000302168174000000014E
-:102C7000021688400101010102168178000000015E
-:102C80000216817C00000001021681800000000114
-:102C9000021681840000000102168844010101012E
-:102CA00002168188000000010216818C00000004D9
-:102CB00002168190000000040216819400000002B8
-:102CC00002168848080120040216819800000005B9
-:102CD0000216819C00000005021681A0000000057C
-:102CE000021681A4000000050216881420081001B5
-:102CF000021681A800000008021681AC0000000640
-:102D0000021681B000000007021681B40000000125
-:102D10000216881801010120021681B80000000186
-:102D2000021681BC00000001021681C000000001F3
-:102D3000021681C4000000010216881C0101010175
-:102D4000021681C800000001021681CC00000001BB
-:102D5000021681D000000001021681D4000000019B
-:102D60000216882001010101021681D8000000012D
-:102D7000021681DC00000001021681E00000000163
-:102D8000021681E4000000010216882401010101FD
-:102D9000021681E800000001021681EC000000012B
-:102DA000021681F0000000010216882801010101CD
-:102DB00002168240FFFF003F061682440000000218
-:102DC0000216824CFFFF003F0216825000000100F5
-:102DD000021682540000010006168258000000020C
-:102DE00002168260000000C002168264000000C06B
-:102DF0000216826800001E000216826C00001E008F
-:102E0000021682700000400002168274000040002A
-:102E100002168278000080000216827C000080008A
-:102E2000021682800000200002168284000020002A
-:102E30000616828800000007021682A40000000126
-:102E4000061682A80000000A021681F400000C0891
-:102E5000021681F800000040021681FC000001000B
-:102E600002168200000000200216820400000017F3
-:102E700002168208000000800216820C0000020088
-:102E8000021682100000000002168218FFFF01FFE8
-:102E900002168214FFFF01FF0216823C000000139D
-:102EA000021680900000013F021680600000014081
-:102EB00002168064000001400616806800000002CF
-:102EC00002168070000000C0061680740000000723
-:102ED0000216809C00000048021680A000000048F6
-:102EE000061680A400000002021680AC0000004814
-:102EF000061680B00000000702168238000080002D
-:102F000002168234000025E40216809400007FFF40
-:102F100002168220000000070216821C0000000733
-:102F2000021682280000000002168224FFFFFFFF25
-:102F300002168230000000000216822CFFFFFFFF05
-:102F4000021680EC000000FF0214000000000001E7
-:102F50000214000C000000010214004000000001F7
-:102F60000214004400007FFF0214000C0000000067
-:102F700002140000000000000214006C00000000B9
-:102F800002140004000000010214003000000001DF
-:102F900002140004000000000214005C00000000A5
-:102FA00002140008000000010214003400000001B7
-:102FB000021400080000000002140060000000007D
-:102FC00006028000000020000202005800000032CB
-:102FD000020200A003150020020200A40315002035
-:102FE000020200A801000030020200AC081000003C
-:102FF000020200B000000033020200B40000003002
-:10300000020200B800000031020200BC0000000310
-:10301000020200C000000006020200C4000000031B
-:10302000020200C800000003020200CC00000002FF
-:10303000020200D000000000020200D400000002E2
-:10304000020200DC00000000020200E000000006B6
-:10305000020200E400000004020200E80000000296
-:10306000020200EC00000002020200F00000000179
-:10307000020200FC00000006020201200000000025
-:103080000202013400000002020201B0000000014F
-:103090000202020C00000001020202140000000102
-:1030A00002020218000000020202040400000001F3
-:1030B0000202040C00000040020204100000004064
-:1030C0000202041C00000004020204200000002090
-:1030D0000202042400000002020204280000001F73
-:1030E00006020500000000120402048000200434DF
-:1030F000020200600000000F0202006400000007EE
-:1031000002020068000000000202006C0000000ED5
-:103110000602007000000004020200F40000000437
-:103120000202000400000001020200080000000189
-:103130000202000C00000001020200100000000169
-:103140000202001400000001020200180000000149
-:103150000202001C00000001020200200000000129
-:103160000202002400000001020200280000000109
-:103170000202002C000000010202003000000001E9
-:1031800002020034000000010202003800000001C9
-:103190000202003C000000010202004000000001A9
-:1031A0000202004400000001020200480000000189
-:1031B0000202004C00000001020200500000000169
-:1031C00002020108000000C802020118000000020B
-:1031D000020201C400000000020201CC0000000055
-:1031E000020201D400000002020201DC0000000221
-:1031F000020201E4000000FF020201EC000000FFF7
-:103200000202010C000000C80202011C00000002C2
-:10321000020201C800000000020201D0000000000C
-:10322000020201D800000002020201E000000002D8
-:10323000020201E8000000FF020201F0000000FFAE
-:1032400007280400008E00000828076800130454B3
-:10325000072C000033C80000072C800038050CF351
-:10326000072D000038B61AF5072D800007762923B0
-:10327000082D8CB04E6A04560128000000000000A2
-:1032800001280004000000000128000800000000E0
-:103290000128000C000000000128001000000000C0
-:1032A0000128001400000000022800200000000196
-:1032B0000228002400000002022800280000000369
-:1032C0000228002C0000000002280030000000044A
-:1032D000022800340000000102280038000000002D
-:1032E0000228003C00000001022800400000000409
-:1032F00002280044000000000228004800000001ED
-:103300000228004C000000030228005000000000CA
-:1033100002280054000000010228005800000004A8
-:103320000228005C0000000002280060000000018C
-:10333000022800640000000302280068000000006A
-:103340000228006C00000001022800700000000448
-:103350000228007400000000022800780000000429
-:103360000228007C00000003062800800000000204
-:10337000022800A400003FFF022800A8000003FF6D
-:10338000022802240000000002280234000000008D
-:103390000228024C00000000022802E40000FFFFA7
-:1033A0000628200000000800022B8BC0000000014E
-:1033B000022B800000000000022B8040000000185B
-:1033C000022B80800000000C022B80C000000066F1
-:1033D0000C2B83000007A1200A2B8300000001387A
-:1033E0000B2B8300000013880A2B83400000000091
-:1033F0000C2B8340000001F40B2B834000000005E0
-:10340000022B83800007A120022B83C0000001F45F
-:10341000062A3D4800000004042A3D5800020458D2
-:10342000062A3D6000000006062A30000000004821
-:10343000062A2008000000C8062A2000000000021A
-:10344000062A31280000008E062A33680000000397
-:10345000042A33740001045A062A3A780000000254
-:10346000042A3A800002045B042A3A700002045DD8
-:10347000042A3E280002045F042A3EB000040461CE
-:10348000042A250000020465062A25080000010020
-:10349000062A297000000004042A29600004046739
-:1034A000042A2F480002046B062A3378000000D853
-:1034B000022A3A3800000000062A3A88000000324A
-:1034C000042A3D880010046D062A502000000002E6
-:1034D000062A503000000002062A500000000002B8
-:1034E000062A501000000002022A50B80000000115
-:1034F000062A50480000000E042A3D780002047D90
-:10350000062A3C1800000026022A50400000000055
-:10351000062A36D8000000D8022A3A3C00000000F3
-:10352000062A3B5000000032042A3DC80010047FE8
-:10353000062A502800000002062A50380000000227
-:10354000062A500800000002062A50180000000257
-:10355000022A50BC00000001062A50800000000E24
-:10356000042A3D800002048F062A3CB00000002699
-:10357000022A504400000000021010080000000160
-:103580000210101000000264021010000003D000AE
-:10359000021010040000003D091018000200049100
-:1035A00009101100001006910610114000000008DB
-:1035B00009101160000806A1061011800000000229
-:1035C00009101188000606A9061011A000000018B5
-:1035D000021010100000000006102400000000E09F
-:1035E0000210201C0000000002102020000000013A
-:1035F000021020C0000000010210200400000001A1
-:10360000021020080000000109103C00000506AF70
-:1036100009103C20000506B409103800000506B961
-:1036200002104028000000100210404400003FFF3C
-:103630000210405800280000021040840084924A82
-:1036400006104C000000010002104058000000006D
-:103650000610806800000004021080000000108046
-:1036600006108028000000020210803800000010C0
-:10367000021080400000FFFF021080440000FFFFA6
-:1036800002108050000000000210810000000000C5
-:10369000061081200000000202108008000002B520
-:1036A0000210801000000000061082000000004A96
-:1036B000021081080001FFFF061081400000000297
-:1036C0000210800000001A80061090000000002404
-:1036D000061091200000004A061093700000004A76
-:1036E000061095C00000004A0210800400001080FF
-:1036F00006108030000000020210803C0000001024
-:10370000021080480000FFFF0210804C0000FFFF05
-:10371000021080540000000002108104000000002C
-:1037200006108128000000020210800C000002B583
-:103730000210801400000000061084000000004AFF
-:103740000210810C0001FFFF0610814800000002FA
-:103750000210800400001A800610909000000024DF
-:10376000061092480000004A061094980000004A93
-:10377000061096E80000004A0212049000E383401D
-:103780000212051400003C10021205200000000285
-:1037900002120494FFFFFFFF02120498FFFFFFFFD5
-:1037A0000212049CFFFFFFFF021204A0FFFFFFFFB5
-:1037B000021204A4FFFFFFFF021204A8FFFFFFFF95
-:1037C000021204ACFFFFFFFF021204B0FFFFFFFF75
-:1037D000021204B8FFFFFFFF021204BCFFFFFFFF4D
-:1037E000021204C0FFFFFFFF021204C4FFFFFFFF2D
-:1037F000021204C8FFFFFFFF021204CCFFFFFFFF0D
-:10380000021204D0FFFFFFFF021204DCFFFFFFFFE4
-:10381000021204E0FFFFFFFF021204E4FFFFFFFFBC
-:10382000021204E8FFFFFFFF021204ECFFFFFFFF9C
-:10383000021204F0FFFFFFFF021204F4FFFFFFFF7C
-:10384000021204F8FFFFFFFF021204FCFFFFFFFF5C
-:1038500002120500FFFFFFFF02120504FFFFFFFF3A
-:1038600002120508FFFFFFFF0212050CFFFFFFFF1A
-:1038700002120510FFFFFFFF021204D4FFFF3330D6
-:10388000021204D8FFFF3340021204B4F0003000EB
-:1038900002120390000000080212039C00000008BE
-:1038A000061203A000000002021203BC0000000484
-:1038B000021203C400000004021203D00000000042
-:1038C000021203DC000000000212036C0000000181
-:1038D000021203680000003F021201BC0000004019
-:1038E000021201C000001808021201C400000803FF
-:1038F000021201C800000803021201CC00000040BF
-:10390000021201D000000003021201D400000803DB
-:10391000021201D800000803021201DC00000803B3
-:10392000021201E000010003021201E4000008039A
-:10393000021201E800000803021201EC000000037B
-:10394000021201F000000003021201F40000000363
-:10395000021201F800000003021201FC0000000343
-:103960000212020000000003021202040000000321
-:1039700002120208000000030212020C0000000301
-:1039800002120210000000030212021400000003E1
-:1039900002120218000000030212021C00000003C1
-:1039A00002120220000000030212022400000003A1
-:1039B00002120228000024030212022C0000002F31
-:1039C0000212023000000009021202340000001945
-:1039D00002120238000001840212023C000001833E
-:1039E0000212024000000306021202440000001905
-:1039F00002120248000000060212024C00000306F8
-:103A000002120250000003060212025400000306D4
-:103A10000212025800000C860212025C000003062B
-:103A20000212026000000306021202640000000697
-:103A300002120268000000060212026C000000067A
-:103A4000021202700000000602120274000000065A
-:103A500002120278000000060212027C000000063A
-:103A6000021202800000000602120284000000061A
-:103A700002120288000000060212028C00000006FA
-:103A800002120290000000060212029400000006DA
-:103A900002120298000000060212029C00000006BA
-:103AA000021202A000000306021202A4000000138A
-:103AB000021202A800000006021202B00000100468
-:103AC000021202B400001004021203240010644029
-:103AD0000212032800106440021201B0000000012D
-:103AE0000600A000000000160200A06CBF5C0000F1
-:103AF0000200A070FFF51FEF0200A0740000FFFF9E
-:103B00000200A078F00003E00200A07C00000000AA
-:103B10000200A0800000A0000600A08400000005B4
-:103B20000200A0980FE000000600A09C0000001416
-:103B30000200A0EC555400000200A0F05555555568
-:103B40000200A0F4000055550200A0F8F0000000AB
-:103B50000200A0FC555400000200A1005555555527
-:103B60000200A104000055550200A108F000000069
-:103B70000600A22C000000040200A0600000030761
-:103B80000200A10CBF5C00000200A110FFF51FEFB6
-:103B90000200A1140000FFFF0200A118F00003E0E2
-:103BA0000200A11C000000000200A1200000A000F3
-:103BB0000600A124000000050200A1380FE000006B
-:103BC0000600A13C000000140200A18C5554000026
-:103BD0000200A190555555550200A194000055557D
-:103BE0000200A198F00000000200A19C55540000C2
-:103BF0000200A1A0555555550200A1A4000055553D
-:103C00000200A1A8F00000000600A23C0000000491
-:103C10000200A06400000307000000000000000094
-:103C20000000002E00000000000000000000000066
-:103C30000000000000000000000000000000000084
-:103C40000000000000000000000000000000000074
-:103C50000000000000000000000000000000000064
-:103C60000000000000000000000000000000000054
-:103C70000000000000000000002E004D00000000C9
-:103C80000000000000000000000000000000000034
-:103C90000000000000000000000000000000000024
-:103CA00000000000004D008B00000000000000003C
-:103CB0000000000000000000000000000000000004
-:103CC00000000000000000000000000000000000F4
-:103CD000008B009000900094009400980000000079
-:103CE00000000000000000000000000000000000D4
-:103CF000000000000000000000000000009802DE4C
-:103D000002DE02E802E802F200000000000000000B
-:103D100000000000000000000000000000000000A3
-:103D20000000000000000000000000000000000093
-:103D30000000000000000000000000000000000083
-:103D40000000000000000000000000000000000073
-:103D50000000000000000000000000000000000063
-:103D60000000000000000000000000000000000053
-:103D70000000000000000000000000000000000043
-:103D80000000000000000000000000000000000033
-:103D90000000000000000000000000000000000023
-:103DA0000000000000000000000000000000000013
-:103DB0000000000000000000000000000000000003
-:103DC00000000000000000000000000000000000F3
-:103DD000000000000000000002F202FA00000000F3
-:103DE00000000000000000000000000000000000D3
-:103DF00000000000000000000000000000000000C3
-:103E000000000000000000000000000000000000B2
-:103E100000000000000000000000000000000000A2
-:103E20000000000000000000000000000000000092
-:103E300002FA02FF02FF030A030A03150000000052
-:103E40000000000000000000000000000000000072
-:103E50000000000000000000000000000000000062
-:103E60000000000000000000000000000000000052
-:103E70000000000000000000000000000000000042
-:103E80000000000000000000031503160000000001
-:103E90000000000000000000000000000000000022
-:103EA0000000000000000000000000000000000012
-:103EB000000000000316035700000000000000008F
-:103EC00000000000000000000000000000000000F2
-:103ED00000000000000000000000000000000000E2
-:103EE0000357037B000000000000000000000000FA
-:103EF00000000000000000000000000000000000C2
-:103F0000000000000000000000000000037B03BB75
-:103F100000000000000000000000000000000000A1
-:103F20000000000000000000000000000000000091
-:103F3000000000000000000003BB03F700000000C9
-:103F40000000000000000000000000000000000071
-:103F50000000000000000000000000000000000061
-:103F60000000000003F7043D043D045204520467BE
-:103F70000000000000000000000000000000000041
-:103F80000000000000000000000000000000000031
-:103F9000046704ED04ED04F204F204F700000000ED
-:103FA0000000000000000000000000000000000011
-:103FB00000000000000000000000000004F704F80A
-:103FC00000000000000000000000000000000000F1
-:103FD00000000000000000000000000000000000E1
-:103FE000000000000000000004F8050A00000000C6
-:103FF00000000000000000000000000000000000C1
-:1040000000000000000000000000000000000000B0
-:1040100000000000050A051F051F052205220525D1
-:104020000000000000000000000000000000000090
-:104030000000000000000000000000000000000080
-:1040400005250555000000000000000000000000EC
-:104050000000000000000000000000000000000060
-:10406000000000000000000000000000055505DC15
-:104070000000000000000000000000000000000040
-:104080000000000000000000000000000000000030
-:10409000000000000000000005DC05E305E305E783
-:1040A00005E705EB00000000000000000000000034
-:1040B0000000000000000000000000000000000000
-:1040C0000000000005EB062B062B06330633063BEB
-:1040D00000000000000000000000000000000000E0
-:1040E00000000000000000000000000000000000D0
-:1040F000063B068806880695069506A20000000085
-:1041000000000000000000000000000000000000AF
-:1041100000000000000000000000000006A206AE43
-:10412000000000000000000000000000000000008F
-:10413000000000000000000000000000000000007F
-:10414000000000000000000006AE06B40000000001
-:10415000000000000000000000000000000000005F
-:10416000000000000000000000000000000000004F
-:104170000000000006B406B70000000000000000C8
-:10418000000000000000000000000000000000002F
-:10419000000000000000000000000000000000001F
-:1041A00006B706BD0000000000000000000000008F
-:1041B00000000000000000000000000000000000FF
-:1041C00000000000000000000000000006BD06BE68
-:1041D00006BE06D006D006E2000000000000000087
-:1041E00000000000000000000000000000000000CF
-:1041F000000000000000000006E2074F0000000081
-:1042000000000000000000000000000000000000AE
-:10421000000000000000000000000000000000009E
-:1042200000000000074F0750075007630763077639
-:10423000000000000000000000000000000000007E
-:10424000000000000000000000000000000000006E
-:10425000000000000000000000000000000000005E
-:10426000000000000000000000000000000000004E
-:10427000000000000000000000000000000000003E
-:10428000000000000000000000000000000000002E
-:10429000000000000000000000000000000000001E
-:1042A000000000000000000000000000000000000E
-:1042B00000000000000000000000000000000000FE
-:1042C00000000000000000000000000000000000EE
-:1042D00000000000000000000000000000000000DE
-:1042E00000000000000000000000000000000000CE
-:1042F00000000000000000000000000000000000BE
-:1043000000000000000000000000000000000000AD
-:10431000000000000000000000000000000000009D
-:10432000000000000000000000000000000000008D
-:1043300000010000000204C00003098000040E40D8
-:1043400000051300000617C000071C80000821406C
-:1043500000092600000A2AC0000B2F80000C344000
-:10436000000D3900000E3DC0000F42800010474094
-:1043700000114C00001250C00013558000145A4028
-:1043800000155F00001663C00017688000186D40BC
-:1043900000197200001A76C0001B7B80001C804050
-:1043A000001D8500001E89C0001F8E800000934004
-:1043B00000002000000040000000600000008000BD
-:1043C0000000A0000000C0000000E00000010000AC
-:1043D0000001200000014000000160000001800099
-:1043E0000001A0000001C0000001E0000002000088
-:1043F0000002200000024000000260000002800075
-:104400000002A0000002C0000002E0000003000063
-:104410000003200000034000000360000003800050
-:104420000003A0000003C0000003E000000400003F
-:10443000000420000004400000046000000480002C
-:104440000004A0000004C0000004E000000500001B
-:104450000005200000054000000560000005800008
-:104460000005A0000005C0000005E00000060000F7
-:1044700000062000000640000006600000068000E4
-:104480000006A0000006C0000006E00000070000D3
-:1044900000072000000740000007600000078000C0
-:1044A0000007A0000007C0000007E00000080000AF
-:1044B000000820000008400000086000000880009C
-:1044C0000008A0000008C0000008E000000900008B
-:1044D0000009200000094000000960000009800078
-:1044E0000009A0000009C0000009E000000A000067
-:1044F000000A2000000A4000000A6000000A800054
-:10450000000AA000000AC000000AE000000B000042
-:10451000000B2000000B4000000B6000000B80002F
-:10452000000BA000000BC000000BE000000C00001E
-:10453000000C2000000C4000000C6000000C80000B
-:10454000000CA000000CC000000CE000000D0000FA
-:10455000000D2000000D4000000D6000000D8000E7
-:10456000000DA000000DC000000DE000000E0000D6
-:10457000000E2000000E4000000E6000000E8000C3
-:10458000000EA000000EC000000EE000000F0000B2
-:10459000000F2000000F4000000F6000000F80009F
-:1045A000000FA000000FC000000FE000001000008E
-:1045B000001020000010400000106000001080007B
-:1045C0000010A0000010C0000010E000001100006A
-:1045D0000011200000114000001160000011800057
-:1045E0000011A0000011C0000011E0000012000046
-:1045F0000012200000124000001260000012800033
-:104600000012A0000012C0000012E0000013000021
-:10461000001320000013400000136000001380000E
-:104620000013A0000013C0000013E00000140000FD
-:1046300000142000001440000014600000148000EA
-:104640000014A0000014C0000014E00000150000D9
-:1046500000152000001540000015600000158000C6
-:104660000015A0000015C0000015E00000160000B5
-:1046700000162000001640000016600000168000A2
-:104680000016A0000016C0000016E0000017000091
-:10469000001720000017400000176000001780007E
-:1046A0000017A0000017C0000017E000001800006D
-:1046B000001820000018400000186000001880005A
-:1046C0000018A0000018C0000018E0000019000049
-:1046D0000019200000194000001960000019800036
-:1046E0000019A0000019C0000019E000001A000025
-:1046F000001A2000001A4000001A6000001A800012
-:10470000001AA000001AC000001AE000001B000000
-:10471000001B2000001B4000001B6000001B8000ED
-:10472000001BA000001BC000001BE000001C0000DC
-:10473000001C2000001C4000001C6000001C8000C9
-:10474000001CA000001CC000001CE000001D0000B8
-:10475000001D2000001D4000001D6000001D8000A5
-:10476000001DA000001DC000001DE000001E000094
-:10477000001E2000001E4000001E6000001E800081
-:10478000001EA000001EC000001EE000001F000070
-:10479000001F2000001F4000001F6000001F80005D
-:1047A000001FA000001FC000001FE000002000004C
-:1047B0000020200000204000002060000020800039
-:1047C0000020A0000020C0000020E0000021000028
-:1047D0000021200000214000002160000021800015
-:1047E0000021A0000021C0000021E0000022000004
-:1047F00000222000002240000022600000228000F1
-:104800000022A0000022C0000022E00000230000DF
-:1048100000232000002340000023600000238000CC
-:104820000023A0000023C0000023E00000240000BB
-:1048300000242000002440000024600000248000A8
-:104840000024A0000024C0000024E0000025000097
-:104850000025200000254000002560000025800084
-:104860000025A0000025C0000025E0000026000073
-:104870000026200000264000002660000026800060
-:104880000026A0000026C0000026E000002700004F
-:10489000002720000027400000276000002780003C
-:1048A0000027A0000027C0000027E000002800002B
-:1048B0000028200000284000002860000028800018
-:1048C0000028A0000028C0000028E0000029000007
-:1048D00000292000002940000029600000298000F4
-:1048E0000029A0000029C0000029E000002A0000E3
-:1048F000002A2000002A4000002A6000002A8000D0
-:10490000002AA000002AC000002AE000002B0000BE
-:10491000002B2000002B4000002B6000002B8000AB
-:10492000002BA000002BC000002BE000002C00009A
-:10493000002C2000002C4000002C6000002C800087
-:10494000002CA000002CC000002CE000002D000076
-:10495000002D2000002D4000002D6000002D800063
-:10496000002DA000002DC000002DE000002E000052
-:10497000002E2000002E4000002E6000002E80003F
-:10498000002EA000002EC000002EE000002F00002E
-:10499000002F2000002F4000002F6000002F80001B
-:1049A000002FA000002FC000002FE000003000000A
-:1049B00000302000003040000030600000308000F7
-:1049C0000030A0000030C0000030E00000310000E6
-:1049D00000312000003140000031600000318000D3
-:1049E0000031A0000031C0000031E00000320000C2
-:1049F00000322000003240000032600000328000AF
-:104A00000032A0000032C0000032E000003300009D
-:104A1000003320000033400000336000003380008A
-:104A20000033A0000033C0000033E0000034000079
-:104A30000034200000344000003460000034800066
-:104A40000034A0000034C0000034E0000035000055
-:104A50000035200000354000003560000035800042
-:104A60000035A0000035C0000035E0000036000031
-:104A7000003620000036400000366000003680001E
-:104A80000036A0000036C0000036E000003700000D
-:104A900000372000003740000037600000378000FA
-:104AA0000037A0000037C0000037E00000380000E9
-:104AB00000382000003840000038600000388000D6
-:104AC0000038A0000038C0000038E00000390000C5
-:104AD00000392000003940000039600000398000B2
-:104AE0000039A0000039C0000039E000003A0000A1
-:104AF000003A2000003A4000003A6000003A80008E
-:104B0000003AA000003AC000003AE000003B00007C
-:104B1000003B2000003B4000003B6000003B800069
-:104B2000003BA000003BC000003BE000003C000058
-:104B3000003C2000003C4000003C6000003C800045
-:104B4000003CA000003CC000003CE000003D000034
-:104B5000003D2000003D4000003D6000003D800021
-:104B6000003DA000003DC000003DE000003E000010
-:104B7000003E2000003E4000003E6000003E8000FD
-:104B8000003EA000003EC000003EE000003F0000EC
-:104B9000003F2000003F4000003F6000003F8000D9
-:104BA000003FA000003FC000003FE000003FE001E8
-:104BB00000000000000001FF0000020000007FF87C
-:104BC00000007FF80000016A0000150000000001ED
-:104BD0000000FF00000000000000FF0000000000D7
-:104BE00000000000140AFF000000000100000000A7
-:104BF00000201001000000000100860000000100FC
-:104C00000000860200008604000086060000860878
-:104C10000000860A0000860C0000860E0000861048
-:104C20000000861200008614000086160000861818
-:104C30000000861A0000861C0000861E00008620E8
-:104C400000008622000086240000862600008628B8
-:104C50000000862A0000862C0000862E0000863088
-:104C60000000863200008634000086360000863858
-:104C70000000863A0000863C0000863E0000864028
-:104C800000008642000086440000864600008648F8
-:104C90000000864A0000864C0000864E00008650C8
-:104CA0000000865200008654000086560000865898
-:104CB0000000865A0000865C0000865E0000866068
-:104CC0000000866200008664000086660000866838
-:104CD0000000866A0000866C0000866E0000867008
-:104CE00000008672000086740000867600008678D8
-:104CF0000000867A0000867C0000867E00008680A8
-:104D00000000868200008684000086860000868877
-:104D10000000868A0000868C0000868E0000869047
-:104D20000000869200008694000086960000869817
-:104D30000000869A0000869C0000869E000086A0E7
-:104D4000000086A2000086A4000086A6000086A8B7
-:104D5000000086AA000086AC000086AE000086B087
-:104D6000000086B2000086B4000086B6000086B857
-:104D7000000086BA000086BC000086BE000086C027
-:104D8000000086C2000086C4000086C6000086C8F7
-:104D9000000086CA000086CC000086CE000086D0C7
-:104DA000000086D2000086D4000086D6000086D897
-:104DB000000086DA000086DC000086DE000086E067
-:104DC000000086E2000086E4000086E6000086E837
-:104DD000000086EA000086EC000086EE000086F007
-:104DE000000086F2000086F4000086F6000086F8D7
-:104DF000000086FA000086FC000086FE00008700A6
-:104E00000000870200008704000087060000870872
-:104E10000000870A0000870C0000870E0000871042
-:104E20000000871200008714000087160000871812
-:104E30000000871A0000871C0000871E00008720E2
-:104E400000008722000087240000872600008728B2
-:104E50000000872A0000872C0000872E0000873082
-:104E60000000873200008734000087360000873852
-:104E70000000873A0000873C0000873E0000874022
-:104E800000008742000087440000874600008748F2
-:104E90000000874A0000874C0000874E00008750C2
-:104EA0000000875200008754000087560000875892
-:104EB0000000875A0000875C0000875E0000876062
-:104EC0000000876200008764000087660000876832
-:104ED0000000876A0000876C0000876E0000877002
-:104EE00000008772000087740000877600008778D2
-:104EF0000000877A0000877C0000877E00008780A2
-:104F00000000878200008784000087860000878871
-:104F10000000878A0000878C0000878E0000879041
-:104F20000000879200008794000087960000879811
-:104F30000000879A0000879C0000879E000087A0E1
-:104F4000000087A2000087A4000087A6000087A8B1
-:104F5000000087AA000087AC000087AE000087B081
-:104F6000000087B2000087B4000087B6000087B851
-:104F7000000087BA000087BC000087BE000087C021
-:104F8000000087C2000087C4000087C6000087C8F1
-:104F9000000087CA000087CC000087CE000087D0C1
-:104FA000000087D2000087D4000087D6000087D891
-:104FB000000087DA000087DC000087DE000087E061
-:104FC000000087E2000087E4000087E6000087E831
-:104FD000000087EA000087EC000087EE000087F001
-:104FE000000087F2000087F4000087F6000087F8D1
-:104FF000000087FA000087FC000087FEFFFFFFFF2C
-:10500000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0
-:10501000FFFFFFFFFFFFFFFFFFFFFFFF0000000399
-:1050200000BEBC20000000000000000500000003DE
-:1050300000BEBC20000000000000000500002000B1
-:10504000000040C000006180000082400000A3001A
-:105050000000C3C00000E4800001054000012600FC
-:10506000000146C000016780000188400001A900DE
-:105070000001C9C00001EA8000020B4000022C00C0
-:1050800000024CC000026D8000028E400002AF00A2
-:105090000002CFC00002F08000001140000080003C
-:1050A000000103800001870000020A8000028E00D8
-:1050B00000031180000395000004188000049C0088
-:1050C00000051F800005A300000626800006AA0038
-:1050D00000072D800007B100000834800008B800E8
-:1050E00000093B800009BF00000A4280000AC60098
-:1050F000000B4980000BCD00000C5080000CD40048
-:10510000000D578000005B0000007FF800007FF872
-:1051100000000166000015000000FF000000000014
-:105120000000FF0000000000000019000000000067
-:1051300000000000FFFFFFFF00007FF800007FF885
-:1051400000000361000015000000FF000FFFFFFFDB
-:105150000000FF000FFFFFFF000000FF0000FF0046
-:105160000FFFFFFF0000FF000FFFFFFF000000FF29
-:105170000000FF000FFFFFFF0000FF000FFFFFFF19
-:10518000000000FF0000FF000FFFFFFF0000FF0016
-:105190000FFFFFFF000000FF0000FF000FFFFFFFF9
-:1051A0000000FF000FFFFFFF000000FF0000FF00F6
-:1051B0000FFFFFFF0000FF000FFFFFFF000000FFD9
-:1051C0000000FF000FFFFFFF0000FF000FFFFFFFC9
-:1051D000000000FF0000FF000FFFFFFF0000FF00C6
-:1051E0000FFFFFFF000000FF0000FF000FFFFFFFA9
-:1051F0000000FF000FFFFFFF000000FF0000FF00A6
-:105200000FFFFFFF0000FF000FFFFFFF000000FF88
-:105210000000FF000FFFFFFF0000FF000FFFFFFF78
-:10522000000000FF0000FF000FFFFFFF0000FF0075
-:105230000FFFFFFF000000FF0000FF000FFFFFFF58
-:105240000000FF000FFFFFFF000000FF0000FF0055
-:105250000FFFFFFF0000FF000FFFFFFF000000FF38
-:105260000000FF000FFFFFFF0000FF000FFFFFFF28
-:10527000000000FF0000FF000FFFFFFF0000FF0025
-:105280000FFFFFFF000000FF0000FF000FFFFFFF08
-:105290000000FF000FFFFFFF000000FF0000FF0005
-:1052A0000FFFFFFF0000FF000FFFFFFF000000FFE8
-:1052B0000000FF000FFFFFFF0000FF000FFFFFFFD8
-:1052C000000000FF0000FF000FFFFFFF0000FF00D5
-:1052D0000FFFFFFF000000FF0000FF000FFFFFFFB8
-:1052E0000000FF000FFFFFFF000000FF0000FF00B5
-:1052F0000FFFFFFF0000FF000FFFFFFF000000FF98
-:105300000000FF000FFFFFFF0000FF000FFFFFFF87
-:10531000000000FF0000FF000FFFFFFF0000FF0084
-:105320000FFFFFFF000000FF0000FF000FFFFFFF67
-:105330000000FF000FFFFFFF000000FF0000FF0064
-:105340000FFFFFFF0000FF000FFFFFFF000000FF47
-:105350000000FF000FFFFFFF0000FF000FFFFFFF37
-:10536000000000FF0000FF000FFFFFFF0000FF0034
-:105370000FFFFFFF000000FF0000FF000FFFFFFF17
-:105380000000FF000FFFFFFF000000FF0000FF0014
-:105390000FFFFFFF0000FF000FFFFFFF000000FFF7
-:1053A0000000FF000FFFFFFF0000FF000FFFFFFFE7
-:1053B000000000FF0000FF000FFFFFFF0000FF00E4
-:1053C0000FFFFFFF000000FF000000FF000000FFD4
-:1053D0000000FF00000000000000FF0000000000CF
-:1053E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD
-:1053F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD
-:1054000000001000000020800000310000004180FA
-:1054100000005200000062800000730000008380E2
-:10542000000094000000A4800000B5000000C580CA
-:105430000000D6000000E6800000F70000010780B1
-:105440000001180000012880000139000001498096
-:1054500000015A0000016A8000017B0000018B807E
-:1054600000019C000001AC800001BD000001CD8066
-:105470000001DE000001EE8000000F0000000000CF
-:1054800000007FF800007FF80000021D00001500FA
-:1054900010000000000028AD00010001FFFFFFFF29
-:1054A000FFFFFFFF00090206CCCCCCC17058103CB6
-:1054B000000000000000FF00000000000000FF00EE
-:1054C000000000000000000000000001CCCC020140
-:1054D000CCCCCCCCCCCC0201CCCCCCCC00000000D1
-:1054E000FFFFFFFF0000FFFF000000000000FFFFC4
-:1054F000000000000000FFFF000000000000FFFFB0
-:10550000000000000000FFFF000000000000FFFF9F
-:10551000000000000000FFFF000000000000FFFF8F
-:1055200000000000000E0000011600D60000FFFF82
-:10553000000000000000FFFF000000000000FFFF6F
-:10554000000000000000FFFF000000000000FFFF5F
-:10555000000000000000FFFF000000000000FFFF4F
-:10556000000000000000FFFF0000000000720000CB
-:10557000012300F3FFFFFFF3318FFFFF0C30C30C5B
-:10558000C30C30C3CF3CF300F3CF3CF30000CF3C5F
-:10559000CDCDCDCDFFFFFFF130EFFFFF0C30C30CC1
-:1055A000C30C30C3CF3CF300F3CF3CF30001CF3C3E
-:1055B000CDCDCDCDFFFFFFF6305FFFFF0C30C30C2C
-:1055C000C30C30C3CF3CF300F3CF3CF30002CF3C1D
-:1055D000CDCDCDCDFFFFF4061CBFFFFF0C30C305C2
-:1055E000C30C30C3CF300014F3CF3CF30004CF3CE6
-:1055F000CDCDCDCDFFFFFFF2304FFFFF0C30C30C00
-:10560000C30C30C3CF3CF300F3CF3CF30008CF3CD6
-:10561000CDCDCDCDFFFFFFFA302FFFFF0C30C30CF7
-:10562000C30C30C3CF3CF300F3CF3CF30010CF3CAE
-:10563000CDCDCDCDFFFFFFF731EFFFFF0C30C30C19
-:10564000C30C30C3CF3CF300F3CF3CF30020CF3C7E
-:10565000CDCDCDCDFFFFFFF5302FFFFF0C30C30CBC
-:10566000C30C30C3CF3CF300F3CF3CF30040CF3C3E
-:10567000CDCDCDCDFFFFFFF3318FFFFF0C30C30C3D
-:10568000C30C30C3CF3CF300F3CF3CF30000CF3C5E
-:10569000CDCDCDCDFFFFFFF1310FFFFF0C30C30C9F
-:1056A000C30C30C3CF3CF300F3CF3CF30001CF3C3D
-:1056B000CDCDCDCDFFFFFFF6305FFFFF0C30C30C2B
-:1056C000C30C30C3CF3CF300F3CF3CF30002CF3C1C
-:1056D000CDCDCDCDFFFFF4061CBFFFFF0C30C305C1
-:1056E000C30C30C3CF300014F3CF3CF30004CF3CE5
-:1056F000CDCDCDCDFFFFFFF2304FFFFF0C30C30CFF
-:10570000C30C30C3CF3CF300F3CF3CF30008CF3CD5
-:10571000CDCDCDCDFFFFFFFA302FFFFF0C30C30CF6
-:10572000C30C30C3CF3CF300F3CF3CF30010CF3CAD
-:10573000CDCDCDCDFFFFFFF730EFFFFF0C30C30C19
-:10574000C30C30C3CF3CF300F3CF3CF30020CF3C7D
-:10575000CDCDCDCDFFFFFFF5304FFFFF0C30C30C9B
-:10576000C30C30C3CF3CF300F3CF3CF30040CF3C3D
-:10577000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CF1
-:10578000C30C30C3CF3CF3CCF3CF3CF30000CF3C91
-:10579000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CD1
-:1057A000C30C30C3CF3CF3CCF3CF3CF30001CF3C70
-:1057B000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CB1
-:1057C000C30C30C3CF3CF3CCF3CF3CF30002CF3C4F
-:1057D000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C91
-:1057E000C30C30C3CF3CF3CCF3CF3CF30004CF3C2D
-:1057F000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C71
-:10580000C30C30C3CF3CF3CCF3CF3CF30008CF3C08
-:10581000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C50
-:10582000C30C30C3CF3CF3CCF3CF3CF30010CF3CE0
-:10583000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C30
-:10584000C30C30C3CF3CF3CCF3CF3CF30020CF3CB0
-:10585000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C10
-:10586000C30C30C3CF3CF3CCF3CF3CF30040CF3C70
-:10587000CDCDCDCDFFFFFFF3320FFFFF0C30C30CBA
-:10588000C30C30C3CF3CF300F3CF3CF30000CF3C5C
-:10589000CDCDCDCDFFFFFFF1310FFFFF0C30C30C9D
-:1058A000C30C30C3CF3CF300F3CF3CF30001CF3C3B
-:1058B000CDCDCDCDFFFFFFF6305FFFFF0C30C30C29
-:1058C000C30C30C3CF3CF300F3CF3CF30002CF3C1A
-:1058D000CDCDCDCDFFFFF4061CBFFFFF0C30C305BF
-:1058E000C30C30C3CF300014F3CF3CF30004CF3CE3
-:1058F000CDCDCDCDFFFFFFF2304FFFFF0C30C30CFD
-:10590000C30C30C3CF3CF300F3CF3CF30008CF3CD3
-:10591000CDCDCDCDFFFFFF8A042FFFFF0C30C30C90
-:10592000C30C30C3CF3CC000F3CF3CF30010CF3CDE
-:10593000CDCDCDCDFFFFFF9705CFFFFF0C30C30CC2
-:10594000C30C30C3CF3CC000F3CF3CF30020CF3CAE
-:10595000CDCDCDCDFFFFFFF5310FFFFF0C30C30CD8
-:10596000C30C30C3CF3CF300F3CF3CF30040CF3C3B
-:10597000CDCDCDCDFFFFFFF3300FFFFF0C30C30CBB
-:10598000C30C30C3CF3CF300F3CF3CF30000CF3C5B
-:10599000CDCDCDCDFFFFFFF1300FFFFF0C30C30C9D
-:1059A000C30C30C3CF3CF300F3CF3CF30001CF3C3A
-:1059B000CDCDCDCDFFFFFFF6305FFFFF0C30C30C28
-:1059C000C30C30C3CF3CF300F3CF3CF30002CF3C19
-:1059D000CDCDCDCDFFFFF4061CBFFFFF0C30C305BE
-:1059E000C30C30C3CF300014F3CF3CF30004CF3CE2
-:1059F000CDCDCDCDFFFFFFF2304FFFFF0C30C30CFC
-:105A0000C30C30C3CF3CF300F3CF3CF30008CF3CD2
-:105A1000CDCDCDCDFFFFFFFA302FFFFF0C30C30CF3
-:105A2000C30C30C3CF3CF300F3CF3CF30010CF3CAA
-:105A3000CDCDCDCDFFFFFF97040FFFFF0C30C30C82
-:105A4000C30C30C3CF3CC000F3CF3CF30020CF3CAD
-:105A5000CDCDCDCDFFFFFFF5300FFFFF0C30C30CD8
-:105A6000C30C30C3CF3CF300F3CF3CF30040CF3C3A
-:105A7000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CEE
-:105A8000C30C30C3CF3CF3CCF3CF3CF30000CF3C8E
-:105A9000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CCE
-:105AA000C30C30C3CF3CF3CCF3CF3CF30001CF3C6D
-:105AB000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CAE
-:105AC000C30C30C3CF3CF3CCF3CF3CF30002CF3C4C
-:105AD000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C8E
-:105AE000C30C30C3CF3CF3CCF3CF3CF30004CF3C2A
-:105AF000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C6E
-:105B0000C30C30C3CF3CF3CCF3CF3CF30008CF3C05
-:105B1000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C4D
-:105B2000C30C30C3CF3CF3CCF3CF3CF30010CF3CDD
-:105B3000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C2D
-:105B4000C30C30C3CF3CF3CCF3CF3CF30020CF3CAD
-:105B5000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C0D
-:105B6000C30C30C3CF3CF3CCF3CF3CF30040CF3C6D
-:105B7000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CED
-:105B8000C30C30C3CF3CF3CCF3CF3CF30000CF3C8D
-:105B9000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CCD
-:105BA000C30C30C3CF3CF3CCF3CF3CF30001CF3C6C
-:105BB000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CAD
-:105BC000C30C30C3CF3CF3CCF3CF3CF30002CF3C4B
-:105BD000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C8D
-:105BE000C30C30C3CF3CF3CCF3CF3CF30004CF3C29
-:105BF000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C6D
-:105C0000C30C30C3CF3CF3CCF3CF3CF30008CF3C04
-:105C1000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C4C
-:105C2000C30C30C3CF3CF3CCF3CF3CF30010CF3CDC
-:105C3000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C2C
-:105C4000C30C30C3CF3CF3CCF3CF3CF30020CF3CAC
-:105C5000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C0C
-:105C6000C30C30C3CF3CF3CCF3CF3CF30040CF3C6C
-:105C7000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CEC
-:105C8000C30C30C3CF3CF3CCF3CF3CF30000CF3C8C
-:105C9000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CCC
-:105CA000C30C30C3CF3CF3CCF3CF3CF30001CF3C6B
-:105CB000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CAC
-:105CC000C30C30C3CF3CF3CCF3CF3CF30002CF3C4A
-:105CD000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C8C
-:105CE000C30C30C3CF3CF3CCF3CF3CF30004CF3C28
-:105CF000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C6C
-:105D0000C30C30C3CF3CF3CCF3CF3CF30008CF3C03
-:105D1000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C4B
-:105D2000C30C30C3CF3CF3CCF3CF3CF30010CF3CDB
-:105D3000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C2B
-:105D4000C30C30C3CF3CF3CCF3CF3CF30020CF3CAB
-:105D5000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C0B
-:105D6000C30C30C3CF3CF3CCF3CF3CF30040CF3C6B
-:105D7000CDCDCDCD000C0000000700C00002813069
-:105D8000000B81580002021000010230000F024097
-:105D900000010330000C0000000800C00002814038
-:105DA000000B81680002022000010240000702503F
-:105DB000000202C000100000000801000002818003
-:105DC000000B81A80002026000018280000E829810
-:105DD0000008038000028000000B8028000200E021
-:105DE000000101000000811000000118CCCCCCCCD7
-:105DF000CCCCCCCCCCCCCCCCCCCCCCCC00002000F3
-:105E0000CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCD2
-:105E100000002000CCCCCCCCCCCCCCCCCCCCCCCCD2
-:105E2000CCCCCCCC00002000000000000000000022
-:105E30001F8B080000000000000BFB51CFC0F003D7
-:105E40008ABB5819180238107C7AE0A58C94E9DFD7
-:105E5000C8CCC0B00388AF02F17E66D2F5B34A2346
-:105E6000D8F7241818182419184E893130EC9244A8
-:105E700088E702D5084A3130DC858A0500D967A554
-:105E8000E81B4EA39836F8BB3A2AFF912A84CE87A6
-:105E900089A3C93F86CA6F5480D03FD5B19BBB0947
-:105EA0002A0F00FE694F6760030000000000000039
-:105EB0001F8B080000000000000BED7D0B7854D50F
-:105EC000B9E8DACFD933994C7642422610700703ED
-:105ED000040D30208FA85427E1D1E0E5E8F0462EEC
-:105EE000CA80AF0892448D356D39373B6412020287
-:105EF0008ECAA1B4A53A207AA247DBD4464B7BF5E3
-:105F0000DC206A73DAD37B9152A52DB6413D281669
-:105F100068F49403BDD796BBFE7FAD3DD97B672661
-:105F20000F5FDF395F1B3EDD597BAFBDD6BFFEF78C
-:105F3000FAFF7FEDA8A297A8971072117EAE256494
-:105F40009D4008C9EBBD5AF78916AD26B9845405A2
-:105F500055632B7DB65E0A1B8DD3E8FD4BC4D01371
-:105F600004EE8F9B432611A2C07B05844C85FF4D18
-:105F70002744CE691D1EF5D37BD2AA2CB85AE3590B
-:105F8000D72A99107D2A3CDF362ED5F3E4FC09A5EB
-:105F9000A75B23F873710C21F5C76F9CFF8AD5A608
-:105FA000FF8D2499B9272FA7BFCC24332F4A847C97
-:105FB00054B828ABD3483FDE070D5DBA3C9690F34A
-:105FC0000D2BE6BF32B6EFF3F512A96D2FED7BFF77
-:105FD0002AA2215E8866AA9189BDEB5E4F48A72759
-:105FE0008790CD859BD87A7329B2AEA4F7DBFE45A6
-:105FF000974B7AE15C2FD37E53FBAE871013C7B566
-:10600000C649BE9FE872BCEF7E2F391E7F9FC8F441
-:10601000DF0C42B00B5DFF74217A2DDCF7142E32B9
-:1060200047D0F6FA67CA49B4343DFC497A7D42F854
-:10603000ADF7D2D291F7FB687F530BA1EF9D54E3EC
-:10604000D75F45F9E8BDEF4BA14DC0477BC6CF21D7
-:10605000017A9F303EB2E8746A7FD3F054FC918E8F
-:106060004E7F4FBCC87F167F5589ABB23AC927E730
-:10607000AF3B80BF326CFCD5BEB8DFF13E297FC597
-:10608000DCFCC5F171BA9DAD9FEC1EC6E8C2E9E526
-:10609000A64F5ABA7CD2F7FAF2D316C0ABA77DB19D
-:1060A0003982A4E0270EAF45AF4F0BEF407C444848
-:1060B0001CE94C484482F97BEFB36B469921009F61
-:1060C000D1E6615847904D4582B7B6DC2D52380372
-:1060D00024D13AAE88B6BBD72C00B803C7E79F02DD
-:1060E00079680E5568B3E97AF569C643F3E835A3D4
-:1060F0005417603D5B89084A808E576D969702BDA4
-:1061000008B69F366F099B80071226643821F7F185
-:106110003511221A326DABF0EB9854EB504927C37E
-:106120008770D1D3F7FD74EB577BDF23178BE0FF2C
-:10613000F71058DF40EF91287BCFA4FF00DF39AE86
-:1061400071F439B46DE3FB00B1B5E9F3A3F00BE2F0
-:10615000FBEE2F64BE6CB24F33A87E504B443D0122
-:10616000FD89912DD37646255544F03C480E528A40
-:106170000C489766422ADB811F493B5938B117BE4C
-:106180005344C0F514DCBE734D0B555DE7CAFC21CA
-:10619000E0F3A04EC8B09CBEEBD9D6401979BCAD97
-:1061A0001D7A0EF93F46F9680C7DDF0C317BB8B5DE
-:1061B000E4653D6A93EF0C41E07CE9E60F62C83389
-:1061C00040CC8055E8B5440C7B039F9E3F64171E6E
-:1061D00007CB1FFEA88D3E64E8F40A72BF61B0FCD5
-:1061E000F169E7B3E8DA57AE1A2DBA6A84D2614B87
-:1061F000F1A294FE477ABAEE23D03FA384841329F8
-:10620000DE1B25085C0E4C87BEC12BA58F9424EFA6
-:10621000BD0E7A49F93356ECED071F52AE131FD667
-:10622000B8DE7AC97897AA4422EB228CA7C2789468
-:106230004FB7041F3609958773C0DB141F527C4A81
-:1062400027B44931413EA43F9D026D7B83E1C45692
-:10625000E48304D2C582CF63880EFCCAB93E479B53
-:10626000AC30053BFCDE7A15E150D147A0E3E87481
-:10627000408A0AD94F3A816F2D7E0536B87829B405
-:10628000BFEEE08356632A4945078B5F01AD8C5F03
-:10629000BF3E38FDE29E6F8913DE41BFE7978D93C5
-:1062A000363B94FE3D999CB4E84391580503D8F8D9
-:1062B00060B3420E089309692A5C46A2F4EE667840
-:1062C00044ED580B5C0BC03F9C8A7A81B40932C004
-:1062D00069D95512CCC17ED30503C713B55AD42B47
-:1062E000923FCCEC2B7F9E1E2E36FF70231ED629AC
-:1062F0007EF3493C2C52FA505D19EA24A037C304BE
-:10630000F88084185F48DC4FB7DE8F717EF692A369
-:10631000F83ED5AEA68EF6CC29C77325FA908EB37B
-:10632000A584243C48A7B8066DB94426B02FA0FA2E
-:10633000C95F40FB6759EC2F2D0801FC59DCBE9268
-:10634000599CBF05AACF289EFDD39CF2ED73C9BF0F
-:10635000CCED711F7D96663F615DDDFEDB6302F76C
-:10636000DF32881FE9CDDF27FED4FEAAE5B75978D2
-:10637000CD1309E293FC54493C51C4D746DBF7BC2A
-:10638000959D80759B159135CD140FE6DB42A809CC
-:10639000E829877BB2E8F3934F4AB85FCA5B567F20
-:1063A00009CCB7BDC11C5B6CF307B7CBB51AE09B3A
-:1063B000F28566B7173790E80B826DFFE509B68C5A
-:1063C0002D1E86FCF7767709980A01F9CFEB8F0529
-:1063D0005F05B9E4F793F8B1B7A5BEEDDC7CC2ED7B
-:1063E000E50DE5613A6F2BE8AE11F8D814283CAD05
-:1063F00005ACFD93C6E1E5603F5B3359FBA3C6776F
-:10640000C28DC817512D42EFD5138E972E8A17A42F
-:10641000BF916FB7AFEEAB7BFD3B64DD077CB6D7BA
-:106420009F735D09D8CF32310468DF1B3BA2AFB147
-:10643000E1E39B9E8A37001F2349422040BF582E2C
-:10644000CA8FE5CF01E341BB80CB5321398CFD4698
-:10645000477ACA15B8B5427F19AE2DC1E7B2519E31
-:10646000C81CFD24CABF245CBC7CF0F29E6EBD013A
-:10647000814452F9F3F74B392857816974DD0EBD19
-:106480005EA8233FF271BF063402FD914D619A0C64
-:106490007A24BE229262BC9F0822F6D3C01E5C41C1
-:1064A000D150B8ACECDFE87A352D3CE5550A97279A
-:1064B000D71F32116C66270C2E039E78A306F82591
-:1064C000472502F2AF158623B7019F924858A0F7DF
-:1064D000B56038B4D5E8BB3E9530FB9043AF179913
-:1064E0007C13E87F4F9E8EFD09D80B6B5D63002EF9
-:1064F00015E1FA0CE89D2B4E1F98CE23487B3918E6
-:10650000B374F4FEACE99CEE7D377D030293AFFBE0
-:106510009BCE874D2A4F2DC7055102A5182F46BA8D
-:10652000689C2EE795A8067EE396AF8A641F6D3FB0
-:106530005ADFBF9F12033FC563B39B3AA3DFC8BBBB
-:10654000F4A9C042E9DEDB7597589948C14F9522FE
-:10655000D3FB5BEE7A383E16E8F98A73BFA7AC0A24
-:10656000A35F4AF77D95400FEB3D6F31B34F643F1A
-:106570005D0FEDAF707FE47CDEA22C92621EEBBA61
-:10658000C7057F21C5732AB9B94FE2FED54E36BE85
-:10659000E5EF9C2FE87F7C0B3F172A4572B814C9A2
-:1065A000EA23A57C3114EF8549BF3B0FDB1EFE2893
-:1065B000512BFA08D8BDC2CE72B82AA4A711F8741C
-:1065C0009748AA52C1B7561211BEC230DD7A50BDEB
-:1065D0005F688AA099C8BD9281F7F357D51E5428E9
-:1065E0005D5A47911098994B603CD0AB07BD683F0E
-:1065F000D55C92F0523DFD5AD1574CB0CB7A21096F
-:10660000032C7A2DEC39E97FD4BE1AF4B9B2316A81
-:10661000225CC108EE110E152D437AB750FFCEC390
-:1066200016E2E0A71653EC04BE8DD3F1C11F8C1BFC
-:106630001528AFE782D4F2C3CFC7147E6BBF712990
-:10664000C485282901CE0932C2494762F4D4195EB3
-:1066500046EE9E453AA9DD69CDDE85F2605E495081
-:106660005E6572D814C0CEC80953A4F0C6AA983E7D
-:106670005072E382DD8EED21D107ED7C23EB9DE8A6
-:10668000FFB5FE595A910AAFD522D36FF7717D78C5
-:106690005E699F8FFE4633958FA2BEFDC39C0EDFC1
-:1066A0008E2D7A703CEA336697ACE75D82E18863B1
-:1066B0008EBCA0E27ADC7ECD3CEED7B41452BF068D
-:1066C000E59D2C003F2683F3470B608F3EF76493D4
-:1066D0008449E1C8007F86FA25A494F9251AFD07AC
-:1066E000FA2F7F85D39FF1B8FC9674FECCD784C86F
-:1066F0000F50DF515505F0EF16E2F3C701BE0BE86E
-:106700007ED2E8BBEE2EBE9F9C2B6D2B6AA1703D06
-:10671000962B3AF861349797C78879E2227D1E2F2D
-:10672000140D803B5E2FE23ACE19CC6F27EF7A1D15
-:1067300076A2D95CA4119BFED9C1E5695B83E69082
-:106740005BF7D5AFC6A391147A4BE7F4C99815C689
-:10675000F8873F9440FAC33A53F9E90F945668FD1D
-:10676000E93FB9445D83F82BAC3825C3B5CCBD5F98
-:106770004A3DAEFB4AEC7EA694BEDF60AF5B289E2E
-:10678000DE561CFE78A704FB2E93A0FFE70D5153A5
-:106790001580AB3E1CE0F786A8B8C1B5BBBC12EEB5
-:1067A0001BB3221AC891659FBDA1C856B89FF52595
-:1067B000790BD0CB5B2E8A12A59F269B24C7263748
-:1067C00053E1A68DBF33A9BAB4E3438B7EA512FC77
-:1067D00054522892B1148ECD1F3768763A75D16D18
-:1067E00008DBB73AF9265EDFBF9EFDB47CF173D1BA
-:1067F0008A8738E9853FF67808A77392FE7DE21A0A
-:10680000FF39E8AD71FA19947E9B0CA027D3177459
-:10681000E385FE435C33C3D08E1B8668DAF4D8C7A9
-:10682000620EE241BE20A35EDABDA6250CF4D2E9D9
-:1068300018405A7A0DA7B2DB5D828A7245F5C655BB
-:10684000D27454C802C43FE74A1B91DE8F517A8349
-:106850001E7B8CD4765DCCED957F2DAAA21FDFD553
-:10686000689637160F456F52F8A85F47F630FFE578
-:1068700012CB7FF97BCA2783F057CE53A3C1EDB16A
-:1068800017F84AEEA62C4DE12ADCC8EC26F86A3946
-:10689000B46D50BBD729F4F2A387CFA394260E8FF3
-:1068A000477A3BEDD363852F0B1EB06FC5CCBEA9D5
-:1068B000666718F44CA098DA2782F66735E06744DB
-:1068C00049BC1CDA2377CFC3757C1BFC503FD8171B
-:1068D00082F8F8A698683429CD7CE148A728C1FE43
-:1068E00099E0FECEA29F7B5E6AF5909EBE6C712FF2
-:1068F000D029507B189669B77BD5525EAF3D1C51AD
-:10690000D289EAD6ED2FA4F513FE2CF1FDD8CCC622
-:10691000306D8F825FA93FB9537CBC11F663114F74
-:10692000B81EE9EEDA4724E3503CDEBDB6CC122AAD
-:1069300063F96FE83C7776291400027E80648F0348
-:10694000DD097689EA9BB5DCAEDD4A2201787886DE
-:1069500088185F3B438E04AEB0F1E14E4965F3B455
-:106960002A6F43FCDE8AEFDE16676D4BFFDCB1DB7E
-:10697000D9BE9D2C1A0EF1DBDB772AB8FE3B5DFBFE
-:10698000D698A4E3B87790DA16C043B342D04F58F4
-:10699000AB1319E2B11B7EF89D19B04FF836B72B37
-:1069A0001F50FE326CFA679D3FA1C27EF69D8E2B72
-:1069B000965D4DE0FD44CB08D89767939476F496A6
-:1069C00056277C03C1EF8697904DFDC221B7092958
-:1069D000E3874F4982236E58AF052641D0E4BC9728
-:1069E0005DCD0AA63FCCDF7A134DE0274A06EF5F64
-:1069F0003B99E5396A67C275A0F77EC6FDD1A1BE95
-:106A00007738CD7B1BB46E15F8BF46362B05B137F2
-:106A10005EA529B5E19120C707CA3B471247BFD6FB
-:106A200041F6AB14FBE9E786F794AE99E2E4BE7059
-:106A3000DF40A26F81DC9D17A3D51827E0707B0093
-:106A4000CF125C65A427C64F8A605E7FAB9005714C
-:106A5000940EF44FBC86ECA0778DA507A85E82B893
-:106A60004F4689F3B93BAED293A46B27CA1786442D
-:106A7000E992029ABF53027FB14C3E9DEC4FE7ABC7
-:106A800086754DC64EA85FEAB87EA926C683B3A612
-:106A9000A17C61BCAE6EFE1813E0A8CB3342A60108
-:106AA0006A3414C6315C7C5573412009DBFEBB4659
-:106AB000EE51418E6AA8FEB6DFBF27C8E2C9E9F4ED
-:106AC000B64234C35F027EAD88789274DAB6ADFB0D
-:106AD000A3B850D9CEF655594BFAD917DF1364F144
-:106AE000E2B55BC666B1B88B535F9DE5F6E127CF93
-:106AF0003CAE76839E79FAC4F5B0CEF5FF53221AE8
-:106B00009DF7EC3399A413ED464205BBB1AE434A61
-:106B1000690F096962F9F3EF6522BDD63DE7492C9B
-:106B2000A0EFAF7BE19D4984C2777653CF6B23C141
-:106B30009F7E5A607171B37BD2627A7F9D4C56A75B
-:106B40008AB34C90D93EE4F48F325680FC0A6D072C
-:106B50006FC671DB972B6057AD7E86AC20BFD27EAF
-:106B600068B7CDA784C45821157C2C1F71FA2981E0
-:106B7000C17740C1FDDFBAB6BD6A94C251D3F621D8
-:106B8000EA8BD9DF7B360078A8392039FCB89A36F1
-:106B9000A9D33309AF27E00A71566106F009E797D8
-:106BA0008E0D185FAD6E7FE0432900EF3BF516C5F3
-:106BB0004BA813F0FAA6145A00ED1FFC63C0A0A85E
-:106BC000FAE0F01301C02B1D778D9A05717C277FA9
-:106BD000C3F81772FA8E47391DF3BD35ED5BD87CCB
-:106BE0002EBDF801FC52D0370E1B919D7974D23620
-:106BF000B83CEFFA67CF3D6AD2F94E3FF7FB474DFD
-:106C00000AF75D7FF9F747BF0E72F9CF5E1DF47A80
-:106C1000CDD3BF0C101B1FAE9359FCE0EC28BA85F6
-:106C2000A2FDCEFECA930087E0EC4BEF8D36E87AEA
-:106C3000CF7EFF4FC30DDABFEEA5B9F9B0FEBAE7BC
-:106C400067E7F7E7C7009F263C76B81238BE714069
-:106C500060CEC28BFCEAA2CBA18E43A301CE33C788
-:106C60003CB83FABA1F7EAA7029D36A09D85F6464A
-:106C70008ADFEA67367F08FAA12F9ECD912206BFF0
-:106C8000A81A0C029DDF9987F4223D681FDDFD6B79
-:106C90008E523A4E4E4FB773E46315F45CCD335BBE
-:106CA000D87C2EBA9D815FAEEC4BB7CD2EBA9D231A
-:106CB000773D560089D78E618E3C8275ED8D9F475A
-:106CC000B222FDE8074BFE07C22BE659285C4BE5D4
-:106CD000F0376490A3E73292745D00747DF6DC684F
-:106CE00042F9E27DA5E766B0073D2F79F47DF4FE19
-:106CF000BA97DE44B93AFBFCEBAA81768CF805EA38
-:106D0000579E25C99FC3E06756339F93D4ECCFECC1
-:106D1000F4047AE9539D58586904F0FE09BC9F6059
-:106D2000FC5E9D38B8444841AFD7E5314CFF27F2AF
-:106D3000102F1BF6FF46257E271D8532A0E389799B
-:106D4000703F1D1DADF5EBB0FE99367AEE6772EA25
-:106D5000EE5F4DE511EC5D92AE09E14D92422ECF12
-:106D6000EEF5C860EFCE825F95326FCAFC99A1E65E
-:106D7000577E263BEBAF92F9158E87F4FCC1E47B7E
-:106D8000A0F50D157F3F920D1CD78DC7D31FA7D639
-:106D9000F7EF717D514DCCCA1197F6F5436412316E
-:106DA0004716F5C27B1A36A894FF4E3F2D613CA8CA
-:106DB000A5FD10EA6DB79EA84E13DFBC20333FA19E
-:106DC000FAC0C149A0CF4EBFFC23E4CFEA674EA86A
-:106DD000102F7EADED076A7769AF3C803D48D8EC57
-:106DE000C1E9EF1E9CC4F4001D3F059D14858D5F15
-:106DF000F3A273FC9A673E748CBFDE6C47FF60A001
-:106E0000793E90C3CB61BD1F1C5608E8D10FDAA5AF
-:106E1000CA547EED07DC1E5A786A797DDE6F200F3A
-:106E200036ED88CF00BBD9B1299CBF1DFCB5230A24
-:106E300001BD4DE4F0EF3DB4DDF1BACF80FC74C785
-:106E400091659261DB87FED085CF9947CDD9997442
-:106E5000BC99DD9169E0A2BAF546D971BAAFB2F139
-:106E600041DDEB95F9A0EF611F6A8C87F94241D8AB
-:106E7000E74A8179952C7F2DEADE94F69A8DA7F862
-:106E80002318AF5274311923837147924423C45796
-:106E900089DFEFCE4F44347B1E6AC5E183B0C5CC99
-:106EA0005DFC62018C132031FD24FA9F2474B11F14
-:106EB000FFCB9D8FB0F09994BF34F9890CFDE6E0CB
-:106EC00041D277BCBE7998A806F1ED16FFDAD6223A
-:106ED0005B1EA625D8270F3357A178681548CA78B6
-:106EE000ED78A562BE9287BBE368AAE737294CAE6E
-:106EF000AE25DDF7AE0138232C9F33CB85AF2F7144
-:106F00007CFDF364BA70AA42CBC1B3A2F89DBD2444
-:106F10001C53E8FDB9AB7A2E7F19BBF37C8E395E2A
-:106F2000BC983178FC0D356F17F12CBA5D1944DE31
-:106F30002E5DFEB8170E93EFC7731C798C436FDD7F
-:106F4000AF75639EA1B6B5C816F71BDEE92561CC07
-:106F5000E319E81F0EEFBCF39BB741DC39B730E40F
-:106F6000257DC7912F5C8D71232B9F2F17863B2189
-:106F7000DE2FEB46B984F32C0F437E61B3C1F205DB
-:106F80009B83FDC7F56628D16605E351D7E0B8A21B
-:106F9000C6EB0F06B9CE6F2C0E209E0314CF20EF48
-:106FA000B8FF81F51D1778DEBCDB94207F78221BAB
-:106FB000F305019994403CE0BCE00B6DC27C823348
-:106FC0006F9E8E7FB7CB26E6CD5B8D3E79F3EF28A3
-:106FD000B67C8396266FAEF99760DE5C23367FB76A
-:106FE000A8B75FAFDCB9F2E63016C665B6CF86B893
-:106FF0004C733671E4CD9B41F0AF22E439E5EAD918
-:107000005877E6E5CFCD59B3C3F63639FE32B679B7
-:10701000FCE98FCDE73641FFDC91A416EBD4E40800
-:10702000596AD383EF292C4EBB4109FF50B1D71DBC
-:10703000717EB0F23F87DE7A0FF90AAE63285E9B5D
-:10704000295F7990AF4E11BB5EB5AE16FF341BFDC4
-:10705000F3857A610AC6CD92EDA0897C110846C3FA
-:10706000E114EF4DF230B9B7E60D94513D4AE54DCC
-:107070003122988F5275BAE135060F7F3AB82C3E0F
-:107080006D36C6B03A289D60FD5EFA754C63714C52
-:10709000887051B876DD787BA83F3FC75AE70C254A
-:1070A0007CD28EF7DC4B52D7EF56AB6CDDCD9155D1
-:1070B0002CBF5EE5CCA742FADA1E679D2E44FF5D29
-:1070C000C13821CBA78A5A84E7474C2B3E1E4CC6B9
-:1070D000C30DA833BCCB047DA8AC6A3705B8E6B2B3
-:1070E0007C4AAE16FD58B1D90759EF6672EBCA0F4C
-:1070F000CE954E0F09BF565DDCD6061DFDF42D0D55
-:10710000416C6F6E30F0DAD210C6FB6E3A361B2F30
-:10711000076FC1BA341FC665D38DFF604308C789A6
-:107120003594B1F178DE9C90CC26E02B55B4E46523
-:1071300018B6FD127F6E163481FC6D17D8F36B5AAA
-:107140002E4579B3F86787D17F5C5A4ACC403E1808
-:10715000EAF87DF9F527B8CEE6597ED4AF03C951D8
-:1071600056279B77B0F328497BC1E6D9314BC379C9
-:1071700076E40E304F9CCD3330FC0C5FDB0E9EC2AC
-:107180003A0485F203A828450FA7AED3E3F2D677D9
-:107190001C0FEAF9E620AB0B538BFD6150FECD06C8
-:1071A000CF3716B27CA35A32BC02EEABA1CBB04EA5
-:1071B0005C2DF5633E4F2D1E7E0BB4B71DDCA25730
-:1071C00080FD2814435E03EC76379173516C307E5A
-:1071D000AB1697DC06FD7590630AC7280FDB6FA915
-:1071E000C557DD01EF1F9CF29AD144FB3717FA42D5
-:1071F0001E90B76ED9C1FF83D61385CE3C1A91A9D4
-:10720000BEA0FA6BDB94DB4B503E355B9D648A7A03
-:10721000419BDED8A0DAF4864AE6988087747A87A4
-:10722000DADFFBD4BCBEE358EF6F5022F52AEA85C3
-:107230000871D6BBA7CE675BF400370BF2917230B2
-:1072400059A7B7A060786F7EDBAAD373E7B5E3F4E4
-:107250005FAABCB6BBFEFCB3AAD3DBA926EBF446FF
-:10726000419DDE8F1512EA84BCFC2FA5D03EA32FD2
-:10727000DFB9C7739FB7A0FE8F06FB9C7472F9330A
-:10728000D5993F2D88BAE87EABD731DF2B202FA5CB
-:1072900003EB979155CE7146D53AEB6A2FA9CF7182
-:1072A000B48BCC118EFE97B68E713C1F1BBFCCF1F8
-:1072B0007CFCEEA98EF684C4558EFE97B75538DA5D
-:1072C00013DBAF73F49F7C6091A33DA573A5A3FF6F
-:1072D000155D6B1DCFA71F5EE7783EF3D83D8EF698
-:1072E00095DD5F73F4AFA7EE900A729BCBEB9073C2
-:1072F000F3457B9EB6358FDA25BACFDF9147190665
-:10730000E3DFACAE4B658F937943F77BB2A1867513
-:10731000CCFB8F9B035722D7A13D958DE11506DE4F
-:107320009F310FAE649AB3BE5635587D32ECE39C64
-:10733000F502CE3A6355DA86793ACFF12F77099381
-:10734000FAD2552D74CAC160EB9415C3F5DE10E571
-:10735000E2BC2517A3A85C60FCED6309CFB5CCC9DE
-:1073600044FFC2B69F423C5AFBA96B34120317D3A9
-:10737000928BF2553D235FC56ED63ECA230EA52ED5
-:10738000CE92BF804DEFC37EC5D233CD6583D3AFE0
-:1073900052E20A873FE9BE3605D6A5D38F051E9B6C
-:1073A0007FEFD68F339448213CD7E4B0496CF11A73
-:1073B00052AB38E01E2C9C9FD40EDC45198EA4D015
-:1073C000E32AA9C5BAAB9615610C02903AE2E0D364
-:1073D0009D8BFF47198C4BFDC219CE7532BFD0ED86
-:1073E0004F53FD86FEF40EEA4FA3BD73E947AAA7EB
-:1073F0004C5EFF65303F82E943F73A3F2F3FFADFAB
-:10740000C059ED875E81A25025EE0FF34402FBC305
-:10741000E6599120C4E7ACBA79EBBD56CFA5384EFA
-:107420002C5715217E19EB9A8BF1FA262DAAB13C27
-:107430007114C769CA16F5547562751E962FD6EA7F
-:107440001F18BBBF9FB88BA69268AA78DA4E0FCBE5
-:1074500007C5F4B55D604733F35403F6DCAD074F61
-:1074600045208E2497C93AECD70905E61D5B7E8F2F
-:107470009028C699B4A0887657ABDF81F30F04EF4C
-:10748000CD1E819FFBD8D22FBC5E3575DC251DBC7F
-:107490005B00DE6903C3EB05788B60FE6D387F8D82
-:1074A000C748897F85842B6703DD4E7C3982E95686
-:1074B000CA36201F3BCAD8BE9C1A02077F5BFB1C42
-:1074C000CADF0F7BF2B07E15F9DA3AE770A347C73F
-:1074D000792CBA92C21C8C6B04A2B1B1C594DF3274
-:1074E000A36C3FDFAB9F181F652A6102F12CD92FD7
-:1074F000627E50E5F110ABDF1F383E9B667523BD01
-:10750000365F29934D426F9D75AC90AE6B72EFBAAA
-:10751000FE8F279BF1279FD7479664615D8AF44CC5
-:10752000B03FBDEDE3F872EBEFEF79B8FE2E20052A
-:107530004C7F972E877C77BA71DC7E4C3D8FF30EA3
-:10754000BDBE9E9F2FF0DFD30571262BCE4782D381
-:1075500052C6E57BF1CAF295BDF45D6E7452FAC96C
-:10756000D3A7629EDC3AAF40D599B35E98D3D7A239
-:10757000AB15472741163FB2E8EC4DE2734FBFF819
-:10758000F482BC5CD1179FBFF2F07CC37F317CBE1C
-:10759000023E0DBD6666B2F3E9E4D05709E6A50ADE
-:1075A0009D7268BD67F1BB7BFD7FFA2FCA4FD6FA8B
-:1075B0002D7E48DFDF4CB9AFB1F2AB999CDF343898
-:1075C000654515CFAB656FB75E0AFBD7A01FF77D8A
-:1075D0009965313CDFAB105307BD9069ED6BF879CD
-:1075E00023AB5EC957EAF4CB34D7FE45E575517D30
-:1075F000CEDB72FFCD7D8E2A895F17BD266B69F2C7
-:1076000063833C7FB48BE7EB0AEAE28DB01F2EB8B0
-:1076100095D5FBEF51C86AA8AF1C51658ABE5CC8FE
-:10762000DF147D3F83AEBFE0C5871A4702496E3540
-:107630008AC0CD7846331C76B8E0AE78B98F3D9FCE
-:1076400002E33CA531BD5B5019C773CE4DCF8FCF40
-:10765000023FE195B796EB101FF828B718F74F6770
-:107660005EF08441FF9FC921555817F6C2CCD7C0A0
-:107670008FFF7D43578E6CE39333DF7D7D86428998
-:1076800074E6B9D767C848AC8463FE0D177F310331
-:10769000E0362B48492DE4EF7495C0B8351ACB97E6
-:1076A00059F53EBB86AB2D70FDA9379BC513F3C5BD
-:1076B0001DD0AE878018F80D3C9E7FF5696339D4E4
-:1076C0005F66772902D4E33D2498A69F5ECF9F781A
-:1076D00048003F4BEDAC85300BBD1F3A042837C73F
-:1076E000B27DC9F922525244F5BEEF70ED78F4A78D
-:1076F0005DF54E16FFCBB309E6FB7A6ED41260AF90
-:10770000B7CBC6375681FD5E25633DCE76F930CACC
-:10771000859B8EC7BD639CF5B93C1E7DE8AD3BE201
-:10772000E5F4FD7BA688C8AFFE1353B2480AF9DD25
-:10773000DE5086F3070ADEAE2C07B03EA67767F46C
-:10774000EE93FC3231B3A889548A4453A178F1975F
-:1077500011F2B68DEF5A4412D6E9F3171A088ED3F8
-:10776000D1A0E1B5AD411F5B4C3706DF6A08E27579
-:10777000678381D7871B4AF0F9830D2187DCC37C9F
-:107780006F97F0760A7FE5F3BA3ED040E7B5C1B116
-:107790006B22957A4AAF5D3C1FF540E9D4ACB5FD4C
-:1077A000C4C1F634740D9B3396230BEA4DEBF4BD44
-:1077B0005BFB817F4FA3B07A11F83577CB917DA821
-:1077C0001FA3058B6CFA91FA6D0584B2E2BD2D23DF
-:1077D000E6CC29407944799976388AFE7841302E72
-:1077E000401CB1E028BB6F9DB7407A5141FB61EE70
-:1077F0001C4101BD594ADA012CB5344A2A68FF9967
-:10780000794BCAE13E99E8BC3F4365F20DE356D09F
-:10781000EB6C2DF2236D3A7CA763B7F92C5DCF1F7B
-:107820003B3C06E4791E7CF94F2AEC0B62BF5235D3
-:10783000F0630A5E3C81750F31A15B85CAD8E35ABB
-:10784000F51C99EA19DC0C627C952A16CA2731D0FE
-:10785000B118FFEC89CDF1C37997E8297BFF5DBEB4
-:10786000E8DDFCE448580B523E4AE62FD6C7C27406
-:10787000D3F902CF5F1CD7D6C5CC4268D3FE53588C
-:107880003B46DF7F213B3A52CC86A28BAA58D79742
-:10789000A06DF5AF8A41BDED9B5CEF107FB408E4AD
-:1078A0002DD9D6693BD3D696599B68EC6AAD77C380
-:1078B000A13FBD067AAEFA45A11D40A37A8FE1FF34
-:1078C000C0435877DBD6D0A5C7144E7F8B0E542407
-:1078D000270409D6D3A909213186EA8F09FCFB14B4
-:1078E00005D3C24623E8D7841202BD19F231BF7115
-:1078F00042828E6393AB0969BE8382795FA0E336CF
-:107900005637ECE6AF67BD2C3F504FCCAD90072308
-:10791000CF283AE623799CF2B465E7F87EF52E2F5E
-:107920006B2A9B4CDF65A07FD6C818075B5F142FBE
-:1079300057E93CEB7F5414A29615F24A58D7B03E53
-:10794000BB7DF854969772B41FE275B4C16C331BBB
-:10795000CE0F541F786834D4055493F8CD5F037864
-:10796000FF95E51F4F1DBC32EB6ADADE40DB107F6E
-:10797000DDD0F1BA1AA5FD8671B8AB3BA65C07EB6A
-:10798000ABDE2612B188C967783CC573387E994C46
-:10799000F9E49AAD23E77A299D9F1A13D645CA07C1
-:1079A0002B7DE39A3568ABFA04909B95BE89CDC0D8
-:1079B00057EB27F2EF359089AF86655E2F45F96268
-:1079C000D8968618D427EC5F59791D98D9E122936F
-:1079D0005BCA88983F94B26398B7F843333BEF0291
-:1079E00029FD8D940EC532E992E97597CAE867B60C
-:1079F000C8182FA6F75B95A940977818CF57B432CF
-:107A0000BD3FF6450FC69D8B6BC377A25FA097E283
-:107A10003E653449FE605EFA12F88D8E335E27E5CE
-:107A2000700EE1C75E162F2C5EB16C3DBC27652E33
-:107A3000F1E1BE5C62E7A0C8B7599C7A979868D715
-:107A400040CE03C548DF5D01C617E6C3A5C817FBD6
-:107A5000C58ACBEE86B8A4B066EBBF005DB38B09D8
-:107A6000D015EEDF43EFEFE7F494B2433AD06F3F27
-:107A7000A7672C219A501F63DD7F41587B27C8DB05
-:107A80003AEFF373348AD7E19E707C18A5C39DDE6C
-:107A9000E763C102A4C3188DE2FDCE2D1D316D1424
-:107AA0001DA7313C42B7B5C7FF997A23989FEC4098
-:107AB0007996B31F5E07F24E9FBFA2D1753E95C364
-:107AC000F5057F5E3C26A93FC284DA1AA9B1579F0B
-:107AD00068D43E14DBFACFA1FAE0C947591DFBF583
-:107AE000743E9077BA0ECCFFF64C9013509FE5A3EE
-:107AF000B080DFE29B3806EBF3E8BA09F8253D13C6
-:107B000065B4B3561CDB3341C4F812F4077EF08D24
-:107B100062FDA9A044406FCA8532EE5765694F786F
-:107B20008201E16396D715F485786ED55B62CBE36D
-:107B300092DE3A606C17E1676E1CEDB19EEE029129
-:107B4000FA95B9C7170AA3E9787778B9BF9D4BFDB5
-:107B50006D7A7FBD97E9A5FB23E69721C4418CEEA2
-:107B600002D44F243215AEF93715E747FBB14B7DF0
-:107B7000FDEA6EF41F76F8539FD39CEE63FBF92663
-:107B8000FF111DF8AD9E50F907B9D019BF59FAC3BE
-:107B90003A9FE0AE27B6F48992CDD65837BF221F60
-:107BA000F480CCEB93643DA4437D6579E634F4FB2B
-:107BB0009EF432BD271DBCF20638A7A1FE2BCB0BCD
-:107BC000EDF146319ED45340DA815FE56098D8F3F9
-:107BD000BF963E6869D0F0FAC4D4711520274F4C87
-:107BE0001D5EA153193834E9C75D90673AB787C95C
-:107BF000EFB9C3B7E1F9C773268B37015B615CB29C
-:107C0000F3113CAFFBB81C7910EB6AA13E8282B441
-:107C10002DDB59BF55CCF16272FDD4ACB0E79B1B94
-:107C200058FC58BD7039C6B554AEC73DD15BF1DCC8
-:107C30008687DA32385FA911D364DF3B6078D00AD7
-:107C40009DDFC3502F4CC2F74D2F8B1F59F522EEED
-:107C5000BA100B9E191C9EBEE7329CF4B0F65F165C
-:107C60001DACF7EB8470BEDE0FDFD45C9048C2160B
-:107C7000FFE8ADEF56F1FE59A88BCF823A9E68FC23
-:107C8000EA22908304EE8FBCFE3A42F8F795904FBB
-:107C900083728FBD0E3DC35517DF475E0C67DB5DFA
-:107CA00017B11E9883D7F1613DAB4CBE29507A9F26
-:107CB000C9F8ED0CF06B6BA87AD02040249B3ACC2D
-:107CC0007F96FBFBF28B7787471A363E170CC73E31
-:107CD000A1FAC0428C23D4ECF763BD7F35E8BFC95D
-:107CE000706EC0ECF238CE0B843BA13E4F39C0C65B
-:107CF0007B12E0A1F7FFA85715C0BA8FC3FE270F6C
-:107D0000EC495462875E0E231E62DEF031A2337DA1
-:107D100026539E88655BFAAC3A061B865D2A71F88D
-:107D20004BBB7CBCEDAB8EC54A7BEB3F8E6BFF0F34
-:107D3000F59B55DF715CFB0FF48776A9F14ED07788
-:107D4000E60B1E03EC177D1FCFEF9A2B4BD00EC412
-:107D50008AC808C0C32BD92AEAB9D8F39E7DA0E708
-:107D6000666BD13735DBBEE14CF61BA361FF956234
-:107D70003CD331DEA8A18D47E7EF00BC5ACF5FC9E5
-:107D8000DE85E716E97B06E60D0B0F8F5E43DBC34E
-:107D90005FF0E0B9216BBFE9E6CB7C2E5F2DAEF33F
-:107DA000802AC89B1FF46D2DCA9927E8CC8359728D
-:107DB000A75E98E0C8073C097696D24F95A310A21B
-:107DC000A4CF4BF1B9C9F9AC85D723A49F2727CD00
-:107DD0003C57A03CA79F67069777C2E558D693DF2C
-:107DE00085E9E7DCA03B4FE2D653D6D5D253DFE29C
-:107DF000FC2993E8153E3ACFBA44FB3C1FBE1D9DBB
-:107E0000047EF0071A3B0755D2F6D0CB609EBFE93F
-:107E100009DFEF9D8EE7BEFEC99B37747958E923D1
-:107E2000BC2EB38F1E62FED5ADCC5FAD9B3F15FD62
-:107E3000BBBAED6374FB3945F7B5EA4286430F0DD3
-:107E4000F31AFC7B7B26EAA3AA0B017CFED9CDE7C3
-:107E5000759C5FE93B9F1F9F5BF3DDE5D2B38726EF
-:107E6000FD74179C73AFFBBE227A6CF3D47D9FD751
-:107E7000FF7BA9DE75CA7B18E45D2E22C9FA2ED0DD
-:107E80000FDB54AB1D6E9E330BFC5A9B7E2803FF09
-:107E9000ABF77DF8CEDD361FEF6F56A6EE9FE1EA19
-:107EA0003FC61A7F21F677C393D43FB01FA3FDE5E9
-:107EB0003F7B2CF8507F3D24BAC6CBB1E6BF11C73B
-:107EC000B3FCEE8BDADA574D19F8345E0EFBA79E41
-:107ED000DB8801DF9F785C0EF94276BED518BF566D
-:107EE0005DB8D441EF5EBC8F73DC7FAF21E8A8D7CB
-:107EF000BD235A8775DA1779FCA98A7AE6F8DE9EDF
-:107F0000918E3ADDBFC1F149E1B83A0D1CD77CC171
-:107F1000701439E4B3178E62C7FD4F0AC7428DE96A
-:107F2000AFE5FC3A5767E766E71A42A889DE9A4B45
-:107F3000EF7B29AF7F995E357A9D2B13D38FDF4579
-:107F40004DB0FEB40DFBFB1BFE7CEFBBD762A22A3B
-:107F5000E8A82B90789DB75BEFC0396F56EFA63934
-:107F6000BE0F675D7D12ABD774DFFFD0C7F0F28D17
-:107F7000CBAB09F8D3D4574F796E6D975FE0DFFB39
-:107F80000C8A8E38376F5B75BE9F155C72069BEF4F
-:107F90001B975F4F20AE2BE7A6FEBEDD413F83BFA0
-:107FA000450B639D784CEFFFBB349F149EE14978ED
-:107FB000AE413C4969F0546BC1A3B3BC604BF0F3D4
-:107FC00081A724C3A25BFFF8D9CAE126172E413E40
-:107FD00092389D5A60FF96A2BF95FF68D13E5FF828
-:107FE000C383A4EF73195F0C7D170D92BEC55C0EA1
-:107FF0005AF4CF179E5B0709CF7516BF05C348AF6C
-:10800000CF0B9EAF0C129E6316BD8CCF173FAD49B0
-:10801000FEEF1F9EBF70B8F333581CA4A5849D27A4
-:10802000F14991078B8481E5C257ECDC676B853E93
-:10803000679DCDBBCEBAAF74EBFC355F673A795A1A
-:10804000A924F2807EC71A583CE00DBE3FF9755551
-:108050005326C6E75DF3B404F765F617B7F9EF5595
-:10806000CE73B903C9F1A40C96FFB931EA7C6FF95C
-:108070008A0C571D9989FD2CFCA51BEFAF056F617C
-:1080800048620E026F145F5945FDEC1B3E6B7CA5E8
-:1080900093BBA1E22BA60F0D5F03C9FB5786882F68
-:1080A0004B5EFF5AF1950FF89AFE37FE1A2CBE165A
-:1080B000FD4D1E8784AF5B872A8FDCAFFD6BC5D774
-:1080C00060E5D1BD6FA3FBBB507FDF17F8ACF1E7D4
-:1080D0009EFFD3E2D11A6F659A7D5E3A7C0E0487CB
-:1080E00075FDD03748BCBAF79F5F345E5DF37F6A99
-:1080F000BCF2F1868CD701E0B0AEF220E5DBF2EB0A
-:10810000DAD4D4DF111D97C9BEE3365EA83D321F15
-:10811000F2C77F27617EFAC89E391BECF540E33237
-:1081200099BF7DA472F606889F9E8B6460EDD9513D
-:1081300031F4F36990575EC4DE738F7F84E3CB9391
-:10814000996DC57FF380AE47238BFB954752695BE2
-:1081500017E68D6CF495FAE2FB0831B64F833CC408
-:1081600082D47058744E37EF50E97B34F2F890F4B3
-:10817000CF40EBFD0FFF9841EA9F04F6CB25C9BF26
-:10818000BB7319E0B34D64F570C7E156017CD78D20
-:1081900060A7E52BF2F7029DEECE64F9C30ED5D8A9
-:1081A00000F913CFE2050F6452BA1D5D9A2DD8CFA6
-:1081B0005FCEC964FBAF19AB52EFBB16723EE87DD0
-:1081C0005F20E353F07798F75BBA8A7D7F8CC8E134
-:1081D000518B6CE74ED7BB9EF7A1476600E1389AFA
-:1081E000E6DCFF02FEFEF225FDBF4F6AD9F77D28CF
-:1081F000DF8DB29F7B4DF219978F33FEE8D24C7A18
-:108200007D43887EE73EE0A3097E766E4826455092
-:108210007F658D932B934E95E2FD5DC5180579CD55
-:1082200014E3DC9C393DFD38E9F06AADC79A074498
-:1082300011BED333576371C46961426641FCD013E8
-:10824000BA9BE50F191FE4F03AC499B5198946D8CD
-:10825000F7CA749D36783BFEEFECFF06CF3B8E8865
-:108260003A9E6F77E16120FDD094C9F2C9B952748A
-:108270009317F226AB8594DFB1DB98C9FEDED1A45B
-:10828000CC64BD14CE336E675481EF5F2C9359FEDE
-:108290008B90E8A885B6F927717E73BF972BB17ACA
-:1082A00023F22693E7B67DEB46A5929F5F70399D3A
-:1082B0009459E2A8735C12B95B01F95CB260A162E7
-:1082C000F8E1B981E32FE570B4A9D15153FCBD7831
-:1082D0004AAB87387E3A8E459BE0BB1FABEB05ACC3
-:1082E0001328DDC8F86EF5C683E2067ADDCBE56FAC
-:1082F00021D0C036DE77395DDBF6F94603FC6DC967
-:10830000FC0D1D98C271F36E82F99027B79F6E81A4
-:108310007C48B74078FEE4C64AA86BE8E6F56D2FC6
-:10832000D3E78D80BF397928DFE3367E5807FAB965
-:108330004325785EE6775B3C09384F60F14B524F3E
-:108340006C3CDF00F5C38FA89D13816FF29A6AEF32
-:108350004B953F7D89D3E18FFE48562A3FD0BA5ACC
-:10836000FADCEAB748369454FD1757BAEC1A877B03
-:1083700098A7F30C4991C74CF261A27F3FED975C3F
-:108380008FFFC295E75D722C759CF1579C7FDB12C5
-:1083900015EBD16E991E3C8762C163E12BD76478DF
-:1083A0005AB64472E8DBD50B325C7E0FC3EB0D1E70
-:1083B000E35158C723FB7E3A11CF51B9EC834F8A62
-:1083C000AAF0FC0ED2A9809E785F32F0FA4683F3C1
-:1083D000EFBCBC41A2DBA783FDAC9752CAD51F39C5
-:1083E000FFBCB1E296A5087F4CD201FE13AB865DBF
-:1083F0005F06FA65851282EFA69F88DD9B799B6DEB
-:10840000FD49BFC605D7AFAB6EE9D76E2D5FE1A4BE
-:108410005B9BCAFC02F33A268777521E9D85FCD5EA
-:10842000BD7D269DFF482267CA56D69DC0DF995A5A
-:10843000CC7F7F5F8CEE9849F5CD2991E549CCAF93
-:1084400030BDB16467A41952A7A7EAAF78A99BF61B
-:10845000F30618DFFDB6BE7FFBE8E6A7713B9DFE85
-:10846000DE8C634485F7A375A9EDC1B7F50CFEF763
-:10847000C442A341BFDCB43175BFFF05CC4CE13928
-:10848000F517A92A557CF22A9DC1BB3A92FAFDAB99
-:10849000F44CF61CEC520A3C9F0B64703DA78F060F
-:1084A0003DBD3A0DBC1F060208EF3BCDF7DF04755A
-:1084B00020EFBBBE03FF4E80F1C5C100E3EF53FBCD
-:1084C000562A7940A71641077E783B3B3401F86D68
-:1084D0004DEC049E7739C0F1FCA62F3225301DE407
-:1084E00065D1DC3C4A978E55242418E9F5FF9501A7
-:1084F000E637E4F2782DB57FEF82FDA3AFBE8BFEA9
-:10850000871C1E7DE34456020575E0A744731DD603
-:1085100019EEF3B1BA52129A6EF7E3BFCCE138B557
-:108520007F68F45E1A71F9417DFCBF7835CEBB3FA0
-:108530004387BA94239552E7B514C893FB33F0FBF5
-:10854000B86EB94837FF50FDC053FB87E6070EB43D
-:10855000EE0D81A241F981E72A1FD9310DE4488D42
-:108560004F4AA57F2D3D7D94C7DFDDFC635DBFCA0B
-:10857000F9E8FD44FF70DDB1DB09CF4DB54E782C35
-:1085800079793FD1E45B0378229D13ED7E299933FD
-:108590007D003BCBF253E9E0DCEED213C07940879B
-:1085A0003BB9BEF96DFD23013B1DDCEB3F25F2FD20
-:1085B000C1A3AC2E776C644D459ED1CB9FDFFA9C56
-:1085C000F8D2B233EE71FEB3F3A165E706E2C3DC85
-:1085D00034799C4970D099BEBF46D655C8D74F0A4A
-:1085E00018AC4DF47970548B94F1BA51628C86F3C7
-:1085F0005FA7F6F9F0EF43995B3D89B15404DEDFE4
-:1086000077F504FB7A7EC5F974F5926CFCFCC4FB2B
-:1086100062687E3ED69D49F81DB7378EE5CC83F65D
-:10862000238745D0D0E4A6BA3512ACEF8D00DB77B6
-:10863000AEDEF83AFA8343E5F3D5B54EFB7F155F1E
-:1086400047D2CF927BA601FFA4C3C36B1C0F4B2361
-:108650000BE7827EBE65A380FAF627300E5DC82D3B
-:108660007218F5368931FB48348A0F6A424EC022AF
-:10867000001FFFC0BF5B254754FB39B9DBB6DD3FA8
-:1086800017FC43B7BCACC8627C5C91C5ECC29BBE16
-:10869000E81F40DF5BFAF96DA1F6603EEDB231A054
-:1086A0005BDF094639B5D6B391C345FDB467F1FB2D
-:1086B000C57C7DA4C7C56F62BCFAC780FF0A0DFDEB
-:1086C000029F87EA7DA88B7EDC877554965C59FEF5
-:1086D0008EFBFD6572D4E13766661539FC77B71FEE
-:1086E000F2377B91BAFF15595FACBDB836EBB3B129
-:1086F00017C3389FB9ED4652AE5BD8799013C73E89
-:108700009A9B4AAE239F100EB73CBFBFCFC7BE9BFC
-:108710007C4D26EA9DDEFD547E02F6CB6EB980FDCF
-:10872000147CF7E3917D3F9B0875BD27B6DF7F532F
-:108730002A7ACED299DF44BAF31DF1BCB50182F595
-:10874000DF84CEF7846D7CEBBDA4BC0C10BF5CB69F
-:10875000F24ADC4FBEB1F2EAD16B4AFBEE2BFAF4DF
-:1087600017A2FFB014E66DE4FBE91D9EAA7DA9F6F1
-:10877000811CAF7DE3C44EFF7EE9C6F266D8526F1E
-:10878000CAB8E64BD114F327F7351B53C7E31EE4F1
-:108790007A2AB9AF31E9BE86E2A37B9514289BD62D
-:1087A000BBAFE9363F9F7DCDEF48CFCF67A2FCA797
-:1087B00086EF7B167FA9D11D5752F84ED1FD8F0948
-:1087C000F223D2F7805FBE957ABFF6387FEF771B32
-:1087D00087A8AF8E39F733E9E4EF7B9F91FCB5A909
-:1087E0003DA3400FFC6EEFC76FDD0FEBD9EB437C71
-:1087F000BBC789E812DF5FF8906F2DFBDCA132FD6B
-:10880000FFBBBF1B817F37DB2D1F84C4AFBF8A3EF8
-:108810003FBE4F9C02DF596CDB9751956A9FB35E58
-:1088200017787CC919EF21DCBF5BCAF94DDFF774FB
-:10883000AD3D1EFD26D757561CE07F67313BBB641C
-:10884000C14215E23DB725E34D04372BFA65857B20
-:10885000E1FB17BFE4E7B9CCB59929CFC7FD86E3A3
-:1088600077A038C48A55CE38C19205FDDB9B938929
-:10887000D47559163FA79B6FA8F6A52D31B4BCD867
-:1088800040EB1CA10FCEBE2C25B55F8278C73212FB
-:1088900052E0BA84D44EFC3145E5C9DD8B119E5FB0
-:1088A0005A7FFFF8E37B27DAFD98FF0F11FE85A1C1
-:1088B00000800000000000001F8B08000000000086
-:1088C000000BDD7D0B7854459670DDBEFD4AD24924
-:1088D0003A9DEEBC091D020818620742001FD02114
-:1088E0004482B2DA810041519A87184948A2E2CA0B
-:1088F000FEBA438720467466C2AA8CBFE3B80D82D5
-:10890000EB286AA2D1418CD8A0F8D8D59DA0AE8B17
-:10891000B3E846C7415E4322A32BB3CB0CFF39A774
-:10892000AAD2F7DE744370C7FDF6FBE338D7BAB7B7
-:108930009EE77D4E9DAAB63915C63C8C7D5B73FBC8
-:108940005F4D628CFDABB579BCD3C1D859FC9B1E81
-:108950007DFECB3AC6221731F6E13A3B8BD8A01CFC
-:1089600036558563D4FB53AA8931E8E85FE1C14AF3
-:10897000190B2D50C33B94C1F5B2705CACB7785E57
-:108980006A30463FF2B9A04665113BA3BFB3F06F12
-:10899000CD9C245DF922A753F4D39A182C62EC885D
-:1089A0001CF7513EEE91307F2FFBBB488C7B247C23
-:1089B000EE716F7E04C61D131DE78666FDB8BD2CE3
-:1089C000B48AB9619C70A2734701C3FF8CD8264456
-:1089D000DBEF759A08AEEC48A689653076876C1B8C
-:1089E00067BC0F057C8DF56BCC7E8B161FB7A77A05
-:1089F00069FEB25C33473F4F6F8A938FCB9CF981FE
-:108A000064C68E6E4BF4133CA6258747C13C2BED04
-:108A10002CE480793EF8E4C59FB1118C2D13F8AF9A
-:108A2000097C6D41781C35F5DF938CEBFAC0E4DCF2
-:108A30000143951DF45BB4F0BB2B85C3EFE8F673DF
-:108A4000C3EFAE143ECF7955FAF9CD3F98A82B1B52
-:108A5000D7FBEF7F7BEF04ECF7DFFFF63B8BB6FF36
-:108A600005A77359243D5A5E52ABF8C34583C77DB1
-:108A700029D53A24B8BF6480E392D3F9D4BF5B65AB
-:108A8000CD1D31D655EEB453FDF981728B07E0B997
-:108A9000FC6EC5A74017339CBC9FE566E6EF80F9E6
-:108AA00030B337BF1AE0EE696DBE2310A39FFF23DA
-:108AB000E0FD8D23901A8BCFE4F363410FB2DE0209
-:108AC00073D012ABFEC25A3D7C7B19AB8A35FF1FB7
-:108AD0003B395F0E951EE5F8C6FA439DC7DD820E51
-:108AE000D36D91DF33155E9C807ECA2E605C437D22
-:108AF000E3B8F73BF5F8338E7FF4CF6A5D2C38BCD2
-:108B000026F83F1800FA89F93D99BE7FC0DA1B7735
-:108B1000137F27F9762018B62FFF09A09DAD9C7D05
-:108B2000C75BF09A25A614D0FA16070E5412BB9D07
-:108B300079B018F1FE6DD5833F2985A91DB5065B77
-:108B400093A1C1D1F58A2FE41D3CCE07B84E90A366
-:108B50001FA13CBD08FB639C6E67C2FF65333646B0
-:108B6000F5D7A3506177D9BC3B347CEB5EFBDD3A93
-:108B700056CCD853D6C0FA64783FFAEEAFD73094CB
-:108B8000792C4CF3FEC2E2BB85E0CD18F1FDA16D5E
-:108B90008EAD9BA05E6A0A97938CF9F203E335725F
-:108BA000C2ECA4F250F1F3611CFC5CA89C92EB8C2B
-:108BB000370E409EE6377786A34D4965ACCBEABDBC
-:108BC00009D7D33F3BC1B90D5038D7EABF1AE1F3FB
-:108BD000C10193A9A580BA35239DCEE343B0826B32
-:108BE0000AEE1F578AF2C7E24F80A954431B36157D
-:108BF000E868862384FD957E38E719C4CF83B536AF
-:108C0000AF8AFD4DF37EAA4279EE5536EF7AE8AF92
-:108C1000AC67C45E37F43F7F8EE264D07EE6EC51F1
-:108C20009E5E585FD25AE8270747B8B7AAC2CCD889
-:108C3000D3F89F97323E6180C55C45965F6C9B0977
-:108C4000F2609CA7CBE40050AF4C7BB1CD0EFDDEB3
-:108C5000D312C872A6C1D236DFD7661FC658468661
-:108C6000BF67BA8FB1D99BEFAFB25F01EB7C54B451
-:108C70000F3DD0E6CF63EC5553B04081EFCD9B77ED
-:108C80005499015EEE4239FE2B6DFECB613D57DDFE
-:108C9000B2630DF4BF25ED9FAACC38EFC572FC9EE0
-:108CA000AA8A9130FFCB65F95FEC385F77926C0F41
-:108CB000F39DC298654474FEE62C18DF25CB9F54C3
-:108CC000CD84F13F2E6FAE30C3F8C7D2FEBDAD6884
-:108CD0002C6393E7943BFD50EEDBFC1F5549809FCE
-:108CE0002E06740AE53F6C3E4DF377AB26DE7FE837
-:108CF0008F34BFB2C5A171F85D617F6AAB8275AF79
-:108D0000B6F7BE85E4DAB43664CF4091A4703AB1C8
-:108D10005B9AFDB9003BCBAEF2482E4DA79DD36BBD
-:108D20005E643CEAB181F218288FD794B378B96BAE
-:108D30003D5B124BDE76BAB81EEE4A8CFDBD228D2D
-:108D4000CB03801BE993D483CCBF33865E1997E6AF
-:108D5000A07EF627B290DD15E5B76B8187A7005F8F
-:108D6000323B9FA7EC6790FE48E3729F85AE75216A
-:108D7000DFCCC12E60E9853E258474CD9A93C2A3D1
-:108D8000907658C43C0FF5876AA2F97A5465493544
-:108D9000F49791C8829DF0F4A4332A437B7FA723E4
-:108DA000DADF7B82EE2B0B03DBB1BFCACCEC92D6B1
-:108DB00082683F30EF0DF609BA799BA7B8F0FBDC6B
-:108DC000925B8B34F02CE2EB003AA07630CC33D3BC
-:108DD000810FBA7AC68DD804F3FB06E5AE27BAAE8A
-:108DE000B29EB91606F5B6B8843CF1F2F69E0A2E8C
-:108DF0007FFA6F4D0A6F43FEB4FB4A104FB2DD0D90
-:108E000002EE15F7CEF919D66BE8B1301BD45BD35F
-:108E1000599EC9CEA1171B4E5FC6C213356573C4D8
-:108E20008A72A7E1F4347A5F71EF7B56E453ECC7A2
-:108E30000BEB5A93E0CFF421DC5A63E39FB1169A0F
-:108E400047C3E934169AA87DCFE114EDDF4DDFCF9B
-:108E5000B7AE687F2A0BA79FAB3F2B7D1F80BB5906
-:108E6000C0DD1A7B9E1B04FD20BC4D1AFA9A2FE828
-:108E70000DA49F1FE5E1A16B8AB6A1BC8F8EBB9E9E
-:108E8000FAEF32031ED10EEC49F4A25D5C66E6F205
-:108E9000B3ACC7E50C2951FA907421F1DAE56A2EDA
-:108EA000A7F5562BCE6D0583E775BF9C97D0A79984
-:108EB0008B83EA52CDFC243F40FF5DA2FFD229C440
-:108EC0003FBFE0F4027C7303F22FDA2DB80E5F642B
-:108ED000FCDCE4C1F33F0DE4854FC02387FF5F391D
-:108EE000C2A80724DC06C33FF73CF8CCA7EF653DDA
-:108EF000FBACB8CE86387CFB802B85DA651E8CA453
-:108F000078A1DE19617774754C4CB80CF9628E89C2
-:108F1000A108C375A3BD5A36206FAF7C7706C8DBA6
-:108F2000CC8132C85B2FE26140FE46ECF668FD1F43
-:108F3000B9AE9CBD01E4B5DB06F82F223BD4CE349C
-:108F4000FEC4EE346EBF4D09B29876CBDFB9927590
-:108F500072ECFFAEAD60BF85F599D3B8DE9FD21B32
-:108F600052102F92AF8D72EA13C18F1F8BE7FFBC97
-:108F70009C52CE23A7AA859CE2EFF783998FF53206
-:108F80003222E315D089CBDE9D380AFD99DBB2543D
-:108F9000EF97C057F314DFB067A1DF1ABBF79E64E9
-:108FA0006F944E6A98DDEB40B883D17416F5FE9C41
-:108FB000042AE31FDA25A7DA154E87CC9B5A333EE5
-:108FC000BE1C92F3B82DCB4AE32DBB6F546A503BC5
-:108FD0003FA127AEB5459E658583F95C9661FEABE2
-:108FE0004DAAE6BB83EBB3B1C9FE6FD2D00E555884
-:108FF0002DCDC7602F3904DF19EDA587B16F0FFDA7
-:109000002F62233E3691739AD9660B33DE24847E19
-:109010006A660713FC1A313568E8C0EECAA3792CDA
-:109020005E081F2F01A6B4BF71C9971A3E7A07E7E1
-:10903000437A213209F934C1C57476DE623590A7CE
-:10904000A0DD9A69F3A19C013C111CF62730730244
-:109050008CFB363C116F95EAAD7B2D6EA403C5D712
-:109060004AD0DF2AFC5616417D73EDF424B25BD959
-:1090700099DB4756033C3C499C6EA11FBBE8C74E99
-:109080007422E4DEAFF3C76E43FD24E5A7C4033BBF
-:10909000A3527FF2FB7EA53ACF09E5FD9E8B4A5A8B
-:1090A00015BDFD83F650D47E4ABF6F16F0E3E4AAE7
-:1090B0008E880958A825E4997D27D4AF4CE26B1E11
-:1090C000E9E27A707F41484DC1FE46C13AE0D55B86
-:1090D00089C1A26647141F60E304117F1956783ACC
-:1090E000387FE0739F8BF3D99C748E942DE9BC9CE0
-:1090F00091C2EB1BE9ED49F17D95C2F1BBA99CCB77
-:109100000963BDE92EDEDF6A7BA82A6384D6BE0A26
-:1091100030A44333E37696DF25E8A482C3ABE2DED6
-:10912000C5A9A837BFED999FCA8AA272F41E25E887
-:10913000F441FD7B2C819F52BCE35F5486FE883551
-:109140002DE87441BDF4A4D8FEF24D621EE9E84F4B
-:1091500043BD9F087FC772FA62F2B317BAB83C4B9F
-:10916000C9AA21798E30F4A29FC2FA434E0DFE5255
-:10917000A798747E83E57431B5BF70BBA1248EDDE2
-:1091800050AAB31BE4B846FBE1D37559347FD9FE2E
-:1091900086AC8F2A99A6FE8DACF71EECEFC635B9CA
-:1091A000BA38513CBBE32E011FB4134231E765D5F9
-:1091B000BDFF14FCC49076FC237CFCE8B849C06871
-:1091C000D171FD2EFFDD2EE2A7CB9D872F864702B2
-:1091D000BC5749DF90DC07BDE4DFEA207D5485F20F
-:1091E0005AFA47C8F7CE54A4F1F20DAE491AFD2839
-:1091F000DA19E5D09F453CE3CF4E6EFFA51E94F6ED
-:1092000062A25751A2FA66B0BE127AC62017CF6783
-:109210005F03BD86B4FADFD8EF53AEEF6B5716C6C7
-:10922000A18FD1FF237665D9E541753CCACD2A854A
-:109230008D82C7E4997A3DDFEDE2FE47B72B49A75F
-:10924000E7E72ED6D78B60BD49F84C1A92BFA2D55E
-:10925000438A8AF28EF7D728E8A1E0D807562FC8AC
-:10926000DFFF1276D017E9FEB791AE3624A614A31D
-:109270007ED8FAA78A315B61DEFDEF5B7CDBB0BB99
-:109280005D9C3ECA17AD6935C37B4B87E2B4318D17
-:10929000DE5ADB79C90A58EF0792FEDD7C1D0DEE20
-:1092A0008875248C9BD3C0C7CFEBD8AB9835F22DF3
-:1092B000AF8ED73BE4B2E8F45EAF287F26FD0F16F1
-:1092C0006EA92CC5FA7EF326107D391D0AC583735D
-:1092D0009A01004007393EDEBFC31756961745D79F
-:1092E000D966AA2E42BDD09691E443BD30D61D3C2E
-:1092F0008CF4DF70281241304D3ED46346FBAEC281
-:10930000EDFF0ADFCB757A55670ECAD5A4437C7E84
-:10931000ED067A070B59D0F9362E6F55F60E437CC1
-:10932000A0EC80F132D68F21BD24EB67B8849EC8B3
-:1093300060C117C8AE626D8CF0C5681D19EB47930C
-:109340007D2FF119B5A3C64E403BAAF0818879194B
-:10935000B4DBFD58ECF8BC45E81158074BF744D78F
-:10936000118F2FA41E93F52C71FC6849EF4955B15C
-:10937000ED53D000F4BD7C91FB3A5C77C3062BB370
-:109380002951F857B803E9389F9C8EAD0AC246D2DE
-:10939000D706D7D34A2EACEFF65B985365F1E7DBDF
-:1093A000B0F6C54B5668FC2DE89FF0B1D5CAEAB4BB
-:1093B000FA54FA1317A773FD73A73B3002C76DDC8D
-:1093C000B5D98AF8BD65FBE7566DBC7BD03A8608F7
-:1093D0002FA58EFB290DB5F630AEB37C9199F057D1
-:1093E000BFC11A4679D4B0B33362427BFA6EE6430A
-:1093F0007E6FE8E87C2B07E092DBE09FA47AA3FD78
-:10940000E53684159C4F0610610FF979112BEA6738
-:10941000235DA33D8C76C95B099CDF4F943B420AD8
-:10942000C0EF8425D880F54E6427F942055178BFF6
-:10943000DD39EB1D05583AF9055B049F6DA66D59A2
-:1094400076A8D736CEEA433AAA700767A5037C5CB4
-:10945000E64017B64F7327FB5AA0ADD7C626907EBD
-:109460001E221C261BE861F2DD9C4FFE263D45DADC
-:109470007B13500E2D4D4F96F612C9A7B72C7C1DAD
-:109480001B189FEF3E977F01D1ABD345E3E63444F1
-:1094900014B4F78DE346E9C9BFF842E81BEC3C2B56
-:1094A000CAF57A2167CA176D577EABA1837A3064FB
-:1094B000905E72766E55D00F84EF2D956EAACF6CAC
-:1094C000286776F2FD887AF87E9346AEC875C49018
-:1094D0002FB7217C1D877ADEE4F22542F427E76B63
-:1094E000C4E78FD2B91D77259805F4DE1A1AE385F3
-:1094F000FEDE1A9148FD497E37F2E78F049DE7D4DE
-:109500006E57306EE04EE276A39C9FACF745FA8C26
-:10951000F5389FC9553D0487D5B566C29B9C4FA5BC
-:10952000353012FDAF76D1DFBE859F597BA1FCD0CF
-:10953000AF0E103DAE6E57FCE417B41FB0CEC7F8A7
-:109540005CE8972AC663AFE62609DBF2D201D22394
-:109550005777F138C1EAAE4EF37247944E0B8EED59
-:10956000BB11E96C75878D2528883FBE5E239D82DF
-:109570007C21BA67212BED67817C0C913C65C1028F
-:10958000F447A4FCDD27EC4BE6E0EF9F10F396FDDB
-:1095900046E56602D17BC1B109FBEC00CFD53EC5E3
-:1095A00007A612D8DBBC1EF41F21F9CBD808F4CBD8
-:1095B00064FF46F8FD5AC8D518787E3E3D861E9158
-:1095C0007AB5E0F1190C9F127F660177D9EF9E748E
-:1095D000BE9FB527DD4CFD6F28E7F1EB0D16AE3FC2
-:1095E00036B4D8C3C8D76FA75DF98E520C707259C4
-:1095F00023F8DC6F5AD680DFF7E7F079B499D68F7D
-:1096000069E6FAEBF574C25F0AE3F289CBA3875EE1
-:10961000E4F2A421E4203FB12158B382F61FDC0913
-:109620003EB4F759F04DEBFCE4283D18F1EB7D61B9
-:10963000AFD50BDFAFEEE07C10855B5847B720E776
-:1096400008EFFB5C723F2258807005FFBD05E30CFC
-:10965000D27F4F591C08257B07F36BBAF0DF27092F
-:10966000FFDD32C5FE17F5DFEBD7FE5336965765A3
-:10967000BD4B4FC92FE027EAF8EA84F0DB0E08BCA7
-:10968000FF41D04B7D6907F143FD97CDC4478E2A3A
-:109690002E4F1C87F47290B11F8BF53F40FD54266E
-:1096A000755CA9A23FFCF78AB395C59FF7CD4AF335
-:1096B0003F4F45BC74AAB42FC5CE80555F06704D90
-:1096C000103010F52C6E1EF73EF1142002F9D2DC9A
-:1096D0006C3D97FD7BBE7E59E42305F15D2F607DD7
-:1096E0006267C5D4DF613CF1A954DF2858FAF19DC7
-:1096F000F3FEE677D0FEC4F6E93ED4D3EED600D131
-:109700004FBF27C1877143B70A962DD0434BC71B64
-:109710002997E1BED833974C40B999E7E67C79ECBC
-:1097200045752DC267FD3F3C3F0DBFD7879574B48B
-:109730001B4F3CF5F77F46BD58B7BD093D0DD6FA26
-:10974000CCEB64879BC25BF9FBA752C9BE3CFAC451
-:10975000E66908F7D68E56FA7EEC89AD54DEF70F2F
-:10976000CFEFF94FB43702293EAC77ECC5CD3FFAC5
-:109770004FA4F39A141FAEA32168E6FBB692BE8DE8
-:1097800072AB732FF1A9A497AB51EF229C6AB9FC7D
-:1097900091F4FC85D8575A56E1684379F6C5A6E49A
-:1097A000BA58F144BF582FC65C488ED52A144F6B67
-:1097B00003AAC1B8465B229B82CFA4A2883517C6F4
-:1097C00059B8B8731AD93DA1CF5762FD79BB12D8E9
-:1097D000268ABF61F016EC7F2275C6C683183C0C42
-:1097E0007E32F4BEFD2CD8D71F5B309643FDE9ECEA
-:1097F000FF796DEFFE11E5688DBD77AFC71B7DDF8B
-:1098000026E234509FF44ED99AD8F1D02AB743D0EB
-:109810002DD79B395DD5795E921336DF288D5D3A61
-:10982000EC60F32610432CA7AEE74A5CC75563965D
-:109830004E24BAC0381FEA9F9083FA5F8D714AE0C8
-:10984000B3456ECE4F194EE6BE14C6AF3433B703E0
-:109850009F8C7D642139B283FA05FB83EC2AEFEB00
-:109860000B77A03DB2C512CC9E84FDB409BDB59D59
-:10987000CF1BDA3B71BF14FA735E3A81FAE9B1B8D3
-:10988000A87D88B79FB5BD4589CE1728351FF51629
-:10989000F657EA403D13AA25FC78ADB4AE635825CF
-:1098A0009BD65D7CC3F828FF1AE33B28CF701FF8D6
-:1098B0004E77F96DEE49D1A78CFB18E1F9327E871E
-:1098C000757FEBF6D3933D95AED32BF1EC957D0BE5
-:1098D0004F72FDFBEAE7246F1A918E71FCE0973A14
-:1098E000FDBB5CD2F12B9F131D2FDFC5F56FE3AEDF
-:1098F000122BD2EDF1757EF65B30401BC53EEB16A8
-:10990000A57725C5795E497062FCEEA4D037F50FC6
-:109910007C7E18F74747ECCA26BFFEE42B09B5D872
-:10992000CF7E9389E0B97FDBC55B5B15ED3CB93F2A
-:10993000007630916A23D8A9DC0E5EB119FDB3D54B
-:1099400075CC87FCDF68A09FC65D07885EA41D5CA0
-:10995000F0F8DC15DCFE4CF025A0FF3693DBA30C01
-:10996000EC51AC9F3633DC6225FA2A2943FADAB788
-:1099700070CF46D4E38D339913FBDF32CCFF4A2EF0
-:10998000AD476198CFB2C5D23EC30CEDB7547A9DB6
-:10999000004980DB76B27BD918ABD0732BC85E6EE2
-:1099A000CCBADE477C669407AFB490DDD5E84DA411
-:1099B000F95CBD4BB98DDB230EC6E7AF107D5E1D94
-:1099C000BE2C8CFBCABF17F093703C69E9B911E15A
-:1099D00071F2252044F87EF54C4EAF69333B488E3A
-:1099E000BCFDCA2CD2E3922E935FB6913E77999D2F
-:1099F0008A8FF4DA3C9B16AFED16AE97D2849E297F
-:109A00007C80E33722F82922F440C46DD5C75B9CE3
-:109A1000A162D4BBBF17F8273182F25DC893D52B62
-:109A200022C44F0D3B797F6E9BBFE4760DFDBA2BB0
-:109A3000B85E94717FDC07A88E212F7EE7E6FAB12D
-:109A4000E0F1659BD15EBE0AF08E2A25678C90A35B
-:109A5000401708B79CBA00D1C155EE9B7D6A01ED55
-:109A60001F909FD8DF6265B1E23C47851CF5A407D3
-:109A70004A31DEECC94C263BC7A3969B12B05D89E8
-:109A8000E2DBE6A5FD4DB2F3FA3DD9BE6D3A7E0F9D
-:109A9000949AA0DE918C648EE7F0AFCD73C7231F3C
-:109AA0007AA59FAEB3FB06FBDBDC6E9CD31E2A4679
-:109AB0003F44EE5F4838845B126BB5F2B34FC02170
-:109AC0003C96C7F3C1BE7750FCDA09E3A05FBFED57
-:109AD000B227B85FDF4AE31F74F3784625AC0FED79
-:109AE000364F61600DD7A7C9BE58F0B853E079DF93
-:109AF000C21B4BD0AF6CAC71F890DF1E7A55594643
-:109B0000F48CC141F4B7832B080F0CF080FCC082A9
-:109B1000DC2F6D6C0E8463D37B35F15F23F29F42A3
-:109B2000F44EF176A0F730A777AEFFA4DF8FF2B145
-:109B30003AC67EA8942F8DD6DED148C7921F1AA7A9
-:109B4000F58E46B80D559E9CB400FF23FF001C9077
-:109B50007F24BF24EFE67CB2A9C55B8EDF37553288
-:109B600067AB461F19FD259C27FA9D52AE8F7507DE
-:109B70000A3D1807304536621E8594C38DBBEF1B26
-:109B80001D2BCF4DCA61BB99CB377B3829DCAAA1ED
-:109B90002FDCDB4B9E404FCADB495A1B3B2E52E663
-:109BA000718878FDD0F222325097A3BCD996144622
-:109BB0007925E344C67EC778145D3C46FA2DB8BFCC
-:109BC00080F5E77A38BD547AB89CB85E3CE5FC2550
-:109BD000FD7B4DC1CF319F289EFE92EDFE52712B31
-:109BE000398ED4A346FCCBFD115C4F7551FC7AED48
-:109BF0007BB97C32D2E372C1275E5C2BD47B4EEC06
-:109C0000670DC62FEF87D59A75F96F6DA6CEBA5836
-:109C1000F12FB9BFC11E320F29BF6EEF3A9E47F533
-:109C20009CC8A7658BCDBA7C2A87CFDB82F1D3197C
-:109C3000F6821295C6E571ACE469EC6BD4C3C5BB82
-:109C4000DAC7609E9227A0DF1FC9AC4DD4ED3F64F8
-:109C5000075DBA726E5D8EAEFEB0E611BAEFC3D785
-:109C60008ED37D2F084DD0950BDB2ED5D51FD53E3D
-:109C7000439F8FFBC855BAFA63C37375E54D2D1D1D
-:109C8000B588978B9FBA4ED76E86D9692E01B88E4C
-:109C9000EF58A6CF1333C033F5CF6A4C3A7CD2537A
-:109CA00040789D61D6E70B5FB24B0F0F4C8BC3FE24
-:109CB0008A99E86FDA9109E7CA632D66E66F7A65DB
-:109CC000FB82C1F4C0ECBDBE400C3F53D2B92C1B8B
-:109CD000F7B1A4FCB850FA8B374F497FF1BEC78368
-:109CE000DBBB1EB90FC3E16219804BADEF5C70B1F5
-:109CF0009C0F2E0CE092FCFDE162EC6F7D5223E59F
-:109D0000037F84058D7DDC2BF84896178452B91E9D
-:109D10000ACC3B8F1DCDE3C0411BDF9F347EB7676C
-:109D200070B9361AE640F019225F7F26F070281EBF
-:109D30005FAFFD7A7F26CAEF2A467EB3B3B9E56BE3
-:109D4000D45B4BCC1186F4FF9058CF169117FAC80C
-:109D50003A27F5F3A8D87F7C6C9D97DE3FBE6E0C4A
-:109D60003DC3EB7CF47EDBBA29F4DC0EF61C3E9F8F
-:109D70005C5745CFA7D605A8DED3EB6AE9B9735D7A
-:109D800090CF6B10BE5819D93981F498F1D2A52122
-:109D9000754878626A5E4C7D19B71F75F139F3C852
-:109DA000D71E5A34FB4D0DFF666524BB0F630EE3CF
-:109DB000643619F733CFD7FEBB75B5B3DF1C3574E6
-:109DC0003E92F4C4CEA48F8EC5D741913FF9BB8794
-:109DD000CF6E0A15C5875794CE62C3A9C67E3207D7
-:109DE0009DF562B41934ED0F1AF8B826981AD36E9F
-:109DF000A811F4596BE3FBEF8B0CFCFD92F8FE52BB
-:109E000006D7779FC49133576798A43F6FA1FDC0D1
-:109E1000417CF7932B62C1777F8657C7C78B820639
-:109E2000BC1AFAF9C4D23ECC1783CFCED78F5C9F31
-:109E3000B1DDC3195C6EBDF8FF297F7E725332F924
-:109E40000F08378F66FD9FDC94541B2B2EF35A06A8
-:109E5000DF0705EB9C15B8C8D40F59D1561CC3BCFD
-:109E60007C9F77A413E343320F203EBD9A298E4492
-:109E7000305407C315F0E1B51642FFE68171226642
-:109E80001CC7678AEA59CCA9619A731EEA607A8076
-:109E9000F6212BE5EFF4E6D0BEFF05D213531F1BCE
-:109EA00075AE7DBA41ED2F50CEECF881E58CE473B0
-:109EB00076E6C151B1F4642D8E7D29AC63CBD4FB21
-:109EC00049CE9CA7DF0B855FADDA4BFBD64386DF1F
-:109ED0002EF790E2526BED29C50CFCBAEF12F83365
-:109EE0003483F1F3589F2584D1CE3F20E6098EFFBD
-:109EF00025DCAF6E9E8CCF7FCE0A7C9801ED975902
-:109F0000B99F383EC3FF119613C53EB035D3BA1181
-:109F10009FCCC9D7718958C74693371FD7F1A5E29F
-:109F20001B8B7E8AD314F6E1338545C6F3BCBB7028
-:109F300010FDB3F48B13BDE8DF268E66AC87E2E13B
-:109F4000BE048C9B5993FAFF7124F2FBEB268C30F4
-:109F5000B2E79D7CBECF3F924BFB2AE801A17C2853
-:109F6000C6F730F54D688743FB6B59F018CEEFA864
-:109F7000D31E32C1BC8A677FE1C27CA8E7BB67D031
-:109F80003E42E4293564C5730B3D27FEEE6AE8EFD7
-:109F9000921E0BC59B2F612AC9F37A337B00F926E9
-:109FA0001E3C8FFF75ECFCAE2B32B9DC93795BC69F
-:109FB000EF79E2FBF13879C48E4CAE17647E8C45A4
-:109FC000E6C778FCE7CC8FB118F2632CE600C37DBE
-:109FD00060CB407ECC6246F931D08F363FE6F88CBC
-:109FE000D8F3708B79584E27C5E93785DE1F1F716E
-:109FF000EE755A4E27E8F2ACA3ED1DF43E5E7ECE20
-:10A000007831FEF138F9496307FACF66A1746D3BE8
-:10A010002F9FF7C03879F4DD62C8F3897EE7F93DF8
-:10A020001BD2389DECCD72BA9742D74B59AF05E998
-:10A030007489C36DC1F85180F93AE9DC8ED9D2DF59
-:10A040002BF96E04D6337F8176B609242DDAD94BED
-:10A05000D65ABEE8D5C8A96ABFBECCB0BE46EE6E21
-:10A06000CA6234DFC4716328AFEF14F3A63ACF217C
-:10A070003717DB55BB59B3DE4371EC865B05FC0E2D
-:10A0800065C786DF7599DCEE88771EE2D6CC14DDD5
-:10A0900039BDDB9DE7969708DF60BAB67F231EDCEB
-:10A0A000F4FD7C70F6E0E61AC6D1CA159EBFFF1714
-:10A0B00087779A3857C5CF05580C79E89BB2B8FC1A
-:10A0C0008BCE9BE7A17FE40CDC9E8972D1EC1DADA9
-:10A0D0003D07D065F6274D80E72121778C70D99D0B
-:10A0E000C9ED37E3BABB443E7DA2CA9A3B35F0378F
-:10A0F000AEF73941E7B2FE060BDFBF82BF801DF02D
-:10A100007203E372EFE1CC11222F3CCD8CF270315F
-:10A11000EF82DDE07C8BF693249C07C14FC0DD0805
-:10A12000C700F3DE8879DBE783674796FF6184CB5E
-:10A13000D203895694FF37DAFBF7A38FDADB63FA91
-:10A1400078243C3F778C3CBC9DE1FEDB9897F7C1BF
-:10A1500033658A8FE751B09964EF28A15CF5ECC5AF
-:10A1600043B77736A604C7207F7C29F2AEA53EDA36
-:10A1700098736C34E6CF7B5DE5ABB23C1477F7A700
-:10A18000231DBD66E374F408F404E5A63D63B7A29D
-:10A190009E79302B5887F5641E1FF3F78FC63C84D9
-:10A1A0000B8513FC59908ECE07A7273219E1E75093
-:10A1B0004A6C3AF94D1C3A31F2079D2F2BFDE1F81C
-:10A1C00043C253EE5BC8F9D565713A944F093763C2
-:10A1D000FE505D9649D4E3F9880F660508CE7DC32D
-:10A1E000BE3E9C00733F64C8F792CF93421E9D6FA2
-:10A1F000FD12DE3F941C3E94187B7EA6ACA1E1E7E5
-:10A20000879A5FBD9C5F71ECF965660D0D7E01D686
-:10A21000FF59DA0FA0C700CFF58867B6A19FE4E326
-:10A220002157EC79960D799E41CB0FA16F257DB317
-:10A23000D0D23ADAAFCF4A8CB95FBF00FC27F47FA7
-:10A240008CFBF6727F1EE407ADB7C6DE7F633AE291
-:10A250007DA65877068BA4E17EE61E1BC5FF8DEB1D
-:10A26000BF42D011C0AB82E035A79FE2188746C736
-:10A27000960B15C6FA6D7C9C78E70BAECE528674B1
-:10A28000BE80950629FE576E774454C0C36D021FE9
-:10A29000D6DC553EB40FCBB3DE3B88EB04F89F18F9
-:10A2A00080A7269FEFD8BA779C232DF1E576BDFADB
-:10A2B0004259738CF5043DC11BB3347E50FD53EFFE
-:10A2C0003A476AF0359EF59AF8F9E87E93CE2FCE9C
-:10A2D0006417E41757639F988FE00A903E40FD8013
-:10A2E0007A67E3EEA925884CB433309FA73F3991B4
-:10A2F000E4686BCEA563BC1A7886B2A47DA9C6B10A
-:10A300001BFF7BF9FF51BB49D1D9AFD1FECDF45E24
-:10A31000E2A7DCF18F31F111F4F8EF213DE6F26FA5
-:10A32000C4A7117EA17B2F4FA3F30508BFE9D1FE7F
-:10A3300006F01F07CF1D1E7F3BF6D720CED1283257
-:10A340008F6F205E61761EB647E13D54BC248A784B
-:10A350001AD80D8F211D586D821F9983CE874BBB54
-:10A360008519EC1B3686FBB73764BDF7478CF76C55
-:10A370004CE12CBBF14709E4072E519C565C37D8C1
-:10A380001F9FFE1CEA0759E4D3BBC83F9476469250
-:10A390007A3669E8F394FEF2F9F2A9F7A13D06F3E3
-:10A3A000996172D0FEE63E585F36C88D1956FE2C74
-:10A3B0009F055405FDCD50F3BA7B615EDFB2338952
-:10A3C00057C0F3A78CC361CD81DFB9D01F9D61B6A3
-:10A3D0001CD3CA2D63BCE38DAC6437E151C43BBED2
-:10A3E00065737E7D31C2E57217C1A5F8959999DA3A
-:10A3F00078CB40BC43AC635E682997A7063927E554
-:10A4000099C9CEEF11617EE6756650DC88C33DA424
-:10A41000303394AF90657452A07CB9409282ED6164
-:10A42000DD5788275B16CC423983693C381E787F1C
-:10A4300059F86C9DEAF3E273BA1230F3798479DE4D
-:10A44000216BCEC3FA267BAFCACFE7C10C32B0BDB9
-:10A450001C8F9793457943CDA91B6FF20E8E633005
-:10A460004732D9BD5631AFA34E47C804EF6D8EC8F1
-:10A4700051CA4F154F63BCE33B532884F9D977AADF
-:10A48000619A6F128B447A303E61071098288EF0E3
-:10A4900007E403F06E1A719E09CE5391BB18E6399A
-:10A4A000FA152CA71BF491C7B186F29E3D01B3416A
-:10A4B0000F0515E49BCC5AE37BBD7EB2B343741EFB
-:10A4C000488904B2CEA69F3F5E638CD35866701451
-:10A4D000F7DFC2EDDE8F13793B4917E9D95CFF3610
-:10A4E000BAAC8CF25D32EC76B4DB4F261FC12397F9
-:10A4F000A837DA506FD82D7E8287D41FABBB6E652C
-:10A50000889FC65DD50CE5E86F14BEFF19BA41A15E
-:10A510003C05796F436D117B1F5AB2A6EC1134CE06
-:10A52000FC7782373440B9E63D363E02F54AA6074D
-:10A530002AF17E96D6F1CCB71ECAAD09C1675FC2BB
-:10A54000F51C50A99F26712E963167FD4EE87FEBD2
-:10A5500075C37C9B704915FD1B310FA8FF3EE6C4F7
-:10A56000BC9141747A06D607F87F02CB30EFA6156E
-:10A57000C15FDC01F5B3DF633EAA23BEA32F82785F
-:10A5800053043DE0FBE9F0BE49D04D61B7C2F7EF9F
-:10A59000DD36CA9F600733895FE6DBF9384DDDE5BC
-:10A5A000D74E827915F64C24321E09F531BF093396
-:10A5B0000C787E1D237FD9587F24D6F752B48AE7C2
-:10A5C000D5E458E9FE2326E4DC6403BF5D16A57FCD
-:10A5D000FA5E22CA4D421FE9F804FB01FFDC5FC6A8
-:10A5E000B7F3A99D9BF3838FC93FCEB797B2E81FFE
-:10A5F000F65B111D87E4EF4CF16DFFA2D994D73DB6
-:10A60000D91CD98B7C7D9978968827F2B51DE0B846
-:10A61000D0DCBCDF03EB495BCB7C2D38CA626F2BEF
-:10A62000F657CA022AC2B9CC795F2BCE6FEAE20391
-:10A63000E9485F4F6617123D5D6EF715260089B435
-:10A640004EF1F99CF0AA76B14270995F6B0F63FEF0
-:10A65000DAFC81FB7A82050B806F160615718E3E3F
-:10A6600058B058138F95797D0B6CE047C7DA77CED9
-:10A67000E67A5CB66F12E74EE4F76DD90E9E5F99ED
-:10A680007D655336E557F07C67E0FBDBB22745E597
-:10A69000088C4BF928F398DF82EB9A27F856F2FDE5
-:10A6A0007CFFED64B7CE0FE8EDCFDF281CDFA145BE
-:10A6B0000AD9830B6BCF6D9FB664CBFDDE3C27C5FB
-:10A6C000B799D4479CAEA4DC9E8B7A1CE56D15E847
-:10A6D0006D8D7DBCF8CE3369D42EF3C9D56787471D
-:10A6E000CFB93419CEB9348A732E4DBB5A2C1948C0
-:10A6F000EFE29C4B53F7E71BB5F97D124E83CFB9C0
-:10A70000F4535EE3026B782F9EFF59B00AD608F52A
-:10A71000DF10E722DEC4731113A274947C5D4284BF
-:10A72000E7CDF9297F2FCF99E4C37C9336D304CAB0
-:10A73000176A4B49F669F37336B53457623D99276A
-:10A7400024CFB52C88B31FFC9C906B5B149EAF1577
-:10A750005A6427787B5476507B4EDF5318A03CB95F
-:10A76000A66C2F8DB345C41130AF74223CC3608EEC
-:10A77000717CF1F646F900FD6DC0FE2A0A7D941F3A
-:10A780005391CAF3CC3CE98192DB8AA2FDD674F3E3
-:10A79000BCBC9AC0D76FF1FCDAEA5284A7519E4B39
-:10A7A000FA32CA75A0BF7D488FDF99B8DE89CAF733
-:10A7B000C0A29BA0BFBEF7AD943FC7EEF62B1668B4
-:10A7C000F7E2BB4E1F9EA7DB501EA8AEA4EF663A71
-:10A7D000EF9751CB2236F85EFA9E751BE6EDD5B1A8
-:10A7E000762BF65767D05BAB1C6F5A913F576DB70E
-:10A7F00044E99161BEA1AF10055DC3CE41710F92D6
-:10A800003F522E19E9988DD4CB9F12296F412E709B
-:10A810007DB598EB39F6A482F19FBEE423AAF09FA0
-:10A8200049DE4D9242CA20E72775BF4DF6CA3490E3
-:10A830000FE89F29582EA6FA5406F93906F3472F38
-:10A840006389445F83EC0431AFD28179737B48CA5A
-:10A85000C5F2298CE17D06122F300ED1B3DCAF9BFF
-:10A8600084F7F0C0F33231EE9D267F5144413CB174
-:10A87000B0A910ED8820D93B46FBA7CCDE9C6487AD
-:10A88000F54D61ED241727EF7F93E424E0F92CCAFE
-:10A8900099D798C4B3CF8E72A61213FF547CEAF1F5
-:10A8A00034CBF19019E1342BCB888F9019E13ADB4E
-:10A8B0003B084F744EC01F074F7E2947985E8E1489
-:10A8C000B033FC5CF27D6FDD817EEFF9EC900F3DE3
-:10A8D000C1AC1C929F7A7B245E5E5D418EE382F266
-:10A8E000EAFA2CDC4FB894F5AEDCA90CA68B93FBEE
-:10A8F000D7AA591AFA9174B95BE4D92BAF8BBCDD96
-:10A90000D264D27351BDC8F15F264A97225D69F0C7
-:10A910007FC5AE84880AF45622DA5F8AF43021AA11
-:10A9200017232687D70AE36E547C6D6A0CBC67B880
-:10A93000BCA4FF269AFC2AD953CC978E7806BC4F2C
-:10A9400043784DB177B49A619E87ADBE9FA3BF5245
-:10A95000CEBC84F772837EA970D498913F2BEC46CD
-:10A96000FCFA09EF95CE41EF4DDF07EFC311EF522F
-:10A970007F0CC1FE04BC2FCC89B15F180FEFC1EF73
-:10A98000897723BE25DF7726382B1C18D7ADE3F94E
-:10A99000C413DF1FD98AE58CD50574CEA533CDF756
-:10A9A000067D6FE6DF4B7BFC2ADE9F58B806BE4370
-:10A9B000B9B3205081E5A6B50AC9CB491F055BB1E3
-:10A9C0003CF26EFEBD647DF31B780F595388B7DFF0
-:10A9D0007D7423DD2711DE28DA97B75760B9A98D7A
-:10A9E000B7FF2AD91E42FFBAEC60B815DF8F7D8011
-:10A9F000CF43DA75D3059D752A2FBC41EDDA79BBBB
-:10AA00009BDFB227927C1276DA34B1CEE98FF175F2
-:10AA1000BA7F7B559517E8F0A6FE9005E9E0B0A94E
-:10AA2000A18CE4651C7FAB5C69CFC3E72C900B8CD9
-:10AA3000F00DF43982E79B6E83211ECBE17686CC44
-:10AA4000D3C47CF16A0DBE1ECBE17127592FC3C55B
-:10AA5000785EF1A3C964B7CA3CD2C8CF98827100AE
-:10AA60005C23E9D73879A5B30A9B495FCE1A2EF348
-:10AA7000497BCDCB60DC92B37FB832967FFD8418E2
-:10AA8000F788C87F97EFEBC20526F43F3A9178E844
-:10AA90001EB3DAF7D12EE94C63BA7B423A0B78B990
-:10AAA000F3D19A1FB7E5017C4DCDE6100AFD7C85F8
-:10AAB000EE3DB9A68745525306CF7F96994578DE7D
-:10AAC000039FFFCA56EBB64D1A3B7DBE141B978FF2
-:10AAD000223D5223F024E5C57C812FE0EFDDC8DF65
-:10AAE0000BECCD64172E12F2FD1616A638C52D06F6
-:10AAF000FEAE777CF399C984F1303D1FAF86E970D3
-:10AB0000BDD0FFF82700FFBA47929DA8E75777E826
-:10AB1000EBD53DF2FE416E5FE9F9BC4EF27958CFBC
-:10AB2000E76038703EFFD938DA7F91E7FA12ECFD22
-:10AB30009F855874BD03FADDC07F0978CE6F0CFA8B
-:10AB40002D269E5F28CA72DC53ED5C0F87400F0BE9
-:10AB50003F8744EDA943B3C3480F25827F251F9744
-:10AB6000087D3E485F5719FD9887883F268A928462
-:10AB7000BBD4CFD00FE967796E10F4F2FB7EF2EF11
-:10AB8000C1FFC4798ED3F3CB2605E47341D45F01B2
-:10AB9000BC7D8D7803796CE7718A7686F22CAEDD08
-:10ABA000EF5813D3EE074947FB0083EDFD88CE8EA7
-:10ABB00037E22B9E5D3F80AF04B09792D08F67C481
-:10ABC0001FFF88CF21E475809C76E4C690D3D67DA4
-:10ABD000BC5EFFD6048A17C8F8B8E437258FDBD5EA
-:10ABE000EF66F95DB9B8FF20FA3F74EB2CDAAFFEDF
-:10ABF00086F969BF1AF38D7263E44BE07EF5064D6A
-:10AC00009CF4505AECB8F5F05CCEEF4B72F9BAC632
-:10AC10007BFC5E1CEF8895C7C58F248A670ADF57C7
-:10AC2000B83897C7B9978867B9781E1179D8475C43
-:10AC3000FA78BAAC5721C6F9729DDDBE412357BCE4
-:10AC40003FB335A3BEF2148ABCF5359C5EFB5E496A
-:10AC5000DBAABDAFED9ADCF22508474FA1DF9A8D44
-:10AC6000719657B85E6834F75A31BFE41A77702A84
-:10AC70007E6FF432FF0BD88FB7D73A0FE0DC27F6A0
-:10AC8000E9FB2CDCDFE84BE04F39AF6B72AB97E0B0
-:10AC90007AFB6EED25F93050AEEE25FEBF2637402B
-:10ACA000E3F6CD97DF45F9C7BCCC847F582EF882F8
-:10ACB000E2BC31E2BA83E3B8FAFB679AACB1F7972A
-:10ACC000595EB22E3E7B43378F1BDE68671B73E1F4
-:10ACD000FB92EE4CF21FEA5242A39D14C7FBEFC554
-:10ACE0005DFB86F5D0BA3695F7E73F5A4AFBB814B4
-:10ACF000F759DDFD36C9B9D5924FBAF47C522FF021
-:10AD00007BBEFD0F635C7C08FCB32616FFBC8CFA8F
-:10AD1000C91285FF6D220FA9526DA8C0B8D0A91520
-:10AD20008CCEBFDEF6AE4AF474DBB30ADD0721ED4C
-:10AD3000B3D502BEF1D683E707BC1AF981E707BC99
-:10AD40001AFF0CCF0F68CB787E405B1FCF0F68BF18
-:10AD5000E3F901ED773C3FA02D97B0E5AD18676BA7
-:10AD60006A63CEB0979F27D0B6C7F304DA329E2726
-:10AD7000D0B6C7F304DAF229C6E178EA3195E2F4F5
-:10AD800078AE40DBFEE677276621DD7425F03C32A5
-:10AD900016F2F714015C5608B8E079036D7FC753CB
-:10ADA000AE7C8701DDADE85939079F97EC5AA5EBDA
-:10ADB000AF5E6D203A64ED5CEE36C33F243FD52292
-:10ADC00015E7F1ED2E85A517E0FDE106FDD9BD796A
-:10ADD000238A9E5BC2FAF7F54C13AF2D181C977FA0
-:10ADE0003957E421E6B01C6D9C264A070E5F04D754
-:10ADF000FF91EA8B450725ECA2548ACFBCA362ECF5
-:10AE0000817DC59AB75CAE68E2F70678D8B2F4F4F3
-:10AE100090E0D5D343D2183D3D24FBF4F4903A455D
-:10AE20004F0F69FE71E7846F7A959E3E8CF09D020C
-:10AE3000FF207C27E0CD9018578275629CF72F0584
-:10AE4000DF2F72C5BE8780EFB7ECF20A87973ED737
-:10AE5000D8CBA2F649E93BCDB4496B8C7B4A384A42
-:10AE60003B41C62F2731EEA7DBF1BC6521DA01DCBF
-:10AE70007F43FD8F7C7ED8CAFD36A420949337B1E2
-:10AE800020C9A39B0CFAFF66C74356D4FF83D60B99
-:10AE90001617DE1B685C2FDA514C134F32EA7FA580
-:10AEA0005B892417E372BBA55C0E9E2563C7AF0CBC
-:10AEB000455EFCDEE1B7E579681C662FD3C57B6390
-:10AEC000DA73721E122E727C1B6B56B3909EC718DB
-:10AED000ED2FBDBF2CFD6BEA54138F96FEB1F44FDE
-:10AEE0008C7056871790DD35D129FDE29EEBF1BDC0
-:10AEF000F4878D7EE8F9F6A5E68594DE9F1744ED8C
-:10AF0000C92BC4739E8817C1B27EFB6FD0F872C57F
-:10AF10003B0CC79BBBFB220FD2CB46A59919E6770A
-:10AF2000F055E84735F5A7F3F84B50B75FF5B6D2C3
-:10AF30004BF35EC0FCF7E0B351C4D31ABBDEA67D71
-:10AF4000D4C62E1E2F60BBF47831DAFBAB5887B520
-:10AF500040196CEF37B01EEACF68DF0FA293F3E819
-:10AF6000F18E3C79DF16CF1760422ED50978C5F3F4
-:10AF70000BCC08E0A9D1FB3B811FE6E54D8AE6D169
-:10AF800066B8C08F51310FC36B8D9527C5F0721510
-:10AF9000B049973B6A484E2C6F1B1497B0123FB5CF
-:10AFA0009F7B7DD20EB81F7C377C96E67979DC20BA
-:10AFB00071CE3B7EFC5CDA93AF3DFFD164E5E70EDA
-:10AFC00059B3FE7CFEDA3C933C3FA50E65FD83E160
-:10AFD000FAFDF2F265FE01C0EF2E2DFCE43E825C2C
-:10AFE000CFEF27F53C89F1433579A61DFD5AAF2BEC
-:10AFF000D882F5871DEC3DACA03C7378293FE4E492
-:10B00000AEA31FA3FF2ED7C758EF16BCDFB66E97AF
-:10B010004AFE60DDAE37C82E8AEFEFB50FDCA32005
-:10B02000F6377E126B5E32AFB9522D4AEDD5D8E9B4
-:10B030004B851F307978E0216C57FA615E0ACED7D4
-:10B0400032A283EEC5EABF83DBC16E95CD44F881A1
-:10B05000DEE37ADF61A67D077752484D413B6E29DA
-:10B06000E3F7D0F99A7D482AEAB0228AD366DCA1B8
-:10B0700006D0FEFE74CDF2343CAF9C91BC22AD10E4
-:10B080009ED36DFC5E9A0CC514E0E74E97A5E13D9A
-:10B090002037D8F8BE7CC15F27450A81DF5EB7F252
-:10B0A000FB46DD4941BABFA03F4DA5F91C5B074BEC
-:10B0B0001B85FB1EDF4CC47B0772CE3826E07CB2BA
-:10B0C000C5BD163FCAE3F7DC1C7FF6BB89E8AFAA13
-:10B0D000671D74BE5DD29FBB30B6BFB242C0A3D164
-:10B0E000C3F3DE4F0AFBF190D86F9579F06BC43E45
-:10B0F000E0A1D103F78379302FA431C19FBA10E3C7
-:10B10000110754CA6BFFC6E94F4D23BB99E7B3AF94
-:10B1100011F6C34991F7B966F68C4CF42FE2E54B72
-:10B120001FC8E376EF0F755FA5CC3F8D0B873433D7
-:10B13000335F42F72E05CE55EFD53FAB31E1795A5B
-:10B140007C8F9737DF97A7E8F2E21B312F1E5EADA9
-:10B1500079A53C939D235FBA11EF23D7E4D7A09F35
-:10B1600086EB6BC4FBC8E99ED213744F07F683F7D6
-:10B17000869DEFDEC815621E8D984F9EAE7DCFF97D
-:10B1800039DABF9BBE3F2DE0F6F43BA6AA6D31E64F
-:10B1900099378CCBA7711E7300F7252F8EF07B3F5C
-:10B1A000E3D593E7B8E3CDAB6B46EF8D386FCCCFEB
-:10B1B0008C355ECA304E2772BE5DAEDE9501BE9FF5
-:10B1C00037BA3A595376F6E7CFD5C8D7D9023F5D9B
-:10B1D00057F5E6D37D00B3B9FF1A0FCF65E66605D4
-:10B1E000E190E00A06D11E91F715E37DC63CCF231E
-:10B1F000744E7C47E1ACEACE1F0C86B395BECBFE05
-:10B20000A4DC39FA884A72E7E807821F99DFA19423
-:10B21000A1BEE27C7594F1B8EED176FEFB1FCB8225
-:10B22000A02B407E2CDD5E3F070F1FAFDC3171236A
-:10B230008A7F7C7F37C89FA5598C4D83E7B20DFA72
-:10B24000FDB16FD903A4E7563C60D467012BCAD97E
-:10B25000950FE9EBD7B107BE46FBA0CE60F76608B5
-:10B26000BD6BB47F670C13F66F192BBB90734E8FB9
-:10B2700030FFEC61A4FFF97EDB24B19F6EACFFBC14
-:10B2800097D3C36D3BFE60C59F048AD7EF319017FB
-:10B2900023A1DF13EB9CF45C32CC5F330CDA350D69
-:10B2A0000B2EC471FA0E70389F6A38B592E2D2B58F
-:10B2B000DC0EB0E1252BF09FB6EBEDE447DF8BF71A
-:10B2C0008C019C6D366E5F48BB4A556F57F1275B0A
-:10B2D000A6FE6E451AAECFFDCCAC2AF43F3CCF247F
-:10B2E000F9111F9BCAFD2528BF37553B689F78ABD6
-:10B2F00089DF4368B7F1FDB9F0D353F7613878645B
-:10B30000C7E619E86738BBF746302ED166E2FBAFD7
-:10B310006DD398B8C79A8FD7D45DDD89F3CAAF01D2
-:10B32000790FFD6D2AF0973835FD33612F350A5CB2
-:10B33000F4BD76D14FF1DEAB9FBF43E62AAC730478
-:10B34000C5BFC6314E3732BF847E1B43132F3A012F
-:10B35000FA8769CE3F8FEB50229614BA5F8FE2D8FE
-:10B360000DEB2319D7A3FEFC25DFAF95F373BF9E2A
-:10B370003D03E3FD529F5E8FF96D18071676EF22AD
-:10B3800026FFF87E41ADA0EB45C2DEBD3E89C37904
-:10B3900019F3D1F9ABEBEC2C05E3CBD757744CA2E6
-:10B3A000FBAFEB2D6968AFC8B8773CBCC78BCF3417
-:10B3B0003E99CCEFCB51FA476327C73006521ACDDE
-:10B3C000B737F6B36398E0E7D1C24E1BC9FCB8CFDC
-:10B3D000D2B8E722CAC7B725F27D35906F76C4EBA5
-:10B3E0007ED4E7B0EE5B5E4D88F07DE3B0B81787A2
-:10B3F00085683F664F26ED2BB80BFDB4EF7ED2D2A9
-:10B400009B4FF200E49702BA73CFB04FAE31E3FD29
-:10B410002039604741F9F82F0E5F83BFCFD238A2A1
-:10B420007725DE179EFEF8595E1ED77B18CBC31E0C
-:10B430004FBC96CA137A57AA509EF278D6B5D41E3E
-:10B440001D2820ACCAC7875F8BE7FC8E89F825F3DF
-:10B45000F5D23D418DBB2F3269E38325F95C4E1F48
-:10B460004BE0F58E15B0257311DE637A476B7F379D
-:10B47000C1932FED526E97C975CA762C2B76FFEFCC
-:10B480000B3D708BB8DF677A126B4BE0FB1521B474
-:10B49000AFDEECBE88E0F2C2309780572FDDDB28AC
-:10B4A000FB319EEF97E3AE42BD8D72DDA23F4FF4BC
-:10B4B0001BA12F609C0D344E91BF04EFE5699C9B4E
-:10B4C000578278037C9905BECCDC0FDC4A78C67EB7
-:10B4D000D38A498F4CC43CB137CF40FD82E8BC8D44
-:10B4E000F471588C734B2BDF67EA4F2B243A9A9EEA
-:10B4F000C4ED3F560AF003393645C0AD245F9CE3E6
-:10B5000019C043A642FDB70AF8E5F1FA17BADED32F
-:10B510003FD07A3578F263DEF19BBBC6129EA60C53
-:10B52000D0C1665D3FC75A0CEDA6F0BC94465721CA
-:10B53000B5BB57DCB32FEF2DC67605D06E7A45FF2D
-:10B5400044E407796F1B0B4D2367BD41488B817B1A
-:10B55000D83A787E0A1BE9E7F711CD9D532AD6E742
-:10B5600014EB736AEFA51BE0C38FFAF36B34F75249
-:10B57000CBF703701FE8AF6882E84FC7CFB1FA433B
-:10B58000BE88878F71F97F617CC8791AE0390067BE
-:10B59000C3FC243C918FA95D919E9FE43C87E59B71
-:10B5A00084BF6DE0E782EF399EC8EF5FFD37221F51
-:10B5B000D2ABA7E7D55D0526DC3F95EDDA3A5A0216
-:10B5C00028E765BCDBD6551D42FDD7D45D4E799B7F
-:10B5D000AB7FF5ECCB2168BFEAF987533099F6A829
-:10B5E000B93D03EDDC861DF7A4F871BFC41C4A41C8
-:10B5F000F97934AC56C53A0F181278907654A3D026
-:10B6000037C79EBEFF1A84C77FECB038518F363DD6
-:10B61000658BD8280E720BD95150FE9C97EFFD1AFE
-:10B62000FDD2A65D7A3B69D53F3C9CE1257A0AE5CF
-:10B630009AF08C0B8BE43278366EB7F8226E1E4F80
-:10B6400084615813EBDF88F333B6C7799C06BC37A7
-:10B6500075A84BF13CAFF13B4812B2C39ABAEE2742
-:10B66000BBAB491B67003CD4C5B1BB6ECDD7E75B14
-:10B670004BB8B0B087EC9AD65FFEACF87307DEA784
-:10B68000F94F294A91565FAE27389DEA58FEF7BB1D
-:10B69000BDF1F5EA49B40B6CDA761CAFDE5D0AED5C
-:10B6A00049B06EFE6CB04452D0CF6FD86AF181E6DB
-:10B6B000650DCF3EF124EE87B04F6C74FF41FDB3B2
-:10B6C000FB3FBE14CAF59D16F71C3E7D879211C53F
-:10B6D0004F9397DB27121FAB5EDC4FF70CE27BB476
-:10B6E0006B255EEA3BF75AD9F8C1F0ABE8D82B7E60
-:10B6F00077C1809F8ECFAFA4FB3C7FF99D15E9FAFF
-:10B70000E81E8565160C6E5FB7757F0AD21FC209E9
-:10B71000FD4B89A701BC0DC257E49ADDA5548FE209
-:10B720001AF1F036379FF178D0AF9E7D0E7F07B0CB
-:10B73000EE37361FAEBFEEB9DB53701D5F999B39F4
-:10B740007DFFE29E0C3F8C5B67096538E9C9DFD756
-:10B750003D7E07D1DDCD07EEC8E0BFA7E1CF364D76
-:10B76000A17566E3FA6E7A6C3EAD6F250B12DDD5DE
-:10B77000FD82C727BE15BFC760C4E769C11F5F6DE3
-:10B78000B3E18F64B0AF30111DF3083F50459EEF19
-:10B79000AD4C7B8F0558DC54FE56C407DE1FD0032A
-:10B7A000CCCE3471D9A6EDF7F6207E8E0DF367E28C
-:10B7B000BE1AC02124E0A5E0FDBAEA81CA4C8E1F62
-:10B7C000E635CBB832D8DF15F81EEBF758FC09C5C3
-:10B7D000BA7662BF9E8F2FE31330EF44DCF7FB2A6B
-:10B7E00023F6B9ADD1C31521DF580FD3D2573C7E14
-:10B7F000DF7E1FD1D5371F71BE690C5757D1F71E99
-:10B800004B048F163786F7D628240F6CBAFB9F0699
-:10B81000E862BB45F0B3FE3BCCD3AC68E1BB87E745
-:10B82000D5AE7CC8A6BB0F214A37D6E8FB82287F5D
-:10B830004A3FEA66C1FFC6F51AE5C11F0CF2803D1A
-:10B84000E619D2BD320D96F0938F22FF02BFA29F60
-:10B85000D9F0AC85FCFCE33BDFF8F83AA0F3E31D3C
-:10B86000926FF572D5C8B7752F4C62B1F8F6B8C3B0
-:10B87000C762F22DBC8FC9B78EE83E8D97FD7072FE
-:10B88000F5E63872356FB8F11C4B512AE6BA1F7BCA
-:10B89000BA7E38C5050C7095FEAC515EBE9CEF8D2E
-:10B8A000292F195E41A581A3849FA4C755CFACA6BB
-:10B8B0007106E856D2A5A4DB01BA1C945FA983A344
-:10B8C000F1FB17288F2645F16E590F7E0ADAB1AFCA
-:10B8D000A9F43B287D30978D00F7BE9D05B40F7A03
-:10B8E0008FB0F3FB9CFD2918D7BB47F815FD184F07
-:10B8F0004C8DBEEF4F10790381FE94348D5DF47949
-:10B90000B79A82765C6F38F6EFC9CA7B2A7BE3FC74
-:10B91000DEAC3CBF54A93AF2D7629CB69DEF4FAE65
-:10B9200068599882F18CBEEE42FA3DA19BDE057FFC
-:10B9300017E6DB27E39A21BF39BB2C7ABFE9111642
-:10B94000A2FDCAE5DDF5B45F688C83AC74D4A4E2D3
-:10B950007EA0310E7233E641611EF263FAF7AB301E
-:10B960003E827832D05310E9297B303DAD1C2EF653
-:10B970005F4B58896EFF55C8B54AB5E8A7689FF474
-:10B9800081DF8EF120A616FD1AF5E9B7E8C723037B
-:10B99000843C44A7F5C12332CF8AE85AD29DD17F97
-:10B9A000373E4FBCF469199E076A78F9DF8A7F0E2B
-:10B9B000CF132F7F32FA552CFFEA5FF3FF8D0DAEC8
-:10B9C0005FB1E78FE4AFF4EDB1D17CFAF6BC9D7FB7
-:10B9D000179677DB7C38DFBEF536FE7BD07B92E9AD
-:10B9E000DEE9BE613CCED6FADA77C5BDA4A7361033
-:10B9F000DEFE6E38BF2FF654F77F7D86F7AB9EEAEA
-:10BA0000B67931EED0B42789FCF0A6DD09744F7CFD
-:10BA1000DF6BDF9569E345FFDDF5348AF3167DC9F9
-:10BA2000AC16F35BFAD2B8BFD6F4EAD4275A0AD0E0
-:10BA30002EDD4BF71657BCFEA762943F7D2F70BBDF
-:10BA400002FCF3C77113F117C3BB7F6A998AE78DB4
-:10BA500018F9D553BD7FBA36E48805170E873E80A6
-:10BA600003AE0BE042F775C78347D7707E0FFFFF29
-:10BA70003E787C4DFE4243F764E2A3285C14FEFB53
-:10BA800023DDC961BB42EBE7EFF77C578C76D2F13F
-:10BA90008E16D2FBE75BF787FF6BE9E0FBAE5B89B5
-:10BAA0000C65DDA7FED7AE9BD3FFDAE15C3F19F949
-:10BAB00060309DFFEAAFA9FC5CB28FE66BE0FFFF50
-:10BAC00007ABA359F3008000000000001F8B0800A3
-:10BAD00000000000000BCD3C0B7814D5B9FFECCC76
-:10BAE0003E926CC22604084260F2244A1E0B791072
-:10BAF0001EA99B842008E206A4A2222EF8E015923B
-:10BB000008B6C66ACD622202F5B6516CAF6DD16F30
-:10BB10004141DADA6B8A41B1025D10115AAAAB8257
-:10BB2000A246BA52AB50031B41052ABDDEFFFFCF30
-:10BB30004CB233243CFCAEDFD7E423C733E7CC3927
-:10BB4000FFFB75CE18498599ADB9004DDB4EE587F1
-:10BB5000B1056806280648526D00FD004E6CFDFADE
-:10BB600090944CAD5D853480BAED710045D8FE31BE
-:10BB70002600124064DBA9129F13E01BFAB912A041
-:10BB8000A3119718D6DD37B71D9B3F2CB917A7D443
-:10BB9000BCF041FEAFB1ED78E1BDEC97A9FFE2BB8F
-:10BBA000433EC0B6D606BE565C2F120F3337213C3B
-:10BBB0009144F000EE5FF7F2E8A796E1FE8BDB3EE2
-:10BBC0009F4DFBD76C1D0532F62BFFF4EFFC30CDFB
-:10BBD000DF2479C4F3F88003E1AADC7E463CDF7EF3
-:10BBE0002A1FB0FD6C93149413B0FF807D7E80D625
-:10BBF000ED05EF118477F17F22DE3B6CB7E278C36D
-:10BC00005095E1EBC67B870DF208DFBDB3697E641A
-:10BC10007BBCCB9E46F0FD7B0844E17F21BCBDFF91
-:10BC2000B1FC3E3FDE007E86DB2A7B1DE908DFC3D8
-:10BC3000100CA9D83E0830B1D5792E3C3FA6C16280
-:10BC40007A0F42D01F4006F123272F9C0209D4AE61
-:10BC5000FA5CCEA7F7A74D4C4338FCAAC5BD5EA53C
-:10BC60001916A6C38AC1EEC02A840B14EFFCB5D8FE
-:10BC7000B70EAD71AFE215EE042801F881435BAF5A
-:10BC8000FF948912AED7B40CE1C2759AFA595C4D93
-:10BC9000B88EA25A82F67C6E3FA2F6A1FE57EFA1A3
-:10BCA0007D15A70D82DABBDFE03F27603F47EBE35E
-:10BCB0007EB199517DFC17033B5D0AEE1FE35620D0
-:10BCC0008028D921EA7D9C7F93EA62BAC442C0EF02
-:10BCD000725E3A9D7E4F83FD7AA793993E3ADDCE00
-:10BCE000A1138083DE57E8BF08FFE45521D2430546
-:10BCF000147F58E0237D23113DDD290E5CCFDAE768
-:10BD00000EF72A899FAB4A89F69E85FE2C31D01703
-:10BD1000E9E789C9EFA673D47A8CBF99CE974A5FB9
-:10BD20009D2F31308DF91C33D8E90E20FC0FAA82EB
-:10BD3000EE0F22DD25A99BBE3ADDCC7CF093EC14FE
-:10BD400077D3BFBB1DE7FA64383312BE41E2FA2B4A
-:10BD500020A71ED7A992C785FDB8FE89D238B79D06
-:10BD6000F44582A03412DBF2FE15807874A4DA1454
-:10BD70006ACB3A11A72878AF3CED00250ABF72487C
-:10BD800034F43B52B3F9FD4AC740C37B1D034B1D3E
-:10BD9000F4BCCA956698FF464C423E14D07B1326ED
-:10BDA000D2F85529971BDE9B7AB863CD1C6CAF95F2
-:10BDB000C245241C1D7B675510BD26A9230CF3B674
-:10BDC000A059217DEEAC9203EB901ED552B07F3E80
-:10BDD000D26D72CE68237C128C273C6B2C285A388B
-:10BDE000EF1A77B961FCDAD2498675AB3DD5867E0C
-:10BDF0004DC357A0F40518DB70169442B4E3C15646
-:10BE0000C3FB857BB618E627EC03391EDB11FBD597
-:10BE1000266A0BDB434924BEB6BE0EBFA50F8A704F
-:10BE2000D85B89E840C991FA57A86D70203DF0F9B8
-:10BE3000A918D122BF58CEFD8762024D08EF294BC9
-:10BE4000C04774B85B0EE4501B3BE88E7C48073853
-:10BE50009AF2B0DC87E0075FA78A7230FA8B401352
-:10BE6000F5AF3CDB2AFBC80E6F94FDB602E2FB94F3
-:10BE7000B8BF92DD6D9580F85EE3B47802E4B792C6
-:10BE80005AF39746C9D7673F845BBCB9E7EAEB8BA7
-:10BE900059E596345CBF39C5D3B283EC66C587B328
-:10BEA000E5F473E7814BE90CEB7449A7F7BC4583D4
-:10BEB000511EE5F8F10EB2EBB19532E30557590387
-:10BEC000EB719DE516778CA6FCEC5F5D13AC6B49BE
-:10BED000AFD7A409FB10FB175025843FB6AF4FCE58
-:10BEE000A3F77E26C17AE8DEEFD652603CB2D22CB0
-:10BEF000420F1457BF9BF3E8FD787EBFA454D011C6
-:10BF0000A6580259B864C241F76E2BF657E7EC7792
-:10BF10009119689B72D82F235DDA0E86CA24D4A5A6
-:10BF2000010F979FCC14F3210BFB6D39E3E3F2D89B
-:10BF30008FE558C8CE2C41B347766647D93339E4EC
-:10BF400027965C7EC500E8C1BEE96DC26909D4C20E
-:10BF5000EEFE9A3495E14A50C2407A9D705AE171E2
-:10BF600068C8B690FDD1D74F98A5BEBB94E0D86302
-:10BF7000852CDA5EF12C223C565DD1AEAE623C04DB
-:10BF8000DE00E1142FA2FA4FF4932A315609A7DC00
-:10BF90001C7F2E1CFFDC589CA8221E7DCBDD896EE9
-:10BFA0006A7F8F441FC374F7131D7E4A7F2EA3DE62
-:10BFB000DAD0781CDF4836518C0701E57A954D1BA5
-:10BFC000279382FDBE9236EE5FEB1D4F7C958DF37D
-:10BFD0000BD2BBE67B1C29DDEB7BD7AE0D35F748DA
-:10BFE0004F3BFBE55513AC01BB7431748DBB005D59
-:10BFF00013045DCFA2F5C77DEE72887D3E96D421F5
-:10C00000246FAB2D68053200F6BB7CD7935CC7CAA2
-:10C01000C13C7A3E37C133A00CE5AFCDE619720FB3
-:10C02000D9956D31EE75F85EF59D9F3DDE407A3D08
-:10C03000F59F39CD24378A276E24EE53E7FA8AED2F
-:10C0400041959CDB87E29D2E3A923CE39E3FB5747E
-:10C05000F7C93E2474D3D59389E3ABA2E8EC709082
-:10C06000FD12FD47D3DABC4CA7DB1C4CA7A59A4EAA
-:10C070003527428B05F5E1A46BC3F7491E4E6EB41C
-:10C0800002C54D6D3448FE32C7C17A05C9E1946AD4
-:10C09000D483BC372D5E8ACBDA513E3C241FF5D9C0
-:10C0A00086F54E8E7B37290FDF3B99AC24117D1628
-:10C0B000866D4CB79B1508DAD15EB625DF5659CE92
-:10C0C000FAA1F278ABB6CE6B599EFBD2D8EF8C7743
-:10C0D0007D8278499E31F237C37BE71779D04F7460
-:10C0E000FB8874AE2334937A9783E6724780E2CC60
-:10C0F000BAD265B9E41F9624660F00C4A36EBCC40F
-:10C10000FEB6AEE10BA6BBBEBE725A06B56F777F18
-:10C110007C86CAF640513C2C0FCA691B8FD7349CD1
-:10C12000643B8EE0A491DE742C13F6AEC50AB754BE
-:10C13000635BF3BFF22DD538BF06430CF617B0D3BF
-:10C14000B624CA1E42EBE75D76BF0079B77ACA5BB8
-:10C15000B16467AB25D70C401C8EA6BBAA95D1D87D
-:10C160008F71CD90B0DFB6EE8C97FBA9AE1916ECAF
-:10C17000EF4ABB498C0F74FDDCE206F87CDD5DA262
-:10C180009FE63A40FD0FD31EA95606623F5EC8C126
-:10C190006FD26AABFDB9245F4EA6CB891571AC1F77
-:10C1A000BDD1795EC3CB06BA9C332E4BB778C96E2E
-:10C1B000CC1476F1D8CA416B391ECA0C65D39E5B8C
-:10C1C000D344FCDA1F79538AFF5E45BD77201D9268
-:10C1D00033C063C1F9C92FA23FA2F91F878610FDA2
-:10C1E000E6BD181394901F8B9F78C546FE68AEACD1
-:10C1F00066935EBD3FCCB793E4E3787C88FBF31A8B
-:10C20000B6335C29592E61A75D9DB95E94CFF9D0F4
-:10C2100062A3F1F9A01C26BF614161A6B866A173B3
-:10C22000978DE2B2854F5B0F87A3FCEA22081F229D
-:10C230003DAD79D67A381CE57F81DE8F92AFC3168B
-:10C240000187A2D163AE1C9A6D13701D20B816270A
-:10C25000617C2F93BB08F5F7715C5493C379494A0D
-:10C260002C90DC2DBFECFD7C5F0F7EB0B511FD3E48
-:10C27000AADCA6C62DDCAEC135C9EE0C50C23637DD
-:10C28000AE53ABD9E592D0611B44BD7F42A36B9FF7
-:10C290002D128FEBF6A27B3C5ED025D733C2827085
-:10C2A0002C9EB66F1CF145E7E79571D01A93C47CBC
-:10C2B000716B7C71135F74FA233D0B157C6FD7593A
-:10C2C0007C2FAD27B9D0E92FE06D8B15F6A27373E3
-:10C2D0000CC74D66F8E3D205BC3A1E43D3CF0FFF1F
-:10C2E000D0F4EF06FEA1E9428FCD78E87AAC3FD7D3
-:10C2F000F5D88CB70EF7A5CB59C8763172A6DB9965
-:10C300005AF0E5D0FABA5DD1E9ACC3A9D3AB8DF24E
-:10C31000A11EE0541A5E32E0A3842A28898071E9C4
-:10C32000E9C28EB54E02E283D2B095E75D2A3EBAED
-:10C33000BDED0D2FDDCE9AF1D3EDAD8EA76E7775E5
-:10C340007CCBD090B03DC4349EF2AC2B4FFB0C7133
-:10C3500070392C30C4C9958E3B0DFD2AD73D86F926
-:10C3600057A52C338C4F52571AC627E73C62E85F1B
-:10C37000E3FEA5298E5F6B8AE37F63181F170E719A
-:10C38000DCFD7AE344509047DF3BD2C9F177B0D16E
-:10C39000C5FD9D8D29DCEE6A5459BF7737E670BB29
-:10C3A000A7D1CDCFFFDC58CAEDBE460FB7A1462FAF
-:10C3B000B766BB30F5F9EB15CA574A432D9564CAE9
-:10C3C0007764F87E928EF47BC312688A473A8D6A4E
-:10C3D00017F139CC37FBE35387EE25BFEEB2B9C96D
-:10C3E0001F36EF182DA93DC47309E8EF3C51F292B6
-:10C3F00030250C1E8A7BD03DF7245F2DE916964729
-:10C4000032FB807A37D301D664D4B79933257713BA
-:10C41000F0733F24711BF4E1F85405FCE4FFAB9D7D
-:10C420004AD09EC0A0791D08E70C0126D8699CFC63
-:10C4300077725F85E2D6EBE821C22B7B64F81E3E63
-:10C440009F51FA97339437DFE86CB5929CDCB0E7E4
-:10C450008163F7E23834FB8B493FBAE206FFFB9673
-:10C460004B891B5A28AE443A462477C843F14EA262
-:10C47000E28ECE07F4F6B674910F4C6DF2CB0948FC
-:10C48000CFCE3781E3385D1F11BF1504BFAE17D57E
-:10C490002E25382C81FCFD239534BF66BFCA74D18C
-:10C4A000F542D7033D0FD4F5A04A7EB689E69F3802
-:10C4B000089C4F8FEAF01D799EF034C59DA59D2DF7
-:10C4C0009594975D286F1C73BAF5159AB7BDD1C7BF
-:10C4D00072B4B57126B7C1C6F99A7CD6737F57631B
-:10C4E00003F77737FAB9DDD3B84293CF161EDFD7FB
-:10C4F000F838F75F6F0C6872BA919F8FCF10FEF714
-:10C500008B50E50092BF17D3451D071CE59C478063
-:10C5100022DA8B95939A9497453C65920FB35CE829
-:10C52000F200683724A4D78DE867C93FDC04FEBC5D
-:10C5300039D8CE9CD7621D2B7D7BB958E86CE6F8C4
-:10C54000C36C0F174090EDDDB9F65DC4FF17B2EF75
-:10C5500032E6ABE4AF74FBB718C2BC9E5DBED34DF0
-:10C56000F594EFCEAFB834BF0273687E57DE1DDBA3
-:10C570003E5BB65C38EF2E1A2CF8AAE7DD183F02B6
-:10C58000F9E54840E6B87A7E5A4B02E7DDA59D09F9
-:10C5900014072CD826333F30CF540622DFE6697CBF
-:10C5A000EB80E03BC49779E3E6715D6EFE1A233EB3
-:10C5B0000B9DD7F509AA3DC6693DE2590B0F7F4E89
-:10C5C000F5B95A8D5EFC1CE16968BF61D2AEA879ED
-:10C5D0003119F1C99FC49142C128A207C2EF0E923E
-:10C5E0009EED9759CF7A938BE3989F909C9F6A9C7E
-:10C5F000396917CAFDF1B38D9C7F25653CF2887FB0
-:10C60000DC77C7AFB559DEA1199C0F856DA43F3A01
-:10C61000FF96938D44B8975738029468478A5D0A0D
-:10C62000ED1F913C723CF1E323702F43FA956F7D2F
-:10C63000ED20E947B9C3C9E708884447343F47EFCD
-:10C64000F7353971DEA87D1E99C2F7E25DE1269AC1
-:10C65000A6FB1BDDFF8CEDE8947D5C17C8643D02F2
-:10C66000CC25BEC9B8783D32E79B4D946FA2413AC4
-:10C67000E99CC0F09E0C829B9E77D7B544BD69ECC7
-:10C68000598F9C80F02DD7F2C3D11F7B198E6A87FA
-:10C69000CA7268D7F2497B8A053C517474D97C1BF5
-:10C6A000A9FE097F8CE13AAF19BEC919C28EAB4908
-:10C6B000DEC94C5FA79A4D794395DCB1E1D7240FD1
-:10C6C0006D716E3BBE67B6B7BA7DEB2D6EAF739DD5
-:10C6D000EC318ED4DB3A8B38371859A91652FE4705
-:10C6E000F125E5857A9E689EEFCBAA989DD18FEBC8
-:10C6F000AB210FC1E5B29C574EEB1A3E3F6F9EA691
-:10C70000EF5FB7ADD83537AA0EB226433F5F505C16
-:10C710009F38BAF976B1FC2DEB9C69F03FFFE9F147
-:10C72000DA540C7324D4A13C2920E20810F1C42C63
-:10C7300008713B1B3AB9F5A124513B17DCDCDE063E
-:10C740005E6EBFCEF4AD26B989583BFB931E1F7BAE
-:10C75000E1EB5C928B63DF1BEB4A53BBFDABEE6FEF
-:10C760002FD5AFC6D2F9520FF2B041935BDD6EF711
-:10C77000CA1F93DD8E8C40FB807046368B73B148A8
-:10C780007C6C80CE0174FB007E63BCA8DB8BC2593D
-:10C79000EE37B85EB84FE6BAA5D97E5429228F0786
-:10C7A000C59D43F5517DFF260BCC2739DB88ED1F56
-:10C7B000108F3EB3C28A1A85CF760D8FF21BC60347
-:10C7C000E52F535D223FAC724032E57370F664EEA4
-:10C7D0000C340453291E45791E95E4F913D1DBFF6F
-:10C7E000D0B8443E7F20FB3314F9F79138B7810568
-:10C7F00052200BE9B1A54DF4F36E4F64FC6E82201C
-:10C80000F3F166085B09FF5B00D8EECE0195DB5BB8
-:10C81000C1C3FCC495E3F2D10EDDDEA68C5C857845
-:10C82000162475A6937EE68D7E2F4942B8F229FE26
-:10C8300075726D6605C5293A1E964C81C765999E2D
-:10C84000B709BE82A4D0AAD514176EB600C5859FBD
-:10C850008EBEE70E88F2AB2559150769DE73923854
-:10C860002FF46FB38BBA1A74F6F746C5E35F6756B9
-:10C870001E22BDFF07C1C6F9EF2A3E47AA7609DA94
-:10C88000C3F87E4C037C6F8837AF27FDF4B37D2C53
-:10C89000205A8A3AA11F4A795FEE7FF5D417D5CD89
-:10C8A000021F3FC5632559BE08ED5760435348F04A
-:10C8B0003F610FACE3B8A97E08D52FE63D69B7907C
-:10C8C0001F7F0FED309D9B7ED0E8E0F643CC6FA834
-:10C8D000FD1BE637D47E84F90DB57FC7FC86DADB15
-:10C8E0004F8F402102F861A6E77F33CE8347EF7672
-:10C8F00046E0119160664FE77DA73244FE91DFF676
-:10C90000F1037124075B6437C969DE6685EB10C7E4
-:10C91000B78E0AC869D174F5C565221CF95BDE7E45
-:10C92000746C11BDA7B8249C7F7CCBC9FE9C379941
-:10C93000E0EBA2C7369BA08706EF7389A155F4FEF2
-:10C94000739BD30942B42320E490F8D9431D0D60B2
-:10C9500019F3F1F50C113F5D6BEF2C8A3EDF040AF1
-:10C9600019A85EA9F9992AF96C423857ABDB8E26D3
-:10C97000B9CE7C83F6F3EF117A887C35D4252A353D
-:10C9800039D4DBBC6D362FE9D373DBDE993619E978
-:10C990003075CCA46259ED9E5F98D98FF7CD1B7D81
-:10C9A000E657AB93793E9F5BDC006BAB5C38EF26C0
-:10C9B000C78E57890437BB3EAA4AC4FE2D29D26EC2
-:10C9C0006AE7A8691392C80E4080F7B935A77C378B
-:10C9D00089D81477B58DFC7239295594DDAD74C4AE
-:10C9E000D1496A57BFCAD5D7D0BF2A659061FE2406
-:10C9F00035C3303E3967B8615CDF778ABBD0308F92
-:10CA0000F495E266C483F90EEB653E97C9DBFCC57D
-:10CA1000FB8B18FF1B8A08FF08D2CF8681C591D2F5
-:10CA200095BF584D6663F3CE043EA735C5A735DBE9
-:10CA30009EDAED517B8F4FBF84AD3DC675B5BDC449
-:10CA400075171B9FA2FD7894EC47C10BD7F1B9FB7A
-:10CA500073A3CF5CA6225EBE4C8C5BC9EE99E2D676
-:10CA60008816B79AE5A74B4E2555C8CD5E19280EF6
-:10CA7000D2E357B3FC003CA0F97FD15EAA9E4F7D64
-:10CA80004BF8AB7F90BEF78D966BAD35D5230A6C16
-:10CA9000E857A84EF85719D6D183B308874EFF8CB4
-:10CAA0006EB987DBD6BE3AB0889FFBE371CB5AAD37
-:10CAB0003EF1AB4CED9CBF66C7AB0393BBC7E1AE89
-:10CAC0008F0CF3E13E69B7A1DF9C66EC3F5CBE3B97
-:10CAD000FAFDDEECD0BC3577DA7C54977E4CD42955
-:10CAE000CDE33A3C553B633C642F95AD76CE876AE7
-:10CAF0005D1EAE9F28BDD44F74BB70830CF53DD92D
-:10CB0000B7F5DABA5376C680FC2DD67D0F6585E081
-:10CB1000F1BF28FCCC7B7D3CE08DDAA73553C47D8A
-:10CB2000C7125B7EFC15CE3BF612B889F4C712859E
-:10CB3000BDCD6FFBD462213F112BE425DF15B62458
-:10CB4000D17D97F9717E3A4FAE5B10EFA773A38248
-:10CB5000F4CE771CC8FA2D4FFB1E75A0DCBD6FB15B
-:10CB600018FC4E846C1DF67764FAA691DF99BC33ED
-:10CB70002668F916F8ECC804E1D72A84BECF26B996
-:10CB8000D1CFC5D0D4D43D08867332C29FFA679EF8
-:10CB9000BEF5ADC728EEDD2BF41F879DE67CF4A61D
-:10CBA000A87C14D608FD75E02FC5390B77B5D828B9
-:10CBB0004FFAAEF4BE3DD3D9ADDFC3CED5675DDF4E
-:10CBC000EB0E087D3FB1F5CBB7C8AE9F407F17ADE8
-:10CBD000EF5D7E51D3F3BAC765D647FDF9F1ADF2EB
-:10CBE000C4400FF47D4D930370651BCECD96949D8C
-:10CBF0009A467E6DC93685CF037BF3D7752B8CE7BC
-:10CC000064CF6DB7CF17E7C8028F88EE4FB77D9915
-:10CC1000549E2BDA657C5EDBA2D91D11C7A01FB51F
-:10CC200026931FAD96B8FE7660DB00BE9F714082F2
-:10CC3000A03A9297B8CE817C9B2E96A3E74E8AC7E6
-:10CC4000202547A17DA669FC9CAED585666C9B918D
-:10CC500045FC7AA76DEE010FA19795C1F2733DF8DF
-:10CC6000391E3C90E84DA57B0A539B847C1F48EC01
-:10CC7000ECA03AD281B23889CEA370FDE6E878EF15
-:10CC800080D59B5ACF78E9E79357C8DFC45D421E31
-:10CC9000ACD943E4A75F12F91CCBBF32F06196AB6D
-:10CCA0000510D8EDC17D6BDD418E4B1781C8EBCDF2
-:10CCB000F17CEDB8CF6CE417CCF967F9961D07E964
-:10CCC000DCE39C3A84495E2F547730E7BDBDD50F35
-:10CCD0004625790BB3A2EA7EE6F8BC2B0ED5E3A875
-:10CCE000F5717C2EF44AD97F1F5F84FDBBD6C7B98E
-:10CCF00028CF3EFAA4DD4F76F9E83A7B40C2F1A393
-:10CD0000499DED94771CDD94E7C615609E45FDDDD9
-:10CD1000B3E4D77F6B65B90030DE6B58527637DFEE
-:10CD2000FF5BB23E5EA27B389022C6F59C4F7E260A
-:10CD30009EE38205CF0FE4734EDDBF907ED0B9F441
-:10CD40009127623C14E41FDD33BD0FD5FB3A2C7FE5
-:10CD5000E0F37C90EF3B44E7F58B36C48FA4F801F9
-:10CD60007281F9367FDDE57CBEF973C53783F0AF9C
-:10CD70007CE69A0174AF6CC1DBFD80F0896C7D9E0E
-:10CD8000CFFFBAE3F49EE3BB135B33FA406E379DEB
-:10CD9000F43AE08AA7977989EFC5922ACE69A0DE96
-:10CDA0003388E4624B35D0BA2365716FB473651C68
-:10CDB000C7A566B9ABC91271608D5E6FE80B8E14A2
-:10CDC000D21F1F301D222B87AFA3F3B0E6AC24CDBA
-:10CDD0004F77664F8BBA975825B7D7BE4CF2B9C676
-:10CDE000CE75908E989ECFC11AB21279FE3C87F113
-:10CDF000DCBCB6E18CB19F8BF91DBE3FB2492DBCA6
-:10CE000013DBA51AFD57A77AEFCDC2F717B63EF28E
-:10CE1000C23EA6CB9A1FBE4FFBEE718AFACB3E41B3
-:10CE20003F73FC3FCF21EA1C006B797FFDF9A74FD0
-:10CE3000BCCBE7AB9F6E1E9E2DCE8D439FFC3A8DE3
-:10CE4000CF8B0FDD8BEDA63D6F315FCCF09E73EE87
-:10CE500027498C6F0DE1D197CE77BD8F109CC80804
-:10CE6000CEDBE6AECA63FAE9E76F91A33DE7273A66
-:10CE70009CFAFA3A7CFAFAFABC27B3441E335BCB2D
-:10CE80000F8ED942C7F91CFD85E112D5F7BA9E274E
-:10CE900085F213A3E4E5BBAAA7DFA8D5430E5A96F3
-:10CEA000FDC046F7E45A575B7DD176EF12EBE85DA3
-:10CEB00071A00754577FE14AD86F21724A7F3AEF39
-:10CEC000D3FAA40CD81FA78127113C746F506B6153
-:10CED000A12F85EBE4B49E4CD71003DC6F2A77AB0F
-:10CEE000D45E29791571EF2BC0F23F01EA07131EBA
-:10CEF000164798CFC5F47B2E3312975F9386FB3588
-:10CF0000F783E514C7345B855EF8E7C471FEA6D3EA
-:10CF100049F733E0CA35F8976617A80AAE3353814C
-:10CF200015D624316F28D2F9C09EB9AF529CF0AE0D
-:10CF300052DF8FF67DCFF9589E64A1F82E104F393D
-:10CF4000E2FB6FFDB6F8AF38F703F09439517EAECF
-:10CF50007BCDC176DF5C8FB81D7CDC9F0761EB1752
-:10CF6000F8DEDF46FF6BFD4EE8C6EB6F63BEDA4CC2
-:10CF7000F9C14D890F14D3FBFA3D4CF37DBFA32EAD
-:10CF800027DF0B34DFFBBB167C9F91DD3A65F1D5C3
-:10CF90008AFA47FD28F2BF91441B48383FD24FA37D
-:10CFA000C731607A44ACDAFB9FABDC2FAA1CC9F511
-:10CFB0004838A5B23D1E6BF23745C32D220FFB4604
-:10CFC000CC2FEB540CFEA6A840ABDB7CAD725C7A98
-:10CFD000E569E5BCFEE8A16C61CF8AFA5AEA7B8A72
-:10CFE0000FD56CA13F4D1094053E224E18DB2557FE
-:10CFF0001E99F857ABF56BC99FA13C45121C7EBA30
-:10D00000E83876AB90AFB14A7007B5685DA181E2B0
-:10D010008A2DE8EF7438E88C306538CBC1185D3E56
-:10D0200071AD59386FB954CF798B83E2196C574978
-:10D030002186E37BD0C9AD47F3E315E0E6763C7883
-:10D04000B945F9E47622B4707B35B4723B0542C22F
-:10D05000EF5F116C627F06F7B9F8DC62D23C0BC55A
-:10D060001B45D7F79C2F546874EA9D0EA87025972E
-:10D070004E8709807A97D1033D06E7B0FD30D3C3D0
-:10D08000AC9F651096593FC93064509D40653DADD9
-:10D09000040FF7AB2E920EA5619FC2751A333D2A7D
-:10D0A0007B968BC91A3DFE950D2C1F3A9FEECF56ED
-:10D0B000F9B9CE2FD4AB14927F331FF5E745711524
-:10D0C00027E96AFA1DD9C3A7D3BDAAA2C28AA5645B
-:10D0D00092EFDE30663ADDAB2A1A5BF13C1D79DE59
-:10D0E000933D4EF40B2A0AAD6ECC5AA4B2E9E3711B
-:10D0F000BE4FBB970C33457C7D9716B7F896FDC0A5
-:10D10000ED423DF1A53ADD849F03837BAA7FCA19D6
-:10D11000E27C70C8C4E04E2BCE3BA4F8E664537C9E
-:10D12000E00826A848F7BB9655F1BDB5876C62BEEE
-:10D13000DD2EEAB03A5EF8DC1F83FD4D9B862F950D
-:10D14000D27BDF1FD7ADA5757DCBB2FCA4AFBECD22
-:10D15000925B70B262C04CD4CF8E9015A81EAAEF1D
-:10D16000939DEA5B9ACDE7BAD95C271BA4C5331D12
-:10D170009B860F27BEDC9FADDDC34A4E2B24BA2D04
-:10D180004BF5DE4FF323F142BEEED7F8D05BBB2167
-:10D19000DB735F76F1B9CF23FF4000F0FD9F65FBA5
-:10D1A0001EA0F5EAE2CEB27F3F3EE2EDE5E1B46ECD
-:10D1B00039959049B310EF260F046CEC07B4FBEAE5
-:10D1C000DA7955E4765C07E950E4F53591491B3589
-:10D1D000ABB384EC27AEFB5FBCAE2D3C6404BEF762
-:10D1E000D8F44336216783859C697668DBF6BDF702
-:10D1F0000E125D2F44E955DDF6335F7D80F4AB3BC5
-:10D20000E174D3F46E7DFAE552CE27C169B01BBA42
-:10D210009E8DD962E7B87AECD6CB6FA779656FB7E8
-:10D2200067105E57B687F91C2CB2EDDD41020E3D4A
-:10D23000DF38257D1BBF4BE7B49CC76D16E7B44BA9
-:10D24000A4FA57E2A9FF7BC9ED47F83FD5FC869EBB
-:10D2500017CFD7F05ABC77FD72AA8BCC5F73EB1453
-:10D26000BEC7131079838ABFA4FF5FC23E3E1F5F13
-:10D27000B4D19C4F74DA88FF8B5B4DF781281FA6D1
-:10D280007B0FD1F6BD877C787BB6764E9B0AA98C46
-:10D29000873CAB8FAF077B67CE771F07CFAB2C9F49
-:10D2A000E09569FF62A5E77AC273DDDFD3B03ECCBB
-:10D2B000D3F6263A3939DFB589FBC24F2C75BBA8A6
-:10D2C000AFE9E75A9495528AA33B7FC9F2AFBFA753
-:10D2D000EBEB8215E25E36ACE9CB3257B0C1EE2102
-:10D2E000BE166C18C0F905E6411CF7ADDD605F4164
-:10D2F000FDA60763FD7201D5933B2FA3BA4A538C59
-:10D30000F8CE89DC23DD132D4817758E33BA5DD72F
-:10D31000FCBA7EDFB62BFF89CFE67BCD5DE361C52E
-:10D32000906F3469F17311C1477160BD55E44F319D
-:10D3300002FE1D6F7E3F8EE2D8CD8A378EEAD2275D
-:10D34000F6A7F7811EE8A6B7C5E85EE03CE78CC506
-:10D35000EF4EC9381FBF8A1ED7EEA76BF2F9C7463A
-:10D360000FFCDDDACD0F1DAF2AF9D94A1BD5396E76
-:10D370000317D53D96EC7DAA89BEB759B212B8A263
-:10D380007082FE50BE70C4C2E7E063F616A6903C01
-:10D39000B669F68ECE85D528B92AA1A210CE2F1E49
-:10D3A0000C01FAFE28468D05352A2F8ECB4932F422
-:10D3B000E3DD9719DEEF539A6E1807BF27945BD20F
-:10D3C0001DBF267AAE30CC7F2861027F8F5316BAFC
-:10D3D00083EB4A7D278E348CDB51AEE99E037C21A2
-:10D3E000E29F52FC65BF0AF532C139360CF02B942E
-:10D3F000BB311DC6F8A834DCC27960CC7EC590D79D
-:10D40000DB2F5067BA7C98A6578361B0B00F667A5D
-:10D410001BEF432CD92B731CB7241503CFB4DEE9C3
-:10D42000ADEB9F4EF77E5E23DD07CC34D279A0CFE3
-:10D4300048E741F38D744EAD37D279688391AE6978
-:10D440007E231D33568C31CCCF6AA930F4873D7EC4
-:10D45000B561FEE5816986FEF08D371AE6E7B5CE47
-:10D46000358C176C59785EBE8F082E318C9BF95E17
-:10D47000B8E74726395498CEC5DAF7593AFFFDF890
-:10D480004BFC1F0BDE3E4189CA81FE26D2C7FF2F0F
-:10D49000FE2F18A69D23E8FCBF48BB7A95E687CDF2
-:10D4A000DF794D8D13F6E6F53D27F67BB0FF865A02
-:10D4B000684DA1B8498B0FBCFA798429EFD3F39456
-:10D4C0006B4B25D3397D8CE19CFE42F7DA8A4341D0
-:10D4D000437FC47EF17DD4C883EE57A82DFED823A8
-:10D4E000477F0F35FA0B76CBE7E49DFAFD383D6FA9
-:10D4F00082E627390F9DA5C34F4A50726E7D51CFEA
-:10D500004FCD79AB9EAF9EFBBD95884BEE967BCB06
-:10D510006345FEAAE7ADDF070F7F5776D560DFDAF8
-:10D520006168FF654B675F1AD7F359222C9D1B4733
-:10D5300088B0FCDDCC3BD33DB9FC3D2AD7BD174AB2
-:10D540006F4FA77BFE08BE2B5C22CA3FF4F3D2309C
-:10D55000DFEF68BDC3926B7921BEFBFA98CF86D00E
-:10D560007AFF334CC46F76192984FE67C02C0FD024
-:10D57000F351499EE768BEF97EB6B935DF1B6A6B89
-:10D580000C72ABB8DC7C6FC75C1F0C5B548E3BFD30
-:10D590003F92F89ECE6704DCE8EE78E5C40A2BC71C
-:10D5A0002BA0E5E3376BF4D7EB16B3347C0EE31214
-:10D5B000F3D1FFDEBCE535E6CBA2940EADDE51CF54
-:10D5C000F1F5AD839D23F91E9AA7D02DEA5C7A1D53
-:10D5D00063D0257D5F7221FC17A51C35D491E0D95D
-:10D5E000BE1775BEDD8DB758FFF04A518F3CBC3277
-:10D5F00095EBDFDDEB1FE77AD2CDF56F1AF4E296FB
-:10D6000086F70C7A30C7FF91613C9CDC69A5FA6112
-:10D61000F88581136E42FA1DDB6CE7EFA1510E3ADB
-:10D6200088AFFAFAE195C3C7F3779517C4F3338649
-:10D63000A3BD31C4FCD5F13CD47890FBE1C630B732
-:10D64000663CF53A85DEDA76420EDDCFEF9462DD98
-:10D65000541736D72FEEB6A89F901E3C9493AEC5B4
-:10D660006BF5055EE69FA857B46BDF97B66BDF9747
-:10D67000B66BDF8BB66BDF87B66BDF8146ACCE1542
-:10D6800054D76897C4BD9F5992E7C939B85FDA602B
-:10D690009F3387E2FE859DF90AEE5357109E2D2198
-:10D6A0009FF3FAF9FAD07309D38581FC3D919FEF7E
-:10D6B000871DB1F8F3E9FB9BC91BB3AEA33CF0484F
-:10D6C000ACFF384522953969D751DE77C426F4700E
-:10D6D000FAC6D8EB48EF3EC6C5083FFF4B92A82BD1
-:10D6E00039C336FA7E6A6AB26F504EB1B8F7C5DFF9
-:10D6F000CDE073924BBDCE19B18A3830A2C583E913
-:10D7000039E21C302347C4AD7A5B463CC7E7D3A956
-:10D7100065FD7C389BBF375963078A5F717FFEBE0A
-:10D7200046BF6762FEFE66E49FECFC9D845E0F2DA3
-:10D73000C949E375E8BB1CD2CBE49FC4B1DD82705C
-:10D7400068087DC7D305EF7EF15DE531AA2347D593
-:10D750009F4B72441D066E03C377408BF71E3E44F9
-:10D7600079D6FBC37C6388AE732D6A09F17571C2EB
-:10D770000EAE774DC951795F8497F145FBD34C7C50
-:10D780005AEC08737DEC42F5F0DEF03F767BE8174B
-:10D79000B95CFF55F3F93B3C6D5F84630AD15FC709
-:10D7A0005B87A37B9DF3CBBF5ED7D5FB9F3EF1503C
-:10D7B000B65697BFC5DB833FBD55A34BBBB5E73A14
-:10D7C000FAFD1A7FCFE1CF3000AADBDB63D14760DF
-:10D7D0005BAFD1E9D80D880FD7273C2388BF8BA733
-:10D7E00039F9FB737D7D5CC7F787F3ECB33AD5BBA2
-:10D7F00090F05F582FEAEEFA7844127CF5AF14757A
-:10D80000D0C5DBDF3B44FF1F8405CFE415727EAF3C
-:10D81000BD6FA633D297BF8B9A2B8B732BA4EFDDF2
-:10D82000C46773BDFDDBD235922ACE57236BCF0C74
-:10D83000A17B648BE9DE1A7D1FA6D5AFA0CD5897DA
-:10D84000427AF9A95E71EE7914F0B9965DF3237608
-:10D85000FDFDC18AE1FD634EEF4F893E2F687603DF
-:10D86000E7072CB87F9B9E279BEA286D2151EF6C20
-:10D870004BB1719C4CF10EF9273DDEB9EB4D51EFE8
-:10D88000BC2B4DC4D1041FF1573AB89BE3842EFF43
-:10D890002FB955A29FD3EA0BD0FEE05BCAFE4B1E08
-:10D8A0008AFCA5F38B3F5FADD503843F2CD6FC5F8C
-:10D8B00031AD43014E6E1FF68B45DABE183F72DD67
-:10D8C0006D34F89A04305ADD6CE56E431DE1FF00BB
-:10D8D00090CECABD504500000000000000000000CE
-:10D8E0001F8B080000000000000BFB51CFC0F003AD
-:10D8F0000917B1A1F26FA0F1B33851F9BF5951F92D
-:10D9000097D0F884B02E1303C30A46D2F420E39DC7
-:10D9100040FD0780F838109F6322DF1C103E210C69
-:10D92000F48F1803C34220DD0DA4AF00F11F207E49
-:10D9300004E44B8B30306801F1325106864420BD3F
-:10D940000688CB4520FA4E02E96651F2ECD4E3A1F9
-:10D95000CCCDA39832BC411A955FA3C2C0B05695F6
-:10D9600081E1931A84BF02499E5D9D81A15605C243
-:10D9700036956360E807AA59208DDD5C33A0FC046E
-:10D98000A0BCB83A840F00134DDDCB680300000043
-:10D9900000000000000000001F8B080000000000D5
-:10D9A000000BCD3D097855D599FF5DDEBEE42679A3
-:10D9B000819705B8090183067C09612DE24D8C1819
-:10D9C0006C8A2F88364E197DA0D56859223235B61B
-:10D9D000DABC4012C2A6416D8741A52F5A2D525A7A
-:10D9E000A3624B67D4792C1DD1B1355AAA76A49D78
-:10D9F000C8388E5A65E242AB558739FF7FCE4DEE6F
-:10DA0000BD7909A89DF98ACBE1DC7B96FFFCE7DFB5
-:10DA1000CF7FEE73CB3E80090027F1CFB900574B83
-:10DA2000009037548237D608118026CDAD6F2A0674
-:10DA3000F886123BAC57B1E763E5D8FD3A3E9F5CF0
-:10DA40000B610005DBE703C4F07FACDFFAE0BA311D
-:10DA500089207BA62CCDC2D21CDF2C9B5400AD129A
-:10DA6000DF6F999CE9BD5942CA35D0EF05FA73B210
-:10DA700004A0E5E86FA71E32EBECBF0208455E0F7D
-:10DA8000B0BFCC8259271580F7828BB3D230F278A1
-:10DA90006FB5769FA54E02F853EBCB530F4D1AFE90
-:10DAA000FE1B0A34F7960F7F3E0BD8A433101F4994
-:10DAB000777CEAD0BA07D71964489AC3FA03A43D21
-:10DAC00039ACDCB5ED2CB56C084EE73A00921CBFC2
-:10DAD0009FB39F2752932E60B50A29318FE052D908
-:10DAE0003F3301A829DB97EB763500C1E580B723EA
-:10DAF000F2978177C4FD12EDDE0BAEEB04D66FBD5D
-:10DB00008BD34B7B9E1C5B07C3E9C5DC0F138FA730
-:10DB1000BB1F37818FE631E9A8495E3AEABE9F8A8A
-:10DB20008EAE443A3AEBFF9E8E927FBD74D441E3B1
-:10DB3000FC95D1114037C717F4AB38FFD0735E4660
-:10DB400096F64A4867ACDA87708FE353C1B896CE31
-:10DB5000EBE5694C4C41ECE93398DC1AD7BFAC1EBD
-:10DB6000E11E7B74E19B58762EA9A93B9FAD2FBF88
-:10DB7000B1F7F90B581989A7A404DBAF3B4046A1C4
-:10DB8000C2C65B91AC66EB6BC7C1E6023C905C66BB
-:10DB90002471BD60008C01F83BB126005957593DF6
-:10DBA000447FCDB40E37A4393EA4939EE1FD475A7D
-:10DBB0007F08FB996D8AF1FF6B00D777AA7EB0963C
-:10DBC000CF9764FF20BE0B87E6A771F29B2C7540B0
-:10DBD000FCD8DFF7E15F08BFD7FFBFCC5700953E09
-:10DBE000940FA17A594B617BE8CD56593DB24285DD
-:10DBF0003493110555DD924B3FF5BE7402D4F5F216
-:10DC0000FD911A4243F0FD2748443FE3BFF55ACF48
-:10DC100006467227960663441F1A406ECEF0F57CC6
-:10DC2000B71509D9525F52232568BED8D3A5AC7F5A
-:10DC30007209D77B77D42FCEB6CA2B8F2409BC3973
-:10DC4000E903747526B215A70FB55E367CD3BE38CE
-:10DC50007DA89F933EF2D65AFAC167DFAF88691755
-:10DC60009C267D7CD1F9CC7D1DCE576D625F4B7DAE
-:10DC7000C0F8F6F6BAC519ED8C91F7B592F83D5299
-:10DC80000F462A43BFFCC1FD4C0E2FD9FE2883DB73
-:10DC90007B836DBF94B1331B7B46C18712B1AFD775
-:10DCA0001CD7D7A2E8AFE5B2AAAAC9389E1BC763A2
-:10DCB00074B6317A7B12183F9C40DA66F850BA2B62
-:10DCC000D258875288DD2F209059DD1735529B8816
-:10DCD0000E52B42F267C1E5DB6E15F8DF86D75681F
-:10DCE0004C4A56F87D2D6E82C38DF3317A57343607
-:10DCF0002043851A84B42F8C2D38FC4806272762D0
-:10DD0000FDDB363AE8D22B21D33E98F48A68E5F45D
-:10DD1000FAEDD3932FCEF996D8E13DED7E41557FB4
-:10DD2000DDA28746EEA7C2EBE6FE30245E8503CC7B
-:10DD300018DAA70D2ED8279DCDF475D1A590604F88
-:10DD400037E0AB3944A764CF6C28AAD490AE609773
-:10DD5000A4229CA61E85680EB5AB90741A47F636B1
-:10DD600003B653820695E6FB91E112F49734F697D9
-:10DD7000B271BF22F6F72B42AF4195EBB57E136E21
-:10DD8000D2B3EA509DADE39D9BD8FF189D242BA4F0
-:10DD9000D4FDD2F0F7F5A817995CAAC7E716B9B277
-:10DDA0007D900FA2B45FF5E2DDC1C75E9A3C9DD1C4
-:10DDB000475F4C01145BEB1EF318B56CFCE7CF9189
-:10DDC000521E49C0CBE05C24E07CD6C81D8774DAC3
-:10DDD00057EB213A5E74C19F2248C6C7F7FD5ACD62
-:10DDE000442F8BE6B986E060FFADB6AE8FFDF7C37A
-:10DDF000C17D29A2794CB856562A0447DF3C2985B3
-:10DE0000F31CFADD7FDDFA2506E7B35552CCA313E8
-:10DE1000BC2160F3F519EF4746F53BCCF975D010FE
-:10DE20009FCEF9CDFD081702E115FE9DE195CD9736
-:10DE3000AC19E85F8F783E26C5D6B3F9B2E6B74C89
-:10DE4000C0798A6599E0DD38CF2B2B8C7EE0E531F7
-:10DE500032E23328F83CCBDDED9DC8E0EC9C24C3D6
-:10DE6000BDECD1C6D2D1E559BB439EA95ADC90582E
-:10DE70007F3DA9552AA3F045CA90EB32C9BB672460
-:10DE8000AE273B928BB5525CDE21BB1D887A296E92
-:10DE9000D1ABCC5E7C4662EB7745381D67D7C6B9FF
-:10DEA0009DD83786E45740EC47D6B4C55990C10E8B
-:10DEB0001E711D6CA24C7673B6CCE183A37C7CD51D
-:10DEC0001C3F67F4F13788F13F6C92A00FE153E3F8
-:10DED0005EDC7F302A889EFD823E616D0ED54DB995
-:10DEE000EB298B7715B37DF44465D0755C5F92F6B2
-:10DEF0007933DBE322068ABF96BD674D377FAA9050
-:10DF00005D922D9F4826191C9BF75F0B3AB353FD7A
-:10DF1000D114507DEAD55EC4CF66A614F8FCBD804E
-:10DF2000F30718D9A27C0D30F9AAA37CD57BD33294
-:10DF3000ABAB751033D8AB901693FC8C640E444B8E
-:10DF4000DA54F6BC7D2910FD025A1116FCB6475F63
-:10DF5000301406576723905DD319A9A1F5B597D75B
-:10DF6000788BD1DEA957E9397CC2F061DA214C1EE9
-:10DF7000FACBC0C0F936E7432A88BC549B47F4E883
-:10DF8000D6F8FAF5EDA5909ECEDE67CFDC8FF327AD
-:10DF90006F81D8243E25C935D5A40B359194D0BFC7
-:10DFA0006BD1629B32D0DD764864C9336C744A7A97
-:10DFB000D789B72C375C88F8EDAC60F45F3C7C9C6B
-:10DFC00022E41F466FA9D8E28B4A32CC532CEB4493
-:10DFD0001F665DFFD04DF08FD47EA81DB3337371E3
-:10DFE000684342BC406D84D69703837F0CACE78ABC
-:10DFF000F58E81666A179DDDBD1FF9ACC0E8AD46A0
-:10E000005C7C3774E9F3B46F70B786F108066DE98C
-:10E01000C9DC21396104B99C782F26937C0CC9692D
-:10E02000CD6003847C7D5152D63A901F91855D1856
-:10E03000C09B5ABBA7A27F19869884EF43313569EC
-:10E04000953F59C0EA36FB0F8E94CE24D2E27C0174
-:10E05000DA7E6419ADACF90C1CEF0E06908FF9C98D
-:10E060005B4209D2177FF285A7E1647F92E3596989
-:10E07000DEBF0CEDEE1B157F6C13D2438CEB072F2C
-:10E08000FB07E55FD66CD5268FB30D7B3DD7A13757
-:10E090001628415A6FF65740E803A37ED29821F81C
-:10E0A00018640D4837DB6A55C0F982410E9709673D
-:10E0B000AEF2495A0682E318C2C1D0437084CB80C5
-:10E0C000FC3D06CF31073CC71CF01CB3C2D3E2E5D0
-:10E0D000EB75FAFDCB65E1F733BF17F5E00978DBA7
-:10E0E000A8438231C6915E096BBC6DD0DB47469573
-:10E0F000061AEDBFD3EF67FBF39E4D3FCC16759D1F
-:10E10000D9F525049FFD3D14119D505D8141FF759A
-:10E11000F96C133FFA575F617C77ED6117205F312F
-:10E12000FE55F0BD4BBCBD56F8B1CB51FF33BD7DA4
-:10E1300015C4C308DF3B2093BDFC0EBC109E6E913E
-:10E140008B77C86EA1C7D9865AF9176251F4ABD53F
-:10E1500060679F1226349874269DA47D8B01F9DD9B
-:10E16000414E6F49F0B6917DD1C5F5A3E9F77DBD6C
-:10E17000DBAEAFAFD96EAF5F0D8BC7207D5D7DA7E6
-:10E180000B526CDC6BADF607DB9F6FC91AC1770DC4
-:10E1900034776A41B2B31A711DCB3550D14F5BF958
-:10E1A000B37B662E63EBD921F4E85B4CAEEB16BD76
-:10E1B000715D24E536CA87AF6FBD145BF42569E451
-:10E1C000F56D70F52D42FB20B9D5457E1D38FDB5A6
-:10E1D000BD0AF96B967E04EF955DF6F59D6AFDCE5E
-:10E1E000F5328F85D67BDDAE65A437475A8F7B9796
-:10E1F00064A432E8B7874D7D28E48B49DF265F278A
-:10E200006B80DB7BBFF7A5D6B3F97E83F291F6BFB7
-:10E21000F96C1E47699E85E5A9FAFDDBE7ECF7EF8F
-:10E220009FB3DF6B428E3BFBADF4F6BB713F57AB48
-:10E23000C93A491EB2A3BDAE66A390A1C2B5AF3A1A
-:10E240008DA698A55DD769B63B2C959C56BB3A79AF
-:10E2500094F18E0B3BE3A93DF7B9FB91FF76BFBA72
-:10E2600008F5FB37FE49012F5BD7F13D2148237D9F
-:10E27000AA2937DA2BD731BA4A513D3DF3628B5D7B
-:10E28000C52896C6FFC64321B20FAE7BC493AA67CA
-:10E29000FDAFFBE97F4C038687E3EB06FEA510E9A3
-:10E2A00075B7C4FDBF64FFB48BD9F3EB54B8229E9D
-:10E2B000814E6485F3CBDB3F0F34A2DD27EDDA7F9F
-:10E2C000398DDBFB5517CA65B3DD47B28BE665EDCB
-:10E2D0000C7C9F7C504A4D92387C0D5387FBDD6F40
-:10E2E0003F2871F8F6B9523E846F578F3BC1DAADC3
-:10E2F000DEF52ED1ED790FFD388C7858BD4FB1F990
-:10E30000BBAB772969CF342A5FC51235A3C4F86D3A
-:10E3100095E0D7557B57921E58D5BBF95DE4D7D50C
-:10E32000FB5C36B9CEF0124B235E5F5262F5587F2C
-:10E33000F487619DA1EAADE8EEB0564EE32E73334B
-:10E34000BABA68B6BD1F8EFF61CEF0F1000628AEE6
-:10E35000B9BA77239F0FB8BE31F9F42DFC4BFE708C
-:10E36000BD3145B19F3B9C806767521C72576E461A
-:10E370003FCED41726BF7EE3C7277626D9BC6F3F92
-:10E38000F2879D4906FF8AFF797FE7B7D9BAE0494E
-:10E390009F867268F5EEDF84C182F75A85FB61C7FC
-:10E3A0001FFCE1033B18BF1CFFAD87ECBAE34FFC39
-:10E3B000D7789DADFBF8C31F8D41BB73ED13E78F7D
-:10E3C00045FA5AFBD879636114FF01E935E5B1EEEE
-:10E3D0006B8AF655DF27611006E071513AF6E7E0E7
-:10E3E0005E258DA1DB775EF6A43C0C3FABD9B396DE
-:10E3F0004ADCAF95A487B07E33C3F3AA3D1BDE553C
-:10E40000A665C277B2508E62C9D8268AFB7DF145D7
-:10E41000E75461E98AE9481F3040F2DFD96FF5110E
-:10E42000B6AF678FBC8F27E01337E27FF59E8D7CF8
-:10E430005EC73EBE837F999341FF0FDBC715DFDFC9
-:10E44000812FF7E6D2BE8FB48F2B1FBB6454FFCC55
-:10E450009407A7C26F93C4E13A5B31D628C8578F9F
-:10E46000FCE8811D11BEBFF50C21C77F7C623C0614
-:10E4700097DF700D5C8E7272E0098F762FEB73DD83
-:10E48000132F119F1D7FEC79B74E72128212D37B2E
-:10E49000C761F04F1FEAC15512AFACFE4128ED092C
-:10E4A0000FEDD3AA54439D1EA6E7AFD2F314A7FFE6
-:10E4B00055A9FD4BA40CFBB65B29E1723995477851
-:10E4C00059A9F7B9B5A07D3FA5D9B88FAF2E40BAED
-:10E4D0001B691FCDF56BB8FE5996FDFC01E7DB917A
-:10E4E000F8F3788F4795B286F6F7B8B00F56A7A421
-:10E4F000972003DF02ACE3F08E70FE68964E7AF848
-:10E5000081831ECCFEE6BA4FC5D7A75ECF67C3D7BF
-:10E510009D8A6EA31B136F6F7F9259DEA7859C584F
-:10E5200005C9BA8289C3F5950AF16461F110BC9DF1
-:10E53000BD0AC9F1B7772964A73BE5C2AA11FCF16E
-:10E540005F29DCFE58B56FFF34945F6F1FF8B9A0E8
-:10E55000434EE7ABF6BCEA4E0AF99FB2CA7F1C2FC6
-:10E56000C37EBC2CE05EFD78E6F156EF7937E378A8
-:10E570006FA9C65711FEB7FA5C906443BCD5AB6473
-:10E580008C6F1C505CB6386E6768E6CB5918DF0C90
-:10E59000FB755CF7FA75C64B49B4435E7001D981CF
-:10E5A0006AEC0D0F7BBF3EE4A773EFF5E1AB41B71B
-:10E5B000E8E976079ED4689CFC603512AFE2B1D7DB
-:10E5C00094CD1F7569B20D6E509345184FF955F1F2
-:10E5D0007FA938EE7368FF9D31D4FE39153A72D9A0
-:10E5E00078CF1952AC0D32C4A71CE3C7E729A05B52
-:10E5F000E9CC2893ADF1D5F0819B282ED102CD69CD
-:10E600008C134111F4DE6F19F7EE560DD26C7EA813
-:10E610002B93ADF1554F73B3E1617014ADD54AD072
-:10E62000341B69FE71CDB23DAE2DE65F23E209B029
-:10E630006BF7EEDD6CDC3A7C57827E0C8F573177BE
-:10E640008AEC98F3841CFC6761071F90E287D0CFA7
-:10E6500032F46D2ACA39A9749B8AF6C4C24FBAD55E
-:10E66000E5167A5C58DA5684F472F853A531135DD6
-:10E670002D51395DB5156F28C2FE877D371671277C
-:10E68000344AEB2C10EB3C34EE9A603F1B777FF161
-:10E69000355B2633B8EAA20A60BCA52EB26C4B05E6
-:10E6A0005B7FC11125E663F582A6A49A983A7C9E09
-:10E6B0009D28EF19FEEE453C32F87FD01AA5FA03EB
-:10E6C000AD3A95BB5ACBA8DCDD1AA3F77B5A67534A
-:10E6D000BDB7B58ECA475AE3F43CFC2D7F02E977FB
-:10E6E0006F6B233DFF696B82CA1A95F3DB42810F82
-:10E6F000CBBAE91C6C497B781DC6514CFC39F15DE5
-:10E70000CB282E87CE0D241DF13D56E572C589D745
-:10E71000969620D9A53B25B0E173A6CAEDC8B8806E
-:10E72000E3903771A1CACAF7EA4ACBC9EE81780CE7
-:10E73000E5F44E297E5B05E397A7C6CD8A5AE56EC0
-:10E74000249888AB7943F5F15D3C3E334BE5F2A963
-:10E750000EDA0E6531F88C4F40473A33D779A05A1C
-:10E760002F42B978A08DC1538EEF6528B3D0993967
-:10E77000DE5C011F0433CBE921BAE5FC1F9D5BB6CB
-:10E780000DE3C4CCF18C4DD2C9EAB6F5DBA69A7183
-:10E790006F9DE8D8A413C63F4F8D8BD030DC5F6CE3
-:10E7A0002AE6EF7D9CCE5BFADFA5F856740CD8E222
-:10E7B0008D1D4D32F9393B8EF2B8F489A6926D93D6
-:10E7C00059FB6A8637F4DB73169666252C74BD45B3
-:10E7D000D0D30E6F3C4B1B457F758A7666FD155F67
-:10E7E000E23B88E7BF9FF0937CA4E71DAED4652889
-:10E7F0001F5B8E7AF475129E37C493B86FF122F6C0
-:10E800009C8174A26EAD879616E4E70F2D37EBDB83
-:10E81000CEB0F0792866E7EB9D2DA3C7A54DB8775C
-:10E8200022DCA3C4654DB8CDFD3851B764E01A1899
-:10E830008E07E7B8390B978C3AFFDDC8771EC2C345
-:10E840004ED5229F8A9A353A6730FB9BEB75F67757
-:10E85000AE77285FE1F4CE677A5D908BFBF9F0C765
-:10E86000E31F7D0E70CBE30ACAB12BD4442FEECB4D
-:10E870004C68A63AA803F9C82FBFF373FADFD1F9A1
-:10E88000403EF1919A2A46BD70BAF375403C5E8DC8
-:10E890007A2B26C7ACF2DC2C7FA19A718234C58F0B
-:10E8A000E888994D29076E8E66C2F3E0F845EADBE9
-:10E8B000D6F3A42D00DC4F4F7BE99C0303221AAB57
-:10E8C000171F86CA4D6CBCDD429E54ABDC2F9C7E6C
-:10E8D00058EF5178FC48690859F028E2A9661CAB4A
-:10E8E000036E068D7575AB15FBB1B9C9870DEEC406
-:10E8F0008B882F7754A7F3775724417C0522FE3D60
-:10E900004EC4E9CF1771C6FB5B789CB105E2179E38
-:10E91000817C7D4401F28F13136DFCEB5CE77E413B
-:10E9200057FF24F4DFCF85DC2E55F74B596CFCD014
-:10E930001BE9036156FE4CC8F1C7841C3FB0ED5F74
-:10E940008A319FA023E18E214EC355FEB4C4ECD082
-:10E950005B67BEA15FCBDA77744F6E47FC6C58CB18
-:10E96000E3F28FA2DC67FD1E16723FDCDC793D9D71
-:10E97000DB09F95264E60B08795224E4C9C16D2F12
-:10E980002EDB80EB4B78699E16483F8D717D582BAE
-:10E99000939D12EEFDDE0D38CE43AD061FB77BF71B
-:10E9A000DFA17D7F8F375DF9AF18FF9FE78E25517F
-:10E9B0004EA526D9E454B877DF8DD82EDCFBCC4D9C
-:10E9C000940F23F0E0799CAD9735C9BAFD703AC435
-:10E9D000DA15F6A7D1EC66FBDAB3700A1BAFB45EAA
-:10E9E000A670F51E297E5E08E9A1819F4367552C1C
-:10E9F00069C3F6DD2B5E4862FF31CF364BB8ED3987
-:10EA00007F776F35E2EFFEA2D79EAE66E5645731A1
-:10EA1000D141F0A89EFF43C0F1E3D16BF591E9F03D
-:10EA2000E08A358072CC73A74CE7F4F7DFB906AE05
-:10EA3000B1E65DAC5033C6C726BB3CFC3CEBCEC553
-:10EA40007D2867CDF3ABC295B55EE2FF67C1763E28
-:10EA50006B9E6399FD2BA4C464571E9D57F0732DC4
-:10EA6000D1BF40411B8F556F90391FC4D33E6BBE41
-:10EA700049F07A399E099E592E95E0698FD5EEFAB4
-:10EA800017369F3AEB52D2CBD06D87C3D98FC131A5
-:10EA90008BC3C1E133E118C74C82209BFFF6852F61
-:10EAA000E6237C1FD60DEA1B3FFAFF1DDF95D3132B
-:10EAB000D8FE6C6D97E9FCFE40D5012FE2714B55F5
-:10EAC0008D9FDB3F9CEE72041FFDA04E26BE3D5184
-:10EAD000C5CFFBE19393741EE612EF73F20E78E953
-:10EAE0000C236904AB6762FA81F9C7925FC0705367
-:10EAF00099F4DBE4A7DC9263CB371807058EBC954D
-:10EB000092A1F6E87FD71D91502F85C47974A97919
-:10EB1000BEAD1C8DE1FAEF32F562AB97CA9EE603FB
-:10EB20003E9DC1F58B664627B42E7B5E8AA7096899
-:10EB30005D05CDFC9C6D8BD6B7DFCDEA45DF65A8C2
-:10EB4000D7D19EEB25F902DD3C5FC03CEF98B4C203
-:10EB50009EB752E4C8B719969FF519FDCCEB5DF648
-:10EB60007CC313B0650AD1435F896D5F7AE630B725
-:10EB7000E6ECE1FEE6E0B8C29F82289773393E3E9C
-:10EB8000C7ADDF529AD05E0A5F58996D3D1FED7494
-:10EB9000713BE9D0EF3C80F1F80DB55E8AE398E770
-:10EBA000E8E67E6FC5A42BCC77687FC087F4B223DC
-:10EBB0005242E5C1B9CFF8FA890E793E8047AC6977
-:10EBC000DDDC67163631BCDE9327938EE9287A2187
-:10EBD0001FCF176FAFF5D2797F38D0DF7B90D58309
-:10EBE0007FEF8EE1F9F6FDD5E946ABFFFA908BDBBE
-:10EBF0005BDB5D425F6DB19F3F333ED88E7CE009A9
-:10EC0000C6E9FC52F68ABC09879F63E2237C205F39
-:10EC10002E9ECACB92A943F6F9DD826E760879BFA3
-:10EC200045C87BE738C54DDA0137DAFD2BB44A25F4
-:10EC3000035F4E68B1DB09E39AED7935854D76BA0D
-:10EC40000FC50A1C76459AF498A98F37F88213915C
-:10EC5000EE2B99BEE4F681265BCFDB9DFA78B76A8E
-:10EC6000EC7391BD7B7A764238106F467C3BEDDCCD
-:10EC70004302DF1F2BC601C46F408D1F72511E68F7
-:10EC80009CE48CD36E1806273038A78E0AE72F5DD8
-:10EC90009FC17E3AD5F9C09FE4F8F6E718C8F3B3F0
-:10ECA00040E45D84480E7784B8BFD2E1E27EC27B47
-:10ECB000625DFFE15268DC01415FF303D09C399F44
-:10ECC0008CC78B3E40C304DB8DCD9CBF8B160BBD28
-:10ECD0002FCCFCFE03173F679B3F61F479FE88F35E
-:10ECE000B0F257AAF1AECB728EF384CB78DF658990
-:10ECF000537CE8D2383F98FB21F2734DFB699F6A41
-:10ED00007C64ED6F96390B553ACF3D01FE98C2F009
-:10ED1000F3643EEC0526479E94043E7FE7A33C2027
-:10ED200013DF83F635CA0FD4034703298CA798FB5A
-:10ED3000609EC30CCA11D1FE4C3797278C6E026EB1
-:10ED40009A3FCECF0B214DF2A140D0CD0EDFD2DBCA
-:10ED50006A5979EBDCB75EC67C85771EF3E908D784
-:10ED6000D6AA6361ABDC84263BFD98CF5D1F16D22B
-:10ED700039FD37A544BEDBE247BA22036EECFFA49F
-:10ED8000A4933F97FC8D42F6C893526A0A192A2A27
-:10ED9000D079C693D746539B2CE71D4E3B3FC7D730
-:10EDA0007FD76A5C7713B39760F8BE9976FAA0DDD7
-:10EDB00011B5F78FBB41D8D96CB98CAF2BC4BA63EE
-:10EDC000AAA1201C332041E52CD0A964FE40A59BBC
-:10EDD000B59F0E03F9C847EB02E3BFC4ED8CFF33C8
-:10EDE000BC197F8D781BA25BBBDE36CF1DF2041EE3
-:10EDF00042D04CE7EFBF685CBE71129BCF5D14241C
-:10EE00007B38AFB1FD7A398CD97E7D1AFA9B79E2D5
-:10EE10003C1C9670FD6C9E4FE7D4DBF5B9537F7BAD
-:10EE200084BDE11941AF3BE5E6487A7D85DBAED78D
-:10EE300007E3C723C83F67FCF8D4F24FBFADB6184D
-:10EE4000F3348C976AD1AE9BA752BC333C11AE8889
-:10EE50005BE8E1F76E223A56F2BC994D8C5F53673E
-:10EE6000703E07F413024C01E179C2383985F93656
-:10EE70001B92A93ACC3FDBA04ED2ACFB583D8EDBB7
-:10EE8000B35B6BFC4D56BBF60F7E178DFFCD40F587
-:10EE90003348C7E5C1540DB97B067304C7F0BC4BBA
-:10EEA000DCB7B334E8C773580F70BDCD38C2CBF5AB
-:10EEB0004AADF63AE56726E0646034BD60CFC7DC52
-:10EEC000ADA6D6F9111F111E7F096D97283947E9A4
-:10EED00035D298CB5515587CB79BEBAF329C67FF6A
-:10EEE0004C66EEB2F67FDCEF263BA73754A8A23D76
-:10EEF000F9A4BCFCFB68070EFCD603789ED2FBE9A4
-:10EF00009974AFA137F4A5054807BD1230CF96AD6F
-:10EF10009FF10F4FFE8100C6EDC3E7198071CB81D1
-:10EF20005F40EC5E36BF2BFA689CF276C108C8B32E
-:10EF3000593F1F7461FE4AECCFFEF7CF6574F74866
-:10EF4000B0F28EB361280E60FAFFB5FEC4A3086765
-:10EF5000C7987F6B423EEB62702A6487195184BB6D
-:10EF6000324F26FE83BC606A127B5E7D38528BF97D
-:10EF700068D56A054A1A0607DFEF577C892710FF14
-:10EF8000B55A436D366B5F7544277B6541F4FA4390
-:10EF9000589F7994D73BDC40F620F22F58F8AFFA0F
-:10EFA000C3F1B4BEC3428EB7478D3E431A653F34AA
-:10EFB000D5719FC39EC762A5036DA68D0E122E2B21
-:10EFC0001DCC667430D54A0786F459E8E07B42DEF2
-:10EFD0009E9A5F389FDCA870BE194EF7CDDE9CF27A
-:10EFE000E1FC61CEBBA92A2782E7AB261F68B36E7E
-:10EFF000D6B0EE59E68E23DF997C61F283E21BE402
-:10F000008B8B7C6C7F9704F5F333F105FA7156FA1C
-:10F01000BF78043E5904038730E77E910AC92C2645
-:10F02000427E35E78DD2F116BA77E269D13C098E7E
-:10F0300059E4D1C993BC6EC1A3369807AD9C3EBEBE
-:10F040005F50F58E8885EF3A99FD8C4661971C8359
-:10F05000BC62E4BBE541CF0CBCDFF07094E2FB9EE8
-:10F060007813E5ADCD7A3B7035A3C33F8E91755CC7
-:10F070007C87BEFC21E2DF97038076DBD699D74DF3
-:10F0800040FFE48FD72626609C7323C3FF31326E86
-:10F09000526365CA85EA1FCBCFCBF4282F1351FEEC
-:10F0A0001CC4FB94A81BA25D3FB563FB6C9387DB7C
-:10F0B000BD5C0E6EF7723B70A3BBDB8BFC3550EC76
-:10F0C000A5F354E7FACFF5707E38D70355B108CDD4
-:10F0D00046F1960EAF52D7C3E350E973D9F37327C5
-:10F0E00096DD6BD58F66BF3B5A53F1D726E17A7612
-:10F0F00051995B9F023C37F09725758CDB7BD7419C
-:10F1000022937DB8C3CBE304DE03FF40E74DB9A5EE
-:10F1100031F24F23F56C3CCBBE2E6228CC62728656
-:10F120002DCB407AEFD0FD64AF2D8AD4BCA94E1B05
-:10F130004E07F8E798653FBDFFA3247AB91F477EC5
-:10F14000C85AE1F7D59678897F3A5ADC3D184FBB0B
-:10F15000CC934DF8FA2052336A9E2DFA5749460F48
-:10F1600029E65F6189E720C933F83908D6F11C0424
-:10F170004B3C07C112CF41F03D9E8360FD27AD0699
-:10F18000D5F13C04EB781E82753C07C13A9E836042
-:10F19000B9AFB589CA7F6C6DA6F78FB7B6509DED34
-:10F1A00013D9E350968C2E6678EEBAC96DE0F976E5
-:10F1B000B7D88F8346492EEEA32FC2FD53DFB3B7D6
-:10F1C00003AEC717E571A5CEE8ED70252BBB6684AD
-:10F1D000BA30E0E57D2848A54FBD0330BEB0534AA4
-:10F1E000366124EFC60DFBCE53991E2F8D5E5F93C3
-:10F1F000C3EAB76C78723DE6F74CD6DB62CBB5A1BB
-:10F20000BA1EAABCEE614B7D42798FEA67EDD779D1
-:10F21000F6AF477E4638D0C8DBB2E1E0796DA58C09
-:10F22000984A80EE790C14BB53488F57E17E4D42CB
-:10F23000F8B9FDFF65581F457F7A82EEAE443E6205
-:10F24000EDD39C7E4FAF7D371E66CD18DE6FB47652
-:10F2500072D569B5036594F1F0BD34CA381DB05E4E
-:10F26000C33B679B91E731EFC817207FAECBC5F951
-:10F27000B7CBC7CBFF167C7BC85B13F7B232EEE58A
-:10F28000FBDAE58BD7613C7460AA4C71855E171B75
-:10F290000293775B8A7F5DC2E6FDE6332A607CFAE3
-:10F2A000871ECEFF932684B85EFDB697F4EA051359
-:10F2B0007EDC9EC3EA93EE8BC5504F6E86981FE9A5
-:10F2C00024B985F3FB8FAA26E634B0E667CD782C07
-:10F2D00007E30DAA802385F79258BDADE3EA09182C
-:10F2E0000FF9E3F35C7EFD54CCD3E3EA6BA6FD9CFF
-:10F2F0001124FB82618CEC87B6A84AE7F7723E2F97
-:10F30000DD2EED6FB09D9B29E82483C7FDE92C2FEE
-:10F31000F9E91F7AC47DB63EB22BDCBE8496CD9E41
-:10F32000772765E2F7F59A3F8529FB9B839574BFA4
-:10F330003659AE527EF6E6721EC70B842E4DA13DA5
-:10F3400071DB7E1F970F412FE569A5CAF71EAE89B5
-:10F3500060296BC8EF2963711DE15D9335CAF762BF
-:10F360007FA3F74D11CAE7DE0C625F9A64F2173B88
-:10F37000C6FCF95FCFC673F1AF6B3171C788F22558
-:10F38000C90492F1BEEFC08100C2F3B7E6FDA4FE4E
-:10F390007501D6BE7DB916C37D98A6D5D4611CB1C2
-:10F3A00043ABF1225F05A6D67A97911C1ACC67A6CB
-:10F3B0007B70EDE5DCAEC5F7C897D00E87F0DE4B6D
-:10F3C000A1906581EC4A09EDA18E7A0A2F61BEAF4A
-:10F3D0002D3FB33DE742CA7F5716E5109C1D60786C
-:10F3E000B17DB25E25FD5518F4A6D1DE2B34E38B3A
-:10F3F000989A6CF1377257D8F39BF39B54DBFD8FCF
-:10F40000B1097B3D4FF80F798E3C68C96B9E23DABA
-:10F41000F1E45C6F6EE4DE6C8437172F34EBC3D7F6
-:10F420007347A4B201D759A8F909EEA8B6AE1AE5F8
-:10F43000D758686E43BAFBCCF03AE09C56DEDE87C4
-:10F44000FB3E4D57E9BEC3D930B00EC7DD2CE8BC3A
-:10F45000ABD8AE4F7FE851C43970CD1CE4478C87E0
-:10F46000252DF31727FD90B4CC37B12BC7569FD469
-:10F470005D606B7FC6F612DBFB29A9336DEFCFDA37
-:10F480005569AB4FED9D6B6B7FF6BE1A5BBD227D60
-:10F49000A1ADFDF4C38B6DF5197D7F636B3FEBE58B
-:10F4A000E5B6F773FAAFB3BDFFD21B6B6CF573060D
-:10F4B000BE656B6FDAD74EBD38DDFBF9EC6A0FDE47
-:10F4C00007B3C50FED76BBD3EEF6FECF7A7D1DCA2E
-:10F4D000B5B09BE85B453DCEEA6B6EE27E8F777EF2
-:10F4E0004C47B93245D063246818B86FD5612FE90D
-:10F4F0000335C8DBA9C10564778CDFCEE4D174B4D1
-:10F500001661F07D00E5726B325EEA1A82DBA77548
-:10F51000D3DD86EA701DC5DFCDFEAA66402284F3E6
-:10F52000E93CFF887995D8CEA7B3FE96753C29CBE8
-:10F5300074157C80F967F75AFCB391FC31A7FF750D
-:10F54000BAFED67819FC58F648F1662CCB9B9FAFD3
-:10F55000C1343CE6875DE565FBB3D51D6FEA61E329
-:10F560006E2DF1F3F332E1877515F7125F0C14ABD2
-:10F57000A45F40D5CB175BE260B709BB32E0BD8B1F
-:10F58000FC40B564F6611DF1DEA6527C62B3C4E3B3
-:10F590002849B60FA8D776CE7DE3DD5BD8736F8997
-:10F5A000B7D0CBE451ECA0DBC073D23B045E4BB4CC
-:10F5B0008A1A667131FBA2E1009693756667B0B254
-:10F5C000AC6CDB012CDBBC2534DF99B1876B50962A
-:10F5D00078E773FB4F99E64EADC3FDD3381C23D1BA
-:10F5E000999AB39D9F6795AAAF23BDA1557E521EE0
-:10F5F000A2031FD2814425D18F2F1224BDE1C30362
-:10F600001FACAB522AC0DE474A0D09F333AAC3DB55
-:10F61000E97CCE97B6DBABCC2FBD0DF11AA9B7EFC5
-:10F6200077C0BB93E06B97789CB62B5B7FB686C1A7
-:10F63000DF9557928331168C633458E4CD76A14F11
-:10F64000AFF0C9A6FE2779E343DEC81BB27718FDE9
-:10F650006F9727227CDD8072CB77733720BDFB3418
-:10F66000B69B686F7F2749F46FDABB3708DEAA2D97
-:10F6700069A473B1F7239564DFFA5A7E92117FBEB5
-:10F680007E058CE923E3353C7907E97B2871EB683B
-:10F6900057B4E86EA327D339A047F81F981F82F00C
-:10F6A00088FC902E810FF35CEE7D336F4A9C07DF60
-:10F6B000900DB6F3C11BF22AC78E668FFB987F9818
-:10F6C000B0C0BB91CD8378E9F8A4A12E4EE784C0E9
-:10F6D000EFB37D5ADE43F7863F59AFE339E62C811D
-:10F6E000EF733D1CBFE3DD407EC27918E7988E5E64
-:10F6F000E997EB902FCDB8C89BDE1CC27F2C094A3E
-:10F7000033D92B2E536FC927CF269875B719CF241D
-:10F710009397EB35F6EF7EBC7F31B1CB7EAF69526C
-:10F72000B7BD7EC6767B7D4ACA5E6756F311B40BC1
-:10F730001A80E3E7AC5DF6F70D663CB096DFC7F0E4
-:10F74000B2994F72FD6BBBFF0A42FF9B71D771BD2F
-:10F75000E96A14AF456BED7AB540E8F90287FEAC73
-:10F760000C29140FA83E1C3984F6A319A779C5A744
-:10F77000DBE29F66BCC529CFFD47B7017B437E75A1
-:10F78000C2C3E31009E6DFB41489F8C6385EBA14C0
-:10F79000FDB9A564A7359F81F2E99037F1B197E2F1
-:10F7A000CEF6FB12EFD5A9BF90743E4FC232CF8D7B
-:10F7B00065C90BF8F253947F62C63B4C7F5E091A11
-:10F7C000711C6F73EC85E683186FFAAD07709CF3BC
-:10F7D00095670FB7B2FA9A712AE54B6AB3567CDF88
-:10F7E0008FF1427CCFEAD5C5FA58A2FFA75DE4D7D6
-:10F7F0006F10F46CDEE331E323519FD03F3ED32EF4
-:10F800004AFA453EAC1FEDDCB37631D96CD3733C7C
-:10F81000EE66C6D7A6F6DADFF78294ABB1FD3BBB46
-:10F82000312573BBCA08565BE2EF678AFD9AB6348E
-:10F830007DFB5256DF03A94AFCAE4485A08BD8213C
-:10F84000FBBDB13120D1FD82314794588AB59FF676
-:10F85000B8FD7DB9E35ED999CE7B668E787048811C
-:10F860007797B1F9B6E8CD12CACF2D4B99CCC2F932
-:10F870007D22CF78324C46FA3B5F09C6D288DFDF63
-:10F8800028A4373CAF9EF1D232D4E7CFF33C166DBB
-:10F89000A2BEAD96D5B57F55483F6901A8A8080E10
-:10F8A000C58FBF773206EDAEA178D46EB6AFA59303
-:10F8B000D0BFF602EA959FB0FDC57A2FF3C7B1FE1F
-:10F8C00008F3C7B1DCCBFC717CFE53E68F637D1F70
-:10F8D000F3C7B1FC47E68FE3F3C7993F8EF56F0698
-:10F8E000AA1738E359D6F8DE503CAB5F32E359280B
-:10F8F0004A3E70EBB4EF8371AD048F6B9D7A1CC3ED
-:10F900001C87E286C3C611F1C3776EFAB707F09E73
-:10F91000F5CA19EBBAF0BEACD765C6CF789E84990C
-:10F92000FF6CF2DFCABDD7D3B9B13BFF4833EEC796
-:10F93000DEAA207D8BC8ED4A68281F9DFE97E977D7
-:10F9400039ED5FB374EA233FDA01D3D14EEAA6B8AA
-:10F95000CF261794D1FD59C91F43BE70C62B4D3E0B
-:10F960007ED15792F1BED4601EAD88CF7820E5C518
-:10F97000B89A5B12EB14799E24C2D8109B919F2DEC
-:10F9800079C9C1F234C539824183EC2F89D96564C4
-:10F99000A7698928C6A13A47C89BBD4FF0675BBEDF
-:10F9A0009BBE37D199CFF3046A8B6251ECBF3E7F87
-:10F9B00066D49A476BE6F91E0ACDF4F65BC65B1374
-:10F9C0002A19554F294CAFEAA3E855C5C3F3DCD734
-:10F9D0001F98E3C5FCE54DC1E57D685F6D8A46E88B
-:10F9E0009EFBFEFC99647F0CB68FCEA63C6725C8B3
-:10F9F000ED5625EA25BB55C5F5970FB537DBB5FAAA
-:10FA0000385D31F6A3F85C20D84BED3C6A9CE21FD0
-:10FA10009E08D0B996C7CBF30A82CCBFF6DAE2AB28
-:10FA20007CDE1611F7DDA427E2D86F5354D5511CA4
-:10FA30006D2AAB243CAF17785E9F67EAFD18D91B8F
-:10FA40003F137836C7592FFCF5F54D6EB2BBE22D4A
-:10FA5000D9466D2EE56DEEF1E1F8C17BBD9807EF5B
-:10FA6000CEAF1A75DC0338EE8CD1C67DB5A6763ADA
-:10FA70008DFB331CD71D5AAEE1B8AE11F2F39F13C4
-:10FA8000707E5EFB92614EA3733130F56D2A6A3D44
-:10FA90004F76967EB413A70FEFB752EF5F80F9C190
-:10FAA0002A24EBFCCAF0FB0DABF6F1EF556D55FBCC
-:10FAB000C8DED9FA8994F19EC418BF24CE6B07FD25
-:10FAC000709BBD5228F8A950BCD7D15E2946BFD241
-:10FAD0006E5F4C3F6CAFCFE8B3D767BDECB4578CCB
-:10FAE000DFA0BDB244C8BB3E269F7972C5808A7232
-:10FAF000209E4C5523DC0DD0DB86E7992E85E7113F
-:10FB00002C11FAEA22A1CF82FE6C82BFB0C96FF33A
-:10FB100013CDEF6E1489F1C7D51EBABE1D856BDCFF
-:10FB2000B47F74F22FC72D7CA49AC4A4C30E6A308C
-:10FB3000ECF7562F72D8394E7BA85AEDA1BCCC02F7
-:10FB400047FCC13CCFC475E2FD5DE7FC9F755E7369
-:10FB5000BC1D4C6FA1BD627ECF80BEF7C5FA8F532E
-:10FB6000D3522C48795E940F58B8168C9E0C747C36
-:10FB70008ED8F761784B9E4B783B4F3C2B08F2EFC9
-:10FB8000A514D42A29BD98E789A13C59BC82AD8728
-:10FB9000ECE593745E6DB6CFC9EEA5BCB21DF5124F
-:10FBA000F71F93407688B9CF3B82FC9E4DC33952F4
-:10FBB0004AC6FECD25343FC15532B4BF0C4FC738BD
-:10FBC0009E781EDAC575F6FB400D0E7BC3A4878BAD
-:10FBD0001CCFFB7DDC2F32F9E09D392F4F1ECFE08B
-:10FBE000582925EB02CAE9EB490B7FB84E221FE2E8
-:10FBF000DFC7D052883F0E781FD5288F20BBFF2E3D
-:10FC00006024D9E08764ED3C807FF60F9C25B17AB3
-:10FC1000E3A6B33BBAC6E1B5C6811FA151E6D950F0
-:10FC2000757EDD394375FF2683EA11310F732D92FE
-:10FC30007CBF2DDF3760F0EEC43C02B44B0DD8A67C
-:10FC4000600EA6AC6D8B150FF5CBC17ED228FDE200
-:10FC5000B04DCDD02F68F663E8EA34BF0752822555
-:10FC60007F2F0B78ACF3AB88374D0FD27D9F05AA61
-:10FC700086E73F5F148E31A75A7702B6B9260EEF9A
-:10FC8000C7C06E33E19733C39FC2F7D6F95DA3C0F7
-:10FC9000FF97C6C7A9C6738BF79F193ED67CDD9820
-:10FCA00091D78B70B9E8BB1A7A50B68C73DBFE8F94
-:10FCB000287EAD5E06749F4775195A8CD179B97646
-:10FCC00027F9E16A76AD8676C04656473B60636F9A
-:10FCD00037C5A9CB4B6FEF42A22F4FFB01E5C154B3
-:10FCE000D0B2F7B071A76A2A66EC807ACE2119E308
-:10FCF000DEF015A0FB2459FBFDFCFB17C573EF4399
-:10FD0000FF283BDB4B71A040F6CCFBB8B1CBE3C185
-:10FD100026FC81EA23351827571B2086ACA84A29E0
-:10FD2000A846269B02740EE137F6DE88F73299E288
-:10FD300023FD44DF8440BD2AE2E26339C940975B7A
-:10FD40006B403F21F98C4AF1F7B17864C188B2BCAD
-:10FD50003C671BC2539E600348083F8F6B4D4DC8E4
-:10FD6000B1341BBFF25DDE0F7EC9EF11305FA2F12F
-:10FD7000B1E0105E4DB93256C4CBA34BEDF164181F
-:10FD8000606B66FD2B7FB9F87E8C278C1926BFB976
-:10FD90007F6D7E6F27EB5D883F46E79A76BDE11762
-:10FDA000DFB5F03BBE97303968BFBF37CC6FF84E38
-:10FDB0009CF48007625E37D9174BC96E30FD911DE8
-:10FDC000D810E3FFE3807FFFCAD97F26EF0F51EE03
-:10FDD0009F78FCCCCCAB64EFAFF31B9417E4617558
-:10FDE0008647C90DDE7CF6BC40E67191360954ACFD
-:10FDF0000FCD97A6F3FC0D52AC2B260DF9BFEBB53A
-:10FE000018E519C0DA1C9BBD6CE6ABAEB9B6786CD0
-:10FE10000E2BB386EE0D69488F6BF24AC97E0EE752
-:10FE2000F67F0DE5EB47FE5BCFF7A23CC53C87B9FB
-:10FE30004C286FEEEA483279EBF9B010748B5DE62E
-:10FE4000519B290EE6F970BCED79BAD57ECFD0086A
-:10FE5000CAB5384F514027BC5683D68EFDAAC17E05
-:10FE60009FD0F361BECD4E1F1ABFC8F63CCDEC1932
-:10FE7000EB772C461E3F007A9975FC89238C3FD97D
-:10FE800031BE9671FCA171736DE376A83C3E9A8CED
-:10FE9000F869DF9DF64055A0A63890374AFC3EC071
-:10FEA000E3F71BA2CD14BFAF01C6F08C4ECEFDE42C
-:10FEB00098C2EFBD01D96D50648FDFD708FA95194C
-:10FEC0004520FD9EABDABF1F361F9CDF13B3DB431B
-:10FED0002F21A3B079E550551FC5F13F0AEAE87F0D
-:10FEE0008D642FF7B502C58FE707FA6FC073EAFA82
-:10FEF000C0F75D1DB3459E6C01C0DF04F69E8FF711
-:10FF000003FBC4BDBE8E884C7889D78CA57B3AE6AE
-:10FF10003871374C42791897797E02FD61F3F7E525
-:10FF200015D8F21CCCD2790FB4C190E2A516BAE96B
-:10FF300093195EADF39D57D8A358D611F7C00C9A0C
-:10FF40004FD8B983F38DF97CF33D2FE24EE67C0D5B
-:10FF50000BECEB6B706BB4BE06C1BFE67CCFE3FA73
-:10FF600032E0F794F3C99C6E06E7BBC0BEBE068FB5
-:10FF700046EB6B10DF031E9C6FCCE79B6F83AB39A6
-:10FF80008176DB3689F3FF77373FDE81FBFA7EFD32
-:10FF90009A28E90361175F841D58BB8B543EDFA28A
-:10FFA000226FAACD32DF0E26070C910F6F78307FBB
-:10FFB00043A37AAA354AE5BDCCCE36287FA38CDE92
-:10FFC0003FD01AA3FAAED6D9549AE394CDE6DFA770
-:10FFD00099324FCA686FFF32C0FDC66DF9DA6557B6
-:10FFE000A15EAAF6F37B93B3BF0486C5FE6506F156
-:10FFF000011F9EBF5C0A15A8DB266FE770476AC722
-:020000021000EC
-:10000000A470FFFC1587FA5A59DDE372E9A84F196D
-:100010002FC433F9A98703DC0FF7B8B9BC87B9FC43
-:100020007B878B845E01A55E72213E2ECAA6F3FEFD
-:10003000C54B8C90C6F0B644927E532AF414DE6F02
-:10004000B9446C95D3CE8FA0C660E3460C2585DFFE
-:1000500031BAA4E87023EAE578E862F20FE2AC6313
-:100060000E1BE712A127AB5FF500E63BC0F96E82DD
-:1000700063C912BB3DBFCD97D6D03ED9561101DC26
-:100080009FC5F5F6F71E37E7C3B8E3FB068B4EF1C5
-:10009000BD03FAE656867C53677CF24040E4AB8AA7
-:1000A00038E40928BFAD165F164546FDDEC14D0197
-:1000B0002E9F4CFD369C8E393C7F10726C47EB3E78
-:1000C0008A8799F015A82909E57561D33E5B5E130F
-:1000D000432C19C3661C1E943D15E88738D7B343DB
-:1000E000DA933FDAF74D0A407DBDBF4C7CFF531ACF
-:1000F000BEEE5703F6F8EB0998F75C2964E21F1E81
-:10010000775D745889B5E9437831F1F0FFCD475BED
-:100110001166563E77DE0755DC7F2BB27D67D3FC38
-:100120007EF0C5837515540B3D5F749D9BEC1930B3
-:1001300006CA91EE8E9C13E0DF7B33ED97F46F657A
-:10014000B45FBEF8F8C6385B7EA71877A4FD72E6E8
-:100150001B5AEE8B0EE5C3637E89C4CFB10A30CF44
-:100160002DCC9F1FB3DB99B63CB7F5FB1F9430CE67
-:100170007717E6E359CEAD0B993F8FF1AEA215F696
-:10018000BC3A275C665ED5E07DDB794BB43D3A7DB9
-:100190005FB11B3F58D3B53D19074B1EA5798FD0D2
-:1001A000F4A79DF7079520FFCE5E54DCCB70C68385
-:1001B0006F94935AB18479AB296F352BA7E72466E6
-:1001C000E195F61B95641D3E57C6CE6D423C2C6DE5
-:1001D000F9760CE3775A6EE6B8F452A1BF6B829CB5
-:1001E0006E8EBAD2E3308E7D4D4E4D4D302F43FB97
-:1001F00096EFD078F347F86EFDD7823C6E7297D0B9
-:10020000E7CEF74BC4FBAFAE94E93B183E08A5A47C
-:10021000623C37EE9E4DF7F656ED8865BA1FF75CE7
-:100220003871B1151E5F29BFA70DD03B07F1B5F19D
-:10023000E3BB7B1F62A8CCF93848723447E1E35A2C
-:10024000FA7F2D386378FF273F7A91EE373F89F7A1
-:1002500059E6E2F6DDB300E3DF5BCD3A86E4B19E1A
-:100260006DD6BFCDDF0FD6672CA866FDB7220D3245
-:1002700022FBFD960B3A51CF6E95407C87BC6E01F8
-:10028000FA875B5DBCFD3F89F7F32F7CFBBEDB503B
-:10029000DECF74931FB855D823267CFD417E1FA95D
-:1002A000FF14F8BC45EC5B10F119F94CF8BC2513B0
-:1002B0003EFB738CEF209E7C9849C140F07DEC5D45
-:1002C0008BF9C6FFD00AB1ABD81AEE8AED7DF036B5
-:1002D000A0FE1D99F019CF313AF17970E5315A5FDE
-:1002E000A83488EE0D6C9C05344E06386E1D6D5F8B
-:1002F0009FCAE272EC93102F7384FDA778FAA2785C
-:10030000FEAF557DEF068DC991CEE2EEC64CF47D71
-:100310007788DBE5D923C4AB1F15F8FDBD16DF894F
-:1003200070B76BB7D37758DD12B71B36CEEE07C95F
-:10033000D2EF85106FCFE07E00E176CFE1DF470D91
-:1003400031BC638259A88AC3BF513F0298FF1D8AFE
-:100350001EA1BCD050553FF13B5D6928E07485FE7D
-:100360009A57D8678F6E59BA00E54C8E62D2E1F188
-:100370004EA41B65A84E74D493C3FBBFBCF578276D
-:10038000FA733B99FD82DFEB4816F0BC11E7FA9E49
-:1003900014F0DE13367E8EEB1B864F4FFF7DB7B118
-:1003A000FE5B27F17B39F3E5BEC62B912E2F0C9215
-:1003B000FDC59E375ABF93F307416F7F0872FB69F3
-:1003C000EB475E7AEFDC8F91E8F5D702DF9F835E23
-:1003D0007F9D89DE18BD1E71D0EB0790995E5FC9C5
-:1003E00044678C5E8F66C28BB3AE80B11DCF67D57C
-:1003F0003F2FD885E3A95F9EB7FD21562A7FBE39DE
-:1004000049BB19936CF750CD792AA4C45B418B7C0E
-:1004100037BFE34D391099C69D35733BCAB1D31828
-:10042000F704C2ED1CF7208E3B03E54B3091E9FB4E
-:1004300046DF0FF1BCF107C5BA46E29BE74EC13774
-:100440003F0D713A607CE30A9D06DFBC2EDAB37D76
-:1004500008854E8B6FEEA4D257CAF986AE2BCF1DFE
-:10046000CE3700AF74A23CEE2CE67C313EF44667FA
-:10047000B2C8C247F011BD5786EA24BF4D3E7A3B51
-:10048000F411F191B37F7884EF594D1A5C47BC1495
-:10049000D76D9CA5B5F3FB38FDA4B77B6060BF8723
-:1004A000F26C795EAB3F9934B8D9D007F87DC4A916
-:1004B000821F77A20F867ECE4C116752FB60716857
-:1004C000383F87AAD255D6EF0D1C12F37F1A8A57F0
-:1004D000E1FC3DD03F05EDAF91F6698E98EF7BD9F9
-:1004E000C69C50063A3F951EBA3CC4F3372F17F30B
-:1004F000E67CEC6D46FBD3C9EFF357FDE39B0F8C15
-:1005000032CED744FF8B439F9BFF2F0E65E6FF251E
-:10051000213BFF57E1773A33F0FFD74299F97F69E2
-:1005200026BC7C017E6F0A65E0CBEAD3C4F78F045A
-:10053000BE7FF405F1BD51F46FFBFCF86E1B01DFCB
-:10054000EB108FA781EF8D23E07B5388EC95470854
-:10055000FE901EA43876D72CD82B956484E376EBD6
-:10056000385E9D8FC3F0FE81C4E87EFE9FBB62991A
-:10057000BE4FC3FAFD83157EB3DF9C90B8270DFAFA
-:10058000F5E89FDFF5E520C5FB997EBC27F497953C
-:10059000FB0F8632C8FDF93297431F6FD9DB89FA0A
-:1005A000FE0B8CFF58263A5B2DE03E955D7058D0CF
-:1005B000075BF7E3A1BCE1F2AF47FC9ECA3DE1C493
-:1005C000C110F957FD0B515EEDFC568E84F1A82247
-:1005D000232DA19FF073A1C72A433ABFCF20FAED84
-:1005E00054D312E6B3EC6CD624BC6F6419EF97A118
-:1005F00019238FE78483C1D7172279673C8FFDE6E3
-:100600000CD9819FC94E6ACC367E1B22BB2DFE0AB7
-:10061000C9ED33EC72DB5C871CEFA6BC17DFECCCBA
-:10062000BFF7F2F3A02AECBFF86B56F97F34A409A8
-:100630003F948FF759F50F83EF9D10D72BFF8DA5B2
-:10064000133E275E4E056711EA793EDE4799F49422
-:10065000733CD36F35F7C98D3AC912D7718707ED4F
-:100660005E5718E549874CF790160979B26876B657
-:10067000B0DB353F8E7F978893DFB5E2F66A3CEFBB
-:10068000EEB959AB4014143471BDA7AF184FF14FF8
-:100690002D2CD9CE93CD72B0BFBB770A7E9F9CCD57
-:1006A0001BC179CF9D0769F41BB3D06EA078844637
-:1006B000BFF795E3E98E62FC74A3D4DDB81CF5EABC
-:1006C000C220BF57125D728AEFBCF1F893B96E88F1
-:1006D000569DA27D1BB5D702DDF49D8CD36EEFE94C
-:1006E0006ECC945F32232C9B788D8D8AD76884E200
-:1006F0005A267E87CFC3F7AF3ADE2C21BE435592F0
-:100700008657AF428C4ED05E924BFB289FE92B550B
-:100710009C5E80F925A37F67A3D3B4D7CE0BE77D7A
-:1007200071B8CC7623CF27DA39EE2BE0B917C5673D
-:10073000835C8E5143567FEF706EC6B8BF596E68AA
-:10074000D58A549775FC148F430EE64FC7A2686F85
-:10075000B500A747887AC90EA3EFB95BF6F39A30C4
-:10076000CF73DE99155F1E26F862F4FD42D0B4D334
-:100770005A0FEB772DEE2BA8AC5FE8F4FB8D5C9A5B
-:10078000BF7317D3E396EFA599FC3A369104FC1E8C
-:100790008DBF1C3489ED7F24649E13723AB8336890
-:1007A000D69374481E2FEDE679F9BA49275CAE68F6
-:1007B000815E43AE00D81EAEBF203A858D579A8821
-:1007C000E2A7F759FD2995E42FAF03D43F7588F4CC
-:1007D0008576A614637A4AAD7BEAF038E057A5C85F
-:1007E000CFAD7B8AE4DD601DD298CFDCE31FAC1B6C
-:1007F000DE28AB970CD69358DF29F4E4F670DD536E
-:10080000EDC4FFF13BACFC512DE8F02F4D7F3D7A5C
-:10081000BB86F70C925195ECAA8D0E7AF8E7B09B47
-:10082000F05FA525EE477A5874F3808A5757BCC508
-:100830009110F2C384E80749FCCEDE8479224DB5DD
-:10084000947FCFA127BA96F8B207F705785A02C667
-:100850002787F62795797FCA52B43F7E9DBF97B10F
-:100860004EFE368FBF05CA383F6B1E1EDFDB27E406
-:10087000C9536145945CBE6645DBC99FF2D6C91475
-:100880003FCEAA936D7A837E298FDAAB367AEBCF8F
-:10089000491C0C5BE523A4E3656C1DFE29911C3CFF
-:1008A0007FA92E53D7A2BFFD7D61FFB17DBA97E42A
-:1008B0004545C49FE0FBF64CC67D137839D5BEBDD7
-:1008C000D89A88D5BA46DEB74B2FE3F9F4CEE7BF06
-:1008D000137838DEF89FDF437659E91DA0EF7E7765
-:1008E00095B6511CD68CBB7AF656A70BF5A17CC0E9
-:1008F0007581F03C2C9DF3BEF8C9DF6B744FE42387
-:100900004FC6F324258BE3F9486B23F5631B4CBFDB
-:10091000D372052E85E7B1D9EEF199F7112E074E66
-:100920000C4BE2CBBE82726879A342DF77B802EC4F
-:10093000F914979B795F2D667E1CCFFB4A40F60227
-:1009400064C36549C7EF4C406C01DEB71FF6FB136B
-:10095000E27CEBEB8EBC89AF362E8BD58A76EFD35B
-:10096000FF5384BF253A97BF4B62FC3B3F97C42F90
-:100970008BD55ACEA35FFA54C99837191FC4473C88
-:10098000563B69383E96C725B7A69F1A2FA78B8777
-:10099000656AC5823C7D381E9CEB6718DB8A78FE51
-:1009A0003AC333DA9D23E183B5A3FD78E932857E2E
-:1009B00077668152EFC273902B1B243A6362F80D65
-:1009C0008BBCB8FAF32DF03AF1E8C4D7954F00DDAF
-:1009D0001BB8F2BB218AB7BD60E2277D2E9D5F98D0
-:1009E000E72796751EE3F95B1AAD73F1EC8A5FE0B9
-:1009F000F71512ED4CDAF2F5DACE019733CCE3BD00
-:100A000005B6EE6323ECBBED3CD0099F137E9FD06F
-:100A10002BCE733150D3E5A807CFCF12E763D32095
-:100A200026CEC7B2281DB734B3BC757E97CEA4B30B
-:100A30002B5A1A06E7C5F125480CD635BCAFF5B4DC
-:100A4000B2F512F6F73551FEFB87F1CB723BF0DDC4
-:100A500022307F97C8A0F3A62B04FE1A98C787BF41
-:100A600099762E134E78AEB7C8F0E941CB3ADFEB5A
-:100A700096EAC43DAAAC2553B15F72BF326D38BC53
-:100A80006BA2FC770E191D7E60A543DF24FEFD5985
-:100A9000275E4C7C350DE165DA67C1CBEF5171E61D
-:100AA000D1790DD9B9039297EEC39BE738ECAF49E2
-:100AB00037139DB764150B3B80AFDBFCCE1740337B
-:100AC000D9F74BC57DACA32E687C38C8CF752A2DCD
-:100AD00072EB3B39D5B76459FC63F35CC7FCAE9449
-:100AE00049CF977B836985D3A1EDBB5143794C09ED
-:100AF000CA6352B256E8888F2E7C3587EC9EAE2CA6
-:100B0000F49F03FCBCCAF7F4A35D97E843FBB7E985
-:100B1000AAC7BA67B0BAFFEBBF4ED2A07A0EE12DDA
-:100B200024F6AD5AEC9B099FBF9C3FB7EC1F8F9FEB
-:100B30009589F899D8C791F484B98FE6BEA11D852F
-:100B4000F4EB2B53FF9CE9F7FAE050D500F2692251
-:100B5000AA520E5D427AAD83BEC705FA4E3C7FBFF6
-:100B6000A2C565FB9DA604DED3C7F61B7DC22F89F7
-:100B700051FFE5F9BC3F9471BB7190EE93ACBF257A
-:100B80000F08BCE131B86FFDAC2FE689B1F1C6A00A
-:100B9000BE872ECB3C25C3E71D713C473F65F0DC8B
-:100BA00024168B59E4F5BE2C6EDFBE17ADEA9533E3
-:100BB000C45FCC72B937B748B5E4871DCBF736664A
-:100BC000FA7EA939DEE0F7E506EDC481A70ECD1B5C
-:100BD000B2133777BC65B713936F7D213BB1FFB676
-:100BE000B79E6A67FDFFF43B0FE9ABF7EAFCB40F71
-:100BF000B92DE7C17FE07D5B157F0390EC7BFA3E6A
-:100C00008EB7A590D623A90C73F83B627A4C427C30
-:100C1000BF891FF3C5B88A0EE910032E578D498886
-:100C2000AFDB853FCAE86C8AF53BAE6F66713BC3AC
-:100C30009CC7E38524DE3336C76574D04679A5F5B5
-:100C4000407AC43C8735F9D91CE74496DD0F3E0D48
-:100C5000FE3D91897F9F959BFFFD16B45F9F5128B4
-:100C60001FF46FA337D1F34B5BAEA4F2B2966BF9CE
-:100C7000BC62BE6F4A8993384E5FE3AFFFF64646CB
-:100C8000AFABF77AE85ED9CA6FBE792BF2A7B7850A
-:100C9000ED3B6BFFBFCC8E383800800000000000B9
-:100CA0001F8B080000000000000BE57D0B7C54C585
-:100CB000B9F89C3DFB4AB2BBD9DDBC96BC38E11902
-:100CC00025C44D801010EB86575109049F51026CCA
-:100CD0000884008104A4BAAD1436246040ACF155F8
-:100CE000F1AA7451ACB657BD4169E5B6D16E442D39
-:100CF000540AB1BED00A06A516154DE45156ABE50F
-:100D0000CEF7CD4C72CEC92E84DAFBFBF7FEFEF196
-:100D1000D77ECC9939F3F8DEF3CD37676F5C587521
-:100D2000FF986442CC430D4E8910D29C45CA5B6D3E
-:100D3000B4DC209501DCA898A7EDA4B0CE5132D246
-:100D4000398690B3F0773994276399781C0652441A
-:100D5000C84A2BFDB742C89943B77BE6D3FEE26D84
-:100D6000362F7D42FBC9B9CB40CB64AF4C1EA740A8
-:100D70004E20F3CAF228B43038D069242405A001EB
-:100D8000611A40DAAF3542679304EDBCDE7A3ABEB1
-:100D9000D518244E8011233E374B747E79BDF31154
-:100DA00050F4678DC8848C82F1F4EF9BF139AC0B61
-:100DB000DE9793D83CC4FBB9F0FE1880621E096C24
-:100DC0001E49FA7E1CECB94CEA014FFA7934254EE3
-:100DD000CA73A6009E7C230112D2692AB31332D7AC
-:100DE000F68783523E85565B58A690044CC73B73EA
-:100DF00009FE9D1D04FF5FE1FC78042112E994CEF9
-:100E0000D2A1677C23850752FCC595C8A17539140A
-:100E10004ACED2D1A369B3129317F0D93124D93E67
-:100E20004835FEE540453AEFD78D4E3BCCB36C8A52
-:100E30005C16CAC3EE53AE857EA654156D62C359C7
-:100E4000492A21F3D8BFC9EBCAF6E641B43E1834AB
-:100E50007987523ACEB3064330BF79C418ECB462F6
-:100E600013E9AC84503116F1F7E87CE74D967D71BB
-:100E70000E4D3B7296CE9334919787D0FEE74A7C15
-:100E800080202DD3F70EF3E207934F5E07CBE824C3
-:100E90004EF320DA7E6E67E574928F5536E0A785B3
-:100EA000BCDDBC80E9684FBFF47F95416D797E71F0
-:100EB000C1AB940C142FA169A381CF2E32209F5572
-:100EC000356BDB2D7CFF8A4F8803FA351EEDC13769
-:100ED000CC93DCCDF8654AA353A1781AED54B03C0D
-:100EE00063F24793092DCF24E43AE877E664D919F1
-:100EF000A6AD37070CC44727BEDF278724BAB6FD47
-:100F0000B99D7B2F07BC159B94C761ADB9E4CE6B2F
-:100F100092A17E9413F05C06CF06607B42A09DC731
-:100F20001A1A4A9F75F83EB255A9F86E7FF1471715
-:100F3000F929BDB61A484D347E22A401E9FAF28F90
-:100F4000E2B19F0FEE9342163AFF29F2377F1C4B16
-:100F5000E753F56393D7A2E0B20C40D7E95E268F42
-:100F600084F86C53283EE71256FE88941585E9F8FC
-:100F70005505874A2CB49FAAF512CAA9C03FC5F7E8
-:100F8000876ABCF9EBCB12C30AE25DF39C76660676
-:100F90007EA678FE30069E3F54E339F0FEBB235F09
-:100FA00056B5BBDB694F063E2785A4F02C45CD69BD
-:100FB00032217114E9BB6E01CFAC3D38F2E5A1845A
-:100FC000DC477C5B50EF904E63D9484A2723F145BC
-:100FD000D303A50E260753E4E3489F13C5B202F8D6
-:100FE000DA1FF8D446398CECFF469E0678263E4A36
-:100FF000EC71BDEF3DE334E37B5BCDC40778DE9A53
-:101000006E0D35D0AEDA7F74715A27D247796002FF
-:10101000D0F10F26F2B8127BBEF6804C8650C62C5B
-:101020000D480805FD0606E28871944A5F91E8F3D1
-:10103000FF1DC8319D5ACA6A6250E8B8AE20F185DA
-:10104000A2F08568B7CCDA3DD548B07DD845E7B782
-:101050005C318424BADE0289F1B3D554EFCBA04DC4
-:101060008D6DB3821904E621E33C143A3F239D5F62
-:101070004E2001CB8302490807075C08870432B081
-:101080007E686030C261811C7C3E3C3002CBB981FD
-:1010900051082F0A1420BC387029C2118149D82E5A
-:1010A0002F50827064E02A7C9E1FB806E12581598A
-:1010B00008BD81D9585F10A8425818A8C4E7A302F8
-:1010C0004BB13C3A703396C70456202C0ADC86702C
-:1010D0006CA0116171A001DB8D0BDC81E5F1817BDE
-:1010E000115E1AB81BE184C043580F0A08F010CFF4
-:1010F000E5F10E6581934A0A70B8027C1C4BEEFE46
-:10110000C1ED52B5D3F731F09D68673610BFBABD57
-:1011100068F735B71B2EA06B94FE4E73FDFC85F768
-:10112000C39F0E27BD746BF6349411B9975E969DDC
-:1011300025E10CFACFE5BB6611D00B243759C3A7C4
-:101140007DF5035BDF5FB8FEDA6AECF0C9C0BFF57E
-:10115000C41BA48F4A47BF2E413FDB14E3B4501495
-:101160007ECB7799705EA39D7E938BC2849CA32FC8
-:10117000833E991974FE7122F04B5EF21F26D2FE57
-:101180000636196004AA4A9CED13A9DE512613D431
-:101190008BDB084179DA16AFB5A7C35C0C1F84B4AA
-:1011A000EE1984F234A490D99FCE2B40BECC3F1AC6
-:1011B0004436E580BC852523ED2FB89290C785CDB8
-:1011C00080F61BE6FF1CEA7BFB33337FA199BC64EE
-:1011D000A513C9695126C65138788BEFA538FACACC
-:1011E000D0907F623C2D0F7F32F812C08B5A431390
-:1011F00013281CB12BFC1235A76464B873A28D961A
-:101200002FD94376035A0B3A9449765A1E75D0B7B4
-:101210009BB20119D3E99FE450603EA146079DCFE0
-:10122000D6C3C4DB40CBC5C75BE444A2A2BF99F8D8
-:1012300077A8E8621FDD313989FE337395B34086A4
-:10124000F78D9D71AEBCBEF4D906EB8675523BF2AC
-:10125000385D57A62F2C39557C72B54B1274280275
-:101260003ACC58DD6D84756E6B72DB917EF1CE12D7
-:1012700018B27B0A713EAA001F1B114FE6F583507E
-:10128000DE05DF51FC5E34CBAEC69B24F45A4D6BB9
-:101290005E6CFC5EFD6F86DF23C06D6362E3D70A80
-:1012A000BC32EEFC725CE5EA91E379AE31B1DB353C
-:1012B000BB983ED5E3799B81ECA1B68A8E4BF9941D
-:1012C000C91509D2A68D9CBFCF87D71FBB985DF9E2
-:1012D00077C1EB4D2EA62762E19528C9A82729BF23
-:1012E0005E4406C7D637D05F34FB758FAB8F9E3315
-:1012F00083BFD8ECA47A6E706C3D37D7C5E81D5318
-:101300007F713D63E67A5C8CF7334EB7038EB2474C
-:1013100080BEB6F58620C85909B1A35C104F32E7EC
-:1013200013673CF0C974D95902FA860C27E847279D
-:10133000E48582B04F1918540A6568064A19F09876
-:101340009E1BDA44BBCEA17E8691D29F761506689D
-:10135000559C86F974DD8942DE9C951EB5BC097BDF
-:10136000DF2B8F822FDCDB36E5307E9D45FD97C37A
-:101370007CDEBDFD48D86EC30FD3B76D52E9C16D99
-:101380001E0F9645FB58FCFB8DE0DFA675C40FF2DF
-:101390003121BADF70D02573BEEDF6019F07BF473C
-:1013A0009CE0CFB89A3E44FDE4A2FA4942FDC4C68F
-:1013B000CF0CC4FF3C48CBEFB852B17FC0E3F5F689
-:1013C000FF77FCFC948B30799AE06C9769FD406A5A
-:1013D000871490D30974EEA3015F66A4BB42181D65
-:1013E000950924047E2FC55BD800FAD7600F819D34
-:1013F000319B5B7C20CFC4ECC2F51F70F83F769D1B
-:1014000043DF3813940220EA99BBFF3ECD46F96FC3
-:10141000438E331ECAA76879B3878EEBEE24BCDCFB
-:101420006C43F9A17FE948C530DD1B807D14659FC1
-:1014300015DA0FEA2907A1BC157C92F1B47FD7D742
-:101440007B9A2862CA5DBED3301FCAD76700FA866E
-:10145000D30DEAE05E7E3E9F3F20E4B3579E9C059D
-:10146000429E2AF3501F4AEE94DEFE62F937BFE532
-:10147000FAD3ED6630967F23F8FE82FD1B3E5FE2D5
-:1014800056CEE9BFC4ED7D63CB765A5EE99195A354
-:10149000D4BFB3A7BFDD61A4652BF5373FA2658339
-:1014A000B5C308ED4AA984DA28BE7DD4C983FD8777
-:1014B00075342BC31FEC3F4EB448D398BE5612AFC1
-:1014C0001D792E3C86703D2B3D661C2F6EE89044A6
-:1014D000902B07E72B62944260C71DC54EE37CEC5E
-:1014E000AF935C4DFBBBC4CDEC82906BD05BCFE681
-:1014F000815E721B61BF6EB192A0DDDDDB3F941394
-:101500000B7BF513E1FBB89BF99EA9659D3771082C
-:10151000C8E97E16476959C3E4B2349384D6819EE4
-:10152000F011C549DBC711F1470597964DBC34FD55
-:101530006B89F8E8FCF77D2D23948690B09DEEF73B
-:101540004ABD5218F68166833504B6B424DD4ACC10
-:101550005076184216908F0F255CA7B9302104CA27
-:101560006F727A7162275DC7C97DBB6DFE28F4BFBB
-:10157000C15FE99D3C2A361E7BDACD79C509787CAE
-:10158000486972821F19F41831EEB0119AAAF4FA60
-:101590005C37F347A83F540E7C3A6341779319E8D0
-:1015A0009D938CFE1019E246BE1DE0D9B9B1044CE2
-:1015B000562DF34FD349A841ED5709FEEA74FBE7D6
-:1015C000BBE93C1EE276848A65C73088575D94EC9F
-:1015D00006BFB4A42EBD0DFCDD07D712EF0213EA3F
-:1015E00083EB605C5F526B01F0EF43DE9DBFB80B95
-:1015F000F069A1FB62D0E3A30ED9144AAF8A31BBD4
-:1016000053603D7FD4CD5FC08AC01AC48B7E1FBC9F
-:10161000D2CDF7C1F9241FF6C127BDD7248691B7D3
-:1016200092A2CA7745E036EC47EC87DF3785B39C5A
-:1016300051E5508B6F317E85C4F6B5C42431FDC7AA
-:10164000ED28D52F4DA8074204EDA6CF223D0AF67E
-:10165000E6A4779417EC762C7D23E643F138B4CCDE
-:101660001EA55E2265D1F4C45637F30F2A4C74BF11
-:1016700040EBA51563EA615E15769B047C27DA6D65
-:10168000E2ED043F8B78959CF8CD18A03FC407A3EA
-:10169000AD7F1E319E52C7A33681ACA5307C79A3A5
-:1016A000F82BB1F075D0D4520AF33AB850260DB4E5
-:1016B0009F93FEB16924CAFB02BE077C43E9B22AAC
-:1016C000898DD743CF21D1F177706D8D77B2A997EE
-:1016D0009E7DEA2BE3CAC17E97031E55E31E70333D
-:1016E0003B7F8C4362F12B4E5A6F9E7FBF938C04DD
-:1016F0003D756A4CD00E71B1EE5F3500BD7F6CC791
-:10170000784579E5E9310D2355F82C266824E7ED75
-:101710007ED0A9D0E7E5439B5282B6D8783C0678C4
-:10172000A478BA031E8CC378CC1FDC17108F2179E4
-:101730006EE437B23BCE1B8678E45BB217FC06182A
-:10174000D78FFA93C5935739D9BCE2747E5E79601E
-:10175000B946BF244424124A52958DAD189F4D8836
-:1017600018F1B95EDE9ED2C99BC07F2C7A0AFCEBD1
-:101770009FFF9EF3E5C1CAC50AC40DCDF1D1FDE0BE
-:10178000EC2449C3576FAFF56BC67BE75B59B35F7A
-:1017900016F0EFBCFF93FE716910AF2A370787F68A
-:1017A00047CE057EDEFEE60127F41BF79525AAFC51
-:1017B0009DE2F689DAD3E6EB14953DBD516E02BC8D
-:1017C0002718B97ED3C99D0FEC2AC5E7E56057E914
-:1017D0001413CE6357E791603BC491F5E30B7BAAEA
-:1017E000E72F615FF574137CE049A2F44BE8A59FF5
-:1017F000881BC6922F21579D5CFEF5F8D7C31BCCE2
-:101800005ABF47C0CFB99C9DF4C79120D58F379759
-:10181000C82122217FA07D3C78BF84FE66B8D28299
-:1018200076B9AA320EE3B3550532D657DD29A3FDAA
-:101830000C53FD504BE7F347AE27F4F1D912227950
-:1018400027ABD63D63749CA67CE3C27BFFB816E24F
-:10185000CBC52605C6DBAFB07873D027A3FF4AFB04
-:10186000F086213E7DDF655EB067821FF6FB6494E3
-:10187000B7E09BB21786EDE0F1E8FDCD052119E850
-:101880002CF97BC6510643FF550AD0E15DCF1627E0
-:10189000E8BBB86F1F282BC3FDA35F2940BB499D40
-:1018A000553AEF382EA793D28BAF073BFEC1661394
-:1018B00081B8D107AB4FA23C77AEADF74E1EDA1B15
-:1018C0005F16F1617D9C591F5FEE1357D6C59305D6
-:1018D0003FE8F9A422067F087D158B3FA81EAB4A7E
-:1018E0004AB9703D26F4C77B7C9D93D2B7DCD940C2
-:1018F000F190B040463C08BE7CF79BDB1F013D1CCD
-:1019000047F9631DF0F3B74FBC02FB10B2588A1AB7
-:1019100047DEDE63F7285D727BE972A37F714F19A2
-:10192000C47F76CD8A9E32AC5F6F5762EBB573EBA6
-:10193000AD61492C5EA1B73B7A79F857DB9DF2CABD
-:10194000FB73E1FDF2CA8521801BD3AD35A07FF585
-:101950007A426F27C47CF4F34C88C824344A3D6F24
-:1019600005DBF5DA0933D607AC8E7C70D6CFC431EF
-:1019700018042710FCD2C371A1461CAFFE92329C02
-:101980007FFD588001E2ED0CC2FA3CF1183F68C9B6
-:1019900064EDE52BE2993F3EDA8DEB9485437ECAF8
-:1019A00085E546BE86516EFF734914BF8D3E431CCC
-:1019B0009C2B4CB21BF742C8A565A28158482F9EAC
-:1019C00084FF4E203240D78B7512EC3B0BACE6C146
-:1019D000E89FFE16FA216BE8BE90F2FBBE7DF2CEC8
-:1019E0006D7489FBBCA312A3F9E702CEF1FC10F5DC
-:1019F000C2F5812A84877EF04E36C8EB2D92FF55C2
-:101A000090838EF2AA3BE15CB86E978CE74A736EC6
-:101A1000797718DBA769CF2765873517E2288D52BC
-:101A2000BC17F488C063BBDD8CFAA5F110D3838D9D
-:101A300047245E66FB889779FDC9F7EDB8CF10782B
-:101A4000A7EB790BC6F7DDEBC2F5887DC677584F5B
-:101A500027E027F67A329DA82F80AFE4DEF9CB7617
-:101A600023AEAB8BC47B61FE011E0F22EFC7A1DF4B
-:101A70002CE85BC7F94FD07739A76F57DBE99F5C3C
-:101A80004ADBB7F8DC78CA2067115C6FD7FB09C85E
-:101A90001F62BD940F4EC1FC76B7313BD172D8CED8
-:101AA000F0652FCA85F909FFDA99C4FC64FDBA2BE9
-:101AB000C43E9DFB19E0DF429C62917BE2D9A431D8
-:101AC00051DA73BF96E2D9904CEB4B9CE45488F406
-:101AD000E2598C23C615EF3992B57E4C058F2BBC8D
-:101AE0006F22E5104F84710B55F35BE32E7124A731
-:101AF000F41DF73BD07140F239F9524BC73AA3AD10
-:101B0000594A243DFB620CA5297DE55C2F67525B99
-:101B1000FB57703EAF97FF33867A22D17E6F95FDDB
-:101B200007DD1436FA49A765705F79389F1EA1F466
-:101B30002E484EE9AB4FFA4BE709C952CF3E86D348
-:101B400079427214BD27F03DDC5DF63DA887F5674C
-:101B500014E23ECF0774073D611E84E3215F76BB2C
-:101B600048E851DA2889C751C47C202E1147DF9BF1
-:101B7000999C83E34A461234D17252AE5702BDDFBC
-:101B80000F3E98F92FE6839B92CF29CF61F44B96B5
-:101B9000717A2F1379163BCF9D67D10FBAD5C03A12
-:101BA000CE18BCDDFE9C0BA7DBCDC97DE4F3E6E4DB
-:101BB00073C8E770B7FF1618AFD14C4EA11F5E5C1B
-:101BC000E981F10E387C9F24D2E72F36707D924355
-:101BD000E946EB5F4996515FDD432E463DFC3D8370
-:101BE00001E7DF45F5EFA339D1F83E6874D3F7CFAD
-:101BF0005C4DF03C8EAE6F3DE3CBA004CF6F9D47B4
-:101C00000CF0DCA33410C305E8A196BEFCD9722EFB
-:101C1000FEA47AE85EA8A7FCB80AF8D1AA388DE736
-:101C2000D2433F4BD6DAF97EF0DFCFD478FE17F0FF
-:101C3000DF2FCFCD7F17CC57CF45D307828FC5BEBF
-:101C40002056BE10954792E1EE3B2E215E3C0F2BB5
-:101C5000715899DDDD21A19D6D3C52E0C7B2DD8A4E
-:101C60004A41D8E1133B59BD3C31BA3FD896EC66A6
-:101C70007906AD2BBC464D1E48109FDFE53BE11CAD
-:101C800042F5E254D986EB4B2A65F143B17EAA674F
-:101C9000A74F49E57153BA9EA42C868724EA0FC04A
-:101CA000399A83EF0F128B8D1ABF5FE0ED56B94C56
-:101CB00082B8B72B9940DA0DF5EB570F87F37B9776
-:101CC0004FDB3E856CFE52C64108CA839BDA6F88A3
-:101CD00063254DD3B5837D483EB4573DCFE9BB9FC7
-:101CE000F83899EF27CCC4037685C815E7E41BD5EF
-:101CF0007EE2F3E47EC4454E261BF8798AD67EB593
-:101D0000C691A871818614BE2F38E542FF57E6764A
-:101D10006B72670EE6A7ACB42B182F9065AF757A7F
-:101D20004EDFF75D3E035154EB4B9A164F14D5FE30
-:101D300021A5CCAD29A795A76BDA0FF00FD2D467F8
-:101D4000D45CACA9CFAA2FD4940706C66BDAE750AF
-:101D500001509707375FA9693FB4E56A4D79F89656
-:101D60009B34ED2F0ACDD7D48F787289A67E64EB91
-:101D70004A4DF9925D3FD2B46FE4715F3D5E2673C8
-:101D8000BC361A99DE69B015623CB2D1A68D4766A1
-:101D9000F37625891372210EDEF861412EE0FB6592
-:101DA000C7788C8BC7E20BBD1E8BA53FF5CF2F4BA1
-:101DB00061FAEE8B97CC069083E5BBA9BC5E42CB63
-:101DC000B6F736C09A9AF3D879AA91B0FC1E71BEC4
-:101DD00022DEEF395F317A597CD561239BA2F04531
-:101DE000768A1235FE29F82816DE1AFA89B7297C78
-:101DF0001DDF156FEF4B2C3F55ADFF774499D79AF8
-:101E00001416DFA2F6655E0AF37746C7A327EE44F1
-:101E100079BC50FD2FE641F5FF9214F443DF98732F
-:101E20002BE8FF9D162FECC9BE287FA3FA0105DA27
-:101E300057B3F6066F2ED02556FC7B4D4A9FF87798
-:101E40000D8B7FC76BF0562BE45D17876B747C8D11
-:101E5000F1EF46B337B73FF1EF5AD031294007C60B
-:101E60001F3DF4E5F1F358FBA000217B25D8F7D8FE
-:101E70008C0A9C739D6F5F4BF7B3B9709EDA02FBBF
-:101E800026D53E87EE6FF9FE260EED02B57BF7A64E
-:101E9000A0DE237B15FAFC0CDDF76E52A028EC9F28
-:101EA0004FE3975B88D76A96919E0FA6E07E97AC2A
-:101EB0008A93215E16DE3721E73BD9F3ED291760BF
-:101EC000CFC9F9CFE5D0EE94D2F5AF8BE277E9CF69
-:101ED000E17AFC6FF0D3243C8F433CADA77611CE62
-:101EE000E3DA53987D5E7F88ED93D71F99E541B97A
-:101EF00049293AE7395C7FF5CDAB297DFCD25753B0
-:101F0000CEE1978AF5AFE4FBDE29725E2BC41B4F4E
-:101F100044CC883799B0FCC8BA3D2612427AB23C0C
-:101F200063414753644307D86713D1E7152B89B042
-:101F30006ED31E19F5134966F541626D003F27B156
-:101F4000586BB75C3EADDD4A9AE6D6D931ADDD4A75
-:101F50002BD7DAAD017EADDDCAA829D4D931ADDDEC
-:101F60001A1898A8B3635ABB35B8F96A9D1DD3DA1D
-:101F7000ADE15BB476EBA290D66E8D7872A5CE8E75
-:101F800069EDD625BBD669EA0BC29B34F5A3F6DC16
-:101F9000A3298FE9F80F4DFB457B9FC3FC9BB1073D
-:101FA0001FD5B41BD7F94B4D3B8AF00EC8D35E80CA
-:101FB0002421E4D263CF6AEA17703FEDB2EEDF6806
-:101FC000FA212D2CDF3A48FF037AFD95F8CDE09CED
-:101FD0001849F7AB1994AECB4392374C9B2DDEB525
-:101FE000A308E6F1D9E12BF6403F8BB668F3B417AE
-:101FF00087B4E53A322811F4431DE58B10E593A52B
-:1020000090BFADD26B4B49BD03F321FAC9678BF684
-:102010005E4330EF33E8EB80FC74B14EC16F3ECECF
-:102020006F627E62BD4BA9DF17567AD7E9A3FFB175
-:102030007D64A719F8B67A9744FE43EABB9E9AB628
-:10204000BB37644459977E1D7ABF734CAA368E3DC8
-:1020500045B6615CFFC49BB297C507B572B8722FD5
-:102060008BE7AF7C5AC2F89A1E1FC22F8D85173995
-:10207000C8F60975C9241452C99FC2F161F168E517
-:10208000EF04FC03E6F3B01C82BCA038255ECF6FE2
-:102090004561D217CF09B95A39D5E3D9EE4D8FCA68
-:1020A000570AFD0FE6514DD8B9949EAFF4785FBE44
-:1020B000EB6E33E8C50BC5FB8254EDF9A0383F2821
-:1020C000A1AB3547C9831378A5FBF225A929B1F740
-:1020D000ADB7A45EF0BEF596D47FEDBEB521F51C7C
-:1020E000F1B32E889751BF521F2FEB1B1FDBFD95BD
-:1020F000E4C038348B7FF9BD5696AFA2B393B91EB6
-:102100008D9DECD9F77E28851A69E7F50E5F0BAC3B
-:102110006F85C37737C0990EDF3DA92AFC3452BCC6
-:10212000E0FD1C6AA77644F10FF7A50ABFA80CE3EF
-:1021300022EB4B587B7DBB5FA7B2FB40ED29451ED0
-:10214000F43B8F1430FB692F3AA7DF79173FCFB9E3
-:1021500003CE0B87F6E6F1DCC9CF55A8D8F9806E1F
-:10216000EB4D651E759EEF83A92E1CCF31EED90E67
-:10217000C8776E741A9C9202FEB301CF459B7CB661
-:10218000693BF3D87BC99AF7D8BD2319F00DFEBC83
-:10219000CDF8B59A6FF7515C42BFB1D6B92F95F91A
-:1021A000BB26E2B382DE15E7B9A60F0BACA06F8D9C
-:1021B00092D7192D8FD3C4F3A426F2F35CD9C9CEDC
-:1021C000777BE4FC3C7952373BFCAFA9F9549CEB9C
-:1021D000CE76F8F6C1F380316801FF32608DBEFF24
-:1021E000FD13A7E35DB03EA4A70DF908C797FB1543
-:1021F0003FF9732AC6E58298AF78ABEC3D06F1B99A
-:10220000FEC6AB3E4EED13AFFA58CD877AF9A3FE6A
-:10221000E72789908797986EC4ED84D19B0BFCDFEC
-:102220000CFF1E87F1D5CF61DD7DF24F1537CFA7AB
-:1022300055CE994F2BFA2977F94EA5B2BCBFBFA551
-:10224000B2BCBF2659D58FE33CFD503CE5D6DBFA46
-:10225000853F396D0CC6358FB160C285C5351D69A6
-:102260007DFC4747DA39FCC733878627C279B288B5
-:102270005BE9DB59034999EAFB31CD2EEDF81B0AE6
-:102280005979001F777922E3FB91698C8E220F50D8
-:10229000C4ADADD3890FEE3BDCC3F3B3453F23D3CD
-:1022A000ECD83ED53D71645A0A9CA749B8AFDCE032
-:1022B0009234FBCB4F524B46C27A86F3FE47A6318F
-:1022C0003EDD3688C567F479902778FB13A9131192
-:1022D00052825D04F834CB72543C16A6B1F97F9259
-:1022E000C8E45BC4CFAAEE67F7BB44DC4CC4010969
-:1022F000F1BE9D40F5CA479B4D04E25A0B65DB06D3
-:10230000E0C39EFB73FC5CDD49FF037B5999578654
-:10231000F947DFF5FE16E033C1DDD75E5E99D6E3FF
-:10232000A7782FF01ED7ACB40B386FEF8C677CDB2F
-:102330006DB7613C5BDF6E29E787CD3C4E01FA1A31
-:10234000EC865B26F5D1ECC7528EF733872C3EF432
-:1023500063A6C5633E8738FF3052FE4C74631A781B
-:1023600010A035909109F7897ACE3F1482EF25D9D4
-:102370006CF89E5121613B5C09357A25C82FEB34FE
-:1023800077AE4F83F95E2679E1FE405A85B33D2D45
-:1023900019EE112A28661B7288A318EA0B0C58EF55
-:1023A000BAD6B9C10479D70A81936C62A2E3D8E99D
-:1023B00038F7A6E5B07505AF694FA3ED12956E32FB
-:1023C000280FF48873AA07E4B89CE5AFEBD7D7C40D
-:1023D000F9D5B69EEE1B001F4AF43CF0A63483C824
-:1023E0009B6F047E2D51C84E762F8AE5A1429A3507
-:1023F000E60B7A59BE7402E41B0D667A06EA7FEAA0
-:102400009AB411DE13F225737C03DFABF3E1EFE541
-:10241000E324E9E453E0930ED000F910C6E904F98F
-:102420007A6645F4F93EC3E9BCCA51F620F0CFCC38
-:10243000090D98E74EBE397B562E02A797C9097D34
-:102440009F401C222E99E9DF3845417D4C9C12E6C5
-:10245000995A156F0D94E36CE39D32D83D0B3F2FD5
-:102460005C6020462A6F93783FBE72227D9CCBE24F
-:10247000AC4CBF1AC9C7422E648E9C22B09FEC8F11
-:10248000FA459B13E87A26D9F6E13962DC90FA1214
-:10249000B857F0CA3CD6C73D31F2F63FE17ACC2DB1
-:1024A000FB3D06F0E9837F79EDE50948E78BE1869E
-:1024B000E61DA6CED7F65CC6E3E7982FDEF99A2F85
-:1024C000EF9FCF2F7F2DADF3B5A6BCEFC2FF5E0906
-:1024D000F4F82794B160DE7AFE17FAECA0EC3F78AE
-:1024E0001BC5FF7594A90285008DA402E9CDF28772
-:1024F000AEE5780E7E4DF16CEDC5F3756D7B117F09
-:10250000074D74DE747CD344866AD38F12793E46BD
-:1025100008C7BDDEDA3205FC9B2E73773E8CDBF5F7
-:10252000C23B5941AA4F0EFDF8A49D50FEFBC0D8F6
-:102530006D87E7C756BF61F751BC1F5A2DE3FD37C2
-:10254000BC97ACCA07FA9CCBCB959EB2A3C057F3FD
-:10255000D67E5BA4F6B3492005EDEEE2900C777CC5
-:102560007BF4DFD2271338D3B1F2B2D6244D59D839
-:10257000E36596E8F7C40779985C2C7E6A9B19F2AC
-:10258000E1AFF4F8FF06E31FE3F906C776DA717FDF
-:1025900025E633FFA90233EC273F68B39030F0BD46
-:1025A000B1C344304EE59B2E51BEF5733ED4CFF3FC
-:1025B000D51713B0BF85F7CB1847AAA46305285ECB
-:1025C000FD6D8BD9FE56B78E858794A9A0AF166E88
-:1025D00094485061ED5753BAF903B7E3F98A7E9DE9
-:1025E0007AFB729AAC36831ED1DB9705C4DB3C01C3
-:1025F000EC568BF6F9A2B63BB0DF45E7398FF178A0
-:10260000F8FEAC888C3D3B18E2CC83305F3096BD41
-:1026100039B69609E5A76BAD088FAF75223C0ACA9B
-:1026200094E279E9AEF6573350AC3B8AC00EC5ED63
-:102630009D64BD89F4FACFC66DD7841F52802FB533
-:10264000F990151CCFC27F5EC4EF199CCF7FAE807E
-:10265000759E231FB2A29FF99027F68CB2C2F3F1A8
-:10266000021F63293ED0FEE61D50C8F9ED6F2CBC59
-:10267000C47A6F197CE7200A9E85DC1CE5FA7DC1CF
-:10268000F6591BD2E9041A5FF86B7627F2258B43C3
-:1026900088732AD9B3A103D62F135DFC2F48DE24FB
-:1026A0002AFED5F3E722E26576C7C6DEB3F2B84468
-:1026B0000F5FB6DD8978157C04370A0C1E80618FA8
-:1026C000A1B8EF7703FA7C1FA0455BFEC2D4990D39
-:1026D0007A63912E5EF085147DFF35DD3388AD5F22
-:1026E000F14D85BC8885A46C038BABB7A09E3A6680
-:1026F0006C79F53690E7ED4C9E963DFFF4AF414F77
-:102700002DF9AFFB1DA0A73E31B6A4C278B58FAF9F
-:1027100077805E3F660C3AE0FD4F4272D4FBBA4FC1
-:10272000787ACE056C9017B61C590C042C3803F43B
-:10273000E4DF1E3739218E5AF7A4256CA1F858BE64
-:1027400093E191968FB0F2ED88AFBA5D5A395CF2A1
-:10275000C4FDA90AEEE783191C7F19A0AA976F3759
-:1027600061FEE8F237652F0C5347BA717DFAF761C5
-:102770001E114AB7BA56B9D29CD8B79E7A3C669019
-:10278000B3BA9D8C4E753A3FB386EB653DBF3FE0D3
-:10279000E17E26E7738A178C87897C561262FAB924
-:1027A000F1170FE41FA1F33ABEFD358794D7CBEFA5
-:1027B00004B22EC12F6FAD9A077906B1F8FC0B2E2B
-:1027C000173D7A9FDB1965179D18F8FE6D0CD69A98
-:1027D000C28E4B293E6AB799BC41FAB8F669D967EF
-:1027E000033FE95D0B7EDF61E9D3AFBC3D9ECE6F59
-:1027F000E90E53F274B60C1BE86741A73AE0EFC24A
-:102800005EBA2C79EE1533E441C2F3D5EE5EFA2CB4
-:10281000DDD16E86BC4A3D1E27B5B69B997CE9E8A2
-:10282000D47A642AD8E5C65F9C31031F7CF2A244A7
-:10283000C085D4BF5FB3ED1507E80FC013D80F41B3
-:10284000AF1EFAF5A15B78C66F46633B279CD3C4E5
-:10285000A25F00E63206F9FB99DFD0F16BDEB378B8
-:1028600061FD35CFDCEC8075FCD558CFF8FC91F5D7
-:10287000A9608F6B4CC1542742F6BC66EB0F90FFEA
-:1028800016BDFE8354827AD33700E497AE7300AC52
-:102890006FE1C3D7E1FAAA891FF9AFE611B90CFCC1
-:1028A000C4D346322D9A9FAF0C60FAE9AF8F5A70AD
-:1028B00053F0573361DFE1F893CCF2F8C80AF443E0
-:1028C0007EC0D74A3531964F5B199D4E79C4FD7550
-:1028D000A6C7EA78ABBAEDB7A31EFB34CB9706F2D6
-:1028E0004EF1A08DA7BE3E258DEB3FFC5E0ABE4794
-:1028F000F96E123C87F61D265F5CBEE63D9ED7CA88
-:10290000C65FC5C7A7F38E87B8DC5F53B5FB570119
-:10291000670C107A807410357FC592FBED1B91AF68
-:102920004EBDC9F4CAF2D0AC6958DF610AA7417D37
-:10293000A8FD5A09F502F52FA2C9F57613976B6D1C
-:102940003D9DA75152E3F745762FAEFA3EDA4EE5AC
-:1029500087F4F28DB9F7794EAF7C8AFC8A453AFF4D
-:102960004C40BD5E481FA0B57FE27DF2704AD47B2B
-:1029700058BDFA20887C516B0AFDFC3F408EDFB5C4
-:10298000E03DC3DAA74DF8BD9CCF9EDAFDF64D942D
-:10299000DF3F6B15F2ABD5B37AF9AD79F63A124D4C
-:1029A0007E3F4B2E2351E5973E8F2ABFC92C7FFFD8
-:1029B0007F5BCF2E8AA167270FD0EA59EA4F245EAA
-:1029C0004A8B9FFE72E940DC67E9F02AF0A9D79BA9
-:1029D000873C0AE257AF37E9DF9B448547813FC117
-:1029E000974BFE73198ED3C3BF823F05FFF6F0A746
-:1029F0007EBD5A3CEAEBE3E0CE514A2FDD4DEBE8D9
-:102A0000FE1ACE5D5F90F1DCB54BE976B8212ECB96
-:102A1000F36EBA9CBCEC62E5EE14F306D01FE279CB
-:102A2000771CCB43E82AEB76B8547EFD9136D9016A
-:102A300079F59DA1E8F91298499102B74463D53719
-:102A4000F0EFD6D8B203B02F6B61E73D0B1A6E7072
-:102A5000803FDDD536786639F8F17B65F4A9BAE2B6
-:102A6000797E55D0671C40F15AC5964C8E91E04F47
-:102A7000C1CFAE6A5B3A1D368D0B366BF1516DBB23
-:102A800016CFB3AAEF33F5F205017F2764063FABFB
-:102A9000E661EDF325905705F4D1F1911FF828CAAE
-:102AA0003D8C3B051F159002B64FE6E7555CAF4DD8
-:102AB00091F3669643FEE21E764FE2449B4C36C08D
-:102AC0007A9FE2E757C114E4CFE5948FD571CEE346
-:102AD000C067C363DBEFE3BF3A54741B6D52FBEB7B
-:102AE0003FE73F44E1F15FBF3BECB7507EFE9DEC1A
-:102AF0003F93BEED27BDF8D55CCCA37CD142605F8F
-:102B0000D4F5E2EFB36F83F26F2C5E9867D73AB6D5
-:102B10003F0EBE6847BBDE95C5FCBFC617CEE47747
-:102B2000A27D6A427AED1AC0EEA99E68FBFB61099C
-:102B3000F2E9DAE8AAC0EEF27D57DD6FE2707FDDE0
-:102B4000F5C219CDBEF2BBAE6739BFAFD46527E57C
-:102B500070BFB8CBC5EE77D6FD76DC63705F71D9F8
-:102B6000CE767315AD9FF4BB6FF341DF743DCBFCA4
-:102B700009EADF6E05977AF780039B4D14CF5F80DB
-:102B8000CF974EF71FE989A5700FA32F5E181EBAC5
-:102B9000281E605D142F35A02763E1E3BD01ECFE24
-:102BA000C8BF1F3EBE9C0BE3D7B68D25104FEFC5A7
-:102BB0008BE463CFED987741D7CF9EBF78261FFC7B
-:102BC000A3F3AD37F2FFD97A53D3FF5DD7CBF87DAE
-:102BD000EB00667FF47CDF97AF9FBF05CBCFD8BDFE
-:102BE00038DF7ECA7B51FABFABBCFFEFD0FBDAFF08
-:102BF000B3F4DECBE96D77C2794AD70BDF66930B6E
-:102C000058F7CDFF47D7DDE3E718BCD6D1747EEF88
-:102C100091D0752552EC3CCE50BA761F3183FB1112
-:102C20003392ABD17F98E163F1954652B807EEA994
-:102C3000057D329E3B60320DC543C7B50521CCDB17
-:102C4000320687FE14F2B8AE5FE665DFF9D2EEAF6A
-:102C500066A44E9B06FEDBFE063A2FDA6EBFDDE071
-:102C60006CA44B98E993D1DFA310FDBCB7265E8519
-:102C70007921338BB5FB8C9B74FB861BCAB5F5D7CA
-:102C800093475320FFEEFA1A13E60B5DA76BBF269E
-:102C9000DD89EBBC81D4AF67F1990BC353473ADBB5
-:102CA0004FF6C5C3B9F1D6074F7C3F89B93C4A5F9F
-:102CB000BC59FC6C7F69A115DCDFE279722BFB85C6
-:102CC0004FC2F79D163EB4C0AFC5C7BED7A9EA171D
-:102CD000F122F07EA1F81674D2E35DE057E04D4F8B
-:102CE00087C7E04C42E58FF7429147E227EA7CCB69
-:102CF000193D7EA30DF178603BBBAF70A0B86A733D
-:102D000001949F92D05F3B3D6114B1D2F5EE3791B3
-:102D10005DECFE974F7116F5E6B348C5BFC7730566
-:102D2000C82754EF4B219F50BD2EC8275497219F91
-:102D300050DD1EF209D5F5904FA8AE877C4275197B
-:102D4000F209D5ED219F505D867C42757BC82754E2
-:102D500097219F50DD1EF209D5F5904FA8AE877CD4
-:102D6000427519F209D5ED219F505D0FF984EA7A79
-:102D7000C8275497219F50DD1EF208D5F59047A82B
-:102D8000AE87BC417519F205D5ED2F8FBCA42997EC
-:102D900090D734ED2759DFD094A738FFAC69FF7D79
-:102DA000CF479AFA2B94CF34F582FE57E59ED43C58
-:102DB00087338B6011EC63D85FA9F7EF9A7E8CA400
-:102DC0000CE3CC66528FD00AF15B0AE3492B421B1D
-:102DD000157380570EF35F9C01FCBA35B801986BF0
-:102DE000FFB833D9A0FF0F4CB886C51FF839C14CC6
-:102DF000F8A7429938E19B4CD8D78A734F474426AD
-:102E0000E151940F2312426724818493281F46E2E4
-:102E100010BA2349F83C29E242981CC9C0E729911D
-:102E2000010853238311A64572107A2223100E88BD
-:102E30005C84303D320ADFCB881420CC8C5C8ACF96
-:102E4000B322E310664726E1F3819112844AE42A13
-:102E50008439912B100E8A5C83ED064766211C1283
-:102E6000998DCF87466E44382C52857078A41261B4
-:102E70006E6429C28B228B115E1CB919DF1B11599C
-:102E800081302F721B3E1F19F921C2FC4823C24B0F
-:102E9000220D08BD913BB05D416423C2C2C8BDF89C
-:102EA0007C54E46E84A3230FE1F33191071116459E
-:102EB0001E433836B20D6171E43F118E8BFC02E186
-:102EC000F8C873F8DEA5911D0827447E8BCF2F8BA1
-:102ED000FC37C2EF4576E3F3CB23ED087D91D7F0C5
-:102EE0007949642FC2899137F0F9A4C8EB082747C4
-:102EF000FE8CCFA744DE453835F211C2EF478E2055
-:102F00009C16F90CE115914F105E193989EF5D158A
-:102F1000F912E1F4C8DFF17969E42B843DFBFD0986
-:102F2000B1EE25FA0D6721AE6573F7EB3B5F846C5C
-:102F3000D19C4B3D90E0403D397335CB23D9507245
-:102F40007232FAB52B2C0AFFBEA64EAF7E6303FF8A
-:102F5000613DD40C607D401EE01CCEBF078A77A780
-:102F600080BFB4A1B0B316E22177E6745600BC2F3F
-:102F700083F90D776430BB784F068B97560E73B28A
-:102F80007B062B86E2F91549EEDF3ADEE4F659B40A
-:102F9000BF398B976DDDD9782FA09FFDF4B7DDF990
-:102FA000F2A37E98E17F2203FD22FDFDBC7EBFFFE0
-:102FB0005FA827FEF9F79F3FD7FB1F707AA564969D
-:102FC000FD16E769F4E543FDC47503E464DA4FE5F3
-:102FD00066C90976B2AAA9602AD0AF90F8309E38A7
-:102FE00027465E5727A7DFFC7A1381B8E27C85600D
-:102FF0003C77FE4E96E70B71D052CA17359C2F9640
-:103000006DDC610617B4A67E11CB3F0AB1389395EB
-:10301000FE07FCBC64F32CCC3F5AFAA436FE540BDA
-:10302000711D19CE91B5CFEB789CA9CFB9822EBE78
-:10303000F46E068F2F7959DE11913371BDA7E97AAD
-:10304000219FC37F8BDD0AFA9FE201CF49C4FA4575
-:10305000BC52E081F4BDCF8079A127F60CC53CB508
-:10306000138A9206EDFC549C3A6C90FFE01F0BCF44
-:1030700029FE309FA4BB2101F3918E507DAE40E22A
-:1030800093D33F16BE9FD6F95E16E1DF6FD49E1B29
-:10309000583763FE75A5890E4CDB553E9E84F71F9D
-:1030A000697FF9BB201EF9B809F3818264A58714F2
-:1030B000F73D57285B6F42FE98BFCBC5F2C382BE77
-:1030C00037215F5FD0E348D3E0A9905734BF39A7D9
-:1030D00000C36EBB4CE8E789F35241A7BE79D165C6
-:1030E00089F07DC425CDAF233D29BD34F5B59BBF07
-:1030F000C4FB03945E4763D0EBE8B9E89598A9A5B3
-:1031000017C4956F80CAD54928A715EBC243EB5564
-:10311000FCA88FD3934C1BDE7714F9C4D3D2193D8E
-:1031200088D19B0A743DB9790CD24B4FA769FFA88F
-:10313000427A90F7ECF8BDDD3983C9BCABE9F3798D
-:103140003C6E39A7F10AF49F7333991E3BB0167297
-:103150002D09797DAD95F8A8F3FCC65A2796DF5A5C
-:10316000EBC1F23B6B1584EFAECD4578D4CCF27950
-:10317000843C5106C0BCBAFC4C2647F999625FB545
-:10318000CA0371E969FF78638C0155A367C6942C63
-:10319000F4BB35791AE5D76AF3303A4D3CCF6BA3CF
-:1031A000E485EFA8CC2FBB54D39EE48EEA2D83FD9B
-:1031B000E07923F39B5DF8FDB61BA72769DA5FDF93
-:1031C0009CA1294FCD5410BFB3A60DD63CBFA96218
-:1031D00084A65CC97F378158E30DEAF329EA19B167
-:1031E0003C6F276B7BAA7E6CDAAD74FC53FB4C58AA
-:1031F000AFA7C7517310F7E3C1472D5EB043C7E0D7
-:103200001E192D1F7B4B467D77CC44824EAABA8F68
-:1032100049A409203132793A7D90C9D3B47FC804DA
-:10322000F6E1E497163CBFABDA229120DCA1EAA6D6
-:1032300098A7E3AEFA8505D7BD608B4CFC785F4953
-:10324000698573EB558F0FF7C2B9E59CC1E12CB8C6
-:10325000B7D7FDAB38EFA3B4B6AA93BD7F8CEEAF62
-:103260005D90972415E2F9C1E7A52DD506C83790E2
-:10327000F7A5809C7EFEAC8CF194C52BDE2A728271
-:103280005E7BB5F5ED623ACED11619C7FDEC49CBA0
-:103290003619E5DD9706DF75ED5D7708E30CAF794C
-:1032A000CAEA32291F7C5A1DCA47BDB39AC5B7FB6B
-:1032B000E287AE17E80DFCAAD263BD768B9D9351D1
-:1032C000E53300F44395C98BE7A647379BF03C8F65
-:1032D000EA7F3CFF3FDA926460FAE759E4BBF946C3
-:1032E000C5AC1E77FE66D9C77E174231C37CC9DDE7
-:1032F000B29F8C8532CB5708364B7E765EA3A5EF06
-:10330000CD2BC6E2FD627DFE94805F5099F2ABCE7C
-:103310008196BCC0CE67C9E84EA33A7F5CC457888B
-:1033200087F52FBEE3533BE8819F4CA0F0848F7D4F
-:1033300072F0F4763BEAC7E386978A6EA5F0B3D2C3
-:10334000E0C7464A977AD9FF5026E4EF18366F95C2
-:10335000F05CE4A39FC079FCA74F9BBC28863C5F30
-:103360006BC92F170F3C577E10CC809D2F8753259C
-:103370000F7C959760FEC66CD2CAE3032176FE0FE0
-:1033800093A0F871D6B273AC8FC6D837C13DDC2A92
-:10339000DDBDDD8FF8BD856732258D7D3ECECB55F9
-:1033A00006269FE445F6FD45C87B19A2B2A7429FB9
-:1033B000BE90C9F2497AEC2A6945BD52CDBF0F5C77
-:1033C000FBA485DDD3518813E47131230FF90AE49E
-:1033D00099CE7789F9E99F023B2F221D68E73E3598
-:1033E00085AA3B72E0FD6D4D6E7CDFE40D81FC72C1
-:1033F0003B60A58A03F4C722C2E6B7AC450A8555EF
-:10340000710AF17B1C04EC824ADFF4B5075A3BB029
-:1034100090DBBB854497EFD3A2B54B6509765CD7AB
-:1034200092169EF7DC332F999CA538ABF6875E9DEC
-:1034300081F396BCA128F35844BAC3F01DE0654F50
-:10344000B1FB40FA79E9D7D1DF79567B674D86EF3A
-:1034500009F78CAB9BB7C037810B4A2A3A08BC5797
-:1034600007193EABDB24A4D75FB85F25EED909BAB4
-:103470002F22653340AF2DBA8FEE0B737AF9A0C7B8
-:103480005EEF08A1BFF4196971D828FFD76ED97112
-:10349000FD3878EFE1D7CDC0DF15EEF050838BEE2D
-:1034A00017833FFEC9B4AC28F65D67CFFF55F821FE
-:1034B0003CCE84EF517C2CDC2E635E83AA1D3FDF63
-:1034C0000F327E0E12CC23AA7953F636D2A735F0EE
-:1034D000733E85173E5F819FFFED79EBFD98DC2CF5
-:1034E0009E6F10C38FD1EB973E7E8CCE7EC2BD09FE
-:1034F000B097DD292C0FFC94D197E846BDACD3BB27
-:103500002985F8DD51A177ABB9DD13E32C047B47A6
-:10351000CB1F6F79CE01F187BFDCF75C2AE65180C3
-:103520007DC9EBB52FB754B1F16E793E0EF3963EDF
-:103530002FEDC807BFAFE291DF3BD4DF35ADF3F825
-:10354000A766C17CB93D5C266FCB76823D0C44CF2B
-:10355000ABE8B3FF8AB54EFB79D669D7AE733EAC04
-:1035600053751FA48AAFF3C366B6BE8F36B3F52E6C
-:10357000E8B3CE209E83DCF298C51B443F238C76B3
-:10358000FCD80E99C0FDB31E3F4367F74F9396AD2D
-:10359000808F652BDF396CA47CB17818C50FE5836B
-:1035A0008ABB2D68E717FF8A9D7F7E2A95A4E101DB
-:1035B000FCCB61C70FE9F325D43F00FFA2771E3D86
-:1035C000767F7996DAEEF7137FCB791C6A79DBEF99
-:1035D000F1F7A2241FCB875C2EBE03B34BF71D1857
-:1035E000057400BB276F053A651285ED13B5F1D45C
-:1035F000BF0DFD72EE4AE4FFEE61EAEFF5D6C58736
-:103600004D90EFDBBD4342BF68D9AA12470981FC48
-:10361000561607BB238BD92FC9E7C3BC170BA56B65
-:103620003C1DEF27590A7BAE38595EF7C304BF3BF8
-:1036300023E6AB7F0EF1712BD83F9B01ED9F7EFD02
-:103640002FF07196C906F4A76BCDCCAFEEE2DF7D0B
-:1036500078288BF9D30F6531FF7A1B8F0F74811F88
-:1036600009E7D39759F0F77A08998C71722361FCB6
-:10367000671478731ABFE8916FF497BB33014F73E7
-:10368000498709E839A3789602F7060EA75AF13B55
-:103690004AF4AF0CFA99CDFBD96F62F7040EC31848
-:1036A000745DB3793CF9307C06948E7F788019FD87
-:1036B000D8E00B16F4136E8F67F13E929C68043EBF
-:1036C000BF89EBA939132C3E381F983DE1F63280B3
-:1036D000B4BF20A1F8AAB076AF2FA0E33418989D0C
-:1036E0006F7013BC2F499A3AC700FE2EA16E31E4C9
-:1036F000C9D3D5EF3C9B742E3ED2DE53A885B8C209
-:1037000078C218AC18F1AB29D79A59FD1B8F1C99B8
-:10371000715F26217F826C26B0338023E08BCA4400
-:10372000DCE7CE843C7E374023F2DBD546123430D2
-:10373000D86CC3EF10B1BC7E710E725D310927D217
-:10374000F585F76AEF51DC10368487C3F98E31DCDA
-:103750000EF833581593938E53364D2A04BCD7AECA
-:10376000EBDF7C3F7EE4F88CFB26D0327CEF0AE670
-:10377000F94309F3796653A1073E9D6B242FCB854E
-:103780008C7EC087756E2588ED56303E17F737045E
-:103790005D0A68F76AFCCEE6F3A3FD343BE07D7377
-:1037A000F4B8C9892CB1CF637EDA522EB74B05DF4E
-:1037B0003DA595D7E46C2E37E00F52BCCDE6301610
-:1037C000DFBBB2995CB8B2599EF5B71738DE320B41
-:1037D00009E3BA5FB0201DC5B833394CCC1E84FD57
-:1037E000897908FEAD26F5987F53CDE33106AA49C5
-:1037F000304FB7E531CCEFD7E709510709F3CE9643
-:103800006CD73F57C573648D5EC238A764EE5E0007
-:10381000F393BE17E7057E9F6D6EC57880BE9DA9A8
-:103820004542393735537F4AE2E75BB46CD92CE126
-:10383000EF3BCCCEEC1E89DF2BE77E7535A72BD571
-:10384000DE53E11E5035F85378FEC5BF13B585F938
-:103850009146EEFFCEDFACF5336637A9FC4C06345B
-:10386000F7EA2DBAFC7013F7373E30778F047DAF3F
-:10387000BF67FF8181CD3F984A303F52DCB337723A
-:103880007F52F093926DD29C8B89FB9C15A0A7D898
-:10389000F70E74F95436FCEE4A85C4BF57C9E38A63
-:1038A00027A8BF89DF95391487764BC419BB4AEC2A
-:1038B0004143227CCE9295E724DE3203FCCC0A877A
-:1038C000D908F08CA113C7B955EEB0E7E4F4C6717E
-:1038D00037948CDA027943D7678F9869CDC2530E3B
-:1038E0007EBFC87B00F2D6AFFD86CE1FCB05337DF1
-:1038F000747FD4F54AF75C2B55D1B55B0B661AA9DA
-:103900003DEFBABF7B2B94D76C1D3FD348ED60D7FA
-:103910009DDDD9F00DE135D997B3FA06D1DFE53356
-:10392000213FB8EB41569E4DEB83E0E7F27B40151B
-:10393000E325D4B36BB8FD11F1A30AC34B0C4E645D
-:10394000BFF371BE76B76797AD01FB2CDB8FE2EF5B
-:1039500009DCADF8D680DFD394E9AFCEA670C92CD0
-:103960002968867BF16F868671FB15F5772FD66403
-:1039700031B9DC3890F527F045FBA9FB67FA49839C
-:103980007E5234FD04FE997E8EF6EDA7E19FE9E7B5
-:10399000FB8AB61FE19F89EFCCFD31C7F708F4BB66
-:1039A000740DDB0F93A336CDFDFF93F5CF0F03BB53
-:1039B0007FF2294B12F0E1D267FE3BBB1AFC3FEECF
-:1039C0000F7DD6FEAE19F2BE9747D87771EA22EC8A
-:1039D0003B39CB77B69BA7E6411E6BBB79926A7EDB
-:1039E000B5BDBF7365BC5AE5C73C9A2DF2B5D9EF9A
-:1039F0003A2E7DE613FC9EE05243EBC790E74BC6A0
-:103A0000B3389A7E9D9BF87B87E1DC3F4ABCE0C9D6
-:103A10006CA66FFF31D8F74436851BB309F62FC764
-:103A2000F86ED797BCBF8A78A6C7AB8AEC5685E2FA
-:103A30007BCC9BFE46C83BAD7E38A750A6F37822D0
-:103A400073E20EE82F767CB39BC537DB587CB3C29C
-:103A5000DDB18A1A29723C7BDE5DD6CB08B9EA015A
-:103A6000D273DF0FE286D32CA27CCBCCC91358BC17
-:103A70000CCA07B6D6DD05F2B387FF3EDB9CB12347
-:103A8000E341CE3B73120C4E2AFFBB322A8FC33C5C
-:103A9000E68CBD6C2A3C2FB1D88755B2F838F2C7F6
-:103AA000AE8CB2DF037DA13DC43DFCE670CA0D744F
-:103AB0001DFE3FC89837EDCF4FF047BBA7F20AB7BE
-:103AC00057C7B3999FB6C740E759D83B0F313E75EA
-:103AD000CC567540DC6ADD8002F0A353324B3ECBFE
-:103AE0001ED33B7E4AA6FF2094C5F874B9F9F0BCFA
-:103AF000BFF3788BD3E333A01B85651364F8524280
-:103B00008F5EBF7A7282A67CEDF424E253C74DAF7C
-:103B1000CDD094CB2B066BDADFB46084A6BED4D2B2
-:103B200031BAFE02FCFD3AFB9398DF7BA8EDF4DB93
-:103B3000B3C18FDD2E7B25BA9EC52F3CFE36E45FD8
-:103B40009F809F2029647131F6BD467E1E63F41963
-:103B500035E7317B9F3383DFAE8AF3EBEEE5EDC3D0
-:103B600038BEFE3C46E48BFFB3E7310903F5BFE7FF
-:103B700079FC55BA323269573BD2A7712FCB636EAD
-:103B8000A47E0B7C4FECFB3B2D21F886FBE7FF7DF1
-:103B9000C4ACA8CE65EA220DF8BBBA93761DC173FA
-:103BA0009BA7B89FB4BCED4B33DC93FA7EDB0A9441
-:103BB000E7A9547F2552BEE968272377423C39C7DD
-:103BC0008E79384B9BAFC03875626436C2DA962B5B
-:103BD000B0BF65916BB0BC9CFF9EEF9EF88EA96054
-:103BE00087F7FCDA85FBC1037278D843D08FC58E86
-:103BF000FAA13463CE3AF013F6C407F36EA6E39548
-:103C0000FED7F7310F7DF94E09E3A6A532D923413E
-:103C1000FE7D240EFB2B95FF347A057D7ED5246630
-:103C2000574BC1C7A1F572917D137E4F3AC6EFA4E1
-:103C30008D1DC8FC3A53279BF794C82CEC4FD45FDA
-:103C4000367090E6BB7CA694EDC6F9B6DEF5983AE0
-:103C5000258457464620ACDB39CB08F9E77FC87D81
-:103C60002C19F044DBE3F7C1FAEAE3B189248ADED8
-:103C700012D0C2F5F06CD0C370FE9EE3BB66600A42
-:103C8000FC1E61A7D10A7AD4667582FF32A3B840C0
-:103C9000A956AD4B7EE946BC076149EE3681FD9ED3
-:103CA0004DA15A6FCF8B61676E1C28F47603426179
-:103CB0008F48E407EC3BA83C3E20E469EA4083E6F9
-:103CC0007B3A1D12938BE0AFD8B940698E7FE940F3
-:103CD000DA4F4709297F16F5684736DC47FF57CD8D
-:103CE0009FD2D70AF477183B09C431EAF97C843CA7
-:103CF0009F6FFE7379FB033209005F1CB8FCF20E64
-:103D00001F9D57FB6DA346815D10E3350C6479A6BA
-:103D1000C4D9FD0DE61BBE98A0405CBF14CE3C4646
-:103D2000F7FAF3908F08F1C3BA172D8FC20752EB41
-:103D30001C747F6F83BCC0B830F06DFBEFE28C6009
-:103D40003F0A87F81B002F937E377C327CC7C7D78A
-:103D5000663112F4837CEBE079ACF99E4F7F0979F0
-:103D6000D4F399BF99C99F9FCB6125E7DBF95C0E1E
-:103D70002B8DDE44388F99B74FC67B91F3574B2379
-:103D800077427C40B1E33D7D218742DE4CC097A362
-:103D9000803F195FD6465C5CBE7378BF4C0E4A65A7
-:103DA000966F573AC285FBE7E591246C27E455C826
-:103DB000E91D39FE1DC0D7A58D54BEE938FE750337
-:103DC0004683BCF4F289D909FC44F9C453ADE283BB
-:103DD000C6F6AF8CC027A60912F28985C2492A3ED1
-:103DE0002AEBF14F9C5353E93C6634E5E0F79445E8
-:103DF000FDAF7BF8A57FFCFE18978FF9B6F050F069
-:103E00006B4DF5715EF88EFC896405F5D8CA8D128C
-:103E1000FE38E14A53D924F02F563E28617C0FFC2E
-:103E20000ED03F4507EBCDEA73901B23F9785E7DFA
-:103E30004D6408C22732FD2F03FD2B23D7733CE6C8
-:103E4000473DEF3B557F3BC6D54E852C5EF69D31F9
-:103E50006DFC6E8CCF8BE77FA67D26B24D81B89B23
-:103E60005FC6F3BD2CE2BC5762F13B88E789F89B43
-:103E700038A71371380B7C0F5765474F1B5BB26136
-:103E80001FD2271E57C2ECFEF1ED26766FABFD4F19
-:103E900045065AFF698E0FE372AF79FC87613D4B8F
-:103EA000AE0E3D63A2E5A5773EE78078B9C067AB6B
-:103EB000313C14F64BAD148F101F6CDD2C4F0B31C1
-:103EC0007F2761962ABF22165F2F890C46FC087B4C
-:103ED00023F4F7F36B3DB829157AFC7C7648F0F7AC
-:103EE000322E07CB400E88DADECC2A83DF3523B9A9
-:103EF00012DE73EDB5374C1E849EA6FC8E72533ACB
-:103F0000380BE3EA426FEBEDD16EB9F5DEF1C03765
-:103F10008ADFA950FCFC0F4D62B3890080000000CD
-:103F20001F8B080000000000000BB55B0B7854D518
-:103F3000B55E67CE9C994932AF3C0986C43393077E
-:103F4000700D383C22E1E1C78140002138C15B455A
-:103F50004D65402411131250AE51B8DF9C90808003
-:103F6000D486EA55DA824E28285AB551B0C68A302E
-:103F70003CB4A15A1DABADF456E8A014791BB15660
-:103F8000FCA472D7DAFB9CCC9C4982526F874F37D6
-:103F9000EBECB5F75E7BAD7FADBDD63E8789BFFC50
-:103FA0007AFBFF0240ED8B4F4F820C8009570920AE
-:103FB0000A00339747CD36A4C16E736FF5205D3A82
-:103FC0004C5E500C70917EE301C4BD5F49F210005D
-:103FD000EBF24A50EC00B7625B668FF54B004A3B50
-:103FE000D20051F32C47EC79A66CC2FFD1F32680A6
-:103FF000129C57E73BBF14E01A80DBDCC07F8DC802
-:10400000D41FD7217EE49B6A85397E5C1FCC91BC8E
-:10401000F8F92A3C1307CAC85A2C0B6CDEFF2FB9DB
-:104020002B44B00969004E7314D28A697E5D6E9587
-:10403000AFF32D725FA1F1BF2342633B8E7F67FC1C
-:10404000F8888272ED5936628428C7D61B2F5B1818
-:104050005F453A8E1D09D0F59A35B419E5069C4F97
-:1040600040FE4F5F1B1C5A8B5B3B0C5D17C83EEA42
-:10407000CE1499F655BF2B85F1D727BB4202F6D750
-:104080003BBB8AFC284FD9EEA4300CC57576279926
-:1040900001D7FD26FFF6F1A49FB2DD0327094E14D8
-:1040A0007AA7D50CC8F7409EA2D0F3BEE4D7E54B63
-:1040B0006CF5FD97570AAACB0530BDCCA19AB05D2F
-:1040C000783E1F6004C05DABA7B1F6E560362A19E3
-:1040D00060F2F94A00DC5BDDF91BD8F345E75318C1
-:1040E0003DFDC14839ED075E16602BCA5F91F3C3F1
-:1040F0001580F27526C3901DB8AF4E6FAEAF9970A4
-:10410000D93A8DF157FC6ACA54DAD7A21DC84CE3DC
-:104110000609A142D2D351BB09B200EEB671F13FFC
-:104120006FF860A48CE33F1FE91806C8BA4F6C7F94
-:10413000788CC0ECD949F69CA8E15D3A2F8282F2D6
-:1041400058CF0BACFD400E2C964B181F401AF9436C
-:10415000FF9101FB77C1D32B928C78946A3F93082F
-:104160004F566CCBE2FAE7683849D4E37F5DA61F6F
-:10417000CCFF8E785A43782AF9B7E2690DE9A9177E
-:104180003CADFD3E78BA841D7DE089E16CFA9B1C54
-:104190001F90EFF06D0586172677A72537D48C7C06
-:1041A000B7925D095F17A181F43987EC9B1EC3EBC1
-:1041B0000E4FE0F9783B7726ABC58B8BBF8B9D6F9D
-:1041C000068A1BB766348082CFE7601B1F37AC645A
-:1041D000BFE29EFBDB7E99766EFB8E76DEAFD91951
-:1041E000DC68C791CC7E32D935D1EE6457B27BFD05
-:1041F0002EEBE64BD9757841E09DDEEC0AEE6413B8
-:10420000C919B38BF506C2CDE76133907FF56557C9
-:104210006903D7BB4EAF0C9BA786D87900E99543BD
-:10422000185E22DF072F1565ED7FB7A5029C0DDD17
-:10423000ED378F06B8B114BBAEA0EE7B5A95028A5B
-:104240002FF8F7316C46056C4C9F9C56974626E13B
-:104250007EA73FDCDDAF52FFE4712E3E1EF9715B9D
-:10426000DDFC67424B22EB98DCAD5CDF81A8D93FD7
-:10427000248E1E89B4238E2E4DA037727E3A47DCE1
-:104280006C9E10F74F9C5F184EB43E9FE607D055CA
-:104290009E8AF69BB94370AF457BDF32EE530BD954
-:1042A000A7A22CFA460EEE57685BEEB70FC6E714CE
-:1042B0000751DED4B69656B5401B8FFE53ABA9D13D
-:1042C000DA2E2822DAA9B65408793D3DF598EA316C
-:1042D0009E67F4331BC78365E4E58D273BB2F15E2F
-:1042E000363E6CBD8CF56F1A074AA8973879A587BA
-:1042F0009FFF7001697D7ED4DD0DB8BF502FFE3663
-:10430000509B376232D501EAEBEAB60DADB65CB42C
-:104310002F707C0C6B7BCCAF721C8292B0DF4BC9D0
-:104320009BA9CB11B75FD9383E7C297DE5F4D097A6
-:10433000868F1A235E5C66FFFECF510E5786E056CD
-:10434000D1FE8BFC49EBC045F6D7F1BDD9AF0CC00F
-:10435000FD2541375E8DF8FE859FF0BD0874FEADEA
-:10436000AD742EF94DDDFC1CEF3B85EEF183D0954D
-:104370005DC0C74F6FDBD2AA16337BB07E469B2F42
-:1043800081F7F6047A5C827F68F866FE49711BF556
-:1043900053D84BDCA8D1F47B4680D914F72213798B
-:1043A000BE17F1F276B587E7770D1A5FA36EE7E4E3
-:1043B000383D0C88D9197F611864D837D3D3CD190B
-:1043C000FABEF7FB67A0DF44D26088803859E10964
-:1043D000B7B6C4E1A4C5B39FE12436DFDE08C5FD4E
-:1043E0009B353DADF6EC8B683812C8EFEA1820100B
-:1043F000073B0455C47DD6110E7AD9E7AC9E3852DE
-:1044000013C62BD225C6CFEE395E49180F52C6E52A
-:104410008CD7EC3423C18E5313EC382981AED2E90A
-:1044200090219EE9716E5EC7FA955928C75DDB043D
-:104430003A26285E5B8461009BDA7EEFB7F727BCE3
-:10444000CA520EC6FCB6B6772236C47225C533866C
-:10445000DF48AB8278BB81FC9DD1EFFA1517E1A74D
-:10446000616536F23FD5F687561BB2DED2B25EA248
-:104470009CE6976DEFB79A71DE9B47FEEA0D9ACFE7
-:10448000DCF4A7C80CCF25F0DA9AB08F8D09B49A66
-:10449000C0FFC8B7C4F79684F1CB13FAD725D01B59
-:1044A00012E8D5C6F173E70BCC4FE6A2FD4871DFE9
-:1044B000E6377B347B76FB3FEE40B0B33CC980FBF4
-:1044C000E9CD9C7EB3EDA87FB53D8EF61CF393BF7E
-:1044D000EB389680FF6ECD0095CE0FA98F78F64A07
-:1044E0005F381A9478DEF1FEBFD25FFB53DE098697
-:1044F00073799F68A4F788BADC7F8FDC63A7873A5B
-:10450000FDB99FF2F1E98F19F78575A1467FE69F06
-:1045100084FE3FFDC71AAD76F995B87DEAFCE5FF4C
-:10452000BC28D27A473C5DFE2DB8EFAA89E1C206CD
-:10453000E4AB4AE32D9E33229D63F536EE4FE5AFA3
-:10454000897E3A67AA92C3854B8AE3F609ED45B4A2
-:10455000CF3DCB44661FB599D723F3C067012C85A7
-:10456000F6B85C8D4F22FFBE6562239D6B871BD31F
-:10457000B348FEE15E5EEFED735D997507D27B5245
-:10458000E65864E4DBF3C064D6EE1595555D88E328
-:104590008B6D17D939BF27C5C5F4F3B5E76B7F130A
-:1045A000C6AB6F3C325B3F90E6CEEAA07C75AD04B3
-:1045B0005B6592C7F738C3CD8FACC3D6A21C739B83
-:1045C000AECAA2FC6DDEFF5496F747BE792B259F3D
-:1045D000C0F86028C91D583BD942FDF35BB4569D15
-:1045E000C2DADDDF6C7F7328F277AD117D9B9179A4
-:1045F000D779AF731ECAF571128FC31F9D2E7092AB
-:104600009C8F7A03C95EC2ABD3912CD0E1E1969D19
-:10461000B370DE87F395146F668C7FF737E21CCAA0
-:10462000375F3D3D2F2B8074A697E366D7F9795904
-:10463000F3E2CEFB0567CC4CCFBB2DF23D945FEE91
-:104640004ECE155481E939BD12FD65BE965F235EDD
-:104650001AB7F772EE9BBC22D3EB516B237C8C20F4
-:10466000DEF360E63892531F57F27EA0D941781EE0
-:10467000200F8FCFA3B3F2267A48DE18CEB2DE2504
-:10468000DCB03C1AE9E2CD69EB553A0BF761FE4F1D
-:10469000726428E5D40FCB9101F34EC86E2F8ABF08
-:1046A0008F88E5A92BB478C0F90EA90E56B71E7AEB
-:1046B000362944F5CC21F52F0EB0C7F3733FA97608
-:1046C0003A543A8C3F7138CCA4D7C3E6E0B1FB70C2
-:1046D000DC824D128BA30B36652EEFA27880F62C70
-:1046E000849EEBAEF44A6C9E3EFD44CDAF34F80997
-:1046F000E457D2B9D6979F946FF6566EB1F7ED276F
-:10470000D55ADE5EBE49F213CEAB4B1C66B81AEB2F
-:10471000EC4DAF6F253C562F4E1A6E45C1AB375945
-:10472000997DA30E87EAC6FE80D3614EC5F6560D6D
-:104730000FD1A62456A788591616F7C4552532E975
-:10474000A74C04B30DCF15D1E993FD9C6E7163DDC9
-:10475000B6D2512A937D577865B6DFEE7ED7ECEB63
-:1047600004AC6BCEE13ED271DC89C6871F1D85F299
-:104770009D84D08DA350EFE7C8D0B8CEB91D624854
-:10478000A573C2AC982B30EED500F7F7BA03DB2D3A
-:1047900013F0AF350DD533A83EBA33247D14D56A56
-:1047A0009F8BF8DF17F09685F2DBBBB6199FA3C786
-:1047B00058C8AFEADA8DCFEB61DD67E2506ACD1FF2
-:1047C000450769CF71DDC60FFF3C647F1CDFDD5EEE
-:1047D00047C6312CC161380C47CDE23AC5AE9B08C3
-:1047E000768D2293575C9114223D8A79FC7C980245
-:1047F00042288900E1C67DE3BA5F060F0ED98F809B
-:1048000010EF1FC1F4723488781A88FA70DA18BF72
-:1048100078BF18B2E2BA65E9A0A4923E1FAD047059
-:10482000307DAA6EA4A7643498293E7579B83EE716
-:104830000AE06F677EEFCBA3FA78C1A62466BFEAD1
-:10484000C7EFFCD34F4792BD2A32E2FDE821C25D9B
-:10485000099B0F6C69B1793E69FAEF3C92A7EC09AC
-:10486000AC2BA9DE14038FDECCE2658A8FC52D77D1
-:10487000F447A308274D29C3D602E1A47F9EB73889
-:1048800036BE7AC5B2223E1EEB5527C5AB24B69F75
-:10489000DA1D568693B96B44859D8FB916763E7E98
-:1048A000D492C4E8DA01A5CCCFE69A2040FBC05CE4
-:1048B000309BC575AE72A8B583B2DD4E717E5D4486
-:1048C0007432FBA89ADD2C649FA7BDE96CFD39A466
-:1048D000633CB70E68389B6BE2F8815D42682B8BB6
-:1048E0004F0D32F97F954960712ED11F7F434918D2
-:1048F000C5C93CDF6D34AEEE21AB6F8587CB20EAB6
-:10490000F2209EEA4C91053FA7797F6D65F71AF575
-:10491000B88F2427AB2F941751FE7A33982D742F1C
-:1049200025F378A6CB532F574E219C62FF4133F6D7
-:10493000D739783CAE4BE5F73DE0B085B6C6AF471A
-:1049400032E7F371B293FC6C34C30BF9BD09FB3F42
-:1049500005DE5FE62C95A3F8BCD304ABE99E84E4A6
-:10496000193C346E5DA4FB0F253C2E367B1D6487FD
-:10497000F41B67D37ACF892C2EA1333D544AF9DF3B
-:1049800073E208AA63E7AED957BE81E81786B94932
-:1049900084B9CFBFC7CEA7BB349C4529EFA7F30A84
-:1049A000E917B0FDC8CBF3FB80C8EF713EF2F2FC13
-:1049B0005FD7ABDE5FB74662F6A85BC9F150D7F4AC
-:1049C000019BB7CE11C9227BD4BD245D43B83EA55F
-:1049D000C93DAF2977DC41C4C73CC9E516F051ADEC
-:1049E0005A6121BAB65560B4BE5EDD9A3F66998AB7
-:1049F000F97CD45A351CC5E6CDCCA3F3ECD4B3E98D
-:104A00007973E3EC7EAAE565A76C27BF0917BAE9BD
-:104A10001E6671926F33F3536E8F532D859BE99E03
-:104A200066BE3BE210B07FFE3DF96974CE1D76870D
-:104A30002DD47FB8DD63225A71BBC711AD98AF6624
-:104A4000F4290CE1EDC51A78D14E8B048E9BDA6700
-:104A5000F759BCB89E3B9FEBE7CC73EF15D17D4176
-:104A60005D5EA488CE5FC455510ED9E51981E50974
-:104A70008B9E1595A4A1315C2D225CA1FF2FD470D3
-:104A8000B568C7CBF7929F2E223C0DEF894BAC2B1C
-:104A9000F7B3E72FB695031FBF9F70A79FF748B7DF
-:104AA0004874AF66D1685C87E8D47C99F901F64F09
-:104AB000E2FD6A313B47206AA17CB85EE47902FAE4
-:104AC0005336E511F51D92DA1D2F695DEA2F8EF53B
-:104AD000F7859BE1F926CDCE56761E0DD7F4125DF3
-:104AE000F392937071E6B97D6F8CA1FAEA45C14DDE
-:104AF000F1BE871F6A7AAB273D39D93E595E544FC4
-:104B00007A71C6F4D4ED6F1A2EEA81EB41D74BBD12
-:104B100059D393DEAF8D1FA1E9A11634BDEE18C89D
-:104B2000FD5DF36FFD1CD1F71748E3E3757CCDD72E
-:104B3000F637219F9F9BB5881B5F31C39762B946AB
-:104B4000ABFBB1EBCC0B6DECDE48B7A72EF7F27CDC
-:104B5000EE0718A795D4B4989DA326A8E9ED9EFA70
-:104B6000264D7F929DC795234D39B735A2FE163E3F
-:104B70002BFA98F2A8E68A5BD76A8A3A585E7ABF1F
-:104B8000E8A67D95FDB2F23ADAB78E3B699B60EEFE
-:104B9000184975462AD3BF2E5F593FFF75A91C7768
-:104BA00061924797F3881066F6525F10DC3CCF8D18
-:104BB0005AE8FE50F7D34479E76BF28A4E618C7065
-:104BC00035C9E393C9BF01CF41268FFDE032B69EC0
-:104BD0007A689967686C9DC3AAC34C7C8781C701BA
-:104BE0001D9747B4FB88232B5F6679B0BECEFD3D91
-:104BF000D7093466F45C47E75F92CFCF01DD2F3AE7
-:104C0000D338FECB5A3E607C7A9CA51FDDC3E9FAFF
-:104C1000D4F516E79706FDE8FEA5FB936ED77FD582
-:104C2000AF607926CB571FD0F6CD7C242B762E1083
-:104C30003EE9BCB35A109776C3B9C9F29A29033E2C
-:104C4000B3047A79AEEB29F179AC9E72E791FEA7B5
-:104C5000D8B34D9407404BF6FE82B8BCEC63BAEF74
-:104C6000A2789A09FC7D06A057C69DE77ABEA69F4A
-:104C7000D7F85BD78D4B1C5F9FA19CA0FE9A918BB0
-:104C80008B288FF847BE97E9EF24B45B26E07CB50C
-:104C9000C723E54E3956AF5CFBF7B0E8A2FBC01D59
-:104CA0001E43BD507B7A3FF3EF3A88ACA2FA76EE12
-:104CB0009AF72A4691DD9FC67C1CF9E6B77AD8B9E7
-:104CC0007762CBED23A8949DBBB290D1776EBD8364
-:104CD000D36B783E377765C993741FFF7192524E3C
-:104CE000F8EE5A2FB8A9DE1ABBB564F92DD83FD615
-:104CF00071652AC97D68CBC71563A86E681499BF12
-:104D0000285B1EBE91FA950ED1475B9D0FEEE5B76D
-:104D100010BECD2EE66F87B573A259E2387B578B54
-:104D20001307BA5B8EC3B2E6E62213ADDB86E71348
-:104D3000EEBFCA22B787A9EE7BAD9F6F33E90BCBDD
-:104D4000D46CC4D17181E7DF3516B011AE0E489135
-:104D5000A524FF81A58E614D248078E11AF20B45D0
-:104D6000ABB3B06E62EBEAFAD2D78F68FEA2CFA3E4
-:104D70008FEBA47C8ACE0F4DDE132D4FDF4879C216
-:104D8000896D856910A7F713B42FD4F79D18175FA5
-:104D9000ECA5FE3B94AFDF4784585BA3DD1B1E9060
-:104DA0005A07D0FB5BCCE38FC6E7E59FB425D90853
-:104DB0008F98C71B9F4BFC3CC13CDEF01CFDE6A856
-:104DC00031DFD7EA3BB1CA15E8250EE96D629EDFF7
-:104DD000956FCF387615F4C8F375BF4B1CAFE7F568
-:104DE000DDF72C1FDA13DEC78C72C125D63F1D44B8
-:104DF000C360EDB78D7C17E59D94F2CFED11AA2726
-:104E00005BAD6E2BEAF728F915BD077C49E479A262
-:104E10000D7C61C4C5D13F8EF0911F2EF890FBDD53
-:104E200082762144AFD8F7AF7F4024FE3B360AD0CC
-:104E30004F88ABB31E597F23B9DD395F60557FE4DE
-:104E40003FB74DF0A94C42C59E505FBDD15FEEBB50
-:104E5000BEFABE75957ECF94A8F72B0BB4FACA079D
-:104E60003EA3DE797DBE1BE1533ABCA7DE4F0703AC
-:104E7000AC8E3A1BAC61EDE8F6B6B21C94FF53E180
-:104E8000C84363C97F1C2E764F723AD8C05E029E1B
-:104E9000ED18716126EAE755BBCB4D71E36CB0911B
-:104EA0003DEFC68B86CF6B77EC117380F1EF1C8BD7
-:104EB000FCBBEC2E7AADD1CBFB366E5F8064FE7E00
-:104EC00054ABB7EF5E3CAA1F3DD7F77BF23E6E674F
-:104ED0005DFE93DB6E77527EBAE7E7E93B47937D51
-:104EE000535C6E8251F506110223008E6DE071E86D
-:104EF000B8CDF524DD971EDF784316D58377485D5E
-:104F0000161FCEEB7BADD249F7027F33479D6E6A09
-:104F1000913F4C72984322C5BF315381BD071C138A
-:104F20003683EC61AFE8194E469F3687C2489FA290
-:104F3000F783746E5F48E6EFE9B5F77E77BCC2EFA2
-:104F4000D3BAEF4FB47B84B1DA7E9715A4E9EF7B37
-:104F5000D8F3B252FEFC938DDB67D27C27B6486E45
-:104F600092F7EC1689CDBF10EB7813E2F038E28DA2
-:104F7000E2D7C2F7451F41FAC4365E272F44DCD280
-:104F80007D71DD6249B1B87AE2B14CE7DB29B0FA54
-:104F90005AC7E5422554CEF4AEE1D3867F2EE29186
-:104FA000910AEDAB481F8938FD57EBFE2584CBDE17
-:104FB000E241020E747DE97888E113182E75BBA7D3
-:104FC000B50F9B90C306A82C5EA8136110E505CD14
-:104FD000161864261C98927DE4E78D36E750BA6770
-:104FE000FA3289B7F79ADCAF53BDFCA54996046C39
-:104FF000FF56E061E3EF157D93899632A2EC7E4087
-:105000002C3329263AEF9AAD2C5E24C69B870A786A
-:105010007EEA25B061FB4C819BE78FD0C0F207BDD3
-:10502000C50DE6527E529992F6858C2C3F2F983111
-:105030008BDEE3568E4D5B9A8F99E52F0A66CD3253
-:1050400023AE2B47A4BDE4457AEB163FA7AF4E2B0A
-:1050500091906E126E983509F9F716283F2D288920
-:10506000ADA3CF8BCF37D2F3B7FA059EA0B6DE62E1
-:105070005F4DF1FE53A16B91498CF1BF2BC0E157FD
-:1050800085181D95208FF2E967E89D6A49DFEDD903
-:1050900002655B412FCFE701AC243DCE537F7B906F
-:1050A000F235FCF96D88B7EB35BCCDB3D9C3840BB1
-:1050B000582D9DEEC68597E292CB4CFE3D5333F7BB
-:1050C000F5E6F01E1A3F185ADCC76C2C15DC783157
-:1050D000BDEF388F8E09C7F4F9707F9F4AB85FB46F
-:1050E000ABA0A0ADD1A504547215C63761E76FBF60
-:1050F000A2799B558826313B54B9097F02044C178D
-:10510000B1AD4B413CA09E96BC74663FC1FF4E3D85
-:105110009FCAE6DF672CD5F0787D4479AC0D85FA1F
-:105120002408190568EB33B0F7AC19D73D610ABC08
-:105130005D807AAC35BD95B74426BF6D7652FE7260
-:10514000E679D13703C7D56A793B5C10C3E3F179BF
-:10515000A767F0E6B57138FA40C3CF694F386F19C9
-:10516000C50F0FAF3BE1C2BEBC65C83FD53BAD84A8
-:10517000CEA54740F97301B3377FDF30D3DCFBF7AF
-:10518000177FB882E73BB0859FAF5633A88E34D6E1
-:105190008213F5310D6529455A425A64EFE3438C79
-:1051A0009FF89C94A7C8B767F3F735E0277FD4ED45
-:1051B000A8DBA787DD5064CACF4D3690C85F06C311
-:1051C00046379D3BBAFD268B76166F96BCC4EFE33F
-:1051D0009608D19674A29FC3F392F4A5F965CF7394
-:1051E00073AB854C51B3F176169FF4B824E31FC21C
-:1051F000CFBFEB5ED252A89D9BC36018E1EADBF201
-:105200001D3D2EA17D1C8571EF7FBFD53EA422DC04
-:105210006FB5B6F664B14A36935E326D3E8ACB4BBB
-:1052200036E5F7E3F1F82710CF071BD3193E57797E
-:105230004466C78A8E1C90F1D19D1D02C878CECDE0
-:10524000E84867B4F37C7F46573CD56F22E5FFDD25
-:10525000EF2D9F1AC8E8134FBE3932C0EF576C3498
-:10526000BF1F74398ADB291F3A674739D00E7EFB8E
-:105270006A765FE887EE3A46B828108D28217F527B
-:105280002495DBC5D6C4FC5ADBD71237B7E39203AB
-:10529000FCDC5D3281BFDF33AB835D8407A95384BF
-:1052A00010D23F3820968491B5598BCBD66C13C859
-:1052B00071F6489293418EABDF4055225427CDD6EC
-:1052C00070923228CDD0FF80109048AED9F6050CF0
-:1052D000370EDF1586F92279E59D4C1F019EDFEA26
-:1052E0007802F1B499E4FC629C00E9888B1FCCC67B
-:1052F000FEB879A5719F4D12586BCC8B512F472F5B
-:105300008527BF8EA7C13098E129413FE81F2CFFB8
-:105310003C87E738A54D985D3C360EE91B3B2508D8
-:10532000C92CDF64FE734E4961F7F72B353DE9B8B0
-:10533000F30F048782F3BA4A8D7A4B558C7A4B9FD0
-:105340006AD453A6DFA8977EB3BD86FEFE81FF30E8
-:10535000F4E7D40C37D0B90D630CFC57364E34D07B
-:105360001EF53A037FFEEA5906BAB0F51603FFC0F0
-:105370000DF30CFD83430B0DFD576D5B62A087B4ED
-:10538000DF6FE0BFBA6385A17F5878ADA17F44E7A6
-:105390004F0C7449E46706FE5107371BFA47479FD5
-:1053A00031F48F3DFEA281BEB6EB3706FEF1E7F782
-:1053B0001AE809F0A681BFCCF69E819EECFE8B8197
-:1053C0007F4AF6C786FE69F22943FFF4419F1BE836
-:1053D0000ADFD706FEB62B024F1462C89F6D5A77BC
-:1053E00048058ACFF28FC7219E6FCA30FBC2C474B2
-:1053F0009975DB53855A9EA6E1F60BB0DF66F27E07
-:105400007B1C5C47794126E17A06D07DEFB9768135
-:10541000E1BAAFF3D985F9AE396E1FA98A0D0BF049
-:10542000189D3ED56DA033FDD906FE7EB365437F42
-:10543000FFC020437F4E8DCF40E736941AF8AF6C03
-:10544000540CB4479D6AE0CF5FED37D085ADB30D06
-:10545000FC0337040CFD83433586FEABB63518E8F4
-:1054600021ED8D06FEAB3B5443FFB0F06A43FF884D
-:10547000CE56035D12D960E01F753064E81F1DDD54
-:1054800066E81F7BBCDD405FDBD561E01F7F3E6CC3
-:10549000A027C001037F99ED5D033DD9FD6703FFA0
-:1054A00094EC2386FE69F209437FED29841FE5CF42
-:1054B000AF0AECFDD7F4419F19FAA50CCCD3E97ED5
-:1054C0001A927DF41D7E629EAEE76F15BEAF0CEBA7
-:1054D000DC6B6A60DFC57D69E2799DA3C8CBCE37FE
-:1054E000CCDF6D361667F1841AC2AE5A9A283F7522
-:1054F000A902C31DA51A55ECBE3083BD576047A352
-:105500004CDFA1617E83449AC9E3A1FA21259687E5
-:105510000EB838E2BBE7A13945C0F07F5D51C05DF0
-:105520005442F5D80BE5549FDC09EA2A9203CF5781
-:1055300017BD677A3BC9786FA4B7D36CA8BFB8F51D
-:105540000E24B50E187E09BF9D663BCDF8BBE7D58E
-:10555000EE9504DCDF92B8F91FC2BAC98C25646BE2
-:1055600010FD0BFDF4274137A31F096633FAD1A0C4
-:10557000CCDA0DC141ACFD59D0C7FA37064B19FD45
-:1055800078506174283895B59B837EF67C4B7036D5
-:10559000A39F0C0658BB2D58C3DA67820DACFFD908
-:1055A0006023A39F0FAAAC6D0FAE66CF5F0CB6321F
-:1055B0007A477003A37F1D0CB1B623B88DB5BF0920
-:1055C000B6B3FE9DC10E46EF0A86191D0E76327ADD
-:1055D0006F30C2E8FDC1838C7E2318656D67F0389B
-:1055E0006B7F17EC62FD6F05CF33FAB476DF3FB502
-:1055F00088E75FBA5E741A6012C3839ED7CEA4BADE
-:1056000085C0512A9D35D42D09F543A23D4E6AEB44
-:105610004813F1D8A63CE78AA2CDCD71F9FE7F16DA
-:10562000F17BC10792414DC2F8D744C53C42B12934
-:105630000D42CDECFD2ACFBBAB355C4206CFB71790
-:105640006872556BFE5042F81CC4F0F9D6E5D44997
-:105650007A9DDC322030BF08DB85B92695DD13D872
-:10566000434594F73F3520504DB83DD770C71B6C6C
-:105670003DB7AF8816A9B086336FA2FB9F0322BB4C
-:105680002FED6BBD7AEDDF2FF4D9BFEBC4003A8765
-:10569000A67E23B2FBF4B725C76CBA1FB94FD3CB94
-:1056A0007D4526433B34D7DF48727E52D8F0E4DD97
-:1056B000C852B5B8D04579EBF5545AA3DF57822CC0
-:1056C000B1EF6341799D3E99FC01267644DF042ABF
-:1056D0006B3B72024D34FE662C20880E8CB1E6F5D1
-:1056E000B69F44791ED470F16091C9D04ECFF5AF0A
-:1056F00025FD1C2D540CF2A8B9B2F6BD7BD7E324CE
-:10570000D73F5EFBEC98901FD3B77E2FB16A82F62D
-:10571000FDD462417F4FCDF3411BE8F920EBAF5A36
-:10572000CAEF677E887519BDAFFC508B87E71A24D6
-:10573000162FAB84641FE5D3E71A960EA4FD24C68A
-:10574000CD2A1C67C27155C0BF87A8FA3085E10B0E
-:10575000E7037AEF5685993BD57F77E7EAF71E5145
-:105760007B269747A1F7B073765ADBA84E459C3C41
-:10577000CDE2D86851B5609DFCB6295424880C1F31
-:105780001601E5ADCE407CF49217E83858A4FDFB35
-:1057900018FD39E26B3BCD77F6955183D87B935D4D
-:1057A000A365D25FB309ED41F735BF13F9771274E2
-:1057B000C54EDF71B88ADBD877FE944490BD463B76
-:1057C000D8FB903D2234BED04BFC7C5FB3DBDBD9F1
-:1057D000D2D4109BD7F89EEFF71AAE7EAFE1AD6240
-:1057E000EF81DC7B71DE459D12AB776064B4D8DF5E
-:1057F000CBF74DF58D6FF62F88DB477DC711FE5D2A
-:1058000014448BE3BF873AADCDABE349B438026DA6
-:10581000F678F9388E10D7EF911E10D7C728AF9FB2
-:1058200069955D37E1D028AA268C6DE00937FBAE7B
-:105830004EFFBE6E3EF8595B8D70201CFBD5F5AC5B
-:10584000FE5D08EDECF9A2D2DBF388AE87AE49D954
-:1058500054BFAC6E7A3D1BA5BBA175FD64BA7F9E9B
-:10586000159AFB3AB5955B84635477A35F1C25BFFB
-:10587000880A0D2BA924BDE5D9092BE99E77A6C876
-:10588000ED006F723B208E1431ADE7FED00F4ED18C
-:1058900078F40326BFEE07552B387EF47F8FD1EDC9
-:1058A00017A577FD3587DE7D98BBD87721F5BBAC92
-:1058B0006984AF8554798AF179A17E3EF3BCE02EEC
-:1058C000CC0B88EFA4C4ED7FF25012FB772F270595
-:1058D000C4C7F09EB8D7F3CC2F4DFCDEED5E11B7F8
-:1058E0002852BDFC30D3538D2D3494F484E7B33467
-:1058F0009070FD71FBAA6174DF37319447F9AAF407
-:105900008CD5D7EC31C479B89812BBC77B48E2F785
-:105910006A89F2F6C85B4ADFF88AF209AB05547A65
-:105920009F84FECFFDFE3097FF4B5320FB1A91E77B
-:105930002BAC8E1EE067F53F64D97C6B859EEBB780
-:1059400068EB76FE93D7D36A2EB0EF7112E510DCC8
-:105950007CDD4479ACC95C0EFDDCE9290FB7832EF0
-:10596000CF90811E7E2EE6296CDF4DA65416BF3ED9
-:105970001503C5A437FD7E4CAF633B3D9FB0B80E09
-:10598000179A07F0EF7BC37D9DA7A7BBEB676FEC72
-:10599000BCD3EF99605CEFF7827E9B5B22BBCD02AC
-:1059A0001F8BFB83E1435D3F867BC2FF035073AFD8
-:1059B00086E0390000000000000000000000000048
-:1059C0001F8B080000000000000B7BC4CEC0F0A3BA
-:1059D0001E822538106C62711D0B03C30756D2F569
-:1059E000C17025507F0910E703711610A7027102DC
-:1059F000104703711810BF069AFD0C881F02F11D95
-:105A000020BE0EC49780F82C109F40B277191B035C
-:105A1000C35A36D2EDFF83E4E78940763910CF24AC
-:105A2000231C46F1F0C0F23C0C0CDABC08FE3E5ED2
-:105A30005479051E047BB92065766D03EA0700E9F9
-:105A4000CD424A800300000000000000000000007A
-:105A50001F8B080000000000000BD57D0B7854D58B
-:105A6000B5F03E8F79253393C9839040C493970452
-:105A700009382421F2AA1E0842A4D406F42A5AAEF8
-:105A80000EC823869044B02DB7729B21092F411B6D
-:105A9000152D5AB483458B0A36F268D106EEF028EC
-:105AA000C65BB4D1A282D536D45B450B4944116F95
-:105AB000B5BF77ADB5F7C9CC393349406BFF7BC370
-:105AC000C7B7B3CFD967EFB5D75E6BEDF5DA3B76E5
-:105AD000D9C5E42B19FB027FA09CA330C60644CA9B
-:105AE00051775EBB687B09FCFE99DDFFB8166967DC
-:105AF00094173389B1D1F09E653056CAD8954EF8C7
-:105B000015DA95BD70EA0F97A531B69F29CC018FA4
-:105B1000C26A59EAB7A09FFD9F333FBE975F706787
-:105B200075B8F1BB2063E98C5DC1F877E16C2DCBD2
-:105B300057881526E373DD49BF433FB99BEAE0FB75
-:105B4000B39FBAE97B2B1C46C93E9759587CF34555
-:105B50000EF6AB7EDC5120EAD90C066702DE2C1A69
-:105B6000D780F7D0DBEF11BC075480578B33BE13BF
-:105B7000E04F8BC0BF9F5D9BC40A39FC7A6904FE6D
-:105B80000B8587E60F786EACD7BE9997CFD8BA7AD7
-:105B900046E5DA7A2795ABEB7DDFCCB331B6B23E82
-:105BA00083CA46153E01381AB7B0501050EF2E8404
-:105BB000F646FFF03F21CF69AA3BB37CA6BA3D0D64
-:105BC000FA2988D455B766AA37BA2739036E1C1F3D
-:105BD000E6EEC0F19D5402984733001F978A79BAC8
-:105BE000B4E02C06EB91E7B66B2180E352F782E933
-:105BF0006C24B6CB27BCD9055E9764367420BC1FD5
-:105C0000433B06F31DE69EF23EF332F69FD94FF07A
-:105C1000796C606C203C5FFDEF751D12F4B732D3D8
-:105C2000AE35407F4FC0F86B1C5178DCAAFEB9033B
-:105C3000FA74C23FC4E3D08DBC1E9937D4A3E631B9
-:105C40008C45BDCF8EF473A1FDE6379BEBD67EF37A
-:105C5000347D12D2ABD16F3EAB68F0B9FFF7F67B63
-:105C600029E03C3525D2AF314EBFFD023954C0B7D3
-:105C7000F91B59289C1D3B4E9EE62F0FC2FBBC8D85
-:105C80002A0B65F3E769C01779FC57D6E49B94109B
-:105C9000288C8587458F93135997BC34FB1C19E8D2
-:105CA000292FE3FA4512D25573D4FAE63066F0CDC7
-:105CB0008FEA7D4C1FCAD8DDF505546EA9F7E9C8F7
-:105CC0002777FF5D99D55218CB8F7F11F2EA1E1B03
-:105CD00023FA0B3ECE428F4BD85FC5AC39505F3FA5
-:105CE0002ABDE82E8D885C4679E61274BC5ED26EC1
-:105CF000C8C1F6AF280CE5A0951FEEB6E9D3B0BF3A
-:105D0000B5A364A901F19CC7F921CF1676E662BF5D
-:105D1000CD39A382D88FFF55E287BCFC4B3405C632
-:105D20001D9627F861F4834E94873DF35F96AEE7A6
-:105D300015339664A103DF79D2816F42DF74F07569
-:105D4000F1C3D7475FCD7DD2D77AFF7DEF3BE0FD32
-:105D5000963CBBA664C7C295797138A3C21D4B6F30
-:105D6000797982CEFC7DD399B57CB03EC4DE011A30
-:105D7000BABF3E83E8EEDE7A8DCAB5488730EF07BA
-:105D8000B0E958A8231DE2B8D71551BDD77D8BAD1A
-:105D900020BA4C9FD5CC50FEDE8FF4390E875BA91C
-:105DA000EB1360AE79A20E5BA40C7BC0BDF87E1035
-:105DB000D575DCCAEE928CF6CF0675C0778A683F3F
-:105DC00075C5B3C146F8FD7E17AF5FBDA2530F6620
-:105DD000457D1F5CA7EB5991F6500F4F52A3FAC3B4
-:105DE000FE0BA3E13948ED8DFEE6AF38A10701BEF9
-:105DF0007B5DBCBFB52B8EFD53FA5F2B053240B5E2
-:105E000060AB2CFDACEDA9DFAB231E8C7172A45FDF
-:105E1000E8C1E8F7C16774DD1D797FB9746F10DFE1
-:105E20006F64157912AC43E6F48A0C06EB6FAF6829
-:105E30000EE296DB039FC077647E0F12BCAE0CFEB1
-:105E40007EC48ADFEB8D51EB3369C5CB4184D7D05B
-:105E5000731441AFF20B594B8F00BD2A49763FE9CD
-:105E60001BD701D364C278B32A980670C969150C90
-:105E7000E58192A6BE1BCD0706FD019C6309CEC934
-:105E800015B37A8133180DA701477F701B70F44E4C
-:105E9000A77C7C2B3D4DBA66CCEF26C0FE6D6FB75C
-:105EA000F9515D48453C4157ECF35B8336789E3AA7
-:105EB0001370ADD1BACD62B9B1FDA64D1FC4425128
-:105EC000FBF73F7A5DF3B0CEF116885E5FA8CF9501
-:105ED0000644F03856B4B3D29F313F5BCCFCAE35AC
-:105EE000CD8FA9818C0A4FFFF3BBD7E59F55E18E7B
-:105EF0006DF75B49A2F1274D19F36DC6C7630E908C
-:105F00005FC9385E5164BCE469301E76A636C71D91
-:105F10002F65328CE7FCFAF069E547035E7B0CBC29
-:105F2000B79AE05D6B03BE8DB3FE5F37BCE7CB7FF6
-:105F30002E90BFC47F797DF3DF3FBABF64FC153E6E
-:105F4000F94865E12B015F775CE524FDDE9073FF86
-:105F50006C7CA5E2A7B07E77BC547CE24A192B404A
-:105F6000D72322E3D74A1AED57BDD1776FF3810DBE
-:105F7000D6D4CFFFAFF9F486D7AF5B0E9DAF7C6D63
-:105F8000783D81213FAD2C642107F4B1B2ED2AB2F6
-:105F900037571E291BC8A05FDB9AE14C8749256350
-:105FA000FFD0DF4A43CF985CD24FFF5CCF00FB4E5F
-:105FB0006F02A56BB7B782F4A29512A3EFD783DE69
-:105FC00016023DA6E4950DCE3958F7EF70CEC1719B
-:105FD0006D8CF4E992570EF9CA80CE5D23524629A2
-:105FE00040022B5DC6F3A3E5A8E7DE55289E7B782B
-:105FF0007FF0BC02DB2788F6BDC1959007F044AD69
-:106000007FA2BD395011477FD76599F0F390D0BB7F
-:10601000EE46BD0B047262424B00F56A57BA5D7BD7
-:106020004C8AFDEE265912F306BD0DEDEC115332EC
-:1060300051CF3A30E389157684AF90915C77E5854E
-:106040007419EAEE02CEDB0F59F67D37AE21E95D19
-:106050009952994ADF99EA77F7E831D913516FF3EA
-:1060600016F0F7650D574C6C8C7ECFFC1371FF3525
-:10607000DE071A4AE97DA6B3E2D804183F13E468A4
-:1060800023E02B536D96EA685DD3E2EA8F1BE63B73
-:10609000678500860D331ECC9E1F673F81D534F186
-:1060A000E9A079663E7B48E0EF6E81CF4CE4F5D104
-:1060B000820E41BEB978D31EF9E61ACAE55B4241A9
-:1060C000F30AC4F7A079CC8FFAF686194F90DE6AEE
-:1060D0008CE32A30CBB94CD53CAFAF6B3E1B99FE5D
-:1060E0001D7974EFFD5BF96C230BDC8AED33C57E03
-:1060F0009E5010920285FDCFDF3ADFDEE6FD2DC413
-:10610000271FA74E1E103BCE3F0B2F996E18A7E4FA
-:106110001F3F4EC23CB3BC3C5FBCC33E20E88C2951
-:10612000B81F58EDAB84129FC464AAB6A31D4EF2EB
-:106130001BE0F6B0E6F24B80DE522B56DD2E83DDFF
-:10614000EC79EBEAF7D1CE4EED9843F676536151F8
-:10615000DB246897E4F7CD984274CA08CF6BB1335B
-:10616000E2BBAA1513615E8D8CF3DD66F996895C3E
-:106170003FD069BDBF2B70062BAEA950477665395D
-:10618000F1E66167613E6FE90B47ECF7BDCDDF16C5
-:10619000F94EF8FF9690DFB4BFEFD8743BF9118346
-:1061A000F00FEDD2644B3F49BA3DE2676488A7A87F
-:1061B0003ABCFF6D0F5FDFFE4F19CFC7EE736A4029
-:1061C0000AB63CD987F67A12F325AB2867278342B3
-:1061D00000A2D897D61D94B5FED7A589B1F29642F4
-:1061E0004E7733A2F4DC0E99EBC969332767AF848D
-:1061F0007ECF9670BF70AA0FFE17C5CE671DEC6BE1
-:10620000E1283FC7BAC2C7887F1B819E72802F8258
-:106210008532F9B7D7E6EDF045F3B5AC18FE6D2B36
-:106220007D304D2D15FA1FE047C99375D7C8AF4E85
-:106230001FCA97A48FC4E951DFB10B5FAF24E5C239
-:10624000E8E3AB8E67AC6B2C5F71FD246DE63C27F9
-:10625000EA3BAB326626C593B3BDAFEB7DB4AEA8C7
-:106260004F84E2F49FA64871FD39567D9EB1A5A6E4
-:10627000F5520696CEDADCD7BAA599F161F4EB5A5D
-:10628000A668FF85C24BF5915FDC29FA5BABDD1791
-:10629000C4FDF32CEEED800FA5795418F53D96C79B
-:1062A000FC8FF326A487B8343D443A24CADDD208D3
-:1062B0007CF62CD9349E9A9660C2379B05DA761408
-:1062C000FCAE657682C389E3C1388A0F3A94D0FF69
-:1062D000CFC22E2FF548FDE1505FE462FD4E131D45
-:1062E000ACCE2A8ABBDFA9625DD16CE5F47AE7F90E
-:1062F000C917EB78D799E13DEFEFDCAAF66E1CFFEA
-:1063000071EC772A7BD7C01720F1961E7AE7EBB4A1
-:10631000CAC6F64849200F32AE67010DEAF80A36C0
-:10632000EB35588E453A2CF2915EB05552114E62C3
-:10633000690DFF737DBE10955BE84F7606084F8AA6
-:106340005B67D45E3B3F7DFF9CD0AFD3843E6FBC88
-:10635000FFA162A77E5556C1D06E3EF7F6D40CEA77
-:10636000578747A51138ACFD162A811F2A0390ECE8
-:10637000383CF801FA09584701F9B5F305CECE3D8E
-:10638000303389F5C15F0F59F8EB2189C3C92ACE93
-:10639000CFCE380763B6637B359040F1B29305C426
-:1063A00007B962FC27D6CF4DC0F19FD8D8379F1BC5
-:1063B00070FCB4DEC9C2A0A786EA7D541AEF43C2BE
-:1063C000DFBF59D831C6F3738A4C70EC137CFF845D
-:1063D000B32281FCE7076F9C360CF82BE7A8E24755
-:1063E0001D4F5BCB52FA1A3F3B68E637A6CCEE1343
-:1063F000DE656F4D9C71288A1F7FA178D2DE1D0E4D
-:10640000BF5CCE2E47FAEBEFFB73F5FA8C43F95FD6
-:106410001D2F9B85FD79AEF1772B48CF095F49FC95
-:106420009923E448CE3C2E0F72AB594843FEFDFC45
-:106430000B164D1F6099109E32AB558DFC4D4C775D
-:10644000CF81F743C5DB4C65BA8C5BF850D4BF50A5
-:106450008E6CE2FE73C3CF0FEB7E17CAB9CDAF29A6
-:10646000640BE7556A0DB8DE39EBCDFEFDC12CCAD1
-:10647000EF8EFE7AA1D7655AFCF85F751D3A701D44
-:1064800012FFF9EB105219D19D51D72456116FFF0D
-:10649000FB44D0A9B6E210B743C0F87B272A1E01FF
-:1064A000EB99829BC04F83F74D44BB35B886F9F317
-:1064B000E3C84B9B9A48746F637A7828FA0FE65CBE
-:1064C000DFB117E5D50466925F71E4864DC5EFD262
-:1064D000B8DC080567F2F27385E265F9EB5908E369
-:1064E0005B9337D4ED47BF5E6635B79B33D7042542
-:1064F0003BD473EA981F87C9AD64BCFD6C16D27992
-:10650000BCE66806D0CD104137430C7A5966A69791
-:10651000C17596B8D01A737D20D2057C37D0422F32
-:10652000D67E723446F1B8BCF5328F17CD32C77DB6
-:10653000F259F7FB3F0778F30FB9FD61161B6FB2F5
-:10654000F6AFB24001E265F70FDDFF590013FCD949
-:10655000FA49A98817902749244F2AE2DB3D31F4F4
-:106560006AE81BBDB48FC84FDEAEB7F7ABF2D39766
-:10657000CE0538D67A7446E307B349AE2B225E794E
-:1065800030F37A6707FA6DDC4524DFF7631DFD3CC5
-:1065900019970C8C96F78AF02319F546E147B28ECD
-:1065A0003755E57AF07B4C9F8A7818E50864605C83
-:1065B000CF9691BE730E8C67F381BE15E7BBB16AAF
-:1065C000029FAFA6FE2D1AFFB071FB481E32BE1F00
-:1065D0003377CA79E1A3440DDCA442199C04660414
-:1065E000D27F0E0B35E2FAD635F3FD2DD2EE16D161
-:1065F0002E8879053DED02D06E84A9DD3C9C0FB458
-:10660000D34DED2A62DADD26FA63A671F598716B37
-:10661000447FA4CFF5B4F3C7F4B754B4233DB0A777
-:106620009D16D3DF3231AE6E6AE78B69F7EF067CD9
-:10663000A6719979DC9EF7A576E33DF9630FE44FE7
-:10664000217A39943FA57C2E8CB3F4451B97115BBE
-:10665000793E874157FB45BB26A4AB42CC5B6163C7
-:10666000AA294F85E7AD34BA673A0351CF7BE8CA10
-:106670003DD317FFF95C537B758D8BE9C5F49CDA2C
-:1066800037FD5D11F1AA1F4C427FEBEA3459F8DB6C
-:10669000AE69D05590630354537D4D86786FBBA689
-:1066A000810262223E02B2F29B8551FCDD33FE3F45
-:1066B0000B7EE13F8EC03FDB02FF6C33FCA2EECCD1
-:1066C000E4EFD595B327E17C0CFFF2D9A6E50D41A7
-:1066D000F7FFE6F95559E65765995F95697EF69596
-:1066E00055938279FF97E6B7CC32BF6596F92D3383
-:1066F000CDCFB972D905AD9FB5DDDDB66692B76B6A
-:10670000F35F27FD7FAD88E326ACD41B56E07BE02A
-:10671000ED76EA4F23F93E8AE99FA33CE8EFBB47B9
-:10672000548DE482D323935C60F9F6507E36876BF8
-:1067300026C885E7541F97DF02CED72CF50F2D759D
-:10674000F8E56FB86FFA9861475AE47C3FFBDACA04
-:106750004CBE9FACF2F8E5E87D4D15B83938A094F1
-:10676000E44FA38FCB9FFD03843C4A837D8DFC4483
-:106770001924AF6C425EDD57CFF3D89A457E506343
-:106780005A11E1A759D80B2C9465DA370F4C9CD2DB
-:10679000867EAB334779DEE23A1BD7C756D6339DA8
-:1067A000E8ABDE49F945FBA0DF003468057D0FCB7F
-:1067B000E741DFC3724F7D0695BFACD7A8DC01E38C
-:1067C00062F94CBD9F0560FC6DF563A8FC31EA8B56
-:1067D000503E20F4C52BD264F2576CAE872D339F08
-:1067E000F4482A1FA9F78D5561BC9FD46750FD233B
-:1067F00069E6581BD9AD1D8D4900E7EE57F3285FB8
-:1068000069429A4AFB2F53C34A5249E4B981D78F50
-:10681000A44957E077E33264DECE196AF4C66F57B5
-:1068200086EDC664A8040F7307156F5ADC76E5364B
-:10683000C04BA95BF4E70B347AE2F7F72D6C57E411
-:1068400016FDA5698DEEF8FDCDC47147FA381E58C6
-:1068500046474362FC763760BB429F986F56584E5E
-:106860008C3FEE6C1C3725A53980F1AD2B6733D2F8
-:10687000476D69DA66292A3E141A50C164A0F39460
-:10688000D4E63A6CF78D809FE5C0F89AD7CF64A024
-:10689000679B1BDE17624E138F478DBF0EDEA33E34
-:1068A0008CEF4744BDC7EFA11C3B4B7C9F647EDF50
-:1068B000A397AF613D793C98BC646B32D79365CEAA
-:1068C0009FCB571E98847C9F6CE7EF7F8A75D4B767
-:1068D0009633431EF1F609FCFD8F8CF65EFEFE1723
-:1068E000A27D4A0A9FB76B8A338471B147BE7B4948
-:1068F000E6DCC2C87C2FFA5EC1B0B951F37BE47B01
-:10690000E332E7BA23F3B9E8FB1386CDEDC3EE49D2
-:106910002D977B7264516E25371792FC1CE5A820D9
-:10692000B9336A60A98EFCACACE770FD87EDAE862A
-:10693000863C822B88F2C680EB278BCD700DAE3162
-:10694000C3F5931A335C836BFB866B9D8DCBB5DEF1
-:10695000E083F1F5E8F11FFD37F3F8437E601EFF99
-:10696000D11F98C71F72E7571E3F1CBD2E9B6E3765
-:106970008F9FB5C43CFEA625E6F1B3967EB5F1FF28
-:1069800051FA78922D70C426F45D255AEFAC0B981D
-:10699000F45368F78A681754A2F5D840C0A49F4200
-:1069A000BBD76D42DF35B5AB8869F707D11F338D93
-:1069B000ABC78CDB21FA0BCBD1FDF963FAFB8B68FB
-:1069C0001794A3FBD362FAFBC080CFD4CE17D3AE0B
-:1069D0004BB463A67199795CF82950A19FEFB30479
-:1069E0003FFA47964D5E4371AF812C20A1BFCF97F0
-:1069F000CA461D82EF592ECFBF4F9EB2EC62B43B08
-:106A0000D7249BFD5CE9766E9FD9EC0A95BE44566F
-:106A100047F900CE60E68CA87C8B6A3BDFCF7ADE3C
-:106A2000BB8399D746BD1F28BE5F23E2D469F6D247
-:106A300046942BBEC1D03E8EBF22538C6BBC67697F
-:106A4000FE761DE0DDF8AF3347A3BF2832AE8DB729
-:106A5000BB588C9B151FAE35D97CDC45386E213E6A
-:106A600037F48B6026E1D7C74BE3F9839EEF49FFEC
-:106A70000578593DD9292B49F07E3DF76F1A7EF6EE
-:106A8000647B9D13F3761B2F92D963D82EAB6F3F97
-:106A90004E53BDD9DFA9FA2A74B4F70655FA8A1401
-:106AA000D6FB770F97CBE5F1E20DA3C5BC9A2A2759
-:106AB00035E7C1F8EC90D96F0B84CDA2F3610A954C
-:106AC000C0687B3CBF6D538129AF3E7950DF7EDBD0
-:106AD00046A15FF4CC033A8AB77E370AF8D8C602DB
-:106AE000939E959C3293F4ABE486AB9DBE38DFADAC
-:106AF000B5F4EF6233756C9798D6CC64EE5C34E9EC
-:106B0000614DBEC7F83E94093209E33F693BC2C8F4
-:106B10003F674BF8790A3523149428CEC1E7896A78
-:106B200025FE24AAE1A00CED076D54593895B1FB60
-:106B3000E5C08D881F575E33F9C7549F2E219ECE26
-:106B4000D94257D379025017E3E57FCCB3733FF0B6
-:106B5000C3DACCDF65C759C7DBEC9A492F1DF4A90E
-:106B60009D858B7B6F1F69C7E1EAA1D30CA04FE421
-:106B70006F8DD3E9ED8ABED84EFA5A968FFC8E8679
-:106B80007C35F85FC4B7E78E61E247BBE10F308F19
-:106B9000DBDA6C3CBFEF73681D15F7B94DF8BFE643
-:106BA0008A78F73C56E1C597A7995C8E7C759ABDAB
-:106BB000EA2D8E5AAFB5763B1F678D8DFC5B463C48
-:106BC000777EB3CDE4EF5AB8D15C5FC066A6A35C14
-:106BD0005AB0C1C6F07CC76D167FD8BFE17C615E3C
-:106BE0000B59DD2AD4D38DFCA0B93EA662FEF7E294
-:106BF0005F3D528A7943CD769EAFF301D08B16C5A7
-:106C00005755EE901DEDF97776155F3F9EE1F7A1A0
-:106C10005583509E26B3B8E78C6E5D6386AF3FF810
-:106C2000ADF032D640F0F60687BA558AEBBF7AD47B
-:106C30002E99E244CB9CDE910CE4CC39172F7BFCDF
-:106C4000297F74917CDF27E80836C0CBB89CAFBBA6
-:106C50001CCBFEBE3BD8CB778B9D1D76E48F5AB5FF
-:106C6000AE5C92237126872DA00F86EF6C7B268663
-:106C7000073353BB35E7D9AE4DCA39AF76E5721F3E
-:106C8000FD750A79F9C2B69FD9D1BF78FAA913D791
-:106C9000201F2EFAB5C29CD0AE739B8785715F50C2
-:106CA0004376942755BB94B871598AFCC3FC17FDF1
-:106CB000C24372A26A8723341DBEAFFAE53B231993
-:106CC000E0A1B3A1FBF060DC479F92787C34D8311F
-:106CD00012F7AD2A95DD122F4FEC84A0BB53CF25C0
-:106CE000CEC27595B6EEBF99FA6DB9C1E688920F1E
-:106CF000C7C4BE04EDB87FED4929941F477E18F143
-:106D0000AC534F4A1CBE3DB6900BE1DBBAD91E0016
-:106D1000386AB77E487454F68BED5EC443ED1EC5E9
-:106D2000E4F7ADDDAA841D23A93C8125C65124E0EA
-:106D3000EB1AC6E563CDAEC5E40FAF6959F7A1E222
-:106D4000C5EFCDF40C78F18711AF6F28FEE958DF5D
-:106D5000F973AF06A8FAA0FD712FE215FA9D634FF3
-:106D6000C278AED98F8DFD7F9A12DB1F63DD76A4CA
-:106D7000AFDA96B57C3C0BBF7C80BF64C6C64F9C27
-:106D80000E4B1C6B6BEA79E9898BB69F7D3408E367
-:106D90009DDAF1D74783B87FFFBF8F1EBD13F59AE9
-:106DA0007D2E1FF27BED53AF7959D43E98E3E07C02
-:106DB000D7F9E4CF9F7818F8A4F3B8838EEE75EE78
-:106DC0007D6F8806F3ED7CF6BFD335687FC7DEABF9
-:106DD000C8EEBF6377D9C0BEF643A4D350F43917C9
-:106DE00091C7A4ED9150D902435E94967539B84B82
-:106DF000612E80F3F4314708F39A6BE1D9B2225C3B
-:106E0000A7C5247FB1BE1CF05BB36DF587CAC878F7
-:106E1000780E0E9631C79E01BB64E03A5FFBED6FC2
-:106E2000946069A338492DEB26F969FDAEF628ACCC
-:106E3000E765BDAFDF59F6B91D8378B5DBD6F271D2
-:106E40002DEB771A7F191BBB7EBA65FDCEB2EA9F88
-:106E50003E8C2F77A5C68DE71AF1AFC5BBFFA54FB6
-:106E6000BDC99003FDE1B752E270791C7A8503F940
-:106E700069C7D34F3C9CC6D7773A20A473FBD9216E
-:106E80000CE8E3A4ADFB66948FDD7B1D3EDCCFAB4D
-:106E9000F6BE41FCD5B9FB15BB46F291B925D0131E
-:106EA0003A59CF4F3BEA0D3512AFD46EF1841DDE57
-:106EB000C83AD58466946B5E7A7E829E8738DDD729
-:106EC00084F65F27C559B7D58E1C2E8F433C696F5A
-:106ED000F1963FD899DBBC9ED2185CC71353F0796A
-:106EE0006FEB68CCDF87F3BF3C6A3DB7707EED8DFA
-:106EF0002F3B373B54CC4730D6B7D3C6F5FDDA909D
-:106F0000F4068BC3AFC6FE76A1F1D00687251E2AF4
-:106F1000E6DB1F3FF73F8F0BC3D3124CAA1C1D8B20
-:106F2000AF539FC797EF8F382401475DF9A0DCD896
-:106F3000FD496515C1C1D911784F8973B3A79E5218
-:106F4000424178BEAAE520C969AB5CA8E9454F7EFD
-:106F5000C6186FCFFE9128BF4E1D788EE8B066DB55
-:106F6000093BDA4787B7EEB4771446E81EE57F742D
-:106F70005EE4A967F68F24398DFDC7599F5F0B79B1
-:106F800057DB6AEEBF76DB87A6FE17055BECE417DE
-:106F9000ED679C0F54FD069CEF07ED368679F71FD1
-:106FA000B428E5F1F49B90C366CA835AE5293D866F
-:106FB0007E4525C5AEA1BC6B5AA1BF11A4738F3607
-:106FC0007EEE51D58F39802F1B93ED1ADAAB4D9E93
-:106FD000EB991625B79B2DF8F4A5F926625CCD3701
-:106FE000B9A224DA7E32E04FD66513FC7778CA075F
-:106FF000E27909B4C3344C3250FDE45756BC53CA4D
-:10700000713E8A4FF6B9E2EECFBC3FF4B721FDDB0B
-:107010007C32D3A2E86B54D9F5C3D1D5A632CD9436
-:10702000BF7AEF641EC735E67FEF456C1303B97B6B
-:10703000AFD4DD86F9ECC1AB795E201376BA17EDDB
-:10704000F4EC587D8EE9BA86F287C40F6FCF7423B3
-:107050007F147EBE0FE0C898BF23FB4999FFBEA2F4
-:10706000533E8F1DC7CD45FB2944CF135998EA8A5B
-:1070700093CB1F0FABA3E749ACA319CF30BDEDA84D
-:10708000F8D401CFEF2B4F9138DC61CAD74816E313
-:10709000C88959997DF13F9BAC9E8AF6FB38D8266A
-:1070A000B24BD0EDF8456A040F463E9CD1EFBDAE21
-:1070B0000912EE3738BFC178AE479C9FF7F5CC5721
-:1070C000A7FA00A36E19075BFA4AC5164BAC1890D5
-:1070D00054056F0D68263FC720D64265166BA73250
-:1070E000C5E9935482EF2DF24BC9ECCFEC8B440BE6
-:1070F0007CE7A18F9F93F5E301281B6DE2F9DB9EEE
-:10710000D0E350DF90CC4CE783739D9CBF2F77CAB0
-:10711000865F26106D7735B26A9ABB2B8D1F63315F
-:10712000BEBBDE1918EE8CA227C5DDCEF3BE84FDF2
-:107130006BD8EB5729CB29FEBE3A83DBD5BDADCF4B
-:10714000CAFA0A935D6D2D9B0738E76C66043FF71A
-:1071500053494E7E7E59679A2F9AFE605C67697428
-:107160003EA3AE937D2FDEDB607AF8D28178546245
-:10717000E96F06D2DF68A4BF0ED14937F9296E57EF
-:107180000257E37C33F2EA24FE3C2071BF97AEE065
-:107190007CD345FF72627566A08F79B259401F514A
-:1071A000792D1B84FDA8AA4C4D284278368975B7E5
-:1071B000D2A5393FD5D0D7DCA2E6107972BF2979A4
-:1071C00095CEA3A8696ECA4F719734DD8EE77C55C2
-:1071D00056E743F9E936F24FFC3C9FD0B08B5D0592
-:1071E000E63C4E87256FD526ECEF983C6EB1EFDE7E
-:1071F000830FE2E8C3D67DF77667FC3C2436267E13
-:10720000BEA0A1879D2FDD5BEDC86A67FB611ADC1C
-:10721000A7539EA52AFC0D13AFF3911FBC6B9BC413
-:10722000CFAD59E8A86B47D2489487C8BF78CF45FF
-:10723000A2782E6DDBBF1FF5A6262FD3935348CE21
-:10724000694A2E9E971AE594A05CBCEBC3977F8D8C
-:10725000FEF55685E1D6DCE536E2937A322E5622EB
-:107260005B6F5ADF0B9D4F6C5C91F3DB129FC16F1C
-:107270006EFAFECC3689CE4F296CF88FF1FC436D47
-:107280009B8D85E0FD19C6FB3FB389EB030B5F8443
-:1072900051F03CA8181FF7A5E8FD23B53C8169D142
-:1072A000793C41BD1DCFFFCF13F8185091627AFF92
-:1072B000D7B9E56DE49F09F07B0006CE1A64EA6F4A
-:1072C00091B27C2825E1093F8606FF90FE8CF99F4C
-:1072D000930376BE4F542485499F01FB17ED86909A
-:1072E00044F94A567F47CD1E89F6A7DB607FC2F37B
-:1072F00038B7852CF6A3258FCEC0B7952E0F3985CC
-:107300007DE066EE5EF0EA0F97507C94F86AC98BD8
-:107310003C2F6CC976294479CC1D439318E159213F
-:10732000BFD17BACEE41D83922F46BC19B23C38C17
-:10733000679766C673628119AF1EBF198F563C27C7
-:107340008DC931B55FA454DB89C8049E0BE01FE2F0
-:1073500019E420CDA306E611D662F159D97AEF2AB5
-:10736000F46FF48B470BFE4E59F07796B5EEE76F4E
-:107370005985339D589BE69DA986897FACFC66E0C4
-:1073800029CBD73E919EF93DE42FCE109D48F3F8CE
-:1073900077839C2D9C798AFCC46F467E7062CF7E79
-:1073A000F90EFB02CAA5330E9D98CB62F96B1396BA
-:1073B000C0D72DF54EDFBC7C8C4F33DF3C1BC6ABFA
-:1073C0007D54C6D947A97FA047DA0FEEC1B8641A29
-:1073D000F2B54AF12B5CAAE9504F6CB5F9D06F7940
-:1073E0004F51F735A8B7D7CEE7798E372770FFEB27
-:1073F0009204BEBFDA12785EF35D1532D3D1BE6F50
-:10740000554212FA8B7CFA8B57A2DED56AD3685F9D
-:10741000F375BFFC1D7A5FECC3F86EA6DC3C0AE195
-:1074200080F6E46FEF6A7DC77B6B94BED3B9E7FE4D
-:1074300061B8EF3C24B3CA787A7CBE8BC3D159F0D3
-:10744000E77424C7C5CE6EB2A35777D455E0BC0C01
-:107450003BC2BE8BFBB76AF6CC207DF2D0027E1E0B
-:1074600073F7297E1E738A32FB9B23A03EF6359567
-:10747000CB4DA64F9F93CE5328701D3760BE24F28C
-:10748000C17FC9A106C24FF3EF314ED5F81795A1C0
-:10749000FE5852B780F69F5F7BA7B46159AAB71414
-:1074A000235F4F6E4D9E88E7646ADFE27995A3DB28
-:1074B000CDFE1CA6541F443FD8D9637C5BBEFC980C
-:1074C0006AB5BB14DC8FC776989F8FEF876ECB5C55
-:1074D000623FF2B2F40BC98BFD91AC4F73917F9474
-:1074E0009FE3F2ABF1EDA74713B87D037891504EBF
-:1074F0007575337F03E0A96BDE209A6FD7C7FC6AEE
-:10750000A6AECF95F278F6D12D2E4E2F0FD979DC7D
-:10751000F6A105EED00A98C781055517A35DF4C9F9
-:10752000BF052E8E17A788D8072C49A63D4F4F625E
-:1075300063902F9AF8F932D69C19EFFCBCC10F0664
-:107540007F187C91B9202110CF7FF98E8BCF6FD21D
-:107550008202CA83EDDC27518CA7B301E0EA038FD6
-:1075600041D63018E1A9DDF311F9179CADF1FDD03A
-:10757000F5784803E9B621B8623CE0EB7BC0D44122
-:10758000E4077B7376BCFE836C03F99B16B834E288
-:10759000B74E27B7A399DA9C39D3837C5276F52A64
-:1075A00080F361E03F24F9876C7E823BB89831F22A
-:1075B000AFAA9CFFB3AE619BEF8AB2B7D6BA263EA4
-:1075C000E082FE1E70F178476AC02F21DCFEBF9F6B
-:1075D000F362FF5D9F3A68FD06093F8FF15D8BC046
-:1075E0004F5982FE23FC9E55A69130F407BCBE790C
-:1075F000B0FF5FB607F01D27BFCBD077520220FB4C
-:10760000009E14B74CE756D0DE427BA296193F414C
-:10761000523E0DFEC34366783ECB90B752AB14F694
-:1076200080DC2C71BAC3E84F49A98479633C8A395C
-:10763000797FED667D14252FCA5D94013C599EDB50
-:107640003B861C36E477533297834DF7AAA146094F
-:10765000D3DF3B5CE83FCED6B549985A95A26A94F1
-:10766000E7705125F3075148E63E92DCA3F78C679B
-:10767000ECD9BF2B71FD1B275DDC1E294B08FC0AD2
-:10768000F135B2ADFB00AA4F7E174BC5F59E22F433
-:107690009BB1A7B93C32F2FA6B85BD619547CF012A
-:1076A0009DA3C018FB0DBEEF8D3DEDF623FDF4C884
-:1076B000A10553681F2D6A2D3E88F939456F717EEB
-:1076C0006442FE80F54678296D0B2A880FABDCE911
-:1076D0004FDE18F2C4BACEA05CF7D4B30029C56D52
-:1076E000C06751FBB7554E1D7389FD55C8A9B36CD2
-:1076F000C2C0ABB4083D152DF31F7444D18F21A730
-:1077000022F414223AB48E2331674FDD978BF2E5D1
-:1077100088827E90AE893C3EB942F051F2C7A1AB5F
-:1077200071FE1B5AA7BA90EE77B4953991AD966465
-:10773000F0735EEAFEEB824C904F745CD7C69C1AE5
-:107740009E291F0F2B8FF8507C508F9AD79966492E
-:107750009C73D492AE8B733F82512EC9E0E7B8760A
-:10776000B4E524713B334CEBDE43F7C20F61F08587
-:1077700041EF56FA36F8A19171BF84A13F28528B90
-:10778000B00BCD7E8146C3CF1174519CF80EA10F72
-:1077900036BA2F5937017E6D0A4FF2615CE20E4F07
-:1077A0000EE533DF3180E3CD8A07A3ACFD14F4C3CB
-:1077B000A8BCF35AB59BFC5AB59FDA4DCF0DBCF669
-:1077C000860F03AFE310AFD297C7EBA7B8BEA36392
-:1077D000F1FB65E79DB5644CDCF372FF57E63D9E17
-:1077E000057EDD4176173FB761D097212F4A976E0E
-:1077F000CC24E26837DFEB65C891317BEA0EA28AC0
-:1078000068951397B5B26B114F63C32AC3A32EFDBE
-:10781000C98D8FF1974C3A7F716302F0DFA817662C
-:107820002DDA068F466A2C753A0035B25D2539C6C9
-:10783000DACF2F0ED512FE381DFD8B865E1A8357C8
-:10784000A1971AFB8B11075A9710A8C4F1A53DC048
-:10785000375ECC3FE5F6EE5A57605102B44F0498BC
-:107860001330D7AE209CCDED53335FF6C687891613
-:107870003E6B01BCD03904D8E7F2A558388CF1F33F
-:107880001292399C406DA8BF6495323E580DBFCF0F
-:107890002E6B240BE03E8CC736719E6B85FE759770
-:1078A000A55CEBAA68C079D9541674147D79B80D1B
-:1078B000BFE0BA043D88F87096EB348FC13EE647CE
-:1078C000BD7EB0DA22F9018E946A4DEA71D618FBBA
-:1078D000379EFB99AE4D44BA189CC7E83CEC60D487
-:1078E00083E2ACCFA6041EAF5DECEC388C21F3DA5A
-:1078F000E975E5DE3EE2D3917B06FCC24F65CEC35F
-:10790000E8DAFBC64518977CFBDF3FF260DCE94F05
-:107910006AB707E13CB9FCF71EBCBFE5EDE5DCCE7C
-:10792000B8D9A2CFEC14F84B4EAC780AF1774BFDE6
-:10793000DF4BA3F99D2DE37194DB420A1A9D3DF4C0
-:10794000BD686B22F9E68CFAE2965453DDA0D3C5EC
-:107950000E9E27659DFFFBC28EBA6DDB66FB600D38
-:10796000C70FB422BE4F0A7DEDE42E0FF9330C7819
-:10797000E66E1B65473CFCA9D521E2F0ED368E7F13
-:107980007D3AC6CF026229AC701EDE9748FDCD7FDE
-:107990004021FD620E8CB50CE83BD07A1BD9D9D6BC
-:1079A00079CC7F5B9B3210D66FFE5A89F4526CBF44
-:1079B0001CE821B06C35C5D9ACF39C13B4C6339721
-:1079C000939D6ECDF398C7B47513B2E3E47BB4F224
-:1079D00038F9C27EEC9A3F26087DA1945D8EF9E8C5
-:1079E0006759E18F0AB5FEED9A93F58C92B43EA8E3
-:1079F000775279AADE47E553091A8F67EFD97F9846
-:107A0000E84B6D2F457EDFD1F64EE24D5A446E5F56
-:107A1000B1F9A3833F817A31E3FE1BC33F3E5BE0B4
-:107A2000FB4A21BF170A7DA0F8D3BEE5F76C9CEF97
-:107A3000C858780DB93D1BEF958DC28321C7ADF8AD
-:107A400038D3969B887421255AE3C05F0D2FBD7DE6
-:107A5000B758899F3768F0CF53C21F306FCB8C5512
-:107A60008360FCC6BDEF0DE1F702B3A3281F0CFA3B
-:107A7000B4D21F637576E4E71E3A6BBD9BF063D00A
-:107A800005F05186883F66A0DD67A5B7FEF2893A0A
-:107A90006D1D43500E58E9AB536271EF154D4DE427
-:107AA000FEF2799A3E05ED50D85E56F1381D973FAB
-:107AB00027D5E6C377227F6EE1FCB1F857DB7F89DB
-:107AC00072A7EA170F7851EEBCAF36A7E378D58FCF
-:107AD000AFF4629CFBA41AF4E2F7EF8794B87985BF
-:107AE0000B1325E10F37E72BB035C16B906F3F7952
-:107AF000DCE6433F43ED56078F83EFE278833A8F0E
-:107B00007FEF8A9FAF50F5F307D2359EC76ACE5BF1
-:107B1000D862A3FC13F497E130BDC5717BE2C22D9E
-:107B20007DC7B76B77AD8B9B7762E40758E9F606A4
-:107B30000BBD025EC88E09023CE4161771EBC62726
-:107B40007F3CF204C0756ACB6FBD5261B4DF9CC745
-:107B5000C7CFB4DCFA530CF1F446AF9D82BE237A52
-:107B600043286E1E43B52DEC453BBC7AB38DECBA71
-:107B7000EAED0A73623ECB7107EDDB8BB6FFE6F5EB
-:107B80007100DFA2676D69D3F934285FC158A79EE1
-:107B90003C12B12E553B7FC3E3BD9AC82711EBB30E
-:107BA000E8D9FD76CC8BB1E2B1AC65BFBDC3928F95
-:107BB00040EBD472620A9DCB7BF29C1DF7D3F7F7A2
-:107BC0004974BFB2F5FBCACDBFF1A27C403C515C09
-:107BD0005EAC57EFF942E16B9E2FA176E487EB6D27
-:107BE000FDC6E0DE3A9AE8FB99E761FCCA371D94CE
-:107BF000AF54F9CC52CAEF794FADE374FEC8CA74E2
-:107C0000DC5F2B6DC1741F95FC79E5A3DF25FA5B62
-:107C1000F8CA77D3F9791E3D93FB6D829938BFF985
-:107C20009BFE85E6B7800588FE2A1F512AD05F7229
-:107C30005665E5CFC6E1933F093E79EF310706511E
-:107C4000D97BC26F197C5511F7FE5AE349FCBE95EA
-:107C5000B3C28EDE95281BF71439A3EDAADA2DAB3B
-:107C6000DB717D3EB8481FE8A3B8BE1A14F89248ED
-:107C70001F7FE5AA81428ED13D31869E5386CFB1CA
-:107C80007DBB8DEE8B89FACE74DFCB1D627C803B91
-:107C900041BA0CCAF4F8FE4C8F5B32E0E3F92F06D0
-:107CA0007DF5C6F75B783EC9C747B95CC1BC187A99
-:107CB000DF6E0B0F34E5C3384CF78944F23D6C821C
-:107CC000AFCDEF014ECA57E9C1EF3E89E2AC0B36AA
-:107CD00038CC79703D7463BDE7C69CBFB2D0A26F4B
-:107CE00019A5552EBC69910B6CD3F9E5AF54DB4255
-:107CF0009477547DDC41F643F5765B05E2E3AFDB38
-:107D00000EBE7E13D0F95F5B0CBE35CB572BDF5612
-:107D1000EE18CDE2F1ED5FDD7E16976FE1795CBE86
-:107D20007547E2111AFBFAE4EBC25EE4ABE28ED1D6
-:107D30000792302FF783A7165D4C7E060B5E0DB9B8
-:107D40006A95978F246AFCFE8298BC3ABE9F47F2E0
-:107D50001D39FE0C7AAC7A7A318DD343B7065D1AA1
-:107D600074DB4B9E96158FD6F72FA23C1A10EBCFE3
-:107D7000084E620578AF5EA39D15A0FF392827F84D
-:107D80001FCF8E93D7C1EA86A29ED1E8CE8E9B9F4D
-:107D9000EB77FBD08CC573654ABC78B7BF4C8EAB14
-:107DA000C797B8B95CD98BB40065B59BE3AD49C43E
-:107DB00057C012A4BC7FF429123F257B899F6CF029
-:107DC0009CD1B94A3F9DDBF627CA1F69A08255B8EE
-:107DD000B5292AFA538BE5A5B9505FE82EE6F5F1EF
-:107DE000F2CE1CA8DFE62EE1F5CBE4621B90E61391
-:107DF0006CF494C950AF31E6392FC9E4DF50E51374
-:107E00000F62DC457D9EDF17B70EF8DA591489F74B
-:107E1000263A58D05584F7344209F555D9BF5F85C5
-:107E200046E00647E01A37C9A3491AE2F594CF495C
-:107E3000F932773C7715E56756BBB9DF78F8CEF1B4
-:107E400074FFEED730FECDEE01BD8FDF64E3FD9C05
-:107E5000DA31BC0CF13AFC62467E0803FF45AA46C3
-:107E6000CF5D2D78F494F83F03CF7F3426DBA99FB4
-:107E7000EA9EF53ABFB251E43528899C0E9424B9A4
-:107E8000EE5928978AF5BF43E0037FD05EEEDA3BD8
-:107E9000F0317EDF53F7105C5F4539F347D41BBBED
-:107EA000FF35D18FE757DE4CE0F8BA2169BDED52BE
-:107EB000A81739872C45A27E53DAF65D2CBFED0951
-:107EC000FC90E39F85B1BF9B6E56787FEE3A0FDE44
-:107ED0009F26E95C8F96806866031E1A75A6D97383
-:107EE0009145CDF9168A52D41DA6713DA671591639
-:107EF000EC83B04E378CE5EB0438A57DF18D31BCB9
-:107F00003E2B94D3D8A1111CF7201CA31CA18BD00D
-:107F1000FEB909D4224ED766FBDB88D3D7FE4526AF
-:107F20003BB356D21ADD50DFF91623B9DC99E015C0
-:107F3000F907FCDE19C32F31F6A5B965B864257BB6
-:107F400016F13C0EE18732E2E86759AB829389F182
-:107F5000535BE4E178B69EE4647FF1B19FBB457C5E
-:107F60006C101B7481F1B167DCE7111FBBC86DE8B1
-:107F7000F322DE2EF6FF334772285F485531278FF4
-:107F800031BBA6508A88F1DD2E8BFC35E878C451D0
-:107F9000DFAD88971147D92DDC5EEA253FE224A3A7
-:107FA000BCE6511D05941F61B3E6471C9329E1A966
-:107FB000F4C5620DF1D924E2C6171AB737E2FEC53F
-:107FC000FC514C1CFF796F39C5418B7DF1E3F8E31F
-:107FD00094D914776047F8FA19717CA6142A08E737
-:107FE000D930D86008E751F3DF01B93C2DA8505AC9
-:107FF000CD5BE6E7E32C74605DEFBF58D7FB7CF305
-:1080000020DEE7F7AA8D6223290FC226F2207EC95F
-:1080100002F747E7411878EC2FCFC49A5762CD2377
-:10802000C90C98F134B8F252D3FB8BEA8A4CF58B29
-:10803000978D33B5CF868D30BA9EBB669AA97D7E6B
-:10804000F34C537DE8C69B4CED8785E69ADE0FDF47
-:108050005AD5E7BA8F6859627AAFC8A162BC0FD20D
-:1080600058F7CBF6FC202E5D18EB6EE46961BA116F
-:10807000E27734ACFBC3D9E43F2A93B4D8F5F78751
-:1080800083B42F5FE8FAE77B843E7481FC3E0A8963
-:108090000DE3443AD713BB6CEE35A81727036C28C1
-:1080A0006FADFA4572EB0BFF2D79E3E55B682B9022
-:1080B0008EBEAFE86371BF1F20F2239B64719E7474
-:1080C0009293F4817B64F996E87BE4AFF0703972A7
-:1080D0008587FB557E02FB26EE9383135990F64F5E
-:1080E00071BE9CA1430AE6EB4D65E2FCF963AB2649
-:1080F0004FC078664781968C2205EADF88C8FD9BD1
-:108100001C5A23C60346295C8E837C9FE6198DFB8F
-:10811000CE721BD77F8236C4F360270B7A8B68DF61
-:10812000A3B866324B939614A2E9D5B3BF685F003B
-:10813000311CAC1A9E8476D0CB383406699D09B4C4
-:10814000FFDF68C8BDCA6124F7CEB87BEEB5A0F3E7
-:108150008E67E6E5D2F3E33703D701FF1CB79BED4B
-:10816000A2FEFC53959BEFF7A0FFFF780133E519C2
-:10817000547BB81D55ED5178BC3CF49774444BD7F3
-:10818000FCCF2E41A06BA5F65528A2576FBCBD822F
-:10819000F27677CD08A2FFCFF03B1BFDD4B64E643C
-:1081A0003DF707433F37BCC1FD5F377C66F6E7DE2E
-:1081B000E9E179D7778AF1AE87C20778BB1EEFF481
-:1081C000C6F2850953901FE0795882FAB7DB40F573
-:1081D00003BA9F11C8B6213CBF67FED7764B98AF54
-:1081E000ADD1F7D7B10A1BC2F5FACD8B3DD8AEA7FA
-:1081F0003FA39FC178A613F6E9E4A02D1DE8A7FBD5
-:108200001B12EDEB309E139F57CC1EBC12B70E63B2
-:10821000BCD759E0F46BB0DE33999FFA35FA672C7E
-:10822000C1240777542EFA536A0ECA3F99FC1F4B9C
-:10823000F63A48FE75559DDBFE20BCBF6570C7450C
-:10824000A85FBC59F5D92588971B372A4C83F50FB1
-:108250002504EEF344E1EDF8BC8F3CF81EF484C72E
-:108260001FC44DFE69079DF37AB3EAE94BA2F5EA14
-:108270004D9E893FF6E03E39E6FCE23D654F0D2319
-:108280007BDBA0AFDB047D2D797228E9834B3CE6D4
-:108290007B53963C9E4BE7894A2516D78EC47B3F7D
-:1082A000302F7D07D0159E23DCF729CF1FDF7924DF
-:1082B000A598CEA3B2C07684CF68BFF3E59B865362
-:1082C0005EE7B1B4F3BB1719E00BA27EC5389C2F53
-:1082D00009FE98D59A5A2CF4BBE7106F37FDFAC9FE
-:1082E000D37F40FCEC7DFAF13BB14DC9F9E18389C4
-:1082F0007DCC2FF000FB18D93F5D2CC1EF8863FFC8
-:108300003C2BF4AFEFCB3AD925E7E40A91BFCEED91
-:108310001045F667601E774BAB928878F3A2C16276
-:10832000C817D009BD78FFA2B83FDD09F6D9702182
-:108330007FDA3D1F4F69E27108935E5772A8CAA4A5
-:10834000CF55C03F94F7976F0A34E23D8DBDEA7573
-:108350006199ECE12FABDFBDF325E57DA787F37FC6
-:108360004B0197DF2DE18410B71B5831EA7BCFE03A
-:108370005CE0FDB464BE2FD8A5CE0227FC7EC6F318
-:10838000C9AA3559B0DC791C1F58C7BFD3C3DA3826
-:108390009DF6E87F872EE57F674E9C032E11E7A2AE
-:1083A00063EC49E02BBEC92698F4C7F0E1BFD13990
-:1083B00097ED29DAEFC6A33E0F7A0AF2BD4BEDB076
-:1083C00027C799DF2F517E027D8FF572FBC4B987D5
-:1083D000C7E19C9A4EF79EB97CBE51682F19ED4FAC
-:1083E00089FD66F1E13787D8619D4ECB47BC1847C0
-:1083F000A8DEBDC38B66F2658981242FC64B8EBF74
-:108400005AEAA37CABCD43D0AE6D09F3F8C408950E
-:1084100005D538F735D76E2CA64BBF6B36A652392B
-:108420000CFD09F0A836CCE7D9B9A731259EBD5D72
-:10843000FB1F7B07E1BA3D3D809F971AD15ABC10C4
-:10844000E51FC2620339F7D4A7C3A9BF4BBCD93417
-:108450003F185FC5E7209164BCEFE86961AF757EA6
-:10846000AA503BA3DF117B262A3E58CBC270F301F2
-:10847000B20F5B1D1AAEB36B0BBF0FCED5EA22B99C
-:1084800057BB6F2AB7E39279DC737B42F71FC5397C
-:1084900036FABB042E5F334B81FEB7DBF9FE380C96
-:1084A0001860873BF2DC18CFD5FA634A6A77E6F1A9
-:1084B0007BF55C6A33FB863B1AEF1EC2FB542FA789
-:1084C000ABED096119F376BA81261F23B822703209
-:1084D0001AD7807318E9F3DBEDDDEFE2F94B3A5F71
-:1084E000A7211C1C4ED63A5443BDC2E5E3F15B976D
-:1084F0004FF307A558B86A47829E0BFC764F038B53
-:10850000FC7D04CC634B88D49DC013DB739890072B
-:10851000C3564FCE8AAE83401A13F97EF63DC35739
-:10852000374D203B27A8A05D0FA52705E7C9F737E2
-:10853000BCBF604011C703FA89139DFC7D4F7B27A8
-:10854000BFB24475F376FE245FE23489F5DC676AD6
-:10855000F89DEE90C2EF5E89FEADF081911AC05297
-:10856000FDC2F344B78BE4D6074768782E31B000DC
-:10857000E9F5576FC90CEF47FAE049179D432E788C
-:108580006E33F9ABADFDAD3ED6701FE665773D2786
-:10859000699807DA65EBA6B8514DEB7B745E71EA1A
-:1085A0009E13746E4B490AD47947635EC48A32C401
-:1085B000DF58D6DC88FE3D908714A76FC9E0F2E350
-:1085C000CCD14B1E5B1185EF07BDC2BFDB1DB818B8
-:1085D000F9A655F0E73ED46FA0DC2DF4ACDDFB6FBF
-:1085E000CC8D3E87156407C81FD6C00E517EA1F101
-:1085F000BC2BA4D239B0E1AF3B6FD1A3E8AD59F0A9
-:108600007BB3182F3F29B08AF876FF9FED5E0DF3FC
-:10861000585B86A0DC6D013DACAF7CC65A0BDFF425
-:10862000E4B79CE4F771C3BA3625C13A3DFDFA9E22
-:108630004BF1EF8B00FC8CEEAB3AEE20B9B93B9BD3
-:10864000F3DF8AD73E198972EB93BD8B2E467C2DC2
-:10865000F3DA0C3A9F9480FCF42C233966F0632102
-:10866000F2A384F742713F4A21D239F29FBD7D1AAD
-:10867000F1DF6E7E2F04D039D13DD0B90FF58B429A
-:108680001FD03D7D3F94F8797BBBCCCF81831CCF3D
-:10869000A7FA24CA57D9DE3ED947FC2C036A8B902F
-:1086A0002FC307A89F16FADB75ACC4729FEB294C49
-:1086B000D21810918F7FF3703E6D29D092FC309FBD
-:1086C000444531F141D43EC9EB621F957F74D3EA32
-:1086D0000DF8F7C3DAC5BE20F4AE7D42CF65C7B84A
-:1086E000BC5F2AF6B225BF19F7ED6D30DF252F29C3
-:1086F0005CFE0B3A3920F4E043F51954C7FD428380
-:10870000751A0D25DE0754AAD7E19F2F6163CA9B16
-:108710000F6239AEA2A50C8F4C4D98D57E909F610B
-:10872000D38723FDED3A70F570CADF3DEE6098A265
-:10873000B8EB6FDD7F7C0AF351F701FEE3EC4BE809
-:108740009F6514BFA9207AEC8D6EBAA48E6BC6FB10
-:10875000410FBCA77AAA0A1B7D0D1206E0E3F57B48
-:10876000AA56E3BD803725E9C7911E97FB02C79142
-:108770008FBA5EF95B3ACAF4DD47FFEC4579BFCBAF
-:10878000AE0F473ADB9503F6401CFA3C2CE8A7A451
-:1087900097BC8ACFBCDC5EBA24C8D621FDD4EC528B
-:1087A000E8EF169CDEA5E8780EFB5D3D908E7ACE54
-:1087B0004916BC7E3CEEEFC2AE9DCFD1CEE6A3DE25
-:1087C0003292EECB30D9994C592ED33DEFAD12F900
-:1087D000272A2D7A48356B5E3518F78DD6CD769CD5
-:1087E00047D516F3F7D5A8BF8CC4B26F7BF533AF6E
-:1087F000D05F72592EEA2F403FE49FE87E4DF13F53
-:10880000C628BFA70DF37B9E96397E405E121F1AC5
-:108810007ACC569F7E1AF5CAD3824EB70B7BB47BB7
-:10882000BB44F9FDC3B6F2BCEB7127B5CD8CCF9F2D
-:10883000F2C22A851C1CA7F2F8C5B8A3B9140F1DF3
-:10884000A333F2872C68954288C74A43AF13E729C0
-:1088500060DB25BD6E2C0B35E2FD720BB74A740E42
-:1088600063D156B3FFBE7AE32B87D13C5CDC62391F
-:108870001F2FF0628D6FECC05FE2C4372E4E12FEE8
-:108880009C216C88E9BC55DBF99DB7FAAB387FFDBC
-:10889000AAE8DF68372189D34D8D986F754809891B
-:1088A000BF4FE9C6FCDB5B057DDC2AE8A39685EDBE
-:1088B00098BFBF78039F2F5B6F33DD5BBC60D7ED44
-:1088C000741EC14A4795DB78DC0D1048F19DCA4DF6
-:1088D000E6F755021F55167CD404240B5C5CDF8E32
-:1088E00085ABE57A5CDFC5DB6CF4F739AC709D6570
-:1088F000B3298FE81F0D9F759DAE33D6E95276A937
-:10890000699DCAFBBE9F2062DF98F5DF670F5F4A53
-:10891000F92E67DA72C87F60D087B59F29427F9EA3
-:10892000BA91EB99A7F794258E40BBE888EA97A007
-:108930009FE2973EF6E2798FA2BD0AC3B860576BFB
-:10894000F13A3CA7BDB32DEF5ABC8FA2E82595F6AE
-:108950008DE2978AE85E90A2978A1273298F424B24
-:10896000457C403FB4EF761DC9FB7D21CACFB6C917
-:108970002588E615478A12513FD8C9B83F427AA9DF
-:1089800024B5236A1F599CC4FD03AB32DEB907F539
-:10899000F7A9CFDAE8BCC9545BF7CB987FB0B34DE9
-:1089A000F5AF807AF54B731BF09E8AEA27253FAA24
-:1089B000D987DB97A47D07E9ACD5E67310BCDF3D12
-:1089C00080EF83DB247F3EB4AFDD7BD5F0ED98E70D
-:1089D000BDB9D81F7D2EBB2859BB1FF32A5966226B
-:1089E000D9DF532FB2D17E7A6A50E2CFE83E167DAE
-:1089F000F31494B3A79EDF69A77383DB2596011355
-:108A0000399C71F019BADFE397AF50BE42D9AE5727
-:108A1000283FA137797F3AA4B030D9DDCD742FCC6F
-:108A2000E2CD46BD83CE415408BDA966CB09AA5705
-:108A3000A1FE0FE3556D52421AFC7A70EFAF28BFCA
-:108A4000A1661BCF6F80F7247FAA307EAA45E87C01
-:108A50002EE3743057C89F458CDF33B4A8999FA389
-:108A600033EE4532E87CFEB639948716936F86F66E
-:108A700025C5219A89BE63EF1BE2F46DBD77C84A14
-:108A8000DF2D067D0F63C390BE3F99C8F3C33E79C7
-:108A90002521B110E6F3C98B0AE5DDF741E7B49F64
-:108AA0001E11FBFF99B04CFB93D1AE73CF47B48F2F
-:108AB000D41E3963477D754AEB87B40ED35BF74FFD
-:108AC000463C7F8B05AA116FDF6A4DF4219F4FEF63
-:108AD000E0726B5AAB23847EEA6FB196265CDFAE00
-:108AE0007D3F6F4A417A7982D38B21CF160A7C2E43
-:108AF00014F85CA8F2FB9EAA0AF73F88F9D0D318B5
-:108B00009737D35A84BCD964C66F97AD4525BA1937
-:108B100021B1E6ECD8FD6E11EBA0738F5D99C3E92E
-:108B2000EF4906C15E453DAC7A9B350ECEEDFA1A93
-:108B3000CB7E7A30C9F6A5EEC178C7B22ED3BBF989
-:108B40007E360DE809E3216DE18642947B067EAC1A
-:108B5000EBD2A6E526F575DEF965A1B71BF56F8B9F
-:108B60007B265A7CCDEE683BBCDCC7F5F0AAB14A47
-:108B700010D7B5C75EC93B38529323F60AD8299F50
-:108B8000250DE076CB28E8FA852C85A5A545EC9542
-:108B9000D519F74F2F4AC3FB23B8BCE81C03FD616E
-:108BA000BE80CA484ED56E7384D0CEF81F85B75AA2
-:108BB0003D008000000000001F8B08000000000046
-:108BC000000B8D576D6C53E7153EF7C31F8913FBE0
-:108BD0009A78662C34BB31F9202584DB109A40D773
-:108BE000F626A51D83141C58296AABE2B65BD90A88
-:108BF0004E5085281295B889A9D6956942DA7E54D7
-:108C0000EA56DD226D621BAB4C096A9892C8A1A19D
-:108C100025E990A0401BD0D659FC60EB9490C0345D
-:108C2000D24D95D873DE7B8D1D12B43A528EDFAFD4
-:108C3000F39EF39CE77DDED75D7DFFF29AF544DF7E
-:108C4000EDBFEECDC2C6FBA54709B63A94F069DF89
-:108C500020EA20F2449A60FB242343B0ABAF7B139D
-:108C6000254423558B4209CCBBA1EAF335B46FF1FF
-:108C7000E7E1BCEDFA52212A23EA84D5CBF2FD9D2F
-:108C80006AD6CBF33BFB25D386ED3DF99F8ACA52CA
-:108C9000A2C981E98AE760576832FE71FFF796A89A
-:108CA000D877EA928F6295D8D8322FD0FD442F9290
-:108CB000F3D9A611ED9987F6F04BEDD4800E697FBC
-:108CC00039B5C0AF878C0CD6755E540C4B47FF0985
-:108CD0000F513351F7277F1A9E1721BAF6AE64F869
-:108CE0007467FDAB8D683F6FEF9F87F9377F27195A
-:108CF00016A6BFF84DA287D0BFED4DCF95ACDFD9FA
-:108D0000EB96F89FBEB217F39247FCFA1B687553B7
-:108D10004F39616E0FED1736493FBBAE04E1AF2FFF
-:108D2000E5655CC82E581F23DA7E78A6BF24A9F912
-:108D300036F2DBF397D68EE182F1355A69E46A00A8
-:108D40005FEAA8EE96C2F1171F90B0FFE488A2F97F
-:108D50002481DBDBDF2AC4E734C058C0FD4526216F
-:108D6000CFC973257611E6FD731FC66A89C6F7C1A0
-:108D7000B90F7E5A148187BCD2B14B06DF8F713D8B
-:108D800019FFC452A23F0CBE7F2FF30109883A6C31
-:108D90003F8C798B0BE24E23A88238119791C17ECC
-:108DA0005D9F2A06DC735C35DE483EAEE36A3668BA
-:108DB00014F0637A9FD9315C8D72492745BD64698F
-:108DC00058D8DBBC39A1C4EDFA7C1BF96C35B1FE77
-:108DD000299717A44E45E388F3590D45043FBBFB83
-:108DE0009DFACA038EC5FE9B8971419BF79F35DEB4
-:108DF00066EDE0F19B9501B218B72FAD766EEF8E60
-:108E000029F406DABB3F79A9960AF6278E13F5ED09
-:108E1000F24C4599B75DE764115FD7B91BD12AB40D
-:108E2000D7D23BAB35B4D7517A3F8F7F180BFC8834
-:108E3000796DF1BEF3F37EBE0829225EE27CE1CFBC
-:108E4000A25F3A7EDD7C7B68A3C0A1C7E5D50B217C
-:108E500059CC7F554BBCC2E770F2DC7FA3489B8E98
-:108E60005FB812E47AE5EA7DE7B9BB1D3776E0F535
-:108E7000375BF5F34F83078D23AA15429EC7C68A39
-:108E8000EC76C66560DBDFF672DD2EFB88CFC3EEC5
-:108E9000C16DB5C47E138965719CC39B833F5EC65B
-:108EA0003890D423E2B2383EC435D17731AAA33FFB
-:108EB000397031CAE3C9E32B7E6161FEF2338DEB79
-:108EC000B8FFD86955F0AFF14C93E0DFB13F37956B
-:108ED0002DE2C0C908B0DFE4881A677C92234D1FD9
-:108EE000B7635EF24C5B93C4DB9C692A63FD592E29
-:108EF000513C8D7169A44AB473F9FC5C73F09B1CFE
-:108F0000021FD02F51CCE10F55CDE0CF8EDE535E46
-:108F1000CE63479F6216F228B7EE90A60A3FBF6560
-:108F2000FE804FDD69C914FC38EAD81D7DC7447E38
-:108F3000DB3D6951EFEE231E67FC8F8E253A28D664
-:108F40005934CF623C3EE62ED461ADD75E480871FD
-:108F5000B492B6A4E7D0C39AB024D68D5E4A7C9B67
-:108F6000F932DA9AA8D5EA67CFB3A84DE443928BD9
-:108F700077AF678D3D87BF2AF6873C8265B4353E63
-:108F8000C77838ECF067AD971273C5F379EE3C11F2
-:108F90001D90C18BF3ED1E8DF94F64962C80CEAEE3
-:108FA000777576D3E31ED3BB0CE3A49D2AC2F8FAEF
-:108FB0009CDEB640CFA00B71FCB1BEC5DF8C873202
-:108FC00080B4C39CA9731B29EEA145F0B36666FF6C
-:108FD00013AC970D6C55E1E76E3AF829EBE0127C83
-:108FE000A9A11AD641524A021278F3EFD31E4D11AD
-:108FF000F1DA55AC0777E697D3990FA17F3AF4EFF2
-:1090000034F48F6D77DD670D59E0313A74E9DDB0E6
-:10901000D0CF228A3101BF8277E49DD4DCBDEFF04E
-:10902000D77DFB7C7E7F06DF72F5998064A7EB67B6
-:10903000D7E786E6D421E91FF782ACD4453B5F979A
-:109040009147BDE2F0CFE74998E5C8C3D3D79A2945
-:10905000673DAD838A22BF8947259B751E7156F8EF
-:109060000A747E628124C6776F966C0B5F87EA3E36
-:1090700013F7763273D6CB7CAAE97DEE35716E2D6F
-:10908000BA40D17C1D37F89DFBF276FD72F9F2A053
-:10909000CEF981CF428F23C2F27CBE1FD7BBF7E14E
-:1090A000869699F5ABA5B38F95238E274DC9B0E76A
-:1090B000AAFB96FB4EB1DC7DDDBA2F09272261E0C9
-:1090C0003179F6C6E6A5F0375AF7F70ABE473BEF07
-:1090D000C2DF0A97DF5D81600385A02EB57A2A0B77
-:1090E0003CDE2B4DDC13669D90BF0ADE4BBC3EFB85
-:1090F000F6CB12D78304DE773B2F55AEBFAAB0E67E
-:10910000E874849633AF7EAF69CEB9F5D80B590FAA
-:10911000A81E8F9995FF5F77BB4F7CD4C075B93679
-:1091200034D2E02DA8DFF8CB38F77C8F0C7C10D53B
-:109130004B0AF925BBFC528595A48DEEFD38936F43
-:10914000E3CC37AEF7D10FD63FCD3CE9DD1491F437
-:1091500082FBF3F8F9607581DF897E45CC27355BAA
-:10916000F34469619CAF893827D28E3FA26CCDA6AB
-:10917000A585E32997B759C1DB9F2CDE19E7739CBE
-:10918000E3AD4A0E6F3BFB3A48DC476EDE692FBE0B
-:10919000202E6BD067FF06E3939EA98A70C1B9F8B1
-:1091A000A18B737346127C5C4996C27E9BE1F119D8
-:1091B0006EAB9451611FA08CE8275A48CCE3FB5D4D
-:1091C0001E37AB9921A941CCB354F072159D15F30C
-:1091D0001EA229614D82C0C3B691216C8B3FB38E14
-:1091E000E5A33E9D56984F99A81ABE0A3EB294CC6C
-:1091F00055BF7CFE2A5DCDF11393F1B8D91A9F4378
-:10920000AF0FBAE7DCE0B71AD77982EC43E87A907F
-:10921000B20A6FF2804A6B14E4F3A04AFE62C47B88
-:10922000745816E77730ABDBAC5F4699BBEE0BACFE
-:1092300043BBD974CE295F35CF34E6F3BD138755D0
-:10924000F017E2792ABDEE113866C47E0F73E0C8CC
-:10925000BB957495DBA970A5C3679A7A96F779A434
-:10926000DF27DE39B2DF1278FC34ECD433003C83E4
-:10927000F0B3EAA04463D8D758E4E49BF3BF0AAF45
-:10928000BE5023CF77EE31B4690CFD01BFB38E68B9
-:10929000B5C6784999A87C2BF0F5719D8C92883BD6
-:1092A000F8C2D4B5BDE2DDE6D30E2124A3FFA3317D
-:1092B00009EF69C934690FC7E32FC9F0FB1AEC182D
-:1092C0002F7C57FF3AFCFC5B7CDE255D13785182D6
-:1092D000747E67CCA75F697C6FC83CAFCC81EF1F01
-:1092E000C0EF4957EF2E173BBA71D8DEA8CBA8C7FD
-:1092F0009688DFE07A34FA2B9613FC6E284D08BF6F
-:1093000097A523D5C2896AAF60BF399E07C86C6133
-:109310009C25B75E7BFC8EBFE922C7F299643E07AD
-:1093200020E77EC47500E7C28FB6D5E6D4DBFABC71
-:10933000C84E61BF69392EC8F88A62F805DF6389B3
-:10934000B16658B5CDD47796F0931D7904F279A41F
-:10935000781FDCC7F4033C1041865D9A934FAA4402
-:109360005ECCBF9752546CE07144BB4A1D9EEDFA2F
-:109370006B914D95B3E33BE94B9CE4FCA665636CB4
-:1093800054DCA33B9B59EF18A7EFE47092F3386DC0
-:10939000B163A9AC2E7019619DBECF67DF93C1BACE
-:1093A000A77C7635C79FC303051224D55C9C73F850
-:1093B000685C3FE6B189FAE5EA1FCBE374A0D8C147
-:1093C000073FDF1C1C74D471E9ECFCFF0753B7A7FF
-:1093D000EBB00E00000000000000000000000000E4
-:1093E0001F8B080000000000000BFBC6C7C0F0A3E5
-:1093F0001E81C3D1F8E878022F7E7952B10C038226
-:109400005DC1C5C010CBC1C01007C42780F82410AF
-:109410006B70323024027112102F00F21702712586
-:10942000101700D5363333301C6663603805C41717
-:1094300081F8061BE9F66B483030EC9241F0396454
-:109440001918D8E4A9EBC7513C78F15A0354FE5BD4
-:109450004D54FE576D06063D4304FF9D2669E627E1
-:1094600001F526033100FBB288BA68030000000052
-:1094700000000000000000001F8B0800000000003A
-:10948000000BED7D0B7854D5B9E8DA8FD9F39EEC5B
-:109490004942184248765E1030E01042048A9E49E4
-:1094A0000A8896D2889E165BAB4340823C035A4C96
-:1094B0008F78B2212104083050AC91224E10305ADE
-:1094C00068A3A2D216DB8094A2F5F4466BABB53E3E
-:1094D00002521E3E68EAA38EF7D4C359FFBFD6CE10
-:1094E000EC3D9909D89E7BEEFDBE7BD2AF2ED65EB9
-:1094F000EF7FFDEFF5AF358AE824F23F117211FEE0
-:10950000683A4C24840C8AA784C85A8F0352A25FFD
-:109510002CB4E4C945E972F27F1B61CDEBBCDF7F5F
-:1095200021248B90EFF032FA1782FC149E31E6630F
-:10953000A424A890AE92783F5308CB6BA2402E0A89
-:10954000F0D55A6E8C53EFF08D2169847CEA64A9C2
-:109550005E458BCA69FA9633DA984F88430817B28A
-:10956000F9D45D593D1AD3AB206D14C8EC4E4F921F
-:10957000799035848CA7C9FE2122A988CF3FB19E5E
-:1095800091363510D2658FE765998492F55B41E796
-:109590000FFD9E13C215381F0F91011E0A87878D7C
-:1095A0000409A1EB3AE29F169843E7DF3A5909DA3A
-:1095B000A160FB10684C7C061C67E761DEC1F39577
-:1095C00044E3F0EE6A29A4ED9C41916CA0B9A6FC9D
-:1095D0002A07292564F3C4BF06C2743E4E3942549B
-:1095E000483DC9E7379388BC9F7BC9E5AC3B713FD9
-:1095F00064D8A3F19815615DC67CB7D8E8BC32E9A0
-:109600007E8C17C95E9ADF543E2B0DE663ACCB917E
-:10961000629C6680EB0842363638306D9A302B8D6E
-:10962000403BD23B1BF677F3C42C718310AF7F64B1
-:10963000E271470F5D6F236FD7AA1D75407D639F51
-:1096400013E1B699C32744049CF7C6D1AED9D1D251
-:10965000FEF308111F966F76D246B00E2F89EECD1D
-:10966000871E7ADAE6D2BC6F825AB641EB8F2F534F
-:1096700046CBC12E3A4F8FC713B4D3724F80B57704
-:10968000BC2144356C1FF20CA1F55DC6FE4F10E302
-:10969000F0A4FFF7916A42283DFA727A5F8371EC79
-:1096A0006FD88321FADDFDD947AFCDA5FD92934256
-:1096B000702F8C4B965BF68BEC6170B5A9F4DFB420
-:1096C000DC3579FE0C5882FBF327AB016EEB8B5631
-:1096D000B856C35E95B0FD53E9FF2E16D0FE35C5D2
-:1096E00032BECDBCBFF9809AD6BCBB78D6D70AB5FE
-:1096F000D4F8E1EEF191AE0C5A59BA05F73B55BDDD
-:10970000FA37C65E73CC346E1BF1669E71D37F5CF4
-:1097100045AE423ABF44FB4F1B82D71CB3E1BA456A
-:1097200033BF49557F2DC78F3E3CCBA7F8518AFBED
-:1097300019B86174FCFB4B8017400F7A25F231A4F5
-:1097400045BADEE6AB49AF44F7A3A958D1D65038A5
-:10975000D855A54BF0B1317B01BFE01FB4A9BDA81E
-:10976000B95B180399EF58F860CBE07F0D760D30A8
-:10977000BFC47DF8A2F0EB02F85D11879F9D54A74E
-:1097800075C17E5707103E5E3E8F7557AFD4BAE85D
-:109790007AD6657F3F749298E07815A3B3BEF9E45A
-:1097A0004489797C83BEAE14422F027C2425F85A6A
-:1097B00098C2834C52827B93AC4B16185F89C3D9F5
-:1097C0002113034E80BF87F5C00D5E9C52B5C304C4
-:1097D000677BE0F867003F399374B9C7E0F7263933
-:1097E0009DF2AF4CA2BBD3B01719F29F917CA44F4E
-:1097F0005A3E452903BE302D18A6E334DBF878EA3B
-:109800006ACBBE7EC6F7355EAE07FED9526EC3FE8A
-:109810009ABD9C6FA88D38BF7EEDFDAC7DE27AFFCE
-:10982000027C743CD45339FE340640DE3886344F13
-:109830003F02701F51D73917D6A8128483C1FFA9E0
-:109840000024508FCA87CFA09D43AB46B8DB73423C
-:10985000248C70B3CAD3947C39418EF6C32795E625
-:109860008D3E0AE0BF392AD21B4994DF3C0D0DBB67
-:109870002C39D8984057B4ABA47266B4C0F82DD137
-:109880003371FDB281075C3FB019E0D8CEE859E5ED
-:10989000E32A301FCA0F9D248A9DBB29A643DE4BB5
-:1098A000EA30FF49A8AC4B00BC91C97AE073F6904E
-:1098B00048F4FCFEE36FE6F224D53A364F4C2E070F
-:1098C00086094C0E489E3ABE1FB7A84067821E26E6
-:1098D0001781DE4884CBBF20EEF7BA867AF20E5DA0
-:1098E0008CEBE87544A3F823E7D48542B49D04B417
-:1098F000485934F194B3540E6A66FCEADB47B21A55
-:10990000FBB351B0C03A6D1EC71C320652F5064C6F
-:109910004B46DD0EF4614B9B560FAA1CC59B4A01BA
-:10992000C67724C72BE2A1443A11F35A75D2F1F855
-:109930007EF37A29F1AB0F3F8CF56A4AB5B73FDE6B
-:10994000B8CA5501488166BB613E83F96C06879BA6
-:10995000978B6360DF22D387D3FD19DC3307E59350
-:10996000F78DEBCEC3BAD696969D00152E2DA8DEA8
-:10997000308DEEA7AB840800EFF5D0D924E8E18460
-:109980005E09721DFE994DC8B7856743BA87A18FDE
-:1099900055DF1435D9E027E280FA8B70D1DEBF7D28
-:1099A0004AFE4C4CF483727CC5E5E94BB7B0F174C8
-:1099B000FA3FA03B7F823C4D0B99FA25001FEB3804
-:1099C000EB006F10BECBFF5BC653C93687067A47E4
-:1099D00091A846E9D86944F5535E4C5C536402F2A1
-:1099E00044CDE9D5617B2FB52F6B09998E7C94D23C
-:1099F000AD19CF77723E10A869CA6FA6FD7E52EEF0
-:109A000009021F184CD966467AFFF56C4CD0B33763
-:109A100096EE46FED848F1A800F4FD5211F5A1F5E6
-:109A2000454FA86679F57383DFF4C30FA2C915C843
-:109A30003A08A1F0918AC49073CC3F8E1F897AD2E4
-:109A4000E5E287FB16EB7E7CD1FDFA759FFE7D7902
-:109A5000F8F18F8E67EC6B2ABE45F715F5EF166DA2
-:109A6000D680FA4BFF7DDD86FBEA2A22A1647CB812
-:109A70005B10ACF2C99C9AE507B9D3B25FB6C2AF2E
-:109A800007760F000F5B49829CE4FD3AEB25ED342D
-:109A9000E8B1B28AF2C8B01FD66BDB74D0E73FC919
-:109AA000214CDF8B2CEF12400F2A22A807410722FE
-:109AB000CD3BB5507483C0F01FF6C5D06F6C541DFC
-:109AC00033C357525D963C99AD0BE6F93BEB159CC1
-:109AD0008703C603BAF4D00E69BF520EE972A2FE24
-:109AE000C9E60F43313BFE9ECBC203035F01AC0CC2
-:109AF0005FADED9A036524D9FEF51BEF26EB7C5391
-:109B0000F2A5C4761E593B63D24752B793C9199345
-:109B10005E33B4CF7FA11BFADC2181EA858D81AF52
-:109B2000EB386FF80F95AF2D905279260DA9226171
-:109B30000DE4A4C6E8444B67F2B743B0D8E1C6F7DA
-:109B4000D4F360E3C56EA7B8087C4DD62CFA7262D8
-:109B5000DAD810F8924C91D25DFFF024791C55624E
-:109B600057876657D3FAEB1B3A26C177A3DE54D149
-:109B7000B0BFA9D834E9C732A1F51CF8955C1C0721
-:109B80001F55A299E4BB83746239FDCAF78FE03E8A
-:109B9000A05E45BBAC1335EC572187B01E7404F5AD
-:109BA00028179F2497B0EE20BFD1160AE1BCE488A5
-:109BB0006305A5BB8D4E9ED778DECFF32ACFE7F3A2
-:109BC0003C951390772B344F53A72DA262DEC5F33B
-:109BD000F93C9FCEF37E9E2FE079611BE6372AACDD
-:109BE000BF0D7294F5EFE2798DE7D3795EE5F90266
-:109BF0009E27BBD9F8769677D9A2AC7F37CFE7F30B
-:109C00007C06CFFB79BE90E785DD984FB57FAEA28D
-:109C10000E06A73EBED019CFA3F0E070EDCB77259E
-:109C2000E419BE64080C0F635F35F02688FC917858
-:109C30007291DE86F0368DF3CAD877EE47317D3FDC
-:109C4000A15139F749584439996ABEDFE7FC743BA2
-:109C5000E8B934DDDAA062BAA521807AEFA6068DD4
-:109C6000FB554AF0FBFA8620E6D7354CC0746D43AD
-:109C700008BF37364CC7FC630DD598EF68988DE95F
-:109C8000BE8630A67B1A1660BABBA10ED328D57744
-:109C900021DDD5A063BAB3A105D31D0D114CDBE6C0
-:109CA000953D5F04F35F40E73F007F183CDBEA0728
-:109CB00019546DE58BE953D22DE5EAE46CABDFA4D2
-:109CC000BCC092F7948EB2E45D456596FE1C399354
-:109CD0002CE54A6695252F7BAEB7E4AFE89865C9B9
-:109CE0008F8C7ED3D2DF88B61A4B797164A1A5BC64
-:109CF000B06585259FAFFF8BA57E5EFD1A4B799BD6
-:109D000033FCAC48F9D5B0BA0D967A43176CB3CA98
-:109D1000AB199997C5B7C8C77A96D99F91C8EFA5CF
-:109D20005C120AA1DC62F2A511F016FC5EC3487455
-:109D3000AF00FEAB6B4F80DD612F6272A79F7D99F4
-:109D4000D09FE2D9F79A4EC7A9F49D08F498E88C01
-:109D5000044CED28DF3F2532BB79C3BDCCAE6EBDD0
-:109D600037B97D8D9C9DAEA3F5F3E4FEDB1E51E279
-:109D70007A906EB1535AEF15B0FE3FDABF519ED8BC
-:109D80006F7C3C8A7315663D246AF845899E15B739
-:109D9000776D3DFEB960F71876AEE460DF2B4B823D
-:109DA000279B28BCD7AA04FD866B3D5504F48A4F37
-:109DB000544637644F2EDAE346FDFEF333E915C807
-:109DC0007F5C563FAD6716FA3DD7660EAC972931DA
-:109DD00009FD77524C205D54EE2872F5F47C4ABFA1
-:109DE000CA2B52703541F993D4BE27641BC2414A35
-:109DF000D06F9AE625F0BD29C370DD36BE8EC6CC85
-:109E00002AFCDEA40E3C2F3BCC0BE6C3E7658BB9E6
-:109E10003195624E9CEFC45806E627C4FC985E1547
-:109E20001B8A69456C08A6E363859896C7F2311DC5
-:109E300017BB02DB95C546623A36360EBF07636331
-:109E400031BD32F625FC3E263611D3D1B12FE3F7D2
-:109E5000D25825A657C4BE82DF47C5AEC37464EC92
-:109E600046FC5E12BB01D311B16F613A3C7633A65A
-:109E7000C5B1B99816C5E6605A185B84ED0A6277D9
-:109E8000609A1FBB13BF6BB1E598E6C5EEC13437CE
-:109E9000F65D4C87C51A31CD89ADC674686C23B6A2
-:109EA000CB8EADC77448EC7BF83D10DB8A6956EC6D
-:109EB000014CFDB187B15C8DB5639A16FB217EF72D
-:109EC000C51EC5D41B7B12BF7B628F63EA8EFD0C5F
-:109ED000BFBB623FC1D4197B0EBF3B624730BDD4CC
-:109EE0003E2939563E2E65BA2CF909A7D32DF851D3
-:109EF000F186958F97BF5260292F7BD1CAC783C740
-:109F0000CA2CF931872759EA971EACB2E447EDB75E
-:109F1000F2F1923D563E3E7CA7958F176DB7F2F158
-:109F200082562B1FD79AAC7C3C7795958FE7DC65E2
-:109F3000E5E3D98BADFC3B30CFCABFB3C80EABFD58
-:109F40003D65B755AE4D7ECCD29FA7FC09ABBDC0D9
-:109F5000F98CABF4A796768EA2A349ED9A447F398B
-:109F60008044A6F47D377105CDE72A469ACEF941A3
-:109F700006D01D4D3339DD0D02BAA369FA5716E339
-:109F800039D3A75F6DF95513ED2C7D28617E017DD6
-:109F90005B15F8BD9A87F03CFD22D07ACDC308FA54
-:109FA0000988FE6E2596E7B3FC0FA433953AF3DFDC
-:109FB000B2727281953B59FEB1C67F5B0DE5E969CE
-:109FC000A1EC20ED678F2D391F7F4262E76D17C42A
-:109FD00050BB44D7FBE7CA9E95E047B33BC27B2505
-:109FE000FA7DB1239C07AEE90F6CE14764E08B2456
-:109FF000B40FBEA791D02312F26BAB5FB415146EF1
-:10A00000DACFC762F57E28CF98D9817691B1EE6616
-:10A01000EFC0F3894A4C2E35FB09DA8DFAA30ACA40
-:10A0200053FC33E4059583F7BB7D2128DFF5A8B207
-:10A03000DBCECB2D72A33E0BE586ADA37939B824D8
-:10A04000EDB09F5232BF680FE6D340E32F04FBBE52
-:10A050003757A6E9527B5733C8F5BFFABBDF122446
-:10A0600084C7AF003E2BAF0F63FD35EE9913603D03
-:10A07000141E27E03B85C7F3D2A0D4F02070B24075
-:10A08000E71F30B068BF60F13F9E13C2BF954C7EA2
-:10A09000CC403888703B20A9080F037EF4EFAE74E3
-:10A0A000C31FC3DAFD11C74DE84FE6E762BF95F85D
-:10A0B000F85C1E1A789C21927032F81BE73EA423AC
-:10A0C000F70BF9B39D8A98741C9B5C8DE7A9FDF88A
-:10A0D0005E66825D9F1986B35E2A3FA9BC4C32AF93
-:10A0E000690AF74FC97997757E15E5FA3DD99FFB47
-:10A0F00085CEBBC0D083FA438D7D3A968BF951BC97
-:10A10000FD50D0EB283E3DF7A6FDE812CA07765178
-:10A110009E614FE20FD8D521E2F9FA503F45385AF7
-:10A120005ECFF5006A13A13E688C2B2FB6FA8F2202
-:10A13000360EC7C356380EA588FD536A72134F1EDC
-:10A140009B1F3FB734FA69EF9BBF751EBBF52031EB
-:10A15000DBDDF9ABA322E83572079DC798FEE31358
-:10A160007EBE60D091ECE17E13350FFB35C64D1CF1
-:10A17000874833F03C29157CFB8DF305CFEB2AE4AF
-:10A18000E4E79D747F104E4529F43CE3BCCEC83F04
-:10A19000F7662D9E7F37476A50BF6B0EF073F6BF90
-:10A1A000D15EA11F921C4FF6727C7A889F8BECDDEA
-:10A1B0005EE5C0769979967D2ABEEF265798E967C5
-:10A1C000E990EE6B63F5863F308F7FAFC1EF0FAD47
-:10A1D00062DFF3EEFDD8C9BE7FE88734AAB3EFDAB9
-:10A1E0006A99D717B13EA9A77FA673A0E16AB508FF
-:10A1F000FAEEF0ED2404DFF2D45E01FCC89A4A4482
-:10A20000DD04D7ECED472BAFA3E5D991EA59D7C1CF
-:10A21000797898048B35F8FEF2EA91B88FC401FB87
-:10A22000BD83AF3B2712DE3012EACDA6F548BCBC99
-:10A230008D8F3B2C12DE761DF8EF4A583F46F9F71A
-:10A24000797B97511EB2B68FF0F2DC55A7BA46D093
-:10A2500076B991DE97AE857A1DD67A9B79BD51503D
-:10A260000EF3085AC769E5F390F4DD04D0438A90F1
-:10A27000F4E9D08F6AED678381BF505E8EFFC6F22E
-:10A28000870DBE90C0478C762D29F6DFE0273BC1B5
-:10A290004F3002FD5598E6B426F7BF96717E65E013
-:10A2A000572A3C270B448B7D47C22E6B7EB649FF55
-:10A2B000837C28DB5A3EA1C05A1E1C65CD97945959
-:10A2C000F3DA244BFED33E3F4BD409F460F8590C2B
-:10A2D000DFCC0E95D149DC8FD7ED34DB2539BCDEE0
-:10A2E0008375CC1FD3E8E1F4C4FD322E4E97CD2503
-:10A2F000CC6E31D6FD24E75711EEF7D8D5D0C6FC89
-:10A300003063438E7CBA9F2DBF938203F9A11FE770
-:10A31000FBF1634E8F07B8FFE6877C5F1EE5FE9B6F
-:10A3200047C07F03F40AFE1B3BEC3FF3DFB473FF2F
-:10A33000CD43E0BFC17DADE67E98D958DE06FE9BD9
-:10A3400011E0275A80E916EEBFD9C4FD371BC17F43
-:10A350003302FC422D980EB231BB7CEBD45036F860
-:10A36000CBF64C4D6E170FB231BCC8074586A6B967
-:10A3700024F46517E02F456C3897293F167ACE4DA7
-:10A38000F323A20CAEE50743CF4179711BCB17F243
-:10A3900071409E807CA1FF60713639541B32E1EF21
-:10A3A000B817A3640EDDB7B7657E0EA051D5232B79
-:10A3B000EE2F8572D8A73785508F3C1EFA25CC8F9B
-:10A3C0001F0E0B401E83EFEAD5155A4F5DDC1D8230
-:10A3D00036BE96CE2EB0B335BD0BDB6DAD0CA29F55
-:10A3E000CDD8273ABA051FE8DC902F0EE3FB4F26A5
-:10A3F0005BF12137B60BF5E1E6BA596988771A198E
-:10A40000D05E2FD969D517866FB7DA49CD77CD1AC7
-:10A41000D0BF9CE82F53275BFD65CD2503B7F7958B
-:10A420005BC7F79426B4F70CDCDE199B39A03D78A6
-:10A43000855893611B14CF17C6AEC1FA89FA9F0CD9
-:10A44000F16F54AF93A72821380796A7A8187A254B
-:10A450004FD1781AE4DF433C5FCDF22A8B93A0FA08
-:10A46000623E8C43F727E1FC3B44E07C7AEB48C238
-:10A47000ED91DA35A11C9AFF6782F6C449F9CE2A1C
-:10A480009DE677CC7088D295806F2CDE41E1FB95FC
-:10A49000A144D723DD6E15C96E9ADF131998EFF525
-:10A4A0008B83F084D07F3374B15A260D40F7DB17CD
-:10A4B0008BD3A349FABD86D315394612F5EA6B6CE6
-:10A4C000F4FBDAC5B354E0FFF24D41B41F88C6E691
-:10A4D0006FF0B98CF481F76F57C27C7353F87556DF
-:10A4E000DB38BD9530FE68E07FC64A86E7A9FA5F93
-:10A4F000C7F959AC53B0F87F06DD545D69CB447B96
-:10A5000028E8013EFAB9C4FC688759FC9A414F8D8E
-:10A51000252F23FF36C6CFCEE902B38D341F99C84D
-:10A52000E22A287CD15E3C42F97829F27B02F55D73
-:10A530000B7A2A991F3D8AF10FAEBAA00E79C9C3D2
-:10A54000F005EC515E1FE7B3E1AE5921D8A7C61C58
-:10A5500012E420C6751A78D018103134E29312A68E
-:10A56000F7CA2AE51330FF9132CE9FEA59172F1A06
-:10A57000F68B04E789BACEEC37167765C4E30D6D28
-:10A580001B83F8DFEC5D89E785FA58A60748A49B92
-:10A5900088F9381F5D2C077FBF1A04596FCBD4058B
-:10A5A00033BE7D4D08DF0BFB1EC7AF4E8C4731E03D
-:10A5B0009708FF6F71BE9A4792DB1F83B97D93A105
-:10A5C000745E077CB7E5518AE749E266FCBCDE0FA2
-:10A5D0003A66A5012919746B941F90341CC7C80FE3
-:10A5E0008D292CFEAFCB6AA7FCFFAEEF1FB459E359
-:10A5F000F3FE47DFFF1F7DFFFF117D9FCBC7A96BD8
-:10A6000060236C1E962F6F9EBA46C7F559ED7649AA
-:10A610000E5AFC1FBD40FF26392F7BAC7AC9E5F3EB
-:10A620000D19F527121C66E1BF19D903CB19C3CF49
-:10A63000F1E930439F0F215D90A21262D6D79A8034
-:10A64000CF5338EEA470E47187384E365F97ABA7CE
-:10A650005A17317EC2CAB7772E38EA1C81FC5FC612
-:10A66000769E406708E4AD43EB46FE6BF069CA9FF7
-:10A67000C72A8380CF5720FF739544307E6D2DD736
-:10A680004313E10AFC305006E325F021A2A53BA0CC
-:10A69000FCBB0C0764F0E3819FB27E603FCBE5C654
-:10A6A0007D187118B9F40FF8D04699CD8F1CB2C639
-:10A6B000B1537C7458E275CF3D8CF2D4E8C7D077A3
-:10A6C00012DB35A9556A32BEF8A610FEBA32009EDA
-:10A6D00024FAB548021FA71C54007D6EE88CE9E8F7
-:10A6E000AFEAF36FC956BE2E078CB898FF5EFE5EC8
-:10A6F000A7FC9DF1EB5FD0FFB78B9FEF27D2716274
-:10A700003FA24EC49E24E3E7EB62C2B9B355EF17F4
-:10A71000648DDD13AAB39ED3C89EECE4E7093CCE5A
-:10A72000B366421FFE7EE38F147FEF3861633C8C7B
-:10A73000CB25C3BF7B07C47BD2FDA981F84F2ABFBD
-:10A74000E7916A1F147E40448C2BFB80BCEC1B6796
-:10A75000DAA77D0AF3E79316DB29B86F64C435DE08
-:10A760001E6179633EB56DD6FC7C322B0BCE35E68F
-:10A770006FB7118863BC83C8A77A8CF9533DE7FB98
-:10A780000A8BD3AE2575CDC0CFD672FF7D8D4A64BE
-:10A7900088435CF2CC8315606F1E50981EF52E85A1
-:10A7A000BF668A575BE8892A703EF1CEC1715FFFB0
-:10A7B0001281F6D1E66C8847A47A2DD8BD89709FA6
-:10A7C000DB629DDFA5E69F385FE37E52AA79C81D54
-:10A7D0004228991DF133C51A3777A97B536F8391AE
-:10A7E0008CE720D67B53976A775AD148B2FB5697AD
-:10A7F0006A77FEEF1CEF428AF196387A14E003CBB9
-:10A80000E4F074A1201EF7A5D8AA43432928E44305
-:10A8100063BBC0176EAAD77299F54E80017219F505
-:10A82000A68B03F47781D3F1AFF63FAC007D7EF0C9
-:10A83000D8C99970EEB3E8671271C0BAF67B4917B0
-:10A84000B34F1490630B0F4AE88F237257C58DA640
-:10A85000385A8CB8A5EB5FF4632FC6692C7CC21EF6
-:10A860009D41DB2F7CFA9D3184C2E1C29ADEE34335
-:10A87000C1CE784C6071897ACF981BE9F78532B9DF
-:10A88000AD3A091FF4D8199EBFFF13F76CC023A17E
-:10A89000E3C8ADD86FE7376C76D3B9A064B7E1B839
-:10A8A000B45E889D6709D16281CDCF7CDFC2880705
-:10A8B0007DFF5181CDEF902DEA84F975B42B615A5B
-:10A8C0006F59C75F106FBFFCE3033E80C3B2439272
-:10A8D00085BF2CEB90BAEC63303D69C7FB34218F08
-:10A8E00040F9C8526431343DB804E3C797766EFC32
-:10A8F0008BE483F656FAA1700976015C5F9582338A
-:10A9000020FFE4233EB01BDFEDDEEB03B8D27EE791
-:10A910002814AFAEF9D8446784F51F4BEFDF1FD57D
-:10A920007414C0AF659DEBD97809F4F92EFC634827
-:10A930007FB930CE6E950B9F90172BD05EEFC84835
-:10A940001A6FDF271738BD2E3AF0C92E9D8EFBFEF9
-:10A9500013EFEDD2E9FC17FFC747BBEE01BDECE7F3
-:10A960004E15F8CCB2C77EE72326B8CFB433BFC1AB
-:10A9700085471FD9B783D2CB853FD8D1AEBDF0EC88
-:10A98000D95C8DAEFBC2E39F6569B4FE5DCF4E1D01
-:10A990000C70B8EBA92F0F1EC84F00F81AB59BF723
-:10A9A000358AFD6B870416DC7F98A709FBF3DCC1B1
-:10A9B000E772619E1FBC66C7FB8CCBE8B7FA32D842
-:10A9C000AF25C8F721BF8AC279E9FE757F91C624F9
-:10A9D00083B73E54C4C3454A3601D8EF1BBF7675D2
-:10A9E00039A4B6A006FD915EE4DB89ED96BD42F781
-:10A9F000F5CAD4FBF809F99B02F05FB67F3D1B371F
-:10AA0000611F3F807F4CECBF8F8BFBEDE3E287D073
-:10AA1000E638989134FECAD8C7254FFDF3807A8076
-:10AA2000C10F2E05DF053C8E70A23DB4CA0E74F531
-:10AA3000845B0FB0FD8DCEA065170E7C924B287EF7
-:10AA40009CB3F5DE0A7CB2F759BBBA9B7E5FF8EC8B
-:10AA5000AB4867179E7A49D1904F128F40F5840B0F
-:10AA6000A4EFAF1BF486A5FCCC79D91E6F97DD1738
-:10AA7000DFA7A5D11BA66B3EFC7E12BF4719FE2F98
-:10AA80008D1EB94948B26F4FDB0B183F8F0E42B88D
-:10AA90002C21DD8A5A6ADD4F6102ECE3C9698077B7
-:10AAA000A9F6D158BF0AEBBFCAB49F7B18DD26D6E2
-:10AAB0005F4AE913FC887DFB1A155E2549E8F442DC
-:10AAC000BB5D8678E10BB64BDC03FE82FA5FA73DE7
-:10AAD000857DCFE170293ABFD4FABE28FC76817318
-:10AAE0007B507F38BEFFB7E4FCFF45CE379692F02F
-:10AAF000F46CA9BFFC9248481F9A1F9F6F73A784EC
-:10AB00007CFDFD0E290A4D13F9C4D2147EA7D7EDA2
-:10AB10004C1F597AE8C818E067EF1FFD09C74B863C
-:10AB2000F74BF79F54742E0FA2667990C23F799A23
-:10AB3000CF7BD9E1E4FD2DDBFF97A4FDBD2B87BEC4
-:10AB400001F37FB7DB4674DAC5BB9D52523FEC6F11
-:10AB5000EC364B5C61B3B7E2B534DA4EF2B9341877
-:10AB6000BA714DE8551DF492976D78DE41E4E039F5
-:10AB70003BF813BD2E6D038557A36F3EFA2B8DFE58
-:10AB80009A12E02407AA75B04BE5CCEA72A62347D7
-:10AB90002D76B14D152DF3A6723607E4D05B63CF49
-:10ABA000DA609D6F27E8836FCBA47930EDEF6D5DA0
-:10ABB00008AED692E1B7B5FFF02A896866F967EF6B
-:10ABC0007D0BE6437EE12410A722FDDCA9033F595B
-:10ABD000B6CB1985B880E79EFA741FC0EDC24376E4
-:10ABE0001E27C0E2CE6B55D6C7D9A73EDDF5EFB420
-:10ABF000FC2C34A6E3D7EEA2F5410FDFEFC6E0FF51
-:10AC00003F3F91368650FE5CFB8B7B66027FA90539
-:10AC10009E4AEBD7FE7830EA756706B1FC9903C30C
-:10AC2000A2B02F8B9F7C7629C891453F7213701973
-:10AC30003CF7D4ABB742FEC22FBC182779E11767A7
-:10AC4000AF013AA0FAB36696E37798DF2BA0FD2E0A
-:10AC5000823C2B172E9AE26F16414AF9C6A243692D
-:10AC6000780FC8540FDB2DB3F7AE0CA23F59CF16A7
-:10AC7000D1C6E9CA063A5CD4611D6FA483F949972D
-:10AC800029BDF359FD4836A3D76E6C57E1E078CA69
-:10AC9000CB13DB1BF5CB1D05967A46FBA5765297A9
-:10ACA0000CFF2B79BF8B3A3E1F61ED8FE16BFF717B
-:10ACB000D8F7EF08EC9E0A79DC89E76D8B95AEE159
-:10ACC000E9945E9F56C802A0DBC5BEAEE17E3ADEC7
-:10ACD000CF389F5CECA279FA3D9BCF03EA439E38C4
-:10ACE0007A7E04FBBBE41927017C5FF20B2F9ECF19
-:10ACF0002C79FAD3333FA0DFDF7FCA8D7E9325BF47
-:10AD0000B81BF77B89BDEB56F0FBF53E6E477FF332
-:10AD1000FB8F3F9F0B7AC8FBB6AEDCF401ECF3254A
-:10AD20009D76EE8CB0AE83DA052575743EFA561624
-:10AD3000C7564F5CC1D5109F028E03C0E3379C2CD1
-:10AD4000DE8A9FEFAEE0FEA00FE7696938FF52E6AA
-:10AD5000DF5AC1FD072BBEAA0DF69BE60171A66462
-:10AD60001C21772B752380CF4AB1AF108DE6E558B3
-:10AD700021A6463D490DE2F98394C9CECF6D994194
-:10AD8000525B0AED585C12F15CDF4767FF8B6EF196
-:10AD90008A07B4C1D0DF4207D3A7DB9CA1BB1D68E3
-:10ADA000CF78F07E29AE933204FD29B6AE4F05B6BA
-:10ADB000AEC4F97E6AD3EDC0CFE3E7DEEC9CA55EBE
-:10ADC000D65E85F34C7282F3A57EEB6774F6A19A8A
-:10ADD0008E7466AC6363838AFC647D4300D3750D17
-:10ADE0002544C3FB0141CC4B1C1EF6529D4870DF2D
-:10ADF000566373B57BAA43707E017DE2B986278CCA
-:10AE0000F8650FD4A1EDEFF010B44F258F4E6A3DD9
-:10AE1000E80F4338C1B90CC049E179B96D06C29554
-:10AE2000B6C7EF2B9DE15D001747CE280B9F52322E
-:10AE3000CB2CF97E7033F0E2C07F37FC08C26B7D0B
-:10AE4000830353B85F017083FB1590FFBF00BFE31E
-:10AE50008EF1ECBE8366A21FB8EFA059E82905FC6D
-:10AE60001EA0F0CB8CD355221CEA797C9B414FA9C4
-:10AE7000E817EEA7C0E5836D0D6D981ADFD353C8B0
-:10AE8000F5E14E81C7058457DBB87F1CF7215327B6
-:10AE900039267F1209E8782F0AEF5743B987F9114D
-:10AEA0008DFD9554F98C95FF69AFC27AEE7EC1266F
-:10AEB00002BF92EA1F26EF6498E87846B5534338FC
-:10AEC00007D17FDBC8E5EBDABEFDB4D2C7C6060DFD
-:10AED000D34D9C4EB6703AD90AFB0EFEB9A0887BC2
-:10AEE000DA3A9DA0FCBC8FE6997DDF45CC7E6D7F74
-:10AEF000B0B3CB46F71F7992866917F2AFD7ECD182
-:10AF000062DACE5D4A42802FFED7BE1BC5B592CE17
-:10AF100000F843FD1C7EE47081FF66F69E828DC9B9
-:10AF20002922B1346203FB2911BE8DC1A30EB0BB2F
-:10AF300053CD272BA8DB73E978596FD8917F67DE53
-:10AF4000D2F95A0D5D87A7D58DF6645690E1A327F7
-:10AF500018166A4DFB979542EFDBE7BC2ED349E903
-:10AF60007810C4F3D2745B5BA113E0BBD1D6190097
-:10AF70003EB8D1CFE48C369B8E7695A93DE78FBE47
-:10AF8000722BFD1BFC589D5C66C16383DFA64FB12D
-:10AF9000E2BBC16FCF3B983ED7E6AC1EEE8478DEB5
-:10AFA000D84EA4C744FC6FB429BA40F59446D025C6
-:10AFB00041BF3B29B0B894FE7C00E3563EECC9DFAC
-:10AFC0000DEF0EACE1F1D43AA517943BDCFF699C80
-:10AFD000CB1F20D52DF00E4C0BC52302EFD550FC16
-:10AFE000017AD84CF107D208C51F4627133035F037
-:10AFF0007326384FCCE7BF45C745769F4304994336
-:10B00000646A077AC0CF7464A203F442D9C6E259D5
-:10B010007ABD6227C4B3ACF5CC7284C0AFE32FC74E
-:10B020007DFFABB7266FA07315785104F046F50489
-:10B03000C9A9D2F8BD5F492D23604F1EF074E3F912
-:10B04000DED54ED132AF3667F846A7C9CF3F1A4694
-:10B05000E7FBF64FB8FEE4F7876F73723F658E4EDD
-:10B060008A4CF46DC499124D2725263A5F533C8DC6
-:10B07000C039687FFA4EC1C7F6FED7F0B1C6BC280A
-:10B08000EE9B2D916F6452FEEEC154175538DF3B95
-:10B09000D4F42D3FE2D95D000FE2D9DDA7BFFC5308
-:10B0A00041FF7926F2ADB83CD2D05F45E5D1FD1322
-:10B0B000800FA6904747DE1CF1358596BFF3BC2470
-:10B0C00098FD750B62EB511ED4C626128DCEB7A625
-:10B0D000ED7B98CE6F6B47BC3F175DEBC3389A167C
-:10B0E00066CF9D8BDAA2523EE2ED4509FCFA84F56B
-:10B0F0007F6E6723D623E07D318D7B6E276B4FCA31
-:10B1000035D4A73FE46BACD9620FC139CDB936DA7B
-:10B110006E0078D6803194443FC5F704E0EE00A974
-:10B120001B017CCEA0F7BB15CA97000E6FD993FA0E
-:10B13000D9573AA7EE00BA5EE90CB533B8A75FD687
-:10B14000BB16EF8854EF4578877D3758FCACCC8F21
-:10B15000F90ED78B892345B98FB75793972F697D00
-:10B16000EFF8BD34D75C1AAE2626FB5A22CCBE5E61
-:10B170007AA892BF2FC2E693043F993EDB6A473E0E
-:10B18000348FFB830C7C8DE34BD8C7EF975AF0E9E3
-:10B190008ED856DC6F61E3E8FB2752F87D44F10856
-:10B1A000FC72C2C6AB07031DADDEF0A52DB7D0FE05
-:10B1B0003F7E51C2EF0B624EAC7FFEDEE0FDB780FA
-:10B1C000BEFE6F36027CE4E31353F13CF6BCCDEADD
-:10B1D0004758E462F2FA1CA7E3F9B18D16FD787EB8
-:10B1E000CB5C05FC8FF3639BF1FB7C3894C17B2027
-:10B1F0007F3E5629C3790DC1F3D173CEF7A7AC01B9
-:10B20000381C2E433F56ED267BD27B29E79C9AE5DE
-:10B21000DCB9B6A715FB25543FCACCE2FD99F84727
-:10B220006D0C2EB1C0FEE804EE2DCCE77CA46F7E41
-:10B230003B6D163E72DE99DC4F12E37AC9FCD8975B
-:10B24000908EFAAFEF1A465FC6B83D8CEEE2EBB9CE
-:10B250007F62B2F5C4D73119EB9FF7271F3F8FC329
-:10B26000F94CC30212A27CA8C64EEB7960FC3B9B52
-:10B2700027809DBDD39F2E98D655DBB688844CEB96
-:10B28000AADD3947A931F51BDF07E72FCDFB90B7C2
-:10B29000419EBAC60372BBDAEDA270AED978F598BA
-:10B2A00030DAD98C9FBC630BE6025F3DDB766752D8
-:10B2B000FACE736916B950DBC6F787EABDE5A6FD7D
-:10B2C00031F625B1FD99376BFF7A2FF8011E604AE0
-:10B2D0004D2A78F5DBB7FCE4709BE862787986CA82
-:10B2E000D930C24D7BFA35C0EB4D6E8CF74C0DBF9B
-:10B2F0002B487820F8A5D05FA9BE53E61A0FE312B9
-:10B3000084436D1BC3834BC12D3E2EC783CAE4EB20
-:10B31000A9EDC3837AA253823DA55C0A0FEE21BA40
-:10B32000638075F4E1C1680B1ED4BA8AA7023D9E02
-:10B33000033D6544FFFD3FA5E8BE49700EB441C220
-:10B3400073A6532E3DEB9B2C3F16F8F3295F64E662
-:10B35000A4F278FE8EBDC5BE39A671CFB6DCE94B2E
-:10B36000E667AD4D853F453A29ADF83F873FEFA4ED
-:10B37000B8C7B5D259B908F6934492FB738DD4E09F
-:10B38000DF529AA7CFEE04797ACA53F0D7282D3D21
-:10B39000E40CAF047ABA5BD4C6CC11E2F6673FFD89
-:10B3A000B361FAD5A78BC15F587DF5691BEA43D815
-:10B3B0001F01BD329FC745A07F6308CA83C4F3D273
-:10B3C0001FB8F2939E8FAE6DA81B07FD12874E54D7
-:10B3D000739C1C617AD4FF86F1F3E3EB516C613509
-:10B3E00008F6A540AA01CF6D72B805EE03DB0299FD
-:10B3F0006375135C1F7031FF97F3D8B1967CDADE6A
-:10B40000F9A7175582F7CC74F4AF3972E40FCDFE6B
-:10B41000695B268B5F2445A6EF0510874CF3163B2E
-:10B420009FCE77003BF567028383EEB5F37B75BA59
-:10B430000472EF662731FE50FFFE8311072237B1F9
-:10B4400072BF51DCC4CAB9FF72590DF34F26EEEB3F
-:10B45000CD87D775833E73F3E12173C18F75B367D1
-:10B46000C49FE07CE167E0C3077CF733B99CD8EE6A
-:10B4700030A7D36FB58BBA8DEECB315BEF5137CCA4
-:10B48000F73BEC1DC76FFEEE98CD4DD3D75F396506
-:10B4900083773B6E83001DBAAE39445398121CC5A6
-:10B4A000F67349A797E53B07CDF29AFBA3A62AF4CA
-:10B4B000B79C9DF37EF377AF4C05F14FFB5B0BE937
-:10B4C0006D2F1205FA9F73506B66D7F8787F8769E6
-:10B4D0007F62BCBF381C1566E7C80E844B1C4E0E3D
-:10B4E000849B012778E606CBE370467DC380731FFB
-:10B4F000DCD2665F4FC6A4A6979B3DC3FF44C6C47B
-:10B50000E79508E78FA188D2DB7157E88F403707AE
-:10B510005CA137205DECE8CD950BF01E630FE4973E
-:10B520004AE1BC2C8A671F0C0B8F1804715CDDC9C3
-:10B53000CF5713E9F42DA01788FFE67198B7F2F5FD
-:10B540003DF7DDB35E8CB37CEAD55C4897483D9B04
-:10B55000BE01F4F66B09F5EF0F0F8E18302EED2DAE
-:10B56000EEEFF8D425F2F303B6BEDBB81E77DB416D
-:10B570007714DEE3BCAD5EB2E8BFB7D5B3380E22B8
-:10B58000778FB9C9A24736A5EC07ECCEC47E8CF5FF
-:10B590001DCDCDBE02ECC387C62B1AF81F8EBCF89A
-:10B5A000E11F6A69DE35CC81E7B29BFC1C7F2B452D
-:10B5B000DCF787FC21F768F03B6D480FEA749D1BB0
-:10B5C0007E493A450A9FA3235746ABE8789BAF16BE
-:10B5D000D167B525F670A40ADA95B2778F54AE8F8D
-:10B5E0006EE93ED506F878F6353BFAFBD3BD12CEB0
-:10B5F0006383AD3A17F4F73FB52B49DFD97378650C
-:10B60000ACD72EF460BCDB5C127100DF38D83D6B28
-:10B6100030CCC717242AA0FFD99D92C8F464C3CFA9
-:10B62000D125333FBB2EB37C88A7AAD3FCDEDDFA3D
-:10B63000E953309E625EEB4B184FEC2B4F7ECF6987
-:10B64000829BDDD7F576A7635CB4778A886F24790F
-:10B6500083BD02B4CBEBAE52B07D4418B07DDE2A80
-:10B66000F53A802BB407FE9F7799ED836E05E1B024
-:10B6700095DBC9EDB660F314DA4FFB26BF00FB6122
-:10B68000D4BBCECDF499B3530CFF4D04FD37B9456F
-:10B69000AA13DE5BC90D2171136F79C401F0DA0DB5
-:10B6A000F5987F13E1D03EF2E92E383FDE00B2017B
-:10B6B000F6D9C6F069C32601FD99147ED9202FFE64
-:10B6C000749FFD2BB08EBC164105DB9BA649E7BDE0
-:10B6D000DAE360F2A6F57EB403C13D0AFDE6EEFCB6
-:10B6E0002DCECB9B62BD3FF430FCF8D325F023C7B1
-:10B6F000CDFC36B9F5DDDC4EEAC2F716230027C8CB
-:10B7000087CAD93B87724833C7A1C4E987D9617416
-:10B710009D18075A334189821F406C69C77785E7B6
-:10B7200046ECE45ABABE56A13B04F4A28F17F97B4B
-:10B730005EA1B7004E9BB70EC678B675622817FD9E
-:10B740003BFFAAE0F9D8D1D0870FC0BBBCBB2628ED
-:10B7500048174743EC9EEC43AB0ADAC10EF7D657C5
-:10B76000E17BC1515541CED2584E5E8078D2C6554C
-:10B77000A22AD0FA916AE33E82EA02BC182B7D74B9
-:10B780005D099C9F0D11C19744CE0AEC9D91B5AB0C
-:10B79000AA54D8D7B56AA660B65B748E077FF457F3
-:10B7A000EB6EBABEC0BDDB548801DF12CBB802FC21
-:10B7B000857A8BA2B1778BD9FB24197C5F32BAC50D
-:10B7C000AEF93ECC7B16501379CB64E6A7FCDEF5D0
-:10B7D00061E65F8433C90AF42FF2BF00EE6B26CF17
-:10B7E0006D18E5C2CCF635F3B13EF49345FBC9289C
-:10B7F00017BB2A68BFBBFDA15D284FA63A104E4477
-:10B80000EE69033845A76607E1DDE46D1387BF04E1
-:10B810004F54659CE89D0572343ACCF57A3BF0A90B
-:10B82000B58A06749EB1EACC2DF0DD1FFCFE9D901A
-:10B830006634FDFE1E9007FE9EBF34E0F7E98AC520
-:10B84000BF97F1C6F9CFA13CA35AB1F8093FF3570E
-:10B850003FECA6F0D9551A89D468EC7B282BBE8E14
-:10B8600003ABBBA7C3FBD9676F1083BB7939AE6B42
-:10B87000BB1ADDC0E0560E72CD80DB3A51EB84F787
-:10B880009DF5990EC48F22D28DFC6A089C2217C6A2
-:10B89000F725E38DF5CB214E22713ECFB885BE77DB
-:10B8A00061E09D4A8CD7A7724C1932C50578FD78A6
-:10B8B000597700F4F84DFEE4F1099F7A587B7B8AB2
-:10B8C000FBEE1F79183E004B6C2BC334341A520F19
-:10B8D000D1D320CD7184203EF67151FB23E2F9369D
-:10B8E0004983FD81FA36BA7F475E7817FD83472288
-:10B8F000BFC5F4654F097BD78F125C16BCB35B7E66
-:10B900000ACF4736AB0C476A5B18BFA80DF438E086
-:10B91000BCA2B694A8BB39BEE9069CC1DFC5E555FB
-:10B92000CD4D0CAE99A504CF5BC12706EF9E6541B6
-:10B930003D0ABFCC96D5CB711F49B75E48EB6D86EB
-:10B940007E617F9AD8FD14427A1C48BF1109CF1B33
-:10B9500029BDFF06CE136B5A07E3793B5C7787FE60
-:10B96000D2F9B8E9BCBF76DA0FF8FFCEB648643733
-:10B97000F2B76E78639868AB282E237EF65696D081
-:10B980007EB57255DD60E081C1C72869CCA3F202A3
-:10B99000E0364FD79703FE9D72A82FC03CDCDBED4D
-:10B9A0001AAC7FDEF667EE06BDC51DE86901FE50E4
-:10B9B0003B81CD37BD957E47FD46FB0DD4AF6DB5C0
-:10B9C0006B6C3C0EBF728E671C0EB7F379DFBE93B3
-:10B9D000CDDB352C1A01FCAC5D45E10A656186F7CB
-:10B9E000E0D2BC28225D9D80F57BF52CEC77D0EC75
-:10B9F00004BA48C03F635D357C5D35ABD8BA08A753
-:10BA0000273AAD2EE8B7A69CAD731E61ED45F84E02
-:10BA1000FBBF9DAFA7467F1AD3DB5BEC96FE779505
-:10BA2000ECE986F9E4972A9A807066EF6DE6F27584
-:10BA3000E536B1F1724B9F4678917AD37CD12F6A6B
-:10BA4000CA53BA3AFB3C252C78CC22D781C874EA79
-:10BA5000BB0A9EA3146DB7AEEBECFA110FB782FFD1
-:10BA6000F33E05CF2B1E17836FE5A11DAA688CFF3F
-:10BA7000047F3B03F8F4ED4D78BFEA402583FFD9FE
-:10BA8000AF9228E043F189EA748077F189304FEB77
-:10BA9000F01C9B0244E8E37B747ED4746A11805FDF
-:10BAA000C60A7FB800F800DD67D0078799E74DE741
-:10BAB00097D192550571489913D2AB147C4238A1A5
-:10BAC000FCC48E59F01E6EE6B11D77C238438869FA
-:10BAD0003DB4FC4A6F21BB9F758C9642BDFA33F78B
-:10BAE000C27EB4F277ED8B6166E9981E833483D20F
-:10BAF000F7C67498A74CA694C5F9C1DEFB2AC60206
-:10BB00005FC1BB2565987691B2FE7CC3547F24AF9C
-:10BB1000AF0B49EA5578358B5DBEF7BE6923C17E10
-:10BB2000DF0C7A621ABC0BA87E04F1317A5044B85B
-:10BB30006FB675394A33E1DD719180FEB2A5E4F745
-:10BB400022D0DDE6832408F89151FD1F76F33ED61E
-:10BB500079FCB86E59211B81FE8F8E3C331DF6296E
-:10BB60007A84EA9DB47ED5AF3C3BE03E71FB1F5822
-:10BB7000FC49FBF37528BF57E62A49DF7D2697D09D
-:10BB80001313EBA717CF423F5EDEF6ADF8BE6CEDA8
-:10BB90007439782DAD9DB9BDB212F418AD9A62D743
-:10BBA000603AEF9D635703116A33D87995369D7DCE
-:10BBB000D7A6B07463C3827160B7473A6467119DBA
-:10BBC000EFA8F5ECFDBE8DA51F3AC2542F2DAF7C1A
-:10BBD000C2F155FAFD74399582F4FBE9C91F3AE1C7
-:10BBE0007CE6A1F2AA0C80E7C116AB5E47E0713695
-:10BBF0006A078DB647425E3AAFD6DF1184A764EF7D
-:10BC00006AABA179E9190F6838FDEC9BF5ADEDB38E
-:10BC1000014FE795607872FF7DE7F2626E7DEFF489
-:10BC200002A05B9DB073D4C8FDC8946FE72C235F5E
-:10BC3000EF46A6E3DDCEEC93881C3A0E7C39521A0F
-:10BC400056A089C1CF5A8B6BF6013F53B8DE4FEA3D
-:10BC500016E0FD48A47F09F4A1DECA6476D3B7DDFF
-:10BC60002EC4ABB33B6F7C15FCD3F3EA99BE9FB7F0
-:10BC7000F32301F783EA7D4368FF79E5F8E425992A
-:10BC8000B72AE2180DFB5324124D83F97412B01336
-:10BC90002254FE98E160F4FBF7B6DFE1B1E33ABE6F
-:10BCA0000DC6F3F8F87A3C7C3DB9C1DECA64F1B345
-:10BCB000DFE2E37EE7C18F8E4C04F8AF6226525E6E
-:10BCC000E4A4E030CD234FBFBC79DC02FDD1793C48
-:10BCD000E961F7A7BDE53D78EF2891BF833A0F747E
-:10BCE000BBCB7D612CB3EFADFCB45F9EE355E2F7B7
-:10BCF000DC047E35DADE793DEEEF01F6BE3A2194C2
-:10BD00006E1DF8ACA8C6DE9D8D1AEFA0D741BD51BF
-:10BD10005E8F0A78D03AF2F765009F4D5C5FB8BD40
-:10BD200094A0BD7A7B4E37EA0B739BB8BE20079B6D
-:10BD300081C9BA77FAC90693FE802E2C702D357111
-:10BD40007DC190FF5C6ED706BA5B50AE827E60927A
-:10BD5000AB353A93AB790126D76B5BE8381A47E6E7
-:10BD60000AB35EC2E4B8B69DEB0F5C0E67F07133A8
-:10BD70005B98BCCA003DC207E1073ACA653CCBCB21
-:10BD80008AEB2D834A99BCCC687D1CE5DA1FC0E99B
-:10BD90003208F8069397C35E7A45073005E8E73620
-:10BDA000CAA78FF1F2804AF5B3F4B87EB64EE4E745
-:10BDB0004C84E987185B4FE77998D737BEEFE1F3FA
-:10BDC0007BFC58FA5780BFEE8D148C954C748B5EBB
-:10BDD0004F9ACF2D67E7F4B9F5EC9CDA1B9CBF4F67
-:10BDE000329D3F6CF5707BD3C0ABFAAE00F48BF79D
-:10BDF0001D918FB3F7AAD6537D09FD4FDCBE9AEB98
-:10BE0000E67E0D8E3FA9E489C187BC24E42BA5F012
-:10BE10003D1DDD87FC5AA7F612ACED74A4317B21E1
-:10BE2000D07BE4867298FFE6897FC5B88BBC14F698
-:10BE3000A2C3EB30E0F085F8BA77FA2BCC0EED1602
-:10BE400093DE9399CAFD0F9D3271033C9D11F6DE7E
-:10BE5000A1738292B4FE042FE39B195E768F68F380
-:10BE6000C47D78BF31A57C96892E2591A786BC6DAF
-:10BE7000857D9E44C8CCD65B9B75B4D3A3D512F206
-:10BE800057760F30C27F77462F51D06FD86A8B38E4
-:10BE9000603FB694F37D551DED703FFD0BEF0B85B4
-:10BEA00007ECF3FA901815F2619FA3EA68E6D7C190
-:10BEB000DFED394BED77F339C52CAFC8E1A489101C
-:10BEC0009F98D7C2F06BF34405E7B1616C56BB9401
-:10BED0006FE6BF02E79F0C4E1B261E47FCBADCF93B
-:10BEE000CDAFBF67D269D339E299071E290038C7A1
-:10BEF000DF6F090D787F617EFD4B93F624391FE8D3
-:10BF00002B073BCA037660F49BE67396855E6667F3
-:10BF10002DF11AEF3333FE06FCD586C645341BFCE3
-:10BF20004B07AE8EFAD07FBF989DD7DEC1CF6BDFB7
-:10BF3000DD7323BEBF301AEED426D9F7F30DD6F742
-:10BF400017CEEF7D249BF935A216FDEA8E7D3F19B1
-:10BF5000C5DE9FD1F9EF72102DB382BDA38D72FAA9
-:10BF60007850B74BF1F7D114F85D0CF0B703051713
-:10BF7000C22BA09D987A807E0BE1F7857A315541DE
-:10BF80001C15829D14C4349354639A45EA300D9075
-:10BF900008A6D9A413D31CB0730B412EF462AA11C6
-:10BFA000552426BE5F4082982F22D598CAB06F19BB
-:10BFB000F17309B9C381F117707E01746F9C531836
-:10BFC000E7FB377B6B1EF02639AFB8C71BDAC1BE63
-:10BFD0007721DF9ECB59F8891F8DEA84FB3D2B36F4
-:10BFE000B1FB25065F47BB86F6FFC3742607F46DD9
-:10BFF00002F2AF35EE99D7201C5B6DEF9BCF1B880B
-:10C00000C35104BF3F63F43B97FB17E672F907EE99
-:10C010006D76FF2E88F77FE6829FC1544EFACAD90B
-:10C02000FD6BA31FD13D79F840E77BA6F6188F5C26
-:10C0300093A0FF5F526E27E4E725B6FF1B9D505685
-:10C04000DC0FF7C36BB45C76CEC4E43645240DDB5D
-:10C05000B5D84FA21D16991A32C3E5258EFF863C2E
-:10C060009997E0D74F4CE7C99C2E12FAA192CF0FB7
-:10C07000F766F00D14135D1BEFE81ABFD375472860
-:10C08000AC0C61CD02B08F2A9F7784ECAC1A42D3FE
-:10C09000739037F9F37FE70BBFED35D1891AAA13F7
-:10C0A000CDEF34CDE77438556AAD04FE76364C8258
-:10C0B000603FDC41EA36833E465E9190BFC13D6CF5
-:10C0C000F8FDA06170A0918E795DA1E9070DEC5E8D
-:10C0D000CE1978476904BC7FCDDE517A0FDE4DA2C0
-:10C0E000E9E8B6BB67021EBC0BEF27C1FD5B4EFF44
-:10C0F000C6B8A33BDD7340EE8FEEBCBA16EA8DEEF8
-:10C10000B0E3EF45951C5C5F0D7E2178CFC545C738
-:10C11000C9A1E339D2818F1094B7EFB5BAA26BE809
-:10C120003CDF6B93902F7F522AE2BB23F06CA6C4B6
-:10C13000E797960EFDFCFBADA087BCCBF988F17E9E
-:10C14000E47B951ADAC7BF3CB04E807B09EFCDD1B6
-:10C1500070DDEF0DE9CC4D07B9E463F1E545FBED8A
-:10C160005D05741E0B1FFB43410DF0BF82C8C26406
-:10C17000E7CCB93E264FDE7B8A603CDC7B4EFEFB83
-:10C18000488E4E9FD9CF1AF00916BEF59E97FFCE66
-:10C1900052CE25EAF1F872E2E9F431BAEFF4C1794E
-:10C1A000D4FDEE1FE1FDB5334FB1738A5F3E509B66
-:10C1B0000BFEA8229FC6CEBD0F3C8971E3B00EB026
-:10C1C000A3E9FC3498DFFDEEB7DE05FF036D87F7CA
-:10C1D000338C76670ED4B2FA6DB4BE0FE14E7C6537
-:10C1E000800F0CEE643FE31386FEB8289A85BFDF0C
-:10C1F000102F17B11CA6E8A4F01FBDFF063CD7AA5C
-:10C20000F0A5337C563B47CDC2F94772611D07AE9E
-:10C210000EE7821FEF8CF17B52722417E070B33768
-:10C220005CE133ADFFFCC96790BF9788756FDF0B8A
-:10C2300078F904FB3D93BBDFD82A9AF9C7541FD382
-:10C240007BEE772FF5C179D499BE7775222CDEE786
-:10C25000307BD77511A7BD33EDD47EA2F038BFFF78
-:10C260007B587EA6EFDD9B4E8C273BBFFFB9744801
-:10C270006B783C3F89DE88F445E1D2E24822AFFA90
-:10C28000EE4545D97DB70B027FCFF441036E75CAE9
-:10C290002CCB7915A3EF9C9DF9C7505F8E26BF2745
-:10C2A0009728EF13DFA7BDD43DE0539C4E4FF377A3
-:10C2B0004DEEF1866B7C49E448CDC625B900E71AFE
-:10C2C000B85387710E95D782BD8DF74DD8FBB45DFD
-:10C2D0000827E3FD59FDAA6B21CEF18C9FE5BFBB7A
-:10C2E000B97A9DCEE1C8EA4F63EDF359F97D504E1E
-:10C2F000EBFFDE5BBD9C8D4F04F6FB48363FFCCE6A
-:10C3000085C1FF52AFDFFA3B171DC093C7637FF7AC
-:10C31000607F32ED6FF43FDE9FC16FFEE17E1CFF58
-:10C32000B5FD187C18E81242F6483038EABF027EA4
-:10C330007F6F7B323BCFC2CF3F7DA0B019CE813E15
-:10C3400009B077A2ECADAB09C8A5DBB76F4DFA3BDE
-:10C35000797D791E4FA214523A33D1F3F39CAF3E4C
-:10C36000EF8B9F07C0F9CC7042F87B175455C9C2B8
-:10C37000901BB4FF46F077E34B4804F5AB51A41390
-:10C38000D352D28DE918D28B291E931682AB2F88F7
-:10C39000E99F2B7B2A60F18B1DE1872054D7EE08A3
-:10C3A0001F077CFA6058F8117807788D7BE924988C
-:10C3B000FFAF7DAAF17BA224E1F7D9E2BF2BA281D6
-:10C3C0005E332330905E4354F9FDBEF88D027C4706
-:10C3D000F8651FAE2FD5EFCD25FC8E25BF476CC06D
-:10C3E0006109E9C438885FEE5CF102BCEBB370BF51
-:10C3F00017E5C1F09D4DF87B620B497716DC2F1DC8
-:10C40000CEDF93206DEC1D0FE39D88916D76CB3BC5
-:10C41000164B127ECF6811FFFDB14589BFEFC5EF06
-:10C420006F6E840F49E20812EF7FF6FA52BCE75AAA
-:10C430009AFC776512EF7FEEEF1431BE6705C40BEF
-:10C440000971BE37724F9DDD8A5F9DD71499DE83D7
-:10C450006A1482CC9EF6BA427B85FEE38C53197E29
-:10C460001D1084A47164DF4C33EC9B26723DEDA754
-:10C4700071B1AC82BDD91875E13968A3CAECC2A10B
-:10C48000DE2A07D8E9C42FAA703F659A3419E3CB96
-:10C490009525F23838F73CB67B6137DC5F680CC80D
-:10C4A000E8A71DEA67E7A0648888EF0334A94FF87E
-:10C4B000E7C23E79D839E33095E0EFA11E695F29E4
-:10C4C00042BE919A2D83611C21DC8DF76E86C88453
-:10C4D0009FBFCE189B85EF98F138A556BC7F3C6571
-:10C4E000C96927C8F53CBEEF5569F9B84E99EFE721
-:10C4F000AEFA537EC0D3E7DB9B5F9E46FBB3456538
-:10C500008C6B2DF9BCF1F56974BCDE768598DFE3A0
-:10C51000CC5D255BEECFE6DC65CD2B09F788656247
-:10C520002AA7F972181FE148F544735C55668839EB
-:10C530000B550FDE0F0EA5094C2FE6F90AC85390D4
-:10C5400074D822552E3ACF8E3705F43B1C6D9F9F31
-:10C550008771FA3F09E7017E1BF890B87F4A9A6617
-:10C56000BCEFE1E4F7839D705897883F4D0DA41808
-:10C57000FCD18EE831D715B08F276CF89ED45AAE17
-:10C580007FCB1E16FF6EE04B62BA3601EFD67E7E81
-:10C5900023E25D2FC5BBDD03E09DAC6AA827D872FE
-:10C5A0004810C8C396D99DADD276573CA3043D141C
-:10C5B00064D37E5C9A06FACC15CFDDCCDEF5A3F011
-:10C5C000C27721EB9562B0FBEDF599C57206D4F305
-:10C5D000203E7EE861E73F72BD3B08E58DED150129
-:10C5E000CD84D7CD0D6AB15C0CEFE3388AE1779644
-:10C5F0009A53FCDEF330BF580DFE2585DBFF77A68E
-:10C60000B1F9DE99E6C674451AF35B3C28EBB360DA
-:10C61000FE0F52FC817881237731FC5D31C481F7B4
-:10C620009E573C5F3878A038A07D0D816280DBCEBC
-:10C63000BB6AD0EF51B9FC9813DE055BE175A880A9
-:10C640008F926FF8FD9301DF5FB0E1BDAF466F855C
-:10C6500036D7D49FE49B807E2549D4B3C1286AD9BC
-:10C66000F2D6B5F244C0177D0748A248DAF16B65EF
-:10C67000CA5F3ABC7AB640CBDBD25E60E583F41D7C
-:10C68000022D8FA6FD86E587E9D9F04B221D692F83
-:10C69000B37CB1BE03F29D69BF67ED41B7A07ACC10
-:10C6A000A1B4D7AF053DA7D1169C0DFE9D1FD1F9B2
-:10C6B00097D2F977F2F4A71C4E46F913F09DC2FB0E
-:10C6C000204F13CB9FE6ED0EA528FF292F3F9CA2FC
-:10C6D000FF9FF3765D29DA1FE5ED8EA5687F9CB795
-:10C6E0003B91A2FC055EFE628AFE7FC3DB75A768F4
-:10C6F000FF326FF74A8AF6BFE7ED5E4B51FE3A2FE5
-:10C700007F23A1FFB778FD1EFE3DC7DBF23ABC1BBD
-:10C7100096D3CE5E022DF1B6A0FEBEB3AE1CF1BF25
-:10C72000713CD3330C7CCF81784D9ABF52657ECD5E
-:10C730002B55C6E75FE1785DB9BC680BE0DD8A7F09
-:10C7400093509E523982BFE7AB2F67712F2B9E67A4
-:10C75000F741562C97F1F7800C7C34DA1BF3DFC5D8
-:10C76000E7D764C031AD809FB7048A6798E33D5531
-:10C770006BDE41E90942769A32997C29595EE518C7
-:10C7800001F283CA17E09B6B3D4A17DCA35FABCA7B
-:10C7900058DE9459A542B9AECA287FD6665639E606
-:10C7A000A23F271DFD13793C6EAF4995F11EBFECEA
-:10C7B0009F82E5D37E3C43053EDA447AFD95B0BEC8
-:10C7C00055329ED71EA9ABC2EF79FE8FFDC09F7F69
-:10C7D000E367703FE63DEE84775FE5EF88282F86BC
-:10C7E00003FCE8B805ABC4A846AB1C535788907F40
-:10C7F000B889C92BFAE71D6B7A77B16365C50B1051
-:10C80000BFD3B8490EC2790EFCC9267950C47FF750
-:10C810005453D32DF2EA41EEC7D5030E8CC32B92AD
-:10C8200049C0FC7B989A2AF17729D83B668511ABE1
-:10C830007CCA6FB1BE63F39FD7EF7F0B008000000F
-:10C84000000000001F8B080000000000000BDD7DD1
-:10C850000D7854C5B9F09CB3677FB309BBC96EB2FC
-:10C860009BDF4D801024C006420C88BA090122A229
-:10C870002E880ADAE286DF00493670A962C5B22145
-:10C880001103450DB71181825DA85AB462438B1222
-:10C8900031E88A88F8157B43AFF6A2F67A17A48AA6
-:10C8A00080B06A45FB63F9E67D6766B3E7245168AB
-:10C8B000FBDC7ECF870F1EE69C397366DEFFBF99D7
-:10C8C000CD23CA89A889E09F8BF984289A764EA344
-:10C8D00069B052C4DBF4AFD16553B52DB664C787D8
-:10C8E00049F41F5EE2BDA82364D9EE65932DB439E7
-:10C8F000E917C503A2C584AC30A58C2003685FF896
-:10C90000732D21CDAB3AAE19A42764EB2A3A2EBD84
-:10C91000367F3D7A26292524966CF1ED900859B38F
-:10C920008A8E3FB8A7FF681BBD3986906D4A683A6A
-:10C9300071D06B58214D745EAF2C9709B497B94DE7
-:10C940006123EDB2EC8DFFBC6E08B497CA5EE2E9DC
-:10C95000795F7B7D72956B307CFF2D3A2718571FCE
-:10C9600090069F1C4DFFAD045CFE644206B625ACEC
-:10C970009FFECD6FA5ED84F5EAF57E9BCD4A48DE9E
-:10C98000B7C04DEF7CCB1E2886F1151C5F3B8F6F27
-:10C9900083EB1AA9B1880CA4573A57804FC829874E
-:10C9A0009FA0EBCC5E71EFB8936984641DB2B400B4
-:10C9B0005C49DBA384A413A2836FD3752B92CF436E
-:10C9C000281E5AF24BBC12BD1E7ED6C2E0946345AF
-:10C9D0003819246FC6F5F46A94FD36189FFEF1C12C
-:10C9E000F80FE458B6AFCB8766C00470C8DE4907BD
-:10C9F000CC84F6C0B53E85E289829B8CA37F43BF81
-:10CA00006BF5D175ED94E2ED6A6877840DBC3F89D2
-:10CA1000C0FF76CB127B4EC7575C84EC9224F63C69
-:10CA2000E4ADAECAA6FD15DB30C54B48D056DAAA38
-:10CA3000CF81E7B278DF47CAE9FAE07BBC0D70F935
-:10CA4000F941F1BCB2B56A101DDF40C4F821E8BF5E
-:10CA50005B9679FBAA56187F57A5787FF05A5F3608
-:10CA6000CEE77A9D9D90FBDA26B65ADD3DF37D68D0
-:10CA7000C3F5AD4D747D9F78A2297419A47EFBC9BE
-:10CA80007442875A3333E007380261FB8713724AD6
-:10CA9000F220BD08FCE9F75484B2E8ADF387FE9CB0
-:10CAA000524CAF415DF45012855F7D67C0A42FA04A
-:10CAB00070D6FB4259F93DEFD5EF994602946E824C
-:10CAC0005D2578EDE3BDC38AFC77BD67325CC2F7B4
-:10CAD0003E89FCB6E119FAA85E1768B50EC4FE845B
-:10CAE000E1BFEFF589F73F79E6B7B7C2F7CE79A294
-:10CAF000E953802E23142E7DBC27FA37745610A0DC
-:10CB00007B29C9B7DEE624641E853971027F357A38
-:10CB1000A17F87A9CDE6A5CFCDFA36BF97F6A7A806
-:10CB20000CCBE53DD7876D83703CED7D2DFF749870
-:10CB300048DA544AD7A13AC5FB0481762869046DC6
-:10CB4000AFAF574637D129AD2EF9DDA862683F67F0
-:10CB50002546DA6EAE3BE82A063EF21A08152F6427
-:10CB6000FDD80E37F0714BBD61E6E340BF9165AE75
-:10CB7000F9C53DE33F64D7E33CD6BE46F96C24BD1E
-:10CB8000EA3BEC12BC3F5821C087663BC5336D9B26
-:10CB9000DDA924940FFDACEB811FD7EA03D595D016
-:10CBA000CF2D9327E877CD83675457D279B89CB2BD
-:10CBB000A4C379541D5B409F37DB0C20D9C87BF69A
-:10CBC00039CF019C7EAE781B810F7F6EB5DA42F4BF
-:10CBD00001958D3EE05B65B0230C6DA38E3476D05D
-:10CBE000F96595107F87B5679EEF71F9F89ECD8046
-:10CBF000705E6FEE985641C7B12C936D21FABDB5AA
-:10CC0000F51BBB27D1EFFCB8FEF9A34DF4FEBA74B7
-:10CC100085C03CAC0E256248A1747C039D239DF722
-:10CC2000AE26BF0DE467CCA9901DF4B9659081785C
-:10CC300012E4A0B598B613E4539A43F199E9FB7F47
-:10CC4000B2078EC0FC47BFF99609DE778D9165600B
-:10CC50009B0E85E139A5543D8E6DBC7A9CD42AF596
-:10CC600073C754F5F3F419EAE7AEEFA8DB99F3D4F0
-:10CC7000ED5B80DEC640473AE732BA0EF68858A22E
-:10CC80009FAE2229089F7700FE9642D90BF031D73C
-:10CC90003F7E6A017D9E05F284CE9F8C20E127288D
-:10CCA0003E0FE47EDF13A57036A6367AECC5BDE1F3
-:10CCB000919563BA1EF0651DA4D808ED6FFDFDC700
-:10CCC0005FC3F85692D02F1FE0E3FBC43686B55DF4
-:10CCD000743EC9F00F0FC0BBF17FEE03BD7754E780
-:10CCE000057867D52BF8FD076778C2BA7CD69DD04A
-:10CCF000FE29BC7F8A697DB76E04BDFE7EED525D64
-:10CD00004A6FB8A6934609F892D207EA0B524350ED
-:10CD10005F3C20935AA01BCAAE04C6B3C10B54CECD
-:10CD2000F8530D0827C5CEE887FE4B86E7E936366F
-:10CD3000A6C13DCF0CFC7CFF2146FFF71BD838F184
-:10CD4000F13CF851544120276D765935CE461BEF02
-:10CD5000C3DB4E3B6BEF3E987A3DF0E5C619A9A3C5
-:10CD6000804E8C3209C07803B24DBEA1747DE63787
-:10CD70000C21890E3A402107F5A9B4BF85DCE9A74B
-:10CD8000F3D87CD812D2D1FBE6F9FF6EA34026255A
-:10CD90007CDEBB577BFF13E440AC4641389A9D6D67
-:10CDA000B651C56C0D213ABF54F807958F1583DB3A
-:10CDB0006D804F73451BEA6F73495B1BC069F35469
-:10CDC00019ED89D47932D2B339A7E3E8207A5F3FED
-:10CDD0005FB6C178A954B11BE8203FCA6EF3FB616E
-:10CDE0005C0A73B98C910A8C8B2BA4DF49E37075B4
-:10CDF00038F6DC2DD171D260BC11AC3FC0C9CEE198
-:10CE000034D6EE413E75F071D306D1FE23D8382DCD
-:10CE1000653DE3083C6EAE2661989FF8AE18273E4C
-:10CE20003EF1492057F5BFA670A37892724D38B9EC
-:10CE3000FB1793B0311FE0E36FDC8E7C6D253B80E8
-:10CE40005F1CD99540479987B74C9747C07B16FC24
-:10CE50008E7E3E09031D672AC4744D2AD82F7E8416
-:10CE6000A3965FDD07DB6EA63C12C78B967FDD0ABB
-:10CE700069D5A5F6E663B7C3515938A20F7ED6F03F
-:10CE80008BFB70EC7B40F45ABE7E2CE95C09C085BC
-:10CE900024F6D77D7B5BA7EB383A09909541F504E2
-:10CEA000057DAEE67B84FCCD086D89C89E8B034171
-:10CEB000EEDB391D537D459975F728DB042BF0E92E
-:10CEC0005282F455B977FDEDBFA6E35D186CB081D1
-:10CED0005EC939DCD60DFA91740686001EB62A8129
-:10CEE0009F24D1E75B8F651090DB6BCD6426D0B7B4
-:10CEF000C2E95CAB5F1E02BE71226B8465D7DF7F27
-:10CF000015F660C7A0F461361B8CFBFA6193F37FC2
-:10CF1000D1CE0A0D433B2BFB60779315BE6F9BDC94
-:10CF20006AA2F035BFC9FA3F48DBA14100BFBA3C55
-:10CF3000E0C303390B104ECABB4602743A5CE70BE0
-:10CF4000439BBC6726207F773EF79D5A0FC89FF40E
-:10CF5000291E90433F017EA7EBD9C6F95EBB7EC573
-:10CF6000E00B803DA1BDFF685C2EF94FD5503C0E13
-:10CF7000FFA981ACA30F8BE439ADF9C0176BA9FCF5
-:10CF8000A54FE7E83C0D3F947AF0D369AED86587AA
-:10CF9000EFAD32918091AEEB2B89042873E6387E99
-:10CFA0005B01F227974424D0B3B98DD4E005BA5A77
-:10CFB0006E2181047ACFFE4AC1FE9D66DF2E3B972B
-:10CFC000FF262A07F4EC9FE4E7A97E52E360320AC9
-:10CFD000EC17FD3396E3203788A3CA17F7370A808A
-:10CFE0007EA9DEA7DFDBC7D7ADA76A423F8AFEB5C1
-:10CFF000CA11E388DEFD5FE6FD14933502F252B1FB
-:10D000001E3986F2C5A69C4DEC670A337D43EA487B
-:10D0100078B0C4E082ED7FB3613B8BCA5FE328B494
-:10D02000FB434698670AF33F88CFE771A403BF101C
-:10D030000472B689B49A683FA476CA6F6ED26D4600
-:10D04000BBF920F1003F5088D9C13F845B00D7ADC8
-:10D05000845427F281B88EB4313E5056E8D05F1A1E
-:10D06000F6AA19E7A36F246133D84330370A6F65F6
-:10D0700039092BE06FAD3060BF91360FBE67208D50
-:10D0800068CFEEFAFAFD4C90D39643D41E1B097874
-:10D0900096514E592C6AFE23A409E1F409E7BF6DAD
-:10D0A000AB6C88E7B87F16788BE339DA04FA22771D
-:10D0B00079AA0ABFA25FF6575924303A71DC308E44
-:10D0C0009B3DE8A0448AE1792E3EDFB6CAF32DE30A
-:10D0D00017F433BE1BE9A8FFF1B3F1F9B6C85BF64C
-:10D0E0001B2928B6C60EDAFD9E1EFB5A0BE7ECE59F
-:10D0F0006AB93CB253DD167031EB7D8E6914E6E6F9
-:10D10000EFC9DEED74BC2B8FA9FB55E7BF8DFE6D1B
-:10D110004FFF88E366E84FFDEFED201D4EA9FBFBB6
-:10D120002B5EB3031FF7F467F3BBF62B753F2D7E21
-:10D13000B4F3A5F372DE9230AF0926A3EAF9CC9AD4
-:10D140005EF372DE9630AFC92E75FF4053DFF3BA3F
-:10D15000BEC8F88DF312FD6E2ABFB47EDA75DC5CB2
-:10D160006DEC07EEACFF6D332F6DDC3B6ABFB9DFB2
-:10D170009D2BB4DF0921BD5F2FF97CA9F43A076E1E
-:10D1800081BD68B5A0DDABA5975D5C7E4E067B8E4C
-:10D19000F69F95EC9B9C4ADB1305DF3DF5BBDB411D
-:10D1A000BE1C7EF68A0C90EB59A0E7109E2CAEB008
-:10D1B000BBCE857185EFF2FE549FB480BCD8BD9381
-:10D1C000BE97C2E695683FA5D531BFC24662C8CFBB
-:10D1D000C25E4A253689F9E3CCDEE9EF3BDAF1D7C6
-:10D1E00071FF73EE8A09E403CA87CF1B6C150AF836
-:10D1F000678F49680FCCADF2E992297D8C6B953031
-:10D200006E34F79E7F1B0D7265EC494F6794DE9F6D
-:10D210001BB67BE1B30DDDC417A67495A15B5A72F2
-:10D220001FBD3E7280DA3FBCBD14E8CDEAF380BF7B
-:10D23000510333A2E39CD53796D8406E7ED7EA03DC
-:10D24000B95933C3F70EAEF7AFD42AA1FDE6B3A5A3
-:10D2500093BDEDD30C1E6A67D47CC7530E764F4D39
-:10D2600087D9875713512C741D35D41E836B868143
-:10D270002866B85A8809AE65AB99FD9552EE37D449
-:10D28000D0EFD774FDEC0B786FA1127985D993613B
-:10D29000C45B4DD71B7F027B6DBECF6F0079316CB5
-:10D2A000A781D9A49C1E8677A8DB200F12DB25114D
-:10D2B000757BF46175FBC35406DF7D527818E06717
-:10D2C0001F5570E017877619515F1CD86F44FC2CEE
-:10D2D0003963D90EF1A7094BAC28D7CF3C6DC6787E
-:10D2E000D43EB9E35968879E4D42BFFA9577F795CA
-:10D2F00049B4BDF817C9323C7FF16B1DC21996A322
-:10D30000A7F7973C3B74FB3A7A7FC9E88E321BBD86
-:10D31000FFFC158474C373253C02D6F7FCDF743818
-:10D320007EEC29637807A587332FFCECD97BE9F7DE
-:10D33000CF3C95952A51BC5C05FA80F61BF75393B8
-:10D3400005FC8C71679E1908F262C94EA36A5D4F95
-:10D35000A7327B83223305E8ADBF78E289B53FC3AE
-:10D36000F78B4E1D437ADBA70FC91658FF5A465F4D
-:10D37000DAFEBB5399BE11F380F7F2297ECE7F6CA3
-:10D38000B913E2684336A9E13B34AC6EBF90CAF4EE
-:10D39000FB1C92703F1FC62B58E3023B753B417B41
-:10D3A000A6E8D4EF6FCF073BDAC8EC07ED3C0EA43C
-:10D3B00032BE7EFA693A0E930F3A663FD315537E1A
-:10D3C0005CC2E9F84589D9AFF4CFF22C4AB74B409B
-:10D3D000F117F4DC5FA2998718FF077C9D0EEE57CA
-:10D3E000C7DED4213E4EAFAA1D7D7270EFF97CB826
-:10D3F000AA716895BEA7BD60D3D2436EFA5EDD6E9A
-:10D4000027FA89E27EDD53AFA6DF41EF9FDDA978E1
-:10D41000C174AD9BF5E443E3A0DF53BA0E982F3CF3
-:10D42000F7D1F59EED782D05FA2DD86A1FA54BC0D2
-:10D43000C3C24DDF1B5A95200F2F971F04FFD671D3
-:10D44000FF766F79F7A42CA0EF4D9217BA2DE9B8AB
-:10D45000E5E61BC056D9AAF30EA6CFCB14E2D78DB2
-:10D4600042D77B065CEB763F7728933E0FEE1F5347
-:10D4700006EB5A27FBAF1F0EF4FF981EE3585AB86D
-:10D48000FC85E39BBE1F91E9FBEB6EB5D686AD38FC
-:10D49000EE41681F28DAA183387BCA292A9FD8FD6C
-:10D4A0006332E5C9535DF78F8078E23EBDB515E87C
-:10D4B0007C5F32C34368970EE53C89B0758CE3719D
-:10D4C000E325FFDD6E50E8F5D4A9D529158C8F50E2
-:10D4D000BE805076D0F5D5FE7438F2DDC24D6A3E7E
-:10D4E00011FDC47C1785D5CFB5F4919526E20DA426
-:10D4F0002891CEB4FDD2A6860CC057752BA83C4E01
-:10D50000B07FEA4EB619C06ED27E072C4022F0AA38
-:10D5100043FA241E5CAF99AD979AAC26BADED3F0DD
-:10D520002F16F796C02F5F2CE112C9922B489587D2
-:10D53000C273C974520DD77D52E4211D9767187FBD
-:10D54000DF9584F2ECAC2DFAE48F81FE9EC9F18662
-:10D55000E8A34C1E973BEB89A4A4D2EB79E00BA087
-:10D560003F1B6B2FEEA2F29CF2F7994F0C28D79B32
-:10D570003A5E4D017C9D7DD62CCB142F6776A75546
-:10D58000423CE76CC7AF53605DA73BD22A212ED740
-:10D590009FBCD1CA29A1CF8FC33FC7526598E6BBB4
-:10D5A0002A0DE4564B1A18E32423ADB1A4B10FFEA3
-:10D5B00017EF390C8D251E901BDFB57A77303811A7
-:10D5C0001F6D7F76386D07E05BC8A91A898D2FDE45
-:10D5D000BF318EC76F968FD5EB86621EE833E21996
-:10D5E00000F27A1A287AFADEE1570A0780BD20EEA7
-:10D5F000373AFD33D2E87D5765B74F0771C429C468
-:10D60000DB4CBB7EA0F3DE65A3F89A47A8FE826BD5
-:10D6100069C08071971627AE6FAE42220AA5F7B98E
-:10D62000A05F47601BF13577AB146EA6EB99B75E30
-:10D630000DAF05EDC61E3AA17F17112A608111B703
-:10D6400026F4A3E32F023D4AF1B0D844224974DC0A
-:10D65000C58FABDF5B4222389FBA672E1AFBC2C769
-:10D66000171C1F8D4E5F7D9A4A0EEA510E2E21FE29
-:10D670006BE0BB4B84BE7E8BE12B78CF3D43E75103
-:10D68000FBE3FC8A7B87CE4B837822F1811D41DA54
-:10D6900093918E975491480E9DD7922E29323CA596
-:10D6A000675CF24B89F96744C1F57FF116C3DFED82
-:10D6B000DCEE994F6F831D7115F8EF80EFCD12CE20
-:10D6C00063DC33522899FA49F34DD4C503F9C4D722
-:10D6D0000BFD07D0F6421242F83C9C968F785B44D3
-:10D6E000BA0D8C7FC2CDE9F4BB0DA7A84C2297429E
-:10D6F000076311DF9F132FE2FBDFE3745086F421F1
-:10D70000EE53FB8698537BBF0F78F325C0B976ABF9
-:10D71000BA4D1E4F6817005E683B015F0D7B2E1AE5
-:10D720007D7DE0E991B87E0B0F9D363C913F98FDE1
-:10D73000FC3EC7E323B72C70833C7A18ECC94C3EFF
-:10D740004039C86F22E22311131DDF329AA8E22567
-:10D75000D44EC3F62FD2FEEBBA4DD9846CD4073029
-:10D76000EF3057E73F0429B281E9815F01DDCF95B2
-:10D770007DB90AC2D557887EF30A460F8F8E6A1C80
-:10D78000DAD887BF2CE6BF51EA88C8209F5E60F6D2
-:10D790004672694C1F48E0F737D3981D33E040F4D8
-:10D7A0005016D0DF7312C6F7374BA445A2707651DE
-:10D7B0003C835EDA2C1D3F047A6CF3751ED24C9FBD
-:10D7C00097EE99B6F435F4B92D5EC897D4EFA9D089
-:10D7D000D55B71FDCCEE4D6ADC2ED3E71977168D43
-:10D7E000023EA3EBBE733ABDFFDB340FC2CD6D65C5
-:10D7F000F4E35A1DCA5F06F1DD03FEA5AF01DD0D9E
-:10D80000B7601C2D83C22A3915AFAD60CFBA4893DB
-:10D8100004FDD63825C4C79A1A32F397C548CDCA35
-:10D820008054763D46AF92425A202E9CA150FB98E0
-:10D83000DD6F81EF3C92C2E6E59475774E03FB7C89
-:10D84000146BA7AE947C3B508F6D403864184935FB
-:10D85000AC1BEE833D4FA7E1DB8DCFC338EF8C09C6
-:10D860008D25308F8C81ECEA3044B2619C23824E4E
-:10D87000BADC32E88DE55CFF2FDF5D91914ADF3F36
-:10D8800072D6A4803C3FE212F668C40AF628195406
-:10D89000C4FA733DBBBC64420630B52357DDEFBC10
-:10D8A000DE376034E8ABA33ACC1BFDD1EA1B60A79E
-:10D8B000FDAE32B07568F1AF7330BC06BF92483828
-:10D8C00021FE109C7901EDFCE0578AEAFED955262D
-:10D8D000124E883FD4D51E9804FDEA49F71AA0C716
-:10D8E000FA8E24124EE08FAB2C7D7F57F045F02B43
-:10D8F0001D098D46B2CF8638E9117D6CCD7CA0C361
-:10D90000FD12C6B382D4AF0F25CEEBAB34124AEB77
-:10D910006B9EE9EAFB743DAA76E797D88F9447534C
-:10D92000E03BE76CD1143B5F1FF413FAF77C580E11
-:10D93000E947629E92E96188335999FE9A06F85543
-:10D940006229D3937BC615CF61BCD484759E9B6935
-:10D950002011C44B0CBF0B700B0D21644BD7A706D5
-:10D960000FD8235DAF20DC04BD24C22F9498B76A82
-:10D97000EE8EC854565CDD9EB3AED84C517580CB4C
-:10D980008550DE3ADF78FA5C27ABE44452695C6E7E
-:10D99000A0987A04B2681857F5AC83386BBCCDFBFD
-:10D9A000C7DF0FE54FA9A2E39516B3F727B717FC1A
-:10D9B0009FD5A003491BD3CF4A2CD79F9CD0366953
-:10D9C000DA56DA1E9ED0B6699E3B34CF5D9A763623
-:10D9D000EB7F363992ABF31232BDBD708A42E5D689
-:10D9E00059776436F5A8C97ADDD02955B45D5FCA88
-:10D9F000F47A4397E44535C5E1D7E06576ABD51BAE
-:10DA000035CC2D0638741F02B952D729D924CA073C
-:10DA1000D68EDD116CC37B9E84F73A247CAFAEE3D7
-:10DA200038BED7EFF84532F2F9BAA213AC5FC74758
-:10DA3000683FAC69A9C1FCBEC85FEB88DF9725F5DC
-:10DA4000E4AF857C3DE7F6BD2A33BAB625FA7341CB
-:10DA50001837216E24FABF37BCEB6D304F92967F9A
-:10DA6000DA04F6F47FD77F3406ECCBF7B81ED9285A
-:10DA70008587C277B790C050D0A3DFAD1FFC8A4C1A
-:10DA8000FBBDAF8F6E831CDD86F66B107EEF2747E4
-:10DA900073242A637EE4B88EB59DD16D00CF8F1DAF
-:10DAA00053A628749CF773A239326D3FDABE9CB539
-:10DAB0000747B741FB654780F51F1ECDD1D9C0553B
-:10DAC000AB9952459F3F61EB9B9F5BB91C11F333B0
-:10DAD0000FF4353BC07EAC63FA671BB57F4D545ED7
-:10DAE000CE5E7C7AD713140EB3BF9F8472EC89B3D9
-:10DAF000374F61FE41C8AF9441FC97FD41FD8872EC
-:10DB00005E41FBC20D3A31B5071FC9B9DD1ED41FF6
-:10DB10005734EE06BB25637631EA8FB169BED3F088
-:10DB20005D71FD4526BB9E76D8985CD6C9980FCF0F
-:10DB3000B83719EDBA87CD6C3D946F10BF568E8FF4
-:10DB40006D0E66976E7330FF7649DAC4D30E7A7D18
-:10DB500057F26D3651B8BFAB272133C8D94516B43B
-:10DB600097EED84EE50695DBED7CDEED1BDC61C85B
-:10DB7000E7DF21113FC815213FDAED3E776A825F6A
-:10DB8000D45E42DBD61E3FB87D9ACF6D71C0355D45
-:10DB900086BC8F904BEDF9EC3DA18F329AD977324C
-:10DBA0001E1EBA03D691A4B0F8D5FC99853B9AD035
-:10DBB0001E988EF3253E9F1BE220271715C810D70D
-:10DBC00012F8B962A06F2FC0E5769E17107812F890
-:10DBD0003CCDD73D5747ED09BADEBF380308476A49
-:10DBE0005F8CE0F133B42F4E836E4F802F51A263D0
-:10DBF000E0FEFF4770FA3D3CFF47E154BF82CA0B8D
-:10DC0000F912E40587DF4629A2CF60F202FD79B858
-:10DC10000F7AA7332D1083F1C5F767DF5B8FF6A46A
-:10DC20009857D2DD7BAB6F23BDF94C6BEFFD19F03C
-:10DC3000E5ECB14BBD220ECABFF3FEBB26CC7BBCCC
-:10DC40006FE840B9F93EF5A39A40BEF0BC7DD9F724
-:10DC5000971C017F548C1B70EA70BCB592CF0DEB02
-:10DC60005B4BF16E82F94F33A0BF21F46ABB3DBC20
-:10DC700019EA26DA6FC9C6BA89F384D5A78456246F
-:10DC800061BFABE41304E2AAB1B136CC9B533AC1F5
-:10DC9000E7EDB30AB17E85D243C80CCF293D419D43
-:10DCA0005F7B095D108C37EB0A7C0EFE3AFAD9B324
-:10DCB0004C385E1F74C2E2D443587D467B3EA7C3F6
-:10DCC00045054887E9CD2C1E4A14DF8869097A7E0C
-:10DCD000BC93E139A934FADC7F01CDAF37A33D0B0A
-:10DCE0003A16734A6D19381EC5FF60278B4B209D6D
-:10DCF000CD7B2899D7C379CB00AE0F2433BADC6A29
-:10DD000066F9AEADD47E46B9C8E957D4E105B89DF1
-:10DD100017AD9553C05E18ED8CC73B7C107FC07863
-:10DD20003B7D3E272A1D07BF6F4E481731425CB826
-:10DD300075A22F9AE0BFC01FC817DEC9E52AD944D3
-:10DD4000D0BFBA13DE4B81F12D29901FBD13DE0722
-:10DD5000FF71E544551E7022C8F0313DF3D3CAFD72
-:10DD6000894E1EDF6C7BD497F81D31BE763CEAC726
-:10DD70004E723A11CE9101E04734E9108FDA7946BC
-:10DD800037B1B87974531ED29D18AFBF79FE8F2E6C
-:10DD9000F63D89EAC10513987F2FFC9EF9DCFF262A
-:10DDA0002BD57E1DC479E26D5DEFB6D64F84FCBEE7
-:10DDB000BA3FB35B928A6306CCFB7824D5FC05BCE2
-:10DDC000FA83439DC0E725C24DE8BD47CD549E521E
-:10DDD0007AD904759094BE36DD93847ACC61080FAD
-:10DDE00005BADA02F535A84F99FFFEF91175FC4521
-:10DDF0008BBF1FC4E9EAF2FCEE26C0B9B3B7DF1D42
-:10DE0000B4C41E03F8072D8C2FCFED4F46BE2283DE
-:10DE1000A2B3A1EEEDFC3E23017E6890A2852027EF
-:10DE2000CE49BE1AECD794E401FEFC406671812015
-:10DE30006084AE3318FA0BD65B053BD57EF839FA11
-:10DE4000B796F2CF39395A06E308F902F204EDAC7D
-:10DE50005A96876A904908FCB4ABE4398BD09E98F7
-:10DE6000954976E0FDE385E09709BD41FB1D94529D
-:10DE7000191902FFD5717C34C827B05F1DD44D013C
-:10DE80005EC05F83781F3C4C885337AC3F83755B23
-:10DE90000D7BD47453D74357D24509DE4BA033943E
-:10DEA0000B218423DAED2047AA581E3D99B793AA87
-:10DEB000BBB18E2BC8E32FCE03D149209F924B3BA1
-:10DEC000C81C7A0D9E6276CBB8AEEDAF825F6EAFA6
-:10DED000EECE01760AF278A7A01B31CFB15D1B749C
-:10DEE000E0370A7B27C16F1D3A5D15B7588DEF816A
-:10DEF0001F0CDF8BC22D379015D3931BB99E4C029C
-:10DF0000871AF469DB10D4A7A0EF40CE093F1AE4CA
-:10DF10001ED0D5C0F4CA23C0F72FA657BEEE74B2E8
-:10DF2000EFA17F00CED7D8FEE94EC047F4037FFAB9
-:10DF30009BE3905C7E13167F5CF686F31BE9FFFD86
-:10DF40004BA6FFA11940E7CB244F06D0F9F138FDCD
-:10DF50001762BE52DCFF5017C038A388772D82F8B5
-:10DF60001EBDD67139B480C7C71688B8D826755E6D
-:10DF700015E2D189EDC5224EB6D3D8536F04F2A372
-:10DF80008A4492E978F51067836B87FABD061263BD
-:10DF90007CD479D1A8CADBB63338DEC9E9C95E15AD
-:10DFA000D681FCDA6C66F13221D7C6ADDC8E7432D4
-:10DFB00060942FFF7EE09B37F4186FF903A70301ED
-:10DFC000974667E551C0A745C7E381F71B519E9F60
-:10DFD000A476C26E1EE7990EFEF1AAC050A897273C
-:10DFE0008A2D37D17F16D775FBCCB5687FA7CB2A92
-:10DFF0007A7DDEC9EA9B30FE85FA2209FD012ADE20
-:10E000004600BD9615087D4D4640DCEDB89EC5CD59
-:10E010001B6EB50660BCA8CCE4A13B9DE929773A0C
-:10E02000AB5714EDB8FFC9E951E443210E95988F21
-:10E03000F0C4FB6FE075C804D7BB7111AF778FF3E5
-:10E04000858CF22DA9D88F7AE12AB912E55BEC63B1
-:10E05000AB07E0527DA66E11ACE3B399160279C905
-:10E06000793C1EEE4DB7E3B8228E7DB9F1F0D1E9CF
-:10E07000717A54C5C3F771B9B88FB0F9865A8C2C30
-:10E080008FC1E7BFEFD41561CE1F21909BB1DD6634
-:10E09000A68FA99D0CF27ADF9E216158CF713DB306
-:10E0A0006742FB93F9FB81CD10A7D9F74BA717EA7D
-:10E0B000A0828B4F8F00FB76DFA9A77FF51BB8BF2F
-:10E0C000DFE8057F741FCF63D419228568CFF3FA88
-:10E0D000CFBA944821C4A55EE4F8AAB3D036BD7F78
-:10E0E00083293035DDD9936F84F7E0FE8930F31B47
-:10E0F0004E104607A1F52C2F4CE1EB8679C4D6666D
-:10E1000060BE12D60578F860FF709CF7463DEFFFC1
-:10E1100020B32F4FF0F689174AB01EF2BCDF80F50E
-:10E12000CBC187993D3B57F63CB60264EF4B49188B
-:10E13000079DDF7E14F347C187164E85E7C1C52BC7
-:10E140006F24DF9057013D9518C73F4762B9E8A794
-:10E15000D7167444E877CF750DF5B2F4A80B937118
-:10E160000DBC4EF624852FCC3BB65F8FF0BFD4F1AB
-:10E1700031A059C6F4257C279898BF42FDA2CE67EE
-:10E180007D5BFB9C3E5A780FFDFEDAD4C00FD213A4
-:10E19000ECD8E04B6E94A31F3CF8652EDA3B6D2C57
-:10E1A0006F7252EF9B0D7C62AF8A18E624C8D78D40
-:10E1B0009C8FE71AB95D4BE56022DF8BE765956AB6
-:10E1C0003E13D747D2995C4EE6F512BD9F8B7ABCC1
-:10E1D0009B8DA08F59C80BC6F5E0FD3C9EC71C77F0
-:10E1E0002AF60AD49DD57594609E346F6504F99221
-:10E1F000C23B02FEC9C9CDC94C9ED065C2380BCA0C
-:10E2000009DAD50B74ACFE638191DAE9CC2EC0FE3D
-:10E210001F6ECE403894AD66F669EC3909E5A2C8A8
-:10E22000E7D610F6FEDE96E3211DED5FB3532AA17B
-:10E23000A295D4B454607DC8E2ADF988FF715CFE4C
-:10E24000CE35FA0A3703BDED4D467AA3DF437FA0F2
-:10E250000E6AE046A15C32807EADDD29617E44AC71
-:10E260005F9B3F256175DE695C0793DFA03748A29D
-:10E27000DDC9F510E80BA2B16FD57411BA247DAADF
-:10E28000D50787E372F2F2F4E9AF417E8DE9AD4F35
-:10E29000A9BF70249DD10993FFBB59BEA99E34B27A
-:10E2A0007C1BD767F175717DF8A18EE9DF05C60D7E
-:10E2B000783D9E9E8FF35A4CA23CEF1433C0FCFA7B
-:10E2C000A3AFE3FDD097A0AB139CCEEA4E91C8D587
-:10E2D000F47B752B49A47E04BB268F40FDCEF4BC95
-:10E2E00089E979B85A2E41DF6BF5BC56AF6BF579E9
-:10E2F0008681E96D414F89F907B093C6AD0CEB58A3
-:10E300009C39DB86FBEB387E97A4F92E668EE9B14B
-:10E310000383C74C26CF4868FB498115E26715EB9C
-:10E32000B2212F40F500F06F1285D376888B71FFF4
-:10E33000E3EE6CB67E17AF93D22B7E5262053C752E
-:10E3400063BC20E624E8BF0BF86E4BA6EF8D82F786
-:10E35000185FC7DF3791164BC2FB95FBCCA8972EF1
-:10E36000BC908C753D54CFE4D9E978E9EF51BF8179
-:10E37000B6CFED4B463BE11CD71B0E1197216B101E
-:10E38000BFCE0C86E710A9CC82F83691A66481A88E
-:10E3900015F66CBDBDBF7C047F9EDF7D2BA33323B0
-:10E3A000EAEB0BF6E85DD0A6F3C13AECE40C36EFED
-:10E3B000E09E0925F742FD85DFEA65500D9480FD5A
-:10E3C00061D42DBF15E25E93742B63F7D075D4E74B
-:10E3D00058B1BEBB2AEFF7BF9B45DB1FEFD113231C
-:10E3E000E0FD899B0744E035C5E7EA8B4F1685F5CC
-:10E3F000AAFD834B76AADBF51DEA769024EC2FA4C8
-:10E400002058F1FB926B0E26D0495946B2E3C36106
-:10E41000C096C40BF5E944F79D01813EE4AEB87E99
-:10E42000B9CA7BCD413DD6F75D9DC1F8D900F6D183
-:10E430001CA0873EDEFB23E77BA3B1F114EC133075
-:10E44000BE68F436D1B7CC198149F07E831C3B04F9
-:10E45000F834E69D1D01FAB432EFAF9827BC701F67
-:10E46000F1027C2E982BD04EBAB0D9EC017FB13D91
-:10E47000D7CAE2322F496189F91553C750F95A8B2F
-:10E4800053A1EBDD74DDC76C530B31C9885FEA55CE
-:10E49000B9405EF9D0CFFB709AC5B69ABE57BB891A
-:10E4A000E9ED3AD29D0272E087803FA06BDD330632
-:10E4B00013FD677E8B6F68139DEF12BF05F733293D
-:10E4C0005F2B7EA0AF0760C804BF644E069307F5BC
-:10E4D000A6A8A102BEFFD779D5CE829E389E41CF95
-:10E4E000E2784A6749248BBEBA70C55CF4BFE2F992
-:10E4F000FACDAC8E6CE13D3578FFD5CD465CDF873B
-:10E50000FB25A4F30FB7B1F52FDC64F640BDFBB5D6
-:10E5100076E6BF2FA4EFF5BDFEC91FC3BA3EDA7A77
-:10E52000B717F2101F11F69D908DC5DB3EB2B1BA40
-:10E5300002E80BE37CB46720DA43B59B164DC5FABD
-:10E54000BE6D3A2FD823647F32C6B1166EFBDE6FE4
-:10E55000C6429C6CFAEDA500876BEDCBD3212E440F
-:10E56000FBF9C3CCBE6675D3A9E54F021F5EFBF570
-:10E5700084EE6BC1EEDA46F9249FED4B007BFFE0A1
-:10E58000B6C968DF2E9C66B1C3BA3C5B9F98047A1B
-:10E59000E8A3699932AE6797446C0007FB8A74B8A8
-:10E5A000BF5052FC7DD1537E860EE15A9167F546ED
-:10E5B000E0BDB775482794AF6E053D5CBF4D8FF643
-:10E5C000F3C1E9EFFE6E96A387AF16EADA6E1D97E8
-:10E5D000603F05B7DE20E88444CAC02F6330D1F223
-:10E5E00097316F6521CC47CB670B573716B2BCDC30
-:10E5F000E5F11BD9CAF8EDF10C89C56F2E9DDF7EC0
-:10E600007E39FC46B25355FAB7B75C0B613F91D7E0
-:10E61000307989EF092BE6AF7D1295BB6F6528F83D
-:10E62000FCAD0CBE8FEB4FCB76BE49E1332B23B054
-:10E630003F03EC28E22B013AF2C46C95B047CBCAF9
-:10E64000ED41B295D9DFE02700BE373AC993EB120E
-:10E65000E221DD196C1F21E5FF4330CEB977FE7A48
-:10E6600008F0D3907B7604CBEBFE11F3A0D62E9668
-:10E670003FB77A635857A077F891FE845C0F7A9978
-:10E68000DED1AE2BC3C5FCC2A02386E37CE6627C50
-:10E6900028F20A5B5658301EBCC51136B37847883D
-:10E6A000805E9A5AAE63F93F6EAFDDC0E3ACA6D28E
-:10E6B0005709E4FDC878566FF766E9AB4A1A6DFF53
-:10E6C000A67CA217F73996FEB4B500D63D5ECF9F63
-:10E6D0000F0CC1BAFFC35781CF97B9741EE0EBA9E5
-:10E6E000A5AC6E94D4A6601CE7CDD20F1CF312E645
-:10E6F000EF27268F95D2C974EA2C25D639DE38DE6D
-:10E70000ECB126D0D7676D5235B39B3D03660C67DD
-:10E71000711AD4C3A56A782C7319F0BB2FA6577C45
-:10E720000A70BEF61A868FD3BB8C61907FA7F9BEA4
-:10E73000A15E74E1E2F4F39D22551D82C3D0910BDA
-:10E74000FAF18CA47E6F71AB0EEB0016B54A244C27
-:10E75000BF77FAA9BDB920C73F7E626FEE9C84F9EE
-:10E7600068DF13578BF81E8F776AE3D7FDC5AD4579
-:10E77000BFF39B48C034B0A7FFF9DA3F63DC7A4EA1
-:10E78000178F7BFB7C831CE04FF1FEDAF146BB194F
-:10E790007D489D12C64D44DCF6C4E19F4286288E1A
-:10E7A0003F7357BE9C58272AAEE338DE6E06BCD1B5
-:10E7B000A5985B59BB3F7CF5C78FFFC1F58FC0DBC8
-:10E7C00089D68103008E8606AB42D8FEBD22B0F703
-:10E7D000B7118B17F8C990E9B282FC12E71F7C6968
-:10E7E000665787855EA9BD96935984EFDD2DFBB1F1
-:10E7F0001EF14BB90DF76FDEAD6BC43AF73217FB64
-:10E800005EB6CDBF7B01FA391D58F74E5AD5F04D93
-:10E810000728809EAA31A09E1270BE6ACE5DE8EFE6
-:10E82000F6819F4D403799E5EC5ED095CFEDE52818
-:10E83000E643CCE5C4067181E6B1219C8FC04F90C0
-:10E8400075275297847632D4EF24A562DE37C4AFA1
-:10E85000C49A4AE2799024EE1F134DDE838AAD10EC
-:10E86000F413F304310675400FDB3BDA0A59DE1866
-:10E87000ED4F1817EECF2956306F00FD0CA3BE9D4B
-:10E88000DEE274C9EB3BA78AFBB5963EF32C5361DD
-:10E890009F14ED9F43F520D87FC4AB57ED93DA4A20
-:10E8A000ED66F0EB441E5B277794B8D00FE98E42FB
-:10E8B0009CC55066F2805E4DD2751401DEB4796D50
-:10E8C000DA2F9FD55364DB41AF887D500D2B26F89E
-:10E8D000619F41DCCED8CFFCA3867B2AF0FE842E3C
-:10E8E000962708B61A711F67B053C2BC5C83DF104D
-:10E8F00036613CC4D304F80A513B0CFCCF763BABE9
-:10E90000036BBFCEE60D91C4B87AF4B17B31AE6E25
-:10E91000C57CE4DF9BA73D9F4C013032210F37C0FF
-:10E92000C4EB0D59DC3D9DD393C0BFE06791D74D3B
-:10E930002EF6E783C5FDE5C6D0AF2DCECBA87F214F
-:10E94000B73DF88DF52FE4A31BA0FEC504D63C7F90
-:10E950000ED3A27A33BEAFD1ECC1FC5DFC399C472B
-:10E9600061EA94F8FBED374C1C8475BBBC9E66D6FF
-:10E970007AA8C37FD84C54DF4B9C9FA2195F4FC726
-:10E98000B77A44FF7BAF9FA8601E9BB7DFFD21D401
-:10E99000FB3CAC578F872428F6619A7ABEB72E6B62
-:10E9A000C883EBC7F7E86FAACFF7BAC6F4E8F10758
-:10E9B000DE9DDA36D203FCF539D6410B7D1C74B0EE
-:10E9C0007A18ADDC3AE09284FD3B0954EC9A993513
-:10E9D000787E433C8FDD35CD07E758883C7670A5BF
-:10E9E0001FEBA141FFBB50FF9FFDF01580D2F4D378
-:10E9F00068FF07BF52585C89DA1112A543535705C7
-:10EA0000C64FA13C17F4A6C0FF62AE97C05607FAE6
-:10EA10000E6EBDED091D7D9EEBF6FD078ECBFD4014
-:10EA2000ED7C4FB9D8BE816051E5669007E47189ED
-:10EA300080DE5E57F419DA190D2F4C1C9358CFBFA6
-:10EA4000A8F311560FBE53DFE7FA4FB9983DDAF03D
-:10EA5000C27318173D1D66DB886A95F0DA71109F46
-:10EA6000A995C1D222A5E19A59A8FF67D275D075A0
-:10EA7000FD86DB25C19D3787607F4190FE05906D47
-:10EA8000F12F407B7FCB4C9315F248C1A2394B91BB
-:10EA90001F6C161FAC5F3BCF781EFC1E0BC62DD71C
-:10EAA00075EAABC16E2AA376D2AFE87C7352A75445
-:10EAB0007BA95CCAD2ED2EF9372BD40FF4AD87D7E2
-:10EAC00067323DDC22F943379562BD2749AC47CA1E
-:10EAD000EB64F6D84597411587BFE86276E2F850B7
-:10EAE000F704A0B997946812D8C541E2FB14FC5C06
-:10EAF000E2B77A601C380103EC2CC72A0FC6854D9B
-:10EB00008EE80F47A2DDA4A09F21FC88732FB038A8
-:10EB1000DA5277C0EA86F88E2EFAA39B006E3F6425
-:10EB2000FBAB89C2E44DEECDD65110F7323BA23F8C
-:10EB3000AAF6601D11C61F065CDD827878C9416C9B
-:10EB4000009F09A11A454AD033426E4C88EF637288
-:10EB500060BCB5928B97C1145B1F9A90445B2EA644
-:10EB6000F5D80587FF3A43819BC25E904D01F4675B
-:10EB7000AA6652FF10E8724DEC900CF17D4737DA2F
-:10EB80008BF51D127EA7BEE89758E7B784D793C5CB
-:10EB9000EBBA9428D6B915BA93785CAC85D103E961
-:10EBA00046FF973CC3E04FF526D6BFF5D8ED4DACF8
-:10EBB000EE888F67E079897A1EAFA180C2E7256E63
-:10EBC000116F5BCDF5AFA8D763DF258AA72C31BEC7
-:10EBD000B0711AD524382F4F0ACCB7D3EC1FE7A653
-:10EBE000EF9FA895595CBC35290C9B72374ADD3ED6
-:10EBF000885F864AFADE7F7413FFEE8003B149987E
-:10EC00003778A1BF7A6056FFBB79CC1558875FDA99
-:10EC1000F9E924A00F524D901FA9BCB8A47AE019BD
-:10EC2000800FE7FF43F5C05EC9B7835EE7BBEDEA3F
-:10EC30007A602FC397C8AB6AEB80CFB9230AABDBEE
-:10EC40008B3EF604E8DD4E23D6034EED7CFD18C462
-:10EC50002FA79A4807E69935F6C3C9B49B1B004F06
-:10EC6000E73FF9F0B1FB09D4913FEF65F5856A7B89
-:10EC7000A03FFB1F7323097E6248D0CD3FC9FE171A
-:10EC8000F23AC8FDA93352ECA14258DF7E9DADAFE8
-:10EC9000FD480FBA45DEB59F7A96AEBEEB5944DC0F
-:10ECA000B93A9AAFCA733D1AE783CBCB9B6D819C6F
-:10ECB000761F793385D7A92912131D24C7A0CA9BB3
-:10ECC00029F6C2FEF266117CFEDC107CFE40AFBC71
-:10ECD00019AB7768D99FE101FBBECE197BF2490FD2
-:10ECE0008C67C0715A5E480A433D7F0B877FDDA564
-:10ECF000E7CD7EE5EE236FB69DDB6F1F14C91103D0
-:10ED000085EB76C2E61FEA12F93319FDD8D88339AC
-:10ED100062FEF8FCFC83C3305E3457E4C55E62716A
-:10ED2000B4B93CFFF5C1F442AC67EB0FCE735BD5D1
-:10ED3000F985D7389C2F982B301E7FD7BF4FC3F84B
-:10ED4000D40288E30F84B8561B8FCBB3789EA79567
-:10ED50009D2BE0D929853D2C3F6392D136B4C970F3
-:10ED60007F0915A35B40F48628D55C496F4B146A74
-:10ED7000F4B9A785B6A9D1AFAC55422EDA6FFBB175
-:10ED8000248C9F3DE0F0E07C1F686179EAD07A290D
-:10ED90003C988D8BE7B5855A641F8CF30737D3F306
-:10EDA0005FBB0D7D9E0FD1A2E7F910FEBD26224765
-:10EDB000E02A4BECFA804DA9EECB7E10E3B5E81BC0
-:10EDC0004D1500EF1C762ECC05836F26C697530B8E
-:10EDD000F1FCA796E4C6D66AF61C79F68239E6C736
-:10EDE000E7572BCC20259E5498EF7B6E9E5FD3C0B7
-:10EDF000797E9BBAADCD1369F7BBCD258121EE811C
-:10EE0000BDF783BDC7F5DF8575F91C2F5ECC97B4C0
-:10EE1000E83DBFCD077A5FCBCE776ACA6670937341
-:10EE2000D8B5C05E85E7F0113BB7E3089B7FC1D53D
-:10EE30000E09F8A1C5CEE8F61F9DB776BEFACC4202
-:10EE4000065F3BE3D796B55298C18BCDFB52E322C8
-:10EE50000333FFB972F103C9FB64241FDF43B91008
-:10EE60007A508F7C778284B3587DA80DE5E61CEE3E
-:10EE7000E716677AF0FB5B6A0B52209F3AF7D41AC9
-:10EE80003CA769C2CD569C7FC34B66F4E3EA574664
-:10EE900073819EB57084D92A429ED2E7731C849DEB
-:10EEA000EFD3AACE0F6AF3BE6B53FDE3201FD450FD
-:10EEB000192D84BCD123F207BB5F67720DF56AC3BD
-:10EEC000CAD8931067FE6E6AA002FA9DBDE7DD49BD
-:10EED00092075F47F9767EFF10DCD739A745BDBFA3
-:10EEE0008DAC57E71F496B2AC6D549BBFA3EECC328
-:10EEF00052BDD72B1FC9EC9A8D86C050B03BAFBD19
-:10EF000086D55B7CB2482680CF4FCC84E7F9859CC0
-:10EF1000F51626EA81D9FDE295F60338F3FA57D1C2
-:10EF2000BF1EF04AF159C7F1FAC9735716025ECFF6
-:10EF3000EEBEB210F0BA51DFE603BE18981E980379
-:10EF4000F03839D18F76A1A8F7BD547A5B9AC9F50C
-:10EF5000E0BF480FFF407CFF32F530FC498C97BC86
-:10EF6000F45756971BEA62FB827BE274A7F17CB3ED
-:10EF7000F35FC912C8E1FEC6B371FBCE652221B0B2
-:10EF8000BFCA2AA3F85ED99F650276A0B07FB5F309
-:10EF9000DFC0F1BA23D377C105F8E571DD5A3EB67B
-:10EFA00029FC39B3B31F97306E6BF28452C6A15F50
-:10EFB000357FB40EE5CAAF70BF07E9926CE09F2CB5
-:10EFC0007ABC099F9FEB9C8BCF655324027E583DF2
-:10EFD0007D0EED35E3D5F5DBFA3D259144BF97CEA7
-:10EFE000E333F04B931C3103D06703D8D5748A0DFB
-:10EFF0000A8B6F373808C6554A3BD57EA2C8DB6EF0
-:10F00000F1B3F373B67449788E56BA21909F0D7898
-:10F01000D5E46F7F91E93B96E9ECC9BF373A7DBBF8
-:10F02000810E1D06928BF57A7AB11F51BD8FB3BF49
-:10F030003AB897057F7CABFD340BEDA42F881FED0C
-:10F04000A403107BC0BCFDAD685789FBBDEBE0C2DB
-:10F05000AA7CFD02BEDF7601DF6F0BF23EA291F7C4
-:10F0600089EDBA843AB8485FF50C09757089EF25C7
-:10F07000D6C1455472B28DEF07598679F220E59BCF
-:10F0800015A37AE8BA8EF03F9B621FE07EA09D46F2
-:10F090008CCFD5F1FADC60ED09F47B82B0BF88F14A
-:10F0A00037AB63E7E755D4517F12EB943BD475BC83
-:10F0B000E7FFC9FA45F4EB2FEEFE670D7F8B7589EC
-:10F0C00075D475498C1F35F3D4FAD1DAF8B9F083C9
-:10F0D0002F55CEA564FD6BE55C5696A0EF7F4CCE18
-:10F0E000F5CA430C8AA578FF0979888F3D6DE91030
-:10F0F0009A6C9518BD4ED2597D2CCFA9637510DA44
-:10F10000FCAF6712E63545DCD7F4BC2EBC3A1FFBDA
-:10F11000635EB77E7F32D625D47A6AD16ED7E63B5E
-:10F120001793DD9300055F9023B88FED1FAD2FA8D7
-:10F13000CC8AD717E45F667DC175599791EF7CD56E
-:10F14000FA795A20814E2A8BA90350DC7F1DD96D94
-:10F150009CEE92781D8A4909117BC2FBFDBD776741
-:10F16000168B1FBECAEB9F1E4E4EC2F3175C06B62F
-:10F170006FC325B33AAD5CB7BF266B0CE81586C7E5
-:10F180009FBC701B81BAC79FE83BF03C8450BDD543
-:10F190000BFA50C4ADC4F8BFE2F1D44BE59FBBFEFF
-:10F1A000C9FCF36D722324BE77A9F9BA4D14060980
-:10F1B0007CA5E583FEDEEB4FAE6CC8F2AFCF42B963
-:10F1C000E51B81798F4B944749A5545E83BEDF636D
-:10F1D000F480FF61E2FB8BC87AB7CA7F9FFB700E99
-:10F1E000EAC34FCCCC1F11FBA0C4FA1FEF17DE7F80
-:10F1F0009FBDF817A7FF4958CFC90A1FEE7B78209B
-:10F2000099E995D853ACCE48BB1F48AB4FC47E1686
-:10F21000F1BD4E21CFFE45F2F4B57F923CA5FA1523
-:10F22000ED8D7EF3BABDDE0FE177CB2ABB7D3CDFEF
-:10F2300085FB39C4BC82DDAC3EEF6D8E3F71FF595A
-:10F24000AE7733B37DBF033C9C7DC764823C6A6963
-:10F2500029939F0D7E2BE6211A3A585D4EC34A82B0
-:10F260007103B1EF775646200A72EA8177AD787E56
-:10F270006C43E7F6D602AC5708A09D78EE1D76DF0A
-:10F280009C113809E307574655F98EB28B9FAFA9F9
-:10F290002EC5F9A2DFEF30AAF75319B2993F2FAE6E
-:10F2A000BA6CA1B7A99F43DF3B5BCBEACA830E9F31
-:10F2B000AD02EB14583C3DC9D38D71F0863DA824B6
-:10F2C0000816B9C2F37BB3916E1AF65494E0F90BA9
-:10F2D0001DE6123C47E83D2BFA6B67EFC90C433C37
-:10F2E0007BA93BF017986F7269F83AB057F3E8774B
-:10F2F000209E7E76F77525185FD4F09DE0B7F83E26
-:10F30000DA3B4CE166A9871F37EA997E147AED0C47
-:10F3100018C74ECC7BB03AC3AE6964BEB5A76D7555
-:10F32000A8EB2F77644E3C03703E93A5F03C39CB9D
-:10F33000CBE79BA8375BD09B0EF3795E7E1AAFA715
-:10F340002021534F1D45C1B7E7E5C5FC445BE4E50B
-:10F3500093BE62767381CD807491DCCAE406A17499
-:10F3600001F6FAF858F704D8BF36A83D321EE0354A
-:10F3700000C00F312E12FDE148C87FA429E321FF10
-:10F38000F1D88A51074C0E8847755F0DA8F1B4D9A2
-:10F390002AC1559D95E12F82FA4AA2341601FD57E4
-:10F3A000BEAD67758F6B9350DFB7E7D661DDE3B90C
-:10F3B000778DAA7D46BDE43459ED82B85341EB7F89
-:10F3C00062FE21798FD4673DEB427022C6B0FE10F9
-:10F3D000C74A6EED0E95435CE641899DC149672F92
-:10F3E000B9209EA0C86077CCED64FBDFE7B6D92BCF
-:10F3F0004D284F2596BF19EF4039A9ACBD5E067F59
-:10F400004F692278DEDDEC6C76DEEDE0769B0C78E1
-:10F410007FF96B5D9F79B91BB27BEAE8005CF5C6AA
-:10F42000D821281D10F944513F27FCABB87CE5E7F3
-:10F43000C20B7DA4B5637BD9AF5C1FC5ED780D1DF4
-:10F44000F7F79EA06F41CF2FEB09DA612F4B26DC37
-:10F45000C726E8BA45EC2BF89AC585F3787DCE89A6
-:10F46000757F19C1CE8114F99830ABABD247D76400
-:10F4700021BCA2D78460DD7BEC724331C6D31A7005
-:10F480009CB5ECDCBABCD681ABCB4BE16A230082E5
-:10F4900013FB96E4015F86281D0CEE830E8AB35998
-:10F4A0001D94B23609F1A66CC013BA89624F47BCED
-:10F4B000298F30FC1466333A17F96011F7CCCC0E63
-:10F4C000ACCC1E93B0FF6C8585ED3FE3FBA4935756
-:10F4D000BCBB0BF6753DC6E3CF075E1A86BF9F71B6
-:10F4E00061AD22411CEA82BD260FFCBD07385E9348
-:10F4F000956E62B326D2E701ACBF2DD8CFEA0815CE
-:10F500007E0E96B2D6B11DE039362D8075C657B73E
-:10F5100044F0A7275EB29DC43C1FB58B70DFF8E9AD
-:10F5200017246117A9F4A1F0D7B47ED88FB3FF7761
-:10F53000FDAB27E372FA32FD2BA2F633E3FD85DF44
-:10F54000A8F52334EFF767FF105F485567F302C74C
-:10F55000BBD0EF995C368AFA9BF8BE6F1236C3FEB9
-:10F560008CC9504BCBD68375489B248B17EC246DEC
-:10F57000FD51BC2E88340E6175298D23D9791E8DDD
-:10F5800057C255D42799A13E25B10E3699D5179962
-:10F59000A13E85DE6FEE779FB8A709BEDF7E9F4D47
-:10F5A000EC136771FB6AC2F3163B701F79EC966C23
-:10F5B000DCF733A19AC50353FD0619E8F2F9BFE958
-:10F5C0007C207763946FC1BE4A1DE47383BD65A63A
-:10F5D000CFA1EE25BE4FBC86F4B94F5CD447897CE1
-:10F5E00071E6908D12E89F78DD4AB067FF387CB7EE
-:10F5F0007DA907E3CDF13AAAEF125C67A590332607
-:10F6000035FE527CAC5FCA4C03DA19E972E029CCB2
-:10F610000B6EE936037FEECE2E40BC359787F11C8A
-:10F62000E4D4E2368CE786D37CE7B29D3DF423E652
-:10F630004736B1F59F87FD6752CF77CF2FFA732EEC
-:10F64000D853955D4646879A796C899F5343BF434B
-:10F65000AFBA1C867FAFC6BE15575D8EA4AAE31352
-:10F66000DFEF6F9D821EBFCD6ED7D257A892E3E722
-:10F670007D7398D53FA9E9EBC0AAEAD127A92C3917
-:10F68000B8CA8FD7F366A94307754AE6D86C90804D
-:10F690006FE6B4DD08E7999C4F8EE5C2F9276FE766
-:10F6A000DE7513B69DB1F7A17D2AE769D61E1C7BD6
-:10F6B0000CCE43F95BCE889BE0BC93F3F0AD4C429B
-:10F6C000B2B615DC142A867D26D135DDA09F4A35D9
-:10F6D000F52E9A731BA02E13CF99B0327C66F0BA28
-:10F6E0005852C5ED77C854D176B3BBC40BF50C5650
-:10F6F000E2D9D30DCFB38DEC7C07C2EAB09A07E70D
-:10F70000B3BA094EEF249BC7B3493404F4DB9C6FB2
-:10F71000C7F7E3F27A8F91E7B1D8F78F3EC7F6BD0E
-:10F72000897A5F426C3960F7583D44D516E79E10E0
-:10F73000C59603E71C348B78216FFFC112B83A27B6
-:10F7400041FF1E9D787731FE8ECBF3F70E82F54E8A
-:10F7500036A8CFC116D79772197D9CE7E7456EB3DF
-:10F760000426C138C792664F82237867A65518ECE5
-:10F7700068A73DA50379E4E474619FC1E667AFF231
-:10F780004BF0FB29E2BC466740C1780009B4EB406E
-:10F790007F3A4FFAB1AEB0CE14CB55287D194D81CA
-:10F7A000E9399057AC397E17E615338FBE0F7520B7
-:10F7B00047F56D1352405FE4F3F333A8E317A2ED6E
-:10F7C000435979E8F7C5CF771D2CA17C983A83ED92
-:10F7D000A79D423A148CBFD8D8FEAE49A5F9DE6683
-:10F7E000FABDA9BC8E64D2317F0AC40126DD16554C
-:10F7F00058FE26A624D66D882B71E93D897C709D24
-:10F8000027A14DE05C6875FB06AFBA7D53F9D7437D
-:10F8100012DB0388AF1EE0F8A214C5FDD6A1B1C467
-:10F82000C6D6C5EA139FE67EDB301731E541FDA45D
-:10F83000430A815F306C6F26E665F696136CA7EF7E
-:10F8400034ED3025AE7F83CCF2BE3C6E2E7EFF09B8
-:10F850009E815E7DFE9D748457BA5546790A117566
-:10F86000A0B7B22C9305E4BB8ECB79B13F7D628A01
-:10F8700009CFED6D5ECA7E37427B6E69B3DEF60A54
-:10F88000E0B1F96338928AFAD9C986889C02F8A255
-:10F89000BE8FA3471E0BFA81F1AE01BA1FC37E9F34
-:10F8A0008B52F9A0C473E39B9D6CAECDF7293CDF6E
-:10F8B000C77E27A428FEBB2194ED687FB02909F2FA
-:10F8C00009CBB7E5887512C507FDDD44B4D97EAF15
-:10F8D00074DE16E7A51252A1E0F94492E8D784ED50
-:10F8E00047793FA9EBF53F017D0C4AA1EBA1D7D7A2
-:10F8F000723C48DC3F958F6E423AB1063C4027DEB1
-:10F90000A4BEF71F75E4303B62624AB90BE2EBCD4F
-:10F910006EAF0BEC2A011F715F8C2B9E8BEF79D39E
-:10F92000FA1EF7352EAF3BF83E68EDF3977364F59A
-:10F9300077F5745CEB377CD7A9FE6EFCBD9CBEDF0F
-:10F9400013F7457FFC59AF32E03306B729BC6E96FA
-:10F9500014A9EB5D48B9D7C4E4BDBABE65B2B4D250
-:10F960000DFC799DA9BE2B4ADF7F9DD3C96439F078
-:10F9700047C837BC3EBBF020F06735FC30011DE7BF
-:10F980007A125903C472BE22F013FB409417C78049
-:10F990008F1A748121A9B4FD89BE6DD0D27CE4AFE9
-:10F9A0007772C6F49E9FA0C3F83C29FD01DE05FDD9
-:10F9B00069E72DE880DCD8810582DB4804AF2EC2E0
-:10F9C000EAB2A9FE62F5D79E9C9E7551E29C646ADC
-:10F9D0001C04FAFDF5A610CA9FC9F61F611DDAF9CD
-:10F9E000BCC03998D7CC919FE2F942C45583F61632
-:10F9F0009DEFF97FE57CA18208EE0B3B50D87BBDE3
-:10FA0000EA913F36A8EA91C5FCB47C2CE61124ECBF
-:10FA1000DCA8095DDBD1BE0BCEB07A61DF4810EA0D
-:10FA20006C4B319F8675CBFBB85F169258FD702FDB
-:10FA30007BB1FFBA65764E41BD8D9D1F24CEA1FAE4
-:10FA40005E81385F88CD9BCA2F7EBE10B6DB6B3CD3
-:10FA5000E8FFC5EDC6F9CC0EBDB6D0D202E735F64B
-:10FA60003E6788C5F7C85EA387DB89A8BFDB93D94B
-:10FA7000773E31B33AF904394EA4F49EF3CF36EA17
-:10FA8000993DE8CDCD677941D95B06F8D802792B4D
-:10FA90005DEF38E4C0F4C0E85CDA6F7EB12F177E0A
-:10FAA0009A65AE81C519295D6DED26506ED7F8387F
-:10FAB0009C0B7A1D697C4B1E88743516FACF1CF698
-:10FAC000293B2FB487AEC6E53A99DC0421F86D7C5A
-:10FAD0007A322D3001C669B777BCD7500A794B23EB
-:10FAE000C25FD4336AF937613E27F56C3E0E381F8A
-:10FAF00099CEE7FABEE67329F49D48471984D1717F
-:10FB00007F740EFB069247F5D0F90012B81DBE1B9C
-:10FB1000A7F735DE56DDC03EE6ADB322DE6F9DC5EC
-:10FB2000F231C12466A7425EC69D0EF127F6FD5B49
-:10FB3000D732FAB8D56C447A99D6558FF91752C591
-:10FB4000F2295EFA1FCC6726F14D849F58B9D93649
-:10FB50000DF781CE98AACEB7CC344DC6FCCE2D84FD
-:10FB6000C5D36E9DA157FD7EA480C34CB2FE53A8A1
-:10FB70000F99A9F9DD482D5CB4F91A018FE6F26FEF
-:10FB8000E6FBFB72E3799D219799D769C945F97422
-:10FB900069799D83FA189E23F09A73E1D6A5942F74
-:10FBA00086FCB818CF5B9F98BEE8F10DB4FDB32D6D
-:10FBB0005760FBB5F43B961F85E78F1562BB4AFE85
-:10FBC0007436F04151D9AC29704EFD41331BC765E5
-:10FBD00009B4C3EF8EB846148C0297ACCA10C37E2A
-:10FBE000D78FAC1F0D75355516D63E52F25FA3B0B8
-:10FBF0005DC0DBA35EBC02DA07A54F67F795171A55
-:10FC0000562445E0F7C5AA5259FFA9A39ECA8438D5
-:10FC10004155256B0FF356AC1D08CFE5CF66F7A510
-:10FC20008F7FC9ED63616FF939BFEFF51D6F81FDFE
-:10FC3000667EABE4857D06FEF2E3EC5C3113AB4BF4
-:10FC4000F0FB4A143877B2D2C7E27B13AC4D6E900A
-:10FC50007F37060CA510C7B559F35BE07CE701E5DB
-:10FC6000156300DF13A81906FA8FF2D5F3C0CF335E
-:10FC7000AFFC343705ED10355F09BA9D26F8A94A67
-:10FC8000CD37541E74313CAAF9818EFB0A8E7B95C8
-:10FC90005A2FC5E5BB866FB5F4D8AFDE276A391891
-:10FCA000D74F6B3A902EB309DB4FB40DE894F1EFC8
-:10FCB0006F617E06B9DB03F7F324EF1558A8D18FE7
-:10FCC000FD20E607660F19D57B5EF04711F6229BF3
-:10FCD00081CD960EDF65CFE97B3EF83138312FFAC2
-:10FCE000FD13089F356C3EDBA446FEFB22CC2E178D
-:10FCF0007E6F83586FA77ABD6516B62FDE45A8DCE8
-:10FD0000C1D87DC915DF34EF20D7B3334CFE078D42
-:10FD100032FC4EE15CC4F36D24F41CD837EF58027A
-:10FD20007F84F9E8E4D0FEA804BF0FE2C37C32C5AB
-:10FD3000E3174CAE33BC887969E1D1D08F5CD5CE66
-:10FD40005B0B871EFC74A37DE6E6BF23185F9766F6
-:10FD50003DCDFC770462254655DDE9911A56572BB7
-:10FD6000E675442245A827250BE651E37127AD7CB3
-:10FD7000EB677F9CD0CF629E77F3FD595FCA4CEE54
-:10FD8000DDAD8BE03CF3AABBCD00C7F2BC02763EF2
-:10FD9000109F7F737908FB1964A9CF3C71799E2C61
-:10FDA000F260A4CF73DC3CF956E08B3B4DFCDC3AAF
-:10FDB0000D5D104DFEAC3F3A11F1BB4AEEB7C4F3F6
-:10FDC000A99A73E2E698FACE9B4914BE59A9BDF1EF
-:10FDD00020F2693768E374D7B1F8D50D3C4E37A1EE
-:10FDE0009AE127754532FA75A9A5471532BCE73C5B
-:10FDF0006B81AF0B8E40551EE635A263208EF0E678
-:10FE0000989F611E499C1BA9859F3F4F16F1C64BC9
-:10FE1000E297FEE6FF078B7F3A7CF713A91BCF839F
-:10FE20001BEDE6E79192403EF093DD965F01F1070E
-:10FE30002A772F5E0467141E51FCEE74066E87F756
-:10FE40006E23FE8950EB9D5A1DD0B3F83DC1F8F1E9
-:10FE500032EE474EE4FAFFB367D87EFD2ADFD04783
-:10FE6000C7837D7A584FC21EA81B67F0F96CAB0E92
-:10FE7000F5FEC23746BBC07EFF80D3E3904DB2EAA9
-:10FE8000770887862DAA733D86ED4C55B587776434
-:10FE9000AAFA8FEC2C503D2F895CA17A3EFAF0280B
-:10FEA000557B4CF73855FF2B8F55AADA63A3535473
-:10FEB000FDAF3A355DD5BE3A76BBFA5C9290AFBBEA
-:10FEC000281D7E3F81C1E3DAAFE6A8FA9F49997405
-:10FED00018F872DE7A56275E4196A8DE5FA2ABC3A1
-:10FEE000FA6BD2C6EC9C46FA1FDF17AF607D1AB5DD
-:10FEF000EFE1A701166E52DB41B55D1BD6802CEEFB
-:10FF0000751E86C6DED1DA37431C35706C3679240F
-:10FF10008FFFAEF895E44AFEBB345ABCE2F9029F6B
-:10FF2000BDA5433F63D91BCCFE5FB68BD5DF1592D1
-:10FF3000C10370DFD9611D094B70CE42E3C6F15297
-:10FF40008F9DA3858BD1A5C6B3D9A3C67352911A31
-:10FF5000CFC95E359E0794ABF16CF7A9F19C56AD05
-:10FF6000C6B3D3AFC673C64C359EDD01359EB36AAA
-:10FF7000D578CE6954E3396F851AAFF9A1C5AAE7E0
-:10FF800042AE0E6C5DA6BADF2C759451494AE6F973
-:10FF90006BF17C89C16DDFEF933E04FE43F43FC6F5
-:10FFA000CF8D58CFBF80E21FEAF9BF20EB0F414A47
-:10FFB000564B070D9D1B30EF76B974F0761EB75F78
-:10FFC00005FE2FD17EA5FAF2BDBC3168E7BC0FF269
-:10FFD00061E610EE97F8FBB67384DC4AB42B12FD91
-:10FFE000EEFEE4592F3DCAFDF07EF5A8C60F7F074F
-:10FFF000AA9FD05E5F8F71AF599CAE3F875B632134
-:020000022000DC
-:10000000EEFA2CDA07EFD08994D379BD03F31E0101
-:1000100076C2308C93DC41227A3C3F1C2A4675A87C
-:10002000BFB04EB386DAED709DCBED87F93C8E62A2
-:10003000340588C789F193BC74F86E7637EE33FBCC
-:10004000BF17F44F2B008000000000001F8B08003A
-:1000500000000000000BE57D097C94D5B5F8FDE6B5
-:100060009B2DC92499241012026126210B908449EA
-:100070005804451C9660D4806193C58833498090AC
-:100080008504D0D7B4A5CD40C2A28536B4A8A8A80F
-:100090000302050B345804D4688745A44F5B636B97
-:1000A000AD4BCB4B0045F618B4D23EDFF37FCEB953
-:1000B000F766E6FB480AF6BDF7FBF5F7FBE3EBBB9B
-:1000C000B9DFDDCF76CF3DE7DC3BECED38C612196A
-:1000D000FB06FFDD717DCA988FB1DE8CFD01FF84C8
-:1000E0007A231C455607E4275A1D0F3D069F8E189C
-:1000F0005879B30DFE28847E46436A2CCA9E96DD4D
-:100100005D3F2BA13163AF2A1E0F1B0EBD265A5D2A
-:10011000DB15C68624316B622C1427F853A64532B2
-:10012000D6C761A07AF04F61F18C0DB6D2DF6C4F6B
-:10013000DFE6A531A9F8973FB628FBDB8F9BEA7075
-:10014000273B4604EBDF68BD6673F3129C6747B537
-:10015000CDB5D5C9D87B5804ED9EBFCF1250A3189A
-:10016000BB62B2AD55A219FB2062DEF1DE0EC69E67
-:1001700009F764215C66CFBA6B35E69523718EA5CD
-:1001800030BF2BDEB6910CE66DB17A5C585E65F53A
-:100190000C8887255EEAEFC98856A1CF220E7FF82A
-:1001A00023BBA8DBF9F3F94C50F8F89F847B46E3B6
-:1001B0003A8E185A935D080F63EB486CC76CBDA963
-:1001C0009F4B660E979EE0303EA27F31AEABCC6275
-:1001D00071A9D0E77885E3F54CDC83F36AE0CFF9C9
-:1001E00086A2F880AA99F79D346FBB7740620AF423
-:1001F0006F12F3B6F6167077641545F63CEF06EC11
-:10020000BF17E47EA0F8B73B392E317FD017E37FCC
-:1002100014F216C3D5F7A643BE23DBE0DA0A459BEA
-:10022000C3A1EB3CC6DE11F07EC604F958FABE1637
-:10023000BF2784F3F6098F1BFC0DD0BE68FCCB846E
-:10024000A7E717DB683D5EE63033985F29739B7143
-:10025000FE9F8CFBCFD7DA001FF31D1E0FC2EDC12E
-:100260003843F27B340FCF90A9306F36E6E6E89F33
-:10027000B175063692B16976BE84F9026ED399DB08
-:1002800084E3CC641E138EFBFBCB663703FAF83D88
-:10029000E098C17C67311F7D9FC3FC94DECF025480
-:1002A000FF01D646F9772372FAD7C1FCA63E919199
-:1002B000C60C1AB8FF1BCE17E8E5C15E9C5ECEF6F1
-:1002C00041B86FEC7D53F43B55D00BF0EB0FB11FF1
-:1002D000E0D7E1B929217C3391D30B33DAD3FE1176
-:1002E000DFB47646E5B0A19877DB1261FD770A149A
-:1002F000DEE9AE2CC475E6AB36D60BE0DFEA50FD86
-:100300001618B3609CB72FAE0BFE45FA004F53DCB6
-:100310002A433CBFB902BE40BD3773553FD2C49497
-:100320004D93CE61FBC271D31BA361FD93BE6E1BC7
-:100330001E80B4A09FE9545B261FE31BF8DF976C77
-:10034000F3C41848EF4ED8676430FFBB076ACB0B85
-:10035000B3206F0DE6A73063B01CC63D8C7000FA69
-:10036000A9FB73EED86321ED186B52916FB63A2258
-:100370007B7D3A04B283D9E06F70DE6A71B4A71B4B
-:10038000FE91E957F5AEB1C78026EF51DCBB1C44A6
-:10039000170E33D27F8991B9BBE3BB8B698AA01F4B
-:1003A000C02EC8B37BC55C3B0BAF9AAFC07ADB1CD9
-:1003B0009EFDD8CFD2C99FCCC3F53123FBED308051
-:1003C000DBE2DF01DCA0FC543D403E03F8B3DECAB3
-:1003D000DC16C63EADB753FEB3FA044ACFD73B286E
-:1003E000BD589F49E597EB5D9467CEA2D7B0DF92E9
-:1003F000B59F1B3D598CAD099378E4F35826E878F6
-:100400004DFF917F72C1786BDE3651BEBCB9695227
-:1004100004A4CBFA9F5A1901DF97ED525CF8BDB2E4
-:10042000C56DB6211F1DF3AC46F259F876DB1414E6
-:100430003BD5D714E601169A3DB0E82D1C6FC41FBA
-:10044000CFC423FCCED68FA2F99CAB77D37CDC2D16
-:10045000EDC7E3A0FD85FA02CA273A8BDE45BA74E0
-:10046000B3CFCD587FF2EE76631294E7BB1537F227
-:10047000F75837F3FB017F9B4C7CBFD804FB05F298
-:10048000FBB8EC69CF3CC4509E7B3EC6F166C69675
-:10049000E6C7C1F729A3BC46AC37EB6BC6302FE9E2
-:1004A000FBC67CCDE1512DF072E97585E074E9C0A1
-:1004B000907B6F83FE5E3FA13215E6D579CD40F388
-:1004C000EAFC20DC0F3B5357BDA52FA5F661364C47
-:1004D00087F46159B83EE804D69DA9180D75C0FF90
-:1004E00017F67C2701E12FC7BD10DBFCD78F50DE4C
-:1004F000FD85CB3BC69A3F7D0AE561BF04D7A3903B
-:10050000BB6C62B3893F596D04EE878BCDCCC3F3CE
-:100510009E2198BF10CE1E2C82FCC8BD49E3917F5E
-:10052000703C4746509EA5EF7D22E5FB8EE0783B70
-:10053000F63CD9F98A03CBFDC4CFBBF63ED3F769AD
-:10054000C855ED5B158EF37A15D6320AF8E3D50D52
-:100550001124B75E35B94ED6A1BC7EC6E6DA0EF5DB
-:100560007EFEE3EF9E3A84E9FAEABCEF421AE38C9E
-:10057000A57ECA7EBA6830B687FD9B25C23A7F71D8
-:10058000500984E53096BDF1F0CA44186FE8E6766C
-:10059000435F4873B7290D980EE95F7002F7CD3EAF
-:1005A0004E07C17DD86EA79A846CD7D7FFD11DB4F2
-:1005B000AF6BF7FBAC8D9F8FEFCB82FBFE60A5F995
-:1005C000FC0A27D2EBFB791E824713CDE3A596E9FF
-:1005D0007FB89FE13A40A3C0797BCD2EDA6760B93E
-:1005E00026C85FDA9FBAE55158E301836F0BED43EC
-:1005F000255CEFB854E47B12E9A51AEAFB205F9D65
-:10060000EB8BBA15CAABFF32D00594C1FA3F7B67BA
-:1006100001C263F1FEC726F5857A97C6309702536B
-:100620002F7FE9EA246CC7FA3386AC7D697F43FCEF
-:100630005C68F7A3ACF123904E8AD4661A87D5F094
-:10064000719E10FB176B03E0C40B92837A3F82CF3D
-:10065000F83DB625E670120BE2A7A66585D308ED36
-:10066000877BAC2E15E9DFE94BACB505F743D8C75E
-:10067000463B91B4CDA25FFBF4E4A26FB18F99C564
-:10068000BE24FB7BC2CC7C61D04F7FF8AEE03E6BDA
-:10069000E6FBEF76900F48BF72FF8571EF728EA078
-:1006A000F66E94A749B0D9E6C23C939EB0903CBF89
-:1006B000D9F1A5DE5413CEE591D43F66C735BCD63B
-:1006C00006EB3D1EEE9989E3CC17FB3733BA1C28A5
-:1006D000A7F784BBEF73D27ED8918C6B80FD712E0F
-:1006E000E617ABA04FA586E853D69BDB1F3F0C77E0
-:1006F0007BB0FDCDD6D7CBCD655F1A582ED0C1B219
-:10070000C72C7E06F36E40F90AEB6A881C694539EE
-:10071000C08E19AA8EC37E793B6FD9D5DFB2C83C93
-:1007200092130D8C750BAFD7819F3D203F0220EFB8
-:100730003DC0D763AF75A89CDE5B8F460F4779C974
-:10074000DC91403F775C33304FC87EA6EF07F05511
-:100750008FEB1BC7229827647F74B31833F22DB335
-:10076000C5FE73EB16F31F23F037A6F38308947FBF
-:10077000CBBECC2339D8D3BA5E13EBFA35AE0BD24D
-:100780004FD28A36201DDFFE85DD88EBBBDD383594
-:1007900019F51398F71338EFB15F18B4F3FE3A5C0C
-:1007A00093BFD9F93FAC309F01F9F173B31FF9B191
-:1007B00005B7398063CBA22C3FF2FD0133CFFBA2FA
-:1007C000CCA49FB644321FCA9196A9F17E9F13E52F
-:1007D00021E3FA6B6FC6CBC344FB39F1D4BEAF053E
-:1007E000408AF2E0FE70D17FED5BD958BE2289E4E9
-:1007F0004883C9BF3605FBFF81EADA0E78FBC06F7C
-:10080000F099804E36C604EE57A1DF8D9FC7331C8A
-:10081000E7031648AAC171CAC349EEDE66303C3808
-:10082000D586F5DC89B100EF03FFAD92DCDF980BD4
-:10083000791BC9EDD9CDF07DE354776238F63335B5
-:10084000DE40F351592D7D77F2761F9978BDB902BC
-:100850005F1F0AFC005F13DF7BA64418916E4F3ABE
-:100860004BDE7512BEDD890ACCF7A9B234867273ED
-:100870006EC55D4EA297A627487ECD163890FD61C5
-:1008800003EB48D47FF9BF39F3B787213E679687DA
-:10089000B5C30EC93E285F19E980F6333D6AC00230
-:1008A000F294CDC87777E9672938AE9BC6AD6E1E46
-:1008B000947A26849E4B2C2027A0FF43619E0F88AC
-:1008C0004F0FE552F921504EBE017E3A5596B617AC
-:1008D000F98A95C9F35FA014F1F07A8795F4CD9E5B
-:1008E000E8A101E13F54D029E26539C73BE85D94B6
-:1008F0006F983D98CE25CF9938DDF8F685115E0BBF
-:10090000A65909CF9DB3C3B758A0FC4121B71A66B9
-:1009100087BB15A8D7F092C56F70D27987EAF95EC8
-:100920008BA47EABCC3C5FF5621AD1D301B37FD7E9
-:100930000E2C7F3D8CE8A12A8A8F5BF54A92A03766
-:10094000B773158EFB9A85E8A02ADC114DE5FF1ED2
-:10095000477432D9EAF91BC20BE8AE16F5822A7346
-:10096000203D06E07B52D0D5496883F8F3D546D2C6
-:10097000BC89E521EF69E8BF15F1E931F372F63D75
-:1009800095CA4FDAF9F827D7F1F18B7F52F9360380
-:10099000BC9D2C9A94381FE671B23682F4BF3FD7C3
-:1009A000A90173149E5F3A1E4F877A97979F1EB9CD
-:1009B00009E6DFB6F2E364A48FE295D585D8AEB838
-:1009C00062F914DC377BE2CBE22A60FE103E4E492E
-:1009D00071C7A4C07AC6A6787A615A93D5B600F5D5
-:1009E000E0CBE6D667F11C9114E7E983DFAFBC7C6E
-:1009F0007607D78F3BD2713F586CE4F421F7D51AB4
-:100A0000417FC7533CFD53709F080FCCC3FD232289
-:100A1000AB95CBBBE53727E7CFB76C3FA0C0389588
-:100A2000E12D8B2955FD39D8CF052510A5A412FC41
-:100A30003CC84F17ED812884BBC7C0F5B3CA9DDA07
-:100A400075E13F23CCAB12FF807695CDAA3B0C71AC
-:100A5000CDFC669C7F253307EB3B8378827E084F75
-:100A6000CCF6E779DF07F857EC1A9487E780CA9845
-:100A7000433FBE8DEA413BC927EAF579B99EEBE7D2
-:100A8000C3D77751D0FF4549FFB3CDF25C4EE35F4A
-:100A90007EB90F8D7F61AA3F1DE17F5911F576590F
-:100AA000783DA00623CEF3979C9E1E37F90CE17487
-:100AB000BE6744CF9571CD23112E520EC11C7C060A
-:100AC000A87F616F12D597728B153186ED2AF726B4
-:100AD0006EE5FA993897E244A17EC52F78FF9847D2
-:100AE0003E3CFF4292188FEBC77AFCE9D75B9C62D1
-:100AF000A0F53E2EE577A4E47357C254807FC62646
-:100B0000B3A6FEE548F3836EE877905FFB5DF65F82
-:100B10009EA2907E364087B7BE6AC7610BF2D3F3C0
-:100B20008CF8553FAF9A147EFE7BE1852E3CA91CC4
-:100B30006FA0064AFA70703DDC8470FEB00B1F0F88
-:100B400025815CAD4418A404E17320D79384F2FF9F
-:100B500032E6715F88817C16EA411CDE322FE1ACFF
-:100B6000A7B3951F2E486A83F64F09F80042FB2071
-:100B70003D76E92F26385F64E1B9B27CD899343CE0
-:100B80006FD60E82ADA06B3D0B36E55A919F166E67
-:100B9000CEB59684E0A161E7B0130E80F3C59D4603
-:100BA000178AE506A3FFC7A84F37EC549B7D8CCA74
-:100BB000AD08DF8BB623BFC37A0B36C7E4A1BE2CCA
-:100BC000DB2FDCF4F0A0B210B80FD9A9C54376B37F
-:100BD000363FF49036BF0D6543EF6FDF2E37A0CD63
-:100BE0000F3BA1CDB30EC016E041B5723C1D1CE514
-:100BF0003AE1003C0DF0AB2EFC34C0366DFA64D403
-:100C00002F36ABAE34281FB0BCE89E6CC87FB679D7
-:100C1000BE0BD15CAEFA167F1F7058FEF1A413B85C
-:100C20001F5E60CDEF4F063C2C68D960363A70DD10
-:100C30005ABA3D6010F4FA02B7972DF26BCBAFE7CA
-:100C4000EB15D25E9A194A4F7ABCC3B8F7B9614224
-:100C50005575CB869D812DB3BC10081D6036BA79C1
-:100C60008319F5B61B8FE3E3F462733B101EDE516C
-:100C7000BCECD6BA09ECF430F863DDBB9370DEDE71
-:100C80001F29A437787F95710CF781F67D73EEA646
-:100C9000F4BE025ABFB4CB2D6C51029190B78F7243
-:100CA0001C6A8376F3FD8A0BE75DD26809CA33F8C4
-:100CB0005FD93ADD3C368694C3FC171E3AFC3705F3
-:100CC000FA2FDFAC6DB708E42CCAAF8A6DDF58424B
-:100CD000BFCB73E3AD2D5B545CF77C397FDF588667
-:100CE000EBBA955765BD847E730633B06FD4F62E8C
-:100CF0003A8BFBCAAD1B793B10975E5C6FB5CDECB0
-:100D0000C0F5565B592002E67122D2ECB6C3F7ABB0
-:100D10009B22C91EB6C002FA641EA52C2C0FDBB99B
-:100D2000A2B1DDA7EF70BB58751CC777F5730A9D9C
-:100D3000A3AAD18889F9E7797E110BD03A904EDCCD
-:100D4000A1EBF36BF3AC899FBFAA8C81C3088F0A18
-:100D5000D6C6CF4F8047B7841FC0AB0AD6F9412C07
-:100D6000EA5BBAF6CCE5C1716B6C5C7FAA39F48D95
-:100D700025B45C9E03E53955DA699F4B2F0AC7718C
-:100D80005629EE27AD30CF5542BFF66D0823FA9DA8
-:100D9000BB85EF37A0C7A6235C366E4874A19E3191
-:100DA00017F4F230E49B45E1540FF45DB2AF748068
-:100DB0005E8DF6F68D31CD01DC37363EE6243D1AE8
-:100DC000F45F824BC7FA30FF5605F560AEC76CDCA6
-:100DD00090417AF8AB729F5ACFF5AE6EF4622A67F3
-:100DE0007DB81EFF112E25440F4E8DF7A4A586ACAD
-:100DF000AB6CA53B11F79DB2696603DA9D58F9CD3E
-:100E0000F90DB60B3DB203D68FEB38A3141D378412
-:100E1000E8A32353F93E3272BC7B87A847FE853294
-:100E2000C3D447EFC0F11E373870BC2E78BBDDE964
-:100E3000388F331BC2F290CE468EE7F69F93B95C93
-:100E4000BE470C676E3FA477887EEF483568D28432
-:100E500070A03FE8E74C3EB73B470E2F227B1BECD0
-:100E6000D524E7F5EBB847F453662EFAF7DBBB99C8
-:100E70008F840F9BC8F585334B94AD7C5E805FC833
-:100E80008FFC6918D9E9CE88FD47C219E86604D9F4
-:100E9000DB85BCDA20E8658389D3816F113F3F058C
-:100EA000E985113D6C14E7ACB902BF6C3DD76B818D
-:100EB0005E389CD7270A7A61ECEF480FF90EAE67CF
-:100EC000DFE47909F05E9ADAFBFA7393C43733FAF8
-:100ED00047FC23FF46F5C13D077CB07F56FCF2B1CD
-:100EE0002806F5CE199BE25DD0BE6AFBAA2837A47E
-:100EF0009F197D517618FF9C5F2DF077036FBF809F
-:100F000037DAD715903F8BF14F07EA3B3F9A82EBD8
-:100F1000FBEB76931D4542CD4E0B9D9F16EF5F4434
-:100F20007A36E4DB797ECDE72AE60F69EDE0153FFE
-:100F30007F2CDE41F0F6251912300D243148176F51
-:100F400033B902685F7E4F75C130A03777ACC6F900
-:100F5000E9DBE33CAE01BE6B9A55AF39FAFAF21AFF
-:100F6000215F6AF6FFE873B4EBD5E8ECEEE5C2FF6B
-:100F7000A0B7BB37A546F6FA140DCCB7B05B500F3F
-:100F800002B8B802C8B7309F3422136EB76DD8F5D7
-:100F9000444E3BEA0BDBDE8A52B2827677E997E871
-:100FA0006C2E7D0EED9A3DF1E36561870DE28BCBF2
-:100FB0002DC7210565001CD0795A650A44DD06F06D
-:100FC000A8DA62223953B5E7F91D4F219D7D68A14A
-:100FD000FDBC72CF1BEFDF8AFAEE3E53AF42BE0C70
-:100FE0009B121FC4538D83DBC9245E2A7EF586D9EC
-:100FF00091CDBF2F8F0DE2A772DF6133CBBE1E8E66
-:10100000139A0F9BDB6CDDE0A9B97D12D989767D3F
-:1010100065463E38F7BAC2FA38AF6F5FBEE58D2835
-:10102000D4C7104EB82F497C75E14F571FFA9FF275
-:10103000CA70AA67C773454FF85B827B07D17724D4
-:101040008B81F1CB3FB2F80B11AF7B9745E13ACEE4
-:101050001A6B399D3FB32A1EF5BA72932FDE4E29C3
-:10106000FF5EFEECC3447F0B95DA787B16D177A246
-:101070008174065F22AE6FFEE699B4BE05CC43F4E0
-:1010800057FE8C5AE487F44B232BD8D70D9FF41DC1
-:10109000C8F9E4EC56402AACEF2CDA6D506EFC5ED9
-:1010A00015E7DC25B47F3F2CD6CAD852CA7F29F475
-:1010B000B64BA95D7E656BE879B166DB9A56C4CF05
-:1010C000F9FEEE3E384F80834FC04BF906FA55DFEC
-:1010D000CDEFC3F1C31CC691A21DECA313F03BD608
-:1010E0006F35B9D1EE1DD24E9CE7F8F80F89F1614A
-:1010F000DEE1785E3D1BCFF576FDFA0A062AD2DEE8
-:10110000D6CA42E9AB27BEDFF608D1D517EF71B9D1
-:10111000B2D83FB580CA5B4D813E58EE3F3C43217B
-:10112000B9606181EEF87A9B49F0B5B61CE6695466
-:1011300042E1FB3AD7431780DE1508E1E320DD9852
-:1011400083DF69DD3F15EB6823BF98F4A72D14F208
-:1011500040BF6EBD7CE83550F8E3847C90EDD9E665
-:10116000EEFD3941B9E0A371AB603F413DA3EA43D5
-:101170000BED1B557B4C45089F0BBB8FBE3F17CF1C
-:10118000A1CD928FB5F256CFC7E52F8EE8968F2F5F
-:10119000ACCBED9E8FE17BB77CBC4E21F9F63F9541
-:1011A000B7B0D391DDA0277E5DD883BC1D3B502B0B
-:1011B0006FBF6459D1B761A1DD3B80F0A383AB84DD
-:1011C000A75E7EBE9FEA20F8EAE527C3D0881038E4
-:1011D0004AF849FA64CC43E374D1B1A45349C75DDA
-:1011E00074AA5FAF168EFA72C34046F3297AD9C447
-:1011F000ED672D0AE9DBD0EE78D270E253376D7FD0
-:10120000ACE97852AFD0BC5F976FD6D577EBF2459B
-:10121000BAFA1E5DBE5653BFEAD051333F1F0434A5
-:10122000F52C75F7D039E37A3DC2CFFD3EFB3F3751
-:10123000FB902EFA7598512E9A56325F24EABBAF76
-:10124000A9A4EF5E717444A15EB22A8CEB6D57ECD9
-:10125000221FC3F31DBDCDAB512ECAEF1D61DC4E65
-:1012600072A5A8232A26E49CDEDEA246A13DB6CDC7
-:10127000CF0ABA8F136920B8B6B19ECAB9FE96AF2D
-:10128000DA92EBD01EDAA4BA804C58D98A5951149C
-:10129000BFD0927AEF6CF83EFF372A85015C09E7F0
-:1012A0007605E6731B317EA094A3907DC67C8F8F5C
-:1012B000817595B6F03882B2755AFC2EB0CD880E85
-:1012C0003850EE68FDFD0BF15C978AE73DEDF70ABB
-:1012D000B68EE8AD42C7171E61A7D5F3C516C9176C
-:1012E000B92C57D863C8CFB154C8EB7C35EBDED9E5
-:1012F00000FF2B275466817C678BCA56E37A772BD5
-:10130000E4EF418700F2DB62E04B9C8F84CF45E441
-:101310009B8C9EF5928B2FFD65E4F7914E0E7C9C85
-:10132000837ED88B073E4C7F15F307FF94FC31BBBF
-:10133000BEFE84D7FF360FE5F095D72D0CE9FBCA2A
-:10134000EB6F26A35DF0CA2B163A2F5F5969E1F6C1
-:10135000E6D723FDE88FBCD29FEBB90DAF7D95D3C7
-:1013600046FB6E23E1EBED8166AE37B5FCE749B491
-:101370005777B6C0AA509F783D82F8A7E69530F21D
-:101380006B5F79EDAB91A1F10FFFD3F548FFF595B8
-:101390004836FB45A45BA1D7D7BC3AFA79F4E756A7
-:1013A000EF3F6C2E85F209BFFEAF1C949F575EE4A1
-:1013B0007AD26553DBB3686BFCD3C0393F3525A2C5
-:1013C0007D0E3AEB0BDC96F6E434E493EBE1C2E1FC
-:1013D0007005E080EB02B894A3DCEF091E97FF656F
-:1013E000E1F1F93C2ECF6E61E8FF0DC245E17E844C
-:1013F0009648BF55A1F5F3EFAF7F9583F2E646EB34
-:10140000B5A59989AFFF7F59EFE0B47F55FC727A9B
-:101410007F71A083C7F5E9E8FE7ABA3EF86F94DFE2
-:101420001BE9A2F9DE24BFDFFD2FBBFEFF1B7C976B
-:10143000FFCBAEF746F8FE8DC077A41DFD8A575E40
-:10144000FBAF64F62DD6BDE65F96AFFFF1BAA5BE41
-:101450003E5E759DC885FA6FB1E6F75C4ED23EBA26
-:10146000D53BF6A7493B093F1F4D607C9F9E60AD71
-:10147000247D7342BFF5A41737B03CF243F8FAA9B4
-:10148000E48FA1E00B80C39B09B97EF2271903FD0D
-:1014900096417E7C5235C55BE9CF8D13C22717A0DC
-:1014A0003E7A7405CC0BFA391A69B0A3AF78623F63
-:1014B0003560C9A1B41DD3E3C9F79C40BD65A24DF9
-:1014C0007B7EBA47771EBACBA12D2F602FF642FF45
-:1014D00059419689F9613E93B07EC8B9F1A7697602
-:1014E00082CB5DACA9D16EFBF6703A23E0743D1C53
-:1014F000FE31DCAE839338271B457D3DDC8CB6473F
-:101500005BB19D91C1B997AF97CECBF2DC7B2378CD
-:1015100032719E368AA1257C8DFDB89F34A45F82EE
-:101520008B84FBB785B7C4931EEE12BE126E7A3C55
-:101530001C446354EF20FCFB19738DC877B70B3D37
-:101540007EA23186E7FBB5AA45C48F7E82FB842F3D
-:101550005C46D44FC6D96228EE9239FAC7E07916B4
-:1015600055CC6F92182B1915335281F5261999CF46
-:1015700002E74DF4A1911DF511A37FA513C7E1F674
-:10158000DAFE466E9706EEF685E7517DB719F2DE74
-:101590009F2D646EA8EF4D622E85D767D1B1148E52
-:1015A000C6548CCB8214DB79A379BFDE3ECCBF92CC
-:1015B000E393F082C726B45F40BF6E432C6F1F9544
-:1015C00047ED7D06DEDE6D8474402AB7AF77ACB29E
-:1015D000D0F9C3BBA67F3ACA8FC2F15ABB71713A28
-:1015E000B7ABC8F4CD74CEEFAAC195807A7149E348
-:1015F000203A0FA9E145D52FA1BD7F6F04D1A37774
-:10160000F5039347E0FCF6C6B9707AE7A7EC1BC96F
-:10161000EBCF79F88FF0DDB3338CBE5F48F7F44938
-:10162000877ECF2B8E792FC187929947CD09308441
-:10163000A779EA25B4FF4DF1EDFB1DFA19A7CC50AF
-:10164000A9FE14C6E32B596304F9A327FB3E3726F2
-:10165000407F93E1B081E5ED61F6E425307FAFB0E6
-:10166000F7A6A673BB8B1ACE3C2FDA705EFDD35360
-:10167000E0FB64D67D3CAF57D61FAF6C46FFD080F1
-:1016800009DC1E2FEB633FD8EFC274EE5FCD117003
-:101690009179802BD52F5B6B694FC573CF5A53203F
-:1016A00003D26732C7E7A54379610A9BB409E1FE1B
-:1016B0005D956DA5F97678C9CE1D99E9403C788095
-:1016C000A429BEB0C9E940BB57FBB8E600FA07DA67
-:1016D0009F74BA1A1C84658AC791E7ACF671818140
-:1016E0006897EFC8E57E8693F6B6483C1F96DAAC5D
-:1016F000149F23E37AE6DB399F0F68685B7F0B9EBC
-:101700003B1F535D5B213FFF31EE77F9C466F52B3C
-:10171000785EDBC8F994ADD3C6F130BB8BEC3DA548
-:101720004DE3CC78BE2CB3B9CDB8CE8A0C4F11AEF8
-:101730008B7D0DF01B89719C8C98C1DBE4A538135F
-:10174000350AF80EF9C4E888C273AF3E0EA846C445
-:10175000FDC8FCA130CF1CECAF24DAB117E9E55489
-:101760005D2AD93D3709BA2BC43846F44F18DB122D
-:10177000713EE1F81DE05F186B4FB7113D87318472
-:1017800043BBC99E8EF4DDBE2ACC807EB6C2959C3A
-:10179000AE81CFAC4668FF889185A3DF2043B42F8C
-:1017A0005E612CDA02F97E56668C8C45BACA25BA7F
-:1017B0006ECBF4E4207D7EF603360AE9A174DD06E3
-:1017C000F2AF48BA60C6D6897130CE67DB9D792802
-:1017D00037251DB5658EAF4D0FA587190AD101A418
-:1017E0008753891EA63D8CFD168E0F0C5C9A85E7EB
-:1017F000D12AE6C6FD3D81B9504FE8641DE47FEC77
-:10180000B4991D68E792F244CA0DC0ABDB1A1FA45D
-:10181000831DB0DF1B4D8CEDACB752FA42BD9D1954
-:1018200041C6EDAE4FA0FCDE7A07A5CDF599F4FDDB
-:10183000C57A17E5F7D78FA2FC817A37E50FD51760
-:1018400050FA4A7D117D977209E0427248CA152903
-:101850008F4A6DE676F4474AB9A4A79B7900DEB1BA
-:1018600079D49EE49E9477B80E435E501E49FCA640
-:101870002845BE0427CAB1B63988FF7CF5E29E83AD
-:10188000782E2FB7B9E89CCEB8DCEB047A45B824A3
-:101890009BD921B4BB362C71B7AF7106E17F7FB9FC
-:1018A000C28C2174F5406D183386EC1B0FD6C568C9
-:1018B000F2C5757F78A30FF45FD1CBB30BF176F24D
-:1018C000879F3EF327F8FEDC0FCFA721BE611EDB0A
-:1018D0009FC071978777CD2316F38D26F2470D9021
-:1018E0007610F8877829619CDF9EFBE1DF89BFDBFA
-:1018F000EB2C0ED4873F423C015CFF2CF054526726
-:1019000021F879579DDE7310F97CB999E45C49A3FD
-:10191000E0C3B500CF10FFEEA94446F608D0A659A3
-:101920001DC0EDD40FCC8108E8FF94C2F95701A582
-:10193000A018E3FED6BEF901F2BF527782FCE71E83
-:10194000AB8DEE35319FE962687F4ADD71AAC7DA57
-:10195000FAC5A0BD84F6B13BD0EFE8363B60DD4868
-:10196000D388B792CC232C11FD264D8A1DFD266508
-:10197000E27BD95A85FC9318773303F4BE77D355AD
-:10198000C26364BA91D2CA7426F4BA26DA9F24BD1F
-:1019900096AD8376C8174DB9E6052172B8447C2F01
-:1019A000CD34502ABFB78B7EFBAECD9D8DFA445F00
-:1019B0002CCFC2346F36C2B7AF6D925109C1FFC789
-:1019C00038FE089C071FBF12910AFFF768668A79E4
-:1019D0007E16E287EF5F729C92CCBCD518C759B2D5
-:1019E0006E1C4A5FD6607225F4827A67BAFAE17A91
-:1019F0001BB3F278E5AA1EF60F693FFB0CFF1C4DE6
-:101A0000EB26BB6EC5DE5FEC7D057AAEF8D842F8FA
-:101A1000AD182AE2A7B2FC23A793A1516BAF9EF8A1
-:101A20008BBF4491FF613F8FAB8494DB53979773D7
-:101A3000FBAB0BF8AA1BFFCFB1BD1F47756BA7DE31
-:101A4000AFDE949DBA46F93A0AF507B99EFCD7BEB7
-:101A50008CA77928D7C8FF53F3DAAAF8EEEECFE8BF
-:101A6000EDD55DF66C61B7D397EBED757D32747E85
-:101A70000123A3FB58D25EC7D4AC68B4EF7F29EE34
-:101A80006BF474AE91F6ED9A4DD0491CF0A7D111CC
-:101A90008DFEAA2B3DE8D30F66F0FDFE92B0875F66
-:101AA000D9ADD239E7CAEE48E2A7C5BB7F761CFDA7
-:101AB000878BB729348D6AD64A700378326BE83E3B
-:101AC00086F16671D7CFBBD39F168DFB48E52F22D9
-:101AD0006B91CE16352BEEED309F4EAB23BA77C807
-:101AE0007C6ECBE0745669691E497016F3CFCD70D9
-:101AF000D077596F51CBCFC87E0CF52E931EF4CB07
-:101B000008F4F523BC7F87F3BCB079980BFD7E8B7E
-:101B10009AF72D263D6277841D8F0CE7459CB0EC2B
-:101B2000E7CE0CCE9F776670BDE582F0075DD8AB3F
-:101B3000923CC379227F9D57B4F1789345BBC9028B
-:101B40006E9F0BFE92F51735B7470D84FA670FFDB0
-:101B500081D259625D8B6CAD39B8FF9EDD1F41FEAD
-:101B6000ACB3FB9F9EF42A8C77A9795C2FE407D94C
-:101B7000FFFC0C13D5BFB4592D4078313F8F7BA9A2
-:101B800046F80E0B9D67DC169F3394EF78DCCF850B
-:101B9000FDBF8A326405F1596DF558F15E63CD7E63
-:101BA0006F11CA8DCF140E4FD3FE713EBC8F54D32C
-:101BB00092CB909E89EF12A9FE5A43483DB3C94586
-:101BC00042D17868AA3B89E02CEE13897879BC1F52
-:101BD00087F267E9542BF927E60D75CCBA1FE5E4C7
-:101BE0005B268E977E8E27507F9BF74E1CC54D2D12
-:101BF000753A66E1FC97BDAB52BCEFBC61420E2466
-:101C0000B48DC0B8C5AAB50A73C33ADB9D5C6FA892
-:101C1000F2ABCC03F9BE400F3E00C5FA8C14214F45
-:101C200003E978AFEFA97283DB0CFBDF4933F3A93B
-:101C300068377A91C73357A5F0B8E1A790EE21AD88
-:101C40008A0DA4C7417F17053EABA605D2314EA22F
-:101C5000EAC5448A93B868E67E4BFC8E7ED2AA3CE5
-:101C6000680FF57A8978586C1F13423F55252E0767
-:101C7000D653635D8E5C1BCED77E99F4D89722191C
-:101C8000EAB18683913CCEE9E7615B2D2178DA9257
-:101C9000C1F5E55E028F6C2E8F877C5CC4633FBE0E
-:101CA0003DD18FE73759FF7193670EC201D781FA93
-:101CB000FB2273533AEAB772BE8BA29A689E17054D
-:101CC0007D2F0A6FE2F1D2E29E2CD6C77CBB8951F0
-:101CD0001C77C72E0BC5939C4F6C3D80E39FDF356F
-:101CE00088E1FADB9DFE0587A81CF447C05BC50BA5
-:101CF0009600AEE7DC2E6E6F3E67E2FAD8B9A9090E
-:101D00000EC45BC1B44DF3C81EB3CDA220DECF29F3
-:101D1000CC9C80E5DB7BBB7CD8BEBE8EE2A42B4096
-:101D20004CE07D1C480BF05ECDB9ED83283EECDC29
-:101D30006F54BC1185DFD7E2770F6B9AF73D84C7EC
-:101D40004E7E7E3AFFC27F0E0ABD5726D38A6DDAD9
-:101D500038384927B2FC4806B70F1C11703E9EC1A7
-:101D6000F7ADEA88E6C753689D1CEE80273AF7C1B5
-:101D7000C61FF9F4708C834853506E3C0574F534DB
-:101D8000DA1576F2F3D5F9DD268A0BAF3818E9A615
-:101D9000B8B335B718280E42E57A788501C047A94F
-:101DA00042FD564CCBA47BBB006F3AC7766C57C53F
-:101DB000388CD970DD3B789C6F21EA8A549E4DE5C2
-:101DC000E744FEDC816CD2EBA07F37DE57AAF8DE59
-:101DD000F7391CA797BFCDC88E6125F95AD5E5C73D
-:101DE00019138DFB5DF59ADBA2F13E1F7B4765A8B9
-:101DF0009FE8E174D5E8EA8372B577A690B3079EB1
-:101E000031A33CA814F7432A5F50B83F19F80CEFF0
-:101E10003B56AEBEED09A2CFDF99581AACE762F38C
-:101E2000CFA234F81072B0ABBED945F52BA13EF667
-:101E300053B9FAAD289ACF0E13C5995CB75FDD6C24
-:101E4000FB17D49B6ADF451FCDDC8E72DDFA59EBA0
-:101E5000BF7D0CFD7FB13BCCE5A3AFCD74AFEC8271
-:101E6000A97901AEFFC29E3092471762B87C380B49
-:101E7000F2D39781F3B8E7271497F5FBE9741F6E47
-:101E8000A15FDBAF1CD79869E27416E78AC6B8BEBB
-:101E9000EA77B87C03BCDC4BEDDF31517BFD3A4E79
-:101EA00067F0765DFCB92782E8E1425F8E970B7B95
-:101EB00033683F6A8FE1740EF34DC6FB7317F66407
-:101EC000E4D2BD34546E801E2AC4F9F6424C73B27B
-:101ED0003DA4BCDD24CE6901A88974836D40EFABBD
-:101EE000A8E37A55A5751DC587605CEDC83C4A031B
-:101EF00096D8EBE363815EE9FC787FA6B053E27885
-:101F0000F1227E9BF49D6633CA6F8FD00BAB76EBCC
-:101F1000E36B79F9AD998A8C0371F492F1BC48872F
-:101F20003E85E24C2A1B972C423AAFACDD703FF263
-:101F3000999C7FA59115E039AC5D51691EED61EC6E
-:101F4000C169B86F848E13AAB7C979E254E3495FB7
-:101F5000A57DECAE4CBEAF61BE09FAAB6A54D6D1DA
-:101F6000384E799EE5EB927002709831AEAF7D9C51
-:101F700028EF61DD729EFA75CBF93C90C9E551BB43
-:101F8000D3F1933188E7DFAA743FF6EAD7C3A2639F
-:101F9000BBD1CB82FBBA3918DF8AF1BE487BD04F68
-:101FA0004E26976B95183F0BF34CDFAC8DEBCEDCD8
-:101FB000A6CD0FDEADCD67EDD7E6735AB479D73134
-:101FC0006D7E1A8EDB9B9FB3F13E2E9EB331C5739F
-:101FD000B6C3C2CFD998C77336A678CEC6EF78CE2F
-:101FE000C63C9EB3318FE76CCC4B78E3791BF3781A
-:101FF000DEC6F2A7059CAA449C24E201E99DBD1C13
-:10200000A6B9EF73E5357E8F03E880F3CD1C33F17D
-:10201000CD535883CE1DDCAED477BAD581F1BE8FB7
-:10202000C47A5665A25F54695D9D887833B651DCE9
-:1020300069CD2B3CEEB42A2FCC86F68DB65567576A
-:102040006338E703B19E47B1FE1553C70E846F7521
-:10205000DD51BABFDEB6C2F1CE1D1C7F646761E5FB
-:10206000B1A43779719F8BED198FFAB86FB64E1BFB
-:10207000E7AD8FFBD6C77BEBE940EA7BCF993A12FD
-:1020800051AE9FDE655D87F33F1D26EE9FCCB6EA1D
-:10209000FCFD424F5BAF6CC5FDFA1799B1DCAF7226
-:1020A00002F4F36EF65999965E1B467A78577E9D38
-:1020B00062A07B7109F1B40F2D13734A563ADAD737
-:1020C000A09C5B64A07DF32AE86538DED5F754D286
-:1020D0001F32361934EB19E40FD7D0D7909DB1BA1F
-:1020E0007B0D7D35F5871E4AD1DD6B18AC8DA39F26
-:1020F000B1E2309EEFA7AF1BA6A95756749B0E8E78
-:1021000062DE427F2D83FDC30DEB7B6AF9A664C4BA
-:10211000EFB2459DED6B503F7D298CEE8595E3FF39
-:1021200003B9580E7DE27DC6F2FDE23E709D761F3A
-:102130002E15FB50B991F9ECB1413A2CB733770C1D
-:10214000B45F34B8352780E78ADFFC61A43D05CF52
-:1021500015E3FAA03C4A36B9290EB66A5F5ACC0A92
-:10216000E8F758AAE7A34CC0CB99A6A33F2EC6FD1B
-:10217000701F3FEF9D5EF7AB288A1313F4966CB285
-:102180008723DEB734F1F838B48FA9B141BAD8D279
-:1021900014173ED0165C6F900EBE263C017EB81D13
-:1021A000A7FC08F93D3A9BC57AC7293ED4A7E5FAB2
-:1021B000968A7D850DE4FD3C24F267C4F942AEF3B6
-:1021C000E2A0C3390EBC7F517F285945796ED8BD36
-:1021D0002311D2D116CF97B89EF22D697F1A03E34F
-:1021E00054FC91AFE7938D13A246A3FEB9C7E42A2E
-:1021F00084FC9AA6E7CD78CEAE30FACD145FB96BE9
-:102200008B19E38BEFDCB985BE2FD8E9A578CA8599
-:10221000AC96CE9F9FC97704043CCAC72B9BED3078
-:10222000EFB983B8FC280FE7FE3BD08FDEC0F73B49
-:10223000AEEE5472318E6746D13EB317BE470D12D3
-:10224000F783747CD2F9F6F4FCDE040F7E5FE38F33
-:102250000C4EF1A9D7F3C5F46B4EE28B19D786D09B
-:10226000B96C6660103FFF66E9CEBF6FABDC5ED72E
-:10227000C2F9A0DC1CE8351DF9E47513E9B9D5B045
-:10228000DF8CCAC37335EC8D90168D5135F45A33FB
-:10229000314243CFB359ACE6DECB7D183412929F66
-:1022A0005198AAA93F6BC6101DFDE705CB498EDCEE
-:1022B000AAB95F57BDDCE75048CF1CAFFDCE789C74
-:1022C0002063776BDA57B369C17A48DFDBB81E5CED
-:1022D000BD3F662BDAFBCA0DFCFC34DBC3BF2F3ECF
-:1022E000C4BFB3D94CC38703525D7FE2FBA289FC14
-:1022F00002D29E3E1BFFEE06FE8C8577DD0FC77B6C
-:10230000F1688FD0DC9F16FE409C37E2A15AD88D31
-:10231000AA33B9DDA8DAD76AC6770700FEC6B8586F
-:10232000AA678DC3F8C82685EC8A982EA778496DD0
-:102330001C16F687718C8B4FA85EE4137D7939BE2D
-:10234000DF83F87D85C7952EDCA48F835C47FEC8AC
-:10235000C5680F0AC1DB53831C425FF1AFEE8BF0FF
-:102360002B5472E95EE4EEC3668CB39B31232617CF
-:10237000F9464F5F52AE033FD3F9BBF3EDA3445F81
-:102380009DE546A2DF1BC161B19BDB51F574B780AF
-:10239000B59AF19EF882FD8A0BCFA3580FE1D117B1
-:1023A000E951078FB8D8EBE120E1D305AFFDFA384A
-:1023B000370EA78587147FA01B38E9E7DD13DCE41F
-:1023C0007A16783C93502EC8752DC4F963FF307F80
-:1023D000EC5FFA21D8283D7FA6927D6A71118F8F1C
-:1023E000D5D3C3B46BDCEE72DF3523A5330AB5FC5D
-:1023F00088ED902F665E8BA7F26F4B2F8B619EFC52
-:10240000FED3CDD1895C8794BB417EE0F7066EF4A4
-:10241000BE8FDEEEB8639088131CC14668E29185DA
-:102420005CD5B7D7C7234B3D40BFBF78230D1437CA
-:10243000D9694B21FD42CA598FD83F3CABBEA47A23
-:102440001EA8C76713AFD96F3CC2FEB7343285DE12
-:1024500063485E11178F78F286D929FEDEBB42A54C
-:10246000B8672FD47384E827AB1B539371BF38F53B
-:1024700048C6B33ED0DB4F7DB757FC2818E7F42A97
-:10248000532FAB2358EFD4AAFC648CD338BDC13290
-:10249000DBDF0DBC5AC5FE50FDC30F683FBB64783F
-:1024A0003B6A36B4AF5AF5521486F957AEE2FB7860
-:1024B00079AAE79D41BD713FDFB2C38EF0B36FC90A
-:1024C00041BBEF49D80EB0BDD41F2A56E5F741FDF8
-:1024D000A2EABF8F3E6BC77BD62B4CF1A87F9E7BB9
-:1024E0000FF64385F633D21B3E0B832EC89F164949
-:1024F0007684CF14E646BFD245C3E1BFAEC1736157
-:102500006E737A00D2EF593C2771DCCA55CF93DE47
-:1025100052F1E88A7455C57ED3A2BBB39BC87487B9
-:10252000D8B7517FC714F5778C9341FD1DF3A8BF31
-:10253000638AFA3B7EAFD9A4D5FF2EA7713925ED6A
-:10254000C9031A3A72D17FE71BCF326B69BFB565F9
-:10255000A2BEBE4C0977A13C5A86BA12E6FF1246CB
-:10256000E758B62D91EFB702CF7556EE37FA4ADC31
-:10257000CFBDBD0374B210FABCE39A9585DE9B1DF6
-:10258000C76234F909D6444DFD7CBB53537E67C204
-:10259000204DF95D8E5C4DFE9ECCD19AFA935DE3A1
-:1025A00034F97B47DDA5A93FD53D55939F5E304764
-:1025B000537F669157533E6BF6224DF91CCF124D57
-:1025C000FEFEF2EF6AEA3F50BB4253FE95014EA475
-:1025D000402F2D78EEB2E0FB29564ABFA3DA8D28B2
-:1025E0003796FD36CD86F81E33C150DB9D7D3F63A7
-:1025F00030D787CA86B85306F7E6EFE0203DF617D6
-:10260000EFDC8C18CCF199C480AAE8BCDB9A88F482
-:10261000ABAFA72F1F1371E4AA0370F893C14367F0
-:102620001A410E8DB9E5C8B054C89F18BC60A611F8
-:10263000E4C698DB8EFC2A05F2AD837FC1CB871EF2
-:10264000B98AE5B38654F2F2E98C548F3FBFD07754
-:10265000A60FE77F47CA3A17B793747BCF5CA608EB
-:1026600007BCAF8D70C03400F48BE911A05F4C8FB4
-:1026700001FD96817C3A0EF48BE909387FE2F77F01
-:1026800087F327A66FC3F913D3DFC1B913D3563825
-:102690007762FAFBFAD994BE57EFA176EFD797533A
-:1026A000FA417D2D7DFFA8BE8ED23FD7FBE8FBD43B
-:1026B000C1D28E11609AFB01E867447FE221D3C545
-:1026C000503FB0F4574AFF64432D6B8B4079D1667D
-:1026D0008CF9D41AF43BF66C0730B24F43F4B1686E
-:1026E000E62E1E4CFA423F3BC96FF1DDE4F0781153
-:1026F000CF7F744E4F1BA6E2BE55FB06BA65FF683E
-:10270000E8FEDDC411823E460D712F20FA10FE75E1
-:10271000E9DFEE8A9B09F1BF1B42E275E85F48DC06
-:102720008DF483CB389FDBADFC9EB1F473CB781E68
-:10273000D95FFE178CE4C3D8B546D25F228D2C80BA
-:10274000FDCBB89DB1D6E65C8C63185B65A37BB509
-:102750007DE0BB398FEAB95548B7FD0DEAE704FDC6
-:10276000EA7DC4FCA19CE69FFF8587ECB063455CD5
-:1027700001B6B7F2721FB61F8BB685E194927C7AD0
-:1027800006EFEDE605FDFC583F82D70F607F03FFA3
-:102790000EE34505F9A67F6C732ECAEBFE8B6D74B4
-:1027A0002F74F3B800BD6745462780CB74797EB29D
-:1027B0008ABCF4E7EDEC4376A40982D7BFEFF06C56
-:1027C00042F81759EC7F89203E4BED8FF6C9A9429C
-:1027D0007FFE07787B06E940C253E245E251E223DF
-:1027E000247E8AF0D0135EF5F8D4E351E22FFF8BFC
-:1027F000205E10AED7E32D8857B4E7FEABE06DB88E
-:1028000091BF5F66A9B2D2BB6837C2E3831D6C5229
-:102810003456717A46207EBCD71CC7315FCAC64D7C
-:1028200042D4CAF2B1583EE2FA72CF171DA6E810A0
-:102830007CDF2EF03DBF87FE643DF91E83ECBFB107
-:1028400087FA6F85C9B80BB72D776430FE71593E92
-:10285000877F815325F84FC85A487A32B3713DD3E8
-:1028600001FFA15C9AF47511BD4FF925DB8D9E5BCC
-:1028700036A997563F2DD0F9ADEF167AE9DD3ABD6E
-:1028800054AF577E3E58F8B39DCCF92DDF9DBCC6A2
-:10289000E5DACDBE3BC9DF2D9D28F82C49D059AAD9
-:1028A000436563908E9887F6C963F86E690EBEEF34
-:1028B000E9A3FC5DCC4FE93D2C40FBEB6410C498D0
-:1028C000BF174428E68F464C29C6BB7113864D18A6
-:1028D00088DF43DE658B1CD29BDE65FB0F7BC8BBAC
-:1028E0006C47263AE87EE5116B2AE95FC887A61097
-:1028F0007BE06F607F1A08FBC751D8BF307D03F6BD
-:10290000AF81B0DE3761FFC2FCDD992B18B69BE4C6
-:10291000D0C6EDC8F6F7D827C0C1A467F8DD93F399
-:10292000723F84EF5B311913D17EFE56CC2D1371AB
-:10293000BD6FC5F431F0D462A634FBE0C0EEF443C1
-:10294000C907C1F126D1787AF84A78EAE128E1FB93
-:102950004FC0F396EEE0396230E3F649EB1FA21266
-:1029600052D07F1725DEA3FC6D8E0AF97338B5446B
-:102970008C57BD8DE639B66E34330E23BF4D16C26B
-:10298000B5CACAE1A5B75BB16D7D0CA1F1BB57CD4E
-:102990009E8221B0EEB39B55BA377EE9C530B2476F
-:1029A0007DE6E7F6B67B14CF649C5F95EA5887EF27
-:1029B00088B2B7F83B67ECEBA3C9D322BF059D6E85
-:1029C000E3F7EDABAC93BAC5A33C4F4D71BA47707A
-:1029D000FAE7EF454ABDA29F85BF4B20DF2FEC49A8
-:1029E000CF1819CEE5603F0B97DB12AFD08EF249BE
-:1029F000D0CF489073493F09A7F3C5CEDEEEF9B8B2
-:102A00003E6947E8EC17E147793B363084DEE52A3A
-:102A100038A1523CF11111DF75E7905A5B0AE0A929
-:102A200029CD5383ED98FAB58A72E66D58671CDAA2
-:102A30001F4E0CB3D1F9F15B9E43BF3344C88B1CCE
-:102A400096A3B9AF26E94EB551FC4EE77BFC3EDEBE
-:102A5000D2DFF0B8CDA5BD558AFFD7C7C58D65E9D2
-:102A60003F417BE3845E2697DF11942FF21D204BBC
-:102A700082813942F4EC3047387384CC27223356B4
-:102A8000938F74F5D5D48F1E95A2298F710FD6948C
-:102A9000C715E469F2BD8B6ED5D4EF337BBC269F9E
-:102AA000E8B95B533FA97C9A368F7C0770EF5F3B98
-:102AB00057D36E405D89A69ED357A129673E776B99
-:102AC000663CCA71FE2F75ED524DF9D351053C7E1F
-:102AD000DCB680EE29A6357D4FD39FC46F521CC74C
-:102AE0002F73F0FDC107FF91DF42E0393F41BB6F1B
-:102AF0004CB08F3B66A7546BD748BA411CD4A17F1A
-:102B0000960EAA99960E7AF1389EFCDF0C73A01EE1
-:102B1000A3C73FFA2342D789FE8850B8A03F22348A
-:102B20008FFE88D0FAE88F082D477F4468F9B013EC
-:102B30005AFC8F68D5E2FF960FC6FF433C8D6ED3DB
-:102B4000D2831E4FB77DA6A58FB19E7082CB04D0D5
-:102B5000C790DE259E66C37FB4CFB3A268B41BDCEA
-:102B6000C1DC742FE07F0B5F9775F8FA92AD1B8183
-:102B7000EF5C5EF17239DED33E7F6580FB0B94BB68
-:102B80002942CEEBED00329ED4379EE3D377328CD0
-:102B9000E4D55786B648DC3FBEA3B6915D3E91753D
-:102BA000BC81EFCF0CE9E56159BDF1CA36703F94A5
-:102BB0003FB5E8BE5CDCE7E6FDDA928C7ACDBC017D
-:102BC000FC3D4196D546EFB4C8F9CC4BE2F147D66F
-:102BD0002C21A75D3C0E29228BDB7F225D768A8328
-:102BE000F6663111E7C992E765231DBE1D96817413
-:102BF000B691DBB9DA4C0E8A6BF1013DA29F12F55A
-:102C00006DD487FB0B7DB4E143AB95D31DD3ECEFC3
-:102C100083FC564D1CEE909D764D3EBB3941537F53
-:102C2000E82187A63C3790A9291F76C2A5C98F68DD
-:102C30001DA5A97FCB076E4D7E745B81A6FE6D9F9F
-:102C40001569F249ACE34984E7F8AC141EDFAF081C
-:102C50003B8083E365DE77E2E93E8D3C47C8B86C94
-:102C60008FA063FD796480D94371DE0D89CC45F76F
-:102C700041ACE23CC8B4E7148F88AB96FA3CF369E8
-:102C8000E3AA653C75D779469C5FE47922249EDAF5
-:102C90008DF397F1D45D7817EF4BEAE9F35E817716
-:102CA000FD3A0698F9FDAF86EF9AE91E8B9C9F7E50
-:102CB0005E9B443CE0766BF7EF0F3D20E8AC2DA522
-:102CC000686616D47B16B62782E775E3B9DA7C000E
-:102CD000DF861F985D2B1D371E6FDE50BE9E627C07
-:102CE00057358BDEE9A47B6B72DC6A31EEF41CA5F0
-:102CF000DBF5CD8BE6F15D2CDA4CF72E7A1E8FC317
-:102D000035C1CC1AE99D24710FE18175CDEB3154A9
-:102D1000B3D8DC64E2EFE3FB4D68272A1C0F7A602E
-:102D20002EDA0DDFDF68037DEDD93A23D97D1EDA77
-:102D30003DE63ED020BBEE950C80731AD24921E2CD
-:102D40001FFA3D97CDE39D1FCBE2F2215FFDBAEB69
-:102D50003E804523E7F9F9AF1BBA237A94EBF8BF1D
-:102D6000BA1F20E9570F2779BE6662FF1A28E625A9
-:102D7000E1D7653F11F093F7331C4B4C455B6D7405
-:102D8000CFA300E3CA24FEBECEE674F96616C737A9
-:102D9000D64379D453BD7C352B1AEDE09DCC116D13
-:102DA000BF813DF8FFE8DE04C1BFA7FB5E3DC989D6
-:102DB000EBE4430FF7BF7AA24FFAF72DEE8185C8F7
-:102DC000091EEF23F0E11F6820BFFA9A482D1FFF6C
-:102DD000358BDB5D9E96FB850FCEDD5A39C1D0AEBB
-:102DE000DFB04A15726241D7EF48E0F7F9AB4CA467
-:102DF0005F3356F438C6197CB2D14471B163DD8CAF
-:102E0000F49892CD8A7F8B82FBE898049CBFD7A769
-:102E1000DD8FEF60AED5E8FF285DABFDBED0C67F8D
-:102E20006F62BEFEDD14715E5F7883F3FAD92CE128
-:102E300007723117E95DC2FF5F2EDAE8F5AE4E3F4B
-:102E4000F79BE1795BE576278A1B93FBBB03FD3794
-:102E500021EF81003CC333711F6F34761BCFD70540
-:102E6000CF1EE2152EDA44BC828DC76774EE0FE3E5
-:102E7000FE4DE95712F52FFAAE5239D6C7DE2EE5D0
-:102E8000F2B80BE94FD2FBAB3A6D06F2B774EE8F96
-:102E900024FF3CFA71A2810ECE1BF6C58F7206E7A5
-:102EA000E76953357E107DEA59F1129D17CB533DEA
-:102EB00031D918876D74595D907FC47684DE8F2A6E
-:102EC00014762FFD7CBBCE5D63F8FB2E9D3EAECF0E
-:102ED0007616F07738402E32E42319873095C129D1
-:102EE00015526F6034CDE7DBFA73A65FCBE57ECC7D
-:102EF0006BB7517BCFDAD1941FD0B87E09DE8399AE
-:102F0000D9B0D0842EECB62797E78743D3B6FEFE20
-:102F100095E188B7714AB776F9BC6C85F8A14D1771
-:102F20005F2FD3ADD99C5F7E9D2DE5B888435AA114
-:102F3000101F2C55988C4B22392EF3579B443E9FE3
-:102F4000E797ADE2F936F1BEFE0E6147C175638ABF
-:102F5000EBC673FF6E6167C175638AEBC6EF28B776
-:102F6000308F720BF328B7308F720B53945BF8BD20
-:102F7000841525E7AADC0F353194EFAE59D9C4107A
-:102F80007E413F54681EFD50A1F5D10F155A8E7E2B
-:102F9000A8D072F44385E6D10F155A1FFD50A179D0
-:102FA00036EAAE601EE59C7BAA263F1DF4FC892113
-:102FB000FC8D7EA8D0FED10FA5E9CFB344D3FE7E11
-:102FC00056A7698F7EA8D0FA0FD6291A3FD583E27B
-:102FD0009DD3D24D71443FF31D4535D980DFFF8825
-:102FE000F8EF874D2988E79645FC5C16EEE2786E8F
-:102FF0002AE07837308EE78E3984E7E5669ECFE7A2
-:10300000F1C97AFA417FCF4413F7F7608AFE1E4C6C
-:10301000D1DF8329FA7B26A6717F0FA6E8EFC1EFE7
-:10302000E8EFC114FD3D98A2BF0753F4F7608AFE94
-:103030001E4CD1DF83EDD0DF8329FA7BF03BFA7B96
-:1030400030457F0F7E3F897E2753705EA8C70FD41F
-:103050009C1F810E35E747BB268F7A7C687DD4E3C1
-:1030600043CB518F0F2D473D3E348F7A7C687DD402
-:10307000E343F3BFCC72109FA13E1FDA0EF5F9D0E7
-:103080007C7693EF0DB49D4DDE7CF918A66D91CA48
-:10309000B30A888CE6ECF7EE433F5D5B98921C0325
-:1030A00092D3B4E2C3FB2682BEE611F17F39ACC3F2
-:1030B00080F8F688F7D43D0146F196D97F4BA4F20B
-:1030C000CB78AF5FC4DB22DE73F733FA5D12E92FF2
-:1030D00096ED5DCCAE622AEB07F3DDD7D38F2FEBF5
-:1030E00091FC0C9907DE00C67895DCE5B63C8CF7C0
-:1030F000DC6150284E62C74A1E27ACA7AB33424F53
-:10310000DA61D87704EF81747815BA0F9C6E642762
-:103110004C7908A7DA3CDC7FDFCE8E11EBAABD1517
-:10312000EF9BC8794BFB26C809BA3F37A6A3754267
-:1031300034F4E3F18DA3DF49293473BD01DBE17978
-:1031400072884F716F0DA1EFF785DCF4F8F8F83F46
-:103150007F6E0A6F17CEDBFDFCB92882E3944685AB
-:10316000E2A5C6EC666EBC9FFB1F429E0ED91D50A9
-:10317000713C6F231F4FF6EBDD9C4CF716BDAC6D19
-:103180006202F9481486725BC20DD6770CD707C766
-:103190008613689FBED97B3FB70F8FC9C7383AD611
-:1031A000C2E81DCBC9C3DFD5AC97D03E92FAA57D4E
-:1031B0002DC3A7D07BC1537C2B56E2B63ED9B7E4D2
-:1031C0008DDE587F1B73391DB415D1BD58399FC191
-:1031D000EE7D06D81659166B358429886F76342E05
-:1031E000847E80F36720BE735D267ABF77AAD16E96
-:1031F000A2F7237A883FB96A93F1273A7D4117678E
-:10320000D2B0FC8364B4272F8D3490FD77E94BFC5A
-:10321000F7003C9B14926B520FF28A38B5AB8D6F5E
-:10322000F49E8570DF67A2FE64FC4975AA3FD980D1
-:1032300071F57DB7E4C4AAA407C4E6A01EE0FBD5DF
-:103240007DA3B0DE2AFE8EE5D5C699D101EA89FBC1
-:103250006BCA04BCCA441C93171FF45683BF8B254A
-:10326000EF77B026AEEF497B8EF7B7C38E237EBDD6
-:10327000CF8877A5D77AE95EB63E8E6851A389E2FA
-:103280008E16E9F4C24AA11756DE402F1C9CA3D328
-:103290000BE5EFA588364CEDF73EC6EDC97B89C539
-:1032A00026CEFFC5FB18D9618B574C30D03BC82FB9
-:1032B00071BA295EC1F59BE297DD74BF50EA8BEFCE
-:1032C000083D66DAB52482FB1F84DE3213E32B014E
-:1032D000BE856D61220E2B91D259D778BCE5341B87
-:1032E00097036DAFF177203A7D16AE4F1D63FC1D3D
-:1032F000331D5D4E35FA0D78E1CE3506E812F293B6
-:10330000510F82FE66A35E148774EECCA7F8BD024F
-:1033100085EEBDE8E9BCD054FB06C687166E672E65
-:103320001F0BA573A05FECCFA7D0FB001E71AE955D
-:10333000F4ABA7F77911C21E65E3F6A62EBB04EA2B
-:10334000A8F44877CE2CD41BE7A16FAF2F27188C99
-:103350003B8BCCE2E5653939B31AF190D3839D42BA
-:10336000FD9E99E0E191EF20F46037407B01CAC9EE
-:10337000071ECA359784C8C9E1AEF18D434704F1F1
-:103380005DD275DF2F8BDE055DFA481AFD1E4E4FAC
-:10339000FA7029C015F9625E74DBC3F80B6B0D3946
-:1033A000CC3D31017F2750AE8F05308E70AEC837CF
-:1033B000EFBDEF4F6B6D0417CAD7E78C998571216C
-:1033C000D5D6B649487635599E02BCC718944F45A4
-:1033D000EE2405E5536E00CF849BE4FD649D3DA281
-:1033E0003987D7D7DB254AB3B8DC96BF8B72EA9111
-:1033F000837B71BF92F33FD5C3EF30ECCCE1F2F7A2
-:103400007FEB1E84FEFEC32FFB7A9ECC81753C6E43
-:10341000E0F7F9FBAA4D4CD887C82F2CE50513EF30
-:103420006004F1EEA677741B1E51ECA1F629CF5A69
-:1034300085DFA3EFC18EC3323B9EDC0EEDE6D59B4C
-:10344000E9F7F89E4BE7F4F31CD00FFD5E8AB9F55F
-:103450000DAB3308C78FEB7E6AA2DFA56181347C98
-:103460007F676E6D980BE5F17057D12F71DE1159A2
-:103470002E92438D18430EF9BB7A15BD88DFABD76A
-:103480001D7E16DF13A86971D2EF95780FE5AEC6E1
-:10349000774E86BB3C07B1DC6BB3D37B1A8B1B63C7
-:1034A00068FF9AD747DC0B651DE46793F07F47D828
-:1034B000AFD6BA38FD5E11E70E14905335F5BAB7A2
-:1034C000E3493BA1DECEA07F5FA227FB82B427A009
-:1034D000FDC01C626794F60953E6A939A837149B0E
-:1034E000B5F71265CA86F27D5F9E03E777ED5B59FB
-:1034F00093FAA07EBC41B1D37B9336C7ACD1902F59
-:103500003B61C2C84E5618EB30E3FB031D805F8C55
-:103510008F2E017E4539532CE2B4CA368D267E2B80
-:10352000F343DACD3B9C32BD7FC3D1FE2F23FD0494
-:10353000DCE4B72CB3BBCDB1217C5FDAA468DE1D1F
-:1035400090F98E1C95F311A8E308BF071E729AF13B
-:103550006D9F62502330FE8F0D7568FCC7508FE25F
-:10356000410A53D871FE0E3CCCDBC9C7CB0BE9BF77
-:10357000A489DF9B9679A84FFACFDF732209AE5E4C
-:103580003BACDB89A99DE60970203875AC87FE1C31
-:10359000340EE1A334E037E179BB18E350203FD784
-:1035A000EE37E138258DFC1D13CF3A3E8E676D8CCA
-:1035B000391BF523A3DDDC1FE1277E6F15E6477A73
-:1035C0006419C005EF63E17D37DC5BF4F0F18AF943
-:1035D0009635C5D03B0AC1EF1B4C888F393DBC8B5B
-:1035E000903594D36D49E338BABF5E6674D33D0716
-:1035F0008F80EF274BC21E45FFC09C8D4F989C903B
-:10360000EF3794D36FD6504E5F852981347AAF68F7
-:1036100049980BE739C7DE44EBEB82EF63000F05F7
-:10362000DFB92922F8025DF8306EAF6CA3169FC196
-:10363000F970F8966DF412BF2D307ACCF6D0796C13
-:103640003A9C86F7AAE6007FE3BB12CCEEA1FB9280
-:103650009F3E362B99D609F344B846BA1C93F0FD29
-:1036600021A0137E0F46AC47DEEB96E34D1CCAEF5C
-:103670009D4E1CCAE567CF7CE926BDA601F08B767E
-:10368000EF9EF8D28C821BC63597F1DF91D0F3A95B
-:10369000E44FC997924F25FF3E6B2A0A24284139EF
-:1036A00003FB6CED8BDDC0A951CC77AEC02BC0F510
-:1036B00058E83DAF6A81D7E2142DBF637FD8EF1C75
-:1036C000C1EFC5E30369F82E93AC2FC72D8EE5ED4E
-:1036D00090EE91DEE688F1B0FE52AAAFBDA752DAB5
-:1036E000252F76AF8A4779B14FE17ED0F547FB7F32
-:1036F00007F5D73D5C7FBD50B57D31EE97CCE84FE7
-:103700000E7DDF7F3EE83928271688FDB92CD0BD15
-:10371000BCB890EEA9181AC2CF653FDB93EEE1F278
-:103720002680F2E6CF7B5EFDE3AD8EE07E2AD753A6
-:10373000B2F65D93D7160A3FBEFE47333BE93E5EC5
-:10374000A9CDECC078E7D2462FC95F96007AA112C6
-:10375000127FA6A30B6FA342F7C84AEB46FAD5FF28
-:1037600045395DBA6E2ABD7B20F126DF6791FBAB40
-:103770009CFF7A31FF2621DFE60AFA9E5B3ECE9C53
-:10378000D88BF46E0CB36473C4F73965DAEF5D78E7
-:10379000EBF25F67AD467EC1FB45743E5967E2F6CA
-:1037A000BEDDDCFE7861E9C1DFDD07F5CE3FBE2579
-:1037B00099A95ABCA19EBA40E8AB0B85FDAF1BBCD2
-:1037C0006D19DA3B985FF81CC75BE9DEDFFE05DFA9
-:1037D000132B4E11F26E3D7F07A0A4791FE171CE2D
-:1037E000DA0D2627D4DB37D44970EA92FFB5B976D3
-:1037F000B42BCF5DBBC58472629F84838E1F8A45C4
-:103800009CB08433EE4B4A887F43D647F988EFDF7C
-:103810003FB4242C0AE379E4381F093A2FAD8D898F
-:10382000C5F14A6BBD3FC6F390DC0FF4EB3C1DC6FF
-:10383000F9A504FA43BE3D3DCE95BC342BA8CFEA92
-:10384000EBBF2BF0F8B489FF4E4D5244F32E8A6B38
-:10385000A80977A1FC1838B0CD8FE3227DE3BCCD59
-:1038600006FEBB3603ABDA3EC77980AA4D713598A8
-:10387000E2FB58A87AC7437EAB81DFDF4A5179FA71
-:103880009590D7501EC072D6AB8D7E5F23246E56A6
-:1038900043BF66B68D7E3FD1DC8BD1FB66925E6501
-:1038A0003F925E253DF7B4BE2B42AEDC687DA79DFE
-:1038B0001C9E66F1BB2937BD3E0BFF1D5DB92E393D
-:1038C0003FD0E1DDF4BEC7F7B3C9DE737A852B19AB
-:1038D000E3267B5EEFC6FCF86ED6AB5FA7E41B1950
-:1038E0000BDFE5CF6AE27E87D30AEC6FD0EEF4926D
-:1038F000308A6F93EBD2DBC3FF1FB640B5F6008072
-:10390000000000001F8B080000000000000BCD56D7
-:103910007D6C5355143FF7BE7EAFDDDEBAB1751B2B
-:10392000DBBA8D8F46BAF1CA80F891681D8CF0C75A
-:10393000A2DD14DD0C6C25B031C68A9360A8C6B830
-:10394000B2229211E24C3618044C876C7F18205D2D
-:10395000208AB19A8689468311E11F1292A60B38FC
-:10396000D16856310A44649E73DF2B9D08897FFA23
-:1039700092E6F4DE7B3E7FE7E3DE0F7A658085002A
-:10398000C77B1D00468093BD4E41A3BD2EB19FA7AE
-:10399000D801E6007E495B930D60AD05DA7C565C8C
-:1039A000C6F1970F9008568DF4B3CC7E831DDA9A3A
-:1039B0009026E4A4CDEEC67DBBBA7FADC7DC0F393F
-:1039C000002D90DCE7588AB2C12A1845538981AB93
-:1039D000368E7C579F463E77466EBB3EB51E88CFDF
-:1039E00066708E5600646DFFAEBE10EDB50F567852
-:1039F00018CAAD0BD6268278BE6E57A102B86EB734
-:103A00003A773BE83C54A1F4E13A6BD033358CE78C
-:103A1000EDBB1629C4BF9D812F4A7E0F1C002800D4
-:103A2000E8807B9FD7B41C6013FD43BE4D56C32472
-:103A3000ABC1F3E0C43C19E53B14B387A1FD4DC312
-:103A40002C6EC4FD060E7BD81280F2B06F5511DAD1
-:103A50004B1D64CA51923D5CEF4D9A5485339500DD
-:103A60005D0B7D35CA325CDC99999941FD8F20460A
-:103A700020515C512FC501434C1E05F2DB67207CB1
-:103A80004E2C760A9C13839336A75BC5BB11F106B7
-:103A900047010794DF6652FD2B37A426DF46BF524D
-:103AA00036AE1CC575BDE4FED649717E2581D1496F
-:103AB000721ABFACF1BFF9A8C98FFAB6D92A0B01A7
-:103AC000E9C66174A216CF9A4D9C70E8D47C6E1F33
-:103AD00079AE00D08F763C77E2F921DA7C0C60F782
-:103AE000E08A8224C9BD5BBF3F540D50A6E1784DEA
-:103AF000976CA4FC5C1F29B4EFC4D83606C20B0037
-:103B0000CF378EBC5D46F4FA88B939827C2BE5C686
-:103B100095B9186FC7E15C8F84FECCD0F714E64DE1
-:103B20004121C4A72BB0A21010AFEEBB13EFC955B3
-:103B3000681FB126DC7F8F664542C8D2DD7BA64C6C
-:103B4000E2E88AD1DF4C786EE1B1171E433D3FB108
-:103B5000C85891E07716CAD68CDEFBE9542FC28094
-:103B6000F51C78F3B2D0F30B3FFF4C0BCA77074E2E
-:103B700065939E2D439796CBB8DF59E5DFA8CC21FE
-:103B8000BD2363324204C323353E8CA35D01E1674C
-:103B900083DDF7420BE1FE9524707F98BDCE334C58
-:103BA000E07B2FCE488E8170F7C7C1201395C140AE
-:103BB000F57D5D8260146943A5DA2FE9FD20E1827D
-:103BC0007E5CCF1928A3BAD83C76A0CC89F4479B59
-:103BD000BA5E3BF6E2D7908DFCC78C06CA975F07AA
-:103BE0000605E5368498374275D389FD5A94B1DFCE
-:103BF000A764097D9B87D1A9BCCC3E4044C4F5A3F2
-:103C00000E56931FE5E194E715A45774F176CAEBBD
-:103C1000951EB312AAA03C3905DF95016915ED8701
-:103C2000B091E6335A9FB2CD43FBAD39D043F2B6E3
-:103C3000A5D138C73C074EE72E91D49212F5B55561
-:103C40005617F5927555099E6F1B6732D5E9B68FE9
-:103C5000CFAD02750DC01E8E67D7AD27C039CBEF33
-:103C6000AED3E306EA8FEEE3182FDAEF8E8E7F51A4
-:103C70008C7AB69E595FABDA1D00AAFF80D6CF5B67
-:103C80004FABB8044E4F1A36B8337AD6BBECBB4BA9
-:103C900030B7A34AEB8B43C8BA9EF2F63840EC64C7
-:103CA00063F3CE79486B641137E852653EECC37E0E
-:103CB000D74503F5516097A6CF757177A588B731C1
-:103CC0000F66D5C398A217726979C443C8C5039615
-:103CD0003DB01887CD56AB8E683860CD267AB88750
-:103CE000BB7488AB97591409F10E9AB26B684EDE1B
-:103CF00034AB346651E90EEE1BEF40176FF20B66E2
-:103D0000C0BADF210D30A24FB97B18220D8BF2FD16
-:103D100031AA5F0744190820E28CFC9EFEF4875A02
-:103D2000B2FF6479F2374097F43BDB9A57627D7CAF
-:103D3000AE68F1B993B554E773CEAA73FA881EF64C
-:103D4000989750DC3E68AA262DF89FF27E9B476824
-:103D50000EC758FC7DD29F8EF796D6C73EA3750F2F
-:103D6000433F1B9CFE6FC88F6799BEDAC32907D2F9
-:103D70007CD23FAD57CF71FE7A4D581775DAF02DD2
-:103D8000E510022C5943B1C34A75CDBC5E08A2FDB3
-:103D90003EF7D90D541F7B532630A2DDB086475D18
-:103DA000CA32C990AFB47835079CC7CC994F770C0D
-:103DB0009C75F39011FDDC0BA608F18309E7B12B8C
-:103DC000338F0DDCEC15FCB12F6FD37C2F917E9DD2
-:103DD000C841FE921D4C09234FEB8DA923DF225DC4
-:103DE0000B110FE1DA95EF9FA2381237564FFA31D7
-:103DF000BF7BE5A84971ABFA66FB1F7BED76B69DEC
-:103E000067FC9A4E4D9DF868295193B877EA629203
-:103E1000B837EEF767DAE1D4911DE48B73E2B7F2BD
-:103E20000863C43F7199FCAB3359E35236C9E97F4B
-:103E30009E7DAFC085D2DCA945E22A8199129CF60D
-:103E400061356F4F6A7D98CE8B85C05F4654CD4FEC
-:103E50001A3FE1FCACFBE433EBD83AAA9F74BFBE37
-:103E6000ACEDDFB8559943F3E546AC2A07DC0FEF1C
-:103E7000CF4B385FE99D70B8C26BF72CCBDCA76BDA
-:103E8000D2B7AB76DF4A9ADE351A4E6BAC5CC5E52D
-:103E9000F9FB70D1EA245D0769BFD3794EE70F5E65
-:103EA000BF702EA742E4ADFA1D10F99A4BF613B776
-:103EB000CFBF856D05C59277D25FF17FCC57DCBC53
-:103EC00090DE0D435CBC1B4A09F825827A39C6078F
-:103ED0002E10F3A055B228FD0F98077E9A078B6924
-:103EE0001E0C883EBFC953E738A379D023D60E48AD
-:103EF000EDD4E13AC19336F23769C6AA47EAF754DE
-:103F00008A7BA0843ABA4ACD13F5F591D76C47E97C
-:103F1000FD1666DE8326940FEBB57EDF6C8D8CE29A
-:103F2000FE748487F4686F303772B003F707D7CC1C
-:103F3000554288D334687C9D1631179EE05CAC53A3
-:103F40002D0591A315C48F7D8D710EB63C22EEF127
-:103F50000FEF4AE2BD989A0FEAB907160CD379A37E
-:103F60004BE8FB243D67F6D984BEC1466F91459C62
-:103F70001770928FE4F95FA2FC164B2A1F3E0404CF
-:103F8000DFA143DE22CAC7A12683E0DBCF7C2DED73
-:103F9000A4A7DAAAD0FB32D9623939A6A623CE96D5
-:103FA000D27B558D375DBFC30B64814B7968F2209E
-:103FB000BD434275E0EAA1F72BD5E1E24C7E9817AC
-:103FC0007361CFE4295D8F213DE62B5FCD571FFB49
-:103FD00077BEF2B57CB120D66D36E52D2AF0BFC98B
-:103FE000D53CEC9020998531495C711891FE91EF98
-:103FF0007F558DF342119DB71A93CB06E85DCCA196
-:1040000033FA803E0C519F8BF739DEA258E76D5A88
-:104010009DB7A5EBF18DFBEA313937772A4BAB47DA
-:1040200094FFDEE2EB237BBFB04BCB69F3FC5F5226
-:10403000F383ECECD5E6C89F467FBFE8F36385FFCA
-:1040400078679EF7FC504AF70CDC99984BF7CE99AD
-:104050003CDF3EE233CF4B19FC8467514A4FF124D9
-:104060005A7E2AA5F74C5BF04BD137FFD5CFB41F52
-:104070007F03DC4DE081B00C000000000000000078
-:1040800000000018000000000000000000000040D8
-:1040900000000000000000000000002800000000F8
-:1040A0000000000000000010000000000000000000
-:1040B00000000020000000000000000000000010D0
-:1040C00000000000000000000000000800000000E8
-:1040D00000000000000000000000000000000000E0
-:1040E00000000000000000000000000000000000D0
-:1040F00000000000000000000000000000000000C0
-:1041000000000000000000000000000000000000AF
-:10411000000000000000000000000000000000009F
-:10412000000000000000000000000000000000008F
-:10413000000000000000000000000000000000007F
-:10414000000000000000000000000000000000006F
-:10415000000000000000000000000000000000005F
-:10416000000000000000000000000000000000004F
-:10417000000000000000000000000000000000003F
-:10418000000000000000000000000000000000002F
-:10419000000000000000000000000000000000001F
-:1041A000000000000000000000000000000000000F
-:1041B00000000000000000000000000000000000FF
-:1041C00000000000000000000000000000000000EF
-:1041D00000000000000000000000000000000000DF
-:1041E0000000000000000000000033280010000064
-:1041F0000000000800003330001000000000000242
-:1042000000003328001000000000001000003A7881
-:104210000000000000000008800000000000000016
-:10422000000000008000000000000000000000000E
-:1042300080000000000000000000000000003120AD
-:1042400000000000000000080000336000010004CE
-:1042500000000001000033680000000000000002C0
-:1042600000003370000000000000000800003374FC
-:10427000000000000000000200003A700000000092
-:104280000000000800003A4000080000000000089C
-:1042900000003D88004000000000004000003A504F
-:1042A000000800000000000800003A60000800005C
-:1042B0000000000800003A8800C8000000000098D4
-:1042C00000003C18009800000000002800003C5846
-:1042D00000980000000000280000337803600030E0
-:1042E0000000036000003EB0000800000000000174
-:1042F00000003EB10008000000000001000020089E
-:10430000001000000000001000002000000000006D
-:104310000000000880000000000000000000000015
-:10432000800000000000000000000000000000000D
-:10433000000000000000000000000000000000007D
-:10434000000000000000000000000000000000006D
-:10435000800000000000000000000000800000005D
-:1043600000000000000000008000000000000000CD
-:1043700000000000800000000000000000000000BD
-:10438000800000000000000000000000800000002D
-:10439000000000000000000080000000000000009D
-:1043A000000000008000000000000000000000008D
-:1043B00080000000000000000000000080000000FD
-:1043C000000000000000000080000000000000006D
-:1043D000000000008000000000000000000000005D
-:1043E000800000000000000000000000000000004D
-:1043F00000000000000000000000000000000000BD
-:1044000000000000000000000000000000000000AC
-:10441000000000000000000000000000000000009C
-:10442000000000000000000080000000000000000C
-:1044300000000000800000000000000000000000FC
-:1044400080000000000000000000000000000000EC
-:1044500000000000000000008000000000000000DC
-:1044600000000000800000000000000000000000CC
-:1044700080000000000000000000000000000000BC
-:10448000000000000000000000000000000000002C
-:10449000000000000000000000000000000000001C
-:1044A000000000000000000000000000000000000C
-:1044B00000000000000000000000000000000000FC
-:1044C00000000000000012C8008000000000008012
-:1044D000000000010000000000000000000040009B
-:1044E0000490000000000490000019C800000000C3
-:1044F0000000000800004948000800000000000813
-:1045000000004928000800000000000800004938A9
-:104510000008000000000008000020080010000053
-:104520000000001000002000000000000000000853
-:104530000000401004900040000000400000499836
-:104540000008000000000001000049990008000078
-:1045500000000001800000000000000000000000DA
-:10456000800000000000000000000000800000004B
-:1045700000000000000000008000000000000000BB
-:1045800000000000800000000000000000000000AB
-:10459000800000000000000000000000800000001B
-:1045A000000000000000000080000000000000008B
-:1045B000000000008000000000000000000000007B
-:1045C00080000000000000000000000080000000EB
-:1045D000000000000000000080000000000000005B
-:1045E000000000008000000000000000000000004B
-:1045F00000000000000000000000000000000000BB
-:1046000000000000000000000000000000000000AA
-:10461000000000000000000000000000000000009A
-:10462000000000000000000000000000800000000A
-:1046300000000000000000008000000000000000FA
-:10464000000000000000000000000000000000006A
-:10465000800000000000000000000000800000005A
-:1046600000000000000000008000000000000000CA
-:1046700000000000800000000000000000000000BA
-:104680000000400000180000000000180000430077
-:104690000040000000000040000043000040000215
-:1046A0000000000100004301004000020000000083
-:1046B00000003000004000000000004080000000CA
-:1046C0000000000000000000000030000008004072
-:1046D0000000000400003004000800400000000456
-:1046E00000004B00002800000000002800004B5094
-:1046F00000100000000000100000380000800000E2
-:104700000000008000003800000800800000000267
-:1047100000003900002000000000002000002008F8
-:104720000010000000000010000020000000000049
-:104730000000000800005108000800000000000808
-:104740000000512000080000000000080000513067
-:104750000008000000000008000051C00008000030
-:1047600000000001000051C100080000000000012D
-:10477000000039400010000400000004000051D087
-:104780000030001800000010000051D80030001860
-:104790000000000280000000000000000000000097
-:1047A0008000000000000000000000008000000009
-:1047B0000000000000000000800000000000000079
-:1047C0000000000080000000000000000000000069
-:1047D00080000000000000000000000080000000D9
-:1047E0000000000000000000800000000000000049
-:1047F0000000000080000000000000000000000039
-:1048000000000000000000000000000000000000A8
-:104810000000000000000000000000000000000098
-:104820000000000000000000000000000000000088
-:104830008000000000000000000000008000000078
-:104840000000000000000000000000000000000068
-:1048500000000000000023E800800000000000804D
-:10486000000000010000000000000000000020081F
-:1048700000100000000000100000200000000000F8
-:104880000000000800002DA0000800000000000843
-:1048900000002DB80008000000000008000024E817
-:1048A00002D00028000002D000002E5800080000AE
-:1048B0000000000100002E59000800000000000167
-:1048C00000002D900008000000000008800000009B
-:1048D0000000000000000000800000000000000058
-:1048E0000000000080000000000000000000000048
-:1048F00080000000000000000000000080000000B8
-:104900000000000000000000800000000000000027
-:104910000000000080000000000000000000000017
-:104920000000000000000000000000000000000087
-:104930000000000000000000000000000000000077
-:104940000000000000000000000000000000000067
-:104950008000000000000000000000008000000057
-:104960000000000000000000000000000000000047
-:1049700000000000800000000000000000000000B7
-:104980008000000000000000000000008000000027
-:104990000000000000000000800000000000000097
-:1049A000000000000000250000400000000000089A
-:1049B000000025080040000000000028000009C099
-:1049C000012000100000000880000000000000002E
-:1049D0000000000080000000000000000000000057
-:1049E0000000402002D00028000000080000300035
-:1049F00000000000000010000000509900000000BE
-:104A000000000001000050B00000000000000002A3
-:104A1000000045A000900008000000088000000091
-:104A200000000000000000000000296000080000F5
-:104A300000000001000029610008000000000001E2
-:104A4000000029700008000400000002000029781E
-:104A5000000800040000000400002FB0000800005F
-:104A60000000000400002FB4000800000000000453
-:104A700000002FC0000000000000000800002FC848
-:104A800000000000000000080000300000000000EE
-:104A90000000001000005040000100010000000173
-:104AA0000000500000000000000000200000080886
-:104AB00000100000000000040000080C00100000BE
-:104AC00000000001000008B7000000000000000125
-:104AD000000008B600000000000000010000100007
-:104AE000003000180000000400001004003000181E
-:104AF0000000000400001008003000180000000250
-:104B00000000100A00300018000000020000100C25
-:104B100000300018000000010000100D00300018E7
-:104B2000000000010000100E00300018000000011D
-:104B300000001010003000180000000400001014E5
-:104B40000030001800000004000030000100008068
-:104B50000008000400003004010000800008000488
-:104B60000000000A000000000000000000003068A3
-:104B70000100008000000001000030690100008099
-:104B8000000000010000306C010000800000000205
-:104B90000000306E01000080000000020000307054
-:104BA000010000800000000400003074010000805B
-:104BB00000000004000030660100008000000002D8
-:104BC000000030640100008000000001000030603F
-:104BD000010000800000000200003062010000803F
-:104BE00000000002000030500100008000000004BE
-:104BF0000000305401000080000000040000305824
-:104C000001000080000000040000305C0100008012
-:104C1000000000040000307C010000800000000162
-:104C20000000307D010000800000000100001C1821
-:104C3000001000000000000400001C300010000004
-:104C40000000000400001C380010000000000004F8
-:104C50008000000000000000000000008000000054
-:104C600000000000000000008000000000000000C4
-:104C700000000000800000000000000000000000B4
-:104C800000004C10000800000000000200004C1260
-:104C9000000800000000000200004C1400080000A2
-:104CA0000000000400004C20000800000000000884
-:104CB00000004C30004000080000000800004C00DC
-:104CC000000800000000000200004C020008000084
-:104CD0000000000100004C04000800000000000279
-:104CE00000004CD0000800000000000800004CE06C
-:104CF000000800000000000400004CE40008000070
-:104D00000000000100004CF000080000000000025C
-:104D100000004CF4000800000000000200004D00FC
-:104D20000008000000000004000050000010000017
-:104D30000000000400005004001000000000000407
-:104D400000005008001000000000000400001400E3
-:104D5000000800000000000200001402000800002B
-:104D60000000000100001404000800000000000220
-:104D700000001410000800000000000200001414DD
-:104D800000080000000000020000141600080000E7
-:104D900000000002000019B8000800000000000830
-:104DA000000014200008000000000002000014248D
-:104DB0000008000000000002000019C80008000000
-:104DC0000000000800002C10000800000000000196
-:104DD00000002C11000800000000000100002C124F
-:104DE000000800000000000100002C130008000073
-:104DF0000000000100002C0000080000000000027C
-:104E000000002C02000800000000000100002C043B
-:104E1000000800000000000200002C300008000024
-:104E20000000000200002C32000800000000000218
-:104E300000002C34000800000000000200002C20BC
-:104E4000000800000000000100002C210008000004
-:104E50000000000100002C220008000000000001FA
-:104E600000002C23000800000000000100002C249A
-:104E7000000800000000000100002C2500080000D0
-:104E80000000000100002C260008000000000001C6
-:104E900000001400000800000000000200001402DE
-:104EA00000080000000000010000140400080000D9
-:104EB000000000020000141200C0001800000002F0
-:104EC0000000141000C00018000000020000141CB4
-:104ED00000C00018000000080000141400C00018F2
-:104EE000000000080000142700C0001800000001A6
-:104EF0000000142400C00018000000020000142666
-:104F000000C000180000000100001590000800001B
-:104F100000000008000015A00008000000000008C4
-:104F2000000015B00008000000000008800000002C
-:104F300000000000000000008000000000000000F1
-:104F400000000000800000000000000000000000E1
-:104F50008000000000000000000000008000000051
-:104F600000000000000000008000000000000000C1
-:104F700000000000800000000000000000000000B1
-:104F80008000000000000000000000008000000021
-:104F90000000000000000000800000000000000091
-:104FA0000000000080000000000000000000000081
-:104FB00080000000000000000000000080000000F1
-:104FC0000000000000000000800000000000000061
-:104FD0000000000080000000000000000000000051
-:104FE00080000000000000000000000080000000C1
-:104FF0000000000000000000800000000000000031
-:105000000000000080000000000000000000000020
-:105010008000000000000000000000008000000090
-:105020000000000000000000800000000000000000
-:1050300000000000800000000000000000000000F0
-:105040008000000000000000000000008000000060
-:1050500000000000000000008000000000000000D0
-:105060000000000000000000000000000000000040
-:1050700080000000000000000000000000000000B0
-:08508000060209000000000017
-:00000001FF
--- /dev/null
+++ zfcpdump-kernel-4.4/firmware/bnx2x/bnx2x-e1-7.12.30.0.fw.ihex
@@ -0,0 +1,10640 @@
+:100000000000165800000068000005D8000016C85F
+:10001000000031D400001CA80000006C00004E80DD
+:10002000000076EC00004EF00000009C0000C5E0EF
+:100030000000C9800000C680000000880001900810
+:1000400000003C1800019098000000880001CCB826
+:100050000000B9680001CD480000120C000286B80B
+:1000600000000004000298C8020600DC0000000145
+:100070000306100002000000010600D80000000086
+:100080000306020000030200020600DC000000007C
+:1000900002060068000000B80206007800000114A3
+:1000A000010600B800000000010600C800000000C2
+:1000B0000206006C000000B80206007C000001147B
+:1000C000010600BC00000000010600CC000000009A
+:1000D000020D004400000032030D004C0004020336
+:1000E000040D005C00000004030D008C00110207E9
+:1000F000020D015C00000001030D01640002021802
+:10010000020D020400000001030D020C0003021A9C
+:10011000030D02200002021D040D028000000012E7
+:10012000030D03000018021F040D03600000000C03
+:10013000040D400000000A00030D0004000F023708
+:10014000020D01140000000D020D01180000002D29
+:100150000310100000030246021010100000026499
+:10016000071011000010024908101140000000089B
+:100170000710116000100259081011A000000018AB
+:1001800007101800020002690210101000000000A1
+:1001900004104C0000000100021040280000001074
+:1001A000031040400002046902104058002800007B
+:1001B000021040840084924A02104058000000005F
+:1001C000030C20080003046B030C201C0004046EC5
+:1001D000030C203800110472040C207C0000004F36
+:1001E000030C21B800110483040C21FC0000000F53
+:1001F000030C223800040494010C22480000000083
+:10020000010C224C00000000010C225000000000F4
+:10021000010C225400000000010C225800000000D4
+:10022000010C225C00000000010C226000000000B4
+:10023000010C226400000000010C22680000000094
+:10024000010C226C00000000010C22700000000074
+:10025000010C227400000000010C22780000000054
+:10026000010C227C00000000020C24BC00000001F4
+:100270000A00000100000001020C2000000003E859
+:100280000A00000100000002020C20000000000A29
+:100290000A00000100000004020C20000000000120
+:1002A0000520040000860000062007800010049846
+:1002B000042200000000160004228000000000401C
+:1002C00004223BD000000008042248000000000681
+:1002D000032248180004049A042248280000000C55
+:1002E000032248580004049E042248680000000CC1
+:1002F00003224898000404A2042248A80000000C2D
+:10030000032248D8000404A6042248E80000000C98
+:1003100003224918000404AA042249280000000C02
+:1003200003224958000404AE042249680000000C6E
+:1003300003224998000404B2042249A80000000CDA
+:10034000032249D8000404B6042249E80000000C46
+:1003500003224A18000404BA04224A280000000CB0
+:1003600003224A58000404BE04224A680000000C1C
+:1003700003224A98000404C204224AA80000000C88
+:1003800003224AD8000404C604224AE80000000CF4
+:1003900003224B18000404CA04224B280000000C5E
+:1003A00003224B58000404CE04224B680000000CCA
+:1003B00003224B98000404D204224BA80000000C36
+:1003C00003224BD8000404D604224BE80000000CA2
+:1003D00003224C18000404DA04224C280000000C0C
+:1003E00003224C58000404DE04224C680000000C78
+:1003F00003224C98000404E204224CA80000000CE4
+:1004000003224CD8000404E604224CE80000000C4F
+:1004100003224D18000404EA04224D280000000CB9
+:1004200003224D58000404EE04224D680000000C25
+:1004300003224D98000404F204224DA80000000C91
+:1004400003224DD8000404F604224DE80000000CFD
+:1004500003224E18000404FA04224E280000000C67
+:1004600003224E58000404FE04224E680000000CD3
+:1004700003224E980004050204224EA80000000C3E
+:1004800003224ED80004050604224EE80000000CAA
+:1004900003224F180004050A04224F280000000C14
+:1004A00003224F580004050E04224F680000000C80
+:1004B00003224F980004051204224FA80000000CEC
+:1004C00003224FD80004051604224FE8000000065E
+:1004D000032251980004051A022380000000001036
+:1004E00002238040000000120223808000000030C0
+:1004F000022380C00000000E022383800007A12099
+:10050000022383C0000001F402238BC0000000011D
+:100510000A00000200000001022383000007A1205E
+:1005200002238340000001F40A00000200000002E0
+:10053000022383000000138802238340000000058B
+:100540000A000002000000040223830000000138BA
+:1005500002238340000000000524000036A30000B1
+:100560000524800005710DA9062489C06D2E051E85
+:100570000120000000000000012000040000000035
+:1005800001200008000000000120000C0000000015
+:1005900001200010000000000120001400000000F5
+:1005A00003200020001A0520032000A40002053AC1
+:1005B000022002240000000002200234000000009B
+:1005C0000220024C00000000022002E40000FFFFB5
+:1005D000082020000000080004221400000000028F
+:1005E00004221490000000300422390000000010A2
+:1005F0000422510800000002042251A80000000655
+:1006000004221408000000020422155000000030EB
+:1006100004223940000000100422511000000002A2
+:10062000042251C00000000604102400000000E075
+:100630000310201C0002053C021020C00000000135
+:10064000031020040002053E02170008000000020B
+:100650000217002C000000030317003800020540B9
+:100660000317004400060542031700600005054813
+:10067000031700780002054D021700040000000F68
+:100680000410806800000004021080000000108048
+:1006900004108040000000020410802800000002C6
+:1006A0000210803800000010031080400002054F47
+:1006B00002108050000000000210810000000000C5
+:1006C000041081200000000202108008000002B522
+:1006D0000210801000000000021081080001FFFFDE
+:1006E000041082000000004A041081400000000253
+:1006F0000210800000001A80041090000000002406
+:10070000041091200000004A041093700000004A79
+:10071000041095C00000004A021080040000108000
+:100720000410804800000002041080300000000225
+:100730000210803C000000100310804800020551A8
+:10074000021080540000000002108104000000002C
+:1007500004108128000000020210800C000002B585
+:1007600002108014000000000210810C0001FFFF45
+:10077000041084000000004A0410814800000002B8
+:100780000210800400001A800410909000000024E1
+:10079000041092480000004A041094980000004A97
+:1007A000041096E80000004A0200A468000AFFDC7A
+:1007B0000200A280000000010300A294000405537F
+:1007C0000200A4FCFF000000030100B40002055772
+:1007D000020100DC000000010301010000020559D4
+:1007E0000201007C003000000201008400000028AB
+:1007F0000201008C00000000020101300000000432
+:10080000040101380000001102010328000000006B
+:100810000201055400000030020100C40000000184
+:10082000020100CC00000001020100F800000001FC
+:10083000020100F000000001020100800030000011
+:100840000201008800000028020100900000000062
+:1008500002010134000000040401017C00000011C9
+:100860000201032C000000000201056400000030BA
+:10087000020100C800000001020100D000000001D8
+:10088000020100FC00000001020100F40000000170
+:1008900002140000000000010214000C000000011E
+:1008A000031400400002055B0214000C000000006D
+:1008B00002140000000000000214006C00000000A0
+:1008C00002140004000000010214003000000001C6
+:1008D00002140004000000000214005C000000008C
+:1008E000021400080000000102140034000000019E
+:1008F0000214000800000000021400600000000064
+:10090000030400040012055D030400540003056F96
+:100910000204007000000004030400780004057263
+:1009200004040088000000050304009C0003057611
+:10093000040400A800000004030400B800050579C1
+:10094000040400CC00000004030400DC0004057E65
+:10095000040400EC00000004010401240000000075
+:1009600001040128000000000104012C0000000027
+:100970000104013000000000020401340000000FF7
+:1009800003120490002205820212052000000002DA
+:1009900002120388000000640212039000000008A5
+:1009A0000312039C000305A4021203BC0000000410
+:1009B000021203C400000004021203D00000000071
+:1009C000021203DC000000000212036C00000001B0
+:1009D000021203680000003F031201BC003C05A79F
+:1009E000031202B0000205E303120324000205E52E
+:1009F000021201B00000000107103800000505E7F1
+:100A000007103C00000505EC07103C20000505F12F
+:100A100003168030000805F602168054000000021C
+:100A200003168060000505FE0416807400000007B0
+:100A300003168090000206030316809C000506053D
+:100A4000041680B000000007031680CC0008060AD8
+:100A5000021680F000000007041680F40000000C6D
+:100A60000316812400040612041681340000000CD1
+:100A700003168164003B0616041682500000000431
+:100A80000316826000020651041682680000000806
+:100A90000316828800080653041682A80000000A84
+:100AA00002168804000000040316880C0010065B80
+:100AB000021680EC000000FF030404080014066B1B
+:100AC000030500440002067F030500500004068170
+:100AD0000405006000000004030500900013068573
+:100AE00002050114000000010305011C0002069824
+:100AF00002050204000000010305020C0002069A30
+:100B00000305021C0003069C040502400000000AC5
+:100B1000030502800020069F0405400000000D0030
+:100B200003050004001006BF020500E00000000EEF
+:100B3000020500E40000002E04164024000000021C
+:100B400003164030000306CF021640440000002088
+:100B5000021640700000001C02164208000000014E
+:100B6000021642100000000102164220000000019F
+:100B70000216422800000001021642300000000167
+:100B80000216423800000001021642600000000117
+:100B90000A000001000000010216401C0003D09072
+:100BA0000A000001000000020216401C000009C4F7
+:100BB0000A000001000000040216401C0000009C16
+:100BC0000216400000000001021640D8000000019B
+:100BD00003164008000306D202164240000000003F
+:100BE0000216424800000000081642700000000291
+:100BF0000216425000000000021642580000000099
+:100C0000081642800000000203042008000406D5F4
+:100C10000304201C000406D90404203800000080CE
+:100C200003042238000406DD01042248000000000D
+:100C30000104224C000000000104225000000000CA
+:100C400001042254000000000104225800000000AA
+:100C50000104225C0000000001042260000000008A
+:100C6000010422640000000001042268000000006A
+:100C70000104226C0000000001042270000000004A
+:100C8000010422740000000001042278000000002A
+:100C90000104227C00000000020424BC00000001CA
+:100CA0000A0000010000000102042000000003E827
+:100CB0000A00000100000002020420000000000AF7
+:100CC0000A000001000000040204200000000001EE
+:100CD00005180400006A000006180760001406E109
+:100CE000041A000000001600041A800000000040F2
+:100CF000031A08B0000206E3031A19C8000206E549
+:100D0000031A2FC0000406E7041A2FD000000006C3
+:100D1000031A2FE8000206EB031A300003F906ED70
+:100D2000041A3FE400000007031A487000040AE6B2
+:100D3000021B800000000034021B804000000018ED
+:100D4000021B80800000000C021B80C000000020FD
+:100D5000021B83800007A120021B83C0000001F456
+:100D6000021B8BC0000000010A000002000000010D
+:100D7000021B83000007A120021B8340000001F436
+:100D80000A00000200000002021B8300000013881A
+:100D9000021B8340000000050A000002000000045E
+:100DA000021B830000000138021B8340000000008A
+:100DB000051C000031730000051C8000358B0C5DA4
+:100DC000051D00000FEB19C0061D21B05BCA0AEA21
+:100DD00001180000000000000118000400000000DD
+:100DE00001180008000000000118000C00000000BD
+:100DF000011800100000000001180014000000009D
+:100E000003180020001A0AEC031800A400020B06C5
+:100E10000218022400000000021802340000000042
+:100E20000218024C00000000021802E4000000FF5B
+:100E30000818100000000400041A08000000000256
+:100E4000041A082000000012041A09C0000000481B
+:100E5000041A250000000010041A2580000000126A
+:100E6000041A261000000012031A2FB000020B080B
+:100E7000041A400000000006041A4030000000027E
+:100E8000041A482000000002031A4C5000020B0A0A
+:100E9000041A081000000002041A0868000000127A
+:100EA000041A0AE000000048041A2540000000105F
+:100EB000041A25C800000012041A26580000001267
+:100EC000031A2FB800020B0C041A40180000000689
+:100ED000041A403800000002041A482800000002EA
+:100EE000031A4C5800020B0E020E004C0000003298
+:100EF000030E005400040B10040E006400000004F4
+:100F0000030E009400130B14020E014400000001B4
+:100F1000030E014C00020B27020E02040000000128
+:100F2000030E020C00020B29030E021C00040B2B03
+:100F3000030E0280001B0B2F040E02EC00000017B2
+:100F4000040E200000000800030E000400110B4AEC
+:100F5000020E01100000000F020E01140000002F0D
+:100F6000020C100000000028030C400800040B5B7A
+:100F7000030C401C00040B5F030C403800020B63A1
+:100F8000040C40400000005E020C41B8000000016B
+:100F9000040C41BC0000001F030C423800040B6528
+:100FA000010C424800000000010C424C000000000F
+:100FB000010C425000000000010C425400000000EF
+:100FC000010C425800000000010C425C00000000CF
+:100FD000010C426000000000010C426400000000AF
+:100FE000010C426800000000010C426C000000008F
+:100FF000010C427000000000010C4274000000006F
+:10100000010C427800000000010C427C000000004E
+:10101000010C428000000000020C44C000000001EE
+:101020000A00000100000001020C4000000003E87B
+:101030000A00000100000002020C40000000000A4B
+:101040000A00000100000004020C40000000000142
+:1010500005300400009B00000630076800130B6990
+:10106000043200000000160004328000000000403E
+:101070000332183000020B6B03322E7000040B6D2C
+:101080000432508000000008033250A000020B71AF
+:10109000023380000000001A023380400000004E3E
+:1010A0000233808000000010023380C00000002066
+:1010B000023383800007A120023383C0000001F4C3
+:1010C00002338BC0000000010A0000020000000192
+:1010D000023383000007A12002338340000001F4A3
+:1010E0000A0000020000000202338300000013889F
+:1010F00002338340000000050A00000200000004E3
+:1011000002338300000001380233834000000000F6
+:1011100005340000332800000534800028840CCA00
+:1011200005350000279416EB0535800036A820D041
+:10113000053600000F982E7A063621503BD60B73E9
+:101140000130000000000000013000040000000039
+:1011500001300008000000000130000C0000000019
+:1011600001300010000000000130001400000000F9
+:1011700003300020001A0B75033000A400020B8F0F
+:10118000023002240000000002300234000000009F
+:101190000230024C00000000023002E40000FFFFB9
+:1011A000083020000000080004322DE0000000029A
+:1011B00004324000000000D8043246C00000012084
+:1011C000043250C80000002404322DE80000000260
+:1011D00004324360000000D804324B40000001207C
+:1011E000043251580000002402020058000000326E
+:1011F0000302006000040B91040200700000000470
+:10120000030200A0000E0B95030200DC00070BA3F5
+:10121000020200FC000000060202012000000000A3
+:101220000202013400000002020201B000000001CD
+:101230000202020C000000010302021400020BAAC9
+:1012400002020404000000010302040C00020BACC3
+:101250000302041C00040BAE03020480001F0BB247
+:10126000040204FC000000130402800000002000BF
+:101270000302000400140BD102020108000000C8A0
+:101280000202011800000002020201C40000000076
+:10129000020201CC00000000020201D400000002A2
+:1012A000020201DC00000002020201E4000000FF73
+:1012B000020201EC000000FF0202010C000000C865
+:1012C0000202011C00000002020201C8000000002E
+:1012D000020201D000000000020201D8000000025A
+:1012E000020201E000000002020201E8000000FF2B
+:1012F000020201F0000000FF0216100000000028AA
+:101300000316600800030BE50316601C00040BE8DD
+:1013100003166038000D0BEC0416606C000000131F
+:10132000031660B800020BF9041660C00000003E0E
+:10133000021661B800000001041661BC0000001F25
+:101340000316623800040BFB01166248000000001F
+:101350000116624C000000000116625000000000FF
+:1013600001166254000000000116625800000000DF
+:101370000116625C000000000116626000000000BF
+:10138000011662640000000001166268000000009F
+:101390000116626C0000000001166270000000007F
+:1013A000011662740000000001166278000000005F
+:1013B0000116627C00000000021664BC00000001FF
+:1013C0000A0000010000000102166000000003E8AE
+:1013D0000A00000100000002021660000000000A7E
+:1013E0000A00000100000004021660000000000175
+:1013F00005280400008800000628076800130BFF7A
+:10140000042A000000001600042A800000000040AA
+:10141000032A250000020C01032A296000040C03A2
+:10142000032A2F4800020C07032A336800020C0924
+:10143000032A392000020C0B032A393000020C0D5C
+:10144000032A3AC800020C0F042A3AD00000000612
+:10145000032A3B9800020C11032A3C2000040C13C1
+:10146000022A3CD000000000022B80000000000097
+:10147000022B804000000018022B80800000000C2E
+:10148000022B80C000000066022B83800007A12091
+:10149000022B83C0000001F4022B8BC0000000016E
+:1014A0000A00000200000001022B83000007A120B7
+:1014B000022B8340000001F40A0000020000000239
+:1014C000022B830000001388022B834000000005DC
+:1014D0000A00000200000004022B83000000013813
+:1014E000022B8340000000000A00000100000020E1
+:1014F000022A3CD400000000052C0000384F0000F8
+:10150000052C80003A560E14052D00003C6D1CAAD7
+:10151000052D80000A4F2BC6062D93704D920C1797
+:101520000128000000000000012800040000000065
+:1015300001280008000000000128000C0000000045
+:101540000128001000000000012800140000000025
+:1015500003280020001A0C19032800A400020C33F1
+:1015600002280224000000000228023400000000CB
+:101570000228024C00000000022802E40000FFFFE5
+:101580000828200000000800042A3910000000028A
+:10159000042A393800000020042A3A3800000010DC
+:1015A000032A3AE800020C35032A3AF800100C37F7
+:1015B000042A3C3000000002042A5000000000020F
+:1015C000042A501000000002042A502000000002EB
+:1015D000042A503000000002022A5040000000009F
+:1015E000042A50480000000E042A391800000002A6
+:1015F000042A39B800000020042A3A7800000010BC
+:10160000032A3AF000020C47032A3B3800100C4929
+:10161000042A3C3800000002042A5008000000029E
+:10162000042A501800000002042A5028000000027A
+:10163000042A503800000002022A50440000000032
+:10164000042A50800000000E0400A00000000016D4
+:101650000300A06C00060C590400A08400000005E3
+:101660000200A0980FE000000400A09C00000014FD
+:101670000300A0EC00080C5F0400A22C0000000492
+:101680000200A060000003070300A10C00060C6725
+:101690000400A124000000050200A1380FE00000B2
+:1016A0000400A13C000000140300A18C00080C6D94
+:1016B0000400A23C000000040200A0640000030734
+:1016C000000000000000000000000000000000001A
+:1016D000000000000000000000000000000000000A
+:1016E00000000000000000000000000000000000FA
+:1016F0000000000000000005000500090009000DC1
+:1017000000000000000000000000000000000000D9
+:1017100000000000000000000000000000000000C9
+:10172000000D001B001B001C001C001D0000000021
+:1017300000000000000000000000000000000000A9
+:10174000000000000000000000000000001D002557
+:101750000000000000000000000000000000000089
+:101760000000000000000000000000000000000079
+:1017700000000000000000000025002B0000000019
+:101780000000000000000000000000000000000059
+:101790000000000000000000000000000000000049
+:1017A00000000000002B00470000000000000000C7
+:1017B0000000000000000000000000000000000029
+:1017C0000000000000000000000000000000000019
+:1017D000004700AE00AE00B300B300B80000000048
+:1017E00000000000000000000000000000000000F9
+:1017F00000000000000000000000000000000000E9
+:1018000000000000000000000000000000000000D8
+:1018100000000000000000000000000000000000C8
+:10182000000000000000000000B800BC0000000044
+:1018300000000000000000000000000000000000A8
+:101840000000000000000000000000000000000098
+:101850000000000000BC00C3000000000000000009
+:101860000000000000000000000000000000000078
+:101870000000000000000000000000000000000068
+:1018800000C300C400C400D600D600E80000000079
+:101890000000000000000000000000000000000048
+:1018A0000000000000000000000000000000000038
+:1018B0000000000000000000000000000000000028
+:1018C0000000000000000000000000000000000018
+:1018D000000000000000000000E800EC0000000034
+:1018E00000000000000000000000000000000000F8
+:1018F00000000000000000000000000000000000E8
+:101900000000000000EC00EF00EF00FA00FA010513
+:1019100000000000000000000000000000000000C7
+:1019200000000000000000000000000000000000B7
+:101930000105010B010B010F010F01130000000055
+:101940000000000000000000000000000000000097
+:101950000000000000000000000000000000000087
+:101960000000000000000000000000000000000077
+:101970000000000000000000000000000000000067
+:10198000000000000000000001130123000000001F
+:101990000000000000000000000000000000000047
+:1019A0000000000000000000000000000000000037
+:1019B00000000000012301320000000000000000D0
+:1019C0000000000000000000000000000000000017
+:1019D0000000000000000000000000000000000007
+:1019E000013201350000000000000000000000008E
+:1019F00000000000000000000000000000000000E7
+:101A00000000000000000000000000000135014A55
+:101A100000000000000000000000000000000000C6
+:101A200000000000000000000000000000000000B6
+:101A30000000000000000000014A014B000000000F
+:101A40000000000000000000000000000000000096
+:101A50000000000000000000000000000000000086
+:101A600000000000014B0158015801590159015A69
+:101A70000000000000000000000000000000000066
+:101A80000000000000000000000000000000000056
+:101A9000015A016E016E01710171017400000000B4
+:101AA0000000000000000000000000000000000036
+:101AB0000000000000000000000000000174018D23
+:101AC0000000000000000000000000000000000016
+:101AD0000000000000000000000000000000000006
+:101AE0000000000000000000018D01BA01BA01C52C
+:101AF00001C501D00000000000000000000000004F
+:101B000000000000000000000000000000000000D5
+:101B10000000000001D001DD01DD01DE01DE01DF9A
+:101B200000000000000000000000000000000000B5
+:101B300000000000000000000000000000000000A5
+:101B400001DF01E0000000000000000000000000D4
+:101B50000000000000000000000000000000000085
+:101B600000000000000000000000000001E001FD96
+:101B70000000000000000000000000000000000065
+:101B80000000000000000000000000000000000055
+:101B9000000000000000000001FD02280228022CC5
+:101BA000022C0230000000000000000000000000D5
+:101BB0000000000000000000000000000000000025
+:101BC00000000000023002420242024A024A02526F
+:101BD0000000000000000000000000000000000005
+:101BE00000000000000000000000000000000000F5
+:101BF000025202530000000000000000000000003C
+:101C000000000000000000000000000000000000D4
+:101C100000000000000000000000000002530271FC
+:101C200000000000000000000000000000000000B4
+:101C300000000000000000000000000000000000A4
+:101C40000000000000000000027102A402A402B023
+:101C500002B002BC00000000000000000000000014
+:101C60000000000000000000000000000000000074
+:101C70000000000002BC02BD02BD02C402C402CBCF
+:101C80000000000000000000000000000000000054
+:101C90000000000000000000000000000000000044
+:101CA00000000000000000000000200000004000D4
+:101CB00000006000000080000000A0000000C000E4
+:101CC0000000E000000100000001200000014000D1
+:101CD00000016000000180000001A0000001C000C0
+:101CE0000001E000000200000002200000024000AD
+:101CF00000026000000280000002A0000002C0009C
+:101D00000002E00000030000000320000003400088
+:101D100000036000000380000003A0000003C00077
+:101D20000003E00000040000000420000004400064
+:101D300000046000000480000004A0000004C00053
+:101D40000004E00000050000000520000005400040
+:101D500000056000000580000005A0000005C0002F
+:101D60000005E0000006000000062000000640001C
+:101D700000066000000680000006A0000006C0000B
+:101D80000006E000000700000007200000074000F8
+:101D900000076000000780000007A0000007C000E7
+:101DA0000007E000000800000008200000084000D4
+:101DB00000086000000880000008A0000008C000C3
+:101DC0000008E000000900000009200000094000B0
+:101DD00000096000000980000009A0000009C0009F
+:101DE0000009E000000A0000000A2000000A40008C
+:101DF000000A6000000A8000000AA000000AC0007B
+:101E0000000AE000000B0000000B2000000B400067
+:101E1000000B6000000B8000000BA000000BC00056
+:101E2000000BE000000C0000000C2000000C400043
+:101E3000000C6000000C8000000CA000000CC00032
+:101E4000000CE000000D0000000D2000000D40001F
+:101E5000000D6000000D8000000DA000000DC0000E
+:101E6000000DE000000E0000000E2000000E4000FB
+:101E7000000E6000000E8000000EA000000EC000EA
+:101E8000000EE000000F0000000F2000000F4000D7
+:101E9000000F6000000F8000000FA000000FC000C6
+:101EA000000FE000001000000010200000104000B3
+:101EB00000106000001080000010A0000010C000A2
+:101EC0000010E0000011000000112000001140008F
+:101ED00000116000001180000011A0000011C0007E
+:101EE0000011E0000012000000122000001240006B
+:101EF00000126000001280000012A0000012C0005A
+:101F00000012E00000130000001320000013400046
+:101F100000136000001380000013A0000013C00035
+:101F20000013E00000140000001420000014400022
+:101F300000146000001480000014A0000014C00011
+:101F40000014E000001500000015200000154000FE
+:101F500000156000001580000015A0000015C000ED
+:101F60000015E000001600000016200000164000DA
+:101F700000166000001680000016A0000016C000C9
+:101F80000016E000001700000017200000174000B6
+:101F900000176000001780000017A0000017C000A5
+:101FA0000017E00000180000001820000018400092
+:101FB00000186000001880000018A0000018C00081
+:101FC0000018E0000019000000192000001940006E
+:101FD00000196000001980000019A0000019C0005D
+:101FE0000019E000001A0000001A2000001A40004A
+:101FF000001A6000001A8000001AA000001AC00039
+:10200000001AE000001B0000001B2000001B400025
+:10201000001B6000001B8000001BA000001BC00014
+:10202000001BE000001C0000001C2000001C400001
+:10203000001C6000001C8000001CA000001CC000F0
+:10204000001CE000001D0000001D2000001D4000DD
+:10205000001D6000001D8000001DA000001DC000CC
+:10206000001DE000001E0000001E2000001E4000B9
+:10207000001E6000001E8000001EA000001EC000A8
+:10208000001EE000001F0000001F2000001F400095
+:10209000001F6000001F8000001FA000001FC00084
+:1020A000001FE00000200000002020000020400071
+:1020B00000206000002080000020A0000020C00060
+:1020C0000020E0000021000000212000002140004D
+:1020D00000216000002180000021A0000021C0003C
+:1020E0000021E00000220000002220000022400029
+:1020F00000226000002280000022A0000022C00018
+:102100000022E00000230000002320000023400004
+:1021100000236000002380000023A0000023C000F3
+:102120000023E000002400000024200000244000E0
+:1021300000246000002480000024A0000024C000CF
+:102140000024E000002500000025200000254000BC
+:1021500000256000002580000025A0000025C000AB
+:102160000025E00000260000002620000026400098
+:1021700000266000002680000026A0000026C00087
+:102180000026E00000270000002720000027400074
+:1021900000276000002780000027A0000027C00063
+:1021A0000027E00000280000002820000028400050
+:1021B00000286000002880000028A0000028C0003F
+:1021C0000028E0000029000000292000002940002C
+:1021D00000296000002980000029A0000029C0001B
+:1021E0000029E000002A0000002A2000002A400008
+:1021F000002A6000002A8000002AA000002AC000F7
+:10220000002AE000002B0000002B2000002B4000E3
+:10221000002B6000002B8000002BA000002BC000D2
+:10222000002BE000002C0000002C2000002C4000BF
+:10223000002C6000002C8000002CA000002CC000AE
+:10224000002CE000002D0000002D2000002D40009B
+:10225000002D6000002D8000002DA000002DC0008A
+:10226000002DE000002E0000002E2000002E400077
+:10227000002E6000002E8000002EA000002EC00066
+:10228000002EE000002F0000002F2000002F400053
+:10229000002F6000002F8000002FA000002FC00042
+:1022A000002FE0000030000000302000003040002F
+:1022B00000306000003080000030A0000030C0001E
+:1022C0000030E0000031000000312000003140000B
+:1022D00000316000003180000031A0000031C000FA
+:1022E0000031E000003200000032200000324000E7
+:1022F00000326000003280000032A0000032C000D6
+:102300000032E000003300000033200000334000C2
+:1023100000336000003380000033A0000033C000B1
+:102320000033E0000034000000342000003440009E
+:1023300000346000003480000034A0000034C0008D
+:102340000034E0000035000000352000003540007A
+:1023500000356000003580000035A0000035C00069
+:102360000035E00000360000003620000036400056
+:1023700000366000003680000036A0000036C00045
+:102380000036E00000370000003720000037400032
+:1023900000376000003780000037A0000037C00021
+:1023A0000037E0000038000000382000003840000E
+:1023B00000386000003880000038A0000038C000FD
+:1023C0000038E000003900000039200000394000EA
+:1023D00000396000003980000039A0000039C000D9
+:1023E0000039E000003A0000003A2000003A4000C6
+:1023F000003A6000003A8000003AA000003AC000B5
+:10240000003AE000003B0000003B2000003B4000A1
+:10241000003B6000003B8000003BA000003BC00090
+:10242000003BE000003C0000003C2000003C40007D
+:10243000003C6000003C8000003CA000003CC0006C
+:10244000003CE000003D0000003D2000003D400059
+:10245000003D6000003D8000003DA000003DC00048
+:10246000003DE000003E0000003E2000003E400035
+:10247000003E6000003E8000003EA000003EC00024
+:10248000003EE000003F0000003F2000003F400011
+:10249000003F6000003F8000003FA000003FC00000
+:1024A000003FE000003FE00100000000000001FFED
+:1024B0000000020000000001000000020000000017
+:1024C000000000080215002002150020081000007E
+:1024D00000000033000000020000000000000005C2
+:1024E00000000005000000000000000000000002E5
+:1024F00000000003000000020000000100000004D2
+:1025000000000002000000020000000100000002C4
+:102510000000002000000040000000400000000318
+:102520000000001800002000000040C00000618092
+:10253000000082400000A3000000C3C00000E4804F
+:102540000001054000012600000146C0000167802F
+:10255000000188400001A9000001C9C00001EA8013
+:1025600000020B4000022C0000024CC000026D80F3
+:1025700000028E400002AF000002CFC00002F080D7
+:1025800000001140000000010000000100000001F7
+:102590000000000100000001000000010000000137
+:1025A0000000000100000001000000010000000127
+:1025B0000000000100000001000000010000000117
+:1025C0000003D0000000003D00000001000D0000ED
+:1025D000000700D000028140000B81680002022049
+:1025E00000010240000F025000010340000C0000F7
+:1025F000000800C000028140000B81680002022038
+:102600000001024000070250000202C0001000005A
+:102610000008010000028180000B81A80002026016
+:1026200000018280000E82980008038000000000F4
+:102630000000000000028000000B8028000200E083
+:10264000000101000000811000000118FFFFFFF3EE
+:1026500001AFFFFF000000000000000000000000CC
+:10266000000000000000000000000000FFFFFFF17C
+:1026700000EFFFFF0000000000000000000000006D
+:10268000000000000001000000000000FFFFFFF656
+:10269000005FFFFF000000000000000000000000DD
+:1026A000000000000002000000000000FFFFF40630
+:1026B0001CBFFFFF00000005000000000000001428
+:1026C000000000000004000000000000FFFFFFF217
+:1026D000004FFFFF000000000000000000000000AD
+:1026E000000000000008000000000000FFFFFFFAEB
+:1026F000002FFFFF000000000000000000000000AD
+:10270000000000000010000000000000FFFFFFF7C5
+:1027100001EFFFFF000000000000000000000000CB
+:10272000000000000020000000000000FFFFFFF597
+:10273000002FFFFF0000000000000000000000006C
+:10274000000000000040000000000000FFFFFFF359
+:10275000018FFFFF000000000000000000000000EB
+:10276000000000000000000000000000FFFFFFF17B
+:10277000010FFFFF0000000000000000000000004B
+:10278000000000000001000000000000FFFFFFF655
+:10279000005FFFFF000000000000000000000000DC
+:1027A000000000000002000000000000FFFFF4062F
+:1027B0001CBFFFFF00000005000000000000001427
+:1027C000000000000004000000000000FFFFFFF216
+:1027D000004FFFFF000000000000000000000000AC
+:1027E000000000000008000000000000FFFFFFFAEA
+:1027F000002FFFFF000000000000000000000000AC
+:10280000000000000010000000000000FFFFFFF7C4
+:1028100000EFFFFF000000000000000000000000CB
+:10282000000000000020000000000000FFFFFFF596
+:10283000004FFFFF0000000000000000000000004B
+:10284000000000000040000000000000FFFFFFFF4C
+:1028500000CFFFFF0000000000000000000000CCDF
+:10286000000000000000000000000000FFFFFFFF6C
+:1028700000CFFFFF0000000000000000000000CCBF
+:10288000000000000001000000000000FFFFFFFF4B
+:1028900000CFFFFF0000000000000000000000CC9F
+:1028A000000000000002000000000000FFFFFFFF2A
+:1028B00000CFFFFF0000000000000000000000CC7F
+:1028C000000000000004000000000000FFFFFFFF08
+:1028D00000CFFFFF0000000000000000000000CC5F
+:1028E000000000000008000000000000FFFFFFFFE4
+:1028F00000CFFFFF0000000000000000000000CC3F
+:10290000000000000010000000000000FFFFFFFFBB
+:1029100000CFFFFF0000000000000000000000CC1E
+:10292000000000000020000000000000FFFFFFFF8B
+:1029300000CFFFFF0000000000000000000000CCFE
+:10294000000000000040000000000000FFFFFFF357
+:10295000020FFFFF00000000000000000000000068
+:10296000000000000000000000000000FFFFFFF179
+:10297000010FFFFF00000000000000000000000049
+:10298000000000000001000000000000FFFFFFF653
+:10299000005FFFFF000000000000000000000000DA
+:1029A000000000000002000000000000FFFFF4062D
+:1029B0001CBFFFFF00000005000000000000001425
+:1029C000000000000004000000000000FFFFFFF214
+:1029D000004FFFFF000000000000000000000000AA
+:1029E000000000000008000000000000FFFFFF8A58
+:1029F000042FFFFF000000000000000000000000A6
+:102A0000000000000010000000000000FFFFFF9722
+:102A100005CFFFFF000000000000000000000000E4
+:102A2000000000000020000000000000FFFFFFF594
+:102A3000010FFFFF00000000000000000000000088
+:102A4000000000000040000000000000FFFFFFF356
+:102A5000000FFFFF00000000000000000000000069
+:102A6000000000000000000000000000FFFFFFF178
+:102A7000000FFFFF00000000000000000000000049
+:102A8000000000000001000000000000FFFFFFF652
+:102A9000005FFFFF000000000000000000000000D9
+:102AA000000000000002000000000000FFFFF4062C
+:102AB0001CBFFFFF00000005000000000000001424
+:102AC000000000000004000000000000FFFFFFF213
+:102AD000004FFFFF000000000000000000000000A9
+:102AE000000000000008000000000000FFFFFFFAE7
+:102AF000002FFFFF000000000000000000000000A9
+:102B0000000000000010000000000000FFFFFF9721
+:102B1000040FFFFF000000000000000000000000A4
+:102B2000000000000020000000000000FFFFFFF593
+:102B3000000FFFFF00000000000000000000000088
+:102B4000000000000040000000000000FFFFFFFF49
+:102B500000CFFFFF0000000000000000000000CCDC
+:102B6000000000000000000000000000FFFFFFFF69
+:102B700000CFFFFF0000000000000000000000CCBC
+:102B8000000000000001000000000000FFFFFFFF48
+:102B900000CFFFFF0000000000000000000000CC9C
+:102BA000000000000002000000000000FFFFFFFF27
+:102BB00000CFFFFF0000000000000000000000CC7C
+:102BC000000000000004000000000000FFFFFFFF05
+:102BD00000CFFFFF0000000000000000000000CC5C
+:102BE000000000000008000000000000FFFFFFFFE1
+:102BF00000CFFFFF0000000000000000000000CC3C
+:102C0000000000000010000000000000FFFFFFFFB8
+:102C100000CFFFFF0000000000000000000000CC1B
+:102C2000000000000020000000000000FFFFFFFF88
+:102C300000CFFFFF0000000000000000000000CCFB
+:102C4000000000000040000000000000FFFFFFFF48
+:102C500000CFFFFF0000000000000000000000CCDB
+:102C6000000000000000000000000000FFFFFFFF68
+:102C700000CFFFFF0000000000000000000000CCBB
+:102C8000000000000001000000000000FFFFFFFF47
+:102C900000CFFFFF0000000000000000000000CC9B
+:102CA000000000000002000000000000FFFFFFFF26
+:102CB00000CFFFFF0000000000000000000000CC7B
+:102CC000000000000004000000000000FFFFFFFF04
+:102CD00000CFFFFF0000000000000000000000CC5B
+:102CE000000000000008000000000000FFFFFFFFE0
+:102CF00000CFFFFF0000000000000000000000CC3B
+:102D0000000000000010000000000000FFFFFFFFB7
+:102D100000CFFFFF0000000000000000000000CC1A
+:102D2000000000000020000000000000FFFFFFFF87
+:102D300000CFFFFF0000000000000000000000CCFA
+:102D4000000000000040000000000000FFFFFFFF47
+:102D500000CFFFFF0000000000000000000000CCDA
+:102D6000000000000000000000000000FFFFFFFF67
+:102D700000CFFFFF0000000000000000000000CCBA
+:102D8000000000000001000000000000FFFFFFFF46
+:102D900000CFFFFF0000000000000000000000CC9A
+:102DA000000000000002000000000000FFFFFFFF25
+:102DB00000CFFFFF0000000000000000000000CC7A
+:102DC000000000000004000000000000FFFFFFFF03
+:102DD00000CFFFFF0000000000000000000000CC5A
+:102DE000000000000008000000000000FFFFFFFFDF
+:102DF00000CFFFFF0000000000000000000000CC3A
+:102E0000000000000010000000000000FFFFFFFFB6
+:102E100000CFFFFF0000000000000000000000CC19
+:102E2000000000000020000000000000FFFFFFFF86
+:102E300000CFFFFF0000000000000000000000CCF9
+:102E40000000000000400000000000000000020040
+:102E500000003DFF00000A1100000A0000000A0403
+:102E60000000FFFF0000FFFF0000FFFF0000FFFF6A
+:102E700000000020000000210000002200000023CC
+:102E800000000024000000250000002600000027AC
+:102E900000000028000000290000002A0000002B8C
+:102EA0000000002C0000002D0000002E0000002F6C
+:102EB00000000010000000010000000100000001FF
+:102EC00000000001000000010000000100000001FE
+:102ED00000000001000000010000000100000001EE
+:102EE00000000001000000010000000100000001DE
+:102EF000000000010000000107FFFFFF0000003F8D
+:102F000007FFFFFF0000000F00007FF800007FF8C0
+:102F10000000FF1C0FFFFFFF0000FF1C0FFFFFFF63
+:102F20000000FF1C0FFFFFFF0000FF1C0FFFFFFF53
+:102F30000000FF1C0FFFFFFF0000FF1C0FFFFFFF43
+:102F40000000FF1C0FFFFFFF0000FF1C0FFFFFFF33
+:102F50000000FF1C0FFFFFFF0000FF1C0FFFFFFF23
+:102F60000000FF1C0FFFFFFF0000FF1C0FFFFFFF13
+:102F70000000FF1C0FFFFFFF0000FF1C0FFFFFFF03
+:102F80000000FF1C0FFFFFFF0000FF1C0FFFFFFFF3
+:102F90000000FF1C0FFFFFFF0000FF1C0FFFFFFFE3
+:102FA0000000FF1C0FFFFFFF0000FF1C0FFFFFFFD3
+:102FB0000000FF1C0FFFFFFF0000FF1C0FFFFFFFC3
+:102FC0000000FF1C0FFFFFFF0000FF1C0FFFFFFFB3
+:102FD0000000FF1C0FFFFFFF0000FF1C0FFFFFFFA3
+:102FE0000000FF1C0FFFFFFF0000FF1C0FFFFFFF93
+:102FF0000000FF1C0FFFFFFF0000FF1C0FFFFFFF83
+:103000000000FF1C0FFFFFFF0000FF1C0FFFFFFF72
+:103010000000FF1C0FFFFFFF0000FF1C0FFFFFFF62
+:103020000000FF1C0FFFFFFF0000FF1C0FFFFFFF52
+:103030000000FF1C0FFFFFFF0000FF1C0FFFFFFF42
+:103040000000FF1C0FFFFFFF0000FF1C0FFFFFFF32
+:103050000000FF1C0FFFFFFF0000FF1C0FFFFFFF22
+:103060000000FF1C0FFFFFFF0000FF1C0FFFFFFF12
+:103070000000FF1C0FFFFFFF0000FF1C0FFFFFFF02
+:103080000000FF1C0FFFFFFF0000FF1C0FFFFFFFF2
+:103090000000FF1C0FFFFFFF0000FF1C0FFFFFFFE2
+:1030A0000000FF1C0FFFFFFF0000FF1C0FFFFFFFD2
+:1030B0000000FF1C0FFFFFFF0000FF1C0FFFFFFFC2
+:1030C0000000FF1C0FFFFFFF0000FF1C0FFFFFFFB2
+:1030D0000000FF1C0FFFFFFF0000FF1C0FFFFFFFA2
+:1030E0000000FF1C0FFFFFFF0000FF1C0FFFFFFF92
+:1030F0000000FF1C0FFFFFFF0000FF1C0FFFFFFF82
+:103100000000FF1C0FFFFFFF0000FF1C0FFFFFFF71
+:103110000000FF00000000000000FF0000000000B1
+:103120000000000200001500000000010000000285
+:103130000000000300000000000000040000000187
+:10314000000000000000000100000004000000007A
+:10315000000000010000000300000000000000016A
+:103160000000000400000000000000010000000357
+:10317000000000000000000100000004000000004A
+:103180000000000400000003000000000000000038
+:1031900000003FFF000003FF0000000000000001EE
+:1031A0000000000100000001007C10040000000489
+:1031B00000000000000000020000009000000090ED
+:1031C00000800090081000000000008A00000080CD
+:1031D000000000810000008000000006000007D011
+:1031E0000000076C0000FFFF0000FFFF0000FFFF72
+:1031F0000000FFFF071D291100000000009C0424AF
+:1032000000000000000000010000000100000001BB
+:10321000000000010000000100007FFF000000FF2F
+:10322000000000FF000000FF000000FF000000FFA2
+:10323000000000FF000000FF000000FF0000003E53
+:10324000000000000000003F0000003F0000003FC1
+:10325000000000000000003F0000003F0000003FB1
+:103260000000000F00000043000000000000000606
+:1032700000000000121700002217000032170000A3
+:103280001215000022150000321500000210000087
+:10329000001000001010000020100000301000008E
+:1032A000001000001214000022140000321400006C
+:1032B00000E38340FFFFFFFFFFFFFFFFFFFFFFFF74
+:1032C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0E
+:1032D000FFFFFFFFF0003000FFFFFFFFFFFFFFFFDA
+:1032E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE
+:1032F000FFFFFFFFFFFF3328FFFF3338FFFFFFFF14
+:10330000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD
+:10331000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD
+:10332000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD
+:10333000FFFFFFFF00003C1000000008000000003D
+:103340000000000000000040000018080000080312
+:103350000000080300000040000000030000080314
+:103360000000080300000803000100030000080338
+:103370000000080300000003000000030000000339
+:103380000000000300000003000000030000000331
+:103390000000000300000003000000030000000321
+:1033A0000000000300000003000000030000000311
+:1033B000000024030000002F000000090000001995
+:1033C00000000184000001830000030600000019D2
+:1033D00000000006000003060000030600000306CC
+:1033E00000000C8600000306000003060000000633
+:1033F00000000006000000060000000600000006B5
+:1034000000000006000000060000000600000006A4
+:103410000000000600000006000000060000000694
+:103420000000000600000006000003060000001374
+:1034300000000006000010040000100400106440AA
+:1034400000106440000000000000000000000000C8
+:10345000000000000000200000000000000000004C
+:10346000000000000000000000002000000000003C
+:10347000000000000000000000000000000020002C
+:103480000000007C0000003D0000003F0000009CA8
+:1034900000000006000000050000000A0000000512
+:1034A000000001400000014000000000000000009A
+:1034B000000000C00000013F00007FFF0000004846
+:1034C000000000480000000000000000000000486C
+:1034D00000000004000000040000000400000004DC
+:1034E00000000004000000040000000400000004CC
+:1034F00000000004000000090000000B0000000AAA
+:1035000000000004000000090000000B0000000A99
+:1035100000000001000000010000000100000001A7
+:103520000000000100000001000000010000000197
+:103530000000000100000001000000010000000187
+:1035400000000004000000090000000B0000000A59
+:103550000000000100000001000000010000000167
+:103560000000000100000001000000010000000157
+:103570000000000100000001000000010000000147
+:1035800000000004000000090000000B0000000A19
+:103590000000000000000000000008000000020021
+:1035A000000001FF00000400000000000000000017
+:1035B0001E491E491E491E490E490E490E490E4913
+:1035C000FFFFFFFF00000000FFFFFFFF0000000003
+:1035D000000025E400008000000000130FFF0FFF33
+:1035E00000000000000000000FFF0FFF100010009F
+:1035F000100010002000200020002000800080002B
+:1036000080008000400040004000400000000000BA
+:10361000000000010101010101200101200101015F
+:10362000010110010101010101200101200101013D
+:10363000010110012001010101011001010101013D
+:10364000012001012001010101011001010101011D
+:1036500001200101000001230000012300000123DB
+:1036600000000123000001230000012300000123CA
+:1036700000000123000001230000012300000123BA
+:1036800000000123000001230000012300000123AA
+:10369000000001230000012300000123000001239A
+:1036A000000001230000002000000032000000079D
+:1036B00000000007000000000000000802150020C4
+:1036C0000215002000000030081000000000003348
+:1036D0000000003000000031000000020000000582
+:1036E00000000006000000020000000200000000D0
+:1036F00000000005000000020000000200000002BF
+:1037000000000001000000060000000100000002AF
+:1037100000000040000000400000002000000013F6
+:103720000000002000010000000204C00003098026
+:1037300000040E4000051300000617C000071C809F
+:103740000008214000092600000A2AC0000B2F8033
+:10375000000C3440000D3900000E3DC0000F4280C7
+:103760000010474000114C00001250C0001355805B
+:1037700000145A4000155F00001663C000176880EF
+:1037800000186D4000197200001A76C0001B7B8083
+:10379000001C8040001D8500001E89C0001F8E8017
+:1037A0000000934000000001000000010000000143
+:1037B0000000000100000001000000010000000105
+:1037C00000000001000000010000000100000001F5
+:1037D00000000001000000010000000100000001E5
+:1037E00000000001000000080000000C00000010B4
+:1037F00000000001000000010000000100000211B3
+:103800000000020000000204000002190000FFFF97
+:103810000000FFFF0000FFFF0000FFFF07FFFFFFAA
+:103820000000003F07FFFFFF0000000F00007FF8CF
+:1038300000007FF800000000140AFF0000000000F4
+:1038400000000001002010010000000001008600BF
+:1038500000000100000000010000000000008602DE
+:1038600000000000000000000000000000008604CE
+:1038700000000000000000000000000000008606BC
+:1038800000000000000000000000000000008608AA
+:103890000000000000000000000000000000860A98
+:1038A0000000000000000000000000000000860C86
+:1038B0000000000000000000000000000000860E74
+:1038C0000000000000000000000000000000861062
+:1038D0000000000000000000000000000000861250
+:1038E000000000000000000000000000000086143E
+:1038F000000000000000000000000000000086162C
+:103900000000000000000000000000000000861819
+:103910000000000000000000000000000000861A07
+:103920000000000000000000000000000000861CF5
+:103930000000000000000000000000000000861EE3
+:1039400000000000000000000000000000008620D1
+:1039500000000000000000000000000000008622BF
+:1039600000000000000000000000000000008624AD
+:10397000000000000000000000000000000086269B
+:103980000000000000000000000000000000862889
+:103990000000000000000000000000000000862A77
+:1039A0000000000000000000000000000000862C65
+:1039B0000000000000000000000000000000862E53
+:1039C0000000000000000000000000000000863041
+:1039D000000000000000000000000000000086322F
+:1039E000000000000000000000000000000086341D
+:1039F000000000000000000000000000000086360B
+:103A000000000000000000000000000000008638F8
+:103A10000000000000000000000000000000863AE6
+:103A20000000000000000000000000000000863CD4
+:103A30000000000000000000000000000000863EC2
+:103A400000000000000000000000000000008640B0
+:103A5000000000000000000000000000000086429E
+:103A6000000000000000000000000000000086448C
+:103A7000000000000000000000000000000086467A
+:103A80000000000000000000000000000000864868
+:103A90000000000000000000000000000000864A56
+:103AA0000000000000000000000000000000864C44
+:103AB0000000000000000000000000000000864E32
+:103AC0000000000000000000000000000000865020
+:103AD000000000000000000000000000000086520E
+:103AE00000000000000000000000000000008654FC
+:103AF00000000000000000000000000000008656EA
+:103B000000000000000000000000000000008658D7
+:103B10000000000000000000000000000000865AC5
+:103B20000000000000000000000000000000865CB3
+:103B30000000000000000000000000000000865EA1
+:103B4000000000000000000000000000000086608F
+:103B5000000000000000000000000000000086627D
+:103B6000000000000000000000000000000086646B
+:103B70000000000000000000000000000000866659
+:103B80000000000000000000000000000000866847
+:103B90000000000000000000000000000000866A35
+:103BA0000000000000000000000000000000866C23
+:103BB0000000000000000000000000000000866E11
+:103BC00000000000000000000000000000008670FF
+:103BD00000000000000000000000000000008672ED
+:103BE00000000000000000000000000000008674DB
+:103BF00000000000000000000000000000008676C9
+:103C000000000000000000000000000000008678B6
+:103C10000000000000000000000000000000867AA4
+:103C20000000000000000000000000000000867C92
+:103C30000000000000000000000000000000867E80
+:103C4000000000000000000000000000000086806E
+:103C5000000000000000000000000000000086825C
+:103C6000000000000000000000000000000086844A
+:103C70000000000000000000000000000000868638
+:103C80000000000000000000000000000000868826
+:103C90000000000000000000000000000000868A14
+:103CA0000000000000000000000000000000868C02
+:103CB0000000000000000000000000000000868EF0
+:103CC00000000000000000000000000000008690DE
+:103CD00000000000000000000000000000008692CC
+:103CE00000000000000000000000000000008694BA
+:103CF00000000000000000000000000000008696A8
+:103D00000000000000000000000000000000869895
+:103D10000000000000000000000000000000869A83
+:103D20000000000000000000000000000000869C71
+:103D30000000000000000000000000000000869E5F
+:103D4000000000000000000000000000000086A04D
+:103D5000000000000000000000000000000086A23B
+:103D6000000000000000000000000000000086A429
+:103D7000000000000000000000000000000086A617
+:103D8000000000000000000000000000000086A805
+:103D9000000000000000000000000000000086AAF3
+:103DA000000000000000000000000000000086ACE1
+:103DB000000000000000000000000000000086AECF
+:103DC000000000000000000000000000000086B0BD
+:103DD000000000000000000000000000000086B2AB
+:103DE000000000000000000000000000000086B499
+:103DF000000000000000000000000000000086B687
+:103E0000000000000000000000000000000086B874
+:103E1000000000000000000000000000000086BA62
+:103E2000000000000000000000000000000086BC50
+:103E3000000000000000000000000000000086BE3E
+:103E4000000000000000000000000000000086C02C
+:103E5000000000000000000000000000000086C21A
+:103E6000000000000000000000000000000086C408
+:103E7000000000000000000000000000000086C6F6
+:103E8000000000000000000000000000000086C8E4
+:103E9000000000000000000000000000000086CAD2
+:103EA000000000000000000000000000000086CCC0
+:103EB000000000000000000000000000000086CEAE
+:103EC000000000000000000000000000000086D09C
+:103ED000000000000000000000000000000086D28A
+:103EE000000000000000000000000000000086D478
+:103EF000000000000000000000000000000086D666
+:103F0000000000000000000000000000000086D853
+:103F1000000000000000000000000000000086DA41
+:103F2000000000000000000000000000000086DC2F
+:103F3000000000000000000000000000000086DE1D
+:103F4000000000000000000000000000000086E00B
+:103F5000000000000000000000000000000086E2F9
+:103F6000000000000000000000000000000086E4E7
+:103F7000000000000000000000000000000086E6D5
+:103F8000000000000000000000000000000086E8C3
+:103F9000000000000000000000000000000086EAB1
+:103FA000000000000000000000000000000086EC9F
+:103FB000000000000000000000000000000086EE8D
+:103FC000000000000000000000000000000086F07B
+:103FD000000000000000000000000000000086F269
+:103FE000000000000000000000000000000086F457
+:103FF000000000000000000000000000000086F645
+:10400000000000000000000000000000000086F832
+:10401000000000000000000000000000000086FA20
+:10402000000000000000000000000000000086FC0E
+:10403000000000000000000000000000000086FEFC
+:1040400000000000000000000000000000008700E9
+:1040500000000000000000000000000000008702D7
+:1040600000000000000000000000000000008704C5
+:1040700000000000000000000000000000008706B3
+:1040800000000000000000000000000000008708A1
+:104090000000000000000000000000000000870A8F
+:1040A0000000000000000000000000000000870C7D
+:1040B0000000000000000000000000000000870E6B
+:1040C0000000000000000000000000000000871059
+:1040D0000000000000000000000000000000871247
+:1040E0000000000000000000000000000000871435
+:1040F0000000000000000000000000000000871623
+:104100000000000000000000000000000000871810
+:104110000000000000000000000000000000871AFE
+:104120000000000000000000000000000000871CEC
+:104130000000000000000000000000000000871EDA
+:1041400000000000000000000000000000008720C8
+:1041500000000000000000000000000000008722B6
+:1041600000000000000000000000000000008724A4
+:104170000000000000000000000000000000872692
+:104180000000000000000000000000000000872880
+:104190000000000000000000000000000000872A6E
+:1041A0000000000000000000000000000000872C5C
+:1041B0000000000000000000000000000000872E4A
+:1041C0000000000000000000000000000000873038
+:1041D0000000000000000000000000000000873226
+:1041E0000000000000000000000000000000873414
+:1041F0000000000000000000000000000000873602
+:1042000000000000000000000000000000008738EF
+:104210000000000000000000000000000000873ADD
+:104220000000000000000000000000000000873CCB
+:104230000000000000000000000000000000873EB9
+:1042400000000000000000000000000000008740A7
+:104250000000000000000000000000000000874295
+:104260000000000000000000000000000000874483
+:104270000000000000000000000000000000874671
+:10428000000000000000000000000000000087485F
+:104290000000000000000000000000000000874A4D
+:1042A0000000000000000000000000000000874C3B
+:1042B0000000000000000000000000000000874E29
+:1042C0000000000000000000000000000000875017
+:1042D0000000000000000000000000000000875205
+:1042E00000000000000000000000000000008754F3
+:1042F00000000000000000000000000000008756E1
+:1043000000000000000000000000000000008758CE
+:104310000000000000000000000000000000875ABC
+:104320000000000000000000000000000000875CAA
+:104330000000000000000000000000000000875E98
+:104340000000000000000000000000000000876086
+:104350000000000000000000000000000000876274
+:104360000000000000000000000000000000876462
+:104370000000000000000000000000000000876650
+:10438000000000000000000000000000000087683E
+:104390000000000000000000000000000000876A2C
+:1043A0000000000000000000000000000000876C1A
+:1043B0000000000000000000000000000000876E08
+:1043C00000000000000000000000000000008770F6
+:1043D00000000000000000000000000000008772E4
+:1043E00000000000000000000000000000008774D2
+:1043F00000000000000000000000000000008776C0
+:1044000000000000000000000000000000008778AD
+:104410000000000000000000000000000000877A9B
+:104420000000000000000000000000000000877C89
+:104430000000000000000000000000000000877E77
+:104440000000000000000000000000000000878065
+:104450000000000000000000000000000000878253
+:104460000000000000000000000000000000878441
+:10447000000000000000000000000000000087862F
+:10448000000000000000000000000000000087881D
+:104490000000000000000000000000000000878A0B
+:1044A0000000000000000000000000000000878CF9
+:1044B0000000000000000000000000000000878EE7
+:1044C00000000000000000000000000000008790D5
+:1044D00000000000000000000000000000008792C3
+:1044E00000000000000000000000000000008794B1
+:1044F000000000000000000000000000000087969F
+:10450000000000000000000000000000000087988C
+:104510000000000000000000000000000000879A7A
+:104520000000000000000000000000000000879C68
+:104530000000000000000000000000000000879E56
+:10454000000000000000000000000000000087A044
+:10455000000000000000000000000000000087A232
+:10456000000000000000000000000000000087A420
+:10457000000000000000000000000000000087A60E
+:10458000000000000000000000000000000087A8FC
+:10459000000000000000000000000000000087AAEA
+:1045A000000000000000000000000000000087ACD8
+:1045B000000000000000000000000000000087AEC6
+:1045C000000000000000000000000000000087B0B4
+:1045D000000000000000000000000000000087B2A2
+:1045E000000000000000000000000000000087B490
+:1045F000000000000000000000000000000087B67E
+:10460000000000000000000000000000000087B86B
+:10461000000000000000000000000000000087BA59
+:10462000000000000000000000000000000087BC47
+:10463000000000000000000000000000000087BE35
+:10464000000000000000000000000000000087C023
+:10465000000000000000000000000000000087C211
+:10466000000000000000000000000000000087C4FF
+:10467000000000000000000000000000000087C6ED
+:10468000000000000000000000000000000087C8DB
+:10469000000000000000000000000000000087CAC9
+:1046A000000000000000000000000000000087CCB7
+:1046B000000000000000000000000000000087CEA5
+:1046C000000000000000000000000000000087D093
+:1046D000000000000000000000000000000087D281
+:1046E000000000000000000000000000000087D46F
+:1046F000000000000000000000000000000087D65D
+:10470000000000000000000000000000000087D84A
+:10471000000000000000000000000000000087DA38
+:10472000000000000000000000000000000087DC26
+:10473000000000000000000000000000000087DE14
+:10474000000000000000000000000000000087E002
+:10475000000000000000000000000000000087E2F0
+:10476000000000000000000000000000000087E4DE
+:10477000000000000000000000000000000087E6CC
+:10478000000000000000000000000000000087E8BA
+:10479000000000000000000000000000000087EAA8
+:1047A000000000000000000000000000000087EC96
+:1047B000000000000000000000000000000087EE84
+:1047C000000000000000000000000000000087F072
+:1047D000000000000000000000000000000087F260
+:1047E000000000000000000000000000000087F44E
+:1047F000000000000000000000000000000087F63C
+:10480000000000000000000000000000000087F829
+:10481000000000000000000000000000000087FA17
+:10482000000000000000000000000000000087FC05
+:10483000000000000000000000000000000087FEF3
+:104840000000FF00000000000000FF00000000006A
+:10485000000000020000150000000001000000023E
+:104860000000000300000000000000040000000140
+:104870000000000000000001000000040000000033
+:104880000000000100000003000000000000000123
+:104890000000000400000000000000010000000310
+:1048A0000000000000000001000000040000000003
+:1048B00000000004000000030000000000000000F1
+:1048C00000003FFF000003FF0000000300BEBC200B
+:1048D00000000000000000050000000300BEBC2036
+:1048E00000000000000000050000000D0000000CAA
+:1048F000000000000000001002150020021500203A
+:1049000000000030081000000000003300000030FC
+:104910000000003100000002000000040000000060
+:104920000000000200000002000000000000000281
+:10493000000000070000000200000002000000016B
+:104940000000000300000001000000020000004021
+:104950000000004000000004000000200000000FE4
+:104960000000001B00008000000103C000018780E0
+:1049700000020B4000028F00000312C0000396806B
+:1049800000041A4000049E00000521C00005A58017
+:10499000000629400006AD00000730C00007B480C3
+:1049A000000838400008BC0000093FC00009C3806F
+:1049B000000A4740000ACB00000B4EC0000BD2801B
+:1049C000000C5640000CDA00000D5DC00000618054
+:1049D00000000001000000010000000100000001D3
+:1049E00000000001000000010000000100000001C3
+:1049F00000000001000000010000000100000001B3
+:104A000000000001000000010000000100000001A2
+:104A100000000001000005AA000005990000059DA6
+:104A2000000003C00000FFFF0000FFFF0000FFFFC9
+:104A30000000FFFF000000460000000C07FFFFFF22
+:104A40000000003F07FFFFFF0000000F00007FF89D
+:104A500000007FF8FFFFFFFFFFFFFFFF0000FF00E8
+:104A6000000000000000FF0000000000000019002E
+:104A7000000000000000000200001500000000011E
+:104A8000000000020000000300000000000000041D
+:104A90000000000100000000000000010000000410
+:104AA0000000000000000001000000030000000002
+:104AB00000000001000000040000000000000001F0
+:104AC00000000003000000000000000100000004DE
+:104AD00000000000000000040000000300000000CF
+:104AE0000000000000003FFF000003FF0000000F77
+:104AF00000000007000000000000000E0315002069
+:104B000003150020010000300810000000000033F1
+:104B1000000000300000003100000003000000062B
+:104B2000000000030000000300000002000000007D
+:104B30000000000200000000000000060000000469
+:104B4000000000020000000200000001000000045C
+:104B500000000001000000020000004000000040D2
+:104B60000000000400000020000000020000001F00
+:104B70000000100000002080000031000000418093
+:104B8000000052000000628000007300000083807B
+:104B9000000094000000A4800000B5000000C58063
+:104BA0000000D6000000E6800000F700000107804A
+:104BB000000118000001288000013900000149802F
+:104BC00000015A0000016A8000017B0000018B8017
+:104BD00000019C000001AC800001BD000001CD80FF
+:104BE0000001DE000001EE8000000F000000000167
+:104BF00000000001000000010000000100000001B1
+:104C000000000001000000010000000100000001A0
+:104C10000000000100000001000000010000000190
+:104C20000000000100000001000000010000000180
+:104C30000000000100000001000000010000061457
+:104C400000000600000006040000FFFF0000FFFF58
+:104C50000000FFFF0000FFFF000000200000002018
+:104C600000000000000000000000002300000024FD
+:104C70000000002500000026000000270000002999
+:104C80000000002A0000002B0000002C00000001A2
+:104C90000000000107FFFFFF0000003F07FFFFFFCC
+:104CA0000000000F00007FF800007FF80000000007
+:104CB00000000001CCCC0201CCCCCCCCCCCC02018D
+:104CC000CCCCCCCCFFFFFFFFFFFFFFFF00000000BC
+:104CD00000010001001E0C07CCCCCCC1FFFFFFFF80
+:104CE000FFFFFFFF10000000000028AD7058103CCF
+:104CF000000000000000FF00000000000000FF00B6
+:104D0000000000000000000200001500000000018B
+:104D1000000000020000000300000000000000048A
+:104D2000000000010000000000000001000000047D
+:104D3000000000000000000100000003000000006F
+:104D4000000000010000000400000000000000015D
+:104D5000000000030000000000000001000000044B
+:104D6000000000000000000400000003000000003C
+:104D70000000000000003FFF000003FF000E0000E5
+:104D8000011600D60000FFFF000000000000FFFF3A
+:104D9000000000000000FFFF000000000000FFFF17
+:104DA000000000000000FFFF000000000000FFFF07
+:104DB0000000000000000000000000000000FFFFF5
+:104DC0000000000000720000012300F30000FFFF5C
+:104DD000000000000000FFFF000000000000FFFFD7
+:104DE000000000000000FFFF000000000000FFFFC7
+:104DF000000000000000FFFF0000000000000000B5
+:104E0000000000000000FFFF00000000BF5C000089
+:104E1000FFF51FEF0000FFFFF00003E000000000BF
+:104E20000000A0005554000055555555000055553B
+:104E3000F0000000555400005555555500005555DB
+:104E4000F0000000BF5C0000FFF51FEF0000FFFF57
+:104E5000F00003E0000000000000A0005554000036
+:104E60005555555500005555F000000055540000AB
+:104E70005555555500005555F00000000000000044
+:104E80001F8B080000000000000BFB51CFC0F00397
+:104E9000099F6347E56730A3F24FB2A0F2071AB744
+:104EA000313130F403F115209EC1845FED6A464C28
+:104EB000B1371208F654310606061108DB4064E0EB
+:104EC000FD368A698FFB9551F95D8A109A072A3E53
+:104ED000014DBE1B2AEF2007A1272A6337D7112ACD
+:104EE0000F00DCF1F0E360030000000000000000B0
+:104EF0001F8B080000000000000BED7D0B7855D5DE
+:104F000099E8DA67EFB3CFFB64279C242790D09D04
+:104F1000906080802721BC2CD69D10E4749AD60323
+:104F2000048D1AF5F0A846410D5CAC696B9B1D928F
+:104F30004004C4A01D9BAAED1CD0B1B4B5BDC11BDB
+:104F40002D9D713A41A58333EDBD94608B15F568B5
+:104F5000AD8F563B51EB407BA9DCFF5F8F73F6DED4
+:104F600079007E753ADFFD063FD9ACBD5EFFFAD70A
+:104F7000FF5EFFDAC7139C4AD44F107206FF5C42F3
+:104F8000C8363739205D4888DF1B3BBC5A873281E1
+:104F90003F8B08D98ACF22F83FE552C87C4202589D
+:104FA000867AB9D8F58A274CC81E1714F2E15D3409
+:104FB0008FB67707DB4852CF8E4BBCC635A4969090
+:104FC000D6A8AA6F9708592F93B6812A2C4F6F2025
+:104FD00073A0BDC4C69F877FE13872A3DE1921E4A8
+:104FE00083544F4CB68CE37CB62A846835F0243B5E
+:104FF0008FC86184CF3D92F612FAE74C1921ED2754
+:10500000AAE3CF8832053914791D815F40169C913F
+:10501000617C5295D339C1F8BFED38AC2915849C19
+:10502000EC88C59FA9185D2FD6B19E90D73C79B862
+:105030004E53BD72362117132F2E26B33E25AFB720
+:10504000201984FA4884E267FDBE6735A5320BD784
+:105050007A850C796A46C34F88C9F021FA1168072E
+:10506000F3AC4F035C96758DEED747E7CF8CAB1052
+:10507000DBBEED7125EBB1DEDF709B3919CAEB1F8A
+:105080005D4E287C007F62F604708BF91DF09F6DE9
+:10509000FEF71A7AB6121721C7DC7A4902F73D7E6D
+:1050A000410381FD5A2131FA12785EBEB487CE37B2
+:1050B0001E9E61BF750DF12C076343943EEE5C08A4
+:1050C000DB48BE407C144FCE7E67A38735A3E9E161
+:1050D000B2A68F811EBE82F480FB18CFA7742ED695
+:1050E000EFC4636B83FB15CF9C09E880F73FF77D26
+:1050F000E0FD46EFFF9631F79F8F2FE840CCF3910C
+:10510000E1E574404842C6F1B265932442C0F72AF3
+:105110004922BEBAF05511EB4F605F3D5AEC219425
+:1051200013F71395B657225E53A67226793FEDDF2B
+:10513000685F8F9BA48804EDDD05953949188F04BD
+:10514000991C72EECFB68EB6B862D9379077CD0380
+:10515000418A3836CF54929A84EB39BD445F111A94
+:105160009F0E86B15F55967E05DC4A31837BBF80FA
+:10517000BBD163CA7328DCFBC782DBAF2508F2C54D
+:10518000F0672F607073FC3BE75BE1FD1F7165AE5C
+:1051900015AFC420058494F0A9FBCA499F9C036500
+:1051A000C365E27E9457F51D44912CE4EADD15F3C6
+:1051B0009F7243B9484D1E443864397610EB4A3625
+:1051C0000F109CB797E361A95CEC7B159EBB1BCAD3
+:1051D00072D6C0F30D228DC957F777C0DADC84ECA4
+:1051E000ECF0D2E7C91719FCE3E1EB810E3D8EED3F
+:1051F00032E556259E82F60F6CD8BBFB52C05B4F42
+:10520000A4BC06F998B44A0AAE2B20B1753D8FF3C1
+:1052100003BCF7DFF8050A27E0F17984C71D49319F
+:105220007A2509C2E80AE0B1E0A3DC300D2D98C56B
+:10523000C734C09B0BF44F5E1F890D118A875771CD
+:105240009C227DC0F0005E26C5635B409564F00043
+:105250005AE5D3E500D73DCF56D46C2759B82B2457
+:10526000974D1E1325569918834EC43EF5039EAAEA
+:105270002AB09C9610CEEDBC2CDA3D4C92EF63BB6D
+:10528000A9493FA5EFA9ED3137AEEBA8C4E80B144F
+:105290002A417AE9E6EBEA5FE3A774D65DA2ED91D5
+:1052A0004B09F9108907E9EA41C9C9DF1F323A61A0
+:1052B000F8513486AF76292949F05EA9324DA48F82
+:1052C0006892BDEF729156BA6E931CC171A2121B07
+:1052D00047D075B85CDFBB1DE69B24317A882EDE93
+:1052E000BAD105789D1455287EA3E9D58D281F7C59
+:1052F000273EFD163EE13DB50BA62607104252D2D1
+:1053000068D6E17C93369BC81924DA983EB2049E95
+:10531000B74AC949088F5FEBEBF4D0C96212E2F3D8
+:105320001EB7493458BF77719F9108E2FE5F4A5615
+:105330005BF442B9C4D6ADE8C4485565F7FF9B326B
+:1053400083BBCF38EABB2188EDFC14DE72D240E982
+:10535000611AB08D0474E0453A60FC300DE70F6CC3
+:10536000EE9324844F8FB9105EA0FF42A4B77BDC7C
+:105370007A11F6BBE746B539C5F0730CE933ECE2B8
+:10538000B8D1E13FC43B2FBF0D9208E70B237E103D
+:105390001F301F4C4AE4B903432EC0636E2389219A
+:1053A0005AC388AF39597C29B503CF4E87FABCCD93
+:1053B0002466E0BE340E99B814A57CC040BAF4C788
+:1053C000637548A780AF4512AC3B4CFA24DC7F459F
+:1053D00033295F3CA0B4BDFC15E8FFC0613966EA23
+:1053E00016FA24409FB3B3782BDE007C68B51B38D7
+:1053F0009DFAB99CE823C9A538BEA73849E9624798
+:105400003EC89570B6BF82F21AF150D944DBABD1D9
+:1054100081E36B505E47A2D5947F15CD85F8D9E125
+:1054200065FB90E5872D74BF7A3B52E4D76EE45F4D
+:1054300036BE574FB067BBACBF86F2AD92C1DD5BE5
+:10544000B52287E07BEF0041FC07FAF653FCC198D8
+:10545000B1BFD719DC4DB02E0F50D710E8A3EFC164
+:10546000F34C29BE4FD179DC513F7D2FD6E96D57E2
+:10547000D9F82442E5CB64CE27256448C2FD215CDF
+:105480009E4EE1DB3AB5784422A0C7F484560FE083
+:1054900092B2E6D853F8FC66EE23457BE8FC0DDAC1
+:1054A000EB30BE644C92CECC1A5FEEA1E27D5DC0C3
+:1054B0002167F11D5DA7BC9AB6EC43B811CA1678F6
+:1054C000FD55F67A90B2D97269761C318F26F49028
+:1054D0001E8B21FF6C77A79A498C900EE9692302F5
+:1054E000FBB4DD973A4E3490B3BD3F31E2D0CE3FAE
+:1054F000959023C837CA8097C0F31B48FC2847748F
+:105500009DCA9B309F6BC742170903BFE41429292A
+:1055100002F31E4CCB44857DD81555529E528E44C5
+:1055200094D7BCBD186757FA5E2FEEDF9D55EF6923
+:10553000F8CC8C1F65ED7D9C3E4E56B808EEAB183E
+:10554000FF648580AB8FF6F7A68127A03E00F3A508
+:1055500090DE499FB70EE5D162302CB1BCD01CA2C1
+:10556000AC674498FD7016790CB60BD5C74AA549AF
+:10557000E52D943BA9FDD2374A7E3E8272C103F2EB
+:1055800013E943C84F31CFF8FB6D0AFD5CA900DE7B
+:105590006E27FE18DA0375527200C76B6F6A27A870
+:1055A000874FAE6A36F0D90E2352BA5EE84AFD7DC7
+:1055B00029A743E8B72B5198C27ECAA4E27C9C7706
+:1055C000D742268FC69B77478759516ED12B3B60B8
+:1055D0005F916F7654D578C7EA17886EAD289F041F
+:1055E000E3C6F5426D0C7BFBECE3AEB08DFB59924C
+:1055F000FCA9943F7A7C42185DBB408F23FDFB835E
+:105600009B09F2959F58E8BD34DB2ECB27F672FF3D
+:10561000EAEBA3888748A1512D011DD702DB274063
+:10562000354602C67EA4F3195B72EA82B02F118F51
+:10563000B1D105F5CB5C23C64E2C836F8BCCFEC954
+:105640002D7F229D006F0478955C04FBB1655AA7FD
+:105650001964F84779B6BDE348D16B6E944FC7E93A
+:10566000F34DAE5F7EC7E9D60FE449E55025B4B3EC
+:10567000F2A562D2F73E1DFA59EDF02819427A528E
+:10568000383D819E1941B95AD40C76978EF464B78F
+:10569000BB9C78FF03D7B3FDA19BE8BA3374522BB0
+:1056A000E8E48877B985CEEFAA3D3FFAD8A9A4BD32
+:1056B000A85F77055FED9D06F466C65CB10A80AB16
+:1056C0000BCB308F3CBBBCDAEA770FB9EB55976553
+:1056D0007F8355309E050F779D271D65E68FD8E7A0
+:1056E000EF898C3B7F818BFA0DA062517EB0A9C9F6
+:1056F000D6A2FB281D3AE111FDAE9592092BDCBE26
+:105700007283E2FD547ADA84F66A2FD083D55EFD87
+:1057100080D301EE77AC0AF71BEA2DFBAD7039118F
+:1057200059D942E1519ABC54CE9016C2EC594E0759
+:105730008AD626ECD81A5C8FD38EFD00891BDEF743
+:10574000BB93D136787F572EE8980BE1E9369B134F
+:10575000B45D3ABAC2A2CF37BB987D9CE9B708F8CE
+:1057600004C6FF21495E82EB2655D120CE2FE8D01A
+:10577000A70D98487FA2FD564E5FFE4A83C9390E99
+:10578000F7E75C5C5E8F03FFB8EB6DB6FB37A2BD3D
+:1057900058E71E57E203C962978E967F691B5D9F8B
+:1057A000AFDC733E831249207F75056BB43516FA62
+:1057B0005CED62FCF565B7B11AF1E4A49FF3958B3B
+:1057C000E3CDDB13B1CFDB969DB76DAC79C142D38E
+:1057D000683C82CB3D25113603A8AF123BDF457DE7
+:1057E0000576727C2DE255D84BDCDE12FAFA6F5743
+:1057F0005D4AF9C7F79C4C907F886298549F001DC2
+:10580000517DD22719CCBF31A8FDE447FB898626FC
+:1058100098FDB448EC7BB9C57E2AC3F998FD64D6DF
+:10582000A30C82E74BBE5417B46FF786E710F03B2A
+:105830004FFAD8F37679202E01DC275D0309A40FF7
+:105840001117F47B13061B8DD1C3398CD37B2EE348
+:1058500038FB39C785760B987FD876213E7794B38D
+:10586000F1FCDE363A8AA438EC4F8E4F61237BBDC3
+:10587000A6B714E5D13199A05D2DF7550FE1F819C0
+:105880003BB498CD077EC8C3DB85FD09F42F73F9BF
+:10589000E4AF72D9EC5077B19FE23BB3DFCDA68481
+:1058A000F3DD26E6E3785682A0D4AAD83EA13D03D4
+:1058B00096361D07CDBC33D45EFD329D47F453822E
+:1058C00064C817A6FA9E58E3670AF68336A84E986E
+:1058D0009EB5F71B8F7E47CDD76487F39CFB0515DC
+:1058E000FD754B5C68FC7E763B79188DBA79A3F721
+:1058F00077792EC8990B47EF33D81F27509E1E7318
+:10590000B72D60C867FBED417B4CC627B39FA91D2F
+:1059100002ED6F5582BD128CE70B0E527BC4A7DBE4
+:10592000EDED5BF11F28972A09954B814A7BBDD38A
+:105930003EF977CED7A0A9646A3F134A23C097C126
+:10594000212A17172A6FA72DFC24D6BD290A7437E0
+:10595000697CBCB8C0430A7AD1FE67FC29F1B280E9
+:10596000E3BD3E298E71824DE002B4D758C755E998
+:10597000B84E79325ADEB6BDB987DAF305318C7389
+:105980006CCF3D415E21E72F77772A26D5E7BDC151
+:105990002DDE329B3D01E5B1F5B9264F604F9CAF3E
+:1059A000FCCDCC1FB1CFDF1319777E1DE7DFC6E337
+:1059B0002CA3E4B016A47A6C328F43D5C84CCF82A6
+:1059C000BFD849989D9EF05AFDC5E69183E81F9681
+:1059D0004CFE45D1219827877453FF10C8B8F6CCE8
+:1059E000DC73A77B8F8BC5434982FBA97CFECC7CF3
+:1059F0003C2ED320337A0378F6AF817F3EB8202D3A
+:105A0000E16460EEBADC005F6993BE85FAAB93593E
+:105A1000DCEFA3FAAB197AD105BD9836FDDCAB7F7C
+:105A20003CFA79959CD193ABE431F464EFC7A49F21
+:105A3000D7F17D8679D7C9F3CEAE9FBFBE324CE594
+:105A400044E88444FD61B3DE90DC487F53490C6335
+:105A5000DAE0F7DD8AF0BB9BCC652896424ADB276B
+:105A6000D08E0B215E6BC9FF0F7EDF0EC493737C5B
+:105A7000A7DF2787BE46F592EF3CFDBEC824F0F7AE
+:105A8000624876D7D4FFD4E2EF7D4B8ED5337F8F3B
+:105A900050FF6E8F9CDC82FE5C648AB11FDB9777BF
+:105AA0005F5B8F718FC83456FF6585D5FF1814353D
+:105AB0008D1B7ADB0C94FBFDABBF5049E3EE51929A
+:105AC000962CFE9AA7393984FC037EDBB7717D01E1
+:105AD000ADEF20B29E1A8D49D87EA91CA4FAE7BD6D
+:105AE0006292F248E3E3F16E1E1FC7B82F9E3BDCC3
+:105AF000D3A1D1726F47943E3D8BD9B9C6CE0E83E8
+:105B0000961F268941A4174F318B03F7F373862E16
+:105B100095B4E2F328F7177585F147F6C9E2D24F3D
+:105B2000BFF8EDFE350857D01F43D48C07575F47A9
+:105B30006505C2D3DF11ABA0717C6948C7F8D0B34B
+:105B40005DAF767A313E240F44B1BCB5FB8DCE06F5
+:105B5000C063D0C5E27EB23EA742B1E8AB7FE3FCB2
+:105B6000A2556EA5F6A96640FD5CEC4FDAC6F26B55
+:105B70007FCEF91ADAD3F35A4D63ED777039EC6CB6
+:105B80007F9CB7DF7EF059A203D30493A684788963
+:105B9000B6CFA7FDB61F7C8BE8B3314E9B3614E021
+:105BA000C3BEA524B617D69DDB5E45E1DC7EF07949
+:105BB0005206FDD21CCED0BA3EBA7F45EDB5B4FF39
+:105BC0003D3E726582C78FD9F98DBE773B95B9FA94
+:105BD00095B8BF6E6D7A1996DFE6FD7D712069B0CC
+:105BE0003FC00B75C68BDEC67D53CA4DBA2E112F32
+:105BF000BA5B62E39A37821D01FF9EAC070D340E3B
+:105C0000269717D463FC7772E54C7ACE3AB931B84F
+:105C10009ABED70BD6B267E5E7F1BDB0FFC24A29FD
+:105C20009D7FB27ED10D58DF3D337E184DA06C1C98
+:105C30002F4DE37844D7A9FD1AE2326B576D590E08
+:105C400099407E500D25E41BE53F3FDA3C96729E5D
+:105C5000A33CD9D1BECC513FD3515F632BB7733C2A
+:105C600093852AC507492B14DEBB783C90B4B95DF7
+:105C700088D7908F950F86EFF7BE52C59EAF5AD644
+:105C80007127AE6B02F955CAF97CB266591FFEE561
+:105C9000F567CB65146F51B413AD72C1802EBB167E
+:105CA00065E48269F59F2D7261A692FFD1E582902D
+:105CB00007BD281FC6D0530F93E47C05E3F0954C35
+:105CC0003E64E541AC15E55F8B32A75E5944E501C2
+:105CD0008D671132678B81E7252E565EAC4CAB3752
+:105CE000AB501E5C509846BB88F397E0077C96C289
+:105CF000536D9F4BE5B59837143D624A115C8F5642
+:105D0000832811EF55E0376C27E26567DDB719F797
+:105D1000B17D8327EE9B900767DBB75D801730D698
+:105D200033E59C4ABFA1CFA1E72BD42ECAA92AA84C
+:105D3000D72DE711D72090B00F390B5D593AA47FCA
+:105D4000C3BE86C6DC5F629465F717F09383F829BB
+:105D5000187A9ECA17273C6AFB0C2A4714C0133EC8
+:105D600043515267042DF222A2ED41BFAFA0D95892
+:105D7000F41B3C978B4CA576E626859FCBA5ED7250
+:105D8000428C0BF26213D28F474B19CCC463F19053
+:105D900082211F0D3187817E7C306E78E11049C2EF
+:105DA000FB6074889E5BA91A58623AC2339FC22373
+:105DB000D6A57279E7F2B2F816D06D928CADCF3AD3
+:105DC0009531F49953CF08387FA830B9279E4BE519
+:105DD0002A8AAFB3D1B5C0ABBF928DEF6CB795EB4C
+:105DE0009D7BB93EEBED58C8CA4F7D83D2E5D7B94C
+:105DF0003EF315F711C4B74F8995A23E32BB97D732
+:105E00003700DDDFEB63FD447B31EEDF71BCFB8AE5
+:105E1000D93E39E77D88AF6312A72767FDA3BC5E33
+:105E20006954D9F940632F93E7C5EA2BF4DC4007A6
+:105E30003D877279C41E1783FD7C14F7D34DDA8633
+:105E40001E2ECDCA7FB1BE7B9F7A8B94CEC67D6D50
+:105E5000A3E798837C9EEC3A78FDC23459CDDBD51C
+:105E6000017C07F8FE0A7AF670BD7536BAFEB1A25B
+:105E7000D9E499A8FFD065FCB342FD5493E2776B57
+:105E80006243E2F3484FDE9D745D8A376C06D07939
+:105E90003D366A7D87916E607D442A45BA11714B0B
+:105EA00073BCF38EFFADD0F30E76CE7172153BF757
+:105EB00018ED4F30BBB7D761F79EAF5F71AE76EF8D
+:105EC000F9FA0D13D8BDBF55CEC1EEED5E7DDF9062
+:105ED000413E82DD7BA1F1AE0BED5E926276EF0575
+:105EE000C67E2C0723F7D6E3F95D64AE90FB8FD412
+:105EF000A3DC8F2C205435FF5FE5DBD4CEFDAA6AEE
+:105F00009C46F832F8AE74317D4B52DEE596F8F1DE
+:105F1000F6CA8FDDCF0FB927F0F3B7E37E7C94F993
+:105F2000CFDDCF2F71B373032A0F552EBABB73AFDA
+:105F30003FDBB9C11556B8D52893AB4A53024FF889
+:105F400047F187136E77218B8B77E75EAED17E0E9C
+:105F5000FEBAD8CDF9D6111FFF4B8D3F46DCFDB4FC
+:105F60006289BB9F46C590FFF1AF47F51874DECC40
+:105F70007CE7796E007287F6779E93FCB5E212ADEE
+:105F8000EE4C7CA0D53D467CE0E38A4BDCEECEC4F3
+:105F9000436E779FC3B941B03496A07676918B203B
+:105FA0007E645FF2B00CFCB22D7ABD6E9666F3C2D1
+:105FB000C4F8FFD33D8D8EDF1D555D1817ED3EBC37
+:105FC000B410EDB4ADEEB6388ED395EBD2F6968E16
+:105FD00086F79B6EA66FE5F61D150F4F10E79279B9
+:105FE0009E5FB7F614852B501DC9C5FC95AE835F27
+:105FF0003C2CA31D152D28457BE71FDD3CBF0A90D7
+:10600000F86B4BBC741BD20FC21F242953C2F97604
+:10601000D1F9CE06DF9D7CBFE4F63B2B1E9E20CE41
+:10602000FA97864FE0B19FF385DCBE93CE2FF02A1E
+:10603000231FA07EA85286304FCA9DF6507B438E08
+:10604000B94C5A16F2A0CA45F32B810F7E84FB4E41
+:106050005EB3F3A9474B0C5179E6D6285CB2AF8DFD
+:10606000CA4791FF134C7653BD14486EB5D9F94217
+:106070006F07DC3CCF2AA8D03C2A95D345D01D3BE6
+:1060800082F412AC9B5E86F422A90C8FBD06AC0B89
+:10609000FCDF5EBE8E3E7E2E29E621A4FCEB2D9811
+:1060A0005F6594D1BCB9B739FEBD2448F9DC8B7863
+:1060B000988B791DBB874A74F45F4291D7F14CBE2F
+:1060C0008C9421DD6EAADBB40CED5BAF6E7AC6CA90
+:1060D000031EAD0F880FE197EB5CBE728CA75533A2
+:1060E0007D40A2B567C9D3E864FBC2F741E05FA970
+:1060F0005218FE319F1CE09579FEA0D8878CBD1EFA
+:1061000065F8CDE4BD9FB0CB2F39C8CF95887267B5
+:106110008B645DFF2E4A0762FDEFB979FEF15F697E
+:10612000FD693793CBE4E9195F6FC17343C315A3CE
+:1061300067EBE540DF163F391064F97C828E7C27DF
+:106140003AC95498C7AFFE75F72F033F780918BFB7
+:106150002B23E2CF46DB395719CF4F14FEB9FF0E80
+:1061600042E3B5A5552C7FB1AC6A0BCD67A4E777A8
+:106170008087923B147A5E0AF574DDA27F69AF6A6C
+:106180003BCF9BB4CE5E2E214C2F7E829FBBD1F79E
+:10619000304F09CFF32B2196F6A8B7E4961CAA2717
+:1061A0001DF2583C9DF9EA0B557BBEBAE83F1E9E96
+:1061B000449EFA2E627C4A9D97A5DBAE3296073547
+:1061C0001AAF4C2E14E8A681FB528879B3180F58E9
+:1061D000CCF266F34892C607C84276FE896E8C35CB
+:1061E000CFFAB32AD3535EF2079A6FA992B449E566
+:1061F00091633FC43EF456B23809EE5F11D4E7F222
+:10620000DDEBC5BF601E7F11C853C0532EC73F6969
+:10621000E0F893888474195EACDACE53558EFF3C57
+:106220001EA7F03BF0ADF27D501DEFDBB87C3B1BB1
+:106230003E9DFB7193A0FF100959F7836863E789BE
+:1062400089FDC8F84DE7395FBB982F08F34DFB086F
+:10625000F339F6E152BE0F5B75B10FA411F7818AD5
+:1062600072E443928CA3FECBD3193F4CE279ABA4EA
+:1062700091E1DD0BFFE13E1436DBF701CD6DB4D3C8
+:10628000BC0E3E180FFF32A7FF25AA712FA5D3D74A
+:106290007C34BEE4CDD0CB93075580737B318961CC
+:1062A0001E2CC1BF30BEF7610EA5931D3192DA02DC
+:1062B000E34C2EBB87C541D105B3F4DFAEAF9830B8
+:1062C0000EDAD781171D08B9ABC34B862E18BF5DF8
+:1062D000484D26315EAC195A1DC69B27C5F51A9A42
+:1062E00067418E188827D5D0A9DEFBB92ACE8389CD
+:1062F000EDDC5C8D33FDEE6D644FD55057233EBD14
+:106300008D0AD52F6A55FD5B0ABED79DF824E77527
+:10631000FE4EDBC8E3B73BD7E7DD8097572D7950BA
+:1063200077A24F0AFBF0818E172E00EE5AF03A71D9
+:106330003DB55A015D476D2C489FE9BA382B27B609
+:1063400063FD88AA33B9D0C0E46958774DB83EFAE6
+:1063500047F86B6559BC08389CF4F3D7C2CF5D8809
+:106360009F0AEBF87D5EB49BF28EC94073E3F7CBD6
+:106370003BA590213CBFF00E0D21DD405B6A977B71
+:106380001783DC42BF54497DE37AB4A3A25AB569AE
+:1063900059CF9F55666FAB98F78E7CAFE8D2CA9005
+:1063A000B55EA578063E3AADD278DDA3DE341D6F2A
+:1063B00080DAC9C12A1741FB74C7E97FF652BBAD29
+:1063C0005565E304BF66931F0FA86E5B7E71467E22
+:1063D0004449DA65F1A385FC2F5293418F25BF51C3
+:1063E0008DB2FC46112F147168271EB676B0782145
+:1063F000F05F45394C7980C7C39FE0E7645AD46F9A
+:10640000201D69514D473AD2A27A392BC7CAB1FC37
+:10641000033C4783F67B3B74DAFE9E8E4A5ADED5F8
+:1064200011E3F75316F2F337839FBBC5E933D591D8
+:10643000A0CF6F7534D3E7831D49FABCBFA395B0D5
+:1064400073B1365A7EB4A39D3EBFDB61D2F7FB3AEF
+:106450007AE9F3918E3E765ED7D14F9F831D29FA5C
+:106460007CAC631FAD1FE818E0F0C7E312C2CBE3BA
+:1064700087B906ACD31AA75EE7A371738DD3ED334A
+:106480002F7AE420ECD36E2EE7761B13CBAD456953
+:106490007B7ED182E3F6FCA20B0FE4D9CAD37A2724
+:1064A000DBED977899AD3E67E14C5B7D2856632B19
+:1064B000072A2FB2B5F7E9F5B672A9F937B6F69FF4
+:1064C000685F61B78FDAAEB2B59FD2BAC6565F9435
+:1064D000BCC9563F7B6093AD3C6BDF976CEDB7D684
+:1064E000AC6D23D584B4787ED0E52D01BA0B24752C
+:1064F0003422A20FFC43179E5B6A51901EE0AFE46A
+:10650000464939E60FB90D66F7B81B4C6ADF43FD03
+:106510004C7C0FF555D80EEA5F413F00EADFE5F508
+:10652000D3793DCD3F52B03FFA090DEC9C4FC543A6
+:1065300056E0D3EE30E81FF44B4F303F2213AF3814
+:106540003D2A8EBAD1837190283B2F15FE1BC0DDEA
+:106550009618C30EB8D3C3F58857A1E308FB287378
+:106560008EA6B373451253A8FF91CBF343447F6FBC
+:1065700003CB0B03AEFA0FCC5FC2EB3067A0CD8C20
+:10658000142B0B3C5ED06F2F57F4D9CBF38ED8CBA6
+:10659000730FDBCB2A3F1F76C2FF3D0EFFF68E81C5
+:1065A00039AF55B0B80D9E6FC06ED0B88D1FF6478D
+:1065B000A3C952ECFE8597E3C90FFC8EE73CA49675
+:1065C000DD07D332EFF5E9D8DE6BC0BAE6603956A5
+:1065D0004EDB713BC87762D96189AE97E54B062ADD
+:1065E000615E0BBD78CBED70072AED65A7BDF58820
+:1065F000E7A3D9DBE3D963A3E4E9E933345F4CDCF7
+:106600009FB88F9F17146DEE3B88F1F4A2751ABDE9
+:1066100017E79EED4AA07FBEB5CA15DF8376359495
+:10662000F159B421D5897651D181D2C7D00EF9D490
+:10663000A9A13AA48BA236AD1AE317D3BD3ABFFF86
+:10664000992CC2F858D181DD523D8C33CDCBE20577
+:10665000458DEC3CBCEB71765EF3CC8B57686918CA
+:10666000F7BD4839953BEF3CE131308EF14E1EBB12
+:106670001FF6CE130B7E827CF0BB8EC379D673CB14
+:10668000777EF0F3F96E18FF9DC77E3E5FA1F98A11
+:1066900029AAA744FDCD6786E7237D9BF5A412F3C5
+:1066A0009A6FD55482E3DEEA65FC43D6313ABEAF39
+:1066B00040DD8AE31714BA76E1B309832EF9D93C99
+:1066C00040C2E9BEE05FDDF49CBEEB593F1DA79DD3
+:1066D000C75F88C6CE953755E85D41286F2AD562D9
+:1066E0008069D2956B7AA662BCF8454FECEFA1BCED
+:1066F000E9D3E0A2637D9146EF4B754BDA122C9BF8
+:1067000025CCAF39594A2A4B411E284B0C3904F38A
+:106710008DCC607905C27F0DA7470C24BB1D4AAA0A
+:106720000BEFC77419848EB34319781ACB3B1A58F0
+:10673000F97657DBEE166A5727FBF0DECAC9F9AEC9
+:106740006AB40FAFF395897BB09EA9F0FEF6050AF7
+:106750007D2FCE119E7ED143D7B3E96732F55343E7
+:106760006E62066A28BD5C628D3304F0460A383BCF
+:106770005FEBA8A470794A5DA61BE0CE8F30BF36D0
+:106780003FCAEEE7879AC04EB1CA71F8FF552FDFB6
+:106790001F4BDCEC00D7C3431D5E3ADEFD1D1A7DA6
+:1067A000FEB8234ADFDFD3A1D3E7931DB109E398F5
+:1067B000E33D7738ECA5FB66C32A00DEFBF8F9F46D
+:1067C000FB552EB3FCC2F1FB3FD87178524345967E
+:1067D0000E4ADAD8F9EBB8ED3BA5EB5600BD793699
+:1067E0002A89BDD42F481659F3E77BDCC92214AAA5
+:1067F000EF798E2F417D017C47F34B0CB2BB4EC32A
+:10680000F3D6752486B82A8AF64978CE02F83F7303
+:1068100046D83FC0983F2AFEC3D339483755640055
+:10682000C152AB0CBD13FB1D9916C338C8A292F21E
+:106830004EE463325BD4C7E41FA09F3078818E475B
+:10684000F5073DC9B95EA0EF0392EB3AE40F9CA7B0
+:106850001E9E5F7BEA8F2A9E47F7BCAA7A31DE56DE
+:10686000F4E42B2ACEDFE34AAB280C9BBC331BF0AD
+:10687000FCBF474DCEC07C80A6DEFDDD58BE2F9C00
+:10688000FC0E1396331B9E89029F78CC07B0FE73D3
+:106890005E62C617C33C6EF36A5C6F0399DEED9DC2
+:1068A0004AEBA760BED4A5305E6F31D4A32D4DCF87
+:1068B00095CABB0D2CE7B27293775AB709FD2FE347
+:1068C00072830493A5E8DF65CA1A94C7383FCFD412
+:1068D0002BAC9E78D953ACEFE6A7FFF89329809FA5
+:1068E0005B9E940630EE54F4E46E8A6794532897C6
+:1068F0000E741CD6BAC57E5BFC8145989781784E94
+:1069000049A932899AA0F43B034A5EBF84FBD1FABD
+:1069100079A2A3DC7CDCC7FCFA456918C722D7172B
+:1069200029EC5EBBF3DE3ABD828EFBB5939D2B1442
+:10693000AD4BAB18873FB0D00CCC81F7EB5797D756
+:1069400074C2BECEE0E3B6035B36A03E8BF8359A48
+:106950000FCEF322DE167E0CCF8BD8C02FACB8B78B
+:1069600010BACF3DBE81028CAB8C7CDF9D678D5B06
+:10697000F7E40E144863BCEF76C37BA433788F70C2
+:106980001DD0CCDC3C18E79603BBA79A80C75B48B8
+:10699000DFB55F42B87F2A13946F6F1D5C94F34993
+:1069A00028DF0C659F8EE7DE472E453C3F34583A82
+:1069B00080F270A797E9E55B0681AE82C8D740F305
+:1069C00020720E187DB314A087677C2F37F8C09E05
+:1069D000FA5199A1B98006D2BEB7BABD174359D5AD
+:1069E00066A0BD95F68D507A5BFF6917BF4C39F2F2
+:1069F0008C518E70105ADEE95DDC8DF927B5CD5EC5
+:106A00006A4F15B81271CCA327475D54BEA2E85B4C
+:106A10000CF89773BBE939DEBFF7B868BE1A1E637E
+:106A2000DE01EF6B15725881E77DE050E37740CCD3
+:106A3000AD0AED07EF7BDD79B84FB1A7515E935EEC
+:106A400042E5F9BC273D347FAAB6CDB891C689B4DA
+:106A5000C5D41E9A4A327F68FEEC27B8DC5CA09150
+:106A60003AF4272FF2B1BCAADAE6CBD763BF69AB01
+:106A70009BFECD80FA8552CAA4E74BCF337DD0531D
+:106A8000F0DD012F946B73140D6315833E63968EB6
+:106A9000FBF4737F35EED3606E4CA3FB1652F2F617
+:106AA00062FC3F0DFE3DE8A5278E6FF8DDC5787EC0
+:106AB000900F8A18E31CD0AE06F07D31CA11C49B3A
+:106AC000B9B9C14039A82637229FBED5BBB91BF33F
+:106AD000EF00EFD3BC80F737BD50867D18EC34A6AD
+:106AE0006896F2823F83DD40F97433E55325F79EC3
+:106AF000F5C8F750FF0CCA931FE511BE2FACBEB608
+:106B00004C9441B42D04383A059F13D30B7AA1D687
+:106B1000D2BE01F8DC5DCFEA0FC17C268DA301ADAA
+:106B2000E7E13AC1FEAD457DA8A4709DB8679877AE
+:106B30007EA9DCF299D9F0DE53C1FC167F2E93CFEB
+:106B4000FE5C9DC6EF067DEC9C7FE4B9600AF1E532
+:106B5000CF6DEBF3607D4939F5470329360E3E7161
+:106B6000FF033C5F5FD296537BD55769BF1FEB7124
+:106B7000DC8755B8BDA738DE7FABD4385802FDDBC3
+:106B8000D3CBA93C497B79FCAC84C5AB6F4F98CB88
+:106B9000D05F9D3932508FE645D5A9234FE1730E62
+:106BA00079B71EC568CC9BFB343E7FE765445BA389
+:106BB000552FC1A57D7271AA8B1EDBEBE92294676C
+:106BC000F36428C33C398B07649CA7F09AF2F33C2A
+:106BD000571FA279063B83AE788A9E3B3EA6ADB690
+:106BE000F4FF079FC82762F2058F7B908EDB495F19
+:106BF0001DDEC785BD67F751B8BC71734741212CB5
+:106C00009EA06831CD04795D17AAA5765E998FF1B3
+:106C1000BF7C70D1656897A82827A0FD833E16DF4A
+:106C20001D2922037B75F4530C42F51ECF2BDCCCBF
+:106C3000E715F2622BF8EBC60520673F37BD5EE42F
+:106C40002BD23CF3A161E90C28CE7B303F91C629C1
+:106C50004654B4271FFF5C413DDAEF3F8CBBD05D4B
+:106C600002B964FC720AF2F71137955BF7E632F964
+:106C700028D6FD1D1F3B6F3BED65F2B6C70DF555E0
+:106C8000F81D0F10DD30BF7A2A405273C14FE2F277
+:106C9000D8935C47E9CC03BA4FA774610A3F893C9B
+:106CA0008EF19562174959FD965361DAFFB497E169
+:106CB000579CBF8E9717F0A4D807C7792B1E442383
+:106CC000DE3767F685C59F7F546FFC925039E176B9
+:106CD0008D753E399FAF4F3D255138C4FB8B5068B1
+:106CE000E37B2549EF97AAA7145A2FD62BDA65EB39
+:106CF000D93A7EAFB1FB316A94F1AB7A40A6F61F68
+:106D0000892A23D6FB2701B4CFA765F94CDC8B1960
+:106D1000BD8ED811EEAF51393B9A0F4D6A076D0EFB
+:106D20001985A88F3CBABDDE99D79281FBD424DBAC
+:106D30003A047F65D75340EB519FA03CB84521DF13
+:106D400040BFEE669E6F70B30CF404F0EFF8C340E2
+:106D500002E7FFBDF0279E64DFB1B979700FCF7BEA
+:106D6000D06D71AC5B0E6CA471A93F68AD456847EE
+:106D70003471FFA8C03524B37B434764E4E79E70B9
+:106D8000A252D298BC54A228FF85BC9CD98DFAF29D
+:106D90003E352B3FD169BDCFCFCA5DBE99DDDDA8A1
+:106DA000DF73993C6DEA7DB2DB2C467D2FCA3FA490
+:106DB00076D47D6AEC698CFB994F7874D4E7D0DF88
+:106DC00040BE33AFAAA4FE4B4F19998C76DF330532
+:106DD000EC7B1F3D4F78F6A22B0DF6E2655E8B5FD4
+:106DE000F54EFEAFA692E098E399B6F1A69EDF7845
+:106DF00030FFA02B275BFF4CC145747CE8A763BF25
+:106E000077F2FD4338FE3B577A691CF841B79D6F16
+:106E1000C5F301CE975B3B34CAAF99FD473EC5F33E
+:106E20006DD2C6F8B398F1A7279A67E3CF2CBD4C73
+:106E30002129CBF97519D7DB597A994AEB4F635F52
+:106E4000CC6BEBD0CF71BEB271E69B7596F9E6D8EC
+:106E5000E643099BB9E736415CD979BFC629EFC43F
+:106E600053C8BB021F1B3F4892077C50BE293D7090
+:106E7000294DCF93B4FC4E68B286DBD78B1EEDEC68
+:106E800042F53DE44EFC07EA7FCC5B413AFFB23B62
+:106E90007101F613E55B5F0B9AB8AFB7A07D02F402
+:106EA000B0E3CD51F72B87A6E8593E1943AE31FC2C
+:106EB000717F1DE537961F3AE276754EE08739E51A
+:106EC000D64EAF53BE31F9F5979B4FB6EDDFE8F9DB
+:106ED000545A9FD54F4942C6D0739B8B8C4262E770
+:106EE0007703F91DD3F1B93D65A27CB857D49B5205
+:106EF0004F4331DAC9D97AB4B70A3CD9FE786FFC6E
+:106F00005EBF681FEC417B6B54FB80A37D99685F7B
+:106F100048DB3BE111F207CB68CF297FF664EC3DFB
+:106F2000846FB7CB315E9E18AF8C8E27ECF8F6DEFF
+:106F3000D9874C05E9B2AF0EF5F208F85118F77889
+:106F40004889F963167BA49DD3A77ACA67C37316D1
+:106F5000BF41FA9E44EDFBB9F9C5658513E57FBFD6
+:106F6000C1F5BA28DF90DC7C29B66FE7FAA1153CA1
+:106F7000011CBFF541D9C6B7FF0DEF7F1578678CAF
+:106F8000639F5431FEFE2F076FD138F016FFA7C262
+:106F9000BB546B3BE8067897EA12BD37B814EA7C1D
+:106FA000C0A3CBF08C1D9E4BC1900D62FC8FC755CA
+:106FB000B18CF18B651FBE7FEC1290DFFB78DEFE9B
+:106FC00005DFDC7CF4D330CE707CEE5C7EFF7FF698
+:106FD0004AB0FB1FF7B373C10BB87DEB84FB713F65
+:106FE000C3C7D1F8929B51BE7E9008D033F963AEEF
+:106FF000D8CF6A31EEB042A6F69FB3DFD10E766EDF
+:107000007E2F3A7CD0FF5842A6F2FA8378450AFBDD
+:107010008F872712976DDF17400FD37A2E4B5E2B89
+:107020007459CF738F12FDAE5AB4671AC786E3B78F
+:1070300008C70538FFCA09E3F36F7278DFC6737EAD
+:1070400078B6EE93699CF4A6047B3AE775F6BFC95F
+:107050009D2A9828BF73FD3ED9763E753678B6F8DE
+:10706000591CF8C694BDDFCD0301C7F938DBF7081A
+:107070008F73012666B2EF1AE86EB457579C60DF33
+:10708000197C0E5F15D17B84FFE487FD5E11AF662E
+:10709000DF9313DFB553405FC020EB76CDA0DF73E5
+:1070A000234D2B69FB437E69ECEF67F2738A7DFC0D
+:1070B000FB70852DA6DBFA1DB66040F8436D2508F0
+:1070C000C7A06ACCFA3E8C7FF4731E1A2FF7AC6C03
+:1070D000DC1102FA397665AE64BD8F98E6F436BFEE
+:1070E000857DBF6DF078D2EDB2F0E79F793DF4BFBA
+:1070F000263D06FE4EF0FACB93123F07374AACDF2F
+:107100006B5403F67A67FF77FC61BAAE63E3DC3B4E
+:107110007C93E3A3B979E2FEA46912FFCE9A31DD34
+:10712000FA9D3527FEBEE84FBEEB07787E29B5BD38
+:10713000781BF2539D97D23151F43908B7C003F050
+:107140007D2F7EBA52ECD36553AAE83E0978C47C01
+:1071500018FAC27849ADC1E26879FCFC63C14E5FA0
+:10716000AA93FA71FC3B9B0AC015A2F34B81FCF178
+:10717000E717E3461432A4C2B8EB5CA936B40B9D02
+:10718000EB10ED86FFB8E43308DFE05197B6A57445
+:10719000F4FA3374C3E5D2F47E3BDD9472BA89F01D
+:1071A0007B6144692B69B6ECDF9400FB9EEBF9D25E
+:1071B000D311B483A0DFF4AFB5B97518F70A85DF32
+:1071C0005783F1ADF4F12CC76724C0DA4764D33F8D
+:1071D00013EDCC5F32F9B26FEF974AC68ADF1CE538
+:1071E000F941FFEAAFB49D6FAD8C571F8AD422BD21
+:1071F000ED8E615C63F0E84525C877972B2CFE3255
+:10720000A89A37E1FE1CBDD6934BE366E7B88EC162
+:10721000E30937EA8FAA2646877B5C89A5F9280708
+:107220001F2317239CAF20AA2DF9779B38DDEF533E
+:10723000935DBE18E8871D7FD7D3EBA5FC4BEDBD52
+:107240001B763CD4837159D23D89F2FDF4A6773781
+:10725000E315D04195C5D39FBB3344CFB1810E6DAB
+:10726000FA26D274B203E3A36B5DFAF5CC4F6672D3
+:10727000E76192FC4C605E56FE8C9237DD2BC57741
+:1072800032A78FF53D55F15D404127FB522B72D659
+:107290005AE8A42BA0DAF0FC0B2EE787B9FC16EF16
+:1072A0009B8EB37C1858078DFFFCEAE2923DB88EA6
+:1072B00048EBC90E6D0E8EC3E22C1FA4CA9EA01F00
+:1072C000A4E4EB17EB84754DFF2EB4BFA2D92E8733
+:1072D000051FAD6A0CD8DFF3FE95B2B19EFA279F69
+:1072E000617EB7182F12077CCDC17525B6844AB3CD
+:1072F0007816F85CE3013C4E23EC821EC05B797784
+:1073000011BDFF94DF95BE0DFDC13F041339791601
+:10731000FAFB2ADFD72C1D323D86ED501FAD50748D
+:10732000F7587A69655C1E13EEB5E1641B19C34F0B
+:10733000CDF0B9430F6AAE3E37B66F266DF4791DB6
+:10734000312EC6E709BE1F19B94C86420B50BEC488
+:10735000651A8F3CD1B632670DACA3C53D10AA812A
+:10736000677F80F1DD0B9B651AE714FAD839DF35AA
+:107370001B64F30AA0B79614D3CB2D1B581CEB9AB1
+:1073800036FB7A86813C16E6219EDB8E7E1AE7FD6F
+:10739000AACCBF0FC9EC85975379D5988745BF27ED
+:1073A000837CB322C0EF4111FABDD024FB27793E84
+:1073B000BEF610C681BF1F607EFE707CEDA5E87A28
+:1073C000DFD04F7E9CD6D12E9A588F27EF906DFA42
+:1073D0007AFAD7ECDF9F9C8F7A04F94E192AB9D636
+:1073E000222703E100C5C7E54DACDE39AE3F1CA442
+:1073F000F5C31FCAAD63D96D7A98E17355FFD8FD07
+:10740000F57088D53F38B61EBB3114E07A62A0040F
+:10741000E5F7AAE6B1C7D91E0CD376276E7EE31A2C
+:107420008C7F1D73D9EF897E25C8E0B82EC8F86C13
+:1074300078EF97B616E17EDC226998CFBD66923E62
+:107440001DE9E5EA0DD5340EDF1C64F4BCD19F18AC
+:1074500046F971C383ABB7E2F941E111978676EB48
+:107460003EC73D54F17CC1A137405FBD86FA2A82F8
+:10747000DFDBA6DF394FC5AE644B3673F270DF99A0
+:10748000DC35F7FA35DCF7E1466E9F9AB36DF6E925
+:107490001B0EFE72EEE70DFD0E7BCC41AF2F931855
+:1074A000B59BCDC68046EF239D7EFF670BD00EBFF8
+:1074B0007E52CC9A0728ECD46195D9D5C3BF9846A3
+:1074C000F313C6A3AB71EDD54699E68FFEA5EDD5B6
+:1074D000E14646E72FDF3137B4668C7EB9C1D273FF
+:1074E000B2575FBE63627E7999E3E175BE2E414F6C
+:1074F000682FAFB1ECFBE4A07D5F9AD7D9E7BDBCA4
+:10750000C53EAFE09363892E3FDA1B84C4A8FD23F8
+:10751000EC57D23D77CCEF8267E55F27F363383CC9
+:10752000C8F76BAA98B8403CAF44D901FB398BD35C
+:10753000FBD1F8DC10D2B3733DC3AE11BAFFE6B78E
+:10754000D8B96545FFEAA78AF4D1F4B7C0B1BE8FB8
+:107550004A7F42AE3BC7C9D05BE347F48B3E663AF5
+:107560001B7F1F52E74467420E5CAD0CB8175531C4
+:10757000F972233C8F6042553E3E75FABC9A9F8358
+:10758000C1E6CDC7FBAFC37BFDF43EBDB93D94AAB8
+:1075900000923EB662D6742B3CB7F17DB9BA7FF942
+:1075A00021CC0938E64AECA276D717D8F9FA8BC76E
+:1075B0001FEBC1F26F405E493AD2DB5A5AFEE0B887
+:1075C0004E7FAF625390F9C3AB9A56BBADE33AE935
+:1075D0007795837E4F707833F69732528B7259AC21
+:1075E00013E56411CCB36AC3EE4538CF0DFD07DD5A
+:1075F00033E0FD3AFC2818CCF7F920EBDFC2ED4E62
+:10760000E285F502FDBF80748BEBFDA2C4F49F926E
+:10761000765BEF4B5EDBF6C6D2B1E4FA439CCE77E5
+:1076200071B9BED19F2C0EE667E56B6153E97CB45E
+:107630006B8A91B72C70977038544FEC1166E7B095
+:107640007564F0780BC3E30BC757F4E4D78E8FC78C
+:1076500007C6E18FB3E1F1D85E3FF59FCC4FB1FD96
+:10766000CDDAB725F49E8080B318E1E4F62DDA89EF
+:10767000820E5ED8F8C63549E68F75337F6CA41646
+:10768000F1F5C39038872D7459EF51FC3A34F677F1
+:107690005C7FC5F9EF6CFC73D54DCF527FE1573756
+:1076A000FD5B099EFB8A7EE3F1C7553C8EB36F9369
+:1076B000A775EF18F39EE4781B252788DDEEB9A1A6
+:1076C00069F5D610A0604B20FC295CEFB8F65C137E
+:1076D000F38BB2F65C2A84790C47397DFC0AEDB94C
+:1076E000AA09ECB956B0E7E658ECB95699DE7770BE
+:1076F000DA73CF91C467E7D566E33CCFAF63F1A8F7
+:10770000971B67B9505E3ED7742FD54BBFE5EB1B77
+:10771000E672FDB926BBDE7825688F678C92A78E4E
+:107720003CE9F1F4CF6FCF53FF80BD5F8272F0B9B7
+:107730003D2DD7DC86F4B7C74FEFB339F7E7D990C3
+:10774000CCED243FF557841C1A5463EF0C46904E41
+:107750008B625BF4D1F439DCC8F4DABE158156B41F
+:10776000E7F6F1FEAFD657EE45FCA0FF84F0A74345
+:10777000DCBF15FE35D75F57531198DD27A1AFD475
+:1077800010931F37F4BFE2D6A1FFB5C26FC63F000A
+:107790008FB67D0ACDB37BC1C5E5C823219A1F25CD
+:1077A000E613EBD24276BC3BE5F7D9F4D8F3299641
+:1077B000FF20E6BDFEC15216A7E2E596CDAC2CF443
+:1077C000DABE948BE9D3F61CBA7EA097D98F43F921
+:1077D000F5F659346FF69CF55CCAF5B1E839C4CFBB
+:1077E000447AEEB3E81CE69F5DCFBD4E489CEEC7E1
+:1077F000E9B5BB16C1FA5EFAD2247ACFE8F57E4627
+:10780000AF9FE2787F494DCFB6C2F73AC7D309BEE2
+:10781000DED733F84D86ADDF8198C7E5DA4B9C0F94
+:107820005E6AB7F3C16742763EB8A1DF0EEF356DF1
+:1078300076789B43EC5CF2A5F62E3FCA9563826E88
+:10784000AE97A9FE399658129A17A1FE78CCBA4F76
+:10785000CD0EFA391BBF5D25817D8FFEF71E3FB52A
+:10786000BB33F1D137D93E7EE065F45E16768DA943
+:107870004732F2F94DFBBEA33D61C5E3939C0F4532
+:10788000F9EA56875F3D62EF3FEC627C6C6E0F5009
+:10789000FB4F53199C1AF82126A3E7F9A80F33F3DD
+:1078A0003BFA5FA5A46CF377723A196FFEB3D95314
+:1078B000FFEDCF8CEDCF7C2FF49FEBCF0C86CE4F1E
+:1078C0009F3CCEED41A75F93D11BDCBE11F6CC9A55
+:1078D0001CFDF54198E2389FE7FAFEE5D4FE1C76E0
+:1078E000257A308FDD3CEAA279AAC38D6BBBB0FC50
+:1078F000417FA9EDF7D58A1DFA4EE89FB3E94F27DE
+:10790000FF3CB76A5B0DCEFBDCAA2B6CF6EFE5A75C
+:10791000A69021CB79A6883764F8D567DFF7912048
+:107920008BFF8D707B32D3EFD4543A4EC62EEE5F70
+:107930004DE30D2D4DBB174996F53C19627EC03FB6
+:1079400085D83A3276B1C2ECE2F1E26D6F3BE4D019
+:10795000737C7F45BC6D95921833DE767993EC90FD
+:107960004FCC4E73CA23D1FE74C82E97C43C4E7CB4
+:107970009EEB7C25412677457C8FBC6DB753C7A312
+:10798000DFCCBC8EF6CE79FFC4F138DEFC07319E29
+:107990003E6FFC78550D8F57CDE7F1AAE1CF7DF210
+:1079A0006718A73BB6E2E9C548872FDFF1FE73579A
+:1079B00044508F1F5A8CE0D7F0F8D5CB98D286F47C
+:1079C0009E94A85D7845FF6AEA97417B26978E4D85
+:1079D000A3F77063616E17AA319B1E74F2E7F73943
+:1079E0009C4F05787E3A19A0E757E78AAF5F8D83F1
+:1079F000AFF3D51BDF17F39F9E3B1BF5C1FE80C67F
+:107A0000CFD386583C6E09FB4EF5A09AB88DE6CFD1
+:107A1000AE0A697B59FC92DA732B08A3A74145DFB4
+:107A20003113EA0713D30C13CAA57FB39CB65FD1F9
+:107A300014D030756939F65904FB551F3471BCDA1E
+:107A4000E1C6EFE1F9C36F9A3D3ADE137A26B156EB
+:107A5000C6F8DBB146895EAD5E7549E21DCCF75ACA
+:107A6000754540C7387A5EBC94DA85DFC5F92C7954
+:107A70006FC732E535DB1AA07E66FEA00B49F09990
+:107A8000F09A6D5E18B7A73311C5BCE5B6F0826DEC
+:107A900098B75C50601CB92406DE7D78D1329AD745
+:107AA0007CBFE87FD136CC53FE4757B214EF233C5E
+:107AB0001FBE72995284F74B1BAA31FFFC855DDF14
+:107AC000A6FD2FBFFCE6CF3F0EF5A7C35F5D86394D
+:107AD00038F35B44FFAE654BCA0959B95894B7797E
+:107AE000B01C0924745735C8C1F0DC650ACE97670D
+:107AF0006CC4FCF5829CB974BC8549C2F264CCBBF1
+:107B0000687F31DEBAF0DC6D980753D4BE84FC1A6E
+:107B1000E4CCC234FBEEE82FEADA96607EFCDFDCD0
+:107B20007DF7B62A90550BE27501CCDB5E7EF7231C
+:107B3000CB3CD5F4BCAA5A87E7CABBBF43C79FDF7B
+:107B400062CEC47A957C7F5BBC1AE1E2E772C5B174
+:107B5000E9B6DFC3AB6471AA4C39CACA835BC6CE2F
+:107B60000FFB750E931B83FEB1EBEF0FDBCF57734B
+:107B70008E13E3D12A3CE725835ED0139779482DF5
+:107B8000C6CDBB30BE3CCF32AF97C125FA11F3B2A0
+:107B90003CA4EF461E33C77A3CC7E9E77C3C2DC6C0
+:107BA000F8385F6676F848B5F410D267BE2C5DB73A
+:107BB0001CDE17F849723FD64F22B4DC4888B13F2B
+:107BC000981DF7A77CD8A5D3120F23BD2E2D2CAA64
+:107BD000C6EFB9C378745D006FB7D7720E05702B0E
+:107BE0000877BEBCA27A639505EE2A06F7601EC32D
+:107BF000C7E09F589C6DF068D95EA4DF1561BBFE9D
+:107C0000987FA4869EABE52F21F477E146EEF2D172
+:107C10007C76E24DC6ACF758BEC3F1B8C19187B3CC
+:107C200041195291CF37F03C9CFCAEB1F741C413DF
+:107C3000379CCA25E65CEB7BB69EEC38115A0FF0F8
+:107C4000B03CF971E0F9C70C3CF63C9BEC382CCF0A
+:107C5000E6E3862793A7272EA4F27145DEB3C80773
+:107C60001E4F7E6E70E43B67E76579CEA59F107965
+:107C700079432AFB9E03836F547EDEFE3A9A8F93EC
+:107C80003DEFE674A0B2F5E33E5BF30A7ECBE97606
+:107C9000A5A06F7ECEBE76323B671FFCD39259CB38
+:107CA000E978EC5C7250617ED77CC5A0E7DDF38F8C
+:107CB000E469785F41D0A5A047414F83796D751481
+:107CC0005FCBA531BF47F5AED07F09761E53D89262
+:107CD00094AD79FE82EF9C7C4AC837F93DE0D8F438
+:107CE0006B502EA03F88F0C7801F6DE7EE0CEECBE7
+:107CF000D196CEA774C0F6AF88DDBB10F8194D0F32
+:107D000053CE420F5369FDFC234FA9B8CE0D1CCEB4
+:107D1000C2E343E159556C1DEBE1F97C0E3B27BAF8
+:107D20002ACCF458EDFF5A12F8248FEFE1A8F3851E
+:107D30007C36DFFE977A90AF8519790DFA84EA31A7
+:107D400022F21687F0DB1DA2FD4FEF7E7B5977797B
+:107D5000163F11340EF2B2F0AEE378BD9EAF1BF0C9
+:107D6000677AF36C72832CACC9CA372127C4786256
+:107D70009C8B72D8380B7278FC4CC83FAE6741DEE2
+:107D800099EC7E988FDADD7F79B9279D45EE2DE756
+:107D9000728FBD3F04E631B65B9B975C8DBF9772D7
+:107DA000F4F0920A8CC78ADF956892923D989FBD45
+:107DB000568DF5842CF47839FE8E44257E0DC6450B
+:107DC000EFD7341D61BF3FB932E13BA7DF9710F316
+:107DD0008BDF99381A67BFA794818BE37FAD7F64EF
+:107DE00033CB17B0F3A728AF9D0E704FB3D40799CC
+:107DF000DE3BE0379A72E6611E0AFF3D84867CDB3B
+:107E0000F9C686B0DD4F11E7D6B501E36AECE76C41
+:107E10003F5A0EB2F6F9FCF76DC1C39167C33EAE8F
+:107E2000B98E108CAB140E10CE9F43AE0D54BF1103
+:107E30005382F5BF9453C2ECCB555069B9A73A2C85
+:107E4000258A69BE7DBE2786F10DD817BAFEA5F238
+:107E50004696D7378DE5F57D392797EBDB915A5C50
+:107E6000677E80D1E1211FF1FA60FC7F81A7B726F0
+:107E70002B97FECFD419F49EB390671939785A1E08
+:107E8000BAC4527F485A5E8C57CE0FE517D6744954
+:107E9000743C9A3F28DAC3B8348F70D987EFBF7D1E
+:107EA000097EEFAC8C8D1781F95758F860419CAD75
+:107EB000FB4E4EFF77E6B0F3E1A50136DEA152207E
+:107EC000139CA702D603FCF0137FB2AA8DC27517CC
+:107ED000CB57F7B3EF0014F07D2BE0BF17F9238DDC
+:107EE000F1D57BFCB95963E31784C7FE0EEFB3BC31
+:107EF0009EA64C40FB1D8D8F39F2D4DBF8C7BED84F
+:107F0000F720B7D7B17B41CE71FE36879D5B801ECF
+:107F1000A3EB1DAD5798FCF32FAAC72F45906E9E7B
+:107F2000B7E26CA706D25EFADDAB598A8BC643B8BE
+:107F30001E1276FF0703CBE977AD9FE478531DDF70
+:107F4000BFEFE6718FF0A900F55B7FC8E1522A5FB1
+:107F5000A3FBAC2C842125FCEE5CC2D42CFBECD61C
+:107F6000ECDFF7089F0AD3FE1B4ECDB5D923A3E55E
+:107F7000F57C5B7E7006CE135750389DEB73E26D37
+:107F800088C32BCA46A5D2402C70D511AD1BE7A9DA
+:107F900023CE7C99C51ABD5F07F486799C20BF99D2
+:107FA0009E80277EAF00F529CA45E18F201F69E03A
+:107FB0008FB4E6D41DCDC9B7E817DE4FF0F1E09FCE
+:107FC000DE3743CC9ECB030D475A38FFB770792F6D
+:107FD000E4B933CF680A97E782DFE3DEA72F7CCDD1
+:107FE000A2E75A73743ACE6149FCEE6F8CE689CDF4
+:107FF0005FCCE401894B04AF1F2F6820B6FC89DFFA
+:10800000E730BBF9F7392C7F43F0CF8A167BBBF7FB
+:10801000B01DD23DE7A3B3E9A58C5C2C607251F191
+:10802000B3EF1EECF9F3127A0F76E4676E9A074706
+:108030000E30BCD45DB9B90BBF43E51E90346B1E46
+:1080400059B07DFF85EB709D7CFD1B220CBE0D9110
+:1080500021B51C409ABC81C1F9FF00307EBD0200F1
+:10806000800000001F8B080000000000000BDD7D79
+:108070000B7854459670DD7EA5937492EE4E27E9F9
+:108080003CB94D000384A4134208CAA393100812FC
+:10809000A4C3CB04419B871025848CA2C61DFF4935
+:1080A00043100151C3A00E3AE874105D66961D039B
+:1080B000323351111B04455731E00B4774DB172253
+:1080C00022447456DC71C7FF9C5375D37D6F120335
+:1080D000CEECF7CDB7996F2CEADEAABAA74E9D7702
+:1080E0009DAACE68DF2F197219FB01FF2630965129
+:1080F000C73C01A89BAD46C6463196566360AC08A6
+:10810000CA46CF76E662CC82CF93188BB1322A1959
+:108110000B48E945D48F6D90A19D1BFA5BA09D3B58
+:10812000202D82711A24683286B175BAEA5CAB03DD
+:10813000CAE458770B3CBBD2E6B35B61FCFA13C1CF
+:10814000601C34197DA2D3E0837E37DA3C89561C4B
+:10815000B703FE93CA98ACB7A6B16CC6624F70B8AD
+:108160005AEDEC3AAF250C2F6377139C8C6D237876
+:1081700092F4EC30B3639D05197C4F9E9BB36D83E5
+:10818000146E9F6C67BE76E89F9CCC7CBB2DD47E22
+:108190001D2B84D66646F34C5E3D64DB0617CD8B03
+:1081A000C6ADC8F66EC7E71529430B5BE079F6C686
+:1081B000A06121F47B66ABAE3210018752165825C0
+:1081C0008203E6911B390F6DBB30FC7E8E47D1CE0A
+:1081D00018A39E5FB8DD2A8227B692E3B7B4D631E2
+:1081E00017E757BFE68FB151F0C9B4F636293617F5
+:1081F000DBDD4BED14BC031CE3100E434C7C1E4B2B
+:10820000C076A5F22A5CCF578D6E6CD2177CF54DE7
+:108210004FE52F4E8CA8AF3111FEDB4CACAE3D3795
+:1082200012AED5F4BDD9561D958FD8BC55F8BD8674
+:108230008E4D265CCF1BB67F68F2E5FEC8FC2F1280
+:108240003F12D025AE437D8D3980F32DADE574B955
+:108250006C8D291005EB52BF735750077576077365
+:108260000F86A2BE7DD78B69809FF47ACF283DD040
+:108270006532105927E2C710343128D3EA83121B24
+:1082800088F858504FF4ED8C75237D1F3231160D50
+:10829000F473A6D4E297F2A134FA7364787FC6151A
+:1082A000E3F6C3FB17A399DF6C0FE3F7A55D930F0C
+:1082B0004BF18CC5ED8E0A6279A3CDB702E7BF61A1
+:1082C000955C8AEBB3A18259916EE428EF1EA2C798
+:1082D0009438B75FBAF8798F16EBAD3C1F7D07E78E
+:1082E00083366BBCE03F56E885B9ADB7C6513D1942
+:1082F00096A104E8F9452387D320E03C6FF5FC0202
+:10830000F98D2113C277335860BFC9D5F3BB1174FF
+:10831000B386DA5F349CED2619E05A26E44769ED0E
+:1083200076E9E38875DF6CD553BBB49D6D924CF450
+:10833000BB7D558583DAB328941B3B25EAB70CDE59
+:108340005F1F21379479F4223F1E46F82C273A0FFD
+:1083500072F911247A53E055D65159AF27AC32D176
+:10836000E72413F347D3780BEB713DD6A5F1F11455
+:108370007ED6F2DF1382AED36AB64BBA5C9C672717
+:10838000CD73798D81D6E5C0D5D72EC671963B5277
+:108390000B900EEFFFD3519304CF9FC27E00CAF221
+:1083A00056C983F286B51E35CD1E81E8FAAD9E25ED
+:1083B000333695F1BF07FF70D424C3F3A97B241A89
+:1083C0006FF99E5D86459630FDB94E1FB816E9736C
+:1083D000797B148B96705D641A574B772017881F32
+:1083E00098DF1418EC22B9E6E772D0E79A111796D5
+:1083F0009BE7055CCCE22DD239500E8E284079F7F0
+:10840000A298A7327E458CFB8019E55EA1E46E61DF
+:1084100008C73182F3658147183F487293B181DE06
+:1084200011E1F17BCAFBE18588DFAF845C84753B99
+:10843000DA9BDC57C6773D3A83C97111EB81788EA0
+:10844000A0A390D544DF0F590D349EA18CE3C960E1
+:10845000E2F337AC360790BF5EB25572FCD8CD84DC
+:108460009F4362BD0F89F55EA75B9DD3C8F5CD879D
+:1084700008CF81ABE319972F5C9EDCFF94C4EB7EA1
+:108480004B80C13FEB7DB3689D9923DAFD38EA0745
+:10849000DF41D3ECB830BD69D755DEBDDF84F3983A
+:1084A000DACEE93A8CAF808A0E414ED17AE33A2196
+:1084B0001E157E57F0A8E0E532E477E867B079BE94
+:1084C00049804FDEE4D4CB9F807CB6CCEBF233B94D
+:1084D000275F2630B36CC961AC91E9D80F006FB14A
+:1084E0009BD7F1EF07F8FFF956A912E5F84D2011D7
+:1084F0009A22E052FADFE434D1F8CB9AFE2315CB6E
+:108500001B9D2F53E9888575867EC6816A3E89B793
+:1085100049D4FF5BB1CE49364E27CB8ADA49DE2EED
+:10852000FBA491F8C652C9E583E5845AAE31768F33
+:10853000D0E31BA9FFB2222E2F973AE2DC92D4B7E8
+:10854000FC592A312FCE837DFF839E15033EA3C5A0
+:108550001CC5FB21364ED79FED800520F9DF6862F0
+:10856000BDE8D7F0788D47C6E03AEFD2BB1F673D34
+:10857000C765C137255CE765665E3DB3B37CCCA7B4
+:108580004027FE1D09EEC130E52F76CEBCFD53E835
+:108590007F66FB04B71EC9A5C54B74D39514EDDEE9
+:1085A00006EBE0D0B34A09F0BDAAFD85F82BA0DFA9
+:1085B000E7FF965F88F26F9C80F3F453FA26C4CBF2
+:1085C000E9A75EB8F7BFA15F5DA020194961F5BFBB
+:1085D0003E6F0A01FCBAC0A6BFA15EABDB9E608DF8
+:1085E00082E72DFFF69BF1585FB63D81E4684BFBB7
+:1085F00063FCFD0EFEFEF4636DE311FF07FEF5C99B
+:108600007D385EBD37DE8DCF3FFFD727C7A3DDF6B0
+:1086100000D039C259EF3378088F0A5D6BE5D4AECC
+:10862000FD44870A9D005D33E2871A2E6F143A3E9F
+:1086300086720BEC8C19659675581E9B125D43F47F
+:108640002CF8B361AEAD8DF49FDFE5C7FE33BDB648
+:10865000820D505D2AE65F9FCBE9621D504D34E0EC
+:10866000293637684A877657CFDB351EE15C17C35A
+:108670004AA2895EE121ACCB0C623618A7F5A5EFC2
+:10868000A43CC64680D83B09740EA36DFF612463E9
+:108690006F83B94AFA2386EB81ABE77D28919E6010
+:1086A00006EB49B186B0C23FA2DF0C349ED2AEDBEE
+:1086B0005E13780038FD627CD237C52B397D1F925E
+:1086C00016B6C4A1BCB9253816E5E733A76E8AA94A
+:1086D000CF8DA473DE3F6D0F970FCBF7B4AD324152
+:1086E000FB2B730A8AF133CB9BCAD9C7C86F7A892F
+:1086F000F8ADC16F51C9C166C16FC956E6B81CBE9D
+:108700005B61600E0B968CBD6924FC3CCEBF6300A0
+:108710001607BC9F5B352F09EDE0078DBED451F8DD
+:10872000BD75428F6DE7F0427FABA590C6B35E5E2C
+:1087300048E3741AED68B7C084A1BFFCFCE4EDAB5C
+:10874000A430DC40D159A8CF70BC220BEA1F7F0DAA
+:10875000E91FD9E4467A388D4D52095F79F3478491
+:10876000E70DF6890FE92CD9C4ED70947BD57168BB
+:1087700037966EB18D0A97C931FCBD763DDEC3F7E1
+:10878000285FEC1E2AD98E449293FDD92707AE3E6E
+:108790004BFC73FFB31F923C6A407AC7EFFB3E511C
+:1087A000E965859E1E7CFA43A2F7191D7C7D1E9407
+:1087B000426B915FFC53A4918F239F377BD8C76096
+:1087C0006836083A5F56F9E1129CFFC08E542BCAF6
+:1087D000ABB3820F1AC68786A09C3CFB34E7834369
+:1087E0003A1DE1F3D0B6E16DA887C0AE25526E68A0
+:1087F00094B745117EB99D5F5ABB785305EAFD3A9F
+:10880000E646BE6ED8539D2193FE8922FCBA1EFD1A
+:10881000682DF2850DACD76819E7F7C12484AFA1A4
+:108820009E8D42FE4E9BE8791AEBAC4362680F279F
+:10883000D73A4A0D445F0B46227D3D98D9BE16F5C6
+:10884000BB1FEC539CCF83C6D63203D41FAC90AD74
+:108850008031C00FE83BECDFADEF66ED21FE75CC5B
+:10886000776F907A910F4FB73971BC861C931BEDCF
+:1088700094A91DDCAE66605723BC0D1DAB7210FEC3
+:10888000A9F2E56E3DBCFF52E047C1D3D48940A7B1
+:10889000383FBF8561FBB3C6CE6BB17EF60F40801B
+:1088A00012B16B29C2772A4F1A89F2E2A5A7C1FE3D
+:1088B000C90BD363DC1FC10E82BADD6095DCC467CF
+:1088C00033A322D7B3D5C8F5954DE89FEC4ABEAE89
+:1088D0009F0A3EFA54C89F4F6D26C1DFAD9CCEADB6
+:1088E000FE3CD4CB5F8AF5A6E150FE8B71972F0E2C
+:1088F000121FD5EFE4F69B23CA53707304DD3ACA06
+:10890000B9BE4C023EAEA652476532FA2F0EF4AB0A
+:10891000E56D7A5ACF19B4BE573A2E2B8C86BAD150
+:10892000CEF5685A8E3497E3C54478494AF46D42CF
+:10893000BBB96BA854BC4DEE49EFD1766EDF25254F
+:108940007A8B24689704FE06D25992BE54178DFD87
+:108950000A2437F64BD2CF20BFB62B29D5BD4DC543
+:10896000D7DC2E3C951CC7D739F0BA614684DC0FA2
+:10897000FBC3D16EF46B4EE9828668179F9FD712B6
+:108980009E5F60554C4DA4BC4A10F3090C6535C878
+:10899000FF609F5BCC28A7AC6017A1DFBDED8AC745
+:1089A000B8DFDD42EDFE6AB3F2EFC13CD04E4BCAF8
+:1089B000F6AEE47A348EE04DCA660BB15F528B534B
+:1089C0004238C2F8B4B6213E1F11EBA9D8E70D40DA
+:1089D000C768D73103E70BF95989E2157DC98130A2
+:1089E0005D733930B583AF6F6C2597032C571A89A7
+:1089F000FA1EE55BF5082E075CF961FE6D30858691
+:108A0000201D5EAC1CA8880D10FF540C1F4271067F
+:108A1000659CB346F023E1F959E053B26B05DDC71D
+:108A20003DC3E95D5997174D7EE2AF1707C6D07A6F
+:108A3000235CE8172AF2B1E199F5437CBDC6151411
+:108A40007DE6F7209E4E0D647CDDC5B866D0917141
+:108A50008554FA513FC43671FD1C9B2B93FE6EC8A2
+:108A6000E91C87FE35ABD451FFBB73DFFC77EC7F8D
+:108A700095DD42FDDB74561ADFD8D4E84F67147FCA
+:108A8000E17ECAB6D800CA15250EA385AB54D08B9B
+:108A900012EF50FC8BE478DEFE4641E7F3ED9C7F5D
+:108AA0006F16A502B7626F43FB8168E0F4A54F948F
+:108AB0007EFFA8B890F21D45AF85F1CCD713E16FCA
+:108AC0001771ACEADCBEDBB5EEE77283FE705D9E2B
+:108AD000496DDB407A55A6F55C2FE8FB4A9B77ACE5
+:108AE0001DF060AFE4FEEFEF25E02FFC7E8D4187A7
+:108AF000747C4B349753DAF195FA7DCD60D25ED613
+:108B0000B7FEB4FE4D4FF032E661381EC513906DCE
+:108B1000CB2ADD38DF7BC43A69FB1998E19B906270
+:108B200037B922E0113617B0041B5F18095740050A
+:108B30009775AC8E0523FC156DFFBEE05D87F3894C
+:108B40008AA867EF63187F8A35C7131D81414FF6E6
+:108B5000FC7A310ED0BDBB9AE41B8F63F5F71D2D57
+:108B60009CD1B21ACE8BC5FF3ADDAE3AA4E77D02A6
+:108B70005E76FFC5CDEFF762BDEE6D3653C9E641B7
+:108B8000BFE2703F8B5B5E857A3E7FAF5C40F6B2A2
+:108B90008EC7EBE2C6B3AFF440AFF125AD39AB51B0
+:108BA0005E7BD570A7D4C4B0A0395C4FF5D955F51C
+:108BB000F4BA3455FBCCC681AAF7039A86A9DEBB6A
+:108BC000FC85AA7AF6BACB55ED07B796A9EA976D58
+:108BD000B952D57E686086AA3E7CC75C55FB11ED14
+:108BE0000BD5F4A1C1DF8655ED35C83F13FEF675F0
+:108BF00019C99B6798ED71A45D736824F25B7E8749
+:108C00007AFE67EC76A2E38412351E2E951E265C52
+:108C1000F871BA55F8289671BA88FD7EDD57FA3C8E
+:108C2000AC6BF8458C3BDECCF9A4BF7157C75E6BCB
+:108C3000403ADF8795087BF86D0D7F57D42490DD8F
+:108C4000C32ECCE8C76EE6FC30278A3522FDCC89DE
+:108C5000E5A5F27E7822979BD989229E7491F47BB8
+:108C60005CD0FBB1BEE817CC9B645CAF4A46FEB457
+:108C7000B572D55718BFA935045901F0CBFD623E36
+:108C80000F8AFE5B9AAD34DEC3CD4E2AB736CBF4E5
+:108C9000FCD1E61C2A03CD6E7ABEADB984CAED6064
+:108CA000C761F9447325953B9ABDD4EE77CD355411
+:108CB000EE6CF6717ED4AEDB053BF93373985A6ED9
+:108CC0005D5DA357AF8BA24F35FDAF661B3BF5F142
+:108CD0003DF1D1A3BF7E5E426F7A5A299B4E145458
+:108CE0001E8CA0CFCB13E31C27919846B3D1E49FF1
+:108CF000F6D3FFDB6677E5C1C1FDD3B5967ED8F725
+:108D0000370F463B58FB7E0E7E3B0DE4E0E64DEB15
+:108D1000FDB93DC70579B82604A49287BC17114751
+:108D2000DEAFA14B8F2141E5DF2AE55382BE4A0524
+:108D30001D966AE8F0FE44AE7F5626727DF87F8D60
+:108D40000E0F44C7911D7DC028672445ACEB81E818
+:108D5000587ACE72983C0BD645F230AB0BE8F24015
+:108D600022DFB793D063A0F8EF202BC52FA22F31BD
+:108D7000CEA1C1A304E6B50BC62B8572BC9DC60F60
+:108D80001A707CB72E2C2F07E27F63C2F4ACEF4938
+:108D90000F308EDF0470FEDEC86413BC7F3751567F
+:108DA000D90F6506FD8FCADF32E4A3BC9EF0F7E859
+:108DB00077897CF4D8FF321F29F4CEBECF1EE48D14
+:108DC000EBF9BE54F0D1DCC467D6FB2D617A2F439A
+:108DD000FB2B028E6342EE1E13F47E40D81B481F0D
+:108DE00085BDD81DAF88F64AFF4BC577A990778C13
+:108DF00085D290FF2FB53F708E01FB959AE3FDB1B0
+:108E00007997DEBF2F7CF6E8D7E1B8A83810481A6A
+:108E100009F97C89806E89D9E2477A625B8C674266
+:108E200011747C7B8CF7D34468DF61641DB8BF008C
+:108E30006A5BB62613DD135EE1CF6B867A81A88F5D
+:108E4000F64B44CF51506942FE08BDF81DCA8B0253
+:108E5000518E162586419DC837B971069CA75B4186
+:108E6000938867162BD58960AAC0FBCB4515448132
+:108E7000B4D28EEE482BC3FDF00D927B9D1EBEA793
+:108E80004F71B52050232B4BF5E8E78C62AD548E23
+:108E9000659D2D0E28C7B32E3DB62F31B7B71800EC
+:108EA000CE01EC7B2BD179CA13CB7F00D7B0C9CCD4
+:108EB000F785BF8DE6A5BF8C91BFE3FF203A807E8A
+:108EC000CD34E68B72001E6ED37BE6E3B8D5B63B9D
+:108ED000F231B80AF2E2A310C55925E2F3324B5140
+:108EE000CDF5C49FFC39E1D1156E47757DCFFA03EE
+:108EF00077F27840CB7A4EC72DAB785D7608BF4CC1
+:108F000094431D42BEE34A24133E08EFD1CCEFC781
+:108F10007D5B9603F82CE6F8257C590E13BE63584A
+:108F20003BE12B7ACE16820F04BDF5E4704066D08B
+:108F3000CB7E88ED395E5FE398CDAD1E33D045EC36
+:108F4000BC80DFD8CB3806B4D7E03B8659263FEA51
+:108F5000F9369D2F1FF1C6327486487B2FCAEA6509
+:108F60006C60981E2F02FFA32F06FFC63277A7075B
+:108F70004868768CE4DEF613D6C1EBB02BF82552A8
+:108F8000DC97CADAD08FAF73302703FA3759CCC4D5
+:108F9000276B32B9DF6F1AC6DCAB115F5E1DE14B88
+:108FA000991F3C60917602E0613AC26F0A481F2225
+:108FB0005E4CCE46F2C79821948EEDF6497CBDB545
+:108FC000FC5AEB9004BF66707A653FAEBF764DB336
+:108FD000BDE72066DA76E5AB4EA897DAAE715801A8
+:108FE000A4070AAE34805CD875941133FDD531E9FD
+:108FF0006EB45376CDB6FD3A09DAD727873618C155
+:109000002ED9355FA2F75F26F1F7EF95B2768CDBAC
+:109010003C60F72D45F8E7BE2A1F42B4EF7AF1C64F
+:109020002CD40B8E7277488FF8BE264AC67D1DF66B
+:109030003DC00178780C410038DB315E68E4CF2711
+:10904000C0F35A85AFFB9023A395BA5F6206A88F41
+:1090500053EA62DCED58CF0EB757E44EF6E29FFDBF
+:10906000E7FF433BA5534F790F520DDF07192DCA78
+:1090700071A22C10A5BD92DB354B37B29112F41FB3
+:10908000B458D9C7890A0C867F0ED80AEFA1FED939
+:1090900026361279E2A4516EB1203D8E606E8C139B
+:1090A00003A1137DBE9D690B603CE23389B5501C62
+:1090B000793D8F23631FDC4F742F86B52E4293CFEB
+:1090C0001CC078F81BCDEDF96B8C11F20FD6C6538E
+:1090D000CCC32B1C0FB9E4178D65E13F9C67451885
+:1090E0004FC44793447D723D8F834579402EA27EC5
+:1090F000D2C8D36816709A095F2ECAC3D04F66567D
+:109100008437AB3208AA12E4A5A794E4E228E67BF0
+:10911000A113CA319E5D424E065A708A14C2C846D7
+:10912000FD271B703DCBC142C57A256BA5F24AD6FF
+:109130004E6515EBA4F22AD645A597598D58FEC168
+:10914000E122FA1D6F06398DFC6E9029DE77F265FB
+:10915000AB1BE38E332A7D26B917FB628981F17D33
+:1091600038E6CB42FE60065FD69C087BE164EDD515
+:10917000F33DD04F16FB28CAF3671DDC4E3E24F8A2
+:10918000E64149C891E55200FDDE076B4D943F73FF
+:109190006CB9B40DE3EFF09EE2AEFE5A33C5E11EAA
+:1091A00034CA99683F7CE39079FCAC7ED76D2C1E65
+:1091B000F7EF96A622BF1E977C93EAA0DF922A1EA5
+:1091C0003767067FE6EC083EFF6C01874BC93750D6
+:1091D0009E1F11F2FB1BA43180EB33809FF6DF94BE
+:1091E000B8DA5C1BC9990A50FC3F8371DF17F3089A
+:1091F00008B9A0F04F9D420706BF290DFACD71BBFB
+:10920000088F73033C2E5B616041B477BBE1AF69AB
+:10921000BB85017DCCADDB6F58924BF942149F5C4E
+:1092200022F287A43AF94E07EE2BDEC1F757C2F9B6
+:10923000417C7F78C9BC5DF3296EB0388A215F2CF0
+:10924000D9B2E97DE4F7ABEB26CB883FF81EC545E4
+:109250002799F9FE9F19BE8FFB6593EB445E46DDAF
+:109260005D9D489FD0CE83F6EE24686F28C4BC1B5A
+:109270009ECF16E3E7F941311395FCA0C643499808
+:109280001FB482B9FDF0D9ABB7B6498CC7FFC81E71
+:10929000EACF5E79E4AEEF6DA88F48AF0F00789A01
+:1092A000F4F22723713E56EA3FD7CCF1B7AEAE8534
+:1092B000E8F02F353009F8EE9C5617D5D941CEDFAE
+:1092C000736A0A421827325746D13C5122E17E8008
+:1092D000995512BF17301E87B809F30AE87D50056B
+:1092E0005F0FFB1FE41DEA87BEEC26653EE62613F2
+:1092F0008757332F455EA05CE9EA85CFA5CA97B8AA
+:109300009D254AE47BE4D742B35B1FA74312F3EAEF
+:10931000B9DCF4338A87B33BB83E897E4242BD6DE7
+:1093200076F8AF4592FBECE0A03B2D84AE56166973
+:10933000F79BCBBCD77B23F86C7DA9777E64DEC31B
+:10934000B024CE6FC39344FCF9557F167EE7D46BEF
+:109350005C3FF8AF8F9229EED40F1E60EA015DF6F4
+:1093600045CC77B190E7A20CDB83720BAEE7B8A4D3
+:109370008104475165B51EED8CA7DA46BF3186F5ED
+:109380005CA7BEE8488B9F6FED9E8A24B20B3CBA67
+:109390008BB19B2BF419D7D403FD9C9F17457CA55B
+:1093A000E8C1425C14E4DB4E1600DE46FD407A2341
+:1093B000751DB34A32C62301F7AA78A4991954F14E
+:1093C00048ABAA9E5EE754B5CF6C9455EF0734E5E1
+:1093D000A8DEBBFC6E553D7B5D89AAFDE0568FAAD9
+:1093E0007ED9964A55FBA101AFAA3E7C478DAAFDC6
+:1093F00079985210E653F496DEEDC7F5F57B3A7393
+:109400008BC37A7D44BB4FD57F74684115CAA7FCD6
+:109410008E3AD538EC04D86566CCDB6914EBE1D61E
+:10942000A39C7083F07DD88528E4EFA93DD4DD2787
+:10943000A67C8E727A6E8D316CCF612FB691E28AE6
+:109440006E8D1DA8F57B971EF61FB2007CB5AFFA96
+:10945000D722FDAF4952FBC1157A0BCDEBFC9B7AAD
+:10946000CA1BA943CA7484D7F13C0E84F3DECF0231
+:109470003CAF433D6FC54FAE45FC40BFB9304E10C9
+:109480005E4539D5EB1D2DABD73B3647BDDE716E42
+:10949000F57A2794A8D7DBE6C9E915BF8995EA755F
+:1094A00057F05B02FF43FCFEA3F1B933491B471899
+:1094B0004BF2F42F5B843CED290766998B7BCA0144
+:1094C000056F3DE48185FB27DDF2608B90075BB47F
+:1094D000F2C0F3422AC037CA07FE218CFBCEFCD172
+:1094E000E928D7D2D85EF25B4050FA303F06F87BCD
+:1094F0003FF2776C933BE4473DB0358AECC8638715
+:10950000961CD2217C95DCBEBF5B3844AF60102A2C
+:1095100089ECFA5792A08C3137FAD14CCF6AF2928B
+:10952000DC7C17FD65DCDCD1C80BA691775A3B5873
+:1095300091279F8DE3F4F4CE6B2CB05A42BFFA28EA
+:10954000F9B397AA17FAF3A7BBE5E83CAE37468B09
+:10955000922DF493FDAEE89196129F4BCA467DE2A0
+:10956000D1335DA47F1D22BD3281F949EE5E51E900
+:10957000FEF54AC4DB9477D2D15ED2FAD980E7B344
+:1095800088AFD8A6769EA75C29119EB5F8D599B963
+:109590005D1293C1F755BF4D52F651BDDFE23A2936
+:1095A00078DE1DED26BA7AAB96FB1F454707B55806
+:1095B000A05FF20D2E37F6DB6D73BF80F5B79673A3
+:1095C0007F70D49B1E3DE6236537BA282F6DB7CB3D
+:1095D0005B8EF5B76EE1EF8B8FFB285F6950137FD1
+:1095E0005FB8BAF18538187FF62FF8FB67BF5CAB20
+:1095F0008F87F781D5A27F696B39D6DFBA93BF1FFA
+:109600007D22D082F5A1EBC4F7A5F617E2D1BEBC4E
+:1096100047E279745ABF47F83913C47AF4584FE1D6
+:109620000F8C17ED15BF66420D5FA7C55DDE49447F
+:10963000669AF5D2DAEB15CC47F5C9CC4FE514168E
+:10964000A0722A0BD2FB692C44F5E9E04263BD9A73
+:10965000C946EA9F9C43789F092291E20B256E330D
+:10966000DAE38E4F5EB99DC587F7A5153BA0D5EE11
+:109670005D8E7682A3DC7B0BDA07E5C9DC8E0D9765
+:10968000DC4E48B6FBB3DCF0FE9451EC1376EF2FC2
+:109690001753FE0334D98876ECE8649EE79ABDB18F
+:1096A000D1807C795586E4C6BC86C968E7027E8293
+:1096B000BF32D8307F0DD7A2377F381CF7D2C475A0
+:1096C0000D7EF22B0AF5F270649679C983EE46FF9F
+:1096D000783732661AE021396FAA3F035B733BA6E5
+:1096E000BF766F8ABC98DD629F7196D7A523FA2C4E
+:1096F00050DB49F392B97DA494A3DEFCC7CEAB70D6
+:10970000B59FF2A4676F8B623C9F85A561DECA128C
+:10971000D648EB7A72849FD6559143B305DDCD16BA
+:10972000F474B22D8AD6E1B3EBA58004F02CD9FAFB
+:10973000D271A4B73EEDA4DCC1246F6609FA9C6324
+:109740006E9C5F8F74ADD84FBF1AA6FF6138E15190
+:109750002D07FBB00393445DF99E7E3CF327013C4B
+:10976000EFCDE77230DD2F915EB85839E850BE2753
+:10977000E4609AF23D0F901CD4B3C45BA99ECF3F26
+:109780004994E9F55A3DE25B85F4EF64AD12D633B6
+:1097900059179532B3AE4ECAC650965B87F59443BF
+:1097A0000757E1F836947B38EFF5078A50EE1945F4
+:1097B000DCD76806FD89F138878792330D07BBE354
+:1097C00064F727A37DF977C6C9C0621A4DFE326BD4
+:1097D000CCC7F213A3651DC56DB5F1941EF11775C5
+:1097E000DC615C2BC783D4AAE8039F13E7876990E9
+:1097F0002ABD30C62D633941F292FCB832D1B7335D
+:109800003909E3138D19D85E670EE9510F6C10E723
+:109810006E360C51FC4B583D2CAD3CCE9D2FD67274
+:109820006DB2692DC6D9D6C6746DC8C679EDD3613F
+:10983000062773812FD76989E827CBD42FCFCAE1B8
+:10984000BF17C7877E313AB918E188D1CB43B0FC46
+:109850004807AB0670243237D54D7A6BD22A1E4F9B
+:109860003C90CCF3376324F8CE9BCFE924F4BFF3CC
+:10987000C67C6447BFF7C9BDDB766C0392F9E6305E
+:1098800057BBF7EED0FBA360FCBCA727C6BE06ED16
+:10989000573EC77933BF4447F2EF0B13DB88793269
+:1098A00033CC7AB301EC892F6E15792B0677567578
+:1098B000447CE02A279783C7FA88F715C597FE15D9
+:1098C000E13A96CAFB6BDF87841C2D9EC7F3F7D85D
+:1098D000A914C2C3D7494C955F51147F158DA3D4E9
+:1098E0008D176CCC17718EC968F032AB059F3BE8C1
+:1098F0007902D8A118AF4FB0951890DECA98F5A09C
+:1099000007F081470A70A2492DFCDC5157AA254077
+:1099100071BEB186AE6EFB6F20EA196E3F521CD647
+:1099200085FB1C6ABB319FA9EBDAB8EB5F843C3442
+:109930005E4867FE91BDC19945CF3D664B508F0A89
+:10994000AFC89D8372D96379E538CFFF02791001E2
+:10995000CFBFD83DE39C80933D269E2FB548E79925
+:109960004AC2E098CE8E7EA8C16EF6635E60C238B1
+:109970003BE5C929DF1B9DC2E3EB7BC022C1F5B1EA
+:10998000EA986F97A5E77CD7005FB9000E570AD712
+:10999000674A7B458ECD57F8CA6F23BB669EE0AB06
+:1099A0005F396D3C5FCBCAF7413E5AFFE59DF87CBD
+:1099B000C1D1181322FBBA792C7E04F4F33D9078C0
+:1099C000C423231DBBF7631E0BBB8FDB0FD6B29CDA
+:1099D000628A1BB389B49F29F9D349BE5EAC7E6805
+:1099E0004E58F0690ADAABF101D90AE3C40C3B45E1
+:1099F000F970EE1446F32E47BB21BB97F5B47CA358
+:109A000043BAD0AE2B7E00D7A1BFF58DD1B3469E11
+:109A10000F161A1299E7D59C50FA69CA28CA4B0D3D
+:109A2000DA31AFF1B9284E5F876169A1BE62DF50BC
+:109A30008A8B3DE6F47D8C708F9EC8ED0D76B06B01
+:109A400008C6D716C58B3C33A7475E05EDEF1BEB69
+:109A500028D8200B6443BDDC6CA37CB1D92962FFFC
+:109A60005CCCE352E9D7813A07E95F9202DBA4FEBE
+:109A7000E7ABE4D92AF3FC3885D3B7522AF3D09E5A
+:109A80006BFB58D0DFC729FC9CCB634E2FCD7BC529
+:109A90008CAE0F6C00C322138F77F637DF3A31CECE
+:109AA0004F9DEFC5AEEB5F80D611AF8B622E0EAE31
+:109AB0009FFF9DEB70B1709D4C1170E55D1C5CF7D4
+:109AC000FD9DF8F230BE3EFDC105EB7912D7934DF6
+:109AD000EC1A82F35864BF38F8F6FC9D7843F8EC32
+:109AE0001707DF63C88F2CC8E19BC3DC46A75E0065
+:109AF0001371CE447BBE648E01746B61F8FC89CE19
+:109B00001CF06197593966A627BBE4A79D33E95E2F
+:109B1000C76416B4A1BFB82F8AE2F8CCDD35245251
+:109B2000AF3E23D6EF31A7E779847FD11021172AE2
+:109B3000D5ED9ED7B4DB502AF474958EF4DBDDB9F5
+:109B400083E89CB4CECCA71C9321D33EC14B826F3B
+:109B5000953C5E657FEF265B5D1DEE6B287A69EDB7
+:109B6000B0BA1CDCCFF0387BD74B0A1CA79B0F5B2D
+:109B70000719FBC6C332FDEEE2C65EF6457E67F707
+:109B8000BD9B129137B06CC7CBD641117197112C88
+:109B9000A4E3F67D978EC77945DE4BCAA5E1FDF5B6
+:109BA000288EF7E6042FC967454F343CF35B19F55F
+:109BB0000FD8030CE3BA5D713124AF5B8695E444A2
+:109BC000EEE3FC3545D1E7FA3EF4B949F53CD86CF3
+:109BD00066FE887C55CF29C344B4C34A99758D95D8
+:109BE000CA58E68FA0DBB05D23317FAF768D819EB2
+:109BF0002BEBD2979DA0E4A9069BDBCD9F80FFB6FF
+:109C0000A639271ACB03CDEEE84F607D1E4A281DEA
+:109C1000E3C47D146F87F913555C36A8AAA7FA0E22
+:109C20009B3F51C5653B55F5CCC6E3AAF6039A4266
+:109C3000AAF72EFF29D5FBEC755DAAFAE0D60BAA90
+:109C4000F6EB74FC9C41599199F2EA2FDBC2A223F6
+:109C5000DF2BF9AF468792FFAAA3F64303E6E8C8D5
+:109C600071CB3C16BF0DEDF2559C0F86EFB0AADE0E
+:109C700097FE6D26ED17313BB3E1FED88876A7EA53
+:109C80003B466B8EAAEE31F33C998712168C41FB52
+:109C9000ABDC5CA07A5FCA76A9E6D19D4FDD4F9E12
+:109CA0008BC1B09EE28EB82739B6B0675EF5430926
+:109CB0001EFA9E96FEFD778D15FB41DC8F06BAA538
+:109CC0007D9C2EC94C7A5C12E78395EF4C73727BB6
+:109CD000AE5E43B7F586A009E9AAFEEFA4DB471202
+:109CE0003CAF24203D95F77EBFC1AD4ECE375F9887
+:109CF0007A7F3F57C067BC001E58AF746FA1E75F03
+:109D000094F1FEB4430A727BA54D8DDF3AF19D7B41
+:109D100045BC62659C27C5FE23795EC60BB12CD07D
+:109D20002B1FC7D3F32F06FEF8F76EBDE4EFE9FB58
+:109D3000989F899EC33AF68A9FBB047EBEB0F7FE09
+:109D4000BEC5A9C8A55495DCB8CB2973BC767F27BE
+:109D500083DEA3DFD4BBFC72D0F3FEFC2666F6B92B
+:109D6000490EFFC3FD25C6E3699768AF2F4CE1702C
+:109D7000F5377ED0E949203BE527EAED18D4D1A993
+:109D800034CE4EE4CBB5267E3E102413C537147F67
+:109D90008869FDA51C9EBF36DFF90AD91131187BF1
+:109DA00000BD1CF38B68DA57B94EB29A10FE6BCD2A
+:109DB0005DEFFF1ADA9F782ECAC4E3238A3F14AB03
+:109DC000C7FDBA8B855389AB28F71D607C1CE55D08
+:109DD000FE846174CEE53EF4F31006715EE13E80D0
+:109DE0002115E44FDED1D909415C278CEBC0FB780B
+:109DF0009C2FC09DA0B3D079A4BEBE9F00022CBDF5
+:109E000010CF7DF07D9484BD86D391EBA0DD47F922
+:109E1000A6F3EB18D4BB6F3BD5FB297F6155AF0F81
+:109E2000477C953808CF794F4F4C89BC5FA43B2FB6
+:109E300053C9F7EB23EEDC1D0FD2C47F94B8CFB823
+:109E40004B8CFF749FEBD7C47FFA8B5B7D6BF77DE8
+:109E5000ED247A53C7AF4C0778BBAEB668B23394E3
+:109E6000789632CFEF04BF7F90E8F90EF5F409A79A
+:109E7000E7BFB13C16CDE341C7A64C4EC0A97DC398
+:109E80003C09E8EF62FE6EBABDE7BA60DC664D845D
+:109E90003C3866EB5D7ED853B9FC3897D94974B825
+:109EA000A1B42BEBE122F25BADDB008FCBF7F278B4
+:109EB000E972B43BD0DED8A3B6372A45FFBBAB76F8
+:109EC0007B113F6DB8B9C4F78F449C8FDB9593EC41
+:109ED0009EC45468770AEF99C138798C28E3B9FC9D
+:109EE000CC12E39844395294A7847C3D65E7ED1584
+:109EF000B89576A344F949B3D9BC6670F8BDFCABFC
+:109F0000A846F44393B295F358C02930AF86BD29D3
+:109F1000E47F2C6EFDD084E79C46A7969A529378F6
+:109F20003BC4CF6243C86487F637DB7CC311DE06CF
+:109F3000997976537C2E649A09F33827ECAB7346F3
+:109F40001EEF3A17CD4B059ED1A9D526EC776E5C56
+:109F5000C884F850EA0DACEB5ACCEB1C9DEAA5EF97
+:109F600041FD514DFD0303D45798447C532B473298
+:109F7000E2547266FEDE97898EAF35B3B5E9F0FE26
+:109F8000BABD2926745EEAE2FD43ACAA78CA4F93B3
+:109F90001F5A3BA33F7E93F68ABC3451B27D2FA754
+:109FA000E3FA8FDDF75A22966BA5468A3B47E4B960
+:109FB0001E7F16D641AFEB4A8CE433655F67BC1950
+:109FC000F86D20C529F839F924D35A2BF0D91AE0B5
+:109FD000032C7F99CAFD475C731E470D58D14E5123
+:109FE000E2AF2BCD1CAE8668CF7D65E8671DD56BD3
+:109FF000E2AEFCBEA0A4164F02C6CDBA8EEA258AF8
+:10A00000D38838EC4A11875DB9AB3405C7BD35F547
+:10A010007FD78E52E26D0D3603732484FB29F36CD7
+:10A0200010F76168D74F79FFECDFF4BDC657CF89D1
+:10A03000F77DD9671BC4BC1A2E0C55D9270DC00754
+:10A040000867C385DC1FB54F7ED9DDDFA6B23FC2EE
+:10A05000FD1DF47C1AF31D443EA8B699FD7AA46F49
+:10A06000832793CB459E075527E8A84E913301B52A
+:10A070009C51EE3BC2FB7FF07C318CF71BE41B65EF
+:10A08000BC378D7C3F770193498E2DD0D80FCAFD08
+:10A09000488B2CB3884F16AD3386F303E8BF1E13ED
+:10A0A000DA35D7B76A9F6BF36B397FC0F78F467E7F
+:10A0B0005F99CFF298AAC31E6C56D449FB710DACC0
+:10A0C00095E440C31E90A3F1584607717F8475A89C
+:10A0D000E7774364DE2FC07B236B37B924F487D541
+:10A0E000F0D4B34E1A6F79FB8FC3A9F801788E8430
+:10A0F000FBCD6395FC007ABF2B55267EFB7254E79F
+:10A100001341F88E3E6EA219F5F2D98ECFDFA6BCB0
+:10A110004627B75B180B3D7805FCB3AE436FC538D7
+:10A120004E5DC70BA40FFA5AA7EEF3F5AC8BE6AF62
+:10A13000EC1B68E9E6C9541EB7B83CDDF336E2D142
+:10A1400038B09DEEF5EABA859F6377E8C17201F8F1
+:10A150009D21F0C074E1FB6998DB63C638E984286F
+:10A160007ECFCEFBD632339ED34FB6E9BC28EFD795
+:10A170005817DAF0BE925471CF46B2A4F3A2BC9E37
+:10A180000FBC88F77D75D51A1E473E77DD1A1BCCAC
+:10A19000867578DEC4CC484F8E581FDDCBD065D392
+:10A1A000D3F74B6BBF19690678D2BEB714625EA1B4
+:10A1B00002F784F2AE9118C7684EF0BD8470671E36
+:10A1C0000F9D943081D8E2A17DD5DF093EFEDD618F
+:10A1D0005DE5B65EE61D9FC6F9715892C18BFB1D09
+:10A1E000C383CCD3D60B5F29ED94F3CB7DF1DD9EF9
+:10A1F000B2D0B5C897187FEDED7BFA34AE977E8963
+:10A200007776E03E803DB404F1B8E74AA01198DFCC
+:10A21000D9E752B6AD8E98DF03625DCE4EE17AED9E
+:10A220008DD91686F2B6D8D028D972C3F2A62EC11F
+:10A23000BB13F939655E5047F113215F503ECB6483
+:10A2400017ABFD2605DE35629F48F197B4F2580B37
+:10A250007FC3054925977E89749B14295F0CF4BE42
+:10A26000427F07E5357CDE2A517EDAE7CCD742F51E
+:10A270008D12E55D7E7E8CDB691839918A513E70C6
+:10A2800079B3E4F19964F72EF4F1FCE605DB97511C
+:10A290007E11D6EF00FA5AE0E4E7A216AE51FB17A2
+:10A2A0008B37AAF90FF781D16FBA1E2F7400FE5CAD
+:10A2B00072BFBA7D1DE3FBA4759ABCA46421D77A52
+:10A2C0009CFF4B13F671312BBE94734B1B99C793B4
+:10A2D000867691C837FE7C7B76CAC2887ED7644872
+:10A2E000AA733AA7414F0D827E679AAD54CE4CF3C4
+:10A2F00054A6C1FB8569BEA9589E3B2AF066E81AA0
+:10A3000042F2BA86CBD1280C22C23FA3AE3193BD14
+:10A310007B17DE7B05F88B8AE2F259D1E77AFDCD17
+:10A32000FA789CE7A7454EE2E37F9B5C8979161B90
+:10A330004A3D05C85F1BAA2D74AF419B8EDF6F6736
+:10A340008EE2F7ED047E37E600EE6D0F6ADF54868D
+:10A35000F70B584341162F63DC6715E5ABAC1BCFF9
+:10A36000E8FE32E53B2521EF2E84276B9685EE2112
+:10A3700071E8DB9C1817710C37897B13B89E691044
+:10A3800038FE75477602EAE3F37B2FA37218E3EBFE
+:10A39000AFE4E5E33759C43EDA9966A8479C6B1CE5
+:10A3A000D62E058DB8BFDEBEAA16E9A57E75E724B8
+:10A3B000BCB7A5EBDF19E5CD389E4F2D93E3C3F075
+:10A3C000D5EF7ADC4EE70B845CBB06FD3EDC8311E7
+:10A3D0007654F73902E1B7D408FAACDDCBFD956BC2
+:10A3E00062397E17327716F69B6B66F13AC0D93523
+:10A3F000E5EDA3501EB165461BDA71979C3722F438
+:10A4000099B6DD693CE380F2F0E9288A2B353C11EE
+:10A410004771B915BA2EFAFE9634A1F7878878FFEE
+:10A4200020E6C13CA3867D97D1FE5614DE9B54489E
+:10A43000F2CB8CEB7A08E52CCCFB8667A3E9DEB681
+:10A44000EE7B49ACCC8F7CBA625F0AF9A78E6C4F69
+:10A45000C14DB9783F46288BF81BE49504B6D8AEB9
+:10A4600087674CC33C95863490B7503F91E69B6616
+:10A47000003A6C18185A82216C437A137F3F2C746F
+:10A4800012EBF1E92DFC7D6168891EEA43D337F1B7
+:10A490003A268A016115A76F9986E7F14EDBB85E0F
+:10A4A000396BE4F1DFB34F0FDDE68F58F781E95CDC
+:10A4B000DE9D8EE6ED4EBBD8753310DF39A12191BC
+:10A4C000F9F026D14ED17FCA3C957E303EEDCF6A61
+:10A4D000C70FA671797B83B84F66422C5B47F76044
+:10A4E00019981FF3AC0EEEBD8CF0F2781A3FC78EB0
+:10A4F00070E2FEBE328EF69CBAF2DD1BD15EB45025
+:10A50000FB9A48FDF19A5837F8CE1AFA4EAEA700DA
+:10A51000F9A461464601AE1BAC9741AC97C14CE72C
+:10A520004CDBA83D8E6BC33CAD72AE37262426B6FD
+:10A5300021DF2B7083FD6321BD2CE07F47E89D1B4D
+:10A540005A04BE0066CC6B6B7886EF7FE2FAA23EBF
+:10A55000199ACEE73F309DC385ED69BC0CC0EF88EA
+:10A560004B9FDFE7FF4BF38B58170FD2C9C18EA16A
+:10A57000B42E0AFC8C6D528D737A95A65F09E3F7B1
+:10A58000AAD8B3A9DF5DD1CCCCEF3BDBD6DDCF952C
+:10A59000C7ED0BA47FE59E30E61940FB54F5423A27
+:10A5A00074DFEFD5CECF47B041303FC4EB8CAA2249
+:10A5B000313FAB989F95CF2FA0A247F66657D6ACF8
+:10A5C000B89E74DA8DF7EEF1720BC5782AFEED6D48
+:10A5D0003C5CF7BED6233DFD1FBC1E0A9CE05E45D9
+:10A5E000AE43379E35F029F844BE157C48799A5A17
+:10A5F0003E8CEF5E470DFFBA7EE2F7C43EDCF2DB35
+:10A60000611DF1FC83ACA6E7E57B5CBA85B9E17E10
+:10A6100077EFD0C44FF6FCCC8F7EFD8ABDD5941762
+:10A620006A5C0D7292F209F4248FCFC1BBB5308FF2
+:10A63000733B5D019CC79D42CEDC69EB8A97287E07
+:10A64000A3D7A19DDB057E33EAEFAE68788EE716CF
+:10A65000E0F9E311F33EE7ED8AB745AC57D1F3FAE1
+:10A6600078DCF70A05C08EEDC5DE50EE710A31FECA
+:10A67000BE426FC96AC23CF2D6EC42DC623B6F66F6
+:10A68000594D0EAC0F2EF413C5F238E3A7CCFBF6F0
+:10A690001508B7C89B627E8F2115E87A91A0EBBAA6
+:10A6A000975BE2C92FDB0BF6577C2FF69565564278
+:10A6B00050EE6957DDC81A498FD66DD53EE7F1C80F
+:10A6C0001B3579DD3E11C7D5DA5B75E9C2DE2A603C
+:10A6D000055C2F727BE126114750F2E5CF897C792A
+:10A6E0009827E1FFFC4E89E7C733F975F4931A0EFA
+:10A6F000EBE9FE2986D9D36322E3965D26B49FB4A5
+:10A700007684B63CF387F78B7F0E4DEAFFF85EDE6A
+:10A71000AFA13CF3C777873C8BF53FBD93F51EEBAC
+:10A72000D9BE7CDF77749FDAB97D510CFD9473FB41
+:10A730005ECAFA39D69F897223DCE75647D13EB00C
+:10A740007F5F1C9D033C9729CEE53EF76D5E88E256
+:10A75000446B687D1E48E779A9E7F7FEF503A493EB
+:10A76000F37BC18A76A15E8E25D9BDE29968BA2FA6
+:10A77000F5DC73DF1647DAA17FEF7C1AC47D81E731
+:10A78000E2580DC5D90C5D5912D911E31291CF963B
+:10A79000EFD96F427FAEFCF9FFC90B61BBDDFB4D0A
+:10A7A0006C04E98F47317F35F0EBE7EEC1739E67AC
+:10A7B00051A6815E1FBBF56FA4D7B5788171CFFE1E
+:10A7C0001CE7F17C2CAD0FE0A50EFDAFBEF0F1A7AC
+:10A7D0007F527C9C3376D27D80E7764923FD7224BC
+:10A7E0005E247E8FF6DEB88059A2F9F3E7FBBECD7A
+:10A7F00043FBF68BF65574BF427FF37E3B9DDF93A0
+:10A80000F77F67DE52F062E6FD977FD2F556E8FFEC
+:10A81000E7E95C2F68F9A027FFFFE956AAFF3ECEC3
+:10A820004DF05E24FF2765FC73CEFF27AFFB6E89DA
+:10A83000E26CFDAD7BD13FE9BCFB5FF797C5BAC7C2
+:10A8400059F1FEC373CFFD4F168B987F7FF39E990E
+:10A85000F1CFC9E7FDCD5B1BC7DCFC1C7B18ED0904
+:10A86000E3349311CFD7CCF14AF4FB07B371C7A2FD
+:10A8700010F3BD3ACB6231DF639E44E760E179506B
+:10A8800026BBCDDBB9189EBF5DB3D989FAC0889DC0
+:10A89000709F608144E7A6675B9D65688724EE65CD
+:10A8A0000FCBB41FC3F35667CF492DC4F64798EFBB
+:10A8B0009E51C857B38CFC1C8C33C710792F29FCD0
+:10A8C000CD3A5C4CE74CE8EFF60C7E0FC3DB63AF90
+:10A8D0007FCB03EFAF6AF13662BC6C7A96B702D7D2
+:10A8E00071FA1C5B01DA11B37181A0E9CF33B8FFB3
+:10A8F000341B3BDB111EAF91FC7C655FC733EC273B
+:10A90000EDEBE49BBA4EDC0C705B8FF038A751D8AE
+:10A91000434ADC6306D623F6C5A7358DAC9A087E7C
+:10A92000C813021EB6B8ED4E4711CDD31F87F3AC46
+:10A93000DF4FE79ABAEB2B3F54BFBF435AABAAAFE6
+:10A9400071A9EB1B4BD746F6EF6B3E332A0B241F46
+:10A95000E8F8C4FB25557EA9522AF0BDB68AD592E7
+:10A96000BDEEF0C89897CBF063A9F85EA7F223C3B9
+:10A9700078E278A915F9BCD3CAD882C87875BB88A3
+:10A9800097B56708FFDE21E2E26E8FDCDBBD59CAB6
+:10A9900078EF2E9D20615C1453B67ADBB7090A78F4
+:10A9A000DF4D902B94FB20D16E3F56CBE3207DE111
+:10A9B000E1ED29AECC8100E79CBD4015409765359F
+:10A9C0000B8CC8D773164F9090EF8F4D0BE9B0CC1E
+:10A9D0001F08F38072EE0FEED4EA087C1D11F3D845
+:10A9E0007C8FDA4F53CAAFC4FB3FEBF87EEB9FE39B
+:10A9F000E5CCDADCC8FE669EEF1FC7E54ABE8119CA
+:10AA0000F4117133BC478DF2196AF83AE1F76744E3
+:10AA10007CE784C0E766713FCCBB4BF38D0B22DE35
+:10AA2000C765F2759AD107DEE23239DEC01E277E95
+:10AA3000DD5C2505F8FDCA1E0BFA134B05FF6D16EC
+:10AA4000E75267E2B95D78B474EC52F22BD856EE57
+:10AA50005798E17FB85F51103468F6513AE95EA328
+:10AA6000991ABF619AF027A6F5734EF44286259C89
+:10AA7000D7007272DA404E4FE0F7CA741FA5A047A4
+:10AA8000651DFAA21FEDF9DCBEE8C1EAD4333C9F94
+:10AA9000A1F819F9A57C1F24DFC8F97CF361EE87C2
+:10AAA0006DAE3A6F477FF38426FE3BAD29BB6A50FB
+:10AAB000C4BEE56BD34C35FC3E4DEEFF1C13FECF00
+:10AAC000E6CA91D1A596F0FA6CAEFC9ACE9574F3D5
+:10AAD00003FB717EC837713F7E6665149D7B9AE9E2
+:10AAE00096DF5FC6EB56D4EB65556D5948C715FA2E
+:10AAF000DC47FE059EBF561545679F14F9F4C64313
+:10AB00008F65A15FEADEB1B40243A405CC77279E2E
+:10AB1000A39A5125B9C92F14F1879378C60DFA2746
+:10AB200006F87DF4FA2A2ED713B7DADA26C37A8D1F
+:10AB3000C814E7F6AA78BBCD356AFAB941C8EBA5C7
+:10AB4000A31E3B3208CA1BA72D1C85E38FCA94792C
+:10AB50005C02E988CE1F1F3D886AA5AEA6807E6F85
+:10AB600046391FADF49FC3DCD523A570FBD35B1E14
+:10AB70007B10D1B4B472C1A860049D2971FD1BB7CC
+:10AB8000ABFDD7C422B5FFBB34A07E3F07FAE0BDC2
+:10AB9000F073FAA1C7F24CA0C7E1617A54BEA7AC2A
+:10ABA0009B76BDB479360AFE3B4AF495684FE4DBE8
+:10ABB0003DBEC87DE09B043E95B263EF7FFD7919F1
+:10ABC000EA453C6F2CA312B64DC4ADD7DABAD222F7
+:10ABD000544365E6828358BFA611EAF07E5E26BF25
+:10ABE000D76EBEF5C30AFC6989EB9CD28B582E90B8
+:10ABF0005D93EC50AE10785F9453FA228687AADCFE
+:10AC0000D5741F6E857E636C1EF2C7567E1F01C809
+:10AC100021BFAE973C9852306222CF89979BA355B3
+:10AC2000E7CB2BAC36557DB23355D57E8AEC52BD81
+:10AC30009F9A3354F5BECA5DA07AFFDB4C9E4FFD50
+:10AC4000E4239FBD7A3BCCF3C9317AFCE50C760452
+:10AC5000F1E208E305E0BD1FE13D32E6B62CFC5D04
+:10AC60009CDB32F9EF9EBCB175F45BB7B3B07C7B73
+:10AC7000BB8A71FA34F078C92CC6F9F16D26E87AEE
+:10AC80008A44F19F5942BECDF4AAE966C658E387CB
+:10AC90005128B744FC645AA576DF384470CE29E1C8
+:10ACA000FBBB899AFDA93942EEF547674F3EF26D2D
+:10ACB0001AF2E7A64C755ED79312BF3FC1FF16FF8D
+:10ACC000DD8DBEE458B7FCD2D0D76F055D2925C80D
+:10ACD00087049413F926753BA57C17EC53038CF37A
+:10ACE0005EB399CAF79BAD54FE67B393CA0F9B65D9
+:10ACF0002A3F6ECEA1F2B7995C1E2636C13A46ECC9
+:10AD0000332656794D3FC6275AF97624A423FE38B8
+:10AD100032FE967897259CAFF0874C7E3EEAB39240
+:10AD20008F2D526E984E3B421F59D03EA865013A76
+:10AD3000BF7A0D0BD279D6F92C44F5EBF008A83E7A
+:10AD40009CCFB0887928CE9560F55279043F9D0656
+:10AD5000F492F99FF7E2BD5679A82F2D94A7B92E4A
+:10AD6000920FBE13789B92E979217314E2B7F183B5
+:10AD700099281FC71B19DA7F4CDCBF94C8F7C8D8C5
+:10AD8000678F8C8E5ED88BDEB5672E7C2D73542436
+:10AD90007E7C266CF7A4729F8FB83FCA903C4865B2
+:10ADA000BF1C17F89D9FE1792393F67B1CE2F723E4
+:10ADB000BCCE1FD5177637D92FCA7C40F24B183F2F
+:10ADC000FD4AE87FA57DBE09E4287C7F9ADB67C247
+:10ADD000BCA7B22D05D1A15EE1F77D9A99A4869F0B
+:10ADE000CB114E4F7DADAF4217974A570AFDB46461
+:10ADF00078CEE3BC0DE25E2783BDC6897863D65961
+:10AE0000441FDF654A3F6A07E4957CBC7124FA253C
+:10AE100045FC1EB0BC8E4E0BCA8B37D0EFC9473DE8
+:10AE2000F959D94840E9B10E6645B970A428FB35F7
+:10AE3000D46B47B646C978DEF933497E0DF9DBDFBE
+:10AE4000A6A77BBC008F749FDC924A5B21FEDEC20A
+:10AE5000F47146D283277D2EFABD8291591C9E53F0
+:10AE6000C27EF283FD81FDA64FBBED839500C7C96D
+:10AE7000AA21F8CB0A40274BE32F47FBE2A16C1D28
+:10AE80000F97BA8D64376DD193BC79B36AD25B8B5F
+:10AE900023E4D8498D1C9BC3C98D9D64FE24DCE747
+:10AEA0009B23F4E4AC1A8DFCAA52D76B34F22951DF
+:10AEB000ECAB6BE596563E0DCA8A0BEB417D4FFB22
+:10AEC000EA94A52B783BCAA94A89F03413FC3E5F6B
+:10AED0003EDA0905C69316A40389E840915333ABC3
+:10AEE000C01F2CC272C14833B42F07FF04FDD49990
+:10AEF0007BDCC62596483A5B6062E8B76C5940BF78
+:10AF000037303FC33B2A8BE8C16BBD1CF0B1792FB2
+:10AF10005FC7FCADEFFC19E7BF64CB576F0E02BCF7
+:10AF20008FA8D45B513F1EDB3A3A0EEDAC37025F7F
+:10AF30003B586E24BD3752FE43D9D6AFD2907EB572
+:10AF4000F2C05FC6E877B0CE482C88BF4B74A634F9
+:10AF5000B90CC73F936932F07208AFA79698797D14
+:10AF600052259615FAB12FE0BD70E7ABF8FD59AF49
+:10AF70008BBCD3AB4216BAE7AF3EA4FB300AF368F2
+:10AF8000BBD4F7BC4CB8A0BEE7A594A9F56AB959E3
+:10AF9000AD57CFBC3C8FFCEB0AAB4BA37F876AF469
+:10AFA0006F81AA7E5548E747FA9A9A3346D5AFC3D0
+:10AFB000C472703DBAA418FA3DA66AC6F7F3A74357
+:10AFC00089BF7B7315E3E738A6B94B55FDEAC1A1EC
+:10AFD00046FC607BCCF7985E3245F5BD7AEC0FCF2E
+:10AFE000ABCD5E75BFA6FF227AB8A2E97BB2BF0BDC
+:10AFF00082EDAAF7230F77A8C671775ACBD11D2D02
+:10B000003CEE7E01CB3598379600AC11F296A35BEF
+:10B01000527CAAF1052CB579C5B7E9D89D1897B926
+:10B020004DEFAB43B9FFAD2E9043E7C1D32765E2A7
+:10B030007E49B56D2D1D1F9EC67CAB90AEC67C13A0
+:10B0400068C1FA84EFDB294FB905CF7927E0BA56FA
+:10B05000C5BE86719E7689ECEA7A8B38E76D6FCF34
+:10B060008BFC5D93EE73DE4E8F7301B4BFD33188DA
+:10B07000E21DDEF2380FEEDF2EFFE365747EACD604
+:10B0800055BA292B299C37C61CEAF300B52ECF2EC2
+:10B09000CC0F8A29D7F3B8CA6423C5556274DE7809
+:10B0A000715F03C5EF4C938D948F9B3C80CB9D9833
+:10B0B000FF6032E6BFC624FAF423B0DF5489213F93
+:10B0C0002AF0CDA8E2E7C47F9B25FC71A177AA9363
+:10B0D000DEDC49FB8903F8EF251657C9878C68A089
+:10B0E0005B0D56949B89C7BDD61100E71E4711F131
+:10B0F000ED9EE39DE32419DBCBD43EA5B2F4E652EA
+:10B10000FCDEFD7AFA5D9D3DD689B1D89EE50CA1A5
+:10B110003CA69B443E68E23CF91DF4ABD861231386
+:10B120003F1B43F3B00E8BF9779C47E271CF329A05
+:10B130006F8E45C6DF7501F85CF83B491F37E35D4C
+:10B14000707DEB998F372625E1BE6E75A935097F95
+:10B150005FA47A935EB9D486B697F067FC78FDFA5F
+:10B16000D727025C3BBAEB2CC800EF1B4C4C5C06AB
+:10B17000C15834D4ABA5EEF6D327E6523C4079EF64
+:10B180006725747E59BC5F42EFAD9AF194F15FCDB3
+:10B19000BAFEF57516C493382768B026513EE1F71C
+:10B1A0003F489179B6317AB918E973A14ECEC3B24E
+:10B1B00028DEF706D28755E71E82F59547477E8041
+:10B1C0007E12C897935B50BE4C3492DC5D91C3EF06
+:10B1D0007DDE6392FF781CF7379362287FC678F78D
+:10B1E0000DED1D30EE0AEB7F117F01FDD279F7F3F3
+:10B1F0009D3A3BC63B17EABBE7E3C1BB563ED2854F
+:10B20000EBC8770BC3F3F1E079C20D11F3C3DF3E56
+:10B210005924DA5B06DC3C7D0DD2FB6233F9BB3787
+:10B220000B1EDE6067AD98D7F975CEE573F0BB5F96
+:10B230006F3452F2F31E7C897AD11943E7368F744A
+:10B24000EA3C18B7F13B62DA0653FDBC19E333ED73
+:10B25000B0DE1E9CA03C4435EED76327FF47368EF8
+:10B26000D7A9D321DE16854C4C46F96160C12890E0
+:10B2700043C56317EA07E6F27BCC3DE0AFDDE0F2C1
+:10B28000FC7716E5952871BF7FB9A4B8DF0AC6E53B
+:10B29000D78A9255B928DF574C94483FAF68FA8651
+:10B2A000F0CA0CFC3C8F292A10588D74FB6C348F2B
+:10B2B000675A3CAA7B1EEE91B9DFDF9CE0B9474E8E
+:10B2C00042F9F735C93FA5FF1991EF80E7C431DF97
+:10B2D000BEFE6FFAEB30EE04F2731DCAD77A76C069
+:10B2E0007453849DC5DABFEA9697F9BAB01D66B863
+:10B2F0005F4FFA453B2F83AF8ABE572D5967E31D39
+:10B30000A3B7CAEF4EC77C9EEA68EB6CCC072A97BE
+:10B310000F4DC7FC9FEA4CEB6CCCFFB9F63703BD71
+:10B32000544FB53EA07333F60BF90A2FB57759DFAA
+:10B33000C2FA6D0344BD40A18B515E0FF25D1CAF9C
+:10B340000F1D30CAEBA7788485CE0B9EAF8CA6DF8D
+:10B350008FEC0BEF339B9E55F90F3DDE8BDF7BA30C
+:10B36000C42EC0F39753F8EFBE28F916CB6764508C
+:10B37000BEC515420EE2EFE994D8C3F9CE5F7EDA7E
+:10B38000B904EF8999B9673DDD573FB3691F7DAFB8
+:10B390009E815501CF6FCAF6950E1885F770843ED1
+:10B3A00040F9BA7CDA1B43E83E616B17DD4B6E1443
+:10B3B000E7BA808F9C0B90FF1C06D2EFB5CC47FEFE
+:10B3C000C62CCB2726BD0EE36E6EF243B4F2BC61F1
+:10B3D0006C34FF9D3F26D1BDAFEDCDA0EF8025762B
+:10B3E000377750E9E9D84FF9CDB59A3CE6FEECB98C
+:10B3F0001EF9D51AB9E251F28C35E75C1F4AF0EA22
+:10B400005DA3F03C51790AF7A3F83C7A7CDF32C89F
+:10B410008878D0C2319305C9AFEA0F9EB3719DD72A
+:10B420009AB2F1778EF8FA2EB7BB06633FC0F70ADF
+:10B430008E6FC0BF1ECFA57626737F62A78CF2E009
+:10B440007C8E99F6E362861DCFEBED7792B5F87BA3
+:10B450001FE64A7AC81032E13D520DC7F93D0A1580
+:10B46000FA7AD283E73B5C2C320EB85ED04982F880
+:10B47000FD2AA01737D28B239B0529EFF14F2FEF21
+:10B48000C4BCC7F5421F2AF4392196B5637EA54294
+:10B4900047405F6EA42F859EC2F9362FECC47C9B7B
+:10B4A000B2011CAE3D315CEE75FD819F5BD2C2F9ED
+:10B4B0009B014A5C560DEFA31709E7A3FF2038153F
+:10B4C000B9A4E049914B4CC8EDDA1AD7B60D52B881
+:10B4D0003EA3CA45FEAA02674FFAD92EF7463FFDA2
+:10B4E000D18D6900FF9D33453E2A7029726E4FF859
+:10B4F0007E150117BF2F370C17BF2721A1E96992CD
+:10B50000D3FA38FE3B68B3729C74BF4B42E779862E
+:10B510007EC16B0306D27712DABFA3D4D184A6BD55
+:10B52000D4BE3F3E54F482761E8A9EE8391F99BEEF
+:10B53000A3D51FE398B82F137592847E80FA3ECC72
+:10B54000523CD9A0F2037EA689BFDDAE6A3FD9B9CD
+:10B550004AF57E8ABC5EF57E6ACE26557D9AFB2131
+:10B5600055FBE9256DAAF7D5E61DAAFAD85027D9CB
+:10B57000DB479A2BC94F1F7FAA8BECEEA0F0E70F99
+:10B58000087FFE20FAF3C0972FA23F0FE5E1663750
+:10B590003D7FA5B984CA579B3D5476367BA9D4F22A
+:10B5A000F3554F5D6D40FFA6A4B395ECFEDF67FA3F
+:10B5B000D2506F4ED7055AE25C78AF1EB7CF999341
+:10B5C000DB978A7D70E7FE31AFA37D99F8AA9E458F
+:10B5D000CB7DEB93840B7AE68988DB27547531BCED
+:10B5E000A73941C481FE3F8BFE2018008000000077
+:10B5F0001F8B080000000000000BB5390B7054D7FA
+:10B6000075E7ED7BFB117A9256425F24E0AD56C898
+:10B610007210E2E96B2144784848410E9F95A08E54
+:10B62000C0225E7F011B2159CAC44A9C997D7409BE
+:10B63000C694CE28F54C8B5B3C5D91312113774647
+:10B6400076314329E0B5E3DA4ACDA46BA3C438557B
+:10B65000C99A24141AC12E981833F68C72CEBDEFF5
+:10B66000B1FB1614D9CC74359AB3E7DE73EF3DF70E
+:10B67000DCF3DFB512EC72E60074CA52B8A00A40DF
+:10B68000516C007900DD809F1A842EB0E7E622EC31
+:10B6900016D420B0711D7268127CAE7C80BF02FE91
+:10B6A000C1F1B01FE99D12E8B49FA889F075A2CB43
+:10B6B0009D2D4103C0062252905E06988F749BE434
+:10B6C000513B7801368EFD75EFC3380EBBF47A5FBF
+:10B6D0000611AD745FA80010F4DFD8A616024CD195
+:10B6E00067F9ED104002A2A3CF94487CE3977A80DB
+:10B6F0001F0A6A44437EF56C497D1987DAC4CAACD7
+:10B70000686562DD9FE6DB189D89AFF3AF06693699
+:10B71000C0DAA02E66D601C4DF07F520EEB57DE8BD
+:10B72000133E2EC11EBA4F1FEED54472724BE17B01
+:10B7300032711E7ED44AF4DBC7152697BEC69D958E
+:10B740005045EB3E65EBFA560A1F3B11EF1BBA0E54
+:10B75000522DF1F14A90E8AF9D05D589F4F74D8659
+:10B76000A22FE0398DF1E1D62CC4977E110A12ACDC
+:10B770000E8F82E432EE85FFB563C740AA48E0260B
+:10B78000DF2702DD20D9014E05FC0C86035B415A00
+:10B7900000F056A09FE16F078618FE4E4067702CA0
+:10B7A000B087C1FF0C0CB3F9D381FD0CFF6520C439
+:10B7B000602470988D3BE6037BFF76C5CD20B8569C
+:10B7C00028BE45246E0E137AA1E890A417DB0BFF68
+:10B7D0009DDD7B26FD984E1F00428A80FB6DAA707E
+:10B7E000C15E0FC083306C5F8AB07B8BBE68A77070
+:10B7F000F77AB111FC7660503A1FC5711B0830858D
+:10B80000FB6E90CBEC88C0866EFBF96892BCD78348
+:10B810005F25FAAED5D67130D69BFB3AE62B4C8F1E
+:10B82000C456111AF1BE4EF169B55FFEEAE7399CC4
+:10B830002AB38399CFE3EF622F0418C2F3ECD9BF88
+:10B840003E14461676C9E3DF166D779043AE14BFFB
+:10B85000B5BE14E0D522BEFEABF207A0DAE9DD6783
+:10B86000E2AFD5A3ED55EA894F37938BF99E8E85CC
+:10B87000FC3DDBC4C943FF44FA7F245D7592AD7E75
+:10B88000312500EAC7775C5C0FAE475A0BFC49765E
+:10B890006ADADF686094E9E56B81630CF6B93F61B1
+:10B8A000F63429D81EF255DE7EEF3E1BF85FC3F159
+:10B8B0001A27B8049293A7E525E2AB4D6C8E687405
+:10B8C000BE5B62F6379DFEF40D5D65FB4F3B8FFB63
+:10B8D0008FE23BF79DAC773F2227C6FF47118C7B59
+:10B8E0004BEE0BAE845CBEAC9E2E8B775BEC7EF990
+:10B8F000677E8BDDAF806D96F956D7D316BCCDFD34
+:10B900003D0BFD370A775AE63B94E72DF3DFACF8A1
+:10B9100091055FA3BE68A15FD7386299EFD47E6AB4
+:10B92000995F2B8246F25DE7EF60EFB409ED95F485
+:10B93000EA4108337DDE0C51863F842A40F0615095
+:10B94000187C143407CD3F0E9A9FD195F8CFD0FBC9
+:10B95000D885A84CF3978F7E5EE647B98AD9E3571E
+:10B960005E80DBFDDC97F56BA63F33FDDB6E076C7D
+:10B970001D45BDD895EDD0492FED793923A227F18A
+:10B980001E7F30E2DE74F613ABC607437E63AFA7BB
+:10B9900003A01EC5326685047C72EDC4BB67852A90
+:10B9A0003293721BF9B54143469A4B0E8B385EDBDE
+:10B9B000A3FED720D2C369111690DE837D3279DFD2
+:10B9C00036095D2CF93F49ADD8BC28717ED086FC84
+:10B9D000A21C0E237C15F9CEEC894A4A92BE8187BF
+:10B9E000F3BB62E34AA0F826F56800389FE9062D0C
+:10B9F00084789B0BEAD268DF2F3EA9A47DD77E8690
+:10BA00000F867ABDD70E617AB782C66A0190EEC5FD
+:10BA10002C4DF0A0FCF5E79AB32FA05F05F413536B
+:10BA2000F36FC76B4441A37BC73BD242073DB7EBE3
+:10BA300073B6C1CF76C33E6A6683AB90CEF7932CC4
+:10BA4000515E1DF71EDC8BF2AAF0E41876122FEF80
+:10BA5000A2B882E182D699717A320D985DAF3F9695
+:10BA6000860139B17F89279BD1AD775D67FA668EF4
+:10BA7000EF18BA69B1D71D95FCFE3541A5F669846A
+:10BA800083143B96E0FBCFF1CDF7E0FA6DEFBDE21A
+:10BA90002856E8BC03DFFD0DF9833199FBA3D37968
+:10BAA000ECAE3101BA4793E4BCDE75959D07306278
+:10BAB000D18F336B3EAC227FB5FE48BA4EEF6CF2AD
+:10BAC000F581A02C223D36FD57EFA94BE7A094FC51
+:10BAD000D5D573CF92FC5E771AF9C54D363FE0F5A8
+:10BAE000D791FC5F1BB331F9F676380F925E82A4D2
+:10BAF0002CEACA48C82576C9CA572A7FE679265F44
+:10BB0000938260F18F2B8CF779C988EB9733D5CD71
+:10BB1000F42E978F16DB7421317E263B52952DFF34
+:10BB2000FFC5F94D60E47DA3C1456E64091EC3BC29
+:10BB30008FE9C1DDC577537F4003C58D7C08C67989
+:10BB4000809792105F66E0C10C0839905E90DFB973
+:10BB500049F6BACC8040468074CD06FFBB857E2076
+:10BB6000FE5C30CCE05E4155082E177C12B0F342EB
+:10BB70004C7FDBA1BF84C6832BA2413A54CA8161AA
+:10BB80007131C0C5DCAEBC9DC4653EEC06C42587E2
+:10BB90006ECF27FBEFCA525F5612F25A6F9CB71551
+:10BBA000FF9B512E52362812D26FC57CD38E72DD88
+:10BBB000B065E3DF5612BDBB99C9B1CBB807AD2361
+:10BBC000393E70BA7F0DC5EB6FBDF977BFD470FCFD
+:10BBD00052CE7003F1F37F918355FF82344F9E392B
+:10BBE0009149F3DBC39176143DEC8038F3BBA6FC9E
+:10BBF0007B20C2E0B721CEA01FDC6CFE1150197C67
+:10BC00000C7C0C3E01FD0C7E5474A0172D003616E2
+:10BC1000ECB35F87841C9ECADED540E7B85BF62F85
+:10BC200020BDD35BA082F2A02157661560427B2322
+:10BC30008DC3CE6C5917B3D83CF39FFAB9B45010EA
+:10BC4000F57C0DF85F20FD1FB7F7DFC7E5DBBF9878
+:10BC5000F42196ED0001E96379DC7FE89721F43265
+:10BC6000CA396637D65F55185ED75AC3E23ADC50F8
+:10BC700058BEBF94F2125722AFA95B6863EB618A8A
+:10BC8000D32F8B4B963CA66EB18DED079FE3BC87FF
+:10BC9000E2AEF417F39C0DA5394CDF96D0007EADD3
+:10BCA0009B6DEBA7B8C23E784EB0307F84F21D1377
+:10BCB000772AEE11F27BEF7978DD11CBB4313DC1FB
+:10BCC000CF065703F1CBDF75E989F70C7DC4C22994
+:10BCD0009FDECB1897C26FD2F80E239EA01766F98D
+:10BCE0005F33E927C9EB98359E40E14289D6371981
+:10BCF0002C98F598807BF5E4903E47447ACFAF438B
+:10BD00009C410DDC2CAEB580CAE04AF03188FACDFA
+:10BD1000E02A1866F07E18657035441884AFA96A69
+:10BD20000D9E6F7385458AD7003F705FC0D0081D98
+:10BD30005B6C531422BF05FDA3F2CC72B96CF8A55D
+:10BD400099E58206DDF065E4E2E7FCA5CAA5A482D8
+:10BD5000D9912917531E69102A24392E83A84870B7
+:10BD600039F038BF02CD91F056D018DE36A33CC270
+:10BD700041C0FB3546FD92BFF20EF268E57A62EAF9
+:10BD80004D9B2833BDBB26E78F38719D526A33E245
+:10BD900022AA2EBEDF809BDFB3012AFEA119E9EAA9
+:10BDA000C7EC9851031C0F68F03BB4816B98718409
+:10BDB00069FDB8A8EA48DAF45828E842BC680FB828
+:10BDC000E96ECE421B28497A9CA6CC0225299F4BBE
+:10BDD000AFC8B1E04D6322AB5733D4399675598D56
+:10BDE000A5163AB44F91F83E1E05F847E4FB08D972
+:10BDF00037BD9BAE452A1B12FE365BFB9A659F65DD
+:10BE000091275603C6F3D9AB6A2CE3709DDB5B2305
+:10BE1000FED13B2D857EA6D74D93563B74C2BEAB5B
+:10BE2000940F34468781F42D6D3CC92E695E6EBF38
+:10BE300044FB3B21691DF2373451BDEAEDA47DC2BC
+:10BE4000A519B92CAF298112B267F33D52FD3EFA14
+:10BE5000B742F24375E92D9F50686C2ECDEF9430B8
+:10BE60003FA8AB6D19F422BEEAA087E34B5BFEB599
+:10BE700014F1FB0F96754A4BC89FB4D4DA55809DD8
+:10BE80003B1774AE443CF83EF77FE02AE7EF6AD4F4
+:10BE90003BD7E4EFAA6E7ABF125925BD79CE8177E0
+:10BEA000423E5C4E0E452FAF2B8F0790FE9E049FA7
+:10BEB0004E27CF17915EA7FC2EEFA2BE91FA0E7609
+:10BEC000AFC2F467DEAAF05B76856C4CA9A57ECA8A
+:10BED000BC397EADB43EB13FF2414A05C5061FE60E
+:10BEE000BA25B24323F941AEA796EEFD9D39BE3681
+:10BEF0005A17CB7031BF6DD21D36F2D225D2B03871
+:10BF000028D338F0BA741A3858AAADA17D52C74D5B
+:10BF10007B1550B83D942F3CA9BA24E6FF9BDDB7B2
+:10BF2000F24EA45DF2982692CB6FE8EEFF39C13E47
+:10BF300031FE04E9474FA97F13EDDBEBBB32AF9A2B
+:10BF4000F2F33FE00549CE50C2ED0EB8BF3E79EAAC
+:10BF500017CF1673D407497EA5EFD4CD4FFF1BFD35
+:10BF600050DF355925F25826BFE7D2132F0E32394C
+:10BF7000806CF1A3A61F6A3AE60C931E2E3D71EF6A
+:10BF8000E344B7ECCC8497F2BBE513D120B5AF62A4
+:10BF9000273F2CE6F66FE433DA0DE16EF219F40F69
+:10BFA000CCBE077E25B27A7580121BC25F15423A5D
+:10BFB000EA4BEF98FD63279EFFBF469C454F2E1727
+:10BFC00035F07C82DD0F229924A7AD071E5D4DFA66
+:10BFD00001215EBF2BF8477676DF59AB7DF58E5A8F
+:10BFE000EBFB3EB237EA5F25C7BF3BD8D35EB22733
+:10BFF00012E05C98CBF8177BB2FC77C8534D7823DE
+:10C00000A0AE7A1BEBB17DA00DD3FBD54BA0915F09
+:10C010006C137FC0EC61606E658D932571DC0F6ED3
+:10C0200049E3F779B04460721978490499E84E3AC7
+:10C0300042643723E8361B497FEA9E677ABDC5E034
+:10C04000CDB49F6D7B0450B03E8003B3994E2D3E1E
+:10C05000E4647A3E72C8B987E4B2F850814630F899
+:10C06000C3593AC59FC50E5E7F04D3E27304CA3339
+:10C070004E3A6C9417509A20E0398B4BE3A594DF2D
+:10C08000BC61F8EBA091DF80526EF1DB0319E5058E
+:10C09000548FDD9A8F4A16FB0F1A75461DF147F52E
+:10C0A00045BF9DD58F03699CFF37DF7F209DF2FE42
+:10C0B000D7255FBA5B263F5F9A0577E87798B03E51
+:10C0C0008CC2FF0B7D8BBAF17D11D2DBBAFD1297CA
+:10C0D000478A9E511C714242EE89F85366893FD7C8
+:10C0E00080EBE1B5120851DD60BEA7193FF27CD6A6
+:10C0F000B853D06D8D3B457E6BDC29DE6A8D37737E
+:10C10000FBADF166FE90358E78746BFCF0EE69B293
+:10C11000D02F186EB1E0F7ECBFDF427F6FA8CB8263
+:10C120002F3CBCC942BF68F411CBFCE2634F5AE616
+:10C130008FC328CB13A68B7BD5E1010BBD19F76A02
+:10C14000C7BE7FC7B8A7E31FB347239E37E23B5064
+:10C150005F6FBAF89716550B29DFBEDBF8075EC391
+:10C160005E8DF8F727ACE8C87F39491F44CA0F79BC
+:10C170005E996AAFD3E995E977D11FAF2B457DEA88
+:10C180004BFFA29CF6EB755D99578B70ED984D2790
+:10C19000BD582BBB3E26FE51DF2AA45CD2A3592AF0
+:10C1A000E53D663CF21976B14E96985F5B9BCEED0D
+:10C1B000661D0E37917DA7D477823C7653C8A43E86
+:10C1C0009590D2A74AB3F4A966EAA7D747C216BC8E
+:10C1D0007A1C44F2E3F5BF578219784EED04EFCF95
+:10C1E000A7D69375517F90C2C47D93183614AA27A1
+:10C1F000393F4D9F8DFE9CE853EB1FB8B88FD59902
+:10C200000EC3AE52EBCE676C589F62BC7B46F4B354
+:10C210007CF486EDB63AB4506279A89FE5A51B8BF5
+:10C22000FC4D5EF43FEFDEAA4F791D0A300A14F789
+:10C2300063F49D82977EB05393A99EC2EF73D0B8EA
+:10C24000F57FEED4292FCF0577B481B767E8D3E91E
+:10C25000F5B7D37EE7055E0F5E5952BCBB16F96C8D
+:10C26000A7788DE3053DA3E0E7FDA26F78EB6FFFB4
+:10C270005D2515A6F66D8F04C20CA657AAAC5E48C4
+:10C28000ED2FFD919858C2F6D5997F1912785FC6A7
+:10C29000A897371B728FDA80D7837BEDAC5E33FBB8
+:10C2A0000C3DC63DCEE3D456F4FB9B8FBDCBDEE305
+:10C2B000A9C249A37FD3AFBA71DDA325720DD51DE5
+:10C2C000A0D5AA5D96BE43B1F855E2F44CF77FAA1B
+:10C2D000F092A54F05AFF0F833FDFE3AF3C749726F
+:10C2E00060FB9FEFE0F1EA7C47710B6426EF7F85EE
+:10C2F000F5BD36F7BF6FD1EF87863EB2E8F3C3FADC
+:10C30000C796F9686EDC5E8CF78F1E2D6A7F10E58C
+:10C3100079F9756703BD07BEFF2E6F527F2BDA7167
+:10C32000EF4AC8FC32F7FC23E363221061EF6BDEB7
+:10C33000F35CE02CC3A3812883A9F734FB042674A3
+:10C34000BC05CC2FC485592AF51753EDE7199B7608
+:10C350008EF4BEA4AC94F77B80EBC1338376564752
+:10C36000A226EF7F18F11B0FA457EF456C62457EA4
+:10C370000BC5F589B90E89C3728E1735BA38DEBE82
+:10C380008A60CC2EEFA13EC384C0FBD9F717F95FBA
+:10C390002639F43D19AF227BBB9217FFD486E7B64E
+:10C3A000E7F80FD3B880EEAE88F5BDF472CA932FCC
+:10C3B000DAF42A016DFAC68F3F67F9FFC559FA15FD
+:10C3C000403CE6BDC1EA838B0E6E87BFF57EC8ECAC
+:10C3D000EE57B8994479C57181F52306B3FD47C876
+:10C3E0009E86ED10A6FBC4FF4D18A1FB831C759023
+:10C3F0007E9AFDC8981D21F501D3387CC3CBF3A1EB
+:10C40000B097FFEE60C25E57D441F1E16F0EBCE61B
+:10C4100023798DD8149E774348A377DF71EC696642
+:10C42000C7BF35ECBA4DDC574EFDF06BAB9D40FEFF
+:10C4300018F9D36C645FA79CCCBEF2F1AE9447FDB3
+:10C440008783D71D356F38C34272BFD3EB61FBE7DB
+:10C450007AD143E3BADC6FA68582F41ED1C8BCCE84
+:10C460000C76AF877CE46FC681F5372F531F98F7A2
+:10C47000013407E25D470B585FE0032FCFA77A7FB7
+:10C4800071FE1CF13FE0F5FF9AE47DAB9F0A910B32
+:10C490006E2FE38FD51F4E1176093933EBA7D91FC5
+:10C4A00035F1336B9E2B277DAF1105C6572AFD67EB
+:10C4B0005EDE8F98B0F33C9035422D7C6BD536EA2A
+:10C4C000D37655323F32BB8CCB3D554EF6322EF7EC
+:10C4D0001AACDDA80FEE9C8531BB667AB95F7E3C55
+:10C4E000F2F79508AF64280BC8FF9AF746399C25E8
+:10C4F000FD30E56DCAC1DCC7E413CFF7D3EF0435D7
+:10C50000EF9DB617E0BEDB7EE6A1F6CCAD7B997C55
+:10C51000EE9EA34D79937EFF46FD62EFA277A4B114
+:10C52000F7EE3DF5D1B96771DDB69F2CAA253D31F7
+:10C53000D7A5F28B7CCE25FE3EB085597F10F994AD
+:10C54000CBF2A88FFD413EC9D7E4F76EDF2736371F
+:10C55000C27E2F8A8DDC9CA7E0FA5EE377965EA30D
+:10C56000DF0347ACFD1D94AF4EF56D6A5C014A19BF
+:10C57000F229BFE1F1C369AE2F912CEBBF37CBE7B6
+:10C580002DC37B1E35FC01D287C8EE29EFA0F872BF
+:10C59000ABAF6CC4A37AC3050967791FB99E202588
+:10C5A0000495592C1ED599E7215FA40FBB059DC5A5
+:10C5B00071B3DF1434E2B6F8E820EBC335C2308340
+:10C5C00036178F530D25B22AB2438D3ED2F3EFB00A
+:10C5D0003AF2CF3F65DAF7B021000000000000001A
+:10C5E0001F8B080000000000000BFB51CFC0F003C0
+:10C5F000099FE142E59F1043E573A0C92FE444E59C
+:10C60000FF6047E5B7A0CBA3E12646FCF284F00922
+:10C61000A0FE8B407C0B881F1330CB9708BBF6998C
+:10C6200042E854203D1D88F70371872E0343B93E2D
+:10C6300003C34D203D5D9732F7A2E37E6DEA9A3742
+:10C640008A49C3932C50F9858E0C0CB39D1818EEB3
+:10C650003943F85D48F25F8062458E1076AB350352
+:10C66000431990DF6481DDDC36A07C39509EC5051E
+:10C67000C207009B5EE59168030000000000000017
+:10C680001F8B080000000000000BED7D0B7895C5A6
+:10C69000B5E8FC8FFD4A767676C24E0810927FE7A9
+:10C6A000014113D884F09062BB09118306D9282A6E
+:10C6B0005ADAB30354908746A535B6D4EC900701F7
+:10C6C0000306811AAD0737905AB456A382458FF6F8
+:10C6D0000641C56A299C23D55ADB1B5289B1A55E48
+:10C6E000B4DAFA7D570F77AD3533C9FFFF7941EBE7
+:10C6F000777AEE776F5A9CCC3FAF356BAD59B3D696
+:10C700009A351397378BB16CC6CEE1CFD718DBE8DB
+:10C71000600795498C79DCA1A39506E419FC5CC2FD
+:10C720005823A6A3E05F5CD5D934C61218FFD132D6
+:10C73000D5532E1F636714A89C061F3252A9BEEE64
+:10C74000AD6251AAD1C2D8544C0D6724C99C8FB098
+:10C750004811630E278BB617325627FBC79F00631D
+:10C760002E7F68EF6685B131CC49F5F5803BA6C1D7
+:10C7700038BABF8545BD385E740CF553C12CF03016
+:10C780001666388E23BD20390AFD322F8747CE4FDB
+:10C79000A60FD7544DD4F34D79075BDCEEC5F67187
+:10C7A0001ACF71378B8F80F1D8E7D7185717F5D587
+:10C7B00073281C4E996FC37685FDE16EDB363763B7
+:10C7C000197C9F22E0B7C329DBC33CA6D0FCC4BCC4
+:10C7D00024FC6DDBC671F8038101E177B8EF98A8FE
+:10C7E0008FE883577E6F489B66440B0522D219FE63
+:10C7F0001F50CFD87683B56840D7F40A3586F49AAF
+:10C8000050668C5A0A452E85D3F7F79E6819F6E3D1
+:10C81000548D5215BE05DBD80607B46B10F3BB4C24
+:10C82000ABF074017C3B2239C94B215DC514A2B722
+:10C830001DAED61A980BE0F59E1A37A57FFBDD7862
+:10C840009A87BD9E4C1FA8E92C32D3E181E88E79EE
+:10C85000E34A188B05D4503E8C9F51593FEA26403D
+:10C860008163AC51ACE15C562A3A4E2A41E1F35A5D
+:10C8700022E0003C2EE17C25E81F90F804784C78FB
+:10C88000F08423617FA1090F2C125660BCB47D2C6B
+:10C89000D4C1080FDFC27E7202307FC80717B5947B
+:10C8A0009AF100FD7BF2019E9DAFE5176F36FAE02D
+:10C8B0007E94A99CFF33039C8FF55006C2619F2F85
+:10C8C000CC8CEAFD00F0548803B07605D7C126CCA5
+:10C8D0009BF090CFA2DF4138C62C4E886913215DB2
+:10C8E0001356713E0D8AE4D30C86FC54DFCBF7D18E
+:10C8F000477F44FC973E19E1DA20E17948198CEF33
+:10C90000360CC477631647C22AB4BF488936627BA7
+:10C91000ADC048C1AEDC6B429436CAF163EC38F668
+:10C920003B52D041F27F9261EC41FEBF1FE902FD14
+:10C930008F2C6FBC4D05F8D3CBF5980BD2919D95FC
+:10C94000150CF0EE7E77DE078C7F27F93166490BF8
+:10C95000A29F651A55B588EFA4F96D61EC7AB412FF
+:10C96000BD9FE0A88AC5CA689CA88270EE7444186E
+:10C97000D2D1312B168E003CAD95D358A589CFF678
+:10C9800021B030BE1660E178611F1FFC40E3BF6F2D
+:10C99000AF58EA595188F512084F17B192B0DF8BA2
+:10C9A000FC006C00FCE0407E30881F7E8CE5C66297
+:10C9B000E3256C170CB4942A06AD8391C8D700C741
+:10C9C000286CB7B3D2B938CEF1F226F1A72AF062BB
+:10C9D000C0FF004F1E91BF953908AE048117370B79
+:10C9E00031960BEB6E624B5805FC0596B09001F545
+:10C9F000126C78D242F11896A7AD61A13074A519D6
+:10CA0000D1D9E3387EFE0DFB4B622D614710EA1B46
+:10CA10007186E9037AD5FFFC3ECCE381A35A28C690
+:10CA20004C7CC9802F4DF26CF472587F05823758C8
+:10CA30001F7F4AB9E067915730BF370DE487CF2495
+:10CA40007F84DC66998BA85E5675E89D95304476A8
+:10CA5000206332A158F7AB8887BD6E3EEF3EFEDF04
+:10CA600040F38FD7C4D91F1CB84E3B15E43F2316A3
+:10CA7000213ECC5ECF54C46B56F559055359EEA8F0
+:10CA8000D68CF746F4CDA3A1F9EA6486E5EE908A48
+:10CA90007C90DB32F92577807830F4239A47842D17
+:10CAA0004AC2A155D601F3FB09A4E7827DF2326B9D
+:10CAB0007D02EB70F7CDDB51EDE4FDC7C287F200DC
+:10CAC000EEF982A5E70B3AB012C77B9D124F3934BD
+:10CAD000C1BE3C4CF8CF77C17F506E4D56E23F52FD
+:10CAE000FA9757083A56E077392EC0A3298AD80F0B
+:10CAF000F97AAE1065870FBC356E0ACCE7584863EB
+:10CB00002EC4DA81579BA740FFBFBA04F286A05318
+:10CB10003AF6C7F1FBAB200B9761F954251E837ED3
+:10CB2000E7CFD04EE17AAB98B5F123941F1508BF3B
+:10CB300069BE1F1EFC8B8EF8BD7596F57B32C29EBA
+:10CB4000460CC3FB17656B8B35EAFF588912C7A5E6
+:10CB50007DE477EF6FFD0AC0F7C62C2584F01D0B2E
+:10CB6000FDC1CBBC7DE3F6E2CB607EC4977D1CC9E2
+:10CB700067403092E7A902DF690C967D2EFD4AFBE3
+:10CB8000D70831BF747F95C2A09F8C192D87F812EA
+:10CB9000E6741C1D6E9FAD436E67D2B8DFC4092FCB
+:10CBA000CCD0A711F40C4500D02126C655CEB950E3
+:10CBB000BE8000F761397C97F4017C8D5C63A2171D
+:10CBC000FC4B5A6CCD7B0AAC79CD4CDF60DF7C240A
+:10CBD0009F7B849EC0C25103D75B93127B1B977AC5
+:10CBE00073D3FDE10A582F8E4EC67C0194037A3C24
+:10CBF0008E75F3F83EAFE1BC01CF4919CE78077CC2
+:10CC000077837A761CE58ADEE246FC3A0A4261CDF9
+:10CC1000E89B3F5B974A7C932470BBA9A43805D757
+:10CC200085EC0FE4A565BDDBF721DD7072BDCA6838
+:10CC30003ACE539DE8E7023D4D09D23E51AE209DCC
+:10CC40005A9401F52C39CE60FB7B1F9D59810EF360
+:10CC5000BA932584707FA89E55FD76143E1E66D13A
+:10CC60006BB07FC7ACCE5A9C57F257ABB371BDFBCC
+:10CC70002E6655285F167F6509EB8634231089756B
+:10CC8000C3F76A45E3FD9DCDA2790B71CE1C1D371C
+:10CC90003003F77D6F281C463CB1C9B42F807CA0BF
+:10CCA0007495C2F783DB455A2DD75D9875209FC9CF
+:10CCB0007E70FF477872C2FE521DE0D1BC5C1EC977
+:10CCC000FDDF3EBF9B453F1B93BE9321F48D33D8C0
+:10CCD0009F53F4B771EC4DEE81F41FBF128D2926DE
+:10CCE000BDCD991122F9F715D8F709DF796166866C
+:10CCF000CBED6D61C8E7AB14BF653C1DE41CAE17FE
+:10CD0000DF5796D038FA2CA92783FE5D48F45B459F
+:10CD1000FD2DB6EA9F9E4098D647127BC8DF9D48FE
+:10CD2000BFE69D83C586B843FEFBB8C41D7701FDF1
+:10CD3000933C20250108AFF21E8D83FB19EEA3C999
+:10CD4000D809ACC7CD35C78B7407F6C3D80C60C5FE
+:10CD5000A490695DF1E4CD3C1857A862D0AE773D50
+:10CD6000D2BAF17AA35CBE86F87A72C3FF505EDC59
+:10CD7000099F66A6627DFF21D4479367E816F9E113
+:10CD80002F08913C48095BBFCF058221FC2997A958
+:10CD900071DAC358B8223FBD6FFCBF797C1311789C
+:10CDA000942B49D07F4A1AECF358FF24DF2747D849
+:10CDB000E4B309BE2E840FB773842FB9B033A652E3
+:10CDC0007D90861AC1D7658663046BFE08E900F082
+:10CDD00059BEE3BCBE5ADC373E8CD7651EAFDACDF8
+:10CDE000E1C37AB3A0BCFADD8F8A8E98DAC74A59BC
+:10CDF00041154CE6392529D07D314306D0717FF9A4
+:10CE0000949D0997E3BED49A49EBC2E7E76DBCEE67
+:10CE1000E3C444290827D0EF6F35678B8E98F44C14
+:10CE2000A0D7C7167ACD107903E425C7AFB59C65A6
+:10CE300012BF505E2378F8BEF77B4FBCCE04BFC450
+:10CE4000F39D5ABC5CC171D57804E19076A2C71DF0
+:10CE50000E73BD91F3E979F4D3F425F5731445C845
+:10CE600070FDD8DBD9FB857AD351AE423A09D3CDD8
+:10CE700079D05F2EF65345B851F430F5D3ABB708EF
+:10CE80007DC829F421873BD21484FEB4373516833C
+:10CE9000BCD63299F4CE5EFDC5E0E33903AC6DB388
+:10CEA000D45B4CF2CE53A05AF4173D3381F49C5E10
+:10CEB0003A2D8E2938DEB7459D5EFD86453B504FA5
+:10CEC000D7818736334A3B703F448985ED71C99CD1
+:10CED000A3FDF77B349E6CBFB9A098E4935D8EE907
+:10CEE000D80EEAA018E4FBA0B5DDE0FB826DBC45DE
+:10CEF0005678CFBB9D5737BA659B9CA1DAE9ACDB6E
+:10CF0000A48F65E3E245F9FF399403BC955840F3DB
+:10CF10008E65223DBBC01EEB007DE1533DB604F1A2
+:10CF2000F5A9E16200213BEAF03766201F342806AC
+:10CF3000D2A9B279E1022CAF7C530BA841411CC8A5
+:10CF40001F0DCE23BAE5AA5CDF677AA78EFB65E5E5
+:10CF50008CE05C94B1E57743BF48EF1C97F223A8BF
+:10CF6000377B46ED726C7795718303E5EEAB8FD717
+:10CF7000D1B8AB8CCB75946313B11FE0D33F3FF6B0
+:10CF8000D43406F01DFD6912EBC07D5E8F3B71BF8E
+:10CF90005FB55F233B67F59349A43FAC7A7AEDDE3A
+:10CFA0000AE847F95912C153FEF48A475C045F1D31
+:10CFB000F5B3EAD96B92EF43384F6A6033405ACBEE
+:10CFC000F7B7B5306737B43F1B74EDDD13ECC39F83
+:10CFD000C487CC2F6B0E3666207CFB82A4EFCBEF90
+:10CFE000AB74F62F11E8A712D2AB07D8F716A9DC5D
+:10CFF0002E3D13742D4678957D87BE49F36CBFDEB8
+:10D0000081F354EA539CA7013FF304DEA01ECD2711
+:10D01000F6A812CF87F2338F2A7C7EED45BB3D41C7
+:10D020001C7FB77329F9956AA93EC0FF2FB8DF2F7F
+:10D03000DB176C1C0DF59635058368CFCE79F2A70A
+:10D04000BE4E6EE77A15A0F72D628DDDBA4FEB402C
+:10D050007DE796FD6B49CE439EF49FD54FBEF86C9D
+:10D060002C09DB6B9675754BFB3D24D7573FE3A22C
+:10D070007DE38F6F6A210FF673D06191F37FCC78D7
+:10D08000CC877649C91B56F98FE37E964AE3543A1A
+:10D0900093FBB703CC3B91FF6E6DDF44E3DCCAF832
+:10D0A000BE43E530DF3FE22FA3FAEF0BDF53613FD2
+:10D0B00040B93C9D4D47FE5EA345923B90DEFB464A
+:10D0C0000CA89FC97D40EA67600FEC8AC1B8679ED3
+:10D0D000FED32E9CF7D12FFEB2EB7B88F7173D7E57
+:10D0E000E4F35B1F3BBDEBBB90FFF341978AFCB2BF
+:10D0F000EAB10F7E8FE57F7D6E7C2AEA6D3B55AEEF
+:10D10000077D18FC5B3AEA61EB5EBC6C24F2E5BA81
+:10D11000037346B201E4864C3F04BE8ABBCCEB34B9
+:10D120004EFD1807A1BF91907D41A436BA1DDEAF18
+:10D130007578816FFEFCB68BF4945BE15B35ECABEC
+:10D14000B754ADA8403B0BF3EB01CFB73CCEED9FFE
+:10D15000FE788E8D513330ED1883A6D72DFBAF5955
+:10D16000706909A68E9081F365671BD1AEB7B7EBE6
+:10D17000A5DF9B40BF49FDCB6F651CEFB7E2FE3FCB
+:10D18000B13FFDFE8CBF5CD29F7ECFA8623F17F4FB
+:10D19000FBEBA337247760E1FE11167FA39D7E6B26
+:10D1A0000F5C9B3C905C36E3B7E33CF0BB52D8FB92
+:10D1B000B56AF8B08AEBF3E99F3CF220E0F7C3DFF1
+:10D1C000B8421580900F7FFA69162A793D8EB3DF39
+:10D1D000C4F577F645977F0FB459F5E25BCE30D0B2
+:10D1E000F9C303279C06ED87A02A821CFF90F5FE59
+:10D1F0001C47B97E8BC233B7B62575A0BF47D2E9AD
+:10D2000096F8C272C347DFC90F744B9CF3FD2DF132
+:10D21000438B9401E8F6BFD51C2E4FE3698497B584
+:10D22000C671A7DF6BA5A73203E9786A2EF2DD602D
+:10D230007494F3F7E3FCA79BE8DA36F4BAFC70B712
+:10D240004B5792FBE8FBA1F01BDF1A57DE6203ACE1
+:10D2500057E9EF60DA9221E964E7874F6DEB59B641
+:10D2600097F31E6E3D0F3F9F0BC3D76914A269FD54
+:10D27000F1567B1997CFC7822ED2B74F388CFBEF70
+:10D2800040FE78CDC1F64093AB72DED78D01ECCF76
+:10D290005F015F1AE3FBF291191FD58F80769159D8
+:10D2A000B09F187D7CDA5B3E4B6386091ECDBF378D
+:10D2B00082FACC60F8D47C6EF21FB1B0DE8DF450EF
+:10D2C000519F55FBF023FD1BD15E360D53FE5BBD18
+:10D2D0007950AC41DEACC05F019ECA708913F58302
+:10D2E000E52CEAD4811E2B590BE557B1764AD7B00D
+:10D2F000E394BA320D27F7BF97F9BB494F59A39D65
+:10D300004B3C7FBD44C2774C31EE2D03FE7164303F
+:10D31000F29BBE3C8AC5715D38C7BC90897CD00C3D
+:10D32000F86380BFC61A3F1AEBACA92683D2DE731E
+:10D330009430288800FFED7E0E3FDBF7D8638FA581
+:10D340000B1507F0D0002A41BB891F0F0B7A9CAC4C
+:10D3500071535AD6DCEEC075ADAC79CA81FBE6CB11
+:10D360004AFBCB7EDC0FD62AC5C2BF76591AC887C6
+:10D37000DC663FF9C15F177EE1DCC593D5A5A67DCC
+:10D38000FFEBD80F7CFFFA9AC9A3717FD9FB8536D2
+:10D39000A01D5DAF713F7EED1627E9A7BB6A19C9D5
+:10D3A000F55D97B8C672E32D83F4E799427F3E326C
+:10D3B000DB35761DD4FBCD4A2D84FEB0DFF4DC973F
+:10D3C00084FBCDA1BB7E307F1A7C9FF926FF3E18DF
+:10D3D000DEF7A05C8479B6C17C513E3E0278C4FC85
+:10D3E0003EC023A68FD518943E5E5340E54FD484AB
+:10D3F00028DF5E3383F24FD78429BFBFA69CF2CFCC
+:10D40000D644287FB06631A52FD4ACA4EFBECDEEB4
+:10D4100028EA393FAFA9A2EF33632115F7C78E9AE7
+:10D420006A2ABF524B253ECF6D0EA951F45736B133
+:10D4300026942FD53116467FF21E47E70D11139D16
+:10D44000AED4B8FE748F485F56426A0ACC37960253
+:10D45000FA28CC3777D1E497904ED77A8306B27BFF
+:10D460001F5D2A1DA585E74F8FAB35EE2729F36A8F
+:10D47000ACC0A4FF5CB708F2A675786C766726CAC4
+:10D480008B63A07EB1D18C75D6EFAA8D417F8F9C26
+:10D49000059B18E1CA70903F748F27BA7902C0B516
+:10D4A0006B94A3640F54DD33D93FDAAC1FFEBBA0ED
+:10D4B000FFEE14AE874E3FCCFDA9F10FC6EDD9406B
+:10D4C0007BC77F9E3B07F4CFC2DF73D19924FC3723
+:10D4D00005FE04F3394BFC2EE187476709B47FFE54
+:10D4E0002E7F1CF5F0B8A2121E20652AE9EFEA1E75
+:10D4F000D4BB99A124A05CDF0D65C908DF06750FB8
+:10D50000FA4F9F17788BFBFD6AC8046716EBF55F2F
+:10D510006824DF0D6638A7E17746FE10590EC37701
+:10D520009C137B1EFA4BA81CA69455CFFD8FA67E9C
+:10D53000689F28889BF2F0EFE27D563F4A51BB3549
+:10D540003FE9A0353FB9C39A9F72D49A9F7ADC9A7B
+:10D550009FFEB6357FADCEE98DE717E8FFCE167298
+:10D560008F199D74DE928D7E70904359317EDE9BC3
+:10D57000B55EB7F973ADFE6E862E9769E26808FE58
+:10D580007349A7B5BE21FCE186CDDFC29614A8661B
+:10D590003B708BCEC82EDE328BFBB5E1A7CC13409F
+:10D5A0007FB6E247B9F34AEB2785EB20CD6A053D0C
+:10D5B0001DF6831FFFEB2B99287FE7DEA54670DD64
+:10D5C000CD0D767A90DE6E23245C72BD7856CF4DF9
+:10D5D0001F9C7E61102508CF962FF8FA4B9DA793CC
+:10D5E0001DF571CCD8A305FBF03441D07895E0C788
+:10D5F000F9B31C16BC5664382C74BDF4AC15EF5F3F
+:10D60000FBCCEE2F33F18176E1F909824EBB40AEBF
+:10D61000E17EE071B6903CF4FC9AFBB7F2ABC32F0D
+:10D62000A1BF3E8B9D9A8DF649368BD7613AB33AAE
+:10D630000198D004471BA78B1B3031D07947DE8E71
+:10D64000F3A3273595CE7D139E739AC08E9F02F962
+:10D6500095733ED0F1BC6011DFAF24DD810EACCB01
+:10D66000CC17E63C8CFF4EC7A30ED42BB23EE3741E
+:10D67000B7B7BFB1BA53890D20D7B23E73527D9967
+:10D68000DF05FB40976378397A372A2569FDE5E99C
+:10D69000C417C1A085FC13B14E05D34977C5354CDD
+:10D6A000DB7BFC2AEE47A10646E5936BA11CF2CF7B
+:10D6B000544339EA079FC32C005EE93298F201AF68
+:10D6C00067D4772A289FFD31BFDA09F582D58CFA15
+:10D6D000F1C7E21AE68D9E4E0FD603F9D8A1045089
+:10D6E0003EAAF10D24DFBA368D47F85F56DB117E76
+:10D6F000C6CFC2D8F3D5461CFDED52FEB1E3F17B97
+:10D7000048AE02BDF13BCAD9049493B5AA90B35C6C
+:10D710005ED1FA07399B1D53C39E891679A5925C89
+:10D720005BCFF9D6CD9A6A51AFBA5079F43CC25367
+:10D7300038BC5C7A49EC43A009D1F704B7C2F5B80C
+:10D7400041E4D46C6695ABFF5572EBDFB12DC09907
+:10D75000EA30521492132A4379158F5DCDF576E1A4
+:10D7600067227A6BFDF97297D047643EBB9EEFFF4C
+:10D77000F67A27E4BEC7BEC6CCFC93556FDC3B4BA4
+:10D78000E83D86817831B6E1795DF0A846E7D8C1F9
+:10D79000FAE3E548F7FC1295E1560BF050FB88D010
+:10D7A000A73C4ECE2F9E46C6E56C8C7967A7F78ABC
+:10D7B00004160F8F48457D30BB5AB5F8430AE4F98B
+:10D7C000689CDB3DD27F9FDF63F57B64815D5C10ED
+:10D7D0004478ADF65116E293EF8756BB49E0AB773C
+:10D7E000DF64DCDFF99F8807E59F2F677BE5BFE0FB
+:10D7F00013296FA5FCCDAF8E2C9846F356480FC960
+:10D800008A313AE7CB66670FB9203FB385C79BFCE7
+:10D81000BF2E7783A8A7A13DF6D939D2EF664A7A01
+:10D82000F7F4C56DF0B82AFF6E94579F9D7A3F5E5E
+:10D8300087FEEBD474B213EF947A4B89880B124DA8
+:10D84000E4386794E89D7A5AFF38973BC5B8A9F346
+:10D85000F2868C134B0AA956FA08BBD485716E2642
+:10D860003A788CD1967AD20E03148651EE66CCE4C7
+:10D870007680ECF7239DEBEF773A542B1C421F7117
+:10D88000087AD9E191769FB4F7B6E8C7DDDCFF618D
+:10D89000D56B1CCCAAC7C8F65BBE882C267D46CAB1
+:10D8A000A9EA5405FDDABBAAAF4EC6F899190ED500
+:10D8B000E21777087AC8F67B6DFEA43C195F23E86F
+:10D8C000D780F573FBCA4789FE72035C9E0D474FF4
+:10D8D000597F087A8E720C40CF2D3AC83FD413413D
+:10D8E000FEE1798A948F0ED13E37707636EEA3D959
+:10D8F000EBC32A8E3F0EFE8D00BCE4355BE5597EFE
+:10D9000000089EC37AE5A343C847BB3CDC55DD3520
+:10D910002F88E702CDBA81700F2A075B4D728DFE0A
+:10D92000CBE31E736DE77E0E21071D83C8414907B7
+:10D93000C705CA4156602ACFB1F0C979C9B93CC6FA
+:10D94000FD10C3CBC3F0499487174BFC087998D7D7
+:10D950002BDF3F22B9E76865A1B88172B0B316F337
+:10D96000D90FF138AB8D0AB7FB2E1678CC0E2458A0
+:10D97000D6D74A87D8F71E97E7C403CBC7710FD90C
+:10D98000F7F718F975241F1495149796E5E0BCACC9
+:10D99000F11B8EB226F23BE696733DC1D16CEDC70A
+:10D9A000BDDF9ABF0D3B9CCAE73BA2F8C2E1B28F34
+:10D9B0002FD7FF60FE0ABB1C92F284798B49CEA45C
+:10D9C000CE5BF7EA58D4079B449C248BB9B2207FE6
+:10D9D00067BD41FE19606292D30E8F4084382FA933
+:10D9E00016F289B5072DE519A365DCC9590FAE9B61
+:10D9F00086F55DA477A6DE9573EF7836389C83F9BB
+:10DA0000A5EECFFE7D39AE3B07E81FE82774E83C62
+:10DA1000EEF26FA794D00666E1278B5D26E5A05D48
+:10DA20009E0D27C74E08B9FAF7CAB1876DF59F1644
+:10DA3000FDE5AE3FBF7D49D61F428E3DED1820FE6D
+:10DA4000F2FFCBB17FB61CE37A9D5D8E49B9349C61
+:10DA50001CB3CBAD0B960B027F76F990AD85FF8A98
+:10DA6000FCF271F9BA8D545DE82BA9B51B2EC7F3F2
+:10DA7000B8C1E4443C9633A45CB1AF57E97F5E0083
+:10DA8000FA911B44CB025826060C7545E6F117CED9
+:10DA900042E99FF4A8C709E5F313C76EC0EA1B1D4E
+:10DAA000670314941066863F9D9FCB239F29071B15
+:10DAB00023A8973A5815E9037506EBD4C8F9BCC4F6
+:10DAC0008FE75C0AEB64E72EEED393EC706D44FFB6
+:10DAD00034ADB30EB293C9EF07FDAA896746A17FA3
+:10DAE00039D3A958CE0764CAAAF533BDF8CC21F8BA
+:10DAF00063A807532C10DAC4977AC81F3951EFA4D2
+:10DB0000789832FFC232B4FBE78682C532B68251C2
+:10DB10003E85D6B5E68C8E77C2380BBC1795E17C76
+:10DB2000303E84E2DE06D1177BE190E70C61D6A996
+:10DB300098F61F5720A8A6B0BE79FFDE1329467CB1
+:10DB4000063359298278995698DC3904BD1E117123
+:10DB5000F5E8AFC7B8AB67816E9876809CC5744F07
+:10DB60008D41E9C19A024AF7D584A8FEAE9A19946C
+:10DB70007FB9264CF99FD744289FCF22A538FEB8FD
+:10DB800007CB47A31CAA73B295741FC316EF76A5E3
+:10DB900093FB67655AE13408FF0D3831F4A79E7096
+:10DBA000F2B8573D3CE6EA249EA27C98A41F3AE2D4
+:10DBB00087AA57BCDB49F32E6C6AAF4F827C7B91FE
+:10DBC000A2B2498CF95E48E85080DF7DC5EFF7DCF2
+:10DBD00003E54F164127F0BDA8B5E508F2F513455A
+:10DBE000203FB15EC1C6DB705DF85EF8F5F728ED49
+:10DBF000E8FE3ED2C3F5F959FF95D8AFDA317A3550
+:10DC0000D277A93784FE8F079F7786B1DC17FAE1B8
+:10DC10001D58BF90856F5C0D5DFB0A1FFD36C9372F
+:10DC20003DA6F900EEC2883F84FBE383CE96391807
+:10DC30008FF9E4752C84E756BEC27FBB93DAB777C1
+:10DC4000DC85F5D3E355B3518627175FF2C3FBA0FC
+:10DC5000BC75C2847BAE8434E3F9D64D98DE5BF4A8
+:10DC60008D2B8B216DC9DB7E02C5CC83996F8EBE57
+:10DC700003F2716790F0F45ADEF68A62E8FFA1358C
+:10DC8000A9B43FBC96773805F7A989F91AF9299FF5
+:10DC90009EA5979BED836F3B799C638DD3C9E3343D
+:10DCA000F334BAAF20E5AE3E8BC7CD3B0EF2F84D54
+:10DCB000C7411EB7E90954D11A84FDA506E9CADA9D
+:10DCC000ACFB8FDC67EA9C7EE147E84C45FFCF81E7
+:10DCD0004CD58FFC7E20F3EA44DCE72165145F9D80
+:10DCE000C7E34A269E885C5904F06FACBA7D7A2D52
+:10DCF000F51349BC1EE0D8E04CA07EEE41FFC1D434
+:10DD000021DA7F04ED619C8D6BA0BDD1D77EB393EA
+:10DD1000C7DF6F1FAE7D70216F5FB5CE32FE7DA273
+:10DD2000FD0FB17DDAE0EDEDEBE84101F781379FC2
+:10DD30004E41F9D8A6B4E73140C98B8D57D7E9B029
+:10DD4000AEAF50E3EF61BC2E73AE98B318D6694501
+:10DD50006F1C6E3881CEA3D6A5929FBA58C89A2B55
+:10DD6000D5F0E642E4BF5F680CCFC706970B6ADFC9
+:10DD7000FE4002C764FF533ED5961F6DAB9F6329DB
+:10DD80007FCD29CEC3D945B67AC596FC9507C795F0
+:10DD9000211F5FD9915ECA7C83C3F7FA8B7CDDBCFF
+:10DDA0008E6B988C71106433187B4691F91573CA89
+:10DDB00060FECF88F263CEB575B585544EFE45F84A
+:10DDC000BED87CAE784CC8E977041F6BFBDD749F2E
+:10DDD00045F2A1B6BFF138E6F50E277DD7DE709E7D
+:10DDE000A27CE126FAAEBDD0487AB9C7DBCBD7EF2B
+:10DDF000105FB70FCCD76C39F747B8C4DCABD9F19B
+:10DE00001B492EEC50795CDDE3FC7CC1857A2EF158
+:10DE100021D78B0B7BEB579553FD0A9DE828F5E244
+:10DE20004251FFA7C00BC7715FD28F131F54B38E2F
+:10DE30002B2EC638AE37548672E7F08EE2D7910F9C
+:10DE40009E3CAA515C3C8BE652FB8952FF8AE7F369
+:10DE5000BCD0B393B3647FFE44E4D7FD4AE8F542F7
+:10DE600094A7F3749263727F96FC1612FDC8FD7A34
+:10DE7000BD8B9F1F3EF1426A228EBBBD4CA7F2496B
+:10DE8000FA53246727FA6797A6183C9EF4F9629420
+:10DE9000BFF123F8BDEDC5712AB2E2EB499DF75DF4
+:10DEA00089F08E5543782E97CFB651184251B591CF
+:10DEB000300FD274570AF53F717DECD5EFE3FCF2D9
+:10DEC000FEA2E279F0A4964F5E4A443C7530BAA7B0
+:10DED00095B74DD75698D6592853A57597B76D075E
+:10DEE000C9BD8640DB4C4DD0E9C624ECD7C5E55A08
+:10DEF000263FDF36C9AD7417F273F3C0F4CDD7589F
+:10DF00004CC3715F55E3747E57EE4F5C683AFF7BFC
+:10DF1000AA1DE428C057F8D4A2DB5F837AF5FE99E6
+:10DF200053783C4178F4CDA4AFCF9A82F27E9C4BDB
+:10DF3000DCCBF30FAA9F8F730DA09F7F5CFE8982BD
+:10DF400078CB2E4824B99BDDCEF9F7A9CF0DADF7DC
+:10DF500070DDB4EE26EEB7FAF7D426ABDF289B9936
+:10DF6000FC46A49F5AD7377BF7E2BEFA39A4FFF1EB
+:10DF70007B0D42AFCF1765A93B55DA879F6861716A
+:10DF80008A438C85BDB3A7F5DD637918F90850BEC7
+:10DF90005BE8B34FC5BA1214E2539D62375F794113
+:10DFA0000D75A07D26CECD1DF5C74B911FE5FD1744
+:10DFB0005753A48EE45E89C362174C7DB385EE91FE
+:10DFC000CCDB6FF5F74A3DB6D8661FE489B8993CBB
+:10DFD0009B7D608F7FB9D6658D7FD9FA5D8DE2ED2F
+:10DFE00062BFD6681DB75DC262784F150D428AF7D1
+:10DFF0005E3A9ACE3924FD643CCC3217F7271DF9DE
+:10E00000DDFB09C8B74FB48CA375B60A27497293D4
+:10E01000C781E48975F5744B0ED9B98767FE22A1D3
+:10E0200093F44F7E2FA748946F80EFC847CF00BE70
+:10E03000B18B1FED2F1E83F7B2EE2B7393B3CFB7C7
+:10E04000373206E31F0FEC16F7E474CE5F186B4B04
+:10E05000EB1FBFA19F3D13EC46A87F874BC4432A0B
+:10E06000913B90DF54378F1BF6E5DE9681F6EDC6C7
+:10E07000A0C2EF1D0ED3CFFABE7ED69BFB91FAEF66
+:10E080000235AA73FEEC20399225F822CBEDE5F299
+:10E09000D8AE371FE7FB05E8BF1B5DA8EFA11E4FF9
+:10E0A0007EF8CE52EAE7FCF5DF98D97ECDF2DF1696
+:10E0B000B6EABFD1EDD8BF113036203E5D997EBAA9
+:10E0C000E7789988E3FFB89AC7810C36CE5EA1073E
+:10E0D0003F2CF4E2DD421F3E8EFA703EDDA37C1839
+:10E0E000F191D5CCEF456455F37B9475CED062DCCD
+:10E0F000DF5FDED83507F7FB0687BF18F7FF1F6F16
+:10E10000ECAA738FC2F8E0B3A330FFDCC677E7B8A0
+:10E11000A1DC57A7D0567C00F2B159308ECAF11F4E
+:10E120007B8409BD97A59603BC139607489FCC56E0
+:10E13000FD5714A09C5AA5921CF7B5713DD20EFF55
+:10E14000C3C2EFE5AB3B751BD2FB3917D7AF9F13AB
+:10E15000F494F9295AF439928B3AD37533FDAAA372
+:10E16000423EB58C46F93400BDB55EFFFF50F46EFB
+:10E17000EBA5F7AB380ED03B1C50FAE8FDBCCBCF7B
+:10E18000E9A9C33845E74FFF2C61770F66E7B93E31
+:10E19000BB182F49F7E6815E27911FB232B93ED0F6
+:10E1A0004B2F15EC122FC2C7EF1DFAB48555B8CE10
+:10E1B000DE17EB5BA69D025FCC6BBDAF04F2BC1318
+:10E1C000E7E5D1AB44103D97E7BE3AE8C76BC2AB79
+:10E1D000B03311AF68674ED14A4F63BB1E97D497D7
+:10E1E000ABE85E2FD3ABE85ED5DF8DEFCC5E7CFF76
+:10E1F00085AFAF4E95E2C718B74BCF17BF7DF7136A
+:10E200008C7A8ACFFA2E0B81ADCDE678175AE2F5DB
+:10E21000E5FE6FEFE7308B6AEE3493DCFCDD4617EA
+:10E22000B65BC0603E84A70E8A5B2F1D619428A850
+:10E230000FC7DC656F80482C45E56634E65D657880
+:10E240002E589AC8F3654DFFA33E06ED4B31B694A8
+:10E25000F4C5DC323CCF2ECDE5E5E5A2BCD019F605
+:10E26000BBA75AE444DCECA705B9908EE539FE144F
+:10E27000D25F1C017E0F6B38FB18FD353A75729624
+:10E28000C7AD54F37BAB712127C0DE3570BEE83FCC
+:10E290001BCADE9DE0E67C24D38BD0184D33D9BB5E
+:10E2A0008F4A7B373E9ADBBBF1D1667EA8665C3E27
+:10E2B000B0591EAEA7083D3347EA8136392CF5CC5C
+:10E2C0001C8F956FE2A3A4DD114AC07DAB4F5F8C1C
+:10E2D00050DECE57524F94FBD9827D9CCF7CFF59A4
+:10E2E00057D90470CC057A225D5D82DFAA3C06F125
+:10E2F000F59E66AE3FA4DEC5E87EE78F5A525370A6
+:10E300008F79C315BECC4CA76657F8721BDDA236B9
+:10E31000BACD47FCF6A79B90E7EB19C589667B3D14
+:10E32000343F490789F7B7049D4E0879FE1F429E86
+:10E33000E7B3F075D86F9D939F6BC77EA1915C1D6D
+:10E340008C0F068D8F14749672649987D3B72FE55E
+:10E3500072F72D11D79B3383CDF427F7F57B9B9B69
+:10E36000DB336F79AC768E4CABDCBCBDAF2E42F2AA
+:10E3700049C6A14D68E2FBB4AC77BB5B9EE31B2AA8
+:10E38000BF47D4A222BF5E8F7041BFB933D82CFFE4
+:10E39000A4BEFA31C187D727F072FBB835725C2171
+:10E3A00017E5B879CDD6716B7BC70DA9FC3D8E30D2
+:10E3B0008D3FA1E92CDDB3CE15F7AF8D964818F34C
+:10E3C0006F7DE3CED33B517F4F2B28167A34C3F7B2
+:10E3D00030EE13F03CE80C67E0781AE009FD3459A0
+:10E3E0000037A60E2F233BCE511D237DCFA4DFDFA8
+:10E3F00047FC9339B07E2FF1EED35999CB24AF323D
+:10E400003DAAC5DF27E779FD925A473AC037BED506
+:10E410004F7E9585650AADBB60387337C6397C225F
+:10E42000F0F2E8BFB27684639CCB68C027351EBE8D
+:10E4300081D1B9C3837783BDEBC379F0FDBAA15411
+:10E4400025FFCFC88ADA076E8674FCC399F43DE3D2
+:10E450000E95FAFFAD3BC8E314EB53E9FB0FAB029B
+:10E46000F4FD81E53CBF774D1ECFD7ABE4CFD96B30
+:10E47000F3EBB4BB359AC7F36EF1AE49BD4AF64F24
+:10E480003FBFCE7ABEFF3996F3F32813FE9E27FCDA
+:10E490000DE2D7F9B95BEE532D9E0484C7CBFD3A4C
+:10E4A0007BBDC5242FF67A855FA45EA5F3D8078EC1
+:10E4B000877E51007C525725FD32A184EBA19F1726
+:10E4C000DDDCAFF20ACA91B421DA9F85F6304EDD69
+:10E4D0001AE917E2ED5F16ED8F61FBA943B4372609
+:10E4E000F3F6E8D7318DFF4B37F7CFFC7A98F67B00
+:10E4F0009B9F4E59615A0F27453B270BBFB309E637
+:10E500009DA4F1FBAB3F565A6E5C85FA5ABE9BE464
+:10E5100046B061B99BFB7DACEBF83D37E7B34F04E8
+:10E520007F1FAEBF8FE2B026D4EF28457CB2166EB7
+:10E53000EF061BCA54B3BD9BB79CDBBBC18600E78B
+:10E54000239BBDFB895BD8BBCBF9BB23267A7EE23C
+:10E550001EC2DE95F200D643BD793DDC26E454EFC1
+:10E560007A10F266B8F520E5DB97B51EAEF0FC63D5
+:10E57000EB21D5C3D7C3048FF0735EF87A98E01906
+:10E58000C2CF29E5343429435709EA79B8CF3E2C64
+:10E590006A49F990BD9EEBD1BDF2137F00FE96C58E
+:10E5A0005C7E82FECDE924BE8F8CA6D3F900BEF836
+:10E5B00080FE87228FD08FFFC17557E8E1EB66AAF6
+:10E5C00067987533C8BA2B11ED2FF50CB36E075948
+:10E5D00077B33C7CFD5C364C7BFBBA2BF3FC63EBE6
+:10E5E000EE1AC197721F3E5CDFA5A0BD9E55FF1EAF
+:10E5F0009DAF81BA11C2EB2DC1065D358F6B2CE743
+:10E60000F00CB6EE9679065D77CB3C43ACBB893A0D
+:10E61000D82D44DFF3D3E7EDE76EC3C507A19EFF16
+:10E62000033A5F0ADFED31EDEB0062BDE053BA7FE4
+:10E6300022F954AEDB5E3E95FA457F3EE5F31A843F
+:10E640004FA5DEE67746EB3C53FBD643361619D88A
+:10E650003FBFFF3CF8BB0D2BDF8E1A64376C46B80A
+:10E66000B366443A707DF7BEDB303E9481F1F275BB
+:10E6700029D677B1F440682FC297FCD59EF6C3E83F
+:10E68000974B2B9E8274BA5FAC7BFBFB0492BE401F
+:10E69000A7FB711C49B75E3F2F30ACD9AFD038EA29
+:10E6A000BAC1DE5978D863D21B1C01FECE82FDDDD3
+:10E6B00003B09F845EE908A1ADFAD228B61FEDAA87
+:10E6C00097E47B47429F5A9011A4F78D1C60B71ABC
+:10E6D00060B71EF604C57E0B3A0AF0D17C613FDEBE
+:10E6E00019885D5EC9D0AE8B93BEFD273DDA8E7072
+:10E6F000FC32F1EEC5FC5D123FE95D2F8973C9580C
+:10E700001A13764207F99B5C821EA52CE456515FD2
+:10E7100047BEC3F39F598CEE5BB10485D33513F824
+:10E72000D0742E5E2AF0CD32855FC2762EEB723326
+:10E730007702EC238AFBD0DB78BFCEA533B78FE21C
+:10E7400004ADE7B2C047AF7A38FD75DD8467478016
+:10E75000F35F178BBE8EE55B67FEF16D0DE0F9F39D
+:10E76000018F8171F1B71A9D57E51AFF7DE725EFFB
+:10E7700091CAF807D8492DF7D565FC83B457B2770D
+:10E78000707B657C8CBF5F5510DB40EF36A17D89C7
+:10E79000E5B93B74867C0DE5B42FC9F6E3E34E4B37
+:10E7A0003C46B0C99ACF15EF43E48BFBF3F41DFA56
+:10E7B000C915F19CB9B6EFF2FEDF2EFC30801FC503
+:10E7C000EE3FFDC233F0FDC1C1EC25E92FF5B1B03C
+:10E7D0009680FC5CCDFD0F75692C667EF749A652CC
+:10E7E0003E686E7E0F4FBE4B21ED2B9627FC2F62AD
+:10E7F0003D30413F4FA6B107F1959AA0487F652A69
+:10E800008D27D7B5EDDEDA2625CAFD35DE182F17A0
+:10E81000F7D8E8090A95DB7906DA75E2DE9AB7A43B
+:10E820008A7CA3AECCAA0EF4CB261530039B2B0515
+:10E830007186FB4942417B06DE7BBA67B07B4F099C
+:10E84000DC3EAA2D7212BCF7FC4E21FFE33DF9DF3E
+:10E85000C930DF4393F13447C67EC7DD69C2EBC6DA
+:10E86000C0ED6EDC2737665E3D24BE1D2D1AC5E166
+:10E870000E5BAF89D71BACDC15E0F7C5FE3636F66C
+:10E880002AA2DA85F15C24770DCB3998A3379E2B29
+:10E8900042EF08497F833C076B7047288EB4219371
+:10E8A000BFAB35E8789F2914C79BAD85CB916E87A8
+:10E8B0008AAE23BC3A8C767A7F27B110F60F485D7A
+:10E8C000A138DD4FF01630BA3F311CDE7313B8DECD
+:10E8D0008DFBA8F9BE9933D49281FB8F33CFC950F9
+:10E8E000BEE85E6BF926F16E8153C4B1C9FED24514
+:10E8F0007F9522451E98518CFCFA4884BF83E12500
+:10E90000B940FD40E1482DBC94F3A1F5BB9A547287
+:10E910001CF9E0F6B14E63283FF43B352C92E7C07A
+:10E920007898AA56F42BB7264C6F68C8A0B846F260
+:10E930007BD56FBEAE01E3A27FAB727F13D3DBD377
+:10E940001616A15DFDECD4CA01E8FFDB84F66F93D7
+:10E95000FCCC72FA517E6E1CCBF9F1EBD727D1FDBE
+:10E960002359EF51B18E64FCA4BD9F1D62FE187146
+:10E97000C1FD969122F37D39FB3DDBAFAF54227987
+:10E980002639F24EEFFE174F42FDA121ED91FC8199
+:10E99000E07DC713FF16F9C5C65AE1BDF13A0E2F47
+:10E9A000E8F353B17D4B826A8157A600C758F3390B
+:10E9B000DEDD625ED0AE48F847084E3B7CBF95ED89
+:10E9C000F5F62481CFFCCA01F0F05B4FFB80F07DAF
+:10E9D0001DE1339D1BFDDC864FC0DBD88545FDE185
+:10E9E000DA99E0B7C04774C6FEAF4DA2FD4ED2FD26
+:10E9F000FB095710DDDF11FE6BC0639AC0E3D481C1
+:10EA0000E07C27213E20DD6FBCDE0AE7CBFDE08CF9
+:10EA1000170D84BFF38073C879FE1815B2B4A1DA5C
+:10EA20000D3CEE0BA2DDAF67E9A43FC6407FCCC72B
+:10EA3000F3B11155DF31DF67BDCDCBEDBFDBBC9C42
+:10EA40002F3EAD28BBB78CA17E1B247D6CC5EB1A75
+:10EA5000D99F199318C9F39E78EEEE98090F9B6B16
+:10EA6000F8BD19DC0762AEBEF384CD25A93E03C60E
+:10EA7000E9A9BF83E450EC5D85EC87C1D66FF5BB97
+:10EA80002B5EF93E946F294D5869B64F3353781C6D
+:10EA9000CEC264BE2F4CF4C6AE0AE27E16D60D6618
+:10EAA000D23F2AFD55FC5C362BE446BFAA8385B6CF
+:10EAB0005E0CF39DF8DC229FF53E78945DC87DF0F6
+:10EAC000D479792710EF9F1ED5E8DE4E8F1EB9EA64
+:10EAD00012C4A757A773D086F8356BF9658FC85451
+:10EAE000A46F522B97CF4D357C33589E50FA05CAF0
+:10EAF000B5B7C4FD9EF7BFAAC4F1DD8643D3566502
+:10EB0000A1DCEEBEEBF84AFCFED7A909F4BECD02AB
+:10EB1000A8E64EE5717F942E996C50BC149004DFEA
+:10EB20000B5850716539C545254ABD37EC536730E0
+:10EB3000F6F61589D4FF9AD6E06EFEEE5694DE4BBB
+:10EB40005823E38BF5A873B1F9BC8475CEB90BD308
+:10EB50004C16BE16E30C5B175E81FD2E58B496EE84
+:10EB6000CF2C986114535A7E4F04F5B99B2A9471A7
+:10EB7000E8575C50FE949F7F3FE4273F45F3B2C6C1
+:10EB800051808F9E026F089F2858507E82CA6F2A3C
+:10EB90005754D4DF7B962F6F1C85F49F91407E9B4A
+:10EBA000A5E53C9E6C758592C7FB3B45F5575628FD
+:10EBB000394632E63FA27EE7D757BE01D36215F34E
+:10EBC000F6EA48D7792C46E73B97B3F8370FD03EA3
+:10EBD000C4FD1E37B5F27770B65E745108F798958C
+:10EBE000F1A75E190DF984AF1684B8BFB437BED44F
+:10EBF000796E0CE336613A3727B0DF040DB45C5808
+:10EC0000A223BD2C5C3603DF0D8D533EC7BBABA1E9
+:10EC10001EF4AF6415CA43F42E5BB82C03CB79BE47
+:10EC200073DFE70D472EE9CB3FDB90DE7864947805
+:10EC3000777434BE5B36612ECA9DE44B5804D7A965
+:10EC4000CEF8FD2720458CEEEFC1EF1BA6F5C1B134
+:10EC5000DA2BFC2FA21E7C7A0AEBFD7AF1B22D781A
+:10EC60007FB6BB49F3A31CAF9F10F6E1FB072C1A3C
+:10EC7000F2E13E72EFA11B7C781F2879D3355791C2
+:10EC8000FEBE5BF1E33A5FD91973221E6E8E29ED49
+:10EC9000B83E4EEB6C2EE6FF543FDBA8857C7672C7
+:10ECA0003EF14F77EB0827C6DD75B6297EEC36F9C5
+:10ECB000D21D8DD84FF7AC24DAEF3B9B73A9DFCA86
+:10ECC000568DE214BAE3B53E3C6FEA6A7AC6373332
+:10ECD00080798DDA9D66B5948F35F17301B4BD08E6
+:10ECE0009E266D0F7F8F93BF0B9988BFC37A49AC67
+:10ECF00057C213300E2199CBAB3F6486B2502E25FC
+:10ED000036FFEC4E8C47EC627CBDC422C2DEC01FD5
+:10ED1000688F67A2C80781268DDADF9CC8E542624A
+:10ED2000E4C2EE97DDDCC9E15BB143891B30CFF76C
+:10ED3000AA2273311E71D9E30ABB6F80F6CB1E5233
+:10ED4000A87E653BAF6F2F4F8C69649FFC51896E25
+:10ED500025B8776A4CBC436AA9771AE0C6F2C4A703
+:10ED600094DD6C8072589D47F0BDBE00933FD6F293
+:10ED700040BBD2C1E3606DDF85DD0378B0C4338F63
+:10ED8000AD58B6039FA11CDBEFBD4C7ECF329D2852
+:10ED9000C3FADDFB5EFD90C3F2DE66BA7C2FD87647
+:10EDA000CFADFB0CBFD7182B5169BEE9AD5C5FEE50
+:10EDB0008614DF1F7823C3F108E91F673BBCD70126
+:10EDC0009FCEBD418DA0BF686E30EAC1FD44DE0B11
+:10EDD000F7E5F27DA9D43DF9881FBE5F91C7E381B5
+:10EDE000657C707926CF6FF9A2EA9BDCEF32F07D6B
+:10EDF000059A8F4A70123F84C57D85F182CFFE63EC
+:10EE0000037FD7A06736C8E160FFB8776831B512D5
+:10EE1000C6EBDA343215633D7A14E197788DF3B599
+:10EE20003D2E7E45857211C5C1B018F97D57C65378
+:10EE3000E8BEC7BC026BBDC8430AF9AD2E376CDF14
+:10EE40009B36D2BB9F6BE2A728AE694DD816776F71
+:10EE5000E78FE1F2E21ED01C41D7A322DE688EB814
+:10EE60001759CEB695A5C27C6E5ECCE3E751AE6273
+:10EE7000FE5B4BF87DC86FB5255AEFDB791D43DE8D
+:10EE8000874C5F32F07D9F0CFEA9F77EE9D8B24532
+:10EE900014879065E3C30C71EF672CDEFB01F83239
+:10EEA000D659DF793DE93C5E9E8BF8CF5268BF753D
+:10EEB000675ADFB1457BC56CD77F94C8E3F15886AC
+:10EEC00041FBF6CD474730735CD2CD5E1EA7CBDA4F
+:10EED0001C67CDFE8D8F8F5E33A41DE831ACE3D867
+:10EEE000DF61EC27DF01B71B4CFB8C49AEC7855CAB
+:10EEF0004F42FE9772BD3CD120B8DF0B87B63AF087
+:10EF0000ACDE08537C836F0E5F1737E1FE087C761A
+:10EF10008DCECAF4547A7798D2426CC7FD44E4BFD0
+:10EF200079A52083FC9037B5EE36F09DF87E70C150
+:10EF3000DED6386D40B862480F844B31C1559F0210
+:10EF4000FB4D2EC227CEB5CAF9BED3AFDF0CEB7E88
+:10EF500066EAB745EE634AC980F3F539906F33C26C
+:10EF60001917D22F088D6D43F61B09F99CB9FDFBCB
+:10EF70008559D44A3CA803C3DB4B1F3B1E10CE5E11
+:10EF80003C2C063C14F5B5F309FCD9D763F7E2DC59
+:10EF9000AD530D2B7DF93D8C41E63B0C7DD2BCBCC5
+:10EFA0009FC1E824EBA7CAFE068107B65F9F6308EE
+:10EFB000BA0ED63EE2E5FC66EFE77CE7E114E5D366
+:10EFC000443F83E159D64F3F5FBC4661DD68FDF1A8
+:10EFD0000A43B763FBCB137BF136A03ED567F754EA
+:10EFE00066E1FED22DEC6E69F774B772BB47DA3B6F
+:10EFF00068E7C44698EC9ECC2A8ADBD95C924376BB
+:10F000004F57AB46E76CFEE9CD5979857D713DCD13
+:10F010007EFEAE628F78AFDE6EEF3C2BCA537C5C17
+:10F02000AFB9D11BBD6A36C0D515D8E0540CD6CFC8
+:10F03000EE81A13BF15DD63AF10EF1E99523B65E82
+:10F0400087F5FE4E7B877E806E6B318541D6CE1074
+:10F05000F1E29F43ED69F8FE161F776D27DFB73E9B
+:10F06000295FE74424AFF59BEEA9C3BF152D4A07DE
+:10F07000BE5BB102FAEF2A10E301BEBB7AED271E98
+:10F080000F8EF6520CF405ADE19A26D4F797272C93
+:10F090007DC40BF3763C70CD54B2AB74D063A1FE4B
+:10F0A000C9547E4FE4D0B48B4EA072D4F34B0743C7
+:10F0B0007FD0ECE985DB50EE759D70D01DA3D9D3D0
+:10F0C0009B77B950CFFD8D8BF25DCFB118D2FB3B52
+:10F0D000E9CE38D2EF4F8778FEAF0FBAE89D8506AC
+:10F0E00047FB2E2FE4DFFF4D1243BB0CEDB6A80B00
+:10F0F000E356401060DC375447FB0AC4583A7FAFF0
+:10F10000CD18C9D3764A7742BD2E7AF7AD43E5DFF5
+:10F110008FA7F3FAD1913C3D4B69B787EB2D12EFE6
+:10F120002FA4717B7B71AAF40FB12C94270DE80FEB
+:10F130004478E6AB71F3FB9F327D2495B76B489121
+:10F140007A50E8067AFFB4225DC57DEECDC8B28460
+:10F15000A978AED89AA3A2FD134AE27C74A22C77B8
+:10F16000AC13FAFD59BD8BCE09DE2B53E20ED84FFE
+:10F170004E058D0DA4BF6D6221F42B8C73801E0390
+:10F18000F9718A128A41EFDDEFB2B803ECB2F75A97
+:10F19000B75F86DF4FEB0AD955ADA9DCFE9ABE43B7
+:10F1A0003BE5003A5F3563F62FAF80F292C7751AE0
+:10F1B000F72769974F3D89FD366864F7BD9CE622C5
+:10F1C000A5F6273BA7C771FC36164EC0F7A862F11B
+:10F1D00081E388E6A472B873762FF319B81EBD2AAE
+:10F1E000C595DF7B68D33103E16829D51155A75157
+:10F1F000C040BF37C567B7D54293933EBE7E4E3AF7
+:10F20000A38DA8CFC71ED4E89D58E4238C13EB161A
+:10F21000EFAE9D6EAD23FBA8BB657C08D7D2CA7844
+:10F220006D16BD5F9CC4F5C43A5CBF6437879A9085
+:10F230005F7B364D1961FE7B23B124A7A41BD93512
+:10F24000F27D07A9BF8F65F2A7576EF1F7EF5BB9A3
+:10F250009D90D5AAD1BB2E63E3AE0EF1FE86E5DD0F
+:10F2600014A847E71963855E3F86C50F95E0F775DB
+:10F27000567D6B4C3DAF377A8D5D0FE3FABD5FACC9
+:10F28000D72E719FEF2B3DB677BC855EEFB7E9F5C2
+:10F29000170BBEB1CFAFBB7E0EBD3F3966274823EB
+:10F2A000AB5CE6F36BE2F7A4B2C0CE19E89DADB15A
+:10F2B0003BB8FD02F5480FB3CFA7BB87F3FFEA7D4C
+:10F2C000DCCEB2CF6BD5998E46DC64D63C6ED503CE
+:10F2D000EDF0B735F17B0833BD3CAE6E668BBADB23
+:10F2E00050F07DF7F63AF4B33BD202F44E6043900F
+:10F2F000AFA3D47965C966BFEAC624BE2E739B54FA
+:10F3000016368D93DF92C0C2263D707C6BAA253FD6
+:10F31000213EDA52FFE27D3996F2A2F68B2CE5937C
+:10F320000E165BF2933B665AEA4F395A6AC94F3D53
+:10F330007E85A5FEF4B7AFB6E42FE9BCD152FF2B12
+:10F340003D4B2DE5979E5D65293F29E22FBFF6D9FC
+:10F35000ED96EFB3D9F72CED36087E7065A82C6ECC
+:10F36000AAE74BE4FA29EAE131CB79BBCAA2A67A33
+:10F37000778BF629972D1A52CFBE57ECAF9BC4BBA3
+:10F380008075F82EA00BFF9E5106A50DF82E20A427
+:10F390001BC5BB805BF05D4017F65BF200EA819F06
+:10F3A00066F0B386CA4CB60BCF455D207B0D83B1AA
+:10F3B00011D3385F25C5F8DFCF881AB118BDEB34FB
+:10F3C000CBAAD727E459DFF1D6BDA99677BEBD8574
+:10F3D000A32DE5CE408E25EFCEBCC852DF57526C30
+:10F3E000C9DBED86CFBC5CFFEA62D163E457C86835
+:10F3F00021BFDD6076CA7578869036F8FB7EEFE334
+:10F40000FB7E06BEEFD792657EDFEF9742AE7D6052
+:10F410007BDFAF7BE7F83D1B681DF3F7FDF0792339
+:10F4200044E04DA9BCFE0A16DA8AE7C4D2BE26BD66
+:10F43000009646770AD75FBA1535CCFD1DAEDD08BC
+:10F440004737BEEF87F92D9A78DFAF92F4CA3F783D
+:10F45000F9FB7EEF3FA8D1FB7EA79581E337415FA3
+:10F4600090F638BDEFB756E4EDEFF9111CA0EF743C
+:10F47000FBAB9C18EFB0F62185E4CDDABEF6FF2D8C
+:10F48000DEF5DB2EF6EB61DFF56BE5F2F0BFF05D4C
+:10F490003FA2FF96107FD72FBC237ADF3CA0DBFC76
+:10F4A0000C2DA4187DEFF8497F8EA4CF60FE9BBF82
+:10F4B000D72F73690A970BF3453B0D6681DFBFECCD
+:10F4C000F7A4B22EF01D15BBFF44FA31A4FF642946
+:10F4D000FA4FA04AB9B14D473C8E7C5CA17720A47D
+:10F4E0009F6575D397EB47195BB6AE2C57B970FF84
+:10F4F00089DD5F82FB1CD2F524526D34CAF59F343E
+:10F50000E27D806D623D6ECF8C24A7221DC53B1C21
+:10F51000AB853C68F629967847FB7B69598F2B03AE
+:10F52000BE97B644D831DB46855EC33F55133BC911
+:10F53000EF8F254C0EDCB01CF2A7C209A47FC9F7DF
+:10F5400029283E05D6F51635E69B13EC1B278EFBC6
+:10F55000C178BC5FCFF78336F14EEC23E29DD87DB6
+:10F56000B81FD0BBB17C3F781CDF891D8FF3697F4A
+:10F5700009EF577FBA884D8E013D2FDAC7485F0CDF
+:10F5800094A5C7F13CE75426D7079142785FEF94E2
+:10F59000F0DDB818DF177ADFC7F039E57B26641F86
+:10F5A0002D1738FDBAB8975529E8EE12EBEF1B8BF3
+:10F5B0003A1DF877D4B6B73C9386FE7256CFDF7308
+:10F5C0000E0BFA7FA3DA6179CF23C06A8FD5A0BF73
+:10F5D000BE5933E241ECD77A6F8F191105E1DE068F
+:10F5E0004AEE8390FF43E7AB7E7A4735A43394B36A
+:10F5F0002E5BFD40DB422503C66719FE51783E387D
+:10F60000901DE99F66B523D17EAE0B47683E03D8B7
+:10F61000910AC6EF9CAF1D791FE234AD8FAE373132
+:10F62000CE47D9AD03F3C9589FB083A2563925DF21
+:10F630008596714B6C645586DFDB9F0FEDED5C2288
+:10F64000BE07F042EF4FE33C918E597AA782EDED71
+:10F65000EFE85DE8FBE077F9C47BF185ACD0F23EE2
+:10F66000B858374B051FDBFB91713EB8CEFC438C7D
+:10F67000D76F7D3571BC497CF6087CDAF1978D8FA8
+:10F68000DCCD84F1B7FA36C6745C6765643FBDD7DC
+:10F69000CBE7617A7FA64DECA5929FFF28E250361A
+:10F6A000A4713ECF167CBD7D1FBFF7990DEB16CF21
+:10F6B000F7F2E4FB342DFCFEA8E4E7B488F5FEA9DC
+:10F6C0005C070176C83F07DA2FAFD7C47B2D563EC3
+:10F6D00095743AF5B98BF4869E3227BDA769E7E7A2
+:10F6E00034D641FCFE2DE0F70E80BDA7F372E7286B
+:10F6F0007E3E44F6A39D3E2C233217CBB75DCBFD57
+:10F70000064FFA443C96A0D7B6518CEEDBDAE551B1
+:10F71000D730F248D26F9B12F955DE00F6B99D7EC4
+:10F720005F96DCEACA8C6FC03CCC77327FFFDB2A65
+:10F73000AFD21685154700E5CA648AEB9CEF4BE70C
+:10F74000FABA4D8E497AAF71F37676F975A9CF2062
+:10F75000FA4BFA6D6F07F9857165ADCB7C3361FCAF
+:10F76000BA1695A1FC003BDC87F1463D7A07E95FBC
+:10F77000CFB7077D616F9F9DD9D394EBCB31F177E4
+:10F7800097D807BA9BB85FACBBA9CE976B2AFF830B
+:10F790008FC721F43063EB259C37AD7635B3DA990A
+:10F7A000AC1EECECF43E3B7B58BB53F0ADB43BFFDE
+:10F7B000517BBAE702EDE980387FB2CFABABC7B877
+:10F7C0006A06D06DF91A9DEC947EF6745CCC2B3EE3
+:10F7D000C8BC741E2F00F506B4A7190B913D619F9C
+:10F7E000CFB233558D68FFAC68B19EF30D6A47B751
+:10F7F0006A163BBA8EB56BA4F79F61EC00E4DB5A46
+:10F8000052B7929FA43E97CC0549D749C2EE68C330
+:10F810000E47A35FE7F6463C17BF41F863EB2FE5C1
+:10F82000EF3A77EE73915DD6D9AC51BE32AEC515C5
+:10F83000187F99F44FEB5C8F947187BDEF8E015C5C
+:10F84000E8D7EB6EBDC6F2CE6B14EB69FDD725FE93
+:10F85000DDD70ED3BB632363CA80EF93A4F939DCF1
+:10F860009F1EFD8BC2F9EF6BB46E96097E4B6F3E07
+:10F8700041EFA9AD2E5119DA6D2399D188EF388F58
+:10F880005C6CDB57C47A5B29703A9245EE25FE1614
+:10F89000EF80C9B8F6EEF81D29A8276449F95A6D1A
+:10F8A0007DFF6BE9E3567D61A4EDFE7EB6E03BBBD8
+:10F8B0007C7D429E0F09BC901E9E8BA9552E0CA6E6
+:10F8C000FFAD5278FD379287D1FFF60D8CC7874484
+:10F8D000BBC1F4BF0F50DE1AEC9FA6FF7D9029DF5D
+:10F8E000B91A5AFFDB92EC94EF72123D979EAFFE6D
+:10F8F000D77461FADF8A56D0FF9421F4BF9D5CFF74
+:10F90000EB1E4EFF7B68E16CFA73B342FF33C74DC9
+:10F9100099F5BEDEB8A96F86DCFAD0715317A4FF43
+:10F920007D22E2CF245DD788F598DD3EB0FEF78DCD
+:10F93000E4FFBBF4BFE792ADFA845DFFAB147CFC3F
+:10F94000A5E97FF543EB7F127F52FFDB73EF131BBB
+:10F950006379B8CEF248FFEB1A46FF7B4FDC7BCED3
+:10F96000F3DBF4BF168DF4A45EFDAFF5EFD3FF9685
+:10F97000B669642F0FA6FF7D80FA5FC9F0FADF6ACF
+:10F98000D4FF82A8FF8DA7B8AFC1F5BF768A0393D5
+:10F99000FADFFF4A3E3FFD6F387BF4CBD6FFFE0F08
+:10F9A00059CD09A4008000001F8B08000000000052
+:10F9B000000BED7D097854C7956EDDBEBD686935D5
+:10F9C000575BAB2584B85AB00408D30261C0C14369
+:10F9D0000B642C088B58ECE08CC3D7422C02897C3A
+:10F9E00022F19699BCA70B92B02C24D132622C1C28
+:10F9F000CCB48870C41827CA32134826F35A8678C4
+:10FA0000EC2476F042269E386F5A0B02644D1ECECF
+:10FA1000D819BE0909EF9CAABA52DFDBDDEA16E06D
+:10FA20000CDFCB93BFE452B7EAD67AEA9CFF9C3A4C
+:10FA300075BAA7AE80F8F209F9BB3A27F15908392F
+:10FA40005DB788A60F67F6BE1A574CC8279B48912A
+:10FA50002213D29FE9DD8F69A59C149D24F4CF5A0F
+:10FA6000721FBC17E05F909FBAC925985208F9C26F
+:10FA7000D345F34578D53AC50E2F09B11003F115DA
+:10FA800010F2C79BF087656FDC2404BE73C7B0EF2C
+:10FA9000FE92D412021F54F82B56937B09F91F5380
+:10FAA00064F6DD072BAF62FAB0F2DD549715CA5E3B
+:10FAB00087EFA1CADDD83294B7F7082EAF957584C9
+:10FAC00040BB1649EA6A86FAAFF75FF6D643DA9882
+:10FAD000642F12A1AAE229064216409962C148E0A9
+:10FAE000FB38FE0976E7E65242460577F11468CF07
+:10FAF0002879889BD6E722E509F81DA1FDB0C5D776
+:10FB00003E590EEF7F2129B624CC7F3CC980F56C8D
+:10FB10008F65F5B82481969B9245C88542786174BB
+:10FB2000DB08941BEEA8B41148BF6372B72D86FEA4
+:10FB30005C7E43749E80FE0C5BCBA724158EB7BF02
+:10FB40008E7FAFA65FAD2374FEB19C04F52C33CA43
+:10FB5000467CAAF9EA73798C48E7958E05FE37DC76
+:10FB6000B9710AF61FBF27F9E3E59679734BB11F08
+:10FB7000CB89B301EBD17FD7688401E3BA6E8AF7F2
+:10FB80009E1482DBD916B7EC4109FA77D14CAA7AD8
+:10FB90000B83F377F2FE13975196605D7189715D67
+:10FBA0004DB8AEB984D457C152E7E2CBC7A4E1D96E
+:10FBB00034DF70139EEF2CABFD22CEEBB004F311BB
+:10FBC00030BE27C2CD0794930A27311F31ACBCBE8B
+:10FBD0005C50BDBC9C7E9E5C92ACE987BE7EE2F030
+:10FBE0009B914EBE6835F65B6C903E63BAE68FE142
+:10FBF000F939F8FFC6213F9437C0886F02BDBEBBFC
+:10FC00007AB911D7A794BFA7E5B2C7CBD1B4189CD6
+:10FC10005E29114ABF2A3D441C0F2FB7DCE88C6EC9
+:10FC20009E8C51CE93F1D6E629D2FEE909DA3F1235
+:10FC3000DD37FDB87FAC91F7CF8C4481CECF5DBC72
+:10FC40007F5E09DC3FC4E131AF07BA11133AEC150E
+:10FC5000565C5F8366FED427E9067A52DB017AAAF6
+:10FC6000E67470D039CF26433D8399A40CEB7B50CA
+:10FC7000B4EE3D07EDFFD6B52419D837295958936E
+:10FC80003508F526279A69BD92E83E1E0FF9E4571C
+:10FC90001682FD1BEE73E707EEB79FAAFB97287647
+:10FCA000C322286F21B5BD940FFA048303F86A9527
+:10FCB00040AC31E3E3FDA96466FC9478EC980FABAB
+:10FCC00026E077FA724019D61258E762CE0F8A39C9
+:10FCD0007F27178C03B84F5CF01F8E6B2EE7FF76E3
+:10FCE00022387DB0CE35EF894E2F144BDBCCCAA91C
+:10FCF000F5CD7D5DA4FBCC425A3E126DF85D407E91
+:10FD0000F6B8BCB0E8DEA7E13FA0DE9DC556AF0F58
+:10FD1000D24F7FF0D19CF301F5B6C83EF354C86FC3
+:10FD2000D94C9C28E7761EDB2B201D5C921252904A
+:10FD30005FC1DA17E23E847976FA709EA17F38CFF0
+:10FD400052AE2FC600DF492F8B9202F58EDC78DE93
+:10FD5000560EEB71D56F29C3F9FBCFBA6B73CECFBB
+:10FD600020E49B404F4678F6D6C510A38990EFD487
+:10FD70004934FDBD3A074DFF439D4C9F67400EE35C
+:10FD8000F307208731FF1F410E63FA9FEA5C34EDD1
+:10FD9000AB2BA36992C8E8458A2FCF72423B7D47BF
+:10FDA0003EB7E52BD08FFE12ABD302FDEF3FEB9EAB
+:10FDB0003ED17E867536B175F39970DD5A97C5557B
+:10FDC0007943F175BEAF3E6F75AF2D81D20329FB2C
+:10FDD000CD824C82F8BC0545B9887CBE9CAEE3A5BB
+:10FDE000AAE4B647B01C2995860BC6F97DF8FE1823
+:10FDF000C97000BF7B0E696F02B9EB0ECB375C9404
+:10FE00006F7448127D3FA430FE11AE9EEA58D6FFB3
+:10FE100060F9EDA1DF15F27AAE9EE67C288CBCEA93
+:10FE20000EC77FFEC4F2AA27021F4E32C98902D034
+:10FE3000C96F3B45A208E3FC0EF0D8CD9BB09E5B9A
+:10FE4000B1606E70BB7F83ED5AC6D3694D0C77E904
+:10FE5000CBFD3091CDE327AFFF8740A8FC5B4A7113
+:10FE6000DE2ED60562EF7EBB0CF7E1EE6203910554
+:10FE7000DC97CE03D8EFB4CD06AD5CE5F8701BDFA0
+:10FE8000A369A4FCD062243685507E92C5EB1BF694
+:10FE90007C39D105E3CF42BE82F2F769D8F7504FE3
+:10FEA0000CFC877CA5B2C734E00FA8378D18070279
+:10FEB000E5EE74CE2FA6EBF8457F82CCF81B9F179A
+:10FEC0003B9F17BB0EC7B60B6433EEF3C3994C1EB2
+:10FED000A9F8B40AFB0A74FC5F895A1C739CAF9F93
+:10FEE0009ACEF2869EC79FF0EFDAD39D6FE4C17C75
+:10FEF00029174527E2EDB8A29447B7417AC415E720
+:10FF0000A4FB90F7CFC2FBD76A506CCBB3C7DBF131
+:10FF100002BFC1E709E037B87EDDC06F30FD12F0E7
+:10FF20001B7CF64489FB67F530FE99526AF78AD04C
+:10FF3000B5112E77880EFFEB71BE91CB1F753D6B0F
+:10FF4000C2E07D956F7F6193DF6482FCC3BD1CEFCF
+:10FF500037983472E20B4F6BD73385EC7BAB0EFADC
+:10FF6000B5F5B4287BB3B15EED3A12B95CC07EB78B
+:10FF70001F15C80B90FED0FFCF12F26BC569242766
+:10FF8000B383E5843191AD7B4AD3FA7DE9F8D22180
+:10FF9000A5A39CBE5B7157A4FDAED2E376C2E8D1A7
+:10FFA000DE119DBEB42A31A2BEB42A3184BEB42A69
+:10FFB00091A8EB4DE9B292B73BBD25349D7F596DB9
+:10FFC000C75D40F9F1137C2DB03E4C53BA463A4F11
+:10FFD000AB7504CEA74ADFFAEF545C00EB3AEC674E
+:10FFE0007287201D6619FD027E3FFD691D9F111F4E
+:10FFF000A3FC2FDCFCEB71C2E5442D1E50BF57E77C
+:020000021000EC
+:10000000D9CDC7ABAF47C501C82726A2A320FEA004
+:10001000C0BC158ECFE755BECFF5F337BD1B069993
+:1000200001B2ABFD6C9392877CA281E2C32BB84FE7
+:10003000D9FA50BED92DF0E9E5FBB19FCBD117938A
+:10004000D83E9DCEF7E5E10691E2B0E9C0770C30ED
+:10005000FF792A7FF530FEA9EEC7D4722D3E53F703
+:10006000710AE9939603FFA8E9011C2707F3577566
+:100070009D466E00C78072574BCDDEFD42F07E4C30
+:10008000253E09F377C27E45DC76D5FFCFE6A9CCC5
+:10009000FEE03C2907AF0F71D4BE968EFBFD61C90F
+:1000A000D90CF9D392B4EBD59E4EE8B8F4FCD41F2A
+:1000B000819FAAEBD72E94FF3C2F3BF2FADD29BE9D
+:1000C000EB477B4B4AF4F61663A29DD243387B8BF9
+:1000D0002A4FF5FCF770A2ACB5B77880FF1622AEB8
+:1000E000FC7E961FE827DFDC7BDC8EEBF0AFB1E413
+:1000F00004D4271C7F9DBE1FFD087066003DAFB372
+:1001000067AB7A818DEB0536C49772BA919085847E
+:10011000984D176A91EF5C2EB612C4CB976F3CB521
+:10012000159583CA633104D7BFF2FAE7B65065A1CB
+:10013000C342F973B767EB054C5F39260A28778607
+:10014000AC5A7E77F958A5E4867E3666D76E41DCD8
+:10015000BD2CA6E8BC04F517744B948F954AEB4B65
+:1001600013213DEB344BF759D97E2974BCFD2AB2DB
+:10017000AA7BE58F9625C1D35990780E9FF39C45B5
+:10018000CB9391ED2D5A7F0E9FAF627B50FE3ED7F1
+:10019000DEE5296CEAB2CAE7E0C3FFCE6CE8575649
+:1001A00093409A21F5CDA66F9B912FCF7DA59D3EC3
+:1001B0007BBBF799112F3ABBFAE8B3E8DB5DF4F9A2
+:1001C000DD9E0A9A0FEB2112953FC2DFFCA3253476
+:1001D0007F5BCBDEF94BA0A1ED9D16D900E31F1686
+:1001E0000C3EC46B4AAB48F54AC923B830BDB34591
+:1001F0003C61A1F95F5A81F4AEBC2210DC0F83B0E0
+:10020000BE09D0AFE32F885E9C5FE9B440907EB614
+:1002100076B2F2D54DED141FE39F1148E58B9CCECD
+:10022000179E3BBCF67EF8EEC31F1B7AF7E32089CE
+:1002300051E1FBD080F4F3C54ED115CBEC1B0AC3C2
+:10024000574DFB6EC254CE3D635402E571914F9BF6
+:100250009EFFBA36FDA160A07869C105EDFB85BFA0
+:10026000D4A67F94C0E50261EDC5C50802B6573239
+:10027000DE2FCA1F7E043207E9A168EE9A37713D6E
+:10028000C8FF329019300FFFC6D7ADBFFC0B59B075
+:1002900015C867E74E9B5F59185E0FA88C569F687C
+:1002A000617AC03AC88A49A24F1F3EFFC5EC4A583E
+:1002B0008074DD2C3A4F40DEBAC78A64E49739C8AF
+:1002C0002AE7417AF567CB705F5D2A7FF11CF2D394
+:1002D000B8820B55B80F1615C71111E99CD4E6E08A
+:1002E0007E5C422E88B81E679328F3237F41AED1EF
+:1002F000F42F57C553795DD199DD65A1F622B71961
+:10030000E9B002EAEF65F646F3E639B43F0AA1FD2B
+:10031000F22FFF0A3E3389EB616CBF73FD2A6C7FBD
+:10032000DDA63D74BFAF5B24CFA3CFB283E5023C13
+:100330007794819C9F82E96F4BEC7D9F84FD7FC108
+:10034000BAF5403AF2E78238A701C755F636CD87AD
+:10035000F2062C7F75DB369AAF2C8A73E2BC57AF5E
+:1003600016EEC1F735AB853C565F3F2DBF6BB590A0
+:1003700023CFC5F447B4DE3592FB67C86E57AFFC98
+:10038000BA11D7E7E223D507908E2F2F8E9B87FBDC
+:10039000F483A41C3AFEB86F7D244F8572BBBABBB0
+:1003A000E4ADA8C72D67EBB783D7B7D1484A8D30E6
+:1003B000CED5843D09617698D70A1C5DCD304F3B80
+:1003C0003AD977649C6ECC37B142FCB71DB54EA4C8
+:1003D000706847042A8325DE934A5CA5C0AFE20C0F
+:1003E0005E9AAE4C7DEAD986C5400F06C877127278
+:1003F00004F31D98CFD2297FFBC3E6F38B314DA8C0
+:10040000FCF5A6FECB2A05D6A38DA70979F4B3C8BF
+:1004100047D5FC6F1C79E0B3983F653129C7753328
+:100420001246F7D04585F269A813F9423CEFD796FA
+:100430005466678987FE7A92E87B5702AC673C7402
+:10044000DC3E8FBE57A6CCA3EF7D56FE34E113C42D
+:100450008D1DE7A390D51F47142FEE1F52E06E4568
+:1004600079DA705494707E40F1B5216E236EC586A2
+:10047000F474A86F572BD2F15597D1190BEB30E5D7
+:10048000E8E1B5487720F8A419507E9BDF65C67572
+:10049000AAEE117AB18BC346EF6B1950DF684B8916
+:1004A000AC40FA73A933E8BA55FA3D6B711DAA7BCB
+:1004B000C41401C6551DE34E40FEB2EE909082E595
+:1004C000463D253617E5435EDB62FCBE1DFA431050
+:1004D000DF0854AFA07C11DBF588274E32CC221BFD
+:1004E000715EF0DF401AF1802767021D7D98CCF421
+:1004F000EE2B994A16D245BCF7FB4F213D0FF1EF89
+:10050000416E7A4FAA9807BE4F1118BF4BF188AEC3
+:1005100099504E4E66FBBDDACFCA57760B5ED44B70
+:10052000E3CBB5FC083AB2C206F9574E811E01F37F
+:1005300052D9B25E40B973C5A464A1FCBB92CDF49C
+:10054000C0003AE3765CC96681F15575276623CE13
+:10055000CE4F667C6D574BD19BC5D8DEE3C4294393
+:100560007D553D156D380FD50E93D3055F5DC67E65
+:10057000E2BEEA1268FFE35D4605ED5EC3318CBE64
+:100580002F7B852ED4DF47855A1BDA459539A0CFBE
+:1005900060730A399F771F9B3A3A055EC187FB2D2E
+:1005A00085E33718D750205E9B166487065254F5B2
+:1005B0005DE8D7EE4DDAF2768E0FEC24E03D7CF765
+:1005C000B3CEFA7328EE3726B37D5B7D5A482C856F
+:1005D0004E2CEE10E7E1343426BA1330DDF86C6EA1
+:1005E000523DA46DC96C1F9BD3DFA378E027C5855E
+:1005F0000694EF6653ED564C9B5F2C30E0F85E306E
+:10060000BB3BD6235F78C140F92A74EA09A4CF1511
+:1006100047930D482F8DD96EDB459C8F745312E69E
+:100620000FAE140E48C01736BBDB1FB4A7A0992A23
+:1006300091CAFDF854662F1B34C9CB285D3C0BF8DA
+:10064000319B92925205FB24A72C7B3F8ECB76FFE9
+:10065000A2952EC8CF596B20D89F7530C618D84F99
+:1006600079091B0C3827F7986A33907E36A530FE3F
+:100670009CF3C143AF0B28176FFC4721EEA30D3944
+:10068000B53B705C53F79C4F7C08EB7936AF889E86
+:1006900083192FC4485AFA30DC5C48E75836ABF36C
+:1006A0006DA0F3AA307C4DFA705E5BFFC0708D1EAA
+:1006B00067FE86D33DF0D55902F0D977F78B945E6B
+:1006C000864B042FE2B3F26E41417C0D352DA8C05C
+:1006D000FD7C322D09E76BCD129386AECBBB9FB963
+:1006E00020DE8B38426EC7F551DE1029AE5EED304C
+:1006F0002981EB8EF6429CCF5DDD89F31057938202
+:10070000807A7282E9BEA6BB9FDA7F6A5CFA7AF4CD
+:10071000FB23425A21EFE5D951DF65F4F83AE06A4C
+:1007200004E7CB396E2D23EDA549B8BF36136A2FE8
+:100730005E491423A6773E06381FCAEFF402470C21
+:10074000DCC75613A5DB18AEBFE8CF59EC8F69E9BB
+:100750003D0BE9DD46F190669FE417E51EB2C0F758
+:1007600062CCD7CB8792C7D7A59EDB83FEA64E2946
+:10077000477B6D675D137D7E8BEFFB34D1F5CD64D8
+:10078000D48F8D4E07D2CBA0A9BCBC04F779A3406F
+:10079000E75DD53FAAF978E91FA477E233808F514E
+:1007A000FB5236B6FF126D3FED74451FCAE1349817
+:1007B0000764F3E9DE7D349DEE9629FDA76D86FE84
+:1007C000048C2BDD0DFD0A3CBF480C4D679B535834
+:1007D000BF557CADCF77A4B07D95DB6420AE80FAA9
+:1007E0006778E2882BA0FEFCCE244D7AA6374353CF
+:1007F0007E764F8E267F4EEF2C4DFEDC33F334E9B0
+:1008000022DFFD9AF2F35F5FA6492FB8B04A537E0C
+:10081000E12F3768D28BFD9FD794FFCC95AD9AFC22
+:1008200007AEEDD6E42FBDFE254DBA84FCB5A67CFF
+:10083000D2CAD229280F2E82B84639BF3FE1E5033C
+:100840000AD0414632C38D20E8E93E57E57A243B81
+:10085000AC7ABEAD9FEF203B6C0FB30FE8CB25A465
+:10086000466787AD19B3C32A07D0BE14CE0E5B1DF1
+:10087000C90E7B7A623B6C55AF49632788D60EFB65
+:1008800054B21C951D963CA6B503BD740DB00BF279
+:10089000338789CACF973ADF2943FEB862C132CA8B
+:1008A000D7D579B2C3FCFBE68FA7573C6A28473BF4
+:1008B000D58A6C772CDA09636427AEE8181F9E2C62
+:1008C000FFCEE4EBB05BC7A707553EDDA3E5D3231E
+:1008D000A7C2F0E91EC6A707A3E4D3BB7B189F7E7F
+:1008E000E09A16C72CBDAE4D6711DF818CEC3BC181
+:1008F000A75D1743F169957FAA7C7A2BE7D36572D0
+:10090000BB11E721CD23906468FF0F686F4F1DE78F
+:10091000EBDB9AB47CBB86D3812A5FBF56F36A6C4B
+:100920007E807C1D2072DB4C9C974E03D583613EFC
+:10093000B390BFAAEB7A9EE3BC6EE28A9B89FCD699
+:10094000CBE64FBF6F7E97C2CAE5745552FBD97094
+:10095000935886FBEB50DF4CDBFD50FFA0679911ED
+:1009600055C541541C20BDC35BD2BD0F3EF95E8A04
+:1009700089F6EFA2D97B90EAE32F88F249364DE65B
+:100980000D683F26CC0E37D2D59E856AC16067A51B
+:100990002D07EA7D2285C9F1814ED60E31CAF49C1D
+:1009A000FB6AD7FC64A403B55F4FA688B45F578881
+:1009B000BB6D51001EA6FB2F878CE1BE6944FD1B59
+:1009C0005B1FE126AC4366A7A858605EB3508F87D3
+:1009D000E7B46E8B0FE73940CFA7FB0DCAD1F3D533
+:1009E000697C1F4F25DEBE627CFFB8562E4EED801F
+:1009F00072F07D468DF63DE1F851E2747085B0737A
+:100A000082CF5CD19693F87E977438F2149FFF6181
+:100A1000F810E9A3E634E0F1ECE0F10E777CF7356D
+:100A2000C4E3535B05D6967EBC5E91E2E52C2FB302
+:100A30005B8C987ACD483741E3F5B2714C3BCD7071
+:100A4000B27E9CFAF155F69A8602F78FBEFF034DEF
+:100A5000953637E51332D5A7BA9B36D1F5543A44CB
+:100A60006A97B8BF93EDFFFB3D862EE4BB9F21BD87
+:100A7000F5880B07F093FB711DEF6D76517B16A186
+:100A800072E4F5646BB3B284EA6536D49F063D0622
+:100A900082F437D0399FEA57035E4142FDEA07DE10
+:100AA0007D549FD2D3B33AFF83DE7A4A6FEAFB7359
+:100AB000EA3C7B19DD0D7BE7DB7203F2CF737A1B17
+:100AC000244ADBE210F3AF9F6FD200F4671FA73F09
+:100AD000FDFCEBE75DA52F75FE6F97CE06F9FE8A4C
+:100AE00096CE5EE6FB4E3FAE2B5794B5540FAB014E
+:100AF000812D87A0AB16BE8F5AD83E0A1A9791D97E
+:100B000085A01CDD47FAF1801E49ED36FAF1EC1A9A
+:100B1000F51D402340CD6993B6FF41FD26745DFA73
+:100B2000DA9FC9F217A25D56D1D9651751BBECA067
+:100B3000CE2EBB22353ABBEC28DA6551AF44BB2C34
+:100B4000E27D6E97DD75FDA12D4C1F67FE23637658
+:100B5000D95E5140FBD5D6145973FE3DDACBECB2C9
+:100B60003EC43F0BD04E2527A1DD5C3D27A9C02EFA
+:100B7000A01C6FE0E71BF837C179D4EF9319CE9C26
+:100B8000E03CEAF7C90B82CFA37E8F46DC0591F1EA
+:100B9000D636DE9F8878CB13FA1CAB2C95D1931EEA
+:100BA0006F6DE7FDB477E8CFBD6B27C45BBBF83949
+:100BB0006958BCD50D78CB1A1E6FEDECB935BC5514
+:100BC000C8D73122DE4A65EBEA7530FA51D7B5064F
+:100BD000CBA31ED51BDD39E3CCD488EB3A3335C427
+:100BE000BACE4C65EBDAF0C0C717D0303FD4293A03
+:100BF00071BE863CCBA99C965A0509EB4FE4B8E13F
+:100C0000B2E0DB42286E7151BEACB7A75D4F62E522
+:100C1000109FA3DD4CB5AB05D9E760EFECBF6FDCEF
+:100C20006EA8E603486CA7F9BCBD5F403913EAE340
+:100C30000DA2771FFDCE45F5BD68EB837F7A305F4F
+:100C4000C0FA52597DC694F1FA1AD2159B2937443D
+:100C50007D507CBF3D647D5ECCFF05E41B03FB251E
+:100C600043BFE6603B5C4FD9AC507BE0E4FD6E9C3B
+:100C7000D42EAEDAC90715E6F71AD43FC83E107A6B
+:100C8000FE68BE92CAC64B2477821068A72C97E8EC
+:100C9000BA455B9F01F3B343D4C3ED9D63E32D538A
+:100CA00034F5C2DB7D6ABD86D0F5D2796CE7F437C6
+:100CB000D9FE7C4DF79D5DED27D1E269751E863723
+:100CC00027DBCC949F68E927496D4FF7DD71FE5D06
+:100CD00083E06E5B208CCFDB8958A6BF9C2892B244
+:100CE0003604F0AF3F72FDA43F91D92D169E63F8F4
+:100CF000E46A57FE89FDB4FE3FD27D8DF019F78F6F
+:100D00006267E5FD05B5664CCFF4CA36A00C727576
+:100D10008D7933EEF7AB82C145ED6B5D962EB4AFA6
+:100D2000419A507F8B7DE2094CABFAD21E3E3F28A0
+:100D3000ABA614D3739313C897AFA0FD04FA392060
+:100D4000496667403F779231BD45C4F9DAC3D33075
+:100D5000CFBE9BDC2E82E7597B38BFDA0372057168
+:100D6000C79EF1EF287F2BF01A357ACEEC1EAD3EF0
+:100D700034A7579B9EECF956A473AD57EC9CDF71DA
+:100D8000BBD67442989D47F60BB8BED3B9FE93D537
+:100D9000C4F043D657F5F841EF27CC7090CCEB590F
+:100DA000ECD79697399F977538A271A69BDACB87B7
+:100DB00063D97C473A378DE7FD8EF6DC746169852F
+:100DC000486DD011F4F256A3BB19F5B15687A95856
+:100DD00061454A63217F75B120A1FEAAEAE73F7B06
+:100DE0007147CB4AF9CEEBE7EB393DAFE1DF893014
+:100DF0006BF85EAF5747D2A323E9C7BF2D1B127410
+:100E0000B879527AB4DEDE59ADB377EE407B27A4D1
+:100E1000779C8E67675B6ABF2669EF44C2C4C9725C
+:100E2000B05763FAFBB4D2C74B7385603BA8A3B439
+:100E300089FA714C2B33509CEE78DCA8D18F62324A
+:100E4000B578F6552BC30DB071A97EBE2689F16128
+:100E5000154744C269AA1F53449CD611DA2E76D690
+:100E60001EDA2EB693CFB7FDD8DBD44EE48ED23F38
+:100E7000B122925DAC21827FA2726BFE89B25DD6F7
+:100E8000F85985C36991E4C5592E8FC6FC193CDC1D
+:100E90009FC1B39EFA23CC3D92CDFC19B87F03B914
+:100EA00040DEC5F3BE815E2827A35FC35EFA7EE104
+:100EB000B9F93F457BF3E82981A0FFC0FC5302F557
+:100EC0005B701F13BD68A71EC573FF00BF07D50E5B
+:100ED0002929824BA0FE1FCC3F01CAADC860F67025
+:100EE0006A3FB91CE35CE1807A8E3F272065A2FF50
+:100EF00003F567A86A82F202B6BBDC8CE5078F882F
+:100F000064BFCCEA0CF46B181436507D4EF9B1A1D5
+:100F100017ED3D417E0D4D4C8FBB5DBF86487CFF7C
+:100F200037A9D1F933FC06D723757CDD6C61F081DC
+:100F30008A0B111F180D28EF953611F907C7E1AA82
+:100F40003E63F744A75F6D51E552781CBEC51E0293
+:100F5000876FB133FAB1D59302C4953BC538E789A1
+:100F60006CB4870F391D90FEB8213F07EDADC96BFA
+:100F7000364DD90AFD98EFE07883CB79C75CE24320
+:100F80003EDEDF904BCF339BEB98FF94E5FA6CA2EB
+:100F900080206981B402FBDA92596BC1769B8B7316
+:100FA0006C32DA4B1AC4329403D2C2D35979F0FCB2
+:100FB000CF5F3F43F31FCD34D1FA472A008F140689
+:100FC000FBB57BD359FEB319AC1F7BAC12F76B3F5B
+:100FD00061A6DBC3659471FCF4DF3265BD7E01EF71
+:100FE0002F9172464FDF3BBCF62FE9CCA87EED6E09
+:100FF00072333E98CFA84FBD5F3BFD53CF01A09108
+:10100000F845310ADA75615F2C0DD417E3FDCF5C2A
+:1010100040BEFA71D9E366945BF192910C04F0D171
+:101020009D1D820FF10DE0223250C0DB43FB93D1B6
+:10103000F9D622A477AB81FAB72574C2BE01F9298B
+:101040009EDCD8B448C67B285B853418B7A971E309
+:1010500002AC9718BD0770FF5C4C62FE72490972C2
+:101060003BF2BF2FBF6DA2FE59250B0BA99DA1EF2F
+:10107000BE59C7E3D13EFD7E2CC17D57B2F0F4715D
+:101080003CD71E78DF42D34DB04E6E98AC03F0F4DF
+:10109000C2FA0DF4B9E7A27E7B04D20333E07F6F7E
+:1010A000B817B2F34FF5BE886240FBC31133F3A704
+:1010B0001FDD04826C0A9DF43496DFCB9F17E87D18
+:1010C00014DC38ECE94EC3E7FAAC6C7E5FE51A4DF0
+:1010D0008FDED81883F534DE10A91DE83C9E4BA1A5
+:1010E0003D63D13D944F00A569FCFD952CA6AF6FE3
+:1010F000147D6FA15D8DFCAD48CFCF3F3936FFE742
+:101100008B6973EC9CF960572E3D67BE52BEE6CDED
+:1011100064481FFEAA6CC0EA76940907D0FFE40475
+:10112000A7D76EF4F7B3A07F9FC4FDFB1CDCBF8F75
+:10113000F9FB9D467F3F0BDE0371D2742FFAFB59FA
+:10114000F01E888BA6BF575746D3FF50574ED36724
+:10115000EA36D3E70FEADCF4F98F755534FF9FEADE
+:101160006A69DA57F7344D1F9ACAC6B1FCD9D2560C
+:10117000C451BB3C22C1FB1FF900AE90FFEE5E6480
+:10118000F6229DED76303F1E521843FD74D65E70F8
+:10119000376563BA47988F69FFAFC9193C9FD8BDBF
+:1011A00049A4F8BDB2D0DC8576C581078533028CB1
+:1011B000B3D223663D8D80AED048BF274EF938A606
+:1011C000DB4A3639717E4E986431B908E8E66B3FE8
+:1011D00059133313E8D54CEA939C909E4A9432A05D
+:1011E000CFF9C51FEDFE0EA4DF7DE16C6B0CD27D47
+:1011F00049F1ABC934BDAB35261BCFD7972550DF9E
+:10120000176557EB79781E14FCC604CCCFE83D98DF
+:1012100002F56DC641DC8FE91953EAF3B0FF84DAB9
+:1012200047E71DDFD5AA00749825012E95B0FDB3C0
+:10123000B4BE4207E053E778FA5E19706A40BEB365
+:1012400000F02AA4672A675BCBA06A97BBE4CD3C79
+:10125000287F34FD3B079BE4E0F6DECBB9D667413F
+:101260003F843642EF9FD964C64F6D4ABEB75E08D1
+:10127000BFFFDB4CFECE4AFCAED142BFEB473D2C5C
+:1012800040AF499CC6F8EEFF4C67F2A12D96D57B86
+:10129000F9618317F9A8BEBE1F4EE7E512593DA0BC
+:1012A000E03D4AFDC236D90DC8D7DF2BAF8C43BA1B
+:1012B000ADEFCC31205FF7A731FA78BB34779A19BC
+:1012C000D6FBFB0D1619ED75974A05AF09D6BB3F46
+:1012D0005BDE4FFD4CB83FC43D26C584F6C47B049D
+:1012E000C1A920DD7F40BC2658FF4BDEC30FE2FBC7
+:1012F000CB46C1896C6C6D3ADB7F0B8F89FD26E094
+:10130000436B1795BCB90AF28B4F1B69BB2FA73EE5
+:10131000B400FD329423A213B63FF971AA858EEB77
+:10132000E5930BBDCCDF8D9FC334843E87A94E6708
+:10133000FC39A7F1EBF41C66C46AA0FCFE505FFA0E
+:101340005B7271F0394C450F3B87B9672AE3EF17A1
+:10135000CDD2013C1F500E88323D0F327ACD1B405A
+:101360000FEE57EDE10D5FA77CAFDF934FFD7E776A
+:10137000F77465A1FC70F176EB1BD4F31867D922E2
+:10138000E47BCF6ACF635CE9E690F6E388E7300D53
+:10139000DC2EDEC0ECE2D37A2CA1CF611AF8B9C4FE
+:1013A0001D3A871920DE7A3A1FDB08950BD1DAC97E
+:1013B0007F9526703EAB1D677F4D29F5D39DDA05DD
+:1013C000B3A7C5956C9C4D7C9C4D61ECFFDC2F292F
+:1013D000B389F55F3FAE7E0430C5E3FE58C1F6F237
+:1013E000726A2FDFDE32F1794C779391D2CDFDE82E
+:1013F000F71BE2DCC5949A62463B755BB6765FAA42
+:10140000CF9EA96CBFFDB9FB375C34CBEDA5B85FAF
+:10141000DF09BD5F57F27D630131EB0DA847B523AE
+:1014200026380D4409A82F5636107720BE76303E58
+:1014300095F8E0A609EF631CE2F2F6592E6FEBB9BE
+:101440007FFD4194B7F06C44790BCF67B8BC6DE574
+:10145000FEF550EF51D4333E7150F591546492E350
+:1014600022A42D780602E349BD8FD15B82225079F8
+:10147000E9961505F51A698956EF8BCB8BD3A48DA8
+:10148000D624E20B1897B53043936F4EC9D1A463AD
+:10149000326769CADB8AE769D2B013A4E1789E8615
+:1014A0008E7EB2BAF4502996AB17B2D0BEE1E7FEF9
+:1014B000452A6EF62BD1E2E6248A9BFB15C6D7A4FB
+:1014C000854B34B8D93B8D9D5F0F86C1CDFF279DDD
+:1014D000E52FCD10F87D50C0CDF2247073D5E1B664
+:1014E00047E8A86E0F37533D171AB1EB70F336DE9D
+:1014F000AE5D879BED7ADCEC01DC7CEF2DE1E62A2A
+:10150000C704B819F0F1DB288746DE34717C5C48EB
+:1015100071F428E0684B76305E1E3D0B0018CA3F20
+:1015200039CBECC5F51BE88334E4FFEE8085A69B40
+:101530004DF2712BCADBF713E8B99E1E5FC36A1B1D
+:10154000193E56F1B41637ABB81BCA19B4389AE134
+:10155000671537EBF1484326E37707D3557D95DDD3
+:1015600077688E65FB231C2E69C86238A63951B591
+:10157000C34D8C4B3E7284C62503884BE646C62578
+:1015800083884B00BF0CB4305C72157109D4BB5119
+:10159000C525DD804BEEBDF3B864F364714937C3F4
+:1015A00025EF67A8FE217A5CE2D1E092A1935D5B12
+:1015B0003264C427C9F4BC7E593A9BA74878645961
+:1015C000BA39A49CBE7BF1C8E4FC424639BDE8C7E9
+:1015D000D7DFB19CE1905641265A3B497438A44567
+:1015E000A0E30D8B43AEB075AC3E161A87EC1CF52C
+:1015F0001E4039B13BC2B97DB438A499FB59A23F12
+:101600006145C0BE3C35EDCFC3CF528D8F11098FE0
+:1016100094F27DF1FFF1C6C478A3C821D37146C20C
+:101620001DDF486376F90122BD857479D6A14D137B
+:101630008742E3DC54A9716EBCDA38376978591AED
+:10164000F98FC349CFB192D572AB8D9A72B1288B05
+:101650001604DFD76A4B93E9F797CA5FCCC27DAD1A
+:10166000DED7D297EBE2E3D197EB3B19EE9EE22F68
+:101670006B719E4716580D2877473E62F70B7EF731
+:10168000628C01ED5B669387F28FD1EE7C9AFECA85
+:1016900054D5AEA4F593E9F6BC4AEF99F77B052A39
+:1016A000A7AAAE5BE8BD2B7382CF9608EDBEE460BF
+:1016B000FD57FD6954FF97BE930BB99F8EF338FA1F
+:1016C00065EAFB3580FD42B987FD2A0EEED710F69C
+:1016D0000BCA3760BF42F8EF747B96BD55877A6CB2
+:1016E0002FF40BCAD560BFACD82F972D11DA3D9CD3
+:1016F000A6EDD79087F54BD577229DFBED4D8BEE70
+:10170000DC6F2F6F477FFED71CE5BDCC7AC7E4EEB8
+:101710006536F0F9D6DFCB7CC1ACB3D33849CCA267
+:1017200079B05E698C6EDE439988F9FB2D14C7D8B9
+:10173000643FF95221C6D3798ECAF3AB61E3E96401
+:10174000660DC2FBF70BD4783A12B587AAF174FA8A
+:10175000319E4E005EFE76BA2AAFA28BA733502090
+:10176000F2F2B7162FC7FD29C5CBD916365E0E315A
+:10177000E3B98C1A2F679B87C5CBF9697A94F1720C
+:101780009E67F1722EDD5848E3E50C7ECAF172F4D3
+:10179000FACC5B056C7D3ECC0F7F0E30517C9BE01C
+:1017A0007380C9C5B7F9773BE397079DFBA95EA690
+:1017B000DED30F47778F6646477724637274B7A2EC
+:1017C00040E4FCEED6E86EF79F3C4E13E85D29C17D
+:1017D000719A3232A2A4BB834077A86F619C26EB3A
+:1017E000A71FA7E9494E67E1E22BED2B60F4174AEA
+:1017F0009F9E90FE82F4E9C9D1DF2607A3BF70F156
+:101800006BAAB16128B7FD1E41E3D719149FE2749A
+:10181000687FC805FCBB70F16BFA31DE02764617B3
+:101820006FA15DB85080CF3B1D472152DC4AF53C8B
+:101830007F909F0FFD55863D64DC4A356E420A2934
+:101840007A03F5B0ED3526D92B8FC751D0C7ABD170
+:10185000C7C7B0FE81C5BBB882F12EB283E3D5A85D
+:10186000FB229594AFC0F39A1DE5CCAFE34A84B850
+:1018700035C4E13E1018F7220A7AF29B909E5CE193
+:10188000E8C92D7C1AF4F4EB19B7464FAFCC1026FB
+:101890008C8774354CFC8E4F8B9EAE4688CBA1D284
+:1018A000D3254E4FE723D3D34ABC27B0E316E969CB
+:1018B00028223DB9E9F99F9BD3D350447A62F25D67
+:1018C000A5A728E4A3969E82CFC927454FAA7CB43A
+:1018D000010D69F1DBC4E77087FA4EAD453BDE00D0
+:1018E000DE9380BCFA9E5C7A4FA2BE41900418D76A
+:1018F0000F1A1243DE9350ED2F03687709A0BFBC87
+:10190000A98CEE46B8FD65A421D796ABC90F730E1E
+:101910004422DC8FD0D95DC2DE8F68B833F723262E
+:101920006B6F499F1AC6DE7245A2FE3435783F823E
+:10193000048F33A2BD45BD1F11C6DE42482DD533ED
+:1019400083ED2C4E6A678974FF66CCCED2A3BD6747
+:10195000534F7A45EA973A4AC8DF0BA8376D684378
+:101960003FF1FE8E5C6A1754D7F31AF74FE9C60AA7
+:1019700033D0DEB7B105EF715EC918D387DBEEFF58
+:1019800014E86C6F043ADBFBFF289DEDE0E30E47A3
+:101990006761EFE1DC369DF942DEC3A9413A837904
+:1019A000AF8CD69E778B74F66FFC5C5EA5B3EAA312
+:1019B0006F1C443A5B3095F943AA7466035A5F94EE
+:1019C00044F556DF52E47B7603BD37AAF2C3DCAFA1
+:1019D000126A0751F5D870F778AAF01E0FB55B3C74
+:1019E000CFEEF1746BE32BF5F37B3CAA1D43F5C7F7
+:1019F00054ED186ABD433C6ED3108FDB54C3EF0720
+:101A0000D560BDC521EAF5B0B84DAA1D42AD57B5A8
+:101A100043D862587C0562F45339E65F4C9CE8A7D2
+:101A2000AF8ECFD6647621DD50524F62E5511EE86D
+:101A3000E5807ADE51C5ED587AB950ED254A2CC6BD
+:101A4000A5891194D8B990E6F7532E75919EE42993
+:101A500088FB04FA7C3783D93B2EB55AE83998BF06
+:101A60008B9C4984F743B1C299C4B9E3F9FE760B64
+:101A70005DB7B5CFEF6AC5786B7ABFE613B1CCAF6F
+:101A8000F972BAA918FB77A2C89DB521801FFC3B4B
+:101A9000A7FBE144E607A7FADD0FBC927F02D74916
+:101AA000F5BB3772DC742D8F958F27AE36432E1918
+:101AB000F36BA67EABD0A58144766E372018581CF8
+:101AC000E25798FFFD00FADF63BA9DC75191B3E971
+:101AD0007D80212BEBEF41EE77FFE198DFBDD3EC6A
+:101AE0000CE8673CD1FADDAB7EF87ABF7BDA8F5C1D
+:101AF0008C4B25B8F8F9DA5DE5773F6D063FCFFAF4
+:101B00006FF6BBD7FBC3B71A890FD7AB758940E314
+:101B100075119DFFFB6B9D1FD7E06BD50FFE1B2F33
+:101B2000BE9689FBE64EFBC19F9AC9F891FEDEF98D
+:101B3000DDEE07BF1BFDE0E510713F7A3E1D3FF86B
+:101B4000C61BA28BDEBF7F9CC5159AAC3F7CA3EF62
+:101B5000FDB25C946B99D94E540DF4FEF1C6F1734D
+:101B60002E4D1C28B209E8E6BE71BA894F5976D5C8
+:101B700068A3FB939E63ABEDE3CE1C0898C791145A
+:101B8000D22402DF325E67F4A3AFA7AF6763593692
+:101B90008CE7B7C7989DA45AAA7D0B0DB7C62641FE
+:101BA00036427D254D02A5CFEDDD8217EDE7C6EB70
+:101BB000665ACFF6EE7637BDFF9E17436205E67F85
+:101BC000306002F8C1E39E34F3B827492BB751BD0A
+:101BD000F463AFD08BF2AF2A4531E3B988492232A2
+:101BE000C6413349DAB8245505CA6BC8AFE20A5971
+:101BF000BECAF7E30BB4F14A729ACCC4953C1E6F8F
+:101C000063E55123C569E3F7D6BC36AA7FEAE2CC87
+:101C10003F912984F99D86641E675E5A8B7ABD1AAE
+:101C200067BEDFAA8DF3FC736E2F54D36A7C562CEB
+:101C3000379938CFFD0D61E2CCF7E496623F6E2311
+:101C4000CEFC5F65A686FF9D861FF1FE4FF6771AD4
+:101C5000C6EF8F393572ECB54C46AF833A3976F51D
+:101C600094568EA971B73ECFDBBFA4BF3FB69EC9C5
+:101C7000AFB1FB63A7407E0901F7C78E68EF8FA95C
+:101C80007CEC92557B7F6C84DB1FF4724C7F7F4C25
+:101C9000E57F7A3936768F82CB313BB9BBE4D833D6
+:101CA000F977C7FDB1E69912F547EA8F65F3BDE410
+:101CB000DA85E5882756E565D3785F7F71FDDA39E7
+:101CC0004C9765B2F4D7F2395FBBCBEF83FD9CDB59
+:101CD0002D23DD075B59A04D3F244F2E7ECA9D96D4
+:101CE000836E9D1CACE072B042B9BBEF833538C641
+:101CF000E223D1FB60E37C468B97374E0B8D9787B1
+:101D00004E69EFA9C673BC5CC0F9CCA08ECF0CCDD8
+:101D1000617C6648C5C99CCF0CA938B955CB6754BE
+:101D2000F93B1896CFF826E4332A7ED6F3195A2FBA
+:101D3000F099F85EC6670270F65DC1671EBE4BF88B
+:101D40004C1BF2196BF47CE6AF67DC1A9F5967F500
+:101D500019E9B916E72FAE0EF7732BA1FC1A8748C5
+:101D6000EDCA2B1EDD40711279209EDE7F08C16F07
+:101D7000FE7517D24711F3F39F2CDFC999111DFE91
+:101D8000BEDBF88E3EEEDE2E7E0F7597F7EEE63B5D
+:101D90007BD318DFF19B088DDF190E376EE3F6FB5E
+:101DA00060DCE8A378B12293D533EA49A6F10E2688
+:101DB0006B07F84D18BE367A24B41DE0DD995ABE83
+:101DC000A6EAF3A389ECFEFDA88A9F8E30BE36AA50
+:101DD000E2A7D6D0F849CFD72E8DF135CFEDE1A7C8
+:101DE000EEBB133F915977AD1D80AE7BAB93D9010C
+:101DF000F4FC47D5FB3FED7875BF93A3C33FB76BAA
+:101E000007C822F2A1D2ECC8E5A28D2BA7DA01C641
+:101E1000E2CA750A346685CAAF76F4DC5E1C503DB2
+:101E20003F7AA8F89D9252C3EDF3217DDCC8D2A37E
+:101E300007A91EFBF607496B303E30FA21A39FB27B
+:101E40005E9F7B97DF5F5DC6FDAED5FEABBF339770
+:101E5000B63A796DB14CEF934FEA77E6726264431C
+:101E6000AD95DE3BE67667AE0FFF6F167F57B5CBBD
+:101E7000E6C45CEB437FF69C16E2AC27C1F6D620A5
+:101E80003F2C6B747E58EF54B816A09FF860A3489F
+:101E9000EF910F6613DF52C465A906CA4F0762852A
+:101EA0009EDCB9841CB86776567F809E7DE0D9FCA5
+:101EB000AC01C4092D02FF5D1AC9FC4840FCBF8A71
+:101EC0002CB3466FEFDFCCFDA9A11C8D7F6D94E88C
+:101ED000EFB10D24303EBCF199BD4F627CA5580393
+:101EE00071233F9CCDEDAFFA67F2D32F970F05EC2E
+:101EF000C7E4D52EB33B01FDA1D63B9480F6F5CFC8
+:101F000046859D9334DE38EC467AADCAABB2238E5B
+:101F1000ADF2C5523EB0E358C54B6857999DC7FD19
+:101F2000C274769B9DFCFEC34E7EDF61C76A27F5B7
+:101F300083D9C9ED42C9DC4EB35377FF416F1F4AC5
+:101F400047879BD4F17B0563EB8B0592503EFA3BB0
+:101F50000DE2ADC7BB1FE4F1EE5BCD6CBD5B9F3303
+:101F6000D0FB0DF9061F8D6BFF3CBFC7FB00F18B4B
+:101F700044BDE701E5963608F49EBA1AF77E7B83E6
+:101F8000E0453FC9ED18EFDECAD66B73C204F1EE2F
+:101F90001BD6AFC2FE848B775F81F1E9E7868A7733
+:101FA0009FB402EFAD5F5D12437FF7448D775F8191
+:101FB000F1EEE762BCFB149AAFC6BBDFA6C6BB1F3F
+:101FC0008B9F1F6DBCFBA934AE811AEFFE57B96C15
+:101FD0001EE20E77154C95C7E3DD07F0C309E3D683
+:101FE0001F9CA5C6A5F7D2F4929E8A430DE9E37122
+:101FF000EBF7CCD6C6AD5F50F8CC1116B79EA59FB7
+:102000007BF1A523E7D3C7E3D46F7AB9EF61E4434B
+:10201000D1C6A95FC8FD22EF789CFA4651423A200A
+:102020002E0FC539C4EDA5F19BD438F5C36A9CFACF
+:10203000C64A7AFE3A16A7DE53F21AC6CBAAEA15AA
+:10204000681FAB7AD79B713FFF2C7706A5EFEDABEE
+:10205000DD2C3EBD574CC1F3DAEA18772B9ED3AD89
+:102060007B9EC5A7EF077C87F6BCF138F50A8DB3D8
+:10207000AEC6A91FE671EAB7737A0D1BA7BE83C56A
+:10208000A97F2397C9D5914C167727BEF3FB4F61E3
+:10209000DCF068E3D47F92C5F84DF56A567E7B6725
+:1020A000B838F56E1AA77EA48BC5A9DFDED14FEF35
+:1020B000158C98BC14E78E6433FE162C773D36E4FD
+:1020C000D7BB3B13B3F1FCED06972B3B3A589CFA78
+:1020D0006A8C530FA5767B05CA9F7677085E97803A
+:1020E00071D5247A0EAEA49BA83F8E1AA7BE1F05F9
+:1020F0002BD27787D0857826629CFA0E760FE3562E
+:10210000E3D4579DD1FA05848D53DF507F0EE3AFA2
+:10211000164CCF6171797B789CFA1616A7BE99C7C9
+:10212000A96FBE5371EA1B930D68B76ACE966C1700
+:1021300053C6E3D45F0A13A7FE5A2EC3A79722C63D
+:10214000A9DFCCE2D43F32719CFA41E42B0BC6E309
+:10215000D4E379D3527ADE349BF2E170F1EAF5B838
+:10216000710C4F46C08F6B389DEFD0C53BEEC778E2
+:10217000C7905FDEA98D773C7C344CBCE34E16EFF4
+:10218000B85FE0F74E23C43BDED119655CFACE3F61
+:102190006D5CFA4FEB7CEA4EC5A59F95CBF8CAA5BE
+:1021A0005B8C43BF5B60E9A0F8F33DFBFAF0DC27F2
+:1021B000DAF8F3CD61E2CF3F95C3EF1586893F3F53
+:1021C00027EFCFE35ED464E3CFAB7AC46DE0361182
+:1021D0007F6636D2EF14BD359DF117FDEF146D6F9C
+:1021E000507FA788E1EBBB0DB755DF21DCF62EE76A
+:1021F000AF71DFBA35DC66CCD3E2B6FFCAFD830629
+:10220000B775E76971DBE84396E702715BD2EC656D
+:10221000CF05FEFED0C1EEDD1B26F3FB429FE4326C
+:10222000DCF67F01DA7E2DB8008000001F8B0800ED
+:1022300000000000000BED7D0F7854D5B5EF3E7324
+:10224000CE4C2661984CFE4F20843349800426648E
+:102250004212088A388108C1A28EE895E845EFF05D
+:102260003F406CE3AD7F687BDFE54002061AE20485
+:10227000A3C68ABC09061B7B910ED55AEABDF5257B
+:10228000883C6A5153159FB5B45F120549CCFB1EBB
+:102290005A7DCDFD4AEB5B6BEF7D92396766321359
+:1022A000C0DBDAEF854F4FF6D9FBECBDD7DA6BAF69
+:1022B000F55B6BAF7332C14C882F99900984B827B6
+:1022C000CE81AB44483A5ECD44499C43EF7759F800
+:1022D000D588573BE94A87F6C42929BDF9842410DB
+:1022E000C5FFA501CAF9DEBD8652421A768AB63DFF
+:1022F0000294DD3EABA710AE5EBFD533919047BAD6
+:1023000037ED2D4B25E4BC5B72C5CB8424EE5C7BA2
+:102310003381F6A445B04D7310B2AED76DCA84FABE
+:102320002D7E2140A0BE4F524E4E82FAA1D60A59B0
+:102330008166C773A7119246C8FA5E2F7D6E8B5FC8
+:102340004C15E0B92D66EFDE6BE0B95B9E1052B123
+:10235000DD90AFC2EA76C22F44B1CE87FB432D3069
+:102360001F289D27425500EEAFC72AB84F7CE2C117
+:1023700043384F4264692ED085BFE7C0B55570170A
+:102380005809F91FB9021D6F30CB9BEDB1C0FDB6E6
+:102390009F3D24C0FD8FF8F38A87F8F9F384C0F3DA
+:1023A000A9F87B2E5C7DA2BB6036B04766CF6FE993
+:1023B00065EDD7B7097EBC35C1C3F8863F5FD2FF54
+:1023C0007B9758A17EB05D203F00BAD7B7160B5E51
+:1023D00098E7A0D19F6D8371071DA43A40E981E77A
+:1023E000CCFC3911FFEFB3C6C1739BDB921C7B8021
+:1023F0000F25322C4219211B5A8BDF28453EDE4F18
+:102400005CD01DD9EC8741815F9B5B05BF1B7EFDC6
+:1024100058B0DD5C0E6525D3E83A04F513DC921262
+:102420000774F599891BE7F971ABD0AE407F434241
+:102430001DE59F52289143949DE444DE5CC63ACA50
+:102440008256A18B009DA9BDAB97132BA5EBA39141
+:10245000F9C17F530894553A1DF462413EA5538E4D
+:102460001352B33CA81EFE4B3FBB6C00FB4B2741F5
+:10247000FDC073A71BEA5F9D04BFFF939C43F9B99E
+:10248000B95348AA8449CC6F12E7201B9A93BC1316
+:102490002B819EE6DDB9C9F5D0AF35A5EE415C2FA5
+:1024A00053E6BB7538D9D74B9D0611E83619EBD6E4
+:1024B00060D9F474BE4181F20F4CDED65B91DE1F11
+:1024C000185C0799183C80F2B964678A610FF4D3ED
+:1024D000ECB059CF40BF1F671A93B1FEDC32619751
+:1024E000AD88906A6FCB0DE9D0CE2D25158BD06EBF
+:1024F0007A1EE3FB39A3BC88CAC56EE23AE4A0A207
+:10250000A4D4C03EC9A972EC40BAACD7542F7343CF
+:102510007DCE1D0682F3B9056834C37ECA9BB8C25E
+:10252000803C996EAC9B84F29399E7A074E69C5D25
+:102530007A0AE56DAFE4A95E0DF3D8BB60964B81D6
+:10254000F156E4D46D40FA26DF7B226929F6B73BC9
+:10255000AF988AC3A87C18BE9C07EDFF5C778FC735
+:1025600049792D9B54BE1B287FA9FCB909E946FE79
+:10257000A6E50874FE1B970B3305A0EF9D1D229561
+:1025800097BE0AC17F10EA3DFB05459C8D0FBBCB72
+:102590005623BF9ECE48C6FD74D302A3468E3DFB94
+:1025A0001FEE11518E04B905D743F9A5E83A04F39B
+:1025B0005D6E372AC172013546E4DFC6FD4973906E
+:1025C000CF243FA89F9C5039AFDDDF27E0BC6BDDF7
+:1025D000FA7EF4FB214A5921EFE601131673F93B09
+:1025E000B50D2AE3A08CF20BF4559196CA64DC2752
+:1025F000D5C4E587FA654491B0BC6515717541791C
+:102600004B2768C0E0F12D462AA7B86DF8BC47E516
+:1026100019C64B5FA5DD0FD928DFC09F6CDDBEF862
+:1026200038953422DF45F3339E8F526051F6BF6AEE
+:102630002981713FDB2FB9E260DC7A01D61FE56AA0
+:10264000671CE5E797F873FDE8F5F16D8A4702D559
+:10265000D8B6AD915E2F3A98DEE9BB8E74E13A6E42
+:1026600004BDB3036E55ECBFD55301E5DA06C105D1
+:102670006493DAB616933C11E5D6B704F5ACD22EC6
+:1026800004709FD776ED3E69443EAC2232EAE9CD34
+:10269000D57E9309CAE95E42E56CF33A9FB006E441
+:1026A0002AA31AC60DA22FD30BE307C9437312C87E
+:1026B0009F2574BED739D87E697684AF4F9DC9EA0D
+:1026C000731B0DC41DD4FF345F027107F53FA32DAA
+:1026D00059532EF04FD2B49FD599A3A92F0CCCD427
+:1026E000D4171D9BA32917775DA3695F726A91A612
+:1026F0005CD673A3A6FDBCF75768CAF37BEFD2B4D0
+:10270000BFF6C21A4DFD7517376BEAAF1FFE674D56
+:10271000B9827C4FD33E79596522DA8133262880ED
+:10272000025CF6A4D4A400BF928D729200F2F0591C
+:10273000A348504FF737DE96E885FBE412F00FF61A
+:10274000F966EC400C272760C0E346CB199D82DB7D
+:10275000EF0C6D27717DF0C5A93F0884CAF5F5D44B
+:10276000BEADE3FB26DDE76841FD5B7B4AA4F66571
+:10277000AF5427A09CED6D1288CF817261205DC19E
+:10278000F6EDD297F4F92D9CB60CE279A41CED81FC
+:10279000422C15E9B81FD84FFFE16F27B9818E6C25
+:1027A0006E4FC856A91FF78919FEE1FE5A1B30F675
+:1027B00007EB9B0C22F507EFA3A9DC7E4CC5FB4180
+:1027C000F643E50BD57FB97865F3FB0BD20BA4DE9E
+:1027D00044989E10A1576CAFD757D75DD4DAEBEB76
+:1027E00087F5F67B9C7A485F56DC67C2E925427A1A
+:1027F00005C44F7ABD5425B748C8EF8C3681A4086C
+:10280000A3FA2B3B5BA6FB5ED5331B505F05CDB314
+:102810009FC8CD05A847DA0C04F508E8F36CC46539
+:10282000EABABF25B375EF20EE8402D4071D22C596
+:10283000077AF9F82DD72F39879EB1CA884F1AC564
+:102840002A94A347BA0B6EBE069E3BE75B24C5C322
+:1028500073E70047A23DDCD851D1B11D1E79D2618A
+:10286000A4FD9F31F97F9589FDFF4894B1FF41C2D6
+:102870007087D2211C44BB79AEF3196B0EF477FE3E
+:10288000D0F67B26C13CEFE2E3F577B271882437BE
+:1028900023DE3B7FA82405ED873AAF7F7488B4DD43
+:1028A00000F1379733BC41711D95AF1C32825FA692
+:1028B00010F567641D842F81DF599DA212877CEC7F
+:1028C00014DDF1709DD21647F14D76F07A3968BB70
+:1028D0003EC44B53B89C4E26FEEE52BC7FBF56DF23
+:1028E0004F6E8276F0FCA45AED7DC271908DAFF7E9
+:1028F000002C69C082FA42DBCEC6E5D9A6C343CD1F
+:102900009C1F831708B5D3B5AD0C57EAE91D6CBA07
+:10291000EDA415EA273F2F109B1C86DE0E4E6F0795
+:10292000A3F782D163427D1C426F07A797E33D3D29
+:102930009D7AFAB6048C5A3A74F3EF6F7CC6EAA516
+:102940007856A6FE414763295D4FA54924D3609E72
+:10295000D77432FC718DCFD08E745D4B02F58883B5
+:10296000FBF1916BF07FED3ED413CD0E567E474EBA
+:10297000784CC942F97BEE66ECE79CCF4050FEFAFA
+:102980003B6FA37E427F8760433FE1E58E16EA17E7
+:10299000E8E559E5FFB98E47A9DCA9F73B1D6C3F77
+:1029A0000C7680DCA19C77DC66CD0DB257CFA1BC44
+:1029B00021EE23BEE66BC2F05FCF6FD200F2973EEE
+:1029C0002A7F7AFEEBF9AECA97CAFF2B95B373E361
+:1029D00094331F97333D5D03177C6FA2FF505B2B31
+:1029E000112A567AB96AE574B546A00BF482399972
+:1029F000B6A374E9E9017FC88472A1A767C35060D8
+:102A0000177146972FB441B82EDD2D3FCBEE85F6DA
+:102A1000334C8103E988833E8827078124E1407590
+:102A2000762FAEF7A7DEA9B6A0F54CC971707A7DF6
+:102A300056831DAF3D564339109F09139E87FE43B1
+:102A40000FF527064B2D04FD87C14B0F517FA26662
+:102A5000BF99EC80476B8697DE43FD595F1C41BFF1
+:102A6000B0C3B7A607CB039DA280787FA943A6FD7C
+:102A7000ABE30D76AEB5E13EC810DD9F3ACA62C742
+:102A80006B224CA73C393A6E13CDCF523C1909BF8B
+:102A9000FD4A66F38986E3C830CC379DFBCD886B51
+:102AA000C13FC6FD407F80FE389BAD1DFDFDE1BEF0
+:102AB0008FFDF5509692D3A95F2422CE437E960ACD
+:102AC000121ADF04FE884AFF90E015916EC9E623D2
+:102AD00014BF8019407B24F2F53BE7B0D1ABDFCEC9
+:102AE000F83F827B1A18EEE96BD0E29E1AEC22378F
+:102AF00006DCE367F3D7B75BC8FD7D3DEED9C0E7E1
+:102B00009DDEC6FCE85A37D3B71944A6386833E0CF
+:102B100020F40F62C03DB784C33D7D87DFA9A2F6D4
+:102B2000BCCC400C8EC8F867B30EFFA8FE5A241C1C
+:102B3000A4FA6D23FEDC7708F5E7A2E123BD9F1719
+:102B4000829722FA7D5DD46F519E96AE8ADFD79729
+:102B500076F26426F9FAF97DAA3F17C9FFEBDE9FEA
+:102B60009B887A49EF07AA72A8FA817ABFAE1E6DD8
+:102B70000CD8BB8BED77FB1467743CD73A95C973BF
+:102B8000343C97967B7978EE9D1C237D6EBC78AEA5
+:102B900095FB17D1F0DC6339CCBEFEBDE3B9539C85
+:102BA0001F7AFA069BEAEF413E4E7E4C9089230C39
+:102BB0007DD1F0838AD73AC2DB59153F6E380CFAC3
+:102BC000CC1106C70D75517B5BDB66D4C4E9AE3E04
+:102BD0009E5BD882B80C6398E8E7B6FDF7F47DCA2F
+:102BE00082AB8FE7FA73386E8E80E73ECC61FEC30E
+:102BF000DF2B9E7B3D676C3CB705F19C1C46CEAE3F
+:102C000018CF7585C573B543DE5D4011C8DFD87830
+:102C1000EE75E43DC5733FA4B86D86C97F80DA9137
+:102C20002878EE48AE83EFABB1F1DC10C773431CDC
+:102C3000CF6D403C07E50D88E7E839810ECF0518D8
+:102C40009EDB9E236BF0DC506004CFCDCAA5F16003
+:102C50000FC56FCA4E81DA4315B7A9F6760B5F47E9
+:102C6000FA03E58D94E3A3E5CD022BAB382EE3F018
+:102C7000EA6ED4B31960A7F0B825B3737B379E977B
+:102C8000647A658AB77C53654A6FAC786E13FE8EA2
+:102C900078AE23363C97931315CFE5E484C173399E
+:102CA0007CFDBE6AFC16F89AE1B70D88DF12C7C03A
+:102CB0006F6D80DFAC978FDFCE3F19237E6B03FCF7
+:102CC000363B76FCB6A12D36FCB6A1ADDB84EBFB22
+:102CD000D7C26F1B397EDB7895E2F664AB9C88F235
+:102CE0007CB9B86D666ED72318BF9D9A6BA372AA84
+:102CF000FA3597BB1FEFCA6571F231F6E35DB9692A
+:102D0000A1FBF12E9411B83F5D66F320123B1F9A90
+:102D1000804DA0CB86EB3EEF590CE37CD420BAF07B
+:102D2000D647BEC5CD88036D8F09361C770A1A8930
+:102D3000323C47ECBA87D0F57253BBFF7FB299BFE4
+:102D400036DEFECE6787EFCFBA989DE3AD5E2EE408
+:102D5000C8B04F6E9348A504FA733961D741D47750
+:102D6000CC9EB9717F9CCCB7B7238658DDD02EAFEF
+:102D7000B1447FFE053E6EA4E7553EAEC8E9A9A268
+:102D8000B877AE81DA1BFD391B8972BEF654EDF1BE
+:102D9000F81941E7747BFF4C28CEB929F7D02318E6
+:102DA000B75A4DE4643CF2DB93C4EE13E5DA16F750
+:102DB00082503C34C1AC3DA797B8FF8E7CC6F378F7
+:102DC000F5BC5EE2E303090AEE7702B66FC75CBCAE
+:102DD000CFE6A7D69B0869C17A0B5FCFF7A01DC6C7
+:102DE0000FFA3A44FF76FA9CDB8EF2126B7FF0AB5F
+:102DF0000FEB27F279617F52EA687F0D997EAB5124
+:102E00000CD31F34DF911EB63F3FD6BF07F552F0FB
+:102E1000BC649857218EC3E5B7DA4FE5E5AB5EAFEA
+:102E2000B4836E1FAE83BA5ECD496C5F13E580CF6D
+:102E30009D151A8FCCCCE0FB81B8CA681EC4AA7C51
+:102E4000030EFA00D72DCF5E24241171B2DD48F3B2
+:102E5000089E6D7B9BDA9125658BE8F9B04A4F7A25
+:102E60009B48BA4A46CB4BEE3478503F2C7178E3FE
+:102E70000DF0BC5976E109D1E879EF38E9FDB73CAE
+:102E800021ECF9EF85CB3CFFBD30CEF3DF68E72BBB
+:102E900057EFFC37FC398BDE8EAC433B4246EDC826
+:102EA0001A6E47D6F8B4E729E3B52368C87011EC69
+:102EB000ECD6885D595AFA7645A521D4AED82B1B9D
+:102EC0003F457E4EA932507FC07EBF365FC29CA573
+:102ED000C5CD450848D2C2EC2F10C35DE1F73FAD28
+:102EE000CFC893D93EB279270AA541F93B1E9F3539
+:102EF00078FF4337DBD5FE0CE1F73FDDAF4ADEF864
+:102F0000E661C07A4798F179FED0C83EAFF26BE631
+:102F100093AE3EA75B67959EBEEA47AD26BA2E5A92
+:102F20003D96ACCE47F75C2B3E07FBA041B03597F2
+:102F30003942E98F958E164E7FB4735A7A9E1A0BDA
+:102F4000DEF585C7BB7D79E1F1EE262E5FE91DBF79
+:102F5000667AB0D440D0BFCF205DBBD03FFAAACEB6
+:102F6000676BF71BFB83E531D6F3D90A55FEA29CAC
+:102F7000D3465BBF769DDC5923C8876A9F503E24A9
+:102F8000C42782BF59444CC471987A7E9EDE191BB7
+:102F90000E3B9617D52F3A9617C62F3A86F3A5F60D
+:102FA000A1F7ED5920F7D9FB05827AF5C8FE761313
+:102FB0000A5BD173B7D26BA075B509E330AE271D9C
+:102FC000B45CBCBB825E498F6B02FA83FD7EF61C4B
+:102FD000F04FC475ACE5E397B41FA5CFD90E1F35EC
+:102FE0004D86766BF70B32E693CC7B55EC42B91CE1
+:102FF0007A5EF4E3B9C59030E724FA91CA6302CD52
+:10300000F3B2B50A6EDC879B0F8B07E368FD8A5D20
+:10301000F49CE14991C6193F015E2640F9C01EF1BA
+:10302000A0C2E272444A1FF5DFE6BDBAB6793ED4CB
+:103030000FBE6608EC80F6358D217103035D3F3FBE
+:10304000B31F66D2B81DF3078B8E69F57E7197B6F4
+:103050005C724A5B1E140C342FAEAC477B7FDEFBE8
+:10306000DAF2EF26F3F5216CBC04B320E07815C149
+:1030700072E1C07624263FF54AF32B0E4C0BBF6F4E
+:10308000A9FF0FFC4ADFCFF22BD6F3FC8A0C1018F5
+:10309000B4A7EBEE27FE2E21F2FE5D6B66CF47F460
+:1030A000539BDEA1FA209A9FBAAEF5F2F671D43C9A
+:1030B0000B1D5ED0E38265F9DAF252F90AEDBDBE6E
+:1030C0001CD5FEB3F840CD56E2C794C965C447F19C
+:1030D000C0A66A66FF37F9C7E74766C8F755A25A20
+:1030E000891507E8EDFF88DDE738209AFDBF2F83BB
+:1030F000D9C95E23A179A3A178D3DB9084FB3C409E
+:10310000E83900B9D8C3F1A681ECA1F8F3B894026C
+:10311000F54B7EE97621BB54DC59B6E0D7C7936402
+:10312000C49D3BA4648C87FD9CB8C0AD258FCB8C1F
+:103130003FE6FFF0BA88767DC2E24E577EF1E21498
+:1031400019FDAF8B27A87E255A1C9A6F6E398EB158
+:10315000CD99B6A38B105A173B2BEAC19D2673DD80
+:10316000F7A1FB484EB6DD7F02DC38C0BDBDF58956
+:1031700038AE5CECC2755CF6B95F4A84ABBBB5EEA9
+:10318000834DD0F026579C0BD5CBCED4CF9C188F37
+:1031900053F17BCEA163CD88CB553D4FF524CE2393
+:1031A000109B9E2F9A1655CF174D0BA3E78B905966
+:1031B000A8E7F9FE5883552018531BC3EB87C72691
+:1031C00071BFDEAB5D3FCAA9749E1A04F321197565
+:1031D000F6E078E701D43F33429F8B234D547EE2E3
+:1031E00088741EF98DBCC1FD982DF50AF8FCD4AD8C
+:1031F0003A7D22AEA2FA4E3F2FF5BAF5ECA785270D
+:1032000082E4EEF5691353CFA313EA244EBACFF844
+:10321000F32A9F57737AF5FDFC71DBC5C213C09B7F
+:1032200047B33C89B631C653E952CBD90D7CBD3882
+:103230003F0775FDABFC9BDA29D0757FE1D08D7B14
+:1032400015006B09C527E8F9D65016A962F9D46EA6
+:10325000AA1F3BD4982BD7A317E259F117D34D746B
+:10326000BDA7923A2A278FFA455717C8C3D433A26D
+:10327000CB00FCCF53F5A78FE94737D703691E4929
+:10328000A33FE3B8BE4C25DDB6C520B7EB3B441ADF
+:10329000A7D2EB4F759D062EC511CCA31FAC34D120
+:1032A0003C80385DBB34D265C3FAB52E89A03D1889
+:1032B000EC5DB9849EBF7908F5B7F4EB43ECAE93AF
+:1032C000769877CB3FD85C346E375DBB5E2D9984A2
+:1032D000D2A59C61E78309C5A977AE43BFDD9D40B8
+:1032E000F791CAE738CEE716A1271FAF23EBB77CCB
+:1032F000C598F2A2AE9F1FF42D5E0F6EB3513BD95D
+:10330000B1CD4ECBCF6E93E9B5735B3EBDFE689BEE
+:103310008BD61FDE564ECB8F66058E23DEF8E27607
+:1033200052ACC0FCFBB2FC3B1218BDC58718999685
+:103330008AB918BFE4FB82AFE3503C2B9F98944EB0
+:10334000D7314E678FFE91AF6B2A298EBF16E39A55
+:10335000B54619D76535B707A481D9C148EB6AF9D5
+:10336000335BA78F709D1CD89F6E3DF9BAA711EFF4
+:103370002E5C1F2FAC4F17D47DD4FB3F6DE8B72BCD
+:10338000B07E871CA1EB7B6212F777ECC4A459379F
+:10339000BE0E5EBA47417E94F07EC137BE66FA63C8
+:1033A00005CAE3ACC8FA43D5D3574D7F0498DE8DE8
+:1033B000A43FBEA1D31FD73E3B8DEB8F52AA3F3E09
+:1033C0008CA23F06B8DC9DD4EB0FD8F75DA557AEB5
+:1033D0003FD63688343E11497FF4A1FE488DAE3F7A
+:1033E000D6A1FE70A0FE9877D23EA6FE60EFE5A8BB
+:1033F00072D818A3FE1842FD1124B77F2BFA630878
+:10340000F5476A74FDD1CFEDC077A3EB8FDD787EF1
+:10341000BAFE32F5C785A8FAC343F5FB06AE3F2EC8
+:1034200044D11FDF1DD11FA07782D6CD3A81C5C3FD
+:10343000DFB3F9ADC928BFF727D37DBE86CBEB0339
+:1034400059CC2F490487A187E66504ACE83FAECE8E
+:1034500062FD7DD2986245BF33523F1B38BF42FBAD
+:103460005134FD5C684BA1E5687E56A47D1FE26780
+:1034700005C2E3A8A61942D83CF6D1F88883C6292C
+:10348000F57E56CD15FA597B25DB9BE540D7DE55F9
+:10349000928CF216C9CFAAF9AAFC2C32763EFBDF39
+:1034A0008A9FE5453FCB31EA67ADAE66F2BD5AF97A
+:1034B000DBF6B31AEC23E76634DF6A247EC3E3301D
+:1034C00047FCF7D1B84BD1D32C6E136863711B172F
+:1034D000C66DA05CDC722BBDBED05A4CAF6ADC4618
+:1034E000CD0728D9DBCDE23681EE939352E9FB7B01
+:1034F0009AB8CD873C6EF3A170D084F5CA933C6E28
+:10350000D3C6E2361B316E2360FD1A16D7D92DD2F1
+:10351000FA4FCC7233EAA903270D01E00CF64726D7
+:10352000623C7FB748EDC4C7828124B0F6EA7B9144
+:1035300034AE93C2E54C1FBF49E1711DB25CBAA223
+:10354000384EB4F8CDE2291CCF4489DF2CC6449C08
+:10355000B4A0F5F0F1F5F075B378DA5181C5D31464
+:10356000753D587C8CF4D8DE413EF6F3F8DBBC5751
+:103570004B683EDB27C0048C5F951C1228DF37ECBC
+:1035800017FD9887F509C69D2CA3EBB69ECB97CA6D
+:10359000FF9AFD8CFF9F086B9650FEEF1564B4AB4D
+:1035A0001F9B158AC30FEC135032890DE687FCDE92
+:1035B000DCC8E26CF35E5DBC0BE771E1A848769075
+:1035C00051FE67E02F229EAB1CB7224E555E33049E
+:1035D000B03FFD7A64E07AA09E59C5EE7F55EBF1CD
+:1035E00052566CF1B497D0D7C675E3384E8D77A795
+:1035F000FB38FEC29F31FCEDB3D3A3FADB67A7878C
+:10360000F1B7CF4EE7E35EA5F84761569F01D37649
+:1036100096DCB9AF92C63F7E415C98D7F6B8EC6FA6
+:10362000A0F18F2E2F8D43448B7F9494764BE1CE67
+:10363000DF22C53DCA16AC1653A1DF7995AB9B9628
+:103640004179E925A501E31C4B1C3D8B69FC23AFA7
+:1036500098C65D165C2495F130AF1B4B051BCEFB65
+:10366000874F9FCC0A8E7BBC35FDBE663CB7ACB1A4
+:10367000BB4F60BE598D45A2795AC46FBC38B25E4B
+:10368000417AD500FA19F56A65C8FBBB5ABD1B52D1
+:10369000764BB26D2E4F6182791A111FC17AD7D73E
+:1036A00010AF99E6A5ACB221CE17903F707D7B514B
+:1036B000DD371147C0025A717F9D792FD780EBA06B
+:1036C000AE6F5A81A0C9AF3ACE71609F8DE1FD45C2
+:1036D000922C85C3FD8BCDA2C66EF799C7F60F4617
+:1036E000FAE5ED1675E656A27ED829B9E87B568A2A
+:1036F00045203F1522F7BF2E61D1C08CB2D1F7F41F
+:103700007E31E3FA66CCCF6D1108D513E89F509C4B
+:10371000C4F7C1166410F0EBB5990C9F44F4530E36
+:1037200087F7EF1EE3CFB564BA7E991706770F448B
+:10373000C0DD7B0D7EEB62E1EAE3E9999D6C1FA79A
+:1037400056A6FBF1DC7A60C43FD2E26A3D7EEECD44
+:1037500034A971318AABD6735CA5E26A1547AB38E0
+:10376000F8EEDB7B8D46A87FB4F585343C87D2E349
+:103770006BC0E1F4FD890D2F0A34BE72F7566DBEA1
+:10378000951E5F0F5ED2FAEF7A1CDD9F9A7C73055F
+:1037900019F597BC3CDEF2516F9CDB8C7C27663FB1
+:1037A000E26FBDDCD7D7B8B767C2FD8117CB6EBE5D
+:1037B000166E6DB6D5D13C4B23F108766C64B765B7
+:1037C000DE4A7143A5ED7CFEE87E88249F0834CE56
+:1037D00007EDB3FF9D4E58DE87599B0FF246B64C5E
+:1037E000F979A5F92067783F91F24160D4749E4F32
+:1037F00029603EA5EA079772FAE36A046209C24BA0
+:10380000A5AA3FD42369D6EB0B72C9C0F4A140E549
+:103810006773168BBB67546BFDA4A2532CAF54F592
+:103820006F8B22F849FAF5A376939E7F5AFCE8E75E
+:10383000EAFDDA26D94FED6D13E04E94E38DFBEFF0
+:1038400013D08EACCBD7FAB7378816EAB77FF6AE6F
+:1038500048DFC3B1E57699D1FFB27D5FB461DE6820
+:10386000FFA527ACA8C7067AE3683EAEEAD71E815B
+:103870007D86F95F01D8679291909FC03EC3F28B1D
+:10388000B0CFB0FC12EC33BC1E837D86D797619F0E
+:1038900061FD7FC03EC3F22BDBDCB4DCB5AD8A96A4
+:1038A0009D93983DDCBB28E128CDAFDF1767C3A30C
+:1038B000A4EE96A5D9DF81F90D5558E8FC867EAEB9
+:1038C000CD83D55F5D9372B8FD568C6C1DBB8CB8F3
+:1038D0008E91F4550DD757DE8228FA2A425EA6ABA8
+:1038E000606C7DD51F21CEF85FA5AFFAB3581E7569
+:1038F000347DE59A6452CFA935E7E551F5D561D01D
+:1039000057CEC8FAAAB646A0F19C58F555A4B84EB1
+:10391000247D3588FAAA744C7D254C467D5553D6B6
+:103920000CB7A15F0FE5BF571114B4CB6995A6760C
+:103930007C274BB2F94D0C675D9EDEBADDCEF49666
+:103940006D4220DB05FCE87EFE67BFFFEE38E456E3
+:103950002FAFB00F68BED527332E3661CEC9D58ABA
+:103960004B7C55FACDFB15E9B77511F51B8B1FABD9
+:10397000FA6D9D8FE9375210A37E7B02F41BF47B16
+:10398000EED23CAB2728BEF255E9B70F7BE358FED9
+:1039900023D9783BEE17757D7B9FFCE2369A532442
+:1039A000D9DEC44538F39E48827162443C67013CCD
+:1039B00007FD2C061C17134E9462C489D265E3C41C
+:1039C000D9056170A2AAF7689E3AC6F5DBC2EBD1B1
+:1039D000BDF9DC1FFA9AC4F56F2A18FB5C507D9F75
+:1039E00054DFCF65C7F55BB571FD01EC3F37947FC0
+:1039F000533B585C7FEE734B5AC713D757CF937E18
+:103A000093AF8BEB07AE4E5C7F73E3D871FD7E1EE8
+:103A1000D71F8812D7DFC8E3FA03BD3F64793B1193
+:103A2000E3FA752783E3C3F505DA73984871FD73EC
+:103A300051FC0B75FD5A04CF5B98271B6DFDAE96AC
+:103A40005D3F1725AE9F76BB5B30A6A29D2D2E4114
+:103A50007174615CBF2CD4CEEBE3BC7AFBFE7CBE00
+:103A6000CC9EE3EBF76813F347A2E5FB6DD4C9A343
+:103A70007A0D8967EF0FBFFF8D33A3C5B359BE5FC2
+:103A8000CD48BE9F7B17EABF4871ECDAD13876F893
+:103A90007CBFC0B793500F47CC13F25FDEF758845A
+:103AA0002C39A67CBF91385EA740503E8F74B27807
+:103AB0006A11E6C1615CB591C5535D2DDB595CB5FA
+:103AC000FD3E1AD77B613F8BF7A9F1B9B59C9E9259
+:103AD000A347E97DDBE1A3F4BC6B53AB20A3EC8EE1
+:103AE000E4C3ED6571D021611F3B4FD7C555373712
+:103AF000B1B8DE90B086ED2B1E57FD10E3AAA9A148
+:103B000071D5C1DD2C4E3B8871D5D2D0B8AA1AD759
+:103B1000FB6BC5F17E3F25B638DEEF31AE1A14C718
+:103B2000DBA2AED7E1D8E2782F15448DE3BD541067
+:103B3000268EF752018910C7FBDBC89BCF9C25FC62
+:103B4000FFBCF931F2E6D7AE62E7396B7D57F6FE7E
+:103B500055A4739C9D974437E6492AF7B3EF308EFE
+:103B6000377F7E67D76FAA72315E94E5A0DFA3D45A
+:103B70009FF34876417D3F88EA4BF57D26723BC82E
+:103B8000E3DC51799C90BA6840B262BD44FAB5F169
+:103B900052D21FC4C7C154D228829C48C34C2EF5B0
+:103BA000FD7477DE56E540FB017802CF7B36D8BA4C
+:103BB000DE14711F1D166409FAAB382C507F71ADED
+:103BC0004FF0E37981346CA2FDACF5B578F1FE9A43
+:103BD0003C338987FB7BC09EF4039E6EE0EFA1ED32
+:103BE000E1EFA1252FCBDB85FEC0E71D42009775D5
+:103BF00053AACF847ACD682332E216A34DFBDEE8C8
+:103C0000A67CDF49C413094E564F970AE34AF9DAF6
+:103C1000F749731A4DC49D12FA9DB2F1BE37F45E96
+:103C200050DC29DC7B43AABD588DCF63FE5C43F892
+:103C300073DF3FCEF87AE5BFFC64E6D83859CD177C
+:103C4000BC6A38B971ECFC39957F6AFECB533FFAF8
+:103C5000D3A30C27A75A6527E65FA9F192B1F3E732
+:103C600042F25FFE4EF2E72ECC8C2DFF255A5CEB24
+:103C7000AF8593FBA3E4CFE971726F66F8FC173D43
+:103C80008ED4E3E40CC4C969413839C070F2D57AE6
+:103C9000FFEF3DF57D53FEFEDF57FDBECDFDB38446
+:103CA00071BE6FE31DF37D9B2BC5DF1B2EF37D9B48
+:103CB000FC99B2261F3912FE1EF77B64B3E4ABFAFF
+:103CC0001ED932F445AFE27B6423F212EB7B649C95
+:103CD0009EF1BE4776F72CF9AABC477617D21F840F
+:103CE000BBC7FB5ED2F4598668EF874F9F15E6FD90
+:103CF000F0E93ABE47A273339F5FB4F7AD54BBAE51
+:103D00007FDF4AB4907CDCD77692E0C2F8F256B3FB
+:103D100075364904BD18CFAE0F19BC5E94CB87C46D
+:103D200080D981FABDD4DB86F3FDA32160AB80721C
+:103D30007DFAEB1E1C6ED5D6EFB92A0107D952C801
+:103D40003F85FB9EEC2A03F1A2BD7A86EFDFB3C666
+:103D5000AE2949B0AFAE2D5DF4CCACB230EDB7FEBC
+:103D60002BED6FA148EA0261F0C5CB1CF73F65203F
+:103D700035D8EFCA7B7F32F02CE224D93907D994A9
+:103D800090DFB3BC04D6A1F1AD5CFA7DEA9FF0717F
+:103D900081D052E4EF2F5CDEA3C1E39A659BC4F8A7
+:103DA0001F988FF50BFFE43CFA16F4D7F80D0B7D46
+:103DB0003FDE9DEBBAA5244CBC13FA7919F9611EBC
+:103DC000DEF329FA196A3FAFC4F73E45686640C57D
+:103DD0001DEF03967A25A977B200E5E3B31C77A41B
+:103DE000664239AD7732D69F503E7DECC47C2803C5
+:103DF00056C4386BDCE14F1FC378E4C21B879E7941
+:103E000004F31CA69BE87B1EBBF9B9903A6EBE5327
+:103E1000A4F4E43BB57C385D3B361FDE0EE5C3DB26
+:103E2000E1F8F046A9FB1DBC0F93A474376E23AED6
+:103E3000753047774620BE04FD2E39F0DC23D0CD07
+:103E4000A43C858252E8E7B7D8DE3CCCF0BEDA4F1E
+:103E50005EA9FB2CF2E774EDDBCBF1BB16F1A745B5
+:103E60001AB732E7116582953ED71FFC5C854CEE90
+:103E7000177246D7A1BD98C97732CA01F4576FF2BD
+:103E8000D96FC5F841DEE3DFB641FB5D0EA5DA135D
+:103E9000463E7EEB64FB2E09A68CCF35D80E9A8366
+:103EA000BF272038191F8ECC715FC4F99904E2C175
+:103EB000767BCA19BFACA753E6507C9A474A578015
+:103EC000DE4A2D64ED61BEC3B4FD7C1F5522F1793D
+:103ED0008CCE3DCE7D04E397F1F65676CDEB25985A
+:103EE000FF114F02665C67E3F3E4F18672A4C395A9
+:103EF0008F65B9D0F7B804EBDE8E492D80EF2641EF
+:103F000019F3430E802247BF4D9964A2E7447ABA61
+:103F1000089FC7F75DEEF6627CBF35AEF79947A004
+:103F2000FDEE02133D5F5868F055AF41B9B9D1427B
+:103F30007114DCAF0EC6E7655C5ECA9CECBB61BB6E
+:103F4000FFD34CEBF57C8D559EB29C21F294E50C91
+:103F50002F4F539CE1E42931A23C4D738697A7F67D
+:103F6000E2B251B950AF92DD44FD7C6978570FBB86
+:103F70009AFBF0B978B38BE9F52A864BC5E104DAF0
+:103F80004E1C6EA2FEBE64ABA3EB047AF8D42C4A9E
+:103F90008741425CA0EA69D1E2A6F5A7547D1C6185
+:103FA0001C028B8AF64DCADB15769C78731D41B9CD
+:103FB0008771129D638C93E864E32CBCD1E245FBCE
+:103FC000B210F566D0FAFDCE29517A7FCCE53B924E
+:103FD000FC2715B2784F24F91F1E957F0FF2399AEE
+:103FE000FC171432B98175A9A6ED23CA7F07BD2637
+:103FF000E433F94FE0F23FEC244A5539CE97C9FB40
+:1040000046E76E2AEFEA7E985BF894663F14411902
+:10401000DF138B445F32A7CF8AF43951BE4405E3E6
+:10402000497F20850731FE642DB749F87DCD6F3A71
+:10403000D57DEBBED7C9F212A97D6D2717BBE37002
+:104040009F2D10A8BF305109B8CD482FF111CC0BCE
+:1040500079903F77C0C0ECBB329DB0735BC947908D
+:104060001FFA7D1A9FD755EA0D9AA789EF5377A1BA
+:10407000E7BF21BF0E186C096847D5F5D0D3F3010F
+:104080001F6F7D09DBD7D1F4FF41D4FF657865CF81
+:1040900025FFC95C176E1F2FFCE6CB03CF8ED18F97
+:1040A0009FEB8327783FAA9E4E50F574FE889E7E34
+:1040B00082EEC7DA3DAA9E7E11F534ECEB36E46B56
+:1040C000C8BE4E817D2D84DDD77E675AF47D7D1577
+:1040D000F673E358FBAC71649F8DCDE74FB89DFD3F
+:1040E00084F3E972F9FC06E7EF89E87C3E1181CFA1
+:1040F000AF85D59F91F9FC4604FDF926DE1FC31E4E
+:10410000BF4BD74737BE19C775D0FAF783D70FEA29
+:104110003F170C6887088DBB267FCB4AFD43751D72
+:10412000553B7515D77500E71F695D171A188E5A2C
+:104130007A78E5E334FE75E5E3FD74ACF17EEA647C
+:104140007445B3DB09A376FB2FC83FBD1E6CE7DFC8
+:1041500011FCBECB6B2CA4F1CEDE65A8770E7C37AC
+:1041600059C06F1065B9BB04C4CB2A1FBFE7647880
+:104170005E7D2ECBCDDA676D4D16301F2AA8BFC4E9
+:10418000B1FAD3CF03E6975C48F596FB03A4FB0393
+:10419000A70E7F715CD09EACD4A05E960B991D9249
+:1041A000B97D50CB334ADC930B195ECAC6F1FF5080
+:1041B0002ADE6FC8617A99E16CA6878D85AC7F8312
+:1041C000C74FF0FB8109E584FA55A3FAFCEE43AA38
+:1041D0003E5F6FC1F692AACF6760FF530BD5EFFB2E
+:1041E000B0FE22CD732EB71773F93AA86598A78B46
+:1041F000CFB364AC79EAF914EB7CD7727B0DF3BDD5
+:10420000AEB02C727FEA7AE1B32413FFDE0EDB9F9F
+:10421000379FCE9D83FBB36A047F7A96623F15E594
+:10422000C28B2CFE614BC0FE9E3201BD4EFC6ED295
+:10423000BE0A13CCA3FD5F6CFCEFD1F8B763F9A9FC
+:104240007A5B31C6CD56F075D2CBE7C8F3A64041B4
+:104250008993F2E30E1CE7FA050C0F249E66DF0D2E
+:10426000AB20B0DF45DCEF8ADD05F36D1414FB1ADB
+:1042700094FB651696CF6DB99DCE5FDFFF087EC5B6
+:10428000ACFA20B92596D228EDB7D3F6B6094A9DE7
+:10429000673CEDE300375882F998528C7CBCB95CDE
+:1042A00050504F559029EDC8EB07B9BCC2FADC87D6
+:1042B00072402C40ECFC51BE86F6AFD075A8F0D40D
+:1042C00009C8D7F87C180AEEC67B148C451283EC1B
+:1042D00023F85DE1843CC2CEE52CEFD2FE46E751E7
+:1042E00052A29DC775CF049F978164A8F25D4FE5E8
+:1042F00025C6F9E8FD766511D3C7CAEFE3FDF5CC15
+:104300006F7F84D247EAE6D1EF6091BA2276EDA2C0
+:1043100071B0EBB95EBBDE6C61E76597A4A1E0BC50
+:104320007401C4783262B391FCF15EE1CB09318D46
+:104330007B20DCB8B1C60B9E2B0C89173C57384646
+:10434000BCC04A7A151193C46C2C8E8CDB69F21CAC
+:10435000B6EF10B7BDC8F77D62041CF6221F4F955B
+:10436000CF953B17911CB8C699893231995D319F21
+:1043700017F6C7CF0B693B66172B6CE4C554C328EF
+:104380003D2A7D6ABF2779BF23F335315C7FD6484C
+:10439000AA8F5A187D7382E6B3A2B4E264309D2AD4
+:1043A0007DFAF99EDAB6D55509382065EB62F261DF
+:1043B0000AE647796919E7193F87AE9B62A4F9C7F6
+:1043C0003DF7FCB380DFFBF5BE8DFDA6E4FBD6ED2B
+:1043D000033EA5BC18EF0209223DE6DC261788DA69
+:1043E000B78EB173AF58E562BCF2D03DF1C1794CE4
+:1043F0006F3139A8BFA1B83A15358B92B9F234F8AC
+:1044000007F56FB8DEB74079E0F9CC957690FBFA06
+:104410005FBBAAD340C54F3EF2C7C79B60DFD7DF63
+:104420005ADC86ED53FEFDFFA6DF80E53B056AEF13
+:104430008D473257A2BDAFEFD6E2AED17DB293C564
+:10444000C14B3DB38B501E25AF4CC7AF1022B46794
+:104450007A6A2B427BC475C306A6DF4A9369B0F221
+:104460007A7EBE423E4FA2E537394FEADDFDBFC23C
+:10447000F877F78238398EC97FC26CAAF76DA78B9F
+:10448000E0FEBE4506039E3FBF7A5D4613EA55DF58
+:10449000228340FFBED44D6C1EC6D45E71B5257418
+:1044A0001E71A5EE6F623FF5770BD5E1E26141ED3C
+:1044B000BE5184575877FC7B817845B935C2FE15CB
+:1044C0007999CB6FD26CEA3F0AA5A9F4BD109B1471
+:1044D000FCFD3E55AE5479FAE5B4FF958D7807E4BE
+:1044E0002773765AA8BC2C9BFE9BE9CC5EEAE4417C
+:1044F000CFBF107E7D66413BFA56B9182F5842F95E
+:104500000BFC9B81F37CEB12E3ABAF7C06FD0EF75B
+:10451000ABF3E30A7AA99DF214E07CC02E954E1409
+:10452000639A7FF1F8E6EF7ADF8BF3BF64D2ACFFDA
+:10453000CD11D65F9CF8B905E785F4A03D80F92F31
+:10454000C4F1C429BD59A817D479C7AAFF96CD666E
+:10455000F63A48FF2D9B9D1659FFC1BA2EC77AC067
+:10456000319F7F0BC5DCC6704C24BD74E7EC71EB4A
+:10457000A53B678F432F85E1FFEAF1F05F3D2F36C2
+:1045800072764351B6417921FE2ED3F3BCDEB8DCFE
+:1045900051F9168649D7442B9373FC1EF6AEE2629E
+:1045A000B3490CED3756FE7F2794FFDF198BFF3799
+:1045B0008843F4BB389F2D10285DEE61983AD5777B
+:1045C000E04205CD7BA1B989FA2389A0F382CFF11E
+:1045D00093DC66127CFE9F5265D394D33C764DFBF0
+:1045E0008C6A9968BF339DAFA99F5CE3D294A7D42E
+:1045F000956BDA4FDDEAD6941D4A95A67D6EA347EA
+:10460000539EE6ABD6B49FD1E6D5D417F86B34F5FC
+:10461000B33AEB34E5C2C0564DFBA2638AA6BEB8DE
+:10462000AB51535F72CAA72997F5B469DACF7BDF24
+:10463000AFA99FDFDBA9A9BFF6424053BEEEE2312E
+:104640004DFB8564245F47C0F395CF40C0F0DCCAC2
+:10465000532CD0782AC0AB1EFCFB06B711F5C7203F
+:104660004BEA3A1A34CFD373BDDBD473C2E5EC7B8B
+:10467000FD0AFC433BE9D1E5C52C047D8BDFCF77F8
+:10468000BBB4DFF55FC8CF0B17EABEBF5E41721245
+:104690006598D7C25322C1F7B5974791AB50BA0876
+:1046A000CD8FF59C11A9BD278ABB07F38946E91276
+:1046B000C645979A2740C8459A77BDB05C203F1001
+:1046C000C2D0C9E901BC2BE1FE0FA197E70BE8E9D5
+:1046D000D59FFF9F9FCDCFFB5DC4152E5F3E121F60
+:1046E0002A14338DDF55B805FA9EBB7ADE1FC20F40
+:1046F000CC7709C235F1B2761F4EC8D7EEC3892EEA
+:10470000FB987214C25F858C8BBF32FCC379DC824C
+:104710000D609EB70C13FA7E4124FEDE2269F3A6DB
+:1047200062E56B529196AF5F9005B794C8CCCF4BC2
+:104730001D23DF05FC930CC41991EC4A5E91D6CF82
+:104740008CC1AEE41505DBA1F1DB1527CE2756BBE6
+:1047500012ABFE9F5F14A2FFE7178DA1FF47FC8FEE
+:1047600005ECEF0DA876097EDC181FB2DAA7FBF185
+:104770009CF886A2B1FD901B8AF47EC86752B01FD8
+:10478000E28ECB48E071BEE3183755FD928A05C52D
+:10479000B7605ADB711E278A95CE3B42E9BC632C79
+:1047A0003A5FD9CEE202AFBC21D2BFDBFB5AAAD816
+:1047B0009506F4ED2385F47D2EF5DCA2CA4BD8FED8
+:1047C000935A3AD11983F97AB1DF2AB942D864C130
+:1047D000FBF7D16B2439BAB768DCF8E4DEA22BC34F
+:1047E000270F8C478EA2F93B0F8975EF7B8184FAE6
+:1047F0009D8C0FCAEF26D0F8E0C3BBD9DF937E783B
+:104800003BF3575A399DF5FC5AE662F251612DA7E8
+:10481000F873A73091EB398FFD5F919F7613CDC769
+:10482000067EEEC1F99EC89C4BFF9ED11F4EBF6312
+:10483000093E8738CBE97C8FD3F9BB0746E8DC47D4
+:10484000E9AC5E4BFF1EB84AE7DD0FAA7466D9A833
+:104850005E403D017AC1640BD0B8F212D142E96BDF
+:10486000C8237ECCC306495C7E433A4F2D85E78939
+:10487000B8FC14DACF2F9C12FD1B6266F5BD2C9993
+:10488000E5BF34C23FAA5F79FEA8D12E69F2D7E313
+:10489000516FCDA6799C9A7C19B57DBC2EBF46AFD1
+:1048A000CFFEAD88BF3F6122194C9FFD4B23A682EE
+:1048B00010E2B507FB377A7DA6964FF4E666F486DC
+:1048C000D927EA35B1FC426E9E06AF5DD49453AA57
+:1048D0008673F334788DE4059733AACD79C1ED332F
+:1048E000BD364D79728D5DD37E4A9DACA99FBA3598
+:1048F0005F53EF505C9A726E63B9A6FD349F5B53B1
+:104900009ED156A5695FE0F768CAB33AAB35ED0BA7
+:10491000035E4DFD11FC857E1FFFD24ACC8B3A828F
+:104920008933E07FFFE6C7FFB9929ED7F5ADB4D3D8
+:10493000F7B1D2EE3007CBA1FE7A228DC96BA47AF3
+:10494000757F46AAAFE27A6B676AFF9E59A978BE67
+:104950009947CFA3492A8FD30B4C1E2F72BD6630C7
+:10496000B3FC9A21C17B11F58F1ADF57F36DAA8032
+:104970008E6B407F2E93BFE3AA0CA2777BD69A362C
+:1049800094F78761BFA1BC3F4C08FFDE3CA3FF61E9
+:1049900089F163847EA1AE11532C46F994598DF9A7
+:1049A000762A9FFEF2E3F46A8CF7EEEA5B6A47FF31
+:1049B000F04412F001EAFF1FAA04856000800000A5
+:1049C0001F8B080000000000000BC57D0B7C54C548
+:1049D000B9F89C3DFB4AB29B6CDE01026C08685042
+:1049E000C04DB2098104D89080B13C0C2818498090
+:1049F0000D2F7904121075ABF4B210C243C36D7C55
+:104A0000B5A82D77A1D86BABB6A0D8528B98007AF9
+:104A1000415143558C2F4C857A1551A2886E15CB88
+:104A2000FFFBBE99D93D679315ACEDFFC61F4EE65F
+:104A3000CC9C797CEFEF9B6F4E2E5C809F318C5D20
+:104A400088280FADF6B9CA4D8CED5FEDA5F2E0EA0E
+:104A500085AEF2418C3DBFBA81EA871456B5D3C604
+:104A600058859979770E09BF77A5CBC0586AB87C6D
+:104A7000C6E54D701530F6D211F50B2FC31F87B167
+:104A80007268F4790E0F7AA39F17C67B9F79D3F1D2
+:104A9000BD766B76B32B85B1FA3DAACBE264EC9A76
+:104AA000CBDEBCCC0BF35EEE72D0F84D8A7F20CB10
+:104AB000867598FC159543707C0F63698C19159A5F
+:104AC0008C35A58E77CD81FE835CF0A0009FDC4EF7
+:104AD000EDB758797BE4BE65696466D62AFB64311C
+:104AE000A6644DAB62B08E8A5433B340BD4261952B
+:104AF000B8FFC8F77AE1BE619E6B9C3F7695CBF715
+:104B0000E1DF9ACC395B989BB10D19F03E2C65031F
+:104B1000368C847FFE5E551E186783117EEFCDD8DC
+:104B20003F7E9F56E52FC1C64CC70771E27D95B108
+:104B300018DC17ECD36833FBD561503A1A18C2E978
+:104B4000B4E22D4138B14C8311F715CBE48F875572
+:104B5000DAB1F4139C22C7F36107580FB399030F1E
+:104B6000C37E18AE15EA9F1FCADE76A7121D2E1B44
+:104B7000563B328DA6709DB100ED7703D203C1DFA5
+:104B80009531D54EE3338417CBB0D1F8B83DD60B71
+:104B9000FFE7CD9902EDD3057DDC9EEB9942EB77E3
+:104BA000003E47449F57EEE3F6DCCA2A17EEC7E8FB
+:104BB000CDA1FD5DE27BDDCB16410F2EA7164E2960
+:104BC000F07BBB0DC78776D8CF7D36598776282BEB
+:104BD00007B6B04E781EE3E4EDAAC2F795EE0D30AD
+:104BE00033EC37CECD1CF8C880FDA0BF23AEDD630B
+:104BF000C8656CBDABAC2A6330B40FF466185C5466
+:104C0000EF30C27C492AD41D387F59C741C0FB36DA
+:104C1000E6B8428176AB714CC7A1518CC5334E17B3
+:104C20008C8DE9F00CC1765967AD2C07EAB1A1BAB9
+:104C3000C79A01F501A1BA1FEB5B0D9CCED6BBC68E
+:104C400074AC1B82FC58B986E06D6D9D9803EBF542
+:104C50005814C79D4EA483148223AC3816E1111555
+:104C60008EA2DFC5E0BD6DC8138706003DF9338C09
+:104C7000AE4130FE466CD2BCF7B8CB4CFDEC79DED1
+:104C80007B713DF6555D4624C1BB8624D991BFC3D7
+:104C9000780844E081C3BD32274078881D1820BCC5
+:104CA000F4CFF8C25F0AF3F50718E276983389F07B
+:104CB000B22D63A58278D93644E0258719902E63FA
+:104CC0006199E9F0A0D1CC1622DDC6E5304F00F1A4
+:104CD0006561B32BA1FCB5A0CFA75CAA28B9FC489D
+:104CE000C8B88F39A13DA6C240FD134419DEFF3A72
+:104CF000EAF794CB28E88BC3E325B77717EE13F0D8
+:104D0000578172E3C83A03F1DBB67503B6290AE2AC
+:104D1000C1519E03E57FAD66AE7926C2530BF63FC7
+:104D2000E24A8EF572BCEDE9116F629F17C35B34E6
+:104D30007C1D1372375AFBF41BD54ADC9FC1EABDB8
+:104D40007F1ACCBB744F72AE0AF31EAB52DDED502E
+:104D50005FF64C7A2E4088B50BB9576FE84A63F07E
+:104D6000E04EDBF64A2C2D7BEEF6F471A29C72EA43
+:104D7000D651BFB794E4D7DAB8F812C477E43A8EC4
+:104D80009D7F2305E5F9A4BF5B48CE02529D469066
+:104D90006FB30989B4ADD706427D9690F35F08FCE6
+:104DA000BCB6BA8AC699D5593B910D63C4B89D5C0F
+:104DB0000E2B172CF07EB84E729DF94C27B16E85E4
+:104DC000FF2E00EF1C338268857D1DF32B2E801C87
+:104DD000AB354E31E37CB57EDE8FDE837F732A7385
+:104DE000C7233BCCDDA87F3EFF9D6B3E42A69DCFF7
+:104DF0008C273B73C2F3DC50551BD20767E9FF01D8
+:104E00004E1F468FC900747064AAC250EE4EABBCF0
+:104E1000D1559E131EEF8D6FD5D9088763F82EAE3E
+:104E2000ABE6F2ED7EA53B3CC6E4CAFD57929E0E72
+:104E3000C18778E1E27008C1EBFF081EE3D5890461
+:104E400087B95314D28F9170008A9F384EB39FBF99
+:104E5000C87D32D7B13858DF896613C18FB502F1EA
+:104E600014323699BFAADDD7FBB82E07FC87FB8228
+:104E7000419A9261BEF9004CE4A3EBFCD0AE996F6D
+:104E80003E6BFE0CF5EC1C5699D0AAD0BEDE8FB25C
+:104E9000AFF7B5FB8A5C77E43E27097DE17BE7B39A
+:104EA000A10735E33163EB10B48BDCB9F6940FAE98
+:104EB00084FA30E6423D7DD67D5D422BE2CF9DDA1D
+:104EC000A3DCFD6A75D7D08383BAEBE3D9BE293A58
+:104ED000FB4361DE50DD0176C48A0CD5793219F8C6
+:104EE000B6CA743F92E1146BA791215CD49A04E492
+:104EF000C729CCEAB441FF3B00D91760CD933D31BF
+:104F00004E9B665F9FB72815283757C070BE3CC2BE
+:104F10000FD955B305DC57649869FCD9CCDF86708E
+:104F2000047AFB424B6FD1E0707D78FFC3BECFFEA9
+:104F30008F82CEC47D3B9259AB0278ED52AC81EDAD
+:104F400030478DEF0E57793EEE9FF9CD202A17E5B9
+:104F50006609FDCFD76B62F2A781ECA51A61CFBEBF
+:104F6000636255BB6C58B6F6CDD3C8F7A9EED245EF
+:104F7000B91A3956E3FB0F1A1FD531D29DA4CF5968
+:104F8000565BABCAE9EE74883E88EE6A1CB83FC037
+:104F900007BB00F6D8FADE8B5D086FA91FC1BE59AA
+:104FA00089E3AF8F8D1FC6125848BEC7205ED10E51
+:104FB000CC317EADA5D36EFAF9E0BC47B6013F789F
+:104FC0006D46762754BDCAC9267C0F206242FA9AE4
+:104FD000ED337DAE7DDF6B072902FB9D936123BB23
+:104FE000727DEF910EAA43DB48C4AB1FFA5BC3EBA3
+:104FF000F722DAE0F9FA2BD8CF3AB379BF55B044AB
+:10500000B65133EE80F0B891F375D34F11E3478E6C
+:10501000B3DE00FA19E0A3DAE72D24FB34A3B7834B
+:105020006CAE1C6E47DE976BD0E99539D6E44C63C5
+:1050300072B8FE7E2F5B95563FCB52BE27E116B667
+:10504000C3DEED389819B6C3EE6A7AA3E3505F8DDC
+:105050001DE67FA303EDF57FD60E7B7AD71B648711
+:105060003163C37B3F81FDDCF3824A784AF695B118
+:1050700013B06E23980D0949642FFBB1B4FAFAD02E
+:105080007E1423400AE09EEC044507EFEFCF75D273
+:10509000BA8D4ED66A87C5251B5D8A0B9EDF23EC31
+:1050A00019FA013AB827C9B1ED4E20798B95AD8B2D
+:1050B00049C2F7F8BEE57CA171735C8A6308F10F01
+:1050C000D93F926F24BC5E46FDA2A5FB8BF3C9CBF2
+:1050D000B905DDF9E48881EFDB0FFB7E18B63033CC
+:1050E000E3C7F47CBA6F2E9537FA1651D921F4191B
+:1050F000F8811DC80FED55AFCEBC0DFDC0DD1617F4
+:10510000A82FF669D5AB0B7EEE44F800BEF1FD1B6F
+:10511000EF9D5608ED9B6C46B2F336F6E5FEA9BA54
+:105120004621FB6193D35CB11BCA99AE52731E0A30
+:10513000BC8C7803F2EBE7B19C5F67BACAE9F95718
+:10514000EF6EC89883F661462C4A14783FEBA706A9
+:10515000F4630EC37A19F225237DBCDECCCB60AE9E
+:1051600091E0121470EDCAE576D0469337A701DAC4
+:10517000AD41588D861EAD463F73D8F0B9919EABB8
+:105180000AAC0FC78BF5E6DCA2819F1CD71A04E698
+:10519000CDEFE97D333DC77DD1FB497C3DB29F9288
+:1051A000C7DF57F20C629C389A6F7D12ACCBA61DFC
+:1051B000279E3F177C16C9270DB9652684CB4C97CF
+:1051C000C79C47FCD2694239392BE35087127F29AB
+:1051D00072AE534139673FAFB4F607BCC796AA8198
+:1051E000B5408FB18A63921BFDCF52930BE1DA9EDB
+:1051F00093621F00F31F353AEC49B08FF43C8EFFE9
+:10520000CA71607FA2BD5F6A227A3E9A33EFD72AC5
+:10521000B7F9AC5A7D33DBEA0F083D13B673783F1C
+:10522000A7B150F48375CD2E573D31F1DDED9FA32D
+:10523000439226B9617CFF2A95FC95D9E3D4636338
+:10524000B1711D3BA8B533415C1C1C08E31D17D58B
+:105250004EE6309729613B63B64F6FFF30F44E0A3C
+:10526000D14EE03FDDEC26B7EBF96427C26367055A
+:10527000C163A8C181F0B8543B8AB1BB09BF71E3D7
+:105280009E74A01F64CFE372C15EFEAA87FCA47166
+:10529000678D04B7128525C23A9B7D06E681793673
+:1052A000BB4D0105DEDF9CD379780CF2A3DBE8A4CB
+:1052B00038404EFBF565D45E40FEC52B38C508EA84
+:1052C0004FFE8ADF660B0C42FD5DF0BA75AE865E5E
+:1052D00036BBDF1F8C7A6CABA0231083B67185615F
+:1052E000B8217C9C2444D7105E0FDE1E4BF87CAFA7
+:1052F000590D58781F03E2D39EC1F9719C6AA3F936
+:10530000E6DEAF0430DE32B7E058A905FACF6D52C1
+:10531000882F67AF52FF6AE1F0D6D965DE864AB2C0
+:10532000176AFD11F69AB0E7607033D2EFA5DA7311
+:1053300091F6C9C23C619FE4B13CAD7D12CD7F9234
+:10534000F6898D799621FFCC31320FC1A7E43A82DC
+:10535000EB38F5F4E131B0AFCFDD0306201C460990
+:105360003F66B3EF2D2BE273F37995F89B193B174A
+:1053700021BCD43B4626A33C6FBBFD8AF413D0BEB0
+:10538000268FFBD15B0DCE9F9720FDBE6022B91A00
+:105390006D3D569FCA0602BFC7F8142A253EECBED3
+:1053A0001866D4C819009107E74D75772903347240
+:1053B000E5A7795C0F24AEE2FE72AA9B799CE80710
+:1053C000E60CD88E7E2C28243FE22D7690330FF504
+:1053D0009AEC7F5AE1F13A6379831FFDC1FEB00E6A
+:1053E0009CCF09EB40FD96E58BA3FA005F3295D97F
+:1053F000BE442A07FAFA50FB205F369597F9B2E8C7
+:10540000F9E5BE2BA99EE3CBA772B02F97CA2B7CE0
+:10541000C5545E09FA0DFB0DF1955239D437819EC2
+:105420000FF35D47E555BE2954BA7CD5D49EEB9B5E
+:105430004B659EAF969EE7FB9650DDEDBB99EA0566
+:10544000BEE55416FAEEA072B8AF91CA22DF1AEA8E
+:1054500037C27717D547FAEEA5B2D877379525BE6C
+:1054600087A85DDA192FE3AF60CF4D4E9CE3207B18
+:105470009BB95C68976D8D227F5F16F27B749EE707
+:105480000F79A9E17EAACA1AB4FD65BF17F2B8FE6A
+:1054900049649CCE0CD6566B36F9EDD979E8B76FD6
+:1054A00005FE77027E960D1EB01DE5E87342CEC65E
+:1054B0009A5A3C7D94B09F9E58EE21FF7CD99EE580
+:1054C00054B2A2E44B8AFB3C25E4CF56A39FA1DE55
+:1054D000DCDAC05C7E781433B05D41F9B06D88A130
+:1054E00002E5F95D433E6F437E9E54E071A3797AF5
+:1054F000D71083C14A72AAD48DEBFC36CFC4E932EF
+:10550000CFF33AEEBBBF3BF547D7417BFF750607AC
+:1055100034B344B789E23889302DCA351957D916C2
+:10552000ABD7835F0A7880A4BE0FDFDFDA7B20D1A0
+:1055300025D4AFE1FC3480FCC6ADE656C588F20D3B
+:105540001C9A87A5ACC7FEEBE7FC1AF96DC046D7DD
+:105550007E5C5F7FBF2B1FD7FBA5E0BBAC16E7D8F7
+:10556000185850F616CFFE18783E28E01D1B0BF594
+:10557000CB1FF1EFC772F0CEC0D83828AFDCD3BA5A
+:105580001FC3AF435B3BC7DAA07ED5217600C54081
+:105590006EBBB3CC0EF5FC0ECF010C4316747ACB68
+:1055A000E2114FE640633CAC67EB71E65A03F5113C
+:1055B0005DFE03243E051E427460610D687F599DA7
+:1055C0002D1E8477E64A07C567647C73ABB133262A
+:1055D00091E286B05FDC1FE01FE57CA6A78BE09F11
+:1055E000E966790042B66D9D847F16D14956BE2288
+:1055F000E2731E533EC6F3621DA51877EA1AC71C54
+:10560000DBA17DF2501EBF32370D203D22E90DE0B7
+:105610003A788A5D0B7F4E5F5B23ECD26870CDCA0F
+:105620003753FFFFDF708D84E72EA4E382EE709581
+:10563000F06CC57D8CB838FFE6E573FA03FE1D9665
+:105640009F1ABDDF0DF91C4E9170DE66608740D752
+:1056500000BE38BD6602FE30FE33558C7BA9709DBE
+:1056600098FF7F43AF91701D9CFFDD702563B417D9
+:10567000BEE788C5F38E687206C7C37DF724DF18BE
+:10568000C525B3B6AB00875A01D73B83DB2A713CF3
+:1056900029DF8C7BEFF6F46161F93634FF22720B5F
+:1056A000A7A678B62D80F2C126E21740091373DC55
+:1056B000E80F2849682FD50BBE79C655B914F10DEE
+:1056C00056AA1BE983B9F4F1F589AAA314E50D2BB9
+:1056D00056C8FEBDB6E4A847257C39F3548E4D3A32
+:1056E0009F51EF88DD8EF8CC02BBC1087400BFB6B5
+:1056F0006299C076B6925FB28EE5A1BE678EDA0C73
+:105700002DDF49BD1EE64B491F49E40F22DD62FF34
+:1057100027057C12643FF49EA0DFFA1FF7A67320D2
+:10572000F9DE365B26BDF7647E22EDCFDCA72EA71F
+:105730007648747A7E4FD2F3BA2708BE7125DC5EB4
+:1057400048589744F49D50EE4DC3E1C3743DC78C57
+:1057500074FD783E8FB74B390E7EF4EC2908FF2498
+:105760005ED24112CA9D3E99DBB9DCBE34FA5FF5C8
+:105770006FA6FF5582AEA3F141FF12479B8AE71344
+:10578000E5CCE144BE2E411D86E71366929F0CEDE9
+:105790005FA82700793FA8105C5B311EEA37D889E3
+:1057A000DE544B6739D18B2591FC83675CDE3FE784
+:1057B0007F071FAD373B7319985C6F3D79F2461B2D
+:1057C000D0DDFA2CE02740DDE1FC4F6E6C2E4278F4
+:1057D0007632517F00DBFFD978068CFF26C6331C5A
+:1057E000713C6E80E77B533574D82EE8E0F27CCFB5
+:1057F000CBB85EE08BB7902F4A195B69C8663F381B
+:105800000E1219FF907C76313B45CA8F30BF3B7238
+:1058100025BF235D83BC3E49FC2BC68B6677350BC9
+:1058200039FC45FEC5ECAEA45223974B82BF397FAD
+:10583000DEC9F8394934B97442D25514B964B7B6DF
+:105840006CD9C1C2F15CAB809F5C5F4CC6FA76F448
+:105850007BEC229EBB0AE3B9406F311319F94FD696
+:1058600081FC39FEF41CD70DD0FC723C19D765C2FF
+:105870005FBB59BCDBB2D6953010FD8F97799C0485
+:10588000A497D301ED13F17758AFE252084F2DFFE3
+:10589000C1F97452260BAC05D298F8B5C23C30DE83
+:1058A00091AF552A23E3B293E03DB4538E28D680BE
+:1058B00015FAB7E55A9819CF4BEC06E137B666F6FC
+:1058C000C37A9E85E2F807738727E0B9EBD923AF47
+:1058D000DABC437AD0B3DE5A5D5C2B4C17FA7DDE1E
+:1058E00030F3391BC2F721C7586B16F9BDFC1CD326
+:1058F0002CE47E48BFBBCDC24EF50E716339AF6B51
+:105900009D19C5B2839F63B20C4E3FBD6CBB0F7B2C
+:10591000E0D75E75DC7EEDCD026B1CB6EE74F992BD
+:10592000DB5B88A1EE87E439611DB7B3363AF939FC
+:1059300061697DEF920130C003A17342EF609CD793
+:1059400093BC3317E9E8A1AFF7C420C99C6347565D
+:10595000927F91FF6E8A13E3DA05CFA5223C26459C
+:10596000AC5F96323E17E9EF8E77EBE3F1E758C96B
+:10597000B5387EB478BC8C1B4ABF17E3828E1EF408
+:105980004324BCE5FC35400E9437605248EE1DC1FF
+:10599000AE23486E54B9E9FC13E4911BE5C7D0006F
+:1059A000CAFF97DCF9745EC15CC9521F676ACF41B8
+:1059B000E57AE0F9A09ECE476BA2E471D4BBB9DCD6
+:1059C000AA3171B9A62C7FAE06F150936B512C59B8
+:1059D000613A9DCDCFE2D82C37D7FBB35D1B3E5348
+:1059E000E3BB9F77CC7273FFF788A935D321E2A57B
+:1059F000AE1EE8331A5CDE34FA67225CDEF45A1C11
+:105A00007E18EF25EFF074D6C3BA65F916D207C039
+:105A10007F24C2AC40833774D67BC07F07E6F798FB
+:105A2000BA9F2785DA6B63288E5E85F0D2AC7B8BBC
+:105A3000D8F7EBA264167F0EC69137CEB9DFCAC085
+:105A4000EED934F0F3023FC07D13EB2AD84EF13586
+:105A50003BC52742F02BE2F0ABAA3D57B046931767
+:105A600034FBC02607D26D55D6BA54FF90EEF07CB9
+:105A7000DDCDF71523E8D9C63C0F227D84E22B0348
+:105A8000AFE7F47020C6D50AF35A5FCFCE437D2F1F
+:105A9000E32B382ED10DE371E0950EBE0E94315AF2
+:105AA000BAAEF22DD3C98B98A0C202DABAB185E2A0
+:105AB000A83141233D8FE49F9F20FFC485F9E7D89B
+:105AC000F90D0EA4272B9E6B0F099FABDB7392E899
+:105AD0001CFD5895EAE1F113C736F4CFFFEAE67AE8
+:105AE00045CA77793E1779DE26CFD9EC11E77631B2
+:105AF00039D6EF3CB793FB0D9FD7E9E11CB99F4323
+:105B0000EE28E77351E84AD293A4AF68F42AE92B50
+:105B1000F2B9A4AF8EDA4D394EA4ABD89EEDCD0FBD
+:105B200005BFCA7A643E813C478F7CEF7762FCB345
+:105B3000DE11C44F5566FFA04B9157922E2E963F13
+:105B400071039E93F430DE5BA1791FA0738B9B0BD6
+:105B50000C0EA4BFCDF0CF8F7CE23651DED49BE794
+:105B60002D0CED407B81E1576B29EEBAAEEFCF50A3
+:105B70007FD65AE89CA315F8BC0EE0BB49F07B2801
+:105B80004EDBAC0606A1BE00CDAB3D079E54C0E384
+:105B9000E89BEFCB0DA07F143BD0AA6BDF543035D0
+:105BA000A1956A2D93E6C038739CFC1CB18AF1F371
+:105BB00040EBB71B2A917E37995A32726D61381CBF
+:105BC00018F4A51DF37198123E6776827DD75A3B73
+:105BD0003CAD93E83583CE47AD0EDE36B7209FCE81
+:105BE000073B319F90CEF145BC98713E9C9BE54EA2
+:105BF000437CC838AF26BEAE8BDB468BF35E6A7C37
+:105C000057D27F249D0F2AD0F3EDF788F35E59A079
+:105C10008DF33AAFD7C913297F243FBC25F6DF3176
+:105C2000E86793F0DCA9633EB70E0F0CFAD94BABD3
+:105C3000DD98676674A2BEB17EFBDFE3900ED822CA
+:105C4000A5C7F8EE2D52FEE2397F4E18FE377A17BF
+:105C500085EA48C6D50B97EBF21322E57F74FEFC6C
+:105C60006EFEEB7273FF4AEA07D4034936AE070CA7
+:105C7000F630BD47D30752FE47EA85483D5055DB15
+:105C8000E4F20FA5F2111CC79A1DDB10E8413F4456
+:105C9000CA75397FE4BA63822A0B246BF9D249FDB5
+:105CA000C272DD4CEDF09383FE978FC5BAD0EE98AB
+:105CB000E5F22C2C207DEF5984E5189767718166F9
+:105CC000FC4613CF87540DCCBB8BFCD3CA0CAD5F05
+:105CD000B4A980D3415329EFD7965A98F137281B9E
+:105CE000FF9A9B6182797F5AC0F3C70EDA0B133A91
+:105CF0007B905BB2FCA9A09FBB500E21FF0B3C4ADE
+:105D00007F1EB6EFC1B84B93A93203FDC2F8114F05
+:105D1000B40F00B8373A0C0E05B6DA20D6D1C80C4D
+:105D2000A417D6796C15BB87607F4672A4C9EE793B
+:105D3000D82FEC9D6976ECCFD765B419BFD6F29712
+:105D4000CFE8B720BC7C567E6E10B9CEFB0B38FC7A
+:105D50006F427B2435BCEFC87E9B0AB8BEAB757919
+:105D6000EE43784E7079361550FCD646E789341FDD
+:105D7000E6AF5A797EC45731BCF48FE5EBF51F8F3F
+:105D80000934C27A2D6EEF567CFF36D5CFD0BF6E68
+:105D90008CBFF52AB487A53D28CFB923E7AF317072
+:105DA00079FD1BB15EB4D3106EC5EEB1BF2928E8F2
+:105DB000A1BFB0CFC00EDF8FE7DDA54EF6450017BF
+:105DC00069F43A31EE23F343C17EDD5940F1A086F8
+:105DD000693DE55DDE739178978C37811FFDC702C1
+:105DE0001E5FFA1396A545E047A39DEF92E374B2B8
+:105DF000EF1A07E044E7BF9700BFE771BFE6F886F8
+:105E0000E1381E60FE2ADCCFA5C2EF6877F81DFDE1
+:105E10002EF87DF5EEE509A80FC0BF677D92BAF7B1
+:105E200093E7FCB2BE31513FFFFA3C5E7F47D0F3AF
+:105E30000C710EDF25D621FD628B95F963508F4DD5
+:105E4000641E941B325F2224C70AECFC3C3F7F6C2B
+:105E500017C2777D96427904EB137929FB3D5650A2
+:105E6000DA85FB3925E6EB127636C6ABD0CE9071DB
+:105E700000D9FF29EC8FE723057C5C104A83119E33
+:105E80006655ED118EE70AF879CEFE5C3EEE787924
+:105E90001EBA599E97EAF3E1E63EC348AFE379297B
+:105EA000F26BB4BC376F8EE3790CDD9C6343641EE8
+:105EB000DF0FD29F08CFB8A4EEFAD35E18D29FAE00
+:105EC000EFA93F930BB5763C73E9E249527F7646E2
+:105ED0009CF3C8F28A42DEDE2CFC679483287F9311
+:105EE00054D64072D8C8FDCB7BE2797C13E94EB121
+:105EF000E17B9C5E22E34F32EE24E35032EE24E35A
+:105F00005091F1A74E7367533AE0A96B30736D67F8
+:105F1000784EBABCCD84E754392C0FF1B43E8BC512
+:105F200017B9294FC485F1FDC4EB1DEB4D504F74DB
+:105F3000B22444AB09C6B5C3B8330BB308FFCDFEDA
+:105F4000EBDAD2A15FEDBACFC80E4C2B7126A1853A
+:105F5000B02D9447BC960DD0D0CFD8424EEF094E0D
+:105F60001E6F65563FBDE7B124E6DEC9B4FDE4FD12
+:105F70000C4F6921D1238F4B27324E47CCC5E38E7E
+:105F8000D7B276CA3B5B6FD84972657E7ED9D5D8C9
+:105F90005FF24DA3812DDCA589BF46E61B55167E19
+:105FA00077BED13D22AEB61EC6DB45F15D190F4C62
+:105FB0005670BDD07F9D2909E1A1C74F082F1171EF
+:105FC000C26871C1D81ACEEF91F4729B80D71C972A
+:105FD000670EC1E1FC850B6A21BF0E81F882F718BC
+:105FE000EAFD98143BC569639CFC7C9B39141E0F29
+:105FF00032F3B89CF93296BFC689F9E4B68D0AE649
+:10600000EDCD3330CCCF2D13E378AA98F2410E8139
+:106010009271796C641F483E5205F060DEB10294C3
+:1060200016407D1CC0A9CCF6C2DF15E0C7F4813C48
+:10603000CE9B9E9240F90FF74489BBCBFCAE703EDD
+:10604000DB8FDED6DE2BB8ABA9FC6D7D3E5BF9DBCA
+:106050003F249FEDBE3F94BFBD4E87B77F6D3E9BF3
+:10606000947F1DAAB7E30E80FF34105AE8B74E8321
+:10607000116B283EC9FD8AEB059CFD5F039CAD6159
+:10608000384FDB7B98E0D7618275C3FCA6B11CD486
+:10609000A6DB1348CF49BF6EBAB5651CDA0767CCDB
+:1060A0005DC370DEA57F7CFC0F68672EFEFDFDF1F1
+:1060B000980CF191B1250D9FD73DDC148FF7303E40
+:1060C00034FAE3D1DEF928A056F44457EF083984B6
+:1060D0007E8D02EB5B26D6F721C81FBC8FB0E84D42
+:1060E0004B600DCC5FFF88A5D502FB5DB67B11C967
+:1060F0006BA8FF95D737901CAEDFA397C38BFFFB30
+:10610000FE3427BFAFD2C79041E8EA832058B6C318
+:1061100044718E65AFA92E9886D5B3AEF5B8BEC8CA
+:10612000F7711D418043FD4EB5D69CD0BD1D249313
+:1061300019F552BDD003F511F27E61147FE94529AE
+:10614000EF87B3E148CF0017572BDA13B01E72EF79
+:1061500002A964BF34FEC6E2C1F8ED476FA56F43E4
+:10616000BFE6F48E17E3952161F9CFD85A82DBE9B7
+:106170009DD9093DC56F65F9E96ACE2461FB86E3C7
+:10618000D1B90716980ED5BDBCAC33B5C617035CA4
+:10619000EAB6995C7E785CF7B8EA41938B01FCD152
+:1061A0003F5EF2F873C746C27A96EC32A54CE4DB48
+:1061B000B12969617CD5C33FA437899FC54F3E672C
+:1061C000760EE5CF31EF55E269C9AE3633C6BB2254
+:1061D000E159B6B3CDCCFDDF087CEDFCEB78A4FB38
+:1061E000C6DF7C65467AFC689FC2D2B3BABFBFF0F7
+:1061F000E117E3B1DFC5F0767A471CD907A7F72A84
+:1062000024A7A2E1EFB142CE4F40DFBF7B1AE65D8B
+:10621000F896C585FB5EF8BB9BE371FDFF6B6CE0F8
+:1062200074FECBA634940B0B4DFE340795FCF9C2DB
+:10623000ADB710FDDD74F416F2DF81BE7B198A68FC
+:106240007FBD705FF37F318DF6B5F09773695FECBA
+:106250000185A18974CEC82A76F580CFA9C3B9FC7F
+:10626000FDDFED1652D6FF6BE6FCE9FF8B1AE079F5
+:1062700018CB89BFE57D3D8A5C41FD9C95E327678E
+:10628000B8CCEFE0F980F5A257FD8E0D74EE71AA3F
+:10629000AF271DF50CC0419717A81E1D97CEF1C260
+:1062A000F303E93DE0FF327C8EFDDB4D9E9861BA41
+:1062B000F7845FC9E75F29E68775C72A57419916B2
+:1062C0003A876CC7752C53F83B483798F7E617FBAD
+:1062D0000CF1FB8E4D1C3F82DFBF788DCB91658129
+:1062E00029152407DA4DADE9D82FD076BD4272C00A
+:1062F00012BE8FA8E5E31D26410FFA76589751D1BB
+:10630000C2739F42F1A405F7413F8DFF5FBFFB2E93
+:106310008A57D7E37D475D5E21E743196FBC292289
+:106320002E2ACB48393071B8880F0A39108A57FEA7
+:1063300022F53BE383D23FA933057EFD20F2EB9BA0
+:10634000163AE7AA7BDC44F99F1F3F76E0D80CA001
+:10635000EF8F774A3ED5CBD5483E5DF8C434D6138F
+:106360009F7E9C52C97AE45378DE239FA6309263C5
+:10637000FF32B91A82B79E2F6F8A22576F8D8027FE
+:10638000D8ED09C5503DF5DB25FD292F2B02AE12B6
+:106390009E91F23171B8B347F9083FAF310D1C251A
+:1063A000FC247D2E7E7429CD13A25B499F524F851C
+:1063B000E83372BF7A3846B6170F67B41E93C165CB
+:1063C000C5D0CC8CD41D76F4471A855D0B06E82128
+:1063D0000C294FF3648B7C2DCEDF225794ED1D2EBC
+:1063E000E35D9CDFE47D1F8B97F3BD8C675818F04D
+:1063F0002F8733F1FDCBA90B2672E36745845C310F
+:10640000905FD09E52F46B91F74072C1424D78FF7D
+:106410006533C1E35A8F4A70B078781EB1667CC28A
+:1064200063A3E744269E4F3516595C2887A13FC1D8
+:10643000699A97C3739A67C24708BFC92987AA3068
+:106440007FFADA223DDFCE88E0C31BAAF4EDD3D970
+:10645000F654B447A72F34B180827690BEFF3DC377
+:10646000F939D30DACA1C9C1E959C0497FEF84897D
+:10647000F3DBC9428EC97CDB577628E45FBE523419
+:10648000B73917EB8F81D508EDE74AF29915E0F09F
+:10649000B289ED21FBD6E3713A0AE95E0D3FDF2DAB
+:1064A000FA1FB2B3128A0C3AF992E889D5AD3FB916
+:1064B0002249574FADECADEB9F5E3540D7DECB7B2D
+:1064C00085AEBDCFC23C5DBD6FC3485DFFFEBEB1B2
+:1064D000BA7A96FF47BAFED91BA7EAEA835A66E85A
+:1064E000FA5FBE658EAE7D7060B1AEFDCA4756E8FC
+:1064F000EA4377DEAEEB7FD59EB5BAF6DCD63B75C8
+:10650000EDF987EED1D50BDA1FD4F51FDEB15DD7DB
+:106510003EA2F3B7BAF6E20F9FD0D547753DADEB7B
+:106520003F26B85F572F652FEAFA97595FD5D5C731
+:1065300039DED6F5BF3AE384AEFD1AE7C7BA7689ED
+:10654000FF09396775CFD161F2033D2CE68FD8245E
+:10655000D737BA718CAC92FC47336BA0D28AF989D9
+:10656000D9785F9DFB9536F433A12C2AF3A616A1AA
+:10657000DED9EA5F8FC4F5F288AFFAA1FE78A5E410
+:106580003ADDB9D7B5F8AB134AABCD8FF254C67527
+:10659000E2832A6BCD073A0C2A543A8271AC15FC7F
+:1065A0008DC4600C9549C1647A9E1C4CA43225D8D8
+:1065B000879EA7067B519916CCA6323D9845654625
+:1065C000F04A2A7B050753D93B984FEFF509E6526D
+:1065D00099192CA6E77D8323A8EC172CA3E7FD834C
+:1065E000A5543A8313A8CC0A5E43E580E075D42F06
+:1065F0003B3885CA81C16A7A3E287823959705E79A
+:10660000527979B096CA9CE0122A0707175179454A
+:10661000F0667AEFCAE0722A8704EFA0E743833F6F
+:10662000A67258B091CAAB826BA87405EFA27EB96E
+:10663000C14D54E605EFA5E7F9C1BBA974071FA238
+:10664000E705C107A82C0CFE8ACAE1C16D541605E6
+:106650001FA57244F037548E0C3E49EF1507775151
+:106660005912FC333D1F15FC1395A38307E8F998D5
+:10667000601B959EE08BF4BC347898CAB1C157E991
+:106680007959F02895E5C1B7E9F9B8E09B548E0F28
+:106690009EA0F2EAE05FA9AC087E4CE535C18FA868
+:1066A000FC51F02CBD3721F819951383DFD0F34945
+:1066B000C1BF5319F2074AA2DEBB335CA038F21601
+:1066C000A2A31A41AF3F8F8B27F977ED2A7EDF60B7
+:1066D0007DE9D9728A872EB738453E7084BC3C6FFD
+:1066E000437BA1095B7AF13130DF65A6A0CB578AE5
+:1066F0000EA4E2F9D5FABCCE3A8C536DCEEAACC109
+:10670000F2D622AEB7961771FF706511B75F9F1B67
+:10671000E19D5C06CF17F735F8D17E581CEF4CB8D9
+:1067200001BA3C2BE4394B49E2F983B6AE7E6847A7
+:106730002C13FCB46CEFFF74A0DC55802D7C68E753
+:10674000C8FB387BF4FB57604D3549A8AF5C562B2E
+:10675000C6733319C5A723F5C2C5E2C2B38BBC9B70
+:106760008A489F340CE7EFF3B8B0D43397F0FEDDDE
+:106770003FF0FD07483E44797F43CAAD95B5583593
+:106780007A8C93001FD5021FD50D37915D037A8E49
+:10679000ECB94EB0E750B75BEAF4F77E2D8EDD26FC
+:1067A000F403AA57F273C7C876F889C73CAEEA4C1F
+:1067B00003C3381794D4AF1AED399D9FB093EE49B7
+:1067C00055A31F16DFBD7D4E147B6F7791DE8F962C
+:1067D00074572DED1475D5213C2F3E7744A518C76D
+:1067E00081543353A0DEB9D44274CB36727BF0EDC2
+:1067F000D43FF4756AFCEA5A90871E3CA75D7A5B29
+:1068000006D2ED86A65D268C6B74F65D4E973D2212
+:10681000FDE8CEBE8CFCDC6AFF7223D99939403189
+:1068200069C21E72A2DDE6DC897064FDAC2E3CBF3D
+:10683000530DFA73EEA2119CAE65F91EC68BD00FF4
+:1068400059C6F37A4C8606BACFC9FAC51A387FF909
+:10685000EBB03EAFF9F201687F55189915F35CE58E
+:10686000781A3B2B96E06B04C068ECB3483BEC44D1
+:1068700051A2F00BF9BDDE13E27B35F8A3C87D50C1
+:10688000FEA1C78C79B096142BB7E75AA62C41FB12
+:10689000F0BDD03D26D81BCC538D6B048057AF8AFA
+:1068A000F30C86F60F05FF9A44FE10D0895F6BDF6C
+:1068B00056A39E83FED78C907120BE3F6FB3C589CF
+:1068C00074D3E37A0C2C94DFEA6D4E0C501C35C562
+:1068D00048EB32F5F5CCC273028B1FD687FC6DEC0A
+:1068E000BAA516CF03FC89FC9EEF3A653CCA1B4B48
+:1068F000F39AE5D80EF06346E47723339A018EB518
+:10690000CC313E03E1DDCCF38D75FB427A6F5668E6
+:106910005FF6D07A3DB330756DAE9FE7D5013DD0BF
+:10692000FC4D3FB17BF8FA946DA89F257EAAC5BCAB
+:10693000D52D7FBC0DE591579C7F548BF9678BBC9F
+:10694000C968701A3942DAF39EE36FB8BBCF2BD710
+:106950002BE1D4A4F0FC68FF66651BD28F65959D82
+:10696000FC75B97F8B5847F98801B41F0987CE356C
+:106970003754D5C2BE4E6EBE1CBFECD16D3D48DB58
+:106980004C431F9174653270FCB07E8CFC6949F7F2
+:10699000925EF247F0F8AB2C5DA17D69E2086A983F
+:1069A0002E23C79772EC6A6D7F787E7526CF077DA0
+:1069B0004FC45D878ED852E387F95E2A12FAC1D997
+:1069C0009043E78D623D0848E20F41B7169BD533EF
+:1069D00018E03146ACA749A92438F8375B881E2255
+:1069E000FD7267880E98D75C28E4A8019F3BE9797F
+:1069F00075B385E02DF1FD7EE8FB3F9E7E53501E72
+:106A00003B041C057D7D2BF4DEB7454E313FD03D68
+:106A1000E2EF6E0BC903899FF77008905F3346540D
+:106A20004E1B5140FC398CE4FB2A7EEFA5C6D036C4
+:106A300008CF2F6BD6B65219965B1C6E15BDE57745
+:106A4000625C943FC2326D940720F354CF3617D066
+:106A500039A3379EF7538CDEE158AFF8C7DCE11855
+:106A600097656FD9E97ECCCC6C367BEA1091DF0755
+:106A7000EB99D9784D05EE73A980CB2BE05F7B2E87
+:106A800067ECE86A2BF300B1BCBADA41F5D7576777
+:106A900050FD8DD54E2ADF5C9D43E54933A78F9984
+:106AA000C9324FDA41F7106F16F2F1E610BC5766A3
+:106AB000A0BF5CF18F57312388A5F89FAE19378AA4
+:106AC000FC4894C1213AADBA3E4E1C52F07A6D6535
+:106AD000B1AEBD53E41FB09CFCF0F3019C2E907E40
+:106AE000E76CCCA2F3AF1B2726EBDE9BBEB18FAECB
+:106AF0007EA7C0F7948A6CDDF3193557EAEAB5E250
+:106B00003E32B3C61AB4F13110D73C4F58E4FDDC25
+:106B1000BCFCEA84DB60FE9B8FAAD41E89875BE7FE
+:106B2000FA67E1FA6EFD95C585F701E66E51983F6B
+:106B300099E0C7F5C73195F86EDE16957961BE53B9
+:106B4000899EF40418EAC318BEAF0F5F57B735A289
+:106B5000FEF84736D74FBFB6907EFAD0C4FC0EFC85
+:106B60004E010A2D787EEAE820BA573133BBB52FA3
+:106B7000DE2BEF7A2A86CEEBE676F2F99892477111
+:106B80008B0F13992711E8F293492D0B285F5D3D78
+:106B9000928AE7309F3C01FA17DE5FB4FCF54207AA
+:106BA000C075F1F33B8F21899F6C519903E3548F9A
+:106BB00058B6F17BCA9E74E487F03E03C3286FB3D6
+:106BC000B07217D2F7A9058161E4A7AF4A25FA8E02
+:106BD00084C749B37738C6CBFD4897309EF756BB7C
+:106BE00015FDAFB926575A2ED1118FD3F999BB177E
+:106BF000A338EC13443F279B078D27F9B851611840
+:106C0000E796E3033F4D46389E6C493620FEE73455
+:106C1000AB742E86F762896FE57769EE56BD6083A7
+:106C2000E0FB5E1E27D2E311245B3AC26D03388479
+:106C3000A87F6645890F7E0ABCE3D5C4A1163FC371
+:106C4000BF27C4DCCE9F96C0FA26EF282BA03C8835
+:106C50000C3EFE1749926EF877943EF7F014EA73F3
+:106C60003BEC01A487D386278E1B010F6D06EFDB5B
+:106C700008BF8593FD5B15C0FF99BD27FE13E3FC9C
+:106C8000A71E37B970781BF3BC43F2C3C7ED217957
+:106C90009EBCF8B73144275FF6BD621BE22F2C3F44
+:106CA000D6F07D8BFEB8221ED76E4D53009E5E2718
+:106CB0001B8F71E46AB653C455389C9CB8288093E6
+:106CC000A38EC7D34E14D8EF6457017E22ECA113D4
+:106CD000821F3F137C2EE55CEE485E9F2BF5CA3E7B
+:106CE0006E1FC9EFF72C641C1E329EAF8C1C4072C5
+:106CF0006EA1B067E907F6BD04E80DF1B9C091B81F
+:106D000012BFCB54F7488C2B00EF8D1EC9F917C664
+:106D100070205F2E12AFDCC402CD7930DFD2474C39
+:106D2000AE56DA8EFCEE8F91E4C42913D86E493842
+:106D30009E42E3D7B528018C3725943498719D4B3A
+:106D4000762B2C99FB45149793F7DB171B3753FCD5
+:106D50006D718E4276317BC47452EB872CDDA9BFF6
+:106D6000D75E1F719F7DBEB5B95DE57906FA7BFCE4
+:106D70002D26D29356665D83E354C6D9695D8B5B3D
+:106D8000B8BF165EBFCA2E002C177803CF4F263827
+:106D900028AE00EBBE8E7129CB691F8B711F59DDA8
+:106DA000D715B9AF4B5DE702571BD149E47A357867
+:106DB00070EAF1D04EF1E4BF359818FA7D0BFC9CD7
+:106DC0000E16EC057867111DB4E3F706241DFC2DA3
+:106DD000A581CE55FEF60B85B56485E942D2C3A2E6
+:106DE0005D0133EAFB8F594BBC0DF8A46ECBAEE9C5
+:106DF00028C26FFAC55133DA0F3549AD830C8908C3
+:106E00003AE72F2BFA86E9735140BFFF258FE8EB55
+:106E1000FF2AF8301157A5F7002EF377A8644768CA
+:106E2000FAE9EC20A6369BF11ED7B980E24279BA86
+:106E3000103F9B91F7FDD75B1FBAFFFFEF5D77A473
+:106E40003FB76CA4F0E75C3C0FE6F386693CBF7685
+:106E500055CFF7A923CF4322F5E93B269EF7D283EE
+:106E60005EBD16E902F4AA012F094693C70B843EC2
+:106E70009D8FFA13CA0FB63C198F71B5BFDDF76449
+:106E80001A9DF3A0FE19A2D5C7A01F511FFF31867E
+:106E9000CE4F6B7E6969C5F8F3E9DD9600CBEA3E1B
+:106EA000FEAF0ABD9BE9CE81D09FA794A385F8BD14
+:106EB000292957A39DE7FEBBF63B07F79B8F760476
+:106EC000DFEFFB1BF93E4F34F37DCFEBB65FBDFD2B
+:106ED000F1614C2BE9FB0F77A90CED0A694748BB20
+:106EE00040EEF31C6BD98ADF095BBAE28DE346A062
+:106EF0008F4597B50F6B8575D5DC6D217B60D153C0
+:106F00007682D729A5349DEE7BB5583C3684E323A1
+:106F100031F43CBC8E907DF0D4C8548D7D7089F0E6
+:106F2000937120C5E9E0F911BF60F47D4B3C1FC1AE
+:106F300073096633907E897CFFB4D0434B5503D9E7
+:106F4000A775666EA79E117EEA0B23B9FDFEC248A7
+:106F5000EED7B48F74087BB56B2BC2EBE833160702
+:106F6000EA9F76338F0F1F3579B6FC04F6B5A4D8A7
+:106F7000FB0AD243A5C13613F9666DDC3013CAA1F2
+:106F800075890BE85C69166B37213C26174D7162D9
+:106F90005CE5789AD5A512FFB34A56188EDFBC6C13
+:106FA000E27935C711CFB0AF6A71DE703C06C425F7
+:106FB000CC7FBC9799E243FE672CA48737C4F27854
+:106FC000304B49A0EFA2CE10FC3EB3DCE241FFBE45
+:106FD000BA7C432596309E9F01BC6AAC5D4D988279
+:106FE000B2C6C0F5DD9A2416407CB3759D0508BF76
+:106FF000ABD83A07E695C0EE775F48FE2E3CE8F343
+:107000007AEA307E3592710415117C75F53A336F4A
+:107010003714FF78E67D9950471B1DEDD16BD4C026
+:10702000F62C8C731B089FD762BE0BD9AF19BAEF31
+:10703000DB4D857F25B0CFA946E6372451B9D1066F
+:10704000E5B422D69A00FB6B3DACCF3BBAA1D5D0BC
+:107050007A399E63195BDB282F46654D68124F65B0
+:1070600059A61578EEBFF6D2D69B59BC6EE67D25A3
+:107070005037F0FBD65D3F56E87B6BB38CECA00A33
+:10708000EBA94F72FAE9F97285ECEA6A60263C9F37
+:1070900085F68DF179F89E42F485F8E5793C3CFF60
+:1070A00049E209FA5963E179EFE22CEE6F8AF56E55
+:1070B000F11AD2F07BBE4B851F35CBCAD661BE1C00
+:1070C000F87BF118C7C985656AF1546F96FED64EF4
+:1070D000F354B06F97ECFD9F8E2C80CB65C59C9EC2
+:1070E00097C878E963FA786945B193E655D02E03DD
+:1070F00078568B321A7F8C13E38D2BE6FC915B2C38
+:10710000FDFE9DE4E72D1171DA68F32DB5B05682CE
+:10711000D73316C2BB9CF75A519615F338865C8755
+:10712000A4F3050CEC816C2CB91E330032294FA757
+:10713000E55794DFB9F0171ABB87FEDF42E7D08B23
+:1071400077443ED7E8418A4FE8E3E58AB96B1EAE43
+:107150004F191DE342BEA836EF24FF5B018702E909
+:107160006B4194F74C2DDCDF3235737B86E22A6E5F
+:107170008CCF2801948FB599AE0CBAA728ECDD0509
+:1071800002FF73521A48CF2E40BB86CE59791C9508
+:107190006DE1EB360A3B756E8B5ECFD76E8CDC17DC
+:1071A000D7F7F23EA905F7A9D1D726A1EF1B4DAE1F
+:1071B0000C94B326A6D7FB8D0A5FBF3F95C77B58BB
+:1071C0000A6F370ABB4EF2FDF46293EE7B72E7D88A
+:1071D0007923C25FB65796E39DE2E872E35A4F5CAB
+:1071E000AB42E7CB571FE2E5A6763A1F16F9D0D798
+:1071F0000A3E87E764C75456287E3CB2B8D6633A45
+:10720000A5DDAFFC5E53A41DB2BA384A5E4649F212
+:1072100025E565C8BCF11A94D7940FCEE3D22BC2F2
+:10722000E7C73928BF6B945817DAE3328EFF79032A
+:10723000BF6F54F32ED77332AE7FA6D4EE3740F92A
+:107240008EA8D7C49B8D68BFCE4CB8753296B7A9AF
+:107250009D34CF57862ED20FFBE27DE5288E3F6FFF
+:1072600078DD8E68585F9ABF056C2AF6DF7F7E75E1
+:10727000A6B52F9D0A8AFCC4F7DEC5BCA5EBCFC31B
+:107280003EA8DE39D303FED899E7BA66E1DDA3173D
+:10729000FFDC39D308F039737FD756AC9FF8F32958
+:1072A0005EDFDCD52F86EA9FF1FA1A319EFFB39993
+:1072B00038DE990778FD4FD0EE2779D23A08F73BB0
+:1072C000B921C6857104198FAA31ECA7121D6D94DE
+:1072D00043922FBE1CF4D9AC156447765D86F2A0AC
+:1072E0003EB6D5948EFCBE8BCBC7A52B4BE34B197A
+:1072F000D21F3F1F7D5AE863C5E321B96981B1629E
+:10730000810E9E413F22B5BB7E6743603DEEF07A21
+:107310001E2DE6FD22D7F54971E5A3C5A9F83DC5A7
+:1073200093743FF9CB519E478BF9F9D3412C174FFA
+:1073300051FC6680177B2D7099B01BC86FDE60D042
+:10734000E7C93F2AE49C2C5F2FE1E3D62C1F447948
+:107350007B30DECB3F64BCB9385E41783C09CFF965
+:10736000029E30FE5B3F647C29B7E478AE51DDD6E7
+:10737000FFC10F19FF9151FAF54BFB54EE6328DA68
+:107380006080E7E2D18CE359AC473E6F525A536FAD
+:10739000C078D76195E2574DA91F18F1BB04ECA442
+:1073A0008DDBC1319CEF624A443CF7272E8AABF952
+:1073B0005FE2F7EF9B52A767A0BDF7F1E3372553D4
+:1073C0001C4AD88F1FB7BD69C6FCBD65417EDFBEB4
+:1073D0003EC8EFDF2FDBDD661E8F793E509669E2F7
+:1073E0001675E1EFFA18310F5FAE23A6C420E41D35
+:1073F0008F9B1CC7BC9D21DDE5487A4928FE4DFBCB
+:107400001E26F677C6E3719468F62D9FCB7B5391C9
+:10741000E3D488713EC5E427CD7857291C7F35B168
+:107420005C1FCF2DB45B9D80AFC28ECA323BC0EFD4
+:10743000A62DFC7B46A7468CED57A2C1BB7C2F1C1A
+:107440002FEEEA395EBC97C78BE57C2EB1CE9AA4AD
+:10745000F695606CB09ABDE95BADA3189BF073160E
+:10746000CA97C6B86C8545D687CD2ACFC478A44ABA
+:10747000F5317B2FDF8AF7D80E89FB0B33870F8D11
+:107480004579D799156770801C9C3AA2B606E132FF
+:1074900073F8A8F1F8BCD462BFAC96C7F389FEA616
+:1074A0008EA82CC276EC8F71A69AE5A605285F3FC0
+:1074B000F7C7503CD23B2CCE8BF1BC430656CE34A2
+:1074C000F7680A05BE6A4A38BDC9F9E5BC300FC97C
+:1074D00069EF3D7D282E3663446975496A78DE1967
+:1074E00023BC15DA79619BC3E87BB951E68FC4DF11
+:1074F000B8121EE7AE2EE1F8AB2C01FAD3E8A7A92B
+:10750000E571BAFAF5139399471B97BEBE8FAE5E2D
+:107510005593ADEB3F63DE95BAF6499676B7D63E06
+:107520009178BB543F6A3CF07D02C0A5BD8D0DDD56
+:107530008D7C9865A77392251BAFA1387742B09ACE
+:10754000CABA966BE893454B83D7517D99F8CEE63E
+:10755000A43E33D7A2DD7228B69DE2B087FE9048E4
+:10756000FEE32B6AEB650FE178163BF1F5A4DF5FD4
+:107570004DF974CB76AF798CE27FCEB87C8CD74E48
+:1075800052D92105F30983317C3CF52FEEE500D774
+:1075900009655C6F4E421D0EED8D22DE188D6F1A4F
+:1075A0004BB81E3175F2758F0B4ED17D8F7453C958
+:1075B00000DDBD4853EA0E23D9D7623FA64E85CAE7
+:1075C0001F05AFA4B27EF714239E2BBF90F3AB141C
+:1075D000D41FD09FBE9311924B926F1A86277CD7EF
+:1075E000F7092C42FE548B73E91A8FE7BF90BE2631
+:1075F000AFEA3462BC87D9CC0EF4532717E5662C6A
+:10760000D08CD3D8762373D2792D33A35EAE865235
+:107610002BAFBC11F7AE64F97084BC92729C3DF63E
+:1076200029FF6EB38C6B0BFAB847D0AB7CBF1D65DE
+:1076300028E2ED297E5E758BC7BB07D7DB5ECAAA41
+:107640009E20F9D1DE0FFD8F7FD5FA01BF56C47F92
+:10765000BC91CF1B5F94B51DEF753D13DA07A7D31F
+:107660008BEDE3B7A2FF2B2AF3217DBC32664C3BA6
+:107670007E87A4ED8EFC7C948BCCD1751EE9AE7E0A
+:107680005F71367D4FA384DFE3ADDFC7F3C9EBF74E
+:1076900059289F7C5272D707DC3F8971A27F82EF05
+:1076A000211D9F81468CDF5F51EA7D09E151BFEFCB
+:1076B000A37CD4779EBD5F1DBFC38D59BA76BAAF88
+:1076C000F249B1E765922751D679317EEC4E5F16CB
+:1076D000E2CBB34E3EBE7723E743AFE0C75A41BF8C
+:1076E00073043F4A7E3621DDE523FD71BAAB0B26DC
+:1076F000F2FE02CEB373F8FDB9A5C12C7A5FF2F1A8
+:107700009C55CA655B903F8D76BAF73347F083E4AA
+:10771000D365C1641D9F4ABEDDE5F17E8B7009F122
+:107720006D23F07BFCA5D0C9DF8D987F612A514C79
+:1077300048271628CB34FC5D29F05E3B8FFB27B52C
+:10774000401FDAF378C3A8EF47EF6704BDCFB1B5A8
+:107750000EC2FB6226B023F1FB3C35A94E925F2B93
+:107760003629F4F1B11526AE57573CC0FF1E00EA8A
+:107770005BB4DF0B3B1ACCDAFB1A3706873127C024
+:10778000E7BAE0402A4F8DF03A46A5225EA60BBC30
+:107790000CBBA4F3C22F1A86A7A35DF3C51113B5C2
+:1077A0001778787CCE14B0B8B665617CCEAB22DE9B
+:1077B0003EECCB1CF76AE27318EFC3B89F3C2794EA
+:1077C000F13A4B8A41776E79CED8D20FEDED6E71DA
+:1077D000BB526E7F9DDE61E279E86D7F29C47BB686
+:1077E000A7B23C14BFBB50E8BD6214DA875303BF95
+:1077F0003361BCBDE5C96378B42DE15933964D20A2
+:10780000BF67BF81E4FECE66B522C0F578DC144DBB
+:10781000BE92B42B0E336E8F483A5D1CCC26F848CE
+:107820007D23E5F71F576790132DE578343D14C984
+:107830002F522F9D6D78633CAEEBEC6E858E42250A
+:107840007D87F590427C05428AE83CAC7F389D4BB1
+:10785000B93D09E34280874909FD29EE26E578A470
+:107860007E2AFE4DF6EEA79D98473EB312E71D73A4
+:10787000A54277A2EB9EE8E5F6F620A7A5BE96F016
+:1078800090F07941D47B7B3CF3908E2ECE3F3164D7
+:10789000E75AFC5318C95928B572D61461D7CAE7FC
+:1078A0008B46C9FB2497C637378CD2FB13729DEDEC
+:1078B0006619B7E6EB7F9171FB43CE738B67AA1F06
+:1078C000F7817A83ECEA51DCBEFD57ED2B9AFE6816
+:1078D0001AF5FDF4C70A010FB93FB90FB9AF23621A
+:1078E000BF97AA5F1E1CF5CFE917F26150FEC624B0
+:1078F000501C66F4B323BEB8C3897AC662443BE326
+:107900008CA7ECC1519A75CA75C975BE24D60D7A7B
+:10791000E8BF4669F0259FFFB37A49F26B24BF4563
+:10792000F26F24DF46DA8B926F22F953F2B5E4D37B
+:107930000977717B9465737B54F2EDA1580E9F43D8
+:10794000572452DC7AD96E1EC766B68480D69E94C0
+:10795000FA6F92BAFD3FF1DEDBA43329AE4616D6AC
+:1079600087926F99C7FB2AC269ECA3DF3CF9160B1B
+:10797000F3EBC5E9F34F26D25B750AD9371628B564
+:107980007ACB1B85EF3ABE27DF3D2FFABFA272FAF2
+:10799000F62798C92EBB18FD9D1AC5BFD7F66FA054
+:1079A000BF5308AF6876F819C1DF407F67904EFF7C
+:1079B0007576D01B6EFC9EF35937D84159613A9ABF
+:1079C000F022D0893B4C2721FA30F715F29ACBF1FF
+:1079D0000917785E9E57C401243DBFE5F1268F2E1E
+:1079E00008D3C3A158FF10B46B2ED5BEAD4E69604D
+:1079F000784FD60BA5563E59C477C523F19F31FA6F
+:107A0000FBE1DF3C3A84FF4B923B39A3FF69BB3675
+:107A10007FF477D8B5CC11AB8B17B84CAE04CC8BB8
+:107A200071BDA422C6A2E253DDC2E11D825BAB514F
+:107A3000DA07C9681F009DB847FF103A6195191809
+:107A4000E7A7BF5340E7379FCC467C1C50659DC7D6
+:107A500029DAB0DE1BF87CF427EFADD3C42DEF118B
+:107A6000F1917D22CE85F19D5D3DE8EBA7C770FFCA
+:107A7000F2C037A71EFD3DC69FFA9BC96E00089C49
+:107A8000EF0238BCDFD74CF93DB27F5B7FB30FF715
+:107A9000D966599D315FC32707FAA79DC77CD603D6
+:107AA000E9FCEFB41DB8239FDEF7D7F3FBC3FBFA65
+:107AB0007DB07938D4F72D53F18BA2617D57C7F390
+:107AC000974C293BEDF335EB3B509F5FE2D4E8DF69
+:107AD00073C2FF7F3BF356FAFB366DFD57B6E3DF0B
+:107AE0008BF3A7F3EF3A5AFE5EE3C07BC8652AFF2B
+:107AF0002EE892D15C4F1E0FCE686F877E4DB60187
+:107B000078F202CF45BC2D73BA95EEEFA618086F38
+:107B100026FB4C8759B31F4F8A91AF2B4BFFBDBC3F
+:107B2000CFC5B8FB043DEE571DB46F588703E30182
+:107B3000B3BFA9E96887794CFD0A9D787EF0EEE82D
+:107B40006C913FED28413BB54CEDCC671ABD76A357
+:107B500041E8AF88FC6C0B9E6B0CD3E5975A298FDC
+:107B6000E12279D391F9ADF8A3A485F34841B70C8C
+:107B7000C372F3688E77E467FC3E83CC9F3E24ECAF
+:107B80001E908AE5F85CE621CB3C69535FB66C2A0F
+:107B9000D119CF8F7F508C23E79179A6D522EF3969
+:107BA000943F9C6E1EB607F0DF6933D33D4CF95C01
+:107BB000CE572DE68B96672CD7F1DBD1FCFBC58D1C
+:107BC0003FE1F1AECE7E4E3A97C01F6D7EB1CC271D
+:107BD000EEECC79651DEB598AF499CF7596C7FB86B
+:107BE0000DCF674279C56B8B33503F36C938C152D0
+:107BF00091C705F031A769F2AC53CC94675D0DEFE6
+:107C0000670DD3C8C5EF9987DC2D3F38A22EED1B39
+:107C1000491F2351361420DDA7AD22BE4AB712DD1D
+:107C2000EFFBFAF60ECC037E2FCD4A7233C4A7E9E0
+:107C30001925F8770EDBEA93577569F864DFD77B6F
+:107C40005FC2FB07FE34633EF2E5E86FCE0FC5BFAF
+:107C500003D2969E42FD47AFFEF8E33FA21FFD4DC3
+:107C60002C7D5F6ADFD7239D2837554327C907F648
+:107C7000752CD1795942558653C317AF0BBE7AB0D4
+:107C8000C8F32ACA3D350DE8DF1696636ADA742F09
+:107C9000F26B635F6243FCFBA9146F6E14F890E310
+:107CA000BC2BF4C2BB92AE8C4EBA2FB35FE574ED21
+:107CB000DFC0EF419B52F7D8B5F1A94F45FFB6B8E9
+:107CC000042E9FEA93CFE33E6B33BD66C5A9EDC793
+:107CD000BF4F6DB126107FB759C678917F6B6DD3BA
+:107CE0004DA47760BE6928BF47F3EF643526727BE9
+:107CF000E03D43A513F1F85C91B7700CBCFFBE8961
+:107D0000AFDBE368B7631EB467657222E69B8C162F
+:107D1000F2A7ADBFD1A78DA39AC770F898C770F925
+:107D2000D1D6FF56C29BC4639BE559C28B29ED7A1D
+:107D3000CA6B1F8DF218F1B03ACE85EB6F4BB712BC
+:107D40005DB6A5F3EF4DB7D5AB1C1E0956B20F417A
+:107D500091115D8C4E3792BC7E77B45317FF92F829
+:107D6000DDAF367470796525BBE2EDBAE4F38817B0
+:107D70009329C181FB7FCFD05580F2E1DDD149FC51
+:107D80003BCB86CA0CA6F1176684E555062BFC4E44
+:107D90007965BE947B1E17935716FCD3C0C09F0312
+:107DA00004FC2E26A7F0C754D8831C12722E52DE74
+:107DB00084EE59FC9BF8774604FFCAE7529F49B806
+:107DC0007E19AAF3BF3724F366DE1776ABBF2F23E5
+:107DD00079549DE9A1FBC76C5DC641ED79BB09E50E
+:107DE00021F4DB709F1A40BF439EBB6F4819EF28F8
+:107DF00005BAD8D0C2EF01C34F33E6C1CD15EF2D80
+:107E0000702FBF0CC77B680C8F237B3F748CC7EF30
+:107E1000A11FCF9C5AB906F379328D0CE9EFD97FB7
+:107E2000F0EF5C9574B59725205FF9F9B94CC82F30
+:107E3000386DA4EF46D43207E543BE17EFABC0F769
+:107E40001B7FA9887D343CEF457AFF25FFFE61E367
+:107E50002DF6788C3B15F77D6D12DA05C5F7A792E4
+:107E60003D769C35B4E37AFDCD2AD127D8E3077B54
+:107E7000E1FE9544923B874DED2F6541FBE15B921E
+:107E8000D1D2640B8CECA001E86381E0AB6A919FD6
+:107E90008170B1E2779800BFF8770301DFAC771EFD
+:107EA0009D3393FD7AC800949987F623A7873AF10A
+:107EB0003E8C67C5FC44A6EE2DC038BA9453C64428
+:107EC00037D9A79FEE995F88FC694ABDDE8BFB3BE3
+:107ED000B3774921C2E1B6312AFF1E78F376FA3B27
+:107EE00005963D77FB71DFA7117868B76EE4DF1563
+:107EF000967F37D522BEB378B171D7CA715B427F06
+:107F00008FF5BBC7DDA2CFA7687C20C68ADFB798F4
+:107F1000775FC473E1E744FE3DABEA667DFD610136
+:107F200017996F10CD6E8DCC57B87F8C4D7F0FEEAB
+:107F300022EFCB7C8587059FB07722CEF11A6E7336
+:107F4000A09C3D0BF4C8F57D8315EBC7F11E9FD2B5
+:107F50007DBCCED58CEE6D5C17C17792CF0E08BF7D
+:107F600003EFBDA05DFCACD9B912E5EBB3B17D1553
+:107F70003FC9D39DC9781EB05BECFFD9D0DF297013
+:107F8000955C07FAE159715F68B7C0CF9F4FE7D1A1
+:107F9000DFC1DD17CC2B99A3B58BD5CE4787939C3A
+:107FA00036D0B92E7E1FE1C91EE070CD6855B74EA0
+:107FB00069BF4BF970AF58B7A4D7C8F78F0AF9D883
+:107FC000B9DAC74E68BEFFEC157E983C4FB5A438B1
+:107FD000757C3BB178ECE1310561BE60076E645998
+:107FE000745F279FFC94A362FFC0BBE3311EC032C5
+:107FF000F4DFC1FC2CE23CFEDE901CFB7EFECB6776
+:10800000C5E0BF68ECFDBBC5FE43EB3A0F35A007EA
+:1080100055C4996BF07C14F8F453B1BEF176037D2E
+:108020006764C2CF5B1F267D72734C1EEA930A0BF6
+:10803000FFBB139837BD4203B74F05BC26FC94EB3A
+:10804000EB098DBCC471B6D9C2ED3563F97BB22E94
+:10805000F729D7F759B1B8BF15251FF8DF5DFE3FE7
+:10806000FA813CB6008000001F8B08000000000071
+:10807000000BAD590D7014C7957EB3B3B33BFADD59
+:108080004512482020BBFC1829081884004988F2B2
+:10809000AC7EB0B82079650A237C4A32011B0961A5
+:1080A000CC1AE288A452B7830558C5512E99F8120C
+:1080B0002AA5F8C62A705439C759127CA5C4602F66
+:1080C0009CB145EC23F25D52C555EC631D30062C86
+:1080D000832C5F0ABB8E9CEEBDEE19697B65E17057
+:1080E00075A2A8D69BF7BAFBFD7CEFF5EB56434D86
+:1080F000ECBFD42900F9BA6AB8A7033C580E003384
+:10810000F03FA459BA1BE06B7F8FBF56120D3AA8FF
+:1081100000BF931D3A3D515B82FC1F8CF14DE2D7AD
+:1081200055F9ECF9A04B302E3F4DF7260E95D0E7D0
+:108130006E80E5381809777851125D867456125DA5
+:108140009E42F770F96C7702FC99F4DD62DF1B70D8
+:108150007DA9946867BDE13553CA001A4F48FE8374
+:10816000018087AA6E7A00F76DA849BC51887616FF
+:10817000C7FD46661A7E3F21313D2BE20596E9E6B2
+:10818000EAC334804781FF7863922EE7215D2E5940
+:10819000738200A3F473EFF858A1BBB85E346F2A62
+:1081A0009FE316E783A7ECEEE6C30A7BFE1C363F8F
+:1081B000EEBD8BFD3756816E654E94BBCF91BB8D66
+:1081C000B4B33EFA6C3DDA67954C94BF9FE471BD41
+:1081D00041976B07A0BF36C64B2C7535C615382E98
+:1081E00036C5171A660957574FB1F74EFAAEB6D7CC
+:1081F0004DB63720CE8FDFC95F3513E6DBB8681385
+:1082000071525735AA431E8D880B5CE7B170DA2195
+:10821000F051FC6D5C9B2B0C1D79836930865301FA
+:10822000D7E64AA316FDF81838F215968E74D8359D
+:1082300026CF717E521A9B5F84F8F1019FBF3B5E8F
+:108240006E917F301E8CCF68F71D701E4BA1AB5214
+:10825000F2C2C635CBCB32CA0BC99A2F4DF4CFD35D
+:10826000769C3F96A03986FB0F56C337C334CEE1C8
+:10827000E34B948DE8B71FDA72CF39714E4FF2C3DA
+:10828000CCF138E34F1C8A04BB999F36E539766FF1
+:1082900034D6CDC3F939B048429CF4E9EBAD7DB397
+:1082A000687ED80D1AE6026CB0DEC67AB2C9F6CB8B
+:1082B0004BFA830993E52D4894673B180030EE276D
+:1082C000245346BB7650DCBFC0AEEF4DC48D99320F
+:1082D0005F57EE30DF9C385F4F990F4ADEDDCCB739
+:1082E000E3B22E256EF52971AB4DA15B1CDA12EAC3
+:1082F0009653CF36B5050F14A21EED2F4A7E926A13
+:10830000A88979A4A500FF12378CCC0AC26740293E
+:1083100044CE9BF1CD0915B1DB44F58BE1758BA5FE
+:10832000631CD6537E33FA61435F427889EC2F4059
+:10833000F97F8D3F62A998070FED7B4601A4DF8985
+:10834000B75A6E8CD7A6B25FBC41EBB9F76E4BAC97
+:1083500093EE80CFEE143B7A52683345FED92FA9B5
+:10836000E3FB52E67F3F857F28853E924277A5E674
+:10837000877FCD34AAF7FB2438085F9E2797EC78D7
+:10838000FE4E8E95A968FF47F1EF58FB0BF01CEBF2
+:10839000E438FF58EF309271AA00FFF9DB3C30E976
+:1083A0003C5026A94F1727C34951EAB9C5F9B51959
+:1083B0007FF9D520AEB7B5DBEBF7220E2FA78116DC
+:1083C00047DAFC83AC1D43A911C4692E9D6B6AC0BA
+:1083D00047FB5E3EB70C0EA23D3B06E4F7BDD9005D
+:1083E000AF3FE365763E7242B6BC2C7E7A6603EA06
+:1083F000DB66E37ADBB392E95D8C74A4751D2C66B1
+:10840000349BB7F55DEE9FAD31C90AE0BC6D96F2C5
+:10841000A784CA6D1C25B701E7B79E94AC38F25B00
+:108420008F88FC1D3191DE09873E9117D3E8FE53FA
+:10843000A2C8FE8EFEB948BF60FEEF79F79345AF44
+:1084400027C9036805E48F29A1ACBC2B0B89046DF7
+:10845000946AAFDCE233BEE0FC72C65BD1E145AFAB
+:10846000CF07C8043D3F44FEFD7E2E1E82009BDDEB
+:10847000A0C7C8AFEEF8D48DA877E7B9DC52C2C167
+:108480006B2E50CB7368BFBD36CEB8FC50D40058AD
+:10849000007023DAC6C6CA13CFC885E8AF9BD2FBEB
+:1084A0004FAFC2F9C31FBBB45E20B9081607941BB7
+:1084B0002AAB0A9490FC1E46033C69E38EE7F1EA7E
+:1084C00013A7E542A46EF45FCA20FDC19FEEA2731C
+:1084D0007CB76DF3A7119C84F1FB74C86D4190BE0D
+:1084E000201FE3B4DB6F030BB4FC0EE4BF765E0128
+:1084F000EA571CBF5DFF2E4694F6BB8DDEC1F556D4
+:10850000D9EBB51E91C1580670FA9F724F56125E94
+:10851000327C7E740B5CEF93D93E5755DF0BEB70CA
+:108520009FAB3DEBA701E6CD23CAB04743BDB45393
+:108530004DD93ADAF101CAC599BF2C99FAA2CA7A83
+:10854000584FF32AE36E08E0BC0FDC9A44F1BF7188
+:1085500019111CA4FC70D7539FF0C8AF659E57A794
+:10856000DDCFCF0F8EEB55536E9B61FB3712E2E7E9
+:10857000CB873DBF6A24F96B47153FE973E3A8C277
+:10858000E6B7235E5D88ABAB7D12C37BFBEF658DE9
+:108590008EE26B7D12E7232E55C2F9E38AEEF14D90
+:1085A000C4758D2387F824DC3BF86ED7AD35407653
+:1085B000D97856F1DF28F651532076C08FFA6FEF45
+:1085C000FBBFE13815BF6D84DB0CFCA5144A09B76D
+:1085D00023910DBE7892FD93E176280A0C6FCEF7B9
+:1085E000DC1341A910C6EB81590D4511D4BFD3034B
+:1085F000456E8AAB2B5D3B46FBABD98BA9B9B895D1
+:10860000C6C70E97FF2CE1A803CF03EA6F6E8482E2
+:10861000CCDFB75C5A1DD1302FAC4B383F5111D451
+:10862000280FE41A5724C6EB994AB81BB4FD185614
+:108630000F0DE6A2BD3F0F397D24305CEEF2737E54
+:108640009D9CC9FC3CD28C7EC675DD66F18FAAA8C4
+:10865000FE0D2860D17CFC62FB4F1A65F527E023F4
+:10866000F9F0800C07490F5D61FC00A87B290E1B07
+:10867000A86EE17EDE02170492FC9916488740D16D
+:1086800038FD0708FBA8EE74DAF6E2013C380FF576
+:108690006AB6F5CE28CA11E49B33B7B2F8676933DE
+:1086A0008475C1502EF3FD030C078DF42D8FFA5BFA
+:1086B0005ED73634233F691DA5EA935A32236CE313
+:1086C00000915C40E78E52C5D771E4C233D75C831A
+:1086D0006C66FFE53BE16441B55DDF8AA19870D22D
+:1086E00029F1FDCDA9601D63752002B4BE83879773
+:1086F00043128B436775808DF2328C1BE236A1C02A
+:10870000ECA52C7EFE5924DF9491F3E700C6E874B3
+:10871000E822BBAF35ADCA79622EF65BE7421F187F
+:108720006EC45FD3B29C97E720FDD6E94B9C5E9266
+:10873000B35C417AAF74C5A8457A30A4BF46F5B39F
+:10874000B3DAEF9C9F6C5DFC7E86BEFFC30AE36CD0
+:1087500008BFEFF4647649D847DCBC677836DD178C
+:108760001CF9C4A9C2598894711AF5D34A8806869F
+:10877000E3C9C65B21FD7CE80BBEEFC8C038E33E11
+:10878000BB5E7E2F3B80EB6E233FA15D5090C9F016
+:10879000F884EDD3A1C6F83D71F4DB8751C89B87FF
+:1087A000F91470197F243D07826FCEA6BAFB614F82
+:1087B0006736D5C38F5F92B57528FFA80C1CF7B735
+:1087C000E5F8BDF8BD7ECE825EC2E5D0F1A7667E3B
+:1087D0000BF5BD64E37E28C8FBE5A1E35E5B6ED3C9
+:1087E000515962E7CC65D277EC7C39BA81E9B5366C
+:1087F00013CF153C974FADE4F1F2BAC1CCCA612357
+:1088000064E377054799DD47AD317E369D43812D81
+:1088100005BC8F41E860DDBCDFC6F3FDEEF8698979
+:10882000F0A6F9DC646F233797F8A61BD771A9A0CF
+:10883000907DC5D0E3A7BA835AF78CE6B2FCD4E2A8
+:10884000986FBBB05FA0636217F98DE8E39265068D
+:10885000A94F50D879FFA15D3F52EBE84E18CCA646
+:10886000B8B6F56C61F9E3D4CDB17CF1BBFF5FEA3A
+:108870006576B55D2F97C2D2BB3CE7F3AA93FC5F48
+:1088800027B704DC64DFD4A252DEEFF07AD59AC6B3
+:10889000ED71E2B1EB2773F3D93950EE65FD5BABB7
+:1088A000AD0BF4E4B2F81D08CA407D41437F2104BA
+:1088B000F0D3B67E0902789EAEEBCF6574F667D32F
+:1088C00019DDF0D3FC6ACAF3B17EFDA70B187DED6C
+:1088D00085B7CA8C9271FF8FFC9EFB1F52EA279EC0
+:1088E000A63FAA42FE8376BD1C011E9F113D83C593
+:1088F000C7B173BF5DE77CE5625D9CA28B7531B744
+:108900005EAC7B53C362BDCB6F9E23F0A71B5F158C
+:10891000F8856DA5023D2B5229C87F654FB54007EC
+:10892000CDBF11E4E7763D20D0F3BB1F12E4171C46
+:10893000D92CF08BAD7681BFB06F97402F8A7D4FD9
+:10894000905FD2FFA4C05F1A3F28F0970D1C16E875
+:10895000E5833F16E4575EE815F815899F09FC5535
+:10896000577F29D0AB877F23C8DFFBD919810EC180
+:108970005B827C8DFAEF025DE7FFA3207F5FC1255C
+:1089800081BF36F091C0FF5AD1A702DDA0FDB7200C
+:108990001F5E00593AE647F74AE33BD588B766D7EA
+:1089A000A19FC4F1FBC8C025379D1BCAD725C82588
+:1089B000DC7F49FEA4E6DFDFA59C437F86CC6FB851
+:1089C000E87D09CB10CC9D3CFFC26AC043EF509BB1
+:1089D000CD372FB0FA449FA68DD7ADCD6A669C9D4A
+:1089E000935DCAD058FEA3FC843A66D7B762D8E735
+:1089F000BFA28ED7AFC9F4A7CCB9E2AC87FADE54D8
+:108A0000F01CC2FC9074B40DF356C2C3AF05EBA2C8
+:108A100074F2CDCF995ECF69AA3A97A45BFC64A7A4
+:108A200004866B7421E5E73A9028DF6212CBCFC948
+:108A3000D6F161FFEA4E8AC3145D057792FF72EBAF
+:108A4000FD023D355C20C8E7370704FE74A348E00B
+:108A500017B669023D2B522EC87F658F2ED041B3C9
+:108A60005E909FDB1516E8F9DDCD82FC822386C07F
+:108A70002FB6DA04FEC2BE88402F8AED11E497F4C7
+:108A80009B027F69BC4BE02F1BE816E8E583470497
+:108A9000F995172C815F91E813F8ABAEC6047AF50F
+:108AA00070BF207FEF6771810EC13941BE467D479F
+:108AB000A0EBFCFF21C8DF57F0BEC05F1BB826F05B
+:108AC0001FFD488B53FEC02B92762C4079F889C04D
+:108AD00057F2B0DFA6F72348D7E8DC4FEDB71D9C6F
+:108AE00035689F0BFB74B822EC1DB54386441AE22F
+:108AF000EF76F51CA70F575599CBB1BCAD87E7A909
+:108B0000EFF09912C31D1DC52D393613FB0076C435
+:108B1000A05E3ECA1324725C41935839D5A075E219
+:108B2000F78CF1BC9939BAECAFCF9B747AEFC4F3F0
+:108B3000B3BCC618A57AD21E3BBE86EE1B6D6A3743
+:108B4000CBEB3AB9C497C073EC7C1A7F1F4C5D6FB6
+:108B5000AD8A7E4CDAEF5C5AF7CCD23BD49DB5EAB5
+:108B600010931F5B57E1EB4A68CCAEA4F59FC67B20
+:108B7000901BAF82DD51CC33AC3387A37E463F1BC5
+:108B80002D60F40FA301361E8916B1F1C7518DF186
+:108B90007BA2E58C7E2EAA33DA8AD6B3B1371A6669
+:108BA000DF8F469B19FD02DEEF69ECC3FB3D8D3F75
+:108BB000C37B3CF15FC4FB3BD12F454D36C6A25D64
+:108BC000ECFB2FA3DD8C3E113DC2E87F8E5A6CEC8E
+:108BD0008FF6B1F137D118E39F8CF633FAD5689C44
+:108BE000D1F1E800A3CF440719FD7AF402A3DF888E
+:108BF00026D83810BDCAC6DF468719FFEDE8678C56
+:108C00001E72411BF5332B6A78BF0272A6CEEE4D61
+:108C1000D50B7A097FCEF7EDAB8C1535F43EEB81A1
+:108C20007EAA5B4F662C560CF6EE2ED6B9D4385C75
+:108C3000B7D757B0BF2EC3759519F7F47622FEF655
+:108C4000D2A51B71B53727D04B779190BDCF53E993
+:108C500060A6B17E95F7A5AD361E218FD7F1AD3652
+:108C6000945BED3C584E782C62787CFB6EEAB873CE
+:108C7000CFBD5E6134915D5B33231EDEC669F75064
+:108C80005FDCE0E5EF37C3E764AD3730F9BA3BBBF3
+:108C9000D76251BE03FFD56B33E97CACFF1FD920EF
+:108CA0003F9C57B29AE9FD628B6DEF961A97307E22
+:108CB000BB32BCB906C7D657BFCBCEC596C7E7FBFC
+:108CC000C8CFF7D3D31FE675130414F6F712D0CF2D
+:108CD00006E9DE88174BA23782C9C6072A8CED64E5
+:108CE000CF266CA0894E48F0C26E89ECE1F84FD5D2
+:108CF00063770D7F87DF5DE312C6C395E1DDB4CEF8
+:108D0000C395F77DC3859F7EB12AC0F46B84E1E7EC
+:108D1000488F9DB38D8B8573C7DF095A6090E90733
+:108D20004EDFA982736F67EF072D52BA46F7F6033D
+:108D300021FE6E63BE97661DC3ADDFB5EBDA484416
+:108D4000617868792FCB423021FDC412AA0B5FC72E
+:108D5000FB8AA774BC0EB620ED2AA5FDEA95A9B83A
+:108D60004E4BB9ACD153A9531F511E3C58CF3ACAF0
+:108D700083CC8E16BC68F0FB0FB077886F9EF4B280
+:108D8000FA77B6C2E826FBDA2B64D383F7BDF61C6C
+:108D9000AC12A8DA532E1E77F3B732ABCF6E3F7FFB
+:108DA000BFD8DA3365A91CE0F8685A0470C18E9701
+:108DB00013FFC7BA704CAA4F88AB1E8AE38D5FAF12
+:108DC0002CA2F8EF7CB5224071ECA4F5F3C6D727AE
+:108DD000BDC81FB2AFE4F9833C4ECC3FC315595612
+:108DE0002FEA795A863DC7BFA01E9EB1E376BE40EA
+:108DF00061EF619D769E39FC576CFD5EB171D67056
+:108E0000E6DCAC0E5CF7B10145A3F75D284B94247A
+:108E1000DFF7C7F0BAE7ADE9F392ECD8D9FFFE1A55
+:108E20009DDDF713250F64717529BEFBEDBC74F64B
+:108E300051A8FFA2C323CF3D34762F9B437EE2751A
+:108E4000DFC19DECC9329ECF4CB683E30D717F9A92
+:108E5000E13E7B0FC3FD48E4836F535227D085F476
+:108E60003E62FCA3DF43F8DA0C1A1B1F86301B5B43
+:108E7000111E14B76D60B1713B240E2C43F9B0F98B
+:108E8000ADD9849F9D305C5B807EDCD0B5F76C01F2
+:108E9000AAB2BEFB99BAE9A8F7833D4165068E4D9B
+:108EA000471FDF4F7F3EC2BCF937DAFFA11743FBF4
+:108EB000E9FD15F3E60ADD8B1AED7B3BE24E9711D7
+:108EC0005772B6AABB307E0F1FE6F5F182EDDFC305
+:108ED00095FA05C253CB931C67C3A7BC2C7E63795C
+:108EE00053BEFD62A18BFA3E607F0FBC79AAD8DA2F
+:108EF0008BFC76EA7BE5E43ED0398F791FB01DFB11
+:108F000000C2EB7585E3E23AE60DD5CFEB12AE5326
+:108F10003AB13F70FACA0E39C2FAE95B2E3445A65F
+:108F20007BE60F98BFDA546B31F905CFE111B21728
+:108F30001261768F6DCF57F93E538C434B699F9FDB
+:108F40004B2CAF92EA3B8C665011E2EB3EADF0F752
+:108F50009854BD53F5F17AC054A93F2E7FE373EACC
+:108F600027CC6A6E87F99FDC8E0ED9285821F33EF4
+:108F700085D6C573224E7DB2E2522DF64695B2FFDC
+:108F8000BE49F695FC7CFD81BFF077677316B0FA99
+:108F900092AA4FEAFEDE74AE9F73EE74C83C1E8E3A
+:108FA0003E85B5FC3D1366EBCCEE81607E911FD70C
+:108FB0006FF47C95F567AA6CCCA845FE3B69FCDD97
+:108FC000C8792772EEDD70BB7326FFFB509CF55706
+:108FD000CE3D0452DE5DC2AA5FA1B8343A7954AEE8
+:108FE000087934F62E5325DE67D6D3793097EE33E1
+:108FF000EF3A7E12EE33FF0BDF219D2A5021000055
+:1090000000000000000000001F8B080000000000AE
+:10901000000BBBC8C6C0F0A31E8139D851F9E8388F
+:10902000174D7E23337EF584F01AA0FEE540BC0880
+:1090300088E702F10C209E0CC47D40DC09C46B590A
+:1090400019185600F162209E07C43381780A10F780
+:109050000371172BC21C07A03F3CD9F0DBF590151C
+:1090600053CC9713C1DE4BC0EFA378F8E373DC0C4D
+:109070000C8778107C535E54F9F3DC08B6802065C9
+:1090800076C903F50300446FD3A5800300000000F8
+:1090900000000000000000001F8B0800000000001E
+:1090A000000BDD7D097855D5B9E8DAC3994F4E76C6
+:1090B00006C24908B03300613E04C480A81B8888FA
+:1090C000945E0F8A16ADB71E0625322522559EB531
+:1090D000CDCE0004418C80350AB5072A880ABD51DF
+:1090E00051B10DDE035A0D8A2D54B44EB5B1B63EC2
+:1090F000AC0A11EBD03E5BDFFFFF6BED9CBD77123E
+:10910000A0EDBDEFFBDE85DAC5DA7B4DFFB0FE6971
+:10911000FD6B1F5F7800932F64EC6BFC03E51A0F67
+:10912000DB278D66CCEF8FB5CF655087FFD804C69F
+:109130005663990FFF2565958D672CC0F81FA550C4
+:109140007ED71761EC32AFCED839F0209A4DED3D85
+:10915000E11A968047FAAD4AA27504B68C32EC3714
+:10916000103BC2F3A9F5FE37878C636C7B63B1ECCF
+:10917000837A0993A8FFB6A6E22083F6727DB4A095
+:1091800003CA87776517C8D04E5FEF654A114D292E
+:10919000B33CC68AFC7C1CC64C86F5818CD7B7379D
+:1091A0005E96C9C2505FBFFA1365541A2EAB2C35B8
+:1091B00065962AE36BFF9A613FF5CF1D561DC61FCA
+:1091C00087FFE883FF57C8C7F5F377CFFDD647EB96
+:1091D000FD4993CC7CACFB3A1EDE55FC6219AE1304
+:1091E000DE2B2CBD0E5C9F313EBDBE7F743D041F47
+:1091F000AE27D59FF0A774C1ADFF46CF0594693265
+:10920000BB5DA792E8707B6DF2BCD2418C15A83B88
+:1092100064402ABB5D4DFA355C87691C8D42FF0AAC
+:1092200066F5672C17EA93041D2795C926F60F9556
+:10923000417FDB7AAC7536D532660C013EA8F5531A
+:1092400099E69758340EE35784AF9FC900DFABBF50
+:109250005FD381486CC8F2EAF5B0FE61DAB40FF072
+:10926000F98BFDA7F9919EAC43FD7D07C050067FA9
+:10927000BF2E66AC51DD95A58D40D2C3731BDC01BA
+:109280009DB7B3D6318CD9EAF07E52D83B57867160
+:10929000BD038C681CC7ADB2BD87712769572E9678
+:1092A000001ED6691BB7388DCF476B356600210F7E
+:1092B000D69651792FD475ACFF4D99D31A4ED3570A
+:1092C00013FCBA7CB24CCC71D7317D3BB26A33FE11
+:1092D0001F8CF3AC071109A33EC4923B24EA5750FC
+:1092E00005F5CDB3F2CA892E95401758E76649FFB8
+:1092F00003F6372FF2EAD8EE5EB57916F6DB1CCF0F
+:10930000964DA93B7DF2E3B2D917D63FAC12F017C8
+:10931000A1FABB43609C831E66C4A15FF30D2C8938
+:10932000F8CDFF328FE963A19F01F887762F06EE13
+:10933000F9D007EFEF9AEED57D521ADF06FC45F81B
+:10934000270CD42E31E1FDA61B54562F75C7BB9BAD
+:109350002FCA9FB3BD473E89733EE9468FE99C1EE5
+:10936000DDE830F3F474B0CA3B6A93EC3DC0E5DA53
+:10937000DA28D16343AD4EE51AA40FF0DB7A6C9A7C
+:10938000DF7DFFC076AB42F9D21464558F211FC434
+:10939000CA7B6C67958CD5919C598B742BA0E51872
+:1093A00088F4E0B8AE7A2A580AF3E3FB89E23D88F4
+:1093B0008226A9EBBDC900BECC747B3304EDD70671
+:1093C00078FD2DF33EC32C4CD73F649B0C7352F7B2
+:1093D000F71B3C9D863286B1A7CD6B8C1101C7F877
+:1093E000068E6F5F9F7F52F7F13604F8FAFECEEEDD
+:1093F000A4FA1A09A05644190320A05F65058D4BF5
+:10940000F59DD909F3B909E9795E6709D3043EBF2F
+:1094100096C50F22FE9352F35459C2793BE6305859
+:10942000573BF6877133CBF83CEDE65AA3414DE349
+:10943000E515D668221C96FC5504BF28A6DF5422E9
+:1094400028BF77190AE048C9611ACA7716E37A413A
+:10945000D60CD6114ED343D1D4F7EDFCD5C517A207
+:109460007DEF74E4EDBAD6EF696E5060FD07F1153B
+:10947000D4A70CAEF8D524E073DF114F0CE70F2012
+:109480005E8135025F296C623636AA3114DC4743AF
+:10949000414642ED67B8E9802F82A5052C69933BD0
+:1094A0004CAD89C647A6C785F98E633B0B5F679AAB
+:1094B0005FED6D7ED520FCAC11F3BBE7DD1088CDF0
+:1094C00041B9366562C5A58CC61924D37E16FD9AAE
+:1094D000CFD765EC3752E27A3382E367A7E188E0C1
+:1094E0003C305F66058C6BC3AF351EE085E1785676
+:1094F0003FAB3DC02BC677E2C53D0EE02F1ACF38FB
+:109500001DFDBFE4F49FEAA2BF7196F4FF6F1AF746
+:1095100053E06194C32B267B9326879F215D2CF813
+:109520002D782DF8DC70AF918CDF4C2A12F64F7637
+:109530009A9E9F62BF3EE9F9BBF1118B5D8AF336BB
+:109540001FF5B0DB4F33AFD5DF3DEF8A97957C56E3
+:10955000DC7D5EF77ADDF3667F39941939A052908D
+:1095600077004FF5755ED257CD952C89F46F6EBF9D
+:1095700088EC948D323B84FC6AFEDAC376C0901B83
+:10958000519E92DD308EFA253358FE65237A97A7D7
+:109590001BC13E30498F425B289B253607E572F69A
+:1095A0002EAEC79A3DCD970CC6F12F92C7EC60F452
+:1095B000FCDDBEA02F9A03CDB3A6D99EE7607B7CCD
+:1095C0009E915C3B785CFA79C10DB981B9617AFFF3
+:1095D0002E8E67CD9F335D66A60DDE2C2F9B1BEF75
+:1095E000619DDF97645AE7D342BFDC2BF44B5650A2
+:1095F0009B8BF8D0EABDFA76C0C75D178D2F9867B0
+:10960000E3A31F8AFDD52CF4D3C13BF224E4B32C91
+:1096100083492AAC2F6B264857C0D7D39E585D2468
+:109620008BB11B2566D4C07AB28E375F8572D7ACFA
+:10963000DBC77CD0BFA012EA1AE8E9488ABDD00790
+:10964000EB8CE4F056E955A301F447F2E54D0DB873
+:109650008E157F845E30E504B559A921FCE7F6A894
+:10966000CF7EF247FF9C24C03961FDEA2397133374
+:10967000251DFC33F10F4E3E781AE11D827047A97B
+:109680004C48CCB1CF34FC27C0A1E13E1B45F6F7D6
+:109690006415F1F2218BA1BD3BC11F7BB30A59A117
+:1096A00092C51AF4EEEBD12A9DFB0DE0996A87E78B
+:1096B000BF0A8E6B99718FD4A7F7F1BAEB87C48F6D
+:1096C000B1FD04217FB32A934A227C3AB82BDE44B1
+:1096D000FB4DBB98C3DDDBF86E78D7097CC27C7B81
+:1096E000A473BACFF7DF850F18F7599267FFE2B876
+:1096F000597F70CBAB662157522A97F356DD6058DD
+:10970000F77A19F975A8F3C82FC43FA8A70A633FD1
+:1097100041F97654F2123ED42897DB97791347111A
+:109720002F6C2673F88F7E2DCE50AE790BCA321374
+:1097300068BF85737BD4FB4DB52DB3548FADEE61FF
+:10974000C24EE770788B593207E1FA6ABE7ED9C8FB
+:1097500074BB7C21F7ACFA7D5DFD9CEB8571EEBDA1
+:109760001EEA1E6DFC58D47B1FE0FA7B582FC0F117
+:10977000816493F3AA66325CF77D370CE6EB5FD029
+:1097800033FEF3FD5B66A93969BE244402FF658997
+:1097900071EF88B2662513EAE3C0BE063E2C29D4D9
+:1097A0000FAAC097F985A916F4C3D7328EE74DBE2C
+:1097B000C45F108F1ED934FD45C85F35347FA38048
+:1097C000EB22E523FFEFA1BEA1A23813E5D8405953
+:1097D00072E825ABDC04721AF1793BF873587EF11C
+:1097E000DB21B4FEDEF87D4BAD7F963AC8569FA9CB
+:1097F0004E477EDAB2A4FC682580BC2AB7B49C74BC
+:109800007595A4225C0189EFAB2C99CBCF4DDFBCC1
+:1098100099D609F8CB9271FDB91C6F8CC519DA572E
+:10982000F847B5E1A3C4300CF40B2D7C1403BA2423
+:109830009827733D8BA574C243810C70E56B350688
+:10984000E2C93F493FA8E8693C80E3D35402EDEF09
+:109850003C34A8FC76DB3EBE46E67A809572BB813E
+:10986000A931D29BBDC98F66C0D3080F914BC27579
+:10987000AE1175ABDD5B526238C2936B04497EE476
+:10988000C69312C275AFD07F56DCA351C0D53C251C
+:10989000487CD7D85FDB86F18CF1D67AB64A6E3E2B
+:1098A0001B2F9F93C68FC567B986919200CE9427D0
+:1098B0003111E157F4668DF64F3CA581C7CA564970
+:1098C000027E931DC1F1B2051D2C7ED7A2FAF6DBF4
+:1098D00061DE19822FB263AB6F44BF2DAB5425BF3D
+:1098E0002EBB632EF991DEB72F21BF139E93FF9AF3
+:1098F0003BDD24F1921FD52723BE1FF32466E0FA37
+:10990000B4312B52387416330C2F8C7BA7C76048A8
+:10991000377552C2C0B8C0A66F8E67736D7CF56D87
+:109920008417D70DEE77329CA6FB5D0A5FE71DE337
+:10993000B2030BC3D82E48782961E30C8C5F140363
+:10994000D969BF22FD19D1FF6A9CDF57D97C80CB32
+:10995000115D46BC00DFF7453CDDE9E98C62BF3BA9
+:10996000BFE99D93E4F838867CE997052E74F80BDF
+:10997000F8F1897AA9ECA175F9111F083F2A6F58EF
+:109980009367584D4A02F91A99CE6288463FE267BA
+:10999000541A3FCA0893617C2A33CE62063450A21F
+:1099A000DA81C11C3FCB083FAC26857456C3A6891B
+:1099B000FCB945ADF9DDF7018E2DED4ACCD46D7CB7
+:1099C000C862E46758782A5C02FBAD07FB3524E4E3
+:1099D000D90B52E256D926BFD7E783FCB0C5BB2CC2
+:1099E000F9CC46CCA6F6BEC254743ECCEB8F46C72B
+:1099F000D03E55358A6FACB7647E17DFD773FF183A
+:109A0000ED1DD8EFDE28972F81D204433DE6D79B8A
+:109A1000A9F415727EB4DE7B572AFA1F50BE8DE082
+:109A2000F26F758CC7BFBCFE14433A84814C68B793
+:109A3000C37688EDA019136C7606F2BBCC52B086C3
+:109A400047A0E4F18724CDEFD3838EB89877A5970C
+:109A50008F0F9625EED7FCB77D7CBF09FDF39614DA
+:109A6000DF42F26081D87F961C88CFE6FAE9581968
+:109A7000C1BB43C4CFBAEF770EF71730F611C49BC2
+:109A80009AA038E4CECDF38208C7CE96CB3213E14C
+:109A9000DEE523DABD293018B6813CC5724BAD46F0
+:109AA0006597BC1471A5AD422E58CF830ADF0FBF56
+:109AB000167272A73F1EA478DDB357CD180AA82CE2
+:109AC0003DA6C45026F4BBAB35EB74F3172E71C61C
+:109AD000119972CD69D7BBF2EDFC59CFD9DA3F2B82
+:109AE00067E4BE1F827F9CCBCEFD5A3973FF2F6A7D
+:109AF000A3B39EF3FCEB78D92AE211C186ABEA301E
+:109B00001EC1521792BC2C16DB34BF8991BF56BAC6
+:109B10008225C987F9EA6BFEBE2B0E6A84E7427D77
+:109B200010DFD36C67D3BCDB514EF47F556132F04C
+:109B3000D320B15FD9661E97F2C35F8C3F51680591
+:109B4000C62D59C092296857D2EC8C37E6B3F59FE1
+:109B5000A0DDD2DF151FCBC77D3F0ADF3BE35F856A
+:109B6000E0575694FFEB74F833D261F8FF7B3A6C00
+:109B7000515B039AAD7F3F89C5915FFB2DFD833417
+:109B8000CFC6AF0185EB0DB632CCDEB3C5F9FA49CD
+:109B9000298A3F6D5B224F4779BB05F0407186DC17
+:109BA0008E9F62972FDE59974FF655DEFB17A01C4C
+:109BB000CC53425CEF4D67DC5E604E3904FA2F4FA8
+:109BC000B1D909DB1A2F63DC6E67C7304EAA0B7A56
+:109BD0006FF9AA41F2021D07AD64B17AA8EB82DEEB
+:109BE000959B6B0E78E079F10A46F117663AE95FCA
+:109BF000BC80D37FD07ACE57FD573AE39C208FEBC1
+:109C0000BDB0DEBE60F6DE07B5D2CD4EFEE82BE479
+:109C10007F5F177FE8C00739C007A5CD89DB71FCDE
+:109C2000FC630AB7915DF30FD25B2F41FC94029E57
+:109C300092647FDAC65190BF62F5480F375FF645F0
+:109C4000BE1CD57DDE7F95EFA62ACEFDFF190BCF7A
+:109C5000DB05D5E4AADD2F0EA656866CD74F16DF9E
+:109C600085997109D289C57BB6DBD3F2D514E71883
+:109C700085329D030998262F8F06F15C60AB577BD8
+:109C800011CF57CCD71486FA61EBF28202FBFAB7F8
+:109C900079B8DCDC16E0E53C85CBCB84E2A17281AF
+:109CA000A86F8DF078706FF2DDF263067F1966A9F8
+:109CB000B1F6BAD75557592AC75E8F50BDB13F2369
+:109CC0007F461FC04CBBBE5D93D14A760F5A12141B
+:109CD000B712F2E9D92C7EEED1182ECF64F45E973C
+:109CE000EDE7388DE1E2BECC06A715EFEE0D8FEE65
+:109CF00078B7EE35A259D0BF316B5A746E2EC6C9F3
+:109D0000B87EFF81D02B0ACE09C26E95F2445D7DEC
+:109D100029D859CCA855FAF07EB85E3D1BEC3346E5
+:109D2000EDC81E73CFB748098A733DF5AFCEF87DF5
+:109D300058233925F8F57A257107F2813985A5D0A0
+:109D40004E37C19D6C40BEAEA911F63DA73FB4DBB6
+:109D500088F3433B13EDAAAE76891AD6154FE4ED8E
+:109D6000EE11ED0C47BB78B7765BC5BCCC31AFD1FB
+:109D70006DDE6D62BC14B38F17EB36DE4E319EC9BB
+:109D8000ECE3E9DDC67BC45A9FA39DD6AD5DAB680D
+:109D9000C71CF332E7BC5DEFF3BCE27D82ECC1D5BA
+:109DA000F9D7FBC94F3ADEDFC1576E3A1DCCE77CCD
+:109DB000F65CFEB426E4839B0E79E89CF240BE93E9
+:109DC000FFACF60DB5AC62C920E43793CE0B1BC2D5
+:109DD000DB691EEB7957BBF076ADE7E71B7B69BF0C
+:109DE00051B4F79F968F1B908F81DF1A449CD1FD51
+:109DF0007EBCCAF7F39A3299FC4CF7FBC9E23DD816
+:109E000069E4BF05CACCF346D8E4E4FF2F7096ABF3
+:109E10005C9FAE295BDE3C055C8ECF1AFE5A877EC6
+:109E20007D53697D1CEBAF9A7FADAB2CFA9F076722
+:109E3000B61AA8B7C3F93316A8AF94FEE7C139BA6A
+:109E4000B1AF03CE1F9B7D4F0BE76AE1BFBBC79D40
+:109E5000A8F238C12A4F82FCDAD5F95746513FAEF5
+:109E600016E78471F5CDBABA3036499CAF62BB3E75
+:109E7000961FA3937E39533FDF50358EFBACA9D498
+:109E8000B9DF5E177AC42ADF40E30DC6F70F5279B7
+:109E9000B244BE373948F027C6DD3E07C79EF4BC42
+:109EA000802F4775D66358B7ED5BF807E9158CC36B
+:109EB0007E5DD25DAF6C1C2AF4ED305E5AEBBA3D8C
+:109EC000C394EDFA36CBD2B7970C0EA0BC9B5A5F69
+:109ED000764929C6590E2B8CEC3F97DE9D5C3FBD21
+:109EE0001DF32736B67BC4FBA843BEAEABE5F90E27
+:109EF0002037FB32E20B9E2760D92F5DF3650CBE45
+:109F0000A414F0700AEC3C7BBCB851E8E946A1A768
+:109F1000DDF4FC9BE09347601ECC3BD8097C87E5D1
+:109F20007D504F083B1DCBFF003B3D01EBD85F1B35
+:109F3000A5FA815A9DCA87603D58DE591BA3F7FFD9
+:109F4000595B41F535C2CE2FD82D1B48C7B5C2DEAF
+:109F5000BFBF964DC0F8DD1DB57E2A1B6AB5091836
+:109F6000F7DB531BA5FA3DB53AD51FA82DA3FAD6AA
+:109F7000DA18D5EFAEADA0FA24E9B22615CF2DAA96
+:109F800018D9F50F9B83B7A3C955B45B25BBA1A80E
+:109F900011F4E0B8F4730BCE49D2943B901F47B74D
+:109FA000CAD46E741B28BC9EDB6DC4F1CF6FE5E391
+:109FB0009DFF6796B2CF636B770FB69BDCC2E14320
+:109FC0003D20F53CDE569C77680B1F6FE803604729
+:109FD000F43CDE361C2F732B5F5FE624B04B7A6EA9
+:109FE000B713C7BB702B1FEFC2AF58AA97791FC119
+:109FF000F142D9B1B971F2575A0F60BBECE95A3648
+:10A00000C6214339B11BF9735DC6B891AF903F0FBC
+:10A01000637BE2673655C6388D2E9E637B7ADED130
+:10A0200080ED03A5621C2F1F7FC325DC6EC8AAD458
+:10A03000B6FB611D3B443D7BBABE0DEB211F9F2F3C
+:10A0400032A08649B0DFB20A354982FA20A8CB5047
+:10A050000F7B755A5FCE0C266F87AE1B8A4D26C1CB
+:10A060003ECED279BB1D5097A11EF6E912AE2BE76A
+:10A070001BD00EF83E32A499DADD29CED3060DD1DD
+:10A0800026D3FA2A75C9AFA7CFD7B24BA11FAC7F91
+:10A090006065C764DCFA8B3CCCB802DEDF792397BD
+:10A0A0003FAFA8D553308F20439C87499EB6297572
+:10A0B00060A7860A78FC2AD42FF67A02E5CC682FAE
+:10A0C0009D03860B621D7824C94605C7E03965B833
+:10A0D0005FEC7812D6C5C67AA99E092694960DFB28
+:10A0E00038F370D9DC1EF69DBBFCF4F0548A178659
+:10A0F00047C8CCE841DF58A536C9791E1B9D5E5381
+:10A10000A7823CAF4078A07E2FC23391B18FD5EFAC
+:10A110004DC17C8CD2E9BC3E70D5AE2975202A4356
+:10A1200003001EC06768602A7F61AE0D9E01A9A270
+:10A1300035B9367806A6863E382E0D4F3EC283715D
+:10A14000859B383C9FAA465FAD07B8DCEB2F58E0F3
+:10A150003CCFD1BD7A3ECA7F65BA773BBABE4A9240
+:10A16000AF6FB567443DFA050DE7335502E4350896
+:10A17000FF2AD3CF9A108F881F3C477847D85B5D62
+:10A1800074D9EB357322BDE335D48FD5F076FE77E5
+:10A19000B15DB880C31FDE1B34737AC8CBEB82037A
+:10A1A000FB51BBF0BBF6F1DDF075A787518FF4983A
+:10A1B000B5EA4EF96EA8F715F80749366572697762
+:10A1C000FA6CBC0EE01D0DA580371FE12DE7F8CD20
+:10A1D00086F93FB7E0B5E836DB7BDA758706F275BE
+:10A1E000876603BCA390AE1C4FE1D9C1D3E2293CE2
+:10A1F00090E3293C3BFCAE7DFCBF6190BDCF99E96B
+:10A20000DA20E06810FE71BE7A0638569C816E1620
+:10A210001C2B04DD2C38569C816E161C2B9C743B29
+:10A220005B38EE1270DC95C1ED9FFCB0E0BFDEE064
+:10A23000987396F498E3A2C79CB3A4C79C7F921E20
+:10A24000D63E12F4C854391CD638DDF6513F233AB5
+:10A25000D721DF0CBDCE26DFDEC179CFC17D619471
+:10A260006DB3C9393587CB83C6F339DE1A33C47C65
+:10A27000614EFFDEE7EBB86FB163BE8EEDEB7A9C0B
+:10A28000AFE3E1476CF38DFA399FEF4C7180D96AE7
+:10A29000628347C40114BBBF5B9374F8BBD06E9359
+:10A2A00068672A76FF399174F8CFD0AEC523FC6C6D
+:10A2B00047BB78B7763F12ED98635EA3DBBCDB4506
+:10A2C000BB946C1F2FD66DBC07453B53B68FA77749
+:10A2D0001B6FB780C370B4D3BAB57B54B4638E79A7
+:10A2E00099735EC66EA4F8F6775DE732EE323BEE08
+:10A2F00075C4FBB44A2F9DA358759FEE7CAF32DB2B
+:10A30000FBA2F47CD67819E25C8925E23AAE7B7533
+:10A3100046E2753C02FBD5AAF7A6E462FE371ECCE6
+:10A32000827EFE95E74FF514A71FC7CF7954B67C00
+:10A3300020EA5F5F4C65C9229EAF8578F097AA142A
+:10A34000575FE5315212C1C9E3687E3DC6E3B8A24A
+:10A350003F10D271EE6595D6FAD4A897E26C6AB434
+:10A36000E9082F55CA7366CDDDCE4BDF46FCFA589F
+:10A370001C0F0DBBCE4BAD797AC3A3ED3CBE0CF3E5
+:10A38000796E61C118E603DC2C27DE47FAAFAC5CBE
+:10A39000C9704B7C7151159D3347598D84406A7D3E
+:10A3A000855D32DF1FC3FDA14D9D447E55431FA730
+:10A3B000FF36C4CBEDFCCF3D0AC1AF85B85C627EF1
+:10A3C000337F960DEE2CD10EDEDF88783F67B5FC2B
+:10A3D0006C5314EA996C8C0476D3A6ACC0D4E90013
+:10A3E000875622FA17F6D2BF843D8AED8779BF3EA1
+:10A3F000A862FB818CF4DE98D5050D26E0431BC2D4
+:10A40000E51B1BA76F6B84F5B7FC7BDE18CC53CE26
+:10A41000F9B79545985FD535CE704EEFB1D80FE7B7
+:10A420004B803D3E3E9D8FB7C997087AF1BC6DBA0F
+:10A430009942BC28612B0FC1A038A4D9C74BE77C37
+:10A440006E7C678AF157CDF553DC2C3ACF9B44FBE9
+:10A45000F987B271018E07F3245DF3F43D9B792EE9
+:10A46000524664FEDE86F762AF33EF61B5C873E82B
+:10A470008D0FD60CB8353F41F06BD6FA488E58EBAD
+:10A480002B13CF59D8CCA7FDAA4199916EDF3CF58B
+:10A490000712F63F29254679295E9A50EDF98BDEA1
+:10A4A000708D89EBB7DA3700FC926D7CEB398BF25B
+:10A4B000F1BBEAD3795D157CAD4DBD86E2176A2507
+:10A4C000CFAB61739CF929AA56D395678178EB9E2F
+:10A4D0006751A8519C9F7179DD15777C27906C801E
+:10A4E000FDBAD21F198546F417015EDEA234B74BC0
+:10A4F000D0EE0BB9398EC058F73CFCFEB8C10F61E5
+:10A50000F87CEE7EEE71A1DDB97CFE9AD158AE2DBD
+:10A5100085F14A709C1AF2A325354E72A1EB1C59A5
+:10A520009C4FAB426679FD097F11C6B7C1CFC67398
+:10A5300073A5790CC571BBCE93C1C6A3FC80287BE3
+:10A5400040E4F3303B1FF94B9DE7239EC2A0435EDE
+:10A55000B239A684F35972D73A6F56C3B019097F3E
+:10A560008690E75CAEE2143C5EF13D87BC56C32C9E
+:10A570001588207CE5CC7E7E61C95F94855CFE7E7B
+:10A58000EFACE47CB7F9663BD779D6FDC2AAFEBE34
+:10A59000EDBCAEF77E2A7BDF760ED5E86544EFC5CD
+:10A5A0007B3EBBDF04BA7DF4D887F79B8087257F8D
+:10A5B000FFF4FEEFA17DF04C4043F957FDF01FEF93
+:10A5C000BF15E8F1F13E9F8CFEDFA2873F78E77B65
+:10A5D00050FFFCE921D91832BA57ECC7138FFE257A
+:10A5E0004F877156ECBF88E22A2B9E98EA38FF709D
+:10A5F00097276A793E697A7D495A8FBE4FC24330A8
+:10A60000C6DA44C98CB004F85C86FF84F99EDDABE1
+:10A61000B000ACEFE3D77D491FE0BB1A9EAD04BB91
+:10A620006859EB523A1FC4FA6D60972DDBBD86CE98
+:10A63000D3AAF7791CE76CC0B9FDE42896A97E98E7
+:10A64000C2B36CEFE5979E3F0E4B0FE58154B3CE3E
+:10A65000D5E84FB9FBE1FC5FC2B8D5C794B9DED1EC
+:10A66000DDDF57B37826EAC5EADD6BF9BCAE73BC13
+:10A670008FF11F13BA9FCF3DE5759E0B7FFED0551E
+:10A6800099297CB937A747FD669DCF2D7DE28AD3F6
+:10A690009E039E10F1A233E1573B5F8EF71487A70C
+:10A6A0009B197D304F96DB9F774E92F331054EAB71
+:10A6B000E3E750DA942FDB310F2BF950F618E4035F
+:10A6C000EB1C2ECC847C13E78A6EF9F1C3FE6C2B55
+:10A6D0009677E74339BABB3CF98537F126E90B9702
+:10A6E0005CF9A124DA65F1FB38203FFC41A0FBDDD9
+:10A6F00052677B093E9F2593BE86E74DC16C5BFB8D
+:10A7000009E2FE8E61E8DA78BE6FB87C8347B0DF7D
+:10A710003C4CFC19163351A87841EE91FC42BB0623
+:10A72000CA206BA5F2CFDE62EE27B023548FCC3A5D
+:10A7300085378918DDC8182F408671FBF8C35C7E09
+:10A74000CF563FB2DBD301B695EC69ECF2B5952F4D
+:10A750009877E67EB8DE7E98BF2FEEADE55AEB0522
+:10A76000B985F5FC2E783486F0F5136FFB3293EC47
+:10A77000990230D370BDFD5907D507E212A02C62B3
+:10A78000893A86F2CA8853FE5B80BD4DFA4336652E
+:10A79000E9EBE1697AF9FC11334479A5DC8EF20A20
+:10A7A0003BCAA2AB2FBC9AF2296E918D3712DCBE48
+:10A7B000CAF60150DE776E3997E387D36FB3F09B0B
+:10A7C000366738EDA8FE3EEEC758E5E62C41B72BBC
+:10A7D00004DDD4B834CB96C747F82AC0D8EA8EA98E
+:10A7E00064BFA87CFDEEE7D67C682FCEE5764E8769
+:10A7F00064CBD71BEDE3716FB043CA308FDBA73555
+:10A80000632679975E45BBA3E3347126CBEE58539C
+:10A810009BA0F23C0C129F63B34F85BDA30AFAC004
+:10A820003CE7FC6BF3684C1DC4F906F5D55B52E2BE
+:10A83000421CCF8FF9A511B4BF797E9422F2C32CAC
+:10A840003FD51AE7121F97D35669E551F906AC3C7C
+:10A850008EFE67F3E4A8D8C771B23F678876805F41
+:10A86000B253EE9684BF24F9C57E62BA9697DE4F46
+:10A870000A987D9457078063E943FE5690AF92543F
+:10A8800086709F001F2EF615139E3258475A89C3B3
+:10A89000FCABCFD79298BFA802C2946C2A53585AE7
+:10A8A000FC82CF3DD93C8E1F81F23A5F36F723B050
+:10A8B0005E8E76663C81F800BEAF93695C43C1FD55
+:10A8C0009127D69767EDAF39CEFDD5C597594E7C08
+:10A8D0002D12FCB858F009CE8F72A5FB3EEEE65F54
+:10A8E0002CF7F5E05F20E6108F0D19AB8B904EDA58
+:10A8F00068F6891CC3E707A71E8E92FDFE28D61BAB
+:10A900001AFF93FB0363393FDFEA7B96F8593B5705
+:10A91000F807154EFFA0C9C7CF8F4CC17F6C92B00E
+:10A920002BB51AB25BC1FEBECB47EF855C36B87D56
+:10A93000DB55AFE4EDBBEA23F8FB7FC22EADC37954
+:10A94000CE64975AFABCA84B8E39FDE22291A77AC1
+:10A9500091122639E05DC9EFB3E8853C8FB5A8B008
+:10A960009EF25A718321DF14AC54E9DE0DBCA77C42
+:10A9700056ABBFDEE8F49BFD0B9C7E7381C8031BC6
+:10A98000C06CCF615105220FACC0ED578BBC1B2BA7
+:10A990002FDEBD4FDD7AFD31DF3F9777F70BC9D84A
+:10A9A000E7237F84E7DD346439F351D2FAD9247A7E
+:10A9B000FDA3F679C3E431AFE7029FF579FAF7C456
+:10A9C0006707AEC8A3F39DFBC23C9FAA2583DF1394
+:10A9D00077EF6F906B3FC67B3EFD5682FA207ED6A6
+:10A9E000E8FE7348BC9712CFFF4542BA68469D9473
+:10A9F00097967BAC9CF39117E9ACA05E4D52BD4B92
+:10AA00008FB24E2A15AD3985A6E4C19553B2F01E1A
+:10AA10004E88AD77EC338B1F4EAD6064F7A96C7830
+:10AA200026D6A32B549E67651A47A27969BEB2F851
+:10AA3000200BC4923DDF3667BABFCBF7C07A9FB810
+:10AA4000E6A8F79D1375B4CF4F805D877034727B95
+:10AA50000ED38B797C2C4EFC175D02B82BEA9E4FEF
+:10AA600018157964F90B522497FBD538F3BDA2224F
+:10AA7000DF2BEAEAE7E6A3FFE313F621A877E42356
+:10AA8000C0432CC5CF25E91E8BDAE123BC14005E40
+:10AA9000100FA718A77FFFB92C691675C78BC5675C
+:10AAA000F0BF580AD63F00C649C1735FD489A7805A
+:10AAB000EEC453A8CC89A78C98134F16BE332B74C1
+:10AAC000473B0B6FD6BDF0DEF05458D55A87F0FCEB
+:10AAD000B378D2FD4E3C7DC6DA0EE0BBFBC4770FE7
+:10AAE00090607E9BBDA4A82949D2D3F8C8AF02FECE
+:10AAF0008575DCDF0BFFF7CF653A1E95B31119E4BE
+:10AB0000FF47053EA5959CEF7BB31BDD7C0EDC5A11
+:10AB100087837AF05A4F09F2F9DB82CFDF636877D7
+:10AB200079D0DE1A8525974FFE5C839266D5308FEB
+:10AB300097819CBDD08F72BE5076E457FAC47D1BBE
+:10AB40004B2E282A1E44623D45F275886887763070
+:10AB5000B3C13504F5E228D44B1C6E292CF6F1560E
+:10AB6000D09336BFD2D207670B27D36264A7F850C1
+:10AB70005F86D2FB7860973D691C43BEB4F27B07C9
+:10AB80009A26D1D9CAEBD56F03BB153BB9F27B4BE3
+:10AB9000CC38F947C5EB9D7C5228E4F68015CE7C75
+:10ABA000CF4221E70B5D79BDFDF5D659B44F6E93C9
+:10ABB000D15266FD6EE3DF5918B082690B6CFDFB64
+:10ABC0002522DA0258778188A3BAF9AEDAEF94F336
+:10ABD00037CD9A4DF2E2C7B76D0FF624EFB7D4FA2E
+:10ABE000B50500F48EDA2895BB6A352A8B5B8E1882
+:10ABF0000158CFE0468E8FA239A9A235502F32FDE1
+:10AC0000313B9F8659E2077EA06FF2C6ABA7A03FFB
+:10AC10005EDA98988CEAE5DF14A3169FB32A1E1714
+:10AC20001DBCB2505B3016F36707D0FADD7AA3DFA4
+:10AC3000D2BD476BA1E9F6DB80AF01B6815FFA0CAC
+:10AC4000B47F302716E1D4CD9484E78377F9B91D1A
+:10AC500078B93FBE1EC72FAE6153088D55D9348FCA
+:10AC6000859FDEF49395170FF31D42FDA166653BAA
+:10AC7000EE296C1734D9E1E7768C1527EAB27F9B71
+:10AC8000ACFB06BA4CF7459A8BEAFDF6F890B86F24
+:10AC900020331E07BA05EF1B4878B93EF100ED13CB
+:10ACA000CD160F2A4EC77FFA2D2D0DA25CDEEE3792
+:10ACB000E520EAB5EF327000191B9A04FADBF90AB5
+:10ACC000FEABC8C63C830EB2A72C780BFD61C2EF69
+:10ACD000E5FE442BE205F185E375E147E4BB0F1483
+:10ACE000FC5D761B23B95CDC0C0A10F8AFACA9B391
+:10ACF0000EE9374DC8F3ED429EC3CA67CEB5C9EB26
+:10AD0000ED09231BCF852DF96AC9531073420FE952
+:10AD1000E4670FBDCDC9F7C5426E96BAE466B1903F
+:10AD2000B7C5AEE743935A8F7C6FC1E9E6FB5F5A24
+:10AD3000F2B62FCBC738D4676C52DF8BF4345F5830
+:10AD400079F36EFBC61D8FB0C61F9372CE2FA92656
+:10AD5000C5913D51A6217FB6F4B1E4B2D38FEFB2D5
+:10AD60003B620913EFB5B2794CC3B877746682F2CF
+:10AD700050A378BF07D7758C9F2BACF5F27EB2DF5E
+:10AD800094300FDC5F78E47CE4C70FFC615ACF6538
+:10AD9000DEF80748CF9C993C6E9983725A39BDFC06
+:10ADA0003395B4FC6BF4274E617F4B0EEA094D0ED0
+:10ADB000F720872DB9EB96B32197BCF4A989D43C31
+:10ADC000BD3BDC783BD97EBF6D4D7F21BF0BB91EEB
+:10ADD000DBB24415E7E4AB2A8D52C6D65DF168B408
+:10ADE0000F5D8A6529AD02EA9748F47ED8DA1F35EF
+:10ADF000A27FB16E16AF5704EE69C4F3847557494C
+:10AE0000E47F9C27DE03A4B45F3D7E0B7F35D7161D
+:10AE1000E1795021B707D7149EFE9E4203C6A38650
+:10AE2000A4DB296A8CEE0F5972C0E78A7BAA61679E
+:10AE30005C575DC2EF0B5AF2415DC2CF8BD68DBC21
+:10AE4000BE1DD781F163A4A3D75F43F9DABEE61B29
+:10AE5000295FD92D27FC424EDC2CEE25819C9003E6
+:10AE6000A82F3567DCD89213322A58783F785C0DCA
+:10AE7000C58B7D7A42D6C3E9B88C2567FD6A9CC52F
+:10AE8000E0B9677A0DC3F7BE9971CA4BF289FB65C9
+:10AE9000B23F7600F9D39F7B2446F2CFC58F1302D1
+:10AEA00016FF191302508EC279A19C14B0E26931C9
+:10AEB00089C7A9797E71A33F7E01B6D30BB57A8984
+:10AEC0009D3D7FD19FF122EE85E77A9AC14E17F71B
+:10AED000B2F83A13FDF592EEFCB9C16B645D0470F3
+:10AEE00035FCD213C3FCA133F9233FAA05F9EA4983
+:10AEF000EB414BFF59FAF0FB8122EBBB07E4B710A3
+:10AF00001FC3F8EBDF1E9EA418BBE08FF50BD874AF
+:10AF10007E0F93F3A54FF8985FF49F17F4022A6F02
+:10AF20000B288437EBFE8CC567C15EF2AC2DFEB4F6
+:10AF3000DA5BFCE96E77B67CE9F5279A8A01EE21A7
+:10AF4000E25C6348F38D07033DE82D6B5CB93B5F22
+:10AF5000DE867CD99BFE7ADD6F7C1FE9BFA13C5663
+:10AF600015EF619D4B823C6EB165C9E6800E78BAE3
+:10AF700017F165DBC7C110C7C317439713BEB60BE4
+:10AF80007C3DB8D589AFE819F065B5FF2FC0971F94
+:10AF9000BF0B1116F8EAED5EE169F0B5FD74F8BA81
+:10AFA0003DBEBDA918CF1513726C908EDF6792530A
+:10AFB0001742FDDE2A7937DEE3DC1CDFEE1F847CDE
+:10AFC000D672B03004EFEF0966F07B7B5AAA1DDB26
+:10AFD00099A5327DDF692DB023EA95352DF24F4CCE
+:10AFE0001B3FEE2CE4F7A3D614CE0BCEB7E161677E
+:10AFF000CBC1A85D2EEE74DD13B4CAF941C971AEA0
+:10B0000079DF027ECF2A3FC19278DFAD52DC6B0A36
+:10B01000E4F27848C0E0F521617ECFE9B931ABE9CF
+:10B02000BB0E6B0B7978DFB22B5A5C7685E5AF07E8
+:10B030004BF9F79E5A12FC7B179EF3B9FD1312F6DB
+:10B0400037BCA7784A7084D3CE5684FDE0DBEA7A19
+:10B050002EEC0D8FCBAEB0DA2B67F0DFB22A3B2897
+:10B060006EF44640D8D37DD940B42BEE8BCB044749
+:10B070003EC0813267FD75CD12DA83F95F2906DFA4
+:10B08000FFCDD1AB47A6ED8B4F0241C2E37A11D77A
+:10B090001BF31C5330941299A4517CD3C2EFC90006
+:10B0A0008FEFAD177962E71C33948CD3B51371C859
+:10B0B000097F3095480FEDF604C57D6F353507E9FA
+:10B0C000B6768C57C378E67A89CB47F3658FE06311
+:10B0D0004674DD799DB60DE3568FB517AFA3ABB5BA
+:10B0E00009BD1CC77B0CF44B71B87739F97890AF68
+:10B0F00067F0F498C1BF43678D97DACDCF4753D13E
+:10B100006B001FCF04B93E792C08F281F09428B06F
+:10B11000C70DFF5DACD7C2D3937A62DD48D457B078
+:10B120000E1C26BBB086617EA735DF63857CBEC75B
+:10B130005E97C92ECB8FBDB61BF587359E35DF9345
+:10B14000C19EE5D1B5421E59F8FE999E5C37CA36BC
+:10B150009F6FBA733EDF02980FEAF9C765CA2BEEFC
+:10B160006DBE9FF532DF5C0B3E41B767F48E75A371
+:10B17000619C20CE87FC8FF3857B98EFCB8D528628
+:10B180006D7FEE17F33C63E1514D145C669343A36E
+:10B19000C4BE7D10E4C77C1877EDA0D501E4E39D23
+:10B1A0005292E4993946A6EFEEACDF7A2A85794EC1
+:10B1B0000F1A8CA2BE5915E664F4D79705B385DC47
+:10B1C0009D42FD24B5B90EF7A3D2C2B85D857E7944
+:10B1D00026EBE1FCAA99EC890133F9F79C2CBB2FF3
+:10B1E000DA52F3E25094132B65FA7E0D03375A1DA1
+:10B1F0009F8E7BB478C478E2FCC9B217F2851D7DBE
+:10B200001ABB21C6ACF325AAF3F3282B0EC2CA0D34
+:10B210008A6758F17F2BCE67C5FDAD787F264B4DF1
+:10B22000B69F43953083BE673848C4458A0C7D0A73
+:10B23000C6CB07B724A6209F65AF60F47D489FB0BA
+:10B24000C343253FCAEA8A0B9E07F305BBEE2114D0
+:10B25000A0BD9013ECBA8740F522D77B35C1F58F9E
+:10B26000BA80CB3776B85BBED1A2601FCA83E071CB
+:10B270001711DF7E4AD8619BE31B0328CFFFE2371B
+:10B28000EA50FFD6093B0DECFEE5D88FCD06BAA0FB
+:10B29000DF0E6DD00F51C24CFE47E89AA623E3F2B1
+:10B2A0007E25F717DDF4EA8DAE16FD2C7AFEA37429
+:10B2B000C44F4A29E8EF603C89EC42F3B4719E42E6
+:10B2C000B593CE177516237A96B238D1B3C0AFC9ED
+:10B2D00048C7E24ABD2E80F4147AB33FE82BD49BD2
+:10B2E000F7C7971311DDF454CB047DE23C1EC38EE7
+:10B2F000488E3817D0E7FEE039DDE9737B7C4A00E1
+:10B30000F5F7CE98DC8AFBDBADB799D63C1DF1B9D9
+:10B31000B3B09CCE0B5ACA3606D00E00BD4D768017
+:10B320005925D37D97B3D0DFE417CDBFFD2DF28B28
+:10B33000D667897B8283BCC91D45A87F746EB777A9
+:10B340001E999A998BF150AE27D67B52D1D8086CB2
+:10B350009F9A330FE5C28FB85C7830EE960B49FFA9
+:10B360007C2452308B9F876EADBF84FC3FD524FB7D
+:10B37000DF9AFFDCE0B9ABC82F0BA728CF6EFDAC7E
+:10B38000E5F43D034B8EB8DB9DDCFF9BFE98E7F1B7
+:10B39000DBEB3ECD80CDC87EA77666E07A8EDFF609
+:10B3A0004A8601EF7F7B9B42F783BE23E25CD7D6C0
+:10B3B000FE6D3CDE0F7F45C8C79121E325E2EF9586
+:10B3C0007D88E96E482A18D4E57C05FF2DDE15C27C
+:10B3D0004DDF555FDA9AE3A85BF1A0A53E7E8EB5FE
+:10B3E00078F7016F3F80FB865D59140F3A2EBEDF60
+:10B3F000767C6FFF6D18B70E8464316FFC2D9C173F
+:10B40000D78374F85D9B8FA5480E1FF170FD67CC44
+:10B41000C4F38684E00FF7BA9E7F2644E35E77B7D5
+:10B420004276D35CC0E54A10B989AAC5144F71AF02
+:10B43000FBBADFB63E5F00EBBA6EAD44DFF1C0F69B
+:10B44000B7819F9758B986E2886EB8E69ACE3C904D
+:10B45000F9ADB3283E396F85447A79DE5689F6EF27
+:10B46000FC2667BBC7DAA77A917FAF6B763E5FD8C1
+:10B47000B68EE659E88A57BAEDA5BF07859D349E7A
+:10B480009D8B76D2A9F6CB28EED89BFF6DD947C706
+:10B49000C16EC70B4D7FAAF553F951AD46E54B413F
+:10B4A000CEB78BF71D789E64837A643CF2D563ED4A
+:10B4B000EF85AE8657CBA3DC5EBF60DBA70D4F32B6
+:10B4C0008AF7285C7E18243FAE11F8BF90F9F5305A
+:10B4D000AC738788C38DFD12EA36F84E354BE4B75E
+:10B4E000C1EED7306FE71A8477148ECFEDF46BF08E
+:10B4F0003BB9A781BB7FC8196FFD57E1EEADDF52A5
+:10B5000085E753BA9F5BFBE125615F34ECBF671AA7
+:10B51000F2CB89BB243A3F3BE149AEA6FADD52ACFF
+:10B520004EA7651F43796BF1A79BFFC0CFF5E2BE25
+:10B53000EEE2B3B63B081F161FC0BE898A7CA5A8E1
+:10B540005CD103BFB9F8CACD4F273C1D03709FBB28
+:10B55000F9E9442F7EC898103F9F5FA01BD3308E1F
+:10B56000721D8B533E14D0F9D5FF4A38ACEF2795A6
+:10B57000F39814E6751995B04F1FFB8AFB37F57BDE
+:10B580004B36A15D3CE625557C97D9243EBB00FF98
+:10B5900009738C29D12FFFF938FEDE64DDF172C109
+:10B5A0000B5F6D9AA99F193F6EBC74C9A1767E7E10
+:10B5B00076C1574E3FE786B635918928B70E737925
+:10B5C0005D7E5875E7977139F7D49E2751DE2E7A44
+:10B5D0006B638441F981DA9C8774D8F3C0AA8881AF
+:10B5E0007257352388D70F924A8FF7A01F0A49D682
+:10B5F00077D91CF96FB03E13E3DF37BCE14BD6C1FE
+:10B60000FAAA77F952A827973DB788E80075D29B28
+:10B61000CBF6F69CFFB6E8C1BBF3749EBFEECC83BD
+:10B620007BC043E781CBC0CF42B63D631E5CAB32EB
+:10B63000D79BD9537E5DA717E546B5F007DD797036
+:10B6400055BD9CA3B4849C79708017F2FB4C580FB5
+:10B650009D1125B9DE6978C867FA619D1FBCD9774D
+:10B660001B9E037FF4C04B1169447A9F5B79681F6E
+:10B67000B5969CF6BB6727843CB0EABDE5C7ED01F3
+:10B680007E407C2F017CA3DDB2E4A81C1A81718965
+:10B690006D1E5AD793AF1FCC1B09F5C58F7A726701
+:10B6A0007270C2A88F2C7A75E5270AFA2C7AFC17DB
+:10B6B0005ECC93ECCA5314745AFCE8012FF2891B38
+:10B6C0009F535B0F783BC23DD0ABF5DD69747FF5CE
+:10B6D000A12FBCA8673E7846627D8BBAF7AFDAF13E
+:10B6E0005204DB9D896E1F3DC0F5E4476D52522A1E
+:10B6F000EA9D7EFF0B65EF39DDCFF5CC29AC0CBFA1
+:10B700006BD9E06565E89798723086F6903B1EC865
+:10B71000C4F7BE6E39C8E83BDA1786AD781FFF0E56
+:10B72000DC2D2FF0E71E8CDDC27FE56F0F4FA2FDF1
+:10B730001F9B2AD7F0EFE0893C8070749B8F073EF7
+:10B74000294E754AC8114F98FB99633ACAEE9984FD
+:10B75000718D760F4BEAE973F153C7F9BE1EDFAE68
+:10B7600090FDFF248B2B68AFFAA232D36DF808E866
+:10B7700041A6DBF8335496EDA837223C781E21CE43
+:10B78000D7C7F2572C2356E01867ACC6BF9F9E5907
+:10B7900051ECE8CF0E3BCFC5993242C1F57D960200
+:10B7A0001B1CE01A7FCC799E3351D0E3DC5C53A1A3
+:10B7B00034A0B75DEFC3D329CE32F10C7196EF867A
+:10B7C00085FE2C6005B8CFE8AE0AD22B2B42F6AB33
+:10B7D00047D8F9F8DD32CCBBFBB9C0672C247FAA6F
+:10B7E000038EFB8503D354D8BFB1B1F24D25781F2A
+:10B7F000617D2EAF9F273F5E0CF511EBFB4CC3FB29
+:10B8000009B1D1F2580FDD8BCF9B5689F749648976
+:10B8100095E3F95F01FF0EC63A2FEC2BD8178D1177
+:10B82000666465E37D566606CA713E9D7F0F0D1CFA
+:10B830008F00E68189F8B11AE1FD1A3DBCDFD98E8F
+:10B84000678D53AEEAF49D4E5F29C05A949EA75C63
+:10B85000E5F08F087B892FD4294614FD1435DB1BB6
+:10B860006BA0769CDFCFB604F93700E59FA29CA2BF
+:10B870003CE9CE7F0F515CFCCD20E7FF6F65AEF752
+:10B880000C837AB97FC04DB879DE94767F17CB3FB1
+:10B89000861313C314E7E7F78FAFFE8EB29DE2392C
+:10B8A000E19A0CA48364707D2B0111AEC17CD07928
+:10B8B00031BF5A8222CA998FA628E59D299A37C39B
+:10B8C000312FB8797ED4B7DFC2BB403A8E0B75E01A
+:10B8D000DBDF54F0FA9C647143874EEB9811063815
+:10B8E000C6F892FD319FF96A39F95D9EA7E7CCE36E
+:10B8F0003A1114FC2FBED3852211C719B76FB19529
+:10B90000BF45F2BBFA55117F3CC2F5A4953F83CBEE
+:10B910005849DFEBEECCC3CEE71D96C92F737F9756
+:10B920007EC261EEA74F70F1F579E25CFFBC33D8BF
+:10B93000C9F3C342AF087E3FDB3CAC6725E306C4D6
+:10B94000C34C9519F6DF0D582E1CD153878B33311C
+:10B950007E7458E8692B6FD1AB2B745EBCD7A55FA2
+:10B960002C7E1B794C9B8FF819798C5D8B72C19D55
+:10B97000CFD3358FC6F139868DBA07BFDFDC9B1C6C
+:10B98000B3D66BC9B32CC329C772A63BE5589FB881
+:10B99000538EF59DE39457F909A79CEA5735CCF1EE
+:10B9A000BE7F4DB9A33E70E54447FB225004F67AB2
+:10B9B00049D30C47FB41CD9739EA435AAE76B41FC1
+:10B9C0009A9CE7783F7CD722C77B4B5EF7267F4760
+:10B9D000B62E77B4B7E4EFE87DB73AC6B5E4AF0961
+:10B9E0007F911FCB5131015E63221FAA37F9ABC88B
+:10B9F0003553513FC652A682F6C53F2B879F74C967
+:10BA0000E1CFD8CC0A46E7BFFC9CB937BEB4F27A86
+:10BA10009510D7874AA65CF32894A3C3DC1F8985B9
+:10BA200045BC4BE37C7272FF108A33631E1CDA2123
+:10BA3000273DE1268C1365012FA11C71EBE7ACB605
+:10BA40001728FEE43EB7BB45D1293EF7856C4CC0B4
+:10BA5000F5F561AD14F76994C5BDC7297ED21F1BEA
+:10BA600064F95A7B3CF6D530DF1FAF8AF56D01399A
+:10BA70008D72B95F08ECD872DEDFFEFB08911CC640
+:10BA8000CFADCDA5AB2B0BF1FB571D657A16EC2B7B
+:10BA9000AC9F9F9667203FC722BE405E75E03E0583
+:10BAA00039D53F0553CDC9ADF148005B3F3F333138
+:10BAB0002F18F0752DC66DB358AEB47C04C61FBBED
+:10BAC000E4A5FE3530CDB38B8653FEF5A9AAA1F4CB
+:10BAD0001DA553B0F62374FEA5F3DF7999CECFCB25
+:10BAE000AE12E760A7169450BB37BE03BB15F8EF44
+:10BAF00097B872D06F6F78F97741CEE467566DDBF7
+:10BB00009481E7C36F94F1F338EBB994C1E3C85261
+:10BB1000864278AA5E10A27CDB65490F9DD3542330
+:10BB20005AD05E4CF27D8E75F4B3D6366E74DEDF7D
+:10BB30006AAF31D17FAF6E9B45F90BDFFA0DF7632A
+:10BB4000BFF57F78DCC59A4FCBE0DF57D3C47C5775
+:10BB50004281F78BAF04FC6761F9C2A469B86FE05A
+:10BB6000794A82FAA5ED601A00BE67258A3C88BC36
+:10BB70005758ECD52760C9FD32F8BCB359DC83FCBB
+:10BB8000F01A4B7CFC6A916D3C6B1C5814EAE5DFA3
+:10BB900064999E3CE097CEF325D24F309F1F9FC7FC
+:10BBA000AFE9B70A45A4359F35CE652C46E35EC1A3
+:10BBB0000C2A9911A4EFB458F271F90DA1540E8C0E
+:10BBC000B71CEC738CB39CACEBFCE9CDB0AEDF2DB5
+:10BBD000FACB1394689FE8E88F7EE9552D0AFD9E05
+:10BBE000CAC1A0519A81FBA322E7ECBE6B07643463
+:10BBF000516F323EDFCB82DE73DA72C60ABD1DCBD7
+:10BC000000F8DF7C664F7F941B2F0E7D7010BF9F66
+:10BC10007A96E30B791F13FC05FA80ECE7932C1856
+:10BC2000F3F5603F3F2AF4EE2DB241F1D95B141ECB
+:10BC3000A7FD42E6769B22C7A22AD45BDB9410F2D2
+:10BC400069048D23DBEFA144308951FCFE891FFC80
+:10BC500088E162FF5D9CF11FD31AB99FEFD4E7C260
+:10BC60006FB1F4771CFEA2BC3C0FEF3B4928BF9D8F
+:10BC7000FEEF84944CFEC53FABAFAFCA70CAC5B3EC
+:10BC8000D7D7897948D7D6322EB75A53419EFF0A63
+:10BC90002A00ED314B8FBBFB57897DB70C7D629439
+:10BCA0009F082BDA9F203F32F83D045329A73A0B17
+:10BCB00067535EB3D187D7CD4C289FD2787BAF74C2
+:10BCC000A2CC0F726AF91D8FAF6E9A84F712395E9B
+:10BCD000B18EBFAFC2FC21AED72D39F2DC30FEDD14
+:10BCE000C0AF004AC4B7F05FDCEB1B077C4BCACD8A
+:10BCF000E27BD13FF5FC5F23E817EEC9D67F751EC6
+:10BD0000DA7B871486FB29A07678B37A80F349948E
+:10BD10004B4318DB97C1E5B07F9F44DFD9F1EBDCE3
+:10BD2000EF0A68DA18CA6D4FB010C65D3E7EB48463
+:10BD3000FCB05884CBEF9A507C3DF2F99FA4A3E36A
+:10BD4000B512B28FEE407C5B786D4DF1EF928F545F
+:10BD500059939A9DC6AB357F75CB583A5C58D692AD
+:10BD600043E550F4B3E151758AC377625F43764F80
+:10BD7000FEFAC8B6B10BE95E5FDFCECFDF429FF0BF
+:10BD80003FF8BD604C69C7FB200F7F399CC6DB9133
+:10BD900051C4ED2B95A91EB22B93327EB7AADAC7F8
+:10BDA000E5DF892F156AD735EEBEC98A06B41E9124
+:10BDB0006A3E88F67FA0CDA753DCF901FEBDC140E5
+:10BDC0005B2089FA4ED53ADF473B5E6DF3690D3A49
+:10BDD0009EF376BE83FCD5B9DF47BF2BB1C7DB4CE2
+:10BDE000ED3B073119EB438152F8FDB080D6CCB260
+:10BDF0006DF004DAEE419B1BF982BE3314509BD9DF
+:10BE0000F9363AC5223CDFE0F90CCE4F7B82293966
+:10BE1000CCC765DB695DE975E2BAF0388AAF732893
+:10BE2000C525F678619DB9B42E0DF96028E3EB6461
+:10BE30006D4374D4CB2AAC87FC9A5226A34870AFCA
+:10BE4000AB7A144BA27CD950CFD2BF8F04F2A23A66
+:10BE500098AEFB616FED2916FADA3CBE1A7F47A84F
+:10BE6000AB8E02AD22DDFFED8C0F573716DAF68F61
+:10BE7000CAF7D342D4177DD2FB08F18071B15EF7C7
+:10BE80005B98B72BDBA67E8AF03F9A0AC7E8F7E2F9
+:10BE9000C4F782AD38CB0A29F5FE856847A50E8E1A
+:10BEA000D2614D4B5EF8D900BCB2B7586EFBE14889
+:10BEB00078BFCA9B781FF9F5A9B76516013CFCE964
+:10BEC000A14072268C53F6F4B63C3CFF708FB7E667
+:10BED000F5FA8DFDD07E7A5AD231AE7BD2D349713C
+:10BEE000D4656DFFDB8BF1BB8BF7BDEB45BBE10789
+:10BEF000914427EE8B8A7D7553118F13587303C6B7
+:10BF0000CD40AED2F74C5AA35C1E9D3A36787B1DCD
+:10BF1000EEAFCEC440E4CBA8D857161DDAC4FE7CE1
+:10BF200006ED06289F1076CB1307AE2AD16DE7F6F3
+:10BF3000263B48F19F7AF65C3FC4B7F5FC6452A5F6
+:10BF4000FC93E1AFF9AF356C7C971DE1FB3D5BCC19
+:10BF5000978C24BC118CF31FF8BD3702707D2875B7
+:10BF60004EC357B09F7D119BBFD30AF68F9D7FBBF9
+:10BF7000ED67D77EAA563BBD142F3CCE48AE00BD20
+:10BF80001B33817E8FBCB66F18DDBFEB8C7F1BF13E
+:10BF9000F0F9AB5E8679114F083BB6EED5CF47A1DD
+:10BFA0001CFB7CFFE28188BF2F855D02FC3F057F83
+:10BFB000BBABF3514672CDDAA723709FC2524668DD
+:10BFC000FC3C7104F27F11F2FF9119B42F9F90197C
+:10BFD000DF877C3F00FF6B282F4668B01FA8FF104B
+:10BFE000DAE77B8EC8FCDC0EF4049EFBED9101B514
+:10BFF000C067E33CA983D86F1CCC5BA7E37E3D12EE
+:10C00000C4BC08B657CEC578DF38FC7EB20D2F0B06
+:10C010003322849785023FB70A3D12C24354DBBEE8
+:10C02000B0E95D5E177AF9FB917E6B36E38FB269FA
+:10C030002187DFC7A22192F737095DB9FC17132FBB
+:10C04000DD0DF02D7F59A1F7E38D9AA9A8562AA6F8
+:10C05000373F8BE5C478EB540C7FA2BED0812EE72E
+:10C060004069805C9D34E7C8B3FC8EAB311CEDA009
+:10C07000BD072F198EE7D027DFF0D16F399CDC3355
+:10C08000E3113CA73CF94680C9528F768A83CFDC06
+:10C09000E549A9238271A02B360CBB5805DF78D95E
+:10C0A000040EE7651BCAD698A0035F891857205F66
+:10C0B0001DCF4C5C1101FC9C3CFAD73C94DD4F1C1D
+:10C0C000FB7D04F5FA5EAF315CA3927F7FD13DFE2C
+:10C0D000D408E78771E2DC10F713DA471FB7E46C86
+:10C0E000C3FDF4F15EC5C803B9757384C7A92C7F7D
+:10C0F000F03A8E3656B597DBCBD71B3CDE7A1DDA8D
+:10C100003358DFEC71F86D558CFB47834DD615071E
+:10C11000477FBBCA65AFD0F97B2EC65125FA0E8A80
+:10C120003B8EBA44F8894BCEE0FFDD1C11718912B9
+:10C130005682760EF003F99F9DAF2AB1EDA8DB542D
+:10C14000D6EE83F53C22BE4B09F290F69365EFE400
+:10C150006AC6531A9E33087EDB23FCB5CE3D52924D
+:10C16000F87F17A37B5D138FEBDB287FC034E8FBE0
+:10C17000DA5542BE4D54B9BF3BF15849CC44F8851D
+:10C180009D5761241B30BFE9FA5D522C496A94C364
+:10C19000076AB52B6E83F02F6C03F8253C3F75C101
+:10C1A000DF72F479CC4958DAEABE1FDF733CF9310B
+:10C1B000FC470FE701F745841D38800DB0DB81ACEB
+:10C1C0003DFBB4F7E22DBBFA4371BFF5D7627CF8B3
+:10C1D00013C6FCB7F704FC4F087E596670789624A6
+:10C1E00095247EE766BEE00FB69EF38775EFA45AEE
+:10C1F000C0BD742BA7BB1BBEAADD1EB27B01617440
+:10C20000FE51B5D5C95F8B04FC8B5CF02FC34BD3BB
+:10C21000B6F92DFB7BBEE0DFDED6B3D8C3E9B7F8B5
+:10C2200055FE7B13FF5DEB73D3E5658B6F87B161C3
+:10C230000EBA4C3FFDF70ABAFC1D971D6BD9C1160B
+:10C240001FB8FB4F13F6EFC52DDC5EDC7BE46013FB
+:10C25000DABBE5FB150DCFF7F61E3915C1F397B123
+:10C26000FB79FEF7C9B6B1EBF03B168FB7975E8E40
+:10C2700079AFE54765DA07635F2E4F626A71F9CBE4
+:10C28000E5A1123AFFD273100F270F73BD79F27038
+:10C29000E92B78AE73B2BD721CAAE9BAC3E521D40A
+:10C2A000EF8F33EEA74B2FFFF99738EFD843EA789B
+:10C2B0008CD3AD8E2AB4DF2EBE77EE4EF4D3FE18AB
+:10C2C000E17EF4F34796CF263A1C96357C7EE2B0A9
+:10C2D0004CED96FC48A13C4EA6DC96FB6D78FF59D0
+:10C2E0009B47E3EBF5D0FCD5FB07E5CCB7F95FF353
+:10C2F000049F9667E99B66A21D971F22BBF7E2FE8B
+:10C300001ED27B1F15847E82F6CB60631B9DD37E7D
+:10C31000F4B39B649CF7E41E89450180E7A3CFFE3C
+:10C3200094BEEBF1E4513A579ABAF7289D23CDB366
+:10C33000FC39712E6AF1D342F4DBC0AFFCF84850EF
+:10C34000E457347B912E4B8F5AF50E2FEAE7B8B0A5
+:10C350007B963DF02ED517A11D0FEB59F480447943
+:10C36000A8CFEE7F8ACEA396EDE6E7518BF66D9BC4
+:10C3700086ED16B3563A4F74CB8B852DCEFA0D82CF
+:10C380000F6F38031F0EC8147C38940DA5EF664C50
+:10C39000E6DFDF684DCD1BB807E63FF5BA8FF8E161
+:10C3A00034FC487AEDB088D79C4AC906C26FB53BC9
+:10C3B00071F89417EDC2696D9F10DE66B61DA84432
+:10C3C0007C7C932596207CDF6C0B6928FF6676F0D9
+:10C3D0007D37A3CD47F72FBFC95A1BF97939973756
+:10C3E0000B051D170ABC9F7CC6C7CF5B7E2A91DD5B
+:10C3F000B110046B0E88B425227ECBB63AE9021246
+:10C40000FD3BFC5CCE4776D337CA9CF89AC1B8FC9A
+:10C4100098B14F22F9F10DA6D3EF407EA31D032959
+:10C42000305F7E887E2767C96EF7392EF7C797B9C8
+:10C43000F45B2C93EBDB7FF47706E22E7ACCECE412
+:10C44000F26986D0A3EDA9FA11183FB2F0E3A6472E
+:10C45000BB7EFAF3DA5F0AFBD8AA5F0A1B05EDB0D0
+:10C46000568DE3FFD0913E9437B4688262A23DF0CE
+:10C470006426B77B97FCFDF24B31C1F423F9E0CD84
+:10C48000BBE1FD87735B07235EC01FA8CA84F72F3B
+:10C4900014CE5F3F06FAFF698F2786F28419DB0608
+:10C4A000A39DB426BA69269E2F55EFE6BFF379A265
+:10C4B0004231497EAA9DD370BE0FF74B1AC655ABC9
+:10C4C000F77DCAFD01E41328E36DD245C8276067F4
+:10C4D000AFC804791737B23C48BF6595129DEBCDC4
+:10C4E000AAFCC48B78057BFBBB9936FFF950690920
+:10C4F000F9CF87549DBE8BD89BBDBDEC4B6EDF59E9
+:10C50000CF97C1BE447C2E6B93C8AF4CDB777D25A3
+:10C51000B2EFF63FF55C36C985AC31A84E7F92D9B3
+:10C520006527515ECAF542CF30A991F6C3DE831F5D
+:10C530005C89F0753EED61C52808A164E7823CFC8A
+:10C540007590ECA213AFF1738A851A3FBF39312F72
+:10C55000D9988D76FD4312D911D70B7D85EF313EE9
+:10C56000793DD86B1794E3AF49D60BBFA5914AF735
+:10C57000BEAFDAF70AE54359F6063D2FEE2E2F96A9
+:10C580000ABE5D7A8638D2F0679E2A46BA3C99295F
+:10C59000EC08C19700C73A949F270F291A9E1FEFF6
+:10C5A0003DF897FB0BD06E027BB818E5B3B02FF6C1
+:10C5B0001E0C907F70F268388978FC93E0BF8F443E
+:10C5C0005CB7AE4221BCC8137889F3D177C2F67F3D
+:10C5D000312001F2F691679E1A86F35B79058B771D
+:10C5E00039F3D296B63AF3CE2CFC560BFCC2BA06FF
+:10C5F000E3FD346B5D4FA81D91580FFB46920E1260
+:10C60000DD64C9E90F563FAD38BEEB03F05C8BF239
+:10C61000AC3DD3CA53EFCC43FD773853277EA86B8C
+:10C62000E37496F7F312E6BF92C7393C347FB7F74D
+:10C6300053CC25E4CF1585E83CB51DFC76FCEDE434
+:10C64000F6D703E48FDDFCEB4543ECBF4BC024EE93
+:10C65000B7567B3AF3C84F3CCABF3B34837D42F99F
+:10C660001333DA3CB98029F67CF1CF553A77182597
+:10C67000B173601C13E7ED8BF1B5E7A8FF95992224
+:10C680003E3E81F7AF177CB5F7D73342E8A79DDC74
+:10C69000DF87F22DDF127EEFF1CCF87BB8CF2C7F55
+:10C6A000A337FBD1E6EF103EAA014EDC478FBFEE69
+:10C6B0004BCE94D03FFDE2B56F23BC8754CAABAEDE
+:10C6C000DBEF33D16FAA7E3340DF236089C46894E7
+:10C6D0001B373FB370089D1B48F5448FCF9F39D45B
+:10C6E00044FD9EF450846FE9FE57F348AF3E71CE8F
+:10C6F00026B453C02EF906DA298FB779C84E297FA0
+:10C70000791CF1DBE387C7E594D0771B62211C77A6
+:10C71000E921358EFB7BE9A1712FCD44FBE2E529B0
+:10C7200064A7482F8FCB41B93356FCAE8F74A894C1
+:10C73000EAFF1776D3957D00800000001F8B08006C
+:10C7400000000000000B8D566D885465147EDEFBE2
+:10C750003173D7999DBDFBE1A8ACD9DD55F723C74F
+:10C76000E9EE9AEEFA5557ADD842735C332524278B
+:10C770008D88D255834828F0AE9B609A24E18F8241
+:10C78000889B50F4C362AC4DF6C72AB3B8A6AD106F
+:10C790001B16AE12310A5981DB6E4548124CE7BCBC
+:10C7A000F78EB35F41B32C67DE8F73CE739EF3BCFD
+:10C7B000EF3BF93C7D1E02EE94A9C06260A4AF6419
+:10C7C0009B9300046AABD10A2898276D3ED8B7B373
+:10C7D000FB7C0851B23DAAE3258AF305BF98A90165
+:10C7E000D3810AD392F13A33C2410BC539E5DB9DBF
+:10C7F0003D5FC42DDAF7929E899B14A7F3A4EEAF98
+:10C800007FEA5BE098F4736D0598015CE2A959C07A
+:10C8100080F09E03411CD0B125437E0357D3F756C9
+:10C82000B05D95AE677BDC14326F018F8BD512370C
+:10C83000447B356602C3DD7A9B172DAE17EC51F6AB
+:10C84000A37CB14A6C4B4DB17EC054E4FAE321A401
+:10C85000392FE044672D01BEE1AF54E213FD2FAE46
+:10C860003563C0BA60DF65A4CAB21412ADFA8D5C3C
+:10C870000390A2BF7C2D50FFAE762367407EF2F47A
+:10C88000BF09968EB9C046FABEAF02C834D8D3ED00
+:10C8900028CFBFF5BB9A2CE6DFB84E7742F74FC6DC
+:10C8A0007577BD4D9F10579379E5B88662FF306B61
+:10C8B000437F4371DD314BAB6E2EA02F75A8CB1398
+:10C8C0009F50A3115105FC755137D51ADEE5CD4BAC
+:10C8D0002D9C9CE7F6FE991BFA75E0ABFD54763D66
+:10C8E0007071BF21ED39E13C6652DD6B3538992915
+:10C8F000F87BA1D4EF4B67E395648EFBD577F5B356
+:10C90000F20780D1AB25A8659EFE2114C4E72E3323
+:10C91000C038C1BF13EDB28F07F0E4381D16FA39E5
+:10C920000CB4651293FBB923E8474743F83AF3D9AF
+:10C93000A18E8698EF370FBD93621DE9BD9D2EE74E
+:10C940006B0FF93A2DF877F4EC453AC178C300F152
+:10C9500032FC88F0C242E29E1396B8C3A8953C0D03
+:10C960007E504EEB9B864A7098D6FB1AAF8472E4D9
+:10C9700047C2FB0E71D2855F0E7665074326CDAFA9
+:10C9800037FC3EB35E4078EABA9F3D8860FEF566AC
+:10C990009A278D3ED83C868F405FEB5BC7F7B71375
+:10C9A00015AE3C97A24ADA7A0C3E5A4D38363BC255
+:10C9B000F668FF0667FCFEF62D4DE789FE2974E256
+:10C9C000EB6CA25EDE33D3074D721819FCE3A98528
+:10C9D000146FA0F1E739CC4747A07FBBDEEAC9510D
+:10C9E0003EFB92D9D4453EBB23B1A449FA7C9BF9C6
+:10C9F00026BFC6D2F451E9EFDD789E2E8FBBFE71C3
+:10CA0000D394EB03BA379BCF7DE1BCD933B0686FC9
+:10CA1000746CFFFCBE1D653D30F04425B0F4BFF5DD
+:10CA2000CF84FBFABA9064FE07FABE4E86C6F4E9DC
+:10CA3000D6CBE97ACEB7FBCCB9B8151DAB2B25D038
+:10CA40009526AD10BECE14315E67B7586709B6DFC4
+:10CA5000C797B31EBAD74C1756717DF7979763F3F4
+:10CA6000C7C41DEE55E57E68B9BA4DA563711E9425
+:10CA70003887337E3C6AAECBFAEA38DDB4E4B04F97
+:10CA8000BFABF078DEF68F594F4097DC5FD06789F7
+:10CA9000EE3AD5548F8E3D2EDB4C08D2DF3D1BF68F
+:10CAA0003EA2F1089D4D50DD23D7CD0F5DA9CFD912
+:10CAB000601D9E0E74F46DC06B0B5D4EACC3A5C8BB
+:10CAC000A87C1E5AA0612B8F356435B22BE0A97C5F
+:10CAD0003E5AB46C9F48CA7957235DAE444ECE533C
+:10CAE000291AFBAD82A5F1780DDC2E7A2CD0DBFD66
+:10CAF000B91AA154D9B8567E9374C657CB54FD2A9F
+:10CB0000F2A1E1664177B4D90E931E1245DC4B8445
+:10CB10008FBBC581B18FF2DF09CEF5720C4A1C764E
+:10CB2000C4AF77F46F782704E4D3B195F62DD7D04E
+:10CB3000A6521D2B3518D3687CAA5F91E7F86CCEFE
+:10CB4000F2F87EB32B03BF5FC9AFA658E732DA5FB6
+:10CB500056C1631CD2253FD929EB1D366B7C5D6223
+:10CB6000F4198EB3A6378CC334A518AECA3AFF3376
+:10CB700078F722C45B8CE22C3B26304438ECB97E3B
+:10CB80007D85F8CB40F99A79BF5F178D3144F31159
+:10CB9000C3F7031E36991F918D2BF9C8FFE7712447
+:10CBA0000E893BB663F4B7D7B8CE3361F30441B214
+:10CBB0007B2F0C097AA784E380F9B48D68568D71B8
+:10CBC000C3B45B77EF057AA7C2E5DBF572C2232C0D
+:10CBD00053F28934AC54293FC5EF9BFC6E28BCAF9F
+:10CBE000D26FD32FD4A7CD81BEAE4D8B2551067CFD
+:10CBF000E2B55BACE32D5586CD7C371B731681E225
+:10CC0000FE144DEBE5C4DB357172BE0CA2798B3995
+:10CC1000EE1B6A06CC2FFD3A90BADC67F8716E976E
+:10CC2000F896CF1AEB3342D7B141788E90EE0D1AB9
+:10CC3000BBABFD3EBA3F96785D94E7553525457709
+:10CC40005BB10D8E87DAF4500B596DB563EDA1F32E
+:10CC50001966FC9122FE8979B89E15857A94623D09
+:10CC600093F3B8FA7D359CC7EACA0959D702AEAB2F
+:10CC700029ECDD93A5F9A715EF15C61181D32A710B
+:10CC8000200BBECFCD80A7429D26F34FBA8343FC35
+:10CC90003714F92FD47B649A5FA78EA01E8BFAB04D
+:10CCA00070721DFF029EEE0248C0090000000000E5
+:10CCB00000000000000000001F8B080000000000C2
+:10CCC000000B9BC2CFC0F0A31E81FF72A2F2D1F174
+:10CCD0004A0E54FE1A2EFCEA0961150604FB193BA4
+:10CCE00003C3572608DE0AC59140EC0AC5A2CC1042
+:10CCF000ACC382D0E3CBC6C01006C4F1409CC18651
+:10CD0000DFAE2E164C317B390686738A087EB62438
+:10CD100003C312201695A2CC5FA3786860494354E0
+:10CD2000FE7C2D547E9F0E303D20A959A0459AF9D6
+:10CD300062460C0CE2400C00564D6D566803000034
+:10CD400000000000000000001F8B08000000000031
+:10CD5000000BC57D0F7C14D5B5F09DD999D9D9CDDF
+:10CD60006E761296B0094B988404A20DB80901039F
+:10CD7000461D30D0587DED8A56A355BA0481A002D5
+:10CD80000BB592B6B63B90BF4020ABA2A588760308
+:10CD9000E2C33F3CA34FADFDAA75A968D1E7D7A672
+:10CDA000AD7DC53EEC0BA8885631DAAAF83EADEF52
+:10CDB0009E73EF6467870DE86BBFDF5B7F7273E77D
+:10CDC000DEB9F7DC73CE3DE7DC73CFBDE3F6951239
+:10CDD000E97C423E831F4DBB65F284701621EDE174
+:10CDE0002E93D05F37FC338B902E488BE9FF29516F
+:10CDF000223309F110F67385C5C3EE7C42562B3AF7
+:10CE00002163E9835021D6977C5112D3A186A40FC8
+:10CE1000A958D5FC6C52569E7CE6FA3CF94FA664A4
+:10CE2000E74DD60FF92E2145847C9B97D19F01F9C0
+:10CE3000469EB1C663A524A2907455A69D46C2F233
+:10CE4000BA2890CF04789A5D6EF5D3A6E64F2301F9
+:10CE5000423EF2B0D49C4B8BEA68FA274FAABD8CB5
+:10CE60008E5F887D89C1133F3B3A15D3B3206D1780
+:10CE700048F3802F071C643D213308D990884E7FEA
+:10CE80004DCE3CF7484943ACC3B623BB016F3E22AD
+:10CE9000C1783608D6F0060D579010351899BE9116
+:10CEA000E6665378A19DD54A7436A430FCA89F90BD
+:10CEB0007D957734B7D07AEF4794881B9FEAACBF53
+:10CEC000CAC9E362D5502F4900BECD339E0BC57C45
+:10CED000D82FD120F51103E025E4FB04E8FB01E0A5
+:10CEE00055CFC0F71522623B997164E3EB39F883A3
+:10CEF00096B727F4868A4A427A65BDAF01F0F47F7F
+:10CF00005D91DD582BDD0C78DB3CA348DC48C7D4B1
+:10CF10002E53FC5078BA13FA7489D6EF4C54617AC8
+:10CF20003E29C77636CF60F0EE9B31393044D3CE00
+:10CF3000B1DEE614C21F1932E9F8D60E3D7CCE46AA
+:10CF40003D93570EFD04F3E7937CA4DB660FC33FCC
+:10CF5000C5108E27C32783CD8B697D7F9D56CBDE81
+:10CF6000377CC5B43C8FB0F1925431F295A2B1BC7C
+:10CF7000B78ED2C9E23FFA7FE3588910FABEAB8E72
+:10CF8000A4DC94FE7987965D4CA6C13C481A04FA4D
+:10CF9000ABA678A1F535FADF6774287E6813E8E65A
+:10CFA000232983D6572B58B9D59E62C723F013E99E
+:10CFB0007DCF05ED399ECB1FBB2269DA0EF9BD0B83
+:10CFC000F94396A383E7033EEB768E33850C5DE44D
+:10CFD0003A361FE5D8B4E98DD329FF1EEA3F677FB3
+:10CFE00055A63F93F8834761B06793B391CF5D57E0
+:10CFF000076239F8D44A3F4AA4CED92F235E443B76
+:10D000001E47ABDF99A0949E92C97795C54214152F
+:10D010002469FE932151D476C9B19010A1F4DF7533
+:10D02000A1D144F3F294482842FB6F2FA08D9610B3
+:10D030007227599136299DE5F6642842D30DB2E353
+:10D04000F905117CDEEE61FCE3ECFF8F1473487F81
+:10D05000391922AE8C5C7073FABA43CF7D2C50FC28
+:10D060006E16A26D87813F0BF2913F69798F5488CC
+:10D070006993520B95559473AAF59E443AA45A4C61
+:10D080001B95421857B2B905DFF7B1F9FA766CDB98
+:10D09000229AEFA9298A6CB4CD9B9F1101E1E9E2A4
+:10D0A000FCDE2B67C37D00CA29BF3F41644CBBFC3B
+:10D0B0009C6FB5F6D025FE1CED703CBD48969BA636
+:10D0C0000FC6418840F9C22C5352BB4156186668BE
+:10D0D000811F80CE968FA3D1CB2917DDBA2D0FFFEC
+:10D0E00068367E2D877FC31AF20FAFFF3340CE58CC
+:10D0F00084C32CB0C3A1AD0B2D007968D27E281C4F
+:10D100006A88FE3D29AB3EE281A46939E019740BBF
+:10D110006DAF3B78737211FD530A12338FF2B15425
+:10D12000D1F59E0B528DEA131FC8BBD8CF50DE69D4
+:10D13000244B0F49C44C0BD0AF3907C72D59F39975
+:10D140007C3B5B4F9C1F3B087274B35FD1D79781C8
+:10D150009E52D2C00FF01B9EC9F984B623D5750D1F
+:10D160000AB45F7730DFCC9B06EDF53238C20EFC97
+:10D170009C66FE38E7DF30CCBF2F65E69F44A28176
+:10D1800034C01D0D8900A79FC3294514D3C5FA1DBE
+:10D19000847E47E6E1D90B022067A4907298E125CE
+:10D1A00049ECFD77C3FCA3839822443F053C758E70
+:10D1B000DB42408EB6CBF183C09F66A5C2E5F1602D
+:10D1C000E892A999F79E03F94EE9B2038A00BFDB02
+:10D1D000C2E2E7E19F76C77CA743627AC40C227D56
+:10D1E000A411FDC5E6A12C30BA540A8C9F4992C9FE
+:10D1F000957CDE8F027A7712D035858DE59134E605
+:10D20000DD6410F3AE70B46F12CEC7A11ED027EE4E
+:10D210007A91F2DCC970F52554C4C36870F79DCBD0
+:10D22000F489CB1727D7DBF05724E473FBE26A0DB0
+:10D23000E8249831F219D08BEA4DA6672321D4EF68
+:10D240008936F22AD5579E5F5C48743ADF14185726
+:10D2500031F053C43080AF4375CC5E0246A47FB634
+:10D260008FD57682DE93C3EA227D1AA4DA253AF2BC
+:10D27000DD3A6C57AE387309E343A6C7E530E77B68
+:10D280009D20FFC94113E9689B07E708008F9A3D7D
+:10D290000FACF7492888769805EFC97688C9C76921
+:10D2A0008D2BA530FB65244F58DE64FA90B7AED4C1
+:10D2B00033B8947A2FF2A7D2281D1DB2E933ABDD23
+:10D2C00076C2F031A207B8DCC31F054DD622BB36AB
+:10D2D00052BA7515CF0F2DA6CF9B0566CF908BB395
+:10D2E000C763BD4FC7DB0CE3953486076B9C5DC5F8
+:10D2F000930398F731BBD339CE2E6A8F48722E38FC
+:10D3000052CC5E2921A931743CE493E9552037576A
+:10D31000021D73B4F3EE28F0BFFBD49711FEF8E9B9
+:10D32000E18FE782FFDDA7A630F89F189B852F2BA2
+:10D330005DA94E6A90A6DBE9C5E69197B7DF172293
+:10D340004917B5D7BD0DA2097A7F427068DB223A32
+:10D350003F3611368E1782B104F4BB224AD6D31958
+:10D360004E56DE18D5C1C4DAC8C733CFE5F31CA1C9
+:10D3700069D2280FB450BEDA2D0859769E95FE88E2
+:10D38000CE73C0632F9D57907EF40A837BB4F9B5AA
+:10D390003DA1CD027B6E247FADD494A2ED6F6FBD15
+:10D3A000F592F9147F9DC18A5A54CFAD02DAB91EA5
+:10D3B0002E177E68C9058E1F8AB71F02FC16FFFF55
+:10D3C00068C9E5C8FFF0936C78081A860176EC0806
+:10D3D0001EE8FBA0170BDA48844A10C0434AA0EDB0
+:10D3E000AED0281E683F2B1B07E7D0B9358207FA5D
+:10D3F000F354D0FAB73C5F59BBD146B7570526174F
+:10D400004975219FCF743EF9479F4F1B289EAA2B39
+:10D41000219F16A01EC8E36A1BFFB508B187018EC5
+:10D4200070059B3FE1F8B002E3396EE94312427B9D
+:10D43000B563643E275B7722BF15D5005C4F09CCEE
+:10D440000E273B84D1F8EC2968DFC967E10A232D58
+:10D45000D0F15E2DC5F641B94B1FD040E42BF12130
+:10D460004C3BF97A850E6310DA0D717A58FCEE099F
+:10D47000E928BF7EC3F92354DFB55AA478F6564B8A
+:10D48000A69B8E2334B4E86230BD954317BE49D8BD
+:10D4900073B443C3319340BF1343E63AC0FB7429CE
+:10D4A000F61BA0A767D68D40164A3F230D76F42DB4
+:10D4B000B24134906F0D3123EA033ACF248B6CFCD8
+:10D4C00075848FDBA5112365A3FF461783B3AF6176
+:10D4D000A7BACC07F5BC4887525267407B1380FC43
+:10D4E000147E09F840473E380CE3D7AB0671C9B249
+:10D4F000521B14003ECAFFB8DEB845D68A818F6E33
+:10D5000059A234A7183E5E02FE54458E0B9DFE07BD
+:10D510007602CFDF2FC8D89F0AF800794822A8A743
+:10D52000E4DA785AA0725F8B9108A05105FC4CCBCD
+:10D53000E0C755671258EF15C449C4A0E5AE50CAFC
+:10D540009C4C103F1F207E48DC00DD29F94CD001A7
+:10D5500064BB14FFCFEFD3FADB0FB82226B1F1A3DF
+:10D5600043BE8F6FA5F32E873CB6F486CB6770BEA3
+:10D5700088A07CA7F84C823C57B9DCBB48884A227B
+:10D58000F071416BDACE57ED0A6945FED42FC37AAC
+:10D590001B2AE7EB401FDA30DA091B1C7682B5CE76
+:10D5A000ED4AA4504F123D88F02AA108C22107631A
+:10D5B000983AE172B5B9F4D7C6D8FAAD60F68E4B99
+:10D5C000E5EBD4E42D6C9DEC23DC8E8990CB40FF01
+:10D5D0005226063BF5019AC27AC992EF52D09BB50A
+:10D5E000DE72B52959ED5BE989482400EDB784E680
+:10D5F000CCAEA0E54BDB56CFAEA0727759DB865997
+:10D6000012CD1FED599CCFE48EAEC07C3ABA6D4965
+:10D610003EC07B74C7127C7E74C724CC934F3EFB04
+:10D62000CC45F963E9C8FC8D63FD65DB04B467F79D
+:10D63000BDB2AC14D6B3CBB675AF065363598F6C7D
+:10D640001839E8B5563470FDD299186C78AD12FCD3
+:10D650000C04F1771E4CA2B1A88F999D2519B84EE4
+:10D660009828C6CE15E978DB86D6FDF27C8AEA8F4B
+:10D67000FCA2EEA27878C6573E0EFA5BABC4A76850
+:10D68000363B676DA11243FEF66DCDD23BB344C667
+:10D69000CF4EB966CE25CD5EB0EFF3E9CA84B6DBD6
+:10D6A000E863F3EAFD2101FD0CED9CCE4EBCCA6D92
+:10D6B0009B107F23795F84E8D5193BD155C552ABC8
+:10D6C000FC32D18B74BB4274613A5D8C5D01FC0805
+:10D6D000D3BCAD10E649EF2CA60F7D689F21DE5C20
+:10D6E000009F8676BD59AAE8ED1457DD53ADF57F4E
+:10D6F0009CD943529C807EB7E06C0CB3F969C13F62
+:10D700009A1EDB9488CE027DD79D68467DB6C93FC0
+:10D7100004BC47D64B119453EB817675E807EBDFD9
+:10D720005906F48A61BDF55AFCC01CF6BC76270187
+:10D73000BDD08AEDACD7E36AB9ED796F22CE9E1BDE
+:10D740007175AEED797EDB161CE77A33DE5416CCAC
+:10D750003CB7E05A4F5637CDC9F97C4D4FEEFA37FA
+:10D76000F640FD7678AEDB9FB73595DB9EC3C20AE7
+:10D77000E6B38B736F77C58D6A8B8D3EEB7D9126FB
+:10D78000B46F41E8DAEB55AD19A59EE1A8375A7B95
+:10D790006676BDC868EDD1D55956BDD1DA2362563B
+:10D7A000BD3ADA5EF5C9F5BAEB6ECC7A6EA594EFA8
+:10D7B000EE156D76901BF86E0CFA439B400EBA4C3A
+:10D7C000A27EB796B25535E9280F10F2AF22B35BAF
+:10D7D000DA2CBE0E13A99E96BB2A88745EA16D7DBD
+:10D7E000A45355518B7CAF663DD7A81D6D5F579EE6
+:10D7F000C4DF649B07F99BCE3FE1F3F36F7BC24428
+:10D80000FEEA49D4235F5AF3CE596FBFC8ED1C47D7
+:10D81000BF749CE4BB857C5D0C72F79007D7F774EE
+:10D82000AE49F5856C9CE7D5DAC611A2E32B64E31B
+:10D83000CC7AAE678FCF7ADEE9901BB256ABEAA8FE
+:10D840001F983E580B7AB68490F7C4EBE780BF630D
+:10D8500044BE1573F91662F26DB4F17726EA678358
+:10D860003F7263C2C0B43D54AB0D81BFC92791B4B0
+:10D870008FC90598CF543E9AA057D6962027124FAD
+:10D88000306682FDE8AEA20A86B2BA126676873B9F
+:10D890009C22CBAA99BFB0AD16ED4F26873F4920F9
+:10D8A000FF6EE2B689B76D3EEA11273C79A1467C4E
+:10D8B000EE1CD77431FA17E037A9AD23B77CBB85CE
+:10D8C0005449201F8837B20EE52F41BBEC7D4A0F2B
+:10D8D00037D0C367BA73F921A4B60B906FADFE0AB7
+:10D8E000DB1373C08FD6F649BBBB14E6FD2177640A
+:10D8F000BD0E7A62CD32A0EF9A573CC42D8C8E4F6C
+:10D90000B9ED5B08BFABED1B59E37305238847975F
+:10D9100046F5421DC216A9D4997E5FC6E43DB9B949
+:10D9200016DEBF89BD1FBB11F5AB13AEE9A231C630
+:10D9300095830FCDBDE4A017F51AD1D651F89E7985
+:10D94000E56CEC67CD61C6FF141F889FF7297EC088
+:10D950009E94387D2CF8BA134D48FF0D89D8EC0AF7
+:10D960003A1FF2385EDC15146E80AF9AC35DC1E0D9
+:10D97000EE4C44B15E6FA215DFCBAB36913F3CBE9F
+:10D9800038F076A67E15AB9F571D853941BCCEF287
+:10D9900088551E335C34EF7396D7D17202E5830449
+:10D9A000EC576F0585CF364FA85EAF077CF823ADE7
+:10D9B00059CFA5D08D8847279EF61F9E12183A850D
+:10D9C0003FAA27D186F2A00FF41AEDB8A72CD61CD7
+:10D9D00005BF24E83719E609D35F1DA09768BA058B
+:10D9E000F4164DD7C064837587C4ECDF5EE85087BA
+:10D9F0007F34A2D2FC662E679332E34BA54E4AEDEC
+:10DA000014607E0CA0FFA65762CF7BEB75DC374914
+:10DA10007A78BD0682F52CBD237958BBBDD4AC0401
+:10DA2000FCF406F514749D2CA0EB0258A796A5559E
+:10DA3000F4F747A8BEB2F1A9A6A49BA0BEF55CF37B
+:10DA4000A6A32C2FD5E66A5F2B4C6B65415EAEDB3F
+:10DA5000DA294F6BA6ED3DEB7952A1ED0533CF935B
+:10DA6000DE41D65F1DEDAFECE4F69385832AB65F09
+:10DA7000C7F4B0B50E4B960FAAA6ED3DABFDCDD2C7
+:10DA8000A0BAE61472CC1F69CEB2EBF3AA289DB2FD
+:10DA9000F4450AE913A86FCDAA276BF1ACFC33AFAC
+:10DAA0004CC99297FB87269D925F8E02BFD8E4F304
+:10DAB000514F6C212920E4DF5CCFCEE908D3BC1C98
+:10DAC0002B15687E57E15BEB9ACE05BB99C987D6CB
+:10DAD000B63928C796F62E56409E2F6BBB88E55365
+:10DAE00002CAD1A55C0EB498240CFAE50917B3FB61
+:10DAF0002CFD49753AEACF9660B67E69D1987E6969
+:10DB00000965EB97961DB2C30FA597A2DDDD7601DF
+:10DB1000CA19ABDEB2DE6F3178A01FB0C3414EA38D
+:10DB2000BC8D9536D3FAF7BB3C08C7D10D534A6379
+:10DB3000B89ED4EF6E03BFE9722FFAF99DF8B1FCDD
+:10DB40007713418ECDC8E881A58EFD3367BA14F4F2
+:10DB500000F42BC510CE2FDADF7D2ED6DF524BFF1F
+:10DB6000D0F1364FCDF47F24C870B1C3A532BD2E9D
+:10DB7000517CE4F0038EE02F7663963CFFA278DBC5
+:10DB8000C5FBB99FC3F579DFB7CADFE078B7F91FE6
+:10DB9000CF00BCFC4FF9E95D97D7B2C750CE905685
+:10DBA0002FDA2D7F3F5F990C9F5F90CE13458DD369
+:10DBB000818E6BAA8D6E0E7A59EFFD96E3F31D50A0
+:10DBC00016634FA693134F475ABDA28BDAA1470E97
+:10DBD000CCC3F5F272C017ADB75DD117C23AA595A7
+:10DBE000E3EB28D57F1DB29D2E8B9FABA7FCD6D231
+:10DBF000535620D8FAA7F92E70212FDD51500B2053
+:10DC00002CEF61785EB66DD1EC0E1B3E28BE2BC0AA
+:10DC10000E1E2BA9B9F15DC1F15D9D6D07B75431A1
+:10DC20003BB825E2C0772A37BE5B38DFD07176DC9F
+:10DC30008AE3BC20E0F165F0B438C4D6EBDBF3F541
+:10DC40007CD01347A93EEBA072EB08B7D78F489161
+:10DC50002DB3605EF5BA6AECF3EA881AD97265AE44
+:10DC6000E7BEC8AF72D57F75C78CFC4539E4B49365
+:10DC70004E8B4337F2F9C1EC928FA85D02FEE21F92
+:10DC8000B8623512C839DFFD6F823FEA23FFEC5FCF
+:10DC9000E9582D5B8F5BED84E2D2113B3E3C55345D
+:10DCA0006F93FB6E3D3B2F115BFD321BBF420F5448
+:10DCB0004FCBC4FAA538FF10F2B66DBF4C1E2A58E0
+:10DCC0000CFEA939BA99063BFBFDA0A8BB73ECAFCB
+:10DCD00064E4913E7D440FE162AB6AFA88BE01FFC5
+:10DCE00045B0FC947EE2F6C413B3EDFAC52551832A
+:10DCF000C9EE1F68FBF96CE0E3FD4191D9BB3EAD75
+:10DD0000DF8DE35AEF88474865E55D6D5DC8EF56E6
+:10DD1000DECDFD5B844475DC37F0C40E82CA2ED89C
+:10DD200012597F61B16D5F20BC95D54B313ECE1B42
+:10DD30007BF93D1B738C1F3DB460AFA7D7A19F51EA
+:10DD4000D523585FAA20640CADAF509C0EB2F58568
+:10DD50000AF6A5A782F9BDDAC09907787F82C519AE
+:10DD600078B8FCE8AE38A241BD8F2664BF47C0E852
+:10DD70009B69AF27927CDA4FFE542945000FE120C2
+:10DD8000F74B474FE99796427C3F31D433C852E670
+:10DD90009F9569B950867EE34EE04B921472EF274F
+:10DDA000F17E46E703D6CFAD0963FA6B9519BE5FE6
+:10DDB0000B7C4F71BF35D184F12E45242E803DF868
+:10DDC000A910BB15FA939A2269E0BD8FFEA9E797C7
+:10DDD000E0F32E1CA7D708942EBF96493A1AA2F951
+:10DDE0003CFD6170A9FE7BE79B737DB4FF4230F67A
+:10DDF000E97AE1EE8E8FD7C3BAA970925E2346A06E
+:10DE0000BB0FE6BE08F5C7EBEFC1FB5DEA7B7321F4
+:10DE1000BEA0708AFE309497DEFA06E62DFBA2873C
+:10DE2000F21DC0D99748CF06B8764BCCBFFCCF12B5
+:10DE30009BC7AA64A2BF51A5FC07FEC280348CF91F
+:10DE400040DB73B35F83791D2269C093E55F78215E
+:10DE5000187B5082FD85E8D07C5987F5181181EF39
+:10DE600037CAA96D1827E067FBAEF36801D88DEFBC
+:10DE7000D7E93BEDEBACFF90985F3D993888FEBE4B
+:10DE80004D09B6DFD2C5F75B362442C43E4F7CEE67
+:10DE900074E419583F9CADA09DA019945075A0E65C
+:10DEA000B57EB09729CE58FC109FD7693EBED54AA3
+:10DEB000340D707EF4CA15C88FEF0F5D4A4879861D
+:10DEC000CE27D1B56EA861643ED37A9BE48166A06B
+:10DED000C71BD2D2B9418ACF4DC028B381FCDF9A8B
+:10DEE0000BFE944D7E469F373B96237DA46A292DD9
+:10DEF000C33E66D5A1ABC0DFB991A47AC0FF656A05
+:10DF0000128B9B20D2DF60FFBF03E26D285FC85FEA
+:10DF1000BA4A15683F8AC8FCDDE405163FD409A457
+:10DF2000281C9DFFA460A4C16E0F0774B6AE774B8A
+:10DF30005CCF52FD0EF4EAE2F85042C43C0FE651C9
+:10DF400023C51745BD2A33FC74245AB3E2B21A859F
+:10DF5000D87B802F39281E867D0E3976C374A0FFAA
+:10DF6000EF24AECF4954C5F9C1E5AB2547A58B5584
+:10DF70009C6FB6F9F53B9C5F0F32BA38E7D707E4E0
+:10DF80001031205EE8D0970FC03EF0BD8903C897DE
+:10DF9000E4C9092827FC9AED059BBC967690B42726
+:10DFA000DF169F50277D68D707CEF8032267C71F6B
+:10DFB00058F10B4ADBF7CEB1FBC5C5508CC0BAC0D7
+:10DFC0008A3BF0CA7A967E53DA7E80F5BB126DE703
+:10DFD00000BF8EC0CBD7417E0E1FB999C11FE2F2A0
+:10DFE000CB1ADF33AF2C4BAFA0F8DF9E64B2797B46
+:10DFF0008CADF7FC0554F20A99792A25D9F846E840
+:10E00000EC18DF7899F9ADEE491CC3FEC30003E6B6
+:10E010008731EFA788FA3F10CFB3DF81473EEE8A02
+:10E02000E224AEFFA9DC667874B44F0E9C1AFFBBE5
+:10E03000299E583CC617A3438D9C3B0E8BB4D1DF61
+:10E040004C7043F0DF27B4746666FFDDC28345176A
+:10E050002B4FD7758153F9C17E9C38319BADEBC9ED
+:10E060003990FEF8E6352AF437F16692023D3031F8
+:10E07000CCF87B629278ABEA301F8131EA262BD74D
+:10E0800079B99E34D4B23ACC63399D06582EF1F258
+:10E09000EEE0FA7D5374982FFC7972F8375F06B979
+:10E0A000D44A22205A651E2F1A0A0D3F3F05ECC4A0
+:10E0B00036E61F2110C940F17A37C76BF8E6A05841
+:10E0C00045D392509478983FC9606A85D5DBC1F1F9
+:10E0D000E136EF1100AD652152D804EDC5B2DBDBAE
+:10E0E0006ED50B31B8494F76F936DEDF244D8269A3
+:10E0F0004ACA4386067E7252CFFC3256BD246F67F1
+:10E100005228DA5466F31359E55B78B927148DE287
+:10E11000FB4956EE093E6A94D1B43FB1ED1CE0C70D
+:10E120008E44CF396C9EB0F736F1F72A42C480781E
+:10E13000941F2792586ECD2BAB9E25C7A50EE68760
+:10E140009C7C731CE34C2CFA7672F965A5C0F71021
+:10E150008A5B598CB8A3E323682FC0BCBC993E9757
+:10E160007A29BF4ECBC1EF84E54BE98FC7C10AB016
+:10E170005EB1F8CBF21FEC3F7C7616BF9136CA5FDA
+:10E18000563BA04FE294CFEC7163ADEA3959E531CB
+:10E190002DBBDC0865E7EBF5ECFAD555D9E5159113
+:10E1A000AC720B8EDE4433FAEB3627DA6635D27466
+:10E1B0001BF7FF6E1EAB97C0BA60E758B62FF4A3EB
+:10E1C000441CFD7B7771BF7007F70F6EE47EBF3E86
+:10E1D000EE27EC01FF1FC895B6F659104FB93D5117
+:10E1E0003FAB91E6F7723C93866C794EE5FC5E1985
+:10E1F000EC87BAA8E942FE60F27DB327DE0CEBB0F3
+:10E20000F1B14141B4E1ED6999E9FD305FDF50833F
+:10E2100052B0C7FD3DCDFBB1E421AD1884FE327A8A
+:10E220002CB54E617AAC06FAFBB9CCE327746AA12F
+:10E23000D8E276F243DA3AF8BB51309E06F8368FD0
+:10E240008DA3DF4FD2A206F8B903868EEBBC30B5A2
+:10E250009B619CDEAA81B40871AB15ECB9D640F184
+:10E26000615B876C2E48A3BFB37B0941FF9647CF04
+:10E27000F64F16C37A9CB633DBB5E05732857F0282
+:10E28000F787B7FB9716B3FD67B62FD722C43E8139
+:10E2900072F72137EA4B7798C5435C20457F0DCF55
+:10E2A000C77CB507F7017E0D736606C6CBA19D50EE
+:10E2B00078D1D52AC643713D4BAECEA683853F2B80
+:10E2C0006E84D26548B6ED835B74F9B56CADCB63F3
+:10E2D000C5C0E73709B1A3508F548554FBFE91E2C6
+:10E2E0008B1AA002ADFAD638CE520C84D382AF5C22
+:10E2F00031FE0CEF8FB44B68BB7E8843304D91C22A
+:10E300003D01E0A5F2EFFF4163334E865BBED18055
+:10E310009DAB93C7D79C3BAEC8191766EDA3AF065C
+:10E32000B868FFC765C6EF8563E2A11A1BDF4D54CD
+:10E33000185F75CBD63E295F07F2780AFCC17A11C7
+:10E34000F2747E152B2CAE9662C5CC3B0BEC746A36
+:10E35000D8801CEC5652BBA95C191763F6E7F64E41
+:10E3600005ED5AB9B56831C43BD0399B867D6FB98C
+:10E37000A36BB580F11171A49F0A127552C63FECD0
+:10E3800083F83E9AE693614C35A2E13AE1DD4543DC
+:10E390003701117EE48E952AB4FF1BD4D8440805BA
+:10E3A000B9E92B837F12E8F35285E1FD5CC928515E
+:10E3B000669CB2FE4278EE23C644A8378E18BA8215
+:10E3C000EBDFEC78566B9F9DFE5EF4DBE84FEE11C1
+:10E3D0009DF3FC4C685FE6F18A237115BE60CEF8B0
+:10E3E00031E73A89FE5EF3CD3C55FB3A5B87707EA0
+:10E3F000B7DAFF61DEB47CB0CB9EE97161DAD53665
+:10E4000009D33F89644B3DEC0FBEE022B9FC865630
+:10E410003A047600E5D54685D94D17F17E16499A1E
+:10E4200002EBEE45E6C7B3EDFEE24526F3FB2C9288
+:10E43000187D17B55D718F3DDED25A073BDFCBF8F3
+:10E44000A7862600FF3BCF4D38CF55AC75259B04E2
+:10E450003ACE8FC464149032327ED53058AB8CBF24
+:10E460003F473B3DFFA0760E007F9DAE9DD39D0FA5
+:10E47000719E0BD95041DB03FE57A3D88A2065C794
+:10E48000BD58F1340AB797DB432CFE85544570BE66
+:10E4900029F46F584FBB9202D3173CFE45AD10B321
+:10E4A000E2929D712FA4D914ECF1BC561C0C3A3A9F
+:10E4B00066DAE51C61E71B3466875BE73CD037888A
+:10E4C000E777BE97759E42F231BB7743456D561C88
+:10E4D000B24458DC38848B313F54F67BA3CF0F47CE
+:10E4E0007F9765C3FDB9DFF349FA519BBD30FA7BD5
+:10E4F00012396AF35FED047982FEDDCF302E1D897B
+:10E500008DE34E8F473B28C1E2AB3F90D2DF003C0A
+:10E510007D30AC10387FF1A44CF66B407741D06170
+:10E52000BD6A68977C0DCA8D975C41B18C2397E6D4
+:10E530009F7CAF09FD49F72A32DF4F1B7441BBC6F0
+:10E540005FB54683E2AFE107B45D90ABEF2B02C845
+:10E55000D5397F4D2F86FCB9C3CD32C8D55F3EF883
+:10E560000CF67BDDF07C09F20FF376DEB9FFE19962
+:10E5700084B6F3E45E3F49A31D9152605D73DDA351
+:10E580002EB42BAF7FC88FF3F7BA4756ECBA98B6C4
+:10E590002BFCC48FF0343CB2EC5EE64F6BC7715F6E
+:10E5A000F7F8A5813E80F3F72EA252FE7B721DF391
+:10E5B0008BAD70834D43C8F07BCA2EFBBE95858F13
+:10E5C00091F5B256B35F03F8F694D5B86CF4BA4E31
+:10E5D00022DF047BC3A0E9821CEB943F7079F4F640
+:10E5E0007B0AC6650B7BF62DC4710E5C81E316E8D1
+:10E5F0004C799DE2E7453E5E5A0FC763DE27A42AA9
+:10E6000069F9DBF7096C7C0353FB3D65D07FBFD212
+:10E61000828B50B65F42E1FF26D85F8D7B6A3A4A13
+:10E62000EA60BFB8AC0C42A92E78682FCA4F3807F1
+:10E6300024507AAF246CDEADDAE34AC37A66E5A3F0
+:10E640002B30AE91E6717D73FD434F3D6EFAE17D57
+:10E6500057D67C5B39B009D77DD7FFAB3B92A6ED8F
+:10E66000BFF5922BE281769E90B3FCB76F0DEECE94
+:10E6700007BA9C7F22DBAF0BFD9E28C47E16298142
+:10E6800093DFA398C7F8EC55031BB09F55C4E6F77A
+:10E69000A5E37D0BFE283E799DF937257B9D798387
+:10E6A0002B1A4803BDF78CC9A9A746CE19703D7532
+:10E6B000FDDE0FEE3669BF6F3FF2E7BB61DC37FC72
+:10E6C000ED2F777F0FD6373FF768A06756DDFFFA4B
+:10E6D000DDDFA5E37DE709B708FC72DDFD6FFEE92C
+:10E6E0007B34FFE14FA71482DD187233FBF6F8C3C9
+:10E6F0001F17E9B49D1B9F9A370EC67FE363178CE3
+:10E7000023A7D8773C4EF92AE5B6CFD314B6A33F5A
+:10E710002180F2A68CC95307DD9E79F4995280EFCF
+:10E720009D836E8C0B58A5B3388095032B30FE1259
+:10E73000F2B0FE59F960379EB33A19CFE67831C48A
+:10E74000E63B84E2AE7CF4D2AF9D5B07A98C719C62
+:10E75000ABC87017F8019DEF8DD0EF254ABFB34EBF
+:10E760002E5F4518DE573DB881F5EBA0DF3BF0C7C3
+:10E77000AC93E937D39D4DBF0FEFBB329086C247B4
+:10E78000C7E4F4C75AF45BF1D8D74F792EE5B863E4
+:10E79000DE8E86DF56EE3797DCC67C37CCCF47F26D
+:10E7A0004C38DA70FC6577EA625A76BCF32FA5B074
+:10E7B000A83C260F2F84F937FC945B83FDF1454F6D
+:10E7C000FD41017976FCB1DF283AEA3FE213A81C4B
+:10E7D0003F4E467E8320D731DE1EF0738F3F0D7E85
+:10E7E000819537B7229D56A62E69D2F3F139FA0BDF
+:10E7F00056A618DFAF4CEDBB4CC841B7EFBB0B9929
+:10E80000DC4E8DE5F65B868E423DD0EFF07CE0B7C6
+:10E81000D1E8678D5B83719F6DA3A7299F723E1E10
+:10E82000EF774B0294F3737B96BDBD2A25FC81E400
+:10E8300098A7D6BEC5173D37B4D63D8ABF888FF797
+:10E8400074F3F8F4E3F962F85AE6D6B15D27DED640
+:10E8500075BA510EFFA9C68D71498765FD876BE9B1
+:10E860007C1C7E5E261067B1B0F60D59CFE167FEC5
+:10E870004FCA8FBA8D1F636DEF758EA3EFC56E669D
+:10E880007AC4B9BF13BBD945741B7EDEA50B2CD04F
+:10E8900017ABEEF6A4C03E75FDFCE585200756FDDE
+:10E8A000DC8F7260A57BF85EDC97FCB19BEC663C6C
+:10E8B0008776C532EED77BE6B1B558FF382D87FA9B
+:10E8C000EFFE3471F43B741CCBB7B1CAEF3E129823
+:10E8D00046E8BCBE9EFE0DFBC4CB9EFEDE57814FBC
+:10E8E000210FFB9A47C7C61F87F68FDE35A106FAB0
+:10E8F0007FE6B18FB0BFE30FE511D0AFC79F7EE3D6
+:10E900003CC0E79F1FFFC934907FCBB6C9BADDEF8B
+:10E91000B2DC7EEED9A65FAF1FD88CE7BFAE8772A0
+:10E92000565FF88CCF19B0A7A07FB04FAE7F2260A2
+:10E9300078A665D5C37656B9876F8AA07E334BC457
+:10E940007AA46F09D0F9FA3DD9FD3FE966FA7795C7
+:10E9500032BC94D54F96307E18C4F79EE772DC2AFD
+:10E9600077BE6FD5FFA5BB3CAB9EF5FE4A3789E766
+:10E970008A3B7C89B77BFD9E4FA764B7C7F8F6E456
+:10E980007ED8F3E35EB6FE5CF1B81FE9BDE2696ACA
+:10E99000DF4C83FC2F4B01BF2B9E5E8BF459E14E65
+:10E9A0002F04FFC6F0C36E0276CBDB0F3F8FE56FFF
+:10E9B000CBE9D242A8F7A4E730CC5B275C2B06DC7E
+:10E9C000FCF06776BFB05FC9FC7869DC3F72F17D0F
+:10E9D0002EBA928DECE671672C4EB218D7C5CEF5E3
+:10E9E00081572D23B9CE8B77C2BE03F8FB549368B1
+:10E9F00076FF3E617193FFE5E00B458E69B05E5393
+:10EA0000041205BCCA52AC07FC9272285843212557
+:10EA10005DA105E8D7E9ADD670FEA82AA3AF9BB6E5
+:10EA20008FF6ECFEAD18FFAF86A5F7B3F6975FF350
+:10EA3000619C1EA9B03D2F4717373EF755D3E736E7
+:10EA40007A28C1D6ACF3D1CE7DEC9F090C1FA6DF8E
+:10EA5000CDCE8512D305F3EECACC0608FAB75FB661
+:10EA6000CE674A1DACBCC02AEE60E57C9EAE6A61F2
+:10EA7000F3D049AF2B9FECC6F39A573E598C7E8753
+:10EA80002B7D535E07F9FB331E8F6616B8911E6708
+:10EA90003D19BDF49F68FE9AD64A3C7F543D10BD97
+:10EAA000682ACD5FDD3A09FD5C5F52193F7EA35FA6
+:10EAB00034654A2F94A100FF770484FF9BB0D0A057
+:10EAC0002F2E22BAC2164D29ACBF980CF8597E6081
+:10EAD0002CC499DBDE77F9E0FDD502EE635DF5FB32
+:10EAE00097E6012EFFF8D2914E48BFF92251F26805
+:10EAF000BF8B1ED5BB981B82B7F7246D4FCCB49744
+:10EB0000C123F3B7104945BC64F0A422DE5E1ED9D0
+:10EB1000A730F15CA50DCFB8AEB4F03C82B740F39E
+:10EB200057480EFE1F29F74D7E9D4CCBC0E5C4F320
+:10EB3000CB241262EBA35ED61F3F37FF177844ED5C
+:10EB4000868379FF2283FFE8650A3FC47BBC9C3F34
+:10EB5000793FBE27FB7A408F7F83A46578FF1A3206
+:10EB60002403FE9CF85D4C0C05CA979074172CEE9C
+:10EB70007EE48E5DA9523856BA62138BA0DFF02076
+:10EB8000C635911773DB4319FBC6E4F38EA7AA4A77
+:10EB9000D4228C2B41785B86DE4B005C2DB47BD07D
+:10EBA0002B1E62E96B76DEA3E5D09B9FDACBC948CA
+:10EBB00039F3CF8FB4A3F6E2FEBAAD5E96BCC67A47
+:10EBC00042AE7668DE163771729EC1E17CDEA2E647
+:10EBD000E3B9921C7011B308F067FDD8FBAF0903CD
+:10EBE00067C2F9FB1E756E630F95CB0F140E96A8C6
+:10EBF00034BF519DDF01F17C7BE97209F66F69BE7C
+:10EC0000D16C80BCB110D66D8B25CACAB6FDD75B5E
+:10EC100054E667BE45657E4E5A6E42F966C8CFC05F
+:10EC2000F82A12A679B86B214CE9FEEA83E5BF3ACF
+:10EC3000531F9D3E2DBD9FB9F51C721E2EB008CEF0
+:10EC400064EB7AF44B3E1731DDAE8C1FF88BFA1370
+:10EC50000B4904D32089626AC523844812D3123237
+:10EC60008069980C625A4A8631D58926323E67F30C
+:10EC7000A09C44305F490C4CF796513D10C4F3679B
+:10EC8000919D39E4FEB86BD8BD117FA57A017C8CCB
+:10EC900069B53CA71E70A9173574D8CF3FDDA7E230
+:10ECA0007A78EF3A1DE9603D4F73399556991F7791
+:10ECB000EFBAC8C118950F47EE5323E08F7FD54FA9
+:10ECC0009402DAEFAB9BFF50BEC897A9F740213BF7
+:10ECD000C775E2F04FCE84730F5B55639F8A70A4B3
+:10ECE000913F2D7E59ACFA98DFB9577EDBAE07BE57
+:10ECF000A9469F87F977E05FBC68E7ADB945403B1F
+:10ED00008FE802CEA76B399D1E281C780BE29DCDA3
+:10ED10002D6E1DE4E6B5BDEEC378BE3939CFB0B770
+:10ED2000F732E72392FC21EEB35E7B1A3FCFB51496
+:10ED30008DC067CE7608995000F631FA1C6CF555F7
+:10ED4000C2CED9518262BC413E5FCFB4EEFC3804E2
+:10ED5000715C6F73BDD8BA85C4408F1E13197EFADB
+:10ED6000F879C83754E6F7B6EABDCDE11D93BA127B
+:10ED7000FDF4AB95D8DB800FCAA759FE79F5620385
+:10ED8000CB8F2949BCF7A4EF4A76DFC0D486CBAF3E
+:10ED900007BD34B5F926B44F6E175221BCBFE13E12
+:10EDA00037DA0F73CE6C7E0FF7639A151DF03AB504
+:10EDB000593140DE7AC1A941FB997C711C4E6891A2
+:10EDC000B7CE4D9580DFB015E28CD0DF13F360BC79
+:10EDD000D013EC3CFD75DC7F78C79E0B02A75A6709
+:10EDE00003906656FC1635ACB2E44EA1235FE2A850
+:10EDF0005F9E553E1EC284E87C1FEF23693F4DF79E
+:10EE0000AE37E700DFF7B59008AC0B278062A2F4BD
+:10EE10001B4FE505DCA301EE362F4DC334AF166260
+:10EE20003971F1F2004D7789034D40D4523E7E4D49
+:10EE30001ABEB0B30CE66B8F10F7D9C73FACA291E6
+:10EE4000C2C75FC461A2ED1068B7AFB95683F29430
+:10EE500042D6003C779CCBE851DDFCE142A447C39D
+:10EE6000FCE590F6CB546F82FFA69FE8EB01FF7B99
+:10EE7000A62CC1E78AD602CFADF7AA9ABBA240BFA3
+:10EE8000A90D45182F77C15001B6FB16D00DCBEF59
+:10EE90005800E56E92CA877316A45924A0FFF74E56
+:10EEA00088FF7202B4AF93085D0982CB8E780A3175
+:10EEB00035FD85B0CD4952102F33351C45BD5C2C36
+:10EEC000B1E7741C868CE5E9729847530F2D7F07D4
+:10EED000FBF558F6646CC36CDAEE03F5228173C25D
+:10EEE000CFBEE2467BE1ADB20ABCA7E681C2C81F35
+:10EEF000CF077A7DB2AB14F6ED765EA510F0436EC7
+:10EF00000727157DFF8E4FE321F08F558495349CA4
+:10EF100063DD3BC1749702DFFEC685F204E8A1D62B
+:10EF2000229D483E4D77EE3CFBAA5FD0E7B7258691
+:10EF30001A3A709D19295E608B2FBE4D8E5C097147
+:10EF4000425FDBF0506390CEB7DB789CD00F3C2F54
+:10EF500074C0398FBEC7A84CA7765C9F157757350C
+:10EF6000ACDAEFA368F60859EBBD3E7EDF0BA918BB
+:10EF7000E6F136C32AF4F7EC2B6B43B00FDDD75024
+:10EF80005B0EEBE1EECDADC540E73B3E1D0E81BC17
+:10EF9000BC8D8F6F2A9D9E7329DC150D747C146FB8
+:10EFA000B72B8322C805F37182F36EEAE5FFD50C17
+:10EFB000F2C1DDF6BB0688EF69F31470FFEC30DEBA
+:10EFC00093713B9C7FF565E0706B6C3F76AD87F984
+:10EFD00023D778987C8873B8E95CCC920770FEDF01
+:10EFE00083FB075103F8777DDE57D1EFDFE6E1FBC6
+:10EFF00084EA30C6EFE5786FAD87B6A75E7695D127
+:10F000004932EFD1F1E3B9DFBE7367E2B89F7DE526
+:10F01000A310F831FB36EF2985F15BE37EEBD35883
+:10F0200031E0A1A299D1D51AC75489A4E1BE1BE24F
+:10F030008B94C37EF3160F936B5639A567F9D76D82
+:10F04000F4D8C2C779BB979757B1F732E5FCFD7C7E
+:10F050007E4EB8C259CEF0F3EC2B572CDF0DF3E8FF
+:10F060003135022E843B36B78500DE6E80D3978122
+:10F0700013F4138CEB4DEB5C3A0429533E0AABA41A
+:10F0800043ADCD25C7989F97D4B338454B9E8C6A26
+:10F090000786A822B7E1D9BABFE385606C37E0DB09
+:10F0A000DD3CA8801B49AF189A0FE93CD7C518EF83
+:10F0B000E0E6FBF4CE768F25E84A85AEDF6E4F5052
+:10F0C00000315E4FC3FC6D8910A6A9848ECF9FE2EC
+:10F0D00078F28A4CDF6C74DC13F628C793554F86A0
+:10F0E0001D8849103FC7F68DA5AA2EF4074815D6EE
+:10F0F000FD2F23FBDB4F01DC24963BBE8C16087CE6
+:10F10000BF7D1FF061D1656C5FB9A899EDB76FE164
+:10F1100074B7FC57163CCF73389EE770FD073879FB
+:10F12000A11F7EBF883BCCEF19B0EE1BE1E7194E63
+:10F1300081F7212137DE5F02F857240FCF2FD62128
+:10F140005E96C54F5AF1927F6D60F76D8DA6C72C04
+:10F15000BC5B74D8908861FEB6442BA681CB18FEA8
+:10F16000528938E65B84E861E82FD070EAF11FE548
+:10F17000F3F9CF1C0F9F779C777832FBEA18171CA6
+:10F1800064F785DC71E5E5A1C5F4F9871E7E5F486B
+:10F190005CC819B740E9F921C067EDEFC37E23CC05
+:10F1A000F7FF50A327501E90E4234B840C3CA75B31
+:10F1B000F71C81B85C3AEED7200EB7F2F4FB966BE1
+:10F1C0006FBB418175DBA742CCEDA5EF7F74EB5798
+:10F1D0004C70072DEEADC17D3E6A37AA5EB0F303D9
+:10F1E000FA8720E78939751EC4DFB6B8F5C7217FD5
+:10F1F000B84E9D07F1B62DE3F49B60BD71C946DFA3
+:10F200003C88176D99C8F4C0928D0D9DA0077EE5CE
+:10F21000310ABCB84F2C17C07E9DD37E3B793CD9B8
+:10F22000FB75265C00C2F8CAB4E391F253A9F7EF6C
+:10F23000E2278B8F543E8F35623F3741E7D199806B
+:10F24000178BAF4EC7476779191FD5F0F442AFC689
+:10F25000F50BE3230F97074E38667919DF6DE072DF
+:10F2600082CAB51EBBFCB3E461918BC4412EEDBBD9
+:10F27000EAFEABE05E38F79EC9E530BEA02BF5474D
+:10F28000B027C9034AED6E1B7FDDFFF1AE92053E4C
+:10F290009043A992DD507E3F2DD7215E391E82FD1D
+:10F2A000B9EAF0870BE17EA2EA0A92AAC4345D5E55
+:10F2B00046C719E4706EE5F5A6868B16839FFEEFB0
+:10F2C000A5DF8F3DD14B191F3039F50F68EF1AA01C
+:10F2D0000FC5AFC0D6577F5F7B14CFA84FC09E54D9
+:10F2E000B81D04570E9148E4CC7F04BCFF5BEF07C8
+:10F2F00048CC84BB5E02107F45E9E8EE5D4760BE06
+:10F3000050FEEE02FC79B6F69BA0FF56350CE07A73
+:10F31000C6E26B6522E337ABDDBBBD6C7D7937E7B9
+:10F320006FF8E9743E4EC63F58BE97E6A7C01F541B
+:10F33000AE4CE1E74CAA4812D7CF6792014CABC95B
+:10F3400020A6D3C830A611A2B920AD2511178F076A
+:10F350009A09E90D6AECC7A0927EE48EDD097CF380
+:10F36000CE84D83F43BCC6FABC95B3611EA6BC563A
+:10F37000FC553A6B5D4BB8DFFF74EBDC71C4B8C76A
+:10F380009B233E087EA39DA389D8E2BFAD73345F63
+:10F39000E03CC4A3D0DF49E721CED2DF63E71B56B0
+:10F3A000A07CB5CE336C1E7B0DCAD7C2B309FA6BF5
+:10F3B000FE7DE39A67419E4A17474D84E1A5DCF143
+:10F3C00070562A8F63F1651D05976B183FA6B2FD35
+:10F3D0002B89FB93AC7ABFF3EAEC7E32479CD93F92
+:10F3E000BA9F93EF378BFE1EE76FC67E2966A96131
+:10F3F000C50D1E477CF1F8384963F27734B8D6E77B
+:10F400002DACB79F437215CC6CDA478726E65D1D9D
+:10F41000B1EFC359E31DA9E763707DD1783CAABF62
+:10F42000FF1DE077C6E539F582959EE0F3E75EAF14
+:10F43000F11778CF16C7F6118C33471CDB09784ECD
+:10F44000F9F46386A76C3E3DA60C5EB98CCAF5D76D
+:10F450000BBCB87EDBF7E26F8BE1BE08A5C02B6268
+:10F46000BC07F7B778B99FA0A384F9A736A55C18A5
+:10F4700027BC6970AEBE2E08F1ED0A72DFEEAAB9A4
+:10F480007953C13EE871B1F3EADC8FA214EFC7F102
+:10F49000DDEA7721FC9B4EB4CF84F7CC7A82EBDD9A
+:10F4A000B9F586BE0ED6916710B4F75BC79CD896A7
+:10F4B00047F377BEBC0C9D7A0D7EE65FB9B35FE182
+:10F4C000F7BB1284E3E88CE8EE8D6599FCB2E0822C
+:10F4D000DD306F6A21B099D6FFF6864918EF06F73E
+:10F4E0003330F7AAE962FB55569A76B1FD2E96772E
+:10F4F000E23BC0F74D9CCF3FF5337D1B38F7B2039D
+:10F5000017D0F697B4E25D1630CFF715D37CB281F1
+:10F51000EA489A0FF4B0B89AA4346CC2D224D960E5
+:10F5200050CAD3E7E121B81384CCCA93B19DFC9EA5
+:10F530005D02AC6FBCAD2C6EFB24FD9EC7C69F94D4
+:10F54000864C17B64322266D3F9FB603FE9CD3BD63
+:10F550005F93C7ECC8243FE7B86CEB228C9B59B68D
+:10F560006D9C00F8B5EA5D98C7C6B5DB10F9BD170C
+:10F57000516CFFC8483EAE403FFE60EC6EB827D2EB
+:10F580001F52902F7C3B040FF8157C2926FC020D9E
+:10F5900031F46775D272F0632E23B152905F03D2BB
+:10F5A000C0CB4B015F147E702107B60A881FA9B03B
+:10F5B000F5EEEF001FCE4ACE023C7EBBFF53720633
+:10F5C000EDE7051F3BB719D04EE07D40813A76BE8E
+:10F5D0002ABF21F73807FCD97EC27C2E67FD5B77F6
+:10F5E000227E4AEA59FCFC9DF2407191EDFD0F7CB0
+:10F5F0008C2F2DFE72B65B9CC7D6B55DC5F7221F5A
+:10F600007B253A3EC05F582170CF86B8E33778EF4C
+:10F6100072A04E8C7C19647F247E10E8D45BCFB737
+:10F620007FC85033C6412F57302EEF18E757B381AC
+:10F63000DD83EAECEF591F1BC75B756213C0D3B7BC
+:10F64000FCB962E0971DFEE150B01ACA193C7D7EFC
+:10F650001FBB9FF2FC7BBF3A89F6E77A607191A0ED
+:10F66000DBDB61E3AAA0F61B9C77DB94F7F3CE0EFD
+:10F67000CA9B15E050A3F6F5539B9FED84F3577793
+:10F68000F5BB387D758C3BFA456AD27808513D7AD6
+:10F6900003F32F1E8B59FEB334FA0FEF9C136371E3
+:10F6A000A4CB458CEFD95EF75B15CE696CAF10111A
+:10F6B000DFFDA9F67CE0877E23580BF9C981059B05
+:10F6C000F2C6C2BD7E736F9D0CFC9BAC1070BED0A9
+:10F6D000BFA599781A08DFDBC2EF7BD0E69314C48C
+:10F6E000CB153428686F1444D8B9914D275C6CFD54
+:10F6F00051CFF6B7B4E4C1EF0191B506B6CED5C28D
+:10F70000777C8B119DE9DF00170D1ADFB7D11A95B1
+:10F71000AC78005AEE6BC57B7CD97D7A161C814192
+:10F7200031BD14EA87BC8717E7B37A45B548DFF4E3
+:10F730004CFABC20747929D827816AF1F0E2691962
+:10F740007FF05D028B7F3567293B013EFADC403A52
+:10F75000CF66795ADEFC08F0F181E128C229454BD9
+:10F76000C13F15A83F7A35C017D8FA071C4F00F6DD
+:10F77000912035B2E12DCA371EC9E3768461E3EFEB
+:10F78000FC3A769F21EECBD0FE5F5FC4EECBC8E79C
+:10F79000E7E1EE1238BF2D217C7F95D6B29FBF02E4
+:10F7A000508AF87D7E22FADD1E8441FBF93ED5DBCE
+:10F7B000032E7C7F5BB38EFB12C714D6DEEB17B231
+:10F7C0007EFC0D5DABA19EBFDEB6EF44FFFF751E54
+:10F7D000B3F3EE1232EB5CE8A718FA29CFE4F17C20
+:10F7E0000DEDF7E1FD851755433FD716E23E6B0758
+:10F7F000C72BFE287DF0F0399523059AD738830E64
+:10F800006E079F270FF37A5B0E68BF80389B39FF26
+:10F810007648053FD72E5F88DD135EFF3E9E93ED51
+:10F82000D318DC2571C65F25A16115FC7B4B7A04DA
+:10F830006D27DF7F83FD309DC343F8BDACE11E2DF6
+:10F8400005F356EF110C8863853D7F71260FF9840F
+:10F850007D9FB8B91A909DDFF0BE80F80B713AB465
+:10F8600032FCF4E943705731B9B347C03850ABDDCF
+:10F87000927ADA2EE58B3B291CA0775FDF2A929DD6
+:10F880006599F1A2FD49F1D47283887C15AE27FDFC
+:10F89000700069719C601CC7EEF0C0F3F0DED1DB34
+:10F8A000DDE887060606B84AF97B8BEB295CB45E77
+:10F8B0009F31DC0376E5EE1BD83DB8A5ADECF9E24F
+:10F8C000AD3F590B7EE2DD2A8367592BC34BE936E6
+:10F8D000F67C191FC7927A3A0E80AB91D197A2D6C7
+:10F8E000FC4C84FE197F1F5D4EFAC1DFAD4C880DC4
+:10F8F0004E06F91E271AC4F194F766F3AF35AECA67
+:10F9000011FC32F8F31B8A74C0C344339B7F2C3C38
+:10F91000B7F0FA95306EC07F1BAB27C1CDD0F4791C
+:10F920004B2BC37F653D4B17F3FD4F11CA611F156C
+:10F93000C603E50D8F63DA1BBA765040BDADE81003
+:10F940007BDCB2D5D12F2529C8251FC7E3EEE729D7
+:10F95000D940086C65F45F57E865F6C7B90AEE6BE5
+:10F96000F95A59BB0F8BD1EDA0C7CC8D6E8CAF87E8
+:10F970007BB375DB7AE1C8A72CFE74F3B9CA1EC04D
+:10F98000171D80807CCDFB795864F8366B997CAB71
+:10F990003D9BC5AF6E89287B404F17D417CE55408D
+:10F9A0001E363039571039FA7D2604B2F77B7D07B1
+:10F9B000D8BDA1A16BB3F14FC763C0FA74448E1ACE
+:10F9C00004FB2972EC0B43BD022AEFB4BAA2B920A2
+:10F9D0005767D8DBA7E5852F4A288F7D07A2E52842
+:10F9E0007F0FEC5800FED84247BD947F12CE3FDF18
+:10F9F00081B888F560579FD6EBE6F79882294E6A62
+:10FA000031DD0F29D5ED661ECB9B4221E045228DCD
+:10FA1000B03F34278AF753587AADB746A989557352
+:10FA2000FA14629A26A738F7DB5B537406E86DDF99
+:10FA30008158B98670EB3A4B354C2D78ACFAC95ADF
+:10FA400082F8F3FBC5ACF3AC56AA35FE2D6B1FFA5A
+:10FA5000AD7CF3A67F037C9EA7A03DDB2E0FE33D8C
+:10FA6000EFED8FF9C0E34CEE2F4895C0BD3DF7F99F
+:10FA7000993CB4FA23D597A17D0C2136305E42988B
+:10FA8000FE38D35FD50FF361AA61A29D3CB5222C4D
+:10FA9000B4A3506271819DC4D0414E9A6111F9ACFA
+:10FAA0003BD47513F0E3961EA110E4C396FAF22E30
+:10FAB000906B037122821C4D723939373ED404F5A4
+:10FAC00036EF13F13CEDE69F1AFA1F69FE430A0375
+:10FAD000D89373EB937128BFB3D287E577FE3436A2
+:10FAE00045B3E10522B399BD4C246E478B3C5E4C77
+:10FAF000C8653F7BC72E50C06E9BB87591097EF1DB
+:10FB000082AD0573400EEB8D54C4423C6088A287E1
+:10FB1000E6BDFCDCB46ED0E767C3BDABAC5C0FB335
+:10FB20007C672286EB6052CDFCF667F65F8AF71D94
+:10FB30009E79863800BD770E368E017BE368AB88F0
+:10FB400062E5D1942BCB7EB5D6DFF24BA90D70AE1A
+:10FB50007CC656116E6825BBB75D3006F86834FD6B
+:10FB6000F172DE19D639399443384F5D197DB245AB
+:10FB7000E3727C2BD727E121D427E11D549F7039F4
+:10FB80000EFAA49CCF6FB80802EA576E2B403BB028
+:10FB90007C878072BC7C2B93C74B43433D289740A6
+:10FBA0000F08197D45F513C6AFC173C88FDF21A4B7
+:10FBB000F020AA147D01EAB76C1B87F27349C818BC
+:10FBC00003714B4B9AA5C84E3D236F752E3FFB1A10
+:10FBD00044E4AFFC1D029E67B7E4EB445EAEDFC0B9
+:10FBE000F4CAC49E752847F51D2CC518B7A28CBE53
+:10FBF0003B0AC148142F13E303A827742E5F2DFA84
+:10FC00001029A29FEA3EF1CE1DFD73701DB1639FC6
+:10FC100020D27453708D02E71DABF8FCB0ECF7F105
+:10FC20007C08E11D87D93AE70666F71F2DEEFA2A10
+:10FC30008CA3AB7FB102EBD09208D343BEF0D27B52
+:10FC4000414E9EC5D79923E7EEE3AD784EC3CFE191
+:10FC5000CFAF1B36A0BDC0D605579C8176FBC078C0
+:10FC600041CFC0F9862F9FAD3BEA860C2CAF67A62B
+:10FC7000E1EE86680FACE3960445C4A9AFA71DE189
+:10FC8000A0EB1E4DB0F989FFD39787FDE7D7B37579
+:10FC9000D0E6AD6C1DD425A7E19B20243F22E2FADB
+:10FCA00047AC8F6D5B04F4A2EB535837740BD1ABA8
+:10FCB00060FD48ED47A63F824C1EF44D98BC13E80A
+:10FCC000BB65460AEF1DBE8EDB55B88EA076FCAA3A
+:10FCD0004D2DF3C1AF638DD3CDC7E90F3BC6599FFF
+:10FCE0003DCE45797C9CF5836C9C756C9CB47ED62E
+:10FCF000388F49695CBF1E8B106D9D0EEB295A1E13
+:10FD00008475E02379D05EA61DF3AB408700C5075C
+:10FD1000D021B0F51726D45B42DF83769CFCF00936
+:10FD2000E0692CBC4FD8BE7DA3D35E3875BCD3032D
+:10FD30008584EB4BA6C74ED2832AFB2E83CFA19797
+:10FD4000BCF96523F7DD985976F0C057908F1E14E3
+:10FD500071DFFBAD7CE6A7F707599C127D6E8E0321
+:10FD6000BD4053D47F039239C5E69FF2D565EB853C
+:10FD70006B4106E55A8FF275289106F1BEBFEE5928
+:10FD8000B199F6EF811CF4B1F5FA411FF34F760BF0
+:10FD90004306F2CFA8EB4F01E5422028A6BE4CFF58
+:10FDA000EC3E97E165CB0C11CF675D07F37506F864
+:10FDB000615EC375686F2BE547C4571CF7935BC73B
+:10FDC000A858BF6F063BCF3590DE897EAC8DA90F5A
+:10FDD0000F2EC6F5163BA7BEA7FFDE1EB807D65BE3
+:10FDE00065CC70D9E0CDAF1AC5EFE057AD7BDA0531
+:10FDF000A627AC94E90B2BEF7CCF0D7E179B9F477A
+:10FE0000D634D487917D7F3D08B1629D5A09C6AB37
+:10FE10002EE4FA79E49EEA949FF9F9D2ECFB03967A
+:10FE20009FCD75A89BDD6793F92EC2423FC8878698
+:10FE3000EC7B6C2CFF5B971C8F029EBA66A0C422E1
+:10FE40007EF0E3F8C07F41F240C4C9550B66ACB305
+:10FE50008DBF93FB9BE40605E9DA5793EDBF5BEB9F
+:10FE600067F78C7D9BC3EB2251BC9F5219647C4485
+:10FE7000E1C6F5AB5247500F5278D1FF492E169C80
+:10FE8000E7496FF483FC4CAF3761DE59F05AF43A1E
+:10FE9000DFCFF68BFAE4E19086FA2F1675B1798BF5
+:10FEA000FEA84D7583682C75C98C7FF2B7BA09C05E
+:10FEB00021D6B3EF468DE7FE8BD757B073DB5BF8E7
+:10FEC000AD39DED0E52AE8876E79B819FCE7961CD3
+:10FED00072CA1FC013B4DB9972A17EEA24B124FA5E
+:10FEE00009682B20CF06A4E85740CEB4D469113B53
+:10FEF000FE16E531BCB400FE7C8CCFEDF7ED7E97AD
+:10FF0000FB755AB89C9039DE7066D9EFA5AA66F7E2
+:10FF100046485BD97A5885FB46C50C3E6DF4BF1B3D
+:10FF2000E9DF949BFEDE3C86C74707CBF1DEEED1CE
+:10FF3000EC55CB2E75DA9557FB74845793A81D5951
+:10FF40009BB1332DFDD82DA4FE781ECCABFB149DA8
+:10FF5000C5E9C6426087B926FB302EE70169C05B60
+:10FF60008BC6ADC9EE654A733E2146F43BB4BEDC98
+:10FF7000E3C2BCBC43386CE71F1BBF3BC77B39F8EF
+:10FF80005F9CFC648DF7F23C26A7B41365C418632C
+:10FF90005B1F348EF80B04B0AF5E9F43103EED4400
+:10FFA00005D6CBE1BF29037BD1E9B7216408E5CCB5
+:10FFB000FF96BFA6ABB848003CFC2FF86B8EF94FFC
+:10FFC000E1AF210E3F8CD37FE3F4C38CE6CFB1FCCD
+:10FFD0002FF0B3FB719CFE982208C09C04FE9C7617
+:10FFE0000FDC877D8CFB010F6C7A639E19CEC49168
+:10FFF000C86909E1936E6074B2E69125572D399B6B
+:020000022000DC
+:1000000043AE4ECA3B855C9DC4E7EFDE757CDE04E3
+:1000100089047AF581077FA142FCE9442E1F47F449
+:100020002EE85B9B7EF583BE9D767A7D9B6C2438A3
+:100030003F0AF9380A86595A38C4EE332B2032A6C3
+:10004000498934413F054DD9783AEB09A71DB28E55
+:10005000F9CF55237809F04B938871FA671FCCAE1E
+:10006000D754F66CF0524A97C279622DDB0FE0EF5D
+:10007000F9C8D8CB805E8D12BE77CEB1ECF732F6E0
+:1000800031AFAF31B8CE3F719A7A41E6CF77C27FB8
+:1000900081EACE0D7FC818FBF56006FE2F87B2EB14
+:1000A000352F7A76EC15B9E00F93A2E6BA0CFC175F
+:1000B00055B94F0D97CEE0FF5AFD69EA55E486FF2A
+:1000C000D2A651E0AF2217C279962B9A4FD32EA712
+:1000D000EB375A4F5DEF9B6DCE7E4CB63E098A1EC4
+:1000E000E067779A7DB7442632A6EE617E1F9E2692
+:1000F000A35CB3FA91C3D9741A9D7FCCE0823A5CB9
+:10010000B7639CB1930F2EAE91914FDC6345F6DD42
+:100110009B11FEE1740B32FC9F962F38FF38F9607B
+:1001200034FE71C2EFE48B0CFF98632F0F66E0770B
+:10013000F201B5EB907FE4704564A3FD3D8B7F82B7
+:100140008CEF4ECB179C7F9C7C90837F901F9CF004
+:100150003BF9E3FF1B5F6832CA153761FC20EBFFF8
+:1001600053BE48072FB5F18593BED139F390FE27D2
+:10017000F305A707E78BD3D29BF38593BE9F972FF9
+:100180004EA6B7C5178CEE16FC4EFAC6D67D5B633D
+:10019000F7E98CF0C3E7A3AF4EE9EBFBFCF39DD886
+:1001A000E12D3F99CEA7A72FBBEF4CB3E8AB33FAB5
+:1001B0006A1AD3177284A5DD167D8DCF47DF6E9541
+:1001C000CA7FF4B732FC38E974D9259D4847CD4140
+:1001D000DF6E1FC72BA7EFE9E8D6CDE97B3AF9DC44
+:1001E0006DD1D701BF936E23F561AD16CCF88B9D11
+:1001F000748BAD933D76FA7687E34D9F876EDD9FD6
+:10020000733E12239BAEA3D1AFD51D4F631CDB38C9
+:10021000F6DD1F775813ECF7F08E0F30FBA2086C59
+:100220002FDA6E6B5EEEF3A67A80C5592CB4EA0520
+:10023000B2E398ACB492D7EBE7F55E81742C9C677F
+:1002400088B6827DF3C83EBD7881EFE4F1DCBACE9A
+:10025000FA8E972E2CB0C587CE0EB075CEAB098D19
+:1002600018B6EF25267B6BE6831FA73039A70BD284
+:100270006B7BC7102307BE0A4E4C42BB3CD35F8A40
+:10028000F955E669B8FF5D70623296BF9A50B17D4C
+:10029000E81FD6CD27B79F374AFBC5A7693FCCD605
+:1002A00005F407E77CACF82757E0C9B7603DD919DA
+:1002B0005674F06358E78B9CF8A4F2869DFF0936CC
+:1002C0001A43367A7F9DE34586733DF07D883D2E47
+:1002D000663F3BEAB58B565C7A2C64C7EB359C4E87
+:1002E0006A4AE27E9758C87E0E21C9DB6F17220743
+:1002F00063C0E713D87DA9DDE766EF0BB40698DF8E
+:10030000AD2330E25F44BF83EC7BEE20F83F652BEA
+:100310004E2C2865C589B58B7CFEAC61F67A7725B5
+:10032000B9473C0BE305314EB38BAE43F0FCA7A0BD
+:100330005AEB2D3CDF6BF93FBBF7517B16FC9D7EE2
+:100340003105FB7CE325B2DF0DE71442EC9CC2884B
+:100350001F6C219B9F5DB710B39CB6DF05A747C1FB
+:100360008FB188EDDB767DCAE0E85AA2A770FFC99D
+:1003700030F46051E6DC1CBC577816C31FD0EBAEDE
+:100380009052037E6A6BFC567FCE73541047436CC9
+:10039000F16EA3E18190087E7F49F6291AF8734E29
+:1003A00087B7D6009B4FD70474C4F7D45D0ABB3718
+:1003B0007CBC82F7B958742CDF2061DCDC5F8937A4
+:1003C00002E36C2F88BB2114BB9D2EB396DBFCB2DD
+:1003D0001D09BDC11E9FDB314A9CD596422627EEE2
+:1003E0002F60F7F1ED155637DBCFD5E515303E38E8
+:1003F000C1F98AD44555163FDAF15BB80FBB4B13F0
+:1004000075C05B4FEA5AFCBEC3AE90A8093AA40B74
+:10041000D4EB701D206AB007BA2BB41EEB9BB43E20
+:100420008C67BFD682E7B33B7AC5E91007450974EC
+:10043000714D51665DBCAB516474AE22A94A3AAEAF
+:100440005B1A6B4BE0BB9293B5C2396C332C2E62B6
+:100450001CF95642B6D3F2FD9B15BC6726A9F9F0EC
+:100460007E03DFD641037C25BB04E2A9C0752FB310
+:10047000C7E6BB7C98DF5D2F61FCD5BEFECB5F90ED
+:10048000693BB71822DE4B10E0DFED3B14607E5372
+:1004900009BE4F47E9B5AB5FBA10DEAB3AA302F92C
+:1004A000674FBF82F7DDEDEAEF2A417F7D43F6FD1E
+:1004B00035FBE6CC2C817D205F5DF6F35D57464B26
+:1004C000F0BB8C27DD8341396B66E6DCEC81DB1504
+:1004D00001DE77DE5FAEF5D460DC36E9F5E1BDB56F
+:1004E0007FA0F314F685F7888688DF43FA133B571D
+:1004F0007DCF2D5D59DFBFD9176474EC4D904A88CC
+:10050000BFAC2A13A3201FACEF0EFBF8F7CE2D7A59
+:100510003BD3F20D8DA7BCB75C5227659DD3B4F8D1
+:10052000CD171914E11EA8498F6A357914FE49BD0B
+:10053000FA134314CEDD534B6BC07564F1DF73B710
+:100540005F7ED572FA7CCD5E463FEF2137DE439069
+:10055000C7E32377EFBB92C0BD29796DC14AB84785
+:10056000D1AB1755C2FD8972248DEB715F9B520987
+:10057000F777CD7FA8FA94DF3FDA98D02AE1FECA58
+:10058000AD091553EBBCC9971EBA18BFF7F9DFCFF9
+:1005900030E3C300800000001F8B08000000000053
+:1005A000000BED7D0B7854D5B9E8DA7BF6BC929957
+:1005B00030934C92C98BCC8404120D38098122628D
+:1005C000DD2401C2C376025183220EEF008104B400
+:1005D0008A2D1E06089040D480E1795027C458B473
+:1005E000DA137A142962CF0868D16B7B22B6542DB6
+:1005F00072025A0BA8185BABF49C56EFFFFF6BED31
+:10060000CC9E4922787BEEF7DDEF7E277C7C3BEBAE
+:10061000BDD6BFFEF7FAD7CAD75FC3CF4D8CD91D61
+:100620001263C98C7D2DD2CAAA785FC3C8483AD953
+:1006300029FB4336063F2177A53D92FF0AB61BC52D
+:10064000D866895577DA22F9B1E5AC444D9BE06272
+:10065000AC7DBBC9B11992E32B4BD297943076AEE7
+:10066000D9E4307B18EB7870E843B3201D7CD3C00D
+:10067000F2A0BC63FBE8F48585917EDAB1FFC2BECF
+:10068000FD178A79EF4F0BEE917CD030F8D1E4372B
+:10069000DC90B606F7304CB3F7791AAAB1B158FE20
+:1006A00087C92ACC73BF117E4F67ACC0F12F9383EB
+:1006B0009876066F971D8C3D64FD5DD3F1EB219D0F
+:1006C000177C5782F40B492C5C3E06D25E5EFFF12C
+:1006D000475C8D4198C7FEE13CFDC42317A87DBB54
+:1006E000588FABCDC418ACA7BDAD219141BDD6CAC2
+:1006F000DCC11EF89E2B0AB919F467DEBAFE842508
+:100700000DEA49BC3D630B2B542C17E9918E05155E
+:10071000D8DFF8CADC9DB3005E5BBB8C3E84CF396A
+:10072000A3A309D3ED009FB550B53DCB9FEEEF07D6
+:100730001ECD6BDC79CDB0B606FCE645F2ED3E771A
+:10074000DE33F98C7EBE86FF464774BA5DF2A7237E
+:10075000BCD6C3F80ACCAFC3E827F8DDDD72234F5F
+:10076000DBFDE9088F792DA3783A59CC3F38BC02DC
+:10077000E1D991C6D3531D0515089FD879B41B7DC7
+:10078000E9BEC2AB9887A8F77FBA8E81E070B5E367
+:10079000FF7FDCFE769FEDCAED5F17F43A603FDE27
+:1007A000ABEBE71FC5C7FF69FF7FB7FD7A470EEDCB
+:1007B000F395F181117F8D935900F9FBF6AA52EB65
+:1007C0001C1D9FFFB14BE6FD603DE4F34C95FCC062
+:1007D0001BCF354DB206005FB7B2AAD7CD4318CBB9
+:1007E0006FCB4D0840BBFCCAE97179C0271B5CC8C0
+:1007F0006DE1FBB7F59629986E951DEB3C50DF0136
+:10080000E5C0E75A208D2CB1C5556AC5FAC166D935
+:10081000877261834BB6CED38D0FF52A502EB5A8C3
+:10082000D3A3E44587901720C9C266E86F536ECE04
+:10083000BECDDE48F96A17C7F3D6C619EFE643798D
+:1008400043B34C6B3EBE7DE2899B60BC0E87EC31AE
+:1008500043FDE38EE2CD63707E6E9999A17CA8631F
+:10086000FA9402483B2B649F077B679ECA02A877D5
+:10087000AD3970E226E847C9903D41483BCBEB6576
+:1008800006E941AD8C25A1EC684E642C8531878545
+:10089000C37623F3975A715D6398AF03D22FFB6140
+:1008A0007CE4F73E16C271E1C75E341ADAE26F30BB
+:1008B000D0C47FC9B4E6427947399F87727AF2057E
+:1008C0003682B1729797D691D43D671AA6B7B616FD
+:1008D000BF9E0FFDDA6E917DD82E719A72AEDB123B
+:1008E000D9CF8471D169A6F82B71DCCDB72828C384
+:1008F000998D41B9B6FF5E5C9FAEBE0E7EC97E4B40
+:100900005EAEAE9FF87C4754FA274AFD7F3C80FBE1
+:10091000D865F005711F3B155A5FBB838524E8E756
+:10092000DC2BEC09761DC8DB66BEEE4DAA2534CC67
+:100930002BE420C265AB12823D641DAFB0C3586F7B
+:10094000EB2BCC270D228053B963636208E77BE071
+:1009500059134BC4FA765B280FD21FADF18D6B4053
+:100960004469D949F05E62E1F033C82D3E0678D87B
+:10097000C4D41C6660ECC44F97B48C877157FECA10
+:10098000E043785EFCE9143793116F6FBB1DE7738A
+:100990007E9F9D19681F1C33E743DA91E8F6A1DEBC
+:1009A000D2807AC3585A669041DF4BA12F2EC75987
+:1009B000D0027878CEEA998D72F325D7ED532CA02A
+:1009C000473C1BC7CB9F6B9DBD39380EF486B61BC9
+:1009D000F3510F58BF6D7C93B508F40FB3E82FA8FF
+:1009E0006C1E0FF87A4096B4FE55067A4727EA1334
+:1009F000949EF67A39ACDD216BF5276C46B95B73B2
+:100A0000CC24C64F8F1B0FE5074A1D23DDD06FAAEC
+:100A1000CB35C59285FD69F30B594AB17F136F9FA2
+:100A2000E00A55E07C8A86749EF921ACCF7C9FC990
+:100A3000B78F89F1713FEE35EDDB27F5D52F2E27E6
+:100A4000C9C40F3A4B5805D217CCAF3AA4A33B7F89
+:100A50009281CA67896F67E846D903F31CA23015F3
+:100A6000F907C02C691AD2D783FBC66ED6F1A96AE2
+:100A7000671CD5AF31B37AAC77A85BDE42F8D2EA17
+:100A800070E23EC8ADFE756721FF726222D5CB0BC6
+:100A90004F4F9750EFDAFF567121D40B3E6723BDBD
+:100AA000F1E2FE197B0C38FF463333C0FCCFD96D21
+:100AB000D54F42BD0DA16BCB118FB4F1AC627E9BC3
+:100AC0009A8B3B57C17C2EDA6C0EC98378EBAB4610
+:100AD000FCFA89CDE4084AB4FF69C8CF72E510E991
+:100AE0003FF76C7DAEB12113D2028EEF271D6E440D
+:100AF0007DADC9EF8B9310DF336586ED36B9A65B0C
+:100B00008098D8A3E357D277932B27C306E54DAA45
+:100B1000C9C3A0BC653CD797DB1475BA17F2DB5A82
+:100B20005C52D013995FBC80733BEAB0B83E172388
+:100B30007A78DA097801F37B3A99B5AF07B8981D4E
+:100B4000AC18D765CCAC57D57EF4EF74D10F031D2C
+:100B5000D8369A4882E821A5FCD48F905F9C3775DF
+:100B6000CD5C84F072C6F9F6417E87B52B4D82FECE
+:100B70005312E3645C472AAE0640D520B3A938EE91
+:100B8000864CE6588BF98DE6A001DAA7349ACFE2BD
+:100B90007703D231EEEB7C16C2F5A536CB67CD09D3
+:100BA00050DEFDD91A1CC7DD2A874D587F968979FA
+:100BB00074F2C57DFAC2DF59024E0FF2757C26250C
+:100BC000C1BFDD097CCD9CE99002369EEF86F9C756
+:100BD000B1DE1F3783B44924E29AE5A019FA7F7683
+:100BE0002DE70F9BD6B210E2EFB9E7D933081F9378
+:100BF000A5B9CB9040ED2DAB8A75705D0D7085F178
+:100C00004C8D9B56E03A4CF9BA79C0FFD349290480
+:100C1000BF4CD62D21FF7854D839C43AA1281B7176
+:100C20002407E1184EB801E1F8805C8C7024DB03E6
+:100C3000E6872C0BCBB5FD38E8E47227B61F8FE8AA
+:100C4000474B3F2EDA1D389E3815F1FBF1606231BB
+:100C5000B21AD8871A2ED778FFC9D80E51D911A742
+:100C60001620FF4FE2F6D081B8FA1A7F3FF8B02382
+:100C7000898FBFE135D85880CB81759EBBE720BCFA
+:100C80004A6586F4FFB2CAF7F15C39C821849FCA6D
+:100C9000E1D9D2CA4228D746FE4A6992613E99E319
+:100CA000E544CE1F0186305F3BFE024D5B7C7E46F5
+:100CB000FAA18BA9D611480FFE6A9C07531C52E576
+:100CC00070A27F26C3BCE3457D7B797005E2478B2C
+:100CD000C56175A0BE90E99B928BE335498E7D047A
+:100CE0000CBF5C698FC0C526E012DF0AED603F6D66
+:100CF0008D128D83FD2272276039EC53BCEBE07DB1
+:100D00001296ABFC3BA82A1AEFEC63A2F779AB80F2
+:100D1000C7DAC438C28B96655C0E13BFC47D5DC252
+:100D2000F129DE17DD4F86C22A4CC5086F47DA7CF1
+:100D300084E36633C3FDCF0E46F79FDE985A8AF8E8
+:100D400097C974EDA1FFBF399DB41FE927F64E97EF
+:100D5000611D1D354C3600D264B0A05A53CCF70744
+:100D6000F58D4D2932F59BE14A2C453A02B854786D
+:100D7000213F3DD553ACE7A346979F1517623D47EA
+:100D8000E950A8F79344BE7FB04784E719277AEE6D
+:100D90004678A7D746AF83E9E9CF70E5B4D1921082
+:100DA0008C877E8C31747B31D1CBF98DC00B146F65
+:100DB000C86F403230E4A317137CAFA3BE15BC57F5
+:100DC000F175403EEA66993047E333723015FA33E5
+:100DD0003FC3E9D8D8A904872590B8574D589EF944
+:100DE00095593FDFFDCF8F4B47B9D26EE474641045
+:100DF000FAA9068703892682EB8144C1FFD821A284
+:100E0000977BC55C4B5FC82C437EDC91C5C8BE3E5A
+:100E10002FFBF7C4E3BCDE35A3EE08FD17AEC772A7
+:100E2000A70A7A870EBE9B947A8BB390961492DDB4
+:100E3000DFFEBB01F51ED8DF76A1D768F91DE1758D
+:100E4000CBE7305C4F70B403D6E10CCB9A5E8114D3
+:100E5000A9D70B821690DB0586E0BD8B411EBDB97C
+:100E60006DF9648715E53E137AC1BCC92AC8A7A2EB
+:100E7000F592687F4713A6237A00909D25A207303C
+:100E8000563FB906EB676AED674E5601E89D162D91
+:100E90003DF435F44F34183B47A3DEA23A438DA806
+:100EA000D76CB0FAAB91C77D96F4F964F467687AB1
+:100EB000CEF9472E3705A1AFE186AE6B2C507F47A8
+:100EC000CB754DE559489FBE38BFFDCAF069577CC8
+:100ED00071B8FE76B1FE0989C326AFCDBDF27EDFC3
+:100EE00081FB0DFB9C95C8F9DF7003D72362F9DF06
+:100EF0000AADBCDD548F7A4BE9301BA7F7076F7D35
+:100F000002E9BDF405DBEE78E47FEFCC3462BA2E63
+:100F10005111F8E3790CF3DBDF31939E8CF638CD79
+:100F2000F3F9590CFD3CC690490DF583178B120B54
+:100F3000080FFBAC33CF4674B9FF795B88C138CF5B
+:100F4000AE037EDD8F3F279828F8F51A803D119378
+:100F50004F4638E626FB55648643DC81207E4D6093
+:100F600087A9FDD87FCAE50CA62645D26D0E95E669
+:100F7000AB5C1E4CF9FF64F0AF4B84FEDFCFDDB7F6
+:100F8000780BB4DB23E4CBC4416A03E6AF97D58783
+:100F90002BBC7DE7A57D1BD678C6A14EDC9B36F623
+:100FA000EF077C7C1087FB3F6017A824AFED71C46E
+:100FB000C706B40BB6B97AED02E27B1BE4509EF78C
+:100FC0001BEC8221451E941756438B05BFB9B2EF27
+:100FD000E1F15EB40F0E5F7C1AED83A7E2C93E68B3
+:100FE00090823F5D85F68891DB033549169A3FFC78
+:100FF00078513E0D6C17EC6CAC28BCB25D104B2FD9
+:10100000C52A237C5214568EFCAF0CF938C0CF7819
+:101010009CEB558A07F86402E79BF8B5B87C244F2F
+:1010200035BEA28414AA67380D7A1A7E9B3792FEC9
+:10103000A338FC0CF5A915A6C031DC5F608B0AC291
+:10104000C3CAD7C20C3695050A07E617DDDB3C9309
+:101050001B61BE86E37167A9DF301FDF707AD3673B
+:10106000A83FB1E7A2FB8371FE1DC7B11CF287E365
+:1010700075FD6BFCE9E0B6C19371FD9D213BF5FF69
+:10108000D6B6CCD782B9DFD07FB84FFFBFEFAF7FE6
+:101090008D1FFE725B5613D939D0D20C30ACD9C932
+:1010A000EDA937B7654E5EAB7CC3386FF419E77CAA
+:1010B000BFEB107CF35FB7799B70DECFAEADAFEEC8
+:1010C0008F8E1312B99F2456FE1951FE1573B997CE
+:1010D000AADB4F33CABF1103CBBF54C407E8AF2606
+:1010E0009EF3B9233D72FCBB642FA53811F53A1568
+:1010F0003FD9B18ECC14692DD26F121FDF11BA9374
+:10110000A13F5A76793676A35DD25499CEF47E7695
+:10111000B49F906EC07ECA23FBE934B7AF9EAF6523
+:10112000799E881D7571FFDD16C4A38093CBD9D439
+:101130004407E1A7F558718071570AC14F93FF43E7
+:1011400007051C49C928EFB97C37673229407A2C3A
+:10115000B7AFFE513BE70127E72F1D56DF944968E3
+:10116000BF94CA0EA44FCD4E01BBC08A7AE5A6ED4E
+:1011700032D9B9BDF689B05F347BA841E67C646B97
+:10118000ABBC0FE1760EE66505FEB2B5B9F82DB43D
+:101190005B37D42BE457E963C7B8C0BE81FE5A1A47
+:1011A0000D53C98F037612DA41EEF9D1F592070596
+:1011B0008A100EB67299F4D68EFC7D641FC6DA1DB5
+:1011C00057D25763F5D0587D33735574F9B7D7F7B5
+:1011D000B8BE76B57A1FFEF4A7EF91FE497CC4DC59
+:1011E000847A04D96790BE9468263D4109737C5087
+:1011F000900EF18BF48774006C14E501D05D7512CC
+:10120000F2A95A4941FD4DA347748FA01C8CF53FAC
+:1012100068DF694E93D003A2F96AFB83430723DE9C
+:101220009D337A66A39DF233E1177D4E7C0BC47922
+:1012300092567E50F84F0F0D507E58941F11DFD8F4
+:10124000F25F8876E101DA1F15ED8E0FD0FE55D1E1
+:10125000EEC400E5AF8BF23706E8FFD7A25DD700FA
+:10126000ED4F8A76BF19A0FD29D1EEED3EE55CCEAB
+:10127000BF2BCA4FC7F47F46D4EF16F9850E0FF780
+:10128000670C704EA6D9AB9887F621A95C4322FB68
+:10129000F96F4E59F89781464747EC408D6F384BB0
+:1012A0005808FD129A7DA9D981EF39F9B8B672B004
+:1012B0004729B393F0A6FD0AF05993C4F9EBFEE178
+:1012C000DC8F8C78B3408767EB938CBCBC88C321E0
+:1012D000B2AEA1B2B62E19F2B7087BBB50F8C7F771
+:1012E0003B23FDCDD3F55727FC51ED57C0ABA5628D
+:1012F0005EED57D8FF1F613D5D7F03E1615D4CBD31
+:1013000081F0617DCCB803D1C5A2987A3F15F53A3A
+:10131000C5F72E2187AE840FB178D52EF4AB829617
+:10132000579AF07CB1FD0AF4719F5817FEE8FD064C
+:10133000B66699F02099F544E14702EB223F8A8690
+:101340001FC6CB5EA68EC434974FCE240FCDDBA82C
+:10135000F819EAFDC6CBB9549EB71F4C7A904B1BC7
+:101360009E87D9C337AFD52105A07ECBF3C02021FE
+:10137000ED740D35A1BC9AABDEABA2BCAC3DDEA5D5
+:101380007A1322FBAE0ABCBE921FB6F689776F971E
+:1013900074ED260979D7ABEF3D746B941D12CB0F1A
+:1013A000EF48B4D038FF15A7DE827A4CCD20EECFBF
+:1013B0006365CC81FA34E85F12EA0F1DC98CFCA08A
+:1013C000B20BF407289F9B696293D0FF9AC4E11483
+:1013D0006665B622D4339AB93F4AD31F0A0C8E3FB2
+:1013E000A3DF9525593C28BF51DF42BF087C8F9B66
+:1013F000E15BECE4FBF12DF42DD599DC57DF524590
+:101400003FFF8D7A70AEEBAAF4E0FEFDE7DF420FFE
+:10141000F6B9FAD5839DD7325893BA357EB327AD46
+:101420006FFF9A5E3CDAF5E889E037E9AB7DF5E2DB
+:10143000EFBAFA81DFB73D1F682F117657BE85ECF2
+:10144000AE2485B9938AB1C3693E3C6FFB9B83F39D
+:10145000AD2B9D335DE95CE94AE749B7B9ECAE0FC6
+:1014600071213EE6433D64E2BF146EAB00FC5CF9C3
+:10147000A681FC37AB5AEE35E3DA63F15EB10C19A5
+:10148000D700BCA0750DF46F8CD8A79BD738280D5A
+:101490007ACA64C4F3B887129D6837FE9B38CF7C44
+:1014A000B9999FA39DAB9279FCC589ED15782EF96A
+:1014B000B9CACF2DB757AD9B8E70696D34F0738666
+:1014C000C6F58D63209D3F4176183C7AFBD89DA7D9
+:1014D000B78F87B90248D9D06F29E97D0D7F2BB32B
+:1014E000A0DCDBE4981E877AB9769ED9D1CACF39C1
+:1014F000B75641BEEDCAE79CB1EBEE7688F303C662
+:10150000CF69AE3D36B312E36FE6362716593DB4C8
+:101510006EF2C79A05FF515619F23E007E968C7AFC
+:1015200031E0D35C87CAF05C435965E2F94CB73FC0
+:10153000B05FF14ECE0FA18BA094487C322F57DBC9
+:101540005FC3C0F4A9D1A346A71A5DEAE87107D129
+:10155000E3AC687D4FC35FEDBCABC4F56805FA85AD
+:101560009E95B81DB9C7F5CF8D88AF460FA37134CE
+:10157000FDD088E38DD0E999A7CD443F465790FA36
+:10158000D38DDB41E39E60FDEA99DAB9DB16D75EC5
+:101590008A6FD9AE04A7D3794848616827BCEC9A12
+:1015A0005E81E7382D025F5A4E18C98EF81CE80696
+:1015B000FD3B786E1EE8679F34FCB00B79188B27D3
+:1015C00073857CE940F90276C8DC4667B47C69BD66
+:1015D00095A17C31A27C29EC2B5F4638391E8C709A
+:1015E00072FB4C9323F198C6F52ABE7C5CDF7E63C8
+:1015F00090E24B8EB6DDEB26BBF0E7816C473FF304
+:10160000EDC5BB411E215F8356F4670103B2CA6377
+:10161000085E3609E057DB0BBF15E477FD81C09DFE
+:101620005A3CA786F12718B8FF2BEE0989CE1996E8
+:101630000615DAB7DAE0BA15E807077E44F2CFFB01
+:101640008491E1B93D94D33E6AED97769A5958C793
+:101650001F963F07699D7DE365CDC417170398C2A8
+:101660003ABEE3C573F3042C8FCE67865983100FFF
+:10167000AC08F4B4BEEB5D75BAED86E3BAFE2F6834
+:10168000FCE83BEC3B642F89F603C1EBCB35A11B97
+:101690008EC33E974AEAA7C897191EE65FCFD84384
+:1016A000D730B24F63EBA31B09E13B6F55197B1F8A
+:1016B000E8EFA0C9315E41BBFC3189FC06EBE2BF1B
+:1016C0003B51413FD479181AD2F3EE5F3A12E974D4
+:1016D00079574B5902CAE166A908DD5DDB8FD61741
+:1016E0003920DD73A7ED46D423984DF5E03920FA73
+:1016F0009A51DFFAD8C8CB8377DA8A506ECFA952D5
+:10170000DF41FC4835AC286A41FBFC6FB03AA8BF0A
+:1017100040ECE60BAD95260FE0CB2225FCB204F39E
+:101720009E33CB3306E139A7D3AAE237D5C4142BB5
+:10173000C8873916A6C4C137358E5928AD300BA6D7
+:1017400047AF637721BF4B18E337CD81FEE71CF924
+:10175000F15FB8B21E227C9C73E4B5BFA21DBE40EF
+:10176000F59B50AFB876BF899FED08B80FEF8C4E50
+:101770005F77283A5D148E4E8F3C119D7E10610F6D
+:10178000FF5FFCFBDDFFF100C0B3E75706D2B79661
+:10179000023BFA2EF0B183D7802D80EB5642837145
+:1017A0007C3063591CC0E7E2D3768A1FB9B4C637D0
+:1017B000AE1C007BF4BC4CBE9BA54FDBDBD04F7C4A
+:1017C000F0ABF71FC2F3BF9E67E3E91CB56CE933CA
+:1017D0003FBD1FD21F3D15EFA4F882DD2F3C86F8D8
+:1017E0007CF1D9610C59D647C2CFFAF2BB873FDCF6
+:1017F00003F94B7E1A5F84F53E7AF685A10897259A
+:101800003F796930C6D95C7CFA27A329FDF45323BC
+:10181000F07BF1A91F0FC5FC8F849F22F8B4B90D8E
+:10182000F76DE933D6B34900B70F3FB1D9F4E7DC20
+:10183000DAF76AFB5D8AFD22FE60BF4877CF6CEA6B
+:101840004A427ADB6F0F26E9F8CA92FD5B3ED3A7C6
+:1018500063BF4BF6F3F90C5CCEFB5D02901E037088
+:10186000FFD0C8E5D8D2FDE6A8FD1AB62B7AFF0A4C
+:1018700042D1E9BA4BD5539C304EFEA559539CD06A
+:10188000DF2521EF62C70B24733BACEE5074FF875A
+:1018900095FEEB2F4CE672311F4F98757C22DDDCF4
+:1018A000FFB942ADA8FFF4D3BDF50DDC8F0264068D
+:1018B0007AD952416F2FF6C625B17B3280AE968A17
+:1018C000735F2D7F29D3AD8FFC2ABE41E85F7689F7
+:1018D000FEBF3402FDE07EAD098CFC00F8C9876BC9
+:1018E000EA0BCA75FAC5A2BD7336A6C1FED51EC8DD
+:1018F0002BC2E1B5FC6B3A8D24776B9F3A9680F250
+:10190000E2E2FE633B16203E761A59BC87F2533062
+:10191000FFE3CE5712EE80FC45BBBC457A3D66D155
+:10192000AE1F1494EBF8DFB7A54B8D8FD43A381C5B
+:101930005E18D3353103F077E92EC987D59676DE68
+:1019400032E366C4BBBD061FFA19472BCC6F28C60D
+:10195000753CFF6A3AE4D7BD346A34AE07BAA8C210
+:10196000FCCDB27FEA70E45B8F19297E0AF24FC882
+:10197000804747F3B799CEC13A4262BF37DF6AABBF
+:1019800041BD09FA3B2E43BB84272455A4DFC6FA88
+:10199000E74B3B13D0EEBB60B435E239C2057BFDAB
+:1019A0005B388FE0B3BC5F16E6F35E2CCE0B6A8E1D
+:1019B00018498F38F8D59F6F1D8BF4DE66F022FF33
+:1019C00058B42B1AAF1C6A8B09E5410DF4ED8671F2
+:1019D0002FB6D9A9FF8BC9A1C128570F7ED57E0686
+:1019E000E9ACE729B3AC8FB3A9D9FFCBBF225F5DC8
+:1019F0001C8AEE2F162F5E11EB839F7C3D7EF5C572
+:101A00001FA628A323E5B5AB404EE8CE836A3F6806
+:101A100031A11EBA789AE91BC7FBF3E917867A64ED
+:101A2000C2D320DA79C10306F2D37EF48989F8FEA5
+:101A3000D26B58B907D6B9DC3D725C39F4BF743A41
+:101A4000ABC034FC481618FF22FE3684A7E9FC051B
+:101A5000F19EFCC4E1876E003CF8E86706B619E623
+:101A6000978EE776009FC32C9C20237FEB34C838E9
+:101A7000CEC5F3A000025C3E76841312914ECE6F69
+:101A8000263FE1DACE6309DD98EE4CA2F3F581F84A
+:101A9000CDE167ADB20CF0FFF8FC93F1AC1FFA5D3D
+:101AA000729E9FABC7F21F4D0E9FC55F415E7F9C2C
+:101AB000ACFE3119E18E4605E809A949F545F5FD69
+:101AC000F4A7B59B23F176A9869554EF9354FF674D
+:101AD000D8DE5E12F4A2FC4E0C587C683FBC6FF05E
+:101AE000DDEB1882723660223F444332F5BF88C175
+:101AF000FE40FE3C858515C0D779289F47509AF84F
+:101B0000FFBCFD52088F52ECCDE6A8F3BF85AD9027
+:101B1000D6AF63AFAE1CF8CD6294DF09740E1646E3
+:101B20007FEE9227A2EB2F05F31DC7AD7DE66BB3C9
+:101B3000BE5FD03CB5384F13EA8D7F1170F9245544
+:101B40008D4B81FCBB25FF77B1DD02F3016AEF12FB
+:101B5000F1133D07A4D03E9427426FA8BBFFFE823D
+:101B6000F9A0AF7CBAEA4705F393847F06E97F9733
+:101B70004476E6D27216CE82F9DD2EF49FA547A4F4
+:101B8000F070482F8075A31E31F61929680739B700
+:101B9000C0C282098867BFE1FB512BD683F50615C9
+:101BA00023FC8204CFC5AC8BE633B686FB55C61E3C
+:101BB00092284E29164E357B63E0A6874B0EC22332
+:101BC0001ACECB9F03F844E10B870FE83DCC0AFB0C
+:101BD000B55DF0F5336047E8F54A8651FC506FFB80
+:101BE0005A89CAB7DF62626E98D78E990BDB31AE25
+:101BF000E661F47388B8428C03DCACC5FD01C158C2
+:101C000060BCB8912C72DE3886F42A4A8FDB91359D
+:101C1000755726F4630CA4A19F6A4725E8B95C9F19
+:101C2000B1A23EB3D51D188FFB34CFE07F150D8CCC
+:101C3000F9B23A58417C5BC5E1B7B3B8BEA0BE1F4C
+:101C400079A8E1F30EA94BA5F3A10724E28FF14790
+:101C50000E843360DECB2A3CE4F74CBEED74FE5CB0
+:101C60001877660AE74F838E7279B55B620D682735
+:101C7000BA011F24D89792E7B6A6A1DEC9E69B8ACF
+:101C8000F19CE9612797073D6FB21BE97C26BEBE38
+:101C90000DE38C52EFCA2FC6F31F58EF5DD3A19FFF
+:101CA000D9291E9A479A8DEFAF7B5DD0BB12F253B4
+:101CB0000126F6441CCFBFE215EC67388F6783FC22
+:101CC00046D43FDD6CAD84F5362673786F9CC3AA8D
+:101CD0007F5648E76BCAA044FE7D1BBE6075361870
+:101CE000E19BAA80FECAF31B709CED097C1DC9B262
+:101CF000E1AE4ADCAF629E4E5C2DA9FB0879B7D2FB
+:101D0000BC52CDAC02D789F9E8878369A907A83C02
+:101D1000C4F1A2ACBE88E63B847FDFE8B6040D8048
+:101D2000C76FB834BD336C23BDF3509A8C72E71E75
+:101D3000212F3F35AAA92391EFBE6964A8FFBB06F6
+:101D4000C7D4CFCD9791AFDE23E4D4E7BEB24148EC
+:101D500054878CEABF3382AB41DAD7CF397E738A9E
+:101D6000F0035FCE60219D5CA8ABFE82F4EFBACB9E
+:101D700083A3F23F5E032B19A6931F35472762BD4D
+:101D800065AC6B23E2DBB24E030BE9E8E39095EB25
+:101D9000FB5FBE6726BABBBB63D83E1E37E64998D9
+:101DA0006E8FD041DD65030B024EDF6090A97E5D32
+:101DB000B589FC4E758D8636A4D3BACB265E9ECDF2
+:101DC000FBABBB9CC48249585FA273C29E2603F939
+:101DD000492F187B36A25E137CC94B70AABB9C426C
+:101DE000F5703CD4A3EA2E4B943E877A1FF4732EF1
+:101DF0002407F3AE43BDF04BB15E8597431784E7EC
+:101E000087B89C9B06720DF9155360DE607F5FF208
+:101E1000BD9F80F03D27F4CD74437702C67FB21793
+:101E2000B9BCFA780D302680D3254F37C92B0D5E0B
+:101E3000971CDD0908A74BD51A5D8615EC678FEF57
+:101E40006505FD3FB5BE9727321DBE44E01ACF821F
+:101E50003AB8A6ACEF0ACBC0235EDB316F4B610111
+:101E60006CE151C10F820BB6A8E3A0DC2047F1075B
+:101E70008C5DD1E28A1145B6CB06717F67E196F29F
+:101E80004C5D5AD4EF6D1F5C34B51CFA2B29E4ED80
+:101E9000DFDA51F3BFD6293A39A0F40CF6DB7569C5
+:101EA0004B4CDA06E9E1BAB423A6DC1553EE8E49B1
+:101EB00067F2FAB307758F32808D766647ED54BCB2
+:101EC0007F343BA3FB0778DFABD95037B53C0DE53A
+:101ED000A96F22EE57DD21C9C1D56E0EBFE53E4682
+:101EE000FA9ECDD76DC2F396F812DFABA857D44255
+:101EF0003D09F023BE30CC907FD5754AE4B7EB6D39
+:101F0000D7C9F5C4DACEB3D46EC0FEF365A2F3CD63
+:101F1000F9E7A8DEB2559F9850AF69AADDE647B948
+:101F2000B3C2C4F91560959A0178B1FC5025F99BAC
+:101F30007E3FFCC86F31DC33FE9ECFD62A50E5BD14
+:101F4000657F1C85ED7E8F5D5F8F7C365480ED67ED
+:101F5000D5CC2DC0FCC4C2AEDFDE0AF5CE18BB1F47
+:101F6000C5389294D4B55315A877C6DE9D8571C93E
+:101F7000EE9D5B783AB9FB5184CB969DCD04A73397
+:101F800059DD5932A4B376BEC2CBF3BA1FC5F48C67
+:101F9000D4A779F9F0EE2C8303DDAA3F21387638F7
+:101FA000385F7B0CEC53E48FBF8F915BF654CED738
+:101FB0004FE6AA96543A97E572E351B0412CC0F728
+:101FC00066EFE97EB603E034FB87F1283158C7C7D6
+:101FD00033A6D0B91E0BFA510F4DE528CCE51BF105
+:101FE0006985F4823494698911B8DA077779701EAB
+:101FF000B172E00FC96A338EAB7D1FF0C017E0DB12
+:102000009CEA117A497D9107FA9D35CBE6437F2EF4
+:1020100053BA47213E3D6CE5EB023AA0FDB2E1BE6A
+:10202000C1BC8688F50C49E5F695256502F57BF778
+:102030007B93765BB85DC6EDEC6546D24B5A2BD5EB
+:1020400034F407B456A6507CF4C1AF0C5CBFE93041
+:10205000D33A6E473E81FEE62246F9AD5B0B286E11
+:1020600056D36B5B1797A5219FB9C1509A8678D834
+:10207000536922FD1FF81AE763CB8C6D94D6F8DA0A
+:1020800032A3E06B20AF088E9DC9FAFB97771899B1
+:102090001FF9D81D6D9C8FF5E64B904FFCA53319A9
+:1020A000F9D5D5E66F2F56D3908F69F34A5DDF4996
+:1020B000F348DDE94D44F893A0443D65EBB07D085D
+:1020C000DFADEEE904FFD6CA27AD730B23F82BE78B
+:1020D000A9D3108EB78B383C0D4FF007FD58F31E77
+:1020E000496D437F4AB3803BE82123503F5BE6D6EE
+:1020F000F69311DD34A7723FE56C73D888F4F03F96
+:10210000FBF20FEFCB9A7F645F96ADFAE355F137A0
+:102110008DEE764861632AEED34B5C5FC47C94FB02
+:10212000135302DB5275FEEED93F5A9646F14062D8
+:102130003EF1F7BD50711B24CFDC7EB1E349687FCF
+:10214000E68756D26B62F5D133EF5A9AD1DF155F2D
+:10215000D8BD0CF7357155BC03F58B33C2BF76463D
+:10216000AC7BF40F97BE41F71D520DB42EC0A334C3
+:10217000E177095A707E95A66FC6A3970C14FF6D80
+:102180008DC5A38E61028F42BB17A28CBDCD46FECA
+:10219000D9D63C99F497D6FBE3C9CE68F576137C83
+:1021A0005BAFF7505C12E8391C8F669AA85F042079
+:1021B000D6FFB43A3D84F007BCE3E3CEB410FE6A28
+:1021C000F18D9FD6E4507CE30D066EC7F4E4C9A1FF
+:1021D000683CEC49A8D4E1CFA7C2BFF529EA39830E
+:1021E00074F98CEB3F20BF490FBBDAFC94F52ADD74
+:1021F0000FD1F050C3BB0FB601DE48A45E0C453AC8
+:10220000F8ADC01F8DDF2E7307DEC4FD8EE8C39CC2
+:10221000AEE63D3C9CDA6DB273FEBCD7CA1A2DC542
+:102220009171F782DD807205ECCB5388B77741C39B
+:102230004390BE2B35F08B6E1C6F9586BF7E13E2EC
+:10224000DB0261D7B2D5D1761BC631F5A60D7DD3A1
+:102250000B55EEFFED6337B3AFCCD1EDB85E125F37
+:10226000D863443CDF696541AB4E6EED42E72EAC6E
+:102270006B17EC3BD2A556EFCF1FC7C978BFE0C4A0
+:102280001B2307E1F9CA9F996F10FA81EAA06FF446
+:102290007FD6C579C80F7583418EE25BCB712989E2
+:1022A00091FD3F77288DF003DBE17CEB72C1E64BBB
+:1022B000447C51E750BBB5768FB62F547FD7308E14
+:1022C0004F1ABE3C2F097CE97992F8E7CF8731C4D9
+:1022D000FB4BC9BCFEA526431BE27D1D4208FB0F3C
+:1022E000FE7D0DFA77CE29A1C52887833571541F4D
+:1022F000FDA87A3B58D3A32FC1EF786FE11C0B2CBC
+:10230000A673E36A5E5FD39B19A2404AE47C68B976
+:10231000CCCF0F757AF450B20B5FB416A31E5D2BB1
+:10232000EEED60EC39F98DB091CE8E41F88C2BA694
+:10233000EF7103ED43F768BFBDAF9DB35C3E3774EB
+:10234000653F766D6FF9AE3FD23D243C47D2EF7FBB
+:102350006D044FA4AF251C5F8737DE081FAA137ECC
+:102360000AD2B371FEE58CEE23DA453ABEA22B8485
+:102370007C29F968F744B25FCE831D8DF50A593187
+:10238000FA3BC71E693B867A68627957166E5F9D75
+:10239000F0D36978A5CDF3FA235B0D681F6874A5A7
+:1023A000A3271A67414D3A9D537423B3BC1E33D7FC
+:1023B000517BB45BF93D1C356D01CC69C7E21CBA99
+:1023C0003712AF70BEBFA065D8BEB5827E91EE3524
+:1023D0007B1734C3D148575BDDA5D3DCD0CF77D38F
+:1023E0004A27E1978CA4EB0786A70617AD1EDABB38
+:1023F000DFE4275BF909D007F0A78AD7F252913EB4
+:10240000564A9E54A48F0F0D01F28B45FC3861FA99
+:10241000D60A3A5F28FC3F0B357FCF2E73549C239E
+:10242000FA51F5E925C20FC4F69B23F18BE8D729B1
+:1024300067613BF4B70CFD47F8ED8C6EB79CF55027
+:10244000BBBA435F47C5E1B256BEBEBBC4FEEFB6E2
+:1024500072BF8F73759B81DB717C7D838A55EF061C
+:10246000E49BAF19C92FF1072C22BEA58E467EFD35
+:10247000496A69A51BEAC5A1FD0BEBFE00E417EE56
+:102480002BE8C9774D477B714DA080E2151475F498
+:10249000F47EF07BF3616B0DE2C3036E39EA1CF945
+:1024A0003B6E23A5C93F84F4DF6426FA1F9D23F405
+:1024B0009A26F33EE433F3CD3CCDB6F0739FE5B7F7
+:1024C000DA02D8DF39E1BF6A72733DB9C9CDE32AB8
+:1024D000B5B4B63EED5C0FFD34FA7B670FF7D6E37B
+:1024E000FE11A604289E6A8731645D40FCD14F7EB0
+:1024F000F23F7DCCF7FFC48979C437FE047C03CF5B
+:1025000085E70BFFE99F9887F8652F7F6C3344C9F7
+:10251000C5F34FA40AB9C9EF1768E77ABDE5E787A5
+:102520006A7C3028933FD2AAC94D15E559F0F9616C
+:1025300024FF99904BE78F6451FD0FF1BC0F407859
+:102540005E09EC5E40FE687E2E705EF31B2CB9388F
+:1025500002F5A1F32C681E8CFCEE8899E4FF874CF1
+:10256000C4CD840CFB38FF0B65CCD0EDDB6171FF73
+:10257000EF3C0B2FA47A9D56F21B68E5E9669ECFCF
+:10258000FE15F275FCEE45A3A87FC02AE9F30F9A69
+:10259000C29C9FFF8CE7FFCE1CF8855B8707B509BF
+:1025A000E1A14EDBD5C00F181DE2C54B7651CEF927
+:1025B000C5F9C6613EF4CFF7CA91DD5C3E5D30F2ED
+:1025C000F6C19F7B097E0F17733C3BDC66685B0797
+:1025D000553FF59B282EFABCF0B768705B77E1C9D0
+:1025E0008C6E5A3FE7FB3B8C1CEEC1368017EA5DD0
+:1025F000267526AD73B33989E40DF267F41B37F203
+:10260000F88D81F84EDDBE79740F7EC0F29ABFCD91
+:10261000A67E62CE012FD5FC6930BF7FE9A6C3A498
+:10262000E50E5116DB5E9347AE9E94FEE44C6FBD03
+:10263000F31B5760BDD871485F1ACDE52BF2B1BAD4
+:1026400098F345A64F1BFAA6FFE676F6C6C1625C74
+:10265000E358A6FD44D7FB0A633292B13CBAFF0FA0
+:102660008CC1043AB7BA20131F5AD63A6736AE3B2C
+:102670003B39604C83FA87B76D1A4D70107831F68C
+:10268000A342AED7B5F0F3880F8CEA6CA46F6779DC
+:10269000D83457274F33D338DF9967E6F61486FFCF
+:1026A000E9F994563EBA349A3F68DF8C34CE27EC71
+:1026B0005D5CAE3136C38CF2FE30FEEAD1D7E37AF0
+:1026C00065669A87FACB3ECFFD3BD9AB43EB31EE43
+:1026D000A1B673CE48045BF6EA30F1950F8C2C8CD2
+:1026E000FAFD07BB053EA33F03FA5D3886F7BBD072
+:1026F00000FA25E2AC389F5C22A0B9D00C7A28F011
+:10270000F117F68F37D8A1DF257B251FC64D8D1514
+:102710007C1EF5976C943BE2FCBA86756DEC86FEE8
+:10272000173633CB188A7308193208CE8CEED5CE03
+:102730003377933F91FD442A42FE00F2AA2101DA49
+:102740002D5143E4778C3D3F64FAF33FDC0F3C9717
+:10275000D29DDF2C6B69A2F32F4D0EA2BC62317AA1
+:102760006B341E05FB95B39A1CD2E42DE8D965693C
+:102770007C9FA2CE6D96B17A7E2E25E45DEFB842A5
+:102780005E7E68E0F279A1792B7DABD3BCB44F4B70
+:10279000583797B7203F91EF5F697FAB059E68FB85
+:1027A0005A0B0CF246E87F26EEB74E0FAA5DCDC25B
+:1027B000CB46F0AF7D04C193EB0116AE07E037EED8
+:1027C0002AF481583D2056EEC7CAFB541397EF1ADE
+:1027D0001EE8FDFAA8DF8C5D1D32E07EBEBA46A57C
+:1027E000F3F95596841118B7F5A5957F83A59CAE8E
+:1027F0008267AC641FDC67F0ED7A13507FE2269E9F
+:10280000CFFE239EF8E8FA262E1FD6AFE5F2778B8F
+:10281000A08F55E2BB57D0C1511C270FEF0F54D0EA
+:1028200078132D450AD2EF64C767831541C73680F8
+:10283000F32481D7CBCDE18D688F1E4B5BF6B85367
+:10284000DC377740F944FC05F23F31067E8C0ECE32
+:1028500009CCD3807AF66E736053DA2854677DF31F
+:10286000574A1877B47C1CD2958DA98D989FCAD4ED
+:10287000A6348A03CB74503C94C0376D5E65AC8738
+:10288000CE97265ACEDE8B72529B67ECBC6A2D81A6
+:10289000C73154ED58DA7BB3593FF38279ECC271FA
+:1028A000EE8DF336B0E879EC16F3D89336AAEF3C08
+:1028B0002C48EF068C03B5539C952EDEAF9DE69D0C
+:1028C0002947C5CD6AF17E1ABD1CFB84E5A0DDC693
+:1028D0001AD1378870E1F83AC1663E8BF87FD4C8C8
+:1028E0000E213DADB7B37CD4A38FB138DF3A2F753D
+:1028F00093EB4AA1A953FD638CD353F0B495F657DB
+:10290000B2F0737EC6021EB4778E59CD2AF1598F6C
+:10291000272A5E4EE3C3C7DECB22BBFFA8D56C439C
+:102920003C82FA947FF4BDF8500E8EE7D2C5C3E521
+:10293000F4C53B5435CF239FDB584FEF18B85927C8
+:10294000BDEB705AD029635D12CE2FF31EE6A1793C
+:102950008CF159B81F9E9FD7978975C4CEAFCC62B2
+:10296000A3F84D66337EDCADE34FAC65A7AA87D7ED
+:102970005184E3A0083C35F8C5CEBBCFFA7701DC23
+:1029800047EBE06E817623E89C8E6524F6D39E6546
+:102990003A3FBC9687F2239FD8951AE8C67DFED2AF
+:1029A00058CFE3BD2A2D24F7122B7AE8FED999C817
+:1029B0007B0AB4CE636258397E5C26C643FD55D08F
+:1029C00059ECBCB4F5C4AE33160EDA7CAFB4CEE32A
+:1029D0005A7FB1EB750CD03E669DA34DFEFF42FCC5
+:1029E0003F2377DB89DF8A7BAE75E23C103112FB37
+:1029F0009D2BFA9DDB2D51BF7B58CF4343911F1D6B
+:102A00003138502ECD3D620853FC6CE304B53B6A6F
+:102A10003C8EFF5A7BB6AB2701F143EBE7D39AFF1D
+:102A20004CC038E581DA3BD225A2A7A333BFA078FA
+:102A30008D3D47DAE93C7A4725601ED9A53E3A4FDD
+:102A4000FB2783FF966CA8F77E8D4CF8FD7E4D1C0E
+:102A5000C5CF6AFCF435E41F7957E6AB8CD57F8788
+:102A6000E36FFD75F89DF8FD399FBBE87DC0176FDA
+:102A70007E0364FFC44973EEC1F49C7F6EBDD9062A
+:102A8000C431B14CE2EF01EED9FD10C63D4FBC6D33
+:102A9000CE3DC9509E9879D3F75C587E8724CECB23
+:102AA000367D0FE3A426DE2591F2D5BE17EAD3B911
+:102AB00042C088E777B7E23B378514CFA0EAE3C48A
+:102AC00046A6F338F991E91C9F4AD23D942610217D
+:102AD000DFAFE6710F601F19B99F2460C4799FBCF6
+:102AE00011B8E620EC3790D5A2D3B74E4D36DFA90A
+:102AF00016F27A7ABFF3A47429CAEF16AB674D4C6D
+:102B0000E7F2553BFFC0F6B70CD797F3FBEE937097
+:102B10007ED08FCDC3E530CEAB6A38FFEAF5DE5309
+:102B200033C74F4032BC251FF832433C0CDC9C8E2F
+:102B30007C33ED133BD723BB87E33ACE18BB79DC5C
+:102B40009093FB81919F1C8686132A7C4FDC07BFE4
+:102B5000DF97CEDFF53965A4B743D8B104735B03C3
+:102B60002CE584E0AFF8D3ACC90B818FF81E8C261E
+:102B70001F7EE9DDA9A07C99C23A15C4FF69AC8B20
+:102B8000BEDF633DF4F5338711BFD3998FBE9F8EAF
+:102B9000EF1E4D7E04217740BECCC7797F92C5E5FC
+:102BA0005F050B1C417DEE6D1C1FF93F0B13BDF63D
+:102BB000F2C118FE3E201FC4E9A544CEBD343E2C10
+:102BC0000580FF63FD8D41E2C7A92C700F8E9FC168
+:102BD000C294CE027E4CFE9A5E3E1C4DEFBDE71FB6
+:102BE00005129D4FEF8C4F207BF36481B44FBC1FC7
+:102BF00066C07B72042F6834295F9A8376CF4E01BA
+:102C0000CF4915A9F3303D69D6C62E9CC7A4FC3721
+:102C10006FC7F440707BD1E89F908CFB7733DFBFA8
+:102C200077D6D4101DFAC20E7A47634AA193E20503
+:102C30008B4FF88E617A5A094F17767695E2BB1A58
+:102C4000DF1BC7D3230EF51CC5B4BF9CA7AF3B1237
+:102C500096313D35DF5B8C69E72C17C539B32A7196
+:102C60005E10B3CF9359B0EA66C48BDFE418517C91
+:102C700087D287129E5E3F5F6213A1DDF555D29326
+:102C8000924E3F60C1A70CC807ABC53E3903FC5C40
+:102C9000B73A5069C4FB158007F7E2FA60FF9F401E
+:102CA000F86BF8706FDC9B672480DB41110F1B9C75
+:102CB000CEE10CF298E05C15E07E55FCA94A41FD9E
+:102CC00048FB7110DFD5F8FA2949B49FC3DF5FF9DB
+:102CD000DD3B207A019FCAFDDE7246F21F140D3CD7
+:102CE000C70998E9DCA67CD66D53E85DB7C0A62E6F
+:102CF0008A8B76E8E2DA119F3E3045A58F09FC7495
+:102D00005749E4BF62FAB87603C6BFF0FBBA6E1B40
+:102D1000D7375203A6A83879B413A2EA33F5583A44
+:102D2000E9030AC59FE48BF813F8358CF193F0554D
+:102D300031FED2987E9EFCFEEF582507C62DDF108F
+:102D4000F257123E0B3BEA3601EF172CDC5F506561
+:102D50009342F86B957FEB9DB8DE84B76D1EF487C8
+:102D6000221E9B4A22F061420E3F2DE4D6B56E66CC
+:102D7000C926392F05D12F71ED0BE9DC1E75F3BB88
+:102D8000F3D7ACF4905E54354B620EC49BE6387AB0
+:102D9000EF01E6F1F5D7BA7BA4B7CD12F3585D1277
+:102DA000421706AB192CEBE5EFC1622D9EC66344BA
+:102DB000E63DDD1F6061DC1737F3A13FFC3755B2FC
+:102DC0006A71D1E30EE4D79567713C98629328FE4F
+:102DD000BBF4723C0B8FC4FD0E352462BD774C846E
+:102DE000BFC95573EE447EA5F1B15271CEC3AA7925
+:102DF000DC7616E08B9FE2242545D1F18958FE82CE
+:102E00008E189C6F5A6F1ABA49417EC1C81FCE2CCA
+:102E1000DD0477BBA63709FB4A7BEFEB866EE73C08
+:102E2000DC9FD1364EE7F8240BFACB2D19393C6ED6
+:102E3000A9FA976F63BEE4E17872EA13361AE77B6A
+:102E40006A80777DED195C8EBDF2DEA22CB4234F33
+:102E5000D9FD59683FA66778283FB7CA1C9661BC60
+:102E6000536901CA3F25E2BBB1FE594C3BFD594EA7
+:102E7000AAEFA5F1B17E228E9B15A0FC5EF962D56A
+:102E8000DA0DCBC47647BD9E598807A70A52253C68
+:102E900077CB14F3C8CD87F1747E9FDCEA4D5D38A3
+:102EA0003ED821EC7DBAE7158EE2DFE81EB1170FA0
+:102EB000CCB76F403F0DC68DC17E617CD843265F85
+:102EC000A301E8A3B43C24FCBAD1FC38F5E3960D89
+:102ED000985BCD7CE52E1EE72A37A644F8EFEF0479
+:102EE0009DEED4F84191E0DB8B0691DFEB37737AEE
+:102EF000F97614BF9B14E07C7B925FE3D79BBA709A
+:102F00007F6E66DD0AF6FB7DBC2A0FE355325F5506
+:102F1000B1847CDA43F815B472FE3929C0F7BB9C42
+:102F2000F9899F57FCB6611A8A9319CCD3AF1CD488
+:102F3000E4DFAB8B1E273BF2DBF277E0A3DFCF1899
+:102F4000D597CF1776F2F49442CEE781CFF833923B
+:102F500023F2E86AE5AB34EB556E37C5EC57C4BED7
+:102F6000E1F2342247791C57964D0EADA3CEEAA567
+:102F7000FEE4E96F237A46B4BD739572BE777CC6D2
+:102F8000FD72191A1932C981766CA6683FDAC282BD
+:102F9000F128FFAB84FD27EC3190FF3FC82066C5C8
+:102FA000ED3037DA61800FED29458477B1F32D706C
+:102FB000ABAB10CE130C361FF2A93FFD86BF6339B1
+:102FC000599D3901E3C5A6B0C006FDFDAD6160574E
+:102FD000283ABE5F10B2804D1C495FBBDF11951EC1
+:102FE000DEE98EAA7FDD214F547911080D7DF9C8E5
+:102FF00013BEA8F4A8AE3151F5BFF3B61A95BEBE04
+:10300000BB22AAFE0DE7FD51E9A12C24E3626FEC7F
+:10301000A98E6AF727164A74905C57BBF253E8FEF4
+:1030200021FDDC743910D57EB8B827369E2D8E6A06
+:10303000CF9EE3F750EBE11FEEDB3531F750878A87
+:1030400077556FAD3246EEABD27C9AC9DF3634A6E7
+:103050007EECBDB06732EC2EDC27A0E91294A77D90
+:10306000F687F17B8165FB5928E4C5F5505D76CD87
+:103070006EFEBE5EECBAB47B63CCF08C82F5FEE2F1
+:1030800091183E29607647EFA7D513BD9FF1F9D17E
+:10309000FB69F745EFE7A031D1FBE954A3F733A96A
+:1030A000227A3F93FDD1FB995A1DBD9F6981E8FDAE
+:1030B000CCA889DECFACFAE87DCC5E15BD5FDE60C2
+:1030C0004D54F990C6FA687C14FB99D7B22AAA9D90
+:1030D000B69F41F8F74DFB5966DB2AA3BD5FF1446B
+:1030E000F4BDE4ABDDD73FC6ECEBD5DEF7033EF72E
+:1030F00009D27519F337244ABC3FBD1DF3BA900BB2
+:10310000C7D26E2E4FF4F0F228BBA66013D9359AC1
+:103110003E83662ED2C55416267EDE570E78284E84
+:103120006A06FADD20BDDC10DE88FAC117695C9FF3
+:1031300005FE2C65921F6D2BB59F82768E14F16370
+:10314000F5C787F1BCE26AF95FAF5FEB7BF5E45F3F
+:10315000D2FC4C03FA973C5911BE064CB36C5599FE
+:103160001FEF317E29CE957AACDCFF5C76FF78CA02
+:103170002FB3AC203F4EE91BFC5DFC529B44F13B5E
+:10318000651566D22F7BEDA20B32C9D793959E2C85
+:103190008CE7393939B5DFB8B0A3F6DBDEAB87266B
+:1031A0006522BEF764116F7FD2E90D61FDA3125352
+:1031B00083284F93B9BC3E6937A838DE4989DFEBD5
+:1031C0003D49BE37F8CEF150FDDEF3B5652CEA7C03
+:1031D000ED70BD439CAF7138F4FC8069711A6417BF
+:1031E0001FB6E588F3C9B3A457F75CCFE8FDCB0B56
+:1031F000C6CE30DD83D9EEA57345420BECAF859F7B
+:10320000D74D10F7990F2B2069719E85FC7EE861E0
+:1032100011EF734AEC2BF9D9B19F66BB66C7F07901
+:10322000B51490FE1C2BE70E33CF5ABA6FBA9A89A9
+:10323000B8ADCED32BB17EF5507A0799E6A1D3571E
+:103240000FB3CE0FB69550BC07D53FE9ECFCFC247C
+:10325000C265F135BE208BE0876BC4D447EFF1A087
+:10326000FDB389CED1CAABF8FDEF72C75A05E94963
+:10327000AAE6F8134B4F5BDD816AC4DB56EF53457A
+:103280002BA1AF0A6F8715EB97093FF5EBBD767A57
+:10329000347D1D4B7B60EFCA7EE8AA571F622DF478
+:1032A000FD07E86929A7A7366AAFD99D40F7B59908
+:1032B000A322EB04006761FCDE25A791F138A92069
+:1032C000D3EB1903D195069F0A47D1712C8E854BFC
+:1032D0007D4A6075A6EE5CA422D177BADE85FE3504
+:1032E000B32F48EB8ED61B4E0E00A73E7C67F23004
+:1032F000F2E794558DA7754D6041FA4E6621E59B26
+:10330000F9CF80FE95169CA7A65F4E177C07E0B408
+:103310003533B92FDFD1F4B15EB8C4DA4357EB6768
+:10332000E9D5B3A2F5423606E810F075BDC68F6246
+:10333000E03451DC4F7FC72189F7D8D5696929B8B6
+:103340006EFEF34E23A79F72E04F28B7A70AF9C479
+:103350000AB9DEE0837F38AFBF305BC0827EA9DC74
+:10336000687DA254DC432F8F7917A3D74E14F7D76B
+:103370004B63CA63E1A0AD33565E69769CF67EF37B
+:1033800040EB3E9A29E49A870DFB1ACA416691BE2A
+:10339000D2F55B03F9C95F49BE6DFE56C0A7618FC8
+:1033A0005F43EFBDBC9272C73D6F62FAB1A1A4C783
+:1033B0004F4C5FBC7705A49FDC5348E59ADC7B2328
+:1033C00093FB21CB656901FAB1F24BDEB9DD0BF35A
+:1033D000396E657762DACD6A5A2B611C77614EF1DE
+:1033E0007AE4072646F5A65EB76CA4FE5CF974265F
+:1033F000F71B4F15F1AA59F8445B317D15F443646E
+:10340000B9438A03FA3589FB3A190A6BC077FE4C37
+:10341000EE169B03E11BC7FB2DCF0967DE8DF6C8B7
+:10342000411BBDCF7CAD2FFEEC109C8F24D17CAE18
+:10343000CD97C2F87E7279A2A85F1ACE7D04EB3FC9
+:103440006D2A463E7CADEFE60B58BF5CBC3B9AA0B4
+:10345000068C05E82F10FE8E630ADF8F2F322DB405
+:10346000EE176CE38D784FFE563FF737B983DD0DCD
+:1034700049B8DEEAF125B85E6D7D7FC9E4F13955C2
+:103480006378BD2AFF1CE37CDDFA6F557BE85D9F06
+:103490005BABCF127FFC5D0CFD56E22F72847EFD8C
+:1034A000F80BE0C99B7702FD225F99E5257A9CC164
+:1034B00054FADEC202C4CFAA590BA56F679DF49DD2
+:1034C000C5BA38DD9EEDA5DB6C570ED1AD394B4743
+:1034D000B7B731F652B7B72FBD0EC4BF80BEED5996
+:1034E000A3FAD2D740FCBAAC7AC5DE95FDD8C16547
+:1034F0007943683D11BEDD497CE7DBFA79B575C0DB
+:10350000BA72B29223FA0F0339807E6D98EF103EA3
+:10351000DFE8F51DED871FE9F5A26FAB0FA1FF05F1
+:10352000F580AC7AC6EDD2183DE81BCE2DC7D2FC93
+:10353000AE706ED9E71C34457DD4931C3917A87B37
+:10354000DB62F160DC74899FE5601C40F2F857BCD7
+:10355000D06F9D38BF88EF626A1BE43F2AE25B0FA1
+:10356000783DD4AFDBC4E325F01DAC221BC6097443
+:1035700085299E2A19F4154FE47CFF513BB4C3F70B
+:10358000ABBD9C7E7BDB5B58439CAE7DE91D9CCF35
+:103590007EF1A089DE01614A201BF59894DFF37764
+:1035A00076CF3D64A2B8B621264E772E2D6E9D6D46
+:1035B000E47F6720CBCBCFE7A4A36E74EA04D9667F
+:1035C000FA6A718FE7C47D962F9C3E7A0FF38B07C2
+:1035D0005324D4D3CE29EAABD530EE90479CD23ACF
+:1035E00016A95F95E5E1ED3CEA6727705D95361E0B
+:1035F00047C60245F45E8EA1648A05CFB30DAB7B4E
+:103600004E40FB655936FAFB55E5D9A74FE17B41A2
+:10361000179E33D21B888B3B660C0A63334575FBC0
+:1036200087F795DB8B43C6283B64E9FEE8F4B2CE0E
+:10363000E8745D8C1C88E5F73FCAEAE5E33EE4E305
+:10364000576B9FA892BA16E96089D877B3B9FE7C08
+:103650001BACDBFC707EF15AC46BD6F332BED19D3D
+:10366000F288B798E2BFB2385FF767F99BB09D392F
+:10367000BB7004DA55A5D9D3E6D03EEEB6D2DF4D05
+:10368000F9021F52C1F44B5C3EB60EE6E5AD7BCCB1
+:103690001E49C8D351A3316E86D34FDD2E2E0FE1C4
+:1036A000C7C2DF93512DB88FAD26D59486EDFE8924
+:1036B000F9703E35BB16517C572DEBA278E95F8B34
+:1036C000FDAA333C63B2C0AFAD89EE52F4D3B6FE6F
+:1036D00054A2773A95BF2B7EC41F0CAFA0FB0F16E8
+:1036E000D5817FF763D92127BD8FD091C5CFC39AEC
+:1036F000C645DF67B03C57194457E64D7F2FA77783
+:103700008216ADBA83DE57E9BDCF2CE2DF16DD3F6E
+:1037100093F28FEDFE3209FBFDF04199FCE11F3E73
+:103720003ABE0BFF8ECCA2669BC7D2DF7A593DFD15
+:103730003D920689DFB3FE84D5FFFA7E00D91F458E
+:103740003C1C73D427103D7BEA13F4F741DAF71AD7
+:10375000E81DA83FEE1D49EFC8B64E9F320AE5F0BE
+:103760004DCE127A274A2BD7F47B2571CC9348474C
+:1037700037FDDD407450FEF0B838F4D72A20C7304A
+:10378000BED4D35C4AF1964BFC714E0F31331E47C9
+:10379000DEFEA085F483BAE689B42F35CD3504F773
+:1037A0002133D265ECB7FD198939705D8671716B73
+:1037B000A17EDDC3E4AE61ED4CA9E8CF5FBC30CBA8
+:1037C00040FB747C7A9C2F0CF52F087FC8F86C3E68
+:1037D0009F89867153D0AE5AF6A04C719FCB1E3C88
+:1037E0009942EF123C61A0777F40A34A4778C4D248
+:1037F0008D36BF58FA3143BFD83E968EDA83FC7DB2
+:10380000F1587AC29FB0EE7CFC447331CD2B96CE3A
+:10381000E636E7D07B09AC91D3DB05A007D23FAFFA
+:103820009EDE3E45FEADD11BCB9C1E1547ADD1970C
+:1038300096D6F8B9765E6BF131B5C346F78C55BCB8
+:1038400047ED1ACCCF6B5D83F93BBCCA5F57EEFFE7
+:1038500015CC7F6F56E02BA4CF6CA616217E793F46
+:1038600067F8FC019D4BD379732EBFEFB2C3E89785
+:10387000492F5402FFFA2BC83736D78C443A778A3F
+:10388000FEFC5901F360E867FEEAC0672F33C4B756
+:103890006B88DEE75FAE92F1BCDBD6AADDAFF497B2
+:1038A0005A5DF4F7074A101F353E9D07F36DEBE7AD
+:1038B0001CBA7830D77BF25C7EEA27219BBF4FD5BC
+:1038C0009ACCE96BCF2A7EEEAFE95709620FBD1E95
+:1038D000FEBE97650C87C74AB7C18371F2300EE50B
+:1038E0007BC7C8C149F0B58DE1F732E34BC2F4DEC6
+:1038F000711EE6031E797D8CDE41D1CAA1FE59CC32
+:103900009799C56383319AE137C487BC7CFE7E9961
+:10391000B795E76BFBFFA71689E8136C5007FE1DF0
+:10392000118CBF277959C2E5E54AB7C9A37F5FE388
+:10393000BB69E3870F46F9A4AAB92EEDDD52F8F969
+:103940002F11BF085C8AE2D7EE2A6401BCD7A6AD6E
+:10395000676CABBA11F130166EF3C53C1FC4790227
+:10396000AA8CF5413A7FE0F939067BA2F0499B9F8A
+:1039700069B94D417A7E14F511D87F53BADB86744C
+:1039800004EBA03826C6E27C78CEA5C55964A5E72D
+:10399000537D2DDEC215075FD01F807D2A888726C4
+:1039A0009995E33D8EFB643F9DB7DD6768A17EBFBF
+:1039B00094B9DE93E9F01F580870CD301C285A01E5
+:1039C000F39B6D51FD83494FF1D0FDDE7303BC1BAA
+:1039D0003FDB32FE16825F6374FC49CA7AC18717E7
+:1039E000CBC487B53894D8B8933D728B05C70F0EFA
+:1039F000E6E74CCCC2EF61ED18CBE8EF50AEBF9ECE
+:103A0000DB85DAFED489FD918E48B42F2C266E46D4
+:103A10008BAB8917F1C1DAB8730B95B0B99FF1F18F
+:103A2000473F6FAD7EFCEE2E2FCE6BA0767B41EF35
+:103A3000C2F853B6D1E7C17A1F7A02AB100E19EB68
+:103A4000E778783C659717E1368D79F64A43302E52
+:103A5000CC9389EFB74DB3FCF26DEC7F9A857592EC
+:103A60009EEA8BB593A3F5F0E5C2DFD62BD75EE2D5
+:103A7000FEB6E59ABFED08F7B7D5097F5BEC7DB9D7
+:103A8000BA43E3D38C905EEE3749E87FBB2039E23E
+:103A9000707E07BF2AA37B74DA3D318FF0AFB51675
+:103AA000753FF623945B8B0BC93F7149DC2F685D32
+:103AB0005B9A86C431E0FDCB0D72DB3EAFEEFEE5D6
+:103AC00006799F883F17F7DE1C71F4F765C43E66E0
+:103AD0000B78B789FB6F6DC21F26ADE6F73CDA6243
+:103AE000FC5BF1857C9CC40699DE2708E141EA2055
+:103AF000ACC7B8DFCC6611F1398E38FE6E01BFC796
+:103B0000943286C3B64DBB3727F0438814D6EA54A7
+:103B1000D3F0FEBFBDD0EFB5E11B63594FFC3A2E89
+:103B2000F95BDCCF67DF6DF9E6FBF95BFC586EC132
+:103B3000D826518E621CE445EFDF0FC1B8E54DF683
+:103B400048B9027A95A5414B57FA27E4C27A2591E4
+:103B50000E2E7E18E38A1EB6B2A8F1F4F35362FA71
+:103B6000377A284E48B47FEC7B13147A1F43A4FFA6
+:103B7000F3217C8FE06163747F84EAA23D26B4F177
+:103B8000E4B68296E67111B90572EC7788F79E1E4D
+:103B90004729FD990721DFE21D3388991A2F571114
+:103BA0007F37BAB8FD8C3101F8B45E5D6ECE3E3A17
+:103BB000E7573C145F61F57A487F3D3B98DB232B48
+:103BC0004C5CDE28472AE9495923F3EDFB9597E43D
+:103BD000DD1F902FA5644F7B15F5134DDE811EBFB1
+:103BE000F1FBD06FD376E01BD08FA555C4318BFD90
+:103BF00036F79EBB07994CF5FCA390BFA8D9814F1F
+:103C000007EBEE61E4B57A4CD89FF6774C5A17E78C
+:103C1000C8924E3E2AD95C1FCDCBE7F229AF35D4EE
+:103C20009803FD29CE2A92AB5ABD1C47AE8CEBCF30
+:103C3000C914720EE428EA9F39AD013AF2CF51025D
+:103C40003371DD39D50B4DA87F2BD95CFF2A690C68
+:103C500059C7E35ED6C8F49EFFC7423E181DF3491C
+:103C60003F37565B6C88BC7BFC4F5AB1FFBCFC7D78
+:103C7000343E7328F42E1753F8DF2D7C2C5119B5E0
+:103C800059379FCD0EA502E731DA105841F10D49A1
+:103C90006355A497ACC42915BE04CEF7EFB6E17DF9
+:103CA000E0FEDF2B9DEDE1FBD220F983DF477A2B8D
+:103CB00002DD9C45CAB3C53B0E19D9FCFE9127E82D
+:103CC000203D7FDCE77ED27F33B2155AC72F94EEBA
+:103CD00078D4EFF298BA622EAED36FF370BF792723
+:103CE000D9A9AE351EBAC76271756FB90ECB7DFC0E
+:103CF000EF4A6AFAF2A59FA7521CCE83D981FCEC49
+:103D000051B89EEE4770DFD916FEF71A2EFDDC4C37
+:103D10007CC2F5A3428A236972753F52C1E8FD0354
+:103D2000B2932DAEB06508C2F1B2EC93104F619B17
+:103D3000F05D1F9B8DBF375402744AF700DC12C53B
+:103D4000A9D87C3D6F61FF533C6FF9701D65E27D22
+:103D5000A4587D8198B376FEC3707D41F6A1855C41
+:103D60003F0D5F2745F488094C257FB8A65FECC05E
+:103D7000EB8AD074876CA1F389922E0E8729AB5FF2
+:103D8000A6F1ECBE4E15FDD2F3D19F09E99CFCE9EA
+:103D9000741F61410BA7A7B9020F9902FA37F0D738
+:103DA0008AEC78112FDC405F926BB89E66139D2BD6
+:103DB000E4347A4DFAF7B5B4F75DE6B6F0F7704C37
+:103DC000E29E584E89882B645BA87C46B624FA5D37
+:103DD00027BEDAFB227CDCDE77878A38BFBE2B77F2
+:103DE0003ABDF39358724D31CEDBAD300BC6B32CD8
+:103DF00016FDC4BE3BA4CDA7A4A2258DE2847ADF24
+:103E00001DE27260E077877A26E460F9640FFDFDB9
+:103E1000ADE5D99EFFB7DE1F02BAC0F787D664F3BF
+:103E20007B41BDEF0FF9A2EF87C6BE3BB4398DFBD6
+:103E3000EFF7B0D02E7CAF23986F72205CA7E5BF60
+:103E4000FA8DFA437DCA8C468CCFBD34F3F219BC8F
+:103E50007BBB7D6DE54CBA17379CDF7B67C103BE2A
+:103E600019241FA3F58CC8FDBE2174FF997C2A6913
+:103E7000FDDCEB2B5242FAFBCBB68E547EDF7D800D
+:103E80007B7D36E780F7FAC224B7C5BD3E940BD8D8
+:103E90007F6D91D28674ABBDE36913F7CED84BFC2E
+:103EA0005CCCD6C6F5044D1FFAF4252BF9E76CA0BF
+:103EB000F7A05EC27ECEEF675C127654D0A7ECE32B
+:103EC000E769AA7B86CE4E6F107CCE26851752FFFF
+:103ED00007FEDBEFF71DCED6C9953EF7FB06842320
+:103EE0008F37EC79D01E753E69DB3D2CFA5D81265B
+:103EF0007E4FFCFD7CFE771B237A56D8A17F5FC0E6
+:103F000066E4EF53CC13F7F334F8CDF39BE8EF7985
+:103F1000D824FE0E0653C20EFD7DB079C5F3E9BC70
+:103F200064207B799EB8A737AF31FA5ED3EF50B1EA
+:103F30004B46FFD278BA6774EFB64AF29F2CC4FBA7
+:103F40004943D0BFD222EE1B45FC48F82EF112D6D1
+:103F500049F99E4625E886F57ADE8E0FA1C801ED67
+:103F6000C0C3BE83FA9A9FF8A03753F685B199244F
+:103F70004BA8A778D0EB9C0AD36F52084E6D8D5298
+:103F800008E34B3735C8E23C95F3F16083AC623F00
+:103F9000309E1BF5F22F85BC1DE411F22AE6EF7F5F
+:103FA00069FD3718393F5CCBE430A665897F37A1BE
+:103FB0003CEDC71ED2FA6B30D65B50DEF764C9E425
+:103FC000776D3006EA70DF1ADE899751DE37D8EB5D
+:103FD0001B2B7839D1DA17D67005F93F8BF8DF271C
+:103FE00025F283F9FF6FAFD51F430080000000006A
+:103FF0001F8B080000000000000BCD7D097C54D50C
+:10400000D5F87DB327990993909540329390050890
+:10401000C9244044409C2484468D74D80414710201
+:1040200001B20341DB68C14C4C80A0E133D4284885
+:1040300051266C6A051B10904AB4C3A6B46A8DADB4
+:10404000B6B8F125A82802128356DADAFA3FE7DC7F
+:10405000FB26EF0DA4D0DFF7EFEFFB62EDF52EEFBF
+:104060002EE79E73EED9EE9DC4F783DA1E9618BB39
+:1040700090A0616C0C630B9A8C8C9918FDFD00FF6D
+:104080002E6C51E7176F54E7CBBCEAFC02E6FE55F5
+:104090008C96B18A67D5E51712ACBC7F6633B02425
+:1040A000C61AF5B63FD84733D6B356C7B6DA18ABFB
+:1040B0001FAC71B21B18D30CE16962D8A4D90CEA09
+:1040C00059988125C3FC9A75F0DF11903645B47973
+:1040D00020DF18C666B79BFFE7F30D9C67B42D85FC
+:1040E000E609FDD3788D6B252F8E077F4E9CCF82FE
+:1040F0005DC66D0FDB21B5D842711DE7A49E342D3E
+:10410000947BD6596C3BA81DAC338AB1F956DEE7D7
+:10411000279263A70FDA6B1EDDBD3605BF7F449B78
+:104120000D23B2FCE96627F6FFF29766AF11BE2BAE
+:104130000598C58643DEF1EE6B581FB82EF8B3E93B
+:1041400072A05FFC2FD8AAF911CC199401FFAD6CB5
+:104150009788FF6F602C4DE4A1CF8448D7CDB64837
+:10416000E8370F0A60FC973719BD0D30DEE39A4F30
+:10417000F6BC8EF0DF13E440F857AFE8D9C9E0FB96
+:104180006F22DC93B1FDF9FB3F982C4139D3F1EF5D
+:104190002EBE12BD15F16474A3B1AF7FFCBF66459E
+:1041A0001EC76F8245DC0869ABBABC7473C077EC7C
+:1041B0009F46E53C196B21B83F61700FB3C2BE6EDC
+:1041C00072E5E4E07C9ED0B71432A85F1FE39E8DB9
+:1041D000F3FAB4C0F59AC64EDB91E21AC9D8ABDF48
+:1041E0002F48D2011C3D274D8E1D50FEAAAE2B2418
+:1041F0002C9DB1F404983CB48F31314F70382FC7E7
+:104200007E0D0FB17B5C90FE807F37F7A50B6C12A3
+:104210008DBFDCE60C4F80947D0FB302786B11B636
+:10422000D095C9BCD7A985715887644D86A4DAC6D4
+:10423000BA17873266EE909C89009F2543355E0948
+:10424000C6AF366BBA6F80F264B386F0850DD57950
+:1042500093B1BC957916C37EE93AEA3DD81FB4F311
+:10426000DC00F965063E4F791ED507A73237CC2F03
+:1042700024C2A55908E3E94B3504A327F42EEAEF3D
+:104280000968EB81FE46C3FE7BCD58E3A57947194B
+:104290005C7941501F15E5737870DF984BE3B230BD
+:1042A000B6D2E6DC6883FACFB02816E830DA598750
+:1042B00070FCF67CB046CA64ECC4BBD30774413FC3
+:1042C000DF32D7002BC0ED8CD6FD132BE0F562E674
+:1042D0003120DCCB989752D63A90F675918EF974CE
+:1042E00000CF45339CEF4B199CBE7C01F4A5CC5705
+:1042F000B24EA2770674E653E043A5CE7758023853
+:104300005599982F04D376F577D5AC87BE5B72F0BC
+:1043100007A34F45071C4FA2B535594B71FD4EE71A
+:10432000D008D827336FC2FE1ECBE1293998CF02BF
+:10433000F3BB279DB94D89D7DFEEACAD254A03EB22
+:104340006D92F8F893B566A709E05AB54E43740A22
+:104350001D158D817E4A19C78B25B6C96719CC3FBB
+:1043600002C80EE9D97440EB7DC84EED1D3EC8571A
+:10437000BD627160D3525B6911CB40F8E84F772979
+:10438000D653CEF64CB6129C5C03904F543CABAE69
+:10439000AF6A57E79730DDE92E198ED0BEF6A3B687
+:1043A000F1C71474D561B3449C194173B3FF807095
+:1043B000D7CE1DE0BE0ABECBE97775DEF1C7F4B0FB
+:1043C0002AC97904F1A25CC79CEDE957B61B3F846A
+:1043D000D3C751F3A5816E457D5E3AA033E473F2F5
+:1043E000AE4E579D4857D06F4827E02BB433E93C79
+:1043F0002C4CF17D7FDFBD6FD3D077470DBCFE51D4
+:104400004B8813E11763604DA6ECBE76311AD6686F
+:10441000027C7426B83EC4F99B6C3603CE6F9BDEDB
+:10442000C334C8172299630780E1293DF30441BBD7
+:1044300038AD86F6334E6BDA8A7CF08FF17C5DD72F
+:10444000C28F90F41E3DC2314EBB87F06E888679D4
+:1044500018F467D0C0B980FD86301604F3DA1CC4A6
+:104460003C381FA86712AF672C1BBF633E09D26898
+:10447000D8CB10287F14CF17E4BF23CDDEAD308515
+:104480005828473E0510EB92A0FC911C930DF96D46
+:10449000B486CFBBBFFD8BD6318F399C5266C11419
+:1044A000966CF917ED657E116DE4F38A0E59DA8684
+:1044B000708ABE272DBB01F029C8EED2D92309CFBF
+:1044C00033907FC870A916F8EE87CB41C96709ED14
+:1044D000A39B1098B30EF95D8B91F81DA12CE56399
+:1044E000BD782E9EC23CF08FAA185718EF5F9CA78C
+:1044F0008F8E24F983D50E24FEB4C602FB9D4E7028
+:1045000054EDB34CF79B25BEDF39799D747EF6AC34
+:10451000640CE127B74B1078166F97547C7585C0F3
+:10452000C37BECCE043BF473FE7D93890D80298E12
+:10453000E6745BED3213FF66ACCBF033284B3828C2
+:10454000591F463E94A6A1FE360F710FC379AFF9ED
+:10455000C0ECD1C2770FA79D5E1D87FC39C2918345
+:10456000EC3109CB819FBA86B84762FF252BDC5F0F
+:104570001F46B6396D7806E263CE0FF9AB0BF97CB6
+:10458000AD5B7148235BAAA4B3DBED1CDFE5F456F9
+:104590003BC7CBF3C01573615E0911CE3988170C88
+:1045A000CE8364D882105BA713F3D5FBB870429317
+:1045B000C0F3E9678309DED5FB72B38E63BE3D2885
+:1045C0000BDBE77C6826789FBF7F90570BF5EB12DB
+:1045D000DC79B81ECBE81E09E7777ECF2D59980607
+:1045E000D2818CFFD14037D87FF45D26921F643C86
+:1045F00078420FFB9FD4471FA3ED369A7782389FEE
+:104600001256B8D842735FDE1CC1F707CA3538DED0
+:10461000725BC16884D768BB8EBEAB89D1DA3E1DA0
+:1046200088A8667D88D9AFC45F3B50B819F8DD23F0
+:104630002004FD804BF7405E21FFF4B6488508D783
+:104640001A10C46AB3FBE6237F5F1363A0FE432EF8
+:10465000EB083F13AD06DA774B93C0D7158CF07794
+:10466000424F67FE0058EFD056DF042D741184636B
+:10467000C5127E3C9209E5110375131E86F2A76BE5
+:10468000B38F9820AF5BDB79136E81BD9569822073
+:10469000D5FD43E7C275D21FD497B45A399EEB9625
+:1046A000A64D03BA5A2BF677F310E732DC87BCF736
+:1046B000F434FE5FD67179F02F61B9670F4760DE81
+:1046C000088CA67F7AF6B023263616D6D19C686071
+:1046D000E9B80E89E0CB860262C07C75EB3EF2F051
+:1046E000F9BD3B04A7B2CD6EA671E77B1C93116C9C
+:1046F000F8BD2606E0DD62CDC3795B9AA769C4E602
+:10470000C74A509EDC344363837C720BEF3770FCE6
+:104710004D82CE7EF3BDB610E5710D743A14CFBD57
+:10472000A1E16D5AA427384F70FD55A911B4FEC7F9
+:10473000047EEB5A5D0C512850FEA9DA57CF9478CD
+:1047400028F31D99DFC878F71BE817D7F51B6622F9
+:10475000F95CC6BF463D87B7E71F1AA28304C6CFE0
+:10476000B3A447BF8FA57ED9439CDF0B3EA8D3DB04
+:1047700056C720EFAAEF9A88705ED01CA6A94EC734
+:104780007E1C35D4CF3A33A37E9A138FA4215F6861
+:10479000B232C986FD2D4E207AFCD0C8105F74EB72
+:1047A000CC1A3C5774EB9D58CA74615179947F1CA4
+:1047B000F2D0FE3EBB9EE65D21F0B151EA9148AEDB
+:1047C00062CE2C9463EFB1BB0F201E84087EC46AB6
+:1047D00083BDC9842F9D44B74FE7740E41F83D6DEA
+:1047E00060A5B89EBC47D3A711BEACD54946C45FEF
+:1047F0009D3B210CF29693D1241F1EB16B5478AFD0
+:10480000C0973806FB9AF88AD685F4A8D373BCD72C
+:10481000AD05BD0ABEFB2CD27D1CE97182A7331FFA
+:10482000F163E2DA4F43726DD77F0E30A787DA2D3E
+:1048300091F9478744FCA3249E51FB5A536806F222
+:10484000DDEF82781A110C29F0CD372F803C0A79E0
+:104850008FD0533CA782BC781EFD54DB53AF8375C9
+:104860009FB4F3F1BED3707EB3145284C33C93FB68
+:10487000439C6F6D57560CEEFFA1D0A83C942B6162
+:1048800092F1787E9DD6733D31100EF34CB95D08E0
+:10489000EF37851E89E3DB611EE1B5F92EE40F11C8
+:1048A00006EF938B905FCF34937E147E7F2E952FEF
+:1048B000FFF81909F5AFFC52467435C865F022FCC3
+:1048C0000F4962DEAF6809EF06153A63F5900F777E
+:1048D000192413D46B63464D2881EF5BDBF8FEB6D9
+:1048E000EE48F522BC0FFC534BF99E62E6DD0AF957
+:1048F000D62CDB9325585F964E72FCCF2581CF0BCB
+:1049000019F5DB6AD1D038AD5580C0D81EFE95B000
+:10491000FD321BD1C178AD86F77737EF8FE9BAE862
+:104920005CBE38D66A457E353E81F7D733C74072C4
+:10493000875FBF9B9DE67D98BE973C2497CC09A6D8
+:10494000FAB3023F3CC989DE1DF63E7E76F1DE7089
+:104950002FEAC10CF8A609F4DD3C517551E8E99E37
+:10496000D2606A7FD1ABF124C3BEE67549DDB82FB2
+:104970001799E8AF94D327D3B5FB34387EA1CD8106
+:10498000F363A6026797424F80F61ED4BB3C660DC8
+:104990001F5FD7138AFC53DE47A827BE13D5E08CD0
+:1049A000457AEC996AD028E50139FD9DE03BE95153
+:1049B000CE84C4317D782AE3F3A1ECE83CD467FAD5
+:1049C000C3EB3F32CEFF6727BAD212A13EFF8E5B08
+:1049D0001A6992455C2F3A2A011E013E1A0C5CAE00
+:1049E00031DC11B7B5C1AE945F38DF3924DA8D8878
+:1049F0006326D4F781163DB87FC30F0C27FE98932A
+:104A0000C8E789A4837684E1E26C1B2EB5D78401C4
+:104A1000DE1F396D8F47FC93F1FA50701CE1BB0229
+:104A2000AFC7E3FC02E7C574AE91D3465E399FC9B8
+:104A300089CE5C828768DFBFDCE8A179190CEDCBF9
+:104A4000083FAA802E607DEF62157CB7ED0EA34F64
+:104A50008BFBAB3737211D9F0C99F75A2480D26C02
+:104A600072FF18FB9F3DEB96D598978E0CB4D5C07E
+:104A7000BC2F1677E5A07EF5A4D13D1DE75B6972DA
+:104A80002744C1BA7ED2DB794A42BEE81A28CE5BFF
+:104A9000D748D7C8FEE7932FF1F1730CEEB938CEA3
+:104AA00051A9CBE24822BCA7EF983992FA3925E008
+:104AB0007558EF9CF035CCFFF0FA84AC06984F7E29
+:104AC000E8FB772DC1F3794374169EF3325C8E8A2E
+:104AD000752DD4B8A27C5AD57CCB68BED6E284D8DA
+:104AE000449AEF3CE2E366315F9D63F0BF9A6F83C7
+:104AF0004CCF2B25C2E7CDC180F2D97D74E5FE48AD
+:104B0000D3867465D434B471BE6072203EBF2DE686
+:104B1000037A0C43F917BE23F97807730C471E106C
+:104B200067E47415B74622BE399F39487F2D61AEC0
+:104B30007814115727BAEB71DEFF1DF2CF31766E74
+:104B40005218F32EF47FE0A16807CAB96C029FFFE8
+:104B5000B5F69FB1660DDA45A609FBD64221174D81
+:104B6000674E3D8E3793B9F5088F3F7C6570A25E26
+:104B7000FC07A1FFCC621E2A9FC3BC94DEC57CD477
+:104B8000FE6ED645F977423286D402FCA76E484DB8
+:104B900046FC56C07B03EE2BE0C73D11881F0FBEBD
+:104BA000C3F1A335F2BAF075AAC00FA0DB2D44B74C
+:104BB000E1F98DC837D9248E177DF4D1D53000E0C6
+:104BC0003735CA9E85F0B8F97BBE1F933FB5B669ED
+:104BD000A53EBC00C6618E85F5FF486C59672F3F26
+:104BE000BF4E38EB2322605E055A33ED43A7434B9B
+:104BF000E7C2EBB915450887D7EBF9FEBCFEA481E7
+:104C0000F6670AF33686417A4BC4D4013EEC073589
+:104C10002618AF335DA273A170B0BE4FCF877F6FF0
+:104C20001DAACE4FD9C8ED0E454E6DB711D374B540
+:104C30009D600A6BFE5A9B81A9DA5E7018D7127EBE
+:104C4000A5DDE068A2B01B0C67C3C91E77FD7683A3
+:104C5000DF262AEC060CAD93C0B77E1CC4F96AE7C8
+:104C600084A3E32FC2BA2F75D809CB1F4AE172EF94
+:104C7000DF135DEFE077D586AE79B8CFA7EBA0AFB5
+:104C800054C63EAD333127E0F2993A2BE5BFA88BED
+:104C9000A1F4CB3A1BA5E7EBD2A8FEAB3A07E5534C
+:104CA000929CEF237EAC09E2FB208FBF5CE0E79A89
+:104CB00021391B5C30FE9A37F5942F6D6F990CAA41
+:104CC0003A5B3EE4F4432100EFE5CF49649FA9E855
+:104CD000701ACC30DF85C7DCAB51FC5DFC66D714A5
+:104CE000641F559725E606D2189FE2FA1CC719F3F0
+:104CF000DEA7510897CFEBC6D23CCED639691EE766
+:104D0000EA0A29CD4D729DC776D54DD2B138E8EF6C
+:104D1000F65DDD3A4C0B0050B8BF139DCCEB857DA2
+:104D2000D8A877BB111F36C69A1C880FB923A73D98
+:104D3000752F437EECFE0BC26566F8828281503E81
+:104D40009975350E847637CF951C3E5B1FDE5E9BD2
+:104D50004E391CAA044E5C785522F8FC719F96E6E9
+:104D6000D17B32D80B270CEBDD174278D7DB6424DC
+:104D700079E290C1638C87FCA1F86007F2C743F128
+:104D800083E85C340A3A3A07FBC460DDD3F7274571
+:104D9000A39E706EF74F6394F6A073E1ED7FF90068
+:104DA000F9D6C71AC7561AB9FDCC26C8BF343886FB
+:104DB000F8CC57820F571B383DB0539AADC807CF78
+:104DC00005737AEB793F782BF2BBD3B21CFF7E7070
+:104DD0001BCA09392FC4E531F539179314D9B7AE79
+:104DE0009AFD23A251FF618323083E69924E53AB83
+:104DF000B01FE0BC6DA97DF9617B179F7EC0D6977F
+:104E00003FB4F76E279EA33B773FD9FB32C259E8E8
+:104E100007CFBDF0D4A05F40AE72CFAA605C27CAB6
+:104E20007963817E0EAD0F21FE7648EF38558BF306
+:104E30007CCA4C76A667FEEBFED307315D57957DA5
+:104E40003F822C299CF6A3E4E77326C742BB9D074B
+:104E5000581692D70898631CCC2F7DE3D74750E4AF
+:104E6000C8F086E50F8272C7B359470741FEF9972C
+:104E7000241FDAF7B3DBDBB64AC843BFDF3608E5E9
+:104E8000D99B936C2AB97EC490C2135A9277D5F2FB
+:104E9000427AEBD779D8DFEE415C6E00F9E1CB7A4C
+:104EA0003BD2C39FB2DDA4DF717BCA985766BE3187
+:104EB0009EE1BA3CB128CF7A8A0D6447C7E5EB2161
+:104EC0007F615F12C92507341E3A8F3CF34D0EDC1B
+:104ED0008F0B2ECF93B87F55D01EE5CEAA2C4FE86E
+:104EE00038D4F33E1EEA000C64439EFE5121C2A753
+:104EF0007ADFE3930741BB0B13984382A997EEBF78
+:104F00003499F61DB451D46F2EEC6B88BA13BE7B66
+:104F1000243D6F0C9EBF2E6D3B8DC396F07136887D
+:104F2000F38E7565905F8550DB86FA3F3361797843
+:104F300047D8E138D6B75F4B3AEAEDE80F18ED36BF
+:104F40003950FFDC68F7C4A2BD4E3E3FE11C2C4641
+:104F5000BC8935887EADD3494FB8DEF34FB6E7C97B
+:104F6000FD6D3070FB9C6CEFDB6CE0E7F90EE03F11
+:104F7000887FF2790DE32E4B1AD3672F64D617B3CF
+:104F8000AC30CFCF408E22BBC0758E2FCB574B8419
+:104F9000DE9427CEDFD9031B5EE982F58E31B95747
+:104FA000E2380B9993DBDD750E1BCA23834DCE07C8
+:104FB00093E81CED89C735C0B9FA10E6ABB5207788
+:104FC0002529E42ED3F59DAB0D427F0BE4B70D965A
+:104FD0009C59681F69407E8B74744C53F91A9C97D6
+:104FE00037F196B0EE517FB6E1BADFD23394F71BBA
+:104FF00018BBEABA5F057A75039FF1C179E04EC527
+:10500000469D0D688F71C2FF2CF0DDC4CBA808F25D
+:1050100031F1FC0AFC1EE0BD05D797CB4254ED9C54
+:105020002C8CECC3CC1C7E5DEB9C107CF57365B9BD
+:10503000E548D2A380C7CBBFE5C2D4F26FB3891FC6
+:10504000F6B79E57C47A7E96E2DE93A4A0DF9BBE9D
+:10505000B1EA901E61BEFB112F27EAB4CCADF493E8
+:10506000C9F8799DF3BD4F621EB4E7B2AF0DA45FDE
+:105070007508FDADA32C9DF4C30386A5FFBD12F5F5
+:10508000AFDFEB895F7558B81EDB31358AE48E439C
+:1050900032DF2DD6927CDA1124BEDF114DF5838CE0
+:1050A000BC9E45335E2FF73F278AFA07FE48E78B01
+:1050B00007F447D257A73A6383513F9D1AA5A1F140
+:1050C000FF7974C4AF90CF4F35915EEDD78BB31895
+:1050D000E99DADF55C2F1EA45DFAC648E4130D21D1
+:1050E00034CF56CBD626F4B3B5AED43A10AF5AED82
+:1050F000BEBB502F6CFD3A85EC1DA0F7929F00F4CB
+:105100005BD2BF7A8AB56D5BB93E2BE7B70A7D7675
+:10511000F65EE27F1ECB5480EBFB62BF4EEAB81E08
+:105120007912F5D5CC3E7FC149D42F493EF4585071
+:105130007F724F09D121DE0796CBFB20977FA00716
+:105140007D14E100FAE80E853EDA1AD612897EB6A1
+:10515000BF27B97B110FE62CDC11C4F9B13708F574
+:10516000DA07B5AE6FB07C53B063CA1DC8874BB8C1
+:105170005EF6815EC0F5AF5C0F7EB5E4F8025CD7E9
+:10518000AB3D314C692795F1C06F0758A9117600E6
+:10519000BE4F5BB64793DE3E3E01F000EBDFD2F23E
+:1051A000735AAE37A7F07AAD4478D4B32748B60324
+:1051B00090BDD9B33F95C62F9CC6E5D5DE159A366E
+:1051C000940D7C758E099392E17B61EFF3745868BE
+:1051D000FFB70878DE23F8D41661F7F7B4EB853E05
+:1051E000EF8B5B82E3760C23FDDFC704FE1D0CA171
+:1051F000FA5EC6FBEB351BB6E13E5F147CA741E2CD
+:1052000072C416E65B44EDDB8354701E64E4E5EC87
+:10521000452857C0E7905EB4DF132429CB0F187CD4
+:105220003B695E7B79F99F8DEE94A10A3AAD0CF54E
+:10523000A58499AF07AE700E20BEDDAFF5D7231E53
+:105240006C593A52862BFFFE4923D5FBED2B557640
+:10525000615FF1AE4DC1F61D91048FAF567C92B3E4
+:10526000D14670CD3888EDF619891E64B8CAF3DBD3
+:1052700022F0CE2DEC0FEC412E579DB2765994FEC4
+:10528000B653AE3316E4531FD56A7D86D0FEF9C9F6
+:10529000DC8D9FFF03FD6D735D866ED423FA6DF781
+:1052A000E07CF26BF65B5FFAFD3CEAA7521DCF7023
+:1052B000EF50A76BA8124FCF6A54F6A897119E9291
+:1052C000029E167F3D8F9BF8225D6DAF3A1B2CE04E
+:1052D000C9ED499EFD76821313F874E6AC86E41896
+:1052E000795E2FEB38BC5E16F6297FB9B027F9E15D
+:1052F000F825C011BE6BB03A4C4A382644BACB11DF
+:105300003F1E32679BBAA0BC7440DE09941FAB7588
+:10531000703EC3BEB40C752FC17A596E91EDA15584
+:10532000E9BE79740EAEB8BE73B622B8A35A4A84E9
+:105330006974EC388029CC8BE0C1F672FEECD6F8AB
+:1053400042455EC27956C07F4E0C47BF329C5DE13C
+:105350003C8FF26A609C0B917C14AF4739A1A25D2F
+:10536000EB0C0AC5BCA1AF9D1DF35E922340BF3379
+:105370008D0579A622ECE07F8D87F272B3D9B482D5
+:10538000FC95EA7893F27D6B3A9332AE2CBF727C37
+:10539000BE3E6676DAD09E503C96D78DABCD679FE9
+:1053A0008C0238093BE2FC66AE0FC35F3DF2FB9214
+:1053B0005689A11E51EC99752BE255F18CC2B3A808
+:1053C0009F143F5ABF1AE59FC5C2DEBCF8E0E1BF9B
+:1053D000E27EC8F10BC5EDCF7C8BF2E8FC80F8953E
+:1053E00092E680795D236EA57CFB0F46751C0B97BA
+:1053F000A3C775B46991AE168AF933CF4486EB1A08
+:1054000027A3A090233EC5CC8D1887E1DA83F8311D
+:10541000AE957F57C578DC851C0FB1C808E732C050
+:10542000FB84C54070B8B47100D9132E097CBEB49A
+:1054300099C3A56A20CF576D93C82F5725F84BD530
+:1054400033DC0EB408E038209BC7693815F3AE147E
+:1054500070C1780D65396BE172A81C9F81711B4E7C
+:10546000857FAD12D675329CC76B28BF53C66B289B
+:10547000CB15F62A61E7F212BCB6E8BDCFED847910
+:105480006A1F0C96E35582514E5DFEF18F9E447B60
+:10549000ABDF9E5EA6EF478E1076F31D9C8FEAFB76
+:1054A000E4086E5F5F3F4CC811CE1494B3D96341DA
+:1054B000A4D7B4466A3C41585FC6F5DF563BE727A0
+:1054C000AD735284FD7CAF8FCEBDC725FFB988FC7C
+:1054D000FBCEF57DFC9DC65D6711FCDD9962A2FAED
+:1054E000610EC18F787D2493F9BB9037BC915361D5
+:1054F0007D1FE07F027CEFD43317F29F3BDB38FF48
+:1055000091E58D3B2528C7F63A6F24CA0332DC02A9
+:10551000CB653E2197B7863963C3D3294EEA1FCAAC
+:1055200073AB35CC1B84714FACF4FAECBB3B04FF7E
+:10553000ED591F44F3FF54E2F15625C1AE876F4683
+:10554000FA7B223111F1CA82CA5B24FAE101BEBCA6
+:105550003DD983E5FD2E813D443DACE4E7A9849728
+:10556000729CC7A92C6E6F0B19CDFDC051A29FA8CC
+:10557000648D2A8D09E671149F16703BA165B4CB2A
+:105580008072D20E1B8F0F2831B87E7793623E3027
+:10559000AE09E16413FDC9702BD1484EF47F94FC31
+:1055A000DC48F400F320BE9E532351FCC7A7C2FE83
+:1055B00027EF0B635C2EBAF3EDC86CF247B07AD9D3
+:1055C0006EEF417F1EC873C477FBC547C0573CA729
+:1055D000C202F171872CD7727C637771F91CC49B6E
+:1055E0003943A1DF05D30DA40FA12DF76F28E716CE
+:1055F000D8BC57956BCBF46D5BED0AB9B64CBFF5D3
+:105600006A78E6C78F003C0BC49BFEF0E93AF0ECE9
+:10561000D6E4C8FEF10CBE1FE3B2F48F67552FED40
+:105620003EE0817996FFEAF15006EDCEEA5AA21CDF
+:10563000D06FE58E55A14E48BFD07942B1BFB35E61
+:105640006DE1D5FCCE4DC992DF1E2B29FC385FE8F9
+:10565000BC2FBC0C70297BDFE8809D634B9E35FA24
+:105660008C648728233905F2DD3CBF86ECA34B0E02
+:1056700006C4633DF37894CD42F38C43BF3848A40D
+:10568000E42FADDEAEA778AEEA77B50E448B25AC3D
+:105690006735CE2FF07B9CC765C0DB25EDDA62C392
+:1056A000802BEB61C70CC8E796EC7BE46BB4DB04A2
+:1056B000C673950A3B5BA07DF6A7C996883368B888
+:1056C000BC81DD80E729C0C5E1437C84F924F36D0A
+:1056D00027FC6D78EE99175E86799EFD203A0B5572
+:1056E000B5F3DBDF0895D2FBECB5B21DFB7C7BD2BA
+:1056F00000F755E02AA75F093B5FDFBE71BE6D3B37
+:1057000028519011EBE069A5DE173A1EC6AB6CD3A9
+:1057100093DDA772F7B69D9B501E01F863DC49C567
+:10572000EEE37F1A07F98A3DFA8822BE1CB314D52E
+:10573000B75F4B6CDC4E22EF4FF98BC70DB691BCB7
+:105740001CE50B799F2AF61C36B09157C233BFFD7A
+:10575000B0A1CB7C95FD6AEF9E8CF6C086E7BE3388
+:1057600020BD9D7D5562D1F62BBF2FDDF14628B6B9
+:10577000BBD6BE9DDF1E427CF17C8744F122FDED4D
+:10578000DF6CDC8C3188DF161606E3967E60F4163B
+:10579000E1BEFED772C2F3CF754B399E3FB52ACA20
+:1057A00009F32ED57BA2AC94F2F2D2A7EF13F8E75F
+:1057B0008CD5904CE489C5F52CDC3C93D653FAD4B7
+:1057C000025A0F7B526263600BBE053976CF55F6E5
+:1057D000F11F820F7EBE153611D6F3B9884FF4FC47
+:1057E000412BF8CE32924FEE136BA48819C87F2B51
+:1057F000E25DFF98ECF7439A94F2EB92ED6B3A710D
+:105800003FBE1CE28C463D16D6EF117092301E470B
+:10581000FB4E4134DF0F1EAF4CDFC159908FE5D8EE
+:10582000BE534F71CB8AEF086EF2F8F78AF161DE52
+:10583000C128477F1EC5E31D18BA48106F24FE4DCE
+:10584000F58AD2221BC07F84F027F8E97CFB5A4EF0
+:10585000D782CEBF7997F38F6AEFD442A2FF4EBDB5
+:105860002F1ADB790FCF9088FE03E34E051E6CD70D
+:105870000B3C50D7C3BC7492129EAF723FDEA2564F
+:10588000457C2BC249F85F96801CEC4B53AE53F815
+:1058900091847F65B1A0F7C0FD0BA4FFEF92857FD7
+:1058A00046D0BFFC3DDB7C757F401FBD7B681F2B56
+:1058B00041BE4039A8F27D23C93995EBB5149FF458
+:1058C00049F3D1A81B01AFCFB5CBF4A9E6A77EFA67
+:1058D0005CC1E3574BF7EE90103F03E9F35CA95727
+:1058E000BA2A7D42F955E9B394FDFFE5A77E78AB6E
+:1058F000E971713FFCD49EA2E6A7DFB2F40168070C
+:1059000067D6E204B2B705C0558667205FEC402633
+:105910001779255F64E81A57C051869F8C9FA0B9FC
+:10592000D1387EBC95F1533E9FFCF819B85E351C0A
+:1059300003EBCF08FEE3FA358F27AB047EC5E39671
+:105940003DAFC58D267A74127B612DAF61FC625F1D
+:10595000DE1B906F0F68EF0CC8BB02DABB03F24B83
+:1059600055ED2B0F1E35F0B8329FAA9DB1F636D2F9
+:1059700097AE9413BC9CAEF77D6DF0205E0CEEA14B
+:10598000F8B63CADE34416ECEB6D9617CDC8571A4C
+:1059900084BECE98E304DA95270F4E12721BE717E8
+:1059A000F9825F3C90C2F961BEA982F6A18169B813
+:1059B000FDEE0A3EA821F9EC75D34D3B51DECF1F19
+:1059C000BC8EF8FCA4C15A9F3183D26E4C273B3861
+:1059D000DE370C1E3518E5FF06B3D1214938FE6DC0
+:1059E00067957E2A39CD37BD351BF5A94966353F08
+:1059F000B92D803FDC6253D717B2BD1128BF16A660
+:105A0000EB9917FBC7F60ABE393BC54AEBBA85B519
+:105A1000345A399D51FE2601D7C1BA2C1DF2DD49F9
+:105A2000BA778EA21E93FB0DB3717CE0F0CDFFC65A
+:105A3000A143F8E69AC3746417B70D09433E832C5B
+:105A4000E68738C6A6B4EFF90AE589293342C87F4C
+:105A50003385B5FF1EFD3C6C86D601B238EB7EC1A6
+:105A60006240FFCBEDED5FEB70BF6F9F20A15AC589
+:105A7000BA83ACF1CBA0BF622D8F736D117CBA21BC
+:105A800088CBA9C5AB87A42442F9ED189F77153FB1
+:105A9000F361B15F0DB9D2663CBF121AB8FE20B7F0
+:105AA000C77EB0DFD753F839F50B91CAF9847CDE95
+:105AB000BEA4C9D89D148AA9DE970AE98461795BDE
+:105AC00052601E4589EC35AEE74836949FBB83840F
+:105AD0009D699D9DE47737807A23AEB33689D13AAC
+:105AE000731D8658A8EF5E6FB7A25F3424DD49DFCF
+:105AF0002F6A916CE867EACE655CFEB718486F3A8A
+:105B000065F50D457E7BCA31CC81727C82AC178EE7
+:105B1000E47155FA34F78B388FE296E237111FD9CA
+:105B2000F7B0EE1CF4D33102FE237706331FC9E130
+:105B30008E50A49B07B5AE8329B0AE4F6AB51EEC5C
+:105B4000E793D260F2D72668B9DFE9AB141BC1B77F
+:105B500008FD50D91827D83507FBD93C5C94875BE2
+:105B600073CC38FEAA2086F32B0EB7CEC3F917AF3D
+:105B70004E25FF5DD1435CAF8AD331930EBE6F4D8E
+:105B8000E17C6D6E7D6B21D9C1EAC33518E738D849
+:105B9000C474185F7E7B7B16D1F303C3DCBFC07572
+:105BA0007CB1928DC37D5AD0BC9EF4B4026DFA00D4
+:105BB000C4BB5E66A37B25FDC9993BEB780CE2B3C1
+:105BC00075264A7F5967653AE061BBEA6228FF4261
+:105BD0009D8DD2F6BA342ADF5BE7A0FCBEBAB19441
+:105BE0003F50E7A4FCC1BA424A5FAE7351F950205E
+:105BF00004B47BC07A3CC66C9E0FE279A7219CE777
+:105C0000711DB01ED233317411ED6543A05C134E8B
+:105C1000ED289E1FDAB1A86CB266798221C523F502
+:105C200072367DC70688EF26427E884EDC2F80FEC6
+:105C3000117EF27EC0F7BE28C57E1468CFAFBB01CF
+:105C4000E0D95BAA71A07CDECBBA76BF447933D9A8
+:105C500041E20DEC20CA3D5D0F9A19CA195A8D23F5
+:105C6000C688F132A018E814E7D7DD4B83984EC1FF
+:105C700027EEA90D53E5231E3C791C8FA18B51EE15
+:105C80001F106F4EDD7FE1B367A0FF2D2BCF8C443B
+:105C90003A8779ECD880E3AE0876186D646767E1DF
+:105CA000986FD4CBF6368AEBA3FB66368C170EE9D9
+:105CB000C6F3E86983F54FCFA0DCB35A6B45BAF859
+:105CC00000F70FE0FD91D8BFF98D9C4FB2960D649F
+:105CD000F72C96F96A5381D37F4E01D06253133962
+:105CE0009D06737B7E77E9E9DD2F41BFDD2B0C0E2E
+:105CF000C1B29DA69C2BC7F7F71FD0DFE95846F627
+:105D000027D08A592DDA253B6CA71623DE3E6CA4DA
+:105D1000387E090E87B950EE6E7AFD24F623D59EA3
+:105D200020FBA0DB64A6B835E6D19F57F627D5BE89
+:105D300046ED58D7E0309413881FDE8C760BA70110
+:105D4000E3A1B14FC49BF9694718F205D622595116
+:105D5000142811E525721CB6CE3D6C061C74B35395
+:105D6000B5B4DEC5A93CCEDDCFCF46733DBECC9BDE
+:105D7000BA55ABB04F3F302C6F74AA928FCD90883C
+:105D80007F01BD9B90BE270C9B3F2E750C951F4637
+:105D9000FE5694E71B5A43FB5AC99CE82F89610EB3
+:105DA000B417E2BE62FFBD4D3A92FB647A50E2AB9B
+:105DB00021BC0F9F01CF9D1A4E074C8BF59062BB03
+:105DC000FF149DCEB371FA91E950A6339C9F269B98
+:105DD000C677EA14FC4DDF94AB41FBB94C4F647FAE
+:105DE000CDC17BA5FCAFA459A27B06252D598645C4
+:105DF0008A7365BE285F80F73914E5CB705FC6E013
+:105E0000BD436F7D0CDA67C47D0FCC27021C9F2831
+:105E100077467898A21FB17F0D41AEAAFDA87FEF0B
+:105E20000EA173B078F5DDB78F417EFAC240C2DFB4
+:105E30002FA7ECA1F8B5F98D73EE7B0FCADDCF0665
+:105E400051F98A547723F2CB2F25DBBCFD28877BC1
+:105E5000EC778C81EF3371B3C99EE16DA2711FCED7
+:105E60001D437179CC664039519EF7FCB4ECD5E8FE
+:105E7000079DDF9C1BC189D45D86FBDB30E74E1D8F
+:105E8000DA1FEF13F35B8C3E7394FBC57909703214
+:105E9000A03DE70BF4A0939D8BDBB5BEFCE5F3675B
+:105EA000F07CFFCB73162B82B33C939FD72CDD9BEA
+:105EB000339DEBA12A7D60D2F31F87225F97E5D93E
+:105EC00025FBB45C7E7570BF03E4497E0D944B8F57
+:105ED000BDF061E855F5807DDC8E712D3D408EABC7
+:105EE0005BF26B2ECFCAFBB144BA4CFAF392575611
+:105EF000455D2D5E0DF54FE407817AC1B5F486400E
+:105F00007DE19954B5BE70BDF17172BEB43623E91E
+:105F1000D351182FE7DE83745B5E9B9384F1E4D545
+:105F2000B5132995E3E74A6B4750BBF2DA5154FEAB
+:105F3000869083988E51DC658DD08F7BBDC903D848
+:105F4000BF187FC94698247CDFABB30D40BB821CD1
+:105F500027CD743D24BF55FC26291CF1ABACE331A1
+:105F60008306CAFF9ECAE5B30B01FA4DF5AE4FC8D2
+:105F7000EE50C53A695F60BF9849A9E76E34D038E2
+:105F8000FDCDAFE279CB52C4DBB276C9B903FAA931
+:105F900030DA1E45F9A5E28DE97A8F621FFF8C7811
+:105FA0001B79E5FCDF4CB5A9CA71BE8CFA69FF0A02
+:105FB000E3CCD8AF42483EBBD8C1EDAF9FEFD26E25
+:105FC0004379ACAC7D4F35D949768558D114F2A5CB
+:105FD0009ECB8B723F9F083AF9245523E8AE9DDA99
+:105FE0009FDB15C21EB6F3F9221FF85252DF1F388D
+:105FF0002BBE3B2BE0E5117426B72F33B71850BFEB
+:10600000B9F0F2F48887705E07FF183A14CA2F8936
+:10601000F55DDC175248F0D8F7F72987503FDB973A
+:106020001F2129F80B4BD3F3F978B91FE64207B7C4
+:106030005F54219C012FCE09BBC3B91706B6F1737B
+:10604000DAAB8A073BB7EFC5504D7ADF3E2E31B54C
+:1060500034E112E57B36417A8F07E5465DC7540F80
+:10606000F276A26B18676D5A8B0BF995DCCE6472D1
+:1060700052BC8E7C1F99C9F18422FE05E487B7DCEF
+:1060800030FF9A320343F9615EA66DD65D780EBE8D
+:10609000A1A7FD60836D1BD08F32EFED810CF9520B
+:1060A0008DDD41F6A279A3387FE9B6F3B8F79EFB00
+:1060B0002D64CFAE6C929813FD6631F13CCEC6AF25
+:1060C0008F39DE5E83768BDF27917DBCD2AB656E28
+:1060D0006C37D6973255615F8E077CC1EF87A7F189
+:1060E000FD3C85F764CC785E1E4911710C128E233D
+:1060F000B73F2FF952283E638F3A3EA0729A2F0580
+:10610000EDFA957B63C9AE7F5EDCB7C1729C7F659B
+:10611000368F03F0B77FE0480AE263E5FCF6342BE4
+:10612000ADCBFA15E915FB2D742F51F39245F8E329
+:1061300082B6E2794CBE43C8978546519C775E1A79
+:10614000D7579EF6D3A72306F9EEA095E650659C97
+:10615000C320A985C733EC50C7399C32F072CF4EAB
+:10616000F53ACEEBA11CCFA71DEA3887F386161EA1
+:10617000E7B0535D5E16DA42EBEAC6380F84D77398
+:10618000DCAFC6CC9D07B0FFF2E783882ECAEB6A6E
+:10619000A7A07EFB65AC77D14128FFF2B9610CE581
+:1061A00056D84F9253CA3C12F1FF7260131827075A
+:1061B0006921C6BB95FF72433CD9635772B9F68417
+:1061C000E509D23F7AB71B25E4E767236D03307FEB
+:1061D000F6B70319C2FDACD4128FF32907490FE5B6
+:1061E00013376B994776E5ED46867EFDF2ED468ADC
+:1061F0004B38BBE3BB614A3B3694ABFCB5F2BCFC0D
+:10620000E7771AA7DBF9024F16A571FDB962D81F0F
+:106210000E20BE77DBF9FEC0FE919EB6694F10E5F9
+:106220002B76476E45BA296F0FEAD6921CA651E924
+:106230007B65C000D14E56C6B83CF3E52E3DC55730
+:106240000025115FAC147CB1403B81EEDB5F6A1F1F
+:106250003500E151AEC9FA31AEBBFCF7C974370065
+:10626000E04FF3C53FD4D7CEEE8CA377178AC2D9BF
+:106270003DD3101EB57FA7788AB3E12D19E157D120
+:10628000ABCA5FB2501C6BF99A1B34644FD7727D56
+:106290001052A7C4EF17E7A03C51B52664A9D2AFAE
+:1062A000526E3E43F11E81F0DB9BC6F9569588FB8A
+:1062B000AAD8C9DFC3A8047AC3B8E88AD5DC2ECE31
+:1062C0007E29D1BDC9E541BED0F1905FBE434BFEF2
+:1062D000800A437B4A24CCFBA934CE37A1BD1BC71F
+:1062E000F57F6F706CA07E7F3F93F6FDA9B4081A0E
+:1062F000EF7CFB6351B8AF81ED9707011F312BDBBA
+:106300006D0B55EEBFDCCEBFAE766EAFB9C43A7F33
+:10631000F2217CF2CDAE209A17F07B8AAB0B5C2F7A
+:10632000CC97F0B2E20523C5959D13F7C33EAFE3CA
+:10633000BCBE62F56D8FD27AFF309DE257177BD5D8
+:10634000DF5FB275E6A01DE1D2BEDB75F8FDD63485
+:106350007EEFAF6ACD78DA67F6B69EBE0BDCB75536
+:10636000A29D9FFE7687F07817D6FE02F6776E77AD
+:106370008806E9AF3B8CE3C7B95C98279E03BBA3B3
+:10638000B3E94E090A538067E5568E67E7C2DAE340
+:10639000AD549F9AA5C22B1FB4447CC46F30AEA3EA
+:1063A00096CB6F15A666B2EB633C484E36A53EE32E
+:1063B00055E246100FD14E10334CF8DF703C8C2361
+:1063C000C1FEE83C6A37A0FFD12DE4CECA5D8171E1
+:1063D0001FBCFECF6992EC5FB045C87128405215D2
+:1063E0001E89FC03158DCBCA90CF542C5D7F17E21C
+:1063F000A53CFF0A1D2B447ED02D69691EDD41405E
+:106400001728AF2AC749E4A935AA6F9DDD62BCCF22
+:10641000D26C346F908B590BF453D9283553FF82CB
+:106420004F50FC91E23B008301CF99EE5C511FB0CD
+:10643000DE6E112FD9B35B6A539E2F81EB1E348C15
+:10644000F3F96EBBEDD109117D7177907FFBE6D139
+:1064500094A77B6B0DB87937D267840767E7F07331
+:1064600002CEF92C841B6A48FE780C2DBD1BA38B31
+:10647000CDE6FA19C6B7A37E8629EA673623D7CFB9
+:10648000308FFA19A6A89F6139EA679847FD0CF387
+:10649000A89F611EF5334C513FC3F271C3389F7CF6
+:1064A000997947E860BC3352E7EA5889FCD2DCFFAF
+:1064B0007CD64CFCCFEF9F3EAB51FBA7CF6A02FDD1
+:1064C000D3214AFFF4B5E2B01222DDA9C322699FAD
+:1064D00055FDBD9CE81D81FAEE1B6956B19FEDA4E8
+:1064E000FFA76C36A8E09EB65D9D1FBE4B9D4FDF9B
+:1064F000A7CE6774A8F38E63EAFC5748EB385E7644
+:106500009019E379BA567DBE1AD5A96F22DCE9C38A
+:10651000283EBB67278FBBF6117FE9AA87FDE5FB05
+:10652000CDED6ED01BE2AF1CCF7BCDF774AEF98EF4
+:106530008E1A1FE478A42DFA9E58E4939F3C676A54
+:10654000C6797E22ECA56CB689E4AB1AFF79C4F556
+:10655000AA9A75D2563C876F1D164EDFF79E48A645
+:10656000F3A93FFD62C1E551249FFBF3CD9286E282
+:10657000A463A2E8BC93E5B77809E437E47BB07E76
+:10658000940B53376A54F31FE60D56C177C4B3E139
+:10659000AAFCC8F641AAF699071355F559BEE1EAD7
+:1065A00078AE19F587F97D08310F21AF4E6F1EA522
+:1065B000FAAEC4355EF5DDF29526C2AFE5EF69C9E6
+:1065C000AE5A8A15183F827225ACB314BF457FEED0
+:1065D000761E47C26AD5E77AA98E79AC30F505E216
+:1065E000FC91E3C04BADCC1906FD5CC86AD989EFBC
+:1065F000CA94FDF68F39568CE79372A3D17EF17C55
+:10660000B2FB5EC49B78BD730AF96BF62487D5A3F1
+:10661000DC79E238F9A5653C89D75B83713FDB5AA9
+:10662000B83E80761C6D78DF7EB7B50C0C1E6AEE26
+:106630005B77DFFEA693FC7CE98416D501569A2B86
+:10664000790C997DF3AF11E7853CDF4F85DEC0867D
+:10665000F27EEE15F595D9AF3F1D0E5B775E73E4C4
+:106660002F6B607EE7B2DA537C90966F6A8BBA1319
+:10667000F509A37B1DAEA3E6ADFC50F4277EBB4B12
+:106680004FF7AA3E6BDDF634C679AC69D96640BBDC
+:1066900041B9CE6B203FF7736D068CF3F8D1B36D23
+:1066A00054BEE8D962D233BFD02F35907CFA94C45F
+:1066B000F6DBFBD65F9A276DB6C2BC2F0A3E5A1A8C
+:1066C000CCDCED64679E703C02CFDB67258A77984F
+:1066D0003923571F89F2FBAE30BACFF98C681F8877
+:1066E000F7BD6F6AB95D6C06DFEFFEEE994EBF6CC9
+:1066F000273C9F717904E95F337DC3B8BE9BAED65A
+:10670000774B0DB6B791AFB3DF69493EF5DB1D1C82
+:106710007A9287319E11E3275D13B42ABC5B32293C
+:10672000448597B359B82AFEF20E3648959F519486
+:10673000A46A3F6BC688007E90DD574FFC609C2AA0
+:106740000E130650D14515B6A0B8BC3C553B2CE7FE
+:10675000F19DB7AAFA5BFED6A8681EAF38ADAF3D73
+:10676000CABFDBB97FA36A5FD856D4BF4BC5FDFC57
+:10677000D96E5E5E7D90973316ECBFDF3040CBED77
+:1067800009CAFB194CF8ED707C846B95B03355A5A4
+:1067900071FB52427EA7C144F2B944F762AB5B245D
+:1067A0008233C05737309CE75764D3F7A681D97D31
+:1067B0007852BD4F7D7F12FB47BF72F5096D31D214
+:1067C00043603D9C53AB07E1BC8BA42CD43B176FBB
+:1067D0000CF44B37935FB01AED468AFDC9447F0B2A
+:1067E000E29BF0E7CCC60AD8B2CAF63DAF617F3370
+:1067F0005D1C2F03F147D60B1631C023F42B01BDCE
+:106800007A6DFDC303EF76A1BE21C3A5DAC9F12DD0
+:1068100010BF0621FE613C2C03B841BF8BF7490E27
+:106820007C670ADB239C0621FE05C085E018000F6B
+:10683000194E32DCD858F5FCAF841F5F077CC7AE19
+:1068400006BFC075F5074F79BDD32E73FB87BCDE3D
+:10685000456E8E078B603DE817BD03DF731985F821
+:10686000C1F9470FF08FBDB84E1787D38C22359DE5
+:10687000F9F1C5C5F15CC6979997A3A89F7F1F5FE3
+:10688000BAC84E7BBD7822DBF565BE8BF6C462F2DA
+:10689000473F74D5773B02ED91370E17F6C8316C40
+:1068A0008C2A1EA49F7B4281F120F2391D784E1460
+:1068B000FF969F13FE7344F0FF9A956944F7321FC9
+:1068C000758B72B7B0D3C9E31443DEA6C8AF6E4C64
+:1068D0008AEF52C811EE55FA28EC27BE7E20A5C5D6
+:1068E00041568A7B2AAEE7F128A7D746478D85FD1A
+:1068F0003BBD8AC7A39CBE7F743CC6959C5E554039
+:10690000E927EB8DB3E95DA1074D0CE3C1AB0E4464
+:10691000F3FBD95A73D46CB4BBED1D48F72B170E9B
+:10692000E7726BE5AAFDA1184655B18A9FBB3F4EA1
+:1069300076170F27FB7BDB4E32785BDB3290EF2B39
+:10694000ECB3CBB1BE0AEDB39077D727539CDC17DD
+:106950003846369E4FFC9CFF22C87A078EF7C573D7
+:106960007ABA270BF54EF493DC2BF9CEDC4CF7E822
+:10697000A428B43B9D7F4F4BF6AF32EDE10C1CAF2A
+:10698000B2EE603C9A0E4AB3E1FC043C986484F990
+:10699000A0FD61D5B678722636B5D1BB8681F6608A
+:1069A000197E1F0A3FFA4E714EA3BC8F29CAFB2CD9
+:1069B00095CBFB9847791F5394F7B17CC946B5BC7A
+:1069C00026DB8313B45F67D5A4F7F98598B5EB1878
+:1069D000F9851F33DA50EF18AC13EF99097F91EC6A
+:1069E0009F91FD46C58F2D66F8E24D711C7348BC22
+:1069F0003DF99102FD47C5785710DB3DA2A3F7F1A1
+:106A0000E82F87FB5771DDB2DF09BF0FCD56F86164
+:106A100085FF47CFACF1783F3121DFFA9393DC8FCC
+:106A20004DFA53511ED747E5757508FFBF9CA6A0C8
+:106A3000FD18FD3B1A470CF2E1298DC3C87EECC955
+:106A400063694B497E30A7619CF27229D881F2EFCD
+:106A500072DC67CC7F1CC4FDA0DE58151D04BE5F30
+:106A600073530FC8880ABABCF9B2899528E83F97D2
+:106A700085A9F2F9A65855FB02AB5D55FFA39861B5
+:106A8000AAFA5B6C59AAFC6D6937AADADFEEC85521
+:106A9000E57F3CF61655FBA9CEA9AAFCF4C239AA9B
+:106AA000F6335DC5AAFA59B3CB54F573DCCB54F970
+:106AB000BB4AEF57B5BF7B69BDAAFEA7A08F229C3A
+:106AC0003B501F35E23D4E13A5DF69AC3A46F24319
+:106AD000B219E96942BE66E9D5E23EDE15747B79FA
+:106AE00084736DFA187EAF16E96E88FCCE1E03A97A
+:106AF00093F4F2CE58A4930921472ED9606FC63D76
+:106B0000DF3853077C6FC20D474625417EF9F38776
+:106B100066EA80AF4E187FE4C544C8FF6CC4B73C3A
+:106B20009F79E412D69F7BDEC7DB4F672422AD1925
+:106B3000B16CA607E7757362B383DB69C4FD211FDF
+:106B4000E1A93FEED064F62529E27B707D25C97866
+:106B5000FFCD4AE911A03F4C8F01FD9500BF7D0D8F
+:106B6000E80FD313A06F63F9EF40DFC6F44DD0B741
+:106B700031FD3DE8DB987682BE8DE91FEA6653FA67
+:106B80006E9D9BBEFB535D29A527EB9652F90775B9
+:106B9000B5947E54E7A1728433E6BF1F2EEC310713
+:106BA000F5E795EFE7C8FE70D9FFCD5E7598309E8A
+:106BB0008075E9C2CE98FAFCDAFDE979681039A34C
+:106BC000900BA399D33882FC2583AD74FE88F2E440
+:106BD00044B77904D0DB7BF6E9C9A3203FEB7BF710
+:106BE0002A24F9F734DC0E1FD8EF69B1CF9D239C1E
+:106BF00061D89FFF7D46C18736EB39DF91F90CFDE7
+:106C000029F885CC576E32F17B350A7E43FC42C1B0
+:106C100087888F147CC388AE2736E9C87F68D13156
+:106C20001FFA97657E0300C9C77B63FACB8CECDC47
+:106C3000F89EA2219BDA39B5906EFF2BB4CF50F0AD
+:106C40003F23F3D07B8E822F423B1ABFE01B37F1EC
+:106C5000C389C2FF3EC400072E6F47710116D4DB03
+:106C6000F0FB815D4771BCB8BF830C00ED405CA1B7
+:106C7000F814990F62FB10DEDE87FD0EFD1B8C1FE2
+:106C80008A70B3F177E3723BED681FDA7C9FC981AC
+:106C9000F63DF95D4A327A019CA60B7E45411C986F
+:106CA00017E73C7B369AEC5779A27E73A23B1FF71D
+:106CB000CD65B47E1C4274953404E598A9427EFFEC
+:106CC00017FB56F87F61DF2662C708EF0846FCFA1B
+:106CD000FFEABE8DD6F1770D8C95268AB7BAD63EDF
+:106CE000DED3C3260F80267727B94FA37C507CD9EB
+:106CF000F61AE64B745906DC3AB97E11D68FB9B252
+:106D0000DEFD4D8F7E8062BF6F123C7A4D3FEDE518
+:106D100076F27BC772FFDBFB197F79018FDF2D7C59
+:106D20008FDBF9DFF0BF07E03467C17EE733DE4F6A
+:106D30007EFA6292DF9999CBC536F807F9D2CD97E2
+:106D4000752A39B99089B81DE6D521FE1506F8E3F4
+:106D50006F1572F4AD017274A05CBC79848893B62F
+:106D600033FBBFF98ECD56C46759EEC23838C4DF45
+:106D7000249BD63421BBEFDD1AF9FDA349827E0A9C
+:106D8000989BCEB51F310FA5B7C0FC313D86EF1FD4
+:106D900065607CA78FCEC3DB81E162F98F5194815E
+:106DA000FCD190297331863A7F54FE502C57BCCBCE
+:106DB000B01FE751AD75FFB755F12EC3914936F2BB
+:106DC0009F1E31F17B1B485FFAF0BE751C85736016
+:106DD000289C03C7E13C1A0AEB791DCE23CCFF1691
+:106DE000CE234CE576936DEA38B25BD3F87B8BB754
+:106DF00059F34121EA1F4EB765FC7A30C2F18DB0DC
+:106E0000D44968977F23EC8649B8BE37C2A2353C87
+:106E1000351AFED53D6019DF6F4BE7F7076EB34EAD
+:106E2000A6F1AA4242C5FB2D1F87C6005EF49A8ECA
+:106E30006668213D8B1344BD28C00EF5791D4BC7F4
+:106E4000F54DAC1D4FDFDF5C7B23A595263E7FB65D
+:106E50003D5AA38CE7DD667077217FFB7CB396F00B
+:106E6000F5C2DE204711F4F385F7C5505C0FC8FB6F
+:106E70009F22BC2BB5B66607DA6FDEE071ADECFB86
+:106E8000A3F1182FE37FD768FB74553CB88C0F959E
+:106E900026BE0E59AFFA499293E88B89F758E4B8A9
+:106EA00099C1467E1F4D7E1F04E5088A030F38AF47
+:106EB0007382393F196CE47CD4CF270C3CCFDC2F94
+:106EC000D2FB6BDBAACD0E3CA786C538FF8AF397B1
+:106ED000EDB8BD8343E89EE844DF08F2A716A21D83
+:106EE00001A67A44C4D9FD68C4527322E0D51D2995
+:106EF0006E6D3ADD43F85E8B7CE9CD64890D94D0EC
+:106F0000EE3BCA4C7AE435E82690EE42D205DD65C8
+:106F1000B08C1FF83B5814D7D3FBAED6C1F5491E31
+:106F20003F20CBD11359CA06B40FE49FD06304436A
+:106F30005F9C5A0CF72FCA74597082C713196334B7
+:106F4000CCA6E01741B66066538E9F16AECA5B1C96
+:106F50008354ED078C4D54D5873987ABEA07166605
+:106F6000ABF291AE71AAF6D1B3F354F958F7ADAACA
+:106F7000F671A5D354F9214BEF54B54FA89DAFAA94
+:106F8000B77BCA55F5A0D1D03E1CB74A6C935DF1D2
+:106F9000BE8AC7D99916C5F923FE2535D5A8BE2BBB
+:106FA000342FA2F7C5925B1E50F5CF6CDC3EE18119
+:106FB0007F10AFBEC58B099016C4A8ED16F9D6DCBC
+:106FC00063B82571220E8A31870DF96FBE556DC7E2
+:106FD000883317525C7BDC35E2A48AFE5D3C700F7F
+:106FE000BF3A1E54F2F33C100FD07FA05C27FA0F7B
+:106FF00094F040FF81328FFE03657BF41F28EBD1B4
+:107000007FA0AC1F75428D07633AD57870C34935B0
+:107010001E1C47FE9FD4FF7EDDD8A5C61379BFC6D0
+:107020007F31EDAAFB351BFEA1F391F1F37512C080
+:10703000CDC7AEDC3779BFE4FDFB9FEE5B43C0BE3E
+:107040007DCB9AC764D1FB86702E69FB3F370B4D11
+:1070500057D7D364BE15A8AF05EACF72FCEF95EF02
+:10706000BE7659F05CFC4ED33512BF8F653DC7F13B
+:107070001EF24B51EE2771BC688C1680FA4D657775
+:10708000D0BBD51787F49CC277BB3DF75B38FF4E6A
+:10709000E7FDCD6BE0EF48C8F39E17C7E38FB6A6B8
+:1070A0000BFFB3A36B0CFA2377A473B9D6E2B052EB
+:1070B0005C7B713A13F1BB2C7EDE48057F5DA1231A
+:1070C000FE3ACFE4FE653ADE4F10EF88CB71EED783
+:1070D000F1EEECAFF03BFFBB1765EA774436F9DF22
+:1070E00011F105A562FDE31AD5FB2C9B2A6DFEF775
+:1070F00059C8CEB992BFE39ABA91A9CE75FFBB2207
+:10710000CB6C743F6D98D7A48A0FC7F766D0AF3D9C
+:10711000E259ABAA7C647B8CAA9F4DE25D9CCC8338
+:107120003655BB4DE2FD912C5F9AAAFDA8130EF5D2
+:10713000F7E25D92319D6355DF77C9EFD994F1F79E
+:1071400035500F40B9FE86934E55BB848A9A292844
+:10715000570C11F2F58D5D85AAFE132E066B304E8D
+:10716000FBAB741E4F3EFE0B97AA9E741EC4839FFA
+:1071700046111EC87A8A426F213DC5C0F87BE006E1
+:10718000D03310FFE478E8403B96DF4E65EAB38BDE
+:1071900029E394653DC31FAFAC736A107FE5786542
+:1071A0003F1EE0FBEF3CDE80E0F0F40351AAF7491C
+:1071B000BE15F8F8550AE3F7F24DDCCE85F153F829
+:1071C0004E31D375C5E2BB43DFA77339E497439DC6
+:1071D0007F4BA7F6DC1FFEB4A1E77D3C47E765F2D5
+:1071E00071E66A34F74C4DE7F1647B157A9D7124A2
+:1071F000FFFEAD0C9ECE1B20EEA7FF8CDF7397D752
+:107200001163608DF47E83AE6B18E2F7DDCDEDEB9C
+:10721000D0B436D7D0A2E771D85E3DD277511EC820
+:10722000B9598CD5FF32E171732CBE8FAE23FB4A66
+:10723000E8EECD778084ECBFBF9300FF8DFB8036F6
+:107240005ED4ABDC19DAABDABDE57B29B6657AD75B
+:107250005633DD6F2944FD4DAE5F9EC1E1E41DAAAA
+:1072600021BFA8FCFB017EFBF3485E3F55ACB34059
+:10727000FB7D31AE6FA1C540F7A0263A5D4FA0DD82
+:107280007B7EAB9EB5A18DC703FA4B14C5AFD05F13
+:10729000B18DEB256EC1B7318F7E93628F9ACF2E61
+:1072A000C6DFEF90886F135D2F301BBCF8D6E682E7
+:1072B0002675BB858CF7B7D8CCDFEF5C18785F51AB
+:1072C000E8398BAFA1E7FC74A4E0D7992CF307C58C
+:1072D000BBA3BDA0078BB87FFE6E52AD81CE511906
+:1072E000EF15784DFAF57F2AAE9F89737EA880A3AB
+:1072F0004C67323EC9F423E313EE2FEE9FBCBF78F8
+:107300007FA8DBDCB7BFFF5BF788FC70BB861DBCCA
+:107310003FBB77205FA13F853DA43F7BB7CC67FC97
+:107320007C8401FF48EA8397ECBF2F153812286749
+:10733000F57A9328FE1AEF3169F93C299E4B3EB746
+:107340006DE8B751F815807E82F17D7B4FA38EEEFC
+:10735000ED07C257A69FFEE20BCE637C01F25AD91D
+:107360003F24EACF7B2E7553FDBE207AB7ED4256FF
+:107370006706FA3D64BF51A01FAA77858961DC5A70
+:10738000EF3E0BF9E5D14F3300DF27AADF9681FEF0
+:107390001B793EEE2EB5DF2930FD71B27BCBC831B3
+:1073A000E8BFD1DF417172668D15FDCF6BCD47E827
+:1073B000DE3DE8FBDE91917DFA5D119C73B86FC0F4
+:1073C000970A71BF653F4BE07AFC743681DF43E872
+:1073D000F5F0B8F3DE4289E6FB1E7391BC522459E6
+:1073E00049CF57E2E7BFE3AF997E398BF667C6E531
+:1073F000F1B44E77D38D944F49F068303E99DD2536
+:10740000917D7AD676B62AD8867146B3C6A0BEF6E6
+:10741000E6482ED7A488F325102EC9829E766A24CA
+:10742000F23FEE7C88C7CF8DD8E5D4E0BB38B3F708
+:1074300059C53BD84BB3513EB82BA07D8A8E9DD009
+:10744000670B3C86F6CFDC60DF4A71CC197CDCFA36
+:10745000E15681275D3A97426EAAA997882FD548B1
+:107460004C8E3722BE24E72FB5887C01CF2F5FC515
+:10747000F35DE2BDCB9DC2BE81F0C314E18776808F
+:107480005DC2BE81F0C314E187E548DF9847FAC6C4
+:107490003CD237E691BE3145FAC6F2F9CC158F0ED3
+:1074A00043F4E34C52F069F4E34C52F05BF4E3280C
+:1074B000F3E8C751B6473F8EB21EFD38CA7AF4E3EF
+:1074C00028F3E8C751B6473F8E32CFC6DED2974782
+:1074D000BFA073AA2A3F1DF484498AF301FD38CA6C
+:1074E000FED18FA3EACFBD4CF5FD5DAC56F57DD244
+:1074F000D27A55FB7B6A25959FA784F5103E2FD83D
+:107500003890F07075A22B2803F6FB9E593DF4EEDF
+:107510006881B6A30CF1A1A62AD8C1F7B9A590EF4E
+:10752000BB86E268B7E86DD1F44EDE5B5AC6F799C8
+:10753000C7F106E227FA3326E9B95F0553F4AB60D9
+:107540008A7E154CD1AF82EF0CA25F0553F4AB607D
+:1075500039FA553045BF0AA6E857C114FD2A98A24A
+:107560005F0553F4ABE077E857C114FD2A588E7ECF
+:10757000154CD1AF82E5A7D0AF02F9128CB9847552
+:107580008E6CF11C479BD494CDA78E619A32A07863
+:10759000AF04A83EEA85C859E8474A0929CE0E73C8
+:1075A000009F96E2664D82BC5BC4C765B01E92FF29
+:1075B000C85F0EEB77FB18C9EB23FF1A4BF57DF480
+:1075C000C2E969E4312BC9A9F5427F92BFCF425786
+:1075D0004D525FFBBEFCD5DB058E2FB7233EA69830
+:1075E000877C2F39E1751B9D4F400774CF4CFEFD02
+:1075F0001BB72797DEE52D3270B90AF8C238D49749
+:10760000467824E756C5FE1509F971C42E668841EF
+:10761000BEB065DE68FA2ED8FFDDDFCE627CC158D1
+:107620003BBD6B38611773B6C1F73333B89F7642F1
+:107630004FFB11E46BC58D53E93BB9DFE2CDF1742B
+:10764000DFB2982D7D007FA7858D9628BE0AF8D0E1
+:1076500031E443F2BAE4F6202E9F40BBE8F5DE6B3E
+:10766000B969745801C68FB10E46EFE8DC3EFA1DC9
+:10767000D5BA695B72A85FE2FFA91E89DE679BE24B
+:10768000A97F08D5C7DB3DCB8E63BC997B3B73D804
+:107690006DC4BA29FE5F9EDF70E71E0D1C1FA08E11
+:1076A000766AF037844055393A50B1BF80E1337083
+:1076B0003FB21C7AF23B4DD559F5748F3FE05C0C1C
+:1076C0008CC7088CEBAB5979B91BE32C6BF6F373C1
+:1076D00056960F8A459CD7A5463DC54B14EF37D229
+:1076E000BB67EE8D12D1B11CAF7141F366D42CF89B
+:1076F000AE2AC91BAFC1B8F0416D19E15A3A47D75C
+:1077000064C03CCF37F2388AEEC617E99EDDA5C6C5
+:1077100099F46EBD6CEF2F11F02911F13A15CCFAE6
+:10772000278C7794DF7597E39B580B9787653B47CA
+:10773000F15B3C0E24504E2E6BD4539C4D59807CF3
+:107740005C21E4E38A6BC8C74F6588F8180773FCAF
+:107750009B7E806D190AB980C9EFFE8AF7EC8BDF3A
+:107760003A3A93CEFBA5C91A3CEF6539616E3D9755
+:1077700003D81E46BFDB33B73E9FCED3B9FB9DF483
+:107780006EC2DBE2FC9F76398EE0FE4771DECFC42D
+:10779000B842807F51571095DF713996D259977949
+:1077A0009C21DEF940FCE8FA35A3B8895E8F91CBC5
+:1077B0001F1D4CC42DAAF1338B590B10DF873BA53D
+:1077C000A3285EDD8EF203F4371BE5898188EFC5BF
+:1077D000AB2211DFBD8CE4BC407C2FD22F3D8EF557
+:1077E000453B18F975647C777BEC05B8BE2985129A
+:1077F000439631DBFD8E0EE91CF88015BF730BBD7F
+:107800004EC6EB403A981722F45D33B7B7F8F560EF
+:107810009C243E92E8593E0BE5B27968431BC411A3
+:107820000BE3B52CE9BCFEEC0BCB67350EFDDFBFDF
+:10783000D72FDFE7EFD3B3B95E8FFAB58BE2493EBE
+:107840002A8826F9262C5B69EF3C2DE87683232FC6
+:107850002313BEAB599B1CFDAFEE6F2E807D43BA48
+:107860009C37A0EB3EFC85025D26734E1A8BBF9FB2
+:10787000C1E447257D18B777A7C86B331FFB735347
+:107880003AC199D7673E380BE319D6AEF87900FFB5
+:10789000733971BF42D29DE4F7E94F8F7F2FCA79C8
+:1078A0004326B45F902EFFCE288FBF3FBDF6F3E78F
+:1078B00095760AD9CEC5580FC9F94F4C8BC912EF2E
+:1078C000AF103D6C2A1F4C760D7BA6C61FB7F49FE8
+:1078D000B8A7B0D2E68ACB247EDA6222FD28ADE7D3
+:1078E000C91D30FEBC3AFEAE9EAC476D290FA67591
+:1078F0006C79C0407C50D6A7E61A3A8FD3EF346536
+:10790000F2761FD6FE5C8FE704EC2BAD636E397FF9
+:107910004F7383C39586E384A43BE89D0B77BA57E6
+:10792000C2DFBF1C64E5F85F94D893A521BB9C79A6
+:107930008CEA7709B5EC18DA45E726CAF7BBF8BD3B
+:1079400075996FCAEDFE92C9F9C95FC53CEE6C919D
+:10795000EFB3B7AD8A423B455316FDD4DF06877BB4
+:107960001CCE634187FD35FC7D89EA83FC5DF3799C
+:10797000D1E2FE36EB8957BEDF3745F4FB1D466585
+:10798000D33D05711F40DC379F1361A57D033C6F1C
+:10799000443D718AD82FD9BED5A7F7EAC8AE60A8F2
+:1079A00035D0BB8EA8AF1AB215F630C6F55F19DE1A
+:1079B000B21EDB07672B7F77C562B0217C8ACD2999
+:1079C00093915E8A5BA470E49305DAA2D7488E5C3B
+:1079D0006F4F4439D29329A9E2B7178AF3B0E6F181
+:1079E0002403FE9E42CD5A90C2906F85DBA89F9ED5
+:1079F0007592752BE2B3B047CBEB2FD97823D153D7
+:107A00008917D2ABBC3724A71FAD3F147923E2AF4F
+:107A1000CF49F19C2556602B0ABBC302B11F81F9E7
+:107A2000A599DC7E3517C45784D7DDF7DA0DF3D17D
+:107A3000EE06E208C6D779326DAA7BCCD08EE2186A
+:107A400014EFD058D10E8CE3652BFA9F1FF0BB7B4F
+:107A500045895C9E7A20D342FDCD6F0933E0BBC0DF
+:107A6000C5562BCDF30A3808F82FF079F50E9C0F88
+:107A7000C64F40FE4EAB579F4D78689B8C7CBCA494
+:107A800099BFABEB6EE6E3B99BC20C23B17DB07539
+:107A900032D9A95749169C5F51B8D340EFC8ACB74B
+:107AA000AB7E672B104EC562DE2530BF85AAF2F58E
+:107AB0007AA49739E2BC98DF984BF7CF4B747CDD02
+:107AC000CF093C750BB87EB62CE861B4AFCF0D6F13
+:107AD00029B81FE970515818C65BFE2293CB8DCF91
+:107AE000093A91E132C7DA42EBF2C3F571800374CF
+:107AF000B9D0EAA2FEE78ADF6D2D691574D55A6CFC
+:107B00004837E33BB96EC3601ADF42FDCDD9C8E701
+:107B1000D9373E7F1F68EE267EFFE3CCE3B3E269F0
+:107B20001DAD1BF48CD6F10EC3DF014738223ECACF
+:107B30007821DF77F6EB379966EABF43CCDF6F3FFA
+:107B40000E7897A3A4B998DEF15810C3E85D29997F
+:107B5000BE647A93E92CD04E3447D889F4CDDD65E4
+:107B6000C8BF647E00E7EAD2BD57396F32049DDF9B
+:107B700029F603E0437C4AAEFF4CD09FCCB7FCE72C
+:107B8000F600DEEF3B62BFE6E6F992F1BD27B9BD34
+:107B90003CEEDC70FE1DEE0FCA32EF88F1B07D0DB9
+:107BA000B557DFCF58E0B7B3EC5A1585E7E81E8923
+:107BB000EC5935EB8E0EF929D2FBEE10BA5772AEA6
+:107BC000724735FEFE16D379E395EF8C2E04390704
+:107BD000E97C91383F4B7C57A7F715A9EED3990A5A
+:107BE000BDA1E4B1DD29C83F61FD3EE41B1FED3EB0
+:107BF000F4DE385BDF7928AF677E531BF1CBBB9B8C
+:107C0000C3B2B59C5F3621BFCC107058D0C8F78D79
+:107C1000C1BEA11C28EF6F7123BF0FB7A036C78B61
+:107C20007628BF5C11C03F03F753DE67793FE7F862
+:107C3000CF83F505CAF3C00FBF3EFD807ED7B2B734
+:107C40009DC3AFB759CFED54BBB85DED5CCD4BBF15
+:107C5000BF03DAFD3FB9CDAD4D008000000000004C
+:107C60001F8B080000000000000BDD587B5054E71C
+:107C7000153FF7DEDDBBBBB00BBB2B2C6F585E4A4C
+:107C8000CC02775725B576F4C6A871328E5D4CAB21
+:107C90009028AC550C2A20A4B681D6294B375182A6
+:107CA000934A27181FAD66A1EAB41D93AE91A94E61
+:107CB0004A3A9BD04C92D68E56675A47A7642D1DE0
+:107CC0005F6D6475A6553B69EC39DF772F8B284DC6
+:107CD000FEEA1F65068EDFE3BC7FE77CE77A5D087E
+:107CE000B7644900F7E8670140C31D2FC02C800D21
+:107CF00077E631FA5C742EC0B4C4B94EB7CD08240F
+:107D000029E989F573AFBF313DE001585D14B9F140
+:107D1000761A40BCCDA40C00C03AFCFD920FE06F77
+:107D2000475F35E6E0FEB30D8203D541BA52887F46
+:107D3000009E89F41B8BAC78AFD56B8714DA770380
+:107D4000CCC17D003582FBAB45F80D3813EB5AA44E
+:107D5000C750CFD6364B0A54129FC369AF0098AFB5
+:107D6000888C6F5911D4FB3D09BB46DBD6FE00F071
+:107D70007CD402F52B90BF09F9DF223B455FBE6141
+:107D800036DAF98AC93720A04169916380EBBA2DB0
+:107D90001E5F4F21D3FBA18076CF560426B7A424C3
+:107DA0001626FB720C0016DC9745089A910E88DCAB
+:107DB000BF2289D31F25451E69B53E182F9D9634D5
+:107DC000C56E923D2500419243D486FEAD26BFD3B9
+:107DD000D91A5C7C3F4A34CF0041D1C7F4064DDA52
+:107DE000DA82F77BCABE012ADA6BCC0445427B7388
+:107DF000CD680FEEE7A07FB22F212F0FE549B82FF6
+:107E0000E3BE487A44B1DE8FF6E524477E06988FBC
+:107E10009C2D337D2174514E826EF2A77A0A7FA782
+:107E2000B25BB777B490C77D3C1E26A4CE841FBA40
+:107E30003D508676A0DEBAEF96F7F7A0AAD12E25A0
+:107E40009FE235959FA3850150094F59A00C3CC472
+:107E5000CFC9FE4159EF6217C9CF702B3DA8126AF6
+:107E6000CC22B800D69B81FD2C963CA931B4F356A8
+:107E70006F712AA0DE51018240F6B759448613CDB6
+:107E80008F239D78197DF869A799D19F77DA0166CC
+:107E9000001CEDCC64EB373BDD8C463ACBD87E87BB
+:107EA000E2E4FE41CCB6C286FE26018B3344095B78
+:107EB0000023EDC5CC5F7D7F9993E371B5336613E5
+:107EC00008871D924838FC6BABA5075209A7311BE8
+:107ED000D50BB417C3615435FA78CC3657BFE74E8B
+:107EE000E069C41EB339A91E8C5C0FD8E4F061941C
+:107EF000B3666BB5BC16F7D7B49F330A485FA4BC12
+:107F0000A27D05C5113583E26993ED2427645332C0
+:107F1000C99E9043C9744EA89B64EB4AD94DF12980
+:107F20008C96D8E9BED7C2E23F625DB9248BFCD9FA
+:107F3000EB2089B0555046DAD12E78C9A41C46B240
+:107F40004C846E81E1212AE790BD5D02EB03FABE0D
+:107F5000B12CF0AA82F82A908EFDF302C97D29592E
+:107F6000213BE053D45B053093844AACFE54AAFB1A
+:107F70001BD3793FC03508B83E28C76AE91C325D7B
+:107F800022E0FDE729AFC40FDADACED705B2FBF461
+:107F90000E92FF9104241FF3FE275A377C6404D30A
+:107FA000045C346AB868E87FDA457858BF57627D68
+:107FB000AF01A91BE97E3AC416B8BDEF0917E16607
+:107FC000FD0F17BF162C07C817C04FFD28DFA82EBE
+:107FD000A7BE71B57F86A34B48C4EF62D8B434EC1A
+:107FE000A1FD13BFAF42BD374EA67BC96C44B94A51
+:107FF000F75F2E49637818A4BE85796993797D1857
+:10800000B67605E95ACBC96A08903DFD3BF201F509
+:10801000AD6F0E4D277AB5DF5213C6FD45F6EA4522
+:108020000E94BBE1C70EAF84AC179B2496FF4D7F27
+:10803000281DA07EF0A156C74D9F0D1FB417A33F6A
+:10804000B86747BDFF8824878378D4D479325F42EC
+:10805000D506536098F2B1591C5A3917E56CDADF2E
+:108060009F0FECBE3BC3FE5FFAD865AC0F37E2BF93
+:10807000F97BE7999C4FC453CB6B91BFA9F9780A60
+:10808000C9D9BCFB5C951DF7BF5A1A384DF2AF0B2E
+:10809000FD47EC1480BDFD157EF44315D433B4BF09
+:1080A000C9807DDDF3A0FC3F5670FB9739FD2B6B3B
+:1080B00067B33C2A13713F99369E1458DEF4F59A43
+:1080C00070AA0C28371005D94E799040A63A0B8635
+:1080D00004F170217F27A8FE02769009F757B4FAC1
+:1080E000B89ADA9B4FF5B0F1C89E7CC2FF351B5F92
+:1080F000AF3EB2EAB7D40F03874C32E12460005997
+:1081000041BE754141A53C432382332BA1FFA6927A
+:10811000CCECDFB877D67DEF274098ED5F33C052C7
+:10812000F2BB40BAE96D437AD1106D205C5C6CB54E
+:108130002841963F8EFB8BBDD212DA0F6E15A054EC
+:10814000A0F5715B89954196E1B7C53EDED732084F
+:108150009F75A9EE3DCF521FF89D91F58D64CF1903
+:1081600055C275F36021C39F6E4760F05D56DF9B7B
+:10817000F09D77A37D4D86A84CF9DE34784C76A32C
+:108180009CA6A3E817AE371F7D57A63ED472D25BDC
+:10819000C5F00BBD4075D60CBCCE5A06B9FFCD83D9
+:1081A00097E47513F2B8B6CCB93D4701701C7B7DDE
+:1081B000D56EBCB796F2F3658005BFD851D3856FF5
+:1081C000CA824A3BF30F0CF17CBF8DDEB3B332CDD4
+:1081D0000FCD2F6AF2CACE6E2F62767B8DC284BC21
+:1081E0003BBD4696279DBF79D0C1F8DACD2915D47D
+:1081F000376F5B380D2E44D914B7114B3884F1AC6E
+:108200003307DC5EBC9FBEF9DB8F411119DF5A4991
+:1082100038442798FEBF18A126F210BCD7991F2F0B
+:1082200025BE21ED5D8B362775D3DCA1B6580D44F4
+:1082300043CD563687A86D672D981118BA91240A38
+:10824000290485F8B0887A4FB802955EB43703B038
+:10825000EA3080B91011A8BEC6DEB9328BEC1ECB55
+:108260008B8F00BA6214F6D52CC23EF3188E41EC07
+:108270001DF1C466917DE9EFF1F7E28011BAE9DD05
+:1082800005831F56E07E54D0FCBB2B8609CF4342AA
+:10829000F42724DF6FB27617A23DCD5E8EE79622DB
+:1082A000FF7CD2EF2F92CABDA4D768ED16303E797D
+:1082B00038BF507F95B333AD846B4155A11DE58B1D
+:1082C000C2FBEBA88FEC8C9BC18472435A3CF3B287
+:1082D00097B2F75170A7E19B05F09E470C9A50FFAB
+:1082E0004E3087E99E2C5A54763EF4C15D01698E6A
+:1082F00074733815CF735E1094109A5A77EBF24668
+:108300008ACFC8DDA3168AFF982BF034D9952DC5E6
+:10831000CA77A1A93BEDCAF900C9F39B952E37C7CF
+:10832000B419F1BD90FF13863AEEA638917F613CF7
+:10833000E912C5772C7EF98D13B3899A15C2C7C28D
+:1083400021296AAA20A6C56AAC8CF3DC637906D51C
+:108350005C959003BD7B80EA668BF66EE8F2A6E240
+:108360001FCB741B285FE089A7EC427DA121C9DEE9
+:1083700003747FF83CF9B9D06C8D4A29C467FC7B43
+:10838000CC3C41EF993CC7E547D95306F77058718B
+:1083900085781EE7A742EBC47ED7E9E5FDBF53CB46
+:1083A000971E6FE6FC7DEF1BAFF72DE36BF7698A35
+:1083B000D7057CDFC89E5B4338CF3CA48FEAF41C12
+:1083C000CD3338A7BC5DAC7652DC751CE879D7F5A7
+:1083D000EAF9D5F308DF39F37E6A21CB5FF92E6025
+:1083E000EFEF81D302CB5F0FD5C5FE3B035ECA6BB7
+:1083F000C8B6A490F0FCFF96B7C97D259084B4F26E
+:10840000C1FEF282E44F9A81F4B6D8CBEA1BFBCDD1
+:108410009B149F7A4FAB40F1C19BC217EC37C789C1
+:108420006F1E3DAA6C4E13C3ECFBC4C0F5850E65F0
+:1084300084696E98578093049D77D8B47377177DBD
+:10844000CF84B6E1DC0BC42F70FE8E64767ECDA89F
+:10845000D9DB51CCE6433288C90B72793447D3FC5F
+:108460001D223DC8170C26B37BA1B0182C4D65E723
+:108470006CBEA65A66729A80CBD1ED6A7587E9BB4D
+:10848000C915E2FCF16FC9619A1703A9CF2FA7BEE6
+:108490001018E37DF182D7A1F5FDD81C9A93777E61
+:1084A000DF0684433DDFD9A0E15BCBB7A4E53BDB2E
+:1084B000C3F39D6D15A326CA5BE3227562DEA65148
+:1084C0006F44B9DFFCF393FBCCB8FE95DE1FDF9160
+:1084D000989D7DD56A56521A519748F3CF2F3FE3A6
+:1084E000F352FCB089D92965CEFACA7A7C07FBBC65
+:1084F000E17D1BE8DED73D4A10F58E889A9C67F82F
+:108500005CDD671383C4D7579B14065A17F2F3BE7A
+:108510008D33D95C359EB7D2FBF336D698CBE28348
+:1085200079E3E7AFD898DEC47911CFAB24B03E81B0
+:10853000F9AA798BBDF3F194EAF2043EC6B4B961AD
+:108540004CCBCBF83EE03EDD37C45328AE9FB7EFAF
+:10855000710544DF9CC4799F43CDA2396872DC77F2
+:108560007779BBA7131E6CA29DE6FBA9F2A5E727AE
+:1085700079957C90E68EF13C05390E9343F398FF94
+:10858000AFE979E990D8BB35398F90CB71A1CFFD98
+:1085900005C14BFBF87B1D7B84EA07EBAE8CBE1755
+:1085A00047A87F5526702BA858ABCE044EF53E3613
+:1085B000B97E8576EC6B290FABDF087B9F6F8B5103
+:1085C000BD7EA7537CE0D73888E1FA80A0649A8A00
+:1085D000BF50FD3EEAC3FEBA37235041FC695ABF83
+:1085E000D82F86BD241FF1D418E17D52A0387FAC6E
+:1085F000C5AF1EFBD134AC93A53EFEFF18B06D5243
+:108600005FD2E25DA7DDFFF813ACA7CA44BEEAB5AE
+:10861000EF9EBA6DA64BD4DFEAB61979FCDB17AB37
+:1086200093E4B0FEACCB01F7CD74F247E7ABDFF8D3
+:10863000AF749A0BA7E48FE53A2E276BFD11FDADC1
+:1086400092FD4F919F2362CCA6607C4EFD5BAA21D8
+:10865000FF2E61BCDD84934319FCBBCCC165ACF03B
+:10866000F177AEC7E4AF26BE53DE2BA5F49D039F82
+:108670000EE7921D4B5CFEAFD1FECB25B764DAAF9F
+:1086800087D80101E58ED45ECF23BBEADB3F60FDD6
+:10869000BB5EEFDF9F13A7C9F1D1E396F0F7563A1F
+:1086A000CDBBFFAB78FD0772A96C9D701300000075
+:1086B000000000000000000000000040000000007A
+:1086C000000000000000004000000000000000006A
+:1086D0000000002800000000000000000000001062
+:1086E000000000000000000000000040000000004A
+:1086F000000000000000001000000000000000006A
+:108700000000000800000000000000000000000061
+:108710000000000000000000000000000000000059
+:108720000000000000000000000000000000000049
+:108730000000000000000000000000000000000039
+:108740000000000000000000000000000000000029
+:108750000000000000000000000000000000000019
+:108760000000000000000000000000000000000009
+:1087700000000000000000000000000000000000F9
+:1087800000000000000000000000000000000000E9
+:1087900000000000000000000000000000000000D9
+:1087A00000000000000000000000000000000000C9
+:1087B00000000000000000000000000000000000B9
+:1087C00000000000000000000000000000000000A9
+:1087D0000000000000000000000000000000000099
+:1087E0000000000000000000000000000000000089
+:1087F0000000000000000000000000000000000079
+:108800000000000000000000000000000000000068
+:108810000000000000000000000000000000000058
+:108820000000332000100000000000080000332882
+:1088300000100000000000020000332000100000C3
+:108840000000001080000000000000000000000098
+:108850008000000000000000000000008000000018
+:108860000000000000000000800000000000000088
+:108870000000000000003358000100040000000167
+:1088800000003360000000000000000200003368B8
+:1088900000000000000000080000336C0000000031
+:1088A0000000000200003920000000000000000865
+:1088B00000003AF800400000000000400000393895
+:1088C000008000000000004800003A38004000002E
+:1088D0000000000800003A480040000000000018B6
+:1088E00000003370002800000000002800003C2039
+:1088F000000800000000000100003C21000800000A
+:108900000000000100003C220008000000000001FF
+:1089100000002008001000000000001000002000EF
+:1089200000000000000000088000000000000000BF
+:108930000000000000000000000000000000000037
+:108940000000000000000000000000000000000027
+:108950000000000000000000000000000000000017
+:108960000000000000000000000000000000000007
+:1089700000000000000000000000000000000000F7
+:1089800000000000000000000000000000000000E7
+:1089900000000000000000000000000000000000D7
+:1089A00000000000000000000000000000000000C7
+:1089B00000000000000000000000000000000000B7
+:1089C00000000000000000000000000000000000A7
+:1089D0000000000000000000000000000000000097
+:1089E0000000000000000000800000000000000007
+:1089F00000000000800000000000000000000000F7
+:108A00008000000000000000000000008000000066
+:108A100000000000000000008000000000000000D6
+:108A200000000000800000000000000000000000C6
+:108A30008000000000000000000000008000000036
+:108A400000000000000000008000000000000000A6
+:108A50000000000080000000000000000000000096
+:108A60008000000000000000000000008000000006
+:108A700000000000000000000000000000000000F6
+:108A800000000000000000000000000000000000E6
+:108A900000000000000000000000000000000000D6
+:108AA00000000000000000000000000000000000C6
+:108AB0000000000080000000000000000000000036
+:108AC00080000000000000000000000080000000A6
+:108AD0000000000000000000000000000000000096
+:108AE0000000000080000000000000000000000006
+:108AF0008000000000000000000000008000000076
+:108B00000000000000000000000000000000000065
+:108B10000000000000000000000000000000000055
+:108B20000000000000000000000000000000000045
+:108B30000000000000000000000000000000000035
+:108B40000000000000000000000000000000000025
+:108B50008000000000000000000000000000000095
+:108B60000000000000000000000019C80000000024
+:108B700000000008000020080010000000000010A5
+:108B8000000020000000000000000008800000003D
+:108B90000000000000000000800000000000000055
+:108BA00000000000000000000000000000000000C5
+:108BB00000000000000000000000000000004870FD
+:108BC00000080000000000010000487100080000DB
+:108BD00000000001000048720008000000000001D1
+:108BE0000000404000380000000000388000000015
+:108BF00000000000000000008000000000000000F5
+:108C000000000000800000000000000000000000E4
+:108C10008000000000000000000000008000000054
+:108C200000000000000000008000000000000000C4
+:108C300000000000800000000000000000000000B4
+:108C40008000000000000000000000008000000024
+:108C50000000000000000000800000000000000094
+:108C60000000000080000000000000000000000084
+:108C700000000000000000000000000000000000F4
+:108C800000000000000000000000000000000000E4
+:108C900000000000000000000000000000000000D4
+:108CA0000000000000000000000000008000000044
+:108CB0000000000000000000800000000000000034
+:108CC00000000000000000000000000000000000A4
+:108CD0008000000000000000000000008000000094
+:108CE0000000000000000000800000000000000004
+:108CF00000000000800000000000000000000000F4
+:108D00008000000000000000000000008000000063
+:108D100000000000000000000000400000400000D3
+:108D2000000000400000480000400000000000403B
+:108D30000000482E00400000000000010000480034
+:108D40000040000200000001000048010040000255
+:108D50000000000000003000004000000000004063
+:108D60008000000000000000000000000000300053
+:108D7000000800400000000400003004000800402B
+:108D80000000000400003B800028000000000028D4
+:108D900000003BD0001000000000001000003BDA93
+:108DA00000100000000000010000380000800000FA
+:108DB0000000008000003800000800800000000271
+:108DC00000003900004000000000004000002008C2
+:108DD0000010000000000010000020000000000053
+:108DE0000000000800005198000800000000000189
+:108DF0000000519900080000000000010000519A95
+:108E0000000800000000000100003980001000048C
+:108E100000000004000051A80030001800000010FD
+:108E2000000051B000300018000000028000000077
+:108E300000000000000000008000000000000000B2
+:108E400000000000800000000000000000000000A2
+:108E50008000000000000000000000008000000012
+:108E60000000000000000000800000000000000082
+:108E70000000000080000000000000000000000072
+:108E800000000000000000000000000000000000E2
+:108E900000000000000000000000000000000000D2
+:108EA00000000000000000000000000000000000C2
+:108EB00080000000000000000000000080000000B2
+:108EC00000000000000000000000000000000000A2
+:108ED0000000000080000000000000000000000012
+:108EE0008000000000000000000000008000000082
+:108EF00000000000000000008000000000000000F2
+:108F000000000000800000000000000000000000E1
+:108F1000000023E800800000000000800000000145
+:108F20000000000000000000000020080010000009
+:108F300000000010000020000000000000000008F9
+:108F400000002E70000800000000000100002E71DB
+:108F5000000800000000000100002E720008000060
+:108F600000000001000024E8003800000000003884
+:108F700000002DD000080000000000088000000064
+:108F80000000000000000000800000000000000061
+:108F90000000000080000000000000000000000051
+:108FA00080000000000000000000000080000000C1
+:108FB0000000000000000000800000000000000031
+:108FC00000000000000000000000000000000000A1
+:108FD0000000000000000000000000000000000091
+:108FE0000000000000000000000000000000000081
+:108FF00000000000800000000000000000000000F1
+:1090000080000000000000000000000000000000E0
+:1090100000000000000000008000000000000000D0
+:1090200000000000800000000000000000000000C0
+:109030008000000000000000000000008000000030
+:1090400000000000000000008000000000000000A0
+:1090500000000000000025000040000000000008A3
+:1090600000002508004000000000002080000000F3
+:109070000000000000000000800000000000000070
+:109080000000000080000000000000000000000060
+:1090900080000000000000000000000080000000D0
+:1090A0000000000000000000000030000000000090
+:1090B00000001000000050A10000000000000001AE
+:1090C000000050B80000000000000002000050C87E
+:1090D0000090000800000008800000000000000070
+:1090E00000000000000029600008000000000001EE
+:1090F0000000296100080000000000010000297044
+:1091000000080004000000020000297800080004A4
+:1091100000000004800000000000000000000000CB
+:1091200000002FB0000800000000000400002FB471
+:10913000000800000000000400002FC00000000034
+:109140000000000800002FC8000000000000000818
+:10915000000030000000000000000010000050403F
+:1091600000010001000000010000500000000000AC
+:1091700000000020000008080010000000000004AB
+:109180000000080C0010000000000001000008B7FB
+:109190000000000000000001000008B60000000010
+:1091A000000000010000100000400020000000044A
+:1091B000000010040040002000000004000010081F
+:1091C00000400020000000020000100A00400020C3
+:1091D000000000020000100C004000200000000110
+:1091E0000000100D00400020000000010000100EE3
+:1091F000004000200000000100001010004000208E
+:1092000000000004000010140040002000000004D2
+:109210000000101800400020000000040000101C96
+:109220000040002000000004000030000100008029
+:109230000008000400003004010000800008000461
+:109240000000000A0000000000000000000030687C
+:109250000100008000000001000030690100008072
+:10926000000000010000306C0100008000000002DE
+:109270000000306E0100008000000002000030702D
+:109280000100008000000004000030740100008034
+:1092900000000004000030660100008000000002B1
+:1092A0000000306401000080000000010000306018
+:1092B0000100008000000002000030620100008018
+:1092C0000000000200003050010000800000000497
+:1092D00000003054010000800000000400003058FD
+:1092E00001000080000000040000305C01000080EC
+:1092F000000000040000307C01000080000000013C
+:109300000000307D010000800000000100001C18FA
+:10931000001000000000000400001C3000100000DD
+:109320000000000400001C380010000000000004D1
+:10933000800000000000000000000000800000002D
+:10934000000000000000000080000000000000009D
+:10935000000000008000000000000000000000008D
+:1093600000004C10000800000000000200004C1239
+:10937000000800000000000200004C14000800007B
+:109380000000000200004C1600080000000000026F
+:1093900000004C20000800000000000800004C0005
+:1093A000000800000000000200004C02000800005D
+:1093B0000000000100004C04000800000000000252
+:1093C00000004C30000800000000000800004C4085
+:1093D000000800000000000400004C4400080000E9
+:1093E0000000000100004C500008000000000002D6
+:1093F00000004C54000800000000000200004C5225
+:10940000000800000000000200004C60000800009E
+:10941000000000040000140000080000000000022A
+:109420000000140200080000000000010000140405
+:1094300000080000000000020000141000080000F6
+:1094400000000002000014140008000000000002E8
+:10945000000014160008000000000002000019B807
+:1094600000080000000000080000142000080000B0
+:1094700000000002000014240008000000000002A8
+:10948000000019C8000800000000000800002C10AF
+:10949000000800000000000100002C11000800007E
+:1094A0000000000100002C12000800000000000174
+:1094B00000002C13000800000000000100002C0038
+:1094C000000800000000000200002C02000800005C
+:1094D0000000000100002C04000800000000000251
+:1094E00000002C30000800000000000200002C32B8
+:1094F000000800000000000200002C3400080000FA
+:109500000000000200002C20000800000000000104
+:1095100000002C21000800000000000100002C22A7
+:10952000000800000000000100002C2300080000DB
+:109530000000000100002C240008000000000001D1
+:1095400000002C25000800000000000100002C266F
+:109550000008000000000001000014800008000066
+:10956000000000020000148200080000000000015A
+:1095700000001484000800000000000200001492A3
+:1095800000C00018000000020000149000C0001885
+:10959000000000020000149C00C000180000000839
+:1095A0000000149400C0001800000008000014A778
+:1095B00000C0001800000001000014A400C0001842
+:1095C00000000002000014A600C000180000000106
+:1095D000000016100008000000000008000016201F
+:1095E000000800000000000800001630000800001D
+:1095F00000000008800000000000000000000000E3
+:10960000800000000000000000000000800000005A
+:1096100000000000000000008000000000000000CA
+:1096200000000000800000000000000000000000BA
+:10963000800000000000000000000000800000002A
+:10964000000000000000000080000000000000009A
+:10965000000000008000000000000000000000008A
+:1096600080000000000000000000000080000000FA
+:10967000000000000000000080000000000000006A
+:10968000000000008000000000000000000000005A
+:1096900080000000000000000000000080000000CA
+:1096A000000000000000000080000000000000003A
+:1096B000000000008000000000000000000000002A
+:1096C000800000000000000000000000800000009A
+:1096D000000000000000000080000000000000000A
+:1096E00000000000800000000000000000000000FA
+:1096F000800000000000000000000000800000006A
+:1097000000000000000000008000000000000000D9
+:1097100000000000800000000000000000000000C9
+:109720008000000000000000000000008000000039
+:1097300000000000000000008000000000000000A9
+:109740000000000080000000000000000000000099
+:109750008000000000000000000000008000000009
+:109760000000000000000000800000000000000079
+:109770000000000080000000000000000000000069
+:1097800080000000000000000000000080000000D9
+:109790000000000000000000800000000000000049
+:1097A0000000000080000000000000000000000039
+:1097B00080000000000000000000000080000000A9
+:1097C0000000000000000000800000000000000019
+:1097D0000000000080000000000000000000000009
+:1097E0008000000000000000000000008000000079
+:1097F00000000000000000008000000000000000E9
+:1098000000000000800000000000000000000000D8
+:109810008000000000000000000000008000000048
+:1098200000000000000000008000000000000000B8
+:1098300000000000800000000000000000000000A8
+:109840008000000000000000000000008000000018
+:109850000000000000000000800000000000000088
+:109860000000000080000000000000000000000078
+:1098700080000000000000000000000080000000E8
+:109880000000000000000000800000000000000058
+:109890000000000080000000000000000000000048
+:1098A0008000000000000000000000000000000038
+:1098B0000000000000000000800000000000000028
+:1098C0000000000000000000070C1E000000000067
+:00000001FF
--- zfcpdump-kernel-4.4.orig/firmware/bnx2x/bnx2x-e1h-6.2.9.0.fw.ihex
+++ /dev/null
@@ -1,13192 +0,0 @@
-:1000000000004F48000000680000070C00004FB8D7
-:1000100000001ED4000056C800000094000075A027
-:1000200000009F4C00007638000000CC00011588CD
-:100030000000DC5800011658000000940001F2B8DE
-:100040000000400C0001F350000000A400023360E7
-:100050000000F4240002340800000FFC00032830E4
-:100060000000000400033830020400480000000FC4
-:1000700002040054000000450204005C0000000679
-:100080000204007000000004020400780000000078
-:100090000204007C121700000204008022170000F6
-:1000A00002040084321700000604008800000005E6
-:1000B0000204009C12150000020400A0221500009A
-:1000C000020400A432150000060400A80000000489
-:1000D000020400B802100000020400BC001000007E
-:1000E000020400C010100000020400C42010000030
-:1000F000020400C830100000020400CC40100000D0
-:10010000060400D000000003020400DC0010000020
-:10011000020400E012140000020400E422140000B3
-:10012000020400E832140000020400EC4214000053
-:10013000060400F000000003010401240000000098
-:1001400001040128000000000104012C000000004F
-:100150000104013000000000020401D00000890603
-:1001600002040004000000FF02040008000000FF79
-:100170000204000C000000FF02040010000000FF59
-:10018000020400140000007F02040018000000FFB9
-:100190000204001C000000FF02040020000000FF19
-:1001A000020400240000003E0204002800000000B9
-:1001B0000204002C0000003F020400300000003F59
-:1001C000020400340000003F020400380000003F39
-:1001D0000204003C0000003F020400400000003F19
-:1001E000020400440000003F020404CC00000001AF
-:1001F00002042008000002110204200C000002008A
-:10020000020420100000020402042014000002195D
-:100210000204201C0000FFFF020420200000FFFF5A
-:10022000020420240000FFFF020420280000FFFF3A
-:1002300002042038000000200604203C0000001FBB
-:10024000020420B800000001060420BC0000005F8A
-:100250000204223807FFFFFF0204223C0000003F97
-:100260000204224007FFFFFF020422440000000FA7
-:1002700001042248000000000104224C000000009C
-:10028000010422500000000001042254000000007C
-:1002900001042258000000000104225C000000005C
-:1002A000010422600000000001042264000000003C
-:1002B00001042268000000000104226C000000001C
-:1002C00001042270000000000104227400000000FC
-:1002D00001042278000000000104227C00000000DC
-:1002E0000C042000000003E80A04200000000001C4
-:1002F0000B0420000000000A0605400000000D006D
-:100300000205004400000020020500480000003201
-:10031000020500900215002002050094021500203D
-:1003200002050098000000300205009C0810000043
-:10033000020500A000000033020500A40000003008
-:10034000020500A800000031020500AC0000000218
-:10035000020500B000000005020500B40000000620
-:10036000020500B800000002020500BC0000000207
-:10037000020500C000000000020500C400000005E6
-:10038000020500C800000002020500CC00000002C7
-:10039000020500D000000002020500D400000001A8
-:1003A00002050114000000010205011C000000010B
-:1003B0000205012000000002020502040000000105
-:1003C0000205020C0000004002050210000000407F
-:1003D0000205021C0000002002050220000000139C
-:1003E0000205022400000020060502400000000A69
-:1003F00004050280002000000205005000000007F4
-:10040000020500540000000702050058000000002B
-:100410000205005C00000008020500600000000109
-:100420000605006400000003020500D80000000675
-:1004300002050004000000010205000800000001A0
-:100440000205000C00000001020500100000000180
-:100450000205001400000001020500180000000160
-:100460000205001C00000001020500200000000140
-:100470000205002400000001020500280000000120
-:100480000205002C00000001020500300000000100
-:1004900002050034000000010205003800000001E0
-:1004A0000205003C000000010205004000000001C0
-:1004B000020500E00000000D020500E80000000059
-:1004C000020500F000000000020500F80000000036
-:1004D000020500E40000002D020500EC00000020F1
-:1004E000020500F400000020020500FC00000020CE
-:1004F000020500E00000001D020500E800000010F9
-:10050000020500F000000010020500F800000010D5
-:10051000020500E40000003D020500EC0000003090
-:10052000020500F400000030020500FC000000306D
-:10053000020500E00000004D020500E80000004058
-:10054000020500F000000040020500F80000004035
-:10055000020500E40000006D020500EC00000060F0
-:10056000020500F400000060020500FC00000060CD
-:10057000020500E00000005D020500E800000050F8
-:10058000020500F000000050020500F800000050D5
-:10059000020500E40000007D020500EC0000007090
-:1005A000020500F400000070020500FC000000706D
-:1005B0000406100002000020020600DC000000011A
-:1005C000010600D80000000004060200000302201B
-:1005D000020600DC00000000010600B80000000078
-:1005E000010600C8000000000206016C00000000C7
-:1005F000010600BC00000000010600CC0000000065
-:1006000002060170000000000718040000910000BD
-:10061000081807D800050223071C00002BF700006C
-:10062000071C80002DD10AFE071D00002F461673FF
-:10063000071D800016342245081DB13049DA022515
-:100640000118000000000000011800040000000074
-:1006500001180008000000000118000C0000000054
-:100660000118001000000000011800140000000034
-:1006700002180020000000010218002400000002FF
-:1006800002180028000000030218002C00000000DF
-:1006900002180030000000040218003400000001BD
-:1006A00002180038000000000218003C00000001A1
-:1006B000021800400000000402180044000000007E
-:1006C00002180048000000010218004C000000035E
-:1006D0000218005000000000021800540000000141
-:1006E00002180058000000040218005C000000001E
-:1006F00002180060000000010218006400000003FE
-:1007000002180068000000000218006C00000001E0
-:1007100002180070000000040218007400000000BD
-:1007200002180078000000040218007C000000039A
-:100730000618008000000002021800A400003FFF1D
-:10074000021800A8000003FF0218022400000000A5
-:1007500002180234000000000218024C00000000E1
-:10076000021802E4000000FF061810000000040058
-:10077000021B8BC000000001021B8000000000343F
-:10078000021B804000000018021B80800000000C4B
-:10079000021B80C0000000200C1B83000007A1206A
-:1007A0000A1B8300000001380B1B83000000138824
-:1007B0000A1B8340000000000C1B8340000001F472
-:1007C0000B1B834000000005021B83800007A12053
-:1007D000021B83C0000001F4021B14800000000112
-:1007E0000A1B148000000000061A1000000003B36A
-:1007F000041A1ECC00010227061A1ED000000008B1
-:10080000061A2008000000C8061A20000000000296
-:10081000041AAF4000100228061A3718000000041E
-:10082000061A371000000002061A500000000002ED
-:10083000061A500800000004061A501800000004B0
-:10084000061A502800000004061A50380000000460
-:10085000061A504800000004061A50580000000410
-:10086000061A506800000004061A507800000002C2
-:10087000041A52C000020238061A40500000000656
-:10088000041A40680002023A041A40400004023C84
-:10089000041A800000010240061A800400000003D0
-:1008A000041A801000010241061A8014000000039F
-:1008B000041A802000010242061A8024000000036E
-:1008C000041A803000010243061A8034000000033D
-:1008D000041A804000010244061A8044000000030C
-:1008E000041A805000010245061A805400000003DB
-:1008F000041A806000010246061A806400000003AA
-:10090000041A807000010247061A80740000000378
-:10091000041A808000010248061A80840000000347
-:10092000041A809000010249061A80940000000316
-:10093000041A80A00001024A061A80A400000003E5
-:10094000041A80B00001024B061A80B400000003B4
-:10095000041A80C00001024C061A80C40000000383
-:10096000041A80D00001024D061A80D40000000352
-:10097000041A80E00001024E061A80E40000000321
-:10098000041A80F00001024F061A80F400000003F0
-:10099000041A810000010250061A810400000003BD
-:1009A000041A811000010251061A8114000000038C
-:1009B000041A812000010252061A8124000000035B
-:1009C000041A813000010253061A8134000000032A
-:1009D000041A814000010254061A814400000003F9
-:1009E000041A815000010255061A815400000003C8
-:1009F000041A816000010256061A81640000000397
-:100A0000041A817000010257061A81740000000365
-:100A1000041A818000010258061A81840000000334
-:100A2000041A819000010259061A81940000000303
-:100A3000041A81A00001025A061A81A400000003D2
-:100A4000041A81B00001025B061A81B400000003A1
-:100A5000041A81C00001025C061A81C40000000370
-:100A6000041A81D00001025D061A81D4000000033F
-:100A7000041A81E00001025E061A81E4000000030E
-:100A8000041A81F00001025F061A81F400000003DD
-:100A9000041A820000010260061A820400000003AA
-:100AA000041A821000010261061A82140000000379
-:100AB000041A822000010262061A82240000000348
-:100AC000041A823000010263061A82340000000317
-:100AD000041A824000010264061A824400000003E6
-:100AE000041A825000010265061A825400000003B5
-:100AF000041A826000010266061A82640000000384
-:100B0000041A827000010267061A82740000000352
-:100B1000041A828000010268061A82840000000321
-:100B2000041A829000010269061A829400000003F0
-:100B3000041A82A00001026A061A82A400000003BF
-:100B4000041A82B00001026B061A82B4000000038E
-:100B5000041A82C00001026C061A82C4000000035D
-:100B6000041A82D00001026D061A82D4000000032C
-:100B7000041A82E00001026E061A82E400000003FB
-:100B8000041A82F00001026F061A82F400000003CA
-:100B9000041A830000010270061A83040000000397
-:100BA000041A831000010271061A83140000000366
-:100BB000041A832000010272061A83240000000335
-:100BC000041A833000010273061A83340000000304
-:100BD000041A834000010274061A834400000003D3
-:100BE000041A835000010275061A835400000003A2
-:100BF000041A836000010276061A83640000000371
-:100C0000041A837000010277061A8374000000033F
-:100C1000041A838000010278061A8384000000030E
-:100C2000041A839000010279061A839400000003DD
-:100C3000041A83A00001027A061A83A400000003AC
-:100C4000041A83B00001027B061A83B4000000037B
-:100C5000041A83C00001027C061A83C4000000034A
-:100C6000041A83D00001027D061A83D40000000319
-:100C7000041A83E00001027E061A83E400000003E8
-:100C8000041A83F00001027F061A83F400000003B7
-:100C9000041A840000010280061A84040000000384
-:100CA000041A841000010281061A84140000000353
-:100CB000041A842000010282061A84240000000322
-:100CC000041A843000010283061A843400000003F1
-:100CD000041A844000010284061A844400000003C0
-:100CE000041A845000010285061A8454000000038F
-:100CF000041A846000010286061A8464000000035E
-:100D0000041A847000010287061A8474000000032C
-:100D1000041A848000010288061A848400000003FB
-:100D2000041A849000010289061A849400000003CA
-:100D3000041A84A00001028A061A84A40000000399
-:100D4000041A84B00001028B061A84B40000000368
-:100D5000041A84C00001028C061A84C40000000337
-:100D6000041A84D00001028D061A84D40000000306
-:100D7000041A84E00001028E061A84E400000003D5
-:100D8000041A84F00001028F061A84F400000003A4
-:100D9000041A850000010290061A85040000000371
-:100DA000041A851000010291061A85140000000340
-:100DB000041A852000010292061A8524000000030F
-:100DC000041A853000010293061A853400000003DE
-:100DD000041A854000010294061A854400000003AD
-:100DE000041A855000010295061A8554000000037C
-:100DF000041A856000010296061A8564000000034B
-:100E0000041A857000010297061A85740000000319
-:100E1000041A858000010298061A858400000003E8
-:100E2000041A859000010299061A859400000003B7
-:100E3000041A85A00001029A061A85A40000000386
-:100E4000041A85B00001029B061A85B40000000355
-:100E5000041A85C00001029C061A85C40000000324
-:100E6000041A85D00001029D061A85D400000003F3
-:100E7000041A85E00001029E061A85E400000003C2
-:100E8000041A85F00001029F061A85F40000000391
-:100E9000041A8600000102A0061A8604000000035E
-:100EA000041A8610000102A1061A8614000000032D
-:100EB000041A8620000102A2061A862400000003FC
-:100EC000041A8630000102A3061A863400000003CB
-:100ED000041A8640000102A4061A8644000000039A
-:100EE000041A8650000102A5061A86540000000369
-:100EF000041A8660000102A6061A86640000000338
-:100F0000041A8670000102A7061A86740000000306
-:100F1000041A8680000102A8061A868400000003D5
-:100F2000041A8690000102A9061A869400000003A4
-:100F3000041A86A0000102AA061A86A40000000373
-:100F4000041A86B0000102AB061A86B40000000342
-:100F5000041A86C0000102AC061A86C40000000311
-:100F6000041A86D0000102AD061A86D400000003E0
-:100F7000041A86E0000102AE061A86E400000003AF
-:100F8000041A86F0000102AF061A86F4000000037E
-:100F9000041A8700000102B0061A8704000000034B
-:100FA000041A8710000102B1061A8714000000031A
-:100FB000041A8720000102B2061A872400000003E9
-:100FC000041A8730000102B3061A873400000003B8
-:100FD000041A8740000102B4061A87440000000387
-:100FE000041A8750000102B5061A87540000000356
-:100FF000041A8760000102B6061A87640000000325
-:10100000041A8770000102B7061A877400000003F3
-:10101000041A8780000102B8061A878400000003C2
-:10102000041A8790000102B9061A87940000000391
-:10103000041A87A0000102BA061A87A40000000360
-:10104000041A87B0000102BB061A87B4000000032F
-:10105000041A87C0000102BC061A87C400000003FE
-:10106000041A87D0000102BD061A87D400000003CD
-:10107000041A87E0000102BE061A87E4000000039C
-:10108000041A87F0000102BF061A87F4000000036B
-:10109000041A8800000102C0061A88040000000338
-:1010A000041A8810000102C1061A88140000000307
-:1010B000041A8820000102C2061A882400000003D6
-:1010C000041A8830000102C3061A883400000003A5
-:1010D000041A8840000102C4061A88440000000374
-:1010E000041A8850000102C5061A88540000000343
-:1010F000041A8860000102C6061A88640000000312
-:10110000041A8870000102C7061A887400000003E0
-:10111000041A8880000102C8061A888400000003AF
-:10112000041A8890000102C9061A8894000000037E
-:10113000041A88A0000102CA061A88A4000000034D
-:10114000041A88B0000102CB061A88B4000000031C
-:10115000041A88C0000102CC061A88C400000003EB
-:10116000041A88D0000102CD061A88D400000003BA
-:10117000041A88E0000102CE061A88E40000000389
-:10118000041A88F0000102CF061A88F40000000358
-:10119000041A8900000102D0061A89040000000325
-:1011A000041A8910000102D1061A891400000003F4
-:1011B000041A8920000102D2061A892400000003C3
-:1011C000041A8930000102D3061A89340000000392
-:1011D000041A8940000102D4061A89440000000361
-:1011E000041A8950000102D5061A89540000000330
-:1011F000041A8960000102D6061A896400000003FF
-:10120000041A8970000102D7061A897400000003CD
-:10121000041A8980000102D8061A8984000000039C
-:10122000041A8990000102D9061A8994000000036B
-:10123000041A89A0000102DA061A89A4000000033A
-:10124000041A89B0000102DB061A89B40000000309
-:10125000041A89C0000102DC061A89C400000003D8
-:10126000041A89D0000102DD061A89D400000003A7
-:10127000041A89E0000102DE061A89E40000000376
-:10128000041A89F0000102DF061A89F40000000345
-:10129000041A8A00000102E0061A8A040000000312
-:1012A000041A8A10000102E1061A8A1400000003E1
-:1012B000041A8A20000102E2061A8A2400000003B0
-:1012C000041A8A30000102E3061A8A34000000037F
-:1012D000041A8A40000102E4061A8A44000000034E
-:1012E000041A8A50000102E5061A8A54000000031D
-:1012F000041A8A60000102E6061A8A6400000003EC
-:10130000041A8A70000102E7061A8A7400000003BA
-:10131000041A8A80000102E8061A8A840000000389
-:10132000041A8A90000102E9061A8A940000000358
-:10133000041A8AA0000102EA061A8AA40000000327
-:10134000041A8AB0000102EB061A8AB400000003F6
-:10135000041A8AC0000102EC061A8AC400000003C5
-:10136000041A8AD0000102ED061A8AD40000000394
-:10137000041A8AE0000102EE061A8AE40000000363
-:10138000041A8AF0000102EF061A8AF40000000332
-:10139000041A8B00000102F0061A8B0400000003FF
-:1013A000041A8B10000102F1061A8B1400000003CE
-:1013B000041A8B20000102F2061A8B24000000039D
-:1013C000041A8B30000102F3061A8B34000000036C
-:1013D000041A8B40000102F4061A8B44000000033B
-:1013E000041A8B50000102F5061A8B54000000030A
-:1013F000041A8B60000102F6061A8B6400000003D9
-:10140000041A8B70000102F7061A8B7400000003A7
-:10141000041A8B80000102F8061A8B840000000376
-:10142000041A8B90000102F9061A8B940000000345
-:10143000041A8BA0000102FA061A8BA40000000314
-:10144000041A8BB0000102FB061A8BB400000003E3
-:10145000041A8BC0000102FC061A8BC400000003B2
-:10146000041A8BD0000102FD061A8BD40000000381
-:10147000041A8BE0000102FE061A8BE40000000350
-:10148000041A8BF0000102FF061A8BF4000000031F
-:10149000041A8C0000010300061A8C0400000003EB
-:1014A000041A8C1000010301061A8C1400000003BA
-:1014B000041A8C2000010302061A8C240000000389
-:1014C000041A8C3000010303061A8C340000000358
-:1014D000041A8C4000010304061A8C440000000327
-:1014E000041A8C5000010305061A8C5400000003F6
-:1014F000041A8C6000010306061A8C6400000003C5
-:10150000041A8C7000010307061A8C740000000393
-:10151000041A8C8000010308061A8C840000000362
-:10152000041A8C9000010309061A8C940000000331
-:10153000041A8CA00001030A061A8CA40000000300
-:10154000041A8CB00001030B061A8CB400000003CF
-:10155000041A8CC00001030C061A8CC4000000039E
-:10156000041A8CD00001030D061A8CD4000000036D
-:10157000041A8CE00001030E061A8CE4000000033C
-:10158000041A8CF00001030F061A8CF4000000030B
-:10159000041A8D0000010310061A8D0400000003D8
-:1015A000041A8D1000010311061A8D1400000003A7
-:1015B000041A8D2000010312061A8D240000000376
-:1015C000041A8D3000010313061A8D340000000345
-:1015D000041A8D4000010314061A8D440000000314
-:1015E000041A8D5000010315061A8D5400000003E3
-:1015F000041A8D6000010316061A8D6400000003B2
-:10160000041A8D7000010317061A8D740000000380
-:10161000041A8D8000010318061A8D84000000034F
-:10162000041A8D9000010319061A8D94000000031E
-:10163000041A8DA00001031A061A8DA400000003ED
-:10164000041A8DB00001031B061A8DB400000003BC
-:10165000041A8DC00001031C061A8DC4000000038B
-:10166000041A8DD00001031D061A8DD4000000035A
-:10167000041A8DE00001031E061A8DE40000000329
-:10168000041A8DF00001031F061A8DF400000003F8
-:10169000041A8E0000010320061A8E0400000003C5
-:1016A000041A8E1000010321061A8E140000000394
-:1016B000041A8E2000010322061A8E240000000363
-:1016C000041A8E3000010323061A8E340000000332
-:1016D000041A8E4000010324061A8E440000000301
-:1016E000041A8E5000010325061A8E5400000003D0
-:1016F000041A8E6000010326061A8E64000000039F
-:10170000041A8E7000010327061A8E74000000036D
-:10171000041A8E8000010328061A8E84000000033C
-:10172000041A8E9000010329061A8E94000000030B
-:10173000041A8EA00001032A061A8EA400000003DA
-:10174000041A8EB00001032B061A8EB400000003A9
-:10175000041A8EC00001032C061A8EC40000000378
-:10176000041A8ED00001032D061A8ED40000000347
-:10177000041A8EE00001032E061A8EE40000000316
-:10178000041A8EF00001032F061A8EF400000003E5
-:10179000041A8F0000010330061A8F0400000003B2
-:1017A000041A8F1000010331061A8F140000000381
-:1017B000041A8F2000010332061A8F240000000350
-:1017C000041A8F3000010333061A8F34000000031F
-:1017D000041A8F4000010334061A8F4400000003EE
-:1017E000041A8F5000010335061A8F5400000003BD
-:1017F000041A8F6000010336061A8F64000000038C
-:10180000041A8F7000010337061A8F74000000035A
-:10181000041A8F8000010338061A8F840000000329
-:10182000041A8F9000010339061A8F9400000003F8
-:10183000041A8FA00001033A061A8FA400000003C7
-:10184000041A8FB00001033B061A8FB40000000396
-:10185000041A8FC00001033C061A8FC40000000365
-:10186000041A8FD00001033D061A8FD40000000334
-:10187000041A8FE00001033E061A8FE400000007FF
-:10188000041A62C00020033F061AD0000000007254
-:10189000061AD24800000010061AD6B00000002038
-:1018A000061AD47000000090061AD46800000002E6
-:1018B000061AA000000001C4061A30000000001043
-:1018C000061A308000000010061A310000000010D7
-:1018D000061A318000000010061A330000000012C2
-:1018E000061A339000000070061AD4580000000257
-:1018F000061AD34800000002061AD3580000002040
-:10190000061AA710000001C4061A3040000000109B
-:10191000061A30C000000010061A31400000001006
-:10192000061A31C000000010061A334800000012E9
-:10193000061A355000000070061AD460000000023C
-:10194000061AD35000000002061AD3D80000002067
-:10195000021AAE2000000000061A5000000000022B
-:10196000061A508000000012041A40000002035FB3
-:10197000041A63C000020361061A7000000000042C
-:10198000061A320000000008021AAE24000000000F
-:10199000061A501000000002061A50C8000000127B
-:1019A000041A400800020363041A63C800020365B6
-:1019B000061A701000000004061A32200000000809
-:1019C000021AAE2800000000061A50200000000293
-:1019D000061A511000000012041A4010000203679A
-:1019E000041A63D000020369061A70200000000484
-:1019F000061A324000000008021AAE2C0000000057
-:101A0000061A503000000002061A51580000001259
-:101A1000041A40180002036B041A63D80002036D15
-:101A2000061A703000000004061A32600000000838
-:101A3000021AAE3000000000061A504000000002FA
-:101A4000061A51A000000012041A40200002036F81
-:101A5000041A63E000020371061A704000000004DB
-:101A6000061A328000000008021AAE34000000009E
-:101A7000061A505000000002061A51E80000001239
-:101A8000041A402800020373041A63E80002037575
-:101A9000061A705000000004061A32A00000000868
-:101AA000021AAE3800000000061A50600000000262
-:101AB000061A523000000012041A40300002037768
-:101AC000041A63F000020379061A70600000000433
-:101AD000061A32C000000008021AAE3C00000000E6
-:101AE000061A507000000002061A52780000001218
-:101AF000041A40380002037B041A63F80002037DD5
-:101B0000061A707000000004061A32E00000000897
-:101B10000200A468000B01C80200A294071D29114D
-:101B20000200A298000000000200A29C009C042475
-:101B30000200A2A0000000000200A2A4000002090E
-:101B40000200A270000000000200A2740000000069
-:101B50000200A270000000000200A2740000000059
-:101B60000200A270000000000200A2740000000049
-:101B70000200A270000000000200A2740000000039
-:101B8000020160A000000001020160A400000262E6
-:101B9000020160A800000002020160AC0000001811
-:101BA0000201620400000001020100B40000000113
-:101BB000020100B800000001020100DC0000000189
-:101BC0000201010000000001020101040000000107
-:101BD0000201007C003000000201008400000028A7
-:101BE0000201008C0000000002010130000000042E
-:101BF0000201025C00000001020103280000000055
-:101C0000020160580000FFFF020160700000000741
-:101C10000201608000000001020105540000003054
-:101C2000020100C400000001020100CC000000011C
-:101C3000020100F800000001020100F000000001B4
-:101C4000020100800030000002010088000000282E
-:101C500002010090000000000201013400000004B5
-:101C6000020102DC000000010201032C0000000060
-:101C70000201605C0000FFFF0201607400000007C9
-:101C800002016084000000010201056400000030D0
-:101C9000020100C800000001020100D000000001A4
-:101CA000020100FC00000001020100F4000000013C
-:101CB000020C100000000028020C20080000021195
-:101CC000020C200C00000200020C20100000020494
-:101CD000020C201C0000FFFF020C20200000FFFF70
-:101CE000020C20240000FFFF020C20280000FFFF50
-:101CF000020C203800000020020C203C00000021D3
-:101D0000020C204000000022020C204400000023AE
-:101D1000020C204800000024020C204C000000258A
-:101D2000020C205000000026020C20540000002766
-:101D3000020C205800000028020C205C0000002942
-:101D4000020C20600000002A020C20640000002B1E
-:101D5000020C20680000002C020C206C0000002DFA
-:101D6000020C20700000002E020C20740000002FD6
-:101D7000020C207800000010060C207C00000007F8
-:101D8000020C209800000011020C209C00000012A0
-:101D9000020C20A000000013060C20A40000001D6F
-:101DA000020C211800000001020C211C000000019F
-:101DB000020C212000000001060C21240000001D5F
-:101DC000020C219800000001060C219C0000000775
-:101DD000020C21B800000001020C21BC000000012F
-:101DE000020C21C000000001020C21C4000000010F
-:101DF000020C21C800000001020C21CC00000001EF
-:101E0000020C21D000000001020C21D400000001CE
-:101E1000020C21D800000001020C21DC00000001AE
-:101E2000020C21E000000001020C21E4000000018E
-:101E3000020C21E800000001020C21EC000000016E
-:101E4000020C21F000000001020C21F4000000014E
-:101E5000020C21F800000001060C21FC0000000724
-:101E6000020C221800000001060C221C00000007D2
-:101E7000020C223807FFFFFF020C223C0000003F4B
-:101E8000020C224007FFFFFF020C22440000000F5B
-:101E9000010C224800000000010C224C0000000050
-:101EA000010C225000000000010C22540000000030
-:101EB000010C225800000000010C225C0000000010
-:101EC000010C226000000000010C226400000000F0
-:101ED000010C226800000000010C226C00000000D0
-:101EE000010C227000000000010C227400000000B0
-:101EF000010C227800000000010C227C0000000090
-:101F00000C0C2000000003E80A0C20000000000177
-:101F10000B0C20000000000A020C40080000101109
-:101F2000020C400C00001000020C401000001004D5
-:101F3000020C401400001021020C401C0000FFFFA6
-:101F4000020C40200000FFFF020C40240000FFFFB5
-:101F5000020C40280000FFFF020C40380000004641
-:101F6000020C403C00000010060C40400000000243
-:101F7000020C404800000018020C404C000000F029
-:101F8000060C40500000001F020C40CC0000000175
-:101F9000060C40D00000003A020C41B800000001DD
-:101FA000060C41BC00000003020C41C80000000107
-:101FB000020C41CC00000001060C41D00000001AC8
-:101FC000020C423807FFFFFF020C423C0000003FBA
-:101FD000020C424007FFFFFF020C42440000000FCA
-:101FE000010C424800000000010C424C00000000BF
-:101FF000010C425000000000010C4254000000009F
-:10200000010C425800000000010C425C000000007E
-:10201000010C426000000000010C4264000000005E
-:10202000010C426800000000010C426C000000003E
-:10203000010C427000000000010C4274000000001E
-:10204000010C427800000000010C427C00000000FE
-:10205000010C4280000000000C0C4000000003E86E
-:102060000A0C4000000000010B0C40000000000AB8
-:10207000060D400000000A00020D0044000000327E
-:10208000020D008C02150020020D009002150020A8
-:10209000020D009408100000020D009800000033AB
-:1020A000020D009C00000002020D00A000000000D4
-:1020B000020D00A400000005020D00A800000005AC
-:1020C000060D00AC00000002020D00B4000000028A
-:1020D000020D00B800000003020D00BC0000000269
-:1020E000020D00C000000001020D00C80000000247
-:1020F000020D00CC00000002020D015C0000000196
-:10210000020D016400000001020D016800000002E0
-:10211000020D020400000001020D020C000000206C
-:10212000020D021000000040020D021400000040E9
-:10213000020D022000000003020D0224000000181E
-:10214000060D028000000012040D03000018037F3A
-:10215000060D03600000000C020D004C00000001A1
-:10216000020D005000000002020D005400000000AB
-:10217000020D005800000008060D005C000000047D
-:10218000020D00C400000004020D00040000000164
-:10219000020D000800000001020D000C000000010B
-:1021A000020D001000000001020D001400000001EB
-:1021B000020D001800000001020D001C00000001CB
-:1021C000020D002000000001020D002400000001AB
-:1021D000020D002800000001020D002C000000018B
-:1021E000020D003000000001020D0034000000016B
-:1021F000020D003800000001020D003C000000014B
-:10220000020D011400000009020D011C0000000A6B
-:10221000020D012400000000020D012C000000004E
-:10222000020D013400000000020D013C0000000B13
-:10223000020D014400000000020D011800000029F9
-:10224000020D01200000002A020D012800000020DC
-:10225000020D013000000020020D013800000020B6
-:10226000020D01400000002B020D0148000000207B
-:10227000020D011400000019020D011C0000001ADB
-:10228000020D012400000010020D012C00000010BE
-:10229000020D013400000010020D013C0000001B83
-:1022A000020D014400000010020D01180000003969
-:1022B000020D01200000003A020D0128000000304C
-:1022C000020D013000000030020D01380000003026
-:1022D000020D01400000003B020D014800000030EB
-:1022E000020D011400000049020D011C0000004A0B
-:1022F000020D012400000040020D012C00000040EE
-:10230000020D013400000040020D013C0000004BB2
-:10231000020D014400000040020D01180000006998
-:10232000020D01200000006A020D0128000000607B
-:10233000020D013000000060020D01380000006055
-:10234000020D01400000006B020D0148000000601A
-:10235000020D011400000059020D011C0000005A7A
-:10236000020D012400000050020D012C000000505D
-:10237000020D013400000050020D013C0000005B22
-:10238000020D014400000050020D01180000007908
-:10239000020D01200000007A020D012800000070EB
-:1023A000020D013000000070020D013800000070C5
-:1023B000020D01400000007B020D0148000000708A
-:1023C000060E200000000800020E004C0000003243
-:1023D000020E009402150020020E00980215002043
-:1023E000020E009C00000030020E00A00810000049
-:1023F000020E00A400000033020E00A8000000300E
-:10240000020E00AC00000031020E00B0000000021D
-:10241000020E00B400000004020E00B8000000002C
-:10242000020E00BC00000002020E00C0000000020C
-:10243000020E00C400000000020E00C800000002EE
-:10244000020E00CC00000007020E00D000000002C7
-:10245000020E00D400000002020E00D800000001AD
-:10246000020E014400000001020E014C00000001B8
-:10247000020E015000000002020E020400000001E2
-:10248000020E020C00000040020E0210000000408C
-:10249000020E021C00000004020E022000000020B8
-:1024A000020E02240000000E020E02280000001B93
-:1024B000060E030000000012040E0280001B0397AA
-:1024C000060E02EC00000005020E00540000000C95
-:1024D000020E00580000000C020E005C000000001C
-:1024E000020E006000000010020E006400000010E8
-:1024F000060E006800000003020E00DC000000036E
-:10250000020E000400000001020E0008000000019D
-:10251000020E000C00000001020E0010000000017D
-:10252000020E001400000001020E0018000000015D
-:10253000020E001C00000001020E0020000000013D
-:10254000020E002400000001020E0028000000011D
-:10255000020E002C00000001020E003000000001FD
-:10256000020E003400000001020E003800000001DD
-:10257000020E003C00000001020E004000000001BD
-:10258000020E004400000001020E01100000000FC6
-:10259000020E011800000000020E012000000000E1
-:1025A000020E012800000000020E01140000002F9E
-:1025B000020E011C00000020020E01240000000099
-:1025C000020E012C00000000020E01100000001F8E
-:1025D000020E011800000010020E01200000000091
-:1025E000020E012800000000020E01140000003F4E
-:1025F000020E011C00000030020E01240000000049
-:10260000020E012C00000000020E01100000004F1D
-:10261000020E011800000040020E01200000000020
-:10262000020E012800000000020E01140000006FDD
-:10263000020E011C00000060020E012400000000D8
-:10264000020E012C00000000020E01100000005FCD
-:10265000020E011800000050020E012000000000D0
-:10266000020E012800000000020E01140000007F8D
-:10267000020E011C00000070020E01240000000088
-:10268000020E012C000000000730040000C9000009
-:10269000083007D8000503B207340000332B0000D0
-:1026A0000734800030A40CCB07350000351A18F52C
-:1026B000073580002A8A263C0736000018D830DF0C
-:1026C00008364630373A03B40130000000000000FD
-:1026D000013000040000000001300008000000008C
-:1026E0000130000C0000000001300010000000006C
-:1026F0000130001400000000023000200000000142
-:102700000230002400000002023000280000000314
-:102710000230002C000000000230003000000004F5
-:1027200002300034000000010230003800000000D8
-:102730000230003C000000010230004000000004B4
-:102740000230004400000000023000480000000198
-:102750000230004C00000003023000500000000076
-:102760000230005400000001023000580000000454
-:102770000230005C00000000023000600000000138
-:102780000230006400000003023000680000000016
-:102790000230006C000000010230007000000004F4
-:1027A00002300074000000000230007800000004D5
-:1027B0000230007C000000030630008000000002B0
-:1027C000023000A400003FFF023000A8000003FF19
-:1027D0000230022400000000023002340000000039
-:1027E0000230024C00000000023002E40000FFFF53
-:1027F000063020000000080002338BC000000001FA
-:10280000023380000000001A023380400000004EB6
-:102810000233808000000010023380C000000020DE
-:102820000C3383000007A1200A3383000000013825
-:102830000B338300000013880A338340000000003C
-:102840000C338340000001F40B338340000000058B
-:10285000023383800007A120023383C0000001F40B
-:1028600002331480000000010A33148000000000CD
-:10287000063280000000010206322008000000C875
-:10288000063220000000000204328EA0001003B6C1
-:1028900006323EB00000000606323ED800000002BC
-:1028A00006323E800000000A04323EA8000203C641
-:1028B00006323E00000000200632500000000400F6
-:1028C0000632400000000004043274C0000203C855
-:1028D00006324110000000020632D0000000003035
-:1028E0000632DD40000000440632DA00000000D06D
-:1028F0000632DEA0000000020632E0000000080000
-:1029000006328450000001180632100000000188D1
-:102910000632500000000020063251000000002066
-:102920000632520000000020063253000000002052
-:10293000063254000000002006325500000000203E
-:10294000063256000000002006325700000000202A
-:102950000632580000000020063259000000002016
-:1029600006325A000000002006325B000000002002
-:1029700006325C000000002006325D0000000020EE
-:1029800006325E000000002006325F0000000020DA
-:1029900006328DF00000000204328E00000203CAED
-:1029A00006328E08000000020632DE9000000002AF
-:1029B00006321C4000000038063288B000000118C2
-:1029C00006321620000001880632508000000020E8
-:1029D00006325180000000200632528000000020A4
-:1029E0000632538000000020063254800000002090
-:1029F000063255800000002006325680000000207C
-:102A00000632578000000020063258800000002067
-:102A1000063259800000002006325A800000002053
-:102A200006325B800000002006325C80000000203F
-:102A300006325D800000002006325E80000000202B
-:102A400006325F800000002006328DF80000000290
-:102A500004328E10000203CC06328E1800000002F1
-:102A60000632DE980000000206321D200000003809
-:102A700002328D50000000000632401000000002BB
-:102A800002328D5400000000063240200000000297
-:102A900002328D5800000000063240300000000273
-:102AA00002328D5C0000000006324040000000024F
-:102AB00002328D600000000006324050000000022B
-:102AC00002328D6400000000063240600000000207
-:102AD00002328D68000000000632407000000002E3
-:102AE00002328D6C000000000632408000000002BF
-:102AF000072004000091000008200780001003CE8A
-:102B0000072400002AFF00000724800015090AC0DE
-:102B10000824A9F0692803D001200000000000006B
-:102B20000120000400000000012000080000000057
-:102B30000120000C00000000012000100000000037
-:102B4000012000140000000002200020000000010D
-:102B500002200024000000020220002800000003E0
-:102B60000220002C000000000220003000000004C1
-:102B700002200034000000010220003800000000A4
-:102B80000220003C00000001022000400000000480
-:102B90000220004400000000022000480000000164
-:102BA0000220004C00000003022000500000000042
-:102BB0000220005400000001022000580000000420
-:102BC0000220005C00000000022000600000000104
-:102BD00002200064000000030220006800000000E2
-:102BE0000220006C000000010220007000000004C0
-:102BF00002200074000000000220007800000004A1
-:102C00000220007C0000000306200080000000027B
-:102C1000022000A400003FFF022000A8000003FFE4
-:102C20000220022400000000022002340000000004
-:102C30000220024C00000000022002E40000FFFF1E
-:102C4000062020000000080002238BC000000001C5
-:102C500002238000000000100223804000000012C8
-:102C60000223808000000030022380C00000000E9C
-:102C70000C2383000007A1200A23830000000138F1
-:102C80000B238300000013880A2383400000000008
-:102C90000C238340000001F40B2383400000000557
-:102CA000022383800007A120022383C0000001F4D7
-:102CB00002231480000000010A2314800000000099
-:102CC000062210000000004206222008000000C872
-:102CD00006222000000000020622B000000000C60C
-:102CE0000422B318000503D20622B32C0000000B07
-:102CF0000422B358000503D70622B36C0000000B72
-:102D00000422B398000503DC0622B3AC0000000BDC
-:102D10000422B3D8000503E10622B3EC0000000B47
-:102D20000422B418000503E60622B42C0000000BB0
-:102D30000422B458000503EB0622B46C0000000B1B
-:102D40000422B498000503F00622B4AC0000000B86
-:102D50000422B4D8000503F50622B4EC0000000BF1
-:102D60000422B518000503FA0622B52C0000000B5A
-:102D70000422B558000503FF0622B56C0000000BC5
-:102D80000422B598000504040622B5AC0000000B2F
-:102D90000422B5D8000504090622B5EC0000000B9A
-:102DA0000422B6180005040E0622B62C0000000B03
-:102DB0000422B658000504130622B66C0000000B6E
-:102DC0000422B698000504180622B6AC0000000BD9
-:102DD0000422B6D80005041D0622B6EC0000000B44
-:102DE0000422B718000504220622B72C0000000BAD
-:102DF0000422B758000504270622B76C0000000B18
-:102E00000422B7980005042C0622B7AC0000000B82
-:102E10000422B7D8000504310622B7EC0000000BED
-:102E20000422B818000504360622B82C0000000B56
-:102E30000422B8580005043B0622B86C0000000BC1
-:102E40000422B898000504400622B8AC0000000B2C
-:102E50000422B8D8000504450622B8EC0000000B97
-:102E60000422B9180005044A0622B92C0000000B00
-:102E70000422B9580005044F0622B96C0000000B6B
-:102E80000422B998000504540622B9AC0000000BD6
-:102E90000422B9D8000504590622B9EC0000000B41
-:102EA0000422BA180005045E0622BA2C0000000BAA
-:102EB0000422BA58000504630622BA6C0000000B15
-:102EC0000422BA98000504680622BAAC0000000B80
-:102ED0000422BAD80005046D0622BAEC00000005F1
-:102EE0000622BB00000000530422BC4C0001047207
-:102EF0000622BC50000000030422BC5C00010473E5
-:102F00000622BC60000000030422BC6C00010474B3
-:102F10000622BC70000000030422BC7C0001047582
-:102F20000622BC80000000030422BC8C0001047651
-:102F30000622BC90000000030422BC9C0001047720
-:102F40000622BCA0000000030422BCAC00010478EF
-:102F50000622BCB0000000030422BCBC00010479BE
-:102F60000622880000000100062280000000020006
-:102F7000042212700010047A06223000000000C003
-:102F800006226700000001000622900000000400F5
-:102F900004226B080020048A022212C0FFFFFFFFF8
-:102FA000062211E800000002062212C800000009F3
-:102FB000062212EC0000000906228C000000000826
-:102FC0000222114800000000062213200000000623
-:102FD000062233000000000206226040000000309C
-:102FE00006228C20000000080222114C0000000084
-:102FF00006221338000000060622330800000002F3
-:10300000062261000000003006228C40000000080B
-:10301000022211500000000006221350000000069A
-:103020000622331000000002062261C000000030BA
-:1030300006228C60000000080222115400000000EB
-:103040000622136800000006062233180000000262
-:10305000062262800000003006228C8000000008FA
-:103060000222115800000000062213800000000612
-:1030700006223320000000020622634000000030D8
-:1030800006228CA0000000080222115C0000000053
-:1030900006221398000000060622332800000002D2
-:1030A000062264000000003006228CC000000008E8
-:1030B0000222116000000000062213B0000000068A
-:1030C0000622333000000002062264C000000030F7
-:1030D00006228CE0000000080222116400000000BB
-:1030E000062213C800000006062233380000000242
-:1030F0000622658000000030021610000000002843
-:1031000002170008000000020217002C0000000354
-:103110000217003C000000040217004800000002F3
-:103120000217004C000000900217005000000090B1
-:103130000217005400800090021700580810000089
-:10314000021700600000008A02170064000000807F
-:1031500002170068000000810217006C0000008068
-:10316000021700700000000602170078000007D068
-:103170000217007C0000076C02170038007C100466
-:10318000021700040000000F061640240000000291
-:10319000021640700000001C0216420800000001E8
-:1031A0000216421000000001021642200000000139
-:1031B0000216422800000001021642300000000101
-:1031C00002164238000000010216426000000002B0
-:1031D0000C16401C0003D0900A16401C0000009CF6
-:1031E0000B16401C000009C4021640300000000805
-:1031F000021640340000000C021640380000001097
-:1032000002164044000000200216400000000001A9
-:10321000021640D80000000102164008000000011C
-:103220000216400C000000010216401000000001D0
-:103230000216424000000000021642480000000052
-:103240000616427000000002021642500000000004
-:1032500002164258000000000616428000000002DC
-:1032600002166008000012240216600C0000121002
-:1032700002166010000012140216601C0000FFFF0E
-:10328000021660200000FFFF021660240000FFFF0E
-:10329000021660280000FFFF0216603800000020C0
-:1032A0000216603C0000002006166040000000028C
-:1032B00002166048000000230216604C0000002443
-:1032C000021660500000002502166054000000261F
-:1032D00002166058000000270216605C00000029FA
-:1032E000021660600000002A021660640000002BD5
-:1032F000021660680000002C0216606C0000002DB1
-:1033000002166070000000EC0216607400000011EC
-:1033100002166078000000120616607C0000000FA4
-:10332000021660B800000001021660BC0000000137
-:10333000061660C00000000C021660F000000001DC
-:10334000061660F400000031021661B800000001AA
-:10335000061661BC0000000D021661F000000001BD
-:10336000061661F4000000110216623807FFFFFF25
-:103370000216623C0000003F0216624007FFFFFF9A
-:10338000021662440000000F0116624800000000AF
-:103390000116624C0000000001166250000000009F
-:1033A000011662540000000001166258000000007F
-:1033B0000116625C0000000001166260000000005F
-:1033C000011662640000000001166268000000003F
-:1033D0000116626C0000000001166270000000001F
-:1033E00001166274000000000116627800000000FF
-:1033F0000116627C000000000C166000000003E86B
-:103400000A166000000000010B1660000000000AB0
-:1034100002168040000000060216804400000005ED
-:10342000021680480000000A0216804C00000005C9
-:103430000216805400000002021680CC0000000436
-:10344000021680D000000004021680D400000004A0
-:10345000021680D800000004021680DC0000000480
-:10346000021680E000000004021680E40000000460
-:10347000021680E800000004021688040000000420
-:10348000021680300000007C021680340000003DEF
-:10349000021680380000003F0216803C0000009CAD
-:1034A000021680F000000007061680F400000005F8
-:1034B0000216880C010101010216810800000000BB
-:1034C0000216810C000000040216811000000004A6
-:1034D0000216811400000002021688100801200460
-:1034E00002168118000000050216811C000000056C
-:1034F000021681200000000502168124000000054C
-:103500000216882C200810010216812800000008ED
-:103510000216812C00000006021681300000000710
-:1035200002168134000000000216883001010120DB
-:1035300006168138000000040216883401010101DA
-:1035400002168148000000000216814C00000004B1
-:10355000021681500000000402168154000000028F
-:103560000216883808012004021681580000000560
-:103570000216815C00000005021681600000000553
-:1035800002168164000000050216883C2008100124
-:1035900002168168000000080216816C0000000617
-:1035A00002168170000000070216817400000001FD
-:1035B00002168840010101200216817800000001F6
-:1035C0000216817C000000010216818000000001CB
-:1035D00002168184000000010216884401010101E5
-:1035E00002168188000000010216818C0000000490
-:1035F000021681900000000402168194000000026F
-:10360000021688480801200402168198000000056F
-:103610000216819C00000005021681A00000000532
-:10362000021681A40000000502168814200810016B
-:10363000021681A800000008021681AC00000006F6
-:10364000021681B000000007021681B400000001DC
-:103650000216881801010120021681B8000000013D
-:10366000021681BC00000001021681C000000001AA
-:10367000021681C4000000010216881C010101012C
-:10368000021681C800000001021681CC000000046F
-:10369000021681D000000004021681D4000000024E
-:1036A0000216882008012004021681D800000005B7
-:1036B000021681DC00000005021681E00000000512
-:1036C000021681E40000000502168824200810017B
-:1036D000021681E800000008021681EC00000006D6
-:1036E000021681F0000000070216E40C0000000042
-:1036F00002168828010101200616E41000000004CB
-:103700000216E000010101010216E42000000000A1
-:103710000216E424000000040216E428000000045D
-:103720000216E42C000000020216E0040801200446
-:103730000216E430000000050216E4340000000523
-:103740000216E438000000050216E43C0000000503
-:103750000216E008200810010216E44000000008EC
-:103760000216E444000000060216E44800000007C8
-:103770000216E44C000000000216E00C01010120DA
-:103780000616E450000000040216E01001010101D9
-:103790000216E460000000000216E4640000000469
-:1037A0000216E468000000040216E46C0000000247
-:1037B0000216E014080120040216E470000000055F
-:1037C0000216E474000000050216E478000000050B
-:1037D0000216E47C000000050216E0182008100123
-:1037E0000216E480000000080216E48400000006CF
-:1037F0000216E488000000070216E48C00000001B5
-:103800000216E01C010101200216E49000000001F4
-:103810000216E494000000010216E4980000000182
-:103820000216E49C000000010216E02001010101E3
-:103830000216E4A0000000010216E4A40000000447
-:103840000216E4A8000000040216E4AC0000000226
-:103850000216E024080120040216E4B0000000056E
-:103860000216E4B4000000050216E4B800000005EA
-:103870000216E4BC000000050216E0282008100132
-:103880000216E4C0000000080216E4C400000006AE
-:103890000216E4C8000000070216E4CC0000000194
-:1038A0000216E02C010101200216E4D00000000104
-:1038B0000216E4D4000000010216E4D80000000162
-:1038C0000216E4DC000000010216E03001010101F3
-:1038D0000216E4E0000000010216E4E40000000427
-:1038E0000216E4E8000000040216E4EC0000000206
-:1038F0000216E034080120040216E4F0000000057E
-:103900000216E4F4000000050216E4F800000005C9
-:103910000216E4FC000000050216E0382008100141
-:103920000216E500000000080216E504000000068B
-:103930000216E508000000070216E03C0101012024
-:1039400002168240003F003F021682440000000041
-:103950000216E524003F003F0216E52800000000A3
-:1039600002168248000000000216824C003F003F11
-:103970000216E52C000000000216E530003F003F73
-:10398000021682500100010002168254010001005B
-:103990000216E534010001000216E53801000100BD
-:1039A00006168258000000020216E53C00000000E6
-:1039B0000216E540000000000216826000C000C050
-:1039C0000216826400C000C00216E54400C000C0B8
-:1039D0000216E54800C000C0021682681E001E00E4
-:1039E0000216826C1E001E000216E54C1E001E0010
-:1039F0000216E5501E001E000216827040004000B4
-:103A000002168274400040000216E5544000400057
-:103A10000216E558400040000216827880008000BF
-:103A20000216827C800080000216E55C8000800027
-:103A30000216E560800080000216828020002000CF
-:103A400002168284200020000216E5642000200077
-:103A50000216E56820002000061682880000000299
-:103A60000216E56C000000000216E5700000000080
-:103A700002168290000000000216829400000000EE
-:103A80000216E574000000000216E5780000000050
-:103A900002168298000000000216829C00000000BE
-:103AA0000216E57C000000000216E5800000000020
-:103AB000021682A000000000021682A4000000018D
-:103AC000061682A80000000A021681F400000C0805
-:103AD000021681F800000040021681FC000001007F
-:103AE0000216820000000020021682040000001767
-:103AF00002168208000000800216820C00000200FC
-:103B000002168210000000000216821801FF01FF59
-:103B10000216821401FF01FF0216E51001FF01FFEA
-:103B20000216E50C01FF01FF0216823C00000013A3
-:103B3000021680900000013F0216806000000140E4
-:103B40000216806400000140061680680000000232
-:103B500002168070000000C0061680740000000786
-:103B60000216809C00000048021680A00000004859
-:103B7000061680A400000002021680AC0000004877
-:103B8000061680B000000007021682380000800090
-:103B900002168234000025E40216809400007FFFA4
-:103BA00002168220000F000F0216821C000F000F69
-:103BB0000216E518000F000F0216E514000F000FA3
-:103BC000021682280000000002168224FFFFFFFF79
-:103BD0000216E520000000000216E51CFFFFFFFFB3
-:103BE0000216E6BC000000000216E6C0000000025B
-:103BF0000216E6C4000000010216E6C80000000339
-:103C00000216E6CC000000040216E6D00000000612
-:103C10000216E6D4000000050216E6D800000007F0
-:103C2000021680EC000000FF0214000000000001FA
-:103C30000214000C0000000102140040000000010A
-:103C40000214004400007FFF0214000C000000007A
-:103C500002140000000000000214006C00000000CC
-:103C600002140004000000010214003000000001F2
-:103C700002140004000000000214005C00000000B8
-:103C800002140008000000010214003400000001CA
-:103C90000214000800000000021400600000000090
-:103CA00006028000000020000202005800000032DE
-:103CB000020200A003150020020200A40315002048
-:103CC000020200A801000030020200AC081000004F
-:103CD000020200B000000033020200B40000003015
-:103CE000020200B800000031020200BC0000000324
-:103CF000020200C000000006020200C4000000032F
-:103D0000020200C800000003020200CC0000000212
-:103D1000020200D000000000020200D400000002F5
-:103D2000020200DC00000000020200E000000006C9
-:103D3000020200E400000004020200E800000002A9
-:103D4000020200EC00000002020200F0000000018C
-:103D5000020200FC00000006020201200000000038
-:103D60000202013400000002020201B00000000162
-:103D70000202020C00000001020202140000000115
-:103D80000202021800000002020204040000000106
-:103D90000202040C00000040020204100000004077
-:103DA0000202041C000000040202042000000020A3
-:103DB0000202042400000002020204280000002085
-:103DC000060205000000001204020480002004AA7C
-:103DD000020200600000000F020200640000000701
-:103DE00002020068000000000202006C0000000EE9
-:103DF000020200700000000E0602007400000003C2
-:103E0000020200F4000000040202000400000001AD
-:103E100002020008000000010202000C0000000184
-:103E20000202001000000001020200140000000164
-:103E300002020018000000010202001C0000000144
-:103E40000202002000000001020200240000000124
-:103E500002020028000000010202002C0000000104
-:103E600002020030000000010202003400000001E4
-:103E700002020038000000010202003C00000001C4
-:103E800002020040000000010202004400000001A4
-:103E900002020048000000010202004C0000000184
-:103EA000020200500000000102020108000000C8E8
-:103EB0000202011800000002020201C4000000001A
-:103EC000020201CC00000000020201D40000000246
-:103ED000020201DC00000002020201E4000000FF17
-:103EE000020201EC000000FF0202010000000000DD
-:103EF0000202010C000000C80202011C00000002C6
-:103F0000020201C800000000020201D0000000000F
-:103F1000020201D800000002020201E000000002DB
-:103F2000020201E8000000FF020201F0000000FFB1
-:103F3000020201040000000002020108000000C8A3
-:103F40000202011800000002020201C40000000089
-:103F5000020201CC00000000020201D400000002B5
-:103F6000020201DC00000002020201E4000000FF86
-:103F7000020201EC000000FF02020100000000004C
-:103F80000202010C000000C80202011C0000000235
-:103F9000020201C800000000020201D0000000007F
-:103FA000020201D800000002020201E0000000024B
-:103FB000020201E8000000FF020201F0000000FF21
-:103FC000020201040000000002020108000000C813
-:103FD0000202011800000002020201C400000000F9
-:103FE000020201CC00000000020201D40000000225
-:103FF000020201DC00000002020201E4000000FFF6
-:10400000020201EC000000FF0202010000000000BB
-:104010000202010C000000C80202011C00000002A4
-:10402000020201C800000000020201D000000000EE
-:10403000020201D800000002020201E000000002BA
-:10404000020201E8000000FF020201F0000000FF90
-:10405000020201040000000002020108000000C882
-:104060000202011800000002020201C40000000068
-:10407000020201CC00000000020201D40000000294
-:10408000020201DC00000002020201E4000000FF65
-:10409000020201EC000000FF02020100000000002B
-:1040A0000202010C000000C80202011C0000000214
-:1040B000020201C800000000020201D0000000005E
-:1040C000020201D800000002020201E0000000022A
-:1040D000020201E8000000FF020201F0000000FF00
-:1040E00002020104000000000728040000A30000F1
-:1040F000082807B8000904CA072C000034F10000A2
-:10410000072C800038A60D3D072D000037B61B6731
-:10411000072D800032632955072E00001C6835EEFC
-:10412000082E48B036EA04CC012800000000000048
-:104130000128000400000000012800080000000021
-:104140000128000C00000000012800100000000001
-:1041500001280014000000000228002000000001D7
-:1041600002280024000000020228002800000003AA
-:104170000228002C0000000002280030000000048B
-:10418000022800340000000102280038000000006E
-:104190000228003C0000000102280040000000044A
-:1041A000022800440000000002280048000000012E
-:1041B0000228004C0000000302280050000000000C
-:1041C00002280054000000010228005800000004EA
-:1041D0000228005C000000000228006000000001CE
-:1041E00002280064000000030228006800000000AC
-:1041F0000228006C0000000102280070000000048A
-:10420000022800740000000002280078000000046A
-:104210000228007C00000003062800800000000245
-:10422000022800A400003FFF022800A8000003FFAE
-:1042300002280224000000000228023400000000CE
-:104240000228024C00000000022802E40000FFFFE8
-:104250000628200000000800022B8BC0000000018F
-:10426000022B800000000000022B8040000000189C
-:10427000022B80800000000C022B80C00000006632
-:104280000C2B83000007A1200A2B830000000138BB
-:104290000B2B8300000013880A2B834000000000D2
-:1042A0000C2B8340000001F40B2B83400000000521
-:1042B000022B83800007A120022B83C0000001F4A1
-:1042C000022B1480000000010A2B14800000000063
-:1042D000062A9AF800000004042A9B08000204CE73
-:1042E000062A9B1000000006062A90800000004865
-:1042F000062A2008000000C8062A2000000000024C
-:10430000062A91A800000086062A900000000020DE
-:10431000062A93C800000003042A93D4000104D0A5
-:10432000062A9DA800000002042A9498000404D1E3
-:10433000042A9D58000104D5062A9D5C0000001146
-:10434000042ACB20001004D6042A3000000204E620
-:10435000062A300800000100062A40400000001034
-:10436000042A4000001004E8042A8408000204F82B
-:10437000062A9DA000000002062AB000000000509E
-:10438000062ABB7000000070062AB150000000022F
-:10439000062ABB6000000004062AD00000000800C6
-:1043A000062AC00000000150062A94A8000000322E
-:1043B000062A502000000002062A503000000002A9
-:1043C000062A500000000002062A501000000002D9
-:1043D000022A520800000001042A9B28000204FA65
-:1043E000062A963800000022042A96C0000104FC28
-:1043F000062A96C400000003062A976800000022DF
-:10440000042A97F0000104FD062A97F40000000337
-:10441000062A989800000022042A9920000104FE30
-:10442000062A992400000003062A99C800000022E9
-:10443000042A9A50000104FF062A9A54000000033F
-:10444000062AB14000000002062AC54000000150C3
-:10445000062A957000000032062A5028000000024B
-:10446000062A503800000002062A50080000000208
-:10447000062A501800000002022A520C0000000117
-:10448000042A9B3000020500062A96D00000002274
-:10449000042A975800010502062A975C00000003D1
-:1044A000062A980000000022042A988800010503CB
-:1044B000062A988C00000003062A9930000000228A
-:1044C000042A99B800010504062A99BC00000003DB
-:1044D000062A9A6000000022042A9AE800010505D5
-:1044E000062A9AEC00000003062AB14800000002E8
-:1044F000022ACA8000000000042A9B38001005062A
-:10450000062A50480000000E022ACA84000000005B
-:10451000042A9B7800100516062A50800000000E21
-:10452000022ACA8800000000042A9BB80010052651
-:10453000062A50B80000000E022ACA8C00000000B3
-:10454000042A9BF800100536062A50F00000000EE1
-:10455000022ACA9000000000042A9C380010054678
-:10456000062A51280000000E022ACA94000000000A
-:10457000042A9C7800100556062A51600000000E9F
-:10458000022ACA9800000000042A9CB800100566A0
-:10459000062A51980000000E022ACA9C0000000062
-:1045A000042A9CF800100576062A51D00000000E5F
-:1045B000021010080000000102101050000000015D
-:1045C000021010000003D000021010040000003D93
-:1045D0000910180002000586091011000010078656
-:1045E0000610114000000008091011600010079625
-:1045F000061011A00000001806102400000000E0C2
-:104600000210201C00000000021020200000000109
-:10461000021020C00000000202102004000000016F
-:10462000021020080000000109103C00000507A648
-:1046300009103800000507AB09103820000507B045
-:1046400006104C000000010002104028000000107D
-:104650000210404400003FFF0210405800280000B4
-:10466000021040840084924A02104058000000006A
-:104670000210800000001080021080AC00000000DA
-:1046800002108038000000100210810000000000BD
-:10469000061081200000000202108008000002B510
-:1046A0000210801000000000061082000000004A86
-:1046B000021081080001FFFF061081400000000287
-:1046C0000210800000001A800610900000000024F4
-:1046D000061091200000004A061093700000004A66
-:1046E000061095C00000004A0210800400001080EF
-:1046F000021080B0000000010210803C0000001099
-:104700000210810400000000061081280000000251
-:104710000210800C000002B502108014000000009E
-:10472000061084000000004A0210810C0001FFFF07
-:1047300006108148000000020210800400001A8068
-:104740000610909000000024061092480000004AD5
-:10475000061094980000004A061096E80000004AEF
-:104760000210800000001080021080AC00000002E7
-:1047700002108038000000100210810000000000CC
-:10478000061081200000000202108008000002B51F
-:104790000210801000000000061082000000004A95
-:1047A000021081080001FFFF061081400000000296
-:1047B0000210800000001A80061090000000002403
-:1047C000061091200000004A061093700000004A75
-:1047D000061095C00000004A0210800400001080FE
-:1047E000021080B0000000030210803C00000010A6
-:1047F0000210810400000000061081280000000261
-:104800000210800C000002B50210801400000000AD
-:10481000061084000000004A0210810C0001FFFF16
-:1048200006108148000000020210800400001A8077
-:104830000610909000000024061092480000004AE4
-:10484000061094980000004A061096E80000004AFE
-:104850000210800000001080021080AC00000004F4
-:1048600002108038000000100210810000000000DB
-:10487000061081200000000202108008000002B52E
-:104880000210801000000000061082000000004AA4
-:10489000021081080001FFFF0610814000000002A5
-:1048A0000210800000001A80061090000000002412
-:1048B000061091200000004A061093700000004A84
-:1048C000061095C00000004A02108004000010800D
-:1048D000021080B0000000050210803C00000010B3
-:1048E0000210810400000000061081280000000270
-:1048F0000210800C000002B50210801400000000BD
-:10490000061084000000004A0210810C0001FFFF25
-:1049100006108148000000020210800400001A8086
-:104920000610909000000024061092480000004AF3
-:10493000061094980000004A061096E80000004A0D
-:104940000210800000001080021080AC0000000601
-:1049500002108038000000100210810000000000EA
-:10496000061081200000000202108008000002B53D
-:104970000210801000000000061082000000004AB3
-:10498000021081080001FFFF0610814000000002B4
-:104990000210800000001A80061090000000002421
-:1049A000061091200000004A061093700000004A93
-:1049B000061095C00000004A02108004000010801C
-:1049C000021080B0000000070210803C00000010C0
-:1049D000021081040000000006108128000000027F
-:1049E0000210800C000002B50210801400000000CC
-:1049F000061084000000004A0210810C0001FFFF35
-:104A000006108148000000020210800400001A8095
-:104A10000610909000000024061092480000004A02
-:104A2000061094980000004A061096E80000004A1C
-:104A3000021205B0000000010212049000E383405E
-:104A40000212051400003C100212066C0000000166
-:104A5000021206700000000002120494FFFFFFFF24
-:104A600002120498FFFFFFFF0212049CFFFFFFFFEA
-:104A7000021204A0FFFFFFFF021204A4FFFFFFFFCA
-:104A8000021204A8FFFFFFFF021204ACFFFFFFFFAA
-:104A9000021204B0FFFFFFFF021204BCFFFFFFFF82
-:104AA000021204C0FFFFFFFF021204C4FFFFFFFF5A
-:104AB000021204C8FFFFFFFF021204CCFFFFFFFF3A
-:104AC000021204D0FFFFFFFF021204D8FFFFFFFF16
-:104AD000021204DCFFFFFFFF021204E0FFFFFFFFF2
-:104AE000021204E4FFFFFFFF021204E8FFFFFFFFD2
-:104AF000021204ECFFFFFFFF021204F0FFFFFFFFB2
-:104B0000021204F4FFFFFFFF021204F8FFFFFFFF91
-:104B1000021204FCFFFFFFFF02120500FFFFFFFF70
-:104B200002120504FFFFFFFF02120508FFFFFFFF4F
-:104B30000212050CFFFFFFFF02120510FFFFFFFF2F
-:104B4000021204D4FF809000021204B4F00050005E
-:104B5000021204B8F00010000212039000000008D6
-:104B60000212039C00000008021203A000000008CB
-:104B7000021203A400000002021203BC00000004A1
-:104B8000021203C000000005021203C4000000046A
-:104B9000021203D0000000000212036C00000001AA
-:104BA000021203680000003F021201BC0000004036
-:104BB000021201C000001808021201C4000008031C
-:104BC000021201C800000803021201CC00000040DC
-:104BD000021201D000000003021201D400000803F9
-:104BE000021201D800000803021201DC00000803D1
-:104BF000021201E000010003021201E400000803B8
-:104C0000021201E800000803021201EC0000000398
-:104C1000021201F000000003021201F40000000380
-:104C2000021201F800000003021201FC0000000360
-:104C3000021202000000000302120204000000033E
-:104C400002120208000000030212020C000000031E
-:104C500002120210000000030212021400000003FE
-:104C600002120218000000030212021C00000003DE
-:104C700002120220000000030212022400000003BE
-:104C800002120228000024030212022C0000002F4E
-:104C90000212023000000009021202340000001962
-:104CA00002120238000001840212023C000001835B
-:104CB0000212024000000306021202440000001922
-:104CC00002120248000000060212024C0000030615
-:104CD00002120250000003060212025400000306F2
-:104CE0000212025800000C860212025C0000030649
-:104CF00002120260000003060212026400000006B5
-:104D000002120268000000060212026C0000000697
-:104D10000212027000000006021202740000000677
-:104D200002120278000000060212027C0000000657
-:104D30000212028000000006021202840000000637
-:104D400002120288000000060212028C0000000617
-:104D500002120290000000060212029400000006F7
-:104D600002120298000000060212029C00000006D7
-:104D7000021202A000000306021202A400000013A7
-:104D8000021202A800000006021202B00000100485
-:104D9000021202B400001004021203240010644046
-:104DA0000212032800106440021205B40000000142
-:104DB000021201B0000000010600A0000000000C7B
-:104DC0000200A050000000000200A05400000000FB
-:104DD0000200A0EC555400000200A0F055555555B6
-:104DE0000200A0F4000055550200A0F8F0000000F9
-:104DF0000200A0FC555400000200A1005555555575
-:104E00000200A104000055550200A108F0000000B6
-:104E10000200A18C555400000200A1905555555533
-:104E20000200A194000055550200A198F000000076
-:104E30000200A19C000000000200A1A000010000EF
-:104E40000200A1A4000050140200A1A8000000006C
-:104E50000200A45C00000C000200A61C000000037D
-:104E60000200A06CFF5C00000200A070FFF55FFF75
-:104E70000200A0740000FFFF0200A078F00003E031
-:104E80000200A07C000000000200A0800000A00042
-:104E90000600A084000000050200A0980FE00000BA
-:104EA0000600A09C000000070200A0B8000004005B
-:104EB0000600A0BC000000030200A0C80000100013
-:104EC0000600A0CC000000030200A0D800004000B3
-:104ED0000600A0DC000000030200A0E800010000C2
-:104EE0000600A22C000000040200A10CFF5C0000E0
-:104EF0000200A110FFF55FFF0200A1140000FFFFF8
-:104F00000200A118F00003E00200A11C0000000054
-:104F10000200A1200000A0000600A124000000055E
-:104F20000200A1380FE000000600A13C00000007CD
-:104F30000200A158000008000600A15C0000000368
-:104F40000200A168000020000600A16C0000000320
-:104F50000200A178000080000600A17C0000000390
-:104F60000200A188000200000600A23C000000042C
-:104F70000200A030000000000200A0340000000089
-:104F80000200A038000000000200A03C0000000069
-:104F90000200A040000000000200A0440000000049
-:104FA0000200A048000000000200A04C0000000029
-:104FB00000000000000000000000003000000000C1
-:104FC00000000000000000000000000000000000E1
-:104FD00000000000000000000000000000000000D1
-:104FE0000000000000300031000000000000000060
-:104FF00000000000000000000000000000000000B1
-:1050000000000000000000000000000000000000A0
-:10501000003100520000000000000000000000000D
-:105020000000000000000000000000000000000080
-:105030000000000000000000000000000052008995
-:1050400000000000000000000089008D008D00912C
-:1050500000910095009500990099009D009D00A188
-:1050600000A100A500A500A900A900AE00AE00B1F6
-:1050700000B100B4000000000000000000000000CB
-:105080000000000000000000000000000000000020
-:105090000000000000B40309030903130313031DF8
-:1050A000031D03240324032B032B03320332033990
-:1050B00003390340034003470347034E034E0355A0
-:1050C00000000000000000000000000000000000E0
-:1050D00000000000000000000000000000000000D0
-:1050E00000000000000000000000000000000000C0
-:1050F00000000000000000000000000000000000B0
-:10510000000000000000000000000000000000009F
-:10511000000000000000000000000000000000008F
-:10512000000000000000000000000000000000007F
-:10513000000000000000000000000000000000006F
-:10514000000000000000000000000000000000005F
-:10515000000000000000000000000000000000004F
-:10516000000000000000000000000000000000003F
-:105170000355035B0000000000000000035B035CBC
-:10518000035C035D035D035E035E035F035F036017
-:1051900003600361036103620362036300000000B4
-:1051A00000000000000000000000000000000000FF
-:1051B00000000000000000000000000000000000EF
-:1051C00000000000000000000363036D036D037B1B
-:1051D000037B0389000000000000000000000000C5
-:1051E00000000000000000000000000000000000BF
-:1051F00000000000000000000000000000000000AF
-:10520000000000000000000000000000000000009E
-:10521000000000000000000000000000000000008E
-:105220000389038A00000000000000000000000065
-:10523000000000000000000000000000000000006E
-:10524000000000000000000000000000038A03D6F8
-:10525000000000000000000000000000000000004E
-:10526000000000000000000000000000000000003E
-:10527000000000000000000003D604010000000050
-:10528000000000000000000000000000000000001E
-:10529000000000000000000000000000000000000E
-:1052A00000000000040104330000000000000000C2
-:1052B0000433043A043A0441044104480448044FC6
-:1052C000044F04560456045D045D04640464046BD6
-:1052D000046B04A4000000000000000004A404A863
-:1052E00004A804AC04AC04B004B004B404B404B81E
-:1052F00004B804BC04BC04C004C004C404C4051342
-:105300000513052A052A05410541054305430545C1
-:1053100005450547054705490549054B054B054D1D
-:10532000054D054F054F0551055105E805E805E90F
-:1053300005E905EA05EA05EF05EF05F405F405F9C9
-:1053400005F905FE05FE0603060306080608060D18
-:10535000060D0612061206130000000000000000F1
-:10536000000000000000000000000000000000003D
-:10537000000000000000000000000000000000002D
-:1053800006130624000000000000000000000000DA
-:10539000000000000000000000000000000000000D
-:1053A0000000000000000000000000000624063994
-:1053B0000639063C063C063F0000000000000000E5
-:1053C00000000000000000000000000000000000DD
-:1053D0000000000000000000063F0675000000000D
-:1053E00000000000000000000000000000000000BD
-:1053F00000000000000000000000000000000000AD
-:1054000000000000067507780000000000000000A2
-:10541000000000000000000000000000000000008C
-:10542000000000000000000000000000000000007C
-:105430000778077F077F078307830787000000003F
-:10544000000000000000000000000000000000005C
-:10545000000000000000000000000000078707C8EF
-:10546000000000000000000007C807D107D107DADC
-:1054700007DA07E307E307EC07EC07F507F507FE94
-:1054800007FE080708070810081008670867087C67
-:10549000087C089108910894089408970897089A3E
-:1054A000089A089D089D08A008A008A308A308A6BC
-:1054B00008A608A908A908B2000000000000000022
-:1054C00000000000000000000000000000000000DC
-:1054D00000000000000000000000000000000000CC
-:1054E00008B208B800000000000000000000000042
-:1054F00000000000000000000000000000000000AC
-:1055000000000000000000000000000008B808BB18
-:10551000000000000000000000000000000000008B
-:10552000000000000000000000000000000000007B
-:10553000000000000000000008BB08C100000000DF
-:10554000000000000000000000000000000000005B
-:10555000000000000000000000000000000000004B
-:10556000000000000000000000000000000000003B
-:1055700008C108D008D008DF08DF08EE08EE08FDF3
-:1055800008FD090C090C091B091B092A092A0939FC
-:10559000093909AA00000000000000000000000016
-:1055A00000000000000000000000000000000000FB
-:1055B00000000000000000000000000009AA09BF70
-:1055C00009BF09D009D009E109E109E209E209E3CB
-:1055D00009E309E409E409E509E509E609E609E75B
-:1055E00009E709E809E809E90000000000000000F7
-:1055F00000000000000000000000000000000000AB
-:10560000000000000000000000000000000000009A
-:10561000000000000000000000000000000000008A
-:10562000000000000000000000000000000000007A
-:10563000000000000000000000000000000000006A
-:10564000000000000000000000000000000000005A
-:10565000000000000000000000000000000000004A
-:10566000000000000000000000000000000000003A
-:10567000000000000000000000000000000000002A
-:10568000000000000000000000000000000000001A
-:10569000000000000000000000000000000000000A
-:1056A00000000000000000000000000000000000FA
-:1056B00000000000000000000000000000000000EA
-:1056C000000000000000000000010000000204C013
-:1056D0000003098000040E4000051300000617C0F7
-:1056E00000071C800008214000092600000A2AC08B
-:1056F000000B2F80000C3440000D3900000E3DC01F
-:10570000000F42800010474000114C00001250C0B2
-:105710000013558000145A4000155F00001663C046
-:105720000017688000186D4000197200001A76C0DA
-:10573000001B7B80001C8040001D8500001E89C06E
-:10574000001F8E80000093400000200000004000F9
-:1057500000006000000080000000A0000000C00009
-:105760000000E000000100000001200000014000F6
-:1057700000016000000180000001A0000001C000E5
-:105780000001E000000200000002200000024000D2
-:1057900000026000000280000002A0000002C000C1
-:1057A0000002E000000300000003200000034000AE
-:1057B00000036000000380000003A0000003C0009D
-:1057C0000003E0000004000000042000000440008A
-:1057D00000046000000480000004A0000004C00079
-:1057E0000004E00000050000000520000005400066
-:1057F00000056000000580000005A0000005C00055
-:105800000005E00000060000000620000006400041
-:1058100000066000000680000006A0000006C00030
-:105820000006E0000007000000072000000740001D
-:1058300000076000000780000007A0000007C0000C
-:105840000007E000000800000008200000084000F9
-:1058500000086000000880000008A0000008C000E8
-:105860000008E000000900000009200000094000D5
-:1058700000096000000980000009A0000009C000C4
-:105880000009E000000A0000000A2000000A4000B1
-:10589000000A6000000A8000000AA000000AC000A0
-:1058A000000AE000000B0000000B2000000B40008D
-:1058B000000B6000000B8000000BA000000BC0007C
-:1058C000000BE000000C0000000C2000000C400069
-:1058D000000C6000000C8000000CA000000CC00058
-:1058E000000CE000000D0000000D2000000D400045
-:1058F000000D6000000D8000000DA000000DC00034
-:10590000000DE000000E0000000E2000000E400020
-:10591000000E6000000E8000000EA000000EC0000F
-:10592000000EE000000F0000000F2000000F4000FC
-:10593000000F6000000F8000000FA000000FC000EB
-:10594000000FE000001000000010200000104000D8
-:1059500000106000001080000010A0000010C000C7
-:105960000010E000001100000011200000114000B4
-:1059700000116000001180000011A0000011C000A3
-:105980000011E00000120000001220000012400090
-:1059900000126000001280000012A0000012C0007F
-:1059A0000012E0000013000000132000001340006C
-:1059B00000136000001380000013A0000013C0005B
-:1059C0000013E00000140000001420000014400048
-:1059D00000146000001480000014A0000014C00037
-:1059E0000014E00000150000001520000015400024
-:1059F00000156000001580000015A0000015C00013
-:105A00000015E000001600000016200000164000FF
-:105A100000166000001680000016A0000016C000EE
-:105A20000016E000001700000017200000174000DB
-:105A300000176000001780000017A0000017C000CA
-:105A40000017E000001800000018200000184000B7
-:105A500000186000001880000018A0000018C000A6
-:105A60000018E00000190000001920000019400093
-:105A700000196000001980000019A0000019C00082
-:105A80000019E000001A0000001A2000001A40006F
-:105A9000001A6000001A8000001AA000001AC0005E
-:105AA000001AE000001B0000001B2000001B40004B
-:105AB000001B6000001B8000001BA000001BC0003A
-:105AC000001BE000001C0000001C2000001C400027
-:105AD000001C6000001C8000001CA000001CC00016
-:105AE000001CE000001D0000001D2000001D400003
-:105AF000001D6000001D8000001DA000001DC000F2
-:105B0000001DE000001E0000001E2000001E4000DE
-:105B1000001E6000001E8000001EA000001EC000CD
-:105B2000001EE000001F0000001F2000001F4000BA
-:105B3000001F6000001F8000001FA000001FC000A9
-:105B4000001FE00000200000002020000020400096
-:105B500000206000002080000020A0000020C00085
-:105B60000020E00000210000002120000021400072
-:105B700000216000002180000021A0000021C00061
-:105B80000021E0000022000000222000002240004E
-:105B900000226000002280000022A0000022C0003D
-:105BA0000022E0000023000000232000002340002A
-:105BB00000236000002380000023A0000023C00019
-:105BC0000023E00000240000002420000024400006
-:105BD00000246000002480000024A0000024C000F5
-:105BE0000024E000002500000025200000254000E2
-:105BF00000256000002580000025A0000025C000D1
-:105C00000025E000002600000026200000264000BD
-:105C100000266000002680000026A0000026C000AC
-:105C20000026E00000270000002720000027400099
-:105C300000276000002780000027A0000027C00088
-:105C40000027E00000280000002820000028400075
-:105C500000286000002880000028A0000028C00064
-:105C60000028E00000290000002920000029400051
-:105C700000296000002980000029A0000029C00040
-:105C80000029E000002A0000002A2000002A40002D
-:105C9000002A6000002A8000002AA000002AC0001C
-:105CA000002AE000002B0000002B2000002B400009
-:105CB000002B6000002B8000002BA000002BC000F8
-:105CC000002BE000002C0000002C2000002C4000E5
-:105CD000002C6000002C8000002CA000002CC000D4
-:105CE000002CE000002D0000002D2000002D4000C1
-:105CF000002D6000002D8000002DA000002DC000B0
-:105D0000002DE000002E0000002E2000002E40009C
-:105D1000002E6000002E8000002EA000002EC0008B
-:105D2000002EE000002F0000002F2000002F400078
-:105D3000002F6000002F8000002FA000002FC00067
-:105D4000002FE00000300000003020000030400054
-:105D500000306000003080000030A0000030C00043
-:105D60000030E00000310000003120000031400030
-:105D700000316000003180000031A0000031C0001F
-:105D80000031E0000032000000322000003240000C
-:105D900000326000003280000032A0000032C000FB
-:105DA0000032E000003300000033200000334000E8
-:105DB00000336000003380000033A0000033C000D7
-:105DC0000033E000003400000034200000344000C4
-:105DD00000346000003480000034A0000034C000B3
-:105DE0000034E000003500000035200000354000A0
-:105DF00000356000003580000035A0000035C0008F
-:105E00000035E0000036000000362000003640007B
-:105E100000366000003680000036A0000036C0006A
-:105E20000036E00000370000003720000037400057
-:105E300000376000003780000037A0000037C00046
-:105E40000037E00000380000003820000038400033
-:105E500000386000003880000038A0000038C00022
-:105E60000038E0000039000000392000003940000F
-:105E700000396000003980000039A0000039C000FE
-:105E80000039E000003A0000003A2000003A4000EB
-:105E9000003A6000003A8000003AA000003AC000DA
-:105EA000003AE000003B0000003B2000003B4000C7
-:105EB000003B6000003B8000003BA000003BC000B6
-:105EC000003BE000003C0000003C2000003C4000A3
-:105ED000003C6000003C8000003CA000003CC00092
-:105EE000003CE000003D0000003D2000003D40007F
-:105EF000003D6000003D8000003DA000003DC0006E
-:105F0000003DE000003E0000003E2000003E40005A
-:105F1000003E6000003E8000003EA000003EC00049
-:105F2000003EE000003F0000003F2000003F400036
-:105F3000003F6000003F8000003FA000003FC00025
-:105F4000003FE000003FE00100000000000001FF12
-:105F50000000020000007FF800007FF80000014010
-:105F600000003500000000010000FF0000000000FC
-:105F70000000FF00000000000000FF000000000023
-:105F80000000FF00000000000000FF000000000013
-:105F90000000FF00000000000000FF000000000003
-:105FA0000000FF000000000000000000140AFF00D5
-:105FB00000000001000000000020100100000000AF
-:105FC0000100900000000100000090020000900419
-:105FD00000009006000090080000900A0000900C5D
-:105FE0000000900E0000901000009012000090142D
-:105FF00000009016000090180000901A0000901CFD
-:106000000000901E000090200000902200009024CC
-:1060100000009026000090280000902A0000902C9C
-:106020000000902E0000903000009032000090346C
-:1060300000009036000090380000903A0000903C3C
-:106040000000903E0000904000009042000090440C
-:1060500000009046000090480000904A0000904CDC
-:106060000000904E000090500000905200009054AC
-:1060700000009056000090580000905A0000905C7C
-:106080000000905E0000906000009062000090644C
-:1060900000009066000090680000906A0000906C1C
-:1060A0000000906E000090700000907200009074EC
-:1060B00000009076000090780000907A0000907CBC
-:1060C0000000907E0000908000009082000090848C
-:1060D00000009086000090880000908A0000908C5C
-:1060E0000000908E0000909000009092000090942C
-:1060F00000009096000090980000909A0000909CFC
-:106100000000909E000090A0000090A2000090A4CB
-:10611000000090A6000090A8000090AA000090AC9B
-:10612000000090AE000090B0000090B2000090B46B
-:10613000000090B6000090B8000090BA000090BC3B
-:10614000000090BE000090C0000090C2000090C40B
-:10615000000090C6000090C8000090CA000090CCDB
-:10616000000090CE000090D0000090D2000090D4AB
-:10617000000090D6000090D8000090DA000090DC7B
-:10618000000090DE000090E0000090E2000090E44B
-:10619000000090E6000090E8000090EA000090EC1B
-:1061A000000090EE000090F0000090F2000090F4EB
-:1061B000000090F6000090F8000090FA000090FCBB
-:1061C000000090FE00009100000091020000910488
-:1061D00000009106000091080000910A0000910C57
-:1061E0000000910E00009110000091120000911427
-:1061F00000009116000091180000911A0000911CF7
-:106200000000911E000091200000912200009124C6
-:1062100000009126000091280000912A0000912C96
-:106220000000912E00009130000091320000913466
-:1062300000009136000091380000913A0000913C36
-:106240000000913E00009140000091420000914406
-:1062500000009146000091480000914A0000914CD6
-:106260000000914E000091500000915200009154A6
-:1062700000009156000091580000915A0000915C76
-:106280000000915E00009160000091620000916446
-:1062900000009166000091680000916A0000916C16
-:1062A0000000916E000091700000917200009174E6
-:1062B00000009176000091780000917A0000917CB6
-:1062C0000000917E00009180000091820000918486
-:1062D00000009186000091880000918A0000918C56
-:1062E0000000918E00009190000091920000919426
-:1062F00000009196000091980000919A0000919CF6
-:106300000000919E000091A0000091A2000091A4C5
-:10631000000091A6000091A8000091AA000091AC95
-:10632000000091AE000091B0000091B2000091B465
-:10633000000091B6000091B8000091BA000091BC35
-:10634000000091BE000091C0000091C2000091C405
-:10635000000091C6000091C8000091CA000091CCD5
-:10636000000091CE000091D0000091D2000091D4A5
-:10637000000091D6000091D8000091DA000091DC75
-:10638000000091DE000091E0000091E2000091E445
-:10639000000091E6000091E8000091EA000091EC15
-:1063A000000091EE000091F0000091F2000091F4E5
-:1063B000000091F6000091F8000091FA000091FCB5
-:1063C000000091FEFFFFFFFFFFFFFFFFFFFFFFFF4A
-:1063D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD
-:1063E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD
-:1063F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD
-:10640000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C
-:10641000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8C
-:10642000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C
-:10643000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C
-:10644000FFFFFFFF0000000300BEBC2000000000B3
-:10645000000000050000000300BEBC20000000009A
-:10646000000000050000000300BEBC20000000008A
-:10647000000000050000000300BEBC20000000007A
-:10648000000000050000000300BEBC20000000006A
-:10649000000000050000000300BEBC20000000005A
-:1064A000000000050000000300BEBC20000000004A
-:1064B000000000050000000300BEBC20000000003A
-:1064C0000000000500002000000040C000006180C6
-:1064D000000082400000A3000000C3C00000E48070
-:1064E0000001054000012600000146C00001678050
-:1064F000000188400001A9000001C9C00001EA8034
-:1065000000020B4000022C0000024CC000026D8013
-:1065100000028E400002AF000002CFC00002F080F7
-:10652000000011400000800000010380000187008E
-:1065300000020A8000028E00000311800003950013
-:106540000004188000049C0000051F800005A300C3
-:10655000000626800006AA0000072D800007B10073
-:10656000000834800008B80000093B800009BF0023
-:10657000000A4280000AC600000B4980000BCD00D3
-:10658000000C5080000CD400000D578000005B0010
-:1065900000007FF800007FF8000000D50000150023
-:1065A0000000FF00000000000000FF0000000000ED
-:1065B0000000FF00000000000000FF0000000000DD
-:1065C0000000FF00000000000000FF0000000000CD
-:1065D0000000FF00000000000000FF0000000000BD
-:1065E000000019000000000000000000FFFFFFFF96
-:1065F0000000000003938700000000000393870061
-:1066000000007FF800007FF80000068E00003500D3
-:106610000000FF000FFFFFFF0000FF000FFFFFFF64
-:10662000000000FF0000FF000FFFFFFF0000FF0061
-:106630000FFFFFFF000000FF0000FF000FFFFFFF44
-:106640000000FF000FFFFFFF000000FF0000FF0041
-:106650000FFFFFFF0000FF000FFFFFFF000000FF24
-:106660000000FF000FFFFFFF0000FF000FFFFFFF14
-:10667000000000FF0000FF000FFFFFFF0000FF0011
-:106680000FFFFFFF000000FF0000FF000FFFFFFFF4
-:106690000000FF000FFFFFFF000000FF0000FF00F1
-:1066A0000FFFFFFF0000FF000FFFFFFF000000FFD4
-:1066B0000000FF000FFFFFFF0000FF000FFFFFFFC4
-:1066C000000000FF0000FF000FFFFFFF0000FF00C1
-:1066D0000FFFFFFF000000FF0000FF000FFFFFFFA4
-:1066E0000000FF000FFFFFFF000000FF0000FF00A1
-:1066F0000FFFFFFF0000FF000FFFFFFF000000FF84
-:106700000000FF000FFFFFFF0000FF000FFFFFFF73
-:10671000000000FF0000FF000FFFFFFF0000FF0070
-:106720000FFFFFFF000000FF0000FF000FFFFFFF53
-:106730000000FF000FFFFFFF000000FF0000FF0050
-:106740000FFFFFFF0000FF000FFFFFFF000000FF33
-:106750000000FF000FFFFFFF0000FF000FFFFFFF23
-:10676000000000FF0000FF000FFFFFFF0000FF0020
-:106770000FFFFFFF000000FF0000FF000FFFFFFF03
-:106780000000FF000FFFFFFF000000FF0000FF0000
-:106790000FFFFFFF0000FF000FFFFFFF000000FFE3
-:1067A0000000FF000FFFFFFF0000FF000FFFFFFFD3
-:1067B000000000FF0000FF000FFFFFFF0000FF00D0
-:1067C0000FFFFFFF000000FF0000FF000FFFFFFFB3
-:1067D0000000FF000FFFFFFF000000FF0000FF00B0
-:1067E0000FFFFFFF0000FF000FFFFFFF000000FF93
-:1067F0000000FF000FFFFFFF0000FF000FFFFFFF83
-:10680000000000FF0000FF000FFFFFFF0000FF007F
-:106810000FFFFFFF000000FF0000FF000FFFFFFF62
-:106820000000FF000FFFFFFF000000FF0000FF005F
-:106830000FFFFFFF0000FF000FFFFFFF000000FF42
-:106840000000FF000FFFFFFF0000FF000FFFFFFF32
-:10685000000000FF0000FF000FFFFFFF0000FF002F
-:106860000FFFFFFF000000FF0000FF000FFFFFFF12
-:106870000000FF000FFFFFFF000000FF0000FF000F
-:106880000FFFFFFF0000FF000FFFFFFF000000FFF2
-:10689000000000FF000000FF000000FF000000FFFC
-:1068A000000000FF000000FF000000FF000000FFEC
-:1068B0000000FF00000000000000FF0000000000DA
-:1068C0000000FF00000000000000FF0000000000CA
-:1068D0000000FF00000000000000FF0000000000BA
-:1068E0000000FF00000000000000FF0000000000AA
-:1068F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8
-:10690000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF97
-:10691000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87
-:10692000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77
-:10693000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF67
-:10694000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF57
-:10695000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF47
-:10696000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF37
-:106970000000100000002080000031000000418075
-:10698000000052000000628000007300000083805D
-:10699000000094000000A4800000B5000000C58045
-:1069A0000000D6000000E6800000F700000107802C
-:1069B0000001180000012880000139000001498011
-:1069C00000015A0000016A8000017B0000018B80F9
-:1069D00000019C000001AC800001BD000001CD80E1
-:1069E0000001DE000001EE800001FF0000000F80CA
-:1069F00000007FF800007FF800000344000035002D
-:106A000010000000000028AD00010001000902068E
-:106A1000CCCCCCC5FFFFFFFFFFFFFFFF7058103C41
-:106A20000000FF00000000000000FF000000000068
-:106A30000000FF00000000000000FF000000000058
-:106A40000000FF00000000000000FF000000000048
-:106A50000000FF00000000000000FF000000000038
-:106A60000000000000000001CCCC0201CCCCCCCC5A
-:106A7000CCCC0201CCCCCCCCCCCC0201CCCCCCCC80
-:106A8000CCCC0201CCCCCCCCCCCC0201CCCCCCCC70
-:106A9000CCCC0201CCCCCCCCCCCC0201CCCCCCCC60
-:106AA000CCCC0201CCCCCCCC00000000FFFFFFFF1F
-:106AB000000E0000011600D6002625A0002625A005
-:106AC000002625A0002625A000720000012300F367
-:106AD000002625A0002625A0002625A0002625A00A
-:106AE0000000FFFF000000000000FFFF00000000AA
-:106AF0000000FFFF000000000000FFFF000000009A
-:106B00000000FFFF000000000000FFFF0000000089
-:106B10000000FFFF000000000000FFFF0000000079
-:106B20000000FFFF000000000000FFFF0000000069
-:106B30000000FFFF000000000000FFFF0000000059
-:106B40000000FFFF000000000000FFFF0000000049
-:106B50000000FFFF000000000000FFFF0000000039
-:106B60000000FFFF000000000000FFFF0000000029
-:106B70000000FFFF000000000000FFFF0000000019
-:106B80000000FFFF000000000000FFFF0000000009
-:106B90000000FFFF000000000000FFFF00000000F9
-:106BA0000000FFFF000000000000FFFF00000000E9
-:106BB0000000FFFF000000000000FFFF00000000D9
-:106BC0000000FFFF000000000000FFFF00000000C9
-:106BD0000000FFFF000000000000FFFF00000000B9
-:106BE0000000FFFF000000000000FFFF00000000A9
-:106BF0000000FFFF000000000000FFFF0000000099
-:106C00000000FFFF000000000000FFFF0000000088
-:106C10000000FFFF000000000000FFFF0000000078
-:106C20000000FFFF000000000000FFFF0000000068
-:106C30000000FFFF000000000000FFFF0000000058
-:106C40000000FFFF000000000000FFFF0000000048
-:106C50000000FFFF000000000000FFFF0000000038
-:106C60000000FFFF000000000000FFFF0000000028
-:106C70000000FFFF000000000000FFFF0000000018
-:106C80000000FFFF000000000000FFFF0000000008
-:106C90000000FFFF000000000000FFFF00000000F8
-:106CA0000000FFFF000000000000FFFF00000000E8
-:106CB0000000FFFF000000000000FFFF00000000D8
-:106CC0000000FFFF000000000000FFFF00000000C8
-:106CD0000000FFFF000000000000FFFF00000000B8
-:106CE000FFFFFFF3318FFFFF0C30C30CC30C30C329
-:106CF000CF3CF300F3CF3CF30000CF3CCDCDCDCD66
-:106D0000FFFFFFF130EFFFFF0C30C30CC30C30C3AB
-:106D1000CF3CF300F3CF3CF30001CF3CCDCDCDCD44
-:106D2000FFFFFFF6305FFFFF0C30C30CC30C30C316
-:106D3000CF3CF300F3CF3CF30002CF3CCDCDCDCD23
-:106D4000FFFFF4061CBFFFFF0C30C305C30C30C3AC
-:106D5000CF300014F3CF3CF30004CF3CCDCDCDCDEC
-:106D6000FFFFFFF2304FFFFF0C30C30CC30C30C3EA
-:106D7000CF3CF300F3CF3CF30008CF3CCDCDCDCDDD
-:106D8000FFFFFFFA302FFFFF0C30C30CC30C30C3E2
-:106D9000CF3CF300F3CF3CF30010CF3CCDCDCDCDB5
-:106DA000FFFFFFF731EFFFFF0C30C30CC30C30C304
-:106DB000CF3CF300F3CF3CF30020CF3CCDCDCDCD85
-:106DC000FFFFFFF5302FFFFF0C30C30CC30C30C3A7
-:106DD000CF3CF300F3CF3CF30040CF3CCDCDCDCD45
-:106DE000FFFFFFF3318FFFFF0C30C30CC30C30C328
-:106DF000CF3CF300F3CF3CF30000CF3CCDCDCDCD65
-:106E0000FFFFFFF1310FFFFF0C30C30CC30C30C389
-:106E1000CF3CF300F3CF3CF30001CF3CCDCDCDCD43
-:106E2000FFFFFFF6305FFFFF0C30C30CC30C30C315
-:106E3000CF3CF300F3CF3CF30002CF3CCDCDCDCD22
-:106E4000FFFFF4061CBFFFFF0C30C305C30C30C3AB
-:106E5000CF300014F3CF3CF30004CF3CCDCDCDCDEB
-:106E6000FFFFFFF2304FFFFF0C30C30CC30C30C3E9
-:106E7000CF3CF300F3CF3CF30008CF3CCDCDCDCDDC
-:106E8000FFFFFFFA302FFFFF0C30C30CC30C30C3E1
-:106E9000CF3CF300F3CF3CF30010CF3CCDCDCDCDB4
-:106EA000FFFFFFF730EFFFFF0C30C30CC30C30C304
-:106EB000CF3CF300F3CF3CF30020CF3CCDCDCDCD84
-:106EC000FFFFFFF5304FFFFF0C30C30CC30C30C386
-:106ED000CF3CF300F3CF3CF30040CF3CCDCDCDCD44
-:106EE000FFFFFFFF30CFFFFF0C30C30CC30C30C3DC
-:106EF000CF3CF3CCF3CF3CF30000CF3CCDCDCDCD98
-:106F0000FFFFFFFF30CFFFFF0C30C30CC30C30C3BB
-:106F1000CF3CF3CCF3CF3CF30001CF3CCDCDCDCD76
-:106F2000FFFFFFFF30CFFFFF0C30C30CC30C30C39B
-:106F3000CF3CF3CCF3CF3CF30002CF3CCDCDCDCD55
-:106F4000FFFFFFFF30CFFFFF0C30C30CC30C30C37B
-:106F5000CF3CF3CCF3CF3CF30004CF3CCDCDCDCD33
-:106F6000FFFFFFFF30CFFFFF0C30C30CC30C30C35B
-:106F7000CF3CF3CCF3CF3CF30008CF3CCDCDCDCD0F
-:106F8000FFFFFFFF30CFFFFF0C30C30CC30C30C33B
-:106F9000CF3CF3CCF3CF3CF30010CF3CCDCDCDCDE7
-:106FA000FFFFFFFF30CFFFFF0C30C30CC30C30C31B
-:106FB000CF3CF3CCF3CF3CF30020CF3CCDCDCDCDB7
-:106FC000FFFFFFFF30CFFFFF0C30C30CC30C30C3FB
-:106FD000CF3CF3CCF3CF3CF30040CF3CCDCDCDCD77
-:106FE000FFFFFFF3320FFFFF0C30C30CC30C30C3A5
-:106FF000CF3CF300F3CF3CF30000CF3CCDCDCDCD63
-:10700000FFFFFFF1310FFFFF0C30C30CC30C30C387
-:10701000CF3CF300F3CF3CF30001CF3CCDCDCDCD41
-:10702000FFFFFFF6305FFFFF0C30C30CC30C30C313
-:10703000CF3CF300F3CF3CF30002CF3CCDCDCDCD20
-:10704000FFFFF4061CBFFFFF0C30C305C30C30C3A9
-:10705000CF300014F3CF3CF30004CF3CCDCDCDCDE9
-:10706000FFFFFFF2304FFFFF0C30C30CC30C30C3E7
-:10707000CF3CF300F3CF3CF30008CF3CCDCDCDCDDA
-:10708000FFFFFF8A042FFFFF0C30C30CC30C30C37B
-:10709000CF3CC000F3CF3CF30010CF3CCDCDCDCDE5
-:1070A000FFFFFF9705CFFFFF0C30C30CC30C30C3AD
-:1070B000CF3CC000F3CF3CF30020CF3CCDCDCDCDB5
-:1070C000FFFFFFF5310FFFFF0C30C30CC30C30C3C3
-:1070D000CF3CF300F3CF3CF30040CF3CCDCDCDCD42
-:1070E000FFFFFFF3320FFFFF0C30C30CC30C30C3A4
-:1070F000CF3CF300F3CF3CF30000CF3CCDCDCDCD62
-:10710000FFFFFFF1302FFFFF0C30C30CC30C30C367
-:10711000CF3CF300F3CF3CF30001CF3CCDCDCDCD40
-:10712000FFFFFFF6305FFFFF0C30C30CC30C30C312
-:10713000CF3CF300F3CF3CF30002CF3CCDCDCDCD1F
-:10714000FFFFFF061CBFFFFF0C30C30CC30C30C396
-:10715000CF3CC014F3CF3CF30004CF3CCDCDCDCD1C
-:10716000FFFFFFF2304FFFFF0C30C30CC30C30C3E6
-:10717000CF3CF300F3CF3CF30008CF3CCDCDCDCDD9
-:10718000FFFFFFFA302FFFFF0C30C30CC30C30C3DE
-:10719000CF3CF300F3CF3CF30010CF3CCDCDCDCDB1
-:1071A000FFFFFFF731CFFFFF0C30C30CC30C30C320
-:1071B000CF3CF300F3CF3CF30020CF3CCDCDCDCD81
-:1071C000FFFFFFFF30CFFFFF0C30C30CC30C30C3F9
-:1071D000CF3CF3CCF3CF3CF30040CF3CCDCDCDCD75
-:1071E000FFFFFFFF30CFFFFF0C30C30CC30C30C3D9
-:1071F000CF3CF3CCF3CF3CF30000CF3CCDCDCDCD95
-:10720000FFFFFFFF30CFFFFF0C30C30CC30C30C3B8
-:10721000CF3CF3CCF3CF3CF30001CF3CCDCDCDCD73
-:10722000FFFFFFFF30CFFFFF0C30C30CC30C30C398
-:10723000CF3CF3CCF3CF3CF30002CF3CCDCDCDCD52
-:10724000FFFFFFFF30CFFFFF0C30C30CC30C30C378
-:10725000CF3CF3CCF3CF3CF30004CF3CCDCDCDCD30
-:10726000FFFFFFFF30CFFFFF0C30C30CC30C30C358
-:10727000CF3CF3CCF3CF3CF30008CF3CCDCDCDCD0C
-:10728000FFFFFFFF30CFFFFF0C30C30CC30C30C338
-:10729000CF3CF3CCF3CF3CF30010CF3CCDCDCDCDE4
-:1072A000FFFFFFFF30CFFFFF0C30C30CC30C30C318
-:1072B000CF3CF3CCF3CF3CF30020CF3CCDCDCDCDB4
-:1072C000FFFFFFFF30CFFFFF0C30C30CC30C30C3F8
-:1072D000CF3CF3CCF3CF3CF30040CF3CCDCDCDCD74
-:1072E000FFFFFFFF30CFFFFF0C30C30CC30C30C3D8
-:1072F000CF3CF3CCF3CF3CF30000CF3CCDCDCDCD94
-:10730000FFFFFFFF30CFFFFF0C30C30CC30C30C3B7
-:10731000CF3CF3CCF3CF3CF30001CF3CCDCDCDCD72
-:10732000FFFFFFFF30CFFFFF0C30C30CC30C30C397
-:10733000CF3CF3CCF3CF3CF30002CF3CCDCDCDCD51
-:10734000FFFFFFFF30CFFFFF0C30C30CC30C30C377
-:10735000CF3CF3CCF3CF3CF30004CF3CCDCDCDCD2F
-:10736000FFFFFFFF30CFFFFF0C30C30CC30C30C357
-:10737000CF3CF3CCF3CF3CF30008CF3CCDCDCDCD0B
-:10738000FFFFFFFF30CFFFFF0C30C30CC30C30C337
-:10739000CF3CF3CCF3CF3CF30010CF3CCDCDCDCDE3
-:1073A000FFFFFFFF30CFFFFF0C30C30CC30C30C317
-:1073B000CF3CF3CCF3CF3CF30020CF3CCDCDCDCDB3
-:1073C000FFFFFFFF30CFFFFF0C30C30CC30C30C3F7
-:1073D000CF3CF3CCF3CF3CF30040CF3CCDCDCDCD73
-:1073E000FFFFFFFF30CFFFFF0C30C30CC30C30C3D7
-:1073F000CF3CF3CCF3CF3CF30000CF3CCDCDCDCD93
-:10740000FFFFFFFF30CFFFFF0C30C30CC30C30C3B6
-:10741000CF3CF3CCF3CF3CF30001CF3CCDCDCDCD71
-:10742000FFFFFFFF30CFFFFF0C30C30CC30C30C396
-:10743000CF3CF3CCF3CF3CF30002CF3CCDCDCDCD50
-:10744000FFFFFFFF30CFFFFF0C30C30CC30C30C376
-:10745000CF3CF3CCF3CF3CF30004CF3CCDCDCDCD2E
-:10746000FFFFFFFF30CFFFFF0C30C30CC30C30C356
-:10747000CF3CF3CCF3CF3CF30008CF3CCDCDCDCD0A
-:10748000FFFFFFFF30CFFFFF0C30C30CC30C30C336
-:10749000CF3CF3CCF3CF3CF30010CF3CCDCDCDCDE2
-:1074A000FFFFFFFF30CFFFFF0C30C30CC30C30C316
-:1074B000CF3CF3CCF3CF3CF30020CF3CCDCDCDCDB2
-:1074C000FFFFFFFF30CFFFFF0C30C30CC30C30C3F6
-:1074D000CF3CF3CCF3CF3CF30040CF3CCDCDCDCD72
-:1074E000000C0000000700C000028130000B815832
-:1074F0000002021000010230000F024000010330C0
-:10750000000C0000000800C000028140000B8168F0
-:10751000000202200001024000070250000202C0E7
-:10752000001000000008010000028180000B81A80B
-:107530000002026000018280000E82980008038031
-:107540000010000000010100000281100009013854
-:10755000000201C8000101E8000E01F8000002D895
-:10756000CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC5B
-:1075700000002000CCCCCCCCCCCCCCCCCCCCCCCC5B
-:10758000CCCCCCCC00002000CCCCCCCCCCCCCCCC4B
-:10759000CCCCCCCCCCCCCCCC040020000000000067
-:1075A0001F8B080000000000000BFB51CFC0F00350
-:1075B0008AB7B13130ECE644F0E98159181818F86F
-:1075C00099C8D7BF1168C04E20BE01C4075948D71B
-:1075D0007F551AC15E26C9C0700A8827883330B427
-:1075E0004A21C4ED651818EE01F92BA16272403DE5
-:1075F00073A4C977F3281E3CB8D014951F620CA160
-:107600005F9840E82234F950A8BCB81E842E36C5D5
-:107610006EAE841E71F6A7A9A0F2BD55F0ABCFD512
-:1076200040E5C7A2A90F81F2017EE9B234D8030078
-:1076300000000000000000001F8B08000000000098
-:10764000000BED7D0B7455D5B5E8DA9FB3CFFF6421
-:10765000278470123EEEC400C1063C4280A0A83BC5
-:10766000FC1A7DD41E1025E5A11C446B004922A6FE
-:10767000D78C96D76CC8870450E3E751BD457BA0F3
-:10768000D88B0E5BA3A68ABDB43D887AA9C3DB2242
-:107690005AA52D7A83FA2C58A0B1572ABD4FCB5B3F
-:1076A00073AEB592BD77CEC9C74F47EF788D43769D
-:1076B000D6DEEB3BFF6BCEB95634D94FF22E27E422
-:1076C0001CFCD0A7291142A6F73DC92D5932C92368
-:1076D000E41B3E823F1FF923534816210D3EF6BCA2
-:1076E0003D10D905CF2D8D84A426C2F771491221F2
-:1076F000244848899A0B2D02B1870BE15977617CA8
-:10770000323E67C23387C8848C84F218FDBD20EBFB
-:10771000FB9C42FF399AA880F114F68AA8A43C96F3
-:10772000C2F6DF226446DF3C48DD57F578B86FDEED
-:10773000EEA7A26B24C5EB9E837F94E5598950E6A2
-:10774000FA0D47A5C79FB7D51F4FC2B9382F95A8C7
-:10775000382FDE9E108BD8E7E7EEE7A346F2F8F36A
-:10776000E3FBC32DD3B8026E6D8D3E7CB636EA24A2
-:10777000E5258436333B4BE93344CC5DA5FDDBCDB9
-:107780002312871F9F0F8C63D0FAF47F42E1DE9CA7
-:107790004B9241C0214938E0D61C5AEC33D3F42730
-:1077A0009E2497C2AD84CFB9A8FF7AFD302F0A0777
-:1077B0003FCC2B0D3C97C2BCA6F79F97BFD83DAFDF
-:1077C0006A6287CF70E7159844C821C0876A128221
-:1077D00078B9CDD19FAC9B56779AFE08A70BD5E020
-:1077E000EB1B229E822572DFF8000723E0A02F6F9B
-:1077F00034C7496F6EBA067820BE3A387CE20AE395
-:1078000007AB0F8FF4199A1D93803568F110E02DA6
-:107810009F30F8E557B7DE2A4F2194D53A0F4EA096
-:10782000F0CBEF5EB99040F9E8152780DF9ACBA640
-:1078300056CEA5F5B2CB63AF2CA04D423143027AB0
-:10784000DD0A9D15407F5FB32A68B909FAA365CBAD
-:10785000BACAB4106EA6036E1472864ACB1EF8B56F
-:10786000280DFC482F1EA473DEFEED33C1CF436C00
-:10787000F8437E5EEFA0CB8C78BF91E1CBA2FF01F5
-:10788000BE46101B5FD37EB22B35075EB25CE33C75
-:107890000ABF20BC6FFD9B8C97439EF41994CE3D8C
-:1078A000A5B29EA478CA26B16CB58CE263A14A4009
-:1078B0008EE5E4EA1290C360786926A412F89F4A24
-:1078C00007B2C826E77ECEF9AB60CDEE9DAD749CC5
-:1078D00033B34331A895AFD3B94EEDBF9E3B40BE05
-:1078E000786DE5B2E74802C7EB3C5844E76595C9B7
-:1078F000B18729DD6C2D3DACDBE5E3B15EF9E2A695
-:107900000F62A833B83CA0F0514A65D31FF9ECF4DC
-:10791000A17C4AFA08DFE8C4C770F1757A98F4F1DF
-:1079200059C71378EDCF571B055E7D847EDF52B2B9
-:1079300078407DD51FAF4F92046D172A2566324DD2
-:10794000BBFFB4EB0BF7D326DFDD72541935A36A06
-:10795000E74078CB75AE57F4EB6F508C7747D0A2E9
-:10796000AAA37CD5B81E688FDE63114A776740F6FC
-:107970005078281D17A5A04C8A49EC61D64D4AA223
-:10798000657FD44C6E413A48225EC4FCBC86EC90C4
-:10799000B36AAE530E932A4BB2CFDFDFA0E13C3483
-:1079A000182F17EC02DA2105851A2229A05B41AFB6
-:1079B000A092CE9D0F65A79DD1664C25E9F0A072DF
-:1079C000BC4B92A0D76F0D4DBEB8C75BE29CEF9049
-:1079D000DB8554E33DD1268D9CEE6BA792F7047EA8
-:1079E00028102F13761DC7D3660FD92B5D48E5C12C
-:1079F000986BC152209BE1D32C6A87C0932A9FCDFC
-:107A000063A6EA4057648FA4C23C71488A4742F596
-:107A10001DD40B4A06F623FBEA90FE9490894FF1A1
-:107A20003DF3BCD8F8BD655FA206F0531DD58C2D83
-:107A3000748E6B15D3D80874318DC9A7EAE88479A0
-:107A4000A0EF3C129BD7B7A57C5C879AD39687762C
-:107A50005906FBAE5AA52A7F2A7CDF3661207E229A
-:107A6000494F4FB70D9E6E7BF06689DA835FA2BFE8
-:107A7000CC2433018E7F8A2DCE4A0D80AFF71B0FA9
-:107A8000EAEAF83E7BD0FD7DAD42EAD2C98156C913
-:107A9000C7F8D26769601F8875AF0576A720DD1625
-:107AA000DBC4D69B9B8BF05DBBE717BA6AE3BFB51F
-:107AB00054CD78A7F65F8F80B7E8A7B77DF2A0A373
-:107AC000BDBB5D6F7F425E507B18E85CD041504A81
-:107AD0006C95E87B6F6CB105EA6CED63150CFF19D2
-:107AE000E6DF8BAF4F397FD16E30BAFAD3EEA656B0
-:107AF000D04FEF691D575D4CE9E8F74F28B14DF4C1
-:107B00006BF58E89F3C05E7A8FD3B7C0D389DD4D14
-:107B100079E9E823139E7E21F9711C415FD5F2F2C9
-:107B200001E96130FA7ACA4D5F9D577F21F475C82B
-:107B30004D5F1C1E273BD9FAC9FD23185E38BEDCF9
-:107B4000F8C988974FDBAE3F3DFD5AA27CEDEDBCF6
-:107B50003A3D3DF1F90A7C7DD6F90E4647798669B2
-:107B6000EA74FC51D48E91407F9491588ACE53A7E9
-:107B70000FD45B31A6B7845C12ED4F4BCC4E53C98A
-:107B80006BD85E21294B477BDB6967CC57E84BDA22
-:107B90004F7309497A715F64FA504F95A884E93FA1
-:107BA00033943F03EC08FEA3CC8EC1BAB3C0FE07EA
-:107BB000FD359BEB5F89DA5B747DA132E7BE37E070
-:107BC000B23F14BE5FE8676F0D737FEC97F9FE3824
-:107BD0004842A88FC4FE38037FF6EE8B395C476AB3
-:107BE000C494E9BAB5839EE42609B41B41FD4C8ECA
-:107BF0004A49E62F20256037AF970A62A00FE83E7A
-:107C0000AF278B7E7FEF070AEA878668DD8A1658E2
-:107C1000F6B50D13BBE9B8F7349269C59EBEF1EE17
-:107C2000513B7C00EFF6E2F50EBBF6BB52A250B61C
-:107C3000E91D7F549B563C0D8653DFEEA6F090293C
-:107C40002081FF02A1FBA22F18003FF6BE174EF6BF
-:107C5000B2D2BF9C0B364F011653B02F6DA7B63B67
-:107C6000B9188AA3A50A4A07ED1EFEDDFA4D05ECF8
-:107C700077DBFDACBC63D3AC8D169447F2FA561596
-:107C8000FB9ECFCAB76DFA4105EC0BDAB2E99AA9AF
-:107C9000BE6EF324ABE269F8FB365976D85F4DC669
-:107CA00082F2FF43D7E1F79917BD40E1498112B352
-:107CB0000CD26B97150ABF41C7DD952500FFD7147D
-:107CC00002F4EC3762F19B0CA43FA47B7FAE19DB7E
-:107CD000424B0DF4850CF528DE1E96605FC7EC3133
-:107CE000F0E79C43FAA57C41BFAFCFD6B13ED16D42
-:107CF000F659519F3DD68B2717DEEE557BFC80B79A
-:107D0000EF8DF9F01713693FD642390664F3BD0DC4
-:107D100045D92B6D787CCC37A70AF0489A73D12EC1
-:107D20008992DE1F13CA62DF5C403A2BC0781C4385
-:107D3000251FA1743A2EDE53012830AAF4E7708F74
-:107D40004BE6E9EFA15DA548E7BE34743BCA0D07D9
-:107D5000DAE3A845543E8D90483C9DDC5DA9E6A041
-:107D60003C185149D73B809FE09B549F30FB2CE14E
-:107D700003FF56A67132CDF333C073934CC71D4D2C
-:107D80009208A7C1E09A099EADD127B3515E7FCE7C
-:107D900070CDD4DE0DCF1112E397956A39F2CB5036
-:107DA000FD3B6D7C3FD5027E38FA6CE27E38777BF6
-:107DB000BFDA416269F0EB379CFE210DF625B67201
-:107DC000BD6C307D1072FB89189EDD7A6101D70B86
-:107DD0002D51AA17983C5C087A20C8E1DF02BB7ECF
-:107DE000909F6192B4E8F720F707915226FF7DF447
-:107DF0003FE0B751554E7DA00D511FBC2BC55F9084
-:107E0000910E8904F3BB5FEAB86202D04F3EB3C75C
-:107E1000A337B445133638D4CB4CDF097D962C16E6
-:107E2000FA8C20FCCEE37348920E3FE8C307362C51
-:107E3000CE42BFDD8D41871C8AB62EC6FDAF8D9E1A
-:107E4000D12FDAC1FDA399F0A76BC9443A7958A89C
-:107E5000307918317B52E0F34342CEE32E434ED6C5
-:107E60000CFEC4B10F8B4CED39783E5DEFCE8BE448
-:107E7000D826DA4E9DADA63C14BE6AF98B55127D0C
-:107E8000EE2C64F0B76611A4D390B1E08402FA58E6
-:107E9000ED467F4DA8D2BD2FB69515E8A7E77AD459
-:107EA000DF763FF500FBB8A13E9B28BCDEB6F13F74
-:107EB000855C4AA1EB50371003EC09D5A4223102AE
-:107EC0004F3D0FE8453563217C765754C2F3BCD94A
-:107ED000F14AD9A6075433BE05EA8FF8CA7DEDB042
-:107EE0005EF526595624C6073936789B4AA1633F6A
-:107EF00097ADBBFCA589D62AD4EF8646C617F69F58
-:107F000077BDAC72B9E7A417412703C8BBCF441FA4
-:107F10006FCAC25FEDC4BF834E8AFAF02BDA85FACE
-:107F2000F9AB9CF875973F6FBCFA014F141FE751EE
-:107F30003C017D9E379BD123B547D17E7AC0D76166
-:107F400002BC1F2836644BEA6B175672989FF92CB7
-:107F5000DD6851BBE7FE95DB4D68975F4C6580841B
-:107F6000CFB4FEA37A59C376542E542ACC6E97C050
-:107F70001E9FAF6CAB82F63B295E81DF77027F43A9
-:107F80007C20A1A11CAE97DB2B36D2BE5B8F4AB200
-:107F90000246ACBE14F1EBE7FCFE912751097EC806
-:107FA0002DFF4B26BB0CD04B03FBBD9A38BE4519A9
-:107FB000FC0D609F8CA9D3A702D833B5DB5E275791
-:107FC000A65B57B5C2F07F47DDE10E344F9F77EED9
-:107FD000473CCB4DA048D897542B36FA0E97317FAB
-:107FE0000749D0F5407D4E371F150E4CAF0FBAE64E
-:107FF0003F96C753DCF55E56B8BFCE60F03244FF03
-:108000001B07EE5FC0E76C9BC2E323D40043221E34
-:1080100049ECFA5BB9F15005BCA75CB709F0B55D56
-:1080200026D5CCDF1C473D14E1E3ED2CCFC1F60B88
-:10803000552647C79AFA16C0F7D866192C05F2B824
-:1080400062E0FB51CBEBF67B281EDA0B492C64E097
-:1080500010D8EF8BE335A4CBFC5CA6C7F2EB290963
-:10806000D07AF9A52469D0F6EDFB1FA8D068394273
-:108070003754600AFBCA193E7D252406A690C72204
-:1080800029997D4F424C5229EFB140951E183F036C
-:10809000F75F77E69298D7E8931B82AEEE6CBEC787
-:1080A0000F7AE481E27BAE9800FEC65215FDE4E44F
-:1080B000630A27E14F54205E163761BCF6596CDE27
-:1080C000F40DE253D5D9FAC7DC3F1BF9A43DFC34CB
-:1080D000CEC35A4762E3B15E8C60FC860A54F05707
-:1080E0003655337BD78D8FF524F1B832DD4EAF870F
-:1080F000906EDA3F51F8BEE0C58D60E78F835F690F
-:10810000F9974D7FDC381CBB45C40F85DDB245EDCA
-:1081100044BEB728CF815E12768CBFB813C7FDBFAF
-:108120009CDE87DABFBFC4E96F75DB356E7BA65E68
-:10813000D61DF6AB7B5D1F795257C0FCB6E4537E6B
-:108140004FA3077E03FA9AB6DF115DFCAB89465F49
-:108150003F7D72C8C0EFA23CE6AC86F8197A7D2A52
-:10816000F7608F6632BE1A2BE4D037285F0D107F80
-:10817000147CF511151287804FD40EA42F6296201F
-:108180005F097E51BA3BDACFA7F460D4CBE0B906E1
-:10819000FE2239B45C48E93D65B38784BC504B3B53
-:1081A000E313A5FE74F7A021231ECF94317F7596AB
-:1081B000D56D4293606927C6F5285DFD17D095AA55
-:1081C0002725C0EB98FB17E0BA7EA93056F7AB2CF9
-:1081D0007EEC5EC7CF397C89BE1BED793F1B8EB22A
-:1081E000F87D31363F579CBDFE5703C6D9FD319708
-:1081F0009D334C3F428ECAFD08DCEF3558FBE1C68B
-:10820000D795B323903E7ACB19E4ED4D2AE78BA3A3
-:10821000BB1C70E9070F65476CA0F9F9859FFE53F9
-:10822000C60550870D010E6E385EA23AFD879F3756
-:108230001CDDF1EF97B8DC1F4C1E044D33252BE0FD
-:108240003F23CCBF1322DCBFE3A4F79DCD32DA215C
-:10825000C1B0BC134CC9ACFA6ED4C1627C4AEF55B4
-:10826000AA8DDE47971E4A413BB73ECAA4870693B4
-:10827000B7AB7CE60D2ACAADF4FBF1BE7C03CA2580
-:1082800069F20D32E2B5EEF3C937182ABC7BFD9BCB
-:108290003C7FE0867241C7C6D2DF51B8AC3EE821D0
-:1082A000E897F998AECE16575BCDF78137F07DE4AD
-:1082B0008D241E818FA7885C09FC728A1C8E4CB3AA
-:1082C000C993FB548DF14B9BE76DF0AF8A78F94D64
-:1082D0001DAC2CE673F3FDCEF2D7C9E23CF0EB7D8A
-:1082E000FD3E0FE26BB5CBBFD6AC32FD7133A96B4F
-:1082F00005BCB5784815C8B11B74A28EA0A6EBBA10
-:10830000671E9CB19296BFCBED91F7A95C366C715C
-:10831000D035A1A406F87DA76BDAB59710689F6CDD
-:108320002D807D5A36C17DAB1BCEABDA9CF31B6C26
-:10833000FEEEF952F2C2F9669A87BA474A6B4F3F8E
-:1083400022E40DC757A6BC2A914FF50B20205ADF17
-:108350009A43D8BEF3AD60B209E535CBA71AACFDA0
-:108360002F55463F9FB6FDAB83B45FE7EB5900CC7A
-:10837000D6966BC5C12F24E28235A4CE1C4D7F5505
-:10838000F72DB246135BBDE810EB150F5C2FD3BC85
-:108390004FE83E4BBEB06FFEDF9512C7D434F3BF3B
-:1083A0005D49D440FF5EC083024F15F18D7E608A27
-:1083B000DF5A35D4266541BE5317EE03FD86EAA089
-:1083C000875AF805E45A09936BC112E777B77FF82B
-:1083D0004355C4E153C87F188236C07E08A514F007
-:1083E000DF94AB277BEBD3F16A605D1742298E7275
-:1083F000A35E67F56B8871D7EC32E43F8C3FD4B74E
-:108400009F8F71F5FA9106FA77551233B10F17DD88
-:10841000D59E9548D2A60F6BD51E0DF8AC96DA45C1
-:10842000F6F7EBA38AC34FEB7E7AA8E51C2A817D81
-:1084300092CCFC483A2DDBD6FDA70E89E7AF185940
-:108440004B06F0DFAD8F327FF00DEDE3B398DFD058
-:10845000297F4F3732BFDCBF3DF67D0DFCFCA71EE8
-:108460003D7615C07BEDBF2AC407F91B8F85490AED
-:10847000EDB1A406F6D89A2EC54CA6CDAF6862F130
-:10848000CFC7C388AF354F7A930B69FB354FBF33E6
-:1084900085D0F99DDED4F3E268B09B1F95581E820B
-:1084A000D53DE56AFA7E8D4A56A4F31B4CF630F9A9
-:1084B00073F2D96015F0B7B467FFF5D86FE7528F44
-:1084C000D7B6DF2EF678906F693D66973F2225C7B5
-:1084D0004BE9E6C7F23F4E3E22B1F9EDF524FD30FF
-:1084E000BF3D3BB5049D47ED9E0F509ECC7DFC8764
-:1084F000118043ED5EC5A1076AF72829EF147C1EA1
-:108500008327C48DA41940279C5EBAD661BCA8A657
-:1085100073EB07E0C7A8DDEB946B142EB114C0F524
-:108520000D25B610CA4FFD4BC4A0A07AFFD0C311D1
-:10853000802BED77A59605FAC649DFD0FFD99CFEC2
-:10854000FD11D283F1BADACE76365ED7577E0F7A36
-:10855000A5D6253FDF875FF2FBDB33D7785CF6CC0F
-:108560009EA1C5EBD6FEF0CC43161DF7E4937F78B1
-:10857000C8A2F3BFE5AFFFF9D0B7803F7FE6D74190
-:10858000FED73EFAEB08B1D163AD87F1E3E9B1C4A0
-:10859000A27B5472FA37DE24F84B4EFFF4F7E30C5B
-:1085A000BAEED34FFC25CFA0F5EB7F3A7F14C0A1E4
-:1085B000FEC773470DB4FF067A4D7AEDF34A225E8B
-:1085C0008DBD123382F6F1A70B3F07BA0E8C83796B
-:1085D0009E3AE28D81DBB996BE6B980AF85A87FA0B
-:1085E00018CA1B289C6B1EDBFC01C889FEF0B6462E
-:1085F000CBE8AC4F8D06A77D4DD73B0B106FA40782
-:10860000F5A8BB7EED6B149F1766C6DF19F2B106A5
-:10861000F2AEF6B176365E27C55FA43FFE4EC12F9F
-:10862000B3FAE3EF0E17FECE905BBE970F798D5D28
-:10863000231C7152F1EC8B0FC6B3E203C80B210F60
-:1086400006836FB5C4E6B5CC633EE801BE7A32D886
-:108650008BDF8580DF1F9E1947287D1CF7F45C0F98
-:1086600072B3E7A75E7D177DBFE6A76F209F9DFED3
-:10867000F12B9A81F9992424E5F13C31F67308E451
-:10868000700DDBCB91DADDE19437D287A79AE4A2B3
-:108690004A2382EF8FE1FB24A3FF9AE4FE25521ABE
-:1086A000BCBDE1296276407224C265DDEEDF69CC93
-:1086B000BEECC3A7540EF83CB600DE67C2A758BF95
-:1086C0000EEB9F69C3EB6EC6B7EEFA35943F41EFF0
-:1086D000F5C36F527A039EA7777A55D07BA7C1FE68
-:1086E0000AF5C77B1FFC99FD33DCFDCA2B6EFE1615
-:1086F000F1630E87CCF461713B60E0F50D177E3FAE
-:10870000F7180E3A12703CF9717AF97F8ACB8D1AFC
-:10871000625516D8EC139F87DA27905F46E2D6E8B9
-:10872000C2BEF99E847D04A5BF938F2A18AF69ED60
-:108730003C8072DC2D2F6A48FA7DFB5F3DCC5EAC3D
-:10874000D9BB7F0AC8B593CF3D8BF459F3D8310D0F
-:10875000F62F2FEE794AEB2EEDE307D00F499B7EE3
-:1087600038F9A3FD53983C48BFFF0D6AACFFDA7D92
-:10877000CEFE6B1FFBC0D1FF5AAB5363790C038F46
-:10878000F3BE6A2E85F5BE7FC843409EBEDFA9A416
-:10879000F5BFF670FD28E0D4FACA82DF419CBFEC39
-:1087A00070C0003DDAB5C91C7507D86B873D04E47D
-:1087B0003751CD3F7869B9EB9500C633BA0E5FAB40
-:1087C0001836FFC4332E78CE7CCD9A1BA6FDCDEC97
-:1087D0008E97C116CA2D37CA8FD27DA3DD7FF54A89
-:1087E000E52890FBCD60CF4F84F16251F07F289156
-:1087F00005952C7F50D6FD69F537EBCF138A63BE04
-:10880000A047977B7DB6488F62BFC5FD4DADA1F4F3
-:10881000FEE8059AD817D0716D7290DAAA55E9F082
-:10882000364B637648A6EF976ACCDF93E97BC52089
-:10883000ED7BF99BE3470BCBF174F39EC6FB71FB19
-:108840005733C9030FEFA74C331CEB05782FB2E564
-:10885000C58F26C98D90274A4221773C3AEEB3C78F
-:10886000A3AB0EED87F873EED5FBF201FE11D2AC8F
-:10887000BF87763C899D1BC08E75C79FDD7989991E
-:10888000E2D1BE50CD9114E9DF5FFFF8BB897928B2
-:10889000CD63E6F90A6DF1F766BD5FFC7DBD46C7A5
-:1088A0006DC9808725DA9C7FD280BE649248F77DAF
-:1088B0000BA79BCB49F7532B619E3116BF9FED82CF
-:1088C000D7A51C5E3F3B9F2E9CAA9E0A62A81E0A4B
-:1088D000DFB94BCC661081F397F7ACDD0F7C26E255
-:1088E000F7D644F95C70E8F01B6E5EC42ADFE27BC9
-:1088F000B521E445103D27AD5EE89B87C5F755518E
-:10890000DC2779389F1D78F3661FC82D95242A0B24
-:1089100061BFC4E39A986F4FFBCB4BF98949E7AB32
-:10892000E906DADB79A9D50FDC0471757D0CC62365
-:1089300094B397A0FFD0DDAF128D59980F16322A4D
-:1089400014DB38ADB92C3EA3EAF1B479C3ABB4C49F
-:1089500013B05EE5EC65D8AFEC8B613D121A5ABEE0
-:10896000EC77AE8E207C7D14BE201F1164B02E9E4D
-:108970003775F7D511D433FE839E9DF0DD1F6279E4
-:1089800054B7CB8118E459B9F3A82ADE6A27D05F1F
-:10899000EB3109E328827E5B0BEBCE03393E401EB0
-:1089A000D54B9ACDAF9E298FCA1FBA11F3A8FC9F51
-:1089B000368FCA2A9807F6586B361179559644E7D0
-:1089C000D1CAF3A2FEA3F5A5B9A09F5AFDE2FBCB45
-:1089D000734D7BD95A7F00CB3CEF6AB4B7BD09EA2F
-:1089E000E78E26759DE8CF33C93536391BF1AA08C5
-:1089F000E77FD6CC7735479E7CD4115F3AF0E666A8
-:108A00001FE86FFAAC2C02F851BA02BB3D2FD54ECD
-:108A1000ECFA483C051DB5160F1CBF53CF5E847E93
-:108A20007C51F6E949D34C537FBE8FD91F827E7D9E
-:108A3000B924097AC967241EB809E83937140B32FA
-:108A4000BAC438595B08DD53FDD6D1567C03C6DB6A
-:108A5000CEE804B95ED071FFF95FC6E75F64615C80
-:108A60002244309E96791D65B88E559A19F6DAE043
-:108A7000987B5EFABCD4BBBD6C3D2DF1E52CEFAC10
-:108A8000DA198715791AA27E504A1478411EE6B287
-:108A900038ACEC63FCD6872FAA2A6CFECD26B2DC5C
-:108AA0000212509777E2D146554F62FD127FE27C69
-:108AB000AF233ED7CDE2BAAE78E27CE516C6DF83BF
-:108AC000E04F9CCBD80A71B789109F8BF2F37D06DB
-:108AD0008FD3992CAF28033DB5150F1C87EA688CFE
-:108AE00061FBBB1ACB59BE9244B85F3BD9047402F8
-:108AF0006E0946F73F6802BE092B822F7E88E53B50
-:108B00002556BEC9FBCC5CC8373CF0E61B55AB28EC
-:108B10007DB49A01E4FFC1D6A72767205E873B4E4C
-:108B2000FFF5B271DBCC10EE77075BB79E62E30E08
-:108B3000751C115FEB5B9F0FC769350619A7838D05
-:108B400033F8FC199FDCB17F35E62FF828FFFBE9ED
-:108B50007BDFEC1E9248D37F16E79F036F7A515E4E
-:108B6000B7E5B2FC284F49C8644E4067FF9ED2BCAF
-:108B70003978DEA1EC02CC9FBF637F3BCA190DC6DA
-:108B8000A1553CB1D04AD62E61C239DBC83C82F136
-:108B9000674F49DE2A78DF403AE273400F97CB2CCB
-:108BA0003FB9A4E426E8271BF892CEA3DCC7F69DC4
-:108BB0009E928B6F86FAFBA7BF9E68023895333A68
-:108BC0002007F31D706C358AC4B99D01F9DE53EEA0
-:108BD0008C5B109F33FF93A84B306E4EE54287D7D6
-:108BE000665752BD781FF23329B3C0DEDBFEB56B8A
-:108BF00063767EFE672DFE1D565FE46B093E4F9F38
-:108C000037D79A2BF2E6123EA50CCE29F5E6532F64
-:108C1000CCB7E77FF17CEA90C8A7E6F1CC0EFA5F0B
-:108C2000BAFC39F739C6CF2B9FFA292FDF0F07C9B6
-:108C300058C8A7FE8987C4529017F36B250679316F
-:108C40006EFA70F7E73E07D06B8F64E0E7F7013804
-:108C500036B9979F70E1ED463FC6E7C478CF837C75
-:108C60002A1D9C4F47573BFB195BE73C9F755E8372
-:108C7000335E55681538EA9FDF56E4F83EBEE302DE
-:108C8000C7F789F74F759427252F76D4FFD29E39E1
-:108C90008EF2E4CE2B1DF52FDCBBD851BE28B5CC0F
-:108CA000517FDAC11B1CDFA71F5AE3F83EF3C87AD5
-:108CB000477956F7371DF51BA87902F92C7040004B
-:108CC000F7ABDB46CB76FA6CCFA67A250BF3B8353B
-:108CD0009ED48FF166968BDC9767E06EA7146BA627
-:108CE0004EF9573126CCD331CFF046E423A5386F67
-:108CF0008E81EF672C00BF132963E7B444FCDA537D
-:108D00004C527EC8EF0BB9F0EB8A4B7B946D29C0B7
-:108D1000B376F4CB07A5487FBC7AA2EE7CC6A1C58A
-:108D2000B555E3B3E507E4F9385F8CA57C817EC4D3
-:108D30008F15D8B7907961B40F6CFB1B84A3D8DF73
-:108D40005CE623CD0053C11715CB7B46BF80D5C44D
-:108D5000BEC62B0F272FB9BF5EF1A2DD25E4CC6084
-:108D60007A45494E73E421B89F54FE95F9609F1EE1
-:108D70005986F2A8775FD02B1FE333E1BB478DA163
-:108D80007CEC957F7B0A1C7261A8F6995B4EDF052F
-:108D9000421FCF05A597D711C80BA372E9CEABAF81
-:108DA000C23818A9278EF3807955711FE83D6A975C
-:108DB0007DC567DB3F47CA997DF6F766A78660BD2C
-:108DC00036F927EC5501D7118575718CEB85650255
-:108DD000FBAAA6D9B128F801DBA08A6D9FF65DDF5A
-:108DE000F958BF39A4C9E02F6D3E381FE3035E7FF9
-:108DF000DC0779CE4D9E7825ACAB295BD6D3E53B1D
-:108E00006DF631FF8CD6109CB67B00FAD034BAEFE9
-:108E10004FB3DE7FF131BF4BB3BEF820E8B99CB051
-:108E20006640FE44EBFE598B305F77A1AAC3BE9625
-:108E3000D04DDC3BB6B8222171F46769B932EA45FE
-:108E4000AD2182E30F36DF5B7DCCCFE06DF00F38D4
-:108E50005FAF96DE4F9169BE9B61BEB983CFD70BE2
-:108E6000F39560FC108EBFC9C7F0E886BF87986D88
-:108E7000F368BD96635FEE28468A61F97AF72E9C07
-:108E80008A744A05B5837EC53E82D2EFC340BF6275
-:108E9000FF2ECEB3DEE263790902AFC460FE881113
-:108EA0000915F7BD3909B6FFED931F8C8E723C3161
-:108EB00082E7BFC6A8189704378DDD8FA1F8D9BE09
-:108EC000C77B690CF1D5FE15956C027A2BA6EB8158
-:108ED00073B90759DCA9DD13AB8A87FAC613EDDF36
-:108EE000E1FB40952CC9C27B529485D174F6672F63
-:108EF0009D73B8B9E5EC011FCFC3CA27F94CCE96D4
-:108F00002E85A34499FA71DB1B0DDCAF3CFCF329E1
-:108F10001D08CFF631F7A11D2DFC63245A3688BFFA
-:108F200087C54BFBF0BCD448513CAA574C45A75FC2
-:108F30007B31C7739D2B9F97E359E057F8ED493478
-:108F400017F95AE05B017802AE94D9D181F495C249
-:108F5000F9C60DCF53FF4DE17904D600743B96AEB0
-:108F60001FF8E6C01504E3602E7E14ED04DDBBD7C8
-:108F70001FF6FFF75EBFA087CCF5ADB4FB0F11D78E
-:108F80000D737AF371BDF942F9DB6D709E44CD65C6
-:108F9000FBDD7079F3AD329CC320960EFEB5B03880
-:108FA000BF53E6BC7F2450EADC7FF85CF74D78F8CD
-:108FB000FEA3DFFD2ADCCE12E7F9DDF377E36BAE2B
-:108FC0003F7D1E261993DEEFEA8EC789F886C88397
-:108FD00015710084035DBF67961C47F95746CC9D09
-:108FE00069E4D3323FD30B5DCFF9314F225CA5A1A9
-:108FF0003FB6A02C5501E5823A12033D71F1F143D1
-:1090000024413BBD20C0E47E41595202BF47C149C3
-:109010009617B89DC72B0BEA93D24ADB38969FE987
-:10902000AD8FDEBC1DE5E37363595EFA6D15CC7E32
-:109030003B14BDA1A302C62D67F9E461BA5F84BCED
-:10904000B1F0116F12EDADB26E027E54AA05AC30D4
-:10905000FD7EBC914CBD713CE47DF9F079B251C705
-:10906000E781B1DAFECB69BDF5850103FA6D290A06
-:10907000B0F3BD611FEEF7FF9CFD75F4AB9E6E8CE7
-:1090800062FDB66F9B685734EF3F817EC3A0392DD8
-:10909000C6FCA8A642CA613E874CF0731035662C08
-:1090A00086EF077E83F5142DF11B0BEC93651AEE0A
-:1090B000EF010E104F68F2B37CB9CDFEBA68363CB2
-:1090C0000BC98A4569E0BD82EB1D4A518A96D79744
-:1090D00087A495A7942CF02797914EC873F7B424D2
-:1090E0002B404F93D5BA01E38CF1252BC07F3CA6D2
-:1090F0005A8F810F5D2B67E745043E3C7E127F222D
-:1091000004F552D2AD74DC89011DC7293892C4BC64
-:10911000E58FDE9C99D6FEBFFD68057EDFD65879C7
-:10912000789E8D9F4319E2951B8BE73CE0A7E3BD3A
-:10913000EA67FC9AA95FF11C6ABFAF723A39F0E6A0
-:10914000C451605F3664C8A356748AA7114C3E812F
-:109150003F62FD78635476C8DE0F8387F2DCB30C80
-:10916000AFA58C3E9B7E3C310BFA7DFECDA53AF837
-:10917000FBFE945B8CFB86534F7B4DB05F4EE590BE
-:109180006ACCB77C7AE68BB03FFC43E3C11CD526A2
-:10919000174FFDE895191EDADFA9275F99A1227301
-:1091A000251D76ECBA73AFCE003BC19A434AEAE87C
-:1091B000B356D708F45BEB63EB107972DBF3B4566C
-:1091C000785E19CCC6F679A3E43BA1ACF85E1DF736
-:1091D000EE345C378B2BF0380E5D5F5308E95AA7ED
-:1091E0001B1088175ADE7110CF7AD38BF4F75121F8
-:1091F0002929BC10FC820AB6EB594D92904FA1A5CB
-:10920000EA803D89FFE52401BE09BEA6EF475AE387
-:10921000F7C1DDE9E7F90F3C8F70E39BB74F04F826
-:1092200008B9AECE2518CFE8F99A2F09F6E83DAA7D
-:10923000F19DE560075EA7E23C6819CF1BB9F1B369
-:109240003C58E488E3E5F0F884C06B263AD9DA4864
-:1092500062C514DE3F6BF4C560FC7D8D3A967FD20B
-:1092600018C5F2DE46039F4F3796E0B3AB3186DF79
-:10927000F73496E353E4F5E1D65E417B3A5E017A3A
-:10928000E81AE687D30DD9847C852C95F8E0BE26B4
-:10929000FDE8BF55C17E1BE44A560EF2BD04ED73D6
-:1092A000799EDFC8FC39ED15469F7C15F2B4C943A1
-:1092B000249047D62CE66708437FB47DEE1242DE49
-:1092C000B6C9F573F49FB74BF8FAE87CB24CE77770
-:1092D00077FD884A1790D3BF1D958B58EEEB373D2D
-:1092E000FC86FB047FF9DB36FADE3E9DAE9AD2D1D6
-:1092F0007689C9B13BF9F73BA6CFC8BA01CAB366B4
-:1093000064815CDF3E8B183A85E35D866C79B2FA46
-:10931000EAEF683C98376F3CD74120A7EAF59D5BA0
-:109320006CFB9831165911B7D1CB5D756AE52EB437
-:109330003312F98B2763BE31F76BEF9E678EC17EC8
-:10934000B13C21F0E23C8BEB159033979D657AA8F8
-:1093500057FF7CCCDE0BBDA771FC6F9BBD4989001C
-:109360009F803C057959962073E83C4397B2F8F703
-:10937000AC775304F2FBB4187D0FF6A8C6F24D0A81
-:10938000A24909CA3FF2C7670620EF3DE7FED42E87
-:109390008AEF0FBBBC06C41BBB9EFB0BE6672853C2
-:1093A000341FF077C1BE6398B7A4C8DD1AEC789774
-:1093B0000526CF57C19E8589607C802A6A8A6725E9
-:1093C0008FAF8F3CD5322F04E7BE1227ECF5B707DD
-:1093D00012B7B21D33317D51CA0F7ED1FE82168085
-:1093E000C7560F2B2F0B4C6AB1B04CEB67B37233DF
-:1093F0006DBF35BB332A6743D2D4C4968397425995
-:10940000D49FD862CD26E41AAE0F48285108FCDE5E
-:109410005BD669396C2BABAC4C7CEC29D6BBEEC06F
-:109420005F5E1C4DE150B34FEAC410DFBE9D12AC2D
-:10943000BB60EF4E94AF054982FBFE82A49484A3E7
-:109440009D7B1A0FEACDC2B926F04245C3A428BBC2
-:109450005F484B7A62B0BD9CC4EF0F1174F17490F9
-:10946000E9C74949DADE1E9776DD273289DF57835F
-:10947000200579B98D9D0776D37929EFAF81585BA7
-:10948000E03C2E79CCA3637C9CFBD94F0ABB89FBC3
-:10949000736EE10E3CCF262B7001C8BF952AFA816E
-:1094A000D7162637521B8AAC7DB630462D56D2E2EF
-:1094B00067F4B236BB336F2AC5674BB6B3DCC4F36F
-:1094C000E7A3D956369CD7ADD97BF738C8EFA92189
-:1094D0001DD77F13E6FB328B879FD83F2BEB125AA9
-:1094E0005EF7328B63ACEB7A4503FABE27C0F38E8E
-:1094F000BA2EBA12D657B34D267221E34B73229D72
-:10950000AED971019CAC7B7EEB5BF3FD630979A462
-:10951000C8D4E58B08E90E9E68F151FC3FA2E9939F
-:10952000803EBA833D2D405F6B67C99C9E7A5E305A
-:10953000559EFF5800E35CDE027196DDCB2AAF0436
-:10954000732B4F66FC4B0912E3DA4A76B30FECF942
-:109550003FB6C8683F838B7403857BB14A0EAAF47B
-:10956000B95DA3F8043E6B55511ED2F76D1EC44B76
-:1095700007DE3342DAD83D2DE3F77957829D5D5CF3
-:1095800067AE467B5B2F453FC038D2FB837912E73D
-:1095900011267F27EAA442A5F566050B117FC55564
-:1095A000D7AE85764A784900F83D4F495AD8FF77BB
-:1095B000991CDE2E273B7D2097234588DFED114641
-:1095C00017D63DA54817BBE53917805DD422ADDC21
-:1095D000F20BC06B76119E7B85F7EB61FD1C9F4DF6
-:1095E0007ACC07F8DBCDF1A9EC942DC8D714EFB7EE
-:1095F0004A37AC06B89ED8523FDF47E19AE735DBE1
-:1096000046503C1CDF52DF129D857828F2D1EFC70F
-:1096100003F52D3E8A97DD1BCD02DD569EF8099598
-:10962000EA48B4F52DE66CF09FDCB7069410FDFE19
-:1096300002F83F1EC9117CCFBE1717F5CA1113ECF3
-:10964000D226AB4FAEF8A85E28B6D59F47E5C20F2D
-:109650001E5210AFFF4EC7033941D76101DDF74CF1
-:1096600052D12E08D0B904683930B908F36DE9BA7F
-:109670004900EC86C92AEA7911C7D126C96837435F
-:109680007DA087407E11E6CF51791D87733E4A94B5
-:10969000C5751465874979980479FEBEA42FC2FB6D
-:1096A00048FC25B6BC0290BFAE3C04C5551EEFED8C
-:1096B000CE97A97ECD3DBA481A47F1F25E80EF8B76
-:1096C00072E93E96BE7F3FC0FC40B7C7AD2F43BE98
-:1096D0000C31BAF3593C2A3E159EA3AE2B1E359091
-:1096E000FFA5FF7E3586F6CBBD63D4B4F960FF1AC3
-:1096F00064FE41EFD862BC57A38150FE07BE08F15B
-:10970000FBF2B8FCF0707BC17D4E40C8134F365B56
-:10971000637DFBDC5139A1BE73704AC8F4813CD82B
-:10972000AF4FCD027B743C9753CDA9595F05BB4524
-:10973000E5F260879F9DCBEDC9269DBB08D8BF3160
-:1097400062CF4B10F2605BA30F9F0F5F3601E39770
-:109750000F5F963707E215072E7E1FF7BF6776303B
-:10976000FE3D73E805B84B899CB1A8B6311859A1E4
-:109770005F3E752FDE17F27D357E17E6CB43BE0EBA
-:109780009DD25DD9CE3CCC47395CCE0578DE808752
-:109790007D17F778A867BF847EE06D7C3DBEC43C32
-:1097A000DC57821B0FCE1DFB4907DEC724E0E0BE5D
-:1097B000BF433D3B85F9EB036C5F2AF297DC794AA6
-:1097C000623EFB8219EE3376E143F835041E44FB1A
-:1097D0007AC91CA50F4037B5671592B4E585F49D8D
-:1097E000DBD0F0FD6938EF9205F7AF243A2E29045B
-:1097F0003E48A29DE80F353BEE712551B5C77EBEB0
-:1098000024E83AEFE2E617B83F18F4B4660C7CAEF1
-:10981000E57DBACD1579B998A7AE9207C0AE3D15D2
-:109820007C6B06F8E36AA998005739512D3C4F7AB2
-:109830009AEF4BD47DB7E2791E313FE18F13E59A61
-:10984000BD8BD04F57BB3B84E7796A924C0EAEF389
-:109850005907BDB23DEFD64C41BEAD672FEB6F3C13
-:10986000E080D2C7877A753EAC3FD870FE4C38672F
-:109870009227D79D370EE0A3323CC07EF9C9109ED7
-:10988000D355BDB6FB53DFE2FBE365DC1E09124B8B
-:1098900006782A8158376167164D95DA474AAFDC5A
-:1098A0009BDC02FCB0DD656F6D0FB0726B70724BAC
-:1098B0007329EA67948BCB023F437BA8C52FCACF9D
-:1098C000A29CDCAEB1FB3AACA7BD06E83DDA1ECFE8
-:1098D000A75BCB4A507F2845A400E0360F1C2D2003
-:1098E000FF9EF6EE023FC38FFC896B0236B89D0ADD
-:1098F0001F1907FBCA34FD598EFEC60DAF3F3A7ED5
-:1099000017E0417C9F17B91FFBA7EDD0DF41C61CB4
-:109910007A8BDABA24EF692F9E33DCE171DADBE26D
-:10992000F920E7CB36D7BD1DBE44B3099B73C19F59
-:10993000EE7B9605BFAA672739F2A4C607593C5BA0
-:10994000554D7055D2EFA5EC7B80D1411BCFC7C9D7
-:109950003C4E4E86719C71BBFEE3CCE07282F07D82
-:10996000ACAAF7DECB3940FEAB3BBEE8966FBD4FED
-:109970002EDFF2393DC7A5C4B3415A5E93EC5C10AB
-:1099800060FC3905F87335A7D3923D773F076AFD30
-:10999000319FF967D837ACF2991704A70F9F7FBAA8
-:1099A00083623DFDE417B3CBAA999D5BDF3EED4A90
-:1099B00028D7DF51A45B69E245E2597D36E8905F24
-:1099C000F7707F51B56AA11CAB3E1BC1EF9FDF78DA
-:1099D0007EC779B6FEE385F0BB18EF16977C3E7024
-:1099E000F14BDBCB291DD73FE191BDB671EA9FE07A
-:1099F000E780FC545E3BF9DD047E570B496F9E22E5
-:109A0000C887BB3451565AC12E7AC42E1FCAC16EA4
-:109A1000EB6B0FF716DE15E0F5AD60FAFA4157FD76
-:109A200022D17F2ED677CF47C81F28839DA67EE2FE
-:109A300015F343F975B7ECEA2F478C3F06FB13F695
-:109A4000FAB703E35F843B25EECA4E568C66FE1DD3
-:109A500003EC80EFABB180FD3EAC6F737AAD3E7B23
-:109A6000BE03DF7D709FE078FFFBC6A8235FFFE6A3
-:109A7000443D9ED3F87680D16535B5E8B1DD8ED111
-:109A80008E3CFD7FCCE3D3CEE3920CF3B8EC6F3C7D
-:109A90008F42077FF6CDA3D8F1FED3CE631FF70B1D
-:109AA0003FC79FF375762FC07C4342BFF57C5AD7E2
-:109AB0004F69FDCBF4E9A3CFF92AB14278CF6D927B
-:109AC000DD6346CBE00FF8EA27B7BD7B39DE0B6DCF
-:109AD000623E8E57E4E3F0731E9BC70C7C5F91FBE4
-:109AE000EF3BB8BF0733DCD3DA1862FBEEBB2FBC09
-:109AF0008A60FE7A28817182FDF90BA260A77FE758
-:109B0000C21A7C36E7CF88823C6A0A7FDD916F4EAD
-:109B1000F70869CFC1FE91F74BCE7E59B69F47D962
-:109B20000CE751D2D41771B1CDBE3ACC03FFA2D607
-:109B3000FBE017B4DE4BC38CDE36FB1218176C8DBE
-:109B40007E31F37F26C4C6B9FBC2CB089BEF6529E3
-:109B500016F7D10CFB7960F1DC1F9E118575366517
-:109B60002F88023D3767CF70AC47C9B09E5561065C
-:109B7000A7CDFA17BB9EC39F793D0BD2E6C1AAB908
-:109B8000E9EF176B17788A2690CEBEA8759DFA1B51
-:109B9000AF6B14C7577588F90D361B8C8F824AFC42
-:109BA0005785D2E07C38D8DF1D21C5863C943CBC6B
-:109BB000DF727865E2DF659EE44898D79146B67F0C
-:109BC0007E9DDF27F5DBEAA630FAB55DE36C1EB3B8
-:109BD0002B3C909FE37F563BCFA70F26375A422C52
-:109BE0005EF3B584B3DDD2AA60DAFB4D28FCEE2A21
-:109BF0002CEC83673FFC7FCE70CB448FC3855B6BBF
-:109C00007478701B8C0FAAE1929BE983C34DD05BE3
-:109C1000A67EFE7FA1B307870E2FA4AFBF15BCFEA3
-:109C20005EE9EB1980D710F8F21FF03AC7F5E6D0DD
-:109C3000E025E4D81E8DDDBBE8EEE74498DDAF34C7
-:109C400051AA3B7C05C417BEA2A0BFF7F08E79EBEA
-:109C5000886CAFC7F4D9E1CAB9EB30DF351EC47BDD
-:109C60003C5F9363FF5E067187C5AC5DBF7972F898
-:109C7000BC14CEE67E4B6324F8115E8B5F3DE0FAA8
-:109C800048A56D5D989769BB8F4AE90FDFC3C4B8DB
-:109C9000A30CFC4D0BD3CF43E033D3B8C3C5E76B64
-:109CA000F1EF0F0B9F83ADF7D970D190E485D837D2
-:109CB000E492DEBF977101C0738FCCF2398EC2ABD4
-:109CC0007CB89F8C60A5A555A376029ECA223CEF66
-:109CD0004933D6819FCC7BF5C2AD618AB7D7AEC977
-:109CE00096BC367879230CCF3396A7B70B73233CF9
-:109CF0002FB7B7BD44E03E44773D85D7BB6639BB3F
-:109D0000978AA8E6D8C5B67375535CDFDDEDC74604
-:109D100022F8FD351E6F777FCFE2ED972E19B83D03
-:109D2000A963F7B950BA1B9BEE7E41C11F9DE14468
-:109D300034429FAF4B8907BF01743429C4E21E2A05
-:109D4000298478BDE8275725298DC2FD5D8F3116FE
-:109D5000FCB469FA291CA89F4C7015EB11E3002B89
-:109D6000C2BD2C74FF88FBC5329390D9B04FF4C6A6
-:109D70006E65870D191DE4F0FC999975C1E446B034
-:109D8000F354BA4EDB7CBBFE6BEEFF80EF5D876564
-:109D90007D53617F380C261F1670BAC955129BFC83
-:109DA000E01F5B21A5BDDFECF208FB3B251F847B98
-:109DB000E3EA38CE84FB121EB8E7E05A9EDF44483F
-:109DC00062ACFDEF8C7DC0E58ABB5DAEC2E2D1E442
-:109DD0000DC6CF7B76AD199B8E7F5EE57CFA41B8D0
-:109DE000C4919FB4247EAB07F873C9C2451E2304F7
-:109DF000DF99BCBC86CF638F96187B51A80F4E1994
-:109E0000E510874FD7914413DCEFB0A241C238521E
-:109E1000E90646772B36EC97D7D1E74ECE7F8B00FD
-:109E200007B6FE6EE578DDB32B300EE6BFA7D74F41
-:109E3000473BA6F3B8FE7E827EAFD591AB3683DF7B
-:109E4000AB5B22FCEF32FCA412F20DBA799E480BF8
-:109E5000FDBE11E63B6F24F2F7840D1FD4837CEE28
-:109E6000D2089E97FB8F762FFE7D0B412FBD72622D
-:109E7000C3478D907477AF969A0C7433B2A9EE1BDA
-:109E8000E9FCE416E7FB0F43F1AC7476AE780A798F
-:109E90002EEA2D560D4FBAFA57573AE59898F7081B
-:109EA0006FEA54BAFB1A7AE93039B0DEFB3597E332
-:109EB00002EFBDF83E927E5FB423C2E2777B9273DD
-:109EC000D6A2DEB2BC06C843311F01AF5C8BC1E92C
-:109ED000DA258A43DEAE5818749D476270FDAAD712
-:109EE0007808D671EFAE9726E3DF5174E987809248
-:109EF000D0E0FBCD24E50139715C31F0F97AA3F3B0
-:109F00005EE6D749E28EE9A03F1B94B47CF50CA72E
-:109F10009FD7AB565D83F36F567498FFB1E523AEC0
-:109F20002A07F952E5C17B828F35DF16BEC9B67E9E
-:109F3000A1EFDCF3FA6DF5AA01F5D6D22A27DEF6F9
-:109F400068CC2EB0AE647CB89ACA9BD9485FDD77E6
-:109F5000CCA4E31F4EE65CB4855527F0F71CAFE6B2
-:109F6000BF1F971377CEA4F2E684CCFC61D63F31B5
-:109F7000B9B1E4BE780BC4794F344CFB6937ADF707
-:109F8000325FDF5B0D03EB47373D4DB8CF793FE5DF
-:109F90008C234483F689FAF4FAE0FAEC2093AF6A52
-:109FA0006C1CC897EB36A4AFB709922B69BD137F21
-:109FB00055AAD3E56D7EA2333E59114FDFFE133D06
-:109FC000CCBE835E4A03E7BD59412EE7F47120A75A
-:109FD0005764986F575604EBBDD372FB7510EF3B77
-:109FE0002E3BE5F30FB278FC3C8BC9E713BB9679A7
-:109FF00046029E5A251DE8E1EDECD824A0B795CD88
-:10A00000C7D08FF02D5EFFBA50FC43D04F4B8E2C43
-:10A010009E3F92E2A56B3989494666F9FF31E79F79
-:10A020005C85DD6340F5DFBBA0FF68D377D1FE50D0
-:10A03000CD715F9BCCAE6C84BCC213B2B506F3503D
-:10A04000760558DE11894DB7DF2F13E0F338B17B69
-:10A0500078F8BE261E1CD08E3F4C3A6A70DCDD417B
-:10A060001DE28F872B95D4E57492EFED0EE23DAFA4
-:10A070006EBEC834FE70EDC013BB8767070EB6EE28
-:10A080005856E190ECC03395F7DE59067CA4754C28
-:10A0900049277F859C7E8DFBADDCF4239EB3393E42
-:10A0A0008E27079ED7CDF73BE7735D9D733E825F9A
-:10A0B0008E279B02901F4E479F6CB74BC9BCE9830C
-:10A0C000E859E6FFCD34CF389FA790134079104F61
-:10A0D0005BCDE5CD5B0DF746EC7870AFFF84CCF738
-:10A0E000070FB1BCADF1F19573461A7DF4795D1699
-:10A0F00093439F375D0A3DE3EEE7EF9D0E859E1B80
-:10A100008C0E855C70B7FF00E2FC23E1EFE3E81AF8
-:10A11000C4653E8818AC4CF40570448694F373CB48
-:10A12000C41807E76E4EEC0AE0FDF6D6166F12FE75
-:10A130006EC7F15D974CB2AF6707C7FF8A25D97824
-:10A140005DCA713976C528CC2F50F0BEAED78FE4EA
-:10A150002C80F2BD876490D0E4BAFA950AACEF8106
-:10A160002C9677BE62C32B680F0E97CE57D439F565
-:10A17000FF277C1DBD7696DA5306F493090EED5940
-:10A180003EB6CF892F9A0FF279D50609E5ED962CC8
-:10A1900003DFAF524D94DBA499E947E2A3F0A02A74
-:10A1A000E4182C02E0F1BFF9DF2953E39AFD7CD2D9
-:10A1B0004DDB6E9F0FF6A19B5F46EB8C8EE15E3010
-:10A1C000785E174A3C9935B24F3EBF2DD5ED1F45FD
-:10A1D000AB5C9EC5ED6DCEA7623D9767B1F5513B77
-:10A1E000ED87F8F799F8FA48CC456F7247CD4F00E4
-:10A1F000FE737C681704BC54EE43DEDCF7033ACBF5
-:10A200009B637C25EC1D77FB6BD584C36E3C94551A
-:10A21000E8C8C771DB21FFD017E9EBFFF96FAC2F5E
-:10A2200064FDD3E98BFF0778BAC08E008000000080
-:10A230001F8B080000000000000BDD3D0B7854D59B
-:10A2400099E7CE9DB9994966924932933738930080
-:10A250000625780321449E370991A0A803040C1A0F
-:10A260007044D4282144C54ABFD2CD0D893120DAAB
-:10A27000505DB4D67587885DB6D235586AD1D2762E
-:10A28000B0828FEA365A45DA8D1A1FA5800FA2AD2B
-:10A29000ABDB8FAD7BFEFF9C93B9F76626046DFBAD
-:10A2A000F12D7C7ED733E7FDBFFFFFFCE7B0A22591
-:10A2B00085449D04FF7C49FF3B9C1A20C44FC8F194
-:10A2C000BFCA8DBD6E428E45DA93AF81AF4D5D90B2
-:10A2D000ED2344EF94C9A3B4DD3B473EAD81F2BD0D
-:10A2E0007D36AF44CB2BD65F238769BB4C28F9A1C1
-:10A2F000DF9234287F097FE60EFFDEF0804CA2C596
-:10A30000B179AF867518CAC77A923502F3CDF14498
-:10A31000C60709D9AB109D9411F2F6E6ECC8265A8F
-:10A32000AE7112DD3D8590B9696CBDBE8D9FB77A67
-:10A3300027D3F5F4FCBA8414D2F5DD7DFB8AF0A4B2
-:10A3400038F37B6D844CA3130402369245C86D7CB0
-:10A35000EFAB528906E3133ADFA386F145BFC3ADE5
-:10A360008444CFA5F5E368BFF2583FEBF8CBAEBC11
-:10A37000702CECFBF09533C75E3329D62F111C9659
-:10A3800049E17F5E0AF3B6C92AC075D73D498D3DC4
-:10A3900071E0A673B85AE7873F76BA8F25FCFF971E
-:10A3A0006EACBCC34341B22965CEEC709CF90F93EF
-:10A3B000F0DDD3E87CFA46369F759EC57C9EC3F5DA
-:10A3C000D72E05F87FA6CB5E99C263A0414EAD8023
-:10A3D0007EF50E753C1D7F40BFD5739D619DBF4FBF
-:10A3E000009FDF375EEB898B07FEBDA2DE4C076F57
-:10A3F00093C197A7C33C3BE3AFEF16581FC5DF31AE
-:10A40000257CCF85747DC72F96559DAEE7B88DF618
-:10A41000037A7990F60B0CEF773DEFF7F6C691E9EA
-:10A420007249AD793D4B8F249BE9D2461A7BE3EC10
-:10A4300067685D6748F72B2CFCB74B191CE3A5FD3B
-:10A44000DFDE71EACDDB613F3B9211DED67132D3A4
-:10A4500065C6A7C02700AF2D499C4FBA9B9FA6FD9C
-:10A46000DEBE344FDD4486F30721DD97CDA0F5FD38
-:10A470003DB6D22DB46A574F4A6324CE7A27A7330C
-:10A480003AF0C97AF279B43D7983E103C80DF866F0
-:10A4900029A7376FCF0F5B882DD6EF0DA0832442FD
-:10A4A0007EDBEAC4EF36AF13C7A95BB84809D079A1
-:10A4B000AEB3130DE0877FE8B8DEF30A766CA153E4
-:10A4C000BD6E63657D15E53F69F87A1EE674B92BAC
-:10A4D000B27844F8D637C82678D62D34C3D74A9FE9
-:10A4E0004723B6DA78FB17F49C68BE2B1D113FE0BA
-:10A4F000E908DFEF61BEDFDF37B67BA0BD759E5D8B
-:10A50000919E11F9E0AA46335D9C6E9F6F7A830895
-:10A510008FE56173BF2BEACDFB5D4A5A66134A2A69
-:10A52000CB88EA806F1D6929799A82F2E8034B7023
-:10A530003DAF13520B729E9CBAB56451496CFC1727
-:10A54000393D7F5677EBA5202EDF505A4ABC71D695
-:10A55000F33A8793C0F7EB09E019E572F70DC033C2
-:10A56000D0EB32392E9EFF8BCFFB46C3C87CB4ACF8
-:10A570006E643C9FF07A113E6F34B427C33E8F89DE
-:10A58000791F64F3825E33E2E3C457D45B56FE1D49
-:10A5900020FA4D48C791642FE8111F9087418F74AE
-:10A5A000A4DB981C2F1E598F88EF6F855CB5B4AF64
-:10A5B000B36B0E233ECABD01849B28D72D34AFF365
-:10A5C000BD54060FCA7163431E83DCE0FA55E8BB35
-:10A5D0007B7F70FE5BA03FC7A7333CD4853E7100F4
-:10A5E0003CA87CBDC303FB7AD5E605F95A7E4473CB
-:10A5F00018E137278DB53FBE7364F8CD4963EB3C56
-:10A600009D9CB5EEF7ED6FDF3905C67DFBDB9F3B0B
-:10A610008CE32FFB229F443363E5ABEB252D1287A0
-:10A62000CF36789551C17D83058E577F3116C7F798
-:10A63000C9A4A537CEBEECE94E6CBF3454E9F05343
-:10A64000785EBB5152253A84239DC9DD6B85BCB32E
-:10A6500007C62EA270F7B7B7DC168A33CE6C0EEFA2
-:10A660003FBB4369F1F84C7C853E17ED96D9C38E0C
-:10A6700078EDAD7A7580F3B9B55DE80CE971C80E77
-:10A68000B2B41FED3AE6A6313ACC4C8A7E04F28889
-:10A690004C32DB61A79DD7D2DE3AEF651CEE89E62E
-:10A6A0001776AD757C9DC33F1CA2F413B7DE83F50E
-:10A6B000AF12A65FF5480AEAC3633BAFBD07CCB74C
-:10A6C000EB17DC7608D4E4CBA9416CD7107AA50649
-:10A6D000D9EDD4BD9301EF9FD5DE7B4F195DDA71C3
-:10A6E00025DCEEA11D8E6F92D06EB1CEF32AD72756
-:10A6F000AF813C3D17C623CC5E9D4747CBA56097F5
-:10A70000B5352054C8B79202463BD5B7E1F356326F
-:10A7100019EC87D0260FFD7DC2C64FD6835E262456
-:10A7200082FDDF75A83722BC09B373FB7BDC3BB627
-:10A73000D076AF825C80F1893A3654629013762FDE
-:10A7400096478B9FDF26C0CF99CA29B1CF44F350DB
-:10A75000C8E3FA1657B9BBA434B07702D7C17E0656
-:10A7600017B8BC3D14858B15ED1280CFABAFD86CFC
-:10A770006D411C16ED15611F072F0BDE755E19C8A4
-:10A780001F87E6A24B5904CECB85948EAADC3A8C67
-:10A7900057F6DB858F017EEEAD4F0AC830DE9CC0D8
-:10A7A0009B322D2FBE3829007E47795FE1011F1DA6
-:10A7B0007FE942C94B68FF790BC6FB07E8FE5236BA
-:10A7C000D071F26079C76AABC711F243986C066129
-:10A7D0000BA6B0582CF1B2EEDB3C8FB63FCFBFD703
-:10A7E000E6A6A09EF85DDF66271DF78EB6508E3771
-:10A7F0009DDA13E91F743967139295A5F5CD5509B4
-:10A8000071677C540BE5BD0F8AF13EEED20A08F960
-:10A81000992D1C9468FDD48CA405760A2F5F91981D
-:10A820003F6FB3368BEEE7E21B1F5D4FC75FFEDD68
-:10A83000490BECB0EE06317FE90258DFD259A25C39
-:10A84000EE82B22F85F787F55650F955185BBF3D5C
-:10A8500087CE9F21DACF58308FF63D5CD9526DA755
-:10A86000F3FFE8BBDAE649130999BEB0D2ABD1F2E7
-:10A870001319F50B52287EF6124AA7B4FC64C6954C
-:10A880000B60FD3ED9C6C7BF6A33ACBFBC413F0FAA
-:10A89000EA257DE5E65ABAEFB5CE814340AEEB3608
-:10A8A000E8CE2CFA3F2912E363A7A345CBA7B073E8
-:10A8B000ECAB8CE6E372BA19BD16444B408F0D9594
-:10A8C0008B69B9C450CE61E5BD9BC8D5F1E4ED6D8F
-:10A8D000994CEEED4D8E5FAF64307B80C20DF54933
-:10A8E000DA11A2ED8EA3573E4A77E37C079389EEF7
-:10A8F000CC88F1DBE594872B285F12275BA71867CC
-:10A9000098FEC8607287E89767803C5D0843D0ADC9
-:10A9100017A912FABBA42525321E688744ED4B40C7
-:10A920007FC8365CAF5F96AE5E44C7CB4A26E13D3A
-:10A93000F4EBCF2458A6FDB53DEED8782F71BAAF11
-:10A94000290AED84F16AB2734BDB83B171E8BA3B3B
-:10A950009C534CEBB6576440FDE2D29B2719E0397B
-:10A9600089ED83D201F6A3D33C3697F2C1DEBEF364
-:10A970000AC17EFFA945EE96F72D7610DAEECA4C95
-:10A980002E5F02ACBFBF9AC99FC19B53223DC09F9F
-:10A990004EB53464B03B031C1ED5772EBC1FDA3590
-:10A9A000F53948126DB77E4F653619412F367D3126
-:10A9B0009344A61ACAF6A80272A7E98B39F87BF568
-:10A9C0009D2F29C0A7304E80EE6BBD4BCB56016E3C
-:10A9D000EDF1F14F1D725C47D317E9449F6AFC9D6E
-:10A9E000C12936BE0FEB4FB7AFD8783289648E34A9
-:10A9F0009E82F54370B773B82BF1D7395FD02985A4
-:10AA0000B7CD405F4B39BD51E9877194FECB26F538
-:10AA100080BC8FCDBB09C7DF6BA778043BB02F3953
-:10AA2000007671B99DC9CFF2BE0CAF2EC5E843D0F8
-:10AA300085C0EBDE8C964ADCEF22C9DB131CBEAE70
-:10AA4000CBC4BAB83ECD6E08CBD718D627F8818EC6
-:10AA5000BF978F5F5681FCF32F4CFF50BE5901FC0E
-:10AA60000B760BEC438D962CF60C5FFFCFA8EC8099
-:10AA70002FC52383FFA5EE08E80101B7E1F0CF3F22
-:10AA80000D3EC7627D79DF330AECB32901DF8632E0
-:10AA900053B15FF691682AF8B5BF4C677A6D6FEFD6
-:10AAA00054D74CE08B853602220CF60DF66AB9902D
-:10AAB000B764D70B5576FAFB5099CADB00E06148C2
-:10AAC000FE469DCE58FBAACC5D0B3A689D2F89E2CD
-:10AAD0007F12DAA14E62F027BE9DC1E4584598C4AA
-:10AAE000B55B966532BB45C0FB7B1BAAC97B747FF7
-:10AAF000CFA533BEAC18D025C08BE06BAB9C7A8859
-:10AB0000E3F17BFCFB8F9753D269E4D4222EA7D8C4
-:10AB1000EF07A9990FEDB2B2A22512D589AB5E98C5
-:10AB20003A1EFC995B72E4C0FB94AF9648EA981F0A
-:10AB3000D171EB9C018C93093AA923CE801BE04E86
-:10AB40008DA62F41EF2F746119FE805DF269B7C4A5
-:10AB5000E89004D2EA4A12CB21B18E5B72149C6F4A
-:10AB6000D5E6F16961E3FAB89EB83C29FA2352347C
-:10AB70009CCF4599AE7FAD4D36D4BB993EFBD0A35B
-:10AB8000FD3483E2E15589D4E37A2CF6D26F78DC88
-:10AB9000C66A2FD5733BD20FE625F2B10D9DD3ECDB
-:10ABA000AEA408615D74F053B37B09E7D7A8ADC9C3
-:10ABB0004007BFCE286076ED15B4F202CA94CE6A83
-:10ABC000ED7D831C7B1ED6837A213A0DF8F4A50C0B
-:10ABD00062B2F31AE4508104766B76920A7286E2CE
-:10ABE00009E170D045EC2E3AEF73F40B78AB916F1E
-:10ABF0003EE0F0011D486A3B427F07F75B4914F4D1
-:10AC0000CDE57353D06E25A76E1D07F10A7F0AA309
-:10AC10005B3A8E938FE3443AE172EF376327F68015
-:10AC20007E12F253E0819C92713C517F505A54E065
-:10AC3000A5E583FE734BDB25B3FD03F650CC7E5AAE
-:10AC4000BF793EB597A6D7F6466D5E902AB72FB866
-:10AC50009DB6AFA1F6938BEEE78F194C0F1E0CEA51
-:10AC6000722A8C379EEE83FE7428393CA9C51DC319
-:10AC700007B571C280BF2C857EDD8C3FE0DB99C9B2
-:10AC80009091E163DF06FECD4A65ED87E93D5EAF59
-:10AC9000490CDE5B2A999CB0B6B3F171D73AF5DA6C
-:10ACA000AC42A37D1522408776C2EC2C19748F1F0D
-:10ACB000F519C2ABFACE8634D09B9FF52D4D239368
-:10ACC0006272D4E1FCEDD8F7A91C899225DF017EE0
-:10ACD000555E9709D8CB7738185D2AE9616F06FD74
-:10ACE00066A6C4F79B27F2F564825F4DDBDDC3FDEA
-:10ACF0001EC717E7A3BF9D9FC9E245A9397528D78D
-:10AD00000196018AF73432A87B0D784CABB099FCE0
-:10AD100007C71793B1FF99DB0FA509EC873293FDA5
-:10AD200020E6B5DA116FB6E6E0FA45FF1539AFD582
-:10AD30001043FB9564E00E186FE5FA7C53BC289134
-:10AD4000FD3137531AB217F4B8EB524CBFBF49FD6F
-:10AD500045DD38FF31367F6CDE14CA70B179E54CC1
-:10AD60004DCB44BF6F96F7E8F9F4E3A2BFCBA877C9
-:10AD700050FE53FDA4ED70A35EAA05B92DFC24E09E
-:10AD80007F6F1AF077656DA6DFA027793FAB3C3A5D
-:10AD9000C0FDEA035CDFA41D117663724092627A03
-:10ADA00067B8DEE276B1453E9ECECEA674AB1BED13
-:10ADB000806178CEFCAAF6655102FA98F00FB12FA7
-:10ADC000CB6785E512909FB512194F3FD3E799F5F0
-:10ADD000BD9EC9FC109D329CD16F59DC606ED701BD
-:10ADE000EDFCF04D1995DF62D447920C728F8DD730
-:10ADF000CCE92178E2552540E57094DB43BB7CDA51
-:10AE00005D40171DC9A993414F74248F8D405C622A
-:10AE1000C7FF5617EFA0EB1F7CD9A1F6C0B0FB18F7
-:10AE20009D542E5FDF6EA7BF3B7A256F1289ADD38D
-:10AE3000BD41D256533EBE9FCB89261FDB4F932F79
-:10AE4000AA8CA3F3E735B17514F41E90EC0679577C
-:10AE5000D0C8DAEDC87498F4CFA350A6E33C22FC26
-:10AE6000111269AB2983F69A1DCE41F27A258C0F17
-:10AE7000E7B55040507AC853D9F86E35225D3B296A
-:10AE8000B6DF2EDBA249A027BAB25254D013277DD9
-:10AE9000E1C760BF4DFDD128806B7A7F9F1DEC3DDF
-:10AEA000975FDB0DBF8B7D06646F1EC8D9947EB69D
-:10AEB000BE6E0BDD1372175F570F93BF32799E0082
-:10AEC0005E4086D0F9B23615A39E12EDB332B8DEDD
-:10AED000C822E127D0CE225D04F146701F599B267F
-:10AEE000A0BD2FF01AB3AB264E01BBAA686BD4BE2F
-:10AEF0008AF67BFAA1F8F1FA17399FD07D1C34EE5F
-:10AF000023117F08BD26DA3912F8D582EE536AE3A1
-:10AF1000DBAB5413607DE572DF95B0EFA60E8524A0
-:10AF20004931F8BBFCA12320B7F27A7748001B2BEC
-:10AF30009D7564FC50CAA7FBBCF546E29549E275D5
-:10AF4000376D90B5D5467EEE5018DD28E6F33DE12D
-:10AF5000677CC2E305B3FDA163008FE67DDB14C00F
-:10AF6000F38D3BDF51463AD7192DDCA446E6BF34BA
-:10AF7000D53B23B0DFCAE576C4E39A0E2502F2A9D9
-:10AF800069F79EA80DECEC8D4405FE6FEADD732891
-:10AF90008FC227BF499B260762E3E5374524584FF8
-:10AFA0001625C63EF4FFA20AE86D2B7D839D0CF6A4
-:10AFB000CA2117E3FF0F2BDDBA44E1F8A123DC041B
-:10AFC000ED3ECC4D51F5600CEECFED99FFBC4459F0
-:10AFD000DCF3445214BE5DB69E1C276DD7759EA24D
-:10AFE000023DB9FC618F8FC229C31EDA0BFDD37DF0
-:10AFF0001EB58DF60D249129A8AF470987E916BA29
-:10B0000098BE91F1CB5C5FAAB003A7805C3AD7E70A
-:10B01000117614CAAB430EB68F0EC2D6DB99A915B2
-:10B02000C07A883703E7CD6B8A4AE00758E78DD1AD
-:10B03000955688ED47BDCE5E05E4FC1A2E6F2A9723
-:10B04000EF94DE33D041A98F9DCFE6EDDE21817FE5
-:10B0500048EBDB6A7CD89E2481BCD9CDCE29D6D0E2
-:10B06000FAEB0CF245EC238E9CA980F5B9FBFB9E14
-:10B070006572268AF427D66BC5E73C1FB3EF2EA274
-:10B080006602FEAEE8C5013ADEA1C2641C4FF0BD07
-:10B09000954FE7F9189DE7D5EF94209EE04B61F6B8
-:10B0A000A4589F68B7CB5755EB4338F4211CD6D62C
-:10B0B000DB116F623D354A681CF865CBF878CF5CD0
-:10B0C000F1963240CBF7FDF415A4C7B5DD9286FEAC
-:10B0D00042F72BCA5288DBE9FF2E439CF61266A288
-:10B0E00090ED3F7905F5CA257B59FC60EDDE3DF614
-:10B0F0006BDD313A0D9E786625D0D9DADE24E292F6
-:10B10000007F01E4532B9D523983744F7405CFB9EE
-:10B11000A89CD451AE927010FC1421873B397F1348
-:10B1200037FBFD46BE6E316E4C7EBA90DE8327A69D
-:10B130003CE3A4F05CAB4AAA0BF891C39B8E1F457D
-:10B14000394C4821F86B627C2BFCFE99DBED71F0E9
-:10B150007C1BE0D9AA4F849E0D3E5C45E02BF06736
-:10B16000E7701FD2EF3E05D7DBE1B3333D5FC9E2A5
-:10B17000DA1D0EA6473ADA9C11E0EBE7D22F7A5E91
-:10B18000A2F2D293A144E17BD0B6AA09EA0FE6B1BC
-:10B190007574D93615B7303D76870FF1974A987C8C
-:10B1A00062F2E8BE1F3379D2A4BBD17F6C0AD7AD5F
-:10B1B000C673099F4B857309127E5659EA89D1835C
-:10B1C00015BF81270E28015A7F492FE38318DC9889
-:10B1D000BE12744BE51CE2BD33539C5F868300575F
-:10B1E000EAD7B741FC41F8F5A90D21DD1318CEAF20
-:10B1F00099DCAF9FC6FD7A4785F36FEAD7AFD9F0E8
-:10B200006BF4836ECA7901BF825FA8FF68E2AB2747
-:10B2100038BEEFF731BDFA948FD1D59AB25EE4878C
-:10B2200035EFB7201FB96B993C71F79BE52021776B
-:10B2300073FB602B8E5393D27B910C7EF2BF4ADE60
-:10B24000769278DD37482DFF097932640FCFDF38E9
-:10B2500045ADFC720A571787016FF76B1FF3B73EB6
-:10B26000DC4511017C696F5146B2874F372E89BE8C
-:10B270002601BED770587FB8BBFAC23F409C7157B9
-:10B280001AE6B37CB07BC937FF40FB7FB873AE0AC8
-:10B290007ADAD71E42FA19F4BB54882752F1592B97
-:10B2A000517A68EBFD55EA4C382F7BEC8229203728
-:10B2B000DFE57C79E2C7F20680CFA67F7B7C0ED4E7
-:10B2C000AF894899603F7EB8EB5FFF0A7AB171E7BA
-:10B2D0003ACC4B6B7FEC976897DB223BD8EFBBD225
-:10B2E000D0CE3CFEC8B63900F7F6DE76AC3FF1C8EA
-:10B2F0000E2C3FF36F8FFFE22F60778452556877F3
-:10B30000E2C7DBFEE92F40E775A92AECA3296C67A9
-:10B31000E7B982BEAD726BCF01E453412F9780DE57
-:10B320000538D533F923E8F95D7EDEB4AADADD0508
-:10B33000F2ECDD2D9EC6787146C5CFF002B11894AF
-:10B3400063F512C6D9BA28D540BCA32B9954C0378F
-:10B35000655254C9A7F35CD1B0670EDA3DFA3BD70A
-:10B3600043FB25FB5C640BC6E520A84BFD0124755F
-:10B37000424AA8183C4AFD663AFACE2F29DD1EA69D
-:10B38000F201F58EC51F58D2F5C2FF801CAD730EB9
-:10B390001C0051287EEFE2F11BDA1EF54EF9FAF897
-:10B3A00071D254BF9BD32DD39B797B171504504E7C
-:10B3B00024A9E30DF6E998232D5B203D29AFB1EFD9
-:10B3C00022D8C7C5C5D74C45BA80F81FE81FDD8D08
-:10B3D000E3AF85F825E5BF73FC3C2EE225BE19746A
-:10B3E000FE1A3BF1B9E14BC86B0E94238FE2B8D43F
-:10B3F000FE40BB2AF0CB2B1E057B64BB239C3B0D80
-:10B40000C6E9E27A6B275B37EDEF8573543A9E7796
-:10B41000C6141CA7CF9181FD75D67FFECE3629B606
-:10B420005E4AA963416FC178656ED0337A3DE227E9
-:10B43000A0E0BE4E40935CDCF7E4152531FEB5C6B6
-:10B440007D409EC1F9F06C7F65857F5AEC2BE2410F
-:10B4500056786EE4F53FF36BF825BB324D7A2591B3
-:10B46000BDF2CC151F33FDFBB37750DE34031DC393
-:10B47000FCE1F74DFAF75A41C74FBD83747CED3EAE
-:10B48000A67F9BF7952A40B71FB46AE43D6A8036D1
-:10B49000F3F3D7EDD2C0F598EFF294CB0B71BD8FDB
-:10B4A000B9BE59B3F59DA3706E5AB82F17FDFC8F26
-:10B4B0009F72D5C338076D3684E7C19EF377B44BCE
-:10B4C000C67532BF80DAC148AACDD44E6576F0EA9F
-:10B4D0006DE0A7AD6D242AF07FB3857E9AF7BD821B
-:10B4E000F422ECE0E0C38B5733FBD3A5BAC08F9BAB
-:10B4F000C7EC5142ED51689F3E2FD2A6207D959614
-:10B50000037D3D73C52F3A418F37CF235E187FFBF4
-:10B5100018EDA97CDC8F4420CF65BBA3BBCA4EFBD2
-:10B520006FAF0978292429DC76A2DD4B8A15AEE7B6
-:10B5300056A3BDDC9C73958A7C6695074FB5A1DD4B
-:10B54000D51C48C6F55CB24FBA85D9236EC2D62F3A
-:10B55000217D5E12991981F8D9471C7E028E1F3B0E
-:10B56000FA56023C3EFE0925445A7FC93C46AFE9E3
-:10B57000F37A518E3CF7D47CD4E3822E3D4F26A142
-:10B580003ECFB07B2515F5DA9224235EBB1D4C2FF0
-:10B59000A5733D53B495E1B793F353A7DFC6BF8AB4
-:10B5A00039FEE2D52783DEFD88E31FC508C8772E64
-:10B5B0004FD6AE8E223F35ED66E3F992B4D25B0DE5
-:10B5C000F4EBAB667A519C07C0F9C0A238F2E231C5
-:10B5D000BE8EE0C3ABB681BD7C31C53BA894BC62D6
-:10B5E0002E47295D00DCF21A43480717FB6E5021F5
-:10B5F0003FD59F49D05F1C6C5348BCB8CFE35C8EED
-:10B60000FA3343651087F6677BD0CEF1CB953617BA
-:10B61000F42B95D49E009E7BA29D37E8CF557B4CA2
-:10B62000FC1E2AB3D176C7B23C0CCF91DFD8179756
-:10B63000001F06D8B816BB6FB8DFCDECC685DDFAA3
-:10B6400064F043C4B9868043A42DB9DE283F7FC28D
-:10B65000E11099C8E2A9D4BE77635CDB4BE701FF38
-:10B66000BE67E623CCBF6FC7760FFB997D5443F7C7
-:10B6700007769BBF28B49EE9538F1A0F1EB3FDC2F5
-:10B680002E5F590A7E65739D5B057EBBEF67D22AEC
-:10B69000A467081682DF1D5E8D7820140FC00F246A
-:10B6A000CCFCD2E69650243EBD2F42FE6B06FE93A4
-:10B6B00090DE310E4FE93DC2E89DE93FE1FF837C1A
-:10B6C00034E61D0A3920E44BB3323001E858F04328
-:10B6D000F39C810900B7D1CA938F1D94FF817F2805
-:10B6E0001C807F04BF789E667CB2A52D5009F55B57
-:10B6F0006A88B7DDA08FACFE12AC13FC4E21D74F89
-:10B70000FA42C7FD1007B0453B21BF42C8E1E6A79A
-:10B71000374F8897FF26E4B0D3CEE49B339212696B
-:10B7200037D0179CF979A6E017F3795236C48F8F7A
-:10B730009CF2BB791C7F74F91259A0CB41DEF4A4B2
-:10B74000605EBB881759C7FDD82F99E232C26F815E
-:10B750007307689F93C5F827258BF3679688CF46B4
-:10B760004CF41FB085DF813CA344FA4BF4FB5BC56E
-:10B77000AFC43C428F5AF12FCE4D603F8B26256ED1
-:10B78000D77D80C9272B3D4EE47C72147C0FDAEE06
-:10B790003FF839D770FCB2714878A2292FAECBB6EA
-:10B7A000A7315E1C4C9C779087268E2AEFEE402BAB
-:10B7B000CBAFFA0F9E674B564F34E559B9D5401BB6
-:10B7C000C451AB9CC15219E765712CCF1CF209E83A
-:10B7D000E1C9FBBA8B217FC91F329F9764D7279B92
-:10B7E000CE2372C319A6727E639EA9FD989642531A
-:10B7F000FD391BCE33D507F529A67251D70C53FB63
-:10B80000F1DD55A6F2B90F5C6C6A3F31B2D854DE57
-:10B81000D2D65B0F78397FD795A67E5576AFBD948B
-:10B82000C2B5A47795397FCC02CFB4BFCA71E9B055
-:10B83000292B8878ADB29BF3882FD8678607A4CBD5
-:10B84000019C27133EDE9C635346CA6F9D4CEC7FE0
-:10B850001E10FD83C3E9813807D4501C3F53D0B973
-:10B86000285BCFB584FC3853FA4BB44E417F89EA4C
-:10B8700013C1ED3B9CFF055C1C4370A95747828BAD
-:10B88000E3747021142E9EAF0E17EB789B529A3101
-:10B890004FF8352818ECE38156F37D98657A1AD372
-:10B8A00043A125A7B1A3591C389CC4CE2BADF5FFED
-:10B8B000C9E1F2218509E261947CFD16C7437F222C
-:10B8C000BEDEF0C9C16C90DFB504FD666F4BDB27AF
-:10B8D000A0B7AEB64709D0FF7D7C3FDB79BEE80359
-:10B8E000AD5E1CE7417E1EF9506B007F7FB8B51836
-:10B8F000BF9156157FEF69ADC0EF4E6ACFC1F70714
-:10B90000ADB5F8DDD51AC2763F6CADC7EFEED630D7
-:10B910005BD7307C9172B473429971E3A5D7E8F29A
-:10B92000A8F044E482B8FA32E13872C388F9E51B22
-:10B93000FAA5C79F35F0EF5B591EDF51C86D9C4ECD
-:10B94000A6C3F9E6E9FA7FDE4A1E7F76FCE8F948ED
-:10B95000D013399539211E5F87795EE563DB57DDAA
-:10B96000A54F4A0CAF189DC587539DF3E33C70D695
-:10B970002783CD60E82FEE9F88725D382DAEDD9075
-:10B9800097CDF46E7D123B8F5F6EE1EF6F6533FAFA
-:10B99000FD5636D377BF4B2067D2793D5DA703CFE5
-:10B9A0000787F1DD3DB3E3C1F7AEEC80292FC57AFF
-:10B9B0006FC53ACEEF1CDD63D4387C76BA71C4FE15
-:10B9C000ACFDAEE2FBFF663661EBFF7FC69FBFBBFF
-:10B9D000CE83FE03C0CD6FD8FFEFAE4BA98F179774
-:10B9E00069CF66E7A1D43A27C10C34F575056CC55B
-:10B9F000621260E7BEE3BC101F12790189E9D58E9F
-:10BA0000712484A13C1CAE141F01A5888E6F1F9A5F
-:10BA1000276A8779545B4CCF42AE0D31DCFF9087AB
-:10BA2000D303EDAF2B98D7339007EB3B537A22F239
-:10BA300043E3473AA71BD6FF0CE5CC9AECBFAF9C7B
-:10BA4000117C4E4EDD3B3E9E9EAC87B967507BEC31
-:10BA5000FE87989C39CDB8670ABF7A7900CFAF4787
-:10BA60000DBF7DBE51C5A53E77A54E26D4AFDBE008
-:10BA700064DFDB93537BE0FBB96B6C84A4527E8163
-:10BA80007552BED5AB08BBBFF596F09B5AA683BCDA
-:10BA9000DD9E1B7A309B8EB34A61FEE29FB2B4EF0B
-:10BAA0004339999F0B27F37361255BE98432D18A6F
-:10BAB000715F17F07D75DA0263615FEF4BEA44F066
-:10BAC0005BBCB6880ADF54122D61F9799130F86BAE
-:10BAD00099E72707C0DF4D9E40481FC6C75517C4CA
-:10BAE000D19494C117C701FFFFD286F7A21FF7B206
-:10BAF000753EFE403E9EB350818FF26232FC4EB7DF
-:10BB0000B205EC72DAFFFB52F8896CBAAFE35EA7BC
-:10BB10006EA3EB9ABCF9BD8C0CFAFBE3FBABF05CBB
-:10BB200021BA4BD615B8DFD0F7E1772FA1E35DD06E
-:10BB3000E7C0F8F3054446F9BEC64EB6021F25829B
-:10BB4000EF07DF889F07E6C8914CF95DD6FAF7B991
-:10BB50001EF82041BEF16BBC5EE4CF3844FE8C5F22
-:10BB60001B317FC661C99F71D84304CE851D43F93F
-:10BB7000330D04F367E838C6FC990FAAE2AFA39F20
-:10BB8000CB73C7172909C64DC5DF3F281C799F8E87
-:10BB90002F5CA67CEC587F37FE9E287FE73301A7F9
-:10BBA00004F94B9F0CAD2F97E899C67E8CEF62F39A
-:10BBB0001460BDC3920714AB67F93F1DE98C4E0EAC
-:10BBC000E4787DD7D0A1AF2103789FF36AB7CF0186
-:10BBD000F1A41051F7E0FD1EBB637040F06121B489
-:10BBE000B3BF0B76B78D4A5EB0BBAFDEE07877C0EF
-:10BBF00020B71669E63281F60639BC1862D8741F80
-:10BC0000C9E71563FEDFA72490E61D418E3638E5AF
-:10BC100090DDB08FFE0476C4859C0EFB73E3C3AF4A
-:10BC200030C766CA631ADE9FE703F07B68B77A47BE
-:10BC3000969F00DF70A6717C2B1E7C587F3A38FBE4
-:10BC4000E1B00DE26A9512CBF3FF9BC33B9DE7BBCE
-:10BC5000B1FB030E4BBEFAE25CEBBA59BEFAFDE94A
-:10BC6000A19939D82F30C1785F60AF5D4B9942BF41
-:10BC7000FD5CEE58E1B289C3D9BAEFBD3CEF3E5945
-:10BC8000262D7B0CF0B7EEF71B398CCE45FB0E074B
-:10BC90003BCF02C1E7A4726F0561726F454E21CFA1
-:10BCA0001F4FB703BE1AD8106485F7109E2F0938AE
-:10BCB0000F831F87BB158E21125809F9DDA783E773
-:10BCC000865C6D450E9DF79A57921590FF2B9D83CC
-:10BCD00007C1671DE8B31D1E47BFEFB8C71DDD498B
-:10BCE000E03CAEF8C967E837B542657915641EDAFD
-:10BCF0003F929E2F7F79FEE8ED9FCED47031F0C742
-:10BD0000FB3C3F5BE8A5CEBC131320CFFEBD8CCA25
-:10BD100029B97E8CC36B9940473F4F6274F4001D74
-:10BD20008996D7FD6222DE87BF2A37AC423B91E776
-:10BD300047B4C109909770A670A27F1C4047A783A3
-:10BD4000D39A1CC2F831353E9DF4E4B0F8DFE9F82F
-:10BD500003EFA195FDFDF843C0539C6388F5A9B995
-:10BD60008C0EC557C0CD9A4FA4E6DA783B96AF78D3
-:10BD7000556E08E17C72CC27475D74EDFD4AFCF7F7
-:10BD80001D9E1CE5FE05BCFF5E72B83F39FEFA5EE3
-:10BD90004CC0C7FFA8F54DCDE5F43339FEFADE1EE1
-:10BDA00025FC4264F0ADF4BF831EA3789E0A78267A
-:10BDB0001D83281FFB33E2AFF3AFA35E67D8F1F713
-:10BDC000D0B782BE897E4D239EDFE724C73DBF5F8B
-:10BDD00046FD29F087ACE7F8E2BC9ECA0FDC6F9DF8
-:10BDE00073706526E07D1EDF771689A6C3F9E62FFE
-:10BDF00092F03C60989EE4FC41E195920BFA64E17C
-:10BE000020C635FA27C4970B29B98CEE86DA77B1AC
-:10BE10007912DD43C8CC9546750F819485311E5843
-:10BE2000E97447658A875B383E94FC9B54B00F2BBE
-:10BE3000735E3A02FBA4F0FF70089E86FCBE13AD51
-:10BE4000CF7BC73912CBED35F213E52D71F63321D7
-:10BE50002B3C21D7106F5CB3EB05EF3803BE4AC80B
-:10BE6000808DDDA31EB499FCE46C72467EF27E17D1
-:10BE7000E397F73242A80F403F80DEE97CFAC252D6
-:10BE80004026D81990DF33E8494639DA9E37A3387F
-:10BE90006080676DAEB02FE50476E3D7BB1F10B3AB
-:10BEA0009B2493FD1A1BDF8EBF0BFC54BA5F8C8B57
-:10BEB0008F0959DAA500CFBF646897C1D70A3FFD43
-:10BEC000CE59E978FF00E0373736DE10FE13E0F98F
-:10BED0001B595A3DC04DCD0CB0BC0191D73714BF92
-:10BEE000B07B8F3A63F01E2D5E92797C8DDA0DABBC
-:10BEF00061BD4A12E747E2C67BE4C26E2116FB86AB
-:10BF000014337F7745CE4BFF03F19FCE54C6B29DCD
-:10BF1000FFE4423FF06AC9ABC0BEA9FDF1E6F76994
-:10BF2000FB3089BEF92DF40F859D91227F9932FA5D
-:10BF3000750AFFF97479D6CF803D46D7536573E310
-:10BF400079E733747FB9546E5429EC5B399F5215ED
-:10BF50001DAF4A2ED83F40D7F51939953C9B7EBF7F
-:10BF600043181CD6BFF2870CF047ABEC8E1346B9D2
-:10BF7000658D7FDC956B8E7F7C4616FEE67C80CBE4
-:10BF8000AC0C84CBE4A7E6651BE32F43F10FBE8F17
-:10BF900025FA354C9E5AE49C906736277B6F84685F
-:10BFA00024E0CDC2381283BB2EE1FB57B345199C68
-:10BFB000145A9EC59124417FBAEFD9FC4B56857324
-:10BFC00040CE405A0FCC47BDBF1CF8B65FA806E074
-:10BFD0003B570AD9D93A222C0F91B414407B9B735A
-:10BFE0004086F945BC02579205E3887959D9C3CBFD
-:10BFF0001D759FAEBC2E303CAE41DC1EB47F15BE1D
-:10C00000BEE35EB76E33C43B92DCD1E398BFCABFD8
-:10C01000D6B8C7EDB2AE43FE7632E94579E9767F10
-:10C02000A40330BCC42B41F9FB52F8E7C017479575
-:10C030006E12A4BF9FFCF9E704DF65831B6245F025
-:10C0400035EB27BF7B3DE645FB43768B5E0A4BC055
-:10C0500047D9F5D6DFCDFACA49FAF1FE90140DE5BD
-:10C060007C9979FA784EA2388EA38AA17EF0466632
-:10C070000F1F4E66FD0F27B37E6F71BDD49CA110BC
-:10C08000CC8BC9723AC19EFFD8730CAE6C823EE96C
-:10C09000027DE274688857A157D6EEBD9900DE9AFA
-:10C0A000F72D4238FC5E62E7A4FA0A09F319C4BB13
-:10C0B0000FF593C8CBB4279991C7FC94A5CF8757A8
-:10C0C00034D172DD4BA4244ADB95CE0DD5C0FB2EB6
-:10C0D000ED2544DD44CBEDAEF08F7E02FB7885BDCF
-:10C0E00037B68EDFABA59858B39B8EBFE3CA31EA53
-:10C0F00016D852F56027E40B0D6E265EC82F194640
-:10C10000BFA7283F507A7804CA74DDEB5687FFE555
-:10C1100036DA3EF725A2621B5E0F3E0AE04FE2745C
-:10C1200001BFCFA5BFAFE37454B45F62E7FC3EF636
-:10C130000E180E0EEF7439D9FFAEDB5F79F934BA01
-:10C14000AEA2BEA948DEE3687BC883824C04D69EBB
-:10C15000D8E2B51F07ED0370AECFF043F2147C3F79
-:10C160008970F937DDC2873363FC80F5A5BCBC8ECE
-:10C17000EB2913DFC038D46FD7CAD9B13FF6F331FA
-:10C18000FE5089F8C3F8790689FD8171AB63F3A08D
-:10C190005C9EC7EB0E2E5F80F9DFD3EDD103C0EFBD
-:10C1A00033F9B7947F81DF9D148E57D85B0EFAE97F
-:10C1B0007ED23710B50D666908B4C37865242403B0
-:10C1C0009CCBBD9BDB617D1736BC9209F475735E19
-:10C1D00011D2DF2CA75AE4A224D25EA1AADE2278D3
-:10C1E0006F4C42B82CAD774620CF6DE9D07B3FE154
-:10C1F000E032CA3F5784257E0F3F1C6C30C46D452A
-:10C20000FEDFB224EA5FC791DF37E731FD2EFAAFD8
-:10C21000E3F75344FDDA3C37CBCFCCBB68461E9ED8
-:10C22000C7B0BC68CAFFB3F3A6C5E40A9D17F356AE
-:10C230009610CD01FB5AC2F957F0FF52ED56B46784
-:10C240009786CC76E9EF25866F7DB98476E215F581
-:10C2500023DBAD0BF3C4B9708117F500117A8AD1D5
-:10C260009590E78B41BF831CAEA5FADC603737DCC5
-:10C270007E2A1DFB65FF60ED97E7C4EEC3ACB3DC1F
-:10C280008769E6F761D6ED6B736401BDF3FB30EBB4
-:10C29000F6BFD369CC0314701A7E1F6610F31F9784
-:10C2A000299103704F68D94D748FB4FDAFF8FD89A3
-:10C2B00067E1FEC494181D79AE7445597E9D867958
-:10C2C0007E05DE1415F252BA6C5330AFA82BD5A3FD
-:10C2D0001AF378B6B4B5D4403B914F24EEBF2C4B43
-:10C2E000706EFCCD3C663F6F97585E97BEDC89F060
-:10C2F000F6CBE488F19EBFBF2884F97433F202388C
-:10C30000CF761E5F80FCD3A9F41BA1661AC317EB7E
-:10C310006F950F74BC0E18AFBA48C53C9AEA3496B4
-:10C320008FE6CF0C95DE3229366EDD7E96BF57172D
-:10C33000FAE410CBC35D5406F04C24D7ADFA8BD28F
-:10C34000DF3D408FC3F556B819E8CF51155A7E1D11
-:10C350001DF7E4CB0AE6DB918D9AE4A0ED7EFC822A
-:10C3600057857B781D95A14535586FC77B8259F558
-:10C37000249A44EBCB5E527A20CFAF91742B304E8F
-:10C38000A3458FDDE47E56013EBD69A72346970491
-:10C39000F213D52210784DBB87C545500E09F964BC
-:10C3A000A56732CE2C874A85DCA5F281E5F73530CA
-:10C3B000BD477E20417CE8A4E798CCFD6B947BD3FD
-:10C3C00084B0B2C8FB69FB9F437B46C0730E9517D0
-:10C3D000E0C749F0FB64EC87652A4F8B21EF742698
-:10C3E00049467A1B6647F0F5950DAD9FD94D424EF3
-:10C3F00056561002EF2358F143E7433A17E77D7092
-:10C40000B402E70833F9FC9FDBB449D120E08B4448
-:10C410006C14CE9D520BEA1D27E481D2EF16298CB5
-:10C4200072F1A7BA2E035C2F242D4B160611EF2FA5
-:10C4300001DE6739FB52000F4715D509F5359030FD
-:10C44000885F33BEE6BBEFB303BCE6E758F1A2DB7F
-:10C4500001BE0B02C3F085F70BB404F8D2845C2153
-:10C4600066B91224A7D8FDE6CD876E03FFF874F6EF
-:10C47000C9F7B2C247E3D1AFB05312E5E59DE4F28C
-:10C4800078B47979271DCCAF984106AEDF2D0DA782
-:10C49000938F0F6E90730CF424E8F4699EA72FFD20
-:10C4A00092E7FD967950FFC5F425A383725E9A0149
-:10C4B000F465A083D9FB5C5199EEB394F79F01F426
-:10C4C0003025A62FA33677402904BCAB5DB23CDCF7
-:10C4D0004ECECA0820FEA7DA34C4FF34EA8171BB0D
-:10C4E000D39D4FF75FE1EC6DB70710FFDF07FFA6A5
-:10C4F000920410FF9516BD53EDAEB3039D543BADB2
-:10C5000078D610FF35DE61BFDBBE0AFECF01FC0B23
-:10C51000BD320AFB94E27F42FE08E78D89F07F413D
-:10C52000BEFB8CF23205FEAD781772608FCB5BEDEF
-:10C5300086787023CB4B9EFAF2B8762867AD0DE271
-:10C540007D993DE9EAAFB0BE85D597F56932BCCF9C
-:10C5500058B49ED6D3F29E60A81ACAEB3648284734
-:10C56000A7BD166E87F2B88DACBE7453CBAFE09DFD
-:10C57000B3753AEBFFF4F14E7CAF22D2C9FB57768C
-:10C580005743795D17EBFF478F5307BFBCFC48A4A7
-:10C590001D7E9FB895AD43D87D7339BDED919EF852
-:10C5A00015F6EB66FD6E38E44C66FE12B3E3E6F07A
-:10C5B0007DCE7D88EDD3F7DEC5B5010AF7EB0675B4
-:10C5C00007CA0D5B5339CAD1047E5AA5D45D00DF7A
-:10C5D000F9544E10C43BA5D34296B7DA43A75893FB
-:10C5E000CFEC2691EF0979E78B0CF85A93CFFC0832
-:10C5F000D12E2B83B0FCE407D9BBB3221F357A3F81
-:10C6000091207E007B44FD9B203F757E510BEAD339
-:10C61000F9E788BCD401FB2A3A6FE9977FBA289ED4
-:10C620005F7E4B3EB3938EF13C7AF17B63246803CB
-:10C63000FF640F100FBE03147D19EC963DF0BE9100
-:10C64000E11D923D4156D6F3F7DFDD459DDC1B6CC5
-:10C650002D761D94C05809DF55B9AC8F44D352874D
-:10C66000AF7FBE9D4459FE045BFFF5ED4ACF1683B4
-:10C670001DBF54888F59E351AFD4713C09B9B194AF
-:10C68000E38BF2F9E67CBAFE65CE16B41B9713A6CF
-:10C69000D76F24118C6FDC68E1F335EE3FBF65B3D3
-:10C6A000411CCDCCCF6BE972D8F9FAE0C3BFA3F03F
-:10C6B0006F7CC0E305FDBFB6D7DCAEF181978F304C
-:10C6C000FBCBCCEF8D82DF23667EA70605E3F7FB6D
-:10C6D000CFC3731B713FD0E51C7C4B27B1FD0EE926
-:10C6E0007D0BFFB9E0BE6031F8353696A7C8CB6246
-:10C6F000DE4FBB995ED6A95EE67E108ADC4FFB2F2B
-:10C70000C17CF852A147B99C11FC5CCAF5FC303DD4
-:10C710005E6BF577EE433E99CA4B56FD2DF4B6B8E5
-:10C720008748C745FD4DF5F5CB1A5D6F9FCD1D01BF
-:10C7300078C7F47604F9688A93CA6B1BE2EF00E0CD
-:10C740006F1AC75B3BD7EB09FD03F7FAB8FE01F59B
-:10C7500037F01C61B85F1035D9FBC3CE3112D8FF5A
-:10C76000437873517B2A05FC7DC2ECE23C32AA3C43
-:10C77000112AB7DFCC1F416F2BCFB0DF0777B8305E
-:10C78000BE20E2EC82FF5E2F6076F8B65CED3D9055
-:10C79000FFFD7CBE7E3E7EFFCDF3F1FCFBCF44C3AC
-:10C7A000F36FC867CA8F937F01E7DF1D8678697FC3
-:10C7B0007AFC38F8275CFE941610FCFEC9AF7D0A9F
-:10C7C000EB3FA6B038FBB164FE4D65E714FF3BD4E8
-:10C7D0009EC98F4CFE15EF911FCB30C7E7453B3FFD
-:10C7E000FFBEDFEA0C7518E2E181FB935A408FF936
-:10C7F0008B785EFC7A46C7279F4ADF617C272E50E4
-:10C8000050595A300DDA694A2EC4679E62FAA2D98D
-:10C810003EA0C0FB3E3E7F38A5C00FF79B88F604C4
-:10C820008C1318509650789FE4E7FE27F97B402739
-:10C830005DEC2BD6152858540AFD4EDE3C80726301
-:10C84000A8BC6800E542A02084F39E5C2AEA79F93E
-:10C850006E5626DCAFACE47C8271E33871E2E171A4
-:10C8600061F37B37EB94F8E7D5A4C0638AF7AED8C1
-:10C87000CFE2902B9DA4339FD65FBD3F1BFD8DC69D
-:10C88000547D02D0C3D78DE39E1CD387FBDA523987
-:10C8900038F6C1323C17C678D1DAFDCFA1FC5B2B4C
-:10C8A000F866AF996F66178CEE3CC51A671F053F97
-:10C8B000CD2F18C10E7A12F4972386875B787E53AA
-:10C8C0008DDC540D71A54F5713BC677BCB0B32D257
-:10C8D000D52D3F92F0DD0961C7ADE5704EB42FB89C
-:10C8E000A71030C815B8A71030F875704FC158861A
-:10C8F0007B0AC6F6704FC1580FF7148CF5704FC104
-:10C90000582E25D7B6439C6E5D17F14602ECDE82A9
-:10C91000B13FDC5B3096E1DE82B13FDC5B30963FBD
-:10C92000250C6E9F3E2463FC1FEE2F18FBDFF0C228
-:10C930008FCBA3B06D17CB536B7751F8031DEA5A19
-:10C94000DF240A9FD51C3E70BFC138EE07A9173DF2
-:10C950000FF859DD77FD42F85EB0EF26D3B8A49BFF
-:10C96000C9E316FA17E0783D09A5813F37850C1E0B
-:10C9700082784773445261DE1B1E30CBEDA1F74C29
-:10C9800022E6DFD71043FC37383CEEBFA5C0E343B7
-:10C99000BACA2379C6784F8C1EDC6A14E0F09AACD0
-:10C9A000C6A38752726E1AC6799E97218641FE48A9
-:10C9B0005AB6CF920CE703167824E598E9C21530F1
-:10C9C000D3454AB1992E3CAA992ED22ACC7491AE65
-:10C9D0009D37227C336BCD74B2466E42BE1770AE6B
-:10C9E000A07F01CE53E0854A802FDD27C48BADF0B8
-:10C9F0006DDCBFAD13ECFE3385EF9316F87E466613
-:10CA000055BB03585DE72C8FD93165CFB7E021B016
-:10CA1000357E2AE028EC081107A5FA1FEDE9985F9A
-:10CA2000CFFC3D6A1F1C2CC0F303E6E7012581DC27
-:10CA3000BC8E84513E5D67B10F6E70DFA7807D3084
-:10CA40006CBFD43283F70BADFB057B8B18E25256DB
-:10CA5000FB40DA2F453D9361BBFB859C0E7F89C669
-:10CA600090268D466EF47AB4FF02B9058EA2B3DC2F
-:10CA700014378E6BF7897508B888F993488B9C0337
-:10CA8000F45C6CB5CFCCFEB5F0C745BC5DC4B585D4
-:10CA90003F2DFC182B9CE57382ED40FF53BDC28FE8
-:10CAA000EEBB0A7E17FEB3D56F1DBA170090857BCB
-:10CAB000373C4E7FA77F9593BDCBC7F84EFCDEE990
-:10CAC0005B9C36523EE61DADE67B30741BDA88F780
-:10CAD0008A00645970EE4420A842B65E7A6800DE8F
-:10CAE000DAD97AD98B83CFD2EF96921F0C6C82BAA7
-:10CAF000535FCA00D7A1783E61F78415DE4F29E85D
-:10CB0000BC19F468B26A27EF1AE8C24935D5BBC52B
-:10CB10007C5ED0133943F5BF319EEBFFA3BE775146
-:10CB2000F8BC3B7E847A456D8C67D759E1259EC35E
-:10CB3000704DBAE838D8272E62D837EA4343598E69
-:10CB4000C10B55AB8CF7A644BD06EF977CDD7D018C
-:10CB5000DEDF7518CBD157DE7718D71F617905F660
-:10CB60001081FC5BC547EB8DFA65880E2943951B48
-:10CB7000F6378A7D01D380FBC9EC1286EFBFD5BEA4
-:10CB80003A2CF88271435967F5FAF4B37C7DD1B33E
-:10CB90001CBF64D1D90D3F6DD1D90D3FFD2C5F5F16
-:10CBA000F42CC72F597C76AF4F5B7C76E3573FCB95
-:10CBB000D7173DCBF14B969CDDF0D3969CDDF0D39F
-:10CBC000CFF2F545CF6EFCEA6807BA2BA204DE97D8
-:10CBD0000874103518A0262BFD19FCF92295609ECB
-:10CBE00006E17E4921F74BB66D6DA90717EA115D85
-:10CBF00009603C88FAF739B47E2261F58F742DC63E
-:10CC0000386BDB980979F05E95BBEBA2E3707F6F20
-:10CC1000A2CEFC71EBBF1BB64833FFFB6B9757648A
-:10CC20009ACAD3FACCEF575CD55864AA5F1E3EDF90
-:10CC3000F2EFE74D35FFBB64A19996F7206E26C64B
-:10CC40007B918524AA427CA5F06E5B159C9BD9C183
-:10CC500067BE90FEB753C17E1AFD6BF45F0AA92729
-:10CC600034347E10E0A698C6775BEACFF41EEAFE65
-:10CC7000B1F1EFA112786432CEBD736B1E26B1DF25
-:10CC800088F13981AF3B37DBD0E5FD6C2BC1771ED6
-:10CC9000AB23011BBE83CEF1763E273DB1EF48ABFF
-:10CCA000F93E7AA14EAA009F451DC406F1B5E04E9B
-:10CCB000A26A04E34248278FE8F1E9E411E2AD8279
-:10CCC00077B91E8910FC77B2045DDCE908E4C1B9CC
-:10CCD000DAF95D8C1E049D04804E52212FC8FAEEB5
-:10CCE00080155F644A94AEF591AD8519C67C54B247
-:10CCF0009BC1DD49FF8E84AFE29D667C0588A1FC67
-:10CD000015F0F5E9D7C497E20B45D37C10CF240189
-:10CD1000C8933A3866820DE011EC52D1FFAFA5CD31
-:10CD200000CEC12EF69E9AC093186F6B2B89CE331E
-:10CD3000F87F4135AA019C6BE44955907FBEA30C56
-:10CD400043C6C3F0B383789321EEBDA3CB968C6F1B
-:10CD500054EFA3782921E4BF372F4B2BA6F53D4193
-:10CD6000920CEF6CF5B4D9F0DDB29EA7A47AF3BBB8
-:10CD7000CAD1245B0EEE23C956815F3BFB6AFC4B94
-:10CD8000ECAC3E2A4379ECC661EF7EC8509F5E6BE7
-:10CD9000F97703892641FBE473581E679A667ECFB4
-:10CDA000C651619607148C7D39E5106FE1F4CEDF32
-:10CDB000498DD490C826BAEE73B8DCB1D251FA1DB1
-:10CDC0008B9198DAC67C03E5594F9B82F077707996
-:10CDD000453632BAD0E95FA0A7740B1D7954331DD4
-:10CDE00039E402CCC3157C25D623E66F1B93956CE2
-:10CDF000C775D9F13D6C87554E58D6E7866020C57A
-:10CE00009DDB4722115AEFD0197F10B91F7F774C55
-:10CE1000272433F815D6F935E553E89CBF8D7CF20D
-:10CE2000F031EF9CC6F6F999CADEB5AEEE60F4EECD
-:10CE3000D9CAE81D6E74B37C2D6D61AEE15C752FAF
-:10CE4000975356B879FAB46AA0E78BE49734C88F41
-:10CE5000B8FB3546FF6D630E3F0FE5AD7733F8073E
-:10CE60005586674A2F6A942EFDEE3BDC98173CB539
-:10CE70008CE20BF0FF92599E4CEB33C3B1C82237C2
-:10CE80008209E06AE5D74470FD96806B39856BD1E5
-:10CE900099C355D1997C4E9FC5DE593C384661FFF8
-:10CEA0003EAFCEE098AEA9287F2F924F45D368BB06
-:10CEB0006D1A9537749DB51A83B7779690E36678A7
-:10CEC0000AF922E05FC8E1EF55BD2FC0BFF3E2D6FB
-:10CED000ED2420017CFF5B033BA27B9A9037830407
-:10CEE000F096A631BA1570EE9ECDE05CA871387749
-:10CEF00071B8494402385BE9D52A9FD3BE269C7796
-:10CF00009DC3E3F159A4FCABC0795B0A7B47D931DF
-:10CF10008EC1D5E11E8C829CED0ADA715F07820A10
-:10CF2000D67795B0FAFB5356E680BEEDF277E60071
-:10CF30005DB605AFCF01F9EECAE1728668EEDCF2AC
-:10CF4000D8BD831A792BBE43DA1950103F9E407C1E
-:10CF5000F995362BECC47926D9898C7078488D07E1
-:10CF6000076799629297F98D66F8A658E0EBFA9AEE
-:10CF7000F2E1B5AF291FEE216CFD778E17EF347407
-:10CF80003B513F55DC8471F34C3ED7E685DF65BFEE
-:10CF900073BD66F8BDB610E489DBAE023C13ADBBD1
-:10CFA000A795F0F75A9CFCFD16F6AECB3678D785E0
-:10CFB00096BF03EFBA2401FDB3775DB6C0BB2EF474
-:10CFC000DB05EFBA9C0BF6B4865FF9D2427C7FF0AA
-:10CFD000B35A82F1F14D297F25F1E055D465D67F12
-:10CFE000413DD9F20E9B59CF65CCCB3395BDB3CC27
-:10CFF000EFB67954F66EDBFF0164680340008000F1
-:10D00000000000001F8B080000000000000BDD7D09
-:10D010000B7854C5D9F09C3D6737BBC966B3B9924C
-:10D0200040124E42081B0861810483829E84406343
-:10D030004D71435151A88D40314248285E1A7FF509
-:10D04000C94282841834A0585A2F2C378BB56AB441
-:10D0500051A922DD2052FAD5964551F152BFF55221
-:10D060002F40258A177C3E5BFF79DF99D93DE76425
-:10D0700013C0E2FFF8FDF1C1C99C993367E6BDBF5B
-:10D08000EFBC332184906FE8BF04CF0412F410FC8E
-:10D0900081BA433D9704EDD1FA23C3EB1C6A3A21D0
-:10D0A0005677A5E139F1F7115F22562D248390546C
-:10D0B000DE365DBED71E2E26644DCDAC24520CFD4F
-:10D0C000B450266D4F80469590D5566F968F3E4F43
-:10D0D000A85954435C84AC6A2124388A90F6163BE4
-:10D0E000962B726CDE601A2177BE2C7BE3E82B3620
-:10D0F000CDA7B969FFDE9C5B09A1CFD7B80919920A
-:10D10000479FBB9711924F88423F20D1BA5233E3D9
-:10D110002352425F98B3849049D1F9ACA9B1788386
-:10D12000A584C4253BBDF07D52ACBC13A66D6EFA40
-:10D13000DF37F4FD6FE0E782681947583BAE13BE56
-:10D14000A3EAEA04BE676C6F7E537A74AFAE7DAC1F
-:10D150009A98F63E2CF61C72CE37322DE579497539
-:10D160004E5A96A71092D5FF7B5FB69047F78E4434
-:10D170008012920E653D01782A7CCCD5C9B3ECC4EF
-:10D180001985B378BECACDE01B27D1CAE4FEE3B649
-:10D19000015CE3A2758510AD1BF0915D1AB3BF2849
-:10D1A0002906082923A4B32578F03D6BF4B9730A46
-:10D1B0007DDFD9BFFF4C55C679CF55552C9D4A9080
-:10D1C000B869BF442F7D5F0717A77666DFA73FA525
-:10D1D0006974BD2E4E37E477920278B5F37A8254A3
-:10D1E00037572D037CF9081941FB956BA4AE987D48
-:10D1F0004F13EF49502AE41D41DF79AC74D3760612
-:10D20000522869BBDDD8AE6620BC705C25FABEF63C
-:10D210008D34F0BCBFAB12F0F8CEC841DA6DDE7AC7
-:10D22000E0A77ECF558B80635F1A859BCCD71B030D
-:10D230008E6DC0DF028EB293C1B14DCADB19A6FC60
-:10D2400066D55C5E8A115291A676035FB6694EE49C
-:10D25000CBB6B4EE5025AD9F28B57861A8C49195A2
-:10D26000C88F6D43F71D5E08709DB9FFC36D08350B
-:10D270002D5425E04BDB133DD5A12A9DBC11F88A26
-:10D28000E7BF778C7D20BC9296A917CF236E4A2AE0
-:10D29000CE21362253BC384656D9EB9C51FCD8E0FF
-:10D2A00017FA3C3E6DC64732E5FB78AF0E8FF0EFC4
-:10D2B0001B564778D0C5DBB26FFDB904449119E91C
-:10D2C0007700E6A3A8BEE8FCC8D9C717C94E43BE7D
-:10D2D000278A3713E4657F7AF733BEE7FD06E60B4E
-:10D2E000D66FBA5C93791585CB9A17987C241E2645
-:10D2F000176C7686CF354463EDD98A97BE41D664E4
-:10D30000AE44F9D1AECE6F07F9F979A685C8123CC3
-:10D310005F6F07F9A198E447BACF62D00743E6C42C
-:10D320001BE4FE9A825928CF069A67569DF1FD614B
-:10D33000F5C6F77396A518EAE23D6BE6452F55A5AD
-:10D3400046EBAB943A3BC8915B33D74B753AFA1E28
-:10D350005254F73AD0ABA8DB3267E27B7139A53182
-:10D36000E7B5CFA3BD0572A25D65F326EED870BE0A
-:10D370008BEBA1BBB91E3AD53A37F2FEBFE6FDEF03
-:10D380006D716319C167C13506BCACCEA2F29A8E2D
-:10D3900007B0D77FFF29B5EE73985F14CF96287C2E
-:10D3A00080698B175B805FC5386D59F90EC0DBFA59
-:10D3B000EAC1E727F4AAE867557CC44BDFB312A3A0
-:10D3C0001CB7A5590CF89890C7E5C6B66B0CDFDD05
-:10D3D0009B3C63631EA5ABF587648274F73BE3FA5D
-:10D3E000FAD3AB711DEB33D9FA07A66FD3BAA944B0
-:10D3F00088D011D6534CF5A1A6FEF9A6F6D1A6F613
-:10D4000009A6FAB9A6FE95A6FA0F4DFD6799EA5747
-:10D4100098FACF37B52F36B52F37D5FF8FB17F2983
-:10D42000C3F3F5E2D920F205F4BAB9BFA268885F68
-:10D43000A1E7237CE536F2E30F722AB43C66671855
-:10D44000F02BE8F374F1B39ACAB810F093A23A50F3
-:10D4500099962F267A7A589F998FFAA38D4E0BF5BD
-:10D4600037B75F52041D5773FB70CE12031DF5E6EC
-:10D47000143AC07E24CE34944BA7A20B89A418DBA7
-:10D48000B5A1D1F67CF8FFD9A58B53D37180EBDD24
-:10D49000C1E72DE4C023C37DD7223E02D49E1E1BCC
-:10D4A00085931AB1A7E9C728DF6D49238138AAEF10
-:10D4B000B6F82D58FF3C937E08EC952AC687237852
-:10D4C0007F42C2128C23E6D3CEE9651DC8295ADEFD
-:10D4D00001728A96B7B56462B97AAD256B218C5713
-:10D4E00063433CA58EBBD5AF4059595E04FAFBB6E9
-:10D4F000B13B340BAD279E94497022B5174AAE2834
-:10D5000087E5244C9F9FB9173EF735FDCE24E04EAA
-:10D510008246C6E62A12B08E2364ED9EAC1F7AE8DE
-:10D52000B86A81E275405BB177859286FDFCE03692
-:10D53000A84ADFFE11B43EBCC082F685B5BCAF057B
-:10D54000EC7731EFB53FA4844B3BE6557B2D7E0A4B
-:10D550008215C3EB7E05701ADE492C1AADAB7E55E1
-:10D5600002B9F6469E8AF276EB1F28438E800FF5AD
-:10D5700065819EFD62AD6D25CC73603C11D952FE74
-:10D58000ED4B310EDA9943F1B906F4AC2A484274F6
-:10D59000951F76C13C9D32AB3F9777CCB7B2385AD6
-:10D5A0007F2CEF987B256DEF9C986B8175E4A5B976
-:10D5B000B4400CBA3A0CF218D6B776D170BD1E340E
-:10D5C000976A0D1D77082D8B7909B4760EC09F9749
-:10D5D0002A7F9EC9EA0738DCD466DE9EC6CAB3FD40
-:10D5E0001DF3F8AFE5B9855D3A94FB8FC5CE8C414C
-:10D5F000EDD3C37965FDED532AE886029D6FB27ABB
-:10D60000875AE8D89BD6DA889FF2D4A61C827EA2DD
-:10D610007F8D2DB01DF84351875EAAB3BB026B32DC
-:10D62000AED0E8FB0189CCD1CBC97B399CEFCA973E
-:10D63000707ED3E5637E99D2EF263F413B6B137139
-:10D640003BC01E89E0DBFFB90FE990E3BB2ABF6A4C
-:10D650001DD02959C8F4667E549EAD50E8389B61B0
-:10D660001C5ADFDC6EC1F96DDA45F9977EEAF39B4F
-:10D67000DFB180DD3C96042DB0BE312480A5872C1F
-:10D68000B30050BAB91EDFC6F9B790F237FA3B20A3
-:10D69000FA68FBA5C3EBBE06BE48222AD655BF1BBF
-:10D6A000E9A9715772652CFBC0966FE17E26A957D8
-:10D6B00026713F87C1D9965FD61FFE56B20CE17E18
-:10D6C00093C767CF07FF6EE7C1E030DAF4C4AB461B
-:10D6D000BA05A8CCD2C99D1CFE9D24AF4F93E93852
-:10D6E0007B72EB92E1FDC6FA4FF665C0D07E3FBE7D
-:10D6F0003F39DF8DFDAE08764F8761C679C395400F
-:10D700000B63AB7BF700C98CD136839B413CE53F73
-:10D71000DF93AAC23CEA86C23885A17005908FB318
-:10D72000FE603003E773BE05E86204CC87D3472D63
-:10D73000D2978A7422F00DF4504BEB573430F850E6
-:10D740008310DB89E236CC7FCB2A4A27CEFE749247
-:10D750009ACFEC236F148EC43AB87FE5CD8F41BFCA
-:10D76000022EB37ABC560817F87EE75E053ED0CC91
-:10D7700040DF5E077DDE9E5B770EACB374A3AF1512
-:10D78000E8CFB92BE4877E024ECE29214DC27EDA46
-:10D79000B9D06FD3CD9595A817BA08FA4B427F9AA6
-:10D7A000F16F9D62B4F708E9C2F58CEC32DAE994C6
-:10D7B0008E519FF7A3E39B23741CAF8F4B08FD137F
-:10D7C000E8B4C47BC0CFA0FE078E35801C7980EB07
-:10D7D0002541D7E27901891D67B8323FE2CF66CA99
-:10D7E00083C3FBCAFC18FEAC0BF86304F2CB7CC00D
-:10D7F000879BF461FBF09B8DFCD2B8F3937DC3E86B
-:10D80000FC9DA5EA04C08FF87E03C737A5E3C54891
-:10D81000C71BFBF6815E1B7E33A3E36BC1D6488F2B
-:10D82000D2E34D1E6D297C47D099793D4BF87ADAC9
-:10D83000737DD7C278576CEC7EDE81EFF9AE473E40
-:10D84000DB180A3A4814BEC3397CE36E89E0D90D6F
-:10D85000F263568DF779D0CF3E8F7B3A9433D5BEA5
-:10D8600036302DE6D6CB06BBCF8C5F4A5FAD485F26
-:10D87000C4374D92C09AEDB6A2FE1C806EA27AD338
-:10D880002FE8FEE653C8ED3B62E1E174C73F99EB38
-:10D89000BB1BDE4FA9F611E4D3D39DD769F61371F4
-:10D8A000B3A81D1BB0EBED5841F71DEDB3D04F16DB
-:10D8B0007810CF57B5CFAACE033A772ADE58FE4F5D
-:10D8C00044DF703ABF9FD3F97A6E7F7571FBEBF638
-:10D8D0001615E57B678B07CB8E162F8F879663B95E
-:10D8E000AA45C37EF29A4F2BD07FBF99605C6B65CF
-:10D8F0004289148BAEF2FC467B7F78B311EFA9D539
-:10D9000046FF3B596F2FD37F49E5F986F644EF6810
-:10D9100043FB69C48B0F00DDDBD22A0DFD48F813F1
-:10D92000837D2BE0385D9E87F1620A4FB4AB853D65
-:10D930002BDA09A9C378AED5E467769AECD80E80C5
-:10D9400023C297C1B10BE088F02DE7F0AC667E13DF
-:10D95000F77BE285DF53B47ECE7C8C8B1094572B03
-:10D96000726CA89F3BF298BDDD8F7E3275F293F208
-:10D97000FCEA354C9F0B7BFCF99C57AAC1AEDD92AB
-:10D98000694139B9256D8F672BD6E3BD4C9FFABB32
-:10D990003C147F560F8F57538ACDA2EB4DE47CB3D6
-:10D9A000DA4A30FEDD91EEF4421C2CD1B3A806FB1E
-:10D9B00099BE4BC8CF89DEFF23EFD51BEC0EA25CCE
-:10D9C00063586764FEA536368E44241827A5D866AA
-:10D9D000C09F9DE8EA79305F5B148F79B05E8E2737
-:10D9E000939D23E214663CB96B8CFA6675117BBF7C
-:10D9F00037E701C4BB19BEAE2A23FD7670BA684B67
-:10DA0000DF827C68EE6F1E9F4C8937F87F1D9EC1B8
-:10DA1000E324C29F16FDC08F76C7E86FF6A3CF86BA
-:10DA2000BFEEC6EF19F55D0C7F7DD2085D3C49C0A5
-:10DA30003B8207115FE47E98885B8BF114C2C6C3FA
-:10DA40003AC6B7FD28FF7E99E0423FB2C0690B801D
-:10DA50002C2CA0F3003A6EFB55426025ADAF4B98DD
-:10DA6000D99744EB05DB6415DB9DBEA11067EEDDA5
-:10DA7000306368987EF71EA9EEA211BA38DCB6E4CE
-:10DA80001B32993DA0BC13F600934BE8E7FAD74D43
-:10DA90000C69608F1711EF76025E306B17F444F457
-:10DAA00075B97FFDB3114CEF66CE25CBBA63E07F2D
-:10DAB0000D6F8FCA715F3CCA6B2EC70B38BCB6772F
-:10DAC000CD8AD7CB71DDF3A4587475B6E4771BC843
-:10DAD000EF51F09D1735D4DBA584CBEF47C8F75144
-:10DAE0007E2FCBAB5B3DA22CC67E9F1246F93D51EB
-:10DAF000D5DA01EFE9E0EF015E7E4AF112631DCF56
-:10DB00008E60F6CDF7152F42AF6EEF7A9CE1A558E7
-:10DB1000E0E57612CBFFFD1EE0E569807B3FBD4A64
-:10DB2000C2B80FFB45B6F60CB43FA56ABB007F1127
-:10DB3000FC5C169B6FFEF91DE3E77EEEB7AEE7F8DF
-:10DB4000E9E2F1F1DB397E3AB9BEEEE0F869E7FAD5
-:10DB5000FA56C04FDC99F3CDF066237E52ABE34D0D
-:10DB6000F830E227A9DC889F44AF113F099ED126F7
-:10DB70007C18F1935EA022FCE2328D78EAC737A7C9
-:10DB8000F057D2609C187672765DA802F6B886CE01
-:10DB9000E9EEB5C220BEAE0A28C57AEF35F9A5A2D6
-:10DBA0004C2F6078CD9C161BEF16DE1EC8D7A40242
-:10DBB0003D9DFC20361FDB79FF63AA1667E87F5185
-:10DBC000ECFE2EDEFFF5E15AA2BE3FFDB94B1EC4AE
-:10DBD0005F30AF3F41D2D20B701DEACE30C5FDB6EB
-:10DBE000156C1F729B43ED86FD7CFF0AA777BB8AED
-:10DBF00023F9ECE01FF171883F09C7CDE59F19EECD
-:10DC0000DCFF15ECFBE52DC81E7A356DCF5B9E79E8
-:10DC1000A48E96A30B46E03CF3EBBD7B00CEB26B2B
-:10DC2000CE50B67F3CCFFDFE184A6AC154E91B7046
-:10DC3000B8DDB1F7ED4529F42995836807D2890449
-:10DC4000B6533A8D5388929802EBD5705D56B06307
-:10DC500065586F17D6E34937964E1262FBD7DC1F23
-:10DC60003DAF200FC7731337FAAB29C48BA5E06310
-:10DC70007B1A51D227E0F86D7113082AFCF3C05FBC
-:10DC800075666FEE009F46A3509884AC82F090EECC
-:10DC9000DA87EB271EA2B278DBCD6ECC4FF8335D6E
-:10DCA000DF98D35FDFE9F6FBD2E12A21498434DB38
-:10DCB00059F98B78D71628BF74E4062068A58DA87B
-:10DCC000FB31E0D55F49D0FEF0BF951068C5C92E85
-:10DCD0003B87F907A73DCEBCB334CECFCED2388D2B
-:10DCE00005E9A71EE736F87532EC63FA9643FFB6EE
-:10DCF000E44968778AD20CD77D1EED06989F627F33
-:10DD000029F7BDD4A8DDE67C5342BBAD4D0A12888D
-:10DD100053FADF96D0BE22C50C4F4E9578F2C64519
-:10DD2000C7717A970D67F12E16EF59F1F75F8C02E4
-:10DD3000FBFB970933C349F4FDAD07A99D0779346F
-:10DD4000D3BCAFD7537A4A4FB579B750FA49E57E7D
-:10DD500072DCDA4907EAE9AF9F8C62FCBDA365BFBC
-:10DD6000BB8D0AA444C57BE104FA9E93EFDF12B990
-:10DD7000260C7663E22445853D8E2239580DF32525
-:10DD80004D16027C714F83713FB7B3B008E122EAB0
-:10DD9000C3F87E2E2955FA227936D48EDF58C0F387
-:10DDA0006A5CC40576A1F26F2D2956DE8328C5FC76
-:10DDB0004AD3A8DE4A82B820E5145A96760631F98D
-:10DDC000A3D21BB4831DBB2140FC360AA707E7FB87
-:10DDD000AE81F13ACB7D0960976F3834EBA2B17414
-:10DDE000DEA1B0E205100447A5E0BA439ABC368133
-:10DDF0003EDFF9A6C50DEBDBCADFEFF449C8FFF73C
-:10DE0000CC23013F85C7D6863D7619ECDE90858C04
-:10DE1000443B973A5C93B82854215ECBF8FE965168
-:10DE2000E9F8B027B43C19E0B22EE1FC9046C7AF48
-:10DE3000AD6671E71972F6F3306EA8D386F849E73C
-:10DE4000F94712A945FB39659ECE5EA6FF123B99A4
-:10DE50005F19BA8E60DE535299D3EBA7DF7B22CCD9
-:10DE6000F68DEEA96671671709E2F767C8BB1C1645
-:10DE7000FABCA75A71033D2599EC73278C4749AE2C
-:10DE800067231BCF359E8D9768CA83B28B79B9E91A
-:10DE9000BC28FEE44405F1ECAE36E64FB94CEF3950
-:10DEA0004DDF7B59E0399B14029E4FF86E98F812B3
-:10DEB000B67AD558F9139D2D2454A5CBB7700E1002
-:10DEC0003FFCB290F909B6ACBD7698D709DF2B6953
-:10DED00010EE7AE15FFBDEBB03CA7FFF574F135D95
-:10DEE000D75FBF3ABCED518063F36D2F221D72BF27
-:10DEF0006A084C81CEE7F95A1BC2B14C63F101525A
-:10DF0000DABBD75A8AEDB8AFB5768F03DB87959326
-:10DF10008083C27398A265FD0CF835247B57A83026
-:10DF200088E6CC9A44D85615ADAFBD92120E950F27
-:10DF3000E9F334D95F0CF190174822C5F7064D522A
-:10DF400059FE9BF43CF0534E95847E58CE219F039E
-:10DF5000E8E1C46C0BE6BFACA8BDF4C29174FCFB55
-:10DF60002A148C375457555C0EEDC30E317A715D0F
-:10DF7000C7F047E114ACA2FC30E2108B279492B0BA
-:10DF80003748DB877989350DF4C73C0A60985F27ED
-:10DF9000C70F8F0F949686FC00D444AF118F6E1379
-:10DFA0001ECD78758DA47804FD52448A985FC7EC25
-:10DFB000C75ADE6743D544F45FEF5189DF3AAE3F7D
-:10DFC000BE5EA4F6A346EDBF10B51FA1FC1BB51F96
-:10DFD000A1ECA1F62394895AC545A574BEA1743A53
-:10DFE0002EF05F4DD94AD81FB86FEAD537FD93960A
-:10DFF000657C9F8D726A4A25FDCE2CE062565FAF2C
-:10E00000519BE4A552D9505F9BA6887D3C3FE8D444
-:10E01000C42C0BDFE79971A746EB9D990ADFD76304
-:10E02000F511C5C450EFA9B118EAE7EDD18D3F0550
-:10E03000F01387F5092377AEF71744DBEF28A475B3
-:10E04000DA7E80DB73B54B2DBE2D31E877D948469B
-:10E05000BFCABF895FA2F8FAAC80A09F2E5B349440
-:10E06000DFA4505141BEF6D7CB540EEAFDEB022A95
-:10E070005775F191C3853CAEEEAB60713612FDF978
-:10E080007A12CFB322F0BC330476C4ADAF5EE90D93
-:10E090009281E5AE355339A2A7938B051D8C2423BD
-:10E0A000D19F27530E54009D754D54801E4A391F31
-:10E0B000106EC761889FD2CF539FDEFD174D053F7D
-:10E0C000ADDDDD3612F37E2E1FA9CB935995BE68C8
-:10E0D00022E83391F7434895FB7DBA2EC97FA90505
-:10E0E000ECB681ED1485BCAF83476FED8C24D00373
-:10E0F0004E2EC7CDFD57B5EC7C05BEBFBAA51B4B58
-:10E10000679A0F858C5DF163FC669FA7AE11E6658B
-:10E11000CFA6ED3A396C4BA3EF19FC806C667709FA
-:10E120003CB809C683C4BEC986CE09F17114189DD6
-:10E13000545F807CDE109A8579159DDE0983C6AF19
-:10E140004EC5275BAB5E2269148E4FBE3AF32FB3E8
-:10E15000697910F88DEAC12738DFE4943FF6DAB523
-:10E16000067E396AE297A3267E397A0A7EB9E04EA6
-:10E1700068EFC9540CF51CE0175D7D6B845F583D5A
-:10E18000CA2F47915FEE79D986F58D238F1AF865EE
-:10E190004521AD67EBF865BAECDB12C30E78E53BC1
-:10E1A000E2975F9F29BFBC7166FCF2C4D9E3973F39
-:10E1B0008E4CFFEEF8C5779AFCE2EBCF2F87605EBE
-:10E1C00067CA2F9DEE20E60376CEB6540762E0FBC9
-:10E1D0007A8E6F11F72EE3718A69F3B4CBC7823D53
-:10E1E000CBF3D6443E4DE73CA6BF57D4CE407DB9D5
-:10E1F000F520D397423F97713CFE8DC731CA424C00
-:10E200006FA6974BF8FE4C4D0AA8F4D74E6A12A49D
-:10E2100082BE9E22912E1596BAAC76A414B59BE8C8
-:10E22000F7D06EBACFCBF266C92166EFD8E97F404E
-:10E230004F17975B0D7A7588D9FE32D5C53EA6D8A3
-:10E24000BFBC0FF212283CBE1EC9ED2693BE15704E
-:10E25000D870A812ED90CFB36D83EE5775F2F546E6
-:10E26000ECA9525F45AC78587DA184F0BEC9A3C526
-:10E270001796813EBE0AF5AED0E766BDDC53F59237
-:10E2800051CEF8C7A75616EBE48C7F3CEACD889CAC
-:10E29000E1F501E50C3907E546442FF37A442FF305
-:10E2A0007A442FF37A44CEC0F8D951BD3CF281F1C3
-:10E2B00077FA757A7B19D4B34FAD9717707970B62A
-:10E2C000E5CC1FB8BDFA5DE9E5CA424E2FFFB99C07
-:10E2D000A929FC0EE54C2DC899A453CB995A90332B
-:10E2E000C506397355E1B7D0CB890DBD7ED8BFBF08
-:10E2F0006200BA77707C371568D7C0F8A4E6F4F2EC
-:10E30000B6CD74D55BFBC0AA0CA0172FF3F3067A29
-:10E310003FB1F9F7AFB4E9F2A21395103B5FD1FC1E
-:10E32000243E9FDB7010E365A79A6F7D21C1D2ACBC
-:10E33000477B6BF7D9916EBD16DC13FFB6F3E89CF3
-:10E34000CDF8F28DED4FAF073EBA8FC7FDCC76AE5C
-:10E35000C0EBE9DA3FE6EF5E3F52C571CDDF3F1516
-:10E36000DD523ADD0C747A22FBBA31E0E7C98977D5
-:10E370002500BCBE07FAF0C96F43A7AF8C64F83C18
-:10E380008D750761FCEF6ADDFF017FBEFC6DD6BDB8
-:10E39000A090D1D569ACFBBFBF4B7CFF07FEC26725
-:10E3A000DF66DDCB04BE093B2FE3865F289FACFF11
-:10E3B00057E1DB10BF58FFEFD18FC13ABBBEB26F40
-:10E3C00086F805F9FA1BD9AD3F3F45D8B99944FE07
-:10E3D0005EA28F9D877157EBCE4791E879295C0F3C
-:10E3E000C63722ED07629D97FBAE4BB047DEB10EFC
-:10E3F000D26E63713BF3F3FF2E90D83936A9D60164
-:10E4000079F1BDB3F760BE41E7EC09B86F65B6536B
-:10E41000C47B3D2D1AC6933A5B7C58DEDE521D82CA
-:10E42000B8C9932FBD25413E58E94B0DA8DFD64E04
-:10E43000FAE130CCE39B5A1A0FF5DB4D768A8BDB81
-:10E4400029DE51AFDFA9F75F9EFC4D13CA4111874A
-:10E45000BA2362BFD0F7549D9F44EB400E113F0991
-:10E46000EA063F69D97AB05F7AC07EA1FDA78E5ACD
-:10E47000B63ED677D65A483DD82F6B1B2CD5B1EC7B
-:10E480009770416CFB85D671DFCD91680FACCC03E2
-:10E490007B86D4E9E36AA7B25F1E1EF5DDFA495711
-:10E4A0008C3A3B7E52846FB9DD32A4485B0821D997
-:10E4B000B32527869DA69C18D65F4EDC38EA5BF80C
-:10E4C00049E102965F2DE86BABEAC578726735C10A
-:10E4D000F8636768656A09AD3FD1602112AD5FFFDF
-:10E4E000328B0B6F2827013847BB219B603DE465C9
-:10E4F00074304376FE08E2E03D55D47F52216EF73A
-:10E50000E35A80EDBA8499B73928BDD4962B04FC20
-:10E51000A619F214FC4E4863F9A1B54EF2A338F0E7
-:10E52000ABA62A64E519C4AD13E562897224E54FF0
-:10E530003519F876A078B439FE4CE417BC802F73F7
-:10E540001CFA4CE3CFDB055D7DFBF833F2DF970F60
-:10E5500034CD8278EEA9E871C12815F599594F9903
-:10E56000F958D0D340F4E7043B69A2AECECFE186A0
-:10E57000F93EB513ECA48951BAE8AD9D94142BFF74
-:10E580004A9409CD7F78457F1E2F41E9C6F1129A42
-:10E5900077E1F3BB206F00D6A778519E3E5849E53E
-:10E5A000708CF9ED6E597608E4E7AE96662C2F5024
-:10E5B000FAE414DAFFE916FF2180DBCE96762C9F71
-:10E5C0006CE9C2F69E968D58DED112C0726DCB0EEC
-:10E5D0002C6F6BE9C6F2C17CF69D294A10C7B9E0E1
-:10E5E000241D5F474753FBE87774F83EEF43BFA114
-:10E5F0007D72B8DDD07ECEE12E43BD2CB4D1D0DF0C
-:10E600003D2560686F2AA83B067CE92ADD6178EE2B
-:10E610002CEE36BC77BA7EC1D9EE976B7F04B6C9B3
-:10E6200049329CBBA0AFC8706E88F2F190662A5E3A
-:10E6300069FDFE441EE7E866FBE49924F283740951
-:10E64000A964601FF426B23CC8D62CF67EEB8DACD4
-:10E650007E7F0EDB3F12799AB23D42D744CA88EEE4
-:10E66000E7DF9FC8CF2915B0BCC8DCE200442448CE
-:10E670002E24A8C17E4829DB2713FBDEAD3CEE70BB
-:10E68000BF95EC94A83DD9AAB0F9B76A24B082F638
-:10E690006B2D66F57BAA48C002F3D7A814CFD0ED46
-:10E6A0007337EFFB4A2A89EE9793D11AEED7C87CCD
-:10E6B0009F3DB2EFED7897E0BE3E87D7CA848F3199
-:10E6C0008F36B9B94F02FE1AD2DCD70BF3BBFF1657
-:10E6D0009B1ACB1FEABDE58B2CE09B4D377E910545
-:10E6E000CCBE29923FD3E7D0E7CFE472B86C6ACEB4
-:10E6F000C7FC854DF52E2F87B3C5D48EF90C9FD757
-:10E70000F3FB0988827ED1307714AE01913F22431A
-:10E71000DE1D5DFF88E8F9D3FF34BF6653F37296C0
-:10E720005F934D787ECD4CF427051E364139AEFF00
-:10E73000B9DEEF3ABFE6947935A63C0703FD42DD2A
-:10E740006FA66F15F112C7E95BBA99E5456499E8C0
-:10E7500046E45D08BA14F919225F43E46FD8785E85
-:10E7600007FD2CCF6B8E4D5FB63DC403E7DE644BD7
-:10E77000BC774BDEA9F3089A3DF95C392C1BC7C660
-:10E7800065F903FF334AFB85A72C3A6E9E47BB51C0
-:10E790005F17E556F875321DC21BAE027BB5A85C4B
-:10E7A0006B85F37C29A504CFE994964B58161D621E
-:10E7B000F5DB3C327EAFCDC3E24DA27EB1A63D0774
-:10E7C000EF2799DEBB38F29E15FBFDDE63E1A5C2A3
-:10E7D000E6CDF3906772FA5E3D5966F9D155129312
-:10E7E0001BB0A13A89EB430ABF8B89FB92025DDC27
-:10E7F000F5C71C5BB7B7B0FC3E910FFDB79765CC72
-:10E80000877696FBA6C1D9B3B2502808FBEBA5DBEF
-:10E81000883B4585F98535E0C7153977EF817C88D8
-:10E82000272E647BB6171F62F6C28FCBAFC6FB469E
-:10E830005C5FCB188F754F49F406E0433556A6FF51
-:10E84000453E74B9D15EA835D90B179FE2FE8F14EF
-:10E85000D2E7073DF988C7148FE5F7800C24BFA3E2
-:10E86000F78030F950CAC77496BB1D10BF2E3A64AA
-:10E87000C1E39EF2364DC6F3B19D2CCFE389906F74
-:10E88000D0F3A82F723886B89CF81BCF93ECE172B6
-:10E89000E2752E270E839CA0E52B3C4FF210CF9300
-:10E8A000349F97D8D152FD92DEDE319745927F1684
-:10E8B000E6416D56089EBF1BE0BE8FA2001DC790AB
-:10E8C000C7B802E9676FF2DD15401CEB350BDA952E
-:10E8D0005D5348562CFFAEEBC2CA41F30F3B5BE6DB
-:10E8E000BCD43688DFE8B4517F26D6FB1E71AEABB0
-:10E8F0000BCF5BA4955B08E45565D9FBD8FE43AF0D
-:10E9000003E97988D78EFBFB649E93BCABCB53B9EC
-:10E91000DDD7350BE6FFE03605CFE7887113BD7410
-:10E920003E3A3A499BB22713E6DF39359809F64C4F
-:10E93000D7F87D1B0B205FE4A04C800CCCF3B21603
-:10E94000717F96AF2B4DD1A45879EA03ADEB038FBD
-:10E9500064B867C20CFF01ED0EC80818FCBC95B383
-:10E960002846FEE269CC13EDDB6F765C3B1BCF4D96
-:10E970009EE6FD17099C0EB3161207FADD408F8341
-:10E98000E0D9650D21DED62EB454C73A5F5B54C47E
-:10E99000F0BDB6F453B48B4971EC7924959BE9959D
-:10E9A000CDE70E858E4FDFEB2A8D3DFEE51C6F9483
-:10E9B000AE5F0379D5556D41BB22092E62C0FC1CA8
-:10E9C0006A074948EF28973E2BB5313BC1242FFAFF
-:10E9D0007DBF54474FF9FDE5D0F9454E437CFF44D8
-:10E9E000F6ECA4600C3C8B52C051C8A1FE70247898
-:10E9F000FEB58BC39114C7E6EB28BE56887855DD6B
-:10EA000029CEEBCD2E2A8B714E6C003C98E9E18E1D
-:10EA1000853E5C1779EE35A282BE2CA5FCA88B43FF
-:10EA20000C043F33BC167EC7F032B7FFA888C74737
-:10EA30004E739DA7DD8FDA456E9D5D0C87A2155A3A
-:10EA40009FCAEB3FF64BE17BA85C9576FD09ED9EF6
-:10EA5000A9BCFC3194543FEE9282EFBE415F9E22EE
-:10EA6000A93980B4594F8F820819B9555A66B07FB9
-:10EA70003A24EFE167302ED4970AFDA6933A852118
-:10EA80003980EBFA93146E05857529D15641D94822
-:10EA9000BA6CF05E63CF9F0EC3771A7B1C4119825C
-:10EAA000933BADC7F471A36BF4E747F2E0168D6EAC
-:10EAB0005B1E9DCF921DC67DD20612C2F196761BBB
-:10EAC0009F9BCF8F4832050C5C4E10C97F9D82F909
-:10EAD000BDC4C1DAE3478BF3E87D85FAFBCCEA39A4
-:10EAE000BCEAEDCE20DC2F4402C6798A7B739EA758
-:10EAF00072CC3E01CFC33C0C74FC91DBEEB7507B73
-:10EB00003923A5AE11E07115516DAC647683589729
-:10EB1000B887668173B60DE0BBA0DDBC0ECD06F3F1
-:10EB2000F959D7E0EB1378FF4711C175DC5EA46299
-:10EB3000B934BE66BF06CDA5A15CFD7D104D5C3F1E
-:10EB40009065A906FE7D51D023D1E4D3597F7FB8CB
-:10EB500016609C4CC075603A35C6C976C121D77421
-:10EB600084DFCB7AF811A5AE04C615EBF96759E836
-:10EB70008120ECAB26B27BA0DE4DA97B03FAE71C1B
-:10EB80000EBF2FD1A913A75A08EBFC78E747AFC8EF
-:10EB9000F9D1F51112BE1BF2A3EB77CAEE0E58CFD6
-:10EBA000CEE70E03BD0FB42E911F4BE901E146E7FE
-:10EBB000F521E837F3BC8EDE407E0A76C974B9D8F9
-:10EBC00010477986C3F19E62DFC7F05EE94BD92E0C
-:10EBD000BC7F27BF7BDF503A8FBEEB25CCAB4D937C
-:10EBE0004915C04FE4237CEA54D0CF4E4BF0CB2ED6
-:10EBF0005AEFBB8A78B7C034BCCBBC402A724EB146
-:10EC0000B783D24DC6F5B20FE4C9DFAF5B90BC80CD
-:10EC10009619890B9347D0F28238E277D0F13224EB
-:10EC20008BAF1B8350F3932FA1F3FC491C9D27ADA1
-:10EC3000E7DD90101C41F9ED8F3662077A4D4BA845
-:10EC40005B371DBE932CE37C8E503B51A172ACE22E
-:10EC5000F2CF26DAE9F7867EED9C00F3C96A9E467C
-:10EC6000DEA5A03C5CC4F8E4E8C35F4E8473E0F228
-:10EC7000374E2F9E33E7F4973682C1C38CEFDD1CED
-:10EC80001E6FC6337FA731DD762BC4DB3FE6FE0F58
-:10EC9000D13CE82F5CC7FD8537E3991FF466A18856
-:10ECA0002F05D3F5F66DA3434BBA0C9C076A274199
-:10ECB000BEF3676E2D2919FA111FF2ED75DC6FFE98
-:10ECC00098906AA0F3EBD64C1B9242DF4F6F6570B1
-:10ECD00030CF6FEC68A69F1B4E5282D6C5CF1A94D8
-:10ECE000A00DE477C3499BE1F9DFA91DEDD79D573E
-:10ECF000FFC98787A6C3FCAE24E155D0FFCAEB123B
-:10ED000058E09EF36B0F9FC74070694C568842E1F4
-:10ED1000D12811DF60FD9EF9B71C13BEB34733FB4A
-:10ED2000257D5AECF55DC4D7376D75CD2F81CE1A90
-:10ED30004356B4E5AFFB43C590C1ECE7C693E791FA
-:10ED4000802EFED7A884111E8D27CFC7E7D3561F6C
-:10ED5000B301DDC3382A7D7E9D431B02F1DA81E0D9
-:10ED6000BC9BDB418D2793893F55FF9CF17774FC59
-:10ED7000346CFF2D87DB6FF75BAA63E577358F6611
-:10ED800070199DAEF8201F684C90689B637C57F407
-:10ED9000CB4831EE5F98E7D55319BE12E67D4E158C
-:10EDA000D1627D6F3187A3986F4F4A78910FE9B395
-:10EDB000AF10EE9988D4DD7DB9FA7B24B672FCF5EC
-:10EDC000FC309C0BE37F7C61EC733B02CF9394653A
-:10EDD000682FBF9052F734C8B77997D10AA58F2111
-:10EDE000F38216763EC53F28BEA370964960E26066
-:10EDF00070B661BB18EFA317393F523F1CF2D4AF76
-:10EE0000E2F2FFAA6D4B30EF49C8A98F36CA28A796
-:10EE10003E42DD42CB8084F6EBFC3A0A6B2A571661
-:10EE20006D9FB60FD4C15599D4064D61CF6F86B290
-:10EE3000CD6A88F78BEF2D38CCECB7859D463D57D2
-:10EE40004F3A3F01FBE0A317993CA0FC6D0379BC4E
-:10EE5000E82EE338F5DB2EFA00E6576FF2CB33B835
-:10EE60007E36DB799B47F3F8FE2432E94CFCF24610
-:10EE7000A2ED188D7AC127C33CCA14E33D5BA24CB6
-:10EE80002F61F05FBEFD84CDA50E3CEE112A470A2E
-:10EE9000E8B8C7A83F0EE51F476BBF1F4DF170FCD8
-:10EEA0002083CB81D1754FC1F78E1F64EBFFB4E196
-:10EEB000D345704F0C99C3EC8638387C407F8D9BCE
-:10EEC0006B0FB4D2F5AEA662CA01E782E2983D228A
-:10EED000EC3059BE5676D1F6C9FF58980CEB4C7BF6
-:10EEE000E807D5305EFA43091AC0ADA3421B0FF202
-:10EEF000BEA3D6E985F32A9B291996D3F7ED741C96
-:10EF0000D02781DF4EDE03DB9105DDEB2AE1DE1742
-:10EF1000F7AEDEE030BAAE760BBB27A3FD7CE26D28
-:10EF200025D1EF35EDAA7D0CE6953B9BEA0709CE8E
-:10EF3000D16BE3DDBAF109B7AF1A394E8E3F3BEA28
-:10EF40008EF3E05CC27E19CDC74F1BF2D1AF1F4DCF
-:10EF5000183D89FC7BF836D891027EC7A8BE22BA3C
-:10EF60003CB5D1DD52D04AD7B5B4E731BC8FA361EF
-:10EF70006530632EE8DB0715A647F9FCD2FE9855ED
-:10EF8000A9BAA2FA77AEE4463B52D8C99713F15317
-:10EF90008CF1C2399C0F2EE7F6F1DC0406E7F9C4C8
-:10EFA0009B0BEF5D61272E0B85D9DC69DD65CB40BE
-:10EFB000EF2EB126837D036B898577519AED20C1B1
-:10EFC000878D0F24FA21EEFAB1D45708831CB13291
-:10EFD0003EEB7B362EB025AFFF38D631CCAF6F2C51
-:10EFE000E4765D01D1E0FC40E3EE51781E2C2E9ECC
-:10EFF000E27102CA3F3BE0F579D0FF74DDD73CE314
-:10F0000008E2B930715F999BF813E9779A760FD9C6
-:10F01000027646DA086DFC723ADEC7D6702ECA0B4D
-:10F020002ADF24AA5B73C7ACB944A17CD53894DA33
-:10F030005DB47ED14377B37A7E789185D6AF7DE893
-:10F04000D14B144A9F8DA3C3EF43FD96879E66F56F
-:10F0500009E14532AD6F7C683FEB0F7BD894B0B6C9
-:10F060003F74E012F0FF8F2433FB8178C35702FD19
-:10F07000343E3DCAD2A15BEFBA314C3E1E71B07E28
-:10F0800047F2C84F6701BC3DE1C259BA7DB9EBC731
-:10F09000083B96D971629DE23D92197BFCB1639861
-:10F0A0001EBD661AEB7741026977B0F3757EB0C773
-:10F0B000F6EE1A8570491993C2E145C7298D8E2352
-:10F0C000E028C613DF5D0C7A1DE4BE95CA7D9D9CC9
-:10F0D0003997E38D7EA70DBF53AC8D877BAC1A6744
-:10F0E000658F07BC517C291C5F8A1D2F57DBCCE63E
-:10F0F00047C74D2E413D3311E2CA7BBFA6FDF3A2A7
-:10F10000F336D3C78C314C1E5DD3CACEF7F7258FAB
-:10F11000403ABA2081D98BA494C28FCAB38D1C6E99
-:10F12000EBC624333F32828721128EDFCAE197CDAE
-:10F13000FA9FE97AE7F0799CEDF5EAF0A4417C6565
-:10F14000EFCE22C4D3C6081DAC338C736485E9BDF1
-:10F1500072CA78308F9411F8DE6A07B1E373B22572
-:10F16000F25E1E7DEF82697D13811F96727B98F897
-:10F17000CFC7BC86062E2D96B6876C10975EDACD6B
-:10F18000E2E4A480AE0FE863564D295F9F9BAFCFAA
-:10F19000CDD61730D02739D4973B3BB13FDD46E081
-:10F1A0001E19AF78021FCFC0CFB1C603BE18081F0B
-:10F1B0001D671B1F629E267846E06C9A9F8027F091
-:10F1C00031BE576CE42731CF5BC644E2B1467ECEF8
-:10F1D000FB96DFAB60EF2DBD91E211EC1FD548CF60
-:10F1E0004B7BF22CF38BA3EFB577AFF0819C4F9064
-:10F1F000541607EFA9F583FE6BDA558171AAA54F66
-:10F200003DFCA49FBEBFF8D10D2E48AEFA48E9CA16
-:10F21000003BB861FB2A17DC33F7A1E27781FCFCE5
-:10F220002820C7CC5B7F9BCB01617735727D73E46F
-:10F23000B7B7CD04787CB1DD8AE70C9B76C405E3D3
-:10F24000306E720DDA63B4FE36ABAFFE04FCD8A6A6
-:10F250009D46FB69F16F3664A8484FFE6116DC04D9
-:10F260000B0E83CDB0C66D56DC4F693C247BE9673D
-:10F270004813E9BB15E6677E1FE67192E2BDA95B04
-:10F28000BE0AF2FBCCED5492A03DD6D4731BDA69D2
-:10F290004D3D177E00764593299FA27E003BECC52D
-:10F2A00031DC0EE3F7A40BF890403ADA37AD0FFEED
-:10F2B000B2E46D3AAF63DBFEE2928AF57A7325E23F
-:10F2C000E9D3EE059B9E5607D6AF1F837D10A77F1F
-:10F2D0008FE157DD29B18DA15DAC6CB0065D101FCB
-:10F2E00068D86CF5520D4C1A1EDEFAC0AFC1BF7C57
-:10F2F0002DCE0BA9A64B1E7EFE9573697DC963D6E4
-:10F30000B41A367D27EC730B3C41CE06D829022F68
-:10F310008B7FFFBC0DE290F01CEC5E819F258FF58A
-:10F32000DAE09C9F198ED3BA7B6D980F6BC653F7AA
-:10F33000DB33C004697DF04B1BD0F747BB25BCF71E
-:10F34000DEFC7EFDE6E75D40870027F04305BE2238
-:10F35000F8EB87B7E0CCA74BB11FC6434E85BFC7BC
-:10F3600001476548E78F3C0D7194D7E3BC0087FAED
-:10F3700047AE75C17A3E5096317ABF6F5506DC971D
-:10F38000576FF567B8B164CFEBEFBF1EE9F0EA83C2
-:10F39000D767B07B24B42C768FA63F0BD6F9B37B0E
-:10F3A0002FC1752E22754887F5F7B1F8C6E70AA96F
-:10F3B0007E2C06BFCC2D66FCF2C19638480E221F6B
-:10F3C000C03E02EC9BBC28E3B9FB7EF72291E558D6
-:10F3D000FF9CC717C61547EEEDB3837DD7C47B35B9
-:10F3E0006D5B1D023C1DC9D186403C9FC2C1CFE16F
-:10F3F00026C1BDEFF2C1E943189E880AFB21F81E21
-:10F40000B5C7A7C173E81FB26A8E12C37BFC7E1B0F
-:10F41000F67D11DFA0F38E87FDF40F32585E9E79E2
-:10F420007D1DC5421E9010D1D3D940FCBF6D0DD2B9
-:10F43000D7678718FF34066AABB13D640D0E81F6BD
-:10F4400040EF6C09E5439C61FF3C421FDBAC9CBF75
-:10F450008DED749E8AA487EF6E09EFD314F4B2E8A1
-:10F46000AE38C37E7D947E8CF745097E157ED6D559
-:10F470005C1E98D76D960F97169BFE8EC2BDE9A7AE
-:10F4800015FF6EB0061EF835F033E55FBF0AFC6C61
-:10F49000C5F8C0D1DF3DF7CA1594EE8F760B3E3626
-:10F4A000CA5B331FD73F5E4662F1F151A797C4E4B0
-:10F4B00063FA3C261F3BD9B9E9FF57F2F6EA01E4AB
-:10F4C000ADBFD8286F3F27C549E711D0334BF0BEF9
-:10F4D00057337C85DF6B96A399C56A4C394A7F0EFA
-:10F4E000111D3C051C057D2E7E68297E2742C782A2
-:10F4F0004E051D47E8D4BC6E233CCDED5530775DFD
-:10F50000FE837525F563C0CE7D560E6CA1533B4E30
-:10F51000E7722B85FFF1DFE561BED12AEE071C778C
-:10F52000F7B9207F6C15F73BFA202E99147DDEE7A2
-:10F5300060F6D2715F9F2B596737BDBD4B76819DB9
-:10F54000170E90EA58F1242AB1711E6132503BDB4C
-:10F55000173BCEE3A1C779BC73BAECCC6D8638708B
-:10F5600017BBD77FE18ACB5CB02F707CD7883B80FC
-:10F57000FF7EF66799DDEBE9D714C89358C0404089
-:10F580003E24FEBBA7D0752ED8B504F31BCC7194D6
-:10F5900045CE6DB8BFF039B9194B73FC6431C4590D
-:10F5A00080DEEF353DDF7511D2D762137DD5017D49
-:10F5B00065F5A7AF1704BF8E27E3F5E7CF9673B9BC
-:10F5C000375D2EBE03EC99E3D4CFC75C02B9F800D7
-:10F5D000E8DDCFC1EF07C6F0A723DD2EA9FBD0C61B
-:10F5E000EF71467A177468F6F7CDE5B127FE3EE96C
-:10F5F00026DAA5E1C9374AEEA1E5B1275F2B7C06E3
-:10F60000EA4FBD9AFB06E9DF7FDAEEAFD0BF39BE25
-:10F610003B0EE7737CF79F726F82FAD37198877500
-:10F620007C651CE645F9772706E03CDFF11C16B740
-:10F630006B7DF6CB12CCBF206D88C793C536668F25
-:10F64000ECFA9FB7207FFAD35D712AC4299A7627F6
-:10F65000A0DFDEF4B403F35E8E3FFBE5247D9CE97E
-:10F660003F5D4FA38DC5338F2792398F033D2733DD
-:10F67000FFAEE999C95B215F6E694FAF0DF607A632
-:10F68000FDF15F2520978E3FCEEC0FEACFDF0F37DD
-:10F690001DCA639BEEB652787F0C3622F5C3378DB8
-:10F6A000EDBE14FCF0FE706170384EE100EBA2700C
-:10F6B000A907793A103C868EB521FD7FFFE0F1095C
-:10F6C000FA170DBBCE413E8AC245D2D8F3C4805D45
-:10F6D000C2F5B3E7BBBF2C017BEA68F70AB40B4E57
-:10F6E000B5EEC963BFAF74F06DD72D054F67DD73FD
-:10F6F000BEB7F866F4FF16D757663EE84FE74FDD12
-:10F7000080F54712BD38DFD3E4FFE6FFDFF0FEB837
-:10F7100084FBF2A7C2FB2FFFD7E2FDCF1CEF896E5F
-:10F72000C82F3BFEECBF72896EFDA75AF793FF4BC3
-:10F73000D71DB18F649F1DAEB8EF24C1109C5F5FD1
-:10F7400035809DF2EE5849E4EFA01F22F277E4B431
-:10F75000C56867C8691D6837AC22EC1E64BF6AE1E2
-:10F76000F7B1B1BCEFF66C6F00E3A28AAF7E33ADA8
-:10F770005B8737783B7004A37F2667D454439CA5EE
-:10F7800075059D171DA735DDE26E55E19A764B3064
-:10F79000AE04CBB7A15C9DF1C3FDF05DC569BCAF04
-:10F7A000D669F237E20B6CC6BC62B2C70DFBD50E50
-:10F7B000AF0277B95353D678BF6DEF58B6AF1D4F30
-:10F7C0000298B779A6704A2D191C4E66F808B8F54C
-:10F7D0008313F747C57DFC4A5A4708F85021D49F48
-:10F7E00064EB413F14FE8E14ECD7589316793BD846
-:10F7F0007E8A1AB9C71FF220B8BF19B96756B5A0DB
-:10F800005F2AE0AC1B0FD76F86F399C257E0C54162
-:10F8100066219E1DD94E6F80CE7F95CAE0BE8AC2FA
-:10F820001DEE1717F0157033E3E17DA0519D1D1FEC
-:10F830002D8DF93AFE4AE2817D96E9F294B01FECF3
-:10F84000E5F204B4978F49242851FFED5845462529
-:10F85000F815C7726C0A9453FBE89A74F3BDE0A4E0
-:10F860003DF237F4A05E41920DF5633985F8FE3420
-:10F870007B96E1BD0390B74DFDF66359E576DC0F4D
-:10F8800075E719DE9B99E0DA02ED07208F1BBF3F79
-:10F8900003FD9B1F641619C699F9CEB17BAFA2E593
-:10F8A0004EEE57F74DB5623CFED89FE755021C2F30
-:10F8B00054C71BFA1F24EE74202ABABE2A58DF450B
-:10F8C0009EC986EF36BCBDA710E2103FF256189EC7
-:10F8D0005F5C7EA1611C9F3D1C04F2AED56A0DCF1A
-:10F8E0001B9ABF204A2A21E7357F4D9489D47C0F8B
-:10F8F000761BC699B87FA7A1BF37E49E0626E3848E
-:10F90000C3DEE7A014F9ECB654BBDF42CBB16F57AE
-:10F91000CAB0EF59F65E5D2B84A1CF3B463C400751
-:10F92000E79078DC0F1C28EFFD4B4BA00ED6F90BAF
-:10F9300039E081327ED8A21258D747999D326C4B5C
-:10F94000DF23D55D5E0276D6678156A85FF075B776
-:10F950000CFE64EB0E19CFD74D976B12FE0AF2B86E
-:10F960005BC21CFF06A705E3F04753BA4BAED5D1E7
-:10F970009DC8DB31F371D1C48A25307E5BA6D6D514
-:10F980000BF2B4F2EF57CA31CEBB12B7F15EBAA296
-:10F9900089BEDB619F5EE425C54F935972FB0FACB6
-:10F9A000182FB9D5E27570A1807AD73DC3BA19F87E
-:10F9B000DD3A8EC98DF8BF1015E241F1A975329C70
-:10F9C000B323774898D722BEB7A09CE5DBDF5E2241
-:10F9D000EE3771A7FF642CBC9FC8F205209606EF96
-:10F9E000D558D04E711DF6EE83FBC8EEF41C728321
-:10F9F00078E8A979C70FFB223D874353258A9721D1
-:10FA00009D15270A587F02F1CD1E4F55C258D46F5D
-:10FA1000E59887B39CE7CFF44EFD8D07F4C7F2A2BB
-:10FA2000D14306CB2F779D9488AACB33B08E5371E8
-:10FA30005E2E258CE7C55C27156C27E1F1CC1FE411
-:10FA4000E3BBE6A9AF5E0BF3D86FC57C67A2684B3A
-:10FA5000601D1DA3DF543B701D84FF5D9130FEDDF2
-:10FA60003CC84FC20BD19470E64F629CC33BB2A31B
-:10FA70002C19FCF2D40A2F9E1B4C7D588E9C9B05A2
-:10FA800038DC0EFFC373B597BE5A45C7DD01B2928D
-:10FA9000B50709A5EF0E9B68A7A2C6C3EF3DC4F644
-:10FAA0004B2F831843BC6CEC3F2E3FD25FB36746AD
-:10FAB000C7FF43C9A5AFB6C584671CEAEB8E1956CC
-:10FAC000CC9F38355C134E01571783EBD7542B640A
-:10FAD00044E38BEF496A2ED0DB9D705C80FAD1BF86
-:10FAE0004CAE0B96A4C3FC8363E1F97C9736642A81
-:10FAF000A5BF1E9B967B23C6491C98FF55FBF3A30D
-:10FB00001BE1C8986BE6114F1BD08DA2254C8038A5
-:10FB100095FB0B940B22CF2D0A474ACFF49BB75B82
-:10FB2000A2759013AE285C35B82BB84307673BAD80
-:10FB3000D772B8FECF23F597B5017E17DA912EAEB6
-:10FB4000E53CD5964CBA20CFEE84FB814B811E4E0E
-:10FB5000ECB062326B0F34821EF5D8D9DFF5490B59
-:10FB600067C2DF71197BD082F1BD37297D68401FE4
-:10FB7000C1F1087731DE8929AFA6C0F98913694A36
-:10FB80000AC06771D88670FB894282707F6A4FDA3B
-:10FB9000C26915C81F2AB677F371264FD4FE518269
-:10FBA0007A9D9FFFD5CE95E1BED481F065DECF87EB
-:10FBB000F8F0B92903D3415B851DEF1F6A2A5F5115
-:10FBC0000C7A62797221E663355549A8879B9A3F82
-:10FBD00043B88BF1959332517579533D104D4CD705
-:10FBE000DD237FD286ED0DCD27509ED3E9E401DFE2
-:10FBF0001CE3FB9D5D56F2D35A5A36FC5BFE69ADA1
-:10FC000013F72DDB419F34903DB6E53A7948BA3F72
-:10FC100089C8FF71147777D6BC180F72B656725F19
-:10FC200002970ECCEADE7B19ECE7D73ADC97C0FEF0
-:10FC30007F8EF71156CF715F02FBFD631F4D9A0354
-:10FC4000FBFBB559EE0DF09741AFF016CDC1F63C78
-:10FC5000F7CB509F316E06AB27323A4879347F8E0E
-:10FC60001FF5B913E1F2697B4260B07B48AE6E7E4E
-:10FC7000C600977EEDB284795198B841E9E79F6B51
-:10FC800086B17B710B4298A735721C8BAF67A4B00D
-:10FC90003FC92BF277D346100DF657D39E72B07B37
-:10FCA0005BDF0BE502FCAE7ECA1184B8E4D2FB9E9A
-:10FCB000B3813E9A2FAB85C057B3CBEAC68C2B835A
-:10FCC000F84908EB5737EFC679754C70F3FB72FBB8
-:10FCD0008A217E55CFF39EEB4DF9BF8B9D7B311E64
-:10FCE000B7789B31EEB68484DF023E6DF8DDE079B3
-:10FCF000BFEF58D83C140E8FF972E84A1B9BD7F916
-:10FD0000E3E8F797A6F462DEB1E20E65D4217C1B2E
-:10FD10003CE8AF64C6E3B99A5B87BE5E12EBBE985F
-:10FD2000EE16AAFF29CB3DDEB2134BE77882EB1922
-:10FD3000A2846D5E3A4E2397CB9342EFD8F4F983B9
-:10FD400073395C9376B2FD6F735EEC5CD05700172D
-:10FD5000BECFBC74D60B53002F029F1724906ECCDD
-:10FD60005F4D215E8E172FE045C03FBADF4CDFCBE1
-:10FD70008B451702FE84E5DBC53379D1F78403EDAB
-:10FD80002BF3FCAFE3FA57ACA39DD7079A7F3BD781
-:10FD9000B7677BFEED5CAE9BD721F8583C177C6CB7
-:10FDA0005EB798F799D359C8763A7426E44C23A9DC
-:10FDB000F3605C96CB150167314F01AF9E01F25D98
-:10FDC00095E63F18D6A3842AF1B0FC7650A420C74C
-:10FDD000BA2FC4942BA57917F63BD3F508793BD0FD
-:10FDE000BA849C35AF4FC85BB14E2177C57AA75214
-:10FDF0004182F210EE7E90C07FA833D8C3157062A6
-:10FE000041BF0F64FFB9A13EDD7DA3A1FF0F3257B3
-:10FE100018DA2F54D718DA2FF2AC33D47FE4FD95DB
-:10FE2000C9AEDF6C68AFD51E34B44F0987A681DD3B
-:10FE3000FDB7966ACCE73EFFC3BEE7A01E6C7163B8
-:10FE40007D4F4B26967B5B54E4EF7D2D1E2CF7B740
-:10FE500078F1F97FB59463F9428B8665A8C587A5CB
-:10FE6000592ECCFCFD650AD8EDE5A12EF407C68F0E
-:10FE7000AFFB0CE4E1014BA03591C2E99C37997DC1
-:10FE80004E02667DFCE55B37815E77B37BE8DA7A0C
-:10FE9000274B6A0C7BCE45F59DA6A317574D98C0FE
-:10FEA000FEB28BC4CEBBFC6A1CCBF7C17C3D4A9B27
-:10FEB00073ECEC5EDB397324CC4F9C43D879055A44
-:10FEC00006EB68FB4C85F841FFD73A15DC8F22FC26
-:10FED000FCF0256C9A70BFBA3F0EF4775A2A9E57F1
-:10FEE0009A0D0FE97C654DC6BCD64BCAFF82F980DE
-:10FEF0005738D9DFCDBA7CFFCA7FDE44DB499BBFD0
-:10FF00008C9D8710F786BC6E3913BBE12B386300DC
-:10FF100079A09297FDDD9464C5ABF70744F9D771DA
-:10FF2000CC1F98D9CACF0B1C2468C7097EA4EB6BE1
-:10FF300087F90BBEA8752BC1512ED0F7EBA641FF58
-:10FF4000FF0B270420E00080000000001F8B08004A
-:10FF500000000000000BB55A0B74146596BED5D591
-:10FF6000AF904EE88400411E76886020AF4E271D7A
-:10FF7000C26B28124054C446650714A540313C9317
-:10FF800018981547F774633308AC6737337A5C5DAC
-:10FF9000C1D3E0A0ECACE7102171339A300D2A8F69
-:10FFA0005947A3828266B141E4B126742428E270E5
-:10FFB0008E7BEFFDABE8AE4E02E859939373F35797
-:10FFC000FDF5FFFF7DDFFB552D3FE4720701A0BA71
-:10FFD0006C4D1E14209D221DB7215DBEFA3B30F7EB
-:10FFE000C3F1EA0B602E06982ABF164C2D01387F0C
-:10FFF00004DC369C3FA65D3DB3CB85FF5CFE5182A1
-:020000021000EC
-:100000000100ABECF83F8ECB3AEB2AFAE2BF45E1B8
-:100010007A30D335FCF911FF8A0F34813927361E27
-:10002000F77DFDDB346FB75F05B305A0D93F876966
-:10003000D8BF18CC2300F6FA6B78FC8E7F358FF78B
-:10004000F9034C0FF8D733FDABBF8EEFBFE77F9EB0
-:10005000C7EFFB434C5BFDDBF97A83DB09D01FE084
-:10006000426BC540350F8F46632F6E689F9CE94BEE
-:10007000416A16740E1DC883D40E968C0CA473248A
-:1000800096075E0F403AD3B08AF79767BEC5F2C0B5
-:100090001F9F1DF99D0DDA4F463F339402DC03820A
-:1000A000FFD965FF7D494AA5819A23A1BCEECDEC1D
-:1000B000031B2580FB2090BF00E99CCA3ACB7889BE
-:1000C000EE4F719E42794881CF4C3FE6A24CE867E3
-:1000D00052778A078553BADC6480A58EB556180E10
-:1000E00080523A1141F99A40821FB3009640D80AD3
-:1000F00074FF8F96139138392F03C8826C3CFF6BC5
-:10010000169EAF5F077A3E6E5DB94286B274929BCF
-:100110008BE5B60222BC9E4D7EC45DE3A0FDEAAC39
-:10012000B44EE2BE4B1DEF5871D0C3BEADFCFCB562
-:10013000F6D5F55405B080E6AFCD54EAF6E0BA2B1B
-:10014000FAB43D209B7A9087D3DC79653D94C3BF98
-:100150008C127A9553A6D85507D9A9034CA8C7681D
-:10016000480ED9709DC55975A9B42E1A662AE0F5B6
-:10017000252D32EB03CC8A7910EAAD52D35B3B8458
-:100180003F21BD544EA89C01A8BFC59B8CFC2C757B
-:100190009C64B97F0BCD3DF25B054F7F23A776E7CB
-:1001A000B76AC22DA769BD2A4D6E7C1DCFB5BA4D69
-:1001B000DAF14EDCBC95EE948C53C9E4583086E4F9
-:1001C000827CB8C3E46F8764F6B7DEECE39C1FD88B
-:1001D000DE2FFA61C73B68FFE72EE3851B009E70A8
-:1001E0004F7B3E30E197D35BBF62DF0637F913DA0E
-:1001F00009F991AEC775684380E75E576E0F0550E9
-:100200009E51AFD34CFB47A5503095F47209DC6B7F
-:1002100050DE939BF71F213F996C7784496EC84449
-:100220007BBC5E27B58BCB134F868229387F7C5BE6
-:100230004026B71D7B480D3A703CE63D05358D7173
-:10024000E61D9F4C7ADFE96F6239D4FBEB99C6FC5F
-:10025000E726F6331884D7B2AFDFCFE021BB89E2BF
-:10026000DA4AED4CC134A83361C0EA724C93539022
-:100270008FAE30B8E97AD1215790CE55DCA6C8A907
-:10028000782EEF493548E75E876A506C1427037271
-:100290005FBC6E3343D88671C4966902254EAE6347
-:1002A0002F84821407F5B8D69C24EC79D2E57A998C
-:1002B000E296D3AA6EDF82F2843793DCDB5CDDCF7B
-:1002C000FD96DBC472FF32DDF7961B29385C237D77
-:1002D000F9643FEDAFBC48F6D390ECB6E173897199
-:1002E0005A8F8BFA3ABADC7439563BBB38EE2F5F23
-:1002F000DDC5712F71DF6A13A8F528774F85ABB87C
-:1003000016D7695F03F367E1B8CE8234AFFBFC8F89
-:100310003CE5EF93BD4C9527B42A742EA7E9AA7645
-:100320005DBDFA1BDEBFD7FBDAFED52D5EE7424787
-:10033000ECBAA34812711ECCCE53F6983EAF57EFDD
-:10034000133BE718F2D6A4EF5543DE9A8C9136FEA4
-:100350007E85FD11C378AAF331C3FC5B32D718EE5A
-:10036000DFEADA60B87F7BCEEF0DE33BDC2F18E6E7
-:10037000DF59B6C5707F96F21F86FB33655024F4B3
-:10038000B97C2964213F9B0BF54CE7412BD307A097
-:1003900093A98A96447421B8993E043EA62B3CAAA0
-:1003A0005C847613B5740E20BFEF78E3EF796417A1
-:1003B0001DBF1AEFCC72C5F2B29EA77F6A3EEE63F4
-:1003C000453DF5600F038A84DDEAF1BE57FD24C484
-:1003D000FB6811C6133C67B43199E34C34A54F4810
-:1003E0009262F1042DD244F958F75B3DBE14CF73ED
-:1003F0007FB092FCE83D1946B8BAC79BA9662C0DA0
-:100400003C74DD9D737F7E6CFFA00916939D6D4744
-:10041000FA3AF2D1775EC4EC8AE3A780F8407B9B7E
-:100420003C770A44F0FA4C272821CA4376C848A2F0
-:100430005878B92B6F36068899DFA3A2D09E7F48E3
-:10044000570A49DE81A726A49DCAD5E2D28DA8BF4E
-:10045000E326E6079648A111288FA60631CE5F94C1
-:10046000C6FCDD0761D6E3FD10B110FFF301384E85
-:100470002F0017D30741617DE2CAC905189F1635C1
-:10048000983D1B91CFC2F4CEE1E49FF9638FA64B58
-:10049000782E2CED14E2A7D004EBA9BED1F9A8D593
-:1004A000F8D858A454D0F90AD35B373E83FB77368B
-:1004B0009A602BAE737AEC630F435C3EDEEE299FAD
-:1004C0004EF37648A0505E0DB4D842DBB268FFCE42
-:1004D00001940FF4792B3C15338B70DDD945C0FAAC
-:1004E00086D6BF00E9679653C81EA6F46719E07365
-:1004F000C37CF93DF967809F2B2459DE00E2421945
-:10050000EFCBE3875F7F6DCEDA3CE6274075DC7684
-:100510008F3A9FCF6FC55840E7DF6C0B6DE57AAB24
-:10052000669884E7AC7CC966A2FC7F14E333DC0CDC
-:10053000F0B9DFCEF47FFC4EA65FF833991EF7BB0F
-:10054000987EE9CF61BAE87B6400F577BA48A922C2
-:100550007E7AE3A3F73823F8884A30A7DED1FD7E00
-:10056000A5E60F050D279F4C263B6892DD64A7F991
-:100570008D689878EE73CD63427256BC5CD5C7899E
-:10058000CF82A68FFF30BE849E333B259C7FAEA9D1
-:100590006B00F96FE2F9AEC8A3C52AE4A19D7747C5
-:1005A0005AEB467A7E47E3703A21C611107648FA34
-:1005B000947AE2630DDBC9AF8A44BEBFD3D659E259
-:1005C00074C4F8032A3130CFD46A7966AA7C39958D
-:1005D000FC6216AD3B96ECFAA60F68BFC001E1873E
-:1005E000A8D7F9BE387FDAA5C941A7F92D561FF95A
-:1005F000D38E964FEEBA1DE53073DCAD5ED9159BF8
-:10060000FF3209C14BF67DE9DF9FC9E0F94EDA6A96
-:100610002E6C99EAC479F7D9F7BC4B22B8DF797C04
-:100620006A1A8EE7674AFB882E70654D4BA7380023
-:10063000217EFEC19CC9FBC8C466B86759A99E98B3
-:100640004C4E1517772BEC186F0C71BE9F617C4BCD
-:10065000E660C3FC5B5DD986FBB7E7E41AEEEBFB13
-:10066000CE70171BE691BF52BD8D7CB0DE619B1C26
-:100670001A21911D5CF86C19F33FB784F88FA2FC26
-:10068000AC58389C29DBF0DC3314361AF7A6927F7D
-:1006900026D6B5CB5B5EDEA7B87AAF6BABC0D737DB
-:1006A0002CF55ECFF6560F5E6F5D8B71E40F14472D
-:1006B0000ADFB8C719C473EC187BE90617F2F761B3
-:1006C00051CFF56E54AB7713EDE88ABD4A2E613FEA
-:1006D0000765A07A48AF7B13ED08E049AD0E10F432
-:1006E000A7FAFBCC8F44DEFA8AFCBE5FBC7D6B347C
-:1006F0005464C8338556CC2FA89FCEBFC9B0952E61
-:100700005CC673E87AC88ED93F3CB4E5DD41257CF0
-:100710003D40756D15E5055C3FD923897597EF79E7
-:10072000775046EC3EAC3A6E980F4F48FB0CE3B561
-:1007300059C6F1D393F7C53FDF5B3CAADCF488557B
-:10074000C5385DF9ACC4F92AF1BE7E9EA97B93142D
-:100750008A9BE6661BF753554E051407554D98477F
-:100760007AC8EB7A7C982B434D4F716E80B6EE8C35
-:10077000BD4920FF8C758FA2ADD07902FF25F2CD47
-:10078000D1BE0AF8E2F6C9F288FAAF23ADEE9FBEF9
-:10079000C3791D7F063789BE234DC4DD8286D326EB
-:1007A00013E5BF3EC25E0A9C11533AD2E8E2E40070
-:1007B000A03F552F4909980AF1FEF0CE4FECA8FA58
-:1007C000519E412FD8516F9F994C86FC13A5988755
-:1007D00063CFCECCB9947F6EDF9B1436FD0C7E3C8C
-:1007E0005473202D2C177EFF00D98DD84701F48F2C
-:1007F000EADF81BEAF427182F8A7F132CF90A3CF7A
-:10080000E2BAD507451CC0DB8EC47EF6BEB87E16A4
-:100810003609FFB5E32FD53B55109AE620DC208C36
-:10082000FE0FBF9CFFCFF43832B8CE213FBFB9BB1B
-:100830005FEB7E5F7D58F8FDF9E66F3FA2387F1EC3
-:10084000F35FBCDFEB72D3FDBDFA7999FD52BF7E39
-:10085000AE599E1EEA41CE65BA5F296EF6D75AA7F9
-:10086000D8B776E2C5BB28CFD5B6A086A4EEFBE804
-:10087000B47ABD0CAEB87D76ECB62D0E39627C44F0
-:10088000F5FCDAF26DFAE43C41D750FE853A2DFED4
-:1008900088BA06F3AA2583F2EA2CC9BD0DC9E196F0
-:1008A00081E524BFC312845D1E5EE21E3B9EEF6E97
-:1008B000B11C5D77507D06993966DAE72E4DAF772A
-:1008C0006BF8D2EC96D92328DE7FD2B0F0B042513B
-:1008D000CE93CDFBFD1A025C1F1E4EF30D5D89E722
-:1008E0009C1914767E38ADB39DF0A8C31393A5A0D0
-:1008F000C4EBAF8DAFFF0E5B7C436B982F0D97520F
-:1009000046CB3F26FF847E598B8BA8CF8024FA3BB1
-:10091000F603F3A0A719675802A17D0AEE5BE50E66
-:10092000739DBA0C042E9058DF574DF8DA4AF9211E
-:10093000B11F9DDCB4E78854D0038E9160B7D7C255
-:100940002D12FBE0DEF0871FD27DDB3C71F8616287
-:10095000BD7EA52ED5EBAA6DC9A1AD789EB727FEA9
-:10096000DBB965385EB52DD9497DF7D9976C018A19
-:10097000CF67B7DA4212DE3F9BDED9467DC8D99DEC
-:10098000F96E5C012A4DAEFF7C8DF2FC9F2C6C173A
-:10099000006EE11F57ECF4D16314EF6AB7A548402D
-:1009A000F5B52AEEEB3DA0FC6A0AD7094B760D0A95
-:1009B000D9A4589E21FF706169716673924245FF08
-:1009C000D90377F725FCAADDF4FA30C6C3E4278EF5
-:1009D0003D86CF2D7B25C543F504E401EB6DF1D6B3
-:1009E000515BA83E7ED1A2EE27FE2B5EBD63601652
-:1009F000ADFF717F207EA2CDBB06507D14ABDB7BAB
-:100A0000AEF7CE3767F785BC989C743C71FD1FD755
-:100A1000F848EFC9928BAF9BA146194C76D1340BA5
-:100A2000685D8F2C29E4979D1B92B94E4DB4BB6332
-:100A30001ED1A72CD7F1877E60CF24FF5181E5100E
-:100A4000DD90BB7523CAE93B4FBA96AF3B47DE95B5
-:100A50001F6F9F6D556F917D6EB2312ED29E64AC2B
-:100A60001B74FABF9E34DEA7D27EC1804354ADBE54
-:100A7000641CE761BF87CF7B82AEE24790AED4E4CF
-:100A8000DF35DAD7E1C1E797D6FFFE8DF7582E9B09
-:100A9000FEF133DAF78043E031EF09F925F60395EB
-:100AA00076817B006CE1F3EAD74F6FFEB480ECF007
-:100AB0007463EE48D2E342B9F5D48BC8E7B994D653
-:100AC000638F23DD79E023D64BE27913F19B7649DE
-:100AD000627E97131F78FD1EAF4F2EEECFEECC7DBA
-:100AE000DCC28DF92CBFA9725E5FD263F46C2FFD5E
-:100AF0008A764E7D7DFD7CFAFAFA3C67B1D0D7FB51
-:100B00001AFEDE616D3D47FAED782357227CF0CA6C
-:100B1000F5F4D682B4387BF9A570F97B357CE4888E
-:100B200069CD6FAC688FEDF5CF58D4F8B8F713F1F5
-:100B3000F82BF5A0022EE700914A386F2173661C4E
-:100B40004FD4C7E40C389EA01D4FA2F3A05F4ED433
-:100B5000282C5533196FA7F590264188C7C1C96E57
-:100B600017D149928F710FBD6F98063543880F9347
-:100B70003DC238E15AC227B16E999DB6EE8E2CDC8B
-:100B80006F6D7F5847F5CC5A8BF08BC08264EEE7CF
-:100B90007439E979069C7986FCB2D6092E33AE33D6
-:100BA000C70CEB2DE962DE8D28E7C30716BE4BB8F4
-:100BB000EBA7E69AFEB4EF51C7B3F99289EABC50AD
-:100BC0000AF58C9F7DF427EFDF70EEE7A04CA4BA06
-:100BD000E29EFD768EFB89F8C42250795C0911CB28
-:100BE000057CEE8BB13F6CDB0B31BEBE18F75D238D
-:100BF000F509F7A53DE9A5E703E5904379E96252D8
-:100C00006A01F1B3DA2EE8A37D52B7123DEB74040A
-:100C10000897BD98342C44F9F445497D80EC199F20
-:100C2000E33E36702C3944F9EE5159AD621C3ACD91
-:100C30000A12CE8FF6D7E4D2012C97A8459BFF8DE0
-:100C40008BC725151EC629E1A28BE3F2F884BC539D
-:100C5000926B12FDD98F62FEC44EB321EF94146AD9
-:100C600078CEDF5D5CA74EFADE7CD5BC74B958F453
-:100C7000BB25FD4C353DD58BCF68F783109605CE4F
-:100C800023EA85F157EC4B91498F55DAB88AF21A6D
-:100C9000DA5534D51E9091DFF1CDC2CEC69BC37B11
-:100CA00088629485D5545F3461DED3CF817105327B
-:100CB00073D91EC6E9768A6BCDC379EBA41AEE63AD
-:100CC000EC54D720DD28B5F2397E059D4C152D9FBB
-:100CD00097839BE914F031453B653A1DEA98DE069F
-:100CE000F54C6740ABC8FFA3C341CE6BF08493FBC8
-:100CF000C15B2B4D547794FCBAE7FEA1518B27BD05
-:100D0000CB011DAFF4A7CB611AA0FF65F7208F219F
-:100D1000391C4712E591E8A7132122B39F5280C8DE
-:100D200026FCC0C5FE5A010A8FA75EA71CCA22AACC
-:100D300099F19B447954F46C17BB35BBA8255BEB48
-:100D40001FD35357B18BC7BABED0BF32A90E4DD4F3
-:100D5000A37EBD24B9BCCB85A1F8B35D27E79A314A
-:100D60002F951497AFCCC6717BF1B773CD98CF4A4E
-:100D7000C697EF1A8EE373BBBE13E3C2F2628B1BFE
-:100D8000BB983517E74EC1F92AF9672151F4438A18
-:100D900067AAE88F5769758CBAE6376E27FA8B3ADF
-:100DA000D4E1263EED58EC133E2A678BF78EC3A69E
-:100DB00087F75A70DE498B7A98FC77853D9CEA422A
-:100DC000F9AF5A33752085CEA7AC62BECD26705AD6
-:100DD0009D3FBC1E48C2F1CE9DB92BA5E1D73E0771
-:100DE000AEFF25ADAFAE191120FF551B25B7D06C56
-:100DF000F9C03928C3F6560B106EAAEFF7E468F570
-:100E00000CE747979BE3F760ADCE69DF999B4B7A80
-:100E1000EA2A163818646415931C8F8FF675D1FC76
-:100E2000688AB0B72ECAE5DEDEE9E012E51B9A9FBC
-:100E3000783DFA151E009F3797A817E97E75F26571
-:100E4000CEFBE78A3E5E17C98AD9AD844A9B87FCF0
-:100E500007150859393F4C705EA95329DE2DC2751C
-:100E6000501E253E3548216ECCBCCE528AABB8AE62
-:100E7000A904F7A9B6468615E173CFDE7DCC2AEC2E
-:100E80006E88B03B2D2EB5EC3EF8F86031F4419CF5
-:100E90009F55EFBEF4DDE728BFEAF30E374D8FF91B
-:100EA000D70B2BB9DF0487218EE87E37AEC9C6F594
-:100EB000F6F8E6518B68DEC48FDBB289AF496D115D
-:100EC0007E8F166DF974B03887DE875C947E4E3E57
-:100ED0003EADE589D3769117E8BD30F77B8DE2BD55
-:100EE00070AD8673D6B648A100C71FD13F2FD6F884
-:100EF0005B71B0711FE1278B373D3883ED2824FAF1
-:100F00000A17FE525C587A44F4CDCBB61BFB8D6AAF
-:100F1000EA9B693E84AD640F2BEA13EE6FAAE0BE34
-:100F2000B93A3EFEF7D0377B4B347C6C280C65BE5B
-:100F3000E4797DD51EE261625F5C05CA8412AE7BF6
-:100F40007D32EDEF35F78C3FF42FD0DF9389FABD7A
-:100F500052DB9BE4E460B958B99FA8DDBCD2EDA494
-:100F6000B1E6B75B4CD453E3C4773E80F8E7743FF7
-:100F70005EB25EE2BE0336F5631B2C7CC5A610BFD5
-:100F800085AF0CE43E04FB25AE0FB7BC625B4FE3BC
-:100F9000E0EFFA04E442C2A13B6F201C269884F5DE
-:100FA000A6C0F341F2300EC3B8C823255ADCD7EAF5
-:100FB00000081719FAF9A096FF6B53460EC4CE39F4
-:100FC00036EFC020437F12D4EAED123A27D58DDBED
-:100FD0006F10F793041F7B3EFC8764AA7B1BCDBE7A
-:100FE00064C2B5CF1F1ACE7D4C6F72F7621A82AB06
-:100FF000BCA7F47E3A23FB6A7A2B79DE2CE4A5D9D0
-:10100000ED9B7E05BEB4C4F4A2F337557EADC24A53
-:10101000B8C843E0249CA4F6E0CB413BF5851B8097
-:101020001188F320ECF9FC1913BF772F859C7F9D65
-:101030008063EF19B33B84CF37687191DE3FBBE229
-:10104000ECCCA6E1BF49AE3EE08AEBA39373D20D90
-:10105000E314F70D86E7FA960D37DC47796FA5F5AF
-:1010600021A0B4E695C6EADE3465B4E1B9A752A77B
-:101070001D60BF6F7D9871A97ED33DC6F3C8CD3288
-:10108000C503B820EAA532FC257F1B038120E96354
-:101090005CBBB18E2A8BD471DF9874C86CC0016CB4
-:1010A000D7C0A5B6907F519C1C024344DC4894B73E
-:1010B000F1FB8BDA8332D77BB543B150CDEA49DE01
-:1010C0003719E4ADFBA32EF7FE3EA3DC07CE31CAF1
-:1010D0007B906A94F7E0C546790FAD31CAFBC6D55F
-:1010E00046B966058C72CC5E3FCE307F445DB961F7
-:1010F0007CF3F3B719E68F0ADD6518E76EBFD730CA
-:101100003FBF7EA1E17E61D3D2EBD27F51B8D63012
-:101110002F51FFC5077E7B55FD07F057E81F581F6D
-:1011200065A88FB0EBFFCF0E4EE87156B783EB8CFE
-:10113000B36F92CF329E302112203B284B663B99F1
-:10114000992CE2CEFB07CE1F5270FC81ABD892499E
-:101150007596563FF8B438A4F733897DE39D655200
-:10116000C2FBFE24C3FBFE6B7D57E76D0D1BC6451E
-:101170008780BF9BF11C71BF4DD47B5261B8ABF42B
-:101180004CCDDB44C75EE0B4DDAD5FD5BFCF4BECEB
-:10119000B760F9217EAF384F7F2F434E51DA1D9F44
-:1011A000D4FB31BDCF4DEC7FF5BEB77B9F26EA98CF
-:1011B000EEFD863BD3CC75B4CA75F57E49659C734C
-:1011C000CB2875B0D74B4D00F6C926EA93234121B1
-:1011D0004C05E83D7494FEA72224F0CCBD84C7479B
-:1011E000D380F17345AABB3790C7C777464A057CC1
-:1011F000443FC55E758417F57A4272AE2B267C6239
-:10120000DCD7C3A81EC9F18A3ACF26A3A4302F0D7C
-:101210009CA7005DFF215D19E5F5C6F092DEEC2686
-:10122000F1FBA4067F98A9D9E9E6EF9712F1C588EA
-:10123000C9C5F569E0B7127FF7F3351D6E6CAC8E4A
-:1012400039BFDEC2750C68FDFCFD9AFC75DC639E3F
-:10125000C6CF095C6231E6E5FB9BF6B35E9665B6E8
-:101260006B78490DD7E30F0E7178F87B38A5D82D30
-:1012700070321D07192CFF94BAEB5AFC2FCB3C6B34
-:10128000C0A1E0B57ED7F5BE3CC6B758FFC4068105
-:10129000679ED83094F1F3D8FAE7188FBABFE643C7
-:1012A000837FCC5F7DD4E00F0B02C70DF723199D20
-:1012B00016C21F236F0C9A761FCAAFA3D1564AFAE3
-:1012C000403B7898F4AAAF1FD9903B85F6BD369F76
-:1012D0005FF339DAFCADAC5F9DCF63FE233C8EF843
-:1012E0002309DFA7093E759C43A7D6BD9063A6F7E7
-:1012F00089521F37E1CABDE11FBA9F994A87F33A65
-:10130000174DAE530227AA1943F55FDBE401E574DC
-:10131000EEB6A156B3A023C57850995D8CA74D2792
-:101320001AB538D6132ED22689EF89E649CA4B0B57
-:1013300070DFC747A94F913F542FED2C20FFAB2EF4
-:101340008C3C20E1FA5DFDD58D241F09DB8B41E942
-:10135000CC077F7776C6142890D055F679BFBC9716
-:10136000FAC4337D02E7A842D9DD784C8CADC21FA8
-:10137000DFF71E60FF3B898B119F813F4B029F72FD
-:1013800044ACB3709D8CFEEA73B42F7D4F46EFF7EB
-:10139000E83AD9A78E97462DA24E8C6AF5E266AF41
-:1013A000A8675F4AA04D54E312FE4894E3F5D323A7
-:1013B000094F3FBFC90654DFE2FE8AA924F6FDCAE1
-:1013C00000E485EAD877ADA2CFF4FCC516A638A50F
-:1013D000E3AAAF7BB378BD8C6C819766FC33C62DD6
-:1013E000F2C348EBB0592971E73D048C6377101EB6
-:1013F0001D8763BFEE15FD3A3C24E25EC786C18CB3
-:10140000B7AF3878E218C5AF7BBC6A23C975A1C9EC
-:1014100055CADF67A5EE61DC6CBFD7C5FBE27999E1
-:101420005F8C436B494F2BEC11C6D9AE85ABF7C629
-:101430007FC7A2D6E7F21847761590DDE8FBE239C0
-:10144000F67BE3F06FFD1CB175AEEE073A3EAC8F54
-:101450004F6F7E6AA486EFCFF7F5905F8F69726950
-:10146000B3F48CC75FF28AF778DDF4733300E1FFE1
-:10147000B63E98FB917EED15FC77CC457E18DF508B
-:101480008A48BF2BEE72B849CEFAFAB88EFAFA55EE
-:10149000F6E91AEDFB8AF85F5A23F07BFD7E5412C1
-:1014A0007A0D6C1078EA8ADD478F3D8EBB2C79353A
-:1014B000BF98F281FE7CA29C51BE23F9FB3B59BC34
-:1014C000FF42F99EA7F51371FB9F2BD7E850F19EC1
-:1014D00036BAE5D230FA3E6D057D0F5740F621F061
-:1014E0002F6830E25A28AF00E11BDDDF6B01BF1F20
-:1014F000B369F9C4A63F3FC46C78BE3EC597548A11
-:10150000E77F438B1B383F64A2EFB9B5F8D4A0F551
-:10151000DD89F84B43ABC04D1B32AD5C4753FD43F7
-:10152000F7F5FA67D58702375D9525EA6C3A27E922
-:10153000593AB28FEB852BB8B884F91EE5986E55F1
-:101540008794923FA92B399FC937A29EE97DC85F36
-:101550006FD37004911FBD5A3EF4D23A74AEBCBE34
-:101560009C274BB47DB1BF60FC6E2CA85AFDA0E156
-:101570006F1BF619F087FF037A5FA88030310000F7
-:1015800000000000000000001F8B080000000000A9
-:10159000000BFB51CFC0F0030947B0A3F20FA0F13D
-:1015A00067B2A1F2B3B950F9875950F9FE68FAD180
-:1015B000713B13030323137E35F8B0083303830C08
-:1015C00010AB00B10E33F9E680B089280343A904BB
-:1015D00003030F906604D23E405C06C4FE407E27A3
-:1015E00010CF0262197106864B405A5E8C81E1A5CC
-:1015F00028449F2D90FD438C3C3BAD792973F32803
-:10160000A60C5BCAA2F285D41818BCD51918266B93
-:1016100040F80648F2AB8062C26A10F611790606FD
-:101620003D205F5D16BBB94781F2FA40F9DD1AF83B
-:10163000EDDFA183CA773543E5E7A1C937BAA0F248
-:1016400035DC50F9AAEE101A00B1C92A3BD80300C4
-:1016500000000000000000001F8B080000000000D8
-:10166000000BCD7D0B7C54D599F8B98FB9736732D7
-:1016700033B949263079C14D081030E02484808A7E
-:10168000701322449BC204698BBB6C77C4D646148A
-:1016900008EA6A7C6C33790701096A77295A3AB1FA
-:1016A000A2A0B44D5DDC3FB5D69D40DCD2D6D6A01D
-:1016B00058E9AE6D23F5DF5A57D9A052A9D2B2E747
-:1016C000FBCEB9997B6F2609E8EEFE363E6ECEBDA5
-:1016D000E7F19DEF7CEFF39D1345F4106D0921E7D1
-:1016E000E1873E5F25F4273BF924A48790F9F01C9D
-:1016F000922373E019E3EFD933B8B64F2045581C55
-:101700002495841410F653D0D4B9599C4BC8641254
-:10171000FEF1CC425A1EBABE8E0468F9F5ABFF004A
-:10172000CFCED5D5B557E984E4ACE93BB69C3E8332
-:1017300091B8102D25E4412212920BFD15C7AA7C09
-:1017400084B44367971332299663C44AA160D002D8
-:10175000217FA7F28188A8CBB4ECC75F93F3309FB9
-:1017600084282451821585F3EED1ED9DF5CDA71F78
-:10177000DA99750AE1FFB71298DF44EDC8ED6CBC49
-:1017800018FDE73CC54B5E727CEC27A7C152268052
-:101790001FFB776304EF9BFF57C6CB25E51EBD8279
-:1017A000CEB74ED4E2509FF465C8B41CBC452609A0
-:1017B000817EAFE8115CFAC4EBD249486D9F0FF10E
-:1017C0002BD4FB93F07D8E08389F2977BFD9DB158A
-:1017D00024E4CC5A5F18E94323242B73F47CBED64F
-:1017E0004C48C26D29AFAE16A2385EF8C7C5B47DAD
-:1017F0006CB518DE0BF0D4ADCA80F766BD3BF93886
-:10180000A3E983E832C5A3CCE943AE130DCFDC4F87
-:101810004F1FF227A48FECDB2DEDC8C5AF17E27D7B
-:10182000FE85D3C7A71DCF5CD7D17CD582704CB9BC
-:10183000BBD843E8FA3F50BB2A3D9AA2DED8EB5A08
-:101840008EFC1EAC23463C45BB2DB09E38CF984D38
-:10185000DEE093AE8F34B2BCB7D9D64B9A5CB9A652
-:10186000771C7C4841FB7CCD7E9526497F338B16C7
-:10187000654D84FE64DE5FA7B62E46806E81B62974
-:101880003EA49EB204A1FC414224BC974320D2B2A4
-:10189000A219F1FB0428C5715D4CF8D462D1369EC3
-:1018A0002BDF6B5B0FB2262658E1579A1484430650
-:1018B00036E1F22E82C28DC10D439C9F06E57B6C02
-:1018C000EB2FFB48C243E5EA96E272625D07934E56
-:1018D00005C1A4D37B2E4CAE38C75B6D87F382DB8A
-:1018E000F964FD77669BA2F1DAC9E477269E28F2B7
-:1018F0005E815F2CEBDEE52287844B0969CBEF8CA0
-:10190000C1DB2EF8DF65489F20B448577EB906F446
-:1019100044F60932C0E931C9239489F57A898EF4F5
-:101920001413EE20504FF245104FE6F7B1E1E27488
-:101930001733FA8B69BF9FE5DD7E96EB3352E17A70
-:1019400073C884BB08E7912CD379BC7B17FD1FA516
-:101950008F589910DF2B8CFE5E07FA90CAA33A7855
-:101960006F91276EC12ECFEAF8B723CFBC36631E26
-:10197000A5C7C1B044405CB53EE3366A68FFC7AE58
-:1019800014E26E81C34BEBAFE070BE686415007D5E
-:101990000ED6B8917E572CFF3008E47BEAD02B722C
-:1019A0002A7E5DB1C8958483FEB7C93A3FFADF2429
-:1019B0001803F9B206E9C8846B43B984700C2E127F
-:1019C000E230CEC0AF7E7FFF1514CE172B84B05B04
-:1019D0004778FD848E3768BC1F1C4F4E10737C9D6A
-:1019E00068804FE7F823EBA186D7005F36688A7ED0
-:1019F0001F1DEF66297C14F41899CCF4438336A399
-:101A000006D64712187D2C1572B05D9BAF7512AECD
-:101A1000BBB436A5BC6AA08A422B87EFDB668C0B71
-:101A200067DC353C64A1EBA6D70BEF1FB0C039478C
-:101A3000F0077F97467F594016C03ABFE75B959EF7
-:101A40002063F7F776B3DA22BB08F9B059BF7FC03D
-:101A500035FAFBCD1269EC2B1DFDFE1A41E5F88825
-:101A600029609F99F31E99A72F88F47D33885F4AD8
-:101A7000EA37EFF3B4C856F9E398C7087E3F613BF5
-:101A800035786B2C57077E8BAE14A01F99FE5399A7
-:101A9000E4C79B0FD433BE73C0DB11FCEF81772208
-:101AA0003E7ECFD7DA09F66A9B8BD14B7BB6186E98
-:101AB00025A3E9C55C0F138F17BA1EDB040FF2874D
-:101AC00049470DE2DA71D77D223ABA03E8E892FF7E
-:101AD000793A7A10E868FEFF493ADAF57F918E92FA
-:101AE000E5E5682FACE47DF50FFDF62190CFBF3022
-:101AF00024947BBF58C4E4FF2FA24C2E0E92E8F62C
-:101B0000F9A00F8E4B28A7068D363FC24B4D629829
-:101B100007FA5D94FE5E017B692695EBCD2A3EE9CE
-:101B2000EC0B56D1EFC7AEFA301FF4D731BAB6601E
-:101B30007F13326C18B4FD4B23656A8043D9C3CA46
-:101B4000C32D6763609F0F0AACFC2F2D678D188E25
-:101B5000B7AD7339C5E74AF895C2B17A9160C453FD
-:101B6000D0C54F0485E1A586D8F42A5D979F0894D7
-:101B70005ED4C866B4AB098910F40F8BA99D60B11F
-:101B80002F9A4081815CAE71A3FE73F6FF12B70BF2
-:101B90009D76DCEA45652ED017EEC86979883E57F8
-:101BA00046042C03FE350BDCA22118A007228BDC97
-:101BB0008F82FE8BC8C4A5A5E0D79586DB66779D8E
-:101BC000E67A8CE2650DF35BB482FA39C9FAA74D67
-:101BD000FDEB98CF587461CEC32C5FBBE8F4401680
-:101BE000CCBB56084F8786AA56F045BFB5FF34D305
-:101BF000BEF103DE7EB1E6DA74460751D4AB263D72
-:101C0000FDF88DAFB860FE647516D2E5EA3AC96694
-:101C10004FAEAA49B3953FBFE8DA71ED7012B5E057
-:101C2000C142F7813C82744A7E43ED144AA7B1EA6F
-:101C3000E128DA2D2705BD8D96D317374D857EEF28
-:101C40001133B1BEB0B869E610DA5BCB90FED37841
-:101C50009FE94AE3EF8B40AE4E17C9A33AD8A3E3FE
-:101C6000FB051D9CCECDB22B188D09743DF5985601
-:101C70002E8D83EFB821D6A6F21BA6896CDD3A62C1
-:101C8000ABB4620068C02E37326A1AD1FE33EB5310
-:101C90003A9E2666C3B8317C3F42C7DD745EB49D70
-:101CA00097D922247DF6AA7432CE3CDA1DEB4FC5BB
-:101CB000BF914ACEDECCE1238758FFA64C4ACFA481
-:101CC000FDA7A86F3EBB78FF67C322190438E588DB
-:101CD0008AFC50524DACFD10A30CCB0A2FBA431115
-:101CE000B590E2D35D2AC2344847E9A386AC031E0F
-:101CF00062B8DE5BE9DAE65BF872EB9F25F4F36F1E
-:101D0000168B5A406E6CEDBF89E8141FDE509C6044
-:101D100079CE8D2AE0692B75B206617CB98F001CE3
-:101D200069F9F4773A4E9A46E23AED4FD6FB122221
-:101D30002DCBB5246CD04F7E2D2C78A99C381C2A35
-:101D40006A91E9FBF6B504E52301E961A19FF6D0AC
-:101D5000CB8604F4B3868401E0F6E03A9C6767E939
-:101D6000BAEE42FAFE4C9D8CF103728EC26BFAF50C
-:101D7000D4CFF0961003C6DB9A43E23EB4830DC481
-:101D8000AFA2B1F5D3771593C43CFA3DA3B21FC6F9
-:101D90008FFD3D617C49985C93B93C2132A53F1889
-:101DA000BF490BDF9782FE5412BD499C6F59672DC6
-:101DB000827EAC136FE90AB906F0DB5E46F9208536
-:101DC000DCBB4314910EE2E1552B8B528C738FA830
-:101DD000A37C32CBFA5905E11FAB7EB29E4C12595F
-:101DE000D0B521005E482488F3CB24233F0694B36A
-:101DF000F87C279146AC175AD8D30FFC966BF45554
-:101E0000012EBEE6FFFC315C37F28806762C85B6E3
-:101E1000F87C56525E80CE81F9BD1716D1EFF08B5B
-:101E200009CDA01DF83D8321747E758271B9746857
-:101E30004201BEAF596D07BB2440C2027CF787E563
-:101E400098D5AE4F27B46C8BA790E3C59584897C59
-:101E5000FCAEF503EB68258D9702300F068C7F05ED
-:101E6000BF699B3F8A7ED8879EC05C18EC4E6FE0AE
-:101E700051787EE8991247FF2CCCFC2D95FE03F299
-:101E80002E7DA16CF36F320C7B39CBE1872D937CD7
-:101E900038CF8CCF12EE5F1975D32725E1A210D56C
-:101EA00003BDECAC9109F8FF3E1F83C7842F4BBAEA
-:101EB0007701EAC7B07C12E0A0684138CE90730980
-:101EC00058E24009C1F82985EBA403AE930EB84E41
-:101ED0005AE16A52D97C9DF662AC9A943452E07E03
-:101EE0002872FF83DA4D60379E21EF18B540389194
-:101EF0006B50CF0634D6C6A70E62B042231AD281E9
-:101F0000D36EA4EBF49ECDFF5AC8CB3A11601E14D9
-:101F10004EFB77928FF48265898CC485D72D34F17E
-:101F2000A57FE1DF29FFDD74D44580BF281F4BF07A
-:101F3000DDC5BFDEC4E3C3EBC0BFA6F8FB12890456
-:101F400000BE77898871A877C9CB81791639794A1B
-:101F5000E4F6092CB1958F493804725CF6750E4A87
-:101F6000014483496FC2795CC73093F33E467731B1
-:101F7000A2B6A03EEC66FEA7194FFD728FDD1FFED4
-:101F8000CA2E7BF946B26A12C44B6F7CC845E2B4D4
-:101F9000DF9BACFE3D5DA757450DE1FB0A69EC04F4
-:101FA000BBA4CBC5EC8D751A9121FEB9E1FF7DA3D1
-:101FB000F27A3A9F33200FE683FD4EC1B7E891F5E0
-:101FC000C1B862948E9E5F9B105E718530F6FCBA3C
-:101FD0005C832BC0FF8E6D77A19D499C71D08312CD
-:101FE000C6412DED10DE1BBAEDF39B68FECEF91253
-:101FF000F200CE77FDBEEBD13E1F6B3ECABED4F6DB
-:10200000A64F126C711F93AF4D7A77F27785A4B308
-:10201000B80E558368AFFC3A2DDE86EBDBB800D6F0
-:1020200077A2F69741FBEC4FDE7EF1A71C7FE90417
-:10203000ED37A8C3CB60BDB7047B22C09F661C6B85
-:1020400023891979F457D7739B6360BA8DD40B5DDC
-:1020500060BD7C5A4FBA807AC5E3F7778ADB253FAB
-:102060003AF02D05ECD4779F7C6305D80137FF400B
-:10207000222AA5875307FC2481F64A5C01FB663DB2
-:10208000A5BB38961395D75AEC614AD1B80E377F65
-:10209000D78F76C4FAA7DDF13ADA7EFD3FFF762EC0
-:1020A000A17838D53AFCAF7940CF4F0A2CEE1A1BF5
-:1020B0009A7B2D7DBF5E267F1B494147D74B8C9F66
-:1020C000DEF97EDA1AB013857DFD5FC47EFBBEE0CB
-:1020D000725BF4F11AC985E3D27AE847C4F60BF1D2
-:1020E000E90283CFEA0F98F1EE77F60B0CBE43AE10
-:1020F000B807E0DBD7AB4469BD4DFB4E235D2FFD38
-:10210000EEB70380874D87EC76FAA67D52C23D1765
-:102110009F6FC01334A85009F864FCBCF1E006D4EA
-:102120001B1BFBB69E067EDE74C86593FF142FE171
-:1021300004E0F535295C07E57F7A22A05354BD3DC4
-:10214000B8370078A5FD5EAF50BA5AB9D0DE0EFAA6
-:102150003F9B39BA3FEA19A2DFBCA96F0B1BEFE026
-:10216000677F0FF27613617ACAE4E7B7E1979CD1F3
-:102170007A668B648F6F9D212F56E23EE0BEAC9451
-:10218000FEB3A9574CBEBEF9DB67F6C4E8F8EF3CD6
-:10219000FD1F7B62741EB7FCE5FD3DF7D0F991E7AA
-:1021A0003D1AC8AB4D4FBE1A2016FC3F26B1FD802C
-:1021B00053FB9F787C37E59353BF74A31D78EA8760
-:1021C000BF9FA2D3F99FFADE9F26819D7AFB0FAFB6
-:1021D0009A0CF8B8FD99A593C7B3D7816EE36EEB5F
-:1021E000FAC6B17FFD90009B20843CC79F8E753A54
-:1021F00072504A4088E0DD13EEB89BE267137DD74A
-:10220000540EEBB601F51594EFA5F8DE78A0EBB40B
-:10221000343715DE637962089E893C128275BF7679
-:10222000E59515F0748575A013328C7AC2D96ED3FA
-:1022300071BABE978EBD9ED49E5000FF9B0E6C61FE
-:10224000E3F6D1F50C8C5ECF77E197CB46AFE71183
-:10225000C91E673A436EF9E66EF878300BD77FAC4B
-:10226000F5DCF0CCE7C6F5EF4CF930119E1B040607
-:10227000D70EC97845027E7CFAA9C77707D93AD725
-:1022800051C49CFAF69929B0C9FB966BF88B2027AC
-:10229000877FE8D6C0AE5EFFC3D790EF4E3D734C4C
-:1022A000D1717F9AF804AA274F91919F41D09B1B2F
-:1022B0000556D8F4983FE10E24D76B63BCBE560F89
-:1022C000E0FB37F07D9CF1C3C678FF6A21C5FAF9BF
-:1022D000E422A69FE2D988970DFAA0A2F9ECEB2A96
-:1022E0002C84F57C6319D0DF58EB69CE5F83F92F1E
-:1022F000B0ACEB638C8FC7E2D753BD6E59481FBD9E
-:10230000CEA7B85DB1292EBC966ADD096965F1BD1D
-:1023100031E2DEE6D349178A6CE773B3BD39FF8932
-:10232000F87CE2795D1CDECE707DEDC4DF3BE752C8
-:10233000EB812259E07AABA736D7A2EF3C2EAAC791
-:102340000AC1EE6C8CE51526E1EDEC9350BEBFB3EF
-:102350004F427BDF2927368EE1D787CD710EF5CF2F
-:102360000579F6CEE1EF737A64F4BEF1C01B4A8CB6
-:10237000EB85B8552F407F29D6E372DEDFA6E75202
-:10238000F7B7E9C0E994FDBD2D1B5F00F8DF1E74AF
-:102390009118EDE2ED3E29659CA45876D9ECAC4E3F
-:1023A0007FE58974DA4E0A787598775BABF15A0C41
-:1023B000EC91975D04ED4739FC969B7E6FF37B7142
-:1023C000BFA52D7023D12DFABBDD81273914413FE4
-:1023D0005A0E462AD85E68DCE6CFBA34D106379169
-:1023E00063F9B0CFF9F3C2DFCBD02FC4D3744B5C09
-:1023F000E8259974403CED254308B79014712D47AA
-:10240000FF914512D1AD74664C15ADF1C5C0E1BB6D
-:1024100030AED1441A13106F22F9A46FAFA5DF4775
-:102420009A7516778D4C15ADF13F7763A3E1A670D1
-:10243000E4DFAE1581FF36D6F8058DF67D5F73FCBF
-:102440005B793C82EC7BF2C92769792A7C13810E87
-:102450002306C2718EED2B2FE5F2F047DC7E3E2C79
-:102460009001B0C36AEF8DCA20EF84D0F518175DD4
-:10247000967FBDBCCE428FCB42A77340AF7EF3CFD9
-:10248000D29A54747A88D355CBDF3F9E03ED777B85
-:10249000BE90CF9CD908C297C7E35D03D9CB7D100E
-:1024A000DFEBBF69D98B33E87C73358940BC269755
-:1024B00054F9CA289C79C7A5B027C53A98CF3D3CA6
-:1024C000AEF768B386F2FFB1E610961FE778DDD766
-:1024D0005C82CF279BC3F8FD40F3422CF735D7E24F
-:1024E000F3E9E608BE0FDCFD6CBF0278F92AE98348
-:1024F00078CDC1E635F8FD9F9BA3F8DCCBE7B30CA4
-:10250000F0E2B3CD1FE33187DA97B4423CC6C4A3EF
-:1025100013EF4B486CC08DFBF9820E78BF4B66F20F
-:10252000C589DF29EE3E01E44BD32D04EDD73D3CB8
-:102530006E6CCEF7EB32B3370F72787EE0897E4750
-:10254000A6CFF76A8B4BD12E229130C8EF3D4224A3
-:10255000BD8C5679217B41C82A87A7FAA30765CB92
-:10256000BEC2946E16EFD92D337935553FDD9F41AC
-:10257000F1509B2FE8104E30E77BB84ACF073979EE
-:10258000581070BD6BF3255262A17BB3BF6FC82298
-:10259000DFDF482DB79374CCE441E6D57209F8B576
-:1025A0006788372C517E7F3E871C24D4FE781EE836
-:1025B00012E4C2AFD2304E6CFA37DBF87A670251C0
-:1025C00040BEC4EBFE38C89FB1FC9E4E5EFF3D0E80
-:1025D000D70639F28A8CFBCA3CFE4A1218C784948B
-:1025E00023A0C7DD9EB53B6AE8F3FECBDF3E01F1D9
-:1025F000C1779FF1E800D7F68A93012B1E4983FC2F
-:102600008E753F7E44DE9CCDC3B8D8FF27D137649A
-:10261000AB1C0A0E2BD0FE7941DF09FBD7B1572541
-:10262000E4BFE785F82C8C63C904FD82E76F0A617B
-:102630007E87D9CE1FB6F377A667E8E14D30EF0667
-:10264000251C4BC117BF49D36DFB46EE90BD7D08DD
-:1026500074E67C56D6297D96F1798765430238E683
-:1026600093283E17101D9F39AEE847308F79A42F6D
-:1026700007CAAD6953AE60FB07FF6378535DFF0780
-:10268000F166D26BE8F2128483DC2D86A7EBE84D6D
-:10269000DAE87CA54BE0F855519EE78EEC4F35FE0D
-:1026A000A82088DDB0388996867230D7C3F0D73439
-:1026B000741AE3BBA129C41677EF6810910F76BF97
-:1026C000CEF6F5CE3414ED9C41EB57117D474DE12C
-:1026D000E87998FCB15B8DA4A7DA9F329F265F98BA
-:1026E000E59D53BF48400EFDE3D42F62DE51EEEB73
-:1026F0001E1DFC8EAA5FEF6F01B9D8F106CBAFF8B3
-:102700009537BAC8353F29673A6E6A9C0A7E50C031
-:102710001F59ECA2F889E4C7AF037977A6F676379C
-:102720004EDDC7F25E9AEED577CED4C75E9F3D4DA3
-:10273000E3EFDF98F3DA03F31A67FFC29C97B95E01
-:10274000676A570FDFA8839C294E8FA66837224FF0
-:10275000AE5E3DEEF87BB85EA1F35F6BA5CF294D71
-:102760001AE6B798EDCDF93ADB3BE79BDC07BEB044
-:10277000BCA03E17C9027AFFDEC753FEE925148DBF
-:102780001109F434E5CF8D004F2569C43291FB72F5
-:10279000C0BE31E97977E7E339A817E47821E67715
-:1027A0005DE0781D2412A9027E0B8B61ABBD623EF9
-:1027B000DB46E83C81715537970362DABDA1547856
-:1027C0001EE93FDFCEFFDB0861723EA1A29C87407D
-:1027D000A146CB854749F97DB4BF06480AA5E35415
-:1027E000C92C1E32EFA8DE2BB1B8AA54EFB7E09186
-:1027F000EF3798F1DD0E722FD174F02BCAFAA1BA1F
-:10280000C9A74794E84340A74A48C77C4F57302A96
-:10281000B0FD38B63F54C2ED92ABA4B52AD8254DD1
-:1028200024A2CE06BE3D2E119687C7F8DA6DEE8340
-:10283000713E76733EA61C8CE519FCFB739CBE0EA4
-:10284000817D82F604A3A383DC3EA9191E3EE2A784
-:10285000ED4A067BAA613A4F83BDE206FB248CDF7A
-:10286000BF03F60A2D1FC9F8C76B6653BCEC33C40F
-:1028700030E0FA40B3C1F8A1B901BF37919877337E
-:10288000C8A547440DE0EC7AA4550AD0F27E55C0A5
-:10289000F8C523CD8D583F70CE9B007F73BF9A1033
-:1028A000C01E391326E118C04DDD2398D70C3E8F8A
-:1028B000AA370771BBFCF1F87BBFDD41EB3DB8D017
-:1028C0008BFB64267FCD681AD6AE01BEDA7B52DF61
-:1028D0000CF0CFBFD580FADBC245B84FF104C51765
-:1028E000ACD3BE5DEFED1AA4DF0372D766F0836749
-:1028F00016AC427B28A0FEE36D500E684FFD1D3ED6
-:10290000D5EFDF09FA7A665CB4ED9F07D49FDE0548
-:10291000DFAB87C235E9B49F59C707BBAFA6CF8EDF
-:10292000F0ED2290787AE61F705FE3B0A07DA907F2
-:10293000E26AD72B48AFC609A305D8D15561CF832A
-:10294000CC7E310A690B64F200C53B01BC1B32F43A
-:10295000FB96AB10E92C14C8A909D0F2E38F9DFCBB
-:10296000F1D5F4FB915DB7A25C743F22A33D36F331
-:102970001BB793AF58E484FB3139655EE95B2E37B2
-:10298000E3A34756F7CCD2197902FFCDDA5BA3A2B5
-:102990009C78D19EE760EE0BF792E85B2EA4676609
-:1029A0009FC81ADB47863D2FD84F240F8B8C4F22B0
-:1029B00051AF35FFB9E4EB6224559CFBAC4BC679B3
-:1029C000B5C76B4A601DE4F377E03E19E9B18F6F3C
-:1029D0008E47C73F6B956FB2C6E02A00D54FD7B37D
-:1029E0005FF9F71C80FF6CA3A9A712A8A706CAC4A9
-:1029F000C4540ADF030F897148CA3C52CBF4D6761F
-:102A000099E50B6EE7E5C7CE91B85098E4A3999C81
-:102A1000DF1E7B4464F65C9CA09E23E7CEA37DE191
-:102A2000E3DF33CB5E56717F2266F8AA2A312B9002
-:102A3000FF58E885E2E8D298D72667C5A64CDBFAAE
-:102A400017508BC59E4F5D94AC2F811C3FAE02FD8D
-:102A50009EA17E2BD0EF12BE4F5463E6614AE7E69B
-:102A6000C1FC1F36F5AC9937E3C893DEDBB8CE0B5B
-:102A7000F1C2174CFA696834D0FFD1DC389EB94FE7
-:102A800058724B2406FAD3956FCF9FAE72E4472F4E
-:102A900071942F36BE52AE38E3A8DB66211DE801E3
-:102AA0009457C51CCF7B2FA3EE7CFAE838CB48BFE8
-:102AB0003C8E407A02B87EC59C80EEBF5B6A00BF48
-:102AC00020F040798635BF60B9C2ECEE815FB9096C
-:102AD000D8F9FB6B548C679A799D2E3EEE0A45C758
-:102AE0007AFB1FBA4385F65DC1220FE0EBC8E5EB28
-:102AF000BD98FFC1F3534DB9DB7AF9FA6B6E0279D9
-:102B0000982DA2EEE9C86FCD857DF9076A54CC3FB8
-:102B10000DA40DF51DA165DF134AF851FA7D7F550F
-:102B2000628D356E7387C2F4D7750ADF07DA66CF18
-:102B3000DFA07C709D02F961BE46DCB714559EC7CC
-:102B4000EBF0EF4D7C040E5F2716FAD9B3C80FFEE9
-:102B500028A38F38A78F3DDC3F7D04E4BF1BE886A8
-:102B6000C9FF6DDC3F75F63BBD217258013BEC1689
-:102B7000AD1C4251CEF59DD66DB7270A6376393725
-:102B8000D549F78DB9B6FA790D45B6EFFEF06C87E9
-:102B90007D92607A8DB0F5E9F2F8A681DC2EA77AF5
-:102BA00097D9199A18B1EEAB38F47A83CB68562EC0
-:102BB000C2BE09A4451A617D9CF6F456BE3E7F2331
-:102BC0001B5B94F9E8BF6D8527B58F79BEBADDFE32
-:102BD000180527A170CE1917CE872E06CE89F6D9F3
-:102BE0009CFB6B774A915D2FD1E7E274960FD9E198
-:102BF00067FE7C07C45169F9594E874F2912F67F49
-:102C000088CF77711AAD9F82BFCDF8EA73907803B1
-:102C1000F526A7CEB3040B08BFE7A5FEFE9CC2F6BF
-:102C2000B3174F1D7F9CE7611CFADCE632BEAF583C
-:102C3000E278ED8AF1036B39A1B0FDE79175E17996
-:102C400094A63D7687CBE8B7D64F3EED72D3DC072E
-:102C5000C9E6EBE9278CFF5E58B36ECB74CACF4A46
-:102C6000BE0FED9FEC35ED9BC500E41F0D6AE00F34
-:102C700064F37D7CB29AC951735F3DB3CE2E579DEC
-:102C8000E7ADDC3C2FDEED3C67C3E5AB931EC7929E
-:102C9000AFBF56ECFB1A23F1EB31E8CA19BF6E82C5
-:102CA0005F999DC9EDE048FAAA3963D3E3CF9B87CA
-:102CB000B70F4C4F965F82F33329E980ED27060E5C
-:102CC000FFA16E7505ECDBB178DA607362F19BD31E
-:102CD00093F22BB228E305887B466A3250DEAC08BB
-:102CE000FD71FB00F5C7EB8DFEC56F5AE639A851A3
-:102CF00068A78DC32786EB232B7F3D2130FAE9E0BF
-:102D0000E3EDE0F874DAD15D62CC0DFD7E40860C17
-:102D100021855F6B9D773BE26DC8077436D6BCC3D7
-:102D20006EC65781858D6188D3B9CF4BC807EEA990
-:102D3000A6DD1246BB659E3B839DFBF015E13E1E62
-:102D4000F5D387FB611D7C2CBFDFD48FEF9BF15443
-:102D5000AEF76ECB60E5ADCD2C7EEC3E72D96B3A12
-:102D60006DE77FD1453CF4FD162AD7210ED84DEDF5
-:102D700078F81EA8182210476FA3F5A316BFBB2D25
-:102D80005CAD819DD05E5AAEEAF4BB34A702CB7233
-:102D900061B9564DC79CEDFEDAD26C8883178B98CB
-:102DA000575B4ACB2DD4A44B776B38BF9F97BCE9B8
-:102DB00003FB2C1D9CF3F9C9F57455440D89C2E33E
-:102DC0000A69D5908B31A2B7399DD1F78F42BCE407
-:102DD00009215AE9A6F3FF393F7FD5A53496DC0ACD
-:102DE0007E8F1C7343FCA04965FB10400FEDF392EE
-:102DF000702FE1F855F8B8237E105FCF0FE4A118CB
-:102E0000A4B67689A421D5FA5CED6672AE5D33B4C2
-:102E100071E949933FB2E54F2F62FCA404293DA517
-:102E2000883F3AE5357147EADDD9C97C25BAB01A41
-:102E3000F22961F69E79BEE74DC5F89C9BCEA3D5DD
-:102E4000C7E5587E26D2297DBFDCFB89E43E8BCFC7
-:102E50001C5E5471AC06FC924117C68B02D3C8DFCE
-:102E6000462CF2F6A81B836EF4C9ECA4FB287DC4A3
-:102E700067B2B80401BA49A38A18F6210BC4F8A3B3
-:102E800085006F6FED34DA5F973C9D5AE6C97EAAE4
-:102E90000A98FDBFBDDADB60F503DE4D63FB2F77DB
-:102EA000F9AA9E86F995FAE2D5E83E4376E62476BD
-:102EB0007E0AE8F8128D0C0922C8C108617A33AC89
-:102EC00032FD5AA3C179298144C9F9B4F1F4A3FDB3
-:102ED0005CD59372BCD50BF808B278977F9780C900
-:102EE00080529F91F08298F4AD6A77337D5102E36E
-:102EF000F4577A898FD6FF63BF82F6619F3F4F06F2
-:102F0000BC3E2FAEFB26C49F867FE9C6FCC6BE3FF3
-:102F1000CFC6FCFB3EFF15CB406EF709E42855F603
-:102F2000A4EA6C1E4F362469B0CF17586A10D8E750
-:102F3000187E8184213FD815FAE9E237E7E1C4D34E
-:102F4000C485B49D87747B68BBF047DEF79750BAA1
-:102F50007ADA57FEE0A524195731E329CBD2A20F24
-:102F600003DE3A26FD5B03F04D37855342FBD5085F
-:102F700001DCE5D922C61F49B62F3E1DE265478315
-:102F800035903F5A2597616A6C60295BEF5F79A3A2
-:102F90007B61BE355A7D0DC4D72B8EEB2867978594
-:102FA000360F40B9F27556EE5018BF40BC8858E451
-:102FB0006ED5D92938BF3E4E27ED2163D010C6E526
-:102FC0001BC7B9037BBE9C950E20CFDD42075197EE
-:102FD000950E16523A9863A50343B8183AF82A2A70
-:102FE000EB4FC23FC66B3542326E379A0F36AB9904
-:102FF000A5A3F9C584E3BE8ACC20C851932FB4059C
-:10300000F7A25C755FAF44C05F37F9C4E48F8F3DB2
-:10301000237C12017E5FEDD3AF4AC527E08758F9C4
-:10302000E1DA31F86605191E08D2462B64124BA767
-:10303000A2E4E797BD553CC5C2074EBCAD582490ED
-:10304000933679C6CA16BC6A23E71BA50BC7FFCB0C
-:10305000B2DE11B4F06127F543C058EE16C304F494
-:10306000CA02DFBA3F025DCA75DF0B813FE87247D3
-:103070001A306F76C13B693752BAFCE3245187C9D5
-:1030800077E8EBBE8BFC7C228D807DB2BD723DC6A5
-:103090007DFF7853742AE8892D14FF27512FC72705
-:1030A0008B9883393499EDB7EB21F68C86D87BC2A7
-:1030B000BFC779D9E0F586B01E5D679B7CDCE16116
-:1030C000FB5D3B3C4CDF6C517A54E0B7E142554B21
-:1030D00095EF5CA9B2FA4BDCA4221CC4D1705FB995
-:1030E00043956A7B599C2FB184BE5F32ADE451EBAE
-:1030F0007E81D9EEC1E63EB453B6341FC267565D39
-:103100009C40DE95B724A6C3FEB8FA97A5820BFAB9
-:103110009DCDF671E17D8BC54ED355C69FEA5FA468
-:1031200028F0B1DA1AD3332DF2581585682A7B7B43
-:10313000A787C569D45682DFD5C35FC77DEFACE2F0
-:10314000B0F06528B7F69030EDC79360EF83C58681
-:10315000F0254BBFC1BA3E9B3E5C41972ABD1CADDA
-:103160002C3C17D3A17B719F6C45B0FA0FF2DCD1D8
-:10317000F4063F272D7463C26FEED7DECEFDF49ABE
-:103180002215F9B4A349E9C573302AB39F3E085606
-:103190008F7BAE00F669A98587FE303C61BF36366D
-:1031A00093EDD74219F66BE109FBB5F084FD5AF8AF
-:1031B0000EFBB550FE4EB38165D8B78532ECDBC649
-:1031C00066B27D5A28C33E2D3C0F3537E0F3D9E671
-:1031D00046FCFE5C731396293DA0FD474A6221B070
-:1031E000ABBBEF520CC8C7E9E2EB7EC428CA027A37
-:1031F000F104593CC1F3E203782EDA131231BED741
-:10320000197A80DC409FDDF3FDDD101F51BFEBC359
-:10321000A7477E9080DDB64788359030211BD58A40
-:103220001A99DA13C5A1CDD59961C0DBE5ED909F60
-:1032300038436F09AFD39265DD5FBEFE7B96F2D453
-:10324000D25ED94BEBDFD5BDA81DE406C0019B6B58
-:103250006DEA929A96624AB445D4A001F957A8C47F
-:1032600081EEBF04EB351DE06776E067485B08E25E
-:103270001F5375A51CF895D64F303EB9B0FA5DAA1C
-:103280008EEF9DEDC6AB27565C503D228DD31F7C43
-:1032900017C6E9A783B4698314F6AD205BC08EF22C
-:1032A000B0FDE06E179313DD1EF6FC9DC7DC0FAF7B
-:1032B0005EEEA1CFE51EC687DD9E482D9C4B199E74
-:1032C00023621CA8CF45BB80430A4D85AFC0F9A13E
-:1032D0003B7E2213D867D8C3F976FA543FD3E7F779
-:1032E000A8A8CF974FFD767B262D4FFF56380CFAB6
-:1032F000792B097B814E62DB985C79AA625A663D24
-:10330000AD7EC9FC6732414F7DAC32BB36CEFD92FB
-:10331000968E1BA742FCEA8FC7989CFC361FA7D746
-:1033200035D888EB39DF87760D752CD06E6909C9E1
-:10333000986724E6B0A7E2D2FE0AEA29D430885181
-:1033400078943F2F50314E72D6CDEFC118447B4652
-:10335000F144B50CFABE272622BFB769DE38D8DFA4
-:103360005B7DE578FE34562AE33994ADA52CCE9AE0
-:10337000E6FF7C1CEC981DFD1E261F7C2AE699C6E4
-:103380004B0F1EAD0EC253D480DFE3C6AA5AC4BB96
-:10339000266A98AF4A7FC3EF0D413CB7B295F075EE
-:1033A0006910F1DC5DC7A48F7E7A29E4EF7C590BAC
-:1033B000F3BB09301F1C4D3311F68D860FA7013C5E
-:1033C0007F63DE6B30D49A46EBB7AFD3C2B00E73D7
-:1033D000B5EA5AC837E8D0AAD11F4A9B53A35E8FDB
-:1033E0007268E4DC06DE9FD15E2A63BE117C07BEF4
-:1033F00024ED6400CECDE771599696512E801DD6EE
-:103400005187E14038D760CB3F6FCFBC06CF2B4907
-:103410002B3211CE0E62A8503F5627A39ECCF3A9A3
-:1034200009B04BF2CCB82F1CC5B0C425B26EB19F09
-:10343000E7C869906DE7C72747EDE56C1E67C8765A
-:103440009CFB38CBE9C58927E77CB3828F6600BC3B
-:103450005970E0571F3D9F0783E5F530CF3CCD8B7A
-:103460007087B4D62A905F9349630BD0DD45C3EBD8
-:1034700080736E69FB20ACFB5C5D263A1DFF523207
-:10348000DC0AFD6EE574DE5D68D7DB7B54C9E4C7FA
-:1034900030F0E3D42691C42CE343BC3266196F5A52
-:1034A00077A6AD3CBD27D7567FE6AE22DBF759F1B4
-:1034B000D9B6EF97EC2BB795E7F45D6EAB7FE9A13A
-:1034C0006A5BB92C718DADFEBCA3AB6CE5F9837F53
-:1034D00065ABBFE0C43ADBF7CB86D6DBBE5FF1D687
-:1034E000ADB6F295C377DBEA9B76BD532FCEE6F6F9
-:1034F000CDC5DAF36EB84FC216BFB5FB0B4E7B5F7E
-:10350000FD4B9BDE0A722DA0207DCBA0C769F9D6AA
-:10351000BB98BFA52E0EEB2057742E47A9185C0050
-:10352000EB561550511FC83E564FF62D43FB63CA4C
-:103530002E2A8FE681554A46BEA7815C6E8E2D2EBF
-:10354000B6C4A53C5A0F9EE1AA0AD4E23E88D95ED1
-:10355000D60C12F5C3783AB37BA8370BF53C3A6D1D
-:103560006F99D7F3A28847A587A95FF8A8C52F1C34
-:10357000CB0F74FA7D17EAE74D118917CF1F089119
-:10358000467896361EAB86B461EAFFFDB587F2E752
-:103590007625D2D04BFBDD5EE465FBA5DCFFEB2E90
-:1035A000EC43BE182E9451BF10592FB5C6ED3AF911
-:1035B000FAA6A94FA1FF49F18EF2D6C4FB566128A5
-:1035C000DE0672E72E2FCAC329BF71BF0CFCA516F9
-:1035D000A9792A7D1F3EA218B00FF520C76B91561E
-:1035E000560DA1A7E250FD6178CED0A99D419F253F
-:1035F000253B0FA35AF314E178B3C3DFAB0659A2FE
-:103600002E66F69F3C5789B7D27E248DC291C2FFA9
-:10361000309F526017DBE728967F07F406D6FF79C4
-:103620003A85AA4C15F3423C4007023E917E3C414C
-:103630001FEA0D0F1C8285B22CC4619F10EC53D879
-:10364000AFABCADC85EB6EDAAD60CF46993FDC09E3
-:10365000780DD6D9D73B4DFD0EE2A95D60F1F1EEB4
-:103660000CFDC56A3A6E77765126C462217E526F90
-:1036700091373BB83E8D7AD9D39437B891333F69AF
-:10368000EF50FADF254E03F87A08C82DCFBD3D0470
-:10369000E8DDA3D1D544BB3EA647509F327BF73629
-:1036A0000E534DD11ACC03783F588EF6ADA7E9F9E9
-:1036B00094F8F30C49C49837365E033376A3BE27DB
-:1036C000458A0E764593AE18BD29E4C15C95FB3959
-:1036D00053CC73AF2C0FA89BE3C38C9B8EC4237970
-:1036E000DCCD8C479AFDDC965D3E793C7BDC43FD6E
-:1036F000D0A805DE2D741CC04BC7B9FA5AC4834C40
-:10370000D8B9DD3F97F6DE87FBB16D3AEC37CFE5F0
-:10371000F67225E087E27B8A42D04F580AF1952C59
-:10372000F07E3F530B7C69C663863CEC1C773846C1
-:1037300024167F73997A4B3C7F29C2AC2B661E19E5
-:103740009ABC4CAFD17FFBE17CD9B46EFBF9CDE9DB
-:103750003DF6F2CC5DF6F2ACB8BD4CADE6E36017D9
-:10376000808D86F18D7DF6EFF5E6BE410D3B6FA6AF
-:10377000D291CF33FD6BBB3F8770FD6FE6BB15F475
-:1037800025AA40BCE6DF6ED7ABB95CCFE73AF46759
-:10379000B95FC2B843D5D1E000D88F667CE8575EE8
-:1037A000DD967766C6799CF2DCFBFA4E42BFA0FF3D
-:1037B0001E75B37807C4913F2CE071957C1E579914
-:1037C000C2E32A052CAEE292F497D60A9827FA3E75
-:1037D000F20569BC94C573D8B9AFF76AE517049DC3
-:1037E0008D17B58C7767496C3943433C07EA99F1EB
-:1037F00015337E10F01BCB817FB7865F6E3C42E9AC
-:10380000A4FA976E02FD5C25BD78B419E45B818C47
-:10381000F9DDDA825BBEE98578257CA7E5EA427DA1
-:1038200032F2C18F5D1847E8E2746D9E5734E33180
-:103830009A97F181CF6BDA47312FCFDFF782BD7BCB
-:10384000C93E2AA36DFA8EC5FDCCF8DE9C3EFBF77F
-:103850003E226469901FB0262E32FBCAF05559F201
-:103860001F67F3759BBB36F1C05A5A3E40E2E570C4
-:103870002F5D19A78FF080FD9CEC2422E039A94927
-:10388000C7A5709CD69FFB9CFD7BA9E31CED6CE754
-:10389000B95AC7FE915F22A7AFA7E36DD31B05906E
-:1038A000A3DBD6525B9E966779F9BEFD0C3203E826
-:1038B000F02AC9174E007E5F95701FCCFDC6CCD78D
-:1038C000AE07BD7E8CE52769D3F49D106FD67E2AA6
-:1038D000A19ED2D24859992FB9DFF40FE7C304F65D
-:1038E0004FCCF8D793745D41AF1CA07E79B10BFC2F
-:1038F0006C0DCB7DD42F87F2D3D42F87E741EA9785
-:10390000C3FB7FA67E39940F51BF1C9ECF52BF1CB4
-:10391000DE3F47FD7228DFE5ABC278F920AD0FF43A
-:10392000E22D3BA84EAB0039ECD2803E9C72A8AA97
-:10393000EA36753525A92F743D85FB1CD557B17C1A
-:10394000EAE5F73D85FB1CD6389C354E998CC30DB6
-:1039500009661C0E42A3BFE6FB1123F1B8288BC7F2
-:103960004DDC8F61F683F1CF51FDF038E8BB77FD78
-:10397000DBE36DF4D386F90F747B8BE07C47238FF8
-:10398000FB99F933BA2D3F7FC3C116CC9F51728E7C
-:1039900037C2BA1EACF0615E89E28A6A206F9DFE72
-:1039A0009CE9C739ED69F3E9D46F7E6E5798F1D57C
-:1039B000ED2E82F9D43181DA13605F34C717BFE985
-:1039C0001A3BEE7AC25BC4F3F8EC7261E41C018F1F
-:1039D000FBB8C19AA5F354048E0F9EDF8EA2B18866
-:1039E000C5FFACF1576F711C0FAF7B7D06DA750216
-:1039F000B5F7D0FED3A22188A375C2B98114F3DB39
-:103A0000CBF9BD2547417BA33387E58BD4E48743BE
-:103A1000D0BE2DA732643D47609E7318F057AA436D
-:103A200096FE6EF5178DABFF24AAAFF571F4B5E4E1
-:103A300066E77CDA0E5FA6C2F98D6EDFBA41F0A3AD
-:103A4000BB43418CD3F7E75492214BFF5268219E30
-:103A5000F3907CCC1E96422ADAC332CCBF3459DFB5
-:103A6000ACD7C2E53E65678C2F7A7C3D58CF2D4799
-:103A7000F07E09771054267D6A6CDFCE5B2C12D560
-:103A8000222FCC71EFF63279D95D1AD520CED21D16
-:103A90009275382FD2AD97239EDB389EDB0A4C7B84
-:103AA000228C76CCF7B97C35FB69E37180B60605CC
-:103AB000EDB948538656938579BDDF017EEEF6B5A4
-:103AC000AAB07FA9E4548CDBEFC084FD964DAA997F
-:103AD00087FD7E1FFA55FCEB34E8D735C6F9A463A1
-:103AE0009C1E3EA9DDEADCEFA3D086AC792BCEA7E5
-:103AF0009FDB9FCE761B4A871458F72D8FD9CF3383
-:103B0000BB083BDFB5F1D066E4F3EDF220DA51DB20
-:103B1000CF0929CF8985D204CE6F23FEBDCD0ECA31
-:103B2000E3FC94C7BF03A981BE284BD8ED96794723
-:103B3000EDE5F983F6F282134E3BC87815ECA0D57B
-:103B40005CEE0D5279CF92668665C0472416AF02AF
-:103B5000B8EB495F0BE453B8249617B29AEBBF95C4
-:103B60005C3F06D23210FEBC06AFCDFF24FC3EC047
-:103B70007CDE7F41CDC0E67610B211D3AED2D16FDC
-:103B80002DB8FAE92A14970EFBAADEB09FF75FE979
-:103B9000B09F9C765695DC8B79BBB98EB886B9EF11
-:103BA0000BF3847B0F9CE35FECB8667F90AF05F26C
-:103BB000CDBC0F06EF1FA6ED0BE48410A678CA6DEE
-:103BC00064E775F26E27466F0A3A5EC2D77D14DE4F
-:103BD000624B106F4BF9BB5C1FBBC72BB7468AEB20
-:103BE00074FCDC863EB40756DD42E78376F879CC78
-:103BF0009731EB6766F4E1B9A5DD7502CFE325687F
-:103C0000D798EBBCDBC7CE19D65F29C44568DF580F
-:103C100084E3235C45C9F5A5783AC9F0C4F212AF34
-:103C2000ADB59F87AC77D82F263DAC74BC3FE96516
-:103C3000FBE7261FBC7BD9891953281C1B849EDAFD
-:103C4000B46917AE2F2DFCE13A0F7C08BF4F6229F3
-:103C50003298EFABFE9386E74232861E269424AF5D
-:103C60004D23B19A4584FC8B77F8128196FF6A6BDD
-:103C70005F4777011CF31E7E0A8C3C77D73357D5FC
-:103C80005E992C7BEFEBC772908F035B906CBD2D20
-:103C9000F7C350D4C5D3187C5B0DB253821C5C5162
-:103CA000DB192E4CB6CB8476C238ED2264A79CA2D9
-:103CB0009DCF6C47D1D509F73FF17979F97791C359
-:103CC000631D5F06BC69BA0FCF3B2E9335D8BFFA90
-:103CD000B4704C9A68DE51B2D3356D743B0A768B62
-:103CE00009BF981AFE387CB78EEF1A07FEFF6E7C6C
-:103CF0004CD49FC2BF5F347CB47AEBA4B1E70B70A5
-:103D0000B9F05E22DD275AFAD9D1FF278C8BCBD7A9
-:103D1000913084BC6497A1C17E5EA9F610FAF77257
-:103D2000468D0676C0165A063B604B5F0FC6BF4BEA
-:103D30008B1FE806A22F4D7809C8833944CB384041
-:103D4000FB9DA3C970028BC8570E88104F279F2573
-:103D5000985F92DEEF65F708155EFE2DF0B7323200
-:103D600054DCCF48CBA8FC16337A599CD9843FAD9C
-:103D7000EA7835C4DFE57A1216002E214EAA80C9F2
-:103D80006611DCDFF01A07EF84F3024466FA09EFEC
-:103D9000D201BDCAE3ED9319C9906E45ABC73C97FC
-:103DA0009FC818C79A0C578551A22C2DCDDC09F05D
-:103DB0009446690702C0CFE26573A2623841FB2FC7
-:103DC0003FCDDA919FB17326D43759F38C2F8957A1
-:103DD00053AE4CE671F8D05A7B9C9A0CD339D3F68B
-:103DE000E53F5BB517E2149346C96FE6B77B399C94
-:103DF000E9A74904FA0FD6D9F58697E7797B1DF72D
-:103E0000CC54F85DF6FBA19DFEC35723A807DC2424
-:103E1000AC2A685FAC45BBC1F44B764345B0C70BD9
-:103E200008BB97D7D9BE92B52721E6A7B8BD4455A0
-:103E3000CBE9F7F55E03F312DDB44CF1282844CD4D
-:103E4000A1EF7345166F6911880CE5E47809CC473A
-:103E500070AB9F6907FBE5B03A0FEF4F33FDEA36D1
-:103E60002D8CF912A4A4DA66379B7961B796154DAB
-:103E700086EFE99346E24E1AD0E5ADD9C56847070B
-:103E8000B286FE1AE4ECB9ADE9CB5490AB90AF71B9
-:103E900039E4477B3B6354E9BBCFE611DD629FB950
-:103EA000E5468CB3B9CF4EB1BD4F34DBCF5B1B3E83
-:103EB000B106C699EA637C5845B476685745ECE785
-:103EC000AADD67736CF67AB2FF7CDBFB04B56BACE2
-:103ED000F7008DDD7F1AD14BACFD4F1BA3FF198E70
-:103EE000FEB594FD27FBCDB2F5DB21B3F86B2CE8D2
-:103EF0004D792FE5025F75311C951D6B7FA0D2C7F0
-:103F0000E29A5DA146DC1FA82694F129BD2C3977E1
-:103F10005262E77D09DA6F24DFBE3F50CDE958A435
-:103F20009481E70764FBFDC68B89F3BE63BB5DF438
-:103F30004B8839507C89FE8A41DC27F8930FCF03E8
-:103F40008E65370F36138C4F2F4E1BBA0DF6C157A7
-:103F50006ED3958E10E63DA33FFF37DBE62F033B84
-:103F6000DFBC07B32328225E22D593F13C97D94FBB
-:103F70004421D3412E46449607813F74FCC1EC5C3A
-:103F80005BBE86F9749E87AF3784C5C596790D42AE
-:103F9000FEA175BCA579BD92651E1137998FE3719D
-:103FA0007B7764BC499F6CBC633C9E658E57BFCCDD
-:103FB0003EBF7A45C3F9D5733E36C73B06F34B8106
-:103FC000DF09C7E3F99523E32DB7CFAFDEADE1FC01
-:103FD000EAF97DBC23E34DFA64E399719D2EA5B106
-:103FE00011E870ACF88E19D7B9B66BBF2DAE43622D
-:103FF000FB97561513B25360F223EEABEE04BA787A
-:10400000BFEED612D42BDCBEC67B57A93E5E293349
-:104010007857E4FBE22D163CEEA672C49809E72916
-:10402000540207CFE07C8581E72D42F87C94DAEBDF
-:1040300006E69794E0F7C79BC358DED7BC109F668F
-:104040003F250BD9FD60B3160929EDF6133EE67F37
-:10405000EECCD1AEFB12E8B72A2FCB0B5E78053140
-:104060002C763435AC0F7B607FE8F3A40C74E48CC1
-:104070005D0CEE60CDA438ACBFB76C60B019E2A0A7
-:10408000B24BC7BC583DF5DF3B78C5C7FC79B79B41
-:10409000B52757B07B525770FD44A43ACC3F5AB174
-:1040A0003203F31156AD36FC1AC5DB6A4178B59878
-:1040B000EB3B381FF539BED44E7F21089A87AE57A7
-:1040C000D090E2708FDCE7F25F5C23D07E23FE6B42
-:1040D000D1CF88D08699B49FCF717D5BF5869B4008
-:1040E0003C825CA5A0FC5ABDDAEE17ECF42434B097
-:1040F00073769605490B6DB7AACEFEDDED667C158D
-:1041000071DC13B362827B63CCBC5C277E9C71D371
-:104110009FF9ECF1D133A474079E0DE3F9BBCEF601
-:10412000661CB4DDC7E45B97C2E4C3683E60F0BCC4
-:104130000B7DA3FF7702E368267CB9725C00799F50
-:10414000D770C2961F4F118B46B5B94F40A4036577
-:10415000A8871DF3D92D1CC819EFDEA85C22FF6EBD
-:10416000A884FF7D0361F4BCDF1935EF452F15935B
-:1041700054FCC3E2C12B8E4AE1163D8917130FFF91
-:10418000DB7CB4CBC7F0F9D2D20F2A981F986FFB13
-:104190003B02E639AF6B47CA32912DF4BC72BD6267
-:1041A000307F75B814E8F2F8956961F6F730B81DFC
-:1041B00094F8A50876D0A7EFDF28B0E53FF37EC7D7
-:1041C0005A2F67DEA5E55C72F29E04C87F690987F5
-:1041D000D01EC81609F0532EE4E305D8F79376BB3A
-:1041E000D5968FD7D6BF5F80B8E1C3909F68398FCF
-:1041F00097D7D02774807DD71267718804AD47E1C7
-:10420000CE6F4808EDA5C9BC2FA75CCFBFC59E2FB8
-:10421000D8B168B5764087BC9AEA1EB8206CCB2E20
-:1042200016E732EB8FC4BBF83955176924704E433B
-:10423000F2B1787388DFDF31519EEF87624C2B2C0F
-:1042400084FCDEB85A45E7BF272BBACC4FFBED0EF6
-:104250009637F6027DCA61CC075FDB744F04E284B7
-:104260005A56EA38F85A6E1FD4FB195DBDEE4A144F
-:1042700040DCFCE5ACEA7A7F768AFA4D5FC5FE1633
-:104280008F712FFD7A3F8BCF3C2CA6960737F0EF2E
-:104290005FD820E27D431EE2C773AC9EE29E85801C
-:1042A0008F8737EE0EA73A8FB9508BAEF35BF0EEE7
-:1042B0002966F70510D27719CC73CBC78FF47D9799
-:1042C000CE3BF3631FCAD94C89F56B69BFDE3A1F39
-:1042D000B3FDF37FFA059EB37F9EDFBF4EC8F4E5C2
-:1042E0001067DF3E52263138E8BC3D839763E272A7
-:1042F000F02B93E5E796554119689412DFBBFE97C2
-:104300003AE1FE9AED02E1C43AB80CEBF3FBDE7F32
-:10431000C2BF2FBEE69D6FED007D50A9A0BFB99D25
-:10432000DB3B267CFFE967793FFFC9D7652C7C6EB4
-:10433000E3DF7D80CFE045E1735B2A7C7E26686CFD
-:1043400087F71EC804A120783E566F87BCECAF37B4
-:1043500093C897E81C1E0E1FDC0F678F68FB8752FF
-:10436000B5FF4196F1353FC27312E7E72FF685019D
-:10437000155B1610EC27051CDF186F5DCB33989C7E
-:104380004B4B67CF4C6E5F4AEEC110E42F6815FFB0
-:10439000709B46E54C67E1E09A5471E2A702CCEECF
-:1043A000CF18232E7E98E3EFEACCC8B701EE76ED66
-:1043B00001F4F7148144A0FE96854344B0B47B23F6
-:1043C000C0E897C2FD0CC0AD5CC6EEB1F653BC436D
-:1043D000829CBF82C1BF453F4E204FDE1F3A8E797F
-:1043E000ADFE8A21E4771485B98CAEC01F54B9FDA7
-:1043F00076D8FF26DAF5999249777774011D4AC974
-:1044000032D2656F266BFFFBC01D5DE02FEE516859
-:104410001B9083B90ADA37CEF9FD2CC0E6A768C62F
-:10442000518077143EDD43DF827B09B64F67F7B9D1
-:104430002C1607D7DC0074798D0FED33FA7E8DF5DD
-:104440005CFE479C7F3FF233FB6AFB9F54FCEE5CB3
-:104450008FB1E8F5246FFF09E8F5642AFEA5F4FAA8
-:104460005B786FA1D70F486A7A7D7B0C7AFD0F6865
-:10447000EFC48BB32C116317EC2BCB1F2DDB07FD87
-:10448000C99F59B4EBBBF4297DB42D86AB19166CCA
-:10449000E79E93F23EFA2718D7BC7FC0FC3B46CD7F
-:1044A0004008F353F4BBA07217C8B10BE8570E6471
-:1044B0008FEEF7653F8377F135BE68AAFB14BE1314
-:1044C00090D9F9D800AB3716DFFC3AC0F253C6E2F8
-:1044D0009B17381F50BE0906E64FCC3767927C9376
-:1044E0001FB820BE79089F9E62C63738FFCB47F3BE
-:1044F0000D89ADEB02F9DA59C8F862CEFD9B902F19
-:1045000046F82816C3EF52B28CF2DBE4A38FEF8F8C
-:10451000617D67FBC018F70656707E5AA845E60114
-:10452000FE8D4BB476768E6908CFEBF692E17E373E
-:10453000E609B3BC5C6F2C6630F36090C0FDB48BB1
-:10454000381EF6808F067E50258F67C98364957F5D
-:10455000343FFB2B1215D67B605EE1E3FBD2234B8D
-:10456000018FBD646816D86763AD532D1F4FC832E5
-:104570006A0329F87F223DB421C0F4D0063E6EE6DE
-:10458000C76A23D8A74E7E5FBCF1D93F3C3E4E3F61
-:10459000EB391CEB029F585FAD0BA4D6573704ECE8
-:1045A000FAAA42284AC9FFEB0329E407E5FF9B5317
-:1045B000E1E553F0FB9D8114FC1E095C18BE9FE5EC
-:1045C000F87EF653E27B176FDF13F8C4F2B62715B7
-:1045D000BE28BE7706B22F08DFBB52AD17C5F7D78E
-:1045E00003B8FE4F23FC7EDD87F1F2EE05E420F4F4
-:1045F00093028E5E6B3FAACEFAA13CF58140E97E24
-:10460000F147DDE154F724D176FB52B5AB0D683CA0
-:104610000EAD6F06FFE1E1CFF8705F81EAC703815D
-:10462000FF5EB97F28151D2C16991CF206167581A0
-:10463000BEFF14FD0FA492FF5FE57436915DF01A82
-:10464000A70B3AEF9F029C4EF9D7CBCF312B5AF4F0
-:10465000E500E26BE86A90577BEECE1420DE956FA2
-:104660002404F0138E723D560597FDCC4FB6DB2324
-:104670002704B867674FA326C079294B7FAF07B2DD
-:10468000C7EECF090785EF3730BE2FDD188276B52C
-:104690007C7E176B271DC934DE0AA0FE89BC0D4F36
-:1046A00063A65D6E9BF310233D2CCF7661EABF734A
-:1046B00079D42F9BF2FF7DABFCFF8F11BA62FD5DB9
-:1046C000ACFEA1F09DE3F0FD25157C4EBC4C04E74B
-:1046D000250199EBDB889A9E424F39FB33FDEC9123
-:1046E00075029D6489FB64A78FE8EF603AAC478749
-:1046F00088E7A8567079B2626106B7DB352FF4FF00
-:10470000308FC33F7CCB0355B0AFDE7BAF5606285E
-:10471000C86D607A4FBF650AC657A7F27E9DF08FBD
-:10472000B457FA66C1DF8FA0E34E83792C59441247
-:10473000E037A683DD80F10A0DFFCE71A6BB27040A
-:10474000F1D92D42CF9A75A057AFF6B17331A1D5EB
-:1047500013DC9FD96AA35B12AA98A07E0BD6D7D28E
-:104760007AF09E950BAEEFEE496967D5A48B9C9EBF
-:10477000A24BC6C56B2888712F13BFA3C761EB5727
-:1047800015691400DFFE0A4183D43B3FA513B0979F
-:10479000C4E241CC9BFA6C05A31742FD92F1EF698C
-:1047A000E934E15A0578FFB47099F5C61E8FD773C6
-:1047B0009CB718F97B643E26C7B0222DBF77342BF7
-:1047C000E5BE82F9EC6AD60CB832F93D4DC7FB1B49
-:1047D000BB46F2BEC3A155FEFFF97AC979C5597C23
-:1047E000D4517FE49E92908AF61FFE9D0FEB7D3D93
-:1047F0009C2ED48C482C1DE54A18EF89A4E5565808
-:104800000FA2D2B21FCBED58D646CA9D583FC4EA7C
-:10481000134DBB20BCD376DBB11F79A49F1DD88F6D
-:104820006F64DC9D580E8E941FC4FAF9ACFE858E21
-:1048300033EA9E964109E7FF816CA4C3BEE9E79B7A
-:104840006EC0F8D2754D37E1B3BB59AB82389D7954
-:104850005FC9E7AFBB41037FFABA2F3F88FBFA6617
-:10486000FF2BC1EF00FED7E55AB097944231F29882
-:104870002FC97F4938DAB1BC4266F7FEAF5C787A5F
-:104880007BBB257EA7C2DF4F87FC1ADD725F06491E
-:10489000CAC32704E37BE91741CFA3E749C800A5B2
-:1048A000DF0F7CC5F118D273B5968A6FCCF98ED51F
-:1048B000BF39DFB1E48D8937F3FD9662FEF7761DCF
-:1048C000F14BCFF41ACCFF59297038FDFCFE485E3D
-:1048D0006F051DE7E952A40B1DE87605F7EF9CFA7A
-:1048E000C11CF709217A02E804E2C4F7968FC6EFEB
-:1048F00085E2CDEC7F723446E0FE2E6F29C17DB19A
-:10490000A0DFDC576772ED219F598E617249A4B810
-:1049100007E59C4737E51ED3935A5A9F2196513F8E
-:10492000A887D48666411E6834047FEA87968FCABA
-:10493000684FB0321DFEE800DA3FDA6CB8F1516D15
-:104940003FF7A3A35712767411F7DDCEFD08F5B734
-:1049500059860B7C4B68D93B5236D4102D178D9459
-:104960006350DEC3ED3EA1E7DC8F60CF84EAE573E0
-:1049700056795FC5E5EA44F2F4BF00B9E905CA001B
-:10498000800000001F8B080000000000000BE57D88
-:104990000B7854D5B5F03E73E695642699BC270490
-:1049A000C8090F098A38090482623BE1D558790C9D
-:1049B00015359628938447782620D5B1D2322180A8
-:1049C000A0D886AA156BC509C57B69AFB6A0B4E5AA
-:1049D0007AD17F10B4D0521A2B55B4A25150F15154
-:1049E000938294A9D572D75A7BEFCC39273321B45F
-:1049F000DEFFEFFF5DF874B3CFD967EFBD1E7BAD6F
-:104A0000B5D75A7B0F6361C6721963DE1CC6C63107
-:104A1000761EFF7CB967C944BB366DAD67C268A816
-:104A200079ADBEA11A631BF15541BC5D89C74EED3E
-:104A30001ECD0CA67BCA199BBEAACBEA8476CEE219
-:104A40001C77D0C55891F79370257C5F349E310D4B
-:104A5000BF1D9245E3B679572A769842DB08E651A6
-:104A600018BD5BE381F6396EC6DAA164D60863230C
-:104A700018BBDF25EB301F28032511D601CF533596
-:104A8000FEDE827578AE3A58D34EA8A795307F04E3
-:104A9000EA1E079B1380B2D863610CE6E5F3A834E5
-:104AA0004F1F8E06F50CEF5AA6417B6795C51F81F7
-:104AB00032034B971EFEB5E23B2B95121FD7E6043F
-:104AC00047209C6D8C55EDC479B168A004E0481D69
-:104AD0009E937537D42A4BAC2B190CF9E86A1698BB
-:104AE0006B63ACC21348C3F6AED29CD4E008AA8F65
-:104AF000F2403FAE75963003BC54327744298EE3C2
-:104B000005669E1A7027A7C7CBAB838149B6E474AC
-:104B1000BBE12635A087439653100FF0FDC7D5EFB4
-:104B20007C1FC159EAECB2B34140CF219B034C45F5
-:104B3000783482D3B97B66B410DE2FDBB39CE17C82
-:104B4000D7A4A58F473A9AC77DF9B3073D01789F4F
-:104B5000F25747606782F196083C1F5D5D4DDF416B
-:104B6000F79A358FB13908CA204604ED7062C994AE
-:104B7000F30E02EFE810787F0BE3CC302B503B8D27
-:104B8000015EEBAA55A616E377DDEDD979A8DFD251
-:104B9000513B958D844AC876129F3BE1EF79E83707
-:104BA000C832A778E0716D983FA7F6F0DF3CE69B2E
-:104BB000920BDFD56F303D7FFD9AF7593ABEB79E15
-:104BC000EC2889F77F63756D6092687786FE1F21F8
-:104BD000786669CC8F749BE54B8B8401C4EB0337FB
-:104BE000052695C4FB7BE573750EE2C58C8FFF44EB
-:104BF0007CE4223E028149437BE2A32EA0D83DDA29
-:104C000085F1D2573CD45A4BA7E46A3DF160861F28
-:104C100030762FE2791EE0F9EEE2E4F88076448FF8
-:104C2000576E827600CA1475AACD0278A89FA93063
-:104C30008742F84D6783B19D7FEA64DD7CCD78348F
-:104C4000E3ABFE19E68B42BFF50FB87DC0E1ECF790
-:104C5000123F5140DA189027BCA91ECEB771FE1E34
-:104C6000F88B707EADA2F4F91C984770ADE2631C1E
-:104C7000DEB7F5F0D5B140465421B8DF4E42F7B764
-:104C8000F5709AE7679E7F0A0A2B907FA1D78BBFAA
-:104C90007340D78E59A323029733F6538F3BE7DD3A
-:104CA000CBA03E92F9CEC3BA3ACBC6678CC2F743CB
-:104CB00012CBDB73ABB5EF1CB0E9D739E7B339A141
-:104CC00099DDE362FF0A0B76D73D80E7C04DEABD70
-:104CD000D7C3BF5F3E98BD0E9FADF0AADAC96CC4C2
-:104CE00017C04BF4F23326F98B6119DEA702FE667A
-:104CF00032A7E6827EBE0C42EA3CC032DD9FA2B9FA
-:104D000074709C6E55AA508E02F132665D1E87D774
-:104D10003CEF155E3B8D07FCF8899E1FCD7879B975
-:104D20007A7006CA9117112F69849791178397AFEC
-:104D3000E0628675E3C9665105E8DCA53823DB60CF
-:104D40004E35A13B039346215E58D80EA2F35D4F2A
-:104D5000B190D31C6E1B937F9A18CAD31A3B0B22B7
-:104D60005CAFDB58F52E1796D101653AB9F57E7622
-:104D7000E5BB28A765BD26F46DEA1F1891F850F22F
-:104D8000F32D4E5754E57CF85137DF903CABF120C2
-:104D9000DD814EEC3CC0A9662CD1106E352D7D24F2
-:104DA000CB606C033601389D9981D328FFD5B4813F
-:104DB00011E4BFD49B7EB481D3F1BEAA1B74744CA2
-:104DC00099F754983AD7B20CF84F13F4AB14F44B4C
-:104DD00029719AE9C7709D864B58E43145A000EAD5
-:104DE000A787F823B86E93E90D49CF9412EBA71D5E
-:104DF0007ABE66AD8457494776607417AED7A0D7A0
-:104E0000CAEEA6F725849FA047E2A7CB86FA644E98
-:104E1000C8765ADF4FB0606EA419BFDBE8F0E1B38B
-:104E20003A8B9687ED004F1ED4E3ACC4E7C3F5C3BD
-:104E3000C2F09DE427C42B1A13BAFE3B00868232CF
-:104E4000EC0FA4277EB74137CEA09EE376AF2B733D
-:104E5000BFA6EF5415EC07B2237C3E9F4E7E0FCECB
-:104E6000E4F6C369EFE89D9641C9F157E7CCF65BDC
-:104E7000B3E3F5B70B9CD591047A40F627F5799604
-:104E80001AF45A10B6F063070FF4473DECB9142436
-:104E900019BBC71639787000431661AC1FFE2F721C
-:104EA000D0EF22BB43D4813161FE6DA9DD75BFD344
-:104EB0000BF541DDF530D6B7C270EC4AB05B32235A
-:104EC00007D7C27CCE1D7790FE3A5D951AC1C59377
-:104ED0001D9AC84EC0BCAD60E66400AB4111C6D29D
-:104EE000192A2478142B600EF09DADF914C4F7AC88
-:104EF0004C8DE66FD558D40D93CBB6FA14C4D7F7C2
-:104F0000ECAC41C88DE13375F6CB2C01AF1CC7E189
-:104F100064E194B278BF606135A31EB14E65A457B9
-:104F2000609D93DD26D7B7EC2798C9F567F7FABCE3
-:104F3000F07A0E662658CF872D4D6F7E0BEDD95F28
-:104F4000ABEC3100E566EF1DF4FC86503D953785EE
-:104F50001652B9488CF70E0B2ECA84B2BDFAA59B27
-:104F60006F07FE6DDCEDF0A15A5E7ADBFBDF29D71F
-:104F7000104F4077FC6E5EFD03E5F0DE3ED442F656
-:104F8000EC8601AC1AF9C9DEAC907DB451B357ED93
-:104F900086F2A18CCA2D993A381ECA98447556A536
-:104FA0005990CF5738399F9F3B7E97B70EED4A9760
-:104FB0008BD68BBDB9F8BB16A8B343306F86F2838E
-:104FC000919DA13A78797726B753EF16F85E93C989
-:104FD000ED3D670C89CCF9BA09C6775AC30CED6C64
-:104FE00067CC4ACFED0ACC2F019FCAFE9C3158A452
-:104FF000A3703CF3F7767A8E70E1F76A3633D83DCA
-:10500000F7E1F7B958CA79A4F179649BFB49E7CF76
-:10501000C5FA33CFE34F9E890F227E1ECAF06FC9B7
-:10502000A475D36143797E8BEBD7C794917D91C7EB
-:105030001D0ACAE3E99F29D122C05F4AA51A595324
-:105040008C7ACD336D34F001ABB4F9109FED43721F
-:10505000DC8374E3FF44D0FF45ABC78DF30C4C06F3
-:10506000BB9AF89BE5CEC27E26D78FE1F20F0C2EBD
-:105070009D9E7D51DBBE6110CADFB08DF64B739CE7
-:10508000E108CE4F67B729E7B95CD6AC63E2F6DF3B
-:105090009C49AA3F25BDA77D07DB900364FF4959C2
-:1050A0001E863A7CF786A8BE39E9CCF5084607F398
-:1050B000D807E9ED41DC2D8D41FB86FF991332DAEB
-:1050C0007D66BBB0AEA2F4052003E02552351AF987
-:1050D0006CB885F8ACAFF632639B399D27B7787012
-:1050E0005FF528CA09A84F9F746212CA8D19605AC9
-:1050F00061BF3326A99E28B4DE14B2303F4CFC8831
-:105100005F8D2800DB91928E435F46BC55D834D228
-:105110005B25ECDEEB72F0FD280FE23920EC106825
-:10512000CFF59BD719190ACFDAFD275CF53ABE3BBC
-:1051300052716238EE5740EE3524E227C69A89AFA5
-:105140000F7C3395FA79F37E25E280F94F563FFBC9
-:10515000ED58B467BF65F3393402CB82749DEA63BE
-:1051600062E3EA774DD6D9012758600CD995A5C7D7
-:105170002B1D68BFAE53689D4AFCCF0919EDCD6069
-:1051800013D8655A4FFB143AB3233FF7D53E35DBAE
-:10519000579F650A7BB38C95E9EDAA647A4ADA5584
-:1051A00056E657B3F87AB2A2DE9D0E0F12C9819A65
-:1051B0000CBE0E26AB1F117D4E57A81AE2EB48E835
-:1051C0000317EEC78F7CA6F27DB03FD760C715648A
-:1051D00071BFC0563B1864F0DDD67ECE483374B53F
-:1051E000EF9B97E677107DB407C7231D7F6D2339AA
-:1051F0009C6CBEEE90CA8600634E0B29544AFA1589
-:1052000085529855A71F8A58E2F95F9AC5F7A1B948
-:10521000AB9845837133C3CC9F687F2CDBC1BE78CC
-:105220008A9551FB6826CC6FD9100BF1A7DC1FA71C
-:10523000D8C2FE4280DFB6777918F7C945303F9C67
-:105240008706F3437D591C4AA3FAA0503695834341
-:1052500099540E0915D2FBA1A1C1545E122AA6E7EA
-:10526000C3429751BD24348ACAE1A1522A2F0D5D51
-:1052700045E565A037B1DD885025959787AEA5E750
-:105280002343D7517945682695BED06C7A5F1AAA18
-:10529000A7B22C544BCF478516537D74E856AA9776
-:1052A000879653392674279563432D5456849AA9BB
-:1052B000DDB8D03D54BF32741F9557853653393E03
-:1052C000F430BD97764BAA588FF768733DE8EF002E
-:1052D0000ED7908F93ADBB85595C0FBC98E99F8921
-:1052E0007C27DBD92DA0C75D3DDBCD136526D235EC
-:1052F000417FC12CCE971FFBDEFEFE3016A7DB469A
-:105300006FEFFE0C56D237BF57208BCBAFADD676A2
-:10531000BF8AFCDBC47C6178346DF48B0ACA973693
-:10532000CD5A95C8BE7B28CB46E33E9A196CCA82FB
-:10533000EFD38A4F1E40793223ECF9ED04E4971144
-:1053400039BF9E00FD15ADB5D0765F639E7DE85FE9
-:10535000D32631928BD2AF04769D419F6ECE92764A
-:10536000E3CE8383683D0D29E3FAA7E31A5C5FF679
-:105370006F0EA2FDFB567B54B1A27DB38231BDFD01
-:10538000BF757DDDBFE1FB787F7C7D166D60CFA1B1
-:10539000895DDCAA4D488172F016FF7329F0C9D0EF
-:1053A0004870422AD487ED083F87E5F09D9109694E
-:1053B000505EB627FA1C6EE32E8F764C7041FD8A44
-:1053C000836C3F2EFFD2766DA21BEAA38EF9F70302
-:1053D0001BB0F28EE0C4740DE713694987F96C7D48
-:1053E000030C3DA8577CD4AAC276284E7FB0E3D0E8
-:1053F0007E9374718F6E9F940DFFECBFD253AAE21F
-:10540000F7D68E94CC113DE9D38670239CA0471E1D
-:1054100003B8FAFBA38A47C727CF08FE003AB42196
-:105420001DA45FB26D6D16F925DB523D953864D72A
-:1054300064E6D9A6211F5B094FF67583C81F27F9BB
-:105440000EF06BB067370B39B1B5DBDE4D8CDF6723
-:1054500010BFE5FF3AF89D9AC5D74332FC3A915701
-:10546000C65D781D1F117C08EBF8D788D764EDCE98
-:1054700008FC9BF1DC6661074157C1B8C0A77C5DA1
-:1054800031F4A37D2CD6FB85F07AEA5F0CAFCF0B0D
-:1054900039910CAF4CCB213909FC3A1CFD63C9E4AE
-:1054A0008D5DEC67CCEF3F17FCA69373DC6FEB01CF
-:1054B000393738B99C3B7421F925E48CDDE4DF49A8
-:1054C000CDE6E3557802CEECF2047E6A1137907E89
-:1054D000EAA9AAA712E50D1BC6C88E4E1B1109E347
-:1054E0003EA528AC95A9D80C8532E2B15F09F91F19
-:1054F0008AC1CEB002FDA1AB28964ECD63A943FF71
-:10550000BB5C6F9E5AAF7EBD497D1F5F8F922FB2ED
-:10551000DAEEE67E496D26D82FD764737E8BF7C30B
-:10552000FD20EBEFE8D776B74E0EB679BD5497ED78
-:1055300093F1EF02F1BE6DED1AC2A7737C62BB61FD
-:1055400062B62AE441971FF93CFC25E6417B2673AD
-:10555000EDDB249F32413E29249FF8F8FD43A9FF4B
-:105560001686FA84EC3C21CF3DA937B8FFDFF173F2
-:105570003EDA54A807C67BF6A918A7013DA4E13A74
-:105580001D0F731F8DF8B213DD35C6E9A88D6711A5
-:10559000B47B016F51DCB7872D6EF233D9EDAD7E50
-:1055A0005CCFCC9E49F057788233B37B91379E34E1
-:1055B000AD14895A97BDEB1A17F0DFFA624F2AD65D
-:1055C000E7407D53058C9BD5C1447DA36BDC3FEE4A
-:1055D000F7A8BBEF6787D0EFB13FCB1FCCE67C5D70
-:1055E00087A57F98C74AFEEA3EC6C1E4FA8CAF277A
-:1055F0004FA95C4FB523481E2EC17E657FC9EC9B29
-:105600004BB2B99CFB56B6C5C0D73DC76D36AFFB94
-:10561000BED93762BE8BB37B5FFF2F1FBC6FCB76CB
-:10562000A6F337F6FB7EBB55437F06F7D3589CEDB8
-:10563000D49F5BF81BFDE86F043E700EE175FC9390
-:10564000C85F9C1C8F119AAFF4334A7F62BAE02B7B
-:10565000665522A8C7D32B3CD63AEAAF837D0DFA14
-:10566000FB81C0935CD728B79E1C817229CB8AFB33
-:1056700075F427B9B3E2FD633DA32C2E9F98D8C7DC
-:10568000DD2AE6DCBAC697812EE7F011EE4769FD08
-:10569000365F97D3FAB3C81A94137EA679A07D0A11
-:1056A000937FFC067FF2D44F15E687F91FFE54A5C1
-:1056B0005219C2A26ED8EF4DF32951DC07DA2DCE74
-:1056C00008EAD2CA7E4E86F14D7BBA2582F111FBE3
-:1056D000DB0AC1692F4B8BA0F09BD4AF2203E39868
-:1056E000670EEF770513D0FFC660ADC1FF65C663D7
-:1056F00077BB9B9FF7201E1FBE409CF65076779C81
-:10570000767F36DA4373BBD6DAB5789C56C61F0B64
-:10571000BCBB3756A2CA5AC2EDD37E2CD2ACB7ABB3
-:105720007471D0DF22BF3F1C8F83B65FA28F833698
-:10573000F6DB8BF6EE43DD71D06014C7F567EF2C16
-:1057400045FE7DD8B7FBC7DF457C3A44BC62D471C7
-:1057500097867EFAF2FDB908CF6F4DF397A5F4E373
-:1057600099F7C1C7B38DF18533BEEB32A2C45BD9C3
-:1057700009D7B7F42FCAFD30FA0F3D09D7A111DFC1
-:1057800072FC1A85EF6B994DE1F24FE851902F9D15
-:105790002407228CF4A6DFA16C437D73C637CA4769
-:1057A00071CF24F246CE07F0383451FC17C64B189F
-:1057B000674DC9E17AAAC6C6FDA6CAF2F2269C5771
-:1057C0008DDBA53874FEFEB342AF9BE3426AC66729
-:1057D000E541E1F74E04BF39BE7356E80BC497DECE
-:1057E0004F7E217C1DB3B552FCF0D83C9535433F2C
-:1057F000678263F35982EF65F91AF2CD50C6DECCA9
-:10580000E1E375D33349BCE8D8EA068A339BE36900
-:10581000DDEF6B53AA517F57231E75E35E29F077A6
-:105820009D289923A879E0BDBDEE010FC3F8D7D01C
-:105830004FCAC36EF48B75FD1CE317EC5B6EF25719
-:1058400054D79E2D6FBE5C87CF0AC6E3B3FB1FF211
-:1058500068F0BC7AE8DADCB02B391ED1B78578BAAB
-:10586000071F8C237F4C79CE45F863D8081E17623A
-:10587000FB53287E9AF207D58776038ECBF500F787
-:1058800027AF147113731CAF3AB4CC205FD2620AF5
-:105890008BE8E21769D69DE49F4D8B59E9B979BD34
-:1058A000E5E774C73969BD49FC27A3A7C4BFF979E7
-:1058B000590EE7CB63B50B35F41BDA5313DBC11B71
-:1058C000453B5937E723248BBBCF17743D131C97F7
-:1058D0008FFEAA6A7B78685FD6B9C4CF85F21CE6D2
-:1058E000E4707DEEBEE92511C753D7626F52AFA6B3
-:1058F000597B8FC7FA4DF1D8B4D13DE279FF23F13E
-:10590000D8969C7F2C1E7BADE0DB0BE5A1DC6837D5
-:10591000DA3DDD7815743C134C6161908FB756AA5F
-:10592000148702FE20FD78EC0185ECCD68AD83F490
-:10593000727D6D0AF967EB4B557A5F7FAF4AFA3398
-:105940000AF26109C887DF0A3961F6CF5632C510FD
-:105950003F9F3E3AC550BF69DE7DBF5D8DFEE50AC3
-:105960009B86E31DD1B8BF39EC57C97E853E7C517B
-:10597000F44FDF7FB50FF599E487237E95D65BF86A
-:10598000A8EAC361DB853FFAC886D208E6A93025BC
-:105990001EA7D70663FFF514077ED5BB85E29C29B9
-:1059A0009F3F1808D0FE31A89592DEE4F1D314B1E0
-:1059B0004E27F6ABB801F5F89B9B6C0CFD466FAE1D
-:1059C0003A43EBB9637513E54548FFB2F40F9BFD0D
-:1059D000CC66FF720FBFB2C99F9C2C9FE15749F85C
-:1059E00043CAAB64FC0162EB484EEEC5CB31293FA4
-:1059F0005E13704EECB7E5DE66C043DA5C95F020CE
-:105A0000F9F2D5CFEE7A04E5700AF0C71A86F8FCF1
-:105A1000F7E7711FC2162A09FDC81952AE63FE448A
-:105A2000499C2E37051776D771F9CF6E586EC8FB93
-:105A300030EB95E472AD77B9B53987DB5D66BD6350
-:105A40005E0F5FB4DEA9AE7DA004BFAFAE9D17C1EF
-:105A500072633F6703CA5FB37C30EB896A939C8DA6
-:105A6000EB07954546E9E7AD51BBB89EB0D3FB7354
-:105A7000293CDF21E4E4E5EDA9E9DBB03C97C2F382
-:105A80001DC26814A29DFA465AA485F6E54D63919D
-:105A90004F42CCD7114638BDA9E44768EDCFDBA90A
-:105AA000D7A472BBFC4025C1AB4AC37C6D25AD9B1E
-:105AB0001601CBD6EC60512ECCA7C56F49C1F8C2F8
-:105AC00044B7F510BA5E5A27589883C5F115CF0B25
-:105AD000611E05BEA7770AEE3F4B9DF6C164A70E77
-:105AE000CB457EF936EC0F81EF0F1F5677B701A833
-:105AF000877DA33212D9E9B234C7918F7FE39581B4
-:105B0000B86EDF61C1B25C8A1FD7DF8BF1E1C63DA1
-:105B10002AC5976EBEEDD54BC8EE36C529D574673C
-:105B200009FA535A94541FCA1389C77D6E3BC99909
-:105B300096E369B49F68794B117537C94389F703B8
-:105B4000D0AE6034E62AB9496E4AFC035C13701E7D
-:105B5000920E952C7A787CF13F05D734C47772B8D1
-:105B6000FA7B487E209FA9713854B795E0EB64A971
-:105B70003E9C5F48F887D8EB69B4FF93746E14FCC1
-:105B800028E9BC4CD0B973EFD9EF5C05ED5BFD594A
-:105B90001475500730C243E7EB6EE21389070937EB
-:105BA000F0451DCE53C2BD7FEFA86341FC3E3D953D
-:105BB000E2F8D2EE9679073DE494D8BF2FCD55BADE
-:105BC000ED5EF45FFC3E7BC2D2DCDC04ED85BD0BF8
-:105BD000F86EC2712B3DEC93088BEFF392E537AC76
-:105BE00012FD77F773E1FC8655B989F21BFE717AD5
-:105BF000DE7531F46CB4BA362819717CCB7D332D47
-:105C000069ADE7FA37AF3F490F65EFBEBF621CDFF2
-:105C10002C176E579B9802E3ACBF9CAF4BB68A69BA
-:105C2000941F645A2F17923740FF6D085732B9D32B
-:105C300057FA3FD193FE4FF446FFEF65077E86EF9C
-:105C400071A8C232DA17EEC23ACA13FB201A8FF8D3
-:105C5000B62B93513E9BCC8F91F3917932514C5A94
-:105C6000CDD5E5E194F814D4137DE08FA87E7E5F56
-:105C7000007FFCA6773916A575BA54D07FA9CCCB86
-:105C8000D8DD7B5E461FE8F75A22FADDAEFABA820B
-:105C9000C57DA7DF3B3DE9F74EEFF40B9EC2F72D24
-:105CA00076F609D9EF15B55EE4970A8F7F16E6A15F
-:105CB0003CDB2CE44E31D00FDE3F9FA3925CFB1EF9
-:105CC000BB94E4F6972C169A6F27C8EB6D4A9FE0B9
-:105CD0008CE5D2FE2F6CCD827E6FBF8E517CCFAB18
-:105CE000352B58CFD7404F6B7D8757CDE37A5C0774
-:105CF000AF9A9740AFEBE4953D8FF3E74AE44FA7A7
-:105D0000E6B1F626AFB2F28C76421FF8312BEF8B5C
-:105D1000E5C70179BDCAAB8BE6B36138BF6472A237
-:105D2000AF79A0B04E596156CFF119F3515CAD3245
-:105D3000DDC9F5F62E45E8F1D220D5DD4E12160765
-:105D4000849E3FBD9BBF572724B62B7D7959C4CF76
-:105D50004B772E0F580DF924617AFE5DFF69CF1045
-:105D600015F3B45D044FF634EE8794F0CB3CED743C
-:105D7000014FF6000E77F6719ED72EF1952EF61B89
-:105D8000191556C33E42E2ED7635A0A01F3D33877C
-:105D9000619A04EC134628E8E7CAF41BDB4B7CE766
-:105DA000B24D7F5631E5ABCAF83E17F73323F1BD4C
-:105DB000EE7982FD2BD0A704F3C766E709FF839D28
-:105DC00079511F31B5A6573ED2ED4FEAF2FAE0679E
-:105DD00069C8B3887D8351EFED4C6109FD0C7F11DB
-:105DE000EB01EC15F237AB42CF4DEA28A67C9715B4
-:105DF0006E8DFC0FAAEA734E2DEEF97DA61F96B7A5
-:105E00000E1FD955A94CD3C19D1BC832D4F3ABFB8F
-:105E100019DA17040719DE17365C6A783FA0A9CC97
-:105E2000502F0A5D69685F0C88D5D7076FF8AAA163
-:105E3000FDD0D6AF19EAC3B67CDDD07E78A4CEF013
-:105E4000FEB21D8B0CEF2FDFB9C250BF62CF370DF2
-:105E5000ED5B841FD98C97FFCCE372BBC5CAE550BC
-:105E6000B3AB8CFC9B2D2EA37FF33E81FFCA8CF13C
-:105E700025E8576F79BBB404F17D20FD4AF2B327C2
-:105E8000E30BB35C4B264FCDCF9F14E37DFC9CDD31
-:105E9000827CBD6C3FACDB2BA0EE7A6D3DC2B47151
-:105EA000048FCFDA18CF1792F11AF97D77BCC6EAC2
-:105EB000E3FEDA7417BB3B015FDC97A725F4A74A22
-:105EC0003E4A8637C98F17C2DBD302BFFF2CDE5E86
-:105ED0005778BEAB5E1FEC4A30AF337916115F0EB8
-:105EE0001E15FA66742A59F21E5A8F17AB0FE43C3E
-:105EF000401FBC9997DB334FF7E3EA97E63FA86171
-:105F0000FBF9BCBDC557827449E64F3F23F0A6F3A9
-:105F1000A737707F7AAA016F6FC9F56EF2EBB5A44F
-:105F20007F4AFEF416BBAFA42FFEF4B7F218E1FFD0
-:105F300069A473AE8EBEC21F9F6C1F1562EC109ECB
-:105F400087602EABA6DF3725DB1F4B790EFBE312F4
-:105F50008CD3B6E2FE4B49A80753F2CB69FF4CFA4B
-:105F6000A015F4A083FC04EC9006F5DB275AD8DDDD
-:105F70005A1C6E69CF3B98CF695789AE19F83DFB23
-:105F8000365B99A27E21FBCC7EF917A1E7D985E388
-:105F90007D64A74D03F8D7E8F6D7123FE6F89EC414
-:105FA000CF341F8FDFAD03FD88F1BD7DB95C4FAFEE
-:105FB00083FD37E2D1931DF00E447B1E9E6F43722A
-:105FC000E48EA1F523F16A8EF3F555EE8CCFEF61E7
-:105FD000B78ECFEFC56E95F0AF10FBE7C9EA889D8D
-:105FE000E8C73C1DB313DE54C6F32E1B0FDA5884EA
-:105FF000E8C8F397251D6DB1F5EDA89F6DCC9CAF5A
-:10600000AC6520FCB683FC9C18CBE1EFC3CCD98CEB
-:10601000764F4685517F65FA8DFA2BBB2ACBA4CFEC
-:106020008CFA2BBFDAA8BF0A8246FD55D85066D23B
-:106030006746FD55149A60D26746FD3578C3D74C44
-:10604000FACCA8BF866D31EAAFE111A3FEBA6CC7E6
-:106050000A933E33EAAF2BF6AC31BC2F8DDE6D7860
-:106060003FEAE0F70CF5F2F61F18DA2F38F414E5E2
-:10607000F58C3DB6CDD06E5CC74F0CED00E1ED98D0
-:10608000FF3D9748C2D855A79E34BC9F2BECB5ABBB
-:10609000BB9E36F4C35A791E7718FE22BDDE6341DB
-:1060A0003B1A2956D6F54221D0755944F145A1D95C
-:1060B000C23DBBC6E03C3E7CE39A83D8CF822DC66E
-:1060C000FCEF851163BD910DCA40B9D0087C110168
-:1060D0003E598C79E13AF9B698358973817DE3B3FD
-:1060E0000587AE63944F1AF6B763DEBB8453F29B09
-:1060F0005FF09B9C9F847731D87F512D0EA71FFEA8
-:10610000F2FD66871DF976FE1E85FD40E9094FC345
-:10611000DECDEB0B13C06586C36C87FE47BED13F57
-:106120003E597551BCE0F451D5C7FD8DC675B8E236
-:10613000108F13AC7842217F9D191FD23E4D8617D8
-:1061400035CCF70D8D392C12D1AD3F4DE0C3E13583
-:10615000AEBFD3F80F9CCF0FD508E61BA568A96684
-:106160007E1B13653DF19C56625CA7663CBB7DFDC2
-:1061700012F295067F711EF3C5F943335F99F1BEA4
-:106180006CCF663BCAC38BC5FB6BF989E312A0EDEC
-:1061900046DB13E4D749BCC2BEBD03F548B2FDECF3
-:1061A00047F917BD9FFD28FF8BDDCF9EEB4DCF75C7
-:1061B000A2BF0DEC4BB39FCDAC8795BDFBFFAAA44E
-:1061C000935FBBC381EB2EE873F23C18939E2C299E
-:1061D00031E8C9EE7DEFDB0AED7B7F91E1B77B61B2
-:1061E0003EBFC9F03BBC00E72D197EA757076F0BD8
-:1061F000E085CEFD809EDA95C04E9CE495719700B7
-:10620000F94DD655F2F6E67623BCFC9CD1BEDC31C6
-:106210005EB23FDF2AF592FDE91ED3ABFDF95D11B9
-:1062200027BA07E39043E3F941F78A780D2C3B3F07
-:10623000D26D9D2DE0D5E70F67783369BCF4714FBF
-:10624000B6631E758BC7E251342C793EF75A97B569
-:106250006ABBF82EC7F01D3FCFA422BE01AF5697F0
-:10626000F5533DDF4EF232EA37199C93BC7C3F690F
-:1062700063C17BD11E92F161DBDB954E94772DCC0F
-:10628000EFE172D2E7D1E77FD8188F074F10F161A5
-:10629000F95CF5FC637958ED19C189DE047958770A
-:1062A00064F827E1F39035EC40BB33E44CBC2FFE9F
-:1062B000AA97AF139B80170C50E22B9A877AF1F1C3
-:1062C0001FB037AFC7716F57C39427D9E21E53125F
-:1062D00074F5DDCF15F4F6B08F82DE5EEC23B04F9F
-:1062E00067E179327F463F2B6D3BACBE12C4F706A7
-:1062F000FCF738F2D32EC0EF7BE4BD8A73B8B08FC1
-:10630000EB358F57F6B33FCBBFCCCBF30D9BB03FF4
-:10631000FF30CF5A55D74FFA05FA917E8E3EF8AD31
-:10632000BEED4DEC1F3D85FABDAF78DCE8EDE12F09
-:10633000DCE8EDC55F78EEF8B00C8C674B7F97B961
-:106340009D3C1729EB1B328DE3AF2FE3F5FBC5B85E
-:10635000AF887B3A7688BAD3745ED43995D13D1D27
-:10636000F29CA9EC6787D74DED9BB327ECC0F9AE43
-:106370002F56681FBA3E5331EC47EBBD953B900E4C
-:10638000DB44FF3B907F73296F94FC39E63CCC25BE
-:10639000A2FD12EF042AF15C2BCA31BBAA26C4E38A
-:1063A000135E3EFF5999BC5FE977AB7F4011FB2735
-:1063B000E3BD08B0CE5F4E03F97362938DCEBDCEC0
-:1063C000535DEB911F93DD73503B2240F94FFFEC7F
-:1063D000F931C4675A564FBDFABC37F1BD05C9E45F
-:1063E00088CE9F76D87B11794B1DA99C4FBBDC2EA4
-:1063F000F29B9BDBBD2BE8B349F83550AEA37EC9B9
-:10640000525953223DF3AEC0FB3F7EAE99DFE79178
-:10641000ED72D177E673CD1DF68E75F938DFAB15C9
-:106420001F9E5FC8AFF1ECCBCFC1738C1AF9F8D6C1
-:1064300017B3F40A7C5F6AA1F799B33CEB6D98F748
-:10644000AD31CCDC673618C70DE3A4171473B8C29E
-:10645000D7EDCB8776195A171B3482CE7B4FF1E2EA
-:10646000BAADE6F9F33DF02DE49B6B1DEC2F101F48
-:106470005AE23CF4F342BF80BCF93BF26BA5C6760E
-:10648000F373593C0F16D992F2157D3C5F3B0DF327
-:106490009D06737983EF95EC89D682DCF8FA520574
-:1064A000BECDE7B9D30BF8387D3DCF3DA326F17CB7
-:1064B000871770B88E67047270DC19E39BB93FECE4
-:1064C000B3F3E7D531681CF37502DF33F457A4E466
-:1064D00070399CA26924979947A13C57A7E66BC0E5
-:1064E0007A8AEB4A8F8A76B283C725D95C0BC3FBC5
-:1064F00055268A7EFCD54C79B784FB65B99CB5B22C
-:106500007725FFAB02396350CFF23F603F6D4A03FE
-:106510007826BA0E537C32654853259E6B787E0EE2
-:10652000EFE37B49CE0DC8F3EEDDE7FAD98F0E1B02
-:10653000CEF5AF7BE4F0C1AB75E7FAC38F1CF68FE5
-:10654000F8C7F3DBA73CF4C8E1B5AEFFB973FD5261
-:106550009E1D5383C7EE04FC5F0F4C152AC3D2CA9D
-:106560006A88DE5EC2DB2C81E7F0A78067671CCFFC
-:10657000D7EF3D44F83B668379C3F8B6091CD5B61E
-:106580006F66445A482E4668DC1B9CAD9371DFD978
-:1065900069EF1A89E3763EF3CA8030C893E3DF3AA5
-:1065A000E366C07F6F5ABBDCF8FCD4AA97DC780F97
-:1065B000C2F1552AD96B742E5A978FD420F8EA5716
-:1065C000058139C85773567F3E466F8FB3502EE909
-:1065D000DF85119552AFA4FC5BBC234D301DAF2F5E
-:1065E000DD996DA84BBDBCD491F89CFAA3059CEE37
-:1065F0000B1F6FB3176A387E70398E7F4AE4379C61
-:10660000DAEDA67D989C4FDDE3A576DC77BEB9D7A1
-:10661000C1A2E4076EB731F267F9A72A79788F1122
-:10662000FF639EE70BCFA6517FF31E50C9EF540BBB
-:10663000638500AFC1BD0BF93ED804C7BCE3DA14D3
-:106640009457F3362A2CACF1F6ABF0FE8CD05D14E7
-:106650008731C369D62F0B92DC9FB360EF3DF4FD09
-:106660005CE6BF07EDD979ADE6F7D7BC874CBEE055
-:1066700002F19CFB0B84DE19C3C69E1F4CF1A38C58
-:10668000CBB50BEB9D53ABF922FD60B593CA8F568A
-:106690007BA89C53C0F978F19E7D2F14D2326F1FD6
-:1066A000837AE9E583F5695FD7E276F798B65BF719
-:1066B0003F4C4D8DF9993502EF63455EE60271EE70
-:1066C000A1FC58EF799935888F913DE72BEDEC1AB5
-:1066D00093DF57DADD667C9C3E38310DF9E3970590
-:1066E000629F3B16F0A2FEF37849F6DD5295DF9BE0
-:1066F000667E2ED7D11CC1D773B7CF5CDF0FC66FB4
-:1067000079E6BD811DC4A7DC7F512EF055EE5ADF1E
-:106710008EF0973393DF30CC8E321D3F033FA9A814
-:1067200077CC7C2BF9891DE5DF3B855FA39B5FF769
-:10673000DE4BF8957C85271D2C68C3B1A8D7527114
-:10674000E17BAEE6B51AEB1FDB3A06A23C5960F2DC
-:10675000377CAC24DEBF1D2A1844F898ABF9A7603B
-:10676000FEC53C1658CFFDF3FC7E9C53D6D617EEE3
-:10677000C475BE9DAFB3A5BF7CE21728BF16FDEC64
-:106780008174945FEF5B5BF370BC258FAD4B4779F1
-:106790007FCA1A4EC7EFDF8FA809CF115FD24FEE25
-:1067A0009FFD2ECC535B46AC06FFCD0D4F47F9F94C
-:1067B00097C76C1EF4C336EE70441D808F65BB39DD
-:1067C0001EA1FE16AFDF45F86ADC635C978BFEFD09
-:1067D000813C8DFC01E14281BF4214E1CBB6DB2854
-:1067E000AF75D951D587C334B22E82CFFC3DCE23AD
-:1067F00006746BDCA9D6DA337ABE074BC88EEBADD4
-:106800007137A767E36E4EAF46931DDA20E4B69961
-:10681000FFF3FA097920F81EF0437E35996FCB22F9
-:106820005C7EB7FCF8C1916FC1FC3EDAFE9B7465DB
-:10683000449CFF196685023D4EEFAC9F63EFE5BEB9
-:106840009E8FC53AE9D60B420F697B6062F950DD35
-:10685000CBCB25B668FA558097256D365F181E2F6D
-:106860007942F5BBD08E7AD541F74F2C7EE2F9976D
-:10687000AF84F92DDE65CB99CAC170A1FC96F46A8C
-:10688000443E2F8BD367D153CFDB314F139FAFCA19
-:106890008AD369F1AE7D76CCFB34E373E2CE7D76AC
-:1068A000BEDE4CF4DAF9D614D4DB2D3F3E67477ECA
-:1068B00078FF5985E517F7FCBEA1EDF9749433888C
-:1068C00027D42F926EDD74EC41BFE8F4A747533B09
-:1068D0000FC6792E44C7BFE019845CE2F79F3E0DD6
-:1068E000F36878CDE1433C34FCF4D67484E73D6B27
-:1068F00013E7FB47D6E5A1DE6EB085F33C54F2E723
-:106900000D5BBF41FCB8E0C56FF0FB9C98BF00D7A2
-:1069100033C05B8070CEFBE1F504E77C16247E6C0F
-:106920007884DF6F78D6CAAA12ED07DAC4BA796F15
-:106930009B83360FEFD919BF2FE4F7AAB80F6B3935
-:10694000D92BDF10308384A6FA5927A7D7CA7EF245
-:106950009C3D976F8DA255E3F6BB48BE7D30C09F2E
-:106960008FEB1FF060F4CFBE38395FC845BAD785CA
-:10697000BE03FE9B88CFB17DBBCD9F32D2F09DC8B8
-:10698000BFE5E3AF14E3C3BC53D1CFF75E9E719F65
-:106990002BCBF66EB9C0DA999ECF92C981ED1B89D7
-:1069A000BF3E39CAE5CCB2C8CC2A7ADF6E8BE6E3AB
-:1069B000FBC8BE590AC909B04312ADF3ED36B1CEDA
-:1069C0008DEF619E56458FDF67F9F93DC92FF3EFD3
-:1069D00087F6BA751DE71F7BFC79717CBDCAFC8DFB
-:1069E00005267B4E966639F1B0494EC8EFD90F7334
-:1069F000139E8F88CB8730E16F892DF26F3FC07572
-:106A0000FDAA83CE452E79C246F7FB7CF8F8FE97A7
-:106A1000BF0EFCFFE14EB99E8DF2D7BC9E1B9EBC03
-:106A20009E255ACF1FE60458C2F50CCF13AEE71CC3
-:106A30007EDEE0FF96FC5D9044FEBED0AFA7DD7128
-:106A400015543FF8C9E222DA9F99F02BF16A96A714
-:106A500037A3B190DB539EC29FA34C874F8947C990
-:106A6000A78BFE63298DD3CDCF925F253F77F3AB04
-:106A7000196E233ECDEF37E2DEA93C4E7FDB1AD8FC
-:106A80009763BCF61995F2F33AB5AEF42C18779DDE
-:106A9000C8EFE9F4887A26AF77E5DAD7A33C91CF3F
-:106AA000BB5278BE4367A02B3D53B71F786BAF9A9C
-:106AB0008EE7013A2289F332286303FD2049F2363A
-:106AC000E4B9DFCE54EEEFEB4CE57EBEC9AA6B60B5
-:106AD00008F777AD3CBE34B7F9C674DCDF77EE1D3E
-:106AE0003CA31AF70387549E7314F65B0B00BFF5A3
-:106AF0001C74768A85BF3F1EEDF7BD8BA7623F737E
-:106B00003719F132DFB5DD8EFD9C65ABA89C7FBFE8
-:106B10002DCE27F0DF22CCD7423EFFA1E9F9DE6B74
-:106B200089AF1699F82A887C95E03C4966A158AF50
-:106B3000A5AC94EFB7457C4CC8BDC9EA8819D59877
-:106B40004F79909FF738BD5765EB11DEC745BC2CD8
-:106B50009C4BFCBA0CF85BEF37FD08F96E58723DA0
-:106B6000FFD1CF8F8FB9139A2CF9C51F473E0CE583
-:106B700047BF78F592FFC2FA2F5F19F847D6B3FDE9
-:106B8000C467FF7A0BE5753EEBA07B4D3B9FFDD5BF
-:106B9000C03BB1FEB483EE17ED5CC3F7D9E167DD0E
-:106BA000A4FF3B07707BB1E59973233B487FF17BE2
-:106BB00083C717F27B2A4EEFFDDB1B0AE6F3ED05D8
-:106BC000A8503E8AFD5BE3D329B44FEF7CE69C617D
-:106BD0007FFACFC2B34C9CBBEA74B36A3C27DD9901
-:106BE000C9CFA936FED7B81FE1B9CBA5BBF7D9EB02
-:106BF000E1FDC4FFF3F94894439D4F72BB03ECE100
-:106C0000ADCCC7D8570A37DF6B03FA7D8C3622AC80
-:106C1000998EC217A7E179929E78E178E8043C202A
-:106C20005C809706949FC9F0714B213F07F3AF87B3
-:106C30008F3FDF82E32FD93B96EE198EE345F1F3C8
-:106C4000E76ECAF700F8F9F367CF8D443BEA42F0EC
-:106C5000AEFA5F06EF0FFEC5F97D5021D74766BE3D
-:106C6000EFC9D7BFBC8DEA3F75FB68BE7D5CEF4FB7
-:106C7000FF2FA3F7B1FF6FE97D48D0DBEDC1B84C22
-:106C8000E7339F0F641701F7B97F593AF70E77B7CB
-:106C9000DD63F13947C3FC5E6391EB2B95E4F9A307
-:106CA00043FA2B721F44FB0C790FF7F49CF96447ED
-:106CB0004CF7737F4C0B2B3B88E7ECC27E95E217B9
-:106CC00094BC0378689F551AA13C316B78E8F73182
-:106CD0006FEC86A53E7E5F9971FF353DAFAA0AED48
-:106CE000B923CD302F6877C46DF1B4000833FC2A86
-:106CF000D97F5092DDF78709D7521ECA8C0AE33E2E
-:106D0000E4EBA6FDC48DD5C6F737B06DB998EF7723
-:106D100043838DF293AE37B5B7F4F7105E6E644DD2
-:106D2000EBB83FE7E2F034AB3FDF8FF5C443EF78D9
-:106D3000EB8127B1DFA4DC21AD27DE1C41BEFF744F
-:106D4000C00B616F89BCBC157DC22713FB5287182D
-:106D50005AE2D7E1E7F78EEAFA25BC48BC5F2CBEC1
-:106D6000259DCC7897F8957833D361189EF7CC8D14
-:106D7000E33F5E1AEFD566C26E9CDE6D37BA088FB0
-:106D8000BFDBCECF4BFCAEA27E5329D61FE7F7C1A7
-:106D90009F1D3F8A3901DE2336B687E2427EBFE679
-:106DA0001913CF9F512A7E45F109CC5FD4EF57319B
-:106DB0007F510F17E62FEAEB98BFA86F8FF98BFA78
-:106DC000F798BFA87F8FF98BFA3AE62FEADB63FECC
-:106DD000A2BE8EF98BFAF698BFA8AF63FEA2BE3DA5
-:106DE000E62FEADF63FEA2FE3DE62FEAEB98BFA89E
-:106DF0006F8FF98BFAF798BFA87F8FF98BFA3AE675
-:106E00002FEADB63DEA2FE3DE62DEADF639EA2BE33
-:106E10008EF989FAF65F8E3D67A857B2DF18DA4F10
-:106E200074BE64A84FF6FCD1D0FE2BDE1386F7D7D4
-:106E3000681F1ADE4BFA5F5B72C6F01C631FE131FC
-:106E4000B88FE17FA6F9FE66E8C7CA021427B5B37A
-:106E5000262A9DE8EF853295EDA4D205CB1CCBF711
-:106E600087057FDA1FF9756B783D32D79171E70698
-:106E7000A2FCFFDDF8EBB85F42C41766E03F356067
-:106E8000E2B4CFFAE33E57C64FD3632A8B8E023E5D
-:106E90008C29547A62692C9A0D7C184BA1322B965E
-:106EA0004DCFB3639954E6C40AE9796EAC80CABC8D
-:106EB000D8602AF363C5547A63975159101B4E6505
-:106EC000BFD828FAAE30564A65FFD855F47C406CDE
-:106ED0001C95036313E97951AC924A2D762D95C523
-:106EE000B16BA81C14BB8EDA0D8ECDA472486C3623
-:106EF0003D1F1ABB89CA4B62F5540E8BD5525912ED
-:106F00005B4CE5F0D8422A2F8DDD4ADF5D165B4EE3
-:106F1000E588D89DF4FCF2D81D548E8CB550794587
-:106F2000AC994A5FEC1E6A571ADB486559EC3E7A09
-:106F30003E2AB699CAD1B187E97979EC212AC7C42A
-:106F40007E44E5D8581B9515B1FFA0725CECC75480
-:106F50005E197B8ABEBB2AB68BCAF1B1FFA2E75786
-:106F6000C7FE93CA2FC5F6D3F32FC7F651E98FFD9D
-:106F7000869E57C60E513921F6123D9F187B91CA45
-:106F800049B13FD2F3C9B157A99C123B41E55762C1
-:106F90006F515915FB90CA6B62EF53F9D5D819FAA6
-:106FA000EEDAD89FA99C1AFB1B3D9F16FB2B95DDA3
-:106FB000FBFFF1497F57C0721EF7CFAEAC3EDD57E5
-:106FC000B6392D9DE4E2F4555C2E3E98F6F101921F
-:106FD00093E31C9A8384DF1643BC8B7E4402F67DC8
-:106FE000FBC6BDD71FED9DF595275EBF15F5D97280
-:106FF0000713FACC24773F73097F27C37CC49B0512
-:107000005FFFAE627F2EDA51EBCB3A96A0DFE4DE73
-:10701000E28E1A2C0B07703D9925CA8201C2CF5A05
-:10702000C2F56FCDF2A1FCF70572FA065FB5D0DBB1
-:10703000B2BD5224EAAEAE81745EAF8FFDF4B5DD11
-:1070400085F2B03EEF1FBC62406E6FE707FBDC4F7E
-:10705000C517D44FE580047961E67EDE14746F1B9A
-:1070600010988CED99D53F12DF4F5853A0E2EFAA4C
-:10707000D46E523CC82FF56B4BA7205DCB989FFC7C
-:10708000923727C9275B2CE85AD76463E89FACD3B3
-:1070900018F987EB76F33C64F4A74E037E6910FC85
-:1070A000B274E39FC9EFD4D0B480E73D45B87F4ABE
-:1070B000FE8ECDE2D6B617D0AD77961DA6FCF8C5EC
-:1070C0003B8CFEAB46E19F5ABAD3F4BCE92B09FDD9
-:1070D0009E66BFD4DC01C2DFE9E3794F4CED4F700F
-:1070E0009F05B8319F24789BDB897A03F0417118A2
-:1070F0008907E9F794F8603DCF5D50FEEAE98343E4
-:10710000294FEEB4A6E563BB603AFF3D2BC51A1CC0
-:107110008BCF018F94CFD2D59C46F9506F811ED072
-:1071200030F1CA131C8BF7C775BC368089FB2B8DD9
-:10713000F108E726CA13AF8539605E4AED63D9745A
-:107140006E13FA1BB907FD9A8FD9281F29CC5678E0
-:107150005945CF7845609D8DF8A26E4F26CF4F0BD5
-:10716000FB8FE2B9024997B7D60E9E82794D751B07
-:107170008A4BC95DB7C746F6A18CCB4A7AF5CCDFFE
-:10718000E6F9028D2CB21E5397805E2713D2AB75A1
-:107190001FD115E8763209DD4EF646B7874D7443A8
-:1071A0003FF58DF8725536ADE79A35D1A14D3AFECF
-:1071B00034FBFFD9DC2BE9DE1399FF5CD54FFECE03
-:1071C000982F0FE97B665339D1CD4CAFAABFD713A7
-:1071D0005DD86B6EBA77F8E6C16CCED7E0F91CE1EA
-:1071E000F7BCB9E51AB2BF770B39F7BBD598FBC925
-:1071F000D88BAB9DCC0FC6F74BAB3D54FFC36A2F6A
-:10720000D55F59AD51F9EAEA122A4FDA795E915CFD
-:107210005FC00894DFF7B458574F0F90FBB2955EEC
-:10722000F47357FDFDA5720B89BE37A64F1E40763D
-:10723000BB215FA47A96311FA4C326F2CD362A3E25
-:10724000BC4FA62E7095A13D2B1915AFA3FE11F9C9
-:107250002B751B32E91EBB9BA6661BDADFB0A1D0E3
-:1072600050FFFD008DE09E5935D8F0FCEB359719A5
-:10727000EAB5E2F723985641EB46C6BF407373BAAE
-:107280007878DB4F9AC6E6DF0EE37F72D846EFCD03
-:10729000F438690FD37E3EBCCDE1C3F8DE293CFF54
-:1072A00006F5537F5029BFE8948D853D20E24F2994
-:1072B0006C2D96CCCAD7D5D9637C5D55FD5D65B87C
-:1072C0008F673F71507CB07E8BC2C27837431760A6
-:1072D0001EC65DF96307C13D778BCA8274BE4ADB67
-:1072E0008971F2958F0DF3617CF4E6C1D10178DEEE
-:1072F000B0EBE7293E3CF755DFC1BF3F05FBF34C40
-:10730000CC8F52CA281EF1A769ADF32D986FA71E26
-:10731000CEC5F5FAA727F9EF9A2D5CFE87311EC07E
-:10732000F3A21776BE5C01E39C6C5569DC0F7738DD
-:10733000DA545AF7FE7CBCDF360E7784FC14D7F69D
-:107340000BFC0DE5F507F3232349FEACE2FEF19EAD
-:10735000F8017891DEC8AF3A7916D76F3CFE064245
-:10736000A800E544BDCD4771D9939B6C142F047DD3
-:1073700040F906275BB32D5C0E3D497C5767D5EC81
-:10738000FA71EB36A97EFEFB189A1DE7CB36AB41AE
-:107390003616EB3C3F22BC4109F2F88F91BEB72E66
-:1073A0001F4BE7A2CD795CB2FC18D6545017575A40
-:1073B000F40C8FFFB2D11D567D9EBBF4CFB060851B
-:1073C000E13EA325831EFCCE78284FFBF9D58B67C1
-:1073D000B7BB494E7E64796ECCED507E382DFCAE45
-:1073E00015E8F2A21A1C3610F3862C9BB62A145705
-:1073F00039F11D8CFB7FF084CD47CB50E48D2DFA05
-:10740000C9428A4F25B7179897C7AFA3798A176FD4
-:107410002766942F329BED14FE8508CF33C04900B8
-:107420007E3C4B785CEC44B9FB6E3C3F5C6F3A6F42
-:107430007C429CB3B872A062D0D7770CE472A0DE15
-:10744000C2D7277B96DF43297F2F4ECA71296FA5AC
-:10745000BCFEEA409EC722E52C633B49BECC17F731
-:10746000252FD9E1E0E78B34E6413C2EE4646277D6
-:107470000DE4EB7A91FD89EF235B2F60EDA4F73EDD
-:10748000B045E6B717E3F76D6BB3E87B9B2F82EB54
-:1074900038227F8FCE4A726401E3F35CDAAA44A2F9
-:1074A0003A7F87FC7D12867A4227777AE805933EF9
-:1074B0009827F4DF3C66CA376A35EAA9409A9BE010
-:1074C0005AD42AF2B0BBE7A5B2F318EF0A465E9889
-:1074D0004EF3567C9104F358C0BAA2782FF2D2C76B
-:1074E000F93926F3BCCC70F4759EF37D3327E1FDAA
-:1074F000CADDE39AE62DF1CDF060958E0E12EFF322
-:10750000C31C9FF3F72A44AF7784BD25CF079AE9C0
-:10751000BF8005A6A39C5B703FEC338BE3FC20F996
-:1075200060E1AE089D07FC90B5A6BB603D2CD9B2CA
-:10753000EB8671F0FD821FBE68477EAFC98A0EB52B
-:1075400064C2FE333CE9BB555727D0FB263DFF45BF
-:10755000E18909BF157D077899B75DA53C0A5D3BB8
-:10756000914710267C3584F9EF09361C557D2DF0A6
-:10757000B4017FE6A8ECE2E72BF1F63F3D6FB35D87
-:10758000F38B81BDDB356679D3C3AE31E9533CCF94
-:1075900081FAB32B97E7A77F62F56764919C36C9A0
-:1075A000E1DC32BA8F55CAE1F9420FCA71E6A1FE99
-:1075B00083FABB5B9E4A477FC63BF73F9547F91A64
-:1075C000A86F46C4F5CD6DF57CBCDB7E9942F952BF
-:1075D0007F9AD63E12EDC19A477E95AEBFEFF54F2A
-:1075E00005C1A30371BE423F2E55DB06E2EF1A4AE6
-:1075F000397BC17D5B3238DD1780D36D84B30EE1FA
-:10760000D49D53A91770BEBD81C377621387776E6F
-:107610000F38C31457B9ED470E5F98EC8E28E9F583
-:1076200053BB5486FBAC6EBBC364079C65AD5B115A
-:107630001F4B57BCF28615F862E125801FE0839A44
-:10764000CD0ED2FB0B7FCEE3A91F2895F914D03FB6
-:10765000104DBF039E2F027B01ED8DF83CBAED80EB
-:10766000CF108FDD76401FF1B74CF8B596EDFD15C4
-:10767000FD8E96E2E7F998CBE4BD367B4CF7DA68ED
-:107680002803F8397F27D2A9BFF93E2EEE9FFDCB04
-:10769000D03FDFB282F8BFEB12FD39B6C6D4A80DD9
-:1076A000F390BB762964272D5D59995EC9F07C1B48
-:1076B000F7AB151471FDA6F8FD945FE300BAA6C2FE
-:1076C00078FD8B34FE5CF3F07CF31F32BA4747CE73
-:1076D000D7FC1CFDED4ED4872E0BE94333FCD716A7
-:1076E00071BDB954B5907DBDC4CEEDEC4E717FC572
-:1076F00070318FE145FC9CC315C2AFD0897625C699
-:10770000BBAF76D0EF18313689FCEE56C6F9CF2ADA
-:10771000F1E6B17EDCBDBEC97EEEEA8F78BA85B5F2
-:10772000D3EF224EAF98A9E1798637F29C744F14BB
-:10773000FC09603FB3453F476CFCFCC21B3806C0E8
-:10774000355BF8A7DFC0EB5161FC370AEC64D786E4
-:107750009F7190DD70572AF71FB29C0C2BAE87AF3C
-:107760000B3975F378871FE5FAECF17705B084FEE5
-:10777000C20CF055E3EC5A570AE3345BB8BE6FCE47
-:1077800062DC2FB0B6A31CF1770598C998BF0FD063
-:10779000EF3E9FDD1B1F19CF4F2C413FC3958C330C
-:1077A0005805E1D7505F62E7EF6B1FDD31E3FEF173
-:1077B000B04FC0AC29D4338823E48BDA0CDAFFCE87
-:1077C000C0F30559585A89DFBE6665610B2F37B87B
-:1077D000E85E25AFE17761AFAF60D10C802F7AC84A
-:1077E00078BEE3C6A8253A0CE345D6E83EC49FC55B
-:1077F000A9D93C304EA04A2943BC2F59D3B7F9AE82
-:107800007CF4A919F7F7873ADEE785F3BC43A17C3E
-:10781000A1D9B0E8914F6FB1B2036A19A71FF26105
-:10782000639616A676CB399FCB7325922EA5D0BD35
-:107830001EBFB3C5FCA09F0DE9F8BD3DB15F252C6F
-:10784000F852DA6B8BC5BA5D2CF9EE71E37ADD265E
-:10785000D70DDA8780B7D9A24CC6F78F8A75F16841
-:1078600011DF67DE5324F7997D1B6FA9834509EE6D
-:10787000671C444739EE0C513E523488FA93F3901A
-:10788000FC3B9F35513ECF7CE1A7B18024A1FCE0B9
-:10789000D61F71BF9029EF080C25CA6F5BB4DDFCC1
-:1078A0005CE7E7510D7289FCA68ABD6B2ECE4FF9BD
-:1078B000528A0FF97DB67D27F907CCED6CF8FBA94C
-:1078C0001877DB00769522E26550776C52E8772FC7
-:1078D00066F7EFBA1CF53948EB29742E54D8DBF360
-:1078E000057D1DE27EABF9685F615C0DED2BC4D7B1
-:1078F000166E575A853D5CB7C9686FCC5EABB33B1B
-:107900007961B81FC061CA53B709BBE34D7BD7E5A6
-:1079100028F7CDF705BC69E17084F318BF573387AA
-:10792000BFB70AFB52F2D5CF8A6C86789B3C775A58
-:1079300083F28ADFDB60CAD372D1FD31350ABFBF63
-:1079400053FA215F17E569B043E9BE9CE369140768
-:1079500037FB273B2BDD618BCE4F7973C66DD3117F
-:107960003F35E9762B96AF77DF2BD641E31FF70C37
-:1079700022FB677DE5A82D989FF4DEA36766380794
-:107980005034459C9F8AFD0EF3E9677D06F050FD5B
-:10799000AF33FCB08FEA7CBEEB162788EECF8B3E70
-:1079A0009D61053DDFF940D756AC67686A80EAF70C
-:1079B000760DC43B9733220E5E6F96FD3902D85F79
-:1079C000E743BCFED1A38E4018ED5F716EA9E64A75
-:1079D00085E4AF0BD75779DCCF5463798E9713F8D2
-:1079E000EFA25CA89D570BB88ACAF13ED493F4FB72
-:1079F0000B8307F95D45807FCFC0E0392C17CD544C
-:107A0000C2763CEF7F347289D06B097F27C425D6BC
-:107A10006B617180BE977E74E88769E53DFBF96F05
-:107A20008E8B3EA000800000000000001F8B08002D
-:107A300000000000000BE57D0978545596F07DF5B7
-:107A40006A4B52498A244042162A090901031490BC
-:107A50004080A04512202C810A28A2A0168B10106D
-:107A60004840EDA65B7AAAC226E216D4B1691B9DF6
-:107A700012D1C66EB5A3B204D92A6C823A5228DA62
-:107A8000A8A041504163774418E30CB6FF39E7DE04
-:107A900097AAFBA8B0F4F4CC37DFF7878FEFE6BCEA
-:107AA0007BDF5DCE7ECEBDF7651C63AE7A1B633F88
-:107AB000E3CF0DA1D2D6D5C05821632F3ADCB6AEA4
-:107AC000504E5D9813EFC967CC9EE18972003CB7B8
-:107AD00052F199FB30C68EFA73DDB18C8DBB423FFB
-:107AE000BFC8BCA49F847FA49F8F74FDDCAEC0BBC5
-:107AF00083E03F733AF0FD3BB25DBD1D1D19BBEB4A
-:107B00005F9807FB6165430C6C0063775B19FD7C34
-:107B10005FB335D75A00E54B96449609ED5ED9968A
-:107B2000310BFA618BE1A514C6BE69FCC8EC807EFE
-:107B300016B4AACC95C85875AB42E5824D8DE611B6
-:107B4000D0AE1ACAD2B0F9CD13F365ACC93821361C
-:107B5000F4BCBF83CF97B1358CE17C5E396BF440C8
-:107B6000BBBB0CF55F3E95048F072BCEE71D97AE90
-:107B70003355BCF72963E5F5F997D60F722854FF02
-:107B8000588EAB08D7D905FA405835F0F5EADB2F07
-:107B900015FD4D8D6677B8A17EC68058AB03F05DAC
-:107BA00078D4B32C16E6316B5D663F15FAE89F5129
-:107BB0005282FDB19983257C9577612C88EB33B691
-:107BC0007462507EBFA3309EC1BCA62604EF617DC7
-:107BD00019FB8DBF7B9D752863637E0B6DBAD02B1F
-:107BE0002E06EF965B04ECBBDE5D560CF0DF558293
-:107BF0003D8EA23A1FBC7F10E703E56D037B45B3C2
-:107C0000DE80BDCC18833D9EB192F469BF41BEB801
-:107C10006DE0D011F87C982536771AE197117F94A2
-:107C2000A4BB27633DB667B00E8F39D0F166588785
-:107C3000E72DD5E98375787AC778FC11F03649E0ED
-:107C4000E1370E3B95070D30CF7EA17968E30367DE
-:107C5000DE1384FE4E2F4DE9BB1AFA7B367DD81217
-:107C6000C28B18FFD974CF9CF0F161B9BDF1F9D581
-:107C7000CE639698C71241377731F099C0F5CFF0AF
-:107C80007F42598C04DF383691B9F242F0A41B537D
-:107C90002578F2D46CA9FDAD33AF93EA2B2CC182C9
-:107CA0001A5B88BFF5F3D14A2014F16975ECC63828
-:107CB00006533CB1E3C28753404EFEB641752A30AD
-:107CC000D7393B9FFF7008B43A070B4E04BC9D7335
-:107CD0000100EB3DB749F5FB32913F5CC68A4E8C03
-:107CE000556157D07EFEA1D7CDC3E0D7AA9AD963FC
-:107CF000918E73FCA6CF9BC2E679815D34B32C9044
-:107D0000878DF2F36AF6D0776A6F840266772FE880
-:107D1000A75E575F33F22B1687ED8C9F3769EB8494
-:107D2000F1171FCF7C645FD8BA9F76C4267D791D7A
-:107D3000FCD28FF5FB59C5F19A0FC00A596943234C
-:107D4000D169D921D5892CBA2C5D610AAC73E4269E
-:107D50008B3F0A44EBDB6D27CD0EC0D70F5EC723E8
-:107D6000FB4C28FFB58C25E27B27CD4DF07CA8C3CA
-:107D700041785AB0E33B3303BA8FDCB190E47A0424
-:107D8000E8B178E09F6023EBB509FAF765C63A9F42
-:107D900087FEEF5A350A848BB1F8D62954CEAB1B37
-:107DA00045FDCD6F9D48F082D618820F46074730BB
-:107DB00098C7C12D1DD83298C7613590FB7BECC7A1
-:107DC000124B7AA222F5B6A5B8EE83D1BEFCBB61F8
-:107DD000BC8A3F8F2C47BC2ED8A4B890CF2A5476AB
-:107DE0005049C0F946517F15EA7B050BE1F998D25D
-:107DF000589F219EEA19837A7540EC6A06B06A069C
-:107E00007D11813F0F09FD626AE2F31EDE5A49FDD2
-:107E100069F5871D59B47E0D3675DC609C6E0BAD1F
-:107E2000C7D4A45039BAF53A2AAB37551A1D30CE0B
-:107E30005B79CF25219EA0BDCD13512F0F8C6711EB
-:107E4000F497565A843E9E82FA18FA3D90E5FA025B
-:107E5000E572DC9226A315F5A9CD6A7F1EF8605C59
-:107E6000515FC7ACB075A97B6E610EE0234B528B9E
-:107E7000C905FD4F81325C7FDFD18EBDF9A64D7FF4
-:107E8000D752A9D925E65CC218F0F9ED763E6F4DC0
-:107E9000AE8E89F6DAFB4185CB876FB3C5FF3CFC1C
-:107EA000FE5996E7279C6F70189BFC1AE9D3604631
-:107EB00065EC3F6FFE405F2BD23FCED8C412E07D11
-:107EC00043A6367F2ED7579A7F8B98FF61952D4614
-:107ED000BE387CC30D4117CCABF1BEFEFDD13E6870
-:107EE000E325669AA93F666FB988FC5ABD2BC6B1D7
-:107EF0001AD65701B441B865A7C5BF3E939E332536
-:107F0000094BCB7A05EAABE35A72D1FE94EE8E0AA6
-:107F100020DF36EE8E32A21D7933C79398D9119F98
-:107F2000772F5380BF5D3B2C46E48364872B29B3B6
-:107F3000B0FDF95E498F69F2A8E733CF2A2E7F1E84
-:107F40002187D304DF4E177238CDE88CFF25CCFB98
-:107F50008E7754867A7CFA12A5D7A602D469B1CE60
-:107F60009C3039D4E4CD847CD91FF993F3E5BCD699
-:107F70000E42BE3345BF5C0E2AC040237E2AAEEBC4
-:107F8000E047F95ED09A48ED3479D5E4343DDB53CF
-:107F90008AEBAE5806F20DE37896A614A0BC84F8DE
-:107FA000C46C477E023E499E15C607CB1A7F342219
-:107FB0009F988A15E2130B94A5617CE46EF353EC51
-:107FC000233AC13CC62DCF34AC66A1FA72E4978E39
-:107FD00057CFEF85A2FD745B20C700FD996AA29C74
-:107FE0004B615EE7921CA4C7163D0000A06091C9DA
-:107FF0005D8A7EC6A2DF294ED4BFE87FA0FE19703D
-:10800000ACC6EC099BDF2DADBD9903F034B1B51BB7
-:1080100095FD333C93100FD35A27093CF6A69239AD
-:108020008A0C389F7BACDCCE9CAFB9FF761CEFBCD2
-:10803000DFE2C4F1182BE2F416F32D74393BFF1282
-:10804000E7F78E893D0BEDCF44795494CB33E9CCDF
-:10805000FE384C71C65AA033F47BC6C47C76A0E7C8
-:108060004C803D087760AE0EFD50EE609D6176E578
-:1080700082B12E8365037D17FDE55323A8C239B96C
-:10808000C1DE011877EA306EFF9B3798C8FECF6BD0
-:108090007C6F8001EABFCE747566A07BC774F1D493
-:1080A000E07AE64EF0BF6202F8AE875F8F1BE4080D
-:1080B000E1B3DE18C831C2FBF580471FCCABFE210F
-:1080C000B5DCCFFD9E98CA5E57E6EBB9ADD9841FEB
-:1080D000CDDE68FA7BAB37191611D2E357B2431ADB
-:1080E0007FCF1772301FE58085DB9B4AF730E4C3F2
-:1080F0003CC599C3C2ED0D97074D4F03BF93DC54A8
-:1081000064A73B97B190DED6DBA3BD6AFDE3836134
-:10811000BDCBB33CEB510F94FCE9BF5EFF18AAE660
-:10812000BDF66219D269D8750A5395ABD1933F9ABF
-:10813000484F2EA964A427A10CD793A676FCF43F40
-:10814000645E9B9EFF57C1F7E0DF92DF887A3CBCFC
-:10815000BFCFB24AB6219D77652A5CEFFE93E6ADAC
-:10816000D7EFBBDAE4F5EAF4FB4BA2FD95F4FB1183
-:10817000D4EF8597EA7306FDA13EFFDBCE1E7ED4C9
-:10818000F79F32D0FF68DF76C4389E17FA9EEC4125
-:1081900074BCFF72FAFEB19C1947103F11F4FD7BCD
-:1081A000FF0C7DAFF1975E1EF472A0E7FB310F82EA
-:1081B000FF8574DAAA30D4AF217F8B111F1FCCE268
-:1081C0007CACC94D98FF45761EE4C19F9379A95CAC
-:1081D0007E5FF3970207C69B05B17D9912E2774D4A
-:1081E0005E347ED7DB9139591E35AB302427F35EE0
-:1081F000D3DB81F6F8699B09E357D3BCEFB81D8048
-:1082000032DC0EB4E7EF58B3AE4D0EFEE32AF92987
-:1082100035EB7F9C9F52B322F3535A56C77F9C9FE6
-:108220002E4347B2331A9F8D799BF307CBE6FE3E70
-:10823000F00BCDFBA039DDBF2C13F51ED787637E75
-:10824000663588CF3B443E41E3D711D91E17CE5344
-:10825000A333FAF7E8B75FAD5F3825A986B9E0F92F
-:108260001D5086EB0D0BD22F827F3FFC1AE9DC3FBD
-:10827000EBEAE83C49D0F99FE8174ECB8AE0173289
-:1082800017B7FF21BA582622DF7C1F303294AFF691
-:10829000E86A5ACBF1AEC12B0246CDBE26A27D05BF
-:1082A0007E99FEDFE1978AD2FAF35670FD7CEB8B64
-:1082B0002B8D83001F454CE43F86AE717543FD0254
-:1082C000BF0FA61E293F725815B0EFFA2365308FF5
-:1082D000318FB7D5FBB07E78717C5B3E054309AD2D
-:1082E000BD77FD90230FD1BCEB38BE3D4D4677AF37
-:1082F00030B800E0D830B84807AFE3EDD18ED8A948
-:108300001F3F974FE85FE987B0D69F9003D632A210
-:1083100003FA8B9B143BE6436E2DFE9B19E95351E8
-:10832000DA742015D6FBF8FAE195B61EF01CF5209C
-:10833000CCF7B9F5156B7C46F17E27CA8FD18FA596
-:108340005E71A940A779458A3F2BF3523C3E9725A1
-:10835000DB33FC31CAEF3373C1B5BD8FF24BEF672E
-:10836000D1FB01CB358C7F733173F923E8C957B545
-:10837000761701D6FA07DC4DACE771B8BEFD3621A1
-:108380006F4183613E037C35AE9FB606F365C3192A
-:10839000E78FBDEB3D95980F2342EBD67BB9F9FEF5
-:1083A000214B8EEFF0C721BF1FB81CBE5EBEE47D1F
-:1083B000C11F5532BFC41BDDFBBE8779C427297698
-:1083C000F46B17B8A31E42FFBDA254E3EFBB2A5DB6
-:1083D000C5B0BE2826E5FF42FC3DAF12F97B01D3B4
-:1083E000DA2F588376C96D686BCFF97D87D2F67E18
-:1083F0001EF00FA5E2E0FD13EBE7AFF1D9881E54A4
-:108400004F70B7CBF07BBD0E2ED6C987E06F924F71
-:10841000D4DB809F9C087AE33F059DBF55D864D488
-:108420007BC112EEEF05B378D9259BFB77866CDE16
-:108430002E3A5BD0393A0C0F69213AC34F00E388DA
-:10844000B075139E6E49D2D6FD70E55858573081ED
-:10845000F552804F92B21F58B33C8C4F3A653F5C47
-:10846000897808F5F7E011D4FBB7083C75C97EE8B8
-:10847000888FEB3305E56E3E3104F0C126C5A7C2F7
-:108480003AE7231F4458E7E94BE5C6A77BDF65BA07
-:10849000CCFB5F5FCA872EDDFBCC94742DEF0B3ACB
-:1084A0008DD5D1B15C47C7321D3C5583FD923ED37B
-:1084B000F4DCF486352B3A2561BE51413381FADA7A
-:1084C000ACF465ACCF734F56DA0621BF3A4CA9A085
-:1084D000F3FB3FB7F6881578B912F519F1EFEFD62F
-:1084E000B8801F27A2BC13FC54A5AB0FF24FCD8A56
-:1084F00064683FE8B9DFAFB142D35B97AF31A14FBA
-:1085000033F4B9A7D718817EB714FCF900F667AC2D
-:10851000FDB72363332FC3AF75BA75ACD3C13E5DCE
-:10852000FB27AEA0DF97EBDE5FA2AB7F4807AFD59E
-:10853000C1ABE4F7A7CD54484EA601FD1071579288
-:108540009B89D96D79A4367BA6D8C84F92F87ECC8A
-:10855000320EDFF6DCCB95ABF2C3E0EC3F5786F38F
-:10856000B189F19F2949CC87F6C3D48E3E1B93DD98
-:108570000E1FE5E9ED1DAFFF0C7F4DA17D16C92E45
-:10858000EF5565B851D5E6BDF3C83D367CA8C13B73
-:108590002AD11F6F77DF83BD5189FB1E631E15B083
-:1085A0006F5B25EA3D6D9D5AFB113FFDACE278778C
-:1085B000676FABDC80FB2A25811CCCD74F4DE025B3
-:1085C000D81915ED58B5C8778CD8A9BAD1CE4C8D2D
-:1085D0000EE42CCA0F5B27ABCFC57536DEA7127D24
-:1085E0007CCB783C329D39CD98AF688C8F5FFC0294
-:1085F000B4DF7B9FBA18EDDAA78B133BE1FCF7657C
-:1086000073BF6D6F7CD74E7702DC18738719F3B593
-:108610008DF70FA7728FEA5AD9027CBCE6B9836442
-:10862000E71B63E2093F0F67EFABAC05B9A8CB7658
-:10863000D0FB9E047BA706F457579B18E6ABC1916D
-:108640007A86F8E6614BDFD5308F69B5D7D1FED198
-:10865000F47FAD1C9102EDA6AF30D1BE02FCF4C692
-:10866000797B560F3763FDCCE5A2F48DA472F7DF5A
-:108670005F7FBB37B46F794075AE87C6BB5AB3E234
-:10868000A6C3BC4E45713DFC7973B7389C678F6EAD
-:108690009E75D9C8AF71B1D10A1A0FBB236E02F40F
-:1086A0009B9BE37A3ABB63A8FDEEBFABB40FB6BDAC
-:1086B000797A27CC3FFD41E8EF5DADD33B4D0FB359
-:1086C000F7B3BE35129E779B1DF7A07FB93B3A5D8D
-:1086D000C1BC0CE03911F3B633857F0DFCB2F8F55F
-:1086E0000876FF896C95F072DAB2989D02266E7C4E
-:1086F000B06331CE537B4FDB7F33A539FA85FBD195
-:108700001BBA96BC8EEB08F1D96747906FC88F06ED
-:1087100078D7739FACF1A12DDC0BFE3FCE23C9357A
-:1087200002EBD99244BE0F9A5C9F1B9E8F08F9A959
-:108730004B853EE0ED4EF862296E3DF152941FE309
-:108740009913BE4F62C3F3EF9A9CCC8E8BF5A13187
-:10875000FE2A36D68878FDD4E8FDF257B86FF8B413
-:1087600089F4E8ACA73B2E69417D00F4C47C907E7F
-:10877000DCE46E261AB7FDFDC1E6CAB2B430396139
-:10878000CD95AEFCF6E5E4D873DF546EB0B52F2777
-:10879000B385DF3EE269931BF97C7661AC11F7E9A2
-:1087A0004A9EDEFF3CF2E3EC8551FD2C30F1D94FBF
-:1087B0005B88BE4DB1B13E3BEE23C6C51A3B40F9C6
-:1087C000ADD0234DB55114A7A89DCCA4F7D4958561
-:1087D0000EC44FA9CA8C56B02B6A9CD3E1E6F07246
-:1087E000CC1BAE882D72207D3B76E3F2D0561F3F26
-:1087F00079B4D23BB46F7676F1E34F0E84F97DCD38
-:10880000FC930666FEF7F7D1AA993B1EF38FFF5340
-:10881000FB68E66EFA7DB4FCF89B91FD16AB346FF5
-:108820007569941FF1A966703B319229B48FC6EC2B
-:10883000B0FE5EA17D34F5D7FD093FA7BDC057DD71
-:10884000012F71566AAFFE5AF55B60DCD2449E6F11
-:10885000559FAC64B8AF0678F5D9011E995443FB17
-:108860006B4B859E99A630773DC9BF3303E3E4592E
-:108870004F47111D673F33E7C3DF1520DD2A92C242
-:10888000E52953F01FF4C7AC09A17EBEAAFD4D0631
-:10889000CEA7F4DF20BEC4B853F53C790BE9CD1860
-:1088A000DA6F63F6A6870722BFD4C6F4C53CF9EC9D
-:1088B000A75332B2F243EFCF5E7A5F2E7F1FE2D62C
-:1088C00038D45B51B49E799B2CC42FD31E505D6469
-:1088D00027D3CD64273F5F1E45F0BCB42292B76911
-:1088E00006BEFF063E6132E9778E7236CFC65CAFB8
-:1088F000DB50DF3F1454397D7C826E66A44F71B724
-:108900004492CB3B10C760BFA622BF75A4FE781E61
-:108910006A9742FB4D8CD538500F4C3528A4EFF4A4
-:108920007259D18DFBAFD3329CB7E37BF31FB138C3
-:108930009766F239A8DA7C206E9A6F08CEC27D481D
-:10894000B6C542F98D6A5847541C3FF7F01ACCBFA0
-:10895000DAC88C66CC4F39B85ED3E653EDA81C89D3
-:10896000FC0AF5C78C503F3F96EBE5F91D78DE8792
-:10897000C55AFDCF878F8773CEE6EF39E250DE060A
-:1089800011BFA0FC1BA0FE6F8CD797C615399AF2B9
-:1089900069FF7E15E64B703E3D7A878D0B704A6FFE
-:1089A000E4C785C6AC58A443E2A4C938DECB2AE9A3
-:1089B0002710AA478AD00F7C59ED8FF1ECB407F647
-:1089C0008E588BF0AB7DED388569AFBC4F76EA2EC3
-:1089D000C1674DE8FFA3DD02F85528EFEDC6F5832A
-:1089E00047E5F99C7BBB29D2BE9F563FFF0113D1BF
-:1089F00063FE0ACE0FF36BFF42FDCE8F0D76427AF7
-:108A0000CCDF6C1A807CFD2F62DED36BD38B8F01A1
-:108A10007F4C37C5DB157834CF576146785E9D4271
-:108A2000B036DEFC073EE864C8E7FD6169117C14DE
-:108A3000EAB76306DAB56F5E4ACC981646F76F96CA
-:108A40006F8DC37DED5351811C3BE663164639D7CC
-:108A5000939C727A7CB33C673DE66B66DA83B1B86F
-:108A60001F3EF39EEC04B4779FDA0366ACFFB43E7E
-:108A7000D380B0CB6E2F46D865EC43F037E29C0A2A
-:108A8000FD009D16289C6FE6BDB4D79C05E33D27ED
-:108A9000F8ECDB97DFCFC5BCC1FC8C602EDA61E05F
-:108AA000ABDC54A4CB1F15F21716BCA4BAA27A876C
-:108AB000F86A01F215C8FF5CC1570B366DFD25CA77
-:108AC000E902E4A77E97F225C497FBE8F96BCF8E05
-:108AD00060FCFD7DC8779ADD0778B909F36B660104
-:108AE000C338086F10FA1AEACB78BD2F9FEC096BD8
-:108AF00032A35F5CAD727F01E42919FD89EA069318
-:108B0000AF294C3F2EC0FAFC507D7B7CB3BF9BD875
-:108B10002FABB5905DDA2FF0D2F4C0E638E48B6F5E
-:108B20005FDE7B6030C659AF2976D4FB97C8A1C001
-:108B30005B35E2298ED649FE5135E2252E84A736D3
-:108B400079137C51CD381E34BC541B059EB47AF188
-:108B5000FE01C187F398C0EBA6EE5CDE857C03C7FF
-:108B6000901DD1D6E74990CF0FFC20F8FEA858E71A
-:108B70003CE01B673EF197CB3C40C4FF50F5EDABAA
-:108B8000CF52FE48A3A736EFF81C87A6A75D1D129B
-:108B900042746E32B0AA48F9EAAF85DC996C5CAFDA
-:108BA0009CAC4DBD7D31E06FEE4BAA939087B157E1
-:108BB000D8B81643532CF9A7BF56EDB8AED23F55DF
-:108BC0008EC6756B7C67DAA8181B709F907520FCA9
-:108BD0006BF32BEDEC1EDD81F35D00E7A3CDF3A479
-:108BE00012207AF95E55ECDCDF6D32631E5193532F
-:108BF000FD7C7F10F355E394C14A1F9C8FD381F213
-:108C0000CDC00ED27C6CC7EEA3F17C27EECBEC1D61
-:108C10001AE7535FAC11DB7DCAB81ED0F8F2A4C8C6
-:108C20004B9C5CB195FC616D9CD81CCE5761E37880
-:108C300016275D3A8ED6DE94C3E7A5C9C5C104CE1A
-:108C4000FFA5CBFF42ED343D8B3F988FD3F0A9E1D8
-:108C50002D4C2E25FC68F2A5C99346D77F54AED87B
-:108C6000928EE4B7DE2FD64D32D2296417903FD1D1
-:108C7000DE59CCFC1C5C98DD24BF6664DA77664F55
-:108C800084E71A9EF4CF4371953D03F13FD2964C91
-:108C9000FBE56C79F2BE6E61FED929CC7BA13E7DED
-:108CA00051F5933E65209561F65CF3DB6A178EB44F
-:108CB0000F43FE7A49A173479AFD869F87DAF8141D
-:108CC000FAAB2A58988BFEC4EA9C2C1ABF3AC97595
-:108CD00016DF9F77263822CE118A5F869E0FA8F175
-:108CE000981FDC9429C50FF39AF7919CCF67C19523
-:108CF00018EF4E7BE0FD8A8148FF174D747E616658
-:108D00005D26D9BFB31B66F4C7D076DA8A1C82E72A
-:108D10003C7F27871FE07EDDB415852F607EFE54E3
-:108D2000946B04F279CB1AC58EF1D790E70B97DCE0
-:108D30000AF54362BB76C0F99ED870AA6230C611AC
-:108D40008B55921BD786C72761BDAB4175E2126771
-:108D500032FB925B91CF8DF12477DAB9C66526CECE
-:108D60006F77E670BD715B0ED71BB709FE2D5DB640
-:108D70002C17CF15B43C0B760AF7D7CD8EFA00C668
-:108D8000813B3B3BD7C338D510B626033F9D51B836
-:108D90003F5E656656E4AF43A6E0BD38FF43F7C6C5
-:108DA000F6ADC509A81707A07CB844DC0571148D81
-:108DB000ABE14B1B7FA61857EB477BEF20FA5568BA
-:108DC00047C47CCF2E7F7112FA0B6737E624B03090
-:108DD000BC9FC57501BEE7807E7C2D423CB8304704
-:108DE000CB4FF8A9AC1279C443A6BA34DCCF05BF87
-:108DF000FE74B87FFED5B35156E44BF0EBE5E726A1
-:108E00006E57C09F979E83FC48705BBCA74E8DF742
-:108E100044D0475AA9F7F797E7D822FAFB9AFC5DA6
-:108E2000A2D7847FDF9677E9766DE7BA9ABD4018BE
-:108E300010886274CEE0FDB2989F5EC7F397B3EAE4
-:108E40002C760BE0F734CA17EE0B6E56B9BF68E507
-:108E5000F2767A675F3FE615661D67CE00C0B38E77
-:108E6000AA4E07B4DFB7E67E3ADF71E73A8575565A
-:108E7000C2E2AE27D64C42713BE7F4AC4C81F6E738
-:108E800036F2F328506DD3C55B07521CEDC75BFF6C
-:108E9000AC384BCB3FE9F1BF2907E2AD18F8C5C9A3
-:108EA0009C32FE79DCBE1BD8A8A8DFA5F86FF67A45
-:108EB00028AEFAABB78ACA41F5CF96A6C23AFEA64B
-:108EC0009C7C6408CA516C3CE54F9ABD35B439F8B6
-:108ED000D786FE17C7019EB6DBE2EDA83FFEEA5D2E
-:108EE0004CCFDBF846F0E9D04D8D6A2AA3F63B86DD
-:108EF00040FB5DB678DCEE88B00FC7E9AC3F7F730E
-:108F0000F7C2819DF1B9B6DEAF7FC5E9DD66C7372F
-:108F1000CE88437FB5F1F7893B06219D63E2EDC81A
-:108F20000AB3C5399C2FD7727D74C61AFF02E65169
-:108F3000CFAC9BD809E3C33B4D2D6627F4EBDC593E
-:108F40001987F9822F8C4D71762CA17D00E761F491
-:108F5000ABA807079733DA1F1C1C303247266DDD9C
-:108F600013FF0C6A36FA316EFE06F70DD18E5F8C58
-:108F7000E6FBF7623FF0CE6D3CCFD6965711F985F0
-:108F80002162BD1D7213B47D207A5E5AC49F7FB5E5
-:108F9000EEF571D8DFD90D263BCEF7AF1B4CD4FFD1
-:108FA0005C88EF0DC08F6736F2F3027377409C9CAC
-:108FB000897A4421FE9D0BFC6B45FE5B687299E348
-:108FC0002FE5CBD28D3CBE9E5BAF50BCADF1E75CD4
-:108FD000977F04E15DF0A915FEFD0CA6A303AB5F2E
-:108FE00089F8688F5FFFD17C803537723E40CF0FA4
-:108FF0001ADE34BE08F12923FED4E89F50DF7758EB
-:109000002ABDE0237CFA4A581EFA0BCBCC2C0FCF9A
-:1090100043F90CD14E94FB1FA2E27A631E6AB1950C
-:1090200097BF8C8E5B8FE50F51197E9CF70F06FB67
-:109030007E8CB3BCB999C4B7BF541D26057E9D98DC
-:10904000D4544666A0D4E032A01D5C66213DA2D770
-:109050004339B9220F98CBA81C96CBCF899B580DCA
-:10906000F9175A09FE403AFA2F95310917F0287975
-:10907000BF173A4FC4FDDECA2109F76683E739F806
-:1090800085F48946E0F3CAFE099BB3002ECE4DE37A
-:10909000709F844213C0B5B51913CBA0FD2DB92E16
-:1090A000676ED8385ABFF0BC3F3E1F99E219908BCB
-:1090B000F6DF6C5B8576E06F4ACB02831A6A7F44E9
-:1090C000619F6E574270938965A0BF3DAC6DFE9164
-:1090D000CB55B9AE1B72233C9FCED80ACC4B4CF774
-:1090E000BD794C217DC6DC56A0E778C17FD3ADB6F3
-:1090F00000E9B955A6E636FEC8423D156F44BA8F61
-:1091000013641F6F0C34E2FB3DD872FB9756721547
-:10911000D7FD9CD8BEFE0741655F6AFDC1FAFE66B9
-:1091200082F5025D1517D01A444C01244F057DA726
-:10913000EC78F347EC77998F3545111DA6DA910F3E
-:1091400015E631FC0CE5FC18E08B3E58023F40BBB5
-:10915000459BBFDD87623147F3B33C45E42FDE63B7
-:10916000E7EB619EC1C4AFF70A7EFDCACB6A3055FA
-:10917000343E188CC3A3B0CDE302B9A81FCA554F23
-:1091800015D2E1AB75CBD21601FF7CFB9AC539161F
-:10919000DA9FF1BF1E8776759EF0F7D945357003CB
-:1091A000D41FCCECB17E75187F2DCCE576BF39335A
-:1091B00090711FEA994C1EAFB28B7B33EE83F6E5BC
-:1091C00059A30A5713165C77E786ED4F8E33463E58
-:1091D000BF31298DFBEB6C03B7C71623F3C52650AF
-:1091E000C9E2004FA3602E45782E156095F6F3FD79
-:1091F000D41EDBC5A15FE39891CCF77B981BF59655
-:10920000465F8D6E97D013A68C7EBDC1CA4CB8DE6A
-:109210001E6C9D1DED9346D7AF843C7E65E572388C
-:109220005CB5919E5AB499E7F516295CDF2EDAA950
-:10923000F0FCE625F676F34AD4C955EB66903ED3AA
-:10924000F49803FE217FCDB5BBE3038E7FC0EEAE65
-:109250002BBD2A7DB65ED3677D595FE4BF2BF94BEA
-:109260009A1E03F2BC98DBF11AE885288375CF16A5
-:10927000731CAE4E7518112F1DAD4ED4E78B9ECECC
-:10928000263BC92EAE65E1EDD8BA44E2DF95992AB6
-:10929000D1B5A2219539E0D19C0685CEC98E6D4805
-:1092A0002438AE3585E08A3F742EC175B7ED83FE54
-:1092B000A13BC1675F78BBC0C3F33456ECDFCDB4CC
-:1092C00079E4D7A3FD39678379009EDDB65594779D
-:1092D00074B3B67848F9594118B806E5CE65F2710D
-:1092E000FA586B49FEC5BA1609B95A7488DBEB45C2
-:1092F000C3F87EA1D1D7231EE96F3AA8323FC03709
-:109300001D520B03D07499D0E79664037384D12D5A
-:10931000CA11CD1C61F4613E5710E3ADC9825FEE06
-:109320008FE27A3F262F416A37D9368BF82798315A
-:10933000E220AE37D6D945EA9779B87FACF1D5248B
-:1093400091371FC75A96A39DBC6932D487F5672A07
-:10935000FE8EEC86A958F6AB012FA72FC74FCD1A6A
-:109360003FF5603D889F74F801F9207B7FEE28BFB0
-:109370007F025EC96F8B019E74D0C4FC50BF42E077
-:1093800005FD568C7FCEB962496E34BE0BA2DD035B
-:109390003D175F24E3AD834BC65B62B98C9F8E6E35
-:1093A000191F9D276749F5299E9E527D6A553F09E1
-:1093B0004EAF192CB5EFBAB84482337DA3A5F6D9C8
-:1093C000AB2648704EDDAD52FBEE6BA74BF53DFC76
-:1093D00073A5FAEB362E92E05EF5BF96DAF7695880
-:1093E0002AD5F70DAC96EAFB1F7C4C820B834F49C4
-:1093F000ED071E5B2FD50F6AFAA3543FE4CC6B1226
-:109400003CB4E50DA9FD0DAD7B2478187B5B6A5F4C
-:109410006A7D5F8287DB3F91DA8F4C3E25D58F7264
-:109420007C23D58FC9FB5E8257083FA7C2F95FD264
-:109430007B4188D8908F73D23C43BB53DEE78C11BD
-:10944000E5EFD86D0A4BC4F8E7E0443BC9FD35C6EB
-:1094500081C3BB8B3844F0F10566BB1DCFB35F49B8
-:109460002F66A33F51887C3E96EE559DABE7F90EE3
-:10947000BD5DD7FCB97830CBC6B0713BB8AC10D06D
-:1094800087E0C472BB047774274BED3B4F7648F5F9
-:10949000299E3CA93EB5CA29C1E9354552FBAE8B90
-:1094A0005D129CE92B97DA67AF724B704EDD64A9B1
-:1094B0007DF7B51EA9BE87BF4AAABF6E638D04F7AC
-:1094C000AA5F2CB5EFD3E093EAFB065649F5FD0FF2
-:1094D000D649706170ADD47EE031BF543FA869A316
-:1094E000543FE44CBD040F6D6990DADFD01A90E070
-:1094F00061EC90D4BED47A448287DB3F92DA8F4C01
-:109500003E29D58F729C95EAE77DE30CD0BED476D8
-:109510007EDF55F3E7C6E47D27B5332581BF8FF99C
-:109520006F16EDC4F3FEEDF9F99A1F58E1FC511ADC
-:10953000F70703F7CF5FEA9E25FC7FEE272EF3B9EE
-:10954000E97C5E021E78053989F729C47F18624DCF
-:10955000A57C6412ED5B90C974E07937F083004814
-:10956000306466621C1213F263D37EEE7FF57EECEC
-:109570001B10E3A05F7DB6BBE7CF289773EB5F1DA1
-:109580008171CE1CE65B89F300BB1B8FFB58EF4655
-:10959000C9F928AD1C65053C868D7728AA2EADDF5C
-:1095A00065E47794B599DAB7F52BF2550AAC6F51AB
-:1095B00058FF8F40FC650439ADF3829C41A0FD98B3
-:1095C000D74EF013DE64829FF43AA85CEBCDA3F291
-:1095D00029AF93EAD7798B087EC6EB22D8EF2DA767
-:1095E00072BDD74DCF37782713FC82D743E5466F3E
-:1095F00015957FF4D650FD4BDEC504BFE2F55159F9
-:10960000EF5D45CF5FF3D611BCC9BB96E02D5E3F41
-:10961000950DDE8D54BEE1ADA7FA1DDE0682777989
-:10962000030407BC0709DEE30D12BCCF7B8CE0030B
-:10963000DE262A0F7ACF50F996B785EADFF1B61207
-:10964000DC2CF613BEEAAE48F7183598B132E207C3
-:10965000CDFF1D87710F324791E9AF52DCA38B3FDD
-:10966000F4F4F85A8C632A01F717FD9F2EB9EB9793
-:1096700085C505DF8BF1EE8F66BE2890875A03CF34
-:109680000BD42630BA1FC6847F3E5BF0254BE27EAA
-:10969000F92C31AFD9420E0A913FF3883FDFB996DA
-:1096A000384B8BB7ED191E350FF933DDE0A3BC83C2
-:1096B0008DDFC3EF9FE131E7811C9DABB9F3008DD6
-:1096C0006777E6E220159640C79B319F7448A53C1A
-:1096D0006C7BE3558B7B12EDD6EF3A9B86F6A8FCAC
-:1096E000EF2AE5EBDF35C54EC67C4B721EC74B72C9
-:1096F0009E412A7764B83BE33CBFCAA979E16E2555
-:1097000074FF7F3C86E620E795CC61A273B8CCB5A8
-:109710001FAFDEDC040E1FC237331F9525E91E077D
-:10972000BE7F0B0418087B065B3222AD473F9F9E2D
-:1097300079DC7FEF996790CA8F32DC3D103FA773C9
-:109740005CD27CE2BA3AC47D9C9667705EFFB1F34E
-:10975000BB2F95EC10BEB5FCC6CA61E29CD6424553
-:10976000DB07E77EA295697E22D54FBD97E77B3464
-:109770007B79BCADE4FAF05C8D89F4E65425DA8996
-:10978000FEF6B99A7BFBE07EE16D10EFE1FEA9A643
-:1097900047A7026C00782AE3E72EA61E8F253ED34A
-:1097A000EB57788FE17EDF54F03F317E54BAF27C84
-:1097B000CABBEEEF4CD82F4B6AA17BABC037A3716D
-:1097C000FD7307A9F4FD86770DFE5C45257E312BE0
-:1097D00030FFD949C02F11FC058D2F16887B39DA4F
-:1097E00073E0B71B913E7FDD36308FF669760D72E0
-:1097F000203E9719F8BD3ADF5B2A3F9781A97C3C50
-:1098000037129FFF2CDD2F40E702E9372896EE172D
-:1098100034AA6CF1AB11F4E9BD828EEF269BCAFD30
-:10982000D4AFBCAFB840D075816857B1E7503ADECD
-:109830001B5C70D04471112B68CA7747385755BDEF
-:10984000F8C15F740BE3F3EA8693FC3C166BCA0F16
-:109850003F87F5B0E06B8DBF5473ACE7595BF8FC04
-:10986000F8F8C0E7F7083EFF12FDFE711647FCCD81
-:10987000F06A13A02600A5E7DFEC749E4F3BD737B4
-:1098800093B9A99C0DE446BE76FBD6D0BDFAB9AC1F
-:109890009E9E2F289A918170356B294B86FE6E5AB9
-:1098A00055BB3F196637B16ECD70CC734FF04FDBAF
-:1098B0008F65E506E54B9F83E464058EDFA4D4AC99
-:1098C000E802E3DDFAD2B01598471EA7723AB0B7A6
-:1098D000391D809F5C6AC2A5EB03B97848C805CDE5
-:1098E0005F938BA94B994B490ADD03699393A2BB04
-:1098F0003E4BC53D16630B9D43A9DE6549C0FCC9BF
-:109900005CC6ED76280FC4EDB526075F9B38DDBF3A
-:109910007E59A17B365F2B8CBEE7D09EDFA0F99FDE
-:10992000207F5CEE3E8DE1FCAF8ABC5E8627B95F8E
-:1099300076C83E7F6DF00F88CB26FBBD11D7632A1A
-:10994000F13CD417CFEBBDA23897C15CBEEEE0CF9F
-:10995000E0E704DAEC00FB392694277CC4C4F376F4
-:109960007A7F575B477BF3B498990FF7B394A203C0
-:109970003FA21F72E97C3DC903002FCB904498970A
-:109980002C713B22CD63B918FFE04F3C1EF7A53385
-:109990003A17A4C7A762E7E3B4975FB544F3F96841
-:1099A000764A9BE7A5F3E2F47A3F2F93E8AACD0F1E
-:1099B00034459E1DC6371AA39D28AF9546CF7B8898
-:1099C0004F2DFFA6C5C50733BF227BC02E2E4BE30C
-:1099D000E78F03EDD9E1E6B6783C2B6427B53C165A
-:1099E0002B8E9C8F745BEDA4BF263027D98B1EEC89
-:1099F000B8862FCA63A9B84348795E0FADC382FA0F
-:109A00001ACA28CCA390BDF4937CC6E0BC685D4123
-:109A1000CC88B03531718487C1C718E9E9C1B8066F
-:109A200058EFCE93CC8FE7A91A2F4C2A8D85FA9D3B
-:109A3000DF1A290EFA6DCC2BA9F81D899D673F4CC2
-:109A4000C57C4FED852D040F681E7196E7CF8E4FB4
-:109A5000C1FEB69F373B2CE4072C243C6879CAED45
-:109A60008C39711FB4E8231BDD332E3C5A1F437819
-:109A70001379B562B1EEE2F33C1FB20B81411007DE
-:109A8000B4985920CC5F36D965B88885C1993824F7
-:109A9000C061798E6B8D1F637B883CC84036303C3B
-:109AA000AFC65A1322DEA7D2EF2316287CDE67F258
-:109AB000DC9D7A50FE6C82CAF1FD7715F17583CD7D
-:109AC0009F82FE6DE39C1752D0DFFD6DCCDF098FC6
-:109AD0004FFD644E41BCD60DFB0FB22375F06E10E6
-:109AE000E35FA33F8A51FE6B3EE5D76E1076F6A981
-:109AF0008B9FB364C0675D1123FBC9841DD6EAEB5D
-:109B00002E9EAB427A5E28B63A502FE48A7C68EDEE
-:109B1000F5FF99DC14868F9DE0570780C0DBC1AF4D
-:109B20000E80EFBF0DFC6A84F1DE29969BC1AFC6A3
-:109B3000D20F7E3596CF805F8DEDD0AFC6F229F083
-:109B4000ABB15C0B7E35964F825F8DED9E00BF1AE8
-:109B5000CBC7C0AFC6E77517A797D27C8E31BA5F67
-:109B6000BF3426CE80FA15E61F8D79A1C3AE7ED113
-:109B7000888FEBCF1B24FA1637474BF0E0D309212F
-:109B8000FA22FD8F7791EA071CCD92EA337D3D25BD
-:109B9000B8EBE27E128CF9A1F0F753AB4A2438C53A
-:109BA000335A6ADF79F20409EEE8BE556A9F583EDF
-:109BB0005DAA7F344E4747FF3C834C47FE7D850BB3
-:109BC000C5363A5FD91E9F3E26E8A2C18FFF4A9D47
-:109BD0001C296F7B570F83140F741173BBBB8783D2
-:109BE0009EEF3B31F0C5DC02A487816F9BBA5A62BD
-:109BF000BA015D721F37303C5748270E607E76F100
-:109C0000DEE325E762902FF75698A3903EBB5D25D3
-:109C1000D1082FAD30A784F3515DA6A71FDD53F007
-:109C2000F0F569EF3F5A32E1B2FBE88F21FF75BFD3
-:109C30004CFDE8B959280F97E09155D17E6D088FFA
-:109C400013E8FB4ECC5325CD5F2F170C37E953702B
-:109C50005CAB8C4F57D6038887A79E30D239ACB601
-:109C6000FEC4FB5A7FC3D58B314DF997CE7FB78B9E
-:109C7000B707FF370AF1026349F34B703A86217E3A
-:109C80007E27E4ED5F85BCFD56D015E35884999D91
-:109C9000BFA7D1ADAEEAB151B92837457C5EEB6FB5
-:109CA0007C4C417593C89CB5F630BC3E21E6F18CE6
-:109CB00058D73AEC17E08E37BA14C45FC662B78241
-:109CC000F2D6754913C14F09F94EAB69A1E7E9F71F
-:109CD00004A8EC5215A4FAE1EA4BB48E363C386580
-:109CE0003CEAE9E417EBD1FA0DBDFFDA21E4B70B4A
-:109CF0002E3EFF389FCD85F622CE6777F2D2214ADD
-:109D0000A713F57E9CCF25E09A7C84B78975C5F9A9
-:109D10007C04FBC5BAEAAA920EBDE0088DC71CD52B
-:109D200086707BD31E3F6D15F8DF2CF0A47F6F9BF0
-:109D3000A9A6BF3D825C69A5664F8B8E1B747A27EE
-:109D40005A92FB43F80BB7037FE981F2E873AB62E9
-:109D5000FF8AF038B12D5E9A4AFCB426E6F6B73198
-:109D6000DEBEF1A8CAB8BD1DB71FF5E5FBA32C6484
-:109D70004F1B478D4C0FE7BB06B18EAD02EF837CC6
-:109D8000AE13F740FB316E0BE5E3073257FABDD057
-:109D9000DFE8B1AA3300FD1D6DB327EE187EDE812A
-:109DA000DB9309620D7BC64E7C10C77FFF28E80558
-:109DB00047689E5AFDE6F289637A211D839C8EEDE9
-:109DC000E1E74D41AFFD625E7B05BD1A057FEF16F1
-:109DD000F664A7B027DBD19E5890CE45623DDC9E4D
-:109DE0006C16F62488F604CA77853D7907ED099448
-:109DF00005A3B2CB486FE22536B22710A0D07982F6
-:109E000005D2BAB47995A7A912BD4624C548F42A4B
-:109E1000B3254AF525C65409765DCC92E0EBCFF721
-:109E2000D4D929D9AE0C3E3D5867A74A2478C0D171
-:109E3000D1D2FB95AE8952FDF8A229527D85738659
-:109E400054CFC47E18DFA283327A9D4A71AED87790
-:109E5000D2FCA9F7CB55DAB719F481EA0C97DB42AB
-:109E6000D6B64F66C07D32705F1C46ADBF2CA99E32
-:109E7000FCA8A326772A9EDFABAD043E84B2F82867
-:109E8000F869947C04BE06BFB7D03D92FC40F097C1
-:109E9000FA131D5AF87E93B66F3548B7FF343A5F10
-:109EA000DE9F2ABCC2FE94AB673B7E59B7C4ABF2BF
-:109EB000CB40BEC8FFFA6DCCED7B916FB67D047EC2
-:109EC0002AFAB91FFD82FC2FCD6FDBFAC52FC8BF60
-:109ED000DDDA262F1E495E0A85DC6E399AD5D0045C
-:109EE000F2B63959710A5493BC1469F2D224F4665B
-:109EF00079353D1F20DEDB6A72C7A0FFB7F9D85263
-:109F0000D16F981E217F3D4C8F601CC912E4FAE48A
-:109F1000D4507D162756787BC67AEAFAEBA78307DA
-:109F2000EBDA97E8E0D1BAF61374F0ADBAF6D3A540
-:109F3000FA0658F7E5FCEDCD423F68ED0A8D6ED587
-:109F40001941DF0E382AEB57E6AE96CE3D349E9887
-:109F5000457A73CBF195028F55127DF668E31C05A7
-:109F60003CE75FFA7E89D117D31BF8A0E498D1595A
-:109F7000EB08D14FA313C37838ACBF52AB2AC95FEB
-:109F8000C3314EDFF6D6B94BE8E71DC2CEBCA1F314
-:109F9000DFD49FCEBF3F1EF8674B9381E2AB2D47C6
-:109FA0002724627FBB2FCEA4F9361C33D03DB217D5
-:109FB0007B8EBFA9B65B687EDA7C0A3F581A83FBAA
-:109FC000AC179A0CA4FF0A4DEE447B04BCEBF9AB32
-:109FD000BD7E35BE05072A11F1B21BEC109D1B1684
-:109FE000FA54C3CB9E134F12DEB71D5B948878BF23
-:109FF000A1D520E165688BECAF0F399320C1034FE9
-:10A00000727F10ECAE84DF2BCD5B2F17B83322C3E9
-:10A010005DE4F657E90F6C1774DA26E8B43DCA39E7
-:10A0200039D2BEC6B64FCD55E1DF5538D393E7DB05
-:10A03000CEF4E4F9AFCD4047D4B3174E1B48CF0E52
-:10A04000B1D7AB3511E851DC6CD0D909D96FB8D68E
-:10A0500078F5543B7AB1BDF735BD58A27D3F2578E0
-:10A0600063C4F3B1213A8873953A7C6A7EF495E92A
-:10A07000A69D47D7D1AF9DF743FDF8F4F134BB0E51
-:10A08000FB69AA247BB326E65DA1CFDF257DFEDE3A
-:10A090008F429FFFD889FCA423A33AA7A31C1D6964
-:10A0A000D3E32C365C8F6BE72183CDEFC584FBF9BE
-:10A0B0006EC18F3B5DEF8FE983F4ECA6FEAFFA3BF8
-:10A0C000EF0A7FE71DF477BAE33E10F7770EB96623
-:10A0D000707F2759A1EFC52C8DB9DEE889C0A7FF95
-:10A0E000D7FD9CF145B29F53E194FD1C6DFF60B715
-:10A0F0005DA1735863F264BF6737FE827926ABE2D5
-:10A10000C77B5CDB5D132FAB870342BE0F09FABC34
-:10A1100029F4F07E1137EC40FC135DCA055D78BE72
-:10A12000A2F8BCD3E674207DAA785C96574DF1F472
-:10A1300050CDBE7B6BA8FD910BD3CFE3FDFEDDF6CA
-:10A1400018CAB3ECC6F9C0128E983CE7F1FB15BBF8
-:10A150005D8A636984B87E488BAC07343F41E3CBAA
-:10A16000DDCD9F135FEE6ABDBC3DD5F497D6EE4DB5
-:10A17000F67A29E2E7FA66C6306EB892FED1DBC500
-:10A180002B8DA36F3FC458AF46B23BFA71DCAD01D3
-:10A1900015CF3FEF6C0926E2769D3B7048C57BE00A
-:10A1A000C52D019AEF3E97625733A95D299E8B7E9C
-:10A1B000F3E27B63F0F9AEF3468385F699EC24B7BE
-:10A1C000C5423EDFB968B03909BF2AED73045A3E73
-:10A1D0007F10E5D56755E9BEC8EE8BFD92C2F1F65A
-:10A1E000E8752AE993ED651603E697B79F378AF37A
-:10A1F000D601F21F76B466D9B0DCEE02F9217D11EA
-:10A2000024FCFFFE3A7E4E7527F4C7F58483E6A151
-:10A21000F141E0BCA13CD2F7767E2FC61B72F1B3B0
-:10A2200018C4CF81F37B62505FED6AE1E30C59D231
-:10A23000148371E6DBAD86589E57E99F84CF1B8758
-:10A24000DF6FEB87EB6A31F0FD1BE1D768E3ED2EA2
-:10A250009B4DF9FCDD2D3C0EDB7D9EE78FB6FBF9B7
-:10A26000B93526F498D67EFBF909637A61FEC06F92
-:10A27000A2F643987F651CB4DBDF71EB7574BEC634
-:10A28000378F85EBBD52BBECE794B4E8EC93671EC7
-:10A29000C981468723DF4DB8B192CED7733D39CA05
-:10A2A00028EB975DE797264DC0F16D7C7CE6E7EFE4
-:10A2B0006BF119FE18C3BEBB523BFCE68915D8DF13
-:10A2C000667ECE6C884DD6674786CDF8FD7C3CFF18
-:10A2D000BF2986ECEC765C3FF67F9451FE6C77F9F3
-:10A2E000E3A57198B76E664EEEC7C97ABDF4C2A6F3
-:10A2F000BD71D0FEBD0D0AE177649EBCDE9DAEEC63
-:10A3000087310EBED0CCF1ABE59334B9DCD39C7071
-:10A310001BE9A732781BF0F85EF9EB94C79EE39730
-:10A32000FB19B831469AF7FCA6045DFC26E7C7C1C5
-:10A33000DFD4F203B68A01A1F8ADB095E7D707FEE6
-:10A3400034A17F00E65B5CC6CFCFEBF3E2A38C16B3
-:10A35000D9CFD2E5C50BF57971BD3D17FED800B157
-:10A36000AF7189FF23EC9C966FD8660A4C715F83AE
-:10A37000FF30C808A10B9DEBF5241600FEDF10FE90
-:10A38000E52073DDDD29202A5B55DF1016E6173046
-:10A39000BB8F250D08C5B7834FCBF140D171992FE5
-:10A3A000217EFC12E3C955B8A74972E0E379D0AB2E
-:10A3B000F433D6C4F46E6802BA0E3CCAC47EC7BF7A
-:10A3C000EC45BE6AF842DBCF00D7A313EECF33F2E1
-:10A3D000B71BBF3013DF6D19CEED94E6A768FB34D1
-:10A3E00037B2A6E5A50A9ECBB6AE68027C6E3A32BD
-:10A3F0002B7501F4FFC1C7B4DDC9B6146ADFA7AF7E
-:10A4000093E2CB815A1EEAB8C1975880FEBA4592B2
-:10A410006BADBEE1F8D218FCBEC885A081F8B4F1DE
-:10A420002333C3BF0FD0B0C342FB390DC7CCB4DF59
-:10A43000B26D0797132DEFACF9F96F097D7E50F8D7
-:10A44000BD0784DFB24FF82D7B84DF12107ECB2E48
-:10A45000E1B7EC107ECB1BC26E6E3A2EE46F498CD6
-:10A460009F7FC796E765B579DED1BDE98411165C9B
-:10A47000FDF180B50186F65C9693510E594E462645
-:10A48000CBFA63B83D556A5F6ACD96EA87B1EBA413
-:10A49000FA1B5AFBE9E291C1BA78A444E78F8C9188
-:10A4A000E5F26858BC4BF1B51CEFDE141EEF6622D6
-:10A4B0009D781CB8ADE931A2E3B6D359F1E17ED95C
-:10A4C0001B426EB69DE6F6F98D33E76223F96D67A0
-:10A4D000043DBE16F468167ECA4D29AEDBF30B317F
-:10A4E000AE3867C6731FEDF1B3F6BEF6DE19FFA9ED
-:10A4F000B870FBF705058D21F8DB2D9FE452FEE4D3
-:10A500002AE563592C3FE7B65989A6FBF757BAD716
-:10A51000F29BFC2CB10F51D387EF8BD60CC4F20504
-:10A52000933B15EF3F6D56DC53508FFB7E678EF8E3
-:10A53000F72496E72B9AF037A07DE04792E1E725D4
-:10A54000C588FC1525C067996739E2C78AF13A3496
-:10A55000526D6E86EBDA64620D68E7998B39EC9D7B
-:10A5600018172118E7875E9ED5F9302F25C8F78F79
-:10A57000C1BCD2F73EF068167E770B4BDC27B35890
-:10A58000F9BD83E87C4F5D7E21FF9E6D7C3FECB77B
-:10A59000249BEFA306487F4F11FD1A6276A4933DDA
-:10A5A0006D4FAFEAE25C364FBE8FA2E79706A16718
-:10A5B000DFC8744F89F41D8C3F0AFC6CFB6A9C8ACF
-:10A5C000E31658E35CFCBB902E15EF81BDF1F5E876
-:10A5D000986911F86C7FEF697FCC0FE38382608DFF
-:10A5E0002AFE4E8541CE6F190248EF0B3633C9F56E
-:10A5F000605C70C2A5FD0D3923FB79839AE4F83FB6
-:10A60000B4BF5FA7E079B3367E428220FD8FF0EFC2
-:10A61000695C899FF4FBF6C7F3B5F3929E4FF01C7B
-:10A62000B11A6FA3F3359B8E58D7A31FA9CFF71D7F
-:10A63000FE80EB71FDFC1B3F98948AFED7E6A137A4
-:10A64000A7A21C6F41054FDFEF5938C925C1B07E65
-:10A650001BEA7B26BEB355CDEB476970CD243C3F4A
-:10A66000B365186FFF49FE9127F17B605B6E13F5B0
-:10A67000BE4778BD06B3459386216C32103CA917BE
-:10A68000B487FE7EEAE93A8EFC199DEF3A81E59F98
-:10A690005076A01CD1D3F519C2C791C760DD477BA6
-:10A6A000B84E86C3893D5CA7C2E1CD6DF6A5C5163F
-:10A6B000BE7FACF1E1E1631384DDE1741FAFC5350A
-:10A6C000C55797E7FF77C1A76F0B7D7548D88F37C0
-:10A6D00085FDD88FF683E2616E3F1AC5BEF16E61CB
-:10A6E0003F768AB8371477B9857F3159C4C33C0E99
-:10A6F0002B185ACAE35EBB96E7CF30468A87C61549
-:10A70000C87EE2D87CD9AE8CEE9628F169795AAA37
-:10A710002E4ECED6C5C9B25D2931F6D7C5C98375CF
-:10A7200071B21CF716378FD6C5C913A4F6C7F31D2F
-:10A7300044D7A2E3B7EAE2E5E952BB101DE57D9BF1
-:10A7400010BD6644A4E396E2190FFEDFA263E4FDA8
-:10A750009AFFFFE8F80FCAA3CD20EDDFE8CB77849E
-:10A76000FD7F4BD88D83C20F3820F21CFB843FB78E
-:10A7700007E9D81DFD3AA7F0EBF8390E2D0FF28648
-:10A78000C8433588731C5BC4BEDB2691875A56FCD0
-:10A790003D3FC77191093ABE1B918E154ED9CF1B13
-:10A7A0009327D371942351E7F7C97EDE70BBECE7A2
-:10A7B000955A653A0E63FD757E9F4CC7A12D253ACB
-:10A7C000BF6FB4CE4EC9E738C02F78B45721DE4BE7
-:10A7D00090CF731406E5F31C7AFBAEDD57D4FC86EC
-:10A7E000363FC12BEF336F421B8AFB452966FEBD06
-:10A7F0000DA3A70BFA1D1ABEFCBDF839C42D9FDCB2
-:10A800004EF82C447B1EC17EFFA917B7FB7FEA657B
-:10A810006FBB1F19DD0FD39B3EEEFFC48FB5F373E3
-:10A82000552C88DF9FBA8CDFF4275CAFE62F19ED3B
-:10A83000350CFD08D562F0E1F777996AA573778743
-:10A84000DBF1A34EF5CAD4BEBFAA60BF9F887E9538
-:10A85000E237F9B9BC5EAECDBDF05E4FA9B305F3EA
-:10A86000E29B3F323B6B919FA3F87750F4FED6E119
-:10A870005EB9D49F863F3CFFFF0BB48FF8A158FA16
-:10A88000DEDEE73AFB090B867E5E88E6F091974FA5
-:10A890004DF2A585ECF527BD2E903DCDB57599817E
-:10A8A000F1B2B2D697C0F72B03245F7ABFAD5DFF3C
-:10A8B00057E7A79DCC7305116FDFA35D2EA47355D9
-:10A8C0002E63BFF6DF7F21DA7D17FF1E8C4BC5712B
-:10A8D000353C69F58704DD0F8BFEDAF0A2F1157EB9
-:10A8E0009F2621EC1EAC6EFE1ABE561ED91BC42339
-:10A8F0008CD7BA1E6D1D11F8C77D05BFFB7BA2AFBB
-:10A900008E7FD858A7B8A71BD9EF33093F329CFEDA
-:10A9100083695D7E6DFD6C783FBCFFA2DD5BE7FA6D
-:10A9200050BB339360AFB367821CDD7E54A5730EBA
-:10A930004CEC831BDBE859ACA09D318E505862581B
-:10A94000DE55BF9FA8CF1FE8CF9515377791E0EB75
-:10A95000CFCBE7CA5C177B5ED6AE94D986E8EC52C3
-:10A96000A9CE6E8DD1D9B5893ABB27E7C58DCCA8C4
-:10A970007D6748ECD72B0EFCFE8E916328BC5E7C75
-:10A980000788E37B793BF2DB767EB69783F0DE26A1
-:10A990001FEB9883D3CF27DD33516D1EA2F3A303A2
-:10A9A000343BE6A4B8D71C1844DFF3343BE5BFCFF3
-:10A9B000E0F75A3F2ECBC17B368CCA67BCF68FCBF3
-:10A9C000E83E4E32954F791DF47CAD378FCA27BDD6
-:10A9D0004E7AFE84B788CAC7BC2E2AEBBCE5543E2B
-:10A9E000E47553BBD5DEC904AFF27AA8CC02F706F2
-:10A9F000FFDE40968F3961C62C7B158C1786E74C9D
-:10AA00001FCC230C8F5D17DB2538BD26596A9F5A52
-:10AA1000E590EA533C79527DE7C94E09EEE82E9263
-:10AA2000DA2796BB24B883AB5C6A1FEB744B704C7F
-:10AA3000DE64A97D94C323D5EFB97E707CD365E431
-:10AA4000B9CEEB3A817858ED759FE0782A3FC1F195
-:10AA50003399CAB9BD3B107DEDC67A17DA6D7BBE5E
-:10AA60009DE1F976B395DFFBEE60B42B1DC2FAEFE2
-:10AA7000E082FEA4F9427F523CE7E7E789F3DC2756
-:10AA8000E4794F96DE0319243BA9F931C3D5B458B4
-:10AA90008CC71E34D9FFBD3FCCE381E12AC37B2B99
-:10AAA00047CA26525E04AF6CB2087AF40BE19FC627
-:10AAB000F4B652BC38FE0985E23B584905E61167F9
-:10AAC0001DCD7686FF3D28AD3CFC1BFEBDA1983D0B
-:10AAD000DB1C98171B5F3C2D312A2CFE1B1FF8B185
-:10AAE0002C85FAEB3B200AE6317EED34F38CFCD06A
-:10AAF000FAB476B39E90FDD110FFFBADC21FA775CF
-:10AB00006AFA69B57D3D3D5F9D77F97D9BB3625DD6
-:10AB10005F097FED0BE1AF9D127EF749E1777F2A58
-:10AB2000FCEEE3C2EFFE58F8DDC784DFFDA1F0D7ED
-:10AB30008E0A7FED3DE177AF147EF7EABCF5F4773E
-:10AB4000AD2E6C54987A99F3A57337C8EBAC5A279D
-:10AB5000EF1BCE7A42F6BB673E24FB6BD397CB7ECE
-:10AB6000F71D8B657FEDB61AD95F9B5225EBC75B4E
-:10AB70003CA5127CF364392F77935BDE37D4E8343D
-:10AB8000B15CD6939664D95F6B6FBD5B03A354FC35
-:10AB90003B2448CC5361F630EC7BF0D279C702BB42
-:10ABA000AB14F76B0A997B19EEE70C3504DFC7FD90
-:10ABB00026F6A14ADF816CC0370681BC5E1830766C
-:10ABC000BC23CCEEF864BC4E3D2EE7476EBD47F685
-:10ABD000832BE7C9F18CB95CF6835D69F27EEC44A6
-:10ABE0009DDD61C21E9AF9EFACCC7D793B648899FA
-:10ABF00047F795AED51E9999FEFC18B747346E9667
-:10AC0000544FF628AA0F3F273140DC53A88D1AF87D
-:10AC10000EEEDFEDF988DF2F00B407BBC1FBD733A1
-:10AC20008E6FB375247D3F6EA789DF1BD89D62733D
-:10AC30002E85AAEB2FF2FB01ACD548E7C73C786F15
-:10AC4000240BFB95CF8F15068DD2F932B3AE3E0D96
-:10AC50006DE265E7C3CFD1FDEFCD479CE3E8C3FAD2
-:10AC6000D0F988A6C8F70DDAFC381D9F6AFAA7202C
-:10AC7000C0FDA38276FDA3A9F49D31E3878CEED9B4
-:10AC80005B0C2D679EC3FB515FF23CEC3026C76D19
-:10AC9000378E95E3B6E1F6CBC76DA31C32BF8EC9E4
-:10ACA00093F5408553D60397F8354DFC1C627B7EA7
-:10ACB000CD4D7DB2B47B3A849FA89C7D317C1F939F
-:10ACC000F3CF10B1CE47CD6EBABFB23C9D119D8679
-:10ACD000D8F979C55ADCB7C1F37F1FF07B2F46E660
-:10ACE0004EEC83E5E911E2FCE25827F5D7CCE955B3
-:10ACF00004FF7ECEBAF47CA2256894BEBB61646179
-:10AD0000F485FA39C85F1D437CF47F675EE2FB0877
-:10AD10001A9FD912AEB07FE793FC40AD1C1674A900
-:10AD2000B88EFD76BE8FBA3F5813C4EF447E9FCCD9
-:10AD3000F314F7A74D30F2EFB6B86CC3812E23C4DD
-:10AD4000FA8BC43ED9162F0BA23FB7C96BA552DBB5
-:10AD5000FF5C99BC2811EDE6960C4F2A9E0BDCD2C5
-:10AD6000B1C372067A7AB3A9435AA47B048DA68133
-:10AD70006467B734A618D10F1D66B41BE97B52690E
-:10AD8000D355CCCF8EC4FB26490833DAA7DBE40DBC
-:10AD900004CBE85CA887CE11C13A4AD18F2DB34FBE
-:10ADA000A3BFF7D8F801C88503FDE30E53F1BD7DBD
-:10ADB0001DF9F96B8B9D9F6F1D91349BE855E0E465
-:10ADC000DFEF2B48B339FDD85D32FF8E4F15FCE322
-:10ADD00074E17602E45EFABECF40160623BD74F03D
-:10ADE000D37A3DA03B97B8F298383FD71479DFE685
-:10ADF00033E1576C117987E3C2AFF858F8154784EF
-:10AE00005FB15297077A5FF815FB441EE880C8E7E8
-:10AE10001D14F9BCB7845FA19DBFD6F822791573C4
-:10AE200058E2197B771AC773CA2AC55F0EEB289DB3
-:10AE3000C9E1E4C57C7FB4ABA7CE5D5280F526E7BF
-:10AE4000485847F2E4BAE1B88E94A92D744F69B21C
-:10AE5000C7EC7029783FE929BA17A5DD0BBB93A38E
-:10AE600086DD3E7304E9DF3B3DE2DCB1DA5C48FCA1
-:10AE7000F58489BE93A47D3F6EF24CF97B4AD3756D
-:10AE8000F8BD5D079B15AE47DED1E4A23FEB1F8EF8
-:10AE9000F714D136EA4E719E172F5D459097B50293
-:10AEA000EF1A5E1AAF1F1DCBD7C1F7432DA29FA388
-:10AEB000C5B7C6623F1FA4F1FE260879D0F7B75A7E
-:10AEC000EB4FDCA78916F47FB4E7E5CF9D1EF63281
-:10AED000E99CE961419FB67E4B1E34E1F7B4270738
-:10AEE0001E48477909DDAB71C5F2FB2B63FF3D13AB
-:10AEF000E8B45ADC43D0F4EACD427EF5E37DE0BD10
-:10AF0000FCFD9D0F4AA698F07BE837057EC5FF1E25
-:10AF1000B0B12639FCBCEF07383FD095F7DF743766
-:10AF2000FD1DC96006E707CB8D16077E67B06B9ADB
-:10AF30006B05E23139CD395CE447C99EFD3FEE81B6
-:10AF4000191B0080000000001F8B0800000000009B
-:10AF5000000BED7D0B7854D5B9E8DAF34E32810958
-:10AF6000049C604227E161AC04262FF260083B108C
-:10AF7000344524131221981026099068D11BAA3D4C
-:10AF8000D27B68B321218418799C6B3D50090EF85F
-:10AF900068CFB99E1AACD7D27EEA8D8AD6DEA312CC
-:10AFA0007A430B6DC5F092F66B7B2F5ED49ED3A3D4
-:10AFB0001FF7FFFFB5D6CCDE3B93800AADF634F920
-:10AFC00074B3F65E7BAD7FFD8FF53FD78E93C18F57
-:10AFD0008F314BC25E65423263CE62858D87F6A6A5
-:10AFE0009245694333185B5EDDBC98CD64EC12FE7C
-:10AFF000CC83E7CCA60D65E24BCC724981FF8799E3
-:10B00000CF361BEFE31DC37376291DFFDFCA82898C
-:10B01000703F78CB6F719C6AD6EAEF87FBDD79EAE7
-:10B02000040F8CCFEAEC67875C8C65C2EFA58CE8D7
-:10B030003CF25ACD6CF45C8EB76431F497E3339AEA
-:10B04000CFF07C6B17F339C742E323806E22BC2F0D
-:10B050009E6DB5855D385F77F05E97EA662C23D5E7
-:10B06000D2E004782AD236AF64B06E56E9F44CC30D
-:10B07000F7030BDFCECD836BE65A1F2E0FFB354354
-:10B08000BFE33776A6F96644E1DABA8D9584609E0F
-:10B09000AD697FE75D9B88FD3E6C0B613F3BABE993
-:10B0A00083F1BBE7FF2E35DD1DED7F7056E94CFFC8
-:10B0B0000418B01CFE97C2D8744728C33F63F87ABF
-:10B0C00019D3189B80F88F670CE038D3A0849D00BB
-:10B0D000574D0FE06F0C3EBFD082F71B7A9CBE6EBF
-:10B0E0000490A9EEDB609D6BF93259C3B48EFC7EEF
-:10B0F000B8AEED01BA61FFDDF6D3882F17FC227ED2
-:10B10000D35A6DA723F8C2FE4CD7C6794C6D07CE33
-:10B1100001F0DEE24F4C7EF726F8772ECBBD64E5DA
-:10B12000F447FCD688BE710D556319D2D30BC82CD9
-:10B130001ABEAE15FF6665FDE319310CCB8FDE3FFD
-:10B14000B17A4A7C08DF43BE7109BE9A453CE97377
-:10B15000CC46FA73BEAA167C05ACF912F19566D7F7
-:10B160002270C2BAD87DF628DF6518C66308EF32B0
-:10B170007D9BDE578F4D05F8570AFE5F1968E1F891
-:10B18000BA8FF3A30B6E8A71A2FC06E3044DFC4751
-:10B19000F49A28E084716E2F2BFB1F3F059C3DBE67
-:10B1A00033E336A4D3EDDFB4322BCC5705DDB05DED
-:10B1B00055A384C3D05E16B899E461997E7CB85FCC
-:10B1C0005D6D3FABA7CF3B1BA7D038ABCAF9386C3E
-:10B1D000A36E7E826F27E133C8D8168F8EDFDE4DD7
-:10B1E000675319E0F1A53DCDFBF0FD73BB9C0CF955
-:10B1F00088E1BBB391EE1CAFC7807791FFCF6F534F
-:10B20000C20700EEB37B9C04E7BB6B943043FA3378
-:10B21000CF93FD70FF017F12CD732E2EB4EF1BF084
-:10B22000BC716B825F83F5768D6BBD2708F39E4BF7
-:10B230000AD5E3388D5B6FB268D0BF2B5E7365E0D3
-:10B24000B88D56FF019862850D703A0EAEF0EFEBA7
-:10B25000E1DAD0A5A31FFC37E85788EF975858A824
-:10B26000CF3D9C7FDCD90ACD8F0877EAE05F926101
-:10B2700021788F3FE42478C764FB689C86C2383508
-:10B280006E0CD291A9B61C8027559D8C709E55409E
-:10B290003E81DFCEDCAE68881F66E374715C3F6977
-:10B2A0003FCAD33F89759E7DB06032F2F39924FE88
-:10B2B000FCB4373E8CEB3AEDE36DCDEB0E3F81B243
-:10B2C000610B652E4BE4EB50800F1A055C8D3E8BB5
-:10B2D0001A07F46D7C68F95791CE8DDE9EF5783DA6
-:10B2E00096A8252AF0FEF93D5686F8467CB872F0FD
-:10B2F0007971333E37E3E5037F06C183F81B0F788E
-:10B300007B77777B6208D6C13C2CE49818C543C391
-:10B31000CE1FDEAFCC2479D6B8BC733951986E3FBE
-:10B3200006FE5DE17368E5300E3B3C95F876858757
-:10B33000F3ADA368CB840CDECD1DE10F1FB57B7090
-:10B340007F6F14ED06E45BC0EB0A949799888F71C8
-:10B35000B3FBE17ECD6A23DF6E49DEFC6015AC7382
-:10B360004DA19D59E1F91AAFCD2037951B8C720480
-:10B37000EB36B4C767335A77D738C19F9D9C3F815E
-:10B38000D32707B3A27CD1EBB748BEF0D947C1BFE2
-:10B3900019AF5F343C9C467E057D7326CDB7AF88E0
-:10B3A000F402F00F878B5975F2D0D0E524BE67C048
-:10B3B0001E8827E04F476556945F247E1A766F22D9
-:10B3C0007E6C107CD7D803FC3346C747267CE19AB5
-:10B3D0006D729E29513EA3E731F8EC453F875BCA69
-:10B3E0005F030BD633EB70B99657A27331D0B36FAE
-:10B3F0005D8D16C0513492E31D25C56389DF053D7F
-:10B40000B8EAA11F17D22D51D2476383B89FBBC59D
-:10B4100043CF06E54419E81BABD8671DEA40B81FC7
-:10B42000EE276DB0D27DD42F36E88FD33224F8F3D7
-:10B43000054F4F87769C68BB055DAD56770AE22BBA
-:10B440009119ED9E71CCA44FFC9CAE52CFEEB4B3DB
-:10B4500014DC8FE3C4FEDEBC708A82FD762A0AD932
-:10B46000078E32231F584D7A605AB685D62FF1C009
-:10B4700084BE75B8F87AE3522C24171FA482425573
-:10B48000A2F87088F58FEBF7F5F5C3F37AAFCB1F11
-:10B49000463E621ED20FA53053BF6EDEEAC509AC30
-:10B4A0005F47E7859EF186F62DDEEB0DFDBFE29B43
-:10B4B00062787E6BE64D86E7B7F9730D6D07D3E9C9
-:10B4C00075847388E3DD21F0AC7B2EF5F200D2B1F8
-:10B4D0004AAC638723E40DC23E5CE55D4BFA7953C9
-:10B4E000C95DDE215887D3CBE5CF81F6248C1B378D
-:10B4F0006DB587EC08A19F0BE117E9D08E83A444BA
-:10B50000F9CC61C2B359FECCF6E4DA6CB07B12A080
-:10B51000F165F665B27BDCE362DA3766FB0D7484B5
-:10B5200005F9355ED06BA1D54D7A636B35D8730ABA
-:10B53000DA974BB9BD94F95F88AE41D18F6916B2E5
-:10B540005B9789F54BFBEBAD36C6FA6F007CCCE719
-:10B5500076D6B2C20BD57ABB5C5EBB453FD98E2F87
-:10B56000DCAFAA31F4694736DF371302FCF9321732
-:10B57000B3A11E92CFB764737DBC4CE8ED2520C704
-:10B58000C8B71578D5D9ADBB049FEE8AF02B1BC880
-:10B59000D1CBE9538A0DF110279AFB596857F6046D
-:10B5A000C4B3469DACEE2023F9FE08B03B9BEC18DB
-:10B5B000FA29CD5EDDFB75F447AA13FDE85B38D5AB
-:10B5C0008627BE0DF88BAF4EF05B7C517E27BF0304
-:10B5D000DAC9999CDF6B525D7E7AACA983536747C9
-:10B5E000EDB26A61DF4D60AD2407C3FC1817E7CBED
-:10B5F00091FD18BEFFC8F99C62FF67D68D7EE2BB45
-:10B6000020DFF72DF08B7C777B8D91AF968746E717
-:10B61000B31F640BFBBA8015109F85D6115F3845A8
-:10B620009F1D93815F389E883FE2257E85BD6DB763
-:10B63000B17E1BD0E908D21F8074DB5922AE734063
-:10B640007D85E4622093D9F57C100C58D5B08E8EA0
-:10B6500003452CDE03FA65C0CED27641BF31EAF253
-:10B66000451E58DF40A933B18136D5B0C16E3F02C7
-:10B67000E39E72B311ED7DB33C4C877FA01ED89A38
-:10B68000F6AE17E1D96A67B4DF3376B106E1DA2E98
-:10B69000DBDAEF6A4AB11D27DB1FEE56A1FF93F1FB
-:10B6A000BCFD61F6A5DD5A2AD18BF82A41D0234191
-:10B6B000DAEF337478053AB89273689F7199F06D38
-:10B6C000B6EBA59E30EFC3E6797F27F70341A7913C
-:10B6D000D63D0C5E60CD2F8F2E17EFA35CB8C05FF8
-:10B6E000D6CBC5F071FAC97EAF15EBB6243C9F16D8
-:10B6F0008AE14746F0BFCEFE7BBDBF00783EA4A0E6
-:10B70000DDABC2DBB319571D308E52F8DABFA3FE92
-:10B7100057766BE3108F56E8807ADECE42048F9422
-:10B72000D738E4032BE2BD9F9E83FE1D52A6E02086
-:10B73000751EE45F05FA5F42FC5CE93E59CEF5DA1E
-:10B740000AB1FF55E094305E45172B45FF3C6E4D26
-:10B75000D3816DA8E754275A1470FF4229C207CF3E
-:10B7600055275D2FA84837E06783DE79A9E44FBFEE
-:10B77000790CDEEB1CB0FA9D306E67E0C70CEDEE85
-:10B780008B33981F17DD811D01BEFA9067A1C38717
-:10B7900072D37FBC631A63A7DAD840997D38BC03A3
-:10B7A0002FC7397CB0D8909634F35918A7ABD0E99D
-:10B7B000417BEE9D8D5607D26960738386C83891B0
-:10B7C000A2F52970BFCB1662E8DF3B36B62F44FEE8
-:10B7D0003E61D7FCE3E0DAB559BB1BFD10D5B7B825
-:10B7E0003C1DE03FD0652B0FC7D89FD7E7707FE7A0
-:10B7F000AD97EEA4F51F4971F8E360DC218C6F0072
-:10B80000FD8ED877A6F971DC4DFF2D0DC73FB266CE
-:10B81000ABFF6580EBC826277A52ECC81E570D8E09
-:10B820007B646EB377AD6E7CD7F58E56BC3F30C966
-:10B83000E19842EB792FD18BEBD9983B1E79B3334A
-:10B84000C531B9099FAF6D66B85E8777A71DD7E789
-:10B85000B2B1DDB8BF7CC97BE1CD02F4977C96D94B
-:10B86000B740FFFFEA0FDD9A83FEC986530B512FC5
-:10B8700039CA92B6E0B553C029F72B49DFA19446E7
-:10B8800017EE639DAB9B781CC66B69203AA6588265
-:10B89000B81F7506D6B8A6CFE0F79BC70CC74B27D5
-:10B8A000C65D66219C6BBD6BB3B0DF876D21E83749
-:10B8B00034D759130B8FCD395C8FB9DA9B333600EF
-:10B8C000DC9D7B5C1EC44FA712DADD0078D5D2DD8B
-:10B8D000FE277CC3DFFB81784FF207D089E4707DBF
-:10B8E000CEA43D9A0DED554E47C08BCBAED39B07F2
-:10B8F0006795AECBD1ED93C3E64DE9247DD1A97018
-:10B90000B9FE414ECE1E0DC6C9F587EECB81F98E2C
-:10B910007481ACCDA2754E467B7F24F91912CF3BC2
-:10B9200037C1BA63C8FFD06A2BBB612CBF5E07D793
-:10B93000E99BAD939518F8199ADB948171AA23F0CD
-:10B94000DC02E30CED71F12BDCCF40FE1A813FF3FA
-:10B9500072B8BECF9A19ECC6F5B2197E8AF3BD99BA
-:10B960001DECA1366BF562FB0BC0BF8F7D4EF897C7
-:10B97000B149C0AFCFCCDCA3814BCA3CE30C76EB22
-:10B9800048FB67900DD9703FDE54F2A716F407BA52
-:10B99000B31C3EA72E2E28EDE825995CBF05A79D78
-:10B9A000CD839D9B55CD584BFE0DD8CB141FF4C0B5
-:10B9B0006FACF86010E3813A7DB8C4D496F6E9BF65
-:10B9C000E608FB45D8C9A9BE9DC1F9E87FBC61F571
-:10B9D00087016F69F802B42B172B61B4D73795FC38
-:10B9E00033D9F14CD8714B049CBF6C73B1B2692C44
-:10B9F000E2CFAD10F7135A4E3D8EFE7502C63F31B1
-:10BA00005EDBE2F451FC05890FF35789F549BF8EDF
-:10BA1000EC4858CF8A16110765BBB8BEB106F29143
-:10BA20001F601D06BF24C84C7EC86ABBC19FAB35D2
-:10BA3000D90F66BFA1CA6437EC40DB09ED425B9FBA
-:10BA40000BF9E9FD193947327CF458EB97F63DF4D0
-:10BA50000B150E6E19D2ED3F8342FFFCAC4D3D81BC
-:10BA6000FA684BF03117C6E1BB6D6117EA93EEF24D
-:10BA70007B1391EFBAEBACE5C86F036DE5D4EFAD86
-:10BA8000B6205D6DB95C6F54FAD58F703F91F65951
-:10BA90005579E9890E1D5D2BD5AF9CE8D0C15F516A
-:10BAA0005869684BFEAAB0B2D6BE18FB4B5EAE8C8E
-:10BAB000BBA8CC608F5A9FF28762EC17F21ACF6C4A
-:10BAC000EFEBF1382ED768F73E3063FED8D1EC1992
-:10BAD000B94E891FB97EF97C2478FF2347FA279F46
-:10BAE0000DDECC4F08AF194E09FF48FD2B70139B9C
-:10BAF00084F076ACD066201D4385B980E7AA326514
-:10BB00000BE6657E26E2953F0B24863580E7D54C13
-:10BB10001EFF8C6FE17E657C59E542DC9F3E29BDAE
-:10BB2000EF2854483EAB034A58857FDE2CFCD55F96
-:10BB30006632CA3F80BCBE9908ED5FCCB5F338329F
-:10BB40005317DF363BEAA7C6D7F1FCC40E07F3F75D
-:10BB5000E37B37BAFD9BE1FE32297F35C63C447555
-:10BB6000B5DDB0CF5498F20EF1A67D6679AEB0BBCC
-:10BB70006703DEA744F13E92FF31129F30DB853C24
-:10BB80008C8B99F1738F093F667FA7E279937C5C78
-:10BB9000A1DF73A02BEFD564B433CA14FF34A41F04
-:10BBA0003E82F7E2D583940ED921E548F87B325FD7
-:10BBB000B5636915F97B6FA13D3096F24D93315E07
-:10BBC0002DC7977E5EAE5FFD466EFEC8700C8AF78D
-:10BBD000B656C6B61306D14E98C5AFD7C175FAD2C0
-:10BBE0000569B1EC84C1226127C073B40F06F794D4
-:10BBF000F36B91D14E60E5B997C1CB265A6FDCB497
-:10BC0000BCB1B1E46E7056E8E1DC09D17642662B36
-:10BC10002BD3E1FDABD9EA3FE27A2B451C42CE079C
-:10BC2000FAFDB0DE0E33CF7728C7C3F15C3E9EF439
-:10BC300085BC5E8E7E364F2B433E7BC0AED6A0BD0C
-:10BC4000678E27FD3097DB895D196A0B3E67EE9C96
-:10BC5000CB8CBB49C6AB33B327F2F403C57D4CFE96
-:10BC6000A0F49FF6E3C3FCA85F68F370BF303EF515
-:10BC7000C2610F3C5A971B7A1EF135F74258B380C8
-:10BC8000DC39172B643F395319D93D57EC875D6177
-:10BC9000BF2E146AE0E7AD8D3C1E5F9A6DA3767CE3
-:10BCA000C87A80F605531C275E7D8FFCB02560079F
-:10BCB00088B80DD953C7853D1564ADE4EFB9ED6182
-:10BCC00017C62BCC719B9A544BFF74D0EB3585175C
-:10BCD000AA7D33E97D43DCA7C69771788278EE812F
-:10BCE000EB92208F032DC338108E5F1DEECAC03C2F
-:10BCF0009CDFE65719F7F3D0BE58DE747FD6C3BE7B
-:10BD0000AB170792F125692F4A7B06F44BD778A42D
-:10BD1000CB02C547BEBF294E648E0BC9B88C397E95
-:10BD2000648E177D9C9B4EF490F6978CFF7C946BF1
-:10BD3000B4C3AC3037F6EB2E822D15E4BBDBCED28C
-:10BD400076CEE0F11DB4978E94FEC483F68535CF90
-:10BD500014E7BCC2FDAD13F6A133B8AFBE126747FE
-:10BD60007B3BE80D513C7189629493C9797C9FF3C8
-:10BD7000E4B9F93C228FDCD9B641BEAFA1BE09A619
-:10BD80003AC2714A741C56987F45F2949CAD4ECAD3
-:10BD9000CB277F2415AFCC0FFE4816FA231ECEDF2B
-:10BDA0008513683D4C9DC0CEE8F3C602EE081C2EFC
-:10BDB000F05BB23EF9FC2988E7FCE83C97C3DB8ED8
-:10BDC00092629703E31140632BE72B4F247E9F8100
-:10BDD000719D753EBD5D518F798B5CB43B795E433F
-:10BDE000DED7C5CF6DC8BFF1A9213518635F5D955A
-:10BDF0006731E44F23F1F74C46F922398E8D7937BC
-:10BE0000911CA0AC4A78AC31E2F402DED5420E00BF
-:10BE1000E12E27B04CD34E2BE375095C4E643EC235
-:10BE200056142C4F87F5366D53286FCCB49AC368DF
-:10BE3000DFAF11CF1D22FE66CE23AD117918665DEE
-:10BE40004776DAEA878CF9B5C61E63DB6C97CB7848
-:10BE5000BF0D8044B8DB249D40C15B47C7C37E5AF9
-:10BE6000E75F291E241F2ECEFDAA17EB5A3AE342A4
-:10BE7000BB1B30AFDDEBA27808F990282FFDF00B4B
-:10BE8000EBD9B6B7F0315CCFF63C2B977B85D7B9B1
-:10BE90001C4E79D835A4E3B7ED82CF66E5F978DC9E
-:10BEA00005F72550892C3599E448D6B51C49E1762B
-:10BEB000A523C0EDC6A7A6BEBC94E75D797D4B6601
-:10BEC000205ADF520AF8C912F8C99CB6DADF0FD738
-:10BED000AC00AF4B9AF1ACD15FBD35D36857669AD1
-:10BEE000FD5553FB405EECBA96689E4DC4DD05FCE3
-:10BEF00066B9FA5E1BCFB7FC33F8AD787DAACD43A7
-:10BF0000D7EFB779E9DAD7E6233BED99B64CBA4AD1
-:10BF1000BC3F600FD6635E4BC621657CBC3F8FFB88
-:10BF20006F2CC0E1A8106B59684D4D443C1F0D703B
-:10BF3000BB70A4FDA5AADC1807BD3D68CCEF2DAFF2
-:10BF400031E6F7EE9BA9BE9407F024CCF4DA43BAAD
-:10BF50007CD41AB1FE1D0FF37C931CFFE83739DD4A
-:10BF600065FB9C58FFCF045F24BC9C62F701B12A9B
-:10BF70001FAABC19E3F6CC937345F6E02F855C2627
-:10BF80006CF6D8312E54D9BFC281E3ACD90DE3B8D9
-:10BF9000AF7C9CAD6913D38CF985AFDD81701C8DAE
-:10BFA000E4175AEFC0FCC251915FF843DEBDDF4198
-:10BFB0003F6B569E7A1AF5862B4F3D83F8F883D057
-:10BFC0009BD03EA76FC3CFEB4913478DE3FF212FD3
-:10BFD0007F781CDFBA40698D55D7F2A19017D05BEE
-:10BFE00017711EE68AC4D13EE06DAE8FE2F2397E53
-:10BFF000DA7FC95A709CF61FB3966762D8F32C5F3C
-:10C000009171B98F490F7AA51E0C5E8A359ED5595C
-:10C010003919F17DCECEEB62CCE3C5E53B247CCE75
-:10C020007C7C3F35025F5C7E7E74BC1D808301A4F6
-:10C0300093CD9348794D7637E53F251F25D47B6E08
-:10C04000C3BA05702C19EE2F09CF796ECBC338CE49
-:10C05000CFA7F89F6023D3F5B782BFCE0BF93A87FD
-:10C06000F205727446C8D729942FB89E14F2F5EBE6
-:10C07000363FB57FD95648EDE36D2AB57FDE564E83
-:10C08000D7C1B620DDFF595B0DB53BDB42743D5A8D
-:10C09000F6D8CDB8EF7CF03D85F4F148F0DCF5B88A
-:10C0A000D5203F2D7B130CF2B6F6A1F186F6EA1EE1
-:10C0B00063FEBCB1638AA1BD6A83317FBEB2D598ED
-:10C0C0003FAF6D9963986F456881499E6F35C97B15
-:10C0D00095A1BD309FDB8955E5B586F79CDE4643CB
-:10C0E000BF84A52C148BFEB7E5F3B8C9CB25C56377
-:10C0F000874689733836DCFA36DA2791B62DC4D0F4
-:10C100009E776C5842F71F88E3FB9DF9BD26C1AFAF
-:10C110009D65AB83F319DA458BAC7ABBE79E59A1D9
-:10C12000E5F93A7FD0E1E5FED8C5A9D5562FF0D183
-:10C13000D2B2F75EBD0EF82834C0C8EF51C1DCF3AF
-:10C14000821D5CD8BA6BC175D0AED6D61BFCC7E2D7
-:10C150009683AF80F8B240D9D1F664783F3F3BD4A4
-:10C1600084E397782FBC82EFCF5F9C6D43367F20AE
-:10C1700089913D7A2ECD113E10831FEE1770CBFCB6
-:10C18000D527DDA7CD79FA8C4C568A71E48CCC0B7F
-:10C19000A5A8D7A0AD62FEEBE0ACD0FD081FDC5730
-:10C1A000514F3E90B53603F79391F2468FE41BE36F
-:10C1B0000912AE1D251C9EA322BF3064CA2FE8E2DF
-:10C1C00009EDF9A3C413CE89F786BE1D3B9E704EC0
-:10C1D000E41DCEC9BCC3C35531F30EE7168A7802FD
-:10C1E0003CC738C2B93D35FCBA70F4BC835C1FEC67
-:10C1F000477BF20D790761E78BB8F9E02C752F3E8C
-:10C20000FF6AB6DA8BD73F66A9FB108F4775F94FE7
-:10C21000CF445DFEB3EC2786FCE7A19CD093F93CAC
-:10C220006FCDD0AF6AD7D850DC14CCC706EF89C524
-:10C23000C7CFE4CBF862FF67CACFEAF2A8964B37C4
-:10C24000B12BCE035C71BF425E9762B66F121023B2
-:10C25000E3A276DFD379A19F20DE3A929EF3F1FA32
-:10C260002B4B74FF40E537823D649E4F8E87FA0A60
-:10C27000F5D620480CEE33DB932ED4A19F724CD020
-:10C28000D37C3D9E2FE8C93CC948DFA7F382BF207D
-:10C29000FDF36C9F8FEADAC4FD2B85E34947F06D0F
-:10C2A000B4633B1BADBE03DC6EA7B8C50D81A470A3
-:10C2B000B72E1F7C11F7CB7C8C3F0E4D7500BDDB7C
-:10C2C00043AFB8B11EFC9DBD36AC8861DF4DD4ECE8
-:10C2D00048FF9A4CBEBFCDF786BE34348A9C033FDC
-:10C2E0008CB778090E8BA590CFCAAF9A825773FF8F
-:10C2F00081BDEF4FF0C178DFEDE5F9AF1B7A57BB99
-:10C300001A75E3DF305BEC97C83379989F54C258B5
-:10C31000A85E1378EFCD02CCAFF82C14E77867E372
-:10C3200007C79663DC51B552DCF19D8D17A97DDC02
-:10C3300067C945F2BDE3FD7FC7B0FF0DDF5C3391F8
-:10C34000FB2D1C1FAB36E63ED99D4E7931C76C984C
-:10C35000E7B87A3171CA8C68FE6C95C282B1EC98EC
-:10C36000C9B339FF2F525BEF40B816859C0CEB9C8C
-:10C370008F376C7D1BDBDF2D557C56F4EB33F93C9E
-:10C38000357B6D544F0BF85987ED37FC090CE79D51
-:10C390001F3A68C3FE1F6629EC3AE52AE255BD380C
-:10C3A00001E5F01DE4BF18F05F94F22BE468BA0DCC
-:10C3B000E43E07F17FD8AD8F534A7ED2F2D4CCD978
-:10C3C00014F70BB504C9CE5D7A19FB7433AFD3FEF5
-:10C3D000DE051BE61EE21F6F9D84F1A561708E00D5
-:10C3E0005F91A0FB1FF3791CF3865EDB9B5F417EB0
-:10C3F000DE68A73A845979C139B3F5FED655DE37E0
-:10C4000064FDDA40213F8F00E634CD03F066DA00A8
-:10C410008E3825DEAF71B9A2F89C4BEC7FD04F1D52
-:10C420000BFD56B1BE7E8CF3319BBAD38AF1C32289
-:10C430003BF9C7CB57DA13912ED17C99DFE06F9887
-:10C44000AF67303F46751A2EBA0E809F8DF912FCE9
-:10C45000014B1C1EDA84DDEF7F449D0A722FEA4AED
-:10C46000EF3F74EB2358577ACCC2DB771DBAF5FA4D
-:10C47000CDB0A433935B8FDD0EEBEADEA5F837F980
-:10C48000F0BA7F77239EAFD8A0F8CBA16B7DFF8D4C
-:10C49000F598626CEE72928D7F7ADBFD3723BF5E7A
-:10C4A000F4320FF2F3F214CECF4D832C6C81F62DC3
-:10C4B0003DBB28EF191CB451DD9ACCCB9E4CE179E1
-:10C4C000D97F68EB27B8D1AF5D389BBBD8F833CEA6
-:10C4D0000F70601CB5CC46F9D2F1CCD389FB4BBCB4
-:10C4E0009A5ECAED698F83F23C8B19FB0EC67936D2
-:10C4F00070BFB948D445CA3C163BCBFDDB16F845A6
-:10C500007D32BEDCE81FE79BFC5FA9DFCCF916E0BB
-:10C510007F0DEF77CE4E34C4EB468ADBCBEBB360B6
-:10C5200047E0FA9E1379DC4360AF633EF3C760AF28
-:10C53000E3F579B0D7F1FE8B60AFE3B51FEC75BCC6
-:10C54000BE0CF63A5E0F83BD8ED7D7C05EC7EBEB4D
-:10C5500060AFE37BFF0BEC75BCBE01F63ADE7F7685
-:10C560002EDFFF3AA739C29B01DE4E3BFB35F29529
-:10C57000562AF2C2224FB62D693AEDEFAE8F80CB2C
-:10C58000C19E1A504277213DB43417F51B48BCF0C8
-:10C590001FFF17DBDBD2C90F6136DFA12178AFE3C4
-:10C5A0001BE9FE6E68763918E9FB53479947017B12
-:10C5B000E6FCEDCA4C8CA39EB94DE9C3F6C06D0AEA
-:10C5C000D913D351F472A2FB68F1FBBE03B89FB537
-:10C5D0002732C18F4FF6AAC07FE71136E4572DA945
-:10C5E0001EFDD2794ED91E538FCF1B3728C24F1D47
-:10C5F000B74F85356C53E4FBA9BDD8BF43BE2FDAD6
-:10C600008316F9FEBABDE8271F8BCCB7BA564D8505
-:10C6100076867CBEB60EC73F15A9AB9BB712DF1F4F
-:10C62000888C3FBB17DF3F9326C7BFB396DA76D916
-:10C63000FEA795D49EC0FBCF7AE1BA47B16EE56AFA
-:10C640008FD71EE2FB1FEC63AA3E9FB3A9D84AFB1B
-:10C650009EAE1E9CE26E32CF6F49704FBB9278A99E
-:10C660002ECF4FF15298CF8E72F6F5D2A4C9A8778B
-:10C670004FA5F963FA29E5C591FA5663FC5455783C
-:10C68000BDBD8785B03E3E5EDC8FEFE175F48E4C1C
-:10C69000DBB03AFA2B8927CABA07194FAC593D7A51
-:10C6A0003CB1A6D4184F5C259E8F144F5C658A2739
-:10C6B000AED868CA43843E593CB18EF5DBD10F63D6
-:10C6C000AA427254E7E97B7522FAFB677D144F6436
-:10C6D000BED729DE2ACF4FE0FF2DB3F1BC196F9FE3
-:10C6E000BF5BF1A25FD17DB73211AF27EF5626A114
-:10C6F0007C9DBD5BF1A0BC7D589041F8CFFF8DFFC4
-:10C70000751FEEB75E8B9FA323F802A62A82AB9318
-:10C710007CDD30CEA9BB9571F8FECAFBD21DC80FD7
-:10C7200060770A7EB4EE45FEB426288676DE64C9BC
-:10C730008FE147503EE68D176D6DF95E949F5287ED
-:10C740007C7F33B5578414D1FFEB7B51BF1C9B2FEB
-:10C75000FB4FACC3E7B74F91E31D20799C9720DBDB
-:10C76000BB49FEBA22E37DFF11ECFF0BD490D4DE6F
-:10C77000B917E5BDB452E8336D268DDF5927C7FFE1
-:10C780005A2FC6AD6A2DF2FDC524FF4D4CB6C17EB1
-:10C7900087F6AFC4FE70D70F3FAEC5B8D61DF2B94D
-:10C7A000F6F123084F9D68AF2BF897BDF8FCAF7EDC
-:10C7B0007D7FE6F9CCED956C60E1757951B930EF8C
-:10C7C0002B0D45DCDF296C3988EA8BD5B5EEB7A295
-:10C7D0003C46F36A29D541E46F9795EAE7825E7695
-:10C7E00073AC7AFE4B057C9C8D05579A5F8B3DCED2
-:10C7F000DA22BECF75CD6731FDDC83B3E66F2DC87D
-:10C800008FDA0D68223AE05A02570B5C3FCE0A3DA0
-:10C8100088CF91D618879171ED25A29E7853C9775C
-:10C8200082F3F1FC5291DD2FC2E103FA7CAF4D9C03
-:10C8300073AD9DCFEBBC42DD4EF2D7AABB441D8940
-:10C84000D54DF908DBF58EFD943713F9D410D61DBC
-:10C8500067505DD7A8E73B6CA63C6A97586F69F6AE
-:10C86000FB94A76E7A83D70BCB3C76BD80AB09F5E2
-:10C8700032C0DDB85A095BE0BD46543C98D7CD6460
-:10C88000615F7A34AFBCA2CCD6EFC07361E27C06A4
-:10C8900013F670241F5EEDEBC3FA189B1AE757716D
-:10C8A0001ED61FA4BA38CC17A5B348FE59EA91CAC0
-:10C8B000E6EBEEC63CB54E6F519E3A9E0DD31BA4DF
-:10C8C0001722754D228F1EA9CF117A40E6A71BC4EF
-:10C8D000BA9645F4C0E22568E7C63F20F2D422FFAD
-:10C8E0002CF3D495A6736D8D810563289EEBB7F963
-:10C8F000A9AC26D5789E29DE44879B8AF9B94A9946
-:10C90000A73E5A60CC373F6067A477BB328C7CB7B8
-:10C91000A098E743FCC5320E19DF1F87F6377391E5
-:10C920001FD28DF19CB1DC1FA1C35CA6B88E6D43F4
-:10C930002DC51FF1B9027CA864BEF6EFA897B15DC2
-:10C940000CFD6D78BE05E9E1B6903F2AE33F68A68D
-:10C950002CCCA138D079E467DB867A1A479E677FB2
-:10C96000323EB67C5C2C9079D63E3BF6ABF5BE767B
-:10C970001CE7FBCC7120E18745EC181FAF7F995471
-:10C98000E09376899D9FF763F6A559142FF9B800B7
-:10C99000EFCFE8F3211C725FBAA3E839DAC7AE3CE7
-:10C9A0000FCEDF5BFBA3976AB5E491F3183705223E
-:10C9B000790737A6C059B2CC3BA889D88EEA595816
-:10C9C00048A141CFD6B5FC27D0B351BB3FA30E9FA2
-:10C9D0007FD1E0077EBAA590EAA778FCED8B06FF31
-:10C9E0001BF96A3DF2E1B59EE7C5FCE03A9C67ABF6
-:10C9F000A2D6B8E95C0CF32BA3E70BEFC5FEE67CEF
-:10CA0000E1E5E2187F8B5B8C1EB7E82D34E6F53F3D
-:10CA10002F718B7F04DCE13E09F27490E429C0E5BC
-:10CA2000E9AF7DFF83F51EC1F56E55FAC2F1D6ABB5
-:10CA30001F37783A2FF46B94A3E9A9AE06B4676068
-:10CA40001E1FCA5F341E0270171AE2217B5BAE41C3
-:10CA50003C04D6F97BD27F659CAE7F05747314E1EC
-:10CA60007A546E47FC15F26506ADAF8FAFEF2F30ED
-:10CA70007F4E11EE034F717E89E287DB493AFCD489
-:10CA8000B5FC65F07333C17788C3F705A0671DD186
-:10CA9000D3CFE1BD9CFFBDBE80FB17F05E13BD97F9
-:10CAA000C7F9E05E6157835FBEE03A5FD42F4FCE97
-:10CAB000569B8BB89D7B6791A1CE54BDAB6874BF6C
-:10CAC000F99EA2D1FDE6FBF0FD2F8ADFBCBF80DB23
-:10CAD000FBD1BC4DD8C53FBED142F9E57AD1B77B79
-:10CAE00043D5A21BB1AE06F08F6D27AEC7AA5B4F30
-:10CAF0009A8DFBDBA6F36AF27B07725D366BDDD89D
-:10CB00007E5F149F6F8D6975E079A86635A913CF94
-:10CB1000DD2EE8788FEA061DAAD3877EE197BCBE9A
-:10CB20004ECCCB56A97CFD8E160F9DEF93E7DDE42E
-:10CB30003994E6FE1B5F73E0B939F05F5260FC8AFE
-:10CB400032FB69FDBA9DA6732936537BC3AFD3B7B9
-:10CB50001FD6F57FAAC8544F687DAA9CBED3D1A129
-:10CB600078449D2FD565348B313695DCB108E39739
-:10CB700060C7F9100F0B76EE1AC07C9AA3C34AB9AE
-:10CB8000F33FB6F9B61F06918AEBB552BCE1830DAF
-:10CB90000AFFDEC7629EC76F12797C668A33C87847
-:10CBA000B8C463DC83BCFEC35178AA8CCE37D6AD43
-:10CBB00019C8E7BC43F1061B878CC9EF6F540ABE46
-:10CBC000AA0FBCD781EF2DF35A0CF543E678848D7C
-:10CBD00099EBE4791DA74DE5759CB64C5E271FCFF8
-:10CBE00054FA5E47FC962AA267A5CAEB38C14812E0
-:10CBF000DFDDE274A908ACA73A1F731CC159688C29
-:10CC00004398F9D24C8F93267A3C61E3E7933A0735
-:10CC1000AD7E0D6E773EB4BA0BE3E7DA43168A6356
-:10CC20009C95F5210024C6F397B3087EC95EEE6C8F
-:10CC3000E5F502922ECB77F2BA11EA6588DBA732CE
-:10CC4000FD773C968BB8C21DAC8FCE3BAC6443766F
-:10CC5000948355184AB7623CC647D726A66D6184AF
-:10CC6000BF50573ACCF744EB783FC6B5FB27D99372
-:10CC7000DECDE47E442CFB359AAFB5B1777571FEFD
-:10CC8000BFC5B53E695CCBAAD1F952AF233C4DB9C3
-:10CC90007C5CEB88C84BC8B8D6D99DE27B1BE2BC54
-:10CCA000C580BD75F24E37F6F3919E19B377F92220
-:10CCB000E48323BD3FF188F3AF1B278EFE5D88829E
-:10CCC000E218F5A43F2F60345E67FA109DA33E6919
-:10CCD00037D6E5CAEBED0159BF19528B75F631F322
-:10CCE00044EA38E717D346C0CF6BCB38D3BADCD091
-:10CCF0002D787FEE05C10F8B95B002EBAD702BAF99
-:10CD00002ABEE8FCCC5C47FFB77C18C11D87F80140
-:10CD10003C0EC4F1BADA817456F34C0CFADC389745
-:10CD2000EBD181ECD8F493CFC13EB9BF7802F79F25
-:10CD3000C6F0B8C2EF1DA3C715BE551C23AE20E92F
-:10CD40007B709EAA71BAF3B62727D489FDDB4341D5
-:10CD5000AAD739DF63F56D42FCF7B7BE5508ED255C
-:10CD6000DFB27A301F7EADF37C930AD289AF2E9763
-:10CD7000E7FB50E0F764A4AEFB5B944FEF8EF867DF
-:10CD8000DC7EAC1DA76BC3965C3CC8FBBF585CBC8B
-:10CD90000FCFD98F646FDE1758D58BFE9CB437A1A7
-:10CDA000BD12DBF27D9084C9A5A0349B5A643EB1CC
-:10CDB00082F2F5D1F956EC43FBF8ACDD38BEB4573E
-:10CDC000078ACBF7A1BD1A8CCC5FBE0FEDD953A655
-:10CDD000FEF47D4A18EFD7C565D4BF91C9F1CBEAFF
-:10CDE000B17F24AEC8D6933F7ACC21DBF7D4A33DE4
-:10CDF000BE3D9D8F371858DFAB7D0EE1B9D6E37F7E
-:10CE0000D2FE23D9FD27EDBC7E50033BED89742C67
-:10CE1000A3ECB372E1531D78C6AE5855683FFA9340
-:10CE2000888307DD16E1E76CEC45BFA7B644F2E95D
-:10CE3000E354073212DFAD7FFE478F68FA756A3F11
-:10CE4000AA35C0ADB5529D8884FB04F68775D4DE43
-:10CE500073A717E1AC95F10DD6D98BEBEB4C92EFA4
-:10CE6000DDB40FDB23CDBBE6F99DBD88EFDAC83C0E
-:10CE7000DFA6F76BE3E578BDD48EE2F300C54BA2E5
-:10CE800070B518E07A2D70A017E10A7AC25B707F46
-:10CE9000087A19EDC777B46CA2FAEE881C693BD208
-:10CEA0004A510EBD9136C757448EEE2739BADA7013
-:10CEB000C17E9A3E07F7BF4CEE275EFD75C33E89E3
-:10CEC000EBEEE17A48F2519D478E03F8077DD2E4FC
-:10CED00093EDAFD5B7B8AFC6BCDCDF0DFE9E917D3C
-:10CEE0002BE58969AB4DF27365E3B5BBBF4675149D
-:10CEF000CDA0D763D563DF5B10D14FB7123E0BA532
-:10CF0000FFCCA4DD5181F72376872F627754CE8939
-:10CF1000617774629DD52CAAE722BDA9C213AFAE7A
-:10CF20000E68C65C9E076C177592799BD95ABDBF77
-:10CF3000FDFD79DC9F7F6A1E874B7EDFF6CC3A854C
-:10CF4000EAC4DA7BA68CC1F36EA7537DDB51AF0D2B
-:10CF5000A45BE83B0527C5F73507BEE14CBB0FEEE8
-:10CF60001F4F73F9515F1D4FDA49DF513BEDB70A8F
-:10CF7000FE3CF40EEEF3BAB8A2867A45C60DEF9EDB
-:10CF8000B3F55194A3133EDE2E9CF7E377509E59E0
-:10CF9000A6F97C6780EC18C7CDB08DE0BBE2FB9CA6
-:10CFA000C5E279E5B61F7CBB0AC710F68BD49FE6B5
-:10CFB000F39EF863D7DB5F5D566E7F79793F2F1B59
-:10CFC000DA74C982E3F2B66B84EFC2D6C8F3CB261B
-:10CFD0007BAAD2743E9989EFA04A7BBC38B9D18F25
-:10CFE0007E5CF13AA37D74BAEB959E42F46BFD56DC
-:10CFF0000F6E93B7661A9F4B3B6C51D763E48F82D9
-:10D000005D689847D6DFDECAFA3AE85CB8EFF5C348
-:10D01000D68951BFA5DD5349764A7326B4603DC712
-:10D02000FEBE34311FED831E2B7E1196D7DEEBD66C
-:10D0300001FDEC9664DAA7FD8AA2AF0BDAF228CAEA
-:10D0400045B42E88B7A3F1F8BF7FD45047C7BEB60A
-:10D05000CA10E7D46A1FA53A3E1917D3AAE9F919ED
-:10D060009B8883694D8FE27E16899369BFEA35C438
-:10D07000C9B4203D0F46F6BF5DFBB0BDCC23E0D167
-:10D080004EF622BFB5AB5C9FBC34C77D52B37DF278
-:10D09000FE209FFF730EC6B7827CBF333F2F1E0C4E
-:10D0A000B78F11761DD68B9BE57C5C80D7DF95A969
-:10D0B000D91D137C3C7EE504FAA82BAD2B316E10F4
-:10D0C000AD5729A2EFA4358D505FB224C0E5F7E833
-:10D0D0001CB7C12F37D7A934893A9591C6B9B38403
-:10D0E000E7D907144F35D7CB56867AB974D714379A
-:10D0F000E6A664BF9B4BF83EF071967A12D76F8E0E
-:10D10000A79DC5781AC9198F7B2C15BC63DBC9BFD5
-:10D11000572FBF677226C9EDDF0CF797F688784561
-:10D12000F9678B9FBD37C7784E7FA4FA87D212BEAE
-:10D130009F1589F57ED6FA8727E35515F135047DCD
-:10D14000313E38AC1E42D439C83A88B1810C5EB742
-:10D15000C1783D44BBD64AF8BBEAE75CC4FE0F7C0D
-:10D160009A1C403EADE17A44F2D94FE7F838FFFD12
-:10D17000C64FFC27F90EFA4F0AA01EA9E6FD8B7FC9
-:10D18000C3BF7B21ED8B718133BD9BA6921EF2053F
-:10D19000F4FEAF3B722E322310430F1D5DA04E0DE7
-:10D1A000E8FC23783F33901FF3FD2F13BCA6F7B3A1
-:10D1B0006606B3E8FDC8794E7566E06F7510A03D50
-:10D1C000CC75277CBF30D79D487BF0CE92DFAFC4B3
-:10D1D000BA934BF3D5651CCF1CBF11BB7288DB39EA
-:10D1E000517B3287F6C36B602F36133D453DCD35FD
-:10D1F00018FF5EFDF8D27E82FB7FA7BFFF79F3DFC9
-:10D2000000BE6E824FE44D3EC5FBFF40EF8B7CCDF0
-:10D210009F01DE30F191B0FB3F87F87CF6730EDFA3
-:10D22000EB44AFC59CDE657398DCB7FF35361F5CF9
-:10D2300031FFFF6F7A5FE4CD75E3FE5C3FDF48FEB0
-:10D2400039F4FB15E16DF130F93919D0E5E347798F
-:10D25000FF8C7E7EDDFBEFEAF9F32AC8F9053D7D00
-:10D26000AFC13EF2118D3F958FFFBBE2C83A2EE968
-:10D27000EFFF2D4E76593E9F3617F1D5CAF9E90AD0
-:10D28000ECEB9BE6F2FA96108FCF6A927F678AFBEF
-:10D2900043789E74F91C26BE8F12CCC6FB2AE3FE8F
-:10D2A0006DC41FD17AF719FD1118688641CFEFD3ED
-:10D2B000FB1BE5739FD88774B72EE0FDE7BE306E89
-:10D2C00015E2DFDC067B64DE5C635DA68AEDCB8D58
-:10D2D0008BF97F7ACF94FFD73D5F44CFA3F50B64E2
-:10D2E000BF82DDE672028D7F51674D6E8476B5F0A8
-:10D2F000DBC1FE8879AEBB3A1AE7AE9EABABC7186E
-:10D300000C5AE97C60C44E61EE4711FF113B4AFBA9
-:10D31000FE3EE3B98D8314E72A11F46D7EE1D97ADC
-:10D3200001E72AC4374B16EBB87CFF35D4DFCBFBC3
-:10D33000C7787E273D4FE57032F7EB67ADBA7C18B2
-:10D340004A9A05F3BCF82F1FC06FBF7D6E32D82BF1
-:10D350002F77293E2BB41BF74A7E7A81E44157F799
-:10D3600041F2B742F0FBD6170ED7233FAF785FC22A
-:10D37000EBE4EB8FD4311DA6F59F10F188092F4205
-:10D380007FCEBFDF24F87C1CBE6B30FE36A213E3D9
-:10D39000F8A9619A7DE2287516BB04FDE1BD9D04E4
-:10D3A000978BC3551352C85E0FAE06890638EA073D
-:10D3B00059CC38D3EEB90EB98FEDA679DDC28FF511
-:10D3C000C73E2FBB2FCA4FFBA8BF87CFE702FD8FF9
-:10D3D000ED40E8E802FC0E448DF8DE784D998DBEF4
-:10D3E000B750537861A98883507E53E6C14B1F9C88
-:10D3F0004AF9CDF8B238EE2FBA8C7FC722D8E4A410
-:10D40000EFC9C9EFD6CABA8C4A66FCBE5C8CFC96E2
-:10D4100021DE22E32291EFC95953C9BF753C2AFE90
-:10D42000FE93E9FB71F11B18C5B79C1DFC1CB839B4
-:10D430004FD5B0B1F5AD22ACFBB0D9292F6BCE677B
-:10D440009AFF1EC63C1753C7E4503DCA6B73F3A343
-:10D450007528E7F74E71A31C9AFDE7F323F9CF7BFC
-:10D460008DFEF380F49FD5ABE33F9F986BF49F1F35
-:10D47000CF0DFE8AF8CAA6D2FEF67249F1528C236D
-:10D480005C147514A71E4A5E82F128AD879F573839
-:10D490002DF2FC32DF7FAA88B93D78DDE2247C9E44
-:10D4A0005A9314C62D784C47F362FCAEA0F4A31136
-:10D4B000F318FFAA10EB34FBDBF18540CF5924664B
-:10D4C000E4679FF278282F50D125BE2F21EA05A4CA
-:10D4D0009F5D21CEF13795F173D518B1437E90DF72
-:10D4E0000FAC107EB8F4C7FB7FCA147D1DC052E696
-:10D4F00027FEAD06C6C0EB32F13DC51A0FDB8240F8
-:10D50000FD312BC44A102F7B399FB0ED36FA3B57C3
-:10D51000A77A76D1BE3AD2390677893CC7A0517E28
-:10D52000F61AF8F9490497D83FAE60BFB98EFADB16
-:10D53000B81C6FC3F3BFF9D1EF4AC873F3DB93781C
-:10D540001C654609DF6FCC57F9DD884FAA3F407F45
-:10D55000DE5082EF47FDF94C84E70AF4E74C825B2A
-:10D560007CB76232E681F8FAB34B783ED73786272C
-:10D5700071BB1CA3D70114968C92CF6597AF235033
-:10D5800063BDFFA1B0B3D7E5861696F07C3FF1AD41
-:10D5900039DF2FFB1DC3F8548CFD76838853950229
-:10D5A0008B5A72869FE7FF459B7A126DBC636DE5CF
-:10D5B000743D6ED312B17EEB2D719E1F0C2DAA67A8
-:10D5C00092755172DC9ABAD2936775FB59C5C2C77E
-:10D5D000A9CEAC3DF3C0EB0AC0795AD47B0D24FA36
-:10D5E000689FD38EF2EF4B2DABFECAC9B3BAFDC311
-:10D5F0000C2FD6456920EAEB4BF877CB5E2975F600
-:10D60000CFCBC3EF3571395CDD738ACEC3D46F687D
-:10D6100060A12CAA9BB2217DDF9EC3BFBF50516881
-:10D62000659A0EAEE46CF5AE121EF759477C12AD4A
-:10D630000BBC1BDBA576750CFEFD49199F94F98286
-:10D640009B5FFC3F94771B4862347FD0CBC29877B6
-:10D650005FA0AE770C61DEC5EBA3F8C8DA121FCD70
-:10D66000DBD8B59FE0890FBC47F0806DDD8FF58377
-:10D67000667C4BB9E814F8D6AD9BF03D92FC562C75
-:10D68000B425227EDF427A41BF07C53E70C476C111
-:10D69000ED8941F7C87B85A5067C3BBDE506BAB59B
-:10D6A000ABF78EC1F5483A378A67E7BBAC6F221DEE
-:10D6B000DF073A32A263EC3A88A348AF1B806F4C75
-:10D6C000F4AAEFE0DFBDAEEF28A5EFC5D5177EC504
-:10D6D00091427900A50FCF4B36953530B4A71D6A1E
-:10D6E000127DDF4ED26F6919D04F072FC8E3632434
-:10D6F000A7C2EEFC14F1F5FF5EA2B383AF75FC1F69
-:10D70000E6FB51490CBBFCCF957F18FE3D1FBEEFD9
-:10D710009E12FC62BECA7D77C4FA662DB8AAE55394
-:10D72000C021E506E5769382F5938A1DF92C88F2EF
-:10D730008BE7D70A7FBB05F3A1CD5ED6877BE13EA1
-:10D740009423C09BA33CDD81F2D3B8379DF802FD42
-:10D750007FC2A7D8A7DFC47D5AF8FF74BF85F3C581
-:10D760005F3AEF03F0FC1BC15327CE177CCEF25279
-:10D77000C9E541F73CC05B50DD4FFAE5A742DEE06A
-:10D78000278D7FB7E993E5418B555E3726F3A131AD
-:10D79000F29F3EE553E43FCD79D591F2A131F29F5E
-:10D7A000067B7DA4FC2733E549CDF9CF455D5328A1
-:10D7B000FFBC28D342DFA99676BFCC7BBED1F50350
-:10D7C0001B7D176986C292D287E747BF2DF431438C
-:10D7D000AB4EB7FEE369FCFBD7DD292EFABBABF8F5
-:10D7E00083F558129FA01F5C4E98B76321AFCBAC56
-:10D7F0004C7FC68C5787F04BAE08AF32BFEEE85275
-:10D80000C29B9135BC2C52FFE7D0D1D991F91CD1E4
-:10D8100091D9FADDF83DEE46FF78AA2733D3A1B8B7
-:10D820008BFF5DCA62CF6CFABB9492FEC5DEE175D8
-:10D830008336095F8CBAC13F3B3D7D9B5D19A3D008
-:10D8400053E6B147A2E3ACBCE0BDF32644BFDF24FE
-:10D85000EF1F4FE3F83D7323137FFFD4484FC0BF42
-:10D860004AE7FA33D9FECDCA707E2816F598C599D5
-:10D87000DA7AAA838F5FECC5BC5904BFA98708BFB9
-:10D88000EDADBEEDE81F1D2DB353BD4A0C7EA0BF0C
-:10D890006F7B397E1846F79E4F47BFDAA22716A442
-:10D8A000C7E08F4F4DD7CBD0D3617DAAABD0174BFC
-:10D8B0004E5FE92139F55B3D4857494F49DFE1F4B7
-:10D8C000E4FB9DA4F7DBF9EABFE07E18A5B3FA34C8
-:10D8D000D2392ABF9AA19EC5FCDD9B1F8A3A161831
-:10D8E000E7391CE710FA58143F540FE138555F8AA6
-:10D8F000FDF74E9E29E5FE4E1DEB7B7522FA7D67F6
-:10D9000099A8D7F4BFEEC338CD862931EB358F3DCA
-:10D91000A0F0BFD3E365FB2D627FB5E8FCDD535873
-:10D92000B709FEED09ACDB84EB5BF3D2F9F7E5B1A7
-:10D930007E732CD8E3A2BEB30EC7C679C09EC5BC09
-:10D940003CB385189E4B1FC0EFB3CCC2EFB36C2223
-:10D95000BD1BADC3F890F45534EEC9DB9501D97603
-:10D9600087A9EE46E63F993764CC7FCE0C1BF41DA9
-:10D970002B0C19F39FBC4E47EAB7CDEAFC10C6B595
-:10D98000A371C5721AFF649DECBF235C3A4397FFF5
-:10D99000D4AAC2AA5B9FDFBC2DACCF6F82BEA4B657
-:10D9A0008C433FD1FF6008EDFAAC99A10B48377961
-:10D9B0006E1E14908A7F87CEEAF61C403F1CFC0343
-:10D9C000A6E68F6C575FEBEBFF07133449A100808D
-:10D9D000000000001F8B080000000000000BE53C69
-:10D9E0000D705467B5DFDD7BF727C9866C42A04B0D
-:10D9F00009ED4DF879692561F909044AE06E76135D
-:10DA0000B62D9405429B0AC50B64101D5E0DB5280A
-:10DA10003EEBCB42421A420BC1E1F937AFBE2D05B6
-:10DA2000677CD631386AA1485DA0459496A63699A0
-:10DA3000521FD280790CD5AAB496577554DE39E7B7
-:10DA4000FBBEDD7B6F3685023A75DC4EE7E6BBF741
-:10DA50007CE73BE77CE7FF7E9745B315C66631F868
-:10DA6000F99386C6585F2DFC79338E83A651C2D8B0
-:10DA7000D2B1725C9934263236374F8EAB4D633655
-:10DA8000631D1E26E6B30403F8D7989BC69B8D5AE8
-:10DA900033318EB1F02255C0C708FF99E5127E4799
-:10DAA000320CF896B9C438B12469F819FB2893E30D
-:10DAB00005345E9E1EC769FC00E3EBEF4D3D6E260C
-:10DAC00060FE77A6C56F3646C0BD68B71EAFF8C703
-:10DAD000A3FF9C22E9196BE2F30F3BBD20EF9851A5
-:10DAE00085E8B9BCFF01E85D41FAB19FD3FB21A4F1
-:10DAF000EF2192E7D39CBE0F013D6D444F37D09389
-:10DB0000FFB75FEFC52A6327EECFDF808F2768DF7F
-:10DB100027723EAE02FE29E23BC4F7C1F9FCE67073
-:10DB200080317C3E8DE37BDD2DF428D164A2DE9F25
-:10DB3000755BF60DC6B37AE57A1BF4B066A57F0374
-:10DB4000D9C9B2223EFFD7A9CF9A8992CC187E06B6
-:10DB5000EEBB9CFF1B7C6E9BFF199ADFE94EC3D383
-:10DB60007A1EF15C39BC89E8CDF09B20F81E077C59
-:10DB7000A3E0AFE07047326191074B3C4AF249FBAA
-:10DB8000A5C4E3E497FA3C72BC8DEC667B29C73FE1
-:10DB9000EAF0E349A41FE47782E43D8ECBEF9F5D7A
-:10DBA0001EBF3584BE947379483DFCCE34E377A81C
-:10DBB000671F367A61FFD4F0888CFEFF1DD62BA438
-:10DBC000F5843D7DD0F9697B14719FCD4FCB77747F
-:10DBD00018EE8FAAD5E979F5DA7D919BE0CFE5CDF6
-:10DBE0004FAA26E2051856CC58BC9F2537C39A7712
-:10DBF000B0A4CA2086C543260B4CB4D835FB32D11D
-:10DC0000E1F1BBC4F8BFC8FF2D9B23F5FA5412F312
-:10DC10008B0CDDFE95B84F69BAD91336BA671FF67B
-:10DC20003F29F80E852D7672A3F1076B412E967C65
-:10DC3000283D16F259F6E057C7A01C969549BCDF5F
-:10DC400048229ED70B25DE7DB4EEB2F43ACFF171B7
-:10DC5000AE84FF29C167E8EA336D74255EA5BC4B2D
-:10DC6000D2F5CDC37DB45F9E4072CBC869706D5252
-:10DC70004209D88F8FAEDDA49A56BFC0BAF530C422
-:10DC8000B7FB597A4C7A95F103DDB4EE8DA66B7D26
-:10DC900058C847D8699ACE7E164A302B7DFBF9FECC
-:10DCA000DCE0F52D7EE121D4DB1B2FF794FB268BE6
-:10DCB000DCA51D2C0FA4EDDB603E90BB2EF1BC60FB
-:10DCC000AEF55FFFBAA0E78F5BFDC9F5F3D153470F
-:10DCD0007CBCC5F725E37F5E36EDFEE7AAE97B3223
-:10DCE0006C89E71F74FE7F87ED7666F13FDF42BEE9
-:10DCF0005BFD451ED4EF9541662481BECBF89B9B0E
-:10DD0000B98EAA55C83FA5EDB39ACF5FB2833577D8
-:10DD10004F1C0C7F53AD8BE05A9F656BBB015FD8E6
-:10DD200073B1296E814B85F9F3436185AEC0DF2164
-:10DD300092FF464EDF89B04EEB8599C60CB0A9869E
-:10DD400025634A500F5A7FCEF1B160882DCECFE0C7
-:10DD5000BB20F0C9750E2FCA6FB4F2F113B1CE8992
-:10DD600030E703E33FC9F311CE875AB02E88F8D5C8
-:10DD70003C595FFE9AE4DAEE16E3C43B14D7FAD2BC
-:10DD80007EE877A4EF4BBD522FDF23FB97F9FA3BD8
-:10DD9000E13F2513B3917EC65C53ACF37E4B7EF01E
-:10DDA0004AF3FA65BC6813FB9548EFD759A4FB4AC0
-:10DDB000F3D588D24C72F2B19402F143F50776772D
-:10DDC000022B1595C69B38FFA5C9C6AFAE060FC876
-:10DDD000E922EDCBC3F67AC4F2FCDDB0AD1EB8B8D3
-:10DDE0002E8E7860652FECDB6BCBD5E25520B7BF6C
-:10DDF000E2FE54517D10CBA65F7FCDECCB5FC3B666
-:10DE00007C3E925F0576C446B942E3F5C1F3FCB5AA
-:10DE10008AD433B14FDA93C8477BDADEF8787B21B6
-:10DE20007F9E73C4BD52D8535E2DAEF33D215F1665
-:10DE300028C6F5D8C4E329753AC45796FE192E189A
-:10DE4000AFC2BF60FDBEC85937EAC18A0EC5486679
-:10DE5000D1FB4176D221F03F96DEBF51B52308AF0A
-:10DE6000C9A68BF801BFBE8F6F22BC8D4D0AD99F0A
-:10DE7000D35EC6D672F98DAD4DCB692CD16F70BC17
-:10DE8000BE69F1F188174099774A06FF0A4177D8B1
-:10DE90001D3F7413E8417B9BA2A33F5AB9716547AC
-:10DEA000298C99E60E8D87CB049414CC6B0F96F9D0
-:10DEB000D10FBC24D6437C1ED8478C25C122826357
-:10DEC0001A5CA7C7D61FC5E97FA930AB70DDEAF899
-:10DED000CE08B235AB71DF51BCDE036E1AF3944D40
-:10DEE00073BE16AF85FDEB99E90EA1AA4176D63334
-:10DEF0000EE86A107469C6BC37D930A8A23C2C94CD
-:10DF00009A8671DD1FDA0CF71B9A3E3E9F55024C34
-:10DF1000DC3DD0EF43664C76B90CF16A03FDE55C5D
-:10DF20006697C1C72DDAE8CE8C91367CEECB3C5F8C
-:10DF3000722BF74FCB6A419E16BDFB91E0EF474233
-:10DF40009E3B80869E8984209FA1DDB0B52E94DF04
-:10DF50004A81ABA76DC95DB7017D97CA5908C75EF5
-:10DF6000E44FCDF077768CC6F963867FC148585769
-:10DF7000ECEBC916F075FF0268DB804FE047539762
-:10DF800017A42C7A7C7298C94298B79527B630D0DE
-:10DF90009388B9D3DD0F74DCDAF4F65ACCFB5698CB
-:10DFA0005E7D1E9078FFDA401DE6B54B4C2197F957
-:10DFB000EE73C8B70FFE43B978526FBEE04139CF58
-:10DFC00056D828C0BF30CA9F4BB9789976CE2A1749
-:10DFD000CD31DE78BA74FBF316F84FD5E6179FFF04
-:10DFE00008FC31954DBD0C7C82035980F45CEA50ED
-:10DFF000026A2981B918F0E9F1F17DDCDBB1FE2577
-:10E00000B4D315412DE4D2913E46F26B146BBCD7CC
-:10E01000A26F7F1E72D5C8C69D5DA877F7F7AACC00
-:10E020000B70EDCBF72226FCF9109F26F4C295F772
-:10E030009F3D1AC069FFA6325C4FCA11E41D980EBD
-:10E04000F7CFF5C17C00BDBF1AE404EBDE63787541
-:10E050001DE07267BFDD8672CA65CDA9E130BE37AB
-:10E06000E862295F862FE03B21E4E2BAACD05ABADD
-:10E0700026D775D99E935C723F17610C7D77C2E8F5
-:10E080001907708BA4DE76F0FD5C64F0FD90FBCA8E
-:10E09000A25C5FE5BEE43AF4D55BEDCEE867167DA1
-:10E0A00075EE43D2B10F7B356E27677B55CA8FCE95
-:10E0B000EE2ABEA71AE491D8E5223B863A6DBF52FC
-:10E0C000007FA414A681FCEF13F4D20FE0F63617FC
-:10E0D000263B4B33FB715FF9B13F2A958C438DCCC6
-:10E0E000F82386452C8CEF15A3FBBE9228423BFDFE
-:10E0F00028EB76A35D3FC0FADDA8FF1FC352504551
-:10E10000FF18F2E0FD465FC08372DCBBEB483EFACD
-:10E1100091D4CDEEC2F3E5642ACCEA279D5794C48E
-:10E1200079C93700A7A4FFF49941F2CB7EB8929F3A
-:10E1300036188E0BEBA23E334B1C3936D5FC31FA28
-:10E140002339D602CD0CE9D83335FE13EE77F9FC2E
-:10E15000F195C64FD17FEE9F629CC0FBDFC07C0F64
-:10E16000E2C3C5DA47A82EF94B857112EF3BFDD803
-:10E1700039F4637A461F163BF441FAB153E8C7E01D
-:10E18000D162B457901B8B5D9F1F3B2BF5E07676D9
-:10E190003BCA07F8F925F97F0DF801B99CC17D9FAD
-:10E1A000C4B0FB966245C4A61E00FA14411FDE5798
-:10E1B000C0BF2B1B7FFC4765181FCF023845EC2BD7
-:10E1C0009691751837BE1EF2F9C6A2BF304F21DFF7
-:10E1D0004EB9406076535D163C760AF5C695F7C396
-:10E1E0003166963898DED775EEB7D27CA11D4126F0
-:10E1F0008F7C28CC745D467E0240C4A8F7D38B0484
-:10E20000E941FB0285F86B2F658DE8CFDBF0D14C3F
-:10E21000D0F7054A37EAFBB722453C5F1AC7F3C27D
-:10E22000CEC26430C4FB2C04CFCA436C494506EF10
-:10E23000B7222AC14F9A66E461E082BC8FF2259929
-:10E24000AF4AB84084E795C3233CCFA8A88C1751A8
-:10E25000A02B0E91DC218F1A4E637F2AE91A29FA2E
-:10E2600022FCA7BB2C7944DFE824C33C24D7C89EFA
-:10E2700037DC1249C7F55B22C8C72E19D78D5B1151
-:10E28000FFDCE18106F4731EA07B7769265EFF60E8
-:10E29000C1175458967D24524AF45537ED6C1D0928
-:10E2A000FB1D0E8FF563DA94AA4906318FE81C0531
-:10E2B00072C8622F1B233C0E4EBB45C00979C9B8FA
-:10E2C000EF83F4DB0DEB6099EFC23CA084E7010F14
-:10E2D00044CA689ECC07003EE101B8F00493F0B454
-:10E2E0008FCFBEDE03429E99781B2A407FCD5833E4
-:10E2F000C58BB88827AFB51867064029FB5A6274EA
-:10E3000005FFDF130507774A4BE487B2C86F61DD6D
-:10E310001E1FC6EDD6F255BE7ECCFF8C08E16D5CAB
-:10E320001E3E3360F1B79D256C0CE601F736DC79B3
-:10E3300066C0626F3DF99C5E8C33096F06EF52D464
-:10E3400013A0F768D89B9A0B02CD0DB2A457A1ABCE
-:10E350005B473B88E8F43C6EAC6426D6E3D5673572
-:10E36000EA7F15B234FC26D89A483973235DF160F0
-:10E3700092E1BC5C18237C7CF6DB04BFB05A6509D3
-:10E380000B9DE07F56901E38F2A51DA86080B77DDA
-:10E39000A692DC0C781B826B28FE6C9A934BF7617B
-:10E3A000DDA417EEDF33BE89E296CCAFDAA3D1103D
-:10E3B000C5A7EBCCA78E4D8D3F84FAE809A6FDEAF0
-:10E3C000C34467C6AF6E8870BFFA19BC4AFFB1FB81
-:10E3D000E86BE43FA00621397782BCBF9B651F37FD
-:10E3E000093BE82CE47AE87CFE55A1AF7FA988B709
-:10E3F000221D06C4B4E0946BCF37DB65BE29E478F8
-:10E40000BDF201797C2962F1CB208F2F679303FC49
-:10E41000DAD05FA8D25B3CAD68A8FF3962F824333C
-:10E420009338CFC79A0948F5C719C6BBC178520CB3
-:10E43000E72D13FC7D507FFC1D486FB85F339E8E27
-:10E44000505DC8F559FA65B04B1E7FAFD16FF7BA72
-:10E45000C09F023D1D786B66E6F921B1CFCF55997B
-:10E4600087701F2794F856A2FC1F558CA05FC5BE6D
-:10E47000A7D9887E84E9536CF306AFB389F0F4958D
-:10E48000996BD1AE99BEF80AF09BC5BA824F9DF345
-:10E4900001EB7E25776C667C25BE7E10317E86F290
-:10E4A0006A35E3BF40BB7BB9DCA52714BA921D7661
-:10E4B00056E724151807A698AFF37D043F0AA83B3A
-:10E4C000CBDFA1BC68E17C85F2B4853EA8E0B2F860
-:10E4D000C9F322DE2CD4F97376DA085AFB1D855174
-:10E4E00097BDEE059530ACFD8BA86B15F6E5653C48
-:10E4F000C3BE49367BBB28EC49F5BE5D827EF5651F
-:10E500007776BFFD4EC443704A54F42544FC5BEA61
-:10E51000E5F5157B11E8B3C4D7E7AA6AFF8FE2627D
-:10E520008225144B5CEC1B7D91FC1D3DB1DC5F280A
-:10E53000FA4EACD78E47F2591465B675415F5D51FE
-:10E54000DEC750A396E74B55C6FB1E3D7679013DCD
-:10E55000BE28AFBB9B94E959E919C7A667A1E79408
-:10E560009D9EA228DF97E7AA8C22C407F17938D2B2
-:10E57000D1510BFA9745BEFB26D5DE84701A4B7439
-:10E580009495BE6FDE7A0BE291634BDEAA47EDFEF7
-:10E59000B534CAFD6B5994FC4AF6752B85DCAED7B1
-:10E5A0003F5CABDD6F73D8BBBC76F67F2FAF12E854
-:10E5B000F07A139F267B9D7875F6FDB15B7A462332
-:10E5C0009F87847EA26FC77CC3D0793EF26094EBB4
-:10E5D00071784292E09E1D22FF48C38160B02F37C0
-:10E5E000541E32F31AF390CED97D7988A7F5DDDD7C
-:10E5F0007958C73F3B509B350F3954D245743AF395
-:10E60000900343E4216BA23C5F3DFABF1ECA2B6A14
-:10E610002EF0385F73A14BD5413FD745B93F9B39A9
-:10E62000D0A39AA027359887009E03220F41F84D6A
-:10E63000A0BA9177BB54A46BE6851E9A570363CCAE
-:10E6400043660E918700152AEADDFE9ACE5771DFE8
-:10E650009CFCBE58696E885AEAADEAFE1E7A4F22CB
-:10E66000E775966FCE33699FED7A736C2AA73733BF
-:10E670008FEBBB136E28FDAA53FDE5D81FD8CA72D5
-:10E68000432887F7728655B2025ED7605EBC15419B
-:10E6900081EFADA7F39209ACAB7DFCF9677387ED11
-:10E6A000C6ABF43F3E6117EFE5DC92147590510064
-:10E6B000F33FAB1AA9B9100FB68EFB6280F3B39E7D
-:10E6C000EC6883904DED4E8DEAE93B827C1F64FE41
-:10E6D000F5D25285F24340337F01C0CF10F83DD3CD
-:10E6E000787D58AFFA096E5B39CF23EF485CA4FE02
-:10E6F000C5CC7E8FAEC37846FF1A5E2FAA3F3C9EE4
-:10E7000087F9FE4734A6C2FDA56DF156D2CFD31EC0
-:10E71000EA67C8FE42556F37C92D6FC063EB73E4DB
-:10E7200082274B59F2168F63CCD4E505D9FC90BCF7
-:10E730003AFB10FBA2A2FEAC64932E835C2EB14781
-:10E740003A9037EFF8DAA34FB1C1F3657FE1C149E1
-:10E75000C633A81FE3DCFDDF7E06E475E02D0FF570
-:10E760002D0EECDA757725F097E8D2A8AF2BEB19D0
-:10E77000905BD122AC675106D4973EB90AF5F2609E
-:10E78000BE1C834303BA0FA6DFD77F629561199F32
-:10E79000886E398771EFE00809FF269F2FC789FE31
-:10E7A00055785EE3E0283EBE14559F4AD0FEF66BD6
-:10E7B00054476FFCA53F9B7F3C5967D7D77BAAD7AF
-:10E7C000737DBDC23CF0EBAF47B3CCCB59606EABB1
-:10E7D00000791C1C70D1FB21A8B352981F3C38C98A
-:10E7E0007C03E11F3DC5E57AF0AD8702B84FDEE15D
-:10E7F000FD0F67F3F3BF11F1285DE74DE6FE83B12E
-:10E80000010DE3D68E39CF9EA884754ECE1C3F45B0
-:10E81000051640163ECC97E57C6F1DAFE332F4BD84
-:10E82000A2AE42FFF3D6B9866CF65E15357F1FB5F2
-:10E83000C1F3F7A2AD5D1AC9BFE8D8BCDD78EE27F9
-:10E8400055D3D5A3C1FE1EF88D8B619D72A042D415
-:10E85000E143D11502BA8AAE8AAE5D33B2E81BD06D
-:10E86000E5A91B3198AE97EB18C9E7C54AC387CF16
-:10E870009D7432D1C79C25FC7DCE9B5FA4BEE381F5
-:10E880007E17354F2E0DEC5651F564FFBBF354192E
-:10E8900066406CEEFCB32AAA94F9886AB3BB19A748
-:10E8A000726DE3079A87DBC6CBD68ECED821FCBF2C
-:10E8B000383AD636F6066FB78DC36CAA6DDC30FFDA
-:10E8C0000E1BBEBA40C4369E17BCDB067FA7BEC473
-:10E8D00036BEBB7C990D7E4168B5ED794D60E7167B
-:10E8E0006C1FC5274ED68633D2C7C975B00F79BD08
-:10E8F00006E9E3A3A71E0AA05EA46AE26350DFFA5A
-:10E90000F27B4AB07FFD923B7BBDF6489D2AE377C0
-:10E9100009C67B83F17A4DC287CBFA6D7DF9D57537
-:10E920003C3EAFA853B2F6099CF158C66119979DB9
-:10E93000EB3BE3AE33DE2EBC6DB78FF7FB79DC5FCC
-:10E940002AF4A0B5FC677EACD75F6AE07D84CE92E6
-:10E9500038F50DFA447C3EBAF4BE31F85E2DB7DCD2
-:10E960001CEE2DCDC4EB487992FD12FB3C81241B9B
-:10E970005B81CF936C7505F5A5B5C8447E7F82B8E1
-:10E98000BF06AF10A7EB2D7273C6DFB06FF20B0599
-:10E990002C93AF34FCC18816007D7735EDD38AE126
-:10E9A0001AF11FD6AC7EE864CDAF8A8788D39FB4B6
-:10E9B000DBC72B641F070616BF6F1C78A385F7DD26
-:10E9C0007FD0E26329E0EF744B80AE3F6F09D2FD48
-:10E9D000575A74BAB6B794D335D512A2E7AFB65426
-:10E9E000D3F5F91683AEC75A62743DDE1227B89F7D
-:10E9F000B634D2F5C51693EE6F1776FA61A1C72823
-:10EA0000977D85F8519742726DC0A3BAB32E18AAAC
-:10EA1000D5CF835CFF239B5CAF359EA46ABA47A326
-:10EA20009E41BCCA6A4FDD7532AF4FEF37D125F337
-:10EA300061AC5F504F649F0EE8FB26D2E7C5FE5CD9
-:10EA4000D1F5D37750E1741D2CE4FD1BC4B3281F0E
-:10EA5000FDF9D7E2B5E4CF474C267F1E649ADD9FCF
-:10EA6000970EF2E72BC9EED871EC93627F91DE53DB
-:10EA700038FA2005F53ACD937D90397FE07D902BD3
-:10EA8000F10F7C1F47BF25FDF6D5F2EDE4F7D85412
-:10EA9000E365C423E3F3A0F861AEA3F8512D6C96AF
-:10EAA00069EF529E9827F8D9716E7101FA172F12EB
-:10EAB000C8EB748355E33E33791E60F7DA92C17870
-:10EAC000DFA8E9A678BE2D9DE7BC4D79CCE0F865BE
-:10EAD0009703E642D6F80E7278B3AE6AB07ED6A936
-:10EAE0003FECDF0CF1F9603FE37DB269FC7D9D8C6A
-:10EAF00083072FF03EC6254D4932D8BA5AD6DC35A9
-:10EB000003AEFBBFC08AE3F8BE698C2BB41740F399
-:10EB10008E1CD07D0017EE3787E7C0F3EA540ECD88
-:10EB2000AB9D3F3989E386F8DBE49F6A357B9CC463
-:10EB30000C351D77A80956E418DF9C8157717FCBEF
-:10EB40003263C0BB6EAAA9D5035F8B2F36331DF08D
-:10EB50007B4B989BCE870C8EEFEB144B9F4D63A1A4
-:10EB60000EE443FBDC36FE5ECFA16F524EB2DF26D1
-:10EB7000EBF0279911C0F59CF8DBC47B17E7FB96F7
-:10EB8000F72ACC20C22B8163F4BE85AD65FC7C8462
-:10EB90000BEA1394DF304F726FE960BDDB3FE5CEC7
-:10EBA00031F564DF09E5C6D4ED5D0AD5EDA26E62EC
-:10EBB000FAA75CD63A46D64DCEFAE831E167655DF4
-:10EBC000F4989B51BDD5AEE486761393CD93F8FBB4
-:10EBD000B8E61978ADA9977EE90BB63AC91FA83FE8
-:10EBE0003330355B1DC7EB11777ABF4B02E7F33249
-:10EBF000FBEDF798413CDFD83E79DD5756A2BC4685
-:10EC0000F8E8FD26D3E23AFA9BC7F1443FDA7320D5
-:10EC1000C18AA767F65765DA79ECC77640F282EFCA
-:10EC200077E3F53C9F70D2E5BE46BA7023E93DB567
-:10EC3000B4771617EF25791EE913F7DB746EF70C1E
-:10EC4000FD96E53D799BDFF0052CFBF828CAD93B02
-:10EC5000F4BEAAA56D01EC6777F95D64A71DBAB68D
-:10EC6000B514C61D7E8DE729BA2B96ED7D5247BDA2
-:10EC700022F8E67405045D6A7831E53343ADD7299F
-:10EC8000F65D8E73279A06D9951E8A63BDDBEA2F3F
-:10EC900056B0CF299FAFAA57C4BE77911CB68AFC45
-:10ECA00028B7BC3BE5427D19B5662A8ACD07F9CE67
-:10ECB00079B8EF9BD84DF951FB089FED7C96BC3E8F
-:10ECC00026F06D75876254BFE7BB18D6EF5B4BB378
-:10ECD000C7C387C5FEB6EA53E2089F00B98C570642
-:10ECE000C3AD11705BDC5DC100ACBB75FCBD74DEF7
-:10ECF0006BEB1872356CF48F6F7B6A937FB07DC0BD
-:10ED000098F6CF1D60F23DBAEDDC43ABDED0B81211
-:10ED1000D6D55E6121340B6937DB313F81AB7BD4C3
-:10ED2000E246D4DF4BD5B92184AF535F4CA01CDB46
-:10ED3000438CFA165A61930FE97EB444A3730E9282
-:10ED40005EC8BB77A3FFC80FB96CF9794175AEC334
-:10ED50008FDAE981F548EF86DA5F277D94924F7963
-:10ED60001FF842B3319E05DFAB697BB7EB97FB0A17
-:10ED7000FA75257E6C71B22413278F1CFBD7D5F84A
-:10ED8000BEE371C69F3F7F6C0ED5EDCEF18DB2F321
-:10ED900056ADAB11F7A5759C87F4CF397F6B29A7CA
-:10EDA000ABB57E965837A0A0FE6FAF2ECA413FED9F
-:10EDB00047876B91EB0B95E6CFEB2D71B830DA4CB2
-:10EDC00071F8BBF58CE4E8D7E38171A017FE5E15FE
-:10EDD000740AE4EEFAF31FCEEAD72E47D66590DE2A
-:10EDE000FA59E6F76790CB30C6F5C4CF1EEBA1B851
-:10EDF000C436109C94D7F65B4F86526CE875FDD5EF
-:10EE0000F63ED307ED23FDA93EBF98E49CC37250A4
-:10EE1000CE97D8230AC5E1A841761748FB557EFE58
-:10EE2000A4580E811D1C93CA2999FE12C3F71768B6
-:10EE30005F26A33C8520478A57573AED0BCD1B2D03
-:10EE4000D0DC8C076354D47FEE772FB1B7F8FA305B
-:10EE50000DCF9F280917C5CB5B51AF01AE94997FA9
-:10EE60003C9BE55CCE9840D3BED5702D9E27FA62C0
-:10EE7000829F2BC943D2FDB7D25B19E79DFD50D9C4
-:10EE80002F7D06FBA5CA95FBA14CBB48729379ACBC
-:10EE9000B33F0A712D0FE5FEDE048D7592DC791EFD
-:10EEA00090A9D74D9FF51C9D8C97ED81C5B63EFB73
-:10EEB0000CA94B0E3EBF7785B8D8D90B7E13F3E172
-:10EEC000E066EAB3EF3FBDEA38D6E397821E9D596C
-:10EED000FC7F7BBEFD3D80C4FBF979A29F3EAA9ECC
-:10EEE000E17CADC76478FECE130C515C6855B2BFAF
-:10EEF0003F689D27F209679C70BC67F99F1C7FD211
-:10EF000053C6D2F14315FE59C657A641141D699D3B
-:10EF1000CFFDA894C77E9157761EF9049D176041D6
-:10EF20004BFFB62CCBFACEFCCF30F4C0F44C3EAA4B
-:10EF3000F4F33C54AEDF2EEAE7D6D37C3F72C5B97A
-:10EF4000A141FA5A617E7A1EF67FCA5D8E3E95DD3A
-:10EF5000DF38F35AAF8F25722DFE0FF2DA8DF328CA
-:10EF60001FB1E7A5C3638C9FEF293419F6712241C5
-:10EF700053C5BECBF4DE669501DF334EBFFF7E2C5A
-:10EF80009AC7F39CF6F25571AC7F641F79C79CBB9E
-:10EF9000C8BF421CDD3ACF52C7CA730B1FB4AF249F
-:10EFA000F575BAD847896FD0F992D91BF8FB9FD372
-:10EFB0000F9D407DDC0FFA8871BE3D3FB1AD02F37D
-:10EFC000935754B6571FDC8772F225FB49FE18D7BA
-:10EFD000534FB0FDE85C97453EFDCDAA4EF2311887
-:10EFE000BEEFD1C4FB1E67FFC8EB359A317EA76A1E
-:10EFF0008C466BFF58CA6D91D0E7376A9AE97DD489
-:10F000003343BCFF9570F89918D6D3B21F553AC94F
-:10F01000FC3EEEEBF4D87A15DD48757C3D9DA3CC23
-:10F02000FB77467520CB55927B61A923739EA53A49
-:10F03000F1F74146FD320FD689C55817F23A51D63D
-:10F040009FD24FD4A94F7794E1F98C5E8DCEDBE54A
-:10F050001DF9840FF3DE70EF6AAAD50C65691EEE08
-:10F06000A33C7F24E9BCDE3AB30AEB4CCB7B928C09
-:10F07000DF88FD02F5A0B325FE8B28E8C781168343
-:10F08000C6ED2D8D74ADD29206F253554E951B9B55
-:10F090003500CF2D7454F5C46CE31D95E619D4CB1F
-:10F0A000BCF2B8EDBE3708F82C7A0175EE3992EF54
-:10F0B000692E4FCF7C85CE152CEC675BB86DFFD3E6
-:10F0C000F8212D7663FC504EEC7DFD107F5FEAE960
-:10F0D00017EF4B1DF6B6679E4E7690B63B7C6F4A97
-:10F0E000712E41F3E9DDDF4CE067D827B9DFCA9C18
-:10F0F000CFA0EF12C3E27B693D366B0FE6B3EDAFF5
-:10F1000033F99DF01EC3F21CFE6AC2EF440E63B1D8
-:10F110000B79E6E65861137D4F2DBE87893416962C
-:10F12000F4B1CCB945A7BCB6C45CB6733161C6FBBB
-:10F1300062F2F92763A26E03765C96730FB978EEDC
-:10F14000214BFEDE24F0350B397578F8B983B98E82
-:10F15000EF3C66C6785D30D4771E9F1378AEF45DC1
-:10F16000C76201773FAE5745E722C331A4372EBEB1
-:10F17000CF1274CCEA4DB60EC32431C8B2E2B93313
-:10F18000C6CFEFA562FC3CB1276868B82F80EF6E50
-:10F19000C2D7C8CF59CAE7B32EA49F2F243D69E038
-:10F1A000CF675D30A91F24BFAFBBF3F8D83D9BC626
-:10F1B00065CED7B4633FC28FDF99F0734BBB04FDBC
-:10F1C000CEABFCCEE4DE8038A793B8758F81780C87
-:10F1D000FE5D65EDF10903098DD6FF18D127BEABA1
-:10F1E000992CF885FBAB882EC7BF0FF0C0F1E01E4D
-:10F1F000F13DCE1A9AD7CCE9CEFC7B07A13DD6EFE4
-:10F200007B261FAF6C12F0EB087E2D87CFA20F423A
-:10F210001FA7ECC15EEA55E0FB0CD1B79CD3571693
-:10F22000D3F977590EBD05B8CFD3BAE23B9FDEF8CC
-:10F230006A1FFAF3CCF7FBB7D17A5721A736C2631E
-:10F24000CAF59838CFC4ED42EABFD4876F08FDBC39
-:10F250003DA648BD7A8CE86DBA61FC7F89E8717C77
-:10F260005774253E2A2AE34FD0BC60FA5CF1D78957
-:10F27000AEEBA4477E07E6B48BEF0BFE61DDA7691A
-:10F280009D92109D2F8275BF7D23D605BCCF101E89
-:10F290005F1AEFFE58767FF381F0B292E2AB3A1F2D
-:10F2A00022C7FF0F94B0BE363046000000000000B9
-:10F2B00000000000000000001F8B0800000000009C
-:10F2C000000B93E46660F8510FC181486C62F11A3B
-:10F2D0007606866816068699AC0C0C15402CC74934
-:10F2E0009AFEE540FD8B80782E10CF00E2C940DC0D
-:10F2F00007C49D40DC02C49240F34480981F88B943
-:10F30000809815881980F8370703C3370E8439377A
-:10F3100080620F48B41B84AD7810EC3340FF6F045B
-:10F32000E2AB6484C3281E1E389D9F81A15A00C190
-:10F3300017104495CFE047B0B94429B34B1AA81F22
-:10F3400000656D40B4800300000000000000000074
-:10F350001F8B080000000000000BE57D0B7854D5E2
-:10F36000B5F03A8F79666672F2204C4280134830CD
-:10F370006A8A03840882F52420C696DA9152C5FE73
-:10F38000D60E34224A2051B1722BFD726002040164
-:10F390003BBC1414E9E00D8A8A362256ACE83F20C3
-:10F3A000B5B4B56D6CB9D55AED0DB5AD2F0C88520D
-:10F3B000FCFBEBE5EEB51F99734E661250F1B7F703
-:10F3C0000F9FEEECB35F6BAFD75E7BEDB577DCB232
-:10F3D0000FF287029CC49F8B00EE7003C0D8743A72
-:10F3E000EAB66FCC7DA49AFCFE7FDD916D7ABA9E61
-:10F3F00048878244EB01180045001779C9AFA4DEA5
-:10F40000A49F1FFED37985007B41010FF9945227F9
-:10F41000157C8DF4B3F7238860B9FCF3406957007D
-:10F42000DB99B4DD9781B54B95E9A55A156640C6C1
-:10F43000EF8697FE4EFA19BEB999B43FFE6180B6C9
-:10F4400077C22152F84886146F737218F6AB7ED0DB
-:10F4500055C9F3654006070EEF64809A34BCFB5F24
-:10F460007B83C2BB4F25F0EA19C6F712F80BD3F025
-:10F47000EF856FE4421583DFA849C37FBAF0D0F966
-:10F480000F0058DEA23F5DEE0258DD024F97570095
-:10F49000AC6CF1D2FCD2168DE6E32D619A5FAE9290
-:10F4A00026040FCBDB216992F6A16A525FF447FE76
-:10F4B0000B54796D79772169EF4DE7D540D896F7F0
-:10F4C00096EAB63C01E76098CCFB1C3E9FA52D0454
-:10F4D000071E1CDF0BC65958FE6D8A171FC75B3C01
-:10F4E00038E2CA61042F6D2F2A84D2002EDD988164
-:10F4F000F09507DC7A92B0C63981D9536124193767
-:10F50000140320F5E21B00D612B8CF0E4C790B4243
-:10F5100000F793FEDB48FF4AA8ED650F295F51E62F
-:10F52000D615C4CB76F52F5D640C2FF987783B6B2D
-:10F5300023CBA7E745F296799E0D9672D2FE977976
-:10F5400077BE2C1138E2E56EDD23A5C7E9A14B3F5C
-:10F55000FD5724EC7967FFE5BA51877C2AFAAD8024
-:10F56000E8122DF0C5EDF71C82DB82FC74BF629CB3
-:10F570007EFB25E48F92B6151B21992AEB3D4EB9EF
-:10F580001EA9374979F946159265EC7B219187725E
-:10F59000F62B2C2FADF3C7AA7AC303D67186A5E943
-:10F5A00052AEBB67CA842FCACBAF982B11BE8184E1
-:10F5B00085CEC31883A2BCFCB045A3FCB8BAA59203
-:10F5C000A6ED2D5A07959F8F95191D55BDE5F0AFF6
-:10F5D000A8A748BB3B5C40F9D0DC06C96D12F61702
-:10F5E0009D3193E4578D2A1A7DBB8EF91932EA05B5
-:10F5F000C1DFAB249DF2B749F81BF59F533E56BBC4
-:10F600008CAF607F2B46C9D212C47339E3F77257AF
-:10F61000CA3B1CFB4D0C1B65623F91DF7561BDF25F
-:10F620008A11BA42C63DBB9CF1FF2FC7DEE9453DBA
-:10F63000D833FF85451DE56300721D7CA09D221F08
-:10F640006813FBE60331CE672D0F678EBF127DF284
-:10F65000D7AAC8DAB7506FB49733BDE184AB7868E6
-:10F660002A1C0DF4E6B7F272C26748A748DF7CE6B1
-:10F670004C37B424E175C243EB5AC294EFD6B4E8D8
-:10F68000345DC9F9D0853C554CF29C0FA1B09AE687
-:10F69000B3AE57B098AE4703A6272146E05C87FC7F
-:10F6A00079017E5F6A18A5A479A5C8434A26BA7F66
-:10F6B0000D9697D0BC01A5C89FA2FC31D320EDF3D5
-:10F6C00079FD29D263669C20699D8FE5EBA56EC309
-:10F6D0002CB5B65F691813D3F5493E55576EED8FBB
-:10F6E000F45F6585E7395A5FF4D7201D324C925F8D
-:10F6F000E363FDB5492F7F2EFDDF2E25C2B8D0ACC8
-:10F7000070F473BBC89B09C3A84A8F53B6F851C3A2
-:10F71000B496C3A3B6F29AC509D32478BB0BA2C38F
-:10F720002542DFE2A9D13010FAFBA2491397DA345F
-:10F730007C0CDFE9F9DD49E1F597B3F22AE9F746F8
-:10F74000DC429F5AE93726C22FEC1B85F3ABFCF352
-:10F75000D29B5F20FCAAE4BA23D4CE282499F1647A
-:10F76000BCE931D0091C723806A80F94B0FA77AB07
-:10F770001C08FE23708EA3704E8ECEC802A769852A
-:10F7800053C0D11FDC028EEC7CCAC677F253DD6514
-:10F79000E37E3B91B0B8AFD315413BAF00F144F4E9
-:10F7A000007CB4CE7091EF05D308EE754AB71930DE
-:10F7B000BC77BF85534B206959C73F6BBA0EC7FC56
-:10F7C000588AB7EF4863D3F425F999563C8EE3F590
-:10F7D0009CFC27E6E7EE35BFEFDAE6076A221C0D50
-:10F7E000F63FBF35BEC88C68A077BD5F4ACC8EAEF1
-:10F7F0009B32EEEBC0C6030FD15F7938DEE8F478B8
-:10F80000795F21E361676A32E378F993C978DE337F
-:10F81000874FA73C0A787DBDE05D6783F776179137
-:10F82000DB0CF43FD3F09EAAFCF989FEA5F257D970
-:10F83000B7FC7DD6FDE5E1AF849FDE57217511C190
-:10F84000D7828BBD49534AEBB9CF1B5F055844E8BB
-:10F85000B7E0D7630E5D246386F0F597D2E3CF97C8
-:10F86000740A7736FECE361F80A4AD9FFF57F3C9CA
-:10F8700086D733AD874E55BF2EF9839FEEEF969610
-:10F880004312E569E9818BE93E73E90B930602E9CE
-:10F89000C7D5762E18645279DCCE588A7606F63FA4
-:10F8A000F9D4EC8CDB5BA0A395185D4F84A2D42E19
-:10F8B0005A2A016DBF8AD86D4962BF54BFD8EE9DE8
-:10F8C00019A076154D97BA80DA31D52FEED726914B
-:10F8D00029F82BF24721EF2FF589EF07EBD1CE5D09
-:10F8E000594EBE13D6581A64FD91EF51AC9F53C1C7
-:10F8F000BE67832BA792C063C1BBCF9D8C65D28F9F
-:10F900005F96658A9F4DDCEE5A8D761751C83E7F13
-:10F91000228676B5BFC8ADDF27F56E37436676FF22
-:10F92000FA8A9F98E8D25881F61B99FFBECBEF87E1
-:10F93000AE2A5C0713868CED23CC35B0C9B1DE0747
-:10F94000D086A3EB66589A44D64CBF23BF5AD4370F
-:10F95000F55AB4D74295ACBC76C985B5716B399C64
-:10F96000578BEBAE28BF66C9585A5EEC8DBE3C91F2
-:10F970008C5F4CF4679CE0A9584D48CD949E99F952
-:10F9800065FDB5DE194902C3FACBEF2CBB36039EE9
-:10F990000815299D45BEA4C12E5F9B38DE56733CD9
-:10F9A0008651C62D7ACDC7AAF6E835DF594CAFF996
-:10F9B0002B138B11CF250D10413B7B3DC15FCC320A
-:10F9C000BEAFD2AEDF8A55FBBCCED47CEE02E32ABA
-:10F9D0007940F6FE9DF27517C46662FD62BE8EFB2D
-:10F9E0002B9352ACAAFFF93BE79B6DDE5FE5F82451
-:10F9F000E3CCCF34CEE78597E20019A7FAB31FC74F
-:10FA0000DF60D793A78A77686C37705F8DA626EE84
-:10FA10009B7D303992A2FBB9DBA81FEE160E3BC4CA
-:10FA2000366968D7C40132EA33B5DC9DF6A7E1FF39
-:10FA300094AB7333D145A40B5F7D2F6FBFA57E526E
-:10FA40000E16FE3D87FC723E9C7F5249B707EEEFD3
-:10FA500053051C817CDBBC4EB41CCDDB4FF4C61AB5
-:10FA60006D1AD5C7D9C67B90E8D11491AF075ABC9F
-:10FA700034DDD6A2418AC8D9BF1379C3FC56227F90
-:10FA800098FE88EC1731BDB72542CBEF691947F3D3
-:10FA90009B5A0C9ABFABA59EA61B5AA2F4FBBA9622
-:10FAA0001934DF83CF8FC87835946501EDAAB36729
-:10FAB000244DD463B003221504BFCBF1BB05FED5A2
-:10FAC00072EDB332FA3D67F8A87F23C8E7E987A44F
-:10FAD00081FA1B0E2AB00DB2CFEB0E3EAFAF28322B
-:10FAE000F39FAA957470414FB91DA85FA5A89AAC61
-:10FAF0005B44E5E65ED89A8FFC5E54CDBE07038476
-:10FB000091C877A51A52BE101D5AC5F61A6FDF3676
-:10FB10004EA6F5566B2A6DEFE48B73A193AE33605E
-:10FB2000782308A777BCCAEA57B1753278FE3EA49D
-:10FB300020B44D94E9FAB9BA9CC1A168767E09D681
-:10FB4000DC0768EF879561741EAB2F50370D473681
-:10FB500080CE9787937E3690AD0DAE6B0F6CDEA98D
-:10FB6000CDB4D0D9AB30FBFCDCE93BA315088F4A00
-:10FB7000E49A8C5FB8D99FC47587D0434178737C71
-:10FB80006C3EE7E298048EC24590BCAF2C5D1EC867
-:10FB9000E3F3D18C5AEA9710DFB9E23957EF48C93D
-:10FBA000D86E2344EE8374B94FB433ECED7CA29D40
-:10FBB0009942DC42E12A7B3BBF6807B5B6767ED12D
-:10FBC0000ED61A74BC0469A7A7CB15DEAE47EE2B80
-:10FBD00035D92A674A409799DCD8E9948D7F34E07B
-:10FBE00074D8674A27115FD52C2F49DEB69332AE01
-:10FBF000B3763AF951CEAD7A2660C913D245517623
-:10FC000071BFC6E9953433D36B9D1AF94539CEAF30
-:10FC10004AB5CD4FD0699D97D3D1F467A4D33A8D1F
-:10FC2000D33106363A0B7AAD13F46AB4E34FD06B96
-:10FC30005D167AAD13F46ACE4CAF7559E8B54ED067
-:10FC4000ABC1DE4ED0CB490FB1EEA4E9D62C21DDFD
-:10FC5000CE143D9C7AE10559A7DFE5F6A39D680F18
-:10FC6000162D50D93EA9B21350CF43697E3F76ABD3
-:10FC7000C9ED93665A7F2DFE2AFC5F28A76E96BFBA
-:10FC8000267EA816EDF07C4994EFAB457F5812CB49
-:10FC900089FD7573FC382D7F528EC614DA5F1270A1
-:10FCA0003FE2C497279A848D04A40A357A6905FA3D
-:10FCB0002537CB11F4DF0A783C20F004FCFCE6D4B5
-:10FCC000F81F80E10BC13B39FC94E0BC45A1F84C26
-:10FCD000323C39E124FBCB8D645F3384F3F710F3BE
-:10FCE000CCC0090D6CBDE8599FB99DE482CCFD5490
-:10FCF0006E966D7C3362BDDFC637E5ABF26DE5C352
-:10FD00005A4B6C797DD1305BFD210BCEB195973686
-:10FD10008EB69597345C60CB87AFAEB3E57BF10BC5
-:10FD2000CFB72BAF2CB6F18B39A20EF76D496074AB
-:10FD3000D81E1F5187FBB6FECABF7E8B6A7809FEAC
-:10FD4000D542375D870805297E04BE723530DDE86F
-:10FD50001F280C242F21E57ECD30A93F403300F72A
-:10FD600073B216A37957D82E5F5F4301227CFAF550
-:10FD7000AD2A780BFBECDFF824FDF7372F27BF887F
-:10FD8000F55D2964EBEA06B25DC2F33593E8C76D11
-:10FD9000645C97C6D67597E01FC2CFA8573455E26A
-:10FDA000F27B7A72367CA31DDEB2843D3FB4CD6116
-:10FDB000079E227F7F5EF2DB1FFED641C4544E01B8
-:10FDC0007F1155E2E7D5A727FFA58D76FC9434B8BF
-:10FDD0001D72E2D0E79F33FE5AC57A01D13AC44B77
-:10FDE000CE7AE64341BB2B935D21F865C3F49BFCBF
-:10FDF000D6F50CACEBD4B0F43834AF64CA7FD1F88C
-:10FE0000A4AB16ED8B9C8564FE65CC8EC9387F4E05
-:10FE1000EF755365BFD50EFBA2CF3F4DE71F9C5634
-:10FE2000FB700FBCA51ADDAF89BC635FD6BBBDC933
-:10FE3000F44DCC275BF524F9A954ABD135E98F20DB
-:10FE40009F9DF08546422ED91F7A597AA6F76D0FED
-:10FE50004C67FB12F3D59C6405E293C771AC7DF54A
-:10FE60004B4984273955863BF19C79B29CAC20F9EB
-:10FE70005BFDA1FB10AE6F2AB15BD50108EF9024AA
-:10FE80009E1783AAE74D0B5AE6C9ED2231FF6CF6A7
-:10FE9000D192D69BEDEB194CAFB3F2E35DADCB69DC
-:10FEA00039B13B5A554AAF2F8A7D9415CE4DEA178A
-:10FEB000D83E12E703CEF6FF2AF6D101B57189DDEF
-:10FEC0003EDACDE8008C0E2FB4EEAE3B9572611F8A
-:10FED000F9036EBEAF77D82F95C43EC2F3A300B727
-:10FEE0005F2A93D45EF1552699FD5229EC19FB7ACD
-:10FEF00076231AA063D3F6511FFD1B9FA4FFFEE6D5
-:10FF0000956D7DF705847D9460F611C135C69928FD
-:10FF1000446DF846225FD8D7F76A5796F5FD7F8C77
-:10FF20007D94597EFBC3DF3A4830FBA81FFC4DCFC0
-:10FF300086BF7F71FB68BB0AFF9FD947D9F8E47F72
-:10FF4000B67D94A6F36763E738ED1A61479C69FBB9
-:10FF500046D827C48EA1769649EC2CB4734EC89A25
-:10FF6000EF4E32CF5B15DD877EEAB55C5E17AAD116
-:10FF7000352EBA7EEB7968676C447D3E80EB59B4D0
-:10FF800083023C3E4F8DC0B42F61FDD84697E51CDF
-:10FF90004209E8793DE7365F203C103BAF522DB473
-:10FFA000CC9FE345E061972B8FD3BBF9FC289BD70F
-:10FFB000E3140FA04BD4DE52751FA64FF3F58DAEA0
-:10FFC000C7D5567CB0BC52AF27511E48FBA75D0376
-:10FFD0006C78F1D9F042D621361E28CC9E336DF1D3
-:10FFE0006CFE6A4D42BF39C97622FFD2F3721D20E2
-:10FFF0000889FA11A4FF82D8B21B311E33F8EAA592
-:020000022000DC
-:100000006F615C6341D74C1ADFD85A35FA401DA99D
-:10001000971BD12E9FA2E3BA0AD4CFB8023BA3E725
-:10002000A110AF0DF0731C22DFBF597A9CAF9B0665
-:10003000D8ED725957853F69587679213FD2494F9B
-:10004000EFF6D9E4C365956B2A9F379D9A7C4E6580
-:10005000726D927FA82FF21CFDE41A8EF304B0E4B7
-:1000600049F9879C8F8985F2B98CA7C15AAF4EF8A0
-:10007000CD552E6B181F990B5A1EF29F7FB20A297D
-:10008000F4BF141E35D105DB1F5D5AB91F1D25F0C5
-:1000900072CB7E22E866F21A9ED55AB68CF47BBCEF
-:1000A0009AC5DF1768E4BFD1BDE7B392CB574FBE07
-:1000B000EA3E7A6E1A27FC340CF9B84AA6F70856BD
-:1000C00094333D2EEA9DE7966CF7082CFB365DAD28
-:1000D000E1F634C18F522E1B68077C5AFE503E2138
-:1000E0007FE44CB5DB05A74BAF89FC5EC5A9F2C721
-:1000F000A71D4FD0B5B75C2DE6746DF0A2DDBF2C07
-:100100003CADCF73D4DE745D4BE9EA2F072399A190
-:10011000FF5AB794317ED6B93F72DAEBCAC09A194A
-:100120005BFBA25BA1D32E63FDFA162AFA5F51791D
-:10013000A91A5D07BCBCBF15FA5A13D793E36833FD
-:10014000107C28895129D49F500EF41C111906CF18
-:100150004D7DBA41F7E17405AA49C3E72E956DE3D9
-:10016000A9857EBB5D3DC394ACF0FB16BA291C5E2D
-:100170001C0FF5B4C6CE3DD58038F774EC1F1D7644
-:10018000C3F2D2D119E30CD4CF6ABF3ADD0EEF2906
-:10019000B70BA8FADF2D7654F6762AFCDD624FAD58
-:1001A000427EB7D07F990B764B641D8E87AF8098C7
-:1001B0004EF258540CD086E978E4C3D11A5DBFB62C
-:1001C0004BF47C988AB48EFFB173A2ABDC3AED4756
-:1001D000F6C6289E948001B4BE7E6AE7482706B31F
-:1001E000B8A56112D8EA3FEC76D37215A2F43CFDB3
-:1001F000C46B978469BF06F9549386C3D9EF55EE53
-:10020000D8C36E6CA73178B001F5478C637E81B09E
-:1002100097B53B31B3EFB8818D285F6759F23C2E1B
-:100220000BDA4E2DAEEB0419B3B38AF2BF1FF7B54C
-:100230009060F6D0504EB3AD8BF2E9F7ADAD7DCB0B
-:10024000F9DD5CCEB770FBA81DED238BDCB7F3782E
-:10025000B36D12D8EE595478587CD63B5CEEB77A21
-:100260004D1FBDAFF0DC0ADF088C7739A8447C0451
-:100270000FE5D71AF9B13EF05091B0CBDBE9C67764
-:10028000BCEACE1CDF91ADBD88EBF8B478D9C6F7D7
-:1002900031159ED971BA6F495D44E5B398F34DF1BC
-:1002A0001CA076ED5013923AD6FDE82458F983FC51
-:1002B000EC433F454903190BE915930DD41F251B4A
-:1002C000DC4999CABB763BB60F1F5458AC21188144
-:1002D0009935945569FBB0F2422D8ADA706E9FC150
-:1002E0002AFBBD8BD245F6FB52258E7B1261B4EF03
-:1002F00042E877B5D42BFBF4F40879083DCEFDFC39
-:10030000E9D1AE1A7ECDD2BE5C82684786FECA3D78
-:10031000CCEE285FB39EC5813504E07531DF6148BE
-:1003200057231F17832D89FB16E3399BD9C0E26B36
-:100330000635826CE5E3319E1CDA8F0B0CF32C82C0
-:10034000B7A5DFBEA2EB19A4EB44B0E9B10CFA6388
-:100350008C87C88BAB90E98FF6C434967EA4D0F519
-:1003600023BC08924B08889363B1C52EA4FF1CA040
-:1003700071E8E186E6BD185F5DDC08111C86F015AA
-:10038000E5AFF00C481A945FE06098F0C76036154E
-:10039000188C7C81EBCF02465FC117258DF6FB36AA
-:1003A000E1067BBE88DBFD45CEFB5B8E7E8A7576E3
-:1003B0000F4A5F2403DEFB83E9F6FB3661E87AF03F
-:1003C00001846F7F2092427E351DE338FA572176F3
-:1003D0008587E0F389EF4FFDE559A4FE8F16D5150B
-:1003E000205EB67AA3B9F45E515BE6B8B35EFC2A30
-:1003F000EC8E2CF5D37AD4B4C5353BD3651545378F
-:10040000CF2270AC081A40F59A7915D5EF0A97DF1C
-:10041000E78AAFF0623CE9D2C0E85CD4B37B314FED
-:10042000D2A5E111346E57F4A3F0F85D918F737D7E
-:10043000EA1CEF160FD3A37F07E316C4C3284F2C83
-:100440008CF376858B1E9FA9D3F3422399A1DD758A
-:100450001E3FB32F75F59F56FC93055CA372087081
-:100460005AFE85599E581BF2A75947B613C8FFC3B9
-:10047000201947FA3727B8DFBDA7DE6A5ECFA47E12
-:100480004F512F9600EBBE93D45B8BF321F50C5BA1
-:10049000BD68AF7A77F17A601BD7E835EE66011F49
-:1004A00058FB8BF4EA6F2BEF8FDA833DF5F45EFD9A
-:1004B000DDCFFB336CF5B45EF51E16F0D9C605FB37
-:1004C000B83DE5E7B89371AAB7593CFDBE8A2994B7
-:1004D0005FF6574CA99F45C6B9F9172EAE23AEA1BA
-:1004E000EBB6E0ABBDBC5E2BF25515DEC385B64660
-:1004F000BC07CCEF09C703D3BC31CBF71EBE0A4CF7
-:10050000D3327F9F65ABAFB6F9C01843BFD3FAAD06
-:100510001F2BDCEF9D3719FD71CB0B65EE9FFB5B4D
-:10052000DC50891E1BA0DAF26D61563ED2FBB7B8D3
-:1005300089778AF83D18A22B9FAEB2C877CFF89F73
-:1005400017FCFC3C230DFFFB71A3DC0A3FCB0BF82F
-:1005500045DE5BCCCA47B7BD3F092F56897B00C338
-:10056000DB0A5AA9FFE20B3B3FA9D53E3F964FCF8E
-:100570008FE5C5FCAADBA4C9FF5AF3CB6DB5F31F09
-:10058000CBA7E7C7F2627E356DB9A7353F673DBCA3
-:10059000AF847A7E45C5FD615C7756E0424AFA1D1C
-:1005A000D7F6527C31C9DF3E40D8DB3AD5EFA3C045
-:1005B00038C73BB6FF76BFC2E037D2D61B64E7C16F
-:1005C00050E1E6E7C18930FA39DFF0683C8E8EC130
-:1005D000A978EDF9A1981F90CE935FFE89EB308644
-:1005E00029B2FDA443CFF7B3AE2D2D66EBC9B2609F
-:1005F00044B6AE6B220EFAB9013554FFC435A67F5E
-:10060000F60EE0FAA890AC6BCC9F47EBBBB8BE5A95
-:10061000DBC2DE0B48F0FBB0F1C2D1143F09711F01
-:10062000D69C62D36FFB6AA71C40FFD5B183EC9DBB
-:1006300088A7BC6CDD5BDA021DECDD032FBDD7FDA6
-:100640002CE937462AEC21F61EA63F25F61EA6BB4E
-:100650005BC234FD498B4ED39D645C4C1F6D894059
-:100660008C8CBFA3651C4DEFE2FBAB0D682F92F4A1
-:10067000CB8532F55B6C6D2196B20BFDBD5E9ADECB
-:10068000DBA2AD522BD0DF1BA6F963D2B4EBBC7456
-:10069000FFDA15CF25703EF1BB727A4F7C62A14A1A
-:1006A000D75F50534A6E75FABBC0EB31A9AE11DB70
-:1006B0005D1096593D6F321ECA5CEF46AC372EACCA
-:1006C000527820602AA1C28CF5BE87FC5513E0FD4C
-:1006D00069B17830737FB7617FA303BCBF423D1E11
-:1006E000C8DC9F89FD8DD4181E20DCB5242773BD7E
-:1006F000A558AF4AE3F32D4DC93999C7BD1DEBE5A8
-:10070000E727E8FD9D8BAE066A8FBA0AF5ADD46780
-:10071000C1EB25074441267C9E5F9068C67A17C6C8
-:1007200022308C8CAF872220137E7605487915DE27
-:100730002527FD9074C274528EE74258FE254B392E
-:10074000B627E9F819BC7DAEBD5C8CE76A839EFBD9
-:10075000D37869DCD56ACFE7C94C3E1F6ABB6A32E1
-:10076000CA7D1E3F7FFA35E6C9B8AE4520F411AB0D
-:10077000EF67E5CF88FA2156FE1ACFE7E7B379FB9A
-:10078000A67869BCF0BDB78C289E55959EEFE0EF2A
-:10079000559E3DCB32BF7BBF7741F1AC407A3E8363
-:1007A0006F9D78F6AC3EF63D05F572CF9B24A8B759
-:1007B000F21255547F8EF244A97D386A608D81F221
-:1007C000ACAC6270BDEB2D6B5DA252B84C7A4F930E
-:1007D000C375CF3C3B5C83E6DBE1BA67BE1DAE412F
-:1007E0004D7DC3F59497E9B56CF091F10DEBF85B95
-:1007F000FECD3EFE90EFDBC7DFF27DFBF8436EFBE4
-:10080000D4E3A7AC74D97CA37DFCD29BECE36FBE90
-:10081000C93E7EE9CD9F6EFCCFCA1EBFD01BFBA791
-:1008200097DBBB8AD5EE6C8ED9EC5352EF24AF67C1
-:100830002A563B3616B3D9A7A49EEAE3F6AEAD5EC0
-:10084000B4573D9F8FDBBBB6718D5EE386787F2901
-:10085000D9DA5FA4577F05BC9E295BFBD37BF517D4
-:10086000E6E31AB67A5AAF7A83057CB671C13E2E9A
-:10087000F038B05B791C189577527FE1D5649F5DA5
-:1008800086FBD0A884FB7DAD0046EDC7FB26C3D90F
-:10089000BB477953160EC5F55C9AB2F02C5CFFDAB3
-:1008A000F2C0B66F9BE2637E84B13E85A65A0E34D9
-:1008B00053FF9DB7B9F872CBBDD72DBC5E4F79A061
-:1008C000B9F81B96F24B78FB367E6F70B2EFB7D457
-:1008D0001ED10691FA19FC66978AFE783914463AB9
-:1008E0000D02F75D574D1B6BD5CF5B7C2E3A7F6DAC
-:1008F000281FB734335C6D656CDC7B71DC007E17C0
-:10090000F6477331C5B7C652F17D4370B6F457C48C
-:100910006ABB97AEEB6EBEAEE7B99B1F282370C4CF
-:1009200007CB80F7229697F6EDCF696DB19F2FA880
-:100930005AD4C07D5FC91C6D348A47B67677D7CB51
-:10094000F599CE1F1AF87C5AE7D425CAC9F8B0DF4A
-:10095000EEC7250C0ED6FBC857B9630DBE4C7EDC26
-:1009600056AFCDBEC92B9A960B7DCC23DE62F7E342
-:1009700012D56B64A2DB4A1F3F1F39E8B5D95B79FA
-:10098000F932DD771EAF62E7066016533F610F5EF6
-:100990004BEABCD6F15738C6F3C13403D7015CA685
-:1009A000505EDCE5EC5D157F61422BD3D17FD049F1
-:1009B000CF0381DF7713FDB686A7D1FDF8717E0FD7
-:1009C000560D276A99DF91C3A7715DC5C729D9A8BC
-:1009D00042AA808CED8AADF48DB5D2CDA4F74B4EF2
-:1009E000B89297D2F79ECA08FDA5DEF3BFD3C7FC25
-:1009F000C577EBD37E5B9681BEF7A0B3D8D26FC923
-:100A0000876E488DC95E3F5D8FC1D5C3B761C2AFE8
-:100A100028FF3AE75BB7F1235FA6780BA11FF839EF
-:100A2000F8AC71C07FF42BFF44E671FD01177B77B2
-:100A300041DCB7E1A5D773BFE92CEE776D8068087C
-:100A40000BDF05B91EE5EC5DF85D688C85FE4FFB9C
-:100A5000DC0CAE3617F5778973DF6B132E9B3FECFA
-:100A6000BA8DF6FC6C9856847A6BF67A17F5AF5D02
-:100A7000EFF0D33ECCE77B1D342F433B5EDCDB9EA7
-:100A8000A5818AEFF2CC7BF2DE1ABC1FB5CFC7EE90
-:100A9000EFBD4DF846B7C8DB0D81A41BEF01BCBE0E
-:100AA0006BCC151300DB279795A0BECD838CEFBED2
-:100AB0007DB7CD0E5F7FF03BE10558D2271CEA766B
-:100AC00029A37FABD327CE8919BDB2C57988B88B4E
-:100AD000639C8F7AFC307FCEE17E18167FD15FFB5E
-:100AE00013FDB49FE7ED72A3FC34A9CDF5929C3EB3
-:100AF0009FF2B862C620324FD7EEDAD420B0D56B61
-:100B0000EBBBDED12940F5657314F948D49B0FA4E3
-:100B10001ECAE59ECB4D5BBD72526F78F67ADD5CE6
-:100B2000AFFE7CC7BFBBD11FF9EE43872E43B99CF4
-:100B3000FBB4025E326EF78E20A4E83E36E9C6FDB5
-:100B4000DC0DBB948CE7B9346280F43FF7C741BA3F
-:100B50005EDEB0D3939C4ADADFF093D74702C143FD
-:100B6000F792A3CF0FC275F721899DAB9A5D2371D0
-:100B70005DBB4185EF4433F437C0CFF8F0F0533913
-:100B80003390CED2F6BDD7D07E3BAE74792CFA220C
-:100B9000E077897ACC1FF7A044E3A37BC3C7CEC11B
-:100BA0000E3F2831F876BB923E846FFB56778CC09F
-:100BB000D1B4FD3DCA57937EFC4808F1D0B45BB177
-:100BC000F9899BB62B29CF489A1EC214CF57A41A75
-:100BD000C427D38FF377CDA3FEF3F91D2BDF534248
-:100BE000D8DECEDF042F9114E2F525253215F38FE0
-:100BF0003F10D209AADEEEDC1642BC927E67BA73C1
-:100C0000F11CD8EEF7C6FE3FCCEFDD1FC05137F226
-:100C10005753C70A36DEAEAFBD81FAA5C921476F6B
-:100C2000E32FC5BDCF5D2EF43BCEC1B6179C927DA0
-:100C300039F791E35B4C32EEE19DEF6C3109FC8DAD
-:100C4000FFF5FE96DBD00E7AD6A7A11E687AE83FA4
-:100C500042605937AFF43379EC7EF081FBEF26F236
-:100C6000D1FD470F5D3FBA9F7963884EE6DDFDD821
-:100C7000FF29D249FD05CF5C4CFD050B9E9834B091
-:100C8000AFF513F935697D978CDF3FD77793710600
-:100C900092EC1E9E3AE8F3DC2E057C04CE775FF6DC
-:100CA000D07B524DE4DBC2D148AF79542F637E1123
-:100CB000C1F3FC1DCBDF534666C2B73948C64B07AC
-:100CC00040C4308CF4FEC6D72FACC6D445CF579A5B
-:100CD000E028D5ABCE764D07095DCFCB4EC7E3F00C
-:100CE000911BE3569A76AC60E376103A867AD3F19C
-:100CF0005DFC657C6F3A7ECF41C7E3D0F8233C1F93
-:100D0000845D0519CF85C5F9D9BC27BED9A7BD25F6
-:100D1000F4427F789E2331B8EAFCC6323FCAD7CE70
-:100D200087EFBFBB90D1792A414CF723C78700E1F9
-:100D300093375D47AF41FD78F4198F86EBFD0DCFFA
-:100D4000BC44E5ADFB8917DD3AB5BF2120117BA37B
-:100D50001B7A7E3AD1FE982FB14C537B30E509A522
-:100D6000E9353F7979BD1EA2DF0FD1EF492607F3A0
-:100D7000937BA74B19E8F7AC9FDDE786E4008A97E1
-:100D800079ED7F72D373700B5DA57148CF4353F03B
-:100D90007B367A8AF96B38FFF32D746D67F29B4DC1
-:100DA0004EBBB77A548C6B70D2B9DBC5F6094D498E
-:100DB000E9A54C7417EBE0E99EAB3EE5946F3EEF7E
-:100DC000FEE4BBFFF99C1EBEB6FB751BDF08BC1D15
-:100DD000FE28B3DE3FE897381CCDF525C37BAF83F3
-:100DE0002A44CD416569780FD3B7C948FA9042DFEC
-:100DF0003B5DD6F11CD5DF4E3D313F8B9DFD37AEBF
-:100E00009FE6EFDE3B12F5D9E17D4F517E9CBFE3BB
-:100E1000901BF737CF6F7FDCDD5595E67F5C17AC15
-:100E2000EF5B1C7E74EF48AABFB1FF0CF439C6FB20
-:100E30006FDA63EFBF69C77BB6FEE79A1D6EEA5FA4
-:100E4000ED679CB755E34A9CEFDB9D2EC07793DEA0
-:100E5000EE50EA33D9412FF175B127AE2658F3325F
-:100E6000FA27957CB78EFAAF75B1F112BE9B68BEBA
-:100E7000E862EF56AAC6CB1E229FF13CB78EFBDE7E
-:100E8000D6E015A05BF478C2814FAD50ABC5FD80B4
-:100E900036395A6DDD7F09F8F30CD906FF8260FD03
-:100EA000407CEF0AF7713ABE53A14698FF3A34A549
-:100EB0009EDE7BD464CD9771DD66FDA1DF0EF9DF88
-:100EC000A5C9A05BF86BD4A42BCE45979D0ABA6D3B
-:100ED0003FB066323B0F16F35F33183603D1C36B56
-:100EE000A4A307F09D08F352166728EC3BE0FBFE35
-:100EF00010EEFBCB7ADB7B60183AEA23AA8E7436BD
-:100F0000BE61B9E79C8EE3055D56309E39423701DC
-:100F10002AC468108617E36C87E3BEAB83A601A2E0
-:100F2000DE309D98338CF1371CA5F9B5F57FA171A2
-:100F30008F8539D1513903309F2FB179A4E83E4FC5
-:100F40005CE397734A8BFBD20730593D6CF52779E8
-:100F50006033DDCFA03BF364411A2F22DE4EF4BB99
-:100F6000C63751C2F508E73908DF69C3478E2CEF51
-:100F70007088F8C90122EF18076B6A357C09A6A2B0
-:100F800019935CC3F17C3F21E1FC4AA083A6A5D064
-:100F900049D37CAF26A914BE57A9BF4B86BFC0C991
-:100FA0001C077CA760C73BEDEF5B15FD9518A1639F
-:100FB0009CEF73EECBB3C7237D3B87E9991B73642A
-:100FC00011FF1CB3EEDBE2D04871E02B64CF93F548
-:100FD000C8414EECDA1C0B9F29814E165FE6D82FD4
-:100FE0005FAC2CA2E7FBCBC37DC7752DC5F8F0B372
-:100FF000B297270678676E050A3FF383495E16E7C6
-:101000006D80AE59F91163796AAC719386ED3D1D1F
-:1010100017F2A182783669EA43B922690EF215A166
-:10102000C34ACE8741E8E29D1CA5FE8F2DEE581CD9
-:10103000F97060794C62C1445189F9D50CC5CA0771
-:1010400072CED5C57DC56DC174C22796B899FB38DF
-:101050005D541554FF68846733A7BF933FED71B0AB
-:10106000C2AE0BF09C87C7E3FDACFA77F4FD17B571
-:101070003040E35F02D5AD37E2FBAD2A346BA857B1
-:101080000322BE25C2E216C5BEDA57698F17F538AE
-:10109000E2635D7CFFDE2B5E9CAFC777E0870C765A
-:1010A000B3733D7E3827739C138CCB1C9728ECB40C
-:1010B0004FCAFF62FFD9E8ED7C9E02A11934AE53FE
-:1010C000E57E8BDAE91AF5B71FD921B1F7361CFC9A
-:1010D000746467EE48D49728CFF87E790EFF2EED22
-:1010E000D8BB17EDABD6101879F954FFE90AC1FF48
-:1010F0003269945722E9BC5DEFFDE669F4E3EF51F4
-:1011000000DF753B42E6D889F3548D3C245A0EAC7F
-:10111000B2D1F993CEABF7392693BF9B34217F012F
-:10112000DAEED80E89BDF303E7DE85EF5D351D707D
-:101130004192941F03D6EFB1CDCC6EB8EE178FD786
-:101140001049808D1C1E5CBFACEB4C41BD1F740B65
-:101150009F84C5BA601A9DF8DE7303C7CF8068BE4E
-:10116000AD9E98DF3BB3EA0F50FF4F8CBDFF3C7044
-:101170004689AD7FE0FE119DFC43BEECE5679063C0
-:101180006EA0EB4A343745ED20B29FC6FD47528A28
-:1011900020DC4E7FCAFCDD125DCFAE27EB19BEC747
-:1011A000767DD2B11F75C45309FC3BF9560E703BD6
-:1011B0003200812C788EA4AAE9F92C95BB9B7EA1E4
-:1011C000507BECA647A4248DA7EE3A2B1728DE15FA
-:1011D000EA977A039AEF242B4C9ABF1DF8F384ED1B
-:1011E00078F7E976BCE754DAF11B8CD8F1E8C473E0
-:1011F000EEB861B6FA73954637653E8EEF4AF20F48
-:10120000F14DF4249DC77C328F94DE1B9F73F6ACA6
-:101210005986FE927EF1E8C0DF390EFC1D873D7BCA
-:10122000592944BD4596F84F3545E5CA2987024FEF
-:10123000A55A672DFD1609523F7598772235B0766D
-:1012400025DE0E2654A323540E459C724ECFBAFAC7
-:101250003A9C24E9CD97EF3F340BB2CB5D478B37F7
-:10126000D2E0C2F371883454E079B946D3CD58FF47
-:10127000BCBED65B838EE7828886E91DFCDCE44831
-:10128000157B17A923F54111DA7F778C3E7A19DA9D
-:10129000FD4DD74294BECB1464EBEF2E9E4E0EB2A2
-:1012A00038EBDBA33218E82FD8A32425F44369C612
-:1012B0002F2E42BB6D8F4BA7EB9F76F437FF8B969B
-:1012C0008FD1F01CA3584E8CC271497DEAEF3FB21A
-:1012D000E7F5D0772DF651F7EE7567E3FAB4498656
-:1012E0003999F6010D01367E77E55F8A902DE77911
-:1012F0008FD27DF9F22EBB9FCDBD8BF9E1E6EFBE1B
-:101300009CDAA3FB67B3F7389F38CCEEA54E51AEFD
-:10131000FEEA97487EFC7FF0778CC0983AB38885C8
-:1013200072203DE33E826782C7F53C7EB3E9AF326F
-:101330008DDF1C7F214828AFE3FF08111351DB3CF0
-:101340009BAE574F87A61CC074F21E89FA8F9A0E67
-:10135000B3F56D6CA7DD4F74FE64A21748FF357BB3
-:10136000987FABA68B9D0F9CFFB2BDDEF82E7B7ED7
-:10137000423FFCBB24C0D7AD10149D4E7CEE1E979F
-:10138000B122C0CED3E8BDB2889A79FFD515647674
-:1013900018C1079DFF91A3105942E671A4A1A4169C
-:1013A000EF291DF9809D371CF948A9CFB4BFDA1287
-:1013B00060FCB2C9CDCE8F37CD0E24179379EC9B4C
-:1013C0007DC350DC57FDE3DF6243B5BEEC12A222C1
-:1013D00064BA261AB9300EE5A395DD77834471A669
-:1013E000F793855C083911F2513CDB1FCBE4171DE4
-:1013F0001664FBBFBAD99512C66F773F2BD133A6BF
-:10140000EE2504AE3EF068C29241084FD3EEF7A934
-:101410009FC2BB27B3BFFBD94088CEBF7B89B978B9
-:1014200002C1D7F788709B280FEE4459A6FE4D588D
-:101430004FFD57DB028C9FBBBD6C1F0E6AA218DFED
-:101440008DE8DE3DE9D26504CEBB89FCE1FABDC979
-:1014500015A1709BF380BEFF07FC7E61E965B0F5C6
-:1014600076CB7EED40A0F620D2FB6080C51F15C470
-:101470002212C21DF9F84408FB3FF2A187D2AF84C3
-:10148000FB8B44BB23017E0E17347E43F9654E214E
-:10149000558A915828D23006E0BCDD04DF16FD9D48
-:1014A000A69B49C7C98F01BD479F1F90D97918D9FD
-:1014B000A7E1FEA309C48F49F72B42FEF0D29B6A35
-:1014C00089BB97F648A920D19FD5DE400AFD32F9A5
-:1014D00073647C8387D8A35ED65FA7DD6E450D8CD1
-:1014E000FA177500D03CDB1F097D2CF4786B1ED3F6
-:1014F0007FAD6B54AA1F37AB5D3EF44B97197A9DB5
-:101500004AC6CD57751A6F31780E93F79CE1F7E60E
-:10151000F5D84513001EFB58C9E81F392B28F015D4
-:10152000FB07E26BE481A3FBD0BC8AF8A000E93D95
-:1015300085DB3DE3DF65FA48DC3368EAB94760D70D
-:10154000479B7CDC8E81C4EFF1DCFEA9BFAAF4FED0
-:10155000408FFE993D85AEA7A0543D87FC35E157ED
-:101560007C7BC0F50FD9ED51BC9CFF422C8E7038AE
-:10157000F5CD38207A49EA5FEF38E94C8CF09E7C53
-:101580002941CA980344CE2CED9D7A6A6090AFB38E
-:101590005C4F1D8789032FD6D3FC347A61E4398FE1
-:1015A000857F849E4AF35392E2D5398E04DE9EBC39
-:1015B000361CF5CB0B0AFA518ED4B2BFF393E2720C
-:1015C00094F741F252E487F57B2EF121DFEF3C30B6
-:1015D000C98B62755398DD3B53F74E3781B38FF556
-:1015E0005CD9055E3D5089F890291E148DE42DE3E9
-:1015F0001F4B48FCDEA59E3B3DC3FBD822BD29CC3A
-:10160000EE95ED3C302C97ED475394EE3D7CCFFDAD
-:1016100017422E04BF3BF95BC8439CB4922D7684DD
-:101620002275F0FDA3DD8F10E776445CBC3F6316A6
-:1016300053FB7001B70FE381112BF1CF1CB4A6EA65
-:10164000343CF758101C46E3AB170C60F873E243C8
-:10165000A44D1F127BD11207DFA41EA5FEB1A60F59
-:10166000DDB6EF02BFD9F022F07B01E257FAE4F8D1
-:101670003D3FC8E8ECC4F3A79D7FE94DE332DEE7C8
-:10168000FB5799FF04883DDD45FDB1EC3E89E0370D
-:10169000A13F6A6E6E8BE7E8697D21EE8308BD236A
-:1016A000F4CBF98D89E77232E80FA7DE88B8B4EF82
-:1016B000AE22F88BFC2C40DFEB70EA910FF09762C2
-:1016C000EA77BB2748E07DECF9B765F49B3CF15322
-:1016D0003277521ED93B99F9053B4FEDBC4BD8AD43
-:1016E000C25E75D613F6AA5877C479D3AF83B18793
-:1016F000707C693791A710C6C7B27DF28140EC11AA
-:10170000FC9E4360F6632C6065AA8CED67EDF29A4F
-:101710004D3E731CF2D79152D93B3201F62E9413F1
-:101720000E317E4390BF2B40B80EED9AD21A6083E3
-:10173000CD67EF06948E8418AECF78BD14E7F92BF1
-:101740006E97BDC0D71B911E0844F723FC2E154C85
-:10175000CFE84F0EB7F02FFE3A68ECC3FEBCF5069B
-:101760009DC7200D2268EF0F523BA4088123BF5173
-:10177000977A9C3D625D27FD0D9AAAD7A21C0DC2E7
-:101780003B05581FEDA30CF4F97390C535CDF376E6
-:101790003D8F267CD3D4E6FA501FE7EBE9F7102201
-:1017A000DCCF658F0339F2CC4B83F1FCF3B51FBC62
-:1017B0001FC473ADFF548F0611CE3717FD3E88F757
-:1017C000215E5BC4F61FD738EC9CE31C7FD343D16A
-:1017D000C341927EA7E5E31ADB3B240BD9F9CCF594
-:1017E000490537A53DFC3E777B0EF5ED89FCBC8EA7
-:1017F000025B5EF0E93C0F8BDB72CEBF2AC4E2686D
-:10180000AEDFB1D53D48C7F163FF85E3BFC9EDB891
-:10181000377705A9FF43C0336BC72837E2E13FF7AD
-:1018200078F8B97FA78BE1DF988AE773314E0A27F2
-:101830009CCF3F9B43FBBB768342ED8E9964AC8586
-:1018400084BF637BAEA7FB70E73CAE7D4D9F3290BB
-:10185000D0EFDA1512B557B1FE22C20FB185CBE930
-:10186000399E739E334D47FC08B72B9C7126D7EDEC
-:1018700061E7EF0DA0AF9C589621EE64CFA5F4DC94
-:10188000EDBA7EF63D65216E4FD4C0F918377F1C46
-:10189000AA7E58A5F7BFEF79B3056810D9DB2D5E96
-:1018A0009A1E6ED158CAF5E7DCDD7B9FA77CA67631
-:1018B000D6A0DCEF3CF07ACEB7F4B41EFFF2D6F738
-:1018C0009FBB87E4C700F3F3087FFBD51CEF1771BC
-:1018D0007D7E1DB717C67CD8B73EBF1AF131B2372F
-:1018E000BC428F5F8D7F6FD08207A1D79DF838767D
-:1018F00060780EF2C7E490F3BCF9D3E1255BBB79C5
-:101900004AE67846214787838CAF1BDA2F5F564221
-:10191000C68F3FF3C6902EA6270EA29E107C0AD03B
-:10192000EC463976F2A3E0931EBEDBB39AE249F0AF
-:101930000791AB303FE70CE3FED0C97FFDC537759B
-:10194000BBBA86A05E70F259B7E35EB448AF083107
-:10195000FF7B836E4CC1FD2A596E96B1F340A68F72
-:10196000DE5413CFDF86F2DACEE465DE938FFC041B
-:10197000F5D00D3FDE10423DF4969A28C2F11AB719
-:101980002D0DE1B9FA9BAA19C2F66F25958CF18F3E
-:101990003B4292784FC31627016DE66528C7FFD8F2
-:1019A000E6D2F01CAC69BB879DBBEF6278237976E9
-:1019B000DEBE2B739CC40D0F6C28D259DCAD3D5E8E
-:1019C000A2DD45FD17E85FC361B29D17F79C3F7725
-:1019D000F47D9EDEB48BC7D9ECBA3463BC84884BEB
-:1019E00070F2F16607FF12FC50BF9F49E0A2EE764D
-:1019F0007E4E1E7FF0AE9187087C87DB7F1592AA12
-:101A0000ACFE78761E7FACE3BB3FF2CAD9F9B79B38
-:101A1000F37BDA9E48668C9F6874A542B8AF6ADC97
-:101A2000EAA2FBC0C64714FA5E1DFCD143D7F3B946
-:101A30008FFCEC0F1710F8E63EE62A9CCAA641E39D
-:101A40002404BD7AE258387D6E78FC67EC7C59E757
-:101A5000F12C9C4E731FDBEBC6B81C273E2775ECA0
-:101A6000757739E22028BD3A0E4DA1F7091F3CE1F8
-:101A7000C675F6AD67251858D6BBFD9CAD3F0BA1CA
-:101A8000BE403CD138004EB7EC714BA9CB7E5A4DCD
-:101A9000EB51BF5D7F745C84B23896F2FBA33F25A7
-:101AA00070CC79C543E3A7E63C7A338D337A436D36
-:101AB000667C7FEFD2225C7FE7B8CC228DA6ECFB60
-:101AC0009C2DB7507EBCEEC55B8AF87DA462E6EF24
-:101AD000318B719ED76EFE269DE76C88517E9C737C
-:101AE000AF12453FCB7115EA1FCB2037237299DC2B
-:101AF000BC719F071FD38137B89FD3FC9DC2FF5E87
-:101B0000A4F3BC8ABD1B739CEFBFFF19EA396FF4C5
-:101B10005AF7634DEDCB3B914E6F0F36066A349EFC
-:101B2000403539DEE8FBEBCA8B170FE4FA8DBE7740
-:101B300023ECA049F81DEB77BAE8BB379676B67769
-:101B40006B16F0F109DC7EE93C921665F6837E3374
-:101B5000571271F02CFE46F059363DD0CEE2593E78
-:101B600038C8F40CC6E5D0F24E576AA02D1EC763E4
-:101B70007B17251D67E2E2726E2F2770D278991EBF
-:101B8000FC3E2B25F11D64C12FB3D77BECF1793DD1
-:101B9000FCE37CB7C71E3F739DC32E1369AFF53FAF
-:101BA000D7715EB7F9D4E2671A5D491AFFD4F847D6
-:101BB0000FDD9F343EE28A225EDED9F1DC1FBE4596
-:101BC000F8FE9D0E21C776BDEB94E3393BC7422654
-:101BD000397E2710818C724CBE6794E340FA5C43D7
-:101BE0008733AF77AFCBA277BFEAC027B11B723183
-:101BF0008EF8ED87E60EA5FE0A077E85BE75EAD152
-:101C0000D7433AC573EF783FB6EEA7E331191E0507
-:101C10007FDEF0F03C3A4E0F1F0B3E157C9C256E8C
-:101C2000CC894F67792EFACEC6F6F68B9875508917
-:101C30007FA729EE06F6DE9BEC8F20FFF677DEF914
-:101C4000DBDC32F1FEDB796C5FC8CE3B23010DFF9C
-:101C50006205DE9753329DB34726C919EDFF1FE495
-:101C6000323B09DDB2983E99CBF0D7AA44B923AFF5
-:101C700083DE63A067AB08675E88CA998BC7A990AB
-:101C80009EE97DF4488EFCBE4EFAB8FB87FB2F51CF
-:101C9000D13F3B46BE7938C9EFFCE1CB97A884DE43
-:101CA0009109F2E3C3487ED70FFFC8CACF93C7B8E4
-:101CB00008AB6E375FB96432C9CFE7F39E2FFC24BF
-:101CC000AD636D7E12553E74279EE7A83F657F8FFA
-:101CD0006825917BEFE8F439738E074C1FC9E7B88C
-:101CE000494AF2CBCA7EBF0C3791BFF2C736E652E3
-:101CF0007CD5E988E7C39A97C6EF2C78EA621A4741
-:101D0000FA642EF3479FFBF804FA771DCF201C0FCF
-:101D1000E60EC80E47AB8BF57378E7B99310CFE7A3
-:101D20000E459F5A9A1EA3559D7EF711B49BCCEE8B
-:101D30000FE3FD96789E9BF6F324E7B3534D45DC05
-:101D40008B92C3F842C9959B1F23E9B39C1FFE7772
-:101D5000AE26D621BAEF3EF2CCC0FBD8BB314787C6
-:101D600020BD15E5D89FD1DE3CFAED1CFA774B5E1D
-:101D7000F133BCBDE26778BB327795EB1CF27DB4E2
-:101D800077C8CDC8F4AF483B6EC174AB16FB25A332
-:101D900007A4B0DF6F5DA3B07E03CD417C374E3228
-:101DA000981D2E1166BA9AE0236E80EE1E8E226C6C
-:101DB0008FFF5094D1475374FCA06D7C2825EB26EF
-:101DC00091F32BC7337A11DCD275F4A5712C2FE077
-:101DD0009B911C16EFD2293C7F4278467992837101
-:101DE0003FF52D625631BEB7EFEBBBFDEC7CB31B6C
-:101DF000DB8F4CC70F34FD4DA6FBD9269C03C93F92
-:101E00007E18F8DF2B64EFEB08BFC7F85FDF44FDF7
-:101E1000DFD5BBE7B23813EEEF12E7F935FBD9F99E
-:101E20009CD3BF350156517D3ADEA14727ECFE2AEF
-:101E3000D5AFFD9DCFFD43E8D5122839CDF3B98F3D
-:101E4000734FE17CEEBF013359118B00800000001D
-:101E50001F8B080000000000000BB55A0974545590
-:101E60009AFE5FBDDA92AA54AA2A450804E34B02FF
-:101E700024210B45122004D42220D0314A8016811F
-:101E8000F64881B298AD98B4DB699D438520D2DADB
-:101E9000A319756CCE69BAE785D61125E92924D135
-:101EA000E05432C52204254E9045A01D3BED74231D
-:101EB000DA64313D824BF761FEFFDEFBA82541E984
-:101EC0003E67C8E1DCBAEFDD77DF7FBFFFFBB77BA2
-:101ED000DFBA4409600CD03F1D2403D49BF1970264
-:101EE000307C3C2311F200F47A00D9096054642854
-:101EF000C1F62AFDBB0DA06D338E3385FB6F252AFD
-:101F00006C9EFC53F6FBC1462DAC86828879ED7C35
-:101F1000DEDB652B4031CE7F1154533AC0B4BEECAA
-:101F20009FCFC1BEA1DB002ABD979EA0FB6775AA0B
-:101F30001F459B71ECD74521BCB435CE560053F1FB
-:101F400095293A50CC6C5EB88AFFE3947850B2C3BE
-:101F50007D4BB633AA2FC7DB764122FEF07B7A5346
-:101F6000508E227E0B12DCE3A3E679DBB6A89BE45D
-:101F70002EB2AFAF20B9134B32A2E681E3FA4FFA8B
-:101F8000B09F8D7F573300A643656208E52F844AD2
-:101F90008F84F2BA3F027708E59F718A8FD39E73D0
-:101FA00087FCB217712CF928FA7A2944F4719EC77C
-:101FB0003EFAC27138429EE9F604D7050BFE180FAF
-:101FC000E3AFCAA3E2E80E114EA76437AA01EA8F75
-:101FD000E12017B69F810A88DB3428480486AB0CC1
-:101FE0002AF6DF04EF0B73B0BDB279C871785218CE
-:101FF0004F87271ACFA445D1788EA98CC673EC8A57
-:1020000068DCC679A3714ADD3825EAFE4D9B0AA338
-:10201000FA373F561A353EDD5F16D5CFDC5E1E35EA
-:102020007E52D3D2A87ED68E5551E373D4B551F7E4
-:10203000737757DD90FEF303F551E362F53FB5E3A7
-:102040002751F396CAF7CA9011E6811FFF880785CA
-:10205000A462D23FEA210423F53FD3E527C6FFCD92
-:10206000FA7F98F49F1BA17FF9DE44AF356C6FB106
-:10207000ADA6D79FD05AC7905E714E14EE0AE919EB
-:10208000AF0D1AACDB256C1DC89D7BF1FA63667E33
-:10209000FD5181CF95B83495D6EF081EFD5AC21672
-:1020A000D5C2ECD0FFB1456D44DE3C2A2B0DC4AB4C
-:1020B00017E54A09509E54549D2E1379A4838D012F
-:1020C000E4F7B33ADDEACA08F99EB373BFF29C5D48
-:1020D000C7DA5F18D156F1BDA916F09B0BD973B4BE
-:1020E00036FAE7015CB72D8981822F2CDF3E7F0E07
-:1020F000DE77F4652B0E0033F56F01381FCFE53D19
-:102100001FCFE55C65521AFBC87FC8EA2492A7D9A5
-:10211000EEDD69C7F79C979E30E09BC1E0F21BC8DB
-:10212000EE52CDE0B7E1FB1A0DB0BA12FB0E7049CA
-:10213000F5D826C24E3BE18B622857911487AA72CC
-:1021400013FBF0FAFB24D138B231B70E6600ACD4E1
-:10215000FCE1C61CE60F87718DBDA450BD9208D866
-:102160000E3F90C9AE9FBB0FAD10EDE99C91E3A16E
-:10217000E17051F8C9CF379B597B69B33DCA6F6E87
-:102180006C7E2141C179CE65C3A240047E5D84DFAF
-:10219000746A6586DF80FAC764826770DDB7934929
-:1021A000689FD4BBCD8A439EDAF10F95807A30B612
-:1021B0002DF1A34E60A55161E3B5797CC1B94038DA
-:1021C0001063E9FA3D1FC22692EF9E6FB18D785FD2
-:1021D0008FDDC0DED743EFC376393676C46D39EA7A
-:1021E000C541EDD1390BC82EF07A48C2FEE26E30FF
-:1021F000903D2CF1A61B489E93E03EDD8EF29CB5EF
-:102200002BECF91F42A581E43A735F6D028DBB365A
-:102210009F360F0AEBC078F2A1C36F4846BF3574F2
-:102220008BE4DEA5B0F799E97AE5BDA94F5A95F0A0
-:10223000FBCE80B7FF34EA7B29B8D9BCDAFC6879D9
-:10224000517EF18D8DD5BF4BCA207FA80333F9C3D2
-:102250004E13F3878355575A5FC2FBAB53FB6E3265
-:10226000E273E7ABBE9D4CB8ACDC218382FAFF245D
-:10227000C1FB07FBF4301EE71EF87302DD5F6552F9
-:102280005F7909ED00F698DCAF003DB7873DA78D7B
-:102290001BB0CFFD8C78072508D4ACEBDBA786FFFD
-:1022A000BCD773C612CF347E3D28F855FF5AD65896
-:1022B000E2537DC2357EF1FE2B9963895F3324CED4
-:1022C000CBD879BB905F4A16AE1B79A520AFBABEBA
-:1022D0002A4B223FB1EFB8B388E4D483F76AE4BA5B
-:1022E000F6BDBF2A97EEC359D70DC94BB6E947399A
-:1022F000EF012E678FB08F15C1A422D23BDA9DC5A6
-:1023000081E356FDC76BFDBF257C3AF7BCF2388DE3
-:1023100029BE313C34FFB4379EC7231071CE2D70D7
-:10232000C13897AD47510721DE4DF9C2F5FCD65EA5
-:10233000F20BC8AB2B3A747C99E4AF2A81FC82057E
-:10234000DC0AB5E865DE9B8D7A6C3CA083A7B16B97
-:1023500023A7A6F99F12ECCB3AEE7FB06F4EC1389F
-:1023600022FCD324C7BF2EDACAECC7635D3383B91E
-:10237000442657F1E1AA0A7A2FF4A21F47592BF1FC
-:102380008FE2C16CD874280EE59CB103F3031C37AF
-:10239000F32CBFAFF9F55921DD1A63228DFBD91754
-:1023A000B28D208A8E03B30F977F4AF3CE8688E7DB
-:1023B00046890FB31C7F5F7C98EFE0FE2190CDFD36
-:1023C0007B2014AFFAD3D9B44595F9C817278F1FCE
-:1023D0002D8839D9B1511AC836A31F5EE468DEBE14
-:1023E0007D02D26122C785FA8DF45B29623CBE96DC
-:1023F000371E9EC2FC21FC05A522BCEC42E61879E2
-:102400008AD1EE78307647E59DA123DFD8FA701D9A
-:10241000AD4EE5BF485F4398D7905F88D3F7191D4D
-:10242000A3ACEF4DF2AFC8FFE71C3A26AFB943F2B9
-:10243000A8F87EB3E20109D71067B74F93A5F0F86B
-:1024400032078F4BB547CEA719515FFDBAE3B63CB3
-:102450009CBFA6FD0D1B2E1F7E6CF3AE73E03CD51A
-:10246000E73E9841A10B199E569940386524923D4C
-:10247000E5EBC1AF2F1C29876F072E06295FB72315
-:1024800089B5391D125B9F2FC4D739D0D1E88CF4A0
-:102490001BD79EFBCFCEF1A4B73D636005F9E3FCEB
-:1024A00060D106E231C962405DBCFE552E9BEF094A
-:1024B000473ACFAFF5A0A7EB00AA6E290EDA63C0AA
-:1024C000E770DE81AF64364E9B37BF63AE6C471E4C
-:1024D000E5859A0E525E18173429A4E7B89781E370
-:1024E000128C637ED1D7B510287F1D74805BC2FB30
-:1024F000ADF1431F132F863A4DCA2E89F06B022788
-:10250000CEDF6AE4F133070DE10D6BF8BAF6BEB821
-:10251000E0CF81FC15F2C3A3D27D7D13DC628DC4B4
-:102520003D81C9FF4B07E7576B7C486725BF8F9CF0
-:10253000DCC5E40ACB09ECBD9A9C39AC0E68350EBB
-:102540005D78DCC5E4B2131F7280CB09C12CE515A0
-:102550007ADEEE61EB88B32B6EBF34522E5F01E65C
-:10256000C56877CF6E816B764E76EF8B0FF7CD68AF
-:1025700013AD1920FCC229968784FBE8B04AC2CF6C
-:10258000BFF1CF67B66F9DC3EA23BF8C7CB0609B61
-:10259000E0A47572FBC2B2C933A690E3E0469C2C5E
-:1025A000667EFFDA78E4BB95FA563ECE9D68B79416
-:1025B0004BCC6E80ECA64EF89987A4D085DB50B545
-:1025C0005F860E1628284BCDD1B7196FAB75C19712
-:1025D000F2F17E59BC3748FEF7AD8F7460C3F57FCA
-:1025E000FE5A9C5A817864EF6F4EF65847CEF7D466
-:1025F000D92DCFA792BEF74B0A228D79E1501AC987
-:102600005717FCD4E8C17661C7EF8D149F5639BDCA
-:1026100047C80E4A3A1AE6117EB3A0A9D16E657E6C
-:10262000D14B3C0DA470FF317C6AF2AE8608BC2F02
-:102630003978DE0243DE9BC96E82C23EBB28FFC1F1
-:10264000B65DE461ED0756662AF9E1E7FC703015E6
-:1026500070CE2D70389570D6AE0FAAFA45C4A7DC9F
-:1026600033E6D59E08BE5D10F67E41BCEF1F9DDEB1
-:102670008F0887EA039F186DB82EDF1F0269149F29
-:102680000298A7D9BFC32FFA62ECC6A71F32D2782F
-:10269000DF45607E04F5BA3511F5B4E74CC79435D3
-:1026A00056263F24E2BADBCF9998DF6C4FE7F6D786
-:1026B00070FA7201F9ADCB9DD537135EEF3B0C1A62
-:1026C000CFCBE2C99EF602F3639A3DE6913DA2E8C4
-:1026D00079C4F362EAE7B0F95A8DBDE5CCFEDA754C
-:1026E00040F6873C67BC479EDB29FFC8B323EFD980
-:1026F000F359CC9E5B7B31E061DF8F7E7C12EB97E0
-:102700002DA37E6BEF7C3BB3671D425B4876193A85
-:10271000C8E609604C23D549501999A796396C4CE5
-:102720005ECD3F563AB8FF0F642B896E5C8F45969D
-:10273000A3EC20225EF2BE88A72B9F37FCF4C509CC
-:10274000644D222E88BCAC4BE4C1E02D62FEFEC776
-:102750002296D5BF53BAB805D75BDF2373FF2F7816
-:102760007250E4C98737A7B03EC50B05F5341D5B31
-:102770000FFAD3199E4DF3D0C6A06451D3216A4BF2
-:102780002B03F3107198B3A2F790819B732EF1AFD6
-:10279000EDE00F72F5C4F77326884311DBBE19FA1A
-:1027A000F875C4E1912EC47F94B884CB61FC4304D6
-:1027B000181FAFC79B41A9EFAED96E4CF99F1FFB05
-:1027C000037D1CDA0F1103F1C87B7ECC4FFD28502E
-:1027D000BBD333D58938FE36C93BD589380E9EF830
-:1027E00026997C7AFBA94F6CE4EFDB8C9E5CE25966
-:1027F0005B06D60BA3F0738293F3A7D8149DA76B47
-:10280000ED5227E7FF643F3C43FCA96B93ED2AEAB6
-:10281000BBBF4DF618318FBAE0F126EB11D28BE039
-:102820005F3E9BE2BBA87FD771D8611DE52F18677B
-:10283000D6BF6888AA4B6BC4BE4616F46D4B459C48
-:102840007C2F4BACAEDD18938FD450FE5240F54533
-:10285000B391D653F572CC3C94C714D0B8EFAE7395
-:10286000973AC53E472664521E833C62F5F4D06910
-:10287000D9BD8B62A01EBA4DC8DF3D3A8E13FA4D0A
-:10288000668F5A3E637279E691DDCFD3E28AA85B08
-:10289000875A2595D9CF6EF4F3D82FBDA83403C736
-:1028A000E154CA0C5A0FE765A99E8F2F0DA633FB82
-:1028B0002BF1603D8FEB5E8FF5BC4AEBD6F23CD539
-:1028C000C0D68FE197E579B3406DB4E1B80DBB2573
-:1028D000B6EF53BDDB1095E7F9043E353B4E1CA126
-:1028E00072B23610735FE0E38BC1E70DFA316B24EF
-:1028F0004E8F3A45BE97066991F91E743B47AD0B62
-:10290000347CB43CFB4F069E5F7C20E6D7C6FD8B33
-:1029100093D7E7751E60FB4735AAACAA3C1FB4AE3F
-:1029200041BEDC2FF872BFE08B0FF8B8DADD921AE7
-:10293000A278F533AE7733FE112EEB026B16A42A84
-:1029400023795525F0D8D86260F92FC02623D9E71E
-:10295000C69D31E3042E5531B8D479A518F9783ED7
-:10296000FEB7CA576DE0FB35D5C82FBFF2FF276F02
-:10297000ACFEFE5DD3DF149812A5BF454937A4BF56
-:10298000D83C79EF9129167A7EB83B83ED4368BC39
-:10299000899D6781C8B317EEE0F9687FC73C4B3E5D
-:1029A000D553C7F56E09E729EAF95F5B3EE251D8D6
-:1029B0002943054E31182C7AC68FEBDCD73D71992F
-:1029C00082F1A1B047CFE24B514FA14A754D614F03
-:1029D000A1253381194F12D50B380F8BCF83C72711
-:1029E0009ECC233FDB3DBF98606F385E68A13C62A0
-:1029F0001FF07D0DA9A738A92F22DE743BF9BEC6B2
-:102A0000B694FF7996F2FC857B0D6ECA47161A863E
-:102A1000DE9FEDA2F7EBDD0DD8AFE959BB258EF4B3
-:102A2000FE9AE4A674FC486FBDEB47A4DFA0C16E1C
-:102A300062F23E7C90EEFB5B24F7241CEFEBBC3D86
-:102A4000B715FB85CD456E82597B5FA14379A18285
-:102A5000F2C5711656C72FBCC9C0E2EEA5F1965F4C
-:102A600053BE54E5695E40FEF8D2DBFB8CE40F06F2
-:102A70005B2548C1851C4939F41B3FAEF3D29B2727
-:102A80008C9494CF6B3B61ECFB8E7CA25F9521C450
-:102A9000EAF72623D541B5CD5ABFCF487AAA14F913
-:102AA00055DDCBBF67FD2AAA13F07D553B6555C1A7
-:102AB0009F873ADF3212DE752D128C4D8FB8FFB230
-:102AC000C4EE6BBC5F0B9C076B857FAA16FB90D591
-:102AD000B40F89D7613BF7371AEF1FD8BDE40885DB
-:102AE000EF754DD17EE841C1F30D5497B2FADB6B1F
-:102AF00024BD6ED811334EF0FCC1EFE1B93549F871
-:102B0000F31CC8219E5F9ECBE3C9E513F1963C5CA4
-:102B1000D7E563B21BE03BF9CEE2EF71912F0C8752
-:102B2000742C9E69E3063AFECCE28DEFF8B091F288
-:102B3000DB05C12F983E2A8207E613DE7782B7862F
-:102B4000F0BB3368B193FD57F4717F501E34A9B4C4
-:102B50000F7E2704B6929E07BB5EDDEA24DEFC1BD7
-:102B6000E70D087FB741E0BA41E0BA011D7E12BA15
-:102B7000D8AABC032F61BA0FE5C0FD507940F8A177
-:102B80009DD13863E4B98FF4551734C1D378FF0E63
-:102B9000E18FEE68E1FE28364ED6897D80C171B99D
-:102BA0008BD97E2BD6BB94C7D5B444E35F27F605FB
-:102BB000EA62E2F0CD497CDFEEFBEAFF583DCD8DC5
-:102BC000D153C510E74F39C53D5C7F77684B1EED8B
-:102BD000DB6978C5EAA95BC94C1CAD9ED5DAF7451F
-:102BE000DEAFF517237129DF0CD89BAC9175FCABD8
-:102BF000493CFE54CD92FDA4E76BF5CEC443058A53
-:102C00002E5CEF609DB332690CAF7BA6E1D4472701
-:102C1000C8E07285EB9DA7525EA828A47CA585FB21
-:102C20009181129C2F91F27960FECBD76252A94E0E
-:102C3000F1217F589D43BCC1B63228DD4EBCC1FA9C
-:102C4000611DCDBF84B68E1187251D3CEF5932FF23
-:102C50000BC6B76313F97A87F5CAD8D1EA09AD8EE6
-:102C6000A8FB8AE7A9DAF53AB47B1A5F1794585D96
-:102C7000DC76F0EBB474F49F839D57D2D660FBA250
-:102C800058BF96A70E619E9A21F214CA9FD77395DA
-:102C9000C1064C871F431EAE17710EA4ADCC4EEA81
-:102CA00028D925BEB54B7C1F673F5E9889FEF78308
-:102CB0007896C70C9CE1E743F4FC1398470DAC0DE4
-:102CC0001C76E2F8CBAD128B7FEB31C7BDB570A49B
-:102CD000BDD70A5E36C01651976D656D79F6DE4F29
-:102CE0001E277FD46256C8BF0E74341AD9FEB21A9A
-:102CF000F17CC6C87CA856F0B7F67BF6B55E4D12DF
-:102D00007152F012D7C1F2DBC163B2DD2431FC7E17
-:102D1000353E122791FFB41D8C637A1E3C61552904
-:102D2000CFFF5CF0EF92D8776F2891192EBA59BC7B
-:102D3000CDED7A2B83F44A7AF0D23E4AD75B533CEE
-:102D40006C9F4F65F654BD5BA6C3BEB0FC010BDBA8
-:102D50000BD5FA1ABE3E812FCA35D9E80ACBD5AEBB
-:102D6000EFB3B947B11B493AC8F4A693A2EB5CDFB5
-:102D70007EB9528DB0275CCF6AF26FFB053F403FB2
-:102D8000944C7EB9334961F23504B99E759DBCC53A
-:102D9000F72FE7FB3606F6FE11F7CBFC3574FF7212
-:102DA000BA05184FBEF25750FF910C99F9A9473E4A
-:102DB000A8CA8288F783C4EB719F612899D5C3277D
-:102DC000744C3EDF89E1E48956F283CDF3ED79E47A
-:102DD000DFB87F389261D948FCF6D37BC786E759C4
-:102DE00098C4E33CD07A53289B7991CF2BD6BB056E
-:102DF00096321CB6089E75897C14EBA633648FB19D
-:102E000075D3F5F2DD88FA8D3D7F79AE72F247C851
-:102E100083C2637A3FD5EBFBCE723FD1D0B9E17765
-:102E20005407FBCE9B80FCC4235D1BB2280E83D7C6
-:102E30003B95F2BBCB5D0F4E65FB97D21626979F55
-:102E4000E44BA1BCE97432E543B59DA793595C6F8F
-:102E50009FFE02E5499817DD41D7315F61FC2BECFD
-:102E60002966FCDB77BC3829930407B785E6AD3DBE
-:102E7000A6AF247C6A8F15BF5741F94B4F19CB93EE
-:102E8000B4BCA888EA71CA938E4D8CCA93FA057EA9
-:102E90008307E2D8FE8704199C3F30318A3F356DA5
-:102EA000EFB07CA2A643F644F2E8DA732E3DE38D40
-:102EB000C1A5B0F91A029287F1632F6F6B3AF6B190
-:102EC000F5551B024CDF0D2D067EBF95B7004DEC6E
-:102ED000793F38FD84C77B7409F5506E5427D0FEC6
-:102EE000FABBE9BCBE88D5C77617DF4F78F79CF7E9
-:102EF00066E2CBBB73BD59F651E2861FCA78DD2D61
-:102F000009BCDB0C2CAF8C1DB7CDC5F77B6C491011
-:102F100075DEA8B5F52ECE9F7223DFA78ABD7FABE5
-:102F20008BD7CDF8EF191DF2E26485C1FEB4A82756
-:102F3000C6A1BFBD4BF8DB65771A58DE71529C33D2
-:102F4000DDA5F9DD121EBFB5FDFE253BE1492CFFD5
-:102F5000E14BC863E7604B3CD17EEF6E915F2D5B28
-:102F600014735DE453777F4F3E35C325FCE16498CD
-:102F7000CCEB06AB85F645BFEC36D86526B73AB143
-:102F8000327FE43A357F73449C0F75A31FA4B621AA
-:102F9000E743B64FF5EE8173BF71303F1A07197CD6
-:102FA000DF91EDD7D75E67BFBEE19A9DFE308A778D
-:102FB0009A9EFA29CFCF1BA9A7A502EF5AF3252382
-:102FC0003BB7844DDB7572F89CD264F07A52711D68
-:102FD000868EB9213ABF6CC831B17CA9FF764925EC
-:102FE0007F8F72A69922FC7DFF389E7F3DB25C6286
-:102FF000FBC207723E6471BC36D46B245E4D6E5BBF
-:10300000F324B35F3F9CA27A49D3E762338F9FD703
-:10301000F4A8AD976E2AB43EA79FFB65176B693C79
-:10302000C5CBBB447C5C5C12ADBF2CE85D40FB2390
-:10303000F77824962F5D4FEF4B574C7B87DCDF8D65
-:10304000EAFF9F5CDE875D64EFBDC3CB697FF7DD80
-:103050009C4FD328BED65D87CF7E81AFCFC2CFC570
-:103060007C167E1EE6CE521AFB101FBDC3BBD9458F
-:10307000FB4FBABFD8A600CDD3F7AB7A89F4030CC7
-:10308000FFEBD9D13631EF36979DDB8B8B9F0FC588
-:10309000519FECD9A04E203F01793776CED7B0FFB3
-:1030A0006801E969E0C0B10263843E2FD5A33FA067
-:1030B000F8D2792859B146F24D27F8A667AD242DEC
-:1030C0001571339A7F97887FA4FFBD87EEA2BAB0AF
-:1030D000BF6D994B5222E26AFB49DBA48879FB83DE
-:1030E000321B8FF5D8E4BB1322E57C92C9D91FE0CF
-:1030F000F301F44D5E961F79BF919F1B99FB188FCA
-:103100009FCADEC4CEDD351EEB81F3B8AE6309B0D5
-:103110003825D61D30E20FAA33BA4C2A9D53D07EF3
-:10312000BB23C24E8E0A9C67627140FC9C057E994F
-:10313000E69D8933DE4B7D3D84E84C6E3684647EAB
-:10314000DE3D0188D73304AF67EA4307A402368E19
-:103150009D4B95422F1B772B0CB1D603763DB56561
-:10316000E0666D89397407B993BC40807D97144A35
-:10317000D63B2E98D951298CA6BFF0FAF57041E3C1
-:10318000290EC6A487EDE3C78E1B1676EFA6DA825A
-:10319000F4DC0F6C1FEE16E893E925B3F5B088BE9A
-:1031A00027BB450FE6789477EF611DB3E7AE3E4548
-:1031B000257FE64E12CF7D86CF617FA687DB2D85EA
-:1031C00020FA6E455B6F2C0EA5381FED0BCED46335
-:1031D000E5CB700CB1F7DD4682E3BAE782A2A7FE29
-:1031E0001F5DE9623F85D769F3449DA633FB191E35
-:1031F0007F12F191CE736C384F69930467E97C2696
-:1032000093AF579BBF14B3C1C4421ACFE31B6D8564
-:103210009F75F2731E1B3B9F9B6F27BCA450B2EEA1
-:10322000AAE5C6711D4C0626B7EDFEA181C78BC36A
-:10323000E75DEEE0D1B3F45D8EE4F1B0EF7ADC66E9
-:103240006B88F27364C7A5C8BCFBAA6BED5FC9DECF
-:1032500025C5CEF0022F28947F8C0D7FEF02579367
-:10326000C2DFD3108C1793C3E7FBDAF735BBD5A5C4
-:103270008A0EF5B2C26576935E0ACD6945540F3663
-:10328000DBBD7F75B1EF6C5A26B1C9F4EAF4CA848C
-:1032900030DF2DE02921BCB5737D49E8EF7AE7F6F0
-:1032A00064ABC4730BBA7DFA2EE819B417B373B4C8
-:1032B000EF8FF8793E5AA142DF1DC113F314FA2EA5
-:1032C000609BC3EC7E5AA2141FD76709AFAFD1CC65
-:1032D000BF276834F3EF0260EB74B67FF690388F47
-:1032E00068B4EAB2A9DE6A84783795F49ABC0F25EF
-:1032F000703E3EF4DF16763E1A2BF7D7F1DE9C3196
-:10330000D3C3F23F2ABBCF62EE1385E71C0D4F5D9E
-:1033100018CF156A46639FC2F09B46CF4F33A9373B
-:10332000D1BEC82A13FF7E49C30D15CA486D17FACE
-:10333000D0F0B393BE691D1ED4B7C6978C307ECF34
-:10334000C473DC0CF4E544267B56217F1D8BCBFF38
-:1033500001AF6B7F8EF0290000000000000000002C
-:103360001F8B080000000000000BFBCACFC0F0A3B9
-:103370001E8143D1F8E8389D0F534C941182D7B386
-:10338000E0D78B0D5B3122D8FEDC0C0CCA9C0C0CF8
-:103390002A40DC07C4FD40FC1E880DB818180C81BB
-:1033A000380DC84E07627B2076E386E86966676061
-:1033B000E806E2C9403C9B9D74FBCD251918CECA96
-:1033C00022F8B2720C0C510AA49B338A87267633FA
-:1033D00042E5C76BA3F2BB7419184E23A949D02646
-:1033E000CD7C466306062663DCF271E6A8FC504BF2
-:1033F00054FE5D3354FE4577080D00AEA32483B818
-:1034000003000000000000001F8B08000000000007
-:10341000000BC57D0D7C54C5B5F8DCBB77EF6EF6AF
-:103420002B9B0FC20642721302040CB8C480C14A1F
-:10343000BB89A0A0C85B502B585F5D02242004828A
-:103440005A492BFE73212104126041D4A0881B3EEF
-:10345000142BD8A0A0B6B576F9D0529FCF4645A57B
-:10346000ADA50115D4024DB5C8F63D7DFCE79C998C
-:103470009BBDF76637E0EBFBBF7FFAABC3DC993B44
-:1034800077E67C9F33676665318564E6117211FECD
-:10349000BE47C8040B21644CBC244155206309F984
-:1034A000919DE09FD6CF5C36D61312B511129B4B7F
-:1034B00048A78B76946AEDA49896B7DE28922C42A2
-:1034C00052E17D859026A1F6C8E05242D44122D92E
-:1034D000491FADCA999E1A72251F77371FF7B97A0F
-:1034E0003B961DF55E2C9FAFF761B9AF5E21D161B0
-:1034F00084BC585F84E5CBF57E7CFE8BFA322C5F72
-:10350000A90F60F96AFD242CA3F5412C0FD6CFC07A
-:10351000F2707D08DF7BBD7E1E9647EA6BF1F91BDA
-:10352000F57558BE59AFE2F3B7EA9BB1ECAC0F6347
-:10353000F94E7D1B9647EB23D8EFFDFA5D581EAB85
-:10354000EFC0E77FA87F19CB0FEBA358DE4ED20860
-:10355000E947C86DB79DB7CFA2EB1DF6C47DEF4C10
-:10356000CE2464FD18D10FE01AF6C4C7BE50717C9A
-:10357000DDEBBFB1CCE8480097EF1301C759EF2648
-:10358000D8BEFEC0EF893292907563BA7C2AAD4FE7
-:10359000E6DF19BEF3A87D5671BC9F799C4F8885E4
-:1035A0008D63A5EDB4DFD0CDACBFD63E19BE3326BA
-:1035B000DEFE54DB3BF6D92E7D3B7BFFE92DEFD8B9
-:1035C000017F6B63128922DE554268E950BADBFA4B
-:1035D000513CA71CB3115B3EC5BFD241BAE838EBE2
-:1035E000C63D12154B61DDB49B02EB7C9708140EAF
-:1035F000AA9B203D2830C6D5F1EF5C4D449CC7B056
-:10360000278EB2EFDC7A1ECB57FF211342DF5B77A8
-:103610009B1071D2F1D78DFFC217007A539FB10072
-:10362000BD21B92AF09F2E5F908EBD7EFCFB3E959A
-:10363000C269ED37EFCE980DF4379AF8E17B6B0F46
-:10364000FC9C28D03EB21BE1D7C0D7BD76E6AC3C8F
-:103650006F7172BAA49444C432BA5C17094412C0A0
-:10366000F75F0108143E166F04D7E4A0FD12E1E1F4
-:103670005F898CFDD6BA83EF015CD4DBACFE9D7410
-:10368000DED7F9A3E4942B3E6FA87F44EBAEBF478F
-:1036900089C50DF3FECC67A1EB7796C957A5D0D9A4
-:1036A000B8BABB8FC1FBAE6BAB02B0F675A3BB7CE7
-:1036B00055B4BFBDA813D74BFCC43F848EEB285232
-:1036C000C9EC62808305F16A9ECF6C80773FC0D3DE
-:1036D000573EC0894687EFDDFAAEBD52D7FF698DF0
-:1036E0003E04465FA4356A9FE68EB73FA1B5A7307A
-:1036F000FA217663FB66131D939C24ED560A68C479
-:103700009718D92920DCEDD347F69E776BF4B7C81C
-:10371000072E7FD41E4AB02ECA2776903BA9A5A2B9
-:103720001FE0B56E3CE597E2F83A2FC577CD1C2E29
-:103730006B4BA7BB61FC4BC9AD911D2289167199DA
-:1037400049FF7FE5CB0E3AF3787D7434DD50BFEA54
-:10375000C80043FF319D0586F6AB8F8D30B48FEBEB
-:103760002A31D4BFF3E93586FEE3BB2B0CF5EFC558
-:103770006E34F42F27B718EAD7D97F60E83FD13BE2
-:10378000DBD07E836F81A17DB272AFA17E53D10366
-:1037900086FE37FB1B0CEDFF52D662689F1678C879
-:1037A00050BF65D2E386FEB705B71BDA6F9FF1AC59
-:1037B000A17D66E80543BDC6113A0EF8F9C1BC5FAC
-:1037C0001ADEFBD7DA4386FA7B844C4A845F2230C8
-:1037D000394329C87BEA0ADE9F8A382FD01CD07172
-:1037E0003F46A745ED49E4246F7F66C73BF6B9061F
-:1037F000396965749CCDDA7745DE49FCFE20CE2719
-:10380000A4D33EDDAD6F67F3BAE21F54BE42BBA442
-:103810007E2BF9EAF6FAB1BF2657297D13720D8582
-:10382000AF3A5055F17B743C2A2F2D6CC9A48E30D1
-:103830003945C8BDF85CD3FB2487442D74DC06777A
-:103840004EFB1A80091D5BCA847AF136A88B4A8028
-:10385000742580ABC52B1BF064862F71A55362EED7
-:103860004BCEAA083F75222992E0FB82C3BF9CAED3
-:103870005722A101027D7E410CF960F24B2DEA6FC7
-:1038800042F9F1FECBC7D37F42FF13426405F657DE
-:10389000108E0D234900F4869A2D4776E6233C6D61
-:1038A000204FB4F7E803A58BCD57BD38D85067F348
-:1038B000BD64FDEB61C6BA36EE4F8CF0A47086FA9B
-:1038C0005DBCD26BDD7E394EB716E8C7EA8A289018
-:1038D0008B28078DEDDA772EA4784691548A473BE2
-:1038E0002B973A3CDBA0BC90921B211E428AC5500C
-:1038F00005C04DAD60F0518F3B230D385EEDD5C155
-:103900009100DFC4F602212B187F7C3859D4AF23F5
-:1039100019DE1AC06E1BA6A3831C3FCA71BA6AD4F3
-:103920006FE6FEB70B321BDF455145C7B711466343
-:10393000A996D0EDC218586D9048384F3F0922BE65
-:103940002611B04BED1A3CC373B1EEE276E601F7F7
-:10395000D863218AE7B501D90F63550A0AC783DF07
-:10396000077AC056269235B4B65679C70EFCD19C5C
-:103970002F67835CB749B5C44BEBB642CA0709F45D
-:10398000C8E21E39F120B91CBBD88CA722FA3A9B99
-:103990000741386AF30F0FEAB417005D8EA776313E
-:1039A0009DEAFA6BFBD62F2B397C5BC02EA6E53A3D
-:1039B000657A2A41BE253381BE9BF3B344E4530E9E
-:1039C000A71EB8E4BF6F073E5DCDDF5FEB7F07ED5D
-:1039D000F4D59A1E37C1B179F44984CF2C81E9E33B
-:1039E00096918E19910470992578B0BD19782A1393
-:1039F000ED2BC65F267AA12DBE4ADA6E57BC256B29
-:103A0000E8F813464A33812EDC6544B121FF065C99
-:103A1000D9F4FB0EDE5B524483FC706732BAB57F8B
-:103A2000284414DADFE563DFB3B9482480EF2F318F
-:103A3000E0C551169A4246513BE91F167C8FCE9144
-:103A4000D9114727233F5ABD6C9DA488E1C94BFF7C
-:103A500077B1808EA7C806BDB1BC5CF647E9779602
-:103A60007A5C484F563D5EE9779DDFBC1084F15784
-:103A7000E5DCE3584EC7BF50DEB40AD8D2F2E1E429
-:103A8000CF80EF2CE6FE83A6FF6E70023ED04A6721
-:103A90009787443360803BFBA403CF87ED6F1CD630
-:103AA000CDF315C19D89F2F56A7235CA854BBC7F8D
-:103AB000A13EF2C6E121080FF172E879A589AF9B1A
-:103AC000F235BDA5FAA6E9ECB2F302D36B442D475B
-:103AD000384B9C9F9BC6936EB05BD7E5CBCA0ADA86
-:103AE000452A93A3403AF0D74DBF0FB6190179ADDF
-:103AF0003475B2E73F32C8CDD5FDA7FAA37DC04DDE
-:103B00002A34E99B4BACBF0EE0A7EBFF31C0CF19C5
-:103B1000879F8D0453A3402FE149063F7655F9FD59
-:103B20004A94FE73D580470227880E8EDFA37CA8B7
-:103B3000E30F5B4E84E8BFAFC9C55BC44037C861C3
-:103B40008BEC4739450A64F447CCF32B1299BC89B6
-:103B5000C3D92E111D7F902911843BFD0BDAB33898
-:103B6000FCE85F8AEFF57F00FCA88E8E3A47E1F310
-:103B700046A984CE2793A8CE2BE9FB1291A03E48FC
-:103B8000CC47BEA5ED13E474E0DFEBFD20079BB846
-:103B9000DF47BCED3EBD5D3E4864788DB7477CB7DE
-:103BA00019DA99BDD3A4D9F5DEED06BAE8793F8DCF
-:103BB00024F43FFA89CCCE1E247A39FD6C47FF6D80
-:103BC00075E69418A02125FB7A7F25F0AB97201C81
-:103BD000343DA1E905AA2F0689FDE2E3C98541220A
-:103BE00060BB51FF2695D726BD9B52649403446F5A
-:103BF000CF14C07F73BC482FC4ACEF7919BCF1B2AD
-:103C0000F8AA97BE2489FDC5692293C344CDC4F5A3
-:103C10006B7C45B83D61D5E882307AF5F0EFCA306B
-:103C20009FC180E7080EEEA46E15D4DDA416EBE765
-:103C3000CB4AA200279BD4D54CB87E54F313F8513D
-:103C40003C0E936C1DEBC727D60FE5A207F16971F7
-:103C5000D59210D2F19D68070A6A885C447B30CC0B
-:103C6000F5AADF07785C555F473EA28B711C9C8CE0
-:103C7000FEB9941308807F6F0122C8A6FF7795B222
-:103C800052F22B7AFAECC123598EE3592958609DE0
-:103C900056977D16E801ABCB3B0DCBA211730528DF
-:103CA00053AFAF1391AD12D393361EA5AB79228CCF
-:103CB0009719427E96BC412C892B13ED57DA5F0988
-:103CC000269C07A703DE2F29DDF5D08D0607458644
-:103CD000F1CCF4E428A51E8988D54E986F7F8EED2F
-:103CE000FE739A960088DD24DC3C94E2AD7FD7AC6D
-:103CF00029A077DCA07FE83A5716971C01932FD5AF
-:103D0000EFDD70BD02710022001E56C360D7C0787F
-:103D10003F585E8EF10FFA37800A8B15C172E61F8D
-:103D2000044C76ABA8489A7D26F669EF08176DBD5E
-:103D3000DF4FB67E1BD1F115EAF17B2ECFBEBA93D1
-:103D40007D4FA5FF037E4C33E9D9D480511FB84D78
-:103D5000DF790E6089F05EF2BFF23D2FD96857C05F
-:103D60005E2914BD114ACBA9C49B067E946302F55B
-:103D7000EF68DD9BD3ADC2942E859795DC8F25949B
-:103D80009FF5F47F88CBD7ECAA4DB39AE8B8E74B00
-:103D90005D7EA0E7FE549C66A4F75E4F4B3D31F07C
-:103DA000734BF136A4EB06AAF00AC03F2816D15E89
-:103DB0005F5DF8BC57AFC73ED1E4502FFA208A347C
-:103DC00096FB93143E9642319032EA9FA70FB3FDC3
-:103DD00074B9F4E1BCD3888F6F8BAF2FBE257DFC07
-:103DE000B3DF5B992C3EC1E559765523F35794BE5A
-:103DF000FD83DE78DD88787550BF26917CBED08348
-:103E00004FB57769D02BC6B880F586EFCFD8D107EC
-:103E10003CAC33CCFE3F1B37A5CEA27C0CF6ADE408
-:103E200035F841AB958D2AD8F3E7C12E07FB305CFE
-:103E30008EF16152C8E2B5308048EB294A20C2FCBD
-:103E40009B08D1EB4139C71877B3643A8CFA7B866B
-:103E50002AE8E79F5227E33CECF0BD4C8CE746E0B4
-:103E6000BB162F89A6A0FDC9F0079F62F180072E1F
-:103E70008B0E347A053398D1ABF1BD553925241119
-:103E8000FE7A7DEF56E37C93CA25F37B2E4939A554
-:103E9000B35392BF2791533A7BA742DBF7E178A255
-:103EA00076DECB422A9507BEEF9310856F133465FB
-:103EB000433C94A03E6BF29578519FEF124C7EBB31
-:103EC000C2E84749C7FEA29DE94DAD9E7C3EECBBD2
-:103ED000F17D2405FDDA64FD1BEACB1E9628713ABC
-:103EE000EB0E6D92281E1B97076604D1BF3DB249A9
-:103EF0001A12EF5763D1FC76AA3EC7C6F7072442D1
-:103F0000FB21DC4472F12A78E825CA588026FBB3ED
-:103F1000934E6CA74F391E89D0E3CFD021DB609D33
-:103F2000189F3886FD60A08B186FEA6275FA22D45C
-:103F30005BAC8100CE4B0ADBEFA1F06A49E17585ED
-:103F4000D7D378DDCBEBF9BC4EF505D49D32ADD39C
-:103F500032C51AF662DDC1EBF9BC9ECEEB69BC5EE0
-:103F6000C0EBC246ACB7C86CBC3552848DEFE0756F
-:103F700085D7D379DDCBEB05BC4EB6B1EFDB58DD91
-:103F8000618DB0F19DBC9ECFEB19BC9EC6EB8379D1
-:103F90005DD886F564F8731452F81BE44367BC8E51
-:103FA0004A84C3B5A7DE656A67F49221106E87A9BB
-:103FB000D960B71D98757F36C4431F3D71B50FE8B2
-:103FC000A7E1668D9EFC283F49CE4D28C7FA737F36
-:103FD000AEE1CE1518876808C98C89787C26DE5E2C
-:103FE0007204F4F6F919A21F1ADB92F82FCF723B74
-:103FF000FE191E97799AEF57EEE4FB95DBF97E6583
-:104000003BDFAF7C92EF573EC1F72B1FE7FB959B41
-:10401000F97EE526D8AFA4FD36F0FDCAF57CBF7267
-:104020002DDFAF6C81FDCA6140EF7558AEE2FB95A4
-:104030002BF97E6503DFAF7CE4CE92DF16D2F59DCF
-:104040007789680F24C347F16EA3FC1CB1C3283FD6
-:104050008BB6A41BEA43370D30C8F7C256E3BE4502
-:1040600041E308435D595662A8E7DE778D61BC9C49
-:1040700085C67D8B01736E34D4FB05A71BFAA74F51
-:10408000B8C350F75E5B69A87B4AEF36D45DC5F7CD
-:1040900018C67314FEC450B7E7AC30F47FDC52800E
-:1040A000F42567AE31F4935C1B0DFD6A1C81CF2DA6
-:1040B00020EFA6645E967C237F57B3F4F2D2AC1F48
-:1040C0002CB92410403DC7F411C66821AE3688C50E
-:1040D000AFEC1FDE7004FC175B21D353E6789579B3
-:1040E0003CD9F5D431957EA7DC73C4D7A5A35BE298
-:1040F000D3BD47979A2A3139B9E64146DFAD0F263D
-:10410000A673D404741DADDF248E17BB258B418F9D
-:10411000687E4DEB8302F6FF67C7D7DACDE3C6BFF3
-:1041200047713D566FB744F87CA88ED0D90BD6AEF8
-:10413000B4D904F53CF3972D9CDFCB27F84F3452CC
-:1041400078AFF412BF8DD657BA2A02CC2E1115942F
-:104150000FCB6E46BF5EEBAFCDABD1359DC917A27D
-:104160008B5BA29C7218E20A2B33FBB6DFE4980546
-:10417000E37F969840A2542FC95270523EE55FF9F2
-:10418000A8C5BF9CA07E4A181F206423DB77F619C0
-:10419000E3A68D734CF28FE7655835F9965981CFB8
-:1041A0001BBD7DCFCB06F382F9F07959634E2C2DE0
-:1041B000B1149CEFB85806D6CB6269585E1D1B88B7
-:1041C000E5D8583696636283B12C8DE5637955EC5A
-:1041D0000A7CAF24361CCBD1B1ABF0B93F361ACB39
-:1041E0002B63DFC1E7A362E3B01C19BB0E9F17C7A7
-:1041F000CAB1BC2276133E1F119B8CE5F0D82DF876
-:10420000BC28360DCB61B11F6039343613CB21B1D8
-:10421000D95816C666613938B600DF2B88CDC7324B
-:104220003F762F3E57624BB0CC8B3D80656EECC71E
-:10423000580E8A356099135B8EE5C0580BBE372047
-:10424000B61ACBECD843F8DC17DB8065566C339696
-:1042500069B1EDD8EE8DB563991A7B169F7B62CF5D
-:1042600060E98EBD80CF5DB1BD583A63BFC4E78EB3
-:10427000D8CFB14C891DC2E7F6D8012C2F85A74BAA
-:10428000D9C1651F1BF79FC77E68DC7F2E3D6A94EE
-:10429000E3256F1AF79FFD878DFBCFA35E31EE3FBD
-:1042A00017EF33CAF111BB8DFBCF453B8C727CE815
-:1042B000963B8C7A6493518E17B4DE6DD4238D4671
-:1042C000399EBBEC27463D72DF0AA31E59B8C6D003
-:1042D000EE9B6394DF59E431A39F3E619B518F5C59
-:1042E000FB53C378AED2E74D7E4D04E58BA3F817A0
-:1042F00086F7EC85074D725965F2C9146F0790C0B7
-:10430000FEE652E2F0835F63C6673A970719C0770B
-:10431000B4CCE47CD70FF88E96E9372DF4013D64D8
-:104320004C2D9B0576CC85138202B132616ADD305B
-:10433000D8EF491F48583C818CB80EE2684DD95AD5
-:104340009DA8026D6F1A4430BE40D4E5150117C612
-:104350009BB1FE5BE9C10AC88B69B2F276B292B535
-:10436000A7B0FAB1C6392BA03D3DB5231B12991E4B
-:10437000B72696E75D12DBDF1B28057E27D1F5FF08
-:10438000B5BCEB7E88CBFDBB3DF4AE449F2FB4871C
-:10439000F2606BEDAC35F434A88E02217014FA8D06
-:1043A0001402EF4928B78D71D629A038E9F37C298A
-:1043B000F807E89731D527C0FA353834B9FB9ECFD6
-:1043C0005B5C3F35A511F437D5D57C3F18FE34BD75
-:1043D00041F5E1A34E0FCAFDC86A799B8DD9854688
-:1043E000FDA166CDC6786273D312D4C7805F4BA29D
-:1043F000386B17D653C1BA1C0C7181EE5C89968B51
-:104400006CD126D0275FA5751E172C088FF3B09EA0
-:10441000FB6F0C61FF15CEA965B01E0A8FAF383C4B
-:104420002EF4050FFA17F4D1F9F934AADA2D18E2AF
-:104430009AA9969060EDC7F653617C5FC88F7ED9CC
-:104440001F25166FD7E047FFEE4BD7E23804DF4B4E
-:10445000B18EE93D9E368E000003BAE67A51A3EB99
-:10446000BA247A4A8B7713F5E66FB5EF7444E67E8B
-:104470009CE93B16C98FFBB6E6F72497510E5A5DAF
-:1044800021CC8790A5C4FBBBB28DEF5B6D997A59A7
-:10449000FBDC3BB47534DE7C59FDDBB5FED43184E6
-:1044A000FE391C8E64CBCD4877055C1FE770FBEEB0
-:1044B000D09F6E58D14AF939429FD912C41122CDEA
-:1044C00022EE6BE6D45082CB8FC37BA0C2EC42EDD0
-:1044D000BB036B8D7198031A1C375D1EFCB5FCCEB7
-:1044E0001C4AF8BF28E93D0FB2632A5B8F9755A598
-:1044F0000D417B0A9D5701A3253290BA23FA38A0BB
-:10450000793E84EF5F0CE4C30D74B1FE649771DCF7
-:104510005EDFB5BC32BA2F3DD8EB3BDF723FB0CA8D
-:104520009A783F95E20BF13DD064FF69A5B61FA8CC
-:10453000D50FFDA9DA0E7677D3C24ADC6F6FF23160
-:10454000FD4DBEA6A38E8DAFDB3CCE4E0EF7EDDC4F
-:104550009FDCB9A902F31FC96E237D0E79F8564777
-:1045600088D96FE9503ED5C6FA0DDD3C873FAFC410
-:10457000E7DB5BD9F3C16B4BF9F3127CBE23CC9E16
-:10458000176E98E080784EA3B7221DE33A75F44F7A
-:1045900027EF86784322C4E386B491003C1BECF5F8
-:1045A0008B20FF0BBD012CB5790FDAB4AD7C38ED53
-:1045B0003F6861703AE4B952C2C4FC430221153A23
-:1045C000EFC7F87A73B5F690B1BD8D7F2FAFAD729E
-:1045D000F970FACFBC85A18D934BF1997F0889F7CB
-:1045E0007B848F63D7DA03C6F6306F575A4FA21811
-:1045F0005016FADF9904FD9A8DDF5BC7FBB928B32B
-:10460000C1BC0B16061CC3615E45ACDF131ADF9AF2
-:10461000E482146E249375DF6BE5F3B62C64715657
-:104620004D3E6CE37180AD10071816EFBF46EB6F7F
-:10463000DFFEC4C7548F4B0B593EA9D6DECCE7A58D
-:10464000E5E514DC678CDFFEC2CAF8B85B66F15B97
-:104650008DAE92D13799271AFC3D127218EB337444
-:104660007621D403038CED6505C676FF0863BDA8EB
-:10467000C45857AE31D42FF4C4613A53F471182D95
-:10468000A6F384B712FD9078FCAF3B459F479ECBC5
-:10469000F9EDC9BA12ECD7E0E27C64CAA769522AE4
-:1046A000ECFA7DF8BD9C8FF6413C84962F40FE3697
-:1046B0002DF78F0ED8F341BFBF67F16F23C9E1B665
-:1046C00095E3710BE7C3C7009FB46CE3F87C84C724
-:1046D00075D6F3B8CE5A1ED76981B80EC667585C36
-:1046E00067158FEBFC8CE7A1EFE1719D67795CE7C3
-:1046F000191ED7799AE7A1EFE479E8DB795CA79DE9
-:10470000C7752672F9BD7F624736C4D91E9F98D8F7
-:104710004F9E28337D168480262DAF224A8315E8CC
-:104720009AC206F6754AEA148B0DF262030CAE25A6
-:10473000F3148BCCF271F06F3AFF0EE815CC9F7931
-:1047400093E7F5E450AB4847EFA30F4709E47564DE
-:104750004DF08E8690682AA747DAE6837E5C0D903E
-:10476000ACC35E307388640978E57E303EC17EF963
-:10477000BBC307C19C1911ADAD70D2F78B5E0E564D
-:10478000504F9B0C2DF21F1414C8170A8880E7FDA8
-:10479000E5FE234A691C5F741606BAA073447D9631
-:1047A000A7E9876B8D7471556C2BDACB4D753C5F27
-:1047B0004A2109FD78ADF45E2B9AE249463FAA6989
-:1047C0009931DFC35C8ED861F4C38BB698DE57FA9B
-:1047D0007E7FE826D1145F33E61137B9A6F7191F9B
-:1047E000CF8F4DEDD35FBCC552799D3C265E77C619
-:1047F000BE8BFDCDF6A004761EB557A5A37200ECC6
-:104800005DE9A837007113E9A8C24B3F7F1EE0F5B0
-:1048100020D6A9DD1884F1295E0C76A3850A7CD800
-:104820001BD90FC21DFD908B2B02D418DA7F1B41C0
-:10483000BF224D765EA7827114988BF891397E3233
-:10484000E4DAA7210E12A911C9365A7F7C61DFF282
-:10485000AE575E852B80FB4939B5DE124B1FFCBE7F
-:10486000A9569C94689F6C31A7EB95B5D3BDA83F22
-:104870000E5F326F60B1ACCB1BE8772BCF1B38C318
-:10488000F2E20669EBBABF6F3A78D4B48EFE49EC17
-:10489000EAE735BE73B1BC138DEE330AFAA6935521
-:1048A0005C3EC62222E904792B05507EF6BB358496
-:1048B000F9F1A0A0F57CD2F4CD75C887EA83EC1C91
-:1048C0004FBF5B03449F77AFCD63504E17B875A4BD
-:1048D000E9C03896C741E10FFBD74D0708FF8E8A24
-:1048E000C2C17E1FA980EFD9492DB1437CB3CEAFA1
-:1048F000C2738B8BC10BFC55DE1FE7D5BC4CC49437
-:104900008A86092C3EAAC97F8D4E1A7C3C5E3F41A7
-:10491000C278B7E4AD8D02DE9B46133C6F43EDAE2B
-:104920008B1735FF06F2BC323BF1DFD6A26814E8E4
-:1049300092042621FCB4FCC026775639ECD3ABF3A5
-:1049400035FB82E7A14A7E3CB790D3368AC5C33295
-:10495000C3985771BF187A4EEEA7A7BB0E844F536A
-:1049600092F3056B6596F7E44B82D7F7B91CCE90AE
-:10497000A393993F4AE93F419CA093F7DBD23CFDCA
-:104980007743499C7FB5F63F4A0AB66BF59C988CF5
-:10499000F3266DDFCE0FB85EF3F74CFE9B550A1A77
-:1049A000FCB05CAB82FDB4BA9C699467973F4F89B9
-:1049B000E54316DF68C073C680BEF9A689F3CD85CE
-:1049C0004126BBA3B088ED1BF7D81D22F150B86E6D
-:1049D00035D193A647AC45DE0DC3F27BD3C5D66572
-:1049E00095AA00FB2A7E82FB426E7F4700F6055D9A
-:1049F000399172B08F291DFC15E840A38B9CB6B18C
-:104A000008EF1735BD57472A0209E6AFD975E06FA1
-:104A1000F9D2616493DF43825EF0AF7296331B720A
-:104A2000208F2B0C54FBF6FB2E77FF5ADB4FCEA5C5
-:104A30007FE0F7FC42C3F7A7A6B89597B2EC589D64
-:104A40007EFF3443B0E8E8B2C7CF37BD47FD0B6FF8
-:104A500022B92D594259361DBD98FD77B39F4D7A25
-:104A6000E5BD9512C89BB24C997404F21F7BFCED16
-:104A70002D5399FCE278B3727FB4B73F79A7BF2F6B
-:104A80007D627599F659BEA53FE9B719F34B2F3BE7
-:104A90003FF75BC6231A789E5E2FBFC3348E180E75
-:104AA0008889CE6D0C091BE12EB98C76C79556C648
-:104AB0009F839B8D71E4BCBA0189E39D3C5FADB2DD
-:104AC0004CC39372FB1F29BFCD3F62653E10F78335
-:104AD000B578D37C9E375D09796C144F7348D00349
-:104AE0008D678988F93167C93B9EAB747C536563D8
-:104AF000E7E848B3F5249CBFD0F2B3E686595D9B46
-:104B00004F759BB15E45A66741DCB56A9395403E03
-:104B1000D67C229DECD2E64FF9FDFB366607559315
-:104B2000DA26906B2B793CB1D24B24C8A7AA79E93D
-:104B300089B1709EA7C6C6E4F7E714FE8A2EEFE699
-:104B40006E574406FEFE68DF55DFFF0E81F7234DEA
-:104B500003406FA6253E0731BBD938BF4BCDDF3CA4
-:104B60005FED9C46B27948BB8484E7151FD0E25EB6
-:104B700097798E64BB8DE13FD939924BBDBF0BDE77
-:104B8000EFE31CCAA5DEDFF34FBEFFFC25E65F6343
-:104B9000EFBE1EE4C4AACCDA20C8552D9F651109CA
-:104BA0000520566379659A3A50D1F5F35D66BF1CCE
-:104BB000DACF7219FD0AFB1EEF1CD7C3BFD9BD5D4A
-:104BC00006FE3DFBD31353C12E58F04B0BB1533AA5
-:104BD00038B7DBCDCF8B4564D08F77EFB360DC8007
-:104BE00048D1B1B7E8F20531B3908EBFE0676EDC13
-:104BF0005FBEFB795B640A7DFFEE173F1A45281CF8
-:104C0000CEADE87E7D20D83D3F1558FE95DA35EAD9
-:104C100016FAFC6E89DC154CA0B73A391F9CF9B91D
-:104C20007306D099B0EBC00F71DC8EDBAD369D5EA4
-:104C3000F88DCD8AF0A7FDD879AC6784C81081CDF6
-:104C40004F9F2FAEE5BD9D794660F37BD91A498110
-:104C5000F9ED6A9743B4DFE25D7F43BABEEE677B4E
-:104C60003C0087C52F5B0CF267F12E4BD4360ACB84
-:104C7000133694F701973016E049500F2CDA57831A
-:104C800079B28B3A5AFE66F1C0FB46FEA270C17340
-:104C90001F0B3EB0F8A740FD85A73D60C77EDEB97B
-:104CA000D30370A5E3CE92295D7DF7EF3A3E246CE5
-:104CB000FC587AEFF1205203F4B5B86335FBDEBE41
-:104CC0009B4F837C5B6CE2E3CFE11FD9BDF547CC02
-:104CD000668C479E276F8E857D0AB22B23617E717D
-:104CE0008FFEE07CBD60CFF9AD709EF8CCF37FD92C
-:104CF0000A76FDC2FFFA72EB03100F7835C50BF28E
-:104D000068F14FDFF3101DFC33ECCC8E3FF7CCD3B2
-:104D10004F3D46F9E4DCEF6D68E79CFBD5E95C8527
-:104D2000AEFFDCDE7F64C1B9DBFB7E35B13FC0E3A3
-:104D3000BEFDD7F5EFCBCF00BA8DD8F4F88D207E2D
-:104D400095970596CCFC0A2F4D783AB4EF502ECCAF
-:104D5000F3EC311B9EBF594C9FD59500DE6A503F46
-:104D6000407D1985F7A2DDABFE66199508EEEA4095
-:104D7000113745A203C1C85EB4EF967F195F0AA53B
-:104D8000D5AFC078A41BE5BBF9BDC547297EAF4CA4
-:104D90008ECFF3E46B19E0BF78F76AF6DD0E8A4F29
-:104DA0004F6F7C9E857F8CEB8DCF12BB199F0B9F25
-:104DB000C4D8E8BE8C8479241A3E6BF6DFD6A7DD12
-:104DC000A0C9874BC1791ECF9BFA2F5BA0C20E7C76
-:104DD000F6BC53F5313C47A6D0B6737BCEE7124AFA
-:104DE000279F5ABB7F0872B2FB57362FF81D77FFFB
-:104DF000EA03E4BB73FBDF961576FEC42550BBE2E5
-:104E00001CE9F9EB043B6311DF335BBCC31DB579CF
-:104E1000E2F85A14993649F1E0F313F83CC2F8610C
-:104E200051E4C0AD4202FC2DB31730FD14E9877088
-:104E3000A9A19E0E9CCFD7E35528037C9EB81EE8FF
-:104E40002F193EB5F57B61FD57EBF0BA83F1B1B98F
-:104E5000FF22CAAF20877BE137227C00E5B9769B31
-:104E600004F991E7AC2CFE66C67B1CFEFCFCE4B7A3
-:104E7000B417EFB727D97FE070B814BF5F6A7DDF42
-:104E8000167E73EC0A8E6B86E399AF13EB838D5C11
-:104E90007E2C22B59306E8F499CD4AF5593ED87B8D
-:104EA0004175A0109F6F538705E5FC995D9608E852
-:104EB0000BB3BC584412EFDB45ECCC7E59F4F281C5
-:104EC0005120D7CE1CFC39A74B46F78B769F9055C7
-:104ED000AE1F227AFD90C4DFFE291F6FF12B89C718
-:104EE0005BBCFB6F09C7FB5C0ADC0EF3FFBCD34A5B
-:104EF000543AC4E71D964989ECAD4D76AB31CFD617
-:104F00003DF6582A7DCFE27128B0EE8615810F5408
-:104F1000B04BDEB1629C9648FE4F6D78DEDAA1ACF4
-:104F2000A1706BF054613C451BAFD10427C91744F5
-:104F3000BF54CA0C96329B3A62F0A7ADD4DFD5CFEE
-:104F40009BEADD1CD04BC7479FB6C23AFF6CB21F2D
-:104F5000FF2C91A6FE74BC3FAB827FB992C85F3430
-:104F60008E1F5A66218A5E1FDABA8FC37CC8AF5380
-:104F700008E4AF595E4D51419E2CDE9A12817DCDE1
-:104F800043FB2F3C05703BF7A48DEF73B23CDB6A0B
-:104F9000BEEF777AFF85ADFF49DB4FC3CBF4FBD57E
-:104FA0005B697FB0DB773B315FF3AFCFA78E2254D5
-:104FB0004E57FFFA81A9205FAAC1C7A2FDAB7FD6D9
-:104FC0003FD240C73BD58FD54FED191401BC2C7C87
-:104FD000E1578B409F2C78CE4980240FEDFFE0876E
-:104FE000503FF76B37E67B9DFBF5E9EF021F507BE7
-:104FF0005BD1EBF5F9FAF3DE74DC055067EDC245E1
-:105000002EEBC08F590025A5F7052FA7E2F9075D04
-:105010003F7C6FB1ADFB7E1688520788E8134507C9
-:10502000001F2ED865FCDE5FEDCC9E5A2C7757B161
-:10503000FEE1018C5F3BF1BDAF353AE5EDE6F7B53A
-:10504000FEFF612F308DC3DE5F6423B589E8DF96F4
-:10505000C2C65DB0EB9B61C6F118BDF6FE0E7BFECD
-:105060002381E5E793BD29B84FB0508E0E4D2FC672
-:1050700078C73CE0DB859EE8D034FABD5F7279B931
-:10508000D041EBF4F9003E0FE80F7562EF7A0EF0B5
-:105090005BF3520A017AAFF9B51BE3C9352F5E38CD
-:1050A000F5387D7E66BF13E37A35BF5E8AF8AEB110
-:1050B000457F08F1BDEEBD36B28DF63FB3F7B7B907
-:1050C000608F9CB14673D3FB880FD574D87832B803
-:1050D000711DD42F28AAA5F35137B0BC9C3AC2EE5B
-:1050E0001DA883A00ED0F18729EC1C31DF97BA8769
-:1050F000C7A3BE98A3A4E2FCAFBD893DE7F1867BC0
-:105100006E56FAA7E9E6017973E42AEA97C8B5C3AF
-:1051100040CE5A62371105F6FF6283B1D4FA59E0E6
-:10512000FE8662C8DF62FB7ED64C3FA9A6E5D2743C
-:1051300012C2F397AE1B7BF8EC7714C5F76C56FAE6
-:10514000C378FE14265F6A1C81F129980F69BC7729
-:1051500041DDCFD67581DFA7609EEF05AB6A03798D
-:105160001EDFAF6379837592F201C47DC9112E975A
-:105170007AAD9FF1D917DE74E4336D1D2DF55E9481
-:1051800027ABEB7D58AEAA2F220AE629FBB16EE1D0
-:10519000F0B015AB04EE99001E843F9B2B1880FBEA
-:1051A0002C604C88B75B5C21A42F9BAF16630576FF
-:1051B0007EFF8EC5A5926A17C467189C206E0C707E
-:1051C00092795D6A9B8270A5EFE3F3898ED09C94FF
-:1051D0003190EF3BC220A7E4CC1243BD17DC34BAB8
-:1051E000D8F3BF0D3F82F05A5D6FC772557D19C26B
-:1051F0006D657D00EBFF1FE0D7CAE0770D5174FCB1
-:1052000023675618EA49E1B799C22F33CE5766385B
-:10521000D4F1FC1C8D9F92F1EF23F504375F36D655
-:10522000B761A93D4F4FA2D7CFA6307BA48E8496FD
-:10523000E33EA897C56148A64A7274F127E253F18C
-:105240001C089E3785F69C9B307EA9E1D7E2954EDF
-:1052500019E59FF201AC67E91B5611E495A56E3B79
-:10526000F92843C7C75382290AC2D98F71E006AE15
-:105270005F57F6E0D3C81F2DF50A966B399FACE750
-:105280007CB201F00EF13DBF88386D9D44507F3EE9
-:105290004CEBCCDF8F127D3C3CCDDF11B552FCA333
-:1052A0004C52B064F7701CB34586D0F79CC52400FF
-:1052B000F49276ECC7115C2BE9C0F3D669DA3D3085
-:1052C000AF14A4CDC4FD1F62657A8A585819B682FE
-:1052D0001F65866F83FF20DE2F916C3EE5C7E70BCD
-:1052E000F0BD0B33D99E59E69D1DC7E03E0857AB74
-:1052F00013FDCA2C7F6D5E2ECA571BD2ABCB1F127B
-:10530000AA7578CC4A62FF2D734CFE23D0E38790B8
-:105310009748F1BBB16D700AC0B9C5DAE10379D81D
-:1053200092C6F48D3283424177BFD86B5C4E7A4A85
-:105330008D724093CBDE6B4B0CF4ACC9DDF40946A7
-:10534000BAD7E4EECF7AE46EF02CC8DD8CD816E440
-:105350004B331F34586555B812EFA361F1A7130200
-:10536000DB57EF2D0F70DFFD8BAEFC6D701E5BE326
-:105370001FF3FAA5E6C9F89D1E7BD09A381F60205E
-:10538000BF97A199D21BA174D44AE90C10B18ED257
-:105390001994614A678C9FCAB0D4E8780561324499
-:1053A000DD27B279F278ADB67FB2C25E12003CAEB4
-:1053B000EC603C34C8C1F7493345CC0B90A83FE9B9
-:1053C000A28FA403E3EC605F4A56B68FDFED163B75
-:1053D000601F7FA56BBA1DF24A85B452A49FAFDC53
-:1053E00095797DEDEBC0FD6B407F5E979F9C2C8E89
-:1053F0009F9BB4784B08F8A57B5C9D98DFE472888E
-:1054000086FDA71A47A8C0A1AB8F84AF73BCC3B0F9
-:105410007B929CBF1CC5D743725452A893133DF78F
-:1054200025292A29D2C98B1543AEC7FB987ACB8987
-:1054300024F270E7FF8C3C6CC88B205EAD66F9935C
-:1054400019C03BA068A9C2D50AD43A5FF983D148F4
-:10545000A7D739C00F716DEBB183BE57D07B9E6665
-:10546000F917D76B0AC6C1A85E7BB40CE46952BDBC
-:10547000567B17D271EB4005E8F8C0BA079E84FA54
-:1054800047EB6C78EF4B556C3551E87CAB63E3B080
-:105490009CD7F61096956DED94890859BEB67ADDC5
-:1054A0004CE8BFD982F19F5391ABCED5D1FAA95622
-:1054B0001BDAEFA7B6DC9B07F6DFA956A762017BD4
-:1054C0007FCB18637B33BBFFE5549B356261F47B74
-:1054D000D102FB1184CB778802E9E64B4A15B4E38D
-:1054E000BF30EDB754AEB705044F72F857B625B6C6
-:1054F00027F1FC36E45C93DA61205FCB8FFF380F35
-:10550000E84393334BD3A9DC03F81DB79144FB0266
-:10551000131D1317039E263A024B19BE2EEFDEAC65
-:105520008F446A77239E429E6986B82F8BAB7EC4D8
-:10553000ED72624FD2EEE1EF7B13B7D7B4FEE5F523
-:1055400007696D55B131AE6D8178B500FEF83496BE
-:10555000EFA0ED03F5A66B664FB7DA50AECCE1F1E4
-:10556000288DCEE37416F2F07C31031DCE8F6D4092
-:10557000B927B48C7C741C85DF9794FE803E84969A
-:10558000F1FD01BECBD77C67FD9D74FCBFBF69C137
-:10559000E7F36229D8FFB307FD8FDE09FEC2BF5BC8
-:1055A00009C89FBF1F9988FBC89F598D718C7227AE
-:1055B0009397AF72FEAF8AB518ECF3AAE6D932C45E
-:1055C00041AB62EBF079156C22611EFD1DAFC10687
-:1055D00070152CFD1A78FFF6892B509F96601CAD34
-:1055E0007AAD2D619EFFAB0EC520AFAABB5A715C90
-:1055F00042EDB3CC2C3E9E4EEE54C732903F8857BE
-:105600002590F75DC5E54FCFFCB6580DF2E7B39492
-:10561000C4719AB71C6C9D55B1EF20DFF55EDF7742
-:10562000F17995F6DD2EC6A7F1F53C3A2ED17AE256
-:10563000EBB816FB7F9696F8FBE7397C4FD5CF2366
-:10564000012ABF2A6DB49F0BBE7F6F5319F8F95B17
-:10565000D2D205DDBAAADB1690806E5DD55B66C935
-:10566000FAFB29E378B8CF8087F36B16231E9639AF
-:105670008227400F54B68C1F15423F7F35C2F92355
-:10568000AB3F17E4F1E9B67B3D89EE913C6FC64F25
-:105690001BC70FB5BB4B75F8D1F0627EFFD49FAA34
-:1056A000BF7A10E4D466B741AE98CB5E78CB4F0C8E
-:1056B000B7544E9FA7A8FE0E21DC94178F015DAF53
-:1056C00075627E5C72F85D41427DC12F89FD4CEDB3
-:1056D0002CBB730C7C97201CAADB181D5C0A6EF196
-:1056E000EF723A284FBC9EF14E8D0EEA884A19F6A9
-:1056F000A47C293A7880A8F63ED6D143076DAF95B1
-:1057000017C6E960BC333C7105EDF729D83FC37A71
-:10571000E3FFA4AC7AAE017B678D05F7BD4E3AD4AA
-:10572000AC3B587D34C8E7939EF0D46B4AE3F5F95F
-:105730003B8778F4F73A9E6EA6704800BFF1CE24FE
-:10574000F453A892E2B1FFEFE8E7A324E760263A1A
-:10575000CACB019F249C389EAC959AFCB6A4BA7A19
-:10576000FC5ED0A3275D055F4568EB3A47E86627F6
-:105770006D6F4CBB1FF5FCC99302EAE1E57F5A3A15
-:105780000CE4702FFBB73EF6D8C743306EF9F8C76C
-:1057900056B4A7705C42ED1FD003986F8E7EC04058
-:1057A0008CB324DBCFBD172EFF1D13DFD7D5F66FCB
-:1057B00057D6773E04E313BB4ABCDA797D054A66C7
-:1057C0008FFD07CC43179F97AD21AF1FFC5D810470
-:1057D00081EEAD52A819F20CADBECCD1AA0ECE4BC3
-:1057E0009C2C2F27E5F0E1E67CFA7ECADCDF7921EC
-:1057F000CE67A3DF81D29E237DA18F975B3359DED5
-:105800001729D43D2F8073C8B46E883BD0F9F6E1D8
-:1058100037FF52E8B9670DEF379EA95DF405A0A3E5
-:1058200074F37B2D7F456A64ED695A73236BE771CE
-:10583000D4C5952C4E7A68562AC24F5BD7CC5756A2
-:10584000E17D6B335FC9C6F34C335DC33E0178FE27
-:1058500012126B80EED3987E36D3C5435CFEFCA05B
-:105860005D54AD74BCC3D6EE834EE08B1F09E85780
-:10587000DFF1DE612B90FC1F8E9EB4425ED45D9002
-:105880005844D7338B283233A223F8FE6CD2E1661A
-:10589000F58E7E70FF697C3CEA32C3784BD8FEF30C
-:1058A0001DEF1D9D086A948EB712CABBDE24328C90
-:1058B0003F6B9FD2C48E43F1F15EA1E389F1F17A8F
-:1058C000E027D9111E71F8D8115EBFEF395FA2A28F
-:1058D0007DA1832FDA2B1A7C1B006E147E33536755
-:1058E000DC484625E79799AEA19F9051F1F998E1E0
-:1058F000FB7768A2FCF68433B017F8AFD119781E95
-:10590000F867A1BD3B572AC073602FC2F34596507C
-:105910005E16A5ABB38342C3FAC1BD1E9D89F7795C
-:10592000CD7C7A1CF8E54A28295FC03CF879951FA0
-:10593000F2751EFAF169379E47D9FF412E943596CC
-:10594000AEB5B703BFFD9B05EDCF2FF60DEB33AF23
-:10595000EE388FBBBCE514F9796BB6CEBBB83D779A
-:10596000D73E6704EE41BCABCED2E35F015DDF55AD
-:10597000C7F24F88D439EA56833DD9C8F7437A8FA6
-:1059800003FE82791C6D9D0773075C01FEE593633E
-:1059900064F4230EBCF9C5EFAB69DD31C88E7EC25D
-:1059A000DA344EBFE5CC6F7D322DE01C09F1AF3506
-:1059B000E97E95AE73CD6BA443A4703A38FCFE48E3
-:1059C0004529DC0B2D62EC6C7D6C7BB802DE2B660E
-:1059D000F7CE78B95DBABEF3641BD0E3E96336DC79
-:1059E00077F8CCCDCE11AEB10673C18EFFA45D4E5B
-:1059F00078FFD99FDD12CEB75DE81280CE6793B0F5
-:105A00001DE4C5BECEE9FD613E1E3FF102F99FDEF9
-:105A10006211D9FD685ABC252AB178BF2AB17A80B3
-:105A200097DE14FD7D63AB274DC03C8F39AD6F63AE
-:105A3000329EA734F13D3FA92E365F7767FA64BCEA
-:105A40007773828879D86E7FB700EFE57556C8F80E
-:105A50007E58E8F3FDBC655ECC4385F741CEE75D3B
-:105A6000E6FB3617CBD3DAC0FDEC76ABBF69021D7F
-:105A7000A77D6D9A00F8D0FA292E26574E4FD0E216
-:105A800048618C23E5167A53E01E8BDC00323771B7
-:105A90009786F1BEEF6DD08FC559110EEDC35F8CA7
-:105AA000C23EF61A88AF009EAD8C9ED6AC1530AEC5
-:105AB0004AE13700F4C4270FDB6E8275E4350B5ED4
-:105AC000F0DD699970DE33DC7646E7AD8FA25F08C2
-:105AD000615A183777CBBB382F7792F5AE70B37B0E
-:105AE000F23FB9047D7CE964F726E6D675F2FBF156
-:105AF000A2780F5E18E004F54029BBDF440A28FABB
-:105B0000FC9838FF2CE7744802B0CF56592647203E
-:105B10008E2036B7CF8075CF0EDBC80D747DAD42B9
-:105B20006700F8451D23F2FB9402C7014EEB36F4E3
-:105B3000C73CBC55622017F4B0FA7F64DCA73B1861
-:105B4000F86233DC1FBFB54C46BE381860E70D9FC6
-:105B50005C56D00EFB94EEBA8AB6D974BC88574610
-:105B6000C9D2504ADE1806FB94CB44AF40FB878372
-:105B70005ADEB6D7017431DAF2E5E422D8C7CB1683
-:105B800031A6745A60F736AC5C56E105BCAEF466DB
-:105B90000A7AFFE5764E07C7D383B7BB287C7C0F14
-:105BA0006EF452338EF267C6151047549B65453B21
-:105BB000B70BF73D6470BC64748AD12A0FD65DF3CD
-:105BC000D2E13E5D162F7DE8C6108B73C2DEE85829
-:105BD0008C73F23F1FE23593D7D68C706065D38A01
-:105BE0002AEC0FE364D171324AC5E8583AEEB6B4F4
-:105BF000C0568CDB4DB4239C88D4D506708A4C1CCF
-:105C0000E0877B6D378E1BFA369C5FC938D23D1D0D
-:105C1000F4686490E30FED20A756CA0AF079C6B283
-:105C20005377C2F334FF23F74299D1F8FE0320A73C
-:105C3000D3BAFE568FCF27C986F862C6879F7D03E9
-:105C4000ED1941D910A7FC3A3DF81380CBD6E2708C
-:105C500018EFC5048C66C5D7B16779E724B8EFF8AB
-:105C6000F434D1BF8DB7E3BA3679236B18DC4A41DF
-:105C70002F68705B252A1D5158D7543BD24721E924
-:105C80004479950DBBD983E378C9F870F512C8D76C
-:105C900030CF679D4BE8B97F03EE09045C417E8CF1
-:105CA0009CCDCE15EE2DE9F4813DBF362D717CF2F1
-:105CB0002D377BDF26B238ABB9FD0D37A30710892E
-:105CC0006D252C5F7E24942EA2A64299630F40FE80
-:105CD000F35E51F923D2F9468B02F881FE568ABF52
-:105CE000036F7C8EF1C503E177B17CC65DA4E5DD71
-:105CF00047B3E8FBEB4AD97DC7EBBC8C46AA9B991E
-:105D0000BCA8F675D961DFA4BA9878B7717A533513
-:105D10003843BC8CEBABCA5B195C338B09EEFB429E
-:105D20002C08EE9BCA827E147E99CDCB97201E490B
-:105D3000A73A98F65B07E3027E1A45C2C6EDB22386
-:105D4000FF862DB8EF49F9FD2D886B55B6F6C77D56
-:105D50007F38360CE3A5F3EFA6F3F1DAE938103F0C
-:105D60003CDD6CC17301907E03756519A565A4CFF8
-:105D7000EEF2223AAE52EAF5AED1E84093639435A2
-:105D8000E6507D01709BA3AA4B80FE4EDABD6FC02A
-:105D90003C9C9B6C0AAC7FCEA6979682FDE2F47584
-:105DA00035837CA82E63F34D6FA5CFD1CE51DE8213
-:105DB000FED5AD36857D8FC3AF94D31987C35C3EC6
-:105DC000EFB95BD8BC1D832261A0CFEA6514AED0C9
-:105DD0001662740F21D18B22F2D51158BF5BCDC250
-:105DE00071FBCD30F18589FEB47555F275552E6382
-:105DF000EB229C9FE8B4A2306E65295BE71CC2DEF3
-:105E000017E1391D7F2E5F4FA5FA2296739B6D8691
-:105E1000F1B716EDE884F9E417CB0A9E1321ECBE26
-:105E2000C35CBEAEDC46F6BDDCE217115EA44E37A5
-:105E30005F8CABEAEA94AF4EFF9632165C0A00071D
-:105E4000D8E8B8277F2CE37E4EE126E3BA4EAF1E9A
-:105E5000B6BD95B67FF4B08CFBDE7B45FFF13CF41C
-:105E6000476585C91FFFBB53404ECF6DF4831CDFD0
-:105E700053CEE07FFA6612017A187224980EF01E53
-:105E80007224C4CB5ADC4FA700117AE41E9D1F7503
-:105E9000999A059097B1C1CFCE033950C6EE231F12
-:105EA000A49F379D5F46735605E4436596A557C882
-:105EB00078B5ABA9FDC863D345683FFCD8BDF09D5C
-:105EC0006CA25B0F6D973D83D97996C3B415FAD553
-:105ED0009D7A10F0D1CACFB90E8199A5637918CAFD
-:105EE0000CCADF2DE9304F894C2889CB839D0F8F59
-:105EF0001D0D7205539E4AB08C9292DE7243D77F7D
-:105F000038EFAF0A09FAB93D8AC13FDFF9F0F5C3AE
-:105F1000C18F5F0776622ADCC7E6FD12F27454BFB8
-:105F200088705F678DDA8B697D15B51BC17E595FFF
-:105F3000F4BE087CB76E1FF1037D6404FFCBA6C7D7
-:105F4000E30D6EF6FB3C924C5A80FF0F0E3F350975
-:105F5000F0143940ED4EDABFE237AEC79C600FFD5A
-:105F60009EE5C1B4FFB616F5F7FDB972C2FB78C95C
-:105F700025EC4473FFF421D3319E97B76903DEEF1C
-:105F8000593D49F2DF407B676E2A2F073B46095295
-:105F9000EAEA4FE7BD65F4726042650ADB2F5326DB
-:105FA000B1E7CA0456B6D41F7908FCF6F02E29A52D
-:105FB00090CE77C46A76AF584BF117F610B54B4BBD
-:105FC000CB9FB7DF4C9F7F5C4AB5207DFEF1B55F6C
-:105FD000A4C0FECE93A5151900CF7DCD46BB8EC0C3
-:105FE0006557D41F1A690B07DC745EADEF1184A7E7
-:105FF000C5166DABA475CB4B2EB0707AF939AB5B7F
-:10600000DB67009DCE2992316C6F5EEFFB5C9FCC0D
-:10601000AEEB9E04F7EBE7AB84C5F7C38FA2509EAF
-:10602000CB4546BEDA8942C7BD89F9276129F03AD6
-:10603000C8E570714886573479D63AA4F22990673A
-:106040007FE2761DA99D87E7C890FF2D600F7597A9
-:1060500027F29B4A5D0EEC7F7ACB2D1F409C7A4E37
-:106060001DB3F7F3B67C29203EA8DD974DC7CF2B93
-:10607000C5AB06C99C6561FB48C04FA1481405E645
-:10608000D341C04F0853FDA3878336EE7FF7FD252C
-:106090006E1BF26129D8CEBAF5B8F87A72FD743D5C
-:1060A00009F47409FFEE8F9EF8F2C03880FF32E6E3
-:1060B00022E5854F0876DD3CF2D4CB9BC755301ED8
-:1060C000D8AF6E2F8EEB2EEDC2FB5CCCF21DCC79DF
-:1060D000E0DBADCE73A3997F6F94A7BDEA9CAECCF5
-:1060E000CF734DF26AA4ADE346C4EF1E76EF35647C
-:1060F000C442BB404485DDFB19D1EEA7AE857E23AB
-:10610000DC2E2FD041EBF0F74B003E6BB9BD30B722
-:1061100098A0BF3A37A713ED85D98DDC5E90FC4D72
-:1061200020649D5BD2C81A9DFD80A612B8D08DDC7C
-:106130005ED0F43FD7DBD5BECE66D4AB8DECBC5F72
-:106140008F9DA132BD9AE7637ABDBA997E47E1C4BB
-:106150003C566F97303DAE6CE2F603D7C319FCBBDB
-:1061600099CD4C5F65801DE181340815F532EE61F3
-:1061700065C5ED967EC54C5F66B4EE45BDD6013F64
-:106180002E3306E406D39783DE3EAA02987CF47190
-:106190001B95D38FF3769F97DA67E971FB6C95C8EF
-:1061A000F79B08B30F31E79FCEF321E8AFB31B771E
-:1061B000F0F9ED3D9C7E13C8D79DE1023C57AEF14E
-:1061C0002D463F693DB794E5AFE4D6B17D72B7BFC8
-:1061D000EA29FDF9B3796E76EFD03C8DAEEAA23EA6
-:1061E0001817EF8540392E637C7135B59730FEC4A2
-:1061F000FDAB6B5C3CAEC1E927993ED1E4909B04BA
-:106200003CC514BE1F479E4279AD527F09D6F67138
-:10621000B861C0DDC0EFE169A530FF75E3BEC2FC27
-:106220008FBC24FEE29F353FF35BCA75F7A4A3CC75
-:106230000FED14139EEFC9F1B0F84387449C00CFD3
-:106240009430BB472EA54C4ED83FD5C3ECECCF398C
-:10625000DCD68D7B0ACF6726D5CF12512D09F4A944
-:10626000A66F5B01CFD7D0FEEE379A54F4D323410B
-:106270000BCA57767E314CBAD08F548B648C1BB6C8
-:106280005AC376C0C7FA528E57AFBD1DEEB7F9D6C6
-:1062900078A1F0003CAF0E8811211FF01CF18E6434
-:1062A000711D3CB77C9AFAEFFAFD8AE11E91C34951
-:1062B000C11FE6CB6B66F4B56E9C8CF358333AABDA
-:1062C000DD92AF97BF02979FEC9CD89A71AF237D68
-:1062D0005DEEFCAAEA9EC57B3FB4E7A7363F5D00B2
-:1062E000708EDF7F11E8F33C4555DDDF36ED48B0B9
-:1062F0004FD0D30E7E940BFCC0C81D867D4D8EDF23
-:10630000091ED1107703F96A45E7223200E24B7B80
-:10631000C6473CF01E59C6F66DE7F37DDBCF77DC50
-:1063200082E7C94752B2B226C0FB67F5C6F3EA9FBF
-:10633000ED7C7A008B6B440C79C2F39FFAF908C3A9
-:10634000FE7080289963F915ACC0EFAFFB559B2513
-:106350007EFF800CBF57007176E0E0C170AB620732
-:10636000962EE05F5A7A4837965E504783C14FF2C7
-:10637000639949825866915A2C7D248CE500D2811C
-:10638000650EF8B983412F7463A910AF487472BFCA
-:1063900080F8B15E4882584A80B78CF8BE84B4CB8E
-:1063A0008EF91BB07F017C9FECDC99DF53B9C4836D
-:1063B000FC5D7B25FB1D23B65F31DD13B8C78378F9
-:1063C00088A2FC9ECD45F991E74674C0F9A37BD61F
-:1063D000B2732F9A7C47FF867EE7D974A60FD48DBF
-:1063E00002CAB115CEA9DF4578B65ACFE8F71B88A7
-:1063F000DD5E08BF0FA28D3B9BC71966733D08E1A8
-:106400006E767ED08FE7936643BC41D74E7ADAD959
-:10641000BD34DA38A2F3DAA17DEDF7E9DEC7FCE896
-:106420004A931F7049FD6DAACF31BFFF359D50566D
-:106430003C1EF7EC77955CA457AEBF294129F85E66
-:10644000B3ED04FA63E189013D5C9EE17CA0E9952E
-:1064500039A67C0F733947E2FC611A876AC0343869
-:10646000D78B774AE8F85BBB9F54BBBF677E20247D
-:1064700067B3D77C80472F9F77986CA9C8A6E5A7FC
-:1064800050D7C5F78FA6865EF2E8FC116FA056D4F0
-:10649000DF77B390F3E3444B6B39C8B9D321E207FC
-:1064A0003F623EA9F57C07E2F9472D28E706D2793D
-:1064B000CBF07B2FB0C1918E75157EEFE56C3D3B27
-:1064C00027748ADF33FC14DC4743CBBFF07B85475E
-:1064D000B62D9D0A74F039BF5FB868DFEA20C47D2D
-:1064E0004676386781DE1FD931BE1ADA47EEB2B17F
-:1064F000DFF1E172429B171C7377A4E33976D59ED6
-:106500000EF284A0DE3DDBEA88C0EFFF9CEDB0B068
-:106510007B558B45BCBF0CAE21B4F0F9A5A6C3F7E3
-:10652000FEF387608F7CCEE5C9194F1AC397A40A82
-:106530006A26A4A5103FD8351B9C8BF01C64952BB4
-:10654000F2D46399901F6EF7AFA0DF3FB0F7A55C60
-:1065500078FEA87311967FD9FC412EC8ADB3FB3FDE
-:106560009013D16D8D1495213EB5609F20C2FE49D8
-:1065700079C72C19F647AA761FC0B8728D3784EDFB
-:106580000BDBF6627DC2EEB771FF6470AA82F33A4C
-:106590009B1DC2386F619B2D0ABFC7B1A7207C77B6
-:1065A000C27DFB54A66736385FC5F11F75BEFA3A47
-:1065B000C265B30DCF7F1CD8FC1B1CF7CCFE97F82F
-:1065C0007C09E60B9E4DE938FE13D05F7BF9794CD0
-:1065D0007BA7471F0F965205837C3DEBE6FB5E3998
-:1065E00097E8C7F30589ABD3C3E452A707F6CDAA52
-:1065F0003A181CFE628DCA60472EE81014F83DBDA3
-:10660000F2DDED781E70C13E3B9E975800F000B859
-:106610005178215CDA0EE0FC0B002EFD601DEF626C
-:106620003E7EE13E0A9751F1752F7085905FB5F57A
-:106630005238B075EFB9149E42463CB5BD2D435C4F
-:1066400066E13E01E1B770379B47D53E36AF09BBE7
-:106650006721FECFEC270AC45B4EEDFDE07358CFF7
-:10666000D9FD76BCCF579B17DCB7E02901FE6174DA
-:106670004AF631B9AAD9DD35912CFCDD819EF6DDD3
-:10668000EC7749016429945E47EE9B86FB82A54026
-:10669000BCC0FFDE8E11ECF705C3B900D73DE3A304
-:1066A000B930EF33DAEF2349E15CC08BDF132A4DB9
-:1066B000D5E1E3B3132FA15E2C126BFFFC20F0F1A8
-:1066C000F3EC7738967EB841D4C3E33AF841AA3167
-:1066D00000B7B73C08B79EFB5BC22C5F8A84901F53
-:1066E000AB383F9E6DA77E275DFF676D2F60FBD99E
-:1066F0006C637ED55FDA0EA503DC2AF9790C12B93A
-:1067000005E511854BB33D819EEF39D71661E7153D
-:10671000CF09FC3ECD2734B8D5CAD30DFB7C4C1E27
-:10672000E66CC93F8C7E4624F13947B39D64BE2F89
-:1067300035593EC0492ECF3EE6F774697A77BA27BD
-:10674000342BB55FF2F3DE952D35B900EF4A381BD7
-:1067500089F79C1EB801E215786E88DD931A05F85A
-:106760009CEAB907F5A51B20CFF4541AABD7A57640
-:10677000AE02BBF69476AFAAFA1A7B3F9FB56F8242
-:1067800076DAFF394FB03695D9F702FB7D1F6B1AC9
-:10679000FC4E83A63792C3C1F83B0D4FD3B5025CC4
-:1067A000E8783FC1F1243ADEC87F7E3C4D4EFFD3EE
-:1067B000E3D8FF67C7D1F417F027A43E12BF7FC408
-:1067C000FF04FCFEBBEF93F05C035F5DD83CB809AF
-:1067D000F6D1CEFBD83D30B6D6E504F4F9DC4D1B3E
-:1067E00012FEFE5B4F9DE7E5C88329BFE9F8FA4832
-:1067F0002AB3CB8F70390D7FB0BF0577E5A05D4C14
-:10680000FF5AB3307509FDE761FC1EF3221246FB07
-:106810007404E9C0B2987462398A746389DBCC83EA
-:106820002154EAC7F2AFE55D6361F10BEDA1275397
-:1068300044CC3B780DE4D0D941A1A7E1A2B615CE56
-:1068400045D7C0FCDF48F57278450DBFB742F4BFAD
-:1068500087A1803D38C5D7973D48BCD2999EBC974B
-:1068600002BCCFF6ED545C5FB2DF515B62BAF786D3
-:106870009D0BD7E050433A308FE4B52DF7BC319CE7
-:10688000C2FFEEDD6EB493876E695C02F2FC6ED2DD
-:106890009905E78487F27B44481BBB0F47BB1F6405
-:1068A000789BCDF83BC2A6DFE359C07F3F6B81F9EF
-:1068B000F7A9F839DC167890201FC37C8EF7AFA9B2
-:1068C00089EF7D21C5897F0FC57C8E77778788F911
-:1068D00051F740DE95CEBF18BEA3D666A42FE5DFE4
-:1068E0000AADBABAE067F108B723B053E8FD9DFFDF
-:1068F0000B82D8B2B4008000000000001F8B08009B
-:1069000000000000000BDD7D0B7854D5B5F03E3360
-:10691000679E99849964924CDE131E21C86B0221F4
-:1069200045A47A122246A43A3C6AC15A9C8040800F
-:10693000BCA068B1C59F8144081425D488400107D4
-:1069400044C5FAE8A417E561B00344448BBDA15ADD
-:106950002F522F1D901F1111466DD1F66AFDD75A87
-:106960007BEF6466480AF4FADDFFFFFEF4B3877D2F
-:10697000F63EFBB1F67AAFB5F70C77288CA532F668
-:1069800082A2DCE31DC4D837F87753D773AA5DC75A
-:10699000D808067F8D6C5C31630DD5AA7D15941ADD
-:1069A00002564DEF84A75D1750F219CB4A2C33CF16
-:1069B000853273E8ECFDDC8C8DD58F3EEC86F6C617
-:1069C0001A75B809CAEDDBE67618F07B97CA4C3029
-:1069D000649603FA8532CBD005FA41B9D1FE1BC7C4
-:1069E0000C18BFC006EFA19F1C3B0BB8A1DFFD5BDD
-:1069F000EFD761B9A19EB1741C47F175B8E93B9519
-:106A00003D85D362DAF8A234C6F2F09F308ECA56C2
-:106A10007FAA4F62ACBCE6B4256C83F7E1CAF16C87
-:106A20000863A5F67C5AA7FAFEAD1F6179CBA25385
-:106A30000E1F8CF7C6D6E57F180BFD1902302FE824
-:106A4000A2F0EB86E36361BCC85623DBC6BAE090D4
-:106A5000BB583D1536D380EC1BF82F7B616CD9C831
-:106A6000A05C28CAF9388FA87A280F17E333368537
-:106A700085D2B05ECCD7A93106F364769BF3CC40C7
-:106A8000C66EB22BEC9BDE5DE511A2BCC3D05C668A
-:106A90008579EEF84FC5B314AA0F6C9D9587EBBBB3
-:106AA000B4C7976787752C32270D61BD2EDF3F83F2
-:106AB000DD2DF6CF6FD1B9F019B2305757FB01DB9E
-:106AC000EB4D3EE8A77109F39CEEC79839D06E1DD7
-:106AD00088FB78D8E081227B4861538250AFDA98F6
-:106AE000168471860B7C897F3EB4C4FDBBBE86AE26
-:106AF000711FFA7AD214DCDF48A255DBA65C3E2F68
-:106B0000F99D6A77FB717F0DD9CC9300E3199C1D29
-:106B10009976F86EE02EA3C706201BFBEB41BDC2A1
-:106B200030EEC08353993B91C30BE7AB2E327A4EC4
-:106B3000A730665AE4F4A8C3B19D8DF0F1339B31C0
-:106B40006042F82FFA7933D6376C2D71B9A3F07AF9
-:106B5000F912BB4785796E5A62F6A8B0C0E5627D2E
-:106B6000F1F3CB71E8BC01F8CEA8633EAC5F00FB4B
-:106B700080705C604FA0E77C51DEACFA27E2FC3706
-:106B800003FE2C457C5DC8F1774186398078BEE0F4
-:106B90008D3EE9AC1BBA92CFA797B83C7D611E9B96
-:106BA000164E7731F8B4747EBBE51658FF8244B3B5
-:106BB0001DF1519F54F0F868C4F7370D0CE9AA2174
-:106BC000B1C43D23AA3F7DD24817C243AFF3673219
-:106BD0003B632BECD32AD40CC417FF46E6616C4D03
-:106BE000F3CDBC9CE8CF54A0FEF1E65B7939D5BF6C
-:106BF0005181FA279ABFC7CB39FE4C1D949F699EDD
-:106C0000C0CBFDFC1BB1FCEBE6EFF3F26098432632
-:106C100063BB9AA756F861FC0683678A07C67D1195
-:106C2000E63F08E61F14CF3D76BEAFB2FE37F81E32
-:106C3000E0BD533CE3EB5F16DFEDEEA17EAFA86F46
-:106C4000EBA1FF57C577A11EBE3F20BE6BEFE1FB56
-:106C500043E2BBC33DD4BF29EA8FF4D0FFEFC57731
-:106C60001D3D7CFF07F1DD3B3D7CFFAEF8EE580F8C
-:106C7000F5C745FDFB71FD9F10EDC3E27D7662D344
-:106C8000713FE05D36F02DFC2B4C6C4A46BCDB546A
-:106C90005F4CF8DF3002F07C5017BE672BCC8BE5E1
-:106CA000210E95FA1B82FC189E6F8BFE4BE7F75D59
-:106CB0008378B7E02DBD07F1B041F11CF341FFFE31
-:106CC000F93A0FF2DD056FE8399ECF57032C8ABEE3
-:106CD000DF8E9BFF1631BF4631DFDFD97B13DDE44A
-:106CE0002D7279C64B7E89746F8F2D9B819E3418CF
-:106CF000BFD1C9E54BE1FC32737F941F205F906FD9
-:106D00003E6433864C30FE437695EA1B9D6576AC37
-:106D1000F7DB55923F0F39CBCC3390AFDA80D99562
-:106D2000C07876DE77A35DAD0820FF709453FDD860
-:106D30005F8FB7231F6D64114729AE6F31C815F8F7
-:106D40007E7F7D19BDCF73FCC581FCF968325F572A
-:106D50007BE2214B3EB453EFD391BC28B0AB24C7A8
-:106D60007A2FD605DCD0A4DDBE4087E5271BB9BC51
-:106D700082BFC42218BF2F1F9EEDB8BFE4CD42943E
-:106D8000670FAB1EB79BBF53A3E4415F94574938CD
-:106D90006E728CBCDA5CCC34ECD7EF32079E827E0C
-:106DA000FBAACC9592DC05F73C879ECB17FD780FAC
-:106DB000CAB53ECDB1F229BF294A3E319497B1F20E
-:106DC000295E5EE5D4037F8CFADEE4B2C7942D8E93
-:106DD00044924FC0633CDFC0D00B5A17DC62655D44
-:106DE000FC3A5E1E3508F920F96EC3D7C363E4830D
-:106DF000E4CBF1F2E1CAFCF5ED5BFB131E02B772C6
-:106E00005F99CFBE8D7800F867F029243F98EA7328
-:106E10007913AF0C2F83C16BB7DBAE0C3743EA3B62
-:106E2000A457187C2AF57F995CB9025C653BA3F9ED
-:106E3000C9CDA741AEFDE5FD9F14322099E5001BA9
-:106E4000DAFF545DE0295877F6A2E73663FF5987E9
-:106E5000AC8D0867A36BC6E6465C4FF3E38C013E3E
-:106E6000E9CD1C9F8C196576FC5ED569AEE43E5079
-:106E70007EF6DDBB14C0277D4ABD87C1BE1D7EF1F5
-:106E8000CDE4DB107E6F1988CE4D3AAF9DF5A1E9B8
-:106E900010BEADC8B16E5D4578EC33239CB27798D7
-:106EA000490E30FFF6951A2075036C071B85F553C4
-:106EB000566AB0EE1D4A67F9562C070346DE1E5887
-:106EC00034FE5FAB4E11F54C535DA4778AFADF5464
-:106ED000948F86F6AA7DA00A7267C1DA979A0C3958
-:106EE00058AF93DF6B6C24AC17C7136515F6E7B981
-:106EF0007651EF3FD8540E44D46A94E3333FB66FD3
-:106F0000D5E978D9DFD684FDBF5026BEF73FBD5204
-:106F1000CBA6F9DCA67740D1F17A93EDFAAEF9AEC3
-:106F20004D7EAB6929ACEF1377380996C16AB69EDE
-:106F30004E43F9BC624ABD17E18688EF0599D84BEC
-:106F4000EF263CEDDCB79D13FC59507BF1D0DF936D
-:106F50000641559D3E7C2801E057B3BBDE6C80EFB7
-:106F60004D06AF3F2BBFEBBB9A9D95A4CFD4B51573
-:106F7000D1B39BEF0EABBDFFA5EFCCC6AB18EF9323
-:106F8000D01F6A9F87AA1A7D7D934D4FED19DFFFB1
-:106F9000EED727BFFFE4F93FDC89E35D7087D3C6F6
-:106FA00041EB1521804B37DFC9F6B5BB27D0F3582D
-:106FB00082B6C601EF6703EF227EA5D67BB07DD0F7
-:106FC000DC6CF700A02D86662FCA0D007D4037B21D
-:106FD000EBF90B475F6A1FFF3E9EBE826696321E2C
-:106FE000F978B54A722A68F6270C81F26AB043969E
-:106FF000C2949615BD3B6C10965FB231B44B1AAA81
-:10700000DB5D8390AE3C4686FAEEEAEB831948E7F7
-:107010008D35C629DB117F430B5C33A3F4ADB5C9B5
-:10702000069AC7CAD780EE86C2D3107428F87D3F6F
-:10703000901B0AF2459F19ED1C4B4632F3E7633B68
-:10704000DB6AA4CF95065F4519B6CBD0917CB1F42D
-:107050009B5C5106F370A5EA143DCDA3FCD82C949B
-:107060006F76234A50762279FA6E84D373AAA71ECC
-:10707000E9F0399BCDEE870AE0911AF23FB59F33D4
-:107080008065939ED5A31CCF2A02791EA5C79E10AA
-:10709000FCF384C348FC6EB52538A114FAB12ED098
-:1070A000D9FD30DECA9A751D63619C5FD6BC7C74C5
-:1070B00029BC5F95A6329C87CDA9868C207F0CDFEA
-:1070C0008339C2BC5F58EAB5237F8DA4AA6C1BD458
-:1070D0005BFB1A993B8A5FD90641398A4FA638551E
-:1070E000CD02DF7F95ECFB77078C3BFCAD77CCF8CE
-:1070F000BD6B844E87641354F93E2715C7F6631F92
-:107100001DDB4F72796CBD737C6C7DDAE4D87AD765
-:10711000DDB1E5CC7B63CB5324BE01CFB1813CB65E
-:10712000F22A660D7FBA04E52DC0E73D84BFB54065
-:10713000E741F8586AB69F9D05F559C84FD01E1A09
-:10714000C248EE1EC8FDA91BF5025372BDDB31E833
-:10715000727864E5986FC3FDB2F555ED0CDADBDEAD
-:10716000FFE86BECDFC6A2DAE5237CB488239597B1
-:107170005D309F44FC871BE15DFFE707512E1ED564
-:107180007B10DE59352A8DFFF0647740CFF5091763
-:10719000EA3349A27D927975871EF879D2FB2BE7F5
-:1071A000A3DD1B0FD73456AF205D027E707BBB92F0
-:1071B00091FC58A1635588376823607FA41E01BFE6
-:1071C00098946224389992156137AA3AAC4F13FA11
-:1071D0009331E35E0BD2F1438738FE3F64E4FD74E4
-:1071E000F6E7A64111E519F2C994645D4C3FEBEC5A
-:1071F000A28D28A73A78B9B53DF936A4CB759393FB
-:1072000087219E98D0EE82FE7A659BB501B03ECB79
-:107210001B46BF029DF65259BB01F6B2D5CAEEF12C
-:10722000C23C361CB6FAF5F0DE32F31776D4D38AB8
-:10723000C5BC5B9779DE463E10A954098E96D4668C
-:10724000FBB0417C0D7E981FA203CAC5D27E2DA43F
-:10725000E7594A9B49BE5B8A9A9B114E1BC6EB4875
-:10726000DF48BE5747F86CC9091EED8B7E82993AFC
-:107270003BF6970C82DF089D3C9ADDEC45BF090385
-:1072800098EB4A38AA60BFB442182745C0D5E9DC5C
-:10729000F91305FA49C1FE86F0F608278780D3E87E
-:1072A0006437C1DD29FA4DE90BED87F07E1A4BBA40
-:1072B000FA91FBB8A18205707E725CD94F67FF4CD2
-:1072C0005390AF1A7E0770837D5272CD34B987E632
-:1072D00032B28F5B9779EBB7125DDBC8CF91E9CC07
-:1072E0002E433CCA3CBC71A26E087E67A5710C336C
-:1072F0005900F1385365E61B9351BFF1121CE3E9C5
-:1073000035A3BD7912EAA9725FE2E93743654DFA08
-:10731000E4CBE938C3E92C2B18D20D3DC7D14BC6BD
-:10732000E1C87D88F4F174BD25E14211C28545B7FD
-:10733000D75FB9ACD7078FA29F87A5839C00D0E702
-:10734000C68DC7D83F4C585698CEFD4D1FE4FB0E56
-:10735000E1BF017905C4DA3ACC3EC686743A9F1182
-:107360007E95ED5A7DD7EFA0BF4BFD8C76942B39DF
-:10737000879B3B503EB2DDBEFEB80F9B54DF130926
-:1073800050BFE9583A43BEBDD2C2ED3155E079BC99
-:107390007C592BE8C68D72CEF5AF3FA57E18EC9BCD
-:1073A00036D00EB4B7F617156F9853FF07F52CF6C5
-:1073B00002E959D9ED1D4B6D38FEDAC34D6680AF39
-:1073C000E52DDEBE19CA7E15E1574DFEAC0339B37B
-:1073D000084EEA7113433C1DACD70258667FB230A9
-:1073E000E4BF3B5EBABBCA8DFC276D9C1BF9D0364F
-:1073F00041EF01619FC5AF5F356A3ED427E2DF6F81
-:107400004CD689FDF49EAD847D1CFCA491AD82CA4E
-:1074100042DDF426B4EF222B81FF42ED74BDBBF6B2
-:10742000E751F6ED23D6D26032DA254BCCCC070AF1
-:1074300073F6970AF30171E638FF508AFC279785A7
-:107440001494B3B9F5A0F0225E2DB4325F14BE6778
-:107450007FA952FB47AC5A3079047F6F063E60E04B
-:10746000FF64CF257B59A593F328D45F0CCF5B4FE6
-:1074700022DF60CE72ADD31EE98DF80B721FC6DB22
-:1074800027D66D00181A86C17F365DC834E4F2F63F
-:1074900007049C54B32D84FC52B51D3946FCC5AE7F
-:1074A0009E8F6E87763731B16A467E59840B957F01
-:1074B0006CA77216F05FD330D2FBFD687FFB93B8E8
-:1074C0003DC234CDED4C437A6104E46C336B3243FE
-:1074D0003BC276A0B70CD66121BDB99DB9911ED033
-:1074E000C3762681581643B86E62AC229A0EE453D6
-:1074F000FA25D4457AB2A7061EB4D07C0CF52C60D0
-:10750000417D08E706F05617B2809ADFE5171CE2C6
-:1075100070D37746564FFAEC0B5F9FC8443E6D3DE3
-:1075200004FAD850DC671DF129AB3596FE185B4A8A
-:10753000708A08FCD8BCC44EFBDC69BFF9DE11FBC5
-:107540001C5E8AF222776172CCFECA76D95F663100
-:10755000DFF0E87E03D46F76DF7605FD32D95FE693
-:1075600052FDE625EE2BF4DFBB87FE33088F7AEE63
-:107570003F9BEA3787DE71DC0EA0D814697778DD8F
-:107580005DFA753C9CB317C6F2E5A1BB63CB122E26
-:107590001683E69C0030B7DCA7F36C85FEBE732C27
-:1075A000B65D45FE1FC9FEED6A1F724EC2F6609FB2
-:1075B0006F85B7379C8D6DEF2D7DCD8174DCD59EA9
-:1075C000CFEFA62F63DBC5EF4FFC7C615EA9DF8F99
-:1075D0009AD718B329A67E4AE565F34AFD41D4BC83
-:1075E0006E71C5B6F72DED7E5EB7159AFEE9BC64E7
-:1075F000BB3B465E5DBBF8754CAA30F50077DEFEFE
-:107600000753AEAEDF1F56FDF376F72C8A1FC74F28
-:10761000F8BE40A78D4981FAE9F80AF5459B95F433
-:10762000DECBEC2C219FC6A1E201DF7992B471F888
-:107630005D85A43BE16738FCE275E9C8D7B3841FD8
-:107640009D09BF426BB58BFC0A3ED11EE44923F273
-:107650008BD61DF05D129F57B4FE9452CDED0A3BC0
-:107660008B103D4B7D2999D9156E8F737DA7A7711E
-:10767000E2FB7F18154098EF8C4563D80740872FB1
-:107680001BEDA52ADA675B14D20766946BFA44C037
-:107690008F514D0AF995663CF0F6A3E88FB9FEB418
-:1076A0007B7718DECF08383C386C6D07D3304E90AE
-:1076B000AE9F5FF4203C1F3BC0288E86E5F9886FA3
-:1076C00036CD8DF64625CE08FA396FA82FB223DFC6
-:1076D000FC914D43BE5939597B8FD6FB156825D097
-:1076E0006E265F3ADBD532C188F18ECABBDD2351ED
-:1076F000EFA90C5A347A9A996A857554823E86CFDE
-:107700007423532DF8B432333E4B9671FD2B69A48C
-:10771000D75809E357B63DF357FC6EB61ADACFF5E2
-:10772000C900ADBBB2ED8DBFA1BE3653F31A915F58
-:107730000CDC61E43AA9C087C1C1D832F283E87297
-:107740005128B63CFC706CF9D3140EDF51C28F7512
-:10775000609F89F8F6BC8FADA47FEE05818776B275
-:10776000FF0513C98F31F36CB45F1F9FB36E45BF24
-:10777000DEFEE3566A3FF7390B6FAF0BBE8865FF3D
-:107780008B096467CF4B099624C3BC5FF95A4FF04D
-:10779000C66519B0FF17076C5D85F5C383251817FB
-:1077A0007BF93AC63AB05E0D0CC175BEFC0FEEB760
-:1077B0008E3C6B0A6C837E3FDEF3CC8B3FC3719FA4
-:1077C000CD4A56607F6E40B900ED463D69B6A2BD18
-:1077D00031EAE3E7FB20DF98B7C314B3BE175314B5
-:1077E000A13FB89310EF7AF23B9E5AF90C7D5F7877
-:1077F000F618E1DD5E835F87713CFF4A8E677B2D63
-:10780000DC4FBAD7921BC07DDA97C2E9EA06DDB633
-:107810005FD6A27EF916D7437AEABFD03563737973
-:10782000377EC6CE7A18371FF6F9E247D67BD01FCF
-:10783000D77F7DEC3E0D08C4965F4BE17AC274168B
-:10784000F53E1FE7D37BB90BE7B395D17C0ACFBEDA
-:107850007F573EEAE326AE87C48FFBFB142E3F7FA3
-:10786000F52BE887F3193DD7C3016240D7F3043DF8
-:10787000BCA2703D18FE166601FECF4305A277D765
-:10788000FB7971F390FD2F1570FADC9CB40DE5B90E
-:10789000D3C8F1FEDC92C38F621C53B63BB344D312
-:1078A000CAA3FCCAB3D6CF3F9401FB5FDD9A4A76E8
-:1078B000A67C5FFDECC1B41FC2FBF33B540FAABE14
-:1078C000D5539F7E6414B67B561FC47962BD06FDF6
-:1078D0009F0FBE9684ED666D720C437F89FC7EF629
-:1078E000FA9BB5F2287E7AADF424E9BF5AD8C7BB1B
-:1078F00046768CCD0278CF5BAF78B0D9BCE0F72765
-:107900007D0F759D4D7A0FC6374A54E6D50F23D3A8
-:107910007D323EAB5B5F3A9409F575FB4694E0BA65
-:1079200056E9BCB70D467AD962203F58FCFE189D37
-:107930001C7FE1FB900EBE5F75A7AD0AE322D06FFE
-:107940003B960F146ED3A31F3FE92CF037FEFE9831
-:107950000E78E6D9B6878680CD02786C6B42FAD86D
-:107960008B8E0B1CE7053DC90916E2EB1825FCCFF1
-:10797000F3FEB3C5A8C2F3ECD96549A59CFE689F88
-:1079800090A93B617D554F0E267A9DBD3E96BE6403
-:107990003B39DF3981D8FA78BC28704A7F052B8CB7
-:1079A000C6AFF87629E3FD46A4C7EA45C0CFA3E8F1
-:1079B000A6FA74B311F5AEF871508364725FF58462
-:1079C00097CC4DEBB5F0F582CA6B86F59EC37F71FF
-:1079D000BFB98276FD5C8596C8E65DC7CADD00CF7B
-:1079E000791359053E253F3C3F323804DBEF35849F
-:1079F0009FFE25F1C144E207E7EDA124F42B650ABF
-:107A0000BFDE79772809F9DC4511B7C37A2CCF6D31
-:107A100003790074FDF12746920B4B83079370BFE7
-:107A2000CEBF68D1E9605F3E6E4D29437FD0F9E05B
-:107A3000EF92705DE7822965E8D7EB894FC4F33791
-:107A4000A90F9CC47F5E0F7A8F531BEB44F86290A2
-:107A50002103E44D4A7D517D37742FBF731AEB8BA0
-:107A6000304F23F2239B671B8713C5F33E3B9CB229
-:107A70000DF75BF2D94A85F72FBF9FEABC3ABE5A91
-:107A8000B16A00C5993E63EE5EC8E7EF46DA80F959
-:107A90001DDE5FD00BF50DF9FEC134EF3D4EE8CF92
-:107AA00055D641F901AE71CCD3004D3FD07BEEB736
-:107AB00003FCEF6520FFF059EC3392DFA63195D639
-:107AC0003743652115F07D06CAE72154267D68C637
-:107AD0002625D000EBB977752CBC66B598BAF004B2
-:107AE000FE9BC380B122216E8A6A07FDCF41390C0B
-:107AF000FB30D7CC4209D0EFDCEDB1DFCD63219A6A
-:107B00004FF5F3DF98BADB8FBF8AFD78304D5B8489
-:107B1000FBA14C34D3BC7EFC824272D229FC9591ED
-:107B2000C77A0530AE364FCAFD77F8BED53D50A9AD
-:107B3000DD0BF87771D10CEDDE144A3DD1501F6199
-:107B40002D8984CFF3CA592807E637AF4D090D4E6A
-:107B5000EAEA8FFD46E1761EE3F1CEBFBEC3F7F140
-:107B60002EA13FCD84D7A88FDCA0E3793D910D0AEB
-:107B7000C9D751CF2BFE44E0CF33CD602A229F12CC
-:107B8000EBC6F6BDA03C9BF9094EBF74E6D3FAE6FE
-:107B9000B00E23A7A340431A8C5B7B167813BB1A45
-:107BA0007CB89EF6FD73E6A17DDF82734E457C288E
-:107BB000213C91EF414F6296E4CBBFC7FDD3A2E0D9
-:107BC0005DB529B6CCB647957BE3FE40396ADF6ADE
-:107BD000777E63D2BAD9AFC73AE55B60C084C1D1C2
-:107BE00074C2F5F013623F1FFBFEAC0CE44B6B500C
-:107BF0009FCE141D8C443ECEA49F256486FEADC34B
-:107C0000598CDF05F43D2ABFE2FCD1B8F5D98CAD23
-:107C100033F8287E3143EF3D84A1B6A274DF6F11A3
-:107C20004F66E8B45C95E0AA1590FDBD88E3C3E318
-:107C3000C3EA07D4776377CBF9AF5382211DF2A74C
-:107C40003D5C5F492C8E187C5174FF9EE0BBBD0EDD
-:107C5000840F6521DEBDA4509C6083C21A1580B3D9
-:107C60000BF619E5D306E5E42194671B6E75B306A0
-:107C7000A82FDE3961FE6B64BB5B29CFA86667A9BC
-:107C8000BEC646EBE7FA7342FD561DD4A7DF533854
-:107C90000CE90DD67DCF44787FC2E9A67965D83846
-:107CA000FEB896F9F317A09FF88077FE6B8877836C
-:107CB000ADE48F4B07582526D3B309F562175BAAAD
-:107CC00060BBE5A90ACF83A864537E3388B059ED21
-:107CD00095CC9FC7E0A9A8AC11FDCBE92AE8D9FC57
-:107CE0007D238EF358129F57AA4E7FCF04D4F3877B
-:107CF000F172F26245DB46F26C2DCD2BDDC42A70A9
-:107D0000DDF81EED029886D64AF5018253FA98FAFC
-:107D1000229C477A1FFE741A43D9D8CF914E3CF16A
-:107D2000E9507E2C147AC0C2AD65E9C8EF8F9C374C
-:107D3000ABC8D78FB8A43E1BB2A13ECBFA16F2F661
-:107D400042DE2E2C1A938E44EDCC8D6D77D1A0F5AA
-:107D50001A8E72EBA89EE24F7FB169BD1CD0EE0671
-:107D600023EB36EFAF572ADFD7BA2F151688F26309
-:107D7000D44DB944F642DD976ACCFBF34BCC2C10C2
-:107D8000E5C7A8AE3A3016DBD5B08EE5888F35C191
-:107D9000041688A28F1BACDD8F2BE9A2EE4B3DF3BE
-:107DA000773BAE31F6FD9729CC9FD25DBBB4D8F7B7
-:107DB000B08E98F2EE2F3AD781EFD9C87012FA75CB
-:107DC000C7A37C86F2C580CE6F00BE75C4C0E5EE49
-:107DD000057B38462E5F7087B95C46BF958DCBB367
-:107DE00009B8CF6A24696262D738B21EBF4F8E5A73
-:107DF000EF85294616A2FD89D03C107EFEFE8C6DD3
-:107E00006CFBD488F93AD56DFB097E126FA2E1E8CC
-:107E10008F8E8335748474C033C6A56E5F35680059
-:107E2000A0E001C91F9E5EA58D867ABD2E865F24C7
-:107E30001477F20F62578F61548EF8CD33ABD06F49
-:107E4000DB55E6EDBBBEDF310EEB8B07F1EF27A76D
-:107E50003EFBE6324A6A69E67A971AC9F5264695E4
-:107E6000CD71651B94074795ED71F5CEB87A575CD7
-:107E7000399BB73F9F18CAD57B18BB27F585712A58
-:107E8000F0CDF319A16998C7B6BAE1D7E3CA819FCB
-:107E9000D51473395FDBA678485C09F8D57AB81E2B
-:107EA0006BF3848D983F9750DC7108F94BF56EC5E4
-:107EB000AE003DD882AD212AE377EEA8EF820A7D9D
-:107EC000571D3C49DFF5D87FA18EE87D55E129DEBD
-:107ED0002EF821E9132B1AE753BE808C87EB994FBC
-:107EE000CB52BAE2E192CF5EC8D00E129FDDA7D886
-:107EF000913E3BF114FB8DF243C9F67F1ADCF64745
-:107F0000545712167EBA14F5EBFFACF97004EA9BD5
-:107F10007F12F2649D121880E36E64BE01284F7FC9
-:107F200054D36FBF0EDA9D30843763CC6F4BEA6B4E
-:107F300004BF1389E11CCC0B0C3CF6EFBC9C1ADE91
-:107F40008CF0BCF458C738CCFB3B9113CEC13CC07D
-:107F5000EDA9FFC5CBFDC29BB17CE4B133BC3C387D
-:107F60009CA387EF7BFB3F1C570EDF3F65EF9EAE68
-:107F70001F13FC44CEAFB6AFD69C8A7A5E359743CA
-:107F80009BC1463303DF9C36F7DC0B4F011CA6FD7B
-:107F90003481F8D953E7278DE3F682DFAB96A03F13
-:107FA00099FF919C247EAF929E9181B231B96B3F33
-:107FB00012733BDC2447AEAB6F45FD257DDA209282
-:107FC00023E54EED0B1C573EF767C113DA7F916A2C
-:107FD000E7FC5BAFA3F87AFACF1249CF5B63E1EB22
-:107FE00001BAA1FDB589FDF89558CFAF52B91D7AF8
-:107FF000BFF366EAE72EA1DFB7AC0C3C6B01F81FBC
-:1080000097793B6BB9BDF0C3ADC057808FB738B41B
-:108010000CE4273F147978927FE0FBE4283BA9A584
-:1080200008CAB62E7BB86582966175E2334D8771BA
-:1080300024C98F5AF2F977522EA537F071D3D70C95
-:10804000D886EB4850B93F6CE694826D4B492F9827
-:1080500048F3659A96A1407FA7E7F4D6A19F4CEE1E
-:10806000CF9ABE5A3BAD47C419E43EC9FDFC2295E8
-:10807000DBF733F4A057C03A2DE93EEA0FF48C2128
-:10808000C21F477AC617B8C751F0656A7804BEFFA9
-:10809000FF084E1F7D1B70AA5904FC427715FC4255
-:1080A000C06F9D1232A4737E41F63DBE47B9D3EE38
-:1080B000F47D9D1A95AF33ED6735A457CA7925FC39
-:1080C0006457C50FD8E57416AFF799D2F87E49FD0D
-:1080D000D423FDAA629C13C7CD144739610C12DF6B
-:1080E0003C0176D552E42F220FA0E4A7F38EA07DA9
-:1080F0002AFBAD49D373FFB4DC77C5DB3A2B1FF302
-:108100006298DF8CEB9860A47D9772B7C5C1F35C71
-:108110005A1EC8A23C978B2CCCC83F3B92117F04BF
-:108120003CA0FAC8D434A27F68EFB760FB39D751BE
-:108130007BC00B3FF187A956B2835A306E8EF55340
-:108140000B03989783763CE1DB1C1D8DDB0DBE7025
-:10815000FF777F9EF721F126AD81FB9998AA0D99B3
-:108160001025E76F4DE3FB9C501C7EE93F50AF5D4F
-:108170006D21BD16652CC5A89AD3A91FD8FF6169CA
-:10818000DC4F417876EF238922BFCE5382705D9118
-:10819000C8F1729385C7CF36811E4D7C51E0AFCCBC
-:1081A000EFF3097D2F5CA54B427D414B937633C89D
-:1081B000F512E1BF87FAE961E524DA7FD3FDFA9091
-:1081C00009FDCC4D376BE1283B06FF30FE788FE090
-:1081D000AB6C3D233BEB1EFC2E09FBB72661BCF5C7
-:1081E0001EFC1EEDC8C537C7C41527A671FA96F345
-:1081F0008BE7FB13E5BC9A1FD7A2C791FDC7F70712
-:1082000076EDA4B4548273A817EEEF523DED5FFCF7
-:108210003CC3EBB91F3EBC3E8FF04EF6D7D33CFFBC
-:10822000AC8FDCA7801C9C3586DBFBD2FE9929EC49
-:1082300071B638D6BE43BF4F67597F7939DE5EC409
-:108240007C81D8F65C6F4918143112DDBA9598F923
-:108250004B78F5048707AE116E52EE3D6E013A0081
-:108260007C598F7995805FEB1F482039E6340606EC
-:10827000205E6DC47C1D92A7DC8EFFFC48AC3F26BF
-:108280007EFF7E9E26FD6AD7667F3F8278D18DFD78
-:108290005D678D6C41F8D75919D1E7857D89448F89
-:1082A000AC6F781AE6D15DDC6B62480FB54AB80056
-:1082B000F9E00545ABA4764B13DC4897D2DFF1C15A
-:1082C000CBDCDF51873B03EBADF3FF17E571D5ED59
-:1082D0008EB5CB2FC07F5540471774E112EC4FF29B
-:1082E00017D0CB35D2B7AA787CAB56C7FC68B7DDC0
-:1082F000A09B3E87F38D4CB68DDE9F2C5810A5F7C2
-:1083000043BB762599A323D261B5D8975ADD296A54
-:10831000578DF958B83F68BFA11F102BA3FCD6B5E5
-:10832000AB3FA67CB0DA9DB1F853DD855FCA370A52
-:108330007E17856FC41FFC82BF30EE8F29E7F1F9ED
-:1083400044514EA8E8A0FCB03AE18F493D101E8B85
-:108350007C2AB138C8A6C3B3EE2CD75F46B56D3DB5
-:108360008876BAA3A22307C9AA4EF84125FEC87988
-:108370005EDFB6568F76A4D47BA2ECD8011363FCE3
-:1083800018CBE83BB48B71BC30BECA40F4E2F27249
-:108390009D9097096860A35C6DEE4F7215E51EF223
-:1083A0003B695723FF43FC2A4A2F3B8EF4FF467A52
-:1083B000D91F399F04BC453B018DB4EB7BC63F09F7
-:1083C0001FD90EEDEB7FEE9F147C9C71BFE48237CA
-:1083D00052FF291D9CEFE4AF57F44BA623BE2F504C
-:1083E000DCE988EF17057F3CBCBF80E2A0F2FD19F5
-:1083F000BD8FFC8FD2FF3507FD7EF0AC16FC689672
-:10840000F097CD927EB2F5B1F15AF4534797E74A0F
-:10841000BFD90E53571E13FAA9CA592811FAAB41F6
-:10842000BF1B3E83B1DFD5B2087D57B7FB1B534C52
-:108430003CB885C3F11E814F8EF2801EF9D8060B21
-:10844000F79F49FE366AF156C2935EC3B4FC87902B
-:108450006EDE3090FFE57F0B3C90707930ADECCF55
-:10846000B8AF56BDF00F3E6422BE7E1AF48556E1C9
-:10847000F7998876F212A6E13901A6DA73A3ED68BE
-:10848000F95CB5D75285F89899AE8BC1D7F634030D
-:1084900095C91F46722381F402607343105F4B7AC3
-:1084A0004BB9CD86A01FEEA4B0EB6BEFB4F9B0BF13
-:1084B000B08EF3C5FEE97C9FFBA7F3BC5959EEB41F
-:1084C00043053ECA382BFAA5A2E314433ADBAF15A5
-:1084D000FA2EA3F5AE9B23F2E83BE942477C2E61DE
-:1084E0009097E4C30DBA32E273918F6C6E844BC5E2
-:1084F000C7D573701D9F4DB1D279C97B859FFCC6CE
-:10850000749E8726FDDBD7EA272F4DEFC4C7183F9F
-:10851000F95EC117F7323E5FFF592BF7F7AACC8FF0
-:108520007C726F704000E75B29FC23A87F21BF8E1F
-:10853000BCC4F791A95C5FDBDB3638807474D2E091
-:10854000DB3013FD4DAD06F21B3235F0ECD3D8CF46
-:10855000AB191ECCB3BAA08B6CF93DB4DB7BF657DC
-:10856000591857DB2BE21BD5C65001E9F522AFB4F1
-:108570003A2954807EAA57C47E555BA10CEF532C38
-:10858000BEBBD253BBE28FF81DBE3F15E076C329B8
-:10859000C6F1C0BF9AC79701BE193371BE2BD3294C
-:1085A0007E89FB82FBF0C1BEC1B4AE7506D17E0FE1
-:1085B000F7732B130BA7919C59654A41F85FF41A86
-:1085C000292FBA6E0DD76B67E8DC5B1621EF7D357E
-:1085D00081D637B3E528C595EA1E994DE74DEBE600
-:1085E0002EBE9DFD93780BCAA968FFFE0516C9250E
-:1085F0007BBDAA773004F3B8D036C0C3C3A5FCFC5A
-:1086000052ADC8BF3D6D601ACE3BB2CF10E8EE5CF4
-:10861000654FFD9383B384CB4B1CA72E3AAE45F236
-:108620002536CE75A5F20543B8E001187F758A6F2F
-:1086300075BAD03B115E75AF66101FFDE0E12F7279
-:1086400049EF69E6F194D3066D1AD289A33C649C84
-:108650001EC55FB70B3A9E6112FA2DF0C168BA973A
-:10866000F52565B174269F4F0A7A4B14791897D770
-:10867000CB3CBF492694C7DCF585FDBAF9393411E6
-:10868000DF1C7536B21FF3D9AA8345143FCD5B1C9E
-:1086900022BA047887D03E39BD2191F3135826F6CB
-:1086A000336B2423FD7A969EE795CC3281BECEF5BE
-:1086B000026A7F66433AC1A16419D753232F29C4A4
-:1086C00017659CB792F1EF77359EF4EBA17DE50E2F
-:1086D000A508582BAB6C2CA5BC93B99BF269FF473E
-:1086E00009FE3BC3A4156C407CDBC5E384301ED976
-:1086F00005D5985B378CF89211E56BD50E85E22590
-:1087000072FDF1715516888D478D0A72FE8D728348
-:1087100045E993520EA1BC60717A6E2C5EF8AF4AA7
-:108720009EC6CB8377D3AF56AF8C95A7EF21FF4A78
-:10873000BD5C9E82DD701CF1B0A48CD371A495C782
-:108740009F6A583D8FC30979D6B92E210FCFE8B95A
-:10875000FC9D655A4BCF8BE93C0E359785451C2A0D
-:1087600062C4F9F5845F17D3657E7B2C7E49BC8A91
-:10877000209E417FD56759E8BB305EF56216AA1985
-:10878000C29F894348BE73396FE6721E9FD6AB9075
-:10879000F7F1723E5EAEC7CB73146728B7253E452E
-:1087A000C723504F1AB538A0E7FEE66C3BE665CA12
-:1087B000FDBDDFA939B253BBF4C0BA6366B37B28F1
-:1087C00096BDACB70DFD68A59B73A0BE4EE5E7C393
-:1087D00013004E5BE1FD666187ACCAE174E612F9F5
-:1087E0005706D5CB8A6CB84F1DE43788A432CAA788
-:1087F00097F0DD9C08DF613E420EC78FCEEFCDAC17
-:10880000D11AF57DD95E0BC9A94B7B12E91C205307
-:108810007D790EE82FED4F603F40F9C2DE44D21360
-:108820002E08B9E194FE19B69CF6A38F8BEFB39F87
-:108830009565A19F9B29E3B2189D8FE7FA6C8DA3E4
-:10884000A7F884A8CFEFB893E39989E4F52547F812
-:108850007E2CC37C28BF3BCBC5F7BD6EE798A29F9B
-:10886000615E86D7E6E150F515A1FE61D22FBCD33B
-:10887000ACC77B1216471E8075D4E4D8286FBC3C69
-:10888000EFFD77A742F9A39D063A5F3AE7A949BDF4
-:1088900042F899AAB9BAA393390143CCB9C5793B37
-:1088A00062CB35C1D8725DDC3D058BDEDFFA667BBD
-:1088B000547DB94B9CEB74330FE6BD33FDDDBD7CBD
-:1088C000DDF05DF9FC6249E0CDF67E9437789B8B54
-:1088D000D3B311F5A3E9880FDD7CA773F17D35993A
-:1088E000EACFE2F903D32B26BACF20DDE59BEC4A91
-:1088F000453B2A7208F7D394777E08CAD3B2BCAF3F
-:10890000286E78E941E641F85CB294929E746983DE
-:10891000C58D76634BAE8DF0A0E55525A070BB628A
-:10892000FC08E0AF55341558EFFA5B3FE2876598D5
-:1089300099DF7F0056950BF9954676DE990956FB2F
-:1089400032F8AE6A3D97DBD5AC2309F9C006B97F92
-:10895000FAE78D66F8677EA3366029CC779ED74A02
-:10896000E7A4D4AF55BA1F600576196597D4BB3814
-:108970003FA831878DA538FE570B2BD00528FD79F0
-:1089800026834FC3F37886DD45A12C78357BD14112
-:10899000B2BF3AE3F6FB38DF9AFDC07E7AAF4CAC4B
-:1089A000A0F59E81F5225C0E6E30D17ACFE4D8C856
-:1089B000FE3DB399DBF9B3EDC68099F4962F53F0E1
-:1089C0001CF399CD06BA3FE07278DC42E7893FDCC0
-:1089D000F43AF91B3F647C5CFF4E3DE93D1FDA230E
-:1089E000252184A3BB3E09F5E6AAF573E83CF2EC29
-:1089F000CD7A2FF2B3D99BEFFBFDF5E8279B785793
-:108A0000312EE926C7C234B7ADAB5EEABB6AF2C805
-:108A1000A7910E6FFA7A4CC74DA8776D063AC9E751
-:108A2000E71D50DF6FDF7C0BE9B7B327581DB82E69
-:108A3000F7A6A7C6A21CFA7042269D9F9EFD82C281
-:108A4000F0CA8CD98E4569F87EB6A27ABBC3A7A1BD
-:108A50002E7EEEB934CFE609E1777FD4139E005D18
-:108A6000DD8972B866B381F4E7F689C7DF9DEAEC69
-:108A7000A22B65E2FADB4761FB670CD4BE536FDAC9
-:108A8000F43D892F2C5482F619875B3C9D99F21690
-:108A900017E0BCE2E96DF6B2FA021EA7BB36BA6374
-:108AA0009B38DDFD9B4BDCFF71F574B7D7957AF5EC
-:108AB00074C7B29363E4F0E5FCCD4FF094710EB34C
-:108AC00087694FD928AEAD29C07F3FC080FE087CA2
-:108AD000F27362EADF16EC780BF1D8E53B82F3C85B
-:108AE000635A11CA4D77C45E8667C06C422F649B7F
-:108AF0004CD29E203B615D2A7B7A55945FE4CFA2E5
-:108B00003FE0037FC47E2EBCF7D521DCA7DADCF37F
-:108B100043D0BF5DF7E55F282E6A6BE371759B2735
-:108B200042F90606A797F050F2F73A0F973FF1EB9C
-:108B30002AC8E0F6619D3342FDE833DD546E1171C1
-:108B4000A48D8BACE437DEE80C58B8DFC3CF503EC1
-:108B50008D1FA9E7F140A1B77D4FF85DCDC507197D
-:108B6000C601D9689E8FF756F1413505CABF1F79F6
-:108B7000B387CE51163FD9D41BD73DDA20EAFBD0BC
-:108B80003D27FFAE9552FD0297DE8DF43DBE98E77E
-:108B9000A3B2AA24F2E7BC55FC81F3DEA8F97B99C5
-:108BA000D96D03BC9908C41A9DFF78FB688BDB164E
-:108BB000853F9F352B155C7F76F79A3C98FB6B4879
-:108BC0001E17C7C26381CB48E3BE915ECA3200CE96
-:108BD00037DDC8F7E3DC0BA600F2C173E25C523C60
-:108BE000FC7A6508FC5107C4E427388DC15C949376
-:108BF0001F2BB1DFCD6DD2537EC09C26850560BC96
-:108C000073CFEECA457EFED153BB72A747CD27FE78
-:108C10003BF9CCC888F57FC6FBB37BF263CB7617F4
-:108C2000D7339FB94F57FB8B557F273FF6F436E17B
-:108C300007D7B4BE4EB4AB44FBF8FECA057E28BBD2
-:108C400015F29F483FEEA9C34F62C4A873FF2C6D75
-:108C5000F9BAE83C52F91C25F66D12EE1B2CC5D270
-:108C6000C4CB3DED574FF47842C821B96FA79AFAAB
-:108C7000F442381A6B6D2AE3E7030B51EFDFCCACFB
-:108C80001EA4A72F443EB1D30A4FD0D38C992E1BDC
-:108C9000F233791FC34FAC49DBF0F985C837765AF8
-:108CA000E109FDE46416527F5FE8BC641FFE44DF07
-:108CB0004CE7466FC9E0704867214541563BEF6578
-:108CC00085F2E49A62E19DD6C0E548A4D248F24B11
-:108CD000C2FD86E9F7931DDCCD7EAD473CCA1CC9B9
-:108CE000DFF933F2851E1DA678896524B3A39FA002
-:108CF000E17A3FCD43EE571D6FCE943685F467CCB5
-:108D0000F34948A6B8B05F3C992D9975C6491284BD
-:108D1000DDCCE2E222E9A077633B394F2853BED095
-:108D20001A47B0B980C795492FC57EF1FDF4412A95
-:108D3000C515B09D71D895F1AF134F453EE878F950
-:108D4000BECADA6D1C663C9ECBC27D00F9887A21D2
-:108D5000F31862CE656D027D1AED3D19E7D6EB8200
-:108D6000452EB24F3AC2E887319698DD286F13F44A
-:108D7000C142DCBFF8B837B4CBE7F916D90E94334B
-:108D8000F2DC55EDA2315E8CC781FEE137E3FE4D8A
-:108D9000E0FB57FB4029BD5726162E45FCAA5BCCAD
-:108DA000E87E88316DAD940F5657C1F5B1BADD2715
-:108DB0008D0CF077BAF00B31E1174F13FB7A4AE8CC
-:108DC000DF5D71BDF016CCB76F99934DE7ACE3F35F
-:108DD00067AE35AE7B31110032342A5ED7CBCCE59D
-:108DE0008CD87F49DF327E9738C89B8F9AB861BD97
-:108DF000E98875C4B5E4C7841F2ECFFE27F931FE7C
-:108E0000FADB313FC68C5ABEA8C769801CED3C47CF
-:108E10006971537CAFB31EEFBF30EF56C47839B7DA
-:108E2000DFAC529EAF289F5A8D7EB1351616335E49
-:108E3000F4FCD4B8FE0DD0BFCD2DDBEBC6637F8F25
-:108E40000D13657FE56ACC075A6388ED8F50509EFD
-:108E5000FB34778DB7393BF8F0EAD15DF21CE4FBC7
-:108E600061941752AEAF383EBE79A81BE9EB73CAC6
-:108E70009B96F2B9CEC9F365E2F9D8DB829F835E97
-:108E80003C1645EE8A29F3E9BE88CE38775BA58685
-:108E9000FAB08C73D72DF652FE34E803FF9141FAF5
-:108EA000C0F933FB19EA9DE7C82EA8FB52E5FE2660
-:108EB000D02BF0FE1F735B29F955319DB75FD4FEAF
-:108EC000CF15720A7578A487BA4D3F784A0FF543DB
-:108ED00033B530F56BE8FEFEAFBF65703DBEAEB09A
-:108EE0006C03F203B65DA1FBB756157E467A47EDDB
-:108EF0009E9B4744E7FFCFD9FD18CF1FDF61E8767F
-:108F0000FD7FCBE07A6AED9E97C86F7A2EC08F2DD9
-:108F100055A98195A8875655E950F362C581CAA91C
-:108F2000A40F4C8175C0BAFE9CC1E153B763921F78
-:108F3000CF23D4C17F0ABCDAE89D4576C1C6296635
-:108F40001BC697EA0AA7CF27FCB75B355C7FFC3CC2
-:108F5000BBE2E9563A37BE6AB7A102F5A812D09B28
-:108F6000FE0DE69B933CAEC2037C294BDF5AF463B3
-:108F70001BE617742F97B764713DA051F1FAEF28E3
-:108F8000267F298BCE57CADBCDF5337BA631C63F72
-:108F90006FCFE4F74C8DF6778C419C7B550D27A065
-:108FA0009E5CC7B44FD1FE655E9B9BFCC48CE713EF
-:108FB0003897B8C94F6C76867F3E94F42895E2E9DD
-:108FC000D2BEB8B087FBD79665FA7232D13FA80FF0
-:108FD0003F7A07C2EDE7AAF037733E933BC9360CE0
-:108FE000FD611667F8D10A37E519915FA2D7771BA3
-:108FF000691F5E75323BC2678CBF5255A2E48CE498
-:109000001B633ACF4D39C90F5BC6D91AEB07BB7545
-:10901000C64C28DAF84D4A979E70F8ABC92ABE9420
-:10902000FA83CEEC233BA77C0AD88D8897CB238785
-:1090300074E8F7777690FE581354689C9AC2DF5014
-:109040001EE03C916FD699F7A586290FEE3B990952
-:10905000C28FD9C8F19275905DCC9EE7F007FE44AF
-:10906000F9715D7AFC526A27FB338A78458DF0E30B
-:1090700000A0A8BE2C53FAE19689A7CCE7E3E3321F
-:10908000D55D12ED775837012409CDCB9D84F37D52
-:10909000C4EABD2D13E6750AF017D779AA2981EE27
-:1090A000035BA77468E8D7F417F1BCE1783CF28958
-:1090B000717B1D888C457912D9D353DE30CF13DEF6
-:1090C00030E23ACADB2FDEFDE958C40F56C1881ED4
-:1090D0006B775F5DDEF04CB11FFFCFE40D7B146D4D
-:1090E0001B3CEFCF7470FD4AE60D7BF87EC9786BB0
-:1090F0007CBEF0858C90CAF3FAC25B9E42BB7DB702
-:1091000089F261C6EF7EFD18FA35C79B5990E2CF10
-:1091100071FA43C4396909D2C9C54FCE6C798861E7
-:10912000BEF9CB1E7E1E36561FE8C91EA098499474
-:10913000DDB83653E8E7DF923D20F9759DB0AF3ECC
-:1091400056228F14E0FAF6E9EDDD9D5FDA22C7EFD3
-:1091500029DFA5ADFB7C17E98FAE08E7C7C4BF7652
-:1091600074F6776DF1B4E7507676134F5345FE9A57
-:10917000AA70D6C11C3CBF49C6D3D4D6011427332C
-:1091800075C5D342AC9B789A2AE2532B0C5A25F929
-:1091900069F699DCDC8EF612FF6A6C4DF5207FAB28
-:1091A0009B7BEE453C7AA13AC6BAF09C5FA3807FD8
-:1091B000F5D5C7D3DA33BB89A76D157ADB0785BA36
-:1091C0009011E0BA9571FEEB6F9371351DD9B59191
-:1091D000877368DECA4433CDFB83574DDBD03F3500
-:1091E00043C6CB5EE5FEB519222EF6C1C402F23F9E
-:1091F000F504E7194DB1718777059C2F594AC94F7E
-:109200007FFF2F26907F7E16FAF7FBA07FAB59F8E1
-:10921000EBB99FCFDDC4EF3170EF50E81E59441316
-:109220001DE9A476BA4F761EB0D18DC87AFD80357F
-:10923000DF81D78A4E417DC8DD086550FAD595AAF1
-:10924000DF05EDB61E4B20BFE20AA75BE4E7F1F8AD
-:10925000B57FB512E8C7FBA5FBE3FC8D3A0DFBB962
-:1092600094C9E57C5296B1DBFB281A0D224E22C62A
-:109270005BCA60DFE1A953F87385B89F301E1EB248
-:10928000BF4643BD19FD7B911C7E0FCD25A33685BE
-:10929000FCCEC90574DF5463627D5305AF279ABDC8
-:1092A000648978A9FEBB2A5748993B99F2A83345AF
-:1092B0005E621C9C6736C796E3E347F1E7E36630DE
-:1092C0005FFF8C3E979F1F3B8FFC16FABFB42A5F4F
-:1092D000EC8B87E2288D06F71FF2290ECBEF935A0D
-:1092E0009ACDE1A6CBE1CFDE8E72BA1710E885EBFE
-:1092F000718CCFBFF7779D0AD24BA383E3ED7F77C5
-:10930000DEF1F34DCB2AE07A8D83D36BE34A25C09F
-:10931000E1C5E77DB57E92E2AC6FD74FF281E2798D
-:109320003A944FDF117FF03F6C20BADB6BE1E75ED0
-:1093300025BFA28423B43F85BD7B232AD318573D84
-:10934000BB9CEE85DA58D53B09E3AE6326D9681D90
-:10935000B5AFF273D5358BC3B988D7B565E182FA5D
-:109360006EE08A03A892BF42BBE94EC6EF176A8A35
-:109370008D23C6C78757A768E3B346A0BDF441EB6A
-:10938000EBB8DFAD1692AFB58B234FA3FFC097E2CA
-:109390009B9405F871FE81E36315377D46FAFCC5A1
-:1093A0007DFDE93CE8F4C6D873716C756C7C923530
-:1093B0002593DF9DB5C4BEC7735B31DF5D16AFE497
-:1093C000FACD3AA36F00EA9F37DDC8F3313E99A387
-:1093D00063B8AF9F58F8FEFB1F4E14FCDA53102DF4
-:1093E0000FEA7BDC5F683708F302789EAC6C5F8322
-:1093F000FB0BFB5A2DF6F79397BE5380FB7BBEF514
-:109400003B05B8BFEB0CCD1AD24751BA6F21C2E36E
-:10941000F4CD5ED20F655EF0D5E25DC3B78C77D731
-:109420002A8F9BB3FE35798C7FD17E9357BFD2FBB9
-:109430002D245FF879E22EFFDD39BA57EDE2973A35
-:1094400005F9714FFDE50B3DCF65667ED4C34ACA71
-:10945000C2F45DC9DF750CF541A907C7CFFF4931DB
-:10946000FF9D599A09E5A0F4F75689BECD81CFB981
-:10947000BEBD5D217FAED9ED4F1A45F6D5CCE17A60
-:10948000E22FFF46E742589B62473B65CEF6A55464
-:109490007F61F70CAAD7994321B4C76AA01ECB2BD2
-:1094A00046C7E6791B77F27890B47F611E7AD4D7ED
-:1094B000129C1123E2672DEAD730C55A95FBBD6B8C
-:1094C0009DCCE367A80FC7DA8B32AEBBD1CBEFEDF3
-:1094D000D9D8A6D0FD5D69465F7E36EE6B5C7C77A1
-:1094E0007F96760EF14EC6E71F4CD30E22DD3A8DE5
-:1094F0002C97F2F90CF25C5AECB9CF9EF2E48E761E
-:10950000E2C195F4A8A9A42FFD9579495F7A072FA8
-:10951000CD243DEA4ED2AFE4FBCBF3E40231F1FCC3
-:1095200059E29CEE2C714E17F97E288EEF4797ABCF
-:10953000A3F2E442DDE53B44E5C9457F179D2717CB
-:109540008AE18F9C9FA4EB17501CBD0EE866D1B03A
-:109550002EBCAE66E26F7DE4033A37B4C3447EBAF4
-:109560006A91C75B57758AEC9F3A3C87C4E95BE315
-:10957000E7E9B97E550D7625E5330763F37D95EC74
-:109580006F57FF96ED7AF2C7DBB2A59DC8E95BAED7
-:109590004BAEA3BA4DE1F41837CF787B3ADEAF2E4D
-:1095A000EDE1ABE573EE6F79DDD7CAE706C7C1E140
-:1095B0005FE57397C527FA46923CDF427CE223774A
-:1095C000731ABA28659E74D33E9E273D566FD37892
-:1095D0003C54CFF325E2E3C2EEB114F7947168F383
-:1095E000CBFAC0B27C6AEFC17CB49A7D8994BF503B
-:1095F000E5AE223D3E3E1E3A97B58EC5ADF82B3BFB
-:1096000042E7DEFEBB7908DFCF4E74129F72B3FCD7
-:109610006BCC43B83BFB1AE2A1076D9FA7F8A2F001
-:10962000A56C101804837ACE379B2BF63F41E4AB30
-:1096300098553F73447DDFD3770BB2B93FF1A0C893
-:10964000935A939840F737B88CFC9C874BC7F3B973
-:1096500086667A17E2FCCD6EBE9F4FECF901C373AC
-:109660007B4F1882749F82BFC6E641B928FD58B26D
-:10967000FF76E15FBD5A3A5AF93FCC3F1E957473AD
-:10968000B5F1BCF5008328FA8AA7879EBEEB89BF97
-:109690006CCFF63EC1F1421B427190ABE44B09C561
-:1096A000C0B751EEEF34B9D11E41BF0CC9DBD5199B
-:1096B000D29EE7F742ACC921B9F88985DB27F2DCF5
-:1096C000945CFF2EB9FE6F496FB4A47BF764437FAF
-:1096D000A74B353A27B12291CB97C8B33C1F29FE3F
-:1096E000FC50BC5C91E75FE478BFFBBFCC578F7D3B
-:1096F0004B7C15E42CE91D3DC67D2FFBDECFEFC171
-:1097000029EBD044FE0D9DFB90F3AAEBE0797C673A
-:10971000C5FCE4FB90D07306E7681F215E9D7FCFF8
-:109720006CC6B86A7131E79FB55E1BC5256A833C7C
-:109730005FA77631233F823C273CDBE5FB1CF76FBC
-:10974000C5711BDD5F5BBB7B6B536FCA67F091BE5E
-:1097500078E13DFE3EDDE5FB02DBD52D0EC7C43FC3
-:109760004ABEF97C794531CD97FC004E53ECF9ABFC
-:109770008C1CCE6FE4332D47C217EC1DF8EE7C1520
-:10978000CF3FAF736AF652CA63E0FEF5047707F97C
-:10979000956A77929060940C8BF53FCB26BCA9DD3F
-:1097A000595A44F736042D45740FD19FF8BD5DE733
-:1097B0001FC80CE8B93F3E2967049E3B09DC8A7A42
-:1097C0006B1E8C832AEEF9D65B8BC8DF1847779225
-:1097D000DE3ACFDDFED01C6850BAE8719D81CB49DE
-:1097E00029DFFE91EDE6F110A7C8476C9BC066DA51
-:1097F000BACA36676C9EE6CEAC9BFF81FBF38F6CDA
-:1098000055C4D179DC3EDF0CD66CEFCBF1305FC4B0
-:10981000ED27887C0BE63777E559F4BE72DC5ECE27
-:10982000AF93EF8BB87DC297E27722EC46C28BC430
-:1098300026CE3718E005EAEDA3231D63F0BC5BDFFD
-:1098400096D06884572F043F9EA361E19F0FC5788F
-:10985000488A3A1AE3215B160D3B80715A7565C739
-:1098600077716BDCCDF632345967BBBC37E4107FBF
-:10987000A92F44FC2FFBA381E747AE4C2079DF9250
-:109880005B4DF991178E9B62CE23C53FFD6C990B02
-:10989000FD50BD9BDEA67844E24EA5DBBCD79FE61B
-:1098A000D844FEE43217FAB5129B3AFC23D14FF3A9
-:1098B000B0C2EF0085D92B2EF427A83AD43B66EC32
-:1098C000E6E7E567343BCACCC44F151ECF19ED243B
-:1098D0003EA9AEBC4D87769FBA94D17D7BF373B819
-:1098E0005FBC5F8B5D87FBFEDBAFF5DDC6E97C39D6
-:1098F0003A19573422B86A4C914398DA29E38B32EB
-:10990000CFAEA77BECA53C8AD7672FD363853CEA13
-:10991000D4E7E3F0B8A7EF247E4B7CFEAD81911E27
-:10992000F65BC54CE7DE245E37CAF3075F733F7111
-:109930009EC8DF39B5EABF86F07B02647C26C0EFA3
-:10994000713584976711BCC237FA71DD3B1DBADAF5
-:1099500041E45FABA57E56F27BF2F29AFA2C1B59DA
-:109960008C4F3B53600AA7F6CECB43BAF4031EF4E8
-:10997000EB060F6ECAE17952EACA04DA37752DDDBB
-:1099800010CE54471AED9BFA18DF9FEB73383C65F5
-:109990007C58FA4107E7F8D6603E70E739B545567E
-:1099A0007E4E4D9CAB4E5C74FC053CFFB545F8A368
-:1099B0000FBC3A907EDFE3D24A55413DF592A39227
-:1099C0007ECF6AA3D8D744B583D96DD1F87980F218
-:1099D000747BEFE3F986AA3837AEAE746E4578969D
-:1099E0003B7D948FFCDDC610FD04C6ABF6D314F7A7
-:1099F00003BD88CE079FDBA348BD28461E4ABB2D6A
-:109A0000DE1E7B51F2CDFF213D694F279FBE463BB5
-:109A10008BC5DA9B9DEDA5FD186F4FC47DDF93FECE
-:109A2000C3347F4CDECD11B1EF52BE670ADE28F39E
-:109A3000713ACF89B38005CF714C41A21CD1959763
-:109A4000C444BED27AC5EA417DA9A7BCA4CEBC213C
-:109A5000563F94FB37EBBF834F99D724F3962C984E
-:109A6000BF927279FE8A05F35752F07750F87973F6
-:109A7000997FD26070533E8BFF4146714965620504
-:109A8000F9FF92BD46C2BF8B2CB0017F07C03FD902
-:109A900046E7EAF19C13E27D447151BF632A34D951
-:109AA0005E87ED3BEF93AC64549FDC57CB403DCCDD
-:109AB00002F578CF75E739F399FCDEFDF8FC1599CE
-:109AC0004725E3CA99FD5F56D0CF8A6104CA67F87B
-:109AD000B1F82E9FF7D3F22337F18DB4069E2715E8
-:109AE000B99ED9D1CF5F26F98F39765FD729BE7C51
-:109AF000A4CF75567ECFC266E669D243B93DA7377B
-:109B0000EDE346E6DEAF2386DD4CBFDBF1BC53D38D
-:109B1000E7A676E1939C175BCFD77D11CFAD295D8A
-:109B2000E35D9CF3F75CD4AFCADA4C1C2FE3C6DFCD
-:109B3000D879CF4DC082F2C495CBF1C113A7EFCA3B
-:109B4000A72B5789C9FB93E3F7B43E899F57D2E30C
-:109B500025FEF5846FFE32B14F271248FF90F8764C
-:109B600060C90EBA4FB27D49909E172D4A508FE7BB
-:109B7000872D9169C81973F2B2EEC07B502E26462C
-:109B800072F11E95016EB717EF51B9981A3981E538
-:109B9000EB9FF8BE97EAFB45B6E0BD2A77E41DBB14
-:109BA00083EA713F33192BDA72E40EBF0DCFA9841B
-:109BB0009777A0DC2A8ECB8B89BBFF2141FC0E540A
-:109BC000BACD48FA64BA8813B272A1D763440BCAFB
-:109BD0000D19451417B431F7CE0EACCF36F17B22F8
-:109BE00018E03FD6F7CBE7F9158CAF9B650B7F37B5
-:109BF0000BFBE9771DF31DF47D271FDF6912F12EA2
-:109C00003EFED197785C52E6093366CF417DC8E6C7
-:109C1000663165797F0A53ED39785F4283F4278A8C
-:109C2000F22B09BE49B95172F9E8CD3F1944BF2F53
-:109C3000F3F2CFFA22DFBCC5187B3FB77C26BB39D5
-:109C40009FBC28EEA1BC2FC17777EE08FC7D9969F7
-:109C500063F14AE12929A54607E96FCFEA914FA5AB
-:109C60000AFC704CE6F373947B15FC5D17790F6466
-:109C7000AA4F253F01F3B5E851AEA69EF652FE610C
-:109C8000B539928BBFBFF396D95785F3BC5479F29F
-:109C90007E8A3F661E3D81F922470DCD6392508E2C
-:109CA000E48B7B3830C00BE5435979640F76F2873B
-:109CB0007E0AC547C74FE6E771C7B1A08AFB3CD60D
-:109CC000CECF878D2DCEF734C078E345BEC9D8639B
-:109CD000DE24E46F637F1056F93D2111353ABF430E
-:109CE0003E99CBE08EA6875BDD516586F755C7961A
-:109CF000BFE7892DDF31F2EBFED1E5C18AD680EBDB
-:109D00007C4511F76D007FE1EBE2798CBF12F6DC48
-:109D1000401733E7619EA553F1A3BD30705726C5A8
-:109D20006D768D64544EDB61DE668E5EFF5A1D8F4C
-:109D30006B0BBFBAFC7D2AAC4379FBF27B6904AFA5
-:109D4000341BF05B27711FC2B703826E0F083A2DD8
-:109D5000C9325B91FF1F30B837119E279ADDE8A703
-:109D6000DA9F68A4FB7F1BE6F3DFB75092CCCC08E8
-:109D7000FDEAA7F332B4633742BDBEC44CF92907EC
-:109D800044DE77C3832AF9B9B01EEF41D43F622580
-:109D90007F797952E1DD58AF4F32D2B98BFD8925F9
-:109DA0003E311EFD2EC1F64473087F2723FE1ED6CA
-:109DB000A3382F841BCCEB293E0FA2477D8991F459
-:109DC00070793E1FFAA1789E3ED34CE31D70D8F700
-:109DD00023DE357C449A1ED48F74633E99C4EFF21F
-:109DE000A491F4BB33407D7DA3EFD9D7A779DCFCE8
-:109DF0001C30FF3D95C2CEDF578161A11DBAD51938
-:109E0000D12D8F0FE648B83355C3F6194C96F9F9A2
-:109E1000B5B4CE72A94AF72D29B2BC94CA8F8B7AF9
-:109E2000796F6C6A1EE7534ADBEB7F43BCED9B0402
-:109E300070817DF224747F7EEAB4E0EF97EF5F8952
-:109E40000BFDFE0AAE7350D7FA0F383C2E6F54B993
-:109E50009B7D0920BEC5EFCB018BC78D7EB62BF74E
-:109E6000C7E12AD7A1CFE4F0EC5C474AF7EB48CD35
-:109E7000E3EB088A73E3F1F54A9EEEDB5E67B7F821
-:109E8000F72FAF332D769DDFE23CC3CAB7304F7D4D
-:109E90002ECCCFD6353FFAF9B812E49B1CFFC68909
-:109EA0007C6956189BE7C4467ACC5C5F8CCD6BBA54
-:109EB00045D9D488F2F57111377F5DD0D5A184FFE3
-:109EC000D517F5ADD7A715B413BFEDB5B411894BB0
-:109ED000F267C9FF2F659C2CC132C88101792067C8
-:109EE000EEEF7D741A76DEEE78BC2FCA2BE09BD79E
-:109EF000E58DB87C9E927E3BE70BF48B7424E937AA
-:109F00007EFE928ED8ED414A10DDCC42F474319E33
-:109F10008F0F7A09DD73CFDC395DEB03221F6BAE47
-:109F2000E7EB58EAA779DFE27894F2106FC9F7DD22
-:109F30009407FB3D65E8A774FF147355F6273B4D66
-:109F4000D1B4FF9BF3C58C7F7C2FF5FC78BDFE4A16
-:109F500079E9729EF1FC50CE4799B883F4F83AD073
-:109F6000E379DEBA42FCBEAE4AC7F9F06E85F4FA78
-:109F70005A903328A7E4BDCC3715581BF19ECDBDB0
-:109F800006EE4FF5BF6472C7DE4B159FBF2EEC89FE
-:109F9000C54CDA0BFC7E8B1A3BBF774AC89996FBFF
-:109FA0007ACB7BA9B83C043915732F55A53BF65ED7
-:109FB000AA1EEC05B00B483F63BD74C22EE072BA16
-:109FC000E57AB7DDCFC8FFCC7F2774AA51E88300BC
-:109FD0008BB4AE7BF3C00EA0FB001BF3F2C5BD64D7
-:109FE00001FEBB2C42FF8FF74717A5FB56209ECCE6
-:109FF0001CA4E5E24F04CD30727F33E0DBA60E8671
-:10A000006998F5DBF15ED95B59FD3BBA3E846F0F71
-:10A0100013BE0DFC94DF37DB856F8FE4A572B98426
-:10A0200042E64A741C71FA1EC7715B1CC13FE13DD8
-:10A03000F81BDB4C046F99E71A4FDF51F3396DE0E1
-:10A04000F371EAF5349F27BA9BCFD5E07D345EA546
-:10A05000338EDF3DE13F9E27491CD685FF8315DF08
-:10A060008B386E271D2CE776D765F3D6DB68BFEFFC
-:10A070009CCAE3727509D24ED6C667A4A11F928FFF
-:10A080007FE74A8E177756F2BCA4096D35148763B3
-:10A09000E53CAEE681FFD1EFFC08FE36D9596440BD
-:10A0A000D4FB2BBBDB807ECEC9E363E36F53CCB71D
-:10A0B00050BCEFCEC98698DF39957098227E477DD7
-:10A0C0004ADCEF9BC6C3253E6ED7C90FC47AB3F0F6
-:10A0D000777FE099CDF8399E0CF17B7447F33AE332
-:10A0E0007BFDAF31BE772CEF1AE27BED8608DD3BBE
-:10A0F000F15AEAEC4DF3816EFAFF7210DDDB7F73EB
-:10A10000DA9CED6BA1FCCCC6EBA8FC5ADA0F171E4B
-:10A11000C5FA2D05542ED77D3A0DE9A0B064EA3872
-:10A12000FC9D83760BEFC765F5B5E0EFDFB886F4ED
-:10A130001E86F9C8E5C608B5BB6D68CD70CCAF2AE0
-:10A14000B7F2F291A2FF1846E5DEA23CEC95EBB027
-:10A15000DCAE7C3AADBBF8E0C0422584BF73579EAD
-:10A16000CCDB8F1FF66C26FA8BCACB7879A0A7744C
-:10A17000651FACD77D36AD3B7DC428EC21A95F7B44
-:10A1800005BDEFD24E36E2B944AF4DF1E0F913EF21
-:10A19000C893FC3E3A33CF53F93F722300BD008091
-:10A1A000000000001F8B080000000000000BE57D90
-:10A1B00009789445D270BFF3CE9564924C0E20215D
-:10A1C000102609840492300987288703048C0A38F2
-:10A1D0005C028AF08633E42011748DBBEC6620802B
-:10A1E000E8A28615151574404070118302A206BEC0
-:10A1F000E1505151E3B1AEE82E7FA2ACDC1283AE48
-:10A20000B8EBAE7F55757766DE37C902FBFDDFF32D
-:10A21000ECF7FCF8EC76FAEDABBAAABAAABABABA7D
-:10A22000C7EBC935CFCA626CB847F1F8211DE158B8
-:10A230009268EFC7D858CDDA4F5518733A5296390D
-:10A24000E3198B1E38AC3F7341B99D59582A6337C7
-:10A25000A468E1AE0E8C4DB9E6DBE4289531E62822
-:10A26000ECE98D849405181BC0D838FC13EA8FB331
-:10A270003B026A0EFC9D6F39D790C1E8DFCFD03E1C
-:10A280005BF1385DFD31D725E6EBDE8C61173F5F72
-:10A290004FFD76C0EF53067D9B6CC68F09BCDF0B6C
-:10A2A00016C74A253AD8FF4DA27FE661DDE33B326F
-:10A2B000A688FC4D72BC0CFD78F84F817A9D98F809
-:10A2C000BBEEAD1F15ACB7A25661690005F351BADC
-:10A2D0009ED528084CB6A2A5E3FCACA67A177EEF63
-:10A2E000A6B87B39119E816EBB37BB35DC12BEAE82
-:10A2F00026F890D71A2EFC67867C1293FF14A7B31A
-:10A30000238ECBCBA19D87C506E182F107107E5637
-:10A310007078D62B1594624306ED1688760BE47C94
-:10A32000F7EAE73B209CF9C2008E04E65EA962BB17
-:10A33000F8DC5EFF0AEEF2F0A81CD687B18976EF52
-:10A34000833698C3A4985944E7C9CCB73B06E6FFC7
-:10A3500062845680F0A826DFBE0698D41CE6B1229F
-:10A360005E808E37723A72BA48B88CF86881D388AA
-:10A370001703DC463C04E9539F886922ABA07CCBE1
-:10A38000BC0CF3A9461E047E6DCAB5F937E22066FF
-:10A39000F81FF0F3D1C274FF034A10AEA30ACB300A
-:10A3A000433D9F12EEDE9CC2D80F61307FF81E2F16
-:10A3B000F03068E62FC6B2A8D6F056DA79BD7BC277
-:10A3C000A336627A7D7AF8325334B64FF663FDF8DD
-:10A3D00070487382F0FF60629A1DE0BD47AD25FAB8
-:10A3E00075614D4BCC29413E7BD80593EE8F7C297E
-:10A3F000E7E353904E569332C3EB8039E1BFEB83D2
-:10A40000E9C32E4068078E2F3BC0354370D38C06BE
-:10A41000A55141785D290E5C2F33EC6AC096D39A22
-:10A420005F704676A0D3CCCBF00FAB799C61BBE1DB
-:10A43000765E6F26F68FF5168FF484D69B89E3E05F
-:10A44000B82BE1BB3DF85D01BC27C5B6A60FCC8F8C
-:10A45000E01F5339C27B220EF06515F4BA3792E83B
-:10A4600035E6DE61F45D199FA134C0FC4714B828BD
-:10A470008DEDF7A1996513DDA6D46605E9A876D41C
-:10A480009EC275CACC0DFDC7C1BCDFEBFF5CAE063A
-:10A49000E5C74DAC08EB19F1F75C107F57B48EDAC5
-:10A4A00083FFF508EF36E4FBF34AFD002CCCEFEC1C
-:10A4B000243A32A6A520FD629C29C36210DF3FC169
-:10A4C000B880EF8958047CB0A7A3B613E19DCCBC3B
-:10A4D00023CD30DFD802CDA239683813C2B3D0C93A
-:10A4E000E119A93A886F9BB72B7E1BD4CBF7643E4A
-:10A4F0003E18F2E5472CCC0FE5CD8CF375F33AD539
-:10A50000EF037E9AF7F6CB036005B2AF041FF75C4A
-:10A510006B622E490FF85FA63F9CB93282F9DE5B71
-:10A520006375F9ECDACEBAFA7DF6A6EACA7303BD12
-:10A5300074E57D8FE4E9F2FDEBAFD3D5BFE6B3E17F
-:10A54000BAFCB50D37E9EA0F3A355E971FD2749B16
-:10A55000AE7E7518ACAF3E886E4F7D06E065B6A046
-:10A56000D3F59766EADA9D8D1A7504D7DDEC55F3BD
-:10A5700046E3BA1BC64A74FDB01ACB97C89715F0CC
-:10A580001FD2732EF34607005F2359D39B4980BF28
-:10A59000057EC58D789BB796D793EDE6EFBD7378B2
-:10A5A0000CA67EFDF712660EE6A19FCA3F6D78E706
-:10A5B000704879BEB3D084FC77DE1519FF7504228C
-:10A5C000825DF3B3DA267DDD01A4DF27AADB069FD7
-:10A5D00016BEADD23A58F882E267D06F3AEB118DD1
-:10A5E000F9F2232AF303FD4FB28AC70643FA4395D3
-:10A5F000FF9DC33D82F8B125E8E91CE6D2D339229C
-:10A60000434FE748B79ECED103F5748EF1E8E91CBD
-:10A6100057A0A77307AF9ECE9DA6E8E99CA8E9E9DD
-:10A620009C54A4A773D70A3D9DBB55EAE999E22B38
-:10A63000D6D3CF407F299FD3562ED4D56BE1036F5D
-:10A64000D1684C7BD4FC52D76F895A6A65A6203FEB
-:10A65000F8E03FE4879E8CB90380E705408780AB34
-:10A66000351F14D5AD5E91F46FF041760AD0BF77F7
-:10A6700008FDD569D15A1BF25CA692AEA04FFBA68D
-:10A68000F4273B6800A6537A821D04728379DBB6F7
-:10A6900083A4FC0AB53BCC0382FAAA3DB9D64ACFC3
-:10A6A0008E95FAA91D3DEBEA1A94838090638CDBAA
-:10A6B000018CAD32211C53055F1F0CE77C79118B97
-:10A6C000AE857A506720C0750CE186718E85F73EA5
-:10A6D0008CEBF436566BC1FEA7B17A4AA7B3264A73
-:10A6E00035E624BB622673533A9B79297DCFAE4D64
-:10A6F0004901B9596A6F188076C95F0B3F3CAE209B
-:10A700003047E310D876F12AE5F5C7F827D47B3037
-:10A71000C5AB215EF3EDAEBB1E854F07514FA0FCCC
-:10A720001D1D47F032B3377B7C765BFD2C25F9FE8F
-:10A73000BAA26928777D8976F766985BEF24664F21
-:10A74000443D97E04F1D0FF4294FD1EB975E8227D0
-:10A750005EE85CBB10ED28C6FCB1A81FAE76DC5FDE
-:10A76000A5787E8170CBFA979BAFD55A7B27C2D94B
-:10A7700054E6706F04FEFC44D0E3D95B6D01352ACA
-:10A78000C8479F454C7FB303D0EDEE086D19F1DB50
-:10A79000E41B57605E3918E75A08F05D28047C73A3
-:10A7A000FCAFC4F252BBD6AD234CF17C57AD67343D
-:10A7B000E2DFCBF10F7F647BDB849FC33342E1E3B5
-:10A7C000BF1EA1ADC67E0E9AEA93DD880F73FD0011
-:10A7D000B24B1D1DA89FF3568E97F6F0303CA2EBAE
-:10A7E000349CD76C9BCD8DFB93E10AA7EB89B819FC
-:10A7F000D3CBE1CF39266FC780AA83FB1982DB59FF
-:10A80000D82D11F8E6BC45C06DEF20F0EECAC27538
-:10A81000D51EDCD5D83FDA89BF56FC6827D23FC8A1
-:10A82000BFE28BF13F00799BE9E22713D07EC93666
-:10A83000B93742D1BA70E81AF8FD0381EFF516C8AE
-:10A84000C7D2F795F83D219CB74F78CCE4AF86F698
-:10A85000DEE1AF129D9E5DE0A0F91432971517D985
-:10A860002C615FFF65D8DFF735003DF6A5687B7189
-:10A870001E33E24CC99F101C5A6FB477D8E02BE30B
-:10A880007FB94EC73BF914E608BC4D601E5A77935A
-:10A890009866C1713FFAC6EA41F9F991902760FFC5
-:10A8A000D3F7A9CC4FE9ED2C40F5EF600D94FF30C4
-:10A8B00022A76B25C037EEF19E3D50BE86E0FD7DA0
-:10A8C000BE5EB519F19C5F4E7642BCAFE97045FCA7
-:10A8D0003B4EF00BACD74FB11F58AFFD725343D670
-:10A8E0004D3EE7176676F6F857EBA6BE99EB0B10D0
-:10A8F0008C8E4498FF0D828437784A484FA09D156E
-:10A900000FF8AF77A96467150C6B3423FC5BBEE5C9
-:10A9100072ECAD252CD207E56F0D5319D26BECDA32
-:10A9200051A7B1DD511688EF07F5475ED20E47C338
-:10A93000FCC7827C0789CC0ABA809E08D14B372598
-:10A94000ACCE473BE2A6EEFAEF37B31A15F1373A31
-:10A950004BAF57C6A25E91F560BC038887D8D6FA84
-:10A96000E547A95F7AB15E57A35F169A3C2C95EC38
-:10A97000549715F97EA69979DA5A6F937B2AC29E6D
-:10A98000E576CB2D62ECE6D117AD1760BE0353B56B
-:10A9900008EC67E198BF4C47790CFBACF7FAA21EB4
-:10A9A0007D5F650F40F99755807150AE27AAECCCBA
-:10A9B0000306CED7554ECA9FAA4AA0F44C958BD217
-:10A9C00073551954FE4D959BF25353BDF1D8EFCCFE
-:10A9D00095DF9AD18EBA2F4CD28FC3B148F0EF7D5C
-:10A9E000617C9FB52872D1678530EE225280A0AF7E
-:10A9F0006B6B46A1D955BCB7F64D4CE1BBEAC0F232
-:10AA0000D58A1BF5D39CC3DA0A649F79471BC6A27B
-:10AA1000D8E9FF87131D116F659714A6C1523AD06C
-:10AA2000C39386E39FAC1A48709DAEF2105C9EBA49
-:10AA3000C637E3A0FDD9AA02CA2F4CF566A6764018
-:10AA400075FBAD15DB8FD9DE684E82F2911EC58392
-:10AA5000EB7BA887F9FD40BFB516AE2FD682BE406E
-:10AA6000FE19963D7EFD5D0CE5B9D617C799143BDE
-:10AA70006B641CF2D5C04233D69BFC13D85C2941D1
-:10AA8000FEBEDC3A39BF5F21FC9CDF1F43F89078A3
-:10AA90002A13F43ABFA7F72D83A0DFFD6047AA0071
-:10AAA0005FF32513C1D7FC59B81F8D0463FB85BB29
-:10AAB000D33A3107CE131ADB30DFBB13033A9C7D48
-:10AAC000E19E04A44786623655825C381B5BFBD747
-:10AAD000CF51EEFD99CB3DC66ABF7E12E562970469
-:10AAE000F70390FBC602FB34DAD75444A05E5C60E7
-:10AAF000651ACF6BBD317F369CD1FE76C08EA4E146
-:10AB0000B89E703C57CFA05C4BDFF178EAAF5CC1D8
-:10AB1000F96E79E189E6D75C58EE27BEDCB6637D35
-:10AB2000E7A72057BA737938C2F53ADA19B04E5E02
-:10AB30005F1D41F2EB758BFB7825CAEDF50EF766CC
-:10AB4000A8F7DC43F77EB917D307CBF2EE45FE48F2
-:10AB50008DA57E66FF6E7E2F6C0F7A9C25C2BC7E13
-:10AB6000FF8A120843FFCB9A034B1361BC3EEB1ADA
-:10AB70004D9D21CDDDA45463DABB6BC111D49F156B
-:10AB8000A92E6ADF777B8A8AF661AFCEFECFAF2728
-:10AB9000FDAED7FB596BBE1DDE9905F57F2FA5F6DF
-:10ABA000CC12A0EF7D5D3FCDE3FBBE1AEA6777DDF7
-:10ABB000848F6F67380FB02C10EE422BF92570BAD6
-:10ABC00016C89FDF95B601FD177B4CBE0DA48F669E
-:10ABD00072FBE3BCD7F704F24D19D4F741BE2CD772
-:10ABE00017751D9497FDB9BB1B3884757DFA8602D5
-:10ABF000C4C7825D8F8EEA0CF5CE0F666E05402FBE
-:10AC0000DA7D7114B6635DC156C67E765577BC0D8C
-:10AC1000DAFD366B787FE413AF5A4BE3B0723ECE69
-:10AC2000E3428FB1861CF20B904A817ABF85CFF840
-:10AC30003DB62EE600F76D71FA94D72D4941FF4AD3
-:10AC40003FCDEE56711DA4F8122B1C41BD08FAEC45
-:10AC500077B87E12ADA25FE78464EF55E833ABD0DE
-:10AC60004FB2BFC7ADCC1716CBED6005F5AD95EB78
-:10AC7000E1CD202F905FA51E867137A6F2F664FF06
-:10AC80002681D2CD0538931EB7F949D75FE1F84642
-:10AC9000BF99B443A6C455EF6B40FF4E84B603C7BB
-:10ACA000917E326676BBD0CE5916E1793195ECA80B
-:10ACB000A6649C03E8C997B1DE0215ECAAB410BBE8
-:10ACC000CA7E657AF2C508CFABD8FE4AEB1BE5E831
-:10ACD000A2EF4D2C17F860D1A336DA77560BFF415F
-:10ACE000B5F06755470EB0E3FA67874DA56F82FE52
-:10ACF0001CC27B68E97751641EC9876AC6DAC4DB67
-:10AD00007E58D71AC89100E8010DD6F7D04B4D2ACE
-:10AD1000E7FBFA43D1FD507E324FA40BF7F526A690
-:10AD200085E847633F40B76338CF612C8269217A59
-:10AD3000D0C362ACB87E9923F6DF9AFF60413F39F9
-:10AD40008FC1C27F37B8F9B30894838BBECF237904
-:10AD5000D8DEFCF689F9FD17CE0F526F4FEF39841C
-:10AD600073C8774E33CE7388795C32DA2D007F3327
-:10AD70007E1FFA9D490FFF4FE1BAFC95CEE36E8529
-:10AD8000F94CB83EBFB5FA717DD6017FE37AAE9B30
-:10AD90009FE54739B007D603FAF17DE3AD64B7D636
-:10ADA00009BF685D0727F98B5EB7F0BC6FAA681F03
-:10ADB000C6482FD44DED4CED3BDB2ADECDC6FEABB5
-:10ADC00023487ED659FC2B53B1FF5FC7B97D402F76
-:10ADD000D5FEECFA137D61FFE037F92CC82F96C041
-:10ADE000ED2AF6F7AD95E1786B620249E5507FCD2B
-:10ADF000FCCE54FF33308DD01F37C8649A31CE81DA
-:10AE0000E59EC458C8EFF9A74A7A604D2EE41D2488
-:10AE1000C7C9BFB7669C27313C1ED38E26824765C3
-:10AE200015F43D85B7FBDCC2EBDD26E8774CD00797
-:10AE3000D639C9016D6C8419F9F8DAB49959696485
-:10AE4000C778121580E7C9D93D18CAD1DB8A6F4C83
-:10AE500021BE117ECE298206B23F26FCA493F8675C
-:10AE60003675CEE630A4E7A4A230F2837E56B43421
-:10AE7000D205ED2769C2FF3951EF17BD36CD43E347
-:10AE800096D566A69D08E1EB9936901BD0FF43E16D
-:10AE90005ADF34E4C7BDB954BE178C959F615D7D00
-:10AEA00039BBC70EF253CC96FBC2C02CA4EBFE26D6
-:10AEB0003BC3FD467BFC508D74807EBB215DE2046C
-:10AEC000BF22FDA784F37D8B19F805F2D5B599B49F
-:10AED0006F79C6C23C0AD26BB78DE85F30DEEE21D7
-:10AEE0007FE294F00D36289F21E459F59470FA5EC4
-:10AEF000BD2FD26F52683F4479DF4E0BB52BB5FAA8
-:10AF0000B76D817E4AF76792BED96315E3BE16C15D
-:10AF1000CBA33C29CBFB617927E283D72DAE682AEE
-:10AF20007F5B65541E1E488F013CC6856913111F47
-:10AF30009D6D406707F6CBBF1F17FC751CBA45FA1D
-:10AF4000F92A22A95F5AFA90D7AABB6E447A6A56A8
-:10AF50005ECE7EA952F971A727710EE48F57241196
-:10AF60005CD26F74DC6B25BE3F5EAA90FDF3A74AEE
-:10AF700035600DF5DB8FDF7A7F3AB4FB6ABF85FC65
-:10AF800072D31E2E398ADFA72D2D23FFE2B4E2C52E
-:10AF9000742EF0CDE2AF06AC85F9342CFD22590BAE
-:10AFA000F1334F2B855621EBF937699E32E4832725
-:10AFB000D3B40A9C5F7956C35CB497BFB1D63F8DBA
-:10AFC000F67F7ABCB608BF5F78F5E4166E4737A502
-:10AFD000A39E5860E67C22F56DB9E0C35EDDB57BCB
-:10AFE000B13EE06D3AEA9588AC7A2EFF165F99FC87
-:10AFF0003F53B7798F02E39484D72DA054F5E760CF
-:10B000003F67954094924678D4705D9D7306A21078
-:10B01000FF9A89DB6D255BF5F3C27F789E55827FB1
-:10B0200040BB925AD51386EB80F9AD087F09B30671
-:10B03000EBA704E905FD10BD98E34FD37F05742805
-:10B04000DE969987FB859298BD0F0DA27AD04EAE01
-:10B0500017B5755ECEA7353C7C7EE7C43A38075FEE
-:10B060002CC82FDB6D72DF4EE37FF36A271ABFA374
-:10B070005827DF28825FB78571BE72C3BC10CE1718
-:10B08000395F3D26E5E436DE4F499CCF8472A9A4A2
-:10B09000CA497C25E512C042EBEBEC8E246A27E519
-:10B0A00018F33246F577246EE4F69BD8BF22C050E1
-:10B0B000BFF8F77C1CCCA33C3FF37C921C97EC6759
-:10B0C000A33E36CE7B7F9A89EC2DD0D39DFED5FE54
-:10B0D0002F2361D6FAD97D43E613691572C19D30DD
-:10B0E0002E1BCF0BACBA7EBF89B4CEF038F0DC405B
-:10B0F000FF5DF6F74E1ADF1F7633D0B9B3DA74C0AE
-:10B1000086EBF059467AC308C787A2DDF3CFB7D0E4
-:10B110005515FE71E692FCE4E2F63CD1EF9855D26B
-:10B12000EFAE2490C72588ABD4201EF7E46A49A867
-:10B1300037BE11E73D7B62209F85F614A78BCC4B71
-:10B140007A18F972E9B1B94978BEF4CF34EEB73361
-:10B15000E27B09E015CBAB2DB05FC9C27DEB914717
-:10B160004EF408CEE7EB2A8F6776487EEEDA5C3B3A
-:10B17000AEC779EB72ED3343E851BDB5EF1117E07F
-:10B18000FDDC56B31BC57BB5D9FF10DAE9D55BD51D
-:10B190005AE42328B723BECF390EBE8FF5E6AE8B17
-:10B1A000C9433B5CB69FB776A46776081D7A6FD516
-:10B1B000D325BB569FEFB3579FB7776734BFAB6DAF
-:10B1C000971BD0E7FB1ED1E75913506F00DA039CA1
-:10B1D0006EAF0C741F7101DDBAF955377EEAE618BF
-:10B1E0003F610CDA11EB54770F28EFB6D87B33DAD6
-:10B1F00015A7D6CD7123D98B54DF825F014D8BBE4D
-:10B20000187504F5EA5956FBE918A0CBDCBAD556F7
-:10B21000B30BE7ADE7F73D26C1BFCF737FDC7CBF43
-:10B22000BEBCB55C5822FD1819A1FC65E40318F7F3
-:10B23000560F00545AF9F12328178A4603E3A31E38
-:10B24000AF5D6D45FBEFF2E3F8B87DE9F0B8101F94
-:10B25000850379D9759523D857B0EED8AA0F472121
-:10B26000DC85BF55C8FE287CB9E761E4AFC69D53B5
-:10B270006FA2F4D6029ABFF4FBCDAB530291907744
-:10B280000E74ED6D807673FCDC7F3173992D280F81
-:10B29000199E7B19E05813520EF0CFDB7BE0473C40
-:10B2A000172E5AA76F371FE434EA9FE24D3FDB4267
-:10B2B000BFCBFDE875751B549CF71C01BFD49FCC18
-:10B2C0003794CE1DAEE34DD809FC3FD03BBFEEA86E
-:10B2D0008DEEDE3FA847AF5BC3DB83D82DC47997E3
-:10B2E00039AC2E9C77999D0522009E2391560FC65E
-:10B2F000955C5C1B497EB7B936B057F3286518B723
-:10B30000008298CEBFBEFE4025BBA72C8ED3BDECDD
-:10B310001985F66965E82CC5FCB33C3F9F05683E7E
-:10B32000C82F9ED079FAF57956C3F777A5E6C00104
-:10B33000C44B316BE0FB33A0A727E4FCBA14E6F959
-:10B34000592CDA6F86F6CCADD1B99C83DB63E57BF3
-:10B350007FB68596CB7DA6DC074B7FF033E9DE70A8
-:10B360001CC722ECE635F77BD211DEE5164F3AE238
-:10B37000C1B73A8CF6FBB76DE0FA6B4D0CD8B1F162
-:10B38000643F933D7E9BC2ED733695CBC341A69738
-:10B3900002A86F9A1E8D716F74517DD2636B1ECCA3
-:10B3A000E4F6FF3F55B2879A56F3388835B91C7FCB
-:10B3B0006B1ECCE6F6BFD47B1D18F5D7DADEF6A4FB
-:10B3C000A31F823DC2E1FA1CA714625FE776D21E7A
-:10B3D000E81E323F6997B3A22B3B9FD82CE2329AEA
-:10B3E0005687F9F17CE284E27DD31462DF3ED59D7D
-:10B3F000EB8901C33D5B443D3AC7986D1AF7C0F530
-:10B4000000D7ECC74C2EF4A7B5E0DBE34947FD7944
-:10B410006275581EF2D980E1DCBF743C97CBFD8881
-:10B420007E8CE29B36897E377537E9D28470E03FA7
-:10B43000E8E7C448EEDF8EECE725BFDE661797FB32
-:10B44000C679D48A7E665BBDEF0C69031E891796A8
-:10B45000CFED8E13772A1B395C406FC80FF85D184B
-:10B46000F9034F08BD24F10B7C43710C526EC5B437
-:10B47000F08B7F5B18F0CB6A0BE703B96F0BE1171A
-:10B4800041FFAE44DFDB047DD98361825F4CEC6F0A
-:10B4900088C7914ECE0F57B9FF027A1F417A1BF72A
-:10B4A0006192DECCECEFFFAFCE51CA5E79618F0FB7
-:10B4B000EC8CE2171F8D6250EFB4B9A6A31BDA978C
-:10B4C0006E5E1EE581F494D917E584F14FFBD50239
-:10B4D0007F1BF8B6F690FE688F430939F73CF3FC02
-:10B4E0006FC7E23CFFBAD9E2449150BED546FBB1EA
-:10B4F00005BBE693BD0EF9469EBFEF5B3C072DDF13
-:10B50000ABF7B7173FF7684717E1DB97644AC034DA
-:10B5100090C4205DB0C9D2722E0CC380FDDDB40290
-:10B52000E133B647382E01BDCB6BD5426B74EBF2DD
-:10B5300072215FCA77FDF65BF41B96EFBAF124CA5D
-:10B54000FB72839FBF489C7718FDFC7FEDAE3F47A1
-:10B5500006FC50DC800FE0EA41ECC2FDC4D5DB1EE6
-:10B56000CF6944FB61D3BB514A56D0DF2FCF419AFC
-:10B570006B673D83FED3F6D6E537C2DF1BA41B976E
-:10B580005FAEBD0A0F9AABE369A925103508F77BBA
-:10B590001B2C64FF96BEF0EC962791CF8ED948BF46
-:10B5A00097BCF0C6A7D7A1FDBCD3123F9A4FC3A149
-:10B5B00084C4D994BBB83F4ED2A7F8E537ACAE6C83
-:10B5C000FE7D716C904E253B0F5831DEC788CF1140
-:10B5D000B507AC0D8E36E855DB388AFC50DB7EB003
-:10B5E000E2FA38BD5F619D525AB72FDAF04614DA9D
-:10B5F000678827D44F926E2D7434D487FEC7BED689
-:10B600008FEA39719F72393A7E2AECACB2572259CF
-:10B610000CC051F4B9CD3F1AE9BB635114CEE7A475
-:10B62000B982F3FDFAE51DD1DE2BB2F83A3A29E5ED
-:10B63000DF8B9EBE9BF8719E52D1D19945FC9E68CE
-:10B64000225BC29788F39CB36E12CD732ED3881FF2
-:10B650008BD6AB5E3FA4DF9B59C1CE36D6CD52B15F
-:10B660006E4E6E04E2C23C4F8A782BDF47AAD84761
-:10B67000DF49FAFC6E3167C61652FE7B61CF4DEC96
-:10B68000D1729E6D0FDD87966FBAAF1EE974A6ABBF
-:10B69000A713C20978F009BC293F43BFEA87233BBF
-:10B6A000713A3117C623503BD0AB23F03BD6AFB72E
-:10B6B00078D0CF1ED24EEC13F9F87789F101EE70F5
-:10B6C000DC079FECD8763CD7CE16B9C0EA43E3B985
-:10B6D000DA95039BEE27FEFAEE132E6716F8C715D0
-:10B6E0005079BD25D009CBFD07262A24276C2CD004
-:10B6F000D63ADF6411EB5C5F0E709A9550FCEEE772
-:10B70000F6A9E497B960970542EC8420FF5883DFDF
-:10B7100069FEBF13F86EA0F33979AE374FC807E35F
-:10B72000FC8DF262718FB6E34ED8BAB6CF938272B7
-:10B73000C247E396827E477BA4F4988DEC88D217AB
-:10B740002C5EC4D3D9ED873EBD0DF7B7B5725DEB66
-:10B75000E5B0715D17BDD4BFCD757D76556EDBEB61
-:10B760001ABEB7B9AE572924EFFEBB7218341FF9C1
-:10B77000252EB77EE7B523879F33E0F57B96153DF1
-:10B78000080B9D85DD884E06FC4ABC1AE5EA1014BC
-:10B79000921D5ACB5586211A21F8947894FCCA98A8
-:10B7A00046E3B4F0B5E45BC9D72D7C6B9CB71E9F14
-:10B7B000C6F2F9487B80C7FBAA85EC85D23A1E6F9A
-:10B7C00008ED283EAE1CFDF354BBE6CDA4F8D0BC7A
-:10B7D000DF90AF35D4F718F25E437DCD90AFD0D572
-:10B7E0002FDD7BC8CAF70F015D3D5BE5CDB41F6956
-:10B7F0006D67F8F9B9D3AE6FAD3EE48F2E4D569418
-:10B800009396A5CC1709ED9BF6A964F75C703545B6
-:10B81000A1DDB23C8CDB75179C221FC3F34D1DAC20
-:10B820002B504ECAEF4D61DC0F73C1DB141513B200
-:10B830009F6FAC53A3D0FFDBE067056DC7AB54131C
-:10B840005E1B587BE5DCBEBB10CEFD0D17C2B9BF39
-:10B8500061A4EA48AE443F6C0D8F0B9CBD6472142A
-:10B86000C555D4A5DD3205BECF795BE561E03E8FDD
-:10B8700019E319667152B253CC47F181B3EA785C8F
-:10B88000C3EC557A3ACF756CA2F8B7EFD9624AE7A4
-:10B89000AED1C72314B355C46745EB0CDFEB6EA6DE
-:10B8A00075526C58279AF00F1BD789235DC43DE66B
-:10B8B000B25C5DDCA390E723D5AC5BA6003D2E1CFB
-:10B8C00051990DF2CD752A5BD18FC7B9E2F9136E8C
-:10B8D0004870FD2D80F58A7693C4D7395C473DDBEF
-:10B8E000B75FCEEDFEF3805F21DFECF92207CF8555
-:10B8F000CFED3996FE3AE65FF963F217AC75FD11AC
-:10B90000FB7F9C8E72FAC27E1B437EBFB0FFAD648C
-:10B91000F4475E78CD46FBEC0B4B6DDCCFBD3FD2E0
-:10B920008F2AE642576E1757EFFB21A781F4F232B8
-:10B93000A2DF35E9566E5FD5FDFD38FAD39BEB608B
-:10B940005628F7F747D07A2A7F2D8CFCCC17F6FDC6
-:10B950003020D43FF7DF9D8F3C4FBF10C9A6BC8479
-:10B960007C1CC3F705E5AF5FFB2C9E2F97ED3A607B
-:10B970009D05E523FEEB1F3928572FBCC4EDA96FA9
-:10B980002C0D4FA38F73F896A8472C89E8E783CE38
-:10B990003A33F6C596B1137C596DE185E3E102E0D7
-:10B9A00001E7057829427DD01E3EA6223E3AFC27BB
-:10B9B000E2E3DBE95CBE5DC3F03C3A8817C5C3BF78
-:10B9C00047FAED0ACD9F7FDFFF430ECA9FCBCDF72D
-:10B9D0009EFFCFE6FBE87FEC7C39BF774D77119C6B
-:10B9E00046BE6FCDD7AFFC82F23B22DD04EF15AE31
-:10B9F000F7DDFFB1EBFD7F86DE1FFFC7CEF772F4E8
-:10BA00007E5BD03BD289E79917F6FD23995DC5BCD3
-:10BA10009BFF97CE5BDAF1C355F7915CA8FF2EAB85
-:10BA2000FDC49D42D6489B7648B7609C1FED9F465B
-:10BA300030AEA747D84BC8FE1CD1E541B297AB59F1
-:10BA40001E9D5FF8BAA874AE4341208087B712727A
-:10BA5000E95E153307BA2C82FCF0A4328AFF32EE7D
-:10BA60002B47848F2940FBF4D012800BFA391469DC
-:10BA700072E219757E177E4F09D2464CDF4CBE9993
-:10BA8000E2F8F31DFAFDD5CD867DD28D2E7D7901AC
-:10BA90007B291ECFED0AB22C745F6214D60FD957E2
-:10BAA000FE23DD4978B991D52C733AAE1E4FB70805
-:10BAB0003CB5C6C3BFC65B2B3C897DB459D437E2C5
-:10BAC000CDEC78A01EDB9919EC8BF97C693F2DF742
-:10BAD000C597C32713FB6DB3185AE2D7DC859FCFF8
-:10BAE00086F44B789178BF5A7C4B3A19F12EF12BA2
-:10BAF000F166A4432AC6F8F50FE2BF8B39D78CEB69
-:10BB00006E88B0EBF3CD313CDFA55EF5D27AF473ED
-:10BB10003EFFCE6D46BB7E982386E2428DF71166CE
-:10BB20000E8C19A0C07C93CCCC67837D289EBD91E0
-:10BB3000DFF57EB37F690A8EC3FDBB5DCDDC7F0D73
-:10BB4000ABDB179E47F53D56C8173E328F79A07E76
-:10BB50006112732BBC3E8B8EA5F038A6C6F27B9B80
-:10BB6000D8AE309AF75BD889F997727A125DD0ED2A
-:10BB700083FE0DE8D7638AE5EDA3F2A8BDCFC4DB51
-:10BB80007BCC90764BE3710A4DCBB95FBEF0BEAE75
-:10BB9000E9283F460FD7FB99DFEAC9FDD232ED9B7A
-:10BBA000E1227CA9267702DD8F589649FB2335DCFC
-:10BBB0005BB61BFDF43B789C4EE18A3BC6F447F82C
-:10BBC00076C4B911BC3363770EE0F5A7DEFD07F844
-:10BBD000AE6D0DA3EF9333B4A53D311E40714DDF23
-:10BBE0000D1F664E3A644D8021B4DA71E7D14F38AB
-:10BBF000D6B7F37D3C9F1C3B51A5FA63198FF764C0
-:10BC0000CB601C281FE3FBD69C00FD8D814D079661
-:10BC100037863993EF04F80B857FF8215C2F086F86
-:10BC200038D35E72205C5DD353E1FB18D676BCF14D
-:10BC300051597FB8B20ECF99BA8DE0FE7B591FFBE8
-:10BC4000C17E3FEAC9FD514F8854E601AF547FF6EB
-:10BC50004A5B631AEE7F565A023D2175F41ABEBE46
-:10BC600027E06F742A1BB516F17EAFCA3612BC4DA1
-:10BC70008574AE1099E1423A68C0D274BE5293E224
-:10BC800042BF58E3B0DA009E27343E91E2AE76110F
-:10BC900095291E48EEB71A8705BAA31FBF29979F9B
-:10BCA0004B1C773644E27E7196C3CEEF498AB8A228
-:10BCB00039E25E4CB7EA8607AFC17DE8A32A9DD77B
-:10BCC000CC7994DFF7FA8BC3EE5770DFB646DCD73A
-:10BCD0005CA58F23624E37F98166D50CB3E27E7383
-:10BCE000B6C363C579FE31437B1DE725EF17F642E6
-:10BCF00022409785358514AFA246C1BAC3756276D6
-:10BD000045E13ED81887542EE28E64FEA170ED30D6
-:10BD1000F2C3CC68D70EE4972F2BD3C83FAA0ABE34
-:10BD20001B8D7195789E616E484478EEEEE922BED7
-:10BD30001C1DEB4C77103F8731C443A3C5998EFC83
-:10BD4000DDB83CCC84E772A39772BE867566374334
-:10BD5000FBFBCD2C1CCF197E27DA4F5B62F66E8081
-:10BD60007C173B3347C6225FE5125FDFD24B7B0275
-:10BD7000E777EAD76C20F2C3AC55ABE93C46F20555
-:10BD800033D7E7C7C138A736A7E4A1DC6C91D3BD90
-:10BD9000867F81ED5AF861A2427C00E98134E28716
-:10BDA000F10D38CFD1C303DD1766E17EB49479502D
-:10BDB000BF273037DA09CDAC89CE2B9B1D5617FA39
-:10BDC000BFA43C917203E8EAC17BB7920FB680BE74
-:10BDD000375B18DB5A65A7F4F92A2733F7606C7BC9
-:10BDE0005502E57754B928ADADCAA0EF2F55B92952
-:10BDF000BFAB6A20E5F7547928BFB7AA80D2D7AA8B
-:10BE0000BCF45DCA25C00BC9212957A43C9AE5B0F2
-:10BE1000D27D5F29978C7C331DD03B348FDA93DC45
-:10BE200093F20EE761CA0BCA2349DF54C5EB4B48B6
-:10BE30004139D63015E93F523DF7C22BB82F2F724A
-:10BE4000B8699FCEB8DC6B067E45BC245BD95EF436
-:10BE5000CB56DFE969BC2F2588FFDB8B14660EE12A
-:10BE6000AB3B2AC29839446FCCA88CD1E5A7557E4C
-:10BE7000FC4627E8FF9E0E5A7C06C071FC375FAF78
-:10BE8000FF237C7FE637677A20BD018ECD8FE3B834
-:10BE90008BC35BE088C5FC320B9D737513FE936EFC
-:10BEA000C27F82FF903EF27EF333BFF91BADF3C633
-:10BEB0004A9B0BEDE2CF915E80DF3F097ACDACB4B7
-:10BEC000111E0B977FF5C22BB8DE175B49DECD5CE8
-:10BED00026D6A3E15EF397898CFC126055B34AC065
-:10BEE000DF97BFB60622A0FF2F15BE8E15300EA617
-:10BEF00061FCE1CAB73E4339A0541EA1F3770DEFB0
-:10BF0000E1217C3ECB39DD3DE9CA37A91E6BE81241
-:10BF1000837E1379CF38A29FC7EA82F9236F23FD6E
-:10BF200066661C648978CE52A338D185385B7C9FC5
-:10BF3000BD92BFDB80713C13C1FE1B92A1123D2B51
-:10BF40007B9A29FD14F52DF9936B484F49BE9DBD91
-:10BF50000ADAE1FAA8C9B5CE0D91C733C5F7591968
-:10BF6000264AE5F731D82F9EFFADCC9D82764567F6
-:10BF70002CCFC2346F0AE2B7B363945909E1831B33
-:10BF800032CC020E46ED3EC54507E90319A9D63964
-:10BF90005974BF8FF4981C676646DE0A8C2F9DB9D2
-:10BFA0006A184A61566D7127C4433D6F4B3FDC7E72
-:10BFB00063761E475DDA8E1E917EB553F8E7B53481
-:10BFC0006FF2FB16EFF8FD8ED7A0E7E22F6C44DF8F
-:10BFD000E23E226E2BCB3F60023920F5FEECFCDF07
-:10BFE000FF398ACE2976F1F84E48B99F757111F75D
-:10BFF000CBBA617DB5715E7478C717516DFAB177B0
-:10C00000A957E4C72E577E8A423B42CE67E4BEEF73
-:10C010003B121CCA253A272ADFB7BC635B715E4618
-:10C020003F768BBF5BF8F5CA1717B4E9EF36FAEF26
-:10C03000966518CE0FCC8CEE8D49FF1D53B3A2F13F
-:10C040001CE07B719FA4BD7D8EF47F97AF854EE28F
-:10C0500060BD9A5DD178BE75A11DFBFA6806D7FF59
-:10C06000E785BFFCC27695F63D17B647D2BA5AB0FF
-:10C07000FD9137F1DC71C12685C02863F5843FC08E
-:10C080002BB387EA358C638B6B0D77B3BF4734EAEC
-:10C090009592DF475620BFCDAF553C9B019E66BBB6
-:10C0A0002BBA43083C5B91DF807F4A6CB50308DF05
-:10C0B00002FEA7514EF60FD69B5FF708F997A1DE57
-:10C0C000376417BD1881B10288F7F711CEB3EBFAC8
-:10C0D000BAF1BC707EEDCE0564576C8F70A25FE143
-:10C0E0008C885B96FDEC12FCBD2B83DB3167C5F9B8
-:10C0F000D1D91DFC5E3FC289EBEC8CC2FDD0B2DD14
-:10C100006B02CED732F8BEE48E0CBECE65FDF9B51B
-:10C110008D51DDA1FEC9BD1F537A58D49FEFA8CF22
-:10C12000417D7C7257049D7F9DDCF5D4A8D761BC0E
-:10C13000F3B5C3E2715DC8FE3FCAB050FDF3EBD466
-:10C1400002C417F3F3B89932C46FDF5038E336F8FE
-:10C150005242D71F8F1F3ABBEBE5285356909E657E
-:10C16000F60A7BA209D7D19D5EE4EF68641E80D7F2
-:10C17000BA6B9C0F7558795D2E43BEA6F59748F5AE
-:10C18000579A42EAD92C6E8A33B5EC2DF48837548D
-:10C19000F83D2711C73F52CDA273C5E97D5C936F6F
-:10C1A0004739F9AE85E8B130D33519E5D3C57A956D
-:10C1B000219C0B535800ED9345F7466E403D26E118
-:10C1C0009EDE97CB83D2950AF3C0FC4AFD2AD3208A
-:10C1D000ED0CF4F7213F2534F4C738C9C6146E5767
-:10C1E000C8F8D1278B4C1E2BE8C19F3262E5FB0FAC
-:10C1F0004FCCC1F3B3F119B49F3B6E653E15FD4AB8
-:10C200002FF1F8D2D2541ED7FCA488872F8D0DA40D
-:10C21000C7417FE7047D4BC707D231EEA2F4A544A6
-:10C220008ABB3867E5E79EF81DCF594BF3A0BD8365
-:10C23000DECDD064FB98107E2A9DE976613D35D62F
-:10C24000EDCA7520BCCE6FC8CEDD1DC9D0CE35BDC0
-:10C2500012C9E3A69E0BDB680BA19B3393F39F7C73
-:10C260008F83DDC6E38C1EB3F0B8D4C73627FAFD42
-:10C2700021F87ACCA24D453CE03CD0BE9F6FAD4941
-:10C2800047FB57C23B3FAA86E03C27F87D7E780DEE
-:10C290008FE716F77BB13EE61B451C7AD3361BC5EC
-:10C2A000019D49ACDF83E39FD996892FF200FCFE04
-:10C2B000B97BA91CEC4BA067F1F3B600CEE7F436CE
-:10C2C000EE8F3E6DE1F6DAE971092EA46FC1F8B583
-:10C2D000D3C95FB3C9A6A09FEFB4C2AC0958BEB919
-:10C2E00003C59F17575552FC7631880DBC3F046932
-:10C2F00001DE033ABD3993E2CD4EE33B0C0A7D5F8C
-:10C3000089DF355633FD97888FAD7C7F75E6F9BFA1
-:10C310006786C67BCBB478933EBE4EF2892CCFCDD8
-:10C32000E4F22D57E0B97F267F2FA42CA2F6B1545A
-:10C330009A27C73BD089BF5BC31A229FEA87F114B3
-:10C340003D1494234FB240FA53E877D8CAF75F6799
-:10C35000B65B286EBDF895480FC5B1DD778D89E2D3
-:10C3600029546EA7179B007D902ABFD94AF165F129
-:10C37000CF87E5D9C83E67B4CF6DDAAC8A71C026E5
-:10C38000C6796FE171C7A3D196A4F26C2A3F2DF252
-:10C39000A7F76493DD07FD7BF07E55F12F7FC5F194
-:10C3A00038A1E828B7BBEC246F4B5BCE790647A3D6
-:10C3B0001E2CBB6F5034DE3F641FA80CED16239E6D
-:10C3C0002E9ADD9D50CE2ECB147277CF7A3A9F2ACB
-:10C3D00011F7084A9E57F83934AC43BC9F59B262F2
-:10C3E000D0E3C49FEF5B580F98CFB9DA47A242E978
-:10C3F000B12093CBD396FA5637D52F81FAD84FC9AF
-:10C400008A77A3089E2D168A5731D2F18ADB3FAF77
-:10C410005E51FB16FEA8E57E9656F367F5BFF8025F
-:10C42000FAFF6E7B98DB475F6BE91EDC594BED5CD6
-:10C430009CFFD917C2486E9D8DE1F2E124C8535F7D
-:10C440004F84E3E68729BEEBA309747F6F9E5FDF0D
-:10C45000AF1C77512697E36571EE688C172CFB8033
-:10C46000CB41A0CB2DD4FE030BB537CE63BC68D730
-:10C47000B23E5F88207E38DB99D3E5EC8E9EA49F88
-:10C480001A63389F03BCC978DFEFEC0B3D73E91EDC
-:10C490001D1A3DC00FC562FF7B36A636D91952DE84
-:10C4A0006811FBB800D444BEC13620DF8B2BB9BD68
-:10C4B00055625F45F12518AF3B208FD2802DB675B0
-:10C4C000DC2DF02BED2FDFC9147E4C1CAFA388139D
-:10C4D000273BA8D68A725B13F662E97663DC2E2FBF
-:10C4E000DF26DB03B4F1324E18F9D0A7509C4AC9BD
-:10C4F000B23BE753FC7DC5EADB719D49F84BCCAC00
-:10C5000000F7698D8A4A703486B119E3D1AE0C1DEB
-:10C5100027C49EDB151C87E1FB5FA5F807ACD9BDDE
-:10C52000992EFA8EF91AE8AF7499B28AC64991FB2E
-:10C530005D3E2F8927408715E3041B8789F276E645
-:10C540002DE134CEBBC5EECAE4FEA5C614D7C38325
-:10C5500091CEEFA9749FF7E24F7DA363DBB0D38246
-:10C560007ADE1A8C9705F88F6532EA677D26B7D395
-:10C570004B301E17E04C5FA78F17CFD8A4CFF7DA48
-:10C58000AECF67EDD2E773EAF479F7617DFE8018EC
-:10C5900017F7E1787F18F7E198E23EDC65E3FB707E
-:10C5A000CCE33E1C53DC87E377DC87631EF7E1981E
-:10C5B000C77D38E625BE713F8E79DC8F6379782F91
-:10C5C0008EA752116F8974407E67AF86E9EE235DB6
-:10C5D000D8C7EF97001FF07533D54AEBE649AC4159
-:10C5E000FB11EE77EA3CC1EEC2F8E15571DA7799BA
-:10C5F000FDF11E4AFD8A44A49BB981E258CB5FE35A
-:10C6000071ACA579610EF47F342C3FB902C343B5F8
-:10C6100038ED47AC7FC1D2B405F15B567988EEDFC7
-:10C62000372C717D703DA71FF96158512CD9518568
-:10C63000A8E762DBA7A3319E9CADD2C78F1BE3C9DD
-:10C640008D71E4463E90F6DF3396A64494EB5F6D21
-:10C65000B3AF42F8BF0A13F761A6D80DF1000E92EE
-:10C66000270B1F5436A2BEEEDC8BDB51CD47C05EDC
-:10C670006F43CFCA74D6A5BE6497B7E45729268AFC
-:10C680004FD73CA4871609989295A6C6FB50CECDED
-:10C690003791DEBC08F61AD9839FA8643FE03B5966
-:10C6A000A1F3C177B242F90BDFC9D2DF97E8ACAB97
-:10C6B0008FEF64E9EF4BF4D2C7E74F5C7200F7FDF0
-:10C6C0001356F5D5D59BED1D64C0A3805BD8B3B3DD
-:10C6D000417F78D0BE5CBC3619E9BB687E73E37DD0
-:10C6E00040DF45BBC3DC585E84FF0772B108FAC463
-:10C6F0007B9745BBC4FDE54ABD1E9E25F45091992C
-:10C70000F99CB1413E2C72324F0CB49FDFAB3E0717
-:10C71000DFC39AFFF6C7039CA9B8CF18D609E55125
-:10C72000B2C54371B5A53B7BC42C817E7BF7D06E2F
-:10C73000EC05EBFA44CDA187A6A13EDCC9F77F5FEB
-:10C74000AD7A398AE2CB04BF255B9CE148F70D3511
-:10C750003CBE0EFD676A6C902F36D4C48577770493
-:10C76000E71BE4839F884E401FEEE7293A48E72203
-:10C77000CDB562BEC3141FDAD9727EF21D2DB68C00
-:10C78000F77397C89F10FB0D39CF739907725C78C8
-:10C79000AFA36A6FB28AF2DCB47D0BEE43FE69D3BD
-:10C7A00066F7EA8FF1A03DFE88EFAA15FF81CFE77B
-:10C7B0002F6B46445D8BF6E70B16F768C8DF57F31F
-:10C7C000AC15F715C566BF95E233B76DB062BCF224
-:10C7D0000D5B37D0F7B95B0B291E731EABA0FDE8CC
-:10C7E00029F9EE81C047D170659D13E07E47C88F5F
-:10C7F000A2707EBE07F6D11BF8EEC8C5AD4A2EC6A4
-:10C80000F94CF4EEB416C2F75F8B7AC675D27C741D
-:10C81000C2C80E840F7E0FE40F0C76F769ADD7C542
-:10C82000844B29B42E265EEA4DFBB449814CBE1FD1
-:10C83000CE32EC878FAADC9F57C7D7419135103F86
-:10C8400001D7C97E0BD9B96566FE6E5319FC7D1DF3
-:10C85000A4DEC1AA8E5FCBF32374FC3C85C5EAEE4F
-:10C86000D3DC8A412521F989A3D374F5274FEC6DD8
-:10C87000E0FFBC6039C991EB74F7FECA16FB5CF4AB
-:10C88000BE211BAEFFCE787C21BD086A0FFD3E3E67
-:10C89000580FF97B93C2F73DBB6236A21FB0C8C4E4
-:10C8A000F74F5334FE7DC15EFE9D4D61BA75D82DA4
-:10C8B000CDFD47AE172D746E20FDED53F0EF36F031
-:10C8C0000F9AA2E51E3BDEE347FF84EE7EB7382FCA
-:10C8D00044B8910E65C29F5496C1FD4965BE7A2B3E
-:10C8E000BE9300F837C7C5523D7B1CC655D628E419
-:10C8F0006FC47431C559EAE3B4B03F8C7F5C7044B7
-:10C900002DC475622C2FC2778790BEAFF1B8D405C5
-:10C91000E8178A6AFDDED902F413A17FCBF0BE9935
-:10C92000A3B74BF811FD2B3A231E472BB9746F7335
-:10C93000FB012BC6E74D9C18938BEBC7C86752BE13
-:10C94000C3BAA6B8C2E6A38788CF9A8BCCC4C797D0
-:10C95000C3C7020FF7B31AF96F2EABB7E2FD94B954
-:10C96000BB1437EE4BB11EE2A533F2A5012F71B116
-:10C97000ADF121F1D4823743F93CC6F1356FAFE216
-:10C9800047F9D80A4F027F46F8DBC39F9CD75C4D1E
-:10C990001B857242CE6F1ECE03C78179E038F2DC70
-:10C9A000820D34AED734F25F2DF0F2385B237F8CEA
-:10C9B000BFC4FD32B75E32533A71B47E7D623B5CD8
-:10C9C00027932E75A4F2ABE59F050027EA85ABE51A
-:10C9D0001B391F298F83EB84DF4BB8DCBB4546FF37
-:10C9E00064426FE19FECCFFAEBE29B85BC35B63732
-:10C9F000C6374BFBC0A8770A234D146FD9EC4825E6
-:10CA0000BB43CA5F4DE8156DF9F7544F837A1C1A82
-:10CA10008F4E0F69C24FB8303295DE91485E12D703
-:10CA200011E95518E6A4B8FEC2252AC55117423DA2
-:10CA30005788DDB262595A32EA912FEFEFF9B40FFD
-:10CA4000ECF92FEF8DEF3810C6F96AB925DEEE0A42
-:10CA5000D6FB72F9C8648CEFF86AB56D8ABF0D7C9D
-:10CA60000DEFCDFD0A65BFF98CF4DC79D3D1A8298F
-:10CA7000D0BE74F9EE28BC3E50B29CEBF7F7BA6B0F
-:10CA8000C37AD3B9EF862DF49EB173430EFA89BDF4
-:10CA90001CA72D7645F1F2919DD0EE28FDE7A1A7C8
-:10CAA0009D782F7C89A523DAA5A73F013DA9909EFB
-:10CAB000237BE254187441E77091F49ED92985795B
-:10CAC000F03CEA9CE9C05FEFC3FD626E6D7A40C145
-:10CAD000C353CDDB1BF7F7CB9F257BA6F88125E958
-:10CAE000F8AEA0B6A447745BFE14996E11FA1CED63
-:10CAF0007A4CD1AEC7F81AB4EB318F763DA668D721
-:10CB0000E3F7F2B57ABB706A4F2EB7A4DFB95B7555
-:10CB1000532E9EFBF986B38C0AD2C30E7A07789106
-:10CB200012EE46F9B4086D28CCFF3982FC0EEC9366
-:10CB30001B757496EF04CB7780873481AD16B24EA7
-:10CB4000AEBF6467A1F77487B1185D7E843D51570D
-:10CB50007FA43345577E4342A6AEFC4657AE2E7F98
-:10CB600073C6B5BAFA63DCC374F95B06DEA8AB3FE3
-:10CB7000CE334E979F503055577F92B750573E79DE
-:10CB8000CA7C5DF954ED4E5DFEF6A27B75F5EFA80B
-:10CB900058A22B97EF22D7E17ECC86EFBFD82995FC
-:10CBA000EF23DFA3327A5F6DF00813F733DAB83E74
-:10CBB0005AF45E0F47281F3C29F8F95296E751E4D2
-:10CBC00057F9BEA57CB7722BEAA3FE788E1950F8F0
-:10CBD0007EB83E11F9D858CF583E38E2E04517D01C
-:10CBE0003266FBA94966901783AF39D8370DF253E7
-:10CBF000B7E7DC4AF941075F4E857C61D6DDB79A1D
-:10CC0000415E0DEE73F022969FDDDE97974F6064D4
-:10CC10009A94657D3209E365075F9FBACACDFD2806
-:10CC20006DDE779729E203EF89233E300D001F6305
-:10CC30007A10F818D3C3C0C7B32D8CBD097C8CE91A
-:10CC400011D89FE2F777607F8AE951D89F62FA3E58
-:10CC5000EC4B31AD877D29A61F554DA1F4932A8D4C
-:10CC6000DA7D5A5544E9675515F4FDF3AA4A4AFF9F
-:10CC700054E5A3EF877B4BFF4340F77E687BEF844F
-:10CC8000CA734E79AE595DC11A22506E349863BE94
-:10CC9000B607CF2BDBF71398D9D721F65AB6E2F9AE
-:10CCA000A0378DDFC54971E2E2FB1D29DA2748E78D
-:10CCB0003FA44CE8D157453D56F10686DAFCC1D475
-:10CCC000F67B905B7B733BF9DD2CCF31EC6F889D5D
-:10CCD000DF4F1E62E7F78F8798EBAB91BFAA7F64A7
-:10CCE0002E8CFF3910C9DFFDA8BEDFEC473FA872CC
-:10CCF00089AFF3A1F18CF2D53F36D07DE5214E7797
-:10CD000002EA2B996F39F7C77F21713EF21C5EC68C
-:10CD1000F7E45FAA1F81F6C25087D5857224346E6E
-:10CD200000CFDB0F447E2DE161389E3CDFDFF42332
-:10CD30000B987282E7F843ECF529E837187A97DD0B
-:10CD40001D1AB724CFEB954B0D2AFA55657C921C22
-:10CD500047C21B6986FEF282F147439CB5B978DE73
-:10CD6000515DE6A0FE3AC1776B1ED5F3A8D4AE366E
-:10CD700017FD72434B1D14072BE3043A8979433D99
-:10CD80009A67FE258DE224868A3809ECC7CECB7DD2
-:10CD9000D8CFD0F84022C6810DADE0EF90AD57F866
-:10CDA000FBF3326E01EB4784AC5B8413FBEDFE3783
-:10CDB0008017ED288F87F03B41EEEB5C222FCF1DD3
-:10CDC000EDC3C9BF3542C89A8F53B4CE59786FC5E9
-:10CDD000E6FC7304ADEFB4AEE8371D27ECFA7FC173
-:10CDE0002FDDB0DD7F9F5F3C9CDEF8807F4A6BBE0D
-:10CDF000917491746E8F8F24DD43E2CC88CE2D71B7
-:10CE000063A21F237FB5C757929F86D839DD91AEA5
-:10CE100018A726F948B9C4DF751B5A6A277D27F978
-:10CE2000C8C807ADF988F365F5DD76EAAF351F05AB
-:10CE3000E98FF8F8F7F9A841C5F3ABABE59F194DB9
-:10CE40006C5434143D94AA6D45395278C9F526E6E0
-:10CE500067B161A390A564F9E358DEBF75B9F65DCB
-:10CE600093253A84CF86083EDBDF4E7FB29E7CF767
-:10CE700042F67FBC9DFAEF0ABBE1DD3019A7E271F3
-:10CE8000E40E08C68D2E1AC9F9AB204525BB6344B4
-:10CE9000167FCF9C39B89DED82FF501EDFC4B4C30E
-:10CEA000D129F8EEA897DE1B1D156F786F54D8E7CF
-:10CEB000058673FE9BB26E20FBFCA6CBBC5BBD2C33
-:10CEC0004BDCDF49612957F9AEE86FB3687F78A57D
-:10CED000EF8AF2F768F3C57A4F12FC94E652D9E074
-:10CEE000587C9F5D33A372398CEFD1E6E0BBAD3E39
-:10CEF000CADFC8FC94DECC0264478C014584F95B30
-:10CF000018A37BFB8722C64EC33B8723FA8EE88E8D
-:10CF1000DF43DED9F3237C0B54EDFF3843DED93BEE
-:10CF200098EFA2FBAB07ED696487E27AB584F84B12
-:10CF3000DF06FDDC1DE67708F437A66F80FEEE0EF7
-:10CF40007AF42DD0DF98BF296309C376A35CFAB8C1
-:10CF500027D9FE66E708D8A8B58FBF9B735EED8220
-:10CF6000F87D37A6673EF2C5BB31D7E4E37CDF8DA1
-:10CF7000E964E2A9CD4A69F62BDDDBB293E57A08D4
-:10CF80008E378AC633E257E2D3884789DF7F039F13
-:10CF9000EFB485CFADB88FC0FB21F68FA31252F14D
-:10CFA0007C93CBD9B28864F1BEE87B396A2AC6FB90
-:10CFB0000E223887565ECBCC78DE6EE7783A59C5BC
-:10CFC0007C88DFD3380574781BFC7BCC3CDC141ADE
-:10CFD00007FD8A4DFB13C271729D4AF7F5CFBF144E
-:10CFE000467EBB537EEE975C68D21AB3D06FAFBA61
-:10CFF00056B9D1DE7C57253F30FBE950F2F8C8AB7B
-:10D00000E0D74DFC9D8352FBA836E929F797CFA5C1
-:10D010007A68FD33C3EF4B74B1F1F720E4BB94970A
-:10D02000FBDD962E362EAF257DD759851D00FD0CD4
-:10D0300000399BF47038EDB7F674F4FC88F3837D07
-:10D040000CBD3FD5DC2592F4D34111173734D09B6A
-:10D05000DE5B2B10BF23F096789FFDA08897FB7BAB
-:10D06000BA66CE0678DF721DEC82FE87EB193F07A9
-:10D07000BAD1C1DFC3BFDAFDB9235BECCF7358CEA1
-:10D0800055FDEE410795EE530C65E9740E3F02E144
-:10D090004539F7F62C33EAC990DF3DA079FD6FFBE7
-:10D0A000DD03C69A549C579253614FA65CFDEF2056
-:10D0B000A8625F257F0FA18017B5FA1D84A7A20A79
-:10D0C000785CBE636E9BBF839024DEA9662EAE376C
-:10D0D000E4EF208C4CD0EB9111CE61879D94EAFD5A
-:10D0E0003C4997891F1B9D2DF4C7D5D2BF8C11FDDC
-:10D0F0005BE24CE379FCD350ADD7C3E89F1F116FBF
-:10D1000071FB5DADF9E03FED774EDAA393F1F74F98
-:10D110008C7432FE1E4A925A6AA67720059DA6C0DC
-:10D120007F48A7EBC5EF55E4E3EF55B0FF7774AB4D
-:10D1300036D0ED7BB6AA3FBE5B7AA190CBF5F6F474
-:10D14000FE0D299EFBB341FE3C2AFC47D23F22E361
-:10D15000728DBF9724FD00325ED7379CD3DB773CBE
-:10D1600082CEAFEE511B2251CF1C37F1DF471AD8C8
-:10D17000417B1CE5D38CAC0A05F191C0BC3BE702B6
-:10D18000FCD3FFCB968CF9E9DDF87B912C8BFFFE6D
-:10D190008F846F7A128FE77A265BE17E3F378FDFCD
-:10D1A000DA98CDF701916E27C599176631113FCBFB
-:10D1B00092A767237F1E0DEB89FCB786FB031BF04C
-:10D1C000BDCAF8E07B9568A7A35DDC55D8A5D5C797
-:10D1D000EC76CE874CA7FF33FD765D9C73EFAD4EAA
-:10D1E0005D3EBB364157BFCF5E97AE3C3790A12B1B
-:10D1F000EF7BC4ADCBF7AF1FA8AB7FCD671E5DFE45
-:10D20000DA86025DFD41A7BCBA7C126B7A02F17B23
-:10D210002C3B95DF9F50849FC4C5E931FD9E8E74E1
-:10D220005F49EE3F64DCBB26F8D9B8AFE966E57626
-:10D230007D7522E3FB56BBD89F32FDFE461371EB92
-:10D24000D2AE673E7DDCBA8C576FD907897D8EDC04
-:10D250004F84C4AB7B107E19AFDE4277F17EA8917C
-:10D260005FBF167437CEA39B95DFAFABBED74AF72F
-:10D2700084247C46B8D40CCEDF9BED6DBF07F55DF2
-:10D2800036B713F2BB7BCF21BF3E0DE28AF0D96ADD
-:10D290003C7703FE9E40F5AFADEEA5AECB8F37BD1C
-:10D2A0000F9FCF347C37378BDE5FA57B81725C7339
-:10D2B0000E1FF75C1FC1E786F1A647F3F838166D1D
-:10D2C000A57B2DED8FC7F19A6065CBE8DD2A71CF84
-:10D2D000E38E55B50FA20B759AB5C6C21F1EF05B43
-:10D2E000D08F367A38D889B9E85F7DF85107D86988
-:10D2F0004F579AC92F1691639FECEB1EBCB7D30D05
-:10D30000F669C827A391FED0EF923E3C3E3D0B6DDF
-:10D310009F0EE47F6FB96F61D3C97F46F2BF0DBE28
-:10D32000237E94F3F89FBA7F21F9D78827B92F6716
-:10D3300042AF75177049FCC97521F127EFBFB8EEF0
-:10D34000B478373AE81E4D01C6E549FAADE9C3FDA8
-:10D350009CD3053EB01ECAA3F6EA8D54B3A2F1BC1D
-:10D36000A099B9A29D97F19BFF0FDD4B21FCB777E8
-:10D370009FAE3D39D14A3EB473BFAE3DFEA47F5748
-:10D3800071CF2E444EF07829410F7F7713C525DCED
-:10D3900017A95FC70FE570FCE689F504FADB91ABCE
-:10D3A00097130CCF3FAA97AB424ECC6DF9FD10FC02
-:10D3B0003E67B985EC6EC6BC8F619CC65FD658E8E7
-:10D3C0009DC7A11E46F6CDCC758A7F8312FCDDAECB
-:10D3D000429FE19D16F527B20FBF5FA538F1F71FF9
-:10D3E00066ADD497CF73F0DF1D99637CAF469EC7BF
-:10D3F0005D665F5F9523F4BB9BB9C92E137114451D
-:10D40000A28ED12E6BF6F3F346DC97ABDC8F45F1A1
-:10D410007752EFBBF0BC2BE41D16C06B7806EAF127
-:10D4200065E636E3225BF0DA4EDCC7398788FB70AD
-:10D43000F03897E65D61FC7C589EC389FAE77C175B
-:10D44000A91CEB636FE77379FC8A3C7F339EEF3551
-:10D450003B4C743ED5BC2B92E21CF0DC2B1AF8E15D
-:10D460008C6967C7812941F8B40655776E644CB55D
-:10D4700025BB693FF95E776D5B0EC6E99BDD7637AC
-:10D48000E4EF771CA477BC460B3F9811DE96DFF1E2
-:10D490001BCCDFD569F6717BB7B980BF7702F291FB
-:10D4A000E17A92F11CE3185877901606AE2578AE13
-:10D4B000F6FC6BC2A55C7EFE7B6910B5D7565E4B51
-:10D4C000F96ECB1EBC13EF194DAA9E67C150808622
-:10D4D00027168F0C87A60D5DFD4BC3916EC3943646
-:10D4E000CF2FDEC9E17AA5C1706F41A6D7F5E17AE9
-:10D4F0007532C6E6F40F89E75AA2D07A58A83019D7
-:10D50000DF45F25CE62FD688FC489E5FB49CE71BA3
-:10D51000C4EF2A6C11FE169C37A6386FF40B6C17FB
-:10D52000FE189C37A6386FFC8EF20BF328BF308FA5
-:10D53000F20BF328BF3045F985DF67326F72AECA50
-:10D54000CFEDF243D6079EDBE587D847786E179A72
-:10D55000C773BBD0FA786E175A8EE776A1E5786E5E
-:10D56000179AC773BBD0FA786E179A67036F0CE6E9
-:10D5700051DE79C6E9F213C0FECF0F59DF786E177E
-:10D58000DA3F9EDBE9FAD3EED4B5BF9D55EADAE384
-:10D59000B95D68FD19958AEE5C6F86788776D6DA74
-:10D5A00038E29F7D295E5B1FA0EFFF89F8E7DD165B
-:10D5B000DC2FAA75F3F9BE2DDCCDE95C53C0E96E12
-:10D5C000E2F72C94A6A944E7C5569E1FC9E3BC8D7B
-:10D5D000FC83E762F9167E2E86299E8B618AE762BC
-:10D5E00098E2B9587E0F7E2E86299E8BE1773C17F4
-:10D5F000C314CFC530C573314CF15C0C533C17C319
-:10D6000014CFC5B01D9E8B618AE762F81DCFC5306F
-:10D61000C57331FC7E1CCFE72C41B8D09EEFAEDB4A
-:10D6200057021FEAF6954E5D1EEDF9D0FA68CF87D6
-:10D6300096A33D1F5A8EF67C681EEDF9D0FA68CF8E
-:10D6400087E647E5B8687DA15D1FDA0EEDFAD07C6C
-:10D65000768DEF0DF49D8D59F7CD614C1B2295A76A
-:10D66000151019057DFC93F1FCB2214C498E01C9BE
-:10D670006959B279723EE435114799C39A4CF4FB6B
-:10D680007BB879C4388700A3B8D5EC1F13A97CAA4E
-:10D69000BC7F87FF80EEB9BB18FD1E8D3C5F97ED08
-:10D6A000DDCCA9622AEB07F36DD7338E2FEB91FC0B
-:10D6B0000C81036F5A63BC4FEE62471EC6CD6E11DC
-:10D6C000BF8FBB65298FB736F2D562612F6D31ED03
-:10D6D0003C88F7699A0A15BA779D6E66472C798857
-:10D6E000A78A3CB42366F789117AA9E23AFC1D3176
-:10D6F00009B7F483829CA0FB89839BEA4744433F9C
-:10D700009A6F18FD3ECE682BB71FB01DEE2B7BFB2A
-:10D7100014CFC610FE5E20EC71CDC7C77FEE99B165
-:10D72000BC5D386FF7DC335184C7B1CB148A3B1B27
-:10D73000BC9D79F01EF43D429EF6DE1E5071BCC2C7
-:10D74000657C3CD96FE1BA64BA175AC81AF2F15E27
-:10D750000BEBA73094DB126F30BFC338BF74582A6D
-:10D76000E8C7BED2FB5443FAC58CC4784456C7E818
-:10D770005DD131FD3ED4CD97C83E80FA25BDD6D3CC
-:10D78000A7D03BCE637D4B96225B8CF1DDF946073B
-:10D79000ACBF89B9535CA48AE8FEB184A79767A798
-:10D7A00009D422CB62F5A63005E9CD0EC585F00F70
-:10D7B000ACFC8948EF5CB785DE551E67765AE89D5C
-:10D7C0008E76E2752E3A64BC8EC15E30C4E5542F6D
-:10D7D000FE2C19FDCD0B234DE43759B83B82EC06E6
-:10D7E0006DAD42724DDA418522DEEFE2B2373A4C3E
-:10D7F00046BCEFB4507F325EA72CCD9F6CC2FB09B4
-:10D800009D37E4C4AA64073C8FF2F0ACEFE55B07F8
-:10D8100062BDE5FC5DD18BCB76F3DF1915E73BF2FA
-:10D82000774B678BF8AFC26C6F34C6C3C8DF4793C2
-:10D83000F764E4EF924A3F4FE17B7DDF44FA16AE96
-:10D8400017EF7EAF2CA4FBEFC6B8AB1261FFCD5F24
-:10D8500066A1B8ADF906FBB044C4655DEEF74A0FAA
-:10D86000F531D887F27772441DA676F914FDC2F21D
-:10D87000DEE7340B9703D376323AAF9AB664840965
-:10D88000DFAB66BB39FF4C5BC2ED9C69AF7AE8FE4B
-:10D89000A6B41B3F10F6CCF84B4984FF8F85FD32B0
-:10D8A00009E35501CFA31BC2441C5B22A5932FF1B2
-:10D8B000F8D5F10E2E0F1AF6F177379A7D366E579E
-:10D8C0001D66FCDD38037F8E33FB4D78A1D13D18FA
-:10D8D000F813F263D01E82FEA6A07D1487FC9E3250
-:10D8E00092E2210B14BA4764E4F7D1968A3730DE0E
-:10D8F00076F466E6F6B1507E073EC6FE7C0ABDC7EA
-:10D90000A0897DAEE46323DF4F8F10FE2907F73F28
-:10D91000B5F829D056C547D47D7F9B8CF1C4D3D1AF
-:10D9200067D899A6E1C1B8BDC82C5EFE8F17FF3637
-:10D9300079196E7ADAF15BA8BFB4123E34F9EE447D
-:10D940003B7E04F41FA0BCBCE3AE5CEBCC1079F9C9
-:10D950007F018165E5A90080000000001F8B0800A1
-:10D9600000000000000BED7D0B7854D5B5F03E7340
-:10D9700066269364122621901048980422A906383E
-:10D980007941401E87C82358B40349143009C33B6A
-:10D99000A878236A0DBDB499908001C11B340AA2F6
-:10D9A000E880CAA5966AB4DE0A4ABD838855EB03AF
-:10D9B0008354EF6F1B86A7A0B546B8D6F67E5EFDF2
-:10D9C000D75A7BEFCC9C9399006AFFFF7EF76BF8E8
-:10D9D00074679FB39F6BAFF75AFBE4ADFCD28CFC2E
-:10D9E0007E0C7F2CAC3F630B5CF43B9BA2E6A50650
-:10D9F000F3185BB12E27953919FB067F26F62C17F5
-:10DA0000FEF54AE6EECB584D9FE01D8AC6D8208D24
-:10DA1000E993D3189B83838CA5A1022C97B1B9A25B
-:10DA20003E5D1BF2410B8C5713CFEB69ED8ED93E57
-:10DA3000A82F7704A7AAF0E89FF2EACA065818EBC5
-:10DA4000A3BA198375C5D8BCFAC02CC66C7BF20387
-:10DA500003E1919AEBA2E7CC1A1CE04960AC7A434F
-:10DA6000FBC6616E1C17FE57CC5895BDD5C67020FD
-:10DA7000E6B77986C3FAF298EE77627BF8AF88B1A1
-:10DA8000E3EB9E7F6ABD125AFF711B9BDD1E617F17
-:10DA900093340BCDB3B38131F730C6763538A87CDB
-:10DAA000B2C1C5DC318CED6E48A3FA530D6E2ADB92
-:10DAB0001B72E9F9B30D1AD59F6B28A1FAAF1B743D
-:10DAC000AAEF6928A3F285060F3DDF3FD05BA0C116
-:10DAD0007A1FB0E8C7EE82FDA5ABAD8C0D8135B6DF
-:10DAE0006E66780E8B700B6E829FEE18C598971F2E
-:10DAF0000B1B6CD7ED2C85B1A6758A6B35F4F33A08
-:10DB0000EDC79444285B9440CC0868E09BA207735F
-:10DB100079DB6FB2115E1C8E2CB7EBC127A05F4D75
-:10DB2000839DAD87478F5EC6741CE7D19FD8FDBE2D
-:10DB30002C84DBA1838EAC101C3FACBFD7061881B0
-:10DB4000C797E3867673EB62B5F5F0FEAD7C4F19AF
-:10DB5000AE3B3E4FB37B016E19F98CC6BFAE9FE75B
-:10DB6000871A94CB37EC7FE47D3CC77D59762FE054
-:10DB7000CFFC3DF96BD3DCD8CFEBC17EF39D2EBB40
-:10DB800007FADDD29C6477231EA4B2BAF63C9CA7A8
-:10DB90002B73564208FEB59A42EBC82AE0E37F8613
-:10DBA000E744ED5A6D330DED2CD40EE0A63BFA8719
-:10DBB000E09461653E4B01C2CBCB7484D700A621B3
-:10DBC000BC06C2F39802FE3E3639043F33DCEC005B
-:10DBD000770BBC1F08A5BD2004C70C78AFC2735BD0
-:10DBE000EEF1392C1BE1C6E67922E0CF83B87E84C2
-:10DBF000FB6C07D1D562073F4FA0ABA9A980872B4B
-:10DC000036292E4003B6C8E9BE7E0CD417BD666324
-:10DC1000ABA13E23D96D1F00F52E38DF1D505F707C
-:10DC20007BBEDD0DFBAEC2B380752CDA3286E86DAB
-:10DC3000911FCAC2E87479C3A603197B117F02BA87
-:10DC40001DE964914BB727E785D16DAB427461AE96
-:10DC5000AFD3545A77156393117ED5B767D9173868
-:10DC6000B1FE9A6D451EEE8BC341F68376016C378B
-:10DC7000239BBD8AF4D505FBDA91C5E72B081B7FF2
-:10DC8000018E1F363FB49FE781FA7D5A028D37DF40
-:10DC900005FBCEC2D245EB0438109CBA36C2786E72
-:10DCA0009A87CE6361C06FD3703D569817EA735D53
-:10DCB0007E1BCEB3A039DF8E7CCABB81CFE36D491A
-:10DCC000B20F87FA7CABCB9E81F08B0358A4D0FABD
-:10DCD000FC3BE06816015C929D380F9B37CBD91353
-:10DCE0003EF3C57A17B526D9171B9E6FB2E17900AE
-:10DCF0007FD323F18D83E2DC17344FB233EC6FD541
-:10DD0000ED1AAE47C0F7D4ADB1EB591FE8DFB6D975
-:10DD10009605F57F13F87B50C07546762047C17D88
-:10DD2000DF1AABE13AE7B85A697FDDF0BD1FE001C9
-:10DD3000CF17BB3C045FC00B1F03382C6A339E67B0
-:10DD4000683D1CBE8BDAE613BD2DB17AEDAEF075E1
-:10DD50006CD99FA3005CE6007D2B007FE6F2662273
-:10DD6000BE9CBEFFFA4CDA27AC13E19AA0B9A7A675
-:10DD700015119E101E4B7CA929E4F42BE7FBA3662A
-:10DD8000A5F9FE28F86774BAD45F4D43BA84F35DF1
-:10DD9000ED8E4E977664DC30AF7D91E26F527AD291
-:10DDA000A9A44F4997924E25FD3E62F304D29410E8
-:10DDB0009FA9E9C3EA9E8D00A78C7C7E0E73C5B92E
-:10DDC000025C5F41B8CAF7F67CCE8FAAB28DF48EA2
-:10DDD000E3E1B8E704BFAA2A0DE4DC9A176A2FE74B
-:10DDE000AD4AE6FD10EF11DFCE8973C7F62BA8BD53
-:10DDF000E063825F2CECE617BBD7F4477EF18CA280
-:10DE000021BF58B1F140C69D00B715BF8CD7100691
-:10DE10009FDCFCC42D03B251BEF9E9DCE4BA16FF65
-:10DE2000359FF8C412219F170522F38BEB73BD6A4F
-:10DE30007E71A8BEE8BE5F5EE6E5FC2680FCE60FCC
-:10DE4000BF7CF1C85877489ECAFD2C6879D736DF69
-:10DE5000190E3FBEDFF5B9E7E6E3792D74DADD2A66
-:10DE60003C5AD83C9FF82F4B635A8E123A7F335E50
-:10DE7000CC6F5674EA573FCAAF7E8F7C7AE18699A1
-:10DE80000CE5943C379898B15121F92AD77F593E37
-:10DE9000A7DB1FE4F3FE73057ECFAD9D641F908268
-:10DEA000FB9D5F886AC51CF17CCE22E3F3EE7373A1
-:10DEB00075F3F9B5482FE7DAF9B99DDB6023FE73F6
-:10DEC0006E77829FC1FE3E59F1FCDBD741BB8F1FAD
-:10DED000D89E89FA4AF8B9B1427E6E582E8573638E
-:10DEE0007D239EDBD8F0735BFA283FB7854FBDF5E5
-:10DEF000C717DCB45FCEEF36C6F8911F2F687F8658
-:10DF0000CE714ECB265B16B4BB3A3F8BCEAB9BFF9C
-:10DF1000D7E5BB18C0776ECB761BF289AB251C4CBE
-:10DF2000F400A5CEC2E80CE592921CD2C7647BE453
-:10DF30008FCFC03CB7DF1A9BC84686E6B92D9FF34A
-:10DF400085857549C938DFC2BAF9F7B01121796002
-:10DF5000DEE789584E2F0B603CA4DB1393B4CC153D
-:10DF6000849F968872F74681870F01B863011F0668
-:10DF7000C6B7FF1CE130F09FE234E41F438706FD83
-:10DF8000382FE237AEDB0EFCD301ED86DE1CFC1C25
-:10DF9000D73114300CFB6199904C25EB0FF51DB077
-:10DFA000EC1228B3555EB6E6733D09DE07F03D4B33
-:10DFB0000916E3FE257E9BF1D7CE1E6FC9463E961D
-:10DFC000C2B42677085FE538125F253E47DB5FCB9A
-:10DFD00045EEEF441687A73D0EF6977C09FB0364D8
-:10DFE0002D490EED4BAE0F7478DD82FAE33F0FDF63
-:10DFF0008EFAF389462DB3CED9DB7EDBA6F48FB043
-:10E000005FF33E25DD2C72709A06BAE98376C7B9B4
-:10E01000D6217D50EE9C5040BE41BF13B7C65A700A
-:10E02000FD725FA897B318AE9763897A391BC6F55E
-:10E0300072ACA35E8E25EAE5F43C3F99CB23164CE7
-:10E04000403D13F401CE0F029C4E3AEB87D0BEE464
-:10E0500073A91774BA8209C961FCFB649D909B2C5B
-:10E06000B811E99BD50F614FC0549DAD27122C7993
-:10E07000889F7C7DB2DFEDB62EE2872CC1EE7E025A
-:10E08000482EFEF677A7A4C27C8BDBB2F215E857C8
-:10E090005D5FD8590FEFAB9B5335E41B8B9DEEB5FD
-:10E0A000281717FBB234948BF16DF9A7B7C0FBC5E5
-:10E0B000CD5768D8FE76857990BEA49DB08475FF53
-:10E0C000909DB054F0B5A5C82F015E4BEA0F0C75BA
-:10E0D00041FF255A6C3ECAF7A55BB89D30C3C25AB2
-:10E0E0001494C34D9EA9C8C7BA1E5434D437D9C39B
-:10E0F000C05F1D21FEFA7EAEE7B7C867D857807FA4
-:10E1000030FEE5288355DC57BB8EFB60A08F3CC1F9
-:10E1100070DD1ED2EBA70ABED1D9762CC19DC7E116
-:10E120008DFA3AF3EA16E4BB2B845C1B6CEF3A766B
-:10E1300017EA3309166D07E797EFB8719FAFAB2C5D
-:10E1400086E48D682FF8E9E09F953890BFAD48C808
-:10E150004E25BD6A8B4AFC51E24FAD58F3E2EDE526
-:10E16000FD116F16C37B94775BF121B0D0B56D576D
-:10E17000F547BC5AB469CA033E906399028E27AD35
-:10E18000C199783E67B6A72637A25EB8BCE93206C9
-:10E19000EF176DBF2B13CB33DB636723BF9FEC9A65
-:10E1A000393909F6BBE4E1A47C354C6EFC45D0E37B
-:10E1B0008DCBAF4A457BE0E6AF0F3CE2023B6E31D0
-:10E1C000C01AE1FE457BBCDF074D6E6ED893A902F5
-:10E1D0008D7D1DE3FD1CE1799365DF756390FF2B59
-:10E1E000FE9D03A8BD3BD5D58B9D7D1AED50C0E7A4
-:10E1F000E53FFB80C6F9D4F2E6B573A0FFCDCB7F37
-:10E200009588E3DC74FFE1512E78FED650EF7FA3B2
-:10E210003DFFB1B27DA70B05D396ED23506E7F8DE8
-:10E22000765A31E2B5E7BA3908F7D755827BB4F9A7
-:10E230006AF728045F59AFF6F7217DD61B60761781
-:10E24000962E46FAF21995D5A33E20F51AF93CA967
-:10E2500080C3E54C9FD64CC48B653B3767A25C39C5
-:10E260009BC0EB553BAF7F03F994F7F118AEB75B5A
-:10E2700019E9C90B7D5CEF66B540AF0342F30F2C83
-:10E2800088A7F1966D2934C843D04BE8F9592B2B58
-:10E29000C3750C6EEACA47FDEB436B60319EEB879A
-:10E2A000A0D7A27DFB17C1C73E6C55A7E2731F1014
-:10E2B00012EA231FB6FE2A61A833A4C72514B507A6
-:10E2C00090CF2D7F2EA940E52845F8754BB75FC448
-:10E2D0003975600AE9632EC4D3157B0F4E65BC0EF9
-:10E2E00082303A3C6F147A5877FDB967C8AEBB7973
-:10E2F00037D7276E6E7FE6D57418E7963D429F109C
-:10E300007ACA7241CFB73CC7E1B2FCB963F685E186
-:10E31000F6486EF2DA81A0094E78F6F2D9F7BBD151
-:10E32000DE56C8AF52A965CE691C8AA5F4977491D0
-:10E330007EB83EB783ECF2E5CD62BCDC8EB5D9B4D5
-:10E34000DF997DC3F5A1890536EA27FB033CA8DFE9
-:10E3500097B1892390FF0596C7B5A05CD76F715A16
-:10E36000B16C5AEE2439FF709D25D70AF0D5953847
-:10E370000DF5B87A076F7F675CE20E2CF7C5F1FAEE
-:10E3800097B19924A7BEB4789E5902EDEE540FC5FB
-:10E39000A2FF6300EB3A60817A493FEF7505306F69
-:10E3A0002A03EA51517E04147CFFD96F3E2AC475BA
-:10E3B0004C181C3CCF6069B6C6BC3993014F6A0A41
-:10E3C000C43EF3828588EFFD5EE6FC7A9B8DB5A0A6
-:10E3D000BC63560F9B05CF03C8BFF0FCFF66F1235B
-:10E3E0003FDEA7041E0BD7BFEE1378EB8971B6286A
-:10E3F000B0CEC7B3BC4B711D3F526CC35175616E3B
-:10E400003507C7FFCCC6DF4B3DB65430E10C618FFA
-:10E41000D9D3D39CB8BF26012F45D7593DAC6375DE
-:10E42000DECB0B115FEEEE72B01898BFB42B8EF4FA
-:10E43000DA8CF432926F4D022E8A3B05650E7B39E1
-:10E44000CFE28B81F5DECD1C7E6CCF1C26FDD71272
-:10E45000AB633F65DF6FFF86FC7EA0FAF9813ED09B
-:10E460007EE09D8AD6046D6ACE9DDEF60E43FBD912
-:10E470009F8FF0BBB39FB7B100F6D779AEEC98177A
-:10E48000CEFB6E57BB43CBE3E385EF63DFCABF250B
-:10E49000265B42EBFBACEBF42F9F2FC2D24172A85C
-:10E4A000749FCAFD4DA6F57C96E6B6D23975390241
-:10E4B000166CEFB4F81505DB1FF800D757EA7006A5
-:10E4C00054D4E31DB63F85CB19762823E9F41524EF
-:10E4D0005AD837A02CF46FE2E737A18FD1BEDC59B0
-:10E4E000C0EDA49DE29C247C25DC985B67E172E68C
-:10E4F00025E7CE6AEEC7E274FC4FE2F9B9BF669336
-:10E500007E716E1FE81911F44E591E463D03F487C3
-:10E510002FB3F5A7106E52CE564AA92BE4B02AC6E7
-:10E52000AD14F0AA745A387C2A4CF0117863C60BEB
-:10E53000F3B9CBF3643F3974B04F169DE3F07F61BC
-:10E54000747E7B111F3BFFF6E61A203796AEEAC7B2
-:10E55000BC59FF13CF2F103B0CF58AFB2DA457A0FD
-:10E56000DE877AA2E41F5EE40323E939D703731937
-:10E57000F18D1A358EFC8C66BE21F985370ECA11D5
-:10E58000C8375A891FDCA9761DB428213E31B82C22
-:10E59000381CE5702798FEF83E6869A7E7DF146429
-:10E5A000137F18C40E0D203FAB35588C7AA0EA7843
-:10E5B0006CDB4910296DEB387D34D9FC0F2E41FE00
-:10E5C00050E9D450AFFBCC6FF1D9609D6D499C6F81
-:10E5D000B42D4B2779FE19137C64B69DF8C89516A7
-:10E5E0008B8FECAD39E9646F75B7CF71937FF5D739
-:10E5F0005FAB976DC1F7331D2477DB501E43BD6DB4
-:10E60000E3707AFFA2E44BCB385F6A9BA90F88C303
-:10E61000F733FB5B70BEDD29DEBFE1B9A7ABFE9F20
-:10E62000C7A23E79531C7B029EB765E90350DE3ECC
-:10E63000A078E62CC6FEC3F9BA8373E29EDAC98FCE
-:10E640002780FEA4CEFA841DE17E6FE9471FEC3BD4
-:10E65000F620C2CB57CA72519FEF44FC1C193A2FC7
-:10E66000B0CA597D72E8DC524CE726F1D56783F3D6
-:10E670004BE1E7B75A897E7E29E2FC947AC06FE2CB
-:10E68000FFFC7CEE54397F672F696E2CD5FEDED4FB
-:10E6900042585FD3AD702E2410837720BCB6AD4CAA
-:10E6A000D0711F9D1656DB1E816EB30B85DF09A549
-:10E6B00031D0C33C410FF324DEAE32E16D7050D255
-:10E6C000E97881B7D0FFC578CF509CF753E5F028A3
-:10E6D0007CF8E67FABB323CD33BC90FB0BF68356BF
-:10E6E0005A48F2B5D4A0AFBE99FF5106CA29F6D553
-:10E6F000814128775F49F18C2C04FE113BB48BFCDF
-:10E70000E69D03BA6CB8CFCE391F67A05E34AFFE6A
-:10E71000B7445F17BBCED5F135361C27A922CB16DF
-:10E720008432B522EB20E2CF91E931EE98087AC825
-:10E73000FEE9C33250FFEDA81C96817CAF030EF0BA
-:10E7400010AECFEA4E40FEC7F654131FAB147CAC9C
-:10E75000A362087F2EF866D8F38D45A8D73A2D5AC4
-:10E76000B8BE602ECF02DF0C00DFFC08EC332C4F6C
-:10E77000817D1600FDF504D867583F06F6199647C7
-:10E78000C13EC3B2A341A3F74D1543F604E19CBFBC
-:10E790006851687CF4DF46D28B6F7C5C6501091F91
-:10E7A000F8AFF6E17816C80DD597B4F535D4176DE6
-:10E7B0001868A82F681E62A84B3DD2BBEA0AC3B8EE
-:10E7C000E565858676ABE347D8F05C93CAF239DC21
-:10E7D000CBF209EE1DD74481FB35A309EE87A78F45
-:10E7E000CE40781E46B8A3FD66D512F01C24DC6727
-:10E7F00089390F9715F2E702EEA1E7E5BDCAA94FE7
-:10E8000010DE31087707951F21BC09EE1CDE2710AA
-:10E81000DE3108F75C2A8F22BC87E1B800EFA20B3B
-:10E82000C3FBE6DDAA010E373E6E8477EDC37D4D56
-:10E83000F01F6880E3A20D430C7509EF05CD467803
-:10E840007B57159ADA31B601E0508EBF001D1C2EA1
-:10E850009E467129AB83F9E281AF2421BDC1FAAD97
-:10E86000150AD78FE0A715E87016FE02F46575F259
-:10E87000F7CD73143FF225D489D0AE00B806E281FB
-:10E88000CECA5D979D42BE743D723015ED7A3F95BC
-:10E8900037B000D167350B527D1EEBCAB443798B7C
-:10E8A0001A588BFEBBB71CDE27919EFF32FDDD4E52
-:10E8B0000589529B3F0CE99C3993C9DE8C764EC08A
-:10E8C00029257F62CE51625FF05381FC1FFA75C427
-:10E8D0008FB8E30E3887CFE60747E1FC373BBC8FA4
-:10E8E000A65868BE3D38DFA736EFB0BEF0FCADE2FB
-:10E8F000D11948FFCCD3CF6027459B6F136E16E02C
-:10E9000030BF0CE0A4601C8EC3E5642587CBFE4DB0
-:10E910003176F4679C5C67237FE5E6F8CC4CC4DB7A
-:10E92000936BA66522DE356E1A9689F83EAB65DAE2
-:10E9300059E4DF53D41935144F6DE578CFD8ADA421
-:10E9400077DD21CEEEB89B6901785F393D41F3C197
-:10E950007EBCBEAC445A2FD39DF9D06EA1D8F7C26D
-:10E96000D6A533703CB9FF051B620CE7FFA3126309
-:10E97000BD92D943789685E76C0FBDC7F357ABFAC4
-:10E98000787BB1A3EBFFB0FD8D57C2C63B5E98907C
-:10E99000827A0B1BCD467FA386FA4783EB970DFE49
-:10E9A000375EC909C155E2D36F0A3D9FE0F9C063E4
-:10E9B0008AB7012D913CB8A5DBAFB52F11E1B7297E
-:10E9C000FEA57BAE44B8BCC7FD1C9BE36B887F7C77
-:10E9D000827C3B0BF9F4F519C130BE20FB07053FE3
-:10E9E0003DF2CBEB898F1CA84CA5784CC773DCBFDC
-:10E9F0007C54D07D47C5F5D57700FFECD8AD929E0D
-:10EA0000D7B1E7FC41F4D374B42B9A00B9257CDC70
-:10EA10008E3DC0CF91DF7A6CF47EFFEE5FD13ABFBE
-:10EA20002F7E5EB157F0F32D7CFEC5560FF117E631
-:10EA30009D6DD8DFDF8BAF5F889F1FB1713CED38D4
-:10EA4000A292BF8DF9F443B9FDC3F0B38CE36763C1
-:10EA5000650CE3F295F39959154007A8E733773130
-:10EA6000DA949FEC29EF47F27283ED38EAD32EF85F
-:10EA70008772DB0CC74A663D1E0CC3DF9B9F83F683
-:10EA800061EB9B85EFC3F0D98CAF2545467CFD82B9
-:10EA90007D9569CFE6EF0FF50FF13DFC09E72F9269
-:10EAA0006F49FC05BE55837C0DF8CA554580B73FBC
-:10EAB0002EC8FA4D5009E32B17C9C736C57F4D72D2
-:10EAC0007073FCD784C7872B051E839E81CF3BAE16
-:10EAD000E1FA06F3CF267A9827F5089B2701FDA4D3
-:10EAE0004756F54DC4F7C79ACB89EE243D99E73BCD
-:10EAF0002AF04FB69B67EDB26911E4A17795117FBB
-:10EB0000D8AED984EF7798F02CDAF8E6F6729E79D1
-:10EB1000A678AF799EDB8A84DED95E7D51F3211918
-:10EB200076F727FD362E84972AF2812F1382A47F51
-:10EB3000CD36E86547CB46935E76B8E27C44FDEC83
-:10EB400068C5F9B74623BD95D904BDD752FF72F108
-:10EB5000DEBC8E8F84DE704AF08F1382AEE57B754B
-:10EB6000FB9AFE7311EF57A91AF2AB23330A09CFB0
-:10EB7000CFF82B69FEA3152AF99BEE2F9A3217FDC9
-:10EB80004D723D72BEF26BCE27A03FED0B8017FA9F
-:10EB9000C7CA6D5ABF48FA85191ED1C695F803FA3F
-:10EBA000EC11DCE761E4A3F8D66B84D361EC0FEFE2
-:10EBB000676D5729DE6686D381E9C3882F1DDD2561
-:10EBC000F827C015F5F0DA878DE7BAA42DDEC46FFB
-:10EBD000FA1ADECFAAE47A99E4D7727D87570DE955
-:10EBE000179E3775A1F396E35C2CBEDC28FAA3D8F8
-:10EBF000FC86E46FB2613CB0144DF3659BDE5F6E42
-:10EC00007A5F60AC5F241E1F13F823E5CFB158ADC7
-:10EC10003A521CEFE8D531B5E1F9099D45DC7FD3C7
-:10EC20005924E2DE9728B7FFA328B2DC8ED65FF224
-:10EC3000BDA70B3D41E4772C504EF1EC8BE57361A1
-:10EC400072FE4C11D27950B1637FA957DD58C6E5E9
-:10EC5000C2E6F8A7284FE3D346AE17ED6F8C213CF0
-:10EC6000FCF335FCFD9FFFED23D2A70EECDD9C18D5
-:10EC70002EE7255E9EDD332D11FDC2272B1E4B0C8A
-:10EC8000B703E4FB8F2B1EBB672CD1B7AAF5762EFA
-:10EC9000DFD61EE8A810F680D0176EB2B6FF3FB1DF
-:10ECA00007CC76C014F5E144E47F667BE0AC5B4FB3
-:10ECB00074117C04DD09B972A380CF9F6D7A22C5DF
-:10ECC000E9761572B962C24F0987D3120E1BCA7B4F
-:10ECD000C59B53422EC8FA622B2378781D8CF465AD
-:10ECE000D6A66818FFC234951238974315F98FA13C
-:10ECF000FF4AB67FA65825FC96F31CD9A6B4A37F7D
-:10ED0000E5B7CDE5D57760BEC38C78E2ABB2FD1236
-:10ED10005FEFF2EBC8C6A46B711EEF1655C3475EDA
-:10ED2000DFB17EE1EB977A9AB9DF326BEB45D9D14F
-:10ED30005EDFF644B46F83629DC1FDB1767742CF4A
-:10ED40007E18AFC1FD2F9BA16A8DB0FE651BF8BA7E
-:10ED50002A7DAA960DF5DFB63E762DD2C1897A9B23
-:10ED600085DB072E039EBFD95AF836B63F59C6E554
-:10ED7000CAB18AAB12310FCEB7C5A6E5B87BCE5764
-:10ED800053CCF3D2CEEE89B1A0FFF46CBD8D05C893
-:10ED90007FE1217BF9C88621549E45F871FB9ACE0C
-:10EDA000FFC662EEE73AD1BAB03FA72737AD43E2DC
-:10EDB000CBB15D6A993F02BFBA519CDBA9AF9E26D9
-:10EDC0007C7B755739C9E313157C9E53ABB44484DF
-:10EDD000E7EF36A844C7277D7CFCFD7BEF4A1C0B80
-:10EDE000FB385BC1F77576CF9D6F8F817D062BA4B5
-:10EDF0003CE6724AE6F704370CA178EFA7CDDCFEBB
-:10EE000096F42EE3E157AD3C9248FDA59CDB3DDB3B
-:10EE1000B0FE8E5D27C80E3BBB0166E372CE998FB4
-:10EE2000F986BC3B5B32C378BEB32AE20DF5792D7F
-:10EE30004679D6B897F32BB39EBB7803E8C1E89721
-:10EE400032D9790B1B0B134B907E510FC63C932785
-:10EE5000CA0FA6E23EDAABA95D85889B2D6C8B318B
-:10EE6000F083CA66A35DB7C064C7F5B0EB4CF24847
-:10EE7000C2697914F924F5B90E61AF1CB579AA23DA
-:10EE8000E553B41773F9330FE8370DE3444CAFBCC7
-:10EE900052C07B3DC2C7DEF5450EE8D31DAA361E23
-:10EEA000F5EA1E7460D203CBCB8CF0659A8F95483F
-:10EEB0007F849BF4FBD3A8FFB7F41572DB0772289D
-:10EEC00001E592FE6C31CA958BF51F5CB47E5E2322
-:10EED000F4F31A837EDE814DC2FAEFAFBC9EFC5480
-:10EEE00047AEB99EF4F523DD7E2A8FC14F25F5BAD2
-:10EEF0002333CA0DFA67D8F33EBDE58B47D3378F6E
-:10EF0000213F263ECDE5D25A6147360B3BF2C80C75
-:10EF10006147A630A223AB556791F8D9A5EA6F0BDC
-:10EF20009A8D72C9BBCA683F3E3FC97B16CF252662
-:10EF3000ED72C3739BABC0E83F34E1E740C6FDE729
-:10EF400077A12F00E0DE54C9F34EF139E6BF48B98E
-:10EF5000C4A03DF28BCA0D97FBD7F3F73EB500D3A3
-:10EF6000E518AA74D4DECAEBBAC2EB3EA778AF8A22
-:10EF7000BC371BD48F6569B351EFC2BC9EF864FEE9
-:10EF80001E516420E075627248FEA15F3F9687D6ED
-:10EF90007D89D06F5045D62B48D798EF735901DA49
-:10EFA0008C3C2F2C0D5DFA05347E00F37A824D13D4
-:10EFB000C9DF5CEE48E4F179B0A37BC7BF46AED7AA
-:10EFC00095F5A5C90659F97AA2E2B36877217C0EB6
-:10EFD000D3C3068C223F9A85FC2D9BE247D8107F35
-:10EFE00067393D190807C07792AF1DBFB1131FDE07
-:10EFF0005FC9FDB01DD3476FBB1D9E8F78DA49BE38
-:10F00000F48EC5D20FDE95108EB747579DB0205FA6
-:10F01000FEFD1EA6611EE3D1DD5507DF80710EAC3B
-:10F020005AB8B118E9E84D95EC06B3FF76D2D3E3B0
-:10F03000C8FEBAEE1A95F2BB0F97A90CE5DAE10DFE
-:10F0400071063B24E4D755093FBED867A5F768EAA7
-:10F05000E462FE15FA37314FAB8C9FCB0B829FB524
-:10F060008B73FCB9D063760ABA69137473AFA09B33
-:10F070007566FFEEC39C6E0EEF01C301E4FA3B33ED
-:10F08000169692DF7A0BA33874D674757D11ECEF67
-:10F090008A18CD86F09B34239FC3B342B160FCA68F
-:10F0A000BC2CDF86F47E455FB70DF96879D94CAA90
-:10F0B0004FAEC8223B7FFF2A908F68EF2768194820
-:10F0C000974367C4042C89683716129FB8F28CC521
-:10F0D000402FF9813803DD5DFE78B2E1FDB02DE906
-:10F0E000867A3F4FB6A17DDF32233DC60D2D30F22B
-:10F0F0005DC6F54209E729EA38F2731D0DC9517A58
-:10F100002FF511E9AF93ED015A06BED622E4C808E7
-:10F11000A8633EDDBA8A2607E64D7CD16ED5F8F8A5
-:10F1200055A41F38B29E73209D606815F3AB5AA496
-:10F13000FE29FCF74C67A6756D6018673D5AC60836
-:10F140009F62873205F5AF3671DEF7897981AF4E60
-:10F15000B2919F8E9F63DF191E6AC73C46FB200D4C
-:10F16000E9AC00F184F7FFB9E8BF53E0CBD1B2C7F7
-:10F1700056C7213ECC66A46F4C516F5E8DF1C4A37F
-:10F180003318D1497BE0E5385C3F8E83F9812F4409
-:10F190001BA7E2571FDE82EBD965A771CA1F671351
-:10F1A000104F2EFFD1B18FDF46F06D711D88653D88
-:10F1B000E5F088C7750D81937B86056C540674E471
-:10F1C0003FB9670EE9180FBCFCCFBB3E7E8AE1BC9D
-:10F1D0005C2EB408FC36F3D75F3CF1EB05289F7F2B
-:10F1E000B1736BC10750FE60F583E9F550FE7CF505
-:10F1F0004D5B6F7787FCA53BAF5DBAA30DEAC37E7D
-:10F20000F8D3279F43BCBAF6A7FFE7395CEFB57F79
-:10F21000FBA313D67F59530243FA96EB33CF93C621
-:10F220005A148C8B221F25BE6CF5517DBECF68FF12
-:10F2300098E53EB6B702FCCAEB7F41F1E534D1FF59
-:10F24000F03577292ACCFBC17CCE573A1ABADA2698
-:10F25000DBA87D00DB039FA47CCD818380AD607F34
-:10F26000BB4FC1B83828481AC67B07C07BE4E7CC3F
-:10F27000ED26FD2A53E2AFE02B78CD81913FD04AB5
-:10F2800078962BE291C87F91DFBF312A9BF8F2403C
-:10F2900027D3F17CCB5EDCA0609EDAFB5EB7467ABA
-:10F2A0004103BB7F32D8C997AB3CEF22B7ECFDB925
-:10F2B000782EB055ABB72034EE2EA1D795BDE8A47B
-:10F2C000BCEDF77739B7939E7FE85A4BB87E58FA72
-:10F2D0008B3F3DFB3BC4AFF9B1845F66BDA543D016
-:10F2E0004777DDE6DE763BC0C7F71B07B7AB747721
-:10F2F00006D9E99A3B03F377BADBFD54C6D3B43F92
-:10F30000223F9F55154F7106195752CB3E5F83F42C
-:10F3100038AFA4AE18F5F7743C87BEA138F607CB1A
-:10F32000EC946FE053E2282F3D5ABCFABF843C6452
-:10F33000AC6E24AD83D58DC6F2FCECA66D767774E9
-:10F3400079D52CCE35DA7B9B9D7923C595FF6B143F
-:10F35000F72336E139D8C2CEC1F9FBB9181F8E7632
-:10F360000ECCEA2FA03C4B876328E681A48AC79B7A
-:10F37000E37FF616CAABCE235C5EA5D67FD980F4B8
-:10F3800027FD163569AC3B6EA6433F9BE8972AE202
-:10F390002C48C3A87FD78878516735A378516AFD78
-:10F3A00047FF8DF0D924C6AF798F8F6FB706F6234C
-:10F3B000BED438DD24773AFB256A78AF897DC5F362
-:10F3C00053D219C747393E13E3E3CA59D8BA53E3B6
-:10F3D000AADEA1EB101358201EF14771D0BCE9AB97
-:10F3E0006228AF55EA57A9F577DDAA8E308CA7A021
-:10F3F0005EFD7E15B7B7D1ECEC1E37CBA057919EC2
-:10F40000655E87ECD769637BD0FE0DD3B3480F638D
-:10F41000E1F30C31D4851FCD58B7A5D90D7CE2FDA1
-:10F42000AFCAFBD47139E04E19C5FD77080FA98F1B
-:10F4300049BDADC7B882DEC3F44B1FF20B9947D16B
-:10F44000AD27D586D94DD93DFBC97C35790E129EA5
-:10F45000D1FA3F3F499F329AF4AC008DE315C3586F
-:10F46000E29D99045F13BF04B6C5F3E9851E0A5AED
-:10F47000A4218F41EA95923F770ABE1BCC0A92DF06
-:10F4800050E6890F823E99D0FF86D149DD79F6A8F2
-:10F49000071D6DF88CE2EF35A887C2FCC1D59F1817
-:10F4A000EEA114954EBA81D66BCA97088BBBD27A5F
-:10F4B000BD826F4E519D94B7D2C9E234E45F9D3E48
-:10F4C000A18FFD219EF431C92FCCFCE11ACDC8FFDC
-:10F4D0007F5462E4FF33F5BE26BBD018A7AAF49888
-:10F4E000E2E1EF4D37F04DC97FEE44379F8AEE25BC
-:10F4F0000FC575DE14FCF26DA107DA591D3D77309A
-:10F500007E7F348EB553E96487A84C645D54BA9805
-:10F510008BF26B929946650AF350D99FD55199C6E3
-:10F52000783E553A6BA772103B446526EBA2D2CDCC
-:10F530005C162CB39946E550E6A1D2C35C14277F34
-:10F540002F21987118E037E37A26EEFD1EBA418725
-:10F5500073EAAC64A17BC04857539840BEB7F9FB2F
-:10F56000E9B2FECE0D3ABE9FC4DB6F7DFEBD87F0D3
-:10F570005E30F01BF1BE83BFEFAEBF7BC324EC6FE8
-:10F58000B3507DA7687FAA487F08CFFFE9D18CCE12
-:10F59000BBAC48DF36BA38543F53A83F1A5EEF3F42
-:10F5A0004ADF1E5E1F5DA83F16DE7F49A1FE44F8BC
-:10F5B000FB7DC5FABFF2BA8BF0F23D9B4EFA2EFCF2
-:10F5C000EC5246717CC39F3EAAF769C2C3DD8A151F
-:10F5D000CF3546D09B1DCF51453AD21C31587A7851
-:10F5E000DE4F30D6198CB7F462FF98E82888FC0902
-:10F5F000F070B8E2DD47F398F889E213F98329C681
-:10F60000B809E03BF95583ABB89DCE58E4F772DEFC
-:10F610000BE139D3C3FCBCD9A171A3EDC38CBF8767
-:10F62000849ED721F4BCF7441CB97BDF416BD269BF
-:10F6300047888EA3DB8756763A9C5FF6D8F79FAA59
-:10F640006D40D7C1FA1817CABBCE58F636DA69BE74
-:10F65000232A433DE352D7DB5638F50CE78B835C16
-:10F66000C867BAE7157CA6137F053DE78A3ED2BE80
-:10F67000D41C1CDEDCEE4812EB6A9A9C7C752EF9D9
-:10F68000F3B95E9F673B34731AAC337503F7AB264F
-:10F69000227D63E8ECE93FB8308ED63AC5C2904F80
-:10F6A000AD917E5E933F6ED3E415AE707FF09A44C9
-:10F6B000BF82F1CBF4402CF743A4307F2CCAD13267
-:10F6C000AD8CF2667CAAAB0CEB55ECDA5CA82F682B
-:10F6D00053DD6530EF81B65FAD403FE0A22A3BC508
-:10F6E000316CFAD4B3DCFFC7F33792059E37AF8B8A
-:10F6F000D10208C77E4EF2DBE6AD2928437BB7C9AD
-:10F70000999C8CB8985CB584FC864D4EED35BCDF79
-:10F71000E17359283F91B9744739E82BDB6FB796ED
-:10F72000211FCF78A628510D5BF789E673B1180722
-:10F7300079D465A1F78FAE2A752C71E23D46B017DA
-:10F74000A03CE03AAEA3FEBE15DAA0BFF19EDAE31C
-:10F75000AD97F5728E89657603DEC66BC67A8CC965
-:10F76000DF6833E905C34A1252E89C47B15178CEAD
-:10F77000239FFC8AECDF794E37F9D54B5B14CA8F97
-:10F7800009EED73251DF3CB17118E5BB34B718FD33
-:10F79000D1C10C9689F77DE6B72AA4AFAACD9F37D1
-:10F7A00062BFC1B9EE0138CE60AD6B802B8CFE1EFE
-:10F7B000FDE98F6351DE35E38535C223C6E342C2DE
-:10F7C0005E95F7CAE7BBCE55A3DEBFA8F55D0FC2B5
-:10F7D0003F49B710CD1CB5F9D3F0FCD74F9A45740B
-:10F7E00089F7B4508FE9A18FFE15D619763F614D88
-:10F7F0004A761CCE1BC25F3D11F77BB2B590F4A3D5
-:10F800001D2DA5741FC03CCEDD0DAC1DF5D6350DEC
-:10F810008EF648FAEFDD999E4CBCBF7D6AD3A4B545
-:10F820000CCEFFD4FE656978DF7D716B0C8B75F7AC
-:10F830006C7F72D3689A6F31DEA3C6795B67DA5149
-:10F840006E4C6B9B6447B8DDDD30FB99F0791E2A66
-:10F85000F5569700FDC5B73E4378E264011FC2F537
-:10F86000DFC7EB99A85F9CCC6111F33997962844C8
-:10F87000B7BF1BEFA1FB29A73222B7BBA984EBE7D7
-:10F88000C11237BFB76E656F2F4D217BD085F47ADB
-:10F89000A2A590E277368CBB0FC1EF567CD580F8DD
-:10F8A0007FBE6AE1074BE1FD9AE9D79DC172A4BD15
-:10F8B0008EF466F67B95E801F442BA27F69F150EA2
-:10F8C0005753581E21EA8FBAC1AFE161687FD85AF9
-:10F8D000D4801DF8BB6DDF69D2C3115FF530FCA584
-:10F8E0009F51429F17F92169A3E8DE1DFDACB9FACB
-:10F8F0003A7F00CAE32D0B1D91CE31FAFC61E3A2E1
-:10F900007E3B99E9B161F383540C905FDBCBE7EB6D
-:10F910006E27DE8319AAD3FA845E6E7EDF4D6F5B9D
-:10F920008CF4B94D9C8FD4CFA3ADF7077E63BF177E
-:10F930003038818644FBB5067AB95C6D5F817115FC
-:10F94000F63EE7FF60D7314F84385788CFC2DAFBE5
-:10F950000BF8013CD7A6CC22FB24DA3AECFE437A22
-:10F96000D68890FDF68334E3BA64BB17C4BE62FC4C
-:10F970002C604BC43240F73962A03FCAEF2FAA6E09
-:10F98000735D1D812E6469E65BF8E30E8BFF98F9C9
-:10F9900004A2C150A98F58787F3D8CCF25DCCFF5CC
-:10F9A000DF935B14D27FD76FE279145FF8A14ECA60
-:10F9B000053F27542DBE11CA8E33ECDEE192175B52
-:10F9C000EEB9DC6D80DBA2F0EF999C79F2276FE352
-:10F9D000FB8F9EFA8907977B57CAA244CEB78E2D1C
-:10F9E000C0794E5D61277F0CFE38247E40C3A5FEA2
-:10F9F00018031EAEDFFBE496052877F63A344CC7B1
-:10FA00005BBCC5F83E262D6C5F8CE397CF00A760EA
-:10FA1000F64CA0A3A33FFD57BA1F1E87FC13E97144
-:10FA2000550CDD0B33C3795C49F77746086F1784B3
-:10FA3000E250741F44D2D5F10D4DA7541867ED2A3A
-:10FA4000BB9BBEA760B2BF8EBA67EA6961F161FB7A
-:10FA50002A7E4F9385DB89D9A1FDCB718FFA163AA7
-:10FA6000DCCE9EE3F5C0BB28E3F529D5BF46BE98A2
-:10FA700056EA6163281EBD90F65DBF67D5D137A0F9
-:10FA8000CD3D715EEB987EB8FE21A314BC2F63754B
-:10FA9000D3BDC1E6664B2CF2FDD6766BEC50847775
-:10FAA000B385E47C6B7B4ADC50944B4E0BC54F51C5
-:10FAB000AEA861FEFDD16338BC42F2C39318AEFF1D
-:10FAC000C4097C3C952BF49FC95CFF519EDE477AAC
-:10FAD00047F31A1EA792FA864BE08FAB99C721A372
-:10FAE000E93FC87870DD09C58B5CC8D7D624F2EF32
-:10FAF0006F2C9AACF9F03EE7554E467263305EAA21
-:10FB0000403DCBC9FCD3601ED5C5F51B6F2B237DB3
-:10FB100026D9E9D410D4A96D7E1FAD5BE774E680C9
-:10FB20007F08CFB85C9DE1F856935E6137E90DAA76
-:10FB3000A9AE8D11792B428F6042FF96F1E0848D42
-:10FB4000BDE70149BF6EABF04F80FEE4A37B2325E8
-:10FB5000CC8F78CB74DD9DD23F6407A489EF1EA5BE
-:10FB600095B0ED4D61F127457F95FC06D22F29FD1B
-:10FB70000FD2CF31A204ECB5C4307FC44B605AAA77
-:10FB8000140F9B8E789205EC80ECC93CA6F0EB1923
-:10FB9000DF524FAFBFB8B8CF432FF3FB41CD9638FC
-:10FBA0006D4756CF76378DE3F8167700F6867AEDF7
-:10FBB000F50EBA873345DD4DF7EE371759785E33CA
-:10FBC0003BE4427D60E118CE77B34A3D0BC6503C22
-:10FBD000D593857803F0F0D9F0FE9EF0DB66DC91DA
-:10FBE0001D87FAF007034E6F42BDDCB7C642FC46E4
-:10FBF000C231ABD1722FA261587C2E602D08C5D9BD
-:10FC0000D67BCEF9F0BEF0B5E3B8DF356EE6C9FDC0
-:10FC1000E8075D37D4427EF6BB12748ADB01FD38FB
-:10FC2000541EAF7B0DE36D2DEEE464FCEECE534924
-:10FC3000FCBDFC7ED50309FDB787E797948EE3FAF8
-:10FC4000C8034A647DA5EF3885E759ED0540F621E4
-:10FC5000BF16B7C77D5F54E9CEB03AD21EF4FF1786
-:10FC60001FB7A75BF67E51E51B4A7692789F534DEE
-:10FC7000F63AFA18E1FD89BD2F55F9A0FE4856E481
-:10FC8000797F2BE67DE475EF60D467837B017FFA93
-:10FC9000443ADF00B394D0B89918970AAE8C991DF6
-:10FCA000E93B3683C6F37D6E8677317D427AECE69A
-:10FCB0002AB39EEA277E75BEF6F8414AD306FE5166
-:10FCC0000CF490C422F3CB0BEBAB5A1AEA9D4D2BEC
-:10FCD00095B5C83F9A405FC5B860AACB4EFA6A7323
-:10FCE000D28F27E1B99CAF652EBCEFBA03D43EE4B6
-:10FCF0005FE857C57BACD3EA399FF1BAB89F15ECE2
-:10FD000038CF55888F03AC848F527FB55671FE7300
-:10FD1000450CCF47EE4C7292DF34A99EE71FC7FB1C
-:10FD2000409FC5FD4DE6F9C33AFC433E24F55B67B1
-:10FD30009ED590476C37E5195B4D79C5FBC718ED2B
-:10FD40009984E2A25EF5AA97C0FEC575EE03FE8314
-:10FD50006500EC602C5F06BB1DCB57C06EC7B8C1F9
-:10FD6000AB0DB954BED6A0D1F3371A4AA89C981946
-:10FD7000A4B822F991C97FC3020AF9F1247E7D3A21
-:10FD8000A814EA4F4DE2EFFFF3853B1FF50D82F714
-:10FD900029A2BDEFEA6AC4D7EE3AABAFC6F6356921
-:10FDA000BC5E3DF6C7D5E8FFE99AA27F88F2AD9F19
-:10FDB000C5337F0DB6FD498C16C9BEAF1D2BE47946
-:10FDC00014FB9DE127128CFE9CB3637AF1E73CA003
-:10FDD000F075F4DDF7D2C348177D665A3D88C799A0
-:10FDE000D9463FFFD563395D3C3896F39FCC3780C9
-:10FDF0003E7A81BBA48F68EF9BF6020A44A02B5980
-:10FE00006E4E6013E87E76B57D76A43CA7F3827FC4
-:10FE1000441DDFC9DC312343F4D6E434D35B90E2E4
-:10FE2000BBE7EB6FDB8FF2F2BBD31B23FB3058AD8C
-:10FE300093BC0E02BD213F576B39BDA9567E3FB31F
-:10FE4000E64DEE1FD981F485F970486FF0EB341F51
-:10FE5000AFA79AE8ADC94C6F4E23BD0591DE60BCDB
-:10FE6000241FD72FE2ABDABF577A1B39F6BBD1DBA1
-:10FE7000BF8F0F525E436756DD0084CF66F13DBCF5
-:10FE80004BA5C337C7DAB93C18AE935FA0597CFFC6
-:10FE90001058CC06FCCECAB4418DD66480DF8C9459
-:10FEA0007CFA0EC16D63FB0B3A39E4447F4DE224CA
-:10FEB0007DDA58A4AFEBCED0FDC67E164EBFB5633B
-:10FEC000BBAA90FE32D674CC9C8674B75225396991
-:10FED000DED78B1338DD35297C5E38B901E171BD81
-:10FEE000B963393EBA5736290ED4C7E7332D278B6D
-:10FEF000BE2B43DFBBF997E6FF74E1B82F4EE0DF7E
-:10FF0000737137BE97E4E5FEB534B4DFE84A734158
-:10FF10004F7A849F765B7F033D2FC47D44A3E70B1C
-:10FF2000F18FE01845C085511EB057DCDF94719108
-:10FF3000A8F46CF2E346F51F0E8FFC5DCAC9E3F925
-:10FF4000BC4DC2FF6BD6F7E4FE0F4FF2FE6C2C8C5B
-:10FF5000A3385FE57EE07DCC8DEB9471B3EE3C235E
-:10FF6000A91FFA98BF09F56D2BA832FDB9BA81E334
-:10FF700075E71F093D7159A9771D8EBB9DB9F7A380
-:10FF80007C736A3C5FE1F949FA7A82E7B7D4034BA4
-:10FF90004AF57B71DC6878B56C9AFE406FEFD957F3
-:10FFA00030CAA8505C6BD24C2BE70BF58AE003CE2D
-:10FFB000B576A86F4E027EE646BD9DEFDB057CC39D
-:10FFC0004D7686D18E988ACE48E41BC84708B8FA89
-:10FFD0000CCCAB4C14E387E475F020EAA54180ED2E
-:10FFE000BDF02AD1C7E575D39B9CAFD881AF505CDB
-:10FFF000BA84DB09F25E507C9E46F697AAF76E3F04
-:020000023000CC
-:10000000584DF6FD9EB1C27E28604508B74C8BFB6B
-:10001000BE31F0BCF0C12987C7C0E3E26D8BFBA203
-:10002000381DBD7D4D397EEF6BD913A7B6A39F74E4
-:10003000CC7FC430F15D35CA33F83BCA193A97F327
-:10004000FB58B5CF8AFC2A321EAF19CFE59F8CB37F
-:10005000F682C7EF131E8B38E725E0B1F302787CF8
-:100060001CF135021E9FF88E78FC09F6BF170F01B0
-:10007000D61D3B4DFFB437BC9D3A55FFBC377E1AA9
-:10008000163FE0F943AC96EC6719BFEC015794AF0B
-:1000900039BDF8A5D6ED88457BB6A976C7EBF8DD66
-:1000A000C7A67A6E677726688E12B46FDE55E97B35
-:1000B00056D1FAA3DDED0366B96A3CCF8F3EB0326C
-:1000C000263011C6497772799BEED419E68B5B5DB9
-:1000D000419B3701F5350F43BDCD9E6261BE307F38
-:1000E000CC48DB2192CB9D20C7913E803E39BD2577
-:1000F000F171A47C9EB8F23E8CE4B0F15DC0FBC20D
-:10010000E8E4F5BD25E4874B287E6E05F653ABED9C
-:100110006EC4EF897F05B91936CF24D044C2EB579E
-:10012000390618C699E2CA32BC9F96F603C3FBABE8
-:10013000015FEC14C7E6F702A55E33DD9D6F68979B
-:1001400024E21C3FCC1D6318CFAA7E75EF68A47F04
-:10015000A1478C837FF45D5E93BE60D627CCFAC343
-:10016000E82B8DF75D4658451E9A95E7476C660E5D
-:10017000FA2E05F041FAEE414D284F80E864843DA7
-:10018000B8E36EF4ABCC71683E78D6BCF7EAB4F94C
-:100190004521FFD9E67AEEF76BDAE3D88EF4B05555
-:1001A000D0A5A4AFBC84E37318C9753B43796CA692
-:1001B0005799EF24FD05D29FA0D4723FC3D90959A6
-:1001C0003CEF48F09FCD55DCFE7D4809C42A4338FA
-:1001D0005DBA9343DFA74B638A6F3AA76F3D59948B
-:1001E000AAC8479579AF380EDAD9697C3EF61ACF9E
-:1001F0009B6CFC67ECEF62BE41C29F91911CF25375
-:10020000607EC2CDBC9F6FBAE83758E45BF6E1EB85
-:100210000F4C11F38D8052ADD3857FDA4B650CC640
-:10022000C3A1CC56B438F47F0C513D14684914F185
-:10023000F574114F8F57029C797C4B3E3212D828AF
-:10024000E625B064FE7D91D25F38994AF461DF8182
-:10025000F2E8AE63DA3BC5F0BC39E1C76F4D84E725
-:100260002DEFAA1AFA49EFCAF07D80746D0564F08B
-:10027000915FCB331FCF4DAD70B8A6413FD5B7BD11
-:1002800011E3BB23EDFEFD749EAB6388DE83D00FCC
-:10029000F1616B02D029E22B7ABA4685F281641CA7
-:1002A00023384673A01C0D623BEE6F36F83F23E403
-:1002B0009B90BFD42AEACDCE1DA4BFAF4DB1E317AA
-:1002C0005331BF27B31EF1B25F1CBF7FCB78DC6018
-:1002D00030FE12966F6F7745F66B82BE4670083619
-:1002E0002E4DEB4DEF8A1A47715A02F6C48B8FA33D
-:1002F000ACB9F13A7F206C9D72DF6B9D3B9405ECAD
-:1003000052E667C6384A2DD363474488A304FD0AE2
-:10031000AE73702D8FB30C16FEFA6F1B47A99CC0ED
-:10032000F5C74B8DA3C8FD5E237E9F01882DEE1976
-:10033000533C81CECB125A5F18FC1E277E44B82155
-:100340005004EA3F12F5B77677FCE949F8F5CD5D40
-:100350002FEFC652EA7133C5FB6B877DB90F73B7B8
-:1003600066AE5B21E258C6F8C33560D585FBF9F16E
-:100370007B01E1F599A6F5945A8D7182C94E63FB14
-:10038000A929C6F76583627A9C1BFAE569BF4ACF43
-:10039000FDDE157F0FE3DF9B0A3B07F5C27507E61D
-:1003A000CD61DCC7DD134FC2E3009EDF58597211E7
-:1003B000E28B85F4D2ADBEA5F75702FDAC0539CA74
-:1003C00079B1DB407FA1B847998EF824FDFDD1E8D3
-:1003D000E9B8339BFCFF83EBF7B74FEECBBAE300F2
-:1003E000F7C4791DE3F07B41CE730AEA2183EB5F0A
-:1003F000A1F7D7CD29EE158F72EA0FB44F0EFB8E01
-:10040000608ED56341FB39A7FE557A1E559FEFC913
-:1004100047286F2D47E085CC0BDC8A798100F79C5B
-:100420005AF17DE0B6DEF3DFA43C6C0ECBEFA364A3
-:1004300006B7C2C2C79772AF873F9D71BFAF9CAF6F
-:100440003B2FD0346FB7FC7371F9F7FC24AF36AE95
-:1004500038EC5E86B8C701FB8E98073A5AF8B37B32
-:10046000C963E37667C56B1FE0F8976C7746197729
-:10047000626630E23DA9A9C26FD5191BCC40BF41CD
-:100480006794BF9BF0D094A93F1CD78BBE8B79B3E8
-:1004900008CB68EBFCB679B37522DE24E3AD327F7E
-:1004A00056E6C55E287FF6BBFAE1570A7F40E93879
-:1004B00016310E615EEF6DC23F9E55EA598178118B
-:1004C0002DFE20DB7F30C01ED12F7E6442E4EF0E74
-:1004D000C8FC50586F4AB81D24FBC9BC7CF3786037
-:1004E00017AD1917E60FF436E690BF2FCCDE92F960
-:1004F000B0441F9B851FA29B0ECC7AA1888798F5DC
-:1005000042191F51AAB87F02E8A30DE745BD0BF3BE
-:10051000D2A59D27F34965DE28E685523CEA5BEAD1
-:1005200055DFBB3DD53885F2BA9A5CA5AF7D177B08
-:10053000EADF2718ED29AF93FB1DBC684F0DEF696B
-:100540004F15957A5F447899EDAAA33FFB84F26337
-:10055000C10EDD37EEFBE01326FFD4DC311CBFA556
-:100560009C96FEB4FD432D06BFEB5475D57ECA178D
-:10057000AFE5FE9674BD9DEC34BBD3EE467F8B7524
-:1005800032A7235B1EF3EB3CCE4BFE15995796EC3E
-:100590005C12F1BEA9B41383D24EF4F1FBA99D6F96
-:1005A000F2B86D3CFA5BB06119976BD2DF624B1108
-:1005B000FE16533E76BCC9BF62F6B79C1E27FCB63A
-:1005C000C2DFF288E2BE1B49FD575BA6FC0E41F17B
-:1005D0006F0F2F8E4753FF79FF9A1F0A7FCB834EF1
-:1005E00058DFDE0F8CFE1673FC2B42DC8B9C57838E
-:1005F000C6FF8EE26E12BE926EA53F2BBD9E7FBFE0
-:1006000069AABA5B41FEB2D9C9E1ABA23F2B25E48E
-:10061000CF529EFE53B75F8AEEE3F68893D7BD8E26
-:10062000EBB402C3591FC9BF25E06A8E4725D68B9C
-:100630007BC0DF933F2B79BC11BE050F16DE87DF31
-:10064000352EDA567E18CB51DB6FEB3B17CA92275B
-:10065000EE2BC7F22FAF07B350EF34FBB114047E7B
-:10066000714FF89AE128F1D45B2BF1D46927BAAD28
-:10067000E27034C32955E7789A03780A2A4237FE94
-:10068000752671FA4C9FACBD86FEB5C17956160928
-:100690008FADF5FC7B59128E5B051C936B97909F79
-:1006A000D08CA783DB2E0D3FC79AE0F7EC96C2BB38
-:1006B000116ECF3D5CFE3B2C7FEDBF2D1EE1B6E7FA
-:1006C000F1FB7E28E03780BEA76B82DF03F811E9DB
-:1006D0007E3DE13751E3F6F5E7A5DEB2F100DFAB91
-:1006E0008143A03F64474B81C3180732F2D3D4EF54
-:1006F000C93F15ECE6A7ECED9C4BE0A71F9BFC5314
-:10070000A93E4E37A9BE63449FE9409FB1E8AFAA16
-:10071000E57A24887D7FBC823637E7AF52AE21CBA5
-:10072000B180F0D9EAE271E7087ECA007DEFD7C454
-:1007300087D181138E772057EB107E52DE6DADE5A9
-:1007400071B4DBA678568CEF178AAB3D3F49BF6D7D
-:100750003CDD5FF8D6FEC77FC6FED2FF08784AFBB5
-:100760005701DFF1FBE657813C41FBDF5A1BB4A187
-:100770005CA9A9BF55F142D9E74A4E3FA9695E86F7
-:1007800071FE9EFEBA6002EAED138776E3C37A9C9F
-:1007900047E2C3C895E7EF433F57347C488F92AF99
-:1007A00074617C2835C8D7CDDDF850B7EEB2948B94
-:1007B000C787B809FCFB11DDF820E83FB536F82003
-:1007C000D2AF55E083D5057C0CE0A1221EE485E282
-:1007D0009E921E8222FFC00C9FA06F48943C8415FD
-:1007E0004A492FEBBBE8FC03110F6D12F1506F3D2E
-:1007F000CF97ED5C1933D5987FA0D1BAA739EB9488
-:10080000F03CFE0879B22FE3F9C938A78C6B7E5E05
-:10081000EA79059F4FCCE5E71C8C1E670AE0FD5680
-:10082000403F9709CFDF223C97F70F841E77DB14F8
-:10083000FD6D1C7784DD4F79CEA0EF1DC6765BF78A
-:100840003EC9BFB72BFC90322FEF3BFBCD12ED7EA4
-:10085000BC2F29FD669B13EC3BF0BCE7B3E014FA18
-:10086000CE2FC629D0EFB43186F21A172A6078232A
-:100870005FBCCAFBD1788AEB79281FD75BE170A1F6
-:100880009EDF9C34350DF946CD5A95E47A34FB460B
-:10089000D25B0DF01BA2B77ACE6F5201BF08DF7C8E
-:1008A0000AF19B74E0379CFFE80CF53A2BD29DB31C
-:1008B00027BFD9DC0BFC2F92EF7C83708FC077941D
-:1008C00009C506BE6399F01DF8CE4FC6336E1F8A68
-:1008D000FD633C80F68FF415BE7FB33EDBBD6F2316
-:1008E0007D49BAFB5F4067232744A6B3FC09DF8D2F
-:1008F000CEC662FF087476E504239DE913FE67D235
-:100900005905E1DB05E8ECA3F14CD8B7D71AF48A16
-:10091000CBD5F6733938FFFFE7FCED8357723BFE0A
-:1009200042F9DBF87331FE53733EF73FFCA9FF6BCE
-:10093000FDA9CF4EF81EFCA9AE716EC23FB35FF5A4
-:1009400093D1FABE09BDC495259FB64A3E0DFC1849
-:10095000796F0DF033E4CFA9555D9F3ECFED4D2D5E
-:10096000DE4DFE86D771BC74C1AFCD7C19F4CE3795
-:1009700026FC1DFD0D7F2FBFE14AE167BDD07DFB49
-:100980009502CED1EEDD3709FBBE09C6C07B7A5B8E
-:1009900057DAFDCDB0608FD0AB47D45E773512D932
-:1009A0003BCBEC71C15EEC26F977245A1BBC2F9E21
-:1009B000CC09DF1F8B28B7BAF767D293C3ED26F7B0
-:1009C00025D84D33261AF5646B2DB773AD20EF286B
-:1009D000AEAF9704905FA7FB94764C0DF6A6D42992
-:1009E0002807536B3D940F7FA9717D331E458BF310
-:1009F0007FDF717D73DEC0FF94387FD14461CF9B70
-:100A0000E2FCD2FF6A8ECB8FB0B796917CADB6E098
-:100A10005FC060CD7B3FDE71379EF71C07DDD330B2
-:100A2000E703448BDB8F48B607E3B3A3C7EFA5BF4B
-:100A3000E0115BDDEB68873FD268A1F335E70DE499
-:100A400025F0FCF1B313766DA3FC1FA90F57093EE7
-:100A500053AFD8E9BB8E557EE2335E7D5723C693F4
-:100A6000539DAC1DF5ACB8896EC23F354D273E6332
-:100A7000ADF2125EC9F8444D26BF37172BF04B1D5F
-:100A80005AF7168E9F7448D530BEBD119B02CF48D1
-:100A90004059897AC4180BE545B42975E4F76855BF
-:100AA000DCF4F73F92F25CA41F3D95A4FD7E36AEC8
-:100AB000BF1FFF3B2507A62F49433EB8B6B1310DF6
-:100AC000EF27DE3491F3877BA79FAEA6387A2EE816
-:100AD0007F0A9586BF672BCB1DBA22FEDE929FF25E
-:100AE0001161DD5BA8DF503BF9D954FD81DB900F2C
-:100AF000A8974D25BC6E555C7316E079E5D8498FF3
-:100B000069CE19357B11EC6B5D3F4F59169E6BD248
-:100B100050DA677352FF44D447D70DC8A6F95B1467
-:100B20006F5916F61B6021BA56457C7E5DCE92D772
-:100B3000F0EF8034A55B18DE3B68CB39DD82EDDA5F
-:100B4000C6F03F82635EAFEA32DE93C20F1F21FF21
-:100B500056D3785C5C157171D514572ED51599FF55
-:100B600048718758C1B76A7256CFA6EF2738ED2E65
-:100B700044B2A6846025E1C74A1BC3381DB3B61A28
-:100B8000F4B4BB1B8CDF7F71E619D7D3D27D3F2134
-:100B9000CB8B7C86FE062CDD5F48F2227E20BFE5F3
-:100BA000497FF1BC1E2BEA019BD717E17CFE51FE69
-:100BB000A3FC47192AFF2F0D22483C0080000000AB
-:100BC0001F8B080000000000000BC55B0D701CF5BA
-:100BD000757F7BBBB777279D4E7BD2C93E816C5614
-:100BE000B6446410F25AB68494D8684FDF322EBDF2
-:100BF000387C88C476CED8B8CE34932A4E49EC845B
-:100C00005667EB64C95FB2A414E44C3AD3B34932DB
-:100C10006DF08042661AF33967700821D028811080
-:100C200032930461885B529A310127A2434BDF7BE8
-:100C3000FF5DDDEDEAE4AFB81331CCDFFFDDFFFE91
-:100C40003FDEE7EFBDF73F00F0C00200D90F003AEA
-:100C5000C0A6224F122200E7AA200D95D8F74E9782
-:100C60006941800FE9AF25DB1EE807C8F8B2FD60D7
-:100C7000AD0A660DF0DF87A271CD3B6E5AF3C29FBD
-:100C800073DEE16AB5371D9C3BAF3DAED594001ACB
-:100C9000F2AE03D225AD73E6673A8E4FFE4C866AFC
-:100CA0007DEE7AEEEFEDEF3615AD2F86DAFFBFF170
-:100CB000F3D175A9E90128137D68C47353BB44744B
-:100CC00075A48302820E039D8DE90CFE73424A0CCB
-:100CD00057D2F9C21EE39B30970E762B6B73F897B1
-:100CE0009D5F16D347ECF9710BF2CE801908D12B1A
-:100CF000FC0E69AFE1B63F449628110F3F076BBE6B
-:100D000028C0B31FE2FE8E67F905DA82ECBCF2065A
-:100D100095C72F57FB5E6C5885CF5E918D6FEAD9D2
-:100D200079793F95C00B80FD5D65F6BD62ADFB91A5
-:100D3000232A64ECF1F8FF0933CC749AD8783F2465
-:100D400090BE3FDFF089E2441E39B0DB6569E7F70A
-:100D50006FE09CC07483F437F1DFA95F8C4ABCF864
-:100D600009F13CB5424BEFC7E7FBA5F4FEEB68DCAD
-:100D7000DD82BE361F0A2D3EE05FB40AE9E8B5F811
-:100D8000E4759F0BFF94054C278B38397C58C27350
-:100D900054D1B907ECF974230348A703CBEB56EC05
-:100DA000D7E9FCA3FFF26DDCC791E37BDEFA36BE28
-:100DB0000ED4D68D34E17E0A0C8F21933C7FEAC499
-:100DC0000964170CD5DE334AD36E1D954C0DDFFB3D
-:100DD000B5E03199CEE8974C9A4F39BC90CF13DDEE
-:100DE000EA948309C958504EE71B9380F85268383B
-:100DF000DFFBF49CF3E0FF4788CF2C9F39CF916E47
-:100E000048BDDEC9DAB9747FC5926705C727ED7999
-:100E1000912EE35EFD16A2F3F83E199238E5F82E06
-:100E2000548AAB007E6B4E7E7A3732FD9E412FF3A3
-:100E30006122A6A6251C3F51A4DDDE4BFD328F7139
-:100E40008C898AFFE3B946975DCBE7B2D7FB6C8B01
-:100E5000CEEB8DC51694933EE2B8F2F80D73E5CF54
-:100E6000BDFF4B95BFED668925EFA340F3C3E42D8D
-:100E70001ED227BF35E63A79B27E09ADF7731984E1
-:100E8000DCF441BC682E7D06C91E7C242B27AA25D4
-:100E9000477B23EB7F4CD3CF27CF6A7ACAACACA376
-:100EA00075A08FE8BE2CEADC9F3DEE7316BF7C690F
-:100EB000C87843D4664CA8A376CA94B03DB7E10B7A
-:100EC000DA5A7DFE757C90336F25CD077C6E2F241A
-:100ED0009858C4573387AF7B0AEBEE24BE0CDEACC8
-:100EE00002CB9F9BCE17E8AB4AE6A4142279F80800
-:100EF000CB4712E5A31AE7F1469D72187F72154C95
-:100F000007059F92FCBCDB243E255ABCB376C89FE4
-:100F1000632F41DFFD1B19E7FB6AB7AAEFC77D7E90
-:100F200035BEEDBEDB48CF5F900D89DFEB6C0FEF78
-:100F3000B1D680D109968762CBEFEC3C71EF6BCFD5
-:100F4000138FBAD5D7896EA4C7B37411F6D9F43705
-:100F500066D73BDC747A7829D221359C7FFEBB4A68
-:100F6000F5CF11FD6C3ACF37EFACFDDE7972B27D73
-:100F700065B63F529008C4F09C2341038D00BD3FED
-:100F8000C5EF6115CA65F9FCFC448AB23CBC46FF5A
-:100F9000C4713DEDA616C3BE7C02B7BE1CED6291C6
-:100FA0007ECB7A7CD511797D23D17F6BD0A3C939D3
-:100FB000FA3570D00B99201102D745B95B07D31BC6
-:100FC000D7E338A8F2B29CCB9115FC7C4B515CF175
-:100FD000607B6D6C09AF677FDF03FFA0ECC0E7CBE0
-:100FE000BDDA2B2427A988443BC2E74840DCFA5AE3
-:100FF00005CC10B65D7ACC4F7EADFB095A08A02512
-:101000003C1E21BF54F7D8918A04E975D29CAA41AD
-:10101000FE842D765DEF9B8AB7E17C032FCAC61E46
-:10102000EC8783DBD601CA91F47090EDC400DA79C5
-:101030001FF25D0976BE45CFD79C0568CF91A79674
-:10104000193FB4E7D8BD18CE9CDB6FF3973BC6774A
-:1010500068958EF732984606E9D4155DE61857D4A0
-:10106000B04AA3FDF6E82B1CCF6FAE69767C0FED7E
-:10107000CAE969ECAFC6FF88EF32883EBFAF249C57
-:1010800080FD9CEF15C8E9E3FBB5B1A2C819724A0F
-:1010900037C28DA447C8976307C8FEF4FAD96F0D0D
-:1010A00078E184540CA4FA49A827629BECEF254B05
-:1010B0005E93B14AE693147CF67D96C327A63D84E1
-:1010C000B3E031A827FBFA8F9A7ED28343AEA629DC
-:1010D000F1FB280ABA8E7C4218960CD4F37373691C
-:1010E00009F93929D983FD45382E2A44119EA37167
-:1010F0007ED8FD15310E16D1380D9215D8D70C2893
-:1011000020BE56E03C9F2DE1EF923DD677D788EF89
-:1011100092C52562FEBA7AF6A3990E6C8F82013EC3
-:10112000B63F71044D6445FAB8BD867685CF1F0081
-:10113000A39EFAD530CD760AD92F517F214C6AC2B1
-:10114000C86784DD9E56C267FCC2EEE7D397ACDE6B
-:101150002870C6E6070EBEBDC5FC12E9CDED773698
-:101160009C1777283B9F71E8ED23315DF8C39D5DA7
-:10117000AC27CACE67F9FD4BB1F81E9A8F48EFAF86
-:101180009F4BEF3A350364BF523130923845EAD174
-:10119000B5D1CDC8DFE4A37EA31AAE1C3F2E950FB8
-:1011A00069D00A88AE72DFE5F201D8CF074FF88F19
-:1011B000EE676134D94FFE097CF9F6E5F0C5CD0F35
-:1011C000B8B714A0F9C276F4EB5226202D657A98B0
-:1011D000D1FA2CFDB19F5C66D1ABC4E2872CDA8CCE
-:1011E0006C3D574AE6E70BCD575A92E5CF85F8128A
-:1011F0008DE3FBFA2C7FE43E938967FB691F9C65B6
-:101200007CBB4432985F4BE5B887FA8552C6023DF5
-:1012100069F69B21D0983F57411FB711EFF466C67E
-:10122000C33B7121C2B31FA097CD89C752C1567F5E
-:1012300025D9D71AC5F060BFB6C8134F231DAF56C6
-:101240002043E72B572049F61C9101CF9F7A14BD0C
-:1012500015FA9914BA690F7DB7CB9F4E49D9F5EBB2
-:101260002CBBFDE3A26F69D3B5593A9F26FBB55C51
-:10127000D0C3C3F6673243DF47BBC118D0E7DA33C8
-:101280001C97942D3B45ED267AD1CC744B86B02F1C
-:101290000DFFE07DC219349F82FDEFC512EF923F32
-:1012A000259C1E2C61BB345D48C07A2E2E30095718
-:1012B0006CB6D6E9BD495F1CC77D6E1EF6BD4EF308
-:1012C00041CAE7C405EEEF750972BFB7BF9B952B06
-:1012D000F7F797A907B0B3ECA27040ECE1D5C5D3FE
-:1012E0007970FB2CCE243D29CDFD4EF0498D24187C
-:1012F00077A8A42FA5179EC7EBC22FF63C5E145CFF
-:101300009AC76BE117DB4F6D83B35E65A9B54FA438
-:10131000D716B0FF224CCF4D16FD3E4DFE2A44F4A9
-:10132000C44005CFBD15E22AC9ED5F2184261CBF4C
-:1013300064DFD610E30568D7883E52E663F287D7AC
-:101340005F021D2D3A6DCABCE5D5C92EED2C823742
-:1013500072E337EBFDBB1B3E21E274BFBFCA9F1394
-:101360001F169EF8A09F8CFA9EC2BF7FB105B73EA4
-:10137000F8926CC895F45EE0E60008FF5D487A8A52
-:10138000FB2E7CE2CCFFD0F84217AEA69921675E17
-:101390004FE141C6B3852155679CED92331B47C38E
-:1013A000070207072DEAE5CC2B115EB6E31E9E5718
-:1013B0009ABBEE0D163EC757B10F2F02CFBB713A45
-:1013C000CCE273F13E1854859E609C9971C4C17A39
-:1013D0005E3DB3F76D7F57A6C62B8DDA3CDF5B7C95
-:1013E000A8A5401CEDC2C20A48EFC6FD0E0FEF884B
-:1013F00015627FAC0C748C3061A8F38B12E18DD632
-:101400008810A57093C085B404D8713CFE85FF4355
-:10141000DF5F83EFB755040DDC192C7C1B7132CED6
-:10142000737785DF30F1410AC4FB649347C4934965
-:101430007899F0E8568B3FDE2704CE64DEA01E1EAE
-:101440006C15F86AEB89CFAE23FE8E94DC6A64706B
-:10145000DC56B44FA584C746BD8CE710D73970BFA2
-:10146000AF290707E2FF771FF13AFA5E174E3CD02B
-:101470008A3810E5DBC681F7B702EB19ED8BFCC9A2
-:10148000955A078211B6A73728539E7CF9379B1FC0
-:1014900036FE7EB24CD0D9FB9EA00B06CC3BE8B901
-:1014A000EF3D118FA1010F362C20EF2FE8E76B40A5
-:1014B000FAD0D3F7843FC02F79DF26FE47FB76E3CF
-:1014C000619F0B0FBBF76BF3E1619B3E8DD048F43E
-:1014D000417CCE38C13E8FFB1C4F607CDE8E42F1DA
-:1014E00054BF9FDB4CBFC6EDD3FD516E4FF5EBD023
-:1014F0008E00ECD9FE1A6E9FEB37F8F9F3FD4DDC48
-:10150000DA74984B1F91D7BCC6DAB3523B15273F0C
-:101510007A55BB875561EC5E0FD3ED1CCA27295F56
-:10152000C8A0DC1B8EEFF6A429A4B7E39F8596BC68
-:101530005EEF3B7BD287E347CAC1D883DF2F6CDAEB
-:10154000C672B6E6AC27AB2740714E81234F10839D
-:101550005247BFCD7FB5637C87B6D4F1BE2436CD6C
-:1015600076AA2B7ABD639CCDE77FA2380BF737D6DE
-:101570007E5A23BAF6E82B1DE3947B91FF7514FF86
-:101580007CCC312FC8EB0CB2D3251B9C721872F1A6
-:1015900055DD7EFE38C8E6F3DBADCE78683EFEBA98
-:1015A000E5D5A66BC92C5D455C99A2B812E95AA293
-:1015B00009BADAE71DB1CE6BAFAB3489F35DE9F858
-:1015C0003244F16565BEF8F24D8BCE17882FBB9D76
-:1015D000F1A59BAE178A2F17B439EDCAC5D273D3C4
-:1015E0006291772B7941E6B845EEEE633F583A2594
-:1015F0001B5D64122D5C56443600C76D6A50D3845F
-:1016000033C7603A4AFEFCB0845445792BAD35CAE5
-:10161000C9CE3C14365EE925DCD823F280CFC46EF7
-:101620008F12EE18DC7D348ACE0A9ADB3C6CEF46D2
-:101630006367387FA1E8C0F90B6CCD741E7C628FA4
-:10164000B7F38D8737AA6909C71FB6F28D877B6606
-:10165000F38D5CDF986810F9C68FB6E9569E29199C
-:10166000A578E5AB1B1BCBD95929D8BF81861BAC0C
-:1016700027FB035A88E2E8D4468F46E79257DDFFFE
-:1016800005928F4352DFBE2A8ADFCA3C9C774D8584
-:101690001BCB37E3387913C218EA6F6C7C956CF674
-:1016A0004499BEAF8ABE0F5731FD0657DFEEA775CE
-:1016B00046C20B7A283F32D2E1611EC98433423CD4
-:1016C0004FCDF9E21E771D40268B4BF15BC4935141
-:1016D000C95F11FEC8C9FBDBFCDF1F56393FBBA544
-:1016E000EDC1A3C92A7ECCF66BA15D97D9D8CA7982
-:1016F000E6738427A4F9EB327BAD7CE7ACDF893A53
-:10170000F793671DC605765D82FE743B4F8B7FA9FC
-:101710005B3AD3E447C721DE4DF633193C7F1D44C5
-:10172000099EBF0E325FDD63579BC8A37E99F82EDA
-:10173000EA338E7A89D26DD545ACF8F530E5C349E8
-:101740001E5C75127B1F03D67CA9593972D54D5684
-:10175000ABD67C06E4CB5FFFA9F593FBDB44BDE68B
-:1017600052EB26DF6D03B15F2BDFEDB5F87F9D3CBB
-:10177000B983E4F1CF9DEFFE6EDB95CD77CFAD134E
-:10178000A5595FE0C4D93758AF972DB0F0CBF9EB2E
-:1017900040FB09E823FFC657202EA5FA87D54FDE68
-:1017A00020E675D78502561EE5876D4B45BC45F68C
-:1017B0008498AB188B89AE41E53B490DCF51101C85
-:1017C0008330B6BEC8E624B52D8B75AE0F8D2FF3D2
-:1017D000B0BF1A2F4A1C1DA4FD2F0BE6D58B572D29
-:1017E000FB376CD56F48803DA46F92AD1C90F02004
-:1017F0009F2640F0F9EDB6308F57B4D1A6BB506E9E
-:10180000DE247928E3F3E4ADFF9C6913F59F9CF98E
-:10181000BF41729AB226A77936E33CFF65C923908F
-:10182000E35840C18E58CFAF8F36112EF85D9B26FE
-:10183000DE2B2B0CD287F170FEF57E679D072815F5
-:10184000D398C5470B378879C02FBE3F2C9DED3DFF
-:10185000BD8AF9CAFA44FBA0F7EEFA977BFE408DE9
-:1018600033BE512B9CE33F983D87332E3A344F7D56
-:101870006C51BB90D796C542CE483EF6E4910FB767
-:10188000BEAB94F7A478AA3D6CAD27EC4E50996A94
-:10189000A57827580B06D71495937CDEF893552727
-:1018A000A657919D0F191407297E3495F5D938D183
-:1018B0007DEE0BC5798A02496FFDDC780FE7358B29
-:1018C000EB859F49E6CC774DBB901339371EACA40E
-:1018D0007044BF85EB785407A4FE2E5F6F3E3F5DDA
-:1018E000DD76FEBACE9138C61114A43E7C70DF16A8
-:1018F000ECBFAB79341F8FD1F3D67534AB3F5BD7D8
-:10190000895F5C5D67B4BDA4A7EA52EA3AF3CC3BB9
-:10191000EB8FE7D675DADBF19C6341515F99ADEB54
-:10192000DC1AB9A87C0E587EB9C4B2CB453D561C12
-:10193000B153E238E2E9867F3FB09CE4ACC1CB72A0
-:1019400000072720574FD66DD0BF564A7EE6551F59
-:10195000540BBB66D27C765C6CD34FB5E66F7DF0E2
-:101960000585C68F977B1A793EC8F83C5CEC4EAA79
-:10197000562B53BB5CCDC8C5346F095875F48C44E5
-:10198000CF6348ACDCF86064E6A76DC59427098294
-:1019900041266824A6ED2EA67F501588F04EA59E00
-:1019A000267BDBE62F74D8FF911E55D8D76A715F6E
-:1019B00066FCA4FEB5AD387E68678071D3A10A8F3E
-:1019C000D0AFA4C4F5E40ECD19F78C4F2E1178ECEE
-:1019D000A0D7A07B22C727C5F82DB1C6B4CCB8DBF1
-:1019E0001917F5E8CEB8684B79FD2B841761D0CB79
-:1019F000F978CDC2B537D738E3A4A2CABEE708A7A5
-:101A00006C1A1478786FB464C116B47FBF6AD71D9E
-:101A100071E2E6C1BBB96E34A802D7534736AAAC0F
-:101A20001F23DED78F6C61DC58C0749CD8A8962722
-:101A300072F4A5B4C367DD8B10F803E1656232CFA1
-:101A4000FBD20E617750B0D98FDBF2F2179F117481
-:101A50000E55405A271CD7B3234371E578059E09DC
-:101A6000DF0F46AB7A4ED2FA2FCB40E774CB6165DD
-:101A70004735EBE9AC3F6DF238E8E4F5C5FB687E2D
-:101A8000B81974B26BEDDDD8A73CC00615283FE04D
-:101A90008BFE2D9FB704FB01ECFBBB47930AF6FDC1
-:101AA000558995848B9FD975C7702C42FE4EE8B737
-:101AB0006FC3B6F82768FC2A2F04687FA04B51DA61
-:101AC0005F52DC6770EBC3DED4F7DB894F7B0D8997
-:101AD00059B4A967FD76BEB7142960DC34EA8D6F6E
-:101AE000667B749B5F4BB20F9CE638C2FB151F9060
-:101AF000DC4DECFA4D19E1EF1FB58BBA664077C6A5
-:101B0000D77E1865BFBDDA9CDA40DFAD6E52A9E220
-:101B1000014F379F61BE4D34F80C1FEE63A259622E
-:101B20003AFFA1C19BA6759E52A7645AF7A93FE050
-:101B3000DA95F9F43BBF5ED97AE41E3FD2B4DE4FAA
-:101B400072B117A66E25FA2467449ECA3D2EDE2187
-:101B5000FCD5DED46D350AE7B354AEB72B670DB3B1
-:101B600018670FCFC4FF9972AFC97645C449E59E87
-:101B7000A484F30DF5887B194345896192E721948C
-:101B80007B8E9322E23ED27879C4D89FB3DE78F37D
-:101B9000ED3564CF5E6C0830BE1F38F5377711BE67
-:101BA0006F95DFFEEEC3145755A8CCCF216FDFAB86
-:101BB0001407251B02BCDF538B54F0933D88DCF5E2
-:101BC00000C5D9707C03E4CAEB44B7D0D3890AA11D
-:101BD000F7D2C31B380E189764A6B359764C223C33
-:101BE000E6EBB6F34E22CF14B3CCD9C48647380FF8
-:101BF00075558FC8A3C6BAAD7C931C4CB25CDE1879
-:101C00007880F4DF54BC8EF878CD5967BC7C952B76
-:101C10005E76E7A3FEB7DDCA475879275B2E43D629
-:101C2000988926CB4EAFF2A5851CF6956BB573F55A
-:101C3000FBDF2CFC3CD5EFE77B643FEDD7B81F32D0
-:101C4000DFD95D8AF3BCDC1FE5E77FB9FAA894FB16
-:101C5000DDC8AADBFC3ADB93E928CDEBB6236EB9ED
-:101C6000D8DF5EE0F027F63E8B9A5BC5FDBBB36C18
-:101C700091614D70BA8D7D234C0573F17EA65FDCBA
-:101C8000737BDADAE729DAA78FF264627FCFF5EBAC
-:101C9000DC3EDF5FC3EDC60E10F500DB3E5C83F675
-:101CA00001E9D05E21FA640F88FF2591BB384FE629
-:101CB0008B2A1AE9BBBF623423E5D88789A2BE5FAD
-:101CC000DC4D76BF2CC8F2E83ED79A0E4FDE736D1E
-:101CD0006ADEC176E71CAE43F4473BB39DED10DAF4
-:101CE000055E77837A27EFC344BBC476A1EF6B7799
-:101CF000B05DF002C9B9DB0E9424857E277491BFD4
-:101D0000B3EF09CDDA055C278DEB3C8D769DFA4368
-:101D10006807689DA1E6D7FF9AD6FDC3FB057C2F17
-:101D20006A62E32B6C175E3C8736FB0ADA055B0FB1
-:101D30005F3B153B961BCF67F9BCFE8E13821E1AC4
-:101D400008BAF6C6F3C48997CA67302F0EC7A495A0
-:101D5000E93B45DD51653ACC5B774C7A0C4A0B0C7C
-:101D60004C2ADD56DD11A8EE68D71F73EA8E05CE2A
-:101D7000BAA39A4E31BE495B75C7DBD78ABAA35A5C
-:101D8000301DCCEEC3AE370ED2A3F26C7DFEAE8E0C
-:101D9000C4AE8E866C9D5197441DFCA598F9657A5A
-:101DA0000E9112F6FFEE3AA55D8F4478272572EA70
-:101DB0009B75F8DC5F92AD7FB9EB99F6BD8C3A75F7
-:101DC000FAD801A4CBC09D7EC60FF6FE061EFDE824
-:101DD000AB8948F63E805DEFB4EB9976DD13F73DB5
-:101DE00096BB6F7802D8EEC063FEA3E4DFDCFBFD98
-:101DF0005E2C717F47599E7D5F647D711D58F32372
-:101E0000EE227D7ECDA2A33DEE414B1F97AB22BFBC
-:101E10000D2195E39DD607832013CE2E528F915E20
-:101E20006C86E90EA2EF4058E0BCD4212FDBC9E359
-:101E30001D3AF3AF4C35F93E44D99703C66E9C2644
-:101E400075520B51FEA9A7DD3CDEC1FB18BD753DE7
-:101E5000ED03713BD9BB5F57DF17E17A3FDD7B2A8A
-:101E6000A6F8CF584C7990173AF2DF576A597C762A
-:101E70003DAF5BE4018ACF5201E339BE57FCA4C2F7
-:101E8000F3F5E014663DDF5F6A574B681E713F75DE
-:101E900020789AF9D552ED5BC179BDA2FC71E0B30F
-:101EA0001D226E5D8B73A938CF675A13DFA77D5350
-:101EB000AE34CA722CE2BB17C84E0AFB75AFA7310D
-:101EC0009B072B96132FD078382E29E41F7D96DCA4
-:101ED000D871E23BADE68BC477E48749EBDBF78052
-:101EE000ECF55FB2F890EC307F4AE35EB7D6A9D349
-:101EF0009231D2C3BA04CA83C4FAE3AAC30BB9703D
-:101F0000CBAB2D6FB375784B0E254DD46B51AE5EB8
-:101F1000E7FD3EA59FF448546F4F1C3D40DF5E66D1
-:101F2000BDFBEA36F32DDA77716BFC3F69DE5FEFBC
-:101F3000BA83EF055FEC3D8E96C57D51AAE30F0590
-:101F4000046E7E286638ECDDA24EC19F459D022FAF
-:101F50005D8F3233C5F74B0DBEF70DB09D71B46D7B
-:101F60009F46FB138FBF599DFD3ED50F93540F9A8B
-:101F70006F1FDE7D3B38AF3B50D1EA27FB83F6ADC8
-:101F800098FA43156634771FA92221E7C945226FC5
-:101F900041F9B464CE7DF2924E99CFD35601199295
-:101FA0001D5F50D4DD7CA8B83AFA1F9FD9C4F78BC7
-:101FB000F1F924A518AEEAD4455C1E31C0A478B36B
-:101FC000220EA4DF3E2DFB3DD551DB2AFAF8BEE5FB
-:101FD0007CF3C851FBFB047F7F53A7C6F3AA118F84
-:101FE000230F7021BAB9E9324874AB9E9F6EEA455F
-:101FF000D34DE89D9B5E8D16BD9E097F91CF071F37
-:10200000B4B19EF9343C27B6AB3B857D9183262441
-:102010008AC846C51141529EBD0FA80E6DD359D630
-:10202000049D65AD8FBFF3551890B881E89260BAF2
-:10203000B8E9807602C84EFCF0D12311C2A72DD892
-:102040008F0AFB013E6CBFDE21F862EBE93AF849EA
-:1020500050E4BF9DFEC26D4FEDF6212BFFEC7E2EAE
-:10206000750584FDD0C141F722EBF70BC786EB194C
-:102070001FA0FF4CD2BD98CEF2EA02EA5FE93AA275
-:10208000BB7EE8AE13BAEB8359B931FDB4CF77B557
-:10209000D3C98FE79117BB3D60E9DB60BF3FAFDE7F
-:1020A0001D407D27FE0D359B49AA1BED0D4F47595D
-:1020B0006E4EBEC5B858794136085F2A8AE073E78C
-:1020C000A269E663579309546F3AD0DFFB9DDC7930
-:1020D000BFDE9AF84A27CA49A13669D23C41C824D2
-:1020E000C9FFAC2D35FBF2E1A621CB8EBCD31ADFA4
-:1020F0004DDFD1B575E2FF9B31730FF52FD66ECD55
-:10210000A74F8A4DBB4BD6A7D3429F9A76B03E8D40
-:1021100054F431CE1AF9894C482A8B232D7D1A6943
-:102120003EC3FA6EEB55DAB63F4D422F288F40FE84
-:102130003B5461B2DDF896A54F0AEA09E993CFD284
-:10214000A790961D4FF9F136A2333E572AA6F9BB48
-:102150005093A57FA44F41BA3F0C8C038650EF28C3
-:102160002FE2D6AF962AE1379F684D3CD449F862FA
-:10217000D17ACECB0F55FCBE94F18B25FF59BC5BB9
-:10218000CFFEFCDCB0C7207DA823005D9FD503FBFC
-:10219000DCAB6764C8206BD6CC48DCDE3453C86D3A
-:1021A000CB4C805B73A694DBD84C98DBD699ABB94B
-:1021B0006D9B29E7B67D06F56025EAC34C25B79DE2
-:1021C00033D773DB35B38CDBEE99953CAE67660590
-:1021D000B76B673EC6EDCD33CD629D1A71AE3CFA4A
-:1021E0004065B02BA00F46128A480F3EF32ADB77DA
-:1021F0004DE53B4AA97023D7897CCA34EBC3B1268D
-:1022000061EFBB82824F6E7D78A735F1AB7CFA30EF
-:102210008B6F15D088FE2A587F2EFC80F8E737F4A4
-:10222000BD8D7BD5A8C97286F8E40CF1F37271C23A
-:102230002CCE5CAC321EB571E6C822C49995599C6F
-:1022400039D42CE2B2D4211FC76F5B2471BFECEAF2
-:10225000B6C47FB37E82C813256EF56B849B53E1B1
-:10226000CE6890F27A7B65A07C01E2900F789F4A5D
-:102270005CDC67BD487D7E3326ECBE3DBE0E4E7BEA
-:10228000FA2E01C7FC9AFED93CBF5D28B95C3FEB32
-:102290006D13764113762155D137CC7569975DB0B2
-:1022A000FD2CD2C3611796765976C1D2F3920AE11A
-:1022B0002F4BC82E207D9675D976C1E967151B87EF
-:1022C00074DB38C4B20BDDE23BC4ED0E3F8BECF6A1
-:1022D000430E2E46395ADE950787B03FCFF1730380
-:1022E00055D531FA2D41F82CC4483C4333FA5A23D2
-:1022F0008FDF4969F5AC07279536C8CDAF5CB29E34
-:10230000856DBF63B2DF718FB3F56DE8648F38A759
-:10231000E5874EE2F9CD1C7DEBD2843F42FF73335B
-:102320009DD3AD6F2D8BCD443CCF3E3FD925F0FEE4
-:102330008FD658B81771A511647C9F17377C92F817
-:10234000D7207EA7F118DA9F8EEE644AD159CF3F8D
-:1023500049EBAE6E9F92290F7453D3E8CB541241D0
-:102360003DFD5457C3E5EB6953AB55EFDB592A2EBE
-:102370003B5BED85E4DFC645B61EB8C73D5469F644
-:10238000E6A3C7B3163D06863D3D74E1CF968B9319
-:10239000CA52C63F79ECAD695C117B7B71F8E324CE
-:1023A000FA41E2FB79F0C7817CFC9F0F7F8C77CDEF
-:1023B000E28F31E2534BADC01FCF76C179E39BCBA7
-:1023C000C615B1D34CB7CBC5150F769D1F577CA74B
-:1023D0004BD84D459B66FB11BA4C5CE1B613881F88
-:1023E000FE95E96308BF6BFFDE842F50E6F82FB43B
-:1023F000338FD338C20D7479EC58B03529B11EC46F
-:102400009FA4E7A3E61296A32BA50F88137FD09570
-:10241000D3BF905E5CF4B8C98D9C07B4EB997F0C78
-:1024200084EA283FB2D32FDA2F15848E513BD62F62
-:10243000F2D07F0C2C4E53DE6CCC0B5C3F18940A10
-:102440008C63223FBA9C7F5F037D37527BA6CBAE65
-:10245000CBFF9DA35E1AD6B63DFE6669BEFD88FB26
-:10246000BD948AFF90EF8157689C3FB7E84169208F
-:10247000F6CFD5058CFF00614B538EDD4F75AC1345
-:102480007172A59FEB79322867281F3F4C6BF1FED4
-:102490007AB98E19B0FC212849FDE3BC5F9107B5DC
-:1024A0007FF7B76FF5FA627109793B8FB7E57F5F08
-:1024B00070D4AFD53AF4DDF1BB6E772BAF38A5B54C
-:1024C000E17EC77485EBAE078D4880EB2615227B35
-:1024D000EE5FE489A7F3E8E9B5DDB3F722785F6141
-:1024E0006B5FBE0E11AFCDB7DEFE7EE73DAB82DA8D
-:1024F000B849FEC45FD91727BAF9174524CAABCE2D
-:10250000D2BB5BB2EE69189916A4F7B0A587053562
-:1025100093190FD139BC6D25D1D65F938633344FD3
-:10252000ED24BC41FEA2D2DF9B6FDFD759FB1EF624
-:1025300026E38493862B15AE5F0E57E6F72F25DD35
-:10254000C2FEFA17EDE0F1B048E1FAB37B9CD22D60
-:10255000E4689FDAC7758CA145F7F37DB721FA21AE
-:10256000CD47D1EEFD70E681DDF8FC50FFF6C7DF08
-:10257000F4929C26B8DD77ED7E8DEE711EAAF76889
-:1025800094870BFB337EFA7D6678B5C87396B4E307
-:10259000B8DC7855AE08909D0DADC27972E2D031AD
-:1025A000D002B4EEBE906D1FA7FDC23E0A792AB2DA
-:1025B000C68EAC1275A9917576FE5FF02FFB7E7CFE
-:1025C000BBB82FA7EAC079685197E2D49E4EF7674F
-:1025D000EBC374AE324DD4A30E59F23568E5D9DDA4
-:1025E0007439B4788AFDC9A13553BDE43F429ADFFE
-:1025F000E826B93EEEDCD7DEE66907DE1869386DFD
-:10260000EDDFBD3F21F7CAD36F093B69E1FE90F1D1
-:102610007BC659F63DAEAED5420F8BAD7BF4C5916E
-:10262000B849F3EDBEF6B749AA131D2EB7EF167CD5
-:10263000DE790F03A6191787565B7539F96DBEFF52
-:102640000BB78A7B12F63D6F35A23AF202A5AEFBBC
-:102650005921571FE40DE7BDCFB6F397479F3F952C
-:10266000C3CFCF773BEF835FE8FB3FF6A79F3F8564
-:102670007E6E6CD5F9F5CFE6D3E1FE266E6D39B4EA
-:10268000E5324C47AC9FFFFBB1703C6FBDE5114B91
-:102690004FDCF2EA96D3625F9CFDFEE81AE73CF756
-:1026A000597A7E9F358FBA18CA090F8D86855E8E3E
-:1026B00006A0F7913CE77AAC5BE5F159B977E28285
-:1026C000A2CBC5052B5AADB8A284F56D6C55EB7342
-:1026D0002437EF915EE4D82777DEDCC6054A8FC049
-:1026E000A5CF845589FCBA169C66BC3CEBD72D1C43
-:1026F000E0F6EB7E6FB297F4CF5FA9DA7689ED470B
-:102700006577E01BC920FB0329D70F1ECADCC9F37C
-:10271000865D797388387F87B2B71B984E61DDB2CA
-:102720002FDD8AB887356A42EE3D9A31CFDB336FB1
-:10273000E8E2DF1FD838A292DE1F9CE2DFC7C03D6F
-:1027400090BBFEDE964DFC7B880BF1DDDE17DDCB0A
-:10275000CAD59B4BD58B976DBD084080F4E21CDC3D
-:10276000CB757418ED76F821AE282C601320FEF09E
-:10277000984AA365C7A4ACBE409755DF4E883A3D42
-:102780005198BE33ACCFCAE99604C5D790E1DF1D9E
-:10279000DAF6E51CFC92D74D3E2D49B3B8E96A0C38
-:1027A000DFE9F78C4B690B9A875AF7FE9780C1CF08
-:1027B000AB20CEEDB5D0C76D0D8C727B1D4C725B1E
-:1027C0000B53DCD6C1596E57802ED3222BC1948176
-:1027D000AF5E26B87F2324B96D86C4FB742774B01E
-:1027E0006CDB0AB257EFBBE864D3398FBE332EB42B
-:1027F000E961D3FD2132D20D17E66B2A2CEC6F5B19
-:10280000D314E3D7A2A01DFF0A39B7E7990FC7BABF
-:1028100071979F70D7CAB9727021DC65E3C4FF035A
-:1028200008E97101B048000000000000000000004D
-:102830000000001800000000000000000000004040
-:102840000000000000000000000000280000000060
-:102850000000000000000010000000000000000068
-:102860000000002000000000000000000000001038
-:102870000000000000000000000000080000000050
-:102880000000000000000000000000000000000048
-:102890000000000000000000000000000000000038
-:1028A0000000000000000000000000000000000028
-:1028B0000000000000000000000000000000000018
-:1028C0000000000000000000000000000000000008
-:1028D00000000000000000000000000000000000F8
-:1028E00000000000000000000000000000000000E8
-:1028F00000000000000000000000000000000000D8
-:1029000000000000000000000000000000000000C7
-:1029100000000000000000000000000000000000B7
-:1029200000000000000000000000000000000000A7
-:102930000000000000000000000000000000000097
-:102940000000000000000000000000000000000087
-:102950000000000000000000000000000000000077
-:102960000000000000000000000000000000000067
-:102970000000000000000000000000000000000057
-:102980000000000000000000000000000000000047
-:102990000000000000000000000090000010000097
-:1029A0000000000800009008001000000000000275
-:1029B00000009000001000000000001000009DA822
-:1029C000000000000000000880000000000000007F
-:1029D0000000000080000000000000000000000077
-:1029E000800000000000000000000000000091A036
-:1029F0000000000000000008000093C00001000477
-:102A000000000001000093C8000000000000000268
-:102A1000000093D00000000000000008000093D4E4
-:102A20000000000000000002000094980000000078
-:102A300000000008000093D8000800000000000813
-:102A400000009B3800400000000000400000941887
-:102A50000008000000000008000094580008000072
-:102A600000000008000094A800C8000000000098C2
-:102A700000009638009800000000002800009678BA
-:102A800000980000000000280000C0000540003051
-:102A9000000005400000CB200008000000000001FD
-:102AA0000000CB2100080000000000010000200809
-:102AB00000100000000000100000200000000000D6
-:102AC0000000000800009D600008000000000002F7
-:102AD00000009DA0000000000000000100000000B8
-:102AE00000000000000000000000000000000000E6
-:102AF00000000000000000000000000000000000D6
-:102B000080000000000000000000000080000000C5
-:102B10000000000000000000800000000000000035
-:102B20000000000080000000000000000000000025
-:102B30008000000000000000000000008000000095
-:102B40000000000000000000800000000000000005
-:102B500000000000800000000000000000000000F5
-:102B60008000000000000000000000008000000065
-:102B700000000000000000008000000000000000D5
-:102B800000000000800000000000000000000000C5
-:102B900080000000000000000000000000000000B5
-:102BA0000000000000000000000000000000000025
-:102BB0000000000000000000000000000000000015
-:102BC0000000000000000000000000000000000005
-:102BD0000000000000000000800000000000000075
-:102BE0000000000080000000000000000000000065
-:102BF0008000000000000000000000000000000055
-:102C00000000000000000000800000000000000044
-:102C10000000000080000000000000000000000034
-:102C20008000000000000000000000000000000024
-:102C30000000000000000000000000000000000094
-:102C40000000000000000000000000000000000084
-:102C50000000000000000000000000000000000074
-:102C60000000000000000000000000000000000064
-:102C700000000000000012C800800000000000807A
-:102C80000000000100000000000000000000A000A3
-:102C9000071000000000071000001EC80000000020
-:102CA000000000080000AEC000080000000000089E
-:102CB0000000AE4000080000000000080000AE80E8
-:102CC00000080000000000080000200800100000BC
-:102CD00000000010000020000000000000000008BC
-:102CE0000000A01007100040000000400000AF40AE
-:102CF00000080000000000010000AF4100080000D3
-:102D00000000000100001ED00000000000000001D3
-:102D100000001ED8000000000000000200001EDAC3
-:102D20000000000000000002000012B000080000D7
-:102D3000000000088000000000000000000000000B
-:102D40008000000000000000000000008000000083
-:102D500000000000000000008000000000000000F3
-:102D600000000000800000000000000000000000E3
-:102D70008000000000000000000000008000000053
-:102D800000000000000000008000000000000000C3
-:102D900000000000800000000000000000000000B3
-:102DA0000000000000000000000000000000000023
-:102DB0000000000000000000000000000000000013
-:102DC0000000000000000000000000000000000003
-:102DD0000000000000000000000000008000000073
-:102DE0000000000000000000800000000000000063
-:102DF00000000000000000000000000000000000D3
-:102E000080000000000000000000000080000000C2
-:102E10000000000000000000800000000000000032
-:102E20000000000080000000000000000000000022
-:102E30000000B00000180000000000180000B300FF
-:102E400000400000000000400000B300004000020D
-:102E5000000000010000B30100400002000000007B
-:102E600000008000004000000000004080000000E2
-:102E7000000000000000000000008000000800408A
-:102E8000000000040000800400080040000000046E
-:102E90000000BB0000280000000000280000BC402B
-:102EA00000100000000000100000880000800000FA
-:102EB0000000008000008800000800800000000280
-:102EC00000008C000020000000000020000020080E
-:102ED00000100000000000100000200000000000B2
-:102EE00000000008000011080008000000000008B1
-:102EF000000011680008000000000008000011A890
-:102F00000008000000000008000012700008000027
-:102F10000000000100001271000800000000000124
-:102F200000008D00001000040000000400001320C9
-:102F300000300018000000100000132800300018B6
-:102F400000000002800000000000000000000000FF
-:102F5000800000000000000000000000000011E8F8
-:102F600000000000000000018000000000000000E0
-:102F700000000000800000000000000000000000D1
-:102F80008000000000000000000000008000000041
-:102F900000000000000000008000000000000000B1
-:102FA00000000000800000000000000000000000A1
-:102FB0000000000000000000000000000000000011
-:102FC0000000000000000000000000000000000001
-:102FD00000000000000000000000000000000000F1
-:102FE00080000000000000000000000080000000E1
-:102FF00000000000000000000000000000000000D1
-:103000000000000000008308008000000000008035
-:103010000000000100000000000000000000200887
-:103020000010000000000010000020000000000060
-:103030000000000800008D100008000000000008DB
-:1030400000008D700008000000000008000084509F
-:10305000046000280000046000008EA0000800004A
-:103060000000000100008EA1000800000000000127
-:1030700000008408000800000000000800008448E8
-:10308000000000000000000100008DF400080000B6
-:103090000000000200008DF60008000000000002A1
-:1030A00000008E04001000000000000480000000FA
-:1030B0000000000000000000800000000000000090
-:1030C0000000000080000000000000000000000080
-:1030D00000000000000000000000000000000000F0
-:1030E00000000000000000000000000000000000E0
-:1030F00000000000000000000000000000000000D0
-:1031000080000000000000000000000080000000BF
-:1031100000000000000000000000000000000000AF
-:10312000000000008000000000000000000000001F
-:10313000800000000000000000000000800000008F
-:1031400000000000000000008000000000000000FF
-:1031500000000000000030000040000000000008F7
-:1031600000003008004000000000002800003390FC
-:1031700001C0001000000008000032000020000024
-:1031800000000020000037200000000000000008C0
-:103190000000102006200038000000080000A000F9
-:1031A000000000000000200000003EA90000000018
-:1031B0000000000100003EC8000000000000000206
-:1031C00000001C4000E00008000000088000000033
-:1031D00000000000000000000000400000080000A7
-:1031E0000000000100004001000800000000000194
-:1031F00000004040000800040000000200004060A1
-:103200000008000400000004000040000008000066
-:10321000000000040000400400080000000000045A
-:10322000000040400000000000000008000040488E
-:103230000000000000000008000080000000000006
-:1032400000000010000050400001000400000001D8
-:1032500000005000000000000000002000005008A6
-:1032600000100000000000040000500C00100000DE
-:1032700000000001000052C7000000000000000133
-:10328000000052C6000000000000000100003000F5
-:103290000030001800000004000030040030001866
-:1032A0000000000400003008003000180000000298
-:1032B0000000300A00300018000000020000300C4E
-:1032C00000300018000000010000300D0030001830
-:1032D000000000010000300E003000180000000166
-:1032E000000030100030001800000004000030140E
-:1032F00000300018000000040000500001000080B1
-:1033000000080004000050040100008000080004D0
-:103310000000000A000000000000000000005068EB
-:1033200001000080000000010000506901000080E1
-:10333000000000010000506C01000080000000024D
-:103340000000506E0100008000000002000050707C
-:1033500001000080000000040000507401000080A3
-:103360000000000400005066010000800000000220
-:103370000000506401000080000000010000506067
-:103380000100008000000002000050620100008087
-:103390000000000200005050010000800000000406
-:1033A000000050540100008000000004000050584C
-:1033B00001000080000000040000505C010000805B
-:1033C000000000040000507C0100008000000001AB
-:1033D0000000507D01000080000000010000401846
-:1033E00000100000000000040000409000100000E9
-:1033F00000000004000040980010000000000004DD
-:103400000000411000000000000000020000411216
-:103410000000000000000002000041140000000055
-:103420000000000200004116000000000000000241
-:103430000000604000080000000000020000604240
-:1034400000080000000000020000604400080000C6
-:103450000000000400006080000800000000000878
-:10346000000060C00040000800000008000060008C
-:1034700000080000000000020000600200080000D8
-:1034800000000001000060040008000000000002CD
-:103490000000634000080000000000080000638096
-:1034A0000008000000000004000063840008000021
-:1034B00000000001000063C00008000000000002DE
-:1034C000000063C400080000000000020000640067
-:1034D0000008000000000004000070000010000060
-:1034E0000000000400007004001000000000000450
-:1034F00000007008001000000000000400007000D0
-:103500000008000000000002000070020008000037
-:10351000000000010000700400080000000000022C
-:10352000000070400008000000000002000070442D
-:1035300000080000000000020000704600080000C3
-:1035400000000002000076480008000000000008AB
-:10355000000070800008000000000002000070847D
-:10356000000800000000000200007688000800004B
-:10357000000000080000804000080000000000017A
-:1035800000008041000800000000000100008042AF
-:103590000008000000000001000080430008000057
-:1035A0000000000100008000000800000000000290
-:1035B00000008002000800000000000100008004FC
-:1035C0000008000000000002000080C000080000A9
-:1035D00000000002000080C200080000000000029D
-:1035E000000080C40008000000000002000080808D
-:1035F00000080000000000010000808100080000B9
-:1036000000000001000080820008000000000001AE
-:10361000000080830008000000000001000080849A
-:103620000008000000000001000080850008000084
-:10363000000000010000808600080000000000017A
-:1036400000006000000800000000000200006002AE
-:1036500000080000000000010000600400080000F5
-:10366000000000020000604200C0001800000002DC
-:103670000000604000C00018000000020000604C24
-:1036800000C00018000000080000604400C00018DE
-:10369000000000080000605700C000180000000192
-:1036A0000000605400C000180000000200006056D6
-:1036B00000C0001800000001000066400008000083
-:1036C00000000008000066800008000000000008FC
-:1036D000000066C000080000000000080000D94299
-:1036E00000180000000000020000DE4000000000A2
-:1036F000000000000000E0000000000000000004E6
-:103700000000DD4000000000000000040000DD4477
-:1037100000000000000000040000DD480000000080
-:10372000000000040000DD4C000000000000000468
-:103730000000DD5000000000000000040000DD5427
-:1037400000000000000000040000DD580000000040
-:10375000000000040000DD40000000000000002028
-:103760000000DA0000000000000000040000DA00A1
-:1037700000000000000000680000BB6000000000C6
-:10378000000000000000D000000000000000000465
-:103790000000B0C000000000000000040000B0C441
-:1037A00000000000000000040000B0C8000000009D
-:1037B000000000040000B0C0000000000000001085
-:1037C0000000D6B000000000000000040000D6B4E5
-:1037D00000000000000000040000D6B80000000057
-:1037E000000000040000D6BC00000000000000043F
-:1037F0000000D6B000000000000000100000D34818
-:1038000000000000000000080000D3580000000085
-:103810000000008000000010000000000000000018
-:103820000000D35800000000000000080000000065
-:0838300006020900000000007F
-:00000001FF
--- /dev/null
+++ zfcpdump-kernel-4.4/firmware/bnx2x/bnx2x-e1h-7.12.30.0.fw.ihex
@@ -0,0 +1,11190 @@
+:10000000000021F800000068000005D80000226808
+:10001000000036EC000028480000007000005F3847
+:1000200000007A8C00005FB0000000A00000DA4001
+:100030000000D2DC0000DAE8000000880001ADC852
+:1000400000003CA40001AE58000000880001EB0055
+:100050000000BD780001EB900000120C0002A91016
+:10006000000000040002BB20020600DC00000001CA
+:100070000306100002000000010600D80000000086
+:100080000306020000030200020600DC000000007C
+:10009000010600B800000000010600C800000000D2
+:1000A0000206016C00000000010600BC0000000018
+:1000B000010600CC000000000206017000000000F4
+:1000C000020D004400000032030D004C0004020346
+:1000D000040D005C00000004030D008C00110207F9
+:1000E000020D015C00000001030D01640002021812
+:1000F000020D020400000001030D020C0003021AAD
+:10010000030D02200002021D040D028000000012F7
+:10011000030D03000018021F040D03600000000C13
+:10012000040D400000000A00030D0004000F023718
+:10013000020D01140000000D020D01180000002D39
+:10014000020D01140000001D020D01180000003D09
+:10015000020D01140000004D020D01180000006D99
+:10016000020D01140000005D020D01180000007D69
+:10017000031010000003024602101050000000019E
+:10018000071011000010024908101140000000087B
+:100190000710116000100259081011A0000000188B
+:1001A000071018000200026904104C000000010052
+:1001B00002104028000000100310404000020469B3
+:1001C0000210405800280000021040840084924A27
+:1001D0000210405800000000030C20080003046BCC
+:1001E000030C201C0004046E030C20380011047260
+:1001F000040C207C0000004F030C21B80011048384
+:10020000040C21FC0000000F030C223800040494AD
+:10021000010C224800000000010C224C00000000EC
+:10022000010C225000000000010C225400000000CC
+:10023000010C225800000000010C225C00000000AC
+:10024000010C226000000000010C2264000000008C
+:10025000010C226800000000010C226C000000006C
+:10026000010C227000000000010C2274000000004C
+:10027000010C227800000000010C227C000000002C
+:100280000A00000100000001020C2000000003E849
+:100290000A00000100000002020C20000000000A19
+:1002A0000A00000100000004020C20000000000110
+:1002B0000520040000860000062007800010049836
+:1002C000042200000000400004232400000000403D
+:1002D000032212500010049A0422B14000000020B2
+:1002E0000422C800000000060322C818000404AA63
+:1002F0000422C8280000000C0322C858000404AEE1
+:100300000422C8680000000C0322C898000404B24C
+:100310000422C8A80000000C0322C8D8000404B6B8
+:100320000422C8E80000000C0322C918000404BA23
+:100330000422C9280000000C0322C958000404BE8E
+:100340000422C9680000000C0322C998000404C2FA
+:100350000422C9A80000000C0322C9D8000404C666
+:100360000422C9E80000000C0322CA18000404CAD1
+:100370000422CA280000000C0322CA58000404CE3C
+:100380000422CA680000000C0322CA98000404D2A8
+:100390000422CAA80000000C0322CAD8000404D614
+:1003A0000422CAE80000000C0322CB18000404DA7F
+:1003B0000422CB280000000C0322CB58000404DEEA
+:1003C0000422CB680000000C0322CB98000404E256
+:1003D0000422CBA80000000C0322CBD8000404E6C2
+:1003E0000422CBE80000000C0322CC18000404EA2D
+:1003F0000422CC280000000C0322CC58000404EE98
+:100400000422CC680000000C0322CC98000404F203
+:100410000422CCA80000000C0322CCD8000404F66F
+:100420000422CCE80000000C0322CD18000404FADA
+:100430000422CD280000000C0322CD58000404FE45
+:100440000422CD680000000C0322CD9800040502B0
+:100450000422CDA80000000C0322CDD8000405061C
+:100460000422CDE80000000C0322CE180004050A87
+:100470000422CE280000000C0322CE580004050EF2
+:100480000422CE680000000C0322CE98000405125E
+:100490000422CEA80000000C0322CED800040516CA
+:1004A0000422CEE80000000C0322CF180004051A35
+:1004B0000422CF280000000C0322CF580004051EA0
+:1004C0000422CF680000000C0322CF98000405220C
+:1004D0000422CFA80000000C0322CFD80004052678
+:1004E0000422CFE800000006022380000000001074
+:1004F00002238040000000120223808000000030B0
+:10050000022380C00000000E022383800007A12088
+:10051000022383C0000001F402238BC0000000010D
+:100520000A00000200000001022383000007A1204E
+:1005300002238340000001F40A00000200000002D0
+:10054000022383000000138802238340000000057B
+:100550000A000002000000040223830000000138AA
+:1005600002238340000000000524000036500000F4
+:100570000524800006540D9406248B306D00052A56
+:100580000A000001000000020223148000000000A5
+:100590000A00000100000004022314800000000093
+:1005A0000120000000000000012000040000000005
+:1005B00001200008000000000120000C00000000E5
+:1005C00001200010000000000120001400000000C5
+:1005D00003200020001A052C032000A40002054679
+:1005E000022002240000000002200234000000006B
+:1005F0000220024C00000000022002E40000FFFF85
+:100600000820200000000800042211080000000259
+:1006100004221290000000060422340000000002B0
+:10062000042260400000003004228C000000001012
+:100630000422111000000002042212A8000000068B
+:10064000042234080000000204226100000000308F
+:1006500004228C4000000010042211180000000247
+:10066000042212C000000006042234100000000220
+:10067000042261C00000003004228C8000000010C1
+:100680000422112000000002042212D800000006FB
+:1006900004223418000000020422628000000030AE
+:1006A00004228CC000000010042211280000000267
+:1006B000042212F000000006042234200000000290
+:1006C000042263400000003004228D00000000106E
+:1006D000042211300000000204221308000000066A
+:1006E00004223428000000020422640000000030CC
+:1006F00004228D4000000010042211380000000286
+:1007000004221320000000060422343000000002FE
+:10071000042264C00000003004228D80000000101C
+:1007200004221140000000020422133800000006D9
+:1007300004223438000000020422658000000030EA
+:1007400004228DC00000001004102400000000E00E
+:100750000310201C00020548021020C00000000207
+:10076000031020040002054A0217000800000002DE
+:100770000217002C00000003031700380002054C8C
+:10078000031700480005054E0317006000050553D8
+:100790000317007800020558021700040000000F3C
+:1007A0000210800000001080041080400000000251
+:1007B000021080AC00000000021080380000001021
+:1007C00002108100000000000410812000000002DF
+:1007D00002108008000002B5021080100000000026
+:1007E000021081080001FFFF041082000000004A8F
+:1007F00004108140000000020210800000001A80F6
+:100800000410900000000024041091200000004A11
+:10081000041093700000004A041095C00000004AC4
+:1008200002108004000010800410804800000002C4
+:10083000021080B0000000010210803C0000001097
+:100840000210810400000000041081280000000252
+:100850000210800C000002B502108014000000009D
+:100860000210810C0001FFFF041084000000004A08
+:1008700004108148000000020210800400001A8069
+:100880000410909000000024041092480000004AD8
+:10089000041094980000004A041096E80000004AF2
+:1008A0000210800000001080041080400000000250
+:1008B000021080AC0000000202108038000000101E
+:1008C00002108100000000000410812000000002DE
+:1008D00002108008000002B5021080100000000025
+:1008E000021081080001FFFF041082000000004A8E
+:1008F00004108140000000020210800000001A80F5
+:100900000410900000000024041091200000004A10
+:10091000041093700000004A041095C00000004AC3
+:1009200002108004000010800410804800000002C3
+:10093000021080B0000000030210803C0000001094
+:100940000210810400000000041081280000000251
+:100950000210800C000002B502108014000000009C
+:100960000210810C0001FFFF041084000000004A07
+:1009700004108148000000020210800400001A8068
+:100980000410909000000024041092480000004AD7
+:10099000041094980000004A041096E80000004AF1
+:1009A000021080000000108004108040000000024F
+:1009B000021080AC0000000402108038000000101B
+:1009C00002108100000000000410812000000002DD
+:1009D00002108008000002B5021080100000000024
+:1009E000021081080001FFFF041082000000004A8D
+:1009F00004108140000000020210800000001A80F4
+:100A00000410900000000024041091200000004A0F
+:100A1000041093700000004A041095C00000004AC2
+:100A200002108004000010800410804800000002C2
+:100A3000021080B0000000050210803C0000001091
+:100A40000210810400000000041081280000000250
+:100A50000210800C000002B502108014000000009B
+:100A60000210810C0001FFFF041084000000004A06
+:100A700004108148000000020210800400001A8067
+:100A80000410909000000024041092480000004AD6
+:100A9000041094980000004A041096E80000004AF0
+:100AA000021080000000108004108040000000024E
+:100AB000021080AC00000006021080380000001018
+:100AC00002108100000000000410812000000002DC
+:100AD00002108008000002B5021080100000000023
+:100AE000021081080001FFFF041082000000004A8C
+:100AF00004108140000000020210800000001A80F3
+:100B00000410900000000024041091200000004A0E
+:100B1000041093700000004A041095C00000004AC1
+:100B200002108004000010800410804800000002C1
+:100B3000021080B0000000070210803C000000108E
+:100B4000021081040000000004108128000000024F
+:100B50000210800C000002B502108014000000009A
+:100B60000210810C0001FFFF041084000000004A05
+:100B700004108148000000020210800400001A8066
+:100B80000410909000000024041092480000004AD5
+:100B9000041094980000004A041096E80000004AEF
+:100BA0000200A468000B01C80300A2940004055AC7
+:100BB0000A000001000000800200A5F8000000000B
+:100BC0000A000001000001000200A5F80000000179
+:100BD0000200A270000000000200A27400000000E9
+:100BE0000200A270000000000200A27400000000D9
+:100BF0000200A270000000000200A27400000000C9
+:100C00000200A270000000000200A27400000000B8
+:100C1000030100B40002055E020100DC00000001D7
+:100C200003010100000205600201007C00300000A9
+:100C300002010084000000280201008C0000000076
+:100C4000020101300000000402010328000000003E
+:100C50000201055400000030020160580000FFFF4F
+:100C600002016070000000070201608000000001C6
+:100C7000020100C400000001020100CC00000001DC
+:100C8000020100F800000001020100F00000000174
+:100C900002010080003000000201008800000028EE
+:100CA0000201009000000000020101340000000475
+:100CB0000201032C00000000020105640000003066
+:100CC0000201605C0000FFFF020160740000000789
+:100CD0000201608400000001020100C80000000160
+:100CE000020100D000000001020100FC0000000130
+:100CF000020100F4000000010401013800000011AD
+:100D00000401017C00000011040101380000001101
+:100D10000401017C000000110401013800000011F1
+:100D20000401017C000000110401013800000011E1
+:100D30000401017C00000011021400000000000109
+:100D40000214000C000000010314004000020562C0
+:100D50000214000C0000000002140000000000005B
+:100D60000214006C000000000214000400000001E6
+:100D70000214003000000001021400040000000012
+:100D80000214005C000000000214000800000001D2
+:100D900002140034000000010214000800000000EA
+:100DA0000214006000000000030400040012056447
+:100DB00002040054000000430204005C000000062E
+:100DC00002040070000000040304007800040576AB
+:100DD00004040088000000050304009C0003057A59
+:100DE000040400A800000004030400B80005057D09
+:100DF000040400CC00000004030400DC00040582AD
+:100E0000040400EC000000040104012400000000C0
+:100E100001040128000000000104012C0000000072
+:100E20000104013000000000020401340000000F42
+:100E3000020401D000008906021205B00000000182
+:100E400003120490002205860312066C000205A816
+:100E500002120388000000640212039000000008E0
+:100E60000312039C000305AA031203BC000305AD93
+:100E7000021203D0000000000212036C0000000107
+:100E8000021203680000003F031201BC003C05B0E1
+:100E9000031202B0000205EC03120324000205EE67
+:100EA000021205B400000001021201B000000001AE
+:100EB00007103800000505F007103820000505F57B
+:100EC00007103C00000505FA03168030000805FFF6
+:100ED0000216805400000002031680600005060719
+:100EE0000416807400000007031680900002060CB0
+:100EF0000316809C0005060E041680B00000000753
+:100F0000031680CC00080613021680F000000007CC
+:100F1000041680F40000000C031681240004061B54
+:100F2000041681340000000C031681640032061F91
+:100F30000316823400070651041682500000000494
+:100F4000031682600002065804168268000000083A
+:100F5000031682880008065A041682A80000000AB8
+:100F600002168804000000040316880C00100662B4
+:100F70000316E000001006720416E40C0000000CDA
+:100F80000316E43C000406820416E44C0000000C46
+:100F90000316E47C002E06860416E53400000004E7
+:100FA0000316E544000206B40416E54C00000008F0
+:100FB0000316E56C000606B60316E6BC000806BC80
+:100FC000021680EC000000FF03040408001406C4AD
+:100FD000020404CC0000000103050044000206D80E
+:100FE00003050050000406DA040500600000000458
+:100FF00003050090001306DE020501140000000145
+:101000000305011C000206F10205020400000001B4
+:101010000305020C000206F30305021C000306F59B
+:10102000040502400000000A03050280002006F8C3
+:101030000405400000000D0003050004001007181F
+:10104000020500E00000000E020500E40000002E92
+:10105000020500E00000001E020500E40000003E62
+:10106000020500E00000004E020500E40000006EF2
+:10107000020500E00000005E020500E40000007EC2
+:101080000416402400000002031640300003072825
+:101090000216404400000020021640700000001CB0
+:1010A0000216420800000001021642100000000172
+:1010B0000216422000000001021642280000000132
+:1010C0000216423000000001021642380000000102
+:1010D00002164260000000020A0000010000000148
+:1010E0000216401C0003D0900A000001000000021C
+:1010F0000216401C000009C40A00000100000004A0
+:101100000216401C0000009C021640000000000176
+:10111000021640D800000001031640080003072B08
+:101120000216424000000000021642480000000083
+:101130000816427000000002021642500000000033
+:10114000021642580000000008164280000000020B
+:10115000030420080004072E0304201C00040732A7
+:1011600002042038000000200404203C0000001F7E
+:10117000020420B800000001040420BC0000005F4D
+:10118000030422380004073601042248000000004E
+:101190000104224C00000000010422500000000065
+:1011A0000104225400000000010422580000000045
+:1011B0000104225C00000000010422600000000025
+:1011C0000104226400000000010422680000000005
+:1011D0000104226C000000000104227000000000E5
+:1011E00001042274000000000104227800000000C5
+:1011F0000104227C000000000A0000010000000140
+:1012000002042000000003E80A00000100000002C0
+:10121000020420000000000A0A000001000000048F
+:101220000204200000000001051804000070000006
+:10123000061807600014073A041A00000000400076
+:10124000041B240000000040031A1EC80002073CD3
+:10125000031A40400004073E041A405000000006F4
+:10126000031A406800020742031A52C000020744F2
+:10127000031A800003F90746041A8FE400000007F0
+:10128000031AA08000100B3F021B800000000034F6
+:10129000021B804000000018021B80800000000C30
+:1012A000021B80C000000020021B83800007A120D9
+:1012B000021B83C0000001F4021B8BC00000000170
+:1012C0000A00000200000001021B83000007A120A9
+:1012D000021B8340000001F40A000002000000022B
+:1012E000021B830000001388021B834000000005DE
+:1012F0000A00000200000004021B83000000013805
+:10130000021B834000000000051C0000317A000031
+:10131000051C800035910C5F051D0000137B19C46E
+:10132000061D2B105A9E0B4F0A0000010000000200
+:10133000021B1480000000000A00000100000004ED
+:10134000021B1480000000000118000000000000D3
+:10135000011800040000000001180008000000004F
+:101360000118000C0000000001180010000000002F
+:10137000011800140000000003180020001A0B518F
+:10138000031800A400020B6B0218022400000000E6
+:1013900002180234000000000218024C0000000095
+:1013A000021802E4000000FF08181000000004000A
+:1013B000041A300000000010041A308000000010F1
+:1013C000041A310000000010041A318000000010DF
+:1013D000041A330000000012041A339000000012B7
+:1013E000041A342000000070041A90000000000667
+:1013F000041A304000000010041A30C00000001031
+:10140000041A314000000010041A31C0000000101E
+:10141000041A334800000012041A33D800000012E6
+:10142000041A35E000000070041A9018000000064D
+:10143000031A400000020B6D041A50000000000265
+:10144000041A508000000012031A614000020B6F62
+:10145000041A903000000002041AA00000000002EC
+:10146000031A400800020B71041A50100000000219
+:10147000041A50C800000012031A614800020B73DE
+:10148000041A903800000002041AA00800000002AC
+:10149000031A401000020B75041A502000000002CD
+:1014A000041A511000000012031A615000020B7759
+:1014B000041A904000000002041AA010000000026C
+:1014C000031A401800020B79041A50300000000281
+:1014D000041A515800000012031A615800020B7BD5
+:1014E000041A904800000002041AA018000000022C
+:1014F000031A402000020B7D041A50400000000235
+:10150000041A51A000000012031A616000020B7F50
+:10151000041A905000000002041AA02000000002EB
+:10152000031A402800020B81041A505000000002E8
+:10153000041A51E800000012031A616800020B83CC
+:10154000041A905800000002041AA02800000002AB
+:10155000031A403000020B85041A5060000000029C
+:10156000041A523000000012031A617000020B8747
+:10157000041A906000000002041AA030000000026B
+:10158000031A403800020B89041A50700000000250
+:10159000041A527800000012031A617800020B8BC3
+:1015A000041A906800000002041AA038000000022B
+:1015B000020E004C00000032030E005400040B8D9C
+:1015C000040E006400000004030E009400130B914D
+:1015D000020E014400000001030E014C00020BA4A6
+:1015E000020E020400000001030E020C00020BA612
+:1015F000030E021C00040BA8030E0280001B0BACA0
+:10160000040E02EC00000017040E20000000080089
+:10161000030E000400110BC7020E01100000000FA2
+:10162000020E01140000002F020E01100000001F26
+:10163000020E01140000003F020E01100000004FD6
+:10164000020E01140000006F020E01100000005F86
+:10165000020E01140000007F020C100000000028A0
+:10166000030C400800040BD8030C401C00040BDCE6
+:10167000030C403800050BE0040C404C0000005BFC
+:10168000030C41B800050BE5040C41CC0000001B25
+:10169000030C423800040BEA010C42480000000031
+:1016A000010C424C00000000010C42500000000000
+:1016B000010C425400000000010C425800000000E0
+:1016C000010C425C00000000010C426000000000C0
+:1016D000010C426400000000010C426800000000A0
+:1016E000010C426C00000000010C42700000000080
+:1016F000010C427400000000010C42780000000060
+:10170000010C427C00000000010C4280000000003F
+:101710000A00000100000001020C4000000003E884
+:101720000A00000100000002020C40000000000A54
+:101730000A00000100000004020C4000000000014B
+:1017400005300400009E00000630076800130BEE11
+:101750000432000000004000043324000000004078
+:1017600004323E800000001003323EC000020BF045
+:10177000033274C000080BF20332850000100BFA2C
+:10178000023380000000001A023380400000004E47
+:101790000233808000000010023380C0000000206F
+:1017A000023383800007A120023383C0000001F4CC
+:1017B00002338BC0000000010A000002000000019B
+:1017C000023383000007A12002338340000001F4AC
+:1017D0000A000002000000020233830000001388A8
+:1017E00002338340000000050A00000200000004EC
+:1017F0000233830000000138023383400000000000
+:1018000005340000346A000005348000283C0D1BBC
+:101810000535000024B7172A0535800034C8205844
+:10182000053600001CB42D8A063640B037EA0C0A93
+:101830000A000001000000020233148000000000D2
+:101840000A000001000000040233148000000000C0
+:101850000130000000000000013000040000000022
+:1018600001300008000000000130000C0000000002
+:1018700001300010000000000130001400000000E2
+:1018800003300020001A0C0C033000A400020C26C8
+:101890000230022400000000023002340000000088
+:1018A0000230024C00000000023002E40000FFFFA2
+:1018B000083020000000080004321000000001C0C1
+:1018C00004321E000000003804323000000001C065
+:1018D00004325000000000200432510000000020BB
+:1018E00004325200000000200432530000000020A7
+:1018F0000432540000000020043255000000002093
+:10190000043256000000002004325700000000207E
+:10191000043258000000002004325900000000206A
+:1019200004325A000000002004325B000000002056
+:1019300004325C000000002004325D000000002042
+:1019400004325E000000002004325F00000000202E
+:1019500004328450000000020332846000040C282A
+:1019600004321700000001C004321EE000000038FD
+:1019700004323700000001C0043250800000002013
+:101980000432518000000020043252800000002008
+:1019900004325380000000200432548000000020F4
+:1019A00004325580000000200432568000000020E0
+:1019B00004325780000000200432588000000020CC
+:1019C000043259800000002004325A8000000020B8
+:1019D00004325B800000002004325C8000000020A4
+:1019E00004325D800000002004325E800000002090
+:1019F00004325F800000002004328458000000029E
+:101A00000332847000040C2C0432401000000002E9
+:101A10000432841000000002043240200000000262
+:101A2000043284180000000204324030000000023A
+:101A30000432842000000002043240400000000212
+:101A400004328428000000020432405000000002EA
+:101A500004328430000000020432406000000002C2
+:101A6000043284380000000204324070000000029A
+:101A70000432844000000002043240800000000272
+:101A800004328448000000020202005800000032C4
+:101A90000302006000040C30040200700000000427
+:101AA000030200A0000E0C34030200DC00070C420D
+:101AB000020200FC000000060202012000000000FB
+:101AC0000202013400000002020201B00000000125
+:101AD0000202020C000000010302021400020C4981
+:101AE00002020404000000010302040C00020C4B7B
+:101AF0000302041C00040C4D0302048000200C515E
+:101B00000402050000000012040280000000200012
+:101B10000302000400140C7102020108000000C856
+:101B20000202011800000002020201C400000000CD
+:101B3000020201CC00000000020201D400000002F9
+:101B4000020201DC00000002020201E4000000FFCA
+:101B5000020201EC000000FF0202010C000000C8BC
+:101B60000202011C00000002020201C80000000085
+:101B7000020201D000000000020201D800000002B1
+:101B8000020201E000000002020201E8000000FF82
+:101B9000020201F0000000FF02020108000000C87C
+:101BA0000202011800000002020201C4000000004D
+:101BB000020201CC00000000020201D40000000279
+:101BC000020201DC00000002020201E4000000FF4A
+:101BD000020201EC000000FF0202010C000000C83C
+:101BE0000202011C00000002020201C80000000005
+:101BF000020201D000000000020201D80000000231
+:101C0000020201E000000002020201E8000000FF01
+:101C1000020201F0000000FF02020108000000C8FB
+:101C20000202011800000002020201C400000000CC
+:101C3000020201CC00000000020201D400000002F8
+:101C4000020201DC00000002020201E4000000FFC9
+:101C5000020201EC000000FF0202010C000000C8BB
+:101C60000202011C00000002020201C80000000084
+:101C7000020201D000000000020201D800000002B0
+:101C8000020201E000000002020201E8000000FF81
+:101C9000020201F0000000FF02020108000000C87B
+:101CA0000202011800000002020201C4000000004C
+:101CB000020201CC00000000020201D40000000278
+:101CC000020201DC00000002020201E4000000FF49
+:101CD000020201EC000000FF0202010C000000C83B
+:101CE0000202011C00000002020201C80000000004
+:101CF000020201D000000000020201D80000000230
+:101D0000020201E000000002020201E8000000FF00
+:101D1000020201F0000000FF02161000000000287F
+:101D20000316600800030C850316601C00040C8871
+:101D300003166038000D0C8C0416606C0000001354
+:101D4000031660B800020C99041660C00000003E43
+:101D5000021661B800000001041661BC0000001FFB
+:101D60000316623800040C9B011662480000000054
+:101D70000116624C000000000116625000000000D5
+:101D800001166254000000000116625800000000B5
+:101D90000116625C00000000011662600000000095
+:101DA0000116626400000000011662680000000075
+:101DB0000116626C00000000011662700000000055
+:101DC0000116627400000000011662780000000035
+:101DD0000116627C000000000A0000010000000102
+:101DE00002166000000003E80A0000010000000283
+:101DF000021660000000000A0A0000010000000452
+:101E000002166000000000010528040000870000A1
+:101E10000628076800130C9F042A000000004000F9
+:101E2000042B240000000040032A300000020CA113
+:101E3000032A400000100CA3032A840800080CB3F6
+:101E4000032A93C800040CBB032A96F000020CBFBF
+:101E5000042A96F800000006032A994000020CC1EB
+:101E6000022A9A2800000001032AC0C000100CC3F7
+:101E7000022B800000000000022B804000000018B0
+:101E8000022B80800000000C022B80C00000006646
+:101E9000022B83800007A120022B83C0000001F4E5
+:101EA000022B8BC0000000010A00000200000001AC
+:101EB000022B83000007A120022B8340000001F4C5
+:101EC0000A00000200000002022B830000001388B9
+:101ED000022B8340000000050A00000200000004FD
+:101EE000022B830000000138022B83400000000019
+:101EF0000A00000100000020022A9A2C00000000C5
+:101F0000052C000038390000052C80003B470E0FDF
+:101F1000052D00003C671CE1052D80000D892BFB81
+:101F2000062D9A804CB00CD30A000001000000027C
+:101F3000022B1480000000000A00000100000004D1
+:101F4000022B1480000000000128000000000000A7
+:101F50000128000400000000012800080000000023
+:101F60000128000C00000000012800100000000003
+:101F7000012800140000000003280020001A0CD5DE
+:101F8000032800A400020CEF022802240000000035
+:101F900002280234000000000228024C0000000069
+:101FA000022802E40000FFFF0828200000000800CB
+:101FB000042A500000000002042A50100000000211
+:101FC000042A502000000002042A503000000002C1
+:101FD000042A93E000000020042A94E00000000E90
+:101FE000032A951800020CF1042A95600000000EE7
+:101FF000032A959800020CF3042A95E00000000ED5
+:10200000032A961800020CF5042A96600000000EC0
+:10201000032A969800020CF7032A971000020CF985
+:10202000042A500800000002042A50180000000290
+:10203000042A502800000002042A50380000000240
+:10204000042A946000000020042A95200000000E5D
+:10205000032A955800020CFB042A95A00000000EEC
+:10206000032A95D800020CFD042A96200000000ED9
+:10207000032A965800020CFF042A96A00000000EC6
+:10208000032A96D800020D01032A971800020D03B7
+:10209000042A50480000000E032A972000100D0566
+:1020A000042A995000000002042AC0000000000227
+:1020B000042A50800000000E032A976000100D15BE
+:1020C000042A995800000002042AC00800000002F7
+:1020D000042A50B80000000E032A97A000100D2516
+:1020E000042A996000000002042AC01000000002C7
+:1020F000042A50F00000000E032A97E000100D356E
+:10210000042A996800000002042AC0180000000296
+:10211000042A51280000000E032A982000100D45C3
+:10212000042A997000000002042AC0200000000266
+:10213000042A51600000000E032A986000100D551B
+:10214000042A997800000002042AC0280000000236
+:10215000042A51980000000E032A98A000100D6573
+:10216000042A998000000002042AC0300000000206
+:10217000042A51D00000000E032A98E000100D75CB
+:10218000042A998800000002042AC03800000002D6
+:102190000400A0000000000C0400A0500000000299
+:1021A0000300A0EC00080D850300A18C00080D8D34
+:1021B0000200A45C00000C000200A61C000000034A
+:1021C0000300A06C00060D950400A084000000052B
+:1021D0000200A0980FE000000400A09C000000078F
+:1021E0000300A0B8000D0D9B0400A22C0000000409
+:1021F0000300A10C00060DA80400A12400000005A6
+:102200000200A1380FE000000400A13C000000071C
+:102210000300A158000D0DAE0400A23C0000000414
+:102220000200A030000000000200A0340000000006
+:102230000200A038000000000200A03C00000000E6
+:102240000200A040000000000200A04400000000C6
+:102250000200A048000000000200A04C00000000A6
+:10226000000000000000000000000000000000006E
+:10227000000000000000000000000000000000005E
+:10228000000000000000000000000000000000004E
+:102290000000000000000005000500080008000B19
+:1022A000000000000000000000000000000000002E
+:1022B000000000000000000000000000000000001E
+:1022C000000B001900000000000000000019001AB7
+:1022D000001A001B001B001C001C001D001D001E1E
+:1022E000001E001F001F00200020002100210028E8
+:1022F00000000000000000000000000000000000DE
+:1023000000000000000000000000000000000000CD
+:1023100000000000000000000028002E0000000067
+:1023200000000000000000000000000000000000AD
+:10233000000000000000000000000000000000009D
+:1023400000000000002E0049000000000000000016
+:10235000000000000000000000000000000000007D
+:10236000000000000000000000000000000000006D
+:10237000004900B4000000000000000000B400B9F3
+:1023800000B900BE00BE00C300C300C800C800CD35
+:1023900000CD00D200D200D700D700DC0000000042
+:1023A000000000000000000000000000000000002D
+:1023B000000000000000000000000000000000001D
+:1023C000000000000000000000DC00E00000000051
+:1023D00000000000000000000000000000000000FD
+:1023E00000000000000000000000000000000000ED
+:1023F0000000000000E000E7000000000000000016
+:1024000000000000000000000000000000000000CC
+:1024100000000000000000000000000000000000BC
+:1024200000000000000000000000000000E700F7CE
+:1024300000F70107010701170117012701270137DD
+:1024400001370147014701570157016700000000AC
+:10245000000000000000000000000000000000007C
+:10246000000000000000000000000000000000006C
+:1024700000000000000000000167016D0000000086
+:1024800000000000016D016E016E016F016F0170AF
+:1024900001700171017101720172017301730174A4
+:1024A000017401750175017801780185018501923A
+:1024B0000192019301930194019401950195019674
+:1024C0000196019701970198019801990199019A44
+:1024D000019A01A001A001A401A401A8000000002C
+:1024E00000000000000000000000000000000000EC
+:1024F00000000000000000000000000000000000DC
+:1025000000000000000000000000000000000000CB
+:1025100000000000000000000000000000000000BB
+:10252000000000000000000001A801BA0000000047
+:10253000000000000000000000000000000000009B
+:10254000000000000000000000000000000000008B
+:102550000000000001BA01C90000000000000000F6
+:10256000000000000000000000000000000000006B
+:10257000000000000000000000000000000000005B
+:1025800001C901CC000000000000000000000000B4
+:10259000000000000000000000000000000000003B
+:1025A00000000000000000000000000001CC01EC71
+:1025B000000000000000000000000000000000001B
+:1025C000000000000000000000000000000000000B
+:1025D000000000000000000001EC01EE000000001F
+:1025E00000000000000000000000000000000000EB
+:1025F00000000000000000000000000000000000DB
+:102600000000000001EE01FB0000000000000000DF
+:1026100001FB01FC01FC01FD01FD01FE01FE01FFCA
+:1026200001FF020002000201020102020202020393
+:10263000020302170217021A021A021D000000000C
+:10264000000000000000000000000000000000008A
+:10265000000000000000000000000000021D023821
+:10266000000000000000000000000000000000006A
+:10267000000000000000000000000000000000005A
+:1026800000000000000000000238026902690271C7
+:10269000027102790279027F027F02850285028B34
+:1026A000028B0291029102970297029D029D02A362
+:1026B00002A302A902A902B6000000000000000067
+:1026C00002B602B702B702B802B802B902B902BA3A
+:1026D00002BA02BB02BB02BC02BC02BD02BD02BE0A
+:1026E00002BE02BF00000000000000000000000069
+:1026F00000000000000000000000000000000000DA
+:1027000000000000000000000000000002BF02DB2B
+:1027100000000000000000000000000000000000B9
+:1027200000000000000000000000000000000000A9
+:10273000000000000000000002DB030A030A031F80
+:10274000031F033403340336033603380338033AD4
+:10275000033A033C033C033E033E03400340034271
+:10276000034203440344035600000000000000003D
+:102770000356035E035E03660366036E036E037611
+:102780000376037E037E03860386038E038E039601
+:102790000396039700000000000000000000000006
+:1027A0000000000000000000000000000000000029
+:1027B000000000000000000000000000039703B4C8
+:1027C0000000000000000000000000000000000009
+:1027D00000000000000000000000000000000000F9
+:1027E000000000000000000003B403E903E903F760
+:1027F00003F70405040504090409040D040D04117C
+:1028000004110415041504190419041D041D0421E0
+:10281000042104250425042B042B0431043104373E
+:1028200004370438043804390439043A043A043BC0
+:10283000043B043C043C043D043D043E043E043F90
+:102840000000000000000000000020000000400028
+:1028500000006000000080000000A0000000C00038
+:102860000000E00000010000000120000001400025
+:1028700000016000000180000001A0000001C00014
+:102880000001E00000020000000220000002400001
+:1028900000026000000280000002A0000002C000F0
+:1028A0000002E000000300000003200000034000DD
+:1028B00000036000000380000003A0000003C000CC
+:1028C0000003E000000400000004200000044000B9
+:1028D00000046000000480000004A0000004C000A8
+:1028E0000004E00000050000000520000005400095
+:1028F00000056000000580000005A0000005C00084
+:102900000005E00000060000000620000006400070
+:1029100000066000000680000006A0000006C0005F
+:102920000006E0000007000000072000000740004C
+:1029300000076000000780000007A0000007C0003B
+:102940000007E00000080000000820000008400028
+:1029500000086000000880000008A0000008C00017
+:102960000008E00000090000000920000009400004
+:1029700000096000000980000009A0000009C000F3
+:102980000009E000000A0000000A2000000A4000E0
+:10299000000A6000000A8000000AA000000AC000CF
+:1029A000000AE000000B0000000B2000000B4000BC
+:1029B000000B6000000B8000000BA000000BC000AB
+:1029C000000BE000000C0000000C2000000C400098
+:1029D000000C6000000C8000000CA000000CC00087
+:1029E000000CE000000D0000000D2000000D400074
+:1029F000000D6000000D8000000DA000000DC00063
+:102A0000000DE000000E0000000E2000000E40004F
+:102A1000000E6000000E8000000EA000000EC0003E
+:102A2000000EE000000F0000000F2000000F40002B
+:102A3000000F6000000F8000000FA000000FC0001A
+:102A4000000FE00000100000001020000010400007
+:102A500000106000001080000010A0000010C000F6
+:102A60000010E000001100000011200000114000E3
+:102A700000116000001180000011A0000011C000D2
+:102A80000011E000001200000012200000124000BF
+:102A900000126000001280000012A0000012C000AE
+:102AA0000012E0000013000000132000001340009B
+:102AB00000136000001380000013A0000013C0008A
+:102AC0000013E00000140000001420000014400077
+:102AD00000146000001480000014A0000014C00066
+:102AE0000014E00000150000001520000015400053
+:102AF00000156000001580000015A0000015C00042
+:102B00000015E0000016000000162000001640002E
+:102B100000166000001680000016A0000016C0001D
+:102B20000016E0000017000000172000001740000A
+:102B300000176000001780000017A0000017C000F9
+:102B40000017E000001800000018200000184000E6
+:102B500000186000001880000018A0000018C000D5
+:102B60000018E000001900000019200000194000C2
+:102B700000196000001980000019A0000019C000B1
+:102B80000019E000001A0000001A2000001A40009E
+:102B9000001A6000001A8000001AA000001AC0008D
+:102BA000001AE000001B0000001B2000001B40007A
+:102BB000001B6000001B8000001BA000001BC00069
+:102BC000001BE000001C0000001C2000001C400056
+:102BD000001C6000001C8000001CA000001CC00045
+:102BE000001CE000001D0000001D2000001D400032
+:102BF000001D6000001D8000001DA000001DC00021
+:102C0000001DE000001E0000001E2000001E40000D
+:102C1000001E6000001E8000001EA000001EC000FC
+:102C2000001EE000001F0000001F2000001F4000E9
+:102C3000001F6000001F8000001FA000001FC000D8
+:102C4000001FE000002000000020200000204000C5
+:102C500000206000002080000020A0000020C000B4
+:102C60000020E000002100000021200000214000A1
+:102C700000216000002180000021A0000021C00090
+:102C80000021E0000022000000222000002240007D
+:102C900000226000002280000022A0000022C0006C
+:102CA0000022E00000230000002320000023400059
+:102CB00000236000002380000023A0000023C00048
+:102CC0000023E00000240000002420000024400035
+:102CD00000246000002480000024A0000024C00024
+:102CE0000024E00000250000002520000025400011
+:102CF00000256000002580000025A0000025C00000
+:102D00000025E000002600000026200000264000EC
+:102D100000266000002680000026A0000026C000DB
+:102D20000026E000002700000027200000274000C8
+:102D300000276000002780000027A0000027C000B7
+:102D40000027E000002800000028200000284000A4
+:102D500000286000002880000028A0000028C00093
+:102D60000028E00000290000002920000029400080
+:102D700000296000002980000029A0000029C0006F
+:102D80000029E000002A0000002A2000002A40005C
+:102D9000002A6000002A8000002AA000002AC0004B
+:102DA000002AE000002B0000002B2000002B400038
+:102DB000002B6000002B8000002BA000002BC00027
+:102DC000002BE000002C0000002C2000002C400014
+:102DD000002C6000002C8000002CA000002CC00003
+:102DE000002CE000002D0000002D2000002D4000F0
+:102DF000002D6000002D8000002DA000002DC000DF
+:102E0000002DE000002E0000002E2000002E4000CB
+:102E1000002E6000002E8000002EA000002EC000BA
+:102E2000002EE000002F0000002F2000002F4000A7
+:102E3000002F6000002F8000002FA000002FC00096
+:102E4000002FE00000300000003020000030400083
+:102E500000306000003080000030A0000030C00072
+:102E60000030E0000031000000312000003140005F
+:102E700000316000003180000031A0000031C0004E
+:102E80000031E0000032000000322000003240003B
+:102E900000326000003280000032A0000032C0002A
+:102EA0000032E00000330000003320000033400017
+:102EB00000336000003380000033A0000033C00006
+:102EC0000033E000003400000034200000344000F3
+:102ED00000346000003480000034A0000034C000E2
+:102EE0000034E000003500000035200000354000CF
+:102EF00000356000003580000035A0000035C000BE
+:102F00000035E000003600000036200000364000AA
+:102F100000366000003680000036A0000036C00099
+:102F20000036E00000370000003720000037400086
+:102F300000376000003780000037A0000037C00075
+:102F40000037E00000380000003820000038400062
+:102F500000386000003880000038A0000038C00051
+:102F60000038E0000039000000392000003940003E
+:102F700000396000003980000039A0000039C0002D
+:102F80000039E000003A0000003A2000003A40001A
+:102F9000003A6000003A8000003AA000003AC00009
+:102FA000003AE000003B0000003B2000003B4000F6
+:102FB000003B6000003B8000003BA000003BC000E5
+:102FC000003BE000003C0000003C2000003C4000D2
+:102FD000003C6000003C8000003CA000003CC000C1
+:102FE000003CE000003D0000003D2000003D4000AE
+:102FF000003D6000003D8000003DA000003DC0009D
+:10300000003DE000003E0000003E2000003E400089
+:10301000003E6000003E8000003EA000003EC00078
+:10302000003EE000003F0000003F2000003F400065
+:10303000003F6000003F8000003FA000003FC00054
+:10304000003FE000003FE00100000000000001FF41
+:10305000000002000000000100000002000000006B
+:1030600000000008021500200215002008100000D2
+:103070000000003300000002000000000000000516
+:103080000000000500000000000000000000000239
+:103090000000000300000002000000010000000426
+:1030A0000000000200000002000000010000000219
+:1030B000000000200000004000000040000000036D
+:1030C0000000001800002000000040C000006180E7
+:1030D000000082400000A3000000C3C00000E480A4
+:1030E0000001054000012600000146C00001678084
+:1030F000000188400001A9000001C9C00001EA8068
+:1031000000020B4000022C0000024CC000026D8047
+:1031100000028E400002AF000002CFC00002F0802B
+:10312000000011400000000100000001000000014B
+:10313000000000010000000100000001000000018B
+:10314000000000010000000100000001000000017B
+:10315000000000010000000100000001000000016B
+:103160000003D0000000003D00000001000D000041
+:10317000000700D000028140000B8168000202209D
+:1031800000010240000F025000010340000C00004B
+:10319000000800C000028140000B8168000202208C
+:1031A0000001024000070250000202C000100000AF
+:1031B0000008010000028180000B81A8000202606B
+:1031C00000018280000E8298000803800000000049
+:1031D000000000000002800000090028000200B882
+:1031E000000100D8000000E8000000E8FFFFFFF346
+:1031F00001AFFFFF00000000000000000000000021
+:10320000000000000000000000000000FFFFFFF1D0
+:1032100000EFFFFF000000000000000000000000C1
+:10322000000000000001000000000000FFFFFFF6AA
+:10323000005FFFFF00000000000000000000000031
+:10324000000000000002000000000000FFFFF40684
+:103250001CBFFFFF0000000500000000000000147C
+:10326000000000000004000000000000FFFFFFF26B
+:10327000004FFFFF00000000000000000000000001
+:10328000000000000008000000000000FFFFFFFA3F
+:10329000002FFFFF00000000000000000000000001
+:1032A000000000000010000000000000FFFFFFF71A
+:1032B00001EFFFFF00000000000000000000000020
+:1032C000000000000020000000000000FFFFFFF5EC
+:1032D000002FFFFF000000000000000000000000C1
+:1032E000000000000040000000000000FFFFFFF3AE
+:1032F000018FFFFF00000000000000000000000040
+:10330000000000000000000000000000FFFFFFF1CF
+:10331000010FFFFF0000000000000000000000009F
+:10332000000000000001000000000000FFFFFFF6A9
+:10333000005FFFFF00000000000000000000000030
+:10334000000000000002000000000000FFFFF40683
+:103350001CBFFFFF0000000500000000000000147B
+:10336000000000000004000000000000FFFFFFF26A
+:10337000004FFFFF00000000000000000000000000
+:10338000000000000008000000000000FFFFFFFA3E
+:10339000002FFFFF00000000000000000000000000
+:1033A000000000000010000000000000FFFFFFF719
+:1033B00000EFFFFF00000000000000000000000020
+:1033C000000000000020000000000000FFFFFFF5EB
+:1033D000004FFFFF000000000000000000000000A0
+:1033E000000000000040000000000000FFFFFFFFA1
+:1033F00000CFFFFF0000000000000000000000CC34
+:10340000000000000000000000000000FFFFFFFFC0
+:1034100000CFFFFF0000000000000000000000CC13
+:10342000000000000001000000000000FFFFFFFF9F
+:1034300000CFFFFF0000000000000000000000CCF3
+:10344000000000000002000000000000FFFFFFFF7E
+:1034500000CFFFFF0000000000000000000000CCD3
+:10346000000000000004000000000000FFFFFFFF5C
+:1034700000CFFFFF0000000000000000000000CCB3
+:10348000000000000008000000000000FFFFFFFF38
+:1034900000CFFFFF0000000000000000000000CC93
+:1034A000000000000010000000000000FFFFFFFF10
+:1034B00000CFFFFF0000000000000000000000CC73
+:1034C000000000000020000000000000FFFFFFFFE0
+:1034D00000CFFFFF0000000000000000000000CC53
+:1034E000000000000040000000000000FFFFFFF3AC
+:1034F000020FFFFF000000000000000000000000BD
+:10350000000000000000000000000000FFFFFFF1CD
+:10351000010FFFFF0000000000000000000000009D
+:10352000000000000001000000000000FFFFFFF6A7
+:10353000005FFFFF0000000000000000000000002E
+:10354000000000000002000000000000FFFFF40681
+:103550001CBFFFFF00000005000000000000001479
+:10356000000000000004000000000000FFFFFFF268
+:10357000004FFFFF000000000000000000000000FE
+:10358000000000000008000000000000FFFFFF8AAC
+:10359000042FFFFF000000000000000000000000FA
+:1035A000000000000010000000000000FFFFFF9777
+:1035B00005CFFFFF00000000000000000000000039
+:1035C000000000000020000000000000FFFFFFF5E9
+:1035D000010FFFFF000000000000000000000000DD
+:1035E000000000000040000000000000FFFFFFF3AB
+:1035F000000FFFFF000000000000000000000000BE
+:10360000000000000000000000000000FFFFFFF1CC
+:10361000000FFFFF0000000000000000000000009D
+:10362000000000000001000000000000FFFFFFF6A6
+:10363000005FFFFF0000000000000000000000002D
+:10364000000000000002000000000000FFFFFF0675
+:103650001CBFFFFF0000000000000000000000147D
+:10366000000000000004000000000000FFFFFFF267
+:10367000004FFFFF000000000000000000000000FD
+:10368000000000000008000000000000FFFFFFFA3B
+:10369000002FFFFF000000000000000000000000FD
+:1036A000000000000010000000000000FFFFFFF716
+:1036B000000FFFFF000000000000000000000000FD
+:1036C000000000000020000000000000FFFFFFFFDE
+:1036D00000CFFFFF0000000000000000000000CC51
+:1036E000000000000040000000000000FFFFFFFF9E
+:1036F00000CFFFFF0000000000000000000000CC31
+:10370000000000000000000000000000FFFFFFFFBD
+:1037100000CFFFFF0000000000000000000000CC10
+:10372000000000000001000000000000FFFFFFFF9C
+:1037300000CFFFFF0000000000000000000000CCF0
+:10374000000000000002000000000000FFFFFFFF7B
+:1037500000CFFFFF0000000000000000000000CCD0
+:10376000000000000004000000000000FFFFFFFF59
+:1037700000CFFFFF0000000000000000000000CCB0
+:10378000000000000008000000000000FFFFFFFF35
+:1037900000CFFFFF0000000000000000000000CC90
+:1037A000000000000010000000000000FFFFFFFF0D
+:1037B00000CFFFFF0000000000000000000000CC70
+:1037C000000000000020000000000000FFFFFFFFDD
+:1037D00000CFFFFF0000000000000000000000CC50
+:1037E000000000000040000000000000FFFFFFFF9D
+:1037F00000CFFFFF0000000000000000000000CC30
+:10380000000000000000000000000000FFFFFFFFBC
+:1038100000CFFFFF0000000000000000000000CC0F
+:10382000000000000001000000000000FFFFFFFF9B
+:1038300000CFFFFF0000000000000000000000CCEF
+:10384000000000000002000000000000FFFFFFFF7A
+:1038500000CFFFFF0000000000000000000000CCCF
+:10386000000000000004000000000000FFFFFFFF58
+:1038700000CFFFFF0000000000000000000000CCAF
+:10388000000000000008000000000000FFFFFFFF34
+:1038900000CFFFFF0000000000000000000000CC8F
+:1038A000000000000010000000000000FFFFFFFF0C
+:1038B00000CFFFFF0000000000000000000000CC6F
+:1038C000000000000020000000000000FFFFFFFFDC
+:1038D00000CFFFFF0000000000000000000000CC4F
+:1038E000000000000040000000000000FFFFFFFF9C
+:1038F00000CFFFFF0000000000000000000000CC2F
+:10390000000000000000000000000000FFFFFFFFBB
+:1039100000CFFFFF0000000000000000000000CC0E
+:10392000000000000001000000000000FFFFFFFF9A
+:1039300000CFFFFF0000000000000000000000CCEE
+:10394000000000000002000000000000FFFFFFFF79
+:1039500000CFFFFF0000000000000000000000CCCE
+:10396000000000000004000000000000FFFFFFFF57
+:1039700000CFFFFF0000000000000000000000CCAE
+:10398000000000000008000000000000FFFFFFFF33
+:1039900000CFFFFF0000000000000000000000CC8E
+:1039A000000000000010000000000000FFFFFFFF0B
+:1039B00000CFFFFF0000000000000000000000CC6E
+:1039C000000000000020000000000000FFFFFFFFDB
+:1039D00000CFFFFF0000000000000000000000CC4E
+:1039E0000000000000400000000000000000020095
+:1039F00000003DFF00000211000002000000020470
+:103A00000000FFFF0000FFFF0000FFFF0000FFFFBE
+:103A10000000002000000021000000220000002320
+:103A20000000002400000025000000260000002700
+:103A300000000028000000290000002A0000002BE0
+:103A40000000002C0000002D0000002E0000002FC0
+:103A50000000001000000001000000010000000153
+:103A60000000000100000001000000010000000152
+:103A70000000000100000001000000010000000142
+:103A80000000000100000001000000010000000132
+:103A9000000000010000000107FFFFFF0000003FE1
+:103AA00007FFFFFF0000000F00007FF800007FF815
+:103AB0000000FF00000000000000FF000000000008
+:103AC0000000FF00000000000000FF0000000000F8
+:103AD0000000FF00000000000000FF0000000000E8
+:103AE0000000FF00000000000000FF0000000000D8
+:103AF0000000FF1C0FFFFFFF0000FF1C0FFFFFFF78
+:103B00000000FF1C0FFFFFFF0000FF1C0FFFFFFF67
+:103B10000000FF1C0FFFFFFF0000FF1C0FFFFFFF57
+:103B20000000FF1C0FFFFFFF0000FF1C0FFFFFFF47
+:103B30000000FF1C0FFFFFFF0000FF1C0FFFFFFF37
+:103B40000000FF1C0FFFFFFF0000FF1C0FFFFFFF27
+:103B50000000FF1C0FFFFFFF0000FF1C0FFFFFFF17
+:103B60000000FF1C0FFFFFFF0000FF1C0FFFFFFF07
+:103B70000000FF1C0FFFFFFF0000FF1C0FFFFFFFF7
+:103B80000000FF1C0FFFFFFF0000FF1C0FFFFFFFE7
+:103B90000000FF1C0FFFFFFF0000FF1C0FFFFFFFD7
+:103BA0000000FF1C0FFFFFFF0000FF1C0FFFFFFFC7
+:103BB0000000FF1C0FFFFFFF0000FF1C0FFFFFFFB7
+:103BC0000000FF1C0FFFFFFF0000FF1C0FFFFFFFA7
+:103BD0000000FF1C0FFFFFFF0000FF1C0FFFFFFF97
+:103BE0000000FF1C0FFFFFFF0000FF1C0FFFFFFF87
+:103BF0000000FF1C0FFFFFFF0000FF1C0FFFFFFF77
+:103C00000000FF1C0FFFFFFF0000FF1C0FFFFFFF66
+:103C10000000FF1C0FFFFFFF0000FF1C0FFFFFFF56
+:103C20000000FF1C0FFFFFFF0000FF1C0FFFFFFF46
+:103C30000000FF1C0FFFFFFF0000FF1C0FFFFFFF36
+:103C40000000FF1C0FFFFFFF0000FF1C0FFFFFFF26
+:103C50000000FF1C0FFFFFFF0000FF1C0FFFFFFF16
+:103C60000000FF1C0FFFFFFF0000FF1C0FFFFFFF06
+:103C70000000FF1C0FFFFFFF0000FF1C0FFFFFFFF6
+:103C80000000FF1C0FFFFFFF0000FF1C0FFFFFFFE6
+:103C90000000FF1C0FFFFFFF0000FF1C0FFFFFFFD6
+:103CA0000000FF1C0FFFFFFF0000FF1C0FFFFFFFC6
+:103CB0000000FF1C0FFFFFFF0000FF1C0FFFFFFFB6
+:103CC0000000FF1C0FFFFFFF0000FF1C0FFFFFFFA6
+:103CD0000000FF1C0FFFFFFF0000FF1C0FFFFFFF96
+:103CE0000000FF1C0FFFFFFF0000FF1C0FFFFFFF86
+:103CF00000000002000015000000000100000002AA
+:103D000000000003000000000000000400000001AB
+:103D1000000000000000000100000004000000009E
+:103D2000000000010000000300000000000000018E
+:103D3000000000040000000000000001000000037B
+:103D4000000000000000000100000004000000006E
+:103D5000000000040000000300000000000000005C
+:103D600000003FFF000003FF000000000000000112
+:103D70000000000100000001007C100400000004AD
+:103D80000000000200000090000000900080009001
+:103D9000081000000000008A000000800000008180
+:103DA0000000008000000006000007D00000076C43
+:103DB000071D291100000000009C042400000000E1
+:103DC00000000001000000010000000100000001EF
+:103DD0000000000100007FFF000000FF000000FF66
+:103DE000000000FF000000FF0000007F000000FF57
+:103DF000000000FF000000FF0000003E0000000087
+:103E00000000003F0000003F0000003F0000003FB6
+:103E10000000003F0000003F0000003F0000000FD6
+:103E200000000000121700002217000032170000E7
+:103E300012150000221500003215000002100000CB
+:103E400000100000101000002010000030100000D2
+:103E500000100000121400002214000032140000B0
+:103E600000E38340FFFFFFFFFFFFFFFFFFFFFFFFB8
+:103E7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF52
+:103E8000FFFFFFFFF0005000F0001000FFFFFFFFFA
+:103E9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF32
+:103EA000FFFFFFFFFF809000FFFFFFFFFFFFFFFF0F
+:103EB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF12
+:103EC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02
+:103ED000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2
+:103EE000FFFFFFFF00003C10000000010000000089
+:103EF00000000008000000080000000200000004AC
+:103F00000000000500000004000000400000180848
+:103F10000000080300000803000000400000000348
+:103F2000000008030000080300000803000100036C
+:103F30000000080300000803000000030000000365
+:103F40000000000300000003000000030000000365
+:103F50000000000300000003000000030000000355
+:103F60000000000300000003000000030000000345
+:103F700000000003000024030000002F00000009DF
+:103F80000000001900000184000001830000030606
+:103F900000000019000000060000030600000306F0
+:103FA0000000030600000C86000003060000030664
+:103FB00000000006000000060000000600000006E9
+:103FC00000000006000000060000000600000006D9
+:103FD00000000006000000060000000600000006C9
+:103FE00000000006000000060000000600000306B6
+:103FF0000000001300000006000010040000100480
+:104000000010644000106440000000000000000048
+:104010000000000000000000000020000000000080
+:10402000000000000000000000000000040020006C
+:104030000000000000000000000000000000000080
+:10404000000020000000007C0000003D0000003F58
+:104050000000009C00000006000000050000000AAF
+:1040600000000005000001400000014000000000C9
+:1040700000000000000000C00000013F00007FFFC2
+:1040800000000048000000480000000000000000A0
+:1040900000000048000000040000000400000004CC
+:1040A0000000000400000004000000040000000400
+:1040B0000000000400000004000000090000000BE4
+:1040C0000000000A00000004000000090000000BCE
+:1040D0000000000A000000010000000100000001D3
+:1040E00000000001000000010000000100000001CC
+:1040F00000000001000000010000000100000001BC
+:104100000000000100000004000000090000000B96
+:104110000000000A00000001000000010000000192
+:10412000000000010000000100000001000000018B
+:10413000000000010000000100000001000000017B
+:104140000000000100000004000000090000000B56
+:104150000000000A0000000000000000000008004D
+:1041600000000200000001FF000004000000000049
+:10417000000000001E491E491E491E490E490E49F5
+:104180000E490E49FFFFFFFF00000000000025E47C
+:1041900000008000000000130FFF0FFF0000000070
+:1041A000000000000FFF0FFF1000100010001000B3
+:1041B000200020002000200080008000800080007F
+:1041C00040004000400040000000000000000001EE
+:1041D0000101010101200101200101010101100182
+:1041E0000101010101200101200101010101100172
+:1041F0002001010101011001010101010120010162
+:104200002001010101011001010101010120010151
+:104210000101010101200101200101010101100141
+:104220000101010101200101200101010101100131
+:104230000101010101200101200101010101100121
+:104240000101010101200101200101010101100111
+:1042500000000004000000090000000B0000000A3C
+:1042600000000004000000090000000B0000000A2C
+:10427000000000010000000100000001000000013A
+:10428000000000010000000100000001000000012A
+:10429000000000010000000100000001000000011A
+:1042A00000000004000000090000000B0000000AEC
+:1042B00000000001000000010000000100000001FA
+:1042C00000000001000000010000000100000001EA
+:1042D00000000001000000010000000100000001DA
+:1042E00000000004000000090000000B0000000AAC
+:1042F0001E491E491E491E490E490E490E490E49C6
+:10430000FFFFFFFF000000000FFF0FFF0000000095
+:10431000000000000FFF0FFF100010001000100041
+:10432000200020002000200080008000800080000D
+:10433000400040004000400000000000000000027B
+:10434000000000010000000300000004000000065F
+:104350000000000500000007000001230000012309
+:1043600000000123000001230000012300000123BD
+:1043700000000123000001230000012300000123AD
+:10438000000001230000012300000123000001239D
+:10439000000001230000012300000123000001238D
+:1043A0000000012300000123000000200000003273
+:1043B00000000007000000070000000000000008E7
+:1043C0000215002002150020000000300810000037
+:1043D0000000003300000030000000310000000247
+:1043E00000000005000000060000000200000002BE
+:1043F00000000000000000050000000200000002B4
+:1044000000000002000000010000000600000001A2
+:1044100000000002000000400000004000000020FA
+:10442000000000130000002000010000000204C092
+:104430000003098000040E4000051300000617C0A9
+:1044400000071C800008214000092600000A2AC03D
+:10445000000B2F80000C3440000D3900000E3DC0D1
+:10446000000F42800010474000114C00001250C065
+:104470000013558000145A4000155F00001663C0F9
+:104480000017688000186D4000197200001A76C08D
+:10449000001B7B80001C8040001D8500001E89C021
+:1044A000001F8E800000934000000001000000010A
+:1044B00000000001000000010000000100000001F8
+:1044C00000000001000000010000000100000001E8
+:1044D00000000001000000010000000100000001D8
+:1044E0000000000100000001000000080000000CB6
+:1044F00000000010000000010000000100000001A9
+:104500000000021100000200000002040000021975
+:104510000000FFFF0000FFFF0000FFFF0000FFFFA3
+:1045200007FFFFFF0000003F07FFFFFF0000000F35
+:1045300000007FF800007FF800000000000000018C
+:1045400000201001000000000100900000000100A8
+:10455000000000010000000000000000140AFF003D
+:1045600000009002000000000000000000000000B9
+:1045700000009004000000000000000000000000A7
+:104580000000900600000000000000000000000095
+:104590000000900800000000000000000000000083
+:1045A0000000900A00000000000000000000000071
+:1045B0000000900C0000000000000000000000005F
+:1045C0000000900E0000000000000000000000004D
+:1045D000000090100000000000000000000000003B
+:1045E0000000901200000000000000000000000029
+:1045F0000000901400000000000000000000000017
+:104600000000901600000000000000000000000004
+:1046100000009018000000000000000000000000F2
+:104620000000901A000000000000000000000000E0
+:104630000000901C000000000000000000000000CE
+:104640000000901E000000000000000000000000BC
+:1046500000009020000000000000000000000000AA
+:104660000000902200000000000000000000000098
+:104670000000902400000000000000000000000086
+:104680000000902600000000000000000000000074
+:104690000000902800000000000000000000000062
+:1046A0000000902A00000000000000000000000050
+:1046B0000000902C0000000000000000000000003E
+:1046C0000000902E0000000000000000000000002C
+:1046D000000090300000000000000000000000001A
+:1046E0000000903200000000000000000000000008
+:1046F00000009034000000000000000000000000F6
+:1047000000009036000000000000000000000000E3
+:1047100000009038000000000000000000000000D1
+:104720000000903A000000000000000000000000BF
+:104730000000903C000000000000000000000000AD
+:104740000000903E0000000000000000000000009B
+:104750000000904000000000000000000000000089
+:104760000000904200000000000000000000000077
+:104770000000904400000000000000000000000065
+:104780000000904600000000000000000000000053
+:104790000000904800000000000000000000000041
+:1047A0000000904A0000000000000000000000002F
+:1047B0000000904C0000000000000000000000001D
+:1047C0000000904E0000000000000000000000000B
+:1047D00000009050000000000000000000000000F9
+:1047E00000009052000000000000000000000000E7
+:1047F00000009054000000000000000000000000D5
+:1048000000009056000000000000000000000000C2
+:1048100000009058000000000000000000000000B0
+:104820000000905A0000000000000000000000009E
+:104830000000905C0000000000000000000000008C
+:104840000000905E0000000000000000000000007A
+:104850000000906000000000000000000000000068
+:104860000000906200000000000000000000000056
+:104870000000906400000000000000000000000044
+:104880000000906600000000000000000000000032
+:104890000000906800000000000000000000000020
+:1048A0000000906A0000000000000000000000000E
+:1048B0000000906C000000000000000000000000FC
+:1048C0000000906E000000000000000000000000EA
+:1048D00000009070000000000000000000000000D8
+:1048E00000009072000000000000000000000000C6
+:1048F00000009074000000000000000000000000B4
+:1049000000009076000000000000000000000000A1
+:10491000000090780000000000000000000000008F
+:104920000000907A0000000000000000000000007D
+:104930000000907C0000000000000000000000006B
+:104940000000907E00000000000000000000000059
+:104950000000908000000000000000000000000047
+:104960000000908200000000000000000000000035
+:104970000000908400000000000000000000000023
+:104980000000908600000000000000000000000011
+:1049900000009088000000000000000000000000FF
+:1049A0000000908A000000000000000000000000ED
+:1049B0000000908C000000000000000000000000DB
+:1049C0000000908E000000000000000000000000C9
+:1049D00000009090000000000000000000000000B7
+:1049E00000009092000000000000000000000000A5
+:1049F0000000909400000000000000000000000093
+:104A00000000909600000000000000000000000080
+:104A1000000090980000000000000000000000006E
+:104A20000000909A0000000000000000000000005C
+:104A30000000909C0000000000000000000000004A
+:104A40000000909E00000000000000000000000038
+:104A5000000090A000000000000000000000000026
+:104A6000000090A200000000000000000000000014
+:104A7000000090A400000000000000000000000002
+:104A8000000090A6000000000000000000000000F0
+:104A9000000090A8000000000000000000000000DE
+:104AA000000090AA000000000000000000000000CC
+:104AB000000090AC000000000000000000000000BA
+:104AC000000090AE000000000000000000000000A8
+:104AD000000090B000000000000000000000000096
+:104AE000000090B200000000000000000000000084
+:104AF000000090B400000000000000000000000072
+:104B0000000090B60000000000000000000000005F
+:104B1000000090B80000000000000000000000004D
+:104B2000000090BA0000000000000000000000003B
+:104B3000000090BC00000000000000000000000029
+:104B4000000090BE00000000000000000000000017
+:104B5000000090C000000000000000000000000005
+:104B6000000090C2000000000000000000000000F3
+:104B7000000090C4000000000000000000000000E1
+:104B8000000090C6000000000000000000000000CF
+:104B9000000090C8000000000000000000000000BD
+:104BA000000090CA000000000000000000000000AB
+:104BB000000090CC00000000000000000000000099
+:104BC000000090CE00000000000000000000000087
+:104BD000000090D000000000000000000000000075
+:104BE000000090D200000000000000000000000063
+:104BF000000090D400000000000000000000000051
+:104C0000000090D60000000000000000000000003E
+:104C1000000090D80000000000000000000000002C
+:104C2000000090DA0000000000000000000000001A
+:104C3000000090DC00000000000000000000000008
+:104C4000000090DE000000000000000000000000F6
+:104C5000000090E0000000000000000000000000E4
+:104C6000000090E2000000000000000000000000D2
+:104C7000000090E4000000000000000000000000C0
+:104C8000000090E6000000000000000000000000AE
+:104C9000000090E80000000000000000000000009C
+:104CA000000090EA0000000000000000000000008A
+:104CB000000090EC00000000000000000000000078
+:104CC000000090EE00000000000000000000000066
+:104CD000000090F000000000000000000000000054
+:104CE000000090F200000000000000000000000042
+:104CF000000090F400000000000000000000000030
+:104D0000000090F60000000000000000000000001D
+:104D1000000090F80000000000000000000000000B
+:104D2000000090FA000000000000000000000000F9
+:104D3000000090FC000000000000000000000000E7
+:104D4000000090FE000000000000000000000000D5
+:104D500000009100000000000000000000000000C2
+:104D600000009102000000000000000000000000B0
+:104D7000000091040000000000000000000000009E
+:104D8000000091060000000000000000000000008C
+:104D9000000091080000000000000000000000007A
+:104DA0000000910A00000000000000000000000068
+:104DB0000000910C00000000000000000000000056
+:104DC0000000910E00000000000000000000000044
+:104DD0000000911000000000000000000000000032
+:104DE0000000911200000000000000000000000020
+:104DF000000091140000000000000000000000000E
+:104E000000009116000000000000000000000000FB
+:104E100000009118000000000000000000000000E9
+:104E20000000911A000000000000000000000000D7
+:104E30000000911C000000000000000000000000C5
+:104E40000000911E000000000000000000000000B3
+:104E500000009120000000000000000000000000A1
+:104E6000000091220000000000000000000000008F
+:104E7000000091240000000000000000000000007D
+:104E8000000091260000000000000000000000006B
+:104E90000000912800000000000000000000000059
+:104EA0000000912A00000000000000000000000047
+:104EB0000000912C00000000000000000000000035
+:104EC0000000912E00000000000000000000000023
+:104ED0000000913000000000000000000000000011
+:104EE00000009132000000000000000000000000FF
+:104EF00000009134000000000000000000000000ED
+:104F000000009136000000000000000000000000DA
+:104F100000009138000000000000000000000000C8
+:104F20000000913A000000000000000000000000B6
+:104F30000000913C000000000000000000000000A4
+:104F40000000913E00000000000000000000000092
+:104F50000000914000000000000000000000000080
+:104F6000000091420000000000000000000000006E
+:104F7000000091440000000000000000000000005C
+:104F8000000091460000000000000000000000004A
+:104F90000000914800000000000000000000000038
+:104FA0000000914A00000000000000000000000026
+:104FB0000000914C00000000000000000000000014
+:104FC0000000914E00000000000000000000000002
+:104FD00000009150000000000000000000000000F0
+:104FE00000009152000000000000000000000000DE
+:104FF00000009154000000000000000000000000CC
+:1050000000009156000000000000000000000000B9
+:1050100000009158000000000000000000000000A7
+:105020000000915A00000000000000000000000095
+:105030000000915C00000000000000000000000083
+:105040000000915E00000000000000000000000071
+:10505000000091600000000000000000000000005F
+:10506000000091620000000000000000000000004D
+:10507000000091640000000000000000000000003B
+:105080000000916600000000000000000000000029
+:105090000000916800000000000000000000000017
+:1050A0000000916A00000000000000000000000005
+:1050B0000000916C000000000000000000000000F3
+:1050C0000000916E000000000000000000000000E1
+:1050D00000009170000000000000000000000000CF
+:1050E00000009172000000000000000000000000BD
+:1050F00000009174000000000000000000000000AB
+:105100000000917600000000000000000000000098
+:105110000000917800000000000000000000000086
+:105120000000917A00000000000000000000000074
+:105130000000917C00000000000000000000000062
+:105140000000917E00000000000000000000000050
+:10515000000091800000000000000000000000003E
+:10516000000091820000000000000000000000002C
+:10517000000091840000000000000000000000001A
+:105180000000918600000000000000000000000008
+:1051900000009188000000000000000000000000F6
+:1051A0000000918A000000000000000000000000E4
+:1051B0000000918C000000000000000000000000D2
+:1051C0000000918E000000000000000000000000C0
+:1051D00000009190000000000000000000000000AE
+:1051E000000091920000000000000000000000009C
+:1051F000000091940000000000000000000000008A
+:105200000000919600000000000000000000000077
+:105210000000919800000000000000000000000065
+:105220000000919A00000000000000000000000053
+:105230000000919C00000000000000000000000041
+:105240000000919E0000000000000000000000002F
+:10525000000091A00000000000000000000000001D
+:10526000000091A20000000000000000000000000B
+:10527000000091A4000000000000000000000000F9
+:10528000000091A6000000000000000000000000E7
+:10529000000091A8000000000000000000000000D5
+:1052A000000091AA000000000000000000000000C3
+:1052B000000091AC000000000000000000000000B1
+:1052C000000091AE0000000000000000000000009F
+:1052D000000091B00000000000000000000000008D
+:1052E000000091B20000000000000000000000007B
+:1052F000000091B400000000000000000000000069
+:10530000000091B600000000000000000000000056
+:10531000000091B800000000000000000000000044
+:10532000000091BA00000000000000000000000032
+:10533000000091BC00000000000000000000000020
+:10534000000091BE0000000000000000000000000E
+:10535000000091C0000000000000000000000000FC
+:10536000000091C2000000000000000000000000EA
+:10537000000091C4000000000000000000000000D8
+:10538000000091C6000000000000000000000000C6
+:10539000000091C8000000000000000000000000B4
+:1053A000000091CA000000000000000000000000A2
+:1053B000000091CC00000000000000000000000090
+:1053C000000091CE0000000000000000000000007E
+:1053D000000091D00000000000000000000000006C
+:1053E000000091D20000000000000000000000005A
+:1053F000000091D400000000000000000000000048
+:10540000000091D600000000000000000000000035
+:10541000000091D800000000000000000000000023
+:10542000000091DA00000000000000000000000011
+:10543000000091DC000000000000000000000000FF
+:10544000000091DE000000000000000000000000ED
+:10545000000091E0000000000000000000000000DB
+:10546000000091E2000000000000000000000000C9
+:10547000000091E4000000000000000000000000B7
+:10548000000091E6000000000000000000000000A5
+:10549000000091E800000000000000000000000093
+:1054A000000091EA00000000000000000000000081
+:1054B000000091EC0000000000000000000000006F
+:1054C000000091EE0000000000000000000000005D
+:1054D000000091F00000000000000000000000004B
+:1054E000000091F200000000000000000000000039
+:1054F000000091F400000000000000000000000027
+:10550000000091F600000000000000000000000014
+:10551000000091F800000000000000000000000002
+:10552000000091FA000000000000000000000000F0
+:10553000000091FC000000000000000000000000DE
+:10554000000091FE0000FF00000000000000FF00CE
+:10555000000000000000FF00000000000000FF004D
+:10556000000000000000FF00000000000000FF003D
+:10557000000000000000FF00000000000000FF002D
+:105580000000000000000002000015000000000103
+:105590000000000200000003000000000000000402
+:1055A00000000001000000000000000100000004F5
+:1055B00000000000000000010000000300000000E7
+:1055C00000000001000000040000000000000001D5
+:1055D00000000003000000000000000100000004C3
+:1055E00000000000000000040000000300000000B4
+:1055F0000000000000003FFF000003FF0000000368
+:1056000000BEBC20000000000000000500000003F8
+:1056100000BEBC20000000000000000500000003E8
+:1056200000BEBC20000000000000000500000003D8
+:1056300000BEBC20000000000000000500000003C8
+:1056400000BEBC20000000000000000500000003B8
+:1056500000BEBC20000000000000000500000003A8
+:1056600000BEBC2000000000000000050000000398
+:1056700000BEBC2000000000000000050000000D7E
+:105680000000000C000000000000001002150020C7
+:105690000215002000000030081000000000003358
+:1056A0000000003000000031000000020000000493
+:1056B00000000000000000020000000200000000E6
+:1056C00000000002000000070000000200000002CD
+:1056D00000000001000000030000000100000002C3
+:1056E0000000004000000040000000040000002016
+:1056F0000000000F0000001B00008000000103C03C
+:105700000001878000020B4000028F00000312C0DE
+:105710000003968000041A4000049E00000521C08A
+:105720000005A580000629400006AD00000730C036
+:105730000007B480000838400008BC0000093FC0E2
+:105740000009C380000A4740000ACB00000B4EC08E
+:10575000000BD280000C5640000CDA00000D5DC03A
+:105760000000618000000001000000010000000155
+:105770000000000100000001000000010000000125
+:105780000000000100000001000000010000000115
+:105790000000000100000001000000010000000105
+:1057A00000000001000000010000101100001000C6
+:1057B00000001004000010210000FFFF0000FFFFA8
+:1057C0000000FFFF0000FFFF000000460000001087
+:1057D00000000000000000000000001800000001B0
+:1057E00000000000000000000000000000000001B8
+:1057F00007FFFFFF0000003F07FFFFFF0000000F53
+:1058000000007FF800007FF8000019000000000091
+:10581000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF98
+:10582000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF88
+:105830000000FF00000000000000FF00000000006A
+:105840000000FF00000000000000FF00000000005A
+:105850000000FF00000000000000FF00000000004A
+:105860000000FF00000000000000FF00000000003A
+:10587000000000020000150000000001000000020E
+:105880000000000300000000000000040000000110
+:105890000000000000000001000000040000000003
+:1058A00000000001000000030000000000000001F3
+:1058B00000000004000000000000000100000003E0
+:1058C00000000000000000010000000400000000D3
+:1058D00000000004000000030000000000000000C1
+:1058E00000003FFF000003FF00000000039387005B
+:1058F000000000000000000000000000039387008B
+:1059000000000000000000000000000F0000000781
+:10591000000000000000000E031500200315002009
+:1059200001000030081000000000003300000030CB
+:10593000000000310000000300000006000000032A
+:105940000000000300000002000000000000000250
+:10595000000000000000000600000004000000023B
+:10596000000000020000000100000004000000012F
+:1059700000000002000000400000004000000004A1
+:1059800000000020000000020000002000001000C5
+:105990000000208000003100000041800000520023
+:1059A000000062800000730000008380000094000B
+:1059B0000000A4800000B5000000C5800000D600F3
+:1059C0000000E6800000F7000001078000011800D9
+:1059D00000012880000139000001498000015A00BF
+:1059E00000016A8000017B0000018B8000019C00A7
+:1059F0000001AC800001BD000001CD800001DE008F
+:105A00000001EE800001FF0000000F800000000197
+:105A10000000000100000001000000010000000182
+:105A20000000000100000001000000010000000172
+:105A30000000000100000001000000010000000162
+:105A40000000000100000001000000010000000152
+:105A5000000000010000000100000001000012240D
+:105A600000001210000012140000FFFF0000FFFFF2
+:105A70000000FFFF0000FFFF0000002000000020EA
+:105A800000000000000000000000002300000024CF
+:105A9000000000250000002600000027000000296B
+:105AA0000000002A0000002B0000002C0000000174
+:105AB0000000000107FFFFFF0000003F07FFFFFF9E
+:105AC0000000000F00007FF800007FF800000000D9
+:105AD00000000001CCCC0201CCCCCCCCCCCC02015F
+:105AE000CCCCCCCCCCCC0201CCCCCCCCCCCC020120
+:105AF000CCCCCCCCCCCC0201CCCCCCCCCCCC020110
+:105B0000CCCCCCCCCCCC0201CCCCCCCCCCCC0201FF
+:105B1000CCCCCCCCFFFFFFFFFFFFFFFFFFFFFFFF61
+:105B2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF85
+:105B3000FFFFFFFF0000000000010001001E0C0736
+:105B4000CCCCCCC510000000000028AD7058103C33
+:105B5000000000000000FF00000000000000FF0047
+:105B6000000000000000FF00000000000000FF0037
+:105B7000000000000000FF00000000000000FF0027
+:105B8000000000000000FF00000000000000FF0017
+:105B900000000000000000020000150000000001ED
+:105BA00000000002000000030000000000000004EC
+:105BB00000000001000000000000000100000004DF
+:105BC00000000000000000010000000300000000D1
+:105BD00000000001000000040000000000000001BF
+:105BE00000000003000000000000000100000004AD
+:105BF000000000000000000400000003000000009E
+:105C00000000000000003FFF000003FF002625A069
+:105C100000000000002625A000000000002625A0AE
+:105C200000000000002625A000000000000E00007B
+:105C3000011600D6002625A000000000002625A0A1
+:105C400000000000002625A000000000002625A07E
+:105C50000000000000720000012300F30000FFFFBD
+:105C6000000000000000FFFF000000000000FFFF38
+:105C7000000000000000FFFF000000000000FFFF28
+:105C8000000000000000FFFF000000000000000016
+:105C9000000000000000FFFF000000000000FFFF08
+:105CA000000000000000FFFF000000000000FFFFF8
+:105CB000000000000000FFFF000000000000FFFFE8
+:105CC000000000000000FFFF0000000000000000D6
+:105CD000000000000000FFFF000000000000FFFFC8
+:105CE000000000000000FFFF000000000000FFFFB8
+:105CF000000000000000FFFF000000000000FFFFA8
+:105D0000000000000000FFFF000000000000000095
+:105D1000000000000000FFFF000000000000FFFF87
+:105D2000000000000000FFFF000000000000FFFF77
+:105D3000000000000000FFFF000000000000FFFF67
+:105D4000000000000000FFFF000000000000000055
+:105D5000000000000000FFFF000000000000FFFF47
+:105D6000000000000000FFFF000000000000FFFF37
+:105D7000000000000000FFFF000000000000FFFF27
+:105D8000000000000000FFFF000000000000000015
+:105D9000000000000000FFFF000000000000FFFF07
+:105DA000000000000000FFFF000000000000FFFFF7
+:105DB000000000000000FFFF000000000000FFFFE7
+:105DC000000000000000FFFF0000000000000000D5
+:105DD000000000000000FFFF000000000000FFFFC7
+:105DE000000000000000FFFF000000000000FFFFB7
+:105DF000000000000000FFFF000000000000FFFFA7
+:105E0000000000000000FFFF000000000000000094
+:105E1000000000000000FFFF000000000000FFFF86
+:105E2000000000000000FFFF000000000000FFFF76
+:105E3000000000000000FFFF000000000000FFFF66
+:105E4000000000000000FFFF000000000000000054
+:105E5000000000000000FFFF00000000555400009B
+:105E60005555555500005555F0000000555400009B
+:105E70005555555500005555F0000000555400008B
+:105E80005555555500005555F00000000000000024
+:105E9000000100000000501400000000FF5C000042
+:105EA000FFF55FFF0000FFFFF00003E000000000CF
+:105EB0000000A0000000040000000000000000003E
+:105EC00000000000000010000000000000000000C2
+:105ED0000000000000004000000000000000000082
+:105EE0000000000000010000FF5C0000FFF55FFF04
+:105EF0000000FFFFF00003E0000000000000A00031
+:105F00000000080000000000000000000000000089
+:105F10000000200000000000000000000000000061
+:105F200000008000000000000000000000000000F1
+:105F300000020000000000001F8B080000000000AD
+:105F4000000BFB51CFC0F003096FE440E50BB3A099
+:105F5000F2D171152B7E794298878132FDBACC0C33
+:105F60000CE6405C07C48ECCF8D5F232618A7D968F
+:105F700044B067893330308942D826A294B96B1473
+:105F80000F0DBC4B0595BF4E09429B42C577A3C977
+:105F9000AF87CA27C943E83D2AD8CD4D86CA03003A
+:105FA000760E86656003000000000000000000001F
+:105FB0001F8B080000000000000BED7D6D6054D5C4
+:105FC00099F0B93377EE7C676E42122624C19B109C
+:105FD0002140C0490810BA717B13828C6D5A0708A2
+:105FE0009A6AB483504D153458DA66BBEECE255FFD
+:105FF000C48010B4C554B13BA6D697EDBA6D74A356
+:10600000C5ADED3B8876E9DBF66D4AD0A2A2446BC4
+:1060100069BBD536B67E75D75DF73CCF3967E6DE0E
+:106020009B4C0057DFB73F96EE7A3873BE9EF37CE9
+:106030009FE73CE7E20ECC25851F25E43DF843CBE6
+:106040005D2E7258BA8810AF27726C9346EB84FEAF
+:106050005945481F9445F4FF930E99AC20C447D886
+:106060001F6789E325770E211F77D2CE05F487704D
+:106070001EF677053A489CFE44B6861CA49090CF45
+:106080007B58FFB7BD394B4988904E0F2BBFE8CBEB
+:106090001986B23741486A01B4CF4D123A9F42483F
+:1060A000A55C0B237C916F9441D9B132B604CB8BA4
+:1060B000A09C431C842C877A897AC6CFE67ECF09C0
+:1060C000FFFD6B02F089F5C8A97803ACEF24E24F1D
+:1060D00094C07827D9F3BA732921724788DC5A43D0
+:1060E000EBAA42527CCC7BB8B1B6503C90C18BBD80
+:1060F000EC3CD5907CB232D37F3109E69F594CFFFE
+:10610000221319E1E0E3093108ACEF86BF6A53E7D7
+:10611000793BA1279F744DC553B675059E06121E87
+:1061200092A2937627542C7D25444F06902EFAC3D5
+:10613000553043D270E4533A6AE50F0F10131C5EDA
+:10614000064794488C5E246EC1577FC91D1E7D860C
+:106150007D930A8A27B1EFF2A9FBA3A4D047E8FAFE
+:106160007E0ACF30EE7F2435131C9F4AC3D14ECC1C
+:10617000FB3F7F383E6719EF5A48C818AC2FD3F55C
+:106180004CF3108DD159D6F8B873C4BB92EFB0F070
+:1061900087BFD267A9CB813C2BFF4CE1CB41CEAF6F
+:1061A0003127E363514F223FBAE69238E0AD1B7EC0
+:1061B0002AE2AC4AF1E656235F1F9080AB15EC2F24
+:1061C000E77B0C27CA5BFCAF717C33B1C8A38BCED5
+:1061D0002BD1FEAEC2CA501CF820C0E4D1BE9F5DD8
+:1061E0000923295F6891FBD691008307D7994B92C9
+:1061F000B3A87C9077576BEB83D9F1325E4AC7D155
+:1062000075D6D335611D01B75CC2E0BE03E0A6F4CC
+:10621000959BDD06C81B85FB0EA4B70D6EAF1A2338
+:1062200020D2E39F58C0E08E16201EECEBADF77431
+:1062300027E5659C8F906F880EF42B15FB9718FE51
+:10624000F61711C4D3BDE1CA271C94D66525910861
+:10625000CC7F4778E8082DC88F95F8308C77971059
+:1062600009D62BDD3149405E075C6C3F6B9CF5DE47
+:10627000976979677379E85AFAFB31E0D3E553E11E
+:106280003948E551A6F2BB9BCA23E0F3ED1718FC91
+:10629000D9F0D5972016BCF775C8D124EDDF177E4D
+:1062A00022772DC55B6F7E450DB24BBB24C3BE7CF0
+:1062B0001293937FE6EB1FDCFE0502F3533CFE33A3
+:1062C000C0EFCA1F244CCFC408E32B0A8F091FE577
+:1062D0007A5257617F5187017ABA8CEB85703F897A
+:1062E000A4181E8EC2BC459593BA9BAEA3C6558713
+:1062F000A265F04048E48715B4FFD00F2FAC1930E9
+:10630000C9874BE2FA373F9FD15D8E54C6A6E11391
+:1063100041A7BD144F552EE47B09FA7D0DEA263CBA
+:10632000F492F809E85754E743BA156D89B8605FED
+:10633000C725014718F5540FDFD7DE8FF890CF7AC5
+:106340004AD5FB9CD43E9C16F6E0A064E12B8AA7BC
+:10635000D38C4F187E6495E1EBA4147F99AD9734EC
+:106360004077E56CD1418D926E0769473930C81886
+:10637000CC334722993F743DB5561B06BEFE23D74A
+:106380005B739AFAB63B005E4D46FCCE99D8D44C6E
+:10639000289F074F5DFA1B28E9EF2FB96959DA3EAC
+:1063A00069001F16D7261B00BFBEAD830D80EFFF0F
+:1063B0002BC5FF0870176F21EB9A907527507E87C9
+:1063C0005C49A2823EAF1FD36301A0FB25649349C1
+:1063D0008FC9807F90AB4AA6F705DDEF75327EB995
+:1063E000237ADC7B7D00FAF9102FE5A44987F9CAEE
+:1063F000A8B848741FBE0CFD9D129D27B46310966B
+:10640000256AA5DA057052BE9F0D7C36E4328A609B
+:10641000DCD076A535C9F07202F832C7C171A2D1BD
+:10642000FF513CA9BCFE13AA8100AE1C8E971C81B3
+:106430000FBA2E1861E745138693DAF5595B484485
+:10644000D33278922344027B1F6E2711DA93F8C36C
+:106450000F239EE4DAC994CCF014063873E214F1E9
+:10646000546FFBD4C12300679FDC71FA6FE87EFA9A
+:106470008E39238666E24742F97149065FEE309510
+:106480003B93BD167CE9E3FA623B895748A80FE2CB
+:10649000C81FAEC2C361B31CCB0AD5CFB0FFCA16AA
+:1064A000ECAF84474E5E0BFA393F5C8DF22AAB6845
+:1064B00047767B88C5CE13D285F8EF4F24C92F5C71
+:1064C00020AF6C7E8F166365A7537B05F459258337
+:1064D000BBBF6A7D08EC95C73382F4F70F3E84F6A4
+:1064E00093CE19F986C6E06E5902F6D681F6EF1FF3
+:1064F00068F91EFA47495CC715F665EC2281F91563
+:106500009C3F0D8F47BF9A503CB787150DF8F84652
+:1065100027E900F96A0FCF6F023A08FD799D54C44C
+:10652000E4C9D9ACEDA4EBBF99EC8D38B5EC7AADEC
+:106530005DA63C5003567CCF18C82F49BA26278445
+:106540003D2C9FEA2FAD93B8BFB492AC04FBF82664
+:10655000A90AED9C61FE7F4D1C5351BF727FC9DEBD
+:106560002EF6712321AFB8F3609F86F2298AA79B8C
+:10657000240FD259EC4FCEEB2F447DC9F9E4C6432A
+:106580003F54CD7C71A34CDDA99AA9F0A7ED8D18DD
+:1065900047DD3058E7C6090A97D9EE4F19C7EC7C9A
+:1065A0007A5E99D8F5D3E724DAEE6DFABC3187EE3E
+:1065B000FFC607D7317D4EE107FECD0AB758DF068B
+:1065C000FFD9D6FF43536F1FA8CA132EAD340674EC
+:1065D0008F2E68027F5BD86F81E7756B7A0BA7F30C
+:1065E0007FD3FC22134D053C3B039114F2C76D751C
+:1065F0002007FF4BF24E6B27CFC60F77023FF82DD7
+:10660000FC7059CB87C00FDFE2FC20FC0BB17F3B55
+:106610001EDB9B5CA8B7B3F2011F7FEE74E0E3A61C
+:10662000D2FF9FA6A53F9F5FF08158E77DC34BF245
+:10663000D19F98037FD5C03F4849641E7643FFA988
+:1066400098C333B7625202FED0626A2398EBF2D647
+:10665000C81350DE9BFB40D17D1AF46852CFD07531
+:10666000257D96F4DEE219FC73BACD33023E67064F
+:106670000ED13E67ABFCF284496ED42DB46EDA4F76
+:106680004EBDB5DD474CED6599F9F2B8BE225A24EE
+:1066900062F63FF6BA265A4984FA05D21FF57CDA2B
+:1066A000BED73B7192A8D4CFB8ED2D3D4AEB3973DC
+:1066B000C5F960D203FAF6DF258DE1A92E8AE70835
+:1066C00095AFBD4F77901CCADFB96572124CFE9131
+:1066D00009273D0B50A9D2E4A41B7D8328FA25216C
+:1066E000AEF7C53C8313E31E42F9EFF6FABC5CCB70
+:1066F000FC61D63F28CEC3CB1DC4519B99FF6DCA08
+:10670000D363E0EFC863389EE895088F989F683F91
+:106710003B368FF6F7AC9109F863732726D1BFBBE0
+:1067200080909D602F643D99427447CFCD2F93EBAD
+:1067300014F4B7E4BAFE3156327F85BA69763EF575
+:10674000389683DDA17EFABC8C1F25D6C9CE078280
+:10675000FFD879FE8BF43C0F76A740D12517AD7793
+:1067600096904817DD9726C5F31DE0CFB6747CBA26
+:1067700097D6A5CB3B174CD0F93B2906D0FED5398F
+:10678000922C0E40F9958EDB1B9B9D8479E4592554
+:106790000500C7DE3AE6AF64836377822CAB30F93D
+:1067A0009BBBE5110FE06B77558D67BA71FEB0B2F8
+:1067B000AC62169D37AACD56673887669F77BD6550
+:1067C000DEBF95E211C7F2A9F313CED70E4A7C9033
+:1067D000135FE0CB780E9ACAEFA6BA736A7D68534E
+:1067E0001FFA2BF9B3F56A89F2F9B3D43D885197B2
+:1067F00039DFAF3F0472F0D3AE4F3704289DF2DD8E
+:10680000FA76076D7FCD51DEB007EA947140294CCE
+:10681000747D4CDA09E3C1267F84905F757D61A7A2
+:10682000C1F10F7E4F5F22957CC505718763C95703
+:10683000E87E9B1DCCFFBCCCC1F85A91E3E8AFB811
+:10684000C3B49F596E65E6C7FA2BE938B37E0C9343
+:1068500014F0974C185F533FB405F053D44A8EB8E8
+:1068600034E02FFB79AC2AF4B2890E6D0EEB796C13
+:1068700000CE61263AF83CCFCC35FB3D7D89937341
+:1068800019FC1373017EEA37EAE0CF1B7584005FC1
+:10689000ED4BFC1ADB73EA3AF07C9523B37DA7F548
+:1068A00089839D2F44299396500AE8A2DE8FFA33FC
+:1068B00087EF43DE1122B7E6417DCFEB204F39AAA7
+:1068C000FC9659AFD9EDDE2D0EABDD0B75FE16E152
+:1068D00016F1A310C73F3935CCD611E711E7AB113C
+:1068E00038970AFB37E0E071143E2E87D075291DDA
+:1068F000C0A9E7FC83703839BF887DD9E1E9B1C10F
+:1069000073B63898587F2FF8FFC007E9B8CB18C680
+:106910005D48AD7C06D615F1167798D2C11247A115
+:10692000F430ADAFD6FFDAD23E141C40BE4EEB8140
+:106930004AAA07100749CF3A937F3F50797EF2BFAA
+:10694000479EF080DEDC1B78B91FF4A91171442E3C
+:10695000A43076439DAEE35C52516DF6773FA73489
+:106960003E6096DF40159DCF04E700E889F7B37ECF
+:10697000BE75FDDEFCACEB3FEA607AF45573BCAD4E
+:10698000BFEC0B1EA08F1D1E31EE7B52FC2D33DCA5
+:10699000EE121DF9FB9D8979678953A42C710A9029
+:1069A000EF4815936FB3DF91DE0F972F51FF0AE881
+:1069B00005BA6E90F2018C0B46AC740FC079701E54
+:1069C000C4AB529EA7408FB778303E44DA088B7B29
+:1069D0007036A776E7E7B06F596572198830BBF358
+:1069E000155062CBF17C1AEEA0BF0FE4525E0F810E
+:1069F000BE88B7C6F03C3C115E6FE28F394EA62FC1
+:106A0000D2E356517D09FDAAC201584FE8A12112D7
+:106A1000FF25ACE76FED48313D14B7ACD70FFC480C
+:106A2000EBDE4A06BF80FB0DAE07EDF00BB8656EDE
+:106A300037F337B4A15D48EFB7D5EA0F8AFE22AE2F
+:106A4000F37167EC2B0E53FC62AA3D9CF0AC33FB58
+:106A50003DE76907ED65402231D037DD811AF55AEF
+:106A600093DCBB39FE962ABADBB97C2ABF9DAF9D69
+:106A7000CCB66E6FBE75DDC2CCBA85D3AD6B8FB3AD
+:106A8000EEAD3C13FB0CD02D9663F8E1DC14637A79
+:106A9000585653884F999FB7859E17E7F61C3E6757
+:106AA0004F1D3B7F5347CA403F83F215FA198312AB
+:106AB000D3C3946FE1FC1D202C1E5CC0CFDF2F726E
+:106AC0007E2725A6B87039ACC7CEDF4623E8425AE8
+:106AD000BE184C764BD9EF41C4FDC7DB8E64549A87
+:106AE00097B957F1B9060DF00FA9FFA5C3DCEF6305
+:106AF000BEFE99E63BDB78FB7AE21E66A0221943D4
+:106B00003996E97CF887E1351DD7E0F81567648F81
+:106B1000C7F094817E3BE12410AF710E56A760DE72
+:106B2000747CA384AD43EDC5FD0322AEB122737F17
+:106B3000E3ADB4C6E15D25D6383C693524733C5FCE
+:106B4000C43FE4007582AA18FDC01F861B268893E7
+:106B5000C056DEC37390F5DE480E90943707EC4ABA
+:106B60000D31DB3F99B0FB838C5DB58ECBC6DF5317
+:106B7000D66BB1C279CEE302B276C6C45FD9C7592B
+:106B8000CF5F7F03085C9E9DCEEB72A93EBA28437F
+:106B90006FEAAFEE72164CA5FB0957C745400C379C
+:106BA000F8F558B2731AFAAF141F37CB817ED0C3F1
+:106BB000DEC028041D8957B39EE36E86BFA01D2743
+:106BC000A8BFFC95D676BB5F7BB753DC0FD163CDF6
+:106BD0008A8C9F95E309A4507FD6C9AFA6FB9BF092
+:106BE000714B98F2DFACECF871108F16A0EB7AB80D
+:106BF000FC4ABC2EE0F8C3A01405BFF316EA927459
+:106C0000D698E755705EBBDE99AA978DCA615ADFA8
+:106C10005B51188173DA40EE29F212397FFDBC878F
+:106C20009E4F41AFEE0BFCE118F805193F85D5A743
+:106C3000F113BEEB349DB3FFBB7A3ABD7EBE75FD4A
+:106C4000DEFCACEBFF08F4743F8FDB4FD1D76A401A
+:106C500036C7D55FE0F42D25A99D849DEF621E7394
+:106C60003CA275F208C41F4AE73F53F49406FE7035
+:106C70000FC61FA8BB59FBDEB273E77F8F83DDAF62
+:106C800091088F8364E2FA6C3D7ECFF27B6E6F28B1
+:106C90003C0F5D4BFF7A70E504C643E831C9E1A2C1
+:106CA000F095B5685D180F99BFE209F00FDE6F3CF3
+:106CB00024CD2FF5C29F9DB4F8B3FBEA3F1C3B4E99
+:106CC000E4B43D25F234F674DF79FAB1D9D6B5DBF8
+:106CD000F15066DDD074EBDAE569FF861CD413FE53
+:106CE0005352D24DF17ED786EFA39DF09EF26A10EB
+:106CF00077311A59FCC0984B227067DA5911D38149
+:106D00001E9A142F95293F35BCF85818E207BB2F5F
+:106D1000ECB88098CF0FB5D638C2EDB638C2EDB515
+:106D20001F4E1CE1F60F2E8EB04A3E87388233F894
+:106D300065B45BDEF38C23E4CFD2ABA508D41E6D23
+:106D4000FC715D267ED0DCD3DF182882F801C17883
+:106D500041ACE7709701F18262FD21E87F42FE4E6F
+:106D600023C4D9F2E7B1F6C5BDB41DFC2D0F3D67B4
+:106D700053BD7C331007EE57E2CA4BE08FB94B0C82
+:106D8000E67F85C984648A03B85BE32990AF1F2B33
+:106D9000F1CB818E2175F088A4C17D0BBBA75DE38B
+:106DA0000CA03DFA4309C1F85B367C427E04DCCB83
+:106DB000DEC3E3027B122AD6BF9A0863E9AE64F70A
+:106DC000E8FD091DDB7B496C33E0D55DC2EE1D8714
+:106DD00078DCA15B21ED501EE7F7E33FE57C9C29C1
+:106DE000593CE0E80BDF79F63A802BE08B008AB261
+:106DF000C1D597A88CC07AFB12112CFB25EA05D1CE
+:106E0000A345A7FC912ECF2AAA879CA922A8F7C93F
+:106E10001FED6A5A95D15B4E6D694436E9BB2FC9A7
+:106E20004C6F2A5BFB308F45D1597B31C4BDA7E144
+:106E30003323D37F0CFBABACFF41AEA7EDFD77F165
+:106E4000FDDD73E4AB44A3FE92B79EC563429D2B68
+:106E500022F22CF8FD31A2517DB5C7359292E8BEE1
+:106E6000F79592C830DDB7BBB38AB7DF46CAE9B839
+:106E70007D7C5D8FCEE8A776D662FB1EEF243FA710
+:106E8000119E2FC0EE55A99D6F05FABAD4F9E550B1
+:106E9000BF878F0FC2ED3DF52BE8E9D71E97BC07E2
+:106EA000E826D71AB82F1197C4B9C05EE512D4AF3F
+:106EB0003D37453D6B71440AEF9F4BB60474702615
+:106EC0004ADA0B1BB1DCBA08EF594A6A039BB0BE21
+:106ED000A5703394DF93CB70FD922D959FC1F62D55
+:106EE0001FB91E7E2F9E6B8BD3D6451D00979FEB3F
+:106EF000B4DBABCA4364063D82164CE83F94431FA3
+:106F0000F844A67A9EAD3EC7D6BFDCD6BEC8D65ED4
+:106F100063A977723C935A85D91B758EE5BE924C56
+:106F2000CE61F0F3BC9C23DBFA3C2F0558698EBB85
+:106F3000F59F655F633293F312D5B43FF88FC7971F
+:106F4000A99723DEC2781F4FF583EE30E9875AAA4E
+:106F50001F965AF483613E9F9BF4C37340F7F7ABCF
+:106F60001F06132C6FA39FE76DD8DB7B49FC0CE851
+:106F70001FB7CECEE919BD1069077D1870F535CA67
+:106F8000AB502F60BC944A6C17E42B791CACFEAA62
+:106F9000FCD78DA01F8FBEB060F64455C61F1AA443
+:106FA0007253BE849565B4543A97452A4C72ED0FDE
+:106FB0008F18703FAF84D51A8C99F1DF152A77D0DE
+:106FC0004FC463CF4ABF86038C7EB404FAA9FC3E4B
+:106FD000EC36A0DF0C76680FC50B5990A907759F9A
+:106FE000AED1FDE73AD8FD77B0A9B051CB31B503AA
+:106FF000DD20CE137164F811FF4BE91BB4D099E882
+:10700000E5D9E94CF114023C15A61E437D63874B7C
+:10701000E95C88FA4AA6F882D21F9ED4F52A93FE2C
+:10702000C857EF83F36261ABBEEA979017923F17A0
+:10703000FDD2792E9E173261D51B625EAA3FE6B95A
+:10704000001E7550672E218BB314A66E43383CDAB0
+:107050001889D332A88E19A0E7E430D1E0A82F8395
+:107060001E5C96D98F027A0FE0F318B84FCAB77139
+:1070700032BD5DAB764D63D7ECF646C077BD8BE98C
+:107080006151421C7C6206F9137170814F5F654447
+:107090009ACE2FE9E3F6E74E6ED7F626EA58FD8939
+:1070A000AF9232BADFB52E16DFF7960C12E06BAF57
+:1070B0001C2903BB64F4FC7D6313B5F3777AD938DC
+:1070C000D15FCC7B19C7B7B784D1C7BEEE0617D343
+:1070D000E7B3B85DB3B7B7F176B999DF4B35F37B5A
+:1070E000A912C62F721DB37764724A9CB0CD05F900
+:1070F0000FA423757F59C60E88FDDDF9C4B3286F30
+:10710000C1920ECCA3D9C2F199D9076FAF1D239BB1
+:1071100078BF060A5F3BE76FC1CF6E6EBFCE95AFFB
+:107120006F76A96C3F1E03F59CE08FBF77EA1D2E9A
+:107130009CD7C0F6BED85616B7F2F0BC544F8EE1BD
+:1071400087C3EE8929FBFC2BE01FBA4F229501FF74
+:1071500088FC2F23CB3D5BAC01EFD9F249A48BA077
+:107160007FBC13D675C7B2DCB3A5E3EBCC3F1E00E2
+:10717000FFB82CE31F9F6F9CFD5CFDE3F38D9FCF59
+:10718000E01FDFEB3A07FFB867D381944EDE877FBD
+:107190007C91FEBA03FC63E34FCC3F5EA03F04F555
+:1071A000C0975F6D8CC27DDA326E0F8CF71A416E1C
+:1071B000F2571234DDDFEA25DDE00F57BBF56F0330
+:1071C000FDD2F8D6D2F1024B1CB75F3BDF3841123B
+:1071D000F1311018EE2FB7C409587D9A737ACA3569
+:1071E000439CA0FFBCE3047CFD7CEBFABDF959D7BE
+:1071F0001F63FC4F06414F2A9CBF7B72AF437ACE80
+:10720000709FE1534C702B61769F21B7C408A6177D
+:10721000DAE4C50EB76B368BBFF7E45EAEE2389B9F
+:10722000BC4D7239B6C7E13FA8F9A789EF7F9BE152
+:1072300081D99D6FC322CB3FFCFD7C07F870B969F3
+:10724000BDF3BC9FA07A08C7DBF34F3FE87B3A7BD6
+:10725000992DAE51AC30BBB154D18B813FFEBBF701
+:1072600073D9D6B5C7351629E9B8C622E51CE21A86
+:1072700081B2480CFDF02207DE3B3BBDF163900F6D
+:10728000B92B7C9D669465F2EFC4FCD72AF370FE9F
+:107290009EB0E280B86ACFB135B3C17FEB7375445D
+:1072A000619EEE5C873A5C3615DE98C2ECB7B3D3CC
+:1072B000BFECFE19E2644E85D9E11EF50984CB5F6F
+:1072C0009D9F0BF9B4DD47FEEA9813FCAA70619903
+:1072D00097D66F52B81F4585FC17A678EB2E7070B5
+:1072E00000FE00491A12AC9783EB9D0DBE7A4E2F1B
+:1072F00067A777D9FD33C4693F68F8041E3FAE68BD
+:107300007CFD00AE2FF0EA043900FB5025A7209F3A
+:10731000D735E1463FC41961F9D3697D50E5C03CDA
+:10732000192A075B81EEE415AB9CBAD5580ACA95B9
+:107330000ABB37747A3BF0BE57E4EF05E232DA2538
+:107340007F9CD927B15F61C7FD2E964FA10464CC05
+:10735000EFF5F0FCBC802B3206FC1268985F0EFC47
+:1073600032CAF1D8A7B37DF5C13EE09C01F7A05524
+:10737000997508A9B8ABAD16E204E5350374EB7F47
+:10738000C7C7292480FB53381E9489EDA952D0DB4E
+:107390000ACF032827E5C0B7B734DCF22F008212EA
+:1073A00036DCD3E5034CB507C40BFB753638BC158A
+:1073B00070BF53CDEC01D16ACF922FB493E18BD340
+:1073C00041E05FAE62F9D52EC82FA57877EA941E0A
+:1073D0004B337448FBEFA7ECF1014667A2E5A35CD1
+:1073E00039032CEF5621F26D6D65E6FD33BE15FBBA
+:1073F000FF86C2F353FF3FEDFF4E85E9657274E1EE
+:107400005D6D9067AC3B225E185F62E56F7F40C6A2
+:10741000F757828FDCA73691B9B4DFF7FE5CE0A79F
+:10742000A70788EFC150F69FED96FB328DE7878B5B
+:10743000737BCE0E82F1DE0BEA65A4AF56DFB5DDBD
+:107440000176881EE0A07DCE0E19633BB41DF72D9A
+:10745000C65F602896BC67758BB53E87E7E39412DC
+:10746000D3EF749D393CFF7C0E31BDFF027F8CE76A
+:10747000BD08B9B3EFD39E37F35BC59ACF7CAE7925
+:10748000333713FD75D41F9C3FBB17B1772B53F1D6
+:10749000CAF442A1D681F97EB3E93907E304F52C99
+:1074A0008F3F8FC4316E40EAD83DAA6C839BB89958
+:1074B0009D729337F01D8042260CD447367A083AE5
+:1074C000ECAA243CBF510F14D1F65C2E4FF81E10CD
+:1074D000DE0F14517D4AF1940BF887734A13C7AB42
+:1074E0004424E0CB9C7AEB7B3A85BFB7CBE3F10B2E
+:1074F0009F8D0E0AD001DFFD597F9FE7962C794DB5
+:10750000D9F069A747A99BEBAF20095ADEE3A9F997
+:10751000D3BE2B4ABFC313E7A8F37DFF27D60BD0FA
+:10752000F5E6BD8FF56C74B884D3A1BF42D0813429
+:10753000031D667139EA079984FB104E87595C0E6A
+:107540004833C3BB87FE0FE830BBD54A07EF39E2AB
+:10755000DDC9FD90B794D8256E94634DC2F7455BA5
+:10756000FC187772A7F9E5F1230A9C132B08C6BD16
+:107570001F82472DB4FFEECF1EC310E79CB95D9864
+:107580005F4BA046C7293C5E35105E3F631CEAF6A0
+:1075900004C1778D43FC9D63B67E61251E873872DA
+:1075A000B076C2007F60D60EAD06547E38CEF8B4F9
+:1075B000A45E1B86BDF4093E020E35DDBB23871792
+:1075C000225FE29F921A36AEAF9424BBE890BC1DB6
+:1075D000CCEEF795B1F84C68879C72D17A5ED525D0
+:1075E000BFC1770E720781735B5EB315CFA18E1F8B
+:1075F000B44A78596DC22BE4F7954C5E8374AAB7F0
+:10760000BE5FCCB6BF732DFB28BE5E36E55FF54787
+:10761000D83EDE2C219857EC8E5315077632AE16E5
+:1076200002BDDDF14800CB898628FB3D3600E53000
+:10763000D00FE2183C0FB8A8C4617BD7383DFE20BC
+:10764000340F21E910C78B802364E32B3B3EECF51C
+:107650000F1A0F70AE06BE283DE124E0F7641B57F9
+:10766000FA8E4C52D4FE0F785229E83F5042D01F78
+:1076700077D7B3F7AC0139F955B8DF7187D56A838D
+:1076800064C67DDBCDFC4E85BFBF25B2266D089A52
+:10769000DBD9FBC7B714FD5BEE029097073D10974F
+:1076A000DBED4A617C6577358590AE136857D878F5
+:1076B000C8FF35E98B4FB85D96BCF9B4BE08930995
+:1076C00087E9DC2CF4FD8F95F8F7601D9147AB84BA
+:1076D000D9BD8D881B8A78B47DFF221E7E38412259
+:1076E000E007F42546B0FEE40B5F4478EB741FDE40
+:1076F00097D4E9AA067C52A76B15AC1EA960F56861
+:1077000014F8BDAE89DDEF912D5E8C47E77279DF0D
+:10771000D5B41EEF0DF6F2787B3FDCC7D1F251B83D
+:107720008FA3E537131A965F4B5462793011C1F578
+:10773000EF4ED4617D08EEE968FD8E4414EB8712AC
+:10774000312C1F48B462797F228EE570A21DFB2583
+:10775000131D581F4D7462FDE18481F591443F96DD
+:10776000DF4A0C62F9606288DF0F26B11C481CC238
+:10777000FE022FAB26283ECC725DE7B0F8155ECD39
+:107780009A7FB4F2A4F51DF0E243732CFD2FE82C90
+:10779000B7B497762CB2B417B7D758EA45F18F58DB
+:1077A000FACF8A365AEA0B931FB3F45F30B4DE5235
+:1077B000BF70F04A4BFF79FDD75ADACB8C1B2CED0A
+:1077C000CBC76EB1D4971DFB92A5BF88370ED638B4
+:1077D000B713CABBFE7E578FA7949A393F29032758
+:1077E00061A838AF07E2C3B970EB7B11F8ADA40212
+:1077F0009483AB89F935AE1203E3B9B47D11FC4E25
+:10780000DBABA01F6DC7B8296D7F9DB7CFE7ED98A3
+:10781000A724C378F0F74BD83D9F0AC606E2FC398F
+:107820004C4F3B4FB173423A1EF1EE94B8A9E6813A
+:107830003887CEE2C7E27CA6FAE31DB169E4A1CEA7
+:10784000C3ED854796CDF9B6E97B348DDD2B928863
+:107850008CE70D6EA3D3E33D2524E55D0A7698E71A
+:10786000615340DEA37DAA53AC2EF079D1616B7DCC
+:10787000C988B51E8C58EBFE4A6B5DCD1247BF8A96
+:10788000C3DF9748AE847C7788CBE8CC3F44B815FB
+:107890004A1F15FD6AF6FEC7C3F7A750F986FB1EFF
+:1078A00052CBDE1F0BBF4FD1B5F9D0DFD3C4F2E20C
+:1078B000142AF7D84FE49B9F5A7B4CC2FD323FDB22
+:1078C0001DA6EB9AF8C65367CD8357C249A493DB34
+:1078D000B61FBB5F75B9E7FDE5A367F3BBA6E8D1AB
+:1078E00077DFC3BC32B7CA37FA2E6D87F739F07726
+:1078F000C86B2C9563F03E3B524BF4FB685922A7B2
+:10790000A4ED267C6FF530FDAFC1E16C392CB9BF19
+:1079100001F94F8E17C1BBF903FCFEE1ED17EE6ACA
+:1079200070835F7D9D86EF45C5F8031EE6978F85C2
+:107930001DC857C1183BFF284527F4065ACFAB8511
+:10794000BB7FA08786F92E105A05D89E98EB23732B
+:1079500068E573CFBAB1FFD1B9EC3DF42DB98AE532
+:10796000DE33FFDDCF4580BF5D17DC1A063DFEEB41
+:1079700004A9D97221BC9FF360F96A42C5F27789E4
+:1079800030966F955E87F932EE444718C6B9F5C553
+:1079900096FB49CA2E4ECA43E9FAAE230B25C8030B
+:1079A0000846C7748877BB8F7AF15D45505586BD10
+:1079B00026387A5CF1A24D00FCA7143C9FECF70E30
+:1079C00036401CC3F80CA9FE069D7597AFA33297ED
+:1079D000AEB7AB9C7C7ADD34FCBC9DE389729253DC
+:1079E00031F96B91E860430EF8C25B4884824F5CCA
+:1079F000BD540D407DB93A02F39678E83AE0076E3F
+:107A000051B56E0DFA533B5D95A197CB4B620F05B7
+:107A1000A01FA36BA997DDD714C50625A063F72384
+:107A2000EC1EEDC917AE50E19EE40FF91568C75E74
+:107A30007BD4AD43BCE5B53CF65EFCB54757FE00D4
+:107A4000F4D46F13C7F2CCF7C9AF7DEB672B5C940E
+:107A500060AF3DFCB315323255D2F26E65DB7BE38D
+:107A60002BC07F351A4965072D6F5615CC63BF199A
+:107A70006482ED0BE5F540A1D207F317CE76EC85D5
+:107A8000B2D9C7F212441E27E17AA9F0FFB8308FAD
+:107A9000A2FB873E9CA7531E398AF868A2E7425A88
+:107AA000DC72A1D61DA0F55BCAD4089500D29D6BEF
+:107AB000B8E7021D5E70B3F64B8913DB8B547C4F25
+:107AC0009DEB19C7F728EE270753C0D6FB25DD1914
+:107AD000043A2E64F389B8C1DB65A4B28CEA7179EB
+:107AE000F54814E09E0C3AC8B004F7348C1EBBE98C
+:107AF000B914D60BBD4276E668908FDCB1BF0DFDA0
+:107B000041F65D972B7CE52CEEC5EF6B76BEF0C59C
+:107B10000533F92BA2FC3EF7579E4878B03C9C50A9
+:107B2000231554FE538930D6EF4C6858BF3B51891A
+:107B3000F5DD890896F561164FA2FC2C81FCD7ABC8
+:107B40004CFF5D9CCFE20EC59A43572E8276967706
+:107B50005AC0F5C1C561F6BD9BFDFCBEB6F8D4BFE9
+:107B6000B482DEAB7F83FA9D263D562013CFAC3C1A
+:107B7000CC633442983F4ADB2B39DCCE8CDE117A61
+:107B8000A660AB75FC7ED7089EAB8C4B199EEDF3BF
+:107B900007F9FC79D46D754E337F306AED3FA83913
+:107BA0000CD745E7EF4FDF63F3A70F6CA358A27C18
+:107BB0007580E733DCB36D45E85A137DE07B182F01
+:107BC0009BF8FFE0F615A14DB4FDC076A2A921D324
+:107BD0003C7CFCC1C4B1C2A60B33FC5BDAC1EEF144
+:107BE00045BF12837C3A66D2F7831D727418E31680
+:107BF00054BF52BEE9055D8F8F5A234D7A09CE8B53
+:107C0000F512EFBA26C8BF28DAC1E4B8D1B3FF082D
+:107C1000988420D5137E4AE7A2DA41490F64F43DE7
+:107C2000FAD1146FFF5BCF6B5201EFB56404C05201
+:107C30006A756D27C44DC7E645E0DEFFA30D3547E5
+:107C4000F0BB44CB457BA4FBDB1087195DA041EA68
+:107C5000C7FD9EF8122F95EFEF4B0E84BB283C28F2
+:107C600035D2F2EE27FEA4809EECF993E201B92C06
+:107C70007AFC2505EEC77BA40905F3EBBC0F344164
+:107C80003E09D5930BE19EBDD95BDD0BF50339F1C0
+:107C9000BF27689B1E687A92EADD42F7C43DD0FF99
+:107CA000122F31A2F5741DD7C45560A49BC8708FE4
+:107CB000672EB617433E9E4EE7EBA7F8F83EC8186E
+:107CC000E6A7DCD7A343FF5C566FF6267B0C5A5F12
+:107CD000CBF51D09C4CB400ED37595D683A6BACC7F
+:107CE000EAC4C34AB19F6D47FFF483628A8F9B1E2B
+:107CF000974620F5A4E871AA2100EF87F763DEC15B
+:107D0000E1C431B547D057E0998AFA2AC8EB01BCE3
+:107D100026A564B98447177C9F2EE70D1D81FBA320
+:107D2000F6CF100DC464D4C7FC985513741E133FCE
+:107D3000AF92D97B68FB7B67FC740ED0670FBB5793
+:107D40002DDA32A1C07DCDE13AC3BF94FE7EE3A619
+:107D50008A9A9D948E657CDE4E62F89BC02F5215E8
+:107D600015E44CE4D5BC2ACEB73CAF66AB97555D65
+:107D70005D8C1F7BBD238500E7E43FBAF2CCF71B87
+:107D8000BDB92385D234BF5379C6DF0DFA3BC07528
+:107D9000583572F3E83C371DDE3F170CFA4D64F09E
+:107DA0009A2F01DC3F761280E337475685FE82D654
+:107DB000B7D13A98AAAFCB6397009EBF3E5A36021E
+:107DC0007AB4C7CBE0BF6994F25100CE4594E6D4B3
+:107DD000493DAC0F2E9629FD8F0E5CB3C67B312139
+:107DE0008F95EBAA83D2FCF4407BAF07EA8ABA10E6
+:107DF000FCF6D30337237FDD78A983C98F71F35352
+:107E00007A05C0C1E4A7C77BB807E4A7B6D583E766
+:107E1000B942472C0AEF36C87107DA6F30C5F5143E
+:107E2000FFCEDC1E4F3985EBF7BD0E8CFFC07537DA
+:107E3000BC7FAC95C931999607A8E308DF8F30FA6B
+:107E4000641C477FEF77E5019D067578F74CFA993A
+:107E50007E5BFEB81BF3EE6A3BF4CF623C51AD474C
+:107E6000BF7A2E49FFC13CED0B08D3D32B55D2204E
+:107E7000D37E35DC0ED6B65E7E238C9BB7A9E54754
+:107E80003A6DAF93D8776EC8B32C1EDA93FBC088D7
+:107E900087D66B43B20AF1A051AFBE1842AE933FF2
+:107EA000F355039D4673232AD22D28E781DDEA99F5
+:107EB00070186E2AA78F9EDCFADB8BE19EA9C0A307
+:107EC000417EBA93F6ABA1F80E80DEC07BFEC926D8
+:107ED0001DF49912DF0E72F9D26D933D90C749F1EE
+:107EE0003ECF43F13EE19DC4F3D1E84EBD5835D5B8
+:107EF00057FE07D5D22897933DA0B7E4DC3B6E042C
+:107F000039A7ED4F7AE87E1ECB137A8DB5D7968BC5
+:107F10003AF5D7A91E70EE14724D0C0FD5FBB5A61D
+:107F2000FE4D54AE5D8DACFD7B743DA0239C833A29
+:107F3000F3609F04BFBF32B9504EC23E8166F0BEAF
+:107F4000E11267DBC797407CE342128110902F97C4
+:107F5000E9635FAE86F1C5512FCB07997C3A900457
+:107F60007CF9723B06DDD05E5A41E05ECD9F64F342
+:107F70004009F4F7F3772192BA0ECF3DDE4AEBFBCE
+:107F80007EF16E04EB905FC2CF0DB2EDF7AF95E9D5
+:107F9000474AE9F8CE8975A84F4E7A799CBD94DDA1
+:107FA0006B7C3166AC8538C7A2C991467083AADE66
+:107FB000197B02CAA5E4F546509B114FEE51287F6C
+:107FC000C1FDBD1AB57A356CED2FEA93DD187ED26E
+:107FD000268A409F2D77D23A5D27543FE28475660A
+:107FE0005F5D719EF91729CC7FD813704493783F59
+:107FF000FDB0BAC934FE319FB89F64FAC5C5FD8D86
+:108000004E32D8A0A0FEE1EF9FB8BE71F18397CCAD
+:10801000BFA726AB11D5A0FAB621588BFEE81C1FCE
+:10802000F3879D47565D06E70405F404ED7FD0CB4A
+:10803000EE01268BC8C8B006F7A33AC13C399E9F13
+:10804000BA83AF2BF4455FC243F405843CF2C9F90F
+:108050008D1897A464C6F70CA971E93D7AEEBA238E
+:10806000F39D0405FCDE473E59D8A8523A7D27EA25
+:10807000806337D54BFACF8B41BEC75CA8B7EECC37
+:10808000B5DAEB437CDF6F7819BCD45E7F1ACE156E
+:10809000BBE8FA49BABEF28E9F24A97FD9CFF5B1C9
+:1080A0003BBE05F9CC1DA660225F18E2BC4D1E291F
+:1080B0008373B58324CDF70AEFE4E0F837BC6C1D79
+:1080C000714F9F2D7FE4BB3E0777E6ECDF678B2285
+:1080D0005D76A4E9C2EE291E6BD47F4E504FB81CCA
+:1080E000D3DD632FE5F329EF480887F8BDC6C7F84D
+:1080F0004DBC8B57DE91B15DEC57F4CBB4B37DFC36
+:108100004E65EFB094309357E5B013FD4D129627AE
+:10811000CDEF9CFC708E98979133F1FE6AEA3E2277
+:108120006378EEAF607A76AA1C1AE8F7EC08EAB337
+:10813000C11EB9356BBB3DFF290DF73BB32CFB10BE
+:10814000F295D94F21B6833D017D70934CBE0AF163
+:10815000C16D3C2F659B93F213857FE08D640CD637
+:10816000FF9D38F73CCEBE7FB26D743FCF8FD12CD0
+:10817000F1CF9B0E6FC7FC137FE73FAC8477586F3E
+:10818000A8ED45E04FF865A6AF48AB07EDFE7EAF22
+:1081900038D72C60F761F4FFF0FB3B84F50B546992
+:1081A000C3E0679EE0E7CA66101EBA4E4F500F4B01
+:1081B0002C16A0CB94063D0542AF3ED0037274400E
+:1081C000C9E85D089A1CF0B17A97EF819E1EF00B0A
+:1081D0007259FF666F7DAF51027E82A8AFEC057FBA
+:1081E000EB8012390AE751E351B70670D2F13AFA3F
+:1081F000055756B23CF5323207F0F064AE827E4C41
+:10820000CF23EE6138DF53BF72ADD7746E7C2DF78C
+:1082100099B9A46ADAF90CCB7CA5E7371F5D7FD446
+:108220007151A6FDC9DC15479D6C9C06E35ECB55DC
+:1082300030DFFFB54F79F05EE1A0CB2AEFA2BCDBC7
+:1082400027E24F2ACA799A6F40BE217F8274307A22
+:108250009530B97687F32C729DE1B3629234E5478D
+:10826000CCE1F63EC36773B1FD0D4EBFBE84768E82
+:10827000EB9567596FF159D65B6A590F3473FA3D24
+:10828000E60CF717F6F75F763D294AA127737C6C59
+:10829000FE8BA5F8777CB47EC3C4C825980E2AA9A6
+:1082A000053B69972BB95FBEEAC19DDDC09E9F5318
+:1082B00062BFF316B0BC28908FA54AEC029FA97E3E
+:1082C000F32B01C341F9E026F06B287D077ECDDE5C
+:1082D000ED0AF9F27A62A9622D235FD3E843863F63
+:1082E0001E8F00BD0FF5AF8FB91C3BA7D18B197C3A
+:1082F0005AF55D8F57B3E193E9BD0F6E3DA7857EBB
+:1083000053D753B03D63D7E2844C631F7714E99889
+:108310000F6492771DE41D9E83703FCC00FD706753
+:10832000BA7D676F5309F8D7997682E7B5CC78F8AC
+:108330006EC29D3E51DFD30B7EDA94FE7E5BFF72F0
+:1083400051BF0BFBDBE139E0CBD4C10F94FFC39DE0
+:10835000F61301BEFD0EDB7C79A23E8CF309FFBF54
+:10836000C3FB8F4F1932F0E56003D8F3497AFE82E0
+:10837000F73C5F9723BE88C98FE9E0FCA9BCE3B551
+:10838000E03983DF00FE4EC2567AEE7861EDEC995B
+:10839000EE7B7FC5FD0151BF3EBEE312E8DFC1EDBC
+:1083A0004A3B3D41C0FCED079D16B9FD1F78FF5CBF
+:1083B000E05D98C5AFA962F2FD67076F5116784B73
+:1083C000FE9FC2BB46ED38E2A2F0AED1247CC7BA14
+:1083D00086B679A98CAE851C0E5AAEA10E7000FD32
+:1083E00096247BFF41EB10F758FB9F7F3CF151AA8D
+:1083F000BF0FF1F7220BEEDD71FC523ACF7874D942
+:1084000032BC2F90F5251BE87961D4CFEE9F177011
+:10841000BFD80EF7A89FE1E37874F536CC1788F93A
+:1084200031F7E38423F2935AF09FD63BD16FB48F98
+:108430003B9E60F91977F87371FC899893E51B44AA
+:108440002F4C3AA5EC782251A7EDBBCD3E6B3E40B8
+:1084500085E630E7C11C27DAEDB5E0CF344F0FC712
+:10846000AB09F63DEC13B10D33DE0BFD2BEFF76BD3
+:10847000C827A1E50D234E8CFF6E8D3931DE6B5F71
+:10848000D73E7EAB2B5538533EFCB611A7E59EF484
+:108490006CF0ECF4B378F78D87ACE33E9BF4DBF241
+:1084A0002D18DDF3797C8C626211FBCEAFE682730E
+:1084B000EBFA53ECBBCA3F879F56E13BD6C7FD742E
+:1084C000DEF5D16AF6FD5CF15D6799E0BDCC96BD45
+:1084D0000BD1EF256D1BB0FF937EC9E25FA7E9C406
+:1084E000EFC70EF1EFE1CE6E335CE6EFCFFA03FC9F
+:1084F0003C4BE2A500CFA8A22FFE473AFFF14FBAAE
+:10850000D93BD00DCDBB83947F4E6CCC95CCEF6125
+:108510004FF3F556B4B17B98D1933197C3249FEFB5
+:10852000727EA4E3AF9E98067FCFF3F68D7189E744
+:108530005BE8A5E6EF53BB026C7ED13E855FE0F0C1
+:1085400051007ED4F4EF5E7FC5E76F6D99793C6989
+:108550009BC5838DFA7CF37766EDF8EBF4C727FDB6
+:1085600074BE67A4F8BD9F073E6EF0201F13595BD1
+:108570000A700B3C50B9EF874F750B3A5D565C851E
+:108580007412F088F520640671965A9DC5DFF27862
+:108590007EF3CA3DDEE44E3CFFF1EF8ACB14AE2001
+:1085A000AE4F0205D9D717F3E6CB24A5D079B7385B
+:1085B000921DE017DAF721FA8DFF69F5C701BED1E8
+:1085C000E30EB5AB6CEAFED37CC3F5D2FC212BDF06
+:1085D000689C6FF2F93B65EA7F95B69ABFD314F0B9
+:1085E000E2F8F3E5A79F82DF44CBF95F8EBB34BA94
+:1085F000EEE5328B9BC0FCE6EF401DE3FD670558BE
+:10860000FF7CA7E15B047EE6CF997E39347C43E9A9
+:1086100074727B9CEB8D1FFA2B2DF2B2215AFD5404
+:108620007E2DF0DBFE08C443468F7F04C76FE4EB6A
+:108630008F2AC60D409FE357BA73217E70AEFB00B0
+:10864000B900FB51C5F9F03E476C4D01D0EF6172A6
+:1086500031C0F9129777317E3BE7FB434ABCDB0B15
+:10866000F703810BFAFA3D28BFE8EF5D1798D707AB
+:108670007140D2C3E838BFE5F51D909F37AAB038E6
+:10868000FCD3B705318F82F2A1C5DEE4B7BC9D8073
+:10869000B8EA6687761DFB080FD33BBD24FEB1C048
+:1086A000F28CFE99A26F7A3688EF4FCE9FEEFBF1E7
+:1086B000E2BBC8824F0E25D787369BF0DE15502CC3
+:1086C000F7A4CF70FD3D6ECB076C39C9F2AEE83E22
+:1086D000306EF4DCC5A5F7C13EF2DBDF4E40BE4292
+:1086E0005780C567DE4C963F0AFB15FB17FBA4FBC2
+:1086F0009AFF4DDAFF8A56AB1E1672B4B1D96FFDE0
+:108700009D8FAF74EA37E2F9E4E3ECDC2DE6CB8F22
+:10871000527C2D857DC5BA8265193C0B7C5EEBA62B
+:10872000789C47D8C3500A6FE5BE22FCFE4441F74F
+:10873000C4E7E13CF8462016CA33E9A5BF0958F55D
+:10874000B3B0BBD00FECD17A59734D679736449DC7
+:10875000D3C2BD3927DE41A639A7A6E5DC66075599
+:10876000C7A00BFAB7920E2C3F4DF48BA13CC5E984
+:1087700021C69F22A9E04AF017A24E8CB79CEAD8E6
+:1087800080F7826DAE91600D2DEF0A303DF6FC0E44
+:1087900027C6477FCDF7615FEFEAAD4EE30ACA6FA8
+:1087A0006D496697DBB6B2F8D7D51DD6FD8C53F66A
+:1087B000A8CB033C771CBF14D6FD5B27FF3E36F3E6
+:1087C000174E27F3AA21DF6F1C700F72B3DE2FDE66
+:1087D00035E277D2E3ECAFE4D9E8E6A7207EFC608F
+:1087E000A00CE11B8F6EBE048EF6D70F91EF4F6881
+:1087F000E017CD6CC7E3B73A2DF67AFE97ADDFDF11
+:108800005ED12AA17E2772AAF41A931EF285FC88F3
+:10881000EFCB5B58BB7D5E6F28C0E0F94F67FB7400
+:108820007EDB05216E0787A61F7F4128C8DA0F4E21
+:108830006FC7DA73FCFC5E6F04EDF7C6D6E9E7B9E3
+:108840002DC8ECDDA96DBFBA1AEE994E38ACEF9386
+:108850006F0D32FEBC26C8E46C7CF84B7D45408F22
+:108860009B2415DE0B5C3B4B9B0FFC72D5D66A8CB0
+:10887000DF5FC1FB77F863C7417F5C7F70531FDC0C
+:108880003BCC1E73A8E0B71EB2BD7F16E57336BBA6
+:1088900041EDD52B60AFF2E1FBCEF85DED64E45322
+:1088A000419CDA08E501DD99DE35867D2AD07DBC64
+:1088B00099FBA7C6128B7F7A86F365367A5E3F6492
+:1088C000F3C76CFC7A9A44D06F369AFD2ABEE37CDB
+:1088D000F78F3F59097EF875B322E67C53E1A78EE6
+:1088E0002BCCAF1E7F661EE64364E3ABACFE6A335F
+:1088F0002B3F687F75BC99F1F9E95B9705AF9D66E1
+:108900009C1A64F271367FF5F4AD33CBCB69BEAF00
+:10891000335C8F0B7E027FD99C475014B4EABDD6DE
+:108920002DD6752F6FB3AE2BE4E444ACDB07FE0607
+:108930002111F47F84FF4A7A969DD3BB15010FC89D
+:10894000FDB5554C5DC0397003E80E4ACF451CAEED
+:10895000E3D16541E067FB7EC61D93487FE36BEC86
+:10896000BEF3C2A14D4F146953F96F45D0CA77EFDA
+:1089700097FF845EB7CF93E6B7E6F7792EFA90F9C2
+:108980002C3B1D92E7C467420F5C258FB8565531CA
+:10899000FDF2595AFE143EE2067E5440C3F22A7E8E
+:1089A0007F4689B702DEA18E0FFB08C4AF8D8160C0
+:1089B000F24288FFAF5F3CDF0CCF0E4E97AB86D6FE
+:1089C0003D05EEFD09476C2FFA5D5F60F7F22F9CC5
+:1089D0007CB817EABFA4FA4AD280DF3663FDCD9394
+:1089E0001AFEFB08DB83B9ECFCD1B2C9659ED7CE79
+:1089F000BF1B6DFCFB3C8737ED7FC993B5A097C5C6
+:108A00003E414F16D175366EDDBF0AD6B97EE88875
+:108A10006B21FD7D337C489CC2BB25C8C6B709BF0E
+:108A2000D743F74BF9FF79E05BD8EF5F49CCFEC93C
+:108A3000132EF33BF36B3A7EB5663ABD3ECCF9FCA0
+:108A4000F620D3BB1DFE7871B020A35F67B794AD4D
+:108A500000BFA618CE1026B84B381C8A3BF200F394
+:108A600073D83ED278BC89E1F1F993EB7B0B6AB302
+:108A7000E3F1EE2CF271363C9E18F6B1EF3AFF2589
+:108A8000A36FC6BF2D4D7699FCB4628093FBB7E00F
+:108A9000270A3E787EFBAFAE8EB3F3580F3B8F4D67
+:108AA000D602BE1ECDE1F7869A66F9F7A27E116462
+:108AB000FEAE1DCEE7B85C9D4D7EAEBCE187785E14
+:108AC00078EE861F95C27DB118974D3EAEE4719C3D
+:108AD00043B7B8DB87A759F72D8EB7297A8258FD9F
+:108AE0009EEB5B36F5010ABAFC397F09FBCDEACF74
+:108AF000B5B07351C69F4B0621FFE1677C9DE7C06F
+:108B00009FAB9AC19F6BA7FEDC52933FD7EEC47711
+:108B100025767FEE6912FBC4F2DA4C9CE7D92D2C46
+:108B20001E75BA79B103F4E5D32D77A25DFA0DE78E
+:108B3000CB71AED79F6EB1DA8D099BDD98A24F4FF6
+:108B40005AF3F5B3D99FDF9CA7FDA1FE7E29E8C1AA
+:108B5000A7EF6BBB1ACFD9F7F9F0BDA49D3EC77242
+:108B60009CCCAF033E35E9A15125F2DA683EF069AD
+:108B7000117E0FDFCE9FE3CDCCAE1D5AEF6F077F86
+:108B8000EE101FFF726325BE6F82F313C07F3A475A
+:108B9000E2E75A7EBEE6F6EB2A5481193A097BE5F4
+:108BA000CA61FAE3FAA197F0DC7C0DFFEE39FEA171
+:108BB000F0A803C5988FF7BC83EB91078278BF2A92
+:108BC000D613FB0AE558E5F5B3492BBECE66C79E22
+:108BD0004DB2BC09B1EE7507CB589C8AD7DB76B095
+:108BE000BAB06B87922C5FFACDCE10EE9FF2CB928B
+:108BF0004768FD4CE7E21A737EF559ED5CD2F1A1AE
+:108C0000D839C0CF4C76AE39E7DCFCA93384449127
+:108C10001EEF6EDEBB8AEEEFC52FCDC27F87EBCC99
+:108C200010E3D78B39BD5F54269698E13BC3F77BA1
+:108C30008AD3F94C1ABFF11CF3F7186AB95E7B911D
+:108C4000CBC18B9D5639F8588E550EAE1FB2C27BE4
+:108C5000758715DE2B72D8BDE48B9DDD3ED02B27AA
+:108C600004DF5CE744FB7322B63AB83C1FCFE31144
+:108C7000339DAEC8393F79BB52A2FE3D9CBFEFF396
+:108C8000A1DF9D8E8F56323ABEE961FC5E16724CB2
+:108C90001BDF4CEBE74A2BDDC19F30E3F1BB5C0EE1
+:108CA00045FDAA76DBB93A621D3FEE60726C0CF8A6
+:108CB000D1FF531506A74ACF2106E3E715600FD36E
+:108CC000EBDBC65F29272DEB1B9C4FB2AD7F367FB8
+:108CD000EA7FCE33D39F67BE9953764EF1F70FEA02
+:108CE0003CF34FE7C9DFA3DC1FB49F6BD27683FB55
+:108CF00037C29FB936A49D19A54BFC9CEBE1EB86CE
+:108D0000D6A1FF39EE88F562BEFE71870AFC38DE17
+:108D1000BCB91BEA6F0E9559FE3DAF629BBF25ECB7
+:108D2000CFD9ECA75D7E9EDEB8AB06D67D7AE31583
+:108D300016FFF7F2778A49CA749F29E20D6979F51F
+:108D40005AE9FEFB208BFFFD9EFB93E971EFCCC53A
+:108D500079D27EF1D0268C37B4B5EC5F2599F6F345
+:108D60005D6ED71ECFD1AC7EB1CCFCE26CF1B6DF2C
+:108D7000DAECD8D39CBE22DEB6518E4D1B6FBBBC45
+:108D8000C569D34FCC4FB3EB23D1FFDF73AC7A4926
+:108D9000AC63C7E7B9AE5712647A57C4F748957603
+:108DA0004EFFAE697A5D5B7FFBBA7FCAD12C78B18A
+:108DB000AF8F8F4366885755F378D50A1EAF1AFFD9
+:108DC000E45FFC04E27427D61FAD073E3C7DEB1F39
+:108DD0009FBE221FECF853F5007E358F5F9D8654B1
+:108DE00038E0F7B8847EE115439BF05C46FB33BD69
+:108DF00074621EBEF7BE88CF4FF591C50EDAE5F35B
+:108E0000410EE79180CAEFAF464A31AFFD1CF1F544
+:108E10005C167C9DAFDD7830C0F3EADF5DB604EC14
+:108E2000C1481A9E148BC7AD66DF511F55629FC79C
+:108E3000BCDB8D417598C52FD19F5B4F183F8DCA04
+:108E4000DAEE45B47D34364F3768BDEC63EBB0FFE6
+:108E5000FA16BF0ADFC559076356517A35060C98D2
+:108E6000AF76BCF91FE0FEE197AD6E0DBEA3F364D3
+:108E70006CB313E26F279A250279BF1B3F1A7B0D53
+:108E8000F2C9365EE1D7F0FD7BB40CFDC26FC27A49
+:108E9000A6BCB713A26EBCB4AB89B62F2A1875C096
+:108EA000168EEE7B699787CEDBBB3316867CE79BFD
+:108EB000F73DBA0BF2CE0B0BF5B18F4608F9BB7D2F
+:108EC00087D7623EF4DD62FC63BB20BFF9BB8E78BE
+:108ED00019BC5B38B9EFE45AC84B97A5A66AC85BC2
+:108EE0007F2EB4A01FFA5F7EF9B6CF3C42DBFF7D38
+:108EF000DF7FAC851C9C156D62BC23BA5A26644387
+:108F0000BDA82B1EA8E7FB639AA39A90CFEC7B78B1
+:108F1000AD0CEBE5E9F85EB560F0E15D305F5D9CBE
+:108F2000F03C996074754566BECDFB1EDE65D07A57
+:108F300051E76AF20BAA67EA260C7C3FF24C43C762
+:108F40006AC8ABBF540DF5572D246465B4C10FF941
+:108F5000DE31757ED45D8DF755D51A2DD7AB0B114B
+:108F6000DE156DC62268578CAAFE28E6F2F27BB9A0
+:108F700092C87CCBBFFF5BC9E254E97A98D547BB66
+:108F8000A6CF0FFB85CAF4C6A86FFAF6AF86ACF77A
+:108F9000ABA193447F90964FF9C8A887DA89CBDCC0
+:108FA000A416E2E65D3CBE9C5ED7C3E012E3887186
+:108FB000591EE8A1661E338776B8C7B98BCBD9BCDA
+:108FC0000893E30227F3C327ABA5AF037F16382529
+:108FD0007CBF57E823F187A07D167BCFD74C880E46
+:108FE000EFECC4BC3FE6D3AE9917BB1FF875CDECD0
+:108FF000A2EAEE329C0FF745E1EDF198EEA128DCF4
+:1090000032C05DE05C5FBDBDCA047715837B348FE1
+:10901000E163F4DF589C6DF478F930F0EFBA9055C5
+:109020000E578CD5E0BD5AC16A82FFEEDAE4ED5EE0
+:10903000CC83279EB8E5DF8F3BC4F7B9D59687B3BD
+:10904000554E2920E75B791E4E41F7F47410F1C4A8
+:10905000ADEFE412C3F27E92ED27334F3EB6537864
+:10906000587E7D1678FE390D8F35CF26330FCBB362
+:10907000F9B0E149E7E98987C17C5E912F2DF2883B
+:10908000B3E9CFADB63CE9CCBA2C3FBAEC0291972C
+:109090009752D8BFD7C1E09B929FF750C36CF65D43
+:1090A0001171DFCDF94061FB073A9BF30A7EC3F1F2
+:1090B000B741F037BF67DF3C87DDB38FFEDBEAC522
+:1090C000EB703E762F392AB373D70A59C7FBEE15DA
+:1090D00063792ABC73107C29F851F0D3685E47038A
+:1090E000E26B9D34EDF7CE26855CC6D87DCCECB620
+:1090F000B8D3FC3E40C89D5D4E09B997BF438FCCA5
+:10910000BF1AF4029C0701FE089547CBBD3B837B49
+:109110006388D937CA078C7E45ECBD86C08F9D1FFA
+:10912000FE0B5192C7FB0080000000001F8B08005F
+:1091300000000000000BDD7D0D7C54D595F87DF31B
+:10914000662633C924793399C977C20CE123088490
+:109150004908212A1F9384402C4127E12B41D0E16B
+:1091600043881262546CB3BBD64C08D218598D3F59
+:109170002DA52D6B87145DD6A53520DAA888C3A749
+:10918000D82A06A48A15DDF1A380883045BB6297F2
+:10919000D6FF3DE7DE9B99F79210B0EEFFB7BB69B3
+:1091A000F57ADFBBF7BE73CFD73DE7DC73EFD45F53
+:1091B000CC20FEF1847C037F5309FD0B103281909B
+:1091C0007A7DD0A8586879311BDF17F5EC3512A8E5
+:1091D0002F249EC01842528E07134643B9D027AFA2
+:1091E000A4E5BB4A02210E426A13152C0B9F2D8B5E
+:1091F000BBBE90903FF6E81418B56812FDD775F421
+:109200001F7FFDA1D261B49FA8D327C449C84E3D9A
+:10921000FDAF74AC074DA648FBD73BEA2BD6D2F680
+:1092200045FCBB76993EB745E05D9A28E1F76E4B69
+:109230002408F78158E237D922F3B8298690E20250
+:109240005A35B94778C7D2EFD8C8AD5E4B643C31C8
+:10925000CEB58A84ED8B7849FC37D94811219530F9
+:1092600014852FC72DF9099D0F596F0E0C77D14F1B
+:10927000CA3A0A0C21E17CE9979D00822CDD5A450F
+:10928000C74B8E25BEEDB4742411ACD3FE9EED9673
+:10929000C878AF13F6579EE3DD02E395A7A4E5B7C0
+:1092A000BA587F808BC2BFD654A0825F5F6C83F7B1
+:1092B00055F9778D893C3F60A453A2ED96DA7C8BFB
+:1092C000258A93A387CA86130AD2DDA9B2F3932411
+:1092D00042E648BE0708856BA9D1FD40BC2B32CFC2
+:1092E00079C4E4B4E41272176DFC0D7D3FA727D654
+:1092F0002F53D2CDF69A9D161383ED1BFACF850E10
+:10930000A9A28B7EEF6E4294A682BEFC7177AA1151
+:10931000BF73B42227D1170D17C7FFD2D8F06A0246
+:10932000B4221D0C9F7A867F515F3A82C29D13F54D
+:10933000DE42DFC713F29B38CF6C85D273998EF86B
+:10934000E0FB641AADA445BEBF3291D127028F1F46
+:10935000E93FDEE259A04CE8DB5E5B8AF6F4FFC130
+:1093600018E4139F3C96D271C9AD84B4D35A4A17FE
+:10937000E50B0BF07550570F7494895FA2F3FF4013
+:10938000C9C24E6FCDA52FC745C67B4BF2664AB406
+:10939000BFDF11E37E5242BAE0FCCBE5BBF618EC2E
+:1093A0004067C9DD4AC7FD47C5CAE649C285304F97
+:1093B000471CE3C303666232D3F15FA525D25D4F3C
+:1093C0003CC0576F668FEA6CA7E3ED34B27602BFFC
+:1093D000E4921C9C1AF5FE805495A9D0FA01474AE4
+:1093E00041AB84E3117314FFD37109C033E36F5FA2
+:1093F0009C9D4AE96118CAC6B3D3EF5747C9C1C497
+:109400000A36EF36CEFF6D4A1C96E5716CBC032E12
+:10941000CA26F09DE1743E541E0EC6FAC634225C84
+:10942000FF8CED80EFBB683D99D32DD9C8EA2F5949
+:10943000997C7E6965E37E9F97C909AC9D963EBF86
+:10944000E3EF753034EDD75ED9E925944F66CA4E07
+:10945000AC9B4D8D840C85975E02FCD45E42E7D3B5
+:10946000CF388F2B3A46E732365FD710427A005E0C
+:10947000AAD708F26B0B7E476F7A2B1BF8F8E1E254
+:109480004E05F878AD81D474F5D3DE181732019DFE
+:10949000C968BDEE492A4FA4B84207F27C2F9799BC
+:1094A0003F775525827EDCA5B0F91A65D208E3081E
+:1094B00078D63603C3119270318E04E9F77E03F03B
+:1094C000C1F7733F417AEB8BA99AA15D0DC4EB57AD
+:1094D000A2E86DA0ED82B911B94CB89880FDEB2FD0
+:1094E0008E2781A4CBE9ED227C4F52299CC9517073
+:1094F0009E988F706AE7A7C55F90C32BEA9E5CFDBC
+:10950000341205570951D6C2774AA89047C347C8B5
+:1095100024E5E4685A50BEFB46463DCED60B5A6E53
+:10952000B6A09EAF00FD5845E74AAE65F2A450DDF7
+:10953000BD4229390A72DFBBCEF07E429E77FEE53E
+:109540000B7F3CC5D3CEA3436D6BE8E39BB91EB83C
+:109550003991F189D0EBA067AAE32370A7737A0849
+:10956000B9AF3095793E89C2DB0A85F1D52189D121
+:109570009D107716F42F9AC4F402A990C8705A4C23
+:109580009CC6E443F43B07937740C9E444C851F5D3
+:109590004275BB0BD06E029471D87EB0F5A9573FCF
+:1095A0002633FDA88F4DC8238950660708D5D39B65
+:1095B000FF5AE66C8175E70D83BB139A7733FC94F1
+:1095C000D4AE6ED5D3E7862E49892191EF5B9A24DC
+:1095D000CF32E0032E87F5760667BD3D681C464115
+:1095E0004BAF67F06676ED91F4517C9059C7DA99EC
+:1095F000AD068427BD862ED074BD4A6FF46C2194CD
+:10960000FFE3E1391D2FCE4A387E03524621F6236F
+:10961000ED14A5E96E36AEC51D9096D2711A38BD0F
+:10962000DB745563405FB525C7B9415F55DA7C49A6
+:1096300056E0DB13C1603CE0F9448FDE07F4B779F4
+:10964000EC5647647E4E5949073D107782C1D5C11B
+:10965000E91DE1FF87B87EED64722F934304F14C5E
+:1096600082205FCE05B9A82F45FB641BD757C9C41C
+:10967000B7C382EDDB08D281E03C93D78CE86C77EE
+:1096800045E81459AF4715C07A9DB33EA85F42FB29
+:10969000BDB84957114D6F5116703D46E731367AC6
+:1096A0001E83AD4BA29D21563DBF483BA6B7E2B8F5
+:1096B000BE2EA9B52F80F9D5AF7D3E2E867E32BD58
+:1096C0006BB31487FAED616C27F04EE1980278D6FF
+:1096D000F2537A5789B305E8FABAC12D9181E1AC0A
+:1096E0006F923DCBA2ECC4FAB546A4C36623A98B06
+:1096F000D6E384ACC1EFCEB732FDF60B9BF746F84C
+:109700006E43F7A346A0EBED5B3E34FAFAD137BDCA
+:10971000FDAF104F12E54FA0477D8D2900F32EA914
+:1097200065FCB972AD311043E953BF6D7B5007F64C
+:10973000DA7DC40DF25BDFB5FD603AC55346BD6707
+:10974000022C25C994D97AC644F45F7A7D5082757B
+:1097500025BD6B713DF2796A9C1BF81CEC2C58FFFF
+:10976000CE9658FC125DF7CF1AFCB94EFAFEAC2B20
+:10977000D6EDA7EF0F9A993C0B3CBFBA7DC6218965
+:10978000E2357E474C10CA7A9BEF2E987F7B8BB3D5
+:1097900004E8D45E4E14E01F678C7727F2654ABC5C
+:1097A000DB2F5DF9BCC53A2D9E4FBC8FC9C32FADD1
+:1097B000095C0E4901D8170F59E3B14ED763D42F76
+:1097C000070D0C4E3D87F34BABC78F7C09C248BFDA
+:1097D0009B49027B8CAEBEDF8DE29F75308F2B875D
+:1097E000B3CBE8A470ADE47AA4A4768BF47114DD55
+:1097F0007F6C95995ED9B65972221F6F6929B7633C
+:109800007B1203FA639B84FD56D2F7B745E90F310B
+:109810008F7EF4C826988FE544CF7EA64782C86F16
+:10982000025E414741AFAD56277E7F3AB5D7CC386F
+:10983000DE927AA0475B3A1B4FC8B5560EB772BE90
+:109840004EAFD922E9D06EEAC179AEAAD1235DF636
+:10985000CEBF65198CB3CA9E960F7CF8F86F8E1830
+:1098600025FAFC39DE6F5587E4C175A6E388712EB1
+:10987000E87BFFBFC9B03ECF644B28D9F0DC11A311
+:10988000933E9FB953C2F156EDDCAE5F6A89F09FFB
+:10989000EBCCDE5B803F5775C510B3047461EB976A
+:1098A00096EFA87E4079207E23F757286198BDEB7C
+:1098B00082F54DE8CF2F395CC4E22DD4D9411F8EFB
+:1098C000CD07BD77883F17E397C7BAF79A40FF15D2
+:1098D000307BD675E628C2F93B8E473A7E10F527D5
+:1098E000B5CE601D13E3F7D5FBA3D14EFD82AF4784
+:1098F000946E6FF5A7FFC5F8AE27AA89333E8A1E7E
+:1099000080E7283EFAC86AC4EF7F64D5E378FA524C
+:109910008627BD91CD5FBFC61400F97AD55AC1F034
+:109920006333217E0E707A1FE0F46ED3ADC96D648F
+:10993000EBCEC700CFDEF90984E917A64F1E7F568C
+:109940006275BF25007E55BD6F0ED299D8CD6EB41D
+:10995000077DFB8D73E323FCA6A5AB73C71E23CC49
+:10996000636617E3EB08BE022A3EA47A0AE90D7487
+:10997000023C0A7917781478C9E5F26EB479BE040E
+:10998000BB49F87D968561F4A7B57299C8FDBE46BE
+:10999000F0FB28BC456E5687BFFEFC3D0197E82FC3
+:1099A000FCBD954DBFCBFE84AE0377A4BE8625F8E3
+:1099B00011607F0BBF42B4576C6CFDFB9AD33985A5
+:1099C000F3D1CAC22ED4B72B3F6944B9B15430FD8C
+:1099D0006039A1D66BC2AFA00E37EFC7F4E50A7BA2
+:1099E000BC5B9206D63F2B24E245BFF112B53EA9DF
+:1099F0007D5E6FE673E4EF736DCC2F38B595120082
+:109A0000F57F23DA9B038FD778F85AA0F376D9FD38
+:109A100024E93B2E091E9380CE2BB97D7D765BD940
+:109A2000B57FA47CE2DF9AE81E4EA7FCD9B6D9FF29
+:109A3000F047DAFFEC96A96E7087EDAD5EE49BB05F
+:109A4000C3ECEE74613CA302FCCB96AE7D09102FF3
+:109A5000F9F4DFC71580FE9BCAE13CF3ACDC047867
+:109A600039F3ECBE87FF42FBD505F2938115D6FC96
+:109A7000EB2BC610855F1778F46FB0AED56D4944F7
+:109A8000BBAFF5DF7F3105EA2BB724A21E6DEDFADF
+:109A9000257BBF95BD3FF3CBCD5300FF7BFFF599F1
+:109AA000DD305EBD37C10DCF3FFDD767A680FDF627
+:109AB00063CAE70067BD4FEF413C0ABED6EAA9ED95
+:109AC0007B900F059F50BEC67808A961FA46F0F159
+:109AD00051D05BD4DEA82EB5B44179F406730DF2F3
+:109AE0003397CF8605D6CDB8FEF95D7EE83FDB6BB8
+:109AF000CD073FFC763E7FEA8333BF94720DF8C9F1
+:109B0000716382C60CDA6EFEC2ED5300CEB65852B7
+:109B10006C467EA50F295DAA51D8E8381DAF7E2D71
+:109B2000E5113296AABD93B9E84F6EF986F2EBDBE8
+:109B300006E60FB7713B7CFEC20F255C27885E39B5
+:109B400029E21FF2E5D6373D8E27DAF5DA6D1C0FD4
+:109B50006DDCFFA7E3E37A53B49AF1F70169492B6F
+:109B6000F82F07EE0D4E02FDF9E2E9BB63EBC744A7
+:109B7000F339EB9FBE93E987553B37B71869FBEF85
+:109B8000E5E617C167563595918F93805F2494B7AA
+:109B900006BF45A5075B6C4CCE921562BF0EE20F67
+:109BA0007A62B74049C83103E2E7491E87A1224ED5
+:109BB000F17EBE65A103ECE10D065FDA04F85E1BE1
+:109BC0005FC7B63078697FC55280E329D715E03882
+:109BD0003D061BD82D04E360CE57666C6991227058
+:109BE000538ECE86F50CC62BB4C0FAE3AFC1F5C7D1
+:109BF0006974033F9C81266988AFBC456323F3D613
+:109C0000C60B40EF55C583DD58F233DB844829E2AB
+:109C10000B5A7ABCCFDFA72479B0245B93504F0E48
+:109C2000669FEC9D7F0EE5E7F1973E447DD400FCF6
+:109C30000EDFF77DA25A97053F6D78E143E4F7EA1E
+:109C40006E469F0D52681DC88BFF0669FC9320E786
+:109C5000CD1EF23135341B389FAFACF87039CC7F54
+:109C600068779A02FAEA1C97838629A111A027CF68
+:109C7000BDC0E4E0804E87F83CD0397A33AC43D4A1
+:109C8000AE45566E687476C6207E99BD5F52BBECB9
+:109C9000D17258F7EB881BE4BA616755A613D79FBA
+:109CA00018C4AFEB898FD6815C58A9F56A76C2FCDF
+:109CB0003E980EF035D4930920DFE9D33C2F409D28
+:109CC00074337F36B9D65EA247FE5A3C1EF86B430A
+:109CD00056D73A58DFFDD43E85F96C307494EA6962
+:109CE0007D43B953A118A3F8A1EB1DF4EF5DEFE696
+:109CF000EC44F9B52F72B74BFDE8871736A7C27849
+:109D00000DB94637D82933BB995D4DA85D0DF036A6
+:109D100074B7E402FC339DD7B965FAFE738E1F81D8
+:109D2000A799D3289FC2FCFC1602EDCF197A6E8149
+:109D3000FAB9E728034A28AE2500DFE93C693CE888
+:109D40008B575FA0F64F5E841FE39FA77610ADDBB5
+:109D5000F48AE446399B1D134DCF0E035BAFAC7CF8
+:109D6000FDC9A960743DC5E5E89458276C46CEDF6F
+:109D70003C4EA9F8F3605DFE9CD31B8703FDCFC763
+:109D80005DB52C887254BF8DD96FF6184FFE3D51CA
+:109D90007C6B2F63EBA588173B641D8B1B83FF62D5
+:109DA00007FFDAD929233DAB91BEDFB38F2C30D327
+:109DB0007A4C12832B3D575AC0F06244BC38927CD7
+:109DC0008F82DD1C1E2515753AFBF27B5C128F839A
+:109DD00025790B217EE5A0FE462BC6AB4B7466169B
+:109DE000BF76433F875C8DFE6DD891E6EE54C93552
+:109DF000B30B4F27C7333A07DED45747E9FD885FD7
+:109E00006C76835F735A17D49BA3E2D9627E8196E6
+:109E1000D89A687D654D62F6416014A901F9A7F6EC
+:109E2000B905E39F0AB58BC0FFEEBCFE97CCFF6E71
+:109E300045F8FF6A53D8F7E83CC04E73E47857B34F
+:109E400075341EE175E49025D0CFD19A2A011C11FA
+:109E50007C2A9B019FBFE0F414F67903E563B0EB25
+:109E6000889EC985F32509E31603E981085F333D20
+:109E700030B39BD137AE82E90132461A0FEB3DE891
+:109E8000B7AAB14C0FB8C645E4B7C1181A017C781F
+:109E9000A57AA03C2E80F2533E7A04C61BC438E754
+:109EA0000CD48FA4CFCF513945BB96F37DFC8B8C5E
+:109EB000DF055D0E1AFD285F0787C622BD012EF063
+:109EC0000B857E6C78F1C111BE7EE30B623DF363BE
+:109ED0005CF2F450C2E8CEC785BD99F8022CFDB003
+:109EE0003EC435B1F59954E8B07D7BEEB15F417B5E
+:109EF0009DA92B087C63CEEC990CFEB63789C5CBA7
+:109F000066CA6C7F28BBC94BE0FBC9E09300FE3AF0
+:109F1000E302A057443C460B5719E77F11F710FEA8
+:109F200005C491A17D7D12F3576EE57C756F92A4F7
+:109F30005A9785BD4DDB0F050367A0F544F4FBAED2
+:109F4000E243E23B625D8BE0B945150787F9548D2A
+:109F500019B85DC71EA637F00FE8F262DAE6765C44
+:109F6000579D48CF87387F57DABC53926869AB60FA
+:109F7000FEEFAF455CD3378AC5ABCD4C4F69C717F1
+:109F8000F54720EE3B72E0F553F99BCCF6658887E8
+:109F9000805C603C01C4B6B4C20DF37D84E34FDB4A
+:109FA0004F4FF45F8684DDE48A8287DB5C10C69DB8
+:109FB000D2CF3E53EF7727A9E3E0DAFE03C1DBA659
+:109FC0008963B7E5EC26107F8A332530BE2597D00C
+:109FD0009E7F908F43F9DE5D85FA8DC5B106FB8EBD
+:109FE000164EB3530DE795E2BF4DB7BD0EF8793766
+:109FF00087976CBAB2F9FD9AD3EBE166139664D9F0
+:10A000002855BCDFE276B6C03A3F6E97331FED6548
+:10A010001D8BD7C54F217F9229BF261477E4AE014F
+:10A020007DED55C39D52134B8251FB81693E9BAA26
+:10A030009E5197AE6A9FD53854F57E48D335AAF71E
+:10A040002E7F81AA9ED3769DAAFDF08E52557DE487
+:10A05000C6EFA9DA8F0A54ABEAA3B72E50B51FDBBF
+:10A06000B544CD1F1AFCB5B774D580FC4CFDDB1789
+:10A07000A5A86F5E2456D8AF23A6D07890B771DD1F
+:10A08000EAF99F4BB2211F2716ABF170B5FC30F5F2
+:10A09000E2E5F956C8511C617C1177A9ED4F721E9B
+:10A0A000D435F2C2C79D62627232D8B86BE26ED10B
+:10A0B000039FEF864A943DFCB646BECB6B12D93E59
+:10A0C000CBC5EA41EC66260FF3624823F0CFBC38DB
+:10A0D000568AF763ED4CEE87DB793CE90AF9F738ED
+:10A0E000E7F7A303F12F356F92815E1504FD69A593
+:10A0F000A2E54F10BFA9D507493E9597C7F97C3611
+:10A10000F0FE1B9B151CEF67CDA9586E6A76E2F333
+:10A11000279A73B10C34BBF179677331965BA81D34
+:10A1200007E553CD15586E6DF662BBA79B6BB0DC8F
+:10A13000D6EC63F2A8A5DB451BFA33F3885A6FCD42
+:10A14000AFD1EE87F9D93AA4E93F9FACEF817D7793
+:10A150002D3EFAF4971726F6B74E8BB2E9444960C4
+:10A160007F54FB49F6783BEEBF4D2413D13F1DA42D
+:10A17000FF57CD9EC07EC3E07CADE51F72E99EE136
+:10A1800060076BDFCF03464EA7FCFBB8ADDD6FE980
+:10A190003B2ED5876B439455F240F6A2E2C87B3440
+:10A1A0007CE9D127AAFC5B513EC7F9AB84F36189F6
+:10A1B000860F37703EFCFEFF513EDC6B8E473B7ACC
+:10A1C000AFC199E988A2EB5E731C3E27B9C43987F9
+:10A1D000D245F210C545F972BF9DEDD349E031601B
+:10A1E000FC779882F10BF355C639347894A879ED51
+:10A1F000A2E395D0728A0DC70FEA617CB72EA22F19
+:10A20000719F3E36C2CF725F7EA0E3F88D14CE5FA1
+:10A210001B88D348DFBF6777AAEC8752BD7C59FD06
+:10A220005B0A7294D717FE3EFDAE528E9EFC6F966F
+:10A2300023C1EFE452CE306F7CDFF7255C8E16DA57
+:10A24000AF6FF78F89F07B29D85F51701CE3FC7EDC
+:10A25000CCCEFD1B6E6F007F14F46377BC6E57DBB2
+:10A2600067578BEF12AEEF0809A583FC5F6D7F2A5D
+:10A27000397AE857624AF0C7E55D7DFF81F0D9A7DA
+:10A280005FB7FD8AE24054D34830FE720EDD729310
+:10A29000C50FFC44361ACE86A2F8B829CE7BCA4E2A
+:10A2A000DB771B4837EC2FD065DBA92423DF235E47
+:10A2B000E99FD744EBF9BC3ED12F213FC7D04A13C9
+:10A2C000C847E8E0D7A02FF27939919710064D05DD
+:10A2D000B91913AF077DE31668E2F1CC22519D4610
+:10A2E0004D9564913207E31269B50DDC910E02FBC6
+:10A2F000E2ED92BB4DA6DF93535CAD00D4F88A1219
+:10A3000099E0165B079693484F2BE4CE4D216119D7
+:10A31000DA179BBA5AF514CE21E4927212782DE521
+:10A32000A955DF50D7F02B33DB1F6E32B1F207B1E6
+:10A33000099D507E6566FBC5FE5282FE8FFF83F845
+:10A3400000F895F74BBE3807C5CB573ACF22F88EA9
+:10A350003E29D3C1E3A91F8530EE2AA1DC975A0A12
+:10A360006B6E437965CF11AFAE483BACCB7DEB3F15
+:10A370007E80C5075A1F647CDDDAC2EAC31CCCCFDD
+:10A380004B77307E1EEBE0FA1E28938CF8413A980A
+:10A3900089DF0FFBB82497E2B788E11BF1673984A6
+:10A3A000F88F255D883FF3BC8D081F9538CC5F91F1
+:10A3B000825EF24D5CDFF1061AC764EAF098289FCE
+:10A3C000C42D0CF80DFD8CA3E774D2CF3162BEDD35
+:10A3D0004CD9371EF046327548F758319EE2E5F900
+:10A3E0004D8C3FBF053D265F093D0CA5EE1E0F6558
+:10A3F000B1B9B112E6915C2D5DE6396C62BF1959B5
+:10A4000075771AD90C7E7F9D9DA4427E9CD16242B5
+:10A41000395A9BE5C4B8BE710471AF01FC797588E7
+:10A420003F315F91C725E492E2652EC06F0C481F53
+:10A43000029E8CA98DE8AF117D2803DAED9618FDF8
+:10A44000B5F27C2BE7078A50C6CFE4F2EBDBF65976
+:10A45000D6F7EC286CC367BE5E4CEB25D69BED0AA5
+:10A46000212336ECFC9E9EDA25DB8F10143669C35F
+:10A47000A18740FF6E9F6BFDB983B6BF2B65E94393
+:10A4800006AA57B62F92F0FD17F09EE2F7BD12D242
+:10A4900005719D9F24F95639281C0B5E771E801C80
+:10A4A000B6ED07EFC806FCDBCBDC2119F07D738C21
+:10A4B00013F67DC8250A07C5C32F01040A6717C410
+:10A4C000130DECF954FABC56A067003D3351D4FD8E
+:10A4D00012D1D3FA6451E7E36E817A4EA4BDD04B1A
+:10A4E00039CBEEFA8F1F821DD323635E8454C3F6EB
+:10A4F0004926F272322FF37969AB6076CF8AF56420
+:10A50000BC44FB0F5B26F6796202C3E97F0ED94497
+:10A51000DFD3FAA947C9789091930667AB05F87124
+:10A520002C71431C99E8197FBE9D650D40BCE294D7
+:10A53000445A31CEFC208B33431FD86F742FA3B401
+:10A540002E0493D0148078F95BCDC4B37678947ED2
+:10A55000A4B4F114B1F00BC3C318F49B2691C81F27
+:10A56000CCB33C822794ABE9BC3EA39EC5C9623CF8
+:10A57000546FC2FAA5D1B76612483521BE5C98A7C0
+:10A5800021CF200AC09B5D11A44B29D5A79E12D4D0
+:10A590009B13886F5F0F2DAFF56CE77A34D00A53A9
+:10A5A000C410470EAC8F4E3DD0B38C5AB050AF2084
+:10A5B0001D587E8F746159497AB0BC9184B1F412F0
+:10A5C000C500E54B0E17CAD31413D5E320FF7A2735
+:10A5D000C6034FBEA6B8212E595DE1333AFBB13F09
+:10A5E00096EB09DBA723BE6CCC1FD3FBB2E745D9A2
+:10A5F00013276BE72FF2D07E4E9D3ADF728F83D9FF
+:10A600000BBFE3FA7383C4F5C82A29007EF1865A8A
+:10A6100023E6D71C5D2575427C9EBEC7B8ACBFD66D
+:10A620008471BA0D066716D8177F7138597CAD7ED4
+:10A63000FB0F401F1DBD61451AC8EB71C937BD8EA8
+:10A64000F65B5EC9E2EA44EFCF9A1B25E7A7163313
+:10A65000B8443E42AF3DC3E5F82FA05B20FE4EE17B
+:10A6600047FD25E26E0BACA867CA498D1EF2A13FDB
+:10A67000E6F30870BD20E4A74EF081DE6F4CA7FD25
+:10A68000E6B95D88C7050116B72DD79320D8C3BD9D
+:10A69000F0D76CBE9750FE5850B747BF7C0CE613FE
+:10A6A000613C7339CF2F92EA9C0FD861DFF13EB63F
+:10A6B000FF12C91F62FBC7CB176E5F8471856531BE
+:10A6C00004E462F9C647DF07799F5F37C309F8A33F
+:10A6D000DFC3B8E97413DB1F34D1EFC37EDA8C3AE1
+:10A6E0009EB751F7A31EE04FDACE03F6F074DA5EA0
+:10A6F0005F0079392CEF2DD6CFF28762A789FCA1B4
+:10A70000C6030EC81FBA93B8FDF4B3F3376D96585D
+:10A710005E2B41BF65307BE65F7E74C98AF62DAC47
+:10A72000FB43283C4DB213F6F3895EC1FE0B4C0C83
+:10A730007F6D75ADC8877FAEA193A0DF9DD7E16225
+:10A7400079F0FB997CCFABC90F411CC9541183F33D
+:10A75000048D04715F13A94079CF272C4E7137CF38
+:10A7600037A756AF0ABE3EFE01D577B03E0C645700
+:10A7700089F9989A8C0C5ECDBC84BE00BD12EE4760
+:10A78000CEA58A57991DC64B907B90D702935B8EBE
+:10A79000D7018B7965A637FD04E3E5E43EB69E98C4
+:10A7A0009F92601D37D9FDB780A97D6AFFB0072C45
+:10A7B00088AE0E12ED17984ABDB745E7233F58E221
+:10A7C0005D149D17E14E66FC8DBBF8C0E3AFFBB393
+:10A7D000E13BA7DF60EB83FFB61827C6A506C103E0
+:10A7E0009D7A40977305F35DC6F5392F23F6A2B322
+:10A7F00015E859963C14E129ACA892C1EE7876F39D
+:10A80000C4B7AE257DE934101F69F1F37592676610
+:10A8100032B3AB7557625797CB9937D753FEB9B060
+:10A820003006E54AAC8305401490DB1E12A0B20D41
+:10A83000EB03AE1B696D44919C10AF84DC693E0E46
+:10A84000B0718D89E855F14A4555CFA84B55B5CF24
+:10A850006A74AADE0F69CA55BD77F9DDAA7A4E5B24
+:10A86000B1AAFDF00E8FAA3E726385AAFDA880579B
+:10A87000551FBDB546D5FE029D5290CEA7F0F7B24A
+:10A88000DB0FF4F57B7AC61445D6F5B15D3E55FF76
+:10A8900089A1C595A09FC675D7A9C62127A85D66C1
+:10A8A00082BC9E464E0FB70C7AC24D95EFCF5C80AE
+:10A8B00042F61EDBD3BAFBC40D9F829E5E506388B6
+:10A8C000D873D08BACC7B8A35B63076AFDE215876A
+:10A8D000FC072C14BEDAD7FDEB80FFDB93D57E722C
+:10A8E000B96CC1795D3826635E491D70A63D42C7CB
+:10A8F0000B3010CC7B0F09B0BC0FF5BC851F5D0B76
+:10A90000F8A1FD16D07182F4554CAA9ADE66A79A7A
+:10A91000DE71B96A7AC7BBD5F44E2C56D3DBEAC9CF
+:10A92000ED17BF49156ABA0BFC16D3FF017EBF6B4A
+:10A930007CEE00FCC591A838C324D4A77FDEC8F5FF
+:10A94000695F3D30C754D4570F08BCF5D10716E6F0
+:10A95000AFF4EA838D5C1F6CD4EA03CFBE340ADF08
+:10A96000041FF51FE9B8EF2C9A98017A2D9DEC127F
+:10A97000F9FC3EC89FA1F2FD6AF204D8F77387FC88
+:10A98000B00E6C8A413B72FB811168E71F1D4E2699
+:10A99000A3BB50C1ECFC762383B327D9C2F28464F5
+:10A9A0006F0FF437343506C13E7E17FC69D8FCD1F1
+:10A9B000E80BA2D1775A3B58E8935393193FBDF364
+:10A9C0000609AC91C0EF3E82FEEED5AE0B83F9DBFB
+:10A9D000BD7A74215B3726F2922CF1A3FD2ED6911D
+:10A9E000D6629F0BF2F60B4C1E99E8A2FDEF10AE5B
+:10A9F0002B53891FF5EEF515EE9FAF26602FBD9303
+:10AA000001F692D60FA778FE92E1B9777F55854F70
+:10AA1000EDFEEAA564B1BFEABD941CB5BFBAC3ECB4
+:10AA2000467EFA7D2DF33B0A8F0C6BB5D07EC9B7FD
+:10AA3000BBDCD06F87D5BD0FEABF5FC5FCC009C7BF
+:10AA40003C32E429E534BA305F6D87CB5B06F5DF35
+:10AA5000DFCBDE171DF7611ED3B026F6BE604DE3D7
+:10AA6000BE783AFEDCFBD9FB973E5F87E784026B3A
+:10AA700078FF928E32A8FFFE01F67EE289402BD449
+:10AA800047B5F1EF4B5DFB12C0AEFC6789E5D769B6
+:10AA9000FD1DEEDF4CE574E84347EE074CE1ED8524
+:10AAA0003F33B586D16759D83B1DD94B4327AD9D60
+:10AAB0005E4E7C589F41FC58DE400258CE24417CBB
+:10AAC0003F8B84B07E131CD1A1F52AE23440BD2215
+:10AAD0002517F97A36757531CE50EC36811D6EFF2B
+:10AAE000E4B7FF401222FBD562FDEFB07957817DBC
+:10AAF000602FF3DE0B7641450AB35F23A5D87FF6BE
+:10AB000067BBE9FBD3FC3C5264DFB908F3226893CE
+:10AB1000F560BF4E4A61F92939EB1BF5208F376686
+:10AB20004A6EC8779801F62DC54FF0277A2BE4B509
+:10AB3000012DFAF38323F1304DBC57EF477FA2403C
+:10AB4000768E062159FC93A71E02BF780708643A47
+:10AB500055423FE99AE947E78BD92F83B53BC6F3C6
+:10AB60006576F0FDC7395E970EF9335F6D1F2D4E88
+:10AB700061F69128271CFB6EE755B0C68FF9D37399
+:10AB80003B6308CB7321E990CFB29C34225D4F8E9A
+:10AB9000F51BD8B945A67FE672BE9BCBF9E9E4E682
+:10ABA00018A4C3A9DBA48044E159BEE9D5E3C06F72
+:10ABB00003DA476386A39E99C3F9739EA971513D39
+:10ABC000F0B5B09B7E728DFCCD68C4A35AFF0D60BA
+:10ABD000FF39785D7C4F9E42FC0E0ACF7B8B98FE3E
+:10ABE000CBF04BB81E5CA9FEB36BF45FBAF89E873E
+:10ABF000B21CAD670BFD57CFE6EFE06546BD76FDB5
+:10AC0000F0B500FFA7920E09EA59248CA593286B92
+:10AC10001C3910D272EBA09E72607F0B8C6F057D89
+:10AC200007F37E706F21E83B038F071B4C74DD0434
+:10AC3000BBDCEEC1A44DFDFEDE78D94F5320BEF340
+:10AC40001DC7CBA8E5340EF8FC1383A50DE3BADAD3
+:10AC5000784A9FF88B3AEE30B983E143EA10EB81F2
+:10AC60002F15E6096992AA75E15AB713CAA9921776
+:10AC7000F548A5DDB723C501F189C64C68AF33851A
+:10AC8000645807DAF9F99C767E3EA77D84F0332973
+:10AC900035A1F4E4229F8CE3B45D976C5C07F1B6B8
+:10ACA00075B1E1F61C98D76E1D647A469DEFE3FD01
+:10ACB000F879C53C85CDE361F80EED17AB7316014D
+:10ACC0003CB1B27304941FE92815293C49C48D7521
+:10ACD000A3AC385A5C18577C2D05992F1C2BD1EF4B
+:10ACE0001C7B5927811F9E77ED4736F07F9FD9D572
+:10ACF000B9B593B2D09787D8F2FBF056D91F43C7A6
+:10AD0000CF7B615ADC1BB4FDEA9799AC8E2BD6A1A0
+:10AD10003EFCCC48D6433E4DB549F6EA29FD3FFB03
+:10AD20003ECF6FD1BBB3ABA2E20473D3585CF7E85C
+:10AD30000071BFF18925BA540AD7D1B4FECF819EE4
+:10AD4000E27A559CCF23B94EC4C3170EA2CAC318CA
+:10AD50009F78238E23EA868B56E28B3A2768D07B36
+:10AD6000091CE5335CB4E3F3446A8F425C3FD15A7B
+:10AD7000AC07FE2B25CA7E8F84478391BE8E567604
+:10AD80003E299C660960BC6F923EDC6B070E8575A0
+:10AD900087D991188F75C17E88DA7E1C47D4756D6E
+:10ADA000FCF5125F270C9AF3FB1138D9B97D8FC9D6
+:10ADB000129461012C74E7829EF6587E7B9CE58993
+:10ADC00051FD1005CF7D499E69691322E78D97EAF1
+:10ADD0003C3351391CD5D9C01FD5DB4C7EC81F4C24
+:10ADE0009C6CC37C3AF1BD29A98C3E3BE9D205F4A9
+:10ADF0005174C487E7DD35F35D4BE5CB45E1C84DC4
+:10AE000065708BF642AF2D12F2E5B7A29DB390CBE1
+:10AE1000D71369ECDCF42285ED977CF4E0E70FC0F2
+:10AE2000F3C547628D80EC5B179284B1B49FEFC786
+:10AE300049873D4EE063F71EC877218F307B42295A
+:10AE4000CD2D62E7D3A7E1BEA7E4CF407D7BA5EB84
+:10AE5000C5FDCAE2B3C017B10901A742C789BDE663
+:10AE600034E6CD4DA4F4877994811D91D30F3D2D07
+:10AE70005FEA802FB474850F001D06A36F2C3F3F3F
+:10AE80004C486844743ED8FD4AC9D9D40998BF1AC1
+:10AE9000B441FEE3CB318CBF0E51D2D2FA9DBB47F9
+:10AEA000617CECE934DF196827CEAD92FD613C1777
+:10AEB000BB3481E7A3A57AF01CE92393ECF9ED4EAE
+:10AEC0008E6C5A2F335931AF6C612A931B318FAB83
+:10AED000E55F3BAC41C0FF9214E894069FAFC8C742
+:10AEE00015F33C93CAD67F518A7968CFBF9DE1FCA8
+:10AEF00077263501CBA7D3BC38EF3BABC31F5873C4
+:10AF0000E0FE037E8FC020F3BDF3EF9CEF95D2F5FA
+:10AF1000520A61E77B63AF0CAE35FF9FE0FA3C95C8
+:10AF2000C3957765706DF83BE1F210469FC1E0A2D2
+:10AF3000F4FC1CE48F4C0BE3FD104B6D5706DF4B0C
+:10AF4000DF017CB62B83EF69842FC8E09B47DC864A
+:10AF500054990313751E457B0E659E9EAEAD0591FB
+:10AF6000732A3A53C0075DE6E49A08E8D76F7B1E60
+:10AF7000A5978EC9246805FF7C770CC6F3893B3CF6
+:10AF8000227A5DDDC3E5E6E934CF419097A523B889
+:10AF90005EA850B73BC8F128DA89FB1648A50ED742
+:10AFA000B7F6DC619D2CDF974DD99CE9C4FD82C3C7
+:10AFB0005C6E45BEAFD8E7BBDB5A5707FB1B625D33
+:10AFC0005A774D5D2EEC6B7852FB5F977AE5BCF9B2
+:10AFD0009032CC30301E56CA3B8A1AFBD91FD99604
+:10AFE000E40BA546E5E3ADDCFA9A322C2A0E349642
+:10AFF0008474CCDE0FEB58BC97E7C7A45C1DDE77EA
+:10B00000C0980ED0CF5ED4CF629D6878F1DF9CB03F
+:10B01000FE507B80407C371C1F8BFABAF59AE2DC2D
+:10B02000E8FD1C5D9A58CFE501D673A3EA79B0D943
+:10B0300044FCD1F7339C66F73344EE658823FE2841
+:10B04000BE8DD83512F1F76BD7E8F1B9A0CB4076B9
+:10B0500082C8670D3607AB3F31C0BD16C5B3A1DC52
+:10B06000DBEC99FD09F5EF362A251EB0231CDE43E3
+:10B07000D59F44E139A5A647554FF31DAFFE240ADD
+:10B08000BE8CBA90EA7D56E369D5FB214D6155DD52
+:10B09000E5BFA86A9FD3466647D78777986647B7C4
+:10B0A0006FD3B1F308A58526CCBF1FB95151BD1789
+:10B0B00079B206BBC893D561FB518154D5B8A51EA2
+:10B0C0008BDF0AF6790B9383D15B9DAA714AFE361A
+:10B0D0001BF78D888D58619F6C6C57AEAABF4129B4
+:10B0E00056B5F798583ECD4665B1270DEC09538902
+:10B0F0007A3CB24735EFDEBCEB41F261F4FA07313E
+:10B10000FE087B93930AFAE65F6F543CF83D2DFFEF
+:10B11000FB7F3489EF0B31BF9AF22DEEE7842513C4
+:10B12000AEE3123F472CBE3387F36DBD866F23F726
+:10B1300090FC7D7CBB49F1FC16CEB78A7B5CB4F3F6
+:10B14000FC611AD3339F19FB7FBFB857AECCAAFB63
+:10B1500052227C6FC1E79F958A7B76D87D29ABAD63
+:10B160006AFCDEC9BFF3308F5FAC8EF7A4D82E9394
+:10B170000F66B8184702FDCA71023EFF6CE8E5BFD2
+:10B18000F7C3ABFE9E3CC0FC8CF89CD2B15FFC3C8C
+:10B190002CF067EBFF7D7B2FFED2547AE3E134275E
+:10B1A000BB9FA6F73B99F81EFCA6FEF5971D9F0FC7
+:10B1B000E6371193CF8D7AF83BF79708C27BB5F647
+:10B1C000FA921406D760E3BF9AE6494EC5FC936F26
+:10B1D000B76EC7C21A9D86E33C0B72B9CEC8CE11BA
+:10B1E00052CD84F10EE10F11ADBF94CBF2DC16A568
+:10B1F000FE16ED88588841D07539F67E33EEAFDC07
+:10B200002A294680FF1653F8FD9FD3F6275E8E311C
+:10B21000B27889F087E264D8B7BB5238459C45DCE8
+:10B220008B007172D077E3A65E83E7611E013F0F4A
+:10B2300060E0E71A1EA130A451FD9377646E62109E
+:10B24000E804711EFA3E01E64BE14ED459F0DCD21F
+:10B2500040DF4FA40A2CA300CE87B0FD94C45DFA52
+:10B2600033D174D0EEA77CD9F3452CACBBEFA7A9A2
+:10B27000F755FE4C2ADF1C0DF82AB6239EF35E9884
+:10B2800096127D0F496FFEA6C80B1C200EDD1B1702
+:10B29000D2C48144FC67F255C6817ACFFF6BE2408D
+:10B2A00083C5B1BE4EF2FD17F0C940F12CE35EF646
+:10B2B0003CBCD98CF686886F89F94AE94CAE437656
+:10B2C0008F944EBFFF719A47970E7114338B0B1DED
+:10B2D00085EFE4C1FEC48C4498EA97C49308FE2F1E
+:10B2E000E4FD66D8FAD209E2386BA3E4FEA8B57F84
+:10B2F0007D9291CEF4CDF9AC1EE4CBF69270F6CFF0
+:10B300000AD18F553A295E57ED62F1D45560878096
+:10B31000FDB1536D7F5471B807BB17AC22C99309B7
+:10B32000F33A0DF7D3401C3D9697094C9F8EE4707D
+:10B3300024F272122F4F737D7BDAC6DAF7F2217F87
+:10B340003F857FFF936693776D943DEAFC494C23DC
+:10B35000F8A58E1C718E8B4A0E9D57C3AE14F44710
+:10B3600096757C6884F3519EF49244C033B403FC18
+:10B370002CD3878C36DAFE5E9BAF109E37388967F8
+:10B3800007F477868CB3E93CCE737BEBBC81C5BFF9
+:10B39000CE9B5929E0F1A45725C23CCF4F0E19018D
+:10B3A0001FA2DE40C2B7403EA827DD8BDFA3F527F2
+:10B3B00034F50FF4B47EA791C73DB57A25335EA569
+:10B3C0007716ED7A0DF9FA1613599741DFDFBA2B8C
+:10B3D000C508CE4C5D827F84A28AAF7C3B7DA2B53E
+:10B3E0003B06933F6917CF57E325D9FD5A06D07F17
+:10B3F000D2EE3792A05C2735625C3A2A3FF6F84BD2
+:10B40000940EB22E9C142D7762DF678A89CADF50B2
+:10B410008C5BB0F3F50EE33AB8976C2D950728379F
+:10B42000A5337F692D970BC84D63F1D58082F7A2B4
+:10B43000F1B8EC6A1383AFC1EC79A414FCAF23B26A
+:10B44000261ECBEE1B72B47A12219E163E224B189A
+:10B45000BFE1F1D9D53C3EBB7A7B490A8CEB4FFF6B
+:10B46000EFB5AF441CAEC1AA27F6C4483F31DF0692
+:10B470007E9F86968EE2FD4B7F93FB8DBB7ECDDF5C
+:10B480000F64B73DCEE7D5707194CA6E69A0F20023
+:10B4900070365C1C7359BB6513E7FF06B037FAEDD5
+:10B4A0006FC7E7F74BBEC3C0EF5556935F063ED755
+:10B4B0007BB2D83D6B2C4FAA8EF3539DD03701B58C
+:10B4C000BE11F72589FB36E978FF06F225C63B66F3
+:10B4D00060FBBD8B8913F5D9628D5D21EE575A6AE9
+:10B4E0009983F2B2B4CD10C91FC07F7B8C60EFDCB2
+:10B4F000D6A17DAECDBF657242BFFF5EF4F7C57CBD
+:10B5000056C5561EF240B3C21EDCB76B201DA80FF5
+:10B510001A76527D9A00A53908FB28A45B3DBFDB53
+:10B52000A3F38229BC77902EA34B023F590D4F3DC8
+:10B53000E9C1F156755D1E4EE11FC03914E64FABEF
+:10B54000EF037C29DD8974FB7C42CF5341FA1D391E
+:10B550007E9A09D6EB73DD9FBE8D798FA9CC9EA113
+:10B560002BD386EBE97FD675CB0AC477EABAF7E12D
+:10B57000BA30109D7ACFE79330CE5FEC2768F9E6BA
+:10B580008574BECF9AE909011E0D43BBF05EB0F091
+:10B59000BDEC1CBC5DA6160D853F35443D335DE416
+:10B5A0007E1BE2F698207E3A3586DDD3F3BE526AE2
+:10B5B0008273FEC9569D17F4FE5A658915EE3B4904
+:10B5C000E3F774244B3A2FE8ED455416E1BEB07012
+:10B5D000ADFE499073D7F7E38239940EAF18D97D49
+:10B5E0009FF6381FDEEB10B6CAF8FD92DA2FC79B24
+:10B5F000283CE9972C05907728E09E5A161E0FF1FB
+:10B600008DFB15DF11803BEB78E8A4040914160FBD
+:10B61000EEBF3ECDE5F8E943BA8ACE7EE69D9AC1FB
+:10B62000E67D8D43EF857D90D141761FE340EDC4EB
+:10B63000F9E781E46E6769E816904B88CBF6F7BDB1
+:10B64000F80CD66E136C2842BCDF165A0E78DCF963
+:10B650003DCA23747EE75E4EE95C1335BF5F707DA3
+:10B6600071EE06B6BE897B218BF48D92754C44DF5A
+:10B67000AC50BCCFC3FCE17E568CAB70FD027ADAD5
+:10B6800089F6B2DA9F12F0AEE5FB47C28F1AECFEE4
+:10B69000CB868B924A2F6DE27C1BD12F7A7C5F2E5A
+:10B6A0005BD0CEFA3420619EE8A784E5437CDA21A2
+:10B6B000615ED7A74799FD061115A908F403D33792
+:10B6C000CB9F1CBF0EC463898FE53F2FDEB212F300
+:10B6D0008FA07E1FE5AFC5A9EC5CD592B56ABF43CC
+:10B6E0008C771BF12606C1AE58AF96C73AC2F64F0B
+:10B6F000611F19FCAC4F8F327B71F9E3EA71EAB636
+:10B70000CC3C05DFABD3E43325737DA7B5AB6764D1
+:10B71000F03CAF22527435E7A15611CFAC0CD8C71C
+:10B72000E779CA9F6EC9495912D56F6596A43A2F19
+:10B730007B86AE5FC3E8DA7AB659C1727186672E2E
+:10B74000F43F7F84CDBB31C3579BE1803A9B17D137
+:10B7500087D9BD99354CCFC640F091FE67CCCDA6B8
+:10B7600000E4C9FE08EED5A2F88D8961FA5BACFB56
+:10B77000B27C8F9C00F3FD63612ACAF9BFCFA8C0D9
+:10B78000FDD6124F3EC85F7B9505EF4DD8AC63F7F1
+:10B79000E79962D87D3E81A7AFDD0B2C3DACEBD1A4
+:10B7A000D20C50EFA120497042BCA805F35EDAA686
+:10B7B00010BC1F4D7CA738E4DD0EF064CFB1E03D36
+:10B7C000277679732AC453ECA38DFC5E06B60E353A
+:10B7D000701AFCBC3B07EF67BDB06B2496D710C650
+:10B7E0001F22AF1FBE49A2F6DFCE36D37AD4B9C925
+:10B7F0006BBAA4A001F6E9BB5A6A81BEF56B7AA6C2
+:10B80000C3BD30E15F11CCBFB1BF9256EA4C88C0D6
+:10B8100057BFFD491B9E4FE07AEF66F01761EF8638
+:10B82000DB5BBDE710B8BF53C3F9B77617F3736E90
+:10B830008E63F85D42DCD9D06F818924E828CE6E12
+:10B840002EEB9A80F703AF3458C1DEBBEAFC13BE7F
+:10B85000DE69DB9D011F0DF4E50B31188F6A782A34
+:10B860001EE37977EAC2F8FDA732B85D3182EF13A3
+:10B870000C231EC8576AD83D12F7C562E05EA602C7
+:10B88000D46F26A0EB01D0C374DEB7BF64C67BE1E2
+:10B890007AEF3D51881FE4F8CEDD29E8D7DA733C12
+:10B8A000F9778F81FB3742D928FF549F49D4567BC3
+:10B8B000E5E7EFCED2C37D1AE9541FD3FA998C5332
+:10B8C000AC3E34B41C6E3EB7657EC3EAD7844E42AC
+:10B8D0003D3333F646C88F6928082D87D0F8C4CC8D
+:10B8E0005456874433CA58D33287DC08E74DCE58C4
+:10B8F000D9BA73CEC0E2C6E75E18D5E98FA2BB3BCA
+:10B9000093EF7B9959BB332E769F33C90DA9EEBFB8
+:10B91000B5678A73516C7D14F314FDE8F8B8AFABCA
+:10B920001DFF7006EB773BBFAF666A1C6933B3FB44
+:10B93000A9FD90AFB57FD748C4CBB319EC1C10C09C
+:10B94000097901621CED3978F1DD3BC09EB460FBE2
+:10B950009AE8F5E53D4E37FA9DB5F89D319E7C900D
+:10B960009386EACC7CA01BA5979ED34BCFEECFDD70
+:10B970008CED615C2BE47B95B175656A52D2669063
+:10B980007B0137B58F2CB86E73F8FFC8D7A5DB5B8A
+:10B9900039BE28CC901FD7F022DB3705FAC27A33A4
+:10B9A0003193AD83EECC487B1C2F93E277ECD5CF5F
+:10B9B000EF2BFEDDEF7A7E5174F1009FECEF1E85D8
+:10B9C0007411F013F2A86A9C332D9A7EC504F336E5
+:10B9D0001B6C39D8EF47FC3E72718F2EF473E53142
+:10B9E000FB03F85FDC43463C43707FAB9E6B87DE16
+:10B9F000FBC3BAD8F90A328CCE0FF05A5D59C8E7AA
+:10BA0000A7F0F929D1F71FF7CADDB170F69CF8BE8F
+:10BA10007CDA8BF7DEF1C614F0F154F2DBDF78400C
+:10BA2000F781E8312AF33BE637012775BFA2E9D059
+:10BA30008B670D7C029F20B75C0EF1BE5AAD1C6671
+:10BA4000F6D25123BFAE6FF93DBE7FB7EA1F281D66
+:10BA5000E1FC8453CDCFAB76BA744BC644FAB56FD4
+:10BA6000D5C45976DEE507FFFFCE5D55985F6A586D
+:10BA700043F05EEEF0CB32EAE3F3F4DD3A3A8FF3D3
+:10BA8000DB5C0198C7035CCF3C600D274818E79149
+:10BA900075600787A97F0DEB79D84C9FC3B907FA6A
+:10BAA000FCC9A8799FF78613AC51F42A7C454E80D7
+:10BAB000FDB25080DAB9FDD81DE29EA81061EFA951
+:10BAC0005D96DD0479E81D390590F376C144B29B9B
+:10BAD000EC501F5EE0478E65F1C9F33CDFEA8FC48E
+:10BAE000FBF6F5B01EFB3DFA34CAD74B395F9FE732
+:10BAF000795875AFB526A0FFB68BDA69097DEDAE32
+:10BB0000E5962DE8DFAD00BB4CEA6B6FDDC1E39736
+:10BB1000759B34CF77513B0CF486264FDCC7E3C1CD
+:10BB20005A3BAC2993C735F3493E5B2799FD7037E3
+:10BB30008F3B88FCFBF33CFF9ECE1BE971619BC4ED
+:10BB4000F2ED89F34DF0AB1A0EC978DF15F13BD059
+:10BB5000DE8BC43FC346B0A7B47685B63CFBDCFBA6
+:10BB600045FF449BD43FFF5EDECF6979F6F9774706
+:10BB7000BC04F5DFBC93FD1EE9DBBE6CF7D7787F14
+:10BB8000DBF9DD3104ECE4F3BB5FCDFE27A8BF1881
+:10BB9000E306B8CFAF89C1FD64FFEE783C57783E2D
+:10BBA0008B9FFB7DF9ABBC10C697D622BD9ECC34D3
+:10BBB000229D2FECFAAF0F806F2EEC8A71823D74BC
+:10BBC000E7EE38D4E577BE68C6FB59CFBFFC5551C8
+:10BBD000B47DFAF7CEA781DF4F783E9ED4607C4ECD
+:10BBE0001FCE96D0AE989C0472B76AE71E23F87FEA
+:10BBF00065AFFC352F04ED76EC3192B1B89E3C0177
+:10BC000079B15D9BCA1F8673A3E740C7D175BEF2A9
+:10BC10005FD6DD08E746B578A1E39EFB2798C72BE2
+:10BC200071481F8A973AF0D706C2C7AB992CFFF725
+:10BC30007F1A3ECE1B7AF0FEC1F3DBA5F1E007458B
+:10BC4000F022B17BBB77C5074C12CE9F3DDFFD557F
+:10BC50001ED8BB9F75B5E07D0E83CDFBE4FFB9799F
+:10BC60004BC12B99B721EB7FE6BC05FF3F94E964FC
+:10BC7000FB6C1A39E82BFFBFF93ED67F1DEF4678E3
+:10BC8000AF50FE8767FDCF94FF6F4DF71D12C6E5DD
+:10BC900006A3FBB4FFB5747F8DD33D5E81FB16CF49
+:10BCA000BFFCD76C1235FFC1E6BDF47FE9BCB571AE
+:10BCB000CFC75E263F033BC330CB688073C4B3BCA1
+:10BCC00012FEDEC25CD8E92880F325E163B3216F60
+:10BCD000A446C673B5F479D089769CB767197DFE02
+:10BCE00046E163A9B01E1824778F07F6156A0D98F0
+:10BCF000DF3A57492D05FB216917F99913F7715858
+:10BD0000FEEBDC796905D0FE30E9298D03B95AC80C
+:10BD1000CFD7A4E6EAA3EF41A57F730E15E1F9158D
+:10BD2000FC6BCF62FEDCDC09AD06B0676E6CF536ED
+:10BD3000427CEDA6ECF0306B549CECE12C17CE7BF2
+:10BD4000AEDE6B8073D8738160FDEC0BCE85416DE8
+:10BD500000A7D7C07E2F88EF1379AEF956FB44E3D6
+:10BD60008CE113F7D0F9288759BCD4C0ED24111FFA
+:10BD70009905F59CC838494DFB7CD3A8BFF2028FCA
+:10BD80003391659BCB9300FF74407437EAF7942797
+:10BD90001546D5577FA87E7F9F345D555FEB52D700
+:10BDA000D7974C8FEE3FD07C6615BA0C3EDAA0FADE
+:10BDB000714995BF2A4A01DF632DA416F7D5ED1E00
+:10BDC00027E4FD127B21CEEF852C9DCADF8CE08914
+:10BDD000E1A596E70B279592C5D1FB25FBB2989F6D
+:10BDE000B32F8BFB11761E5F777B9CFDDDDF25C6B5
+:10BDF0007B77C53803C457299F60DC6ECE2E6273F3
+:10BE000046ED1F1FE5E3BE9BE82B67792CCCFF7F37
+:10BE10007B428AEA7756B4E51BB58BB386D2F6A58A
+:10BE2000DE237A909759CB6E32801E78BBEA431D91
+:10BE30008498C60D65F02FF8C6995515358F109F5B
+:10BE4000FFD17F56FB71A23466B3F9FD41C7F66D91
+:10BE5000FF90E0CBAA55F53761FFB7E359FF717A40
+:10BE6000A297A3E26AB36002902751C8E8B3E01B2F
+:10BE70004F567554FF737CBEC7F87D34809FC55103
+:10BE8000EF87F2EF0B7C69E11B9ACDFAB74C66E7BE
+:10BE900061DF9E45F07705926A66E0F95111477EB1
+:10BEA000BB82C591215E0C7EC80A2EA76FF3F3C238
+:10BEB000D5FCBCF09B065F16E06945CD0A8C1B9350
+:10BEC0004DCC1F31D1FFC17E487E50AFF24FAA3515
+:10BED00071DE241E274ED23CD7FA1BF1D996C8F941
+:10BEE0005EAA4F93387DA8BFECC47B32397F8606AB
+:10BEF000E14FEDB9E081F8434995897E7CC41F1973
+:10BF000057C2F657C61998DC1F3DC4FCB7A3155F8E
+:10BF1000D8C04F157489C87BAB6F58D47EE863379F
+:10BF2000C4B07BD1B89F748CFB4947BD6F594AC6DA
+:10BF300044E8F686F70B1B9E9311F2412E2F1FE368
+:10BF40008CCCFF5F591983E7AE56BADDEFAF04BD65
+:10BF50005019A3007CA5858BB3601D2B9727FDCBC3
+:10BF6000BD00F7B6183C7BF5D94FDFCA843889BBD2
+:10BF7000F007D3F1DE0849C1F3DAA0B89EA3F89F19
+:10BF80005DB9F8308C3B6B9B24411EB0D06FE5D976
+:10BF90004C2FCBDBEE3A9846C74BAAB4BA67900851
+:10BFA0003F7DF65309F969F936C64F827FEEE07A94
+:10BFB000BDAC32BC10DA3DB62DC609FC75C736C61D
+:10BFC000372B67ED383C8CC03E80BB2489F6AFCA66
+:10BFD00076B2B801F115C1FEC2ACCA960D85386DB6
+:10BFE000764E5B8C47F9EF61F85D84CF7E65C07B50
+:10BFF0007DC4782D9357E0F3B77F25E379FEE5C440
+:10C000003F1DAE845D0E7C0EE7AB49C74138673CEF
+:10C010008B8F7FB462BC15D66DED7EA3D85F584E72
+:10C02000FF817BEC930A35FB1C5B34FEF720E7AC09
+:10C030006F053E16F9402323E30B7A6BE9ACCD077D
+:10C040001274E82E962B809FC6D93CBE683DFB300B
+:10C05000E7235176EFFACF3FAC8475B7909D8FF60A
+:10C0600010EB34D80AAEAD2B2984E5ACD494BF1FB5
+:10C07000EA3737D23AC55353B6819F73F9B01C7E65
+:10C0800052E5D654E920948B9DAEE9F0D3190F0107
+:10C090005DE8B84B734B0E4238AAD25D85F7FB962C
+:10C0A000CBEBE3F240AEE87780BFA85EF3EBFA5942
+:10C0B000874BA891147DAEBDCC64569D872F57AC9D
+:10C0C000AAFA8CD43455FB1B9C2ED5FB99B9A354EA
+:10C0D000EF2BDDF9AAF787B2D97DDDCF4C38557942
+:10C0E0000F9DE733D7CAF04B6CE430E0C51EC10B9F
+:10C0F00085F77180F7F0B5EF64DE46E7F35836FB5D
+:10C100001D17A2677198DB7BF9AD67218CF3D866A8
+:10C1100019F9EDF6CAE5C86F751366A09D22F4E71C
+:10C12000639B981C3C46D8FD56737ECAF6E1564C7C
+:10C13000327C1893D7976FAA79BCA665328513FA1B
+:10C140005338018FCB3769DA554E47FE9DA3D197FF
+:10C15000D55C8F6AF5AB96FF9E99F0553AC87D572E
+:10C16000B63A2FED1989E975FFEFD9EF8B0CA417BB
+:10C170007BF5A186EF0E6533BD2BCA72794C22E8A0
+:10C180009D7146753B51BE4BED623D45FC7BCD2616
+:10C190002CDF6F56B0FC8FE6542C3F6C7662F97141
+:10C1A000732E9687B2995D92D444E91BB51F9A54B9
+:10C1B000E9355E4E7EB4FAF2704887727378CA032E
+:10C1C000092E4B24AFE258363BDF75BAF8638B3447
+:10C1D00026C2BFDDA18F2C607FD492009EC7BD997F
+:10C1E00004F17CEE2212C2FAAD70A4558EE45D2CEF
+:10C1F000251EDCB74A54BC581E864FA753B978A2F7
+:10C20000E111D84FC98375D98279A66DD1F2913ADF
+:10C2100084E1EDB66CCF47D9A0D76D3D2766837E0C
+:10C220009D6220605F127E8F5412DBAB236F4C98AF
+:10C23000685ED2CFFA3E327BC9D9EC09D1F8F11948
+:10C24000A1DD33E25E227E0F963E7918C6697BE956
+:10C25000CAF1BB2ACB7301BE2FF245A8DD9F7AD964
+:10C26000F5C7E6C67558CC87AE2812C4719521EA89
+:10C27000F5709CD16784F8EB727723EE5B976ECAFA
+:10C280003787FAE18B91D93EFD100DFC4CBF307E13
+:10C290001A88BE822FAE96AF04FF6CC8F258E1BB7D
+:10C2A0007A7E3F95DE56930A7823CA1CE48FD42108
+:10C2B000D265ED8ABCE28FD78F8705AA5287F7B285
+:10C2C000E675BBCDA0478E727FEB70E5477B87D1CB
+:10C2D000F787BBD9BD318F554C34C33AFF98C59F02
+:10C2E0000D78392DB9CDFF08FAE8495941FF88B0DA
+:10C2F00075724565F250A0D34D9327A01E3955E9BC
+:10C300002A00BD3D97C3F32961F4F47B25BC0FEBF4
+:10C31000F40D3FCA8671DE98905200DF21F2A5C766
+:10C3200057D3F77FDE24DBA0DFDB852BE6DE43CBB4
+:10C33000535B64767EBCC215003FB65C3E61417FB4
+:10C3400097EBBBF9302EEDFF06713A805E7336C96C
+:10C35000A8B7E683BEA37A66DE42B55E12EBFF297C
+:10C36000B02725F8FD1CF5FBA44D6CDDFDB6F6DF0E
+:10C37000F42197BFDFE5530B8BB75753FFD347F13A
+:10C380005D56E1329C043FA44942BE107AABBA929A
+:10C39000F9A5D5158BC79BE8FC12031325D087653B
+:10C3A00095CE72F04F67554845D176E1AC8ABBD047
+:10C3B0008F9EB5E92EFCDDAC5559DEF9431CC02734
+:10C3C0005EEF75A0DFE9F780F9C705DEF903CC6FF2
+:10C3D000C5A63F1D1B46C71F5BA953603D7D2C3082
+:10C3E000321EE87C74CB1776F42B7AE5A0C308F9EB
+:10C3F0008AA55BFE940E72A0D513FE5282BF03760F
+:10C40000562241F85DA6B325C9A530FED92CA39EBE
+:10C410009523583DADD8C4EAD32BA0A476DE3EB810
+:10C42000F7EE4225BB1FECC69005EF2FBC31A4F3FD
+:10C4300003FDEA43BA0F63203F38ACBEC766EA4546
+:10C44000F53D362544BD0EBFC9F371CB4CEAF5F876
+:10C45000EC6B0BD1EF2F57D4EBF28D71099DD07E91
+:10C4600046EA28CDFA9DAFAADF6462798C3373AFB8
+:10C4700055F5EF36925CC85B0D4BB1F8FB54558413
+:10C48000E51FDC444BF81DA059EE1255FB7AEAD0AB
+:10C49000039EA01DE4ADDC547C83EA3BF5D08F3EC7
+:10C4A000AF3279D5FD9AFE13F9E3FAA64B68EFE7B0
+:10C4B00007BB54EFC71FEA568DE3EE51CAC01D2ECD
+:10C4C00038EEDE07A5C88F5E0B7970B42C0C79CBE3
+:10C4D000C0EC2D3ADDB80FCA81F2A67F2013FC5DB7
+:10C4E000ECAF74BE3ACC0BD505BA16D3791E9314B3
+:10C4F0000794F74BBE27411F15873BCA206DE7FA0B
+:10C500004B8156285BE13C7B22D0B932EE0D88434B
+:10C51000754968CFD75BF879765B575EF4EFBCF46A
+:10C520009E674FF5A42EA6ED1FB00FC3788CB72CD5
+:10C53000DE03FBCDAB9E1F89E7E47E38B4E439F817
+:10C540009EC8832376F5B9871F0EF5BC04F94EB15A
+:10C55000654C6F901906D437B13A6F02BFA702E35A
+:10C560008BC61906CC33BECEC9F453ECEF8813F258
+:10C570007A63937CF258E8375322105712F05557DC
+:10C58000B2F3F06F0CE17101BE3E55398E6D03FFC1
+:10C59000FD3A103A3A4E51A5F300FC8E3551F40A9B
+:10C5A000D86B49C7BDCA580AE74E7BE11EE0939D90
+:10C5B000C77B264B4E68EFC4F6291525F794C0F7C4
+:10C5C0001E97F17786762AD3E2A03D09B8D93E15A9
+:10C5D000CF6F4D5AE87C07EC2D72C840F8CFE8E0E9
+:10C5E0003C946B627F05F3483AEE5989F3CDB53838
+:10C5F000E1776E287C2EF8DDA88F9BE1EEBB81D71A
+:10C60000A38FD73B1CA057AA4A1407FCDE4AD5A328
+:10C6100072EFEFCCC3120E3FBBCCEA5FBD398DBECB
+:10C62000DFDA5B274192CBEFD761BF434FCCB9FC38
+:10C63000778A59FB9BA659303E21DEFB49319ED3B8
+:10C64000E6EF2FE27B45339E183F3CE4AB37DB2C13
+:10C650008027661713BDE2C0FCC84BDFE0EFC78937
+:10C66000BCE158D959047CB944E7CC83727CA2EF71
+:10C670002BE00F45E71E01F5D547C67F0079CA5468
+:10C68000DF9CDC08FA669A01F5F09DB9EC1EEC9D82
+:10C6900046E7F3C7613FD6118BF93E86876EEFEA16
+:10C6A000A6E3DEA9FC27CA19E55F3CD77FA147674F
+:10C6B000033BF9FF01D519CFF7008000000000000F
+:10C6C0001F8B080000000000000BCD3A0B70545582
+:10C6D00096E7F57BFD4B3A49E79F10C0D7F960908C
+:10C6E000009DAF01823C1270C8C8A713508303D2CB
+:10C6F000A2086A0221CC8E99D19A6E6C54A4B42AF5
+:10C70000AEEE2EB383550DB5B26CADB31B1DD48CFC
+:10C7100022DBA0AB7145B711DCC1598A6AD919C5B2
+:10C72000359026B8223596EC39E7BE47F7EB9009ED
+:10C730005AB3559B54389CFBCEBDF7DC73CFFFBD7D
+:10C74000B532004C00FAD1C00170DA92C0954A802F
+:10C75000B584CF1678393EDF91C0230EC4EFD6E9F9
+:10C76000BDAAD5B7AD0AFF7F8FC30205005B1C4C85
+:10C77000033B72A04F9E0970A172F66D9087F0493D
+:10C780002B8004B09F1E221E2C4A0B3F8FF80751AE
+:10C790008B26D5219E97B6BB82F11147A90BA03FEE
+:10C7A000801BDB9136E8B5404362DD0B4D3F78AF2F
+:10C7B0008CD68B5A2CA0221F311BA8B500D50A4459
+:10C7C000EC35000D4D6BE552E4E704CDBF1EE0A94A
+:10C7D000526DB25A4F3317B83FC57349DACFE4CB25
+:10C7E000E90097E967DE6808A000D1D1CF6594D150
+:10C7F000263A760EC2C6AD553003E102E9133BC1BD
+:10C80000DE2F41A92572BFD7970160B387C38FE0A0
+:10C8100039E075A7F7799AECD226B74D4FACFBA259
+:10C820000705960FF073B7F6A207F9E9ECBD004AC9
+:10C830006E62FED05658E343BEFBACB0A60D61E776
+:10C84000B7F29A36944327C076A986E0615B4F55CC
+:10C85000129FFDE741D1653213975E285765C5F0F9
+:10C86000B9F2ACFC893D73F4B914FF62DEAF4D72CE
+:10C87000DF0A6E80BFF53CE0536621EE74DF2A21AB
+:10C88000BEDE73BB4F29467C92FB560BE28F84F7CA
+:10C890000BBCD8FD57162FC01ECFFB02F7B83F22A6
+:10C8A000FC97EAFB627EB5A117EFF834E4B72D439D
+:10C8B000E04BD4777CC12AE2CBA5D17D8F2C728648
+:10C8C000ED9EB1E5BEBCF775E66FCCE7B2C4F28170
+:10C8D0000EFC43399F6D2DDEBD03D78372ADDA8226
+:10C8E0007857FBC49A1DA83F6B54FC07E55B807723
+:10C8F000D6887FFF6A0370A0FCCEFE217AAFA50C1C
+:10C90000D7D9FFC4792993F63BC8FB75823A1D70CD
+:10C91000FCB972FF3AD2930FA5D829C07BEF5A72A7
+:10C920006C0A908EBBE3E5743FD62280DE1C3ACFC2
+:10C93000E2A2BB70BF913CC56B47FD5B097E2BD16A
+:10C94000AF70FDDE26237D3B78ADB41EE429F1985F
+:10C95000A147A5001B9B9CCCF74690C29244FADDF0
+:10C960000F0A9AC44B810186DAC0A113C4D74A507A
+:10C970004ED33C0B1ACB653CDF8A0EEBE9987ECF99
+:10C9800097F1AF7DB119079DDED057F8E6B2447636
+:10C99000F863A241FE34872B22CFA0A7D6A1647EE4
+:10C9A00076BA7DD797E279BF8CB614FAAB12E71846
+:10C9B000B5BFABDC4A7248E56339446C443F1E3F67
+:10C9C000E732A277DA501E56FD7EBB723C15340F5B
+:10C9D000E5FD8C9037CA1F716B5EB4C0EF22F9BEC3
+:10C9E000A0923F18A974801DE59476C38919FEAA08
+:10C9F000D1FA902A3F09CF44F655A8C46C5E5C6713
+:10CA0000E309D0C2BC5EA73C9DD61BF000B91363FE
+:10CA1000FEAF484F903E6B40623AD4172FE94B5E11
+:10CA200019442CA8AF79AFBEFB424822BA0CA633FA
+:10CA3000F4735E3AF43B73127A84FAE525FD32F41E
+:10CA4000695E0BF282F3E7E5BEF94208E577AF2AAB
+:10CA5000F8DA9F26FC5EFC6567788F67349F6FEA83
+:10CA60007A9BCAEFE16BE4F3F09F894FC32F1972F1
+:10CA700032FC12E87E7B6587670FD99981B72F4614
+:10CA8000DC93E073B4FEFC9D7A35FD194F6F6E5058
+:10CA9000DDBC9EE11F0DBE0C3F87716451BF89AFA5
+:10CAA000ECDD66BEB2D93F64F5FE86FDB49CA1F014
+:10CAB000F88ACAA2DD328D4747D047039C574B59AD
+:10CAC000EE59FD9700AA88FE00D38F6787465C4821
+:10CAD0003D871127469F47E5F3A4C68FB9E8D0D814
+:10CAE0008F534C42FEE77DED07A532B1DE7CB8EFF7
+:10CAF0008A9F27BCC5B1D9842F74FFD444FF83A279
+:10CB0000ADA6E7ADEA13A6E7B7543E6DC297787FAE
+:10CB100061A25FD6B8DBF4BCCDB1CF8437C5A22DFE
+:10CB2000A84EF0416011281500379D89BF4978242F
+:10CB3000E066FC70A088E15B0195EDF2ED4025C355
+:10CB4000C18097C7FF2DD0C8F0484063180DF81872
+:10CB5000A6DAF3D25FDFAE002EDC18ED6BA190F207
+:10CB6000FE64FF4D14379759C2A10CBC8F1B4FF6C2
+:10CB7000CBE417C0EF35E51D8F1E9AF5EF5BD07E35
+:10CB8000728FC8E054C78E27595FCBA0D526E18BA2
+:10CB9000E340F12B0B5D663FC2A50A6CB3E3FDB623
+:10CBA000B9944821DED7023D7E53F801B4A30E07A5
+:10CBB000BA2CD4A78E0EC91B021E0F420EB3E0730F
+:10CBC000203FB7EAAA88E3113FD2DB1508D27AB238
+:10CBD00026C34D449797AB505EB3828890CF5B716C
+:10CBE000CFEB90EE0E573FC78F95838F74DD85E3B3
+:10CBF000B02D584FFA7F257F09FECE7279DAB5E75E
+:10CC00002F0B2846A2DC1E95BC518DF2AE6C85F32D
+:10CC100013C38E8C79C574BEFA04BE4CCF179686AA
+:10CC2000827226CA337E14BC7BD4841DA27CB6D308
+:10CC3000790C3B68732B91EB33299E3EDD42F49DCA
+:10CC4000C755968B610F9DBD5FF1BC54FD477F1F9B
+:10CC500022FA9113E0257F77E35038F60CEED318D3
+:10CC6000EF6BC1BB8039DF844304AB23FD263DADB0
+:10CC70001D1C30E9A5C1F7814007EBCFC1809F6142
+:10CC800024B041D7CB6EC6DF0AF432FE7620C870DE
+:10CC900030B05DD7CB3E7E7E24B093F10F02615D54
+:10CCA0003FF7F1F80DAA90E3FD1EDD2F39E6ABBE8C
+:10CCB000E9246E01137AA10621492F3A8B843F1E85
+:10CCC0004F3FC6D20780B04A7EFA0E8C87E4CF7EF3
+:10CCD0008419E21C841DEB83D3B74ADF5F2FBE7B30
+:10CCE000BCF77BAF25DE1B7E4E6E9139FFB2CB9B2E
+:10CCF000BDDDAEEFBE9FCD2EF2A8F1F713F762E4D3
+:10CD000067D6ECFFD81BC1B16DAEE377523E364A11
+:10CD10000E2979D9EB54F3E47F77FEB0F2B1D2BD9E
+:10CD20008FC7DFFA52ED9F3CF949F14CBF4FDB341E
+:10CD3000719F0BE5A1BDBF24FDDF9FCEF9646AFEA4
+:10CD400066E46706FF86FDA5FACB4DEE0B6C4F43FC
+:10CD50009285E375EAB93759C0FF128ED7D8C12141
+:10CD6000A19CA696361FF270BED114D5687FB7E29B
+:10CD70004DCE8F46CDEF3DCFEB8FF91CD727BFB9F6
+:10CD8000E98D7AF75A57625C2A15790DCAC5FDA953
+:10CD90002321976BD5D3B9F10E93DDFFBF8B8FDACB
+:10CDA0003F989E2FC5B042F25DE66FE57BBA832ABD
+:10CDB0003A99EC36C2FABC1A628CAF41152078174A
+:10CDC000A80CEF06CD46CFD781E627D835C97F918D
+:10CDD000EEC72AC55CF4FCEC2B7F2CA7FC58CE3E9A
+:10CDE0007EEE1918EDE7AED5AF19FECCF06F8FD9F6
+:10CDF0006003E551DBB26D41D24B6B7E0EE747C657
+:10CE00007D384B45DC1BCB7E86ABF1C290DFE197D2
+:10CE1000D3B9BE19CE48E3FA463BF0CE0989F2A059
+:10CE200088393E1BF548ED2A2FC769C0385D417A25
+:10CE30009F529F2C5444DD068AB77275521D1DB255
+:10CE400020BF28877D085F44BE3357C5143549DFAE
+:10CE5000CA757EE7AF5C005C0FAFD238CFCB74638E
+:10CE60009E4DF5A803EA9CB4EE3717AA68DDA57AB3
+:10CE70001EB0C30A11BAB7C2C66A89F2C09D6EADB0
+:10CE800082EAA3E0E34DD99FA25F05AC7D2F5F3717
+:10CE90001AAF91258DCE1D6F15797DAA3ED7EBFC7B
+:10CEA00074EAF651930B8E22DADF0F9C8F0EB74E89
+:10CEB000E57C7A71698EEE1FE253DA29AE60B82004
+:10CEC000DC88D3434E91872F1F7062404EACAF95E4
+:10CED000668BBCDFF1A5296FDFD87BC964AF1BABC4
+:10CEE000C4F96B426AED66845B287660FDFE6C894E
+:10CEF000AF85CE79DF7B2FD84A54DA6FD74F7E4784
+:10CF0000FE60D025FCD1917C3EEBB0041DFD497242
+:10CF10005EEE382FFA17B0DBA41FC796FC96EBB570
+:10CF2000E5FBD38374CF065F469D67F8AFAE839F62
+:10CF30009F8252F257E74F3D44F27BD9AEE71797F5
+:10CF4000F839D6871DC4D74B8316966F57AB7D0F24
+:10CF5000E92528EAF4F68C845C863F37F395CA9F6E
+:10CF6000B19FC1D7902499FCE33AFD7E0E515CC776
+:10CF7000FDCE667A57D3BD9C7DA5C4129412E3C73B
+:10CF8000B2A333B25DFF7771FE0ED0F3BEFED07454
+:10CF900037F51DEEC1BC8FF5E0FBC577437F40033D
+:10CFA000D55DC0AD37DE0FF0504A01D51D020F65CB
+:10CFB00040D886F492EBED4B64AF7375C8C510D2C0
+:10CFC00035E9FC3F267503F1E7803E863B24AF4AF6
+:10CFD000709EE45380F70BB39C6E86EE89341E9AE4
+:10CFE0001F0BD1A68ADE073C93D79EBF95B82C8035
+:10CFF000C70071C516B41690FDB767799F5713F235
+:10D000005AAEEFB701FF9A502E4A36A80AD26FC027
+:10D010007CD38A725DB17EE5535544EF6E6239B6BA
+:10D02000EBE7A07924C7DB8E742FA1787DFBA1BF2D
+:10D03000FC40C3F1CF73FA1A889FFF8EEE99F12B53
+:10D04000A4B9FFD8814C7ADE1989DE8CA2878D10B5
+:10D0500067BF6BC87F154419DE0971867E70F3F3D4
+:10D06000B5E065780FF818DE0BDD0C3F2EDED585B8
+:10D0700016002B0B9FB47E0909393C90BDAD81F69B
+:10D080007137EFAC20BD0B364325E541179D993331
+:10D09000A8C8E87508F8605AE61E826DD9AEA09C53
+:10D0A00045CF2787A9EEF9B9E41F28CDE779EC57DA
+:10D0B00083A732C254E71FB776CF24790F67DB40CE
+:10D0C00042FAE17CE147826781FBA9C3569DFEBC21
+:10D0D000CA785D4B0DC777B8A872DE3F87F2134759
+:10D0E00022BFA99B66E1F97059D0CF8D2BA67CA6F3
+:10D0F0008E9A8B34FF8FF8DC43F157F993F9CE4FBA
+:10D10000CB72F8FCB36800FF5B976BE94EAED3437C
+:10D110004505A26FA7E376D5CD757B5CB7C3E14C1F
+:10D120000BEB0BFEAC703410BFE27EE71C784FD7E0
+:10D130004B2CA00AE8DEF471257288C637EA710527
+:10D14000BD31E7814DA4A7A49703E6B80245D314E7
+:10D150009A3F5B67C1A8CB245C6B550EE97554A65A
+:10D160007BBD09E20C3570737C6B062FC305E06351
+:10D17000887ACE7011F431FC21F4335C0C51867046
+:10D1800083D75B83FB5B1C1199E236C0C3EE4F3142
+:10D190004442EB7A0BF59FEB6E87EE7ED7F872C9AF
+:10D1A000291375D9F87241C36EB816B9F8057FA96D
+:10D1B000729958C9F664C8C5908713C24524C7B987
+:10D1C000109309522B99E6CF47B324BC0534C617F8
+:10D1D0008E2B8F4808F07C8D31BFC2757BAA3C5ADC
+:10D1E000849E187AB35076792314878EE756535E5F
+:10D1F000BA40970390EAE2FDF5B8C5391BA0F26F7B
+:10D200009A90AE7ED08A9935C06B010DFE0B6D6091
+:10D2100004BA65EE3BC700FA70DFD9F784430EA469
+:10D220002BDE0E6E3A9BBDC8026A921E3BD534506F
+:10D2300093F2BAF4CA1C133E7B50E6BA35C33BC125
+:10D24000342FABB1D444F71AF4B39CF6939DD37D3D
+:10D2500005B5685543C2DF666B3798E6CF8DDEBBF8
+:10D2600098EC3D77518D691CBE1476D688BF743F0B
+:10D27000CE18FA5F84B387CCF61772A2FFC07DEC9C
+:10D28000F0E479CA0B9CC793EC91F4DB75F3E7B437
+:10D29000BE1D92E6A13C7A4FCE0FBF954477A62CD7
+:10D2A000238FEF63224C243B36EE21D5EFA37F2B57
+:10D2B000A2B85497DE7C814A9ABBCAF6B5D17B816D
+:10D2C000BADAE62D65887795ED6FA3F70275739A44
+:10D2D0007F5D8AF8A6B257C5F399CDB5562FC056D3
+:10D2E00069A06D013E0F1D15FE0F54F17EA747AFDB
+:10D2F00077424785FF1B71FDC4EBA6FB9FE8F292C6
+:10D30000DE3C6EC3B3213F0EBB807299A82F5F0B2A
+:10D31000E0BCEB13FCDAED226F44FA20E579F96703
+:10D32000822BA9FF30A35C65FF327951E4B055250B
+:10D330001B536BA9AF5259E25F57969F581FF9E1F3
+:10D34000B857A2F363CC9BE5B269C417E4796AE9E4
+:10D35000FC8F94F8EEA779C3190EF6DB06DD3E3D8F
+:10D360003F9DA5F4C95B5C340EACB763C19D655AA3
+:10D370004FD955C60D7B9550C8AB286FB8DFEB5021
+:10D3800038CE36B9AFE49F781FB3EED16472F90D91
+:10D390001DDD6F12DC24C7EF25FDDB5AE60F107F81
+:10D3A0005DBE7393AB294FFF838D9B5B78C1C2EE4B
+:10D3B00040F8EB370EBEFB5089407D90E457361D98
+:10D3C000BCF4D57FA2FD6C1A7179897C38539C73AB
+:10D3D000CE815F6C613980CBE4470D3F347BC01E4A
+:10D3E000213D9C7360EA3AA29B7BEC6419E9EDBC99
+:10D3F00093B110B5B186DFF86D89B07FE37DDC4570
+:10D40000E9FBE435E81F382EF5BC21F17BA51E09A8
+:10D41000D85FF47C247B91023ED3E36BD7A095DFE9
+:10D4200087A12777153788BC82CEF79943E859271B
+:10D430004433495E1B76DDBD98FBB66151CFABF836
+:10D440004B7677E30925A5EF8B7686745DFD297D04
+:10D45000DF5D2D9FD17A9B92E3E155ECEC45C3CE85
+:10D4600026C1243E8FBC2ACB7F95FCD58017035A5A
+:10D47000F82DBCD82ED05EA5FBAC5740EBE7F76A81
+:10D480000FB37DF44CAAAAB18BBE37FBC5F54E7124
+:10D49000BE072689BABBE739195C2C275B98EC6874
+:10D4A00037BAD146D2A7C1A758CFD7EB6730ECE93E
+:10D4B000BEED12BF4F855DB9AC6333F7DA59EF7734
+:10D4C000EFB56F27F9CCDC5BA8110C3D9A16A47858
+:10D4D00034D326EA9290333E81DFE3BE61B3509E9F
+:10D4E000406903BDB79C591A2FA5BCE733DD7F8780
+:10D4F000F4FCC778AF6BF8F1909EF7F4644C29A464
+:10D500007AED0A9D7B82F0F7867FD0EB903AE2932A
+:10D51000EA8FF804B18E539CE3D0D1DBD2A92E78E8
+:10D5200059F1A5BB5D143F4AB3E02AFD902BF55994
+:10D53000042FE14FF435EA8E3F19257DAEDBA908B3
+:10D54000B924F44F8F4F32F74D60545C2A37C5A58C
+:10D5500011A2607F0661AA2B8C7B35E24ABECF1CEC
+:10D560008F0A3BCCF1A8D86F8E47251BCC7168522F
+:10D57000B7390E5DD76B8E339EA039BE946D9F6D0B
+:10D58000A2AFE86B36E1D7EFFCA1897E6AB8DD84F3
+:10D590004FDB7787897E7AFF5AD3F39903F77FA70A
+:10D5A000B8581DE931D11B71B176F067578D8B41A9
+:10D5B000FC65FB0461F78D780FD4F71B2F3E36C650
+:10D5C000FA80ECEDFBC6C9A9E5E638F93F58F991B8
+:10D5D0007FB3935EC8943F8ABC33D57EC7D22FC336
+:10D5E0002F6F2DF3FF98E2C0A6F46FA6D07A5D8E60
+:10D5F00073936B112E1DB404493F96BA1C9F10FF04
+:10D60000A877950AE53590E625BF67C42B9F6E1F66
+:10D61000CB5C0AFBBBA5E9C27E96E1F06CB2F79445
+:10D620003AD0A84396354A29FD2CA7A99F355EDF3D
+:10D63000BD3E1A31E1D5C741263F5FFF7B3594815E
+:10D64000FBD49E147DFCD4BAB32EE60F915BBE7161
+:10D6500008C38A4AF5E7E0257A4F395787B3BFEE0A
+:10D660007F93E6A5D649F0ECD3645C60731BE710AA
+:10D670007E23B55E7D501675ED458B9FF357E37E97
+:10D680008C7C36345FD4AD46BDBA76827F5D39CAB4
+:10D690005FB688BA151D4BAE78EFD20F0487698C40
+:10D6A000835D63BB467D876CE0EF5F2C50DF4EDF10
+:10D6B0003960AEE98E3588B60EFD3C5CEEDF5C8EDF
+:10D6C0007EE2B424EAC873B34A1EAB457E37EBF161
+:10D6D000BD70553FF8459FA9A73C7FF4FB9854982F
+:10D6E000DAEFDD1F88304CAFF2727D91DA97FA8263
+:10D6F0009898C5EB06D9EFF44AA29FA3D7D9ABF50A
+:10D700007B885940D48F3BAC5CDF19FD8955FA39D1
+:10D710004EE3A30D1817560FBCC3F7F240D190DEAD
+:10D72000F7E9F6BA71DEDD135DFCDD0568B5DE767E
+:10D7300053BFA244FE2E717DBCF33F50F4B9A9BF84
+:10D74000052F88F834F6FA41F6D34972E0F54FB761
+:10D750008A7876BAB5A4193293D73FC7FDB2D5DD22
+:10D76000474DFABEA6F763937EDF15FCC4F43C96E2
+:10D7700017B796E0F963AF14DFFC2394E7D997ED70
+:10D780000D741F78FFFF5C9ED4178BB54E5D00991A
+:10D79000D772CE2F988F938128DFAF71CE5381132C
+:10D7A0008CC7023186A9E734FA0B06B41D06F613BE
+:10D7B0007129CD4B7DC9B1FA0E86FD2CAA28E575DD
+:10D7C0001E94B55322CF177A71B1C7CA75E8C9F94B
+:10D7D00005CD14F74F4EB229024E117871A343E0E4
+:10D7E000372F22386C756DA7BEC44949F4C13F9AE2
+:10D7F000F0D55E1B2EBD7C82FF28C963B839FE952B
+:10D8000085F29EBCD864B2AB45B9FEE3342EA11BB1
+:10D810002CE6BE59700AE5D7672CC119F45D52D9C0
+:10D82000F34FB7533D71262D788EBE5B2AA978AA97
+:10D830009DEA893336618FE9155D6C7F1FE1A20A8D
+:10D84000E51FAF49DCC7F88B1C7F8CECB9CF0A1100
+:10D85000FEEEE237D26E9203B86236D253A39F39FE
+:10D860006C4548F6EC14F08B72F11DC350B9C89F9B
+:10D870000CD8E588D9A89FB363D71E1FF98D5B64C8
+:10D8800095E9ACD0A7D1FD6F1CD8CCF69C5E01FA0F
+:10D89000771C4F4EA17EFAC8623B909F46FE34FA39
+:10D8A0005E2378D0CE7696FA7D52CDBFD8235252E1
+:10D8B000BFF4DB720FAF9F5706FCFD54DE2D4EEE1A
+:10D8C000FF402C3A99BEB1A2EFC47CD43F380E9AE7
+:10D8D000F81E6AEA1EBD7FA0D9106F7FA590FB09D4
+:10D8E000DF968BBCABEBDDD3A788FFE7CAFD968A3A
+:10D8F000FCA47E2C443F7597317F5CB7D865D82651
+:10D90000E58CAFA7467FD5C08F2D797C0AE97D0DC8
+:10D910007DA775957CB6BC42F071D20A29DF7119DA
+:10D920007C1BDF7155B13F995771F5EFB8AA2B8475
+:10D93000DC6BB0E6A33EBA3D0D7D7ACDD8723FBB1D
+:10D940002EFAD7551EFA0E49AD20BD36CE8D725037
+:10D950002A92FAE6861C8C750C3E717F3FBD67A843
+:10D9600079EF88B510D7BDEF1F3DD4D6B9722E839D
+:10D97000CF674BB4691549F68EFAC5F7126C75F28C
+:10D980007D771DFCF8D44338EFBEBF9F5E4B7A62B3
+:10D99000CC4BE517F99C44FC7D6889D8F4EFD21A8A
+:10D9A00069DD97063FE4EFA30C7EBFEFFD0C4F8AC5
+:10D9B000F2FBA6E1DD9726AB38BF4B7F4FD3657CEA
+:10D9C00027B6DFDC1742F906A92E4E8D2F40A94459
+:10D9D00001F0374A1447ECC6FC898A697E6FBA6F3A
+:10D9E00019F1FF8AEE17903ECCF68FF908C5992BF6
+:10D9F0007D693D2ED5EBAE473A21FAD0F50429BE1C
+:10DA00005765715CAA33F643BE481F1E9382DC97AC
+:10DA1000B812D7F5BEB47CF716EEDF35421F438B44
+:10DA200043C4AB86892EAFCC9BEAFDA727DEE6FA7E
+:10DA3000F37F01B3C10BF8102B00000000000000C1
+:10DA40001F8B080000000000000BFB51CFC0F0034B
+:10DA500009BFE541E5674AA2F28F70A0F25DB951B6
+:10DA6000F996ACA8FC4634F30861356ED2D47F64D5
+:10DA70006460F80DC4AC4C0C0CFC4CF8D56E612401
+:10DA80006C5E9B2584D606D2B140DC0EC46F0D18A7
+:10DA900018EE1B313038183230FC3520CD7D84F043
+:10DAA000273DEA9A378A49C32936A87C3F5706861C
+:10DAB0000637068663EE107E3492FC5DA098BF2B7D
+:10DAC000841D670F9403F2836CB09B1B0F948F012E
+:10DAD000CABF839A0300878BB61268030000000058
+:10DAE00000000000000000001F8B08000000000084
+:10DAF000000BED7D0B7854E599F0772E73C96432F5
+:10DB000099DC20C0309C0909040938847095EA101A
+:10DB100082064419905A445A274005B948B46E8D7C
+:10DB20002DDD9CDC2060C068711B29C5E122052F1A
+:10DB3000352A50DAB5FB0F17956AD70D8A5511BBF8
+:10DB4000212262D7BA48DB95DFA72EFBBEEFF79DF7
+:10DB5000E49C9399807DFAECBFFFFFFCE9633FBE34
+:10DB6000F3DDDFFBFB7E97717983CC7F1D6397F03C
+:10DB70000FD2750E7650BA9A31B73B7CAC8A411EF3
+:10DB8000FE6393185B8BE900F82F2EAB6C3C636946
+:10DB90008CFF2901F9B4CB0745B2C6581E7CC8CF0B
+:10DBA000A6FAAAB79AC5A8462B63E330D59CD10C38
+:10DBB00073BE9A61DE1164B1F612C61A8CFEF12FA3
+:10DBC0009731973FBC7383C4D820E6A4FA6AAE5B52
+:10DBD00057601CD5AFB358098E171B44FDCC629615
+:10DBE000F93016E1FDF62BCEC47ACCCBE763ACCF8F
+:10DBF00048B7D5B226D561CA3BD87C9C072C90C6C5
+:10DC0000737C8FC5734643F62FB7687347C17C2476
+:10DC100096B49FDD83A19DB7F7BC773F767DFE620A
+:10DC2000E86FAC98BF7D9E467B58C7585A9F58975F
+:10DC300031FFDD8F0DE3F30FE4125CECE3BADC4A55
+:10DC4000933AB667BEDDF81B3C5EE3FD4047FD003E
+:10DC50001D62BCABB4D67A0950942ED6D1965B79AE
+:10DC60001BE2F7D1DC7CFA5EB047D798CCD8CEF473
+:10DC7000D874737FF93126637FEB1C7C9DD3959517
+:10DC8000695D90FF87F905998B20BF9C498477FBDC
+:10DC9000FCB6D4C29A00BEEB6BDD947EFEFE705AD9
+:10DCA0008FBD9E9136D5FA1BCDF8685AA656C6A1EF
+:10DCB000FEC0BB763D762780C031582B557021CBF6
+:10DCC0002415D79586EB80792F14E3031C1772BABD
+:10DCD00012F8CF35E009F330C321521DF1C3F7FC30
+:10DCE00079B2EE02FC8E60D509A98CB1FE7B583862
+:10DCF000A1D1FABF8DFD1504980C9863A185AD875D
+:10DD00001D5ACFFA198BAD2F82F9FCE8D745A51B18
+:10DD10004C787C128187F45FC2F1C5D4703ECEC3CB
+:10DD2000BE4EC674AAF708C0A7A408F3ED5214E8C3
+:10DD30006B2BE64DEB2F62B1EFE27A06557A88EE57
+:10DD400007AD8C713C48069DC28A809E1ABBE95E75
+:10DD5000DBBB8BE8AFDF980D30DF7A633E5BA55409
+:10DD600074579F8CEE0654563317B41FB4241CC14D
+:10DD7000F46129B60EEBE54AD12C3614E7916031F7
+:10DD80008043B3310F9D7560FF0324D6F307F3C8BA
+:10DD9000096B3B368480CE103FD07E4074ED3D321F
+:10DDA000AC233FAAEA242F3AAB663180BFF7D48C6C
+:10DDB0008F19FF7E1AF13168494702BB08845B2541
+:10DDC000847FCED70B0F217DD649B136EC47A94EC3
+:10DDD000B0E934884E70FB91A39A213E5D531291B5
+:10DDE00028CC6BCB5DE3599589CEF60A382801160D
+:10DDF000897B7BE8A14DE1F4F3E8BCFAB4A55EAC05
+:10DE0000E7A1795EC5CA227E2FD24538C1802E5C3B
+:10DE100048178CE8620F966B31ED30B60B055A0F40
+:10DE2000E3BC800FFA23FC601E03B0DD8FEE72CEE0
+:10DE3000A771747602E9344736D003FF033865CB07
+:10DE40007CDCD5CC41E3E508B8785918260972770F
+:10DE50009856A702FCFA2D61610DEAE5D8E0A414FA
+:10DE6000870F6179FF952C1C817225AC4F0D71F8DD
+:10DE7000BC88FD65CFEF483850EC696109FB6B52F7
+:10DE8000ABFFF50750BFE918D4D44CF4C9803E4726
+:10DE9000F5C0C9990BFC572C6884F5D06908F10AC4
+:10DEA000F5FD2CFA0AF6BF23AF467799E8C8E1E4FE
+:10DEB000F29B35CEA37AAE80B665190C11CCCD1F7E
+:10DEC000A3E078AA5F4638EC705BE90F2914FB7B6E
+:10DED000BC36CE3E7020BF56131D0E591325FA0ACC
+:10DEE000D69C9730EF0A744A9837CA1D358A762631
+:10DEF00007C7CB2539D6D43C379361B95B9311FE64
+:10DF000005ADA17A7719D160F8091A31CAE6015D29
+:10DF10000F013A48C0FA9E82F45208BFC7697C5785
+:10DF20008D8725DC3DEB76D43879FF7AE45021CC1F
+:10DF3000FB2681BE9B100F007F56E638D369C0A92F
+:10DF400080A8A9270FF0FEC303F07F30BE3E468AAB
+:10DF50003F21F52E9F85781C4DEAE04CA7312ECC51
+:10DF60004795B81C433E4478CD126547F6BF3D6CDB
+:10DF70002C2CF5F5B0C210EEF5FB5F69190BFDFF17
+:10DF8000CB2485F894F084F5398DB17F09B148052B
+:10DF9000968F93E23AF47BD34485F86AD694759FC2
+:10DFA0002998E2FC4DEBFDF4E01F5584EBEA29D6FD
+:10DFB000EF7E9C3BC9D30A9233C67C56952AD4FF88
+:10DFC000EB65521C59FBE8FB1F6DBA06E6F79B296F
+:10DFD0005218E7F77AF8032FE2C318B71B5E1AF35B
+:10DFE00023BCECE31874E66A0C393B893FBF43EB72
+:10DFF000F93B51A78669D7E743FF28709E10EBF5E0
+:10E00000C37CAAC47AAB54E69E082A5E6EE6ED177E
+:10E01000A99A13E9A0AAD945F8B68FC3C2E5448FDF
+:10E0200055A2FF439D3B1F1D0FFD9F6A5668FEA72B
+:10E030001A39FE4ED5C0FA007E5D2C913101CAF529
+:10E04000134A18C7EF6AFE202346F3D482282FBF55
+:10E050002EF8E35F417E2786337612F45D023B5251
+:10E06000B5E05C283FE9887F13599BB15D9113208F
+:10E07000B24FA2201EC8D89D752FE83AC0BD4BE212
+:10E08000F9D2BA17223AF5DBB2F606D3FA628D124C
+:10E09000975B51467A6FBD90B3315D2239EB0E84A8
+:10E0A000772A30CF29282D490F46A748828EC8DE0F
+:10E0B0002A848AE37BE0994AFF9EC6F9BB7AF2592B
+:10E0C00052EC7AEC27D6F8998395E078594EA493D0
+:10E0D000A5929FC3518D0FC6FEBBBAF5517CF01CB3
+:10E0E000F378697CFE4BA5E4F6817DBC3B1AB3AEA8
+:10E0F000CF47BE5D2985492DBAE383BF65924F772F
+:10E100004A3EA247BD8AEB617D8044E31AE5B78BA6
+:10E1100071964A42EFFDF5EB5E9A7CDD063F746630
+:10E12000A0DC3C557D4B26A78318F187414FBF3EAD
+:10E13000FD8A83E8785E1EC9A7D81AC5225F6E5F84
+:10E14000966EC92F6CE4FDA49A1FAB71F5D42F30E5
+:10E15000D131CB257AC8E645F02922A17E66C2EEF0
+:10E16000CB11F4D3CF5F2D3168973FB1F510D94F64
+:10E1700042EE0D8CB44F5521F768C6B077E3C45713
+:10E180004C53611D01FC17E92C55177C2A5D72A1C7
+:10E190003E6691B4D1580EDF0DBE02BA1BB052B527
+:10E1A000F0734ECC9ACFA8B4E615B33C0CF5ACC7CF
+:10E1B000586F86B04F5944D790BE5AA4C43BC83F4D
+:10E1C0002DEED722B380CF029D8CF9804EB2A36A88
+:10E1D0003C8E75CBB83E1B8CEB86EF399A339E8014
+:10E1E0007EC1AD611D48976A871BF1E8AA0C2754D0
+:10E1F000D3FA19760AEBCD1173DB386B6E16CA2D84
+:10E20000A33F98579FF69B1A76EA284FD57073075D
+:10E210004F55F2835C508EA408F6D5B3C487AD5237
+:10E2200052FFC4182725DEBBF1CC8A5558D7FDCC48
+:10E230001346BF22D3197E27064D6B4A9CE17AC054
+:10E240009B634A671DEAD9A32CF6228E97796DCD80
+:10E2500010A427E9DA9AE19DB06EDF48568D7C3232
+:10E26000FF9A85EC2CDABDB951FD2C947F2429BC92
+:10E27000FFF34182832266E748DCC634B49FBDE1E8
+:10E280004804F52A1B437695C31DA6F41DE42F8090
+:10E290005FA7E0B38F246EDFC1B2124877463F60BC
+:10E2A0002FBD8EF32988F8CB55989FE235FC88EA7C
+:10E2B00077AA509E66B8499E4E574A32BB4CF4FF2F
+:10E2C000B6E8AFDB9F117E448FDFE36B44FDFC605B
+:10E2D000C6C17C61DF7F82E33AC5B80F8EBAD39D99
+:10E2E000CCCFB85F8AFDBB64A233677E98EC0C5636
+:10E2F0001861E6795FC3621F623D772416417A5147
+:10E30000BCDC1E7907E5DE381CF7403EE65510C838
+:10E31000C86FBE6B16D278EA14C33FAD36FCD37714
+:10E3200008FFF3AD7E9F3B17C6037ECC605BFD67A5
+:10E33000D389D50A2FC17AF472C6ED86DF65C41B76
+:10E3400000049FA7F946B34CC0B39BA7F77B7C3B67
+:10E3500030FD3C2D18473BE473B9B5521ADAE37728
+:10E36000A739741DF5958B4522C8F77F457FCD7F72
+:10E37000E3FE8E2189A5EAEF72EDEDE331567D359E
+:10E38000CADDF585AD5184BBAA427FF467B30B8526
+:10E39000BDE944BE46FE70479B43D08F7242616820
+:10E3A000FF2AAD63C8AEEFB60F353E8E3397EDDA78
+:10E3B00060D885267E7017CA163B420D78AC76C5AC
+:10E3C0007CD033267BA5DB7E64B104EA6715680543
+:10E3D000FD44481369683F02A5627B5CD22592D751
+:10E3E000DF67663DB5BEB09425D3072AB6833AC829
+:10E3F0001E5C6E5ADBA59623B6F1E659E77BC5EDA8
+:10E40000BCAA76D6A48752B753D959B3BD8BBA04E8
+:10E41000E5C35FA0DCB06B68DD7A00F1D925F4EFCD
+:10E420009F557D21C2EBCF1A485018F458967F2D86
+:10E43000DA037A93A4219EAA5AE6644A505E754292
+:10E44000C995430239903F169A41788BCA0E61975D
+:10E4500074AA285FAB2686AE47F955F9F7D02FE2AC
+:10E46000BBC0253D01F5A64EAC5B82ED6ED66E734A
+:10E47000B820FFCAD30D34EE72ED0615633CB7CB5E
+:10E48000DC2FFBC393CF8D6730BF63CF64B004E94B
+:10E4900091B813F5C8F27D4A04E3122B9ECD207D7E
+:10E4A000B3FCF9553B67413FD2CF33683E95CF2F40
+:10E4B000DDEDA2F935D07C961FB825F3119CE75B02
+:10E4C0000A7303AD1DABE3F6D22A5833FA29E743AA
+:10E4D000AE9D3B423DF033E061E417B784D6A2FD28
+:10E4E000BB7C4F688C62C2D77295DD112D21FBF782
+:10E4F0008EB949E45D9DCCE5F42721D77C9CAFB46F
+:10E50000E7D0B7689DEDDF70E03AA5C62CE787003D
+:10E510009FEF8AF5423D5A8FBE578A1741F9277BF4
+:10E5200025BEBEF651DBD34238FE76E7228ADFD520
+:10E53000517D98FF1DA80F16EF09AD1D08F5163780
+:10E540008742C8EAD39E7DC6C7EDF88857027CDFB4
+:10E550002D786CF51E2581FEC0DDFB56911F0579D7
+:10E56000F20F563CFBAB037A06B6572C7C7577FB53
+:10E57000839FA13C5DF1822B9C80FE7F0FF6771A72
+:10E58000F673D0D165B6277EDFF1840FF152F61B0A
+:10E59000D5F21DC7BD984DE35439337BB703C83B53
+:10E5A00091FE56B7AFA77156EFBBE923F4CB5633B4
+:10E5B000E8C7649FFC1EFF017ABAE6545DE351D3BD
+:10E5C000FCF6CA19B928BFD9043601E97CA512CDD9
+:10E5D00044BB83EDC9491A27FCBC566F3CEA20BAFC
+:10E5E00027BA00BF6B9B0EE37FF2FCBF6DC3F51F24
+:10E5F000FBF28FDBBE8FF0FF559A1FE97DF5931F6D
+:10E600006EFB1EE4FF70D02523DD2C7FF2E3DF617B
+:10E61000F97FFC627836EAFB2332D7939F863EEF80
+:10E6200087FAFABE5F4DEF8F70B86FFFB4FEAC0F84
+:10E630007BF253A0AFB8CBCCAF71EA473B08FDF5F6
+:10E6400087EC8B22B5E1EFC83E25E105FAF9C33B23
+:10E65000AE38D2F76AF856530AE5D54B293E81F910
+:10E660003500EFBB9FE67E666F78EB83640AC225B8
+:10E670000661E8EAEE7DB7CCFE5A19A68EB086EBAD
+:10E6800065E7D7A2DF666FD78DC71380C7AB7B97CF
+:10E69000AF661CEEAB590B1FB7FA868F88BE6C783D
+:10E6A000FC03FE63526F3C76D9F0F81F7B6FCB4CB6
+:10E6B00060E1BE9CA4F69981C755FBBFDEA7DDFED5
+:10E6C000A98D8F53C17999B0779F95231764E4C3BF
+:10E6D000E79FDABD05E0FCE9BBAEF02C00CCA7CF8C
+:10E6E000FC3908C6023BE738FF2DE4C7F3BF72F9D7
+:10E6F00077409BE5BF7ADB19017C7FBAFFB8531BDB
+:10E7000045CBF14A20D73F65DD7F1D28E7EF16FE98
+:10E71000E2EA5D1909B44F0D7CDD1D9F53A9F9E8AC
+:10E720003BD9AD77C7391FDC1D3F344F4A82BF91BB
+:10E730004A0197E3F13C82CB2AAD83FC6C335EA5A2
+:10E740008988CFD3D723FDA5C2A7B17E3FAE7F82F4
+:10E7500009BFBBFAE6D34FB7BB5429B3379E3F1569
+:10E7600071D9D571E9ED647837E24C4C59D827BEA0
+:10E77000EC7451A458E9C2686FACFF72FC7DF97566
+:10E780007D35B8E522D3E7F5865FDD742EB75F0FE0
+:10E79000015FC2A7E30EED47DF413AF9B583ED8093
+:10E7A0002637177CA46AA37ACFF75F803EB5E13D98
+:10E7B000F9E8C4CF1A73A05D744A88C7ED6CFB0AF0
+:10E7C000D1290AD3CC7E9CFFC8B567C6A686A7E22E
+:10E7D0007353FC8E45D4B3880FD00DD225B9073EB4
+:10E7E000E469F663628F08FF2294FF76775E65E83E
+:10E7F0008F2EC57FC27CAA22654EB41B96B098D3DB
+:10E8000001E932D64AF9E5AC9DD295AC8352574026
+:10E810007372BFA0C27F96EC9795CAA5F42BB75729
+:10E820008CF9BD2E690F5500FD38F219ED131C1936
+:10E83000C0E2C81FCE412F06900E5A007E0CE0B7F2
+:10E84000B6D68F462D6BAECDA7B47B1F2B3284EC92
+:10E85000D07BFD7CFE6CCF934F3ED94F983E008716
+:10E86000263015DA4DF4F816E203DA1FAF75537A45
+:10E870006B4BBB03F95B5AF91CC5138E48EDD3F300
+:10E88000D06F5A2595F2B8A67F7A2EE487B6F84B5A
+:10E8900031DEFF9AC4F96068E5187991A9DFDBB130
+:10E8A0001FC8DFBE72CC40D4373BBF542C7113233A
+:10E8B000DDA7F0F849DD4627D9ADDBEA18C9F96DC7
+:10E8C000935C83C92F060B0BD73359D8D547A7BA0A
+:10E8D00006DF07F5DE5DA684310EF9EEB94732504A
+:10E8E000FF1C7AE01F6EC278DAE413FC7B2AB8EFD3
+:10E8F00010F1B25D225EB61BE088F93D00474C9FE7
+:10E90000ACD5287DBAB698CA7F561BA67C7BED4451
+:10E91000CA3F5F1BA1FCBEDA4ACA1FA88D52FE6027
+:10E92000ED7C4A5FAC5D46DF7D1BDC31B47FFEA928
+:10E93000B69ABE4FD6C332EACB446D0D957F5FC900
+:10E94000263A1FDA129663F05D6B666EF24B74BE68
+:10E950005FB0C3D1795BD404CFEF2BDCEFFD4791DF
+:10E960001E91C2F58497DBC04E85F50EAD18539EFF
+:10E97000077C34675E484372EFC14BC8515E72E555
+:10E98000F8A817FDDF3A4F61C526BE9B5B61CDBF7E
+:10E990003EB53380F2E275740C063236BAE9401D9A
+:10E9A000C615779F672C13E795EFA038F48EB4D87F
+:10E9B000861130AF6D031C653BA0DD8E31FE816694
+:10E9C000BB515639FEB76771FB74C2111E078D7FAC
+:10E9D0003C6C473DE990FFBC7409F01FC47F23FFE6
+:10E9E00089FAACD8EF31C749E20F88FD0F749EA1B8
+:10E9F000FD2F1FF0C7D13E8F4B32C1015226935DD0
+:10EA00002FEF407B9C699207E5FB7628CBC4F9D5B4
+:10EA1000CB3B306EFD4B01B7B8DF2F874DF30CB207
+:10EA2000EEB89442F25D639A733C7E67E4571BE54F
+:10EA3000307CE292D07DB8DF43E5B0A460238BA0A8
+:10EA40001F66EA87F44471DC9487FF46EE31C5B94E
+:10EA5000E0BF51EDD6FCD507ADF931096B7EEC3145
+:10EA60006B7E5C87353FE11D6B7EB32AE2963A3BB5
+:10EA700081FB0E4384DC635AA784F01D22F6818259
+:10EA80003ADF6F0FAE516D7174EB3E03C32DA5F1EC
+:10EA9000BC0BFCBF499DD6FA9AD887D06CFB10AC52
+:10EAA0009ACB2DC33FDCA832F297374EE1FB09F039
+:10EAB0005791968BFB08921FE5CECB6D7F2AB90F3D
+:10EAC000D2601BD8EF6032FDF4272F0750FE5EFFA7
+:10EAD000801C45BEBB3ED49986F8766B6111A2E9D5
+:10EAE00086B37C69426AFC454094E07C367EC9F975
+:10EAF0002F7B864AFED5055DDB81F16E034E230434
+:10EB00008EF7AADC1EBE698AC302D759F90E0B5EC6
+:10EB1000BF76DE0AF7EB2E5AF3A6F909387EB5FC6C
+:10EB20000881A76D20D7501FA4395B491EA6FD564A
+:10EB300009EB50A7A8267218B70782ECF454DCB78B
+:10EB40003CB9E6BC447ED739C6F6C3BA26D778802E
+:10EB5000184DF3D9C5F1E3068824DB6F2ADC7C6508
+:10EB600078A5A646B0D804EF8266F0F3418F0797E8
+:10EB70004DFB58C5FD9A2556FC033E5897993ECC4F
+:10EB80007918FFE4B29D1B717D0B968D198FE018EB
+:10EB90007251A1FEECFD2C48EC75A0BFBB6059552D
+:10EBA0000EEEDD1BFC0CDF5F72E1F735E1EB314669
+:10EBB00016BC28256F5FD32935249193432E3A93B1
+:10EBC000D64FA577821755AA6FE4B7811EEA725C0B
+:10EBD0005E8EFF0C8DA271BDE5F9E85F7549A8F75F
+:10EBE0007E56035A1DBE5F5D175730DF7ECE2F6302
+:10EBF0001A6EEAA4F2310F30CABFA04339CAC7BFA8
+:10EC000000F4000F462863ECC7BC1EC82719F58323
+:10EC1000BFC62FA3DE0FE9FCBBBF86B10CD4ABBAD5
+:10EC20004C765EF09CDFC34C72FA970FB0783D745F
+:10EC30001604B36A4A29CACFEC99C548572FC9EDC3
+:10EC4000B89E5F82DCF560BE0EE42EB62F642AD635
+:10EC5000238C1AF266A8452ECA283F87E832C5FDE4
+:10EC6000D91ACE276ED65C8776DCE5E4DF84233BB9
+:10EC700007617CC22E077F897AA0E4F2F2F082223B
+:10EC80008B383DE7678F5BE2F6630AF9389559E503
+:10EC9000F97F97BC9451CFE1BEBB43CB92483EC9AC
+:10ECA0000CE5645C9FCBFD0511F7223C2BBDE9719F
+:10ECB0009BB083BAE9B991DB1DBDE8DC21E2ECEC45
+:10ECC0003A66A69B60A3F6D014616F691AC2457BB1
+:10ECD00018F76743C7143ACF126AECA844FA282AF7
+:10ECE00093199A78301F6A1F15765C1A4A65944FFB
+:10ECF0006B1997EF3AF34EEDD72D82583C92938DD6
+:10ED000076E8901A6B1CB4D8D80F8F737FCB0DFFA9
+:10ED100043F95474CE1A8709827F5E1CC2F95AFDEA
+:10ED2000B2A038CF10B4FB6B025EDDFA1AF7EDDD4E
+:10ED3000647D5C427AFC3F2DDFBBF58EA01343CE91
+:10ED40001B72BFA8263A7B3CAD5B22BE0CEA8CF658
+:10ED5000A986B0F38750CE4D6EE5E749FEAF93F339
+:10ED60006BC05F29492DDFED7AC024DF2D723FA5EE
+:10ED70007CB7E901BBBCFF5BC9F92AC1AFECE22556
+:10ED8000B267271B74768E515C97FEE81C957F3B1B
+:10ED9000EEB75D3CFD51BC01E3F8D9FDC82F3E60E4
+:10EDA000D86965E21C1AB3CE63801C3BA026395794
+:10EDB00075C09013330AFB3C97981196AD74619C13
+:10EDC00053C1739526FCA769032DF5F472CEF7FAAB
+:10EDD000AB8E30FAA08707B07DE8C71C16FACAB020
+:10EDE000C767E78776E0BA1C1747320DE0B3D0114A
+:10EDF0001272053C723CEF2271BA76E446E763FD7D
+:10EE0000FB3B250DE5C62C607484D3FD8ED80C0722
+:10EE1000ACFF9FD3FF7E3EDF27EEA4735887250EFD
+:10EE2000373D8FC5C9AE07B311E9CF25F8A49C853E
+:10EE3000DDB282FB775EDA276353F87E2DF3480458
+:10EE40006716503F319FAB2917786001C6CFD14478
+:10EE500098E6EFC7F723B03F17081C0FE82FC97DCE
+:10EE6000E81D8C57B954E6F611DD2FF49F1D89F586
+:10EE70003AD92548172BB19883AF4FC5788243E024
+:10EE8000CB911BA37D960F586C09966F9AFCFB776C
+:10EE9000148CB7EE4FD3148A6F76DE3C54FB9FBBC5
+:10EEA0002E23CE00FC1D41FCE64FE67EAE41473FDF
+:10EEB0007088736F4E9E76D39DB0B7090E49F67178
+:10EEC0008CB88611CFD8A876B8799CCF6AB73B9812
+:10EED000D54E37DA6FFC323A9FEC75431FB6644B60
+:10EEE000A85776B6CCCDC47379471DB2653FA8400C
+:10EEF000F05F4A7DD82CCEED097E6DC2FA437BCA05
+:10EF00009F10EB0CE65E19FF1AF5FBE0DF271C49AA
+:10EF1000F877A30A7A16FDA013E21C9DD0C3063D24
+:10EF20000573FDE5688F851AB93D3F1CCF404ABD8A
+:10EF3000F5A6A17F0B84FE1DC262E59249EF1A7A05
+:10EF4000656773E9AB68BF0D794B09E3BE8AA15FC2
+:10EF5000404F74713DC1F5EDB0ADAA2DAE1865C836
+:10EF60008F4398E93BC6B184BE75A4D0B70E810724
+:10EF7000C757D4B7ACD8545E60A1932BD2A760AF6B
+:10EF80003C54215D413B3DF29659EF3E23F4EE1097
+:10EF9000A10747B1D3F5E900AF8216168E43F96891
+:10EFA000D6519E0E3808B5F173BDC6B959038EA16E
+:10EFB00066ABFEFD93615F5D460F0F6D33E5E9FFC4
+:10EFC000758A5B1A7430B2AC6B6A854CF0B7E86531
+:10EFD000474533C5D7839532ED7B396AACFDB89F81
+:10EFE000B6EAF72FB1C33CBEDE9CECAF3E2FFBF878
+:10EFF00006FFA7D29776BD63C813E62D2539933D4A
+:10F00000E3BE5706033CE39BB552E4A3698B9A5DCC
+:10F010004180F7CE56AD949F4374CB6497761F74AE
+:10F02000E1FB8435F84F9477A7242E3FF574D2DFA7
+:10F03000463D63FCED2D73DDE81765E715CC0EB199
+:10F04000D4F34C15777D78C8EF2A719C10D8B9E8B5
+:10F050001FFD6848F030F2A1E3549A86F9A9BFBBBE
+:10F060002D82F268E7697E4E71675EF5105662A1E7
+:10F07000334B3CC2908F76397739F91613F2F66F1D
+:10F0800025DFA63ABF9A7C33EAF721DFA63AFFBF15
+:10F090007CFB1F28DFAC7EC53336BFE272F2CD2E7B
+:10F0A000CFBEB2BC1072D42E37662B912627D0D398
+:10F0B00085CAFB6E4843BA10766B765DBD0BF3A92B
+:10F0C000E4475C2FE853DED8F9D8D877990D76AAB3
+:10F0D0001B44CE6C60130D869A19E878F13C23BB73
+:10F0E000B30DE77153FA97B9C4546A359D5FB7DB26
+:10F0F0004F52FBDA28A7836AE2A3068D752AB4E98A
+:10F1000092DC7EB2CF6B1DE37E0E0C4FF199A0B066
+:10F1100087E5F44F062C82EF4F3925CBBE9891B28C
+:10F120001AB0F30CB815D0FC75F4C35CC27E645FF2
+:10F130004B237BAF44EDA473F915FE391559F0FD4F
+:10F14000FA70A8D4386BC4289F457CFD88337600BC
+:10F15000F974B6F7AA0AE20B715F2A95DFD03D0F6A
+:10F16000637F2D0286B9492FB972437216EB59F7A6
+:10F17000CEF4E821EC3F1460E538453C87D7D90749
+:10F18000BE5E14F7787601DED422C68E00DE30DD56
+:10F1900001F217D303B51A95BF545B4CE93FD586EE
+:10F1A000293D583B91CAF7D64628DD565B4969BCD4
+:10F1B000364AE5452CFA06E275CA856503915E1A62
+:10F1C0009C6C19DD0713F7B18CF1DF73F2FD062398
+:10F1D0003DE5D4080FEB1C1C6EFA7127B7A7D5C804
+:10F1E000203C778D29D287ABA555453ACDF11F97A5
+:10F1F00033219DEB3DAE6740DA3E4392D13FF205AD
+:10F200003C093C5AEC1BF6D139D0586CDD0CE804B3
+:10F21000BE3F3B03E4E7D5C0679B1309ECCE376BD9
+:10F22000ED3D4857BEC06FBF4F69E2EC0F102FCEC7
+:10F23000467DC183D05F86DCB16005E2799B93CEC9
+:10F24000356EF9276784EA15FEF83B988E6291A91E
+:10F2500059D0B5AF72EFDF113ED5586316F0F3A861
+:10F2600079FE30C6D1B7383B1B70BFA67D010BE3DA
+:10F27000FE8CAFF21FEFA7F6FB120F60FDFE7F3989
+:10F280001F7B04EABD7053F3BB78E7E7A1195F4623
+:10F29000A7419A3FE1EC827B217DFE60E3769CC72B
+:10F2A0006307E7A5A3DFD21A7EE461147F635CDC09
+:10F2B000BF730E38EA1E0AFD6FA996494FB4840F3A
+:10F2C000533EB02A9BF2A3C7C851D443CF4FE1F7B6
+:10F2D000AE0CB83B5DFC9CA8DF25EEE185F9BD29AD
+:10F2E000430EAB65FCDE8EE3457E1ED67190E7DDF6
+:10F2F000B9D54CD248DFF85D645759F591A17772C2
+:10F300005D7EE35C7536C627F7B7C97EA4FFFD6D49
+:10F3100073D3D11E8094A1DE718465D293A38F47ED
+:10F320006F1C05F3DE5D7DEF843AEA279AFE0D98A7
+:10F33000478E8BDFDF09A02C19D747FBCFA03D8C70
+:10F34000B37B25B4D77ADA0FC2F6B0CE426C9FD722
+:10F3500047FBD01CDEBEFA3ECBF843C5F825971913
+:10F36000DFCE5723C5B8FB4F3C9F85F4FF53492B95
+:10F37000C2A3C937BB7EDCA04EC2FB43E1D3747F7E
+:10F3800060EDB3D3E603DFCEC073CDE4CF577BF897
+:10F39000BE6C98ECA952217BE6CAD51B4AD0FF7CF3
+:10F3A0005561B84F9C5A4EC83DF104124026FD41AC
+:10F3B000F96C5B7EA0AD7E81A57C81AB40ECEB5F00
+:10F3C00065AB576AC9CF7D715805D2F5DC44BF7271
+:10F3D000A4EB54F37B6330E79F3732F8D024D82670
+:10F3E0008AFB5418B4D19F9D5601EBCFF1F1FC1D5F
+:10F3F000EBF637D479A99CEE23BD90C1E31E467F7E
+:10F4000077B8B8DC5E21E858893BC95F570EAEA5D6
+:10F41000F3DB063D2AB3DCA7E93C7782D3B312586D
+:10F420004B76BB5AB9BE0353B7B79BAE57105DB707
+:10F4300027A76B1022849771C20EAA619D5B483E7C
+:10F44000EC93493EB0EA4CB297C7898635C28F3FEC
+:10F45000B26FEE83586FDD2C9599EDEAD1A21FC3F0
+:10F460007E1EDD3D603EE5AF761BFD74BE8AE75D26
+:10F47000D95199F09FFD52C16C5267FA20EAE76AB0
+:10F48000712F23B3FB7C7C98E8749F749EDAE93774
+:10F49000F176867E36E82B2CC637F475A53B9BF0BB
+:10F4A000FD42A25CC6FDC0ACE9D2182C9FD1527DB2
+:10F4B00018E75D5C534D681FB6479B5DC2F98CE44D
+:10F4C000C50B5B172D780372A3B7F27B8033DA7814
+:10F4D0003A2A2E533A3AC0CFD1CF88F374B7F0DB33
+:10F4E0001C012E77466DE5FED34B82DE46178EB5A6
+:10F4F000D81D8E7D932DF98B9D43FBB44376D74663
+:10F500002DF74E7F2ACE6518F873D8FC9497041D0A
+:10F5100019F832F068AF773C8FDF4B4B3D2E3F1F21
+:10F52000B68799E81B00B6A74D16F9DF29D35571A8
+:10F53000FF7A724FF9BAADD6F2178CF67AD7348CBF
+:10F54000D3BFD0A652FEC5755DD3EA0A01BD02BE87
+:10F550008E360E3F35C008AE0E0147939C7EC9859E
+:10F56000FCEBB6D2B3EC8E909F30CB1B6A40BD79DA
+:10F570003F7CFB25B0F4B8531DE52031701F623A83
+:10F58000C6757F931151519FB58F92C278EE686610
+:10F5900073EB513CB758F7FEF01FAFC438E20127B8
+:10F5A000F95D1F087DF4B983CBE19AA372B81EBE42
+:10F5B0001F39FAC6DC1B818E1C8D059673238E7D48
+:10F5C000F322783F972558B808BE8FDAAF2A4B4D03
+:10F5D000F80C471C245747EDCFBD11AF3636E5EE8A
+:10F5E0009AAC083E5C9081E3B9F87D8D8843B7AD55
+:10F5F000F703E2DF96E4FC3B5361BA82FCFA8ACC63
+:10F60000FDD64A7FFA1CD33987E78E819E84714BE1
+:10F610007FBD6BDF1B50AFD13F792C3F37D5BAF0A0
+:10F620005EF2CFA68C45BDFE4717BF97C5FC29FDEE
+:10F63000B13F22DCEDFED885CA33746F2758924E55
+:10F64000722AB84FC829E15F151BF2C026C727757B
+:10F650007A2C7162B9D11A370E9AE538C533AD727A
+:10F660009C9D1AD9535E80F3C87D2D93FC072DEB2A
+:10F670002A58D78D2FCADA06A2C688772ACC630EFD
+:10F68000E3F37816CF39019E6E7C0C4C7FA087ED9A
+:10F69000427E18FB23CF35CB54DE5428C5F1A8CACF
+:10F6A000CBB9329DEB759DE0F7EEE6083FC755D329
+:10F6B000514E7AADC261F503D774D6A31E1DBDCFDE
+:10F6C000E4DFC17F3384DF72A3CDEF9B81E7045178
+:10F6D0008ED8FC44FB39BF02B7F59CDFA6EF293476
+:10F6E0002FFDB70ADD0FF8E924A6E37B081800C058
+:10F6F000F9672D1A18A7B8AEB817F9BCC08371FE08
+:10F70000EF6A37F7BF8FBEFFB907EDE9F1C80440D4
+:10F7100067CF6EFD2EEDD7FEF458411AAEEFC8E468
+:10F72000931E714E9AE247867CAF9F7CF2D5BB60F8
+:10F730009C17B6CBE416ED39583A08CF4F3C52E14E
+:10F740002666F3ED8CD2BEEAFEED465C9FD3D57AF9
+:10F750008107825D2EDE0BE4F181EBDC3CDE3A407A
+:10F760008E5EE7CEEBE167DFD0AA8118C7D81DE235
+:10F77000F7E82ED74F654F3F95E67E0C3F67B61CE6
+:10F7800053F9E1B604C9CDA0A0F320C6C5916EED32
+:10F79000FE5107B703C0CFB9C53D0EF717AAC57E06
+:10F7A0005FA29C2E5F5CB99FA35BE214FE7B225696
+:10F7B0003F277607F6AFE56AF528575C01BF8C71E5
+:10F7C000FFE98A97F079A1869F734B35CECE5A7E9A
+:10F7D000FFE871F47F8A90AEFD943F827E0FF92F8F
+:10F7E000B115088F600BBFFF13ACE1F7F41B9CE170
+:10F7F000F968B73DDC5C598176DC3A87BF14F3DFEA
+:10F8000069AE6C74437E887C7E00F3E3FDE5F20A0A
+:10F81000CCFBF0920BB0661DE4F5008C2373F8EB83
+:10F82000BBC53E81CAB22B61BE2396E492BF304471
+:10F83000F6CF2C46F9B49CDB13BE5DE027F87ACFF7
+:10F84000FF71A13F7D0DA7EF417C37B9B9FFD424EB
+:10F85000E8D4C82F56624D08273C76A99AF157C3C1
+:10F86000F74940AE0D44B99404DF4AF73E635FF8B0
+:10F87000DED58DEF1F1AF8CE0AF5E07BADDBB85769
+:10F880000AE38CBA72FC07193FA799CA9F775D1CDF
+:10F89000898F7074E7015FDB095F016EDF75E34BF1
+:10F8A00006BFD38BFB25DC7EF42973AA91CF5E10B3
+:10F8B0007032D2A7DD224EECB5DEEB0339FE34F612
+:10F8C000EB56ABC5214F2EC77D0DD08FD7045711F6
+:10F8D0004F40B8623C61B152FE1CB6DBE736FCA07B
+:10F8E0006ABA7768C437FE6A7807BAE1FDBFB0FF2D
+:10F8F00059C897B84FC53AF93DD12B84AF714FAB7A
+:10F90000E75E96D6E847F9F83D166E80754CF3CE63
+:10F91000B1DC5732EC037B7F4759ECB8DB1437A9D5
+:10F920007BFFFE3B90BEEFEF92283E3B9BC5547E93
+:10F93000E92A41F777CA73B43209FD1E7D75C56F98
+:10F94000C0EE2F47614876CEDD1568E794A7F37CBB
+:10F95000CEFAD626BC375D8E67EAC92FD8C0CB87D2
+:10F96000F2F2FE580EF97F74467E47F4DD2337E24B
+:10F97000E6B83DC88933585EE0CF2ACFD2707F9079
+:10F98000DF57BC52391117F26187888FD8CB81EECF
+:10F99000CE63FF41DD2E2792C73BFEB7A03323FD88
+:10F9A00042E891EE78C74623DE111EC8E31DE181CF
+:10F9B000667AE98EBB4F4913FB96223EDF6D3758BE
+:10F9C000E5B43D2E6FD0558F9F10E1FEA68DCE0C75
+:10F9D000FFA0487C3BB2DE99B80EE0B563A29BE085
+:10F9E00035BB85D361FEA6652A9A1A869CEFF4F092
+:10F9F000F594087ADCDE5C3E13CFA7664FE7B77458
+:10FA0000DBDC91DCB4BC1E7CCD7747FAA559F1173D
+:10FA1000B3E12F907605F80B7AD32CF0EFA64F8147
+:10FA2000B737459CEB6D11DF2A6291229C4783D347
+:10FA3000D85FE7EF00A4A28394E7C2057E0DF9F238
+:10FA4000A687E3B527E5FAF5A8A85730914DF667E4
+:10FA5000F6F41B49E3F58EA6B1A4E785AF4BE3F2BC
+:10FA6000C9D71025B965ECF7879AB9FE36EA4D4D2E
+:10FA700093849FAEC92467999FD20A31AFC2896C23
+:10FA80008A79DCD962DC0A0F2FB78F7BB331AE9055
+:10FA900097C6B845AD30AE895FA2DDE346C4B85124
+:10FAA00019F93CD4CCDFF9285CC3482F6B9BA31118
+:10FAB000CC1FCDBAA1F061B4E7F38A4BB95D1D61EB
+:10FAC000F80E539598CF1667241FC70B029C304E33
+:10FAD000A7C0BC3175D430F2DF1D5E9DEE8998EC75
+:10FAE000FD2AA2A740727BDF80BB4F65152E93FCD9
+:10FAF0001A2AF062E48D751AF1DBD1FBFC742FEF4A
+:10FB0000965912F1DB8848603B9E1FF842C065E7BA
+:10FB10002EC6FD5B57C78215789EBA89DFDBDE52A1
+:10FB2000CFE31B5B9C9DCFBF86EBDCE024BF69D796
+:10FB30007EEF8CABA0BF7ED17B0EE541BE6DFFDAC0
+:10FB4000E75E83FC5378090FFADBBBEB919968877A
+:10FB50006F5DC9E376467ED03DB9947FACE59119DF
+:10FB6000C3503EEC92E91D85BDB6789E9EC6E379F2
+:10FB70001BD2B85FA2B670BFBB3B9E3785FBDD0EC4
+:10FB80005DC4F396F0F37326386E2038A688E76DCF
+:10FB90004A137A9CB5A679601E7BBD3C9EB7D7FB05
+:10FBA00008D9BF7BBD221E1691693FEBB18ED69955
+:10FBB00057015C1AAA8D785CABE71BB81F95C6E3AA
+:10FBC00069FF80038C33B7E7E72D8346FBF3ADB4C1
+:10FBD000FE8695463C90B77F54B4DF86EDF3FA1865
+:10FBE0005F7B98B7C7789E69FC9FA4F1B8DCEECB29
+:10FBF0008CBF77D7F3594B4DFAEF0931EE0801D797
+:10FC00009107ABCB51D439594758E86FB7F9BCFCD1
+:10FC1000E3CFB475BE0AE54F49D56FCC40BC0DE0CB
+:10FC2000F69C61B719F57E2EE8E91541FF47B6CE7F
+:10FC300065E83F38B60AFF780D237C0FFFC99F2483
+:10FC4000F37C862CE171C7E13FB9EFD51149FCE3A4
+:10FC500057D25C3CAEBB84CFD784E75708CF29FC92
+:10FC6000E30B954B64F8CC4635F238DAA8D6B5C428
+:10FC70006FA3F6E99C8F2F8E25BB6BC8C531F41896
+:10FC800045F0E23594775C9C44F9216D7CBC3DC223
+:10FC9000EE1ADDCCDB3B305E81FB507AA9C56FFDEF
+:10FCA00022AD80BFCB56638FEF7C508FFB60179ED9
+:10FCB000F687CDE7CEECE9368CF398F4F2E3DDFB82
+:10FCC0003C3CCE53608BDF7C21E4953DCE63D41B5E
+:10FCD00026B128B67F6AC3DC4CD6477CC9D8EF353D
+:10FCE000FA1BF6031E67A73FDCB7CD8DD0FDE5619B
+:10FCF0008FFDE9D7B8A7AAE65594211F7F91C6EFDB
+:10FD0000E5DAE33146BF809F2F50DF19F832FC312E
+:10FD1000438E831C6B34CBB1D31ED9F2CE86A12780
+:10FD20000C3936326E9563C3518E493D7A69FB7644
+:10FD300046782E76B55F7815E5D87ABB1CD34B5F35
+:10FD400045FA7A84CBB1D6AD8B24945FFD17D60DDE
+:10FD5000580EE9C867D710FDE57F87EF3F347A7802
+:10FD60001CE8A75BEFA5EF3FAE16F26B09CFEF5D86
+:10FD700059C8F35B65925F763936C0C3E5D8628FA8
+:10FD8000D897D86ADB97B8BC1C5BECE9635FC2D03C
+:10FD9000B3D0A4C2956DA60B1B1C0DBD27F0D93A9C
+:10FDA0009FEB3D23DF3FD68FF4EF1D02FE172A4F56
+:10FDB000907D5212AB1B83F65085FFB46CB69F2F1B
+:10FDC000CB37ED9C6F9E117CE3684FCE2F7778B2D6
+:10FDD00053F04BDFF1D0CBF18926E2C746F91D9EE7
+:10FDE000E47C62D42B117CF2B3FABEE3A1069F1827
+:10FDF000FD95A4E09392E7AC7C7287E7B27C7287B2
+:10FE000027099F80BF4BFC837E99C59F12FEEE524F
+:10FE10008FE18FA5D263420F6CE5F235951EBBD3FF
+:10FE2000C3F5C16A0C968E4BA2878CF629F4D8DDF7
+:10FE30001EAE87EEEFD5DE367E0A3DF65DD1BE16EC
+:10FE4000DB27D383A2BD5D8FFDBD98F7E8A75B0FCD
+:10FE5000E3FE694AFDF58BB6F86B50FE3389CF5F40
+:10FE6000AF93296E36E28925F42E8A5D8FB50A3E5E
+:10FE7000880B3C1FD1418FE13C76CDA3F339861E20
+:10FE80001BF144723D36E209D5539C448FC53D2297
+:10FE9000CEDB5B8FC53D7DC4792F541E253D562C8E
+:10FEA000F458B1D063C5F18E2BD363367E1C69E85C
+:10FEB000B1147CF9A687EF5BF4E6CB170E239D5DAA
+:10FEC00038F8B7D563867F914A8F75F3E715EA3125
+:10FED000A3BFC7DB79FCBB873F63BBADFCB9643C08
+:10FEE000F2E79B424EF7C19F6F7AF27AF36789CAB5
+:10FEF000E33A571AEFB09F3FB9DC796917EB9CFAE8
+:10FF0000309DB38868E926FF0650D96896F76FDA06
+:10FF1000ED7FC3BF12EB4E25EF03E986BC6F24795A
+:10FF20003FAC5BDE3FF7D5E4BDCD4E4A651F05D241
+:10FF3000FF7BE47D20BD6F79DF6D175DA1BC37FAD3
+:10FF40007BBCCD4A4FA3F7013D41D1E36B163D8207
+:10FF500076F1E8FD4BE85E41205D492AEF818E0293
+:10FF60008847837E5CFB741D434420E789BED02F05
+:10FF70005593C879239EF0B83356949E541F548BE2
+:10FF80007D19BDEFF7B8F29DB48F159C184D20DD9B
+:10FF90001F65B1D1D85FAFF7B88687F3F13E6B43E9
+:10FFA00096F16E9EC13FE19D484799D79E6B3F8277
+:10FFB000FB4979A56371BDD7A48BF7836DEF489991
+:10FFC000F8E79A74937EEBD97F6661735C7CED8071
+:10FFD0005B53BD8B352DDD64CF3872F9BB58F6F716
+:10FFE000A91437BFEFAF97B3E26A6F4F3C83158A0E
+:10FFF00038A8886B1AEB710734BA67305BE07780FA
+:020000021000EC
+:100000001C9D4DF035E667BB1FBF5E8AF14797BC6C
+:100010003A2F17F7E5E968184CA2B196BF57B051CF
+:10002000DC8F077891FE52BC617ABFD751C2346C25
+:100030002E95B4935F945E529D8FF7ABD7A5B85FB2
+:10004000FDB09857DD6027CD77C3FB12DDABDB50E9
+:10005000343EDF7CDFDD2578EC68C67877A7899EA3
+:100060001B02A5745EB5C13BB7CF7725BCADFCBE06
+:10007000CC65EB352B96FB2AF65409B366DC875228
+:10008000D4307F97F6948BEC6F9778BF98754AE2DF
+:10009000BD531EE733E62D79AB89EE8CF89E4BF00D
+:1000A000E9B4D2896EFCDEE00ED3F9FE8640DFF2C1
+:1000B000DF85F77672E83CE03AA49743237693DE37
+:1000C000F668D5F45E9C2B0074330ADF8568E7EF91
+:1000D0005E013E700BE3727888A573F9EAF0CBAC51
+:1000E000D824B79CFED67C7CE7D659E864184FF13B
+:1000F00095C9967BEFEB25BE6FE51472C8E8EF1645
+:10010000D15F5CA44813134B917E5F26FA0548D358
+:100110003940EA070A6F5022DBD3F37A7F37DEBF1C
+:10012000115382BF7B2CEF6D19F7DF8CF8E290CD75
+:100130008CE867B8CEE573B15E7F8F4CFE083F2F29
+:100140003B74B3CA90BFA19CFC10A3FDF0B8D3725E
+:100150007E36D46CCD0F15FB9845E2FD2FFA0EFDCF
+:100160000C15FB9E436DDF8D774AB6E18724FB219A
+:10017000F6FDCFC3E919B9B46EDB3B27A9E8C0D8B7
+:10018000E7F4B1C831E2E71ABE8FD03098915EB67D
+:10019000D737E4E6C5D337F4A9874E821E6A349D6B
+:1001A000C3784FE8A193811D198B4ACCFDD5115E10
+:1001B000DFAB7DE7DA338E1E3DE43BFCAE2394419A
+:1001C000E94BFD806EBEB932340649FD9BD5871CD4
+:1001D000E6F73016AE7CF7DA33A6F52FC8BFB5B117
+:1001E00091E842FD02F78F317C89EF9DD13E4D5E53
+:1001F000CF38EB607E678AF0DD06EE1F6F2A72C68D
+:10020000BDF0CF4D5FF2FBB7FA697EBEBDA9763E69
+:10021000D5237908F0CFF5723F3773E53D6E7E5FE9
+:100220002AEAE6F299F3A9D27D3E48E853C1A78AAB
+:1002300010F44726BD4C72A78685E9BC1E3BC1CF92
+:10024000756D3AF42EF19D1D8EADB5FC5CC983F839
+:100250005E06094FAEC7BD46DC5FE86BAFE8BF4145
+:10026000BCA751C312CD8B4DFDAFCDAF7717E4E2E4
+:1002700039C102CBBB632D2AC7CB865AEB39F66F47
+:100280007A0D3BB32342E726BC8CEE1D679685139F
+:10029000888FCC955288DE53047C94C37A32A7743D
+:1002A000925CD894422EFCBBB09F16564B749F6A4A
+:1002B00013C097C3FB88A33FC2FB6BFCFD3E7BBB17
+:1002C0008898C7FF6BF05DED35ECAEBF0D7C07790C
+:1002D000397CD580EE42BBD4CE17AE40DC619603AC
+:1002E000412956E9CDA3F7E6697EEB1DADF9F796F6
+:1002F000A01ED66FA07B12B9D6FAA676B3BDE37A5C
+:10030000B75BDF6D3FCC233E710780BFCCF23F1758
+:10031000F8C824EF7BF8BF9EE3B73097BF136BE3B9
+:10032000DB54F26743C561B706F36BF1CA64677AC1
+:10033000A696B90B4DF35DEEE57184062FB7431F0A
+:100340008C1C761796F42E6FF1CB963894917ABC6C
+:100350002A8D93E9D5049ECE47F03E21DE07443C2A
+:1003600079F30E77E0F9BAA64001C5B52E379F356F
+:100370005EFE9E61AAF918E5A9E6335ECCE71A9CF9
+:10038000CFB8CBCFE74C7AB401F164D877767D282B
+:10039000679475A0DCBB77B053EB6B1FF4642DBB87
+:1003A000B6B088DE796DC3F30EBF68B9616D533E98
+:1003B000DDBFA2FDD827BC4BD7E27EEC7B32DFF756
+:1003C000646A7BDE9C51B8CF73605C5512FA79CFBA
+:1003D000D3FE77B4DF1974FA51BEAE13F6DAEDDF4F
+:1003E000C8A077408C7AAF0AFE582725DF1FDBEFC5
+:1003F00095855C681FC5F7D7A3A3CC710CFB7B5711
+:10040000B72F93AE2D34D1E3C9EE7BB4F10C3C078A
+:10041000D694B7BB28D97C4FA6C5BF4DFA60B0753E
+:10042000BE0B6EE5F305F93F0EDB3F27F8CF98EFE3
+:100430003ADB3BDA467F8F7B8D7D33982FED9BF146
+:10044000DF4FB1CFEF3DA3BDDA9E21E059549504B3
+:100450000EEFA5B5279DDFED383FD33EE1BF0A394A
+:10046000DA33AFF6C17346F59ED701AF1127E3F338
+:10047000233C63FF5FCF207D68E07D5BCB82B5B816
+:100480004F7F52F8B100C73C01C771C9E679D2135A
+:100490004F8AF705DFB0CEF36CAF79C6472583DF0F
+:1004A00015CCB3CF751EC339E7F5D52EF9B8EF6378
+:1004B0003B18F7B75354F21B75F01B8BD09ECDD170
+:1004C000BF6B7E57EA873E1E27F9A18FD3E99F674E
+:1004D000553C54C130DE10A27DE765AF291457CFDB
+:1004E000BF9A25E45C7C877EE876DD0407435FE005
+:1004F000FE33FE408371EE654359B60FE54C57E37A
+:100500007712185FD34FF1F7D553F1EFE70EDD8582
+:10051000F18D8DE59E6566B9E2CFE5F36BCEE2EB3A
+:100520001AEDD56F0EA1BE8BA81A33DDBFA9F25705
+:10053000F3F7C3836137C60B1D2CB26924148EFEFA
+:10054000C53C9FF55DB618FB2AEFB265CF283C8EFF
+:1005500070FFF33185DEB138A7466F9E84F0F4AAB0
+:10056000640734C56F59C52FDB45C7217E33DAB820
+:10057000BFD25CCBC8896CF2960FC930F9B987C677
+:100580007B088F67BF26D1B980B79DB16D2E80CF14
+:10059000B9932EB683CEA3804ECAE6F790285D3875
+:1005A00046A3F72E0025F86EDFEC593756A2FD1D45
+:1005B000CE0819FBDA3E7922C04DBCA7B1718B443D
+:1005C000F87967663AE597B5F17196A11D427C1AF4
+:1005D00073CE379FEF619DD31EC034C0225FC7FB2F
+:1005E0004F6D736662FFB3E7ADA27391B3276AA53F
+:1005F00094563E1895287DCECFF387FCB4FFD29A4F
+:1006000043BF93D05526D17DBA3B2BF9FD96D995A2
+:10061000C7A95ED792256B0720FE277AE81C6D6C70
+:1006200096340CF7CBBF5D09FE3BD45B3C4B2AE410
+:10063000F54F53FD45B3A4028DF29F51FF2FB71E16
+:10064000D98CEA63266BA5733A95AC9AD2B76E5DE6
+:1006500041FDFE7E9287EE310DF3717BD7D3B07DE5
+:10066000193E83B7A879CCCB382FCFB5C561BE8FE3
+:10067000DF7DEFCD796910E331AC7E5C7F23DD78DF
+:1006800014D0E6C0AA93C0C1A800387BE438E52B9B
+:100690007CCFAE6D9C84D61694835E5984E513B1ED
+:1006A0009CE73BF764AC3B3AA9277FA069F8BAA363
+:1006B0000330CFE5CF68DFE41B50FE644EE2F12942
+:1006C00095F17741E0934EEF84C1BFEBC7F7CC6360
+:1006D000A34FEC8F8B7AF0E939ACF7DBF98B37E27B
+:1006E00079CCB3CD8A1FE579E388B04FC5B8782CB3
+:1006F000E243BA7BE8D05D9B26C17A3FD495309A1D
+:100700008099EB6FB999DE03D82EF991EF9775EACE
+:10071000CE8150BEF469A91DF965C5D6CF3AA64170
+:10072000BEAA8DDF83BC35AB88C6ADEA8CDE8C7487
+:10073000B3B44DC9C5F3B24BDDCC87F43E7B9D9479
+:10074000AB43BD2EB5D587EF477D1C3FE4C3F78291
+:10075000CEB637F8B412940B8B89CF3E6475BEC900
+:1007600088EF667E5EA58A71B9C59A951DFC7749AA
+:10077000F87BFFF47B50C037E98D526404E0FDF64E
+:100780002C2E4FCF04A2419403E99B7F7E3FDE8F46
+:10079000EA629CAEF5A8388F887FE3F17781189DD7
+:1007A00077CB6D56A8FD8319BC7D7AB4EF77579649
+:1007B00076F2FEEE7A5A8A6BA1DEE51F54B75F8FA0
+:1007C000EFFC7FBB5D628F68BDCBD37585FCEC6FA2
+:1007D000EFE2FED88A56E847EA5DEFF7526C13CD98
+:1007E000BB0EECEE24E59D306F2C4F7F58DACE9295
+:1007F000CC03B8F368E1787E948A2559476EAB94B0
+:10080000E072C1F65DF8F70007CBBDEEC1B3166F1D
+:1008100046B37570AFDF41E0EF0FF523CCB05EEF6C
+:10082000B0ADDCE5B0DCD7EC27FCFF7EB6FB9A6709
+:100830003FE1EFFDE86532ADB75F1B8F2B9D85145F
+:10084000EF97FD26DFB19BEC90F309EFAD40AFD7FA
+:10085000DFC6F7D9AE0FC5D250AF18EFB4F9867224
+:10086000FD54EE1E73D40FDF6716F27B8AC67E71CD
+:100870006580E7377EA97F8BC7C393DFA3A6F5C842
+:10088000344FA28788B847FD2D41676FD673FFF9B3
+:10089000DC54298EEF60DBEFE3428B71F87B015D66
+:1008A000EBFB67E3B9F373923887F56B4ED7F6FB32
+:1008B000BA77CD92AEC27762A18603FDA265F12C14
+:1008C0007A1F7346B1B55E749744FB3D3768B6EF47
+:1008D000CDEBE89ECFCAF86909E7BD3262BB0F6C69
+:1008E000A78FCBE5C5BB05D3045E8F89F3F0D3C4D6
+:1008F00079F74AF6704536ACA76A3E0BC7199E5782
+:10090000D755CCAF58C8EFF5AE684CB7DEEBF53A2B
+:10091000FABCD7DB6FA1FD9D2B9D997F07CE787721
+:100920006970C53CDA5F09DAE8305FBC533058BC07
+:1009300053907F9FF59EF05BCE8ECAA108FF208F5B
+:1009400037BA03D6DFF3C17D1873FC2AC7C7F72572
+:1009500058BE46FAFBAE6339CC7C1EED2E2FBF2F5E
+:10096000C87639CE9BEF595F38D6F7EFA2A469B6A7
+:100970007BE72C40F16A030EBDE43BC0B2DEA46706
+:100980004C723D2EE47A06D2BF21D797676834EFC8
+:100990000F22914DF8DE2CD322741ED7378DF3C56C
+:1009A0009DA81F417FDEA2B20A359B7E7F89D29B24
+:1009B000453B267E8FE4E5E27CDA1FBAB36DBB8649
+:1009C00071A85EF302DDB6767CD279E9880F9C9738
+:1009D000649A576316E81B05E727ECD94AAE777A85
+:1009E000F59B6FD567A67E5B0D3D2695255DAFCF48
+:1009F00081749B1FA173C857DA2F088D87FBEC37D2
+:100A00001AF13987F6EE17565167C0414E3EDF6E38
+:100A1000FCD8E18078E986C37C8083A95F9F809FB2
+:100A20009D1FCFCE1FBA699C66C52FBF1F9E62BD9A
+:100A300097C1CF049F46FA3A159E8CFAD9467F2972
+:100A4000E6D3288509EEA9F09AAAFDBD3EBE0E7B2D
+:100A50003F57BA0EA7289FDFC73A10CE46FD7E57F4
+:100A60000AD718F08DD21BAE30743BB6BF4BD44BB7
+:100A7000654FF5F83F5564879C15FEB7E1FF9C6D07
+:100A8000E3FE8FE1F7A0BFA3E798FC9F40B50BE51D
+:100A9000C786B202EEFFB4291427F14F9815C43867
+:100AA0008AE1E79CCEE6719D3355FCDD5ABBDF93AE
+:100AB00093C3CB4BFDDCEF59E08DDD3C15E6D595BE
+:100AC0005BEF9434D6CBFF71E14E0CBE3B207E1F12
+:100AD000E6C365399B6EC57A7FA5DF437F80B75536
+:100AE00098C220AB26BA75710FEC3AFCBE448CBBA1
+:100AF000AA93EBAD3F55DEE74420AFF29BDE6F8358
+:100B0000FF96829D82EF382E85FEBB8AC57821B480
+:100B1000230D3F8A9FDB40BF49077B4169BAA51976
+:100B2000CC6BF09B161DF3E1FECC63B78CE3EF2E8C
+:100B300080FD0AF5DFCAE6F7D60F8DBFEA381A47FF
+:100B40005DFFEC60E8DF4C9D50F230F955C7BBF318
+:100B5000E4577DF2AE8BF2AC38B60DCFEB35BD9BD2
+:100B6000467AE093434C477CFEC71617BD3FD8E456
+:100B7000486CC3DF1938F76E06F961E8BFC55C78C9
+:100B80009E1A0401DD47D565F4B3408CF5E3EFA769
+:100B90006BFD79DA4EE9A350AF8B7E402C21F3EF49
+:100BA0001DFD78FD587F9E9EA7F46C1AB75B0CB8AC
+:100BB00057E471BF7B7C9E11276241E4BF2634E27B
+:100BC000D13EB9498E9B7FA7C348DF16F59BB20C77
+:100BD0003B287C1BC2A36A563F19D77722BAD83369
+:100BE0000ECFE5B415C8E8FFCCCDE476CFF18AA1ED
+:100BF000839DD0EFCF1B5DF4DED8071552DC017664
+:100C0000CBE990564FF6DB7A16C6F8C23007D831DA
+:100C100065B8AF2E8575E8FDEC2946F53E68FBE129
+:100C200074B46F3E5425F2ABFE3397FBA113362B01
+:100C3000A71D80E79B274EFDE799D0AEEC6995C6CE
+:100C40007D2AEF86716F61BF4D0AF97F2FE5B9C824
+:100C5000A87DEAD109711C7F178B78F0FCBD1E4F6F
+:100C60007EBEFDE35C3EEF82ED8BC9CF382BE29672
+:100C70000F1D5AFFBA06ED3E6C2D5711541FA2806E
+:100C8000817EEF8C4FDD55074DBC599C7FDE72C6CF
+:100C9000D6A23DAF6F51E8F75C908EF0DEC259717D
+:100CA000DFF6C3B606F28BCEB60C0F235F2D8BD7C3
+:100CB00005D18FD921E0D580FC4B71A37033D2EBE5
+:100CC000B9F563733698E6B923D369ECCF6BDDFBD6
+:100CD000FC48AFC27E1FCC8CBF6EB9C57FD7AC8D30
+:100CE000FB11C13685DE391D1C7725C4BB9496F7F0
+:100CF00044A11EEDDB0D1676FD20163F5486DFEF76
+:100D0000B3DA5B831A79BD812BED7618B7EFFD82DC
+:100D10005FBB443CFC9A73D67A7E61D7FB6D76FD4F
+:100D20004D9952D2F59D6D1C4BBFEB32E851809A24
+:100D3000552EF3F5352B747E24087E4EB277AF071F
+:100D40006F06FF6534D5233BCCBE9EB3E738FDAFBD
+:100D5000D8C3FD34FBBA967F92588B4A66E5D3B66A
+:100D6000DF8FB4CD7F57338F634FF6F27BA0935B59
+:100D7000E5EDE8AF5DC3DA1B70FFD991974BEFF655
+:100D80003785381F65CFA8C834C757F766F278E9AA
+:100D9000D06699454CE314B57A58C464070E6FCBFE
+:100DA000B6E447C4075AEA8FDC5360291FD57E9505
+:100DB000A5FCEA83A596FC98C4644BFDB1C7CA2D77
+:100DC000F9711D332DF527BC33D7929FD4B9C0528A
+:100DD000FF9A738B2CE55F3BBFDC52FE96B80F7415
+:100DE000DDC57B2DDFA7B2EF5BDAED127CE1CA97A0
+:100DF00059DC54CF97CEED53B4C375537DB497638C
+:100E0000A67A71414F59D3E7F569673709FDFA2092
+:100E1000BED33F1CF741F93BFD1BF19D7E17FEBE83
+:100E2000B3466903BED30FDF1F12EFF4674D2F7B6C
+:100E30000CF5FA9F8BF91E3CE03288FBF9E06D93CC
+:100E40007B9B732D233991A9F3DFD98CF9233A9E2B
+:100E50003F70E6CA96DF47F496587F9FD51DC8B607
+:100E6000D8FDBEB28196724F6181F5F7BABC575971
+:100E7000F2FE29A57DFA0D0333B9FDD5C562AF5346
+:100E80005C22BF957E7F24959F5283BEE6B8D4EF47
+:100E9000ED9FC3F7F6357C6FBF3A38D704E74F05AF
+:100EA000FC3FCAE2768DF18EF3996786EFA8273E64
+:100EB000E6EFEDE3B3E6F46E551EC7F707C5D54E72
+:100EC00002A85645F6EE992C27FDBED31949E6BF78
+:100ED000DFF48C6B3BEA8D33C63BFB1B15F1CE3E3A
+:100EE000F7C7C98E0056FAC0CBDFDBFF688B42EF35
+:100EF000EDFF9B88639FF5479D61D33CC15E30FC4D
+:100F0000717A6F7F95C8DBDFD7A77EC1DE59B559EF
+:100F10002239BAAAA7DDFF88F7F5C7E4C957F6BE9C
+:100F20007E1B9783FF8DEFEB13DE3786F9FBFA917B
+:100F3000CD313AEF7653BE427AD0784FDF88E3184E
+:100F4000784915B7F9AAF198FF028688DAD60080A9
+:100F5000000000001F8B080000000000000BED7D6A
+:100F600009585CC7956EDD5E599B0B0D4D83A0B98A
+:100F70002C3648465223A135B2DD4858468E16B469
+:100F8000C45112DB690496D096879738CA9BCCE38C
+:100F90004A208C244060E1043948D32828C11392A8
+:100FA000C17626513C997960693476C6F648B69583
+:100FB00097F8397ED06A3689F7458EE3442F9F3201
+:100FC0007AE754D585BEB7BBE94696679C99513EF2
+:100FD0007F37D555B76E2D67F9EB9C530717210363
+:100FE00037B30919B10A84A410B28E18E4C128429B
+:100FF000F4E426C1DFD7DA8DB48CFF6EC27F775F51
+:1010000083FA82A9F2BDD7D565C2DFA7657D60D915
+:1010100041A4A3A5D9E1DB11D97529CF46C82AFC83
+:101020004122E4D55AA834C3FBEFAD19271642CAB2
+:10103000485B69523121DBB612A7079A94496D06C5
+:1010400002E5D44E8158A1FF5583156BC93C427609
+:1010500034C612E23FBE38A30FBF13455CE4660EF0
+:10106000FDAE6F72FCF05DDB43069FFF7C6120F0FC
+:10107000232176F613C92C7DB23457C079F8BD0709
+:10108000DFB397367EA087716596E986CCF05DFB6D
+:10109000937EF5F05F548651D56FD29AD2047721B2
+:1010A00021974C504827A43BE1674FCB503E5C9CB6
+:1010B000D32624C37E34EA8900FD7A1B3727B8E3A0
+:1010C000E01DFC776FE0F3DD5A42FAF3A7CA23D59F
+:1010D000FA320FB48F29AAB7E4F9BDB75A3412B265
+:1010E0008890B16A639907BE73C49964C92B0CAC2C
+:1010F0001FDAC3DED77EA74C34D0FA3762CBCB449D
+:10110000A0932FEDFD6A148EAB4D205BFBE0792C94
+:10111000A33C2109FA23D7A13DACD71E5823924BFB
+:10112000C85951A0EF29FD9CD48CD7D127B83C8554
+:1011300081DF3BC6DF6B4B73BE9607EB215FD23B73
+:101140004F139C57F217AAA03CE48A71E227C80DFE
+:1011500068BF989206FD5EB34EB6ACCA9EFA8E0783
+:10116000E8069FA76A45D20F8DBA6BEDB4FCDD5A35
+:10117000893E7B6A0BE8F3AF6B9DB4BEB776292D31
+:101180001FCBE87B2506E8E9A32DA44806FA9BD3EC
+:1011900003FDC377934B6D1E3D7C78288394E1BC9F
+:1011A00091A24AE0FB4302A35333D1917ED8F77F4B
+:1011B000C579C06FF5A289F2158C93106857C5697F
+:1011C000E04BA406998C54703A35235DC3F3E12DAE
+:1011D000834623F473ACF5A51417AE67BDD18B74A9
+:1011E000E3E2F4FAF03E28FBD15532D9FF662D8CAC
+:1011F000CBEDD14B1E01FB357827E90CF94C2A17B2
+:1012000070DC6DCD02790ECA6383FF24EA703D9DC8
+:1012100006723A1BC7AB6E9F2C6F1CB0C3F7895D7B
+:101220004CDB184FC817E3DCEB4BA0E84D3E6012D7
+:10123000F077974112611E0251E64B068D308F3ACE
+:1012400057399DCF70B5B5E5416C474AC591026CE1
+:10125000E7166EDE159A7E81FFC8881FFFFD0878AD
+:1012600088AF17DDD7DD7C5FB37A83D3C91651C74A
+:10127000DAEFCBD2E1FA7E95CF05570CF9D6CCC781
+:1012800049526BECA21F5DFF15D28739F03D3369DF
+:10129000A27C0CEB323258C0E689FB9865B826E098
+:1012A000FBD237607FFDE583FEA169F973DF7BFB2D
+:1012B000EBCFF9ED579F189F3C02EB410A4921956E
+:1012C00073FC7D856FB6D33E03FBF943AD5C7FCEE7
+:1012D000C8F84C9CE67B01FCD5C1D64D594FAFA652
+:1012E0007F65FDB21A6192CB09392ECE69940DC883
+:1012F000675B2C127C6718E9BC90AE675C098CAF09
+:101300005BE0CBCBE979349A15BD7613E5D72C4E4B
+:10131000D7C73AF5CE7EA0B32CE05B1DAC7F1ED2C2
+:1013200039EE6DAB81D2AF42CF29E57EF447A6F806
+:1013300020990C88AB80FF1EF5E8A97CCFD2D0A9FC
+:10134000B24F633780E3E03BDE5293E740107A4EC2
+:1013500021FDA20EFAA9007AEF47793AF8F9D5698A
+:1013600048FFE5C4795A0ADC1FA0FBD576E497CF85
+:1013700089CEC3503FA2D9AFB63442E7A5954723E3
+:10138000288F2412521E29FBD72694FF4B5E76F835
+:10139000FDBB5D726B24C3732086CDB7E8349BA67A
+:1013A0004A5EA56C7109C664942B450B911CEB45F4
+:1013B0001BDD47AD1C53F67B67147B4F2BBF9E1480
+:1013C00025F61EDFBF63DD20BF807EEA3A2A2DCBE3
+:1013D000613C75AD3A82EB7374E0904502B93266B8
+:1013E000E8373981AE5EEECBB6603BA04B4A67630F
+:1013F0008DB9961C3FFA4E4B647A00F421D55B23DD
+:101400008D75965CBFFAF4443DA5DF3122B52C639F
+:10141000B4291916A37E867F4CBF2BB842B8899B8E
+:10142000524FCE21AEC8E4649CD1A897CD40478EE0
+:1014300046BD2BDA42F5BAEC4F3F999C6EA11DD503
+:10144000EBB38867A0187ECF78528D1366D5433DE5
+:10145000B44BDFA3C50F240ED74DE472688CCFF3D5
+:101460003363EA76225F3791F8FD0EDFF96C22C311
+:1014700065DA7979C7A4F54B61DF2AF718A878D324
+:10148000CE33C3C3E7E509312FE0F1A824DA8ECECD
+:101490004B3B1FE05053797CE07CAA265A1B8017F7
+:1014A000C8CE26A30ADF68C7DDDD68A038627907E9
+:1014B000EC0FECFFF2565D970453A9237D7AD447D5
+:1014C000F204217F0BE5EED6A49665503F569FAB04
+:1014D00043FA53F6756302DBF76EEC10F0D17872C5
+:1014E0001DC5477F11CFE8ACFE6E03D5C7833D66AF
+:1014F0000F0AE9C156F69D0A8FDE83B8E960BCC8C1
+:10150000D60D96C704EB168BFD80A84B324A89880E
+:10151000AF7E0BE392E1BD910E86AF14BEDD85ED8B
+:1015200082C8DF6F727DA194537B82EBA36D496CFF
+:10153000DC1FBDFAA1C0E8EF5ECA378F727AB3B57F
+:101540005F2CC371EF29D6115C8F54223588D04FA0
+:10155000EA56C66F93EBCFF9AD9AAF692A293F4A95
+:10156000E95B26540E3B787F239E271211273814FF
+:10157000F9BA8FC9D728F81FCAD76D7D46957C4D1B
+:101580002506AF3F6ECDE274A795AF17709DFDF4B1
+:10159000B00D2B72F1A9960BB70FAFB6ABF0686721
+:1015A00022C3A3E38857E310AF2E50E159A5FEF202
+:1015B0001E261702E468E2245E3D9918015EAD160E
+:1015C000D8BEA72585C1AB1ED8F720F31B4F9C1EA4
+:1015D000AF8E87D10F9F345E1D9FD4E3D3E3D577C1
+:1015E00013D578F5D110F23E00AFB633791F295EDE
+:1015F000DD25035ECD9E06AFC2463D877C8D78B566
+:10160000781ABCDAB35148C302C7ABF3E2E4F5D9A8
+:10161000B8CE1A9C5A21D650FE278F38A30CB0EEB4
+:1016200046E26AB90B2AE7FD748BC54DD7E5D6F0C3
+:101630006A0A7C13F73D52BCFAD7897F5E78D5944D
+:10164000F4E9C2ABCAFA2978F537899766845787D7
+:10165000385E7D2C498357EB6F135EED06BC2A85FF
+:10166000C6ABE388578BC3E3D54AC4AB422478D5D5
+:1016700079DE1FAFAE48FACF8557DF4D9C1EAFEE27
+:101680000871DEFE79A244E96812AF76F2F336A75C
+:10169000EB4A4E77B62626EFE93FF8AE5914BB0E5B
+:1016A00043FFD787463D75503624D98AF4D0D56E8E
+:1016B000A44B9403C58201F99893D9148ED5B977B8
+:1016C000A31E32883261F2C645105FED4E246C1CB9
+:1016D00051B1F53E2B21BFD85A49E5D1D346A6A733
+:1016E0007E21BA2D497E72E4EB5C3F3D1D0FF588EB
+:1016F00087ED6E4B113C2DB1F253E5749C4E1D7E6F
+:10170000BF2A9AAD97F2DEB3490C47260070B85055
+:1017100048C598059029E0A65C0BE2B9B78C520B3E
+:10172000E2C9B1D7F4CE53F09E370EF4A31FDF7693
+:101730006BF4E22B7CDFB11DE2979506C9108CCFCC
+:101740005745E955B846C107F83EF1E3FB951DB989
+:10175000A5389E55C4598FFD68DF3B688005433D21
+:10176000B025D6735A08FCCEC1B895CF25A5507BBD
+:101770005A755F10B9FB333E7EAD5E30225D00DDF1
+:10178000D7551377542EFEF89088FC03F53AD4030E
+:101790006FAD94BF82EBEA15195E50FAFB395FCF4B
+:1017A00080F51099BC8B783DA2A6978F93FDF276B9
+:1017B000DA757A3649528D43DB3FB10F521CFF95E3
+:1017C00038033D9F9033C66B93F2C6CFFE09A73313
+:1017D000AACFDE5EBBCA80FB53AAB16F6AEDA4DA62
+:1017E000F2C92446C70A3D849D0F6FB7CAE08C6CCE
+:1017F0009D0C11AE93E1D6D62952FE1B8F90FF1E91
+:101800008D56F3BFD1CADE9BE23F91F2DD507B647F
+:10181000FCF75C72087AFBF4F05F8C75D114FF1151
+:101820007BAB09F1983EBEDD561187F4A153C90F79
+:10183000E549BA811E95EF003DF6231D2D62785FC4
+:10184000827E2E737D7E9F3EEEB1B3F0FDDFBA56F1
+:10185000585157952CD9E3B80CFD5EB2323D2EEAB3
+:10186000DD2763A19EFC6F33C1F18D0CB8F3FDD76A
+:10187000AF80AF3FCCC0A65B0AEDCDA486D96FFB8D
+:10188000059D1DF61F0E00717E7ABDC0CA713069BC
+:10189000B5E9A8F1FF8280EF69DB2938A398CB93E3
+:1018A00062AE5FC805830A07CFE7FAC74604AA8F6E
+:1018B00077BFC37042EA56359E98FF2AB323287833
+:1018C00061BE1647707DA5C50DA9F87FE8B932CE77
+:1018D00083B8418B139AA4BEF3E950DFB495385115
+:1018E000CFEEE97B4C403A586905BC8087638E1780
+:1018F000609D9DFDB8CE303E5C6731B73F0AED6B11
+:10190000E2F7F4A29C8DF8E57B9672D88F2B836664
+:101910006AFF5670C20F819E0C7710D20738C00044
+:10192000E517010760F9478003B0FC63C001F83C8C
+:101930000338009F2F030EC0FA9F010EC0F23FD460
+:10194000BA68B9BFB68C961FB6329C27C6963B9C28
+:10195000F09D81673FFFC8D7D1EE5F12E734C3F82F
+:10196000877EEACE9A4ECEC03E1BD9BEF51B71DFF4
+:101970009A57C6547BFCFC2BBEA65C1D9E572F3786
+:101980006D4ED806BF3F691582D2A7F6BCEAAB669A
+:10199000E7CD982283EABCFAB8D548C73B38795ED0
+:1019A0007D3C68FD6808FFCA79EBE479F5BCD5EFAA
+:1019B000BCAA8CF74A379CAFF11CD73DB3F3F59521
+:1019C000C9F3F539D5781AF9782626C7FB62D0FA1B
+:1019D000AB21C67B18C79B42C77B18F93EDCF97A5E
+:1019E0001B3F5F6F4C0E73BE6E0C7EBECEE6F22FB9
+:1019F000D4F9DAF7EFEC0FF245E80F3A6F559FAFE5
+:101A0000DD919EAFE5999DAF777686F1073DCFFCDE
+:101A100041A3E1FC41DD1BF7A74B6426FE207714B0
+:101A2000FA83AA43F98318AE0ACDB7C1FD4191EA02
+:101A3000E75F5B23D3CF3B34F838503F337CFC4126
+:101A400092487F1FEC647A3A9CFD701BA73BEDBC6B
+:101A500002EC8721E8FC454EE75AFB61355F5F9B4E
+:101A6000E762192A9B2AB41F52B9EF6C407D1DCA48
+:101A70007EA8D8EB43DA0FBB9F4844BA0A653FAC57
+:101A80006CBD35FBA10EFD0111D80F23DD573B5F67
+:101A90009770FBBA3BECB9A786EEE3FE24661F1EE7
+:101AA000EDCDA5FBAC8CB39A8F33CB13DC7EF34D1D
+:101AB0002B3FE7FD99D86FEE4956EB77ADFDA62297
+:101AC00004BDDEB2FDA69E9F97F97A0E6BFA57D63B
+:101AD0002FAB5DA076FDFCE47F3EC4EC3755D47E91
+:101AE0003312C67E33C1F7772099C9D149FB4D9F88
+:101AF0009EE2968F6BBF71B74EEF6FF4717FE3304C
+:101B0000DA6F84F0F69BE141B3C95E1CB9FDE6C90A
+:101B1000E4C8EC37E1E21FFEBDEC374368BF298E15
+:101B2000DC7E73DE3ABDFD667B08FDF863ABA4B6D0
+:101B3000DF7430FD18EABCFE56A8F3D3BFF179DD9F
+:101B400088E35E14BA7F852F153BB28DDB91E9BF28
+:101B500069EC4F1F5AC3DA9F3EB406B13F7D08B20D
+:101B60007726FAF5B508E5707558FD2A5139ACE8C5
+:101B700057AF87C9E14FABFD20DCBE0D3CFB13C75F
+:101B800020B4CB37F59DB401FD57BF1B4D4EC1941A
+:101B90008593AFD2DF273E80F38ADFF7F529D9CAD4
+:101BA000F9D2C2CF97163CA74869200C9710623231
+:101BB0005EA8C1FD1E2F8EA33863FCC6D7B661B9DF
+:101BC000AA338AA0DDB8EAFAE71FC132693753DCCD
+:101BD000D6DDBAED02E282B16EBDA087B2294152D4
+:101BE000D1FB7877A588FB5A347FDD1B77E161F55F
+:101BF0007FEAC81DD0444860F31A2A7FD881FE913D
+:101C0000CFCECF5C5809ED3E4C66FAD16367E30155
+:101C100004F416BE07F89C1C86D20F1B1F33E1FE8E
+:101C2000CD3FB1DF84EBD4E719A04FE70B15F4F7F4
+:101C3000A2E35DB4FC528F40E271DC1D7A0FC9A6AD
+:101C40007CAD47BEAEE4F4B9B0AD8DB613BBDBCE10
+:101C5000A39C7CB45790F07CB7E4EC667A5EF59D6B
+:101C600010C80168E7131E5FB802E5CA0FCC12CE98
+:101C7000D79141C88A05F05EA740D05EBCAD437FD6
+:101C8000CA9C4DDB35A03C95BBF404E58F238F182F
+:101C9000B01DFE33005D7E85F3D555E1806539B614
+:101CA000FB475D1FCA653FFFB80EE5CF573A98DF87
+:101CB0009C9C31CA0C0F35EEBF09EB33FF8C3ADE2A
+:101CC000B1A85F5D5EF8AABABCE882BABCE497EA44
+:101CD000F2FB09DC1F44D87762A20401BF533235FE
+:101CE0001EAA57DE4F20749F0E66CB8FE0F97B65EE
+:101CF00054D13911C65FD02D52FE2F15379626428A
+:101D0000794E2F2B5FB6B07E0BED175F4113F33C7E
+:101D1000E98395685A7116249EC5E70267D12A6443
+:101D2000FDE2A51BCFE2D3676174B0D8F5D8AA64F1
+:101D3000F65947F95CD007D1EC7BA78A44C7263F08
+:101D4000FA6D486172602891C989256799FF7DF015
+:101D5000D9FC5307A8BDF05FA91CB3F273DF0B7663
+:101D6000D67EACA0C684EB3FDB2359D02434B8CE5A
+:101D7000B415F1C2A0A073D1B88067CD5D68BF81F2
+:101D800032D5B3B08FA74E33DD41FDF87BE90E416C
+:101D90003FF04E02D48F1ED69F42FE18E6E74EAFAC
+:101DA000E83239FDC6B9834CAEB71ED7712F2F0369
+:101DB00055F7DF14A6E8622FA78BBDAD02DDF7BD96
+:101DC000C46F9FE0BD028F4115077B578F7A1FE7D5
+:101DD000F6A9CBB79B4E7E6DE774229377307E25B4
+:101DE0008B108633A54101E57816D78B8E46663F6A
+:101DF000727C431BCFA1B5DFB2B81489F7B36C5026
+:101E0000DD5EE27A55D2C4751C9CED76A09C1F89DC
+:101E100066F23F1C1D1E4B617A29523A5C525AA150
+:101E2000A7F4579345F5888293BF7B8DEDB76C3748
+:101E300052FB63B3C17D7836D05BB3DD582CB3263B
+:101E4000A5D150BFB658101147D9E07CD6BF9090AD
+:101E5000D74F6C6F5A03E5D55FD095239DADCE76F5
+:101E600047235D45494E8CBC25CD7F62F4ED173F7D
+:101E7000A3BBB9648ADE6C9CDE6C9C1E5C3C5EFA83
+:101E8000434ECF9F74BCF46FCB7C82268E6946F1A3
+:101E9000D24A1CB4122FBD0BE3A5A17E0D910D58A3
+:101EA000DEFE10E04B78657BCFED8D9356E2B46F8C
+:101EB00057BCB4CFC2700230AE03E97D0361F14B71
+:101EC000F0ECC7E7FF32B9E217A1FDFCB0DE790AFA
+:101ED000EA363C5424E1F77370CB40FE6F58FBD9CF
+:101EE000325C87E1F21367F17C105370A11AE5CDE3
+:101EF000D2E21882FAB29BD4E4A09C5A412EE85157
+:101F00000E5C41FD0CDFBB875CA3E55F3E104BF12F
+:101F1000574547769799CA37B709E5239C9F5CF4E4
+:101F2000BC62709BB6CEA5E391091DD7E0AAAFE3D2
+:101F30003383B83E87DFEFD8F8007E7FC396BD7449
+:101F40003F362C9516D067D99172019EDBD70A795E
+:101F50002401CB2F88ECF70111C7FF5CDCB6863477
+:101F6000D8A7CB2BA2E8B96643D9455ABFBD0C040C
+:101F700024B4BF5C5545EBE5A5314ED4E77BD60ACA
+:101F80007792F9B0CF658003697F43B47DE55A212C
+:101F9000479A8FE50F68BFEB44F7EBD09CAC5DF33D
+:101FA0001D03D2F7A5077737A09F797C59CC02246F
+:101FB000A7785B0E9D7FCC4B5D3D704C23954D5DAE
+:101FC000D236E01FCB2A86F3B6F3FE361B48A901B2
+:101FD000E6B996B02721CC4F70BEC0DE7518D66921
+:101FE0007B077BCF8F5E4D3767E1E6114A2F06CE28
+:101FF0005F317AD87DD8E24E3B7195020E8AD17955
+:1020000068F9990ECB91FA34E07D1DD43B09B93FB4
+:102010000DEAED58CFCA5F5BB7B9E9DCB2A9F2337C
+:10202000278EF132A1E7CB79C77FB816E3C61296A7
+:102030009172DC2703E76318924CE53FBC43FCE256
+:10204000C39A791C6B2C8CAF3589FEEE8A87FD8B89
+:102050008581DA16D0DFE58405F4F7FE38FE34E238
+:10206000138E4B369C7F21EB3F86C81ED4E3A4C061
+:10207000DD8CE7C1FAE37A11D783B8440BD22F7114
+:10208000CB16A49FA3033B9B916E475D062742E6B8
+:1020900084E34FACA7CE846641BC03C65739E8A49D
+:1020A000B868778FD087431C3178CEA74379A2B523
+:1020B00044C2F35666EA1D540E550DD6D0F776F796
+:1020C000E893D14EBC3BCA1D8F71971B8E09C9D8AE
+:1020D0006EA2A9C842FDDBC4F326FA99269AF554EC
+:1020E0004E8E1281DA2DABB00ABFDB04FA96D237DE
+:1020F0008B378CC53502528805BD381BE8283D95C5
+:10210000E1F8B10C99EA8158CF4FBE86F47B99BFB4
+:102110000FE73E2A9FE93F781F8F0BC83FC94D7AD2
+:10212000D76CA0BB0D362637770F12C2F0ACE0C1DA
+:1021300038B8D872AD5CAC596D413C8B764A1867A3
+:1021400055EB4601F1EB985176208E1ECB66FA3E98
+:10215000502E8A1633E2EFCEC46C5CEF076D4CFF55
+:10216000EC682D7AA318BFF7247122DD57F754D0FD
+:10217000B8C3DD76A3D305E571818D47EE12E8F88B
+:10218000635D061A3F3912C5E879DC2374A1FF6349
+:102190004268A5EB27CF35507C09DC7E2E6F317D60
+:1021A00095FE4BF608FDC85FC9DCFE00F352C9B1CD
+:1021B000CC00BF2AD3C354CFC0C0766D51B7B7711E
+:1021C0003D6CD3E8E1D73BEAF469D0FE00F229AEDA
+:1021D00067AF90580A8358D6AEA7FC7B30D11D8FCD
+:1021E000E583877293EAA06CB132BE35A5BD43CFBB
+:1021F000153F2F2ED4A1DDDA64ACA1E70AD3890202
+:102200001DE2A8E74CEEF68D28479FD351390A838B
+:10221000FA2AD2E7EAE3561DE2FE83D96ECB25DC2B
+:1022200097346312D6FBD6080D22C899ADEEB6FBE3
+:102230006CC9680E4EA47ABF84E3159F515A49E9D0
+:10224000E21071225DC168E56AE0939CB2EC03384C
+:102250002FCBF2A56B5CF05ECE7A1DC1F16C409D78
+:1022600003FC9417BF49876B72A7B1261DE9E7707D
+:102270002A3B2FE5BC77FFAB02E2F21B1F16221FA1
+:102280006DCA91B7E3BC66ED3D97783FF67328AF12
+:1022900008E7DF6CB81025AAE92322BDAEE001ED06
+:1022A000F9302F95D1ED8EB5C21C01E4DEDB0718A5
+:1022B000DE1D29113C78CE2BEF1464FD3C2AFE165E
+:1022C00055203F9F484DC2F55AB7C2A8A2EBF2CEA7
+:1022D000A72FA0DE1B11A436DC1FF9353DB50B6915
+:1022E0007103FAAF703D7774262E403E25057EFDC2
+:1022F00004C1037B3A87049CCF1E97B69F30B84138
+:102300005BE6F8321C8EA8E6F7AE141CB193E388A6
+:102310009D9E5826DBC9ADE108053768F1427E5124
+:10232000EE5133BCAF8F3A7B8F6FE1D4BED471DCFA
+:10233000FFCD5AF91EF41B76D436D2E7FB9CEFEFA3
+:10234000D7BB7E6DA3B8C169477AF119CBCB4B706F
+:10235000DD0F0A74DD55717B12FB1EB59BE3337BE9
+:10236000AA4CE343B3F1FBE7E9F7537B2B4AF07C3C
+:102370009ABA150D1E84A479F6D3729A5BA2F49FC3
+:10238000BA15C6E3B7EF696E1897DF3C0F2606A7AC
+:10239000B39654C637CA394F5BBF9ED7E736EA8833
+:1023A000CBAFBF3B5A6388CBEF7BF91D49AAF26CD8
+:1023B0004FBAAAFD5D3D39AAFAB97D7354F5F3CF42
+:1023C0002C50958BFA97ABDA2F7C75A5AABCE8C286
+:1023D00003AAF64B7EB949555E36F84555FBCF8CBE
+:1023E0006D53D5DF7D6D97AAFEDEEB8FABCA25E47A
+:1023F0002F54ED43DD9F5B630B1EF75D7FF7EF2EE0
+:10240000E0C1F672871E353EB9DCB490DE4B10DBBE
+:102410000411C9DE6593E87BE342FF2384C60139DA
+:10242000A99EFEA4E3C557D985A0F1E23B383DDA69
+:102430003A99BF672A5E5C9E365E7C375FA390FE4A
+:102440009EDEE9E3C5AB6F315EFCBBB87E7E71B04A
+:10245000A1FC3DE1CE75DFED788BCE77F5A29554EA
+:102460001F28EBA49CE794F2ED3ECF6DE2FBB00B8E
+:10247000E57BC2947CF7A17C87FAF21E90EFB85EF0
+:102480005CBE5F793E847CEF01F93E0FED5020DFAA
+:102490008BC3CBF75D3D4CBE873B273A487F437AE1
+:1024A000F6ED90EFB778AFB649A0B61C07BFE7A32B
+:1024B000E883CA46B5BCFF36E723452F7F7BCF2B89
+:1024C000D1F97E7AD94BA496D9B8DF1D3A42E52FCF
+:1024D00071523B93B2AF1FDA047EEFC31583E77BE3
+:1024E000D9C3D64FCB37857CBF72BA2A699C90720C
+:1024F0003FE8E8C06C6AD7F3B5AE3444C37B3E3CDA
+:1025000060E039D753D2BD1F5EB992CAE21A2E9944
+:102510003C47685CED737AE9345B26D326E0F7111B
+:10252000C2FCF857BA1E73A0DFDBD75149EF237DF9
+:102530009FE35E6F07FB0E31482DCB50CF772DB454
+:102540001EF61B5F6FAA9EE163E26E59CA70B0FA75
+:102550003E12C78BCAFDA3807B3B1D7A19CFC30EE9
+:10256000B43FC233B3D3DC4F82DCDF8176D4CEA359
+:10257000DC4F0A792FA99DDDEFB9DDF792FE0F5FE1
+:102580008F9131B6BE7B7A01C7FB9D1B94F98EB447
+:10259000BF74DE02EB34AB4D20A21464BE9A7B4ABA
+:1025A000578C7D26A49B80F9F27B4A99BD0C5F6B0A
+:1025B000E719704FA94F6D3FD08EDFDB58C9E3FE9E
+:1025C000257A0EEB6EDC42F7536ED753BBB8F6DEBE
+:1025D000D267485F1DE2491A8FBE1CF7F1B523E8A8
+:1025E0006F3A887306FDF307DBF78EC82BE8798E08
+:1025F000EA155FAB8E20FD793B56AD477CEDF508C3
+:10260000229ECB5EF6ECA7E7302D3D2BEBEFF3D40B
+:10261000A9EEBFFD3F8E3B473CFCFE9B6795EAFE63
+:10262000DB1F39BDF9887C6BF7DFC2DD1353EEBFCA
+:1026300079C2DC7F8B90CE7C33A4B3213E7FEDBC8E
+:10264000C6C6E4F5F4FC86F7DF82D1552B9F576BA5
+:1026500098FB6FADA1EEBFD504BDFFB663A29FDEB0
+:102660007FDBD33B3D7D0D61401EECCB40F3D3DCE3
+:102670002F246BFC42658E41DCEF0FD4716CDFB010
+:1026800047E6179AE07EA109EE17DAC1FD423BAE9C
+:102690002F617EA1268D5FA88FF9853A5225951F5F
+:1026A0006BA28FF9857EC37153059192D05FAC8D7B
+:1026B0000FB0D547E6872C4A0DEB872C4A0DE287F1
+:1026C0002CC2F54A098FB794B8FCB078AB2938DE34
+:1026D000FA1FDC6E1BEE7EDEAE49BCD53A6D7C8DFA
+:1026E00072BF2024DEEA9C1E6FEDEC51C76F458A55
+:1026F000B7B6F17D0C87B716DB357E3C253F035F0F
+:10270000475B5F64F71BBEACF81F42EFEB97ED8BA6
+:1027100002F7F5CB7612D49E96CFF122E273B49BEA
+:102720002976B500FB1CBC7F60F1949D50A907B0D1
+:10273000D786F5F339DEF805B433E279BC5EEFD91C
+:102740004FDF73D1F35EA4FDC1FF6DC57A271F175C
+:10275000F667489EEAAF3E4DB6187383F427A10D85
+:1027600026687F1EACFF05D41BFCC725C1B8E6E276
+:1027700077B83D7BABCCEC8101FED517987FF50790
+:1027800003F4D9D7D7459FCEE7DB987FF534F3BF65
+:10279000BED4F918F58BBABBCD120D1ED2F857C7AF
+:1027A000850556E60F1528DE123DFBA93DB1A25561
+:1027B00090501D2C396B35A1FD78EC10F3B38A8D48
+:1027C0001B4D2897B6B5BF40FDF3577BF5241EEA95
+:1027D0005F68D47BD016A8F85DC7051DA1711E8760
+:1027E000987F2E949F35C0AFDAC870CDC7F5AB8EF9
+:1027F000093A7AEE0FE7377B2A2532FFEA53298C14
+:102800004E238D83B8C2F167B83888CAB0F7005C30
+:10281000AA38085F536471864A7C485839D81B3CF3
+:10282000CE707D5A64E7CEEAC9384371DA736755D2
+:102830003839D83ABD1CACF0DC9A1CEC4991228A9C
+:10284000330CE05B58EE86E07285D6FF8D9DF72B4A
+:10285000BAE3057FFB7DB948F1A2D21EBAD9AFF425
+:10286000A70B2E57A81CC84D63F415E93874589F60
+:102870001DE4FBDC7F30293FCA64D5786CCA7BFE3F
+:10288000F4AD9F9ACFC856ABC544F75B2D1F939408
+:10289000F168DE5B92C6DEAB17DC2D8B84C0F94796
+:1028A0003A8F623EFFC97870659F1A23C315A060F6
+:1028B000C2E10A9216045710FC6E4AF879966ADA59
+:1028C0005942ACA3A21F701D0D685712E4163DFCBF
+:1028D0006EA9230528E777E8639C682F485AE373BD
+:1028E000A29CFD5D7D7E0EDA31ACEBB6D07B069707
+:1028F000D219FE181298DCB0CF27FD68BF18AACFF6
+:10290000ED423E3F5CCBE290CCD7EF2232C8A1260D
+:1029100028CBC0CFE68C1A33BF0F40E324BDF52C83
+:102920002E5F5CD2E9C07BF17F30CA66B47B3CEE9F
+:10293000E0F7E62B4C5B715D957B0FCA3A9DCA6050
+:10294000F52B3318FFEF8D13793CF729135D16979C
+:1029500041C2F515B81CC0FC3E02DE8F23E574BFF2
+:102960007C3F3AB6FE4BB81F53F7A5C9CDD840F906
+:10297000A23CB5F1DCF49F6297838FC42E8D627602
+:10298000F31BD0DA4F6FC50E323BF9EFCADE3121AF
+:1029900011C58A06E2F5C3DB7B9B847E1EA741BC82
+:1029A00005FC7B78AE03798AE702394E47E325E3DD
+:1029B0003B04222F04A8737A73E35209EF296D3B7D
+:1029C0009506F3361EDCBC88DE0737781AD09F7672
+:1029D0002989C55F26C54B6D28F79EB86824E8EFA6
+:1029E00019589C4E717AC9928C9366C4DDBF32131C
+:1029F000F4FF962C799DDE37F2FE2A9A961B619F92
+:102A0000DCB0580DF0F4601CD9807B3ECACB67A1C6
+:102A1000ECBD03FE7BCDBD84F923641DE279E55E48
+:102A2000D1B3A61A1AAF38BA85C886F974D153192A
+:102A3000EEEFE34F6264ED2FD8D8D39D8ACF371DD8
+:102A4000CA39E11A2D8FDED81C85FB7FF0869EDA0D
+:102A50002FCE25EB283F4D2CBDF394996E6639D5CA
+:102A600047DB785CDE7589D1E1667D7FCB52F4FB74
+:102A7000FD0D8B97FAA877E1BF2CA79F657E9F235A
+:102A8000C77375340F4EF9BA37ACD0EED837241D62
+:102A900076575D26344809182FCAE8B51BE347CDA1
+:102AA000182F2AF278513B8F1765F1A3BD183F6AA2
+:102AB000C67B424E5AEEC3F85133DE1372D1F28F09
+:102AC0006ACB68F9C7B5E5B47CA6762B7DBE5CEB16
+:102AD000A6CF9FD556D3FA7FA8ADA1E5FEDA7DB487
+:102AE0007C436274BCEA506933DA8B76C1F91D719C
+:102AF0004DFEF30241FDB973A989E607D9693F602C
+:102B0000C27D268551D44FBEFE82BB311BCBDDC2B8
+:102B1000422C8FFE9A9C41BFCECE2D7A1A875455F7
+:102B200068EAC2FB4183F70967D01E58D5FEC4FB93
+:102B300078FF88141AE8FBC4491CFBA0DC52B2C51C
+:102B40008978ED9451D25B8B00579F7C784314AC0D
+:102B500071AC89D42539A1EC207219D0EDC2E20FF5
+:102B600076BD08E5D733171F8D827E634B8A5FB130
+:102B7000D2F2480B96F3E257C6535F34196939070E
+:102B8000CF23C2A0211EEB4F90E6E4D900137112AF
+:102B9000CBB17C20A12E0FC74FA8DD212E6BA40541
+:102BA000E3A7E788175F4914F17BACFF42FB072BD3
+:102BB000D9F759799E947836C9AFDE5950B4CA0A0C
+:102BC000E507C9E2A365D0B5CB5DF2461EB4FF4C64
+:102BD000A7AEB991047EEF9D9C6B0348FFA32D84A3
+:102BE000DE4FC470315C278B9CEFA91342F3FFD0FA
+:102BF0003242EDA64AB9C558F308D2FB50347B2ABD
+:102C0000BFE76531F92E6530BCD612CDFA1FFD9CA9
+:102C10008EDA5FB5FDEAB259FB9644D60FD0F717AE
+:102C2000687CC6169B0EF5C73BE5953148BF751D00
+:102C3000393AD41F07D2199D5C2CCDCD34C1BEFFCB
+:102C4000A4DE2CE179F872A9E031C2FE0E654B07D3
+:102C5000FCFD94771A65239ED7EF1404A70CBD8F53
+:102C6000BE473C46A08FCB9DC7EEC3DFC70C821387
+:102C7000C5D9B559D9B4DF251EFD9011E6B97E69D5
+:102C8000C91B0F407D71AF817EF7FB29F72F427F73
+:102C9000A9DCAC77821820FF9862A6F3FAFE697867
+:102CA00023DBCFCE591FDCCE199FC1F834E7E07784
+:102CB000A89DF34A9C8ECAFDA303696F4AC581761D
+:102CC000CE8A1E66E7CC7228764EB101ED6F728314
+:102CD0005EA2F65683C7B409F4F790626FAAFF4E5E
+:102CE00003FAAD86DAF3693CF9AE9E2E07EA19EFD6
+:102CF0002CF6DDBA7AC5DEE92C43BFF795430BAD60
+:102D000087FDF4AE779689DFAB9CA19DB39EDB6710
+:102D1000EA997D26B3C7DC4FE3D7881A9767D47347
+:102D2000BB5F383B675364F6272FF1D4D1F5A82257
+:102D3000543F446A87FA4B4E3FDA790EEDD942EDA3
+:102D40002DB34E08ECFCA59D67B8FC529DDC9ED9C6
+:102D500018DC0E3554C5F6B5AA9BD957B5F3DB3947
+:102D6000E16C401056D93ABD3D6A321F539C2EA8E3
+:102D70005DD398926C42DCD492ADE64BE5F952D625
+:102D80007FF91DB17CC9C4FD3A6F05E7D7AB9C6FD5
+:102D9000CC761DF1F8F56389ADA1E7C2783816CA83
+:102DA0007EFD454B3AE2F66BF736C78789F76D999A
+:102DB000F69ECF41AE778FF07B1B4F73BDDB8C7AD5
+:102DC00017E8EE10EA5D78D6F17B1B47B9DE857E09
+:102DD0008F633CD24705D4FC432AE28803ED1CA054
+:102DE000F5903D48CA3D84CAA70459A0F1DA6ED1D6
+:102DF00025E379D494ACBE87145718A32A476524D9
+:102E0000A9CE8596E274557D4C5E8EAADE103747BA
+:102E10005516572C509F2B498648EF2D11861B3F86
+:102E20005A5B7AB414FBAD131C887306B9DF5FC11B
+:102E3000CF8372A4F83989E2E72199C93571C95A5B
+:102E400007DE7BD5E2675F058B4BD6E2E71D994C29
+:102E5000AE9A33993CF822E2676906F8B9FA9836D7
+:102E60003FE62DE1677ACE858FD834F8598963B073
+:102E700069F0B34D8B9F7B013FCFBB25FC1C336BAF
+:102E80001AFC3CB078CE45A49F2B6F1809E2CE9275
+:102E90002585144F8F5D54CABD27CD14379B6979A2
+:102EA000ECA70088A1FCD41C9307F7CF3BC0CABF96
+:102EB0006F30D3F261A374320ECAA3BF8AA77673B0
+:102EC0002DCE86DD36309CACDCD357E367057F43DF
+:102ED0003B1DB7A7AB70B4829FB578E4A95C26EF21
+:102EE000E666E814B94FFD948711971487C625F755
+:102EF000E6B0F70E232EA1E7D0E971C9312E2FB429
+:102F0000B8C48BB8647E785CE2E3B8C4DB7A8CC664
+:102F10005F8D232E817E3F52704937E09279B71F33
+:102F200097FC71D60C714937C3256F6532FE0AC410
+:102F300025AD2A5C327CBAEB118C3BF5D55BA93F01
+:102F4000CC17211EF1FDD9E19199F9C35AF83A68DD
+:102F5000E737D4B499E19036E1D670486B181C82FB
+:102F60007E5EE87F8F27380EA99EF050BFD8AEBE98
+:102F700008F34286C12187B319FF609C4F851F5F0C
+:102F8000FE3789F1E37F741CA2E451098747466646
+:102F9000313DF45F78637ABCF1360673A484C71DB3
+:102FA0006BD299BFCC4BC437912EBF348BDF4FE42B
+:102FB000E570F9947E8AB1EDC89F7627BD97635579
+:102FC000DAAD35A8DA7D1F85DBA2C0FB784E1C2761
+:102FD000FC7EB9FC8403F95AB98FA76DB76A56F025
+:102FE0007603A7FF89DAABF24DFD2769FCE8A4BFA1
+:102FF000F99735C86F5716C5E950EF5EF980C5FDE2
+:10300000FEFE44940EED5C2663EB23587FB53B9F98
+:10301000C601F74DDA97D47EE8EED617DFAC857699
+:10302000439D02D5533BAE9BE9FD07537C9F251181
+:103030009E65B3D83A2BFEEAABBDCCBF3C70FA7E9E
+:10304000EE0777513FB8765C5E1C17EA3D1C57715E
+:10305000E0B886715C503EEDC8E6F25D3BAE4D34A3
+:10306000EFC5502F1BD7EEC971955B12D14FC4D756
+:103070005519D7703B1B9772DE09778FC99A1ED9F5
+:103080007D3A2BA733ED7D26459E85FBCE1DB3668D
+:10309000765FEA4E4E07DA7B7BCF9934F61A2789A2
+:1030A0005ABA00F89FAFC33B398CEF460F98298E70
+:1030B000B14883E4F1C2A97C33831D2CDF8CE27715
+:1030C0000A2517B4F9660627F3CD3CA9CAD7FA60DA
+:1030D00006CF7F33F9F7070EA8F2CD28F56321F26A
+:1030E000CD6CCD98CC37B3356351E4F95CED7709FD
+:1030F000AA7BB091E673BD365B98369FAB37C4FDB3
+:10310000FB36E142013E6FF7BD7A6F987BF58A1F6F
+:10311000CEC71D23C73282DFAB57EED12793A268FB
+:10312000C4F98FEE314A1E69EA5EBD36BF8C365F48
+:1031300042DC9F58FECA2B3CFF8136BF8C721F3F7A
+:103140008594AF46BF7265398B0BBF12268FAB36A5
+:103150000F4230BFC4747F7720885F6246795C5B22
+:10316000B8FFE78873253D1F2AF97C02F38E653886
+:103170002E039D55CD65F92744BD783216198FE78A
+:103180001D1BC2BC637E74FD528682D722CB3BF6E8
+:10319000D5B97ADEFED6F28A6D7F87E5AFB8DD79E4
+:1031A000C5DC21F38AB9E9BD3125AF985B6679C5E5
+:1031B000DEC850E7B1089957EC5B2CAFD8F08D25ED
+:1031C00034AFD8E54F38AF98F63C5F9ECFF6E76F47
+:1031D000E7B0A722FFBC3D2C9FF5959E99C93FEF14
+:1031E000647E30753EEBDF73F93695CF7A65D07A21
+:1031F0005F08F9777D4AFE5DF7977F11F0892A1FF6
+:1032000053209FCC2C1F93C227CA3A8DDDE23A8D02
+:103210004DAE933A2FD92C7E3E9CCA4B9614B43EA9
+:10322000D4DFA9C9CC9C5CA7CCCC08F444A5C0E4ED
+:10323000F6C373C2E88910F164CFCC16A6CD4B3625
+:103240001122CFEE27A52726C2E4CF55F4C455AEF0
+:1032500027B66686D513AF613CEB0ED41364E67ACD
+:10326000C2C7F31C87D61335E7514F3CCAF5842FEC
+:103270004C3E32622FA7F990153D11CCFE36AD9E23
+:1032800008B4BFCD484FFC3E5DD1139BA8DD633829
+:10329000647ECA99E9897D9933D313670A3F9E9E5C
+:1032A000D8F509E989CA907AC2D3E09F7FB2B28982
+:1032B000E989673223CC3F7904F404DA076F7CCBC9
+:1032C00082787DFCDF584FFCA090EDCF03856A3DEE
+:1032D000E16B67F26FB87D66F26F2A8FA41A27FF41
+:1032E0001D976F5338795BD0FA91107FF7E0EFA705
+:1032F000E4DFDFFBCBBF08F844AD2702F864667A51
+:1033000042E1130B8C517DEE98DE8F7C74E0F9F571
+:10331000188FE0E5F1F3753DB9F45E735DBD20E211
+:103320003ABF5C9F18347E5EB11B7AB9BD70521FE4
+:1033300038D87E5DE176C32BF5B9AAF8F94C470879
+:103340007B21091337AFB117868C9BAF0F1337FF63
+:1033500009D909931C21EC8463E29BB8BE21E3E602
+:10336000C3D90995B8F9107642905F41E3E6AB27DF
+:103370005CD44F59D51BA17DB0477DFF22F0EFC62D
+:103380002C68C17B3E434DB9D49E3DA98FB93D4CBD
+:10339000F9BB317F9CD5DD2CA3BF2773D2AED3B24E
+:1033A000FC13A0B35D61E86CD77F503AFB72183A0A
+:1033B000DB13EAEF137D6C3AEB0B4A67BB153A0B54
+:1033C00073FFE7E3D2D9FE74359DC577A637E3FDD9
+:1033D000D3790E359D5980D69726517B4BFFBD285A
+:1033E000F76C3A7A5F5C9187B9DF20D47EA7D85F0B
+:1033F000A6E28FAD1694DB53F1C7A2C53F9FF57FC0
+:103400007708AAF8E321BBC8E38F6BA6CD87F94DF7
+:10341000BE5F53F1C7FD34EFDA44AF3A0FF9688865
+:103420003CE4EF70BB8852BEED79C8EB734B711C66
+:103430001F230FF9B71D8B42FF1D8057385E9FE990
+:10344000DF0150EEDD0CF37B37C3FCDECD6E7EEF8B
+:1034500066F7F56FB17B37DDEA7B3743EDECDE8D48
+:10346000627F54EE6128F647A5DFABD82FB4BB8A44
+:10347000FD16FBDFE709D16F2FF42B4CD95B957E4E
+:10348000157BAB258AE95DADBE55FCA1D1E9CCAE7B
+:10349000ADD5BF551E22472700DF460972F47CE4F4
+:1034A00023661FBBDC457AACF0FB70B4409FAF676E
+:1034B000327BE8E567CD34CE74B48B9C4984F683C7
+:1034C000D1C29944BFFAD1FD66CA1FBF491B699199
+:1034D000F380BE2A5C8BD0FF397E504FEF1B8C6788
+:1034E000035FE07EA6E8E87E7AA1FF5CE8A7E1CE74
+:1034F000BB1C437E74D47028DFE14539DE24F0FC28
+:10350000A0A2E9C1F8A9FAF7B97C9D94D35BB99F51
+:1035100010DAD138608348F3D17B39BF6C7EFAB1C1
+:10352000A7F0FE5EB48EB891BF5A395D6B9F29FB40
+:10353000FEF91EE447EBBED7E8BDFF942DE526F764
+:103540005C38AFB46FB4CBD0DFC13FE9297F6AE903
+:10355000ACB450CD2701744A369665A39C6964FECD
+:10356000D583C9CFB8711F46EEA8B621BD0077D26A
+:10357000F9B5CE6638DFFB974C0EECE5FEFE918187
+:103580009D8E28F4AB765458A3A1FD5EEEEFDFDEEE
+:103590009FB61AF36B6EDFE25C8C7A6D6FF2CA71C4
+:1035A00003FEBED62954E2FB9A3880947D6FD2F98F
+:1035B000217E9BFC1D3EF9721A9363D67DAFD379B1
+:1035C00007D893E322B3275F7C2F691DE65D413F57
+:1035D00032FA99B57CF93A3FF7646429F734D47F1D
+:1035E0008F2275AD757DB144EF03CCE8EF51E44413
+:1035F00049BA9A381AC7CDE5AF48FF5EDEE8FB2C22
+:10360000AF8932EE9C289817AC634E1371D23C29D7
+:103610001A7E38155DC3F3DFC9AAFC77DBB3D8FE89
+:103620008E69F2DF0D1F57E7BF8BE576E8AC7CD6DD
+:10363000DE57704195FF6E782E8B331916742CFF70
+:10364000DD7196FF6E58C97FD7A6CE7FA7E433F011
+:10365000C5B17BF3FF97E7BF1B99CC7FE7A17F57ED
+:103660005119A75F1E3B9AFF2E9697B5F9EF68BFD9
+:1036700030AED81E81DECF899D7AEF5391FFEEB335
+:10368000F9BA4F45FEBB96D9A283C5AFB2F55E71BC
+:10369000EDC22ADC8707F2B269DE9D7BAE5F3B8B11
+:1036A000E5B20C56BE7127DBF799E6B3DB10D76F96
+:1036B000A0E7759EF7C0D5EE7E660DB45F67D75361
+:1036C0007BD2EA2F6CA2F283DC1D4BE39103F32043
+:1036D000D4BCBB13FA1B2D32537E9D693E84FC0281
+:1036E000C697DAFC06DA3C066B0AD4E5FBA599E539
+:1036F00027B8DDF9ED7687CA4BD3FBF1F2D27CD245
+:10370000F9EDACDCEF3C682434BF95963E4E453372
+:10371000FA184D3316E37E9E2A723B36F9F1F9F51D
+:103720002CB65F23894CBF4DCAA32E904794CF99E6
+:103730003C327079F4369747570BFA28DF13299BF0
+:10374000DEEB194ED4C8A32E9047D97EF2E807C10C
+:10375000F3715EE5F2E808974763FC7E8B361FA79E
+:103760009F5CF9B3CEC779F353228FB472A5D940C9
+:10377000FA71DF9B57081E99EA21755ECCF31DBFD5
+:10378000DB833F2B72E5FF0348B774EE0080000037
+:103790001F8B080000000000000BED7D0D5854D772
+:1037A000B9EEDAB3F70CC38FE306014111F7F0E786
+:1037B000A02083823F89D141390653D4D144435B51
+:1037C0009333A0222AC9C1137B624FF35C47458B18
+:1037D000147050927013CD1D08A6A487D38E27E9CC
+:1037E00049DAE7A40F1AAF2739352D4D6ADAA73722
+:1037F0004F3BFC888ADE7B4DDA9E78EF31C7FB7D3C
+:103800006BAD0D339B196640CCCFB9873ECD76EDBD
+:10381000B5F6FAF9D6B7DEEFFDBEB5F69EEF9FBA64
+:1038200090E2C82164F5D77576770C5CCD8E485D43
+:103830003C2146C56A20F0D7F859CDE3F61CFC9729
+:10384000E4F41AF14A747716C37F15A21816119280
+:1038500048EFE015F22D84D808397BC74C48428EDA
+:1038600000FF2164ED323DBD8F7F77E0FFA5497AEF
+:10387000B51E9A7EE0A6E497BFE2967FDAA75D7256
+:10388000471C9DFEA464402069A1CB11A7ED520600
+:10389000747615A17D27EFEC87CC08487BCB4BC90C
+:1038A0007C424A4873715C0121BBCA88D50DF96B13
+:1038B0008853C2F4D62DC4DA0D8F6CED8C26C4B7B4
+:1038C0005F31FA01ACDF0823BEC3DA1F18EE37B44C
+:1038D00097B8451AF01D2774800A2B89DD22A91F8D
+:1038E000ADB9464C841CBE2DDA8A41DECEBDC47D06
+:1038F0001A4496EA5B0FC831A9B8EE6311CACD2A03
+:10390000D1F546403F93F6FAE4E3FC146C2C31C346
+:10391000F30F36880B7098C614BD5FBBAFCC804ADE
+:103920000B79A3305FD17CBEC8B6D93AECCFB7785B
+:10393000D9E8F895D72413E64BA4CFA77D82691F59
+:10394000391E7E867413EC6F8740FB1B754B24DD9C
+:10395000D346D777B8FBEB4623C8AFA2AE7C5A2438
+:10396000941B8A2775621EA4BBB38FA07E5558ACEA
+:10397000AB23B1F65B42C0E7CF76A61B0428F789DC
+:103980004C56C13491FE652E07C1FA328CE420F406
+:10399000ABA8CEDC5C0CE9CA1ED18AF951B70C0188
+:1039A000EBA9ECD863507209D9717283C101573AFF
+:1039B0005571D8AE44CBDFC1BF1584D4EF27A44FD7
+:1039C0004F48ED7EE772498FE93A7ADD2EDB570BDF
+:1039D000D08E144F141DE8855E867C1FF96FCFB121
+:1039E0001FD1417EB485E5475BE0391FF9A7D519A2
+:1039F000880DDAB984AB690621D75FDCD4E8847519
+:103A0000F6CA4D42A6A21C93F4548EED918EFA6C28
+:103A1000A8E74AB2BEA01DEA69CF77A46ECC19E927
+:103A2000DFEB0A9BC7C15852E681FB8BDF86C9805A
+:103A3000F2038D73DA0F0AD8DABFDFB903E396F029
+:103A4000DF90D53E8795BF61E931609A2866931D66
+:103A5000C63F106B2873C3F30382CE86CF3B1B2374
+:103A6000DAB07D48131C87F38CD87EDA4C46ADEF74
+:103A70001BD0E7A990FF3FEBC5762794EF17A01F57
+:103A800070AF4F761BAC3EFD7C820CAF5F11F547EB
+:103A9000C5058990EE3B02938B94C8EB4D876BA7CD
+:103AA000608B9C3F524ED53B8B5BF2C389799DFE68
+:103AB000B890EBF14FE7BDE99FCEEFF64F2F7CC7F3
+:103AC0003F5DD8E39F5EFC5BFFF42FE6E8D8BA7158
+:103AD000925F236ECC265426F07FAF609F02698EE2
+:103AE0001BA975626F04AC9BD467B4EBDD1F0FE0BC
+:103AF0002F06D79FC2EB59EAF52FAF201ECCC72C5B
+:103B00009FFB380F35FEFADC0882C4796BB40A6E6D
+:103B100027E4DB5A1CC7D7801EAD4D12AD02D4FB83
+:103B20007D8EE789ADB02E178ECCCB64E3FB37B921
+:103B30007EADE5CF89300ABC3FD9F89E4A9463C573
+:103B4000E6D0E582E1BB8AB32ABE57727C2F519A38
+:103B50002594E3F43A814C338FD8818AD66804F5F2
+:103B600091FEDD25CE3F58F07E51B16EFCB8AEC55A
+:103B7000F1B835C553715E551C197CF1238A234772
+:103B800000B7DC7308899CA1D0F950F1CDABF7B632
+:103B9000EAA07F26ECFB02ECB697AE6FEF5262AD67
+:103BA000378F9437D5196C386EF5B9F5D836BB76A2
+:103BB000E3F53706DB9442D0972BF5A2B51DF2D67C
+:103BC0006FC957509E69A80A50EFFAD2AF95E0F33B
+:103BD00003F653A21EAA8CB2F454A17D585210458C
+:103BE0004468A783D4A421FE2C233D22AEF704B35E
+:103BF00099F282E5E4264DFFF621903794DF5A6B67
+:103C00006E8BA0F32C1B707D6D85FA115F88241BD1
+:103C1000CAA6D0FE3859FFBCABBE8DD71462DB8478
+:103C2000EDD76E7808FBB3FE9127E8FCAD5FA22CC0
+:103C3000A0D792EFD905B896970A19240FD36764D5
+:103C400076FFAC8CE55F88895B9D04F2B8B6CC68E2
+:103C500045DC5E5FF22B9A5F5E024008E5AF6D8B3C
+:103C6000A7F9CE2551D64CC8AF2E15B2F07E658986
+:103C70002091A958BE9796DF592AA429B4FE8F69CE
+:103C8000BD6B65C745284E4AD7BC2CE1BAB9B4799B
+:103C9000E6EA2418DFD5A5510B44C8D8966DA67264
+:103CA0008F7AADAD3319CAEDEC68532A62FCF4D9B2
+:103CB000706726613A98487193AEBF2811B44326C5
+:103CC000E43BD9C4560CCA15A573D3F49E57DB5CEC
+:103CD000B550D1541DE45B09993B17F297603ED370
+:103CE00093C3D9F226D493269E262473932D06F3EC
+:103CF00059F926D78C67CF2F1D29BFEC07964D4E5B
+:103D0000D0B3A94B891DED8CC4D73D3CE2A4F80D7E
+:103D1000CFF8F288EA6C039DCF68E8AF2B8EDEB750
+:103D20004D817989868E272EA0F79D5317D0FBDD14
+:103D300031FCAAC76B12E94E84F22487D51F459C3B
+:103D4000EE3BD8078BA311F5B4F6B028D7637B36CA
+:103D500017B55BC4E136A15E1C3BBBB311F571D056
+:103D6000265923419E530F6F5D87EB983C2BC899D2
+:103D7000507EBBD7BE3A19D2D527050F76B157AAC8
+:103D800031CC84F2D71B8A142794572C9954FE5BAC
+:103D9000BD0EFA5CF549315E80E7AA8D8EC6FB2028
+:103DA000BDFE98100F2B985C6FD960B2D179A959DC
+:103DB000B714EE5F7F16FA03A9412294A05CB662A5
+:103DC00016D44B5AB8BD84AA25940BF6191647741D
+:103DD0008360CBC6F56D613C7828C5916A87FAA2ED
+:103DE0005BDF785A80FB97F109D42F3BE37DF40F1A
+:103DF0009E8FC77FC3BA886F11E9F3DF32339CAD62
+:103E0000F6B2F25B5B0537528168BB16471DAB4DBE
+:103E1000D09FA153027901C6B9B5215F40BC18D229
+:103E2000BB53656877C8CC78C3681C759922E0B924
+:103E30005DADB166C48567CCCCEE5536E4BF5700A6
+:103E4000F7ABF712AB02F5ED3A29D0F67735086EED
+:103E50001BFCF3AA20AF5B82FD4FD65B4F432DD1F5
+:103E600036C98976B0178112F5BD416843FB745D90
+:103E700070AE5B8A3C275722A7193C9ECF58C4449A
+:103E80004745D82074E33A8A47FC35D171F9E1DE21
+:103E90002C0D6E126E47A95D827EED28F5C7CD44CC
+:103EA0006E47133576F462ED21712694EF34A7D175
+:103EB000F9D8D529C422EF5EEA12E9BA6C8A754CAA
+:103EC000413ED974343DEE10A44DD36AFE06E7CBD3
+:103ED00090FCEB1AECECBF14E4E84418B7415F53D4
+:103EE0008169C3298B0E79D00B0647CB06C4C7174F
+:103EF00074141FA153DF42FD5C7D789AAE1EEB3532
+:103F0000CBA64B8CD7C5617EFF1AE1880C7851E6B1
+:103F100068FE8B4428679362F3B1FDF72C4CEEFDED
+:103F20007A6525E5D7478915F50A7AEBAC82759253
+:103F300056623E88E332DD57B6C606F9699B7504C2
+:103F4000FBB39EE37BC6948D3A944996BE6606EA1F
+:103F50004FB785E14CDA470FBE83FAD628D9CBCAD2
+:103F600091372C9B67C575B031ADA612C737F38961
+:103F7000F3B10F627D4733F2194DF1E701C3FC2025
+:103F8000041FD89DC5F4BCAA54982BC0F83E38C86D
+:103F9000F8696F91E06E877CBB5B708AF3F1615BBF
+:103FA0006139EA47DBF4385C4F5AFFD0EEFE6E0F02
+:103FB000DAC55E41A1FCDEF9AE683DAD8CE6159038
+:103FC000A347F955B96317A09C89C5A79E00FE6059
+:103FD000B5BB57A07865D3D613825768D39C0F8E94
+:103FE000D78FACE67E64F55DFA912A9FD1F289AB5A
+:103FF000E05FA1DC45E3DBCB0780F79D75BF1DB318
+:1040000010DAFDE4A4648D807E1C1260FE51AF0EB8
+:10401000475079AABC50BD3EC7FD9E56EEF774646A
+:10402000B2F9EC7D00FC3DA8A70A7007FD8C22F7D1
+:10403000067B11A477D70AB4DEDDADCDD4BFEAD7B5
+:10404000BB56CFC0F93A2578709DEFEEFEF6053DE0
+:10405000E2CA16A2204EEF2A731B0C909FE8205450
+:10406000CF766D730915A057D3CBFCFDA96487BF2C
+:10407000FFD4140BFA1733BABF6F66B2F5D2640ED1
+:104080009CFFF35C969F5EA723369FFA325D51C476
+:10409000E6D3DE9CD638BF74B67B865FF9799D691E
+:1040A0007EF9B99EB97EF9796F2EF04BE777DFE79D
+:1040B000577EE13B2BFDD2853D0FF9955FFCDB8DF3
+:1040C0007EE9A5DE6FF895BFFF6A855FFE0337774F
+:1040D000F9E5AFB8F5D77EE922F21DBFF25ADEA8A6
+:1040E000FA9F77C1F3DE4633DD88F541F9C6E33A3E
+:1040F00037E2E01C5D37E5731BD318BF7B80784542
+:10410000C20085965B512BB4A13D57F95E65ADE0C9
+:1041100046BE5739593C0F79D9183CEFB225CA8AA7
+:10412000FDD6F2BCCB4178DE56E48D3E3C6FFB38C9
+:1041300079DE966C2687A8D73EF626417A7BCBF8A7
+:1041400078DEBAF92A8F633CAF6CFE8AE6DAA523E3
+:104150003CAF67BECA0359BAB06BC9F3E79347D205
+:10416000C767953DEFCBEBDE98FFD4A3E3E1752B5A
+:1041700072BE64BCAE746C5E97A8F2BAD2CF87D719
+:104180004DB3305E36515EE749E3BCAE948C93D7B5
+:10419000F51A26C2EBDE48D3D1F9FCCAF0BA37F5DE
+:1041A000E3E275FD6981795D3DF23A48D723AF239B
+:1041B00093C7EBEA91D7C587E675177299DC278B11
+:1041C000D7FD2497E1CA08AF23DD2B18AFA3383CF5
+:1041D000D9BC6E15E70195C8EBA606E075ADC0EB3E
+:1041E0004CF830E37583FF3508AF6B055E373F7CD5
+:1041F0005E57D91A26AF6BEDA5F1FF2F8AD755214F
+:10420000AF837455E7DDC58D82F1BA39F9E9C7226C
+:10421000D246789DCA6F0EF1F8AB96B7FD6386C0A3
+:10422000FD083BE569CEC3029533B90DCFC13C57BC
+:10423000139F3F4857E1D507A776092C3DDD532E44
+:10424000CC88477E46A8DD4CEE3C40D3C90E85EABB
+:104250007528DE561FCBF44BCBCBC40CB61EEACD73
+:1042600081F3FF85E7FF276F0B1CEF6B8F64726B89
+:10427000CFB7A56EF4E1BD6FA6B3791F88657AA1AB
+:10428000EE0F0CBE3AA7FD20C557B63FA0DA212796
+:10429000B75F57707F201DE5A798E240F4831BD8D5
+:1042A000FEC020EE0F205EBDCAF60706717F00D368
+:1042B000A7C02E621D1ADCB812C3F633D4FD81A14B
+:1042C000E1FD018FC1EAD3CF71EF0F7409B648D376
+:1042D000976F7FA0CBC2F4F48BDE1FA8CF9653510B
+:1042E0001F7A2399BC97DDEC5985F3F0508699EE3F
+:1042F000072EBF75F36D4C97A4B0F4BC6C36EFDAA3
+:104300007D05ED7E54A3C4F6A31A93F4054E56A47E
+:104310003812F24B0B04197159DD5FB878AAB261FB
+:104320008D32F9FB0BEFF3B859A8FD853516FFF474
+:1043300083CAF8ECC064EF1F3B34F6A19CDB8772A4
+:10434000E7E4EE2BA8F66256F1DE625CFA77BBBFBB
+:10435000903553667A219154D4DF3EA23465A33E52
+:10436000B4EA08B51FC49E8A7C5D5DC7EBD3D9FC57
+:1043700074105B14EA89B343A47C518BE76DDC1E97
+:10438000A59D7ED9A4205FAD134B105F8E9DCD5EA1
+:1043900087BCBCDFB552C27DE07E7480309ED351B5
+:1043A000D471001EF9CB0C3D7DEE92C11D4DE30A88
+:1043B0003F1015AC7F88301EEAEC10283FEFEF7CF1
+:1043C000D9948678757ACFE3B8A5A1F0F6FA3A5970
+:1043D0003B44529AEE435E727AE134D45BB55FE6B9
+:1043E0000C9196BB46DC4D4B7C787E2AFE2B8D0CC7
+:1043F000F3D95944FD1BD607E10ECC7B4AA7E8440C
+:10440000B9A6768A74FF72566B04E5BBA9BE7A63BF
+:10441000A6E5E8FA9FC579F04CE23E5B80F7F7FA33
+:10442000CFEF4C172B37A35A3BEF0C1764AE77D75F
+:1044300040D5709DDF7FD5BF9CCCF141D6E0C32332
+:104440005C1EDAF10DB99E7A1CEDC3CC464121E623
+:1044500000E3EBE0E3EB60E3D38E6B16E7F7508EFF
+:10446000F65B3B9EA1AB84DA9F4A0FF36BB4E3AAE1
+:10447000BEE1394272307EE4AF87DAFEF7D5BD6C1B
+:104480007250FC50A8BFD85157DC847AE374890479
+:104490003C3E725F27B373F7B9746DD8CEFDC47319
+:1044A00008FDA23E7CE43E3AAEE3B61CE41B84DA8F
+:1044B000D187D3B71F77A6A0FEBDBA0EF5A2DFA5A0
+:1044C00023A87F7D9D0BA9DFD8D721C80294FD6961
+:1044D00047B3C916809FA8F2EFEF3841F54EBDFFF4
+:1044E0002497F35007E81DEA79C74253BA8FDDFBE2
+:1044F0002BAE6FFDC4D5749F1040DF34F227B5A0FA
+:104500007F8923FA17723EB87EA9F371B77AD63F36
+:104510004E3DDB9CC1F0403BAE6B575D26F413ABC8
+:10452000AB2566DBB47AD6C0C7D510645C128B535A
+:1045300041B9807A069E34DD2FD48E67F70D07D5FA
+:10454000AF4A8FBF1F39BADF84CECBD967BF9FEA8E
+:1045500085F2730CEE97D0FFD8F1BB48D20E431210
+:104560005E5A92EAC5F9FED8315BF699CFE99966B1
+:104570003E5E97494741B9C7A45B02834F860E2F21
+:10458000467FB287FA97D70B6208F5976F3F5D4178
+:10459000D7C34923C1386AE5AD47E9FA232D110491
+:1045A00071ACC355D183E96B5DA280FBA653321475
+:1045B000DA2FB5BDEB5D5B655C070F8AB63732124B
+:1045C00046F37B119A5D82719771F27CD17881FA02
+:1045D00015A1F8FED7D2597F42F1FE50BCE295D624
+:1045E000F74B709CAB0B57523F571DDFBD3EAF9052
+:1045F0009C19787FE2CA04F727AE8C737F22D439E6
+:1046000088C9DB9F088FA76CD7F0940ACE532A5A2B
+:10461000EE0D4F99AC73107F863EE23CFE5D06E3E3
+:104620002BEE24B6DEE2F44A2C3D2F5627D2F5D6E7
+:1046300057F7F05407C6F9F87AD88E1588A3F1FC1D
+:10464000B9FDE07844F8ACEB16C1E60E80FBEFF163
+:10465000FDAD3FBFF347CE1757D075B4938F33B13D
+:10466000E3572594BF14E88802ED4F279E2332DDDF
+:10467000DFD0916EDF78DEED3BF4B96A239B9FE9D2
+:10468000C47E8CF20F2789294AE4B8097F7D9EA752
+:1046900062D1FEA4725C27FBA43E948B11FE87F3CB
+:1046A000B0DBADEFF395D37422F5F9CA7536C7E9DF
+:1046B000D978DF07EF7E8FB892302297613F8BB0B9
+:1046C0007EFE3B8E57F091672D93676FADBF3C77B1
+:1046D000F0E742CAF324C833C0FECCF52C662FB5F0
+:1046E000F2AC54E5D9CAE292BB6DC01FA83C61BDD3
+:1046F000613CF31D91EA6918725D1F48AEBD9E0FC3
+:10470000E83C4D2F047FD61C5CBEBBBAF47DBE7A5C
+:10471000A7C6BF82C9598D830DC7C7BE4D28AE68D5
+:10472000E5AF95BB366EA69D87E071B46EBABFE764
+:104730003C254D4A1CADB2F5AC01E7F73F4A1C8D54
+:10474000EC53A6222FD0E2CD701C8AC7D3B4F1B3AC
+:104750004368178137FE63C7A96627B3B7A7330B32
+:10476000C3DF0755ED70A8FD50D5EE06DB178D4F62
+:1047700053E83A0D656F43F9694969E1F9699BB3FB
+:1047800026E6A7C567E969FDE3F5D32E717B1CCA50
+:104790004FFB30F3FF0F3F2D92CB5FF59B76373009
+:1047A000DCD38E77C8B5F002EE07CD3C23B0B6B4AB
+:1047B000E3D5F80957F45603EE078C1A2FF7138642
+:1047C000FD38CD3847F96B5DF7D84F73FE9EFA6917
+:1047D0004D66964E69BFFC9C73D9E4FB69E9DC8E9B
+:1047E00007F3D332B244B65FF31FD44F8BCE1ADB3C
+:1047F0004FDB8D7E9A1240AFEEDA4F7318502FB414
+:10480000E3A9BCD17D0437A143E9577416E17EDAF0
+:104810003F733FAD3B2C3FEDFF6685E7A70DA19FA2
+:1048200086716BF4D3B0DE93EC3D831DE8A7D1FD18
+:10483000608D9FD6097E1A943F8787061246DA1B41
+:10484000EA647EDABDE64F1F05E1A35F56FEA4FAD7
+:104850005D41F913F7BF26CA9F547F2D247F1A3E6E
+:104860005F161E7F0AF77C596FC205031EAFFDAAB3
+:104870009D2F53CF8D05E35167DDE95371BD4D94F5
+:10488000477564EA288F22B7EED0FDA75D5881C82E
+:10489000DEFB70C770A5023947C8323D1F74ABF705
+:1048A0008AFB10A4A5B8441A77C8CAE4FB2C058279
+:1048B00084931EC91F51DB4FD639B2909F49B293E2
+:1048C00030FB6323C8FBB2D0E8148EB4BB536DB782
+:1048D00023BC76F765F1F73F82B7BB2F2B6174BB22
+:1048E000FB10A71226DEAE3D3364BBF6CC00EDDA3A
+:1048F0003359BB8E2C7FBF78743CC6511B8BBCCC0C
+:1049000043280F24377B783C4647EA697CE69C3491
+:104910000DCF39BC6BB3A23AAA7199C265BF3A17E1
+:10492000AB605CE6A0148778F81362C5269F535CE1
+:10493000541F8DFFE4B0127F7D0F1897B15AF257C4
+:104940004D837A4AC9CDF3542EC43F4E6331369F0E
+:1049500043DB36573EB33216AEF9394587F0B5AE74
+:1049600045B63DABB0D90BAD7BCF831B46569BBD47
+:1049700087F07D24A3926FC575B2E64F6E69AA8257
+:10498000EFC3D4FC6E27145C6B8DB0A20A1E8EFFA1
+:104990002407E5D4F819A1F1DF399673C730FE4B2F
+:1049A00088F7FD79F07C6A974010377ED875C08013
+:1049B000F1C2BC36B301ED91A76E0F4D5B4FE5D34D
+:1049C000747EE3067A7DADA5885E018744E21367B5
+:1049D0005BD8DC46EFCB9D6D869918E7EB1214F49B
+:1049E0000B2ABBF62C5C06FDA970410A3A24D7417C
+:1049F0001AFD88AE0805CFBF0D086986196C5F9552
+:104A00009EA3B97252245320FF4C9DE8C63347A998
+:104A1000D0D7650BD8FB5951F4FC08DB7F4DCD2076
+:104A200012DEA71207E1A28C100F7DECB20EF16F1F
+:104A30005A1DB3D7A494C9D948EA0EE079ACF1EE77
+:104A4000875E1774747F31D4BEE8E6D95C7F09C3F2
+:104A5000CB28A320607B45C49F2F6C9ECDF4558E40
+:104A60009653F1FDB1B387A73FBE0FC67DA328863D
+:104A7000BECF77E327FE765C7B457C66F6BC5B8F1A
+:104A8000F6BC716514C59BBE93DFD8E49442C7831E
+:104A90002AF9BA0C697F5B03C783244BE0F8C5365B
+:104AA00042759E24BACCD4DEEE067B8B7CAA51AA3A
+:104AB00011E87B5B1E81B8CCC1EDEFCE5071A18EA9
+:104AC000B1E342D51ABB1B6E5C28543CE85EBFE7DD
+:104AD00035D1B826AC63017965B8EF770DE0641481
+:104AE0008ED8B751EF7BA9B800FC09EDFE0F5B191A
+:104AF0001EE41DDD40F1C0D3B287A6ADA7185EE469
+:104B0000B79D61B8D05544D3A371A199E142473311
+:104B1000C5855D0D800B04AF0C07B4B850D9398C36
+:104B20000B47F0BCA3F35991FAF5975B26860BD39C
+:104B3000B99E6B71613AE202EACF16767FA2B83075
+:104B400084B890131A173A146EC743E042078C9545
+:104B5000E1079F87063E0F0D6D0C9F5F2D67F8CC18
+:104B6000E7C57A94E172FEB30CAF5F3B7926F03C67
+:104B7000FC3D9B1FD95544E7A1AA81E1735503C3AE
+:104B8000E74A0F9F87D63603FA1137848A23349E6B
+:104B90007194E1F2E2B7D39BF05CE4D07FD7790E59
+:104BA000621F7B147A6E559D871B380F05C1E7E1A4
+:104BB00049FC47007C7E52C5E737F57785CFE1CECB
+:104BC000C3D530F1F92AC76795C76CE57A94D81038
+:104BD0001E8FA99A1392C754CD09C063AAE6B07676
+:104BE0007F9026B3F625C61FD473C9B50FFCA9075D
+:104BF00089C0E55A91DAFDCB2D0FD3B891DC28C8D6
+:104C0000D86E1BC6CD0AF11CABE771E61FD8E93C94
+:104C1000FD957962F5559A15FA9CB6BE50FEDDDD1C
+:104C2000DA973396C0FE5D15FE13BA94E866F66512
+:104C30002BDA1742D7B90DF7A3B6EF25EEEE31EC1C
+:104C4000CB363EC741FD3BD707940F86F2EFB63710
+:104C50004C6CFF21A49D09F1BD88BB3DEF73F7FBB0
+:104C600067DCAFDE47DC6E01FD2FC67F7796B1F8BB
+:104C7000F5CEAEF1C5AFA72B7B8A51ADC2DD47D3D0
+:104C8000FA61C3FB667C1F2DD4FED9B4196C1D7864
+:104C9000F5849E1F1FC6590FC759CF0166EF86794D
+:104CA000B0C070F68040A6A0BE81FDC1F322F98D90
+:104CB000CCAEBDD6C1F1B381E1A78ABBDB79BFFB26
+:104CC0008505279229BF15A81D934FEEA1E7F8B7D8
+:104CD00075313B08576ABFAAEBC476E263D7FA8501
+:104CE000BFA6F53A9F8D50104F650FC36515572F1E
+:104CF0000BE7183EB7317CA692F5B17757DDD3A20A
+:104D0000F17B0FF7CAEE85C2D9CEF4F0EC5D274EE9
+:104D1000BE8F9F3A5EFFB8C01212670B2C0170B6AF
+:104D200000FBEA13B7DA98D643E33A3B16E9683C4E
+:104D30006DBCFBEB2F569F8B9C133F72DE5CF5B76F
+:104D400076675D76611CB79C287119667C9F8BF035
+:104D500073391F1DB7A58C8EF786C2558A7FE1C4B3
+:104D6000CDDC81E3666BB303F3F6917D5CF65D9178
+:104D70001D9CB7ABB8BA0D7155088EABBB43E06A4A
+:104D8000A324FF02E3E18D5B24FABE4A305CDD76AA
+:104D9000F21EE12AB9B7E728270B571D88ABE611A9
+:104DA0005C2D2F6371ADF19E9FFCBC71557B7E72B3
+:104DB000B2E22EB929BD3A3CD6B3FAEBC78B69DC17
+:104DC000E52D42DF537B4E71D7D2B84BB783F296B5
+:104DD00050EB7561C15929D0BA0D166F295C562E5A
+:104DE000C643BD8B8BCB1BD6A03EDC76D6627C65E2
+:104DF000B5B967158DBB64E4D378CFB29BEC5CF09A
+:104E00004305C097C8C8F747D4F5FFBE65A899C643
+:104E10005B38BE513E8EF8E6090FDFFE101ADFFE4A
+:104E20001008DFFEC0F1CDB48ABDEF538EEFEF4D19
+:104E300025E46189144B71187F62D727395FA40F6D
+:104E4000C2B82E5892DAF0AC60792D7B5F2FD4F384
+:104E5000F9E6B19FD7BE3FB716CB2730FE89EFC921
+:104E6000A9EFD18D7A1F0F14F4E0A291F702D57C3F
+:104E70000321CD98BF89D7F32194D363BCBC43747D
+:104E80001FA0CFD99270FCE1D607FF7461FE669F28
+:104E9000FAA4F891FA6A93DD26BD18A03E287E3068
+:104EA00031607D6ECCFF10F225DF7E29D0AF5C6CC7
+:104EB00087F3F03237DD27FC69324F136B217D1FFA
+:104EC00090E39883EBC96C67601CCF9EC5F5621FA9
+:104ED000ACB34523EB8C6A76220F0DE0BA985E9353
+:104EE000E41B47FA6FDC4E689F8B200D749D4710C2
+:104EF0006910C7815DC671CC966E0AF8BCF20CE0F1
+:104F0000A92F8E885BA85D0A169FDAF7D181DAF3A4
+:104F10003E78F1A3EC29F18338E9392487E2217F37
+:104F20005E5D17C1ECDAA7FB9DB5E7F5849C48B13F
+:104F30004F1D2B1EF6128E6BCE483A95DB3F559EC9
+:104F4000439AFA55F9CDEE14E83A6D7DB5A509E31B
+:104F5000664F26D9CEE37EE4933112DDC703BFF45A
+:104F6000E630CEF9E0AC0E2484E3281EF51E9FF651
+:104F7000BD064DDA2629F2227E1411E6474F6A68F3
+:104F8000BF0E55118791FA575BE4C179345F7707FB
+:104F9000AEEFAFAC7912D71F911413F2824B1FA65C
+:104FA000EB1027D4711C9827F8F198735C0E7D32B2
+:104FB00093D74A499102C96D9551F4B3E37DC6B1C7
+:104FC000E53B5C2F2FB7B236BD18E30987252B8D43
+:104FD00033396304F2632178FD876356FEAFECC278
+:104FE00091F779CEBDBAFE98D3677E76F3F999DD55
+:104FF00015D81FDC96C2F9E45744DFA7CC057D9F86
+:10500000175CDF553B3069FAEE617253E5D9ABA905
+:105010005F95DFEC5A81F2CD7FCD5E40F57D14AE19
+:10502000011C1D098CBB34BF295B61B8233BA6E082
+:1050300077E186DF67B6BB4C017137487D3ACC37E4
+:1050400007A887BF173D8C93256EBF7AE1EE01B5A7
+:105050005E5DE07A29FE66CD25B49FE3ED8F159F56
+:105060004B18B99FA8F693F8F339550EBD65274C38
+:10507000068A0BFE76274E6D4FF3DCC2B9ECB95AA7
+:10508000416E2A348F965BB0E7D669FA650AD22F53
+:10509000D58E61BF248CEF08EE2611D65554FEEB59
+:1050A0002605F4E37A0A3B2F01FDA5FCBC43E0CBC7
+:1050B00088F3F8C148B68E6AE6B1F7DF67233E4150
+:1050C000BD275A456B37CCD3EC4B22FD5E5486CAC4
+:1050D000DF5D8C9FDB380F4DB04B7EF1F708CED7EC
+:1050E000E3C9597915C60D3CA2D54D46F377753DF8
+:1050F000DEB81D41BFD335546CA0E7CC2234E51295
+:1051000048B78CF9E5003B18E719F2BE7181FAC186
+:105110007642F7B1B5EB9024C9F4BB04CD9B642B68
+:10512000FAF74ECDBA6C4E067E8DBCF4123B1716C4
+:10513000951FFFF56DB89F6E8BA2FB67EA7AA2F808
+:1051400002726C167A2C781D5EA7A51BC7C4057564
+:105150009DBA81EFE3B57DBF4CF1A8637F124DBFCF
+:10516000B25FA1D7CEFD167AFDC17E2BCDEFDABF9F
+:1051700084A64FA478CE615CF5CF8F907CF49BAE73
+:10518000A6B80F46B1F1E673BF3FA608D73BE724A8
+:10519000EA3CF671A258362B91EA5B84C61FFA26C8
+:1051A0009FD778927F14E3BA3BAAF50ACE4B39F722
+:1051B00047482DDB470936AF319FB1791AC07932A4
+:1051C000637D9AF9E4F39E406A2E60BC63BB9DF94F
+:1051D0003103DE7F96E97B94307FA7CDA3E7B76CE0
+:1051E00016F72392ECAB937DE6ADBE20AD19ED5FD3
+:1051F0007F8B48F0BB06975B1E1E53EEBFD3E06368
+:105200007F153BEF14952F99327CECCBBB73D9F90A
+:105210003D6F959EE67FCF5A61CA88199D3F58CD54
+:10522000CEE969DBF9F95C89E6BF176DFFF95CE847
+:10523000F7379FF89611FBD5CCDFFF441C8FF3D9CD
+:10524000FFAF14981E5DD4D8ED51781E242E7A92AB
+:105250003FD79C6C7D372380DEDE40BD5546EB6D2D
+:10526000A3CE6D5A254CBE3ECEED24D47F892F4E61
+:1052700074E379A01B882F39A3F552AB7FB7520C8A
+:105280006C9EB9BE56701D50F552D543558F1E7B8E
+:10529000C4ABC7EFEB9DA87B2D01F7FFB4FA097AE9
+:1052A0004CCFA76E7B5DA0F8F2D83EFF3882563F08
+:1052B000876E3F4AF7238700008F07D0C366B3B2DB
+:1052C0000E3FD5D71B5F2CE077EA86BCCFB3F3AC9B
+:1052D0008F70FF55C3E362CCC4660439C40846FA34
+:1052E0001D8243558CD7E9896DDDFD50CF133FD624
+:1052F0003B517FAF151BDAF0FD164976D3F3C6C0DC
+:1053000020E541CB08DF0BA6CF88FC833E3CB209E9
+:105310003B95103EAE7B83E1BA7372707D67DDD83A
+:10532000B8DE87B88E7E15C78B60B8BE0B711DFACC
+:10533000DE8BF28E1F0BD7DD4766F8E0C3FDF3FC72
+:10534000FD8B60B81E6C7D7CD1B87E03713D3E3410
+:10535000AE5FE1B87E222524AEBF8BDF77D98EB851
+:10536000AE8C1FD755FB1B1CD7D9F768B6725C1FD4
+:10537000425C2F088EEB2752545CB75EF0B5C71124
+:10538000C6E8DA8169E02F974D33A1BCBFAB67B89F
+:10539000F9A12C9BE27CE4BF8FE3DE77A7B0EFBDE1
+:1053A000F426C9A67CB89AA2597C82E06B5B209255
+:1053B000ED5C3EEA73CFA5B2E7A6A612D283B82170
+:1053C000D94CE8B71C4C65FC72A0259DA6C1BFFA5C
+:1053D00005E2C1A50F45E2EB5F69AFC37E500CF05B
+:1053E00073786E15F83F61F9575298FE953461FF56
+:1053F000EA857909C1FD2BF5BCE5EC9381EDCA6F17
+:10540000E67EB5E2093F99F7C5C613AED33E8F9647
+:105410001FF8AFD4BF6AFFBBDDCF3A331077F65227
+:105420007CBE12029FFB393E77E66AF0B96172F0EA
+:10543000B9224CDE7D3D043EABBCFBBA77CE91A4D5
+:1054400031F1D99F77FFEF30F13918EF56F98B3AE8
+:105450007FCD82FD97B89FF279E17328DE9DF088B9
+:105460004DC0F75B1EDB97BF10D5F116E273C26823
+:105470007C56E7DB6164CF69F9CEA7E81F268CCCA8
+:10548000DF0927F09D98D0E7B9D4F3095A398CDAAF
+:10549000176A08BCFE2BE60B21F685D8FB7DDBF1F5
+:1054A000FD3EE17378BFAF6562E7B8621445E595EC
+:1054B00063EE0769E3D275FC7D236D5C7A5AA9D34C
+:1054C000E0C07319EEF254275C6FA4B2FA073FDB19
+:1054D0009A8ADFF7772618A8BD23B71F4EDA306502
+:1054E000C44FB906F324F8CC53303DD5FA29D786FA
+:1054F000FD94023F3FE5F11CF63D88FE613FA5DDCE
+:10550000CF4F51F38782F8298E1C89E6839FE2C82A
+:105510004908EDA7ECE27ECACCDC107E4A67607DCC
+:10552000BA9EC3F429989F3210629DDF6B3F65607D
+:10553000188FC7F653DE9AE5EFA7EC08D74F393935
+:10554000B69F525125D0737AE1FA2983DC4F89AF97
+:105550008B4DD6A58DC6E7DEF8478AF0FCFDA0F797
+:10556000D11233EA651D7B2F3BB49F626B5A04D77F
+:105570005D720D7D0FE61B3BFDFD1442EC84EE4B8E
+:105580004CD04FF957EC143DE7EA61E75CFFFE8D24
+:10559000DFFF6DC1DD9F73FDFEACCCCD4E1AC47331
+:1055A00025F2F75A04CC57ED6B011F6F449540620A
+:1055B0007C70A440E5C13D92DFBCFC99DCD6B1FD16
+:1055C0004181EAC9AE1476BE657A99BF5DCD7B870D
+:1055D000BDDFA3DACDBC20FC583B3FF45C069E1F28
+:1055E0002988A1FBE85A7BD9A0307FA6A18CD0EFF7
+:1055F000136F6DD823E0FAFC30C73F5EF517620CDD
+:10560000E5039FFC9AFDEE879CDE6D44BF4AFE9E3B
+:1056100028E37CF6DD7EDEE4FB3D58D55EFE10D649
+:105620009394498807D613BE9FF00FB09E30FD3A81
+:10563000AC27FADD34584F787D13D6135E7F0AEB22
+:1056400009F3FF09D613A67FB6DF46D3DDFB4B680F
+:10565000FA9A37827D4FDDB97933DAA751F3E2FB4D
+:105660001D06DCC7F204DEC7AACEF96AF14E63EE6E
+:10567000D8BCB39CE398B69E09F3CEDAB179A72AD9
+:105680003F95777E9CB3E839943FC6B9F03D56EF1D
+:10569000703CE68BE19D3B5C22C5B960BC7380C762
+:1056A0000542F1CEED3C2E70DDFBF485E43179A7A7
+:1056B0007FDC70796E78BCB3F74BCA3B7BC7C93BC4
+:1056C000DF9A3536EFAC0A62BF1A72147FDEE966E4
+:1056D000F62B5CFFBC3A373CFFBC32A47F5EE3E7AD
+:1056E0009F5F69E5FEF93DC2F9CA7B84F38EA0385D
+:1056F000EF3892EC83F30E27C3F913B961E2FCF3A0
+:1057000080F3D0CEE5DB8B4DBEDF8FBC5738DFAFEB
+:10571000E23CE97CD817E7D5F74CC2D50F4F2EE312
+:1057200083A1F4A33AA47E38FDF4E3AA87E9875A5B
+:10573000FE5E9DE35B75FA203DC7A39EE3AB8F251C
+:10574000DCFE09C76DCB467F5FEBCBFA1DA067B8C7
+:105750009FF79FDF010AFC1DA06DFC3B1CDBEED117
+:10576000778026EDF7EEBAD8F79DEFFDEFDD797E75
+:1057700021D2737B82827EEEE7F57B77451E81FE28
+:10578000CEDEB616F69DFC6D2DCDC3BF7F17690E1C
+:10579000FE7B77716B32685CEA4F1D8207D5804EC5
+:1057A00055DCC87A0AF777EF76CAAE317FF76E67B5
+:1057B0008E6B42BF7B37DE7369CDFC7C5ED8E7D24F
+:1057C000429C9B73F13847B07373DAF869A29B9FD0
+:1057D0002BC1BF31CE29A6A93C3EF839C5B49C00E7
+:1057E000E714F1DB14BEE71A86C7A14CEC7C5D73AD
+:1057F0001ADF67E0E7EBEEF577B17E335F18E77706
+:10580000B11C4790FF87718E3A70DCACEBA958B49D
+:10581000C3C1E26695EE89C5CDFE90AB8415371BFA
+:10582000EF79A1BF9DAF84755E28DC733D5D689BF9
+:105830002670AE27D839A3617DD19C330A76EE4716
+:105840001DCF78CFFD74CF67EB2ED8B99F70C7F10D
+:10585000161FFF44DF97383A3FE43A3D3A3FC03ADB
+:105860003D3ADF7F9D061BE77B9A72C1CE29A9B81E
+:10587000A63DA7F469A4693EFEEE8818432CB8BE85
+:1058800093489415E350FB8CECFED351A676BC7E76
+:105890001A99EAC6CA9F161D0E1CFFA73A8F11F768
+:1058A000EBDF5BECF80CFB1F1D7BDE8ECD1E4EBCD0
+:1058B000CF82EB7DCBBEEFD88B8157C9D3C85F06B3
+:1058C000FABD9C2D3AE240DE6ACC63EBF9237DF70A
+:1058D000AC5818BFB064A531AF3040F97DFF85D614
+:1058E000B75C24359E00B8309BD7F3A28E5461BDBF
+:1058F0008F3EF10FD75E81F14429390B506C5196E0
+:105900009ED285302F75BF4CA7DFA59E9EC7ED7632
+:1059100012294079EF2F7024FAB66B5464899D17D1
+:10592000F02CC5FCE5FF9673E697505FDDD762E883
+:105930007B7AB674EBFA85C2E87E403DB3B11EE3D4
+:10594000ADFA8F91D7A9F5FC2CD2FB22FDCD13E740
+:105950001F1FFD2DD8829FC57A670A909EF3A30F63
+:105960001E8D5F0AE904EF4CCC3F4F3AE8EFA8FCEC
+:105970000C6C22F2FEEABC8EE7D18E2D7FE8C6CBFE
+:10598000C7A0FF24CB40BF837094C791D5761BF38B
+:10599000443AFE463E2E550E17ABC796C3622E37CD
+:1059A0001F392C0E2487134B6C4BF03E74928EBB28
+:1059B0006E3FB16F833EDAA67B2217C2C4272B9EAF
+:1059C000578F413533329C9404403D362607C6AF8D
+:1059D000D47A8616DB8AF0FEC5EAF74BF17B289174
+:1059E00017D9EF881A338833DA449F7B302F61E46C
+:1059F000B92285EC15D246E6614721D3F738D403A6
+:105A0000A8EF90C195B401AE72C6734FC950FE881D
+:105A1000D95D1648DF6C56B60EC18DA0BFFF532B63
+:105A2000B71B2B7CCA5572B9ED5D64DB84FD33086E
+:105A3000C48EE5EA973079992E4E5B40E36219A453
+:105A40006023E0D8B7ADAC3CF4F7315A7EA98B8225
+:105A50004A64061B677DCE7182F1A0C8A41676CD7C
+:105A6000F0D2F51D493C469CE75DD6D79EAF4DC2AE
+:105A70007158E9EFE71CF6AC6C9560DEDBF0E50BE6
+:105A8000E02FFB218DEF27BD04C08E3CD939C3E048
+:105A90003E1D200EB2DDCAE66F6D816D4721CA251D
+:105AA000C2FBF231287F34DB40FDDDE53A57590572
+:105AB000EACD4331D45F80FB65BE76F5053EEE1737
+:105AC000F2D8B9ABA3FFC748F3B5720D579F0E8C40
+:105AD0005E5707F21202EAD341BC3F4A9FA606D5A1
+:105AE000A7FA20FAB4A3B070442FD4AB9464A07E7C
+:105AF0009574EB480FBB1A7BE973462BAD4F2A61B7
+:105B00007106F156142D27DE6AA0FE9524D7D079B0
+:105B1000025CCECDA3EB4227214F50715B8CB1D1FB
+:105B2000FCDCBC30DBC93812AA9DBD63B5B397B7A6
+:105B3000B3FCA11807DA9BE5889B3EF3B7D2CACE27
+:105B4000C3C55BD979E360FAFF3721F4FF31EBB0CD
+:105B5000FEFF18FB134AFF9BB8DEC1BCBC45CB0758
+:105B6000D5FF0E7A8DB230FD8FE2FAFF9895384B53
+:105B700092B0BF4CDF2FFEE8FE56F4E3D5F5F0A25D
+:105B800067ADDF7A688134AE8760E37B9A8FDF840C
+:105B9000E38376DE2B109DE807FD91E4B6A3BF6F8B
+:105BA0005A224BF89DC30FF2D47EDBDECFA37E9B3F
+:105BB00097DADB3672F36C04AEB365028D534E7127
+:105BC0007A6C461C2F7111DC67FC1F5CAF5FD23111
+:105BD0007BEFCC22743D12C945501EDA751A99D15B
+:105BE0005DE0F099A7DD5CBEA7ADF63E94D74B3AD9
+:105BF000390AF99E3A1FDAF1ACE0F29DB798ADEBA5
+:105C000050F81F6165F81FC1DB89FB37634DA07534
+:105C1000BCFCC99F5E7B658C7AF4BCDDDB7CBC2A56
+:105C20004E47A9386D19C6E9DB14A7ABEB559C7E2E
+:105C30001D711AD6F56701EDC43458D790FE7FAFB9
+:105C400086736100800000001F8B080000000000C8
+:105C5000000BC57D0B7C54D5D1F8B97BF71936C93B
+:105C6000E64596F70612091260936C5E10E086878F
+:105C7000C696C7A2A28104B20141C008415157A5EE
+:105C80001F37E641D0F01951FBD1D28F6E102D7D18
+:105C9000E807CAD7A29FB58B6045050D9F8A88AFDC
+:105CA000285A5FB45290BA6D6DFDCFCCB927BBF7BF
+:105CB000260BA1B6FF0F7E3A9C7BCE3D67CE9C990A
+:105CC000393373E69E1DE4D9FDD37B196383B35545
+:105CD000C64632B6C117B0788B18B347DAFE28270C
+:105CE00001F4B8CC0127639F9528D717C1F3EBE1E6
+:105CF0003F96C198D96D55E5F10023AD5D1CDADF03
+:105D0000A7F6762FF563AE6CA7F7E54802B59323A7
+:105D1000ED5D5836BB1A58208FB141A6C0EF274021
+:105D20003FCC6D32B362C61C8CFF919D0AD5FF7EBD
+:105D3000021F67CA774E3D746F3AFCFB12AB370700
+:105D4000C0268955ED067CBEC13F5319F37B65C65D
+:105D50008A104AD43EF5AFF68610BCDF64ED70CFF2
+:105D60008376AEECEFDFEC8271A7AC7EEAD347CE50
+:105D7000D34F01BE0FFD8CD1E0E1FAFF9D55E863E2
+:105D80002CE1B0EC953C30AF5CA60E4822FA8CF1C9
+:105D9000C238F6FABB697E151EB65782F9DE5FAAD5
+:105DA0005C8ACF8730EFDC42E8A26D03F35F676166
+:105DB0004C49DBEDC0F2A0DE742EA07E7AD3B91080
+:105DC0009F8BF11D62FCEC9EF1CB687D0CE3DB71D7
+:105DD000DC2CAA9F1CDB2FD47F2999802E36181C1F
+:105DE000FA4B5D93146A94A2EB38DB07EB9AF14F00
+:105DF0005DD739885FBC759D02B8B0898CFD624261
+:105E0000C25635EF9F32DE60EF79F868B097CF6BFE
+:105E1000BB15E60EF357075B430F6745D75DC035EB
+:105E20001AFF003D9622FEAD59B858B00EFF3569F5
+:105E3000AB3A94B14EC62A915F66FB02AB683CD682
+:105E40007D05037EDA7E47AA7437B41DAA84A59423
+:105E5000BC281DBB2778088AF7862ABCFDD060AA1B
+:105E6000A44ABAFED69DAF3F231E80DF6D88DFC3F4
+:105E70005E652ABE3715E707E5549935607F4D26E4
+:105E8000B60261676A68851F608BD744F52D1A5F7B
+:105E90008BF2EF8B1515FB017E69C27ECEFAE4759D
+:105EA00026A0775229E743C087F913195BA5F56F40
+:105EB000F28758373C4F28654A08E0119FAC9A009A
+:105EC000DFB36CD1C3B2C4DF5BE6C4F6669AF706F3
+:105ED0009FD28EFD377B5D5416FDC5C3739B86D75D
+:105EE000360DCF6D513C1FF4527F81ADE7C3D348CF
+:105EF000A7FEE27B68420FBE3B886FE3F427D60B18
+:105F0000DF6583E0793397CF39874715A07C3EAAB8
+:105F1000E1BDC1E7FF05F653512AED45FE050D949D
+:105F200080FD6DB3C27C613DB7D56FA9B0021E9DE7
+:105F3000EB5DF932716AA811CBDB9A5CF977433FCC
+:105F4000BFD2F8D0C89F3DEF5B778F29CC237AFC76
+:105F50000F8E33B5BC6B5621BC9F0C7A027BAB60B5
+:105F600020EF32CABBEAF602BE6D92EA5E827C7F07
+:105F700085D3FB3036705E4DF81BFB1790B1BB68C4
+:105F80001E62BECCE9BB40FB466AEF1AA036F82F72
+:105F9000A6BD4DADC2F6513AA6E5231DE7944A2AA7
+:105FA000EAA90A36AC1369FD16F2015F9F63B43E9D
+:105FB0004E986C5994AEBDFB57A97D85BF4142BA3E
+:105FC0003A72612878EAF0C373A09BC9D3C1BA01C1
+:105FD0002664035FE4617FAF517F513C0A0BF57883
+:105FE0004C7E08F188F6DF2AF0F984E4B69FF87C4D
+:105FF000E5481ACF92190BDA39BC2D216907C2AFD7
+:106000001CC3430CF4D99192C0399C9F3A8DEB6923
+:10601000F5DDC45013F21A6B98E01F8730CC50BFE7
+:106020004DD5F4DB54BB93F421FBDA7CAADBCE9F85
+:106030007D03FC26013B0F49C5528DEB7763A1CC54
+:10604000BAA56F06F46B7C4B7E46FCF16B8277FA47
+:106050006714C22CD358ADDFD97B9E352616407EFF
+:1060600071E573FE7DDB121E86FA4B2A9DE6CA2F70
+:10607000EAA37DF0DFA8BF24D6ADCA3E241FF33EBD
+:10608000EC417C01FF022E8757C2B843F2B91E00D3
+:106090005495DD7D8C3B245FD2F1EBB52DD3D848F0
+:1060A00080363B531353394C2E2079F1E4533BBED9
+:1060B0004F56B8D8DE7453743E627EA2DF715ABF69
+:1060C0003DF85A617E79382F56B5C7C9E757108316
+:1060D0008FBBB4625CEC3CC5FC8CF81EDA10F4CFCC
+:1060E00000BB202D389D9D4C63ECD90D012A239EC9
+:1060F0008E025A3FD502D0CCBA16DF04289C6481A8
+:1061000032EC372DB7E3BA2D40A7B4BD0E2F701473
+:10611000EBB28F6AF702EBADD9277B6D9EFEF3C71A
+:10612000C5F285911FF627DE3A01F55AD3CCFCAAB9
+:1061300074D438EA91AAC3A5503EE23DEE84F2BC85
+:106140003D47AADC20FF4D47BD5519A0FA9BF6FC40
+:106150007C6B3BC847D3BCFCADD83EED7F7EE69E52
+:1061600089E50512D90137427B15F783FD7A7B2C2F
+:106170002A3F2DC44F474AFCDF2F407933073CC8E4
+:106180008F4D15529CF65C7F0541E4B3D1DE8B98B0
+:10619000B8DE3B089A7120D0451808CD1544AF975A
+:1061A00035DA34291FBC2441FBFDE5368F2D8BE405
+:1061B000E1A67CDAB75C8727C0F32DD34CA6BBA140
+:1061C000746072663BEADB8E692609E9DE349BE384
+:1061D0006149EF96EB9CBDF13852A21CC37E9A1622
+:1061E00041BBBCF8F842BB27707E36587F670187F9
+:1061F000C8BF169067592B6B7C7C7B3ED927922FAA
+:106200007D14E167467A18F94BF0D50B396F0C47CE
+:106210003B08F8A811DF33F2CD1597BC7909DF47A9
+:10622000F57CD18B7EBDE875C689FBEB2BA5B2430F
+:1062300072F6A62FD0EF5E1CEF95AF395D3B4A4753
+:106240007B18D0F540996D4C37ED5FFEFBB01EDE3C
+:10625000F225CAFDC2FF071787BFF77800F1FFDA02
+:10626000AA5BFF3971D65F4EFCD28978E17C709FC2
+:1062700000FC1FC1759387750F45FD20F0EEAF1E22
+:10628000DCA3E98F183DB827BF8F7D5DE80958D79B
+:10629000BDF9DCBEF9720DB2B98BDB37F1F4D3FE78
+:1062A0007CBD9DD00FFDB43F76FC0BE9A73EE8FF17
+:1062B000C2C5D01FD435D1DBA2911B8A1E1794A76B
+:1062C000E0BFE13DD893BB6DA3A2FC2D455838310A
+:1062D00089F3B91DF8BE353FDF6E957BF7DB5FFABA
+:1062E000BFDF9BFEEF9F8FFE33E5534DC9A0E7CE86
+:1062F000944B342F2502A893BE04D72A06EF29F623
+:1063000076F2539241E7997335BD0AFFA528766668
+:10631000B647CB69952E5D39C3EFD6B5CFACF2E861
+:10632000EA07057275F543567875E5610DA5BAF66D
+:1063300023828AAE9CA556EADA8F6AF3EBCA391D2E
+:1063400055BAF6A3B70674F563422B74F563773537
+:10635000E8CAE3760775ED27EC5375F5F9E1365D8C
+:106360007DE1A10E5DB9A86BABAE7DC9F190AEBE6B
+:10637000AC7B97AE7ED227BB75E5C9A7F7E9DA4FAC
+:106380006166B59B97A56F60A9CF008349B07EFE7B
+:106390007CC9ABC23A81D9D5950DF27D15137F4CDE
+:1063A0001EB3584793EE7DF60DE8A5ABBAEB66E158
+:1063B0007EC766593EC4E72AFCC5FD12A8F8616C89
+:1063C000BB29A06F25808AD7127D8EF8BC7DC5A71A
+:1063D0006C3CF5FB61CF7E8B76061B99EC01BCA66D
+:1063E0001C925908CAB32EC057BDE7C5BC619CD7E3
+:1063F000EB32EDFB4C55BAB207C6CE4BBAA87929A1
+:10640000F097DB01A7CDB8AF4F2995D80FA53EE691
+:10641000A9CD07EC6033CA7FAFF932EE971BE71BBB
+:106420007CBBB1F9604CBB390589E9BF437DE065B0
+:10643000DE6F64943327CDE7CC6BA03F587C3A5491
+:10644000A8D029E8990A450A21DDBEDAA0361FB492
+:10645000F4410F378BF209CCCBE1D1CBE1805CBDAD
+:106460001C267ADDE7E5A35EF455D945D1D7037F35
+:10647000118FB9D800F09C1B61A170567CFACE3503
+:106480005BA2F4BB08BADE8E741D1BA5EB39563E29
+:10649000B7D0C3FD3FB40B8C7A4ED00FFC960D687D
+:1064A00067C4DB57DA0B2E7A5F692FF876FBCA03D5
+:1064B000F87E7FF795FEEAFFCE825E7E4867417FD9
+:1064C000FC10D0FFE887887D09FE2818374A725FE4
+:1064D00012BA1BBA7CB480FBA3F1FC9147B571A33F
+:1064E000FEC81973AC3FA2D83213B4F85F1BC65371
+:1064F000857F52519E3F17D0606DE8E316F57F9E71
+:10650000CF14F4DAE79E2938CF3EF74C238F173C9F
+:106510007344F6EE80A19E4B97C31930BF2D6C5C7F
+:1065200008FDDC2926BEDE9501C6E5CF7CDF2E7492
+:10653000CA00DF4348BF4A4F85B4D289CFD7128CF7
+:10654000C747AF5F3C1FBDFE2DF9E89D828BB04F62
+:106550002ED6EFF9CAD4703C00B0A985FB291B37B1
+:1065600031B2E73736F2F2DFB4F99ED2E08F0B3961
+:106570009F542495921DDA22256AFACEEFFE37A4A5
+:10658000ABDBCA30DE03743D8BF33E38A83819ED1F
+:10659000CBB3875F750662FC84B7B5F91ED3E6FB03
+:1065A000CE2D3DF3FD2BC94DD5D2CD4531F35D74D4
+:1065B000AB98EF5017E95DD417A01FACAEDD144FB8
+:1065C000BD4C76D2BC9AB359C846FEBD326BE6408C
+:1065D00054C25CFF3279D621DC47CFE599990C7A19
+:1065E000C78EFA0DFD488FF903D4476DF097F42C50
+:1065F000EA2FA093C50DCF63F49203F517B41FC023
+:10660000787BA1BF447B078B69DF875E4B2FD4F477
+:106610009A956572BDB6BE6D2CE2C502EE583FC7B5
+:10662000A8D744F960F7A8CCEE3EE445C0E4527B1D
+:1066300053768CBE4D515CBA725AA5BB293B069F5E
+:106640000CBF47579F5995ABAB1F14F0EACA43568E
+:1066500094EADA0F6B5074E511C14A5DFB2CD5AF9B
+:106660002B8F6AABD2B5CFE908E8EA476F5DA1ABE3
+:106670001F136AD095C7EE0AEADA8FDBADEAEA1F8C
+:10668000C37F0C86FFD43D0B14A0D363A0E7D00FCB
+:106690009FF6C4630B30CED9FAFEB56E8671E38CDB
+:1066A0006BECB17C6884073338BFC6AB17721AAF86
+:1066B000BE52D35F26BBBF320BF8D7EE1A5920C3A8
+:1066C0003A3FB66F9A6B09F4BBB090CB114BD7C76A
+:1066D000F5C5FB834C81858545D17300B46C30FED4
+:1066E0005609F39908FAF40ACFEDFE1931F36E1C3E
+:1066F000BA642BF2FD46903BE4FB8D8CCF5BD061FE
+:10670000A399D3A5870E5243DB5829965E2F2F50AD
+:10671000F2A2F45AF1C44B0BD472A4D7E56EF4176D
+:106720000FA6003DCEC37746BD7570C30AFF8C1C13
+:10673000C67EBBA181CA87B4F3A84A4D4F8AF71E13
+:10674000D4F48880E8FF17623CE4B0FC658066D72B
+:106750007FFFBFF03CFBEC7D852E7E3E20A9D90C4F
+:10676000EC874A4BA892E2B99A1F6796382D5B32A4
+:106770002EF32E81E7F716F27D87B13BA8FE164176
+:10678000EB38F33783408763F4819435BF0AF7977A
+:10679000CA0C580F28574ACCDFD77EDA54C8E37F9B
+:1067A000FD5F4FBE4E623DC53A19F5A11DE705D00C
+:1067B000ECD4CE9FA2E7498F205FB1A1C07703A39D
+:1067C0007C27F84BC4738DFD05B101DA0F4E7EBEF8
+:1067D000440A15EDDC43A33AEF96E2D365E306974E
+:1067E0006246BBD6E54976211F4A7C5F01C3CE7D58
+:1067F00065E2BFBE9D283316223A1BDB07F19F18C6
+:1068000047713B695E48568CEF833ECE9D07F5AFDE
+:106810006BEB33B94879B190A0FF30F219B307722E
+:10682000915E507E99E8E9EA297751D90D658C6B24
+:10683000BB5C143F8F471F416F78EF8D421EFF13E3
+:10684000FDBC49FD38793F507E8BEAD37BCAEF50BF
+:1068500079286FDFDF717AE6DB25871E8675FBD22C
+:10686000AC24A7023DAE092E257B64417025C1B63C
+:106870000DAE8A0F817E2736F89B9B015EB3A0D0B8
+:10688000E5017A2F58B694A0E8B71AF91ADEB76670
+:1068900099FD78DE206799FC3B49AEF839882C8554
+:1068A000347A3653792110783DD889D52BE635379F
+:1068B000C7F0BB03F11B85FE8DF92FB1FEC27049F5
+:1068C000F97361CCB9C8C5CF0F7411F0E997CEEC5C
+:1068D000908A7CCBA6B9FA3AC710F38CD7BF9867D9
+:1068E000EF71F93C05BDC4F34DD9052EAEB743BADF
+:1068F00038BB2367860BF551B5A4E19968E7F2A48C
+:10690000B55B08E33C8EEF99BD1EE4CF859ADE109F
+:10691000E7720B81F3D6A746C71D2EF947F8327AE6
+:10692000D3B3BFF44A8731BA70BDCC1D747EF480F6
+:106930005394A11EA03F9B9F27393CBC5EE0911958
+:1069400008313C7F1AE0632E7C64C276682F0FE822
+:10695000524CF9A0EF7CD90BDD63A03E3BE03679C9
+:10696000A97CC29C81E7A35076E1F8D9270E96A3B3
+:106970001FE1BA54827ABBD973E2D06446AE26EDE9
+:1069800047CC7302F55C674F998519ECFB9D093D77
+:1069900065C50EBE71E7C89EB28AE5EDDAF97BA542
+:1069A000CF73A299C761A7FB907FECE159B9E9E8E1
+:1069B0009F482EB44BFB7BAED55F3A76E63D7E68B2
+:1069C00024DAD36EB337C7837624D3BDB7C667A5A1
+:1069D00076AF1605E6233E89EB4F93DB7E4F5E6A6A
+:1069E00022F243741D428675E074F7E786B473BDE6
+:1069F00010ADCB08F7976A058C37A29C9BB5CC935A
+:106A00004AEBD2E95E47E7829D79DABAE482570F12
+:106A1000E504403313ED7BED9C75402E3F3776D96E
+:106A2000B87FB3C2C7F7DFDB7CB206F9FE97EC7E16
+:106A300080A1BC3B2A4DD43E5983D1F973B9BECD58
+:106A400067D6F64B4E8FFB4B0337FB62FCC4C3CDBE
+:106A500026DA2F3A9B47764A12AE836B462EC01F2A
+:106A60006B7924B04E57225D0E7BD312027CDDEE93
+:106A7000E873DDB4795E68DDE2AD97F033E2D55FAF
+:106A8000B340F687C86E0B3C381FC6BD715F5A3ED7
+:106A9000DA6DC7AA645F179457FF3A93CEB5B7680B
+:106AA000F45A633A3D10F7D94DCE2D7E84B67D8DD4
+:106AB000CA101411934787C79AA72B68FFBD6B4074
+:106AC0005239AEB7118F635FBF91EE87FAD97FB6A7
+:106AD00091BC63A005E332B5B48834ADD7306EB352
+:106AE00058B3537EE9E3F6E36B1BAAA89FC5C28F98
+:106AF00001C1D5F4A7F40D3864B5D132D9252CC81D
+:106B0000E33176F88B7ECE3133980630AF63AA44FA
+:106B1000F1A63AF33C2B8E57A7EAE3364BFCF997E4
+:106B2000A1382C6DD33F5FA6F93DCB0CF19F6BAB29
+:106B3000EA7AEC99B32CAADF9859B198800F0E5FCE
+:106B40002931B41BE6FB17F867C4D8F36FFC4DAED0
+:106B5000453A1CC37711AF9AD13B309FC4480FA967
+:106B600088F3E76B1BFC6467F6D08764E1C274E8C6
+:106B7000A1D7FF113D2E9367111D96CE93C8BE334A
+:106B8000D241F8AD623EFF2BE6C9BCC706007E27A6
+:106B9000DB2D443F169E4AE73C73F8ABB1F322FF6E
+:106BA000D4057F793CD4D39206E32D0362A21C5D09
+:106BB000A55A747EED32CDAF5DC2FCC96189E6F5A0
+:106BC000419C79E9FC5B23DEC679CED6F60BA31F88
+:106BD000CCCCE13CB463FEE4D3E2A7E3799CEFAC18
+:106BE000EFAAE430AE1F2A8F3EF4AED11F167C55BB
+:106BF0001B9CA7B39F2516E829BBC0AEB8C92D7B47
+:106C00003E4CC37882E54164C379F66E33C5A9E58D
+:106C10009A6494C779CCEE7142FB3B61B1314E3A34
+:106C20004771789C31F89EE9902A516FDE04DD05AA
+:106C3000296EA6905F50ABD1FD26B795FAAF65EAF5
+:106C40007EA423F0DB97B1FC168F0E038B7AE63F10
+:106C5000FE62E67F3FDAE23CCE19C678C669C91EFD
+:106C6000DA2145E354F04FD50AAA726C5196A697E3
+:106C700015FD79156B207BBF1F71ABB1457DC4AD90
+:106C8000C479BCE0CFC5766758E67C77AA873F74A5
+:106C9000E7F1018671A9D6C1ABBC48EFD6041E97B7
+:106CA00012FB24D8B325182F6C4DE0F129A1E71D64
+:106CB000B8BE32E6B9805D1843B75EFBF4C1EB762F
+:106CC00075825C049C667637B5CA25FC022E81DF8E
+:106CD000690BF6531BB49C89ED2790085A05E6BF53
+:106CE000C4CDF3095A074F745199713F9BA9D03E07
+:106CF00026FE1EC065C4E7768FAE7F6C4F76595B6B
+:106D00004CFF23098D630AE0D57A9785F0328EDF38
+:106D10006BFF328C67ECAF55CB2B9313AF5B41FE0F
+:106D2000977BB08B6CB25CEEAF2C2C32E9F69D25D4
+:106D3000F634C59C162D7F30C85915BB7F0B28DE55
+:106D400013F48CDA69619D9D764FCB53270E0D8B22
+:106D5000B1D3D4A74E607CE11FB5D3D4FF7EEA4403
+:106D600033D9390DEF7D0FE3B42FCA4427913F6229
+:106D700006B3223995FC3215A13D3884E623F2484A
+:106D8000D23C5E09D7ABADC8C3F33B3DFC9C35CDCF
+:106D9000EC95BCF07C8B66EFD01FCC7348757562A8
+:106DA000FEA1CDCE9A1DA9F81E9FB718AFA7DF5C34
+:106DB000AFE4CA8B1FFF7DA0E8A2F3671E28EA2379
+:106DC0007FE6B089CF5B8579635C7E91FB767A6ED6
+:106DD000F4C7B66BE39D6481EDD84F57D5AB8B6E8E
+:106DE000C338C75E1BC55DFF50F5EAF2FFF0207D9A
+:106DF00060BDF1FD05F7CF2F4E47BBC44C7660DB7D
+:106E0000301E7F911B25B22F3679AC957B017E50C9
+:106E1000587118FB63951E13F2F39904CECF1F141B
+:106E2000CEA0E75FBDB3D1BD04ED477702E5DFC972
+:106E30008D59F7629E217B01F06528AF8CF6EB56E9
+:106E40002B87CF14F17CC36734BAFEB288FBCF6DB9
+:106E500096406E431EE6ED023631FC6837AB0CFD02
+:106E6000787BC44CCF6549223FAB3521907B4B0CDE
+:106E7000FD44BFF6080871615FEF5BE939CE8BDE38
+:106E80004FE5F88876CF1771FBF4790D1F7B64000E
+:106E90008DD79A0A783963FB49E2CF353933CA492D
+:106EA00041D1F497501F7E50A81C2E2279E9B6A03C
+:106EB0001E5DEC3E745C4AEA8F1EE4F1F9C4AFA596
+:106EC000F008CCBFAE904377013F2648AED93ED400
+:106ED000E91516CAE7E8CA4D4FC47395A366572251
+:106EE000FAE7EF14717BCF3F53263FDB5F61217ED2
+:106EF0003E9A7BDD2332B709EDB1FB51AD5D0D69E3
+:106F0000FB50D40EE2ED3CE662AD1DE0553B43562E
+:106F10001C49BDEDA3A379A9B37DD0BFBA5E267F7E
+:106F2000A676A67C0C8F0CC0DC3F186B8782BA3823
+:106F300088E7D0EF6AC56EE6B24E97A276486D50EC
+:106F40006F1F31F45E8AD18EE07F7AD9553EEF6FA4
+:106F5000D33C488FDD95448F712617D2A3BF761698
+:106F600063F7119D06CC7CC2857ED2ABA817D0DF1B
+:106F70009AF1AA427ED4CCB366A25BB9C45200CFC8
+:106F8000F6A0892930CE669F2584E7DE9B73BB5F20
+:106F9000988AF2E8337BC82FCFEDBA7A3AD51791A9
+:106FA000FFF10A0E5146EDF9F989D319CAC1FDBDA9
+:106FB000E875FBD2187ED9ECFB600CEE73DB353E36
+:106FC0000235E89C591CA51BD2C7434A94FBF10724
+:106FD000EF48A0F57CAF5DD6CE2DC010013A27BAA0
+:106FE000B93CCED4CE35963E2885309EB8B4E8580C
+:106FF000850DDA2F6D91482E6BD7CBEFDB38BD7541
+:10700000765BA0C14FF6449D6AB0E7347B0F3AB778
+:1070100022FFF6D7DE33DA2FE38BB5F38C0256105E
+:107020006BBFC4F3AF84FDE204AA17C3BC9798F901
+:1070300039232BBF8AE83A533EF5C25498D719DF5B
+:10704000C89148879F6871D8CDC113765CCFCD5F5A
+:10705000CB24DFCCDCBD12E925DF39310DF5F9FE9B
+:107060003B2ECD3C09F597175BA9FD7693E73FCA08
+:10707000917F5FB4905E8D878F3D28B36C9077478A
+:10708000502228D62331E860E6183D9388E7A130E6
+:107090006E86EFB4343246AFCC2FE67299B29EFBC7
+:1070A000D3193EA678D04FCC1EB903FD5CD89028EA
+:1070B000CFD691E52940FE11ED079978DEB87946E3
+:1070C000833AC483E726328DE7013C707FCB0A0EFA
+:1070D000A0F2C8601AC151C11482D9C121549F13B2
+:1070E0001C45F09260163D1F1D1C4BE5DC6021C164
+:1070F00031C17C82970627111C0BFB1BB6CB0B56AC
+:10710000101C17FC2E3D1F1FBC8AE084E03C82DE71
+:107110006035D5E70797122C08D6D1F3C2E00D549D
+:10712000F6056FA67251702DC1E2E09D044B824DB1
+:10713000044B838DD4AE2C780F952706EF27382982
+:10714000781FC1F2E036AA1776C6CBF84FB0F3E647
+:10715000A42C71F1BC11AF17FD82ED71F4EF03C5E2
+:107160005C7F9B8B95F5C519D176B296776F6CD7FE
+:1071700051CCF7A114ED3CDB640FDB47915F3F8AF4
+:10718000CE63B683FC63FECAEA9C913B508FDEA3BC
+:10719000AD8FC3A22A43B2A27E7CCA0CFEBDC5EA53
+:1071A0007D6BF9794C695ABFE2427716F3F7B79BCA
+:1071B0005586FBE6F60646F93B8EEC2E09F543674D
+:1071C0009EA912F5F93D7967F6A33CCF2E52300205
+:1071D000036593C94E7AAAC287781E28B6D07C5E12
+:1071E0002D52B6E1BC47F832BE7315D48F6836B95C
+:1071F000A09AA5F82C14E749816151AF89B84B6773
+:10720000827E1F7C5AA30B68EA07F0FDED83B30B67
+:10721000B8BDCCBFCF90EF1C497EE5766B5832A34A
+:107220007E0387E761A1EBB17DEB924750DE46B666
+:10723000799F45FC46A8DE42C4F7E9621EDFCAEA30
+:10724000F04C730042A3B62ACFE2D9424E28302D2B
+:1072500001CAA377A9CF221CB33B346D00C0B1FB98
+:10726000C2CFA2DB332EDC3DCD09E50987D801541E
+:1072700003F95D9EE989502E3CAE1CC0B076517773
+:10728000607A12AE9335D49404F86C7F97791BA181
+:107290005C765A3D40EA535B871E3EB0B106B4BFF0
+:1072A000EC9E0E05E93D749D8BE237C0095C2F987A
+:1072B000BB1D29145784F9E2FC60FD51CF0F554ED8
+:1072C00013FD87FA5801909075360BFA67119F7C71
+:1072D000ACF105D0FF25A47F6782AB02E352A7671C
+:1072E00032D70EA89F338EC7B7AC2D23691F11FC70
+:1072F00006741D332F3196FE5C9F6D37D8A5F1E8DB
+:10730000FAB1A6CFFE7FD3D548CFDB343E36D25577
+:10731000D0338CF328BBB0FC46A2F2FB65ACFC1A60
+:10732000DB0D2BE17432D2B9D3C40EC15E13F3BDB1
+:107330009189617CC85D62BA28BAA696FCDFF0AB81
+:1073400091AE5F205D8BE2D3958CD141F89E2B816D
+:10735000F591F724F40CF687F3EE4BBF318A5B66A8
+:10736000EDC07C87D11A5D3745EEF3637F42BF994C
+:107370009F6E54701F12FAEDEC85F4160E4DF16EEF
+:10738000279DB338B5F80670C2AC5C1FFA03522AC9
+:10739000EE7745DA781B7CFEC2123A37633E3A1725
+:1073A000F3EAE3EFB3645705EA1B364922FB776E35
+:1073B000F95145A6F5F214F0EF88F8F9A37C67C2FD
+:1073C0000E5CCF2CB01BCCC007F0CF30C264B63BF4
+:1073D0004C7E49332BC0FD9EB9EADCB17227F6F52D
+:1073E000A85C0AFE48257F10F916DBDF5E22E9F271
+:1073F0009F288A8EFEFBED83E99C53BCD7E91C4A8B
+:10740000EFDD5E9242FD5A87D4E7D6E5C5E7E78710
+:10741000053F373F4EF41D50CEED85E4E654E2EFD4
+:10742000E4198181D87D94AF975891AF6F2E913533
+:1074300039E07A1CFCE85AFCEEB33395433AB04489
+:10744000BD3364E80EAEB7FBC7FFD3FEC5FC3FAD4E
+:10745000C4A3C963DF7230A2DCB51FF3D146CC6090
+:107460002E0FCA7539EE61787E6125FDC9D0FE8583
+:107470007232B037E66F025DC3182F554D89C46F65
+:10748000B2AD7B06F18B2D85FC830DBE4063C979BF
+:10749000F453ABD593CFC0E40AFDEAF96A67197ECD
+:1074A0005F00F2044B776F4957757B29D2B39B6914
+:1074B000E56D58FF8FC633A0FFB7F0DCC93580C734
+:1074C0000DF01C39F65CFAFB1A1FFCBE587900F16E
+:1074D00005B90821AC606C9D09BF77F896711063FF
+:1074E000FC43C8D985EC14A13FA2F2EECA17F28E74
+:1074F0007C0DFAFA6724BF5A7FF1ECAE2B4BB8BD76
+:10750000F554C985ECAED40A33D74B9A7C73F9DCB9
+:10751000C4F8394A3CBDF453C15771F452A2BD635B
+:10752000EB4E168DF7DA35FA09FC1C6EFE1D6EA2C5
+:1075300016EF5D8FF15EE037C72C46FE933D9B3F13
+:10754000C73F7DC77D43BAB88F88FB32CD5FBB593B
+:107550007BB7E32E6F327E5FA2BECCE324E2FB80DA
+:1075600059F86FC057F24AB44E1DFFC6E574F65085
+:1075700016BA0B5863D65F24A6407F87FF221334C8
+:10758000C66D67C37B68A71C96EC21BB84DF49D816
+:107590009815CF53124D9ADF181E3A1CCB05368A28
+:1075A000F31FCC2FA1BC1D63DE9D80D706EAFACC69
+:1075B0004334CEF3DA45CF3991BEDB5CD3EC59E4EA
+:1075C000F7F2734EABA6F77BF6F712AB66A706CEC3
+:1075D00020BF245E77BAD98A6AD9C5CF39999BF37F
+:1075E000CF20E7DE17302E3AA89EDBAF8359A8D113
+:1075F000E5ECCD97F79706BE2E81FEB68973C47A67
+:107600006E67B579F83962C59AC1E523A1831FF485
+:107610009C2306BEC0F64ADAEE7CE4A36D7FD9E770
+:10762000C0BCE173ECF03AF22F0ADF49F760DCBB33
+:10763000E8B90CA4C76C03FE028AF89CD1DF7596EA
+:10764000EAE3F5222F395EBC5EC40D85DF8B714104
+:10765000571FFB8391DE62FC1A6007CA13B048A46F
+:10766000F70E63D332D21BC34BF97EAAD87DA83F55
+:10767000C651FEEE115F219D67306F9AD88F87C685
+:107680009E930A7CE0794E5FE7A73571F2948A4AAF
+:10769000B9DEAAB170BD26AD7DAE06D7A126DF2624
+:1076A000D9B2A27C5ACBCFEA58B6D6BED6BB91F29D
+:1076B000BD8DE721D9A53C1FEBB0253CD4A5C54B1A
+:1076C000BD7DF0673CBABC695617215DDE0CD85C05
+:1076D00098D771245092C9FAC05BC013C81F399C57
+:1076E00076D85FCFBAA1B3DEC7FA1FC7FC354BEF20
+:1076F000F3A69EFA3A07C5D1AB0C79218B4BB9FDA5
+:10770000B04D83CCA6E6621CB96DC98376360EF304
+:1077100042CE14A989A8E74E17EDA0F85A22C52732
+:107720007AE857CAE9575577AEA83126EFADF6C0CB
+:107730002617F26D55567306DE2B60A4E7B6523E4F
+:107740002F87C6CF4EA6044A63E32BD957737E38E2
+:10775000E0F086615CFBEBA30A70BF17F115EC97B4
+:10776000E7D5F238F03AED5C03754C2C5F570557BE
+:10777000EBF4852322B1506CD9DC41715447C44CE1
+:10778000CF8DF233BD548B1769F273ECEB8D2EE481
+:10779000273B9E7BE745CFDD137353E99CFD58954E
+:1077A0004C765F428E8BBE97FE4929DF57847E1749
+:1077B000E777C6F338710E976838D773E4DACF7B72
+:1077C000AE27E61B3DCFD3D3D9389F7F2F8D737E55
+:1077D0001787AF043F09FE8AC7AF82BF8CCF057FF2
+:1077E0001DAFDB94EB41BE4AE8DBDE7C4C6B27CA65
+:1077F000C67C0371CE6E7C6F9D26B7670365244FF0
+:10780000555635A73FFA4AF0C585F22BAEB5F2BC06
+:1078100058E3F350CFB83FA0738B9B8B4C2EE4BF43
+:10782000CDF09F8A72E2B3509ED49B5FDB18DA8161
+:107830008945A687EEA2B86BF3B0EFE3FE5967A3C4
+:10784000738E30C8793DC8F9264DDE7BE2B4ED7207
+:107850002807F70B26E9CE896717F138FAE607F211
+:1078600043E81F2564DB75F59B8AAE4C0E53A96374
+:1078700036DE33B0C4C3CF17AB183F1FB4FF6DA3C0
+:107880001FF97793A5C39DEF8CD2E140CE9F1231B3
+:107890005F8749D173680FD877E1BA9281DDC4AFB1
+:1078A000FC7CD2EEE2754B8B0AE91CB21BF365E956
+:1078B0009C5F8B17332E874BB37C03713D449C3701
+:1078C00026BEAE8BDBC68BF3F637BE2BF8DFC8E7E0
+:1078D0009FC7E1F378EB1C13E7FD23EE533D7AC815
+:1078E00073B54E9F08FD23E4E18436FFE339DF9F43
+:1078F0008DE74EC79771EBF040CEF78F6CF0517E5D
+:10790000207DBF6CFFDB4F66221FB095529FF1DDDB
+:107910004942FF621E406E94FE0B022B7BCAC8C612
+:10792000D52BD6EAF2178CFA3FBE7C9E5FFE7E59BD
+:10793000CAED20B13FE03E90EAE4FB802931CAEF76
+:10794000F1F603A1FF8DFB82711FA8AA6BF1AAE3D8
+:1079500008EEC27EECA312E87E20A3DE32EA753187
+:10796000BE116F474466A1B458B9F4F07DA547AF86
+:107970005BA91E1918FDAF204BF0A2DDF1F742659F
+:107980007C19B44BF3291310FEB450F196C5E89F4F
+:10799000260BCFBB954D2CB087FC53BF2E5F776E67
+:1079A00019C7A7A582B7DB9F51ECFE0860D3FBF98E
+:1079B0006E0B8C3BBF8C9FFF1D4C3C7F5EFEBD1A47
+:1079C000FFDC837A08E55F5B47E1CFC3F4158CBB2E
+:1079D000B458FC6EF40B93CA1EEF1A09746F7299B7
+:1079E0005C124CB5B88CF34D93CB4C71D966A7B9EA
+:1079F0007227B567A4475A12958755CDDE999F889F
+:107A0000ED395E66A73E6F3568566D48AFA09D9F05
+:107A10001B18F1ACD6E63B4EB347C4BC8DEDE696E1
+:107A2000F1B896DBA72C44BA1E2C54E696115F3BA6
+:107A3000E93C91C6932FFE7B9F232581E5D8DF5734
+:107A40002695A1BFDD94589C8BFB687FBFCB5AABBA
+:107A5000D129E6BBACB5657DF053CCF7DFF43D58DA
+:107A600085877D1942A4B57B0E443E29D8B3417C5D
+:107A70009FD91BE6F795A7B9E502F12F117F02BF49
+:107A80007A43198F373522AC2865749F8EF05BB727
+:107A900098BAD9F9FA013AD179703FEE13B9B72CF7
+:107AA000A3375DAD490D13B0FFFED2F187BDE9F8F4
+:107AB000C3F3D1F1AB774627E33E21EE4131B61354
+:107AC000E7FFA2DC96A21FBFB580971FD6C61DAAEE
+:107AD0009D873FA9F1A3F097C57D1DF659FC1E199E
+:107AE000914721FA79B22C91DA3F5332ED49C4B76C
+:107AF000358BDF13D19AA2BFB7625D59C59348A7F2
+:107B000027B4FE9F447ECFE0712CB43F447C40B448
+:107B1000FF9ED6FE7B65D39EE47CEE19837C629546
+:107B2000E53EE9F84C19B707C57785E2FBAFA59BA1
+:107B300065DDF75F3DFBE8AF19EDF7788E8A721CC3
+:107B40002F5F2E90EBFA2D8674CEB13C91FFF7ADEE
+:107B5000F655A4E780D4DEFBEAB1B2BEF3DFE2E97A
+:107B6000B7987DF5EDB258FB9E79757126B1AF7669
+:107B70001BCE7F043CABAD7FBBE657A37E44BD8CE0
+:107B8000F757917E3673BF734B128F7B22DFE13D37
+:107B90001867CBF4F932222E25E251223E25E2511C
+:107BA0003DF7BD18E252DDD6EE964C58A7D36318C8
+:107BB0007DA799B27EED7E0B9E5FE5B2025CA7D6F3
+:107BC0002C96548AF5F9262FC6FD53AE76B55AA0E9
+:107BD0009CE261A9B8AC16BC3F04FABD6462169F72
+:107BE000877AD5FE4C6857D7FC47B20F07967B5271
+:107BF000D172E8ECC93FBE8BEECD11F31F3091D3AB
+:107C000027D9C3E3B0CCAED27B8A2D25FF6E16DB1D
+:107C1000CEA4C5AF958489C48F3C5E9DC2381F3108
+:107C20002F8F47CE655D94A7D66ADA4DFA656CC989
+:107C30007417B6177283F781ED8989CB1AF3900612
+:107C400069E3C4CB43DAA2C5DB5AA1BF3D14F715E3
+:107C500071C23409F185F6CD9654A487BE9F9E75F6
+:107C600031C40FE3C50B136AB8BC1BF945D1E895C5
+:107C7000ED53C64E4459FBFA9B6FE4E2E87795F06A
+:107C80001E437BC0919E48F15B87879F7B3397C4DF
+:107C9000E344561EAFB35EC20A1B3D9887EE6C9359
+:107CA00080E9D875268679BDD3B57E942A26FD2E27
+:107CB0009748C9B85E36B3DF09799135E2C1B8D3C8
+:107CC0003452DA60E907009DA63B5FFCB304F298EA
+:107CD00099CDE3BF99E9C99417B1254E3C5EE47D87
+:107CE000F5E4B9A9E3DFD1E5B959C6BCA3CB736309
+:107CF00063DEF936796E8B268E79E75F99E726F495
+:107D0000DF713970FC4EA0FF7C505AE8CFCE871E41
+:107D10006B286EE926BA5DADD159FD0BD0D91EA5F1
+:107D2000F3FCA75F20FA1DB7F0FB492CD338A92D2F
+:107D30007724879AC8DE0951FFD7D83B66621CEDCD
+:107D40000BEBE9F138EE8DBF7AF497687FAEFAAFAE
+:107D500007933049E25373C7407C5EFF704B127E3D
+:107D6000BFF189594D423BE8D3905CD9175F3D3252
+:107D700051D8E98A5302FC566BF87D02FA07BF63BB
+:107D800058F9A62DD408E3AFD9650BDB60BEABF77D
+:107D9000AE247D0DE5F7797923E9E135FBF47A78B6
+:107DA000D54F1E1CE8E1DFB30D31B969B986200952
+:107DB00056EFB450FC63F56BB21786616BD8E95689
+:107DC000C4CFF83EE211013AACD92DD759937BD7F5
+:107DD0008366B2E2BEB446DB07D6ECBDE2636496CE
+:107DE0003506BDBF228E3FF5E0442D0E52C24A90AB
+:107DF000AF813E74EF830A7891FB17CA207BA6E916
+:107E0000A73605E3BB9F9EC8EC44BFE7D4CE97924C
+:107E1000A4BCE83E20EE573AB57B54F2F9BE67FDAC
+:107E2000C3062E2C517B87AFA7671F209809C5A7D3
+:107E300039ACB7849326017DEA3B2D5E151ED73FF2
+:107E40002A2B6882315807F49F6F78F4B9631301C5
+:107E50009F1BF658D267F1E938A581D1755B03FF06
+:107E600021DF89755AF5C47356CF38FE1CF363C5FC
+:107E70007ADDB067BF15E36146BA4EDFBDDFCAFDEC
+:107E800063C3BAED7EFF32E4FFA69F7E6545BEFC6C
+:107E9000F419896566F57E7FC5C32F2561BB0BADDF
+:107EA000DFA99D03C84E38F5B444FAEA42EB780BDB
+:107EB0007E7B9941FCFED85330FE8A13362FCE7F4D
+:107EC000C5633727E13C3E363770BEFFCF9681A8A9
+:107ED000275658D4812E82FCF98AEDB7103F5E7F79
+:107EE000F416F2F381DF07994A699E83707ECB7E98
+:107EF000349FE6B7E23F97D2FCD80F2486297FE76C
+:107F0000CCAC724F1FEB3A7C12D7C71FEFB0D1E653
+:107F1000FDB195CBABFABFFCBB37B0D049DEC5771E
+:107F2000AB14E182F2393B5FA7B31345BE2FCF1BE1
+:107F30005CA3B55AB373239D8F7C364CC9C47D07AF
+:107F4000E8A0CB1F948FCECCE4EBC3F308E93DD07F
+:107F500007D3F139B6EFB2288EF1BAF734FF938F19
+:107F6000BF4E1B1FF04E9026001CD8735ED985783B
+:107F7000AC96F83BC83F981F375B9B678FFCEFDCE4
+:107F8000C4D74993FF2F5FE37A6575685E25E9855D
+:107F90002E4B3813DB85F65F2D915EB045BFCB8D40
+:107FA00095EB9D168D2FF4F58097598AA5E733122E
+:107FB000C59DD6ECBD87E2D8CB1F80F631721CE59B
+:107FC000176BF47956542E457CF27A431C5540A326
+:107FD0005E704FD2EC414D2FF4C4377F9471DE7840
+:107FE000A2F05FEA2DA1477E88F2FBA68DCEC5EAFE
+:107FF0001FB550BEE8E7BF38706C21F0FBE7BB85CA
+:10800000DCEAF5AD516E573C3E9FF525B79FA7FBC7
+:10801000599F720BCFFB94DB747E9FCD3F4DDF6A7F
+:10802000EB104F4EAF8FA36FA74FD2EB5BB0EB932C
+:108030002741F1B39FDD3082F2B90CF4157435EAB3
+:10804000CDB7277AFAD49BF0E73516434F4147C1A5
+:10805000AFAB7E7E238DD3C3C7825FC53ED6C3AF91
+:10806000C679EBE969ACB7E22400758BC96BC74FE1
+:10807000C21666EC4C447FA549DC6FCABC8730143D
+:108080003D5F19A5E5797179D7724CD9A64962FF90
+:10809000E5F227BE23B205B81E6862268A8FDB98F8
+:1080A000FE1EA1973396F37B8134B98EEA1913F93A
+:1080B0000D5DE9A58F68F912A427E86E10137E57AD
+:1080C000B399E8315791890E3685E71FC7F44FEB16
+:1080D000D8A49C1C8AE75A4DA5362FEA67684F74CE
+:1080E0009A1FE0F49CAF7C97DFDF947EA80AF3AE82
+:1080F000E796EAE578A1411EAFADD2D75FC37664BB
+:10810000A0BD7ACD0A0B0B496827E9DBD74EE2E721
+:1081100053D7B2861617E76B8D4EFAEF599876EE65
+:108120003B47D36B224FF7959D12F99FAF942E6D6D
+:10813000CFC7F22FC0AA84FA73E585CC0E7478D924
+:10814000C2F691FDAB281E5731BF1714EBA5D2E73D
+:10815000C90E4B2E35E9F44C8A92A0C33FAD32557F
+:1081600057CEF00FD6B5CFAC1AA9AB1F14B85457E1
+:108170003F644581AE3CAC61A2AEFD88E0345D3920
+:108180004BFD8EAEFDA8B62B75E59C8E85BAF6A389
+:10819000B72ED1D58F09ADD2D58FDD7593AE3C6E9C
+:1081A000F71DBAF613F6DDA5ABCF0FDFADAB2F3C55
+:1081B000B445572EEAFAA1AE7DC9F11DBAFAB2EE66
+:1081C0009FE9EA277DF2B8AE3CF9F453BAF653239F
+:1081D000CFEACA15EC255DFBE9F65775E599AEB710
+:1081E00074ED2F779FD4D55FE1F95C572FD6FFBB95
+:1081F000B96775CFD1A152811F56F1476CB6F7AF61
+:10820000BA7ECCCC4FFEA5953510B4635E23C00476
+:10821000C6FD4E27FAA100875D1EF86012F2EB76CC
+:10822000B51599EBE5B2AF86E33EF24AF955BAF3DC
+:1082300032BAC7CB0310EF534D8AC67D9222320B60
+:1082400017021F462482AEC80016067F2425E220AE
+:10825000981A49A3E769911482E99121F43C2332E9
+:1082600088E0C0C8288299912C82EEC85882832267
+:1082700063080E8E14D27B4322F904874626D1F37D
+:1082800061913282C323D3E9F9884805414FE4BBA9
+:1082900004B32257101C19B98ADA8D8ACC23981D91
+:1082A000A9A6E7399105042F892C25383A52473081
+:1082B000377203C1319195042F8DDC4CEF8D8DAC5D
+:1082C000259817B9939E8F8BDC4E707CA489E0842F
+:1082D0004823416FE41E6A971FD944B020723F3D86
+:1082E0002F8CDC47D017D946CF8B223F20581C79E2
+:1082F000886049A4936069E4E704CB223F253831C4
+:10830000F204BD3729B2876079E47FE8F9E4C893C5
+:1083100004A7440ED0F3A991FD0495C84BF4BC22E8
+:10832000F202C1699157E9F9F4C8518233226FD141
+:10833000F3999137095E163949F0F2C8FB042B23F3
+:108340009F13BC22F229C1EF44CED27BDF8DFC917A
+:10835000E0ACC85FE9F9ECC89F09F6F809E571BF20
+:10836000E7337D03F03EBCB41FF4DB9CF55CDFFD1E
+:10837000C7803F1C24FD5766F3F03D662BF1598DF5
+:10838000C6CF2DF83FD867F7977D3C14EDC5D68A48
+:10839000936FDF8C76D65A1BCF93E9A54FBF766AD1
+:1083A000F626C3FC99451ABFBE527A2003CFC35AA2
+:1083B0000BBAEB31BEB539ABBB06E165E5DC5EACB3
+:1083C00028E7FBDA8C726EE76E9B1C28BC1C9EAF04
+:1083D0001A6652D1BE5895E449BE169AB44FD2EEF1
+:1083E0006F4F4FE5B901CED3C3D1CE58ADC9D9EA4D
+:1083F000A79F3F8EFA58027109A21D24BEEFD9A78C
+:10840000A78B0438D5E07DCCCC6BB7631ED750E684
+:10841000E1F75AEBF78B0BC595F3CA030BCBFB883F
+:108420002B47EFC956FB75DF36F4B3F49FD44F7D6D
+:108430007FFAD9987EABBF0E8B66C53C1BD6A95A76
+:108440005B27261F5E84EF9D536D1E8CF557ABD7BF
+:10845000935D64ABD77F7F5C0DFAAC02F6DDEA7505
+:10846000FC7CD3582FF6D5EE7ACE67DD4A831DFD0E
+:1084700093EAA1266A5F6DB88FAB11F809DBBFD50F
+:10848000C8BF9759A2D98581FACB293E1BD0FCBD24
+:10849000C005BE6FB9BBDC608F6BFC592DEC1D793C
+:1084A000FD213CAF3E7758A658CA810C2BC3FB80F8
+:1084B000BB6FB4D1B8AC8DDB956F65FC729827C6E5
+:1084C0006FAF03BDAAE039F18DB7B991BF37B6ECF4
+:1084D000B160FCA47BD85AFAD8C4E8A7770F63E44C
+:1084E0004757AB6BE9BE4A960B1C3650B3AB3C68A2
+:1084F000FF7976A39DCD86DBE97E3FD9A43F674F08
+:108500009ACCE540C0F7302E8572B79AE715594CE2
+:108510000DF43D291B9E60E2FEA35A8FE5EBDA477E
+:108520008F443BAED2CCEC98672BFA8BB1D712C8F4
+:10853000DF31036162EC3CA33DF764798A663FF169
+:10854000EF8E4F6AF741E11F49CC83F21F152BE6EE
+:10855000E1DAD2EDDC2EEC987703AED77B3DDF512C
+:10856000C1DC8AB5FB5380E0D5EB072863A0FE1978
+:108570004DDE2D5AFE12F08F1A6B27237F61FB11FF
+:108580009385BDCBE71768B779300EDB273E26D63B
+:10859000935F1B684F0951BC36DD4C785986298B97
+:1085A000F13CC2A6027EA80FCCA76FA9C373073502
+:1085B00085E27A8166E932D44FB6F6C6B5588FF7B0
+:1085C000769953E9FE5FB315E858C75C97B991DE19
+:1085D000ED3CDF59372FD027D5ED12CDEBA4A6CF38
+:1085E0006007588CA9734B559ED707FC40E3B77CB6
+:1085F0002F51E1F8499DB8CF8BF5A9D6C6ADEEF85D
+:10860000D56D12F1393F27A8D6C6AFD5F236E3D1E2
+:10861000C9D54327E5DD377CBDC715F80A3AB5480B
+:108620003C3F5BDD2C7522FFD8D627521C40CCDFA7
+:10863000A6E13178F2489A8FA04377E3B5557530BB
+:10864000AF0F378FC65FBAE9850FE99018FE30F299
+:1086500095C5C4D7870D67E4A70BBE17FCE298CC7D
+:10866000E3E1025A270B7AC6C427E4285F1AFB17F6
+:10867000FAEDF2D8F6F0FCF2A13C1FF53D2DBE2B31
+:108680004F6E5A8CF7BC3F54AEED279E06BAA749F1
+:10869000E0838424F9D0F8D6E6B42B63801E191A3F
+:1086A0009D5B243FD141DD6C237E30FAF97F2AEFB8
+:1086B000F1D302D6624DBF9AF0B9879E57B7DB88D7
+:1086C000DE62BD3FE8B9E74A193E8FEEA1D2E8A8C5
+:1086D000F1D7AB1A5FBD8AEF17D1FAD1FDC2EA7D9F
+:1086E00036D207627DDEC32E407F7927FBC74E2E30
+:1086F00022F91C4F7A7F3DFFEEA6C6B43F07CF4B51
+:108700006BEE0A138CEA2D4EB7CAC1E21E1B2FE591
+:10871000AFB08689948720F264CFB617D1796620EE
+:1087200089B793CC81122C57FE7D6909C67FD98900
+:1087300044FA3E67D128567B659E965F08F82C6AFE
+:10874000BAA212E7395DA3DF2BE0A72BA3193BBA2E
+:10875000C1CE1460965737B8A8FCFA063795DFD813
+:10876000E021F8E6865C821F5A397F2C4A1379DAB9
+:108770002EFA0EF20A4D3F5ED1C3FFEBDCE87757CD
+:10878000FEFD55CC4862E9EAC38B674E267F9452C2
+:1087900078049F565D3D403B0CE1E53AFF245D7D4A
+:1087A000B796FFC0720BA3CF4772BE40FE5DD29654
+:1087B00045E76C0B66A5E9DEBBA66D88AE1C98CCC0
+:1087C000D76B5EE528DDF385356375E53AED7B68AB
+:1087D000E629A5FD4AC4DDC012E5F4D7F28E6E5E2F
+:1087E0007B79F26D30FECD4765AA37AEC3AD4BD570
+:1087F000C588DFAD0FD9BCF83DC2D2AD1253D388C6
+:108800007E7CFF382693DC5DB755660118EFB31404
+:10881000253319BAFAC4C1E7F5C9EB7227DA0B950B
+:108820007F1FC5F7A7476CB43F7D6261AA8BEEB18D
+:1088300092487E3F3B9A43DF752C1A151E86DFB5A2
+:108840009FFE6F079D0B2EEDE6E331A980E21F9F8F
+:10885000A4302505F8F2F7B33B9653BEBC7C380331
+:10886000CF7B7EFFB84CF779AE5CFB7AB10BE8BAF0
+:10887000EAB7BB8F618ACB871D327361DC6B97AD22
+:10888000937F27AD64A23C44E7191A8F7CF9E24438
+:10889000FFC6C9B0DE9F2D0F8D277F7F7D06B717DE
+:1088A0000CF4F8D01A28C178BC8A7C09FD056E4DFD
+:1088B000B4A31FB7D4E21D984F7CC4E37E2AF30D06
+:1088C0006214DF7D9CF8E7C3F69CCB483FB6490CA9
+:1088D000E3E8A27F90A73948C70F3BD24CB8FE4BC4
+:1088E000DA65FEBB2DCC6325B915F7E6DC2707C09A
+:1088F00006C1F7033CDEA45F4790D04CA4DBC697CB
+:10890000F93D138BE3C41BFF00B213888967ADFAEE
+:1089100035BFEF88F93CF796A31DBF737A11E55D6B
+:108920000478FF5FA60ABEE1F73C9D51780AF7B9CB
+:108930009D8921E48753A6C7DF35C33A9C3605F6E7
+:10894000A07E583147DD8EBFCFF3C5D327FF1DCFA3
+:10895000113E7BD4E2C5EE9D4C799CF44790DB43FD
+:10896000E2DC7AD5CF1CC4277F1A766927AE5F5424
+:108970007F34F2796BED19FE0216D1333C50027A46
+:10898000063CEC32B2FFD86E2D3EC3E9E441A48030
+:108990004EAE7A1E973B599478379B00EB63B087B5
+:1089A0004E6AF2F8BC26E742CFD9A7F0F252B1AF37
+:1089B0003CC3ED2371BFD00AC6E921CE0B563470FB
+:1089C0007BF638EE6BF0DE9A86CB3FE671312E1FD8
+:1089D0003700DFE1BA2E77A5ACC3FBA3EA7739BC39
+:1089E00021787FE0148FB64F8066063AAFD45EB927
+:1089F0009E85DA0B60DC1B7759BC619A96B89FC8DC
+:108A00004CFAE233B01D4B53B13F89FAAFEF9042BD
+:108A100018BF4A2E6FB022BE37EC95581A8FBB5143
+:108A20009C4F7C67BFCABC99E279AB7225B297D9DB
+:108A3000AE98FBCEA1DF1B77EBBFAF5F63F8AE7ED6
+:108A4000999DFF2ED93266B84FA0C342FBA59DD990
+:108A50001BE93EF9018984D7AA0E6E7747F197D9B1
+:108A60003740D3E581D06FE7101D246F88F5C663CA
+:108A700066FA5A9AC72A9C47566FBC8CF3EA2F9E17
+:108A8000CBBDFB895F8CF8C6AC8347BF0E5D14A7D6
+:108A9000FEA8C1C2D05F5CAE727E58FE34BFAF5D2F
+:108AA000DCBF6FE4878FD21BE8FCE6A31F49AC2331
+:108AB0002BCA1F822F56EE095971FFFF9C7524396E
+:108AC000416EEAB7EEB9A60CDEBFFE4747AD684F70
+:108AD000D4A486734C294842E78F2B8745F97565E6
+:108AE000484F871B76E9CBFF2C3A312D5E4BEF01C7
+:108AF0007D96ED94C9AE8869A7B38B98DC6EC5EFFF
+:108B0000CACE85242FEAD715788D47C1C5E3BBA609
+:108B1000E73E827F2DDE46FFEEB229FA7BE6CF34B8
+:108B2000CCE7F9BEEBFBFEBEDB78DE62DC5FDFB6D6
+:108B3000F07C9B3EF6D9B9C817B0CF9AF0A3C578A0
+:108B4000FA79B9B6BF2EC3FD14E0EFB63E9184F1B9
+:108B5000BA8F1E7862209D23E17E9417BB3FC37EAF
+:108B600089FBF3AFF8EF26D5FCA72D8C71ED537B75
+:108B70006D2196D5BBFFFA89816553106F6D3FFD5E
+:108B80004C3A5A8CF763093D1BEFFCF85F35DF2543
+:108B900038DF42B42BF87C3F68E3F33CD9CEE77D65
+:108BA0005DAFF9EAED914F1C61DAFF3FD92333B491
+:108BB00033845D21EC0431CF73AC633BDE6B76E331
+:108BC0004D6FBC6B06FE587949D778FCDD829AFB65
+:108BD0006C641FACFCEF44A2D767524526CAE7A9D4
+:108BE0000E9B823FF5766A97839E47F1E8B1173670
+:108BF0004F89B517FA493F1147923C2E9E97F123B2
+:108C0000E641BB13CF5DF0BC83394DB4DF18DF3FC5
+:108C1000A8ED4B37CA26B257EBADDC6EFD42F35BD5
+:108C20007768F53BA670FB75D714F1BB84A7B72313
+:108C3000BD8EFEDAE6C27DA8CBCAE3CE472DCAD6EA
+:108C4000EFC1BC664C0DFC640AEC9B7E937311CAA9
+:108C5000CD5D03C65B500F35A72CA7F3AAC5AC8B1F
+:108C6000EECD9A533ACF83DFEBBD3BD0EE9549FE74
+:108C7000999F1547E33C2F5B783ECFBBB8CE30AF12
+:108C80006AED1CE35D07A84D18FFDD4156CA23516C
+:108C90007F6DA37D7963028F33B3F464BA8778A1C3
+:108CA00026EF8B66D814D493D53336FA11427F2A37
+:108CB000037AD5D84FB7E4C3388D26BEEF35A63238
+:108CC0001E876AEE2E42FA4D60CD2ECC6781D9EF19
+:108CD000FD26ED7CEBA0CF27AAC7B8D644C617A8BF
+:108CE00094E8AB2BD75B79FD8929CB6A1F180A65FD
+:108CF000B4D9D13EBD420EEDC8C2F8B989D6732EA3
+:108D0000E6D9903DEBD6DDC77725FC570EF3BCD2F4
+:108D1000CC54532AC13627C0F9A52C9C0CF30BBFA9
+:108D2000A0CF77BA366C0A8FC6F33173783FE5E38C
+:108D3000C8AC054DE42B5996E526CC2FB8AB7FF88F
+:108D40007E39A5A1F68172289BF8F7DFA76F97E817
+:108D50007EB8C56676107FF7614DAA47A5E76B25FB
+:108D6000B2B3AB4198F0FC17EADB920AF03D89F808
+:108D70000BD797E70FF1BC2BB14ED0CE9E00CFCFD3
+:108D80004CC922BBAB5AC3776BC03410EFCFBE5176
+:108D9000F3AB16DB5933E6E981FF9784719D7C4084
+:108DA00033769DD65885FFB5DB8ABF8777C3D3CF8F
+:108DB0001FCF02BAFC5DE3E71B44BCF517FA78ABA2
+:108DC00067AA87C6C5DF7E45FEA8D6603CF918367F
+:108DD00095F7376C2A970FC754E1DFED26BFEF06F2
+:108DE0002DCE1B6FBC1B6D2C4CF4FAB58DD65D8C53
+:108DF0003B578343A6F2B886C043F0F97206F6C02B
+:108E000028847C1F33C162525E50C7439457BAE234
+:108E100047FADF9D010385CEB957ED343E8FD90760
+:108E200075BF1BC5E3F092F5F475889F34C5E14525
+:108E3000B9A8B6EE267F5C020703F96B799CF72C84
+:108E40001DDCFFB2B473BB86E22C3E8CD748F4BB6A
+:108E50002E7543BD6ED40B4BD21B685F1576F07236
+:108E60008D0F6CDAEFB92C473B07E37568E720FDFF
+:108E7000B672FCCD9ADDBAB443BFDFD7B519E7C7E8
+:108E8000F77D4B4FBFFADF87B168FB7E93C5EB469A
+:108E90007D6B61FAFDBF49E2F35033781C88A5F37E
+:108EA0007AB366E709F99F30D5A2BBE7EE1CFBDA7F
+:108EB0008CEB20EAFD33189B52105F7FCC55068463
+:108EC000253ABFBEFC10879BBAE8FC59CBC79EABC6
+:108ED000C93B3C277BC65F29D1EF1ACF552C9FC5D4
+:108EE000CE57DC2365B447AAA6C6C9FF284FEB5767
+:108EF000FE87C85FAF41BD4DBF9FC7E3D53745CFA4
+:108F0000A773518FD748095EB4CF45FCFF6D0D9E06
+:108F100069E0DF43D5BC03FBA1D4FB5CE08B8A4452
+:108F2000D504B026C96AC6755E947CEB1C84E2BC8D
+:108F3000E06D0D7E65EAA6F16B59F7E798677D79DC
+:108F40007A57222E4BCDDA1CCA536BAD28DC0A3679
+:108F5000176BFACDFE5AFB303A8DD4F2268FBC87C0
+:108F60007983577F0DF3A3F2CBB50A8EFBDCE9C5FD
+:108F7000F8ADD44F7EF372AD19E8F6C583A7B76399
+:108F8000F937BF395E6B06BA7CB1F9F4700795DF2B
+:108F9000E3F58D5A7FEA7BB5D8DF173FE0E507A1FF
+:108FA0005E257B259C837498D3E0F062DC41C4AFDE
+:108FB0006A4CCF1244C71CF594909B3FE5FC917E10
+:108FC000AF1234C025A82FD624842D99A80FF6708F
+:108FD000FD79E3BA8AA40A867CC9CF65B768FA4BE3
+:108FE0005214D2AB36E82B01F8E3C1299ADE32ECF9
+:108FF000FF2C0FF0F145F1D988FA2DA3375E2F4CE5
+:10900000F56F9C5A84F73F7E48DF53BF57A15079D4
+:10901000DBE44008E1AA79926AC5DF167F2D7489E6
+:109020006657909FBDD1A4CFDFDFA8E941019F51D2
+:10903000A0DF8CE8FA407F3FFB36FDCD52389EA280
+:109040003F41CF651A3DA1FF5FE278FF68FF42AF65
+:1090500089FE0655F4C2FFD96FD3FF7D86FE84FDDD
+:109060002AE6310E6D3458E7344C5C2E8AE2239E9A
+:10907000B748E18C6B313EF6824CF1AE968CDF99AD
+:10908000F11E05E69FC4ED640797C78FA6F2386C02
+:10909000CBF7BC1487538FF0FB025A32AE71A33D5D
+:1090A000F8F9A3D7A751DC4AB32F3FDFFFA615F38A
+:1090B000085747F8FD006B22FCBE80D57BF75B2F7D
+:1090C000C3FC2280D363E21CF5D17B88CCF87D8081
+:1090D000C0E3A3A9262D0ECEE32CEF62BE505E1F87
+:1090E000F692D2132FA7798FD7E6F7E20CE5D4D406
+:1090F00098798BE7E23B2F633F33152E0F2F4E6598
+:109100007D7E77F6AF82FF0F0CC68CA60080000034
+:109110001F8B080000000000000BB55B097C54E5C4
+:10912000B53F77EEBD3393649299908404B2304397
+:109130000043D9862C102081C94A2C0407700910DD
+:109140007482B288406244492BFDCD404090F27C4D
+:109150007179155B6A278816ABD5A860A945980474
+:10916000A4C1756AEB93F7B43050AB6C4A047DC66A
+:109170004AE59DF37DF74BE64E12305DC28FDF97D7
+:1091800073BFED7CE7FCCFF29D7B03A0B83E3603B6
+:109190008C93002ECB00D5D1708BDB0270EB845802
+:1091A000B37D1CC084A3EE92D84480A5DB1CD9B249
+:1091B0001D2050586C72250148342FAB7B5EC56072
+:1091C0008020CE03A56320505B37D9001300EEC288
+:1091D000B5E9E7E2BE3C2B8CA6DFF87E4E9A978974
+:1091E000FB0D08AE86F100652E8BDF5C0830E35185
+:1091F0001C32984D71018EAB3069B46FA8A7340D45
+:10920000E96F654667B9D2FC3E5CAF9DF8C576E173
+:10921000C431D1301620E48831D8ACD85F5853E639
+:10922000CAA3E785E5F4BCC8143BA2C6C2D61DE1BB
+:109230008EA57EB783FA693CE039ABEF5497009E68
+:10924000F3822F0A640780676C8CC74FEB1BA01456
+:109250000620AFF4330D6088CB009044FCE24A79DD
+:10926000DDFB8B7D711FA0753C0FA536D33ACEC2B6
+:10927000A252DA47ECEB2CF48C27F9897DF1986344
+:10928000E9795FFB8B7D453B96F6C7F54A697F5CC4
+:10929000C75D20834B93F165FC3FA73446475F3F92
+:1092A00033015C59DDF48DD7A7EAE8AAEA4CDDF872
+:1092B000F9B78DD2F5579A82B975966E7D0BBD417F
+:1092C000036E3EA8277FA2458531FECA674B3E2B21
+:1092D000CA25D80A6376E3F97C8E58E793D87BC712
+:1092E000E66B017200AC9D0B58BBA209E9048095A6
+:1092F0009D7319BDAA3386D195A90BD7431CC939D3
+:10930000580EB9D8BE1C0F8DC8C33B7260C4CF685D
+:109310003D13AE87B8AC7C7E7A05E979D5EE75CF82
+:10932000D238B0C7E40CC7719532B44BA8BFDACEBF
+:1093300028BE9EFC6EEE9D28D71925B13E8395F57B
+:1093400003E9B7312F760BE9A35185AA965EE4BEF7
+:10935000C22531B9AB21CE7759E76CB69EE8AF771D
+:109360000D65E715B49AB4535964E93E8F1A9258C3
+:10937000FBFDCE51ACADDD3D5BB1E33EAF673D9152
+:10938000E8B1B0F1166AC13D456F377513AD644F52
+:109390007DC9D9D489FA473E16744AE0C2757DC5A5
+:1093A000AECD84AF596B438A19E50316A3ED49DCB2
+:1093B0007A56FEF8942561EB34B6CE033BE2CE94A8
+:1093C0000846173E5F806D4958BF0781D9D2CBBE92
+:1093D0000F68F80358C7DA59DA3848FB1688EF9B4C
+:1093E0006D9C6F818F7BB5F1627E1079219CFBF6BD
+:1093F00098FCC4D763C59E66B28F601154BDC8FC8B
+:1094000047306376ECBF8E7FD4AF99F41FA7F07D11
+:10941000E3F21D3B7C685F4F759D83E3F46AE77858
+:10942000581BFF8E0C0D848F77A64D0BBA70BDD6DE
+:109430007B7372C82F82ADE312E1AE76FF94CC2D20
+:10944000C8EFCB2E231B5FBB1F71CC9E9BFC12EE83
+:109450005B99D0F131F1D1F16A947D8783CF231CE0
+:109460009FC7CE2DB88EB1CCF332E9AF76FFE91CA1
+:109470000FEEE3DAF7D5B17B71BECB12EB24768E1B
+:109480004C73FD86F9933EF8BC9A3DF6C49789D992
+:10949000E5453B5FDFB399DBA147B3C71A0DBF8B2F
+:1094A000347B14F6AC12EE72087F1C772B3AE3F98A
+:1094B000784DCEB764497E92F3CA4E079B2FEC7865
+:1094C000D15A69C436B24F25D639DC4EEB727B10C7
+:1094D00076BAAA334167A7C26EDF2BF67C4C72E9DD
+:1094E000B2DB46B4F7B8EF8293AF15FB18E4B74090
+:1094F000520927266C4BC2ECDBADE9BDE63689E9A3
+:10950000A906F1015277FFD97EE2FDA8367E9125AA
+:1095100030DC80EBA97551CEF5B85E75929DF9AF40
+:10952000FAFB914091D4AB3CAED63F263951332C57
+:10953000DE8295E26D9DD113C6DFBCCEB16047F9E6
+:10954000CCED1CC6DA40A1E76BD27F4DE78D9A5E69
+:10955000C6B216ECF9061808B09AF44A78847CAEC4
+:10956000678DBF2FEA2626AFC1FDBF785365FD7911
+:109570002EDFCDC48FEA37399B919F53511E99F44A
+:10958000762A1D6C0F238BA754F0D9501FB76E930A
+:10959000C187EBDF86AD07DB53F1E08ACF26BBC383
+:1095A0007386C5892F95A60CC0B8B0B2FEFD630ABC
+:1095B000BAC2DB4704C70670DDEAA240D24DB8EE5E
+:1095C000B99DAAD387FBAE687D778201FBCF385C5B
+:1095D000C980BEF7F5C99E842214DDF239FEE75436
+:1095E000A4CF36BDF4DFF9F66E795617C30CE2ABA3
+:1095F000BACDC0FC7ECB56B9C2CFE378CCEC31619A
+:10960000B8D6F28A23C0F31181D3E59D994C3E224E
+:10961000DE08FFFD1B6F0A1EA2DB8FF7158722ED08
+:1096200045C4A58B75EF97135F17774B141CBBF0E0
+:10963000DD1D87246657E8A418CEBBE30FC7B9F039
+:10964000DB95B281E1AED23AC4DFE8E8F6E391F10E
+:1096500069CAD399BB5FC175963FB3D04DFB4E1B12
+:1096600025818CFBAE787150AEA7173F2DE2B590E7
+:109670008790CFEB1A3DB5D8555994F75DEC27CAC2
+:10968000C8FCAC6F36303F8B6DB89F55853D404868
+:109690009913DBFD7C4E51FFECC6A58D177C0B3E6C
+:1096A00083469E5F09FEDF009E7F887D1E2B9E7392
+:1096B0003BE187E206EDBFAA88C7E97FD5B9FA8A00
+:1096C0001FAB8AFA173F16449C4F9C439CEB4DED11
+:1096D000BCDF35BE341619D9BEFD8D2F8419961FF7
+:1096E0004559FD4F62FFD40393BEB8D74E71C6A44F
+:1096F000509EF17A69496351189F822FC1E75B1A26
+:10970000DF1887361785DD03C4F37F342E097B8D80
+:10971000B4B748FB8DB4DBC87C51D84DA47D0ABBDF
+:1097200016763AE3C73C1F854C9E8F0ABBC57C9ECC
+:10973000C9A7FD7BF17EF237AB683EC391D51F9E72
+:109740004F8AF85729EF786032D9EFF944672374CC
+:10975000C74361B7C38A3DFB484EC5CF7CF3D2FFF8
+:1097600042B7BD5E1D9FBF5559DC5A21B1FCC6846E
+:109770006D78DCF2F46177ADFDB4BBE78BF87DE684
+:109780001D99E3DB6735B2BCEC6AF8FBE3BF0F7FE2
+:109790007F24FCF595871F25FB4E62F83BCAECFE43
+:1097A0005F9607BD9F6B47BE2EE6621EE4E8C6D1FA
+:1097B0008C371027B9DD38E9C287315DF3D7DC8FEC
+:1097C000CFB80C7524670FE93F2C4FFAB6D87389D0
+:1097D000F81478688FF68DA6BCE6BBE6B70B12EBE3
+:1097E000C085E33DD886FB2713E975744FFD4BC553
+:1097F000FDD3FFF9A2FEE5B5F1C5FF705E9B569C57
+:10980000D7775E0B2E9EBF087D3855A7750DCE7796
+:10981000BE2593C6FAD4A7BC8DCBBB4B6E0145E4E5
+:109820000709941F204ED28BFF099C5496B47C618B
+:10983000C6D4764AF1E01A6512DE9FF341AB4FA41D
+:1098400036BB86313F0230999F80EA15CC8E189D39
+:1098500076A294EE990F77F5FBA8BFACC0DA55DF7E
+:10986000205310E327170F3AB195F1DDC4F5E7094E
+:1098700029EE3161742ED2B161747E04BD9D8F8F4B
+:1098800053426063EBF8D973C29D94CD71C2D7EB9C
+:10989000288F47B9CFDA2DD9482FF30BCE1BA92E2D
+:1098A0005359123A9C8AE7AC6C1B5A63C154653E0B
+:1098B000F93DE47361DBF79A7D8A260FD4CF0A4D18
+:1098C0007CA616C925A37E56E44BFEA18E9EF25BB4
+:1098D00058AC8F8FF4A3E8E78331B77FF3497F6CEF
+:1098E000FE50363F60EAC7FE371580CBDF4B9E74D3
+:1098F0008718770969B13ECA6C2E9EAFB7FACB5D67
+:10990000DAF8A0C1B012505EF7B64D6D36A7A35E6F
+:1099100081E3E2476D85353E8E3F70459CF74AFCFA
+:10992000D6F4725EBB7E7EE04AF25ADA63BE868B64
+:10993000657A9C94155C76919D9615202E288F71E2
+:10994000476DA57B476589866B5F458D2B0DCF17CE
+:1099500005BA3A5C17AE7DD7D610AE5781183FA333
+:1099600099FC93DBD0359EE37C9FD4353F0BF143CC
+:10997000A19DE63FDAF6FD66AADBA13E583FA3951E
+:109980002BE0BC25822E88B00B0DD7CC2EC94FA35F
+:109990007C864B3DE5F362318F739F4A3CAE048B6E
+:1099A000795E191CCADB778B795C794593639BD010
+:1099B0007374981CD2BAF58C3F01BAFF849D9BC981
+:1099C000695EA238F7ED3533D13F0407C01809713D
+:1099D000F266F1E2E60D8534DFAD007A3C0596369D
+:1099E000BF89FE679E2697778B979DD07023919DA8
+:1099F000AD640040BDEF967C329E6B25E9BD977348
+:109A00003DDE1337BE88F92EF50AF377F69CEF8A10
+:109A1000980F6A627FE66B7A9919A1B78A08BD959B
+:109A200046D0D582F6EBFC96F067F39639EE4B45BF
+:109A30003E963F2B310F8E7ED9288D07F8A4ADBE00
+:109A4000C63289F0695753B1E76CDBEA1366C4EE9E
+:109A50006CF25F0CAF77333F3D97EC9BD1F7D4B8F6
+:109A6000AC8497BA8D2938FEF3B635CD66B483F948
+:109A70001B1E5401E92FDB7ED0ACA0BEE6E53E7F85
+:109A800098D653D6DD7B62A6E30AF86C8A38C7F60F
+:109A900008DA1731FE91ABF8F10D11F3D746F46FE8
+:109AA0008DA0B745D09B23EDC3563E90FCFD060923
+:109AB000B6C0D5EDC45422F2C1965C339EDF7A70F5
+:109AC00073F3464CB96734729CC797DC5F138E53AF
+:109AD00015F8CF8244F0513C50FBF04F72491F38CB
+:109AE000C98A8C5BA2DF9D42CF8F69F6811A5944E7
+:109AF00079F0C1AEF8CAEDAD55E67C0D2E997772BE
+:109B0000039BCFEF290F69EF25F61B6019D93BAEF8
+:109B100053F1422FFEFFA1527E5F3CF8CD99679E24
+:109B200047B9F88618D97D1D338F4B1D789E93E970
+:109B3000C63C8A93627CEB106303C59156933765EC
+:109B400071587C383864E0A51A9C7F30196C14D7A2
+:109B50000FDE9BC3E6FB6A65E770A4F7677CFC1F1A
+:109B60001391DEBF4ACEA17E314F5D21B338A326CB
+:109B7000B6C42E0EE3EF606D4E813DECDEFBA556C4
+:109B800077FF20ED1E1BC5EBD621AB8345C46FB21A
+:109B9000C2F8357D5D6D93F079898C7928B59A1E70
+:109BA0008F75CE0F0671DC46CB50F254F89CFBB992
+:109BB0008D69379A699DC64403CB97D4D88536639F
+:109BC000D8795C890AE7CB01EEF03CFC754D8F3FFC
+:109BD00029E1F97F9B6C63E7463E6C5487BFE59BA8
+:109BE000EAA341DC47CD9860071CBAA724938D3BBC
+:109BF0006EB015507DA8440EE540D87D729E41BBE5
+:109C00003766A1771DC8F25AEE77CC5B83F258A273
+:109C1000155F88D799CC974970182B0C13B471062F
+:109C20005D3F5C46DCA9060DDF19C0EE170CA8B439
+:109C30002ECDC57DF14E3796DAC5255CEF9447AB46
+:109C4000548F4934BBA2E83D83566FC0DB48293DA1
+:109C5000AFC0FD14BAEF49280792533AAC9AC370CB
+:109C6000D6A292DDD56BEB887D16687C2D40F9D1AC
+:109C70007A0B14508CE8C76E49368EDD8BFA0F597B
+:109C80008C4E8297782EF65BA0ED778BCCEF11A6E9
+:109C900015AA2F14F65E46F0B1BE249EC9B3F14753
+:109CA000FC3D5328C3EE07ED9C72B85CD6C6BAA241
+:109CB000E87D580686780B3B0FDB6F23C53FA22D4E
+:109CC0002FAF91E2BA9F87D64F49A17BE946519FBA
+:109CD0005F29B17B20D99991CE45BF0FA573195D3E
+:109CE00023E95C38DF3136CC6F44F0CB6A90429F79
+:109CF000993DF5349D6873DFB4A82B087C0C2805CA
+:109D000026E7D62103D732BB4A3633DCEFFFDB0F21
+:109D10008FD6207D7CA099DD57BAEC3439A5C04E92
+:109D2000765A9BB0B623CC4EF6FF6DDF5B1368FE10
+:109D3000402587EC72EA3797C6DC4AE39213D9F8DC
+:109D4000A9DEB3677F43F5EB6FA26D121B3FD94EBF
+:109D5000F715D91062FE01FE16CD705E62AD4AB1F4
+:109D600087D9C5AF35BB5A59E07AA604F9940722C2
+:109D7000FE2DDD7E4C1E78A387ECB5319D99216CBC
+:109D80004295925D356AFA10EBECD1EC768FB61EF7
+:109D900028F60C9ADF26735CFB36490CD76AD2DEB4
+:109DA000D8F0F74287351CB6C658B97FAA4DB844DB
+:109DB000E7AC49F318257BF83899AD6B325B997D98
+:109DC000B79AA679C87E6B2C37AAECBE87FBDD80DC
+:109DD000FBBD56A2B0F51AE379BE74DCE0B6931E63
+:109DE0007F56E0892BC5E72755CEB7CB168C95E873
+:109DF0001EB73A21DE872C4CD5FC4FEB10A5213C39
+:109E00007F3EA6F1774CF31FAD43EE617A137A6C77
+:109E1000351D607A51075EEF94995ED01F931EBC8A
+:109E2000314EE2BF35D9CC70D99A6C64F7CDD65A91
+:109E300099CBC36A66710CE31CC3C5D46485F9EB86
+:109E40003D2576DDFB38A1DF36B9EE28F75766767B
+:109E50009FFF6045C225D28BAA5A6D74FEE3868EA1
+:109E60003CF20F7B4A06303E65833B05C2EA74F341
+:109E7000BBFD550A4CB8A2BF32128EFF597F85F345
+:109E80002A54B4CFBF097F75153F453FEA845EFC75
+:109E900090E6E722FD8D98F7EFB2DFF911F62B9EE1
+:109EA0008B7826E4FA7F5D34A25AF08F3CACBBD3AA
+:109EB000C4E4637A44F6934C16A4B94E539D0E360F
+:109EC000A41C1A86FC2DE15BC249C91D7C9FF0844D
+:109ED000F6457A5D52B77426D5F9362596DB8AF0B9
+:109EE000F9A626C9C9DF8BC05605D7BF559BB72435
+:109EF000F7CE11B4DE5DA5FCFDADE794AD3C0EC719
+:109F00001D4B9BE35E9748AD0284BF03DFCAECBBE9
+:109F100088828E608995ECCAC7BF8710F8F29C537F
+:109F2000CA299ED680ED3ECA638EC73554D0FCC682
+:109F30009F4BEC1C27A5BAC31EE20F69F21F8D7759
+:109F4000C7C6D1A5684AFA9F2A292F98F25F49AC63
+:109F50000E720CEA82C4AF6FABCCF0D9A8C2A1419B
+:109F60008457299EF99D236AF02D07F61FB93B817E
+:109F70002A3CB044814306C4C7D4526E570BCC96DA
+:109F800000E190E462C6E70B51BFC6014CDF3038F8
+:109F90009B92265E376A372032B3A96EC3F1505ABE
+:109FA000CAFD0EAE674EA07A81BC2F8FDE5F0B3FDD
+:109FB000A5C4E7B2BAD0677B174F20FB5493AEF726
+:109FC000D0F9CEEFBB6302C9E1BA52EE57EEDFFA29
+:109FD000909BE165EF3A1F9D679081DB61EDE64D57
+:109FE0009FCBA88FDA7D4540FED424F1BCE26AEB1A
+:109FF000CEA775F15CF737E1BAF27758779BFA5143
+:10A00000388E1B1F8B324BE3006E7B24E2B9565F08
+:10A01000ACF1E99F2FD8AAA77FA4C905E46A6B6FAA
+:10A02000EF5944DBF0E1BA0D87C2DE87AD2CB524D1
+:10A030007E3C0A7F99081359FDFC2AF3BFF2FA36D9
+:10A040001C52693F6E27E08CAC4FAEB1919FBD882A
+:10A0500078E4F1BECE4CF4B134036CE9258F0F796E
+:10A0600051D1683AA322EC4ED8D941ADDE7712E344
+:10A070000FE5C5078CF6D5E45F0F44A74B3EE64FCE
+:10A080005B12E83DFC560D57078C3C8F46C60AE62E
+:10A09000627C384079B585FAB9DE7F772EBB80CEF9
+:10A0A000B7BF33BB6051785E2C879E99C8FC34B72C
+:10A0B0004BBC4654BCD48B1C1C5A5C127C8AFC5D85
+:10A0C000F8878735BE055E23E73F5DCAE365C8DBD9
+:10A0D000007F19DEB34E2EBE633225DA75763B6CF7
+:10A0E0005A71736952B75DC0C179E0A0FBD3DA1C25
+:10A0F000561F7C5AD33FDA6E39DD3F20C59D125E74
+:10A100006F7D6B9AFEBDCEC35D7EAC7FF797B7A621
+:10A11000E1FD252CDF7F503B7F175F9790423CC8C5
+:10A12000DAFBDD6AFA2E09EDF4B0C65F79ACC14DF9
+:10A13000F176C6A38127593CB92B2A9BE2498509B0
+:10A140006E996DA1EFAC02C3EBC3E4765893D78C44
+:10A15000FFE4F11AEF77ACA5759A2DDDFDD5C57C2E
+:10A160009EA0C539057F6F4DB369F7D40400BC8745
+:10A1700097C6FCFDA520CA794993C966423E3FA215
+:10A180003A12F9B35779DE7201CFC3FC8BD96EA5B1
+:10A19000FBE2474772187E57B6CB274C68C7871E2D
+:10A1A000E4FE7EF16EEEEFA9425C897E7E99160F89
+:10A1B0006E7F44F299D0BF2D23FF3E96D16CDE9284
+:10A1C0000FC119C0794BFE243BED34CEAF9E0CB7C6
+:10A1D00063BAF6D2BA4B5B247F40A2EFD9F4FDB547
+:10A1E000B0F573F29B2B5B229ED74DFF84E2482D86
+:10A1F0002827C3E3DF71E6847ADA3DDA07D3FBA7C9
+:10A20000A5B1DCFE9DE0EC8FFD5BC07591F028E40C
+:10A21000B948D1EAF74A20E926CA1F8F2464D33D02
+:10A220001EEDCF9CCFE2FD3A9DFCCF7911F1D7A076
+:10A230003FF52E63EDE4DD0FCAA976AAC39F7860CF
+:10A240000ACEEFF8D4E0DC0134AE8E05F7CFCEE5D0
+:10A25000B27BE66768373CD8AFD7EE337ED616EED2
+:10A260006E955381FCF35F62D8F7491175FA8B75CF
+:10A2700026A6DF8BE714ED1EA2FFEE0005904C75BD
+:10A28000FC036FABEC3D8090DB991F70FF24703DA9
+:10A29000455B6FA9F69D41EB3309FB26136E62AC5B
+:10A2A00036CAD3CFEC92D93EA7CCD6A7A81E736AE4
+:10A2B000FBDC818076B858ED303A912FE7ABB3E301
+:10A2C000A80EF9571C1760F2F2CB148F2757C05C09
+:10A2D0009A3739A0801DE7FD55714A8483CF3E022D
+:10A2E0006842FA2CBD2FC0718B7FCBF34968559A19
+:10A2F000873BBAF92AC9D78EA1C9B7B28CDBFB2735
+:10A30000DB5F9A45E34FEF546DC4CF673B55367F13
+:10A3100039E2D680F83AB58BBF375CBE4FF2476161
+:10A32000FFE95D12C3E772C4A719E5B0F24ED56527
+:10A33000B4F6C47709CDA3718853C2BFC0F9729730
+:10A34000BF9CDD27345C9BF1DF654C59E2A1E53E03
+:10A350001BF27FC7AE7F0ECF91382E2BD3F09B0D13
+:10A36000D984DF0B753758036172E80BBFE730EE15
+:10A3700010EEC4F384DD0E2995ADEA63FEC3570CDD
+:10A3800059F43D61A311B214D2AF21DA497EE1AB99
+:10A39000A8B8B1940F359879BB263A6E07B55F45DA
+:10A3A00065F889DF35B2ED357A8FFB4E9983ADF3D1
+:10A3B00095C1AED23D606E62A894A5CA250697816C
+:10A3C000DEA7359A441E6D269C0635B9BA313F4F3B
+:10A3D0004079FCB84CD4A180E1B8DEC6FBCB640B5D
+:10A3E00093FB852A943BCE577C231F2DA0FB48BBB3
+:10A3F0000A7E9A0F5DF9ADC4EA1060B7D27877BBD8
+:10A400000C5B683F17CF9FED605E477AB981FC19FE
+:10A41000DD07520C600F937F943D1AEC61727E0F42
+:10A42000DC56F2478DDAF9C1E70A525E5BA5F11DF1
+:10A4300093354037BECAB284E121D63958B72E7859
+:10A4400078DE62C77FB4FF2C7A86FC5FE7E2FEEE1F
+:10A45000862AEC0F5B67531497AF5AF039939F5BD2
+:10A46000C38B5AA0CF7FDC69E5A749FE78FE8FAE8B
+:10A470008497E872C44B0CFE3212465EE67516EE07
+:10A48000F793C4BDA60EDC6171F3E1327E9F59568D
+:10A490006E67FA94730C2CFE8454C818CFEECDB6B8
+:10A4A000741A3F3B66C09776D4D12FCADE5E44EF64
+:10A4B000DF664F1970772666CABF2CFB13A7730699
+:10A4C000EC198AF4D3AFBDCBE97103F254A4D74998
+:10A4D000EF2D2A453FF35C99EBE76549B48F4DAB0F
+:10A4E0002BF275F1B9BF0CF7BF79B2E7096A6B8D32
+:10A4F00096CD94279E1FD1914179A6181F7A3535A4
+:10A500009DEE515D34F2E71C4D3468FCF7DE1E2DE4
+:10A51000733DCBF7D53F5F19837A1E472DE21AE5CD
+:10A520005DBFE7CF71765CFF7692D720D2633EBBEA
+:10A5300077ADD670099EC90CA7776B3AF9C40B7535
+:10A54000C3C8CE660546D0F7559506CF3EDAE793E9
+:10A55000ED8D69F528EF4F5F343967E2B853FE9708
+:10A56000E2C85FAFD0EA4970490E4CC3FE8AA1D75A
+:10A57000EC20BC9E7B61535A0D9EE35019CF1FCE39
+:10A5800039783E7CEE0593366EDE4E7A578FF1E8D1
+:10A5900035924F571CDA7903E3F35A0BC61F8CE34D
+:10A5A0005BA6F0BC00EFA1BED801AC85387CAE62E2
+:10A5B0002BB3F78E7E7E6FC5FE388A57F65B5378D5
+:10A5C000BD1A2185FEF53A0DE7D729815689EE752A
+:10A5D0004EAB42E79DC58F4BFD3E05D7319841A557
+:10A5E000F38C84ED36C21972BDFD7242B7DDD6BF61
+:10A5F000CAEDB65EE27940FD7BB2D347F2D2FCC928
+:10A60000CA7695E50991FEF61333F72F2B2018C76C
+:10A61000F4BEFD56665FC2CF76D9934DF96EFE75D6
+:10A620007BC977F2AF9F0BFF3A1EC6F7333FF88A1C
+:10A63000F42DF4512657DB153A6F525636CF97B8A2
+:10A640005F5B1AC5CF27F453FFF3CC64163F5A065D
+:10A65000B2BAFD528D67D89EC0F4799F4306CA27CF
+:10A660002AF7A6821D1FDDBE5762DF1BCEDC9BC012
+:10A67000E8B8CE418CAEFC657231C475EBB5F2978B
+:10A68000D730FAF4536FE4D2FD0BF5C1E47F01E358
+:10A690009C09BAF9117E16A3F0A305D87FA3E6574B
+:10A6A000376A7E4F9C8FF243FA6EF2822B967D3F83
+:10A6B0006ACDD7FBCF7897DE7F2654E8FD63925BA7
+:10A6C000EF1793AB86EAFA0779BEA7EB4F5D96AD1D
+:10A6D000A3D3EB26EBC60F6928D6D10EDFF775E3BF
+:10A6E0003337CFD1D1C39BE6EBC65FB36D91AE7F5D
+:10A6F000A47FB9AE7FD4AE7A1D3DA6E587BAF1E35B
+:10A70000F6AED7F58F0F6CD1F5E7B43FA4A3F38273
+:10A710003FD58D9F787487AE7F52E857BAFE29A740
+:10A720005ED4D1851DAFE8C64FEB6CD3D145F08622
+:10A730006E7C89F98F3ABACCF6816EFCF494BFE84E
+:10A74000FAAFB59FD5F5CFC8BAA8A38314F7C71140
+:10A750002EB85D563ABFD1CD0FC286E1E4F7164E52
+:10A76000F12C2847FC1962CE2914678E2E94200103
+:10A77000A17EA17DAE8D70D8DFFBFAAD11F1EB4B60
+:10A78000B0DC4CDFA99AE80BE1CC9EF3055EDD66F8
+:10A79000BB91EAE28B7CBF3FCAFC173D1AD8EDD7CC
+:10A7A0001669F518D8AC9EEBF20738BE879FD3FC2C
+:10A7B000DF48D860A3FB9FF06F7DF14F96F4B1584E
+:10A7C0000FF93DAF62FC423B925C7836B46309837B
+:10A7D0006635FA4D69DFEFBF667C3DEE349BD9BD2F
+:10A7E000B4DA467E47028FE1F228B2D799407584E9
+:10A7F0000B2D12B3D7C875445E66C5B0A484C92BAF
+:10A80000DE6506254C6F0915361D9DE44ED18D4F32
+:10A81000AEB2EBFA0779B274FDA9CB9C3A3ABD2EE1
+:10A820005F377E48834B473B7C15BAF1999BDD3AF5
+:10A830007A7853956EFC35DB3CBAFE91FE65BAFE24
+:10A8400051BBEA74F4989606DDF8717B7DBAFEF18F
+:10A8500081CDBAFE9CF6261D9D17DCA61B3FF1A8F4
+:10A860005FD73F29B44BD73FE5548B8E2EECD8AB46
+:10A870001B3FAD33A0A38BE0886E7C89F90F3ABAF9
+:10A88000CCF63FBAF1D3534EE8FAAFB59FD6F5AF49
+:10A8900038EB0CB0EF1C7F27B1BFA711F89991F5E9
+:10A8A000B96E9C9A88793B7D4F00D14ECA0FFACA87
+:10A8B000D705EE2A9D5FEBF65D23D7317B3A513EFB
+:10A8C00054CBE321148574A3CFCDEADD36B35D22EA
+:10A8D0007BB2FA24863F4A89ABD93D37917DFFC3CD
+:10A8E000420FF267257B416280C1E1A0FB444CB777
+:10A8F000DDA45DCEE987DD687959FA74CF47E54973
+:10A9000074EF7AA19CEE2BCBCC4DCCAECBE4D1D660
+:10A9100010FA93B7A37AAF3B5D6B463986ED772487
+:10A92000AA292DFB0A7EE75AF33936BE6B5D95AF37
+:10A930002BE1F9C2EB330FE03D4A41FFD2E4453B46
+:10A94000C30BF0435E1BA31FF1A630FA275E3B6BDF
+:10A95000B779B358FB53AF93F56FF7E633FA71AF9E
+:10A960008BD17E6F056B7778DDECF94E6F15A39F69
+:10A97000F27A58BBCBBB8CB5BFF2D6B1FE67BD0D2A
+:10A980008C7ECEEB636D8B77337BFEA2B789D1BB18
+:10A99000BDDB18FDB2D7CFDABDDE5DAC7DC5DBC255
+:10A9A000FAF779F7327ABF37C0E880B79DD16DDE0C
+:10A9B00020A30F798F32FAB037C4DA76EF29D6BEEA
+:10A9C000EEED60FD6F7A3B197D4EAB2FA64ED7DEC4
+:10A9D00083C91617BB6F155FB38370279E974EF31D
+:10A9E000A44ECF63DF89EF25BFB53E66ACCAFC7FBE
+:10A9F000849F8BD4C3196D7DB518D3477AFF337804
+:10AA0000C40EFA9E739D81DFDBD70DB0EFA03BCC67
+:10AA100088E9FC9EB2291A7C512C9FE579EB520DF6
+:10AA20008790C8FDB8780FB154C37D1EE1318BE12A
+:10AA3000F1CDFEF871714F0E147A264CA77ABCA5A1
+:10AA4000CEC8D33A27FBFBC14A13AF03751C919DB7
+:10AA50003BEC7DAF5BAB7DEFDC67FFFED369141F82
+:10AA60002BBE953D2487B7D5D82AAA83546872ADEA
+:10AA7000986ED0B533A7BAA7939C97EEFF018B8B46
+:10AA8000D5770EB7929CAFA34F40D07E67835D65AC
+:10AA9000DFCDE17DC141F74DBC90127D13F8589B8D
+:10AAA00055E871D379E661624D744882A7EE92E869
+:10AAB0003C1CFF917C546972AF9A6ED0B5CBA7BA9B
+:10AAC000AB888FDB264FBFD9808F7E3CCDAE7D7F9C
+:10AAD000DFF138F1519BE1399E9AD95D67A886A0D4
+:10AAE000CADFDF6979A8563FC53C95D51FAAA5687E
+:10AAF00027DD1BEE2BD2DE27FE3996DD573FD4E251
+:10AB0000DE879A3FBB50A7325C54FF39C64F758829
+:10AB10000B757FB5102C457C5C88F71B7A8F5E8D9A
+:10AB20002DBD8FA9A6E22EAE57BD5662DF91F7E587
+:10AB300027C5FB99E9050E76BE6ACC7FD9BD299160
+:10AB4000FF3F3F297507D5477F56E869A0732F9FC0
+:10AB500024FB8CF477A336FF08AA336E32703CF8DE
+:10AB60005E9799DF566C6E9744F5D7EDF1E3D9FB0C
+:10AB70005CC40D7D071BD0F42870B14AFB9E5EE0DB
+:10AB800001F1B681F4F3D96F2766112E6AF74F628F
+:10AB9000EFBD1B0DFCEF77C4FA402569DC4FB68E84
+:10ABA0006EDEC2F5C7CED93129D64FDFFDB6CAD089
+:10ABB000F0422F7EF2571AAEDE4E5159BDAD51B361
+:10ABC0003FD1FF84C6DF13DAB8CAB623E9F4F74AE7
+:10ABD000ABDA5527D5912137343ABC7ED085E38650
+:10ABE00027EE191686F3DABD27789D1E42A3E7C427
+:10ABF000727649EF1B357B15FBA894975130495469
+:10AC0000CE75DDDF86929C783C1078948DB19E667F
+:10AC10004BF839BAECE169660F710DCC1E100FAB21
+:10AC2000C9D8432842AAB7787E613312EE168193C1
+:10AC3000B5B7819BB54B112684FFDBC1CFDA3B2032
+:10AC4000741F7D10E4F6D56450BCA9858ED214948F
+:10AC5000E30D9BD7BD9682ACCC6D7AB06C10F27DC3
+:10AC6000E376873A18DBD93BEFDC489F17A23DBD5E
+:10AC700042FBCF7FB66823D577D19E3EA6FBD22C70
+:10AC8000EDBE8F3874C9882B39CECCEA62B73DC48B
+:10AC9000FD664093EFF2A9AE00CDAF5E0F0C2F1D05
+:10ACA000AF9A98FEBAEC29FF8EE3A906CA07817D08
+:10ACB0002F7AFED591FE75D8BF1C789CEECE3379E5
+:10ACC0007C16767046E57838F36B897D1F7F46C227
+:10ACD000F9D97DE35FE49B68AFDCFE8EC5327BF97A
+:10ACE000CAC0F304C8F0A4646792BC7CF7517DF934
+:10ACF0008CC13F212E93C5EB0F887FB5D8B3753C2F
+:10AD0000D5E99E939C8DC8CB99787F469D45E7FFFA
+:10AD1000E1720C3929BEDE032AAFF344E6B7E21C28
+:10AD2000917C9A8CE0A3F7A85D794DFEE1AF29EF05
+:10AD3000E8C9AF27855E6036922A32892FB7BD37C2
+:10AD40003E3644EC2FF6956C7CDDF6BFF33AB72F18
+:10AD50001DD8F73757AB8B9AA2397F223EF5E48B8B
+:10AD6000EBCB5CC1EBA6823F74205936DC4751A285
+:10AD70009D64C77F88E27529516F12F7F57CD9630E
+:10AD8000AAC8A37E5EAF6A777C328CC5D74B8D692B
+:10AD9000FC3BC300CBCBC43D6696B0AB7C5567573C
+:10ADA0001051EF8182DEEF3F6EB34D253B984BF1A2
+:10ADB0002493EE431F0AF9B1FBD0FF03211A67D792
+:10ADC000B0400000000000001F8B080000000000E1
+:10ADD000000BBBC5C6C0F0A31E8185D851F9E8B8E9
+:10ADE0000C4D7E03337EF584F06AA0FE6540BC10F6
+:10ADF00088E700F174209E04C4BD40DC01C46B5898
+:10AE000019189603F122209E0BC43380783210F774
+:10AE10000171272BC21C37A03F02D8F0DBF5981533
+:10AE2000532C9213C13E41C0EFA378F8E307DC0C2A
+:10AE30000CB77910FC005E54F987DC08B6A52065D4
+:10AE4000767901F503006133110A800300000000E8
+:10AE500000000000000000001F8B08000000000040
+:10AE6000000BDD7D0B7854D5B5F03E8F39F3C8CC9F
+:10AE7000E4E4452621C0C903081270081103A21E8C
+:10AE8000206254FA3B3E8B5E6F1D1E2A208F88B4D1
+:10AE9000D2D6DE4C1E8404A20D881681E2808AB6CA
+:10AEA000C26D50B46883777854638B6D68B1A257D4
+:10AEB0006DB45E2F568414AB582FB7FE6BADBD4FEB
+:10AEC00066CE4902D4DEFEDFF75FA8DDEC73F6D96B
+:10AED0007BAFF7DA6BAFBDC7ED1FCA328731F625FE
+:10AEE000FEB994B1952EB65B3A9F318F27DC398B32
+:10AEF000411DFE6313196BC2320FFE8BCB2A9BC020
+:10AF00009897F13F4A81FCAE3BC8D8CD9AC1580E04
+:10AF10003C0865527B97BF8645E1D1D66F2B33DB6A
+:10AF2000FDD8D2646C1063067E08CFF7B77C9657C5
+:10AF30009ACDD8A38D45B21B1E153389B10B18CB02
+:10AF40009F9FFD8BD20A68D22A3305DAD5B70CCA87
+:10AF5000EF86EFB7149AF93AF5C364ECA7D0C3FBB8
+:10AF6000612C46FD0E63BCFE68E3B5E9AC0CEA6DEE
+:10AF70004D7F528249B8AC72784C66090F9FFB979F
+:10AF80000CBF53FFDC5D2AEA858C55E03F100E565E
+:10AF9000C5104E43B43DF0F6A93C9CD763302F3723
+:10AFA000EB3B8FFCF915BE5129F3B6E681F333274D
+:10AFB00024E7F7B7CE87E0CBC1A98415A660D53CBE
+:10AFC000149A4028E67FD49FCB91318C35D41AED6A
+:10AFD000252EFE281BDE5F2CC66B50C31EC4DBC5AE
+:10AFE0007E39E61EDB777CD50FDFA58CCFD84CC22F
+:10AFF000A72A9EADAA05CA01C0CDB51E2A97665CD8
+:10B00000EB61D0DF846CA03BF4D7E2324311A87B24
+:10B0100083915004E01D9F3DFD4306CF27EAB7CF43
+:10B02000C0F217C39B8EB8012F2B74CD70233CEF59
+:10B03000ABEF217CA5F0F7CB2278AE7666E2FC265A
+:10B0400030FEDC823BAD14EA29F31AEF787FB1AE13
+:10B05000CD92A17FCF503E2E6B4F690FFD5E9C7D40
+:10B06000E39D12D09FFDD9FEDCC2E7DE5A9D9923F5
+:10B0700019DB5C5B4A703D037503EBFF6DF12BA799
+:10B08000AF26187D699E0C88656CDD11632BB26A52
+:10B090001BFE1FF4F388ABFB26649A589E663C2E79
+:10B0A00061CBF8C3B743BB076F1854BE0AF03F210A
+:10B0B000C2F1F4A0D4FD2E7E1FBB86B77B460D5F88
+:10B0C00087F507AFCF9463525FBA8EBF5E8EE5C23D
+:10B0D000FC2786008F41AABF3B722CD2FBF18FDC8C
+:10B0E000F05D59B566AC82EFC67F3E8819598C4D2C
+:10B0F000420683793CF02A8BD7E3F308A7C32FBE1F
+:10B100003DDDDB5D96C4BB097F110FEB06C0BB9331
+:10B110007FA6AAAEE47BF8EF629817CA7B1F7A5429
+:10B12000033D82FDD06106D061ECC074B0CA15B594
+:10B1300071F687E18CDD5F1B22BAB4D41A54B60ACB
+:10B14000FAB461D3897DF9F73E99CD6B07F8EEF338
+:10B15000B1794F239C6679BFEDAC92B13AD233F707
+:10B16000A3AC4CA2E998AC92B1F4ECDE7AC257825F
+:10B170007C0DFFCA17EF0BA07FA9B71E6300872FB6
+:10B18000D93E9606EDEFF7F2FABFC73698B1826462
+:10B19000FD23F680199BDCF77D8B2B6E4AE3187B31
+:10B1A0003E768B59E6B5F56F62FFA9F3F34CEEDB03
+:10B1B0005F8B97B7FF2BFB3ED59BA44408F5039507
+:10B1C000610002BEABAAC47EA1AE33B62D331A3BDA
+:10B1D000303139CE11168DC580FEB7B2C83EC4FFDE
+:10B1E0000629DEA014E2B86D3319CCAB13BF877EFD
+:10B1F0007D93F9B89DB116B3414DE2E5B7AC318608
+:10B200007058FA57117CAB346B31D4BBF52D9F9934
+:10B2100012F0A392C574B781506492FD907593A10A
+:10B220003EB7E8A1E8EA07A9FCD5CB17A2FDC07498
+:10B23000E4ED7AE7EF8A4F9361FEFBF015D4A74E59
+:10B24000AAFCF564185FEB7285515F0711AFD065FA
+:10B25000F0B4C2269563A3A829010D5B81D1514E9C
+:10B260005F406607BE48AFCC67F1D4F9A8D150243F
+:10B2700090EC17C63B8AED2C7C9D6D7C15C737FA88
+:10B28000195F3569FC2631BE73DC166F7826EAD566
+:10B29000A9232AAF66D4CF70D92D25BF6B1D65C8F1
+:10B2A000F8DD1889DB4D2FF65F9E84C38BE3C078F1
+:10B2B000BE12E837458F5AFD015E18EA63EB3BABDF
+:10B2C0003DC04B746B1D65C78BB31FC05F08EDCECF
+:10B2D000C0F4DFC6E93F1EE8CF52E81F06FA979D8B
+:10B2E00003FDFF41FD7E023C8CF02F1BA7C563854B
+:10B2F000C28FC94CC26FC16BC1E784BB49325F9F2B
+:10B300002C113D19E2CDA2E727F85D4E72FC3E7C80
+:10B31000C4C284F7D6432EB6EA0CE35ADF3BC75DBE
+:10B32000F6EAFE1058A43EE33AE7EB1C37F3F3517C
+:10B33000CC04FB5084BC0378AAFF9E4676AC6939E6
+:10B340008B23FD9B3A2F233F65AD1CED447E8DFD85
+:10B35000C6C51E872ED7A23E453BD85C41DF3D12B5
+:10B360008886AEF50FAC4FD7819F100382AC853233
+:10B370003E12F1C4C88E66CF53C98E35B98C961271
+:10B38000ECFFDBF2B8C7193D7F3717EC4293D75873
+:10B390005395F23C07DBE3F340F89592ECE4F3AC11
+:10B3A000AFBDEF9DE5A7F7EFE6A6F875391199C592
+:10B3B00052F034548B4623FDCCF35E4926FABC8010
+:10B3C000F685EC3DB72F437DDDB3101FDA02CDD8F3
+:10B3D0000AF8D8FCED1BF367C3F7FB1E1C21BD5711
+:10B3E00086769BCBD766619FACFE32971B12FA41E3
+:10B3F0002FB8BAF7063318AB9198590378CF3C169B
+:10B40000FE27D4BFB5D26EE686F12AAA79BDF2FE38
+:10B410007F632F539D91FEDC587798F4E986571F80
+:10B420006DC0F1977D08AD60A8496A5CA921BC6731
+:10B43000F76BC71EFFD033330EF39AB4AEA9EB3AC5
+:10B440006286B88D6F2E3A6AA7FF0B02CE6704DCC6
+:10B450005189D9E44B13F2A5F5CAD7883A15F5C33B
+:10B4600009467A73922772F37CA84FAA66E106A375
+:10B47000EF7CB46A90B314FC033CD352E1F99F8291
+:10B48000E356663E245D30707F7DED427433B69F97
+:10B4900024F45B6675BB122D3B13DC37129CDA5526
+:10B4A0008CF4F540FD3BE1451F0CE70DE36D977211
+:10B4B000FA8EF78FC207F4BB9FF4D8DFD96FE6513D
+:10B4C000A75E6F13FA24A1A2DD4BD6230CF58B36B1
+:10B4D0009445D1DF52843EA13F30B45A107E14719E
+:10B4E000D12569D45E0D7908AF376BD12EA2DB0C64
+:10B4F000665B377AF4082825E82FBF349DE8E2EF31
+:10B500007FFECDB5914CD595527731E19F7338B41C
+:10B510002216CF42B84ECF31AE1D936C9787F34BB6
+:10B52000E96FC310EB3BFB7C2D7FDDA54F18BF0AF5
+:10B530006A4771FE397DE70B701C9552F4BBAAC7B0
+:10B5400018D177FE083EFFB9D9FDFA2B799EEB3270
+:10B55000D5AC245F16CE30EA5583BA34910FE91585
+:10B56000D41FF01F3D12857FAE667CDE6EB9A71337
+:10B57000EDD36677F414E22FAFB98B49D02E6B462A
+:10B580008245018E15880718F732C5EF453DD5660F
+:10B5900016A5A3DE1A224B36FA5AE546D0CBEA703E
+:10B5A000BE8EC3F2D4DB2369DE03F17943AD2723DA
+:10B5B00015EF0D0BD5EA38F4DFE07FFAD074007593
+:10B5C00045764939D9E679928A7078250E47BA18B6
+:10B5D0007FE3A26F117E006FE932C0EDCAE6F8B2D8
+:10B5E000F808FFA829F01799515387F75993F93AAA
+:10B5F000B510FC53F473329A5938C1080F21EC2767
+:10B600002F9448A0090F54E953118F161EE08F178D
+:10B61000EDC59A578697231DAD79DF2CCB9C7FCB48
+:10B62000B89FC0D430F97303E98D56C053D970E286
+:10B630007B09DB6DC27A0A1EDE94A2A364A447D8FC
+:10B640001753609E7973E312C2F5B064CD23447141
+:10B650008346C137ADE53EE2B7C621FA16F4172B93
+:10B66000646E87D826C9C95F15728A9C59FC9517E4
+:10B670008E52BCE1DF5CD14AC2E3B2761DE5C6372B
+:10B68000B75B477F60A5356E8C75617FD9820E16DA
+:10B690009F67961A5B91CFAB055DB22B9BEEC2758F
+:10B6A0005A56994AEBB8ECEE59B4BEF4BD75C5874D
+:10B6B0008C3FA7F56A5EA48B96A5F9A5E65EC4F754
+:10B6C0004E57B41AC7CF9C78C0243E04FA6800CF06
+:10B6D0001A5794E13A529B1C37711DBE71D18D6C83
+:10B6E000560A5FDD24F0EF02F3132F4BD2FD01E188
+:10B6F000D87D7F72B9F78E326CE723BC14B1EB8929
+:10B700000F0A5984FC5C2D49FF99881FFF8CB629CC
+:10B7100038AF4048AFC77900DFE7229ED6B8F43C87
+:10B720009CC79A451AE93BC0C761E4CB7459E0C392
+:10B7300080BF809F80CCC72D925D349E0FF08D4ED0
+:10B74000A6BBA8CB54409F825A0A63F37481270B8F
+:10B750002FAE9270A781FC388381A709EF05DE5CCC
+:10B76000A5E00714117E16227E0266C2447C69D9C8
+:10B770006D7B310E74EAED0BAB910E27FD3243FA6F
+:10B780005B7CE8E43FD50FF2D6AF1E0E935F9726A1
+:10B79000F4D94B52F4DB728A1ED2F23B43D1147FB0
+:10B7A00047D3B87E6665D7733D529008CD81F13D91
+:10B7B000A1D03842B9AA535CA3D51AAB97FFEB6965
+:10B7C000BC16E1E768A11AE23F6F4994F48DC7689F
+:10B7D000A3D25DC0F9D27AAF2D578CF75188CBB880
+:10B7E000FE6B0A5F9B8E7E91E649105FF8DBF632B6
+:10B7F000C42B8845F8711A31CAAE0F20DFF3B8D7D1
+:10B800005350F2B8439CC6771B3E9648B173DA7228
+:10B810008DF72FE431EF2D37C95DB6B03F6F4A91F8
+:10B820000DA4172C39B4EC43E47A2EEFD55E82F7E1
+:10B830007111A7EB2BF71CEE53D07717E24D8DFA61
+:10B84000D01FDEB66EB60FE1D8B6FEDAF454FC3A7D
+:10B85000CB87413F244040B7805EC57263AD4E65E3
+:10B86000AFDE15F1A44D424EADE75E85EB8143425C
+:10B870002EB779223E8A6FEEBFE9CA5180CA92C3C1
+:10B880004A1875C3E035ED19671ABF60A16CC3177C
+:10B89000536E39E37C97BF7528E3404AFB7D7220E5
+:10B8A000FB83D1F08F0BD9855F2A67FFFE546D575C
+:10B8B000C601D7DF8F974D220EE1556EAA8B21DE90
+:10B8C000139792DE2C12AA2BAF99D13AAD64198B43
+:10B8D0001BD8F6F497FC7D6FDCD7F4CF823AA96AC7
+:10B8E000A86F6B9EBD0AE56CC86B0AC375F87094AF
+:10B8F0004F8C3BADE371270FFCC5B8138558A0DF13
+:10B90000E2B92C9E8076C56DF638631E6BA5B8F142
+:10B9100010477C2B0FF500EA4596D21E9E1780B08B
+:10B920005796FFFD74F804E990F6FF9E0E1BD5763E
+:10B93000AF9EF2FD608945905F072F7A5F9A9DC2A6
+:10B94000AF1E85F3295BEE677F4889E30D96127978
+:10B95000A83FB72C94C93FD8B890C749DDD9DDFFBF
+:10B960008A9F9C7A67751EF957833EB804F5618EED
+:10B9700092C6FBA966DC6F60763D0476304749F1DC
+:10B9800017B6345E4B7A07FE1CC6F8A821E8BDF155
+:10B990007483A4011D872F67E17AA81B82DE55EB13
+:10B9A0006AF6BAE079D132EEC7B3989DFE45733995
+:10B9B000FD87B772BE1AB25C7DCF1E2708D76B30E9
+:10B9C000DF5C50BF1BA056B2CECE1FB9C21EE43AF8
+:10B9D000F8C3003EC8023E28698BAEC2FEF30E2BB0
+:10B9E000DC47768C3FDC68BF02F15302788A93FF14
+:10B9F00099D28F82FC15AE477A38F93217F9726CFA
+:10BA0000DF71FF5EBE9BAAD8E5FF535676F39350D5
+:10BA10007D64C5F64323A855444EF5972CBEF333F9
+:10BA2000B31AE9C422E7B61E63EC72D2C3D67ECA4B
+:10BA300094A5211FC66B3669BA0FF75562BF53181C
+:10BA4000DA874D4BF3F353E7BF45F8775BBCBC9CFB
+:10BA500025F8F056C545E51C85C7E13705791C7802
+:10BA600020FD6ED9D3919FFB59222BB5AE39EA2A1E
+:10BA70004B8C4FAD07A9DE98C3C8EE6CC53225FECE
+:10BA8000B022D0CEF8BED45C19F59322F4D3FE8C4C
+:10BA9000E91E84AFD15F2EF681A204BFF5BED15F4F
+:10BAA00094CB52E06CC438F7C881F1B802E3DCE80B
+:10BAB000F78BB8CC569719CA80B231637A6856367C
+:10BAC000C6C706917DFF9EB02B0A8E09CAAEB16132
+:10BAD000575D3DF0E61A66FE8B7201FF0EFDABADC1
+:10BAE000191318EEEF413B33DE0FBFCC577C1C6FB0
+:10BAF00086FA853D6EEFD7895F04BFDEA6445B9171
+:10BB00000F62535902FDB518ACC71AD09ED7801FDB
+:10BB10001B48D21FDAAD11ED6218BFEB6D17B5D619
+:10BB200003BDED1EC279423BD3D62ED2A7DD46D14E
+:10BB30001FB38D6BF619372EFA4BB0D4FEC27DFAC7
+:10BB40007B5CB48BB1D4FE8C3EFDFDD89A9FAD9D3D
+:10BB5000DEA7DD4F443B661B97D9C7ED7D3F54B34D
+:10BB6000DE93BFB722E7460FAD97E2336D7CE5A4C5
+:10BB7000D3BE1CCE670772A657231FDCFD8A8BD667
+:10BB80000B7B73ECFC67B56FA865CD0B5DB80E64DD
+:10BB9000B45FD8E0DF4AE358CF7BDBF9B7EAFD3F7B
+:10BBA0009F3D40FBD9A2BDE78C7CDC20F8B841F07A
+:10BBB000B1F3FD052A97EFE652B027FDC8B3A9728D
+:10BBC00079676A84D6715A296B2F4BD167FFBFC042
+:10BBD000394EC0D15C5ADF3635CCD89F952FEA3C20
+:10BBE00040FF96D0DAB629507F8D7D515725FDEF65
+:10BBF0008333A3D1539F0AE70B314FFDFF4638C76C
+:10BC0000AAB936381F61B9F5558503C3B942C4CB0B
+:10BC10009DFD4E54F9FA79A52B427A7B45CEB74269
+:10BC200038DF1543B87EBFBAF18DBA3A3F36894E38
+:10BC30005661FC95F05F17DA23D520FB72B6EF3C16
+:10BC4000A3D408CA594B88FB6FD6B8AF0B3B62959B
+:10BC500047C879037F2D4F25FF8EE568F1E1021E6D
+:10BC60008CBB7DAAE836B9CC54756E3F44FD7CD5BB
+:10BC7000FE1EFEF105FA313AC25FDCD7AEAC157696
+:10BC8000B6AFBD8DCBA9F636C3B2B7578CA07DEE4B
+:10BC9000FD2D23AEC07D86C6830A23FFCF6177F7D3
+:10BCA000B64CEF34E0FDDA4E97786FDAF4EB7DE0D6
+:10BCB0002F231F80DECC65C4177CFFD9F25F7AC7C3
+:10BCC0000BF0714E829FE74EE1D346B11FDD28F69F
+:10BCD000A39DF43C2DF4DB0E18C7800F9F04BEC358
+:10BCE000BC830D508F42FD51A847A1BE13FC742C9C
+:10BCF0005FAC0DD1F315B506954FC17CF0F99ADA1A
+:10BD0000309589DA4A2A5BD0CF87327F974C71967B
+:10BD1000D5E8EF433D5ECB5A31DEF7FD5A0F950D66
+:10BD2000B53A953FA90D51B9BED6A0725B6D299564
+:10BD30009B6AC3543E545BD98AF1BFC9D2B52B91DB
+:10BD4000AFF2E731A27BFEF7466C4597AB78974A96
+:10BD5000E314B7821DAC483EB7E09C2C4D6DC5EF97
+:10BD6000C6EDE6F31977000C5EFFEDD660BB4B76AF
+:10BD7000F3FE2EF91CEC7476BFED1E52318E149733
+:10BD8000C95F71411BA9FFFE36627FA3E32AB51B81
+:10BD9000BD9D511CA99F7671EC2FE3313EBF8C2ACB
+:10BDA000161BA0DDE3D8CE7C8CF767322931C0B8F2
+:10BDB0003FC67681CCF0AC08F167FB1419E36FD570
+:10BDC0007A26C6230359E1BBF873B31E9F7B4BF859
+:10BDD000F3606F7B633F3EF7958AE7BDED7B14050B
+:10BDE0009EA795897E34DEBEED0AEE376454E95B8A
+:10BDF0003D308F27AEE0F4C9AC36B6603DE0E6DFFB
+:10BE0000EB23DA9804F29651A24B12C03912EA32AF
+:10BE1000C86B5033A6C8F07DD6954CDE0A9FB69D00
+:10BE20001767123CCF28E5ED9E80BA0CDF05DD4692
+:10BE30001DCE2BEB2A68077CAF9FDF4EED5688FDA9
+:10BE4000A491E7EB7BF17D5A9521A168AC13FB4DE2
+:10BE500099658624C3F885556C2A8AFE7C17336F52
+:10BE600080EF57DCC5F5CF6F1A174FC5BC85F42A94
+:10BE7000C6F31C56FC6C6A1DA896403E8F5F0506F3
+:10BE8000878F44316E74A146FB7FC1FC70770CF53F
+:10BE9000CE04DF38DC9F0C0E0E1F8DE3FB8BF87B8E
+:10BEA00060D5989E09729C7EAC74D619D63F56F91F
+:10BEB000C9C16914370C56C8CCECC7DE58A5966DBD
+:10BEC000DF1FC9AB8ED5213C17223C08AF80E75855
+:10BED000E377A6623EC408B1BF37D4F5248707F7DD
+:10BEE0004B603E816189BC3BB253E0199A285C5992
+:10BEF0009102CFB0C4A827B293F0640B780AEEE6A3
+:10BF0000F07CA29AB97A3FFAC439FF9C887D9F6879
+:10BF1000ABCBA0B8A8523D62032E7D9527F9FC5605
+:10BF2000AC185D5F5F02FA2087A9523A94627DE502
+:10BF3000F2B0661C17F183FB096F0B7DD54B970E92
+:10BF40002D96D54F1E99550606B31ADECEF32EB6A2
+:10BF50000B8AEF821DBE337E1714DF053BFCEF66B4
+:10BF6000050786AF2F3DA2F52AD8D788EBFBF283D1
+:10BF7000500F550B7E8A6D9C3AA5A42F7DD65EC3CB
+:10BF8000E15D2BE0CDB6E005FC6602BC9F5AF05A9D
+:10BF9000749B79167887C1BCA99D80577C179C79C2
+:10BFA0001678C577C19976784FE3A6C60567A76B63
+:10BFB0008380A341AC8FB3D5B3C0B10CE0E8271F99
+:10BFC000B20F1CCB3C349F5E3896F9CEF85D2F1C27
+:10BFD000CBFCEFA6C27BAE70AC1170AC09887C01C3
+:10BFE0003FC0517E06386E3947386E71C071CB390B
+:10BFF000C271CB5783A3578E043D5C821E563F7D92
+:10C00000E468B0199A65D36FA65197A2DFDEB6C671
+:10C010001D6C966E49D1736A16D7078D38DEF950BC
+:10C0200006C478026F038FC7062FB48D07A6BBDF47
+:10C03000F1C064A68C17DECFC73B5B1CE03A357AB3
+:10C040009F4BC401948A81E300D06EAD4BACB39595
+:10C05000EC81E300D0EE07A29D696B17E9D36E93E4
+:10C060001897D9C635FB8CBB45F49790B3078E0360
+:10C0700040BB6DA2BF985C31701C00DA3D65CDCF2E
+:10C08000D64EEFD3AE5DB463B6711D7100C6EEA29D
+:10C09000F8F6371DFB32CE327BAE66CB17CE9C61F5
+:10C0A000AFFB2BEC750DFEF6C6070B93E359FDA510
+:10C0B0005BFBF8D11A03E7B32A103F82F92A875CA9
+:10C0C0007F989A0DCF576570FD79C8F5513DC5E948
+:10C0D000B1027EB0DF8AC34FE6F1BF53E364822F23
+:10C0E00038468D338C4B3299FC427F8116C738A776
+:10C0F0003FDC25519E0DFA1C340F1E5F0B54447813
+:10C100007C57F4030C73C6FD59B554A3389C5ADA16
+:10C11000DCC54B95F2CF595B9FFDD47710EF6EDCF9
+:10C12000DF2B4EEEA75AE30C84DF243D5829E6C1ED
+:10C13000DCC37C61DC3FCDD098A4C2A7CB0B78BC1C
+:10C14000F99B72F48FC8275A55CDAD8D5097A62F05
+:10C150001F89EB8F106602813CE8B9C27F99E30921
+:10C16000A37CE9D326D33E1DE809DB3A6F8CC6D702
+:10C170008D5FB814C2879EC6F510F3C4F2AE49C9EC
+:10C1800067088976F0FE2EA4CF454DEAFEE64AA860
+:10C19000A7B37112F823996BFCD3AA012EBD587C6A
+:10C1A0005F30C0F7C56C27B60F6BD27E15DB0F630F
+:10C1B000642F2F6C1AD280F9A0FA486E875985B186
+:10C1C000A511E6BFFE9F078DC33CC0ACFFB3BC10FA
+:10C1D000F5406F3FA3392B4CC4EFB07D14FCF6093A
+:10C1E000C97CBDCDEE6850C37DB9EAAE04AA16C5C0
+:10C1F000EFCC5B284B7F2F050F83347BDE42532D22
+:10C20000CF57B0EA9AE75719EF8F87EF677928EE93
+:10C21000169AADC5D1FF7E5036ABB40B68FCB8633F
+:10C22000FCA1F8FC5CC72F157025C7F7B0D4FC073C
+:10C2300067B972E877F2A2840FBEAE857991FEB13C
+:10C24000E635563C67FE581EC9B90E6520D9BE6D4D
+:10C25000DABF48F8FD71295A41F30F45D5D47CC7A0
+:10C26000AC1926F1ABD5BE01E09652FAB79EB310D9
+:10C27000EFBFB75ECDEBAAE07B7DDA2D14F750ABB4
+:10C28000783E0E9B69CF6B51F51A2B4F2384F3E850
+:10C290009BA751A0D3BE14E37ABE375EF94E20DED1
+:10C2A00080FB3BDEE05806766FB98797F7F8825B34
+:10C2B000B13CE51D1AC77D9253725BA7A424CF87BA
+:10C2C000785DB118EA07904B13FB3CDBF7CEF140E9
+:10C2D0003F9C8FF36A29698B207C2E15FA33E8B9CD
+:10C2E0007D3F5AEC735B7BEA9A27EA29C43839AC64
+:10C2F000D763C80F6DE3281EDCBB2F0DBE22E505FA
+:10C3000085D863222F88A5F293A7C4BECFE22AF076
+:10C31000D9F42C9B1993703C4B7F5BFBD6AA1F84EE
+:10C3200095F0690ABBC0F5310EC1E31EDFB5E97DAA
+:10C33000D5CF12DE20C257CE52F74154C6F53AA6E9
+:10C3400023723DFEDD73B2177DC6BBDE3ECF73FEAA
+:10C35000CEAF1A1FA4D8FF81BF53D90729FB59AD0F
+:10C3600098680774BF73C7A79B6340B7634F7FB4D8
+:10C3700039067858F8D74F367F17FD8F17BD3AEA40
+:10C38000C7253FFE8FCDDF017A7CBCDB2D7BA0BEB5
+:10C39000E0C71FBEF35DA87FF6FCC84C0C3D6D11D5
+:10C3A000FAE1F8CEBF0C32A09F657B2EA3F8CCB289
+:10C3B00067A7D9F6519CE571D0237177EAFCE2D4E6
+:10C3C0008FB15BC2CD34C63A44C94CBF04F85C8C13
+:10C3D000FF84F1F6EF529817E6F7F11137E5C92E11
+:10C3E0008167CBC1BF5ADCBE88F619B17E2FF877C2
+:10C3F0008BB7AFA47DB925BB5DB6FD3AE0D8C1725D
+:10C4000008CBC4604C095ABCEBBAAB2FAEC0D245C6
+:10C41000F9254B584F13AECB9CDFE1F89F43BF4B40
+:10C420000E2BB3B4F3FBBE5FC222E9B86FBD647BD1
+:10C430000B1FB7FD6BFF8972B2C4B12FF831FE63D9
+:10C4400062DFFDBE8466DFEFFBEC4737A527F0E532
+:10C45000AEAC7EF352ACFDBE45CFDE70C67D45C4AA
+:10C4600073E21CF0AC5F2C47FA8BEB03A7109F3CE8
+:10C4700024F224BE3F59CEC3943ABD85EF6BE953F5
+:10C480003FEF2C86FA23F3B3C7213F58FB7A7E2671
+:10C49000F49ED8A71C489F3C34846DC2F2C13C284E
+:10C4A000CF4FEA975F69D1F7B59C81F5CC4392787D
+:10C4B0009EC1E2786E07F489C7578E79C13D9DC54C
+:10C4C000F8FC1A99EC3B3C6FF665A6B49FC8DB33C9
+:10C4D000D334F4095C8EB89E824783285EC1FF9CEA
+:10C4E000178EA192D1407FA13EF3A05F548C794971
+:10C4F000ED54FE552B22F8FCAC8BEAC16B4EE2C921
+:10C500002446273C2608D0A1DF1C8F9FEBF7EBD5F4
+:10C5100063BD7C50847A7E13F9E9F8C997561EE210
+:10C52000A0B37F87F31D4CE7240AA87DB6355F7161
+:10C530008E2FAF171E9D217C83C5DB5C1623FF2742
+:10C540003F92A07208EBA672184E41A1BCBE3AC63B
+:10C55000FD7309F1EB656F917D9163B2F4E5E82419
+:10C56000FD2CFA30E18769C20F73D2F51EC57C231A
+:10C570005A48FE58811BF378E49ADDDD50D7DEB9C6
+:10C58000A7270A1FAF13F67E5DC0EE778D74737D0B
+:10C590006295EB3204DD6E10745323D235297E2868
+:10C5A000E10BFC9DF356FE681AF93B2A9FBFF3B9D5
+:10C5B000359E2BDBA47DC94081CEF3AEA28088944A
+:10C5C000BCC0896E1ED7DFEC8E94E3BCFD7ADB5EC7
+:10C5D000C9E07E49773FF2619556FE66536D94CA75
+:10C5E0002A0C3EC32402D9350CBF07BFE712778A55
+:10C5F0003FA40A3AFDEDFDEBE4FFA05D45B97A5397
+:10C600008A56633EBBDB606DA877DC053CDF4A11D0
+:10C61000F966965F65F573AD9BFB535669E56569F1
+:10C62000F9F39EDC0278699B1212721C213FF53AE5
+:10C630004107C02BF92F0F4A62FD2579841C314335
+:10C640001F94942305DC40E42717004AF97BC8D7E0
+:10C650000AF2539CCA34940F9097656E2E3F01D610
+:10C660009D34E6D978EE468FE3390C1510A4645258
+:10C6700099C0D2E2137CEECAE4FB0241D4F3EE4C43
+:10C680009ED78C75947F39321FF10CFC5E2753BF07
+:10C69000A682723148CC6F90255733ED72D5CB8F7F
+:10C6A00019767CDD2DF0B44CF0058E8FFAA4AFFC2A
+:10C6B0009E755DF23D773FEB12C4249D130D34153A
+:10C6C00022DDF4F3D99FE4303E7E79DAC14AF2FBF1
+:10C6D0007762BD41FDF9B46A106E7D3CE7EB152B26
+:10C6E0003BA7D1BAE042B1AEA8B4AF2B1E10F35DA8
+:10C6F0002DF8904D16FEA75E43FE2DF8E79B703E89
+:10C70000ABDD623FC8E47E706FBD8AB7EFAD97F1D5
+:10C71000F75FC17F6D759F83FF6AD979A3577FD972
+:10C72000D7DD561ED1658A9FF4816F19B80F80E757
+:10C73000616195F2928D70FD5D78EE94EC1BEE17C1
+:10C740002C53E90C00BCA775A8F5FDB09866F3174B
+:10C750000373EDF5FCDE3C33FBFA3C5FE499E5B393
+:10C7600094753CEA4B91D7639DC376CAADD3CEEFA7
+:10C77000717FB57CB20392B99FF48738C73DB09FF3
+:10C7800017237A7F55FFBD61CAB823D9C06F39CF4F
+:10C790001F257EDB7BC3208A176CF0F3BCADF5014F
+:10C7A0007E0EDD29F7B08E7F6404E07DF0727ECED0
+:10C7B0001AED0F9EAF4E13EFA5E84B7FA1F3A6BA7B
+:10C7C00059270D4AEA3F56CEF949437A2B6867E369
+:10C7D00054EFB5ABAC874A456F4BA0ABB96FF9D4FA
+:10C7E0000C3CA798C65A6DF267F1C5C965FCFC946C
+:10C7F000CA46A7633D047C40F95C31B32B84E7C291
+:10C80000057F168A3CE10C13631549FA64557B5881
+:10C810006ABE6F4E44B7D57367866CEDF3A2E0F73E
+:10C82000211C8DDCCFC374661E878B101F861602F9
+:10C83000EE0AFBE62D8644BE5ADEDC04E9EBC13588
+:10C84000F6BCB290C82B0B39BE73F293DB23FC46C7
+:10C8500030F7C84F80877082EF7FD23921B5DB4D2A
+:10C8600078C907BC201E4E324EF721B3189DB37312
+:10C87000E2C5E237F85F3801F31F0AFD24709C908F
+:10C880001D4F5EC38EA7B4523B9E02613B9E2C7C23
+:10C89000A7571AB67616DEAC73E703E1A9605E7B94
+:10C8A0001DC2F355F154E6C0D3A7AC632FBEDB2005
+:10C8B000EE5540827952FC27454D489291C447DE9F
+:10C8C0003CE05F98C7E601F87F483633704B9E9591
+:10C8D00005285E1012F8949673BE1FC88F74F23943
+:10C8E000706B1D76EAC2E343C5C8E76F093EFF03DC
+:10C8F000433FCCE509C6D2C662C9F59407FC194C82
+:10C90000CE55FD3CFE06FAF62A0FEAFB02D996C781
+:10C91000E916E77A2CFDA0A8CC9053FCD591A21D76
+:10C92000FAC52C05AE91682FC7A27DE2704B7E211F
+:10C93000C79BC07EA6AC3B2DBB70AE70323D4CFE9B
+:10C940008B1BED685A528E2D3D360CE1243FD33CB3
+:10C950008CFC3942CC675833BF3F6284D0E7C6BDF8
+:10C96000E0CFE2C7EBEDF99C9FB219B45E75E66BC0
+:10C9700016083D3E74993DBFB440E8FD02471EF1E4
+:10C9800010A3FD1A9297988C1E341B1CE3F76A0CB7
+:10C990005DC6C27353FA1D1C0D86E78E4F9EE77469
+:10C9A000F2DFBD1EFBFAEEEE6BAE27BD118F6DED13
+:10C9B000378F7C63AD273C17F3886B43543E59ABEC
+:10C9C0005359BCA92BE685F98C140E6BE14CBE5F64
+:10C9D00059D8AC8553F9D5CFA2AB910F1EB96BC115
+:10C9E00054C4C3F0C6E814D4CB5F53CC56E20F71E5
+:10C9F0002E6DE4F2029AF788E543A974DA91C18BAF
+:10CA0000761DAA85A65BEF05FE467BFAB9DB44FFDF
+:10CA1000087370F17B23A64FF5C0FBE266A31CFBF5
+:10CA2000DFECE1FED2AD1EF3611A671E3F5761E1F4
+:10CA300067207B65E5E1C378AFA01D5133326DE718
+:10CA400022B60A5C3FEDE17E8D154FB2FA696AB6F7
+:10CA5000CE3718948752D45658EF498D2389F30D59
+:10CA600032E3F1A27BF07C034C758627BA93E6A9EA
+:10CA7000A7C48D8A9271A2C18B4A7CA89FB77A62A3
+:10CA800032DE2D30F89B0C16868C8D8A03FD6DFCF2
+:10CA9000032E18803AF4B130F19D05EFAD9E680782
+:10CAA000F65FE0F187E7427F858D864C717591577F
+:10CAB0003F4CF075E9BD8CF472511BA3387D69734E
+:10CAC0004F1DF6335DE8F3AD429F833CCC9895A2B1
+:10CAD000AFB746CD4C3A9723F4ABA54F41CD093BB8
+:10CAE00064D03D24A3EEB5F37B91D09B250EBD59B8
+:10CAF00024F46D91E3F9A8B8DE2FBF5B7039F9FD1E
+:10CB00004D8BDF73591EC6A93E6593732F3392FC7C
+:10CB100060E5E73BFD1C679CC2EA7F5CC23EBEA4A9
+:10CB2000C628DEEC0A311DF9727D8EA597EDEBFA71
+:10CB30005EBF231C8DA13FCE66331DE3E6A11951D4
+:10CB4000CA770D55B3B081F33ACCF7295A34FE9D1C
+:10CB5000EC8949986FEE29E8BA18F9F0538F9FF8DD
+:10CB6000F4662DF229D2336B06DF1FC9423DAD9C1E
+:10CB700059FFC594A4FE5BE389FED57341520F1A99
+:10CB8000515DF6F7A3872DBDEBD4B3690E7DE95651
+:10CB9000A389D9465FB8615A46EA7ECDCA21427F51
+:10CBA00017703BB671A12AEEB1585D8507A356DF19
+:10CBB000B03394A3D330091DD61DABAF90E8FD84EC
+:10CBC00096471B719DB1FA1A5EAFF2FE90D76F9235
+:10CBD000681D72B9780F15CAD772792CFCD5DC5A4A
+:10CBE0005881F8E3FEE0CA82339F8768A8E579524E
+:10CBF000563B450DF3FC6D21FF6E475C54F5DBE3BE
+:10CC0000BEEA427E3ED1D20BEA42EEF7AF1E737B04
+:10CC100027CE03E3CB4847CD53C3505EDC6D77513D
+:10CC20005EB4533F78847EF89638FF04FA21E845D5
+:10CC30007BA9DBE3CA967E08A28185F7232B6A9045
+:10CC4000C8B00EAF918DB2649CC6D2AF1E35C2C2C1
+:10CC5000F0DE555DC30C6C37839FA37357F3736D80
+:10CC6000B227BC17F9D393DD1526BDE7E0C7CBBCCF
+:10CC700016FF999779817F26E1B817E0312A2BCEEC
+:10CC80001696781C9BC705D6782257E2BC8D02BD4C
+:10CC90005E62E7CE5FF4678288831522DC263B5311
+:10CCA0001CCCE2EB745CC717F7E5CFFB3533E332FE
+:10CCB00080ABE157AE30E6290DB42EF9612DE8D3F3
+:10CCC000E149BB67D93BCBFE59EB9655DE427B7EF3
+:10CCD000B658BF103FC338AD6F8D8E532C5EF049F0
+:10CCE000EB5C56CDCF7F72FE748B35E7A921B37D07
+:10CCF0009A1FEFF350A83FEBBC8EC56FBE01F2BA8E
+:10CD00002D3EB5DA5B7CEA6C77AEFCA979A2CD4505
+:10CD100068CFC5FEC7C8B6BBF679FBB15B56BF721C
+:10CD20005FFE6CF19EC17EBDEF3157E1FBFBCBC3D3
+:10CD3000F3FABB7FE1DB3E6E4F372E5CE745BE7DED
+:10CD400018F19522CFBE348E8753A39612BE7EE291
+:10CD5000E5FBA14F6CB2E32B74167C59EDFF07F095
+:10CD6000E51981FBD7025F039D633C03BE7E82F21F
+:10CD70003310BE5645B63617613E40540E0F87FE3F
+:10CD8000D745E4C4A5507F789EBC1DCF89AE8B6C7F
+:10CD9000F50C473E5BBFAF200DDE3FE60BF0738224
+:10CDA0007AA213DBC54A64BA47AA45E579902BD726
+:10CDB000CB8FC652F8715B01CFE75D5930DB372767
+:10CDC000050FDBD6EFB39D17DDE638976895353E46
+:10CDD000C9B61FBB612E3FD7951765713C5F5725BC
+:10CDE000CE5179B3797CC46BF2FA483F3F577560F6
+:10CDF0005CD314D4332D053CFC6FF917EB1DFE8575
+:10CE0000B56EF795F07BA5D647C1E4423BD7C5DCAC
+:10CE1000FF4913FE37BCA773C9BE32BB9FAD083FA5
+:10CE2000C2BDC9F15CF81D2E877F61B557CEB28EA9
+:10CE3000CBA8EAA638D2075E1147C965C3D0BFD8D0
+:10CE40001091098E3C8003754FEB6D6D740F48DEB9
+:10CE500069C5E4F2DF16BA794CD2CFF8AB979F6B75
+:10CE60006E1571BF71079882571D0427EB14FFB42C
+:10CE7000F07BDACBFDD956919776C16153099CA915
+:10CE80009D88534E7C3FA604FB69F7829037A62607
+:10CE90006622DD5AC6693AC63B5B25AE2763AFBA48
+:10CEA000041F334ED7F583B6601CEBE9CEA2D574D0
+:10CEB0009437CAFDECA78DA85CE41F586F267C7CD4
+:10CEC0003E23AAC326F3A7F6F7D276BE8F9A08DDD3
+:10CED00002F8F8A58FDB95A77DA01F084FD1FCD4E1
+:10CEE00038E2029F6CC3D3734674F518B45B300FFD
+:10CEF000EC26B3A086C965C9F19E2EE0E33D7D44D2
+:10CF000026FF2C2FFCBBED6847ACFEACF19EF3F581
+:10CF1000AF8F165AE3097CBF60C4578F4D19CF5DA0
+:10CF20006D1FCF3D17C6837ADE5199F298071AEF2D
+:10CF30008501C65B2CE861D1ED45A37BF5F9185F4F
+:10CF4000C4F190FF713C7F3FE37DBE560AA4C8E761
+:10CF50002F701CE8E7450B8F6A34FFDA143D74919B
+:10CF600090DB27407FCC817E5B863779918FB749F4
+:10CF700071D267B17132DDEFD3BAE96402F3AA9ED0
+:10CF800030319B04F8BD323605D7EDDFF5650ABDBB
+:10CF90003B95BE93D436BA0F4659CFB87F85EBF395
+:10CFA00074D6CFBE561BF9154367806E6349FF2FB9
+:10CFB000B4BEE617782FA277B91CA676B08C562798
+:10CFC00024E31FEB5DA23FB12F65F90D79C29F3EAF
+:10CFD00083FF1066D6BE13D5F93E95150F61E52681
+:10CFE000C535ACFD012BDE67ED0B58FB01E92C319B
+:10CFF00025757FAA18CF0314E3B9621E1F29340DCB
+:10D00000BA6762C4FAE854CAAF5EC6E81CBF5BF8F0
+:10D01000E369C53FCCE88D0F5E04EF7DD6398768A4
+:10D020003EAE870C9F750E82D7C73ADEAB516E7F3E
+:10D03000D4B95CBFB1837DF298EEF15D80F771F2F7
+:10D04000B88A15EF3EE0E5FDAE8BACF5A23E7779F0
+:10D05000CDFBC9FE0A7F0DFCFF5A1F8E733DD00524
+:10D06000D7ED7E7E9F97E267F2DF42D7241D19D766
+:10D07000F7CBF9BAD149AF81E86AD1CFA2E7DF4A4D
+:10D080004730958682EB1E3D22FCC3D819E33D054F
+:10D090006A8F44EB1D16267A96B008D133DFA3CBF6
+:10D0A00048C7A22AA3CE8BF414767308D82BB49B5E
+:10D0B0009B234B89884E7AAAA5823E111E8F615D03
+:10D0C000922DDE05F4790AF1ECA4CFAAC8542FDA28
+:10D0D000EF6D61B91DE5DB69B799DE568DF8DC5659
+:10D0E000504EFB07EB4BD77AD10F00BB4D7E406C07
+:10D0F0009E4CE76BCEC17ED3FAA8C6F71EAD8F5A01
+:10D1000033C4B9C4E15AFCF142B43F06F1C3E49E12
+:10D11000AE6978C7617A25B713ADAE44285C86ED59
+:10D12000133367A35EF821D70B4F449C7A21EE9905
+:10D1300003E5C5BE0CE2DB759BEAAFA075A01AA3A0
+:10D140007580357ED5AA8B57D0FACC9FA0F38BADD6
+:10D15000D72CA5FB132C3DE26C7762CFEB43301F3D
+:10D16000E4EDDB3E098030B2DFAB3D019CCFD17BEB
+:10D170007F1B30E1FDDBF72A74FEEF1BF8DD44C6B0
+:10D180006EADFDEF09781EBD5BE8B78BD2CC23C432
+:10D19000DFCB7388E9E6C7150CEE72BE82FFEE7C2A
+:10D1A000320D85BEB7BEA83DCB56B7E2418BDC7CC5
+:10D1B0005FEBCEED7BB5C100F7FC2733281E74541E
+:10D1C000DC137774D7902D18BFCE4D93C5B891A3BB
+:10D1D000288F381FA4C3EF3BDC2C417AB8CBC5EDB8
+:10D1E0009F3903F71DA2823F9CF37AE9C534EAF721
+:10D1F000B60715F29B66012E9783CA8DCEBB93E2CC
+:10D200002ACE79DFF676FB4BF930AFDB5AA430FA41
+:10D21000A1D8FE5E58EF4597AFA438A213AE59319E
+:10D220007BBEC89CF6BB346266A56C7A2EF4F369AB
+:10D23000B344F23EA7D9DEEE8E8ED5D4DFD39DD394
+:10D2400034E4E3DBDA1CEFE75DF59FE887DDE18896
+:10D250005B3AFD267F9AF09726B00BD15F3AD979D9
+:10D260002DC51F075A8F5B7ED251F0DFF120D51FED
+:10D270006B3D541EABD5A93CE23378FED0EEBD2FFA
+:10D28000918E50BB26207F3DDDF987B49BE1D5D23E
+:10D2900010F7DB2FD9F249C3738CE23F0AD723265C
+:10D2A000E9915B041D2E651EC30FF37C5CC4E3C6CD
+:10D2B0007F0EF514F84EB649B47E032DA0639ECFC1
+:10D2C0002D888FB1D83FF7D76FC17B79CF00F7E8B2
+:10D2D00034FB7EDBDF0BF740DF2D52787EA6F3B9FF
+:10D2E000251747845FD3B0E707D3916F8EAF91685E
+:10D2F0003FEDB82BDE44F507A5709D41D33E8C7AF7
+:10D30000D7E253D0201ACAB3931F2DBEE8E5BB8ED7
+:10D31000FB082F163F801C85449E5348AEEC87FFC8
+:10D320001C7CE6E4ABE3AEEEA128F74EBE3A3EC06D
+:10D33000BAE4D234BE9F3FD730A7637CE536166986
+:10D34000E2E701CDD7FE11F0587C54CE6356981712
+:10D3500066E27D854F9FE6EB9EFA5DC50FA0BF3C60
+:10D36000EE97AAB8173A46ED2FC17FC218E38A8D0F
+:10D37000EB7E56C1DFC39B3EF8B9E4E5D30FCC305A
+:10D38000CE8E27277E7AF55327DF5FBBE4B47DFD81
+:10D3900033BF63657012EAB3835C8F971F549DF9A6
+:10D3A000695CFFFD74C773A88717FCFBDA2083F262
+:10D3B00043B56D10D263C7632B8226EA63351644EA
+:10D3C000FC7E1857FA3D8FFD429A24E242F6FC3962
+:10D3D000985F0CE3E2F3DF70C7EB607E4B9E74272F
+:10D3E000D07E2E3EB080E80075B2A78B77F59F3FC8
+:10D3F000B7E0890707193C8FDE9E47F7988BF60B3D
+:10D4000017C3FA0BD9F8AC7974EDCA2C2DBDBFFC4B
+:10D41000BC1E0DF5C812B14E5C72E04AA2BF338F3C
+:10D420006E9EB03F4E79FF9143DE013FB42E8CC11A
+:10D43000BCE84E9A38B74B0D3F72C770DFE2C33776
+:10D4400073B7E07EF1B1C77E19C4F37596FC5B79C2
+:10D450006CC7DA8BCF781FDB71A127ACFA40F97566
+:10D460003B802F10EF0B01EFE8D72C3C24A79561F0
+:10D47000DC628B8BE6F5DC917D83C640FDCE9DAEF4
+:10D48000EC191C1C3FDA2B8B6EBD798E824E0B9EE5
+:10D49000F9B986F996BDF98E825E77EEDCAB21BFD5
+:10D4A00038F13AAD7DAFD6EDEF876EEDEF4EA7F3D5
+:10D4B000B43F3AA5A17FF2E18B12CB2DECFBFDBC72
+:10D4C000C77F19C47667A3DFB1C7B81D3DD621C594
+:10D4D000A5C2B3D3B105697541DF7DC0D854568A62
+:10D4E000F76D3668AC14D72F31D91746BFE96C7980
+:10D4F0000D37F80BADFBB9E8BCEA3DFB19DD3B4746
+:10D500002744A17EEA2546F77FBBB20D2595AEE103
+:10D510006932F91BBD79044775E20B26EE1B3F29E2
+:10D52000F44CBE9FFB1BE3BA4B7F80F7B2BA3A5D67
+:10D530002C6E24F7D54F1EE6723FA153A175C3731D
+:10D5400098172AE1FEB9DC7BC70ADF3FF731238554
+:10D550006FD34A336DF5468413F733C4FEFC78FE6F
+:10D560008A05C2F9B67EC68BFBDCD32B8B6CDFB38E
+:10D5700083F67D758417E77761829FF39870D8BE34
+:10D580001FA4083C4E12F40A2762849FCAB7ECED30
+:10D5900026F9AB294E33E92C719AFBFD62FF279FD8
+:10D5A000E5A31C528E09D2312348FEAF4BAC13F0D9
+:10D5B0001E35CCE73BECE7F6319C267F62E03988EC
+:10D5C000D6ACE9780E223C5EBEBB18EA97FA874DCE
+:10D5D00057416EC317C9CF14417D8ADFE0F5F3E5EB
+:10D5E000F12ED0A45B58E1F42A68AFCA122BC7FD14
+:10D5F000C37C8DE2C2AB35903B909BC62033338019
+:10D600006FD3DC2CE62DC7F10C1A2F0D162E5ECC35
+:10D610003313F16435C8BF6B74F1EFCEB53FAB9FE8
+:10D6200072D5A07B45DD25006B61729C7295C35F4E
+:10D63000E6E7F71BAB53CD10AE73D44C2DDC40EDB9
+:10D64000B81C9C6B097A7228EAC9377D5C0E14E518
+:10D6500024E565F7FC731AC5D9DFF47179F87A7A95
+:10D66000ABEB3CA8977B86DE8DC2F5A6B4FD9B2470
+:10D67000648168C44FF681D1B9E99BBFA1D07D8494
+:10D68000CC5F13407A4826B7CF1210E316CC379DF3
+:10D690001DF6A8C5A8CAEC796FC9F1CB7B12347E00
+:10D6A000C0363E2C1B3D68FFBF8E67880CEC1FEA1E
+:10D6B000C0CFAF57F2FACC785143B741F399E54761
+:10D6C000B972C787601EF5CD72FC9B3C2FD09E2798
+:10D6D00076DC27E442DC33862A14FB398EE301DF53
+:10D6E00056ECE6FE8425C74B3EE6FE00EBE276D61E
+:10D6F000CACFC1E9207C4C393D08DB7D7A50A67B3E
+:10D70000A1CA0FD8F9FD22911730F1208F034C7474
+:10D71000F0FD45BBAFA23CEF8BCEE27FDFEB17768F
+:10D7200049C8C3B9E67DED93CC7AA4D30C9599A9E9
+:10D73000BF7FB0542C744F1E2C4AC7F8D43B69529B
+:10D740006F7E22E64B6A20EEB81FBDCB619F2C7E18
+:10D750001C73589F83F31E7398DD2AF2EA6C794399
+:10D76000BDE3E81CBFE3D8D81FE011AD3EFAEE28B8
+:10D77000D777D67C2DBD9761DAF55D56B55DDFE5CF
+:10D7800044ECFA2E77A65DAFE545EDFA6CF0BCF3FC
+:10D790006CEF87D494DBEAC3964FB2B52F040392A3
+:10D7A0005A2F6EBED2D67E78DBB5B6FAC8F537DB17
+:10D7B000DA8F8ACFB6BD1FFDE402DB7BD0EB0AEA2D
+:10D7C000AF81F4F498F6A5B6F6969E3E7FF7776C97
+:10D7D000FD5A7A3A067F912FCB51F5025EC322EFB4
+:10D7E000EA6C7AFAC2EC1872FA57D6D3BF76E8E937
+:10D7F0004FD98C4A46FBCC7C3F7B20BEB4CED32A8B
+:10D8000069DC6E2AE972CD4E28AB841EBFCC2FE2B4
+:10D810006B3AE793137B46521C1BF3EDD08FB1ECB0
+:10D82000F80997BF19E35119C053A86706B2EB195D
+:10D830001D2F53BCABCF3927D9A078E03A2542F948
+:10D84000ECB0162D948B93F77DDC2FCBB7A6C67D5D
+:10D850004FF8B99C9C10767C23E873D4DF83D3C047
+:10D860002F2EA7EF6CBFF710C4DC5E3AB7FE9DA663
+:10D87000AA02BCD7ABBBD4C80091C2FA90A4FEB335
+:10D88000F41DE8D9F1B4CE0D44FF0BF519E8B12130
+:10D8900068FF6766D7B8248071B087C5304F19F02C
+:10D8A000772BC6893358B6B4B40CE39DBD7AD5F84E
+:10D8B000129868FF82D1940F7E72DE28BA27EAA4FC
+:10D8C000BFF7FE18CA73614698F6E76E12FB6E2723
+:10D8D000E71653BB37BE01D20BFCF82B8400ECE3F8
+:10D8E0001B1AC7C3D9D6B3F3B63C10C07DE9374A7B
+:10D8F000F9FE9FF5BC20C0D7110501BEEFB7646EDD
+:10D900001AE5FB2E8EBB685F6809A207FDCF38972A
+:10D910007BACE3FAADA5716D04E9619D2FF374D67C
+:10D92000C4304EB0A4E31ACA9BF8FAEB7CBDFCF5F8
+:10D93000FFE2711E6BBCD1017EFFEBE800DF97BDFB
+:10D94000110A3C3F7D23D02103CB97274F473982D3
+:10D95000E70909EA5777822B01F8BE265AE842E424
+:10D96000FD96855F7B16A63C2160D07CAF671117C2
+:10D97000F2F1EF58F4E3D70A53FAB3FA8149A11D43
+:10D980007F3D23E61A04FAADE76289EC178CE7C104
+:10D99000E7915B06AF4095698D67F5732D0B53BF1B
+:10D9A0003730D325FC189BBE5C3A3F2D9105FD2DE9
+:10D9B000057F1FE3B227EA7AFEF55B30AFDF2FF871
+:10D9C000CBB378E53D8B760FC175F04DEB15660056
+:10D9D000BD7FED332F0DA0BC54669DDB395820630D
+:10D9E0000CED2AE3E3BD2AE83DB3236BBCB0EF574F
+:10D9F000617F6FBEB86308EA915F8C7A6238E55F39
+:10DA0000579C5BFF967CEEECB5B7DC1E8405BF81AE
+:10DA1000BD20BFFC04F385D14F1E486E770ABB7C46
+:10DA20008F62923E392547C43900582642D9DEA17B
+:10DA3000308C77B7835F84721C44A1B6E40F7C847A
+:10DA40002026555ABFB702EB95D1423E6FBBEFC5BA
+:10DA5000E98DB45F65F7032AC4FAC8B2F711F88BF1
+:10DA60007AF522E1878F5C6F5F6F4F4CC8B48EE907
+:10DA7000B5F34EFB8EEB9673B0EFCB035FD5BE478D
+:10DA8000EB0280EFF652AED7DA133E9E978B3F152E
+:10DA9000342669F79DDFAF0C703D761FAEC5E1FB04
+:10DAA000AB1166A8A7817E09F0731331A59CEACC5F
+:10DAB0009F49F9D6660EAFC7D2A1FCBDCEDB6BD2B3
+:10DAC000F1524F06DEF3B0BFA9B900CF5372FC622A
+:10DAD000BD01FF6D8C273DB3D4D23307CEE3F726CB
+:10DAE0009E062811EF625DE49C5F05F035378642A3
+:10DAF0002EC4F78997BE08E23A7447A6F1EB8BD0A3
+:10DB00005F7C4561286F5EB55BCBE807CEE7506F61
+:10DB10008D04F90C707DEDD92DD1BD401E83AFE78A
+:10DB2000BCBA3E8EEEF38CB2348CF77CBCB398D684
+:10DB3000775707B9DE8AA5459E4239F8A3746882F3
+:10DB40005E4CFED476AC5B786D4FF0FBD9C7A8ACC9
+:10DB500059CD4CE2D51A7FC9FAF1B4D9B1787D1606
+:10DB600095A3705D0F8F9624387CC7773764F617BE
+:10DB70001F18D331FE0E5AEFE6F67CF6EF9867F4E5
+:10DB8000138DF675F1E8039E5FF9F1E7A3A9BF03D2
+:10DB900001BE5E85F1557C8E3FE486F7762D71736C
+:10DBA000FD78FC7385DAF5F6BB7B8AA203ADCB1258
+:10DBB0006DFB703DE1ED701BF47B298FF1FB16BD11
+:10DBC0001D5E922355EFF900D7036A875B6F007CD7
+:10DBD000ECF0F5BC83FCD5B3C76D6C85F73BB43670
+:10DBE0006ADF339CC9581F05FC81F7A779F5369683
+:10DBF00099028FB7E30794D7047C41F72C79D53687
+:10DC000076710A9DAE0E0608CFFF11E0FCB4C397F3
+:10DC100090FDBC5FB695E6959C27CE0BB7C7F83C48
+:10DC200047511C648706F3CCA679E9C807A3189F5F
+:10DC300027EB1869E03A5185F9D03AA984C9A81AA6
+:10DC40009CF35A3296C551DFDC5FCF6CBF1BB5C465
+:10DC500097AC7B40B676145976FDF326FCFDA464A0
+:10DC60001D145E65F2FBFFBAEF8BA6C6C929F2A3AD
+:10DC700072796A0A703B66C911E201E37103CA9BBB
+:10DC80009FB72BDDA27E82F0EF4CF8C374CFB8B8FB
+:10DC90002FD98AEB2C93121F5C8A7E5762DF5803C0
+:10DCA000E6B4F0E51786E2D1C23BE58E87C6C0FB3D
+:10DCB000FBB4A82B08E3FEF42D9905010F7FFC911E
+:10DCC000373E03FA297D7ECB20DC8F71F6B7F24810
+:10DCD000FDDAC1E86F3D2F19185F3EE1EAA138EE89
+:10DCE000E28EFFD4306E78F9EE7735F42B3607A349
+:10DCF000E9D86FE5EEBA6988C789ACAD01E375A0D4
+:10DD00005FE95E96F61013F18C115BEB50BE7AA2C0
+:10DD1000C3902F2F147265D1A143C8E78BE85740F9
+:10DD2000F9ACF06B9EDD7B53B19192471063FB28F9
+:10DD3000DE54CF0E0C467CF7FA6371FEFB05A37F21
+:10DD4000E7B9D54CE1BB7141EE478E13E3ED0D46CB
+:10DD5000870781BFEEDCFB9E1604B83E927AA6E3ED
+:10DD60002B90E711C194F5513BF847A9FCDB479E86
+:10DD70001DF2B444EDD1284E7994DF830FF46E4C3C
+:10DD800007FA3DF5BBDDE7D1FD2A3D917F423C7CA2
+:10DD9000F69A46BF0FF4ACF07BEB5EFB6C2CEAB15D
+:10DDA000CFF6DC390CF1971BE47E0BF0FF541FCA51
+:10DDB000D94E467ACD92D3329453984A99CEF737BA
+:10DDC000CB90FF0B91FFBBAE24B97C56665C0EB9BD
+:10DDD0003C00FFEBA82FCA749007FA7E24C9F98E85
+:10DDE0002E99EF23829DC07DC81D32A016F8ACC2CB
+:10DDF00095D887DF55C0B87506CA6B970FF334D82E
+:10DE00002E391BE38B15787F740A5E9A02419A6F54
+:10DE100093F0EF1E1676240D377553E422C5FEF2FB
+:10DE2000BAB0CF3FBCFFBC95EB30E9D914F641F84E
+:10DE30003D2C3A9EF4FDDDC2562EFDF9A4ABF1DE79
+:10DE40009AA5AF2AF47E8259330D432195D56DFBF7
+:10DE5000B19C14699F86E156B417F87B7917406925
+:10DE6000825E9D3CB36B3F3F8B6B8E463F69D7BE56
+:10DE70002B46A39F70E20D37FDA6C5891D573E8531
+:10DE8000FBA627DEF03259EAD78FB1F199B33C21D6
+:10DE9000750731AEB42C38E97215D6D28B2772389B
+:10DEA000EF0A56AE8CC1C43E0B9ACB90AF827A94E7
+:10DEB000CA1387BE1884BAFBD9C3EF05D1AEEFD21F
+:10DEC000CCD13A95FCFE4967FFB383FC1EE40AB14E
+:10DED0008F89F284FED2C7EBB3B6A03C7DBC4B3138
+:10DEE00007E1F9E7A0C80712EBC7DB38DAD8BC5D59
+:10DEF000DC9FBEDDE4F1DDDBD0AFC1FA3AFBEFFE23
+:10DF0000CD637C3D3522C628BEB4B85DA2733E23E6
+:10DF1000C5F99D25621D39CFE1BF2CB4E2B28EF860
+:10DF2000ED4211A75D789675E34341E1EF14B362CA
+:10DF3000F477802F68DDDAF39A12DECAE89EA54EE8
+:10DF400037CCEB29713F27E845922BCBEF99A49B67
+:10DF5000BFD779DE0DB71B625DD7B3438A931C3CF4
+:10DF6000C9E8DCD9A4A3C616CA6B889974CFF83C5B
+:10DF7000A1E726897D96491D852447F384DF5769EB
+:10DF800072B86F07B8E3644E397C605EC90F9C7449
+:10DF9000B44D413C2DD824511CF4CE279DE7F839CF
+:10DFA0005E16AE3FF412E64C2C6A77BC1F208EFD45
+:10DFB00034FEA39FFD889F59781ACA86A6FA85ACBD
+:10DFC000B3FFDF9B48EE3FC4481E3F12E7737F2339
+:10DFD000FA873F7ECCCFFB83C0C3EB827F169B9C2E
+:10DFE000FE0BE34A3C0EF39923F885B5727EB1CE61
+:10DFF000C5E0FE0AC1BF4B621BA4BEF0CDDBEE2222
+:10E000007F7881C083B55F376F939DEF16083C2CF6
+:10E0100070E0617154B2CDC3F2CFE708BE1E785EE6
+:10E02000ED37223D176C77F1DF6E524ED33C3FDD6A
+:10E03000C5E9E49CA7353F6BBE7FEB3C9D74EAB11C
+:10E04000E8741E3BCF46A7EA33DFBF90BC97C8EE0B
+:10E05000E75A7EB2C517CEEFA70BFFF8F2F5DC9FAB
+:10E06000DCD5B5AF19FDE1F23D8A8EFB8EBBBA4E11
+:10E0700006713F68FC1E9EB77EA263FC6ABC9FE3EC
+:10E0800099CE92EB304FB7FC904CF231FED5F2387E
+:10E09000A64497BF5A9E564CFB724616AE1B4E1CAA
+:10E0A000E476F5C4C192DFE23ED389CEAA0A446B7E
+:10E0B000DDC1F234B4FFCF30BECE975EFDF3AF705A
+:10E0C000DCF1AFA81330EED7145248AE2E7F78D6CD
+:10E0D000365CD779D2F93AFCA5AEA5D7233D161DFB
+:10E0E00094757C7EFCA04CED16FE50A1BC53A6DCC2
+:10E0F0009BFD4F48AF0E97CEE7EBA2F197EC199E30
+:10E1000035C79FE483D9826FCB338C0766A09F9776
+:10E1100097467EF1E5435C64178FE5A73D8AFECD07
+:10E1200008730BED231F7BE16E19C73DB1436221DC
+:10E1300000E0A5D0FE7FA5FB4A9E3B44FB5CD37666
+:10E140001DA27DADD9D6BA4FECD75A7C7507AEEF7C
+:10E1500060FDFA71974FE483B46948974587AC7ABC
+:10E16000B786F63B22FCA2C58FBD4BF505E8E72339
+:10E170003F3E2651DEECFE3D3F257E5CBC9DEF8F91
+:10E180002DD8BD653AB6BB93B5D33EA7538FCC17F8
+:10E19000FC79C77AC773C18FF3CFC28F53D3455C65
+:10E1A0006E141B45F7814CE1F78BB427660FDB013A
+:10E1B000F33879C44D7C7106BE24FB7750C47D4E84
+:10E1C000266413F160B53B7EF0A486FEE3F48E3F37
+:10E1D00011FE6674ECAD42BC7C8D4517229C5FEB52
+:10E1E00048D371BD3CA39BEB952B3BDC6457BEC66B
+:10E1F000DA1BC5EF3D931EBA43D0F30E81FF132FF8
+:10E20000BAF93ECF0B12F9277780E2CD0255B7500D
+:10E21000C485D9263B7D40F2BEC1F70BDDE45F5DCE
+:10E22000556AC7D7958CEB932BB74BA44F168B75BC
+:10E23000FA55CCB81A9F5FD589811918372F6D26EA
+:10E24000F2DBC2ED8EFD66B17E5FECB07FD7A773C7
+:10E250007FED6FFD5D866FA60B3D21E832A387C77A
+:10E260006BAF447B0378E84CD497613CCAC293936C
+:10E270002E9DC699F7937F25FCE9DEF515080EFA69
+:10E280006DED3AA7C32B5D3994F7B460A21243FF3A
+:10E29000E1AD74AEFF17FEF5BAAB3141F698BCEFB5
+:10E2A0005BDBE1FD47B3DA47205E60FD705F3ABC9F
+:10E2B0007FB9604EEB38F8FE8F3B5C61D42FCCDC2D
+:10E2C0003202F5E5CAD00333707F6BC976FE7BA8B6
+:10E2D000C72B9518E953B5673A8EF7D11E49477D8C
+:10E2E000BC64F7277CFD80FC0265A443BA0CF905E9
+:10E2F000FCF287B1FF8899E1423A2EAE027D0DED26
+:10E30000AFA9FA93867805FF7C437A8A7FFE4A4953
+:10E3100031ADB75F510DBA477220FF7CF1E7DC1FCA
+:10E32000B49E2F0639457C2EEE90681D9AF4077333
+:10E3300025F207F7FCF44026E9898C71489E57D2F4
+:10E34000F9FA01FD06F44F6F17F687498D2417BBC4
+:10E35000F67D7823C2D7F3BC8B9FD984925D08FAEF
+:10E36000F137FC77C18E3F27D1BED11D3ADF273A66
+:10E370003E9BD3F933F06F40E3B3DB851DC3F71841
+:10E38000EFBC1DFCBB4BCAF15737EBC53AA7914A0E
+:10E39000A7FCCFDBFD68135FE6A73C077E5924F896
+:10E3A000DAA9471609FE5D7496F8D3E8177F5A84F8
+:10E3B000F479CBC19F00CF6AD4AB275E51748467D8
+:10E3C000D7BEBF6CCE473F0BFCE822D4DBC20FD9CF
+:10E3D000B5CF4BEB8A1387FC71C4E71F051F1E13D3
+:10E3E000F1E2BA4A85F0234FE4258E87F43DB1E788
+:10E3F000D4D028E8E1A75EFCE97926C5E3E244CF62
+:10E400003B9FB4E7D72D6AB7E7CFC1BCB87FFA3BD3
+:10E41000BEDF04F31A81E7EDAC793DAB7607C3FDAF
+:10E42000C88F24ED23FAC9927D1DB9E479C5767FA2
+:10E4300011C0732BEAB7E3161FA83D83D02E9E4C64
+:10E4400037687E751D9CDEF21E5EC2F837F2F888D2
+:10E450008BC6EFF37E6A6C21AD030BD3685FB713F5
+:10E46000D6FBE950EF3CE225FFF35BBF593032F5B4
+:10E47000F71C98C4D7BB4B5C3D83687D7988DFAFC0
+:10E480007425FB13E5795CD9E1CA064CB1978A7E05
+:10E49000A6D27EC658895D00FDC470DC5CC6FE2F26
+:10E4A000ED2D8E7D008000001F8B08000000000015
+:10E4B000000B8D566B6C5365187E4E7B4E2FEBDA3E
+:10E4C0009DEE52C4112C63ECA2DB38BBC0C64D0FCD
+:10E4D00043CD8253EA70824AA4A2C144D92A12755C
+:10E4E00009269C328980FE20FAC71FC61C49349A2F
+:10E4F000A0296EC3FDD8964E87B0E1CC1490B11818
+:10E5000033F66368C2DC349185C438DFF73B2DDD18
+:10E51000CD689BE6EDF77DEFFD79DEEF1C87D497A4
+:10E520008B3B80831976600D1059670B9925C0616C
+:10E530001C16FBED3F6CF594660393DD39E5F62080
+:10E54000F0B7CF06E4003E35E45649765C1AF38511
+:10E55000D3019CCF04960233FCB96FA1040C611760
+:10E56000E9562057016DC34EB35E026E764FFFF839
+:10E5700014AD6FF6CB1AC87FB4DB696450BCC88891
+:10E58000DB74AE20B3707875C80BBCDAF37C21382D
+:10E590008E4479D5907E4FFF5161774651D97B5398
+:10E5A000F7E50028EFA68E35EF1AA45F3958F15031
+:10E5B00090D66D5D8A0ED2AB18AC32DD14AFEDDBB8
+:10E5C000AAAC95A56CA179D86F53BF1C32D359560C
+:10E5D0005DA8A7B84D83B555128719ACCA1A25FB9B
+:10E5E0004A09A1189D4BFDF9629DAC27A85AFD9AD6
+:10E5F000EC75EFD6695F429EC8CB867C21937AFB8F
+:10E60000DACF3A38EF7D9D76DD9C659FB4AB5265DD
+:10E61000D1971A3528643426E9A8263FA72DB9AF2B
+:10E62000B32DC075BCA8C4022AF9899E52ACF3CFA1
+:10E630002C099C1079181AE1B204B8C05B84C3801D
+:10E64000643E074A7140C14ECE7FE06AF8AE4C96F8
+:10E650009BC3852CBB5449C44BE663A056E40DA96B
+:10E6600041E03ED1AED4715FE6E3D891B0F365618D
+:10E67000776891F34F559BC867AB03618E0BE8E950
+:10E680004BD702DFF15F2AF191BE17EA551F7040A8
+:10E69000B578741121052BE9AC46191B2D0242F403
+:10E6A0009DC9031A10CA8853A8C2F7E4B15117C410
+:10E6B00067867EDBE9D742548B1569391AF96FC436
+:10E6C000DBBFDBCB48F66DBD0E92DB1F5674C7EA8D
+:10E6D0007FE7E1F63A658EBF46C822AE5813DF5A8F
+:10E6E0007EFADEDF57943ADFAB7AB3C73DF4A7007A
+:10E6F0000533D44FD8D33D12F1E4CFF38A6A677E55
+:10E70000C2CC0F952E8C337D68C8DFA700DF1CA21A
+:10E71000B20B693C0EB984FC4AD2232AF5A75E8667
+:10E720001E5BA47F6F7A25D1BF68F195B251C6AB4D
+:10E73000F7EAE77EE2EFD45537F298987F5116D486
+:10E74000CF263591E33CFB281A048E87F1D81C1E96
+:10E7500026F19C00EA62250BF13C96C0A3B9C8796A
+:10E760008DFBD96C9F72302EC78EBE13621E295D41
+:10E770005183E33DE908CEE14D73E77E844B385F7A
+:10E7800027407D997840329D92C87BB953E4ED448F
+:10E790009EE8D3D0077E3A6F1C76E3389DF7165F6C
+:10E7A00071F03C11F12E2140BCB0CA41537CC8A18C
+:10E7B000D2FE36978533F385712D687FE60812FB0C
+:10E7C000AF57D03E71F4DE8A59FD48F06B5BCD5CEB
+:10E7D0007CA3C834C45C4AD9421662E8C15CCA63EF
+:10E7E000872E6926E93FAACFE783C5A7869DE567FF
+:10E7F00073B0085F123C9BCF9B5E357C8AEFC3C928
+:10E80000A13F1E2F25BF03C5D797735F9A1373A02F
+:10E8100015063B4729AE76412D6F259B88C757A625
+:10E82000124FBF4CCC4BC4B3DC04CDC5FDDE7087AA
+:10E83000F0638EEDA5CBE4B69F8DAA2AF40614737F
+:10E8400019DF03C9F9D396A0727FFA6C3C2D1C3BEB
+:10E85000981FA48F922C60DD7FDFCBD1E273658C93
+:10E86000C7406F7F9963166E375E0E1772BC48F70C
+:10E87000D78160FA6C9ED9123C938594248B7736AD
+:10E88000692EEF6E30EF4A585E0E6C607EB46FC931
+:10E890009182A9F348C745DFAA597E27BAEC421FE7
+:10E8A000F26841A377769E47449E1331CB1F816D5A
+:10E8B00030DF9ACF94AF3D6EC160D8789DBFE763DB
+:10E8C000E617D02AF4937C752B869E4BF52878C9E1
+:10E8D00060197340D81B3D4EF3235A4FD2ACF273EC
+:10E8E00062F29AFAA121F8BA0CCCCB33095EDD4A68
+:10E8F000E0544D9712F3721D62769E8F6AC8D8C598
+:10E900006B197199E44698769E976A39DE2B958942
+:10E910007D43269E6EC2A8D8A75264B6DB8CA0CCDD
+:10E92000EB2D305AE9E181AEF62FEC7CCDC403B279
+:10E930007F9CF8C657CD6278A5FA21633CC93F5247
+:10E94000D69CC4879254DE6B252BEF6A1DAE168AC7
+:10E950009FE7B7E67C0386441E9AC7AA77EA16CCDF
+:10E960009312C4A36417E96D905167A73A36C97032
+:10E97000A5D1FA749F4DCC75CF68D0E4FB4ECB4A3D
+:10E98000D8FD4A762B5275AE27FD8C4C5EE3A8224B
+:10E99000FA135FB4DE1CFF0A910779789AFD6CE9DF
+:10E9A00072E2386DD95C869D799EEBB7F0F250DF4C
+:10E9B0007CE467FD0909C39487B6D2AA2FE97F3D9D
+:10E9C000285E05EB5B75D11AC3B4EF7159763449F3
+:10E9D0002AF7478A076C339EFFDFC7C90044DEBEB3
+:10E9E00067A77E3BC875763BD5939492D6756E58D3
+:10E9F000A2F994741DDC4FCD951EB7FB1830F9C6F3
+:10EA0000EDFB819E5BABFD7B4AFDC41329A88A7E8A
+:10EA1000228C20BF672CC1FBEAF83DFC7E407AD4F3
+:10EA2000C391345F19322CB87E21BC76247836929B
+:10EA300066DD039F980D41E6F3CE6C97C67DAF70FF
+:10EA40002DAF04F987375CEAA77A47A453AB843328
+:10EA5000D95CC3FEDFB0C7C07D9E765B7EE9ED4129
+:10EA6000F0B4C565AD5F4BF39D6439EDB6FCF30CB6
+:10EA7000326F3D746DBB28CFB7681E5CB4366A2D0B
+:10EA80007C8D9FBD662BB576DA161264A4690ADA0E
+:10EA9000C8BF5C8B7835E525DFE910E74EAECB9338
+:10EAA000AA2B193F59DFFCF85CEFC664BDB6543E93
+:10EAB000C9BA17C63794BBADFA0F8820DEF01389A8
+:10EAC000FA5F116B98ABB87E0FF41AF11E8138F81B
+:10EAD00079A026FA99EC83CA78114FA1135E49BC3C
+:10EAE000F3527D782BCDAA5F2164859F20E156BA31
+:10EAF000B0BE7F00ABD1094D300B0000000000001C
+:10EB00001F8B080000000000000BBBC6CFC0F0A3A5
+:10EB10001E81F5B850F9E87835072AFF1D01F58404
+:10EB2000B00A0382FD929D81E13113042F84625764
+:10EB300020368462566608966741E8F1646360088F
+:10EB400006E258204E67C36F572D0BA6D81539061D
+:10EB5000860C25047FB72403C37F202E94A2CC5FAC
+:10EB6000A37868E0F786A87C7F6D547EA22E0343CD
+:10EB70009D11821FA04D9AF99F817ABF003100211B
+:10EB8000F9ED9E6803000000000000000000000096
+:10EB90001F8B080000000000000BC57D0D7854D5C8
+:10EBA00099F0B933F7DEF9C9FCDC8449988421DE99
+:10EBB0008404220D38A401631BEB0523C696B523FC
+:10EBC000756DB4964EC25F94BFA05B495BBBB990B4
+:10EBD0007F0C6494A8A068072C2E2A6E83EB5FBF7D
+:10EBE000B57610AAB8F5EBA67DDCAD76D50DA89468
+:10EBF000AAA5C15AA17DDAF2BDEF7BCECDDC1926E4
+:10EC000060DBFD9E9D3EF670EE3DF79CF7BCFFE796
+:10EC10003DEF3971F94A59E802C6CEE0EF32C67AC3
+:10EC200014F6AC14644C61F3FA9A75A833F81533F2
+:10EC3000D68BE525F05FD221B3798C7919FF39C3E2
+:10EC40008E23AED98CAD57A171213C8814507BD94D
+:10EC50001737790B591F75D33FCC33D332EAEC8C7D
+:10EC6000F393D4FF3823B36EF271D837192B62ECCB
+:10EC7000EBE21DFC0CAC37888A351FAB645195A5BF
+:10EC8000AAD2FD34305ED71D123B23E1D3CCF7D698
+:10EC900038A73C81D90CF0D1EEE6E5066F603796D7
+:10ECA000A73CA549160068A57835B63317C027B527
+:10ECB00050BEE54F76527F6D17C5663106FF6E1A5E
+:10ECC000F6E580876D626C2EBCEF18DEF64E65FAB5
+:10ECD000B933124D613FAC8E45F7004A998FC93860
+:10ECE000AFCD9235CD51D319026843D14F6F86F71E
+:10ECF0009F05B871FCF56AECB31C2F068BF9F1FF88
+:10ED000075EAFF807FDE6B7168FF61AD1A75C12304
+:10ED100017D37F1E2F636CEB25FF1906C8994B6E26
+:10ED2000631AC0E7AA60C670357EFF6D86F4FD1DCC
+:10ED3000E2554FC3F579E6A0FED2F067E2EB65FC41
+:10ED400007BCEFEE48A52A14C6B64CD507EB615CAC
+:10ED5000F3FF3AA37BA8D548130BE1B8450E9C4BB3
+:10ED6000B7027881F1063B584286F9DFD1E1A6F27D
+:10ED700032564EFD6CBD64FA6484EFC025D383A384
+:10ED800050DE31CBDB9424F86271EC674374F853A6
+:10ED90009B611E4AD16186F8387564FF67916C9754
+:10EDA0002151000F52919BE8B121C0922E9C6F1906
+:10EDB000A743C32C999E2B756C978B70BA9EE66BFC
+:10EDC000F151A08E99D390FFEB4D03708FE331A4E6
+:10EDD0002360D4576CE37BB90EE866F1254DEF2A2A
+:10EDE000EA47D138DEBCD1F8220405E845F4605585
+:10EDF0001C5F1AFCEF0C4C31EFF76F3319E93C95AF
+:10EE0000B1A7902EBA0D9FF09F930D9C74CE4639FA
+:10EE1000B43D877938DFB8EA57D8AF33EB79DE9F56
+:10EE2000FE2586F3DA5A778B7723CECB7963300EC3
+:10EE3000F0E7D571F9CC8B07120D9F4ED3CFF7C6F3
+:10EE4000FCD421DB789DCC1F3A9607FFB8985D4C27
+:10EE5000FC2FBECFE65BAB3CD561A40E29346F8797
+:10EE60005D0E276ADFD9C1586A46BADE556684014D
+:10EE7000156C1BFBA22183BEE8528CB0148576E58D
+:10EE80005F301A41CF3867A4C251187F201F3A2D36
+:10EE900061EC41734DCA84BAB3B38D9EF7E2D89F3B
+:10EEA000B13DBF3C168E027F747B385F658FFF5F7C
+:10EEB0008031E22BA52DCCA6A5F505810DF8776B49
+:10EEC0002FFE5E02BC6E95A2A747518E8B03247F56
+:10EED000F0BE4F2EA0B251ADC1C66ED27F1EC1078B
+:10EEE00050EB926BA86C500B705E6DAF3523DF1743
+:10EEF000FB38DF7F60849BA1BFFEB945D1CD367959
+:10EF00007A9E49C4A75D0AE7CB2D4AA69EF831BE7A
+:10EF10000778FF153800CB2E3F9F17D3B685AF99E2
+:10EF200095A39F7C8E8F7F376F36CD6A9C07C80074
+:10EF3000C251A926F794E16C13E1C5C4C7997A734D
+:10EF4000227A65EB4B7705D4EDFC1EB6BD2FC7FFCB
+:10EF50008F68C43FA2FDF388D44282C3CCB7C3A15B
+:10EF6000DD195E8CF260C2380087274CCC6E6FCF03
+:10EF7000E79982F78867E00DA4979ABFE2704AC7C5
+:10EF8000EF5986FD59AFC69F27BD135C32D6AC73CF
+:10EF9000B292BC99F3699E0AB37E5FCFB4179719FA
+:10EFA000AF39515EE6A8FA26D42351352505F8ABD2
+:10EFB000B179A8DDE087CFEB7A4624901FD51730D2
+:10EFC000F302D89F90CB70A6BC9E4F5EDAB3E4EDFF
+:10EFD0006496BCA92C164C217E128D244F0101A7EA
+:10EFE0005AAB9A389ECA0646B01C97BBCF2E0EA2CB
+:10EFF0007E5235F58813E052C349661FBF0FE5CD39
+:10F0000005CFA5D89FC9CE041FA4F7B26A865B506E
+:10F01000EF94AA422F8F66F0D3CBA8E7810EDFC111
+:10F020005773F1FF12A28C86510F7677B4B3B741B4
+:10F030004F7B5FB889E9B3D0FE31F20BD4509B61AE
+:10F04000107FD6723F0109817A56ABDA85FA5ED11C
+:10F05000DDCD3AE24DD7AEC192B18DD4AF5235730A
+:10F06000B944CF7B4ED23C42064310E40A46F896A0
+:10F07000B518C10D742E96100E7726FDC7E9AD8523
+:10F08000C8EF80BA1E9B95839FC7FD066B3E4995CE
+:10F09000EBF5F13A9BF03BA0878CFF04FE92C31C7A
+:10F0A0004E39EC25BAC811F9D8A85D2EC4389DF8A0
+:10F0B000CF629B5F3555F035FE428897E84368BFC5
+:10F0C0007A8A178697C2F33A49E5702CCA9C9FF555
+:10F0D0003DCCBF0EE72F6B71C28735EF9EE2E94151
+:10F0E000B493CC574078CF86BF07ECB16CF32F7A3E
+:10F0F000140B8E24F73F4A587212F2FD1F3F5D85B4
+:10F1000072B956D033BB9FDF4C00FF6F7E7025C1B4
+:10F110001F93B81F720EF86352E1D9F0FFE6073370
+:10F1200038FCCF1666E0CB2AD7BA0FA6E44976FAA8
+:10F1300071BD5D2CE8511A19998FE2B0C377FAB509
+:10F1400038D4B7300E7FC2777CA102F56061FC6BCA
+:10F1500088B735ED6D3AF255F132E6C0F1360B3C29
+:10F160005CE18C788E023C773694075BA0EC96B815
+:10F170003ECD86E37E9027E1A75079EA4D0EF73920
+:10F18000EC5D06DE3B57CB8D49E8BFD3F7C44F1784
+:10F1900002FEBA431535E466B64AE4DF79253E9FA0
+:10F1A0000D9224F891E307F0B601F1A68438DEEE63
+:10F1B0005F739DC01FC063C78311373480A7D870A9
+:10F1C00098AE00BA157113F57FB89D814349783028
+:10F1D000B19F3561B6005DF5B5F11109CBCDE3FC0A
+:10F1E000A05D5501EDB7BF5C59B3D946B78312F79F
+:10F1F000FB582DF7EB990C7AC03FB17CF5039EAA22
+:10F200002BB19E92B0DD77B0AEA4DB2D90E27722D9
+:10F210001C910A2E3F91B63115E773C2D2FB2C4CDC
+:10F220007E54D7B87C275A7713BF15CD41B81E90AE
+:10F23000B87E623BA589F8EC815C7212A988A33A7A
+:10F24000645F94E3BBF0BD628E68C80FEEB6312AEE
+:10F250007BADF14D3682FD968CFBDB9CDF03BABEA5
+:10F260001BF5D87E419F92FA9EF50EC07371AD4C8E
+:10F27000F82E196D5EC4603E6EF4CF66D373F2BB98
+:10F2800022AD4913BBBA404FCE479B32438EEFC7E6
+:10F29000F103970E19928E2805B8408EB62B71F2A5
+:10F2A000C355F03B6382CECD36FE7A41CC5B093349
+:10F2B00023599DA6FF0EA7C0927197676535B6F3D7
+:10F2C000127CA5EC5AE287A92C66201FA8693E385B
+:10F2D00080F8D7978D2CC4F1D78647366209FC4F4A
+:10F2E000FEF676C52C4638B6AF51B9BF6DB2578918
+:10F2F0003F1D9CCFE03F9DFC1F51DF2C71FFC48B55
+:10F30000F8C0F983BF8CF6DA353B613840FFE7B7C8
+:10F31000B2287EE645FC04D2F851A249D381FCD93B
+:10F32000C6A20643FD9F38A0EB849FFF40F802A0D1
+:10F33000975509ED41D240DD7BEACD8B1B910E1F25
+:10F34000FA1CCC5996E6C76C3E947D207776BB9C20
+:10F3500065BF2C7BE2F4198CF40E8B92DE776A2C5D
+:10F36000817ADD2DF4DFA7A4D8BB08477F7E6BCA66
+:10F37000CE5F9D2A6B253ED1AFA576FD950B75A47A
+:10F3800013744C76BB3FCBAFB2D6793D1D49B29BCF
+:10F390004CE7764A0D47090E4BAEB3E172B63BF52A
+:10F3A0007726D9C6ADE0F6DEE94E109F78127712C7
+:10F3B0007EE199B0E35176AD1FFD0407F9698F41F5
+:10F3C00089EB024BCFCB216F86FFE66C5733FAB740
+:10F3D000CAD35146EBA3DF26A5A409DF2F0DFF6A90
+:10F3E000A802D60D2DEDC57763B9B27DCE900CE5A0
+:10F3F000D1816901BBFE3BDAB79CEAC776565279E8
+:10F400004AD17F7209F4736C9733BA0907FDE39907
+:10F41000334EE09B16A1AF0EEC70915C1D7B40A2B9
+:10F42000F5D9CA3EC9CC43FF265F2F45FE3FD6BF64
+:10F43000B294E5D0AF2D6F802004F17D5929CBE146
+:10F440006FADECEB5D8FFEC4CAA4621839ECF20616
+:10F4500047342C39D18FA9BAEF1D605D27D21BE844
+:10F4600031D3A1D37B905103FD70E68E92BF3CFF58
+:10F47000ADABC2A35877C42F74A09F7DE4CA308E71
+:10F480007B307F6118FDFC5BDE744551AF6C50DB57
+:10F49000666836783604D438C98F6F28834F2B1CA2
+:10F4A0004A867DB1E03217B0262FFAC901A675024F
+:10F4B0003E1A7C20AEC8EFA312F5DF29F8277BBEE9
+:10F4C0004AFBA7891EE3755F94E9D5E452D33C9CBF
+:10F4D00055BCB4DE1B0EAE1F2E77F0F550A9237E6F
+:10F4E00039CE0BD5487B01C6736A87B8BDF569C7AD
+:10F4F0003E25F0E744F8B4D7709D6DD6A83AC237E0
+:10F5000030CBD2D729BE3E96530CF165C1D900E06D
+:10F510003B6DF04F6427073B4E6F93315ED0C18641
+:10F52000D05E0EFA8719D27D931C253D080BCCC600
+:10F5300069D0CF40B4A006D74F9BDCFCF9262DD56F
+:10F5400078393C77461D35BB75A4A79BBEDFA4A7C1
+:10F55000FAA6D99EF7766843D8FF2623D5676FDFD2
+:10F56000DF11E6CFCD5463596DFA795EFB3C9AFF0B
+:10F570002676A071BEEDB905EF26F6425F59CEE7BB
+:10F5800087FAB07D273E67F6E7870F9785D2CF7160
+:10F5900001837A42A86D361039E46EB1F1F9265F25
+:10F5A000B491FC6814127B3BFD8509DA1959ED26EC
+:10F5B000EACFCC6C5701FDF972B583056546BB43B4
+:10F5C00013B57364B4ABCADDDF4055E6F756097C6A
+:10F5D0007797C326073EC17703B0CE26BE3599FB89
+:10F5E0009BB0AE96EB5957F945E04738B8DD6DB79B
+:10F5F000F83AC2E43A78EFAC60F2E70A6CF1339D76
+:10F60000B9E9791573673CD7C04FCFB00BD9FCCDA2
+:10F61000B67B90BF8B84FC85B8DD3C1FFF821E212A
+:10F620003EEAED18DD86FCA7B04C79B3CA6187F0DD
+:10F630005BB2C68579B26F16D0BC481FB2373CC9E1
+:10F640003D3055901DB9AE80CFF37335B6798461E6
+:10F650007E057C9E19CF2399F3B39E77A13CDAFCFB
+:10F66000AFFF423D87F6205CE3D67D693F69FE5BD4
+:10F67000D78731CED68DFAADFA6CFD36D1FCEFE8E6
+:10F68000181DAAA844793A4E6567B4461B253F5712
+:10F690006629945F3946F2BC418D1968EF3700EC5A
+:10F6A0002680E0AE36283EA15430B438609FC0AF0B
+:10F6B000217B9860E8C778853EF258FAF88F1DC420
+:10F6C000BF9B7D5C343CED27862A72D82F6FF803F0
+:10F6D000B2571B022C9E8B0E071CAAD07BB1238E27
+:10F6E000B9E81755E7D67777B22A8CCF399937BA68
+:10F6F00091F431A7CF87401F8C1B3A7DA62BD77A78
+:10F700005F6E7F7F1BEAE33FA37F3417F17A09E145
+:10F7100075831A0DFF6388EC024A223B8871D9DA9F
+:10F72000F3E357699F427617FC012AC7E91D8A3225
+:10F73000F20734112F0EB168A5CEFD88955CFFB39A
+:10F74000DB6BF0FB52FE7D3C7237E26B22BC7C30FF
+:10F750008E17C3E99C9B031F8FB3D7D03E9DF23316
+:10F760000DE38B07DFBC98C6BDE508970FC00FE11E
+:10F77000EB43C017DA739FA09FD57F7FC718E78F31
+:10F780000EF7DD58FA059E3CBE0435F6D426C6FDBC
+:10F79000994AD2E7A7872A48AEB4BBB1F4D72699D5
+:10F7A00084F4A86843DE4FB7D7A03DC3F7B114BEB9
+:10F7B00097F13DB3BD8F58EFE30CEBAEECF7BAF524
+:10F7C000DE642B511E7C009F5D4F38E2554E905BEE
+:10F7D0007704E0B0F913BE30C767369E0E1D99114D
+:10F7E0001C3D471C68B0431FE2EBC8D3A42F06CBD7
+:10F7F0008CA65835C56BE8798FB0635BD03E41B9B4
+:10F8000019ED1794CBD1E945BAC8DCFFEE63D64FAA
+:10F81000636EA8F7332E1703B818263CC8C9DDE875
+:10F820003FB336F2C7FB64FEBCAF4A4F92FDF68889
+:10F8300076D58CDA597649F6F07E02B00C424459FE
+:10F8400070F7699BC8AE0CE41B06C23B5066BACD8C
+:10F8500010EED6805D936C7A5C351BA95FF1DCE716
+:10F860003563BC2ED7E41A271B3FEEFC4D1A8EE3FE
+:10F870002B30C8CEFBCA4DCDB47D6FB51B50A1DF78
+:10F8800050FAF98037C1C7AD8071CBCE3F4EBF76FD
+:10F89000179F4F81984F79C26DDABE1F6F2727DC03
+:10F8A000B79C639DEFD1816E36BE7085817E1976DF
+:10F8B000264974CBABD2329E076AC319F5836FCE4B
+:10F8C000983C6A1BE7D0E8B473F2D131C147E375C5
+:10F8D0004F7C09CB67ECF9CEE7E77745A0AEC44B88
+:10F8E00025A83F74D7DB1B1BA732B642E891D6F69A
+:10F8F0005F6D437DB76260A98AFA7F65FB6F490E31
+:10F90000572425D2BF2B84BE68315904EDD2634EF3
+:10F910002FD92DCBEE822D27BBDB12CAB44B2D1A6B
+:10F92000B74B2DE14CBBD4B253C98A8F817FEFC74F
+:10F9300071DF1FB2EBB39503B7727818DF875A896E
+:10F94000FAFDD3D83E5EDA04ED1F707A088E63FDAF
+:10F95000334A51EF1E95F407DB314E7F9397E2F463
+:10F96000D9F8B1E28BB8B627BB2BECC78AAC7DAD1A
+:10F97000EC7285B01F4C8E139C7FE9783B9D5CEF49
+:10F98000AFB0EC16CCB769567AFCA3218E8B41A799
+:10F990005BC833E02347DC711C7FA8B7ED78FA0B16
+:10F9A000F1760F8E5388F8E378F8A4DF5BEF7F21C0
+:10F9B000F06E8B935E8878F96BF9E9A8D36BF971D7
+:10F9C000DCDF69F592BFF3B7F395F9D7D1D9A10977
+:10F9D0003AC0BC66D9E896452FEBBB1F097C8EA2C6
+:10F9E000119A7B369DB2F174B4D5EB70C27AF5E80A
+:10F9F000E12B68FD7E13E20BDADDA7EA4B50BFB5C1
+:10FA00000A7C1D03BBD85569A7CBD217EB80DF5A00
+:10FA1000FACAF225DBF850EF09034C2B76E6D72023
+:10FA20000837F5713CAFDCEEB9BBCBA64F00DF1554
+:10FA3000DFA47D29B725BF99F8AE10F8AECEF49FAC
+:10FA40005BAAB8FFDC12CDC2773237BE5B04DFC0E1
+:10FA50003CBBEEA2795E1EF4F8D2785A1A2E263BF1
+:10FA6000795F400FA09E3D06760EE77914FD7CFC81
+:10FA70004E8E6EC5388139E09C6397ABA3EEE8D615
+:10FA8000EB733DF7457F92ABFDDB3BE7069A73E8EE
+:10FA9000E96C3A2D1576DB5C103D9EA4FD7A57B4D7
+:10FAA000139AAC77C62B6568B731F09956DA5F06C2
+:10FAB00081473FEF6DDFEE5FD1BE53969DB7FA2BC6
+:10FAC00069938FDAFDEEC0B2CCBAA72AB3AE325B2F
+:10FAD000BDCCC6B738C23CFB7E5552F011F866B6B5
+:10FAE000FD0765347F29C6D1E6EB26EDAF7CE873D0
+:10FAF000E8AEB289F91C1972DC3ED162CD9D18B70F
+:10FB00003B4EF4D3CBCF19C7EEEA18BDC76E67647E
+:10FB1000D960B8CF2A0BBACBEDC7EE41F93F04FD4F
+:10FB20001CA175E1262BDE26F6CD9319F877B6CF0A
+:10FB3000CE88577844FC85B136DAB7E9F398AFA19F
+:10FB4000E9CE0FCCDC74153CEF13FBA2AC82C7519D
+:10FB5000B03BA48F7FEA75DFDD2CE59A6F178D77B8
+:10FB6000416A9781F1186F155800C0935AC7D8247D
+:10FB7000C0931B703942F1BA841BE53150C7E36E64
+:10FB8000AB645DD02146F1676BFFADBFEE430DDB8B
+:10FB90009D021B3AE24B7FC7D049CC68E7600180E9
+:10FBA0002B38574EE2962CC3603AEE83C96DE17351
+:10FBB000ED47C9BA6AD27E92DE37C24B1E3756581D
+:10FBC0009C61A879BD1A6F9711AE84947BDF4B8C32
+:10FBD0003331FDF938777524B7BDC3998BFCF40D2B
+:10FBE000E0A723FE863AF652FE49116B93D04F945C
+:10FBF0001BA329E4B5B7A4782FCAC324357AA4ABD4
+:10FC000016F72F5D14C793AE6E9F817E49C1647D48
+:10FC10008E04747A4961A918E0B6204FDF8F2BB9A2
+:10FC20009F74BFBBC007742AC045410963DBBA3E5D
+:10FC3000DA84FBF305D3F4390E5AE98D2D78250CBF
+:10FC4000F529FA49FCBEC7FDC182466C3F43DF8FF0
+:10FC5000EF2377BE4D75CBDFE801FE7B87FCE5E344
+:10FC600054DE27F3FD889D32976B55167173E04380
+:10FC70008C67E6C9C354CF6B3F4175166629C49B98
+:10FC800015A70816C677213ED7C446697FC8E9B3D1
+:10FC9000F68392DB715FD4F4F37DD12BE005C95775
+:10FCA00097BEDB2E5F3F95A50C7EEE023381EBFF06
+:10FCB0007EDC178272A023CC32E4C57DF58E77807E
+:10FCC000DF1557ACED00AE377A79FFBD1DD1FB7063
+:10FCD0003E80339EDF23E4FB69D921F279E24F2392
+:10FCE000FEE548DC401FE6D49B5F263EFD70F456DF
+:10FCF000EED388BC94B3E8DD5577DFB87C97535ECC
+:10FD00004513D2E52DB9794108F8A40BFDE1CFE008
+:10FD1000DB750B303ED3E5E7741AED5AB609F306EE
+:10FD2000144D4E29C87FB56FDC80FBE15B44FCCDF0
+:10FD30000CC922CE2CFF19F7E5BB31CF0590EABAEA
+:10FD4000F89B6EDC9AF038DAFEFBDB38BF7FE3F914
+:10FD50003EBD206AED3513F3A51289EDB0FBBF79E6
+:10FD6000619815CC4F9785FD3D7E2BB3EF4B9F11CE
+:10FD700074EFEA384C7C3CDE4F88E7B728F157B681
+:10FD8000219ECBA5F871C41B2E8B984D9F5A71F6FE
+:10FD9000976561EF599B9BEB27AE77C7F77717B94C
+:10FDA0004D67A6FCBD4CF2B78FD3295BFE7EC72200
+:10FDB0000E03402B7BE3CAC388AF9E8EB17B48CE37
+:10FDC000128BC87F2813F9404CEC5BEA621C3DC2E1
+:10FDD000529ED9F8CF01DA4FD6BBE48FEDF6353B12
+:10FDE0005FE094EC0F91FDC9CACFF1B44FDB618F96
+:10FDF000E33B2A120CE5D3CA1390143D835F3DED1B
+:10FE0000D3A97D7F87BEE39D4A1BBC62BD54664D6E
+:10FE10002FF105D26F5EE14759F33BF8E6BDE600EE
+:10FE2000D07907B839681F775439484ECA36826688
+:10FE30002E4BCBAD9E80F905D2E366CFAF40E17C7F
+:10FE40000EEBFB7B118E490803D5C3F7223C6540BE
+:10FE500090FF037E09DBBE88E018C7A373A011E3FF
+:10FE600048BFABE232EDAAE4F162BD5AE0336B1C4D
+:10FE7000B6F33C74A8E2707E523A5429B9E9C0DA6C
+:10FE8000E107705658F8FB23BCCDB13F69D1C5AA34
+:10FE9000C3BA2F685FF79D6D7FF57B51AFECE9A882
+:10FEA000BA17F54A17ACC3F97E114BBAC85E70FE9B
+:10FEB0009713318A63433D2A13BFF3F70ABEC73253
+:10FEC00011FBFC8521AA475175560EF1F795E2FB0F
+:10FED000BEED774965F07CFA76F13C616818CFAEEB
+:10FEE0005CCDA8BFE9A25D7195E1C671D8ED3C6E0D
+:10FEF000C270CBAF48E48BC06FAA262F401E9A5227
+:10FF0000157778B0DD766654EAE9760F08BC7B4257
+:10FF10004FCEC7767A552C86E3B06599FDDD6FB577
+:10FF2000ABE270B33E1E17B2DEEF10E34D1B0ACDFD
+:10FF3000BF109E9757C5165F85EDEA79BBAE8E2838
+:10FF4000F1B7D5FE4ED1DFB4AAF8E60B71BC6A3E1C
+:10FF50009EE2FE02C983D56E50B4ABD8FEAA89FDDD
+:10FF6000E655F1B8A4F57E8B18B7A22A7E178D2727
+:10FF7000FAD9DD5147E37DB7C3A0D2922FEBBB3B4B
+:10FF8000C477DD221F544EF07ED53E467AF81F8599
+:10FF90003C6497280761F4E3B12F186F9AC9E50C08
+:10FFA0007187F13D7D6002BE675007BE2D851FF74A
+:10FFB000FB12B41F6FF19B156F3874E4E20CFE6303
+:10FFC000B703BFD9F3BAFEA12AB3BE3A9A595F5616
+:10FFD00097596F30EE1DF737B15EDF98F9BE369650
+:10FFE000F9BEBA29E3BD05C7F60E4671BF1D1DFA5D
+:10FFF0005003E9A9518A07EE28D44B701DB1BB907C
+:020000022000DC
+:10000000E3F10E8C3B93FD0D53FBAD1837ACC47C74
+:100010000D1E674C88F821C6E71BC83EF338A4B70D
+:10002000FD53430D40F787059E816F32F43BE8FD99
+:100030008715F42F96C54CCA0513FA7E8787DD8095
+:10004000EB36777898396C787B46E179235E6BFDE7
+:10005000086EA0DD7E3D23C6B1F4238B003561BC64
+:100060006EC16F689F70FDF2B422F23F74F05C8A3B
+:10007000CEB65FE592F10CC2B5A310E0C03859745A
+:10008000C4C07DB6296D3AAD07BDE05FE3BC027523
+:1000900063297CAE35F0E791D59971CD1DF9A6A401
+:1000A000C2FB6425A37DAC7C43CB78EF11EBF699C2
+:1000B000CEC52FE27879222ED0E95F511CAF4EE3F6
+:1000C000638114FF10DFCB6FB8783E94C6F3392EEE
+:1000D00096632F2930DF4957F7D17EF64B42BF9701
+:1000E000A1F7827E26D3361F828A2EEC2DBBF12CFF
+:1000F000FCFF277EAF9BDC3F2FEBE2F37F49B1D6BD
+:10010000EBF162B4DFD749F137707C561576DBF737
+:10011000A342B136312E6F6FC15DA91A0497054F06
+:1001200058358EF0BAE51740BF7ECC9F889BB84506
+:100130005A8AF0813E3C29EC68369C4ABB41FE5805
+:10014000C1176E7463FF96FFC09A72E7414DB4DF2A
+:10015000BF1EE182FE4F88F54EC1A444788E2DFE6D
+:1001600057A872FFA75F49E761D1BAD0C92CBBC6B7
+:10017000F38FB10E721454F9FE6EB19B997941F46C
+:10018000D76121807AAF53A5F5FFE4654040A0FF19
+:10019000FD1BD5DD68C795D545B4AE04D94C519E3D
+:1001A000A3D9B31EEDBD153F76635C631ACE679885
+:1001B0004A1FC687A7619C788C4A8D69B47EF84D2A
+:1001C000F3E86D48849DAE784805BCAE76C72F40F5
+:1001D000FFF0B6CF8FBC85FBEE211426806B8E6CB2
+:1001E00068EADC73B65F82CF7DCC28C476939951E0
+:1001F000A4127D32F34CADFD7BF8BDE2B7D19F7DFB
+:10020000D791CD4F3AF68F7E1D361ACFFFF07DB2D3
+:10021000F513FCDEF1CD3B57FFBAC81F8865F47FAC
+:10022000675E40457FECDEBCC08B88FFA31B5D147E
+:100230005778CBC1F348AC710E6C7495A21E1EEDBD
+:100240009F41790D07FB5D01FCAEA77D5AC01E07DB
+:100250001EED9B16CC95F730FE1EFD05D06F86E097
+:10026000972B055CCDB2A6E2BABDD92CBBD7EE77F1
+:10027000379B3C7ED42CF37CCDE6F62F7FD72CB376
+:10028000CF9FAFA7B3BF4BC7B946A7A2BC649F7FA0
+:1002900038DFB989538E64A3342D8D37AF1237718F
+:1002A000DDAC30C320ACFFE5FDF5FD0FF77718F9A5
+:1002B00075A2FECEF7FD44E74136572463A4FF64E0
+:1002C000E88FE456E80191EF63E511B9848DEC8C79
+:1002D0002C0EA27FCBAAA224BF2E688B7997CE8446
+:1002E00024CE6B88BC9F2A47467E4F76BE0F6B326A
+:1002F000257BFEB395FF4301151B5F63FF388E130B
+:10030000FC4B8A638873061483A4BCF96F659C97C1
+:10031000C07C2BF49F3757D564E41FCB8CE78BE36D
+:100320001A8AC7B932BF9B58DEB2C6BB3613EE4F2E
+:10033000FC9D4FD68FD9FC8C89BF93D9315B3C6C27
+:1003400037EA278A239FA1FC732236CD3B3505E986
+:1003500077B083E755FF4E4E7D05F5E7EFC654862F
+:10036000097ECFE5B34398FA6C4A928EEB5F43BBAC
+:100370002688FBDBC6ABCE90C35A5441FDB9938DA2
+:10038000DF45FA3DAC2AC28E8D38B15FE323ADC1A3
+:1003900000FCD5FF23F48B7AFA4355C27CF9F91F90
+:1003A000A59662FDD2B12605F5C64BFB0ED2B83735
+:1003B0008F2D94B1BE5FF4F3EB47F7CF63D0CF73CB
+:1003C0008FFB598AE25B4915F9E6E6279D942FB821
+:1003D000EA7B7E92EF9B9F58F3D022E8577AC64F74
+:1003E000F0D43FB1F26117C1D749F3BEF9E92F0547
+:1003F0000711CEFF703237F0E7731BB9BD59037395
+:1004000076C3F76327D587ECFB63163EAC7A833659
+:10041000E710A662DFBCB76C8ED346AF9B65F6359E
+:10042000F4570C2817E758EFFC5CE5FED107277955
+:10043000DEA1B4F7C0129AE7F09769DE1293E47771
+:10044000013FAF88F9423B9A8FF98894AC84F71F3B
+:100450003C22F1F90DCFDAE529C3F177A92D18DB9C
+:1004600010FB3200FFD7D06F6BD83BA7ABA416F7B9
+:10047000ABCBCA3015E2F2EF3D4EFA15CFF748404C
+:10048000EFB5F84F78BE6EAF3385EB9DB54FAEA19B
+:10049000BC45A8D3FA67D5F77EF0B4E9C7EF9D193C
+:1004A000F9FF6B87EFA0F5E3AA7F714553D0FF7B7F
+:1004B000AF3AA31EECE759E5A8DD2F7F6F644F002C
+:1004C000E972D96939E3398E7BBA80C66956836788
+:1004D0007F0798A77CF575C3FD34CEBA27FFEE974A
+:1004E0009847B92E2B9EFC1EFEA3F8EC75EB193530
+:1004F00073DDBADA29CE1BEC9D94D3FE8D9F3310A9
+:10050000F66FD5E3BF7BD084F13F78E2FD0771FE43
+:10051000ABFFFCDB07BF85EB9FE73D1AC6E1D73D8C
+:10052000FAEE83DF8479FFFA599703F9E6E6477F0D
+:10053000F5D6B7A0FEF1F76714A0FF59ECE2FEF183
+:1005400089FDBF2FC27303FFF0832B26231EFEE11C
+:10055000A9CB279FCB9E9D00FE4ABAECF29A247A43
+:10056000EACFA21303D5E7449945BF834F1E2C451C
+:10057000F87EFD1ACFAF5807CF301EB576780DE55F
+:10058000E962FD76C0F7DA7DBD749EE36C7C9B5317
+:100590001C612EF79892BCF6C92F7DF1D25A2C150A
+:1005A000CA675DC7C67A30CE98FDDD381D5F053A53
+:1005B0005E74F6FB75E29CC7BA7DFD7CDC61A063CE
+:1005C000E06C3AFE1AFF71C9D974AC7365D2F1E3DD
+:1005D00047AE0FA6F0E5939372E6C35A745CF3D46A
+:1005E000DF9FF37CCA892C399E08CFAD12874B71EF
+:1005F000198D2E94D727F2CC30E0E5C4EBAEE4227F
+:100600007877A2FBB7A50CF8E3B832B604E571EC35
+:10061000072E0DF7E79B7FF07315F5DB89A77EAA00
+:10062000EA3CEEE69340AF9F60E3BF11D4F374FE63
+:1006300000F1F45D7F0AE3106B6F6F257AAD4D5EBC
+:10064000D3A807E839C533D626B91CAC4D1EB85619
+:10065000CA413FD355C0F56BB250F887697A4A75E5
+:1006600048C7230B91EF26A2A3356F0DE77DB18D0F
+:10067000AEA6724EF93CB1CB25E3F9D975E29CD018
+:10068000BADB1B89BE965FBF2E29FD3C17BDC7F79D
+:100690004DFEC27344DF744D108F12F33E9F5C9F7A
+:1006A0007F5E7F19DE6EC243A673CFC6DFC66E17AC
+:1006B000E9E7B7E6B8287FEA88A2DFBB01E473EC7C
+:1006C0006585E1FA7349CD2F153DC7B982FF06BE96
+:1006D000D46D7C196F3FD93D19BE8BDFCEED4BF643
+:1006E000FE52FC7627C6F4C6E1F9CD549828B45FD3
+:1006F000F7A087F2999DCFBFBE04F5C2BAE7FDA46B
+:1007000017D6BAC61EA67DD1EFB8D81ECE7BE46F31
+:10071000ACD4781F079FDA40ED4FC07B6CFF9BEF96
+:10072000771CFB06CCE3A6EDBCF16F9E08CE6620DD
+:10073000E7AB5036018F2B7FF8ADAB915FB18EFBED
+:10074000AAC70ADB9EE679CE53E7E0F8079F3A4551
+:10075000E39DF85E1E43BB7BE287BFFC1CE2F3FD1A
+:10076000A79F998DFA70E57645B7EF17DE643F0FC6
+:100770006DB3BBAB86B7D07ED12A7CCFDB4B678411
+:10078000ECA09F85E3A3DFB2EAD9A0E1999DD18EC9
+:10079000FA59E71ABB2D4A76CF2C71D4117D4B90B4
+:1007A000CEABF6668EFF4317B7CBEBD4B115BC7D4D
+:1007B000A284F3C3087DF78A8BC72BACF7D9DF5B24
+:1007C000EDFFCD559ED50FFF7EAD8BB5E5CA47FB3E
+:1007D000B9E877D5DE3FCDC8EC8FF3EDD9E3F0E78C
+:1007E00027BC7C9DBBE6693FD17BCD0FC1EF998DC6
+:1007F000F597289F7CCD0F37107DD6B8524BD03F50
+:100800001BDBEF62E8CF7CB0FF657AFF81922A2D77
+:10081000C076CF798EA0FC66C3B566D8250E8D66EE
+:100820008EDB29F6A9BAC43E9553ECB3E14960F4D6
+:10083000E3687F01EB6F4CA5F5F744EB8780BB8C39
+:10084000E66DAD23AC754337EE7B600CD06D32CDD9
+:100850007E1E8DF1BCCF3F64F187AAC4355CEFA941
+:10086000128B217E15394E79CB4A38340720663DEC
+:10087000E1C594DF3A50AD911CF9DC7CBDE882FE05
+:10088000C9DF3D3444FB4BEE88FCA15DBE3DCB820D
+:1008900064375985ED7939CFF7C378A4AF1A9EDB59
+:1008A000F7BB438733CF4967EDA3FFEBF8B91FD3FD
+:1008B000897277BD75B01651087CFCBA755E53EE2F
+:1008C000E2EFF3ADD75DFCBD90D3752D5C0E0F3616
+:1008D00007098F161EAE7FAE7704E318D73F57BCCB
+:1008E00014E97EBD6FC6BB88D77F451D88FB5AF9CA
+:1008F0002E3A977AD173B12FFD1DD4BFDA5A49E74A
+:10090000B2AA87635F9805F51B5BA751FC6CB69B89
+:10091000F3E35776394C05FA3F24F2ECCC6F4844A8
+:10092000CFAFE102043E6C66BACA1753496ABF945E
+:100930000DFB797DB810CFD7D9BE77FAF0FBF51251
+:10094000ED97DDF01FAF5E8138FCC5AB47BBB1FC56
+:10095000DA2B4CCD83719B9FD47B78B843F4F71C82
+:10096000F4E748F7378E3FD94DF848E3C74DF8B262
+:10097000F0032339E87D1ABFB4CEB4F0DBE901FE01
+:1009800003FC5D1F6CFA3CCBC1F7E3F8F44D7F9795
+:10099000CD4EC3938DDFD799F98351D243037C3C6D
+:1009A000B1EF62F5FF5B7C05FEC3EBD006F34C5E56
+:1009B0000F4C3F44DF29BE3EB4E337B06105F9EF89
+:1009C000463642E5123646659C692A962D7830797E
+:1009D0001A6E17C4A8DCE98A7FC54D71A3D17918B6
+:1009E000F7FAF5D4F8054588EF5772FB4369FFC65F
+:1009F00014711D51BADD941B609D4F69193DD98159
+:100A000070B50059D19E789865A77515E31D2D6FB7
+:100A1000FCEA4FF6F76CFC3D8FF78FF7E3E6E776DD
+:100A20006DED32F434B59372F503F58CBC8DEC3A70
+:100A30008723FB798B9B9F53CE0117E6B6033F5A62
+:100A40003FFEFD3BD2F04C3C77BFD97D79431FE898
+:100A5000E3C70A464ADC501F705FD9D555CFD8E3AB
+:100A6000B07CC2FD61A8379811AC1B4B701DB75408
+:100A70000616B6E50D6D13F2B1CDCDE3A8F0DEC4D8
+:100A8000F783582FA4BC2EBA1A64299640F7B7F7FB
+:100A900095FF64A63E317D5A06CEB8F41CFA1D2F90
+:100AA000B608CDE3EB7C8A9FBC18355D4ED483FC41
+:100AB000DCD95F1AAF2C60512A432C46A59507114B
+:100AC00066092A4BD8309511364265291BA3526717
+:100AD0009A83C705B81C94B328D52B9941E5E365E3
+:100AE000A0FF439837E88DA27D395FBCE8476E6E62
+:100AF0001F277F5526BDF411D8093AE726F47F3623
+:100B00007E9CEE877674D9CF873DE2A675F3E31B12
+:100B100075A28FF5FC47822E3F12FAFDF18D51CA66
+:100B20003B3FFA883B8AE751DEF633351FE0787B9E
+:100B3000CBCFCB9B7DE9768F15F0F8E4E923CFCCC2
+:100B4000C43CD97BDCC68B6E929714F1ADC5474B84
+:100B5000DD3E1EEF1E503EB0DB836677EC276EE86D
+:100B6000E7F03F7BC9EFBBE54E89FC3EA64B24670F
+:100B7000CB04FD1E2B187E0FCFE19B5B5D3AEAD1C3
+:100B80006503AE23A80758E20AC3DEDF5B621E2CB2
+:100B9000712FEDE72E3B4F3C6819A011F92FBB1FB9
+:100BA000C6A6E663FC986213B6F66EE02F2B5F1CB8
+:100BB000D7B301B1CE69DDFDFB30EECB9C74733F42
+:100BC000A8F52D9E3F7F5CC46F07C57EDE076E1EB5
+:100BD0006FB7DA9D744B16BF66DF577012F1A2260D
+:100BE000AFA738BDB58F725C4D34219E06AFE7F7D5
+:100BF00011CCAABF6E15F2C5DD52ECA444710E8E65
+:100C00009F594DB791FF327FE6DE303E0FEE7351B4
+:100C1000BEFDACBD2E03F116F470FF61FAA2363CA6
+:100C200069C6DEBF345982EB81D6F1BCA76440DCD3
+:100C30006B42FA7F95C0CD7BFB2E3F675C19CD855B
+:100C4000698B93E18CCC0C7D5490552FC96A5F9EC3
+:100C5000F17E0AF07831E881293E96F243F9F826D0
+:100C6000733EF2FD2028785C2F4E458305F49B02ED
+:100C70007A04EFD5C0B09C17CA08D4DD05F49E39BC
+:100C8000C5FB20940F39861B91A8D370FE80774D49
+:100C90001EBBAABB0CE5B84F6ACB98FF98DB3EFFA2
+:100CA000220113F4C3B0DFC1A61ACAF74AAAEC1690
+:100CB00084E79E4B393DAA9B3E5E82F4A8AE624912
+:100CC00085CA5439E2DB2BF68F77A9DA0DD8FEBD41
+:100CD000C75D827E0B6FC2F6557B7B6358CEDA37D9
+:100CE0006339D26DB35F6B21BF03FA457A96E1A2F7
+:100CF00002E878CF23AEE426A46F3DDF87013A9562
+:100D0000E2FEE1FB4F01E2C06EBEFFC8A926DC2770
+:100D1000AE6ABA6731B7BF3ED213EE90BE1BE3890D
+:100D20008687CBC77BD81EE4D9BD97EFC701BF1913
+:100D30001EE4C3BD52C67E85AA1BC47F978FAE7FBB
+:100D4000692A8CFFBECE683DE462C381529483BDA4
+:100D50004E8672F0F8540EDFFB493549F382AAA79C
+:100D6000804AD38F652446FE42B1CCEB804703E531
+:100D70006ED61B37FD1AE7B144D0E331666AA81777
+:100D8000DFDB772BE5096DAD673528FFA7147E4FB4
+:100D9000C9AA7D5E9A7F513DA3F39DF3F749A9CB84
+:100DA000309E37A0D2F9D09B9BDA2EC076AE7D92D2
+:100DB0004ECAFF8FB7A64AA0BEFB069E3BD5D09475
+:100DC0002CC538DE7B73C6C278EEF9C7187C037C6D
+:100DD0000CFEA92D8CFAB022A2A6F07CF247A373D8
+:100DE0006E7881E1BCCC528C570DF6837ED6391FCC
+:100DF000B96B88BF58A006F793EBEEEBA2FDFB049E
+:100E0000DD5762C941BF92A07CAA9BFB530D21F024
+:100E10002FFA3DC4EA6C6FFFD12ECC9F1A7C0AE6F4
+:100E200003F41AB4F6E9AAC6DCF67DE05B059DACD6
+:100E3000FAA0B8AF86558CB9B93D1F73E339CA53D0
+:100E4000CAB08AF1CAF9FB4E1E9E467870D3FD4D9A
+:100E5000A7DEDC7001977B4947FB60E10BF0432C78
+:100E6000E1DAD72CE13A661C1F5B4ED379550B0FA4
+:100E700087045E66815A5A5093C6CBDDEA8803F533
+:100E80009FF934A3F5CAACEBFED084F477B57FEAC2
+:100E90003EE4EFFB3DF95C9FC963745FC8DD780EEB
+:100EA000DA9786DFA5F17DED1D1E1E9F1DF2703BBA
+:100EB0007297982FC094AD07EF42BE54DD31A31B4B
+:100EC0009A6CCABB9AF6CBEEF7887D58F718DD33DB
+:100ED00090E3BB1D1ED49FD7DE6074EBE9EF006F7B
+:100EE000197996A794B1D796C27C5601DE36E98867
+:100EF000C7F5C47737D733C2A30D6F197C3511FE00
+:100F00000E4DC04F161E66C92C85F704315FB4FC28
+:100F10001A80FB590FD7FFD67BC6A2E57F6F83EF00
+:100F20005981A7BBBDE27D15FF2EFD5E7C1F10E73A
+:100F3000CD2BB2DF733B03FCF03594CF22E40709DD
+:100F4000E763C9CF3537EDC1FDA22739DFB8F6EE2B
+:100F500057298F353FA922FCABF6AE277E6988C49E
+:100F60008B71DFF19E2D7B69FDFB5ED6FCD0FEA36D
+:100F7000FDF895B0730C93D2C12E46DCACCB9D230B
+:100F8000BF6FFCDC455D88FC6F4B5F4FE87F87C11E
+:100F900081B2DDA7A48AFDDC6061FC3F91CEAEA6E4
+:100FA0001115C3777AC5E8422CAF702EA27C159735
+:100FB000C83FCEEEF77807AC0C416EEFEE70E3DD84
+:100FC0004A20C71AD5B77584A94C76E8F4FC84C0CA
+:100FD000AFD7C1EDF9E6AC7BDADE15FC6BB553702B
+:100FE0002708F7EDAA783E805CD5C3F3752BF8FD92
+:100FF0003BD6394AE0CF1308372C5872E60BC20BA8
+:10100000C9CA9BC07645D7F27C81A2269E37B155CE
+:10101000F0CB89ACFBA0FE20E0F883A0FB2806D92A
+:10102000097F7CFFDA1531B91C84ADBC637E7EE597
+:101030001C781F9572E35DF1C2FB3589230B8B6130
+:10104000084F05CF8FB5F2613FAAE7F7A94DE42716
+:101050005878B7E8D0DF11A7FAB68E562A83D77230
+:10106000FC253BDAA8BE408A15E078C1FA73CF7F31
+:10107000B297CF3FE215FAE413CEF31E8FE05BFC8C
+:1010800085705F94DF5B73CFF5D78597C2F3195EE8
+:1010900071EF4E5BA67DB4FA017ACEF0CE4DE76DCE
+:1010A0005879B7A3EED8850837AC339E582EA5E102
+:1010B00039DF7AF328E66157A6D703EF60FEB572F1
+:1010C000AE7D64A3E665BE8F4CE714DE92E297E046
+:1010D000B8A7EEBA5945FBED1C986F62380EFCF3C9
+:1010E000CF209C2D41FD633A516B5E7D05E659B7DB
+:1010F000B8F4A7B17EB2BEEC0ABC57AD65B27E1B98
+:10110000AEF7B66DAEBC02ED57CB058CF281FF6930
+:10111000F357BBD17E9DF118977B695F5FC9C7FD0F
+:10112000D36C3FF9EC7965EE9FBE8008E4FC652244
+:101130003E2DFE02BE8AFD6D7C65F1935BC8B34611
+:10114000FC63BD0779BA91F848F0D7F9F8A959F0CE
+:10115000D1CD82AF2C3EFA5BE7ED71E43E5F7B8B35
+:1011600018A75FE819D08B7D76FD69E9D322276B3C
+:1011700043BD76E086476F40FFC7B5777A39E225F1
+:10118000E44CFE02ED147B4CADD963E3CF477FFF07
+:1011900050C9621FEAB164C91E7CFF28BCD7319FC9
+:1011A000BD2D8CFBACD5918F97E07D5BD5152C596F
+:1011B0004965AABC0CF01312700E8976B322454B18
+:1011C000717FA545E0C53B9E17D9467678B35FC8C9
+:1011D00091DC16463BD42FFCCCFEA91F3789FB00BF
+:1011E000580AF34B35EE8FE27BFDA2747FA02745B2
+:1011F0007ED8B89E6CF1E6F04B2D3D39E289DD4D8D
+:10120000EF85BEFC5BE902FD7DC7CBE92CF1BCEFAD
+:10121000BFAD3FA017D9355C37A8C26FC42BB858F3
+:10122000343AF37F02DEFFADEF832C6E868164419A
+:10123000CCE7037E700D6C6428AF205F87512F7858
+:101240008676996887D7D50F53DE9B2557EA059C8C
+:101250006FAD7E47BDDC7E8E5AFA1A7E3AD0793A5F
+:10126000FD83D707A03E03FF017A6C8638D754C5AB
+:1012700012143F99C986A9AC662354CE66635446BE
+:1012800099E6C4B286459D22DF6C1E96ABDDF1EF78
+:10129000A069DCE98ABF8974FEF5D4F83F61FECE0F
+:1012A000A6BCB59FA1F39B5E4DE0259511BF606282
+:1012B000BFE77CF18CC9CC38C6F56266FE19FE2604
+:1012C0003AB765E438B7F5579CC3398DE34E780ECD
+:1012D000E722FD243F573348FADE3A47B3A5B0E38F
+:1012E0000A3A577331A3F549C91D433F42FD2E2FDA
+:1012F0008A9904D3AB2CA7BDB34A6532CF67ECCA39
+:10130000BF4EA3BC4637DFCF94457C71DC2E639083
+:101310007AEED9798DFFD3E364F7BF5E8D15E711BF
+:101320009EC7FDAA625E8EE7A5D6E415A6F331AD91
+:10133000BCD489E0DA94B7A4CE7E0ECE993FAFF14B
+:10134000004CCD917763D4BE1F6BCD77BC9D8FC30E
+:10135000F597E67F82FE2B41F8B3F340B3ED945549
+:10136000D6E771793AEE352EC679D9F2263F9B57EA
+:1013700098336FB21EFB07BEBD34AFF06CBE3DAEFE
+:101380008E5CBF12F4F5BBF95E8A031E78E567C573
+:10139000B8AE54F3BD0ECA07127136EBFC475709BD
+:1013A0008F4BDE917452FEF91D230BF48D50DF1329
+:1013B0005689FBF6542DC89B857E4A9F93F2E1F334
+:1013C00044FC4C2D3E44F37BD5EF24F9BBE374E79A
+:1013D0003CFCCEAC836FA0C9823A43DF88EBF00BB4
+:1013E000F9BAAC75D2E9ED7950BFFFF59514E43543
+:1013F000FD3CAE76FF2E711F19FE703F756E6CCFEF
+:10140000E6B2747D6568F11E94A3DBFC328DF3F5C2
+:10141000FE695B7109E2AAC2002FFE4C27DFB7B458
+:10142000CA9493EF7BF27A36BE8362DF2CFBF965B8
+:1014300001AECF82975E7B18EF135ADE4A77B1A0D8
+:10144000DC1F28867AA21E6C25D4837D3CEF2A21DE
+:101450008F99B8644AD41B21135A0523A378E70255
+:10146000FB769E427006FA1E92701DE66DE5E7015E
+:10147000B2C7FB761EC75B421E359DD40F8B9AD038
+:101480007F00FAC1F5DAF9BEFF7A1EF76F13E2BCEE
+:10149000EDCAA166CAAB5AB97DB284F8B5DA6DC996
+:1014A000E3F3DA633832EE6D393A5E6FA3F5A33FAA
+:1014B000147F10EFB3F58755E20BDF4EC9F319A87F
+:1014C000FB925C1906EBE314C7EC86F7B81E5DC906
+:1014D000E2A5A8CF86E5E1D75720BE007EDC520802
+:1014E0000E49841FB9A0F5C16F201F5E92B804F1A8
+:1014F000F8F55D7F6217C238013F3F3F1CD44ED3E1
+:101500007D56C1DA313AD717A8CF3DCF0FFDC28F34
+:10151000137C1B107AD73FB49BF05352C7EFCDBB5F
+:101520005F192E2EB27D7F89E04B8BBFB2FBFD6A27
+:101530001E5FA7F7143F4C7CEC95E3748FF5CA88C7
+:10154000CAF05E18C7CE9F52FE7DB0D611BD126D97
+:1015500041B48DEE951DA813DB806CB409DFF7DE76
+:10156000A4D21DDEC705BF9AF53C0F3B7B3C8F5FC5
+:10157000C4F16A1D8D08CFE04D2F1623BFECF48F08
+:101580008543D5F89EF3CDA0DF47F03A2F7BF86A6C
+:101590008C0F391F5B5A24E9F67EF8BC2AC02FC491
+:1015A0007396FF9E37DA8DF74254602015FCFD33A9
+:1015B0005B7ED98DE7321FD8E514F4D5292FED8550
+:1015C000E4B42998127D6CB54A79CAC7E356DC3475
+:1015D000E5C1F7F7CF8F935C99373928EFEBBEDA87
+:1015E0009FB96740FDBE0A07E17B57B23380FCB06C
+:1015F000CB08517CAF35B8F8DF51FFDCD7BAE0AE8D
+:10160000E9C8BF890A89E405FE2DCFA35367F4DD3D
+:10161000560FC78BB690D18589F9F5FC5C6C7E942A
+:101620009F3BBAE3B493EFB7D6F17B84B5C46BDFCD
+:1016300042226BF57CFDAD45EEB995139DDBE3A031
+:10164000500D9AD8C7D31AD48CBC1078EF6BA5FB79
+:101650009CF97D93161CC111476A05B60F7B8F2C30
+:101660000DF076453544DFD43C789E1FBEAE94F233
+:10167000EBAB1D4796CE4EEF033C20F1FC69F31215
+:101680007537C207CF29BFDEFC0CAFC3FBA627907E
+:101690008F0F8FC5787C37568A71BE60DDB11B1104
+:1016A000BEE0D0CF693E41DC57C4D2C884B72960C0
+:1016B0007C9C67F32B2CFE0ED4F2FB3E699F0EC67A
+:1016C0007FB799DFE712C0F39705342EE7B7E52C13
+:1016D00029F25B6A513EFCE27BFCE13D92E8F3A11A
+:1016E0003F37F814DB8793F68B7DCB0F869DF4FD97
+:1016F000F6263D89F27C5CE5FDBD7B151FC75FDFEB
+:10170000B31EDBF9EB6CFB90F0DF241FE7E307A4CB
+:10171000F4FA9BEE2BC571CAD3F5ED8C8FBBFF504D
+:10172000C117AA719C6505B4DFDE25F04A3FA00F02
+:101730005D82007A245FF31A17C2E44645FFFB4539
+:10174000BBAD87B51730EF6AFE8FDF70A35FF44B38
+:101750005F98DE6FA9FBD08D7C3BA871B84BDA385F
+:101760007F9584C7DC18EF5CDE2769BBC57EAC695A
+:101770009D0BC4FD75715F4EA44F4BA2DCEA7D92B8
+:101780008179CE98FBE198275282711FB0CD5C8F92
+:10179000C80ED47F2811FEC2820EAD1C3F83FA28EA
+:1017A000DE6DC5EEEF93284FD8EAB7A40EFA05BE5A
+:1017B000B81FE040BBFBEE9083ED2E4BCF97FC5162
+:1017C000C053CB6A07F155A48EED92E0FDD23646A8
+:1017D000F93C7B22C32FE377C7EE76E9183747063B
+:1017E00046B84AC5774BEB002E6837688CF5A19F49
+:1017F000B967B583613E4C692B7FBE74E8990DB81B
+:101800007FB1C7CDE159D9CAF152BA9D3F5F29E6F0
+:10181000B1BC0EE681703570FA026ACD330E1C9FA2
+:10182000F3F7B19BD82EDC1750A7C647A6A37E6F4F
+:10183000631AC6D3CB0732F9D79A57E5387E39FCFD
+:1018400081FA221DF1708199C93F169E5B44FB4AC3
+:101850009C37E2BF9DB793F1867078DED2CAF15F04
+:1018600059C7CBA5623FDC81EF715F1DE783EFEBCA
+:101870009FA67220BC6C4422BBADEA989BDE3294DA
+:10188000352E1E419EC7F359108F7B5E06B2A11202
+:1018900018E2F4DF58E0E5FEC7A52AED67FA5A79A9
+:1018A000BFFB1DB1FBD08E999B5DB46F82690ABAF4
+:1018B0006DFD70F44F3C3F79CBA5EA5EC4174C40F8
+:1018C00022BE16E3EC77707C9B355CBFD55CCCF315
+:1018D0009BB746D5BD68A7F3EB0A16A8A80FEBB9CE
+:1018E0009ECB8F1EFB36570299FBFFBEC3FC5EDD0D
+:1018F000F0B24CFCC37C0C5CAF8EEB5183D138450D
+:10190000597902D82EBF06AFF12E5A807A75AEBD36
+:101910007F785FF00ABF9FC07738564EFAF7F0CE57
+:10192000C518272EC86A77D43F8DE4CF77B8CD414C
+:10193000ED30CB6376FA9E5D74C5590D9587B00482
+:10194000DB6EE6F1BA2915205E64D680FB82F36374
+:10195000744F8A65D706E6A873E2D5823E0554A681
+:10196000588EF872BA7DD18568B77D87E3E51AC1D4
+:10197000ADEBBCD4A8B4E0B1DA276A18E1EF1ABF26
+:1019800023E73DD05AC39F33F212DE0B98B7FD1800
+:10199000F1F93995FCD94E656C3BFA479D4FF9300A
+:1019A00012CE1ECD4F96E0FD51EF0BBB3E7ECF70A9
+:1019B000F5B5E41F638A15CE9789FBD267FAAB763B
+:1019C000A13CCC324CF293675544A44E524A3C3F62
+:1019D000B49B193AEA4933E2203EEB0DF7DC467F2F
+:1019E00057A34F2A40FDB0B5AEBC07F5DA701B73A4
+:1019F000A01E7DD5C7FDA2056DA3747FEE96030ED4
+:101A00003AB7BDE5FB86FE0BA87F0C30A03FB9A01E
+:101A10002ED146E7C12A7DF4FEFEEFC7676836BCCB
+:101A200060E63EF797992CFC6887C81B9472F9CF43
+:101A3000DEC2C52AFA6D170C359B18AFCF1FCA9F9F
+:101A40004FE7B41B40C5625E6818D00375AF38BF5E
+:101A5000AF1BF0FC623A8F4DEFF508AF7777A4F833
+:101A60007AB99AEF27CCDCF5A546BC4F73E6858E94
+:101A7000611CBD7BA46112FA1BC75A1DA4569E4C63
+:101A80003A33FC576B3DAEBC9AEC2F877673871CBC
+:101A90003A2AF93DDB2F9F847C3491FD98EABB9074
+:101AA000FB933AD74324A7CEB43DD9AA093D3E249F
+:101AB000EC496494EC496427D813A1C7D19E940BD8
+:101AC000F906FF6923B6AFDC9E4F7E60F94E89F4BC
+:101AD00078F910D7C72BC2A37DA497D00E48697B95
+:101AE00005F689F218F139D6A7EC949212E98FD84D
+:101AF000BF61FB96ED93497F2E0F1B93307F6D796D
+:101B0000934CFB9996BED585FE1CAC77107F05766D
+:101B10004ABBE8CC9CD0AF1788F7FA6A6E572EE81C
+:101B2000DB487A54DFC94BCA752C4ADBBB993E9D12
+:101B3000DFAFD2364C764217FAD5A20F93A3E7BC9B
+:101B40007FBF7BE7AEF9B48ED8794072407947E821
+:101B50001615CFD1AE16F261F9EF53C414223B8FA4
+:101B6000F075CE6AEEF71F2BEEB91AE7D1B36BA969
+:101B70008AEBD09228B743BEC88A87514FDE2AD657
+:101B80008B8CC5F87E6A5B2B9DE3F10BF803B56384
+:101B900006F6171C5AFCE50BC96F1F9E22E969382F
+:101BA0003FE50FF0F55DEDA841EFEBB86BB8A73E50
+:101BB000D687EBB8E52107E1D4D7D74970C0BA473B
+:101BC000936C71EB69FE3CBEAEABE3EBA02D437CA6
+:101BD0001DD4A3A418AE0B025107AD7F1C75F1ED07
+:101BE00078BFE672589FE2BAA1578ADD80EB47F0D2
+:101BF0001FB9FD08717D3038753AC553B7CE4DD247
+:101C0000BDDCFF9CC7E599D611E0C7FFCB1D5D0B7E
+:101C100031AE63CDD325E6E98F64CDB32E739E7BC1
+:101C2000F2C43CEB46F83C6BF93CA17DC63C8FCB43
+:101C3000295ABF1E8F326DA38EEB29781FC275E023
+:101C40001379D85FBA1FF36AA44310F08174080EA9
+:101C5000BD6062BBE5F01DF693CD0F86C0D31E8C30
+:101C600049149EED9F9F2FFFEDB10226EC25B7632F
+:101C700067D9418C1FA19ECFB24B8B0265E3F1392E
+:101C800033C30F1EFE3CF1D13E079DAF7B2FC0F743
+:101C90000DFC219EB706CFCDC9E8E74249F66F5843
+:101CA0003667D8E253BEDA4CBBB0D7C772AF47C570
+:101CB0003A94C92306F243EF25F179F6BF0B13F1ED
+:101CC000F3F57AC4CFE395BDD2A841FC33E1FA53D2
+:101CD00022BD100C399257C23F7B2FE578D93AD7F5
+:101CE00041E7F7FE19E355B8CF5EFC0EAD43075A46
+:101CF0005526F2CA28AEDF3AC94DED07E7F2F37E6A
+:101D0000C3A9DD14C7DA9CFC98F6CFCD3A7E9FC2FA
+:101D1000DE5D0FF79587F03E2563AED3066FA06AB0
+:101D200082B88358BF03A5256E27AC92DB0BAB9E10
+:101D3000FD9D0BE32EB6388FA269640FA3073E7A90
+:101D40000D7307BBB512CA57DE2DECF3F8FDED4954
+:101D50003F8FF3A5F8DFE7B0E26CCE377A4778FC27
+:101D60006FFCEF88ECF623FDEB33EF53B2E26F3DEF
+:101D70004A5B0CF1D433973416F3631CC787F10B1D
+:101D800096872A4EA95A3C77A36DFE2F89789352E5
+:101D9000AF125D07E764C6EFBEEFE7F7DD3DE3E7AF
+:101DA000F13B278BD1FDA9002FAD5B013E8A77B2B5
+:101DB0004552F679E5A711CE9E919618E25BF6C5DD
+:101DC000DCD57A9A3E9D823F0695B1B046F62E1E2E
+:101DD000737239A5F8D31DB523E41CF5289C5F0266
+:101DE000432E86E33AEAC47D01225EF1EE1A7E4F6D
+:101DF000F756713B93377C9D9BFE1E8232D684F151
+:101E0000734BEF64EB1BC40BF6DB9D74923DEA66EB
+:101E1000F104C505A017D45FC332BFB7A3A5568B85
+:101E2000DAF1B547C4315B105F3ECED7F6FBAA9F0F
+:101E300013719C87855E5046B8BC9124D9E3E9D5DF
+:101E4000FC5E137988AF7F55BC0FB73C8D4F1BBD2F
+:101E50004789DE8DB9E97D751ECF377972A43C8044
+:101E6000ED27F24F2D3F34DB8F4CFA74916F067ED5
+:101E7000634DDAAFB4EC61AF94FCC5E7508E1E51F0
+:101E800075D253723C8C7E9773BA8FF2961E9387ED
+:101E9000BD35E4CC9AFC3EB0149FAF9319B16F40AE
+:101EA0007BA5CF497565A7447E92C53736FECE9E89
+:101EB000EF7D14EFCDE2276BBEF759FAF6741933B4
+:101EC00026D9D6030DE3F10109FDA977E7F3BC2A72
+:101ED000ED7405B5CB11AF2943FF303B4E837F4FE7
+:101EE00008F5CAFF567CA6A7B848423CFC2FC46739
+:101EF00066060A793D577C8665C55DB2E335D971C2
+:101F00009789E23756BC057FF6B84D76FCA50813D5
+:101F10006DA761FCA6D383F7AF1F17713FDF806702
+:101F200021E6715BF92C4A8AFFFD1279B5F83B5224
+:101F3000428E2C3D6AE9D51C7A7465DE39F4E84A94
+:101F4000E4B3B9384F21372126A31D7D6CDF0B6E1A
+:101F5000CC335E2AF4E1B89D45FB6AB3A77EB4AFEB
+:101F6000B3CF6F5F130D8CE4A340CC237F8C970518
+:101F7000A332E9877CA6509990F9BDF2F98D997842
+:101F8000BAE8D96CBF63238F97BB8DD035C82F8D2E
+:101F90000E3A9F71F16B99ED1ACB7E14FA12D0A50F
+:101FA000E00A470D8FFF8BEF7CACF05AA45703BFBC
+:101FB0002FEDB3C733BF4BFBC3A2BDC6E1BAECF4F0
+:101FC00079DA8578FC3E1BFECBDDAEDCF0878DC276
+:101FD000BF0FA5E1BF329CD9AEA9F947855FCE05F9
+:101FE0007F841535D5A6E1FF4295EBDC70E91CFE38
+:101FF0002FD69DA75D456EF8BFD43801FC55EC2A5D
+:102000003CBFF4E5A6F3F42BE8FA95D673B7FB5A78
+:102010007BF638265F8F841C1EE46717F20FEA599F
+:10202000A650E91AE3FCA3680AE9356B1C2592491E
+:10203000A789F9C70C2DAEA5753AE59367F3C1A240
+:10204000390AF189ABD0C1FF0ED438FF08BA89FB39
+:10205000F6CECB17827FB2F96022FEC9863F9B2F56
+:10206000D2FC63165E174AC39FCD07E0C711FF2855
+:10207000918AE866FB7716FF8438DF9D972F04FF6F
+:1020800064F3410EFE217EC8863F9B3FFEBFF18573
+:10209000A6905E7131CE0F8AFED7F2452AF4251B39
+:1020A0005F64D33736FF0AA2FFD97C21E821F8E22A
+:1020B000BCF4167C914DDF4FCA1767D3DBE20B4EA1
+:1020C000770BFE6CFAC6377E5DE37972E3FCF0C9EC
+:1020D000E8AB037D7D9F5CDE991DDEF2B3E97C7E7B
+:1020E000FADE42F7E869167D754E5F4DE3F64289E8
+:1020F000F2B2D7A2AFF1C9E8DBEB06FD4FF1558E86
+:102100009F6C3A5D7B4D37D151CBA26FAF4FE055FD
+:10211000D0F77C74EB15F43D9F7EEEB5E89B057F10
+:1021200036DDC6DBE3DA2C948E0F67D32DBE51F17A
+:10213000D8E9DB1B696BFC2474EBFD84F2C88C4C82
+:10214000BA4E44BF56575B8AF2E126F3BF7FE58A59
+:102150006852B36D1DF1D520F72F9AD0F782B235B2
+:102160002FF739E316D12E89EDB0DF60661E935547
+:10217000AE14EDDE16FD5D10E4ED1FDF146B45FFC0
+:10218000E689037AF162DFD9F3B96BA375BE55977F
+:10219000ECE7086E0FF278D7D10E8D19B6F3ED8902
+:1021A000BEB28518B7291898D383E5D2BE49CCC8EA
+:1021B00081AFFCD3D3C82F4F8F97A4FEB42B34DA52
+:1021C000EFCE3F3D9DDE1FED7053FF383EAE93CF07
+:1021D000EE3F6F82FE8BCFD37F84AF0B18BF53D9F6
+:1021E000CA7F72069F7B0FD793DD1195F2D1AD7335
+:1021F00064D9F8047DC3CF79851A8C511BBDEF15C6
+:102200007851F0FC16FEFD92BD4EEE3F67B5EB74C3
+:102210005879F5F18CF319DF09F2B8803B298B3836
+:102220004B9CFE8E97F5FE6741BEBEEC94A2F47700
+:10223000B1CDA92AC969EFA599FB008F8A762F062F
+:10224000C7E3891467507C2FBE86F14EC5CA130BB5
+:10225000C91979629D0E213FB7707FBDB7927DD7B6
+:102260007111E50B52BE670FAC43E8DCAFE4B6D6A4
+:102270005B749EDB8A77F61E007F16E39B7E079DCC
+:10228000879922B3432E3CA7115653F8F706C7E3AC
+:102290005E4BB87CF6DCC94CFCFB483D786A18E321
+:1022A00016CD7C9FB6E74F1C8E9EE53A9DDB61867E
+:1022B000A1878AD2E726F1BB828B38FE905E0F841D
+:1022C000D539F6FBB4ADF1B2CFCB61DE4CC6BDBAA9
+:1022D00013E081B128FDBD30C5A76AF477BACF837A
+:1022E000B747835CAEBE13D409EFB31E52F97DF538
+:1022F0005354BADFC7A26379BF4C79731F316F148F
+:10230000E7D999DFE6A23BC4997103E2A5F3A8449B
+:10231000F1706B1E5D1DA994FD5EFDAE09F2AB7EF2
+:1023200056C0F9E6D1FCB62694E7C7A5F54DF6737D
+:10233000945FCCE77CF9594DC49D6A63E2FEE0AE40
+:102340009F5D8678D61C3AE2AF2FB9CC8DFB13BBCC
+:10235000C30E0DC1DA1D5EECBE99FC698746F78499
+:102360008637FD0CF37A4D688FF33AA4B5D0B9FCEB
+:10237000AE3EC7A7494C99B1684E517A7DBCBB812E
+:10238000C7FDCD2A96AC2CA3BFD3588279EBD3B529
+:1023900082F97C13ACCD4179ED03B0B687F787FAAB
+:1023A000D528E6E126341F9DE7F20D8C18183381FD
+:1023B00035A6A782E2CBDC2F5BE8F4792A60DCFF4C
+:1023C0000740829ADC008000000000001F8B08009C
+:1023D00000000000000BED7D7B7C54D5B5F03E671E
+:1023E000CEBC9249324926C9E44566028180012764
+:1023F00021A480580F214008412721405094411EBC
+:1024000006082460ABD8D2CB0001120C1A2420702D
+:10241000A14E12B0F8BCA1171129F60E0F2D5AEDDE
+:102420008D62B9689106F4DA88AF58ADD2FBB57AFF
+:10243000D75A7B9FE4CC9008DE7EDF3FDFEFA63FDC
+:102440007BD8EFBDD75EEFBDF69EB6D18AC7EC62F2
+:10245000EC784BC1AB4607635B559999DD8CC5742D
+:10246000CE2B65D18C65D821318A31E5FC940FD90A
+:1024700008C65A5B942983A05EF6D0418C41BB0309
+:102480002D89C93E1B63D1E3944B9D16467FDFC265
+:102490007FC7270E4E5902F59A5A4CCC0C695B7EC9
+:1024A0006879D36C578A3D87B10806F9D922DFCD08
+:1024B000BFC102C6B2F01FD0FFE98644A913EA29C2
+:1024C0004CD71EEAC5363309C765AACDF1C10D8CBC
+:1024D000A5D825F6AD0CF39155D90AE3FA2F489EFD
+:1024E000FD50BCCFE8377BA1FDB7F8770B63A6049E
+:1024F00089D6B3790DF3BC6F8475B8656F00CA1FB8
+:102500009458653BCEC7C6D476E8F7B6585E2FFC24
+:102510009BD95014E3D3F517FE552C278375237BE5
+:10252000D37546E817FA8BC8EE90EDF98CD90FD920
+:10253000732361FE76D575A413E6D9366A40AE0DD5
+:10254000D6F9661C4C3E81B197B714BC5305F92BE4
+:102550009FB179086EE7CD170D00F7284BE3E7F838
+:102560006D3B3E9BB986437A95C333281ECA5D896D
+:102570009E41309E313BC0101E11AB4C9EF7213D59
+:10258000E95F72923ABF639E8D6BEC9E4100E4E678
+:102590003516FA364A7C9E37FC4B69CCDDB6DE7ABE
+:1025A0005E3B5F77CFFA563DD85417DF9B4E8805C8
+:1025B000F8D968D79C6551BDF916012FADDFF0F150
+:1025C000B57296AF264F84F5B66E31D937031CC667
+:1025D000970D22BCD95F6FB2E3FADB1A666E9E8359
+:1025E000FBF9868170A26DCBE09445BAFE5AFBE9F7
+:1025F000BF46CCFB40B27FB7E4C1F94597BCE68447
+:10260000B4D5BF9B61DA6FE469A8C6C662B9A544B8
+:1026100005781D009C60298C5537BD31C50FFD1E06
+:1026200088F5DF2EDB197BA8E1AF0DA792219DE590
+:102630007F4782F4DFE259B06834A4DDBCFEFBF1D1
+:1026400005F5547F384F7F186F2BC1742BAE07F6FA
+:10265000DD017480F8DCDA5217C720BFB9AC22C59F
+:1026600005E3EDCF0D3A19F43775EBFED316E8DF2D
+:1026700021F1F6CCBFA958857AFB45FABEA68DC5D7
+:10268000FE1C82CFA3088FA60E23E1C77E236B9882
+:1026900003FDB7027CD662FFE99E146F1FF0D8BC21
+:1026A000C6E9690400D6E1D7D89B1F99EDF43CAD8B
+:1026B000A34BA33D34DD2A7952707E2FC3F8CA188C
+:1026C00080BFD143F03B6C9F5BACC07CDBA23C295C
+:1026D000088FC7EDB3783A41CC9FDD46F36F4BE6E8
+:1026E000E9879A4A8A111EE1F36835BA523C39D714
+:1026F000310F51EF7FBA8EFEE070BDE3FF7FDCFE4D
+:10270000768FEDDAEDA36243F9C055FDB8AFAF9F08
+:102710007F141FFFB7FDFFDBF62FDB33490E5D1B78
+:102720001F18D5B3C9CC87FC777B45A1759E8EEF6A
+:102730007CEC90095FBC765E0F04B5E405DEB87FE3
+:10274000FB242BCACFAD4C79C53C10E46F4B9DA543
+:1027500004F8D7FE46D96E7041BA4CB66641BACE7F
+:10276000815C17BE7F1B194169285F07E5CDDE3804
+:10277000AB1BF95D11AFBFD52117A3FCD9E088B31E
+:10278000CED7C9BBAD8D908FE314E5A52CD2E5B7AC
+:1027900009390F922C68063EBA695066EB66776F6E
+:1027A000F97107C7F3E6E6BCDDD9386EBD4C7CFB9A
+:1027B000D49649A76F81749B5D76A17E74CA9EF7FB
+:1027C0002A9517CBC487078B746CB1E27111945CA6
+:1027D000254321AD386586726D086B5FC9203DD0F9
+:1027E0006E6341D45F8A7CD45F8C537619207DDC84
+:1027F0009B77C282FAD76846FA18B38170023D68A7
+:10280000A080F946FC3FA8EFCF66019209B005B958
+:10281000501E4F43A1BC4F7B251BE542914CFA96BD
+:10282000A6AF3538DC04FF78D4E746A07E97B91907
+:10283000E7193143F660BBB8D250BD2C5C8F638A78
+:10284000B78C41BF8D3314B659BA5A5F0BD7CB7AC8
+:10285000F4022FE815D9BDFD4479EC21E9D697D8CB
+:102860003E16C3D8538A6B37EA3B4D81488F1FF21F
+:10287000BF7ED76C9D0AE92FEBF9FE2A8CB919E0CF
+:10288000C943B80F30EF4D4D4A6008CCA34B16F04A
+:10289000D828133C14CBD45DA8F7B4BDC48EB21BAA
+:1028A000619D2F318F14C3A88338D4BBA2D302B843
+:1028B000CF079F31F17651964016A43F5AE3DD557C
+:1028C000878A45D3A38C2532B6C4C2E16935345911
+:1028D00070DC41B2E7E1F150EFF4B3472F3F897A62
+:1028E000D91391B4DF6D46FBEC0590AE8AB7D0BC2E
+:1028F000E1CF8DFA4F1DEA0FA44F303F83BE961AE9
+:10290000989087CC6F013CED8AF02F47F9296F5FD3
+:102910005D620179FA4C042FFFAB63ED66FF38D49A
+:10292000A76FCE4679FB9B47E6375873191B6AD6CB
+:10293000FA1BB2793CE0ED4159D2FA5719E81FED84
+:10294000A85760DABFFCD52250C9EDB256BF6A3332
+:10295000EA3355274D429F1817311E6071B0D03EA3
+:10296000D209FDCE692E28B1DC8CFD69F33B6129CB
+:1029700084F91D34F1F6D31D278A713EB903DB2F8C
+:10298000FC04D669BEDFE46965627CA49BFB4CADA8
+:10299000A07B5DA567DC2CE8BE3D9F15239DC1FC97
+:1029A0002A033AFADB1E6F207C6CC12FD60B0C97E2
+:1029B000510FCA5440EF46BAB4B0F852A4B386D609
+:1029C000B148375ABB3DB11154BFCACC6A91DF1C24
+:1029D000E9941FC479B436DA630D300FB9D1B3EE80
+:1029E00022E4DF1C1F47F50606F35224D4BF0E9CD9
+:1029F000C9CBC1FD3E6423FDF1F28191BB0D38FFCF
+:102A00006613C376FBA36C958F23FF08DC50847894
+:102A1000A38D77AB98E7A6FABCDAC550FFB2CD66B6
+:102A2000975C88AF9E4AC49FA76C26BB9FE8D09E48
+:102A30008C7C6D901C203DE8C8D6B3F57500B7417D
+:102A4000028ED98EF3A41736785D1112B46B4A93B7
+:102A500019B6DBE428B7A01EB877FC4AFA6E726498
+:102A6000A6DA609C06D5E46250DE349EEBB52D8A72
+:102A70005AEE86FC962687E4D7C1C31BCFE1DCEA79
+:102A80001174E0E07CE1C958C00B483F99C0DAD628
+:102A900003DE9AED2C0FD7654CAB55D53EF4C2B989
+:102AA000A21F06ECC656402440F89F5874F6A7C8EB
+:102AB0002FBA4C1DB3EF4178C546785A21BFCDDA05
+:102AC000918CEB488C8B90711D49B81A00559DCCA8
+:102AD000A6E2B81BD2987D2DE6379BFC68AF243662
+:102AE0009BC87ED980F48BF6CE0216C0F525D5CBD7
+:102AF00017CD58DEF9F91A1CC7D928074D989E63DF
+:102B0000622E1D9F709EFFF0EF68873A19E4EBF884
+:102B10004C65B4F7ED58D81F739A9DDB8158B70008
+:102B2000F953CF9F13F9A7492422EA65BF19FA790F
+:102B3000662D87D7A6B52C80F8BBFF39F634C2C7FF
+:102B40006469EC3044537BCBAA3C1D5C57035C6149
+:102B50003C53F3C615B80E53B66E1E48F48E44C2ED
+:102B60009334D62921BFD82BEC11629D5094813823
+:102B70009289700C46DF8470FC999C8770241B043A
+:102B8000E6872C0ACBB5FDF82FD4B312AEEEC725DD
+:102B9000FAD1D28F8976074FC54DCD817E1FF3C7FD
+:102BA000E521AB817DA8E2F28DF78FE62EEE4F8214
+:102BB0003D421D0AF33F1BCFFB3F18515BD5979D4C
+:102BC000F087782EFF36BC021B0B7039B8CE75EF3C
+:102BD0003C8457A1CC90FE8FAB9C0FEF2F6201334A
+:102BE000C24FE5706A6A64013FC069E4EB4A830C36
+:102BF000F3491B2FC719843DEF87F946E13FA069D0
+:102C000093C7CB504F8C7230D53A02E9C15B89F340
+:102C1000608A5D2A1B4EF4CF649877A4A81F55E400
+:102C20005F81F8D164B15BD15FB035CD5582FE874D
+:102C3000A6EDCCDE4AC0F0C86551BD70B109B844FC
+:102C400036423BD84F5B331F07FB45E48EC672D834
+:102C5000A748C7E1FB252C57F937A62214EFA24657
+:102C600087EEF356018FB5711184C74DCB60FD6EB1
+:102C7000C12F715F97707C8AF484F693AAB0625377
+:102C80001EC2DB9EBC00E1B8C3C470FF33FCA1FDD3
+:102C9000A734271622FEA5315D7BE85F8D8BA5FD4D
+:102CA0004A39BDA75C46FBBF8AC906409A54E6571D
+:102CB000ABF2687FBE4079BE2951A67E531D718557
+:102CC000484720B78B514F4A4972E56D66BDFB6B93
+:102CD0007478595E0ED6B3170E867A4FC5093C4FED
+:102CE000E4789E7ABAFB5E84774A75E83A989EFE4D
+:102CF0000CD74E1B2DD1FE48E8C71846B737C67310
+:102D00007F92861728DE90DF004763C8472F47BBB6
+:102D100036A31EE3BF4FF1EC877CD4D1D2608EC6C0
+:102D2000A7657F12F467862FF20D63BBE21F124D79
+:102D3000E25D356179DA3766FD7C0F3C9743F675C5
+:102D4000AB91EB7B06A1A76A70F82ACE44F3F84A50
+:102D5000F85D807313BDDC27E65AF87CDA04E4C71B
+:102D60006DE95C1FEB923DBB23715EEF98C926872E
+:102D7000FED76379AC0A7A860EBE9B945A4B6C0ED2
+:102D80002D29203BBFFF7783D08B5A518F89E9CD06
+:102D90006F0BAE5B3E8FE17AFC054807B14159D31A
+:102DA0002B9022F57A81DF02F267A8C1FF5515C882
+:102DB000A3C4F8AD53EC4351EE3351BE718A9A0669
+:102DC000727DBD24F4829F3560BA570F00B2B3F410
+:102DD000EA01CCFFC8942AD403D2B4F6ABA7A8006A
+:102DE000F4768B565EFC0ACA953A637B01EA2D7530
+:102DF000B127EA51AFD960F556228F2B684E0CD11E
+:102E000073863B5249CF196EE8186681FA3B9ACA1D
+:102E10001A8AD2913E5D11B8FFD7824FABE28AB0D9
+:102E2000A35CC7F5C3F80D7153A6AC55AEBDDF8FDB
+:102E300089FD9E17C7F9DB7003D723C2F9DF735AE8
+:102E4000799BA916F596C221364EEF0D33F721BFB7
+:102E50002B7CDEB62B12F9DFDBB38D48FFFF1AA700
+:102E6000087CF6EEC6FCD6B7CD0CF54CB4CB699E0B
+:102E7000CFCD21A6640C98D4401F78F154DC506A61
+:102E80007FD53AB3F8B8079EB305400366CFAC03CD
+:102E90007EDD873FEF9498EF863580089C9864D25A
+:102EA0004712BC2A8E9BE9F4F919B433815EA6EA75
+:102EB000E8436BAF5C4965AACE9FD7625719D657D6
+:102EC000AE0CA0FC1506EFCB71D0FF7B835A173FE9
+:102ED00008ED760BF9521FA39EC6FCF5B2FA70B14D
+:102EE000FBEA7969DFBA35C120EAD73D6963DFFEC5
+:102EF000BA4B315C2EFD0FEC0295F8AF2D2230C499
+:102F0000ADB30B1E51AE6917603DFBC6B800DA3594
+:102F10006817C4915D600B6449FDDB0506B9C98380
+:102F2000E336303513E5EAE96797348D47BBE07542
+:102F300003D9054F3D3BF6769CCFE5D628D22F61CD
+:102F400004B213EC714E0FF2E1FEED8317EA8B73BE
+:102F5000AE6D1F84D34D9ECA08AF148515211FDCAA
+:102F600084FC1CF6C5780AF42BE48F2EAEF720FF04
+:102F7000C4AFC9E121F9A8F11725A0503DC379B329
+:102F80001FE58FA17E6307EA398ADD4BFEE4152633
+:102F90009F257E14B14705E1A0E957069BCA7C39FD
+:102FA000FDF38DAC6D8553EA61BE86531117A9DF21
+:102FB000201FDF707E13F9B1D9A1D0FE601C473C01
+:102FC000ECBFE9883718E9EAED5FE353FFE71175D5
+:102FD0008A3F0DED8528EADFB9ED87AFF8077D4719
+:102FE000FFC1ABFA77E13AC2FBD7F8A26DDB2D0D3A
+:102FF00064EF404B33C0B0EA616E57256EFB21F1A0
+:10300000977EC779EDAA7186F7B90EC13FAF3C3202
+:10301000A1C1AFA01E5A5BD9173D97C7717D3C5C1B
+:103020000EE2D94C5A1E977F49BAFD34A31C1CD11D
+:10303000BF1CBC03F101E65315C9F9DDB16E39F2CD
+:103040001DB29B1263918EDA150FE1AB3D2D515AE3
+:103050000BF453E4E0F2D01EB893213F951DDE75CA
+:103060009D689F6CF7A430DD7C5B851DE5073B2ADE
+:103070008BECA8F379A887FA9FAB6659AE5E7BEA22
+:10308000F2817B2D8847FB624DD4EF1D71765A9FEC
+:10309000F5649E0FF53BA2449D1E5015E39B81FBFA
+:1030A000647670396F4E63928FF4596E67FDA3F6A4
+:1030B000CE71E1C76CB3BA4A26C37C130B653BF2F1
+:1030C00017CD5E01FBC03A08F5A92D32D9BB3D767C
+:1030D0008AB06334BBA84EF099AD8D722BC26D3FA0
+:1030E000CCCB0AF4B4B53EEF4C29F4BBA15621FF7A
+:1030F000CA55F68C03EC1CD8B7A666792AC27D2B7C
+:10310000D84B680F391784D69B15E3BB0FF1C8560F
+:103110002493FEDA96DD4A7662B8FD712DBD355CEA
+:103120001F0DD73BD35685967F7FBD8FEB6DD7ABF9
+:10313000FFE15F5F7A1FE9A1C4478636A0DF82EC1A
+:1031400034488F8C1F4A74A904393E284887F845B3
+:10315000FA433A603E264944777B894F554B0A0B28
+:10316000B10355E68DBADA0FA17D9B624D421F086F
+:10317000E5ABAD0D335310EFF61BBDE4D7FEA5F064
+:10318000931E12DF6A71BEA4951F16FED423FD9410
+:103190001F15E5C7C437BCFCD7A25DB09FF6274416
+:1031A000BB53FDB47F59B43BDD4FF9ABA2FCB57EF8
+:1031B000FAFF9D68D7D14FFB3745BBB7FA697F56F9
+:1031C000B43B77553997F7EF88F2F361FD5F10F55F
+:1031D0003B457E8DDDC5FD1AFD9C9B69762BE6A1E6
+:1031E0009D48AAFBC0DEFD34F4E8F340A305BDF61C
+:1031F000A0C63762F35900FD139A9DA9D983EE3812
+:1032000017F7671781BD4899ED8437ADB8BE9CFEAE
+:10321000E1730A1DB0A3E8DC8FF44EC49B853A3CF1
+:103220003B1D6FE4E5B91C0EBDEB1A2C6BEB92A1B4
+:103230007E87B0CB6B84BFFC406C6F7F7ABFF6217A
+:10324000E197D2E6D51F5EB58B7969F5FADBFF60B1
+:103250003C0BE9AF3F3C3C1456AF3F7C381D366E0B
+:103260007F74F174587FCF8A7AEDE2BB2F5E16F03F
+:10327000F86E7C08C7AB56EDFCD6DED5E0CFE9EDA5
+:10328000BF3FFA3826E68B7F7AFF81AD9EF3DD04DF
+:10329000D61D821FD1AC83FC291A7E18AFB8993A8B
+:1032A00012D35C3ECD8CE7F3352A5E86FABFF1CAB5
+:1032B000202A1F78004C7B904B1B9E83D9C37760DC
+:1032C000A35DF241FDA6E78041423AD631534679EB
+:1032D00095A5DEA7A2BCAC3ED5A1BAA3757A732C86
+:1032E00087C7B5FCB1D5FBDEB95DD2B57B30B6473B
+:1032F000AFE6FADEE69921F648383F7C2CCE42F55F
+:103300006F895477A17E5F15C3FD7A6C02B3A37FEA
+:1033100000F42F09F587B60446FE50D901FA03944C
+:1033200067A599D864289F2CD61F64136CB9A86729
+:10333000D473BF94A63F0C35D8BF40BD81C55B5C3C
+:1033400028BF51DF42FF087C4F99E17B9F3857FA35
+:103350001EFA565D6C1F7A5D5D2CFBBFAD072F76A4
+:103360005C971EDCB71FFD7BE8C13F76F4A907C759
+:10337000DEC062715D2336BBC65CDDBFA617FFD41D
+:10338000F16FA7FDDFA5AF5EAD17AFEF6BBCEF7BB5
+:103390004ED09ACFF530BFC7427EA4788539E3F38B
+:1033A0001040A51E3C7F536339DFBAD679D3B5CE22
+:1033B00097AE75AEB4C71145F140604379500F998F
+:1033C000F42F398F14C3BC56BE61203FCE3EA32AD2
+:1033D0005B21BDEABCE459C7AEC67F2D7E478B8B0F
+:1033E000D1EC552D5E66BBE22F273F77739C84722C
+:1033F0004449E07479DC515E8C7EFAD60A7E1ED890
+:103400007A7A7B319E5B7EA9F273CCFAE6F292A1C6
+:10341000A8EF05140FD28D4D56A7E0F9D3F68ACC4C
+:1034200008C257E04B7A3B7988C38794CDF657148E
+:1034300092DE57F7B70916947B9BEC7911A8973762
+:1034400035F273CFB646D93A1FBE5B2B20DFD69B31
+:10345000DFA4F67DEE19BEDE81B1E21C81B1628A85
+:10346000FF3939BB0CE371B2EAE372AD04552FF9B1
+:1034700065A70AFEA3AC3278DE079E9950CFE92AF1
+:10348000CBAE323CDF5030EE08F3996E7FDC18375C
+:10349000C5F90174E197E2884F7A06E9F5C47EE840
+:1034A00053A3478D4E35BAD4D1E31F881EE784EA73
+:1034B0007B1AFE6AE75E0F38FEAD782DD889CF48BB
+:1034C000DC8EFCA3E3C57AC457A38BEB939A7E688A
+:1034D000C4F146E8F44C8CBBC2F9387C349E6EDCF7
+:1034E000CB482FEC34EB53CFD4CEDF3A1CBFA678B9
+:1034F000971E7C09280CED040D4FB60A3CD97ADAE8
+:1035000048FCFB4BA01BE6E6E7E87DC59769F8E1C0
+:1035100015F2301C4F3251BE001F6B43F902DFCC55
+:103520007AAFEC8BEA952F598D3319EAD546942F53
+:103530003957CB9795627F57C6DAE9ABC991DB6201
+:10354000B9BDC6144F36AEEF80D14FF126275AEEE3
+:1035500073925DF8822FC3DEC77CB56F578C4BE842
+:10356000637E2BFAB5800159E5D1042F9B04F0ABA3
+:10357000EE81DF0AF2BFFE58E046B5883F9C68B096
+:1035800091DE16B14FA2F386A57E85F0A3DABF6E59
+:10359000854CFB1720F8B9F719C9EF06E5B48F5A27
+:1035A000FBA5ED6616D4F197E58720ADE3176EC64F
+:1035B000E3EA160398823ABC75E3F979349687E614
+:1035C00033C39C18C4032B023DF9EAF5AE3A3F3EE3
+:1035D000784AD7FF8804E0477898F103F603B2975A
+:1035E00044FBFEE0F5F51A3578CA88E73D6A7E02AD
+:1035F000C20D0F3B80DF3F348C917D1A5E1FDD488A
+:1036000008DFF9AB26B0F7806F1D36D9C72BC88706
+:103610007F2E91DF605DE40F2729784EDD0543435F
+:103620007AFE03BFDD86FEB0E51D4D13A2510E37B5
+:103630004AB9E8E6DA7EA236D70EE9EE3B6D37A34B
+:103640001EC16CAA0BCF03D1E78CFAD6C7465EEE3B
+:10365000BFD3968B727B5E85FA36E2479261456EE8
+:1036600013DAE77F83D541FD8562379F6F2E33B92B
+:10367000005FEE5182C72598F7BC39AED108CF79EB
+:10368000ED5615BF4926A658413ECCB3302502BEA3
+:103690004911CC42698559305DB08ECD457E173DCC
+:1036A000DA6B9A07FDCF3BF68BBF70653DC0FDB866
+:1036B000C75EF92BDAE10B55AF09F58A1B0E98F8B6
+:1036C000198F80FBF0F6D0F48D4742D3B9C1D0F406
+:1036D000C8D3A1E93711F6F0DFAFFE7EEF1F7F06FA
+:1036E000F0EC7EDD40FAD65260473F043E76781813
+:1036F000D038AE5B090CC0F1C18C6511E8F77B32A4
+:103700008AE2493E5DE3DD5504803DD12593EF66B5
+:10371000E993512DE82F3EFCCD7B0FE13960F73363
+:1037200091749E3A61E9D3CF3E00E98F9E888C4523
+:103730007E7079D7F33F27FFE13343C8AEFD48F8E9
+:103740005B8FBF73F483DD90BFE4D9C85CACF7D165
+:1037500033CF0F46B82C79EAC501187773F9C9A79A
+:103760000A28FDE41323F07BF9895F0CC6FC8F3433
+:103770007FE893E616DCB7A54F5B2FC603DC3EF867
+:10378000C466D39F776BDFEBED7729F68BF883FD6B
+:1037900022DD3DBDA9231EE9ED40943F5EC757964B
+:1037A0001C78F0737D3AFCBBE4009F4FFFE5BCDF63
+:1037B0002500E9D100F70F847F7FE90173C87E0DF2
+:1037C000D919BA7F4303A1E99A4F2B4B62619CEC54
+:1037D0004FE794C4427F9F321E9F103EDE7E111F32
+:1037E0005C7324B4FFA34ADFF59F12F23F1B4F9A8C
+:1037F000757C22C5DCF7F9C2C1042E6F9F7CB2A78D
+:10380000BE81FB5180CC402F5B2AE8ED573D714AC9
+:10381000EC47A940574BC5F9AF96BF94E9D607E3EB
+:103820007D61896EB503DF9F2DFAFFDA08F483FB13
+:10383000B526B80DE39C3F58A3AA45BA38AF7BF62E
+:10384000CCDB980CFB577D302B1787D7F287B51B45
+:1038500049EE563F71321AED91CB074EEE5888F87B
+:10386000D86E64A81F427E22E67FDCFE52F41D90D3
+:103870007FCF4E772EF2959E7E774E548B74FCEF61
+:10388000FBD2A5C647AAED1C0ECF8FEE98940AF87E
+:10389000BB74A7E4C16A4BDB674C9F8678B7C7E06F
+:1038A000413F6381C2BC863C5CC7732FA7407ECD7D
+:1038B0008BA30A703DD04505E66F96BD538723DF85
+:1038C000FAB991E2C121FFB40C787422FB11D3251F
+:1038D00058C77F2670FB68F34C5B15EA4DD0DF2993
+:1038E00019DA45EF9354913E87F5BB0ADBA3D1EE7D
+:1038F000FBD068ABC7F3830FA36ACFE03CFCCFF0EB
+:103900007E5990CF7BB13827A83A66243DE2F03744
+:103910005FCC1C8BF4DE627023FFB86767285ED92A
+:10392000D52613CA832AE8DB09E35E6E89A2FE2F3F
+:10393000270406A05C3DFC4DDB05A4B3EE27CCB20A
+:103940003EDEA6EAC06FFE8A7C757120B4BF70BCF3
+:1039500088489434FB365B8F5FE1F590932905BD71
+:10396000E5D5AB404EE8CE85AADF6F32A11EBAB8CE
+:10397000D4F49DE37D71FEF9C12E99F0D44FFEE1A0
+:103980008306F2D37EF48989F8FED261ACC805EBD8
+:103990005CEE9CBEAB08FA5F5ACE8A310D7F920571
+:1039A000C6BF8CFF1AC8D374EE82784F7EE2E04324
+:1039B00037011E7CF44B03C5D3A5E0F91DFA3F582F
+:1039C000305A46FED66E90719CCB5DA000025C3EE4
+:1039D000B607A3E3904EBA36939F706DFBC9688C0F
+:1039E000875FDA1E4FE7ECFDF19BA3CF586519E026
+:1039F000FF71D7E391AC0FFA5DD2C5CFD7C3F98F72
+:103A000026872FE23F415EE726AA398928433058AE
+:103A10001EF484A4F8DADCDA3EFAD3DACD9378BB6C
+:103A200024C34AAA37C6E92DC0F651F97E37CAEF3A
+:103A3000389FC583E749EF193CF7D907A29CF59950
+:103A4000C80F519740FDDFC3607F207FBEC2820A4E
+:103A5000E0EB7C94CF23284DFC7FFE012980472991
+:103A6000518DE69073C045CD90D6AF638FAE1CF8F4
+:103A7000CD6294DFD174FE15447FEE927DA1F5975F
+:103A800082F98EE3563FFDAD59DF2F689E02EF5459
+:103A900013EA8D7F117019E3546FC37549E5169AC7
+:103AA000D7BDDB63288E62A1F920F5E310F114DDA8
+:103AB00007A5402BCA15A13FD43C304F5D007ACBFF
+:103AC00067ABE6AB0BE2859F06F9C04E89ECCDA54E
+:103AD000452C980EF3BC5DE8414B8F49C1E1905EE7
+:103AE00008EB477D62ECD3923F0AE4DD420BF347DB
+:103AF00023BEBDC5F7A55AAC0BEBC5E4211CFD04E4
+:103B0000D7C5AC83E633B68AFB57C61E91286E290B
+:103B10001C5E557BC2E0A7874F26C22514DECB0F63
+:103B2000019C42F086C309F41F66857DDB2EF8FBFD
+:103B300005B027F4FA256030D5DBBE56A2F2ED338E
+:103B40004CCC09F3DA317B511BC6D93C8CFE0E11EB
+:103B5000678871819B7BE20041FD85F12246B2DEE0
+:103B600073C7D1A45F517ADD0E75EA4EB08776181F
+:103B70007DC9E8AFDA5106FA2ED76BACA8D7743AF4
+:103B80007D9B1261DCF906EFCB68682C90D5010AA9
+:103B9000E2DD2A0EBF47F36A87D6F6211735BCDE71
+:103BA0002175A806A4CF9FF1FB3891C70E0653617B
+:103BB000DECB8A5DE4FF4C98753E1BEF9B3C26F8FC
+:103BC00054CC092EB77649AC0EED4527E08304FBB3
+:103BD000927F686B32EA9F6C81290FCF9B1E8EE526
+:103BE00072A1FB0D76339DD344D6B660DC51D2DC96
+:103BF000EC3C3C0782F5CE2D877EF625BA681EC9BF
+:103C000036BEBFCE757EF74AC84F029844C5E178EC
+:103C1000DE152F613FC3797C1BE4D7A31EEA646BDA
+:103C200025ACB73181C37BE33C56F9CB1C3A6753D3
+:103C300062E2F8F71C7CC1FAAC33C23749013D9609
+:103C4000E7D7E138DBA3F93A1264C3DC32DCAF3CDE
+:103C50009E8E5B2DA9AD84BC5B695E4966568CEB7C
+:103C6000C47CF4C7C1B4D483541EE07831A1369724
+:103C7000E63B907F5FEBB4F80D80C7AF3934FD337E
+:103C80006823FD937965E4973F1272F333A39A3466
+:103C900012F9EF1B46867680634058FD41D9BCBEC1
+:103CA00090575F7A26C420511D31AAFFCE08AE0678
+:103CB000A9B58F73FD37C53ED55C4965019D7CA8CC
+:103CC000A9FC8AF4F09A2B0342F23F5E032B19A25F
+:103CD000932355272661BD65AC6323E2DBB27603EF
+:103CE0000BE8E8E38895EBFD8CD5FEF16730FF4BE0
+:103CF000AF65E5E9E340353AA8B962607EC0E99B6B
+:103D00000C32D5AFA934511C404DBDA105E9B4E634
+:103D10008A899767F0FE6AAEC4337F3CD697C84F56
+:103D2000D5DD60207F69EFBC13A9BC673D57A4D0E7
+:103D3000F491AF453D85F2D9E8CE68E46B8B31BE96
+:103D400000D2A520CF903F7D08FAE92F61BC4F3DFE
+:103D500006E21B9F8AF97CBC06180FC0E192C2FDE7
+:103D60002C9702B23F4BA77F5F12FA28535CD1E534
+:103D7000C3AFCE4F3174464B88FFBFE2724E2BFF6C
+:103D8000D4D54972AE276DEF8C46B87E5AA9D17151
+:103D900050C17DDDED39AEA0DFA8DA737C12D3E12E
+:103DA00057EF3E44626C79CF3E24AEEF08CA187AD2
+:103DB000F668C3833956F89E10FCC3FFE0832AF0EF
+:103DC0008B44831CC24F30F6458B4B4694DA2E1B36
+:103DD000447C51E38345E3746951BFA7BD7FCBD4D5
+:103DE000A234A0EF1CDE3EE3D1877EBB4ED1C90FCB
+:103DF000A57B80374A97B684A56D901EAE4BDBC37A
+:103E0000CA1D61E5CEB0741AAF7F574CE72803D8BE
+:103E100076C31E7D642ADE73BA2BB5F3C7786FAC08
+:103E2000D1B07D6A5132CA61CF24E4633547243B67
+:103E300057D739FC967B18E989364FA709CF6922F5
+:103E4000F33D2FA33E520DF524C0DBC89C20437EDA
+:103E500057D32E51DC4A4FBB76AE5F56B75FA47680
+:103E6000FDF69F2D135FD89C7D89EA2D5BF58909AE
+:103E7000F5A1CDD5AD5E94532B4C9CBF29CCA7A604
+:103E800002BD2E3F52467EAA3F0C3FF67B0C178D9B
+:103E9000FCD1E76B15A8F2EEB23F8DC2767FC0AEC3
+:103EA000C7205F0E0CC5F673AAEE1E8AF971391D84
+:103EB000BF9F09F52E183BF762FCC9DD49BF988A00
+:103EC000F7B92E4475A6635CF382470FF27442E79C
+:103ED0005E84CB7F3CFA4B82D385F4CE7419D28BAF
+:103EE0001FFD88A7B33AF762FAB1A40E9E1EDE99B1
+:103EF0006EB0A33BF68DA94590DE6FE77CF0E760DE
+:103F0000D7223FFD43989C9B9DC4F5F107B2D48A0C
+:103F1000243ACFE572662FD82E16E09377EDEE7C2B
+:103F2000663FC0E9AE9F44A28461FB3F9E5EC2F93A
+:103F300085DF8BFA6B1247612E0F89AF2BA44724C4
+:103F4000A30C8CEB856BD4800E17CE235C6E0C4BD0
+:103F500054CF2525F47E13DDF085FAE7925CC28FFD
+:103F6000559BEB827EE7CCB179306E88299DA310FA
+:103F70009F1EB6F275011DD07ED970DF90EF88F5D7
+:103F8000D424713B715AE244EAEFDE7727EFB27036
+:103F90007B8EDBE7CB8CA4C73497A9C9E847682E92
+:103FA0004BA4F8EAC3DF703ED2BDD54AEBB81DF989
+:103FB0004C3CF2033519F1854D37113FD0F850F3E1
+:103FC000E209C9C8A76E321426231E769799C86ED7
+:103FD000003EC8F9DE32630BA5353EB8CC487C50B4
+:103FE000E35B8CB527E8EF71DE61645EE45777B47C
+:103FF00084F2AB3B24C827FED29EA0E757D7CADF86
+:104000009EA726231FD3E695B4BE9DE691F4A83B58
+:104010000EE14F8215F59AAD435A11BE9DCE7282C4
+:104020005773D9E3D6BB737AF1F7892C7527EECF96
+:10403000ED228E4FC313FC43FFD7FC6D492DE8875B
+:104040003927E00E7ACB08D4E78E39B5FD648407B2
+:10405000E792B8BFF32E73D088F4F0BFFBF20FEFF6
+:10406000CB6FFF917D59B6EA4FD7C5DF34BADB215C
+:10407000058D49B84F2F72FD12F3CB014E8D89BECD
+:104080000B493A3FF95D3F5D964C7144623E91F7B2
+:104090003F5F3C0B92176EBFBCFF71687FE12756F4
+:1040A000D283C2F5D70BEF581AD14F1699D3B90C5A
+:1040B000F73B6E55A41DF5ED0BC22F7741ACBBE06D
+:1040C000274B5F43BB33DFC9CFB9008F9285BFC693
+:1040D0006FC1F99599BE1B8F5E3450FCB855E05105
+:1040E000736E60D722AC3723C7E37791BD4BFA0DCF
+:1040F000FB6924D9D3CD5997089ECD63189D2F35E0
+:10410000BB7979F3ECC1013FE191EC273C9A1D4169
+:10411000FD6A78A8C53D7E56E9A4B847C03F3EFE7B
+:104120006299F0B8A77C5026DD97027C24FDA91780
+:104130000FBBA3CB74F8F399F08B7D86FA4C8C2ED1
+:104140005F9C2781FC8E2E8FBAFEFCC4F52ADD2FE2
+:10415000D1F050C3BBF71F01BC9148BD188C74E06F
+:104160007672FCD1F8ED31A72FDD99A0D79F395D8C
+:10417000CD7F7838B5DB14C5F9F31E2BABB7E4F56A
+:104180008EBB07EC0C942B60976662FBB9D0F008ED
+:10419000A4E726F97EDD89E3ADD2F0D76B427C5BE4
+:1041A00028EC61B63AD4CEC3F8A79EB4E1EAF42273
+:1041B00095FB8DAFB2B7D937E6D0765C2F89CCE9C5
+:1041C00036229E3F6A657EAB4E6EED44A730AC6BE7
+:1041D000E7039101A44BADDE171F47C8783FE1F418
+:1041E0006B2363F05CE60BE68941FF510DF48D7E95
+:1041F000536651E761BB9A75512E84C7725C02E425
+:104200002F975DE4D7BAC9C0EFE7743F2711BE60AE
+:104210003B9C6FCD20C6C6C591BD4EF8F54183814C
+:10422000FCD837650416131F5B1CC1F83EF91663F2
+:10423000FF972A87D13DC19B0C9F3F4EFDBD60A6D5
+:10424000F24F133AC99F558390C17EFD7F5FC3FD36
+:10425000F9B06589BDE740E877D5DBCB9FC27F78B1
+:10426000CF41C3DF6A714FA7171F5DD1880FCB65A0
+:104270007EBE18AE5F13752492FF180F73AE47CF42
+:104280001E4C76E6AFAC797A3D3BFC8BF01B974732
+:10429000DF5306DA9FCE026F541FF5E44B8357F6C7
+:1042A000611FF794EFFC13DD6FC273293D5E54F775
+:1042B000E28FF4AD84F3D7E193BB973FD5087F0736
+:1042C000E9DF38EF2246F1CB51221D59DC11407E47
+:1042D0009570A27312D9415D608F63BD1C9687FEF5
+:1042E000D3B1C75A4EA27E1A57D4918EDB5823FC05
+:1042F0007E1ABE69F31C736CAB01ED068DDE74741F
+:1043000046E32CAC4AA1738F4E64A26330731DB593
+:1043100047FB97DFEF519317C29C762CCEA4FB2866
+:10432000910A97070B9B86B4AE15748DFC40B39B26
+:1043300041632C407AEB7416FEB313FA7928B970F6
+:1043400007D227195F63FA87A70617AD1EDACDDFFC
+:10435000E5775BF909D00DF0ADE257B292906E5659
+:104360004AAE24C4D30F0C3EF2B3F5FA8382F4AD07
+:1043700016F4BF48F89116697EA39DE690B849F4FB
+:10438000CBEAD34B843F891D30F7C643A27FA88870
+:1043900005A3A0BF65E887C26F7B68BBE5AC9BDA6D
+:1043A000D51CF93624AE9735F3F5CD15FBBFCBCA36
+:1043B000FD47B1AB5B0CDCBEE3EB8BC953DD1B905F
+:1043C0004E5F31927FE33FB188F8995A807C7C8CB4
+:1043D000B33080F08D403B1AD6FD3EC835DC57D057
+:1043E0009FE796A31DB986A9838CB47F05E57DE080
+:1043F000F7E6A3D62AC487D7043FD6F2373A8D947E
+:10440000263F13F2810633F195824CA1EF34985B7D
+:1044100051DE2C30F3347B909F232D9F69F3617F15
+:1044200097841FEC9C93EBCFE79C3C4E534B6BEB7C
+:10443000D3CE09D1DFA3BFCF76A1A71EF7B3007FEC
+:10444000A2F8AC1DC6807521F14D2FF9DDFFFC31BE
+:10445000DFFFD3A7E72FC679FEB93282E139F30235
+:10446000E18FFD3373111FEDE18F2D069293BDF2A5
+:10447000B496CE07BB5E8BA7F8FE1E79FAA14993CE
+:10448000A77EE4935DED43B9BC05FD8EF4ACE7383F
+:104490003C808F115FF5BF385CDCEBF6EDC2F39624
+:1044A000AEF6040FFA3D3EC07344006597127802E1
+:1044B000F514FF312BE9395D82BF7D76F1E208D436
+:1044C00097BA04FFFA8089FE0286D6FD347E2075F5
+:1044D000BA6EDF8E8A7B855D2CB888EAB55B43FCBB
+:1044E0000929669ECFFE15F275FE9F5F1945FD8373
+:1044F00056499F7FD8147C9CF4E45FF2FC77CCBED5
+:10450000A8641DDFA88E0E0E8EB57D17FC80C1E15C
+:104510007A8FA5737D2303F804C717C2D71EB9D3BA
+:10452000626835737D84F7F38224E0D79D4DFEC524
+:104530000F07BB70FC751FF2FBDD475BB89CFACC24
+:104540006BA278EB2E2117BAC2FC2E1ADC76184526
+:10455000FC128C83F0386C5267D37A379BE3B1DF5F
+:104560001AE4D3E887AEE77121FDF19F9AD6F9747A
+:10457000CFBEDFF2AABFDD45FD849D2F7E5AF5E751
+:1045800001FC7E27BFF7BFDC2ECAC2DB0BF9C71CBC
+:10459000DD897DC99B9E7A5D1B5760BDF071489F88
+:1045A0002AE07218F9594DD8B925D3A70D57A74B52
+:1045B000936343E225C732ED2FB4DEADC86312B07A
+:1045C0003CB4FFF78DFE683A0FFB50A6FD5DD63C6C
+:1045D000EF2E5CF78204DF8C64A87FF4914D050414
+:1045E00007A1878EFD2887EB7D4DFC9CE37DA37A98
+:1045F00017D2796C51D074B74EAE5627F373CFF9FA
+:10460000667E2E8461857A7EA595171486F209ED63
+:10461000BB3499F38BA80E2EDFC08033A3DE701459
+:10462000FFE9D2D7E37CAE3AD945FD657471FF4FFF
+:10463000C6EAC07A8CA7A86E9F3712C196B13A48D5
+:10464000FCE57D230BA2FEFFFEAE28CE0FD0DF01DE
+:10465000FD2E1ACDFB5D6400FD13CF23C4B9E71214
+:1046600001CD4566D053819F3F7F60BC210AFA5D32
+:10467000B247F258A1FE58C1EF515FCA40F923CEAC
+:10468000C5AB58C7C64EE87F5123B38CA6F88980C6
+:104690002195E04CB15D00974E3FD9A54F49B9E84F
+:1046A0000F06B955170DED96A801F26B869F4B3298
+:1046B000FDB922EE079E77E9CE85963535D0B99AB9
+:1046C000260F516EB130BD36148FFC7DCA5B4D1E76
+:1046D000697217F4F06DC97C9F42CE8196B15A7E03
+:1046E000DE25E45ECFB8426E7E60E0727A91792B6F
+:1046F0007D0F24BB697F96B04E2E77418E22FFBF7F
+:10470000D6FE1E10FBABED6B3530CA9BA1FF27C454
+:104710007EF7E0D36A165C36827FA346103CB93E32
+:1047200060E1FA007E23AE432F08D707C2E57FB8C9
+:10473000DC4F327139AFE181FE9C00F59CB1AB03D7
+:1047400006DCCF97D704B6BD9FC5D8D7D6E81118D9
+:104750000FB6CAC2BFF74744B7E2F76BEB8000EA77
+:104760009DFE424E67FE0B51743EF8B5ECD9F9063A
+:104770007C276DE274B4BE81CB8BF56BB93CBE98DF
+:10478000CCFDFFAF88EFD7025E27703C23DE4F38A9
+:1047900040E34EB2E42A48C753ED9F0F50A08A0170
+:1047A000F4A5488C73B6713E6B381245E77E935280
+:1047B0006F0EE23E9F8C32D13B2848F736D897C91E
+:1047C000ACF7CF0EE949F80F1872B26DF07F22FFF7
+:1047D0009C24F6BDDAE27B0C43D73E31FA7E818E13
+:1047E000D33D66DFBB883F1399AB0EF5FD09232649
+:1047F000D33C60D80B989FC4D43F26935E9066A7A5
+:10480000B82C819FDAFCB5796AF347D9857AAAE199
+:104810009899E2CFC2E76710EB59FF4254601D94AC
+:104820009F4C7E7D23E253F8BC35B884CF1FE6FB56
+:1048300005CEEBABE437EE42BC2DB4C03A649AEF40
+:1048400097384F98EF5F92475D3D5F13F291811863
+:10485000AF1AE50F8B53FE86EAA7C92171BE5A7CB9
+:10486000A24687273F6199682FB27A20DB448417DC
+:10487000A7838936F345A4AB13467604E9747D1407
+:10488000CBC6F59F64119E756EEA66103E7920894D
+:10489000FA2719A753FFF928D25F240B8F4B003D4D
+:1048A000C68576D449AB5925FEED7285C4F769FCFF
+:1048B000FDE4BBA9A4179DB09A6D8897581FF9E530
+:1048C00009C912C8947AF1973974717C9957E33306
+:1048D0008A9BAEBC5EBCD6DEA5189DC2F9402A0BF1
+:1048E000D2FB0CE93055E483E93699F68B8938839D
+:1048F00009623DE1F39C60B151DC29B3193FEED46C
+:10490000F13FD6F4A8AA87DB0984674C2F5C3538C1
+:1049100086CFFB2A38EC04F817E8E06F817623E8AD
+:104920005C91A5C6F5D19EA5C5627C33C5EC001F80
+:104930007A3FC9372E2501E37DB81EDA5D6621B9BD
+:104940001A57DC4DF7E62EF4BE0741EB3C2986955D
+:1049500023C7A5611CD78C142E17C3E7A5AD277CF0
+:104960009DE170D0E67BAD759ED2FA0B5FAFBD9F27
+:10497000F661EBCC317967E13A2FC89D51C4CFC5C0
+:10498000BDDC1A717E899889FDDE2DFABDBB53A26C
+:104990007E77B3EE870693DE6CB0A3DCBBFB982179
+:1049A00088F14DAC7EA2DA19321EA703AD3DDBD9EA
+:1049B0001D8DF242EBE7B3AAFF8AC6F8EAFEDA578A
+:1049C000A7707E7862F6571467B2FB581B9D9FEF65
+:1049D0002863AC83EC5F4F34DA652B0CDE4F336019
+:1049E0001DEF55C984FFEF554550DC6F38BFFEAD54
+:1049F000E017D7CBB719ABBD11E73BE9B6795F3A02
+:104A0000E87DC3FF9AF61AE8189326CFFB11A6FF9C
+:104A1000F8CF6F4CB381DC9C3441A273B88D29EF81
+:104A20003D84F1C99366CDFB5102946FDFB3EE561E
+:104A30000796DF218973BA7FBF15E38527CD954897
+:104A4000C91B91CEEB47E6FB8C788E3853BCD7035D
+:104A500059AA3ECEAD2985FB3F9B045E6D4D715139
+:104A60009A4085FA47258FD7007BCC584EE7703E99
+:104A700023CEFBCCCD60C5DC88FDFAD29B747ADDF9
+:104A8000D969E63B551BAFA7F77FEF4B9142FC7FFF
+:104A9000E1FA5C9B185F3B87C1F63386EBCBF9BD2F
+:104AA000FD7D627E361797F738AF8AE1FCABD7AF52
+:104AB000CFCE1EFF125E019AE171D7616F3926DFFA
+:104AC0009329A390DF7F12C5F5D5CEE1B88E0BC632
+:104AD0004E1EF714CBFDD1C8578E021D4F2CF6EC9D
+:104AE000BB1FFE7D2E258EC63B6BA43750D8C968F0
+:104AF000734B1D2CE5B4E0B7F8D7A8C917E8776B5E
+:104B0000E443692B016E2569668A172FB17138FE5F
+:104B1000364BD2F817BD7BA3C99952D6A1207D4C44
+:104B2000CE194272E656D64D692FB31BF15BCE3CCF
+:104B3000F4FD6C7C6701F93334F999DE233F5FC2E1
+:104B40007515B300B59BCA7CC750AF7CBB677E416F
+:104B5000A2EB1E7E19260FFAE59738BDC4DEF339A5
+:104B60008D5F4B0B84BCD8E827FE9CC47CBF4F09EB
+:104B7000E1D71D12F98F467B2CFCDC36942FF49C78
+:104B8000D30C9548FE3C1A194DF6E2E9A152AB99B7
+:104B9000C3C780F700099ED06872B6348FDE4143E8
+:104BA000E10BEDA67A24D24326BB92E6235D4DC5E8
+:104BB000B1A0FD9BA3387CB5754F2E067842F9E471
+:104BC000059B3A90AF4FCE7EE3F6BEE0FB2BA3777A
+:104BD0006202EEFF34BEFF155EC980EF8494674B1E
+:104BE0001427F9D69AD3A467E49E72D1FB21533DD2
+:104BF000B1943FF2B5A08CEF8B4C1B1D4BF198C3C9
+:104C00000F75AEC3F46D2A2FBFF158F7094C97E525
+:104C1000C4E6613AA7DD3E1EFDE225156E8C3460C8
+:104C2000B173144E5F8324ED7DB810BC28FE7D5D0A
+:104C30002982CF943A98F06F8C576293A0FD980A1E
+:104C4000E9717429AF8B5C3E8ECE55FC4F1890AF46
+:104C5000CE12FB193B879F53CF9A5366C47B2680A5
+:104C600037F7E13A014F2252137AF1E7BE88372E27
+:104C7000483091C3222ED87FAB46E7DC1F31DD3BA5
+:104C800024B059CCAB422F6FD1419BD82B27CE4AB1
+:104C9000A2FD3CFE1ECDAB6F83410C7C6142A9BBE3
+:104CA00088915EC1E85C23C96BA673A809D9B34A91
+:104CB000705F2678377550B92D4C8EBCAF8BDF876F
+:104CC000F49BB89FD09FB34222BF1BD3C7F71B30C2
+:104CD000FE87DF5B761673BC4CF29942EE0BA05D4B
+:104CE00013529FA94353493F032D17E09D2DE26FB7
+:104CF000E09F418C2385AF8A71A8C6942E3AC738AD
+:104D0000BD50A2776D6F0A78CB483F1076DF7441B3
+:104D100017CF2FE0FE8D12AF14B0C03F4BB2D7CEED
+:104D2000C1F5469FB3917E8CF86ECAEF850F137262
+:104D3000FD4921076F70324B06E90D921FCF516E6E
+:104D4000783E85DBCF4EFE86C0B0952EDA87925234
+:104D500089919FBB3182DEC183797CFBADEE3EED54
+:104D6000F452318FD5F9017AC7C2314DD6EFD3E174
+:104D70003C2D9EC86F442150E9F5B120D293937920
+:104D8000F0FCE9D50A59C5F70CFDCC42FE6839475D
+:104D9000223C28F74AE49729BC12C9822371BF5DDF
+:104DA0001B1C58EF6D13D14B42C5BC3B996E9F0A3B
+:104DB000C1AE227F54258F5F47CD48D1F19174C099
+:104DC0001F2FDACF617C081D9608D7E49E347493B8
+:104DD000887C85D13900B37412DCA3343D4CD88370
+:104DE000DAFB673775C6CEC7FD29F0723A4FAAFCC9
+:104DF000CD39FC2E4FCD2420E19335E8F797104FA5
+:104E0000A0DED94F5801F289B3FDBC47FC93542D65
+:104E10002E9BEB69E53E7EFF6C964F22B937BE783C
+:104E2000AD82F6F0D7B1FE53C83FCA7324B60EE682
+:104E300031B578AB11F588A205F3D251AF381BE537
+:104E40004D473B797BAA8BE631A8C21C9471FC6468
+:104E50001FE59F15F1F15FBF7BFF5CC49B7257ACF0
+:104E60001BF166BC6B4506E2C3D405B16E847F7D41
+:104E70002AB7DB2A8BF9F8537D6534CE8C05F368AD
+:104E80003F8B2A5BD2703EDA38AFA607D2D04F07ED
+:104E9000F298DEAF1B542AC6B5868E373307C68319
+:104EA000F2F1397CBC19A57CBC1D62BCF24A180F1A
+:104EB000E03443AC6B76698B42EBCB5E41EBFB0F8E
+:104EC00077ED9DD8EEEC141807DA0D2A867100EE06
+:104ED000832A3775E07827D6A8EC3DF44787C921A7
+:104EE000BC5A1495D7BFFCB909FD5E18D707F884E2
+:104EF000F17B0F993CF506B4B78A02C25F1E2A57B0
+:104F0000923E563760BF25CC53E4E0F1C8727D6213
+:104F1000AF1CD1E4C2A31ABFCA15F2677A0CE1F93B
+:104F20009B287F60FE5BA7C7105F9E99CFEF2F691C
+:104F3000F2677231C81BF8CE14F2E6CC189037280D
+:104F4000874AB9DCD6E40CFEE9F9B826776EC3A728
+:104F50000F605E65CCF3561EF205A38BE8C46FE5C7
+:104F600072A78879492E4D61FE8A69A85FBCF567F2
+:104F7000B2C3971B821B11FFC1DE247E7D5F849B21
+:104F8000FA99CE7CE3FE02F99EA09DDEBD2AC9E11E
+:104F90007227EFB4E724A64BF3793AA7BDA310E537
+:104FA000D0ADE3781AE4C0EBC8FF461CE1F2C95B60
+:104FB000A4D5E3E9921C37C92BE093BFE37C32749C
+:104FC000DFDE1274DEB36FE1741CB68F3D7A839717
+:104FD000D31DDB584B7A8293B54BFC5E7687847089
+:104FE00048FB11A373CEFEF486DFF6EA5BA1F6DF81
+:104FF00075EA33DA3C88D3687C85776747BB3F4DD9
+:10500000B42F407F02CE3747D3736A353DE70B0E8E
+:105010000F3E5F27CE17E0DF96984B78193EDF559D
+:105020004EF52B94B7130D360FF2D93FBFC5DF1BDA
+:105030009AAA361421DD9732FF06BB8EEF0C013B96
+:105040004BD1C9ADA1010B5374FEB91B0ED843D28D
+:10505000C3DB9D21F56F3CE20A29CF05A1A72F1FD5
+:1050600079DA13921ED5313AA4FE0FCEA921E93187
+:105070009DC521F56FEAF286A487319F8C8BBDB95F
+:10508000BB32A45DB1CB1D83F433F480C2DF53F295
+:10509000AB1DD989749F94FE6EB9E20BE967B8B86D
+:1050A000F7379E2D0EE9871DE2F78A6BE17FB87F07
+:1050B000C3C2EE150F16EFE556EED3DD3F86FF06B1
+:1050C000E3FDC068FC86D60FBFE777439AB8E79741
+:1050D000CFF2512FB86A9F18BFE739E3000B0424C1
+:1050E0003C57A2BA6CD82EFE6E62F8BAB47B80CC64
+:1050F000F09A82F5FE02F2189F88303B43F7D5EA1A
+:105100000ADDD7C8ECD07D8DF284EE6BCCE8D07D83
+:105110008D5543F735BE38745F13BCA1FB9A541903
+:10512000BAAFC9BED07D4DAD0ADDD7F4DAD0FDCC23
+:105130005815BA5F6E7F5548F9C0FADA50BC14FBB7
+:1051400099D5B42AA49DB69F7EF8DF77EDE78C8AC7
+:10515000F146F4834CF71A43EE995FEFBE2E0ADB5B
+:10516000D7EBBDBF09FCAE3A6D54AF1E837F7ABB4F
+:10517000EE37537EA070FB6EF9A137607F8B6DDC3C
+:10518000BEC33F3DBF2FCA2953F098AC58C889739E
+:10519000595C4E68FA1ABA01C8AEF171FBA444D842
+:1051A0007FE176C974D63D4019D83FFF073E5E8740
+:1051B000F37D39F2D734AF6216A4F66FF5CC3F78A1
+:1051C00095DD87E748D7CB277BF8F5ADB5C4A7AF0A
+:1051D000C9AF5DE9BDFC0F98EB845513BC786FB582
+:1051E000C7CFF5BA91EE634E78603CE5AF7DD74C02
+:1051F000715685A5DC4F3B0195674C77C964DF1577
+:10520000DA787A821DF46AAE47AB7ED4A313B8DC99
+:105210003E53E649C7B8AC33D392B4B82CD25FBB87
+:10522000250B9D339E889AF56E2D8E27E2BCCFE428
+:10523000F2FD3833CF45F47B42D3039671BDFC4C6D
+:10524000148FEB3AB382BF777BC60DEB84F1CEFCB3
+:10525000D8E5D2E2B3D00FD91D2587C5677592BFB7
+:10526000F9E8683BFD1EC64D19ED418C4FEDDE2E71
+:10527000D17AB5F3D2A34D43B4F82C7E4EB2859FBC
+:105280002F7D6864DC1EDE3A94D61557CCE795D1A5
+:1052900025B760D589E25EFB51052435CED7C5EF31
+:1052A000091F15F15B67855C3CDA13A7E527FFC38F
+:1052B000D1CAC174BE1D2E1F8F32FFA04770BCCA59
+:1052C00008117FE7CF7F13EB570DE3F559A8DD0FEA
+:1052D000F5737E89F5BD16AA7F26D6938EF1EB1A5B
+:1052E0009E9C9936391DE9B508EC399C675105BF7C
+:1052F000F75F64DFAA60BE54C9E56838DD753A7DA2
+:10530000E7D312302EEE89152BA1AF2959FBAD48FA
+:10531000A767FAF1ABFC661AD09FDC4B7F25487F6C
+:105320002EFCBAC8BE7C13F428D4BFC3E951F303E2
+:1053300068FA55316B127E124E2FD358A78248DB84
+:10534000AB9F75D37D99ABE92E97E24DD1FF8F745A
+:1053500057827E160E54F23B01FFF812D7A3C1E12B
+:10536000ADD8F69378BE5804F3F2D3ACFC4CAFB78B
+:10537000F4477F1AFCA6D82FD2F9F209EBD703F431
+:10538000FCEB70A2CF90AE3BD79A1217B0DAFBD0ED
+:10539000877FDBAF7FEAD7E7113FCA857FAA5CC072
+:1053A000EF8C95DB37E1F09B50319EFBA7849E3B51
+:1053B00091F9859E1A20B895F6C3BFBEC35F959A32
+:1053C0009E80F077697A2CF9AB007E69E97DE89BD5
+:1053D000BF17EBB85E7D331C7F7BF85945A8DF4AC9
+:1053E000F357B1D19CCED76BFC2C0C8E3D7EBEB05A
+:1053F000712517EF6F9278EFE0553BB717A0626900
+:105400007222E219FF7BB59ED333E001F19D622148
+:105410001F61F9240F3DF03F9CF75F98CD6701387D
+:1054200095E684CABD42F1AE4151D83B2B85E21DC1
+:1054300084C2B07C6DBDE172513B5FE96FDDD3D2B8
+:10544000C53B2C2E36E45B28079948FA50C7EF0D70
+:10545000743EF152C2AC055B611D431E1B46EF0357
+:10546000BD9478C78FDEC0F4CF0793BD302965F1B6
+:105470009E15907E7C770E956B72751646A9C1BEFF
+:1054800016C9D242F40B66E7BF7DBB1BE67DCACAD4
+:10549000EEC4B493553597C138CE9CCCBCF5D04FF3
+:1054A000918951BDA9372E1BA98F17B847F43355E1
+:1054B000C429A7E3937E79F455D05F93EE0C287648
+:1054C000E8D724EE75A52AAC0EDF8534399B6C76BF
+:1054D000845F04EFB7283398762FDA3D876DF4AEFA
+:1054E000F70D9EC88B03713E9244F3B9215B0AE22B
+:1054F000BBDB4571A27E6170D036ACFFA4290FF9E9
+:10550000F90D9E691F62FD22F15E6DB4EA330E450E
+:10551000BF8AF00BFD87C2F1636DBA85ECE7E7E760
+:105520008C37E2BB0A33BDDC2FE7F477D6C5E37ACC
+:105530002BC7E7E37AB5F5F9D379FC55C5685EAFBB
+:10554000C23BCFB840B7FE996A37BDF33AB3F2A277
+:1055500082FCE0F761F45D86FF20FE78D79D3F86F0
+:10556000FE2B8A387FACE8873F7AF11F802F13E645
+:1055700070BE5656CCE97B26AB25BAAC644DF4BD63
+:105580009DB5D3770EEBE0747DB187AE331C9921C6
+:1055900074BD03E97A065385DF9ABDD8E9BE9A9EA9
+:1055A000FBE37B40FF7BD213AEA6BF57FBD1C7B650
+:1055B000463EBB07F9D8EC34BE4E56B9F525A4B328
+:1055C00009C566B2CBAEE263C307D239407FF2A011
+:1055D0003F3ED6BF1ED6A2083DECB9749D1EA693D1
+:1055E0000787FBE26767FAE0677ABDAC5F7DAC5482
+:1055F000F0AF307D0CFD5AB8EEF45AC6CF17C2F4A6
+:10560000B0EF38777E9DE07D8D73E7F073EC6989AC
+:105610006A817B54EF394ECD398BC585F1F6F95E41
+:105620009669C37B38E3E76642798D386F8AEC6010
+:105630006A0BE4EF1571D153335DD4AFD3C4E36883
+:10564000F0DDB55C1BC68F7470BD2981D9912EB574
+:10565000B88FBD51D02E0FDB49D4AEA7BD85D5453F
+:10566000E8DA17DEC1F9F0575B4CE2DCDF9781FA2C
+:1056700052E21FCC14DF7CE92113C53D0E3471BA10
+:105680007568F71DF0975AA0BFCFD2DD7CBDD20957
+:10569000273AA7FC6C337DB5B8D84BE21ED457B17E
+:1056A000FCFDD5AFB6244AA8175E52D4972B61DC17
+:1056B00081DB62252E3F79FD3FA5F3795E72A99FBC
+:1056C0009FC67595D9B83EC87CB918C76936E497A6
+:1056D000580C283F56779F86F6CBD26D76C4E3A24E
+:1056E0008CF367F17DF80F0F19E9CDCDC5FBA7C786
+:1056F00004B199A23ABDC3AFD6A3160742E5C5D2FD
+:1057000003A1E965EDA1E99A3079112E27A20708D6
+:10571000FBC9C53C2807AED77E1A20A98E0118BF49
+:1057200023F6DD6CAEED6A81759B1FCECE5B4B7CA4
+:10573000A7FB38BE0D9FB8CD4DF7437F27F8F97B07
+:10574000E9DE346C67CEC81981FA62614629C5BDAD
+:105750007FB5CB4ABFDBF39595DB015FBDC8E5673D
+:10576000F3005EDEBCDBEC9288CED5D25105184F3B
+:10577000C5E9A766279797F067E1EF17A916DCC779
+:1057800066936A4AC676FFC43C389FAA9DF750DCF0
+:105790005F35EBA078FAF903F87ED5189E3659E00C
+:1057A0009FCD71CE42B4279A9F95E85D58E5EF0AE8
+:1057B000FDEEE026EC720CBE9DACDAF11DE965470A
+:1057C000F8F9CFE801DC5FBC795CE83D18D3A13281
+:1057D0003FFA9A6EF97B11BD7375CFAA5F51BCB6C3
+:1057E000C3D41D3F1EED892D32E1FB3D0FBC40F9B6
+:1057F00052797107FECED0075B6C2EC4E393BBCC0D
+:10580000B4FE0F5EE4FAC5077B393CEE49B3D179AB
+:1058100043F8FAEBA4A0889FEAA0F3F03FEDBD3F68
+:105820001AF7EF4F5A1CBDBD96EEC132576D483C7A
+:105830007DDB1E03BD43F6A73D235FC5778C9BCB65
+:105840004B46A15CBF25369FDE29D3CAB53810254B
+:105850006EF4E34857B7FCDD407451F4F0B808F437
+:105860003F2B2017311ED9D55848F1B94BBC11B187
+:105870002E89D645FBD6B6C542EBAA699C44FB549B
+:10588000D55845FB30707A8A4CE54F4B0C7FC2925D
+:1058900019C645AC85F6350F939B89B531A5B82F50
+:1058A0003FFD5FD30DFC5DCFF2084F10EA7F28FC6F
+:1058B00037E333F87C2619C695A09DB96C8B4C71E3
+:1058C000C2CBB6BC9948EF62EC33D0BB5352F9E877
+:1058D00014F46387D39136BF707A3243BFD83E9CAD
+:1058E000AEDAFC1E7AE73E9CBEF02FA88B7338DD43
+:1058F0009847F30AA7BBBB1B33E9BD0E56CFF5B0E3
+:105900007F1AC07F1FF37BD05F9D9EFE585A794857
+:10591000DCBD466F5A5AE3EFDA79BBC5C3D4FD3616
+:10592000BADFAEE2FDFD27062854FEC4001EC7AD57
+:10593000FC75E581D761FE370EF06D1B80F1764C6A
+:10594000CDA57736BF64F8FC06C515F0F34C7E6F25
+:105950006A87D12B131E2ABE7F7D1DF28D8D5523A4
+:1059600091EE1F17FDBD97EEDB83FD2C58EDFBFC80
+:1059700038437C1B46F4BFE04A05FDBE10FE0E080E
+:10598000BFA7EB2DC4DF07353ABCF9888F1ADFCEED
+:1059900082F9B6F41147F09B015C8FCA7278A99F17
+:1059A0005F64F0FB82CDC8DBA19FDDAB78FC86A6EF
+:1059B000AF458B3D74BB18BD536619CDE1B1D269BB
+:1059C00070213DC23894EF1E2DFB27C3D7369ADFD6
+:1059D000EF8DCC0FD27BDB59980F78E4F6307A87C5
+:1059E000472B87FA17315F6616970DC668847F21AB
+:1059F0003E6465F3F7F3DCCD3C5FDBFF3F374944A2
+:105A00009F600BDBF1F76C2C4CC8CF7C2E3F573AD4
+:105A10004D2EFDFB2E0F258F3F81FBCD54759043FE
+:105A20007B3717FE6689F808E05A14E7383787F99C
+:105A3000F07EA4B69EB1CD2AC5BB85C36D8198E723
+:105A4000169C27A0CA580FA4B3FB9FDF7EC12FB5B9
+:105A5000F6DAFC4CCB6D0AD2F35ED44F60FF4D29D1
+:105A60004E1BD2911627E388802FE80BE929D954E1
+:105A70000FD647F16AA08178F0DCB1BFF81947046E
+:105A80007CA17EBACC14C44F93CC8AF0FED0FD0624
+:105A90002F293B5FCB4DC24F1F94503F4B35B4EC89
+:105AA0005A04FDA6CE4AF3A09EEDB3A85D042FE6EE
+:105AB000A2FBE397FAF95D039F65FC2788975A9C40
+:105AC0009D46B789EB59C8BD3B2DCE283CAE68B783
+:105AD000DC6421FD2C43E81316EE1FDA3196D9D190
+:105AE000BFB27E0CB73FB57DAB11FB261D9368BFDF
+:105AF00058585C9416371529E2CBB571EFCE518218
+:105B0000E63EC6C73FFDBCB5FA91BB3ADC38AFFEF6
+:105B1000DAED01FD0CE397D9468F0BEBF9DD3E3B47
+:105B2000C63DA5AE9FE712F2C48D702B65AE3DD287
+:105B300040F44BB8D2F05DC152CB6FCE61FFA516D9
+:105B4000D64EFAAC27DC1E0FD5E7970BBFA0C3C417
+:105B5000DF8BD0FC82CB855F502AB7905FB0C6CB7D
+:105B6000F5B809C7B8BCABA9E37E41ED3DAD9A23BA
+:105B7000E3938D90BFDC6B92500EBA849FEFF037A9
+:105B800013E8BEA6761FB1E73E6F6EE7CF7F8A723D
+:105B90006D31BF9FF9A9E8A7796D6132124FBFF748
+:105BA0007C37C82DAD6EDD3DDF0D72ABF0DB89FBC0
+:105BB0006CF608FA1D24B19F1902EE2DE29E658B4A
+:105BC000F0D349ABF9BDA116E65A4BEFFDAD66FC2B
+:105BD0007D951C3E4E5C9DDC8AE7BE013CE08EC19B
+:105BE0007A8CFB056D161197618F28E7BF9B44F7F0
+:105BF000EF12477318B7687E3F812742E4B0E6583A
+:105C00003519FD7451395EB7CDC3D81B7B3FF95DA3
+:105C1000C4A8EFF30EC4E6A6EF7E07E29C17DF816F
+:105C2000B060EC9A28477504E449CFEFDC60FCFBD8
+:105C3000A6A8DE7205F4304B9D48FBF77A278288D0
+:105C4000C1B3155E7EF8618C5F7BD8CA42C6D3CFE4
+:105C50004F09EBDFE8A2383091EEBA15FBDB9EA7C7
+:105C6000A5273E8CBF93F3B031B43F4279D11E13C8
+:105C7000DA787BDCF735358EEB956B20E76A11FF20
+:105C80005DDDF642FAF91121FF22EDD3F97BCC5705
+:105C90002A88FF1B1DDC5EC7580D7CFAB1263BB37A
+:105CA00095CEBD146E774724F3DF73FA4906B75FCC
+:105CB0005698B83C528E95A9F8E48191795A5F774D
+:105CC000933CFCA70CDC9F8CD297517FD1E421E858
+:105CD000FD1B6F837E1BB633F22F5B9A453CBCD80D
+:105CE0006F734F3C849FC954CF3B0AC77B3BC3575C
+:105CF0009FA1E3CF59CD2E13F6D726F85EF3E24CE1
+:105D000059D2C9CFBD19FCBC3F2B9BCBAFACE640F1
+:105D10007D26F4A7C45690DCD5EA65DA07C9F43BC2
+:105D20003569420E829C453D38B3D947A118998AFE
+:105D30006F36AE3BB3729109F5F5BD195C3FCBAF41
+:105D40000F5851DF655532FFBD890C178D67B42F91
+:105D500020BDD05869B121F2EEF63E6EC5FEB3B259
+:105D60005B697C6657E8DD38A6801E00F57E1EA7BD
+:105D70008CD2BF2FB3D9AED0EF8616187C2B28EE6D
+:105D8000247EAC8AF4921E5752EC8946397030F763
+:105D90005E1BDE3BEFFB3DDDAF5D7C5FEA24AFFFCA
+:105DA00036A4B75C906DACB73C43BC17722883FF38
+:105DB0001E86CB6F27BB60DC975ED28F0F65F0B875
+:105DC000C45F2B9D91A8FF653175C5DDB84EAFCD81
+:105DD000857E7AC6F87980638D8BEE87591C9D0F7E
+:105DE000DE88E51ED983EF786AFAF4A72F24517C68
+:105DF000D46097EF38E24181A1731BEE3B7B90FFAB
+:105E00009EC8A72F98894F387E9A43F13D0D8ECEBC
+:105E10006DE863DC6BE476B5C511B40C44385E9173
+:105E2000E9BDE248D8267C6FCA66E3EF60E5039DD2
+:105E3000D27D12A744F143364FF719ECBFC475C6A3
+:105E400083EB9820DEED0AD72748E869E7560CD7A0
+:105E5000E7671F58C8D554F76D7CAF9E3191A914E0
+:105E6000BFAFE91F3BF0FA2B34DD215BE87E7B7E80
+:105E7000078743C9EAE3345E94A79DEED52D40FF22
+:105E800028A433B3CBE95ECBC2264E4F770B3C64DC
+:105E90008A2705ED988B1991E21E531D7D49BEE1BD
+:105EA0007A1A4D746E9259EF36E9DF7FD3DE1DBA50
+:105EB000BB89BFD36412F70E33F345DC287B90CA4D
+:105EC0003F1674A9D9EDBDEFD8F0717BDEC3CAE5EA
+:105ED000FC7AEEA0727A7F2A2E7F581ECEDBA93084
+:105EE0000BC615C9028FC2DFC3D2E6935FDC948C68
+:105EF000BF27DFFB1E169703FDBF87D53D3113CBB0
+:105F0000A7B8E877E2CC2E0ED7FF06528A8D6A003A
+:105F1000800000001F8B080000000000000BDD7DEA
+:105F20000B7C54D5B5F73EF34E3209930079F04817
+:105F30006612120224611201411E0E096054A4C3AC
+:105F40004B40294E2040200F106A1B7BB19998F0DE
+:105F500050B1C68A885E2A135E6A051B10292AD8AA
+:105F60000144697D45ABBD609526E8451190085513
+:105F7000B1D75BBFF55FFB9CCC390328FDEEBDBFFD
+:105F8000FBFDBE58DDDDCFB3F7DA6BADBD5E7B4FF9
+:105F90009A53882E4542A4DE1DF42CC91322C52134
+:105FA000447C12951DF0DF7E6890101DF9B1DE8DE6
+:105FB0006E2E5F158376A25E41BB15DD95E92D48F7
+:105FC000CBC4F49D945AE87F5D92647A8452C522D2
+:105FD0001AAD94A6588425569637E23B0F2788DBE6
+:105FE000FCD4BEBBC97CDB444A1F2E92F924AFF01F
+:105FF0006DA4B9A4BA13A992FAD945A99224CB43A6
+:10600000544FD3F2EDA0FA9492C5853CCF2C99DE83
+:106010009B16B6882C211E13A1755B68BEC15C9BC4
+:106020006B8B10627CEE2B4794024A1DA2C59C40EC
+:10603000055EEBE9B65CC17FDF650AB13B79B2C7AB
+:106040004DDFF97CC685633554F670FDC41973D1F4
+:106050003FDFE9DD42EB15C11DDEC9F168DD2BF143
+:10606000C40021CCE877AD10E74EC79A942E421CAD
+:106070003E9CD5A58DE6B3114DD2A85CB8BBB868DF
+:106080003EC3CD2621BA11DC0A2DA18D8A100B1C2E
+:10609000373EFA71576A6359FCD7BB687CE71B5DD2
+:1060A000BDF7D2F8C333846C9768E37604A0A009E7
+:1060B000F53BFA85EEF5601C25CCF5CFD9B9FEA4E9
+:1060C000D5EF5330BF1DD9DE2DBC8AB06B623ECDFB
+:1060D000BFCEFFE8986CEA67153E41F5625F7C68C9
+:1060E0000BB577369B82D934CF6E36F99DB3FB6200
+:1060F0004277A35C91DF11CFC785B6D0773E17B248
+:106100005FD06BD9B885E7E14B9D4CE37E873F5A62
+:106110006FA322789F9D4A781E8FBF23C684765A2C
+:106120007D0F3B95D3F8E2592AF744CA5FB4CAF20F
+:10613000E08E18455FBEDB16DECADFDB29CBDFB79A
+:106140000726631FB4FAAA84704EA2F3FBE02882EC
+:106150002877DEDF3B74AFA283E33D0AB7532639CD
+:106160007CC89F28B46CB42B0CC7DBFC34DE47B969
+:10617000A6B0AD0070247C7546E0A77D97E0E7C728
+:106180003AE7ACFBE43F4541047E73FCB67673010D
+:10619000C3CDDF827E96B06B527CA4DF9CA2F2F16D
+:1061A0002221928F4EE7547C3B0BE3CD5965672447
+:1061B00066FCA37F1703C7060BF155CC681B90EB59
+:1061C000A7BF9A68031ECF138B39AD104D9CD29F89
+:1061D000C3948AC4E7300D1562A168E172F72A4BB7
+:1061E0003095E0E83E121772D33ADD41E116570BC5
+:1061F000E1118427B47E4F2F93378C6E8A4911D4D6
+:10620000CFDD48F52934FD7B8812A95FF32A25A448
+:1062100050BF958D26CE07572BA16CDA8F60A3C98E
+:106220008771E87BA97E5A6793DBCCF4F8A4DBC6C0
+:10623000F3A56987301F2DD5C66FB40A8673BD30AC
+:1062400085913729325DE9B294869C17C3451BAF0F
+:10625000D1BAD8311AFBD7DBE4029F69B4061661C4
+:10626000FF1A8FC69982349FC6F8C5AB4A653DD3E5
+:10627000DA5731E152D47F5568124145C2338DE679
+:106280009F7934A619F8B0C26DE2F946C37B6E93CC
+:10629000313F7F9D31BF2064CCCF1181DFA6D2D2A8
+:1062A0002B9F3496AF70BBE4F8C2CDFBD06875BFAE
+:1062B000E3019F24B862FEF5BD24FC4CBD659A99AC
+:1062C00038663AD34DA24D64D3FC565B24BEAE5E15
+:1062D000D5AD19F36F4C24FA72FED7E71B3DCF16EC
+:1062E000770ECF93C6E7EF35127DA8F0627A9FB3A1
+:1062F000CDBE097C664EBC3B01EB38A574E49A81A7
+:1063000007F7C7BB990F085A67B210B35D72CC8FFD
+:1063100014EFD630B5373DB0FD9E1CF4BFCF5C44C2
+:106320005F1425939D4C6F2F7CE60C81DE2A086656
+:1063300069C4B75FF0BEFB0AEAA3D7457F6ECB10F6
+:106340001A17FF8FB66A7637E18B21FA10FA769921
+:10635000F82FE187C6AF69CCF2EEFE23E0132F14CD
+:106360000BC6D7171EB3871AE87B0F9B3EDAF12ABC
+:10637000E0BF2386CFA99A651D5B05F51FD63DF0CA
+:1063800057B43F7DE7FBE31437F30DEE77765FCA32
+:1063900046E0C9A0467B647CFC67B52E8FEFAFA2B8
+:1063A000450CA3748DB1BC627D543FF10FBB7E9E42
+:1063B00044318CD76B6D817E2EDAD7C7FC43866063
+:1063C0003E6BAD4DA5A0F3B6D4C01798D7C763FDFB
+:1063D000AF983CBC1D397EE2432F7D3B27CB027E2C
+:1063E00079C4E1055F7CC9D2169748FCE850869BCA
+:1063F000C74B758820CE5194635CDBDD92DEA2E949
+:10640000EA5B30036AEFF4F89ECEA0EF886F69561E
+:10641000046F33604B43399C3B7D66F0EBBD8A8B48
+:106420008E0D51E316EDF3897F39F72ABE4C82CFEA
+:10643000A25C5348A1EFD7384DED575379B6D3241A
+:10644000CF955C0BF3879A3522389FF6CBB2B72CE9
+:1064500088D953BBE0D594BFDDE6667CD3E651B363
+:1064600067A208D0FCE2BAF94D73E97BD60A13C3E0
+:10647000682D9D63186F2DB5057D0FA2FD0F313F6F
+:106480000EF1BC936DFEE218AA4F4E0E7B83D837F7
+:10649000E137810F257B7C851EEAF3EF28A2F37696
+:1064A00058AA2F15F92F711E0FA4F3F8DDC97C1E11
+:1064B0007F29FC7C0E9F30077EEA22BC9E2F82CC77
+:1064C0005F178810A7624D57DED7791611B6103CBA
+:1064D000E74DF11D859C00FA0A47D1973E5F255A8A
+:1064E000253F263A0BEBF0A1CA12DEAF109CAA1D85
+:1064F000221C87B4C5D8AF467470BF457BBEB38736
+:106500000D7420F124C5BCA47031D6EFF3F5E94633
+:10651000FBE4944DC4B41E129E8A5784E3697EB78F
+:10652000E5898023F3CADB9D7437259BCC7C1E3222
+:10653000DEAFDAA784EC04EF7166A7CF41F9EAFB7E
+:106540004D4CAF34E0F8C14370DE48FC58E41E7790
+:1065500012E799263738769B43777BB8BD374CF9DD
+:10656000EA7DF15E34AD70578CC7B9B620643DDE6C
+:10657000A65BD742B1639C8BE1E5EF027E51F9A4A3
+:10658000B1BEBAC5985F242CC73BE5326A5FFBC138
+:10659000E8F0CB3AFABAD913DF0DF217CDCDF31DDF
+:1065A000E06F9ED9257009BCD7D2AFEB7CE197ADE7
+:1065B00042A42BBE991E82EF428BF0E15C8F6EF7F6
+:1065C000666F4927079DE7BB0674F5C5797490523D
+:1065D0007E48F1A5E96BA1476178C7B5AA72A925E4
+:1065E000281275FD2FD76FA9C724BF6793F50FC475
+:1065F000C7F900BF549B58E5288AB44B3589460734
+:10660000E1E5D10CFF1DC06F87DB6DC3FC365983FC
+:10661000C204FED05DB0FCF76BAB08C650BB9E66F3
+:1066200013EF674FB36323F86155865CD70FE149D9
+:106630005C5E871570EC69DEC1F847C76B50D07897
+:1066400036139D0F18374E08C8FBEB634410F3A1B7
+:106650007AA1C87A218AD04F849522A92FC451F9F2
+:10666000033867585F70B21C9646E5E05742B4B6EF
+:10667000416EBD6F88C30DBE9B6292F3BEDCFE917E
+:10668000BE10744ABD81F510125982F1DFD35EE36A
+:106690001B297639AF94B8C5CD8053CA6DB9450D65
+:1066A000844F9B3CFEC70147024801F88806971AB1
+:1066B00015DF3BE1B24709C72744E8278EE66C01A6
+:1066C000DF6BB233DF6394E57C1ACBD7C790273EEC
+:1066D000B237D5FF34F04C68E7EA03F92C8788DA43
+:1066E000AECCA756C64BFD86E068D8678DFED72B8B
+:1066F00072BF8714B7F239DA7117E9143AF93A43DD
+:10670000C5B33D2ADE69E5DD3D729FBFF1F89EC746
+:10671000F74F1F753804C9AB830649BAADF13B99F1
+:106720008FD38963FB172ACBD8A3B8EE053FCA35B0
+:10673000F17803D30307019795EF3B8366EA776F00
+:10674000EEF1153DC1A7BB7987804D66A19CF8EAA3
+:1067500047BD03AF62FCF265812FF6837D4EEA5F91
+:10676000007C1CF25DC98A52395F17E4B26E76B1C3
+:10677000584F679F78A41CA6A51FABF33F4DDC7153
+:1067800034CD2BA39B6F06F042D0B9904D5B10E740
+:106790006E65FDA666971452781238A7FEA517C33A
+:1067A000BB66D7E8C243C8B7C414A2FD90BF38196E
+:1067B000DEA7EFEC1132537D8E3BF001D6133FA8DC
+:1067C00043C1FC4EEFB8BE1069341D68F89F427497
+:1067D00083F1536E75B01CA1E1C15A2BED7F568435
+:1067E0003EDEF4B819CE19EA3995B1CC2FE63A233A
+:1067F000796737B93F546EC2F79C9EB16F025E6FE6
+:106800007A2CDC6F49AAD90DBDC52D5C770BCFC59D
+:10681000F8EB210A7712BFBB8F84A1EFB0F420E51B
+:106820007572D0B926A514705D4202596D51643E4F
+:106830005AFF25A9361E3FEE8294EB335D36DEF714
+:10684000F8552ABE2E138CBF233A5A4BBAD07AFB86
+:10685000AC098F30D31031F8561AE3C77D03A9BCB9
+:106860005B57CB08E8A58FD7161D7074839ED03A6E
+:10687000125BE059234C31945AFED3E2C73AF98FA8
+:10688000EACBD7B8249E5B16E7421FCACA94F838F1
+:1068900030DD179749702C7ECFCADFFFEA7E2917BB
+:1068A0007E9538FAE47EC8EDF7DB89D15C9E9E8345
+:1068B000E280037A43E6EA4C9BC8C33A1486AFE809
+:1068C000438841F3B5DCFF4150CEEFDDDE98CAC806
+:1068D0004C27EFDBECA0771CC086FEAC9F34B98A56
+:1068E00031EFF8D5934CEAE6A729549EBD6A8AC9D0
+:1068F0004DF9EC26396EF4F707A9EBF8FDB7E6522F
+:10690000C8E5261AB40FCEBDDCA46633E889CE13E1
+:10691000ACBF7A40375E7F7EA6C46FCB1ABF487388
+:106920005F2C0755EF2A6339289AEF68FC46C3BBF2
+:10693000DFD3B858D7EF8583E5740DFF48AF627891
+:1069400007FFD3C47440EA2E9F67590F7C9BC6F89B
+:106950002DEE96FC5EE58316AB7B05F4424B7DDBAA
+:1069600028C079CEEA44534D1EC6F12EE171EE7770
+:106970000A1E6775E6815CF085552EA1B831DEFCF4
+:106980000CA6C7BFD805F0C572BFD38473C5F2A0EB
+:106990000FA5C292985CCCF987294FEDBB645AF9D8
+:1069A0007BD64C39FF46A54361F94AF80A21CF7ED0
+:1069B000E309F833074B3ECA745C1B1BCA667C694B
+:1069C00065BA7D7C486B6FC0EF719BA8C07A8A1F47
+:1069D000C89BC4F8728F45819C126F096424523E93
+:1069E000FE480ACB893355385F025F7A0ADAD7CC82
+:1069F0007D663FE8D16295786FB987F42BEAD73F7F
+:106A000039701BE63122D85A02FC1875CFC771A322
+:106A1000DD577E0E085F90DB2DD2F8C75E85F9C783
+:106A2000B7E982D7FF754C4201F86EB7584A895FC3
+:106A3000D63A64FE67B1091B91BE7E46DA8BBE8EE4
+:106A4000490FB15C154B29F50FAA7A4CF0583CF36D
+:106A50009F3B32255D7F6DEAA8B7507EB149E203C6
+:106A60002120DB69028E402DE8AAB6AD301578F101
+:106A700062427231E44E9A7C3ACEB5E356A947465B
+:106A8000C327E0187D17FABDAEEA99988F87E6997B
+:106A9000545BE207DFE8660B3D3A0F7C7CAA93F576
+:106AA000A7A43B4773B932A996ED553D5EB77A5915
+:106AB000CFAB104C773DFC3696235F54D4F9EF33BF
+:106AC000335EF628F5A559299FE4B7290EAA37A702
+:106AD0004E7EB49CC659D32CF77F4D993B84FDD88C
+:106AE000FD0FB3B4D7CC152C27AC29743F5A8EFABE
+:106AF00005792CEFFF4A51F1BD5AF0BAD7C49B0477
+:106B0000EC196B6E2704477B8FFCEE9A1FCBF18646
+:106B10009B8F0BE84D1DC3E439A4B313497D6F7AF5
+:106B2000B2B4A76976A2198ED04649C76C473A3BE2
+:106B3000BDBF666F93F5D926D5DEA6AEEF8E4C9E0F
+:106B400087C6F7CE56F4E0F682F8AB83F4E362B57D
+:106B5000EAACAAD7072B249D9E0D49FB51719BD20D
+:106B60008E7D3A2B5AC2B0BB054B85B42F0E957C57
+:106B7000A461AF79238FE718EBD3DB27CF0A512A23
+:106B8000ED4D1D097A7B93569EDCE04B03BD764CA0
+:106B9000B499F4F2829696674A797349B26F5FE6C8
+:106BA000E0081E6BF8FE62514A31F49ECBE1FD9F76
+:106BB000843C1FBECAF4BF82FE25375FDFC8931B2B
+:106BC0002FF5A783AA5DD06693728FEDE69E1B1BFF
+:106BD0003C7AF946F2A517D576037A0A07EC024407
+:106BE000AB41EC67FFDDFD997FBEABD235480BF6BC
+:106BF00086FEEAD9D75F69599248E7F081E39E742F
+:106C0000D80934FC7E31B627E3BD0EBF8FF2FAA25D
+:106C1000E6252CFEFC49F917CFE7E34CDF5FF5EDE5
+:106C20002F2F5706795E365BCBED2CD756137DD0D0
+:106C3000FADE4515F5DB74B33D0CBBF259AB7315A9
+:106C4000E8FB48DCAC57BA13285D8EC0198C3F7D39
+:106C5000DAF52B90570E74752FA1799F2D6B1B02BF
+:106C60003D70BD3DF005EAAB1C818C645AD74FCF17
+:106C7000B51E53C037FD5DD5F3D89FEFCFBFFC7C69
+:106C80004A14F9FD3C5BE0EFA0EB834A5BBC177A4A
+:106C900091A58DFB0967771EE7980AAFFD56DF883F
+:106CA0002F68FEFB1FCC286CA0F994241CBD751125
+:106CB000CEEF47520A2107687039A8AE6BAEC99F64
+:106CC0001C361BE66BCFA221AB5C651969993CDFD2
+:106CD00059CCE79DEA7C2DDE5EDF37DF068D9EEF27
+:106CE00052988ED6C712AA1745E829F081A919F83B
+:106CF0006F37353433FD9539BCC0E7B7D4F9909E72
+:106D000023201F533F969FB7086F7FF0809E7649E0
+:106D10009F3D572A21E0DD6CE1653DBB5CF8D32146
+:106D200042F6C90A6460DE7F8DFBC7608F343D0C7C
+:106D30007E97C6DF7D778A1772B01821E7FF43FB85
+:106D40002FC46A13EC2793543BD85C556E9A2C7C65
+:106D5000567C6FAA0858018F773EB7F9C0DFDF5124
+:106D6000F5A36922C8E5334488D35B4598DBFF5817
+:106D7000B471FEEDB882DEB504FF898FF4CD067ED6
+:106D8000EBE03D384BE2C76DDD801FBF785BE2C7AB
+:106D90009AEE5784AF1355FC20BA1D89714A924A66
+:106DA0001A21778A31122F22F4D1D6D085E03731DB
+:106DB000D95308785CFBADDC8F711FBB9ACD4A04B8
+:106DC0002F887138D368FDD7A95BD67A4E9E73871A
+:106DD0007DF5DDBAD1BCC69A9DBC0FAD5E339F0B6D
+:106DE000AF8EAE647BF8ABF5727F5E1DA6F0F9B690
+:106DF000F50B3A0FA9DF0DA90F8E81AA28CCCEF88A
+:106E0000207DEF4B9F59E07BA5BDAC113B00FD7B86
+:106E1000431F637EC23A699718EF33B7DBF9DC6B27
+:106E2000B100EFC6E719ED0913C4EA2F60AF9F1058
+:106E30006557D88F35255D6C5F989DA5DA17FA8B5D
+:106E4000FE6CBFBB72FB424596CEBE2060CD24FED9
+:106E5000F523089DB4AFAD230E0E3F4BEB3FBFD7DC
+:106E6000C3D89EDF57EA3FFF9AE55F8C7E35B6B602
+:106E700059D8EFE37504E1BEC497EA1CC247387DD8
+:106E8000A2CEC5F94FEB5239FDACCECDE9E9BA5CE3
+:106E9000AEFFBCCECBF9C359BE5A8CB33246EE8797
+:106EA000F6FDA52A9EAE8C9172C6D2983B8E94D1E7
+:106EB0003C96F6964450D1D2348E547BB1704FCB71
+:106EC0002B48A9DC4C3A8C58FA20694634EFB92F8C
+:106ED0000756E0D899FF7ADB04B093C1EF7D9C0C94
+:106EE00078545F50448048E6448E6F25BEFB49DDF0
+:106EF000509ECFC93A1FCFE7545D29A71F65F957A8
+:106F0000F3FA56292FF7A4F16EDAD66E413AD6A7D6
+:106F1000F07937CA274221DA8F75D64000F8B12EB2
+:106F2000CDE105FD8ECE9FF4EB9F08F0E7C05AD06F
+:106F3000EDD4A43963BBC25E25DA1ABB52BB6B67C2
+:106F40002ADEB03B82C73F4CB7121ED52A6E9C7911
+:106F50004961389D792991E1F2A75D669ECFB923F9
+:106F6000B12C579CDB15C7F87F6E953D047A79D11B
+:106F700016B4A753FEC5F4582FF8E68BE93DF8BCCC
+:106F8000B4ABF4758AF64DD0FA273F979502FDE22F
+:106F9000D4F69FA5EAED48A7925ABE7A1FFCEC43AF
+:106FA00093977D84A2E5C46394FF5DAF54E63F9F51
+:106FB000ABFCB9C626E9441C336D047F3C152BE9B4
+:106FC000B0E368EC46F0C1E39AFC7F34B61972C5B1
+:106FD00090677A160BE3F9F73CE015BDBE25CF0D9F
+:106FE0004881FE247A756378E52A1653ADCEFE807B
+:106FF000F9BBFB46F2FD76CE3FFE73B7CE7FB7F30B
+:10700000C73E9CB35BB73F7AEE05C05DD52F9E7A35
+:10701000E6D73DFE9572553B96C762BD9003871239
+:107020005DBDF8601CF3BF17ADDE63B598EFAF9D93
+:107030006CA77AE297771EDF83F4FEEAA23B29FD74
+:107040004B5612EF4FF9AF668C4BA3765B778B42B2
+:1070500090DD009A634F9A5FDEBA2F0E408F2A08A8
+:107060002596F4A072EF93850721A23CFD3B250CE9
+:107070003F41514BF34605A8FCEDA61E907BDBB3C8
+:10708000DC067D7840EFD2C3ECEF8D9227F2D67C00
+:10709000518CF1B6F7907205C9179FD513BC57F6FE
+:1070A000FE7311EB67AA3D66F0BEA9AF0D175857E6
+:1070B000300DF26EB0CCC6F6782CDF4AF933BBB295
+:1070C000586ED96D0AF279159CEDF0625FCEF883A7
+:1070D0008F621FABA93DF4B7EAC260C235D0133F3F
+:1070E000ECE3258C14BD1FBFAE14F0A9D9F5F0B8A0
+:1070F0001ED4EECC08E15568EA15CF9D1FC7FB4FA3
+:10710000DA2CF4A333BB1A926FA17EF7E5150FC6F4
+:10711000F9EC37B7F077C422F99D47D4F350B41592
+:10712000B07F8651DD0DFB8170A03C696FE2FE9E51
+:1071300022B25F8BF6D67B201F0F0A38BCD05FD7F8
+:10714000798269B0F769E72B9D93E63E20299B3A47
+:10715000AE6B32EB13577A3E6AF6406DBC476CD289
+:10716000BEA7D90BD7DBE479BF85F812F04F3BCF30
+:10717000E9BB5DFB0C8ED81B85EBD94217CDF3DF45
+:1071800049CE62BBC2157E5F93BF16A9FA57B17A8A
+:107190003E4FEFDAB0AF8DD63B94E42CAC6FAEF03F
+:1071A00049FBBDC5EBC6B991E1F0B9FBF039DB9104
+:1071B0008E35D0B9DB07ED6ACC249765E9E432C798
+:1071C000959DBB0DAA1E18CD871B54BD6FE9974531
+:1071D0004702E0B3A4CF60BFC4CBA6AA57E85C1DAA
+:1071E000297B74C27D697C11D36D8310975CFF4B42
+:1071F00044B701E23B613A2F027DD1A8B501761D6B
+:107200001FFD2F9EC61D75C1443C417E1BE75B746C
+:107210007F827B31D6395AC419DAF94422DB998549
+:1072200033E98AD63B22F6D2E7CE0855BF1D716EF0
+:10723000E8BFB909AFF7BD6EE5725A3FF3C9CBADF0
+:107240006B9FBAAE9CBE81A97D747AFEC8BFB92C73
+:10725000A04F9AF70C948FB2984540EF7FD3F0F58A
+:107260000AE77D07E21F404F5FD8584FDBABEA7952
+:107270007B17E4B1DD65B74DC66904DFB432FFDAD0
+:107280001B2FF5DEBD139359DF7C51E3C76566966E
+:1072900067F7C6A8FDBBBBB8BE875DD68B5B3BC797
+:1072A000E77366EF8C1E3CFE8B4A78C06F31FE445C
+:1072B00007EB816B26FAD262A1DF4E4C36F1F7FF65
+:1072C000610EB2BE516F673DB5538F2E5CFC5A3EC6
+:1072D000DAD50F607ED2C31C5A057F9DA833F338E0
+:1072E0007B07FB8EBA799E44806EE8B3C569269D04
+:1072F0007EA8E9C5A407B3BED651666E4639E9BD7E
+:107300005A7EA3AAF7AAF111C1F88904D7A3EA7E8D
+:107310001DB148BDF308F4DA8111FFC311E8A32CB5
+:107320004F06E3A16F0526C4594007D1E5DA3E6850
+:10733000E5EF5B497F051C697EFA789235894DDD62
+:10734000E1BFDBD027B016F43963EE9618C99F432E
+:1073500031D0836F37FBD7010F1E8BF54EB8197CE8
+:10736000B95CEA71EFAB700E7E63E27D79A9FCD067
+:107370001CACEBA58E54A1B7BB6A78D0195F72978D
+:1073800089E11C1DA7B3E1F5AE7C4E77DA0DE26D05
+:107390009D7603C075434B3F197F42F0C33A22717B
+:1073A0003AEA3CF6E5F3FE97C2FF06B96299A919DD
+:1073B000B243588DD7D9A0DA11832D569EEF06150A
+:1073C000AEB7A9FC6B8308F7849E16DC1B23E37D14
+:1073D000547BC6863D03F8BB61E1EEC2F689C36605
+:1073E000C1E793C59B8A78A5B32A1F6A50A47C4144
+:1073F000E3C8389C96FFF6B89D3FF6D19DBB17C5F4
+:10740000ED5C0457C1769C0DB55D3BED316CBFB8AA
+:107410003D5E83AB5C5F9547856BF33D3918679F95
+:1074200095ED5227AD1D6F5C8DEF3F9F25ED27C475
+:107430002AD661BC3DBD399E4AB3BF115C0BF6A094
+:10744000DD2E3BC34D83AB6677DBA0E25F679CD04C
+:107450005DA68DD05B02361140F931575BBCDE9FD3
+:1074600077CC7F221E7CEB835A73D8F63D713E3376
+:10747000D5B8A1996ABCD065DBFD6236FB4D2F5BA8
+:10748000AFC60BCDAC32C64DF4C8F67DD5478FB72D
+:10749000274DD171510CDF179C491A7C255D9F74D3
+:1074A0001AEC5D2F7CDA5F85EF8EB089F15651E1E1
+:1074B0002BE11F7CB46F48C67F84E2F4F1512F5852
+:1074C00024DC5E50ED5A9DE5AA3D2AA0DA81C4670E
+:1074D000268E236B70791D7A3896770FB8B2095FC4
+:1074E000EE761639DAA8BCA24BF161C89735163A88
+:1074F000BF697F866407BA67439851E51ACDDE5AA3
+:107500009D179EC5E7E3B22B3B872B63F7D62899DF
+:10751000348DBD5B7623A579319E899D925F074CA2
+:10752000E10435AF609E95F47F4725C16F4D6756E6
+:1075300092CC439E8D8EA761124C96F590232A5BC8
+:10754000CCBE9804E46D91761EE4432C67905EE80F
+:10755000184AF24E65E29E5F0EA7F2854EA76319A8
+:10756000FB438D712D0B77AD6CCD2AB8B8FCE2EFE3
+:10757000CBF509A7CF0D7B44D95059774D6D89F8CC
+:10758000E82A82936A7F9CBD5AE17388FEEA11E77C
+:1075900051BE4611E06365C1693700AFCAA6949E2B
+:1075A000841E53F640FD0AC847F3557BF6FC3DFBAD
+:1075B000BFC17E687112652D4F7C09B96576549CF8
+:1075C0004CF9EAA879FD407CCCC2CDDFD98DF132EF
+:1075D00052CEBE666FB3197435579DBF46BF223871
+:1075E0004A607DD7A830FF18FF1986788FC074E0F5
+:1075F0008F46C7D7AC91FDAB858CF3D0E22FE6D98F
+:10760000E9BC26B81F8EB7313CCEAFEBC27689F30A
+:1076100042C2E7FC7A099FEAAE325FBD49DA27AA87
+:1076200055FB6FF513D29E34CF22E3621117E2D3DC
+:10763000CDBF4A850FE243F4E5A249CAAB5A3C08E4
+:10764000E2447C3A3F5E15AD0B71B1880FD1F7D3A0
+:10765000C787E8CB75762FD55E1662B86DB0869E6B
+:10766000DA4AF334FF22568B8F89853CBBF4C3EB97
+:107670001E85DDB6D32EBFC0CA747C09F942F28FD5
+:107680000763982F583BE50B5F8E8BFAAD79B09F5F
+:1076900097E518339DEF381F2A63E538DD4DCC2F71
+:1076A000D7CCB0A9767869CF5EF3B087E511F02525
+:1076B000E6E70FDA2FE24B98CF2D9DF19ABE1C071B
+:1076C000B78BF1EAF9FE2DDDDDDA79CAF111113956
+:1076D00024D41D7CE87DFC5F82EF2D6A9CE62D6A38
+:1076E0007CA62687DCD2199F19EA0E3941835B7488
+:1076F000B9C62FB4F23589BEB4A43C8ECBDA9CADAA
+:10770000933BD72486621067252AAECC4EBC455DDC
+:107710008706D78F1519DF551EEBBFF75AD0E1DA70
+:10772000CC4CE0D52E287983E1EF97F0D6E0A0EDA0
+:107730007739ED21F4B5F25FF565BCD4E2498E15D9
+:107740004ABB5DDC20E96FDEA78EB32FDB644853B4
+:107750006365BCC6C763A5BD317E90DF06F989CEDF
+:107760004C8E4328B7F9FF3852371FFAAE03707AB0
+:10777000355BDAA734B8959B141FE21FCA7F656793
+:107780007AA079307F1FB244E138938F553BA2B67F
+:107790002F4290DC44E3DEF256F7A27B192FEB3543
+:1077A000FB7FD0C1F2AE4DFA732E878F84AFC09BA2
+:1077B000C44E7C94DF5B332387E5E61E66095FF1E8
+:1077C00040BC1C676C711AF424D882FF8E76633536
+:1077D0007F9089E17591BCBBC0DABCD1A3937717C8
+:1077E0005837221F8D679DF8118567D17873397CD2
+:1077F000BA023CFBE2FBF08CFA0FF6C75F1ECFAA81
+:107800007FB77D7790E6B9F0B70F27086A77D2D2B5
+:1078100094ECA571ABB62C4FF051FAA9259880F1E4
+:107820004E86CCA597F26F7B73944EBBAEA2F30746
+:107830007D6A093DF302C165C151BB17A6DB454F07
+:10784000DAC376B6572C607985F2ED32BF92EDAB94
+:107850008BF644C57D3DF170B29BE3E5833D65BC8D
+:107860007298FDB2359BAD1C3756F3AED90BB458A8
+:10787000243A56607ED1FD318F0B84B78B5ACC658C
+:10788000B62E17D7D38ED9C0E716EDBAEF0BD8773F
+:1078900016EDBAFE139C4FD1F16315AA7D2EDACEF8
+:1078A0009B91A3DA79AF1657E37C25F878C3C04BD8
+:1078B0009A57B6DC7EC6E386A79E78E6059AEFC99E
+:1078C000F7530AA1CA9DDEFC5A829217B1FB6A7671
+:1078D000F1D32D595D029780AF967EAEDA0723FB78
+:1078E00027F9B77B8FC2414D62AF4CABACE184E16D
+:1078F000F4BDAA662BF3D1AAED9BB63E063CA77D4C
+:10790000409C4BE5F6437FBE86F2953BACDDC6CB93
+:10791000E53895E4C8BE2D724BBB8AB64F0B9F3D30
+:107920006473E7CB72C81BDA7E55EED86F13F91774
+:10793000C3B5A465BFADCD79897D6B691FC7768856
+:10794000A7BEB6813E4FBEA48814CFC5FD2BB6BCE2
+:107950009680763FB47FA737C731FD9EDEAB707C43
+:10796000CA0FEDE377D814C6F7789148DFAF78DF18
+:107970001E1A8FFDFDE552C6FB4F2C8B25DEFF7ACC
+:1079800079B28FE65F610D26BB3895E5158FDFA1D3
+:10799000E2A32FCDC4B252300DEB9ABB7E2AAFAB1F
+:1079A000E2D773785DE251450CA6ADF892E4DB1D99
+:1079B00097D8CF2772245FFC64236D26ADEB133577
+:1079C0002E32F88E5995936F6779E50E75AD1CA927
+:1079D00043F92FD578DB65399DFE4D875EAE5DB4EA
+:1079E00079652BF6E5B3DEBE14E8BBB4FEA00A2F22
+:1079F000057140E6B7C7A6C87D91F1D2DC8FCE866F
+:107A00001294A37DAB95E3A675FD186EDAF77FA2FD
+:107A10007E9FE61D0BF9FA93641967417FAD984785
+:107A20008D22FBD42CAB18EF26F8FF595D6727DDBC
+:107A30006FBE47D2B94AF77F7B57F2939AD0C452B0
+:107A4000E607ADD6700ADA85F64F51981F44C7BDD8
+:107A5000AAF8B0D9AAE283B19EE66551F4F07C4958
+:107A6000FA0717A9FE9B796B7471B680D7B25215CD
+:107A70004F6C91724F841E35BFCD7C95FEA3F731BC
+:107A80009A1F3447F103ADBF587F69FF4284FE83DC
+:107A90000CA72A923B60AFAC3A6AE7F3A9EA4133FC
+:107AA000C7477DB4FA60F230C2F3532D1ABD1AF9FC
+:107AB0006C27BD2E93F1B3153BB728C0D3687A3D30
+:107AC0005511522E49AF547E497AAD10FFBD7C56F8
+:107AD000DD8708DC8DF439FF327CF675C0352E0267
+:107AE000D72F455E17D8D385AB2C83ED7451F0D5D5
+:107AF000E01ACD2FE7E6B82FC92F055CF03A786A77
+:107B000070D4F095343CFE4E271E6BF8AA9D5F9D05
+:107B1000F81ABD6E233CA3EB1FC8113C1FFFF332C4
+:107B2000AEAD8AF8988C9F0EBED27310D3A78FD9B2
+:107B30008D687A057194917C282ADF12D5DE17951D
+:107B4000F747B50F44E5171BDA57ED396893F16D28
+:107B500061433B7BED8DAC575D2C4784A45F60D7C0
+:107B600017B620F0A35707C7D9159BBD870B695FD0
+:107B70006F8C7FD6093ED3A0C59F08EF61D815C78B
+:107B8000F5CA52E53AC93F4A54FE91DD57CA13255A
+:107B90008E4ADE8706619276BF8BF8A289F58757F9
+:107BA0001D23B7C23E51D2EB7EE6FF637A99C3F63E
+:107BB000024EDB918EF34AFC6FE875552FD85D1BA2
+:107BC0009C762FEE298DEB75E3C94BDDB32A71BC92
+:107BD000311DFAD618A791BFDC18C527AE771BEB6D
+:107BE0004BC5CE6E906F4BF3AC2284F1D15EC7478C
+:107BF000CD7DE53D9FEB4553A34BD21BE747AA70D4
+:107C0000ED6529B4800F8FB1BC7D107697D17F13BD
+:107C10006E890F12BE257FF35A00DFD1CE440BDBF5
+:107C2000D5DDBD23F7087B0A31A165C7E790332670
+:107C30004C89633FD004D1F226FC45628AB4E7B692
+:107C40003F136F831FE7A6962F2CD8EF9B46285033
+:107C5000BB447B8C2BFD761AAFCC2CE36D87ABF04D
+:107C60006F8891726CD98ADE3999547E13E2042FA1
+:107C7000E1C7AE52FDD00DA395F538CF321AA47EE0
+:107C8000A1B5C7381C6FDA579E5BE3FAAA71446A44
+:107C90003EA344B62F5F656FCF4A406A0DF7A5F447
+:107CA00064BFE21BFA52FDF84CF18AD4831437E426
+:107CB000EBF618D5CE77BF87E5FB000D09BB9DA875
+:107CC000CD12BCCED15E1BEE6FB53FE871C1CF1AAD
+:107CD00097E7E3FEF39A1437FC55EDA385C1FE7ACE
+:107CE000CC15EE03BE7BCC2BF5D40C2D6E2B3F9622
+:107CF000C7DF991B988579943595BD0E7C14DFD22A
+:107D0000BA87C0DF2718F8F7DD122BC22CA77B1328
+:107D10004037B79BFD73FAD2FA3EAA35B37DECA388
+:107D20008A58F6FF6698A5FFEAD1BE6E5EF778F82E
+:107D3000B38A10AFD83603E38C1F20F9D3F824D7C9
+:107D400010F8CF3B96C708CCAF2CC9350BF32F5B8F
+:107D5000D197FD80E3EF967A574F8B7058A8FFB507
+:107D6000EA7833EBD794B23E539F6442BC652F87C9
+:107D7000B020CEFDA69642A6E7BEFD03E330AF4F8E
+:107D8000EF12D7609FE6AC7E90F5B8B1E6BC2EC08E
+:107D90003BEDBEE9E5E4CFAD753216F2C93A07A76F
+:107DA000BFA973090BC954DBEA5239FF4C9D9BD321
+:107DB00096BA5C2EDF59E7E5FCAEBAA19CDF5DE721
+:107DC000E3FC9EBA524E5FA8F373791F2204D84594
+:107DD000683D417B91CCC7C8BCCF9624F35807AD12
+:107DE00087F5508450C2AED69BCA4D49DC8EEF1544
+:107DF000503B915CC456AF602CA5385A2F14713F8C
+:107E0000D145ED378AF2BD2DEA3D071A1FF0D3F6B2
+:107E100083FA879375FB31D67CFA7ED887CF559845
+:107E2000385EF19C68DBFE3BCE3BD94E926E137BF5
+:107E30002007B5FDC2292077984DDE543BE27248F9
+:107E400061B0E8CEAF1F2F8E11161D9FB8AD36D191
+:107E500090EFF68B2387700C0D4F09FC067876ECBB
+:107E6000CE33FFFE048DBFE1AE13F9A0739AC7961F
+:107E700047F0DD65B15EBB1BF3102209F946AB6626
+:107E800097E3B841BEFFE646DC725C3BCEA3C76D0C
+:107E9000AE3F3F01396885D905BA781FFB47F0FE30
+:107EA00040DDBFD98D924F66C4AA7EC6A647D84E84
+:107EB0005AA6F1D755637D9DE71501EF50DF4C19A8
+:107EC000B71E2BFD8FED15C7B7FF8EC66F5F66F32C
+:107ED000AAACDBE71872F13CB4EF448F773C4DB0AD
+:107EE0009D8AB467510B3BE65EF7B1F9C0DF7BEDCD
+:107EF0007CAF40A1436226950756BDCAF7AE95DA1E
+:107F0000C36C4F0C389C1C272782D6D3FAF1945AA5
+:107F1000793F5BB4F54A84BCA0DDAF8E1BE4B3218E
+:107F20003E1B63027F66E71EE0FB9DA24971411F75
+:107F30002A57CBCBB5B8704BA0DF143AF02CB9F26E
+:107F40009E6AD75C1977DFC9D706497D7F41A8EFC4
+:107F500046B3CEFFD1B77F711BE8AB939F4D5198CD
+:107F60008F11DD3B40E727FBCD3E817A2ADF0F3EB4
+:107F700037BE38DC6709EF6F95F0C19F932ABCB01C
+:107F80002B627F31FEB95516960335BAD0E3AD2D7D
+:107F90002982D784EF3E93A40761463DA568F73F49
+:107FA00045AFB3DC928E347AD4E80DF33315F1F794
+:107FB0007D161D9FB3AE1A6D82BD5DA32BB6D70E85
+:107FC000C17D57F957BE5AE17B0FE54D85B679BAA9
+:107FD000F365B65A3E07F74B74E5BDB12F83711FA9
+:107FE00032549F0ABBA27AFF04F94C82E3DA85BEC1
+:107FF0006E4111699FA0EE5F438CBFFA39E8E7DB61
+:10800000E3F83C2C5BF1E39B0683AF3ED395F1F79D
+:10801000B3093B385E6E76E38C3BDEA3F2C093314E
+:108020005C9E9B1B1808BAFC4C71CF7A0E7279D0FB
+:1080300073F360EAFF1714B21E165AC5DFBD77F45A
+:10804000608E03146E1BE4456DDEB3738B56C0AFB8
+:108050003A7B356E2503D9020BB0BF0D336EB1C02C
+:108060003EE9C1FC18CF84D403D47393E06483DD6C
+:10807000E75378E2D91E26ED5F9FFDE6E91338E766
+:10808000BF7A2ADE05702E1C28CF6D91171A22DFC9
+:108090001730EA07639EFE3001FC5D936B17ED32EB
+:1080A0004B39D62BFD14946739365A3E7DF999BF6A
+:1080B000245C522FD825ED1C3FA41768717C8B9E41
+:1080C0009772ADB61F8B940BAC572FDAB73CF952B1
+:1080D0007171D04BC10FA2F5832BD523A2F587294F
+:1080E000B946FDE14AE3F1B47C456D41D6C757215D
+:1080F0003E2F302B17F179B543B26007ACA91DC5EF
+:10810000A916AF57513B80DB2DACBD8ACB7FAACAE5
+:1081100051C22238DE7389AA3F9F0B657711DFF3C6
+:10812000FD45EB6892D4FF9CC5DD0576075DDC3626
+:10813000CB7395BFCF4A029E2DD8FB90CD44E54F1F
+:10814000E6CAEF9C89D2776AB67DC476896AD1CABD
+:10815000FB43FB261C7AFD779D8DBF73B9F9553E15
+:108160001DBF18F8BBA045F16DA1712AEDEE0720E7
+:10817000CF54BE36D91AD4ED67A38ABFD1F3BF332B
+:10818000D76D88A3C27C058FD3F239E2D8C46FE3E0
+:10819000585E3BBB57DA6B3FD966DE04F96C41CBC6
+:1081A0008E1AB6A36C8B73C184FC9955CA8FDA38CA
+:1081B0004DEAF79A72353B480BB73FB52D4EDCEBD5
+:1081C00091F3053FF84C31DE5F58ABF65B9B2BE536
+:1081D000D53C95DEB4F60B9C4D36E83B675E98DCEB
+:1081E000ED6ECC6BCF9F12FA507948ED7776571C25
+:1081F000BF3BB060D77F4C7811FADAAE926E8A8EB0
+:10820000CF6CCFB5CAF984A4DFE6CC5E69DFA806DF
+:108210009C092F4EA9768953CF746D96E776C800D6
+:108220009F53BB9E4D30E545F6719123B40A22B2AF
+:1082300076FF27D61A084260B7EC9D18048F67FABC
+:108240004EC33DBB901F7C4B6B6773F858D8D1EE83
+:108250004B0B2D6E518DA72179E28D00CD7FC90288
+:108260009B803C316BA07BDAAD380F5FB3F27E8828
+:108270005EEE47E0C79DF5565701FEB4C4E3657B4B
+:10828000D2ACAB249F69F7C878FB8E3BE3D9FE5D87
+:10829000B54A113E5A9F7872BC8CDBE9D4CFBC6FD3
+:1082A000AD843DE3CD2C013DAF2A641601B41B1A09
+:1082B000CE99A8B347A713BEA0FFBFA9FB790CF7BF
+:1082C000779C38370FE4B03F79478C82EF68ED4FE9
+:1082D0002BE11C8EF3D8618C33A89A14CE811FA099
+:1082E0006A671AFB014EABF780508EF95715C978B3
+:1082F00082CEF63F3F90037CAC9ADD92EBE275B9FB
+:108300003E673DE3B978BE2F69FA5DBCEABF8B6179
+:108310007F3EFB1C29BF202199E3CBCFE64A3DE6F7
+:10832000F14EFA94F1123DEE7226E8E3257A284DDB
+:10833000322E628B315EE2984D9607B71AD771DA0A
+:10834000DAC4EFA204B718E3254EDB9A64BCC45626
+:1083500063F98284265E57BB55C8B891A7649C8F89
+:1083600070B6EEC6F80B9F8E61BA5858573B01FCA9
+:10837000F2B3B4D0BC3D54FED953FD38AE87F653AA
+:10838000FA37820A9F030B894D20FE8ED252C4D148
+:108390002DFCCD23E96CB7BD4BCAB987E3D7B23EFC
+:1083A000726EB35D015F3FD95DC68D9CFC43577E05
+:1083B0003FE3A4D2948EF92C24890F724A4034CD25
+:1083C00062FBF366BB40FCC4C2CD768E6738B9E56C
+:1083D000EB7E7A7B37951BFCBCDABCB4FA2EFD240D
+:1083E0009FEBD24FC2BD6B3FA94F57F67B6737E477
+:1083F0008B768FDC1FDA3FD6DB1EDB11C3F9CAEDAB
+:10840000DD3742FF5AD812D36E66794CF5E710E398
+:1084100083DD6C8190F2CC67DBAC1C8F81E751C0AF
+:108420000FAB547EA8FC62686A1BCB6923F83D80C1
+:1084300085A6C22EC3693D0B09AFA15FB65BBD3FE8
+:1084400062BC79C3CAFA1AFEA0BF9DDCDA93DF854D
+:10845000189F246E9B847EB5FFC1711827939A0ADA
+:10846000922EA1672DFC5D3CC7C72E5C79B589EDC6
+:10847000EE66A91F52EA53E4BDE721902BAA57C626
+:108480002DD6FB61163A4F709C4834FC6EEB27E505
+:108490009E6A357EAC72AB7CAFA38AE80D71D7952E
+:1084A0002BA4FD5CFC46BED3B234269C80752DDD2A
+:1084B0006266BF41A5AD25A73BCDFB867E92FF51ED
+:1084C000FB00BEDBD9DFE67D84C77D732AEFFB0DA1
+:1084D000FDBAA97E8C8792B1AFD1ED97C6101F71FE
+:1084E000EADB6D4AD0EFBFD6AE735D2DD27E735EF0
+:1084F000B4FEF42FD4E56FDB62785EC4EF393E2F13
+:108500007ABD345FC6CBCA67EC7CBFEF947A3FED8F
+:1085100013E2A7C1BE98CF8D0FF07ADF99CC71B16D
+:10852000F343C6FEE7DDAD43605738BFEB260BFAD9
+:10853000FFA89FBC8F58BD7238EFAF78CBCAFDA2A1
+:10854000F7AD486DD7497FDBE3E4FB4BA2E5198C1F
+:10855000776A7B9C09F4D79E28F1F9D4689A27CED4
+:1085600081ED29457C97054215E1DB4297C4B7535D
+:10857000892DE92EAEEF5B88FA76F51D1C11A696C3
+:10858000C04BF4413C48AD94E32A1DABD9EE8F3883
+:108590009221459C86ED978837011EC26E7048A5D2
+:1085A000233CC7027E5D89F1186F5B6CF05706545F
+:1085B000F9B36A5B74BC88AC6FD4FAD36CBB69F155
+:1085C0002B447F954185FD07958DB72F009FA95CB2
+:1085D000FCE0ADC04B6DFE9516510A7ED0AE987989
+:1085E0001EED314417905BF5DFC994A92B39B2CE4B
+:1085F0005FAADFFB553FB7261F8B261AA7AA515942
+:10860000CDE3AB7C82FDFEBA7E04061BCE99F6D18B
+:108610006A7DD47ADBD5B8CB8EED4AB3FE7C895E19
+:10862000F7ABFDE4B9D4EE713F3002EDDF3073FCFF
+:108630003DE5DFBA96E9DECCF1900DD8BC61724C15
+:10864000FCBB76412F8EEBAE300B4B1AC75BD822AA
+:10865000F11B66A35D0571F3D0D390424F73DBA588
+:108660009E863CF434A4D0D3500E3D0D79E869C801
+:10867000434F431E7A1A52E86928FF44E5932F8836
+:10868000D0008B59E7BFC63DF5419138AE485C97A5
+:10869000C9E8CF3E698AF66773FCD609A575459A85
+:1086A000F2C3F15BE5DD03EFF6EBCEFB6C18EF8573
+:1086B000CCD000E8BDB5E0DF889756DF9FCA596F80
+:1086C00033C03D77B331DF7F9B319FB7CB982FD835
+:1086D0006BCC7B5F36E6FFB59F90DF2B8A71222E35
+:1086E000A86DF9272BA0560DEB1E38DA8FE3BE3BA1
+:1086F000B6CA78EE30F397B67ADA5FB9DFD20E47B2
+:10870000A3017FB5B8E01F7CEFE707DFF931E28313
+:1087100016C7B4C1DA91063EF9D1538ED598E74712
+:10872000AAFD544C77B07CA5C9E99A7EB5E47E8554
+:10873000DF25FBBA5F12F73F779876E37BEC78731F
+:108740002E5CC5F279677EB562E238A9808FCF3D95
+:108750004D7E4B57487E03DFA3F5432EECBBCE6422
+:10876000987FBF50AC01BE039E4C32E4F35B7A1895
+:10877000DA0FDC9369A82F0CF737C6814DA9DF2FDC
+:10878000EF59A8F350E5D5C9ABAF32F42BF70F374B
+:10879000F45B7A9783F16BE97B66B6B356A002F17E
+:1087A00026902B699D15E80B7FEF661977226A8D5D
+:1087B000E77B8545045D4978A74D9E3F5A3C798506
+:1087C0004BF812699C33854D5BF1EECD823FFC691D
+:1087D000880B7180CAE814D831A6E4043CFD096F07
+:1087E000D2ADBE09ECBFD9919D580FB9F3F021F677
+:1087F0005F6B78926E75C5623F9B9BA43E007B8E3B
+:108800003929B2DFCD4D5D63FB3823EB8EEC6F1E53
+:10881000CBCFE70F9BA10E888AD14AD0363032FFEA
+:1088200025EA79A1CDF763556F108D729C9FA8F54D
+:108830005545AF3E9E445B77DA74E0AB9534BF5349
+:10884000852D39614A173ED69C7C0BC1C36A0F5CEB
+:10885000D31FF6F8374A12E067FC729B95DFE3F905
+:10886000F7359B1E475CC8CAA64D36C83F0B2D2165
+:108870001BFBC19F6AB6212EE4BA279BB97CDE930D
+:1088800065AC677E6A5D6C63F9F4D78A78CE13595C
+:108890007F45B1B2DE85F8EEFE928F56C48A400B5A
+:1088A000DB9D471CEA86F3F64985E322A64E196D47
+:1088B000ED0EF97D5B22DF239DA2B68FC6FB73AF61
+:1088C0009BA57D6C8ADCEFCBDD6F9D7CC1C3783EC0
+:1088D000E5C200D6BFA686FB497D37CFA8EF56D8A4
+:1088E000DC6F81AF8B3F9A593EEDB43F78AD2C0FD2
+:1088F000230E127197FE116603DE2D1A1367C0CB8B
+:10890000E922C910B779B3E861C84F199F65683F7C
+:108910006DCA80287E5014A9677E708D217E933E9B
+:1089200060A08B6AB4E073A5D8D00EE5322EF406B1
+:10893000C3784BDFB82A45C6374E8AB487BEBC59C8
+:10894000FA3BAA77256E84FE5D619271CBD303B2A8
+:10895000BC668F2C270DB4F39E4417B3B427E8EF01
+:108960007B08D58F87EF03AED5AABDA93A57DA9910
+:10897000324A5A6D8E6E6A7C300D5DD3A4309C09EC
+:10898000BE96AE4932BFAC88FB3BBA1645F0A46632
+:1089900097F1DE26C687BFB9E6B0B90CF4105D4F7B
+:1089A000E7D48A1E98F778A5107A670DEC450988F8
+:1089B000BB8CF25BC37E043F2FEC47BA7DFA6B7F22
+:1089C000B7C43BD5CF331D15B475552D3B5EC1B82B
+:1089D00053FD123FA3F148D30FE609C227F89B8845
+:1089E0006E43EECBC30577C7A07F68F0A9F149BC01
+:1089F0008BC6B31EC043C4D30A821F8D3B7F97E250
+:108A0000C53B58680F78F5001E46C187E1F9CFC213
+:108A10006D68941D48A3B33D0AD3D9E5E018BDBEE7
+:108A2000CBC1555BF7A40BD21EA2AD7B5E40E2C565
+:108A30003C5A17FCA637E3DD99AB802F929F741048
+:108A40003FD989EFFB25BCA68C37D25D27FEF825E0
+:108A5000DE6BF833F542328FF3CFE34F1BDB6FFF52
+:108A600059BCD1ECFE1A3F869DB18CFDD6771BEC2C
+:108A70003C5A1A6DA73CD95F8D1F192C061BE24783
+:108A80002E730F293A7E443BBFA3CF8FB23FC8F36A
+:108A9000A3F37C51CF852577E5323FD0F86B402D8D
+:108AA0000FA8F63BED3B659477EBF22B1AB3D2DBC4
+:108AB00074F24560B93519E3A4D777E5B42CC6C57F
+:108AC000F15265F5327EE5F83D29C943691F8F2FC4
+:108AD00097F12BC7EF1C948E3894E3CBC772FAD171
+:108AE00083F6E9FC0ED22F1C02F1E5D5BB53E47DE1
+:108AF00071B333793AEC713BBBF27DCEEE03A43C0B
+:108B00005BB5FCB904845F552E97E7F157D981C452
+:108B1000016C9F6FDECA0671577301CE039DDD366F
+:108B20006B00F438D86D291FA8CFE638BB4FF18D04
+:108B3000229C5BF2FCFF34C67533BEF7E95356BE88
+:108B40009F4BF53EF8517EA2844F5CCBF7F69464C0
+:108B5000D8A34EBF6766BBD802F3FE027CAFAA6EF5
+:108B60004F3AAE505414D1B94A7830CE4EF3198CE6
+:108B7000F96D4A67A7E3AA667E8F31DA4EDC094FAA
+:108B8000D54EBC553DBFA10720851E20FA4A3D00A9
+:108B900079E80148A107A07CD13AA31CA7D9893361
+:108BA000CC5FF03BC69ADF48B8DA5E66FFF14376E9
+:108BB00037F4D05E16F5FD35D59FA4F96F34BF525A
+:108BC000D943F3055EE829EB29BC8A6CCF7EA66801
+:108BD000FF52197C8668779F85DFF3E3BF21D20FB0
+:108BE0008B756B7E29F44F28D2F96B55FF9055B8E1
+:108BF000D2711F32A3C4F5D323D2DFCD7AD5F86268
+:108C0000A9A76AEB9AAFC60B68E93BAA5F69ADC931
+:108C10009B0ABE3CA1B11FDB9583C5227731CB15E2
+:108C2000CE5CC43B2F5562BD908B97629F91FF3005
+:108C30005EBE57DA7ABD9427547CD7DEDBD1DED90D
+:108C400019D941B2A38E2EAFBDE010E53AFA1F2D1F
+:108C5000120DF912479AA1FD5897C7507F5D6A3FE0
+:108C600043FDF5EE4243FEC6DC6186F63779471BCD
+:108C7000F23F1A7ABDA1FD44DF44437E72E90C4302
+:108C8000FBA9FE3243FDB4E90B0CF53302B71BF22E
+:108C9000B756DC6968FFE3C5F5867AEDDDA1BDD086
+:108CA00053EDB82FEAE0547B7FE86B93E0F7B247CF
+:108CB00094C87B44C22EE3EE96BE91EDD4DB77964A
+:108CC000ABF4FBC73CDFCCFCC1F23E2FE8AFB7F6FC
+:108CD0003EA020A994F5F6D634D0CB88B803E7F1AE
+:108CE00034EEDF077C38D542FC74C4D507AECA72B7
+:108CF000E13DC5AC9B393FFCC0B39994BF216FD611
+:108D0000CD16E28F23061E388FFA7D79B9323F598E
+:108D1000B00875F3B63F4C0DD23C465C9BB9DA2BDC
+:108D2000ED38DA7BD78CAF9D718B0E67384B170F00
+:108D300084759667E37E9D8BD3034487485F263A0C
+:108D40002C27BEFB0AD121D2C3A48FA3FC8FA48FF2
+:108D5000237D9DF471A46F923E8EB495F471A4EFBF
+:108D6000D44DE7F4DDBA00F7FB735D05A747EA16BB
+:108D700073F9FB75B59C7E5017E472C01BF9ED03C7
+:108D8000547BCB1EE37BE39ADF5CF3938B97BC0EA3
+:108D9000C41F88364BE20947C4FF7D393D10069356
+:108DA000133AB93145F8F60C607F4A2F17FBCBD444
+:108DB000F28399817DE067EF7926675F45F969DF86
+:108DC000069683F4DF33493B7DF4B80F0D90727B38
+:108DD000739EEF00FA8D74C87B38231DF29ECD4838
+:108DE0004B6B03BF53F48D70836FEC57EFD534DCBE
+:108DF00063E17B35CA0549AFA3BA09CE377CD36698
+:108E0000EE7C6C4FC75F46BABCA97CDEAAF5DABD22
+:108E10008D31175A4BC09746396D1C3FA5F1C1F5EE
+:108E200056C9F7F6C79F28C13D13FABEC0F81ADF2E
+:108E3000DBFC8D089B0A22FC6DA4A3CD0C3EA4E3B1
+:108E40007BCCB7940B6D66C8793ABEC87C4D9B4706
+:108E5000BC85C6298AF03D6D9E787FD256C4F53E0A
+:108E600033E633DABB0EEFA5ACA779E0BCE9E4C387
+:108E70007611E4773055FE4CEDF9FB632E04384E45
+:108E800060941A27D0DB4607BF6CC7F10BF1D02BDB
+:108E9000D1BF6BDB41ACAFE77FD0B8D48EC4278E97
+:108EA000A7D1F831DAC7C9F6618CFB10E28E10FF4A
+:108EB000F2779A7702DEE17CDB03BB65CF9FC9774F
+:108EC0003484CFC7709FACF24BE156F3AA9C21BA11
+:108ED0001573BE58ADBF262B60CE435CA3DDF56194
+:108EE0001CD373566FC8531355BDE27BF0C591D7A1
+:108EF000FDBF8E2F832C12AE762A877FE3FF75BCD1
+:108F0000E9192BE7DBF3EF120FFE7FC39FDB3AC4B7
+:108F1000B82ED4E4BBACC043E02F6517DCAF205FB4
+:108F20006E29B40165B47A479F4BD707FED661ED31
+:108F3000A2C3B391EAD9D4EF32EDB576DAFBD4DA35
+:108F4000F8D7A1FDE08BDBBFA69EFF4BC74A3C2AAA
+:108F5000EDA7BD6BEE7316D23825428EF39A7ADEFA
+:108F600095E4CD673D4638A55EE0A67FD8DEA7CA6A
+:108F7000EBD75EB018F4851B543DA254487E5D1AB1
+:108F800015AF7043DE75AC4FDC10A54F44EB07D531
+:108F900079AA7EE0119E7FF25DA1A5A0474DFE4417
+:108FA000DC20F036CB6D768C288ABC23A4BD4B35F3
+:108FB00046A5E3B12260C121729D08727ABD087195
+:108FC000FA32DEA52A403C6C98CFFD9BE8C041F9FF
+:108FD0008F20D251FE60DC8499883D2FB9AAA40F5E
+:108FE000CA75EF61AC007DD798037F75E9DEC338A1
+:108FF00030C6CDFEE5030E79FF057485DFF9D0D6C6
+:109000007190CEC13E740E1EA2F3B80FADE7553A73
+:109010008F91FF039DC748B576E3DCC6B8BB1B72D2
+:10902000EB05C6BBD155420AE2E5E17463C1F3BD6D
+:1090300000C7D712FB8EC1FEBE9678F518ACEFB50F
+:10904000C414934CEDB6EFBB5FADE1FF8D79F2FE3A
+:10905000C58DAE71FCBDEA38C9C7AAE3D2D5F77396
+:109060003E4C48253C39E7385860A6F424260A3D92
+:1090700031CA5EF7499D08629DA36A87F338D7D647
+:109080000EE3B4CA21D7212CC5267D1CF4265B60D3
+:1090900027E0FAC97A33C7EB9FD919E31D4FE37C68
+:1090A0001A7A3601EB22FD6737EAABCCEED55EC803
+:1090B00067AFC97860F1EDC174C41775BE37B57973
+:1090C000B2218E5EC38B2A875C8FA667A6F6F13D20
+:1090D00024E504F91E8E1667D4CB2EEFF969EFB3A1
+:1090E000409EE2F8F928B96548ACE427BDEC92AFA0
+:1090F0006AF0A37E9C178167F97DBC4D354E2FF435
+:1091000095DA54DF6B983FC9F5FC4EC2B95EF1CCDD
+:10911000E70FA8718BA3C203D8FF5C0A7B0B4DF944
+:10912000D558F92ED801354E51E91BF833FABFEA6C
+:109130003ED00BFAD9B9C3E7CDA0F3837D1481F7F4
+:10914000A07E888EA2E9F0589E1A4F54200ABE9342
+:10915000EF95713CD4B977CD5EA9670B837E314A18
+:10916000E43C027B50C9612B223E22F17DA992CFC3
+:1091700068743AF6B08CC3B2A79A845BC73F62DCCE
+:10918000B1C2ADFB7E5C6E92211FEFED6168DF65C1
+:1091900068A6A13ED1D7DF50DFB5B4C890EFEEBFCF
+:1091A000C6D03E657AB1219F16B8C1D0BE67C5242E
+:1091B00043BEF7E25B0CED336A671BEA3DC185866F
+:1091C0007AD2F418FE875C8A78CCA37BE726E86B1A
+:1091D000CD4D967C127F59AB9618FA953AE7F13B44
+:1091E00070D94D3F378C2FDCD27E13A47F805F5F18
+:1091F000E26207A563538D761DB3AAC794B846BF34
+:109200008CADE9A9C69195B88CF69D9ECE52BE173D
+:10921000D0F307E2CA32F2FF493C08F4BF341E54CF
+:10922000098EE38DC603F85BF4EB84BF450F0FF89E
+:109230005BF479F85BF4EDE16FD1D7C3DFA2AFBF88
+:10924000EAB0110F06B71AF1E0EA23463C3884F37E
+:1092500020EBF2FB35ACCD8827DA7E0DFF74D225EA
+:10926000F76B3AFD83FD221263BE3586E016169732
+:10927000DFB7C87EC9FDFBBFDDB79BF3D57354DDF7
+:10928000B72FC5EAC185FC0E259D533ABF6CF43952
+:109290007A8383F4D6EE17EBAD1AFF8AD65F35BB1F
+:1092A00082165F1DFD8EAFA63F6BF1D4D1EFF77E26
+:1092B0006D6A8BC7F979CCD4C4EF209B530235F883
+:1092C000FE6D798B15F8DBBB57AE603C3FDBBBE333
+:1092D00018DE630FDE192FF97A9E1C6756430ADFEA
+:1092E0007FD7D631ABA78CDFFA59BE7ADE7BDB069F
+:1092F000C39FFBF37CA997C77B5D7C4FA02C4FA835
+:1093000071D0227D567EC4CF786E9994B7038E407B
+:109310001DF4F706F57D78EDDEC015BC1BDC88F981
+:1093200077BE37B220FA3D97704C5FFACE636B92EE
+:109330008CEFE4540BC37B238F2DCBD1EEF5CBFA0E
+:10934000DBE5BBBF7DD709C3F9AFF9ADFB851C8653
+:10935000787BBCFB83B880014FBA0CE5F92DA98658
+:10936000FE8FA9EF130DDCE336B47B4C7DFFA530F7
+:109370009C6B687FD561AFB1BFFA2ECCE0D6A186D9
+:10938000FE6DDA7B3E0BE4BB26D01320EF5F7DC47D
+:1093900067689751B96402E486DEAADC3DACADD4BF
+:1093A000307EC6D95813E2DD0FE6CBB8FCE19FFA58
+:1093B0000DF5AC9B010F7E96CCF0D2F499CEDF79FF
+:1093C00050F5179B90EFBCDB5659D83FAAC595477F
+:1093D000DBFB3AED798E88FD501FEFADE91F9D71E3
+:1093E000DF16926BB22271DF9D788877FD65BC062F
+:1093F000C3E1F19F2737EBF1F48FF9521F7C146F13
+:1094000091D1BAB638A43D10F16778675A58DAD2CC
+:10941000F0FED3DB2A1EFBB37D6F011F1F55EF57F4
+:109420003D6EEB388A7375D640F99D992613FF2E51
+:109430001CE2F176EAF4CF0FF2A55D65D34099CE38
+:10944000EA22E723FE45BE2BA0AD23D5261AF9BD9F
+:109450000C4B5B3FE0F78F57B7DC8FAA99B626AB72
+:109460008C670F59F9DDD06292830B092F9EFED9CC
+:10947000C3CE6178F7DEC2F6A78FF2EDD3827D22EC
+:10948000F7A132A818FB005B38F4ADC103CD977C7F
+:10949000875CBBE7E3BEDDEAC7EFD88D378952E8CA
+:1094A000755A7DE94049B7A13E26F62B6BBF0BA14B
+:1094B000D5DF5A20EB730AE4FAC69ABF2DC3FAE649
+:1094C000C64BFD7694CFBF16FE81D96BACA219FABC
+:1094D0004E90F49D648EFFE1BF32B7D457022A1F2D
+:1094E000471EFEA6B2A091EFD279C0F2D67CFC3E18
+:1094F0008B027EEE5D01FBFF9C55C67673851C6F6B
+:10950000BE53BEBB3A37FAFEA7E66FF9013D687C51
+:10951000817AEE0E1403BFD3BD177B4ED5FFCF0962
+:10952000B98FE76A6D7CAE6A78AFC36BD6BBFFA715
+:10953000EE4708F5DCEFA3C251A3330D9F34FAD1F7
+:10954000F009FB8BFDD3F617F7B1DA9D91FDFDDF36
+:10955000BA97D509B71FF0175CCE3F10CD57F84F1B
+:109560006787B99C5F40E3339D7C4410FFC88AC085
+:109570004B8B7FA85071245AEE3A17CAE2F875DC7B
+:109580000B33CB79723C9C768EBBE1DFD2F95F88DE
+:109590007E62F1BB05C1460BBF8F100D5F8D7E2E25
+:1095A000179F711AF119E0B59A1F4DAD3F1D3CDFB1
+:1095B000CEF5BB62F81DDC3385AD05D03F34FF5AD4
+:1095C000B4BFEEDC328740DCDFB95DF1EC6F853F84
+:1095D000AB0BDE85AADF54003F57E739DA66F4CFDC
+:1095E00045A75F65077E52D01D7E2EEBCD1C67E838
+:1095F00034B9E0BFBFC77980DF3548577C77A05EBC
+:10960000D3FBC6D339877D23BE548AFDD6FC51D106
+:10961000EBE9A4B311F23EC7B9A08CDB3F572AFD9A
+:10962000C3EF09E28234DFF18A8BED007AFCFC673C
+:10963000FC5A932F14F2FE4CB9309CD71958358C34
+:10964000F339194113E2BBC5AD0ADBEFA76D16CBA9
+:1096500063DD88D39A3618FA5BB3BA4F39EAF91248
+:109660000D97BF17C87365AB49BE07B4F56E197F78
+:1096700038609BCF847789A6EF72A9EF972F2E824F
+:109680007CE055E94F6B9F631187AD452A1E53FB64
+:1096900027AEF6F03BFB29EAF95138C0A5E2491B99
+:1096A000BF23DD199F552F7F276B8922B4782DE6C4
+:1096B0004B5AFE7C939A1F2BF34B97CB7C9BFA0E55
+:1096C000E956D5FE01F82105FC601FD8A6DA3F0057
+:1096D0003FA4801FCA41DFC883BE91077D230FFAD4
+:1096E000460AFA46F96CE14F876315FEAE313A3E01
+:1096F0000D7FD7181DBF85BF4B9F87BF4BDF1EFE59
+:109700002E7D3DFC5DFA7AF8BBF479F8BBF4EDE10F
+:10971000EFD2E7C5D0EB2379D8D57C130DF9C9A4D6
+:10972000378CD19D0FF077E9C787BFCB305EE076ED
+:1097300043FF5B45ADA17FD6E27A43FBDB6A15832D
+:109740003FAC5C74303ECF59D795F1B04F96FF18BF
+:10975000E8E7B6691DFC1EEC58F3DE05C08725D589
+:10976000B15EB9CF4DA572DF4D1C87BCC1EA4EE199
+:109770007708DF300BB9CF320E3A1A3FE1EF1963A9
+:10978000957E27A4F03B2185DF0929FC4E78E7115F
+:109790007E27A4F03BA11C7E27A4F03B2185DF0996
+:1097A00029FC4E48E177420ABF13FAC1EF84147EC8
+:1097B0002794C3EF84147E27941F83DF89F2C3604C
+:1097C000BB217CCE6F0A1E82AD6AC2FA632F23CD05
+:1097D000E952B6532154770C0C4E831F2E27AEACA2
+:1097E00028D14B7CBA7EF9B43144AA0135BEB040D1
+:1097F00074B0FCC77105B4FE4058CAE9F9DFA47122
+:109800007D845E243DE5BFEC6239B550BD07ADF502
+:109810002F842B2B2BD23E92BF74BBE8EF6BED98BD
+:109820008FE9E6A1DDF3CE78D5CDE713D101DFD7FF
+:10983000D37ED728101CCDEF258FB749B98AF8C23F
+:1098400035D097060415FE5D616DDF3C2AFD0FD80B
+:10985000266CA9E00B1B660DE27EB19DFDFE7E121B
+:109860007118433DFCAEE4886DC2D74CFDFB0F94EC
+:10987000FC684447CB01F0B5B2C689DC4F1BB76C1E
+:109880007D3ADF5B2D138B7F8EDFDF1183148E4FCC
+:10989000233EF432F890B6AECE738A500276D32BC4
+:1098A000BD17347250E258C4DF89BD82DF2BBA691C
+:1098B000D0DB8675F3B60CE17199FFF70D2AFC1E1B
+:1098C000DE8460FDDD501F6F0ADE7E08F17A81CDF7
+:1098D000C2EB7133EBE67B14DAFCFAFB7698E8F81E
+:1098E0002075B4D584DF8682AAD255B7BF84E153F0
+:1098F000B01F855E2BDF4F99687159F95D84A8739D
+:10990000313A6E253A2E72C95D17DA11A7BAE439D9
+:1099100079CE6AF241991A2777BED1CA712565CFEF
+:10992000D9F99DB9C03A85E9588B6B39637A3D798D
+:109930001AF5ABCE0AA59B1057DFA3B920C9CCE717
+:10994000E8CC81B8A7D028E34DDA1B9FE5FB8AE776
+:109950001B9FB3F1FB91AA7FA05C854FB91ADF541E
+:10996000962FE560ED1D7E2D2E4C34497958B37B42
+:1099700094BD21E365A2E5E44A550E5ED068E5F8A2
+:10998000A405517272A51A7F54F90372F2D281AA0A
+:109990009DC32BBCFFA4BFE0CE813A7F81D0DE63A4
+:1099A000567F87A0EC8D8353F9DC5F9C6DC2B9AF05
+:1099B000C90B33EBA53C207608FE5DA699F5257C06
+:1099C000AECE7CCEC7EF51BCA5CA01932EF464F88D
+:1099D000FF493DF7A7223E93F6617C5B0C97DF7C45
+:1099E000218DD3691764BC26EECE004FDA9E171C7A
+:1099F00067722E689772C85EA1C67F1AF1B450B81C
+:109A0000C602EFFBFB948310B36E821C41E34D87CB
+:109A10005CD115785FB6BC3BF03E2458DE8BC6FBAC
+:109A2000F1D6C587503F7E8BF0064504EF0341CF4A
+:109A300058AC6F42A9C2BF2F313DF0B605F44EFCC1
+:109A4000C0857E0155BFD3F03B9A1E66C5A97AAF8B
+:109A500053DA5D3AF5614C128F53068F4D435CED3E
+:109A60002CD8D67AF0B27C88738BCF93F5BFFFEDFC
+:109A7000B1698D7DFEF7DF4BD0DE4988E8DB52BF50
+:109A8000879EEDE7F89B0FC6A6B09C9358A4B783BA
+:109A90001E57E9B7BAB0D8E2A57E4BEEC94EF9BE63
+:109AA0007BB07368DF409FB3BAB4DDA1D0F9F2FE9A
+:109AB00040E11B3314BF7F22B4C73CC3887BBC4545
+:109AC000CD1F1DF88F7F5B95C770E6FC9F079E9C9E
+:109AD00086B88F7B976D8CE2837E1FC8212ECFC7FF
+:109AE000FEA1CBE9F39E145FBC97F6714E9EF67B08
+:109AF000B2F21EC3F17B3E795A6FAFD0EC5D427477
+:109B0000B0BCBF76526AA1FAAE0DD3C3630BE53D7C
+:109B100090AF557EFF3F75DF23D9E3FF6220FB65E1
+:109B20009A1CAC27E5763CBA85BE3FABCEC6F72F74
+:109B3000357D6AC3C2585EC7869FDB981F6A7AD597
+:109B40004C5BEB21FCCED6D181B2DD5F6A7F65052F
+:109B50009FA37DE575CC5C28DF31AD2EF4FF03FCBF
+:109B6000212ECFCBEF8704F2420A7EDFB4874BE28F
+:109B7000FFFF01CAEF279700800000001F8B08003D
+:109B800000000000000BDD597D7054D5153FEFBD7E
+:109B9000DDB79BCD6EF276C9272161771320EA02EB
+:109BA0006F3784519969D79450679AB18B4E31C100
+:109BB000105E48827C2490A44C0DAD369B2E600C28
+:109BC00050420DF2D14A37B1D08F099D808C322599
+:109BD000CEAC52BF5A2CA8D3A923362EC5224A3563
+:109BE0004B662AD2B1DA73EE7D2FBB2CC4FA57FF35
+:109BF0006866989B7BDFBDE79EF33BE7FCCEB9A18F
+:109C0000C69BF08B0B00128FD82B8704802FE8E7C0
+:109C1000EB003325F83DB800EABDB0326407FCE93B
+:109C2000075808D04CBFBA93FB4EAB782817E08C8E
+:109C3000EA66E3F27E2118C5FDCDFD835BF3720079
+:109C400056F5FA174A78A4CDAF292A7E6F1AF5BCCB
+:109C500054845B379C70CA9A0FA0211FDA477C247A
+:109C6000345172AF2329B74C97FB9A1F3F55028C92
+:109C70009BA196EF8BF67A516E5D8EE2EF433945EC
+:109C800026D86271D17E91ED2F3641580CF0310308
+:109C9000D765300501F7CB5D723482228B008232AA
+:109CA0007E9F6185B015BF17A34409C7FD73B8FE39
+:109CB000327E17710EA6F82D21D4A75E565E02C221
+:109CC000C721BB099F46FBEC25F9386FEC175C02F6
+:109CD0001EA9966A5E22F99DBB3D5E8B076099AE18
+:109CE00037D45A45C80368B172BC3AF794CA85B4F0
+:109CF000EF3141A1798DCBCDE424760ACA10CEEBA9
+:109D0000517D0824ED6FDE7707B8A7E118C5B122B1
+:109D1000B99E3EBEB3FB64EE1D781E624199F46DA0
+:109D20005682B2CB97FCDEA4FB237DBE4495989E61
+:109D3000F5008B09AF159B3CF22A3BCD5F3177FADA
+:109D4000C80E8E87710EF7C5685F8D17381EBB5120
+:109D50006F0FBF2F90227F15C94FB9BF86E207E76B
+:109D600021D5C1E4ADEA77CA8217F15314A6E70DF5
+:109D700038E8F837C5A26695F431E1BD385FAE44E6
+:109D8000CD011687EE25058863F30E01FA70A6ED66
+:109D9000E0F769BD4E792EEDB7294BC81F89AD821A
+:109DA00083F4AB7105653BCD777BC4D4F84EC7A96E
+:109DB00051D7BB19F56BB96E7DB7D98DF33AD46B1A
+:109DC00004E5AFDA72972C527C9BB8DDDDE46F8C32
+:109DD0004F4DC7F5EF1D197D908D7AB8FAAB37E37B
+:109DE000BDF5AB9DCE08DAD5A1C76737E15A99C456
+:109DF000A54EE967764DE2BA077140912D4A88C9B0
+:109E0000C7B808531E360FE87935D028FB705C6D53
+:109E1000D2E419EC7E079357B78FEB99BC1F4040F3
+:109E200079F5072CD108E27071CFFD25CC8E81BD6C
+:109E3000666076BC0ED2028E23C5A311170D153CA9
+:109E40001F0DFB7F424EC8A55164F718F98579179D
+:109E5000B6A4E459F38E4608A2BD4D05A00A4232CD
+:109E6000BF8C7C33F2CCC82F23DFEA205E07A5002D
+:109E7000E61DE7D78298E483866C683F66BF31DED3
+:109E80004DBA1ECB757F203E8CA78CEF27F5FC3397
+:109E900078CB58277924F797BABFEAAB62B33A7CFC
+:109EA000C9FDC6BD881B3B47FEB9D74EFBC5C9FDE2
+:109EB0009D6CBF785D7E37E9F95D2D0D6FCD433C1C
+:109EC0003B8F0AAA05973A779E2A7E88F2FD48A61C
+:109ED0004A517BB9F5D086422FF14AB42494C2731B
+:109EE0002D9FFA599EAFFE7411CFF7D8CDF3BDBCAC
+:109EF0005C3BA156A6C4EFE34766137FA2FD31E2A7
+:109F00008D778E9CFCF39D6EC68FE6D0DCA43DABB6
+:109F10007A07195FAED8E10C489C2F7B892F4D3A08
+:109F20000E4D5BB8DF00FD364B48FAB7718B10A4BD
+:109F3000786CEA5A18953C493FA7F367BA3F0D3F42
+:109F40001BFEAC9BAC07BBAB53EBC1247E8A819F4D
+:109F50006F5B01DE3731C2F19BD86106CAE38961CC
+:109F60004714F0FECB9DCFFE6919EEFB50886E289A
+:109F700094AEC70F2A387E343E88F8C1B49BE217EE
+:109F80005753F8ECC19FEBF879473EFE1DF143872C
+:109F9000451DC27B9BF0DFED68DFE5E1C7CD45B82D
+:109FA000FE408BE0247D2FAB1E1E772383662FDAC5
+:109FB000D3D4EE57208BD6F5BA97168FC69C78E38C
+:109FC00028DEB3A923230BE6D339A74B9987A6F93B
+:109FD000C5EB78C0D0EB4247E38F01BF5FC8E0F12B
+:109FE000D78AE78F313F074A4C8C272D01E207C8FB
+:109FF00019394AFE69D8E80BF479D8BDAF08A8B77B
+:10A00000CDCFFD5A56168F927EE86FC8C07519796C
+:10A01000C48AE390C8EDF34A7CFCA96DE496F69BF4
+:10A02000E4D9641D6E8D5F217DCA00FD1FE0A3038E
+:10A03000ED0BF8B9DD38873CBE1ECB0B4CCD0F7D48
+:10A04000E5AB2088FA9A31CE289ED2F9C19097CEFE
+:10A0500013F5A2C8F2B12873E4D7140F451B6F0D96
+:10A06000501D976DD04BF6CC99C2DEA9F436F4BDE5
+:10A07000E0E1B84FE2814177BB2B6987A10F94A340
+:10A080001E786FC30FE60EF6E155177AD412C26B35
+:10A090002A3B2F7834964F894250876E6267BA7D8B
+:10A0A00050DECFF2A221DFAD523F63E44533F10A27
+:10A0B000B0BCC88EA39E13FDA5D9C4DB1704AC07A2
+:10A0C000A47F4786C8E244B7E370376E461B7ED54F
+:10A0D0006D65E36FBA31B1E6000C7717B0F96FBB6D
+:10A0E000DD6C1CE92E67EBDFF6BB186E007107F51F
+:10A0F0005DF536BDCF8B01CBBBB1AE5266AFB15E65
+:10A10000E3E2F158EF8A3BA8AE24364BAC9EBED7B3
+:10A11000CEEB4D2BCAA17C81AE523884575DB82B53
+:10A12000EEB8C3D897D22F8E297107D5DD4D667E44
+:10A130000F38E4E82181FA8FA57223AEAFE87AD315
+:10A140002CE0B85CF7EBCCD291607E0EEBBF587F71
+:10A150001071A805A44FC4A916A4D6EF4CFB32D9A0
+:10A160004DF87862650AEDF76730FCC7ECCB965086
+:10A17000DF35B6CF498C079B0475AC0BF582AD1665
+:10A18000F5100E3522F40A2C1E627211E9DB233021
+:10A190001E30D68F956B6BFDB9D40F1FFDE46DD6C5
+:10A1A0005764AAA4077C86F7623F7C2B099558FE6A
+:10A1B00005218507A99F13707E50C6FA4604A205A3
+:10A1C00045EA9F3BF57A41EE67739DFF66CAEE3321
+:10A1D0008F92FC572518E27CF8179AB7BC6A064B99
+:10A1E0004A5CACD1E3A265F0BE3C8A87E67D12E30F
+:10A1F000BD161CA96E1CA08F4881DB06BE9147715D
+:10A20000D3BCBBFA8930D683120142C44725E6E0AD
+:10A210003DC41B9706E7387B52FAA17351CBDDD4BE
+:10A22000FF5C1A7CF6B58578EFC72772FD8CA7C353
+:10A2300022AB037DE5392C1EFAFCBCFE75C8DC4E52
+:10A24000D3A6C630B07E7E2968A4CFE0A32580F7D0
+:10A2500035B74566D3786930A396F87FB1B274B14B
+:10A2600013E5AEFE99D34F75E85CABC4FCBFEEF5C9
+:10A270005943C40707FDBC0EB77E7EEAA082FD40AD
+:10A280000BAE2978EF3F4732A361FCD4DA7DA244BC
+:10A29000C2ABCD166DBF1FE362BD38BA8CFADE7556
+:10A2A00007064B80ED77E72B5FC26317313FDC1861
+:10A2B000FF6D3F7C8BC9F9483C7D4F1D9E6F6D7BC8
+:10A2C0003A8BE4ACDFF3E64205D73F99A51D22F9AE
+:10A2D0001F0A8387150260DFE0BC10C32F7898E265
+:10A2E000609D0979DD77A3FCE1F93C5E6B5CA165BB
+:10A2F000750B981FD5D4B84F1FD79C1098DF8CF9D9
+:10A300008A68B60CD4C7C64056C80F12C89467E115
+:10A3100088201EF224FB114D01D6B73EA7E7C7A542
+:10A32000ECFE12CA87B587F79650FC7FE0E0F3FA9F
+:10A33000C3F7FF81F850FB8545A638D14C20AB7898
+:10A34000AE29CCFB5C5883C15998BCFF657F26C3FE
+:10A350007FEDBE8AEBEA27F613EC9E0F4C7037D9DF
+:10A360003D53BAE2A7BEE99C29D6427171AE3D4386
+:10A370000D33FFF17838D72F2DA1F5F02601A89FD6
+:10A3800038D7FFB4A38CF5EDC0E2778332C96BF9FF
+:10A3900071D6E7B9F73E403CF04733E38D4CDFD947
+:10A3A000A084F3B6E31E167F861EDAF1E7597EAF6E
+:10A3B000D3FBA456534C267FAF3B7E54A6BEB67546
+:10A3C00098F719EB879F978987369CD0FB0CFDDDAA
+:10A3D000DA063CCF361CE7F6B71D3F2F37A5F6F956
+:10A3E000E5AE6D45D8A9BD7FD456BB07F735927F42
+:10A3F000EE449346266A7BB028E4AA0AE74B5382D0
+:10A40000F56F7DE56FB0F76BDB165D5EF91BDBBCAE
+:10A410004C6FBF5948F1FB25BF99E1629C6F3BCE61
+:10A42000DFBD5733B2E6116F7659F9F8902D6B887E
+:10A43000C6AB1925AC8E6956ED2AC55BB80AEF2468
+:10A440003CC71CECFD9ABBFE7BF3C1CB8C617AFC54
+:10A450008DDEC537897BCD7AD76714C7A37A7D8B0C
+:10A46000B5D97AA9FF086EB09B688CB4D9593F1250
+:10A47000EC782383FAB4D18F6DA2904521913825D1
+:10A48000A23FA57C4D0EE0FDF980D98740CE80111A
+:10A4900081F26CFCB9F72B48FFF1E2C418A049E641
+:10A4A0001E53DD628CA3AC80C2EBA52F5E41F992F6
+:10A4B000FB02AF1B4F9AA197EA2F9842702FAEC7AD
+:10A4C00004DD9E6B6294E27A54883D45F243167B2C
+:10A4D000AF07F5A90E701EB0978672E9FE90579AE5
+:10A4E000EBA77BCDF65E01F129D6DF43F2F4023B08
+:10A4F000E114D171148241E8C27B44E1C526E295A2
+:10A50000ED092BD07BBC78FADDAC4E46745C057748
+:10A510000E7B1BBDE013C316D4633B58A3B44F1688
+:10A520003382B44F187DF99A80639174E554367E76
+:10A530002F7A485023A872C3C445D6CF8E5D1BCE58
+:10A5400020FC17E56BB70510DFE9527CEE2E54793D
+:10A55000BBA2BEA591BC9055ED71F318B762BC5774
+:10A56000F15F6174F3B52C179EAF4AD8CE13CEE3DA
+:10A57000898B479E5D40A355A578A91A9562967967
+:10A5800074A83A182FE767BE607E86A07561520EE8
+:10A59000F4EF05CAA38D7A1D31E44D757EBCC06D04
+:10A5A00022BF812F91B50BEF8B8C4A0ABD9BAB4626
+:10A5B0004FBD45765659ED31298BCE99FF11B7A67F
+:10A5C000DC7BB6D879F13656DAE00B6C5EF222DC31
+:10A5D0009F5FCBBEFE7D581BE0F5A056F79BE10FB9
+:10A5E000700721B5DE19F81B3CB071B20EBACF105E
+:10A5F0006E6F63DD23BD2646B1CFB909BF1AE39B59
+:10A60000D4E760FFD25016AC0D5426E3223D0ED2A3
+:10A61000FD6DF815BE7FF6C56C0FF3E7DC5DC0EA93
+:10A62000F3936704E6CF668AB7039F0EF9C9CF118B
+:10A63000C7128FE6FBFFF3A3C13B9A0DC7F95FC2B8
+:10A640003F361CE7DDC83F57C5906D8E87F1531F1D
+:10A65000E1857CF122F14501B4339EF80ABCB48B4C
+:10A66000CE2DA222CCFA3A314A7DE45AEBB7F6BF9E
+:10A67000378D78023B0EB2AFAB384AEF9A4533DDE7
+:10A680003D26DAF708F0BECBC4F58974DDC6BF4BB2
+:10A690000297B3598A52BFF78119F901E7E19E3950
+:10A6A000ACAF643F388F848BA2D4BF50FF4D7D7B0D
+:10A6B000C4C4D7C3ADC0F645A262785636FBCEFA05
+:10A6C00072CA7966773B309E9ABC77D36C26C7C82E
+:10A6D000072DBBF31EC2491BE7FCF94CC0A9D78963
+:10A6E0007825F5D5DB7FE4008A4FC3FFD3418F7B0C
+:10A6F000DDFF92EEFFE93EEEFFE9763166213FAEE7
+:10A70000591C4CF56382381471FBEE5FBFB9DF8AC8
+:10A71000F393068F3E2731FD0796060B6D3934E61D
+:10A7200089D42F3DF3F953FB57132EDFB133DCA44B
+:10A7300082FBF63723BE037E6EF740DD6CD6578D65
+:10A74000893A5ECB6D5C8E43647207D6DAA24073A1
+:10A750000FBF67609697ED47BFCDDE4772975A9956
+:10A76000DC14BFB17DE36B66E87EE3F724763A98AC
+:10A770005F92DFBD0C3FF41BC30FFD557B8CF507CB
+:10A7800089ACA573937132AEF71BE3BA5F26D7018C
+:10A79000D769BF299195FAF7E2A9D63BF3B4772997
+:10A7A000DE8CEF03CE6021F54FE9F8EFE9F1F7CE4B
+:10A7B000261C1CA242EF82A9FC66F829F37EF92030
+:10A7C000F52B93FE0AF338CC8C2C62F63F61F80728
+:10A7D000E392C54F9A3F61068F0FE3BD30337C7E15
+:10A7E0003FAFEBF15BA87E62DE95D33B738CF86DD7
+:10A7F0007E326E05A4D52E57328F8D7835786EAAAD
+:10A800007C16BA90FFB26E96CF237A7D8778662940
+:10A81000CB6B7305EA23896A8185E5F3D942D2E7D8
+:10A820002BE4B58DCEE5E8BCF25EBE96C5E79C474D
+:10A830000E88513FDD83F1B686FF1D1FA30BF17F0C
+:10A8400057C77525F2D734DC575EA1FF7DEDE134A3
+:10A850001ED3FDD0A0EF7FF723CCB7F9493FAED48C
+:10A86000DF510D0F5BCE131F363C6CE67EE9AA0E5E
+:10A87000A6C9617C6EC801F7955CB2CB38B772EDA2
+:10A88000BF72A9CF9CF27C7C86F362A6CEA768B784
+:10A890004F0EDD5A514976C51D2AE277FADF12FBC9
+:10A8A0007F8AF3E81F77368D255137CAA9A8E0F5CE
+:10A8B00071A7450B54307EA8BAEEFD77DAFFFE2C67
+:10A8C0007A3FC167A766903E3BF24295B4EFB1B2C2
+:10A8D0000999D65742FC4901E58FD57D584CFAAD10
+:10A8E000EC7A99F1FE4A83F7FF0B5EE93819F825F7
+:10A8F000ED9EC8A53EFA7F859B1137FF01F8EF3F1B
+:10A90000E3801A00000000000000000000000000CA
+:10A9100000000040000000000000000000000040B7
+:10A9200000000000000000000000002800000000FF
+:10A930000000000000000010000000000000000007
+:10A9400000000040000000000000000000000010B7
+:10A9500000000000000000000000000800000000EF
+:10A9600000000000000000000000000000000000E7
+:10A9700000000000000000000000000000000000D7
+:10A9800000000000000000000000000000000000C7
+:10A9900000000000000000000000000000000000B7
+:10A9A00000000000000000000000000000000000A7
+:10A9B0000000000000000000000000000000000097
+:10A9C0000000000000000000000000000000000087
+:10A9D0000000000000000000000000000000000077
+:10A9E0000000000000000000000000000000000067
+:10A9F0000000000000000000000000000000000057
+:10AA00000000000000000000000000000000000046
+:10AA10000000000000000000000000000000000036
+:10AA20000000000000000000000000000000000026
+:10AA30000000000000000000000000000000000016
+:10AA40000000000000000000000000000000000006
+:10AA500000000000000000000000000000000000F6
+:10AA600000000000000000000000000000000000E6
+:10AA70000000000000000000000090000010000036
+:10AA80000000000800009008001000000000000214
+:10AA90000000900000100000000000108000000086
+:10AAA0000000000000000000800000000000000026
+:10AAB0000000000080000000000000000000000016
+:10AAC000800000000000000000000000000093B8BB
+:10AAD0000001000400000001000093C0000000001D
+:10AAE00000000002000093C8000000000000000801
+:10AAF000000093CC0000000000000002000093D092
+:10AB00000000000000000008000097200040000046
+:10AB100000000040000093E00080000000000048BA
+:10AB2000000094E00040000000000008000094F0E5
+:10AB300000400000000000180000A00000280000F5
+:10AB4000000000280000C0C0000800000000000154
+:10AB50000000C0C100080000000000010000C0C2E9
+:10AB600000080000000000010000200800100000A4
+:10AB7000000000100000200000000000000000089D
+:10AB80008000000000000000000000000000000045
+:10AB900000000000000000000000000000000000B5
+:10ABA00000000000000000000000000000000000A5
+:10ABB0000000000000000000000000000000000095
+:10ABC0000000000000000000000000000000000085
+:10ABD0000000000000000000000000000000000075
+:10ABE0000000000000000000000000000000000065
+:10ABF0000000000000000000000000000000000055
+:10AC00000000000000000000000000000000000044
+:10AC10000000000000000000000000000000000034
+:10AC20000000000000000000000000000000000024
+:10AC30000000000000000000000000000000000014
+:10AC40008000000000000000000000008000000004
+:10AC50000000000000000000800000000000000074
+:10AC60000000000080000000000000000000000064
+:10AC700080000000000000000000000080000000D4
+:10AC80000000000000000000800000000000000044
+:10AC90000000000080000000000000000000000034
+:10ACA00080000000000000000000000080000000A4
+:10ACB0000000000000000000800000000000000014
+:10ACC0000000000080000000000000000000000004
+:10ACD0000000000000000000000000000000000074
+:10ACE0000000000000000000000000000000000064
+:10ACF0000000000000000000000000000000000054
+:10AD000000000000000000000000000080000000C3
+:10AD100000000000000000008000000000000000B3
+:10AD200000000000800000000000000000000000A3
+:10AD30000000000000000000000000008000000093
+:10AD40000000000000000000800000000000000083
+:10AD50000000000080000000000000000000000073
+:10AD600000000000000000000000000000000000E3
+:10AD700000000000000000000000000000000000D3
+:10AD800000000000000000000000000000000000C3
+:10AD900000000000000000000000000000000000B3
+:10ADA0000000000000000000800000000000000023
+:10ADB0000000000000000000000000000000000093
+:10ADC00000001EC80000000000000008000020086D
+:10ADD0000010000000000010000020000000000033
+:10ADE00000000008800000000000000000000000DB
+:10ADF00080000000000000000000000000000000D3
+:10AE00000000000000000000000000000000000042
+:10AE1000000000000000A080000800000000000109
+:10AE20000000A08100080000000000010000A082D6
+:10AE300000080000000000010000907000380000D1
+:10AE40000000003800001ED80000000000000002D2
+:10AE500000001EDA00000000000000028000000078
+:10AE60000000000000000000800000000000000062
+:10AE70000000000080000000000000000000000052
+:10AE800080000000000000000000000080000000C2
+:10AE90000000000000000000800000000000000032
+:10AEA0000000000080000000000000000000000022
+:10AEB0008000000000000000000000008000000092
+:10AEC0000000000000000000000000000000000082
+:10AED0000000000000000000000000000000000072
+:10AEE0000000000000000000000000000000000062
+:10AEF0000000000000000000000000000000000052
+:10AF000000000000800000000000000000000000C1
+:10AF100080000000000000000000000000000000B1
+:10AF200000000000000000008000000000000000A1
+:10AF30000000000080000000000000000000000091
+:10AF40008000000000000000000000008000000001
+:10AF50000000000000000000800000000000000071
+:10AF60000000000080000000000000000000000061
+:10AF70000000C00000400000000000400000C800C9
+:10AF800000400000000000400000C82E004000000B
+:10AF9000000000010000C8000040000200000001A5
+:10AFA0000000C80100400002000000000000800016
+:10AFB0000040000000000040800000000000000091
+:10AFC00000000000000080000008004000000004B5
+:10AFD0000000800400080040000000040000B000F1
+:10AFE00000280000000000280000B1400010000010
+:10AFF000000000100000B14A001000000000000135
+:10B000000000880000800000000000800000880030
+:10B01000000800800000000200008C0000400000DA
+:10B020000000004000002008001000000000001098
+:10B030000000200000000000000000080000125086
+:10B04000000800000000000100001251000800008C
+:10B050000000000100001252000800000000000182
+:10B0600000008E0000100004000000040000129098
+:10B070000030001800000010000012980030001886
+:10B08000000000028000000000000000000000003E
+:10B0900080000000000000000000000080000000B0
+:10B0A0000000000000000000800000000000000020
+:10B0B0000000000080000000000000000000000010
+:10B0C0008000000000000000000000008000000080
+:10B0D0000000000000000000000000000000000070
+:10B0E0000000000000000000000000000000000060
+:10B0F0000000000000000000000000000000000050
+:10B1000000000000000000008000000000000000BF
+:10B1100000000000800000000000000000000000AF
+:10B12000000000000000000000000000800000009F
+:10B13000000000000000000080000000000000008F
+:10B14000000000008000000000000000000000007F
+:10B1500080000000000000000000000080000000EF
+:10B1600000000000000000000000830800800000D4
+:10B17000000000800000000100000000000000004E
+:10B180000000200800100000000000100000200057
+:10B19000000000000000000800008500000800001A
+:10B1A000000000010000850100080000000000010F
+:10B1B000000085020008000000000001000060009F
+:10B1C000003800000000003880000000000000008F
+:10B1D000000000000000845400080000000000028D
+:10B1E0000000845600080000000000020000846493
+:10B1F00000100000000000048000000000000000BB
+:10B2000000000000800000000000000000000000BE
+:10B2100080000000000000000000000000000000AE
+:10B22000000000000000000000000000000000001E
+:10B23000000000000000000000000000000000000E
+:10B24000000000000000000000000000800000007E
+:10B25000000000000000000080000000000000006E
+:10B2600000000000000000000000000000000000DE
+:10B2700080000000000000000000000080000000CE
+:10B28000000000000000000080000000000000003E
+:10B29000000000008000000000000000000000002E
+:10B2A00080000000000000000000000000003000EE
+:10B2B00000400000000000080000300800400000CE
+:10B2C00000000020000032000020000000000020EC
+:10B2D000000037A800000000000000088000000007
+:10B2E00000000000000000008000000000000000DE
+:10B2F00000000000800000000000000000000000CE
+:10B300000000A000000000000000200000003EC17E
+:10B31000000000000000000100003EE0000000000E
+:10B320000000000200001E0000E00008000000080D
+:10B33000800000000000000000000000000040004D
+:10B3400000080000000000010000400100080000AB
+:10B35000000000010000404000080004000000025E
+:10B3600000004060000800040000000480000000AD
+:10B370000000000000000000000040000008000085
+:10B380000000000400004004000800000000000469
+:10B39000000040400000000000000008000040489D
+:10B3A0000000000000000008000080000000000015
+:10B3B00000000010000050400001000400000001E7
+:10B3C00000005000000000000000002000005008B5
+:10B3D00000100000000000040000500C00100000ED
+:10B3E00000000001000052C7000000000000000142
+:10B3F000000052C600000000000000010000300004
+:10B400000040002000000004000030040040002044
+:10B41000000000040000300800400020000000028E
+:10B420000000300A00400020000000020000300C44
+:10B4300000400020000000010000300D004000200E
+:10B44000000000010000300E00400020000000015C
+:10B450000000301000400020000000040000301404
+:10B4600000400020000000040000301800400020D0
+:10B47000000000040000301C004000200000000418
+:10B48000000050000100008000080004000050048B
+:10B4900001000080000800040000000A0000000015
+:10B4A0000000000000005068010000800000000162
+:10B4B0000000506901000080000000010000506C95
+:10B4C00001000080000000020000506E01000080BA
+:10B4D0000000000200005070010000800000000425
+:10B4E000000050740100008000000004000050665D
+:10B4F0000100008000000002000050640100008094
+:10B500000000000100005060010000800000000207
+:10B510000000506201000080000000020000505056
+:10B520000100008000000004000050540100008071
+:10B5300000000004000050580100008000000004DA
+:10B540000000505C01000080000000040000507CFE
+:10B5500001000080000000010000507D010000801B
+:10B56000000000010000401800100000000000046E
+:10B57000000040900010000000000004000040980F
+:10B580000010000000000004000041100000000056
+:10B590000000000200004112000000000000000254
+:10B5A00000004114000000000000000200004116ED
+:10B5B00000000000000000020000604000080000E1
+:10B5C00000000002000060420008000000000002CD
+:10B5D0000000604400080000000000020000604617
+:10B5E0000008000000000002000060800008000069
+:10B5F00000000008000060000008000000000002D9
+:10B60000000060020008000000000001000060046B
+:10B610000008000000000002000060C000080000F8
+:10B6200000000008000061000008000000000004A5
+:10B6300000006104000800000000000100006140FB
+:10B640000008000000000002000061440008000043
+:10B65000000000020000614200080000000000023B
+:10B66000000061800008000000000004000070007D
+:10B670000008000000000002000070020008000046
+:10B68000000000010000700400080000000000023B
+:10B69000000070400008000000000002000070443C
+:10B6A00000080000000000020000704600080000D2
+:10B6B00000000002000076600008000000000008A2
+:10B6C000000070800008000000000002000070848C
+:10B6D0000008000000000002000076A00008000042
+:10B6E0000000000800008040000800000000000189
+:10B6F00000008041000800000000000100008042BE
+:10B700000008000000000001000080430008000065
+:10B71000000000010000800000080000000000029E
+:10B72000000080020008000000000001000080040A
+:10B730000008000000000002000080C000080000B7
+:10B7400000000002000080C20008000000000002AB
+:10B75000000080C40008000000000002000080809B
+:10B7600000080000000000010000808100080000C7
+:10B7700000000001000080820008000000000001BD
+:10B7800000008083000800000000000100008084A9
+:10B790000008000000000001000080850008000093
+:10B7A0000000000100008086000800000000000189
+:10B7B00000006000000800000000000200006002BD
+:10B7C0000008000000000001000060040008000004
+:10B7D000000000020000604200C0001800000002EB
+:10B7E0000000604000C00018000000020000604C33
+:10B7F00000C00018000000080000604400C00018ED
+:10B80000000000080000605700C0001800000001A0
+:10B810000000605400C000180000000200006056E4
+:10B8200000C0001800000001000066400008000091
+:10B83000000000080000668000080000000000080A
+:10B84000000066C000080000000000088000000042
+:10B850000000000000000000800000000000000068
+:10B860000000000080000000000000000000000058
+:10B8700080000000000000000000000080000000C8
+:10B880000000000000000000800000000000000038
+:10B890000000000080000000000000000000000028
+:10B8A0008000000000000000000000008000000098
+:10B8B0000000000000000000800000000000000008
+:10B8C00000000000800000000000000000000000F8
+:10B8D0008000000000000000000000008000000068
+:10B8E00000000000000000008000000000000000D8
+:10B8F00000000000800000000000000000000000C8
+:10B900008000000000000000000000008000000037
+:10B9100000000000000000008000000000000000A7
+:10B920000000000080000000000000000000000097
+:10B930008000000000000000000000008000000007
+:10B940000000000000000000800000000000000077
+:10B950000000000080000000000000000000000067
+:10B9600080000000000000000000000080000000D7
+:10B970000000000000000000800000000000000047
+:10B980000000000080000000000000000000000037
+:10B9900080000000000000000000000080000000A7
+:10B9A0000000000000000000800000000000000017
+:10B9B0000000000080000000000000000000000007
+:10B9C0008000000000000000000000008000000077
+:10B9D00000000000000000008000000000000000E7
+:10B9E00000000000800000000000000000000000D7
+:10B9F0008000000000000000000000008000000047
+:10BA000000000000000000008000000000000000B6
+:10BA100000000000800000000000000000000000A6
+:10BA20008000000000000000000000008000000016
+:10BA30000000000000000000800000000000000086
+:10BA40000000000080000000000000000000000076
+:10BA500080000000000000000000000080000000E6
+:10BA60000000000000000000800000000000000056
+:10BA70000000000080000000000000000000000046
+:10BA800080000000000000000000000080000000B6
+:10BA90000000000000000000800000000000000026
+:10BAA0000000000080000000000000000000000016
+:10BAB0008000000000000000000000008000000086
+:10BAC00000000000000000008000000000000000F6
+:10BAD00000000000800000000000000000000000E6
+:10BAE0008000000000000000000000008000000056
+:10BAF00000000000000000008000000000000000C6
+:10BB00000000000000000000000000000000000035
+:10BB100080000000000000000000000000000000A5
+:08BB2000070C1E0000000000EC
+:00000001FF
--- zfcpdump-kernel-4.4.orig/firmware/bnx2x/bnx2x-e2-6.2.9.0.fw.ihex
+++ /dev/null
@@ -1,15473 +0,0 @@
-:1000000000005310000000680000070C000053803F
-:100010000000318000005A90000000B000008C18F1
-:100020000000C13400008CD0000000D800014E0850
-:100030000000F26400014EE800000074000241502C
-:1000400000005250000241C8000000B40002942099
-:10005000000121EC000294D800000FFC0003B6C898
-:10006000000000040003C6C8020400480000000F9E
-:1000700002040054000000450204005C0000000679
-:100080000204007000000004020400780000000078
-:100090000204007C121700000204008022170000F6
-:1000A00002040084321700000604008800000005E6
-:1000B0000204009C12150000020400A0221500009A
-:1000C000020400A432150000060400A80000000489
-:1000D000020400B802100000020400BC001000007E
-:1000E000020400C010100000020400C42010000030
-:1000F000020400C830100000020400CC40100000D0
-:10010000060400D000000003020400DC0010000020
-:10011000020400E012140000020400E422140000B3
-:10012000020400E832140000020400EC4214000053
-:10013000060400F000000003010401240000000098
-:1001400001040128000000000104012C000000004F
-:100150000104013000000000020401D00000890603
-:1001600002040258000000360204025C000000365F
-:10017000020402600810000002040264081000007B
-:1001800002040004000000FF02040008000000FF59
-:100190000204000C000000FF02040010000000FF39
-:1001A000020400140000007F02040018000000FF99
-:1001B0000204001C000000FF02040020000000FFF9
-:1001C000020400240000003E020400280000000099
-:1001D0000204002C0000003F020400300000003F39
-:1001E000020400340000003F020400380000003F19
-:1001F0000204003C0000003F020400400000003FF9
-:10020000020400440000003F020404CC000000018E
-:1002100002042008000002110204200C0000020069
-:10022000020420100000020402042014000002193D
-:100230000204201C0000FFFF020420200000FFFF3A
-:10024000020420240000FFFF020420280000FFFF1A
-:1002500002042038000000200604203C0000000FAB
-:1002600002042078000000210604207C0000000F1A
-:10027000020420B800000001060420BC0000000FAA
-:10028000020420F800000001060420FC0000003FEA
-:10029000020421F800000001060421FC0000000F08
-:1002A0000204223807FFFFFF0204223C0000007F07
-:1002B0000204224007FFFFFF020422440000003F27
-:1002C00001042248000000000104224C000000004C
-:1002D000010422500000000001042254000000002C
-:1002E00001042258000000000104225C000000000C
-:1002F00001042260000000000104226400000000EC
-:1003000001042268000000000104226C00000000CB
-:1003100001042270000000000104227400000000AB
-:1003200001042278000000000104227C000000008B
-:10033000020422C00000FFFF020422C40000FFFFED
-:10034000020422C80000FFFF020422CC0000FFFFCD
-:100350000C042000000003E80A0420000000000153
-:100360000B042000000000030605400000000D0003
-:100370000205004400000020020500480000003291
-:1003800002050090021500200205009402150020CD
-:1003900002050098000000300205009C08100000D3
-:1003A000020500A000000036020500A40000003095
-:1003B000020500A800000031020500B000000004A2
-:1003C000020500B400000005020500C000000000A6
-:1003D000020500C400000004020500D40000000172
-:1003E00002050114000000010205011C00000001CB
-:1003F00002050120000000020205020400000001C5
-:100400000205020C0000004002050210000000403E
-:100410000205021C00000020020502200000001C52
-:100420000205022400000020060502400000000A28
-:1004300004050280002000000205005000000007B3
-:1004400002050054000000070205005800000000EB
-:100450000205005C000000080205006000000001C9
-:100460000605006400000003020500D80000000635
-:100470000205000400000001020500080000000160
-:100480000205000C00000001020500100000000140
-:100490000205001400000001020500180000000120
-:1004A0000205001C00000001020500200000000100
-:1004B00002050024000000010205002800000001E0
-:1004C0000205002C000000010205003000000001C0
-:1004D00002050034000000010205003800000001A0
-:1004E0000205003C00000001020500400000000180
-:1004F000020500E00000000D020500E80000000019
-:10050000020500F000000000020500F800000000F5
-:10051000020500E40000002D020500EC00000020B0
-:10052000020500F400000020020500FC000000208D
-:10053000020500E00000001D020500E800000010B8
-:10054000020500F000000010020500F80000001095
-:10055000020500E40000003D020500EC0000003050
-:10056000020500F400000030020500FC000000302D
-:10057000020500E00000004D020500E80000004018
-:10058000020500F000000040020500F800000040F5
-:10059000020500E40000006D020500EC00000060B0
-:1005A000020500F400000060020500FC000000608D
-:1005B000020500E00000005D020500E800000050B8
-:1005C000020500F000000050020500F80000005095
-:1005D000020500E40000007D020500EC0000007050
-:1005E000020500F400000070020500FC000000702D
-:1005F0000406100002000020020600DC00000001DA
-:100600000406020000030220020600DC00000000D5
-:100610000718040000AD0000081807D800050223E1
-:10062000071C000029920000071C8000312A0A657F
-:10063000071D000034A216B0071D80002E7A23D9B2
-:10064000071E000003502F78081E07F03F02022506
-:10065000021800BC0000003001180000000000007B
-:10066000011800040000000001180008000000004C
-:100670000118000C0000000001180010000000002C
-:100680000118001400000000021800200000000102
-:1006900002180024000000020218002800000003D5
-:1006A0000218002C000000000218003000000004B6
-:1006B0000218003400000001021800380000000099
-:1006C0000218003C00000001021800400000000475
-:1006D0000218004400000000021800480000000159
-:1006E0000218004C00000003021800500000000037
-:1006F0000218005400000001021800580000000415
-:100700000218005C000000000218006000000001F8
-:1007100002180064000000030218006800000000D6
-:100720000218006C000000010218007000000004B4
-:100730000218007400000000021800780000000495
-:100740000218007C00000003061800800000000270
-:10075000021800A400007FFF021800A8000003FF99
-:1007600002180224000000000218023400000000F9
-:100770000218024C00000000021802E4000000FF12
-:100780000618100000000400021B8BC000000001CE
-:10079000021B800000000034021B80400000001893
-:1007A000021B80800000000C021B80C000000020A3
-:1007B0000C1B8300000864700A1B830000000157B3
-:1007C0000B1B83000000055F0A1B83400000000034
-:1007D0000C1B8340000002260B1B8340000000011D
-:1007E000021B838000086470021B83C00000022685
-:1007F000021B1480000000010A1B1480000000008E
-:10080000021B944000000001061B944800000002F7
-:10081000061A1000000002B3041A1ACC00010227C5
-:10082000061A1AD000000008061A2008000000C8A6
-:10083000061A200000000002041A1BF8009002288B
-:10084000061A371800000004061A371000000002CC
-:10085000061A500000000002061A500800000004AA
-:10086000061A501800000004061A50280000000460
-:10087000061A503800000004061A50480000000410
-:10088000061A505800000004061A506800000004C0
-:10089000061A507800000002041A52C0000202B882
-:1008A000061A405000000006041A4068000202BA0E
-:1008B000041A4040000402BC041A8000000102C077
-:1008C000061A800400000003041A8010000102C10F
-:1008D000061A801400000003041A8020000102C2DE
-:1008E000061A802400000003041A8030000102C3AD
-:1008F000061A803400000003041A8040000102C47C
-:10090000061A804400000003041A8050000102C54A
-:10091000061A805400000003041A8060000102C619
-:10092000061A806400000003041A8070000102C7E8
-:10093000061A807400000003041A8080000102C8B7
-:10094000061A808400000003041A8090000102C986
-:10095000061A809400000003041A80A0000102CA55
-:10096000061A80A400000003041A80B0000102CB24
-:10097000061A80B400000003041A80C0000102CCF3
-:10098000061A80C400000003041A80D0000102CDC2
-:10099000061A80D400000003041A80E0000102CE91
-:1009A000061A80E400000003041A80F0000102CF60
-:1009B000061A80F400000003041A8100000102D02E
-:1009C000061A810400000003041A8110000102D1FC
-:1009D000061A811400000003041A8120000102D2CB
-:1009E000061A812400000003041A8130000102D39A
-:1009F000061A813400000003041A8140000102D469
-:100A0000061A814400000003041A8150000102D537
-:100A1000061A815400000003041A8160000102D606
-:100A2000061A816400000003041A8170000102D7D5
-:100A3000061A817400000003041A8180000102D8A4
-:100A4000061A818400000003041A8190000102D973
-:100A5000061A819400000003041A81A0000102DA42
-:100A6000061A81A400000003041A81B0000102DB11
-:100A7000061A81B400000003041A81C0000102DCE0
-:100A8000061A81C400000003041A81D0000102DDAF
-:100A9000061A81D400000003041A81E0000102DE7E
-:100AA000061A81E400000003041A81F0000102DF4D
-:100AB000061A81F400000003041A8200000102E01B
-:100AC000061A820400000003041A8210000102E1E9
-:100AD000061A821400000003041A8220000102E2B8
-:100AE000061A822400000003041A8230000102E387
-:100AF000061A823400000003041A8240000102E456
-:100B0000061A824400000003041A8250000102E524
-:100B1000061A825400000003041A8260000102E6F3
-:100B2000061A826400000003041A8270000102E7C2
-:100B3000061A827400000003041A8280000102E891
-:100B4000061A828400000003041A8290000102E960
-:100B5000061A829400000003041A82A0000102EA2F
-:100B6000061A82A400000003041A82B0000102EBFE
-:100B7000061A82B400000003041A82C0000102ECCD
-:100B8000061A82C400000003041A82D0000102ED9C
-:100B9000061A82D400000003041A82E0000102EE6B
-:100BA000061A82E400000003041A82F0000102EF3A
-:100BB000061A82F400000003041A8300000102F008
-:100BC000061A830400000003041A8310000102F1D6
-:100BD000061A831400000003041A8320000102F2A5
-:100BE000061A832400000003041A8330000102F374
-:100BF000061A833400000003041A8340000102F443
-:100C0000061A834400000003041A8350000102F511
-:100C1000061A835400000003041A8360000102F6E0
-:100C2000061A836400000003041A8370000102F7AF
-:100C3000061A837400000003041A8380000102F87E
-:100C4000061A838400000003041A8390000102F94D
-:100C5000061A839400000003041A83A0000102FA1C
-:100C6000061A83A400000003041A83B0000102FBEB
-:100C7000061A83B400000003041A83C0000102FCBA
-:100C8000061A83C400000003041A83D0000102FD89
-:100C9000061A83D400000003041A83E0000102FE58
-:100CA000061A83E400000003041A83F0000102FF27
-:100CB000061A83F400000003041A840000010300F4
-:100CC000061A840400000003041A841000010301C2
-:100CD000061A841400000003041A84200001030291
-:100CE000061A842400000003041A84300001030360
-:100CF000061A843400000003041A8440000103042F
-:100D0000061A844400000003041A845000010305FD
-:100D1000061A845400000003041A846000010306CC
-:100D2000061A846400000003041A8470000103079B
-:100D3000061A847400000003041A8480000103086A
-:100D4000061A848400000003041A84900001030939
-:100D5000061A849400000003041A84A00001030A08
-:100D6000061A84A400000003041A84B00001030BD7
-:100D7000061A84B400000003041A84C00001030CA6
-:100D8000061A84C400000003041A84D00001030D75
-:100D9000061A84D400000003041A84E00001030E44
-:100DA000061A84E400000003041A84F00001030F13
-:100DB000061A84F400000003041A850000010310E1
-:100DC000061A850400000003041A851000010311AF
-:100DD000061A851400000003041A8520000103127E
-:100DE000061A852400000003041A8530000103134D
-:100DF000061A853400000003041A8540000103141C
-:100E0000061A854400000003041A855000010315EA
-:100E1000061A855400000003041A856000010316B9
-:100E2000061A856400000003041A85700001031788
-:100E3000061A857400000003041A85800001031857
-:100E4000061A858400000003041A85900001031926
-:100E5000061A859400000003041A85A00001031AF5
-:100E6000061A85A400000003041A85B00001031BC4
-:100E7000061A85B400000003041A85C00001031C93
-:100E8000061A85C400000003041A85D00001031D62
-:100E9000061A85D400000003041A85E00001031E31
-:100EA000061A85E400000003041A85F00001031F00
-:100EB000061A85F400000003041A860000010320CE
-:100EC000061A860400000003041A8610000103219C
-:100ED000061A861400000003041A8620000103226B
-:100EE000061A862400000003041A8630000103233A
-:100EF000061A863400000003041A86400001032409
-:100F0000061A864400000003041A865000010325D7
-:100F1000061A865400000003041A866000010326A6
-:100F2000061A866400000003041A86700001032775
-:100F3000061A867400000003041A86800001032844
-:100F4000061A868400000003041A86900001032913
-:100F5000061A869400000003041A86A00001032AE2
-:100F6000061A86A400000003041A86B00001032BB1
-:100F7000061A86B400000003041A86C00001032C80
-:100F8000061A86C400000003041A86D00001032D4F
-:100F9000061A86D400000003041A86E00001032E1E
-:100FA000061A86E400000003041A86F00001032FED
-:100FB000061A86F400000003041A870000010330BB
-:100FC000061A870400000003041A87100001033189
-:100FD000061A871400000003041A87200001033258
-:100FE000061A872400000003041A87300001033327
-:100FF000061A873400000003041A874000010334F6
-:10100000061A874400000003041A875000010335C4
-:10101000061A875400000003041A87600001033693
-:10102000061A876400000003041A87700001033762
-:10103000061A877400000003041A87800001033831
-:10104000061A878400000003041A87900001033900
-:10105000061A879400000003041A87A00001033ACF
-:10106000061A87A400000003041A87B00001033B9E
-:10107000061A87B400000003041A87C00001033C6D
-:10108000061A87C400000003041A87D00001033D3C
-:10109000061A87D400000003041A87E00001033E0B
-:1010A000061A87E400000003041A87F00001033FDA
-:1010B000061A87F400000003041A880000010340A8
-:1010C000061A880400000003041A88100001034176
-:1010D000061A881400000003041A88200001034245
-:1010E000061A882400000003041A88300001034314
-:1010F000061A883400000003041A884000010344E3
-:10110000061A884400000003041A885000010345B1
-:10111000061A885400000003041A88600001034680
-:10112000061A886400000003041A8870000103474F
-:10113000061A887400000003041A8880000103481E
-:10114000061A888400000003041A889000010349ED
-:10115000061A889400000003041A88A00001034ABC
-:10116000061A88A400000003041A88B00001034B8B
-:10117000061A88B400000003041A88C00001034C5A
-:10118000061A88C400000003041A88D00001034D29
-:10119000061A88D400000003041A88E00001034EF8
-:1011A000061A88E400000003041A88F00001034FC7
-:1011B000061A88F400000003041A89000001035095
-:1011C000061A890400000003041A89100001035163
-:1011D000061A891400000003041A89200001035232
-:1011E000061A892400000003041A89300001035301
-:1011F000061A893400000003041A894000010354D0
-:10120000061A894400000003041A8950000103559E
-:10121000061A895400000003041A8960000103566D
-:10122000061A896400000003041A8970000103573C
-:10123000061A897400000003041A8980000103580B
-:10124000061A898400000003041A899000010359DA
-:10125000061A899400000003041A89A00001035AA9
-:10126000061A89A400000003041A89B00001035B78
-:10127000061A89B400000003041A89C00001035C47
-:10128000061A89C400000003041A89D00001035D16
-:10129000061A89D400000003041A89E00001035EE5
-:1012A000061A89E400000003041A89F00001035FB4
-:1012B000061A89F400000003041A8A000001036082
-:1012C000061A8A0400000003041A8A100001036150
-:1012D000061A8A1400000003041A8A20000103621F
-:1012E000061A8A2400000003041A8A3000010363EE
-:1012F000061A8A3400000003041A8A4000010364BD
-:10130000061A8A4400000003041A8A50000103658B
-:10131000061A8A5400000003041A8A60000103665A
-:10132000061A8A6400000003041A8A700001036729
-:10133000061A8A7400000003041A8A8000010368F8
-:10134000061A8A8400000003041A8A9000010369C7
-:10135000061A8A9400000003041A8AA00001036A96
-:10136000061A8AA400000003041A8AB00001036B65
-:10137000061A8AB400000003041A8AC00001036C34
-:10138000061A8AC400000003041A8AD00001036D03
-:10139000061A8AD400000003041A8AE00001036ED2
-:1013A000061A8AE400000003041A8AF00001036FA1
-:1013B000061A8AF400000003041A8B00000103706F
-:1013C000061A8B0400000003041A8B10000103713D
-:1013D000061A8B1400000003041A8B20000103720C
-:1013E000061A8B2400000003041A8B3000010373DB
-:1013F000061A8B3400000003041A8B4000010374AA
-:10140000061A8B4400000003041A8B500001037578
-:10141000061A8B5400000003041A8B600001037647
-:10142000061A8B6400000003041A8B700001037716
-:10143000061A8B7400000003041A8B8000010378E5
-:10144000061A8B8400000003041A8B9000010379B4
-:10145000061A8B9400000003041A8BA00001037A83
-:10146000061A8BA400000003041A8BB00001037B52
-:10147000061A8BB400000003041A8BC00001037C21
-:10148000061A8BC400000003041A8BD00001037DF0
-:10149000061A8BD400000003041A8BE00001037EBF
-:1014A000061A8BE400000003041A8BF00001037F8E
-:1014B000061A8BF400000003041A8C00000103805C
-:1014C000061A8C0400000003041A8C10000103812A
-:1014D000061A8C1400000003041A8C2000010382F9
-:1014E000061A8C2400000003041A8C3000010383C8
-:1014F000061A8C3400000003041A8C400001038497
-:10150000061A8C4400000003041A8C500001038565
-:10151000061A8C5400000003041A8C600001038634
-:10152000061A8C6400000003041A8C700001038703
-:10153000061A8C7400000003041A8C8000010388D2
-:10154000061A8C8400000003041A8C9000010389A1
-:10155000061A8C9400000003041A8CA00001038A70
-:10156000061A8CA400000003041A8CB00001038B3F
-:10157000061A8CB400000003041A8CC00001038C0E
-:10158000061A8CC400000003041A8CD00001038DDD
-:10159000061A8CD400000003041A8CE00001038EAC
-:1015A000061A8CE400000003041A8CF00001038F7B
-:1015B000061A8CF400000003041A8D000001039049
-:1015C000061A8D0400000003041A8D100001039117
-:1015D000061A8D1400000003041A8D2000010392E6
-:1015E000061A8D2400000003041A8D3000010393B5
-:1015F000061A8D3400000003041A8D400001039484
-:10160000061A8D4400000003041A8D500001039552
-:10161000061A8D5400000003041A8D600001039621
-:10162000061A8D6400000003041A8D7000010397F0
-:10163000061A8D7400000003041A8D8000010398BF
-:10164000061A8D8400000003041A8D90000103998E
-:10165000061A8D9400000003041A8DA00001039A5D
-:10166000061A8DA400000003041A8DB00001039B2C
-:10167000061A8DB400000003041A8DC00001039CFB
-:10168000061A8DC400000003041A8DD00001039DCA
-:10169000061A8DD400000003041A8DE00001039E99
-:1016A000061A8DE400000003041A8DF00001039F68
-:1016B000061A8DF400000003041A8E00000103A036
-:1016C000061A8E0400000003041A8E10000103A104
-:1016D000061A8E1400000003041A8E20000103A2D3
-:1016E000061A8E2400000003041A8E30000103A3A2
-:1016F000061A8E3400000003041A8E40000103A471
-:10170000061A8E4400000003041A8E50000103A53F
-:10171000061A8E5400000003041A8E60000103A60E
-:10172000061A8E6400000003041A8E70000103A7DD
-:10173000061A8E7400000003041A8E80000103A8AC
-:10174000061A8E8400000003041A8E90000103A97B
-:10175000061A8E9400000003041A8EA0000103AA4A
-:10176000061A8EA400000003041A8EB0000103AB19
-:10177000061A8EB400000003041A8EC0000103ACE8
-:10178000061A8EC400000003041A8ED0000103ADB7
-:10179000061A8ED400000003041A8EE0000103AE86
-:1017A000061A8EE400000003041A8EF0000103AF55
-:1017B000061A8EF400000003041A8F00000103B023
-:1017C000061A8F0400000003041A8F10000103B1F1
-:1017D000061A8F1400000003041A8F20000103B2C0
-:1017E000061A8F2400000003041A8F30000103B38F
-:1017F000061A8F3400000003041A8F40000103B45E
-:10180000061A8F4400000003041A8F50000103B52C
-:10181000061A8F5400000003041A8F60000103B6FB
-:10182000061A8F6400000003041A8F70000103B7CA
-:10183000061A8F7400000003041A8F80000103B899
-:10184000061A8F8400000003041A8F90000103B968
-:10185000061A8F9400000003041A8FA0000103BA37
-:10186000061A8FA400000003041A8FB0000103BB06
-:10187000061A8FB400000003041A8FC0000103BCD5
-:10188000061A8FC400000003041A8FD0000103BDA4
-:10189000061A8FD400000003041A8FE0000103BE73
-:1018A000061A8FE400000007041A62C0002003BF7C
-:1018B000061A1AF000000042061AAF0000000008E5
-:1018C000061AE00000000540061AD0000000007271
-:1018D000061AD24800000010061AD6B000000020F8
-:1018E000061AD47000000090061AD46800000002A6
-:1018F000061AA000000001C4061A30000000001003
-:10190000061A308000000010061A31000000001096
-:10191000061A318000000010061A33000000001281
-:10192000061A339000000070061AD4580000000216
-:10193000061AD34800000002061AD35800000020FF
-:10194000061AA710000001C4061A3040000000105B
-:10195000061A30C000000010061A314000000010C6
-:10196000061A31C000000010061A334800000012A9
-:10197000061A355000000070061AD46000000002FC
-:10198000061AD35000000002061AD3D80000002027
-:10199000021AAE2000000000061A500000000002EB
-:1019A000061A508000000012041A4000000203DFF3
-:1019B000041A63C0000203E1061A7000000000046C
-:1019C000061A320000000008021AAE2400000000CF
-:1019D000061A501000000002061A50C8000000123B
-:1019E000041A4008000203E3041A63C8000203E576
-:1019F000061A701000000004061A322000000008C9
-:101A0000021AAE2800000000061A50200000000252
-:101A1000061A511000000012041A4010000203E7D9
-:101A2000041A63D0000203E9061A702000000004C3
-:101A3000061A324000000008021AAE2C0000000016
-:101A4000061A503000000002061A51580000001219
-:101A5000041A4018000203EB041A63D8000203EDD5
-:101A6000061A703000000004061A326000000008F8
-:101A7000021AAE3000000000061A504000000002BA
-:101A8000061A51A000000012041A4020000203EFC1
-:101A9000041A63E0000203F1061A7040000000041B
-:101AA000061A328000000008021AAE34000000005E
-:101AB000061A505000000002061A51E800000012F9
-:101AC000041A4028000203F3041A63E8000203F535
-:101AD000061A705000000004061A32A00000000828
-:101AE000021AAE3800000000061A50600000000222
-:101AF000061A523000000012041A4030000203F7A8
-:101B0000041A63F0000203F9061A70600000000472
-:101B1000061A32C000000008021AAE3C00000000A5
-:101B2000061A507000000002061A527800000012D7
-:101B3000041A4038000203FB041A63F8000203FD94
-:101B4000061A707000000004061A32E00000000857
-:101B50000200A2A4000002090200A270000000001E
-:101B60000200A274000000000200A2700000000049
-:101B70000200A274000000000200A2700000000039
-:101B80000200A274000000000200A2700000000029
-:101B90000200A27400000000020100B40000000175
-:101BA000020100B800000001020100CC00000001A9
-:101BB000020100D000000001020100DC0000000171
-:101BC0000201010000000001020101040000000107
-:101BD0000201007C003000000201008400000028A7
-:101BE0000201008C0000000002010130000000042E
-:101BF0000201025C00000001020103280000000055
-:101C0000020160580000FFFF020160700000000741
-:101C10000201055400000030020100C40000000170
-:101C2000020100F800000001020100F000000001C4
-:101C3000020100800030000002010088000000283E
-:101C400002010090000000000201013400000004C5
-:101C5000020102DC000000010201032C0000000070
-:101C60000201605C0000FFFF0201607400000007D9
-:101C70000201056400000030020100C800000001FC
-:101C8000020100FC00000001020100F4000000015C
-:101C9000020C100000000028020C200800000211B5
-:101CA000020C200C00000200020C201000000204B4
-:101CB000020C201C0000FFFF020C20200000FFFF90
-:101CC000020C20240000FFFF020C20280000FFFF70
-:101CD000020C203800000000020C203C00000037FD
-:101CE000020C204000000021020C204400000020D3
-:101CF000060C20480000001D020C20BC0000000162
-:101D0000060C20C00000003F020C21BC00000001B6
-:101D1000020C21C000000001020C21C400000001DF
-:101D2000060C21C80000001C020C223807FFFFFF30
-:101D3000020C223C0000007F020C224007FFFFFF44
-:101D4000020C22440000003F010C22480000000069
-:101D5000010C224C00000000010C22500000000089
-:101D6000010C225400000000010C22580000000069
-:101D7000010C225C00000000010C22600000000049
-:101D8000010C226400000000010C22680000000029
-:101D9000010C226C00000000010C22700000000009
-:101DA000010C227400000000010C227800000000E9
-:101DB000010C227C00000000020C22D80000FFFF72
-:101DC000020C22DC0000FFFF020C22E00000FFFFFB
-:101DD000020C22E40000FFFF0C0C2000000003E8CE
-:101DE0000A0C2000000000010B0C20000000000382
-:101DF000020C400800001011020C400C0000100002
-:101E0000020C401000001004020C401400001021CD
-:101E1000020C401C0000FFFF020C40200000FFFFEE
-:101E2000020C40240000FFFF020C40280000FFFFCE
-:101E3000020C403800000046020C403C0000000C40
-:101E4000060C404000000002020C40480000001850
-:101E5000020C404C000000F0060C40500000001F37
-:101E6000020C40CC00000001060C40D00000003AFB
-:101E7000020C41B800000001060C41BC0000000348
-:101E8000020C41C800000001020C41CC000000011E
-:101E9000060C41D00000001A020C423807FFFFFF79
-:101EA000020C423C0000007F020C424007FFFFFF93
-:101EB000020C42440000003F010C424800000000B8
-:101EC000010C424C00000000010C425000000000D8
-:101ED000010C425400000000010C425800000000B8
-:101EE000010C425C00000000010C42600000000098
-:101EF000010C426400000000010C42680000000078
-:101F0000010C426C00000000010C42700000000057
-:101F1000010C427400000000010C42780000000037
-:101F2000010C427C00000000010C42800000000017
-:101F3000020C42D80000FFFF020C42DC0000FFFF51
-:101F4000020C42E00000FFFF020C42E40000FFFF31
-:101F50000C0C4000000003E80A0C400000000001E7
-:101F60000B0C400000000003060D400000000A00BA
-:101F7000020D004400000032020D008C021500200A
-:101F8000020D009002150020020D009408100000C0
-:101F9000020D009800000036020D00A000000000B5
-:101FA000020D00A400000004020D00A800000004BF
-:101FB000060D00AC00000002020D00B80000000297
-:101FC000020D00C000000001020D00C80000000268
-:101FD000020D00CC00000002020D015C00000001B7
-:101FE000020D016400000001020D01680000000202
-:101FF000020D020400000001020D020C000000208E
-:10200000020D021000000040020D0214000000400A
-:10201000020D022000000003020D0224000000183F
-:10202000060D028000000012040D0300001803FFDB
-:10203000060D03600000000C020D004C00000001C2
-:10204000020D005000000002020D005400000000CC
-:10205000020D005800000008060D005C000000049E
-:10206000020D00C400000004020D00040000000185
-:10207000020D000800000001020D000C000000012C
-:10208000020D001000000001020D0014000000010C
-:10209000020D001800000001020D001C00000001EC
-:1020A000020D002000000001020D002400000001CC
-:1020B000020D002800000001020D002C00000001AC
-:1020C000020D003000000001020D0034000000018C
-:1020D000020D003800000001020D003C000000016C
-:1020E000020D011400000009020D011C0000000A8D
-:1020F000020D012400000000020D012C0000000070
-:10210000020D013400000000020D013C0000000B34
-:10211000020D014400000000020D0118000000291A
-:10212000020D01200000002A020D012800000020FD
-:10213000020D013000000020020D013800000020D7
-:10214000020D01400000002B020D0148000000209C
-:10215000020D011400000019020D011C0000001AFC
-:10216000020D012400000010020D012C00000010DF
-:10217000020D013400000010020D013C0000001BA4
-:10218000020D014400000010020D0118000000398A
-:10219000020D01200000003A020D0128000000306D
-:1021A000020D013000000030020D01380000003047
-:1021B000020D01400000003B020D0148000000300C
-:1021C000020D011400000049020D011C0000004A2C
-:1021D000020D012400000040020D012C000000400F
-:1021E000020D013400000040020D013C0000004BD4
-:1021F000020D014400000040020D011800000069BA
-:10220000020D01200000006A020D0128000000609C
-:10221000020D013000000060020D01380000006076
-:10222000020D01400000006B020D0148000000603B
-:10223000020D011400000059020D011C0000005A9B
-:10224000020D012400000050020D012C000000507E
-:10225000020D013400000050020D013C0000005B43
-:10226000020D014400000050020D01180000007929
-:10227000020D01200000007A020D0128000000700C
-:10228000020D013000000070020D013800000070E6
-:10229000020D01400000007B020D014800000070AB
-:1022A000060E200000000800020E004C0000003264
-:1022B000020E009402150020020E00980215002064
-:1022C000020E009C00000030020E00A0081000006A
-:1022D000020E00A400000036020E00A8000000302C
-:1022E000020E00AC00000031020E00B4000000033A
-:1022F000020E00B800000000020E00C40000000042
-:10230000020E00CC00000006020E00D80000000102
-:10231000020E014400000001020E014C0000000109
-:10232000020E015000000002020E02040000000133
-:10233000020E020C00000040020E021000000040DD
-:10234000020E021C00000004020E02200000002009
-:10235000020E02240000000E020E02280000001BE4
-:10236000060E030000000012040E0280001B04177A
-:10237000060E02EC00000005020E00540000000CE6
-:10238000020E00580000000C020E005C000000006D
-:10239000020E006000000010020E00640000001039
-:1023A000060E006800000003020E00DC00000003BF
-:1023B000020E000400000001020E000800000001EF
-:1023C000020E000C00000001020E001000000001CF
-:1023D000020E001400000001020E001800000001AF
-:1023E000020E001C00000001020E0020000000018F
-:1023F000020E002400000001020E0028000000016F
-:10240000020E002C00000001020E0030000000014E
-:10241000020E003400000001020E0038000000012E
-:10242000020E003C00000001020E0040000000010E
-:10243000020E004400000001020E01100000000F17
-:10244000020E011800000000020E01200000000032
-:10245000020E012800000000020E01140000002FEF
-:10246000020E011C00000020020E012400000020CA
-:10247000020E012C00000020020E01100000001FBF
-:10248000020E011800000010020E012000000010D2
-:10249000020E012800000010020E01140000003F8F
-:1024A000020E011C00000030020E0124000000306A
-:1024B000020E012C00000030020E01100000004F3F
-:1024C000020E011800000040020E01200000004032
-:1024D000020E012800000040020E01140000006FEF
-:1024E000020E011C00000060020E012400000060CA
-:1024F000020E012C00000060020E01100000005FBF
-:10250000020E011800000050020E012000000050D1
-:10251000020E012800000050020E01140000007F8E
-:10252000020E011C00000070020E01240000007069
-:10253000020E012C000000700730040000D60000DD
-:10254000083007D80005043207340000322B0000A1
-:1025500007348000314B0C8B0735000038C518DE7E
-:10256000073580002F90271007360000268F32F5A0
-:102570000836716031D40434023000BC00000030F1
-:1025800001300000000000000130000400000000E5
-:1025900001300008000000000130000C00000000C5
-:1025A00001300010000000000130001400000000A5
-:1025B0000230002000000001023000240000000270
-:1025C00002300028000000030230002C0000000050
-:1025D000023000300000000402300034000000012E
-:1025E00002300038000000000230003C0000000112
-:1025F00002300040000000040230004400000000EF
-:1026000002300048000000010230004C00000003CE
-:1026100002300050000000000230005400000001B1
-:1026200002300058000000040230005C000000008E
-:10263000023000600000000102300064000000036E
-:1026400002300068000000000230006C0000000151
-:10265000023000700000000402300074000000002E
-:1026600002300078000000040230007C000000030B
-:102670000630008000000002023000A400007FFF4E
-:10268000023000A8000003FF023002240000000016
-:1026900002300234000000000230024C0000000052
-:1026A000023002E40000FFFF0630200000000800B6
-:1026B00002338BC000000001023380000000001ACA
-:1026C000023380400000004E023380800000001082
-:1026D000023380C0000000200C33830000086470C7
-:1026E0000A338300000001570B3383000000055FAD
-:1026F0000A338340000000000C33834000000226B0
-:102700000B338340000000010233838000086470B3
-:10271000023383C00000022602331480000000014F
-:102720000A3314800000000006328000000001021D
-:1027300006322008000000C8063220000000000217
-:1027400004328520008F04360632875C00000009C1
-:1027500006323EB00000000606323ED00000000205
-:1027600006323E800000000A04323EA8000204C582
-:1027700006323E00000000200632500000000940F2
-:102780000632400000000004043294C0000204C776
-:1027900006324110000000020632D0000000007036
-:1027A0000632DB00000000D40632DEA0000000028A
-:1027B0000632E00000000800063324000000011883
-:1027C0000632100000000188063250000000002090
-:1027D00006325100000000200632520000000020A6
-:1027E0000632530000000020063254000000002092
-:1027F000063255000000002006325600000000207E
-:102800000632570000000020063258000000002069
-:10281000063259000000002006325A000000002055
-:1028200006325B000000002006325C000000002041
-:1028300006325D000000002006325E00000000202D
-:1028400006325F0000000020063284F00000000223
-:1028500004328500000204C9063285080000000227
-:102860000632DE90000000020633286000000118E6
-:102870000632162000000188063250800000002039
-:1028800006325180000000200632528000000020F5
-:1028900006325380000000200632548000000020E1
-:1028A00006325580000000200632568000000020CD
-:1028B00006325780000000200632588000000020B9
-:1028C000063259800000002006325A8000000020A5
-:1028D00006325B800000002006325C800000002091
-:1028E00006325D800000002006325E80000000207D
-:1028F00006325F8000000020063284F800000002EB
-:1029000004328510000204CB063285180000000254
-:102910000632DE98000000020232845000000000FF
-:102920000632401000000002023284540000000011
-:1029300006324020000000020232845800000000ED
-:1029400006324030000000020232845C00000000C9
-:1029500006324040000000020232846000000000A5
-:102960000632405000000002023284640000000081
-:10297000063240600000000202328468000000005D
-:1029800006324070000000020232846C0000000039
-:10299000063240800000000207200400007300009F
-:1029A00008200780001004CD072400002AE400005E
-:1029B0000724800027670ABA0824D35063FC04CF99
-:1029C000022000BC000000300120000000000000D8
-:1029D00001200004000000000120000800000000A9
-:1029E0000120000C00000000012000100000000089
-:1029F000012000140000000002200020000000015F
-:102A00000220002400000002022000280000000331
-:102A10000220002C00000000022000300000000412
-:102A200002200034000000010220003800000000F5
-:102A30000220003C000000010220004000000004D1
-:102A400002200044000000000220004800000001B5
-:102A50000220004C00000003022000500000000093
-:102A60000220005400000001022000580000000471
-:102A70000220005C00000000022000600000000155
-:102A80000220006400000003022000680000000033
-:102A90000220006C00000001022000700000000411
-:102AA00002200074000000000220007800000004F2
-:102AB0000220007C000000030620008000000002CD
-:102AC000022000A400007FFF022000A8000003FFF6
-:102AD0000220022400000000022002340000000056
-:102AE0000220024C00000000022002E40000FFFF70
-:102AF000062020000000080002238BC00000000117
-:102B00000223800000000010022380400000001219
-:102B10000223808000000030022380C00000000EED
-:102B20000C238300000864700A238300000001570F
-:102B30000B2383000000055F0A2383400000000090
-:102B40000C238340000002260B2383400000000179
-:102B50000223838000086470022383C000000226E1
-:102B600002231480000000010A23148000000000EA
-:102B7000062210000000004206222008000000C8C3
-:102B800006222000000000020622B00000000330F0
-:102B90000622F400000000530422F54C000104D189
-:102BA0000622F550000000030422F55C000104D267
-:102BB0000622F560000000030422F56C000104D336
-:102BC0000622F570000000030422F57C000104D405
-:102BD0000622F580000000030422F58C000104D5D4
-:102BE0000622F590000000030422F59C000104D6A3
-:102BF0000622F5A0000000030422F5AC000104D772
-:102C00000622F5B0000000030422F5BC000104D840
-:102C10000622F5C0000000460622E2000000044043
-:102C200004221240009004D906223000000000C0A7
-:102C30000622670000000100062290000000040048
-:102C400004226B0800200569062211F0000000062E
-:102C50000422120800060589062212200000000244
-:102C600006224000000005C00622C0000000000649
-:102C70000422C0180006058F0622C0300000000A9A
-:102C80000422C058000605950622C0700000000A04
-:102C90000422C0980006059B0622C0B00000000A6E
-:102CA0000422C0D8000605A10622C0F00000000AD8
-:102CB0000422C118000605A70622C1300000000A40
-:102CC0000422C158000605AD0622C1700000000AAA
-:102CD0000422C198000605B30622C1B00000000A14
-:102CE0000422C1D8000605B90622C1F00000000A7E
-:102CF0000422C218000605BF0622C2300000000AE6
-:102D00000422C258000605C50622C2700000000A4F
-:102D10000422C298000605CB0622C2B00000000AB9
-:102D20000422C2D8000605D10622C2F00000000A23
-:102D30000422C318000605D70622C3300000000A8B
-:102D40000422C358000605DD0622C3700000000AF5
-:102D50000422C398000605E30622C3B00000000A5F
-:102D60000422C3D8000605E90622C3F00000000AC9
-:102D70000422C418000605EF0622C4300000000A31
-:102D80000422C458000605F50622C4700000000A9B
-:102D90000422C498000605FB0622C4B00000000A05
-:102DA0000422C4D8000606010622C4F00000000A6E
-:102DB0000422C518000606070622C5300000000AD6
-:102DC0000422C5580006060D0622C5700000000A40
-:102DD0000422C598000606130622C5B00000000AAA
-:102DE0000422C5D8000606190622C5F00000000A14
-:102DF0000422C6180006061F0622C6300000000A7C
-:102E00000422C658000606250622C6700000000AE5
-:102E10000422C6980006062B0622C6B00000000A4F
-:102E20000422C6D8000606310622C6F00000000AB9
-:102E30000422C718000606370622C7300000000A21
-:102E40000422C7580006063D0622C7700000000A8B
-:102E50000422C798000606430622C7B00000000AF5
-:102E60000422C7D8000606490622C7F00000000A5F
-:102E70000422C8180006064F0622C8300000000AC7
-:102E80000422C858000606550622C8700000000A31
-:102E90000422C8980006065B0622C8B00000000A9B
-:102EA0000422C8D8000606610622C8F00000000A05
-:102EB0000422C918000606670622C9300000000A6D
-:102EC0000422C9580006066D0622C9700000000AD7
-:102ED0000422C998000606730622C9B00000000A41
-:102EE0000422C9D8000606790622C9F00000000AAB
-:102EF0000422CA180006067F0622CA300000000A13
-:102F00000422CA58000606850622CA700000000A7C
-:102F10000422CA980006068B0622CAB00000000AE6
-:102F20000422CAD8000606910622CAF00000000A50
-:102F30000422CB18000606970622CB300000000AB8
-:102F40000422CB580006069D0622CB700000000A22
-:102F50000422CB98000606A30622CBB00000000A8C
-:102F60000422CBD8000606A90622CBF00000000AF6
-:102F70000422CC18000606AF0622CC300000000A5E
-:102F80000422CC58000606B50622CC700000000AC8
-:102F90000422CC98000606BB0622CCB00000000A32
-:102FA0000422CCD8000606C10622CCF00000000A9C
-:102FB0000422CD18000606C70622CD300000000A04
-:102FC0000422CD58000606CD0622CD700000000A6E
-:102FD0000422CD98000606D30622CDB00000000AD8
-:102FE0000422CDD8000606D90622CDF00000000A42
-:102FF0000422CE18000606DF0622CE300000000AAA
-:103000000422CE58000606E50622CE700000000A13
-:103010000422CE98000606EB0622CEB00000000A7D
-:103020000422CED8000606F10622CEF00000000AE7
-:103030000422CF18000606F70622CF300000000A4F
-:103040000422CF58000606FD0622CF700000000AB9
-:103050000422CF98000607030622CFB00000000A22
-:103060000422CFD8000607090622CFF00000000A8C
-:103070000422D0180006070F0622D0300000000AF4
-:103080000422D058000607150622D0700000000A5E
-:103090000422D0980006071B0622D0B00000000AC8
-:1030A0000422D0D8000607210622D0F00000000A32
-:1030B0000422D118000607270622D1300000000A9A
-:1030C0000422D1580006072D0622D1700000000A04
-:1030D0000422D198000607330622D1B00000000A6E
-:1030E0000422D1D8000607390622D1F00000000AD8
-:1030F0000422D2180006073F0622D2300000000A40
-:103100000422D258000607450622D2700000000AA9
-:103110000422D2980006074B0622D2B00000000A13
-:103120000422D2D8000607510622D2F00000000A7D
-:103130000422D318000607570622D3300000000AE5
-:103140000422D3580006075D0622D3700000000A4F
-:103150000422D398000607630622D3B00000000AB9
-:103160000422D3D8000607690622D3F00000000A23
-:103170000422D4180006076F0622D4300000000A8B
-:103180000422D458000607750622D4700000000AF5
-:103190000422D4980006077B0622D4B00000000A5F
-:1031A0000422D4D8000607810622D4F00000000AC9
-:1031B0000422D518000607870622D5300000000A31
-:1031C0000422D5580006078D0622D5700000000A9B
-:1031D0000422D598000607930622D5B00000000A05
-:1031E0000422D5D8000607990622D5F00000000A6F
-:1031F0000422D6180006079F0622D6300000000AD7
-:103200000422D658000607A50622D6700000000A40
-:103210000422D698000607AB0622D6B00000000AAA
-:103220000422D6D8000607B10622D6F00000000A14
-:103230000422D718000607B70622D7300000000A7C
-:103240000422D758000607BD0622D7700000000AE6
-:103250000422D798000607C30622D7B00000000A50
-:103260000422D7D8000607C90622D7F00000000ABA
-:103270000422D818000607CF0622D8300000000A22
-:103280000422D858000607D50622D8700000000A8C
-:103290000422D898000607DB0622D8B00000000AF6
-:1032A0000422D8D8000607E10622D8F00000000A60
-:1032B0000422D918000607E70622D9300000000AC8
-:1032C0000422D958000607ED0622D9700000000A32
-:1032D0000422D998000607F30622D9B00000000A9C
-:1032E0000422D9D8000607F90622D9F00000000A06
-:1032F0000422DA18000607FF0622DA300000000A6E
-:103300000422DA58000608050622DA700000000AD6
-:103310000422DA980006080B0622DAB00000000A40
-:103320000422DAD8000608110622DAF00000000AAA
-:103330000422DB18000608170622DB300000000A12
-:103340000422DB580006081D0622DB700000000A7C
-:103350000422DB98000608230622DBB00000000AE6
-:103360000422DBD8000608290622DBF00000000A50
-:103370000422DC180006082F0622DC300000000AB8
-:103380000422DC58000608350622DC700000000A22
-:103390000422DC980006083B0622DCB00000000A8C
-:1033A0000422DCD8000608410622DCF00000000AF6
-:1033B0000422DD18000608470622DD300000000A5E
-:1033C0000422DD580006084D0622DD700000000AC8
-:1033D0000422DD98000608530622DDB00000000A32
-:1033E0000422DDD8000608590622DDF00000000A9C
-:1033F0000422DE180006085F0622DE300000000A04
-:103400000422DE58000608650622DE700000000A6D
-:103410000422DE980006086B0622DEB00000000AD7
-:103420000422DED8000608710622DEF00000000A41
-:103430000422DF18000608770622DF300000000AA9
-:103440000422DF580006087D0622DF700000000A13
-:103450000422DF98000608830622DFB00000000A7D
-:103460000422DFD8000608890622DFF00000000AE7
-:103470000422E0180006088F0622E0300000000A4F
-:103480000422E058000608950622E0700000000AB9
-:103490000422E0980006089B0622E0B00000000A23
-:1034A0000422E0D8000608A10622E0F00000000A8D
-:1034B0000422E118000608A70622E1300000000AF5
-:1034C0000422E158000608AD0622E1700000000A5F
-:1034D0000422E198000608B30622E1B00000000AC9
-:1034E0000422E1D8000608B90622E1F00000000439
-:1034F0000622153800000002062211E80000000232
-:103500000622F3000000000802221148000000001B
-:1035100006225900000000060622330000000002C7
-:1035200006226040000000300622F3200000000860
-:103530000222114C0000000006225918000000066B
-:10354000062233080000000206226100000000305D
-:103550000622F34000000008022211500000000083
-:103560000622593000000006062233100000000237
-:10357000062261C0000000300622F360000000084F
-:1035800002221154000000000622594800000006E3
-:10359000062233180000000206226280000000307C
-:1035A0000622F380000000080222115800000000EB
-:1035B00006225960000000060622332000000002A7
-:1035C00006226340000000300622F3A0000000083D
-:1035D0000222115C0000000006225978000000065B
-:1035E000062233280000000206226400000000309A
-:1035F0000622F3C000000008022211600000000053
-:103600000622599000000006062233300000000216
-:10361000062264C0000000300622F3E0000000082B
-:103620000222116400000000062259A800000006D2
-:1036300006223338000000020622658000000030B8
-:103640000216100000000028021700080000000207
-:103650000217002C000000030217003C00000004C9
-:10366000021700440000000002170048000000029A
-:103670000217004C0000009002170050000000905C
-:103680000217005400800090021700580810000034
-:10369000021700700000000602170078000009FF02
-:1036A0000217007C0000076C021701C4081000001C
-:1036B0000217034400000001021704000000008A02
-:1036C00002170404000000800217040800000081B3
-:1036D0000217040C00000080021704100000008A8A
-:1036E0000217041400000080021704180000008173
-:1036F0000217041C00000080021704300000008A3A
-:103700000217043400000080021704380000008112
-:103710000217043C00000080021704400000008AE9
-:1037200002170444000000800217044800000081D2
-:103730000217044C00000080021704800000008A79
-:103740000217048400000080021704880000008132
-:103750000217048C0000008002170038007C10045F
-:10376000021700040000000F021701EC0000000225
-:10377000021701F400000002021701EC0000000231
-:10378000021701F400000002021701EC0000000221
-:10379000021701F400000002021701EC0000000211
-:1037A000021701F400000002021701EC0000000201
-:1037B000021701F400000002021701EC00000002F1
-:1037C000021701F400000002021701EC00000002E1
-:1037D000021701F400000002021701EC00000002D1
-:1037E000021701F400000002061640240000000247
-:1037F000021640700000001C021642080000000182
-:1038000002164210000000010216422000000001D2
-:10381000021642280000000102164230000000019A
-:103820000216423800000001021642600000000249
-:103830000C16401C0003D0900A16401C0000009C8F
-:103840000B16401C000002710216403000000028D8
-:10385000021640340000002C0216403800000030F0
-:103860000216404400000020021640000000000143
-:10387000021640D8000000010216400800000001B6
-:103880000216400C0000000102164010000000016A
-:1038900002164240000000000216424800000000EC
-:1038A000061642700000000202164250000000009E
-:1038B0000216425800000000061642800000000276
-:1038C00002166008000012140216600C00001200BC
-:1038D00002166010000012040216601C0000FFFFB8
-:1038E000021660200000FFFF021660240000FFFFA8
-:1038F000021660280000FFFF02166038000000205A
-:103900000216603C00000010061660400000000235
-:1039100002166048000000230216604C00000024DC
-:1039200002166050000000250216605400000026B8
-:1039300002166058000000270216605C00000011AB
-:103940000216606000000000021660640000002B98
-:10395000021660680000002C0216606C0000002D4A
-:1039600002166070000000EC021660740000000097
-:1039700002166078000000290216607C0000002A10
-:10398000021660800000002F061660840000000D03
-:10399000021660B800000001061660BC00000008B6
-:1039A000021660DC00000001061660E00000000462
-:1039B000021660F000000001061660F4000000032B
-:1039C0000216610000000001061661040000002DCF
-:1039D000021661B800000001061661BC0000000874
-:1039E000021661DC00000001061661E00000000420
-:1039F000021661F000000001061661F400000003E9
-:103A00000216620000000001061662040000000DAC
-:103A10000216623807FFFFFF0216623C0000007FBB
-:103A20000216624007FFFFFF021662440000003FDB
-:103A300001166248000000000116624C0000000000
-:103A400001166250000000000116625400000000E0
-:103A500001166258000000000116625C00000000C0
-:103A600001166260000000000116626400000000A0
-:103A700001166268000000000116626C0000000080
-:103A80000116627000000000011662740000000060
-:103A900001166278000000000116627C0000000040
-:103AA000011662D400000000021662D80000FFFF79
-:103AB000021662DC0000FFFF021662E00000FFFF5A
-:103AC000021662E40000FFFF0C166000000003E82D
-:103AD0000A166000000000010B16600000000003E1
-:103AE0000216804000000006021680440000000517
-:103AF000021680480000000A0216804C00000005F3
-:103B00000216805400000002021680CC000000045F
-:103B1000021680D000000004021680D400000004C9
-:103B2000021680D800000004021680DC00000004A9
-:103B3000021680E000000004021680E40000000489
-:103B4000021680E800000004021688040000000647
-:103B5000021680300000007C021680340000003D18
-:103B6000021680380000003F0216803C0000009CD6
-:103B70000216E6E8000060000216E6EC00006000B5
-:103B80000216E6F0000060000216E6F40000600095
-:103B900002168234000025E40216823800008000FC
-:103BA00002168094000025E3021681F400000C0840
-:103BB000021681F800000040021681FC000001009E
-:103BC0000216820000000020021682040000001786
-:103BD00002168208000000800216820C000002001B
-:103BE00002168210000000000216823C0000001342
-:103BF00002168220008F008F0216821C008F008F19
-:103C0000021680F0000000070216821801FF01FF73
-:103C10000216821401FF01FF061680F40000000264
-:103C20000216811C0000000502168120000000051C
-:103C300002168124000000050216812800000008F9
-:103C40000216812C000000060216813000000007D9
-:103C50000616813400000004021680FC00000000FB
-:103C600006168144000000020216814C0000000488
-:103C7000021681500000000102168154000000026B
-:103C800002168158000000050216815C0000000544
-:103C90000216816000000005021681640000000524
-:103CA0000216816800000008021681000000000072
-:103CB0000216816C000000060216817000000007E9
-:103CC00006168174000000060216818C00000004B4
-:103CD000021681900000000102168104000000001D
-:103CE000021681940000000202168198000000056F
-:103CF0000216819C00000005021681A0000000054C
-:103D0000021681A400000005021681A80000000828
-:103D1000021681AC00000006021681B00000000708
-:103D2000061681B40000000202168108000000009F
-:103D3000061681BC00000004021681CC00000004BD
-:103D4000021681D000000001021681D4000000029A
-:103D5000021681D800000005021681DC0000000573
-:103D6000021681E0000000050216810C000000042C
-:103D7000021681E400000005021681E80000000838
-:103D8000021681EC00000006021681F00000000718
-:103D900002168110000000010216811400000002CA
-:103DA00002168118000000050216809C0000004CDD
-:103DB000021680A00000004C061680C4000000021D
-:103DC000021680A400000000021680A80000000077
-:103DD000021680AC0000004C061680B00000000502
-:103DE0000216E6F80000020402168240003F003F7F
-:103DF00002168244003F003F061682900000000435
-:103E000002168248008000800216824C00800080EA
-:103E100002168250010001000216825401000100C6
-:103E20000616825800000002021682600040004020
-:103E30000216826400400040021682681E001E00C6
-:103E40000216826C1E001E000216827040004000A6
-:103E500002168274400040000216827880008000C2
-:103E60000216827C800080000216828020002000E2
-:103E700002168284200020000616828800000002BC
-:103E8000021680900000004B021680600000014086
-:103E900002168064000001400616808800000002BF
-:103EA00002168068000000000216806C000000000E
-:103EB00002168070000000C0061680740000000525
-:103EC0000216880C0101010102168810010120046C
-:103ED000021688142008100102168818010101201A
-:103EE0000216881C0101010102168820010120042C
-:103EF00002168824200810010216882801010120DA
-:103F00000216882C200810010216883001010120B9
-:103F100002168834010101010216883801012004CB
-:103F20000216883C20081001021688400101012079
-:103F3000021688440101010102168848010120048B
-:103F40000216E6BC000000000216E6C000000002F7
-:103F50000216E6C4000000040216E6C800000006CF
-:103F60000216E79400000001021680EC000000FF3A
-:103F700002140000000000010215C024000000002F
-:103F80000215C0EC000000010215C0F000000001A5
-:103F90000615C10000000002021400040000000128
-:103FA00002140008000000010214000C00000001CF
-:103FB000021400300000000102140034000000016F
-:103FC0000214004000000001021400440000FFFF42
-:103FD00006140004000000030214000000000000AA
-:103FE000060280000000200002020058000000329B
-:103FF000020200A003150020020200A40315002005
-:10400000020200A801000030020200AC081000000B
-:10401000020200B000000036020200B400000030CE
-:10402000020200B800000031020200BC00000002E1
-:10403000020200C000000005020200C400000002ED
-:10404000020200C800000002020200D000000007C7
-:10405000020200DC00000000020200E00000000597
-:10406000020200E400000003020200F00000000170
-:10407000020200FC00000006020201200000000015
-:104080000202013400000002020201B0000000013F
-:104090000202020C000000010202021400000001F2
-:1040A00002020218000000020202040400000001E3
-:1040B0000202040C00000040020204100000004054
-:1040C0000202041C00000004020204200000002080
-:1040D0000202042400000002020204280000002062
-:1040E000060205000000001204020480002008BF40
-:1040F000020200600000000F0202006400000007DE
-:1041000002020068000000000202006C0000000EC5
-:10411000020200700000000E06020074000000039E
-:10412000020200F40000000402020004000000018A
-:1041300002020008000000010202000C0000000161
-:104140000202001000000001020200140000000141
-:1041500002020018000000010202001C0000000121
-:104160000202002000000001020200240000000101
-:1041700002020028000000010202002C00000001E1
-:1041800002020030000000010202003400000001C1
-:1041900002020038000000010202003C00000001A1
-:1041A0000202004000000001020200440000000181
-:1041B00002020048000000010202004C0000000161
-:1041C000020200500000000102020108000000C8C5
-:1041D0000202011800000002020201C400000000F7
-:1041E000020201CC00000000020201D40000000223
-:1041F000020201DC00000002020201E4000000FFF4
-:10420000020201EC000000FF0202010000000000B9
-:104210000202010C000000C80202011C00000002A2
-:10422000020201C800000000020201D000000000EC
-:10423000020201D800000002020201E000000002B8
-:10424000020201E8000000FF020201F0000000FF8E
-:10425000020201040000002002020108000000C860
-:104260000202011800000002020201C40000000066
-:10427000020201CC00000000020201D40000000292
-:10428000020201DC00000002020201E4000000FF63
-:10429000020201EC000000FF020201000000001019
-:1042A0000202010C000000C80202011C0000000212
-:1042B000020201C800000000020201D0000000005C
-:1042C000020201D800000002020201E00000000228
-:1042D000020201E8000000FF020201F0000000FFFE
-:1042E000020201040000003002020108000000C8C0
-:1042F0000202011800000002020201C400000000D6
-:10430000020201CC00000000020201D40000000201
-:10431000020201DC00000002020201E4000000FFD2
-:10432000020201EC000000FF020201000000004058
-:104330000202010C000000C80202011C0000000281
-:10434000020201C800000000020201D000000000CB
-:10435000020201D800000002020201E00000000297
-:10436000020201E8000000FF020201F0000000FF6D
-:10437000020201040000006002020108000000C8FF
-:104380000202011800000002020201C40000000045
-:10439000020201CC00000000020201D40000000271
-:1043A000020201DC00000002020201E4000000FF42
-:1043B000020201EC000000FF0202010000000050B8
-:1043C0000202010C000000C80202011C00000002F1
-:1043D000020201C800000000020201D0000000003B
-:1043E000020201D800000002020201E00000000207
-:1043F000020201E8000000FF020201F0000000FFDD
-:1044000002020104000000700728040000B300004D
-:10441000082807B8000908DF072C000028CB000097
-:10442000072C8000365D0A33072D0000347017CB4F
-:10443000072D80003A9424E8072E000036C7338EFB
-:10444000072E80001CE94140082EC5D0274608E110
-:10445000022800BC0000003001280000000000001D
-:1044600001280004000000000128000800000000EE
-:104470000128000C000000000128001000000000CE
-:1044800001280014000000000228002000000001A4
-:104490000228002400000002022800280000000377
-:1044A0000228002C00000000022800300000000458
-:1044B000022800340000000102280038000000003B
-:1044C0000228003C00000001022800400000000417
-:1044D00002280044000000000228004800000001FB
-:1044E0000228004C000000030228005000000000D9
-:1044F00002280054000000010228005800000004B7
-:104500000228005C0000000002280060000000019A
-:104510000228006400000003022800680000000078
-:104520000228006C00000001022800700000000456
-:104530000228007400000000022800780000000437
-:104540000228007C00000003062800800000000212
-:10455000022800A400007FFF022800A8000003FF3B
-:10456000022802240000000002280234000000009B
-:104570000228024C00000000022802E40000FFFFB5
-:104580000628200000000800022B8BC0000000015C
-:10459000022B800000000000022B80400000001869
-:1045A000022B80800000000C022B80C000000066FF
-:1045B0000C2B8300000864700A2B83000000015755
-:1045C0000B2B83000000055F0A2B834000000000D6
-:1045D0000C2B8340000002260B2B834000000001BF
-:1045E000022B838000086470022B83C00000022627
-:1045F000022B1480000000010A2B14800000000030
-:10460000022B944000000001062B94480000000299
-:10461000062A9A7000000004042A9A80000408E325
-:10462000062A9A9000000002042A9A98000208E7DD
-:10463000062A900000000048062A2008000000C852
-:10464000062A200000000002062A912800000086A9
-:10465000062AC00000000120062A9348000000033B
-:10466000042A9354000108E9062A9FB000000002C2
-:10467000042A9418000208EA042A9CD0000108ECDD
-:10468000062A9CD400000011042A9D20008F08ED0A
-:10469000062A9F5C00000005042A30000002097C05
-:1046A000062A300800000100062A404000000010E1
-:1046B000042A40000010097E042A84080002098EA2
-:1046C000042ACF4000040990042ACF600002099414
-:1046D000062A9FA000000004062A60000000054092
-:1046E000062A9D1800000002062AB00000000050B3
-:1046F000062ABB7000000070062ABB68000000029A
-:10470000062AB94800000004062AD000000008006C
-:10471000062AC48000000150062A942000000032BE
-:10472000062A502000000002062A50300000000235
-:10473000062A500000000002062A50100000000265
-:10474000022A520800000001042A9AA000020996D9
-:10475000062A95B000000022042A96380001099824
-:10476000062A963C00000003062A96E0000000227C
-:10477000042A976800010999062A976C0000000333
-:10478000062A981000000022042A98980001099A2D
-:10479000062A989C00000003062A99400000002287
-:1047A000042A99C80001099B062A99CC000000033D
-:1047B000062ABB5800000002062AC9C000000150AA
-:1047C000062A94E800000032062A50280000000261
-:1047D000062A503800000002062A50080000000295
-:1047E000062A501800000002022A520C00000001A4
-:1047F000042A9AA80002099C062A96480000002272
-:10480000042A96D00001099E062A96D400000003CF
-:10481000062A977800000022042A98000001099FC8
-:10482000062A980400000003062A98A80000002227
-:10483000042A9930000109A0062A993400000003D7
-:10484000062A99D800000022042A9A60000109A1D2
-:10485000062A9A6400000003062ABB6000000002DA
-:10486000022ACF0000000000042A9AB0001009A21A
-:10487000062A50480000000E022ACF040000000063
-:10488000042A9AF0001009B2062A50800000000E97
-:10489000022ACF0800000000042A9B30001009C241
-:1048A000062A50B80000000E022ACF0C00000000BB
-:1048B000042A9B70001009D2062A50F00000000E56
-:1048C000022ACF1000000000042A9BB0001009E269
-:1048D000062A51280000000E022ACF140000000012
-:1048E000042A9BF0001009F2062A51600000000E15
-:1048F000022ACF1800000000042A9C3000100A028F
-:10490000062A51980000000E022ACF1C0000000069
-:10491000042A9C7000100A12062A51D00000000ED2
-:1049200002101008000000010210105000000001E9
-:10493000021010000003D000021010040000003D1F
-:104940000910180002000A220910110000100C22A0
-:1049500006101140000000080910116000100C3210
-:10496000061011A00000001806102400000000E04E
-:104970000210201C00000000021020200000000196
-:10498000021020C0000000020210200400000001FC
-:104990000210200800000001021030D800000001C1
-:1049A00009103C0000050C420910380000050C47B6
-:1049B0000910392000050C4C09103B0000050C5172
-:1049C000021040D400000030021040D80000003037
-:1049D00006104C00000001000210402800000010EA
-:1049E0000210404400003FFF021040580028000021
-:1049F000021040840084924A0210405800000000D7
-:104A0000021041380000000102104138000000018E
-:104A1000021041380000000102104138000000017E
-:104A2000021041380000000102104138000000016E
-:104A3000021041380000000102104138000000015E
-:104A40000212049001F680400212051400003C108E
-:104A500002120494FFFFFFFF02120498FFFFFFFF02
-:104A60000212049CFFFFFFFF021204A0FFFFFFFFE2
-:104A7000021204A4FFFFFFFF021204A8FFFFFFFFC2
-:104A8000021204ACFFFFFFFF021204B0FFFFFFFFA2
-:104A9000021204B8FFFFFFFF021204BCFFFFFFFF7A
-:104AA000021204C0FFFFFFFF021204C4FFFFFFFF5A
-:104AB000021204C8FFFFFFFF021204CCFFFFFFFF3A
-:104AC000021204D0FFFFFFFF021204D8FFFFFFFF16
-:104AD000021204DCFFFFFFFF021204E0FFFFFFFFF2
-:104AE000021204E4FFFFFFFF021204E8FFFFFFFFD2
-:104AF000021204ECFFFFFFFF021204F0FFFFFFFFB2
-:104B0000021204F4FFFFFFFF021204F8FFFFFFFF91
-:104B1000021204FCFFFFFFFF02120500FFFFFFFF70
-:104B200002120504FFFFFFFF02120508FFFFFFFF4F
-:104B30000212050CFFFFFFFF02120510FFFFFFFF2F
-:104B4000021204D4F800C000021204B4F0005000B5
-:104B500002120390000000080212039C00000008EB
-:104B6000021203A000000008021203A400000002C9
-:104B7000021203BC00000004021203C00000000582
-:104B8000021203C400000004021203D0000000005F
-:104B90000212036C00000001021201BC0000004080
-:104BA000021201C000001808021201C4000008032C
-:104BB000021201C800000803021201CC00000040EC
-:104BC000021201D000000003021201D40000080309
-:104BD000021201D800000803021201DC00000803E1
-:104BE000021201E000010003021201E400000803C8
-:104BF000021201E800000803021201EC00000003A9
-:104C0000021201F000000003021201F40000000390
-:104C1000021201F800000003021201FC0000000370
-:104C2000021202000000000302120204000000034E
-:104C300002120208000000030212020C000000032E
-:104C4000021202100000000302120214000000030E
-:104C500002120218000000030212021C00000003EE
-:104C600002120220000000030212022400000003CE
-:104C700002120228000024030212022C0000002F5E
-:104C80000212023000000009021202340000001972
-:104C900002120238000001840212023C000001836B
-:104CA0000212024000000306021202440000001932
-:104CB00002120248000000060212024C0000030625
-:104CC0000212025000000306021202540000030602
-:104CD0000212025800000C860212025C0000030659
-:104CE00002120260000003060212026400000006C5
-:104CF00002120268000000060212026C00000006A8
-:104D00000212027000000006021202740000000687
-:104D100002120278000000060212027C0000000667
-:104D20000212028000000006021202840000000647
-:104D300002120288000000060212028C0000000627
-:104D40000212029000000006021202940000000607
-:104D500002120298000000060212029C00000006E7
-:104D6000021202A000000306021202A400000013B7
-:104D7000021202A800000006021202B00000100495
-:104D8000021202B400001004021203240010644056
-:104D90000212032800106440021205B40000000152
-:104DA000021205F800000040021205FC0000001984
-:104DB00002120600000000010212066C0000000151
-:104DC000021201B000000001021207D80000000327
-:104DD000021207D800000003021207D800000003E7
-:104DE000021207D800000003021207D800000003D7
-:104DF000021207D800000003021207D800000003C7
-:104E0000021207D8000000030600A0000000000CFA
-:104E10000200A050000000000200A05400000000AA
-:104E20000200A0EC555400000200A0F05555555565
-:104E30000200A0F4000055550200A0F8F0000000A8
-:104E40000200A0FC555400000200A1005555555524
-:104E50000200A104000055550200A108F000000066
-:104E60000200A19C000000000200A1A000010000BF
-:104E70000200A1A4000050140200A1A8000000003C
-:104E80000200A6A8000000000200A6AC000000007E
-:104E90000200A6D0000000000200A45C00000C008C
-:104EA0000200A61C000000030200A070FFF55FFFD7
-:104EB0000200A0740000FFFF0200A078F00003E0F1
-:104EC0000200A07C000000000200A0800000A00002
-:104ED0000600A084000000050200A0980FE000007A
-:104EE0000600A09C000000070200A0B8000004001B
-:104EF0000600A0BC000000030200A0C800001000D3
-:104F00000600A0CC000000030200A0D80000400072
-:104F10000600A0DC000000030200A0E80001000081
-:104F20000600A22C000000040200A688000000FC7D
-:104F30000600A68C000000070200A6F40000000096
-:104F40000200A10CFF5C00000200A110FFF55FFF52
-:104F50000200A1140000FFFF0200A118F00003E00E
-:104F60000200A11C000000000200A1200000A0001F
-:104F70000600A124000000050200A1380FE0000097
-:104F80000600A13C000000070200A1580000080034
-:104F90000600A15C000000030200A16800002000E0
-:104FA0000600A16C000000030200A1780000800050
-:104FB0000600A17C000000030200A188000200009E
-:104FC0000600A23C000000040200A6B0000000FCA5
-:104FD0000600A6B4000000070200A6F800000000CA
-:104FE0000200A030000000000200A0340000000019
-:104FF0000200A038000000000200A03C00000000F9
-:105000000200A040000000000200A04400000000D8
-:105010000200A048000000000200A04C00000000B8
-:10502000020090C40000E000020090CC0000F300F9
-:10503000020090D400000003020091A000000001D3
-:105040000600917000000003020090EC0000600078
-:10505000020090F400007300020090FC00000003C6
-:10506000020091A8000000010600918800000003E2
-:10507000020091000000400002009108000053006F
-:105080000200911000000004020091AC0000000139
-:1050900006009194000000020200919C00000001B3
-:1050A000020090D800006000020090E00000730051
-:1050B000020090E800000003020091A4000000013B
-:1050C0000200917C000000010200918000000001BC
-:1050D00002009184000000000200912800000300FB
-:1050E0000200916C0003F0080200912C0000030004
-:1050F0000200913000000300020091340000030020
-:1051000002009138000003000200913C00000300FF
-:1051100002009140000003000200942C00000001F6
-:1051200002009430000000010200943400000001ED
-:105130000200942C000000010200943000000001E5
-:1051400002009434000000010200942C00000001D1
-:1051500002009430000000010200943400000001BD
-:105160000200942C000000010200943000000001B5
-:1051700002009434000000010200942C00000001A1
-:10518000020094300000000102009434000000018D
-:105190000200942C00000001020094300000000185
-:1051A00002009434000000010200942C0000000171
-:1051B000020094300000000102009434000000015D
-:1051C0000200942C00000001020094300000000155
-:1051D0000200943400000001021300780000003047
-:1051E0000213003C000061A8061301080000000340
-:1051F000021301040000000002130134000000004B
-:10520000061301080000000302130104000000005F
-:10521000021301340000000006130108000000031F
-:10522000021301040000000002130134000000001A
-:10523000061301080000000302130104000000002F
-:1052400002130134000000000613010800000003EF
-:1052500002130104000000000213013400000000EA
-:1052600006130108000000030213010400000000FF
-:1052700002130134000000000613010800000003BF
-:1052800002130104000000000213013400000000BA
-:1052900006130108000000030213010400000000CF
-:1052A0000213013400000000021100B800000001E8
-:1052B0000216E6E8000020000216E6EC00002000DE
-:1052C0000216E6F0000065550216E6F4000065558A
-:1052D00002168150000000000216817400000001D7
-:1052E00002168178000000010216817C0000000196
-:1052F0000216818000000001021681840000000176
-:105300000216818800000001021681B4000000012D
-:10531000021681B800000001021681BC00000001E5
-:10532000021681C000000001021681C400000001C5
-:10533000021681C800000001021681100000000062
-:105340000216824000BF00BF061682440000000221
-:105350000216824C00BF00BF0216E6C40000000126
-:105360000216E6C8000000030216E79400000000E1
-:10537000042ACF40000A0C56000000000000000084
-:1053800000000034000000000000000000000000E9
-:10539000000000000000000000000000000000000D
-:1053A0000000000000000000000000000034003594
-:1053B00000000000000000000000000000000000ED
-:1053C00000000000000000000000000000000000DD
-:1053D0000000000000000000003500600000000038
-:1053E00000000000000000000000000000000000BD
-:1053F00000000000000000000000000000000000AD
-:1054000000000000006000910000000000000000AB
-:1054100000910095009500990099009D009D00A1C4
-:1054200000A100A500A500A900A900AD00AD00B134
-:1054300000B100B500000000000000000000000006
-:10544000000000000000000000000000000000005C
-:1054500000000000000000000000000000B5031183
-:105460000311031B031B03250325032C032C033308
-:105470000333033A033A0341034103480348034F0C
-:10548000034F03560356035D0000000000000000B8
-:10549000000000000000000000000000000000000C
-:1054A00000000000000000000000000000000000FC
-:1054B00000000000000000000000000000000000EC
-:1054C00000000000000000000000000000000000DC
-:1054D00000000000000000000000000000000000CC
-:1054E00000000000000000000000000000000000BC
-:1054F00000000000000000000000000000000000AC
-:10550000000000000000000000000000000000009B
-:10551000000000000000000000000000000000008B
-:10552000000000000000000000000000000000007B
-:105530000000000000000000035D035E00000000AA
-:1055400000000000035E035F035F0360036003610C
-:10555000036103620362036303630364036403651B
-:10556000036503660000000000000000000000006A
-:10557000000000000000000000000000000000002B
-:10558000000000000000000000000000000000001B
-:105590000366036D036D0379037903850000000042
-:1055A00000000000000000000000000000000000FB
-:1055B00000000000000000000000000000000000EB
-:1055C00000000000000000000000000000000000DB
-:1055D00000000000000000000000000000000000CB
-:1055E00000000000000000000385038600000000AA
-:1055F00000000000000000000000000000000000AB
-:10560000000000000000000000000000000000009A
-:1056100000000000038603B100000000000000004D
-:10562000000000000000000000000000000000007A
-:10563000000000000000000000000000000000006A
-:1056400003B103E0000000000000000000000000C3
-:10565000000000000000000000000000000000004A
-:1056600000000000000000000000000003E0040F44
-:105670000000000000000000040F04160416041DC2
-:10568000041D04240424042B042B043204320439A2
-:1056900004390440044004470447047A0000000031
-:1056A00000000000047A047E047E048204820486E2
-:1056B0000486048A048A048E048E0492049204965A
-:1056C0000496049A049A04EA04EA05000500051603
-:1056D000051605180518051A051A051C051C051ED2
-:1056E000051E052005200522052205240524052682
-:1056F00005260693000000000000000006930698AF
-:105700000698069D069D06A206A206A706A706AC59
-:1057100006AC06B106B106B606B606BB06BB06BCAD
-:105720000000000000000000000000000000000079
-:105730000000000000000000000000000000000069
-:10574000000000000000000006BC06E000000000B1
-:105750000000000006E006E206E206E406E406E6D3
-:1057600006E606E806E806EA06EA06EC06EC06EEB9
-:1057700006EE06F006F00705070507080708070B01
-:105780000000000000000000000000000000000019
-:105790000000000000000000000000000000000009
-:1057A000070B074F00000000000000000000000091
-:1057B00000000000000000000000000000000000E9
-:1057C000000000000000000000000000074F07E19B
-:1057D00000000000000000000000000000000000C9
-:1057E00000000000000000000000000000000000B9
-:1057F000000000000000000007E107EF00000000CB
-:105800000000000000000000000000000000000098
-:105810000000000000000000000000000000000088
-:105820000000000007EF082C00000000000000004E
-:10583000082C08350835083E083E08470847085038
-:1058400008500859085908620862086B086B087408
-:10585000087408D508D508EA08EA08FF08FF090215
-:1058600009020905090509080908090B090B090EB0
-:10587000090E09110911091409140917091709203A
-:105880000000000000000000000000000000000018
-:105890000000000000000000000000000000000008
-:1058A00000000000000000000920092600000000A0
-:1058B00000000000000000000000000000000000E8
-:1058C00000000000000000000000000000000000D8
-:1058D000000000000926092B000000000000000065
-:1058E00000000000000000000000000000000000B8
-:1058F00000000000000000000000000000000000A8
-:10590000092B0933000000000000000009330934AE
-:10591000093409350935093609360937093709388F
-:10592000093809390939093A093A093B00000000E8
-:105930000000000000000000000000000000000067
-:105940000000000000000000000000000000000057
-:105950000000000000000000093B09AC000000004E
-:105960000000000009AC09AD09AD09AE09AE09AFF0
-:1059700009AF09B009B009B109B109B209B209B357
-:1059800009B309B409B409C809C809DB09DB09EF7F
-:1059900009EF09F009F009F109F109F209F209F337
-:1059A00009F309F409F409F509F509F609F609F707
-:1059B00009F70A1600000000000000000A160A1984
-:1059C0000A190A1C0A1C0A1F0A1F0A220A220A258F
-:1059D0000A250A280A280A2B0A2B0A2E0A2E0A3020
-:1059E00000000000000000000A300A330A330A36C3
-:1059F0000A360A390A390A3C0A3C0A3F0A3F0A4277
-:105A00000A420A450A450A480A480A4900000000B5
-:105A10000000000000000000000000000000000086
-:105A20000000000000000000000000000000000076
-:105A3000000000000A490A610000000000000000A8
-:105A40000000000000000000000000000000000056
-:105A50000000000000000000000000000000000046
-:105A60000A610A620000000000000000000000005F
-:105A70000000000000000000000000000000000026
-:105A80000000000000000000000000000000000016
-:105A9000000100000002070000030E0000041500D2
-:105AA00000051C000006230000072A000008310042
-:105AB00000093800000A3F00000B4600000C4D00B2
-:105AC000000D5400000E5B00000F62000010690022
-:105AD000001170000012770000137E000014850092
-:105AE00000158C000016930000179A000018A10002
-:105AF0000019A800001AAF00001BB600001CBD0072
-:105B0000001DC400001ECB00001FD2000000D90001
-:105B10000000200000004000000060000000800045
-:105B20000000A0000000C0000000E0000001000034
-:105B30000001200000014000000160000001800021
-:105B40000001A0000001C0000001E0000002000010
-:105B500000022000000240000002600000028000FD
-:105B60000002A0000002C0000002E00000030000EC
-:105B700000032000000340000003600000038000D9
-:105B80000003A0000003C0000003E00000040000C8
-:105B900000042000000440000004600000048000B5
-:105BA0000004A0000004C0000004E00000050000A4
-:105BB0000005200000054000000560000005800091
-:105BC0000005A0000005C0000005E0000006000080
-:105BD000000620000006400000066000000680006D
-:105BE0000006A0000006C0000006E000000700005C
-:105BF0000007200000074000000760000007800049
-:105C00000007A0000007C0000007E0000008000037
-:105C10000008200000084000000860000008800024
-:105C20000008A0000008C0000008E0000009000013
-:105C30000009200000094000000960000009800000
-:105C40000009A0000009C0000009E000000A0000EF
-:105C5000000A2000000A4000000A6000000A8000DC
-:105C6000000AA000000AC000000AE000000B0000CB
-:105C7000000B2000000B4000000B6000000B8000B8
-:105C8000000BA000000BC000000BE000000C0000A7
-:105C9000000C2000000C4000000C6000000C800094
-:105CA000000CA000000CC000000CE000000D000083
-:105CB000000D2000000D4000000D6000000D800070
-:105CC000000DA000000DC000000DE000000E00005F
-:105CD000000E2000000E4000000E6000000E80004C
-:105CE000000EA000000EC000000EE000000F00003B
-:105CF000000F2000000F4000000F6000000F800028
-:105D0000000FA000000FC000000FE0000010000016
-:105D10000010200000104000001060000010800003
-:105D20000010A0000010C0000010E00000110000F2
-:105D300000112000001140000011600000118000DF
-:105D40000011A0000011C0000011E00000120000CE
-:105D500000122000001240000012600000128000BB
-:105D60000012A0000012C0000012E00000130000AA
-:105D70000013200000134000001360000013800097
-:105D80000013A0000013C0000013E0000014000086
-:105D90000014200000144000001460000014800073
-:105DA0000014A0000014C0000014E0000015000062
-:105DB000001520000015400000156000001580004F
-:105DC0000015A0000015C0000015E000001600003E
-:105DD000001620000016400000166000001680002B
-:105DE0000016A0000016C0000016E000001700001A
-:105DF0000017200000174000001760000017800007
-:105E00000017A0000017C0000017E00000180000F5
-:105E100000182000001840000018600000188000E2
-:105E20000018A0000018C0000018E00000190000D1
-:105E300000192000001940000019600000198000BE
-:105E40000019A0000019C0000019E000001A0000AD
-:105E5000001A2000001A4000001A6000001A80009A
-:105E6000001AA000001AC000001AE000001B000089
-:105E7000001B2000001B4000001B6000001B800076
-:105E8000001BA000001BC000001BE000001C000065
-:105E9000001C2000001C4000001C6000001C800052
-:105EA000001CA000001CC000001CE000001D000041
-:105EB000001D2000001D4000001D6000001D80002E
-:105EC000001DA000001DC000001DE000001E00001D
-:105ED000001E2000001E4000001E6000001E80000A
-:105EE000001EA000001EC000001EE000001F0000F9
-:105EF000001F2000001F4000001F6000001F8000E6
-:105F0000001FA000001FC000001FE00000200000D4
-:105F100000202000002040000020600000208000C1
-:105F20000020A0000020C0000020E00000210000B0
-:105F3000002120000021400000216000002180009D
-:105F40000021A0000021C0000021E000002200008C
-:105F50000022200000224000002260000022800079
-:105F60000022A0000022C0000022E0000023000068
-:105F70000023200000234000002360000023800055
-:105F80000023A0000023C0000023E0000024000044
-:105F90000024200000244000002460000024800031
-:105FA0000024A0000024C0000024E0000025000020
-:105FB000002520000025400000256000002580000D
-:105FC0000025A0000025C0000025E00000260000FC
-:105FD00000262000002640000026600000268000E9
-:105FE0000026A0000026C0000026E00000270000D8
-:105FF00000272000002740000027600000278000C5
-:106000000027A0000027C0000027E00000280000B3
-:1060100000282000002840000028600000288000A0
-:106020000028A0000028C0000028E000002900008F
-:10603000002920000029400000296000002980007C
-:106040000029A0000029C0000029E000002A00006B
-:10605000002A2000002A4000002A6000002A800058
-:10606000002AA000002AC000002AE000002B000047
-:10607000002B2000002B4000002B6000002B800034
-:10608000002BA000002BC000002BE000002C000023
-:10609000002C2000002C4000002C6000002C800010
-:1060A000002CA000002CC000002CE000002D0000FF
-:1060B000002D2000002D4000002D6000002D8000EC
-:1060C000002DA000002DC000002DE000002E0000DB
-:1060D000002E2000002E4000002E6000002E8000C8
-:1060E000002EA000002EC000002EE000002F0000B7
-:1060F000002F2000002F4000002F6000002F8000A4
-:10610000002FA000002FC000002FE0000030000092
-:10611000003020000030400000306000003080007F
-:106120000030A0000030C0000030E000003100006E
-:10613000003120000031400000316000003180005B
-:106140000031A0000031C0000031E000003200004A
-:106150000032200000324000003260000032800037
-:106160000032A0000032C0000032E0000033000026
-:106170000033200000334000003360000033800013
-:106180000033A0000033C0000033E0000034000002
-:1061900000342000003440000034600000348000EF
-:1061A0000034A0000034C0000034E00000350000DE
-:1061B00000352000003540000035600000358000CB
-:1061C0000035A0000035C0000035E00000360000BA
-:1061D00000362000003640000036600000368000A7
-:1061E0000036A0000036C0000036E0000037000096
-:1061F0000037200000374000003760000037800083
-:106200000037A0000037C0000037E0000038000071
-:10621000003820000038400000386000003880005E
-:106220000038A0000038C0000038E000003900004D
-:10623000003920000039400000396000003980003A
-:106240000039A0000039C0000039E000003A000029
-:10625000003A2000003A4000003A6000003A800016
-:10626000003AA000003AC000003AE000003B000005
-:10627000003B2000003B4000003B6000003B8000F2
-:10628000003BA000003BC000003BE000003C0000E1
-:10629000003C2000003C4000003C6000003C8000CE
-:1062A000003CA000003CC000003CE000003D0000BD
-:1062B000003D2000003D4000003D6000003D8000AA
-:1062C000003DA000003DC000003DE000003E000099
-:1062D000003E2000003E4000003E6000003E800086
-:1062E000003EA000003EC000003EE000003F000075
-:1062F000003F2000003F4000003F6000003F800062
-:10630000003FA000003FC000003FE000003FE00170
-:1063100000000000000001FF0000020000007FF804
-:1063200000007FF800000A90000035000000000126
-:106330000000FF00000000000000FF00000000005F
-:106340000000FF00000000000000FF00000000004F
-:106350000000FF00000000000000FF00000000003F
-:106360000000FF00000000000000FF00000000002F
-:106370000000FF00000000000000FF00000000001F
-:106380000000FF00000000000000FF00000000000F
-:106390000000FF00000000000000FF0000000000FF
-:1063A0000000FF00000000000000FF0000000000EF
-:1063B0000000FF00000000000000FF0000000000DF
-:1063C0000000FF00000000000000FF0000000000CF
-:1063D0000000FF00000000000000FF0000000000BF
-:1063E0000000FF00000000000000FF0000000000AF
-:1063F0000000FF00000000000000FF00000000009F
-:106400000000FF00000000000000FF00000000008E
-:106410000000FF00000000000000FF00000000007E
-:106420000000FF00000000000000FF00000000006E
-:106430000000FF00000000000000FF00000000005E
-:106440000000FF00000000000000FF00000000004E
-:106450000000FF00000000000000FF00000000003E
-:106460000000FF00000000000000FF00000000002E
-:106470000000FF00000000000000FF00000000001E
-:106480000000FF00000000000000FF00000000000E
-:106490000000FF00000000000000FF0000000000FE
-:1064A0000000FF00000000000000FF0000000000EE
-:1064B0000000FF00000000000000FF0000000000DE
-:1064C0000000FF00000000000000FF0000000000CE
-:1064D0000000FF00000000000000FF0000000000BE
-:1064E0000000FF00000000000000FF0000000000AE
-:1064F0000000FF00000000000000FF00000000009E
-:106500000000FF00000000000000FF00000000008D
-:106510000000FF00000000000000FF00000000007D
-:106520000000FF00000000000000FF00000000006D
-:106530000000FF00000000000000FF00000000005D
-:106540000000FF00000000000000FF00000000004D
-:106550000000FF00000000000000FF00000000003D
-:106560000000FF00000000000000FF00000000002D
-:1065700000000000140AFF000000000100000000FD
-:106580000020100100000000010090000000010048
-:1065900000009002000090040000900600009008A7
-:1065A0000000900A0000900C0000900E0000901077
-:1065B0000000901200009014000090160000901847
-:1065C0000000901A0000901C0000901E0000902017
-:1065D00000009022000090240000902600009028E7
-:1065E0000000902A0000902C0000902E00009030B7
-:1065F0000000903200009034000090360000903887
-:106600000000903A0000903C0000903E0000904056
-:106610000000904200009044000090460000904826
-:106620000000904A0000904C0000904E00009050F6
-:1066300000009052000090540000905600009058C6
-:106640000000905A0000905C0000905E0000906096
-:106650000000906200009064000090660000906866
-:106660000000906A0000906C0000906E0000907036
-:106670000000907200009074000090760000907806
-:106680000000907A0000907C0000907E00009080D6
-:1066900000009082000090840000908600009088A6
-:1066A0000000908A0000908C0000908E0000909076
-:1066B0000000909200009094000090960000909846
-:1066C0000000909A0000909C0000909E000090A016
-:1066D000000090A2000090A4000090A6000090A8E6
-:1066E000000090AA000090AC000090AE000090B0B6
-:1066F000000090B2000090B4000090B6000090B886
-:10670000000090BA000090BC000090BE000090C055
-:10671000000090C2000090C4000090C6000090C825
-:10672000000090CA000090CC000090CE000090D0F5
-:10673000000090D2000090D4000090D6000090D8C5
-:10674000000090DA000090DC000090DE000090E095
-:10675000000090E2000090E4000090E6000090E865
-:10676000000090EA000090EC000090EE000090F035
-:10677000000090F2000090F4000090F6000090F805
-:10678000000090FA000090FC000090FE00009100D4
-:1067900000009102000091040000910600009108A1
-:1067A0000000910A0000910C0000910E0000911071
-:1067B0000000911200009114000091160000911841
-:1067C0000000911A0000911C0000911E0000912011
-:1067D00000009122000091240000912600009128E1
-:1067E0000000912A0000912C0000912E00009130B1
-:1067F0000000913200009134000091360000913881
-:106800000000913A0000913C0000913E0000914050
-:106810000000914200009144000091460000914820
-:106820000000914A0000914C0000914E00009150F0
-:1068300000009152000091540000915600009158C0
-:106840000000915A0000915C0000915E0000916090
-:106850000000916200009164000091660000916860
-:106860000000916A0000916C0000916E0000917030
-:106870000000917200009174000091760000917800
-:106880000000917A0000917C0000917E00009180D0
-:1068900000009182000091840000918600009188A0
-:1068A0000000918A0000918C0000918E0000919070
-:1068B0000000919200009194000091960000919840
-:1068C0000000919A0000919C0000919E000091A010
-:1068D000000091A2000091A4000091A6000091A8E0
-:1068E000000091AA000091AC000091AE000091B0B0
-:1068F000000091B2000091B4000091B6000091B880
-:10690000000091BA000091BC000091BE000091C04F
-:10691000000091C2000091C4000091C6000091C81F
-:10692000000091CA000091CC000091CE000091D0EF
-:10693000000091D2000091D4000091D6000091D8BF
-:10694000000091DA000091DC000091DE000091E08F
-:10695000000091E2000091E4000091E6000091E85F
-:10696000000091EA000091EC000091EE000091F02F
-:10697000000091F2000091F4000091F6000091F8FF
-:10698000000091FA000091FC000091FEFFFFFFFF64
-:10699000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF07
-:1069A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7
-:1069B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7
-:1069C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7
-:1069D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7
-:1069E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7
-:1069F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7
-:106A0000FFFFFFFFFFFFFFFFFFFFFFFF000000038F
-:106A100000BEBC20000000000000000500000003D4
-:106A200000BEBC20000000000000000500000003C4
-:106A300000BEBC20000000000000000500000003B4
-:106A400000BEBC20000000000000000500000003A4
-:106A500000BEBC2000000000000000050000000394
-:106A600000BEBC2000000000000000050000000384
-:106A700000BEBC2000000000000000050000000374
-:106A800000BEBC2000000000000000050000200047
-:106A9000000040C000006180000082400000A300B0
-:106AA0000000C3C00000E480000105400001260092
-:106AB000000146C000016780000188400001A90074
-:106AC0000001C9C00001EA8000020B4000022C0056
-:106AD00000024CC000026D8000028E400002AF0038
-:106AE0000002CFC00002F0800000114000008000D2
-:106AF000000103800001870000020A8000028E006E
-:106B000000031180000395000004188000049C001D
-:106B100000051F800005A300000626800006AA00CD
-:106B200000072D800007B100000834800008B8007D
-:106B300000093B800009BF00000A4280000AC6002D
-:106B4000000B4980000BCD00000C5080000CD400DD
-:106B5000000D578000005B0000007FF800007FF808
-:106B60000000022A000035000000FF0000000000C5
-:106B70000000FF00000000000000FF000000000017
-:106B80000000FF00000000000000FF000000000007
-:106B90000000FF00000000000000FF0000000000F7
-:106BA0000000FF00000000000000FF0000000000E7
-:106BB0000000FF00000000000000FF0000000000D7
-:106BC0000000FF00000000000000FF0000000000C7
-:106BD0000000FF00000000000000FF0000000000B7
-:106BE0000000FF00000000000000FF0000000000A7
-:106BF0000000FF00000000000000FF000000000097
-:106C00000000FF00000000000000FF000000000086
-:106C10000000FF00000000000000FF000000000076
-:106C20000000FF00000000000000FF000000000066
-:106C30000000FF00000000000000FF000000000056
-:106C40000000FF00000000000000FF000000000046
-:106C50000000FF00000000000000FF000000000036
-:106C60000000FF00000000000000FF000000000026
-:106C70000000FF00000000000000FF000000000016
-:106C80000000FF00000000000000FF000000000006
-:106C90000000FF00000000000000FF0000000000F6
-:106CA0000000FF00000000000000FF0000000000E6
-:106CB0000000FF00000000000000FF0000000000D6
-:106CC0000000FF00000000000000FF0000000000C6
-:106CD0000000FF00000000000000FF0000000000B6
-:106CE0000000FF00000000000000FF0000000000A6
-:106CF0000000FF00000000000000FF000000000096
-:106D00000000FF00000000000000FF000000000085
-:106D10000000FF00000000000000FF000000000075
-:106D20000000FF00000000000000FF000000000065
-:106D30000000FF00000000000000FF000000000055
-:106D40000000FF00000000000000FF000000000045
-:106D50000000FF00000000000000FF000000000035
-:106D60000000FF00000000000000FF000000000025
-:106D70000000FF00000000000000FF000000000015
-:106D80000000FF00000000000000FF000000000005
-:106D90000000FF00000000000000FF0000000000F5
-:106DA0000000FF00000019000000000000000000CB
-:106DB000FFFFFFFF000000000393870000000000BA
-:106DC0000393870000007FF800007FF800000BA30A
-:106DD00000001500000000FF000000FF000000FFA1
-:106DE000000000FF000000FF000000FF000000FFA7
-:106DF000000000FF0000FF00000000000000FF0096
-:106E0000000000000000FF00000000000000FF0084
-:106E1000000000000000FF00000000000000FF0074
-:106E2000000000000000FF00000000000000FF0064
-:106E3000000000000000FF00000000000000FF0054
-:106E4000000000000000FF00000000000000FF0044
-:106E5000000000000000FF00000000000000FF0034
-:106E6000000000000000FF00000000000000FF0024
-:106E7000000000000000FF00000000000000FF0014
-:106E8000000000000000FF00000000000000FF0004
-:106E9000000000000000FF00000000000000FF00F4
-:106EA000000000000000FF00000000000000FF00E4
-:106EB000000000000000FF00000000000000FF00D4
-:106EC000000000000000FF00000000000000FF00C4
-:106ED000000000000000FF00000000000000FF00B4
-:106EE000000000000000FF00000000000000FF00A4
-:106EF000000000000000FF00000000000000FF0094
-:106F0000000000000000FF00000000000000FF0083
-:106F1000000000000000FF00000000000000FF0073
-:106F2000000000000000FF00000000000000FF0063
-:106F3000000000000000FF00000000000000FF0053
-:106F4000000000000000FF00000000000000FF0043
-:106F5000000000000000FF00000000000000FF0033
-:106F6000000000000000FF00000000000000FF0023
-:106F7000000000000000FF00000000000000FF0013
-:106F8000000000000000FF00000000000000FF0003
-:106F9000000000000000FF00000000000000FF00F3
-:106FA000000000000000FF00000000000000FF00E3
-:106FB000000000000000FF00000000000000FF00D3
-:106FC000000000000000FF00000000000000FF00C3
-:106FD000000000000000FF00000000000000FF00B3
-:106FE000000000000000FF00000000000000FF00A3
-:106FF000000000000000FF00000000000000FF0093
-:10700000000000000000FF00000000000000FF0082
-:10701000000000000000FF00000000000000FF0072
-:10702000000000000000FF00000000000000FF0062
-:1070300000000000FFFFFFFFFFFFFFFFFFFFFFFF5C
-:10704000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50
-:10705000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40
-:10706000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30
-:10707000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20
-:10708000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10
-:10709000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00
-:1070A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0
-:1070B000FFFFFFFF00000000000028AD00002918BE
-:1070C0000000291900000005000000070000FF0073
-:1070D0000FFFFFFF0000FF000FFFFFFF000000FF9A
-:1070E0000000FF000000FF000FFFFFFF0000FF0097
-:1070F0000FFFFFFF000000FF0000FF000000FF0087
-:107100000FFFFFFF0000FF000FFFFFFF000000FF69
-:107110000000FF000000FF000FFFFFFF0000FF0066
-:107120000FFFFFFF000000FF0000FF000000FF0056
-:107130000FFFFFFF0000FF000FFFFFFF000000FF39
-:107140000000FF000000FF000FFFFFFF0000FF0036
-:107150000FFFFFFF000000FF0000FF000000FF0026
-:107160000FFFFFFF0000FF000FFFFFFF000000FF09
-:107170000000FF000000FF000FFFFFFF0000FF0006
-:107180000FFFFFFF000000FF0000FF000000FF00F6
-:107190000FFFFFFF0000FF000FFFFFFF000000FFD9
-:1071A0000000FF000000FF000FFFFFFF0000FF00D6
-:1071B0000FFFFFFF000000FF0000FF000000FF00C6
-:1071C0000FFFFFFF0000FF000FFFFFFF000000FFA9
-:1071D0000000FF000000FF000FFFFFFF0000FF00A6
-:1071E0000FFFFFFF000000FF0000FF000000FF0096
-:1071F0000FFFFFFF0000FF000FFFFFFF000000FF79
-:107200000000FF000000FF000FFFFFFF0000FF0075
-:107210000FFFFFFF000000FF0000FF000000FF0065
-:107220000FFFFFFF0000FF000FFFFFFF000000FF48
-:107230000000FF000000FF000FFFFFFF0000FF0045
-:107240000FFFFFFF000000FF0000FF000000FF0035
-:107250000FFFFFFF0000FF000FFFFFFF000000FF18
-:107260000000FF000000FF000FFFFFFF0000FF0015
-:107270000FFFFFFF000000FF0000FF000000FF0005
-:107280000FFFFFFF0000FF000FFFFFFF000000FFE8
-:107290000000FF000000FF000FFFFFFF0000FF00E5
-:1072A0000FFFFFFF000000FF0000FF000000FF00D5
-:1072B0000FFFFFFF0000FF000FFFFFFF000000FFB8
-:1072C0000000FF000000FF000FFFFFFF0000FF00B5
-:1072D0000FFFFFFF000000FF0000FF000000FF00A5
-:1072E0000FFFFFFF0000FF000FFFFFFF000000FF88
-:1072F0000000FF000000FF000FFFFFFF0000FF0085
-:107300000FFFFFFF000000FF0000FF000000FF0074
-:107310000FFFFFFF0000FF000FFFFFFF000000FF57
-:107320000000FF000000FF000FFFFFFF0000FF0054
-:107330000FFFFFFF000000FF0000FF000000FF0044
-:107340000FFFFFFF0000FF000FFFFFFF000000FF27
-:107350000000FF000000FF000FFFFFFF0000FF0024
-:107360000FFFFFFF000000FF0000FF000000FF0014
-:107370000FFFFFFF0000FF000FFFFFFF000000FFF7
-:107380000000FF000000FF000FFFFFFF0000FF00F4
-:107390000FFFFFFF000000FF0000FF000000FF00E4
-:1073A0000FFFFFFF0000FF000FFFFFFF000000FFC7
-:1073B0000000FF000000FF000FFFFFFF0000FF00C4
-:1073C0000FFFFFFF000000FF0000FF000000FF00B4
-:1073D0000FFFFFFF0000FF000FFFFFFF000000FF97
-:1073E0000000FF000000FF000FFFFFFF0000FF0094
-:1073F0000FFFFFFF000000FF0000FF000000FF0084
-:107400000FFFFFFF0000FF000FFFFFFF000000FF66
-:107410000000FF000000FF000FFFFFFF0000FF0063
-:107420000FFFFFFF000000FF0000FF000000FF0053
-:107430000FFFFFFF0000FF000FFFFFFF000000FF36
-:107440000000FF000000FF000FFFFFFF0000FF0033
-:107450000FFFFFFF000000FF0000FF000000FF0023
-:107460000FFFFFFF0000FF000FFFFFFF000000FF06
-:107470000000FF000000FF000FFFFFFF0000FF0003
-:107480000FFFFFFF000000FF0000FF000000FF00F3
-:107490000FFFFFFF0000FF000FFFFFFF000000FFD6
-:1074A0000000FF000000FF000FFFFFFF0000FF00D3
-:1074B0000FFFFFFF000000FF0000FF000000FF00C3
-:1074C0000FFFFFFF0000FF000FFFFFFF000000FFA6
-:1074D0000000FF000000FF000FFFFFFF0000FF00A3
-:1074E0000FFFFFFF000000FF0000FF000000FF0093
-:1074F0000FFFFFFF0000FF000FFFFFFF000000FF76
-:107500000000FF000000FF000FFFFFFF0000FF0072
-:107510000FFFFFFF000000FF0000FF000000FF0062
-:107520000FFFFFFF0000FF000FFFFFFF000000FF45
-:107530000000FF000000FF000FFFFFFF0000FF0042
-:107540000FFFFFFF000000FF0000FF000000FF0032
-:107550000FFFFFFF0000FF000FFFFFFF000000FF15
-:107560000000FF000000FF000FFFFFFF0000FF0012
-:107570000FFFFFFF000000FF0000FF000000FF0002
-:107580000FFFFFFF0000FF000FFFFFFF000000FFE5
-:107590000000FF000000FF000FFFFFFF0000FF00E2
-:1075A0000FFFFFFF000000FF0000FF000000FF00D2
-:1075B0000FFFFFFF0000FF000FFFFFFF000000FFB5
-:1075C0000000FF000000FF000FFFFFFF0000FF00B2
-:1075D0000FFFFFFF000000FF0000FF000000FF00A2
-:1075E0000FFFFFFF0000FF000FFFFFFF000000FF85
-:1075F0000000FF000000FF000FFFFFFF0000FF0082
-:107600000FFFFFFF000000FF0000FF000000FF0071
-:107610000FFFFFFF0000FF000FFFFFFF000000FF54
-:107620000000FF000000FF000FFFFFFF0000FF0051
-:107630000FFFFFFF000000FF0000FF000000FF0041
-:107640000FFFFFFF0000FF000FFFFFFF000000FF24
-:107650000000FF000000FF000FFFFFFF0000FF0021
-:107660000FFFFFFF000000FF0000FF000000FF0011
-:107670000FFFFFFF0000FF000FFFFFFF000000FFF4
-:107680000000FF000000FF000FFFFFFF0000FF00F1
-:107690000FFFFFFF000000FF0000FF000000FF00E1
-:1076A0000FFFFFFF0000FF000FFFFFFF000000FFC4
-:1076B0000000FF000000FF000FFFFFFF0000FF00C1
-:1076C0000FFFFFFF000000FF0000FF000000FF00B1
-:1076D0000FFFFFFF0000FF000FFFFFFF000000FF94
-:1076E0000000FF000000FF000FFFFFFF0000FF0091
-:1076F0000FFFFFFF000000FF0000FF000000FF0081
-:107700000FFFFFFF0000FF000FFFFFFF000000FF63
-:107710000000FF000000FF000FFFFFFF0000FF0060
-:107720000FFFFFFF000000FF0000FF000000FF0050
-:107730000FFFFFFF0000FF000FFFFFFF000000FF33
-:107740000000FF000000FF000FFFFFFF0000FF0030
-:107750000FFFFFFF000000FF0000FF000000FF0020
-:107760000FFFFFFF0000FF000FFFFFFF000000FF03
-:107770000000FF000000FF000FFFFFFF0000FF0000
-:107780000FFFFFFF000000FF0000FF000000FF00F0
-:107790000FFFFFFF0000FF000FFFFFFF000000FFD3
-:1077A0000000FF000000FF000FFFFFFF0000FF00D0
-:1077B0000FFFFFFF000000FF0000FF000000FF00C0
-:1077C0000FFFFFFF0000FF000FFFFFFF000000FFA3
-:1077D0000000FF000000FF000FFFFFFF0000FF00A0
-:1077E0000FFFFFFF000000FF0000FF000000FF0090
-:1077F0000FFFFFFF0000FF000FFFFFFF000000FF73
-:107800000000FF000000FF000FFFFFFF0000FF006F
-:107810000FFFFFFF000000FF0000FF000000FF005F
-:107820000FFFFFFF0000FF000FFFFFFF000000FF42
-:107830000000FF000000FF000FFFFFFF0000FF003F
-:107840000FFFFFFF000000FF0000FF000000FF002F
-:107850000FFFFFFF0000FF000FFFFFFF000000FF12
-:107860000000FF000000FF000FFFFFFF0000FF000F
-:107870000FFFFFFF000000FF0000FF000000FF00FF
-:107880000FFFFFFF0000FF000FFFFFFF000000FFE2
-:107890000000FF000000FF000FFFFFFF0000FF00DF
-:1078A0000FFFFFFF000000FF0000FF000000FF00CF
-:1078B0000FFFFFFF0000FF000FFFFFFF000000FFB2
-:1078C0000000FF000000FF000FFFFFFF0000FF00AF
-:1078D0000FFFFFFF000000FF0000FF000000FF009F
-:1078E0000FFFFFFF0000FF000FFFFFFF000000FF82
-:1078F0000000FF000000FF000FFFFFFF0000FF007F
-:107900000FFFFFFF000000FF0000FF000000FF006E
-:107910000FFFFFFF0000FF000FFFFFFF000000FF51
-:107920000000FF000000FF000FFFFFFF0000FF004E
-:107930000FFFFFFF000000FF0000FF000000FF003E
-:107940000FFFFFFF0000FF000FFFFFFF000000FF21
-:107950000000FF000000FF000FFFFFFF0000FF001E
-:107960000FFFFFFF000000FF0000FF000000FF000E
-:107970000FFFFFFF0000FF000FFFFFFF000000FFF1
-:107980000000FF000000FF000FFFFFFF0000FF00EE
-:107990000FFFFFFF000000FF0000FF000000FF00DE
-:1079A0000FFFFFFF0000FF000FFFFFFF000000FFC1
-:1079B0000000FF000000FF000FFFFFFF0000FF00BE
-:1079C0000FFFFFFF000000FF0000FF000000FF00AE
-:1079D0000FFFFFFF0000FF000FFFFFFF000000FF91
-:1079E0000000FF000000FF000FFFFFFF0000FF008E
-:1079F0000FFFFFFF000000FF0000FF000000FF007E
-:107A00000FFFFFFF0000FF000FFFFFFF000000FF60
-:107A10000000FF000000FF000FFFFFFF0000FF005D
-:107A20000FFFFFFF000000FF0000FF000000FF004D
-:107A30000FFFFFFF0000FF000FFFFFFF000000FF30
-:107A40000000FF000000FF000FFFFFFF0000FF002D
-:107A50000FFFFFFF000000FF0000FF000000FF001D
-:107A60000FFFFFFF0000FF000FFFFFFF000000FF00
-:107A70000000FF000000FF000FFFFFFF0000FF00FD
-:107A80000FFFFFFF000000FF0000FF000000FF00ED
-:107A90000FFFFFFF0000FF000FFFFFFF000000FFD0
-:107AA0000000FF000000FF000FFFFFFF0000FF00CD
-:107AB0000FFFFFFF000000FF0000FF000000FF00BD
-:107AC0000FFFFFFF0000FF000FFFFFFF000000FFA0
-:107AD0000000FF000000FF000FFFFFFF0000FF009D
-:107AE0000FFFFFFF000000FF0000FF000000FF008D
-:107AF0000FFFFFFF0000FF000FFFFFFF000000FF70
-:107B00000000FF000000FF000FFFFFFF0000FF006C
-:107B10000FFFFFFF000000FF0000FF000000FF005C
-:107B20000FFFFFFF0000FF000FFFFFFF000000FF3F
-:107B30000000FF000000FF000FFFFFFF0000FF003C
-:107B40000FFFFFFF000000FF0000FF000000FF002C
-:107B50000FFFFFFF0000FF000FFFFFFF000000FF0F
-:107B60000000FF000000FF000FFFFFFF0000FF000C
-:107B70000FFFFFFF000000FF0000FF000000FF00FC
-:107B80000FFFFFFF0000FF000FFFFFFF000000FFDF
-:107B90000000FF000000FF000FFFFFFF0000FF00DC
-:107BA0000FFFFFFF000000FF0000FF000000FF00CC
-:107BB0000FFFFFFF0000FF000FFFFFFF000000FFAF
-:107BC0000000FF000000FF000FFFFFFF0000FF00AC
-:107BD0000FFFFFFF000000FF0000FF000000FF009C
-:107BE0000FFFFFFF0000FF000FFFFFFF000000FF7F
-:107BF0000000FF000000FF000FFFFFFF0000FF007C
-:107C00000FFFFFFF000000FF0000FF000000FF006B
-:107C10000FFFFFFF0000FF000FFFFFFF000000FF4E
-:107C20000000FF000000FF000FFFFFFF0000FF004B
-:107C30000FFFFFFF000000FF0000FF000000FF003B
-:107C40000FFFFFFF0000FF000FFFFFFF000000FF1E
-:107C50000000FF000000FF000FFFFFFF0000FF001B
-:107C60000FFFFFFF000000FF0000FF000000FF000B
-:107C70000FFFFFFF0000FF000FFFFFFF000000FFEE
-:107C80000000FF000000FF000FFFFFFF0000FF00EB
-:107C90000FFFFFFF000000FF0000FF000000FF00DB
-:107CA0000FFFFFFF0000FF000FFFFFFF000000FFBE
-:107CB0000000FF000000FF000FFFFFFF0000FF00BB
-:107CC0000FFFFFFF000000FF0000FF000000FF00AB
-:107CD0000FFFFFFF0000FF000FFFFFFF000000FF8E
-:107CE0000000FF000000FF000FFFFFFF0000FF008B
-:107CF0000FFFFFFF000000FF0000FF000000FF007B
-:107D00000FFFFFFF0000FF000FFFFFFF000000FF5D
-:107D10000000FF000000FF000FFFFFFF0000FF005A
-:107D20000FFFFFFF000000FF0000FF000000FF004A
-:107D30000FFFFFFF0000FF000FFFFFFF000000FF2D
-:107D40000000FF000000FF000FFFFFFF0000FF002A
-:107D50000FFFFFFF000000FF0000FF000000FF001A
-:107D60000FFFFFFF0000FF000FFFFFFF000000FFFD
-:107D70000000FF000000FF000FFFFFFF0000FF00FA
-:107D80000FFFFFFF000000FF0000FF0000001000D9
-:107D900000002080000031000000418000005200FF
-:107DA00000006280000073000000838000009400E7
-:107DB0000000A4800000B5000000C5800000D600CF
-:107DC0000000E6800000F7000001078000011800B5
-:107DD00000012880000139000001498000015A009B
-:107DE00000016A8000017B0000018B8000019C0083
-:107DF0000001AC800001BD000001CD800001DE006B
-:107E00000001EE800001FF0000000F8000007FF8FD
-:107E100000007FF8000005F60000350010000000AB
-:107E2000000028AD000029180000291900000005F5
-:107E3000000000060001000100090206CCCCCCC9FC
-:107E40007058103C0000FF00000000000000FF0020
-:107E5000000000000000FF00000000000000FF0024
-:107E6000000000000000FF00000000000000FF0014
-:107E7000000000000000FF00000000000000FF0004
-:107E8000000000000000FF00000000000000FF00F4
-:107E9000000000000000FF00000000000000FF00E4
-:107EA000000000000000FF00000000000000FF00D4
-:107EB000000000000000FF00000000000000FF00C4
-:107EC000000000000000FF00000000000000FF00B4
-:107ED000000000000000FF00000000000000FF00A4
-:107EE000000000000000FF00000000000000FF0094
-:107EF000000000000000FF00000000000000FF0084
-:107F0000000000000000FF00000000000000FF0073
-:107F1000000000000000FF00000000000000FF0063
-:107F2000000000000000FF00000000000000FF0053
-:107F3000000000000000FF00000000000000FF0043
-:107F4000000000000000FF00000000000000FF0033
-:107F5000000000000000FF00000000000000FF0023
-:107F6000000000000000FF00000000000000FF0013
-:107F7000000000000000FF00000000000000FF0003
-:107F8000000000000000FF00000000000000FF00F3
-:107F9000000000000000FF00000000000000FF00E3
-:107FA000000000000000FF00000000000000FF00D3
-:107FB000000000000000FF00000000000000FF00C3
-:107FC000000000000000FF00000000000000FF00B3
-:107FD000000000000000FF00000000000000FF00A3
-:107FE000000000000000FF00000000000000FF0093
-:107FF000000000000000FF00000000000000FF0083
-:10800000000000000000FF00000000000000FF0072
-:10801000000000000000FF00000000000000FF0062
-:10802000000000000000FF00000000000000FF0052
-:10803000000000000000FF00000000000000FF0042
-:10804000000000000000FF00000000000000FF0032
-:10805000000000000000FF00000000000000FF0022
-:10806000000000000000FF00000000000000FF0012
-:10807000000000000000FF00000000000000FF0002
-:108080000000000000000001CCCC0201CCCCCCCC24
-:10809000CCCC0201CCCCCCCCCCCC0201CCCCCCCC4A
-:1080A000CCCC0201CCCCCCCCCCCC0201CCCCCCCC3A
-:1080B000CCCC0201CCCCCCCCCCCC0201CCCCCCCC2A
-:1080C000CCCC0201CCCCCCCC00000000FFFFFFFFE9
-:1080D000030303031342020250505020706080508B
-:1080E0000200020006040604000E0000011600D67D
-:1080F000002625A0002625A0002625A0002625A0D4
-:1081000000720000012300F3002625A0002625A010
-:10811000002625A0002625A00000FFFF000000008B
-:108120000000FFFF000000000000FFFF0000000053
-:108130000000FFFF000000000000FFFF0000000043
-:108140000000FFFF000000000000FFFF0000000033
-:108150000000FFFF000000000000FFFF0000000023
-:108160000000FFFF000000000000FFFF0000000013
-:108170000000FFFF000000000000FFFF0000000003
-:108180000000FFFF000000000000FFFF00000000F3
-:108190000000FFFF000000000000FFFF00000000E3
-:1081A0000000FFFF000000000000FFFF00000000D3
-:1081B0000000FFFF000000000000FFFF00000000C3
-:1081C0000000FFFF000000000000FFFF00000000B3
-:1081D0000000FFFF000000000000FFFF00000000A3
-:1081E0000000FFFF000000000000FFFF0000000093
-:1081F0000000FFFF000000000000FFFF0000000083
-:108200000000FFFF000000000000FFFF0000000072
-:108210000000FFFF000000000000FFFF0000000062
-:108220000000FFFF000000000000FFFF0000000052
-:108230000000FFFF000000000000FFFF0000000042
-:108240000000FFFF000000000000FFFF0000000032
-:108250000000FFFF000000000000FFFF0000000022
-:108260000000FFFF000000000000FFFF0000000012
-:108270000000FFFF000000000000FFFF0000000002
-:108280000000FFFF000000000000FFFF00000000F2
-:108290000000FFFF000000000000FFFF00000000E2
-:1082A0000000FFFF000000000000FFFF00000000D2
-:1082B0000000FFFF000000000000FFFF00000000C2
-:1082C0000000FFFF000000000000FFFF00000000B2
-:1082D0000000FFFF000000000000FFFF00000000A2
-:1082E0000000FFFF000000000000FFFF0000000092
-:1082F0000000FFFF000000000000FFFF0000000082
-:108300000000FFFF000000000000FFFF0000000071
-:108310000000FFFF00000000FFFFFFF3318FFFFFB1
-:108320000C30C30CC30C30C3CF3CF300F3CF3CF391
-:108330000000CF3CCDCDCDCDFFFFFFF130EFFFFFF3
-:108340000C30C30CC30C30C3CF3CF300F3CF3CF371
-:108350000001CF3CCDCDCDCDFFFFFFF6305FFFFF5D
-:108360000C30C30CC30C30C3CF3CF300F3CF3CF351
-:108370000002CF3CCDCDCDCDFFFFF4061CBFFFFFEB
-:108380000C30C305C30C30C3CF300014F3CF3CF323
-:108390000004CF3CCDCDCDCDFFFFFFF2304FFFFF2E
-:1083A0000C30C30CC30C30C3CF3CF300F3CF3CF311
-:1083B0000008CF3CCDCDCDCDFFFFFFFA302FFFFF22
-:1083C0000C30C30CC30C30C3CF3CF300F3CF3CF3F1
-:1083D0000010CF3CCDCDCDCDFFFFFFF731EFFFFF3C
-:1083E0000C30C30CC30C30C3CF3CF300F3CF3CF3D1
-:1083F0000020CF3CCDCDCDCDFFFFFFF5302FFFFFCF
-:108400000C30C30CC30C30C3CF3CF300F3CF3CF3B0
-:108410000040CF3CCDCDCDCDFFFFFFF3318FFFFF2F
-:108420000C30C30CC30C30C3CF3CF300F3CF3CF390
-:108430000000CF3CCDCDCDCDFFFFFFF1310FFFFFD1
-:108440000C30C30CC30C30C3CF3CF300F3CF3CF370
-:108450000001CF3CCDCDCDCDFFFFFFF6305FFFFF5C
-:108460000C30C30CC30C30C3CF3CF300F3CF3CF350
-:108470000002CF3CCDCDCDCDFFFFF4061CBFFFFFEA
-:108480000C30C305C30C30C3CF300014F3CF3CF322
-:108490000004CF3CCDCDCDCDFFFFFFF2304FFFFF2D
-:1084A0000C30C30CC30C30C3CF3CF300F3CF3CF310
-:1084B0000008CF3CCDCDCDCDFFFFFFFA302FFFFF21
-:1084C0000C30C30CC30C30C3CF3CF300F3CF3CF3F0
-:1084D0000010CF3CCDCDCDCDFFFFFFF730EFFFFF3C
-:1084E0000C30C30CC30C30C3CF3CF300F3CF3CF3D0
-:1084F0000020CF3CCDCDCDCDFFFFFFF5304FFFFFAE
-:108500000C30C30CC30C30C3CF3CF300F3CF3CF3AF
-:108510000040CF3CCDCDCDCDFFFFFFFF30CFFFFFE3
-:108520000C30C30CC30C30C3CF3CF3CCF3CF3CF3C3
-:108530000000CF3CCDCDCDCDFFFFFFFF30CFFFFF03
-:108540000C30C30CC30C30C3CF3CF3CCF3CF3CF3A3
-:108550000001CF3CCDCDCDCDFFFFFFFF30CFFFFFE2
-:108560000C30C30CC30C30C3CF3CF3CCF3CF3CF383
-:108570000002CF3CCDCDCDCDFFFFFFFF30CFFFFFC1
-:108580000C30C30CC30C30C3CF3CF3CCF3CF3CF363
-:108590000004CF3CCDCDCDCDFFFFFFFF30CFFFFF9F
-:1085A0000C30C30CC30C30C3CF3CF3CCF3CF3CF343
-:1085B0000008CF3CCDCDCDCDFFFFFFFF30CFFFFF7B
-:1085C0000C30C30CC30C30C3CF3CF3CCF3CF3CF323
-:1085D0000010CF3CCDCDCDCDFFFFFFFF30CFFFFF53
-:1085E0000C30C30CC30C30C3CF3CF3CCF3CF3CF303
-:1085F0000020CF3CCDCDCDCDFFFFFFFF30CFFFFF23
-:108600000C30C30CC30C30C3CF3CF3CCF3CF3CF3E2
-:108610000040CF3CCDCDCDCDFFFFFFF3320FFFFFAC
-:108620000C30C30CC30C30C3CF3CF300F3CF3CF38E
-:108630000000CF3CCDCDCDCDFFFFFFF1310FFFFFCF
-:108640000C30C30CC30C30C3CF3CF300F3CF3CF36E
-:108650000001CF3CCDCDCDCDFFFFFFF6305FFFFF5A
-:108660000C30C30CC30C30C3CF3CF300F3CF3CF34E
-:108670000002CF3CCDCDCDCDFFFFF4061CBFFFFFE8
-:108680000C30C305C30C30C3CF300014F3CF3CF320
-:108690000004CF3CCDCDCDCDFFFFFFF2304FFFFF2B
-:1086A0000C30C30CC30C30C3CF3CF300F3CF3CF30E
-:1086B0000008CF3CCDCDCDCDFFFFFF8A042FFFFFBB
-:1086C0000C30C30CC30C30C3CF3CC000F3CF3CF321
-:1086D0000010CF3CCDCDCDCDFFFFFF9705CFFFFFE5
-:1086E0000C30C30CC30C30C3CF3CC000F3CF3CF301
-:1086F0000020CF3CCDCDCDCDFFFFFFF5310FFFFFEB
-:108700000C30C30CC30C30C3CF3CF300F3CF3CF3AD
-:108710000040CF3CCDCDCDCDFFFFFFF3320FFFFFAB
-:108720000C30C30CC30C30C3CF3CF300F3CF3CF38D
-:108730000000CF3CCDCDCDCDFFFFFFF1302FFFFFAF
-:108740000C30C30CC30C30C3CF3CF300F3CF3CF36D
-:108750000001CF3CCDCDCDCDFFFFFFF6305FFFFF59
-:108760000C30C30CC30C30C3CF3CF300F3CF3CF34D
-:108770000002CF3CCDCDCDCDFFFFFF061CBFFFFFDC
-:108780000C30C30CC30C30C3CF3CC014F3CF3CF34C
-:108790000004CF3CCDCDCDCDFFFFFFF2304FFFFF2A
-:1087A0000C30C30CC30C30C3CF3CF300F3CF3CF30D
-:1087B0000008CF3CCDCDCDCDFFFFFFFA302FFFFF1E
-:1087C0000C30C30CC30C30C3CF3CF300F3CF3CF3ED
-:1087D0000010CF3CCDCDCDCDFFFFFFF731CFFFFF58
-:1087E0000C30C30CC30C30C3CF3CF300F3CF3CF3CD
-:1087F0000020CF3CCDCDCDCDFFFFFFFF30CFFFFF21
-:108800000C30C30CC30C30C3CF3CF3CCF3CF3CF3E0
-:108810000040CF3CCDCDCDCDFFFFFFFF30CFFFFFE0
-:108820000C30C30CC30C30C3CF3CF3CCF3CF3CF3C0
-:108830000000CF3CCDCDCDCDFFFFFFFF30CFFFFF00
-:108840000C30C30CC30C30C3CF3CF3CCF3CF3CF3A0
-:108850000001CF3CCDCDCDCDFFFFFFFF30CFFFFFDF
-:108860000C30C30CC30C30C3CF3CF3CCF3CF3CF380
-:108870000002CF3CCDCDCDCDFFFFFFFF30CFFFFFBE
-:108880000C30C30CC30C30C3CF3CF3CCF3CF3CF360
-:108890000004CF3CCDCDCDCDFFFFFFFF30CFFFFF9C
-:1088A0000C30C30CC30C30C3CF3CF3CCF3CF3CF340
-:1088B0000008CF3CCDCDCDCDFFFFFFFF30CFFFFF78
-:1088C0000C30C30CC30C30C3CF3CF3CCF3CF3CF320
-:1088D0000010CF3CCDCDCDCDFFFFFFFF30CFFFFF50
-:1088E0000C30C30CC30C30C3CF3CF3CCF3CF3CF300
-:1088F0000020CF3CCDCDCDCDFFFFFFFF30CFFFFF20
-:108900000C30C30CC30C30C3CF3CF3CCF3CF3CF3DF
-:108910000040CF3CCDCDCDCDFFFFFFFF30CFFFFFDF
-:108920000C30C30CC30C30C3CF3CF3CCF3CF3CF3BF
-:108930000000CF3CCDCDCDCDFFFFFFFF30CFFFFFFF
-:108940000C30C30CC30C30C3CF3CF3CCF3CF3CF39F
-:108950000001CF3CCDCDCDCDFFFFFFFF30CFFFFFDE
-:108960000C30C30CC30C30C3CF3CF3CCF3CF3CF37F
-:108970000002CF3CCDCDCDCDFFFFFFFF30CFFFFFBD
-:108980000C30C30CC30C30C3CF3CF3CCF3CF3CF35F
-:108990000004CF3CCDCDCDCDFFFFFFFF30CFFFFF9B
-:1089A0000C30C30CC30C30C3CF3CF3CCF3CF3CF33F
-:1089B0000008CF3CCDCDCDCDFFFFFFFF30CFFFFF77
-:1089C0000C30C30CC30C30C3CF3CF3CCF3CF3CF31F
-:1089D0000010CF3CCDCDCDCDFFFFFFFF30CFFFFF4F
-:1089E0000C30C30CC30C30C3CF3CF3CCF3CF3CF3FF
-:1089F0000020CF3CCDCDCDCDFFFFFFFF30CFFFFF1F
-:108A00000C30C30CC30C30C3CF3CF3CCF3CF3CF3DE
-:108A10000040CF3CCDCDCDCDFFFFFFFF30CFFFFFDE
-:108A20000C30C30CC30C30C3CF3CF3CCF3CF3CF3BE
-:108A30000000CF3CCDCDCDCDFFFFFFFF30CFFFFFFE
-:108A40000C30C30CC30C30C3CF3CF3CCF3CF3CF39E
-:108A50000001CF3CCDCDCDCDFFFFFFFF30CFFFFFDD
-:108A60000C30C30CC30C30C3CF3CF3CCF3CF3CF37E
-:108A70000002CF3CCDCDCDCDFFFFFFFF30CFFFFFBC
-:108A80000C30C30CC30C30C3CF3CF3CCF3CF3CF35E
-:108A90000004CF3CCDCDCDCDFFFFFFFF30CFFFFF9A
-:108AA0000C30C30CC30C30C3CF3CF3CCF3CF3CF33E
-:108AB0000008CF3CCDCDCDCDFFFFFFFF30CFFFFF76
-:108AC0000C30C30CC30C30C3CF3CF3CCF3CF3CF31E
-:108AD0000010CF3CCDCDCDCDFFFFFFFF30CFFFFF4E
-:108AE0000C30C30CC30C30C3CF3CF3CCF3CF3CF3FE
-:108AF0000020CF3CCDCDCDCDFFFFFFFF30CFFFFF1E
-:108B00000C30C30CC30C30C3CF3CF3CCF3CF3CF3DD
-:108B10000040CF3CCDCDCDCD000C0000000700C003
-:108B200000028130000B8158000202100001023067
-:108B3000000F024000010330000C0000000800C0DC
-:108B400000028140000B8168000202200001024007
-:108B500000070250000202C00010000000080100DF
-:108B600000028180000B81A8000202600001828067
-:108B7000000E829800080380001000000001010030
-:108B80000002811000090138000201C8000101E85B
-:108B9000000E01F8000002D8CCCCCCCCCCCCCCCC94
-:108BA000CCCCCCCCCCCCCCCC00002000CCCCCCCC15
-:108BB000CCCCCCCCCCCCCCCCCCCCCCCC0000200005
-:108BC000CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCE5
-:108BD00004002000CCCCCCCCCCCCCCCCCCCCCCCCE1
-:108BE000CCCCCCCC4100200003030303034202029F
-:108BF0005050502070608050131313131342121200
-:108C000050505020706080500301020000000000AE
-:108C100000000000000000001F8B080000000000A2
-:108C2000000BFB51CFC0F0038A0F093230688A2055
-:108C3000F8C4E05C760686751C0C0C5BB849D3075B
-:108C4000C32C0C0C0CDA4CE4E905E1FBBC0C0CAFBA
-:108C50008098850F559C871342FF015AC0C7CAC030
-:108C6000A0C1865DFF3A35043B408581A11C88D9AF
-:108C7000941818CC5411E2D2EA0C0C3380FC04A8EE
-:108C8000D81D201DAB46BE9B47F1E0C1378D51F981
-:108C90005B0DA169012A7E0B4D7E1B54BE4A074223
-:108CA000DF36C66E6EB50E71F69FB546E5AFB4C63B
-:108CB000AFFEAE3D2AFF209AFAAD503E00C5D55B0F
-:108CC000A7D8030000000000000000000000000022
-:108CD0001F8B080000000000000BED7D7F7C14D589
-:108CE000B5F8999DD9D9D9CDEE6608096C20E02454
-:108CF000861AFB82DFE577A841878034B63CDF8A9D
-:108D00005AD3D6F6BB506C551456BF3EE1F56933C5
-:108D1000F941122262049FDAD61F2B554BFB6C8956
-:108D2000942AAD3FDE024AF1F5C743AAD5D7A22F58
-:108D3000FE80AA455FC4D2D87E51DE3DE7DEC9CEB3
-:108D40004C76930DD01F7FBCF081E1CEDC1FE79EF7
-:108D500073EE39E79E73EE8DEA0BC2C7CE05388EEF
-:108D60003FECD913028059D9A771F5BCAEBE99006A
-:108D70004721D2D35D0AD0A68009AC6C1D88A41F00
-:108D800094007F6A14565E2D7F3CDE5D097067D1CA
-:108D9000D7EEC3FA6B2C0502ECD9DD0C9039837D3C
-:108DA0000F453743314011A4B6E277F6937890F53A
-:108DB00037109C9C866876FC32F0D1B80015FAA179
-:108DC00022AA07C765F6CF81E47C18072083FDB38C
-:108DD000067A593FCAF3721AC795E5C5FA8B55D979
-:108DE0007EBC4F595721A389FEF01FF9B2E26438C7
-:108DF0007FFD35072AB73E5D93AD7F06444A0FFDE0
-:108E00001DFB8F020AC123AF07C4C3D130A4E5CA3A
-:108E1000FCFD0C341B5B9FF6231EBF509C989ABF31
-:108E20009E8DA7AE668D9E1DCD3A6402000C64B384
-:108E3000B7963DC3606EAE1DDA6E0148842FCDB08B
-:108E4000089EF6B02F5D5489502701187EFD881FBB
-:108E500009DF2FD1CC1CEDED279432FCD8F36578D7
-:108E60000C02EF0FD8FC1E64FD0571FC1CF8BA085B
-:108E7000C72F63DFAB878E6FCD3CF1F1436702EC08
-:108E80000B23BE4D84017C7A0AE282DE9F9486E940
-:108E900047D05931783F23E1BDA8C6971D97FD0DF6
-:108EA0001A21179F0462256EBEF1F225E2A90CE992
-:108EB0006548AF4FC9F6AB22DD72E0EB4A81AFFEE9
-:108EC000F989A604C3C7DA66B05E73B4936360A67B
-:108ED00073E069B568678FA794B27A39FA076811A9
-:108EE000EBC772D52F14BE9B4E10BE9BFF42F0DD28
-:108EF00026F89D49287AF6CF4F129CDEFE72AD2FE0
-:108F0000B68807CB21256DF990BF4B21FE207BF859
-:108F100035BECEECEFDF073FF5B303250E1BA74DA3
-:108F2000C0D73F9FCBBFB5D3D4F46689E4910BCEB5
-:108F300087517EB1769224F0A1F502F25FD1070A43
-:108F4000C05884CF844404605D7583369CFC015D09
-:108F5000F9539FCD775543F9EEE36C18842B14CE6B
-:108F60008DA7EF0FCAD1CBACD7583F5A90BD3F1D4C
-:108F7000FB2D8D55CC069C1DFDF8C577907CF271BC
-:108F80005CB7C758BDD942CECAD43FC911A8009218
-:108F9000F7B2A84FE3B0FA01362D733A7BE2FB1A21
-:108FA000318E34B45F6FBB0128E1F811F0D8725DE7
-:108FB0008627A89F41789404E1CBFBDECFDEEBE16E
-:108FC000937F7FB265BF9167BC1E89F869A4F6AF35
-:108FD000087E19C29F79E8BA5FAC33057A4D383DF7
-:108FE000CB47367F9D281F9D349FB0E1495FE4E168
-:108FF000130B52B46E5835AB7BDAE8F925079F6442
-:109000009CF5174B63F83C9438F10B834721BED590
-:10901000393C65D34BA93F09D7F819D88328231EBB
-:10902000D87C97D9ED214EEB3584768EA33D9B1CE1
-:10903000C12BC99290FBBCDE0D629DCF6BA8E0F006
-:1090400083E8DF032FEB4F73F627438587CF39DCA7
-:109050001B242EDF58FD0CE1D33BBE2211BC322471
-:109060002C1F6BB7598CEF955FF673BBE86FBD048F
-:109070004DBD61BE9E9638F4618324E484C6D799C1
-:10908000573EF991AF669C385F152AD7174BB9F553
-:109090000EB38A621746F2EB9D629FAD0F323141EB
-:1090A000B751D1FD74A9C445F742E15D7682F04E17
-:1090B0001C0A6F417C76A6E41B959EBCE104E10B83
-:1090C0007AE03B557C3D43F059A1F0DBEB60B4F016
-:1090D000CB43F15BD03A9A3B4AF8369F207ECB7C5B
-:1090E000B69D24E0CBB36EE7097A5BC0F9436176A5
-:1090F00038EE730A85EFD191E103F804FB6BBD6A8A
-:10910000990AD96B0013009E6E79D5B2942C7C26F7
-:1091100070B93EDAF1F78C4C3F31FE5B96599D1DDC
-:10912000FFF996B75CE32B8C7F90D90A1DF7854237
-:10913000E70DEFB9E6FDBAF49E6BDC13C5FBC18207
-:10914000C7FFA36BDEEF4B7F74CF3BCCE67D7AE1AC
-:10915000E3FEFE04F9B152AC97064977E9817CF64B
-:10916000FB0C41D7BBEDFA36BC79EA9F29E06A2FA8
-:10917000B0FE44D1FFE70AACDF2BFAEFC5FA652356
-:10918000D73F5DD44F15585FF2F175984F7FCE975A
-:109190006CFC816BFFD1A6713F88D9A640F09CA1E1
-:1091A0007E13AB21F5ED3E467BAB35A0B79592DF44
-:1091B00084FC226B0012E837F92624EB7CAC1F6399
-:1091C000C74DF761BD238AA677EBC01724FB1E3C71
-:1091D00010D9DC5D991D6FB59C6C929097DAA2FA5C
-:1091E00083E45F493549EC59668575F4DB0C5425F9
-:1091F0005A9696E23C0CDD62FDFCFA8A8B76627927
-:109200009326E9322BFFCB39736FFB0C6B35F0E102
-:10921000CE974EC37AD3C655B592BC3425C44F6998
-:109220005C35E5287B5E7C71561FE03F8B1D6566D3
-:10923000077CB6E9122EFFC5F7CF27DDE54B1A2FC5
-:1092400071B5BF34E1FE9E9D0FF07DC7B9DCFF30E4
-:109250005095FA2F0ED7C72A2DEE5FA0F9EA565483
-:10926000EF66F35CFFE1B5545EDF52ABB7B2F2E7F5
-:10927000AEF4B72C65CFB004BACC9652715CA5F9A8
-:10928000029BAF5AC7768FE73CDB35DBC8BFFF2AAE
-:10929000363DF38C5F9C8593CDB3E9EADC70ABFA85
-:1092A000FB13DE60F6D2C0CEA089F084F7CAE9A035
-:1092B0004474DD3909E9621527397D40AA66CF2358
-:1092C0008D3AA07FA4A13169C8ACBC31A6C5030604
-:1092D000DAC9190DF11E411ACC65EFE3BE20DA633D
-:1092E000AAFE07EA5F17DF7BE255E3D13FF2E3E630
-:1092F000351315B6DE77345BF47CB4B98B9EDB9BFB
-:109300007B262ACC88DFD27C173DEDF9A12431ECF5
-:10931000F9C9B8AF365B91DF06FCCC34423CCEF7DE
-:10932000D1FE7603CA113FCAE1745B14DFD7C1B422
-:109330006E40B9C4E5CBC6F8B6DDF87E633D4C435C
-:10934000926D3437B745D93CAE2B87E9D8F7CE9725
-:109350001FE3DF2B607A8095773536905CED89FBD3
-:10936000D2814A82FF7CE4E79E461F3093078AEB56
-:10937000185C0EBC0662EEF2AE4626B066123ED215
-:1093800001293B7F852D33C4C746B32AE8DC57CF7C
-:10939000DAE76E7F66DA5DDE88ED87F14BCDED733F
-:1093A000D79FF392BBCC24DB2B837CC0F1F8AF3E7C
-:1093B000260F76BF3CDE67E1BC4D3E4FF6E4FEC2B1
-:1093C000982F8DC6E716813F1BBF03112E5F3636DF
-:1093D000733F603E78367EEAAAD8707E03B5B1232B
-:1093E00081FE54B5B1270167E1332D9EBD09A79FCA
-:1093F000D57EBE88C68FC35FD211DB58B2B4360BA0
-:109400008FB7FE785925793750C6BF77C45ED3979A
-:10941000D63AFB93BCDFB5CBC3CEEFDCAF32506E98
-:109420007F3FA22D0DE7683F897DCF4197A532FF91
-:10943000FEF4CB81863B901F057E77BFFC13AD1AEF
-:10944000F1FDBC0CC8671BF73590BC453E4379B1B4
-:109450008BF1455F2DD27FFD2BCE755B5CE72E3304
-:10946000BEE2FCC5FAC5A17E86F4601DFEBBF0CB52
-:10947000EE157ED93DCD317A3EDD6CD07357730D3C
-:109480007DCF34C7A9FC54731D959F6836A9FCE3B2
-:10949000E6462AEF684E50F9D1E6267A6E6F4ED234
-:1094A000734BF315F464FC4BFCBCA13925FCC06B79
-:1094B0005CFCF0F7F1808BFF3E5DE32E9F6F9C918B
-:1094C0005DD7ECEF2763EEF279FA275DE5059ABBED
-:1094D0003C1FBEE2EAEFDC0FBEEC2ACFEBEF70D50B
-:1094E0003FFB4D77796EDF439EF5E22ECFDAB7C7AB
-:1094F000B31EDDE5E2BA43AEFE023177F97E1432E7
-:109500005C4E117F74C45A4B72F2CFE0F78DA12FDD
-:10951000B9BECBD47E64FE59D65589FC93F6C52DD1
-:10952000943B26E7275BEE78F9C4A6DB48FC65C3CD
-:10953000F197E6ABFFE5A7E1F9A9607EA85772F2C3
-:109540008397EE5EFE18226704BFFC2F1FFC6DF0B0
-:1095500001CC64C42ECFAF5773D877649F061240F6
-:10956000F69D1FED34477B75722A69E6D09F57F947
-:10957000E66F95593F8152E8C0786840C9E3E795A6
-:10958000F93E25A0F1EFC16A93ECB26230A6CB633D
-:1095900000AE796C5EF932F6FEE7421F765C089603
-:1095A000C4FA1B37414DE23EA6B8DABDDF7B46E682
-:1095B000FB18FBB9E9879126FC0EA5334798378F36
-:1095C000D7C8136737FDC660CF0B666F59CBDE86F1
-:1095D000AA9319F2019596927D9A0C19D4AF5997D6
-:1095E000B67CA518478338DA8972D884241B67AE05
-:1095F000CFFC05CE9BD947FF21CFCADA3D9BC4F3F0
-:1096000047621D5EE4337F29EA3D3F5C3D7BDC1110
-:10961000E905494BE2FEA9F8830C447F69DC653F0C
-:10962000D9F353948499C8616FFC4EE04BD2E34D5B
-:10963000DC0FA202CA877CF50FCAB6FFC972ED071C
-:109640008BA13F23231C311E6F82631719174E1DF8
-:109650000A87AA2492380EC6AB37B371DAC77CC624
-:10966000483AC6F948E67E2A2966123CAACEE1515C
-:1096700095B899C8C14703021EBB1F3B6E26C5FAA9
-:10968000A12F9C856F6D30D184FB256B8C4A786A45
-:109690008FB8EDAF190AEFA75A3CDBFDB9ED438057
-:1096A00056BE1F1E57A761FF6D750D1ADAD78C1DA8
-:1096B00068BFD21E5E523C9CBDBD5ED8BFDD280F88
-:1096C00003180FD785BC8AD1B33DBCAD11D7C1D12A
-:1096D0005A8687CAFCFD44E2EEB86E514DC813C7E6
-:1096E0004D139C41A3C413EF9DE06AE71FA7F8EC5C
-:1096F000B8364823C3DF21E0B7EB752A294DCF895F
-:10970000273EBE5D0EC4DCF0FEF9F0C7DB17F97B27
-:10971000F55C709D2ABCE58BC3DA4F75AC9A4A7331
-:109720007F4ACCB90E3E2BF84B1DABA5483E69F9DC
-:10973000BE8778FB7082FC5B5A38614055361EABA1
-:10974000E17A70E0E95AD1EED78A4FACCB540CFDE8
-:109750005C92916A427ED22AD83A9286B6B39F49E9
-:10976000D1BEF3C3FFF712AD93328DD68964B075C5
-:1097700094631C4931AF56D8F31DD9BC46C1F8CC0F
-:10978000477232D77A5921E0D116270CAD8A427838
-:109790003CDFC303C73A85EB834336FC568AFC564D
-:1097A00085C2BFA640F8ED7118FCED02FEB5C3C13D
-:1097B000DF26E02901A3857C990697B300171ACE0E
-:1097C000BC8B37C4F825424E314C11DDECEFFF2540
-:1097D000FA29743E1B059C23CDE78D2C3DEEC579FF
-:1097E000B0F9DC87F3CA379F7B041C6F285CCF6815
-:1097F000898411AB22559F93AF9E1070F42B228E5B
-:10980000665D3B2ABEFAD702E7F144962E8F09BA6D
-:10981000EC186E1E8F8A79F4C830F70DF4339E2E43
-:10982000F40E2C71D1E5A8C04F4FC0A6CB752EBA4F
-:10983000FC4ECCABD0F93C53209F1DCDD2E5393145
-:109840009FFDC3CDC751FF4551FF25519FFCE74701
-:10985000952B5AAD5AFC9E38A0CCCA8EC7EABDECF7
-:10986000AC776DFB2CBBDEABC80F5223D783ACDECD
-:109870006BCE7A605DD08AF6DB5A8C897E02E081FD
-:10988000F6AF3688766F52BBC583FDBF25D607B5C8
-:109890005BD73EBFD50A53BD77F07DCB828FEC7A84
-:1098A000EFBAE15D61C37184E04D0CC2F1BEB3DE7D
-:1098B00013CAE7A9BF217947B19282EC1F7F699251
-:1098C000F2F74A20D283FEC50E2545FE640C36A071
-:1098D0001F7275204EA92A23F9A3CB2EE6ED7445FD
-:1098E000237F6A005270177BBFA154A1F8C862257C
-:1098F00019F1A31D21252D0AAE827E590BF63FD604
-:10990000A0FC2F1B9EDB8ABED845FD3078B0DF3B24
-:109910008BA23B91AF364E520DE4AB9D936E20BFB0
-:10992000F96D2D3C7FF0B6F355DA676D7A3942FA5E
-:1099300077AD12FF2CD6B74CD5403FFAEAD0472F6F
-:109940002D67E5BE96625D3A87E641705B3E48B49E
-:10995000CD74E42332B80371CAA7233FDC6D8D3C7C
-:10996000AEC37ECAB1FDEA0546BCDB40F1C5E418D2
-:10997000FBDE59A792FD7A5B45D57C1C6F539D4653
-:10998000F6C6A6C5552DE4C7AB0B91BFB2246C48F3
-:10999000E8678FCE519901CECAA5460BDA9B91D9C3
-:1099A0002140BF5349051F2F7206901FCA0F3D89E2
-:1099B0006AF68C76A990198BFD2DC97C09ED99BAB0
-:1099C00000F9E1D9C4F6D78EA39437FE23FF0C101B
-:1099D0001EFF441910EF367DA33D83ED87CD638CC8
-:1099E000A60BAC9729AC5EA44B81CC8C02EAF51493
-:1099F000582F5D60BD0CAF17800B87CDE78338CF44
-:109A000023D4D81F9EC7E8C82BACE4F6BBD36EF1B5
-:109A10007BBE8F362FF42ABFC80B9D0373785EE898
-:109A2000F0EDED7CD091E60BE0CBC2298F5C7F6D31
-:109A3000F3F07E63FFB81B62987FD959F655F1BCED
-:109A4000913FCBC5FBF2353194779DE5E27BF98DF3
-:109A50004DB9F6AF77FAB91CAE81C4B0742811F0D5
-:109A60001F62B0637E4F8DC2EA47F2D7574B7DC36A
-:109A7000E6596A8AD540EB76B18FD66D008501AE86
-:109A80009B0ABE8EFD904A54F37855B4DCB17EFC3F
-:109A9000F57B68FDFCA25C06A98EE813473C7AF9C9
-:109AA000C4CB170170942B4F9E4FB6FE99F8C4DFBC
-:109AB0002517B47EFC3D05D64B17582F53583DB59E
-:109AC0004B2A48AEA83D05D64B17582FC3EBAD9D8A
-:109AD000AB727D0E7F68C578BFFF139AABBCF613DF
-:109AE00021F7F7B3C3AE72C72C777B75B6BB7DC7C2
-:109AF0006C777B750E6F1FEC800518CF2F749D1C43
-:109B00003CC17552A30D5F3F5237C2BAD2F420B6A2
-:109B10002F510CC89492BE4A0BBD95331E7E9ACA33
-:109B2000D77F959FC7CF6F53F420EE23FFD6E72949
-:109B3000A93C9FC09EEF48F0DAF2F7B7B2B0B7F297
-:109B4000E47D438C9F7FF043288E768EB1506B78F6
-:109B500085E1D1FF2CCF7BF7F6FB8A9A9CA63AF6DB
-:109B6000C5CC3E83A4C30F737E99C2F36D181DD07C
-:109B70001E5221D158C9FA6BABF0913DA28447D057
-:109B80001B150EB995232F2FEB970213CF53D02718
-:109B90000360FE9B7CDC501C08EE08F4D166BA180A
-:109BA00053E54E07180386C493BEE212CF13ACD719
-:109BB000519E95064F75BF9751BF92791B1C2F1A66
-:109BC00045BF4A1FE5CB9CF27E478037087753BFDD
-:109BD0006C97547A7C6CB65F7F2C452F314F56764C
-:109BE000E4CBE1B908CA37F1C53394DF30214AFB31
-:109BF000B2B5A5D7B9F2C1FF59AD72F98754BDE32B
-:109C00005A09E3BA15579B7DC3F079331357E4F72C
-:109C1000AC586EF6D5E4AF3798A78FF99E39D64188
-:109C2000879A4CA3FD6E4D0EF3FDBC92227F63A775
-:109C300054321DF32DEC7A4A0593B40CAEC84CD3C4
-:109C4000C2FD5EE7585F1CED5405D6EF93CE62ED82
-:109C5000E4C571A7FFD2FB542A94B79DF3B95D65A3
-:109C60007A12E1147AB26D047E1FD1EE51E3C95C21
-:109C70007ED16FAB7C5FEB0FE5FEDE176A78409D0F
-:109C800035146F8F217E717F3B06BAA4FFC3D9873D
-:109C9000F2A52AF6BC8478585BB62836DC7CD90657
-:109CA000EAF0205D18897F16321F4179300C1C3F85
-:109CB000CC0507840BF37FEB0BE3C48783F65229B3
-:109CC00088FD98199518DF870457DE32737306CF25
-:109CD00043F897864DA49F6C6E01F457DB76936C26
-:109CE000865EF5113DEBB9FD54C3ED2193FDC179BD
-:109CF00044EB87B7AB654FF939D56D0FB535EF003C
-:109D0000679E9BF75C85FD4C871A5ECC8D8FC2F6F3
-:109D1000C3B7337EC13CFB8DCD1A22057A9A752AD2
-:109D20006F688E51797DB341CFF6E61A7ADE8C4D9D
-:109D3000E7E2F9A7545725C35B57EC81D8E5ACCAD5
-:109D4000ED283B288FEFDE05682F770F96D93690E8
-:109D5000C1DD3D09785E9F7AEB02DCE7770741F8C9
-:109D600015DA16A05D9D2DDFD1361FCBC2CF10EACC
-:109D7000BC6F01EEF76F17F90FA098DA250EBD77CB
-:109D80005AC04FFC477B576A6FB5617F414594E1EC
-:109D90009105EE3298084F50E3E505816DD43F8977
-:109DA0000036DEA7033FE0E34D11F96DB54B46C029
-:109DB00023F7EF5BAAC1FD5DB525143F52E3717433
-:109DC000BFC2ED6304DC05F6034A92EB3B718E2FB4
-:109DD000FFBA1941AF093846A23F4307F9D1EDF365
-:109DE00069CA0BB9F5F4A91EF776FFE8F0A2D6F51B
-:109DF0005B7886ED09353927C0DA47CCDE4C252B58
-:109E00004717672C5ABE058E3B3660E7392669FD39
-:109E1000DB7856746E77ACF0D0D15FCAE3754171D0
-:109E2000FEA4507893AA1847F4030F37940F67AF36
-:109E300095257C68840DCA8BB18D21E19CE1E531CB
-:109E40006689AB5C5C37C1553F12AF727DF7EB1F83
-:109E5000777D3F513A5DE299C7A784DD6897CFF5DA
-:109E6000CEB3C07E0F1627560570DD34404D8AE113
-:109E7000F5CE2F3C44F80F0DAED385ED6605E58396
-:109E80008B753D8F9775FB7B5DBB59CFCA86FD7D7A
-:109E9000062F9BF6F738AF6FD9DFA7F2EF28F759F7
-:109EA000F96B9D67B45BF81D5AC96F0B152958E211
-:109EB000A0CFD8F10DAD08DFF8CBD2318BBDEFFECE
-:109EC00050E6F2007A62CE7A776ADC0FFDCC943BE2
-:109ED00062E8AF5C77E64331207927E58C07FE3CEA
-:109EE000C0F3C5CA42899E00AD77B3BF98F1E1A126
-:109EF000876483EB21E535D4873E8BE7E3AB10DF46
-:109F000067A25D54C3FDD521F19DE85899AD3F4846
-:109F1000574FF9EF34AED77F87491B0CCEEF159B17
-:109F2000F7D0B890961AD97AAFB0A01FCF1F81B0E2
-:109F3000FB26F2A6509A48939F6F12C3A7CCBE4F40
-:109F4000BEB8BFC5CF706D5CA6FB7089542D8FFB6A
-:109F500048C00DDA9163A5E3ECF93DA417CAE39B71
-:109F60005280FA7BED990F35215E02997F0283E1E1
-:109F7000ED1F27A5C040FF6F80C315B8AC07483E52
-:109F800057F7109EBDF85A3788F7B40BEF3F0970AA
-:109F90007F7E2CC9DB0DD65358BDA943EB75077BDB
-:109FA000E6AB68BF4DE178F48EF35E4012E776DDF4
-:109FB00070D8FD7AEBDF1210716D2D4DF18D67CEEB
-:109FC000BC21867EEDCE298CFEB5F9E97F4B80E77A
-:109FD0005B19C76E22B9DB3D6923C533D7556F26A0
-:109FE0007BF228B323F0FC747765EEF69DCD3C3F01
-:109FF000E65CB8BBB18AD1A7F37999FCB4DE7ADF0D
-:10A000000954B9E28D5A857B3FC8F8AF0FE5E8489F
-:10A01000FC27471EE0EB72947C8766213FCF50D629
-:10A020008EF6805F94EF0E1C6F13FA9FE47FF9F2B7
-:10A030001E70E64BBE2FF82213E0722658C1F9A31A
-:10A04000DB6F494EFAC5D8FBF98E76F9E8968F1F7B
-:10A050001E17EBE17D25DE44CA5F49E9B9E4B3127E
-:10A06000FBF42F173ACE7BB52B694D47F86B364A78
-:10A070004EBBF61B6632A439F627A1D805BF5C8813
-:10A08000FB1F259E739FFE29D38C6A6CFC9B9B61F2
-:10A0900046359E4B50AC00D6BB59C934D2BEA2DA6D
-:10A0A00047FEF27515D7EDC53C2BABD617C76A6DC9
-:10A0B00015BB1AAB0CE4976D9467FAA6BE2486FD17
-:10A0C0000462EA8CEAB194DF9DC079876B59BF0EB8
-:10A0D0007ADBE3DE2DF8F65BBA3959E3F2E034EDD2
-:10A0E0002F200FDE87788C1B590CCF39F65743F1A0
-:10A0F000CCF3043A2B86E0798EE6E0EB00E27906B9
-:10A10000C9FB9CFE0B86E7B35D780686E7A9593C40
-:10A110007757703C77D66CEEAA72E2B966D7DE4A02
-:10A1200003C7E7787E48E3E773438867079C5E3C94
-:10A1300087255BFF7CAC1DF9D6CBF70CEF7F8FF04A
-:10A14000D8EF3F0AFC82ECE1B1E313176AE43F4920
-:10A15000D1FEE94E29AF5EBA442B402F758A757443
-:10A16000A7C03FEBFF0BD47FA9E8DFD6B7421FFEA5
-:10A1700083F66F0B501FB27ACBA89E9EA27DF06033
-:10A180003D0B86D5A3ACDD95C447614FFF268C4AB5
-:10A190001FB37EAEA37E34CFF8069C949E67FDDE8F
-:10A1A00044FD2A9E7E4FB13DC1C6E926FC81070FC2
-:10A1B0007F663B2696F4F083D2E3927B363F942F62
-:10A1C00077D7CBAFD77AB85E1B6AD710DFFEBC73E8
-:10A1D000CF6EDC27BDA99BDF46BC8E761DD876608E
-:10A1E0005928B94DE376209D83B0BE51946E636DBE
-:10A1F00095E33D511E7F77EBA3F1B63D54CDF5407D
-:10A2000070947A699FB0D73AC6301955CC9EFE44F7
-:10A21000532E3FC3339A9DB7E6B69B7F8373243F8B
-:10A220005182FC6BEDB1CFECE863B4331B7B20971C
-:10A230009C4F86923FC7F9A9BA65927A15FE917C28
-:10A24000FD9626AC9D7B6792DCEDC7BC461072186C
-:10A250004D6BF4C74519DE0E69E4C288A37FADECEF
-:10A26000626B3ECAB10AC62F587F5CD33E29992B38
-:10A270003E6EEF7F10881CFB97719F9B9DA47CB85E
-:10A28000C53347D8DFB4D8F6EB6F715E87D49E0B29
-:10A29000A638F06ED3E90E2971E179284FE7713ABB
-:10A2A000158F924E03824EB098E7A19E7BEC5C8D99
-:10A2B000FC8B115F02FDF0417F8F5EE2E0A3713EF7
-:10A2C00048F68E02FE7AE8DF7D1CF77F611FED778E
-:10A2D000BBC3CBBE83F7EF58BA1A9F6264C7ED6663
-:10A2E000FABEC4A17FBCFEAAC17DF4E2C2F265A79A
-:10A2F000587328DE9FBD3FC89D7FC018AB06F3860C
-:10A3000056CBDC7F7E67D1D7280F618D15D003A592
-:10A31000A4C7C8FE5B27F2D93A453EDB5A91CFE687
-:10A32000B7566FC5FA9B0012E8976C9997A2787F91
-:10A3300054D1F4D638C2919A837A225A6AAFCF1F89
-:10A340002FC4F53958B6BED1DEC0E61B8DD9E58DD8
-:10A3500064BFB5B77079F3D9E00B0BAD7A64C53E35
-:10A36000A2C7A6BA25C5308C3F325CEBCE9F0B55F9
-:10A37000875C65ADA2C455564B270C1BB7F819FA7C
-:10A380008966E17CFA208E70E6C9179E12E476B6E3
-:10A390002C4FEBCF60BEC1D96A7CB381E7A8DD79D1
-:10A3A0009CED416E0F3E8A0E218AE30ABEA8E3713E
-:10A3B000D5A2B955BD180782319C2F304FD0C90F97
-:10A3C000F9F8E2AF8D1F5FD1E118E65DDCD21A0526
-:10A3D000CC73B965EEAFE21903E56A5F0CF333DACB
-:10A3E00098246965DF37CCFD9591CB9F7C404B2E3F
-:10A3F0000F22FEC209B2BF223393F4FC6BCF6B2451
-:10A400007ADE19E47A6E8AA0A782F49C99A5E7BA4D
-:10A410003A46CF99D975BE4EE9D10AA1E7F9387EFF
-:10A4200019CAA1FFA67DDBCD75BE46944306F45242
-:10A43000FEED865A9F0FFBFF6BE1C5862B3C97C94B
-:10A4400047A25326817A61435CF1A11CF99BE3C3C7
-:10A450008FFAE87D017CF8C35C7CB85CD0432EDACF
-:10A46000D7942BEF6E4A5072E1653DD28BE3A591F4
-:10A47000E3C5F757C1CBA0BED0922B916FAE88A990
-:10A48000B4EF564ABA3A285EC4F41EC61B56C8A694
-:10A4900081F126F8969FDFC7847ADBA15FFE180C56
-:10A4A00072FB445EBF88E2186C6AB82F63E58F0DBB
-:10A4B0001B0F4DFBFB9DF79478F3325E0BBAE31054
-:10A4C000472A961423BDF2F5F776F35E1DCFD5DA51
-:10A4D000F919DEEF2B6448E53AB72885346167F651
-:10A4E000AA84871B99AE9D86F8F8D8423C9FD9591B
-:10A4F000D13A8EEC1871AE61C5966775C501E70A51
-:10A5000085A9BFE943E763E37705AAC91247FBF4CE
-:10A510005E577B6FBBC1FE447B66B7F9430C3E536D
-:10A5200049EDC578B37D7E43DD323F436A330FDCAE
-:10A530008C8E270577A1E7388E3CD0D681FB6DB491
-:10A54000BF3EC1F8E4B78FC8F156F6F58ABBCF58C5
-:10A5500088E75A0F01E7179B3E6F3DD0362E175FF5
-:10A56000E4A3CF79A12087E714F3D759210F7FF512
-:10A570005E549C8153CF5F8BF3F197C0CFE15E8E29
-:10A580000FB86B6C4E3AE59BCF209DEC7682CFBC2A
-:10A59000EDF3B5637C95E07C95899E5D085F097855
-:10A5A0006DFA9D2CBC23F155608D6CE079AE4A2587
-:10A5B0004172B3B3F43A4BDCEB48F99E72CFB48CE2
-:10A5C000B8D74AE4B54306ED8940A949767448DC1A
-:10A5D000CFA355BBE5A612739F9B8835253276BF66
-:10A5E000E8BF0CAC5169DCC1F8711832C12896790A
-:10A5F0009C14C51FEE2B02F04DF27BB27639FD9E06
-:10A60000F65311F96A98CB4BF7B2C1E747C86F719F
-:10A610008F13BB78F8FC1A6F7D082BC62107DEF379
-:10A62000B753E090639FB341DC2B6AE3DFDCB29465
-:10A63000F2CA83E08BD3FE20D661E1BEAF43ACE724
-:10A640004E7CCEC573BCD375DAAF55F0788B257DC3
-:10A6500099FC0CF6B9337B3CFBBC995D6F24FAAFD7
-:10A66000C6F594637DEF0A717D3AF0B5D47FE33E81
-:10A67000C4FA1318780FC5E3CD1F509CFA9CCC5B2D
-:10A6800032FAF79F098DA37ECEE9EF931738D6E50E
-:10A6900039E21C0740AF9CEB9C97DF0AEC427E78C6
-:10A6A000EA30DF8F3D75F808D9E14FFDDE9746BEF1
-:10A6B0007BEA83E1F31E1E17FB22BBDEE3BFE7F656
-:10A6C000D9E34A6F512EFB2E3B7E9AEF070FBBF961
-:10A6D00015945E19F965E0A67D32FA071E6FD6A4BF
-:10A6E000D799FC9927E679CEE13E19F74D23CD6B3A
-:10A6F000AB87BEF63CB7D6737B746BFD9110FAFF47
-:10A70000B73EC1E77BB49E9F8FCD07EFAE669EDF5D
-:10A71000B1F589DCF86898C7F7C70D7EA334A75D4B
-:10A72000EB3967B54093DDE7BB4E317CBBEBB9DD60
-:10A73000B55B89874F049EBCEBBBAEA711DD08510A
-:10A740004836CE9708BDFB5D7E92035F6FF932E617
-:10A750006B2C0D9B12EE65A12FF3249B5789A92525
-:10A76000F0DE98E2FA1E6932E677C4781EF937AF58
-:10A770007E2DF3322BDFDC5444655D379E5B84F81D
-:10A7800028D5C99F72337A5C48407F732DE627D065
-:10A790007A64E5C0CD3DE7A13F4B012E2F98C56BF4
-:10A7A00028E3E85E3F72D2E4931BEC473A1EC8B63A
-:10A7B000CB3B4F4FDE6D00960C2FC796F3FA16FB7E
-:10A7C0008372A8C49367A22F74E7A5443DFD4F454B
-:10A7D0005BB5AC80BCF2931C670C6CD30CDC67D708
-:10A7E000FAF434D607630CE60D861B9981C4E83968
-:10A7F000460709CDE591F0BE0EA091FBBF33E03CCA
-:10A80000A7D350C4E5D584AB6E97709F7134CEB892
-:10A81000621A96DFCC997FD52EE4C76059DF45F2E6
-:10A82000B4037AF7525C20E9233BFCE6DAD631CE5A
-:10A83000F64B8B24DB1F28E80F86323B4B7F363FDD
-:10A840003378D65F8EFEB1E56EBC8F962ED714712D
-:10A85000793512FD4F761C9B6E43D7478BA0DB03E7
-:10A860001417EDAE195EEE0FA5DB36D277E1DADC18
-:10A87000F9BAD715492E796C3F3548419CF1892C9E
-:10A88000EE6796C7CF6EBA7F18F9233BEF67866CE9
-:10A890003FE38C1E13E356E3A1C7C473DF8CA7E329
-:10A8A0001940FE3601ED24661E111FC99EFDDC46CF
-:10A8B000C14741789EDAB35560E9A45752A03BF2F4
-:10A8C00054CE93C371F45FACD3C3742F12CA4F9E9E
-:10A8D000BFC3F3FC8B39480CBFFD80F22D542E838F
-:10A8E000857EBF7A01AFC4F80EF3FB0FBC7500F78D
-:10A8F0002BE1996E3A29078A28AF2DE43D2772E0B3
-:10A900009A6B687FE3A1E368F3FEBF5F24ECFF224C
-:10A910000893DD24DAE7CBDFB3ED7E1BBFC6B108B9
-:10A92000E5ED741C90081F659313F7E3FE0C7E257C
-:10A9300003CFCB0413F3F656FF74167D1F1A574846
-:10A9400054225DDE3A50A4B75616922F9948B6B0FD
-:10A95000FAC68140BCD520D5E2D3908E7D12D1516C
-:10A960001AA751BED6EA7FF7DF1F18265FCB8E3FAE
-:10A970000E96158BE29B5DC674CD294FCA42C95F06
-:10A980001639E3F622AEEBF5AF07C3EDB16760F41D
-:10A99000F18FD2F120E2F29F5F84F64B17AE019E59
-:10A9A0001747797A5DE5BCFC46D1944518DFE98A02
-:10A9B000F07271F8C8792D246713E4FF5BC3180E99
-:10A9C000F1087BFDE21E4963FC85C3C80BEFFCD791
-:10A9D0002BFB284FFE9EF0FEF3CF40FAC47DE48FA0
-:10A9E000BBE7FA6DAEFB93DED41BDE2FA2F5AAB750
-:10A9F000637C7A62D2CED774C74526A0D660F39B1B
-:10AA0000C408E3677838ED626845B6A9BCACB71CEA
-:10AA1000F7C96B4BB78DE1E7FD17EA87C86E972939
-:10AA20003E9D0F5EAF9D9E6FBE76BCDDDBFEAE0829
-:10AA3000BF47D51B17F3FA831E44FC9651FE2C60CA
-:10AA4000FE6CA7BF2F673CEA8D22EED76CAF5894FF
-:10AA5000B81CE7A598730F327CDC5B1AA57D90FFCC
-:10AA6000A2DA4B7D0E7BC3CE6753C47ECE5F9A22A3
-:10AA7000B9A86866D719182F7A5EC61505153D3B2B
-:10AA800025B4E7EDFB2010AD174FE5F3C579058040
-:10AA9000DBC5785EE1B863DE1073F8C1509E88FDB7
-:10AAA000DB29A0F7B4F0ACA1F49DDFC5F3D0635768
-:10AAB000F0F34D1395DCF41E7F99EEE3F1AF534BA9
-:10AAC000E77CEDF3C53DEF8AA8B47EA6E8ABF7E2DC
-:10AAD0003D771D567112E33103FE5417CAAB0DFFCB
-:10AAE000E883CD34FFD1E937454FD03D7A15297D34
-:10AAF0003A2EEF7CEDEE48ED0A129E2D9ECFE0FD42
-:10AB00007E7998EB9B9E94EF36FC6E3E9DDAE9C70A
-:10AB10007D678CEFABED7D783294BC3CECB0CF75AB
-:10AB2000D3223E9A92BC94E4C0405961F72F0CE2C4
-:10AB30002B4F1EF31D11AE97A718AB79BF9386F765
-:10AB4000CBDA78F9A04B16BF1721134438FC8C914F
-:10AB500013B82E6EE472E2EE35BBE8BD7263DF7CA3
-:10AB6000FEBDBF05F5EA1D3EB82297DFA82DC2E362
-:10AB70004193CDCC3AD41B93533E40FBF4F688412D
-:10AB8000EFC75FC6F1D43509E238EC69D81FFBCFB7
-:10AB90009E4A95F4D2D852A0FB92C6AE01D2DB6396
-:10ABA0006B206DB072D7CEB93BD1BE55AB218EAE06
-:10ABB000EBDD953758680F6CAA0013F5B8FF46B661
-:10ABC000C0587DD5F0A53150BC29B58CEE6959CB64
-:10ABD000D6255263ADD140F6C3D1182F072AF839D4
-:10ABE00098AE331582C3BE7F9CEC4EA61FFCB5FD0C
-:10ABF000265EFD65C015D48F7F2EA7AB71573D9D96
-:10AC000053EB1AF310DD4B635D033CDE69C7A515FA
-:10AC1000C65F6C9CF62BF49CFE9523A1E4B79DFCCB
-:10AC2000C0F891E44C17E613E4C0676798E3F30EAD
-:10AC300021E706FCF0298A97B4F8E83E176FFD6516
-:10AC400002FF775B4BFEE10C23AB6FECEF078B0C45
-:10AC5000977FA3E20395E6B348BE1174A43BB39378
-:10AC6000E8FE17BC18F4745A9617943BCEB3DC1B5D
-:10AC7000EF85C98867DB2EAAE5F68C7DEE91E12190
-:10AC8000730FFBAED705E87ED1F14DB9ED23B5408A
-:10AC9000FBA8ABC8FC6918F30D443EFFD7972F21E2
-:10ACA0007D9FEFDEDABB235CCEDF2559951D489FE3
-:10ACB00049FCFE196FBD83C25E64F620F1CD268B80
-:10ACC000DFBBB5896D7D1E45BEBA9EDFF3C7DEF3DF
-:10ACD000730E06D079F1D80DCBB45CEBD51B57CEF3
-:10ACE000B7EE826A5F3257BCA556D0AD24AECFF71F
-:10ACF000F1E983E9B0478B6A81EEFFD2197DD0F686
-:10AD0000AD805E4ABADFD858528971A15B6F540D8D
-:10AD10007C7F5F65AFB510E72D41EF839823A3F4E7
-:10AD20009A781EBD223ECEE8769CF72EAE7894CE61
-:10AD3000C3DFFE54000275783FA9E7F7D938E9234D
-:10AD400067E96CEBAB7CF32BF4790BC397F3F780DB
-:10AD5000308833388F220B0CBA1FD9E8253BF4A872
-:10AD60001544DD0A467D2FD72BED2178308EF7CCA8
-:10AD7000F2F2A6F054C0FB6735A597EC754DAFA273
-:10AD8000725175A29BECF369DBF55CFAE153914AD1
-:10AD900097DF24E4895369C91B9AB89F56852939DE
-:10ADA000D6D9C12285DBD3AC29C573ADE1E5EDC9A8
-:10ADB000F2C79B42DFE8D97D32F107C92E468F707A
-:10ADC000C5A2B764C77D9C61EFF9622F3D3DE59355
-:10ADD000A5E73AA4A723BEA0D52735A49FC1EC249C
-:10ADE000B2FBEB019CF7A66FD22C7E0F8361F82C8F
-:10ADF000077ECB85DDA77CA0D079DBBB9676D0FE25
-:10AE0000632CEB03F37AD933E7BDD3078B785E78F5
-:10AE10005751624984F27281EE195E27E4C679F2D5
-:10AE2000CF8298871504A6E7908F16FBE0C11C74AB
-:10AE30002D8F703CA743E6E722B3F2CFF77129F7D5
-:10AE40007DA276FB83C20F50B81CE6F39D620ED044
-:10AE500079D2819B0AD3DF036C6EFBD02E57E25C64
-:10AE60004FF719D03E93EE7F4AA3DEDD145B4278A4
-:10AE7000BF0FF529DA56B55C4FFA53DC4F0C864408
-:10AE8000F7CA86C4BD1BF7A58E3C8B76CFD11A05B9
-:10AE90003D3E10AC485AA85F8BABFB2C09F56C69A2
-:10AEA0009AE2C74C8F598867E3AE4504B75FE96DF6
-:10AEB000417D99562084FA7C008D4966C73D127EFB
-:10AEC000A403F35DFCB5695064DCD70338EFF737B2
-:10AED000602FD9597EA687C96E52FA5A502EB5D71F
-:10AEE000EB14D739EDC63E70EEEFD8B8B7E2B81321
-:10AEF0004AD97846567F7AED8D7C7606D3B3222FD9
-:10AF0000674107EEDF6829B1F2C3E1ED1D686F7E8E
-:10AF10004B37BF4EFC93679FC1F8E29E48D9E8F9D2
-:10AF2000E2B9B09B2F06FD27C2EFBAAC4E087A30CB
-:10AF30002EFD0D83FBCABD7EC0F99F7BECBE3DF7A5
-:10AF4000307CC8A84FC972E9D9F324FBBE1CFDB000
-:10AF5000AC7CE581A92ACABD5F4D90F1EC30F25975
-:10AF600014F9E71DF0917FE81DD81F9DE180676708
-:10AF700084AF13E8F2BFD6E7F03F5EDEC3CBB6FC8A
-:10AF8000FBCA5DEEF29761C938B4BFBE7CBB1FD26D
-:10AF900012FEDE29F7BEF99108CF37FF0AA43A1056
-:10AFA000CF6BC5F9A46B1E9BAAA2FD74E50CBD1264
-:10AFB000E39F361CCF0A3DFD36E363C3210FAF0A82
-:10AFC000A755CC977A7DFB8CCF9C0DD84FBA6302E6
-:10AFD000FA0FC7404E3DFEA52E379C23CDC30BB7BD
-:10AFE0007DDE281F1CCA1629A71FECC588DB0F763B
-:10AFF000B2F7B31F45FB7856F6F7D7D9796627DB4A
-:10B00000EF9FF2F47B8D86175103AC527A1AA5AAF2
-:10B010006CDC2BE8B7CC8968FFED989FC1DC7547E5
-:10B02000BDAE02EB35FA86A937D27C5687EE8DA2EB
-:10B03000BFA84F8244AEFB77CA42C931D15943EF12
-:10B04000E101F1FB820EBD62DF63DFBF08FD7C0121
-:10B0500060FB7B7A2AC407E4FF91D05EEDC9989526
-:10B06000183F565CFC5184F11466F7AE12F6655138
-:10B070008DFBBBD71F747A94AFEB7AE823FB3FAA12
-:10B080008533329E6BAD73E73FDD59F44592BB2BA0
-:10B09000F7F9C9CE5C09C6ADF533691D921FECFA0C
-:10B0A00075A7539CF8FA32236EA15C83B8496D3DB5
-:10B0B0007CB7EA0309D20E3FC12AA55FC5F5B68A5F
-:10B0C000E90FE7FBEB62B2F1468EDFDF643FFDA0E4
-:10B0D00019E11AC4838F9FA7D559D931CF233D5287
-:10B0E000238FCB19C5170FB37FBF2EA6D238CBD66F
-:10B0F0004D29E6FE21B7DC7C57E8A99F3CFC2D9545
-:10B10000EEA3FAEEAB17201E563C2E83C6C67DF783
-:10B11000E10864487FA555D45F576D9773EA77CCF3
-:10B1200074A2BC94ADDC7F79D5B6407A316B7FD503
-:10B13000A3AF9F050CBE775BFBF74CC475F05DEECB
-:10B140005704ABEFAC8BD8FBAB14F8BFB9ECA9CF6D
-:10B1500047B9BD7DF847454DB8BEA52D3BBF48FD5D
-:10B16000F65EEA0F38E2734BA2FC7C2CABC7FDA065
-:10B17000DF91D25372C4EF6CBFFBE1EF481CBE1DE0
-:10B18000FE7410E1DB72BF9A6470ACDAF21EC993F0
-:10B19000055BBF17453CACDAE18ED3ADD8FA610749
-:10B1A000E6A1AC90A17F31F2B37C8CCA474DAD5F74
-:10B1B00026B9CFCF57AF2492B07A3FF8EDA2DFB0D7
-:10B1C000EF6FC7640832D1FBF6BE83EAE3584E86C0
-:10B1D00053B8C35DB5C32DF7566D799DF222741F28
-:10B1E000F4579C8DF9016EBEF6D667EB4745FB69B7
-:10B1F00055EFBAF7D0AE5CB5FD9D5FA3FC58E59165
-:10B200009F6FE37FCA87FAA9DBA29EFB69B61496FB
-:10B210003FB1E27B47EFB5D8B887B7FDEE5ECCB360
-:10B22000BFFAA3F7EFFD67B4179E0AEA28FF577D20
-:10B23000F7852838F8F11EB1FEDE9D045639ABF7CC
-:10B24000EE7F06D278A0F5DD277F3B19CFC9BDFB85
-:10B25000C81FC719ACFEF54F9E47F7F25FFFC30545
-:10B26000E387B3AB905FD301275C69A2ABB143E244
-:10B27000C6CB13E2E9A1C7E1470654B477FF2041EA
-:10B280003FEAB995BD1FAAB83FD963423FE267F7CD
-:10B29000F6D7F77C9595DF61F409E4A00F9BFF4496
-:10B2A0001FE96F2626D973E5F6D71721BCABA09FFF
-:10B2B000F4E9107A3ECFE839334B4FEFF7A3704CE7
-:10B2C000C57DC1AA8719FDCE423A32FA9D35947EDA
-:10B2D000EFE07FE60EA5DFE351F7BD0947E1EAFBAA
-:10B2E000CA7163BA7D6CCE3C886C9C61F87B506CF3
-:10B2F0007930127EAF90385C5D51F3A728EF0F6F65
-:10B300002B1AA4EF62A4EFF78E4E46E3ED4D7FFFBC
-:10B3100017110FFD4F0674FCFD12573DF922ADB316
-:10B32000777FF89C6A505C07A2D26C5686C19FFD5D
-:10B33000C0CA2BB90F1CAE79E0FF2FFA356B7F0D19
-:10B34000EB02F7998C6E54DEC3D61DD1217D61A32B
-:10B35000817A335D46F35E99E6EB61657AE7C578FD
-:10B360001F8517EFFE62FB3ED02C3DF1BE8395DBBF
-:10B370005F5D847C978F9EF6FC759CFF1CF6FD013B
-:10B38000F77AF5D65FC9D627E9292F7DD33B7F8190
-:10B39000CF77EF0F28783EE35D71AFAE97EE59FCA3
-:10B3A0008B73F3A38C431DF7F0C7601C4AE0293F61
-:10B3B0007FF0753ED2FC468BBF77A2868B8F6C3CAC
-:10B3C0001E3E965BFE4F2CE6726325F434A2E9EC38
-:10B3D000B55714485A132BB3F01E46FB82C17BF8B5
-:10B3E000BB32F9853A7A77931CF7CA8B9590FBF7B5
-:10B3F0006FD516737B71E58E9D67A15C3BBCEB47F7
-:10B40000C49F2B1F7E55C57DC79E2D3F50FB6AB341
-:10B41000EB01F543DA81EFC3DFDF79169707B9FD5A
-:10B420005E73C57C563DE1EE7FD5C3EFB9FA5F612F
-:10B43000F592BD30D2386F2BE6A538DFB7F7F9E9C2
-:10B440001EC2B77BE5C65C76F0E462BFCB0EEE7839
-:10B450006ED16FF03CECCCFD21BA7F717BAB39FE35
-:10B4600016B4DFF6FB457CD1FC1DDAA5DB9F0B9102
-:10B470009F67FBFECF503E90DDDF631E7CCE79DE02
-:10B480005A1061FDCDE94BCC948DA172A3EE00DB87
-:10B49000EF39F8E0FAE71AC7A3DCC7FDB181BF5F57
-:10B4A0004E89D3392C39BA88F2CC65DDA70773EA07
-:10B4B0006FDE9F3FCCF7937EC698CEFBDCCF3DF688
-:10B4C0001FB47FEF88FB72E2E13E817FFBF73FD93B
-:10B4D000EFD74B9C6FAC67793C24DFFADAD81C8B32
-:10B4E000573354DEDA5C17C7B8CFB5C5FCBE9EB182
-:10B4F0006F18129E2D99DB674CC7F917432FE0791F
-:10B50000FFDB9BF5B8333E5476D86CC17A67BF0930
-:10B5100071AC87E3E27E6DB4E35AC5FCDCF3907155
-:10B520006B7B092F858CAB9DC0B8B79E8271C327FA
-:10B53000806780CD058DEBCDB3F28EAF4EE379639E
-:10B54000DEF192B63E10F1055A7AC3F8DBFCA29FF9
-:10B55000A5C586EBF7958192A17BABB3791769A955
-:10B560007326C6EF06CF1B2734C77963F69DCE1B23
-:10B57000B7993C0F96B5A375D025FC1318CF5CE6A0
-:10B5800080F705219F0215A918DA5F9D79E211AFB6
-:10B59000083EEF8C346838999DFAF4E2BE61F48677
-:10B5A000B2E69B339CE792153D23B9E2C8E6EB7403
-:10B5B0007F56BEF6DEF8A20D7FE7CE7F82AAA9985D
-:10B5C000379B80D61C706E17EB07EB5562BD581287
-:10B5D0005A1CF5D4189FA75DEE147EA1576E7DA569
-:10B5E00093E2F679F0B443D0F30574CC97D1F64DDD
-:10B5F000C3F86F57C44772B22B98FB1EFBFF2CF6A3
-:10B60000B9E4A48AE71FC90FBB8FF68DC6B1974D69
-:10B61000BC1FE9D65A95FC6091FAFD543E6AFAC8FF
-:10B62000FACF871FFB3E83C1721EFF53BDCEE9BB1D
-:10B63000DBDC46F9B1D74D558DE1F22D426BA6C545
-:10B64000316F425B73761CCF6B876AF8EF61D8303D
-:10B650000FE26106DF863CFCF13F58523CAB0080B4
-:10B66000000000001F8B080000000000000BED7DB3
-:10B670000B5C54D79DF0B93377EE3C813B30C0F082
-:10B68000BE8310D1623A28A2363E2E0F0D3E62468E
-:10B69000C4A809D6D13C4A2218B436A11B1B2E02DD
-:10B6A00082F8C2266BCDAE4D47A22D6DD31653DA6C
-:10B6B000358FF61B4C74ED635B626CE2F6D30613B8
-:10B6C00037AB59D365B7CDD6ED9736DFF9FFCFBD90
-:10B6D000CCBDC30C68DAF4B7FB7D4B7EC9C9B9E7B2
-:10B6E000F53FFFF37F9FC77C4AE4089949C8EE2DD8
-:10B6F000840C151342F8B08DB808D95762B2433A9A
-:10B70000284F4F1AA6E987F0B7606C6A6DFEDB1907
-:10B71000553322F9CEBC442E48FBD999F73819A6E7
-:10B72000A9F5831612A0EDAD3C91FB69EA96C960BC
-:10B730009287E6E55B7C561F4D5D24C3544ADB953A
-:10B74000DFC2EDF08DED7F30E711EF5BB45DBA4CF9
-:10B750003220ED2C17324C3A787ABED04402749CD9
-:10B760008E72612DC0690D7F9E480991F2274513A5
-:10B7700021A9F47B5D8F2CC3FC08C90824C03C4977
-:10B78000468DAE5E0F47D6F4178F1DFF10E087B6CB
-:10B79000DFAD96EF9BF3CEA17B29FCA22C95986997
-:10B7A00037FB06AF92FC69341FBE2A73302F0F9906
-:10B7B0006E2763FB817A3E5A2FD11B241B00CEECEF
-:10B7C0006112A4E327160D1398BF43229249C27E4B
-:10B7D00010FEA4D92344A1F592E60E7B9569BA7EAA
-:10B7E000FE608E09A719E649D7D1D15CEA2F48211E
-:10B7F000C4D63CDF5F40D725811F2222ED2741625E
-:10B80000F88F6EF7CF490C3F1A5E7ACA6F490AC6A5
-:10B81000E87F747D5BCEA4F1165DBEBC670DE0DFF2
-:10B82000E2092A30FFC4D90C2F5A79A2344C643A69
-:10B830006E2261F324A5443E4693845285C0387439
-:10B8400048593F9F07547A7C409D0FFCC969588F27
-:10B8500010FA29415E74D57C2BE479F256112BFF46
-:10B86000D0477041DFB2A979F3D87CBCF94C94EE93
-:10B870006A21E42DDD7C6DD974FE5ABFF4DF1E0B06
-:10B88000C900FC7E54BC09DE61A407EDFB3675FEE1
-:10B8900016CF30E2670CFE8A19FE9CC50C7FCE28BD
-:10B8A000FCED55DBEFFD2F86BF513C71A63540877F
-:10B8B000D178D4EA578CC2AD205DD276847C0AF26E
-:10B8C000816AE0DF1E3BCB1F12EFAC06FE00BE9A82
-:10B8D000805F08C9A44D7AB82E28CF1545ECDF7AD1
-:10B8E0001F9507FA7C50930F6C5C97CF5F4D283DF6
-:10B8F000139F891CA328ED9AAB7861BDBA9153229E
-:10B90000FDFFA33809EB774A8289FB244DCF2C4CED
-:10B9100007B9D966EBB1C17CBB2C3DD84F5B8E49D2
-:10B92000EC8D21DF4EABF335373B671C9D111F8F2C
-:10B9300066810463F1FDDBAA7C6B1B7CEA8C99D2E7
-:10B94000072F09929DC20B4CFFB6B6BEF9B43DE974
-:10B950001FF2F9609C441CC7A5C2E52A349156DF4A
-:10B96000C4701E57E98A6FB68F0B270F70C69033CD
-:10B970001A9CED00A7273E9CCE9C0AA453BED985F5
-:10B98000E30C8A125B0F4B936D239D9FAB35496A85
-:10B99000A5E92EBEA9AB0ED2210B5168150B91CF94
-:10B9A0005450B8F969D309A1FD745C9A659B04B43D
-:10B9B000DFDC43023A391F74042F89B43F5E0C92D6
-:10B9C00020859377293280F1AC4A07DABA91A264D4
-:10B9D00042E6D0F182FC0C90A7CEA080A9D68F467B
-:10B9E000274E8B4CC462E8C7248740DF416773222F
-:10B9F000F5E6BB19DEDAE6860354F691EE129EEC0C
-:10BA0000A09FDA8B28BD24D1BC45EEAAA3F8E87E1E
-:10BA1000D5427A757CA08D9BEB66FAC74E6A93C2BD
-:10BA2000D0B7F9B037388E3EB603DE68BBE60BBE42
-:10BA3000EFBCA2E115FE15133CEF38917633809FE1
-:10BA4000DF27C5AB4DA6F8FDFCAE45FACE2B3A7903
-:10BA5000D54C98FE20444A5F312D7EBBDD2D6446D7
-:10BA6000416124BF870F213EBB5DBD5DF9749E8A95
-:10BA7000DFE42FA4EB45B24B0D788A4E096965725D
-:10BA800070CCBAAE96C2B47D779189B702BD1690DC
-:10BA90009019F092ED41BED4D635E8607463F13070
-:10BAA000396976C998DA008F20EFCC7BBCE3C96B8B
-:10BAB0001BF0490C3C16B9291E3FF1DF0F8F1E37D2
-:10BAC000C1D499509304F8232FEF22D23400C3C875
-:10BAD0007F5A3B8DDEA3E75FFDDF7CFE1A9DC4AF7E
-:10BAE000AF68F6103F48AB660549A89BC37CC0967B
-:10BAF000864D29E854A5D8C2ADA09A72EAFA334E11
-:10BB000011D0CFEDE23B36145DFE0F53C6EB9F27FD
-:10BB1000EF68F83447C6D3E3C7047AE78C25748C02
-:10BB20008BE02941FCB47790DC089E9A6C208F3A18
-:10BB30005D5BCFF84A2378EACC7E4EDCA0A3F72BDE
-:10BB40006285E2A6F8D809766D0C7972AFBBA21DAA
-:10BB5000CA05536C797E48956B5480F30BE9380B1A
-:10BB6000468C789AA7E2697EFA3B8FC134A994E4A7
-:10BB70000915C815017F15E0AD6A4D00C882085946
-:10BB80001F7C2288F45025025E3865B2E943E78DB8
-:10BB9000E32F1EBE5C1C09C482FB19B1E6881BF4AE
-:10BBA0004931C59BCEFEA08421A27CD4D6C5E5999F
-:10BBB00080AED8BABD7C31DDA4D0AA9D5E5308FC0E
-:10BBC000190B69EA02BC93736602765A5A3803CBA2
-:10BBD000ADDEFC10E8BBB4B09DC8E82788213BADC2
-:10BBE0007F70ED5D7ED443D76F23614A3728CB4009
-:10BBF0008E65CB61B0A779512A374B30CEA336F092
-:10BC00006F3ABD354984D9DB24961ED8E20EFE007A
-:10BC1000D68DBF3E1FFB33D998DCBBD1F97C69655B
-:10BC200022013BC07E810B812E3BB0727ED77029F2
-:10BC3000C8CD841E2B4DDB78250C7A4CB96097005B
-:10BC4000DF5B0B95DB4D342DFF95BD88A7DFBB383F
-:10BC5000871FF0D05548979CF6F3BBA79C2142F371
-:10BC60003B572E1F49827E8E9A25287FF2C3A64F0E
-:10BC7000823D65FB603FFA8736D53F247CD32C5844
-:10BC80003FFB479413BBF91EA4FF5D05D36D7AF902
-:10BC90009EEA080E035EB4BCDD4BE5DB0CA4A7B73F
-:10BCA00086293D99148E7C48E9D3E6DAE63D25C124
-:10BCB0007CE9778D3E7C917A11BE35E63D14D760E4
-:10BCC0006712726431D8919D206FD06E250A07EB00
-:10BCD00096C1CADF3FB06231D8A19D76AD7CE562E6
-:10BCE000599F57FE7006F3AADDEB4FF6EC82FA9EE1
-:10BCF0002CD2C4F01320AB74F64C41328FEBD6E754
-:10BD0000967FEFD6D9CD1A5D761530BA7CF9626789
-:10BD100035C8CD4E4A975609E87097C14FD6528D17
-:10BD20000E3B0B189DC5C3BBE57A0909EBEC408BB4
-:10BD3000A707E9D1E609A01D1D5D7F450AB363345D
-:10BD4000FAB77909F2834D0A3E753FF287CB0FECC3
-:10BD5000672D68221CA5138BC8FCE189E6110F3EF4
-:10BD60008DFE3B0BF215A0D7F745E227E3D4B75C75
-:10BD70002FC5F96C71CB93927578F4E451BCC798D8
-:10BD8000CF5792D97C3A027581FB69BF72BDA4205E
-:10BD9000DF7889BF1BF412257FB03BA9BDF9C9E448
-:10BDA000543D9E983DA2F5AF704D8316E0730F6D24
-:10BDB00047BFB6939714587A8B2764E0EF2FA604F9
-:10BDC00067EBFBE145E61F2E34BB4CE423E0673F05
-:10BDD000F5CBC293A99FD82262BAA7C58B69578BAE
-:10BDE0008469778B4CC256EAFE90EBE7EF053BDBAC
-:10BDF000E540F826A28B8E163FB66F6F99CDFAE11B
-:10BE0000343A9FBA0BE8C261D2F8C4BF0BE83CC910
-:10BE1000AC959761BE8763E58F242F58AC14E37C03
-:10BE200050EE754D30AE395486EB77F3FDABF25BD7
-:10BE3000C5DFFE798F54E703FDBD6126FA38C618C9
-:10BE40007A09B3F16EB4FFAE6C13CAD3FDF3769EDC
-:10BE5000F1D1BCE575DAFF78F4D8C3FA8FDB9F0621
-:10BE6000EFE02E84D74AD7DB4EFBB38A4CDEC7E324
-:10BE700087E8F9D294207F7808CAE9FD836BC9CBA3
-:10BE8000C09F7458BB087C1A9021DE25B4531CFB5C
-:10BE900041DF06C2CF80BEB571E418CD0B2ADF505A
-:10BEA000B5AFBC4CFB11641BE9A6ED06E7DD45A070
-:10BEB0005DE72B360A13A5D3947CB417EC85B5A4A3
-:10BEC0008DD6DB596D2766FA3D69FE1A02FDEDFC41
-:10BED000991DFBF79D9982FCBA4B647C34A11CF23E
-:10BEE0009A4858AFC76D8E483E1FE4E57D24300D5B
-:10BEF000F9FA693D5F533DD90BFC24902A8570A067
-:10BF0000871FF0333B4451E569E05832DA81016C18
-:10BF10001FB10B9B8808FC7ACE1CEA06BFC4DC80EC
-:10BF200046DF22F361DB30F2B5BC3CA38C10170373
-:10BF300081ECF287492EE025C34C6D31204B818482
-:10BF4000A9DEE8A1FF007CFC85AB17C8AD84A4AFD7
-:10BF5000110CF3E02F382F996E05F8587D4D0FF135
-:10BF6000171A1BA13E4F74F5D19FA94B1ACF2F8CE6
-:10BF7000B6E30793557FD0497240EFB5B79C206F69
-:10BF80005B22FDF05171252DD5ECF9875358DC6209
-:10BF9000949E2446DF2F503F1DE8B1E31766D21B65
-:10BFA00083BEAF27FB0CF66E46D014991FFDF795A4
-:10BFB0008BD68A8306FA1C7FFDB3EA8DED739A1C3B
-:10BFC000063CE635271BF23E25D3507F5257BEA1D3
-:10BFD000BCB067AAA17CF2A1E986FC94D0A70CF5BD
-:10BFE0003FD15761C84FEB5F62A8FFC91335867C0C
-:10BFF00049F86E43FD1967361ACA670E3D64289FDB
-:10C00000757EAB213F67F8AF0CF5BD41F1E409E067
-:10C010004F4A8F668AAF5D19CA21D09FC36DD48EF7
-:10C020009BCFEC63D0B7249BA8F631554C694057A1
-:10C03000ECAF1DF400C8F93D8F85BF807AD2E407CC
-:10C04000FEE50B16C91BA15DBB68225E9D1C911607
-:10C0500011F85EB1C78DDFE5D256E40F81AA0D7BE2
-:10C0600022E86DE37A10F376D20FF0BDC1E0E3452C
-:10C0700025A67C12B28DF46F25F72405C6B1FB2CE2
-:10C0800092B1FECDD2BF2F45A5FF1C4AFFE689DB4A
-:10C090006B74FF90499E9CC2FCC3AA731E83DF830E
-:10C0A000781DF57B6CA41DD8A9BC6E24EB14ABAE37
-:10C0B000FA3756D3879FB871FF269ABF684A714EE8
-:10C0C000D7C9CBE4B566DF8FD587330CF65974DA60
-:10C0D00096F810CA3B2A17CB530C72315005F31354
-:10C0E0007819E5A2F6DDD73715E57297C8EC944EBE
-:10C0F00089F2E538F88A96CB5F4E9698BF18473E8E
-:10C100000B54CE82C2DDB9F2D35D8037791B41BDBD
-:10C11000447510CAD9E8FEA95D7537C2E965F4A473
-:10C12000F9439ABF65A3F203FC2B9B44105F568A28
-:10C130002F27DA478FA27D49E721817D64F550FBE7
-:10C1400013F43DB53F99BDF9E7B52FF361DE7AFBF6
-:10C150004FD5972187DC94921ABFFF17E3EC479DD8
-:10C1600049D6FCEEFF9EF427A718F1A1D1A146679E
-:10C1700056203A3ADEFB125B77DA2291D3F62F246F
-:10C18000F84F10E9E5D4ECB34A25AC5BD0255BA9A8
-:10C190005EDD37BB06DB0993780272266178C33215
-:10C1A000D093A494C90985FE03F4E62836CA0D5B32
-:10C1B000941E15401F278ED5BB9A7CD0FCF389E4D2
-:10C1C000CBB752D438D92C324B2F5FE2F9E19A7CAD
-:10C1D000D1F0B0E0831611ED8E0F68B9664FD07EB6
-:10C1E0002C397C00E2CC829FC84762F0DFCBAA5E8C
-:10C1F000EE3B6997812E5D6B04F4B332FDE172C8AA
-:10C200006736113FE067F670980469FF3FF4B0F5B8
-:10C21000C8F48738B0CF332F873880F3A085C58521
-:10C2200032B785387DDCE89AEAC7FDEEE2A37E5896
-:10C23000F78A3C17F2E9671713A48F21EFC69E72A5
-:10C24000D857984BFCC03F2E0F4F32217FDE1A4249
-:10C2500079E21F51A8AF4392E944614DAFB490E930
-:10C26000F751FFFDDD161BA6D75A444C2BF38A0766
-:10C2700017D07A5B7D0E8C1774E43B709CCE5C010A
-:10C28000C7F98F9C87F2C02EF8758B17EB773DDED0
-:10C290005404F184CE93FF8971CD083D53AC7901EC
-:10C2A0009E30EEF710BEC90BFBBE49F20CDC27ED49
-:10C2B000B404FF7103C413D70AFE6331F837E9E50C
-:10C2C0001FA19F0CF8013CB4DB195EACCE26BF1B4E
-:10C2D000E2FD93C8FA15B1F854C513A530B340E98F
-:10C2E0003789910611E686DA1241AFFA493F059B7C
-:10C2F000583A421CEC8790074509E245D9B6D02050
-:10C300009467D78BFE36AC4F705F415B278B9D04E3
-:10C310008EBBA05E98DB42BFBFE811D9FA0D8570D5
-:10C32000DFFD37176E1FCC21F1F97B4F4BF5D92A72
-:10C330005D3CD64562EF0BFFCB6D15160FEDF77622
-:10C34000806D26ACF7AC71F5E38DF67BBB8753E3CC
-:10C350001393D3C15E6EE663DB996691AD0FC47F24
-:10C36000C08FDE5A28A5BB5DFA7E183ECC279FC73A
-:10C37000F57116B3F9B77DEF8DCD8F513AF977DAB4
-:10C3800010E255AF5CFC0CFA8FEF254BFBC1EF526E
-:10C390007E6C26B0CEEF7D7FD669589431F36E392E
-:10C3A00093CCEBE249EF7DFBD5320BEDFFBDE75EB1
-:10C3B0002DE3510885101F5A79E387AF9541FC4A58
-:10C3C00068FE4DE6650AAF52418A9A204F0D68E635
-:10C3D000876E591A1E076F07D31ED802F1C2509BF1
-:10C3E0004BE4A8BDF625E71F05A0C766809FA60FF2
-:10C3F000DB4676727489B9F4779754D1FEB6728AA7
-:10C40000E2E2006F8A15FC0A72C1EA07BAD95AC87B
-:10C41000F4E5D607C59002722CDCC4C8DDF65AE6F6
-:10C42000652A87ED3F0DC11900D2CE052A13207E63
-:10C43000378D20BDDF76AD290FF695DD44C8073A6C
-:10C44000B498CCD8CFC84567A817E56FD32C9043D4
-:10C45000AD171F9D0CEBF57B55BE6871B73453D3F8
-:10C46000813A1FC4DDFC1877DBCDF7639C3EDE7C90
-:10C470009D5EB6AFC0571235DEF5DBEE7076841EDA
-:10C4800034FE8A6EB7B785F861BC975A6C98BED0F7
-:10C4900022627AA2C58BE9F75B244C075A8A30EDF9
-:10C4A0006BF1FB0B2C00E76C4C3B2C647D40476729
-:10C4B0005FF0B0FDC87B92CABF0074FE24EDF73276
-:10C4C0006DF745DAFE32AD3FAF366C86B8CCBC11A5
-:10C4D0002A2F2528EFC2EFFB697F506F6CB9AD049E
-:10C4E000CA4BABFBC380C7D262FA9D407F7D587FA9
-:10C4F0007FCB093F2B1FAAB450FC96FE96953BE7D5
-:10C50000D27E68DEA9F643C72F61F567637F745C4E
-:10C51000CCC7E8B784C173A224163CD1F5A9956FA6
-:10C5200026548F88F0BFE0EF59240EF75138123EA1
-:10C5300006F2F882B51CF4E79E12926FA2FACD9231
-:10C540005AC041FEA966229A4BA8CACBA8D9554E1B
-:10C55000A09D8CDF95557CE8980FF513F6ABE9A705
-:10C56000E4EA30EA9D243FC937BB69CAD381A753A7
-:10C5700054DF4722E70D503EB13CAE076D2756937E
-:10C58000C8790332717DAA5FA2CA63D3DB474D210C
-:10C590003EA63FF771701EB1835F4B7DFD7E924BCF
-:10C5A000F3AA7DF645B5DEFE7965491B21BFF8810A
-:10C5B000A7200EFE1BE2E5603F7EB47D943D77B878
-:10C5C000E54C5A55A1AA1440DE6F138FE8EDDC6CE0
-:10C5D00085D2AB8E0F7A9AF8EA5E8C2F04336A7498
-:10C5E000FAADC312CCA0CC4BAE3FF18F8B413E8055
-:10C5F000BE06393D7784E9F751BDFE5B261F357BCA
-:10C600004250D76B9FBCB12D01F7D3A83E92C0AE6C
-:10C6100008920ADA3EB17CEBCBF09D9418BF270854
-:10C620008C8F32BD210EF2999EC04F3CB0DF907CC2
-:10C63000487E86CEF7B7035609E8AFEFE4DA7A888A
-:10C640001B3E4C12253BED27F3A54B02C0D1611ACE
-:10C65000168008473CCD4B786A0775089A9CA486DB
-:10C660000F5DFF8E34552E90DF7757D1FA074DC1FD
-:10C67000AB54578ED63FE8086E813CFD936D54AFA6
-:10C68000EF1D8DA36FEB96294DEC55E3E6239ECF6E
-:10C69000762BD990A7F5DD2CDF4EDBEF750F794DAA
-:10C6A000349FC86DE93E930379ADFE966E85B6BFA3
-:10C6B000EA61E700882BE803B9379A17693E41978A
-:10C6C000E7599ED858DA77F23F05D0431D6923A772
-:10C6D000B3009F3FE4FA41BE36BEFCF541C86FAEE1
-:10C6E0002712C4E7324F1CC175F8AAB97C04F0D6F2
-:10C6F000D7724644431DFEB475A176EA142FC17863
-:10C70000B210E242F960BF15F798D07EDB4E49B017
-:10C7100004F0DD9506EB5C91C6FC812921DA8F8E51
-:10C720007FA650BEB34E0775651919D6FB5BC46F63
-:10C73000027811E5F01FE57F2F01FDD4375B714CC6
-:10C74000A5E36DDAC0FB5B25D03FA15601D6FF04FF
-:10C75000877AC2772663C73768FE5A7F4A2FF81B4D
-:10C76000961D8C3E37F9FAD3A6D3B4C3CEE86293B4
-:10C770005BCDBB8DF976D59EF4BA157732FDBEF947
-:10C78000C4815C3000AF1E9B857EE4660D1E720086
-:10C79000E1B93A3827E9363ADFC69FB2B866E340D6
-:10C7A000C912987FE31E13013F6EF300A5271D7F7A
-:10C7B000ECA37C284FA6F3907BA6F2943E02070BD5
-:10C7C00096DAE9FA7E3D5F16015FF569B7EEB6517C
-:10C7D000E7E8EB823805E8A13EAD7437D0D3A6393F
-:10C7E0006F213D26A596FEA49AE2EBE8DDD54B40ED
-:10C7F000ACA599185F5282433967766F43FCFF6B93
-:10C800003919B1BA119DB8CF9907FF47E19B2CCADE
-:10C8100015505F5C465D22A053217012EC10A5C23A
-:10C820008671D20A711996E7AE21A66E0ACF112938
-:10C8300039B99536B517C826B053F2030E8C7F9AD6
-:10C8400013AA76803F7AEC1CCB47D6E912E2C55199
-:10C8500014EAB7D17E6E71F122F8226966D906EB2F
-:10C86000467979E85829F00BB303942F1663BCE797
-:10C870006022A97F8EB63B6ADAD8FD235AEF68B2F0
-:10C8800087805DD9C171EB6BF07BC5D4AD743D8EF3
-:10C89000AAEB6776FB4558AFA36E637E2FB7F141D5
-:10C8A000C0DB23A92F2E81F9A559E59E140ADFE7E5
-:10C8B000525FECF666209EF36DB4FC737FFD42B7C9
-:10C8C0008DE2FD68AB9C29EAF293FF40A536CEE3EA
-:10C8D00005E453DEFDC587808F69F98F6D54FF7EB7
-:10C8E0003D59B307587941BEC6D7D4AF9D4DE168D5
-:10C8F0001DCD2BB622D8F78AD4AFA27CFED5A7CD0A
-:10C9000044EB1FEC09C79C7E9BC38CF3200EB067E1
-:10C91000A6F168CF38DC6C5D1D53F2D14E3A6A67E0
-:10C92000F81AC93161F922F3B322C407AC53781362
-:10C930009EE5214D01D0CF7C364F58BCF7B03C4529
-:10C9400082B029DB1FE47A56A07F682FD2ED071250
-:10C95000F0638DFB877C54BED03A9C61A27AD87379
-:10C960006105974BFBFB6CAAEA2F7A4806C4631F4C
-:10C970004D6572E6D18072BB45021A1B66E75649C7
-:10C98000603AA4E9EB0AD2C73BBF32F65C4018ED2F
-:10C99000B23D2E938AB749BBC305D45E763D27824C
-:10C9A0001CA16A7EC761D06F1E1EE9A610F89FE623
-:10C9B000B7B9591CDED7B7E44BB3C13E7CB5D00440
-:10C9C000FCCF8B7E11CED99527942681DDC68FD2E0
-:10C9D000E9EB4BC240378373EE043F5000FEA59F46
-:10C9E0000FDBD9F9D0910CD20F7161DE2B13FD3E14
-:10C9F000A1C6BF3B5B6C98527FFE5DD01F5FEB22F0
-:10CA0000B84F2078039897DA09077CF1F2A7EEC6B1
-:10CA1000719FE10349EB40DE9E63763D900BC63982
-:10CA2000C24F7010E778DF16488279EF771BEDBFB1
-:10CA3000B23466C776A632F9D9D9C2E2A0C2F54FA0
-:10CA4000605CA7C3A2C923D7D2F05CB0E783788E1D
-:10CA5000D61ADC2683BCB21145117571725BB631F2
-:10CA6000DE255CBF95C58752D938D1E70D5C9CD6D1
-:10CA70007FC1EEF1FC032D8D3E9FD04C02288FC864
-:10CA8000103BF7B06D57657AB2AE9F6D9C9C2E8EB1
-:10CA9000431F0F5F379390EE9CCAC3FC8800F37965
-:10CAA000F8BA80DF897738B115F66528C175C33AC1
-:10CAB0003EFF5DD44B0ED213860373568853E8CEE7
-:10CAC00085122F3F324AFFF911FEC07D752E067F79
-:10CAD00048C67CF47EFAA3E03BD37F77387F2DC035
-:10CAE0003CDFAB242360871232BC08F8B7B1D28197
-:10CAF00071EA87498FCD06062EDF23EAE3C58D0351
-:10CB000097123794E23E960476F0C32F951BE254B9
-:10CB1000DAF9302DBFF9C4068C1F3E7CF49A30B58B
-:10CB200014C118B2507FACD1D673C69A1FA96FB783
-:10CB300004952CA0FF975AE52CFAE95B00279CABE3
-:10CB40006A9E340BFCBFDF8AF519802727AFEA8F76
-:10CB50003536D41FED76EAAF019D5E9C8CFA9416B3
-:10CB6000F3A09FB5F15778181D8EA8FE7C023533CF
-:10CB700001BF1D8EC01566B41399A7F64E47B24685
-:10CB800037CDDDA0FF0E0A11B908933DE860F9E446
-:10CB9000B4E6EE76A687B1FEC893FC6EB0873AEC99
-:10CBA0006ADE43307F50E8413F41F9BE5502380FFD
-:10CBB0003A027EF007951D5324D02755E92E9C8715
-:10CBC000E5EFACBD200F333DC1AB60B7100FB38FA5
-:10CBD000DE4BBD904B5C31FB19E16EA41FAFB11F62
-:10CBE000FB5C36FE7B9C39B0A334528FB60FE3B9A1
-:10CBF000807B6C18FFD1EA1FB618ED642D9D92C69C
-:10CC0000E20C204F80AFB5EF42F03EE45F2B69426B
-:10CC1000FEB57A8DFB451A3F0BD7A718E297DF4A7E
-:10CC2000F5E1FA687240B85E8CE59D2A9DEE847D40
-:10CC3000F471C7498E33CE0C9413F1C72953E5081C
-:10CC400051E3493C9E33D3F824BEBC30C671A3E502
-:10CC50009F966AF2EF884AC7FF600F2E4CA3FFFF32
-:10CC600050A87F91035B076F85F5F9A36AF716F566
-:10CC70001D3809E47745945B5353E13C957C1CD205
-:10CC80009BE59BFA3436DE5839C6E20FDB1E945022
-:10CC90003F3FC3FB1DFE1870D75F771AE4577EAA8B
-:10CCA00084FDD5F30ACAB1FAEB8958FED1FBB793DC
-:10CCB000D08CF1FA7761F968FFFDACFF973FF5E39F
-:10CCC00083B3A1FFE3169355E7CF6D3BBE301DE262
-:10CCD00095DBEC542E1BF95606BEE57D64D40F029D
-:10CCE0003EDFAFF945CAA2DD5573C16ED5F1F96CCF
-:10CCF000B0BF22ED79BACEFB1D5AFB3B77833D34A2
-:10CD0000A6BE33AA7EBED6FF6AEC3F1A1E4D8E40E9
-:10CD10001EEC2DFE0F560D3E9443074C51FD8DCA5F
-:10CD2000A520F6B7690EB33392FEBAFE270A0FF4B8
-:10CD3000172ACF023BEB4122C139E768BC27A9740F
-:10CD4000587F7D92615D23F8BEC5F0FD9F5BBC24DA
-:10CD5000A4E3B7CF04B72D027E4BD2D689283BB1CE
-:10CD6000DDE12C12D2F1DDFFC0F151E1B82D0E1C36
-:10CD7000F3FFC270F80C7C1981A3C0F0FDA3C2615F
-:10CD8000B65DCFBCACCB5B4492A5CF97846D599771
-:10CD90007576CB8C33A2213F73C86BA83FEBBC6484
-:10CDA000289F335C6428BFED8ADF909F3732DB50C9
-:10CDB0007FC175D9902F278B0DF52B6D2B0CF98525
-:10CDC000E25A43FD696A9CFC76EF0643BDC5D283F7
-:10CDD000867A4273CA77C07E59F0C1021BF8173BAE
-:10CDE0005DA6EA10C5CF4E3E684B8E211FCBD47E88
-:10CDF00047F59D370DDB2F149BDA411E2EA4AE7034
-:10CE00001BB5D7D2EB02EDA0F7AB45229AD16F0E3E
-:10CE1000B1F8C9072BABE0FB9D8B89D8ED8EE46F91
-:10CE2000FF2B42206FCD96F15C9BBDD884E7067640
-:10CE300017D78CBBFFB04FB5DFF744E9FB51FA3190
-:10CE4000B3F393D1DF8BD3195D1D58B08FC03E81F2
-:10CE5000CD15C27B3E8353767A21FFA505DFF6828E
-:10CE60009FD135E5112FD04F67CE570DE7F21C0546
-:10CE70006C7F26BADFBF55FB2DB8FEA80DF4E7EE98
-:10CE80006C86CFE87ADAF9F4DD361637FFB8E6B902
-:10CE9000F8639AE7E5746667EDB68530FEDF5DF40A
-:10CEA000F1C07FAF3ACE81058F1306EFE3780EB95C
-:10CEB0002B4790F47A564BE1DE28CCA7D3B7D30B9F
-:10CEC0007AB7CBF788C1FEB7C27C628C63F3323C81
-:10CED000ED163FDEF93CFE27CF6767CC7D775B9C84
-:10CEE00079156BF3F2AAF7283EA6793DF5179E5700
-:10CEF000581D2F359DD9A7BB25C64749E6C0CFF39E
-:10CF00007DF1F92F69B6F19C5282DFE807E417043E
-:10CF1000C63D7F745EC54F3C7E5D635152018ED726
-:10CF20005BD839DB7380479A9E0F4EAA80FB0AAF0D
-:10CF3000C3792D0EDAEF48186F1DD606CD063827B7
-:10CF4000920F25E9F9888FD56B8CED56059CC6F3B9
-:10CF500052EA39038AA7FD105FD6F036669DFF4C72
-:10CF6000788A476F378AA7EEA29BC3D344F49D9A71
-:10CF70002E21BD4C84278D8EE2F5F3FF2A1D2DBE98
-:10CF800071FC20FD7CDCF8F9AF463FF7A64B37C4B7
-:10CF900067FFBFE2E7F11BC4CFE8796B81D4C73AE2
-:10CFA00007D2E915900E27734D6717839FBDD88C64
-:10CFB000F1B3D70E1734927C7D3DA6075E5B36A990
-:10CFC00011CF8F553BF1ACD65953EC7E5F53F1F145
-:10CFD00090D7AD9EA7F3A782DD7BB67AE5B8F322A2
-:10CFE000CBCCC6F38BC411999F99F64BA40A8C9FA6
-:10CFF00051BC1E1B67DDB5758B37DE8DAEDBD9EA04
-:10D00000B69B5A376D3C8AA798EDEEF6E6DF10DF47
-:10D01000C309768637761EA0EF7166B7F701BE6941
-:10D02000BFBF84A20CB0FF09C6FD56AF493F02F056
-:10D03000BEE665F1F001416AC47741562EDB0DE78B
-:10D0400051CEAD727310D2D0E038A6AE67595D6C88
-:10D05000BBF339B53CD29E2393A5B1F58EA876CF0C
-:10D06000AA3A0EED07C2CB39FA773FFE21AA3CBAA5
-:10D07000FD4BDE442C3F17E73CE6B7D4F6AB6BC75D
-:10D080006F4FEA53F0DC1F21528EFE3EFA285DA955
-:10D090007CB0C21BFCBE97D67F9D0B7EF973104FF0
-:10D0A0009DE2C2F33D84273ED8F71FED8797F1BC80
-:10D0B000C6E54686F7E87E75FD85BDA9F1FB8B8741
-:10D0C0005F6D5EDA78A524807E1DA926E27E36BEDD
-:10D0D00019CE39DC59499A707C5E427852DEA4FE42
-:10D0E0009C2F421F174CD23ABC48A3F633F0FBCA20
-:10D0F000A5D0CFC05993B8C3171FEE78F2E09F5464
-:10D10000FAF198833BE05C0159CFC53CB7F72BAFF0
-:10D110001DEBEDF78EEED7E338B73C19B448B4DF1A
-:10D12000BBD4736784047356E8C6DFAFCE3BBA9DA9
-:10D13000C7CCF6C7C91B66C45F5FEF4339B1F8E7D8
-:10D1400035D55EDEEF2D32F8C7B5812D16B06B6B8D
-:10D1500097ADB0482E289718DDA970F409C19C122C
-:10D1600057044F71E58F8A9F81F3413CB7B1BE9957
-:10D17000C373C7C5DB19FDADDF3E686AA4E911952D
-:10D180000F57C03E93AE3F77069B5F5FAF2317E01C
-:10D19000EFD39FBFA0707CFA10C1B89D2DE3E93D8D
-:10D1A00010B71BE6881AE7332D87FD8661755FACE3
-:10D1B0009096B702BC55A9C8E7EBB7AF403FFF96C2
-:10D1C0006AE6E70F0804CF01BD392F2104EF1D10D7
-:10D1D0009B3CF828CDBFF58724D2ED8FD0C71342F2
-:10D1E000781AD0476A5BE073B1E2D35206E3F3DF0B
-:10D1F000BAD83E5E3CBC9C55E5A956AF86972CB18B
-:10D20000EAAFAC36CA350DFE146BF83D12239E3ED4
-:10D210004A8FA1F1F5DD2F5439FD5A94BF547B3E5E
-:10D22000B6DF3237433DA71BAAD884FA4AB14A7801
-:10D23000B65885C7A3AC467C7EB8948890BFD32AE5
-:10D240003D0DF0DD556B8E92C321EC67FD32A76179
-:10D250005E4FF4FE781ADC4BCA2F60F2F7FD2217FE
-:10D260009E137F80340970FEAB8E28F3912F896462
-:10D2700001FA3EA7E24F83EF1C91136682BC683629
-:10D28000C7E4AFBB543A3A17A85C85E7DFDBCD783B
-:10D290001EE1526DCA72887F2B018B1F8E375D6A2B
-:10D2A0005F9970BF6E5D35BDA7D935E78395E3EA19
-:10D2B000AF5501E37AF5093DB8FFA75490A66394F2
-:10D2C000CE267FF9F2DE59347F36642A61E7DCD856
-:10D2D0007CCF86B2B473F1844FA3EBAE165D350DEF
-:10D2E000637DE56FD8BCD6D58516C296D83D877AC2
-:10D2F000F6CDA2F9860CB7BAEF387F1EF0EBAF9AE5
-:10D30000C7B707A2E9E996271D867CD97922E07B79
-:10D3100014DB62EB87F7B29C6C5F87F7E7C23AAC2D
-:10D32000DB1EBB9E3BDB85F5AEFED15C1FCBEF3E2B
-:10D3300090C5D6637D3D17539E1FC84A60E50DB169
-:10D34000FB5F95E954E59D980BEBB23E0EBC2B328A
-:10D3500013118EB73B56AF83FDFB2B51F655452677
-:10D360008343CA64E72BAFF6BED09106F4B09313A3
-:10D37000E11CD95B6EFF14A0BF0DED97D0CF4F57C6
-:10D38000EB3BD2034F66D0F4EEF3CF9D82FA0375E8
-:10D39000C4CF49F1F5C0E10C4D0F68F7A2357DD837
-:10D3A00063077D04FF0BFBAB1404252919D65D79B7
-:10D3B00008CFC5F43A44760FCA3F536F577F43A551
-:10D3C000E7AB476F6EBDEFA937DA4567C1FEF3449F
-:10D3D000ECBFAB82B4B7948E7B95D25B2B9D0FF9DB
-:10D3E000E0895BF5FA46E38778E3DEA81D78F5E887
-:10D3F000CDD98113CDF36719BE1BB203DFAF7E62B7
-:10D400005FA904F3ECB93596BCD5E4F22F55B918F1
-:10D410004D2F5AFA4B55CE5F098D0FD7670E19E184
-:10D4200059D7648447E38F2BA13607BCAB45479F90
-:10D4300006EBACD9A5A46AE60DBD17120FCE5FAB03
-:10D4400074F2AB66338F72EF2887F1E95F353F9155
-:10D45000182B6E153DFFAB264A0F401F4FF3287F58
-:10D460000AEB379C4C9322F4F87F543CFCA974A837
-:10D47000C9574D9F44B7FFAF4A779A3E9B88EE3C11
-:10D4800071E28F07326C88BF0DBC28C0FED1810CC1
-:10D4900089E589B8C80BF6EB6C76EE9D4AA85C78F6
-:10D4A00057E26AAF03EF8329DDD650215DC72BBD5C
-:10D4B000B74DD1AFE3EC4CB61EEB1BDC3B61CBFAB6
-:10D4C0008AC9BF381DD6AF86BDEF71EE7CF2A2745B
-:10D4D000DAFE892113BC9045D66DDB6086F9CDCC90
-:10D4E000647A64FDF657D1EEBB59BA5EDF64D4E7C7
-:10D4F0005FCE10553DC1ECF03BA95D00E708E3E1CC
-:10D50000A13093E1E19EFAE3284FEFDDCEA13CBDCF
-:10D510002593E1E35E3E847299B433FB99D8283EAB
-:10D52000A85CBA0493007CFC35C7CE77F30141FFB9
-:10D53000FEC6FD7B562F043B309A3FBEA7E2E92B87
-:10D5400099EA3B84E9C13B33D13F0C70D0DF5B9F4C
-:10D5500067F0AEDFBE05CF275FCC50ED6B953F2F58
-:10D56000C23ACD8CCC2F459DDF05C7C836D0179465
-:10D570006F4C78BEE47533C275F5ABDF6C827AE22E
-:10D580005417DEF7423B96E6FB9627845A75F13A2C
-:10D59000CDAEC9F7337EA8E565835DD890E933D871
-:10D5A000E9D1F6C6FFE80396F6A878FA4BE983C3FB
-:10D5B000AA5DF0A7EA834754FE8FD60BA37CBC93E9
-:10D5C000F1F1A5F3FFBE10F2D17CFCADCC8FA69794
-:10D5D000A2F9F74AEFDD48D7CA1222161AFCA39C1B
-:10D5E00010F8C1A3F41FF1933838DFF644EF4FA6CB
-:10D5F000419CEBD2DED5EB628DFF4416B3B33626E9
-:10D600004A267C1FF2754667D17222BADD285FC4B4
-:10D61000892FD6D6CC41FFF05CCD6DB970EF2DDAF5
-:10D620003F18539F935357817FDCAAFAC7FBACF591
-:10D63000BD31E0F566317CE6178C9C027CBFDFC013
-:10D64000E17D62F8D3DBE9779FF7FF60581A0BEFB3
-:10D65000685EF34FB6B3F1A2C779575DB751FF4487
-:10D66000A1FE09C5F370AD3911CEB16AFEC9B0F2A1
-:10D67000E7F54FDE2423FF300BD6F9686CB81CEABF
-:10D68000FCAF08C17D73281C579798FD0AF08B8961
-:10D69000B6D3F925D1EDFEA8CEE7CDED37298FCE53
-:10D6A0001BE3C9F1F86D14AE3F91DFFA84911CE0E1
-:10D6B000FB378F7C70F15198CF1107BE3F16DDCF3D
-:10D6C000D7B2CCAA7FE0403ED0F4EF80D0B3F905CA
-:10D6D000DAEECD3B32FD3B888E2F08E50BFAFDC21A
-:10D6E0001F295FF851BE211FF7F53AEB63F9298333
-:10D6F000AA3F141DB7117BBFD1047EB14CFC167D2F
-:10D70000DCE90D75DD7FA1CAA5A22CA63FEFAA5DBD
-:10D710002140BCE8FED1781141E7429C9A7D04FC8F
-:10D72000CBD7D47B02CAC68498F1DE992A5E278AB9
-:10D730001FACA933FAF577D51AE5C73BA1FC513DDB
-:10D740005238CE7E9446BFF1C6BB51FDD117BAB94F
-:10D75000FD8089E6F7D9AC1BD31FAB48D33C8C7353
-:10D76000D0F581B496344D7B81C2F3CEA19509608A
-:10D7700047FD82906AB4E33FF8EC34BD5D1254F18A
-:10D78000FC7EED67EF00727943689A164BFF44C741
-:10D79000697E118A7D2EE32E55AEBEA1DDA7B82B82
-:10D7A000763C7F8B3AEE1B75E3F34D74DCA67699DD
-:10D7B00071DE4A16B387DEA86B7304995FCDC6FD90
-:10D7C0001B362EE82DBD5DAA64FD79F4E330C4EF6D
-:10D7D000619CED84403CA54F50A6EACF5DA5643323
-:10D7E0003CE4178DBF0FA5EDA768F5A2EDAC9F67D0
-:10D7F0004A867BB3B5CB8C70B569F62D11310E72AC
-:10D8000015F4A527A22FEFB4FA1F043A202E09CB56
-:10D810004FA878BFBBFEDF2C307F2A3F3BF01EDBDA
-:10D82000599308F2B3EC7CC8A2C7CB851BF4AB2E8E
-:10D83000A8F6C2447234BF6804E5DBFB2117DE8F13
-:10D8400078F30BBFB3C4EAB7F67A96E11CF1FA405D
-:10D85000ECB88A98258C8B6731CB88BFF5D773F1EC
-:10D860005C703CFBFF10C8AF99608F1EE9D0DBFFF6
-:10D870004F6549AAFDAFCA339ED9FDF1E2AF432AF5
-:10D880009D4D147FD5F4B3562F7AFDB5345A5F0EF3
-:10D89000ABFC1C5DEF52D68DD1DDA81D1387EEE2E7
-:10D8A0008DABF91F5ADC37BF98B68FB12F33661C8A
-:10D8B000B55EF4386F46ADCF183F224EDC2E299B63
-:10D8C000E13718276E9794CDE2766709D38B4AC863
-:10D8D000897AECCAD17BF781B9F7C0E2CF9D06F512
-:10D8E000D6A8C66BEAEA5F3D057EAAE65744ECF18E
-:10D8F000601BEC935DDDC1A1BD113D4EB45DDE0842
-:10D90000EF15822055E307456619E3D4E43176BE6E
-:10D91000DFD3BC1AED4B2D3EDD27047624D0EFB7C4
-:10D920006CFFB76DA05F353FFE2D8BFF411667661C
-:10D93000F6EE855E17DE73DD3AEAFFF931DE38CAAE
-:10D94000FF6AFC71A2F518953771D6632279132FFF
-:10D950002EA2A5A3FB2C8254F80A9C4BE512FDBD18
-:10D9600034AD11080F78A859CEA19F5923C84B3167
-:10D97000DEFCAAC90479DF72DF6E3807BFB2DA2293
-:10D98000DBA5C8FE4BE96B0D85AF807F41270C7E80
-:10D99000ECC02FA57F82FBC1AF2FB64BB03F727694
-:10D9A0009E34E8A1F9B3777022D83D558BEF374FFD
-:10D9B00083F15671F80E8DB399A8E7B56F5D5E5986
-:10D9C00040C8370044DDBD8F1A6D9F4659BB0FEE2E
-:10D9D000CD4E4D1D30B9284ABF7B78ED3E1B85AB3F
-:10D9E000A335E085FB78F76597EC83FB786969F2EE
-:10D9F000D0026A471DCC9EB11CF2037FA3F557BA33
-:10DA00000FEEDFBD680AFA385AFE83EC65CB79D891
-:10DA10008F98A48DBF1ECBEF5AF2E0B16DB4FFB763
-:10DA20000F6F590E67D7CBEAB4F11F595EC953FA8D
-:10DA30009FABE51F4B84BCC74922FB4CB309B144E3
-:10DA4000EEF7E179F781D1FB7C2DCBE1FCF8EBE53A
-:10DA50004D95708FB3ECCB1DFB8AA710326B59B973
-:10DA600028D3FCDC9C2F2F77C2FE31A1F448F3723F
-:10DA7000CE57107E8FD9A4F61FDA2767033CCA540D
-:10DA800028E79467F655BBE13EC2F06920CB879B3F
-:10DA90007B6C69867B098A0CA68970A23C9C85E018
-:10DAA000A8FBDAD9E169ECBE9D9A2F62718AD1BCDC
-:10DAB00097E50776C4BE7FF2610E935F038ED8E5CB
-:10DAC0003D2ADF6BFBAF49E789FC6C0CFEFF3CC4D1
-:10DAD000FD6746F8E914C4433CF8E45C532BECC3FF
-:10DAE000DA189CF1F671F7A9E314B426E13B45CBB3
-:10DAF0009A9CF8AECE243F9337948BF89520FFCDB7
-:10DB0000268433D5CCE17B26690E123C4ED3D41447
-:10DB1000F6BEC9328A6A787764E1A4C0513CDF9BC3
-:10DB20009E51D206E7EB5A7FCE831DA6B51F0BA7E9
-:10DB3000B805E04C35D7946C29D6E1AF98C14DD7E4
-:10DB40005D6D277F13DE7B19189A9A0F767565B67F
-:10DB50006488CB940DD558E05CEAE51C554E48AC82
-:10DB60007D6A25932B235BD4F72A6CFE12435C5FFE
-:10DB70009D7F65E7B22F41BD86210B817388DB8EC7
-:10DB800097E33BFDF1F8BF01CEBBEBF476031FC674
-:10DB900073E60D70DE7D06F4F75301CE37423FE0A9
-:10DBA0001FC0BD0EB09B52DB62AFB716576EB8EE0A
-:10DBB00026CA0CFD7786AF48FF1E2C9F685E91FE3B
-:10DBC0008CF7F8C6F6A7DEE7D3F0CEAB781762C3C2
-:10DBD000F9AA469714DF261D3DAD52E98B4A3F7CDA
-:10DBE000D7F7C2F2E25EFD7B0584EC60E73A78BAD3
-:10DBF0008E604F0E39F07DE0329EC9C7B2A16451EC
-:10DC0000E1C6D285B6AE03C94DF83ED1C80A2EE6AC
-:10DC1000EF0F9CD7E052EDA7F4BAA079830E3E8DAA
-:10DC2000FE23FD0F7D41E38F75C8B77B197C606FC4
-:10DC3000C03CFCE169FA73201AFCB753D981E7496B
-:10DC4000DB54FCDFE10AF57211BC8DC57FD604EB15
-:10DC5000998BE5654327059867431C3EFD650E3BA0
-:10DC600027927E3E9C08E703966633FD35D03FC37E
-:10DC70007E1BF0C53213E124366FB033CB34F94A42
-:10DC8000DEFB590595AFE9A3792A5F2558875179BD
-:10DC90001BB6D922F57F9AF3DEF276AA3F3C567680
-:10DCA0001F8CDA8F36A2BB8768CD61F1DBD9C1D872
-:10DCB000FBD6C3390906B9F5547325799BCE6F6538
-:10DCC00036D3E7B387157C2749E3EB68B95498C38B
-:10DCD000D6D197C3ECF18F5F2E7113C8A515AA5C3E
-:10DCE00062E5C4136880F234937A2F4164EBBEF18D
-:10DCF00047330A210EB7D56B96E09EC34ACE9FF3F9
-:10DD00002D3A4EAD4DEA489022F4514B6C920BF0F7
-:10DD10004D47807BAF35CBEC98873FB03BFEBD874E
-:10DD200063F447A4A4DA71EC5A0D9EAD5E01C7DB23
-:10DD3000B8AB3029A887930F3C8BF13DA70AA72DDC
-:10DD40004A5FF1C67C5A5AB8D164D695BB98FEEAB0
-:10DD5000F6CAE539605FAAE79BA2EDA27BB23983E0
-:10DD60001CD6ECA2DF79199F50FE45FF319DFA8F3A
-:10DD700004EE7BF407F03C183C605488F775D9FB3F
-:10DD8000C66F1D2773C14FD2FAB92BA7D8D06FDD4C
-:10DD90006ABA489FA4CC69AB942FEBE4D919F57DFE
-:10DDA0007A4A0F33815F57E710633B73201BEE9570
-:10DDB0009374AB1FE4CD29217018D757246E58DF18
-:10DDC00085E62D87912ECCC4DD86E7A48E60FBEA24
-:10DDD000BA9152B4533F308741EFFC3C3703E339EB
-:10DDE000A94E46B7A7EC4DD88E275232CA1155EE30
-:10DDF000FD3C770ABE7FA1C9CFC87D16AD1F567EF8
-:10DE00008A5B910DEFC49E4A9D5CD2C619ED1DB090
-:10DE10007F22F6D2F3FB6EA7FC38ABBA3F4C61A66B
-:10DE200052E5A5E58FD2FA5B7298FE3BE50B0CC07C
-:10DE3000B8A7DC4404F8670F079F85FC62AF13DFC7
-:10DE400071D3D623CDC47E1F264DFDFD15E01348AA
-:10DE5000C55CC66F8773D93ABEA3E6D31263FF9E33
-:10DE6000CC7FA8F57AE0FE1FADD75D1EFBDEE81E75
-:10DE7000958F1B6D3DD570955E77CF13EF2DF38495
-:10DE8000DA55B4CADE1CD60FD56788AFCACE3AFCC5
-:10DE90003DB1F78756E1BBAEA3BFF301EF54D17597
-:10DEA0000F9395FB01EFC22FCC787EB3C3C2E8522B
-:10DEB000700745B88794E28CEDEF7E578527C5CC77
-:10DEC000DEEBD6EE2F58D4FBFCC7547B2CD15B8BFA
-:10DED000721DDE58937CF02EDB08DECFD5D631FAEA
-:10DEE0003CAE45BDC77FF3F643491CFBA1D4603F60
-:10DEF00068E346DB1117E13D6E5DBC7B9DF7DC42BC
-:10DF0000A2ABFF6932DC01FD7D7A5B96212E11CF39
-:10DF1000FEF8912A6FC15E5062C22518BE5FA47ED2
-:10DF2000A0A21FFF0A1B3F32AE9328BA71F7E6C8C2
-:10DF30003FCEC1F8CD5C11DFB1B0133C0F5BA6BE84
-:10DF40005F47F513BE5748F55235C86FCD2F02BE57
-:10DF5000179380AFCBCFE6A4EAF4A4DA2E5A1EDDE5
-:10DF6000A1DA0177A8FA26E9BC66373A248E8BE855
-:10DF70009DB17A8B53EDE868F918AD178C7635A50D
-:10DF80005B456F078CE11715AF374F1F93E2D0C782
-:10DF90002D7F11FBB26C6ED03C0DE4663547601FDF
-:10DFA00064569551DF3B7299DFE1C8751ACEE1D610
-:10DFB000D419EB25423DE0AB5CE70DF9297A7DC42D
-:10DFC0009941EEB1FE36ABF4E07BF7AC00EF372EB3
-:10DFD000C965F650499E9C9A4BD3237FA8EC83DFFA
-:10DFE000A11869E549AF07DAC97DC31E98974D04AA
-:10DFF0003FB57C6D55D1115A6EF9A905DF9D2427D7
-:10E0000062FBF7AE664EBE8FF273BE2AE71A3C6C17
-:10E010005E0D9EB05040E1C86C60F064F70F72BCBA
-:10E020004EEE65D7B37AC5B91683FEF1439EC2772B
-:10E030006BAE16BF0CB5C2EFA164D7CB3CE8BBCC2E
-:10E040007E8EA8EF6EE27BA9997ED6BFCB1FE2EE53
-:10E050002D8ECCBBCBB4A218F445579AD30FFAE25D
-:10E060007379C1329877C3857018D036EBC2100F20
-:10E0700076DFFE3C79167CD7E62799C54CD81F770A
-:10E080005E60F0F544D13F21BBD575E965F0B9027A
-:10E0900025004F5AA284EF10D1BF7CD0AB69C9AA2A
-:10E0A000DE482341782F88D8683DB0831CB49EFE9B
-:10E0B000DE260994C23E412875DA74D0730B1DFE2A
-:10E0C0009336D0AFD37DD3E15DA1170EC78EA7D70E
-:10E0D000AA7A87C27FA71EFE78FC31FADEBA5ACF31
-:10E0E00012C78FD6E8DE591DDB5EA59A00CBCBD7D1
-:10E0F0007AEE86F934B40BF81B5D1ADEF7E70536C5
-:10E10000E6A6C23A1DE1805F33FBCB91AE32159E8D
-:10E11000805DD1EEC80DC13BB2EDC99F4A07FCC777
-:10E1200083BBA1D92CDFA7E7E77601D7E348D4F971
-:10E1300035CDCF782C97E9A3D37981AD30FEE613A6
-:10E1400007F09CE083472F09E3BDEB73A378E3EA74
-:10E1500099FFD2B086BD9751BE96473ADCD42EE0E7
-:10E16000BBEA0DCF1E0FE37EF17682FBA00DFDC74B
-:10E170004FC33BAD590DF24CFDEF126435B077E360
-:10E18000D212467F1F5400BD9DD9BFA201E95A2477
-:10E1900022413A0AA2DD956D63F6A886DFD34238A4
-:10E1A00017E267A74DC4DF46CBAF59942289E6AF8B
-:10E1B000F91C7E787FE1EF8FBF213D067886B81885
-:10E1C000BC7B9017FC12E0A3BB959D27EF5E48ED4A
-:10E1D0001E5A6FA1936C85FCC2361701FEB8513CE4
-:10E1E000CC8AA28B59DB199FFC283751E55782EF67
-:10E1F000291DCF4D50EDA8601DDAAF741E9D731020
-:10E200002E9C87982B7F15E9564CC671331BC29CF8
-:10E21000FEFE899646E84A7E3637F566E0ECC77D15
-:10E22000C64DAA9C295F7B947B5B47072FE69A919A
-:10E230006E329F3DC2817F48CB5B177AB03EC607E6
-:10E24000339F657ED3265A7EBF41AE6CC0F97439C8
-:10E2500098FD48E5CA4980EB94690BBEEF776A3AAE
-:10E26000C17766EFB8103E8DE25985F794C0D6931A
-:10E27000A77868A5F99FE54A38FE6921781FACFBAD
-:10E28000E94C76BFBBCBB403DF3BD5F83E9A4F7F5A
-:10E2900096CBFCC9CC3547398827789CCC9ED4E0F6
-:10E2A000D3EA95E4559C05FCCEAA1E423C34AEE16F
-:10E2B000D97D0D159E8542A000FCB461B5BF93AB1E
-:10E2C000BF6D3E44E16B2CE6909E9FFCBB57912EA8
-:10E2D0001B7B38F6BB413DAF0AAB74FED5C1EFBD29
-:10E2E0008A7A65E9008B1F340E1CE7EF7581BE3911
-:10E2F00089F4D948E9CF5E0AEBC6ECD86B96702E4C
-:10E30000E8CB68FA745633B90831D742F60E1CEEE2
-:10E31000FF86D6DAD0EED7E4AFA8C209EF08827C38
-:10E32000FD8DCAEF5AFF117FD5EE07FAF6BD3BFD12
-:10E3300024BCEBD6E8E7FC701EF93F46F50993D7FD
-:10E340005222FC7660A4FF68FCE5E631F91A438F9F
-:10E350007C184B8F687AD6F77405BE97ACAD1FAFAB
-:10E36000E27D54BFE7B1FB578979BC0A8FEC853851
-:10E37000B644F9B9BB14DEF50B144B809F54A71FAC
-:10E38000E23B7FEF7E5DDAA0C3D76981F23BCD9F90
-:10E39000CE77203C942F92F274EBD750CC7E67EA74
-:10E3A000C9EFAE40BC36C0DA51BC3604EFBB0FF14A
-:10E3B000EC25E231902F4126BF1AD6DCC5DE05D709
-:10E3C000F4DF731CE2BF4171E13BD74BFB57207D6B
-:10E3D000128FDD5FC8A15CC375D6F84CCCD5F61D95
-:10E3E000D8BB43D4AF6F857889E6D727D605940488
-:10E3F000692C9FA6A87EFD4CD5AFB7CCB6FD59FDC4
-:10E40000FA4DCD3F41FFE721EF8F30D5F884FA8DEB
-:10E41000067EBA2D8FD92D929A56E431BEDC54DA9D
-:10E420008FF4BFE97213F28FAB9AC911D705A3FC21
-:10E43000D3E260D4836374E8EC5F04FB110BBFC2CA
-:10E44000892007E2C1FD19AEE967705E851C67E7A8
-:10E4500028167CF0F344FD3BA435798CBEAFF599CA
-:10E460004918F0CD3709E3D9BFF1FACB0957CDF9F7
-:10E4700027BA7EFFD29784E782AE3DBBF2F3905776
-:10E480008E26E139929C702DD2C535CF1C3FD081AC
-:10E49000A78DE1E95A7F25D2CFBBE99209DE096B4E
-:10E4A000ED7F623EFC5E74BD0AD7BBDF3537031ECD
-:10E4B000767CED3BF3E15DC94D212E05EE9B5DEBD6
-:10E4C000FBCA1F41EFD51F7D18CF7DB57DF37FA11E
-:10E4D000DD6D0A1D61DFFB9244A877F59903F30116
-:10E4E000BF6DFD6D58FEEE3347307FF26BDF311F9D
-:10E4F0002A8DD0F1BBDF3DF2C3DF433E9088F77237
-:10E500001A824F3E0E79529BC8EE5D055F11F4BF33
-:10E51000DF75F0F820F2A146174BFB39F5DD30012D
-:10E52000CF7968F4FB56457119F01DA550BF793EAF
-:10E53000CD7727D4C78A23EE51E7DB00B408E3AEDA
-:10E54000E142C0075D82D287F25CECCF0579EE2C08
-:10E550000E0BF02EE9EABAE3F3D9CF10B662F94A0E
-:10E560001B3B2F368DF20BBC1F457B3BFA21C4F7BA
-:10E57000BA1E5C07FD1D3613D19C118177B320A113
-:10E580007FB4B986F3530E231CD9762A15F6C79AA1
-:10E59000897AAE8BD5EBA2EEA52D19F510B1D3B4C7
-:10E5A0006C5BEC38E893792E953E19BF660EACC8CB
-:10E5B00006F9413C567FA12FD25FCEF9A66E78DED8
-:10E5C0003FB37E6811CC6349D18619300F0FC4FB6D
-:10E5D00040BF282EECBF11E293949FBEAACAC73455
-:10E5E0003180EF8CD8E4402AFC269B640DE0396E24
-:10E5F000697DC0D20A72861FC95D858AF09861FF65
-:10E60000F0A025983113FAEB52F5D351063F6D8FE8
-:10E61000FD4995B207DAD3FEB13F5B9DCCE36FBEF7
-:10E62000D9D83AFCEB0F6E3F668C9787C6F45FEA49
-:10E6300002FDA2ACC17593049CEFBB5015F1ADDC9B
-:10E64000AA8F6347C77B409EC17EEFE9BCF2C1BC85
-:10E65000D448AAC581A2F1CC4BB49CF65321C998E9
-:10E6600092BE1BBB77A6C9EDCD7B54BDFBE22594C2
-:10E670003B9B833CD3BBC1CBA877FFA545266F53FB
-:10E68000C3F2E0F39790BEEF3DC1F4EEE61325022E
-:10E69000D0B3F61EF2E68A6BA87F153341BADE2CA2
-:10E6A000F49FF642FFDDC44D2D7BB279FEF02D20A4
-:10E6B000FF7EFDBC7D0DB43F653221BD9DEAFDC4EA
-:10E6C00091364E0F1FF303B8FA10F2E366D52E28E9
-:10E6D0005F7BDF01F0C71AEBD9EF116C1E50F98B8D
-:10E6E000FA6380DFCD275E45FAD1EC5EDFD3354893
-:10E6F0006F6E4A6FF8BB095543081FFDF317D2D45C
-:10E700005DC5DEC55D52545206F47672F50F778210
-:10E71000DEDE5C4544E8FF608EFC3CBEFFFB3C87D0
-:10E72000EF511EB4F454C03DC9830B2511F8637337
-:10E73000B076543FE1F9EA60ED00F28F679D1FEC7F
-:10E7400087EED620DAD5DD194EB40B0E3EDF8AFAFD
-:10E7500073B3E4F0C3EF992C3DC16DC5F68A8B30DD
-:10E76000F839B4F397866EC3735B1A3E96560DE77D
-:10E770003279C1E0FEB565E8D330EF5F7FCF0A6F35
-:10E780007E8FD2DFFF05D640AE560080000000002D
-:10E790001F8B080000000000000BDD7D0B7854D5B6
-:10E7A000B5F03A73CE3C1226939327E1E9C90308EA
-:10E7B00098841308EF872704102BB583F2B2220E3A
-:10E7C000C823424846C48AD77E37830331526F6FCD
-:10E7D000AC2FEAA576A06AD12B106DAC51030DA821
-:10E7E00014ABB5D1528A16BDA3222F918CE083DEE3
-:10E7F000D2F2AFB5F639C9CC640262EDFFF9FFE998
-:10E800005737FBECF7DAEBBDD7DE9336D9BFF18E85
-:10E8100032802BD561BAAC03A42B6DBE3B3201D242
-:10E8200000F435986FB07B9D3A9647FE430A6DCE53
-:10E83000C5EFD3C0081501E4DF23192137408A262C
-:10E840000164516A335307C008C0BF0691AA811200
-:10E850006F31C027B5067C3800F84FCB0658CEFF85
-:10E860000058B1A8D5A1617F554F89FE329D46E978
-:10E870002D989EA3BFCB305F013778B13C4B966E8D
-:10E8800098C1A98D53ABDC4A8799F3C87D64E1BD7B
-:10E890005370FEDFA9043D0987E85D88DF310F7EF4
-:10E8A000080DC0F9F7AEF4F6D5A83C73A92E633E67
-:10E8B0002B03BE4FE591350ED82C75ED7724AD6B4B
-:10E8C00004D5F39649582FAB678A1EA4A1E4725B66
-:10E8D00012B52B95F4CD1AE5AF7E14084E59BD74D0
-:10E8E000EA072064C2C15B66C37A47B353F4F5F408
-:10E8F0003DF407E56A84C7244DB5CA4BA99DE601DE
-:10E90000585FDAD96E4ABE97FB9BD233490FE23C7F
-:10E91000A737044A204FC0C1EBEE8443684DF2DCB8
-:10E9200050143CC6131CB07D6830CC6D2C22F87B93
-:10E93000ABA89F6C9B9EB11E3715DC81926B526811
-:10E940009C20C36B00CD03D329B83E3FF59BEF5D00
-:10E95000C5F0C84AD113C163CF25021EBBE76C9333
-:10E960003760BDEA2229E4C4F9DDFFE28C525A6720
-:10E97000F54CB70E98AFF6290B695C08B8E031CCBE
-:10E98000836FD1BD53305F5DE9D5D76BBCEE455485
-:10E99000DE3733495F8FE50F3E2F1994AF0EB84332
-:10E9A0004998BFB259E04375F3D3CA8D98F620BC9D
-:10E9B0007353BB40C98CE2CEF900ACE1F9544F3A35
-:10E9C000D1FF656C1F9041972762DE111EA8E3FA04
-:10E9D000AB27860712BC4E3E9F3497DABF62B30561
-:10E9E000689C57365FBA292875EDE7A4DDDB44EB58
-:10E9F0003F89EB0F60F96F9FFF7388E8612DD28329
-:10EA00009C837BB4462BA7F2F55340A57DB1F66BF2
-:10EA10008F23504878B5272F99F183E6E945381FB1
-:10EA2000A77FF602B8F5126F8D8670AEB6B5D629FF
-:10EA3000D46E4B06C018CCBF70F7409FBB2B9CB167
-:10EA40003DEF8B4B01C65F57A847281885572E17F7
-:10EA5000D2DA304E036E4C7BAC16F089EFE74ECD28
-:10EA6000CDFDAC7085F7E0CE41CDEA065736E29198
-:10EA70002F59E3EF49F680D107E7E3682E6FED8366
-:10EA8000E5D9E9F81FDAB7CD3D42B46FD9D9E07BBB
-:10EA90002641BFAB4C3CB3F6A5211D182FB33DA2B8
-:10EAA000FECF4DBAF98949975BCC348A2E62F1DEEC
-:10EAB000EDCB253E919D0CBEC604E359ED717E5C05
-:10EAC0006ECD0B5CD84F26B5D36C8CDF717417CA32
-:10EAD0002A1E4674372559DFED227A1A963B2C08F8
-:10EAE0009DE320247267A474C5035A07D10FAD8B30
-:10EAF000E8ACBB7A0DBB047F8AC7CB674C3AA9222E
-:10EB00005CC7796F93901E13EEB3E8A7DE966B7B1C
-:10EB100010E7FBA3FD32F3D9F87A56BAAB16A0750D
-:10EB20001040DEC66B53BDC5DDD7DB66D6FB71ADCD
-:10EB30008B53B7AEAD51B0FFA12D5AA90C349E3600
-:10EB400089C60BE078B4CF2913E15319E1E319DD4D
-:10EB50005078672EE179E35C5AD750256C2B25BE9F
-:10EB6000EBB5416BA1E0DFE7F0FF3DE72643ABAB40
-:10EB700033DFCB971E93EF53D93BA67E3F7F5E4C8E
-:10EB8000F925AB87C494E70686C5E4F3EBC7C6D482
-:10EB90001FD03029263F68C37762EA0F0E5D1D93B0
-:10EBA000BF74CBF763EA17372E8C299FF48FFCDDF7
-:10EBB0003F253CA7F527E073561AD17279FF8636B8
-:10EBC000C7AE3F7574ECFA158800D1FBA4E4BFEA28
-:10EBD00089E8D94A5341F92C6CB5233EE0D26C0F39
-:10EBE000E23CCAFF2C87D627988785CF567E922293
-:10EBF000C78C6BF1890BE1579EEFFCF8F263C217EB
-:10EC0000E779E6FD0F39215DAAB9820F28E0E5F525
-:10EC1000A74E9C7BDEF5DBE3D70F1AE3BD87D69FBB
-:10EC200000EFE3D79F3A3A761FACF5E7F90637874E
-:10EC3000B19FCFE74A2C5FF651D198AEFDBD1BB70F
-:10EC4000CED9AB52599F01EF3509EB77CEE34E9EFB
-:10EC5000C7F54EF02782C374130E95B982DE2F4498
-:10EC60009FEF9BF3F81FA24F4CDD6B73991E619FC2
-:10EC70001C1A805D2DAC9776F544BC48F7B9592F26
-:10EC80005BA8B44269949CBFDFA4EF074DFADE5045
-:10EC9000AB723F0FD7E670BAB156E3EF8FD416725E
-:10ECA0001AAAD5F9FBE6DAD19C3E8AFA18A58FD7C5
-:10ECB0004EE3744BAD97EB3D593B97D3A76A7DFC70
-:10ECC000DDDA9FEBCDFD016F06CBB3F8F5CC5F9598
-:10ECD000182F412EE2F6F391CEE4F3F0B52EEDE5D8
-:10ECE00079A9E7C3A3D50773B7BF1C8507D7E5A6E6
-:10ECF000641EEE81FF1805A3CEC9176EFF65ADB681
-:10ED0000FD65FB85E9C2C21738FBE18044F5AEA77B
-:10ED100031C722BFC9DDDC1070770F9F4E3C8AC31C
-:10ED2000572FE22B7E2D21D9DE8BCAC3BDA3C7F995
-:10ED300093B9CF567EE64C81AFF1FDDE6FE2DF2C5A
-:10ED4000C24F2C9F1D47AFA77385FC3C9D2BF4F44D
-:10ED5000FDDDF08B7B726DA6FC14FB3E6B9FE04BE0
-:10ED600077F6983FC197605C294F8BA1CFD9336369
-:10ED7000F771BF5DF0B7FD7F92436B12ECFF85DA50
-:10ED80005BEB896FF72773BD9FFE7F466FFBAF4D2F
-:10ED9000617D7EBFDDD72F2B6A7FF65FDB636EA2BE
-:10EDA0007DFFDF5CBBD8AF421548BE433A18A407CD
-:10EDB000E192020ED2E5A0403D4C7482C610D145CE
-:10EDC000F778A9C0618B9E64826712EBE39FCF4CFA
-:10EDD000E1FD079F6A4054FFA0A8AC976EFB2EEAA6
-:10EDE0000A349E82E3A11E0ABAAD73FFF2E8BFC9DE
-:10EDF0009DFC5AEE9EDE2E8407161F994D7CE43C46
-:10EE0000F2BA6BBB8BE32387888F5CFACDF3118B4F
-:10EE10008EE1EC8D03BC295DCB67111FE90DF0D3AA
-:10EE2000DCB7998F7C6D3859746BEA13F1FCA4DB65
-:10EE300076CD9917907F263F57FCF561C48BDBE4B4
-:10EE40009486F5D8E42EC5FF73CA07020A3C86A94A
-:10EE500073F5E9DE878673B7850AD71BC2F69D5323
-:10EE6000F1FF32CCF6A053A57A0FF5F8F7ED945FD9
-:10EE70008D1CD389E99749FD4380B640699EE03FE8
-:10EE8000B2EB4CEF4351F3B3ABD0273A5FDAEAEA87
-:10EE900073286ADF86EF5563F223DA7262EA8F3AEB
-:10EEA000A0C5948F0917C6948F3BAAC7E427444690
-:10EEB000C7D4BFEC8C11932F872B62EA57B866C476
-:10EEC000E4A7A8D7C6D4BF3C67414CF915DA4DB1C9
-:10EED000FD157887E7E1BA173ADCF5522ADA69B905
-:10EEE0004619E59393ABFD0BC84E5AE3516122D509
-:10EEF0000E85086E750E97BA1EF9D40792D11F10B1
-:10EF00004FEFB3A1D59D8FF5E530507AD0A697523B
-:10EF10009A676CF1119D6E2F4CD6681F920702B450
-:10EF2000919C52F424407EE2E811F95D01EDCB6F33
-:10EF30006CF01826DB5554F4A97E736688ECDFACC0
-:10EF400064DF15348FF5B606CF1ADA671B781FCB4E
-:10EF500064BCFAC968CC1F7E41B1119E6D6FB1DDF2
-:10EF60003316F39F61F7329637B59DF8C995981F10
-:10EF7000DA66D7A9F65090D94E5CAEC03D4A7AF712
-:10EF800078F6F10F843D15FFFD677982DF6755083C
-:10EF90003B33BEFC8E3C21DF3E76242E5F6EB6AF47
-:10EFA000B86BFA43C4D7EC6D7620BFC5AA2CA32753
-:10EFB0009C4F5F3D930FA1E15179C50BAA9BBE0FFA
-:10EFC000E4EF1577CD83B05BF4437EAC5549464FF3
-:10EFD000F23B7C3C29F13C6E31E7613FD3A39B7E41
-:10EFE0003DFCFDE3BCF3AFD37E2609421989DABBB1
-:10EFF000F97B563071FB7BCCF13F4E4F5C5EDFD12D
-:10F000007F2F086444B7137CA7739CBE5C6E3F934C
-:10F01000068184EBC8E4EF9063E410DEEC423A270B
-:10F020007E519E96ED0024F1F91079C540F8CF206D
-:10F030009300F1145C7A29F12950EC91B04517281E
-:10F040003F1680F201D90B3644C67338B51B56DB28
-:10F050003F0847D1D10C23360F543F4ADE7C427D16
-:10F06000E37A928714A612BE9F022D554D805F56FB
-:10F070003ACF257B95A8F51CEC464F6A33E178B072
-:10F080005762383E6FF2B191F320A1BED696E711D8
-:10F090007659A1DEF37C7283E0EBCB88EE377E1FDE
-:10F0A00032B9FCABC219F182E57AE4BBEE10FB2960
-:10F0B000BF71785BF8DD27062F3EC98F9F777F2EC3
-:10F0C0002FE8EB7D2B8FE58A3690E4629349BF4DA4
-:10F0D0008AD163989BF8185426827F9F7C534F8D6A
-:10F0E0005B771318390BC8AFA1D875E267C932F83E
-:10F0F0009F4E00FFF875A79AF3C6F6735BA93D789B
-:10F1000074C1E7C0EBCA463D9FFE854B280FBC6922
-:10F11000A7FEE7F93DFA7A54813ECF13FAF40208CC
-:10F12000DB890F77819F3BD34E7EDB78387A419B1A
-:10F130002FE55F189EE905C6E7041F9B4BCDDE8ACD
-:10F14000EB9C1FF000F9696E98079E629C8FEFBBE5
-:10F15000E96F185877E155434AD6527AE9F83A9957
-:10F160005B4F66BD4F0AF491CF5DFAD5F5BE3A8F7D
-:10F17000AF90E8E390A42D61384808079237BD8F1F
-:10F180000F5C1005C715FDCA7F9F9F45E7036064AC
-:10F1900090BF788793FD56B001580FADD9397813D9
-:10F1A000C9852FF27DAF51BD51934DFFAD11197837
-:10F1B00075CAC5C30BFFEC44271782976CD2FB417D
-:10F1C0004F62BC19972FF6EBABD24B66BE8043045F
-:10F1D000E1B0B9EC9BA717845F0CFF782D5FF05F5F
-:10F1E0002BB5E0366A5AAC7FF735731DAFE57B3837
-:10F1F000FD22DFCB706EEFF7E9E12492FF0E5C7F1A
-:10F2000002BCF7764337DDADBF3B7AF9A6F8F2C111
-:10F21000E4C4F35CFC2D99E71B344FE2F32589E746
-:10F22000F96F17894FB83F4B5CF9DFFC3CBFC8371B
-:10F23000DEC8A779A6279EE74F2F129EC8EC96B48A
-:10F2400062BDD9C807A9DE373D5F082C984272E835
-:10F250001A9FF0FF1723C7253E845379F4DC70D240
-:10F260006FF5751B88EFACF4E80195F9C81BF982BE
-:10F270000F8281F399394D627F52FB884F97288422
-:10F28000EFD9D09A46FC6AA793FDD9F1EB0F99EB21
-:10F29000473A799CE004D32303899F1C1C98984F1C
-:10F2A0003C1E5FBF3EC2F2697D7962FD749B49AF2F
-:10F2B0002B5C0DD3B26DD1E72BB84099B86CC0E888
-:10F2C00043F2B64C5D4BFCC4817289E0EAE833A49A
-:10F2D00027ED07E6BD12F981735E3F207918DE271E
-:10F2E0003AE097D739CEF1DABD6A81BD7B7EBE5C4C
-:10F2F0007E66A43FC17AB66ABE5DF95176E3F22D0F
-:10F30000AFAA05D1FE7108DB800547C4E6E5F341ED
-:10F31000D36FD0132ECA6F509C29E865453F2FCB81
-:10F3200007921B643FD7BD30A6943617F50F20FB1C
-:10F33000209292CCF222D87B6CA11605CF0FF32D30
-:10F34000FD53EE46AF74C47C7FB7D685266567FE55
-:10F35000FAA3FBA6903E3F1FC2EBA8FEFC553DE87A
-:10F3600008B2639D1DFD9D9162F4DBCEFE15FE5E2D
-:10F37000EE72B7CA433175FF2EE17E6CD58CA304C3
-:10F38000CFB5FD8C63B4CE78F805EE1A9FC67E0427
-:10F3900082DF655DF7BDBB7DFEAB669CA6FE5EE8C9
-:10F3A000A75A7E1D9DCFE392ADF361453DECEA8403
-:10F3B000F757DD9764D3BF88FAC4399AB701557EF1
-:10F3C0009ACF3C8BBEE3F41C2814FE803A4FDBBA84
-:10F3D0005D517478832D9225E476781D3999FE6706
-:10F3E0004712F38FF61DBFEDE7E3F3344BEFE8214F
-:10F3F0009FEBF1D5E767F917ECC989F569EB1C6359
-:10F40000B7BDA880F5123AE71D8D79495B44F6AA8D
-:10F41000A2821EC4F5955F8ED884FD4D92FBB68402
-:10F42000711D9FC3D9E40998FE2788F5AF7AF3A32D
-:10F4300074F2634E52ECC7A3F953BC1F684041AC51
-:10F440003FF914CC4B6D25B88C4F67B86C6F99940D
-:10F450004AFD943C3FB927A5BB6AEB55C5DEE90FD1
-:10F460008A9F7F793776E9B002A177BE9E6C0C2B1C
-:10F47000C0B4BC9BF58F32EB85938D5105599DFD32
-:10F4800051FD44F1106D832C3FAE80EB358105AC0E
-:10F490006FD95CC857897FA2FE2AABE4272CB03312
-:10F4A000BD1BA0A9D9EC3714FB8F7C5DC1FC0433D4
-:10F4B0002FD5BF1DA4761B6FF1F03938F83420F931
-:10F4C0008080E173813AC9CF7E0717C57D60BA5E3F
-:10F4D000D237902E26DB2219822E4222AE017C0AE0
-:10F4E000E57F2B85831427B0D6F5EF3F273FB81172
-:10F4F00054206922E615603F63E0600A9FCBF1CC9F
-:10F50000701E4E6B5E663EC5CCB7CF9A3A6D00A6B4
-:10F51000B7253FE2213C0D4BC847B19F2F93FFBD5C
-:10F5200095E9C69FACDB7B937FE93DCE4B2B937572
-:10F530002987FC4F9E42D2535743B2EEC4710C77D9
-:10F540007180C67568C0FEF86468E475B8DD9F0414
-:10F5500008282AA812DB4FC9BE65056CAF009F932F
-:10F560001F7E2F6533AD3F493DD57A077ECA0083A4
-:10F57000EB65C4C9C72CF72A89E337BC4A9C5CF405
-:10F580004904FF9E73E3BFC7CA4B171C54899F48A9
-:10F59000ADDE9C73C89FDA086E659D706B53845D09
-:10F5A00067C12D30C9FF4B826BE04EA71ACCECDE51
-:10F5B000DF86001A45FA789BBA642BD547C3096CDD
-:10F5C000D45F8E585FA0D229F641F16DA5F6EFD831
-:10F5D0007354B27B2C3C7B68A0C9AFBBF1773C5025
-:10F5E00020F4A3EAF4C3D524E70007B5F50738995A
-:10F5F000727424F10D9497F5242F93EC06C3DB92DB
-:10F600009B2B9AD600D15575F30220BEF28EE41BD7
-:10F61000F032DB23C076D99C6981576C1AF9B26647
-:10F62000AE7363FA49411EE3D7FE57A6BEC26C48CB
-:10F63000761753BBD2CBBC53B270DC6031E8776233
-:10F64000BD60926FEBB3B4AE3765FD318DE2212A18
-:10F65000E0C3E12632E1F74DB333D86F9A5911A9CF
-:10F66000A37881C8DDA0527C4F17FA388BEB1B09B9
-:10F67000F00B1E0BFB59A4B612FEF4427C93D4CEC1
-:10F68000F247A93C5FE42FC37C8DD852C86F29FF95
-:10F69000DE0882479B0C141655D322D968FCFC99CE
-:10F6A000C359AF29A0F2CCE8F2B4E54F61BE60EED9
-:10F6B000049DC849B3F97E762B95BF01BC0E30F985
-:10F6C000F7A838FA1DD749375C5EDA91F757D07C36
-:10F6D0005FB919D88EAD31E56D0CBDD162B1CC18D2
-:10F6E00049F8D7D10F503F15667E9CA2723F7DFD31
-:10F6F00060F205EFC607F89CC0A6937FB24E6A6021
-:10F70000F840C0CFFA1EC5CD10BDF49FB76BB79DB2
-:10F7100006CB1474A7EF157457065E99E03552BDF9
-:10F720003B48E3CF9997CB7C66CC5160B830E5611C
-:10F730007E429AC4FB943F209FF165BC4BAF97116A
-:10F740008F64B9343F09C79B3B4FE2F38959735D1E
-:10F750002109FF390BE983E3A1145FEE6CC4F7398B
-:10F760003E499CFB627E5E943F1EB5613E379BED39
-:10F7700004FFD309F0397F80C077AB7DCD5A478C29
-:10F780007FE792016EE1E71830F59302E6BF22AE03
-:10F79000252BD91B117CA381F9D4611BEADFA4FFBF
-:10F7A00082C1FAF63526BD5BFC6296710BDBC1B3F4
-:10F7B000BCB17AF43BB4274407D74AACE7CE997B77
-:10F7C0007E3DFB5C8164C6DDF455599E99DF35D0E2
-:10F7D000D89EBE9AF49C12FC380DF59028FD7EDE72
-:10F7E0006D67D3B87ECFC7579CBB0451A152F09729
-:10F7F0001A8427F1CBF26B15A697EAB50E8EFFAAF5
-:10F80000695E63CF267CFE21E8025FDFAFEB83F306
-:10F81000EC53658C90B528BF4D554822BACE269E34
-:10F82000C3F08F38C82F37DBA157D1BA66A7831A28
-:10F830004843BCBCF68A8DD4FF5A17A832CADBDE17
-:10F840002D6F8608AF9095EB849388391CD7D657D7
-:10F85000EDC1E70BF5B6611CB755EF49D1A3E3A4A1
-:10F86000D6AFE9C43B8AD7D29C304C35F737919D4F
-:10F87000346480E0570F4AC0F22270AD8BE19C9552
-:10F880002FE295B2527547308DF88D66D5E338BBBF
-:10F8900007EDBE5EC3310DA15A29F647B48BA7FB15
-:10F8A000AC0CB39F1E9A1444629CD9525A6623B87A
-:10F8B000B953748A4FB4FAAD4836ECC4B72A8648B7
-:10F8C00023820CCF4DCA22D24F9362F9BEDD2EF6B1
-:10F8D00005DE157C3F5E0EA21C60BE4F7EFB6019EC
-:10F8E000CBAF8A01592C0FB89FD58A4B75EAD0450A
-:10F8F0009E657A2185FC5CC31064A4AFB7E5786788
-:10F9000050FC5EE07585FD6A6573F5EB1647EDEB1F
-:10F91000E60E391099CFF1503FD4FB503CD4DAF2C7
-:10F92000CE3CC53D56428383F0BD324E3E2E73BF62
-:10F93000CC7AE4B247ED9DF80B1427AAE713FFA891
-:10F940007AAA8B3F88F954273F8BB32F417D89D604
-:10F950003302F931F121A3204566FF32CC13721432
-:10F960001E97C82F267B56D793DC6B97521AE4B2AA
-:10F970004E3E39C2DCAFBB14EF4B141F1B407DE978
-:10F980003115BACA01F0B3FE3211E526E9D152CBE6
-:10F990001C99C6DDB814FBA6F37C255C41F9DB9607
-:10F9A0008A735208DCCCE760E3024E95E8FFCBE4B3
-:10F9B000FE6BCD71FD7664D6C7D41F727F80FB428B
-:10F9C0007A8B44FC10CB7B4FC3A64807E35A8E705A
-:10F9D0007F1B33045DC4EB312FDBDC219B8DF86E84
-:10F9E00080E54E128472087E4681E0B36507049F6D
-:10F9F0007D2E801AB44CAAACFF9AE9B9AC0772F913
-:10FA0000D80870FCCC0EF0559BFACE5D034650B47E
-:10FA1000A85FF071535FB0F4B82971FB78B9FB7E31
-:10FA200085F8D6E5395DF64BA6FEA781C4FAE21546
-:10FA3000DAF9F99661F12588E54BB97096F70FEE82
-:10FA4000DE732BF90982717A50F022F5A05EB9BEFF
-:10FA50005FD0FAE2F5A1EEE2299F1A7071F194A845
-:10FA600041CC27F935D6B2B3E2F0A77ACFF1F9F756
-:10FA70004027DE75E07360D375B40E94E72AD97D14
-:10FA8000D26F1E62BA5E8BF5E4F104CD83C1FFC272
-:10FA90007CAB0DFC14AF003EF534E1A92577911342
-:10FAA000319ED42D1678374A11F9BEA8C8125E06C9
-:10FAB00047C7EBEBBE5CF2471B65C51C1F6BC9E378
-:10FAC000E13683F16404E81954CFC2939161518EF9
-:10FAD000F8F11AF19371D3105FF228CE76541FD249
-:10FAE000BBCA4163FC288F936B15EE990AD17985C7
-:10FAF0002B7EFF0D3E779C6CE2C714F5EBE1C7252A
-:10FB0000841F96DC423DF9AE38FBE2AE38FBE22BB7
-:10FB1000E0C7918BC18FC845E247BBFD87EF05CA9F
-:10FB2000D89EF5CBFDBBE287D472DB927B88DE8367
-:10FB30002940FBFE74925AE1C679D6548AB8F3E1A3
-:10FB4000BF2F08523E7B452EEB854FA7E92F71B999
-:10FB50005F9497B519720AE6F3576139E69FCEF5BF
-:10FB60005650BE66359663FD11FB7C41CA17FC50AA
-:10FB70009497DEE97F2985E47C40B47FE1589DECD1
-:10FB8000C1F2509DD9BEBCA182F235F5A2FDC803D9
-:10FB9000A120E507DF23C6B7F4CECB4CFEF9B47441
-:10FBA000EAA5DBA93FE49F9B917F8E3B61946EC3E6
-:10FBB000FC22D56623BC5D1C09D8091F0EDBAA46B2
-:10FBC00012FEC0425F0EE19993EC56B9937FD9C8FB
-:10FBD000A983ED262A76D6FB5E95FC0AD59B4624A2
-:10FBE000417276B4EE22FE4EF1C89B51DE1499F2BA
-:10FBF000C88ADFA57B0433A2F6AB68A090F356BD9C
-:10FC0000EC748117F0B0C00B2BBEB8F52190C8DFA3
-:10FC1000426B633F449778633FCBEF50BFE2618410
-:10FC2000B797539C31965F3E56C419979E3B3D351E
-:10FC3000915D347CA0B0E78F9AF722ACEF95A15C80
-:10FC40001BD1CFD3843CBD099EDA1F495F7A9AC687
-:10FC50001ACB200DC068DA47912F7FBCEF7DF57D70
-:10FC60000196DAFC0AE111F497749AFF556DFEC90A
-:10FC7000BC9E2A80EFF54AB00E53DE2F093A368B30
-:10FC80003811C17F6699FB764C9DF7CAED6C3F7BBE
-:10FC9000743B8E3369FC00A6FB9973258BEEBF3352
-:10FCA00090F4603AC1607FB68FE3DD6F8290830687
-:10FCB000B9298EEE97BB3F7B8FE4D2F22DB174BD94
-:10FCC000025A1DC2DF1C79E46DECBF72438A4AF20E
-:10FCD0006745636CBDCA0DBF3F209574E50395165B
-:10FCE0001F08C5F2015438041F7868089F7FADCC07
-:10FCF00091B54319E4FFF0B3BC4F0221EFEF52F48A
-:10FD000030D35F8B53D851A67E7E9B2CF4F32470A6
-:10FD100069EE42E2C336335E55E4ADF1212ECEE505
-:10FD200054C3CDCC6FAC78180420CBFB5381CBD51A
-:10FD3000683F5B079F8FA3F7D2969EAD74DFC0F23A
-:10FD4000B3A07EC0F6152C424E378EF910EF9BB44F
-:10FD50000CFF3F86D6E5E0753DD4A33FF3F7D548C9
-:10FD600010CE52B28B95E256EA7388A02717D111B4
-:10FD7000F1F769B1F65612083D7E789BF0E38CE806
-:10FD800094FB75B4BF4ED05D42EE3700D157B7F645
-:10FD90008A7B55427B852514F63F7B9AE0EB17B2B0
-:10FDA00057BAB3473AF63309F5364C67FA92B6D3E9
-:10FDB000BA2F3B9B9A92289E6A66B9EC25BB6CA62B
-:10FDC000DDC84A4FA0E73F60EAD91DF57D6EEE4FD2
-:10FDD000F1656CA7F825ECB795F87FDBEB8E8471A5
-:10FDE000C98AD9BF6237D444FD5F454EA9287FBB7D
-:10FDF000E2CBE67EBF017DE579DA977879E4D81D1C
-:10FE0000774E098181D171054F0F12FC6E4281F14D
-:10FE10009B81744E94D49FF99D568AF6541FCE73DD
-:10FE20007F076FBE9CE3243E03E38271126BA3FC49
-:10FE3000E707D3129F8BBC61F2D7148A7DC3F47697
-:10FE4000CDF8038D7FD421CE5D8E269BA9479C5B88
-:10FE5000BDD3515FF0C788C5276DA2FC687AEC79E5
-:10FE60008D55EF94D9EE50ADCBBB36CAFFAA3DE419
-:10FE7000F4939CCECA37EF71AC02B69FDB9F4FDB89
-:10FE800014BDAF670796A70CA2F8A27CC3D18BE084
-:10FE9000F8BC907FD54AD841FBFBF025BEA334EFD8
-:10FEA0006A0D8C67A81F2DECB8A698EC06111FD21E
-:10FEB0006E1776607B9248AD799D1D382365109D45
-:10FEC000CBDE1C66BED8919F1166BE7776A097C721
-:10FED0006D9F65959BF9FF10790D549DE65BEE32A1
-:10FEE000ED8742752DFB5D51EF23BF4DFCF901C03D
-:10FEF00078A11F9BF19E46DFBFF3395E777E7E9B24
-:10FF0000ABED95FFC2EFF34D7FB0AFF9D357EED015
-:10FF1000187F0ED3B80B4249C071DFFFA45FBFBD8D
-:10FF20005F1BAF677D79A4FFC3651C2FC07EB5152D
-:10FF30002DBF65BEBEC2A2FBA658BAEF65C2F14294
-:10FF4000E76AF1E72DDF009D0D1C9440EFFB35C9FA
-:10FF50006BC4AF29F274E66BA79A24F68768D05673
-:10FF600047705E29897D59F9EA8D150ECA2F0695CD
-:10FF7000F97C533C3FF305494F585E0F2CEF4A2163
-:10FF80003F95E05DB357261F02DFB7D1A2F824DD0D
-:10FF9000B7D1A2EC62BA6F139DA7FB36D1F5E9BECB
-:10FFA0004D7439DDB7892EA7FB36D179BA6F135D51
-:10FFB0009FEEDB44E7E9BE4D747DBA6F139DA7FB4E
-:10FFC00036D1F58F80FFC1F112C175E206826BD385
-:10FFD0001AA74A70C5ED7AAB289BC519E31FDDCB84
-:10FFE00089EE67B967AA6305C2614F8E0CD268BA01
-:10FFF00077B32CA6DFE57215FB0950ED6039E2C737
-:020000021000EC
-:10000000FF313CE522B6933F6F962003F175E986F8
-:1000100038FDA1E5DE3AD2B76F0AC57E5F0E517E8C
-:10002000F7DCAEE7404B0699F1C0BDA137E1F31410
-:10003000D9ADD33E9FDA27EB4E305D00B4CF5B8560
-:100040003FB214063D349EF7D10E218D8E4744F900
-:10005000A98D722890DB793E746AEFAF0EFBB0DE9B
-:10006000D25EB24A74E7CC89DDEF242D76BF7B14D3
-:10007000C6EE778A1EBBDFA9A363F73B1ECE694697
-:10008000ECFE833C9DE1BCBC0F9A77387EC6B45829
-:100090007CB0E03B1AFF27F05563F82E41F83E2C68
-:1000A000D1B9DA3D7BFA685DE15CDD7CAF83F4D7E2
-:1000B0008B85F37D7170FE1CC657B819B830D335E7
-:1000C000B2535F2ADBEBE72081636ADF0AF35EAF9E
-:1000D00038DF31E18AFA0BDB0B51E750F5B2CCFA8D
-:1000E000CC26A267233385F980BEA107EFD73097CE
-:1000F000E86F31F8983F2D8ED36B96BAEF77905E0C
-:1001000013BF4E9A0DF95D2A5B845E13BFDE2EFE8F
-:10011000A842B5B58FE0DB8D0FEBB4CC168B4FFB4F
-:10012000C88F91096D0ED263BAE38333728C5F93EB
-:10013000DC402E06040F610AF05F427DB2A6A35890
-:10014000F8E79D7EE1E787401ACF6314887970A3B2
-:10015000287FFF2825C47E073429D8BF64D963F1DE
-:10016000F084BED2DAB7B05FF92530E1A8CB92AD0A
-:10017000D37F8F56A041FAF5C8CF84FE34DAD51864
-:1001800054B4AEF6F927F9E639B762C67F5EE01CD3
-:1001900092E64F7E8E6BCCF8BB092DA35EA17CC787
-:1001A000B9E4CE57FBD07E8DDFF9FB0C4ADF92B469
-:1001B000C7EEC0F1AF96045EC4DB95C11DE334DA2F
-:1001C000FFCB242FFB2BA682BFAFB047423CAF89A9
-:1001D0002E1FEBB5369761E7F328D37F09109E4AAF
-:1001E0007AFA32DDC1F358AB7E3095FC31CBC1F4E5
-:1001F000C734C7EE5F177B28CE0EAAC2FDA77EE3E9
-:10020000ED9E047814170F102BEF17145AF7CA45F8
-:10021000BC8A06E2FE77A5E947AA746DF4887338B4
-:1002200094737DA18BDDA410E0C7F07985BD90EDBE
-:1002300062B407F8BC5F73248AD7033593CFD56FB8
-:1002400074CF64BE7C637D17BF0EE3F5E2860BAC12
-:10025000CBD413C6D3379CFFE1419A90FBC9D3F7A7
-:100260001A545CD6D63F5A9FAD7188FBB9E0CF884F
-:10027000B9B730B8509C7B97997A53A5CB8453611A
-:10028000A08EF4E30EBDA98BBDF8F5EEC958F12E92
-:1002900008AFA242C6E306CF9ACCCEF31D6B1D9FDA
-:1002A0008C687BBC15E125A74C76117F5CD1CF37DC
-:1002B0008CEAF73B103E4C74036E8DF5F593CDC779
-:1002C000F6CB799DEB423C7B701CADA35956C5BD66
-:1002D000F940DD38ECB7BD54E05DF7F6AF8027CECE
-:1002E000EBB2C2ACAEF3B2E2ECA7C845A9E128BDBF
-:1002F0003DC3845FFB10EF146A57F6C7BE1E9AAF6A
-:100300003DAF714F6FD28B6F157A31EE2BFB41648D
-:100310003B48A4974E91CFDE42F95339A092FD9904
-:10032000D923207B48CF5B00EC2702DDAF13AAC89E
-:10033000FD8AD84ECEBE15ED27ECF7DD5537A6D198
-:10034000FDFEEC944569F96E8A6FC2A90EC0BC64CB
-:10035000F38AFBD9CFBCF76F65543E8FFDD2D73BF4
-:10036000C53973EE0FFEB69CE900B474E7181ACFD6
-:10037000C7EF0B44D2649E5FF9B59F0D27FDAAF726
-:1003800059F730D2CF7AD1392F8274A8491F9755A7
-:100390004486FBDD9D70CACC4F6CBF649BF03898DF
-:1003A0007C72369D8758F7301EEAF1069F879F348E
-:1003B000CF4FF28C69A984E707075AE75AAD59E491
-:1003C000B2AA4E3252E7D03CDF94F97EC567AA91BB
-:1003D0009A86E527C1CBFA63A0CDCEE744ABEEAE5B
-:1003E000E899EEEE3E6E7F4DA1B06FAAE2E2A2AABE
-:1003F0009456079D6755FD9371514D6871273A0FCB
-:10040000B3D65F9DA68032145309BCE7ABF7E23F39
-:10041000E48470DC629677777FE3E7E6FAACFB1959
-:10042000D5743F033FAD7ABEBC279CC70EAD3E33AB
-:100430002EE61E04D96BB4BEEA3313F97BC55D27E3
-:100440001C84DFD40F3D8560DDCFE80ECED985C298
-:10045000DEA8A67B0D19D1DF051D77F69FC9E54FF4
-:100460009A707B72AF6DDAE604F37CBD50D8DD4341
-:10047000B214F6175CDA0AC6A604E35AF5ACF70D17
-:10048000BA9B57D3A4F07C9A37C505271A6FA709E2
-:10049000476BBE4DE9E1255E71CE3A90DE2FE8C88C
-:1004A000AB91FE5747F1D3B3A67FA0E93BE1FEFC39
-:1004B0005EC615C28EED6E9FE7F4F3A5137F18A9F3
-:1004C000B4DEFA4A269B5D407EB49EF35A6D242723
-:1004D0003BF84F37FBDD096739E61E4C57383BB810
-:1004E000BCE3FE19181E299BE410B03EF0D01F4B50
-:1004F0001C0E1CFF980D22C477A6C87DA7BE4079AC
-:10050000B41F882E8FB1ECC07483CCF7998E3D9ABE
-:10051000EF20BB6C49394464E45BC7DEEA5F477196
-:1005200097DA02D424C7A1BAB336F6FCB1128C3DD7
-:1005300029D8EEC603DED456CC2FBA27568E1D7BA3
-:10054000EBC70EB207A4856E3FC515E13CA7BE8080
-:10055000F9C5CD0EBE9FB5E4FEF8FE62F5E06C5322
-:10056000DEC6EBC39F179AFAF048184972E685DA9F
-:1005700066F17E8E791F11F53F23119E587A7028FF
-:1005800079D2DF99EF43A34C7C699C92B8FE92220A
-:10059000B10F2B1F3BEDF068DDD3D971E42705388F
-:1005A000FE895A95D3ACC1866B30F63F60B02F659B
-:1005B00030B697B548FF4FD8CF29CE4111DF385F0D
-:1005C00043F7D448DECE157A8253BEB992F5D13EB8
-:1005D000A006597FF1FBD99F6E43FD248DE2376E53
-:1005E000913DEC6F10EF078DF968511AAD37F3BFED
-:1005F000E73C4D70A53B0E40EFB0941BA5C4DFD780
-:10060000CF70F379FF265B80FBA140ADBB109EA1AC
-:1006100027C7EC26F77941E3BD93C8EE535B76B567
-:1006200092BD526FFB740FC525D44F043DC8D00E48
-:10063000F138352D339EA6F6FD67BA75BA5FBA3E1E
-:10064000D72855A3FAD720F21EE99927AB6CEC37CF
-:100650003DD5FC0B3EAF42FB2E42CAF7A9AA3CF6A1
-:100660009B59713F7CF697C06F7802E51B44DDE72C
-:100670005ED1B4C946FAF8A5B451517155D6BCAA99
-:10068000EE6CCDBE8EE4EE130ACBD1CCDF5CC1F1B3
-:1006900003B98A26113CAF9354A18F9A7AF2B560C0
-:1006A000FD35BC42FAE942D293110F3F94421CAF90
-:1006B00069839667A9FDDC1CA10F82D63882FCD71E
-:1006C000E12AF37DA2E5F634D26FAC7382EEF0A19D
-:1006D0003B3F0FF6B4E41D1CF7A404EC6FAAB14530
-:1006E000FAD3FC8EDB13CBD779834D3E30D01F621B
-:1006F000799E0EEA6334AF025F2ED165B54D5BC9BA
-:100700007EAF7D5E8E0F6997D4F498775ED4865F56
-:1007100093DE5D6353857D73C028A5F398F6194574
-:10072000FCEECB497BB83FF311E47B149775EB13D8
-:100730004D3315845B756FD4BB30BFF9895D3315BC
-:100740007A87272FBCC486F95707FF45940F091FE6
-:10075000A6FC1F9FF848940F0B2FA1FD39F9C4691F
-:100760009127030C11EC6F4FFCEFCC00AEEBB8E916
-:10077000FF043D3C9FE659FDC2205BB47FF1C86099
-:10078000C1378F27897AC773E186AB49FF280CF3FD
-:100790007D18ABDE6B83CDFB0426FEDFF462522BAB
-:1007A000C5095BED202771FF41B3DD4DE67B59485C
-:1007B0007FBFA27A2FE768E9BCCF479147115C9EC3
-:1007C0001FCCE73D370D4EE7FA049FF4A2AEE32DB0
-:1007D00023394F72C01E7BFFADC1DC2F2812FD579D
-:1007E000F756D3683FB2D3859D811B927617BF63BE
-:1007F000B0C9D4ABC4FE64CA6A695065B9339CEC15
-:10080000E697CFF62D65BBB9A29BFB9E83851CBBEB
-:100810002928C689F4D2D4CD7CEF1C0C8A4779B93B
-:10082000396973F47B29274DF81E199C26E0D7B14E
-:100830000F3D251E2768C2A52FC2BBB8137FACF69B
-:10084000175AF7F67FD1BABBEC5399989FB51E8023
-:100850007B051C707E69A8E71F5F63B61B6DCD43E7
-:10086000637AB8E9C5DB3708FEA7A5B3DD0E3F11F3
-:10087000707059E316F1F9E40A530F96036F38C804
-:10088000DE5851DFC6EFAFAD6814EF6D75D29DB184
-:100890002A9ACE32F3C53A33652333C8F488EB6322
-:1008A0007A34CC788358FCE980773C1D77E94F4B4C
-:1008B0008FED4FE3FEBADB87B08917DFD83E041314
-:1008C000C3B383BFC4C1AF831E73CD76458867654C
-:1008D0005DE9F18FDDD171EED71CCFBC77B2E27646
-:1008E000335E558BC5E3154DB9B685459DF5EF6E65
-:1008F000BCD71B1D4FEB6A5A1020F957D352CE714B
-:10090000B52B9EDBFAEB00B65FB6FD010F05531F5A
-:10091000531AB2492FAE7A6C9DC7A0731625E021F9
-:10092000BE792C244F4B747F75D41029461FABA67B
-:100930007F62FFC79FFC5BDDBFE1FCBF9050BF4201
-:10094000785737FDB58EECB73D862B4272FBA81267
-:100950009E4A72F4A6056E3FBD2F58D31CAB4F2D97
-:10096000FBE503D91A077707FAD8589F6AED43EDDC
-:10097000AA1FB5EB64BF57EF93751C066A20524758
-:10098000F38B6F5FD3F8A183E0AAA23ED8775CD740
-:1009900072E4248CF7354D3FFA54F6507AEC1D285A
-:1009A000A1FEA2FC1108F7CA6EF4B2C221B1F7028F
-:1009B0002CF840288BF59BE0130F95BC8FF33AF190
-:1009C000E86B1EA9285A5EDE29CEA91A6FFCF90B26
-:1009D0005AF772F524E907CEAE7A80D62C0925BBEA
-:1009E00045A455F6560FF905AA36D9F5007EAEDABC
-:1009F000FA8BC7E95C05DE76EA74F458B5F5B48382
-:100A0000DE3FAB928C88C47A1678A4919DFBB47CAF
-:100A1000EB47C25FD54B86E9B84FCB7EF5B9A86FDF
-:100A2000402409EB2F7FFA7DF66F55F9DC7E578263
-:100A30007DAA68DCE508BB13EC53E3FB53490F0ABE
-:100A40003EF125EFC3B19D12F4CCEDDABE72D3476F
-:100A50000EA29B13B8211969025E649FD634CA0B9B
-:100A60001CA989F6ADF52AD2FFB09CFD2017DA3F0C
-:100A7000D7101074F1DCD66D640F54BEE3D4A7D345
-:100A8000B8DB6EF100EEFF11C52FF0FD67EBB20D84
-:100A90001CB7D21EC8563915DF2B1FB995F170E966
-:100AA0009BB766B35E07462FDB685E6F2F5AE7E29F
-:100AB0008DB3789D4BC0C77858F933E1CFF85C818E
-:100AC0006989EE1B6F1F22E487136E2E21FAF81C32
-:100AD0007B223FCC11078878DEB7C43B644EB83A1E
-:100AE00035FA9DB93B8708391080D07BF4FE640D40
-:100AF000DAC5C417E4373F9F4AFDACCA55FC4E9592
-:100B0000D71F30E1259D13F11C9A62C59DE6E17E59
-:100B1000BD39A527D9C14E38E5B8BE8CDF69D0C82C
-:100B2000FF1BD58EE17664B33359423BFF4876E232
-:100B30007B84EF99EBC0BFB7200A9F6AB61C617C2B
-:100B400002B4BB527344FE61A243B48B52116E9F38
-:100B5000EDFBD0D19BFC1D99361840F36DFB88F35B
-:100B6000A0676954DFEABFA6D919F32E49CDA31FA8
-:100B7000C5D1B333EEBD133FC3B3065235D2378F61
-:100B80003822535FA471705C8AD75C72BF33E6BDB4
-:100B9000B04E7C71747ECFEDA44FCBBE5A6AD27F2B
-:100BA000FCFAE3F9C19371FC0036667DA5F79FAAB4
-:100BB000ECA1C7093E5548AF01A657417FA8A347FE
-:100BC00006203D7CFCD44BFBBF4F7EBA467BE674CF
-:100BD0001E2D96CF563E83F44BFE348477924E7C86
-:100BE000F64B07E9BD39156807E3BC3F76EB74297E
-:100BF000AD2BDDE2F78474EB063ED7FABFC55F97F5
-:100C000076C35FF7C5C1F373284AA53B0CC79F5C49
-:100C10007E09FB15E2E06BD9BBF17CB37A88C67024
-:100C20008EE79BF8B71FA2E0B8ECBF3F61BCFDA206
-:100C3000973807AB7EF4AF2CBF10AC1127E26D756F
-:100C4000E853CEAF23F9C5F95D33E9BCBAEBBA631B
-:100C5000E1195FBEC1E4471DF7DCEE8400C5DD4548
-:100C600076C8FC0E433BCEA58EF4F3A772F99C70B8
-:100C70009DA9EFB7AB110FE9E7EBD2AC3CDC40EF3D
-:100C8000C1B4074AD400B54F32E30FBC114F5A9498
-:100C90009EF47E8BEC21BD2E1C826989DF050CF24F
-:100CA0003CC2D05DF91A715F4B3EBB2D6CDAF54E3C
-:100CB0001C2FBCE6CB6D746E7E4871F1B9E5A23590
-:100CC000733C7CFFAF25FF3F092F16BF8A70247A43
-:100CD0000A188E5E08E71B0508D0FC08F079B09C66
-:100CE00052B6E745ACB704014CE724F1FE9465E049
-:100CF0004D6DCDEDEA374139E820F9BF14E511FB20
-:100D0000BD37C6962F6BF998F16C591C9EF908CF28
-:100D10007A75C5B3DC4B4DFF4A29949AE7BA6CCF7C
-:100D2000B7EF95F93CFF940B58DFA0735EDC3138C8
-:100D3000D522F3FE9C7A4A0A71BC61204BBCDF8A43
-:100D4000F84E7A968587F1F67D7C7AE2D97747D29C
-:100D50003DB1AA5FFFA5E4BF303DF1EBB707BE4848
-:100D6000F9E7FEDCFF2FD0B57EC5CEBFB21DD3BEE6
-:100D7000D3C9FED0F69DBFED4F72B9FD05A74EF861
-:100D8000DB7EA753C435EC4CE177CCDAFB09BF5DC1
-:100D900070C7972561965B6B791FA75FEAE0FD3E00
-:100DA000D5F2379623A75A9C1AADA366670FF68F24
-:100DB000D5BC901422FF40FB8E2F4746BF77F5CF5E
-:100DC000AEA7DABC4FD39E0273296EA63D4DC4591F
-:100DD000D6BC38E6176BC81E69DAE520FF7FC56F01
-:100DE000FE5E427CA9FD995D0EE25B68973E02883B
-:100DF0001F732EFDE903F65E745F0CD8DE3E7DE9BD
-:100E00003BB3E87DACAE701170684738D0BA102E95
-:100E100095A49775078FEA6F2D3C3E657BA2AA6566
-:100E200014D351275C24437C4F09B9245AFFF31E85
-:100E3000F21BB5E7A1FCD769DD5F9690FE74A17542
-:100E4000FFC7A5E27DEEFFE7D76D838B5AF753DF2F
-:100E5000DA750BFC1F76A926DEA78AA383AE78FE7F
-:100E6000DC0F38BF2D45E7F97E45FA7FFD5BBBFE01
-:100E7000AFBCEF25E4B7BDD87DFFF85BBBEE0BED53
-:100E8000FBABE6BEA7A874BFAE7DC7DFFBF37ABF9E
-:100E9000E2BA938BBEADFCEDFCEBEED08F64AF8B72
-:100EA0009ED8BA075ADB344CD775A3A78C2AB2FC5C
-:100EB00010C21E914D7D631D0C3336915D857A06FF
-:100EC000D901EB3245BE1EF50799EF0F72B00AD477
-:100ED000F7D5C5BBB68A1F54CCDBFF7C23C7B3ACA8
-:100EE000CBFE0EE495D17985F06304D7E8BE5DD8DA
-:100EF0003E9866D3823A3D57B5D2B709CBD5DEB21C
-:100F00004AF6CD3AED6A57F43B168ADB1163A7B86F
-:100F1000E3EC8DE402478C5D9204BB55F2C327E9F4
-:100F20000AC7FF3921AA3DD6CF2A12EFF42743285A
-:100F3000A0BA2F1E4E8BBE3E9C5C7CAF5235E104A6
-:100F40008641EB766A0AEB610AA0FD28D621EC4EB9
-:100F500084A316054730ED50C504B9A20D6338A22D
-:100F600001A14D1A4D70F5331C83BD6495E1DAD9AA
-:100F70001FAF3B7E1FD6699320CFD4C725FD9B872B
-:100F8000F3D822111F100F672BCDF795AF21FD77F6
-:100F9000D51A71CEF5CCEFBEC3F9263BEAC374CFA8
-:100FA00030D5B7A288FC8E5E43223A5D3543BC2F14
-:100FB0005846F7C032C9D41771B899AEBEA0B0BFB9
-:100FC00012ED0CF657AA40F69F3C091AD91FE855B6
-:100FD000E2E27A558E7B0ADE2CE29EA01034F14EBE
-:100FE0004B6CFC4F601214525CC314B9AA81E675B5
-:100FF0000A521A28EED2616FEDCFFEE17E008F918A
-:10100000BFA5FC8B8D549E8B7A3DD07D32A5F53DDE
-:101010008A6FB84D4E058EAB8AE0A728B85D76C6BC
-:10102000054A149CCB212D267FA2DFE126B213F2C4
-:10103000024E9582C72A5CBD62DA9FE87586C70BAF
-:101040003A5D2AD94753D4DC98F6B267EF7B64D770
-:10105000BC916E63BBE0F29CC131EDAFFAE0C4C657
-:101060000526CED23ABEF7AEB8A78AF6D623AF632E
-:10107000BB37EF0720BFF1155A694CBB66D3BF12CF
-:101080009962E7F766AE2C1C13336E737837C3A5ED
-:101090002A0B243A0FAEB2214960BDEFEAE531F5E3
-:1010A000BE37FA8A987E67183362F255ABBF0025C7
-:1010B0000360DCEAB340EF0796B636C6B41FBEB78E
-:1010C00039A6BEE7753485302DDDA705291D75507D
-:1010D000DC231D8EFB41E71BCDE1853AC5EB14D324
-:1010E00005D0323A16F0565018F2C8A3FE9728BD24
-:1010F00050FC3298EFB2269BE7AFEB6DA1C605B965
-:1011000014FFD3F0E35D12C743EE263C1D1D69A812
-:1011100048C5EA63CF34BE446953DBF87A7AC7B373
-:101120000AA08DE5AFDBC6E70253E4961289ED9F76
-:101130001EC39D51E72EDDBDD7F9A3D2F27D4548F0
-:10114000476B738C865DC4F727BD3B5FCEEB5A0FB0
-:101150005425128DE73F2AF51EA6384D2B4E2AB98D
-:101160004216BF4771B98893A9B3E94926F362FDD6
-:10117000409D6AE738FE65C582BF8D6CDBDCE82EDA
-:1011800023BBD3A5D1BE2667C4DEF3BE71B4B8B706
-:10119000F7459179BEA2A859D7931FBC3845B4270B
-:1011A0001F1F8D37DDC6FA94E780BEC78EF9FB0A94
-:1011B000F7A9C4CE9AA67F10E0F74D0FB44D903436
-:1011C000809EF794DAC80E87BD76FE7D99A6C2C9C7
-:1011D000A70BA87CFA5B1CC3B86BC22F0B49BEAD32
-:1011E0001C3CE4BCEF8C7ACE48A045C5412C2BD6E4
-:1011F000783E1E25CCEF1279CE285CEE99A7DBFA5B
-:10120000478DB77282D0FF560E4EDE4A78EB3960BA
-:1012100088B8A842B73680E9239CC37C4209E75CC2
-:101220009F22E2ABB4F3BCF37F7CCB88349263198A
-:10123000E57A1AF94133B6CA1DF7CE683D3FA6FFDD
-:10124000D0C13AACDF3F19E7B58562D744792BF2BC
-:101250002458EFB0CA9125613E43B2CAD7CF9E5CF5
-:10126000C4EF31C6D41F9AD751DF70E574F6AF15BD
-:10127000AFDFBFB688E037CA467125EB7F67E777F7
-:1012800006709DAC4FAC447A06E97CF0EC710178B5
-:101290007AB8FC90A4C5BD9FDB5A4CF982BEBE4112
-:1012A000C558FF92B3A9FC0EC067F5492CFF2E3933
-:1012B000FB3D7EAFB3C961F4BF9DFD37491C6F365E
-:1012C000E3E68F37AC26BABEEA7821C52858EF5737
-:1012D000D6A85F303FB0E2EC3AE187F88B78FF6345
-:1012E0005B679EF883A7139E06BDCFB53E0ABEF48A
-:1012F0009B2F334C78FA8A37CE5E8BFD6B8BA6E53D
-:10130000105D9E0637C7F59D561F9F4DF33DBDC529
-:10131000CE41B44D26BF0C149AEF11648673E85E7B
-:101320007EF19B368E473A88F860203EE4B7BE993E
-:101330005E4CED3295748A6F383DFECFFC6EC2E98B
-:101340001F0207172F0B3B185E4D998B2ACA19FFF6
-:10135000B574F23F58F06D34FB79B8D4B8B298FD4B
-:101360005CE67D1163EC45BD3FB96BC2977C2EB046
-:101370003617F5FC340A393E5347EF4BAECCB5B3C4
-:101380005C5A99F6C5D44CC2F7725784DE81A859CD
-:10139000FD19C317BBC98DBE07A69C91418B8ADF7F
-:1013A000D2868AFD571483F75F39E3E0F2AAD5A706
-:1013B000996F5BED4F98E7ABF42E23DD17AAFA8700
-:1013C000CCF746911FD64BC328DDED5819C54FA069
-:1013D000F1D30E3E3F14F7EABEE96F25939F728664
-:1013E000A4CEA2F9B56C3B339BE2056624A9B328D1
-:1013F000DEA06EDBFBB329BE60463F7516C517DC69
-:10140000573C790E97F7521FB0A1FC7AB964BEC859
-:10141000E7AA7FA2FC535BEF98C3F553C4BEDFB6C7
-:1014200075CE9C00F36337D3C1A9FA1E21E779E892
-:1014300060E9EA1721FA3DDB2EE5E6EF49C15CC120
-:10144000F73EB9BB0FBFDB09056D1C2FB6BE58F8C0
-:10145000FB3BCF5741A5F3D5CC7C30C8DF9CF95C72
-:1014600092F85DA2436DFD097E4736DEF203F2A7D6
-:10147000AE9080DFD1AF026D24D1D5425BF83D4AFA
-:101480005F1CEEBBB798F5A9368E775DBA7A27CF89
-:10149000EF53DD8C5B562345DEAFF54E04F69FF02F
-:1014A0009D88D838E30F6CDA40EA5731E1B2506ECC
-:1014B0009BEF10F37A94E6B5227D17C7392B6A5B50
-:1014C000B64FE851856C3FE524F37BD175BDDF292C
-:1014D00049F43B088DB528EF91E49EA96DE674F5BB
-:1014E00050607CEBA9841D3AF6537D40C89D916DF8
-:1014F0001F38A2E319779BF04D357FEF2A3E1E7708
-:1015000037C9A5A8B88315BD5BFB927E68ED6BE774
-:10151000BEB4F635F70568BE99192F3D45EF9D50CD
-:101520009CEB0FE93CE3B9A456F25B778F27D63EDC
-:10153000887937250BBE11793689F5A6F8751C34E4
-:10154000E76DAD2762CADFEED61131E5EBBF6A1D4C
-:101550001193BFC7AFC7A26FEBBB45DF5DDB8BF954
-:101560005F3CDE897B6D17C23B8BFF5483AF50DC41
-:101570009716FCC682B7354F0B6E4DDDC4E32AAB20
-:101580009F8F598FD236898C1E482D11EF5F298D80
-:101590005700ED87B2BA85EB75B71E39E5333EC704
-:1015A00059A6819FF4DEF875554123B7EBBAAE0812
-:1015B000F3E3159AE0C75DE3F823CC9FABD13E235C
-:1015C0007DDC5A77079FC6F5137D4F4086C37C9319
-:1015D000EE124A645FF862F4E372BA31117D6EE58F
-:1015E000BA39263F45BD3DA6FEE5396B62CAAFD08C
-:1015F000EE8E29BFB2F0DE98FC77F59FC6E9F79B27
-:10160000E2F4FB2762CAC787DB58FF7EA3761AC7BE
-:10161000A74F3C1A613DBCB556E5FCEEDA1C4E5FA7
-:10162000AED598FEF7D41672BAB756E7EFBFAB1D2A
-:10163000CDE9EBB506A76DB55E4EE3F946595BB84B
-:101640008CFCFBA33353F93C6AE350DFF525140708
-:10165000B92F5244F837F640E34B240AF2439FBEB9
-:1016600047F54EAB0E8E475CBB6BCC1F6EC17CC684
-:10167000EB322469E7D38B6430A2F0C7333D0C749E
-:10168000FEED01F13E567CFD8525424F9E0B61F13A
-:101690009EC06A3E0187B92EF5152393C54684EC9A
-:1016A000F6B9E0673DD4B65ABC5333177428237B90
-:1016B000D607FE7B381E29F67D01AF3163DDAFB062
-:1016C0007C36DD3BC5F6DF7737F2BDF267F6A64F15
-:1016D0002EC5EFD77A25FE9D8F033BEFBAD5C5F611
-:1016E000AF75FFF41DDBC5E8130B4B047DB54B7ADA
-:1016F0001BCD379026DE2F8A6F37CA5CE755C108AD
-:10170000EB1F11D43F28DECCA2CB19EA2173FD9A3E
-:101710002D750CD1C71ABEDF50D5A6E94184F798C4
-:1017200043822E46205DD0BE8D3D2AE86024D20142
-:10173000CB41D33EB4E800EDA997A8FDA983A03B17
-:10174000B17DDDC41FC9647F8DF92C14A4F4B2B33C
-:10175000915DE7B07C5C9BF8DDA40BD993965EDAD3
-:10176000523B97F16867AD8FD3D6DA4A133FFD9CA1
-:101770007FB97635E7F7D40638DD5B5B6FE2670348
-:1017800097BF5EBB81F36FD4864C3CDDC2DF3592E0
-:1017900067089FBB4B4C39ED2A37ED0A917A8D359E
-:1017A00076BEE78F9F889FCCA5B9127E544A21E26E
-:1017B000DF75E9013BE5EB92690F68D601AE7F9DCD
-:1017C0001B5A490E54E5BC28F4B0383C29CFBC86DE
-:1017D000F164A619C77A20BDEE5607E2C389C6FB9D
-:1017E000ECB1EF8D5E1C5E2C73AFE57B7DF17CF17F
-:1017F000267A8F42EECA0F0174BDAC4CDCEFA238E2
-:10180000BDAFCAEF555B9B795F4CDC7FA9EEEBE681
-:1018100038DB7F9D9C514D39030BA87E87FD9D7C55
-:10182000703EBD8FD7052E71F6F7E141627F2DFB2B
-:101830001BF54CF64BB58764B6BF2A731B3C6C7F17
-:101840008F8E78683F6FDA2103EB8B8A38EF5D4A21
-:101850001D6914D7D3BA7F1CCB99557B882F2D33A4
-:10186000CF7BE3CF6DABE9BC574A04EF30C7D52F30
-:1018700037CF7BE3D75D3DFE089FF7565FE05EE91B
-:101880007B25B1BFE7137F7FB73B7CA17882E8F768
-:101890005C4F9EAD653BEDC8B63B1E0AF4FDD7ED2F
-:1018A000DFADA5DECF4A441C35DF9BB3F6B3CEFCDB
-:1018B0005DCEBA492EBEC7D03E42E5F76FDA25F1BC
-:1018C000FE4EFB5F415FA3D1FB3AEACB24172ED338
-:1018D0001DCC574787C57B01E3E95E6282F702268C
-:1018E0001C0A0553A8DDC100FBA3C6ECF305E9DE25
-:1018F000EDA8D70D99C8ABF465AF4C7860C9274BFC
-:101900005E75D295796F8E6232F2BF3AFD698B4671
-:10191000E7907ED761B7BAA7F23B45A75B81A349A1
-:101920002DBFD8F083864CF712461CF20549DED64F
-:101930009976E6A813013915BF4FF8CCCF76D018A9
-:10194000B453E552718FDA8882AFE5D7B2F89CC5FF
-:10195000D7AC7B7BAAC3B785FCCFF04212BFFF1286
-:101960003FEF41436DD67BD6838612DF33EFE94DDF
-:1019700091CFEE3A4776419B8817B8E46CFBE3645D
-:10198000F7AC7AB607DF53BB907D50A39E4EA89F5D
-:101990005A698D4D9CA30CABD08693BD497A2BD947
-:1019A000A1965D1A5FBFAC74D2D8A15934AFF16D66
-:1019B00006E1B76A3B2F7ED7ACFEF4BC76A1357E3C
-:1019C000CD8E11EAC228BFD5EAA19219C7F2F5DE81
-:1019D000A19E10991B23C7BEED7A1FD26119E11792
-:1019E000D98624A7BE4F3B80EBB80E5A595FB9DEAB
-:1019F000FC1D8B1B001CD1F7646F0483F9C39F741B
-:101A00005F0DE1CD6288CCA77C8D14A97A1141F8D5
-:101A1000C9C4716AAED6555E5FAC7C4E36EFC1C6A6
-:101A2000C3FD4E136F2DFEDFEDFEC4F1FFF65295A0
-:101A3000EF41B73F3BCE46E738EDBF97F9FD54ACD9
-:101A4000C87C25384CDC3B1D3ECF7C8704F9CA009E
-:101A5000BD2B5F393D7ECE64F61FD1C106C59F2ADE
-:101A60007AE1F551F7CD82E6EFBA6CC194E22553E5
-:101A7000E78595E8F3B39F9AF32FBF7632903D74D4
-:101A8000952AECCE292EC84C225E78F674D12C64AF
-:101A90001057913E3B9CDF617F98E0DCF10E08F12E
-:101AA000A34B70DFDE17E77C7093C4FED2E626916D
-:101AB0002F5E9CC6EBFAAAFB883DF728C1F52F6E76
-:101AC0005286117D0F4D8FE4115D168F793B5DC2FB
-:101AD000799598F7B170DAF510F5FB56EF9AEBF8B7
-:101AE0007CA8B18DE63734BD6DFD7DA45F3E6B03F0
-:101AF000F21B1E1973FB128892CB9ED249BFA27AA9
-:101B0000DB25F39DBA1DE2F70CB04576B47FEB4FB1
-:101B10007AC5F354AFD5F433C0AAE7F91EFF0C55CC
-:101B2000EC014CCE327F4F32D23FD1EF0B59E75907
-:101B3000430996C2FFC8EF8A6D37FD936F0EFD60B3
-:101B40000EF917A1359247F3389224EE517B4A7D66
-:101B5000BF233E3394FCBCB48E9F09FFC091343F39
-:101B6000DF23791BF9339D1FFFA5D6C5E9BB681F8D
-:101B700051FA3F681F51FA3EDA47947E88F611A564
-:101B80008BCF60A7B87F3374E36DE6AFDDACA37B8A
-:101B9000FE1230F5FBC4BFD3F49609FF92A643773B
-:101BA000F6203C6896393EBAF85985F5D3932DA3B3
-:101BB000627E9714E9F530ADAFA4F98F3FA17BD6D3
-:101BC000254D8A2A69742FFB7436C71FC6CD8FE056
-:101BD00040E70D911D0EF17B4AE67CB7A7B5ADA796
-:101BE000F6DB9FCDA319D2398EC0C31DCE84BF377B
-:101BF0006CC5DB3D3154E85FDF7346CAA2CF1FE3FB
-:101C0000E3D3D80F3C86F0B9E00F344E60AF0C033D
-:101C1000182F63FD1BFD74710FC14A8B7738384E46
-:101C200079FB8EFD575F89FDFD1F8FB61B3100804C
-:101C3000000000001F8B080000000000000BCD7D9D
-:101C40000B7854D5B5F09A39F34A32934CC2000957
-:101C5000123809AF00018664121212E024048A8A45
-:101C60007482D482A28EB462541E23D29ADED23FF2
-:101C700027244012830605CA558401C1C7FDFCAE66
-:101C8000D102175BF44E50A9F6B73422E2A354C731
-:101C900047552C4A8A62EBAD2DFF5A6B9F939933BF
-:101CA0004C0222FC97F0E9CE3E7B9FFD58EFC73EE9
-:101CB0003BB3265E5E24C900A7E9670A80CBDB1729
-:101CC000A008604CE9D70FDCEFC1F2599BDB0400A0
-:101CD000F360DB3437F6BBCED1F1A21BEBD7BBDF11
-:101CE0009B968EF51B334D07A8BC49CE999E812546
-:101CF0004088DFFF515EC5810CACCDF456DB024E4F
-:101D0000800A9000F2807F4EE37F531D29008E6889
-:101D10007D9ABB8FA1FEBDCCCB0CFD2F978718DA27
-:101D2000AFCC1B6D68D7E79DE92D34F41B97D19597
-:101D30001B74D23EBEBAA71CF70326080FA37DED85
-:101D4000FEF2EDDBB19C35719E8FF67F0CDAAE1999
-:101D50008D1BFDA4A479E3FDF4B245B165F503B88C
-:101D6000857EC7F6E3103E5286ED926BF9813BF11A
-:101D7000BDDB322590BC00359BADEF4762D6B10488
-:101D8000FC6961EC77DB0EE37380882DEC03B83DD2
-:101D9000E00CB62000173D81ED0E433B8FBB78AFC2
-:101DA000CD4DED4BC0126DCF01A83D9AF3E40B3140
-:101DB000E38DCBE8BCEF7E1C6FDC9E39EE065CDF6A
-:101DC00093A55F0F90719FE55E97E723040D4C800C
-:101DD00009A711E42039CD80FD4EBD2485245CD7B0
-:101DE00034E99BD4483E3EAF423C67E17B26F90F85
-:101DF00065D8AEBE2CC14E1CE76F75F2932F5869A3
-:101E00007CB8D19F1FA50B80950C5FBD7CAB0E7F6E
-:101E10001D01F0C73A07977FAA7373F96E5D269785
-:101E2000EFD5C95C7E5097C7E5AC431068C7F1FE9B
-:101E3000FCF7F1007D681C15A06FB41C67F39A07CE
-:101E4000E03ABA7E2F85B6E37EBF289F9006B4CED7
-:101E50006F70FE620D0F4802D5448CA5F8DF8FB776
-:101E6000BD98E5E3E7AA0BA75AF27709141C77B9E6
-:101E7000D724C65DD4F1629627DA0ECBDF33F48720
-:101E800015A603867A638EB1DE5A7120F67D1D0E8B
-:101E9000F1E52D9BEFB0055C58AE372921E799EDB0
-:101EA000FA7AA6ED4F524C389E659F3D64C7FD2DD2
-:101EB000712BA0607F0B80D29E7FE67B00F50CE744
-:101EC000791204DB138C5B47E312BDEF4F02E93C50
-:101ED000C67D0B6983D6A3FE973DB413DF7B2B4DE4
-:101EE000017FCC3C2DDAF89FA5B7FDE22BECF7D9AA
-:101EF00033404FB00E73693D63777D6C3663392E86
-:101F000059D0C95877C49C81E5899A7F6C3CE261BD
-:101F100032F59B26637B6ED71107A2FCBEF6AB366B
-:101F200039106F6F9BCD00034020BE04FBE31854B3
-:101F30007FD07BD5DC46FCFDCAFD4961F379ECE737
-:101F400041E445A6A34AC1EF3710DD88791440511A
-:101F5000B37415E8F32A241F68FF547FADDDFFE654
-:101F60007AA233E8DA48F2E13840B885D7AFA4C6A0
-:101F7000F2FFD2677FC2FCB9280BF99E04E066C16C
-:101F8000BF0EFC773A97F83534DD89EBBD358CFC14
-:101F90000F179FFF9FF13AA37C3E22219F1FBA1289
-:101FA000EB4B9F91BC766C3EB96F98E0278DEF7537
-:101FB0003ED7E1B87493C47CA9D73FDF27CD08256D
-:101FC00080F7368D2E86285DB369BE65CF5AA00591
-:101FD000D7B76CD288FEB1E3C7BFB7B44902396640
-:101FE000FC279FB3D710BFC8D0D5AF1AF967DCB3B1
-:101FF000A7322AF24559CFF868D3E44DD720FF180D
-:1020000094D726FF9F7E8EF301E27127C2A7327319
-:102010006E36CD3FDB094ACB7806CB1C07CA89ABAD
-:102020000588E0EA92EBB201E1B919D12521DDCDB5
-:1020300051AA5FBF0EF1F80373E02A92F3C7BC43C5
-:1020400078FC6B5CCBAD606672CD36E17873E7D817
-:102050000B693FB31A045DBF9EDE759C9EBF3E298F
-:10206000C5D480EFBD6E8246C888EEE375AB3F9B5A
-:10207000E80D37EEFE08F163524649A7537A9617EA
-:1020800044C91FE97894A2F26F9AE454699E936E52
-:1020900033D3BD25ABD546EBBA154207149C7789DF
-:1020A000376C23F9773BB82D5462D1D54D1F447F4F
-:1020B000E5FFE8388DEF2FE9944226ECDF5ED70E7E
-:1020C00016C4EFD3757BB91CFCCDE0C6CB101ECB7C
-:1020D000C7DBBC2DA4B734FA32AB26389D405F9DD8
-:1020E000499F96683BAEBBC2E10C4BA9F4D87A3C41
-:1020F000761D8DD94ACA78DC8FBAA63C9DE99368D3
-:102100006170749FE36C004E92F33B5358CE1F7B7B
-:10211000AED84C783AF63B6BC844F52D23DEB8D3E5
-:10212000C7752079732CC36BB6517B466E48C5F6D4
-:102130005BCCA0925C86ED426E3D3FE9AE77488E67
-:102140002DDFE932D94D828E653401A447D7BEF325
-:10215000EF38CEADC8AC766F546F2C9AF2E8C62734
-:10216000900E1699DBEE29C767A7203CD68DF0FCB0
-:102170008BA97D38E9ED8F1FB287CDF4DEC323B77D
-:102180004B38FECBA98191B41FC854FAE7E0F39A0B
-:10219000437DA105DF9FFAE83F0F92DEBCF5C9BE83
-:1021A000CC5F3ADD4F233EC4F59C403EA4F59CDC59
-:1021B0003784F92E8A7F0187C5280FC8246ADEB1CB
-:1021C000CE4FF80C24CBFCDC02AA7219E17BEF4D58
-:1021D00040765381645288CEBB9A115EA633E9499A
-:1021E000196FE6F7169951BF121D06E44282C7091E
-:1021F000935CA0F105D07ADE7F6EE4F6167C7FAEAC
-:10220000D63F4A774797FC86E86EB3DD6BC7251C3F
-:102210004F32EA7DBD9C393E9DF9E516C79760298E
-:102220008C3E5F52FBB5B19E0F0AC98D8206B9F094
-:102230000E2CEFD4E07EC548FFF7C7E3FBB7B5AF80
-:10224000DBF38A4CF36EFEE9DB34EF4B4E9E175EF8
-:1022500011F03B6112FAA55BBF3AFECAE3A3E4E1C9
-:10226000F5EACF3F7EE88DB1011CFFE3DDA38703D4
-:10227000D2DD02A9F3A307115F9FBB3ADFF93996BC
-:102280004FBF74A81FC12F7EBD8B6ABF004B8C1C33
-:102290003A6E32F17E17D13EF0F96F0AFD3733BE48
-:1022A0002DA827106E0B5AC66C2779304DCA4F23C4
-:1022B000BBE9C431E3FAE2D7A98FAFAF4F1F5FEF9D
-:1022C000B78CE08F709838CE2DF4ABADF373C2EFBE
-:1022D000677B469B9015A3CF333AC7A6E747F1E447
-:1022E00057EAADD4EF1A12F5888AB90E81D7B935FD
-:1022F000A650430EF7E3F6EBF039E1BDC2D3C0F5CB
-:10230000394ED467D87F51E66F785D24E81CA8D792
-:102310007E00FA4FF5AA5F61BF3797A5B25C987B44
-:102320004B9B95ECDC6E79A6BE6D3E3DFADBCB3364
-:10233000849EECEE07CCC3A43F013767C1FA24ADFD
-:102340006E2AF963C3AF483EDF99EA95D064841AD8
-:1023500019C2C4D7272144F05E6D0AB2BDE7203D03
-:1023600080658BC99B69C1523277F5019E27C47085
-:102370009A06010BD57F6B8A3400BEB7CA539949C0
-:10238000F4FF2638FD6417FD207DF51892A395EE25
-:102390009973E9F96C35D5DD82FB6DB4CA77E793A3
-:1023A000FDF303C94B76AF0E175D7FCCB578AD0456
-:1023B000DF7E41D9AB22FD16BEA2384C0C7F874A86
-:1023C000E3BE6109F6A575BDE55C3FC664263B2DFD
-:1023D000E41A839B7DFBD07F14FD1EDFFF2328932F
-:1023E000C81E98F35B07CBF19B40667EFF11282C3B
-:1023F000C76F8600D76F8188F54B7CEFDDD2FFD9A0
-:10240000B91FA2FB7A77E257BBC9AE9F2BB5F7CDB8
-:10241000C176B512F248CFFCDAF17FB646701D4A9C
-:10242000830592D0BEFA35D129D9EF475DA19DD859
-:10243000EFAEE42DA91D588F9884FDA556069FA4E4
-:10244000FEAA19FC0D58F64D0E3C4F7CF8CB14310A
-:102450004EADC5E126F94806168DF3D13B2EA67781
-:10246000D2BB3761BD0CB145F03AD157D09BFA577A
-:1024700060B97BC2EAED5468DC53B27727BD3AD528
-:10248000CCEFC36999D75116A75F7CA3CDFC3EFC66
-:1024900043E6F72775590CFAC537CE1C7C1AF73777
-:1024A000E5EF965EF5CECD05827F7C7DCCC144F60E
-:1024B000E0FF68FC851092683D0D7B4DA116264219
-:1024C000611F94E9F40891D5446FE50041A27BD8DF
-:1024D0008B7A4C9F2797F7FFB9EA233AC476B60761
-:1024E000DB9F2739690F0A3EC1FA54DA8F23085E51
-:1024F000B2D750218305EB49F8A290BB6E203BB6C2
-:10250000A502DAA93E092212E17B0A417A08F9C341
-:1025100032D3ED5450B8AED3F1F740E5F272087102
-:1025200079258485BE07B9F1299CFFAA4F40EC6745
-:102530005498E91D1D19F747686FC0E5B798C9EEB3
-:10254000F0FD30B1BF30A840870B22C473EE709904
-:102550000E814C31BF80879D9EFBA2F070C4C123C9
-:1025600089E0E18DC203E710F03803BE023E931408
-:10257000840FCAA7C9D025D13C8A66DF548297CB85
-:102580002AF073D90B5C5EA8F79C09979248C01299
-:10259000C84F009FA989E96684069F3F1600CB2F8C
-:1025A0005DFE5C5B20F3735D0E217F66923D1A2F0A
-:1025B0009FF4E7BE94CA2F64A487AA82AC7916D48C
-:1025C00067BEC2CA3B8760FDEAA7F344BDACF257C1
-:1025D000B958FF41C128511F5759684578D59B46C6
-:1025E000CFABC2FA90806923F1E5F27AB4AB715FA8
-:1025F00081A47B8244C7A60C709BB03D505FE42D44
-:10260000C07A00E912106E7629A79EE06CFF397837
-:102610001B7015196981C905B8DEFCF99DAB053E33
-:102620002BFBCFC5FEC73BAD6CB7ACB10583842790
-:102630006477777D69747FC79FFE790D3D7F7A004F
-:10264000B849BF80472EF4BBCE5C8FD9015C5F8C4C
-:102650007283E21F38DF4C9A2F80EA49A6753D2528
-:102660008508FECBEBA7B13F7024CFFFFD82BE31C2
-:10267000E3E33EA4F134AFD073E0C92924B8958CCC
-:10268000F45F4BFD4EB850BEA651BBC0434F6563CF
-:10269000813297E68D7F6E4EF9E6862538CF52A4BB
-:1026A0001192D38B0B0237D2B84BCD914185F86C88
-:1026B00065CA3B36A60B05E993E403F12BEDB7069B
-:1026C000E991E87ABFE057E40077B7FD8AF8F5F8BA
-:1026D000BB6E58E813224EC2FF15CF0D3E8F6635F4
-:1026E0008D7F3BAD63A9D4B590E8F2F3F4D76C7F4E
-:1026F00066BE1C28E84E935B4B9FFB9AF9E7593363
-:102700000425CD3F8618BE5BFA5C9285FCC3A59F6D
-:10271000422805DF2FDBF77803F93BA5E8FF939FFD
-:10272000BC78D753CC6FFB485F22E896FEF7B3CF57
-:102730003F487C7A6512C7A126BD767408D94153FB
-:102740008E461A106D70E2D9372E13F4AFFB257F39
-:10275000339D8F1E9F26ADB887F0BD0CF16FC7F972
-:10276000969982A26E75B855967BC24FAED1F6F19E
-:1027700019746E9CCF72453D504AFBC99480E56345
-:1027800048F81332FE23FEBFFD686835AD13A46F11
-:102790006C246F4EA15F4CFBBAFDB178BFA3EB4038
-:1027A00029F9DDE417E33E17B71BDB97C6EA870478
-:1027B0007EF296022D1E960DD9B4AF5FA33FF4C1F1
-:1027C000309A777E1AD9871329AE90405EEAFE715F
-:1027D00028B9F29102B697DB25E287324BE2FE0B75
-:1027E000F3855FACDBFFCB1E92D88F5BF6509F5119
-:1027F000EC276BFC0A612FF3EF93A45788CE022FCE
-:1028000003D1C12DDA9E60731FA6B95B9B4CECC748
-:10281000D8A53BBCA4F7C73DD2FFB67F63BA4975C4
-:102820004326D527CC7DCCC3F655908435FA556C1C
-:10283000673E99DE954BF33F992E838AF3352475D5
-:10284000E5929C559F757849EFC6AFFBED02E10F0D
-:102850000C098FDF14F1083C139FE7BC54BA89F0D0
-:102860007C12F99CF0B7CC35BC3F38C96E989C19E6
-:10287000C1B241B3D3731E1B95361BE1E2A3F5C66B
-:10288000D8D51DAF5E9342F6F26E8B3FC58DFD4EDF
-:102890001ECE35F841F16551189153D84BFB1B33CF
-:1028A000870412C05D2F7D9B2C0C2F9D6E7F5DA732
-:1028B000C00756C247B9D8876A77DB7D447FA1A994
-:1028C000E44F2EBB19DC2DD87BD9CB0F3738A8DECF
-:1028D0000C4CCD27E97FD4FF137388ECF15FA68CF5
-:1028E000BDB71CEBBB8E59849FA22A87F263EC58BC
-:1028F0007BA6196403BD764A8B491E13DD23BD26D2
-:10290000C9C920C7D0634A5E86A1EEF20E30BC9FD3
-:1029100056926B684F574619DA8BA13612C0F514E0
-:10292000654AEE10AEB8CF8C0243BB1DE93A4CEBC2
-:10293000FC52D85125F84FE8DB20DB4365118007B6
-:10294000900E261E37DA59259136F637930E5B0C1A
-:102950007100FB59E250C9851A7F0D8481C45F481C
-:10296000FF5E9263270F8BB893ACC17359B6D0CF7B
-:10297000CB5E96D80E5C76CCCC7AE22478BBF14361
-:10298000F251E7BB78B8F7F51BE1DC7FAE11AE5929
-:1029900001235C2FAB31C2353B6884EBE05A235CEA
-:1029A0007354231C87344D34F41FD65669A88FD82E
-:1029B0007485A1FFC8D06C437DF463D71AFA8F6980
-:1029C0005F60681FB7F736437B3C5D8D0F2F33B4D4
-:1029D000DB538F305D1D40BA32A13E287CE9DFE237
-:1029E000E8C2C2702F1AE8F48662F0AFE23FC27FFD
-:1029F00099969798006A03F1E385C2FF1584FF94C6
-:102A000028FE75B9DA139FEAF81D42FA9AE565794E
-:102A100084F07EB22485E9E5E04B270F2B40F84F88
-:102A20008502DCEFAC29228E22C9C126A2934E700A
-:102A3000B591FDB9C61264FF4545B3702729E53845
-:102A40007FF3FB25E86FC6ACB35A49024BCC7EC777
-:102A500087DB0DF5C297F61AFA1775860DF5F18723
-:102A600041227D55F0A6F7792A8B3E5438FC55FC5F
-:102A700049F0792A4BBF0CDE45FA37DECFBD5AAD9F
-:102A800097D2C8AFFF7BFBF368D6A07F364825BF3F
-:102A9000377247AAD73400E191FC4E03F9DF807604
-:102AA000B4159511B80FB23E98EF10EFFF2D69F2F3
-:102AB0002AEA6F42FF9CF08E70C9237BAF1692BD4D
-:102AC0000417B25BC80F832B843DBFDAA4B23D9AD2
-:102AD00084F628D9230D157EB697A74370203DBFF5
-:102AE000069455C4779219ED577CFE3F23028D85DD
-:102AF0004562B1443F777D21B3FF3D85FC6906A661
-:102B000002A4F74ED0EFB43E78691EC5E34F902E75
-:102B1000C3F5B7B5BC304F253BC303EE08AE3B2031
-:102B200040069B0B03F7D0B8EF9BDCAB0BF1DD83CA
-:102B300013FF3288EC917585C2EEB34B0829A4814E
-:102B4000FEF315A0E78DD9CA7D8545D1384B4FF4EA
-:102B5000A3C733F5F8E6AEBA309716B75722BA8B4B
-:102B60008F3B46CCEEAAF1A4FF9699D8EFFC0B2D33
-:102B7000AE94E7496539EF804E7B3A2F99FDFFEB24
-:102B800035BC991D9DAB7E8EEFDD1014F6D60293F9
-:102B900097FDF5DB338F731CC52E99C047FE505A45
-:102BA000FE76117FD1E3259749DFC6CE3ADB7E6FF3
-:102BB000CF3C668857C1137D12C6D7A3E3ABACFFE9
-:102BC00062F6B9659347E835F2F3DF6FCEAE84D491
-:102BD00044F37CCEF1ABEB83AF1AF8E2C6DAB70C64
-:102BE0007C7093FA9EA13DE2E9B252BC32B2276BEF
-:102BF0003AC5D73FDB6D2F263C20FE0F16C6C4EB2F
-:102C000022CDA3AB60ECB9ECF72FBC8EA3759D8CE5
-:102C1000577DBFEFD4BDC9F5485D84CBF8FDEAF11F
-:102C200011BD4471D844F6CC5D12CA0BF277495EEF
-:102C30007862E405401ED9FF7749A3BC44EFB6FD96
-:102C4000C147A9BDABDEEEDEEEE3F808C74D6A91E1
-:102C50002EC86E00A7787F81CDC176E81D3EE12F9A
-:102C60001EADF8EA06B25F7320D58B32107FC27FAB
-:102C7000A2B8C97C531AEBFFD55907B8FE61338857
-:102C8000BC514DF821F25797A6A60ABB58C1FE5871
-:102C90003F9161E6FAA11181AF981FF3C39CDF5801
-:102CA000DA5FC4F3C01319447CF833D9FFB5E05799
-:102CB0007780DA6B32D0DF46FAFDC4AC8E35116B0B
-:102CC000ED1A70AD05F1FE49B2FA395934637CFD55
-:102CD000AE253FF3139BE0DF49BB4ECF53113E1FA0
-:102CE0009A24F6CFD5674C1CAF0167C4568D7ED8A9
-:102CF000038303561F8EDF66457BD2299ECF1E13AA
-:102D00008DCB9EB0624971D024513A7DC2EE75F9E7
-:102D1000449E532F4710CCB09CE4D3E57CEB708AE3
-:102D2000BF9DDC6C07925B38BF42FE96FAAC88E32D
-:102D3000F7CBF02F028117F71A5CAF6788FC05F11B
-:102D40009F4742BF16F721FB720CF167726053B1C7
-:102D5000FDFD3DF66D84BFEEF51E16F1B0CF9A472E
-:102D600073BC5BA713D9A7C5BD7F0C20DA2FDB4648
-:102D7000ED8B5F7EFF1D8ACFFDA63030D487ED0B33
-:102D8000CC7231C9C9C5A91D1CA72BF6C93C2FAEF1
-:102D900097F78B72AB117D7158EC88705CEF6CF11A
-:102DA000FB9EF6FFD9CD9D1BF3395E2D8F25B9A271
-:102DB000CF8BEB28A675E8FBD4D7111DA777FED1E2
-:102DC000E3D07AFDE387D60CD7F20837FA13E8E5AB
-:102DD000AB743AB6268EFBD768F88CC74FC18860B3
-:102DE00088E3796E703760FD5A0D4E9FCDC3FD703C
-:102DF0003C44194FF85D3CDBE92538EBE3F7CB8029
-:102E0000C053BDCC73C548FF1CA2BFDB82224FA0BC
-:102E1000B723FD893867730AD3EBE2E7DE7AE7E789
-:102E200038CBAD8F8E2924FDA1BF1F0F6784EF70B3
-:102E30005ACF0249E4CF10BE37D1F8F1F981F385BA
-:102E4000EB89EC4ED60B27B6FD2C44EB3B91056E7F
-:102E500013F2E3E27DBF7DD33496E8C41996B084C3
-:102E60005DC6F857BC9E7243E03A92237694236481
-:102E7000DFD8F5F7065A0CEF55672A77F9D81F55B2
-:102E8000EE2679645785BF362450C1F5E556E1AF8B
-:102E9000EDEA34CBC4DFBB2C10223DBEFCD50C9533
-:102EA000ECC7E56877B0A79317E4F54232FA41E939
-:102EB00009EC069357E6785C5A600DC14BFAD1D401
-:102EC000079FC889FAA3BABE2CD2F4BD927F6303D0
-:102ED0008DEFD3E281686772BCB314029A1DA1C55D
-:102EE000E19A0F701C4297DB3698EBA0F8CF9ABEA0
-:102EF0000B1CE41FCA382CC7D73CB3D3A0173B72B6
-:102F0000551D4ADA11D1BAB5073F5E3F1FC06BECC1
-:102F100047DB0512D6D07AD5814823FEDA3AEB7723
-:102F20005D2F60D932E691C84A6AFBE6B44476A4C4
-:102F300043B303B8E847EB14EFD906AEBEC384FA37
-:102F400033D96B81F763F4A00339FFFD3C6D5EB2AA
-:102F50000732BBDBFF4078EB691F17AB24F8BC6F6F
-:102F6000EDA5DDE6AD49240F12C28BC8C433FD18B0
-:102F7000D16332C4EC9BED9E98BA14072F89CAEE38
-:102F800076E57482FCE577DDD7AABAF0AB1F1AECC0
-:102F90008110AFDF6AF18317E9C9E6C176C3390C46
-:102FA00055CB7F220117C7ECEF1CF64576B955DBF0
-:102FB00097F522EF8BC6F5F7BBA4D7A75EE2EB0B24
-:102FC0005FE2F885EA4B1B7E4AF5A50D3FF5125FDF
-:102FD0005FF812C72FCCBEB4D7A7CCBEB4F1AB5E9E
-:102FE000E2EB0B5FE2F885AB2F6DF829575FDAF063
-:102FF000532FF1F5852F6DFCAA6C073ACB81CFCD0D
-:10300000A6379A4374CE46AA0A73DE3857058E4710
-:10301000A73603E72BB67B851FA5C7E947D2103239
-:10302000FA2D567716D9D1DB1BEFABFC318E732A04
-:1030300013174FF9FCEC230A8DB36D1A70FEC2D939
-:10304000F8D1518A7FE540D81BCEA1B89A04E11887
-:10305000BBF4FA600A8463FC896AA58FA15ED43947
-:10306000C0D0FF964D430CED37B78D36B4FFA8A9FD
-:10307000D050BF492D33F4B7434E4B1EE55D1B2D99
-:103080005ECA8359686FA567C20D76D8F83D05FF03
-:10309000911F9383167DF7B8B88F74D56618D7192A
-:1030A000D77EB67C407C3E614EB1964FE8FE7E41B5
-:1030B000BC0F6E4FC2B8A79E4FD0F139DC92C4F856
-:1030C0005AA78A7CD39A69C28F9C1A729B286FA9CF
-:1030D000E36FB44672FABEB7D519FDC9F446772539
-:1030E000FBA34DC0F9DCDC2A7348C9A138C1C04A32
-:1030F00007E239B443D04708047D841A81F385A1DF
-:10310000AADC95D47E2A047C0A46A78FD1550B678A
-:1031100052DCB53EBB5F16C51972AA043D2CDD6BAF
-:10312000A4034AE7D256D30F4BBCFEF4FA8C02CA72
-:10313000E79D819727049CF5F3E7E97170CFDB6188
-:10314000C44B3CDEBE2D5ED614C77F57F2EDF06255
-:103150009B2177A4519C540599E2322F660F373397
-:103160001C9ABC8C9F19D88DF830A70938DF134FF3
-:103170008FAD7510AE8AE1DF1C6F5821FC4C93F2C5
-:103180002B99CFF0DDFEC0A744195FDB9A44FE16F1
-:10319000CB641A1FF6CA0328AE105267F3BAB737CA
-:1031A000DB92E93CDF57F566A0F3F2DB73E40194B0
-:1031B00017DBFE8C696EECF920A40ABB3993F7612A
-:1031C0003797706911A5A2956011ED6189EA835660
-:1031D00098E3F0A94AD49E3E2339EEB962A2FE5B81
-:1031E0008A73193E694A86015FD61223BF23180FDE
-:1031F000E5A37C1C4CBFCB4457824E42AF4BA195FC
-:103200001C5FE932D510DD68E72DD257CD06CA47DD
-:10321000D567FF742ECBAF7A1BC31D5608BAD0F307
-:1032200082D6264187F1F4E3F21AE9C72A0D3489E0
-:10323000FC96E01F7D1DDB146DDE2C0954967BB6D9
-:1032400001C467D6B8F1EC243C49DE78045F3A61EA
-:1032500036D07BCE123BE7B1413ACAF8B74E00E810
-:1032600013734E217EBD675DE777A4F30FBF239DE7
-:10327000EBF267AD57933F45E25CE429A46B8A1FEC
-:103280004DADEA04FEFE0ADC26A247A4835959C5C7
-:103290007CF4817F76911CB213BCAAD3A8DDD5A99A
-:1032A0004C25FA9D2EBDA2B8709CB587059DA37EC6
-:1032B0007989EAADCD16A0732628674C3FA2794BD9
-:1032C000EDEE952479A481E369DD853E943B1447B6
-:1032D0007CC5282F8A3A8D70CB8D97EB3DC0B127E6
-:1032E0003D110F47D7040D8EC508C721DF1E8E364E
-:1032F000AFD0C3E92542CEBE98FD537ED57D589C04
-:10330000AB495780E1FA852AF4F274E97898E4CB66
-:103310003A05E50BB6CFD0DADD25429EE870CED572
-:10332000E0ACCB9375F32183F8DE4DF2C44970FD18
-:1033300088F5765B9180334084F39FA98AE09335CA
-:1033400056F0529CB6ADD4E9A57861AEA2C1B7499A
-:103350008397094C04DF78BA9421A68EEB4B8DAB92
-:103360007F5BF8964ED0F4643F283E1FF8AE4B4981
-:1033700015FC3654C0C7EA8CF0B9E6A61C8B77253D
-:10338000F275470EC21BDB9B5E17F0FEA5D67FD5FC
-:1033900018E07A53DFD5990CAF9C859944CF4DD670
-:1033A0003695F2584D3AFD69E7C25C9A9C9886FCC6
-:1033B000BD00DF5F8DF289F290A92501078DD794BA
-:1033C0006F0189F7BFD99B68FF0E9FCD20072FABF8
-:1033D00031C235250E8E49DF91FF7F3CE1BBF1FF05
-:1033E00076FA15FBAD1906D0C979C89083E0642B35
-:1033F00099984C74D4D2BA9DEB32849A7271FF0FB3
-:103400003B85FDD5D23ABBD7F351214D2E6CA97324
-:1034100070795F9D9BCBB6BA4C2EEFA993D97E698C
-:10342000ADCBE3B2A5CECB65535D0997ABEA14EE05
-:1034300027ADCDA860395C051CCF5E99F239E7DF76
-:10344000E3E7CB518D7A6C706DB201EE7D6618F5B5
-:1034500055BA62D457748E29B6DDE51D65684FC92B
-:103460002B30D493E48986FE5326047E3981E48090
-:10347000A7324E0F223F8E899EB36B6915DF4BE951
-:10348000F0D3F59353E3F33556EF00CA3B395B05B0
-:103490009F366B765E13C111CB6405F8DC8CEDB002
-:1034A000E40D01F1FF6AA6F38771EEFE488B1DD98A
-:1034B000D7286427B4C8C28EB78238F76BCBF4879D
-:1034C0006BF07912EA2FCAEBDAE6A6B05C78D8E3A3
-:1034D000F4D239DB96D6656E5E8F579CA771E3BF39
-:1034E000447980F8F3358EA1C67339D6B39C6FFC4E
-:1034F000754FF4DA9491508E9C2167BBF32FEF6BDC
-:103500007429F22FF778043CED3DC8A3D6387BD957
-:10351000A9E55F60A02F61FFA83D25F20BAD717199
-:103520007BF4C312E66FDE9A2071FF3F4F9085BF98
-:10353000660903C96B9717DF8FF53B14F17DE8B976
-:10354000CE8F3F3E4F8C7C0A2407FE3C019F2B4FC1
-:10355000083B254916DFA1D84051583E81C887D085
-:10356000591FD237A95ABEA75BCE908888A13BE7E6
-:1035700019FEAEC88BD06716443F96E8FB17C4BF50
-:10358000FDB66523F9C3C37A69A7FC5002B9E02AE6
-:10359000D1BF1F832E4F3180EEBA23FC5C2589E119
-:1035A000172678359AD6CDC8C5E7A95E8B173100A6
-:1035B0001525F25E3A5FB14A4965FDBEAA446E2701
-:1035C000FEF942717A091FADF955ACAC93867DC8FE
-:1035D000A2B7B1C4C676BA8E87246D5E444F679594
-:1035E0000E67ECEFCC9B11ADE37FCD6336725EAF1F
-:1035F000E5AA4738DFD732EB3F38DFB73A6B7A1EA0
-:10360000C9BDA492E9C7F82097861F660DD2237919
-:10361000C6FCDEE9D3A2CE70A0F8849607048F31F1
-:10362000CF6791FD86F92F349E60A0D0436051F89A
-:103630007B8333E95BF0B5DEAF673E50F5EF4E5765
-:10364000D2F9E0268F90A34DE07D3340F55724AFAB
-:103650002AD3F38237E9BCE9EA8116C6CBEACCD992
-:103660004DC28E177E53936725E76DE3F5369DD7E0
-:103670008C95DB745E3356BE37C9B37BD5CB59010D
-:10368000739CDE37BE9F1D34EA1FFDBDA4CC2B5FAB
-:10369000AB8A392FD56CF13B485EACF2DC678AD53A
-:1036A000730F2881052531E793AC99B3F83D7BB6BC
-:1036B0002FE1BAAE50948544DFB8FF5EED81F59AF4
-:1036C0005CDCA8E997B3ED7393D6FF01ADFF66D23A
-:1036D000EB23A2F8193EF4F26496CFEB441C8379F5
-:1036E00020665EA524B082D615C5AB390A17A4D3CF
-:1036F000E1F957B0DDD1B06E7632E169E7FADED795
-:10370000A3E7D5F57E7A1E353EBF6EF3980DF0DF48
-:10371000A3C985175C0B2B1F40D0EC6C13F4D4B0FD
-:103720004EE891E14F887D9C4987C6F5EE6CEBDD54
-:103730000E8AEF4F91C56E3AE17A465C7D405CFFA0
-:10374000DCB8F65171ED0571F58971FD2BE3EA578F
-:10375000C4F59F1D57BF36AEFF82B8F6DBE2DA979D
-:10376000C5D5FFCD884FDFB56989E0188F3FBDDF34
-:10377000B9E2EF5D5FC57EA2A3E13083E945A7B75B
-:1037800073C543D4DEF5339DD94A46B17CDF81F65B
-:1037900015D9433BDB2ADDE27C4760E56E8D3E4870
-:1037A0003F58368879D0CE4AE6F89CD36390236799
-:1037B000C3B709328CEDB17668EE85C7F7D9E93326
-:1037C000A4D917BDAF5BE7E32913FC27490E414895
-:1037D000F899BA5DBB4D15FCB34D5D50B99EE46DD3
-:1037E0009359C49FB5FB50E86E1D11270F684A38E6
-:1037F000C2F18426CD4F68D3E4C95A4D9EDCADF9A1
-:10380000094943839B28EE9B7C988FE740B3AFE048
-:10381000AF0B103FF797166FA3EFC7EE1E53F2F8EA
-:10382000C35877FD5D827021DAE9635B14B259DA1F
-:10383000948C243A4F946272B4939FB8AAB0CD3F4F
-:1038400014FBADDD7FACFD79C4B39C69F3A2CE0758
-:10385000D9D265227A837C2F7F9786EB54C9C6B272
-:103860009677D5253A77BAF60AB7898CB0F419B2AB
-:1038700099CE11F79910E85B8AF018DC046605EB25
-:10388000196A98CFE25C532A0BFFEA196428DE6FAD
-:103890005716C1EBAB66DB7EAAF68C0F90B438DD11
-:1038A0007995FA38698234E887E38EB245ABAB8FFD
-:1038B0006CA6F3D04E49D4A73CF3F8FC95F9D1FAA5
-:1038C00098671E1FB812DB5B0B0799489EA67B52B8
-:1038D00013DE137375A9909FDB9B170E4EE48FE9DF
-:1038E000A53C13383021E76B25D1D4042C876AA579
-:1038F000AC3DCF14F52B35B8C9B55ABB4794177AF0
-:103900009EF8F1E794BA753B7B809F8D6CC877F683
-:1039100033D88B5797F6622FA279CCF1DAAD56796E
-:10392000009D23DCDA6C03BAFF616B3688EF905799
-:10393000D9F8DC2858DC03AE7145D71D5AD56F1E67
-:10394000D14DC80486386EA6065FFB4493768EF28E
-:103950009B307DC7B755CBF36C8588DB9D1F8BE70C
-:103960005FCD27BCEA78DE57FAAFCD449F1DD90B57
-:103970002B37E27BEB1ACD1C3759D798CB744EE32B
-:10398000907D746AC52133D9ADF9D06E263B7F1482
-:103990007D793D84AE400A70D9AEC9E7FFD4FCF80A
-:1039A00061A0F0F341D0C5C0F9B438F01382CB1058
-:1039B000126D12F18FDBE4C07996EC4BAF48A4B7DF
-:1039C000EB4AF5EF7AA1C652ACF91732C3B78EF8BD
-:1039D000281EBE74429FE38E8ABF9EDA9D7B5F0DD8
-:1039E0005F86D5DD6F18E993F0363B46CF6CD4E0A7
-:1039F000E7F6FA15C2E1B5C581167A7FC9A6BF1EE2
-:103A0000207354565533BDFF14E11D9F2F0C07A79B
-:103A1000D33063BCE14AEA3FBA76DB7E8AA7E5058C
-:103A2000EFA8EC8FEB1BAE54577A888694C0FD3418
-:103A3000CED0CE48850BEBCE4DAF86B3783D6379C3
-:103A4000BC5C7D3D480FD54C476E11C7D7F04BF895
-:103A5000A773CB0B370BF8607B16EFCFE2CE8A5DF6
-:103A6000FFB669FDF8BB8578BA68D5E0F758148EC3
-:103A70006035FA358F2582A34EA73A3C6E78A26B4B
-:103A800015E53AE7873A5F2439E8DFE49EC6F2B0ED
-:103A900038F024BDEF6BF337701E7057275D47D4A5
-:103AA0000D1FA7D249D7BB603FE569C2FBD615EF12
-:103AB0005772BC782F88B8589C3ED44BAB129F6786
-:103AC00010F7E58CDB6BB493915E958D9E587A353B
-:103AD00073BE33A4E9935013D22FCDB742D06F48B1
-:103AE0005DE64E44678F687A658746B7FAF3A13D75
-:103AF0009CBB3C54DAED27664A46781EEA8DEFD32C
-:103B0000C0CBFC807C7084FA65101F607DF00A37A2
-:103B1000D3A7CE074BF6FEF500DD67E3F4C905B188
-:103B2000F7D745343C227DBE43EF2FD9D475807C36
-:103B3000C5C12B047D7E4C77871545E90CFDC7F781
-:103B4000A89F4E3FF1FB78571B4F2EF67F4C785CB9
-:103B5000B829C8E321FF1C2BE5713AC349CC724A4E
-:103B600025ED676B1BB8693FF65F1474905C3855A0
-:103B70006B62B8DE981F5E65C6F2FAA160A5EB869F
-:103B8000AA33916C72298F6BCCFF0D6B33E20FE976
-:103B9000E76F344F91276013C1EBA08DE5690F7477
-:103BA00011D57BAA0EFF157172D73CB1177A3ED79B
-:103BB00071D7162B8E8945DF621DE7D84F8F379D51
-:103BC000193F1DC5FE434BD36CFD9CF00CBA8F67AB
-:103BD0003BC54F11AEAB9A7AB7572F58FCB4F9A436
-:103BE000889FAE008E03AD4C196B4A44379740FC5A
-:103BF00074CAC444F1D3C87B063B735593900B3A07
-:103C0000FC86578D4C16792948A57C891E1FD3F751
-:103C100075B7664F3669706B21B8313C05DCDA0840
-:103C20006E0C4F1D6E33843F425F8853BCD66316C3
-:103C300079B1910B3651BEE054A6C893D767DB44E7
-:103C40007B8EC82F9C411F9931F634F2C19A667160
-:103C50009F08BECF79B517B30F3886509E33D3CCAB
-:103C600071DAED9EFB6AB6733D99F9CF0A6A5B1E65
-:103C7000CE3BFCC3B9EA027A5E62E773F27A3EA7F2
-:103C8000A5AFC8E7B8F2B47C4EDC7C76B8A9B28D9B
-:103C9000E6CB137E4B8F74ECD3F2115A1E2823DF30
-:103CA00098AF70C4E52BE2F3956B9A17ECDF2EE228
-:103CB0002B2C9F87FF7824FB63F1F3B8671AFDB7BD
-:103CC0003523753FEA1147A2EF1852AB8CF4D8A206
-:103CD000E1BBA1AFC8479C6D7C284F36F8552D79C4
-:103CE000E71647D0FB911FEA4ED03FDE0F3D1FFF86
-:103CF000D6CDE31BEF074CE0DF6E99C8F11441DF2E
-:103D00006B9AC5FEBBE3699A5FA59F3FD2C7B16AB4
-:103D10007E1CD773A2724ACF870D75DB985E876AC7
-:103D2000F74535FC7B4A68650EE5D76675513E72EE
-:103D3000E80E89F3EE439D7ECE43746C98CEF9F184
-:103D4000BEC981A727C6C49F76B87E9AC9F9022D3D
-:103D5000DECFF7E6A0DE53D715762A64EF8E04BED9
-:103D60006727392E1F107F3F4E7C7D4E99D0C39917
-:103D7000D741C27B4F3E9F28DACFF4DFAF6038A136
-:103D8000BF9B2CE4ADA2D7FFBFE4A976B61DE2EF3E
-:103D90007D4EF94093B3FF0997A29C3D5112389E86
-:103DA00050CE5ABA58CE8627289F919E5C4E177DDA
-:103DB000101E6E4C7C3F8F5C76A9E2E16981877CA6
-:103DC0001D0FF75C92F942C4437659223CA05F452F
-:103DD000F06AF32983A85D29510653D98D8F1F26D8
-:103DE000E68B5965C2EEBB58F858A7E1E35EC207FF
-:103DF000C769642D4E93C7CF9B357CAC39031FEF49
-:103E00000B7C94E8F878EEBCF09151956168779757
-:103E10001BF191EACB35D49DF9467C240F2D308CD3
-:103E2000B7BC4C16F7240D9C68E877263E8CFEC084
-:103E30009DF45E2FF6E8C04067057D4B34606E7BD5
-:103E400007C9E64C7F5B0595FA3E37C7F9737AB927
-:103E50005CC35FE6D4C4F85DA0F15BC644E526030D
-:103E60003D7C2F317FD668FD979728B794C5F2F334
-:103E70009589FB2FD1FADF3641591CDB1F7FD64BCA
-:103E800031F6784FFB0E242BCBCB78FD224FB6A317
-:103E90003E95F3663B92E476CA57ABF54EC3BD75CB
-:103EA00083E937AC67FEE89B0E95CED9D13D4168DA
-:103EB000596DBBA35FEE1A6CDA96317C25C1B1A9AE
-:103EC0006C88B8BF7591FF6DCAEF28EA09ED1CD266
-:103ED0007CBEEFC814EE63A27BB2C09D714EF92385
-:103EE0009467E25EB7C120BE238620EB41C90FE98B
-:103EF000F4DDB205FC225F4EFDC5F785BCF9140860
-:103F000073DD0511AEA7697EDE0365393C6E3AC8E4
-:103F1000260124AF89E4A8CEA70E4F90E9DF53EB2A
-:103F200036AD245FCE0250467EA073207FCF0B9526
-:103F3000A0523ECB040EB6334DEB0F7CCD793AFD4B
-:103F4000FBC397FB88EF0FCF717FE7DAAF91EEE508
-:103F5000F344EFE56BD4EC01FD5E3EB532C8DF976C
-:103F6000AB2BEDEE06CF99DF973F3A31B08BF0FDEA
-:103F7000B7A4412191640E4E98EDBAA0E3872FF2C9
-:103F8000F8AF5CE4F1DFEC6DFCBBE9D752CAEBF9AA
-:103F90008F123F37B88AD9EED4CB78BC5DA12811F7
-:103FA000EA27395E1BF0619FA83DE73C6A627FA863
-:103FB000C124CE9FA9EF99D8EE827C41074E19F219
-:103FC00072C645C7717A838345DC49C45FEAFF74D2
-:103FD000D708B2BF7F99322B9286E31D7C55D87FDC
-:103FE00096A991CD74BF73FF349B773BF2DD3DDA28
-:103FF0007AEDA513EEBD137FBD798A90172E8BF74E
-:10400000F2023EB7343342F6A3ABD82253AEC01906
-:1040100097D76CB5B42553BCB275C77D15A3B0FB5B
-:1040200063752FB91B137CEFE9D4F29A23A5C472F0
-:10403000F09F939244DCCB67BC4FD85AAE9D2B497E
-:104040008554B2232DFF52D2129D07D04B7DFE2204
-:104050004FA48ABEBF8ED0256E88E7A292EAA464E0
-:104060000F9F8BE824F8567AC30EB27F1F5F10BCF7
-:1040700035F6FBD3D61270911DEF9B22CEC36E5046
-:104080002417DDAFF160C4C2F78E3FB8E8E9E6144B
-:10409000ACEF3D6A76133C5AFDEF3993B1FE388E92
-:1040A0004BF2EEE00E71CE529D0FA16108BF56F2A9
-:1040B0002AB1BE5B11E7B2D9212BD6AEEA43F8FF95
-:1040C00075725F016F0856D3BD9DEB5226F37D9646
-:1040D000D973443C78BA74B483DE7FB0C4CEF81B85
-:1040E000A29DD331A9D57C9F65DFF9C6733A0F2E07
-:1040F000EF5409BFEE52BB5BE5F3974ED7587CDF18
-:10410000F5A8192456715D3CF974C929D6E5157EC8
-:10411000EEE37258A5FB8EFBE27BF56EBE35D170E7
-:104120001E68F726E19FA68D777A91D271BD71E75F
-:1041300085F475B5E1BAE8DE63D7508E4764CC31BB
-:10414000AE2F2DCE6F70C6D5A79677DFE3339CF0E8
-:10415000FD85FFA785AF71AB574EE47FB6D64167AB
-:1041600055CCB904670F71C09AC982AE6D592F380A
-:10417000C84EF9C27FC4433878E59F073EBC97CA52
-:104180007FFD6ED75284CFEFBF7E73C793B4BFDA83
-:10419000BB0F11BDEAFE189FC1C4F5BC586D63B8D2
-:1041A000F96768E7397D1D2F587DDCCEF9A5B5FB91
-:1041B00093B87D64398492B07DA445C9BA99E8AEBC
-:1041C00053F2D6CB3488388FA8E37FED0D7E138C65
-:1041D000213CFA25BA0F639A76BE76C3229009FF76
-:1041E000B645ED7C5EDDB75C9C57F729D5497CDE92
-:1041F000748E99CF87D4575F73F930ACEFBA5CDC1B
-:104200004F3563B9328FE75704BDA475169B9713DA
-:104210005D6689FB9AF4F3A645D0C5DF7F8CF4B6C2
-:1042200077D848DECC4700D3FA5A357C69718322AF
-:104230005FA74AF6A4CB6BC463461CDEE2F1BA4228
-:10424000C7E34818497894A12D99F4E14300ED742F
-:10425000AFC086E54FCFA3F36C5FA8690CAF9EF8A3
-:10426000F91DB4579511740F8B83CB4EB457A9DC4D
-:1042700085F62A95AE60C575CB71DD7BDE38F8D248
-:104280000F71BA594AF5957444AB48CB7B81BA7427
-:104290005025AEFF06E25E51DF4289C4777D92A1D0
-:1042A000BED66389FE3D00FCD595A5FF7D80D35B1E
-:1042B00094A108964C8B968F11F559E487C4B4EFFE
-:1042C0009E69EC5FB63F66FC81B8DEC5366E0FEDC9
-:1042D0005BBA45B5C4B43F87F572805735FBF1FA38
-:1042E0009D66FFF604F2EDDD7261475AFE052AC9AC
-:1042F000B52FD14E23FF5E322B2CDF21D72227BAD8
-:10430000570F00E561AC5F2E1BE5EBE51A5F58FC2B
-:1043100015A0E5C7E01B3DFE803F7BFE388BEF63B9
-:104320005A35C4C2F70FA13EF0F696AFB3782C9F72
-:10433000C6DEDBF5AC2EBF87C1309AFF4B28FF43AA
-:1043400005F341CCBD0DC4F76DCF5FB614E7F11D89
-:104350004DE638AAE45A9FC2F731D535B13C7F40CB
-:1043600009FCB63CE67C4963FAC242922FFA3999BD
-:10437000E8BD47D798BFCDBDF71DD50780F4C297DC
-:10438000485AF65EE8B0B16EEF115AC7EABA762E17
-:104390009D6E85858DDD12E4B8CF154AE04FB43EA1
-:1043A0007B26B6C7F089D58DEF19FC0EE37D9CB254
-:1043B0003BE224B86F28F9C049F3B71E167CBDE173
-:1043C000F0EC24E2BB56EFA124E29B2FE8E2C7EF1A
-:1043D000C0273EE5559661BBDF48BD9EE8674F4369
-:1043E0001ADB150797DF7F2DF1CF8DBFF801C3BB17
-:1043F0009B6FE0E14195CE18BE818799AEBBF9462F
-:10440000ABF7CC377F67BEDADDCD37A2EECB074303
-:10441000FDE04C63FF6EBEA0F1912F1EAFB073BBE9
-:104420007DD2C35BD418BE3A49F558BEF909F24DA6
-:1044300002B93F7D9246DF17986F522E32DF0C9DF6
-:10444000A4C9CFEFCE3763275D14BED9633A1FBE30
-:10445000B9EC4CBEA99AD4F7DBF34DAB3BCCE7E902
-:104460005AE79813FE7D900F347939757EA0B28D8E
-:10447000EC1A45DCDF374D9A99E5F3109F497487B4
-:1044800034EA4FA1CF0F5EDFFD7D06EB67FDFEF541
-:10449000F58450B293160BBAE9AC1371DF6952F987
-:1044A000B4C5A477E93B024A3553F694EC02D4FB39
-:1044B00032D985D05EE1C179365499A04DA62D0739
-:1044C000AB87F1F861B6CF8668717FA7942FBE677E
-:1044D0009A29FEEE85FE5D4CB562BC5FB6FF59ECD5
-:1044E000265C770AF931EE12F17750164D8AD7BF64
-:1044F0006887E0FA3A07DA984E362857F71A273ACB
-:10450000E35CB52F98302FF9D6249376CFBEF233E3
-:10451000A2B3DD6F6C49A673127B24E0F339F383F9
-:104520004FCD23BE73A942DEB4AEF833A52361D7C5
-:10453000B41F1AF5347C6AD4D3F0A9514F6BF51E21
-:10454000E58D7AC2A8A7B57AB79ED6EADD7A5AABCE
-:1045500047E5CDA7063DBD61D2A70679F31ED5CFAD
-:10456000414F1F9E7471F4F4A88B2C6F9EBE70F2A5
-:1045700066DFA4BE1743DE1C392F79937DA6BC39B4
-:10458000743EF2C6B5B943A5F4CCC21EF8A056C31A
-:10459000FB5B65CADB343E949C5BBC269EBE3AAA9C
-:1045A00017AEA6BF2BF3A557F87F3DBDEFAAFDD5EB
-:1045B00091C6183FDC65E914DF23D4EEE1E7B76C60
-:1045C0007E95E3B1675D2F5D105A74A65E45BBC84A
-:1045D000C1F4EB35732EFC7CD7D13A47F0DB95CF95
-:1045E000DEC1FC945C6E9C4FB77F3BAA6D669EAFAC
-:1045F00044C8E99EECA19EE6FDA05C16F7FFC5CD80
-:104600001F4FBF489FE9938B981E2D742FF8179D5D
-:10461000C07FA7EABF4E6EFCBF8A7C49E9C51193F3
-:10462000CF834EA76BF84CB06FEFC5DDF705E3CF36
-:10463000E993CFC38E3E4CFBEE9B70DFDF67385EA5
-:10464000B47D5F30FFE1E6F3C1F7BBE5DDFBE6EFEC
-:104650005132B47D6FF8E735EF515C63C3BFAE7D77
-:104660008AE21AF77D9DB78DE21AFABD726910FDD4
-:1046700091F5EF8F102E2EBFF89E24634ECC774518
-:10468000C0FE7DF4BB13B2377CDDEDFF2BF7CA9182
-:104690007DD2DBBD72AD36635C4F2FAF2A17F64A71
-:1046A000AB691DC72336A05F558F78EB9823E211C5
-:1046B000AD68A7B0DC9953D0AB7DB4AB4EE1B85335
-:1046C0006B9D9FCB7BEB6670B9EBB5256524777D41
-:1046D000AF2D62BDE7F3FAAF7B1881E4AEF8D049A5
-:1046E000CFEFF5E8FE90B05FD2C87EC1FAC393D792
-:1046F0006F8D8D0B8CFAEFE15BD481D178555B66C1
-:104700008CDD23C7FA51A012B944FD28AC1BEC9AEA
-:1047100011EC47ED26BB06EBED934718EC1A7D9E96
-:10472000B566A821BB66ED0EF38C4476CDACF2C421
-:104730007E14D6390FE27039F8FB7F49FBFB5F51DD
-:104740007EE9DDAEC99D7271ED9ADF4FBE30F18713
-:104750006E3ED6EC990714E50D4DAE7C47F9B1D10C
-:104760004CF1E36F2B3F4692FCC837C88FCFCE4742
-:104770007ECC2A771BE2A20765B5CF58B2D37798D3
-:10478000A15ED6F42FD63BD1AF31219C7E5221B110
-:104790009FB3C10BFCF7FDA64BF35F267AD8BDC8CB
-:1047A000CCDFBB3FA88873220FCD11E7A91E5E5E48
-:1047B000309B3E235A9772C3DD4914D72E17F70456
-:1047C0004C97CA39CEFDE00C61E7643BDB2FA7FDB7
-:1047D0001FACB000D1D5D9E2DC146EE778B5E6475E
-:1047E00081B499FD0ED70F2D6E3AAF1A1FBF769682
-:1047F0007CCCDFCD83F40A7FDF7DB6F8F5B78D5B27
-:104800000F98F29DE3D6CC8F35CF0DBF41759E49F1
-:104810009F4726CBE25C620F7A2C9E9F3BAAA7A7FC
-:10482000457A3917E524FB29E61E59FD7BD659E563
-:10483000621E27D94F8551BAE8A82EEEF55EDA94AC
-:10484000DA678EC4E685522CED3C5E4AED3E7EBEB4
-:104850009ECE2F90CCB27859AE3E5E89F239C178A7
-:10486000FBEA8287092EBFAEAB3D4C71EA49964EFA
-:1048700089FE9EEBDE3A95EB7BEA9AB8DC55D7C60B
-:10488000FDD6D76DE2F2BEBA103FBFB7EE31AEDF54
-:104890005DD7CEF5C773C53C132D211E6752178E09
-:1048A0001FC30F659FE03C31782E8DA886F6096FF7
-:1048B0003619DA8B3ADB0CF5BEFE4D86FE7D66843A
-:1048C0000CED6F950502538AE85CC363867ECEFCCF
-:1048D0007643FD5CFD850BDD6F654AAAE51FC8AF19
-:1048E0008302484F4867E9B5B2CA79F31AC197FD08
-:1048F0006BBD61AA6F71D998BF75BAE433CB26B18D
-:104900007E53CC3DB51D2E717EB2A1AF88A734FC7D
-:104910004CD4B76489F391C3AB447EA461A0B8972B
-:1049200044CFC36F7169F793F8C43D1A83F223FC37
-:10493000DDED20EDEFC139CB45FECC0D6ECECF378E
-:10494000D481F67D6284F31D1960F68AFBD5159932
-:10495000FF9E920542F5385F43BE5BBD85E44C3057
-:10496000D56BF6F29F960D99298F48E2899330ED29
-:104970009ADED1F2F2491F009F3BE886CFE7E27B47
-:1049800084DA2EBEB7A97F6D17E7E3B6FC42DC637D
-:10499000130FD78E5F7CC5F72A6DFDD95759C4D444
-:1049A0005BBBCFED7425C57E8FB6A52695EF5BD892
-:1049B0005A9BCBE728B6D688EF8D6510FBDDB2C8D1
-:1049C000C6E730B6D69ACD24274F2DB2305CF4F529
-:1049D000C7CFAB7FBFB94E3BD773AF76AE67AD766F
-:1049E000CEEA6EED5C4FB376CE6A8D763E76159D3F
-:1049F000EBB1133CC5B99EADB50B14ED3CAB7E2FAE
-:104A000003C35742F8F2772A56D86B1A07F4870C7B
-:104A1000196EF1DFC7665425C79DE7319EB74AF589
-:104A20000D30D49DF9C6F356C9434719CFA90E34AA
-:104A30009EEFB1798CE77A2CCE4AE3F9D058FA444C
-:104A4000609A566CAC27FC77FF7D477AD88FFF7E43
-:104A50005C37FD86F47340129D4349637ACDAC12F6
-:104A6000F499A17D0FE3864E2E53915EA874529E59
-:104A70005DA273902AD351F4FB37A5577A3ADFBF72
-:104A80000720AD4CFCF700F473087FD1ECA8A553C8
-:104A9000944FA71445E7BB7F8A723CB6AE973DC9D9
-:104AA00085FFADF2FF01C18CE32B00800000000008
-:104AB0001F8B080000000000000BB555CF4B1B41B9
-:104AC00014FEB2BBD144A35934B6865A481A520DCB
-:104AD000A4B06D37A225D2D5869283C8163C78E85B
-:104AE00021879CFAE358E86D635B904A24A9422F22
-:104AF00052C8C11E0A821EFC03621B7A8E680B52CA
-:104B000029C18AE7405B7A11D23793AC899BC47A7A
-:104B1000E940F2F266E6FDF8BEF7E6E50D68798158
-:104B200090A2DD137D40245A2A3848065468B930D3
-:104B3000305324E9A2FDB5AA94359114C0A9095CAB
-:104B40009ABA1E2F4912D9C9163BFDD4CECEEF8D8D
-:104B500031BB0126252EAF1F39000FB015B3E51666
-:104B6000FDC0C20E9DABC0EF315B0E7E96DC49A549
-:104B700032CA4D01917D69BDDE4BC02CFB49F17AF3
-:104B8000C73D0309F29F3180FC30BBF3D0CD745791
-:104B9000343BE5A33C427B4548E42F5284DC078646
-:104BA000AFAC81F6E7AFDE17258AFB6109B84CFB95
-:104BB0000BF652EC11DDDB1AEF945F28CCCFB4FD7D
-:104BC000299DCF5C1121325DB71F962855D860AB67
-:104BD0005C237EA25255A755A1CF0334E894F70C6D
-:104BE000D347EABAFB243029535ECF0FFC1B8591D3
-:104BF000BA5D805261FBB7B51ECF71376D8410AAC4
-:104C000088751C15B6EE36CB3F866FA360673821DA
-:104C100030BED43D21E7A738BD5F96BB183EB1A892
-:104C20008B25B2478C508F13CE3DDD8D73FC7D6795
-:104C3000FC7502078683CBA22173B9650C72796C6F
-:104C4000F8B83C3246B83C34142E4BC61897408A0C
-:104C5000D7B3D3061E2F63C47763C1F6F1645B59E3
-:104C60006775C78484F7ACCE432AB76BBA17253F64
-:104C70000D7C115DBC190A3D6F2799FDBB27028F82
-:104C8000B91ADDF4EAE166FBD56753E7E24E1B7320
-:104C9000BBAFECEDCF5D1D486CB6F0FBB2D6C740A4
-:104CA00096E711880B58A43CBC0EC529D3FDF4B679
-:104CB00093F7754871E49C0CDF9A0B3F4C1CD43F72
-:104CC000CB696A19829CD524997AEAD46F8F42F90C
-:104CD00034F45560FAE320AB677A223FA8138ED5EF
-:104CE0009B9FE786C92EB5232288E6BC5E6B369E65
-:104CF00097892B202982DC027F3B5C8F6BF618F2B0
-:104D0000F0B960E5DF7ADFAC3BADB4345A7BA2B4D6
-:104D1000125D898C4675D2D66D9C07A70FFC7D77F6
-:104D200040CB33BC17C80FB8433CE7238994AB9EF4
-:104D30004FBB3A997974D7FACF9B2C3B12846FF909
-:104D40001F7DD8672F3A58BD9692423CD7228FF5E7
-:104D5000DA9C5B526F39D97B44B8751EFD716B9F2D
-:104D600056F35991C83F9B4F2AF96FC1F737C67761
-:104D7000B59FF745AA6B46137CAC9FFB891B8D4200
-:104D8000F547904B116FD9A8A0E4E9FC97DAA17020
-:104D9000F796F9D0145F6DE8A36BCD73675B73551D
-:104DA000E74D1041366F7E0ECDBAF32DEA6B4A9374
-:104DB0004773EE34F358AEE24C567122DCFA3DD71D
-:104DC000EB355F1BEA488867FBE6EB797DD38E7F86
-:104DD0006B1FAC2475779EFE1FF0691FBE1B8C8F66
-:104DE000B3EFAF1D6F569E8EFF334FD6F3A23957E8
-:104DF0002E88F3A2F74CFD2FDBA790A6F00700004A
-:104E000000000000000000001F8B080000000000F0
-:104E1000000BFB51CFC0F0030977F3A0F2BFA3F161
-:104E2000D7F3A3F2CBB851F99E68FC2634FDE7D145
-:104E3000E4591820B4233BAA38B158988381410E15
-:104E400088353950C5F3A1E6D6002DE807E215AC48
-:104E500084CDFA2C05748F1C03C32920DD00C4D730
-:104E6000651918D8817C216906065F204E00E2CFC3
-:104E7000320C0CB380F43B20DE2A0DD1C707143B63
-:104E800027439EFBBB85C8D3378AA9831F28A1F27D
-:104E900067683330DCD66160D0D683F0AF20C9BB01
-:104EA00003C5666A43D831AA0C0C877419184E28BA
-:104EB00061373716287F18281FAB87DF7E572354AA
-:104EC000FE2E6B54FE4F4354FE134F547E9F372AE1
-:104ED000BFD107420300BDE0D98DD8030000000018
-:104EE00000000000000000001F8B08000000000010
-:104EF000000BCD7D0D7C15D595F8998F376FDE674A
-:104F000026C90B3C20C02404891AE8000182224EE5
-:104F100042B0C14DF181546997EA93B53622C81366
-:104F2000B1A6AE6D26DFE1AB8DE85656AD3E586DAD
-:104F3000A9D51A2D6D6957DB04D0C52D8548A9B5B3
-:104F40002DFB6F50575B16D9E816755D5AFEF79C1E
-:104F50003B93CC3C5E3EECC7CFC6ED0E77E67E9C25
-:104F60007BEE39E79EAF7B9F220640BF1CE01CFE14
-:104F7000B1E7452200CC197C462BA0542E07D8243B
-:104F8000048D70117BFE415AD91566DFC08A2F9FB0
-:104F90003ED8EE5A10A8FEF3456DF13EF6BD63EA29
-:104FA00057E350C6EA4F14A8BE53CF79DE0812402B
-:104FB000014049E76A35C1FAD934AE49C5FA1DFA4C
-:104FC000F695C0C63B53A28084E315656FDFD6001B
-:104FD000D03D0DE072D8AA16C758F998646C866C5B
-:104FE000E314D1384ED91F17A1BB14E8EF1CFBDF27
-:104FF000A62F2621C1C66D9DFAD59508B7D27D335F
-:10500000E811803BC6254167EF678248F3522A2C9E
-:10501000305959D5ADB835FDFC713A102F65D86BB4
-:10502000677C7964F0FD32072F0C1F197801B804F2
-:10503000408359DD16960340ED33FB35EDF1B5F8AD
-:10504000E8C63F7FFE7CFC19A0131E40ED8C272292
-:1050500083F06CF2F5774B0CDF5611188FB12A39BB
-:105060006C9C4A573F99E30DCC53EEF4ACFF74842B
-:10507000B380E621C8AEFE32E1996BD79BCB668E3A
-:105080004F675E390BF83823F57F25A2B800EB7720
-:10509000C6AD888B1E65CB83F7A05D5F33BDF586FB
-:1050A000C24F08F13307F163C5911E1D3A96C27ACB
-:1050B000630D9B4F8105FD522E918D096300F2F126
-:1050C0005FAC89ACE99548AF634C56977D1F1BB325
-:1050D0001A25F67EDC82B420B367041ED2DE0801F6
-:1050E0004253728E1A599CEEBB6677F431BA3D0377
-:1050F00091CECDECD92CB37E116FC723E9C71848E8
-:105100008D97A51EE963E588254353398D4B7C783F
-:10511000A77491B19991F4669BFE3B1A547AB63507
-:1051200068D0ED07686988D3F3FED097BE81FDD7BC
-:105130005B7ECDCF9E72D7ED4F61B9192081E345DB
-:1051400062BC7F9055ED310DCB6022DE2325FCF94A
-:1051500012E285C1F9558649C4CB0F6D3CE9D04DAB
-:10516000FCDA6C2CCF812CF8749EA1522F9F05F491
-:10517000206B3958F6C7F33C659F36DE531FA0906D
-:10518000F04665262AEA042E8F22722F180827C3BC
-:105190005756B960CB15499AD9DFCDE6179EA718A7
-:1051A000BB58D36D8297BFC6099C3ECA04959E31F9
-:1051B000E8DF7F0EF16288E9CD6CACE0CCE2AEEEC8
-:1051C000188EA91853D93A067D692D2F0B7F41B946
-:1051D0007CAACF81BBF8A3C78F24F5A41259C6FDC2
-:1051E000BDBD7E979F3DA222FFAB33C544BA0CE103
-:1051F000B5126CF2B05597459CF74707F7F0EB7581
-:10520000C2E6E73650A9BE8CEB553EB85E1D065B84
-:105210002FE49F72BE5E1DB2A58E66BD1E07F0E034
-:10522000253480972E8E97B28F182FCDFB5626B23D
-:10523000CCA3CD5E4F190CA394F0A0E808E7D646A6
-:105240004EB716A3DB6CF277283C4839C7E3C9B2E6
-:10525000F3F17E8DC0C75964F38983A74D865893B7
-:105260000E239E3A6B506E6D2D1145944B1F159E6B
-:105270001CB8360FC095E670957EB47049A1EE95C6
-:10528000D9F8B12D831FB720DC9CEE6A38DD891F69
-:1052900029DD397005901FF83A27F83ACB7F13EBD8
-:1052A000DC36B0CE49BECEF18F669D9DFD1C5463A9
-:1052B00025AE5B9DC6F890C1718B642937E0FE1A5C
-:1052C00012E03183D101C23F8EE999E1A697751DA5
-:1052D000E03E21C0F50D69554ED2056F9DCC749608
-:1052E00059F87EEB05C961E601695F7F9F0327E3FB
-:1052F000DFFAE38DED075C707E5188C408CE79300B
-:105300000FE17C27BC3CA71B86EEEF6483DA28FB09
-:1053100000DE6BB0DA0FF8CEFF7E8B04A96CFAE5E5
-:1053200083B65C00B54BA1F9DFCD787026E2E1824F
-:105330006A88B2F508378DC17940987D9CCFFAD93B
-:105340001D68945DF81D6A3E037875DA3175C79F54
-:10535000777EFBA1DA7D20241F11187E5B63623506
-:10536000C2A596401AD7C0BF7B59F778181ADED667
-:10537000D85F06DE21D7CDAEF74EB8A90D58BB6673
-:105380009F71506774D252201A4D300887432FCE38
-:10539000BA38781CEDBAFC6680BEB65E01A467829E
-:1053A0002ECDFCF3E9EA20D2D5C57F7DBA7AE36F32
-:1053B00097AE4E0A057FBB74A5D44BFAEBCCCE2832
-:1053C000924D2E27B5D516AD3F8ECDE492D439B38C
-:1053D0001BE525C4997DC68701919515CDE47A2FEB
-:1053E0001880FAAB5AE29593BE42AF9C8CAF34BBA7
-:1053F0009D7E37EB38AE42E3A27984E3CA61E80EC2
-:1054000044B1AC503F48CEE7A6303CC18335C5BC63
-:105410009D81ED869A8F8CEDD878A87E9C2BC276E4
-:105420007F9F93C862F70ECEDF3B4E7C452227114B
-:10543000197D7D08CBFA1B2EBC0FDD4E86371CBCB8
-:1054400030FA2F453F49C120FECDDDB791FF220044
-:10545000A241765D619B855FDBF1FFCDC77D9FF348
-:10546000757BE12C0DF52D60FB0DBEB784CF039647
-:105470003F1074E25B673C299C00A21BBBDE48EB3B
-:105480007F27F25316FE5E25727DE3BD2FA5FE1B1E
-:10549000ED416BB3A03FC6F07AB8E17D788DF1E5C0
-:1054A000EAEE0B15F47B5C2F8EA17AAB1714298BD7
-:1054B0005CFDAC066E1702F4C9CB22EE711BB91E5F
-:1054C000DA25EDC379BF5A21A571FF7BB5E27F488C
-:1054D0003F7FD594D288E4573BAECE194EEE1C6E7A
-:1054E000E0F6AC53EFB029D1FE7E58EE0B67D3E364
-:1054F00007C74FD3F8575548DE7D5AEE9371FDDF4D
-:10550000FB22F8507F3EDCA00AAF4D65C62FCE933C
-:10551000D1D1EA8A2205FD0E23CD6B89ED0773F008
-:10552000EBCCB3252CD23C5BC255E4B76AD1DE216B
-:10553000FBF10C7B8FF26028781DBF558BB63C2B9E
-:105540003E9408D7B7145F32BBBD69CFD72967FA3D
-:10555000B31CF8DAC2DC2E6A0B73B8DA62621AF98D
-:10556000BF2D9E7D5CE7D96CC3E7D46B8971BDB458
-:1055700085C993D1C02387BDF030B41D457FC94490
-:105580005BD6E4D7F6367E0EEDEC64D8940C7CD373
-:105590002B4C62E5097109366B6CDC9AAA8E6AC6DF
-:1055A0000279AB122F3230602C7456A21F70F217A2
-:1055B00037F67C8DCD6BC27CBF86EDF26A523DCF53
-:1055C000B176E399989358BBB1C7D7AD4339FB4F38
-:1055D0006827A220B66E6A443F560B0E7109C0C3FD
-:1055E000E2AA4AF4B3C9C0E502937ABA3C06FD3395
-:1055F00040CE99A1E403FB13CEF907DB0D85B788F4
-:105600002DAF68DE24AF960F2FAF36F2FE2DF61FBA
-:10561000CA9B0983E351FB71758A078F6333BE1FF1
-:10562000B0E9D20FCBFEAAE38C87E501D44F222B41
-:10563000442D8DF5A12B17FD5063D6CAD08DDFCB3D
-:105640003B1B99F81811EF4CEED570BF715258E61C
-:1056500082F79722F7334DBAEB9820A0DFD7602A64
-:10566000FD4C2CD7CFCC46A7DB6DFA1C28D7AC1647
-:1056700092345E62C954946BB522D9BDFFB46256B0
-:10568000AEBBFDFBF63883EB0FBA3C17CB7CFDE5D8
-:1056900015A21998F1A7AFBFFC21D73F7FA3E2D98C
-:1056A0004F3FECBAC8687B148CBCFE7FEE38CEBA94
-:1056B0009DCF1F5C3E4EBAAB3A80F2EFBEC4F07293
-:1056C000E5FC755B4EEB36660598E92C72252009E2
-:1056D0009E7DD579AA900283ADB3744C22F9268DB4
-:1056E0009DBB72270C3DAE145332EC37BB3FCBDC75
-:1056F0005FC2D6FF13E0FCF5CA28876A510EA15C91
-:105700002AF7BDEEF68F308C0F9619EEDFFAC2FE47
-:1057100003288F2C268FD07F9AF9BD16CB2E7AB80E
-:1057200042E2FBEFBEEFFEE202818D73C4F0EB7E3E
-:10573000F6EA90D0FB06F97D2B25DA8F113E752E07
-:10574000B607524E8E989259CDEAF7960BB48FFA5F
-:10575000E1A5EBFE91DA8728DED1BBE0B52F5FCA69
-:10576000DA7FE2321F720EC704B68FB37FA25E7378
-:10577000B6EFCB97B2FA872ECB1F56DFAAC5F9BA80
-:10578000E8E4AA67BDE555486F08FF7FBC59FB20D8
-:105790001BEF08E424FCF8ACE0F01D41F890EEFBB0
-:1057A0007EF506EA85874D81FC51472A7E16437BAC
-:1057B000BCD214485F5CBA4048FBB3CC73E982DBCF
-:1057C000264F62FD258C901660DF0F55BEBDF55249
-:1057D00006EF553F90B6E1F3F45EA920593634BC8C
-:1057E000CEFBAB4CEFFB01BD189216E21D341E97A9
-:1057F000F0C58CB89B5E07F418396166F3B7AD95B8
-:10580000B8FF51D00CD2EFE4B002388FA1EADF34F8
-:1058100004FDE6407FB7847038FAF7D9AB75B73C22
-:1058200074E050E44412C791340576A19E917B8DBB
-:10583000EE9E7F83C4E34242DC2478148DC3A3C868
-:105840008699CDDF546FC3E3F403D069B7EF87BE09
-:10585000F0207CAD81C44AF45B58B9DC7FD812F1EA
-:10586000FA03F7D8FD3CE6F4E783AC71158026EA2D
-:10587000BF6A4C858AFD3757703D490783FCE32D8D
-:10588000CC6E8461F4BAADB6BCD88CF10D3FC6398C
-:10589000343BCE11E7FA53F819F2939D2913C9AEA0
-:1058A00019AA9F88E1D54742A55E3BC6D15F027A1F
-:1058B0005E861FC8EBF7F18D914547EF437A1D09CE
-:1058C000FE013DCFAED72EA7542D2B9ED2C3EA7337
-:1058D0007F3DFCF1F6215F97960DAEBF14DE1CBA3A
-:1058E000CAEC5FC95752698ADB25E21E7DC09693D8
-:1058F0004ABE9AC27D01D4A1BE0779FB30FB8EF16E
-:105900008C7042477F8A043C2EA4221FB8F0F3B665
-:10591000DDEED3B268EBF3298A830A7A8AFC766AD1
-:1059200021E31FE1FC76CEB3CF6EDFFE87DB5F2184
-:10593000FE2850893F049DF14F96719A24F394C438
-:105940009EB74AE65BF8F4FD514A66E393FFB2E581
-:105950008A5A9BD0D5628A2B923D92094740E6FD38
-:10596000DEE4C06FA5284E395AF8DF1F25FCCE387B
-:105970000C7E592E20F87DF81C0A7EC986270FF46C
-:105980004619E59ACEE52BC032DDAD97DC28737958
-:105990009167CB2780DBE26E7BEB7ABB9FD1CE2772
-:1059A0004F1EDD7C9C71D97C26C97C3D26CBC3ACC7
-:1059B000C7441B8E1B65BEDFA9D5093DCED6257712
-:1059C00008BA5A60C39192455BAFB8ED43D1D5C5D3
-:1059D000A39CC782C1759967AF4BC570F3986BCF15
-:1059E000A35382F9AFA35E3CC5F1F72CF7ACCB1DF6
-:1059F000367E3AFDCEBA6CF0ACCB2DF6BC463B9F62
-:105A0000C5767F23CDE78EC1755966CF67F970F3F0
-:105A100071D5BFD6AEBFD2AE4F76C71D726913DA4D
-:105A2000194D5262955C30381EABF71977BDB79BA4
-:105A3000CF34DAF56EC0F7420DDFFF58BDD5EE7AF0
-:105A400060459BD03FD08AB602B3634A5A2EA9B2B2
-:105A5000DBD551BBDA81FE6FB6F983DA055A8426AD
-:105A60002B4CF5D661BDC6457F74EADDEA85F76249
-:105A700007DE0D046FF5001CB7BBEB2D9027507FA0
-:105A8000E7C51D46E90FF2C5921D18E7CF834827E9
-:105A9000E679B4C9A947300FC0B264780CF309FCA9
-:105AA00086803EB66845EA1B582FD762F635AE5B56
-:105AB00055EA292C5B22249ACB299F80F205EA65BE
-:105AC00055F31B987F61C00E56D662721AEDF356DD
-:105AD0002169E1BEF85329F96599E4ABB6AA11FB37
-:105AE000CFD7B99E0E7DB46F3970DD13BA8EF21F19
-:105AF00072195CE88F6ACD80EBFED0A41EDC6FEFDC
-:105B00002D50484F66065629CA973BA5A081FDF542
-:105B1000147C9EE0DDDEC8F31BB67FE2F304EF7D6C
-:105B20000250DCF63E1FCF6FB8C7A76A4D1AF617B2
-:105B30001DF759CA87C8D1FCE5361C08DFDF1513ED
-:105B40007CF9A055DE2890F8EA41FBB6B542217DEC
-:105B5000797B6C5625F557A1929E7A5F625623E9B0
-:105B60001D1541F2D1E7870DB25BA3F314B0B01C51
-:105B7000331A51CF8CCC0D620E0CE417022617405D
-:105B8000641AA4B1EC83CECE12F68C7630BB249F7F
-:105B9000EC26B811EDDE0A8677B4232CF328DA253B
-:105BA00061B0FFA44326CEDB374102F47B38EB1B08
-:105BB000ED1C683FACDD154D8FB25EF7E8EA453A63
-:105BC00098DD3F7B14F53A47592F3DCA7ADDBCDE9C
-:105BD00088FE0E83DB7B2AFB0FEDB640A6DD1CF6AC
-:105BE000DAC3BE8CEF99F1B8CC67663CE4A4EC8DC7
-:105BF000878CD4DE89838C345F744A0CC0298D5C19
-:105C0000DFD13787FAAE8CBF266EB2F6ADE33E1D0C
-:105C100027B9366E157F4EB4DF4F5C69973F6D979D
-:105C200057AD34B3C8F7B13E2E874BD11F329CDF3E
-:105C300001B8FEF80683FD9C80C94BC3FB4F32F5CB
-:105C4000DE4C79A7CA5615F2EBF604F76BFA9119F8
-:105C5000910F0B81FCB03E487596A09C0033BA783A
-:105C6000CC20FFF8CC174CE4E7C3E324102A687D6E
-:105C70000CF2A767D049265DF833FC397F2E9D7C56
-:105C8000CCE78DC7FEA5E844E99046C53F4AE72822
-:105C9000EBA54759AF7B74F5FC1DC2E8EA758EB2DF
-:105CA0005E7A94F5BA79BDB6F90ADFCFE17B4D662D
-:105CB0000983FB12D5536EBB24E8FD7E69D8536E71
-:105CC0009FA3D0FEEF94FD73554FB99DC979CFF7CF
-:105CD00079612A6F6AEDAE625BD9A8F9E43FFF44AF
-:105CE0003E295547F04B578819765B065FA97A0025
-:105CF000DBE7CB3A60FE547E8CEF53EC69A6B3E051
-:105D0000F7119BFF77C93C7F73BBAC07D07EFC5B70
-:105D10009F67A38FC3EBCC7724781DF9FBA664EBB8
-:105D20005B43E57D54F3BC4C1982949759526D56F0
-:105D3000994C2EC92FF2385866BFD729C9A77D2E96
-:105D40007B58D6923CBE67F7B7A44026BD44667226
-:105D50000DF51E05123545144714C9DF278747D8AE
-:105D6000370A5D72AB7818B8ED3C56FAA40354FEBE
-:105D7000968F1B3480E46B04FAC898CE41AD670A55
-:105D8000EA69BA00D4DE10B8FF7C8186FB5E2CF095
-:105D900097EE7715F52B98F7C0B9D087E857EE2323
-:105DA0007FE75FBCDF11E00D607EEFC5144288B96C
-:105DB000F37B7DF114BD84B3E7CE49738137A1BF76
-:105DC00024C5D765D1207F288C8F925DD61ADBA0A1
-:105DD000BAD7F5FF7CC51EBF89A2B5DD2644D9B36D
-:105DE00070ADD9370C9D9FC3600CFA470A6F34FB26
-:105DF00086D94F07E29918AFCFC2076D4A328DFAA4
-:105E0000BB3529CCED7939457EC676216FD6E67251
-:105E100017FD162ADD0857A4DCB4D0DE6BCF170DB2
-:105E2000D45365D8DA2BCC60EDA45A2399458F184A
-:105E30006C2F9F74CF27A678F5A9E611E8BD7504ED
-:105E4000BDC7A718C96CFED0690AB76B7DC1ECDF6E
-:105E5000EF12AB4A9439E7E38DA9F9DCBECD850E8C
-:105E6000E1639C7C28DFA1F08557100FAD0557C476
-:105E7000879B2F68DEBCCB9B4473A6323C1C73B25D
-:105E8000C131DA7C10ADDA203A1CD097629CAE5159
-:105E90004F12C660BE07FFDB56BEAB1BF3407C371C
-:105EA000F0B8AC64EE06F4533B7A9364064F88B4C2
-:105EB0009E0BB8FE54CAF52193FD87F3882E185E19
-:105EC000AF9632CACB14AF3ED4DCB017303EEFC031
-:105ED000EFF8F132E7758958756D767C8CCE1EBE71
-:105EE0008FD10B4CC378948A4881CE068DCA5F6EE1
-:105EF0008853796B834ECF9686527A6EC1A6F39102
-:105F0000CF531D450C6F1DF147E39F6555EE43D9F7
-:105F100041FBFE758B504FDE3C50666620837B3321
-:105F200006BC991E71BB72D522B4DF3707C0F62BB1
-:105F30002C5A647ACAD7345762D9F6336C6EBB9E3A
-:105F4000EADF3711EC7310A6FA49D7BEF788E223CF
-:105F5000FEC6BD85B7379BB1BF806C97E1B645DE05
-:105F60003298084F40E5E5FDCA06EA9F44001BEF62
-:105F700027CAED7CBCA9DC8F0F65CB47C023F7EBAC
-:105F800083A273F9599647F92C8A61A0FB15EECBD1
-:105F9000B5E11E6D3F7292EF77C7B2EF97837C3306
-:105FA000C2BE66C331D2FA3374D87E88245838EE24
-:105FB000CF791CF1AF3DEE7DBE0F8717A5A2DFC2E2
-:105FC000F3230B94E4F791DE23665777112B476B8D
-:105FD000BB2D62DF518E7BAFA2D9F34E12FF3B780F
-:105FE00076F48EFFF279D7D11733290F2910E6FC0A
-:105FF000375A78FB50BF9A33D80F3C51356E387DF5
-:10600000AD2021A21236202FF26B82688C0D947382
-:10601000CD3C4F39A762BCA77EC428F67CF7691730
-:1060200079BEFFA9EBF4F38C79FCBBAD373AE51FE1
-:1060300067CE7394FD3AE59EBE4562295B87976BF8
-:1060400025D2EF5EAE7DEDBED9584E4814BF3DB3AC
-:10605000B2D9878C740CCCC81CF4872525DB9F6EC5
-:106060004E447CFE1CFFC9C67B09F73D269F8ED897
-:10607000E77F989C9888E79F8E5C366F22AEEB1185
-:106080001FE76FB03A493EFDCC071E79F0335BFE47
-:1060900018ED3B9AD10F794CE065A97DC7228BE2C0
-:1060A000835BDB3ECEF496AB390A6179AD90D51EA9
-:1060B00088F815C2C7074232E267F334ABF5D61849
-:1060C000E6BFE940FAAA1F12A497D5835529A2BEBC
-:1060D000C3E88FE2DC727F6136BDE367F67EEE8750
-:1060E000AB49DF5F5E9BEB4363DE5F33D3877ED4D8
-:1060F000AB6B2A7D60EBCB9A0B3E3121D0F9A91511
-:10610000B5FE5D88D715B2E9CB16D7BA3AE1F7EC00
-:106110005333190E11FE63F6B90780FE4277BC694E
-:10612000A69FDB3BF192E1ED05076EA7BCAC76E6DE
-:10613000F38807866D3A8F026A7FE1751177BF2178
-:10614000272E1CC17E5F5EF90F7C7F6674817EC541
-:10615000174F7CCE4771D915F91EFE5B5E2D79E095
-:106160004F2C0879CAD7D45E9D33ACFE91F467C832
-:1061700033CB3E8729921CDE7C5C20F99033A93F0B
-:106180008D799AF0B2045CFF73FCAF9790FF353ABB
-:10619000A15F477D017E13D21E73C9CF169B2E8748
-:1061A0001AFF393FD76BE5BC1A8A6FBF7742D071AF
-:1061B000BE425EFD349CAFAC984D386E4B9198C694
-:1061C000B8F79DC5DB555CEF4D251F4E0FF4C57824
-:1061D000BC5FB7B459C8FE43B54B9BFC1C41E6FB02
-:1061E000B57E1E6F69B5966B25B88C07B44A9C7F47
-:1061F000A010B29E3365F4BFD68F7EFB98053CBEDF
-:106200009E20BDBA445D4D79B8F2F8E1E3B59978C6
-:1062100093ED386066BD276D7A2CA9D845FDBE7711
-:10622000E1F0FD3A7879DF10A1D7D627B0BE0A6C2D
-:106230003E0CFF5B4A791E6E4BD9338467C9AC2490
-:106240007DD6A7A54CACB7A56C35D1652BAB93CF4C
-:1062500086CEADEEA2739A5BFEC0E3134FB61F6805
-:1062600046FD614BCFCD807995C1781A507E6C99EF
-:106270007E938A78D8B213A017E958EE22A75CC89B
-:10628000F687873448334B0A426526A05CC8D3F8AA
-:1062900099CA7DF12AC075DB520E06B2667E3AD5E8
-:1062A00088A19F2D711EFF0E969A354508F73891EB
-:1062B000C4800EC90E2CB7D4CA348F368DE303EDDB
-:1062C000AE734E7E17E6C19470BBAB04FDFBAC7F92
-:1062D000E58B7CDEFA8E12F2136DC97DD9447DD731
-:1062E000FA04185381EBB5A427C88C8EB0FF7A2D21
-:1062F000EBBA6F1593DFF2BBE2F7B2A60B48A79992
-:10630000F879CF0757E2BC5B668AB02B8BBEB1D75A
-:10631000CFE3756963F955C559C679CEAF7BF204F1
-:10632000F4F715827BA8FA83F564F2EBA3E1B1845C
-:10633000CDA3A086FB4B21E31C6B0C9264DF8E0582
-:10634000AB11F9D139BF3AA13AF1CB247B4A91156F
-:10635000944F37D4795627CF7375852D9041BFF66A
-:10636000D76CBE371FF401E2EDF2B38FBC80F95257
-:10637000BE0ABF46F955D0F902E66FDEC8D4312C0B
-:10638000DF7C7CBA82F93F2F8F97303706F9278A56
-:1063900074F81688947FF6161C8DCE76D1F9297B79
-:1063A000DF41C98A72A43997CF4B0EB7F54A515CC9
-:1063B00077D9EA73F2F74861E279ED1066EF55CAD2
-:1063C0003E6A24F9D7C1F3859CFCC8CF767AF3875F
-:1063D0003EB7C35BBE09968F41BEB989297469D6A1
-:1063E000EFCDEEBC2F36FE313FD70F3E07A936DC8E
-:1063F0007FDAEDFC9875DF9FAE205DDF3C5B2BC242
-:106400007318CE3C7EEFE776E849C6A7BA8BFFD774
-:10641000C4D2949F9C39BFB7F62CEA4EB2F26BBA45
-:106420009CE276B6779EEDBEDEA598EF656DF3D95A
-:106430007A8337CF71CDEE4A13F3C518F6F47C6F2B
-:106440007B82FF1F3ABCF31D091F99F377F4C1A1AA
-:10645000E6A3EC16B2E6FB85546FBE54B3CAE38DD7
-:1064600066B30C8185E79F8FB6AA5274BED96AF2D3
-:106470006BCD318A4F52FCAF9E110EC6F7CA559DA7
-:10648000FA792F30290D740E21350FF5A33FB7DFB0
-:10649000F92AE7C3BF74BF0B8780779DDAA7207FF7
-:1064A000AE973B6B84E2C1F301019F654E60F8F645
-:1064B000EF5DD63D013CF53A4659EF201E811E4561
-:1064C000BD1A7198FE4EDBFBD6BF3DF12F0AEEDF01
-:1064D0006F3D7E6229CAB95BFE550295D53BFD44EE
-:1064E00004BA69DF492B2897D7EC9168FD41EE9EED
-:1064F0007BB527DFBE99E67FCB5311DA1FD63CE38D
-:106500004FD7B2F66BBEF7DA0C607C7BBAA9FF8579
-:106510000988BFC7059EC760F5CDB89ABD5F23C384
-:10652000F5D9F2106E50395F9DFA416825EEEFC241
-:10653000EE9EEBA8DFAE6B7D7E97FC5DA9727B9A29
-:10654000D533F1BBF54D213D55E0F065CBCB3BF5A7
-:106550004DEE4759B3D797C63CC535BB772A495648
-:106560006FFDEEB789BE173DF56414F1B07EAFF74D
-:106570003CC22D4FFDA1ED92723AEFD45F8BF24FEA
-:106580003A4BE533A6DACFF3E0B93FE656E2585688
-:10659000EF3B6F5EF16BF6FD645C82001329277B95
-:1065A000FF53F9572C27C32926CA58FFBE57DD7C55
-:1065B000B87EF76B74EE481399027B299E87C8F862
-:1065C0009E519FE9B90ACAC3F55D9BDE4679B97E43
-:1065D000CF5BBF42BA5B0FF2AB6E7E3E89FF18778E
-:1065E0007E3C6B93EAF5D39D814373C901B03B3F79
-:1065F000ABBDE8C4B31CFEBEE5C9330FA31E71EAF0
-:1066000099FF7A18EF6758FBC7FF7918F35AE147EB
-:10661000010DE5D6FAC77F1E0517FE1FB5E5C3E9D4
-:106620006F7EE3EB0F303C9CFEA59FB076FAB93746
-:1066300027E13D1DA79FFEDF31A87F6C7C6EF158DE
-:10664000A4B38DDF5D3476B873A048B769BF7B7D96
-:10665000D3FC7E83BD026E8200CFDACF8C7581437E
-:10666000FD0AEABDEF0AD0BF3997BDEFFA8382FA7F
-:10667000CB0B26F4239EF6EF79ED85BB58F92DB6AA
-:106680004EFE2CEBC4E63F41A4FD8DB10F7BDEBA7C
-:10669000E7EAAB2E2BC7A7CFC0EED7433FED1BE7F2
-:1066A000ADEF31B6BEE583EB9BF9FD0C9C5510FFB9
-:1066B000EB9F60EB3903D795ADE78CF3D7F32DFC57
-:1066C000C7FCF3D773BFEAF5C79D81B58F3C801F28
-:1066D000F7E467B56F9DF55CF7DD4F0EAB973BF2C6
-:1066E00061243CD3F95E06D75754F3672AF2ED33A1
-:1066F000DFFAFA0331BECEB50C31A79F3C33090F48
-:106700006BFCD6D77F1DE2A1FF39BF867AD49AE70A
-:106710007E417C77FABB2FD1B91EF61715D87E774C
-:106720001A06FE8E022BDF2AF0C23ABDFF8A5FB145
-:106730007ED7B12E2C83D6EF8A5F95E3FAA9FDB4FC
-:106740001EE965353ACADF7401CDFBD634E78F5BAD
-:10675000D33D2BD09F9D89F748C0C9271C5C57F4B7
-:1067600097DEBAE7C415487F43ADA7337F0DE73FF7
-:106770008F7D7FD4CBBF43F2ABBDBEA777BEA7A0B2
-:106780007ED5FDAF8A26323BFFB4AF5F198FFBCDBC
-:10679000D39286E78D33D77D10FF4D59CF1D673ECD
-:1067A00033E9C31FC81EBF76F03412BF8F3CBF0F42
-:1067B00087BF33F63E9C89C75367B3EF075302DCAC
-:1067C0009EBB153A6B50C5CCDCCF7C90B226140D25
-:1067D000C2DBD625919C3FB59BFB6932E5C5AD4335
-:1067E000D867339D71F6F6CC40B9766ADF0F6CBA84
-:1067F000E4747FEB132714CBDE1FD22EFCAE1FC236
-:10680000DF7DA9DDDFFA67B3F7B7FE89B7B3F677A7
-:106810005236AF45F84FF6FA282FE9649794D5CE53
-:106820009D1AF079F4AEB6C8DC5772583B291AA409
-:10683000BCABE626F317E827B58EFA6C3F80F15B18
-:10684000CCB76A8E04E99C7B73F426BA2FC9E9AFF2
-:1068500025034F723C41F6931C4B94F31858DA63AE
-:10686000C7F81841B8E106D92A44BDFF70D19B3260
-:10687000F67B04F548975D7F4486D6FC723C172171
-:10688000188D90C5BF91D17F628104BADB4FD83D8E
-:106890004EFC3D6BEF3F26A511B5F590EAA67301BE
-:1068A00085D0F55896FE1E6AD0C97E2E4A5C4FFEF2
-:1068B0001F7F2A65A2BE56B8512B16F5A1C79D9819
-:1068C000F2C6AFC733CAFF3D8E73D047FA20EC7EC5
-:1068D000FCF1C7C7F02D05F5F217F0C9E4DFE57547
-:1068E0007A21961FB2E7CD7880CE314EB41232CAEB
-:1068F0003921B64C46FD62712A21AF76ADE7E298A8
-:10690000301EF7D3F410F7407D3FC0F7CFC6C66BFB
-:10691000288FFDC12F8A44D70F063E5E887C7620E3
-:10692000775E18FD6B3DEBE61E9AC6E09C10960064
-:106930004DCEFDE1E1CF6D3E6CFB1776D9F70F3DF3
-:106940006AE7977FDDC6DBEE86527A3EDE60D0F7DF
-:10695000271A2AA8DCD55043CF671A12F43E7A577B
-:106960003089F4B9A76125BD9F006F0BB8FEDF6BBE
-:106970004852F9D1402EC13FF96E1093ECFD62C42C
-:10698000477870DE0E3C69DBEEFE7EE0C72DC8174F
-:106990000378CCC0F7E5D02BA8E8BF8A093AAE7BD4
-:1069A0007D40E779AE19F89DE4EF17302E577F3719
-:1069B000CF877858F09E77B8DF96FFDFB1F9F4DD26
-:1069C00068F2C9007BBE53B3A294F421D0CA906E82
-:1069D0001E1612478C22C2B3E7DCC9FABCE4770268
-:1069E0002EFFF0A40E6ED7EF08D8F26D2388486F03
-:1069F0001353A023BD39F3DE57A917A25CDC270887
-:106A0000B4DE486FA52E7A1BA0DF809D971CCFBEF9
-:106A10008F0FD22FE7FFF825A5F754235E3688E4C1
-:106A20000769C64FAE761FD874C4EC16D1427AAE51
-:106A300013C99F3BF9F8096112834FD7BE15C07B7C
-:106A4000BBE293C0F637750590BE1EACE3FEC5AF42
-:106A50001DE7E798CE6C2C5E368DD55FCAF083C1FA
-:106A6000A8BC25251EBFA5737EE16B6A22471BC605
-:106A7000BF9599F776FFE42FBD9FC3C699703CA4DC
-:106A8000E379987B26FFA84761E5F17D02F993C67B
-:106A90008753D3703D2BFFDF37C7F5B9D6E181753A
-:106AA000A9C9A837B64DFEB6807C30FEEC8F05DC58
-:106AB000474AB4E49BB83E1364FB9CB09C9A87762B
-:106AC000C1F57989DFE1FB4461FA53484F676A36C3
-:106AD000FE1BF6EFC421EBEBF5DC692EF990799EF5
-:106AE000E2A1D4F0FE4C67FE0FE1FC87A9E7CCDF02
-:106AF00059BF3335B1B5281733F199D96FDE9215E7
-:106B0000C38EFF907D8F189BBF3FE8926B85A93E97
-:106B100019DB39ED878ABB66CE77C04F34CA386D32
-:106B2000970FF2912E9EFEBF49DF3902483A0909BC
-:106B3000FD53FB02C97108CF5C4851994947CA67A8
-:106B4000377239FF3E30E6EBE388EFE47411E57D00
-:106B50008C72BC5648242A719F334423DB3E303D5F
-:106B6000C8E97E01A4C83F2A86EE1E3ECE5FE88DAE
-:106B7000F36F059A0458DDAA1DFF0059437FD841E1
-:106B800098857EC8FC20E7F74A99DB97B30FEA3B6C
-:106B900025EEB79296455CF8B3FD763EDE3583FB75
-:106BA0006ED0743CF735B34770F1EB7BA1E4C220A3
-:106BB000ABAFC4B93FD2174BD279CBC55258247F63
-:106BC0006E2797FFF590502FE47119C079EB1017DD
-:106BD00071BF7F68233FDFAE6B2182FBA1984EE53A
-:106BE0007A5B4FF9B14D473FB0E5FEF76D7AF92E6C
-:106BF000CA7DA49B3EF3400E83EB3BB6FC7FDA9646
-:106C0000FF4FD9F27FCEB13EF86639C96303F39ED8
-:106C1000BFBC3DDE84D37CB2C1A47ABB1AEAE8B91A
-:106C20003F77ACB897D57B74A3B80BF9F9516DECED
-:106C30009578DF55DA140D81357EC8DABE28CAE0B2
-:106C4000DFA90A143F7BB82145ED76AA7A938AF131
-:106C500014662D5B4806F5BD14F6A8FC6DBF56C33F
-:106C6000EA7DAD33EF4A8CC3DD5B23533B878FF462
-:106C7000391BB03944F3FC4164ABBC826E750ADA4F
-:106C8000E91B45EAE72B81CFA88BD873E2C4A3EABE
-:106C9000C7755C8C13668A7D5FC4908CF3A8E8EBA3
-:106CA000B3B05CF27A98F2B5E7BED2074FB3725137
-:106CB0005D84CA132D2F5F4CDFD367753238269E53
-:106CC000E2DFABF37E6775B1FA391BA2D45FD5EB77
-:106CD0007D02D2B3AFDC7BFE6A87EF97FB236CFCAF
-:106CE000D8A1848078DB27688B3025C4FA143F7FD5
-:106CF00033F62054E1FB787409ADC3F66011D1CFAF
-:106D0000D75A8EC66F463C6D8CB5A099B37FE3060B
-:106D10003A9FE0DFB891EB4129EEFF9E78C701E191
-:106D2000732EF950D82267F5DB6D0FFA799C64E376
-:106D30008AC4340EDE8130EA7B25DC5F59D45AEDFB
-:106D4000C96B72E2231F08C9ED41B29B789C44D6FF
-:106D500052F4FE32097545F6FA4E91EB4989DE8010
-:106D6000DB0FA3DFC1EF67CB8463575026385AACE3
-:106D7000EA3A9417DBE6287200E19866DFCF62C733
-:106D80002107F63121B9CB2DD7648DC33591A132BE
-:106D9000847077F77EAA8BF5F37ECAD9C7CC20E939
-:106DA00049F788C41F5BCBF939C0FDC63BDD78CFFE
-:106DB00085C34FAD8648FCBB5D16D202EB677B797D
-:106DC00071EE85483F31DCBD69BE2AE2B944F6F177
-:106DD0001C0E30F7A15FDC8F7E71B6DE25C743271E
-:106DE00044F2FF79F3BF8B2CEFFA8BF5DE73771348
-:106DF00099D2E3CE57064634037446FB6BF5BEFFCB
-:106E0000407E5819223A03CB8C568EC1F445FB4F75
-:106E1000AAA5F3CF2519E70C1EB0EDF787ED738413
-:106E200070F63640B9F5807DFEFA81B5625067781C
-:106E300079DE3A4AFBE6C4FAEE4A0ACC687E4F7E17
-:106E4000B5FF6EAD09F7D7A294374FA832232FA80C
-:106E5000E4CFCCB33E1EF4DAA9FB4E060DBC0F2FD7
-:106E60007D4C32509FFDF25DB349FE596BB8DE9206
-:106E7000AECB7B00CFBBE40B60E07BA75FC77E7D22
-:106E80002798477C939ECFBEE730B912E95A5287C4
-:106E9000EB05395A530CCF43DF09DFC6FEEBF8FA96
-:106EA000571602DDAF5318033AE7CC9E9B2F40FEE6
-:106EB000DF28624C1CCEA19C4739AEF6BE88EF732A
-:106EC000AF14E9FE9CA216EB429CE7BE4BC68F476F
-:106ED000FAD81AE6E75E9A851468086F01E7879D7D
-:106EE000916ECA07DD562342135214C3A581FDAC2F
-:106EF0000EEEA23C1684770ED11DE95D18A3407EEC
-:106F0000B46E08F27DE7AC7521FA95A3A1BEAEFD83
-:106F1000AC9F70BB62EC62FDECACF4DE533735C461
-:106F2000F7BB404870E2FB81107B9A5B81F216D977
-:106F30005C88BF195F5940FB8246769513DF8FEE60
-:106F40005B22164DE7CF6217FFEEB2E56CDACE5B3F
-:106F500078D8DE3F1C7DE301DB6ED86AEF1B45E687
-:106F6000554D0AD26D1DCC443C95ACED125667B31D
-:106F7000EF3BBC7235935F2667F24BCA7B4E75427E
-:106F80005DB1E77BC4B8C8F39D4231B8EE6CFF46F3
-:106F90003CB707CA24D4FB6643C274CB95A1F6FF65
-:106FA000FCA03923F421F49F68289142FD3353FF5C
-:106FB000BED45E97EB0289F9B81ED14B56521ECF54
-:106FC000BA40E252EA5F4E0B284F1760BB58567822
-:106FD00029F96B14F0567F18784136E83CD79D921A
-:106FE000739FADF73C1764DC5F9B793FEDC2FFBB3D
-:106FF0009BEEA76D1598A287E51CFB7E5A3FBF9FAD
-:10700000B635C2EDAE563B8FEA561B0FD787F87DDB
-:10701000AF6B6D3A5D18CA7EFF91E3F74AA16CC071
-:107020007A63B3DF3B861A15F6B77042F6EFA91004
-:107030008F3B2E9C3CFC381B701CD6CFDCA0B92E9D
-:10704000E4F2AFCC0E99EBDDE5DB43767E919C203C
-:10705000BDD294F97E5814343786E6B8F06B3FF30E
-:107060009694D379BE33F6793ED66E87407895B440
-:10707000D1E0DDD1FF5B05FD1E92833F677A5F960D
-:10708000F5782F18B5C49CC17894A31FED0E717BC1
-:1070900092D1DB263E8F34E5418741BF07EF8198CF
-:1070A00080F770EBE85738FEF0BFA0BCBDACB70668
-:1070B000F5A7753F94E87EBBF3F0B596D19D2B1FE5
-:1070C000C5793FFEFD0964074F9692F7875CF6F19C
-:1070D000F8BA7E05E91DE1AFE6F0F3FC69217D21F8
-:1070E000B70780E238AD37C73DF98499F6481EDE10
-:1070F0007340724521BD2E132EC79E70CA99E711A9
-:107100000EDB74847FFA18BC271CB8322B9B12F25A
-:10711000D71C48D2731EE8F464764B17CE83F19FD8
-:107120008E703685265D8AF3F82BE2ED47A1397F14
-:107130007B7873E8B82879F9001D67BBFFFAFE5029
-:1071400094E46DFDF108E9FDD17D5F20BA96185DEC
-:10715000076283F932F560E7D187A10BF5DEA264FF
-:10716000039D0B3DC3E818FB95347E8E55062D819B
-:10717000711B29C6F9C327976AA2867159CB8F79EB
-:1071800007563118286BD11FE986B73C9C7CD38DFC
-:10719000C73B8FDF43F2F6BA40F224AEE79D259657
-:1071A0001F353B971C3EE596C3028475E4BF856797
-:1071B000F97E5999D465A487458CD311EF8B214969
-:1071C000E58F8345CF2590A6E7DFE19546A4C7D993
-:1071D000E716BAAF15DDE71606F2B9CB9D7C0E1E99
-:1071E000A72AB0E9106C3BF5F995CB1B17B3F1D981
-:1071F000E29B188FFAEA4A9ECFE39F27D3F9D58204
-:10720000BE1B6A314E042BB85EE6E441E4D57AF544
-:10721000B4F3EEB73AFEBBE3D82EF39C9CA3AF6564
-:10722000EE5BCE33535FCB0B673F3F39D4BE931930
-:1072300057A8C77F72FBD5B6AB1339EE7BE3339FFC
-:10724000871BFA5B0EB8F2CC8FE0FD4659F7011EA2
-:10725000EF8DEEFB5DED8A72BA5FCEC094C9DE861B
-:10726000EE85AF4F1DB483130B729F477F74A23A14
-:107270007796C4F0BE34FE6ECB817C806566CFC24B
-:10728000D75DF3ECD518B459F48481F14CDF07EEE7
-:10729000FDF72D85CB97567BBC881D1F6B172D3FA7
-:1072A000F1ABED7FFB7D21B7D31DFB3EDB7C5B08A3
-:1072B0005F7D61A487A1E6FB0F61BE9F8E5969D0F7
-:1072C0007DF9CDF67DF9CD139DFC2D43437DF2A6CE
-:1072D000702EBFAF205C42F1D5E69EF9E44F2E3808
-:1072E000E4237FFA981549C172ED8BF73670FFEBF6
-:1072F00057987E87F9205B985E87E57D957355B436
-:10730000176E8FCCA278EDE606C3932FE23CF13ED8
-:10731000BAA4CBBFD79CA8D230DEDB523B4B45BBD7
-:1073200043FA443995E50B677556317EFECCD61984
-:107330005714605CA28CDF47763D2B3796303B3A82
-:10734000CCF7D9C3C6EB61C453555877E887D6D17B
-:10735000B72269FA502EC4B52ACC9571DE834D5FF1
-:10736000EC3DE9D76F29C99BC36CFE87ED7BB1DA91
-:107370009554E986323C17CF040EFA8955EE27441E
-:107380003A68993D08F7061BBF97D8E33281243E3F
-:10739000ED5A3F25CED7AF5D84BA6CEB737798EB8F
-:1073A000372D9AA90D4B479AFC81E7FED0F218CFF2
-:1073B000CF8F313A72F1F3F9F4CEF9A93C9C680908
-:1073C00017A05C84D214CD3F4CF287DA4983F7587A
-:1073D000C6C36607D63B9A6BEB2F853C0F9ABDDF81
-:1073E0009243F34B917C77F4C17699EB73A3D50765
-:1073F000F3966C247DF01DC65A649F7D6223C9ED0F
-:107400008D3E95EEFFDBB740A67856740A5CEFB66A
-:107410005BA4887DFF7F84FBE5F17712D2D3B8DED1
-:1074200083E73CA221A0732EFD13797E693BECAC6F
-:107430009942F04DD5DCFB59E544EE67D85615ACC2
-:1074400073FB1B16E6F278D98BB995BFC3F9978504
-:10745000D355C89A176BD087F93450C5CF8F09859B
-:10746000FC9C8D0F0C95F36BB586F7860A90A4F300
-:107470006743AE1F78EF177D5C4E3705116F31EE15
-:10748000D789EC1028694FEA32BBF1EC4E7BEEF263
-:107490001F223D32B967207FF7CC0D92BDF76E8F6A
-:1074A00042F6E7BB37C3AFD19FF4AE2F072CB654DB
-:1074B0003F12C55F3FC5E6DBCF987517E67F69FCD5
-:1074C000FBCCAD02F99B7EF4417002D2BB110511D9
-:1074D0007FCF6229D32778922084303E1B5D04DD64
-:1074E0009763FB9E30E1CF17FFC9C2D767D3FE1366
-:1074F000122BF0BC96F820CEFF9938E461FBD9FF3F
-:107500005B25A1FFCAD187BEAA258F22DEE6815561
-:10751000D7C3DA6F53387F6DCB53D218A79C552051
-:10752000921E02BE507A2AFBBEF4E0EBD598DFB97A
-:10753000B46226D6C4F169BD4BB4E4719C77B5B68C
-:10754000AC3A97D52F3FA693FCBD227EDB012CCF12
-:107550003DCECB3E3FD7E3518F719F0F58FAFE24AB
-:107560009AD79B61AECFB6C4CD5E531896AF32EEBC
-:10757000E5F59E2F70E8806DEB3AE6A5D3BF75A2C6
-:107580008BA44F1CF43F4185619F3F71E8C1143EBD
-:107590000C3DEC09F37DA11DF3CD6283F966EDB6D8
-:1075A000FE36DA7CB34C7ECA5B22D33ABCC3F42DE0
-:1075B000BCCFE37C3EB98DEEFFCCE42707CECDE512
-:1075C000793194C30EDF68F3EE26B9ECBF41A1FB1D
-:1075D0004C1D3E72F8E7D29C013EBA0FE5C58AB059
-:1075E000BE98A76898E0E693AB47E0ABA5D07F20B4
-:1075F000C6CA4B65B07298083A3CFFB725935C7CCD
-:107600009289CFA50B0478D5230779D9856F6DE0D2
-:107610001EE02C76F250EB7254E6E71E1C3EC5DFEE
-:1076200063C1F3631DA201B81FB5E7AE36226CDD5E
-:10763000E4DADCB5C80F5B84440AF92132EF54E880
-:107640002686F777C7302D12FD87FAEAA788DF5F15
-:1076500009915DB66DEE1A8A4BBD7B737232EE2FC7
-:107660009B18DE5FA5FD3C3D56A45CDBBEB13C6FC4
-:10767000428FF36732CEDF83FD3D6D974DBB5E1FBA
-:10768000D563EBEB919B3F8D723EF86994EF539B72
-:10769000944E15E9A1BF48D5B2E52BA722BCFEE563
-:1076A0007E28C7FB18D968941FD0AA4A353BC95910
-:1076B000C2E5C4E5534A77B9CF5739EDEE6DE822FC
-:1076C000BD6653C35E7AE6D7A601F3E882A5968E1F
-:1076D000FA87FAC74502EEC770118FCBE3FB4697D6
-:1076E0005EF7695BBEAB785F101B4F6DB274F7FD40
-:1076F000B4AA2864BD47E84894FB89D526A0EFEAE0
-:10770000BE7FA6FC85FC1243F82C969B3AE9F765F0
-:1077100002DDFC7DACC4146E74F51BABEDF2ECA382
-:10772000AAD82793DD540F9A8546A0DC578DFEB961
-:107730008EE5C14ECC6BCEA437FC7BD54537EA1F16
-:10774000AF26FD098E72FDB5BA58253A6FAD577652
-:10775000A2FFEFF7B12ACA67EF88089EFC02E7890B
-:10776000F177A611923FCDF2F338BC358DC7E1B168
-:107770008C71787C621C1E9F1887C7EF1887C7F230
-:10778000B71B4C2A633C1ECB188FC732C6E1B18CA5
-:10779000F1777CEE6DA8A3E70F1B52F4FDD9867A32
-:1077A0002A5F6ECB5728E5BF07D6F105C5C4FCA9F3
-:1077B0006E7B7DF69BCBEB7E86FE42881AB8AF07C8
-:1077C0000E35BDF2EF7699EEC98E17E7A3FF126270
-:1077D0002260DCA12DBE9DE9A283F30BC8F7824E87
-:1077E0007177AB0EF31EBFB1ADF70A99E91F25F112
-:1077F000DBAAF258F9C96D2FB7619EE9057AE3CA91
-:107800009DAEB21E99B5E6696DB03CB96CA71C641B
-:10781000DF9F89FCB20DE54520C6F5C367B7FD9A29
-:10782000F4C3EE62A600A1BC2B52D248EF37E23A75
-:107830004DC579F07CEEBF83E638E6F94DD6955913
-:10784000C8A7AC7E37E78F51D6C760CD9CF3DB0D60
-:10785000574F2C1F553D3AA73B643DF65D18A69F38
-:107860005668D67A19EC5B7C7C1FB60AB89FB8C301
-:10787000C7E54347803FA7E438F90D55CDD102CC89
-:10788000FBE17CDC11E0F713F44F17E9777BA05E96
-:10789000F87BECE7F3E341C3FCC859D38BF3D14E3B
-:1078A000F8854D0F532747F8FEFE8F2AEDEF1F9FF7
-:1078B000FC644B1E2B4FFD17C3C0FD7A0B1841947F
-:1078C00027D6562E4FBE553E256F19AB7EF19CEF45
-:1078D000E6A17E3CCF964F69DB8E696CBD6932DADA
-:1078E00011EFBEC4E5E31BB67CD9E9EB4DD17ACEEE
-:1078F00009D3790B804ED25F1AE332E58989E3F828
-:1079000053F1699FA6FB335B15BAAF49F9C33C95A8
-:10791000FCAEEFFBEDFB8A7B49AF5102492D97BDD1
-:10792000EFB444F253346BC134DE9BB5253C8B7EFF
-:10793000BFC12A93296EB6A58CC77F42916BE85EC2
-:10794000ACAFF404A87E6B58A57CE174D99E835536
-:10795000317C8A1AEA07697339DD636969A246795D
-:10796000C7EC5FF47D6D8CFC4174FE18BFAFE5F190
-:107970000ADFD843546EFEA446FD839DDF4F2A9A4A
-:1079800088BF2791E8F1DE4BDBFF938FA1BF640D29
-:107990003FBF32435BDEF31CFBDE62AA8962C60F87
-:1079A000ADDA3BFB42585E05144F0D4D7FBD298477
-:1079B000F56FD40C9EAFC5CF4B807D0F724BD98A2B
-:1079C0009EFFC0FE578660AA81F5AB55E4576881DB
-:1079D00017F0DEAA428288BDCF9D25A0DED65A4B85
-:1079E000D77332F8BCE70C5AF2AE54916EA4A57965
-:1079F000344E2B982AD6B76A65DA3F0BC36A37FA3A
-:107A0000170A6DFF84230FF253AEF306EC7FE3D722
-:107A1000CA9EF308636FF4960B32EEE12DB7E927A7
-:107A2000136F99F3CC8F3D938BF0E4AFA59313E7DD
-:107A3000C17F6F6CD6329CD7386D9FB0B39C4C1F02
-:107A40004DC77BC821D5E8CED7F873E19D51D6D27A
-:107A50008BF4304397416778F918F43761FF5B6C1A
-:107A6000FAEF28F2EEE3BFB0ED1FC6A76BA37330A9
-:107A7000EE2182E5EA1FE322960B9E291D799EF2F4
-:107A8000D4CEF19EFAD376147BBE5F98BEC8F3FDC8
-:107A9000E2DDB33CE5E95D9778EA7F6C6F95A73C42
-:107AA000B3FB4A4FFDD907977BCA737A3FEDA93FD5
-:107AB000EF95D59EEFF3FBD678BE5FFADB0D9EF215
-:107AC00065FD7779EA3BFA7FE6BE795394CBA30F45
-:107AD000ABF7E3EF03B9CF1D67DA15E7DDAFF3C707
-:107AE000661DE38410E5F7E9CAB8BFB3F2862F70CC
-:107AF000FB4C5D68E8286F5645B97C5D9F67DE8E5C
-:107B0000F2B532AAD23E2187793D397C05E923932B
-:107B1000763039359BECB681EF18AFEE68B016962B
-:107B2000B8FC5A01AD13304FAC325A43F70A3AED64
-:107B300065CD04CC9F5B15D5B91EC4AC5EBA2F4091
-:107B400067ED5DF36276225D31D1CFEC48D4FF075B
-:107B5000EC443987E2C3CC4E243BD20872BB11CE31
-:107B60004AF4DDF88A40F7F8333B90ECC867C2CCA2
-:107B70008E9C89765BDF169443FD3F9529DEC8FE17
-:107B8000C84E2C6776E2E65CB7BFBCAF089F69D0F1
-:107B9000C6E3B347E916C71691DDF8CF48CF9FD9A2
-:107BA000F8521DF63BBD9CDFBFD731A6368EFA7466
-:107BB000475117F1497F91CCF7213951EAF6031E5D
-:107BC000B0F7AB90FA2DB257D93A905C76D6618B6C
-:107BD000D097C67B0EAD2F04C92F3EE937FEA3C850
-:107BE0006F6AB13A01F3048DFD8A89E3DD6BE3B975
-:107BF000589B59853F0759125FB60F9F17E84C1FD6
-:107C000061CFD2D27BF6E1F37B51327AE122E3E914
-:107C10002A9431EA42EEDF966728E92601FDD20C6C
-:107C20008E2CF689F394A23BF8BD4025F21B487FC9
-:107C3000681D9C6353A8CC5329BE1C40BA10E84968
-:107C4000F4149043B4BF04F0B02A962B843486C455
-:107C5000507FC5BCD1CABC1D44078E5E8BFA6E92A4
-:107C6000DBD10790DE62B5DEF50FA9DF263CB5D883
-:107C7000E7A23B72F543556CDC8E82E23CF4EDA248
-:107C8000DF65994BFE1CB4F7DD477344474F20F97D
-:107C9000B30073190A06F522C60F3BC429086F8288
-:107CA000E2F0814312D9FD81BB3BE97758039AA5E5
-:107CB00003E9FF968EFD5617AF243FE1FFC466919E
-:107CC0001E1CA8FF5156BC05FA2430670F8DCFE863
-:107CD000050F903E0063823AEEB3F5B1A0B9338B45
-:107CE0007D5017B1ED9F498EDF3341E7625BD12FA5
-:107CF00017C6AD4D15319FE7F69F1678EC9ADB0B52
-:107D0000B81F73A8F103CC1E4DBAE0DBC4FA4539A5
-:107D1000DE7A76590DDDBB8ADB4C399E1B2DDB49A3
-:107D2000FEFCB3CD3AE67DD5D9784D61320FC3DF85
-:107D3000240516ED447992C7F42386D24ADBFFE28C
-:107D4000F86926E6F0F8BF6181C4FD773E67DF126F
-:107D5000CFE17D353AE8CA5CFB2A005281F9BEC604
-:107D6000FEAF07CF0F4EE970ED7380FB81B73C6D1E
-:107D700087B77C61DA5B665AF4CBA807AC00E0FEFB
-:107D80008FDDDEEF61307D186F19EFDCB39FE0E728
-:107D900009550601D2775957BAE76B6C7E09E73E61
-:107DA000CC8C7BF5A7EF4993FE7295FDBB1F99F72D
-:107DB000BD8FC7DF019941F3F2ECA3B37C12F92523
-:107DC000D09F64B8FC49259AEEB1AB1CBF50A65CAD
-:107DD0000F1EBF07D817B2EB937EBC37552B43FF5E
-:107DE000435BE1977E73A27CD00FD326A7DE3C4194
-:107DF0007E4EA67FC5B89F04FDD7B7FFF48EFF3E29
-:107E0000E1F267BE1B4DCE46BFC7FD93797BE75EAF
-:107E100055E7DCDF3B35F2F382CEE148BAE0B8B398
-:107E2000D4FA385757D2E3D08FE4F8611C7FC3F5FA
-:107E30007926E9E75B8CA3A9FDACDFAA5FFA01FB19
-:107E4000592C1D3AD880F26EA24C7925DABCB58F38
-:107E500004D1EF89DF59B9AA481F4BFCF1A28FFC6E
-:107E60000EED36DF3BE7571DBF4D2287F347AD6D63
-:107E70000FB09906ED731B41D4932FDECDD6D0B34E
-:107E80001F72BFA1E31F9CDEE5FD7E111E0527FFCB
-:107E9000E84ECA8332E6F33CA8312BD3FB709D3FFA
-:107EA00066AF33C6B72AE70EC659C7AE4AEF433DA1
-:107EB00074869DCF54F6E2F3F493BF20154A485FD1
-:107EC00017611E136B671C903DE746C68040F94062
-:107ED000638E49469AF533E359EFF73270958B106C
-:107EE0003E6F39337EC5D4ADB76F10F0F7535302F0
-:107EF000CAB3ADAB988DC0CAEB72EC3CA40BE002E8
-:107F0000A4DBC552D8C0FBF536FC5CA23C64FF89FB
-:107F100069BFC0382ABCC4F32EB5293C2EABFD4442
-:107F2000329804042D0433678607E35D5F3D67E004
-:107F30005DFB037EB4C7D9BAE33EF404B3FB4B7CCC
-:107F400068C76B54EE62763F969F61763F3EF7308E
-:107F5000BB1FDF7F8FD9FD58DECBEC7E7CFE90D936
-:107F6000FDF8FE5966F763F9C5DCCA2D397330BEDA
-:107F7000554AF4149CB987F21EDB559F86F4932969
-:107F8000CF2A2B6F575730FC6E0E2FA6784BD56239
-:107F90009E77BF256731D9D303FEBC0C7FE8A07F55
-:107FA000AF4F70FC7B78043A6EDBB3037ED2A44102
-:107FB000F71B8CDC8FE9F4437ED6F3FAB1FDAD6F8D
-:107FC0007DE1575F6F669FD6CDD9DE112CC6733F1A
-:107FD00029FEDDCE3FCCFCDDAD757B1A291F501983
-:107FE000772C85EBBAA73C4CFA06FE2E13CAED4C53
-:107FF0003BD1B10F33F571E799B91F66E6CB446CFD
-:10800000BD64A4FC8D6DBE14C5B7AD46265F70BFC0
-:1080100068482F7CDD77BE7F77B29697714E99E7DF
-:1080200067F90FF2BCBD0E486AEEF93BE723C8E6DC
-:108030002BE67E46B77F375892A6FB1B826193F4EE
-:108040004581E991A4576A498A17B60DF1FBDAA771
-:108050006C39D138EE1ADAEFDB5EF491BE556DE77C
-:10806000C9358F53A9DC3C6E6E9CF22B2373D5BEB1
-:108070002CFD6C88140FBBBF4A6CFFD787D9FF2536
-:108080003F3F17D6BC6FBE8AE7A73AC2AB7BD16E23
-:10809000EF88C7284ED0336EAEE77E72295E41F777
-:1080A000594861AE674B7195F46C19E75F3658DF3C
-:1080B000A9773087D30F6373F26306C29D54CF2F25
-:1080C000274CF4B7F8633C0FD9AFF1B862B0440461
-:1080D00035CB798D1EDB2FDE5196D4D0AFD31197DF
-:1080E000E9DC47873E6BA8B82CBFEF42F3FA079B49
-:1080F0006DBF43739D427A61A23E57ABCEA7730B0F
-:108100006790CF3BC24D2AC669FF3F82909C4F00CB
-:10811000800000001F8B080000000000000BCD7DD8
-:108120000B7C14D5B9F8999DD9577637996437C91E
-:10813000E6C90402060DB8818487C6380991A222D7
-:108140002E0235B4B42C0414E415D1B6ABD5B2214B
-:10815000098F2025581F282DDD50B02FBD8D96DEAC
-:1081600052ABFD6F04B9A8A8A97A15FDA146B43E8B
-:10817000EECF6A04BDC547FFFCBFEF3B33C9CE64F9
-:108180003604B5F77FB1653833E7F19DEF7CEFF347
-:108190009DB38EBCCA60CCC758CB3FC5862E2F3C42
-:1081A0008B18EB8127934219AC9C318F2C3096CDE4
-:1081B000D869FC73317CEF76ABAC129ECB1C717727
-:1081C0000963E168454EFD44C6166685990CF51CA9
-:1081D000BEC5720CDADB1953B13FBD9DFE0C627F48
-:1081E000558C89F26F6BDEF20FFEAE3FC5F41D2C8D
-:1081F0008270944A6FF7BA18B3294C386D8332F302
-:10820000CA6F9FC7E8CF6911FFEE09867DA9FBF110
-:10821000B9FEADE6AD8983DBAD2AEF75880A639BB5
-:10822000F7748419943F131482CBCE626A01CC6B2D
-:10823000F5FEEB5904E6BF55EA71C900C7D62F8495
-:1082400085E1F2C1FD2FD3F003088B219CF0C776A6
-:10825000FA7CF85B618A63126305F866243EF9775D
-:1082600018A5FB34F45F91807299060FFC7FE261E0
-:1082700063B9AAC7589E7CD458662C640F8F63ECF0
-:108280008575D0E9398CCD39F6DE3196CED8DC58FB
-:10829000E8F147038CE5ABAE705C666C1E0B3DFEEF
-:1082A0002A940B1A3C2C1182C16D6C19AE0B4CF345
-:1082B000A55280AF8111ACAC60591A63AE81FEBF8C
-:1082C0002B67123E1A7A17CD64E319FBF1CD2D8C82
-:1082D000413FB13A21BE17E09F5DBF67F62878DEC7
-:1082E0005B692BBA0F1B45EC6FE1FC5CD0D9699838
-:1082F0006FA6EDFA1123A17E789A4768817A3FBE76
-:10830000E0DCCDA550EE993E3A8478077CBDD53FA0
-:108310001FC0FFBC306FAF8FFF6CE589B9A3E0B918
-:10832000B3F2A1D9F89C935C1FFA9B35A5B3D90190
-:10833000FD5DB9529980FD85EB8DED0BAA8D6580B1
-:108340009CD609E7EBCF1A0CEF99E0318FAFF777A6
-:10835000EF3A85F0CFBE007A007C86F113B40F4B64
-:108360007D5208F09C5F2DA871A09B0255503B2DBB
-:10837000F8619B463F66FC8BB10C867C56374F8C70
-:10838000B743957C979DF09F3F53882B307EFEB27C
-:10839000BEC469287FD3658F8BF03D2BB34BC0EFF4
-:1083A000F7AE64ACA384C04BAF4D5ADF7B5D6DF676
-:1083B00062F83E2F4F6436A003563D8AC6233846E6
-:1083C000123E8E737CB8081F052B438FFF0CC6BF6F
-:1083D0007A8A5316A1FED50DFCBB0EDF5609E80CB8
-:1083E000BE6F053A8B119D49C793F133E7D8AA5563
-:1083F000488F734CEFC7CA8CE8EAEF538F8E29067B
-:10840000B856091D333C008ADBDEC4182E346010D8
-:10841000E95AE7471D4FABF635133F26F199FD3476
-:10842000F233FE3B8750437CF698EBF732CA8DBFA0
-:1084300064F6EE6440C2BF9059ACBE9AB1FF93D6C9
-:10844000779E00E5DF74346CDA74117C77F7FD9663
-:108450005530E6DCF89D19338A06CA69EDCB67CC46
-:10846000B808FBE3E3C014627CBDFBC725FAE893C0
-:10847000397C5B54B65D84B26493B7874A06DA658B
-:10848000613B61887661B65DB268E7D5DB019E36F7
-:10849000C0FAA569F34AD3BEDB347892C797106F50
-:1084A000B2E215603DA4E9928CF4F255E1C839D3EB
-:1084B000BC236CBB7DD4E0760076B30EBFCD1AFE34
-:1084C000387E4F1EDF3E04FC5F373ECED49F43FB19
-:1084D0007ED6F041F5F539A9E78B70D9515F298A2D
-:1084E000D796D4CFB6EE4F9F3A1F88579ACF426E99
-:1084F000E843B2AB7208E8BC5CBEC3859D4B99F5FE
-:108500007204F86133945578BFB9ABC3A5C0FBF2D0
-:10851000D2DB3721D19727D218CA83714CCEBC1F2A
-:10852000FA1D274B2C81AB76D1419B07CAEC0A166A
-:108530001A0DFD6674A7913CC92CB9E017028C9BFB
-:1085400099E952B1BD2773D22F18D10753A4247CC7
-:10855000786A5FA8F3205CB35908595112E2AC164F
-:10856000996C2C637BA19C79C91E560FE5097FF796
-:108570002922F2B4C4F55D3BB6473DDDCA0EA17EAB
-:10858000C9D3E4CF2687BC9DF4C7751243FDE1191A
-:10859000778780F0DC0B5D89C097E5E559B3EBA1E7
-:1085A0005C7EC41652149C4F87508CF3098AA4B782
-:1085B000747CEA7264C24709CEF463597C2FC0DF31
-:1085C0006A8F27505EC5A65E2DEF0578F29724C905
-:1085D0006BFCAB0F7080F03E7DD5DEF612A46FE928
-:1085E000ADE4FE323E8A27509EB1DA8630B60FCC1B
-:1085F000940CF23F4D936769263DD09A65273AD196
-:10860000F50153254586790BDABCD98FC2A40F9C9E
-:108610002CE47290BDB280EC1081F50AA73D307F4A
-:10862000AC887017F1790C6A3F89B767C1900BED80
-:108630001C675A5313D6878F59CD805CE1BA341525
-:10864000F5B3E060AEBC09306F1B8B74019D340B39
-:108650004CC2F2C0780986E3395D9E56B4BB1E73E6
-:10866000B5D8107F2D87417FC03C36DA19B7FFE4BB
-:10867000902B0BDA4735FB6D6DC5C85C2C67E4E8C1
-:1086800076615846BA5C9B5D9A8BF661BABFF7DBA0
-:108690002867676EFFE30C17CAD53AA87301E89DF7
-:1086A000CC8736C540EE3A4F153025C9CE734A4DBA
-:1086B0000CED29E7A962C3FBC43A98D1390365D50B
-:1086C0006BABC771D6642A84D75A26B762BB5A40AF
-:1086D0008692B42ECE53794C9968D57FA1E17D0264
-:1086E000EC24C5399CFE3D4C294BEE7F548AFEC7D5
-:1086F00098FA972DFB1FE8D76FE8B74D626447C71C
-:10870000025E5A77B35DB031B3EEC64CB4479DAC50
-:10871000A9CBC2EEDC906923BADB186CEA51A17DCB
-:108720001D03C6073AB9F88BE322237B06560AE8F5
-:1087300085154A7DFD743C12EB71FAB5C50486724D
-:10874000E962C96EE0931A662C9BEDA27361AD11CC
-:108750005F365F650FD2CFDAEC34C56901BFFEEC3E
-:1087600059C76A4A47C37CD3C2CB18F0F1CFB71FB1
-:1087700076B505A19CCEE9E481EDAFCE88C1FC7A47
-:10878000044E7F6D011BE1255C97DB2926F51B76E6
-:10879000B0D12817C348DF5E0E0F8EDF935DB8BBE4
-:1087A000DD627C10BB06FB61B62AD49426CDAB47B4
-:1087B000B383FBC79B56D0897CD03F9E9355D1781D
-:1087C00022E03F79BC9C2F37DE5F717EE503E3CD6D
-:1087D0009E6E9CDF6C874CF39BADF1AF3EDE5F710C
-:1087E0007E255F623C9C5FF278DF30CE6FB653A689
-:1087F000F9CD16397DF58F97F3E5C6EB59574676D7
-:10880000F04607C827A093B48A7DAE5130EE469754
-:108810005D16948176B5B537B8E6A2EEF54E9B9E0F
-:108820000DE3D45D0295F3B19769D36B4B19DB2E41
-:1088300070BAE8CBFCAF4DE8479E9CB9B68CF48982
-:10884000665F5F8955411F5F29717867157AE3CDAF
-:108850004978BC17E4880A70FC14F85D057EDC05D5
-:108860007C89E5F8BA203D7783BD8ECF3D002F7E11
-:10887000BF6F5D88CABF5A37859E7A3F6553B8DDA2
-:108880003EB6DADA6E3F2F8BDBEDDBF3E4F94B50CB
-:10889000AFD5A685502FB229173235D9AE664D8F88
-:1088A000B9E1FBD66FB20AD48D637670B803F5399F
-:1088B00064B7A7551CEC5907E58D925D41BDBC51CD
-:1088C0006133ACFCE631A867603CA793B7671772C9
-:1088D0003F2C10EE3D887A6F0EDAE980D7ECB9BDF7
-:1088E00007D1FFBB0AEC72D2CBEC8D83AFC2F71776
-:1088F000C0FF6BC7B2E865329467CDC9A6F1E14FFE
-:108900007A6D0EDAEFFCCF4F669E20BF22ECE67A3E
-:1089100021C0663FDE8DF0861C4A9CFA6377869103
-:108920000F54BBD24EA2206C473D9D8D7A1ABED704
-:10893000BEE1643684EF1207C9B5B9738D7EC37684
-:10894000774246FB677B45803543FF57CD347E77C2
-:108950003A39BF854D7EC32C5319AC2DAE77C50572
-:108960001968EF6FC4575307E32D7AAC79E3C1243C
-:108970003A55B27C81B73DB8106C0CCAB34F58F968
-:10898000B67AFC589845C68AB9FD3FD6C5361E044E
-:10899000D4BF80720FE5AD83CB8DC1FCC1E1A9D1FD
-:1089A000E4E3BDEB7A6ADE1A3D005FBE1417500F98
-:1089B000142C83F749F395027101FD1D26DE5F81BA
-:1089C000FE8D791EF70AF7E7318BF1F4673E93DEEF
-:1089D00046BCE052A23C37CFB766D07CAB9F2D653A
-:1089E00056FCA46C477B6ED66131D4AC0CE0439F3F
-:1089F000FFFF345FBDABE19BA90196007A7916E8D1
-:108A0000BD9DFB310CED549D5EA102D94F575E090F
-:108A1000DF912E54B508F1F9ECC8BE3DD7603B900C
-:108A20001D2DE8EFEA7650E2651BDA415FB6DF2BD9
-:108A3000AF7390BDC558BDFC76D9407FA9D607FB62
-:108A40007D3B497FF6DB89F8679226FA10C6E6502F
-:108A500090EC819BC03E467F3F5AFF9E94CEBF1F45
-:108A60004FB253F1CFF1A4FE5ABA7F2D280057E739
-:108A7000BAAE9AB7EC03E3962C936D6D68CF35C709
-:108A8000058A4324A01ED803239729B656C0FF1297
-:108A9000EC07E9D324D747B6423FC9764AF55CF9DB
-:108AA0007EA087D6F2BA8E103C37EFE0F132BD7E61
-:108AB0007FDC2C1023FFDCCE9A9800703ADC3FFA62
-:108AC000792FCC476D9198BB06CA766EEFB0577D73
-:108AD0002417446FD32FF17B3006720BE75DD7F478
-:108AE0003B2CC76C2CDC02CFBB3DBC7D5472C94E05
-:108AF00058BF76B975064E3F272F726F168CD796E2
-:108B0000934672D0F19A6F37CA2947E6846568F7B1
-:108B10002C88FE308CF148D9CF16862DE86B816603
-:108B20003FECD5E8EC983D519409704FCFABDB9BFF
-:108B30005565513FFA23EAAF46B4B6C31ED5FAD9FC
-:108B400069B3960BFF9EC5E39D57AF7AE8BDFB6006
-:108B50003E9E526F08C96DF3F96C9F601B5CBF3B72
-:108B60003BF287ACA478ABBB5496280ECABAA6A237
-:108B70003DB7F9F39F76FD0E509EF5B997E46C96DC
-:108B8000E88B0B2586F68F26CF436FFF974F5F0C40
-:108B9000E2FAFCC5CD48BFB2D8D397AA18D7D4CB38
-:108BA000F046C072A65EFEEDA5E86F0E94AFB9B4B4
-:108BB00016CB48BB409435FEE866D4CF5B05A611C2
-:108BC000F14DBCBE9DD72FD4BED75CF6FE2FB6A10B
-:108BD0003E98E4203F74AB6607E9F0A97E91F0A3CC
-:108BE000FA87C6E36B1A9E5DC3C7E36B567838906D
-:108BF000A7BE8EF875B32E01E9D8FDB9EB466C7FA0
-:108C0000CF3A165E02B0EF54F6FD7A9B42EDDFB626
-:108C10005A87F3F3D477B2088EE3BFD80670F8749E
-:108C20003826B31B53C0F1E150EBF9A71C2EE7BE69
-:108C300015E0CF2CCDDE74387A82B3E12957DE758A
-:108C4000830CF2664349578355FCF9333FF70332EF
-:108C500053C4DB037E4E7FDDB9E1D30847ABFC9004
-:108C60000BC74F135818EB6F99D2CB84A47E4301E6
-:108C70008E6780DBE987766953998A74E663BE382C
-:108C8000033AF35572F8B7045F600AB4F395C1D3A1
-:108C90008BEF7B89FFD1E5E0F400820ECA0E8D3E9A
-:108CA00002FEAD97A29D9F25EAF457D48EF4E2B060
-:108CB00069F563459761B9338B9727DD51D41E2B36
-:108CC000043DE380362817F21D64EF98E75718E05B
-:108CD000F3DB96ADE6FBB32DF0E9ECA575DA3ACE01
-:108CE000118AC1BAD6D87A1A1AF1DB655EB2D7E01A
-:108CF0007D433C69FE976BF8BADCCFEDADAD9FBA12
-:108D00001AE216EB918A4E276AEDCF824E27FA2D92
-:108D1000E803E8B412F19F44A71F336B3ABDD06F4C
-:108D200041E740A7D5F8DE8C0F735964EA8E450001
-:108D3000A0F4D9F45F6D436D7579F58EDFC1B3E6AC
-:108D400073AFE4873AE2184676A2CDC5E5FB80DC36
-:108D50008F5C86704B7213BD17BD61DAAF792E2B15
-:108D600045BF9327ED40B9358C7EE721DCE67E4B8D
-:108D7000FD8CD6A3E6326F246E81F77FFA256E1F35
-:108D80000778BD54FC322E60A3EF29F945A7FFDC1C
-:108D9000F05284E34CFC523FC02FAB86C72FFB88B8
-:108DA0005F3CE59C5F3C29F80523D1289F3794F070
-:108DB000F28FFCB9C40FFDFCC3CAE87B3FFFB0B221
-:108DC000CBB0ACF3CF658132AA6F6E9F8EF3B6C085
-:108DD0004B9B5F9F47B815D7553D4F6E15C9DEE8D1
-:108DE0006528A73A595FB713F9B05A08ED85B7B3AC
-:108DF000623DF52E05BFF7B0D9607F6CD5E87E17D0
-:108E0000C283FED0242D9E25F5B0AB7C83F9D857C4
-:108E100099288B24E17FA486C76F07C277E0F89D6D
-:108E2000AC772CDAA5A9D6E91E6DBC9B82EA3D562B
-:108E30007C7F26BDF328EA9D6C7CF27EB23E7735BE
-:108E4000A11C30F379CDEA87DFBB6F887E1ED6F098
-:108E5000F6D0D9F3FD4329F8FEF726BEAF14465AE3
-:108E6000F2FDC329F8FECF567CFF15F8FC3FACF8A5
-:108E7000BCD33F3C3CBB035CBFBBB5F5FDB2787EC9
-:108E800047C3EFEBFEB3B6035EB7C213E0B9779802
-:108E9000787EC76A9D00CFEFFA69BD6D31DC17405F
-:108EA0007E47FF7DD3E4581FEE875AC0D197DC8FF1
-:108EB0004BE1FD8069FFB100745EF3D9A650C48216
-:108EC0002FA1DD3F92E1D7DBDDE397B5B8B3723D6B
-:108ED000DAD53B2FF7F2FD846CF5732B7EF80AEBA5
-:108EE000EF0C58C8E31A1B9743DFF6BF4576DE57F1
-:108EF000E8DF6FD5FF331A7D9D49FF8F49D2FFD838
-:108F00008F59DE75321E4FD9961D290910BE7A2F52
-:108F100045F9B4EBE62C01FDBA423521A0FD9FAF27
-:108F20008D77BB5F21FAD2DBED92128284F59B64D0
-:108F3000212618FA3B6FA8FECC70007CE30324DFE7
-:108F4000D4F3F1798FA6CFCED61EBA30A84E0E70CC
-:108F5000393D15C757CF31CA697D1EB67017EB452D
-:108F6000FD02EE77DC82AEF2357D09FDD4513F9AE9
-:108F7000BCBF20206BFE29EFEF6CF50DC07739F6F2
-:108F800007FD5E61059F192F6782F3960138AF0ECA
-:108F900058E825737FBA7FADAF13E9D3A4B8CE12DA
-:108FA0008D5E80AF1A113E579B2DC60203FCABEBC2
-:108FB0006B904C69D8FF4E078FA3EE5C797B2DE652
-:108FC0001B74DE2257204AF297713DA7AC2CA6B83D
-:108FD000EA6AAD5F33FCFDED1D5D632796D3B86B88
-:108FE00071DC8BAB5902E54606DA09147F90258CBB
-:108FF0002F64393B821897DD2C74342C463D7AA9B6
-:1090000097F42D0BCEB58C4FE94F3DFEA4CF9B05B9
-:109010002BCF50BF99EACB9E8E26B493865DDFD9C5
-:10902000616957FD44B3AB607E3F1E12AFC100C5FE
-:10903000B774FC0E1E87AF5F6DB849407CA795C31F
-:1090400090C09269E10EDA6CB595C6592FDA4F657A
-:10905000402FD4DF0B9671BF81FE36E8707522FD7C
-:109060007C55B8F47AA9C7E3F570FF8CE21D5E2E3B
-:10907000B7E803944F1CF65BEE1FE8CF8DEB645509
-:1090800002FD73425632305EB851D383E09905AF8A
-:10909000F2FDEBEB0DCC23CEE39DA6FA51C6E99E83
-:1090A000055D64DF61183E996E8E6A74B02D27FCF1
-:1090B0007480E4482884740DE567495EBAA0ECA387
-:1090C000F25FA92CF7979FA7FA415E9FC9F2B0F013
-:1090D0000CED5EA176527F3FC7A8ECED1FF7351A65
-:1090E00027D05FEEA5EF85BCFE70C7495A573EFFFB
-:1090F0001E91E6FFB1A466E0FEE837A38D14279A1F
-:109100001F5D4ECF4DEBE45A8CC73DB3AEAFB515E6
-:109110009EDF9CDF28A3DD3F7FE94F68FF5EEFFF06
-:109120004AF42B90DF156906D94525B6F01EEF00ED
-:10913000BF0DC0D1AAE9FBDE7AA42397CAFADA2BC5
-:10914000A0FD948F5A5B0D794E1D943FE356A4CF3A
-:1091500092E3EABA1CFCBB433D1D383B3A36CD973F
-:10916000B18330FEC7DED2788CE8BA4EB6E2177D06
-:10917000DEA9FAD7E79D4ACEE8F8D3DF6F2E9D200F
-:10918000F3FC9FB8012FEED1F594EF73A5A0C1E9D0
-:109190007369FCC6EBCD82711E2A27FA50907E6758
-:1091A000697E9C592FE8E3FEDD1119938DEDE0CD2A
-:1091B0002D132CF03B4CBC1D5DB72C5C6F4779DC4C
-:1091C000E5A6FD7B26539C5FAFD79062FE75D95C08
-:1091D0008F30A74AF3D9726B461CED8E2D8BFE2083
-:1091E0006370C533EEE32ACCD7F4087D9F2C46F993
-:1091F00072AB8FF2311A167D52D59CD4FFC2037F19
-:109200007261BCB761DCFA6C8CBB2C64D2C7C9F943
-:109210000EE6711BA2AB896E63CD428395BF752CA0
-:1092200087F3F5424C9111A9BFE3C9FBC88B9409A0
-:109230000E8C4F2C8A19F77340433A903E1A379997
-:10924000DF27EDE788D83FA379C770330FF55E9B22
-:109250008DE86D27E00DFDC0625097F83C9693A510
-:10926000F1410FE1F35F0DCFB11C6E0F395D2CE6BC
-:10927000C91AA09BDC480743FDE4AB14687F33E0C8
-:10928000D3F323BA484FDDE1D5CBA0B700FFE1729D
-:10929000CDCE29E5DF6D5846FFC7D373D0067CDC01
-:1092A0009EFDF865C1B1D05F79246893A9FCA44400
-:1092B000F6212F33F6F89307C99E95CF1542C0FFCC
-:1092C00052F793878BC89FD7ECB1EE27C91EEB2FBF
-:1092D000B30483F974A6F597555710CA23FBCB3115
-:1092E0002CEFD2ECF8F6ECEE275BC93E09B7652708
-:1092F000E9EF5AC6E3CB5FB77EEC0C2EE9C07CA247
-:1093000058A98DFCBD34133F3E98EDA07A637223BB
-:109310007767C373D62D7D12C61B1C792F04500EA0
-:109320008C283DA18E04FA1F51CDD36458191FB764
-:10933000B3742DD90D9DDABAC0FFD6A3DE1B589F9A
-:109340001ED3FAF0F50857F6D0FAF8CA7B68BD6C60
-:1093500058A6B81FDF8FBFA292DB1BB293EF2BFC86
-:10936000269BC75DFF942D6A4FEE976694DE4EF103
-:109370001DF70C1BD5CFD09E6639FEA76CC9A05730
-:109380000EE445FE909D64B7C2FB705925CAB740F4
-:1093900016EEB3D6964A37223DFF5CF34F619DEE41
-:1093A000A0752A09A445F8BA3D62B96E65C35BB7DA
-:1093B00017D745485EA55AB76FCE17C35671B76722
-:1093C000353C7CD0F0B7BB902D57B9FA1CB80FB321
-:1093D000B974BB21AFDAB56F760273A1F5BCEAF5BB
-:1093E0009EF46A94DBE6715FFCE23F0288DF999F9E
-:1093F0003A2DE5E37F6BF2F185750DD40E16589189
-:1094000072480E309EF7D29F27269C76D2F45EC417
-:109410003CB4EF12EB333637FC06ED572F0E8A0CB7
-:10942000F7C71732635E198BEA79C13C0FF645091D
-:109430005C5340E18B31210498628BA4D9BA5C3132
-:10944000E487CD9B3BFB10EEC3376AFBF0205F0C3B
-:10945000DF979AF2C6AE6E5814AED7BE9FA4BFE394
-:1094600034AFB90AB71BE77ABDA45FE785E787EB9E
-:1094700093F6E35EFAA76899875E97A3E3251CAE8F
-:109480001F3D182F8BC3824356CE8C1F333E6A2557
-:109490008EAF451ABECCF831E3A171EE6C5A7FF362
-:1094A000FC5F7485093F2F027E305FD88C0FC62287
-:1094B0005720DDBE345F64681F4F1767DA314FA055
-:1094C00071B6C030BF68290BA5F3FC6075D625497D
-:1094D000F09AF168C657E3A32C94807E1BEFF4D179
-:1094E000FA3DA7E1474C7C48F30AC3BCDAF9BC8ECD
-:1094F000F3FC5599E675955AF17800BE475A41DA62
-:109500002A567A84CF6731CCA75D1EAC4F3E61D519
-:109510004D48274B4D790B66F8CCF0CF4439387560
-:10952000F03EFEE41C5F80CE2F8C67216D1F3F83D1
-:109530008E3584B287CC5B18E0734E5F0BA3B3FB10
-:10954000C7C37E0516E92FCB80DF994FF8B7CE83CE
-:109550007FAF0D8A0AE609CE9E3FAA0DE71F66E19E
-:109560008C4409DAFB7D76942357313063A1DDC545
-:109570003049D4B7E17A3795F57E4F747C64273D46
-:109580001E614D7B69FF5DC9983B2EB57C591B74EC
-:10959000D078663B6566C5E80C9417667CE878FA77
-:1095A000568E96DF309E8D3F1BBCF4A0EC457F1697
-:1095B000E368B08E7DCB19DB5D31B07FCC0A556E90
-:1095C0004FE630DAFF5F9D93A9D91D4D147758A05F
-:1095D000E9856376D6F0A097EF234F48928F0BF37F
-:1095E0006A57E724C5FBF47D642FEB25FC7DD7E5A6
-:1095F0004D88E389EEDEEFA70F925F7ABE6684F2B4
-:1096000035C58C950AC5C53CE9E35906D8C58CCF4C
-:109610001BFC989B7230AEE7298EA31130F3895F53
-:109620006C9AA70CACDBE6257B3B105CF7D2DFC75E
-:10963000A87385E77378B475ABD5D6ADDF8E2E836E
-:10964000F749F83DD1A1D961655A1C1FFF40F94483
-:10965000A91A1FCA7FD5D7D15D06FE87218FB08397
-:10966000F0A7AF2738117DC89791A04439C336E6DB
-:1096700022FF387213CFC758C8945D981FB4306A60
-:109680003F91DC4F244F2238229BDD5ADC2444FDDD
-:109690002CCEE3FDB032EEE7F5D37D0CDA27E53FC3
-:1096A000DA5C604A62FB4C1642FF09FACB417DCF7F
-:1096B00036258D3372F0B8A9FA33B713B5FD5BD1F7
-:1096C000190A8592E4F46F72B89E3C11ACECB28D2D
-:1096D0004C8DBFC52EBF2A25E5C51ECF733558C595
-:1096E000C5F4FE74FDDD6F27C6963F956C277A376B
-:1096F000343E75F8A2243B31D6F814C515F5F2595D
-:10970000DA89CFDFD5F8542BCCEF1FAF7E83F2C7B9
-:109710004F3481C0043CFAA3D3D89B7E940F32E926
-:10972000AFE206F0A830F95B52C622BDBBA305AA82
-:1097300094942F7B2C4721B8FDA52AED9741D32E79
-:1097400074C5FD524840BCDDAEC5CD8070C7CEF6B5
-:1097500025B7E37E883E9ED325131C0E7D3C166AFA
-:10976000A6FCFA998CF4889E07A2F3B5DECFBB392C
-:10977000C678DD30F8F9DD9CAAC1FC2C8A4DAFDF3C
-:109780008A72E22991FCB0EF046FA2F7E678C089F3
-:109790001C6E1F8E102327502EF4343CFF9D1F405B
-:1097A000BB35FB9C2154C3ABBEFFDE8FAB14C4138F
-:1097B0005FFFF94B1BEFACC2798D9664DADF28E2CC
-:1097C000711847B340FEABBBC411DE07CFB703B57A
-:1097D000237293E07A3B504FE59133385C27A0CF5A
-:1097E0007605DB6D6F207FD1C7F7BD4F280A9DEF4F
-:1097F000133D8CEC09D1C99F99B9DC2ECDCCE5780D
-:10980000766B4FD729811609E9BA09F72DA418E517
-:1098100041BB4E49F4DE210896F69ADE9FEB140810
-:1098200067C497C7DCDE41EF713ED85EF433837DB9
-:10983000938FEDABF0C9E9DD75CAC3E1F09BFB493D
-:10984000E7EF35FE33C37163CEB462C4CBDB017581
-:10985000442E8F6F7339EC7DF2A8307E38F298E792
-:10986000EB5F9127B928AE77AB101F0DF2A9BDECC5
-:10987000441BC9AD1257139E934AB29F047EEE86D5
-:109880009FAB18B04FFB2E995389D16BA6DC1B1AE6
-:109890006C6FBD5EF9C9BC3958D0CE4F7C5797BDAF
-:1098A0003128833DF79A565CA48CDC80A1FE2BAB5B
-:1098B000B97DD688F65988E496C1EE32DB675ED072
-:1098C000F773802E96062519E9C26CA7B557CE23EB
-:1098D000BBA61DEC1ACCD71E6CA77179735BD4C6DE
-:1098E00054A8F74CB5487EC63365BD4F5C8CFA6210
-:1098F0008A5D217D51D677DB1CFA3E91C6F16AFE66
-:109900001DD4E7E71D429EF86878F76CF59BDEC62C
-:10991000A4F57E66CA9B63D12FD89522BF428FD310
-:109920001CBC99E77FBD7E87107722DE6E116DD853
-:10993000EFC20A1FE5AD5E227A699CC6AD62DC49C2
-:109940003854D32FC919B01B99589DF33CE2619B41
-:109950009DE1F9C1A21B7B0D76EEC2A8D19E8B348E
-:1099600081FDA39CBD1D68B6FFCC76CCDA5CCDAE84
-:109970009BC026A0FDF2CCBAFDECCDD10376CCACD9
-:1099800014FBDFBA1D7381ADEEE65C1E17A4FD83E8
-:109990005992F5FEFE559A7FCA42DC1FBC447C9F5B
-:1099A000D6EB444852107FDE9B9EA4731DDE7F8A57
-:1099B00061ABF1B6E7727F7C978391BCDD35C14323
-:1099C00079D7DD379F9BDB4BEBA5DC5D8DEBFFA4EF
-:1099D0009DE4602AFDE68E8AAC1426E68B0AF4D458
-:1099E000D77344D4CD92F5C38814790ABB73B9DC1C
-:1099F000CEBE85D9D0CFCE8C31D5CA2FD5EB813F05
-:109A00003A1D63D4503F9109F0AD2EB551DC5FF79C
-:109A10004BDD767EDED7FEC8F531F44F47007C087B
-:109A20008702F0A11C2E897AA83C32EAA7E7A86831
-:109A3000263D4BA305F47D7474143DC7444BE8FDEB
-:109A400039D1F3A85C169D48CFB1D10A7A9E1BBDCF
-:109A5000909EE781DEC27AE5D15A7A8E8B5E4EEF18
-:109A6000C747E7D0F3FCE86C7A86A2DFA6EF15D1F2
-:109A7000467A4E882EA2F713A32BA85C19BD81CA83
-:109A800055D1EBE93929FA437A4E8EB6D0734AB4F0
-:109A900099EA4D8D6EA1F205D19FD0F3C2E8767A96
-:109AA000564777D2779D9F3D9A3DFD74708F4CF954
-:109AB000F62C518EF231151FBEA1E9856FE4AA4F35
-:109AC000A03CD5EB1DD1CE1D98EBBD9A3B74DECDED
-:109AD000D15C4E9F1F848EDF85C769F575DB1C1C2A
-:109AE0003A8EC0CA0367D8B7E2F33B9CCBDBEF9258
-:109AF0003AC8DED8D5C4281FCC57D923503E43508E
-:109B00009A61454799417EBE6B4C6EE45D9CA737D8
-:109B1000EFAD83B81F7565AC27300DE92514489B60
-:109B200006FD8D68B5917BAD3059C0B252CFE404CB
-:109B30001B88E7807D65D06BEEA04D8BFFF4CC9C3D
-:109B400088F09C5B3A81EC576D3FF9C8CD2319FA38
-:109B50001DBB1C09414279B996B1643B7CD786C5CF
-:109B6000F7259FD370071D9C8F36B1C7304E56D254
-:109B7000A1D4E179C2513BD4C730C573743C52972C
-:109B800006E5737E157B0C9F63BBE2751E789EB75E
-:109B90003FF118BA4FE312BD755E289F7F981DC034
-:109BA000F053458F32CD07E58947D503B84D52D5DF
-:109BB0001B9996AE203CF196748067D76B60684124
-:109BC00079CAFB1D22B82503EB0F76DB8349EBE254
-:109BD0002EED5145F867E18D7205CAD95D52AF3B54
-:109BE000B37CF0FA74E2BC719EA057F66AFBE8728F
-:109BF000D27A5405053D1E9817AC1A880776B63EF2
-:109C000047F1C0CE34B916435D7D973079B7827481
-:109C1000CCFD84B4B691A49F74BA03FC1AEC49B786
-:109C2000D6EFAE7E7BD31ABF55FFCBF07B50A3E7B8
-:109C300054F87D1AE79177663E9E1EE47615F07122
-:109C40005D303B75BD15412E4FCD78DE25C9E7123D
-:109C5000BEBCCC16AB1858B76B34FA3E135E23FF6C
-:109C6000CBF07A517068BCB24A3F8F336BF969A967
-:109C7000E4CD9114E744BEA7E13149CEF178A90CB7
-:109C8000726E546A39578B70650F21BF52E43BAC3A
-:109C9000D7E8BB3B3B1C0B669F39AE7F9B4DAEC5E7
-:109CA0007C97D878467E02D897AD98BF3322A64CD1
-:109CB000A06D2C14CA88C709E7919F5E02F686340E
-:109CC0008161AA63029F575466DA1697635E83C662
-:109CD0006FF2A26032BFE9FA7E801F75BAC8EAA4AB
-:109CE000731640AF984FD8ADE169A01F1E8FD87092
-:109CF000537E677B921CEC0C155059AF9F8A7E5F98
-:109D0000D7E9B7F539DAEFBFA2DA3ADFE4CF41514C
-:109D1000CB3BEA5391CE63354CA6F3CEADC7493E5B
-:109D200065827C124A787808C72F8CA6DD8771DAA5
-:109D30008783399A3F2EA77DD3F7FF8F9EB781AFD8
-:109D40004E7E66B5DC8DE72A46801E52504E560385
-:109D5000EC95A8E71CB4EE0AE3EBA854B3784220D4
-:109D6000BC25D06F8ED9F8F98C238E2E95F48E23D6
-:109D700053C6FC93EEECC813C121F842F62815B87F
-:109D8000A8AF0457CDF4E6615E8E9C86E597A07C73
-:109D9000DB14CC13EA655AF936EFD42F1F7F7865B0
-:109DA000C78A23B84F7561503D8AF0005DBF827449
-:109DB000AD9E234B141F1EE6FE93CE9F03FC24573B
-:109DC000E8FCB4A89CE4E15BC1A4FDAC54F6CD2E44
-:109DD0004D7E7E121CDABED1E9FEACED1B0DDE37E6
-:109DE00035B9948AFF673EF1FC8E3D6C20FEE7CBCF
-:109DF0007FB14752D0DE9EC6DE9C8871AF1E4EF703
-:109E00008CC7F9548CFF011DB82B5DA6B8AD30434B
-:109E10008BBB0C19AFD5E3C97ABC4F8FEBA56B7424
-:109E2000851706A01E4F9F224B8BA9BF5E7615E6B5
-:109E300037E5D90C7C8D720BF7E75D6D59D2C8F20E
-:109E4000817E196B2239D5D9C0E4F64CBEFF9A0148
-:109E5000F2A5633D233F2FF68C48FD9F546DEF61C3
-:109E6000CEF7C94A4020CA059529728E760E8188A0
-:109E70005C267A7532D685FE36FB51C8E5C038F7C8
-:109E800067025301EE239F89F49430C20D8DAE0812
-:109E90005584B0716D467508F703C537A10C70D6AF
-:109EA00067546760F9C89189216611BFBB3AB2C88F
-:109EB000105F32E3A9BFDE77DA285F61E719F63F6A
-:109EC0002FCA73E876E7E43CDCFF5CD2D7EA5006A1
-:109ED000F63FF57DBDBCD2872EC57B76F25672FB70
-:109EE000339FC59B93EDA6A4FDC5DABC2ADC4FEFDA
-:109EF000DF5FEC1993BCBFB826FF163CBA7F4FFF5B
-:109F0000FE62A412EBABFEAE0AA44F3D1FF688839F
-:109F1000EF03B0894F05140BFA5850F17836D1A3EE
-:109F2000E64F0CFAAEC5CDCC7EF09C3C631CFF64C2
-:109F3000684E46023FA688E3EBF13CDD0FC6789DF4
-:109F40006CC97746FCEBE32F10B81FCBEC02C93B82
-:109F50005D6F823C598AF88666148F569D02E56BC8
-:109F60009D0C352AE417A5902FFDFB062C31DA6AEB
-:109F70009F75819677627EFFA33CAE9716D8799C39
-:109F800052B87E6904C75D90E7129C4976D28A3C3C
-:109F9000AEC7F5FD1747FEA92AC4B3C31151ACE6FD
-:109FA0006DDE475981B66015C753C842EFA5C2D3CD
-:109FB000517B07EDCB1D5D2AD279DD9391C974EFFA
-:109FC000432AB9F00AD2CF68C6E6E5733D34B08EB5
-:109FD000D678D3F364CCFB55FDDF17B9E9FC8D3996
-:109FE0005FE6210D6F4F6978F957E7CB3CA5E1EFAC
-:109FF000692D3EA3C7B3AE4821EF2FB0D53D90C722
-:10A00000E38C43C665CED3F37D34FCB00363E95ED5
-:10A010008E2D3DF6B85B40786CB47FD9F09F620816
-:10A02000ED2FBD9DD7242FF4FC1DBDEC3925B07854
-:10A03000D23E8247EAA238A9E79444EFCDFC775B91
-:10A040005EFFFE22F19FBE2EA9D6595F17F3FBFBE0
-:10A05000B47539BAE84F413CEFB2C5CD2CF38958FD
-:10A06000BE31FE6ECE0348B5CFFD9AD6FFC9C8D427
-:10A070005C94CB0D8ED8E8E1F0BD8E9F17BFF8A39E
-:10A080000BF96CCB29E70CABF57849D34FA04F37D0
-:10A0900025EF83FAE63FDF8ABD7A24E33EA8AE4F80
-:10A0A000F57D504FA5791FCD7A1F740BB3968FA9FC
-:10A0B000F64107ED7F6AFAF6B3BC14FB9FE5439FB8
-:10A0C000673F90C78695F771B5839F9735BFEFD1EE
-:10A0D000F8EE646473D15DC057372C7252965262A9
-:10A0E0009193F8B071919BE2B28D153CDEDB78A7BD
-:10A0F000A0EDD719E3B04F83BC5809E33FABE99D0E
-:10A1000037597812DAA3B32A05C33E79B8DA6D2835
-:10A11000CF5FFA93A7F1DE8467A6D8158A3F435F25
-:10A1200031B40BAA799E2253FA6EC338B71E7FD67C
-:10A13000D7FF99EA37E91EB418D8F9A343187F1658
-:10A1400089BF9E796122BF974E18D80F57C04ED84D
-:10A1500072C128CAF778B9FC5B14E7DD8271719887
-:10A16000E9962FFE3883E80894720CF9757C561C2A
-:10A17000E563E3B80939489707C67FE6C3B8E8EB5B
-:10A18000B79CCCC675EA5DD7447907E67537C799A1
-:10A19000CDF1E5B38D2757E71BE9E169533C5997AA
-:10A1A0005766F991144FAECF1F463C59975BBA9C46
-:10A1B000D0E5D7CBE5EDAFEE867FBE1C71124CAF7C
-:10A1C00068F3EEE74B8D2E5FD6F9F00B27D9230706
-:10A1D000C63F4CF9567ABDD6BC4CA2AF6F95C7EDC1
-:10A1E000B43F8B790A6503EB323FB2BCBF8CDD7E96
-:10A1F0007BD9F506FAE8975367946343CB29573E1A
-:10A20000B7C352E56BF6A4D43FA3C94EF5FCD51EE7
-:10A2100077957C793DD4B0E80F0AB683E70E6A3FA4
-:10A22000DE11895BE827333C9E53228B4F4C7EAF77
-:10A23000F0F7FD7AC041DF6375CAFAF5016E4FB7DA
-:10A24000107FC69CB8EE52B6DA8A749097ADB6E528
-:10A2500043BBDF06D40DF949F2B4C5CEF723451B45
-:10A260008B3C688197C7F235BCB07010FB6BAB3587
-:10A270009EE7D29FBFC997B4F3189382685FB7BCBB
-:10A28000511144FE39E89B44F676AA75DBA6F31318
-:10A29000CAAFD103FEC4566DBD814555DCC76DB351
-:10A2A0008783C9F1C6ADF99CAED2A73ED48376733D
-:10A2B0008B6CA33CC11699E75FB77AA5197BB4767E
-:10A2C00001433B493F4745F765485E637EF5636858
-:10A2D000EF54A59EE763F9DC3FB4B3C41DD5C2803B
-:10A2E0005EB11FAF75D1FD0F4C95797E53C8904F6D
-:10A2F0006DD7F44B9D295F4394BF9CDF569C1DE9AD
-:10A30000C6F534FB6D8702EA63F83E2AC59C481FF8
-:10A31000519735DF1FD6D6B5459BAFF95E55D17441
-:10A32000EF8368BAF72156D7F4CB5EA4B7F54EB9E0
-:10A330002540F73CD0BD0F51BC72099EFF70F37CE5
-:10A3400016F0FF26F3F306A15E94AF2CE8A2785432
-:10A3500047A1AA164259F4D976AF87FE5AD43A15C6
-:10A360008FAE74786D9DB8CF979317790DE731CD87
-:10A370002791DEE9B82C8DF4107C777339C26461C3
-:10A3800012F98374690AFAE078BECC1E74503CABB3
-:10A3900025C27A9DA3F8F97FA4F75A9638525D82B8
-:10A3A000F6B6AB12F17424343123622127F4A77975
-:10A3B000FFFFD5EFBD544CF9AA62E4A37CDAF76F36
-:10A3C000DC8AFBFA6BF68B21DC47F8CEF75F1EC305
-:10A3D000CF1B19F799EFF6D4F4A23E8B7A1D54AF38
-:10A3E000DB37A903F1D422F83AD0DF6D79E3FA9F85
-:10A3F000231E5B9A799CDB8CE783BEEFD3FD1A2783
-:10A400006139B1BEF97E0DD6713D5F27A78BF62D60
-:10A4100061BEF6822ABE8E141F3CE6A37BA04E1EB0
-:10A4200039E045F8BEC2BC65EC37F5BC0B65D257C8
-:10A430001AFD3029BC09E7F503D1D7D11EC07BD264
-:10A4400060BD11EE47ECE4EFDFED49A7758D027CAE
-:10A45000B8AEA2AF5E4597ECC3FD22AD73546AA2BD
-:10A4600079B198C4F6E2FB473EF9F18548076A16D0
-:10A47000ED6A89454D84970F012FEB2DF002F433DF
-:10A48000A600FDE5476EA07E3A1C2E192D9B16DF17
-:10A49000243AAF3CDCFB452A0A847E7F4BBB5FA499
-:10A4A00002FB1D545FF3B3D0DFC6EFB532FB38CEED
-:10A4B00006F09E2A7F452D30DACFC3C85F510B2CA2
-:10A4C000FCBBAFB0AE97170C49CFC6756D71FDDF01
-:10A4D000E96867A9627AC85D0C655C27C43FAE1362
-:10A4E000AE9716B72115A4201DC88902A4831BD2DC
-:10A4F00043489F67921B12E3EB6E97809EC1AE7339
-:10A50000CA91A37476518BF7E8F2C4CC672D2EA3C1
-:10A51000BC6AD1EFE53B363C7905F4B202F16096B6
-:10A520005BC3A593EF0FA693EF0F45276979E12849
-:10A530007E473C154CA078C5CD583E7244DCE718E8
-:10A5400089E3F1B8595F1E937727E565E9F06CC69A
-:10A55000CD6ED2CB3C6F4A6A600CF3E0FC652141C2
-:10A560002E1F161D6DFE9AE9E88EA1E48397F5D0A3
-:10A57000798D557A7ECEBEA1F373BEAAFE81F5BC5D
-:10A580000FE169F17D9FE87383DD25F37BD4CE6E07
-:10A590005D1F2C10CCF70B3D988CB7C1EB1AD987F7
-:10A5A000EBA8164CA27B8CD8944564377567ABC773
-:10A5B000305F8C4921835C1CC43F9ADCFEC1390AA0
-:10A5C000E5ABFEA5599373CD4E19EDF1C70337FCEA
-:10A5D0000EEBDFCE9430C6436B6C6B094F1FC2FC91
-:10A5E000768748AE96E1BE4F94A585343DFA1F08A4
-:10A5F000CF0CA559C882F781058A8DAE2155B63397
-:10A600005BF9F0F1F0DC603C3C37141E400EFEA715
-:10A6100046CF37223DEBE7ED53C9C137B4FECF42F9
-:10A620000EBE91CC5F5F03FDBE3FB47EFBDAE5CD8D
-:10A63000A7389E59DE78357EFE6E8885305E3EDC1A
-:10A640007C36B03715E4AFDA7417D14FCB8302E50F
-:10A650004B811D1EA1B2CF45C2E6A0CFC1F37FF74B
-:10A66000F1EF621DC7B3194F42213F9FB5AAEBFA24
-:10A67000B064C8938AF1F39AEA09B954C4FCFE6A3B
-:10A68000A267BF66CFE879FDE99AFCEFD7F3336D97
-:10A69000349EBF88CB773FD83B681731A997A11F5D
-:10A6A000FF83029EBF0FFC40F40DA384911F32A6CE
-:10A6B00048A63C2DCE2FD912B77732034C205D83AC
-:10A6C0007962F0FE13B027F07E824CD5D8EE076990
-:10A6D000DF15506FF52EF23609740E3EDCFD33287F
-:10A6E0006761BE17F08D7F86B17E364B2A5BF8E737
-:10A6F000B13A5686798B15855ABCCDC182A41F35D7
-:10A700003F5DBF2F503C73DED7D4C261F8E9171705
-:10A71000EA79C2467DDCE56696F1B523855C1FD5F6
-:10A72000F7D6D6A15DBDD6C7C8AE5A8BBA13CB99A2
-:10A730000EBAD726D45DE9B2BAAF2253B519EEE707
-:10A74000F5CF4833DC7B9B1DCE3294731BF20DF5A5
-:10A75000F322230DDF0B969D6BF85ED434C1501E9F
-:10A7600011BDC050BF04109C5C1EB5E93243FDD141
-:10A770001D5719CAE7ECF896A1FED8F862C3F7F3A3
-:10A780007E759DE1FBB8AEB586F2F9FB6F36D46FEE
-:10A7900061D6F777766878057E2739D6ECAD6BA061
-:10A7A000DFD1901D8638FF755ABDEECC4965180F74
-:10A7B00069395E5146FE70FA0543FAC366B9984A94
-:10A7C0001E9BDF6F2EE4F2F383C7DE9EB412E91CFA
-:10A7D000853CC8A50FBCAF6CC0396D2EE77909FA6E
-:10A7E000EF6298EFE5EFDFA794549ACF822C07B37E
-:10A7F0003A1F705DA162B9BFD02A845CB857940A31
-:10A800006F478689B7EDDA3CBE2ADE8E09C638105E
-:10A81000EA93072DE07A42E32BD057BF453E047DF3
-:10A820005599461E06BFC7E16CF5890E07E8937F70
-:10A830002FCC1E9C1FFE41C3F3D7DCAD60FD6B78AF
-:10A840007D5BA80CD725D5BED21385E67DA5AA656C
-:10A8500028E716F8D284E4FB9AF76BF5F478764B88
-:10A86000FA67B4AFD4E208950D675F697F21E3F71B
-:10A87000E0E2FA6627ADAB5D0DCA96FE9DD98E610A
-:10A880004FE03D1831AF4479C366FF2EAAC96DDD94
-:10A890009F930ED692BFDFE21D49791F2DEA5AD24F
-:10A8A000971D29FC5CD097BDB83ED37C371AFCB904
-:10A8B0008178804AE3415BB29B5A92FC7F6CA7DEB1
-:10A8C000CDEFD5FE1AFCE08F0ACFC2FF5718F783F1
-:10A8D0004F328EA793AA8DEC84936027A0FC6D93D2
-:10A8E00018ED7BC72A05C5CA2FEE58AFD987EB39BB
-:10A8F000DECCFBDD663BE38AD0F584B736A0275774
-:10A9000025CE9FDBBF6D767EFFA6EC0F0751DFF6ED
-:10A91000653BD86E80F660368FCFE978F9B2F228C1
-:10A92000A76890FF93533484FF738958DE85F7B688
-:10A930009E38C5E3220A1E450CE03DE47CFDD63E70
-:10A940003127B606F55489D484F9EB225332102FFF
-:10A950006B0E8B2C2EA01C33E6E7DB59D35D188FD2
-:10A960006301FE3EC65CCD6827654C31EAB14CD52B
-:10A97000A8C7FC33B24C7ACDA8C7721B8C7A2C2F97
-:10A9800062D46305CB2698F49A518F8D88D699F4BA
-:10A990009A518F8DDA749549AF19F5D8393B8C7A75
-:10A9A0006C6CDCA8C7CEFBD55A935E33EAB1F3F7E3
-:10A9B000AF377CAF48B41BBE4F3C7CBBA15CD573AA
-:10A9C000AFA1FEE4A3BB0DDFA7F6FEC6F01D10FD90
-:10A9D0001C9E67C07B6871112F7CF721E377A63A34
-:10A9E000301F7F059ECF8475BCA8EF61437FAC8389
-:10A9F0009F5B88C17FB85EEFB008DD030072EC504A
-:10AA000001B45B1D17420986FAE9C1B771DF6679A7
-:10AA100050243F6E0D065B911EEEF7C5911EAEDD14
-:10AA2000613CFFB03C6E2CC7807E148C2B00FD2057
-:10AA30007DAD30FD6E04D883446F2B14A909ED4A17
-:10AA4000337DBDA3D3574C7D0ECF73E8F3D5E767B5
-:10AA5000D7CF9F6AF4A76AF4C7C44708EE1505224A
-:10AA6000FDFE8E3E5F15FEE3DFDF77E03C3ED92F33
-:10AA7000303FC0710D8B1D2AB098CFEAFDDB1DC899
-:10AA80009FE67999E761B653DB8A8CFB489788DEAD
-:10AA900010F1DD0B22E9239A02F2D903FCBCDEDAC5
-:10AAA00027443A17837C88FE82186B20BCAC01BC1B
-:10AAB000E0BDE1BADD7A426B77E2A7229D6F3E13DB
-:10AAC0003F2A1A3E9C41233FBA9534133D19F1EBBE
-:10AAD0002933F2E78AD72E75A0FC3A04F816A6307F
-:10AAE000E60B19F97585B892F6F9743C2BF01F8EB8
-:10AAF0002B81A98BF35E0DF34E2883F1BBEC91ED16
-:10AB00001B0A2CE8E64CF87DB0C8B8DFAEEFCFD515
-:10AB100002761C1679A53AFEBAB3D53FA27C4CE565
-:10AB20000F1F283A6B7FF840D1D7EB0F3F5334A467
-:10AB30003FDC370BFD29274B0FB55BC4FD242627CF
-:10AB4000305E6B6FE271BF81F8DDD71EE7790BE1F4
-:10AB50009464AE27DD921EE7091D8DA07D92716E73
-:10AB600008F3A2861BE7F870B01EFB70283D06F6BE
-:10AB7000C5313C4FA866E4D7DB9099A45019DDEFAE
-:10AB80008C20F03CA4FF46F806E5EB966669F9C711
-:10AB9000CA90F9C75768FBBB1706D57F221CD0DFC8
-:10ABA00069ECAFFF3EB6CA6CEA27FD0CFDC4EAB8FB
-:10ABB000BD16B3F93A5AB8BD46FB4C5F431CC35FA0
-:10ABC0008C712D2FC77F8B83C76DCF36CE565C3CE3
-:10ABD00028BE545C3C447CE91FAFE6F273AB21B065
-:10ABE0000E2A52D3B77E0E532F6FCE34FACB1B26CC
-:10ABF00070B8CE2DE6EB1ED1CEE3D668653DEF12E0
-:10AC0000F316DD13A03C939F53D2CFB5EAFDD414C5
-:10AC1000FBA8FEA7C1BA1AC4C786127EFFCE864C17
-:10AC2000E33D3C278A6A6B705E53B4FE6B8A193F22
-:10AC30003731523BB7698A177CAED5FFBCA88E9ED0
-:10AC4000788E16FD1287285AE2735AB14DBBEF86F3
-:10AC5000D173BA7E7EEE4E7EBECE7CEF02F0C98B03
-:10AC6000F8FB506FDE66277F0FF4119D9F5B5AC083
-:10AC7000CF219AEF538894C98750BC7EC2CA2DEF6A
-:10AC8000E51994E770EC26CABF7B662A9385BC332E
-:10AC9000E73D7CBBB85F5F85BEE439BAC6E261E4DC
-:10ACA0006B2DD1CED1F5A6713DD697E78AEFB6F0E0
-:10ACB000776FD5E8F236CDAFC5FD69DC27C7FBBDA0
-:10ACC000ADF6CB6F2DE6FBC3C33D577DBB231241D1
-:10ACD000BE359FAB4E759EBAD7D1DB968BF08E6595
-:10ACE00021B4DF7317C8DDB9502FAD5EA1F38F1B00
-:10ACF0004A58FA14FC5E610BE1B98ECCB9F2063BFE
-:10AD000094334B599600E5DED81C1AFFB606268B05
-:10AD100000D77DC5FC3E8485B77C44E36557C3D42A
-:10AD2000143A773E1DFDB35803A37B0BCDF3BC5BF8
-:10AD3000A35F571BBF2727A3D43A0FFFEE62DDBFE7
-:10AD40000EDF85F45B5BCAF6F1F3B3FC9C025E4B4D
-:10AD50004FF99BA134DA17BC12D68DEF9FF7D0FACA
-:10AD6000DD149CF6536CA7F39B43CB53309F27BF56
-:10AD7000AFF8ECCE93A72DB08637A1ADF735D9E16A
-:10AD8000FB918ED2CA3AF8EF977E71FAB43849FB3C
-:10AD9000694705DB4722A8FFDCA0FF047C2A329D1F
-:10ADA000A3652E81CEC3BA9426A22BF794901F7F61
-:10ADB000178D2DB131BCC7659AD65E6D6002FE9EBF
-:10ADC00004E502929C36FDBE841A6A6D86F697E011
-:10ADD000BE5908F3BE43CBB0BF7A6F9A8CF14D7762
-:10ADE00069532DAED7E30B791FB7A7382FA19FB3B7
-:10ADF0001FB87F6ACDB3867B051CCB9F35DC2BC08B
-:10AE0000963FFB55EE1578AD78F9B3FF13F70AE8D6
-:10AE1000F20DD4901DEDFAA322BF47EFC347AFB6A2
-:10AE2000E33A6CA8655D88F7D8678067D7009EED28
-:10AE300075E1C777A25DB2363DC47F4F24F61D840D
-:10AE4000F3350F93B1BD9E6F28B032D2D7731B0478
-:10AE5000B21F98D4B71ACBF31FF1C8E83F7CF8E8CB
-:10AE60004B4531A0CF576F3DE9C3FCD4D7A53E1F5A
-:10AE7000C2F5EE2DCFFBF0FEAE576F11290F85CE38
-:10AE80007D27E5890923387D2D1A113E85F4B5709B
-:10AE9000DD3F2725DB672C9A4DFA7E791C204EB6C4
-:10AEA0007B7FE531FCAEE8AA2EBFA1ACEBF9554E95
-:10AEB000EB73F35347703E5C7E7FA7A340C1F12341
-:10AEC0006923A0FEBBDA39A077F7F9C88ED7E1591C
-:10AED0007C7F8503EDE1D71F71B204C5057BECCC07
-:10AEE000CBF507E65D44F8D083E03CF4970207F227
-:10AEF000D95281F53989B9D921C4F7DF34FFCF3C64
-:10AF00008FA5AFCA0E5CDFA5B5AC0FCF9D2DBE518E
-:10AF1000D8F003A8BF38E225BFDF3C4FB3BEB91657
-:10AF2000EFB311ACEE816B3AF467E86709F483F68E
-:10AF3000E7D20EE3F713876F38B413C6DDB7DF41EE
-:10AF4000F6E2B56788F78F1FA1E9A5496CF2E951D0
-:10AF5000A4FF32C629A9ED0E5D1FBDBB8E5192CA5A
-:10AF60007FE1EFFBC2F3FD75323D4F152BB41E2B75
-:10AF7000F6771FA2DF16967A26A1BC9BF944A3E7B9
-:10AF80005B6C20AF685267CB819D5455CF574D50B5
-:10AF90007C6F8A76FFCBB5DAF98FAAA3E67CD5EE73
-:10AFA000C7FF8C761BCCFF6CEEED5930CC7B7B4E13
-:10AFB0001C9EE6413A993D42F37F26035EC4AF8E64
-:10AFC0009754ED56A5F8DD169D9F4E697A66C99E89
-:10AFD000D91BF261FC9647DF29C6F8718C71FAAE75
-:10AFE000FA29FFFD9F2A6F0ED19B0BE9330F9B9827
-:10AFF000EE7988B11759127D5FFB8887E82408F63F
-:10B0000090730ABEE1F45A85F776227DBFC0DBBBA0
-:10B0100034FF36F2C8ADBCFE9F1DB233487C19B474
-:10B02000D13311B44DB1B867CB7CBF5887B1FC8127
-:10B03000BDB718E5CAB5263FF403C13A3FAD71C4A8
-:10B0400048C2C712459D8E79004B5978038FDFF2B5
-:10B050007B7BDE953A0EFD10F97D8FC06280A7558F
-:10B060007F7CE0DF518E5DF7BB3BD3518EBD2775F2
-:10B07000E4E0782BF7B6A5A31E78578AA563FBF703
-:10B08000E25C9E0DD29723044D0EABE902C8E4D5D5
-:10B09000446AF0FF257D1B6E8671FE1BF08C7CBF21
-:10B0A0007ADFA7543EA4BAFA5810FBED9D8E702C9F
-:10B0B0005FE46D6A0EA17F69E4CFEB7E79678E4213
-:10B0C000791EB1020D7F05D86EF51E3BE5F9A21F72
-:10B0D0008FC3AC617D343F73FB355D6F3A505ECBFF
-:10B0E00036D65778E1E0EF60213990DFD6ECDBF21D
-:10B0F00091988ECFF75EC1DF835A63B24F9769F2A2
-:10B10000DB4CFF5D26BA07FC507C210670F19F6383
-:10B11000E272BCE5D7778F7F03E07B7FCF53E9F8FE
-:10B120007B133AFDEBF73C9FE86A5CE818E21EA14E
-:10B130000F343EE9D70F9A7E52F60360B9507C84F3
-:10B140003F57DA13E917C27C5776DA4348F32B1FCF
-:10B1500010552FDA552F3BC91E59F9C049A2DB956E
-:10B1600082DA27909E63E928C7F5F55AF1C0DFA679
-:10B17000A39C5E9127B299C08AD7FDFE135E1FE89B
-:10B18000DC0DF5573CF8C6F41F6219E489CB62BDAB
-:10B19000A675753B7ABD16EBD5F5C6748CCFB7FC9A
-:10B1A000FA1FB41EEFFD4560B92583DB2FEBFC1BB6
-:10B1B000C5C1DE8785F167727CA1BE59D3252E7289
-:10B1C0006458AD5F62D6C395F49DF2C2CFB48E1DB4
-:10B1D0002318D78F7F7CE0DF1E063896BDE20CCDAA
-:10B1E000C471FFED86740674F08ED4C4E9FE676DF9
-:10B1F00039A8BF97D96339323DF9FB65BBBE47F427
-:10B2000078ED5FBF97A3ED37E4D9481EC4F2709E76
-:10B210004B7F3A8FE6790D8B103D2EFB19BF67F1FE
-:10B2200013F0B3ADFC84A90AE71B27BB7EFCCD015C
-:10B23000949B78670BC0E160FCBEAEE778FEBB93E1
-:10B240005D95916CE77A146ECFC558FC35B43BD749
-:10B25000805A46B9F6FF003503B31E008000000097
-:10B260001F8B080000000000000BE5BD0B7C54C5DF
-:10B27000F5383E77EFBE425E4B5E8457B8791224B4
-:10B28000C485249040D485400C0AB8404494884B2F
-:10B29000C010202101AD60A5CD860002C53628551D
-:10B2A00014B40B8245451B31086AC08D2886EA1705
-:10B2B000438D165BA18B2008045810EAFA2DCAEFC3
-:10B2C0009C33F766EFDD243C5ABF9F4FFF9F7FFA08
-:10B2D000A9C3B93377EECC79CF9999B3E2814BF911
-:10B2E000BF8C62ECE1787DA5C9C25805D33B3D66B1
-:10B2F000867FC215814A493F189FC35F0263790761
-:10B300004675F3A4316662178CF767327611EA9FAF
-:10B31000B36ADE6357E2193BB1D1D445B819CA18F4
-:10B32000565A07EDAFE0DF6DFEB25482CEA3A9F905
-:10B330005F18F43F97BE04FD6C3991BF0EFA65B1FA
-:10B34000220B8FE5F073303E4B71486578367CAF49
-:10B35000E5A8B107D43BA3742C19C7DBFC0DC1CC05
-:10B360001A2D617BA5FF8A9D26E656C603FFAFD83E
-:10B37000F48D91613F3AE6ED35AC7D3D6395E9880A
-:10B38000870A162EAD84F284D19BFF2E7E07BEBBAA
-:10B3900019BE53B206DAA7AAFAAB3FF937968EED7B
-:10B3A0008DFEE7F1F8DFC58C65412116853B42181B
-:10B3B0009B8938CC693FFF855F553FFE81AABF0C52
-:10B3C0002934EA7830FC63081B7245F4BFCFD603FA
-:10B3D00092BAB77FFFFB2AE7E31F18F06D27E1B1B0
-:10B3E000CCE07A09F154F6A5C9EA043C96BD76C9C9
-:10B3F000A88B422A326F7257C64E6FDDF3C57D307F
-:10B400009FD37586A831F4555B9810E3C77BE9B6E6
-:10B410006FF2D7417B03E03D08E839B7FE7BA30E0E
-:10B42000DAC7E631AF09C67F3ACACED800C49BE17D
-:10B430006B8F0A6F79F0DC1342E3E8A98BC5D2DD8C
-:10B44000934139378A59DDF0FEDC16D12A21BE98A6
-:10B45000779925A4FDFB15754703E8A2AD67CC6B72
-:10B46000B4E377EB7F735E0C53E35DFFB5478577FD
-:10B4700005CF81789D8A78EDEFC7EB2596160E9F54
-:10B4800061A75E99D3C791D61EBF0A5ECF563164BD
-:10B4900072FFF33E12E159DA091FEA06750D72C90F
-:10B4A000D8174C85C7D9AF9E21FEFD67779189C01B
-:10B4B000377337FDB00CF90AD0EA3501FFCE759D20
-:10B4C0002778A9CDEC650437160AE91DCD5B8BCF33
-:10B4D000C0FA78446AB49FFE86C5CC190AFD7A7713
-:10B4E00089AE8D30B47392372C02E6B734883D6054
-:10B4F00087F29C4586BB2A307B601A8CF39C33DD37
-:10B50000E2C4F782D8E43AA0CF39BB37AC6B887F6E
-:10B51000DE471AC43009DA7B5CACA02EA43D1F3292
-:10B520005643DFF7B0CEEAAB491E4689975FF7C0B6
-:10B53000F72E38F5CC04DFF3547FFFBA07CA637ADD
-:10B54000B305F134A3FA9E30A683EF3724DE351914
-:10B55000DA3DB80FF047D3B319BB037EA7F3A9B305
-:10B560006F99F3E95C989F189AB9F75D78BF04105A
-:10B570002B02BFCE58A5C5CF6C660F77C7A3DC1AC8
-:10B58000FC7C42FF7519DDF0DE4C4748E54AF86E59
-:10B59000E97A6DFDEC86D3C45FB303F8CB81FCD5AB
-:10B5A000BD3D7FBDA2C8ED403610F96B9418A24393
-:10B5B0007E3ED724BA4CF0CE852506B60CE00B5B58
-:10B5C0000517837E2E3440238477729839A3896FC0
-:10B5D000153E57F0D68AFCD7B73D3EDBEAB71F1AB7
-:10B5E000FC1834297BEBEFE9EBA06C7DEBCB947777
-:10B5F00011DEF1D7B8BFB3F6EDF376FF3095C6B5DF
-:10B60000DBC4705CE7767F14F718C2EF98ACC8B75C
-:10B61000E7169B6C0CF5DDEE505732D6F7067E0030
-:10B62000BAD7ECFA3E1DF53D634B888E9F4B462AF8
-:10B630002F34FCEBB080F3683049388F8ADD80040A
-:10B6400078BFE29D2017C3F7777D3FD811F2F3CD85
-:10B6500067AE9139883F43D9E46DC8BF5D990DE766
-:10B6600053F16ECE8BD5F0FDF2FA46E374A8CF7B92
-:10B67000EFC774D447E7B6351A515F9D35785E60E1
-:10B6800056E4DFFB6B0D80E7B3A1D0590FC61EDD7A
-:10B69000F0BCDD19D2115E381ECE011E705E80979F
-:10B6A00052575AE7F8F8FEBF161FE7A7E2F7CB1A82
-:10B6B0008630315E8D17C1C69F87BACC02CD9F3FC1
-:10B6C000DFFD7D3A0BB9F67CA3E38D24EFFF7F9974
-:10B6D0006F46FC7F2B7D39BFBF2B4934BE40BE6F08
-:10B6E000CFD73B1E21F8F5502B8DF73AE57DE27F51
-:10B6F000EDFCFF6FE83DEFBF76BED7A2F73E99DEC7
-:10B70000A11613EAAD5D3FC6B11B9877EDFF47E781
-:10B71000DDE6FFE8ACE64C18DFDF98EBEEE10279FE
-:10B72000251DFA23BBE2B5EB8E71B25F51C3BE1E7D
-:10B73000390DBEEB047F02FDFD9A90AFF52D003769
-:10B74000839F80FE0543E704F0D05C38D0B512ED4E
-:10B75000B6BE925900367C319DE0C9C53FE833A1A1
-:10B76000FDDDE0E761FBFDD59E19D550BFBFAB4EB7
-:10B77000AA01F82EDBC4E47A802D3D440BAE636A47
-:10B780006C19664935BEBBB2B5EB91FB02D615F715
-:10B790004CD6D64F621BA3F5D0DFA4520373C194DD
-:10B7A000EE0E68BF2EDE42F8BA87552EB584DC381F
-:10B7B0009E4ECB78AA61839A24C48B4DB46E66EDFD
-:10B7C000F1C6106F8897D80CB6D28A5FF1E85B009B
-:10B7D00036C9FE15FC913CDE1D657E09F16462F3FD
-:10B7E000D923D0DF25495F89ED4D0CD68D7CDCB4A3
-:10B7F000DE0CC41B93D79F26990477D91E628867F5
-:10B800007CDE2756F33ECD3B10CF378ED7C5C94FD0
-:10B81000235E0B43AD2EE40BDB8BD17AF85E0DE09B
-:10B820005910FCF854F0148877F43969FD27E35B6C
-:10B8300029D398772AFA9D612CCCBA12FA0F33F7E4
-:10B84000627A3E0FAFA93B161686EB357104AB5BEF
-:10B8500009EB3596AD6F6D9B5702D5BB1F83F76A19
-:10B86000E6C1FB88D75E4CB213FF1759707D2330B9
-:10B8700007BB12ECF73F3FCD06FF339E4AE2DB4F9A
-:10B8800037717FF352EE9BCB0682283198B3733029
-:10B89000FAB9F29FD35384EF894C67C5F52FB3D91A
-:10B8A00024CB60EC97D1BA263C5BA759FF76B575DF
-:10B8B000D1E02DB220420347DB7B68DA779B9CA066
-:10B8C000A9EFEEB84953DFB3749006EE5D3954D357
-:10B8D000BECFC2111A38DE7987A67DE2F2091A3886
-:10B8E000B9F63E4DFBBE6B8B35F5FD5CB335F5FD12
-:10B8F000B7CCD7C003EA7EA9697FF3CEC59AFA8197
-:10B90000EE959AFA8CA627357056F3739AF6430E85
-:10B910006ED4D4E7785ED1D40FFB769B06BEC5FB10
-:10B920008EA6FD6DBEF735F070F6B1A67D9EF9339B
-:10B930000D3CCAF2774DFBDB638F06C43B2CCE87F0
-:10B9400032518D013F819C8D964E6BDA83C75C84AA
-:10B950007C6390F9E1CED4EF34F563ADFFD2F467A8
-:10B960006495400464AB5A2ABBB03A2A43583395D5
-:10B97000BF1EE0B027A05CBCE05C864CB53FE7FB97
-:10B9800038B4239FE63EE444BEBB14CB2CE24018FF
-:10B990000FF3EA91AF75C1977B395471A3309FC8FB
-:10B9A000DC19C0873E814A8B2F98B923810F7D41D6
-:10B9B0005446F822E979A4AF2B9551BE9EF43CDAA7
-:10B9C000D79DCA185F2295DD7CF154C6FAFA53D987
-:10B9D000DDD78FCA1EBE0C7AAFA76F2095BD7CC382
-:10B9E000E8796F5F0E9571BE3C7ADEC7379C4AC915
-:10B9F000772795F1BED15426F82652BB44DF782A2A
-:10BA0000937C53E879B2EF5E2A537CD3A9ECEB9B8D
-:10BA10004665AA6F0E95FD7CB3A8BCC9F710BDD7CB
-:10BA2000DF378FCA34DF63F47C80EF512AD37D3552
-:10BA300054DEECABA6D2EAFB0DB51BE85B41E5207A
-:10BA4000DF53F43CC3B79ACA4CDF3A7A9EE57B9643
-:10BA5000CAC1BE17A91CE2DB4065B6EF552A737C4C
-:10BA60002F5339D4F726BD37CCF70695B9BE77E901
-:10BA7000F92DBEB7A9BCD5B7879EDFE66BA4D2E689
-:10BA8000FB989E0FF7EDA37284EF337A9EE73B405D
-:10BA9000E548DFDFE9F928DF9754E6FB8E5279BBF2
-:10BAA000EF089505BED3548EF69DA4F20EDF77F411
-:10BAB000DE9DBEF3548EF1FD8B9E8FF5FD40655BE0
-:10BAC0003C21D710A017DBF49FEE0AC67942223A38
-:10BAD0008CB7B5BD2FEBE3D5C12F308C7B8CAB146D
-:10BAE000689DFE4CF0D90F484FE69824849762D3A6
-:10BAF000EEFC3B9618C6EEC77F488C35E69868FD8D
-:10BB0000BEFF57FCBD65C38F7EF510DAC779268668
-:10BB1000F63150FF2ADFFD347B4F34FA61CB0679D2
-:10BB2000CA30FEF244BCA708CB860481ECC59B72E8
-:10BB3000F94E828ECA3503B8FD2E9A971C4E71AA13
-:10BB4000A8EB9BD7FFA2DD8FF6B77F2189F7C34211
-:10BB5000BC71642FAEB39FEB6DB7D4FCEB3F605C60
-:10BB6000C756A36741B702ACE7F6DEF955A86B33B9
-:10BB70004CC939A2F28F18E7712E36596AA210CF3C
-:10BB8000BFFE13B65FC898DD04E51F121C9F254059
-:10BB90003FDF07C5B9C038C25FE59009A13F6BFF21
-:10BBA000FFF83FEEFF34EAB5CEFAFF87CC476312C9
-:10BBB000EDE7701C4C6F4B473A8C58DC5D8C82F77C
-:10BBC000A7AD122CC847D3970CCC47FE18C46C14F1
-:10BBD00027BD3F923D60EFC02FEB96A893FD0BC9A8
-:10BBE000780F8CE70CB81CE84F144B8CF8B2B841B6
-:10BBF0007039290E6D0B1B0BF6BB54E6DBE2E5D565
-:10BC0000C605D0AEBC3B8F9731178F9799E17F283F
-:10BC100047736A37ECA570A37899E26397D0EF0574
-:10BC2000D699B3A57D3C7601C699771A2D6837CA97
-:10BC3000EB02E2B90171B3C0789925518EC75A99C8
-:10BC400095C7B9434AFE8ADF63619218756DBC28B7
-:10BC5000F1598949DD108FA3C4B4705CC75C684A90
-:10BC60000E67584A52376CE7005A344329E81D439F
-:10BC7000F039E0D38974F55607BB36C2B88E803DE3
-:10BC8000913270408E21468C47FEAD375B2910D52E
-:10BC9000C80FABD824925FEF59FCAF6518C79E154B
-:10BCA000AFA775C0348CB9E3F8DEEEEA720AD42F80
-:10BCB000E1DDFB9A407157279B1F8B71DDC07D141E
-:10BCC000FBD2E871D948A7E55D079990564EDB177E
-:10BCD00049312AFA2CA921BC16C74672FAEC3490D5
-:10BCE0005F0BF4A946FACC72198EA9F17C895D36F6
-:10BCF000E27E4CF1F2F344AFD97E7A69DA95D73619
-:10BD0000125D814E9AE71595279438FAB1ABD12B85
-:10BD10003F805E183FBF072B1745927E285AEC4E96
-:10BD2000AE54F169E0BE44D28CA1E1769087821EC8
-:10BD30009C1E4C6F8D417A7EB72A8BE81548A782EE
-:10BD40009FA6133DD8DF42D96618CFFD89EC810943
-:10BD5000F0FC0139FE7A7FCDE8028C974F4DE4EB81
-:10BD6000934F61FD6983F5E7812A33B3816AFEACA5
-:10BD7000CA42F0E755B104FFB54AA2F2CBAA542A51
-:10BD80008F1959699D4ABE80018C38BE192857D138
-:10BD9000582AEBC3876331EE5EF0D367593A52A954
-:10BDA0006F8E1FD51BD7178004157E261706932F7D
-:10BDB000ADC01E83253F16F5C70AC1BA19E96A1F2F
-:10BDC000A669CF5233FC30DA2F3DE727E08B8DC8D0
-:10BDD0007FF78E89D4B49FB4BCA7065E9428D1F8AF
-:10BDE000C617246A9EDF57D45F034FF3C17A1E3E05
-:10BDF000952415E89CD0FFC54F0CC4CF172B877432
-:10BE00005BC061E2BB40FC1F333A298EE0DC68B2C4
-:10BE1000A2FEFB3688F3F7B79F8BAE1A5AF73A2982
-:10BE2000EE72C96C91709DF2C874671CD63F120CFB
-:10BE30002EF940C497C8307EC05E3191FE9CBE563C
-:10BE4000604E94112FA3F5F2C32F9B689E33D68AC0
-:10BE5000CC91417C1287ED1F8E96A8BFFB13A53AAB
-:10BE6000E467EF66937523D44EF7C8EF0B83681F22
-:10BE7000A47CFE5F0FEB511E529AD371AD5514EFA7
-:10BE80008E463DD8BAC940FB5EE5E286921020D1CD
-:10BE90009C27DE0CCB9148FC08BFA70E446FC0F96D
-:10BEA000FBE7EBA2B8C8377DEC1B13419F9E2A71BC
-:10BEB000A5D33A79118FC7B7C70B233DE5D4854980
-:10BEC0009B71BED31D432C696A7BC8F7FDA61BACD2
-:10BED00031D634E4FECCEEA8078EAD321460DC051A
-:10BEE000F4FE38C4D3B1DA48DD4A5A546D23FE2A31
-:10BEF000D64B46F5778B5789366A0FFA7D3CDAEBDD
-:10BF0000D5A2830D41B896FA772E171CB8EF94C4CA
-:10BF1000B2BB21DF3E346F48379CC7D44EF619CFF1
-:10BF200082CC3854FB58B3778976177E2FD3A32F52
-:10BF30001CA01E3F8F03253996F79A8F747A23C869
-:10BF4000BA5242BD9A188EEBD4932D6037E01BB3E2
-:10BF50006A1AD32560BDB28776101D4AC7D5A5B829
-:10BF6000E1F901B3E313C4E3B7DDEB9E1E8671A2D2
-:10BF70008617E39C680717F2FDB5D9AFCCEAA3F6A4
-:10BF8000E7DBFB132C56978D853B4600BC38249687
-:10BF90008FF89DC2EAE4F8858BC627A1D2057C58AC
-:10BFA000CAF8FEDB749D75EA679988FE500BD2458E
-:10BFB000E9EFA881C7B9FE21CBB362877B24713F2B
-:10BFC0006BBA8ECB1DDB2D109F02C1BE4852D9CB60
-:10BFD0000AB68AEC656C4F91E1BEDDD9C408592FD1
-:10BFE00070FB3707ED1FEE0B5B04928FB22D269787
-:10BFF0000BF82B3589CBE76CE36B4F0FC2E6F1955D
-:10C0000046FCCEAC7A813D074D4F195C25CDB82F4B
-:10C0100065D9B02482DE33585DC8A7B27E3783422B
-:10C0200040BD3013FF09F5E56B04979BF8C54E76CC
-:10C030006806C64D70FD8F7A5EA547DAE9F700BD48
-:10C04000FE200BD8D7AFD5DA177B70A819C7397B7C
-:10C050000DF76BFDE311D915C05589C3B5771C8D5C
-:10C0600057A0B848E0F767E2F870BC303EB7F5C6B5
-:10C07000C75362E5725A562BB85C1D8C4FC16B7862
-:10C080002E93D03ECFD924B8901F4745CD23FCCE68
-:10C0900006FC46225E9DF6B07B002E014672517C66
-:10C0A00085E3BF623DC73FD0F92F6ABBFB4D94D7F4
-:10C0B0008878FD06ECA713F7032BBF27BAEF05FA24
-:10C0C000A2FCCE7AC365C48DC8D3AC362C04F97EED
-:10C0D000ED81BDB82CF866CD9B31B87E2D8A7027D6
-:10C0E000EB406F45B2E8270B6EF1F35FA0BD6E67C2
-:10C0F0009703F0E36476B243EDF0645ED58CFBDE2B
-:10C10000EDE827C7C51EC47F017E1EDC24DA82D27B
-:10C1100035EDE4F3084EC25BA9D34B7E4229CCB384
-:10C12000C6824F9DF9889707AD8CF4EE8D8E3770DF
-:10C130009C4C2C22FEC4B81EFA21FFEE7803FD8F22
-:10C14000494957F73F02F548A0FFF195C1A65B8C1E
-:10C150007EDF01BE2F7E51EFEE8DF27B312AC10AC8
-:10C160002DFC7A347A5037D4F38A1E2D91ED96D275
-:10C17000EF8368AF003EBEF6CD30A4BB42FF9968A6
-:10C1800027D2FC76E291E9D03F7CEF911D41D4FFAC
-:10C1900099B160A7A0CFA2E73F0A632AFDF7781FF5
-:10C1A000C7FC24D4278A5D1337C45980BF147D7916
-:10C1B000AD7557A7F30A099857A8765EC538AF0C36
-:10C1C0007F7FD3E5797DBD9CCFE7E82A3EBF19ED9F
-:10C1D000E6C5EDFE232F9AAC4EF20BDCD12887DFAB
-:10C1E000BE21B21AA22FF71B2E99819F0662FC6610
-:10C1F00015D9F593D14CC2B84EA7F67BB589FC8210
-:10C2000059DBF97EEB29617837DAF8FFC01DF62893
-:10C21000CAF53691A11DF28FA7CD6E3F9BA4B6DB68
-:10C22000D789378CB3A23D9B0BA843BE9FDBD08D33
-:10C23000E1399755C3599D48FBF01ED263C04214A3
-:10C240009F063F5C136F3031ABD98C74EA24FEFA41
-:10C25000CFE4F353E7133EBC29887FE5FB155DDC93
-:10C26000866EE8D7BC21905F53FEF0F0B0E10CBFC2
-:10C27000C3E3663B92B89D7A07F51CCC4BB0555290
-:10C280005C0C7C1ACBEF705CEB797C98BDCFEA102C
-:10C29000BF0853FC58C7E7214816563488C7E5CD78
-:10C2A00068D7427464D702F17042FE4EB9A823FFEA
-:10C2B000B7CCC8FDE073023FFFF1916C1F3F4AE22B
-:10C2C000EBCC4F92783CE11CFA81D0EFB95B4CAEDD
-:10C2D0006A01DD563DAD93F5B92617FA337A7388B6
-:10C2E0005B4C47F4EACFB6C933E06B2A6B36203D8E
-:10C2F000C765CFDB82F339DC8359C4AE546DC77D8B
-:10C300008429A41918DB6FF8EA438C473AA1AD08D9
-:10C310006B8529D9277A63FBF508C3FC0F07D57D08
-:10C32000887196C3F17A86FB02CE5D26B2FF861134
-:10C330009EDE14A7ECC258CD408CC7EC598A7CB461
-:10C34000373632D502ED1FD077B18A5CFF8C3C8F37
-:10C35000E32D15F8FECD124F16D2E766B6C472DC97
-:10C360004C5B0BF55722AFC63F7A765CE10318535E
-:10C37000D908F8C750C6192B9BF0A98101AF045FFB
-:10C38000DEF4C88435B9B869220D403A972578F5AE
-:10C39000B89FE215987723E0E1EE6CAFDE86F4B249
-:10C3A000B1BABB807FDDFB9880DF4111C0EFDEE3D7
-:10C3B0004E18857860A9120B87FABBF412C1BD0A2A
-:10C3C000588428EF1B601CEBE03081E8A0334B065B
-:10C3D0009CB7BD401884FBA2658BAF6F9C61C9D52B
-:10C3E00034CE329D8EAF671FE5EBD929CE23A3C88B
-:10C3F0004FCA6502F26145449D81D6D1202F38FE97
-:10C4000081D08D1A7F53F41E3EBE52185F0ECA456E
-:10C4100012F1F17D9502F99315C68EE31A3D9295BE
-:10C42000759745C2F673E05FC8D7731A7624E3F7B1
-:10C4300056099C0FE6287CB6552B97B9C9ECAA7C07
-:10C440009D93CCF93A2799F37572DBF7EAC8EECEE3
-:10C4500069F8E820AE2B3BEBBFDCC4DC84975D269B
-:10C460008A1F083A6F12D1051109749882FE24B808
-:10C4700088439223B89F2EF36709FA1F8958F2B8B0
-:10C48000880E9427DAC3D2DA178D88B4C0F347E058
-:10C49000F8D039A0D99B029FABE22AA246EF50DC2C
-:10C4A00053307A67E078845B83ACA88FA718EB6879
-:10C4B0005D1ED8CE50CBFD2CC372EE67D1BE1AC024
-:10C4C000A655DCCF9CD2CB3B80919EB3E40BF1AC64
-:10C4D000CD2F2EE19F86E7651ABFD88471048C7B2F
-:10C4E000ADE5FEA05EF65F8B5769FD85294B54FED6
-:10C4F0002275EB2DC7F11A160553DCC584FE84CADC
-:10C500000FF8876EBC13F5B033414FE72F0D2CD0D9
-:10C510009FB0331ECFE4CFF5B29F383AD9A0D97F70
-:10C52000738E60A9888722D44389A86AECCB319E98
-:10C53000778185D662DC6C94B888E27F45D5FC5C57
-:10C540005A60FCEF42E587CF637BACC7E70BBAFCD0
-:10C550001487FB9BB02CB50BB782BFD1E5F0250744
-:10C56000CA07282AC3508C03EEFF06614117CE8408
-:10C570006CFCBEFB79ECDF69345B506F3D131C46ED
-:10C58000FD2C5C28507C788985CBDBA1AF4237A29B
-:10C590009E52E2BDCB8667ACC5734B359B1B27987B
-:10C5A0007BA37A60746E8939F7FEC506F329BC0C4B
-:10C5B0007243F047136CE1C0E71F7AA79A014FCF8F
-:10C5C00026374DD0839C9CFBBDF705845F4D3EC054
-:10C5D000E127BC7141086FFE9CC3D54A7F9F4FC0C5
-:10C5E000FECE3DCBE1E550EF84EF17A17EC3790F7E
-:10C5F0001568DDFF8AEC7F2BF19E22DDFBBC1CC1A0
-:10C60000DC683FAFD5AE3ED9FE0AFA3B62E8B150D6
-:10C61000F42FDEEE6B7B05EDF78E44FB53C948AF7C
-:10C6200016574C34C6B174AC19E90276CCD6D1BEDB
-:10C63000F42B493C4EF3568A9DDE57F005FDACFFC6
-:10C6400077FA1999C2C7A5EA67F3BFD34F78DF76A7
-:10C65000E3793D39FAC6FB9917D08FE2B781032CF5
-:10C66000A19EF2A6DAF6E1F8E6FCDA36A21EF5CFD4
-:10C670007E91F8F4BBCA1D2968F7BFDB6A8A44FBC8
-:10C6800037E7F5B7E34A308E20FB45A71BBF344A96
-:10C69000F0FE5C9FC86CA0A72B7C029573EB1B8DF2
-:10C6A000F96978AEB6D198A71A57993C4EE074FD57
-:10C6B00004951FB33F5927EBCDD554CE79FDA41E69
-:10C6C000E9394757771CCF1FB3A13CEE1538BF1D82
-:10C6D000B2DE3D8CE70D3A8803B4C8FAB9777FDB48
-:10C6E0006788B7B7509F030CE6CAD111BE7AA5F090
-:10C6F000711475E17A3EABC55AF219ADFBD27522C1
-:10C7000094830F561A8BE1F9C1C41187105FEDE3D2
-:10C71000905E1E876CE071C8A288E687C198B16EF2
-:10C720002F5D7CD20CEBB83B9F91E503450FF44B9A
-:10C7300081499197E0892373799C0BE1FF4D363C49
-:10C7400085E7089BBA34FFE233B40F2B42D94690F9
-:10C75000B3FB8784C66D83714C77860B603BD970C1
-:10C760005368CA3468D79A30BC5B0AE92746FE6131
-:10C770006B82FD02CED7131FAC036784398C3C9EBD
-:10C78000E5F8B348F12C477AB0C3D501BEBC323EC0
-:10C79000BBA5F0FD9D261D8C73108E839FEF85BF7A
-:10C7A000B86D186F5ADC4740BE53BE3F2671788C77
-:10C7B000FAFB6312ED624AB4BA7D38C3F6D73B0E7A
-:10C7C00096C2C71193C2E965CF05FE52E9FD092360
-:10C7D000833570E198486653AFEF0A7B6AE0C9453C
-:10C7E000899AF6F7CDE8AFA91F6B6ACEACBC017F82
-:10C7F0005F0C4B0DA7F57F165F871C6AB8F4C51454
-:10C80000F46337895601E6356BD7E62F8651EF1270
-:10C81000C5B94E3589648FC0BD35AAF74FCEB06615
-:10C820003A77ACEFBA84ECDF9C587EBE7B964BBB6C
-:10C83000FFA1C4E53BDA37417B5686E7623ADA3737
-:10C84000F1C7E3AFBA7F929D22AF8707B1417C3D2C
-:10C85000DCBA1766CAF2763612BD6AF6895664D516
-:10C860009ADE0213609CB7D79B5C4130EE336F1F9A
-:10C87000314AAAFD930A5F35062DE0BD23463C4FA1
-:10C8800075305922FACD6D386F64C017B737CC2395
-:10C89000B96E6E744445A3FD027F757B26F2575D29
-:10C8A00026DABF269DC58EFB6173968FA63873B8B6
-:10C8B0006F0A9565B5A3A9DF72DF4482E7FA8209A2
-:10C8C000FE546CAE3F80FD3C136E417B5EAE776ED6
-:10C8D00045BA944BC119B85F35B7FEC0C55FA21DFC
-:10C8E000B5F07B1D63C5BF6462FDD83E165D4D5734
-:10C8F0001C6F10F5D33CE2EF9968970A705D00CF8A
-:10C90000CBB6E53850EE87D7845A50EE453C4FD62B
-:10C91000019FCE48E1FE9EC1C3C73BCA379EFA5372
-:10C92000EA67A72450BD021BA237E9517F28F330E4
-:10C9300080C1C7F20E5F7F2A2BEAC7EBF15CFC9F38
-:10C94000535F8C423C41FB102C93460E233DF35D1C
-:10C95000E59070D681DE524A93AC87A7A01E86FE72
-:10C96000EE4DB555A11C8E5BE4D19B518F86982D61
-:10C97000B8FF312E7BA054A29A8FF8FEBDB892006A
-:10C980005FC56B40BB3D054AB5DE7EA013FBB234EC
-:10C9900045D1DBD54467C50EB12D4F325C874DE5DF
-:10C9A00067B5DAE46ABE2CD7CAFBCD02F7079CDB79
-:10C9B000795C7F7EAA632DEA91E6E16CF236D2A71C
-:10C9C000CD71E3437FBEF187E99B89CE611649872C
-:10C9D000FB0A4AFDF36DF3E0F27DAD79AC94DB7FA9
-:10C9E0002AB285C8179FDE765BB30DFA6D7C2C23C7
-:10C9F0004354D9A9D753F8F94766F15E267DB13B78
-:10CA000058423D3016F71E32FD7E3F9E87C4B84621
-:10CA1000C56ED3463C0F561106EB7CF8FEF8FE8E31
-:10CA2000D7917E8DEFE55CC47B34365C98819CDBCE
-:10CA30001A865CC473F63633681B2BFA41B63F91F5
-:10CA4000BEED64BCD7D2674923E744A13FF11D0C7A
-:10CA500009ED2DD8FDCC160EDB115F8EE55CFE1CBA
-:10CA6000B21C4E93F9B75896C3697A2E870FAC095A
-:10CA7000B760BCB378913000CFCB3129D48A2AC0BB
-:10CA8000807C9981FCC9F9B2CCD75596E778B91F5B
-:10CA9000CEFF81F239D71749ED1439FD53AAE310BF
-:10CAA000B72BCD990B615C77805CA3DE732CEE9E77
-:10CAB0008972E2E713A305F909F824B644C50735DE
-:10CAC0008D3FE8914F0CB902F18909CA3C151FD975
-:10CAD000DBFC134B7E0CFA554BE2752B99BFFEEB3A
-:10CAE00014659FFCFAF8FD53B97D7108F81114FF25
-:10CAF0000963185FBB1025519C74FE0A1824A060BE
-:10CB0000BEC19D8C7198F9F382280E56D252B92C71
-:10CB1000546A4FAF7B7DE9B4BF3CD19744E5C14433
-:10CB20008717E5659A6F928CC7F4EBDA9FCBB2F169
-:10CB3000B89BC165B26E88C7B89B43A4FDB8DECC74
-:10CB4000F214D929653F8EC7DD309E87F1BDC0FD47
-:10CB5000358CC3E17ADA14A5D3EC13B68BC70DD7A5
-:10CB6000EEA79535FE65B00EEA4FC5DB282EF74DD2
-:10CB70001F47505F98C7EC09AED70DEA7D36198F75
-:10CB8000757A7732DAD1BA4A8E9FBA556201ED379B
-:10CB900031163C5E755EF75A7C3CDB9748F851ECE9
-:10CBA0008BA2B77754D1A1CF36FD7D2DBB532EF389
-:10CBB0007B39F2BBB5BD9D51F835909F15FD6C8852
-:10CBC0006E213D7407BC82FE83A2AF0BF286E5A204
-:10CBD0009D1FF67262FD3B30FFD854470EE2E5B66A
-:10CBE000577B67AE03F80EBD4B6F09B91E7DF88306
-:10CBF00081F4E1A2F18CF421946A7D68E8C40FBF4E
-:10CC0000B5EF8DF1779ADC1EFC58EE1F82BE56F709
-:10CC1000373F75C4F8BED074525F6E277FAE717710
-:10CC2000A6C727F5BD313D9E278FFF5A7A7C565FF8
-:10CC3000AEC703F5366863D2DBE776F5A338D96172
-:10CC4000067A1EED5943B0B4395E75CEBD4BB84B74
-:10CC5000ADD77BF79F3E0BE97A1D7A7D36B6FB7721
-:10CC6000F57AFEF837C8AF823FFB5DB7C2FAE3370B
-:10CC7000B0BE43F85358DFC5B79787403908E47B07
-:10CC8000588FD41F80F1353DDD87E20E2007C4F7B1
-:10CC9000E5C0F728078ABCCCAD1F188EFB06EC1345
-:10CCA00091A1FE0F948382BC57F518A7423D8EF8E0
-:10CCB000DA03328F7A26D04EFCD8D7F12CF28F22AD
-:10CCC0000F8A1C5C9B8FDE36E0BAD450769EEB79DF
-:10CCD00028D57ABE337FE6851BE4FF55D7C93F6F61
-:10CCE000FCFCFCF3C675F2CFB6FF847F9246BE4BC8
-:10CCF000FC83FA13D76F777E6C0D5FC0F987CE2562
-:10CD0000023F6462DCB969706F2BC669EEBCC2FD7C
-:10CD10007AD0E9E4D707FAD55364FDF7801C2738A9
-:10CD2000986AFFBC2F9757F2DB8727060F447B7565
-:10CD3000BDFEDE94A84A6683E70F40A9D61326A459
-:10CD40005B07FEFADF6E90BE4DD749DFD37DFF63F0
-:10CD50003FEF52DFEBF0F3926CE68988CFEFDC7A9D
-:10CD60008678BAD67AC0B096E3B9CD5F77EB15BBBB
-:10CD700019897613F8E39FFF097F8CCDABBB68065A
-:10CD8000BA466D3116EAA1FD243C6B41F10CD31A71
-:10CD90005B12EA1BA6EC0B50BCE35351869DE69652
-:10CDA00091308E3B9F62FE7D03A81F951BDE161FF0
-:10CDB0001198BF7DE41643CB2A8A3FF0F32ACCE1D9
-:10CDC000D1F37D3219CE043854056707C0EB79FBE7
-:10CDD00030BD87F1731FF27359FF8CB3F07D01FFF3
-:10CDE0007E9E37BF2BFA7FF58205F717EECB3D67A6
-:10CDF000C478CED83CCFDE9ED02E654B7861483FBC
-:10CE0000785E2FD07807A7765BE34CA2235B363C95
-:10CE10006F5896CDF74D4C758DF9B60EF87070AA17
-:10CE2000D64EE19F3E86E263F467AA13983193F7EA
-:10CE300093107F7DEF23FDE8FD047ADF6D8ABAFE53
-:10CE4000F7EFC9653657077C345269877161A57F52
-:10CE5000A0C9C43AC1D651DC664C2A9797669DAEEC
-:10CE60009C019E0A53FBAFC1B8D728C6F96252EAAB
-:10CE70004D854E1E4762B680F95E6DBC433B98AF50
-:10CE8000A47DDF7D357CD95215B957DE97E95FAABD
-:10CE9000E59370BDFD83EF601CE1518205FDD4B9BF
-:10CEA000F6A0552C1CE92EF335CB2AB4E5C2FC8242
-:10CEB00098268ED7C6D76C70E1C834F9DE3ED567A8
-:10CEC000AF41FADB756DED399F37086DEFA7EA19B1
-:10CED0007E82DEAF4C1DB206E37E400FAA2738E902
-:10CEE0002A7C5E1700E706C805E330C925EA65C05D
-:10CEF0004F7207FBB74FC8F83D23F0F34DCD23B871
-:10CF00003FD79CC0CBADA9DC7F5B23E371BDDCBE0A
-:10CF1000B98B0A0FBDFC74863F37AE0754F3263C2D
-:10CF2000DD1BA5CC7B52E118985773041B20009F92
-:10CF3000BC943A61CD92DEFEF7B7A44E223EF1F7E3
-:10CF400057D88276FC5E194F5B53EF6EC17A3C7204
-:10CF500082F2569ECDF75F4DF5073A94B705EDF98D
-:10CF6000C789F915CA8991F03DC166C8E4FD2474EA
-:10CF7000809F5FB57FDF16F03E3344DDC8FB327D16
-:10CF8000C604D0AF20807E2303E0222DECF783A1DE
-:10CF900067F09F8A77AE5E1A83F1B32D02DDB1028E
-:10CFA000FD6C14E079E396070A43703D2A4A869E99
-:10CFB000D0F6C32DD35ACCA0BFC6A3FE227D5C4CB5
-:10CFC000FA7A22CA39C1D30B6D3723DF542E8D85EF
-:10CFD000F61F6F99B106EFBDDEB764B50191FEE9AA
-:10CFE0009692357AE8F7DECC3FEDC5FEF4D5A52D57
-:10CFF0006384ABF0696DC03CD607C0CE80F66BAEE3
-:10D00000A1CF9704BCBF28A07E5500BC36005EAE01
-:10D010007D7FDA0CBE7F390DE88788BB96BC7C9398
-:10D02000DAE617B4D92F01EDD9C75A7EBFB386C34C
-:10D0300067531F295C1EA282B72C2854F3AF41B658
-:10D040001753A2ECB68EF8F75067FC931A68D79C7A
-:10D050009A73898719D3D8DF3DA2166E1495F12EE5
-:10D060006D79384DB51FC89614E23E51E7FB158B1C
-:10D070000B71BFE2CEDF29F58B0B6DAAF929EDF319
-:10D080007FBC22E2F7F42F57176EA2FD3F79FF2EE7
-:10D090008297B75DBE128674C9C7F3A358DFC59DDA
-:10D0A0003C5F6DE7595D0ACEAFF1317EDFD05903A9
-:10D0B000F400392F6656DAFF6E0C0F5FF812B4DFFA
-:10D0C000F398B810EDD7E1859174DEA8B01FF7C7CB
-:10D0D000F684F7897910E0C6E0078C18576D7C7CE0
-:10D0E0001495EF8BB6655E407EFCCBB564C71B83A1
-:10D0F000C3092FBDFBAD2AC42D59A99F44787444A0
-:10D10000586276A21FBAD2C070FF8931EB0BC427D8
-:10D110004F98C84F9D56DD9FF67B8A7F3F3EBF3BB1
-:10D12000B42B5E6AA0F83FFCD17D0CC7CA5146AC57
-:10D130009FB1442E9DB753F9DE4F6F7E9C4EFB3A54
-:10D14000229DDBD9ED8B380E92CCBE760EA0FB0A69
-:10D1500047E5FC2A6FF773A4F583797CDD9A44F9DF
-:10D160005298450A9B807EDB4DB601FDA2FDEDDEA7
-:10D17000FB49A4FDAA775B8B63906E43FA717ED95D
-:10D18000ED2B8E2956D9F592337AC2F37B46E961AD
-:10D19000D41BEF75E92D38496EEB2231CE3A43F6B8
-:10D1A0009B814F16BED9011F26F513A9DF63A68503
-:10D1B00078169635FE263A17C7A5BC97D5E2A8C1C2
-:10D1C0007C31865ED220B57F7C6BF2883C9C879F49
-:10D1D000BFFE48FA9CFC6380C7BDFCE21A27DABC9C
-:10D1E0003DE0D7E338A26CF958AF9CC763B175290D
-:10D1F000EAB882DF0F5D2CCB3F6F77080F07C3F7CC
-:10D200000F6D0DA2735F879C7F0F55FBC78A7CCC87
-:10D210000CFBD5E1665A17874B421CF08DBEEAF82D
-:10D22000A3F05EC9F306D29B25CF472FF2623DD013
-:10D2300013B70C03BFBBA51F3F0FD0B97CD407C8E1
-:10D2400047FD55E5A3F4E5370B378574241F5531A9
-:10D25000C847F9CF1BE87C755197CA4918472CD2AB
-:10D26000DDCC6A607C239EFF450CEEB3CC7CDE44B3
-:10D2700074F584861EE7F3EA138FF36AB33FFDB8B3
-:10D28000BEF254E790BD1075E09D81FE16971968B7
-:10D290003D22C61849EF8961565EDF85C52F06BB62
-:10D2A000BC34345B42FA6E4679C8A27A09F92C2F55
-:10D2B0007CF21D78AEE5F0C244DA073B99C9F7C1AC
-:10D2C000663DFA6218FA9F871EE6E7BB6763BE1DDC
-:10D2D0005CE7FE9BFB5E1572BE9DFFAB7DAF67FA00
-:10D2E00005EE7BF173A07B16666472BC30C984784E
-:10D2F0008A1B4878B9DDCCA420C08B18C15250FFDE
-:10D3000028FB5EE22FB97E127502ADD38F55392905
-:10D310007F415E98993FFF25BFB7273E3D9ED13E96
-:10D32000585425ED8345C8789D26303BCACFD1207F
-:10D330006BDCBC34E4BF20A2E7CC17667DF16C2621
-:10D34000D26D6C94269E80FC17ED7FFF44F52D3442
-:10D35000BE1302B3A0BDCFFB43DF91489F46D1F17E
-:10D36000F4BDA4378369FF9C593C4F0C01786635A6
-:10D37000ACB319F24DF7B884347F3F33173F968230
-:10D38000F4CEFB43901BCFDFCC5812B416CF619480
-:10D3900035F07BDED3567C47E77159BCBE12E39C67
-:10D3A0005F2F09E2E7D4EB8710FF4CD3F1732E2CEB
-:10D3B000CE48F1A5B21019EE954DB0EAFE9211E9F2
-:10D3C000A1DCBFF918F50A7CFFB4820FF41B51EF02
-:10D3D0002AE7E859A584F25FA4133A3CE7F5553FE4
-:10D3E000EE9F4E8BB3D279D1F2DF9AAC8BE3399DAD
-:10D3F00045559EB9729D377F2DF6AB63D2760BAE45
-:10D400001F9A4B70BDCDEAFB521E820A3DD31B23EF
-:10D41000E0B9C4F599329E0A69FCEDC44F7A7650A2
-:10D420001F81786CFEA219F96371A8847191F2AE24
-:10D430005607F51B6AB6703B217F17C79E887CE0B4
-:10D440003346201F7C21E84C3CFF804D07F5E71850
-:10D45000AF6FFBCE921569346FB34537A23BF2DD57
-:10D46000F9FCB5F0DEED4C4AE88EF7C456444E9A0E
-:10D470008CF5AF89A49740987E9B8DFEDE6B62068B
-:10D48000AE53A7ADD843F39BF3C640BC41C0A6BD85
-:10D49000FE19D9A739327F79E4736BC500BF01A5A6
-:10D4A000FE266E271C22ABAC2358D0EC572AF5E59C
-:10D4B0002B0C448FF2A526A27379F55FA9DFF2D079
-:10D4C000E618A447F97603E5EF08BD49A2F6C5D5ED
-:10D4D000BD730FC2B88B0DE116011E9539C71A1125
-:10D4E0002EAB150856BE57BEE2F3185D1AEF0F4B70
-:10D4F000938EEFB3FAFB8D8E437B767A6B64DC34CC
-:10D5000015DD4F2FD91186FBCE4783DCC978CED7E6
-:10D510003B2FC88AE70A9578DAE925C9FC3E90A531
-:10D520003914F7AB673C9C188176EEB0C56DC4FA30
-:10D53000C375F178648ED92C965C846DFA9B093E94
-:10D540002D9F23A13FCC1F2870BE29DBBAC79800AE
-:10D55000DF1B24E3E7CC6B47F70E457C001F5950D7
-:10D56000FFC435A7A01D2ED735A7F444FABC2290DE
-:10D57000BF00EB531BE61F998B7C3508F4A1CC57F9
-:10D5800073EB772C40F92C7FEB643EE2F5CC5866C8
-:10D59000C4F858B93C7F583F7EA087F6E5DB36E4F7
-:10D5A00033FEFE07C8778ABD07788901E026238706
-:10D5B000336EE2FCD364F450DEBBA6498CD1FE99F5
-:10D5C0009E8DC47640797E0F4014E5FB6995B113BA
-:10D5D00078DE3DA7FAFCDC5CAC4FF3D777C6378525
-:10D5E000325F14579BC82E15CA78F1ACD81E867CC2
-:10D5F00071E6B53D7B87A25C6C132C4C2D0F8A1C09
-:10D60000C679793DE0EF49C4DFB6F3F998876276D1
-:10D610006BA8843454F0A4C89B82970AC6F1A0E09A
-:10D62000A5422FE349AEBF5BC64319F3527FAC75E9
-:10D6300080B419FB7FEB07DA6F3B338D09FC9C301C
-:10D64000CF8BA6CCCF11A1DDDF5F26CF6FFA4DDCEB
-:10D650006E9659B85D2C8B6252F540E2339B51C9EE
-:10D660002F094DCEBC714433FEE7653968A337CE30
-:10D6700003C6E9D1F17B8281FAEB51197F47AAA752
-:10D68000B851AFCC76423F99280F96A9B8CFC95E62
-:10D690001765FD0D32A9FA6EDEAB47880F41774959
-:10D6A00011B066316C8171A0FFD5DA9BE28579DD1E
-:10D6B0003C34EFCD632C4C07FAE488E009DD89F6B1
-:10D6C000E05191F494324E9BF363A287AD8ECB2749
-:10D6D000F20BC60715390D1CEF3279BC269DD58398
-:10D6E000E782D96281EEAF898BCF841EE4F68E2269
-:10D6F00089FEFE6FF900F7236D17C324816AAC7AA7
-:10D700006C37F7625802DAEF2372DCE1C8D21D6190
-:10D71000C52A3AACEBEC3BCB864848FFBC90838FE4
-:10D72000A11C3D759320F3BF75E442D40797C22432
-:10D730003C2FD514E14C433FAA49C796B308CE8786
-:10D74000FA183FFE405E087F502F3D65F1CBA532B1
-:10D750006EA09B1BE906ED6D5C8EACB48F31378AF1
-:10D76000EF8B5E5B9E323CA49FAA056963A6BF9DBA
-:10D77000722FEF7179DE2423317E7B80FC89F6CE17
-:10D7800024E7310ACC837A7BAFAE7188BF8A10B3AD
-:10D790000E977081F581B07F3D55A9473F9F2D8938
-:10D7A000DDABBE977634C849F7CFBCDD45B611E88E
-:10D7B000513DEF237E9EB781DFDB52EC34FCAD6A36
-:10D7C000E33F78AF34F37C3EEAD73FE698E85E5318
-:10D7D0004C7F7EDEE514AB330E47FBFF6D737E9806
-:10D7E000E45F9FDC72D12D8693BF10AF591F94B5B3
-:10D7F0007E40F25CCE9AE93EF6B4159F8D1D82F410
-:10D800007ED940E70766D4C6939D3BB9697A06CEB8
-:10D8100077DAD26482676D7E90C32B78FEC3694B42
-:10D82000B35E42FFEB68902D1FF9D9BB5AB0E0FA06
-:10D830006AD8E6AC45F741FDB0D03E5D71DC873675
-:10D840001D1D8B743FB45024FD64DBF4D424ACB7AD
-:10D85000ED14F1C618AC672C8B30AF29D3875BD0A1
-:10D860002F50CE17D618B8BE3D2FEB87936D25E706
-:10D87000D3BC9A9A14F497BC1BC01EE1BEB7D15B0F
-:10D8800042E7BB058B7523F0CBB782936066B1246A
-:10D8900054E7E07D96F5941FE75CB2C9827EF2FD05
-:10D8A000266645BFF6FEF77A0FC2A5824D5E578DFC
-:10D8B0008DE4DF55F0A57CDF2BF33D135795D0BEEB
-:10D8C00043A49480FAAD493E377E541EEFC9252FFC
-:10D8D0004F42BFE0E496E408A6C2FB49394FD32C7F
-:10D8E000D083DB3A58EFFD7893127770D1774AE511
-:10D8F00078E03E436D2FCCFB1978BFEBC486203314
-:10D90000E6E70DBCE775C2C0ED47BBFB5E3BB570FB
-:10D91000609EDBC0F12865BBFBFFFD433AF4E315D5
-:10D92000390B7CBFDD7DF2A4EB3B5F8579C9F0BE8E
-:10D9300077D34D8CC63932F8C737515F97D49A2CBC
-:10D9400078FFFE589044EB2167169336A39D314B28
-:10D95000E1B89E3FB62F83CEFF957CC548AE4AEA1C
-:10D960004517A62AFE6075DFDFE502FC60BDC18AAF
-:10D97000EF9F5CB37A1217336D9E856CC6E57326F4
-:10D98000AC93DC16FFBA2870BD347BED1B748FF0AE
-:10D99000E75A2F2971A4407CDFDA5FCE4FDAC9FD48
-:10D9A000B9F7806DB207B5C7776B9583D64567AB7E
-:10D9B0004AA9CCA9DB90D753C2FB14477E3B0CE5A8
-:10D9C00026349CE221AD5595B489777667C665BC4F
-:10D9D0001FFA6E48B805F5C5D9AA85F2E502994F38
-:10D9E00064BEBCA5BE51ECC9A87DC33068BF3B2452
-:10D9F0009CEEBA24D9B2C3D1CE2B740DBCDFACCC13
-:10DA0000EFD4A39CAECA784F6D991E867E67E3BAA9
-:10DA1000C8869C283C9E1B6E417F7BA67CFEE5F859
-:10DA20005AAE6FBE3587BF3406CFCFAC9F1883EB9D
-:10DA3000BA070D5EA315FAB5EE1A1F8671BC6FF416
-:10DA40009E30BC6FFC0DB477A39DD0BB44D4734310
-:10DA50000B18EDE30D75EB99144F5BE6C41739AD68
-:10DA60007A17D2F5B4FBE29E2BC847AD3A8A77010C
-:10DA700066F65C81F6D6D03E14277CF06DBEDE647F
-:10DA80003F76E1F501F7169FE9CFFD9613EBDF1C1A
-:10DA900047EBF34D060B8EF3ECA6CF63F01CCE6C78
-:10DAA000C6CFD77FBB45A079CC067E0C8A47FDC088
-:10DAB000E3A0B341EF9B85F67C98B7A59AF8703642
-:10DAC000F021E6F59E6DE3F99867633E6689B5CB74
-:10DAD000FFD155E6BB39C077787FF7E7CEFBF13B46
-:10DAE000850F03E45EA1BB821785FE7E3E649AFC2F
-:10DAF0008211750387F7647E7DA0DCEF607ACF2A00
-:10DB0000BCA7B1400CADC57C55FBF5957FA0BC2DE5
-:10DB10004E3DDB4CF69CA562BEBC05E24D568C0723
-:10DB2000D6182BDBF2BA607D605E173184BF3F1ED2
-:10DB3000F313C37CBBA6C5D3F72658ACA310DD8670
-:10DB4000280FC505C43C9D8DEEE5D59868DD1CA861
-:10DB500087EA64FADE95C6F5D0FFF4E7E7B5957B72
-:10DB60007F4A099AB137F2FBF8E0884B1234D9D5D5
-:10DB7000FFD0DDB84F3B7E58C42F12E1FB7B5F3DE9
-:10DB8000CAE18C88ED090037F5FFFA6EBCC731FE9B
-:10DB9000E6882C03FA01D5C7EE1E09F0F1FEB67730
-:10DBA000FBABBEA3F40BCF77E3F37FC439DEEF4FBB
-:10DBB000CFBD2548EF734218CFF796E4A538A8F2F9
-:10DBC000DE01811D7E57F0C31E038BC3BC06FF839D
-:10DBD000BA3BBAF3B27B9AED63FE7DED73A4D077C6
-:10DBE000B8CE94F77F7466C988FE9FDD6AB4F2FCF4
-:10DBF0008ACC6E06BFEA2E997F8BCD974792FDADFA
-:10DC0000645613263059AEBD8FD5CF7F6F6FFD8D13
-:10DC1000DCDB634E9E87AF46CEC3D7D93D4AA1E138
-:10DC2000A31FD0BF0CBC3F95F149F35BC827E3802D
-:10DC3000AFD05E643673F82E994FCA778CA57CCF2F
-:10DC4000F30F185CE827CC92FDB12447172641BB9F
-:10DC50004B20BFA8175AC7B953507F9CA862B5493B
-:10DC6000A0B00ACC8E4BFD014F4DF11F515EB41395
-:10DC7000EB6BC2D0EF3903EB8931D04599ECDFB3C0
-:10DC8000CBA2FB36F483E3FB6D5CA9E2B79F643E55
-:10DC90006B8D77C7E1FAC6196FE2F91A2FEFA13C35
-:10DCA000CF0509A3B3308EB4BF6A273B9AEC7FAF90
-:10DCB000B3FB284375230C69AA7DC971FA8ECF691D
-:10DCC0009C51F2696EE2F6DBA4AFA53C5A40CACA89
-:10DCD0006A82ED14578A451EC5F8B0F410C1CB66B0
-:10DCE000310BDD63F5EFD3D17D5085FE36EB959199
-:10DCF000D86E1CD01FF58DCEECD5236C2FE0E753EA
-:10DD0000FA01E1509F28F41F252EFA2DD261BE7C26
-:10DD10008F6BBE50C9618399CEB906EA478C6B16EA
-:10DD200091DE74EECD417F0CF424E55590F5A2040C
-:10DD3000FFA3BC48D91B8CD4ECDA7991F6E6FC073A
-:10DD4000FA31234D9B475CA193E25F754627454F0F
-:10DD500002BD86A5455F3FBD943C65F39FE7F1CECC
-:10DD6000F9CF4F8F1D44780389437F28ED4F44C47A
-:10DD700099F21CD8FA48E263C308BB84FA76ECCE69
-:10DD80009E4C8247B3760A74BE75CCCE4882C37C63
-:10DD9000DD795E25D9DE8FFD63B711189F3CF9D27E
-:10DDA000DF1FC6BCF7637EC3287EAC0B0EA17C13BD
-:10DDB000E208398F8318F221DE63BD20F1DFA1B0C4
-:10DDC000B376F9037444FF267E4E1656794E4E27DD
-:10DDD0007EEF6FFE3E6EE7E70FE7FB8217F00D6800
-:10DDE0007FA150A43C4DCF04A793FF5673B781EE9B
-:10DDF0004730A7ED2FB8AE9A2CF383291616962A32
-:10DE00007A054920AF2AFA3C1EF4DB0F1DD0BF076C
-:10DE1000D65D420FC682532334F57A67D037983FD8
-:10DE2000D6102B5A5C30FE506B0F4D7F76B1CC80F4
-:10DE3000F114E6E07EB4C25F4C6CD5D3BDF95C9EB4
-:10DE4000BFE2EEC9DA7B9286DCF323C9DEE46AFD29
-:10DE50006FFB35F236FD4AE1A77EAC9F9C979EECA6
-:10DE6000FF85167E3F4462F6B58ABCA0FE07EFE64A
-:10DE700019C4CFA42603734984BFD7B0FE82D364EC
-:10DE8000C178409B1F9E04EF45A19134139F635EB0
-:10DE900050F53C312FA81A2F9817540D635E50751A
-:10DEA0007BCC0BAAAEC7BCA0EA7ACC0BAA86312FDA
-:10DEB000A8BA3DE60555C3981754DD1EF382AA6142
-:10DEC000CC0BAA6E8F7941D5F59817545D8F7941A7
-:10DED000D530E60555B7C7BCA0EA7ACC0BAAAEC7C9
-:10DEE000BCA06A18F382AADB635E50753DE6055557
-:10DEF000D7635E50358C7941D5ED312FA81AC6BC59
-:10DF0000A0EAF69817540D635E50757BCC0BAAAE51
-:10DF1000C73CA0EA7ACCFBA98631EFA7BA7D335B78
-:10DF2000928C766C77BCE37FD268DFE95BE2E783B3
-:10DF3000F7033FA31C364DB450FEC21B5C277E9EE8
-:10DF400026EFF7C8FC7B89854CC573E89DBDAFF013
-:10DF5000E7EBB2BF01F66039F12F0BAD457FEE71F3
-:10DF6000BD8DEE4339EBF8FD44A6E77EC00251F6C5
-:10DF70007FE4BC100B4489FC00CC1DAC578DA7ABD3
-:10DF8000CDCCF42A3C4416583470B43D56D3BEDB95
-:10DF9000644953DFDD91AAA9EF596AD5C0BD2BB3FF
-:10DFA00035EDFB2CB469E0786781A67DE272BB0693
-:10DFB0004EAE9DAC69DF77AD4353DFCF55AAA9EFD5
-:10DFC000BFA552030FA85BA8697FF34EA7A67EA04A
-:10DFD0007BB9A63EA3A956036735AFD5B41F72D04F
-:10DFE000A5A9CFF16CD1D40FFBB64E03DFE2DDA9BA
-:10DFF000697F9BCFAD8187B37D9AF679E6031A7866
-:10E0000094E54B4DFBDB638F68EA474B2735F5659D
-:10E01000A7B97FCF6A607D8071CA109E5F63AE9B97
-:10E02000D5A17F7167EA794D7B4314AC17807FCA15
-:10E03000411FA2DFF77D9738CAC7CC2AC3AC78EF5F
-:10E04000DB39A2F20FEA7BDE63AD3F68BEFF4C70A6
-:10E05000983B88D61766B2B7230624907D6CCB27F1
-:10E06000A2DC67675E161B4521212FFA4702FEC21C
-:10E0700012C061369E171AFC20F29F2CE017A1BF38
-:10E08000D9B62ED2C5C7A35D0EF6FBC5BDAEA8F2AC
-:10E09000BC5CCB2FA66F67519EDE5103301E5EF72E
-:10E0A000463EAEB36631E732DC4F54F22CEE0FD26F
-:10E0B000C6B79472B419F0ABFADEBEA0DA5E83AED6
-:10E0C00022EFA3CDADD4BEAD5F39FE25C064E7AB72
-:10E0D000FAFF2DACFFF420D7B555207FE00F3D5956
-:10E0E0006521784D552CC14F574954AEAD4AA5F224
-:10E0F000B92A2BD5AFAFCA26F8852A1BC1AEAA0212
-:10E100002A3756D9E9F9A6AAC904BF54E5A0724B2B
-:10E11000552995AF545552FDD6AA8504BF5EE5A496
-:10E12000B2AE6A393DDF56554B707DD55A82DFAAB3
-:10E130007251B9B36A0B95EF54D5517D03F86F084E
-:10E14000EFAE7213ECAE6A22F8FDAA66823FA83ADF
-:10E1500048F0DE2A0F954D55DF52F9E72A2FD57F7B
-:10E1600052E523B855DE87583440D0DCC753603DB4
-:10E170003BC6FD3DCC5B817918B20D67AF961F376A
-:10E18000900EA7E4FE0D23C05DC238728F948D35CA
-:10E19000AA75C5F201DC5FACD6F1FC2DD53D98A582
-:10E1A00086FC761BE3E7B4B8DF3E13FF25C1D3A896
-:10E1B000AABDB8DE28A9E479CAB3901F53891F3FCE
-:10E1C000B9A1759ABC2ED891687F6600AE43425CB7
-:10E1D0005FC467FAEFD11F4C743C877C7AA1F2C10F
-:10E1E000BDD87AA6C59A821F196B724763FE2FEFBE
-:10E1F0003ED1BA51EAFC7B15F2FD874EEB779FECDE
-:10E2000085F6AAE02791E2FAFB0DA193719F7FABFF
-:10E210008C8FAD03749AB228C9FE2A8EE74472E54A
-:10E220004B0F09FEFBFB77E1121FE47B3C93280FA9
-:10E23000CE4466FB105DF0BBC11144F81EE6A4B2EB
-:10E2400035C1518FEFDF0B0B10841D434D711DCD78
-:10E2500027703CBBE5F1EC96C7A1940B92ECBB1088
-:10E260006FC7926D9AF16C95F3338C63DE17705C17
-:10E27000FFDC75FEB890E8C7775B3C8555529E8CF5
-:10E2800022C6E3298F635E8C287F5E0C65FD50B447
-:10E290008FFFCE11FDA1FD5C104FEBDBC0BC19CB95
-:10E2A00086EFE17930603D86F77F8BE6FD82F42FC3
-:10E2B000FE1E14DEDB5DD0E530E599F1CC025EEDAB
-:10E2C00049793578DE1B0720B027E5D5A07AE1260D
-:10E2D000F87F771C9739554FE3EB42F94E9E09DEE4
-:10E2E0004F796930A660EA8A798F79BC66BFFD3CB8
-:10E2F000F7BBA3BC743F7547A2E3EB013C4EFE7431
-:10E3000006C689909FF03B16179D5F037E320A80F8
-:10E31000A29951C04F1DF81B0ADFCC95EFE128CF21
-:10E32000811F5B11DF67DF1E928A7C53B13B47423E
-:10E330007CD7E8F87D3AE79FE57D41F9F710C4F016
-:10E34000B40D74EF009D71A46F4E28DD3B6814D9A5
-:10E35000C2373AD0AFA1E95CDEF7C7F27C92350153
-:10E36000FB93C6744E77633AE787B1EFEFA33C6443
-:10E37000739B78BC9A657AD2EC1D9CCBAA58F89B0B
-:10E38000A79354F3A8D879849FE7629E34F539AEF9
-:10E3900064F9FB0AFF89C650C78610F5F878FC01BE
-:10E3A000E420243D8BE4E038DEEB1E6792C2EF11DF
-:10E3B000E8F7C1CE627E19C71F2C741E503917387A
-:10E3C00083D9A99C099613F9DEEE5C4DF7E767B394
-:10E3D0003A7A3E377B7A1CC215CC3B3216D747CBF4
-:10E3E000AB3FC470D0C4DAD5A3BAC3BC26B8A67DEF
-:10E3F00088E5F84DC271A74472D43B1DF7B785CAB2
-:10E40000A53DE07BF76D1DBE14E3D6E3444E07F651
-:10E4100031A74311F0B318D17E7E203749E95C6EF5
-:10E4200068FC8ADC142D66363C7FA0DC0F6993A360
-:10E43000EC39FFE8897B38E04F22BF56EC3645D0F7
-:10E44000FA14F3CCA0BE92E567A99EFB974E4C6DE3
-:10E450004AFA93FB1B069B9CCF8B717F648E93AF14
-:10E46000C74E19B8BC9D3A14EA42FE5ED0E5F538B5
-:10E47000920F83221F3F4DA5F33D0CFC8F5BDBFB0E
-:10E480001F6D79667A31F237589C237650A2DF9E51
-:10E490009FD2B90687F1BCFCA3105F7B63F9FA79C0
-:10E4A0000EE6A1C1FAAE7609E3A5A7A2CD745F2856
-:10E4B00030CF1963569A9F419E1F8C6C32FAD32637
-:10E4C00039AE561330DFEF83E268BED27056C7D044
-:10E4D000B1D05B9CD351EE1FE2766241975F3BF077
-:10E4E000FB9E20661186D17C281EEBD4317B0D8FDC
-:10E4F000CFD2FC16EACD163C97B36C9AE811C84E01
-:10E50000C038319E1765B6F2BCAA4AFEEDC0F1DAFA
-:10E51000B4E333C7319C9F4D64DEA0617CBC383EC0
-:10E5200027D083E803F034D5F8A05F17E5FF0996FC
-:10E530002CE88735FDF8108F2F5773FF11C6BF8564
-:10E54000E8D31DC6DFF3DAE337208BC2F817A4C780
-:10E5500013DFD5E00EA28876B62BE9DF0941F64736
-:10E56000900F931C2B7BCDC7B8468EC98AF13B76A2
-:10E57000B9A617EAA91026515EAD71369E570BBA9F
-:10E580005B82FC301EF3D659C80F6855E761630102
-:10E59000F135200BC55727607C8DDF25FA00E3B3EA
-:10E5A00013E5F3CDFDD8570AFE28BE26E2F8285E13
-:10E5B000EDA0719A90B25006619C87E8E0A27904C0
-:10E5C00033B71CCF6E26FF60B5CC87430F32B21332
-:10E5D0004343B89DD87D84B9F0DC57E30F93F242F2
-:10E5E000A17EF7793DE929C013E5037CE7736E57F7
-:10E5F000769F3CDE13F703AA7FD8DB13FDC4DD064C
-:10E60000875881EFE7982C8BADFEB846C3C1101E2A
-:10E61000D791E37CB7C8F36C60CD3515509FDD5DB5
-:10E62000641807CC6A7107A33C638EDA8EF61B73FD
-:10E630002F1A35BF6B61B068E16CA682E3F1E85137
-:10E64000C0EF7FDEE03A775BBAF6F729DB7EF7B3FF
-:10E6500035EABA7EF733539EC7AA74FBBBE964D789
-:10E66000268832DE05C417E88146C4F773E546FA0A
-:10E670005D83C67263778F6A7CB5B3FE49F87DEF20
-:10E68000C77F92DD7A2F4BC98F531784CF8DCE5021
-:10E690008ABB3D77594771B775A55FD3FAA4369BFE
-:10E6A000D1EF88D55E2E263FE05201C34D24567D22
-:10E6B000EBFF9622FCBB5BCCF4BDC0F1EF027FDE2A
-:10E6C0000D847A17FC79775FC6DE067F1E61BCCFAA
-:10E6D0008AE576F0E7B174813F8FE50BE0CF633BCD
-:10E6E000F4E7B17C0EFC792CD7823F8FE5D3E0CFE5
-:10E6F00063BB35E0CF63F924F8F3F81CC69547E314
-:10E700003AC8E8DEFEE2E0B015E86748CE50F237DE
-:10E710003EB50DEAE251D9D95B2FEA3474CE6DD5FE
-:10E72000FEBECDD063119ADF3FC9FEAA87A67E70D8
-:10E730004B82A63EDEA9FD7D9B3E0BAFFEFB363D28
-:10E740004B4704FC3ECE1D01BF9FA3FD7D9B68FB94
-:10E750007D01BFBFA3FD7D9BDFC9F932153AA648F5
-:10E76000AF05215FAC2B9D10CE3AF02F94F2499962
-:10E770001E0AFCD4A3E2E48EE2C85137737BFFFE8D
-:10E7800021D3BE4D80CFF758B81DE3EEEFD974A466
-:10E79000979E5B1B4271589367E849E49FF76C4C66
-:10E7A00042FE79EEF2882E389EE140467CDEB3943C
-:10E7B000DBA73E374BC4CF3D4BBD22DE17BDEDB2CC
-:10E7C000D78AFCF85418FF9D2DE8D7B518FA7B7F3F
-:10E7D000ECE07E18C7792E04F819E5CDED0D4E0258
-:10E7E00038FC8A8EA17E045B4979FE9DCF86C8E7FE
-:10E7F00051AFD07DB870D4E9A097DE2BE5DF4FF1A3
-:10E800005C0E56FB43BFFBE95A7861C4579DD6DFC7
-:10E81000313B01C7EBC73BA84628535829FB2DE2E3
-:10E82000A38CCB4F6DA98EE4E912C813E207664DA5
-:10E830007461CD5A797F12E5434D87B2841538CF84
-:10E84000E7D6E869B76C94B875DFCDF0CABA16910F
-:10E85000B6D9258B37B823FF4E19F73A1B9F5F8433
-:10E8600095E9D0CE45003E5DB49F6DAD56FF9ED577
-:10E87000B3B27CFE5E96CF67647EC0F536C2A3C499
-:10E88000F5A353701CD95C5F033D05BC8F75690609
-:10E89000A3DF11FD7D6142978EF27CAF91C7F182BB
-:10E8A0003CAFF5D82FC93397FB5162D170EC679D0F
-:10E8B0009D911E5F67FBBA1AE376970A79BF7D16B2
-:10E8C0007904C46FAF4AAF80FDF77ED84DA54B1ECB
-:10E8D000678FD266AA57FA93AC2ECEEF655FB32648
-:10E8E000982F1EB215C95EB4527ED4757A3D433B53
-:10E8F0008CFA0CE14B663D9E91603D661D63789FEE
-:10E90000B936444FFB14EBE69E2278B585C361CE41
-:10E91000CA343C7FF1B63C9F30A7936057C07C520D
-:10E92000A407C2D5BFE71A58EE90F1BC5DC6C7DB9D
-:10E930000687EE028C63C85F45FAFD8ECEDE53EC8F
-:10E940006CF657BA00FDD34523FFF81B7BB25DF888
-:10E95000F5CDB87E76DAC92E28EBB6ED63B87D5DCD
-:10E960001D3CF5635CF717CA7CF44CF0B80FB1FEA0
-:10E97000B3D1FC77701A47DFDE5BAD2777CAE3DEE1
-:10E9800021E33DC7693BF430B41F6F37E1C8C08C49
-:10E99000D97AFF02FAB38F11AD6EA05B4B96220FAE
-:10E9A000F66094BBF7C74C6707B1FF02BEEFB4BD7A
-:10E9B00060223D9798FDCE01F0DE5F9AF5E4CFC06E
-:10E9C000F3ABCAE37E19FF9FC8E3F8B38CFF269927
-:10E9D0004FF7A21DE98B7196542ADF97ED885BB63D
-:10E9E00023BB653BD220DB91B7D18EF4C5794DA610
-:10E9F00072BB6C4732473F457ED225CC8B2BA01D86
-:10EA000099CB96C138F361FC6207F6EDAE6C31E04C
-:10EA100077B2823574BA333552038F967A06FC4E3C
-:10EA20005762C0EF78F5D7D4E79933027E076C9828
-:10EA3000A6FD6DBE1101BF23A6B523438F4DD0FAAD
-:10EA4000335FDDA7A91FDC52ACA977E23F60BE5956
-:10EA5000C718CF2F1B9CFB04F24BD671BDF2FBCC29
-:10EA6000B48FA6F85B81FE4F166BDBC7D3D13E9EF9
-:10EA7000934978AE93B6961334F5E43FB518EC3D60
-:10EA8000F1FC61F578E03B3C87D8523286D13E3CC0
-:10EA9000F02FC85396FDC457946F542CCA203FE9F9
-:10EAA000A25EB39F9613B02F661FA9DD37CBBAC6FF
-:10EAB000BED9B19B3BF91DF6D688EBF2C7409E4408
-:10EAC0001CF733C153F720DEDEFE92DBA9C62F1FF1
-:10EAD000E989CF3FC0A6D0CF8E6F1E21BF6B479B69
-:10EAE0007C3882D5FED6760FB7176FB524ECC47587
-:10EAF0004666B4407A30F3C8FC29C48F2D3AFA7DBB
-:10EB0000CE94828A60C4CBF6838B83B5F7A754FA80
-:10EB10008108A5D20F22B232FFBDBEFF07E9D10F97
-:10EB200034008000000000001F8B0800000000007F
-:10EB3000000BED7D0B7C14D5B9F8999D7D25BB812B
-:10EB40000D09B08104260960AA3C36EF4D48C22465
-:10EB5000048C1AC8427804C1304978A48A9AAAB5AC
-:10EB6000D86233211062A4121F55B08A2BADDAF699
-:10EB7000F6B65425A0A22CCFAA5058306844D4052C
-:10EB800014ADA5F7A284D6F6CFFFE73DDF77CE24FC
-:10EB90003BC32640DB7B5B7B6FF8E9E4CC3973E653
-:10EBA0009CEFFD3A134208F94AA4FF8B1F4E0269FD
-:10EBB000047FBE4A81FFA7F4B6A19F5C4D02F6F028
-:10EBC0007686A19D6F185F62685F6F183FD3D0BED5
-:10EBD000D130BE56D7BF2D3473A0E2A4BFC3CFA49B
-:10EBE0008BAF5B1A09095CD53B2EDBEC133D632F21
-:10EBF0001E97D369EA9D97FEB7F3FD25A6F3F1842E
-:10EC000074748A7E5B32BD1E5F42D42C3A4FA7C912
-:10EC10004F04BC9A08EDDFD6C5DA36A23AC6D3FE59
-:10EC20002D9D664F9B44C80EFEDE31BE85037D31AF
-:10EC3000844C329F8DF85EF982A9777F04E69B3978
-:10EC4000904418A75D77F179038D76BC6E6F74914F
-:10EC500080ADB75F8CC9EEF4D17574844C1E7A9B7D
-:10EC6000AEBF248ED07DEF762E76C0BC74BD840CF2
-:10EC700023E4DACD23AA9A461122D1759BE83EB649
-:10EC8000844CA48DEE33EB287B7F96458E734580B4
-:10EC90002B21263DFC2F9A8FFE009C9CA2BF8DC28B
-:10ECA00065D7FB73E2C6D3F95FEA1409ACC7AAD4EF
-:10ECB0003B7CE368BB8BAD4B9B77B25DD4C1A19825
-:10ECC0003874F8283C3B48D7CE3A41D7499FB74AD9
-:10ECD000157100DF4BAD939068031D0D32B487E9C9
-:10ECE000C68F9128DEC6F58D8797381EB6001EE8C0
-:10ECF000C65E8AF254F922C06BCB07D67A7FD8FD64
-:10ED0000660F054A365C4D78CD3A61F204287CCE18
-:10ED1000779A3C00BC3C57BBD810619EFC8FF4F442
-:10ED200099D319AD83171117F4CB07CB8F37ADD912
-:10ED30001336FEFB9E98F8D3D7D05F72492EEEFFB4
-:10ED400012CFFFA9515DB3C742E99892EC663A8EA3
-:10ED5000B82A0949E87B3C212B717F1A1C892B8E2C
-:10ED60006EEE72F0D48ECF5D84AF3E9EEF9D472550
-:10ED700064308527052F8C5B3BDEF7B887B6496882
-:10ED80008608EF7FD0719B18A2EB7ECC71DB6EA062
-:10ED9000CF037FB64AC0D73BFFDC9108F7F7A76FD8
-:10EDA0004D04BADF4FDF1D84FD9929D668DBAADE4A
-:10EDB000E400FA7AB3F308F28F4482374CC882B683
-:10EDC000C9D34687BD9A563990F403B7D7399DEC1D
-:10EDD000E3FCBA87F3EBAE4637E76309AFAF35A67E
-:10EDE000E1FDED8D1E6CBFDCE8C5F6B64619DB1DF6
-:10EDF0008D65783DDCE8C3FB871AABB0FDDB46854B
-:10EE0000D161DA9DA5208FCE275200D07DAD744C04
-:10EE10003747C2E775929ECFAE75EBF96C0A8573E2
-:10EE2000787BB27DB8812F5375FD93BEBC5AD75FF6
-:10EE3000783643D79EF869BE6E7C5EA844D7CEED87
-:10EE4000BA5E377E6669A5AEDF57305FBF3ED189B7
-:10EE5000F265874B40B93C3DAB4ED7BF037E0139CD
-:10EE60006C17FC6A32C0A5B25F791A00FCD8008E1C
-:10EE70008C8F7FC3F1B317F06303BC30F8BF0AF087
-:10EE8000A7ED5700DEF49ADDADEC1E28811CA8C763
-:10EE9000B6356DA0D343E1FFAA5344F9BFB5B10124
-:10EEA0009FDB7FBEB65BC4F53A24C0CB0EBE9EFD91
-:10EEB00016A55B8C87B620AD142E5E5776979EDF25
-:10EEC000C7942D44B9B9A3F3A403E8EDB52F2F4F90
-:10EED000EF69E37E432A27037D1475525D957C69B3
-:10EEE000FDA7E9AD4BCDAF8D03BD1A495F18E7BD56
-:10EEF000FE4B4524741FAF76A90FC7403BF04D5120
-:10EF0000A2ED9C2E6532E06D4F9AE012051C375938
-:10EF100086755F387203DC7F2D6436C1BA0F5C18CA
-:10EF200044601F3BA8DEB5D1716F92D4B51328BCE5
-:10EF3000035D5FEC07BE549D16CF6872F13A52D361
-:10EF400045942B5BC6DA4CC204D0776612180B7C52
-:10EF5000AE203C3BBE4C71C2754B9AC8EF0791DFA7
-:10EF6000C7A7BBF0B9572F64C443DB4482280F0204
-:10EF7000DDA6327F84FD8E87F750B9937DE143870C
-:10EF80008B8EDFD75DEB00F9F25A179B3F7B45C8AC
-:10EF90000170DAFFE52627DCDF919689F3EE1CB7D6
-:10EFA00014ED8B1DDD26A4EB1D63D73833B2709FA3
-:10EFB0001E80DD8EEEDAB5E940D75D666C4B4421EC
-:10EFC00041A0B734A667B774D79223B4FFBC47F407
-:10EFD000039D6593F67D03E0FE90355692C2E06F87
-:10EFE0001E42C8ADEC6132D9A59703255D7A7D62DA
-:10EFF0000D2D983503EC08A067DA9E668ED3F5EFE9
-:10F000007F7765FC4CC00B8537DC7BADFB8EFDE369
-:10F0100040FEF859FB0FC77F621D48AF4DE3D60C89
-:10F02000BF0DC66D71786C12F428E40BDACEED36A4
-:10F03000FBC1DEC876EAD7B1FF1B9508F72DDDCC02
-:10F04000BE3A9FC6F6B3C353471EA0CFBDCAEDAFAD
-:10F05000C9274695C3FB0E50FB09EC8A573C2FC4C9
-:10F0600065823CF38A3A7AA3F0417A39DF49701E0F
-:10F07000FA33601A8543011B42F9D0D77C3BEDDFA0
-:10F080009F6773ADA4A8DE7161D7EE3B683B374143
-:10F090002422DDC937FDFAF5E5FDD4A16BDFFAA91D
-:10F0A000DE2EB11181EB7327CA81BEF867E259AB3E
-:10F0B000EEB969669B6EDE5C12D68FF8B4F6F62761
-:10F0C0005FDA3ED9CAE59A669F6CB528F37D40D7D2
-:10F0D000C15997D0A32BB9FE6D4079B18D104F5B0C
-:10F0E0003A95EBDF1065E0C3F3C7ED08C7DCC766F0
-:10F0F0004C24A8AF9589C00F488C61F680F7F8259D
-:10F10000EC15974AE273F8AB085CCDA743747C2BEF
-:10F1100055F35F810EE7FADC386F5F7AFF41C70075
-:10F1200094FB05A54C2F3CE638887ABEE37DAAE720
-:10F1300005F68E10C5FB6CF805F4FEFB561CFFCAE5
-:10F140007502CA11CD6EA824B285AA3832DDDB6DF6
-:10F15000FE01C59FCF5E3DEE567A7DE5DD8EE1C0B6
-:10F16000BFAF807D80F2A1C1C1EC8318358E2E71B6
-:10F170007B970DF970EB5913B183DFB0DD86744ACC
-:10F18000F9F4FE71F43DDB83CC5EE838CBEDBDEDE8
-:10F190000EE4939D7F60EBE858E1607EC619AB0CEE
-:10F1A000F6F8D6153108E731524CC00CF32D67F351
-:10F1B0007771BCBECDF1BA9FEBAB37B8BEFA0DD8B4
-:10F1C00013A8BF983DB11BEC097ADDC9ED891DA0DC
-:10F1D000CFE8F5C5B3CFBF077C797E7B14DA9D639A
-:10F1E00048DA6658D776A715D76984F33C45CF0728
-:10F1F00073ABF47643F958BDDD70FDA8E1BA7659DA
-:10F2000062AAEEF9A9F1D7E8FA4B9D997A79649E42
-:10F21000A86BCB17F4764385F7063D3DC9617603AD
-:10F22000CA3BBDDF383BDC6F4C063C313F676BD7D8
-:10F230001D88C7ADC753062A6176C2360EE7ADC733
-:10F2400099FEDC16FA22468960477CCAC77DC6F162
-:10F250007186E3E33F46C8BF4B1F0CFCF20593BF2A
-:10F260007DD0B1F6BCF6DCA7FE5303C2F5FA4851D7
-:10F270004226D1DA7FE8786F0CF45F2E5F503A6D4A
-:10F280000D513C7F478C696FA38FAC31373C056DC6
-:10F2900055359367B2101C6966ECBFDA03F2B839D2
-:10F2A000A6E139E8DFD264736D8A073EFAFEAFA0AB
-:10F2B000BD9CB2828D5EFF1435C24F28AB39324CF3
-:10F2C00038FFB316DF700FE84DC137FF563A5EDDE9
-:10F2D00060F53C235DBC9ED80C4163F66DA087446D
-:10F2E000CEF77F1194D80C7A5FFE8580723A4A225D
-:10F2F000A8176CC41700FE21F5F27CE00F62A2FC97
-:10F3000043AF8D99CA50184F6422B9E83CC8DAF46B
-:10F310007D4270DF9F05BA2E0B6950611E5B3D95E3
-:10F3200030949F1F4D5746E078F34C9CFFC569848D
-:10F33000803CA3DBC176D6DDC4D5164B286B2BA64B
-:10F340002F687B3EF5F7E1FD26C732D453EFFDCEA3
-:10F35000E41723D84B3D705E6639130A8B8F18E98A
-:10F36000A783D3C5B6641FCA5FE3F3B900170AC702
-:10F37000AD1F4E1781BEB2EC0364B02BE806C51971
-:10F3800054BE6F3B79BDA326C273D767D5E4660C24
-:10F39000EE6D6705378B354EF4E745D8D716FA3B47
-:10F3A000ECEBE54E5300F07BDE694579D2D73EF2B7
-:10F3B00042FA38442ED80361FC46C80217F88B0283
-:10F3C0006917BEBA269CBEE4FBC3E9EBC58BE90B0B
-:10F3D000E1FC9DB7D210AECD02A32F95D217F4ABAE
-:10F3E000250D485FAA89F89AB390DEF0F9E566BB6F
-:10F3F000CB4625E4B28C147C4F474CF97B0109DFE6
-:10F40000973A13FDB96AEECF55A39C7FE32893F397
-:10F41000C67DED3C3A677808EC89D17387039F7706
-:10F42000800218068BCA9B27EBDA248076E0140250
-:10F43000212B80C03CB03F3BAED3DA5ED62E66E3D4
-:10F440006F79FED10D2AB46FE2FDEA6CD6AFB549F3
-:10F45000FEBC62685B4CD83E09E3E9FB1EF3C8CBF7
-:10F46000006F8FA6CBB7025DE680D142AF9F4D9073
-:10F470006F87F6B20C82FBFDDE04F95B304E6B6FDA
-:10F480001B2FDF19DEDED2E3A7B6733FF556B44B70
-:10F49000DFE89A89F6AC447C3780DE7923C8E251F4
-:10F4A0005B46F5EF071DE4F6FC01EEA7BE09F2E8A6
-:10F4B0002AD027CC4FDDCBFDD4DD5CAFECE47EEA77
-:10F4C0000EAE575EE57ED22BDC4F7A09FCD4ABC082
-:10F4D0000EA9E27112E6A7668D9E5C8A76844BF3D4
-:10F4E000534744F4532BBC7A7D33CDA3D73737A48D
-:10F4F000C519F48B5EDF4C8DD7EB9B52E73506FDCB
-:10F5000092A91B2F5FD0FBA945DD25BAF10567F451
-:10F510007E6AFE473375E39765488847EFF11B75B0
-:10F52000E3723A6B75E37AF1E6433C59D5279D6067
-:10F53000C76D1955C7F1C6EC050D6F1D97C0DB6F80
-:10F5400038DEF672BCEDE678DBC9F1B683DB03AFDB
-:10F5500072BCBDC2ED819738DEB672BC6DE1F1853B
-:10F56000831C6F0738DEDEE4FE6ED6E8DDE89F9D83
-:10F570003F4B38DE368A91F05696281AF0E030E09C
-:10F58000418FB712F370031E520C78B85AD72E3839
-:10F590009361C043BEAEED3D5E6280FFF506BBA148
-:10F5A00052D7AFE16D9A67BE81BEEA74E32E9BDF4E
-:10F5B0009CCCCEFB6BF96D1FB7E3F670BCED02BCC3
-:10F5C000619CC8C3E3115E1EF76576DCCB1C6FDB64
-:10F5D000785CA803F006F61DC75BF3A87368C79FA5
-:10F5E000BFA0E1ED6044BC5D29BF5DEBD6C785A639
-:10F5F000B8F471A1C9763DBF1513BD7D37E94B3D08
-:10F60000BF159ED5DB77133FD5F35B5E68A6AE4D85
-:10F61000ED8084CC6CD05337EA9ECB0ED6EAC6512F
-:10F620003F89F92D1EAEF7FD95A88F5AA631FD48EA
-:10F63000F910EDEF67BF4DED80F45E78BC68F09F88
-:10F640005EEC437F5F93C9F477C77BD508D76CD056
-:10F65000DF91F20B7C5C4EA60BAF363351A33370B7
-:10F66000997B86D1F5984731BBC71CB316820CF045
-:10F670001334E5F4DA49A2D347607E6A2FE5648645
-:10F68000E97DB3AB8180DD20DA1E5A00FB22A2C9DE
-:10F69000837AD7601F917A977C07DCBF6380A78D40
-:10F6A000C2E296CC585C879B6CB6809DD198294F5E
-:10F6B00002788A93193CB62451DF9DC2634B146BC8
-:10F6C000AB145ECFD0B6387001C2AF83C24B4C874B
-:10F6D000F9E3C9DD745D55995606877984E953F5D8
-:10F6E00039A65F7BF421351868FBD968D6BEF18551
-:10F6F0009FCE53137BF56F5DE64BA84FC73887D578
-:10F7000091F174DEF5EA20B033C7D2F5817C34394B
-:10F71000B62745B2BFFBB2C3568F97E7C17EBEC7BF
-:10F72000F5EB180A117346DFCF3F1BEDBB05F09BCD
-:10F7300005F0088B7BCDCC64766B15CC3318ED4B84
-:10F7400039DCBE24C14A6CB7A433FAFAF1DA99481D
-:10F750006F4E0A2F3116D6CFE037FF2E465F57BACD
-:10F760000F6DFDFDD0892FDC9E0EA393EF45A213F4
-:10F7700052EE71A3BFDE973DA7B2F53673FB51B3CE
-:10F78000936D899ADDECC7F558287BE40FC22B995D
-:10F7900042E13AC845305E53ED32F9FD14645160E0
-:10F7A000F083DC2915882B19669709C363B9142ED9
-:10F7B0007F8CF141EFF168837C1F64D0C3C374ED8B
-:10F7C000A2EE14839F7875BF7ABED439D1A09F264C
-:10F7D000EBC69725DE60F0632B0D7EAE5E4F9889F9
-:10F7E00059E5F83261DC421524730EDC27889FB09E
-:10F7F0007EF43B7BE0FC845C85FCCAFD1A23BF36AB
-:10F80000664A0867C1C5FC1A8D1FB4E735F859DD93
-:10F810000CAFEB7234FDE441BD630B7C93405C950F
-:10F82000DAD0F2E6307ADBD4687FAF7434213F69F6
-:10F8300024EF9552E4F91B5D78DDD8E8C6EB138D13
-:10F84000125E1F6F4CC371EB1B3DD87EB4D18BD7BA
-:10F85000471A65BCFF506319B6DB1B7DD85EDB58C9
-:10F8600085D7B64605EF8F322BAA9DEE6B542BF150
-:10F87000A8742BA3DBE9FBC2E096DA4AD71106F79E
-:10F8800064D5A56B8F5CEED68D4F6A9074FDC3EB8B
-:10F89000D374FD098A47D71E5AE5D58D1FEC9375A1
-:10F8A000EDB8B232DDF858D9A76BC778AA74E31D5A
-:10F8B000698AAE7F5751FEC0503F7CFC506320C820
-:10F8C000E0120C3238BD1E64F0E9C2EBE75CFE0EBC
-:10F8D0003207515E0CCA7251D2A1F8B2B3FC5A9CE5
-:10F8E000D923C486CD1F5746E74B0B5F2F9D4FE7AB
-:10F8F0009FF9915E623C41DD7D475A97EEB929A29E
-:10F90000B304F211870B448C7B1D2E888B01FBE521
-:10F910007E8B6B5A16A5C7434745CF26780E1E88A7
-:10F92000202F4F70BDE8186F47B950B14AD8242234
-:10F93000D1B2E76B3B5323C63D0FDD4BAA605F8E10
-:10F940005D2F494017150535715161FE5A45E0CFCD
-:10F95000A56EB8BF2A3D278ACE56D19A6CAD1BDB67
-:10F96000BB2F6D5CED2ABD7DD94BF77E3BEC638CE4
-:10F970007AAF1DE45B5BE2266CB7A5F59F27F98C97
-:10F98000DB619F723BEC348FC37CC4EDB093DCEF42
-:10F9900009713BEC036E871DE7F6F3316E877571D5
-:10F9A000BFE76D6E3F7772FBF908B7C3DAD29E9F4F
-:10F9B0008AF2F017021123F8A9DAF5969FEAEDB062
-:10F9C0006FFAF576D8D2F57A3B6C71BBDE0EAB6B75
-:10F9D000D5DB6135AADE0E5BB85C6F87DDD4A097FE
-:10F9E00087F3EB27EBDAF3147D9C6D6E95DE7ED604
-:10F9F000F033DBA7978B95657AFBB9AFFDBE12B8E4
-:10FA00000EF33F80C453617AAF279F0B7A85D245AE
-:10FA1000D605AA57300EEE6B86FCC9361842F56F34
-:10FA2000A129F816E47DC8DB2281B8D3AEF339E50D
-:10FA30001511E82F47D5D3CD82E3FAF8C68D77E9C3
-:10FA4000E13A6399DE2FB196E9E12A27EAFD924A6D
-:10FA5000A39EF1E9E1AA1285005D1AF58DC9B14CAA
-:10FA600002F97DA57AC74AA85E616D9DDEB1C29D8F
-:10FA7000145D3FEA9D1F64B17A831CBA0E30169A5A
-:10FA8000A2720F7828DC76BD6BC63A11BAC023A3E8
-:10FA9000A8FE2982DF29FC5EB5286A03E4D9785ED6
-:10FAA00084886776DF4EC75B87B3BC08F9D2FC1148
-:10FAB000CCAFD07F80AF1C42DB617A2E3BC8FAC34B
-:10FAC000D6ABEBF703CE06F7B71EF9C8A89CFFC963
-:10FAD000F5C4C49F06A137814CC07A83D0A0CB8ADD
-:10FAE000AF1AEF6705981D9495C8EC206FD24C9122
-:10FAF000E79F08843CBC2662C778E608E27F06E2FE
-:10FB00009CD1071CD369B319A64C003F49CFFFB362
-:10FB1000CAFBCFCF1BFDB0EBA45483DF768DC1AF02
-:10FB2000D3F3BF8D18EC971091C09E441C9874FDC0
-:10FB300008A777381D359D68990FFB7A2989E75703
-:10FB400038FD4CE4F82264F3EE1ADAEF758B04FC0E
-:10FB50000D1B51E326407D51B04186BC43AED7E634
-:10FB600042BC892B3C68979E61F8F1D27F803F2F81
-:10FB700009C317E0EFB81E7F3643FFEF393D5DBC88
-:10FB80002E4647FFB87519E8CA39E8B2EA588CF72B
-:10FB90008B83B21843D7B7D725601E756FB0215835
-:10FBA0004CDBE7DCAC6E684DE24C33AE97C803A685
-:10FBB000503C4CE5FBF5F2BC56472341BBE3C54640
-:10FBC0003B5E096910411EB5B8EF8803FDD831428C
-:10FBD000190EF5691D836357417E7E8B25363152A0
-:10FBE0005DCB4E4B2EEAD38E9D0966893E5F6C76C7
-:10FBF00099E1B9E2C45A11FCBD6BBB08DA05C589AD
-:10FC000004F3592F36060EB3F729588743F73119F5
-:10FC1000ECD35257CDE4987888CF52DB46023B377D
-:10FC200016FDD73D836D88379B6B69E9B7E8FE0EFB
-:10FC3000268844F052FC788827007A20D1E9F1C365
-:10FC4000746ECB4980733DFD0778D1F402E5F393E0
-:10FC5000E1F8C825616DCC2BE8DB23B3F5F891887A
-:10FC60008275162D5DACBE8C8422E7593EE4768306
-:10FC700016DF3FCEED86633CEE7698DB0D2D86F8E1
-:10FC8000CD5BDC6ED8C3ED867DDC6E789DDB0D6FC1
-:10FC900072BBE100B71B7AFC05A236415E711EB152
-:10FCA00087C05F3858C3E0EC5E25F8CB201FAEB4A8
-:10FCB000FB4AE87DDB2A0BCACF91896A13C4C76D62
-:10FCC00055EA14D8877B417B135C9B8ADA12E0FEED
-:10FCD0003CE5F471F0B3815EA6E5707EA7785867C5
-:10FCE00065705EBF38C6B312E85959528EE31219D7
-:10FCF000DCECF41FC03B61912A001DB8158B0EDEB1
-:10FD00003506F8CE837698FC88067AA4F09C9ECDC2
-:10FD1000EBCF32492683BB1A05708FAAE1704F8B57
-:10FD20008FC827EB39DC35B8EC2CBAD9A4D2A16F37
-:10FD300025B2BA89B70A6E361DA4EBEF9445CCBF45
-:10FD40007626F23A41FE5EE37CEF707B765D49FFFA
-:10FD5000F1BA437C5C4FBB9548B68161F394DC6F8C
-:10FD600091E8F35581FB92802FD60DD0F2C41EB4DA
-:10FD7000AFA78805BF4DA6EB0CF23A484D5ECE21E9
-:10FD80001C3686F7BDC5F7D9D77ADE2AB9C122D18C
-:10FD9000796705EE21F03E9BB9C11D5E5FDAC9D7D8
-:10FDA000B766C69D04F83238E26C3DFAF13E9B041A
-:10FDB00076F7C844CF6AA00377A262F936BD3F9DAB
-:10FDC000CA43C905CB6ADF190FE3E8338F13A09745
-:10FDD000AB37033DBC956447B9D3D77A2ED2237E87
-:10FDE00082F6485F7A84CA1FB4876CE59F1C07BF00
-:10FDF000B692347802F4B960966730F031A9B2A0B7
-:10FE00007E4EA3FFC2F36ADAB5D2A0BF1D5E4BBF20
-:10FE10007278E485C656F03BDE02FEC13C2889813B
-:10FE2000FA9C60F99D76804F4552CA2EC00F29B6C4
-:10FE300087465338AC29587D13C06B4DF952970053
-:10FE40007455988AFDC162FB69A8C8E92A5E9324AB
-:10FE500085C17BCD7DA448017827DDED5E42F79515
-:10FE600092F8C74685F24D9785F93DEF94FC3E31F7
-:10FE7000396C7C4676F1BF67435CC7CDE87C8C5516
-:10FE80004989541FACD179535134C6654ED6B07AE6
-:10FE9000057A7FF572FAA842F5559BA7978F1773DD
-:10FEA0007A8A1ADD5D0FE395FB6C12FA67E282969F
-:10FEB000E5B45D05F612D84F8F58902F357E4E6A07
-:10FEC000D0CB4DC5C0B75506BED6F8E9379AFCEC85
-:10FED000E5E318C06B540DE3276D7FC67DCDFB9223
-:10FEE000DA39718418FDBB7717A546333D1666DFF6
-:10FEF0004E40D92459E9FE66717A9AC5E98992E49F
-:10FF00004E58CFA17B52A701BED426EA07C0DA56CD
-:10FF1000587AEDDF14D82719E0A5FB9FB55C4C0794
-:10FF2000FF94DC65E9A5C714DDFBB05E604E781B6D
-:10FF3000E85595DF013B02C299F0D23F9D38BCB72E
-:10FF400099BEAF73581C69F2E07C1F31F928E17C3F
-:10FF5000870AC4015EE8FFEEE87448E193707AA571
-:10FF6000F38754D65F7D4F6A069A9BBCFDE18AC138
-:10FF70005041467CE596DEF1F0BF5233E27FF60A4F
-:10FF80006113C4FFC6889F9FDD4DC7CFAAB4799A7D
-:10FF9000E9FCB31FACB580DD5FA92A7BEBE8B84A6A
-:10FFA0004A177E17EE43C72747CCC402F31C9105BE
-:10FFB000D24EDBB366E9F9A67A85BE6DB4478EC62C
-:10FFC00028234CF4F94F041BD944AF3B372CDD08F0
-:10FFD000F37DFCA00DEB0A09BC2B07F400E1F1490D
-:10FFE00079E33DB4BF76BD8D405E641EB7F7E37222
-:10FFF00092715E9363013E5FD316837EF1E90D43F8
-:020000022000DC
-:10000000C703FE5B0735DC06F5D41FC72AD580D7AA
-:10001000DA35D798203ED21ADD3E05C67F6222AE81
-:100020004DE9B42D3D6481F57451FB00E2ADDA3A3F
-:100030006B5AC3F00FFBCA6171DCE926A26C8E60BB
-:10004000D73C9A23703D4B545BD8FA37E448787F0D
-:100050007ACAA09687E13D14FB2E0F870BEC7B0A32
-:100060008B8BB6267AAA07D3F6470271AD8C87AB85
-:10007000FC01F0A7FA031B7906D14F70BC75F8B0EC
-:10008000A7DBC2FCFF4CFEDE53B1ACFFA43BDA0F92
-:10009000FB3C29B1B6EA76FA919ECD4ADA9C18B6B5
-:1000A0001F61089C8260EB3B1A235953101F447A4E
-:1000B0009EAEABF691C710BF5B287C803FBB5C5205
-:1000C000CB4EBA8ED35459ABD0EF7E7C0AC0F3CE60
-:1000D0000C4AA80917C3A9316710AEE7F4FAE6186D
-:1000E000AC337111C53AA4171E35ED5BBF238C47A5
-:1000F0003DAF32F9C1F84F2061F29DE2777ADE0F11
-:100100002DB5B0DF28D20E7831ED59658775CEABAD
-:10011000B1607ECC497C65204F6B1E11B04D7FD6FF
-:1001200082BEA8E5FCD52A0DDA07747C12EC71F4C6
-:10013000F79ED80BF501355C7E552DD2D3E962B719
-:1001400059C72F3396EBF987EE53D7DE98C3EA3AB7
-:10015000BBBC1FC7837E6EA5DB06B87CD222F837F6
-:10016000A17CF58D08AFAF1B9363D2E2F092250C12
-:10017000FEB594FE6A416FD8497B09D83579A3A7AB
-:1001800002BD5B8F46E33A8DF0FD6787C3A924A9C2
-:100190007A305DCF294AC750FF73724333DA2FF0AC
-:1001A00023EAF8DAD502F4BD84AEF27117D2A7754E
-:1001B000C6B85E7AD1E053B33E791F8C73FF678C6B
-:1001C000449D2752E3CE5F0AF6640F1D19E0037BBE
-:1001D000366BEF49EDA533EC8F406765742CC38B0C
-:1001E0008AFC5253DA93D71BD15FFD32E23B9FE288
-:1001F000B5237D3EE4A13439B7AEE84DA483732E18
-:10020000E217995FFB36C8FD18BE3695C881BA78EB
-:10021000502654EFBAF01EFACB717CBFB1CB856388
-:10022000A599840C5A2E1E2BA537634B8301D0133E
-:100230003637D7BBDB737F3566089C6E2018A7194D
-:10024000105DEE09E06E5C09784EC1E24A00FBE702
-:100250004141A882B8FD00A2B7ABE20CF02059E6FC
-:100260008FC2EDF2682EEF974E4915D0DF29D3FBF0
-:10027000A766835DF4AB1C93E65FE055825F291CA3
-:100280005BA8FF06726A50A0BD1DE8B39ADAAD7E86
-:10029000DCBF07F33AD652813C2EF4C6AFFE51F1D3
-:1002A0008B8BE2603C7ED1571C4C8B0754B25BD4E5
-:1002B000DF51DC90F7AB74533F6700D85937BBD19F
-:1002C0006F729F46BBD4CAEDD2A8D18B5C2C7FC67F
-:1002D000F8478B0718E9CA185732F29FD12EFDCF85
-:1002E0001C6E3F5D4DAEBE92F88016C75F93C6FC94
-:1002F0009E3569B52BA17EED3CF77B5CAA09F138F0
-:1003000067968078D4ECB539DEB3B380FFB4FA8356
-:100310004BF93D6D063F24DAFBB42C47D09F8E5C31
-:1003200046478E02D63FC74ECCF6B0FC813397E9E4
-:10033000DF39540FDAE916A7F3734415449F9F1A67
-:100340009ACBE4AC76A53FC18C1C5DBDE0D0DCB09F
-:100350007CA88DE743EDBC5EB038BD7BF757705F7E
-:100360006675C036B9E6C96F533844CF8AF19890A4
-:100370007E95677E087EF22C07CADBF83409EB5EB7
-:10038000AB12ED1EA47D557E1BFC32B43325D892F2
-:100390008CF2762EE5DF80AB1F7FC7DE7FDCCCA939
-:1003A000F93B058CAE7AE24B3E26BF4DF41FD0D30D
-:1003B000EC2A3DBDCC55FAA79FDC5CFD39AE31A1DE
-:1003C0000B3BBF42BA60FCBB6E04CB479F2FA763B9
-:1003D000207FDB873DAEF9B74E0BF58B285E82F2AE
-:1003E0006EA4F7601AB184E3DB5720EAEA1B827936
-:1003F00024DA45FD9EA085243D48C70D90E75EEFB9
-:1004000002DFB7D81653837AC3AFB3EF0FD1794F5A
-:1004100038FB5E8791CEEF1BBD04E3FF0F5C4741C5
-:1004200046D77F1F249CB15E6FCB7CF0DB1E8036ED
-:10043000D6DFFDFBFC62684769ED6D3F92C3EA0DB4
-:10044000EEC90DFC482DA07E8D9DEA5B3A9F4322AC
-:1004500098A7226433CA6711E281209FC786C1171B
-:10046000FD063DBC8D76BC58C0E228A281EF8DEF21
-:10047000BD3D97F339C7535FFB363E477FAAAED6E3
-:10048000D3FF7772FBA997353EEF84FA89982BAF9B
-:100490003BA08214F3D3223179C05F262504DF27E5
-:1004A000B8185D8184013D686918E041B8D17614BF
-:1004B000E805BF438BABE2A2A300FF22E41303A82D
-:1004C000CFE95242422A8CD7EA0F14F295E3F2E5C3
-:1004D0001E95C7388F54C6F2CBEFCA2404EF1BF326
-:1004E000F87A5F0EF8EB47A99E95408FDFAC42BCCF
-:1004F000AC7B05C1FC80C3A5609BBE2AD4EC82B84E
-:10050000156B575318815EB6B9F5F5AF3B8B1E2FAF
-:10051000B6D2FE9652166F3DD418787715A5B596CB
-:10052000827C9497AB6060D87A83BBA2AC10875171
-:10053000D46FD9C16EFE708568856B70658D0A9B1E
-:100540007E3741DD2C4810775008F8F9D615CD5389
-:1005500080AFDEB5A89E414ECCAB629EB875A57A41
-:100560002BF83DB2545E964CF96853AB19CF199DE8
-:1005700028F97DA214C6879FE732BFE1E0CEA80725
-:10058000000E6B047B280AAE1665D37DF1F03EABFE
-:10059000A7892EF1DDA68793E03D6B16AFF1EC82C3
-:1005A000FE261B9C40256B36D8AB60DE35494BDC04
-:1005B0004BC2E6B50FB736C0FDE0B016AC6B51CA02
-:1005C0003CD6A858D8D7E731909F6D5D911907B4F4
-:1005D000D892601D5107E396FCE9B7B98077C984CA
-:1005E000795BABBBDD02FB1EE95654C88F9B72944E
-:1005F0000340AFF3969F98827573A5B1ABE13AF2D1
-:10060000C2EDAD00FF77793C2694508BF9DA964520
-:100610007576586F4542CACAF0784C4BC162FB18D8
-:10062000FA5C8ADB54B374C0C5F4D102F19709B007
-:100630002EBA9F7130EE8F8D0A1D174AB256453A79
-:10064000A7F509D747F6E6A529101769D96087F4F9
-:100650000C691194F5901F50939D11EBD833BC0C8D
-:10066000EED58A6B8A5542FC20BF7DBEF5D88FD46B
-:1006700051605732FCD9CDC46E09D37F19D9C567F3
-:1006800072C3FCE88BDE9BD082FAA04560FC9BE144
-:10069000FDE247502FFC7CB6AF1BE0B7A655590FC3
-:1006A000F022AA9D0C28EA9B4F42F7911184CAE3DD
-:1006B00096265B55A43AB4D022713AF009E5A0130E
-:1006C000034684C9E5957529101F09355D85DCDD74
-:1006D000337E83FD03C04368435A2CE8C350526DF8
-:1006E0004A0AD02DA74BE3FC5BB81DF062A62FDAB7
-:1006F0000B76E55896F79C91EB73629BB4BBC1CE29
-:10070000FD1AD06D2AACF71F48B7A8E73ED9FA1FEB
-:100710004857C47579F9481F0999319F5AF4178CC5
-:10072000F7B68DD3CE3FB1F8A066F7468DFE6815BB
-:10073000F8ADBE3C2DDF55B017FCF5E95A3EB59C2F
-:10074000C5075DF45FA4F8A0CF101F9C6E686BF620
-:10075000E60D5EBD7D9B28B5FB4A40EE1E103DE0D8
-:100760004F2411A65766940B7EB0B39B8AA2EDB8B6
-:10077000EE3C1EE7E4FED73CBEEE638D7602F92424
-:1007800093A36035AC7F7A3E5BBFA33E3D3B2081A7
-:100790007C67716E526F93306E02C84F203D7E9A17
-:1007A0000F26A1FB9957BF14EDFD5EF835B1F81087
-:1007B000D1FB133E62F01F16317B4CF3B7E61BEC06
-:1007C00003A3BD6F8C53F7E60536DB819EBAC7667F
-:1007D0001C4A91B05B0D68F9003A6EA1B773752899
-:1007E0004CFE7472FD70A4513EB68AEE7FB5EFC721
-:1007F00076A0D336B3DF0EFAA4ADECCE18A0BFB608
-:10080000056219F07DB0B10CC71D6CF4E1759597C8
-:10081000C9BB60B6BCC21B1677AE2C2B3EB62ABC39
-:10082000EE41BEEED8AAB0F5577867E8DA1A9D55C2
-:1008300088A4617304F9F2BC97D9ED66AAF7B1CE2A
-:1008400050FC85A7BFFA1BEAAF7687C3EF41AFDE46
-:100850009EBD7F6CC9C0FEEC166D7F1A5CB47D6BCB
-:10086000FD7DADF37B7FE33A9FF5EAEDB94BADD368
-:10087000B83E6DDD7D8DAF0061350CD659BA00EA0A
-:100880006283D94A07C8A3CA526135E44B8FF07816
-:10089000E29182183CE7BE378DF97BD1F58C6FA2CF
-:1008A0004B6760DEEF4AF17BA397D995B30A04BF8B
-:1008B0004C7F9DCACFDB1F4B63F9DCA6A29FFF16BE
-:1008C000F2D0EF145A58BC97C8D3A785E5B1D659D2
-:1008D000FD01C8271DEBA9D358B6FA6EDA8ED6E40F
-:1008E0004A953EEF306B963E7F5861C833441BE417
-:1008F000CA518D3E7228DC537BE1DE973FD1177DD4
-:1009000010F3D92CD04346F8DC66808FD17FA9D86C
-:100910006EE087CBF46336B566ED85BC9A4AEDC9C7
-:10092000D1803FE8A2CF45CBBFC634C8803C468FBC
-:10093000634267D6825EECA42A00F4CBBA9977AE04
-:1009400087F679AAF7012F7DBD47F3DF9ECF96BFCB
-:10095000F446A81FE89123601F4C80BC6064FBA094
-:1009600073D1E46911ED83997529D9B0AE197AFB79
-:10097000A07343D99399701FEC03FAD39957A7B387
-:100980000F4859E625E0C3E46ED4E8AC88757AB325
-:10099000B395C17961FB71A43590F07AC6EE1C79EC
-:1009A00008F4CFE07104ED7DD4FEDA638950BFA86E
-:1009B000BD2FD7CBEAF049591CD30FFC7A293C6AEA
-:1009C00075D4F75B64FCDE8B16F7D2C665E731FBA6
-:1009D000B03545AE877EE2CCB8C4BC4D5A9C232DC1
-:1009E0007D08AF1B96488F3FF41741C2FE08FE1EDC
-:1009F00081BC6474E2D93D2E3AE433AF929F970DE7
-:100A0000E728FC2AE4436CE502DA4BB6448276CD53
-:100A1000E5FA57973BAE158A03C0DFAA65F1F2E20B
-:100A20007433B6A3157113C8854917060A20377C9D
-:100A30008AF834AC375AFEFCD31F83BEA67A1FE275
-:100A4000303ED280E7AC9D161FC627DACAE9CCE952
-:100A50001087596949C1787AF2AF63DCF0367F2B91
-:100A6000C4CB6D1E761EAACAABAE86EF6654148E3A
-:100A70001608ED9FEE63F19B3910BF8179679DDD0C
-:100A800009F19FD95E26BFC06F03BD39B7EE3BE3C6
-:100A90001E95FE9AB88DBF352E0BE34912C60B0C7E
-:100AA000F1215BC1548C0F69752ABE0211CF779377
-:100AB00044277E87C218DF31C6738CF11E637CE742
-:100AC000EE3C5627ACD953DFCED3DB532BE00CC220
-:100AD00060B097A8A8A47CDD662149ED943E0F156F
-:100AE0007F42EEA2EB70FED00435E0749C21CE78FC
-:100AF00099722B48E5CA29D8C8EE372CE0DF2E9032
-:100B00006B30BE67A4FBC7B8FCBA2FCFA9ABEB080C
-:100B1000362EE7CF47A980E705A3ACFEA8E4DE792F
-:100B20002E973F9ECA911FCE637EC50F81CE894707
-:100B3000C1F30433725D3ABA250D83C9A9B0F88DAB
-:100B4000F1BDDA7AB4F9AF741D0F71785F2E9FACE6
-:100B50002BCAB75BE9FBCF511C8BA82FA9411D16EF
-:100B60009FD6E2E7DA73D59037C8043B52C0FC81C8
-:100B7000763F2C8E6D06BA8D4E54E448DF9B7A3B4F
-:100B8000AF276E8A794CED3D4450502ED4F17C8DC8
-:100B9000369F99B89B900F80B6B5758911E2E6C46F
-:100BA00063B75192A95D2B1288FF3889DC0EF1677B
-:100BB0006BAB05DB44ADDA0776FA22CE17D682A9F5
-:100BC000FB20AEA6F185316F631513A7C2B475ED96
-:100BD000FAFC95313F65B4A7B5F8BA99BE04D6754D
-:100BE0000EF0C1F6EB172F6FBF4FE37EBEA6FBD50D
-:100BF000E8AA3CF31637D49FB44429EB6BE8BAD487
-:100C000027ED18AF70C0DA002601FA0FE4E493DE96
-:100C10001FE379F67CF65D9A1681D5A3EC49F8635B
-:100C20007CF8F905533EA39B9FE549388EEACF0037
-:100C30009C972263E3912FB4FA934309CC0EAC281E
-:100C40005C1CB893B6FF8DD74B5E53F88C96EF1FA4
-:100C5000509C43B0F403E0B2CECAEAD20E7DC38CFE
-:100C6000F564443CB0EBCEF8DEBADD6B36EBFDCA82
-:100C70001BD2F4F6A0D1FEB31ADA43F38D75648A61
-:100C80001DEBC812781D195FBF914F7EDAC8F21AAA
-:100C90003FE775FFBFE0E72F7FC9EBF736F3F39728
-:100CA000CFF373B31ADCEFB728188F3E711DB5E987
-:100CB000627BE380EB8ABEEBC6F3FBF9CCCF9A22D2
-:100CC0003A77819EEA3D67D1FF77C22ACBF479B3A8
-:100CD000D93E7DDE6C6E953E6FF6FF32E5ECFC6C26
-:100CE000388751BF12BE5330639588F9CA752DE716
-:100CF00050CF9E2F406BFBA2F71CE6E730B4731C6D
-:100D0000DAFD6BF3D9F7911CBB122C508F3F635562
-:100D1000EC54889F1357C665D96F15107387FCCFA5
-:100D20004A9705BE0731239080F1D09AD62B9BE7D6
-:100D3000BED143304EDD13E757C7DE04F2F9B016DB
-:100D4000E727D7DC0471FEC33CCE5FF3F2B827C1BE
-:100D50003FFA599E3C17E0D1942757C1B586AF871B
-:100D6000B66FCC1FDCDBA63FAFC7EABF3F5193DFB6
-:100D70004F3C5D9C2C3444AA17B939BF27CEB5141B
-:100D8000E627F69E38D737613E626FC77376F7E67F
-:100D900033F9D47C8CD4C33CCD2F93FAE723D8DD30
-:100DA00077E50BDA7CDFC2E7DD9A7EF3DDC9E6D7B3
-:100DB000CF27DA624780DF7F82D79719E7BB37DF1B
-:100DC0008AE3E87CDFC3F9127BD6776FF8FA7ACF33
-:100DD000CFB86280691DD58AA98BD2136911B1EE93
-:100DE000C4D1E19A067549646A2AD6B11C2EADFCBD
-:100DF000A7384F73B8F4857FC9F334DBF2932FEB38
-:100E00003C8D63265122C535029C2E7715640E0C4D
-:100E1000F58327EBF2FD41B0337ADA668540DECF09
-:100E2000BAFC20DEBF3FCA551DD1BEE0F2ADA574AD
-:100E3000910F52426B92A68AE1F6CBD92CE5CDFCFC
-:100E400008E713CF8DEADE0DAA6966A96016E2D124
-:100E5000DEF608547E66AD9821BA2542BC0D0F4ED1
-:100E60001E4AFB672552FF2E6CDFF9F5BFDE4DD918
-:100E70009514941E6E8EA7E376E4286F03FD16B9D1
-:100E8000A53DD09EE54BC7BAF7FB6309DA79274643
-:100E90005BFD9B922F5EF7EF7AE5F24AF315C8E50A
-:100EA00096467DFE7B4DD29895B0FE3125240412E6
-:100EB00036C57DB618F27F19D9CAEF605D296E225A
-:100EC000DBC6E37D9984E56F8CF30E98C8F0342679
-:100ED00094F80388271FD2FCFDA22BF6F7FF180E0B
-:100EE0006FE3F584E6EFAF8EECEF9F581417391FD0
-:100EF000D052570BF98013ABF5FEFE890DEE6A3820
-:100F0000E77782FBFB27A6507F7F6CDFF9006D9FA0
-:100F1000540E3927EAF201DC6EE771EDD9D9F2C03F
-:100F200089D9E8CFBBE0DA9829C7E278D575139E56
-:100F3000472691CFC992275C32F839DAB9F65CAF0F
-:100F4000320C9ED7CECB8E01D13608F2A2AEDB2278
-:100F5000D1F368BEBEBF3E4FDA93C734E139EACB66
-:100F60008CD35FEE38C9BB99D5E398599D61544243
-:100F7000891BF253E7C7DA51BFB7C2FFC2F46A6AEE
-:100F8000BE3271E2E0F0790CDF57952EEFBD5A9D2D
-:100F90003EE82BD02F9D849481BC7920B601E31EBE
-:100FA000D771B819AFE513395E892B1EE0999AEF16
-:100FB000BB01F0415EDC2CE17760F9FDBEEAFB8D00
-:100FC000EB78D6EA7B1FCFD7978812ABCB23C81715
-:100FD00057A5B9504F6BF6D7D2894C6EDA48689452
-:100FE00095EEB359DEEDCCA4E33E7CC29C0E8F3D62
-:100FF00017432CB06E5F1A9573741F256E65647F5E
-:10100000F211BE4864F2C2352098DC788D635755E2
-:1010100080FB17F1E313DD83C11E7FEE49969FBA73
-:10102000EAC945F6DAB0F99F98C8E566225B7FB554
-:101030002CF8A56458CF59CC43CD904C1E9940DE76
-:10104000F8FCD1B91027A4F6DB686C9FC376503248
-:1010500065425EFB43F7174761FC55F72E1E82F48D
-:10106000CFE1B17045E6B368E7E728DF05FC070B81
-:10107000CEC5A48E453B7E3DD0FF4281F822D909E2
-:101080000F71BC5D2F37DC087476BD6C23706E2D3C
-:10109000586C43B83F572848E0B75600CD433CE76B
-:1010A0000933C69B293C9641FF018F03BF1B5D227C
-:1010B000FFDA0CED3F8E13C8D07EF4F115C3B5E016
-:1010C000DC60E0C70F81FE22AC7F295FBFC64F14F2
-:1010D000EE25B82E99D58BF44557DD79F2934097DC
-:1010E000AD294A3D7E17D135F3B2BE8B58F1533F3F
-:1010F000D6EED97ED2308C44A8FF3AC4F9C478FF2A
-:101100009713997D770BE78FAB9EEC3E701DF0F542
-:101110000A8B0BF0FAB33CDF66584F8FDFF57796FA
-:101120002353C40588BF60395D3B7EC781C4407BC3
-:10113000FA2833E24F2DE1DFF9B89BB89A63F12921
-:101140006CDB5708C8670E677B1518CDE6BC86A315
-:10115000B3E1B96211CFF5879D73E9B78E2CC4CF87
-:101160009FB5C0F9336ACB075789DA77B7884065EE
-:101170005BB0D4CCEDFBCF9E94E9AFCFF2FACC9329
-:10118000AF5A36421DCB51136BBFFDAA65C44AFA54
-:101190009ED008B68EB607054F9304D7A7D743FE57
-:1011A000B26EB9E029A3EDEAC03D5D10E25AF288C3
-:1011B0008D80ABF0F10F974E85FD9C7313FCBEEC58
-:1011C000DC04C6374A90F84DC9BDFEED0749C4AFEF
-:1011D000E54BE11C9D97EB9987E01C1B5DF7B5EA99
-:1011E000B7D4EF40DE94FABD10571BE461F9CCE8A8
-:1011F000A0D9E327E0EFB2FAC8961F08E421984788
-:101200005CDB0CFEB98DD7EB46CB35E83F0EA2F484
-:101210002981060D9975E7D8EA8882F41B5746396B
-:10122000231DAE7AFF38EB12E7D9E6DE343816F824
-:10123000E52F13F5E732FA8AAF6B57F8DE0DE0A71A
-:1012400083E757B751BB1DF6FB32B5DBE1BA9DDA38
-:10125000ED701FBE530D5738CF06D75DD46E872B68
-:101260009C67832B9C67832B9C6783E7E03C1B5C1C
-:10127000E13C1B9E3F2C540303013EC5D104F243C5
-:101280002D1646676A9215FD8D4021C1FC7D30C93F
-:10129000BA6925C4EB0486273596F50763949BB19C
-:1012A0009D3C96E577CD9E11708E7095305602FB71
-:1012B000A9D5AA60FDF289956602F5CBA169C2FBAA
-:1012C00090772182C92352FB66C757B721FC17CB01
-:1012D000C40475E92BE1BBA1208F3F259B587C2ED0
-:1012E00028C2F7E59A6308A7C73ABF4C65F669417B
-:1012F0006B1F52C09F9D043101A4DF030AF42F5ECF
-:101300002EF076D02F8F82BA06DEAF1E7A0AFCD777
-:10131000558676A7497B3EE52998EF68CFFB465472
-:10132000CB40EF295A7FE242689F8AD29EFF7C2100
-:101330009EE7D2D6A37E8AF38592B4F1A9D5D01FB9
-:10134000EAA9935B82EB0D0D66E3FF6D57E7D3E0EF
-:101350002FFFBDE76B56548CE3ABB3087926F662DA
-:10136000FAFA7892A88F87CA822E1EAAC5DF4D8E00
-:101370000543F1FCD90336948BA79208FA217DC569
-:1013800045C3E2F51817FDD524AD9ED910FF240AF8
-:101390008179AB201EE8C1B72AE1E7D388D040A00D
-:1013A0004EDD772646023BD29A1816BFE332A0BF25
-:1013B000786173038B0F06150B51937BEBFAAD0528
-:1013C000BCAE9FC70BB53A066BC1A3BABC81315EF8
-:1013D00048C465988FF62DD2C7032B942B8B172EFC
-:1013E0002001CB50A07F59F080FFBEC0A57C300407
-:1013F000EDFDABD9F719A5D7316EAA9D1B833BF044
-:10140000DDA92ABEE7B65B4FBC3F848EF3AF8C925A
-:10141000E030FEFC65C5F87C1EDD21C4B76A0AF128
-:10142000F02DC9FED4F3BA04F2D46DF23033CD7787
-:101430006F02D80B8B62316F72D35DE91FC03C8B9A
-:1014400055073E47ED4A4EEF2F6D047A1221701971
-:10145000D6CE1AA1D15BD546E0AF49715A3BE629F9
-:10146000E08762ABF6BC17DBF3148DFFAE790AF4AC
-:10147000C7D1128DBE0F54C3F3B3537BE643FA9E1C
-:10148000E4D0DAD317427F6BCF7C4B36C27CEFC0FF
-:10149000978DB03DF529E0E7E2195C5FA91F6D84E7
-:1014A000F95B1668F34FF0C3771EE79BB4E7A3FC24
-:1014B000B07E85686D2ACF68FB3DCEFFC70A5EA867
-:1014C000067EB9B1A7FF05DCEF02DE3E5E50F714E1
-:1014D000F4FFCBEFEF7FF87DC6F64D2438656856F4
-:1014E0002F5F18E5D56F8B981CF1D6FF1AC8952C85
-:1014F00068781ABFEF06F10096CF4A98E503796144
-:10150000173D943388CFEDC238A7719E9B0B595C71
-:10151000FD4C813E2FD662C88BF9787EAAAF798EBA
-:1015200014B1795A4B22FBB119D9257F2A80FA01CF
-:10153000725684F95C1460F07DB2964CE5FFC37D71
-:10154000CABAF8DD4D2AB23C709FFAC52AD899D3A1
-:101550002938210FDB54F438C6E9437916DDF7400A
-:10156000B43CE73AAB8CF2F1635ED731BF449E7274
-:101570000FF0FF30916CC23A0F27E61BCCC3AD4F82
-:10158000A35CE7794FED7B1CD32F712EC2782EA57B
-:101590009BC3FF5C419B05E4B34AD429A55928AFFE
-:1015A00083506F6C72ACC53CB0ADC88279042DFF1E
-:1015B000ACF0EF7F6B79DF49170632FD9EA6C5754B
-:1015C000FBCFFF2ACB77FAD03E68178949B8381F7E
-:1015D000BCD8A726413DCBF4D2183C2F5055FB0672
-:1015E000CE7F7804C1EF0447CF6AC0F341666A1F1B
-:1015F000CA00179E2FD6EA63465EB81DCF8DD66906
-:10160000F5E662F941B0536D8F513F0BD997C14553
-:10161000CB17CF30C8FBC50595A86709B5E347C709
-:10162000C27BFA3FF7FCF0A458A49B8FDA593D7FA8
-:101630006121CF97F03CF0FD1616E76B4DD1D3D565
-:10164000CF27317F65FD244677BB8A7E5E85F633E2
-:101650003179202F469E60DF8583180B9EB7327E3E
-:101660008F396D0EDA754F8CA45BA4B6B679F97B11
-:10167000185714D6B3E73E1D4F1AC06F319B599BC4
-:101680005E54C8FFE77A9599855097B5FC031CDF37
-:10169000ACB27AEFBEE237D5859ABE67F19BF9EE20
-:1016A0007D5D70AEEC6F8EE318CEBDFA24565FD22E
-:1016B000562069F946FC2E21255C0BD88BA9F9BE72
-:1016C000FA428C6F6D96601D9ABCD957741BCA275D
-:1016D0002247CE4B6B7CDF62C84BFBDCECF923AFBF
-:1016E000DD530D7F17A2AF3CC4B3C53D7983E5F848
-:1016F000FE782D6F20DF03ED5E3D4A37E4D5E9D15A
-:1017000085F5FF0BF4688FDDAE76A11DFB755B3FA1
-:10171000A5AB1710AF652C7EF6755BBF3C517E13F1
-:10172000F8F9BFFB3DE9137D5D00A7FB04B9CAC909
-:10173000927B1E419FE7FBA0B09F3CDFA5E20FFF1D
-:10174000176FE83FDE602FD2E7E1FF59E20D0E3858
-:10175000433518F928B108F8A880F1D1BFBADCA345
-:10176000FBCD2F827CBAB0D91F9DFAF7F7F753F360
-:1017700095B222D4838A6917A59FFB8AEDCC9E0976
-:1017800030F8F6C633E8FABDBA78C653F5FF0DF166
-:101790000CBADF2AC46F297FFFD71F7F77207C65B3
-:1017A000664FFC0BD2E703B8BFCD6C7FFF80F76FAD
-:1017B000447AF905A3975EF8303B290C3E0BEBFF0A
-:1017C00031F0791EE1B38DADEF6B80CFD7119E1E46
-:1017D000B6DE4BF9D7270A044D2E1FC27D66313A7B
-:1017E00038C5ED6BEA774F1E2AF5FADD4FE5C86F75
-:1017F00015313BF76891AEFE537E1BEEF7E3171FE2
-:1018000083FE087E7108EE7FDDFCE2D8429647EC4D
-:10181000CDBBF8D9776F49D5F5DFA0EFF980C21BB2
-:10182000E26D6DCB45B42FCE2712FC1E80666F840F
-:101830006259FDDEC5E7C14A099C47B4E5B1EF8CAA
-:1018400068DF07308B0B0606A48BE17A7080628517
-:101850003AAF25727A0B9C6F9DBCF6733C77659509
-:101860006DF8773547BA3D96BBC08FA67EEEB510B2
-:101870004FAD77E1393AED5C9976FE634960DE3E23
-:101880003867DB46E92181BEA7A2D472327CFF46CD
-:101890007BC36C681BFFAE69C2247DDE83C21FED73
-:1018A0009FF3EB597D5C9B99EC82FA8F3A55F437A4
-:1018B000D1F6336B05FC1EE7220A27F0F727B7277E
-:1018C000633DB935917DEF4CFBBBA7940EDAF3C0B5
-:1018D000FE3B2A12FC3B76FC3C99F69DEFA869671B
-:1018E000F17B5BA7E8FEE1FB3DDA772666703AD133
-:1018F000E019D5148770394FE142002EFCBCCDF4BD
-:10190000E52C1FDCB2607110C8BBBAE0F35591EA58
-:1019100052E6B8F5DF4B37C6338CDF1B3713DF4099
-:101920003857575150AC82BD6AE3F59AD144C6EF9F
-:101930005A9C5AFB63F65D8B528BEE3B22C6F746F0
-:101940001BE8D466883B18E9D4889772035E9E3101
-:10195000B3EF0CB6748A1E95DE6E7964512B9CCB66
-:10196000571F31B1BA7922E3779F5AA8C58BE7CFC9
-:10197000E962215E3F97C353C30B210D16E0B70503
-:10198000DA397453C36A384F3A8F9F43BF916CC69C
-:10199000730637810541DFBB1042E4227C5746B213
-:1019A00032E7C045601D7555EC3B1926D803E409A4
-:1019B0001E3121BFB6B877E1DFFD0A0CB3C49E4EDD
-:1019C00063FE44247BB627AE4021713A2C8EFF7F04
-:1019D000F1ABBF2D7E35B17010AB9B880AB8F29287
-:1019E000D9F726A09E6962A1C4CE2758941178DE4B
-:1019F00061C3272AD08176DE81FEAC18A2FF6EC2B9
-:101A0000C649FDF87F258584D54727879240AE7D5E
-:101A1000D0475DE5E1E29EBACAE72661FE9DDABFE6
-:101A20005920F798FD3B23D7F7B3496817B373CE16
-:101A30005A1CE933AFF24B185F087F3F270BCFE703
-:101A4000F8E1FC4E8553D82B48BDEF27C63AF6FF88
-:101A5000A579AB7BB8DF168C22F81DA46032A97A79
-:101A60003E023E9E29617644303D32BEB47E6A67B6
-:101A70001C9FC4FDA1018C28CE58F5F18193809F55
-:101A80003EFF0E1DC7E3E829F2478877DE7E385710
-:101A90002132D4F72ABEF701AFA7555102BD420249
-:101AA0000A7ECF6FFAF74557A4BFA7F8CF7EFD2F68
-:101AB000E87FAE8400800000000000001F8B08005B
-:101AC00000000000000BED7D0D7854D5B5E83E73A5
-:101AD000CEFC24998409061C24E849001B6DC0E152
-:101AE000279000813393842490C0F0A741221E08E0
-:101AF000D0DC5EB44111634B9B0381102222BE8B6C
-:101B0000AFBCFEE824185AEFB37DD4CB6745D48E22
-:101B1000012D5AD4E0851A2BA54110B1CF7E8F5EDE
-:101B2000E5B5CFE7FB7C6BAD7DF6CC39930920C6DC
-:101B30005EFADD3B7E7E877DF6DFDA6BAFFFBDF6BA
-:101B4000492D8B3AAFCD628C6952A0131EB53EFD74
-:101B5000E4502CB39B59E74478A88723F224C65657
-:101B6000B2D84F7540B986FEC558DB5DA77E3F14DD
-:101B7000DA4536A6A86C3A634B5607A97F11F332B3
-:101B8000199E6DD372181BC258C1B9C06115CABA6B
-:101B9000DF11906898F0778741BFF08A4CB50DC689
-:101BA00059560CAF0A183BE984E714F8DF98B64C95
-:101BB000CB87FE58BE8E3A680CCA4B065BCAD9D09A
-:101BC000F4186F5FA8FD35628C82F199D9DF6CFF44
-:101BD000AEC4DB9F0F66470C2F63B79BF550D6B1A1
-:101BE0002CFA33969E1354A07FBD24CAED9A629DB1
-:101BF000EFDA766D1A63679CF6F16BCDF16669AE2C
-:101C0000761C2F1C9BDFD5AE41F97402FC77305E49
-:101C1000BE557350FB95B1F60E5AEF594994C7EA79
-:101C2000583EEE12FDF39769B0DEED39BC3E1C1A4A
-:101C30001B31B2AF3E78BEEAF1BF303CD354A2AB09
-:101C4000C2FA5F945C0BFFAC6D6897752FD259F8A0
-:101C5000F70CE8D17844523BA14F21DB2B3399C0DC
-:101C600076C94097533489B5C15CEB4212F50F7BBE
-:101C70001D7C1EA328A2019D2D992EE8745904E70E
-:101C8000ED8FEEFEF4D29AC70CEB3A8D354B6D70AA
-:101C90001B636D702FEA82F6505E72F73FF811CE2B
-:101CA00025B9627D2511A4BF964CD1EFC38BCE7BA5
-:101CB000EAA56AA2F725B179E653FB25A962BCDB48
-:101CC000A91CC7E79D767C1A372EC3F9045CA1D006
-:101CD0009D84CFB02FB219F93DEC670103F0797BF9
-:101CE000FD0659CFB7F09151A5121FF963E5889D04
-:101CF0008F0A888F061AAE9153C23FD440CEB0BC33
-:101D0000BD6A78CC57B16E9093B86E43A2750B3A0A
-:101D1000AAF559E8DD03EB564539B0ACDE3B10F3CC
-:101D20007697D1BC1F01BE599C9F98919BC03F974D
-:101D3000375EB377B90BE15EA5495A04DA7F8EBFEF
-:101D400019F1E7E9699CDE019F2F6BF0648580CF74
-:101D5000747CCF488EEF9B107E95F0ACEA8E2E807F
-:101D6000CBA579581BE060DEE4F06FA83DDBE147CE
-:101D7000FC0300D4BEE5285390CF80B7028EA95053
-:101D800076B29ABD49E6FD69C841F3363356B117BC
-:101D9000E09BB8D1B72AEC8DD7E79671B8547CC2D6
-:101DA000B8C7D37BEF1802F3F732E6DB08E3371B43
-:101DB000C0BCF07CBF5E8A48B0E6F7B3C3738AA0AC
-:101DC000DC9DE3086C84E9BB1F708F580BED7B72C0
-:101DD000BC0184AE277347BA0FC67F3F209BF8BA79
-:101DE000E73DE4EBE3E9317E3250BF749BF83DA759
-:101DF000853A908FDF5179F967A56BDF43FE6279F1
-:101E0000CCC786021EB007F0AA236D9AC70DF3BA9D
-:101E1000668238C1BE3EA6BBA0DE8DF5B0C4798F08
-:101E2000EE7E74018E61D4BC32CAA2475D4C317A19
-:101E30003D34AFF2395790CC39293EAE6B67F3CBC6
-:101E4000CDA88FFD320B216FF9797B3FEBDDF0B927
-:101E500003C787721E43127CE97358BF6496F1F77B
-:101E6000392CD1CBC2153908571E0BA0BE9DA73BFC
-:101E7000CFC4EAF9639B32C98413E191D75714C1E7
-:101E800033B5DEDE6E761E943DF1F2AC9D7521C455
-:101E9000FB2C0DBA8D63ECC8CEBA681DC079A4D0F6
-:101EA000ED9300D3AE6CC5D67E36DBBB09F10E7662
-:101EB000C52119F0B2D49CAFD937EFF70CFAADCAEF
-:101EC0008312ACFFF87782E90559C86F72C061B61A
-:101ED00071087C306AE77470391D90A07DF37362DD
-:101EE000DFB40EE403394DB295832E513FA903F9B7
-:101EF000E2784CAE8E598EE5452305DF0CED403D72
-:101F000039234D94072D47BEED559CA63CBBBE031F
-:101F1000E559AB18CFD8457CFD3613F5691D484708
-:101F2000E198FC9BDB8EE55B7D263CC60F491E36A7
-:101F30006B5C9F4C7DE9D55EE30ADA037F16059161
-:101F40000FC35CDE25D64F391669CE30EDBAD16AA3
-:101F50005F7EDB1694898FC2DA9F65DCBFD206C034
-:101F600019EC5F498D74AC00E953612390EF5B9AE3
-:101F700080F74743F9608A4B4D47B9EE9BA925E1AD
-:101F8000DF57830E1AAF2AE8CD3AFB75683F814DC3
-:101F900040BA6B696A14FD0DDC5F7D942B9292D37D
-:101FA000FF38A74AB81CE8967C0BB97E9619EAE779
-:101FB000E02323BD452CDEEEC5122E0F5A26688B7A
-:101FC00083F09C03E297C11E6E98FE837008E63989
-:101FD00053E40CB889CFB4B790CFE69B34F4B04B40
-:101FE000630FA0DC2872FB36A2EC96F39D8D505651
-:101FF0008603BF62B982D3B70EFF7D9E8BE32A7141
-:10200000FA0738E635DAF9416116FA86FAD5C1746D
-:10201000BEFE9BD9CDB8FE079DBEA528C75A737DCD
-:10202000775BE5D9FE122EC79E36D7DB35FD9F6B59
-:10203000103F1F334700E5C79ED430C9B353198CF6
-:1020400075A0CED798EA1B8A7CCDD721E5DDCAB032
-:10205000FD8F6E80250C03381ADFED2E9D00EF7783
-:10206000F17EE7C6B20686EF155E8687618CC37681
-:1020700027A9DDD6602ECDCF1E0B783C48FBD01CA7
-:10208000F7DBCBF63AF1E9487B7E849E647FC4930C
-:10209000AD767E14C303F21268425CB7C474C7E71E
-:1020A000B87E53FE039D6E273AADE17A64CAB9F358
-:1020B000367A2B0DAAD42E91EEA0DFA3D46FA1E81F
-:1020C000C79CBAC55EDF168C443628A48F7E48EDC7
-:1020D000BCA08FB26CFAE8C7F43E411F4DAAD41ED3
-:1020E0000F16C4CBD07F3795FBF6EF0C26D167D007
-:1020F000FEA734AE47277CCD9BAC3D89E589D70B45
-:1021000079020D0B417E5C23CAE977D64FB3CA9F93
-:10211000C2C751DE2CD625B3FEEB8F237F1F0F09DC
-:1021200079736429CA93983C62358FDBE4119B7301
-:1021300027D6C7E40F5BF5188E17933F6CE6E328AC
-:102140003F82F3845E3BF3188EDF522BC6BF25120D
-:1021500044BBC421FAA744900F7526CA763BF27798
-:10216000D3FE65A9D56F62EC5F1ED32C7EC689694C
-:10217000758F931E3486B0D3820F72FBF2BB90032F
-:10218000827E847D78EAE093BA01ED5654686F59F7
-:10219000F7256667F672BB276E5F9EE7F6F7C0DB32
-:1021A0008FA769FE7C4E6F5FC1F8FFCB3ABEB0A728
-:1021B000E0FDBF59DF5F6DFE1CC0E70A21BD4FE4A3
-:1021C000F05D41FF8C10AE2FC0F5D4DF00DE6C9ABD
-:1021D000CFF403AE427C064243AE6AF84A09BE2AF7
-:1021E000BEDF2F6A313A2D4F4E07974DFF73695F5F
-:1021F0004AF9BA2DE3CEA7F755822FD4A4FE3AB4FC
-:10220000BBCDDE2ED6FF7682CB1CF722FDEFB4B716
-:102210008BF55F6EA5CF01E0F3D5D6FDFD0AE4484E
-:10222000238D3F8A8FBF328EC7EF58DFFF67DCEC0C
-:102230009274DE4EFBDEC0E9E932ECED9F60FBAD4F
-:10224000D25E3D83E24486C0FB3F23DEE17DAF0BDF
-:10225000DEBF65EEC79345E19FE17B2CFAC75BFCCF
-:10226000136309AD2FEE9FC040F9567DAFB75BF504
-:10227000FDA1505D3BC22B97F0F6FBBBDE5C86EB0D
-:102280004F2C835D7280D6930576C918B24B9EC7DA
-:10229000F2A5C605F8BBA8DFB39C6E92D4BF42740A
-:1022A000F514AF6F75713BF6EDDA8FC98ED3D6A8F2
-:1022B0000EB4E3845E3F1AE27E00D82315116F5FEF
-:1022C000BBF1684812783B4AE3EEE5F83F1696D337
-:1022D000D1DE8CD92DEC55F283E276D55DEDB88F49
-:1022E00071BBAA81CAD3CD7D3E13BA779909EF0994
-:1022F0008E07733D976EFF1EC1E1E7ED93D49FA556
-:10230000F1B2399CCC7BF80CFAAD44AFFC37CA0172
-:10231000E5556621E85C549C05764BD74E4945321D
-:1023200059B94BECF3FA769BDF68F2E162938E9534
-:1023300092E665185F58FC89E0FF437CFD313FB5AC
-:1023400099E07FC78C4F3C8CED397C9F12FC2A872B
-:10235000EF2B18DF55427619C74F0D339C689789CC
-:10236000F382C4FDCD287188FD4D2F213B99C355C3
-:10237000A34B64BF87579C7222BD2F3DC6B464F443
-:1023800031A4C425E24F43A8BFD7F46F033C2E9479
-:10239000D87E78492C5E359CE0F4F1F936148547F7
-:1023A00060FF69FAD192A17C6B3C688F864BA5488F
-:1023B0005B0EFA37DEB25228CF73B05EF2FB18DB49
-:1023C0008C715FF7F30A6B0B506B55B1C475804B82
-:1023D0007F8B7EE422739FE7B1587CC581F11A4B55
-:1023E000FC86FC4077C9FD793B558ABB50DCC6E5CD
-:1023F00097C9AF083EB482E223A9856E9F1BE7917F
-:10240000B3C9CF75FDD08C172DE4FEA503FE433B69
-:102410003AB59191FF36679B1451A1DEADD9E32FF8
-:1024200075EBCF37937FB782F934F01395427BBDBC
-:102430002BC17F6D99A087104F6777D539101FC1C9
-:102440004AEE879DDD35D28BFC97E8479F453F9A42
-:10245000A4541F3FDA7800E36B163F7AED00FAD1FF
-:102460008B4AC08F465964FAD1238BC2B7113D28DD
-:102470001AC9B7AEE953E693BFBC4D666E687F7A62
-:10248000E7C4370AA16C6C5302186E78DFA92DC51A
-:102490007A03FC69F97ADA2686F1ADB926FCA78BB6
-:1024A000CE9722FCDABDD70790DE4F3FE4263C9F53
-:1024B0005E99194983F132B6FD65530AF47F2532DE
-:1024C0001C836C31FF3AD10F672C6220DD9C6623A0
-:1024D000581BEE83E26338AED290113002717F7BDD
-:1024E0006E9ECFC0F1F4481AC37D8FBECAA4B379E3
-:1024F0008C8E1C908EE731D58985054C7322FE1792
-:10250000319DCAB701BF492371BE3C83E800F80E74
-:10251000E3774D13F4EF10BDFF88D307DBAEB4E3D0
-:1025200079C569E39174E4B33DA9F6788378B698E8
-:10253000FCE9413F7FCC80FAF90F5AE5C465C895A4
-:1025400047F87E727E7595301A07F4643DF279B7CC
-:102550001907DE9EC9E3277BCC3849E213183E0BEE
-:10256000FB7F513D01FAB29DE08DFBF11D08CF6567
-:10257000E8CB9F12DCFBF83A7721DC5CFEFCF7121B
-:102580006E07A819144F01513C89EF2FFE3E95F4B8
-:102590005FE07CDA5312ED578ACA480EB95938CA3F
-:1025A0008989E3117EEB87DAFB3D7BB17E6B827C10
-:1025B000FE3F16EA2FE0FCC5E78142A19DBB8AC71A
-:1025C000C1E77AA5972535DEEE38C6A192ECF779FA
-:1025D000538E42B3A803EC958733600FF2717F02EC
-:1025E00083505EBFDDA49D441BEE7853053D7B9474
-:1025F00006921F3DBBE4C806E8FA4613EB2E1DDD2C
-:1026000077DC9ADAE0C933167934B7EC090F08455C
-:10261000D69CD77158C278BDE656DDD0BF3B3DBCD5
-:102620001DE3F5C651997502BCB72EAC3C79C622A4
-:102630001F12C785F998012CFB61894C701F0CBAD9
-:10264000A333308E60481194072B8C534E8C572E39
-:102650006D5CC674D82757E12905EDC29AA08FDAC0
-:10266000CF2D94996181EBF149DA7B8867A08B3398
-:10267000B4BF81981DF53E96834E2DC3971F8F439F
-:102680008A7381174B9E22FBB83B93D1FC613F8B31
-:102690006C80F94BB465AE5E3C67F187296E7AB207
-:1026A00044A57957EE6C277852A7FD99E001DB39F4
-:1026B000EA18DC17DF820F8E9A786F31F1DE1F9EE9
-:1026C00095521ECF13E5B9654A3AE2F92D45A57337
-:1026D0008EFEF87B7EA97D7FDCFE0A5BB959BBD7F5
-:1026E00081F47476A71CC17D82E7EBB86F9FC0BEF2
-:1026F000B19CF838DDE9ACC6AA9FC5FECC29B5EF80
-:10270000CFD26D7C7F966E0B125E969656BA86F18E
-:1027100073B5BD40DB4C2F5CC6102F2EED9482723A
-:10272000ACBFFD027E1B568AFC6BDA8F57103FCF81
-:1027300029B5D8B55F757C1FE6BBA534899DFDB76B
-:102740003A5F10F4740CE56A7E5CAEDE56CAE5684A
-:10275000E253C8558B3D49714D0B1CCBEBAF000EBE
-:10276000C127C8A728374A7648CEDE7CDC7FE0D771
-:1027700031689F7DB819F35156F919D14356A94ACA
-:1027800074ED9A36CF85F278E5AE3F2BA8AF009F67
-:102790008B4B2D72B8A494093D544BEFEB395DFC83
-:1027A0007B9FEB003C77D3BED77238AFB673A7756B
-:1027B000D5E18DA5740E0472C98BF1789FD04323A7
-:1027C00078DCFB8B9D6FBEBFF35E8676E0BC3FA5D9
-:1027D000AB6807DE5ED4A9E5A849CF3755C976BEF8
-:1027E000591762E45730161AC62E79BE99787EDAE8
-:1027F000F7BCD378B9392B6E77279E77269E6BB2BC
-:102800007ECE3FFB9E771EAC2A02386705649FAAE6
-:10281000C6CF335DD3CE9E6063FB9E770E32F52E1E
-:1028200043ED6D596FCF08756F14F3A38679021DC0
-:10283000BC399327C5F1087AC0E38679369501FC47
-:10284000682FE7743CBA80D9F0E8223C7C413CD246
-:10285000F936E265A714D988FD950603E5F94AE63D
-:10286000537F1088EF676CBCBC751ACAE7EFD47948
-:102870009903F87F73D63D6C19B44F3D92C26468DA
-:102880007F44BD87F6FBC847E92A9EF7BAFD967DCF
-:102890003071A908F8E4BE7ED2DF601F3DC8727DAA
-:1028A000F651ED28453D7BB9FBF76451F803E4632D
-:1028B0000FE86B657CFC7DCF088ECFDE9B58A44370
-:1028C000EABB8F806F8DFCCE3CD6BE91EA1B18C64A
-:1028D0000736498CE33B812E1C69EB0D3CD7762DE6
-:1028E000F7921FD5DCD040F83E0AF8367C9CBFF04A
-:1028F0009CEA22FC25E88249432F9F2E12F7FDC84F
-:10290000CE3AD67875EF6B3FFCB9BB14ED9ECBDDAC
-:10291000D77953B59CB202EB3E6B23CB8658F9D6E0
-:10292000E07E0938C0E44F2E64AC33B3AF1D956F21
-:10293000E6A5C0785FC7F1C69431330EA88DC1F209
-:10294000821B5843B2BC976BCBB93F560B2622C5AE
-:10295000558C54CABBACF5EDF83DE5611A37A9D6E4
-:102960003CCC3ABE0476FCE1F61EAC9F0B8B756442
-:10297000D12BCACB14F80995E5D0B845AB4FBDAE05
-:10298000527580C67781F0473FB5165F523E098B7E
-:1029900074921CD0D97C90F777AC95289FB3C64829
-:1029A00063E8D7C6F32AF626E455F0F2DC6CB3DE12
-:1029B00078B1C37E8EF9DA72DB39A6D19BA0DFFE37
-:1029C00048FACF665F58F4D9072F7FB2DC50ACE7E6
-:1029D000989FD2F8276BC57CC1DDC17CEB39A66B13
-:1029E00037C223E2D4F0DB6D3DA704C8A92CE2C8AE
-:1029F000A933B53A8C87ED9BA0AFC0FD914BA406DF
-:102A0000B48F40C16812C56B7C1DE84F83FDBF12B7
-:102A1000EBFFDED70976485399E5FCE3EF0DFED3D3
-:102A200022BE6F1C5F8EF05DEDF002BE7F46F8AEF9
-:102A3000E0F8FE3B80F7605952FFE4AA81EF6D8217
-:102A40002F760EF1EF0ECF876596F38BAF7A3E6D42
-:102A5000AAF6BF71FD5FC13A1C33711D66FEC165E8
-:102A6000B4F7507BF3BC34B1BE69A6E93F98E7C424
-:102A7000EFC4CEF1AEADC3F17AE3E77A74EE153F61
-:102A800047CC1B89E78871F8F3687E718E189E79B0
-:102A9000731DE545F7738E391FEB4759FBDFB41BF8
-:102AA000F9AC2D613E9759BF6AE6448237BEDE0914
-:102AB000345F7742FB1A737D6B674EDD6D58F00112
-:102AC0009DA87D4C2E31AD0EE78B9F3B4EAFB39E44
-:102AD000DF7E6FA6B65B9CFFCF443A36CF69FFA37B
-:102AE000E363C14C1EDF11E7E5820E474ED116228B
-:102AF0009EAE367861FFEAADF4FF37986FDD4C0B80
-:102B00003F7DD1FE317E34F5BEC89F00FC1A88DFC0
-:102B1000A6723569BE84F013C3BD2C827ECB5416D9
-:102B200091F15C221CD019C641637C6D54125FBBCD
-:102B300062F723E6ED46F917BF1FD1B61BED8BB840
-:102B4000FEFE559D3DCF616E9DF57CBEFD955F8976
-:102B5000753F6AE593811EFF7BE576BCC4CA267E7D
-:102B600096DCFDDF46D8EF5F2CA679DE89DDBFA8B5
-:102B7000DB6DBFC7D0B0DB9EDFF15D3B5CACD50E3B
-:102B8000176BB1ED574679EB6E03CA2E33EFCDB517
-:102B900042EAE77EC572920BE25C17CA36B940E59D
-:102BA000EC8187EBB7828E4C3E8DC1D9273FEF9BDE
-:102BB000BBEDF9790333BF452EBC8DFC30F078E7CF
-:102BC000F73B04DEFBBBDFB15815E5C6BAFAFC2FB4
-:102BD0003F2FE6FF59E5C9975F07BF2FE24ABC2F99
-:102BE000C236D6D9E5CF65C3E72A4F2A7F2EAFFF7D
-:102BF000A0F27EE58F0FC76DF63AE83E8AEE674990
-:102C0000EFA33495F373A9187F9AF751163C9CDC17
-:102C10009FFEAEE94F8B7877D0757E85F5BC6B74DF
-:102C2000398F6FE796C7F25072697D8D1CBE00CA5E
-:102C3000433CEF610AD380A7162E18918DF035FF23
-:102C40008E8FC7FCE027A7C7C7AB36E713F3BC34AA
-:102C50002FBDC69AD730D69C27109F2F40F3ADE7E3
-:102C6000EB9007ADA67B5E31BFDAF831E1B5C5293F
-:102C7000FCEC4EE2EF78DCB883E4CE22B7A0FF276D
-:102C8000775BFD89DB7EFD14C9370C5FE0395EBCE4
-:102C90005F7BDDE5F42B2B37F5F12673BF8CD87EF7
-:102CA000CD44B82FD5DFE24747A5ACB81FBD6F8232
-:102CB0003607FB833F3DB7BCE0D2E3009E16119E72
-:102CC000D6DAFD114BFDE2725B5ED2F9D517CB4B24
-:102CD0005A61EE7B7F79492BCA6379242BCA2DE791
-:102CE0004AC17925E905182719E6487A8FE21E734B
-:102CF0005FE3F95DBFA4F5B408BE33CBDB3379FDE8
-:102D0000B77EFD6C9DC9576BCA2DE717E2BC85E500
-:102D10001F8E629CC7925FA439AC719F92534EA4E0
-:102D200087A5DBA4A4F9337DF8A5D51C7F5B6C1FB8
-:102D30009BCA797C5FC7B8E36231EE3736D0B835CD
-:102D40002BF8B8897CB3D5C4DFD6389EB6129EB4B2
-:102D500058BECD8358C69401F7F8F8F8E27E4FD0FC
-:102D6000197E01CF755A0C4945F9AA372EA3734530
-:102D700056013C09FB141C96BB0D4587986F5C05FA
-:102D80009F0FFE598AEDFCC042C630B06B2B96D126
-:102D9000B9F3248DE7AD4CAEDA200F5129AFE547EA
-:102DA000B8AEA285EDCDB8BCDB6A7F2127CB67E941
-:102DB0008EE5B3B0B7460D05FE36E1C37B216B61EE
-:102DC0009E7762F92C5565EBACF92CE12F97CF2259
-:102DD000E27F4B428057CBBE8D34D739B282E33588
-:102DE0007E0ECCE8FCF6465633EB268C2FE3BD2D49
-:102DF00078DD6DDE73BB90CD2278FEBF617A2AC587
-:102E0000F17A33199DABC28664544FC23C12FE4B1B
-:102E1000195D4A715C37AC0BD781E7B2D1AFC1F015
-:102E200072EDA068127A7E234367012FC6FD8DCD17
-:102E30000CCFD5F447E87CEE86157FAEC77997EACC
-:102E40006E15496071BDAF8CF2B856079CEB300E21
-:102E5000E9979986F1EC2AE77BFC9CC643789A5B5C
-:102E6000CACB022F6EA6BC67C58B92506E3CB16177
-:102E7000CB214B7B5734251DCF05DF2E4FB7DD2BE4
-:102E800062B297E8E082DF11C173A86E85752900F0
-:102E9000479D2ED3F97BE7B635AFE3FDB1A57E257F
-:102EA000E0807596344A94FFB5D8C7F1F49726634D
-:102EB000CB21B0615386E5D239CC059F87A2F12D95
-:102EC000B59D14B7077AE95630AFE70199E1B9B774
-:102ED000C87F9A67D28BC063CAB28F092F17F03CA4
-:102EE0001CF1529849795073001FAA8FCEF93721EF
-:102EF0009E525943F41A98F756BF83452D7168586E
-:102F0000BF2D8F0CC6A6BC3385DED8EA093FA90FBA
-:102F100094F07C34B92A8AFB7AA190EF2B94034871
-:102F2000EFAC94D3A9C07F6A029DBA13F2C312E931
-:102F3000B40FFE2BEC78EF5458208AF4764C26FB25
-:102F4000A277A7924179573B1D9477C55884EE31FB
-:102F500075B2C18136949B5189CE096E33F126F04A
-:102F6000CE58C3E6E518E76EC80860FC9F391A36EC
-:102F7000637ED4E2481AE5DFDDCEF6521ED41DE8AA
-:102F800021C3BC77329F0BCBCB59809E12CBA7FBC2
-:102F900025B7EA12F185CEA2D53701FEA2D7393383
-:102FA000AD7955FDE635C1CACF5ACE23465598F2C4
-:102FB000D2A3FB799EA76EDEFBD1283F28B3ACD409
-:102FC000A32791B7A545FAD72B0A2C7918BE064638
-:102FD000E7D345E1311543E2FD9F9AA08DC5F2E4A8
-:102FE00042ED166CBF07ED3CD0078B0E8F7D02F5CE
-:102FF00059CB046D3CD627CAABD3FDE7DF451B8117
-:10300000EE7A505E511E613EF1E140E5DF9555F4E8
-:10301000C9BF2BA7F598F977279DFC5E19E5224FCC
-:10302000657DEFA735DE46F5E27E5AE2BD34F62334
-:103030005E8605196DE3F0FE6E03AD5BE03D113F6A
-:10304000CCBC97B6C4FF4A8F347600F2D67C60DCE5
-:103050000DBB187D18FCFE72F59A9E2CCA235428CD
-:103060008FB02587DF5FDE844D30116814B7070706
-:10307000557239BE25B3C11F80FA2D4E9E0FC3F283
-:1030800074B6604C7CDC4195B238176A403A00BB9C
-:103090008FEC2561AF8A76F7997AA1B14212F7CE0B
-:1030A000EEC7F696FCEE46DA0F6F34E210E776FCD8
-:1030B00047E740C27E383EBC81F269DC5A727BA190
-:1030C000B922A6CF9B69FC9D429F6B9B70FC19D7D0
-:1030D000F816229FB94A64D6817A6CEE5D24779FF8
-:1030E000C1BC51B06926EB1B4A86C27E3F52619E2D
-:1030F00037D56722BA58B7C6F349A3C50D7ED47732
-:103100005B8625BFF77DB282DBCF13AF3F2FE3B8DD
-:103110005B9681A7320EF167501E9BB1086409943B
-:10312000C1DD3F84E7321EB4038A502FF2F6BE7A27
-:103130006803FBD865E22B7823D00FDACFA3EDF933
-:1031400048E229DA25E65B81284FC77527E6B98969
-:103150007CAB1EC5480F24817F6ED95A0FE56B6585
-:103160002FF7A09E6CD14A68BCC4BCB72DD96C04A3
-:10317000C29598D726F2A644BE9418F7B90A4E27EE
-:10318000226FCAEDE77A0B9E942713AD50CDFBBB9F
-:10319000F6FC36915F83ED29BF269BF1FC1A7F0375
-:1031A000C37E6E2863FBB0997F9698570572E8201E
-:1031B000D1411FFB88919DD15264E60D306DF332F1
-:1031C000B48FF0FC3690C4BE0281807AD005FA0933
-:1031D000EB15797505A6F27C593BAAB428DC83F07F
-:1031E000B9FC3139FB3B82372E67DF35E5EC09ABA3
-:1031F0009C75BFBAF509B4BBB7489C0EB700DE9FFB
-:103200004E421F1F98FCB6253339FD7C6ED26BCB26
-:1032100084F08738BE96C5EF777C513BB3256E6747
-:10322000723C0E909D09F8F8CC2AA7011FFF2F19B8
-:103230001EE0B709E58625CFD45959D07F9E696233
-:10324000FF2BBD277C0DC80DE43FF0077D95E40FF3
-:10325000723A16F2387EDFF6CAE4F53107C85180BB
-:10326000076D026BFBDC4A2EE7C64DD5732B492F49
-:10327000F3FBBE5B83FCBE2F8B6AA4F78FA7EB35F5
-:10328000C8A72C6FFC25E6DB60E6D3EAF56192F374
-:10329000F32FD17EA339BFB9DEBCC1A43FB64ADA51
-:1032A000AE54395EBED4FAAEABD42623FCCD7A98A8
-:1032B000BE97B025CFA11AB0B47F9AAC17E3FB2D0F
-:1032C000791B69FFDA80E024909B731CE71FCA9585
-:1032D000281FF85969103C3DE0B125A1EB59959C98
-:1032E000EEC18AA57A7642F35BE31C6B4DFD16CFE7
-:1032F0000778FA09EB3DA61595FB5618163D86F1A1
-:1033000092A793D0C5C24ACE3FB27B8D4D4F26B611
-:10331000BBB5D245ED56569AF10853EF2D72733F67
-:103320008A1D01F82C7A75DCD4D0EDB4AF063324B5
-:103330008B3E14FA8F6A2CEFDD7E7EFF841DB38FE7
-:1033400023D6799F49A7625EA0D755C81FA077BF33
-:1033500081F388FA4532E3F18E6E3BBE009ED59C28
-:10336000CED88A587E96051ECDC1C78DC1D1638740
-:10337000E33E733FC64DD5EEC371401FAFC3676BCD
-:1033800008E82D095EC71784BE8DF50A335A73739A
-:103390002E6AAF6EC076A26CB1579B2BEDF6EA2673
-:1033A0005C2FC8D1CDF87E4F6AF2797798F81AB0C1
-:1033B000EF065C269F3F88FF4CC22F6DBDFBD2C637
-:1033C000028BB9DDC6BDC497F9E32FC1579C8FEFBF
-:1033D000BCBE81F4DB0BA6FDF1829329985703BC98
-:1033E000154896EF73B452D81B91E18897E7FAB16C
-:1033F0003762EDFAC9ABFF1ADB9176257647DBB46D
-:10340000E36964777CD29186FAFDB933A1A476C7CB
-:103410000BD93B8627B33BF6F76377BC6ADAA7077D
-:10342000DF77911D517C8EDB1DC5E776C8683FBCF8
-:1034300059A9D27A8ACE74CB3AC05D8C76078CB308
-:10344000DFB43BB03DD91D9FEC9011AEA273DDD42B
-:10345000AF18CA687714F56377001432E2E1D9E255
-:10346000B67FC5FD4B5CEFBC897A8F956E0B7BBB3D
-:1034700029BE23FAB5E56D4CD369BFEDF4535AA4C8
-:10348000DAF2E20B7B39BD27B6EB8FCECAE4AAD6BF
-:103490005E58D75696BE83F2319586C7B16C180A2E
-:1034A000FF3E1E7E5F039EF7CF051832B15DC34F0E
-:1034B0007A51AF186E1F7ED7E02FA94BB99FB396F4
-:1034C000F99C53E37288960EA01921733C97C7D7D5
-:1034D0000C76D2F7D332088F8D3E11CFD951910B94
-:1034E000FDEFFFDA28BAF7137A040682F2D46332CA
-:1034F000D58BF8CFEBC318E5E703FFCEA986F127FC
-:103500009BE3839ED3EE85F68B4C3B6CA6ECA5F635
-:103510000FE6F1F6538DF3F5582EEA75A978BF8CB6
-:10352000C9EBE5BB316E8BF608B47FF0F9709907F3
-:10353000EA538F032438DE0917C52F447CA1E0D855
-:103540005EC267DA19972DAE910A122F6AB15B5CE1
-:10355000096526D70E4A269FC433310E71ED2CD350
-:103560001F1DCB6EF91CECAC0B6C7D2BAED13D3A24
-:10357000747037EBDB5FC419CE4FD446CC827D1C10
-:10358000E5D4C96FD95F01B8867DDABF73E7ECB1C6
-:1035900088F71D0AC5754F7E3B8DF6E9C0234A3B6F
-:1035A000C6934E029FF2F8ADB112E9F5403A13E727
-:1035B00040518CCB1D88DD67CE5EA959CAE35E2BD6
-:1035C0007C1FF5E08121A2FD8F79BD281BFFB4127D
-:1035D000F3360E0CE3E525AF3DD369101DF72AE461
-:1035E00057379EF626939F9366DBE9784EE11A4E95
-:1035F000C797E807F27EC6AC24FD52AAB97F75A032
-:1036000016401A8778D24B67015FEFEFB9A7750CA8
-:103610004C3571DAB7BB498E5ED3BB3699DC5F306F
-:103620008BDB53D1E208F95BE0C3737F97298730C6
-:103630007F750E53C7A35FFFF0F4E77E3316E6797C
-:10364000A368F47839095FDF3D2B97C689C37754A7
-:103650005E8E72E9A3F716269303DFAFD417DBD78C
-:10366000C3CF479B772884FF0766FFDF2730EF2112
-:103670005ABC83E277FBFFE460E8AFEC1FC3ED7E4A
-:10368000BCA187DFA51C00F8764E4E427700DF5DB7
-:10369000B30AFAC2377936E3F9A113B56F617D2217
-:1036A000BC2AC6B9015E30AF022847523EFC2FDD6E
-:1036B00018CFDCDFEBA0A0CA85331D3292605B4FD0
-:1036C0006E299AAB33AA4EC94852C5BE4736E3D1DC
-:1036D000AFBE5EB6F1DFE49E545BF98E866B6CE59F
-:1036E00025F5C3E3FCC8F01ED0485BD9EDBFD95621
-:1036F0000EB209B6F2C2AAA9B6F1CA7C25B672B951
-:103700007FB6AD7DA5BAC0569E9DB7C4D6BE3A5011
-:1037100067AB0FE78F53F00A1FD0E5F771BFD38E69
-:1037200069C4E75B7AEEF1215D448BC3E44F1F4F20
-:10373000EFCEC678F5EBFD7C57EED42CAECFEEBCC9
-:103740001E4C239493A0CF3766C6DB07737B6DF1C5
-:10375000F8C3B3B87D7A7056623CBEBF7B705C3FE5
-:103760005FEEFDB7443D3CF7A67B482EB52D942374
-:10377000789FAA39EF2D2FDE1B7B7D218F23B46527
-:10378000C33ABD948F41FC7570D16D23F05C2D352B
-:103790004FBF06E5BFD0DF257911761AEA537D11B8
-:1037A0003612EF9741B9CEBC675692CFDFDF68BEC5
-:1037B0005F854FD0DB332DF84AD4C741CFB897C1CE
-:1037C0005D60D3FFEAA3EFF72DCCE7F19ED24F2245
-:1037D000A5789F7AB6F6D2217E6D9ACB9F378AFF65
-:1037E00098D58FDE7ED3CEAF47891FF69F997F5144
-:1037F000F9FF87261E5F7FA6C9C3A2B0BE134D3E48
-:103800007AFEAEC94FEF8F36A9F46C69CAA367B4CC
-:103810002940F5FFDA5448CF434D1A3D5F69AAA00D
-:10382000E7E1A630B57BADA9869E479A747AFFF191
-:103830002CCE97570B3C5A9E8827840F3A24C2EB14
-:10384000424CD59D724E93ADF21DF0FA6932BC5ECA
-:10385000A91E8916EF1D1EE67A2A291F0D9D2DEE41
-:1038600085713B798E4E323F069F0BE37359F1F819
-:103870009C1B4D9AC104E7A0D9050307E701337EDD
-:10388000732093D53CCDFDBA4D12E91BDF382ECF06
-:103890007F100E913C1F322EB93CCFE923CF979178
-:1038A000DE6287316E8A6945288CD7E1FCC9E32145
-:1038B000C6A09C8BE281CE2B051E2CFB15B8123CBA
-:1038C00024AEBFB4489B8CE3E03D14E7E0BE7AE44D
-:1038D000C6DECF348C493D9BCFE17DF8BDF983D066
-:1038E0005E7163308AEC1570F00A71BF99698FB40C
-:1038F00077D667F71DE70FC57B49AF3F18B3739EB7
-:10390000203B26B11DFC0E111E506F59F090440E45
-:103910008493ADBF4C7EBE7723F43FD0CB285EA608
-:10392000A24D0DF03FA7F0EF341C38E7203C5FF0CC
-:1039300048241FDD0FDCEBC1D8F6B3DFE5ED8C6A60
-:1039400089EE2FA475ED57D14E0DF6EAD7E0F7C6F4
-:103950000AA3954EFC3E6868DAB8408A850E428A12
-:103960005D4FA2A51AD33B140C1B9C50BE2EDE5EED
-:10397000C6FDCF8D9773E8DEF53FCE063A9D7FBE3C
-:1039800081A9F9667C35399E564B96789BC202AD6B
-:103990009373C8EE3C741D9EDB8C661199E8CA20B7
-:1039A000FF5BC02B7BC3742F4FF8E99F4ADAFDB34E
-:1039B00093D80FAC5EA37337E670D0B95BD304BD68
-:1039C00069369DCF279CCBF85EF93F12E8B45607C5
-:1039D0008BA27D6164B8087F89FB35B9B07213AEE4
-:1039E000CBFFA5FDFA1D92F53B0137AA33C89FBA5C
-:1039F00000FE14DE436956F8FD28E3447AA4938060
-:103A0000647968B7DD2FDF1CC0FDFF7EDAF7C83FA1
-:103A10006A047F0BFDAF6DA61CBE3F35A383818278
-:103A2000DAE66CF81F58DF22B17007FA5B29D74736
-:103A300058461CAECED95C9FBBD91D8390CFBCBE6F
-:103A40009927CF4C48E6EF71FFC419DBF76C1FF9DB
-:103A50001B66D9EBD2FD98F7D8326EF52EBC8F6578
-:103A60000CF1F0F34E25ACCE03FC3C64DEAB653EBE
-:103A7000836559EEEFCB4C398BF1D9563066F07C2B
-:103A8000F79709F038AF101E174A18F447B35C11C6
-:103A9000CCAF51511E015CAD7E07F1CD2695F3FDF3
-:103AA00026AFE6F125D9B72D884777FFFB29E76CCC
-:103AB000F2611C7B87D7417CD9AA2A5B73A0DCEA20
-:103AC00055F8F75A554745B27CAD8F6673BB099AD6
-:103AD000A4507E53703ED931FDCDD366EEA728A702
-:103AE000E6EB1AF18F1A08E37A9ABD5912C63745E8
-:103AF000FDAFCDF1459C78AB6917A5E6ED8D62BCB5
-:103B0000A665D8AA09882E0FD83967E1BD277F2F6F
-:103B1000D9452D433C35C9CEBFCECFE671B6ADCE2B
-:103B20004005E2736BBA831980BFAD39C9F5608F68
-:103B3000B97FCDEAF830D12DE063B4D4B7DD6F4C56
-:103B40007DB9D9B9C38FF7D0B68EBE95F2BCB68E0B
-:103B5000E072B7F1C889CE0DF9C80FDF62FF86FCAD
-:103B600090A5D0BEA92CE041FDD5E2537CE8EF4FF3
-:103B7000CC5AE7095AE497A0FFED6887C0D3396CA7
-:103B80007E0DD2E385C2D40022BD4C3E42DF0969DE
-:103B900009803CCDC13CA4069FF5FE3FD8D37215E9
-:103BA000C0951E70D8ECED4185767F4165BA87E8F7
-:103BB0007318A7A3FEF62F111E2F4A9CF117699FB9
-:103BC000A9D724FB2EC9B82A8E574137CE4BD0CD6A
-:103BD000A5E0B7E9BBECB8BECBA91AB10ACF2F1E3E
-:103BE00062BC7EE491F39DE8AF2796BF2C7F362B15
-:103BF0003B481E378F72113D25F6DF9AC3E1F9600D
-:103C0000F647341F861570DF323D3C8EB4BD7070B0
-:103C10004A32793B6BA25E5465B18B324BF7921EF0
-:103C20001D5CC5087F5E35EC1B05E3788FC940A39A
-:103C3000806FC7677F3DA55E391E951D0D2CCCC7D3
-:103C4000233983BFCF40BE6598FA64CB0D6F30CC6B
-:103C50009FD93E5209C89487702470313BDA5B6863
-:103C60008F137DD138504D95998F92C252781E5046
-:103C70005548A1FC1B07D79F1AFC3FD4BCC22E9904
-:103C8000FB3FD43C5A52F1158F7F65D5325A4F2CE9
-:103C90001F05BF2783E3E88CEC0CBC108BEDAE5BFB
-:103CA000CDEDA86CD62BE1F9DE0D98952323BD73DD
-:103CB000F97981653B281F07A6C17C12C97090BEA7
-:103CC000FBAF379C9482F0767BD1AA71B83F89EB29
-:103CD000585365C6B362EBB8381E049C034DA74227
-:103CE0002F377BB89ED54021A7A0119C10D72C93CD
-:103CF000D7535CB3C570FB500F372BA077B3A877B1
-:103D000098E2A00971CDBFA4F0B8A7B48EF9A4229F
-:103D10008A6BE6E13E35B2D400C61D0729BA07EB2F
-:103D2000D346298CD355C3643C3F89FBDBAA97E774
-:103D3000BF35529EE0AF50AF41BBAECF2E2E8FF6B7
-:103D40005D42AFB51D1BE5A5B8B9A72E0DFDEC670B
-:103D5000FCB947D06FB9E0E1F95BA25D57C2F74CFF
-:103D60005A4C39D75365C6C753FE2263FF197E5597
-:103D7000C13CB990671CC9F76629F93940AF29DF02
-:103D80006E54DFE474B65A7C876C35C9FF77D34D27
-:103D9000FAADD79750BCD8B4E398A6A9BE4971FB39
-:103DA0004DE84BBFE233EEC271CCFCA93EEBECFA1E
-:103DB0000786DF57617E4BDC3517E71F14CB9BC3AB
-:103DC000F913EDB6FEF0D966FABDCDFE10E55D5CE7
-:103DD000409995E45C443CC1FEEC463955D06D9762
-:103DE0002F697976F9D2EA68A03C2EE366E6C33CF7
-:103DF0000F5615F05BED5FB0438F571133DBEDC904
-:103E0000FBAAB9BCEBCA54158CBF9478820CCF1BAB
-:103E1000946C9DE17EB8FC818BEEC7CFABB8DE6FB2
-:103E2000C95B1E467FE5E1E9DF24BC4CACE079A527
-:103E3000A21DE8CB0FAA2C7E8BC83BB8ECEF23F970
-:103E40001C948F78B9F1A1B6692BF9F791FCCBE9F5
-:103E5000FB48CF78F8F791BAD2F534B4BFBEE8F793
-:103E600091EEAEE6F41AF27CE3E08C5C0B9E7A7481
-:103E7000CA0771F9CFD3B9CC0C337F24310EE47665
-:103E800037D0395AB4B86189350E2CF0F77393AE38
-:103E9000FF50AC539E4F7F7FDF41B4438CE1BADCCF
-:103EA000669C734BF1B709FFF32B3229CEA49871AE
-:103EB00026D7799DF27A3B27EAD7565BF49D3BDB08
-:103EC000207D97F63DC6EFAF7FCAEFAFA76D6421A7
-:103ED000BCAF1EFA6C3C9D3F85A229C467D33F0945
-:103EE000D0F7A7CBE4A75A73A1BEEB9842DF85EFCA
-:103EF0009A9E9A857AEDE363DCBE4DEBBAE9C82D54
-:103F0000502E3E5687BE3EC81D806570DF754CFF43
-:103F1000C4F1A5FCC702F41F2DE72062DC5F361D4B
-:103F200026FAD8D7D44DCFFD4D517AB635F5D0B35A
-:103F300050D14A703D85DD7426C9A69C817A0B1C40
-:103F40008527A0BF851E864CD4B56AE2BF6E5BBBD9
-:103F5000B4BC1E5B3BF05F4BAB0B308F87E3D3856C
-:103F6000DF0D83F1E7F6B0CD92FA1F4A5EADAA1ECF
-:103F70001879F58FD505179357FC9C34D4637E27A9
-:103F80002C811F1DD52AF90D31BE34CF4B859E6E75
-:103F9000C57F823E6DCEF826976FB17C0C7EFF50B8
-:103FA0007C677EE3EB1FEDA1BCD277CC7A83FD4426
-:103FB000B3D433F6C92ABC0FF2123AAF60879E7BA6
-:103FC000BD6B15DE9BBEB52653D100BE123C58CD4D
-:103FD0008CDF7F11798A8978FB9FD59CAF8FE7FAB8
-:103FE00028BEDE92CBFF5E4162BB37ABB9BC409AC4
-:103FF000B0FE1D8FD47EEEFDBC2AC635F1D6EAE2B6
-:10400000F907FDDDEF78ACFAE2F73BFE60D65FEA38
-:104010003EC72FCD795FC4790B282F720FD285F858
-:104020003B1B51F37DECEF6BF859D2717E6ECADD0C
-:104030001BE7F8CCFDD414F33BD47B893ECCBF877F
-:1040400020EAA79C8BD5EFA3F9627FF740A7F88FF2
-:10405000B85FF7F3EADFEED960F99E574BEC3B8986
-:104060003C6FE95313FEC4A7B85F12FB1E147B6BB1
-:104070008F66F91ED44FAADF396B7EAFEA10C16795
-:10408000DEAB79348E875FD3FB84EF0374BDFEDA39
-:104090001EF33ECE6FA8BE21F1BB5BEFEDB1DEEFAC
-:1040A00079B4FAD42AB3FD515AA7F99DAE247461AC
-:1040B000D2ED993D789FF032C67B97C633BFB3B53A
-:1040C000D9E4A3FEE819DA9FA2F6B1EF0FD7795031
-:1040D000AFC4EFF1BFBBC7F6FDACFEF1F5475AB771
-:1040E0002EE665667E13E717911F26E8C23B87EF31
-:1040F000C776931FF0FE1FF55F316078F88CD69578
-:1041000070AFE852EBD837212CCF4138FCB1FC62BC
-:1041100085CA5F121E711F2C913F86CF91445EF3BA
-:10412000609A273BF61DCE6B06625E1877048D13EE
-:10413000FFBEE7F57392CB9F2F342E532F2F6F4482
-:1041400094FF3F19A999BA607100000000000000B7
-:104150001F8B080000000000000BF3176060F8518F
-:104160008FC09C687C5AE3BF4C0C0CFACC0C0C97AB
-:10417000D818189C39191884F8C833E7229ABE7BDE
-:1041800040B366F030302C636560D809C47A5CD8DF
-:10419000F5D90822D847817E5F01C417E91C06A320
-:1041A00078F0E01A11068649A208BE9E18AA7CADD6
-:1041B0000882AD2345995D4E40FD008850BECB80FE
-:1041C00003000000000000001F8B0800000000003A
-:1041D000000BD57D0F7C54C5B5F0DCDDBB77FF2728
-:1041E00037C9029B10E24DF863D04037103058D4E5
-:1041F0004D041A90D7AE69ABB1A576A14A151156F8
-:104200006B9567D5DCFCDF841002A202455954107F
-:10421000ADB6A9A2B59FE5BD0D508A7D7E9FE8533E
-:10422000AB56FB62A5B45AA5F1594AFA7D086FCE88
-:1042300099B9D97B6FEE6E962A6DBFF86B87B9F38B
-:10424000EFCCF93767CE9C99956C6E52760E21A70C
-:10425000E1EF12421EF21242C6A4D2CAEF7DF986E5
-:1042600027AAE8BFBDCED04E9A54FE626E71B4222A
-:10427000557F1611B05EED2F96FC91D07AFF4EEC73
-:104280008A937EDAE71FF486685E15EC04DA394912
-:104290004DC1BF0468F9902DD445F3C993361FA1D1
-:1042A000FD4C2776E8842844F645A6D1EFE29773C3
-:1042B00089AE7F737AF16691240B08D97F27112389
-:1042C000B45E9BFF8225033E425E6C4CFEE5C864F3
-:1042D00042C2C9A9A242FB39D07808F3FFD678F8C8
-:1042E0002F471C8444491E8E533BF72371296DB719
-:1042F000DF411AFA68BBDAB0E058AA1B2FCAE7B34D
-:10430000DFCDCBE51AD1B2DC4FCBE9F7DAC0E596C9
-:10431000E5513A23AC97C7FB191AB0433D850C7A97
-:10432000719E27EB2DE7398EB7D3F255036CBEFB98
-:10433000DE3E7119D0214972234E484F96BD05F8D3
-:10434000EE77090A29A5F81D5884F84D027E6917F1
-:1043500027DE61F8DEFF892DD444F15DEB927D21EB
-:104360009A2722A5072DAFF59130C225D294C271AC
-:104370001987FB2A9ED6438A7451902EFD2E4A1728
-:10438000DFE8F05EB2594278B579F6C33CB368A76E
-:10439000D1957EF545FCB41DB1E68391F8A1E3CD3E
-:1043A0003C733835BC46E6F6FFE5888BE0DF69FAFA
-:1043B000BFF9F2F37F39529ECA5F3274D890A71CBE
-:1043C0004D5CB329BCF04F0552F1CF035A79292B2C
-:1043D0008771E28DCA9F2751FEEB6D247F9E44F9C1
-:1043E000AFA7D185F9EE4619F35D8D41CCC745DA0B
-:1043F00084D231DE4D122A6D9F17A6F575E3E5567E
-:10440000D3763AF8FC21D990F796070DF5DD8A624C
-:10441000288F2B37DB1294EE9D15B6845D0038A8EB
-:104420008C9C0B70B830A5E0BE16A4F399C49A908A
-:10443000750EE5576500CF4B76D24CF3394AD8B6A6
-:104440008CE64B82769208D1F1730609A1FDC5EF87
-:10445000246423EDAFBB72B66D19CD77CD71CA76EA
-:10446000999004ED3FEEA4FD9C4A2A2DD0CF34292B
-:1044700004FD905EF1B7802717FDEF741921131525
-:10448000E91D5B0E21A52AFDAE9F9F530D825CE7BF
-:10449000561BBF4F5496DF4868FD8944F7BD34452D
-:1044A0004F6D5C2D6F1ECF3CCE396B4CFD9BFA2DB2
-:1044B00051066AE48A54BFE790C126D9F7CFDC6F72
-:1044C000B856003A858892A83C7B70FBD67C9C77D6
-:1044D00064660ACFDD0EA607CDF236406CA83F8891
-:1044E000388684295C8A624B74D17EBA4A6DC83F93
-:1044F0004A1B4980DE5A37E1700CF25DA592D24C1E
-:10450000F3A5E5071B84E984AC9D2023DF75ED75D9
-:1045100092E610832340F9B444E3D353033565C0D6
-:104520008702096DA4E5A5CAD126A82FBFE6511CB4
-:10453000D523E747D6B0F9639ECE7F10FE316B647A
-:10454000BFBF9C258523C0B72A4938293C9D939A33
-:10455000EB543ACE03AA48407EBAEEEC7B1DF01C29
-:104560009FCCE035CFBB449196025F13FDF874BC3D
-:10457000924957DC00F332C3A1E98BEF37CA288F89
-:104580005B1ACB317DA051EE033DB1E513BB257E17
-:104590002F13987EDEEA88D8003E758E2DB113F574
-:1045A0004F74EBF5347FFF77C7CE8075E0E6393680
-:1045B000D42F7FEE66F8BE5FE8BD8A607D49C1FA00
-:1045C00026F97F400C377F8BD6BF3F5840542ACF07
-:1045D000258EC30BCF85FED69455AAB4BFFB6FD9E9
-:1045E000F80EB42F993345B1D3F613AB8FBE4517F0
-:1045F00071B2E5D44030E2833C93EB923563FB2605
-:10460000513E19AFF4DE04E397544B4AA234C597E8
-:10461000C52484E39CD3E025497974FE2C5E9999E6
-:104620003FCF9E1EF8FBC85511C855410AEEADDCC0
-:104630003E31D37DB160437E1996AB6A26574F5EFB
-:10464000C8E8ACC9D59609BDEFE5D27CCF37189F35
-:104650009AF9BCB4FA680DD0B59BCA4F7E909042CF
-:10466000A7F2B140F33D4BB91C561F1596D3F67F08
-:104670007AD5A31090A725D6FA3A1D3FA752E3B8E2
-:104680000FDC62AB8DD07ABFBC76CA1F9D30DE12C4
-:10469000490139EB11CB717CE5BB92A2EAE859B232
-:1046A00084CA13E5AF925BB8FC98E46AB4F1E38D79
-:1046B00009F22E95A30D8D4112A6745BDFA8A07C94
-:1046C000ADE37206B62829A4792E67A47C06E6D34A
-:1046D000D99F8434A1DCB994248952FA6CA07D93CB
-:1046E00022F89E0C87E712920FBAEA42042769A3C8
-:1046F0006BFBFAE17212A64C4F7A049E57FFA88614
-:10470000E9787288E59F6BFAA3DA428570839BE5AE
-:10471000F70AE535EA5C7DFB83D8BF569FE693B583
-:104720009374FD41FF157A786C35505FEBEF8DA6E1
-:10473000A21A958EBF9EE7A5E63C963FCBFD770B70
-:104740007D41CAF464ADA99F6E81E349FD8F70D8A5
-:10475000971AE73EE1BDB06A28FF4318F0A495FF21
-:10476000A0E93F5495D6FF8844B608940E33E64539
-:104770008B08A5BBB72E49C094DA60C2776A7E2F3A
-:10478000E1FC7C152CFF60D32761C0B756FE8CE09E
-:104790006F027C03DFF8C6121244212164F3CFBB01
-:1047A000AF7F01FE5D9E4FC81C3A8ED24B14DA8754
-:1047B0006D524C807D47708978D4200F9CEF287C07
-:1047C0004F08349D3137FA35580A2DE053F5F0691A
-:1047D000E38F06AF06477AFE64E39BF9A87641F5BE
-:1047E0008B73A97C790F3B424E05E6210BA0C7F3E2
-:1047F0000128AAD7F24EED473A11B12F0876B4B985
-:10480000DFFC794524A19BE7674DCF2D9067787B2E
-:10481000454F579A7F4D8FC727A0DEAC917CA7CD1F
-:10482000CF0DF3236007D3F955E9E7F75403CC2FF5
-:104830001DDECCF35BEFEE6D8858E8DF8B6D7CBF3F
-:104840007B71F597A07F3A1E01FDE5560651FFCA20
-:10485000301EDD6AE69EDADF005BDB74E3C973E9D4
-:1048600078E5670F9FA3F1B18FEA2F85D6B3853224
-:10487000F3B1599EB5797B61DE02F011DB0F98E749
-:104880004D08E523FFFFBFF3FE5864F4BC85F6AF87
-:10489000B27931F9F807CDEBE3170A505E011E3B00
-:1048A000E3E7A0157FBD2B28867DAE99AFD3CDEB76
-:1048B0001FC5A723E79519CF675B0F65AB5F9B5FAC
-:1048C000F3201E7BAE61FB849E43F3D1EFD0F3C295
-:1048D000A5E3008E9CF8F9244CEDDF29D03FEDAF25
-:1048E00047B32F36578DD23FB32FEE6B247DAD9358
-:1048F00009793A6700F7C3144E6CBF95DA9F09AA8D
-:10490000E0AA5EBAC5BD948EB7F5BA8D6EF02BF5F0
-:10491000707BB1EAA587372CA0F81C776D7EA59D2A
-:10492000B2428F5BFBBEE7F929F4FBE66BF877EE4A
-:10493000BFA2DF5F82FA415E3F1D5C85D2403482B8
-:10494000F242E1D2E15F2B7FCAC6ECD227C1CE3A58
-:1049500017F633CCCE2AF4F42E05FAE66C959407BC
-:104960008591FDFE6FAE4FEF033B8DCE77CBB5ED5E
-:10497000456057EDDB317BBF0FE0BA86A03E3F3785
-:10498000B1ABDFA1C0F8AA00787ED241343B0BD78F
-:10499000F9A26B34BAD60B974EC276DCCE62F9EF31
-:1049A0000FAFAB5F47BBA538CAF2CF347FB7A64580
-:1049B000D495ABDFAE0917A7CA5F6CBEB106D6DDD2
-:1049C00019AEE89B7329E96650BDD742E198212AC8
-:1049D000F618F0CBE680A5BDB8FB79574382E277A5
-:1049E000F78E2913AFB55847281591CE5A7EE62188
-:1049F000A39C3D09F873021E99DDDA4DD10BF583B6
-:104A000051A505F039F31009C17E349DBE4B47C74F
-:104A1000E036A3BE9B211AE775B6E6F31191D97E65
-:104A20009BF74FD7F5976D6C3E7690A3992293FF35
-:104A30004F3B9F24E089D911BFB1EAFFEF35DF1961
-:104A40003E3A4EE0B31F27681A275DBF667DA5D6A4
-:104A50001241047F7C1109013C79F36204FCF87671
-:104A6000DFE1A04AED3D511EC0D411180CAA54EF4D
-:104A70004A41A510526771A810BED3FD11978F8EC1
-:104A800026D4ABC3F9CE26D0A3EB218FF2B716CB39
-:104A9000370EE7D761FEEE094C3ECFB1DFD30F7A78
-:104AA000B80C940D856B5DFF1B0DE0072838E00BFB
-:104AB00081A951E00B11D0C35A794FFF7B4117D820
-:104AC00071077CC44DF93D5F0E137DFBF5FD7F0D35
-:104AD000CAB4DCC7CB7D8188A17C63FFD4C22045EA
-:104AE0009187977B82512CBFBB7F4EA10276CC0170
-:104AF0009F0CDFBDC5311CF7D25FACB4A13F76B1CE
-:104B00002DE1D4E9ABF8E219A8DF9708D1A9764ADC
-:104B10008F9A5F74BBC07E881FA81807DFD1E6415B
-:104B20007F92F87F613F0AD9D36807F9E4A3E7735E
-:104B30007AD953F4E886F30AF403B3738A383FA7AB
-:104B4000506B9349185FCD6174A21C9DF23F63FBCB
-:104B500043297F35E60F1BF27E3911867DB418A0FC
-:104B6000FA81B6F786D530D05D2A6679BB2F9404DA
-:104B7000FDB1F91B2404608B149F507FFD1C9A57D4
-:104B800080FE116CDF398BE5A56054857CBC92E515
-:104B90009DC5B124E4D74E65F9CD1A9DC9A3463E03
-:104BA000207F42BA770EE7DDCD501ED7F886789B7E
-:104BB000A17CED454CCF168935FB00FF9BFB3B0BE1
-:104BC00097D3FE73811F68FFB94B42482F8D2EF794
-:104BD00029365C6F35BADCA7CCC07382CA5C8A09FF
-:104BE0009C9082F4A83CE7669B0CE71DE7DB123B38
-:104BF00005389FEA760FD07A9BCB6760798968E7A2
-:104C0000FE01E60FDFC9FD0165D4BA00BB63275F73
-:104C1000AFF7DD332517DAEDDBFABF90DE17DBF3F4
-:104C2000B0DDDA72767EF32C5DA7C14FF74CA30B93
-:104C3000D31FD1FEA2545F3FD1E8C2F4078D32A644
-:104C40008F523D0E69372D4F82DF81962769BE6FE7
-:104C5000C05607F27F4F2335CD68FBBB1B5D1F8B12
-:104C600093C15F21637E7D6310F3DFB6D5AFB133AF
-:104C70007F8AB782CEEBE99727A17F2FF4862D920A
-:104C80008079CBA4607155EABB869F6FDB6AEF0425
-:104C90007EFDE18088E31071A0EB7CEB7ACD506F54
-:104CA000FA1B22EB2F30B0F1B28065BD0EA8F7F8E9
-:104CB00011063771253D69FAEB06782BDEE6F00523
-:104CC00093F969FADB00F51E3BC2E1F325BACEB3D6
-:104CD000AE772F8C7BDEDB1CBEE2C4C645D6E37EFE
-:104CE0001FFA73E5337BE573E0CFA8C2756087A038
-:104CF00093E74D4B55C146E9EC2A188841BD6955EB
-:104D000031A18C8E1FB83A26D8A6313BC346F36E2C
-:104D1000E887A6E797D3725A6F1394FB75E5D09E88
-:104D2000A6532B5879E09BC6F261BDDD40343B357C
-:104D300009CED6E0578CF92936A61F9FB3FFB606D9
-:104D4000F87D8AC4CAFF1BF260772D36D5F7B0FC18
-:104D50006FB5FA39ACBD4D6479573E9B77CE565747
-:104D600002ECAE0DF3DB83CB7CA9F9E62D889743EB
-:104D70005E9BDF86055B83CB74F3C9FBC2B6F2652D
-:104D800015E9D715B7622361DDBA3BA5B782840B5D
-:104D9000FEF9F5CB5775EB06AC2BE3F8BA30AE9ABB
-:104DA000AD2B146F2AB35719DED65F64C45BEEC512
-:104DB00046BCADBFD888B7DC4B32E3ED977CFC74C2
-:104DC000F8A3E387F5E36F5C681C3F7F9171FC8D6E
-:104DD0008B8CE3E75FF6A9C74FEAF9A6B7C638BEE2
-:104DE0005C6B1CBFB7D638BE7CE9A71B5FA34F67BF
-:104DF000FF16E3BA5E15217AFAC5FB3B8386753D43
-:104E0000C4D675AD7C6DFF4F83B0BEBB617D07FF1F
-:104E10004C395BDF2BDFFD28087EFBF5171D0CC22C
-:104E20003E633DAD7BB822B56EECBBE856DB63B4A8
-:104E3000DFEF4C65EB4CFF45CFB840FFAF2D67EB84
-:104E40004C9C9FE77635268FAF74A4E6E58FBB7147
-:104E5000BFA7E587ED25F2BB1AE0C378B98DDB4B20
-:104E600085CD616A8BBAA68A867C67052BBFBDB5E6
-:104E7000B059055F8AA816C23AE42D277FAEB0D894
-:104E80006F69E36BF0A41F9FED8B53E34F348D3FAD
-:104E9000D130BE96774F63E5AA38A916E0D9CCF792
-:104EA000CDB788BF43FD72F6E09BD61C9EA4878FCA
-:104EB000E553F0B1BC06DF5DE2F45A75D2DF13BEF4
-:104EC0000B4CF8BBC084BF0B0CF85B23569F11FE44
-:104ED000CCF5BA4DFC790309DF268E013922686FC3
-:104EE000C644999F07B1FEAA442E5F303EC4ED2C04
-:104EF0009512934B59793D5DD796887C1FC6EBD7A9
-:104F000099F29AFD0ACBD169F4C358DBAF12617AEA
-:104F10009BDA1DA19DA8D743284FA97D07F363887D
-:104F200062241CB1D007F78AEC7C5890430D00A78F
-:104F3000E893D08F9AAE7EAF2870FB5A359CEFE491
-:104F400092C1A41DE008128C4F2227BFAC5C3E6DBD
-:104F5000241C921889C2387659220FD2715AF3AEA6
-:104F600050F4714C8F6AF004C3088F2433782431D5
-:104F700014B6F2033F2832BF85D60F8590B71F24A1
-:104F800060276AF0B5B9230D4BC19ECF93104FAD8A
-:104F90007EE379F96FF8BC5EE4696B9A733F02D1E6
-:104FA0001810BF34B61AEDD096EA5A17F0A542424F
-:104FB0002EF0D7B7FAACE389B4D46C77C6A95D0AF2
-:104FC000F9766A9742DAEA7BB20ED69DE3C0C7163D
-:104FD000E7DAC37A2E642349DDFED35BEE214983F1
-:104FE000FF348170BA957CC37767B0C8D0CE315694
-:104FF000447BBED5674B40A8D168F0B773F8B57A4B
-:105000001D62CC2567B15F76068DF09E3DFCB1F642
-:105010005E479F6C05D76785378DAFCCFD4B05523A
-:105020000CED623112D4F3BFDDC1F8542A70C5987B
-:10503000BD9EAEDCC3DAFB6839D8C5BE8802E72F57
-:1050400054E4314ECC0572A0C3CF78DEAED5C1CFCB
-:10505000A3490CFDB582126B003E72154B783E6081
-:105060006EA7A51EDEBEE393EFBC8EF231C685F2BD
-:105070002128547E2CC6795C0C8F75D074B3181E11
-:1050800007A9E3943D6A2527631C4C8E5D9188E255
-:1050900062A12696F0CFE4FDF66AF0AB313CF7CA88
-:1050A00016FEB22CE19F99827FBA6316C2FF39487F
-:1050B000D3C13F8DC3534042FDB06F0706857E09C3
-:1050C000B95CD19FCBF5F07E0B387C84DC8474D343
-:1050D000CA3B391EB29DCFDC2CE7D3939A4F1D9F5C
-:1050E000CFC24CF3F9029F4F8F83AD57AEBA8812EF
-:1050F000A47C959F862ECB79FF5B87E972D319F14B
-:10510000D557B39CC7F2D43C9672BE5A96691E51CD
-:105110000E4FAF9DCC3902F13313F97A43EA0D7487
-:10512000D9AEF19593AD1B84DC6CA0CB3DBC9F6CDC
-:10513000E7B33ACBF96C4FCDE77B9C2E77649A8F1F
-:10514000AE7E13AFDFCCE50AED96ED8EBDCD607F70
-:105150003C2E46DA1DB352E3D17A1DFA7AE3DBBA6C
-:10516000B47A6BE1BBB078B85E371F9FDB450FE1C7
-:105170007EAC0D6C0C6ADF7CB1EDC55AB0C769BB63
-:105180008DD87F84AD9BB4DDDDFAFE67B6DDDBCC68
-:10519000EBDD07F59A2E3DA5F5BF59DFFF764752A7
-:1051A00083631BC25137DCDFFDFA7ACB1D7DCDEC6A
-:1051B0009CB0583EEAD5D935C1ECCE7D1C81687CC7
-:1051C00000FC95C4DF0B7647BB18DB3E00FC408D2E
-:1051D000BC9DF4FB6DCEB020D0F5530EC71E817A76
-:1051E000F9AA53B603DD6A633F82BC6A2311888B38
-:1051F000BCCF7BD776C8AF115DB23304F696824739
-:10520000433D0111E379DA84A80AEBE20931FAACF3
-:1052100003ED1EDA251DE7B60225D12580FF96088D
-:10522000CCEE60706DF05E1D07389C142E880F6EFA
-:1052300033C145C7C37D79E718166F4344522E42E8
-:105240007F764F08FAEB1F732BC21B6F72CAD03EDA
-:105250003EF95684979645303ECF1143783B1C2E3D
-:1052600019E2F1EEF3AEDA0CF1766BD45CAC8F7030
-:10527000C0FC279621FC6E124B2E2D05F5D51BB6D2
-:10528000013C8B258C4B8E0736E2FEB66B315DE41C
-:10529000E8B85DE51B5568777CB107E3EBDCBE5EE3
-:1052A00002F15605974904E280DC815EB433F317BE
-:1052B0007958BE98E038F99F67F1B20E322097D145
-:1052C000B420CEE28EBBCAEBD5A560C754B37854E8
-:1052D000A2865F86F8B63CC2FFECC5FDD0BF63BCBA
-:1052E0009DD84329FA16F40EB7CF8D5AC8CB70BD9E
-:1052F0004496F592D9D5CB8F8BD9D5EBCDB25E2222
-:10530000CB7A4956CF492ECFB58AF718E6FB7912EA
-:10531000DA1F5A7C5B0EB5FC87ED935266B7EBED56
-:1053200015079152F60AF0997D494638D6BCD51436
-:1053300038A0B36F02923F80FB8D0BC8052897A35E
-:10534000B43FD1A8060E38469F2F485852E7271F72
-:10535000ADFE5AB0F79CE9CBBDD3AF08A23E9BF699
-:10536000359E2E616925FD5E016903CF7F8DE7972C
-:1053700034842DC6AB91981E2E27918C747073F8CF
-:105380008FC2993F6D522ED2FA16E7E35AEAABB0BC
-:1053900099EC46A3BE73896A2D9E7394B3F8412796
-:1053A0000823C84D88A07E7190A45C86E78BE19CA1
-:1053B000A56353F2E3088E45F9F93F85762254231D
-:1053C0007D428047339F98F9C267E28B4FCB2757C6
-:1053D0009D253EF1C6ED59C98FB737CB7A892CEBA5
-:1053E00025B3ABE78B0BD9D5EBCDB25E22CB7A4997
-:1053F000566FEDBF48DCDF7A590BF861BC5F74195A
-:10540000F26BBFE831967FC967C8772F34B6F72DA6
-:1054100032B6EF5E646CEFBB8CB57FAAFDAB9782B2
-:105420009F275B39F9DDDF2827E5AECCF5F3178F31
-:1054300022572E15F7936E5121C900AC5F749D124F
-:10544000300D272CECBBE7B9FCBFE0607E9CB8A810
-:10545000E2BEF69F7D9E3F9098DF489BEF68F06A22
-:10546000FAF7F7766E6F99EDAF61BFCEC9D3A76734
-:10547000831E21102C4D64854E8DEA1B0FF1842074
-:1054800054C4539EC0F36973FF5D705EC7FC2EC1A8
-:105490007A1D1CCF3B995FE5E7A5ED413CAF9DBA76
-:1054A0002B08FBF4AE0982A59FE594C4CE05CBA2E0
-:1054B0005EB4333A1417EAC3AE09EC1E5397238146
-:1054C000FEE3AE52637B17B71F4E496CBCAE3B6325
-:1054D00004ECFFB6A9BB1A605C67F25F8942E1FE8B
-:1054E000EE8418C68FB63BD93EC0195609AC0B2EB8
-:1054F00045C5F377333C712D6E882482F5BA79D790
-:105500003B19DFFC9CCE279B79BD2B49585F0E339E
-:10551000FCA5C3D7DE33C4D7B54ED6AF127423BEB5
-:105520008E57135C4F8090F6D9048FC6D9DF20D1F7
-:10553000F387793D060A337E3B8D7945BC2A233FAC
-:1055400099FD30CAB6AF65E4E70EBE9E3BC9D7B140
-:105550005FA7120B83BEF35624C832C42F0993B140
-:105560009CEF14F8BF56D546E5977241682B6575D8
-:10557000EF98CE50D2227E6998FE1592515ECE7081
-:105580003D9BE9A4EB9937B59E1D27DDE884EDB678
-:1055900091EBACF0AEAD674AE0AA8CF3EE6A647EA4
-:1055A0002B42EE207D309F57EC481F5B395137501E
-:1055B0007A392B443CE7704E4A10A0B3AB9C24DDF3
-:1055C00039E9E7F51AE73B259879DC1E8EEF6E4E38
-:1055D000A774F5BAF9B9E76B1D0FB5C0FE2D6F1EA4
-:1055E000938361BE171306FE1C92985FA3CBAD3464
-:1055F000613C4B29F38F8C983787D32C57F134F7C4
-:105600006934B9FDABA4303DE44AA0DF41932F4596
-:10561000F957D4735D139A5DC0D471E541F4131F3B
-:105620002F9708DC8331EB032DD5ECC84B48B70B23
-:10563000EE2BAD7DC51EEAB280D70D44D0F9F5CC76
-:10564000FA7A347D72DFA7D4273FD1E47EA43E41AD
-:10565000FA5CDBD1BA1FE8D3E566FEEBFC3A952C89
-:10566000D5CDB79B8FBFC4C9D7856206479743AED8
-:10567000D1D3298F7EAFD1EBCD34F44947F72B211D
-:105680001870560A0EF3FC763959BD7C18BF627447
-:105690003C8CA403C3438BD39A0F3EABF9343BB38A
-:1056A000E3E36DBCDE368E576D5EA3C989D67F1FDE
-:1056B000C757DE3C93DE175503FDED1ADEEA4CF5C5
-:1056C0005CC67A1A7E4427B357B47562B4FEDF967F
-:1056D000187F98FB4F2787BF19964315FDB2DA381C
-:1056E0004EF21CFA0F8E53BDDC5549F7A3BE418C18
-:1056F0002FA07B7D8C6F82F82FBDDE35EB2F4DFF09
-:10570000A7D347E67DCB68F5A58094D14ED2EC9A1D
-:105710007C7E6FD2C5E381370AD6E73C435C8EA816
-:1057200062CF2AAE0FC244001F2442F8FDBF707F33
-:1057300013CD8F0D494A17F83FC4F9FD3B687ECC65
-:10574000CF9CA42B042E9779FDFD94DFD6865D11A6
-:10575000281FE72A1DBEA7D53B1BFC5ACCEE22F61C
-:105760003B5E877BC063AF1409E0D549E6609CF6D9
-:10577000F13594769523E1192B12323E9FA6DC3F3A
-:1057800080E787B0A5FC8A119F64B12E0F7E6097D9
-:1057900071DDCB76DE6678D2B51B159ED43EF4085B
-:1057A0008CEF2499D7B5339DDFB05D9BE5BCB4FB8E
-:1057B00068DAF7D2213B51E07EFB9080E939435E05
-:1057C0004C4B86DC984E182A200A255AF1501EA60A
-:1057D000E387C6E3F7A2A1424C0B8726621A1C2A74
-:1057E000C5346FE87C4CE5A1A9986EE072983B3413
-:1057F00013F3DAFDB79CA14ACCFB873E8FA96F68F3
-:105800000E2BE7E7A91BEE8C12F0574BB00E51F9A7
-:10581000689BBF1CD725F3BC36B8D83ADCCEEF095D
-:10582000B79BF4761F2F7FCCC5E47E03970B22C66F
-:1058300088DE6F7E3FAFB7A12C8AF677BBB61E1607
-:105840002E37AC87E6FAED69EE273FA395737848CB
-:1058500079FD28F461E7AFCE4014EF0D101245BD7D
-:1058600044C4A841EFB66BF067798F70C3FC6790B2
-:105870008FDD549021B4D0FD856D0D0F83DE5970FE
-:10588000EB7507A8DC7DE88CDEE68271BFB002997B
-:10589000EEFBAB6E0F82DF77C3FC7BF17E1398DFEC
-:1058A00010D7DCB1E08ED8C3C87551B4B369BBBBA7
-:1058B0005CBA73D0CEE5B737ECA2FD29AD36A2E8CD
-:1058C000F8B5E40E0F51F4FAEB644121B42FBE2574
-:1058D000DFF0BD686591A19D764F22784D99A19E1C
-:1058E0003CEF3C43BD9CB9338CEDF839B9AFEA428B
-:1058F000433BA74FC32B3B47A4F437AC1F1D823556
-:105900001D632EA62FD3F1CD152EB6AEA5FACF4C22
-:10591000B774FD677B2F24C51F69E781E710B1F8D5
-:10592000E279604F39E528DE5339F3FA67771ED9FB
-:10593000D633EBAB1CD05705A04F044C7DA0AF0A6B
-:10594000408FB831D5EA9DE97DDB75A06F7C3A7D4B
-:10595000338BCABD053FF8DC99F5CDF9BC7CB29B11
-:10596000E99B759CAFCC7C13E4F5D681BEA9185D8C
-:10597000DF04DD99F54D251FEF1FAD6F3A67DC1B86
-:10598000FD16CDB92FD8D6F0104D3B2A6FC53CD5AA
-:1059900017A29B9677CCBE23F6904E8F9093FFC9AB
-:1059A000F892F3436EB5517F68FDFB43263DA2C9D3
-:1059B000C3DF28D7A738BFA6A3CF914F29D7A7CE3B
-:1059C000925C9F7275CD83F3C56CE57A64FDB33B41
-:1059D0008F6CEBA9B5247909EC4BA678122DE0BFAA
-:1059E000B4F586D8BDBC28C6ED743EEFE07E1EE659
-:1059F000FF9BE10A2F02FE99E18A2C76D3F63797B6
-:105A00002AE3609DA6F92FC2775D3E62CAD79BEA62
-:105A10007FC594BFC254BF415F1E57947170BE18BA
-:105A20003FE4C0F3C1B862ABB3E2A7856EC62F876F
-:105A30005C9128F4776EE2BC7140179A5F86FDB9DD
-:105A4000597F347F8D29BF1CC74FE5AF3395AF30E9
-:105A500095AF34E557E9EB779E9A781FBEBFF14BBF
-:105A600007D969E14F7A95EB898EC9B7479B995C55
-:105A7000DE06ED3BA6DC115B46902F08C06DF79962
-:105A8000F67F94CFF4FC7288F7F3F309B7E2BEA96E
-:105A900083EE9F308E11FC7816F8F9B59BBFC3A535
-:105AA0005C8FF71FE28537A39FA3A3B819E3148E79
-:105AB0002B129ECFC64BADDB7736323F5347B1F545
-:105AC00039C2AF210857678F9049CCFF076270DA5F
-:105AD00006EF0931FDDE56DA8EFA554A5ECFFC1B21
-:105AE0008551F46F3CC8E927F962E8577016C72C56
-:105AF000F7F51DC3F830FA35F769F8E0FB481D3EAD
-:105B0000500E9B3B3F3C00EB6BDC6D2D673F7633CB
-:105B1000397304B31B7FE4FCD9FAB01D2EB558ECE1
-:105B20006BE30E1627AF4E607E00918EA3F72B9885
-:105B3000C71B9EA7699FFD00C753DCCDE2ECB5FEF5
-:105B4000CCF03CC2EB3DE2667E056D5EA2CCC61990
-:105B5000ADFFE7E0B216F80164B31FC2A8E7EEE0BC
-:105B6000F51D0163BD74F8B973183F2C1E4BE3DFBC
-:105B7000D1F85D1BE710C085FB59EB7DB872B21AF6
-:105B8000E3378E137F6F17EC9B45F97588E3B88D6B
-:105B90006E93C0CFDF22AAE85F501522EFC4F34F07
-:105BA00076FE709BFDBC10E83B178FAB20105711A1
-:105BB000D0C525829FF35C8CB37804CAD7A84E1950
-:105BC000DE3719724F6471AB27D7603C4527DDA9DA
-:105BD000C3B827DC250978CFCA9EDB8DF6BCDD5E15
-:105BE00019B38A33153D8C6F2F39B91EF56CBBC2C2
-:105BF000EEDDB48B51577E05B8AA5594D74E257368
-:105C0000FCA2390ED2219BE30F8DF89AE661F48D48
-:105C1000F3F537EE0E35E8E393821E37960FB98D14
-:105C2000F075007C3E802B86F1A4F1629B0DF0762E
-:105C3000B6E0D3C6954A6D11C04B8044315EC515A0
-:105C400014715C9B97E137DDB844113FD0BF1F73DF
-:105C5000B6F039BCFE46193F89C483FCA4CC73D589
-:105C6000EE86FCF3CC2F6F1EE788277A8147E71773
-:105C700016E528FAB7B4FE168E6171DE6231C1FBFB
-:105C80008A1289D495D2F9B714B3771645DF2871F3
-:105C900011C5667F45BA7339763E824554446BFE22
-:105CA000C0C6F5F078013F19C060D15C50E91321FE
-:105CB0005E4011D83B102181C595CFC538F280FBDD
-:105CC000B3EE7709F62B843790D3DE33E8571C40C8
-:105CD0003FD767DEEF28F0BAC936EC1742534F17AB
-:105CE000A4FA05FD8B4EA593A74FC3B9999D687F74
-:105CF000CC0E176DEC5E1529CAC1B8C3B6C0CD2E47
-:105D00003D5D9B3C6586F55592DB6F1272E0DEE7E8
-:105D1000CAF04006BE6C0339023F62F135E181F200
-:105D2000F4F53438453A7D2B7F68BB144D3481BD82
-:105D300058E263F1AA620CCF473A84FC195D553AE8
-:105D4000FE2D96920097BF2AAC423C6347812D04FA
-:105D5000715822E93E8CEF3BD9178732C9AB582CDA
-:105D6000BEAF9FCF568F310EA465147E6FE3FA3A13
-:105D70005DB9430A45ADF4F0131EBE8E79ACCB3F3E
-:105D8000F6D63EE6B15877F6723DD5914755E9E72C
-:105D900018FB001F88C5075F073CB48D5990593F19
-:105DA000C946FDF45FDEF04F609C0C703C67050750
-:105DB00081C714B2B0FBE579188C988A070A30BE07
-:105DC000863820612C9CD2B2BF75550F26C1EE7665
-:105DD0002CF585817EF6F06E02EBA81617640F7B1A
-:105DE000DEB1213DE7B2F8A072E6670DD3FF308E39
-:105DF0006C6EE6B831BB29FF2B339D1B9FC5F72284
-:105E000034F8B53875F3BC9EF2D6BEED9965858F32
-:105E1000ECF6419B28BF10CA2F1BE9FA4E91427A3B
-:105E20001B65CCF7340631DFDDA860DADA588EE97D
-:105E30005A683A07E23F62F152D88F041F0E5E4B58
-:105E4000AB6C029A605CCB8EF9B08FEC1ACE135516
-:105E5000807325B81F4FEDD0BF7A36CEE7E76C3C94
-:105E60006EB67D3E9EA30DE7B7B4815DD8C5E368ED
-:105E7000E5B50FCE87FDE3A609DA3E39ECFAAACEE6
-:105E8000FE9AEC75B073A652AD7D4B1BF4E7167904
-:105E90009EEC996FCC9330C0E376B1FC42EFD3080F
-:105EA0000FAA003ADEE5DE6730BF6932F73B54D413
-:105EB0008F8247E6C768F728CC0EAAC8473F8514EB
-:105EC0000AC1F502B2298FC39D653FB0FFC1F5EE4F
-:105ED00015EBF5322537A3AC6B1C8ED1E84FD18181
-:105EE000F605E86115C67DD58EF270B6C7DDE438DB
-:105EF00033BC48D5832A5CFDDAE7895EE4A5EDFD75
-:105F0000E1BE6429CDE72C4EAA28BE598E5BE8E598
-:105F1000F7C9E87C41FE353C6B76C74D40C731A9D7
-:105F2000FE1C8130BE23E1E6EF09670BEF728F6C38
-:105F3000E8873C5E5B98E9DC654CC4064146C3FAE1
-:105F4000A2A0CEC38335583E2F9C6FC8E7561719C1
-:105F5000EAFB43658672877C9EA1FC6FA5D3D73D83
-:105F6000B281AF23A679CD379567DBAF7B8D5D819D
-:105F7000F7204B45CD1EDD88F7928F038E413FF60B
-:105F800056E23D5D3249BB8740C210AFE256C2C8FF
-:105F90009F1E12C2755A2A36DAA962C068A7061B6C
-:105FA000D4A4D62FC425B8D74838EEF03AE563F12B
-:105FB00020DA3919EED72782AAFBDEA152D6CE32DB
-:105FC0009E414B457E5E8677EF4B473F4F358F13A3
-:105FD000FC4AE63835737DE21395A33AF94BDF4E60
-:105FE000244775EF6AEC00DACF4AE13FBC7B29FA1F
-:105FF0003D9C84DAD114CF2DC12B4894CEB31DAA79
-:1060000050FAC521A57CDE1E9C21631CBEC2E86A35
-:10601000733139F98E5731C473D87D4C4EB47AA39D
-:10602000D1FF363B8959AD67AF7AD93EF9C45DB12E
-:106030003FC1FE527D99E03BAE7D8D43F8CE655564
-:1060400072A11DFC26AF7BC7E27CAA0E84ED97EA05
-:10605000FAA922ECBD6FFA67D7FB5335FF3039E957
-:10606000C2B8E03D491617BC27F9DFFB4F43FE904D
-:106070000DDF15DD7338B37DD5C7ED2BAD5EDF21A8
-:10608000B65FED1389373F939DC3EFBF55264D7122
-:106090008722B103FD4FDCA9D8C1DEE96B7409B0DA
-:1060A000EECFE0F3AC4A86EDB09E8E36AF7D26FA99
-:1060B0006AF384FB8730CF561FBB0FD82AD3F9224F
-:1060C0005FB3F7B2D3C13BBCEF97ADF121F9D9BBB8
-:1060D0001792232A5BCD7BB47B8A1A7CED009F004C
-:1060E0002983AB3DC0E8D01ECC4C87160E9F56AF1F
-:1060F00035C0E8D04AED836CE0117D4678A88D2745
-:10610000805DE823893A7CD34C252FC33E08558512
-:106110000278D897BC1FE0857B1760CFE75509D779
-:10612000C2BD8F28B30FFD55C9E4DE009A2711B810
-:10613000975130D09F7C9B961F6CF0E2634FF2B575
-:106140004792D08F280FA2FC74C160681F4D6C0766
-:106150007BA70DFE4955FAB8EEE002B03F44C2F409
-:10616000029538451CCBED130B79D79DEF0BA79DFE
-:10617000A976E9F066B63B9DA43EB3BEE2E7FD2AF0
-:10618000FD0FF48D6CBA1F61B673CD71F017813EAF
-:106190001F93C53D8C4F394E2E79D005EF21D8CBBA
-:1061A0006D32BCC34C557A1EDCFFF1864502718D01
-:1061B000B9BE017C3A6B34BC53FD57C7E246FB883D
-:1061C000FE1E69BD8FF98102F55582C0EE1128F0DF
-:1061D000EE66A0FE50C88A4F35FE1CCEFB9E44FDE5
-:1061E000D8461271883B51EB6CB8AE759597E5E9CE
-:1061F000F74737F904BE0FD5E84F1471768AFE745D
-:106200007E61F7F4BF1FFDF3171BF17EA674B9D3AF
-:10621000C7F4D268F4FFB4E368741B291F4D9C6E69
-:106220009B50FF754ECA4EAFA4E8F620CAABB79C90
-:10623000841316ED9A39BDCCF7F65D2446E0F728B5
-:10624000ECAF307BDA3E6E76C30E92812E23E2AC49
-:10625000583F761FF3A7AD133C21186A5D1AFFF271
-:1062600024BFC0F5FF008BE79B733008E7C7DDB3A1
-:106270008E06E19CA3E713EB73C8857E7E2E127E0B
-:1062800003F7013DB3985F10FE40EFDCC6FE49CA3C
-:10629000D4F736C33B66EBDEF21AECA1F6C6CCFEB1
-:1062A00006A9E8BA28D81927DE1114586F84A23538
-:1062B000E7025CFD7396E3BB23ED55FBF01CA63BA8
-:1062C00094992E5A9C6FBB29DE36DDB9E1092EAFB9
-:1062D00065EA0D685FF614BE8CE3ACABCA3C0EBC3D
-:1062E0009795299ED7652351F4179BCE75DFE4E37C
-:1062F000BDE9E3E7138EC8972696C2EF72A8E81FA0
-:106300001B5B1EE9B751BCD5FBA3AFF9285D7BE64B
-:10631000DC5A0870C03B317ABA07A07F0BF8C6FA86
-:106320006D06BBE94459ECBFEEAC82DFA79882EF63
-:10633000D66BF5BAD3C4B19FA7D15971E3BEA71DDF
-:10634000E2FE297CDD85D9E15FA3F325E405D7448E
-:10635000680F71BE19F8D9BCDE8F8677331E7A1CA0
-:10636000031807D52358CF67A19FC95DCF9D4976F4
-:10637000AE36E7289EABF9926F60FCC477671DC606
-:1063800073B5123FA387DF378071A539D5EC3DC0C7
-:106390007472F400A79F281BEB1171C070EEB3DD7F
-:1063A000C7CFCB0299FBD3E024AE0176DE33522E69
-:1063B00071FDD9D9FDF0417C378524F15CA1FD55F3
-:1063C0003BDC4D1DC6C308B98AB3DF85E9818DC7A3
-:1063D0008530CE5DEDE027E9D1CED92AD9BE49ACD2
-:1063E0004AE2399BCBAF18E3AF43DABB88D9CDD3B0
-:1063F000076B11F30F8BB0AE823F1EE06BADBC029A
-:10640000FD69E9E8FA1D6F74A67F8CDEAFCFF65DFB
-:10641000FF6C7C78C2A718EC43333F3AC937CE688B
-:106420005F97CEBF7C82CB67002AEAF649DFF44B48
-:10643000D6F87DFBCAD1F0FB4D6BFC5EE501784FD1
-:10644000DC63FDFB445ABAC5A4EFB668F128F0231B
-:106450002185D85FE9E516F3D6D6D5137EEDFD9EEE
-:10646000A807D68D3275AE07C6DFD5BDCC03E3EEE7
-:10647000DA9C999EDAF8DBF9F96282DF77D1CA13E8
-:106480009C2F7798F4FC2B5CAEEFE7F2B5CB15F1BF
-:10649000E0EF55ECBF6AD1548ABF32CA17E05254BC
-:1064A0003A497EA6F14B55D3BEE40CEFB5F4F84D56
-:1064B000F1BD59DED3FCB478D901FC7321E0E1DFF2
-:1064C00051EEEDC95C94A7B2958C6FCAAE194CC25F
-:1064D000BE76E2265B42C1389628E2A570A5A86088
-:1064E0004C1BBFF77A2E5FDF89FD0E5B0994C3BD9D
-:1064F0007119DC2EF2D7301E669BF1F73F76B9C2D8
-:10650000CD12D8BF718C742465DDC6DFCB184F74F3
-:10651000BF5741C72D7CEB3DFCFD9442D3EF827CFD
-:106520005ABCEFFD07E13D21128F5E1F2B028958F7
-:10653000E9FDFFE47CA9341D60EF18C47CE45DDD57
-:106540003907A55F3ED805DBD58D35804F354E42E6
-:10655000932DF4D86FFD5EED777C0EC03B0B8E6201
-:1065600076FFAC6DE915037BA9CADA7E472DB13AF7
-:106570005FA17AE1B77E5C9F985E48A8F52C3D69E3
-:10658000473E99DC4D12F03B28F336C5FA1D20EA50
-:106590002BD93BD48571559068BE8C9AAFB47B32B1
-:1065A000F13AC2EA2F218930F211792D3836F57B84
-:1065B00027250337F5C3BEF820DD17C3EFA868BF52
-:1065C00057A2F1CBF898913F26C78DF971267E31FD
-:1065D000B72F53C822187F52B78DC0BE6E4C83AE02
-:1065E0003EF44706DF7B848E3FF9003CCC48D3DE87
-:1065F000CCFD8B24EAC8A1F87CFA2EDF2FCBE9046E
-:106600001FEAAE2D00BCEC721176EF22E2C27717C2
-:1066100048C4FA3C6904DF6A767F9AFA297DC9EAA0
-:1066200069EB5EC75B027BE7A2447EA714FC9CAFCC
-:10663000B1DFAD4BBD5B7121BE5B112431663F9272
-:1066400008A6AD9C3FE54B8B4BC11F1A7FDB2BC3CC
-:10665000FD2CB9C0E84F13F3EBF03DB061BB3B9F9D
-:10666000DADDB43C9E67D4A33539CC6E0DE5B07B42
-:10667000A1B297F5435C6AA15EEF6FCA118CE53E4B
-:10668000B5F0CBBAF25ADE3ECEDF2DBF24675107FC
-:10669000D833F2785ADF823FE7F171B57212081DE4
-:1066A00086F73F367FA37E967E3DDF94C3CE77E4A8
-:1066B00073F8B8C5D670C54BD9B877F37137E518FC
-:1066C000DF8D23324BB5EFF7FA6F158E507C9F703C
-:1066D000905A88576919634BC0BB69B78DD5E2C220
-:1066E00032EB098D0EC3F896593C52D175F20CBBB2
-:1066F000851C6BE9D63AE6A7327FBF9ACFA3F5BADD
-:10670000DADE4914AEF0012677CE00B13C07A2F2E2
-:106710007D75CE2C8B75BFB50EF77127F232AFFBAE
-:10672000E67DAEC8FD8BE67A4D9C4ECA2B417C8A35
-:10673000BB35C8FC895AFF270A995FD1DCAED3D498
-:10674000BF9BD48721CE18CE57E15C559A4412499D
-:10675000DA8F27D02B972A101F705885FD91422879
-:106760001EC1CF162268D7B506D97E540CF6D6D8EE
-:10677000209E84D4C97A3BAC88FFAEA29677F8A25B
-:106780004D39680F8505C48BC8CEF34F38120B0105
-:106790009F2DA53662F54E7F770EB373B72AF52F7E
-:1067A000965AD06F438E62B09F8B8698FD9DAE7EC9
-:1067B000AA1E836F981F832ADE3F200AE3C77A7FD1
-:1067C000F89E1CABF35B4DAF703FE4B26AAE7089CC
-:1067D00072E5AFE93CAE3FE4C0D8F44B4E6E3F08E3
-:1067E000FAD74EF56F17FE8E5CEF41F0435E03F76C
-:1067F0009F68FEFAB7A64925B4FCB5223B7F743EDC
-:106800009203E37E486CE82FF990BC9C335347BF5A
-:10681000A77224B6DEC41DA847357FDCB5BD0E8344
-:106820005EFDF666637E39A91F0B7E8AE59B1C24FC
-:1068300041F17BBD49EF3E94C3CE89BE4D62EDB0C0
-:106840007EB6F1F3BF1B7F324D02B9B97EA65C6AFA
-:10685000D7DDBB7A2E87D977EF533E527472B6C21A
-:106860009790601FF7EE9E99577C9E403F89F622D5
-:10687000F0A7E559C7017E2B6E8473B47998E1D6F1
-:10688000CEF3D2C121EE162CFD42CFE708067F7C65
-:106890008B8BBD87146E1189FB6288C3A3020B70BA
-:1068A000BFE5C7F7BBD5DA18C6D5A9CD4EB9258047
-:1068B0007176184FB786120CDE1F3ACAF94F8BABB0
-:1068C000A306C505B04FBBD13520815F79B518ABA4
-:1068D000839F4ED3CE659C8E68783C85DFF16C4DEE
-:1068E000723C31D48B6759EF90509655BD3A5B8618
-:1068F000FE8E713DF98BC71F9260FDF9F0B177BE36
-:10690000087278C373760257F38E3DEE2749DC3F59
-:10691000242490F3157BEC96EF48508C61FF37FCF4
-:10692000C88F7A71C593CEC462DA7EC533EF4E2725
-:10693000549E8E350F1E1C0FF87B4C60E785EAC015
-:1069400074589F5688E49B56EF8EB97399BC7FF0BC
-:10695000536F03D04FD8DD7F35F6DB77A543FF2E8D
-:106960003EC965EB0FADC7E2261F1512932DF487C4
-:10697000B61FFAE0511657B2E2594702428257EC6D
-:10698000DE2145291CAB777F84FC72E98F9EC8010C
-:106990003CAC7ED66EB0236EF8D127ED17523ADFAD
-:1069A0006027838B418EED27317F3CEC1AB4A35CCA
-:1069B000B3F89455A80268BDA77EBFE0D7B4FCFD2C
-:1069C000A09D4088EBFB877F273D07F9A88F5A6E73
-:1069D000D0BF91AF57EF7E57C2DF31B291C1E2CF46
-:1069E000C3F987D14E32D7276450023DB5BAAFF311
-:1069F000233BE5B7D57B3E7C13F86EB5493EDE8779
-:106A00007F148EB4CF2B734DF6F9EE82ACECA31B42
-:106A10009E38FE00F8233E78F28F0FC03DDA95A72E
-:106A20003E7EE07B1017F66F6E19E47BF563AFE6F0
-:106A3000109DFEBF2C97AD9BC71E7D64D7563AFFB5
-:106A4000636F38115BC7F6FEBE04FC3FC77EFCD700
-:106A5000B1E00FBA65EF7CFCDD9A5B9EBE745CA66C
-:106A60007511F835A1FF7D457E6EA43C2B80314920
-:106A7000C8CF786AA207E91D94605DFB8B4006BB16
-:106A8000F2E8F7BE4F24B0CF0E86C920E067FF9E24
-:106A9000770FDE4EF31F52FA382DE843E73FDE86CC
-:106AA000FA998A0D4D57EDF9F2972EAA82D4817684
-:106AB000F86A32887A73045D5FA174AD4AD1D55CFF
-:106AC0007E9C9C94E0DC60F5E3948ED3819E948E52
-:106AD000D347D2F143F8C79C91745C916B8C4B3ACD
-:106AE0004E566EDF0A857B0A2CCF79B57DD68D4F49
-:106AF0007F35A3FDA4E985D1F07C9DC0E09A9D1B64
-:106B0000BE3D17E4EBC91FECDA1A60745E4C1173DA
-:106B1000EC89E32584F2C91F1C8357031E06F73A4C
-:106B20006558DF57ECFD15CADBB1A75F92148C6F77
-:106B30002139C26C9A27C37F2F139A5F25B0CC8D61
-:106B40000FFFBF056FD2F637C2431E32D20FF307D5
-:106B5000A9FC213D1297D729A077136370DEAB12F1
-:106B60004C2E5625FABF02717D66BC3F956BD3F45F
-:106B7000FF305D216E6CD59E771600FFA5A3A7366A
-:106B80007F19E67F012D7FD828B769E594D3F7D820
-:106B90008E1312D807C9E724D946EDE1638E410967
-:106BA000D7C71FDBE59DA191744FE19FC71F9DE1F2
-:106BB0003EFC876639E7F8194DCE479FD799E16DBE
-:106BC0005BAEC2F65726FC7D70D25AFF3FCFF5C6AA
-:106BD0002A12AB2B9A3872FD1249441D5F9A82F734
-:106BE00003881FA3F07EF0981DF787ED7DFB518F82
-:106BF0009BF5C5AA3476F49BB9CC1E58F56CFF748E
-:106C0000D06B1FECFB29F2E5AAC7DF91C07F737040
-:106C1000F753D240454A0E607DD0FF0ECE073FECC1
-:106C20009F0EFA6B759A38C0DFF3F9ACFE99B1FF8D
-:106C3000D58F7F64E8FF06B54F423FD928E3BC2FCC
-:106C400086AF84F9BE7FD8012718E4FD3E7B9D9571
-:106C50009DF3025F1F353CB5FB67BF9E0BE75EF9F6
-:106C6000EC1DC6D6A6F0AFF0F77B5F72F0FD6DF8B5
-:106C700075B0675AF224BC8FD0EABF02FDF55A7F87
-:106C8000BD267CCA01B906F603F2BC48957E5FA515
-:106C9000C19F17B619E0BFC55F374EF1B1FD9942EC
-:106CA000F71FFF03B64D466E008000000000000095
-:106CB0001F8B080000000000000BD57C0B7C54D516
-:106CC000B5F73A73CE3CC24C2627AFC9D37892F0C1
-:106CD00094804312DEB40E0491226A505AA9F5AB97
-:106CE00003F28821C9A4F8E25ABFCB8444F4029F7E
-:106CF0008D95166A693B70A152217690A0B10DDC8A
-:106D0000012C06056F105F78B18D5A152B24631482
-:106D1000B4575BEF5A6B9FC3CC9C4C84DEFBFBBE2D
-:106D2000DFEF0BBF76BBCFD9679FB5D7FAAFD7DE02
-:106D3000EB0C28DEDCEA5400D93D6B366461AB5ABB
-:106D4000D41409E02BFABB2AD6028400C603585D8E
-:106D5000D5E07761AB5A407300FF7D45FFA7785BB4
-:106D60007BF0F97BE5D4D6B5348FB5F157D48726BF
-:106D700005B657F2B0914A25DDBFC2BBB61860A375
-:106D8000F39F1FA7FB2B8376D58E6D73EA3DBFA5BE
-:106D9000FE0609AA65EAD3F3383E6875A8DB55BC40
-:106DA0009E0E0BC265317AF25424321BA00CE9A06E
-:106DB00016FFFC3001DF2B488266A8031C0129590D
-:106DC000A120B5C6730FAAFE62757CAC2FBBBAC1F9
-:106DD0008FF35E2DBB2CB4FE07732D217B31B537AD
-:106DE000A641D9403E18ED03ABAA213262F0FBADBB
-:106DF000D98E855B80E90E5A681D9223B49D08F1F7
-:106E000081A67A8069030DFF873C74C4D18D037C11
-:106E1000B40E45BF6FC565D14D3B04B94D213960F6
-:106E2000EB84084029D2AD96B05C52A1479F240A5A
-:106E3000D563006E4CF57F93D6993BB451A2EB1EFF
-:106E4000A8E6B612FC12DDB738EBF2FC5FB33E5891
-:106E5000A09CE919A9CB175FB1C12AF8AF28A00CF3
-:106E600029273A36ABEF8FC679E87E268D0AB21C09
-:106E7000C6557D67740BC181888FE3F32333676444
-:106E8000126E8C71CD8EA29312F2DB27A7A8294532
-:106E9000D8579033C4A753A9CCA71F4DC399F1FE6F
-:106EA0008F4FA56E95511E8F48024F41C213E10AC4
-:106EB0001A1F277CB8113F6BE9B9198DBF65BC5803
-:106EC000A0BAB952E7A487F827FE106F8CA7958A5D
-:106ED00043B57B89B73E4DA1796C105A2B11BD7E0D
-:106EE000E6A7035AB91D02616E5DD0CDED5DC4E722
-:106EF0006C928397FB69D0D33A149F9BA356D7AA71
-:106F000078FDC7B333245A9F0B549DBF8579D41F96
-:106F100094BF3391BF8E187FEDC44FE7407E3A4057
-:106F2000653EA47BC1BB761CCF0B115CC723D3216C
-:106F30002433885450112F39FA3A33C127117D84F4
-:106F40001F5A5FF602B13EF3FB72A195C7E5439865
-:106F5000DB42E8E636C3A14A0AD3734A97EF3BF017
-:106F60009533468FD1DA09C138FFB9429CBF98B931
-:106F7000ED963CB47EE3AF9A71F887CA83BE2A1CB3
-:106F8000A7F85D3E3B2EE5FF54CE201082F572053A
-:106F900048AEAE9E8573C18DC3BD36888CA4D9839F
-:106FA0004C5FCA48D137EC8B1D051531E8C7E7ACFB
-:106FB000A73E3C45CF59216E1CD121DF9A467C7FEC
-:106FC000982E4C1EC8F795A79AB29E8B9B77AB9ACA
-:106FD0009A45EB848930F12B39F63C4CCA40233377
-:106FE000F0F9CF5605B39EB3C6F8D0E2F867C6A550
-:106FF0000F019CF24DEC138EB36238465CB29D0BD0
-:10700000AEB6ABCD598C43C6E94A64901DDBCF5276
-:107010008A42BC7E689C7823DA618BC3274978BD9D
-:107020004E7587883FF5AEF02CB61326BB317DBE7A
-:107030001AC9C7717D8DE025BE6EDC73C369E26B32
-:107040009F07347BBAC0856F02D909C38E8026A3FF
-:107050007CD748E31C12B6F5ED1FBFF47B1C9FD212
-:1070600029838CF7FB70CDDDB46EC5974E4274C298
-:10707000FA04FD6E7608FD31D669D6D77F749D2857
-:10708000799E9FE52093FD5DFF2FF47C3FA4B6D24F
-:10709000F84D0ABE9AE6EFB286B6231F561C911928
-:1070A0006F2BDAA410909C152D8DFAF7BE2883C0A3
-:1070B0001FF0FD7B7F55CA789461F48FA6E1F381C0
-:1070C000CD562F5A4C48F725FAABCCD943408BC349
-:1070D00001047D2FE722BF16EBFCDAE87C780BD1A8
-:1070E000B3A949F8A7ECEA8C84F19FA55C6F5B8A91
-:1070F000F36B7948D714C24DE7F035D85F5E20AB0B
-:10710000329A889C05F989FEB1D5FA0EE99F86FF6F
-:1071100008DF86FD5A4AF68BEC907C3FFBBF73205C
-:10712000FC9F02C2FF35A0BD8AE07CCB3689E78D8B
-:10713000F96A3A1F595380ED1DA1C4EBCB4189F583
-:10714000D9CFBA47921D580943BC766920FE2DE974
-:10715000887F02890B5C420E2E2FD997FE5764AFB1
-:107160005DB082F595F84E7644EE19B1711ACE17DE
-:10717000E8B24248237989FBFD9BE550B038A61F51
-:10718000FD5D7B981FCBF2901F884F7B6E22FF53D3
-:10719000B444FE3B47667CAD3C52BD267ECA739923
-:1071A000FFC86FA0F9D32695243EAFF37B24FE13CE
-:1071B000FCF6319D4B3B24784C223EAF3F5CA00D4A
-:1071C000E46B43C72336D2FF8BF1D5CCC7D1E9BAE4
-:1071D0001DD1F9780E3A0FE8A8AC7678D894F03A39
-:1071E00014B5753AE1B410F5967062D66B837FD60C
-:1071F0002CD567C37197D1385C5FBE232C94D10B1B
-:10720000CA09C2CB2261779B551FFB23C3DE3A2FED
-:10721000D8ED77E12B6CB3E6553E4438BA534A6D4E
-:10722000952B07EAEDBA31F7B0FD2A5C8DF698FD93
-:107230006A629C165EE5F02E467A9E5C05DEC5C34A
-:10724000009E5AA5726B8EDF0C7DDF8CF19B5DF882
-:10725000679E5741FCAE55C9FE7855A2F3611BB03D
-:107260009EF69541682BBE3F1CF9D4A391BD2E8F8D
-:107270005E5F8DF145600954539CF1AF1922AE7BDE
-:10728000466F6765D8B85D5B6D011FBEA7B7530E2B
-:1072900049485FAFEA3B7215D99D4EABC6F1951ACE
-:1072A0007DE97B7CBF425D8BFCCCB3B48EA3F7E25F
-:1072B000F8D9219CB7AFF35DF7ED717EB9B7E3D193
-:1072C000511407FDCC0235E124F1D0F2740BC73123
-:1072D000BD23DFF1E0B2A1DE11B501E2E9C19EC636
-:1072E0006A8AA7EE746A4C97AD7D7AA480F1338FD9
-:1072F000E3E3E7960E61BCED3D0321D2BB59F2AD4D
-:10730000D78EC1FEE45715AF9D95CA77FDC2093CE3
-:1073100084E5BEE1CB8A4DC4BF00F273355F6C3D9E
-:1073200041F27AF6CF0A90DE55363EFDAE1FD77990
-:107330003817D1300960822F5C11C151333BD3A77C
-:10734000937E074E01EBEBF86E2501B720D71D2A7F
-:1073500020BBF286080F27BE61BA0F4199E2FFC930
-:107360003D89D7A75E04EFFF62D80D377808EF8F0D
-:10737000ADEA8077C92FEAFE331F17988C9F06BEAF
-:10738000F738673C922EE2769970EB55928F7F2703
-:1073900043C4F91BBE9425C2655F14BCAB915F7DED
-:1073A0008BF379DD7D9F524086ED97F2EC709278F9
-:1073B000EBD7E93696DFCF6C02F73F5BEA0A35E19F
-:1073C0007A0E2EADBDBC07DF77FE9FFC97AB5F1733
-:1073D00007A369B14C6279A511DFEF9CD722B11EDA
-:1073E000426B1EF1CD3CDED013436F0C7DC95B3A7E
-:1073F000C41F4AF29EE1B43EA46FC6D291928D7032
-:10740000BB5F029263EF6AA4EB6BE2C720AC2E2055
-:107410007A021D9FD8C85F3B3A255F28C9F8C3E9A7
-:107420006EE65FEFEA60D354E4D73D8BF059D20BA0
-:107430005B6B71B2F983B0A1008343684BD704EE54
-:107440001D701BE92528AD79E4B77B3BAABE4576C4
-:10745000FD31D4438A1B7E66F532DDC17A80EDC4EE
-:10746000160A3CB15F783D6C591B974776A74F3F92
-:10747000958EF39D4A5779DE4CBF5722BABD7FFBEC
-:10748000CC4DF3F77D6E67F9E5930EC7C56D9FA6EA
-:107490000BFEACC9F0BDC678A9C96263EAF5BBBDF5
-:1074A0008B2B00AEEC407EC7E13226B720AF3BC34A
-:1074B0001F647A32BA3171E2FCCBA751BC1CD08D6B
-:1074C0003344245026C4EC73A5A3305220F28770B5
-:1074D0000EF237A3E6C76CAF53D00E53280EDD89EA
-:1074E00079115B647C9E749FEC42B32AE2AC967483
-:1074F00061E75A1E5142CDF8DECD4A4FCA306C8B3F
-:107500007DDA0C45237B5FC6F3E6DE05ACDF16476C
-:1075100048223BE42CFD45FA85B86B2AC0EEBFC972
-:10752000CC7FB39C46EB7AB126C3FF05F1756C574F
-:10753000F420856FDE14C824B9CE925DBCEEC96715
-:1075400085FD31DB1B39F2AB9F91BDE9D3F3A72455
-:10755000F6E676F2AF86BD01B9EC10E167EA8B7A08
-:107560009AA9DB19CC3E980F138FFA9B5D49ECCB9F
-:1075700024A84E43165FD4BE98E588C1FE857E21BF
-:1075800032A3A20BF528EE79B33D2AC8D0FDAF6E29
-:107590008FCEC1B49CABB5185ECA577A0FD9E3F051
-:1075A00061D8A1185E428C33F37B24705CE8ABA5F4
-:1075B000643F8ECA696477A6A3DC71FE2E5D4FD24C
-:1075C0003F0D7D8BE4BFA1F39A14C2F5535D550EB8
-:1075D000529B15B9B2F6678C9F9503F383A0C385C0
-:1075E000EC9DF15E2B3834D748E28785F920ABD883
-:1075F0008F7B7F7FAB349BEC220A2D6DFE98C1ED13
-:10760000C18A5C1BBFE7A9AE9234C2910B30BF4563
-:10761000F955764A1C2798716DC67133BEC0C27980
-:107620006335C713B214D6F71D12F3D2E2E064F645
-:107630005377611E4E716B7F17FA2D6C9F423F4F3F
-:10764000714AB36B16AFDB58AF41DF5DA93372A04F
-:107650006CE0FA8D36F0B90CA1CCB8BE12B5118E23
-:10766000039FDB12AE1BFC1C8C0F063FA7103FA52F
-:10767000FF3E3FA76608B99AF9FA3F5D7FE18A4964
-:10768000906C5FE0FF97F54F05FFEF7B44BEF55A26
-:10769000AE27664F0A57CC9697211F26503CEE8D99
-:1076A000D90707FE237C8DED68657B3309ED0DC599
-:1076B00099057561B62F137345BE64B61B5776C224
-:1076C0004D641F2747302EBD04FBF129FD471EEFF7
-:1076D000E3FC3203E91EF7FC82E5BBF0D2580D3221
-:1076E000E7E27BC6762B5EF27BD09D99745FC0EC9F
-:1076F000378CB8D48847CDE38C78D4F0270D3A1F67
-:10770000FE3DC3FF64065D57D520E91BEA55F831FD
-:107710002FC35EA378A13BBD7A37DF1F190E721EFF
-:1077200050022AEDEBA0BE721C56E97045E4B1038D
-:10773000F5D369D2C330F285F609822E4B689834AE
-:10774000900E0CB78314F7E103FCFEA5BABF28C462
-:10775000312CB406E0F8BF702CF8C9EF1696638B95
-:10776000EB3CA6C7232F995AA4FB79E2AB5581A025
-:10777000BDFC1FA797482C2827FEF8FE40EB77CCCE
-:10778000F631FD052A78298E2F50C29217DF9F51BE
-:10779000A7491736910C3F8DF315CCD5D85F160C41
-:1077A000C53E8DA77827895C7A32ACBCCE7A47CFAC
-:1077B000611BF22130B771B6DB128BD3ED56BFAF30
-:1077C00080F68F3A44BC0EB4DF379EED9244EB5105
-:1077D0006608FE0454915FB94065BB59A9CBB1D28C
-:1077E0003197F777C827DA270F5CB7A4F97870FECE
-:1077F0007CD082936376D5C87F701AA0F798ED6A23
-:10780000DFBED72F0BA23EBEF5BF3F4905BCFF2709
-:10781000259A4AFC387DFF89541FF2E3ADFB45FEF3
-:10782000F27D537CA4640AB92ECEACFE82F87ADBDA
-:10783000AABF4D88B72FB0329BF5E28E904CC9F0AD
-:1078400005FD59BEC3C97BCF46BF3E9C99D037F4D6
-:10785000A0DE0E8DC9E2EA6999222FBA63D7161B02
-:10786000E5D18B33FDA999D83FADC77FA7DB53790D
-:107870003FC0A067D1AE7136E2F79F3AED106103C9
-:10788000D96D1572F65D2F4DA0CD7BF167A6F3F093
-:10789000FE021BED9F2F91202AF6B5E0F0CFB1FF3D
-:1078A0005EAE0C6BBD03D7B1E42DD56641F92C99C2
-:1078B0000ED120EAD5A2BBA435F7E2F8457E1745E4
-:1078C0007003D6B9309898E72FD3E395DB1FB29AAF
-:1078D000F2A4C6C3B45FB618E7A17C76496BE2FD9B
-:1078E000FEAE3B0FFF9CFC40878DFDC0B28BE44F8A
-:1078F000E332F57865024CFCAA94E295B21F9569D3
-:1079000083DB25235E39BD0A083CF097550E6ECF08
-:10791000AC52B9FD42B7D7CB3B0E1C665C2BDD13D6
-:10792000C8CF3ED5F5AEF3162DE637BEB9E5934385
-:107930003FC77E05ADB398EC65C44A78BC4AF71BD7
-:10794000CBF438A4E273B3DF38F087DF539E8DEBBE
-:10795000DFCE19D7A5C523B782F2693C1F0C3F6261
-:10796000E6477F57A99370323F33713FF67FCA973E
-:10797000C19EAB9711D749EC87A14F5F64087C2F5C
-:10798000DE366F4D3EBEBF79DF07453DC22EBD06D8
-:107990009E185ED1D033DE960144D7223EFD9DFF76
-:1079A0007498F87498F03689FA97F1FDDC2AC42FA0
-:1079B000EAEDB2CE0FDF84B1AC5FB9965C6A23B951
-:1079C000945F9A7168C69F196FBDD69E22B20F66EA
-:1079D0009CF54A89E76446BB34539C5F2CD67CB344
-:1079E00028DF45B7B646E5F508FB775A693DFC4305
-:1079F000D2DB6D12E787F5CFB43D4DF6A8F6B73F61
-:107A000071933DFA5069F5D0FBEAB63FE0F6915D1F
-:107A100052826E7AFEC390B04BE6F775EA7C34CEA4
-:107A2000052EF8A587A26BEE437E9C477D26FD6D53
-:107A300068FFEB9AFB28CFF039A294779E567A66BE
-:107A4000111D772C7435367929BF4D5C77EDE33FF6
-:107A5000F168BC7F1C2CD0F9C7F96AC336AB3782FA
-:107A6000F336BC227BE9350188F2FACCCF07C2EFAE
-:107A7000DAC87EAB1688164E1D781FC56823BD096F
-:107A8000B4AFFB5876532BE415203EC79D33D4E8A2
-:107A900076D88CE35D99FABE888E5FE40FEFA70677
-:107AA000912EDA3F8290B0C7CDBFD938F66DA4EFE2
-:107AB000CCB617DD5259FCB9C26A96477FF8F65F1B
-:107AC000392C83E3B757C77B2C6E09F1735A87248F
-:107AD0000E833A455B678DB8296FABDB62F506F123
-:107AE000725D9B0C0EF25F27ED1C37D4B57DC2F89A
-:107AF000AC937C51691C2FC32DC5C511CBDBDE9B1C
-:107B000045F676799E0C7351A56AF79C13E37D10B8
-:107B10004DC1F1CB77BF3DEB87D447BC3B92C8AB9F
-:107B20002A7CC026F4C624AFF0DBB3281E6EFECD3F
-:107B3000672C8F0FF74B90533CF0F99A2DEFD9C873
-:107B40009F9C41C164A60B7E91DF0884E585B6B495
-:107B500064F28B5CFFBB4ABECFFB7F1793E37A3A9C
-:107B60006B1BCF787FF2774847CD9B76EF5C7AEF3F
-:107B70009377BA0171F081D22870FF8B073CE487BC
-:107B80006BAC418FCAADB85EF3CBBB198FCB8EDF28
-:107B9000ED11F98D2F4FEC1705F3689D4B367F9B48
-:107BA000D7B914FC8CC79A5FC8D5B44F734E81D92E
-:107BB000BB93E84D659688B7ECF083B1F789F30085
-:107BC000A0FCFC037DDF34F8B2CC719B1D6E4C9B96
-:107BD00017B7FF64CF12F62A08A13FD2B96A00DDB9
-:107BE0002B9F831C3F378BE6B9AB5869A473225C8B
-:107BF0007F50E797F415EF0B80A6C4C55955C7AF62
-:107C0000CEA17D313BF4DBFE5725C7D51AC53D71AA
-:107C1000CF31DF3ED86A1F225D89AD27F9BEE9ED7D
-:107C20005986FEC3CB1087A7C08E0F184F80FE3B2E
-:107C30002D57F41F237D5CE46A4C43BE7DFACABB1A
-:107C4000363AD70AE27A8611BDDDEF711FBCD91A28
-:107C50008D37E60F74D863E781A4D7DBDE33E9758F
-:107C6000E27DF4DFCCCF00A46994B77D608BCE2297
-:107C70007F1EC4F7527DC1D20DF684F3C6185E4C48
-:107C8000E78BBA7E1AFB9CCB4CF198D19AEDC2954A
-:107C9000598976013667273D5F34E72175D6D0AF25
-:107CA000893F7527ED9CBFD4B509FDC3803A3A0CD6
-:107CB000F5E1A35D875EBB05D7F151D89A3597DF13
-:107CC00096686F6B9E42FDC5F132F23B85EDED6724
-:107CD0001C4F19FEE823175E1C93446FF17A52BDC6
-:107CE0007501DBB3FF577676D92076F6BB5903E2F0
-:107CF00084347C0DFCE589E597537C61E6AF615FD8
-:107D0000CD76F3934C2DA9DD04DDCF1B7CACDD7962
-:107D100096717B3E4F9C37356CFB2BFB31646BD4EB
-:107D20008EB86D087DCCFD07C88F71FFC07C696C73
-:107D3000B27527F2D37CFF32922DE723D1EF139F48
-:107D4000658BDB2BF6E7543ECF6F26BF49765A533F
-:107D500081E40833204C7187D4F9FC5FE97DE6BCEF
-:107D60002238034636F2B92EAC8BAFCF092B7A3DC1
-:107D70004530797D4EB32D769E4BF7073BCF7D5F27
-:107D8000B7575E97CAE508D62C4D4E5657E2ADB2AE
-:107D900024CD237E9225CE774AB3C5BA8F65097963
-:107DA000B4C8D5FA46A3C897680F95ED5FBA9BCFC4
-:107DB00083AD7A7D06CE9CCBE7074ECB27C812D881
-:107DC000BDA17A8E42FBC315963B4BB1DFB5E1F600
-:107DD000390AE2C73BD5B2A704FB2F6C582CFA57DF
-:107DE0005A2AAC08FDC7834BE6CCA47D03CBDB3F0E
-:107DF000A5F529AB15A0FA91D296F7B87F97559CB7
-:107E00005F353CBBB786DEDF20A12090FF2DEE70F2
-:107E100023D731E482BA9A368FB53D7EBABF260F9A
-:107E2000F379944724CDFFDB2CF22B8E885B2BA1BA
-:107E3000BCD2B7F17B785F79D94A3921AE53EC8354
-:107E40008FDE333597ECEEFF85F7FF5B56F6E0EFFC
-:107E50003FF3D4B50B68FC68195419E72B57B42AC3
-:107E6000EADB31BFA6BCCD9043B922F85EE6B27121
-:107E70003ED792EECB253C1D239C665F7ADBACD7C8
-:107E80000FC94E810339CDD2B81BDB5774F9BFAA95
-:107E9000F383FE685FA06F5FCE56AE5B816811C949
-:107EA0005796B7B6113FA24D0A6CA5FDD77D8FB787
-:107EB000113E5FB73978FFE8E6B4F5D62B90E4724F
-:107EC00047D19D04FE37A55D7753BB2FDBDF93259C
-:107ED000E68DD0BCB77C5F16F3BA1A53C97F820F08
-:107EE000F54AECD370FC0E7ED42BA2F920EAD538EB
-:107EF000320589754E663AE4B45D4CC7CD7641C70C
-:107F0000825049730FD231CE1EBA8CF22B7C7F94F3
-:107F1000E4700B865B84E760217491DC5EBFEDCA80
-:107F20002D627D85ACAFACFF7CFE7EE6499A2F804A
-:107F3000F3D3396A40EAE1FE1EC5A1065561DF1799
-:107F4000C6EDBB3D0BAD27CAC4FE7E33E51D53F520
-:107F5000BCD8D87F33EA0D2676F9AB5C64B0E54E29
-:107F600099ECCA398CD7C88E99F7DD269BECEFD4F3
-:107F70008E8FD82E5FEC3CD099ADDBE37CC8A77523
-:107F800084E93C90025EDD4F7AE93C3089FEC79D72
-:107F90000766660B397DED79E09DBABDD1A84E0E1E
-:107FA000D7D18F1393DCFA8F2E82F24AAE476884C2
-:107FB000F4C1FD6ABBC9FE1B381FF38A7A3BD9B3F3
-:107FC00031AFC06DB4DEABF5F393FED3C0F580E303
-:107FD0007A1C5C1F68EDB28642525C3DCA490BD7E1
-:107FE000A3F48337C4F52B41BB1A647B3996EB4F5E
-:107FF0005A4EEAE7BD7A3D438560D93F5C0F61AEDA
-:108000007F98E29E242FACE4F31990260DAC7F9864
-:1080100022DF2A935D81A3429E17EA20E43299D69B
-:10802000752E024029DA8457E2E48DFF9B9815945F
-:10803000B9FCE954E2F529265C98E57F6DB61EDFB0
-:10804000E8F21FB48EE443B1AF360EC6721D89D577
-:108050005C47F286850B366375241521D2B7094D2E
-:1080600062DFF862753CE63A1D731D4E9E3F914FEC
-:1080700005355724DCBFACB13CA17FF9CA2909E31F
-:108080008BD1A1C6F74B1F9A93307E58EB8D09FD1B
-:10809000119B6E49183F2AB428E1FEE81DB549EB53
-:1080A0005E0C9C8C09AF48B8BFD1F9E4BB84AF9695
-:1080B0003C59A578FECA8EFB4C7531D31817538CEA
-:1080C0007D785DFE465D1D9581119FC7A3FC1F2B2A
-:1080D000A6B8E9FE2A491B88036F24C87EFC1FC589
-:1080E000C17A931D30F4FF62FB373FD6FD849C526A
-:1080F00024519CE3C3B82A652AD5118B737B784B36
-:10810000D4AB7C96F2778E8B34C9ED856FD25B55FC
-:1081100089E2A07BAB348E83EE1D527480F60F7A19
-:108120007EE0F64AF903EB42CD75A0190EDF64E05C
-:10813000AD115107D982869EEC7F708683E38C87D0
-:108140002D96DBAAE3E87F225BD89F27B245BEF5D8
-:10815000735B7837D901C5016A539E789E8A1F8068
-:108160002A7B502EEE4C10F561F0C6DA9985E43F7B
-:108170007B466AE9543F8BFD6FE06525C4FEE496BB
-:108180006685F3BCD5CE27D99F942BC29F8C93854F
-:10819000DF403FD241F6F14DE97EAB88B382569283
-:1081A0004F810382EE72F6AF7C4E9C0E59D28A321A
-:1081B000AA4FBDE0B7B4AF104C876AA75A884FFDED
-:1081C0008B653E0F7E8948427AFB6B46719D73FF3B
-:1081D00085FA3F2D8DF2EBFEC58F9EBDBB32A69773
-:1081E000276DC9F3BC8BEDBBD56C793495CE514E60
-:1081F0008E8484FA8C37B3457EF866B62CEA0C423E
-:10820000EF79884D7D4BBE184E4407A4EE352E1CE9
-:10821000F2E0A61F54935C6CEDF382B4AF69ECE31B
-:108220005FC8033BA773FDB6912FDDFCBAD8D7BB5F
-:10823000F98BC47DEB8FB2C5B9C047F43E6CCBBBA4
-:10824000FCE3496E379042F0BEB27F3CC507D52AA9
-:1082500068E4F717F817DE7D14FBF3D64B1CEFD359
-:108260007D1A7F23CA90EE9F00EFAB7B91BECFB308
-:10827000053DF3A1DA4A74BEF6FDFA54C2D3EBE928
-:10828000627C54026D6BDC7C37E8F3BDFEFDE57B60
-:10829000294FA7F7D1FB891E7AFF3C154AA8FF1A80
-:1082A000F8CFBE5A3CF0BD3781CFAAD77B59C94F12
-:1082B0009642A8ED69B2AB472CDEB5C06D2493FDA4
-:1082C000929DFD525F53F4C97B90CE3FD5FE75AFB2
-:1082D000847CFDE3C2E8AF9FC6EBDFDD248386B874
-:1082E000F838C32F7BE2EAB44F2EFE2495F889F1CB
-:1082F000CAF69F92DEEDB47BA9AEE3CDDA9DC3E36F
-:10830000E3FA54CF74073D07932EED3CADEA89C9DB
-:108310008CBF15DB05FE56FC66440EE16C45EA0594
-:10832000DC89FEF6523E279D2041D2FC783FE24D8B
-:108330001BC17535A021CEF67F2EEACAF71CCDA849
-:1083400020FA14F05F16BF9E3D2FDD329AEB79DFE5
-:10835000C8BA243A496783687F6F665389F181AE52
-:10836000270B3A332BF478729487E2B9DFFFE6ECFF
-:108370007F105FF6EDDCFE43D6914BE3C3C03A5A63
-:108380007527DB27230FA3BA57CAD30E59D84F5EE0
-:108390002DDFCF7918D56970DE35A488C7A3C15108
-:1083A000ADC2BE89EF24300E6EF672BD27EBEB4AEC
-:1083B00055C42D469E245BBCB98AF8C8E0C5A93CCB
-:1083C0007F09D0FE989B122BC35E611CE1962DBAEB
-:1083D000BD029F03F3D3D1BA3D9BE5F15EDB22CE14
-:1083E0006B12E24FEC57ED4A127756E33F8E3B3764
-:1083F000FB9B53D82F6D96CB28EEF03922E4C7CDE6
-:1084000071E75458CFFB0003E2CFE7FE7249F1E772
-:10841000F73CFF3DBFB3D4A3B1FD098F14762E1CEA
-:1084200019C2790EFE55907E0DA5BD003A07CD13F9
-:10843000AD4DEA1DE940FDACF594AF7B681AC2650D
-:10844000A8E00FF551A450AA7D72E82B8A03BB1552
-:10845000965FFF73577CED772495A887E4EC23871C
-:10846000A770BD735F97D08FB60CEDDFA7529E81CA
-:1084700071E656243145E9B1A52759CFD3647F5120
-:108480001FC21E9147393AC4B9A843F301D99714C2
-:10849000551D4789B9317EB147D8DDFAC36F16D96A
-:1084A000503E672D47DD74BE52B7F729372E179A15
-:1084B00033FD0F90FE2C3FF9F20495EBDCB614511E
-:1084C000FE1D8EBC3C83E3B3D9C8DA7183AF27B0FD
-:1084D000A9823E4280864D99DC8EA27D15BC14880F
-:1084E0008875F676346724DB1F08FCDB5B0769BD03
-:1084F0003B8FA570DCB233BB9BF520380F603BF29D
-:10850000FB89CF47F37C0830A6E38A6A4D227FFFC0
-:108510000B7D3D3BF5FCB2F77399C719F38EE998D3
-:108520002EAB88ABB248EB41AEE3EAB46B24DF94E8
-:108530006D20F8D399C2756181FDD788BC335D9CED
-:1085400047B70D89FE91DE13DD67D7A84E35456D1F
-:10855000850C9CBFCD26FCEC2804FE53AED875E3F9
-:108560007D299D1BF92308C405D7E3A528ADF00D8F
-:10857000573CFF5399DEFD1E11EFB40D89585CE4A2
-:10858000273057DACA74C5E8047EAF41E7288E8BDE
-:10859000DB6CD1F769BF1DE9520917A340D0099DD3
-:1085A00023348A57525471AE9EA26ADEA03490AE34
-:1085B000C058086170000FAF860B7ACE7584436295
-:1085C0007D07EA425B891EC70417AF9B392DAE4F6A
-:1085D000866C52ECF9139E65EB5A0A695DC20F2A4C
-:1085E0004A98CFC7DD0B40A5F3EF14C5C77952CA2F
-:1085F0007CD09A505E4E878FEF7B708EA6C9DC8F41
-:1086000010FD2ADDA77D9B34D53907E94EFB328D5D
-:108610009F6BE8B672DD79DDDF6F4A2BC3F59DB144
-:108620001CBC6717B61F2D0C0FA773DA0969FEB7BC
-:10863000C81E3F736AD1BA3138FE2F6D56EF5CB257
-:108640004B3DC11FD3B97DED13568DFCE2836FF412
-:1086500047BE22F93E2BB15DECB38AFBD8D79AF026
-:108660007E43E707363AD7BAA6E36D1BED7FAFCC62
-:10867000F1BF4F7A30A9A3A98AF836195A9B699F8E
-:1086800013ED21D74B847385BDE87F65F8D6A638F6
-:108690003EBB72F47DEFA8FF72D29B4E5D3FF75355
-:1086A0007C84ED5E3D4EDB7BE0BBA55ADCF96910B6
-:1086B0000EF27EE06A788EEB3A8DEB7D216536E135
-:1086C00068F46B8EDB7C7138B3E5087DB7E9EFFBAE
-:1086D000798EFF4BD6DB03EFD8DCB8FEC09FC345D5
-:1086E000E4AFC218CF7D5D1D69C0A42F17EA8E4E7E
-:1086F00003DB919DAF7570FCBDF33E359DF41EE923
-:108700008734ECEFC5F882F4686FB1D0BBA657CFC1
-:108710008FA5FDE2F3FB965F4EFCEAF5580D7CCF8A
-:1087200018427AB41BD88E197A58467A28D1F77B2A
-:1087300062BFA78CF04D7A67EB9EC37AB7D702A4CD
-:1087400077886FC63BE25BA538A44C45BCF3F323A6
-:10875000588FDBBA5FBE82EBD991BDC3C651DFC271
-:10876000F86A8BCC0949F87CA53572909EAFC4F7A6
-:10877000376931BDAC9412EB7A167B449DAC611F16
-:108780007FA0EB6778A496E6C5F14E594EC07F9C5A
-:108790009F147DDD8FDEBBF127EB36A0BE94FA2A55
-:1087A0002C1328DE3926B31FD8AFC7C92BFE30E5FE
-:1087B000865DE23AFBCF888E8B837ADCFCDCAA5C98
-:1087C000EE935FD0502EE3B1F55550BD7763156D34
-:1087D000C54D9ADD7A88DA29D5E12A3A2E9CB6A0D1
-:1087E000FB90F8C6CD379AF0D67EF05BA3B94EFA6F
-:1087F000A41DE83BCEF6FF8CFEF1095CFF3DFB912A
-:10880000DF90342E61BCA1C766FC0D86933EA9E7BC
-:10881000FAA96897AFDBF8EB6B1574E80D04045CFC
-:10882000FF9C8DDBD605D1079EC8F15D9783F8FBD1
-:1088300022D77F5D0EF2ADEFF87F7AC89FEC7DE521
-:108840001D37F9E1769B6F34E1AABD04F3882478E3
-:108850009C926365FF5A3948BD49638EC8B7860745
-:10886000611DE1A5A15D5643E4A77DDDD793DF78C7
-:108870001F5949FBDA4BA707DD942FD5EC3DC47592
-:10888000FA463EBD04F43FF9D659C4FF73B9223FFE
-:108890005EBAC19A90DF8E80888DCE91037E576339
-:1088A000044552638A3BEEE8D8C2DF8DD46E4B7C20
-:1088B000AE8EE2148450DD45F2E3C61C7D9FA41405
-:1088C0004A294E41DCF03E49F455D9BB15B8BEAA41
-:1088D0008BEAAB765A049F9C0E6849CB88C52B2344
-:1088E000F27C4BC8DE2D31FC875EAF146D93F87BB4
-:1088F0008A513B44BE3CE5B4B685BF930AFAB84EF4
-:10890000AF860840BAA728415EFF94DC5208E2FA1D
-:1089100027A179267D59DA2985989FFA772F0AFEB3
-:1089200013FB459B65FECE6FB30499C5346F94F974
-:1089300053ABEF1F2EDF91787E51B7E9F8610A95AE
-:10894000EAC3A6F3209D3FE6F39DA7E83F929CEF84
-:10895000FC24478FE78AA028E1BBBCAE4BFB2EEF7F
-:10896000238A075C74F8080971F91E1D470DFABACD
-:10897000EB42B258378A82EAA36FD76112002FF315
-:10898000A91E71423880F542DE463D632D54DBA8B6
-:108990008EACBEBDE9309DBF2DD5E35A339E90A16C
-:1089A000CCAF657ADD50CDE6C4FBB53A5F6A4D7C4D
-:1089B00069F04B26FA44DC7DA9F4A1E5FA0EE1A0AA
-:1089C000769795EBB9CFC1AD5C7F55DFBE85E95990
-:1089D000AACB6F20BD415ECF325C0FE9D3A5D26B2D
-:1089E00096DF3103E757C01509F29B9D7949F22BB9
-:1089F000057539ADAFBF4BE4B5FD5D25BC2F61E01A
-:108A0000C5FCFC2C3D8EBE66938837CF7654392941
-:108A10001EE83BAA7825C47DC5B14FDDF4FD4DF9B4
-:108A20003E19E89CB4AFB3625D10EDE59EAEA13790
-:108A300069E807CA8F29EC372A8E9587528AA95F81
-:108A4000EE2CE53A132D93F2009C87FD70DFD1A147
-:108A500027CA384E9F5949296AD3D17227C50B7B43
-:108A600040EC6F48C72A337BE2FCCA7B3962BF61A6
-:108A70004DEEBB0F939DBA66B795F783AFB1465FD6
-:108A8000A23C6C4F97E26DC27EDDB145AB5348DE30
-:108A9000BF91BC14761FEE5E9145E735F59D56D526
-:108AA000CEF4DE7D90EE077749DE61383EB0EFEA26
-:108AB000D16DB44FB4A5C24BEC35DE579EAE3D4AE6
-:108AC000F5AE90E7E4BCFD9ACBACEC5FCFE43BFFA6
-:108AD000752EAEABD6B76516D9E133BFDBC37515BE
-:108AE0007D6D12E44AB48F7CE849AAF739F3F4713A
-:108AF0001B9D0757B51FE7BA8DC1FCC1D910E28E87
-:108B0000F3F6561BE537F55B8C7E0F7F8F52ADC7B2
-:108B1000510DDBDEE67E2DE50184C7CD7248C3FF33
-:108B20003CB4EF193E1F6ED825EA3E2EDCDF26F15D
-:108B30007D03EF8B74BBB51C34C6FB7203EF7A7DEB
-:108B40009481F7733097EBB496EF7A84F1BD44C704
-:108B5000B7B96E0A2DB0AD2C4BE82BEDB799BFFF1E
-:108B6000BB43C7F71D17C1F7A85C1DDFA36014E165
-:108B7000FBFC74514F77FEF81027CD7FFE08EFBE47
-:108B80007E1DCED9EF1ED5E382FE88C567BB323687
-:108B9000AEB7E313FE0E3170B4DF467527B33A3F2C
-:108BA0006679CCED3C3093F87D1DF8EB887FD77566
-:108BB0003A558A83E7F6087B36A7D3CEE713D74129
-:108BC000B885E4DCB7FFF1960CC2CDAF056E0C3B67
-:108BD000B74CE7EBB5653F9845F97BADEE0FFBBBB6
-:108BE000EE9CC576671C1453BC3747FFCE7B4E58AE
-:108BF000B7439B13F94EE7D424B7864E3BD79B5C13
-:108C00000B3D36F267D7EAFED3EC27FBF29C2CE74C
-:108C100020FAAB6138BE6E97A98E52E9617AFA3BB1
-:108C20006C7CDED560F2BFD372AD09F51783E1D35A
-:108C30002CAFDB72757FA2CB6B6E54D431CC7945EF
-:108C4000F6D2F94357647519C50B06DFCCF2EAD2A8
-:108C50004AD3BEEEF7125ED2E37CA37F83FEFD5BB8
-:108C6000586D75C5E7EDCFE75AF473CED04F2B7032
-:108C70009D7749D04D38C4FCE6867229697EB332AF
-:108C800017C73F5F78FBFA71F1F98D6FCB708AF7E8
-:108C90001E44BB5251C9F53BDD7C5EA8B4CEA57322
-:108CA000B0C02EAB97F29A4087CCF14060973D64FC
-:108CB000C179AF211C215DD59DD2D58423CC1B5A0F
-:108CC00072D13ECDA32D651C37AF03E3117C6EDE60
-:108CD000CC8F197F47868A75F72B5A4EB23CC2C893
-:108CE0001F1A3E17F1AA71BD01ED008D6FD0BF4B69
-:108CF0006B3FF8D7A2E2543AB7FDAC6821C5A9B9D9
-:108D0000227F31E2D528C6AB257ABC4275174B8548
-:108D1000E860E973F7D9C87E1DA61FB6A0FA49D549
-:108D2000BF86F261D50F8D3FA240436A613D6A2044
-:108D30009D221CEE95C4FECDB356AA0D81A6978741
-:108D4000705D60EF6BE21CCAACEFBD8BBAD95E9C64
-:108D50005FE86A24BC2D2FDBB206230C18BDFF751B
-:108D6000B637A37F67532D6A6C5D4DF4DD1DE7694F
-:108D70002D09F1726F47B38DF7A1E3BF1B2E1918B0
-:108D80001FD55F641FEB79935D41FA39DEED3B221D
-:108D9000ABB42F847CFC657E3CBFF478A8FD600AF0
-:108DA000FBAFBEE3AE10C5FD7FD1F17846DF976F14
-:108DB0009A24333F2C93453B7AFF3325245F9287D7
-:108DC0001FEDFDCEFDCF5CE1E37DF490A823DE91A5
-:108DD00058875D1F4EACB336F81AD0F98A740DA7C8
-:108DE000EF950DBAF62A3D6E6F123D92A4832C2F9B
-:108DF0008B9498E7069E95ABE3EB48713DB791DD08
-:108E00003B69E88B12F5901F7E2B5763DC34750AA3
-:108E1000F95AF68916DFFF1DB15F63E5F70FB83F1A
-:108E2000235847F7CF173BB9BE013E0FCEA5FE3DF5
-:108E300025E2F703EE79B97644FC3E1D48221F0F68
-:108E400058A35CEF17386E61FA02C7FB3D435D64BF
-:108E500017B7CCA43ADA6B757B71B8C45943380F95
-:108E6000D27B7362F32CC915E71B40EBCD8D7D5F80
-:108E700069AC7735DCC87C58ADE3EA3FF4BC1EF33F
-:108E8000A8F3B949F2A8C1E2DF0B74EBF1D3F9E919
-:108E9000DA89EF210ECA8F2841CAD7F7BC91122276
-:108EA000FFDFB46FD99F281F0EBC69078A43EED934
-:108EB000BF6C04D7E1FBFD57923D39BFFF8E2BB944
-:108EC0008E5112DF970689BE5C8AA75EF5509C54CE
-:108ED000BFEF55AE73ACDF3BFE518A9F305EBA9652
-:108EE000AE631CC3F82B3F56C9F8DB73B432B3949E
-:108EF0000807AF93E6AD3FA270DD63FD91CA17E7A7
-:108F0000525C736C06C74F46BC5441F938C54F4795
-:108F10008626C44FA979827F7D075278FF4382124B
-:108F2000811F189A809FBAF63F709C5187F62E1EBB
-:108F300047C673C5790ACF332C4FC74F58F2313E1D
-:108F4000768BB6AE630FAF6FB935CCF26EDA6515BE
-:108F5000F7DB446BD44907212348FC78912EA11CF0
-:108F6000E6D84285946FBE502CF20DB33C9EC813D8
-:108F7000E7852F9C14DF19BF30DD3F22D9F7C641AA
-:108F80009821F27049E777BB7576B2EF7977E4897B
-:108F9000FD097726249C4B1AEDA379425FE6D8C4DD
-:108FA0003E95F9BE3FCFF03FB08ECE634ECCB5AA12
-:108FB000C6EFB7E4A1DDBD1E8C3FEFABF3B3E89C79
-:108FC0004BE4D5003D33C91E7E9BF6F929FE9A2459
-:108FD000FCBAB1CF3F6F333C20F6F96FB5925D30EC
-:108FE000EA4BE6F9CCF157F5D534CF8DE8DF699E31
-:108FF0009B6627DEFFF645E2AE0579BA1F1F0EC35A
-:10900000455EE172923F38D76555655E476868B244
-:10901000EF0B0DFB737895383FEA42BB486DD3A840
-:10902000D779DFEA8503279F4C67BB9A0225C8E200
-:10903000ABBEFC9327D93C4D17F4757E02FE0C792C
-:109040009DA53CA06CA0BCEECCB3E8DF259DB1F1A2
-:10905000F926343E649107FF2EA969D4672DA44FE9
-:1090600067F5EF5E90BE227B9CDD3F9BF731DFBF53
-:109070006706448378FFC0283BFBBFFA99129F1F05
-:10908000D447843FAC9F2FFCE1F0F6792C97EFA0FA
-:109090005C7C5E3613AF515DAE21EFABBEEC9B69DD
-:1090A000E493748ED34438673B9DC56D7DFBDB2D07
-:1090B0007C5E897E97E2C21B2625CA6D04F81FC814
-:1090C000C6FB37CF96BCE84106C8FDE65BE7B1DCDE
-:1090D0006FD2BF8FB998DC7F9BE7FF691EE97D7770
-:1090E000FF77C6208B5E18F54111F9D7864170BD18
-:1090F00055E72F0C8D3E4DE765DE0BE7E97F7F3AA4
-:10910000FE3CBDC4E3DF924776D5F2A5FB0AA0F989
-:109110007A7EB942223901EBC5607AB5439F7F4719
-:109120009E2ADE9325CE8746E9FD17ACA142FE9E1E
-:10913000A2ECD2CE019B9E7D7E2CD9B9DE0347C620
-:10914000DAE2E47A6605DA07F237FB0EF1F78731E7
-:10915000DC5974DC29DC4AD28DBA1F4DC4E119C236
-:1091600021D9E7DD87AEA7FCF16CFB4D599216E7DC
-:1091700067F79E700F8B9BF7ACFEBB1898B70DFF7F
-:10918000766A3C9D0F309D67C3623ED4FFE1378D08
-:1091900089BFDF6C7C67C7787E7064239FD31B78A0
-:1091A0005640E0D9F83D8C0BDF55DA80BF7B0CEEE2
-:1091B000B7737D459F355A941EA72F1F1A72449886
-:1091C0001566312BB9DE75226CA8E273024CDED72E
-:1091D0004DA6CFEFC2B2A80F6DE4BAC5698DE025E8
-:1091E000DC4AB099FB13668BF3F229D02D135DDFB7
-:1091F0008428B73E50156A67508519B6931C61994B
-:10920000C2ADB6F6834EC257C4A3A4BFEF10A5A744
-:10921000C9E4175BBF02EF1B78C5C1180425FD4EDA
-:109220003F2B5FD87FAF53E863F4ACF8DD936F401A
-:109230000FD33F55E9667A53352D83CE4B763FB732
-:1092400042A6FA97FDA04549CFBC998DBCFF169D5B
-:109250000EE1ADE9B1F54EA2F5AAB1FE940560A10B
-:10926000F54AB04BACBF1132E87C6C3244F83D5744
-:1092700011C1B8DEE9A029D4B7E517EB7C16F95B7C
-:10928000959EBF591C41AEFB49CD17B8762A2139AE
-:10929000AF92B7B6C38FD0F94CA958E744BCCEE71C
-:1092A000388D82EE0BFE3A5FD8BB29106639430D2C
-:1092B000A82FF28F2BCC54895F52C463A1DF13BB5C
-:1092C00054BEF67980E977DF1EEDFD6165ECDCCBFD
-:1092D000DB99C3F5D0EB254B5426BA1C85A21E3A68
-:1092E0000261FE2E3392F87B67C5F9375E9E4F7E92
-:1092F000CF2FBEC335D775EE086DE5BA9B05416427
-:109300000FCD530870DA13AB03B09684F8BE95CE38
-:10931000D955AE33ADA07C715FB6FFF2FC6CAE37B1
-:109320001DC69329A1F1D5A931BC2365FCFB3B4E99
-:10933000486D257BD4ACD7D30655B75ECF54C4EB6C
-:10934000D0D0CEF38F4828A2AEFBDE2A517F7AEF31
-:1093500090FD5CE7DB23812A15D0F9FF7EAE03A6E2
-:109360001F86B3167CCDF97F96FEBB0F25FE3726F0
-:1093700096EA461E9F6B3E95CAF5AFCA0C9F46758E
-:10938000BCE67AF1D296F10FF5705E6AD06BAA1343
-:1093900057BC7CFF5EDDBE363BC4EF0049ABEDAA97
-:1093A000348DBE7F5FC1BF63D54CA141257DF7BE23
-:1093B000829FA73A662A02ED4DF3DF44FC32FF2E6E
-:1093C00015C2ABFF059A376D38EFF72593C73443C5
-:1093D0001E9681755228875B49BE46DDAD516F4BA5
-:1093E00080A0753B7DE277F054C409FFEE1F42C9AF
-:1093F0004EB8F4997FCF43D4FFB6E8FC47BA7670F5
-:10940000DDA7437CA76D7CCF6BE69B81DFFF02B9B4
-:10941000D77EA250530000000000000000000000B2
-:109420001F8B080000000000000B9B25C3C0F0A3A9
-:109430001E8145A551F9E8F81C9A3C0B0303C34F64
-:10944000205ECC835F1F2E1CCB82607B893330185B
-:109450008B32309800F12C209E0DC43F81D8508C67
-:1094600081C108888B81EC1220F6056247A0DA2FB3
-:109470001C0C0C13851918E600F1726154735F30EF
-:109480004268252E060653206664C66E3FA73AD072
-:109490005E5D04FF23906D6F409E5F46F1D0C35523
-:1094A0004EA8FC7C6B54FE2C5B0606666704BFC0AE
-:1094B0009A34F3ED817A1D9C71CB77BAA3F21B3DF0
-:1094C00051F97FDC50F935E1101A008D579524B819
-:1094D00003000000000000001F8B080000000000D7
-:1094E000000BED7D7D9C14D595E8A9AEEAEAEACFA4
-:1094F000A9197AA04706A8611A19E3A0050C30281B
-:1095000048CDA0384693349890D1D5BC168821090F
-:10951000CFD7F1ED2A1AC9F47CCFC0800DB2067DF9
-:10952000515B0C89262621899B3559B3698DC92346
-:10953000D96C168D9B47B2B86F243C379F9B79EE50
-:1095400043FABD90B0F79C7B6BA6ABA6BF00DDE4F1
-:109550008F37FCCCCDA9BA1FE79C7BEEB9E79C7B8B
-:10956000EAB6EAF1437C1EC059FC5B03F0A6170083
-:10957000964D95E94E33076DACFC1C98FDECD1A5DA
-:109580007AAE5362E5A2D0B84732002E8F66003C17
-:1095900000F1C38F8287D51B695461671380DFD8C0
-:1095A0005003A1A97EDD657F0F406E61E9F7F20BE4
-:1095B000A33123CCFA7B6A79B7C5FA19F9727BB764
-:1095C000D53AF5BE010765F8CD07864D3DC0E09C54
-:1095D00007C113051866632F64FF69F72521C1DAF7
-:1095E000A9B951301661BD5AAAAF3D73D4731B7B24
-:1095F0003EEC85EEC3ACD49E4DE7820CEFCB9ED300
-:1096000097C88C1EBF62797EC5607FCC934D231DA9
-:10961000B17DD4EF2946170EF576D1B314E9617404
-:10962000ACAA929E55A5E8792E9D467A2E7FD658F3
-:109630005C488FD6C8E9D11AFB689E4EC5183D4DCF
-:109640001742CF3D44CFB0A067D845CFBB043D1BE8
-:109650006D7A1A86889EA1398C1EF6C8775F1A1219
-:10966000ACBE86F484B19E939E21A4A7B5083DDAD2
-:109670001F879E0F09794B213DCB2AD393427AEA6B
-:10968000ABA02794019D3DF783641D6E9D8E975F6F
-:10969000F071D13399589AF53BFA7B99E699ADC8A8
-:1096A000D8864553F5C6055EDF691A8A8DA37C2DE1
-:1096B000783006ACBFD13912D577F7FB10A8547FAC
-:1096C00066A3D58BFDBFE34967FFA37338BE76FD64
-:1096D000DF8879FC0DC8D46E5628318AF0E882AF55
-:1096E0004112C7F166623AB66BE2ED06172CEF1E27
-:1096F0000F156BCFE919DD912679D672F710BFFEF1
-:10970000624E060C06FB9F4C02F25F8D717CECF6FC
-:109710000C2F802B90ECBB2C8BE30770119BA7F4D4
-:109720005DB9341B2F9EB9434B307E8C36F46948AB
-:10973000F788B1AF1BF5D6A9B80A7213E2559C0F92
-:10974000B65CAC81316D3E9BCFFE576473274CAF46
-:109750009746E1AA9F82959007722D407F6701E9A5
-:1097600049D2FC0F2E7890E85691AE4548570A0C26
-:10977000F6FC1B427E7CCFA401E54A33D2B1F4A2B1
-:10978000E9E38C20FF5BB1D74C6C4301FD3FB5E7AB
-:1097900097CDAB6B7E892F0F81954B235FFCCE79E4
-:1097A000B3CBEF09BE5FDE9826FE561A7F3AFD7CEA
-:1097B000FCBF0683FA012D134B84A7F019F58EF731
-:1097C000A15CB335691E62552E63E37414F0DB3D72
-:1097D000DE249D4AC621C75F137C1AF54FBC50D8C2
-:1097E0009F1B9F6F897ADF029D4A9BAECB9EE5E36C
-:1097F00054EAFF47C8E27AACEF5A574ADAC1F77B1E
-:1098000045FDCB9F73D62BC59F8F4FF2271D437904
-:10981000B4D723FE59330184C8D05F6839C025F816
-:109820007F5893DFDE367E172EADE3D1E4296CBF7F
-:109830000D92F302CD6CBD78939FC5729D62BD49B8
-:10984000FD42487FFD52217732E9013E1EEB1E5852
-:10985000FF61D19F2275013079F6B543762743ED3C
-:109860001AF9784E62FCDC0760CED20BF6F5137C59
-:109870005F5FA967D7E27E7EA5C20861E3D580EE6F
-:10988000C712EBE758BDC8B290C946021FFC594D3C
-:10989000A288DCF8DB20EDAF61E3B7AB8E75E1B7F2
-:1098A00092807A211C839C3F02A04BE128E1BF02F9
-:1098B0005670FC0D09FBAB538C5E858D23C73DE6CE
-:1098C00041F6B46615ACDC54208786C4E5B737EEA4
-:1098D000F1205D434CFFFBD8928CCC61EB1DD7434C
-:1098E0008CD91B45E47652BFE765C8CD60FDE625FF
-:1098F000C82D657008562659BB8C0F569EA471C1A1
-:109900003C5844CE364A7C5EA5F8C4D9B3641740AF
-:10991000F65AB20B32B48ED578C6C27D40B322A6B9
-:109920000FA7FDCCFD5CAF2960A19CD4C633B91A4A
-:109930007C6F5CDC84F8CE8AA7E0B5565E9E28C0BA
-:10994000570BA563643F355D2CF515EC63CF33F9F8
-:109950003951206F233BB81D30D83424F4CC8749CB
-:109960007FDAEF3F20F8A48E3364902E43CDCE975C
-:10997000A6CBF588545C4F6C16F4E2DFD5CB9DF294
-:10998000AACC14F2CA86F02940F235FC1464115FA7
-:10999000C6C9176E63F0A52F6AB093C9572B1CF583
-:1099A000A0FC5C0613549AA0CB582E0193CA3648EB
-:1099B00050F9DB0E26F7ACDC6631799F4FF2FF3EA3
-:1099C000898DFF9B39C98511F6DC1F4F5F81FB0B29
-:1099D00093FF8DF89CC98984F2546741D1FDB2563A
-:1099E000E2EB75AFA2FBB1DE5E0B483FEE97FAD318
-:1099F000B84F8C083B69C40F8E75BC47D03D22CA56
-:109A0000DA7812C6717ED9BCA05E7FBEE9765AC7ED
-:109A10003E85C3436C5E48EE56F37DCC8D8786F35E
-:109A2000B2E8FCE761E31F7F1E86A4FAA2F3308C44
-:109A3000F3B051E2FA53FD391FBF0C7DB44F6FEE06
-:109A40007D9CF8AF9E3CB7FA36FDCB5D7A7385D02E
-:109A50007357C2C45C85E9913B7C39559108EF4747
-:109A600010EF377F72F403480F8C2717E23EC5F0E2
-:109A70007E54223D9982A36C7CE515398B7E8A2722
-:109A80007883962CE3A780CEF49926F4D97CFCDF6A
-:109A900046FDF5E074FD7BF1E10F1D237B03B4E48B
-:109AA0004ED44FAB531ACA457FE3060DE568B89113
-:109AB000C128373155932E676508BA50FE6CFB6399
-:109AC00028B669A4298A768FB91CBBB5C75F1B4B22
-:109AD0008244CF93337C4DCEE73FC3F5AF2763324B
-:109AE000A34FCD5EAB219D83FA06ADD0EF5243C9A3
-:109AF00098CAE47018C7C3F1BDA9234D6DA83F6192
-:109B0000691FEA733D054B51BE639D84E7DAC68445
-:109B100086EF7DB125E03390C509B2AB86A24E7FBA
-:109B20006EB8F14EB89DEAA7E0F5D074FBDA174A9B
-:109B3000815AB04FE03872C13CFB94540EE99263F5
-:109B4000C5F5EE3F09F9F71809DA6F20F3494B63C1
-:109B500072EF1532E08DC14FA4CB0AE6295AB0EF5F
-:109B6000B0791AF29BDDC5D625DB419CFD9A1268BF
-:109B7000CBABEF776ABF15F39E5931324EF31ECE51
-:109B8000E0BCF733BD4FFBEAF170F61023A1777507
-:109B9000EA317CEF4D2BD017A56E5A709FBB5B7ED0
-:109BA0008789F2B707F9C6368EB11E8DCA9D3D3A38
-:109BB00095233D312A3F19FCC467C759BBED699F06
-:109BC000EE4339C8DCFD25EC8F79DD899DD86F9493
-:109BD000F58FFD2A9A7E484798EF3BDE382F6FF1CC
-:109BE000703ED67802846F9B87DBE10658242F19DC
-:109BF000BDBC9F5ED3EEB473C366606A3DB0FF82A6
-:109C00002D750ED86F5CE4A8EF5E2F2F79B8DEF0CB
-:109C10002A09305BB12CAEC7CF4A32D593E5C513C4
-:109C2000687F28B354B20B0625A7DE7ED4C3F7BBEA
-:109C3000273C1AD11983896F9F65FCF0EA1EB27B1D
-:109C400022B5F30FE7903FF5AAB9801511EFB85E82
-:109C500057643C882ABF1E2F58E74F4956DCF3272C
-:109C6000C0A769F4F7763AE47A9787EF7767C57A01
-:109C7000917D5637EA9918134320F9301E473E78F4
-:109C800082ABCC16C687C15AD5407F68A0D7537423
-:109C9000DF71F341AEB92586FAD1CDF76F09397A74
-:109CA0005AF07DCD99F7909ED8AD7BBAB221E4DB16
-:109CB000D12ED4F3036D1E0FCAF99F0CFF5C746C98
-:109CC0009FE4DF241DC4B78128B79BC774263FB823
-:109CD0009EA35C7E0CC875D17B93D1254DA7CBCDBF
-:109CE000BFB79B3E9BEF35B59E44B615F19B481020
-:109CF0007EAB94A2F8FD47F1DDC62B3489578EE385
-:109D000065FE69E0F594943C88EB7B8F90D73DCA63
-:109D1000B8867A216ECB4D90AFA3E97A4972C83BE1
-:109D2000EBE7F3D8CFFDD80FAB7FBF32E1E8C7AE8A
-:109D300017463EF07591E0EB42F9A3AE0B1BAF9DC9
-:109D4000026F03B25CAE5B8ACBF5DB8D97BD9FF6ED
-:109D500005AF02D437B5A104D9DFB342891CF2ABF9
-:109D6000BF5E35D0FE618E12EDD7D4D428F093EAD1
-:109D700037C6B0FE607823D9E583DE04D9E947EA27
-:109D8000BF66DDC6E8EA3F53033E93F903C1AB8EDD
-:109D900018A8178FC8E4AFF59F699E952A32CF4166
-:109DA0008C8F31FC03881FD9D5EAA4118EF8F68771
-:109DB00098E263FDBCD10A59D4A7DE901543BBBB22
-:109DC0007F9166F651AD04207FFB821F684FB64E2F
-:109DD0006F1F0C0D7D4CBE6C6A1CF6279D45DB97F2
-:109DE000EDE1E8C7137D92E37D513C2AC1DE29589D
-:109DF000A7FE196C68D8B5649D6D9EE23BA3A5458E
-:109E0000C17D130226CE7F3CD1D5F73BE4D3F76466
-:109E1000D2836EFEFCB59C0CC8CBA6606F3449F3B0
-:109E200066F7775DBD427A546984AC4FC251135DC9
-:109E300068DFF6377A28BEA68436D494B5BB1BAB50
-:109E4000B3BB41C43D6C79E8F8391F376072FD1D22
-:109E50008671C0B84A0DF0B8462D1812507B534A8F
-:109E600050B06415C553A2FEB7BADF5BA85FC9DA6C
-:109E70000B6783E7D0AFC2FA6D7E1BFAAD80AF1FD0
-:109E80003E45FD32F5103D3B63AA5F6F2C450FE167
-:109E9000CCD9B3F272E04DE82F49F2AD784C5A9F1D
-:109EA0007051C43CC48AC1E89D0E7FEABDF27C4774
-:109EB000DC54D5873E264558D9B8CD1A2FD00FEEA1
-:109EC000F9EDC681D0BF6CDC628D57A137D0EC2E86
-:109ED00016971A5293D95EDCBFE786288E084A8A05
-:109EE000E2C2C352DD12B49FED7A4AA39A43BCC2C8
-:109EF0006D561AF5C5F00C8F299BD8EFD851F40791
-:109F000040BEC14C96892F298DCA2F0BE9F9CF721B
-:109F1000384A788A38577F05791FEA297F3EA1AAF7
-:109F200066B2983F9396B9FDA2068ABFBF5AEDDC90
-:109F3000212F9BCEB70CF28E3D1FAE652EF7E55C50
-:109F40007C500E94C6EF1E433E0C35AC8B95A31788
-:109F50007466E714F845A66AED94CBE3B1A7181E22
-:109F60001062C2B3B2CC38627EF5AB4D1EEF40A595
-:109F700088E771C23E637847A4995C4FE3DFEEB691
-:109F800083398CA3796F0B59387FB2F524C8ACFEA6
-:109F90000F1B6490DA110EBCE6A1F95C6592BE6AF3
-:109FA000E1FE9DC5FE211D9155AA63DF42FD39B931
-:109FB0006F35A1FC3BE1CFC9CE78667FCFB3F0B35C
-:109FC0000553F8B34756B178B1A2761E2ECE8FBA9C
-:109FD000AAF8B19FC90B3079D9C7FC46C614C8305E
-:109FE000BF11E13DCC6F04F2270D2A077A5AA8DC95
-:109FF000854D57E2F9596AA4A909E3A59F8E7D9082
-:10A0000055D98FBA83CE55029D183FDF69C3EC89BD
-:10A0100084B03867F941FFEF3A301EB3D3CF618087
-:10A02000890ECB01CB7D18EFDF19E6ED7F26873A4D
-:10A03000F13C62BF384702C5D2DE57E0FFE7652F2B
-:10A04000D18136106FFF9B5EECCFAF08383D87F0B3
-:10A050009984191F111FBFC6E1C681B9D43FA90059
-:10A06000365E7C601E1F6F01B7EFA17543053EF69B
-:10A0700091FCDF84877048736B1D1E2A836A9A8067
-:10A08000DBCDFE5A817795FD8092E4FB9D882B9570
-:10A090005E3715F6358147A5F907F44B317EC1F4DB
-:10A0A000701AC7FDC7E2FBF45B3DEE7EEFB9F145E8
-:10A0B0006D9F482B8CC57F29277585C161EB70AEDC
-:10A0C00089C1911B72695ABE558EFB6B5917F1D02D
-:10A0D00024AD7F9BCF8ACEED8EAB5DF3E88D5A74B5
-:10A0E0002EE90FF1F5572DBE2B719C827EE0E9CE53
-:10A0F0008644B874BBFA8467CADE62FFCDE80A4CB6
-:10A10000D96BECBF5AABCE01D7B45FE4A81F36E7DA
-:10A110003BDE7BF57738DE9FEF3C5DE6A2A3D9E618
-:10A120009F80636E3AAB963BC510FB5C9ADB8F93C6
-:10A13000B0D88F2BC167163A61DEAF0F6EAEE1F675
-:10A140000DB763FE13883A6E3CCC02FD2B633D0EC7
-:10A150001B1E096CFB36D732BDFF7EED131487B38F
-:10A16000FA15F05F353D4E97EE4C519C2DDDE7D34F
-:10A17000FBA31477A338DB7666C8FB58B9CD9BDC0C
-:10A180008AF27BDA3F370B11EC37B502E3D6FDAE2E
-:10A1900078825B9EE29FBAA9E879995D8EF4F0F827
-:10A1A0009F0D6B8DC5F300EE55F879FD77BDC97B2A
-:10A1B000110FD48D40715AA075E035F8FEF87CD3AC
-:10A1C0003AF805F9FFFC7C4C85F4B166464F86F9F8
-:10A1D0006B3B0DA49BAF9391A6755A9C3DDF5BEB47
-:10A1E0001136DD04D94F998E990DB89E6A94093ABB
-:10A1F000B7AB8917C7E77EC523E6EDD6B2F4B9E75A
-:10A20000E3560CB4B2767BE7481EE2FF1C4FF61013
-:10A21000C6A31A3DB4AE775BEAE378D4BEBBADEE1D
-:10A22000268AA75BAA47263A725AB1753828ECA647
-:10A230007E113FDDD3C8FDD6E73B5ED7F0BC668F0D
-:10A24000D949F9004AE687D47E58F03BB3F804C5F3
-:10A25000C9874B9CBFF429DCCFEF0F07BAB345DFAA
-:10A2600047E87DA6A9E38587900EA67F0F917F061C
-:10A270000D5B181DBAA52F417EEF9D63797E81721B
-:10A28000B5DA437216C1B89C8CE7A24EFF79EF6A2B
-:10A290000F9DB366F49089F6FB29EB0DA08D48D194
-:10A2A0001BF07CB1E6F8953AED95CCDE6928B0F369
-:10A2B0006B56A556E07CD974F9607DD1F990E66EB5
-:10A2C0004F223FEF5E0206FA63BEB95DB94758BF41
-:10A2D000A757FA7454055787AFCE7D13E5896D2BC8
-:10A2E000E827FBA2560EED267F77100CF63E123BB8
-:10A2F0004C76941693C142BBEAFFCA345F4C671098
-:10A300005DCAFE9547D7B0F6EA6ACF2CB2CB5AF9B0
-:10A310007EA3B37FB8DF6871A75D257B73D4DFFDB3
-:10A32000E38FD3B9B2EAB2AB1428A88F76D7EA0D7F
-:10A33000EF692EA20FEC521E8FD0B92EC8B794B57C
-:10A34000B343C73FFC0F2F16F0FD84E2B2D385FD67
-:10A3500066F753CA7E3BDDB3F51F5E64B29CF4F230
-:10A3600038A8A25ABFC47579429C2FEE75E5DD244A
-:10A37000BD7CBD9C16EB186716FD6DF48F915F03D5
-:10A38000D76CE47E16980E3F86ADF7D34A819F6D59
-:10A39000EF7719ABBC3F3195D712F2C7CBE4B5AC20
-:10A3A00057928AB74C5E8BBD5E47575B1063F33B99
-:10A3B000560BD93E9CDF35166C467995C0ECD379A7
-:10A3C000FD09FB1CA509E5F01AD882EBD7504C3CDF
-:10A3D000871C6C7E3773144BE3AB449DF251691EAE
-:10A3E000B7BBE671B6D769877B2151936BC23846FC
-:10A3F000EC26C463775435713D7A3DB76CDD644C0F
-:10A400009F4758C1F586379A8362E3DAFCBCC36B79
-:10A410002DF4629C5D358F2551FE3B55F27BDDF5B9
-:10A420006FF58A3C962650D03E4BE33AC1F5DB658A
-:10A43000F1BC31494F3D6C12FA09C7B956FC4DCAFF
-:10A4400067FB940CA919AB006EF436713DD3B19142
-:10A45000DB3DD78324D762FD24ED5F0D962EB1BE80
-:10A4600061D4B6CBF4DB62EB0BF4E48D423EA7DEA5
-:10A470002763EF73BCF7723CC3C26ED637C7D62FC3
-:10A480002AD2BEB6B89EBC5EC8F58D5E614FA437B9
-:10A49000535ED0A0714B02F93CB0C632B7A0D64291
-:10A4A00019C17C941038EC6326DF37223FEDF89118
-:10A4B000A227A8B4ED8152F3EFB603BC3167DE49A1
-:10A4C000B5E7B6F1FD37951DC7BD3FDBF96DA8F9BE
-:10A4D0000AF9E4157C6815EB65CA5ECA88F56E5208
-:10A4E0003E90AC5A498C4BCA1238ECADBD425EE48A
-:10A4F000007FEFC683F9CF77E13A952316F9D7109D
-:10A500006AE3769B621AEB8BE06F9F733E21F278D1
-:10A51000E39977D3FE3756DB49FBDE805E5E7FD85A
-:10A52000FBEA1AB841C3B8DD6069FD3156A83FD4D3
-:10A53000A8C7B98E857FCFE8378AF1D9E6534CC4D6
-:10A540004BFBC31B6365E382AEF31553B51E22BEFE
-:10A5500094E6DB23E7C3B7319157B763F0E51744BF
-:10A560001E82535F2F2EA9AFBFE0D0A7425FBF8DE1
-:10A57000FC7FEEADE07FB57118FF76D9383983A93D
-:10A5800078254DF48C1AFBD2148FC1F58D7640A638
-:10A5900083F215200EA417B121EA3BBF6111DF023F
-:10A5A00022CEA4363AF719391A70C0B1EE3460BE23
-:10A5B0001AF68B74FBB7AB34AECD6F66B3503E99D1
-:10A5C0006D5FE272427FA4547E9A5DDAF11B3CC655
-:10A5D000394BFBD4C78F207F4F8580F687D2F43B61
-:10A5E000C789BD37515E3FB9EA4348315E2F722EAD
-:10A5F00038BD9D02AF17E8B5FFE3D227D693B775F4
-:10A60000931E058F89F1CBFED8464832BC8780EB7C
-:10A6100093112C57623EC9121DFDDFEF7A0DDEDE6D
-:10A62000E0FE9D4713717AA33A7FEF6EB60F15B324
-:10A630007F2E56B97D7CFA13A9DF625E427AA76449
-:10A64000E0FE76B2274FF6D3A6DC252AE6A55DA26A
-:10A65000CEA47A9BF637A96B0BD6E726E0E7FE0C73
-:10A6600011B5508FDAEB4FCDF85E403A4F64785C0D
-:10A67000E344E6DFE85CFFC401398B4C3D31726393
-:10A68000D9F57352E86DBBDEC903B285FDA547A4B9
-:10A69000EC02D6FEA462458AE60140969F070BF8BD
-:10A6A0008319D92197A7772455D433277B34E967B9
-:10A6B0006C6E6E473A19FE9B324D2AFA6495E89A01
-:10A6C000A13AE7D3A67310F3159AA6F27706A36F03
-:10A6D00010BDA7D873B94C3C69A7D01383D1E2FA57
-:10A6E0002420CE5F03DE6CF1BC0717BDC116E7BAAC
-:10A6F000B4F11B16F914C33AC76B38E6A179186E8A
-:10A700002CAFC706C43CD8F50663FCBC755049683D
-:10A71000D5E0E3D59DF8941A475B75B80BB7F91AE5
-:10A7200048767536117B5FC63802850E0DF49F9E04
-:10A73000923EC4D6CB0F6F0B59520C1F4EE4BEC9CC
-:10A74000E898C5FC1DB44F752B2BCD6DC3BC4E19BD
-:10A75000306EFCC89FBF917B15FD51E6FF205C6BFE
-:10A76000A4D65F6B601E5C52C275B51B953F75FE2B
-:10A77000AEFE8E56B1FE18FCD1A1CEB5188754207E
-:10A7800021E2191E03F3F568E97B4AEB09D49E67C1
-:10A790007D53ED4AD2E9F28B7CB0A1BCFFBD95D7C9
-:10A7A0004FB37FA87766B9FCACDA6EA7DD5DE37ABC
-:10A7B000BF57C86B29BFF2AD1A6726BCACE1B9AC74
-:10A7C000D6E6D1B3581F52B5B8DF466E5100EDF84A
-:10A7D0009986DE8B21BE4A7CDF053CCF0DBF8828E1
-:10A7E0005C7F9F51B91DDB78E7A725DC9F4EA197C1
-:10A7F000BD18E1BC594C7EDD76DF887182E2894369
-:10A8000070B4AB19EDF92D1E3A4FDADDB6AFB6B024
-:10A81000FD77C43853F30F86B29C4E65C99F57DB52
-:10A820003C16EE5BE73BFF6E3FB9D2FC376C75DA46
-:10A83000C5E73A2F2F21E2CB2ACFFF858E63CFDBEE
-:10A84000F4F5C1F566E39D2F521C67CC2CAF6FA6C3
-:10A85000CFDBCB346F9136B08AC5717E2CF6317761
-:10A860005E9F062930313FF115BEFFC8CDCB63078F
-:10A87000CBE81F39EEF23F443FF90F021CC5FD56ED
-:10A88000312A7C0F7778BFC2F6CDE0F62BF72B4B41
-:10A89000313FCBA23CAFD11E8B9E4FCEBFCF23F01A
-:10A8A00095C0B35CE81583CE3FF72B646F78E02C3E
-:10A8B000C6414007C3963BC07A5DFB158AC7182284
-:10A8C0008F80559D89ED80F4D2624CF6ACA7737AE7
-:10A8D000EA073BE271986E0EB386344F5ECB22BC22
-:10A8E000948C7627E3E72EBF800D01D70A581770A6
-:10A8F0009380611FC14195C11897F7667482030266
-:10A900006E12709D806B053C5FC0D23E8277A9BC01
-:10A91000BF9D4A96F71F10B021E03A01EB029E2F2F
-:10A920006038C8C7F77118F7438283026E12F00CC3
-:10A9300001D70AB859C0D241824BCD5F206E117F3A
-:10A94000A7E6BF8BF30D40F89B0917DC3D55BFC050
-:10A950001F1DEC31A4C2F3436F89F8D3121FD73304
-:10A96000131D09CA5362FE42FA44E1B963ACB8BC94
-:10A970005BA2DDE4B97994D52B1ABFEE2DBA2EAACD
-:10A98000C56FDD79E2F7DEFF20FC6EF6D9EB9EFBAA
-:10A99000E7131D26E1E9EECFDD0EED2D2838A70FD8
-:10A9A00028D934C66B988D44FE8E5773E6B3DEED1E
-:10A9B000E3E79CBD3E9ECFDA2FF09BE8E0E70F83F4
-:10A9C0000B02D983D2F438E35FF8783CE1FB369E82
-:10A9D000DA61F27B8279B662C90FE27ED468BCB3D9
-:10A9E00042FEBAF2FF0AFD65771CE4DFF01D1B276B
-:10A9F000102ACEA7BB27F5CD2DE913ACAEE667CF65
-:10AA0000D19FD1A3B1C6C2BC69F11E248F4CFAE517
-:10AA10000CAB67E78BC8D43F8F1737F278B12CEABD
-:10AA2000D3384DFC3B066B09EE33EC798B18479A13
-:10AA3000DEAFBB5DCE57C7E74BE063E7A7C8F01CAE
-:10AA4000F533898F92207EB99F631EB21EBAF0E75C
-:10AA5000170A7B8D12E365F8F94BA5F69F15F232C4
-:10AA60004D3E4BCCEB7FF3D976CA610BF3816C3949
-:10AA7000B2E5EB7CE5E882E50437A4B6D2729286B3
-:10AA800014AD1B055DCEC5E72E2F45E4245758BFF6
-:10AA90005EAB15E7F926C90BC34721B9D5393EF599
-:10AAA0004BA2D49F846B7C21F62060E403A3F75271
-:10AAB000AD56F081C7290278CE58D09E1147F84A8A
-:10AAC000B224F43EAFB746E3EB7C756723C71F445F
-:10AAD000FF2E7C597F5A617F3234BAE49CE3FD7EBD
-:10AAE0008DCF2FAB4FDFF94D1B5F91085F191269B6
-:10AAF0000F6BF75151DFADBFEC7287C06FD4035BB2
-:10AB0000F977920928FCAE32A879C4778F7C9DB979
-:10AB1000F59317E56AE9F9CB55B57ABD5E2BBEEF23
-:10AB2000303DDF82F1BE52FBCE316D723F6811F3D2
-:10AB3000764EF3FE6BD443CBA6E6B35A7C2F15E3D7
-:10AB40009E2BBE27A7E35B959CBD21F444B5F8ADD1
-:10AB5000394FFC5E76E1F756C9F519B11F558BFFE9
-:10AB6000FBCF531E7E309DBF55AD238F766EFCFD0F
-:10AB7000E879E2F7CF6EFC4AAC5B55E3FC4A0397F9
-:10AB80000F459CBF548B5F4F65FC44BED8BA012B68
-:10AB90004EF61AF9E3BBB5750369650A3F0BB85E5B
-:10ABA0003FD7F1EFAF7AFC770F58CAD4F88F68EF30
-:10ABB000768CAF2826095BB5E33E5AEDB8E9F73944
-:10ABC000E87E7AE47D8E71CF97EF5FAC7AFC5B1DF7
-:10ABD000743F3772AB93EE9049F9C4D58EFBCDF339
-:10ABE0005CEFBF14F80635DDB10F94B2DFCF08BBC0
-:10ABF000F6839AEE90E352F5DF10F6CABBAAAC7F5B
-:10AC000052F4DF6CE353A1FE3D02FF7BAAACFF6B65
-:10AC100081CFCA2AF1F9BE5887A5F6CF80E07B1014
-:10AC20007564815F73A1794B5B7C49C98FE79CCFC9
-:10AC3000F4D077826F289A8EF14EE802B2C7FDC732
-:10AC4000C307795E495AF8FFC9B4C4F530C5B7BC2B
-:10AC500051D3711E67FB5D8A92B08A9DB7D5FAB950
-:10AC6000FE9374B39BAF7715300FA954FDA0BF7846
-:10AC7000FCA5062628FF0462E21CE9CC8D46D173B0
-:10AC8000022541792DB2AEC24136CE40ED46A33009
-:10AC90006F396EE313B3081F55E7F8A88A6915CB1F
-:10ACA000539EE3E7F36AF763FB87526C02F83D0EAD
-:10ACB0001CBF417FA21BF3C4D3B52AF16920EC3C31
-:10ACC0001FBF49F4F34E41DF80B77C9E58E7CC7636
-:10ACD000CA57EA6FE7F94A069894DF39102A7FAF1E
-:10ACE000C1580F8FFFEF14F94F23F8FD287E4F8CCA
-:10ACF000DF8F2EC4F65FA1EFF04EB57ACADE8F1358
-:10AD0000369D71F6608BF37B1E3B2EEF379CDFF593
-:10AD1000F862CEEF7ABC3315CAEB1A08F1F3814A18
-:10AD2000F8DB79EF76BD6125A5E945F994759C0BB3
-:10AD3000F8624E7CDF3EFEF1F641EF61BD185E6FBA
-:10AD400015DF4AC51B26E9AD515359AE371CF91919
-:10AD50003D42BE7C355A0AF532D3BB25DE0778FB6F
-:10AD60005082F243B458C2A078B4D807345C0F05BF
-:10AD70007CFAA4BD2E031E3BDF98F23A24C3A2F353
-:10AD8000470DD79134BDDDE4BCDA72FFFBB5315A13
-:10AD900027F51AAD13C998A0EFBADCE32CF45BFBDE
-:10ADA000FC783EE6B71EC0D2FB0739596CBDECF506
-:10ADB000733DAADD9030B4F9E4AA92DDE3C6E34B1B
-:10ADC00062FD856CFCD316E55F548BFFA355E26FE3
-:10ADD0008FC3F0FF1CEA5986FFE7B12C85FF534271
-:10ADE0001FD581D14B7BB6C1F52CC07AA330BE1ED6
-:10ADF00008F07EEB849E02E870E4F578055DD5D21C
-:10AE0000F3ACADD72AD0638FCBE87951CCC777CAE2
-:10AE1000CDC7B7053D8100DFB7B40309832D4DB819
-:10AE2000B8C4BC9C1078CC0C88B852BAE39CE4EA55
-:10AE3000A52AE93831352FAF8A79F9E772741C17E2
-:10AE400072959161E549DC4F9BEDFC850D8E7999FA
-:10AE50002DF893F1D9F3D2E99897DA739C975F555F
-:10AE600049CFECA979392DE6255F4ECE0AEAFF5E7F
-:10AE7000D4FF83A84F76E2ECC0EF06F0BC6CA13F94
-:10AE8000E109D44FED6FAC9E1C583655EF93A347A4
-:10AE9000EC7A3EAAD735594F0B14F407E9D706F0E0
-:10AEA000FC7B507CFFF1FDD1F035A25D84DADDC082
-:10AEB000E961ED6A0AFBFFD2E82B76FF33B05EEF63
-:10AEC000DA3FD8F5A285F56607FE60D78BE173E916
-:10AED000C0647F0D85789CF0FFEB00CFD771E57BD8
-:10AEE000E9D5E53B78A349BACFA10EC2199995439C
-:10AEF0000ABF5F21CD8CEA43983FEB4BE6A00ABB2B
-:10AF0000CBA3F1763E666FE1F9F10C1D9EF71BE8CD
-:10AF100082987080BDDF1355C81FB8D39F6C0BD4C7
-:10AF2000733C290FE0556E8FF586DA441C85E3B536
-:10AF300037F88111EC4F677861FF9F0C469EC7FA86
-:10AF4000FBE6A894CFFBFC9CBBC84EDCDBAB00BE91
-:10AF5000DF7B9D4A76E203AF86691F1E54CC9B2897
-:10AF6000FFC1520DB41BEF0EFCE118E6298FF7D696
-:10AF7000E8D255440FE19FF640A29FFAE776E776C4
-:10AF8000863FE603D3D685FD76713F06449EF3DD0A
-:10AF90006B0DCA9B3180DFDF34DCAE529ED2DEC641
-:10AFA000F91D38DE03ED1AD91D0FDC30BF97F2B959
-:10AFB000DB0394FB56173224CCEF89AC50013F04DD
-:10AFC000A98B1ABD6877869707F0CE2FA86BE4E3AC
-:10AFD000851702DDF3E7854C22CECAC8884AF738C8
-:10AFE0003D70C386DC66B46BDA79FE3223ECE5F89B
-:10AFF0007280906025C83F00C4C73B9B9FE7DBF38E
-:10B000001CC94CB62F7B8E18C956592F575DBDF001
-:10B010008842F9C915EB65AAAC97ADB25E8ED7AB85
-:10B02000787E2FF22935F60FE3707E773E76A8FC06
-:10B030007771E79AAFBB37E0CCBBAED4DECED3ADF1
-:10B04000442F1E664EE22957AE6FE7D9957AEF9DE1
-:10B0500079570CBF4B1BAEBF5794F7F1B2413C6F11
-:10B06000D81EA3FB221BC4FB86FBE8FE48773F7F6C
-:10B070002BF4710B24CACE439DC0FF75863BC6B32B
-:10B080005B940AF900EE7C3F97DED3947427ADDB26
-:10B090001B787ED1E4F7938DE2BB114825E214CFF3
-:10B0A000B2228B674EAD1FEFAAEFD2FAB1BF9B64FD
-:10B0B000F3C3BF9774C9895B2E7CAEFC940B959348
-:10B0C0001FBF4D72E21D91AB5A3FDE4C95F5B25554
-:10B0D000D6CB55574F1D91AAD22B6AA6CA7AD92A28
-:10B0E000EBE578BDC195AAD8D7470731BEE5BD428B
-:10B0F00073C08357049CEFAF0C39E0A165CEF6EA2C
-:10B100007267FBA1E5CEF6EA0ADEDE0CEEBF261D75
-:10B11000AF7E9DFCAFF35C272D5AF9FAE1F60AEBFE
-:10B120004AD3FDD8BE4E3100EF1762FB5556EC5B9B
-:10B1300045E33FEB827CFD5F17D01DF7D3FDA9D31C
-:10B14000D912E4F8DAF456C2D7D6BFFF220BBBAB54
-:10B1500044DE3D7E564079D830DE80FD3D7FCFCC49
-:10B1600006B4E7F6BEB682EEEFE87F979D376352EE
-:10B170003EA472EC9764BFECDDCEEF977EB4D6ECC4
-:10B180008AA3BD12F600DACBCC8DA27B3DF6C63C7D
-:10B19000648FF45F5DFEFE924FF5F03CA187D1EF26
-:10B1A00067FAFF80B877EB4171EFD6FD3D0695BB9E
-:10B1B0007B5AA8DCD5635239DAD3CEF3197B2CF154
-:10B1C000DD5917955FEA49D0F32FF47453F9F99ECE
-:10B1D000243D7FAA672B959FED49D1F3433DDBA921
-:10B1E0007CA2274DCF1FEF19A1F2B19E0C3D1FBAD3
-:10B1F0007A03DD9371EA3E0F7D1D520AFF392967FC
-:10B20000DC61F65667DCA121E98C37CCEA76C61BF7
-:10B21000F455F31DEF236DEF70C0A1D6258EFA8192
-:10B22000F8150E586BEC74C04AE89D0ED87C6E83FE
-:10B2300003BEEC999B1D70EBD39B1CF03B3EFD11B4
-:10B2400007DCF2A93B1DF0C5FBEF75E0171FEB73A0
-:10B25000C0EB83F3F97DE0033B1DCF8DFBF639E0B6
-:10B260008FCCB41E0B623C3413E1F6EC7189F6C14D
-:10B270001973CDDBF03B29F8B14CF204519E0F3F1E
-:10B28000637EEA72BCA70C94D48A1BC395EF91B677
-:10B29000E33D72A43D89F27AFA35C9407B578A6C46
-:10B2A0005F58E8CFD9E5D65329388C71499167A604
-:10B2B0005F0496C5DA05983EA1C34548E57650DCA3
-:10B2C000D243DF5165A424E59B309BD9FC2B1DF3B1
-:10B2D000E8DDFB6F90ECF253519ECFDED1A9350D26
-:10B2E000B0FABB17A926A6784DC3D775BFDDAF82CC
-:10B2F000DC0FDEB583C72BF517FC4D1A6B1F32939D
-:10B3000033D055B5DB8572DFA3EF944286B91CFDBF
-:10B310009A503C039B43588F7FD7C7EA7F3558200C
-:10B32000BFA164CE5259FDD89664B387D5DF2DFAFC
-:10B33000DFBDECC7748F6038F713B898FC9DCFD091
-:10B34000F8E1B6A3707B18F5D338AC2BB28E77FF3B
-:10B35000BEF8F748E34199DAEFEECD82C9DA05721B
-:10B360005FA77B38ED7909B61E8524F6BB6A82BEDD
-:10B37000A1DDBD43A27E764B2FC56282CE5E179DB6
-:10B380008817D2753BEB27D49D94D6B5F2E7CDE173
-:10B39000A97EF1FD667C7F4B4AC23CF76AF8A72282
-:10B3A0009F928C7FB8DEB664A4B2FC337216F25B57
-:10B3B0008B57E2DF839C7F8C6FB7B74EE7D764FD76
-:10B3C000F45158DE5AC06FD11EF9727B11BE4EF295
-:10B3D00089B54F52FB97606988B7433E8419DD9B5E
-:10B3E0008BB5935E12E3649DE3303EDE4ECFD322F5
-:10B3F000BEC8EFF5B4F344ECFAF8D7B55CE42932F3
-:10B40000BABDE3B59BF1FBEB8ED624DD033C18F20D
-:10B41000D0FD4283A1AFE4E89E7E1DE8FB5945B113
-:10B42000FA7E14E571E83EA9D83A75FA09F8654A3A
-:10B43000E1F76403213B0FBF82BD24EE1596C5BD25
-:10B44000C2AA92E86AE2EBD9EC85A9F8EAF4F1F72E
-:10B4500011DD72CCB9FF0E6C71EE7B71FD668A63F3
-:10B46000F747ABFB6EC897E7F6A52AF0F1E683FC39
-:10B47000BEE3BC9FF0B4F233A85C93AFA5F2AAFC84
-:10B480006C7ABF3ADF40F0AA7C33C157E69BA8BC78
-:10B49000227F293D5F99BF84E0F6FC522A57E417CA
-:10B4A000D3F3E5F92B095E965F49705B7E2D954BD2
-:10B4B000F31D542EC95F4FEF17E7AF23D8CCDF48F9
-:10B4C000E525F9F554B6E4FF8CDE2FCCDF44F0C55A
-:10B4D000F9CD042FC8DF46703CFF51829BF31FA6B5
-:10B4E000727EFEBF52D994FF18BD37F21F27785ED7
-:10B4F000FE1E82E7E6FB099E93EF25B831BF8BE085
-:10B50000D9F9512A2FCA3F4065437E2FBD9F957FB1
-:10B5100088CA99F927E8796DFE712AF5FCE7C57D9F
-:10B52000D14F5119C97F95CA70FECBF43E94FF1BD1
-:10B530008283F9AF5319C87F9B4A2DFF3C9595E64E
-:10B54000A9D2F74F6B6086432E56E72F72C0574E35
-:10B5500038F7EF953F77EEDF2BC69738E065C79C4D
-:10B56000FBF7D2A39D8EF78B8FBCD3015F9273EE56
-:10B57000DF0BB3CEFD7BC1814D8EFACD998F38E0C4
-:10B58000A611E7FE3D2FEDDCBFE76CEF73DA2FA9C4
-:10B590009D0EB861AB73DF9E050FBBF2C90F3AEA8F
-:10B5A000D7589F73D40FB77FC575BE92E5FADFFCFD
-:10B5B00086D38E6979A1E8394C7CFF75F4DDFEA94C
-:10B5C000468FB86748DCDB2AEE4773CF679DD00310
-:10B5D00033F2DC7F8A8A75578FEBAE20EF89D91959
-:10B5E000AFA17EB0ED8C19F38D2FBFC8E0D373559A
-:10B5F000B397C1B69D61D7AFF8BB15AA399E6678DF
-:10B600007A8FFBE8DE3929D26D615CEDEE1312DD35
-:10B610006F57371B449EC0755D3C3E01F67D3A7402
-:10B62000BFCFF01CFBFDE66B298ED1C4E123A11D29
-:10B63000EB308E3AECB5DF7FFE5A6AEFE7F0FF0899
-:10B640006D19C2F775358763681FED2A71BEF93F22
-:10B65000432AF1B33664FD30B46CEA9EE9E3D1E4E9
-:10B66000CB21F67C9B969C875776E33DF7788FF34A
-:10B670003AC5FA11D65BAF58AF84685F70FA0FEF26
-:10B68000C7DCD765742FE04FF0BD1C7996F6A3BADE
-:10B69000EBEFA3FBAA86C30C9F50697CFE3E244FB0
-:10B6A000EE3760EF37F3299E4AF6E05013D0BD190C
-:10B6B000C3B58934DEE797FE8E06874CA43BC3935F
-:10B6C00095447EE2F025862D178EFD092091C33822
-:10B6D0007E301932D05E0BC151CABF88C004953A82
-:10B6E000E892E3BE6D9BFE399C7EBCFF3F44E7F0D1
-:10B6F000D6B3E314674D81B8BFFA4D7CCEF8723AE9
-:10B70000B4AC345FAE91EF039D8DFF28B327918ECB
-:10B710004781E33B86FEA98478A6F466EAD7798F51
-:10B720008472FCEB243776BC47915769CD488FB8BB
-:10B73000C7A18BFD43FBB03E513EDEE3BEB7E15CEB
-:10B74000E33DD1B03BDE13A2F3E453ADE5BF83B3D9
-:10B75000E33E63ADE5CF7B9F157EDFD7C479EF3342
-:10B76000E2BCF72BC2EF3B2CFCBE2FA2DFC79E3FF3
-:10B770002DFCBECFA1DFC7E027D1EF2BF8BEE4C977
-:10B7800012F7BF2CAC95849C6D27FB3E28EE2B62F4
-:10B7900023903D1F10F6FC98D93713FD8E602D6461
-:10B7A000D14FD87ADD41FA7E969162E2FD0077FCB6
-:10B7B000E2F599FF85C1F11838EE770AB4BAEE4B7D
-:10B7C000A8348E92B5B0DF20F31B326669FE9C73FD
-:10B7D000BF5A16FCE7D52FBFE7C7BEB78D71328DB4
-:10B7E000F21744BA7594ABBFA1714E897140FEC186
-:10B7F00011BACFF07205CAC9C1B471CE51FEB68478
-:10B800005DBF4FE1923FC0840D46EF3CF1BDA611F4
-:10B810004A37EF61EF9FB84F757C9FED96C7DED733
-:10B820007C14871D5CCCEFE579B17EDD45E80F7EA9
-:10B830007AEF9B4D889FFDDD52BFE98C5BCCBB0F3F
-:10B84000A4C27C9603623FE8D7CBCBB97DAF78FF2B
-:10B8500058F97A0F8A7A5F0C5A7D61D22B13741FC4
-:10B8600064FB89AE9B11DFC77668745EE36EF7C533
-:10B8700060726778D9743C0BDBA3BC9569BFAF5C81
-:10B88000FBE53FEDFA29946FFF70B8BE74FBB697E5
-:10B89000BB1EAE80FFC1E2E3A71FC376F3623CCEBE
-:10B8A000D4DB3044F3BB6B07F79F5F5CB48EEE993B
-:10B8B0001DA8E5F356A4DF2F54E04B7705BAFEAA86
-:10B8C000527BA93C5DDF2CC717C6D76315F8F29DE4
-:10B8D0000A7C3D5001FFBF2FC1D77988F73CFC7D22
-:10B8E00038D6AE770EE32BFA6FC85798BE1E8AF48F
-:10B8F0007BAC1C5E55C8EBF805CAEBCF2BF0B592BC
-:10B90000BC4E5CA0BCE64BC92BE27D01F22A47CAC3
-:10B91000F3B592BC06231726AF33CAB5AF425E67B4
-:10B9200097C3BF0A796D2E36BE0F8216DAD5A75A95
-:10B93000F939D9D60E7E3F99B785EFC3C1E39F256C
-:10B940007B6980ED5733DA71DF3EF1E01D6D53FB0B
-:10B95000B47B1F72F7E7DE47EFF8DF9FA17D342449
-:10B96000F67D1B1FBFE1EEA7FCFD16E73A6E007FD8
-:10B9700097A9E0F72E1A926FF578CE7D3E60F2F12E
-:10B98000818DBF96CE159FA673C59AF60B1DB77C09
-:10B99000FD59DD1766177C28E2B40B666FFFEA637A
-:10B9A000741F89E867B662D1EFF8297035BFFF646C
-:10B9B0001BCF1F92B77FF9B1934B0BEE9982C35205
-:10B9C00061BE90BCEDF063270BF0CA63FC87C79B98
-:10B9D000298F31AE5F11A07BEBC6CA9F67FC40EC9C
-:10B9E000E3DF17E71947C479C677855DFBA2B06B23
-:10B9F0005F10766D4ED8B57F2BECDAE7845DFB0DDA
-:10BA0000719EF1A0388FC8F41C20784F4F56FC4E21
-:10BA1000C993E2774A0E8B7CC967F9B9454F8EDB33
-:10BA2000C78F7FAD19F93145873B8EC5E9B0EF4728
-:10BA300077D3F12ED379DFC6F52D41C7BC5D6738CA
-:10BA4000E322D7C6663BEA5FA3373BDEAFD52E7550
-:10BA5000BCEF80A5CE384BFE0A679C65C21917B9AA
-:10BA6000F2E7CE738D95E3CEB8C88A63373BE32CFB
-:10BA7000479DE71A4B8F38E3228B73773AE0CB9FD1
-:10BA8000BDD7517FD161E7B9C6A54F3AE322B3BA1A
-:10BA9000F739E05AEB61E777F5EDCEB848D874C6D0
-:10BAA00045822D5F71C0EF61FB3DEA4FBFE18C8B9A
-:10BAB000F862CEB8C84F43FC1CD0F6B359BBBF8B5D
-:10BAC00090BF19CA5DC9E4FD8928BFE7FD09485246
-:10BAD0009E2CC09F93DFA04CFA0D16AD7B59E81D3C
-:10BAE000B5E1E48FD1AF517673BFE70E69454E2BB8
-:10BAF000F47BBCFF2215CA87ACBBFD870AFD7B4DDA
-:10BB0000F277940A7EC9F47EB9BE9ABAE7BC2D8D4D
-:10BB1000F954CAA45F72BDCB2FD996A1DFB39A5155
-:10BB2000DE2F9936CE39EA9FD391127E49CC43FC61
-:10BB30003314EE97EC32855F02FC7B29BB3F5BFF41
-:10BB4000A80DE5F5887D5F8BBA88FB0D4AA8F879CA
-:10BB5000B67DDFA4BAB87C7FB65FF37711714F5C16
-:10BB60000D88B8FEFF978FB7523EAEAC29113779DA
-:10BB70009BE5A354BD73950F057506E5837C70188E
-:10BB8000F3417C2E581370CDFDDBD6E1F74DDB8100
-:10BB90009FEFC02BFCDED552FDDBF95DF155B7966A
-:10BBA000CD83B0E3AC522D3FFF8CB7DF4AF993A7AA
-:10BBB000D818E5EED576E75BC8D114FEE81E7ECF37
-:10BBC0005EF4DCE79FEA785C28DEFD81B2F68AFB52
-:10BBD00077C1E256F97B764705FEDF7E7516D9A957
-:10BBE000BBB6717DAC747FF37994C74FA33C9A14B4
-:10BBF00057D12E41BAB62974AF5AC8008A0FCE0D5C
-:10BC000041B6B709F96AA6F13E2FF647E7CB93F2A2
-:10BC1000B9CD79BFC9EF74BE9EE389F27CADF8BBA4
-:10BC2000062B0F77D0774206A4F45A5A3FF07A9445
-:10BC3000F023391D6E37F9EFDF317C747D7A7B3765
-:10BC40005EEEF5A96CB98AE24AB3257B7D064DCC40
-:10BC5000D739150A95BDEF6D5ABFE7B81EBF306DD5
-:10BC60003DDED0F78F38EE9888236D677F05E79D1E
-:10BC7000EEFEECF568C3DF7EF56EFABE6578EC4E3D
-:10BC80007E6F71A3B81F6C8CEBC752781D1272B413
-:10BC90005BD88587F677F6217F07D8BA29D4470B7A
-:10BCA000FEF2BD81243F5FACC3F23307F877DB17A8
-:10BCB0003FB4453CDF44CF1744F9FD470B983C6146
-:10BCC000CC3BBCEC158DBF7F59A7FAD1F1117C7F1D
-:10BCD000B178BFA7BDCDC2DFAA8CD4CEEFC4521EAF
-:10BCE0003B4A7A97CDB9B5C0C07115FA1D9DB923ED
-:10BCF000F038D231772CB1E13AF40FD2C07FAF2DBA
-:10BD00009ADC89F21AC900F597060E1BDB759ABFFB
-:10BD1000F858721FD56FE5F5D97B82E7A6F8FBE0EE
-:10BD200018C317C733D97B03DF73FC1BB7E814AF05
-:10BD30000B8D1D4DAC257FC46ECFE1865B787B6596
-:10BD40008CD183ED6376FBF10CBE9F15E5EDD5310B
-:10BD5000BE3FEE69DF44F7EAB1F1E9DE29AF78FED4
-:10BD600084E07FBCFB5F336BA35379196966FFAE38
-:10BD70002FB29EED756FFF0E60BFF80E49D3663F80
-:10BD800072B2E05E06FB77430363CEFDF94C0D5FB4
-:10BD900097FF1DF5CCB2CAF7B3FD3B5950D3F30062
-:10BDA000800000001F8B080000000000000BC57D14
-:10BDB0000B7854D5B5F03E67CEBC3293E4E43D79C0
-:10BDC0004D4E2040944007081810DB495444458DDF
-:10BDD00068DBE0B53A04E419202296A0D89C9004D0
-:10BDE000F20206EB2F111126281A2BE86041B15AF6
-:10BDF000EF80B9147B6D9B5A2FA2A28DA05114B86D
-:10BE00002915C9DF5FAFFF5A6B9F43E64C2609EA4D
-:10BE1000EDBDF93ED8D967BFD77BAFBDF60E6B102D
-:10BE200059C8C6E8E79B61F09F1A63CC5725B2500A
-:10BE30007E58BE32C3989F3BCC58FFF64B8D79D7C6
-:10BE400078633E798AA1FDF91B18EB744246F2D85B
-:10BE500018A4D2D1DB6CA56318AB4D5E4EF9DEBBE6
-:10BE6000F4726F0CE6F3E418912533B6AD400C3450
-:10BE7000E532F644D5F2C3C320BF3659A43ED7BA43
-:10BE800066C6FBA0DE37F8F3A3FE69433563212BBA
-:10BE900063DBABFD946EAB6EA5B43E79F0767BB5FB
-:10BEA00076CF57DB58681463C16A99F2CF56BB2826
-:10BEB000BFAB5AA1F457D5F9F4BDBDDA43F927ABAE
-:10BEC0008B287DA2DA4BDFDBAAA7537E6B7529E5B1
-:10BED000B7549751BEB5DA47E9C3D50B28F5575784
-:10BEE00052BAA1BA8AEAB554AB94365537D0F7C0E6
-:10BEF000B860596941FF79D6CA00871428BFDA9320
-:10BF0000510AEB79FC6A56168C5A4FA07A1B6500D1
-:10BF1000DA44C6DCCCCF1C85F07B2B633B15C6EC2A
-:10BF20009D7ED50970BD74177CC37CC8AF3A209F35
-:10BF3000FF04CF6FD2C6A962CCCBB05D150BEC0469
-:10BF40007CD8143F9B0DE379B35576732C63376926
-:10BF5000E3E07784AF9AAB32C4EF098BB7544EC19C
-:10BF60007EF8F8313E9F00CB63692B588D05D28453
-:10BF70008A2E668771E21F0A796D900E6BE864BEA7
-:10BF800002C4AF586282799CF38B011374AD4C6587
-:10BF9000A208E337BB383D44AED3DDBB8D852640D8
-:10BFA000BDE42E3B8EBBAE6A663C8B020F3D1DDDB1
-:10BFB0002EF6D127FCBB2410C60FF06F9D7FF0F644
-:10BFC0006965C6F609DE88F605D01EE0102806FC75
-:10BFD00045A1B7F82263FB584F447BD7E0E3C7F491
-:10BFE000DEC8424903D3F3294B790DC25DCF8FECF4
-:10BFF000FD21D57FD729131E12AF5FED4238C3CF85
-:10C00000550867298B059A04CC7AD902C89BE1B7F9
-:10C010002699E76D90374990F7403D55F1B2B198B8
-:10C020007ABC2C0E532FE50F997D1BE589982FE5DF
-:10C03000DF651FD141E012E82203E58DD2E0CD8219
-:10C04000FC8FE1F7298CDD2C8F9EAE42FEBCD927F8
-:10C050005641FFCDD9626007E075A57B7C0CAEFB35
-:10C06000F196C1F9B416F974545FDEE4F43201FAC2
-:10C07000C9AC90C79BD8C0ED1EAA10A707A2F4BBFD
-:10C080005BA3DFFA8A99F2085C7507CA30C6AC4E2A
-:10C090001695DE60BDBB71BDE664BECE945B4B29D8
-:10C0A000CDDB35D9560AFC703E7670FC3546CCDFC8
-:10C0B0000E4306A3E1519B57DE1B2F91BC3C3F86EC
-:10C0C000D3D540FD366BF2AB3720B24EC4AF544AE5
-:10C0D000F235E5561FCB83F5AC4B17034E58CFBA5C
-:10C0E000AF6F69C8057E5237892407F4F9478E6B14
-:10C0F0002AE8124C50BEEEC042A6C0F8665729533B
-:10C100000B30AFCBEB20C3FE1DCE90175390980C95
-:10C11000D7EFA8F2A998B7B854E2E775E917EADBB8
-:10C12000102ECD7E91E4FBDA2C31C0044A9913E63F
-:10C13000736E35A37C4EFA838C24FD57309F49D013
-:10C140000FFE6E42783355C475E4325A471E3BCC1D
-:10C150004CD0CE3686799AA04A7C1E3B80EDD6A57F
-:10C160007F79C08AEBBB97794628D8D847F2080870
-:10C1700094A11C595B2953FDCCD6B1C417FABA7FE0
-:10C1800062F17D1ACE3716179767EBBE364595AF2D
-:10C190008735F9183300FEE21378F97973F05A9471
-:10C1A0009FCD90DF11859EEC5ABD47E5997FCA5718
-:10C1B000FAF8532F7FD7A910DFEAF9CC5E0BCD3BFD
-:10C1C000EFD69FC5E3BA06A287B51A9DF9E3B9FC7D
-:10C1D000CD9B7A8517E17E0EE68AFC1E597F51BC05
-:10C1E00042F3D0F392D328A72E7E7E12C9E3BC532C
-:10C1F000AB383F640F4EB7FA3CCF671BED04316F8D
-:10C20000818A7C5DAF007E15B417D63091EC02E6D2
-:10C21000615C45B138C83FB15A935FF95DF64B2078
-:10C220006F7BCBC410BFDBAA4A4415E09E932B055D
-:10C230004C00F7F82CBF97813DE2286002CE1FF03A
-:10C240003D322105E96012C1337B754810A1D31E30
-:10C25000947D29B4EC3AD7243E0EFE077C3F26019C
-:10C26000D6E9DD2570F9E0E2F2C10CD3B191FCAC66
-:10C27000624118CFF19689BE033F841E807C8C2CCE
-:10C280007A509EB678D6A4221F3A1218E9B505D77F
-:10C29000EE20B905F2D6B30556B4F46477EA32C895
-:10C2A000E7B9F87A74F8C414580CFA61C871A4801C
-:10C2B00017FB7508CCE3F70CA247BE6DBFB600B301
-:10C2C0007FA77E4191A4129F683FEDAA80E3E0BA68
-:10C2D000A15F2B7B99C639A78DC34C6F1C467E8905
-:10C2E000F981C44C51F865C0714CB70FAA37AA8EBA
-:10C2F0002DFC5347183DDF95109BDC3D1A7EB98C11
-:10C300005DF60D2A0E13103CCE03EC4E13AD9FAD1F
-:10C31000413CE7C8DCEE509CEAF00D50FEF86A0B99
-:10C32000C90FBDDFF3D50BFED401486C29E072BF05
-:10C33000E6436B09F6533F4E0C58A15D47CAB48CD7
-:10C340002EF8FEC4A62F73717EBA7D5AEB31F245EA
-:10C35000CE6A4E977ABE55E38B5A79707DB241EF23
-:10C36000AF65F07A0F6BF59E75786B918E81D20573
-:10C37000E4CFA2E3D36FC3F96E7FC0C64C51E4C2D1
-:10C38000B30E5F73C2C4FEF30C6F8FF43648FB5FCD
-:10C390000ED67ED2BBD3DF6583B77F342165E0F64E
-:10C3A000856F4EDF32C4FC1F8F3EBEBA1DDBE5B881
-:10C3B0002C0CF15B93BE96F0DBFC80C563057EEF31
-:10C3C0001833CD8578AB4BE0788BD2EFB383CD0BB0
-:10C3D000E05236C4BA5E18AABD30F8BA5E1D02AE8D
-:10C3E000478780CBA1C1DA035C5B8798FF1FA3CF8F
-:10C3F0005FCDC179E7645948CFD464035C518E2383
-:10C400005C597F7E88D2EF3B43C065287AFDF07B84
-:10C41000D2EBC9C1C6BF087AFDDBF7A4D7FF3B103A
-:10C42000BDE2BCBF07BD4A89DF8F5E9D8983C375AE
-:10C43000287A4D1EACFD45D06BD660F3BF087ACD8F
-:10C440008B36BE9539BC2ADA45055C9F2F281649E4
-:10C45000BF9BF3B91E761C7BCA8BEBAA037D955458
-:10C46000847AFBF8C34B0BFBF474A41E8AEC2F52A6
-:10C470008F2EFDDB93A4479D9ADED7E7635722FBFF
-:10C48000F99741EDBB6F3B6E8C8B85EC63FBDAA7B4
-:10C49000FBFEBBC733EAF9180F1F9FC1F85716A15F
-:10C4A0007EDDE541BA8C2FFABEE30E5E3FADECFBBC
-:10C4B000D9050B12C12E70F4D9059955BFDEFE5176
-:10C4C000525F3F999297C9403712BB8AEC3756C1E9
-:10C4D0003C3BB1B86ACFF68F26F4D903007F01FD4B
-:10C4E00023FA38A68AE0F68FC2E6D53B9769FBB4FB
-:10C4F0004ADA17E5C95362908ED7B50C6E2FBFA1EB
-:10C50000E9F1DF6B7EAAC39A9FEA10FAA920ED40F9
-:10C510003F15A407D14F05E521F45341FE55CD4FFA
-:10C52000F58AE6A7FA8DE6A77A58F393F9D14F4634
-:10C53000FEA880E68F6AD7FC51414A1BAAF753BA7E
-:10C54000B63A44F5DADB5E188EF0E85B07B7DBF34A
-:10C5500064DDBFC7D7C158298B86AF1B3C26C3FEFD
-:10C56000E2FA7C87016FD72A4986FC35AE4C43FD41
-:10C57000ABE5E186F22B6DA30DE5C56C8221FFA32F
-:10C58000DE2986FA57F49418F2977F7A9DA1FEE48B
-:10C59000AE9986FC65476F33D49FD8596E289F703B
-:10C5A0007891A17C5C68B921FF83FDF719EA8F09B6
-:10C5B000AE31948F6E6F3294A7953D18E167DA62C1
-:10C5C000A81F5FB423C28FF42B43B923FF7943FE26
-:10C5D00026D0F728FFECCA6F0CEDACAE8386FCBF0B
-:10C5E000C531DAFFD89D41AF378A3DF9553CDFAF01
-:10C5F00082DD5E4CF632C8B1A671D8BAD28FFBF19B
-:10C600004CF81DED63C0AEC08643EA31CA1D5385A8
-:10C61000C538FE10FC8C1E00ACEF861FE4C7AFF4DB
-:10C62000FD6CBB5DFD218E9FC7E5B02AABE47F8822
-:10C630006CAFFB8BF2DA67C563799D5C2247930789
-:10C64000272CBE93E1FA2172FF9BE78D655E1CAF3C
-:10C6500042F797717967E25558E6B16B0E0BE8FF28
-:10C660002A7B3501D7A3FB79D6697C5AAFF991AD06
-:10C67000EC72F2639CD3E43F334DF50C269F22E12C
-:10C68000F56DE5999814B9CF9911FA18C7AF9002D2
-:10C69000D1F4A49EEA722CEFAD3B07C58F0E5F1D4F
-:10C6A0008F2639E845BD6A532A59B9B33F9C4C5986
-:10C6B000400F71FFFC75E72619E5F839F64AB177A6
-:10C6C000D845ACB7EC0E5A878ECFC87AFA7EAB0548
-:10C6D000F14AF291CBDF5A0DBF6291770DC2370E4E
-:10C6E000F6D1B8FF133D21D6F51DFCC08EFC4443A6
-:10C6F0005E726618EA9B3D952C88FE5B1887113D9B
-:10C70000FA18FA73F11FFA4B4C3287F3C07C773971
-:10C71000F909CE45D82103F11F0EF1CDF0A1F9F5AD
-:10C72000BBF277C7DC54EAFFBE78A6F95F549EAA35
-:10C73000EC4DA49FF2228D8098F2D3F760DE0B0FB0
-:10C740009B49CEFCE8ABED871E03BE341559E526A8
-:10C75000F20CF90FFD16CAE77A6DA5985F786C8C1C
-:10C76000C50DE5473280085C585E1A8772E03413C5
-:10C77000A7A3DFEE347B336E42989CBB27C942F2FD
-:10C780008535988F77D9707895CEB1EEF2F3BCBE2F
-:10C79000AEF9ADC6FC3C3633558271E63D646601A8
-:10C7A00000D642261DEFD2E10074302789FBDFE777
-:10C7B000B3CAB5328C5B6FE6E7364B5E1C63413C17
-:10C7C0002C9C20E79AC6F5CDE3FE2491EA7F06F47F
-:10C7D000A658FBBE2F72062C28974FEC9DF093CBEA
-:10C7E00019F613589B81FECE04B04394FEF09DD3FE
-:10C7F000609CE750EB889C37BA41069B87D42E7823
-:10C80000A3F9D51B9304031E6B6DBFD8DE05F3F4AB
-:10C81000D64ACCFE43C84BFC5C493D161BD889F276
-:10C82000BBA4F2A92E8083BAC62AD742BAD9F18B0B
-:10C83000E7B07E15200CFDB9CF2729348FF376772A
-:10C8400000CF1940DF5C3633F6FBF7FBE23FA9DF90
-:10C8500057B0DF94FEFD2EB17559D09FB84CAA9CFD
-:10C860002E88E857E4F5AC669F3713FD89FBC78532
-:10C87000321543BD868BAC7758187651F5A68B835D
-:10C88000F47746936FBFDBF5B805E5D6E95F7D78B1
-:10C8900023EE8716BF6C6236A87766572C0B91BDC6
-:10C8A00017B0A0DDBA68AFC91BA07C68D22DB1E17A
-:10C8B0007C5D4BFD2F7E2E96F6538B9EB706664011
-:10C8C000FB452F9C18CB401E9C59D3732813E1F7CE
-:10C8D0002B81EC67A6768DBD05BE2F92D89DD1CE5B
-:10C8E0003DFF9AC4ED8E532F39CA90DE84F603774C
-:10C8F00050BFC19F9AAD617AEC489299F009F5C892
-:10C90000DFAD3E2D0446087C7E378F099F5F0DAF5B
-:10C91000F734F7E72EDA6F0ED8717EED6D161FD45F
-:10C920005BD6FE37A2EF2B9FDB1D877058B6DF6802
-:10C93000AF2E7EEEEBB55300CF8B4DAC6706E9F121
-:10C94000AF287FCE6BEB31911CF2C60920B79692CF
-:10C95000C8827ABFFE64DA7B50FE99CBC4EC200A11
-:10C960003EEBFCD8F232E67DCE4AF4682FDB6FE472
-:10C97000C365ED272C382F59643D59C0E83FFC2290
-:10C980008C2F59FFFAB00FB6A09C5D166CFC9B096A
-:10C99000E86DD9DED3EF22DD2D8BE0E7CFF097F401
-:10C9A000FEFAD29A1CA92FDF9884FE72D60E9B9FA6
-:10C9B000C903EB4B9DBF17EF3EB74D85F14F3DFFD0
-:10C9C000F93615505EF15F7FDF763FEE8F5EB5CBB7
-:10C9D000289796FDEA3FE25818FC872573F970E620
-:10C9E000E9A79EDC027038F38E95A076E6B79FB873
-:10C9F0001580FB993DFF3715CF9D56FCF6EA34A410
-:10CA0000B315FBAE4C1B6C5F84741BB086E33740E0
-:10CA1000F855F6C33869907D454B23F0726ACF799B
-:10CA20000B9E0B7D29B01E94BF4B835F5BD03E3BBA
-:10CA3000E4653D08A7D7F69E38741FE44F039EAC0B
-:10CA400051F004EBCF1449AF843251BF2CDD7BCBC6
-:10CA50004D5714626AF6288827D643F2BE1F7EDF40
-:10CA600002FC16F6E137B2FC1CFBCA82F05FB60B83
-:10CA7000F03916F10AF81CDB1F9FA7F197C9FDF1E9
-:10CA8000599C6CB4FBCEB18AED5BB0706F12E17F44
-:10CA9000207C2ED9F7E341ED2C5D3E0C05E7050225
-:10CAA0009F576CB2F7E664E4DBE71DAA8BE33930ED
-:10CAB00003CACEEC3EE76640279F9A7BEE4038F4EF
-:10CAC000FCD62AEF80EF8B7EFB36F1DD997D7FB6B9
-:10CAD00020FEE1274E98047976E1E74D06F9A5DCC2
-:10CAE00006674B58CFB4770B31653DAA87F047F9FD
-:10CAF00043C087848FC0CDD31594BF81145AF7D219
-:10CB000000E78FA58103B70A63FBC3BD3959D4F58C
-:10CB1000D605BC0A4588CF0FA721FD0D844F7DFDAA
-:10CB200032AEFF32287FC2C8BF91F59702BFE2FE46
-:10CB3000A81F7E0307FE88E99936AB24802D740672
-:10CB4000ED04677FBCF7C19FEBE76F6B1FD747F022
-:10CB5000BBDE5E87D350FC3ED4FABE2DFCEE4956B8
-:10CB60000C74A4C3F1D457D1F5411BCA8F8908C7EF
-:10CB7000CAE919C3FBEB33132B553385BEF9AE0D50
-:10CB80009A48CE9F6A07BB5CE82F2F96E2396E94D5
-:10CB9000719ED3E4D4D2FD07C6A25C3B75F0258D0F
-:10CBA0002E39DD2FDDF5A145D5F443205C3E0F7015
-:10CBB0002EFC9236EF65AF44EF6FD9AEBF45EDEF77
-:10CBC00033C9FB539CFF679D66A642179F054D51D5
-:10CBD000E3191E4FE6FAEFC2BA63271D8DC77D41E8
-:10CBE0005C8C82EBAE5DE37D1BCF45D537CD74FE0B
-:10CBF000CF24CFA75628AF8D8D51D08F571B378F9D
-:10CC000029617ABC2E024E92AB94CEEFA4E4D242BC
-:10CC1000BEA70B18CE7FCD4010E1F306BD9B857AF1
-:10CC2000E983719F98719D7F8DB023FF2AB1B5690B
-:10CC3000D0DF5F55C153A344DB1F18FBF7AD36317E
-:10CC400025ACFFA5D69E0F703EEC5FED0CED32D308
-:10CC5000AB7601E5C9B26D66DA7F2D836D15C2ED45
-:10CC600093C7EC0115F29B7F5D7D07EAA5FFDC66AB
-:10CC700065781EF1DABE95DDAB502E3D2A30F4A367
-:10CC8000FFE74BD55FA25E5EB8155607F264BEA300
-:10CC9000E7496C3FFFB94C560BED3F178293703359
-:10CCA000DB9D129A84FB90EEDDE91E95FA797129DD
-:10CCB000F67BE63907F57BE65FDFA671CEFC6B2CD1
-:10CCC000E9357DFE606F2BE17A1CEC6DE5021F906B
-:10CCD000BD1D96877116639ED717BED1641ECABF4D
-:10CCE000C59802DD2FDE1FEF45FF4A583DEA6799E0
-:10CCF000B5E7E71EDA7FAB1922ED9D4219C88F8B8D
-:10CD0000DB8DE37FA3C9BB65969E79BCBE3F83F3F1
-:10CD10006D27B573A668F4AA9547B6D7EBC7A40CE0
-:10CD20008BE887B75F6A6595D1F8204DEB7771FB8B
-:10CD3000D7A38CFD71BAED3F0EFF7EAFC0E340D8A4
-:10CD40001E3BC5A35558422313816F5FB0B005C881
-:10CD5000BF1571A1910930DECB9ADCAC88813C7C97
-:10CD6000CFD0E681F531CF6C5D6710AF4B5EB4D3A9
-:10CD700079CA9217DEFE12F1790A610C183B95D23E
-:10CD8000F9E5FD4007A71E333115ECB525D690FB1C
-:10CD900051D4537BAC6C07F2F7ABAF93DE3AFDBCDA
-:10CDA000551CEC9C7A4910A8C1D67F1D6A09CBAFEF
-:10CDB00074621C8E576CC37DC36153A006C6AE92CD
-:10CDC000BC6B9EC3F51D36D33EE3EC5C968FFBCA6D
-:10CDD000B32CC3A312FE95B725285FF97BB3102DA2
-:10CDE0003EC9DC0B427D02F041EFF54C8154EA1D57
-:10CDF0004EE94A4BE52894BB26191657407E02B2ED
-:10CE0000DBCDC91E361FD29589CC87F063CEEB2EC1
-:10CE1000F0D79F00A5CB1F51D2B0DD8F52CC34EF9D
-:10CE200045A9DEEB53483F3A65B22F343A55F7F146
-:10CE3000799E17623C35189FD37BDF9D08DFE51F85
-:10CE40000A4A783C43643C6895A4BCAD14D27A4944
-:10CE50001EE5C9310CE17A563B773F3B57894F08B5
-:10CE600093CBCDD532C98FC66A17A5EBAAF39942E9
-:10CE7000FE350FE54DDAFAAD052AC507214FE38FE0
-:10CE8000D559EA453B0FE784714126A78FE8C8EAE8
-:10CE9000AA24DF94CDC9681F6B72AA6C3EA46627D2
-:10CEA000878FC9594AF0B16879A97506C113DAD3D9
-:10CEB000F7AB537D77233C6C59971AE4922579BCE4
-:10CEC00021DF0F5E3AFE77FF4FC18D119C1AAB6DCB
-:10CED00094AEAB2E2278D5577B29FFBF00B7D694EE
-:10CEE0008908B7294CB185C3ADC4901F106E8F005F
-:10CEF000DF2487F30DC011F986C5787646597F6423
-:10CF00008AF11028A81FAC6EA554FF9E3880DE3E23
-:10CF10009F2268F1B0BE1A338E23737F0B4B565994
-:10CF2000D6A43EFF2673A94CC13CF22AE2E5680C68
-:10CF3000C16EF9FB76F21B9B64A93B5CAE2DBF4131
-:10CF40004943F965AA7A9C9D088B4733CD28B52BB8
-:10CF500004570F9D53D66A7AB3FE02FE8C7CD05CD8
-:10CF6000AD50BA5EE3878D1A3F6C423C631C8987E3
-:10CF70009F6BB64C67A417FF0FE4F93E3EC4C2E3B3
-:10CF800046123CC19019F04D3252A13444F1BF47D2
-:10CF9000AD8111B9143FE545FA4838BA8AFCC78C0F
-:10CFA000055DE84F4BD0E0C65E1996302B9696672C
-:10CFB000E67A879978EA37A33D1E09D75ACF411BF5
-:10CFC000EEAF079A4FF1070B051CEFFC2C42134BF9
-:10CFD000BE3D78B41CCF4F5B1CA457533D9539E838
-:10CFE000DF63C7AC449F4E8F4F981F86BFD401ECC0
-:10CFF000BA55A9D77E8C7CDB8DB20CE8F0C1D6E1A6
-:10D00000768473B339E84279D79CC0F587520650CD
-:10D01000B8ACAFDD9F3439185768E4775DBECA53AA
-:10D02000C71BE85797AB895719E95C97AB2FA570D9
-:10D030007B6D516AE9799C4F52EF56E2C348BACFF3
-:10D0400093A794F992510F304F13DA6B6833A21DF6
-:10D05000F7A110E0F4CEFD5367BB7277A09D03BB30
-:10D0600002922B2AF203E1A9E7B56F9231DE95CB4C
-:10D070008735B699365C6F03D0111B85FE6C850031
-:10D08000BC01E887D179A047E38F224A75FA74A7DB
-:10D09000E61AE2044D798744C4573DD811144F0C69
-:10D0A000FB3B278C271D986C437B4F327B0EA39C48
-:10D0B000EA891583A837EB9D336D5EF4DF241412E3
-:10D0C000DEBF8C2DCF192C6E09EC16F2DBCA4E0F89
-:10D0D0003B8EE330467E5B933C9EE13E71B7B333BB
-:10D0E00006F72DB1A9A2615E8B527DC353C3F263D3
-:10D0F00070740D5FD8ED6EAD9FC8F17E90AAF92DCA
-:10D10000B354E60D3BB7A8D2E95B51D95561FCBDDC
-:10D1100066C434867117917C3DA0DCDAF9FDE456D3
-:10D120006D4E80F0658E9417C920C79D94AAA28C7D
-:10D13000F3569AFF2581E8EA4A840373EEB86087C4
-:10D14000FC685814FA3A7A691AC56B5ED033B06B32
-:10D150002E203DB3B988DB239A9EE1FAE96C8B83DC
-:10D16000F4D3D9B995144775B6254D41BA3BB0E112
-:10D17000F2B1088F79BD8D4C81F9CDEF9D4CE982DC
-:10D18000D65F525ADEDA0644CE58CDFAF91B664114
-:10D19000BB138F98282EA83B30E14C15E4BB5BAC49
-:10D1A0000CE38EBBB7DE93837EF16E1807EDABEE1A
-:10D1B000AD2388BEBA016E946F30D6C7786113E094
-:10D1C000A59C313D68D38BF5E7BD6E6A8B662795CC
-:10D1D0006FB47AA39DEF5C286F8D6EB7D5E2AFE98F
-:10D1E000F85FE5288457F107AB7270BD3AFFAF4C8A
-:10D1F000047984F0FAC0CAA2F9E3AF4EBDBA227531
-:10D2000022A6DE159832676254FF5A1FFDF3714F54
-:10D210008860DF125E7C71371BFCACDC8F7942B317
-:10D220007F996D80F238ADBD1CBD7C49CBE7871E70
-:10D2300060787FA1B214895EDF4F9B18ECA705DCF4
-:10D24000FFDE4CF1D0FA7CC04E253A66800F942F59
-:10D2500073357F0FC0FD260B7C3FF1BA4940FAE8D9
-:10D26000A3275F1CDA2D42F30D6B7643F9DF0FF332
-:10D27000FDD9C2DE4D24EF84E6319B27C3F77B5EE8
-:10D2800037939CAF69BA7CE3ED80DF2FDE30517EAF
-:10D2900041AF9DEA9D7CC0B3F976A8D7F30733D997
-:10D2A000E15F1CBE9AE21E4F9A8D7E82A9699C8F17
-:10D2B0005FD2F8795E6F33D91F7AF9BC863916854B
-:10D2C000E874037D9F878736785F8195FD7B711EAB
-:10D2D0009EE730BAAFF0D2C3B75EBF86F4DA78B259
-:10D2E000F7E7AFB77AA2C54FBF94AA18E4CFFCAE58
-:10D2F00016EA97815D949CAAF5172647E6F7261152
-:10D300001F30596518673C4F932717E6B7D56C90C7
-:10D310002727EDD1FD20AFA7F27DD4BCDECB89BF9E
-:10D32000FAAFEF87F47D9E3E6E17E7C7BEF56C9EA1
-:10D330001C6D3D7DEB984AF54F26441FBF471BBF30
-:10D34000BB7A01F3825C2AB7423D278E7FCFDAA2F7
-:10D35000425C4742A210B6AEF9AD8B99376C5DF3D3
-:10D36000B7CEB69487F5DB8787E5FF5E2CF5E1A1A4
-:10D37000277509E161556AE931E49BF2E62BC62283
-:10D380003DCE6F6D24389F307BDC285F3F69BD2721
-:10D39000CE17759E8AC18F30BF55C30FD8BB85612C
-:10D3A000F8D1F112D9BEFBFDF95F3E80F2E7116EB4
-:10D3B000DC0C04AF7E78CB8D0EB7188D3EBB41DF01
-:10D3C000FA086ECA0B4791AED73B3C48D703C36FF0
-:10D3D00034F30D06BF01EC57B0774C69785F017DDF
-:10D3E000B4780ED9CAE96028B8F58DABD14171F493
-:10D3F000F514A5E97450C55460D8E396A1E8E07E21
-:10D40000A6DA0659C7053A78D84007459BD7131DB9
-:10D410007C8AF6CAA8FEF83F6E51E3A6E0B94F93A6
-:10D4200089CE958EC7A8A9B7F1FC3894C7C7E3FC8D
-:10D4300037E2398D9E5FB87344DCECB0713F690010
-:10D440003844815F51DA00F493A7B28249FF3CFA75
-:10D4500039618E7EBFEFEAD4E2A969A83FFCD1FD15
-:10D46000B57AAACB6B53BCF3C23E13F5E771E7B0B4
-:10D470002F0350DA9CEA9B8E745197F0F33B511EB8
-:10D480001C3F2E90BEAD797FE528D46B917602ECDF
-:10D490003F1BF0DC73A529D64F76A854B99DCE4129
-:10D4A0005589ED2CC47D4AE5968F46A0DFB08A529F
-:10D4B000A6D9A12B4D977A9AC82F5BF9149E930297
-:10D4C00091C8585F6295746E0A82B014F39B1DFC7C
-:10D4D000DCB54AB2C9D6B0B884E51ABFD45797FEB6
-:10D4E000F223F443DB5426A7627B2E3725C6EDAF2B
-:10D4F0007FE03CC3F4BDC5EC933DB80F155829F24D
-:10D500008559F2D1FD27B32B799C1A8687CA347EC0
-:10D51000DE6EEFE868C885F6F6BBFE20A31EB4C237
-:10D5200038E867B3654967C3FDD5E6E420DD6F627F
-:10D530007961DFC1AE721640DEE00780F90E621736
-:10D54000BE2C785C5F223DD67078142188207D67E0
-:10D55000EEF03694CB45529D09E38E66DD3582F2BE
-:10D560009BE77C33B22B0A3DCC7A655D27DA33B377
-:10D570005E499F83E707B39C233FC614B60BB618DA
-:10D5800068FF9AC0824D905E657B9CE2195FD3FC78
-:10D59000631D980FD38B1D1ABD819D337D0FA4B3DE
-:10D5A0006C7EF3DD057DFEB4C871376B7CDF610EE8
-:10D5B000A65C8A7400E3E03A7EF64AE0C7A0FAD996
-:10D5C000EDC1C00D63003F77B01E33C2D1C7643ACE
-:10D5D000F7D0FDBAE5CCA3E519ED4FDFAB30EF4056
-:10D5E0003A89ECEFF610EFEF671DD01FA4771CEE21
-:10D5F000F93754CBBEA03CCDC1C2FADBEF39E460B1
-:10D60000FDFB8B84B347B299D430B8028AC470B89A
-:10D61000F7836F7CD9756CECC07CD6076F3E8F4862
-:10D620007C7C8145C0A76D69DE5F23BFA969DEBD33
-:10D63000C8BF15B61EB70474732CD9B71FBF2F35DA
-:10D64000F97252011EA7B37DA352102E9DD1CF5F58
-:10D6500023F93BAFECF463C83777D4480CF1BC76C0
-:10D66000DF278F215F9E36031FC17EE0B5559FC423
-:10D6700022DD2C01060C97271F548D20FBE9ECDEE0
-:10D680005183DE1FF940F397746A7CA2AFF34E64B6
-:10D690004018EFCEBD0EDACFDC5965BAB0CF427A72
-:10D6A000BFB38AC78730A973ECAD06BBB36EC07E2B
-:10D6B000701F11D94F77B56F3BF1BDE49B8476F7AE
-:10D6C00089EA05DB51BE44CE73A4CB77228DF4DB0F
-:10D6D0006C43BCEDDC9685DBC3F950AF5F3B807CCF
-:10D6E000F58CD2CE016D7C3CA6FCA0D83989EE6BBE
-:10D6F000D28F3D64FB5008A387A1C6637957792F69
-:10D70000C805DC7FF944E64CEDDF5F643DBD7F5723
-:10D71000D595ECC4045C9FF7FFA5A50C3D7F8B8BD2
-:10D72000CFDFAEB5D3BFDB7D7E8676A1FDAB78B211
-:10D73000133CA3B8FFE11F9A5DC09CB05E6430FF4C
-:10D7400066EFFFC67A61608A17B66FB5468D2BCA41
-:10D7500074491C2FC143C5B628F3EBD75F48621745
-:10D7600053CF338AAF1FDD64E4EF1A1943FB9AF2FB
-:10D77000AA5ADA673782FC407D10399FE34D8F2A21
-:10D78000A807EC16BF827ED1C691A9B96BA01D482F
-:10D7900035F2FBD863FC8A14FE5DF307D9D7F81580
-:10D7A000DCDF368EC8A0EF7A7F8D0297B33A5F3404
-:10D7B000C2BEEF79F28B795C3331AEF4ADC0F45870
-:10D7C00068B7632D0B99DC8C1D74678CC67DAEBF6A
-:10D7D000DE42E77B8DF962FA5CC8C765DBC83FD6DD
-:10D7E00096109A85F76B554122FDEA4F50AE8D4554
-:10D7F000FFEE9AB44E947F07EFB6D07A9B27F3FBE7
-:10D800006AD6291FF9AFC4FE57300FEAD51DBDBF38
-:10D810006EC57702D4A3B09F45BF21760AF268C7D0
-:10D82000F4B376DCCFB930AE0EF0B1D51CA4796D6F
-:10D83000A9B152BF5BDA2C65D1F0F779BA44EB0A93
-:10D84000085D141F9CC4827684EB83D3676ECE83FD
-:10D8500076B9794CC6FD7C73C1596DBFE935F1F3DA
-:10D8600028DD8FC8ECDA79964D3BA7B285C7173E05
-:10D87000EADF4BFE43C78C204FA78BE47F8E9CC70B
-:10D880000A17A77BC7D4CEE9A8271C852213D0BFCF
-:10D8900099C7045C973C7D075DD2C8CD6703B43758
-:10D8A000517BD90BED0B797BF409C917D9BEC2C5E1
-:10D8B000E30CD7A31F0ACA03668F702DCC23708395
-:10D8C0002CA84A5FBD7A17D7AFDBA1FF10C9D100E2
-:10D8D000ADCB9D1F0C21BDB92B44C2D3FAA2E3747A
-:10D8E0002EF060A1EE47F5D03CB6D61C3980F6D7B5
-:10D8F000D67B19D9495B518642BBAD37B0003F4F4B
-:10D90000621928DFB62CB45C4FE7F905007F81D29D
-:10D91000A8F39E9D6E237CBB573F18C2FBFB311EB4
-:10D9200020D45C4AA3D66F4CE770DA620EA4A37FC2
-:10D930006420BA287371BFAABB4AB3AB98DF85785D
-:10D94000DDA0C187DD3A9EFB1724AF121EC7D5A705
-:10D950004FB81F03D64771AD497516D247E28CD038
-:10D960002C5C5762BE855D938BFCC5E1A68E117958
-:10D97000DC190BB4227FB65D924AF1A4EBC4800B94
-:10D98000FDCD6A8985CE930F1689B3F05D848D75C0
-:10D9900016F243409EF8C5EF1DD686FCE6985A5213
-:10D9A000B6A010DFB9B0C808DFDA02D98E745CEB1C
-:10D9B000156501F21B4AF5FB118CDE37186732D969
-:10D9C000F3A17C7BBA883E5AB65D1088DFEBBD259B
-:10D9D000FEE1F0BD5E4E16C2FD002FBBB8DD7B77C9
-:10D9E0004EE9CB2E4803DE07FDC3158E4B6912E3CB
-:10D9F000572CE02796851660CC4D5BFD934771BD93
-:10DA0000EBC7D9E8FE6CF60A7F19CE37F6128B8287
-:10DA100078DDD19B349AD6576751909F3709816B37
-:10DA200091EFB7DE7D4845BFBAFD6327C60E336769
-:10DA3000D7DFAA317ECC59688938C76222CA717D86
-:10DA40005CE75B21A2A72EC1F79758F2FF1434E5DB
-:10DA500027533CF32484E78629EFE6CF8B4217D087
-:10DA6000DE993A1EED653134692CCA29AEC7982477
-:10DA7000A787E3775376C63BE867DA560CF3C7F11E
-:10DA8000AABA6FA779798FDC8F7695F3D8C9AFA33F
-:10DA9000CFF34DD223B1C71C21712CA64B66907DCC
-:10DAA000165E0FE4FEC61CEFC72EA09BDD355CEEB4
-:10DAB000B7DCC5E83D0AFCC90F836F4B014869FE1E
-:10DAC000048D42F50A64F2A3AF13956008E139D6DC
-:10DAD00046F494C67C24D722D7EB38D67837C61DB7
-:10DAE000393CC679F66AFC8D3F522A9D57A025CA5B
-:10DAF0002CE973ED28FFF68C57D271BFFD6042749C
-:10DB00003DFF5E3A6FBF5B886E9F9F4BB7737D0989
-:10DB1000B232348950C528AE0FF2622A9DDB909351
-:10DB2000DB2A72B9C0AE63A4F7E2C675D93D61E3E2
-:10DB3000ED49EF9B27C61FC46BED98DC13AA81F556
-:10DB4000B701D5E27DEEB86C0E47A7DA0747AC2FD8
-:10DB50006BEB023EA81955884094A93E2BB5D0B96D
-:10DB6000084843F51BB10F0EB15AFD2D459280EFC9
-:10DB7000900C036008503F61BAC5708E22D71D51CA
-:10DB8000B1FC7E1353128BFAC67F6C1C0BAC81F177
-:10DB9000E3BD4678C7AE786125DAE591748033B885
-:10DBA000D02F868ACF35B64BBDBD1F1F103C699E56
-:10DBB000009A96B7D80E0B00A5A55DD2E36349FE87
-:10DBC0004E3475AAE80FC580A47D30FF4B9F7ECBF5
-:10DBD000BB0BF22D3ECE67B1F92FAC44BA4CC8E076
-:10DBE000787A077DCB00E74799FC778CDB51AB4413
-:10DBF00005F1B12D348CF47823934A114F8D95475C
-:10DC00004494EBCD7B99471090FEFFCB1A3EBFDBCF
-:10DC1000D2F9390D9314927F929BDF1B6D2E101D4C
-:10DC2000285F0FDEFD02E9BDC70E880CF9BFE4775F
-:10DC3000C71EC1F7815ADEB152BEE5F54A921B3FBD
-:10DC400087766A14FFF9507A39B27EDE921D029E01
-:10DC50004FE42C08BE3E12E5B35FF25C83F858D067
-:10DC600049EF872885FC9CCD392344EF8728A8D528
-:10DC7000C02655FC5ADAC2CBD9AD89B48F1A63EDF0
-:10DC80006AB80EE6F7E8D312437D69B206D3E743DC
-:10DC9000BFA6179DA809FAED8F1E9D114A47391E90
-:10DCA000534961D0FDE677229DCB59F70CE5F72368
-:10DCB000A1DF84A91C96767FDA0194976833E3BDCF
-:10DCC0000A87CAF5DC0629E0C538EF0D2B7C161C47
-:10DCD0009F69FB97C625E54F229C4F6A7A8F552E88
-:10DCE000A0774CDC1ABF38AA5871B47D56AB2B868E
-:10DCF000C7B73C201E40FE707B19E90FB92A181ADD
-:10DD0000A5E9659CB8BCFAF946D42FCE0A91D6B1E4
-:10DD100041EAACC1772536AC60728DD2BFBFEFDA75
-:10DD2000BE2ADD4AF36F451CA7F4AD835C7220DF89
-:10DD3000DC0BA2AFE3611C7762DF3A62F475E47733
-:10DD4000515E9FC7766FF0A2E6B1595BC7A6749982
-:10DD5000524701681A677F79BFC6F101BD2B1300D6
-:10DD60005BDD44F7D182D7615E794E64FCBE96914B
-:10DD7000BFFBE535BA8AFCAEB0B0717291EE389E49
-:10DD800081EE34FB09F8CE86224054BE213F869FA7
-:10DD9000D61F498FFF74B9183E6FE83FB68109144A
-:10DDA0001757C19492F4FE72916972D1C6D410CA09
-:10DDB000BFFF69B9087290E4620BAC3409762AB1EE
-:10DDC0001D4D77A31ED7E5E144C4C914645FDB0D84
-:10DDD000254EDA1751FEB247FED082F191EB44EDA9
-:10DDE000BC4B830BBAA1102E5FBB14833E7D187F02
-:10DDF0008175ECE948BCBE00C6DB5C366C1CEE2FBE
-:10DE0000ECFE17C93E7017F0F81577153F3F77E421
-:10DE1000CD7B32FC5E5C653AB7D32B75FAABF2BBB7
-:10DE2000709C0DD82FCAE73C0BE9CB475990EB43C8
-:10DE3000CD3EDDE6D2FC241A5D45F249A47C9AF081
-:10DE400087E41294EFE98255C6FD1CEAE783A946F0
-:10DE50007D8DF4A2EBEBD6CE3509E80FCBD5FCFDDA
-:10DE6000B936639CC365195C9E99D3F93CD68995F4
-:10DE7000B4DF544B44DAC7E9F477418F47C031121D
-:10DE80007E48A86B27517C0CE5E38A7B18F2EF36BD
-:10DE900020597CE32D2E5DD1E2A6658273DBCFC4D1
-:10DEA000F1282FF77494DBD1BF2EB86DD7E2FE7046
-:10DEB000A3C04228373716BF4971254D55D0332CA2
-:10DEC000CA992FCEB68CED8F67E063DAAF3A546B08
-:10DED00027FAB582A11D14B7D01438348B713B9644
-:10DEE000615C4A53FE9A8C4528DFF34B0B11BF6DE2
-:10DEF000F5168A9B91F359543FC2E7B88F213AF93E
-:10DF0000767ACCA1EF2F2BA2EF2B4B33F8FE3628DD
-:10DF100081A882F964E58B1EE4FFAC3A4BD4795CAE
-:10DF2000A9E1293383DF0F6BAB3F944EEF668995F0
-:10DF3000013618BE60FA6B52C3F03179007CB874B8
-:10DF40007C483A3E1266131F76758A5CDE925EDB71
-:10DF5000C0E4DB503FAA9516B2631BCD7C5FBEA325
-:10DF600040E30BD9D686C4F66DE93A6E8948F7705E
-:10DF7000B28B44DA273A2A9EA7B8A64759CFEB2896
-:10DF8000EFD4027E7F3EB2FD1D19DC7F159414C1D3
-:10DF900043FB698E47C02BCD67EB88D4B6703E6DCE
-:10DFA000D5ECE8561787E3D6FA87894F2F769EBAC5
-:10DFB000DCAED5ECE8855E9F05D5812A944E4B47B3
-:10DFC000FDF9047F878A999C64977F8A4DC2FCB2D1
-:10DFD000ABB27C951961E743B2B752C47A57E3BB41
-:10DFE00042D0FE9320BF0FFA49F0D7C5F40E978FA9
-:10DFF00011332F649D023139C8D09D907749412A51
-:10E00000772D80B924D0ED48CADB6CA0176142A7F8
-:10E01000ABF9FD8B6E7C5F92DE9FE4EF4B7EAEBD75
-:10E020002739A6755DC9A3389E22F950667C86EF14
-:10E030004BE2FDE7A277292EFA14C8DAA6048C87F2
-:10E04000E1F7B7E5FB982C4EC6FCFA128C7BBEE7D5
-:10E0500055AB764FB2730DDE7B795C8475439B665E
-:10E0600009F4FD702C6A102AC3E878F7159D7178C1
-:10E07000CE773A78CBA0FE63BC3F48F3CDE078DAA8
-:10E08000E4584AF7CBE639436E6C7F60CF534F6E4E
-:10E0900081F13EDF67A3F74C363B96BAB1FCF347FC
-:10E0A000DE76A3BE38BDEF6D4BB4F3C92552701AAE
-:10E0B000DE23AB50E3D91A987F7170B685E24F76B4
-:10E0C0001DA0FB694B649F05FBAF68DD43F9AB7690
-:10E0D000FDD98DE5EF67703D713ADDE746BF445EDF
-:10E0E000AB352482FED93DCCBF28EA397B86A8CD4A
-:10E0F000FB55EA7FB3E3D5438897D38F58C9EF76B2
-:10E10000E091DF51BFA7F6BD48F3FD7CF7DB77A0B8
-:10E110003D5DC19807E5F969BBE6D7B375C685EFE4
-:10E120006F5FD5E0A1E74FC76AFBE0AC21EA69E782
-:10E1300031CC09F0A7FB039D7178BFF073B3CF8298
-:10E14000F0588CF080B418E080727F7150A0792E66
-:10E150006E6DA3FB568BF772FFE0628017C1A5F5C9
-:10E1600000CDFF5806971BA7F6FDC54DEF52ECB545
-:10E17000D2FE595FF762A7CF8DF0D1D70B70E0EBDD
-:10E18000DE7D71789AA7E3A9F5CF34AF8ABD7C5EB6
-:10E1900015BBF83CE6ED053C39114FB309FFA7F676
-:10E1A0003105EFC174EF79FB33B4674EEFB32968E3
-:10E1B00057E8F3CA02711B371EF988EB63B6572084
-:10E1C0007DCCA44E3ACF5922CB32BE4F70A13C60D9
-:10E1D000097079DA599209E5CF3C24D2FB964C0EAE
-:10E1E0005E8AFED53319FAF946A71BFD62BBAFF074
-:10E1F000137D9E8CD5E02D75BA317E6673A6EF4CEB
-:10E2000038BF9FFEF0C54B71DD2B4D95BFCBC6715E
-:10E210009EE2F1A1E78755FEF5019AF770C3796395
-:10E22000640A708BC3F3EF7C91F9E85EF2DED7628B
-:10E23000C2CFA14D99DCEFB6D9F101DD473C8DEF9E
-:10E240003CD27C8214A735D25BEEC673BE93CCE978
-:10E25000C373D9CF9F788DE26DBAD375FF5327D59D
-:10E260003BB5F7B5444CCBB5787816B885E418C003
-:10E27000B1C1363E9A7CD4EE1705F8BDB133020821
-:10E280004CD4138FE970AEB4CC349CEB70399AB592
-:10E2900035B783FC2D81E8F7CD22E56FDE4393E9A6
-:10E2A0005CF91C8B7EAECCB438B995A6188ABFD960
-:10E2B000ECF805DDBFAD52AD32DE5F39AEC9C58FBA
-:10E2C000B4F716CEC7C4A922D0CD4B99BEE199139D
-:10E2D000FBDFC32D6F5EE246F896E3B9076D6A7601
-:10E2E000DC807189140F3A85B46D88E067D6CB5B0A
-:10E2F000797902CF4FC9DCB31EDFC344F8723BF516
-:10E30000495E9ECBCB7FA295CFCF281D9F49FA8532
-:10E31000D13B4560912574DBB80A8F068F3EB84823
-:10E32000AC5BB7ABA1F2C24CC6E336324AA7E27A85
-:10E33000A058E07CFFFDFA03BCABB6C4FF867E6C40
-:10E34000FF5DFD04492F893E7CE30ABE79B8FE7B60
-:10E35000BC84C94D09DFBFFFEFDA7EA5C92B9E44FF
-:10E360003A8C1789EE75BEEE7E64D438DCFF5B1AFA
-:10E37000EE0EA1DAEC8E2DB1A4C3F7730A3F3FB9BC
-:10E38000EBA14D86F755F534F21D5BFD1CCF32DC59
-:10E39000783EDB92C9E5514B669FFF0DCFE546E223
-:10E3A0002F0ACFB7A452280CB7D359A588F187F903
-:10E3B0001D367AC7F712068202E63F9A8544D4DFFB
-:10E3C000635817E57F802080FC38A698303F81F5A0
-:10E3D000B8A5E178FE1C5A8B76DAB1645F13D2D906
-:10E3E000978F747E2040F9CF337CBFE982EFEB3307
-:10E3F000F93EC8096621D2B38C29D0A1E898E18AF8
-:10E4000026F72FC053964E859FB7DD2C791F223AF1
-:10E41000665972B7A30FCEBA3C58A4BDBBA4B7FFD0
-:10E42000ECE9A786D17B437DEF850F7A1F785ED517
-:10E43000C2879E983048B9266777D7046E0BD7F706
-:10E44000ED1A9C9FC9D4F5805FD70764C7FDEA66C3
-:10E450006E3FEDBEC2BBE67194B7AD26DA4F9F6C3E
-:10E46000FD0BBDFB78AE94915D37D0B82723F07ECD
-:10E4700072E75319FCBC2360D0EF0B9F7CE9D2F00C
-:10E48000784B00B3923C89BFC341783FE451AD263D
-:10E49000A4D252F2C75858258F53C1F90EC777B886
-:10E4A00082943A5927A571AC875299C9E49F4E646A
-:10E4B0001E4A935929A5A9AC52E0F69D9FD20C168D
-:10E4C000A4340BED53F4F7B01E4A15BCF11916BF76
-:10E4D000310C4F4C87E37BBCA5FC7B447C9084785B
-:10E4E0009C10459E47C40549ED5524CF312E684404
-:10E4F00072FFF71474F9BD39B3E43D94A72F657A20
-:10E500008F617AF8D9DFF3FB15EB05B2AF4FD8670F
-:10E51000581440DD33895E7A07441559E94ED0EF2F
-:10E520007375FF3FFEE871C208CC16F3A9F0F81D21
-:10E530006673E6E379F11CADEA1CED1C648EE60718
-:10E54000C1F7CDF83D3D0FDDB79FA39D3FCC89F0CE
-:10E55000BF30BFD5E04751F11758C71CBF40E70691
-:10E56000736266BCDAC506A693B0FEE8DE5F798406
-:10E570001F6A487F56447E6E647B9BC06CA9F89DE1
-:10E58000D3D3333F54C8AED3FD5940700AB56BB0F6
-:10E590007E487E21FFD5DE70382565F17DABDD7FBD
-:10E5A0004D5CB47797F4742ED867E6C4FEED6147EE
-:10E5B00098807CAFCB619DCE7371638B7C946F0927
-:10E5C0000C1697AABF77DDF4809FE1BCEDA155F44E
-:10E5D0004EF5BDD92AF96A6D0501BA1F10931F7057
-:10E5E000A951E6D784EF3A037F35C51ACF4D966718
-:10E5F00071FE5F9EC5CFB50F5D925A82E7D9EB14CD
-:10E6000091EE0DAF53F8DF2D589735D43BE536C367
-:10E610003DF9B549DBE81D20FB57DB19DA93762974
-:10E62000FABD94DBB4F13769F537276D233F49C351
-:10E63000087EBE1F59FFC08887E9DDC7C65CD8EFDA
-:10E6400062FA804AFDD78F78B80CDBDB428D86FBFF
-:10E65000BCB3B3F8BEDAB697D3A329CF121886F4A9
-:10E6600020F929BE40AFD738C079D28D595C2E36FB
-:10E670009903744FA649B3879667C56D407B675D64
-:10E68000D68EA3C8AFE7F2189D37DA434FD339824D
-:10E690002DDFC2EC82F6770230BEA32048F8416736
-:10E6A00053C840B7317DEF6C98FAF75FF78DDF857F
-:10E6B000EB6BCCF5D3F843ADF74A8D4E1B35FDDA45
-:10E6C00068379EA35568F0BE5E5B97ED1546F26411
-:10E6D00010B890BD77E3D61137A27FCAB67F48380D
-:10E6E0001AEAE7B2B2F868FC1229FF9D0562C43B42
-:10E6F0004A02CDEBDC5E417B6F91BF63D1670704BB
-:10E700002DD8EFBF6D2D3F782DCC6791CFE9C5F89F
-:10E71000C9A7B6EEA07BFA8B5F34537CC2C8AED9D2
-:10E720005C0EB6F27712F5F78D2E69B51ADE9B5A9C
-:10E73000C2C2DE5184F1161F3B798CD13D63E37771
-:10E74000FDDD8066FC10254E2DF2DD8187B222DFD3
-:10E7500023D3DE1D2888EEA7897C7760575024BD1F
-:10E76000B11CE358691FB0AD04F73D55C704F21B57
-:10E77000F4E743E5B13C73585EF0103DAAB131DED9
-:10E780009D51F8E9BD6C4E2FBBF1508DECFEEA0DAA
-:10E79000A12C4CEB189E37D5AE90643CD7AE0DC47F
-:10E7A000D0FD925A590C60DC48766C890DFD8F2C97
-:10E7B0004194F11EDA34D354BAF764B9579A40EF52
-:10E7C000B3EE58D489F7EA6A5D12433ECE4EE0714B
-:10E7D000042C5DA4F769EAE43713E6E03ECEC9EF06
-:10E7E000E9E5C82CA00868D779199E2FC366A53221
-:10E7F00004A657B6E00DE17B576CB255DEC9DF9930
-:10E80000B971DC24F203D3CF81B669A1DFE2385EAF
-:10E810005B29E2FFAA7B93C91E0CB84C0CE3003FB6
-:10E82000CDE2E78296D892D0FB38BF590EF2ED06C2
-:10E83000543111F1F07ADBDA99D7C0777340A278BE
-:10E8400087FCAF6B6FBB06DAF7B459E8BE850E27BD
-:10E85000A54E32BCDFE05E6DCC5B22DEAB9058583B
-:10E8600039E4DFC179905D55C642E171BCC95E7E75
-:10E87000E82E3B894EBA813FE9FC43CBBF8779A0A4
-:10E88000D776B39FF0DEFEBE40FED5836DF37248AF
-:10E890005E3A966EC7BF635275949F630E249F9F26
-:10E8A000CE52F47712ECDA3B1576F47B45D2535D09
-:10E8B00035F3609CA12DD011331AF17BD8ECC1B097
-:10E8C000E67A4D3E4A4E2EC775BA894CEB23E8AF27
-:10E8D000DEECC9F743FDFAAF4DDABEF1F48D485FC7
-:10E8E00092ACD0BEDA9CC53C680E9B933B336498D7
-:10E8F000C7E8172D1EFC7B07D39E2B8847393FFAAC
-:10E90000B55924DF104E882FA9CAE2413BD95A9548
-:10E91000EC9126603D27D1E559A785EC21A9CAE1F4
-:10E9200027FBAB6D924B09937B6BAB658F64C6BFC6
-:10E930008F63A374ED00F23E27412C45BFAB45B376
-:10E9400097D3B475A5653B284DCDE6F273BBA4CE35
-:10E95000A4F77B816E30EEE6C06A4EDFCBD36DA4A8
-:10E960003797BF3E3C6D30FFE093D52E4F1E0076AB
-:10E97000DBEA72F2DB16AFFAA811E96E79AC4D460C
-:10E980003A34C58DDC3C15E9FEF766BAE7591B3B06
-:10E99000499913D69F29AEC885F030896A06D2738B
-:10E9A000C163C11BA5C94827EA16BCCF5F98DD7AB1
-:10E9B000A304F2A53D56CDC0F3B2A9D95B793E457B
-:10E9C000DD22209F6407783E5BCD10213F23FB09A9
-:10E9D0009E1FA16EC1FCADD9ED3C3F86EBA3DBB31E
-:10E9E00077DD88FAA8D6EC2943FFF4B330FF821113
-:10E9F000F87783787A870617BDFC79FC6EC6BF333B
-:10EA0000C4D3C8F217B476FB0728FF8D56FECA00A0
-:10EA1000FDBFAAB50B0DD0FEA0D6AE6380F687B4BD
-:10EA200076870728FFBD56FEC600FDFF516BD7391C
-:10EA300040FB37B5766F0DD0FE88D6EEE800E5EFE7
-:10EA40006AE5C722FAFF40ABDFA57D77C736BC8BEE
-:10EA5000F69A1BE415CA93FCD806F2776DAB2A240C
-:10EA6000FAAF9DC8F5BF4EEF6EED5EC0916C7E6E45
-:10EA700073249BDB01551A9D17AFCADB3815E9F0EB
-:10EA80000FFC9E22E88FA3780F575D25927F6FF9C8
-:10EA9000EBFC5D99E5AB243ADFB8A0F7B4F6FAFCDD
-:10EAA00003DA3CEBB4B4329BBF9791ABBA3C33C2B0
-:10EAB000F4A35936E66DC04F18FF5F97CCF54CFEB6
-:10EAC000AA92063C37A9053D83EBAB775A42E8FF93
-:10EAD000AA97252AAF4B2EF1E379BF2A4BA487EAE8
-:10EAE000931343F84E735D5DA1E1BDCF3A59A2F790
-:10EAF00063A484AB6C739C283766C8283FEB989C52
-:10EB0000584CE76AB04F437D525522A3DCC94D48AB
-:10EB10004E44B93C3787AFAB23B6DB8EF728A4074A
-:10EB2000447A2B60A42C11BFE7D5890105E6D121D9
-:10EB30002F27FFEBCE16ED4C91F1F3445DCEB7FFDE
-:10EB4000621AE9B15AD0630AE931163F2EB5EFFED9
-:10EB5000A6746CB405F5969C61626690CBBFCB4EF3
-:10EB6000A471773EC4F5D608D05BF8CEDAF642C67B
-:10EB7000DF7973D9C8AF5B2E315752981FF377D91D
-:10EB8000DC8E67A6191EDC678FC0F710C3E03BDC84
-:10EB90006FD45BB943E8AD9C2A909761F5AD2ED94F
-:10EBA000900F666BEF2A799807ED9B69CF6D257DF5
-:10EBB0007216F50943FDF2C798D1A85F408F5859E6
-:10EBC0007F39A8CB63DD6ED1E574ADA6376A23F437
-:10EBD000C6D072F7EFAF8F22FA140DEFD00C247F5E
-:10EBE000AB304E00E8DFEC1348AF30C947F7FB8786
-:10EBF000829BD95C2ACBCEA1E1674EF92201E5B414
-:10EC0000D927793E8A724F6A28F8EAF52CB6CCC724
-:10EC100050AF7D716C653EFABDD69A3B67EF42BA44
-:10EC200015E2E97E87A2F91DB655EF672746603CDD
-:10EC3000FC7B5BEB26E0FD71AF4CFE92F41205DB32
-:10EC4000D9619F9E44761CDF6F32D9E75F84F6FC62
-:10EC50008B1605CF050E3FABBDDF90ED2478DEB3FC
-:10EC60006705B5330B952E7EDECF08DEEB3212F949
-:10EC7000DF0969B76976E3998DDE3CE857EC1250FD
-:10EC8000FFFC474EDB461BEA0F6D3FC058DB4DB81B
-:10EC9000FF09062C5A7DBCE8CED81E51D0FDCF5EB0
-:10ECA000C9156E875A6EBA2A0BCF43E5D112F49775
-:10ECB000B1CDBED17C05968B7A7B2F5E1E42F1A52D
-:10ECC000E725C0C3331D5AB99AB6F12A98CF1E8BD7
-:10ECD0003E3E18D445389EA8D193BC11FBDF5DA2FF
-:10ECE000B7EFD9E89D4AF3B9DE047BB07C77E646FE
-:10ECF000677ADF7C87E7E46EAC81B59F56BAE27035
-:10ED00001BB7A4EDA354D4DBEBCAF8FD616400F497
-:10ED10008FE8F7882FE06DEFCD2ABA62FFF3D03F7E
-:10ED2000E20AA06899A9EB9003E0B6647FA5CD2C18
-:10ED3000E2FB5DA52ABEDFA5B75BB27736D939CB3A
-:10ED40005E194769947687F1FECC776867B35CC437
-:10ED500078A7436F2EDDA5E0BD99CA06A789EA33DF
-:10ED6000EEFF8ABE3EBDFDE95D6FFE04C73BA374A6
-:10ED7000A55E07B5D785002E51DAE9F5F5FBD55329
-:10ED80005CDECBDCC07FFF70733E6452A507EB07EF
-:10ED90006D7EBAC76637FB4B519F002A0318A7A0A8
-:10EDA000A753DC79FC5DEC88EF91FC15B4B1A41994
-:10EDB000282F574874EE1EB4A98EB1906F817D4AFA
-:10EDC0000D4C69CDB823E3315EA0659F93E47AEDE5
-:10EDD0008A0E5701F295C7C2D0EE6DB9A2331DDF7E
-:10EDE000BFAFBBD752F604D26F68B9EBAE303B6C05
-:10EDF000780E8FABCF4EF097213FDA811F511F372E
-:10EE00009A7D367C37454D1729AEDA0EE56F50797D
-:10EE1000B656EE997E0DEDCB4419E7559F37777ABC
-:10EE200009EA355722FFFB8423AE2A9B0FE501D95F
-:10EE3000222379DD9D53EE43383D23792A91FF9EAD
-:10EE4000713A658CC7025949FA401A914CF15956EA
-:10EE5000EDBE53F638AEE7F57936B9B9FDD0E4B674
-:10EE6000101E5A623B6F2E867631F789B20AFD3743
-:10EE7000DEFB7029C6273E76EF913F637C6B53AA79
-:10EE800044EF0CECAE0979B15E8FC03A77801DB9C2
-:10EE9000BE6A6627EE47D73345417B7DB730D38FB7
-:10EEA000FAB92745623BA07E4C9E315ED559608CF5
-:10EEB00097CAAA30E637E6F8EEC7754DF8436131D8
-:10EEC0008E9322280A3E1D5CD8C9283E3F352F4F1D
-:10EED000C6B8EEB8C28838D8A9C67E12AF32962717
-:10EEE000CF8888DBBAD558EEBADD98CF986BCC7F47
-:10EEF000AED3A38B9F3FE87FE7E1B17B9F64A8A7D8
-:10EF00001BBF8AA778568423DAED3123250F9E8B09
-:10EF1000645B3A67611C1CBB3486ECA583EE18A6C3
-:10EF200040DEBA94913CB526060FE07ED52ACAA5EC
-:10EF30002A69A8E081F7A1DC01FB5594BF91F0CBD1
-:10EF4000CEE6FE416725FF7B7141294476847D55DD
-:10EF5000BC5CE3C1AD63841FB6222CCFE3BD1F7739
-:10EF6000F3F338BA774F477284575819E26D320B72
-:10EF7000E03B94D9F77EA486601EEB95BC4AB4337F
-:10EF8000D6895D348E5AEEF4E1BE3B05E3BC4D18E4
-:10EF9000EFAD521A898FE7DDDC4E52D85C3FE2D1EB
-:10EFA000355BA4F891FA43317578F852AFBDD7A01C
-:10EFB000C7B1E974F9B29BFBE7F67488A217FDE0CC
-:10EFC000B7E7ED407CEBF9565F721BC5F58FABECF4
-:10EFD00042BA6437703B14F400DDCBD6E3C4F4B816
-:10EFE000C2EE1C1EBF763A47BC80BF901E47141667
-:10EFF000074E4777263CBAF0CB78DE933DAE5446B9
-:10F0000039F34BFDFE05E3FDE2F385746E3043F406
-:10F010005EA2F9D3D1AE4BD2C64B4A96BCF4BE3BEE
-:10F02000CC4984FA0F315E3F296FEF4ABC77B507B0
-:10F030000907F9E72E0EE748BA4DEFF0978E4178B1
-:10F0400009A00FB3FAD3B1E06EA5F3C0FAFB58A242
-:10F05000755C7FBA9E68E2F64FCF4285E22C87A2AC
-:10F06000F393EE04EEC74ED922A37D9B91F7500D8A
-:10F07000DD83B98FC9A8EF323A3A6F46BF57243FB4
-:10F08000041C71E3799CDCB7F3C39B4C9C3F589AFA
-:10F0900044788B8C2F8D8C271D9E93A0F929400FCF
-:10F0A000C4E27D00F94A8C13EC59C5E89D809217A3
-:10F0B0005B6EFB77E8EFCB111619E575CE5BBEA74B
-:10F0C0001C30AF2F5FF2E5A09CDE2675D913C2FC81
-:10F0D0009E92C8EF9F45CAEBE139A246AFA0375CCC
-:10F0E000DF3DCD46FA06E20AE6A58E968108876FD7
-:10F0F000DFF4275BCAFFA0DDA2DAFCF8F746DD1DCE
-:10F100007A3E8BECB09CB778BE685BD6465542B869
-:10F110005590BFE860F63CF21749EF727FD1189323
-:10F12000378079F69E9DE2EEDAF7DDBE00E3D5EAA0
-:10F1300053AF53503F176AFB9FF139425478491639
-:10F14000AF0FF926F27B81065FC64A3F9D0DF81B83
-:10F15000F3B885E2EEF2C5F2865CE4874613E1B3CC
-:10F16000DCA42C6D0EDBA735A71697E44CA47D011B
-:10F17000F3C18641E915980FDF614A3E5E8CF49A2F
-:10F18000036C86F22547E506644E550CF385D1A93C
-:10F19000D22B51FDE6546F498E26F7F0DCC7ACB197
-:10F1A000F43389A56C36EA65F8867AD7BC2B869F3E
-:10F1B000F7241BEF479A4C3C5EE4266DDD663CD796
-:10F1C000198FEFBD8921EBD8FEF56FD5EA49366777
-:10F1D000C8148F7EB2378ED2BDCB887360DCDF520D
-:10F1E0005C4E05233F28C285F2F7C8FCDDEE2A1EDF
-:10F1F0000F50BB9A09781650ABDD5351EFE07F8F6B
-:10F200009879BD0ABEAF425B4C05FF0B11FFBA6C8B
-:10F210002C11EBA7B34E8A63641D4CE1F112C67347
-:10F22000A76D03BC03A5FB01A42A13ED5346BF66DB
-:10F23000E77F17AA8AD13BE1F46613EE7F57B380CC
-:10F2400024F4F9E18E642BD44E3F8FDDFDF50719D0
-:10F250002897F3C51DBE37C86E889577A07E8C3180
-:10F26000F2A17E7FAD56A3936DD532E15B2F77ABD4
-:10F27000C729DE3E87F5D4E03E2BA72AD180E70BD5
-:10F280007ED9DE4CE69B10DE6F80BFAB9B27D13B67
-:10F290005D4AAF9BCAB7552B43F43F6C80FED389C0
-:10F2A0009E06EE3F8BCAB787BE48B81140B1ADE7A6
-:10F2B000A38452A5CF6E8D84B37BB5517EFF607F52
-:10F2C000643C39878BDDEC4DBE19E0667F40F4B4B9
-:10F2D00031FC7B3CC67AD373CF25F0F372BD7E2818
-:10F2E000F916AC0FFBDE3605FFBE8FB17E69F1C7A4
-:10F2F00009FCDC5DAFCFE7F7A35E63BD48FC44CEFD
-:10F3000017E695F2E3B0795D69B31ACACB66F79B4D
-:10F3100057CA4FC3E6758DCB58DF57137D5ED7E7CD
-:10F320005B079D975EEFA6A28BAB17B98E5BA65BC2
-:10F3300007803BAFFFD3B28BEBF75F160C5EEFCECF
-:10F34000AAC871542E272CDE2328E7CA99B216DFEB
-:10F350000967CE98A871C1259A1D7316FD14180F60
-:10F3600097E97D1FE55A4F368F4B39FCEC223F9EC3
-:10F37000C32CDF6751F0BC235BF35B83E0598CFC4B
-:10F38000BBC72627603CA0CDAD68FBABCE5C8CE74D
-:10F39000DBD37EE436927BCC68CFC07EAD18F535EA
-:10F3A0008830BA97F126B64B098FA3F092FD572FFC
-:10F3B0007AFE42FBAA9FF07D951EBF1F6E67B14982
-:10F3C0007D76961EBFBD491BE7BF7286D17CC0CE3D
-:10F3D000A7BF7B9B9A27517CF32F6D9D9BF0FED19D
-:10F3E0002F939313703F73589BB76E37EAF71AD277
-:10F3F00066E78D334581D7FF0791B1925A008000AF
-:10F40000000000001F8B080000000000000BDD7DE5
-:10F410000B7C54D599F8B973EFBC9299C99D64F2ED
-:10F42000E211EEE4C5044298608801AD4C12A0A838
-:10F430002C3BC147412D0E893C227921A8A1B2F570
-:10F44000864484F8206840A0A043148A56ED6011D9
-:10F4500001C11DA2A6764B6DECF661A94B47602950
-:10F4600002C2A8BB487F7F2D7BBEEFDC9B99B99978
-:10F470005150B6DDDF9FFEECCDB9E79ED777BEF7E2
-:10F48000F79D33172FD27F93087928892C0C1413FA
-:10F49000FCC7951162CFCFEFE9741232BCD42B8E2A
-:10F4A000A3EFDFC9D111329E9087E983D07AB9509A
-:10F4B000F06FE3E8DF22212BCBE9F7D030979027DC
-:10F4C000C57EBB40EB9F7408A2CC413B09DBED7CC1
-:10F4D0004BA7F3380879EA8EFC1EDE19296FF03944
-:10F4E000B64279B88EF80216E8445C44E8FB9D26E3
-:10F4F000D1DE594A8B42BFB3C64ACB3B7E7F1B67E6
-:10F500002364C40882FDD5B55693635711B2DB104E
-:10F510007EF322CC673DE7DF46FB79ADBB74AA40A2
-:10F52000DBCF3B4988997E5AB7ECA6278FA71132CB
-:10F53000E1B85809EFEB36DBDD3C7DDFD4DF321577
-:10F54000C6212DC45DE0262493AFE4ADB49FCC4723
-:10F55000DE73B7D329AFEB95F6846839BC9573F7A2
-:10F560004850BFB87431C0C7E2912C74BD7361AA12
-:10F57000F8DE3E550FED6E32B83B683F67F4641617
-:10F58000C0F1A20257F539F70EA982D0F9CF0D2CA0
-:10F590009B8BE38A1464D9B46C12711E26494C6D9E
-:10F5A000A3E5CC2462328F23A47C85D8F7008C5F3E
-:10F5B0006F157B288C6D1562DF8F605D2D3922EF12
-:10F5C00086C1FD0807B5FF791EAF81D07147EF30C6
-:10F5D000D0CED83E5EA4FF8D09C496C7EE892D9784
-:10F5E0000663CB57BD135B7E5562F09E681ABAE581
-:10F5F000388577EF012381F92E3A9DE4375278EF71
-:10F60000D31302EB975F32223E542FB278003F4E65
-:10F610009F4ADA6AA4E5838793F0FBBB7F6266DFCB
-:10F62000EB022F43597E3999C0F78BD202E5A974BA
-:10F63000DEAF7FC9DFE92D66CBD243FF2F176DED1B
-:10F6400084FAAB02E5227DBF7B1421FD502FF84BDD
-:10F65000609DBBFFC663BFE1E78DFE1EDAEFE9BD2B
-:10F660003F7E19E075FAF9A1A91C9DF335BA9EAB4E
-:10F670003AA1BECD2AF5D0F7134FBF98E78BDA97A2
-:10F68000453B8C31EB5C2C71B8CE56C1B3E259D8F6
-:10F690009F437AC4A725F3FC7541DA7E0997E39668
-:10F6A000A11F03C5D36228BB33ED145F27DA18DE30
-:10F6B0002E31D3729C7D579FB51B78E2BB2A523EF8
-:10F6C000BAFAC7381FD7C9F711AFF7E9655D12C09D
-:10F6D0007135E7DE46E7BFCF6C2B2129F0CCF10373
-:10F6E000DEC81225BC745CD78F9A002F7EC5BB7B09
-:10F6F00048E2F15C597FDA3CF9AAAFA8A7E33A4B9C
-:10F700000839F751D29D1E3A8F911B62F7BDC81F71
-:10F710005B5EA5C0A79644BD77C27C725766219DEB
-:10F72000109C8FEBE407B739E97C8718490BC0457B
-:10F730003BEE5A651D2FBC40FB716137FC459EF5C1
-:10F740002765D07D51E8EA758ED111FDB77428A5E3
-:10F75000B7451CE32FEAFB459A79A8FD4F94189F03
-:10F760007218DC6B42B8FF4611F6FFD483D39E3C7F
-:10F77000AE1F3C9F130F7A3C93A3DECFDFB0B82FB0
-:10F780009BB66BD8993E8E8F826FC3F36F66DC4E4B
-:10F79000DF9FD921B8810536CCDEFEF844F8EE793A
-:10F7A0003E00F3857A0F5DEF99C0DB36F86EFE669A
-:10F7B000FB385E8AB45FB0618A67B22B02CFCBA5FB
-:10F7C000D3D72A189F5B14D0FB4D401781DF4D1D06
-:10F7D0000A78BA817317D071CA051F0F74672DF3A9
-:10F7E000E8E509844CFAE25FFB86D0FAE603E3CB56
-:10F7F0003B697DA7CE7BD33F01DD3DCDBBB7015D2E
-:10F80000FFF69E0C5FD4FEBC03FB4BF7A5F3D606B8
-:10F81000EC47A6B85140997AAFABB61ACA138B0918
-:10F8200067A4FCD8769278FC16188FBCAF4B25E401
-:10F83000E4FE874A041DF2A3DB814E4E139B1BE8B6
-:10F840006E9FB5E5DF71BC97F438DEA4600A07FC53
-:10F8500077DF739CBB93003C62E9EFE4C915B64ABD
-:10F8600046D7777A510EE88883F6B7F0D931C807C2
-:10F87000D4F7DAFDABF7C7F6A3C58B8F9475016A91
-:10F8800046E397F6BBB4E9B201E8B1A195CA8B286B
-:10F89000BA6938DE652096C1E3103280BF04F09764
-:10F8A000E2259170BD66E41BF41F67A2787B0AFE17
-:10F8B000CA636542C7BF9BC3A59145A30285C0E744
-:10F8C0003841ACEAC88EF05752E1473E7F86FED9F8
-:10F8D000E906BE103802F40EB2741BC817317876F0
-:10F8E00013D4CB233CC08F860092D227F96932F221
-:10F8F000DF3352683BB67F718C5BA6AFCF01BD583A
-:10F90000B09D2D358A3FB505DEB48568F9F4CEB4D7
-:10F910002ADE0678FB4B1BACF35420ADCA604BCCFF
-:10F9200037B47C93CE0CE1FB21FC49F14E747A9202
-:10F930009D00EF0E2A74419EA5B594B6C4D937B583
-:10F940009DC3D0522A01FFF8BEC5DDC3E0463CB4DA
-:10F95000FCE93B693DB0EFD7E8742817E672AC7F4D
-:10F96000B57D913311BF9666071D117EFD84228FF0
-:10F97000557EFD8495C1E372F9B5F639ADB328051E
-:10F98000E0F7299152403EA59AEA9E013D43AD7FA2
-:10F9900022811E50EA64FCE99D838529214BA4FD48
-:10F9A0009FF3BC6500B7ACAA7E0F4FE79F7503714C
-:10F9B000B7D3651DE3DDF789147FEE2254BEC3B3D0
-:10F9C000CC67003E483AD211BE84B8A7C2FE2F9839
-:10F9D0004EF1A59495411ED77B0DEE4EAA37D40962
-:10F9E0000C3FEA7670FE760AB2BB1E8DDDBFF9DDF4
-:10F9F000C6081EC3FF6D8EAAA7E3D40BFE95206731
-:10FA000087514D29AD82E2EF73B1DF2F22419C5720
-:10FA1000C38B178DF1F0E2BF15BCF8739E6706AC7F
-:10FA20008F9B69C2F92C7989437DC06108A0FE13C0
-:10FA30005E4CE5079D2FF92DC39BFFE4BDB8EEE6B4
-:10FA400065733D77D17D38D75AE7B98B56216B80E6
-:10FA5000FD0E307D6FD1E4401FF24122BE727B1655
-:10FA6000F4E74578501889DB101E028EF7DFBF657A
-:10FA7000F8749BA2375EA39B89EB0AD713B187F278
-:10FA8000B9892F1EC432FDD772FB4478B07EE6B729
-:10FA90001011E0BA80C8064269ED01A713F7AF9EC6
-:10FAA000F41B185DFBDB3368BB26AA6F025F8BA3D8
-:10FAB0003F7C3F1A1F0F6BF0F1F015C3C709884F49
-:10FAC0009F1137E2D36D1A7C3C9C001FDB07F0B11D
-:10FAD0001CF1596D4FF550624E1DFC3DE08B276ABD
-:10FAE0009F176E8E2D93E7A2CAB98017B41C852F7D
-:10FAF0004DBB2E1A3D71F064DD80BCF717D58C89A3
-:10FB0000E6136D38BF230A1EADBB657E36F0E935BE
-:10FB100060700C513AA800F946FFC27D234113EDF5
-:10FB20003FE9AA8132D697AF6065FFD65F7B375C2D
-:10FB30004BC87ABD2F5BA4F0AAE3BD7D3A902FF9A4
-:10FB4000BEE79C6057E83C3902EEABA7D03B0636D7
-:10FB500094E1E353E35A8A5AE2C04F9DFF7A2E1094
-:10FB6000D4019FDECBF4376B59581F2D5FDF703205
-:10FB70003994D21B427C0DBFCA11B02B36726BB3C5
-:10FB800001CF36664B5C3B5D53D9AEB64AC45FCA03
-:10FB9000EB0B28DE35EEFAB06F282D974DEB07F40E
-:10FBA000A3EBF62E7E1BF8E5F824669724B76CD5F8
-:10FBB000D1FE32EF748D6BA7F8F6A653C27192AEE8
-:10FBC000EA3A08FD84174B620FED276B85ECBCA762
-:10FBD00018C66F6943BCAF21F83EFD7BCBDBE0BBB1
-:10FBE000478690541EBE236D1C7CB7329DC3FD58C2
-:10FBF0003997CC7AA518A84844BD7ED82C916B9B28
-:10FC000000E5964AA41749B4FF321BA9AC2385DA54
-:10FC10002DEB6C04F975BA8EBFB3863ED78D63E5C4
-:10FC2000D4E59CA70789772DCE2FD348A671A9ECE0
-:10FC3000BDBF18598E6727D6FB71BF33AB5B4A61D6
-:10FC40001E9979ECE930F874F974FC43EFE9FD2B67
-:10FC5000E83A0F29F8B2746B5566B45C3B74C6245D
-:10FC6000E8A8DE7C284BB5178216B0179696566723
-:10FC700002F3C8CD9F9602FBEAC889AD3FA7F7A45F
-:10FC80005C05F2FB3D9EC0FEFD97C59302F4798DA5
-:10FC900081CD5FBBEF9F29FBD97C8123FE28BA6C05
-:10FCA0009E751EEDB0E60B42CCFB330F9A08A810F0
-:10FCB000037AC5C2DEA9F05D23E95F0978D8184848
-:10FCC00026FE28BAB82629FEB82A3D345FE0891CF2
-:10FCD000775C43ECFB0B69444E8BF75D46EC7BBADB
-:10FCE0008E98F29ECF07D601EF4945C8E6A576F873
-:10FCF00074D05368F99C5F27EBC7029B63FCEBACA5
-:10FD000018B201FFA2FA480BECCB592984FAC63984
-:10FD1000CA9AA01EE4780DECAF10B6CDB446C65119
-:10FD2000EBA17DF43E9E9D652041DC9F30CE03E03B
-:10FD3000278F2464D3FE4F0C12E869FB0F22FC547A
-:10FD40007C8986A31CC56F32DAFB833A4A5725B9F2
-:10FD5000196B8B8BE896F5AA7C216BAD87F2810C31
-:10FD60005E17C32792CB06F806B2A9753A5EE13357
-:10FD7000D96B275F1B5D66DF47DA0FA981FAB26294
-:10FD8000D6BE2277E87B2B40F6922E9C1F5D470E55
-:10FD9000C06FA06CD2942DB43C26AA2C6AEA1D9A9E
-:10FDA000FA2C4D7918FBFE8C359803FE81EADC11A4
-:10FDB0003502A5D333D9C1391C2D3FDAEEAC994CAD
-:10FDC000E9B4B18CE9174DFB39374722F06B723338
-:10FDD000BDDEE20E19EA8A010EFD7DC0571AF670EB
-:10FDE0002247E9C112D819C432B493A2DA05386C9B
-:10FDF000D710F810DB25ECDFA5433AEF741D65DF63
-:10FE000005FE827ACCC31D8BBDC0D8FAF48C6F512D
-:10FE100029E7194A1B36EDA9213E4B84BF9ECDF63A
-:10FE2000BC89FCF50027027D0EE029F46B89D085A2
-:10FE3000FAFD9FC6ECFF1DA849C94B3F6913E8F7BF
-:10FE4000FFD1F897F1A077FF499123EB397F118C0F
-:10FE5000BB89F88A408E7FBFB1E0A08E7E77441FB9
-:10FE6000DA02BCB73DF76A84DF116B683847F59258
-:10FE70008772AB6A040ABF23E9A12D00CFFFC8AD8A
-:10FE800066E5E1A1E13A5A5EDDD3C4CA05A12D5071
-:10FE90007EA567362B8F090DE769FB3CF93684FF99
-:10FEA00036313E5D2FCB65FAAC3ABF87CA3C4B7307
-:10FEB000418F6E60F267CEDD876703BF9DA323226B
-:10FEC000A17C7ADB99632F6DA3F0D8D69A4C7A186F
-:10FED0003A7A056A6F6432D4A772A20BF97AD8C94C
-:10FEE000F41BCAED42E0D74B1E6F923A9D917D51B3
-:10FEF000C7CF1CD5B213FACF9C538C72C4ECF41C40
-:10FF000081F1D5E7F451EC79245764FC9BD779F063
-:10FF1000FB07AC7EF87E8D99AD8BD20FEEB345D941
-:10FF20009735CABAD6E4323D63BA73CA91DCF1A000
-:10FF30009F28F6CEAA40FA283AAF6E8E04C06EA46F
-:10FF40007A8A6C063E5C9F84F64C37CC1DEAD766F5
-:10FF5000FB653ACEED1CF1027F51F949B7DD939D67
-:10FF60001A65377697D2B225E227E8AEF1642739D1
-:10FF7000E099A1031B4AE54FDD4ED64E954F99ED12
-:10FF80006C9CCC35453DB09E6481A0BC9B37ABB02A
-:10FF9000A70DF58399386FE2F16473B4BFE3F5B947
-:10FFA0003A80A3BA5FDBCB3C2FE0BA78E6F750F794
-:10FFB0004D85EF915CE6F7A8E3A97E41F1EEF17C77
-:10FFC0001FF647F58D1214EC8ABE710490767C04FE
-:10FFD000CE44088D87F7FF1FC2AB1FF0E9DBC2AB31
-:10FFE000B195F211DD25F011058EEBB9A03E93F12C
-:10FFF00011F44BC07B9047CF3B7DC773A3E861CE24
-:020000023000CC
-:10000000038DA867AAF34ABEFFB569DF234087A71F
-:1000100090EEE6FC2019FD085A3D50B503557D359C
-:10002000911DF8A9420F6ED5EFADCC23B938F4D2AB
-:1000300063145EA9C42A021F3D62088D71D3F6477E
-:1000400074BE675F83790FE145CA4306F5F7421E28
-:100050008FE39B553C2161DB2847044F56533C31CD
-:1000600041FB1A03DA25DD76FFC6F98027B70C734A
-:10007000CB12CA61A467B93519EBAFD11D25E0C712
-:100080000F4F1045D033295E617DF7EC42BFCCFCA9
-:1000900031B219FDD349FE1EC0BB520A00E86FF60B
-:1000A00028AC077F08FA91669BD87883F18AF92DEE
-:1000B000461256EF54F0B63E17F136A39D303F90EE
-:1000C000E029A989D217BE9FC7F022B92CF4EA1FF4
-:1000D00040FF7CD4EC2E20CC6405FF12E9CAC4FE9C
-:1000E00028BE8CC81BCFE438F47BD7E3D6AD8CEFA9
-:1000F000B9CB01CE0F5BBBC832F40FEA71FE9BCDCA
-:1001000041D4C37526C90E7EF8393C595F08FDB548
-:10011000EB45C0132DBC2BF312F91F42F746FB8BA6
-:10012000E71865630ED43F6846BB40B5FBE6A430D4
-:10013000BA52ED3ED5CFA11D47B5FBEED4D873031F
-:10014000F59D7F2DA8A5FDFD59C13377EF8582B9B7
-:1001500016B66EF03FD5C25F74DCDAE5E60FC1CFAC
-:100160005C2BEB83461BF091299E50949D4636B044
-:1001700075F87EA5F7039C5A05B27E3BEC8FCCD672
-:100180004FEDD8FAE8756D32B075C93FB0C6AC6BAB
-:10019000938DC591BEFDBA3E1A1FBBAE93E3957514
-:1001A0001153066DA7C8B93B5BAD1F7225F409EB6F
-:1001B000A24FB29CAECB1559D7B23CC64FE7287CB4
-:1001C0006C90DCCD637A7C1CBBFDFFC67ABB9EF2D3
-:1001D000C45BAF769D7FCEF3FC202F1DE9262896C9
-:1001E00045F0DAB791AEAB0CF635DDDF86FBCAF031
-:1001F00093109B1BF8D89279745DF06CCB447FE12F
-:100200001CA3B407FCE6E44729CA3A09F281251B7E
-:1002100087235D52BC6574FB14F3BF2C317BD17F07
-:10022000B364B1E8964558FF2B680787297F45BD21
-:10023000A43596AF7F3D1CCC39B5C5D17030E5CC27
-:100240002D8EB3EFB211F139D1BEFF990FDFCBE59F
-:1002500025F69790E5B17E0AF0E70E94F9C165ADF9
-:10026000DF8390BF1963BF9713E051E8FBD1787427
-:1002700044AFE0D13233CA1F158F8E5815BF900698
-:100280008F08D5A2818ED5756BE13807E018C72F8E
-:1002900044F1A900E07844B1CF283E15001C553A3E
-:1002A000B8B395F1032DDCFE9498AF7DBB7568F073
-:1002B000F8DBAE43AD4FB40E55BFDDC02DDE08F800
-:1002C000B9219B88EDA80787C6809DE430F88B6034
-:1002D0005E9B0C947E91AF303FE1678762FDCEDA82
-:1002E000F95CB8647EC1FA4DC42712E1E5E5FAF97C
-:1002F0006A35703BAAC06910BEE733B9A9F5F3357A
-:10030000DBC24F83DED49CC4E4F7D90356A47392B6
-:100310001F9A03F6C2B97D4602F2A0890B15C27777
-:100320006739CF5CFCAE2D590239AEFA738FED669A
-:10033000FE5C99507B9D961B7CCC1FDD2CFF7225AB
-:10034000C0E5629ED002F672F39E587F20DD0F1B3F
-:10035000ECCF591DE987EF9B787F3D98D8EB0D4C8A
-:100360007F59AF23018067C48F70B410ED9A6C91F0
-:1003700080FFAA49F761E13D517E8726A5BE298706
-:10038000F9D3203F01E32E309473305C9A1E3DFD7B
-:1003900025C4579B7669E93B96FE1B2265EE220732
-:1003A000FD45D53B23F48FFE03C08BC9C45FC081DC
-:1003B0001F909593A7F5FB21CFA159F13FA7F78691
-:1003C000A6827E632D0B10E0FBCD2799DD3471FFF3
-:1003D000D637C13F689FD63F1C54A866251EA5B5D9
-:1003E000D726EC5FCB833F4BB5B7A2FC67453363A1
-:1003F000FCA72BB01DF8E360BC10BC82B881C0F430
-:10040000F2F58A5E4EF577E4F3F3BA46A2FE0EFAF1
-:1004100035E849AA3F0FF426D09F77E757CDC8A704
-:10042000EB9C5D50757DFE78361EFA29C04934215B
-:1004300031DEAAF051BF03BFDE57C78514FD8FB070
-:1004400078D03DBF48FF4ABA5C949F307E7F7BB432
-:10045000FF7D9FC6FFBEEFCAC5833281AEEEE1A429
-:100460004CA0AB891AF9B62F811DB0247F201E94B1
-:100470000974ADB63FC1FB30FEA1C61DEA21CE8294
-:100480007226887189BB5B88BB13F3407C2BA1DC8F
-:10049000B890889D14DF1B26FB58FCA38588374E37
-:1004A000607156298ADE208E195D263B6839460E1A
-:1004B000F6631CA489F6B0C90D7E9AD8EF9B89BF5C
-:1004C0005A003CDE73D118D34F37DBD73B15FCDE27
-:1004D0006866F18389CBB7F224CA8F9332CEE37C6E
-:1004E00008E8F7177AF45FFFA7828F2A3CFE9C5733
-:1004F0007513E05512F8D5E0BB878CA8C71CD791BF
-:100500008580DF6BECE4CE99F479F641E2C9D7033C
-:100510001E8B39D1FE44F5D9B9CFBC10E8E219855C
-:10052000EFA9EF2BA051BA120F40FD3F19F3472856
-:10053000FB2F01BA29CF55ED0E520271880F157E9F
-:10054000DA74ABC507FD85748CAFBF98CFE4C08B60
-:10055000F906DC3FB53CE08F53E8828E83FD255DD4
-:100560004562E2D73F53F055F58713254EB7BE3E9F
-:1005700089D92903F4A943FE9B5CEC35F890FF551B
-:1005800021FF0D7F6491002ED34E37D4C33A3E9D98
-:10059000954420DFE62E254EFA6EBE1DFB55E38BFB
-:1005A000FF40BA8889935E2A5DFC3E421731715242
-:1005B0000AD764900BFB74CCAEDD47110BFD8201B2
-:1005C00025EE2E100FC8AD7DBB46A21D3357F15747
-:1005D00053BE81F66B98CA37B6DFBE8DF3E0BB40E1
-:1005E00001E6237CA8F73FBF1DF49903CC4E53F7D7
-:1005F00063DFBEA17EE03B134F7F9103F0DF77F214
-:1006000085A190E7B14F89AB37188285E84F31302B
-:10061000F9DE600B1602FC5E57F0A6218996E9FB15
-:10062000BC745F18F05ACD8B8176765C8F64037F43
-:10063000CE31C54E3F4AED769817A5967E88F7D302
-:10064000FDCE8672787526D3A7E9BC002F8E1D18C3
-:1006500083EB5BAF67782CEFE5D0FF73541F3ED17F
-:100660004ABF3F9A7D156913413E5FD8DE07FD3FC3
-:10067000CD13A30879479F9FDF43BF3F378417C13E
-:100680002F59A7F34ECD067EB19BF943B4FB00F280
-:100690003A3AAE7B968473D06FBA303700F87376EF
-:1006A0007F11E6D3118748645A6EDECBEC476D7E2E
-:1006B000C4717D2CFE6BFB857581FFB219FE067D32
-:1006C00024BA7D9CFEBEAE7C561F2A5C46E13145B5
-:1006D000F24905517E80E637B2518E1C7BEC73DC0B
-:1006E0004FD2C5E2E8C7F59E39303FFBE4A0A13602
-:1006F0000A1FAF2E50FC5046A65F50FE6B88E637AF
-:100700006A7D7915899B9F525EC0E8DCDACFE4F4FC
-:10071000E07A86E7F7926779E0175743320FED6F7B
-:10072000849267732FF9ECA011F4A94029E6F18CAB
-:10073000581E443E40E78BF8797C630AF247F22862
-:10074000C3D7F93F3222FF984FE507F367B0BC42A9
-:10075000F228CB1F3AF19013F1B97C45B01CE9C1E6
-:100760004EDCA047BDD6F1A1CCD3FAB93BB852C8F4
-:100770009B9CDBE1443BF0EE5D4EDCDF890A5FAF22
-:10078000337A304F923CC3E29C773D518FE334265D
-:10079000133B8FFAB5DF007AC4C21D1CC6C32706FF
-:1007A00018FF6F108207414FD7E6FD107F6CBE0126
-:1007B000C82312A5C783FC211ABB2B76DFE54BD2D9
-:1007C00017B472667141427DE1EFA4C77F337D614A
-:1007D0005981AAC7C7EA0B60FF17303C64726D27C6
-:1007E000C7F89CA22F3482BE00BAB022A75539BFE9
-:1007F0004091F32778A667CC37AEC5E79A0296E713
-:1008000070370929790E6103E87F89F0788D322FDE
-:10081000158FBB008FC747F0B8E164B0CF887E0763
-:10082000F76EC8D368584E82566AB7CF175A509E93
-:100830000D118988F9AFD53E9C57E6126AAF51BCBD
-:100840009C0FB1FC7197AFC70CD25B34FA8A3A6F38
-:1008500015AFB5FAF5C4E57E1EE28BBE9104DFABA1
-:100860004F91044A61BE352666DFD4982C411EFCA8
-:100870000F93F567A2EDCF1AC1F322E33BC3EC2738
-:1008800046234B23D0EF74A7E737A3D2237A7B729A
-:100890005978E563B43F3D29D1015F57C7373B2BFA
-:1008A0003F298638AFD08FF62BC962F92C478A19B9
-:1008B0005C93E93E6CA570D50B32C24F6F12ED6DA3
-:1008C00076D8FF7E8CD385D309FA6DD5FDDA622503
-:1008D00032E4151F2966787FA458C4276D8FF9006C
-:1008E0007A176D4FFBAFDA67463E727EAFD50FFACF
-:1008F00004959323ECB43EE34FD40EA4E5B3FBACD4
-:10090000A8579D55E49B43F5DF9395B8FFEF2A78F0
-:100910002393AAA160EF11EE86A174EE44B5431AA9
-:10092000ED89E2DA4ABDB3FF5686BF46D46FCEDB0F
-:1009300043F74199CE0773E0FA14BC6ADE555DFABD
-:1009400000C81BAFC5CDA0EE2B057DCDC82FBDD5F2
-:1009500044813D955F1E5E06783FDC221A6993C98B
-:10096000233EF8FD6C5AFE68979E18017FB6DD9411
-:100970001284668227CB3B66F07CEAFDFAA3A128AD
-:10098000BEB368476CB931105B6E26C2D15094BCBF
-:100990006AFDA0FED76F45E1DBB902AB03F08048EA
-:1009A000C47D91D2D3F107F7906320BBF93B52800D
-:1009B0009FDF45D9563C7AFFFCC185BF7E8B7E27E1
-:1009C00018AA3E2F40FD5232007DD5523D279E9DF4
-:1009D000BF4DE16B4663CBC9AD143EC6D78DEE3635
-:1009E000DAAAB7C0470AD3C13E0EF7C1BE1A479C68
-:1009F0002981F846D5882F30BFE4FCBF1037C0E905
-:100A0000BCB912F1E9FC46B3047E80EE1C0BF3CBBB
-:100A1000BFC1F9396617CE184FEDE9853815E0BB2F
-:100A2000E1951B41AE4C308A2B445CAE4987FB4DAF
-:100A3000AD63FAEC36C82BC1CFDE4D0DF43637D896
-:100A4000D1FD362086A98512CB9FE05F3498E89FC0
-:100A5000CE0E4F511BFD6E91378940DEACF0A5E004
-:100A6000053C7B18BA8AB22B8715323ED3680A1927
-:100A70002AE977CD5F2C9D96AE8BC47D8C7A9F67DB
-:100A8000289DB77E4F6970287DB5A0B51AED672AFD
-:100A90001F185F3CC0F8E2826595F89E9B390DD720
-:100AA0007B82AE17E0F2E64623AEF7C4700BFA3352
-:100AB0004E6CE1B0BC403460DE2DD5A7D22A1DF0CB
-:100AC0005E2F1AC96078346F7878E5465AFF6E3623
-:100AD0004F388AFF7FD9FC738C4FFD85B0F1E55DFF
-:100AE0003CEA697F11C3E54180A7D4628BB6D71772
-:100AF0006CE1BDC02F176CB9F7DD0900B799B79548
-:100B0000013C26D99766489648BDAA9F0AA915DBDD
-:100B1000812E277D59DD3F09F4C42D946EE8BC0574
-:100B20001DF181BDF4D696EFA27DB0A026C90EEBD3
-:100B300093366F9B0AF2F82F354374B8AE9738227C
-:100B4000023CECAD19F07E012778E3E1D5E1021E0D
-:100B5000F1AA7284C50DF271C1EF78C4174A67B764
-:100B6000425CA9718B1EED8FB7661EFEFD6C47843B
-:100B7000CEB8991B664C84EF7FACC7EF07F4BFCDAE
-:100B80001F7F007E17F84735119043083F2DDD1970
-:100B9000472C2F847969E96FC18A964296EF717963
-:100BA000744836333AF41572C8A7BF011D2E2CBC09
-:100BB0000C3A24C35263F48EC17C4F46BC55E3E526
-:100BC0002637F16CB3607E9487A3FC7A6DA180F523
-:100BD0006B0B999D29FCF59E1DBFA2704A2BF4FD5D
-:100BE000A010E42BF194827C96C26215B8E62D8A9F
-:100BF0009E4B36B3F318600FC1FEAF4F27DB3BA30C
-:100C0000FC5F8F417FE9C817DAA19FB37FFCA20F79
-:100C1000F6AB29E74C09D801CD17FE0BF36C2CFB82
-:100C2000597E96C51DC6BC35BDC38BF8A8F2FD66BE
-:100C3000379343DA755D28D4333EED08633F635C38
-:100C40008C3ED5F8F4A6D6248C136E72F8CDCC8FDA
-:100C500045F553DAFFF4321EF98CA9AC9D801C23B4
-:100C6000153CC6F7267DF16B02F1D077AFAD7683E8
-:100C70001E6C297B5348837556E895FA9FAECAA52A
-:100C8000F5BFBE760ADA73F764F112E853D3CBF2FC
-:100C900064949F1E96273FE98B14A4C319F5335023
-:100CA0000F56E7EB2526C942F1642625D6E8F30462
-:100CB00033AE354B9628FCFAB48B9BC6EC0029E585
-:100CC000E631CCEF162866F23C1A0EF7641970FC78
-:100CD000D905952F01BE4CBA8EEDC3A9978CFE1590
-:100CE00074DC53E6F8FADDFE42E647C815AE47BEAF
-:100CF000B4F42523E66B9CE6E27F7FF72A1EF3CC53
-:100D0000EA5771C44FC73BF5FC6B39C0D73FDAF6E1
-:100D10005A4E6DD47C12B5FF6361227F76F0AE68C7
-:100D2000FFC074038B139171C6187FFF749B721EF2
-:100D3000E612E35FFF9430EEF38B6130DF5F0DC4AA
-:100D40007DDE19161DFF1A8863BA59DC471BBFCC1C
-:100D5000AFF83765BEECFC41ABA0CCD76D6471AC8D
-:100D6000792C4F62C98134C4BBE986F0E318DF7C7B
-:100D70008317953897C784EDB3587D8275118F27F7
-:100D8000DF518EFE319C0FB7870B5A6DDF627D8479
-:100D9000C5B5B4EBABDDCFC78DD336BB585E48725B
-:100DA0007118EDC0A3EF3C0B991803F86EDEEFD479
-:100DB000459F5B19D06715FCBE09F09BAECFBC8A7E
-:100DC0009513E175227EF5A822B755FC3EBA2A2F6D
-:100DD00005F0ED215353A88FC2CFC3A710F3105ACB
-:100DE00056F241E40FACC88778052E4491835B3EF0
-:100DF000B0A27DD6AE6F7906CED9C96D02D946DFD5
-:100E00003B929AFC6DB42CE9AD9847777FD28CADBC
-:100E1000608786A882CBD1F2E74947B6829E404CD4
-:100E200029444FC791AB94F60693D84EF58BA79201
-:100E30006DC85F5AEF2228BF334990E32840DC2376
-:100E400073991F7CD16E0EF3E729C583DEE7CE8B45
-:100E5000AF8F168C64FCFB8F905045D7EBAE8EFFA6
-:100E60009D7BA4EAF7137CA128BBF461CE2D29F960
-:100E7000E404F265F5A47F36F265AAC7FF9ACA8337
-:100E8000A1FC2BE8FF3EF6A0EF9978E792D4E75D4E
-:100E9000D5F1FD0A1394715D5D9C5F6F43FAD56DCA
-:100EA0008DA15F25AE6BCD70530903F17C16B7CDD4
-:100EB00027EAF9940D10171952C1E668F38408E87F
-:100EC00017595DD7135F1AD0D3C44C906F4BE6C54A
-:100ED000DAB959B5ABB2D10F597BDF0C90DF1BF4F7
-:100EE00096555C0A3C63FD871B34FEC3AFE30B5988
-:100EF00009E9664216F8633644E2C1883FED73455E
-:100F00003FCFE12A48749E4346BBD4E7033DA8D2B5
-:100F1000E4EE710FA61F52E1CE8275BDA8EE9B4292
-:100F2000CFCD0A6A72FB39B44B07F343059E8DC3DC
-:100F3000109EE6AEFBD16E4A2E657EF7E4FA5A1F8C
-:100F4000F09F64CA7FC08E33185A38DCFF89CC6E9C
-:100F50005BC2B1F2924A5194E9F7069B923F7D033E
-:100F6000ADB7039C7CBE68BFC335BA7B2AA3F3B47C
-:100F70004542DB031F9EC5C69B6E5ACEF2C47D540C
-:100F800047CA8EC0B14A81637E45123B6771AF0983
-:100F9000FD719BCD5D385F9DC4ECECDA4E33F2BB46
-:100FA000A1BC0BE352BD7A861FB2D584F4EAEE7D74
-:100FB0001FF305875E9D25F1CE28FC59CAEA55BC72
-:100FC000209A3C138341EA037F239D881BF2949669
-:100FD00070525F15AE4B0CCB6E58B7C2974B9298C0
-:100FE0001CA1E66616832B8B3B6AF68BE20D8B0306
-:100FF0008CB1303F17F149A87769D63B186FF6BA24
-:1010000080DFF60EE0CD1E573C7EBBC62EF5F544C4
-:10101000E30B9156821FF8111D0977C6C31F77ACE9
-:101020009DAFCD9BD4DAFB4DADD55EC5FE904DB8DE
-:101030009F06B43F9A96557A99FDE16A037F59F36A
-:10104000722AA9689BEAFD9C09FA6B9E6543FBBB6B
-:1010500079CF4ECCA7689A46DC308D5AC59FADAE8D
-:10106000F3A89EC549A9CC0A403E47B73DF4349C3D
-:1010700083EDAE57F3BA589E93BC8753F2BAD43C73
-:10108000C0F011F0D7767312FA6D07CED3D2FD6798
-:10109000F95C979717682DF63AC112FF69C17FFC7A
-:1010A0002629FD32F2AAE582755F9D579D742BD4E7
-:1010B0009B602F947A4003AA2FAB658F59827CAE38
-:1010C00048BD40ED4ED31E8EB597D7DC3245C07378
-:1010D000704AF9F327E1BCEB1A3389192F7A7E8223
-:1010E000A67F302D2D92FAFD1F664EC9C73C48657C
-:1010F000FE154F7A86D1FEF4B1FD21CA28EDA1A0DC
-:101100008EF7C2E863DD8F0E8BE8ED548FFF6CE441
-:10111000F888FEFEF0E1E95D63E958C9E26778EE20
-:1011200050D5C39B1D2CCF5A8BE77F53E414B58752
-:10113000A7826AFDF0ACC55EE877200F72FF5C0FF6
-:10114000D8C16A1E64F3722F9E3FA47ABFCE057980
-:10115000D57F3C73E220013BF314FA039A2F08CCAD
-:101160004F4EED078EE28B69FF5AC41FB243EF0763
-:10117000D74EB75D26808FDD07B8F1805F84B4E479
-:10118000DC42617F9BCB9384FD25C83FC873313F10
-:1011900077B3AB6A6321C0FA398E803EDEE9FA1478
-:1011A000ED8AA6BD53C6479F97ADDFB38E9DBBDCCE
-:1011B000A18FBBEE3C17CB776CDAFB2AC67B4EF9CE
-:1011C00039A4B985827F35D89B0B17EAC0B2226556
-:1011D000FEB998374D661908CCDFACD821CD3B6EEF
-:1011E00092E1FC6E33FD8F9200D9E49D8FFAF6A652
-:1011F00059260BE40934BB6A1723BF13933C60CA1A
-:1012000069E739900FB92C09F3AA3AF7E8A7819D4D
-:10121000544EE9E26716E0ABEF39B702FF4C1BC74B
-:10122000B78B90771A5FFF2E1AC5E45007E795FF3A
-:10123000B90CE338243ABF7DC41E667F4D74196231
-:10124000FD932E66175E2BF75703AEBD218492C126
-:101250001E6E269E4FC0EF45BC1609E3582480FE43
-:1012600040C78312DA4D2647E891B1507FAD8076B2
-:1012700093EA4738BB3713F5B1975DBEEFC23E9690
-:10128000F3A127FF19E0F688A0C4C3185FC9B9C944
-:10129000320EEC2BBD83E93366AACFC0B9A1EB5661
-:1012A0001FFF6535F0568717F50842851CDCEF50A7
-:1012B0006DE2583C48A33713D13D19DA4F55FCD2A3
-:1012C0000574B74E9810353B2EA6813FC32103BC51
-:1012D000DFA10B48A3F55388A783ED0BDBBFF50611
-:1012E000A6AFAFD799505F57F5E164473FDA898DD4
-:1012F000010EC76974BD82E7471629E71406CE0BB5
-:1013000008213C3F51EB4A56E2B01D0C3F493FFAE1
-:10131000C3C88B6C1FA8E689E72A54B8ABE70CD486
-:10132000FE0C4A7CB751F1E75280317A74A9F1DDA5
-:1013300015CA533D07C2C62582541EED775C5F4334
-:10134000483FCE4BB2C17C1FC9F0DEE7A2DF1FA52C
-:10135000780C78767455B29F708047FD1E88D3C88C
-:10136000A52CFEA2C5A7475C9C72CE2C3C15F3F0C1
-:10137000F6263867B627F69C19E50F8BDFA6E394AF
-:10138000951D76037EAFB12BEDAF2778BE407BCEA7
-:10139000AC4BD987FF73E7CCDC9CA7873EB7BAEC90
-:1013A000B1E7CCDC6CBFD43C19EDF9B2B3D94181C3
-:1013B0009D07093DBD0DE5A511EDC2D73FEEEB0040
-:1013C0003FF3B952831BCED564DCF64E07E62B7192
-:1013D000420BC44FB5FAC0EF9CD53F01FA5977CB09
-:1013E0006E37E68F6BF481447E008CED46F9890EF2
-:1013F000B8AEAC1FC0DCF5B90DF0ED34177E1CF2B1
-:101400009AE5037CDCBCE60F5C89E2629E59D1FA66
-:1014100069879AFF674F8AC987ED4890FF9748EF21
-:101420001712E6FD5D8FFA5BC740DEDF34557F8B18
-:10143000CD6B1693BED25E56C79F1672C6E4117C62
-:1014400072C9EB54EC9804EB4B64B75D6E5E841686
-:101450000E1D09E4E85F5D03F13F4D5E8447843C67
-:10146000820EC823A04F812332FACF760EE44504C2
-:10147000D15FFCEA48F47B1913E645B0FC3EE1C0BD
-:101480004809BE7B58EFF5803D23EFD42B72C0FF97
-:101490003CF84D3A0E64A39F8DB84225C01F05FB52
-:1014A000D42CD0AB3A14FC6CB8F4BC88B4A2387914
-:1014B000115BFDE31ECF65F6737F32D5CBB61226E6
-:1014C000A7E4FDCCAF49E78D7EBDF063C3515FE576
-:1014D000669A701DC7DE30F618510F77639E436D14
-:1014E000162F827CE9AE293F01F2EB18555C818E04
-:1014F000EBEE5E8EF66BA2FDA95B151B7756DF5FE8
-:10150000EA3E8D2B62FB7414EC7B14B432FA8B1719
-:10151000AEE20E62FEB626EE5D56441439119BC74C
-:1015200070DE5C89F1D8FB9EA8C138EC7CD282CFFA
-:1015300085A44B89CBB2788BB44A403921EDE0FCCD
-:10154000929391890E6D7B5187F7F550F1B609445E
-:10155000A24CA9E66AFA9AD371A0A74A1DB49C4985
-:10156000D7B55A90B3E8775BDF4F46FFEBC30E4920
-:101570003957C3EC2FF9510EF53FDA2FDACF720746
-:10158000C51BDACFCD452C2ED050C4FCC91445FC68
-:10159000381FE5D9A1E47DA8E3B5115D109E3A8E10
-:1015A0003D1F168569F1F43BB5BF0E7D8B09E22D19
-:1015B000E1E13A8C679E377866613C30B59080BD3A
-:1015C000D8616D59358DD5230F3D6F0E7BB1FE3B34
-:1015D00002331488940AF3BD41D90FEDBECEEB8AD5
-:1015E0002D6BF313B4F77ED411DFC8ECBCC1F760E8
-:1015F000DC50C4E4E1F94EA7B22F6E8C9777E8A5D2
-:10160000DF38413EAE16500EB70D6370D30D67CF75
-:101610005CFBE4592887ED543FC5F9B2F9E77EC772
-:10162000C101FD75D8197E7DDB796BE7BBB4A810CD
-:10163000F7AD038C063A5EC76ACECFE0C5E67DA95A
-:10164000FEEA278AAEAC9C3AC6B9B70701CF2CFE9A
-:101650001F81DFAFAECD28023F3BCD29F4BF9A47B3
-:101660007EB669612A968FAE2A403FD000DD9E5C2F
-:10167000B918EE33B9D47C8AE714BC7857E387AB4A
-:10168000ADE0DE837EB47007841254F9439B56DFCD
-:10169000543C15F863938E4899A00FACD2E4B3681C
-:1016A000E8798AE47BA508EC0F437F1FE353A1424E
-:1016B00001F56FB31BE0B64E776CE7CF015F769A0A
-:1016C000313FB26979783BF82B3325DF5E68776666
-:1016D000D9E1A99C84DDA19E74EEC048BC1FA7B6C9
-:1016E00043738FC7A3B1793464552ACBFBE88E7D51
-:1016F0000FF737C4B41B945FC3F4D6F5065F11D857
-:101700001793AE6379891FD7EB08E0C5C766863F9C
-:10171000F2635645CEB80BA3F5DADF6BF1E3313354
-:10172000E2479D72EE4DBB1F8D801F74DF1A14FCC3
-:10173000F8F8D5AB0B013FCEECBCBA10F063BDBEE0
-:10174000CB03F4B53BDF7718E0717C8AB74FC7F85D
-:1017500052E1E5E0ED4757186F2F55BF328D4A141F
-:101760006F91EE888EB7F4EA999F4C36C79E1BEBBB
-:10177000BD4CBF6A62FF58517EAC7FCC951F57BFEE
-:101780003299BF52BFBAFC75103C37A8C6617AAD1A
-:10179000E1C7B747C16B8999E5A32C291245B91454
-:1017A000D6579B87E710FF6872F77057749D317E9C
-:1017B000C037BEC85BD905F3F030BFE51B82D477D4
-:1017C0000D1DF70DC2FC96DA75DFA8C46154BB5B32
-:1017D000B503B5E3978C627AE6A4519E52B00B260E
-:1017E0007D7111FD0827E11E2C3AAEC9FF33B4E725
-:1017F000C87E4EC4738C128B8336ED9DF72CF85D3A
-:10180000EBFD4AFC721787F67AFD739F60FDD93DA8
-:1018100075586FD9CF05210EDA3C4C87725BCD7FAE
-:1018200050FD3FCDFB4BD1EFA3FA7FE83CC6805D76
-:1018300099EC081B906F817D49DB35092CBEDBE4F8
-:10184000206E1958ED9E58BF899A1FB5C96B407A12
-:10185000DFB49FF3833D9E61F03987213C87892760
-:1018600092237C63FA28CF4AC87352F3EEE0FE9FBE
-:1018700051E3D10F9A83E710F4EA7D2FB1F7F324F7
-:10188000C2E70509E986CC89C6B790260E11BA626F
-:1018900079CCB351DFFE6FE2457DDBA7C1B75002C3
-:1018A000F9D23C4ACD63BE15F57DB5FDE0FC7E3F27
-:1018B000CBEF1FC8CF6379FC0DD309E9B4B332DC99
-:1018C000EBD408F73AB999BC0F6AE47D7419F2E1D8
-:1018D00082517CBE41E8C77302EA3D4E901F17FD5E
-:1018E0007D139CDBC963797231FD28FC3F93BF07F0
-:1018F000E35571E2C47744DB4B8754BBB0543D17CA
-:101900001636803F6A499B230C718F4356E5BCBA5B
-:1019100092AFBCC41C3E06FE9A25CF67E279A201B5
-:101920007BE425A3E2EF6774DAC0FE24CD0B8FA21F
-:101930005FA219EEA5E022FB363DA11DF98B7C8844
-:101940001F1D1AB023DFC987F363AA5C687033FEDA
-:10195000D6B08763E70803B1E7C85E1E7565E58406
-:10196000FA5DA2F6874625B24BBF0ECE0CDF0F25DF
-:101970003A7FA7F075158E5ABCBF5CF8A9F503F045
-:10198000A37C08E583067E5ABF9FEABF231D22FA87
-:10199000F7A80E1580FC53D57F77A9F2FB43054EBF
-:1019A0007F6FF94D4627E243DF6E7F12F1A3CBDD57
-:1019B0009741F21BF6A724B1FCCEAFF83765DEDA0B
-:1019C000BC0965DE9ABC8943FAF00C760F0B858F53
-:1019D0007370DE4442FCFB9ABC896FB04E4DDEC48E
-:1019E00057AF539B37F1CC81A76C105A84F38BE02F
-:1019F00027E9DDA6C77C81A9BCC5C3F2D97896FFCB
-:101A00004A3C785F6FB3C98CFE106DBE1FE5542B46
-:101A10005B401FAEA0760A9C97DAD28E7A4463367A
-:101A20008FBE55C86F14A538F9A4424D4A501A9C70
-:101A3000D706E70BF05E8BCBCC6BBB66B4D581F2DF
-:101A40005722CE6F985F5A3D1AFD0F5F9DD7F65C07
-:101A500001C3FF372D9FA545DFA75B552C13885386
-:101A6000253A0751339A1BC85BC6F38A824CA2E51C
-:101A700071A276B34733FBEC4D43F8FD00E881B427
-:101A80001B88D36619A8F55F16B9AFE13697F7F64C
-:101A9000D1E9A83FE1FE9EDDFB078C4F3C934D440E
-:101AA0003897F08C5EC67D96D309E2B59A7FA18EF9
-:101AB000734E89A35D2AFF593CFAEF2B171EFFBF17
-:101AC000CE7706E569317AFC06FC06E96F809FE86F
-:101AD00059FC4ABDAFE56BE5DC95E6339AFC9244D0
-:101AE000EB6A065AA4F8F3CA68EF8B8C8E3CE817B1
-:101AF000BD5CF9975C46F52180C72EA304A466520D
-:101B0000EE65218F66AB7E5C769FE79AE1A82F7F1A
-:101B10006C66F355EF9B51D7F3B6163FBFA5DDFDBD
-:101B200078BEF7E7405FC72B3D780EFC612BD3DB17
-:101B3000C2CFB33C7DEDFD29946ED87D32CABDE0A5
-:101B4000DA7B20FE38FA1F23BF2F8CFEDFD1AFFED9
-:101B500051F2FBF2D7116B7F1FB2B23CC888FDFD7A
-:101B6000BFB6AECB92D76A5E747955BF129FE008BC
-:101B7000C427D4719AFBD9B9A2A1CA7916F5FD8DF3
-:101B80008A5E7867B167189C9F292B0B3E0DE76B27
-:101B90009A880D7FD7A02970FF8E5F39D8F9662CFF
-:101BA000BB587C95782D785E3FADD057588CF41B90
-:101BB0005A09F439C241CA21CED1E99A49EA2C988E
-:101BC00037310AEA472C0F3DFDAB32CC1B6B017A53
-:101BD00055F3A6CB2F7EB6725A19CE17FDD50E63DC
-:101BE000ECBD333716337B507D4E53E64FB73D1B6C
-:101BF000E67366213BEFDBECF088E0F756E3F4C9CF
-:101C0000523FE63934ED62465139D88A50FFC03030
-:101C1000A4AFA65D95A510BF25017329DE07FE2799
-:101C2000760FFF996543D03FFAB2CB5709F3B696CA
-:101C3000F9AF07BB7F041D07E2BC67765E5FEA8BE6
-:101C4000C33733F95419E2E0993C093C2946F816A8
-:101C5000B5F767A37F7B6518FD6EA5C5EC7DB383E3
-:101C6000C9F5E6FD35649E2552B63862CF8B4D1A14
-:101C700035A514E6515A2C2879A42C6FD549D530B6
-:101C8000F0736AF1C9A9E4ADD62879D9443645F292
-:101C9000B173BF3E6F559D9F5A56F356932F30BF79
-:101CA00043AE68C03C17EB2AC657C97282718E6B6F
-:101CB000C3FDD529144EF9DDC16B014E290076BC58
-:101CC0006F39F4C858FADE91265C0BFE9BA75BC700
-:101CD000F582FE2BACEEFF0E6C89D42556814B3479
-:101CE000ADD0DB887824B4B8802F55FD4ECFCE55CB
-:101CF000AD4E46BDB23BA701CF559D3D6C8C7B2FB1
-:101D000085FA94C98A2C8893E4AEFA77CC63B0EE56
-:101D1000E2E29EBF7BB7D8A29CBB5A91057117EB3C
-:101D2000AA7EB982F69FFB184714333A9BCB027FF9
-:101D3000B6A003F95AB787DDCF58D765AF32A1BC3B
-:101D400061FE2572AD03E588B0FA461DF009A18D4C
-:101D50006AB1749D6F17B3787A41B7A80339F5AFAC
-:101D60005FF271E35E4F1447CEE700B81A8DE1BE13
-:101D70002C67242F493D97A3FAA706E4CFAEB9E814
-:101D80009FBAFC3CF4F0ED98E7F86506C683A6DB45
-:101D9000983D420591723F516CFB41F713297A8BB4
-:101DA0006A176BE9409BD79D5F3104E982F2D1C08D
-:101DB000263186EFC5CDEF6E1598DE4DD7615802FE
-:101DC000F3A8CC72833FF152F3E9B5F6F4809EA3F9
-:101DD000E825EABCBF69FEB95ADF0079E771FC1F4C
-:101DE000AA5ED3A19E33FF92DD1F3742B1278E76C4
-:101DF000FEBF12764FA79AE7E267E754F4947F227A
-:101E0000FE84AE93010F76D9754DC5180F6BC27E57
-:101E100056B3DFFF18B12A6F4545193C45C25178CA
-:101E20001FDDB76804C69B295D14C4A18BC5C5EC32
-:101E3000FE06617532E2B1B09660D6A660CF403C36
-:101E400016D6317C5DA4D0BD9A67A7C62DEF2CF6BF
-:101E50001D2B4E8FBAA7A53589DDD3A2E4AB5B5B02
-:101E60000FBF04F79F3CADC4AD7BDF183D13E38982
-:101E7000AB050EECC3F3F6B923C07F7756E1DF560E
-:101E8000A19F8896687AEDC5F38EB907D8392D41A0
-:101E9000C9AB15563BB6027E9A9D3E3CD7F99D8E46
-:101EA000208F795BE2F127A7496077840D906777EF
-:101EB000AA4D08AFB0A3FE14E327D3FABD8810C023
-:101EC0003C22DD982BAB47A9DF256A2F8D49A83F1F
-:101ED0007DABF322E46BFC53DF16AF13F9A72E7F23
-:101EE0001DDA7322CC3E216FB07CAC38EB8AF15FF7
-:101EF0005EF175A97E4B6D7EDD203A66FE0FD51E24
-:101F000052E325C423C7E4BFF7EAC520E83D904F5C
-:101F1000FCAA1BF4EA1F9BA3F3DFAE1FA38BBDB784
-:101F200092F8CD701F429D723E9A08EE5510B7BDD3
-:101F30009FB776817DD70EE71240BF04F87251E754
-:101F4000333EB0629E46ABC0CE6F10999DFF5832B3
-:101F5000AFE5C7D07E495BA608F097AB5A7E8AE70B
-:101F60003B74C4DB4E9F9F2BBF87A3CE473DAF90F2
-:101F7000487E0E3AAFF035E72DB2139CB758A0E07B
-:101F8000BDEB2E82E72DC82ACF569857779B40206D
-:101F90003E9D3A8D95470826FC7D2633E47DA7E1DA
-:101FA000F958CCCF0E5378429EB919F2BED3E03C1B
-:101FB0000CBBA7939B390DF12F95C207F482763D98
-:101FC000BB9753BEC582F8543D8DC55B53BD06E437
-:101FD0003FE7881BCF09C8707F9F03F06C05E2675D
-:101FE000D89A81F1E2D47CA6479ABD069DC9897929
-:101FF000DD88AF614ECDEB667CAF7BAE84F9F60336
-:10200000F774CE23B83FAB0BA666C3EF920CB9C9E9
-:10201000C0417C499533550A7E746F55DA37B2F664
-:10202000708F27CC8F2C61ED07EEF1FC3EAB6F1566
-:102030004278AF14D561947B2459FD92D919483F59
-:10204000BC722E97DCA69C2BE0D83D644B660F61DA
-:10205000F536C607C9DD498A3C57DADF9BEA57E205
-:1020600005EC7C40BD4EB9EFA08B44C79F553AD3D9
-:10207000FE3E4784CED8F9922722E704909EDBAF3C
-:1020800017310F52BD87B4CA6260E7CE4CB17435C8
-:10209000694C2AC3FB0AB709C65DEBF4FC644C5CCF
-:1020A0003F8D7F6E345F19A2F295BB0D1ABB2C9346
-:1020B000C1D5167E9A9D4F335E965D96380EFA7C9A
-:1020C000766C1C744776741C54DDDFAA8506E42BFD
-:1020D000DD76E92DC897DA44410BF73A6AD7BD6936
-:1020E000E07E76BF19F452AD3D7828415ED4E931E7
-:1020F0004C3F7427F0439C1E93C8CF9520AE5C6A7A
-:10210000FC5F8A8F33FEDB9BE03CE200BC54BDC920
-:10211000A48D7BC897E5F7E935FD10F9A0A75D20F0
-:10212000E6EB6859737E8EF241E48BF20AA3D8EE97
-:10213000003EFA43E48BADD4723546F1456A8E5EBB
-:102140000DFCB8F74117FEDED55B0FBAF179CECCA6
-:1021500005F8B1F00CCF018DE993970DDF83FBCD2E
-:10216000CF59C33970BF794A207516DC577E2E3D92
-:102170007C04CAB69FDEC1CA05E1A7E1BEF3FC9F9D
-:10218000FEF27B58061A1B42975B12FC9E5C0CF712
-:10219000EE8756F6837E5FA63977A0B97F19CEC742
-:1021A000C27A322D068C53672AE792C964C53F0470
-:1021B00099694077D9A598576821D2AE7EA81FC6E5
-:1021C000E42EAD6F83FB7DDB0B9C2C6E4E181F2025
-:1021D000C394BC131292C11FD5EEB463FB01FD6E14
-:1021E0009751C95B63E3BFF72ABB37493D6F4D8801
-:1021F000381CEC468B4462CAEA7DE6441087C3FD76
-:10220000C3ED6ABC5A291FC8F48D2A89B25FDE9BD0
-:10221000727F31ACF3E3DD0FE4833EF55DE577E2F9
-:10222000B478F5D7B14C8EAC48FEDB1CE0E3EFF39D
-:102230003637F80F9666FACAA0BF798EB6F1768A5D
-:102240003F93C54AFC3DAA89F26C0EF88AFD6636BA
-:102250003FFB642F37AF38F23B55E93E01FDF4C434
-:10226000D7CD83BE9D7EDC2B027C1A4CE11C81F60F
-:10227000F381C33709FA3D3FF7C3FB308F70C87B4A
-:1022800047E05ED4F7F45DD536C027A7720F36114C
-:10229000F01C50DFD0113DCAEF6DB1F340059C1228
-:1022A000870D4E06B9700361780B65A8BF51B987D9
-:1022B0006EAAC8EE8D9D5AE6C4DF4F9C41C202E073
-:1022C000C3D4F7BD3602F471B3AF2CDE3D1BEA93E5
-:1022D00064E9A568FAB95E8A2A13C8B7882DFF9306
-:1022E0003BB6FCCF155F8E8C2ED7089E3B60DDAFD2
-:1022F000734CFEC81398FC11496005C8C7175AC42F
-:102300007118577770329447BF3604F3A84816CB3C
-:10231000BF1865CBF53338E46D867585A99CEF71E0
-:10232000C0EFB0B1FBC532DE376C85FB2088246D71
-:10233000063ADCAD77619E6986A5F6676DA8CF5831
-:102340004901F2296933E2B5D524C1EF961CB4B234
-:10235000FC89F6B53A8C37713693CE43BFE37B04E4
-:1023600026FFAD0BABA19E2FA71B426575AF9DFD50
-:10237000AE5BFB78A25F510AFBE67E1FF522AB093C
-:10238000CF274CB6B9EE807ADE66C0FB2B0E5ACB57
-:102390007DCA7804FA7FCEBA10DB038FD653FAEDEC
-:1023A0003533FF3A4FEDE3156C7CFCFD46FE1EA273
-:1023B0008C6F220628D7123C6FD06B17D97CEFD5D3
-:1023C000613C04EAAFC3F999B05EBDCF3272BEB7CB
-:1023D00052C0DF21E088121F6BC3F2530A1F6CD773
-:1023E0008B07014FE58F0881FD986CBB8074C0EBB3
-:1023F0006C6EBC1FC843F21D1984F92CE8F77C866B
-:102400001884FC7BFE1E1BDACDA0F940FD50F813AA
-:10241000E95AF09072C53583E3798E021E8FE08809
-:1024200017F6E354492EF2A36775EF6DC0FC0A8BD3
-:10243000D7E8A6E3186E23B8BFEEE4F8E77AF7967C
-:10244000303A1DBC7FE55990C7C1D92A2478B65BC4
-:102450002B2438A7D46B776779A3CA71F6C50F7898
-:1024600013D91753505702FBE19640BFF8FAFE68A4
-:10247000BD05D623E1BCF8216E09ECD07C1BED87AD
-:10248000F27D775AFC759C52D61150EE2DD4D6FFB2
-:10249000BE4477A5D7A9C1BF6FB9CE8CD8755EC130
-:1024A0007986B82B304F3E87CECF12991FFD13EFA0
-:1024B00051BBC1A243FCBA41BD1FCA157B4E447B30
-:1024C0002E8490E51B81CF7C57C977AD4AFE17F467
-:1024D000E35F4FF57C906B7DC93FCC877CD3A92906
-:1024E0006D1D8C385ACECC037E6CE290EFDC4882B6
-:1024F0002BE1FDB94ADF33F63CE4FB7F2B190FF7E4
-:10250000E9FA46A6D2F2C7FAAEFCC54EE48B1781B3
-:102510002F5A4818E9EE06F8BD46A0BBE9FE0E2882
-:10252000D3315AF09E304A8740B72A1D0E9E3FA5F0
-:102530004BFAFDD0161B9EDFDA428278002F8B7497
-:1025400071CCDFD282728B48C323EBA4443BD5D439
-:1025500082EBF8799B8CF2E1BBF6270528DF5CEA79
-:10256000738CA5F39A35F613FCBD0792357724D802
-:102570009D74BEE963FF81F31D7CAEFEABF3C8FE24
-:102580005EF6E884B1B1F6A823E96F9807277136A3
-:1025900037A1FAE3807DAA37615E42E41C72B80E6F
-:1025A000CF3B73295E9067EA39642DDF9D741DE38C
-:1025B000BB1F2FB6B957E03D923BD02E6DBED9A2BE
-:1025C0009E5346FDAB79A14E39A7CCA15C6922266A
-:1025D000BC2769E0F72CE93F2E23F2BB34FBE0BCBB
-:1025E00072D9579D5796F03CB4BC9CC5E907ECBB2B
-:1025F0004691D9AFEAEF9BDC9BABFE0E05D3531699
-:10260000934BB26FE39C6346BD91A4E814FB95E93C
-:102610000BDD13245126185F657AF86C03D6AF4F93
-:10262000F2E3EF05D5F15D88240D63EDCAFD0F7E61
-:1026300033FEAE98C15D087C428DB3EECEF7358F88
-:10264000A5FB34AFD893C3D1A5D41958FC94D2C1FB
-:10265000E67EDA6A1A69790E7E6FEE7AD2F25B5DF7
-:102660001ED2C1BDF0FDACD19FB0DFA18BD0C17D2A
-:10267000400726C2FC01372871A2D73FDEDE01FBEE
-:102680007E8E23EC3C9A4B7B1ECDFBC3B12C9EA5CA
-:10269000FC9E542CDF899AC7713D9B8783E7711E8E
-:1026A0002BE3CD63101D123F8E4FF7B705CFCB6BD9
-:1026B000F0483B1F6EFFFD789E6FF3ED44E42780EA
-:1026C0001CEF37033C870146E4C13A7DEB609DD99E
-:1026D0009062099354ECEA41F3E62DB8AFB7CE1EF1
-:1026E000C8D399915D0E712236EE53C94DEBC0EF00
-:1026F000D17CBB1EF97BCDFE31A8A7F5C94611924E
-:1027000020C964965FE3A6FF8379CD229E2976DAFD
-:10271000CF4D620DDE0B77F3746D5E8EFC500B6D4A
-:102720007F8B92E773EBCDFAA3D1FAE639FDA37A5A
-:1027300080835C6769E127427F42A4BD73305C06F9
-:10274000DD4BD5C1F813A17A0EF4DF5E1140FE9483
-:10275000884FED1D3B709FDCC86F98EF73702CE2C3
-:10276000ED57E7FB6C57EEB17A4B1FC6FB51DF4EBE
-:102770005FB079315DE7C81F15E3EF1B4FC9A87F34
-:102780006E2D2DFF78D3282CBF9D71FBD2F7A0FEB4
-:10279000E9422C4FD67D3207E8C1553EFB06F85D75
-:1027A000E8B7CCAC9FAC245F770DFD2EAB24771C33
-:1027B0005C6033D910C6EF6E1CDB7815F8632627F2
-:1027C000B1F2A1D23F8CC372AE521EF7FA2828BFD5
-:1027D000C57D32271E5F1CEDE2824554DE4E4E65FC
-:1027E000DF4F1FF7FC10B0E32757B1F26877E5EA37
-:1027F0003CA8D77D3A279EBE7456E1AB93BE38D72E
-:1028000091E680B030FBBDE2D73C1FE2EFCB78A968
-:10281000BC85FB06BC152C0EE7F5940AF07B6655CB
-:102820001E56AEB6B465031F9CE1339441DC55B42B
-:10283000383B44DA2EA5A2723CEC7B3555B721CE4D
-:1028400049E9EB53A4AFAB3FC9B1A15EAAD297A8A7
-:10285000477A4F7CAFE4E76CDF62E981F6F705CA9F
-:10286000CF6B62E5E7207AD5E0E1FF008B7F42C5C0
-:1028700000800000000000001F8B08000000000026
-:10288000000BED7D0B785445D2769F3973CB7D429A
-:102890004248088409F74BC01912205C1D02645994
-:1028A000050C171514E1041002B98DE0EEA2EB9AA5
-:1028B0000901441777E38ACA2AE88080A0C80E0A73
-:1028C000C86A644764237EBA1AAFEBED631345E52B
-:1028D0004E0CA2B89FFFFAD75B7D0E99338405BFDB
-:1028E000CBF3ECF7FC3F3E3E9D3ADDE77475557542
-:1028F00055757575CF55CE4EE15FE60921FC891EF1
-:10290000473E95BD6D271A7B0BFEF74357592A6941
-:10291000427410FABF9521457413A2930870B95EF2
-:10292000D42A421562B2558BF70C12C26E6970E35D
-:102930007917C5D3D745CF45BEC759D41F2F764A7F
-:10294000FEA29F4053F1C395429CB67D922D5285C5
-:1029500008D00375383DF489EEA9D48F82A66ED9CC
-:102960009595E04CA35FA1B85C69E857D62B757FBD
-:10297000E5F7D739E8FD0CEEBF93A73DF093F8AC2F
-:1029800057FC5CBA84F6B8A0F155A40BD73D5EBCE9
-:10299000DCB8324CEFA5D388EFF110B8D73CDE9A03
-:1029A0007CCFA264F5427C2DCEE65961FACE3491FB
-:1029B000E851E9FDF79616B5F712B2D709BF0DE356
-:1029C0007D282E31904CCF2BE724041DF47C670723
-:1029D0006D00E8A15A022F36127CB3F0D9D16EB245
-:1029E000D577059EC70BF9BD0AFADE3D289D448FB9
-:1029F0003C898723A30D7A44E1193DFE56BE346419
-:102A0000A0CC107E86D3856795DAC67884D57F778B
-:102A100023BDFF0B35A1F61E2A1FB2FA2C1BA8FFFF
-:102A2000C0EBB6E06685C72380CFD24F12363AB2EC
-:102A3000A9B40A8685C7C1F54B6E26FCE9BD254AB7
-:102A4000962740CF6B12FC8FE17BCDD556B1311567
-:102A5000DFF76D00FC7A757781F1458F27BDF6A70A
-:102A6000424BA17AC5FF04DA05AA1DAECDD4EEDB38
-:102A7000D87FCCDDC874482AB265111C3369432362
-:102A8000C18ADDE9528869E973D2595ED7DE427C9A
-:102A900020FE050A42DDE603EF475551E38AA40311
-:102AA0006192DD2A9FEB3D44B4F69063831E0105DD
-:102AB0007269B728B38BE28926F877656BB9DE6354
-:102AC0001182F8D43DBFA30FE35EE2151EC80FD1FB
-:102AD0004101DDC55E45A703C913EA15973FE0BA7A
-:102AE000904F4B1BB36F45FD7E0BE14B6501F12B06
-:102AF00005EFC7A9F27DC5D32199FA2F4812FE1020
-:102B0000954B62DCB746D275B8C532BB28477ECF3D
-:102B100049F49BADCF0603CF396B55A1E50A31C609
-:102B200039F7B1C3B9C0775887A28488FA7BFAE431
-:102B3000CCA1F75FB689E9F8BE677FEF9CE21C1E67
-:102B4000872F94C37C5C1102FEA3D33D010FF06B71
-:102B50005EE1017EAA68DEEC011E014716F089C91C
-:102B6000F40404F0AC15B7E545E01F43F803BF3BA0
-:102B7000C6F922C76DE07D313CA3E97D313C2139A6
-:102B8000CEC154AFCBCD1C675C933200A51A7690B2
-:102B9000888A55D4AF33525F45C9B90830DF272E34
-:102BA0001D537498E42DD54E8F20A7B725043712F6
-:102BB000FE136F1BCDCF9529E7589EDBD17C745057
-:102BC0003966BC5B69243CDAE5BD6515FD21A78447
-:102BD00017F0B1360E9A4CF43DD6557B12FAC6C0AA
-:102BE000FF2F839EF06A547FC8224A4239178E6FA6
-:102BF000B72E4F2ED16887DC5538E3C3EA800BE54A
-:102C0000E562F8BFD8A1E839E88D934AC36054560D
-:102C1000F676F17321B46C7C2FD9953D3A197AE29E
-:102C20007BEA6F30F414FDA379D0B7BBF627BC77ED
-:102C3000BD281A67A5F1B61BAFD9341AD738359E0F
-:102C4000E773CB7685F5D5585F8C0574A93C680B86
-:102C500006095EFCAACA745ABC5E0D62D2B608CFE1
-:102C60005ACCC39680C305B97C286EC06F4750F913
-:102C7000D97A9BC7817E03BEB77B53BFF3743EF501
-:102C80005A6B116E832FF47F9F60AC70F76E85FBDB
-:102C90006D6D6782FB873A9ADA5FB1B7ABA9DE1B2D
-:102CA000EE6BAACF3D38D0040F6A18666A3FE48302
-:102CB00002133CB4F12A53FBE147A698E091CD37CB
-:102CC00098DA5F796E8EA9BE34B1B07E298DB73E99
-:102CD0005D150AD9C9D1A2D4D4BE542DB30B62B1AB
-:102CE000A8B57D0A79F4D37FCC4F75A615743EBB89
-:102CF000571129A48F16AC95F5C67B2575F7AD84C1
-:102D00008D5B18343F2F15D65618FAF793856F1E32
-:102D100088E8AF576AB12599CABF7B1252212F624A
-:102D20008818F283CA7CF540DFB4BCAB7A1C42370A
-:102D3000A5042F7E5A09DE437CEC297A3C04BE119F
-:102D40009F45D00DBECAFA96756A3040FD7C5B5532
-:102D5000F2E6011BC10773D7422F2F20BD0CBDE542
-:102D60004837F333C66DE6675C6F333F133C667ECE
-:102D700026E59BF999EC33F33365BC999FED8BCC39
-:102D8000FCEC30DDCCCF0CCDCCCFCC12333F3BFBB9
-:102D9000CDFCECB2D4CCCFECC022537DB4FC765B3E
-:102DA000B5D854FF50DCBE2F34A2436A47D5E5A006
-:102DB000A9D7A3F676D3F7843AC1BE82E8559AA97B
-:102DC0000AD5D52A0701FA4FCE6B3FCFAFF92407BA
-:102DD0000F131FCE8AD5F599EE0BE5A162EF7D7634
-:102DE000CCCF1F2B0FC3BD663920B94BD2DAB06BE5
-:102DF0004669F099FC91D15ED20FD3BCDA582FE925
-:102E000093E9BDBECAB292DE1045C5BD60472EC76C
-:102E10004FB10EFE117ECAA410DBE38BFA29EECE71
-:102E2000ADFA8F9DBF80057AF9C3793696DF65715B
-:102E300003B6432E3FA8917279064D860A71830826
-:102E4000B11FF661EC239DD15F01115C198ACADACA
-:102E50009B80FF4CE04FF6EC26D168C3C7C98EDAE1
-:102E600051160B37977375FFEC66115E89C17C9222
-:102E7000AACD075D2A54AD4B1AE8D1A9218BFDD804
-:102E8000D75380F445E96AE8EB77F027B57BC45B5C
-:102E90005481EF8C71BA6F7DC00D3F80EC03F1451A
-:102EA0004C4861BC85B5A8FF94FE6D7D6719DB8B2E
-:102EB00017144D03BD03194E0FECAD480F3DA3D0C1
-:102EC000F8FAB6730FBC27B9B5FDAFBC867D21C734
-:102ED00086DA3FB92B96E9D5AFC3867618D78FED42
-:102EE000F76EAF6F39F036DA5F6ABC76BB67D1CF69
-:102EF000A8DF6645F8371212EFEA7CC974483F3103
-:102F0000534DF4D4806F71B3EADB131D6EEDA0FD59
-:102F10000EDF9F7EFD4F570256F6A7B817137EA708
-:102F20008B1B07035FA2FF83A82F7312FD6968271D
-:102F30003B6BBD9220144592FEF447FFA236F197F9
-:102F4000F81CD0E9FF6207ED31C8F57E4B439607C8
-:102F50007CB4360C663EBAE4B84EDA255D2E468760
-:102F600082B8CE3341FF790E8747257A1628F2BB07
-:102F7000879366CFAA24BC6FB614A5855513DE4F80
-:102F8000A3BFB2F8E22E19C0DBA6E3ED6CAFD3DD30
-:102F90009D13E99F45E35D83EFC31FFE15F997D9A4
-:102FA000781EDE06F839E1E2F58BC322ED7273B5C7
-:102FB00012DC48F56FEA745E6FA37698974ED1AE37
-:102FC0009AF0BB66E48A0D68F76BCDC9786F169EE0
-:102FD000BE6BB2C10FC1FA3EF32E2558930DBFCA86
-:102FE000C3723F4F1465EDA276AF79B57AE0FFB7B3
-:102FF000B87F0CCAB6F0341EF42E7D67CFB20E9E99
-:103000007B008DB83CF9EF4D9A03FD4F9928EDCE2A
-:10301000CD3ADDA689229EA7C6BA8926FCC90A6ACE
-:10302000379DFEE2F59870F7077E33007B5BE7F58E
-:103030004CD1C0E52CE1E2F5D4DBD51D7E761BB585
-:10304000996269CEB2AB98A7346FB399FEFF0EB9FF
-:10305000F966DC5B8714D0FD0ED263E0F79AF69731
-:1030600025C79315494F9AB79FEBF3360F53EBFCE7
-:10307000FC19DB5ECA9FD5D5E39FCD1F528C891901
-:10308000E4AFFF44AA42F1D09944914AE36CE8AA24
-:1030900006B19E1AA7DE61DD45E36C207FC2817117
-:1030A000FB8A3B9EA6FAF1646FEF91FA352140F05E
-:1030B000249F2AEE6139685CBE909EBF9E4FF5D476
-:1030C000FE956A919047F02B5E9BA786E470DC39F1
-:1030D000ED4012959348EF87A9F555E9F78D857F67
-:1030E00030BE13D991083B715577334C13A113F8B7
-:1030F00074B54EEF093966BB330976C768DF86DDE4
-:1031000021FDAA82BE710375FBD357F485FD79B901
-:103110006AAFF88CEC8B6187C608B9DEB8981DB22F
-:10312000DA0B5206B23FEBB6637ECCC1FA04F476FA
-:10313000691D2747CC97D2210AF3C94D86C742E3C0
-:103140007FF3A01A047DACBEF070D06FF18B0ACB78
-:10315000E9D503B5AC81C48753B6C6F9909B8611F7
-:10316000B94982FAFFB48A10E945F3B7CA297C3419
-:1031700017BEA872317CA42A9DCB63556E2E4F5486
-:10318000F5E6FA53551E86CB0716F5027E73567D7B
-:1031900065859FEF167EF68F96D07A17FC5A92B00F
-:1031A00058C236A70B4AF8AECEF5963882EF0A2AF7
-:1031B0001ED8C585BB822BE308AFD23A9F3D9EE067
-:1031C000259DDB8D8947FB071496FAF907FDF51855
-:1031D000EEA9773FBD6EA2681D6FF93985D7C9EF9B
-:1031E0000FF20D46FF5F56E5335E47AB7C8C97AF21
-:1031F000AEA93E85BE77BC6A3CC3770D2C1A81719F
-:10320000FBC457EC474CDCDE64859F31CEA7F8C089
-:10321000E7513E110C12BDD6DAA45D594B76057A02
-:103220006074FF29EB6F15D0FB5A21DEBFB6DDDCE1
-:1032300071F05727E517B3FF7AFDF782FD5743FE7C
-:103240002F358FDCA2E15426F5773220E9D3B2EB9B
-:103250001D865BAC441F1AF1BE5DA5A582FC83965A
-:10326000736FCBE7D48EFDD4DDB2DD629B6CB77893
-:10327000F7AFDBF9002BA25944ACB78E131F85239F
-:10328000027EFA17E95A847C1D6F17FAE623E8C913
-:103290007FB77836B29C6A9F3D0F3DBADCC57AE6AF
-:1032A000942DF4C5C3D0B39DC9AE72BD3F6E0AC99B
-:1032B00059855D682C7742EB07F878ACE0F800FAA6
-:1032C00073F792CF218F3D773CD4F597EED6FEB6BB
-:1032D0003CFDFB96E7DDA80FF2FCDFB6637DC74738
-:1032E000082ADBB92216787D76EF7399185F2F557F
-:1032F000F8559A67737FF3C7CC3F52FF4F906E41EA
-:103300001CE3059BE7D45EE0B39EF0A1EF3C716F38
-:10331000F940E8B779BF5BD817EF07065A98AE4F68
-:103320003DB793ED3FC998670CE9A9FE6B5E5A96CD
-:1033300041EDAF58D764E948A577935283B274FB47
-:10334000CEB7ABA9BF5C97C50F7F74C54037BF3FF1
-:1033500030B461A302BDFEFDE31D31CF72D67C55B2
-:10336000D0515CDC6F782AEB8396621E572D8F6BF1
-:1033700077DDD4776E14F04BC82301BEC5760FDB22
-:10338000291AB60DFCDED56D03DEDF6309B0FD0939
-:10339000CC917ECBC9A2C0EF31FE726A1F20B8DC8F
-:1033A000DBD0741BD597277715883B1C092E998194
-:1033B0007A9ADE2ED0A762D703851D093E3942785E
-:1033C00014EABF64F79942B66F9DC9F7C6F776D580
-:1033D000A4DD00FB96533048A5FA2235C4FD894A86
-:1033E000D95F65DD4EA7E0F5BC68A792224CAE1B05
-:1033F000FD7266047F2C8DBFC9B6D2F7DA937D04C7
-:10340000BE6BB30319FEF8567BFA9AB7680BEB2331
-:10341000D7FDC5F8CEE78417FCADCBB57F768B7FA3
-:1034200021E3932E5C81A1ADDFED6C092FC43848F8
-:10343000DA5D01FACE6657C30C6E47F06FB95F6D67
-:103440000FE65FA64A544F95F6BA06FDBAA6668106
-:103450005F97DBFF4371FF60BFABD292E871E4B5C9
-:10346000FA2DD3536A5E6C247E6DE8A0EDC7F88C0C
-:10347000B8A4B07ADCD0E3810EBE97F1BCCC49761B
-:10348000D5C2F6F415C0861F7CDE0F735E9E3DDD4F
-:10349000D9C1F717A6E365B677EB7186F37AF5EC39
-:1034A00040935EAD49B00B2F3DAF59E3E0B884388F
-:1034B0006029ABA7F5C7487CC2D2FABD2509033BFA
-:1034C00040DFD708D126BDF6D17CD688B661B203DD
-:1034D0001ACDEB51E79A558DE77DC3CB4979D09F43
-:1034E000C297E0461CC022B4087B17FD1DE2D70935
-:1034F000F06BB488135A84DDF489643BE6AD886FC1
-:103500007799E30E3F6EB627FB1F8F1CF788960F47
-:10351000E2E052113D3AA0BCD8B85ED4C7F5278C82
-:103520008BCA79438AFE01FC467EEDB2627C23ADF4
-:1035300093B3BC5D196F6B2EF53BEA6B8B19EFEF04
-:10354000634DF0E5E2FF3385166A90E3AFEC1C179C
-:10355000AC83EDA771D42DCC0962BEEFB18B801383
-:10356000EB982976F66BEB1202097D51AFB84288D1
-:1035700027BD606B9821D739C2B5D90BF97DE3110E
-:10358000C8FF0D2D7605F1A98E0EF105FC25A126AB
-:1035900089CDA911DF6FEFE2B885EACC5C8FB86204
-:1035A000DD50FDF90C3B3FAFB109B67B8119B18C01
-:1035B000D79A64FF6BFDA97E4DB58C677E2082ABE8
-:1035C000BAA2FE0E95EDC070CBC6CD0F621D333989
-:1035D0009DEDC69AE4706625DA2FECEB09903CEC81
-:1035E000F987CAF6608DD797D12E1E7A50C605D7B7
-:1035F0004CF665C4A6A24CB360BC1D49CFF3F36C76
-:103600006A47E54736D9EE439D6F44E90CE8DB870E
-:10361000E7F510D03F57E7168CCC65FF47C63BAFA8
-:10362000952C10336E7E80E3AD0F6B6A50CD065D36
-:103630007E736F4F826F98A3BA1077BBB62486E370
-:10364000A1D76A7A3C749A390E7B75AE6F642EF1FD
-:10365000BF3CD4A7DBE108399E71738F9F433F7C49
-:103660002A645CFAD769DA38B4137BBDDC6E2F3973
-:103670002B3FC04E38DD03D87F9E67AC1BC3734120
-:10368000DF7DCD4EF64B2F260F42789C7DE9FB0F58
-:103690005A4408F2DC05FC4961B90DC06F0B846225
-:1036A000580EC64F71727CBD25DEC2FB0C8F11BF58
-:1036B00060DF02BBE53E03294AE6DF83FB3AB35DE8
-:1036C0009AADEBB19AE9B1FC5ECD4E5BD0023E2BD8
-:1036D000C16D5BF0DE8B316C3FCBF4386FD9F3FDFD
-:1036E000580EF6D87DD92BD0EF3E07F3B92CD19DDB
-:1036F000C4F5FF962250FF821E772E8B0DF7443CB7
-:10370000BB5B7B6D3EE84172C771F932BB7C7E28A2
-:1037100058C0FB1A82FC95B851040B1FEF4F04C828
-:10372000AFD9EC91FC035E5A4DE78DC057233CC0E6
-:103730006771BB8C971FA2B98CF11DF27766BC94A0
-:1037400029E3336EA6FACF16C7711CF55051FD5907
-:10375000F80187D2559EF7A4A1EE1D42F564731BB4
-:10376000EE21B872E1A76F0CA1A715351F66ED75A4
-:10377000B7D27DE6B2F20982E460E6A23B2689C4B4
-:103780008BCFD799650EAC115BE7B7B063B12661FB
-:10379000D2EB6B727D3590C350AEB612E3AFCC2145
-:1037A000FF99E4E894BDE151C4498EBAB5BB517F9D
-:1037B000FA8F5F6EC173616DEEC9F2E16C2C449CAF
-:1037C000A5CC22E344A3F3B4DFE6B29D4D64FE55DD
-:1037D000861CCCBFB89C06A917EFB83C7B70AC6EBA
-:1037E000F31E85FA298DADABE0520D0E80BD3AAEC9
-:1037F0008413956E4C5F0DF3EA842B9C08FE6816CB
-:10380000E9BF956E8D1EA7DC4F2CC51FBCEE0CD9F1
-:1038100087135E8B48F53EECC2737B6BFBEC563E28
-:10382000D277988F22FE9359BF44FB6D7D06DE430D
-:10383000742F4DDEFB9BE1D917D22F1A36C67321A8
-:103840003EFA3C290A27629E1C57E43C3921A4FE1B
-:103850000A6C8DD1D7FF128F537FECC078A4E9F3A7
-:10386000E894A2B7DBE690ED48F6E0CF94FE41CABB
-:10387000DD8336CF5AB9AF66657D599A22E152474A
-:10388000BA0BFE5647356089855C56099E2F841B0E
-:10389000CFCBE33B32F97D43AF892221A0D74A77D2
-:1038A000646C947E9DBE0EC600A8FDA2A7647F80B6
-:1038B000A1FF8F3D99A9F72FE753345FA3E9F07E6D
-:1038C000AE8C5BD5240CEEF0CFE295BDD33F5E0706
-:1038D00015F4A04DCEEB4082B423E4B7A44FEE8F95
-:1038E000FD06BBE9BBA712ECB37DF1D877303F37BB
-:1038F000BEF769AE5C477689E27B47B5F925F84BA0
-:10390000E271C17A221A8FA3788FF07DF2C9F37C1D
-:103910005625DF49900CF97233FD840DFCF9D06E09
-:10392000F0F1D64CD2EBA5A055D7563AEEF16A99F4
-:10393000B023A7F47DA33DC904E7C0DF92F6C3809E
-:103940000D7E44CBE9B20FE767629F2A2D4FAE0F81
-:103950006A6212078824945941E8816AA22BEAC955
-:103960000EF27EDCB1AAF1F71FB6B58EE78B2A9F67
-:103970008F4CD07978FE5AAF13F373C13AAF734EC0
-:10398000043F6AB6E61E7413DD4F6CB562274BD454
-:103990005883BF19968AE76A2820B8DE097A9F887B
-:1039A000DFFF06DACD5F973C508DD04F0BD68EF3FC
-:1039B000CD8BE043BFAD66BEF40F99E12BF69A6163
-:1039C000377832E8C7BFE70D9BE1DC8366F8B9FCC6
-:1039D00066F507D8A7784BD0A9A06C517F807E0FE1
-:1039E000AA41AC33BADC51347522C147D6CDF5803B
-:1039F000CD0BDE5B3618FC3BB9FBAE3DE5F4DE914A
-:103A000076160FD657C745E8FD89C48FF975F7D9E3
-:103A1000AD6E8CD72CE77B2CBADC3E29E37A0B8386
-:103A2000E6FA0BF543B51E4712BD23E52A9AFFD4EB
-:103A3000EF753E42AC6CE9D4FBE1FF944C2081274A
-:103A4000FC8686EEB38BF8CBE927C072634D14E198
-:103A500074C2AFE9AE048EA70C5B3A467C46DF2BFE
-:103A6000B7BA0663BF7D8E5371617FDB889337EDF4
-:103A7000CCA8803DDDECB278904CE1CAF7D767E680
-:103A8000613D21422E0FE2F477AEC43ABEC49FC816
-:103A9000F45928821C679FB3DCD1AA1FE9FF79ABD8
-:103AA000A3F05913514FE32859676EBF68D30F8EA7
-:103AB00048D858970EABDBA062BC37EB78AB0199C6
-:103AC00037304C8F3F1C4653B2377FEB56549C87A0
-:103AD000F66B46CB7AAB53B7B33E5EE795C7DBDDFB
-:103AE000ACCFAC6FADE4FD1A9A87B00F0713E6FFB9
-:103AF0001CFAEE8C53B81C9C47A231FC458A5C171B
-:103B0000F23E04B53FB34E61BB5E9E22E1F2C79523
-:103B10002062BAE508C2027E42C65DCB747A404E8E
-:103B20007C11E301BF2261516BC4BBC3BCFEADF08D
-:103B30000B0FFC00417CF499F6BDC3F623B0B30132
-:103B400025F4B017FE9EF93B957B7F7044C2E7E3F6
-:103B5000C5C4BA6AFE7E90E9A8DA850F7A5CBD33E7
-:103B600096FD763200B1B0EF36DDBF16AB82ED6167
-:103B7000AFD6C05E51B942F7C303F7497BB526D92A
-:103B8000D7D385FAFB323CA0C30D8ABEBE855F9FAA
-:103B90000CFF7A3FF7DBACB85C1B93D15E0462523A
-:103BA000D9BF96EB847FA86CEF9AC97FC7FEFC1A39
-:103BB0006F280C7CD63C90CDFEFA0B86DDBB3746D9
-:103BC000FAF317FADDEC5F89FBA5FFF891E0BEC5BB
-:103BD0009EEEDA863C92F3B96A116F2ECD5BE6CB8E
-:103BE000C077E74DB15BC00F517279FB1C9BF53C70
-:103BF00098661A2FE2EF8795A27A4B841FFC4C9EA1
-:103C0000B40F830B7C5BF4761EB49B67798BE93031
-:103C1000CF225C58CF6F3EA70A2BC19B6B1DC1659D
-:103C2000F4CABCAEBE9E8B73F09E8C371DF24A7DEB
-:103C30001F97277C41E87FFDBB2FE4594CA5182B2B
-:103C4000E32C8763A41CCE1445851CEF770B53FE31
-:103C50008551BE9227EDDE3C7B83199F4F5E66BE89
-:103C600090CD732D837C8F957EC7E15B14B6E734CE
-:103C70009E9E2E8207FF2E86E38587757B64D097F4
-:103C8000E487F3220CBD95ACCBCB9ABB83DB628877
-:103C9000DEF7D9486EC037921BE4F910DFD92F5CEC
-:103CA00033238DF97E83CE57716F02F36DB8C52231
-:103CB000E97C6F06D399DA8BBFE3BD716EE9CF5F04
-:103CC000E63A8CF8FE37F03D7A3D66F05B58838328
-:103CD000FED97E4CF9734FEF0990FC2FFAC303898C
-:103CE00082DA1DB5D6A679E8FDB2CD2B127D541E21
-:103CF000B106125DD4FFD1A03A3ED806BD3B0F52AB
-:103D0000F4F5902F11797415BA1E3FF6E47FACBC20
-:103D10009DF0FC4611CDD08F15BBBE5B793B8DAFBE
-:103D2000DEE76C863E3D626D2C84DE5D581CEFAF95
-:103D3000F660FE9AE3F28B9E7820CDCDF40E645AA5
-:103D4000D279FE67E2BD8A4D360FD67515EFAA1EF1
-:103D500037E6BD685E09FCA2DFAF0C7D6607FD5D3E
-:103D600016D1DC69781BF5A291F57CE5AE5F7FA5E5
-:103D700026A23CFA11D6179551FB0125FA7E49F48B
-:103D8000BE40C2A084D42F10F0D6F7A3893E9C97E2
-:103D90001020BC7AB0B8C83872CDB6870634C16F6F
-:103DA000D8F45AA292D3BA1F60ECA3B484E63E863C
-:103DB000B8EAC5E6E5A9A838B0A1C7DC7B1599B477
-:103DC0005827CB325B3811FE7ED9061BEB91B2A788
-:103DD0001FDFF230E4ED4387A7871BF0193BF44166
-:103DE00099E26B5658BF8B4465702BBF4A9FFEBC4F
-:103DF000F011F8D719AA9840FC5AF4EC59D9DE27EB
-:103E00009A63A87DE9CEA642AC0FCAB478BFB30DC1
-:103E10007E8D09BD646F8C6F835FA1A6428E536D4A
-:103E2000FB96F971749F223A645FF87EC986CFEDE4
-:103E300042AE0F9A539225BD60EF2A436AB13DE925
-:103E4000C2F6F4FD49CFE771BD0BEB954BF1F124C0
-:103E500068C1F29E2090C758F291233801FCDDB171
-:103E60002411F94F5F5AFD52EED7AF48839F576236
-:103E70000BA4B9B894CF4B1EFD19CBE302C59FE646
-:103E8000E2BC2DD2AFF93CDE0C8CF3E675D7F238EC
-:103E9000E70B8DE5B164BD5A14A4F2AC558CDFD9A3
-:103EA000C6BC796890D4770E71CB00CC93B3F4255F
-:103EB000D8F12FF5757DE06DB99E7688294991FB83
-:103EC000432583A45E0C88E021D881CA061BC7293C
-:103ED000D4B7CE16E23BB7665BFDC8DFA0F107742E
-:103EE0007A293FC8F58B1B790C95F88BECE998B7CC
-:103EF000C67568CCC1F75BEC3751BF5F639DE83195
-:103F0000BDC774FB72A32356B982CAB4B6F3BEEA26
-:103F1000CFCF7FF1B68890A7CAAD5FB23C89745508
-:103F200024A54B18FB11AE39F1FE24A2DBD7EF7E9E
-:103F30006647FC3B906A113D806FC3E70C0B4F7BDB
-:103F400037DA1BDFAFDCEB10E1C879BBE9F3A87906
-:103F50006DAE17C2CFF4AC14496ED8EF2FEDCD85FE
-:103F60002FA01FEA7733F5339FFCAFB0C9BF6A2E8D
-:103F70007C04FA64AFDDC5F107F23FC31172737EB2
-:103F8000BF53DFE75BA0EB83683A44EB87FBA2F407
-:103F900083F1BE58D7F6FE52AB5E08303DCB6C22A3
-:103FA000003FA3EC4307DB8FB2A7E57C14A44F7B53
-:103FB000D0FC38BEFDE5F76FC07A36644B9DC0BDBE
-:103FC0009AF56FC9339FF3B8E612FD633CD0BFDFAB
-:103FD000DAB1FE4D1F239A1D84FFF1D55E3BE4FE4E
-:103FE00082794CCFDB9CC7AB15D66FFF55BD4BF428
-:103FF000E6FCC04BCDD70517D1BB7551743D2B7274
-:1040000092905E2D5CC55D78FF208ABE065DA3F5AB
-:10401000E8B441EE36F528FD7B5F44D051884696E2
-:10402000E36F482F625FAD62D3776CD788ACCDC8A1
-:1040300027AF087EC5F00AD835865F9A8678E58571
-:10404000E336D333BAFE4EC818FD5FF4471BFB05B9
-:104050006575326F91DEE3754725E2F5DCBAB63E51
-:104060003335120E46C1A1A8F6BE28B828AABD163F
-:1040700005FB4DEDCBF6BECCEB2CC2DBD4CEB1F4C0
-:104080006A5E875CE85704791C95BBBEB207201FA7
-:104090009D9AEDD08BB665229040EF37BFA8B2DF76
-:1040A0007BDADD9C083F65458CF4E34EBB7438D960
-:1040B00080C5EC62C2E37460800B7902CD3132DEE0
-:1040C00072BAA839313962DDDE54A726BAA97D63F8
-:1040D000508C6F3BCFA586E753A3B858BDF4E7C615
-:1040E000A9DFEF90F99F5681FCD8C6EA6F77209E32
-:1040F0007498D64FF05FE6555F9F88FD97D375DDC6
-:10410000AE998E75E0ABAA9069D63E3BF220E64AA6
-:10411000568A2322F0E0081A9F9A9057FF02D6573A
-:104120002428D8FF9CB73ACABF11454961ACA7D72C
-:1041300044E72B04EDF06F16909D853E2A5967AE3B
-:104140005F54779CE7CBA2A8F9A2E971E3E8F9D222
-:1041500075B09EB7E0155E3D7F92F3F44E1F545943
-:10416000BE5A96DBC4CA5499278BFC92963A997F23
-:10417000D3B257C222A0E7F5E8F3D6A0DB09CCA75B
-:104180005E17F75B4EECFEF7C1BF84FCECF97800DC
-:10419000F6894FECF9B0E70B809FFB6BD6C7E2C204
-:1041A000F663F67D378BF1DAE710C0EBF4BE57B259
-:1041B000E06F9C7EDEC1F905A79739D85F0FEC4B05
-:1041C000E0B8C5E9CED21FAE79F1DB018D6C8F97D7
-:1041D000331F270EB64BBFAAEE3FD83EB6D439DC0C
-:1041E0001847E5BE389E5795CFC7F0BEDAE917BF2E
-:1041F0001D1C198FFBAF8EC7D8573F9D20A63F03CC
-:10420000F9D5FDFFCA17863E5E8DF5F2AE97EC73C9
-:104210009127F2A7FF3300FAF5F4332FB1FE3D6585
-:104220006B7C14B1CDE97B321EB10D455C8F3ED65F
-:104230005188AFF6CCB811F3E742BA483A9C263A17
-:10424000605C449712F8E517A347E5BF2C3DBE9A82
-:1042500025F5DC10817D9F56BA283EF93C81E35557
-:10426000347EF97CDFB703A0872E35DE7BFF1F1B72
-:10427000EF53186FFB7FC5F14A79CF1DEC66FCA2A6
-:10428000E5FE42B97EEEE70CEF48F030BE9739DF2D
-:104290005FFB971DFFFF0CBF8FFECB8EF752FC7E9E
-:1042A00055E777820BFBA0A75FFC3F59E2478CDB09
-:1042B00039E45F755EFFF3711BFE7C81EA39E8A586
-:1042C000F6AF89D0BB9E6CF64ADAF447060D518CE6
-:1042D000B838AFA7C6E02F37DA0F5C8E734C01F207
-:1042E00027B08EA9891F78E02D825F213F41E57DAF
-:1042F00059194F7A25DD1B94F15DBF403CABE0AF0F
-:1043000073197EDDFB9303C82B2954653CE6E56AEF
-:10431000CFA6061AC7CBC91637CE958DED34F7F068
-:104320004EAA7775545D589FD574CA75BA23F01B91
-:104330001B6F5E675D1DB54EFAA9DB5C3F5E3C936B
-:104340008AFDBAF1393681F33685681FB1AE4C1952
-:1043500022CFF7FC54D42E77C5FF783ACDD5E94467
-:1043600074E17D9B402755CF7333D34D806EA9A058
-:104370004B2EFBEF01E139F016C156DDBF12FAFEFC
-:1043800063A133610BD6D10E51100E127CD66DE5B0
-:10439000F3935641EB61394E5E4747D34DE8EB6AE4
-:1043A000ABCE82B19DC68441673CEF926E7A9FC7C7
-:1043B0001D4DE71F4FD7FD9D9680AEE9099E20E475
-:1043C000A2D3B3A988B3D6109D15A5959E069DA22C
-:1043D000E99E8FCDF541ADF4EE64F55A31CF46EA52
-:1043E000FEFC586BB2843B35A8F25C5E90DB8FF923
-:1043F000DA63853F323A3E99F343857E6E42D5F7C4
-:10440000C39161C778D0FA1479B693ADDA92219C42
-:104410005FEF120558B7168810E2B74ADD2BDF614F
-:104420007D84F32245BCAF59FF01E05E382F86FC46
-:104430008E75D613A6F36E51E72526E5EF1C0D7E8B
-:10444000CD594ACF10C772B9EB311F8BEF77B8C186
-:10445000BF4ED606AEA7B596AB7A2876AB430CC74F
-:10446000CE234F3F03ED5E19CDED970897928C74E4
-:10447000BB109F778C77C97C355ABC7E03D8BE3C75
-:10448000C15D23E32602F2D41D65577C5FB64F1F42
-:104490004BDF43BE9BD0D85F8EEDCE9120D1552906
-:1044A000E2FDF72EDD645E44F30A07AF778AEFEA98
-:1044B000DC137A694281396EFDC510B9AF69945336
-:1044C000F3DD729FC2E249C777E62CEFC3EB2F35CD
-:1044D000B6A87C37E8B8238EE5BC78E54D1307D144
-:1044E000F78B77A47880E6B1493B07CBF6337EF6AD
-:1044F0001E3DD7B6C6F0F39FE76B8F0F419E81E25A
-:104500009EB59B1ECCB9F6657B3A75A185269F4466
-:10451000DC715260E71BD8E79C344DE5F69384CC00
-:104520002B15CBE378DF7C62E02B6B3A7D6F222D7D
-:104530006A50DF14E3CABA85F02FD6E3CD7FD0E707
-:10454000A11A2BB467E28157E79E5DE9F94421F394
-:104550009BA3E7ED71BD7D97311E772AE8A3C4B810
-:10456000701ED6688FEFE0BB5FE9F4785E2F0D9880
-:10457000E8CA71F179AB1C4DDD1251DAC2BDA8EC6D
-:1045800033AC601FE46D425751B816DFBD4D151BAB
-:1045900019DFE6628EB327F476830F9AD0CF77AE19
-:1045A000E9C1FB394DA305CB4FD37DD906BF393FB8
-:1045B000C958CF358DF6D4237FAB79B4D3B3D1832B
-:1045C000FC9650187194436BE57E4D979A7077E88E
-:1045D000D966AFDC07F97C69AE1B7272F303531323
-:1045E000A13FE7AE51C30EC8FB6A73DE9270793803
-:1045F0000F7C6EED683BD6AFF3E27D768CEB4CBE64
-:10460000F611F8659C73EC0B9C708EA7B6F875AC30
-:10461000FBD4449ACF987F567722D6D5D1794F953F
-:104620007A7E9301FF3A4DFB0CDF9B93E4DE01F9A8
-:10463000F87469378EAB76CBD7CF575AC3DD419F1D
-:1046400047692E607E3E3844CADF8476AE9EF12CE8
-:10465000BF3102E36AB2B97A429E9B56C45840A762
-:1046600009CBA41CDF6D95F32BE8735B02F4FEB35A
-:10467000789FBE3BB3DA5AB481FAE9E414D6847663
-:10468000B4CE1DA63D0FFE4C0C541FC2FA7AAE6E7E
-:10469000AFE6AE96E7C1BA8C917C15D686B129F407
-:1046A000FCC8E6EC81C87337E466FEB082BF0F89B0
-:1046B000E0FF84025F617BFACE048BBB057A78DE73
-:1046C00034E5A56E520E7E18C2EBF93A9EE72DA492
-:1046D000271CC93807D82061E4AB426FD43EE4738D
-:1046E00046ACDBED6217D7DBE7C97CD42EF670351C
-:1046F000E75FDD225CCB08DE427E84D526C4D62A65
-:1047000027974F5691BEEB21C4F6AA74867754B909
-:10471000B90C55F5E6E7CF547918DE5595CFF09EE4
-:104720002A1FC37BABC673F97C55113F8FD63F73ED
-:10473000E3E7B33E71F5245E0FBD506E66B9092FF5
-:10474000E81FA770DD85F34742EABBE4DE52FF08AD
-:104750005D1F75ED23EF03E8962FF9615B35DAC233
-:10476000E737AD8D1990BB71EA89A79F43BCA3249D
-:104770009EF3B25A4423CF931661E173D9D03F0E12
-:1047800092BB2E778ECF8ECC3BBFB14411D608F9A9
-:10479000BAC91F23AC11F669F6D264133C73E93B26
-:1047A0007FEE40DFBFB1AB96974F781CBAF38BF525
-:1047B0007FA5E78FDD79AC873CA7FBFD86C8B84BAA
-:1047C0008B6896B0D5C9FBF18FDD9E9196A2DFD3A1
-:1047D000007E19E7A4BBD89B8F3E8179B842F52CA7
-:1047E00023F823F087E8F989CE9FE215DD56FE0213
-:1047F000F3DAE7F428F49D43B7F72BCCA7F68FE95B
-:10480000FB51179CAB4E97F6EB53D8AF6469CF0AB8
-:10481000A047C3D26E7DFAABB4C05DA8BF25D183DB
-:10482000130DDAAA0E810504AFF6DA3D2AE27A7595
-:1048300082EF5D201A4BBF226033DBB1C64EC988C0
-:104840005B1AE79EE3F2824E3E77451D613F664E5E
-:10485000EFFD22037AA9567161BF06E7349DEDA0F2
-:10486000DF14DE1F451ED034B29737E5AB3C3F7FE7
-:104870003FC4CAE559D873A26B8CF0707C66DE6ABF
-:104880006A0FFD58EBB5CF8FD0BF73F4E7737B5B36
-:10489000B8349E97E17BD83F5CE59D0EF9E888FA35
-:1048A0001C9403A703BF8EF185562562FF777EBE59
-:1048B00055EF5FF67B169392E07B7A77B5DF9CC36A
-:1048C000E7ADD86E19FDCCE93D706557D8EBD5A39F
-:1048D000411D5163F3A4A752BBCAF3DF71497FC4E2
-:1048E00029F3B3CB2E62378C38DD11FC29CF3DF292
-:1048F0007817ED786A07CE3D2CFAD8C1F66BD11542
-:10490000D22E899CE0E0A91CD034C7C5C73E75B241
-:10491000FE2EC2E724CE2521DEBFEB333BF24369F6
-:10492000DAF8933200AB4DC8338D8ECF1ED8F171BB
-:10493000629B71F15DEAE5C5C595EF1361178CF1D6
-:104940008C7BF16C1AFCAC4AE51CEF3355BEB822E7
-:10495000ADADFCB0E8B8F8F9F8B958FD15CED757A9
-:10496000DE71A4CDF879741CF0F1FCE8FD88F80242
-:10497000E889B307D520F6D35B823D92441BFD1B2B
-:10498000F1F3CAB5F4520AE6A53B09FB61A72FE291
-:10499000971FC997F6FDA41E6F3FBD5DE5F5D2E9EF
-:1049A000ED0941F8A715DBEFAFC73E65C52685DDEC
-:1049B000F372D1C0F4223A0A67A41D43BE5B0A9C7D
-:1049C0006B7712F495815FE953097EC8D5C290E2F6
-:1049D000DB4C78B438DD49ED23F03800B96A8F3C00
-:1049E000C0D060A6AB8EF7F3BA1E34DA2DACBB9FF5
-:1049F000E3D2D4EE14FB3B7F88139C27289ADF0078
-:104A00007EC7D7E57AB0AFB830B4B382F33BB6C750
-:104A1000B9108738A6E7391BDF69D0FB6BC897FE52
-:104A2000C9717DFFEEF80E79DE1C78623E1D53CC15
-:104A3000F982EFEBEFBD9F2FF7CFEEC05EE2A0D67D
-:104A4000F60B434D89DDA9FD977BDFE1B2516FBFC6
-:104A500030BE6100ECEE97BBE2783FFECB5D8F1479
-:104A600022CE7C32343A15F26F7CFF54BE8DDB9F30
-:104A70005CA78E07BD4450E6D99483AEB99178A661
-:104A80006C086447CE33996F747CD7B389969C5673
-:104A90003E963BFD4E9CF7ACDC754B11E4B8DE2630
-:104AA000E969DF35398063CC95755E01F9E5799662
-:104AB000C1ED575922DA396C1EF68B6D7B8B7D6800
-:104AC0006FC4A117EFB6F179C15957B8AFBF11F351
-:104AD000F0351BF361711FF7F59C8FD4A072FEF2C5
-:104AE000E26C1186FFB1E4B6840DD80F33F09D95CA
-:104AF0002BE77BD92A45F8685C6541790F4747E287
-:104B00007B00394AE98D83903FD9941DBCBB672A4D
-:104B10009FDF0DE3FE1623CF94E6714F9C73EC30BC
-:104B2000B41D8FFBC119856CEF0ED945007A21F0B9
-:104B30008CCCC329EB2AF3A31F86DCA3BF76E19EAE
-:104B40002934DE133A5FCBA6847B222FA3EC990C89
-:104B5000CECB386197FBA5788EFDE2B281F47E3C26
-:104B6000DFCFA119EF2747C851D91C8F1BEDD47691
-:104B70001EB7371EF8BA4EB1DFBA3B41C06FB53C25
-:104B800097A0E757C5701EB9F15EBFA152EE8C7BAE
-:104B90003FC40D321FF3419BCC577D707306DF7706
-:104BA00061B47FD0A6CD80FF8471C05F5F68AFED38
-:104BB000897D1703DF8589B58CE7095DCE17C6D6D9
-:104BC000CABC70FD1C31DA036ED2F3D89BB73938FA
-:104BD0007FE55846C337C0F7D8B63EC88101BDE768
-:104BE000EFE57AF21F899F8B9E7484517F749B8CB2
-:104BF0005B1FB505BF811E3EBA3E85CF471D6D1FA9
-:104C00001CCCF9018ACB02FFECA8A2C33617FB9596
-:104C10005DEC0453FBD4586141FECEF8296B67214B
-:104C2000BFA1659303E2298E6D79288DD735C29D8A
-:104C3000C47936075501BE1D7BF23FFA44FA2F4670
-:104C4000B9689339EFAE295B98EEC9B97AA89C97F9
-:104C500057EBF4BD66A8B453E571A107BBF2F82485
-:104C6000BD893FBCBEA3199AC0F9134FF750A037B6
-:104C70001E16C19F7F9CC7AB6C37F2E6CB9ED9F660
-:104C800006F66B8F594403FC0FE5CEAD3FC77D1B85
-:104C9000A9BF49623B24C4261EDF51973CA74A1393
-:104CA00096C7BFB08384174DDDDA13703DD91C85DC
-:104CB000E6D7228BC2FD2FDAD39FF3ED881F16DED5
-:104CC00027DBA9EAF8904F09FA6D91F9CA13DA05C2
-:104CD000B7C0DF6B5EDF4DE0FCFA3875DD00F0EF4A
-:104CE000CCA6380BE4A9FCAEE149C341B737550166
-:104CF000FFE38CD5D321328E104DAFE83CF0E0506D
-:104D0000A99FCA700F0ECDABD23DEBF9BE9052C831
-:104D100025E8F2A4C2FBD8A52B873FC472FA864DC2
-:104D2000F4A07E4F84EE4F8CE4CF3D43A55F70FE30
-:104D30003B760FB72FA5F6F2FDD71219CF2D36CE41
-:104D40006B89E6EB65BFFFA47A59EF9F1F7F88FC54
-:104D5000820117D2E18C68F8F9C7F4FDAFB7C7F04C
-:104D60007A9056007C8EEDB82D341FE33EFE740C15
-:104D7000EBAFE3C9524F7C49FA34D00B785CFD5B52
-:104D800096D3B7A7F279BF0541F3778D7E7F3B5469
-:104D9000EAF1F2144F12D69DE56F4A7D48FCBA86BF
-:104DA000DF7FD3C6EF478FA3427FEFFC3C7D3A8E77
-:104DB000E5E27847C98FE33B7AB17D6A4A76099686
-:104DC0009B6D36596F0B65C10F3EFE742F6F4DC43E
-:104DD000778F2787B25C11CF9B6CC19543A43E6D42
-:104DE000C6BA588449D50E467E91603D6FBC57EADD
-:104DF0005CDD003F05F9BD8307721976B4BB304F07
-:104E000077423BB99EFC529F779CB39AA6E793B337
-:104E1000DF13B2438F6BBA7F58B63D3ACF57D6D720
-:104E20001BEFD3BC4B35F28A2DC037644FE7788334
-:104E3000703F43F8962EBF6521F2C74BFDF7DD08A2
-:104E4000FFA9D42AC6DB09AF2645653C9A62C4ECAB
-:104E500029F02323FB89F0DFDE6AED47E0DEB6327E
-:104E6000FC41F3E0BDA16E293FB0A4F4BDB2E5CA98
-:104E70006A7CDFD02F1C284C6BA513F25A91DFD32C
-:104E8000345AAFBFC8B89B6CB23E7ADC063E478747
-:104E9000CABCA0A66CF76F47802F7F51F97CD799C9
-:104EA000EF7393DAB5E1A7B5DA7B7B6B9E2DE1FF5B
-:104EB0000D7C6BFACEF3BABE2B25FC8067CF75E66E
-:104EC000BCF2DE9BCC70DFED66386797191E506729
-:104ED000863D07CCF021BD5FACB3710E19EB6C942D
-:104EE0005867BB1D729D0D18EB6C945867E339D65B
-:104EF000D980B1CE068C75366083DE586F03C67AD2
-:104F00001BF5BD86497D2E7CE134E46B5658649ECA
-:104F10002FF1C3C7E79866D84DE7524EBF28CFA5FB
-:104F2000903C487DBF309EE7C9C36831147649CEB6
-:104F3000A7D4E71DC165F4DE38B7963C0C7662ED68
-:104F400057F32177155D1B39EFB569C52B3DEFA7E9
-:104F5000768D4A82805F51B1F6AB59F0A33AB8B56D
-:104F60000EC3089FCAD8869543386E1F66FDD15878
-:104F7000ED7EF34AC9478EBF14ABB8F982EA4BDA2B
-:104F8000B5993F149D772E569BF3CC2F95771E2D08
-:104F900007861FF898AD39C3C5EBF4118F22CEBB3D
-:104FA000584970619DFE598C5886FB8002AFCA3CFF
-:104FB000B59683369937B05AD92822FC93413ABD29
-:104FC0000D78EEB95CF6C7CFC3AB158BB84288EE4F
-:104FD0005A7313D6D7674A2CEC779F2929286C0F70
-:104FE000FF8FD6659813B86F2B125FDCB715293F7A
-:104FF000B86FCB7C6EA2A3A93DEEDB329F9BE86B22
-:10500000AA9FBA3AD7543FAF68B8A9BEBB90F82D53
-:105010005928F19B47F6C197027819E72D2E01EF29
-:10502000C84FC952022B592F6F50F8DCB87BE9AA40
-:1050300042D0E5048933E20886DCCCD5ED8BB0069E
-:10504000EC90BBB3A9B2FEA8D2F0C55DF4DE496F07
-:10505000ED165C8572D2B2EEC1116EE4D76FC872E4
-:10506000D13CBC5509A541F5140CD234C8D9616BAB
-:10507000E364DE4FDCD9BE5D35FCCE8383DEC847FA
-:105080007FDB55CE9B30E425CB26E3741B689D0166
-:10509000FF6A43ADCCE7DD509B12DB3D62FFC518D4
-:1050A000670BF820502E4B4BE5B89068C038C86F9E
-:1050B0005F06BFEDCC41E9B71BE3E9BE3CDC690903
-:1050C000D5DFBA3386E973585F379CE8F3D20037EF
-:1050D000CE6F54EDCD52E10F58B66FC13A22215533
-:1050E0005B0AB92FD9D0E3AFB8AF6BD17BAAC07937
-:1050F0009ACFD78C491C4ADF39F6B4CD3381E0BB57
-:105100006A1FB7639DBCC81AB4731EE6B60D76E479
-:1051100025FF64EB067E3E7F6B31E75D2E107E5EE1
-:10512000471ED1CF6519E32E2950D6B948BE3E1A85
-:1051300026F56349ACDCCF2379FE33C67566ABE256
-:1051400085FF38AD68A7BD989EDFA7B7734F9F3E18
-:105150000EF2D71292F76DB4BCAECA7BC4A6A932C8
-:105160002FE622F7F34C3D97CDF23DED5C3F5E67B5
-:105170005D1BEE23D7B139527FB4D4A9BC1FD7F23F
-:10518000FACBA953F1BD3A1BEFDE95D81BE4F97FAA
-:105190008BF0E31C817B7A8394AB6CE187FFB7E4EF
-:1051A0002FEFD463DE2DC976BA311F8A46A826F9BF
-:1051B000AC1C1B6792DFE9A29DE91CCD75482A89CA
-:1051C00080A74DE8666A7FFDB47E51FA60606B3D52
-:1051D000EB836151E7000B4C70399577403F89AB09
-:1051E0004CEF958B29ADEDB01EDE24FDD6F25DC9E6
-:1051F0001BB12F5E6291EBA1E99A7C5EB1573E171D
-:1052000022F6FCB9749CC7477CC0746E5BDFE74331
-:10521000BF1C0FECD6C0719DE60CD29744D1F2DED4
-:105220008D76C4D3C85D6E469CB43C4030FAF58997
-:10523000E61A9C1FB14AFAC67B5C5D9765B4CA4505
-:10524000C52E73BE55C5C177B89D91CF185D4F9ED1
-:10525000EFCA8EC07B82E2E57393DB9BEC88074D3F
-:10526000D33AF1BD14D1F79F95859A18CF6BF7A665
-:10527000B9B06F5B1175EF59A7E16E699FF4F83F04
-:10528000EE0D927E42835DC66DE3F75B78FEC97BCF
-:1052900076CECB658945DE1710459709DEF7B8BF96
-:1052A0008E19320F0D74B146D0255A8E40276B04EB
-:1052B0009DE60B49A7F9A44D820477849C45D2E76B
-:1052C00047D26B01FEA0FA057B9520F2DFA2E933FD
-:1052D0005F6B64FACDD7E2FD41D785E3A9B8E383DC
-:1052E0007AE8A71D19F29EC268FA2D100D2BB1EEB7
-:1052F0005D4076239CCC726177F23A4DF1C06EBB73
-:10530000F31BED36A9CF38CEDBF2FA3B3CEF5A3C2B
-:1053100034AB211782EAA97DBCCFDDBCAC8D3CDF6C
-:1053200029E764FCE4BA73562EA74D30CFBB6BCF90
-:10533000A5F1F31F4B970AD019728EB85E621BF766
-:10534000E621CE9778E1788DFD10430FB7FA75E628
-:10535000BCE58BF97FD171C2DEC3F538E12031C8DD
-:1053600094B77C11BF233A6FD9B0E32DF1D24E8EA2
-:105370005373DEC4D9C6E257555EA7BBA78FB7F0FB
-:10538000F9F157E57D77DA8AB34D904F2DC1C27A96
-:1053900070714257BED742D3E376463F59D529694B
-:1053A00088FF15C7B8381FBFB85A2D82FD2AA676C8
-:1053B000EE88762B9777CB825DF8F4EE5E8F0668E9
-:1053C000BE7C7A5B6A1AE2FE9FADB0A592E63CDF36
-:1053D000EED315E3B2909FF1D97D8EE9C136E85343
-:1053E000345CDA81F23B3F60BB75D2F27AE2747AC8
-:1053F000BF6CC5EE4484EA4A57BC33D8452EC5E19C
-:105400003CED9AE1BCBFBA610BDF07EDDAC0F709EA
-:1054100068484A6E8F7D8815CCF7458ADCAFBE554B
-:10542000097F7125B53B11735FE2F46CDC6E2A389D
-:105430004FE3ECA604FD3C5A35E70D9D88257F809F
-:10544000DA1F8991F43CB233C1C37762780259BC48
-:105450007E6B2FF7774A2D75D7019F6B52356DF80C
-:1054600020E011DC92AE723B3EB7AE55F7486A2B96
-:10547000FE61945B743B0D7F1B25FC6DE4CBC0DFAC
-:10548000060C7F1B25FC6D3CAF5C6BF6DF6ED7F71F
-:10549000FB8C7870979A662FFCDD4081E8ED673BC6
-:1054A0003BA1E0F7B05BAF4A7F6189E259D5C8FE06
-:1054B00052422DD69D3556E967073E91E7A22082DC
-:1054C000D04FBF50FB7AB09FFF50DC9D8FA1FD52A3
-:1054D000EC0FE5E11E53F2BD22E4F5CA734E1179DB
-:1054E000EE7634396191F0186786A9FD3857B6A970
-:1054F000FE27E97D4CF53F757B4DF0D5BD879ADAE7
-:105500004FF48C36C1D7E4FFD4D47EB26FB2099E7B
-:105510003A7E86A9FDB545C5A6FAEBA72F34D5CFAF
-:10552000D06E31C13796DC666A7F93BFDA542F8420
-:10553000FF09D0C71790F7AAD561FDE4C0FD2F4E33
-:105540002EA9FE0FC8631E4D22CDF7AEFCE5677C89
-:105550008FF57EE435D38C1B31C6E26F2B8EFF07AF
-:105560005DFE6347FAB60DE7756E03DF8B89D82DB4
-:10557000E46E1FECD4A0D6E79DAC46DCAA2143DE46
-:10558000876E6E7FB17623E2F69F7193C8F5AC3BD0
-:10559000739395F4D78821FB73BB21EF79C4E0594D
-:1055A00056D2372386EF7FB62BC1FEBA3B6771FD1B
-:1055B00015FBCFA0FE1F75C3243C55B06B72FB8852
-:1055C000BFDD84FC941157765DED91719136CFB7B4
-:1055D0001B25E88473E1A013CA30C93DCAFD24F736
-:1055E000280F90DCCF23BD564F728FF220AD33F1E0
-:1055F000FCDF689D89F2755A67A27C83D697281BC9
-:10560000687D89F2EDAAE95CBE5BA5F17BEF579559
-:1056100070F941959F9F7F54B594CB4FAA02FCFC33
-:10562000C3E1328E108F7B9313FEC9BDC97E17DF95
-:105630007F50A3DB2D51A7E7D5ECA7F52BE8D96860
-:105640004DFEC2D9BABF78F1F5BE557C11E1B74D18
-:10565000B6FA3E97FCEDE462BDAF3F2FF56AC7A0F6
-:105660004FDECB9EDA235785BDF3FF3989EADEB3DF
-:10567000B47D9FE43E5D5E3E1EE13B8DEF8D741E6A
-:10568000E2FD74770679ABC31956C07F65A08C5FC5
-:105690008EB436D4A0BEE63BE1C6BAF9A584F7794C
-:1056A0001FBC86DC659C3F56CEC9F5CA287DFFBE6F
-:1056B000E63BB97F3F0AB853FD4897ACAFB9992C88
-:1056C0009D17F521FEFE289C7696E7DB4C793B631F
-:1056D000CF358CE1FA78BB1BF9A6A39C61F93DA7F5
-:1056E0007021BEFC52C21ED9FF38D9FFA6EFC2FC02
-:1056F0007DAC3E91973DD2D98ACF32C6AF41DE37DD
-:105700009723DBD7E8ED4769D47F32F0F34BFC8A6F
-:10571000A9BDC49FF5DC287C3319AB6D591F9B2EA6
-:10572000CF278F3DA7D77BE4783B58258C3325A81E
-:10573000CF4CD1848FFACBCC141EC4DF46A536647F
-:10574000707B3D9F21C12ABF97E491F77175FFBB24
-:1057500026F7038800C0DFC84B32E66DE776E10C20
-:10576000F8799D17DBF97B99EA4E2FF4F5A75EAD2A
-:10577000EF08AAB73A2D3CBE1A9F3C2FFFD68BEEFE
-:10578000CEB85F74B2EEAFFF13FE5F81F7473AF712
-:1057900049FEE392B7CC5658994FFF0F6D93FF9295
-:1057A0005E242F183FF19FF9017EEAFC570CFAE8BE
-:1057B000FC3FCFAF6591F5BA7C5CC8FF90E4B72E93
-:1057C0004FA39C326F02EDC1FF9156290F35313244
-:1057D000DFE3A584C287714F16D1A608F1F991863F
-:1057E000BCF8E5F9E1FFADFCCFB3CA7BE41C654E24
-:1057F000BEA7EE52F230BB5914E2DECD8D03B57D6B
-:1058000098D7C5E7DCF580E78AD18570CF8DFAA7F8
-:105810002E52AF7DDD6C036C3C7F1BED06B5D65B75
-:105820009D6FC741EF19DF31DA7DA57FAFB5DD4050
-:10583000FE9D8D25E342EB60BFC6575B396E4D9EE2
-:1058400009C307C99EC97C4E5FA2372D32FFD373AF
-:1058500060711EEE0B95E7B744BCF4ABDDF41FF4AA
-:105860006AE1F745CBD19F50B75BB1EE388B7C5ADC
-:10587000FA4E61AAD93F1F1FB5BF7E55CE97EC8F58
-:105880005F75897BAB7F3742F7A7B345F67FF2DEC2
-:10589000D08747B07EBEBC7B437B8B3A9683B1C535
-:1058A000329F8BC66F1988B88D4FF801170ABF1544
-:1058B00072305ED45AE5BAD277A2228F57ED4C9F50
-:1058C000AB45989F4F24830263720D890FE097E3E5
-:1058D00026CDC47DC06372C774C7F388FBF3FE0096
-:1058E000FC2A54ED6FAE88FBF3F68F95F36DF1B59E
-:1058F00032DEB4DFD9AD4D3FF455B2B7DD7B802E3B
-:1059000082CB3F933DEE4EE37E85EC31E0AB7A57A0
-:105910000BBC57E836E71D19EF5FED1A23AC2917CA
-:10592000B777570FF86327D0F9B5E45E63C1AFD7F7
-:1059300092878C453CFEB5E40E16593AEC5CF67F36
-:10594000AE7B5BF819F3A3B5BF42EECFB8FF776C1F
-:105950007B79FF6F345DAF1221137D27E8F4FD11D1
-:1059600074FD087A349AAEFBF475C57EE73B7B8CF8
-:10597000BC29C493BB2F6F60F8569B9C07E5CF4DA5
-:105980002C405EF4E2F7647EC751A002BBBB7438C2
-:10599000E33F6AE95061CDE5FDA800E85DE6947457
-:1059A0003C19786900EE29AF4FD18E83AF5FAE53BB
-:1059B000F9BCFDC96762381E7724F86C22E869C813
-:1059C0007199EA5ECDBFA7F19A2AEF59FAFEE52C4C
-:1059D000DC2B7A31B92679FE7AC4A036E4399EE40C
-:1059E000B9FF85F22C36C97B0CCA9C856DF2D9585B
-:1059F00077BE30D0C7FAC225C2B740FE2B845C1FE9
-:105A000055385F97F754128C73AFD17ED5E0586A42
-:105A10004FF576A7CC1736F89DE990F75866C6097A
-:105A200017E22042CBED0B7CFB76F7C58DE4FCC280
-:105A30009CED91796BA3C2FD78DF79FC4195F3DD94
-:105A40005F8995F7B837123F14F24F7FD2CF1FDF2F
-:105A500095F8983C444B1B8971A9DFABE8F7F51E1C
-:105A60008A48E1F8796E3CAFB37FE47A3D6BA4AE2F
-:105A70005F068801FFF4F711DACB7B8417BF9A1B0E
-:105A800004DE8BABC9AAA5F2EF5CF03D7135589FDF
-:105A900067B7EA9D51A227FFFEC598541BE799FFFF
-:105AA0006FFB7D844CA1F1FCFBCFFE4EC278F9E880
-:105AB00082DF49C84C5C75404B6DFD9D8CE8DF4929
-:105AC000C8D4EFA7166E693F8CDF47B852F8382F5D
-:105AD0007F5CBAD9AE8C718D3EE0E2D21CEFC9BCBE
-:105AE000443ED74D23F5739D97E27BB9D0F92ECF75
-:105AF00075420EF4DF3B09423E8DDF3B31F86EFC10
-:105B0000EE494D7BF9BB27FF6ABF7312CD9FE8DFDB
-:105B10003D89E64FF4EFA08CD262994E63CAE259F8
-:105B2000AE0D3E4DA7FFD81FC0B95CE5BF9F5FF724
-:105B300047CDD3B362F520DC537ABA58EAF58BD956
-:105B4000FF695EDFEFA16FB6E97ABFC629E321BE28
-:105B50001AAB881925703F21E7CBFEA246DE03551C
-:105B60006395F18000F115F7E27D1BFB0F799F2310
-:105B7000F947B68E88CBF8F9FD80DDE9AAF144FC3F
-:105B80000ED652791EF89045FE9ED4EC1CBF82FDC5
-:105B9000CB4E5DB5A7A0AFD245D1CEF91C97F70F7C
-:105BA000817E9FF5274716EA677591F7478A1CF9AA
-:105BB000BB4106FEB332655ED6B323753DEE9179E7
-:105BC000587B46CAFDC0048F8BCF3514E7083DBF14
-:105BD0005564CDEA0F39FE84FDF816B7F4AB1B6DA2
-:105BE000F21ECBC0AB329F679DFF6DF6FB37935F14
-:105BF000AB4AFF66EDBD1C674814D8C77D2CA6399B
-:105C000019F8F75A2B4CFE429FA0D39497DC6FAB48
-:105C1000CB04F70FA59BDA5FB1D76DAAF7867B9B04
-:105C2000EA730F7A4CF0A0867C53FB211FF84CF0EE
-:105C3000D0C6F1A6F6C38F1499E05323BB4A3A416C
-:105C400026693CB396B882F25E7C1927E96297FE1A
-:105C500054CD6D723D61E4AF6BFA3C88CE5FEF6C62
-:105C600095F9EB76BFB46B5ABC5CDFBADA0997CA18
-:105C7000E7621A18C6DD109C371E30E7997772CAA2
-:105C8000F59565AC5C7FD8F53CF3D8DEF2DC8B9102
-:105C9000574EEB0A1FE8DD5D34CEE0DF2FD0EF1367
-:105CA0008D96E7BF8FD4EF738AC2BB8B5D9EA7AB87
-:105CB000B9CDCEFBE75ABCBD4949BC109F6E7A7E78
-:105CC000E46667DBF73E39474939BB21AF488CA210
-:105CD000768F92D962FFEB82FE3C8DD07735BFB2D2
-:105CE00073DEF8A5FA9B75851CCF4C8B65F6E41C1A
-:105CF0005E0FF23940A3DF74F44BEDFAF874398F7C
-:105D0000EA6F565233DFBB2692EC6EC8AF16BF92D5
-:105D10006157AC4856DBA07BEBB90C99A77FD3EA5F
-:105D2000D0BDBD08CF99F65A9BBC702068833C4C0F
-:105D300028203FD28BF8EB43EBE3891F8FE207EC7F
-:105D4000C8CFE8B2AFDDEC4077F899CD2C0F4844CE
-:105D5000C17E22FC4F75602BDE6BAE9479DFBE51A5
-:105D6000C2B8FF80F16AD1E3232D2274FEFC44A067
-:105D70000D79D3E2EBF91C826BB194A7CE11E7AC9D
-:105D8000B0FEFC9F3A2F21B0434AFDD86A853CE71C
-:105D90007809FA19E754DCB7D88A36C6E3BC881804
-:105DA000AF44D0E1892BA55C2E061DDACB76D04717
-:105DB000176B477E5F12F6175A843BC97589B8FA8C
-:105DC000FFC4F833AD32CE90E594E7453A5B35D663
-:105DD00017F6DEFA3D7717C8BBAE37F4385927AB54
-:105DE0009CF79D3C725E5FA8170EF0F7ED9ABC37EA
-:105DF0002D9ABEFC2F22AE629C5F891D2BF588A1D7
-:105E000017CE9F43E921D7A1365D3F04BB5B38EF36
-:105E1000E0AE04F33C7E7C94A46FA13E8FC9CE27F4
-:105E20007A079BF484C0BE5ECD0A95F504E9C97A71
-:105E30008DF02CC6BD2CAED6DF7BBBF90169C74601
-:105E4000F98A1EC4BEC99C3536B181F715E4FDB090
-:105E50000BF438797120EA7E16DD1F3FBB5A71E1E1
-:105E60007720E6AE32D72F88FFE213AC1F6F8EBECD
-:105E7000A7C6D8AFBB441CE0FE51BAFDF7088F9E01
-:105E80007FBF0CF89D0DCA7BAFCF9F57D2E33F2D4C
-:105E9000C167257C87E07851B45F60C06EEC9345A4
-:105EA000DCC342F48DED0DFBBEDCDA667EA341DF80
-:105EB000F3791EFA3E1D95CB56F07A46E637903EB2
-:105EC000E07DB913540F3FF044E00CB73FB12B868F
-:105ED000F34A4E7A1B0660FFD6D8A7EBAEC97DAC5D
-:105EE000965D0932BF21DE22E1ADF21EFB457F0F38
-:105EF0000EC03AB631F0ACE99C83D668DEE78B2E53
-:105F0000B5EADDBCDE3C9CA7D58D427EBDD5E3F471
-:105F1000107C77FC7EBEA76B02AD1FA1D79097B215
-:105F20002255E2CFFA2B7046D2CF2FE9770D397A7E
-:105F30009C9F27487B228E2968554B65717828F7EE
-:105F4000FF63F7C1A69EF3CAFDDF73C3F97D6DD56C
-:105F500050867B079B477F40FD5EA7C5BB1147BAB4
-:105F6000B6E617E362E9D38DBF8F5FC16567F3F9CA
-:105F700001A3FC58B7238DB6B6EB27E8FA67E19585
-:105F800086BE96F2BEB85AE17DB5C59071C0F7CA1B
-:105F9000FB390DF84CAD0E8F93F092151286698285
-:105FA0001F3C47FFDDB32D7AFC05E34789F1232E23
-:105FB000B05D8FCF60FC28317E3C87BE020C7D0532
-:105FC00018FA0A30F4154AE82B3CFF3C790CEF6BC9
-:105FD00063DF6E6CC47CC2BEDDD888F9817DBB48AE
-:105FE00018FB7691EDB16F17598F7DBBC87AECDB4A
-:105FF00045C2D8B78B6C8F7DBB4858E4FFB415867B
-:106000005EF34D36C153693D3036623E63DF2EF29A
-:10601000FBD8B7337D4FBBC5F4FE8D62A9E97DEC9B
-:10602000DB45B69FBD5431EDEB09D1CC767DEEDA80
-:106030001496A3D7BC451957B6E7DFA9FA99AD2B3B
-:10604000EB078E632C2E8FF5487ED78E97FCB7C852
-:10605000F3114A33FFBEC0993BEC121E67CEDF3608
-:106060004AEC7B8DB5C97D2F94D8F742897D2F945A
-:10607000D8F71ADB43EE7BA1C4BE179E63DF0B2566
-:10608000F6BD5062DF0B25F6BD5062DF0B25F6BD75
-:10609000F01EF6BD5062DF0BCFB1EF8512FB5E78CC
-:1060A0007E88F09817A1C7E0AF7737AD33490E4D22
-:1060B000EB4C970986BF1ED91EFE7A643DFCF5C8DD
-:1060C0007AF8EB9130FCF5C8F6F0D723E11B46B91E
-:1060D000799EC16F8F7C0F7E7B24DCBF36F067C456
-:1060E000D626AE3B7500656382F228CE1BDE70E5D6
-:1060F000B6D9D8BF6C8C51B29249A7DBAA77CC1E17
-:106100000B7BABE73F0E10CD16E81F0D8BC93C3E55
-:1061100067C879A5FDBFCBE0FADBF5FB11F81FF1ED
-:10612000DDBB4BF0EFCE18FBEDC6FB1E32DB288D3E
-:10613000F6AD70DBEDA2FB37DA716E55041E38D177
-:106140008CBC19EF1DF103B10ED9A2FF8EF096653C
-:10615000322F3A5AAE7EABEBA72D969DFB710EA661
-:10616000B958F1E0DC47F75A8DCF99F59F292CAA51
-:10617000B7753CBD1E4BE4BCDA5F5C29ED9181BF75
-:10618000111F257DC1E7074734378C49A2F65A60B5
-:1061900034FF0ECE04BBD07F2FD83F0CEBC97E015D
-:1061A000C5B73142CEABF5EF690189C7138F4D9268
-:1061B000EFC5CAF79E782C91FB9FB45CE13CB3110C
-:1061C000DB850FE794EFD1F1EFB73DACA2BFE2E57D
-:1061D000B23FE3BBC5EBB2EC38CF6DD0AB58348ED9
-:1061E000C57DD2224FC19DB2A2A75563BFB4C34C97
-:1061F00097057ED0E59E831A99973C0E7988A24E2A
-:10620000F0BDA113F3DE328D97C93518BF6B2A7824
-:106210006DA8056EB1A0DF49448014C49309C67807
-:10622000344DF8B389BED74D2F667AF79E2914D026
-:10623000BBCFCC0D96547AAF9FF69205FE5AFFDA8B
-:10624000462E8D71784624AB8027D85CE380FF848E
-:10625000710AEB8FE83C1EF8070C2FB7B13D37FCF5
-:1062600087C509E7F37CFE8A3C9F33076D9CE77383
-:1062700066F959AE2FDE1DC3793DDA5A85F59AE1EC
-:106280003718793B65B7BC3718F439961DDC92DCBA
-:106290008DEDFC1FAF441E4BD79D89381A7762F9EC
-:1062A000EEEBE0529E59BE5BFEFEACBEBF63FC8EC1
-:1062B000A9C8F1713E98E1070AB5CE1EB98F63FCFB
-:1062C0001E1AE94F6E7766AFDDC5BF47A7FF7EA9EF
-:1062D00011F729FE4B6E3DE85ABC5EFE9ED99C55D7
-:1062E000F7154E2778BECF19C6EFA147E7632D8C6F
-:1062F000F2032FF5FBA5C267F6FF2EE6EFFCFFF2D7
-:10630000BFB7FCBF73A5703700800000000000001D
-:106310001F8B080000000000000BED7D0B58556539
-:10632000BAF0B7F6DA37606F5C080AA8E002454DAC
-:10633000C936225EBA2EB9282AE206C4B441DC204E
-:106340002676AC21B3911ACA8D7B4348D6C04469E6
-:106350008ED5D6D433534DD1654A27EB6CB59A2EE2
-:106360009A263975A682ED25B53BE9F1D49CC799EB
-:10637000CEFBBEDF5AB2D776836633E73FFFFFFC22
-:106380007B9E66F1ADEFFE7EEFFD7DBF25136D06B2
-:10639000369EB1337B459F98C258C5BE3DA52C8E15
-:1063A000B1533526C6A05C562F322CB367992F4DBA
-:1063B000C0728E2102CA657F501C82CCD877ABAAEE
-:1063C000F7BF064DF7AF823616C68ABF1FCC5826D8
-:1063D000631DAB642A977E3F86B158C60A0211F44A
-:1063E0007EEEF789F4BCFEFBCBE87DB10DFAC1FC73
-:1063F000811DCCB71AE63BE5B650F9D44EE6C3F999
-:10640000F1173781B111F8070C99C1A43C368CB152
-:10641000D18AB007BAB359DF5F45E3CDFB3E83C6EF
-:10642000BB667C45C300E80FBD1D69D07ED6F8F77A
-:1064300072FAC17A5DEE295922948B8DFE39387E2D
-:10644000B1C3C4DC29F8FE564302D417325613EB0D
-:1064500080F650C6FDBA5CAC468861ECCE89D06946
-:10646000009459CDEB03100E5B98632BBC9AE7AAFE
-:10647000C8C67663CA9820C2D4E551ACA61DF7629F
-:106480000B64155DCED80FF8BB0EDEE322AFC4C59A
-:1064900027BA14A82FEF077F0EA26D29CCCA983D0A
-:1064A0009DD75FA924BABCC3E1EF96758A7520CE4B
-:1064B000C77F43CDD00EE611EF34FB5603FC5D36AB
-:1064C000EB61612C54B8F394C028DEE68754C6868D
-:1064D0004D823FB2E05C0C86854E9867C18A0C7392
-:1064E000657ACF3ACCD9D9F3A6C03EF2F0BC61BCF4
-:1064F000E56B4C3E4B0A3ED3E299ADA75DE87311C4
-:10650000C0578EC575076E17003EF314A6E4C25C33
-:10651000F399B62FE667B08E1BD4B2D7AF049A6C4E
-:10652000040F2ACFF18F70B9611D375B03530193BC
-:10653000D8CFD36BF2130D8CBD61E270B5985CCAF5
-:10654000605887697B867FB08CFB90E83D330612EC
-:106550009D76D8C7DAF6FB46C27BAF22F3FD995B86
-:106560004C0C07623E9313E0BC289D293E84BB91EE
-:10657000E3D191352F3DDD2CF4ACFF8889CD6B0F35
-:10658000B3BF3AC540F36C03BC954732F6DB5556B2
-:106590007A3EB14A6232A0E053AB12A8FC34E0313B
-:1065A0003EDB578DA2F7CFAD7250F9855593A8FC0D
-:1065B000E22A85CADB57E5D3F38FAB9CF4BE60B407
-:1065C000EB1605D6FB9041397C0FEC6F90D8C210CA
-:1065D0006FF1DCAD137ACE37A2E5BB0A3C8F2A9B64
-:1065E00059C6755701685CB08F4AC5EAA8075000C4
-:1065F0006C1B13A05C2EB2EE6647B873E7707C6C20
-:10660000FE7F2D3540BBC7EE8A24BAD5E057663EE3
-:10661000F0BA35A5077E1FD5FEDAC40C746C69325A
-:10662000CC7B434D84A33905F1C3E9C1F546A53BB5
-:10663000CC2E80D7BC298CC6BD32D5D988EF6F5EF1
-:10664000BBEBD10FF0FC76A6985D709E15DB331A7C
-:106650001364ECE7BA5781761536C98C78778B3797
-:10666000C62CE3F9C7033D206EB3EEE4627B0FDC7A
-:10667000B728028D7B7D361FFF1B3C1F6AD7622A1D
-:10668000D2B5E3E7733E3D1C9882F0F200FB581D43
-:1066900083F4F0E2143C77E94EA091C9B01EF63EB7
-:1066A000D59B1398E489391F5E83D90101EB13014F
-:1066B00096EEC93DF06B1E55497CCE043428C604C5
-:1066C000C38F113D85E2CFFBB80F804BE50A6175A2
-:1066D00003CC5FD526FA0401E9ABE00DA2AF564129
-:1066E00026FA7A70983991E84D90907F15F497A723
-:1066F000C643FBEEFB0469B38CF40A738DEB19B748
-:106700006AFD64A2B72A1F3C337BA7CB9FB5EE4935
-:10671000DA21E3312A665C6795A498FB07D1FBA2D6
-:106720001681E822B4FC9A22723A626F9A106E6562
-:10673000C365C19381FBE1F8B160458AB9D286F5A2
-:10674000CC6F807515A4B237B05D772BAC3785CF91
-:10675000332E68DC4A1C37685E68BFD009E57715C0
-:106760003BC1B54292CD8928572489D657B9629743
-:1067700009E1B308E02C64203C1C661B8EBF14C6E4
-:1067800007F8DD20F9F3B0FE867499D5C339547A41
-:1067900033CCC89F5C6BF93CAEA618F3E550AE3025
-:1067A0004AE624289745323A37589F0FFB57013C59
-:1067B000FADB705CB610654B285C2AD4F556B5C47C
-:1067C0009817EBDEB79AE474E26B4A387E214EE10B
-:1067D000785BE92D4A5E87E7EDB64B44B746C5ECDA
-:1067E000C075A9F09DDFB6CE9412D4FF5B158FC59E
-:1067F000291CCF0A52FD6902EEF7D60807AE77BE14
-:10680000D46242789E83F3831C0E8B257F1A8EBF41
-:10681000D8CAE1700E3FDAF4E7DAB33E0EEFAAB65B
-:106820000AA2BF1B8DCEE475D0FF4658A71B9EF36E
-:10683000D7EF4A13F009F42E207F905CC9CE207A5E
-:106840003BFEE0F5C9B47F583FC2DBEE90A722DFE4
-:1068500001BC21B9ABE14F7926A76BADDFE029463A
-:106860009A77F0944BA3D7AAB5EF51FD22A0579485
-:10687000B766F68280F5666084E1E837094786F6F8
-:1068800036C01F77620FFDCE6781F9C85F17AD2D47
-:1068900062AE20FE03F2B6E6B930F09A87EBCD2265
-:1068A000B945E70D74F81AEBDF539FAD9E7759AAEF
-:1068B0009EFE713C1CD7A1D567FBD36E4DEF69AF2F
-:1068C000CD5BD69FF7437A403C74A8F0C1F6CBA9C4
-:1068D0003D2F833C5EDD80FCE13ED16711F0F9780D
-:1068E000C3402C3F0BD216B6F6C5F297DE9D0BCFF8
-:1068F000CF1FDA548EFBD3D6B118F41DE41337AA98
-:10690000F2B9CA1F9E5FFC6292EBBA295941F8F3B3
-:10691000C0EF4720FFFEE2E977D210CE1FDB39BF80
-:10692000FBD9EF1F37B1D49EF55736BD67AAB00526
-:10693000C38BF3BBE65107E9FC168DE2FD1679BF68
-:1069400025F9C5407EA5A59C7FFE15DE6779FB5A1B
-:1069500007B577D9FECCCF7F1093C4C40B9FB77611
-:10696000BEA1E7FEA8C9E94F407D34B54547FFA168
-:10697000FBAF50D75D3585F3B71B543CBEA1BA952C
-:10698000FA5536553C8E7AEF7C8D7EABF4EFB5F33D
-:1069900039B5D644E7736A6D5A23EA8BA7DAF9F959
-:1069A000FC8BD83E7625B4FB62D9D65B1253492FB7
-:1069B0004946BD04CF07F5D21B55FD74099C0FEA6B
-:1069C000A761CEE736D4CBB4F292C7F8F92C7A7A25
-:1069D000DF277F9409FFF8FEEEB3F890FF56B63F2D
-:1069E0007BE84A783FBFA9D59402ED3C5352083E5C
-:1069F000E7F87C4D86C4A2617F4D9B4CC8073CDA0A
-:106A0000BE43F05C832B33723EF328E8F0CD315C5B
-:106A10001E09FD7BDACF674A3CF211E61EC2B6C6FC
-:106A20009DBFFEA7553A2A48759849AE3544B1CD69
-:106A300012AEA3E27E36B677F9753482D305485D8F
-:106A400005E9F3E8144732D285A6BF86B6DFAAD29D
-:106A5000D7E0A8F6F9B8DEC1B120DF01C4BF895480
-:106A6000B251EFF9CD9556C9E3C0FE2E19EB2D5664
-:106A700026A17CDF6C90C7117E827E7F4F22C232BE
-:106A800090857C6FF8B2C0B7B83E44A78871FC69A6
-:106A9000877DBFA3C20B55F181FCBD1F9F49C67600
-:106AA000E25391B51CFF42F50CAD5FA87E11AA57C9
-:106AB000F4B6BF3D17B9BFA3292E1FC98908266D9B
-:106AC0008EA1FD2DC7F2B9FD8D628A01FA97FFF202
-:106AD000F24DA84F1EAD57769BA1FEE81D36EAFF8A
-:106AE0008FDA6FE83EE75755E8F6798E6E5A44B272
-:106AF000334EB56426935D07360F83FAA3B7461865
-:106B000010FE4753B8BE0016A01DF5C46DAA1D891E
-:106B1000FA383E511F6723B93E8EE5A755BB12F5E3
-:106B2000717C7F5CC5BFB248251AE57277BD5DDA1E
-:106B30008CF0F073BAE9AC1D4670003D81F36355EB
-:106B40002FE89402F6FE417C1AE4C77D28EF58ED49
-:106B50003086F65D67CB51BB211DF192AF4F6BBF05
-:106B6000C2D4C2EEC0760F0BBEAD306ED48AF7F23F
-:106B7000E2514EB7A56408D06F41ED69E2870B6C16
-:106B800003658672DCE66A9C88F5EB53A4D5D02DAC
-:106B9000AA2DA3B316FA2FF68E24FB798520937EB7
-:106BA000CFEA05B22B996A1F2CC1BFA0BCC4F6C6A0
-:106BB00070955F1A905F2EBAFF8EC644281F36B0BC
-:106BC0006E11405360289A8AE5820D310E0FCA5B20
-:106BD0000FDF0FDB087CD4DAC3474F4F72B26CA4CF
-:106BE000F7B3806F30FE68581BDA512B4CED0AAEBC
-:106BF0009F81DEB195E17A9DA4C7AF52F1A2B3EDBA
-:106C0000B05D56CF07F5F3E1AEEEC3F7E0B9DA0CAD
-:106C10008E6619E5BBBC5F46B8BF2532D4678733A3
-:106C20005EBFDCCEEBE149FAF1F24DA28F917E5CC2
-:106C3000363080FAD77A91F8E2E24D250351DF58D9
-:106C40000C65945F1B702AC0A7C6B61CDEAE35EF7C
-:106C50002137F0D3648139911F1D33068A101E2716
-:106C600037C5F7AF477DEF66CF0806F5559BEE4970
-:106C7000C6E7C94D11F3908FE74A45B931A8FF6CBB
-:106C80008CC940BB5FA3B3F46C2E0F6EBA39271EBC
-:106C9000E5DDB2BFEF795402B9BA187054423F48EB
-:106CA0007B94CF0D4D96ADDA9E2C026AD9E35C231E
-:106CB000116EFF62D8397732CA61C1B72D91DACB34
-:106CC000F1521F76F371B42B014F6FBEFB431AE7ED
-:106CD0002BC3DEC2F9D07FD9CDCF47E338FFF260B6
-:106CE000C70409DE1F1BEFCAC4F13F17366D93D0EE
-:106CF000AE5DBF692CCA8FF1AA7D54D0DF39773ED3
-:106D000087AF63B3DCFB7CD5DB0582A7565EE0EB87
-:106D10006766A897FA9959C2A7C4480F3E29B25A84
-:106D200094EF9A5EA2BD9F96CDF9CFC97E2DC9780A
-:106D3000FE4BB7AD4B46F9F1999D975D5BFEB4F8FC
-:106D40004E5887ABCD2031C03B979191DEBBC8CD6B
-:106D5000F569560DCC24B167FEA2EC2882F3D2F57A
-:106D6000993AB9878E197CFF9991E5E33A867ABA08
-:106D700033507FFAC8E85F8CE7FA11E8A7E8974933
-:106D8000CFE6F8F7518B3815DFBB57080CFD4F1FC6
-:106D9000B53C6F1FCEFD28E4C7602F9B7C5BA1BD77
-:106DA0007D7CBB1FF9DECD2FC48C4330E689E9F131
-:106DB000883FCB7798A60EE6FA145AD36C99D16F18
-:106DC0000E776E37A97AD4B9F20BCF9A11EF973DAF
-:106DD000D54A7E0550537CA8DF2C6B7FF68D413061
-:106DE000DE2DDB2B32711EADFD2D2F703844B080AF
-:106DF000B92448AFAE18D5BF7130F0C8E5D9F9AEA7
-:106E000007511FC273BA12D424655245BD119F1297
-:106E1000ED9319BB491F07FD8AECEB9BBD7CBC9B26
-:106E2000471D6C4CA57D15C5B2A0F3BF2DDB44E713
-:106E3000A5F5877D533F8FF5EEC702B05EC563644D
-:106E400011D742D9C83EDE86F063D1D256DC879195
-:106E50001D7B039E2BC57EAC199E1B6B96FF2BB52D
-:106E6000AFB748223C3D37D73D1380F964913919BB
-:106E7000F47767D7D0786E33973FEBA29E7EF846C3
-:106E800028D7CEB13900BDA11C4DF0D9F90B03F1C3
-:106E9000F944D6BDC700CF78065404001A92EA6AB6
-:106EA00021BEC3383F5E799BEC437E0C1C5C403CAA
-:106EB000FFE6951399B8EE6B87064E235E99EAA715
-:106EC00057E402FDAFCF56E1921EC8C4760376ABFD
-:106ED0007CCD7880E4A32941EE8FFA8A1FC7C2F5E2
-:106EE000FDD54078B053F03F8EF36A70DAA7D2FB3D
-:106EF0007319AE4DD9F05404D3ED7E683F5B8876AC
-:106F0000E07E0FF417D3C60D433FC4C72938AE1B2C
-:106F1000D0561CDCA3C766AB4B370F9AB41EE132C8
-:106F20000500CAAE065B26BD3F3342F95E66E8B691
-:106F3000C03AB2BBFFB2A91ECAD2AFFB3111449511
-:106F400027229965C3F8C26ED828EC6777FAEE4518
-:106F5000B8CE7BBBAD0CE1C4AC7A3DD76C48F4FF36
-:106F600012F1B926DAC112500EB567203F62B7D8C8
-:106F7000C83FB3E06C20EDE72897FEBA97F4F49F82
-:106F8000A5BA5E46B80E1295C32EA8BF57F20FFBE6
-:106F9000158E5F1BE5A8E7728405AF7FE71D7F8D27
-:106FA0008E857EDF748F303E03EDBE51AC0EF4E76C
-:106FB00075DE39E6B5ABA07CB52A4F42D7F54D82D8
-:106FC0006C44BBE39B6EAB1FF5906F6C06F2736471
-:106FD000EFDCF321FA21B3AD36BF188DFD4C5F060F
-:106FE000CB1B762029E6F8181231EC0780E74055D4
-:106FF0002E5DDB4F6F3F7666733BA853E53F46D966
-:1070000041703EE536B266C44306659CD768959AE2
-:10701000617DAFDAB62D40FFD5A9EF53FBA1DC3877
-:10702000B573583F96DE3B5FEC407D02F484884C9C
-:10703000E5533C7F4DBE96AA708968B9DE84F0F0B6
-:10704000003CD0BF566A33F82DE85F9DA38703ABA1
-:10705000ED2E47BC61866807D20D9E2F9EBF2C186F
-:10706000BAD955E79FF7756725FF2FA1BC00CE134E
-:10707000E15A7EEAF8E5BF62746EDFE23AE01C1B7B
-:10708000AE603DE7F7BFEDBC98D1D184E7B052B414
-:10709000B7E039788C5CDF73036E6D8DA16EDBF029
-:1070A0005C567A86D3390DF4009F403B0598DAE6AA
-:1070B00038E42B07A9FD56CD9F36AA86F84CB9C7F0
-:1070C0002221FCBE8B8CA6FE0CCED534281C9FE161
-:1070D0007CA5B68A115F59985E23E0B927E00CB011
-:1070E0009F4E43C08EFB0C44801609CF6B725255E5
-:1070F000FD1B3882EA67C5FE8FDC61DF8CFC46B47D
-:107100000E7EE4188822D6D41D3D1AD6D526B07638
-:10711000DA9749E51F4B6DA4CFB5C5F888BFB59583
-:107120000E71E05EBF616A7D7524F197AB0C062A93
-:1071300077CF1F48F6585B0CB0561C6FFE68D21B09
-:107140005EFC3B8F9774A7315E9FC146ACC7FAA225
-:107150005134DECB1ABFBACF4EE3B515298991540D
-:107160003FD080FD5B535C137388AE793B503CA8E5
-:10717000DD860D4A229EE7866233B57B4870CE5F7E
-:107180008CE35C6E23BD31303FF2E96DFC38FDE8E5
-:107190005FEAACE5FBD6E840F3AB0F751F7E18F94C
-:1071A000873B1B4E04ED43EBD70B10AF1531DA01D3
-:1071B000287CDE397F770ECF59370097C545769208
-:1071C000BD2EA73104369C9FC4B2114FF6003CA1DE
-:1071D000BDDB04E71CC7CF79751C9E73E1A6E07385
-:1071E00086F1DC2BE1BDB03CDA214CA2731E85E3B5
-:1071F000D7B24807DAD7E7CEEF555F063E4583237F
-:10720000C102B0F83CD5353F27AB478E3CF209ECC4
-:107210000FE0526E0964B5A07E6E60D5ED61F8C0D6
-:10722000A21C6E1F48ACDB84F275A186FF7521F8A5
-:107230001F1812733C4AC57FE8F74ABC73319EC3DE
-:107240005742C7047CB9F76FE2BC70E3DF9CC3F917
-:10725000D68138E7325CDF70E3EE21B7A1BE7187DB
-:1072600085F45F7676CF109CF77729CE9FE378116F
-:10727000C3BBC9BFDE99D86DC2FD75CEFF3C09F511
-:10728000AC85B57F22FABCD8F5AD8E1A6B42B91920
-:10729000939F610A40FFF8FC8CD7F15C0ECEB2C818
-:1072A00096307E905DB32626A13ED4317D6212F2E7
-:1072B000CB8E245833C953871DF9A869FBE5765C4A
-:1072C00067477E26956526ABE5923EF9EB17C05FD2
-:1072D000FDA0087C06F61A3E4F80BDE6077EFB291E
-:1072E000D86BF83C0AF61ABE3F0CF61A3EBB56396C
-:1072F000E87D47FEB0ED8817675AB81F6591D11138
-:10730000562F5BF694C8FC1A7F83FF6EDA12A52B0A
-:10731000576F8CD5956F6C030CB2F694ABD60ED329
-:107320009535FDB3D23B46F7DE5597A92BFF3F03BA
-:10733000DF260E5FF497FF6F822FFED682BC2BC133
-:107340003F00BFF7654D233EDA21B09A5878C64812
-:107350009CFF199D02F9DDF0D70272BB18FF00BA3D
-:1073600031DAE406ACF742FB5F435BB47DD1FE60EB
-:10737000CC61AA80F7A5F91112CAF3B9AC86E86C02
-:107380001E6BA1E70DAC9D9E65EC003DCB19A7C31C
-:107390006F2A0213F0F9719CEB53A4D36556D7639F
-:1073A0007168B725B946C6223FB2F527BBB4B7739B
-:1073B000420D9BA97AAE6D82BA2FF8CDC1B543BFFD
-:1073C0008351636FBF5DEE99471B1FE63B8D7CE3E6
-:1073D0002B139F675FD6C424E40FCC3940674FF569
-:1073E000365FAB2A272BF2399CD0678BE563A50269
-:1073F000C58B77B55ACCE85F38B6C6A4EAEB77936D
-:107400009D7BF810F7CB1C6B98968CF857DF3A32BF
-:1074100019F1FC98496EA805F81F9B0CFCDB417E16
-:107420001C07CA8723F976EA0F92223A03CE6D91A0
-:10743000BABF23B2C37C07B42F4D1499DB81F1F49A
-:1074400094685CBFB6EFD07557AEB5E8F060F6242F
-:107450007DB994997BF02D05CFDBDC538F7A925860
-:10746000D6CFD587DD5DFBF1D2FDAF05E16B72AE06
-:107470003D0EF51A36914DFC41ECE9DF1B7CB57CE5
-:10748000060DBE1A5E7D9FE31C999B45AF29DE86E3
-:10749000717494C71DDB391C5BA3AEBDEF2A80431A
-:1074A000F1FB22E3702E777F84F8BC83FBF543E782
-:1074B00009205D8F447AE5745DE17D8FECB78575B9
-:1074C00045265C5FB1AD3B09FD4EBBEE1A9984E7E2
-:1074D0007270D6C824E41B7BA68F7C64058CDB55B8
-:1074E000203A2C804FBB0A4EDF87E58E3A51C27995
-:1074F000BBB69F56F94BF7BE89B0BEAFF34D24879C
-:10750000BAB6FF73F84CF10EE03330FF191FE733C2
-:107510004B8C4ED608F32E01B8A01DFFCFE63717CF
-:10752000E233074DCE3CCCDBE8AA171CE87FAB9FCB
-:107530006E21FDE120D08785E353C30AE49393C015
-:10754000FE9510DF9C596853766C1F3600E1C5DC50
-:10755000CAC151137AF07D51DD9202F4AFB3B5A6E2
-:1075600023A877A33304E57331331E0904E1A9EBA3
-:1075700005534F99F0DA78241084D7A1787A1BE26A
-:1075800069540F9E9E616793CDA9BCFEC0C01EBE0C
-:1075900087BF60FE728BE86FC478BF86B7FF39FD86
-:1075A000BD72541280AFDC9D0BF8FB8B7129AF04C8
-:1075B0008420BE72917CAC35EAEF24F7D645FD9D60
-:1075C000E4DEA1E95CEEED9A7EFDEEBF20DEDFC5D4
-:1075D000F1BEA37422E1658709E419C0EB605D6622
-:1075E00034968FAE2D213AD3E827749E2E15FFB521
-:1075F000760B8DDD264718FC74D589BAF34C7B6178
-:10760000413FE7E5BDAF5F1B576BA78DBB3024AE95
-:107610001B3AEE13B9DC0E4DDB52D6E7F86000F6EC
-:10762000F4A33C94C81E7C15510FB89EB9013E5D71
-:10763000F91C3E5D05D7133D1ECAD7E8D2C5301EE2
-:107640007B708EE843FDB52BFF34D1E919A0531AA6
-:10765000A397794FAAF4795CA5CF632A7D6AF5E2F6
-:10766000D607E7DE80E3D689C4A70FCEC91C80F316
-:107670007DB6258DE685F550DED15BAF2DACAC1F18
-:107680004EFCC18EFCEB10C001ED8492D212B2A769
-:107690004B4C8E01E1F484D07D878EB76B9685F2DA
-:1076A000C8603CE277C57795B046E40B0007C4CFCD
-:1076B00043D81EEA8BB7723FF01E6C1F170CA791C0
-:1076C000A4AF1CFAADE040D161DAFE373B9EC35255
-:1076D0009F9E5F2C591FA53BB7C52DB1BA72F1749F
-:1076E000BE8F4375C30684CB6BBAD0F969FD2FF604
-:1076F000FC6F52FBE39A7F203DA5BF6E3C04927E57
-:10770000BED490FAD121F5E374E50BE1E361152FC6
-:1077100034397238425E102EBED45568A90ECED3CD
-:1077200088CEE3764B749E1AB7FF917235224FCF05
-:10773000AF2ED45FE34F9FE738A53C94A3FE12CA57
-:10774000DFBA587E14248713F270BD01C18CFD5B33
-:1077500055395BDDCEF16E5DD4FD947FF395AAA71C
-:10776000035E12BFFF5AE5F75FFF412DFF5E20BCAD
-:10777000DCB3636534EAED27B68F8C463BEC48BB3F
-:10778000271AF9BECCDCD157023E7EE904F909D3B1
-:107790009D6CEF5B7E7EA6F29D13780E2437253A12
-:1077A0008FA3AAFC3C8CF293E4FD287A1E44F909CD
-:1077B000F5739E55F5F4DF0A44FF4B8D2DE1FDD3A3
-:1077C0005BF4FCAA7A6354889CD4CBCDAAB58375AC
-:1077D000E54AEF305DD955A7979B796219F1F5130A
-:1077E0003E0EC792FC4C5DFB13B21C2D117C381C65
-:1077F000BE36C9D18867477CB1D1C1F4A2F1DF831D
-:10780000217038867040FCF496F4892747D5FE5ADB
-:1078100019EC4213CE5B6275BC1E877E84B5820371
-:10782000E35498EF3709CEF1C09C8CC79B83F48C4E
-:10783000F7F344C297C3DE3DE5987775060C30F444
-:10784000F3FEA96E4F32FA572B9E8A22BD2974DEB1
-:10785000AA023D9FF9B2A128FB23E857F2BEE8B384
-:10786000223C0A62887FCD7956F48950EEAACB89F2
-:107870000EDEC709950E35B9B3C45813F61CAB37E5
-:10788000EACFB1A4A09EC6E978506817FAC173D7B1
-:107890006490A4E7F72B31F2FD2F794A24FFEE1212
-:1078A000EFB7FB30AEB804F4405413FED4E42944DF
-:1078B000BC3EEC3419889FB6C716227CDC7344CAE0
-:1078C00083DDDB348CF0FC4853CE409CAF4985D33C
-:1078D00089ED168370053C9D26E6277BD54FE7F999
-:1078E000A5B784E4C609840BEA414689E8E2813CF5
-:1078F000EE973F0CE360BD01E804F5E12E9F98EFA1
-:107900000B431F0FA8F31C3DFB2BC29F377C7BA2B0
-:1079100051AF38DCCEC73F5A2745637CEA1D6FA6BE
-:107920009DD65700E3A2DEBBE37A929327BC1C1FCF
-:10793000719D641F3671F9D1E15D74FF6480C75792
-:107940006B45D23BBF6A2A299C8CE7BDD644E59C97
-:10795000A2528A6F74F8B87C39E43B5A8EE777C23A
-:107960000BA70FE5FA1D13F78D8FC37336113E5425
-:107970003DA53F97D2B57AFA825F74C604CACFA4F8
-:10798000B82CA81353D14EAA4C00F909947BB8A087
-:1079900084F22A8BDD7A7964614526C43BD42FB109
-:1079A0005DE52325597EA43FB740F272E10B3CEF21
-:1079B000DAB4E56A9277152D16DDBCC5757AFBA899
-:1079C00032C41E0AB5977EB4BC30D5948793171D78
-:1079D0009A5C60D25484FB1130AC9B33E0FD0B22E7
-:1079E000E5239FF14610FFAC5878EA1A552FBD16D3
-:1079F000F18039DC6C9266A707D159A5570CD1D319
-:107A0000F5F005FDF938EAC74DB1AA1C759790BF8E
-:107A1000EEF31CE510F1FB8BB5BF2F5ABF2D57F5C8
-:107A2000DB72D26F3B4A2D94AF79109B04F5DF5582
-:107A30007A3DF9750ECDBA9EF4DC43E7FC3A4ED59B
-:107A4000AF730D9DDBA102C067921B0EADDCA71EBC
-:107A5000A1F18B4FD57338AAF2C9C32A9FEC52ED1E
-:107A6000AD46555E78557971A840B5B7E218C90B97
-:107A7000A3516117C3676E6C8B0A910FB12176D445
-:107A8000E090F3D1CB8B6545AEC8A940F79684D181
-:107A9000BAF726699CAE9CB66527F98FCFC83C9F84
-:107AA000E81EC4098C9794F2FC2C666D27FF71A91F
-:107AB00043A6FAC1182784F66852611E89869FDAA8
-:107AC0007B298EBFD7CAFD61D7F5D82EA59DCA9E4A
-:107AD00052C6300F66B8360E80A31EF484C1E8C7C4
-:107AE000867912C040C3F61ABE0F99D34AEDB2ABE5
-:107AF000992440BBF4A929C4CF129842FC65E03216
-:107B0000A660BE0BF33D4FED1EBF1BF601781FF0C4
-:107B10005C47767989359AC7BB413EF68D67F53C5F
-:107B20007E991F4B7ACB102347CD5EF1566D77219E
-:107B3000BC0DD283264F25FA34903FA2356AAC099A
-:107B4000F1B4D8E624BF01E0F582DBD15FF98A9970
-:107B5000FB094AB97FF2E0F4898FA0BD3BF6191BFF
-:107B6000F9920F2E067C26FEDECDED84BA1237CABE
-:107B7000BD3FE7733937E6992FE97E44D776E6C0F3
-:107B8000F29EBAE74FBD8DF43247203BA3A32E8768
-:107B9000F365C69C98BFD9919FB39ACA93C030CE63
-:107BA000407A50561B711D00D766AA5F745FD67865
-:107BB000BA6F42F89BA0E6194978AE893DE5384591
-:107BC0002DB3ED544E28E0F9817F54F58376F53CD2
-:107BD0007FA7DA41DB54BA6953E9E6D72ADDAC095D
-:107BE000F5876EE47433C2E8B82F0ACA23DC7692B4
-:107BF00033FB0B8ED2BA81FE258CE7A64C179BC7B0
-:107C000003DCC65802C4A74B40ECAD86FD4C29A846
-:107C1000A7FCC51217A37845F19C7A5A5F00634B05
-:107C200057A1DE542F886A3DF2C731B17E6A5F6C7E
-:107C30006512F62FC97F7617E6E196BA003450CE6A
-:107C40009D532F107C2A603C68BFABEE011AEF50A9
-:107C5000355FC7413BEFDF51C1243794D358FEEE67
-:107C6000157C9D4E8C871EAA7B7E17C17B0E87F7E5
-:107C700055270D3A7ACCF047EAE87AF496FEBAFA3C
-:107C800091EB07E9CA039CA9BAF6B1F97A7A8F1C7D
-:107C90003E4E57DF915F6240397B668E96DFC3FDB3
-:107CA000629A5D37E5199B01E1317796A8F9710D6C
-:107CB0006C205A5D8CFCBE4DAA9EC85A8631CCDF22
-:107CC00078FC4E03E507AC99E3B162DEC3997623F5
-:107CD0009D178C4B7CE4D04E238D6B4DF10AE8C789
-:107CE000BC17E02C06E97F4D9A7C53FDEAB81E6371
-:107CF000D07AFACB0C33C6CEB56F53F1E901751DBE
-:107D0000C0B7A798705E27C793D802663041FF01BD
-:107D100073B89C0EA5CB76B5FFEFD4FEDB547CEC9C
-:107D2000CA7F7C7524C2651E237D244F5CB63A024F
-:107D3000D751C0881EDBFDBB2383F5C73FF636CE87
-:107D40009CCC3C1AC7CDF9E8E8D9822702CF7563ED
-:107D5000E0F377E1F9F2578DABA361BD4F08AC1D9D
-:107D6000294AE39F9AFE7DD5D74D543F7A1C9868E7
-:107D700050FFF2D7CDBCFD0426A3BFEB8FAADC6970
-:107D800052E9276D4B3AF917CFAC3793DDB3AD709D
-:107D9000C9E63658EFC899773DF102E24BE15D7FC5
-:107DA0007941EED1F34B0A133B317F7FC42A3B4329
-:107DB000FEA0CD9BB6E5CB6C5AB7646488A74F6E26
-:107DC0007DB112C7FBDDB6488302E33FB9D948FC59
-:107DD000E5B27B1FD9BC9E9DEF8F29C9D7DBF9BFC8
-:107DE0005BB3EE89EDF8BEF6F9C78E05E5E974CC14
-:107DF000BA2709FDA6075755B7E5A6F5CE3F4BCCE8
-:107E0000CC85F1BBFC97BF7CEE1D98FF03D765E3E3
-:107E100082ED80CFA7727DE7E0AADAB65CB0534767
-:107E20008BEAFD15A37B35C263F44B0365D4DF8079
-:107E3000148C2E8065FE8C088302FBFBC067DC443B
-:107E40007C60C69A343CCFEC270B769FC4733EA46B
-:107E5000E27B2FFAC841F59CCE954D32C1DDFD8AFB
-:107E600095DB378A9C44F6B1434E2A0ED2E70EDEEC
-:107E7000A5C5971C9F201F2F2E8BA2B8B216771175
-:107E8000F3BF6D403EBF70524D9644EBD7C7F1072C
-:107E900021FC3231CECBE3F56EB791515E106C0D03
-:107EA000E964A5389AF24D3E5CFA0B8AD7BBEB2DFC
-:107EB000525A1CC50D9EC1722DF01DCB788AE3FA73
-:107EC0005068274DE37E84D3F33C8F98E5DEE1EFE5
-:107ED000BDC0F998D4F3097D9F348D9F8B07CF25C2
-:107EE0004D772EBBF19ED479E7126D25FCD2CE459D
-:107EF0008C6EA2736156DB28CCFB88E72885FBD902
-:107F00008772A8F310F7977D50765BFD4A289F3A59
-:107F1000DB8F215D687195F2049E7F4047027CCB28
-:107F2000A4F68F57F56EE463A87797AB7197CE05EB
-:107F30008CE22EDA78676AFB497CBC5B486F2EAF17
-:107F400001FA475912F52AE9170DC3787E44B9ADF5
-:107F50007B01E5AB0A0607C6CDE343F47A37ABA154
-:107F6000F5C6BF2F923FDF10B596FAC70378F0FE33
-:107F70002166E8B260BF1218AD984F42570DE52058
-:107F80003D4BCDD78DAF7D89EB4739D03351379FEE
-:107F9000F003ADDFF3A9887CA0D62223DFC3DC2C5D
-:107FA000E4DB04BF14C4A375D45FBA8949788F8316
-:107FB000294CC67B9A823A5FE8FA613CAE17827E12
-:107FC00086FB15EAF8FC1B67F27B206C279383ED98
-:107FD0001616BC9E61BAB2EA27D3974D09669D9CDE
-:107FE000FAE06C49BF9A3EFC35A1FD0DB2B36FBFFC
-:107FF0006F7590DD95DAD35ECB13D3E03CA8D672D3
-:108000005888EEBDDFB222E5E7D3804E6DCC99FDF6
-:1080100036C0C3F5BE48F2CE10B597E01188E0F047
-:1080200039A7CFCEE3FA2E68E7F5946F0DF20ECFA5
-:108030000FF3B44700BE33B73E4F409B578B2F75AD
-:10804000AAFC38901258E00C038F46A4DF2CE4E71A
-:10805000DF50BCBB1CF55BC0E5C0EA2F74F73F4E98
-:10806000164D69C47587E621687AA976AFB4D3CD79
-:10807000E56CA73B93F8CE19666F21FD3F94DF189E
-:1080800019E57DAC14231DCDE4B7BB9BF2466ADD38
-:1080900016C902CF590EBD3F66F624BD3C28526278
-:1080A00043E485DEDF55EAD4C78986B7DD41FCEBC2
-:1080B0000CEA4DC4EFF87A8C6A5E9909EF978868EC
-:1080C000AFBBE9B957E5CFEFAA7A6604F257781F3C
-:1080D0008589E5808F7616A0723F44F96198D22E8B
-:1080E00053BE632C53A83C80B9A8ACE54126321F8F
-:1080F0003DB5FC962416A0F250D487442429999EBD
-:10810000C3D00E19867A9EE35CBC87F22673522890
-:108110005E50C4944FB05D41E65724F70AAE67EA5B
-:108120003DDC138B14287796B29E7BB9986792C773
-:1081300054E4FC7411DE3FEE9CAE958FF3F214DE36
-:10814000FECD3F7DF138DED305FEA5D67FC6EBCF51
-:10815000954F2E9A82659381CAEF637B280FC8538F
-:10816000DE9A06E7FFC9344678E4C955DE092E0FCA
-:10817000CF55F621DE68E5095395FDC1E59539CA6D
-:108180007BC1E5C773948EE0FE5D79CA215ECFF3B3
-:1081900097DE37294968EFC2EFB7C2048E87F87BB4
-:1081A000C3E4FA04DB294F09042F0BF0ED66E2DB90
-:1081B0004E86740A6463C53C22E033E6DBA19E8DE3
-:1081C0003353BE9F21CA96DC973F3294BE0226B637
-:1081D0001DFD744546D717440F217C4F70FFE9AF52
-:1081E00098C703F4908D7A7E408D8704EAB83F40AB
-:1081F000A313ED7DE87C17C27BA604F979537BC6F7
-:10820000ED6DFDA1787C40D5F70EAAFADEFBAA5FE2
-:10821000FADC7E03C698E3D61EFAEE9D7F1AD9F1EA
-:1082200020FE79FE7E8F2E3071F921A1BCE88C08EA
-:108230007F0FBBB7F5EDCF991A974FF95E43248AAC
-:1082400033308DEF737ED3897F021F1CD34FB35F12
-:108250001D5684431A4B98310AE66DCD67A4BF7A48
-:10826000727717D3F70DCA4082C1BA8EAE38861422
-:10827000C78467B83DD192C468BDF6142902F5A53C
-:1082800006956F5A58CCF4E1B8FE214692B7A1EB9F
-:108290006E88F60918571CE48FE0FE8D38E68B8057
-:1082A0007106E53BF2296FC52D4AF9582E6385A367
-:1082B000A05CD926CAF930CE9EB6125605E3564DBB
-:1082C000023E4719E93C9FA2BF8AC7632C8CF22D5E
-:1082D000D60DB051BCDABB66E4AEC5C837134596BF
-:1082E00006EDD31BC6E5A3DFD363EBDF9F624EEA47
-:1082F0007A3C36C79B780FC32D19F83D1249B162FD
-:108300001EFAA615C67CE4E749CF8E8F1683E07F60
-:10831000D47B2A02F3DB1F930C54FF585DB6F5465D
-:108320001BDE23F42B9467201D516C30EF0668137D
-:108330000FE3DD5F7DA46504EB1D1FA2F3CD3A3C86
-:108340008D729843FCA07ABFA529443F28C957F3F2
-:108350003426B00978CE573C71D6847AEE429B4CD5
-:108360007EF4EC2681F25302BB1CC9784E47EF1B0A
-:10837000497E736F93A8FAAD1DE4B70E24B164BCB7
-:108380005F53D122905E2C7ABFADC77E4347C98927
-:1083900038CED0F1DD89C1FEB2C7EEFA4504F25104
-:1083A0006F9941F573331A4796156B0AECFF53AF7B
-:1083B000C0F3274C9280F798ED0F8A11B8AE2E13B8
-:1083C000F75334033FC5FBB9CD538AFBA443D3F71E
-:1083D000B0CE20BBA5212E3512E7EDC15F85FCEBA9
-:1083E000C75A32293EB2B9299BF24142C7B9771523
-:1083F0006B47FBA46195959EE7D5273B931DD0FF66
-:10840000D3D6298D20A4D8A7BB9626E0FDA0C52DE4
-:10841000161611068F8FB54EA4F916E33D669CB76C
-:10842000A5C88C72645ADB1433C2EDDE55CAB3C1E1
-:10843000F31416BBD6205D46B53C4B7862637E379D
-:10844000C2F3DFAE519251BF3896C6C2E6493E90A4
-:10845000CFED8477AE71D27D924F93C2B75B97CF49
-:10846000F335A3A7CBFCFEB891BDBB04E05C01F4DF
-:10847000540FAF8E36654623DE9AD83262521F946F
-:1084800095B8D19E3B8D7A3BF0F3C6BBE6AEAF828A
-:10849000760D778FD88FECE30A33D79BD99F45A20F
-:1084A0000BD00B2B903EFF638E55F204F15FD41F6F
-:1084B000155D7E1A971BA626D16F067E6EDA79FCB3
-:1084C0006F68EF20DE2A41784CBF09AA5DA0E66BF9
-:1084D000244C206D9C7E0D33E6FAFC0CE32E8BAC15
-:1084E000789EA17AFA797872DE3A82C6473D37974C
-:1084F000291141EB0096E0277FB98BCF7BAE9D5AC7
-:108500006F0406F34390FE1E5AAFED63E47A3DBD5F
-:10851000BE93CFF542806F9FF1BACB7CFA7E9FE588
-:10852000333AB7D1A2B2FB38CAD97522E5558F5973
-:10853000C7E3FF678630F213F5369EC67FF1671CEE
-:10854000A8C211E0DA18574CE7D95B3FB3EF80922D
-:1085500032B6C73EBC2C41BF2EADDD67E7F6751BBA
-:108560008BE4FA603BDA67161FF0BDB1F83CA0A0BF
-:10857000FC1EB56985D4D7BE43F919FE6458EF6275
-:10858000F5C864C035E40F9FAE17543D84250C9F99
-:1085900040571749FE607F2588FF015FE1797B3EE8
-:1085A00081E0D3DC7A74F3BDE487B13B782B7E5E47
-:1085B00063992607791E90764F9061686A604F7CB8
-:1085C0004A83E3C9DFAE7EFA097875E2A9E55FE385
-:1085D000D332A0321AE1794FDC9C6B13A1DD58B382
-:1085E0002F01F9E9129FE53CBCB36AF89282F7F3D8
-:1085F000F4F59684A0F5C37FCD3B9E585F89726ADF
-:1086000087D581A9E1885F6E1D7C02A9F85D9CAECB
-:10861000BBFE95EEE7474AA716507E7B9D85EE751B
-:1086200085C27789CA07987A5F43A3A78896910C79
-:10863000FD8B4754BBE9C85AB053A1DC586796F18B
-:10864000BB065D8E222521CC78E63A33FF6E4EB014
-:108650009D98DAB34F6DFC2E37F74336C2F84218B7
-:108660007FDF85C6DB53A48C990EF8BFB7C879F9B4
-:10867000F42CCC6F5A44FBADDD5ED7F536B4B97738
-:10868000A02B03EB8FAC1D36414047A451A6FB7EC7
-:108690005EEF73244F5AF03B3E60CFB7B41B2350BC
-:1086A000FF707B0D14BF6D698F8B1C8E72CA6608BC
-:1086B0001B675D349DC3AB479E38A383F5A1E65C81
-:1086C000AE0F09CF94DD9F0AF0F21EE2798A9AFE7E
-:1086D00021A97833C622117F96BC3CCFAD471FE25B
-:1086E0007AF519D4AB515FCAAA9282E5534334FF9D
-:1086F0000E4655AEC38DF730736C8CE4C750BCACDE
-:10870000807E0B1BF34D4BC1EF643818E6E7F6078C
-:10871000FD4706CC8E6FE3FA4EA4CDE650108F15C0
-:108720004E5756F81FC2337294C2701E63887E6122
-:108730000ED11FC490F282E97A7D42668E6884B3BE
-:10874000FDBEBEF338347F2EE84D74CFCCCD00FE95
-:1087500088A756379D4F34181244CF8A22C70DEC94
-:10876000D1FBF13E1BF7AF48142F129446F2DB6F9A
-:10877000CCE4FE8D44C6E35E83146ECF8F9DE4A6E9
-:1087800032D80F148762AFB248E4CBCB8A5CB723F0
-:108790007EA4001B40FBAF7F3A1388DC2F512F676C
-:1087A000B5171757FACD6EEEFFF31A221D9BC3E0E3
-:1087B000FDAF0BB81F2E720FEC0DF5DBEBAD74BFE8
-:1087C000254F7CAA89F069BC81FCDA5E7640427E46
-:1087D000F2ABE95CDE1F2A72DE3F9DE2B2CE14846A
-:1087E0007F82112C2A5076CDAA1F37E9F6D448D4BF
-:1087F0008B3F4C7C91E0E106D8A5C17F9B6AE3FAF0
-:108800008F82F78FD6AE26B8CA03B89F4CBB771EAF
-:108810002BF1FBFDCDCE536EBCDFBBA22095AFAFDD
-:10882000C8382315CA43EB0202D2DD3D76651EEA45
-:10883000254DF273741E2919B201FD65838DEC4D2F
-:10884000CB38C69E8EE1F5DAF7A31EB20FDC149C7E
-:108850004F52ADEEFB2121BCBE725501DF67E70E22
-:1088600000643FB48F996A7FDB16933D7EAE0C7037
-:1088700043B8B8B9FDFCC274DB62F770B28B78BD47
-:10888000FB2ADE1EE3A5502FBDFD7E15DAE38FA681
-:10889000849FF74B75DE47DFEA7E04E358FF59CF2C
-:1088A000E358BD9FB39F1980B76CB0B3647605F0F1
-:1088B000B9A5E679E1BE2373CD2CCE473A6DED0420
-:1088C0002F06F23CFA2ABA471FAAAF5A918E4E4B96
-:1088D0009BEB27CA9C8F644DA0ABFD1CF742C6BD25
-:1088E000B0DEEA4840FDD3B3B4BB01F98767D7D205
-:1088F0000FF15E7A799999F4D67263CDBFA31D64A6
-:10890000DCCBF35FF01B13880783801FE17DD36905
-:10891000D5FCFC164ADC5F2B3CF3B13307FDB18973
-:1089200046C24B4D8F1D6351DCE897DDA0E6B7339F
-:1089300071483DDEF7320E16C9EF1B55077A2DEE52
-:108940002F97E7EB2AF03FE4439A9E6B4B37EAF20E
-:108950007ACD2179BDC6903CE0AFA7AB79722A1FD2
-:10896000B2678DEF539F7A15EC605CE74EE043F8F9
-:10897000F4833D8CCFDD60AFE3F335B0D7D10FFE8C
-:10898000C6AA51F47C739583DEBFBD6A123DAF4B1E
-:108990000E98109FC91FCDBF33E717C8AFA7E19945
-:1089A00098966DC3EF76F0FA21331BFFD57D35D451
-:1089B000C7A9EDDDAEC5F49D3AADCCD62ECE4E277F
-:1089C0003F38959B67342F46BFCFE652C53A03F038
-:1089D0006480C15981DF7960775A286E11BA9F0788
-:1089E0006768723CBC1DCFF013067A3FCEC0197D7C
-:1089F000F8711E12F83AAEDAFBFE16A48F7E4546D9
-:108A000027E27172AA3E7EB07206D7F35E579FC905
-:108A10006FBB86F6755F5FA38FDEEA3D3B0005FA0C
-:108A2000F55EEFB5B36BB1DE13139EAE06AA74D537
-:108A3000EBF8366E4FB219406F83B11C6A1F0628DF
-:108A4000BFE4746D8E9FC8ED27D35B7712D25B575E
-:108A50008CAF1EEDC4AE5D4BD7E3774244A4372400
-:108A60000BA4378C7F68F456CBCF6321D21BFC3923
-:108A7000ADEE3D670ED26302A72FE1999DCB291F72
-:108A8000E32E9E47A3D15B8C9A2F1F25B593BD483B
-:108A90001FE6C07E407B1B04BCC773FC634AFE100C
-:108AA0000B1CAE7074F723E9AD6CC64FA3B77FBB48
-:108AB0002640F9139D294A02EA335EF5FB813F9671
-:108AC0000ECFCC3073B970B92F11C7D9A08E336DCA
-:108AD000C861F2FF15581D22CAB37C99C3356F7C5B
-:108AE000267D6FC8A7F6DBED5456CC80E780B9270A
-:108AF000C9CF3BC0C0E9F7C1B7CD8B11EF931A0EB8
-:108B0000164D437CB943247D3B745F1F14AA713317
-:108B100081CF0B9A5762701CF11E952EE53B3A38B7
-:108B20009F8F61521AAC27C12D15E7635CE86A0379
-:108B30007D4FA45FD1C11894CFDA78707009986F17
-:108B400082AAAF75DCF9F408BF76D3401D3DB7E0CB
-:108B50003E7AA3E70BF10FFB0C41E31394EFEB52CA
-:108B6000EF49FE58BF6DAF7EC4CBC3FB25AB66712A
-:108B7000BEE131F1FC0F682DE177019A8A5C4FE28A
-:108B80007ECED3FF764A7E17EE637934F995138C47
-:108B90005CDFC36F24F2EFE5B809CE5AFC4DD31762
-:108BA0006585E7172517BBFE80E36E62F22E94679A
-:108BB00036079B47F13590678817CB8A9417675023
-:108BC000FCE5D2F4C02F8B9457895FF7824F03AE38
-:108BD0005776F7856F538AFE63CF0F48FF65DC5FDA
-:108BE000BAB0AC8672B306819D84EB9DAAE6677825
-:108BF00086F07ACDBFEA1DA0C54F9542CC9F8C561A
-:108C0000E135C6E26415D0BF0BE530DEDFDB1BF0DB
-:108C1000E3BD600BDE2393D08FCAA87F4CADE093F9
-:108C2000B1BFF8E5EB182F32E5D0E744189BC4ED4F
-:108C300001EDFE8D94FBE3FC8D87353E318E8D4733
-:108C4000F8241BE40726C3FBCC87F33AF078B21E66
-:108C5000591C8BE272E2A68612FCDED6D2AD9F6E64
-:108C6000427FE8E47FB7303C0FD01FFDC6B0F95C0F
-:108C7000FF303942743570563CD71353C2E3E9E3F1
-:108C8000B354FD13F1344E87A76C66783C25FDE79D
-:108C900027E069E44C3D9E1684E06914CD7BE978B9
-:108CA0001A3B13F0F4559083B8AF17E72A0366F622
-:108CB0008197DF952A897DD507C507C8EE1BC12698
-:108CC0005983BF7BA83D5B515EF6919FD07FCD114C
-:108CD000CA8FF3D49EA63CE52EDB917D6807FD4745
-:108CE000AD450EF66781FEAED3D75B40AEB8C19EF0
-:108CF000DC304B247EB2E70E8BFF3AD46BEBF87D71
-:108D000084F2BA4D02E67B0FAAAE115CC0DFE21519
-:108D1000301DA17F8C62E8F19FC07F57980E903E76
-:108D2000BB0EE4B19BD817BF97A6C9FF31969AB77F
-:108D3000D04EF5FCCDE8588DE7CCA45DC88FA603D6
-:108D40003D617CF39A6E906F41E3BDB56312F9D536
-:108D5000AEFB1EE45F901F670A8C185CCEB126EA5A
-:108D6000FAE54929BAFA690997E9EA35BAEF8C5167
-:108D7000E32A595B72117FC40A9EA7305DCED0B53D
-:108D80005F57964DDF03B86232BF7F3773D464DD1F
-:108D9000F8A17AC1D5F03FA47731440F08D513422A
-:108DA000F5828533F5F740D71803D9C49F18CFABA8
-:108DB0001B7AF6DF880ED6C91CCFBD65A7281FC356
-:108DC00003F63FFA9B0607E597225D8C3507C83FFF
-:108DD000B761BE95CE63C38E27E8BB119AFF0BE83F
-:108DE00086E8686CB64479AEE9F65F537FB694CBFB
-:108DF000D950BA14EA5E22FD6FE36CD81B7E6F6D0A
-:108E0000760A977B3B03E48760779A19CA4DAF6473
-:108E1000A0BCB1DF08FE086118D2AF42F28925304C
-:108E2000C94BF992EFF1EF2932E6589388A6BF4279
-:108E3000798D80F6DD6FA979B488B711F9CCB17A54
-:108E4000327EEF97D377FFF1FC7C6C0E5E96AEE638
-:108E500065CDDE8E49602D98173B18C783B671B576
-:108E60004CF2905FC34FF543F2D9010FCDCFFBC752
-:108E70005731671394C51A45F537BBD4F87A37C50F
-:108E8000BD53054724FA3786894E8A7B473389E2EA
-:108E9000E283580D3DA3043F671E97C847AE00000C
-:108EA000A0BC603799E9FB19D94FDA187DDF68A9B2
-:108EB0007933E5650564F223DE7388DFC3DB60FF89
-:108EC00005C5099AF6F1FB04F724B93FC478E6A07A
-:108ED0003A81BE132E56F33882F8A6E89806F5625A
-:108EE0005D2B7D072EBEDA407EAD2BCC35BBE81C5A
-:108EF000EEB6D0F7E3BAA03FFAB9D6D90D8CE81593
-:108F000098C7397F2AFCBAAE7152DCA2EB6FFD48DC
-:108F1000DEB1103FA7C7C5F56F4F9C99E397EDD41D
-:108F200027C8B71BE322E97EDCBC6B6BF6211FD997
-:108F3000F09EE858ADFA9FD1FF3F14FFC0FC03B389
-:108F40003305F54E7375783FA59939F767A1BFF4DE
-:108F5000AE25097DE951BDC6456C06BF39FAE2E38D
-:108F6000220DE53C0EA2AD53DB67A36DB95029E39A
-:108F70005F3F312E52D64B5C24502320BF1F8AF511
-:108F800063113EDC6F7DA971919AC24B8B8B68FB9C
-:108F90009EA5FE5D0088ADE677505C80CECDD0B357
-:108FA000BE20386EC1F595E35F327F8F7186D96A36
-:108FB00079DF5307BF44BFFEDEDFEE7E0A9FD79DF9
-:108FC0007DAC6C39E045D1243BF97BF7FF32E641BB
-:108FD0003E9C3E7E30CB61D1F9EFF187F849EB1032
-:108FE000F8BDFCE0FAA29075651BF5F1805C9BBEB4
-:108FF000FDD4387D7DFE107DD9CC6A084F43F7BB88
-:109000003AEA6ECA936BBC8D39788678D079881726
-:109010002E9B8798C3EE4BC337E64821BA5FF73ED5
-:10902000A77BE72B2BDE5A4976AC81EECF9F9ED7EC
-:1090300070CF3B32E28799B9699C7C05F1E8BBDFD0
-:10904000A7BF4B311DC9E5BE11DA57E6F0EF459DCC
-:10905000174F50FDF9436B77B5E706C57BEF1DE869
-:10906000721400DE0CB59D12500F195AFB1AD5CFA1
-:109070009D9FD5271EA5D5EE69CF0DFAAE5F9AD17B
-:1090800069403F465AED1BF4BE37BDC720BB79FE91
-:109090005E9959267B4BCD534B53F126AD8CFB5B30
-:1090A000A5542E6F3698B87C7343B57815FC5F5B7A
-:1090B00068BE1BE7EB6726F17B1D0CB810F22B6D29
-:1090C000BC5079A6C9019BC2F5C8B4B287B85CD1BF
-:1090D000F205DB42F3E25C73113E427523B5DB9887
-:1090E000A3B6DBC9F5533683492897619F61F344E2
-:1090F00017A87EDADEF2D398663FCE79F343CCCF61
-:10910000FBD1F6632FE35E971C087BDFF636D56E46
-:10911000ED8C082439B81F38ACFE3EA374EAAD05C7
-:109120007DE8AF98578B30EDD55EB8C4BCDA8D6A58
-:10913000BC488B976AF9B5CCE81B87DFF91C65FB47
-:10914000F30D1407ED25AFF61EBB2380F7DCBD152C
-:10915000118ECDECD2FDEB5BA7737E5A5DC0E81992
-:109160001A5F085DF78602DEFE5091F3E1823EE26F
-:109170000A5AFB0F13C3FBE3BE2DE4FB3F775F29C5
-:109180009FEB7D8A4961E1F240B57CF7D0F7600F33
-:109190003D89EBD0CAAEFA34F2DB794C1C6FDD327C
-:1091A000FF9EA0A63FDA507F243DAA85EAA3ABB973
-:1091B0003EA9E959921AD708A527A08F3FE23C8221
-:1091C0008DD3ADA6279EA38FB9401F409743188F1C
-:1091D0002B19D4BCD121569E827EA97AD4F9F6D31C
-:1091E000F7F64BB29FEAB74690FD54BDF92DD4ABCC
-:1091F000D6D5723F61A7BDE62DFCFE81FB3D91F403
-:10920000A6DEFA6B76D447857A3B0AE38A888FF12B
-:10921000369F205F8E7654C0E482F595A31D65C30A
-:10922000BC555700E1166A4F75DDFD05E5BB82BDF3
-:1092300079B820EB1FC01F42FC4B8DD3393EEF1A8B
-:109240007E8AFC26622DB7F7C45A1E0F3596F1B8F8
-:109250008551E17E1433C82374056A7E940D0EBDDA
-:109260001FA52B89FB51E2736BFCA8079A26592492
-:1092700085E423F7AB6879ED632CBEB7F03E862713
-:10928000C3C8300F1D1455B2032D6A7C03FF410B78
-:1092900094579ADF24346FDA16E22709F5A358674A
-:1092A000E9FD268F0AF2BD93619EE7D7E7BD83688B
-:1092B000FB878D8BA3D06FF292AF61A6EA37791846
-:1092C000D7B3E343EE37E9DAC1ED22172A305785E9
-:1092D000C3BFF3E254E407B966DFE12AF483687E92
-:1092E000A8F86A151E6ADC07E18BF014F3393C63B9
-:1092F00042E0E91DA2C58554780EE0F02D2F709252
-:10930000DF4942784A3DF0D4FC54DEBDEDF47D6D7A
-:10931000CB1D16D94DF0FC92EC5513C213E1FF138F
-:10932000FD50E342E039EEE1CC07F03BC1E31F29F9
-:10933000E9C0E7844DB7C5DE00CF495B1F28C127D0
-:109340007B93C709FE7316E75798D91D4C8F636747
-:10935000C8BA3883064F0D0F7BFC778CFCB1E51241
-:10936000F7E797AB789886700BF6E739F470DBA0D7
-:10937000E64B1A736BDC68EF0E0D819B86871E84AB
-:109380001BF2BB18B3EC26FF5D9D80F6506F78385A
-:10939000B4EDC7E1E1FC59AA3DAFC2EDB9F599F7CB
-:1093A00022BC5ED858F20E3E5FF4DD1685F0DABEC0
-:1093B000E58199BDC02D3198CFEF991E1E6E5B8B54
-:1093C0005DD5B3E0FD750E9F91F82CE01BDABD9BD7
-:1093D0009BC659F5F1198D3FE65BC3C98F0BFB970F
-:1093E00096535EA1A76C39F1C7AE73FCB1DB8E79E1
-:1093F0008817CB1F2D85FCBE7D79ED77AF5F077099
-:10940000CDA93D4CF46704FAA373AB3B6C50F33128
-:109410005804C88BF832E6C7F8F12066F545099480
-:109420009F407CD38B79CEF881D2503F85F4C65FC4
-:1094300005220E261812808F63EED4152407EF9FA5
-:109440001586CFAE2B3390FF67B3EA1F944B9D2D4B
-:10945000D84E8B6F2D2B525A67FD347FE1C3D85FF6
-:10946000F31776C6B073FE35FC3E784EED2601F359
-:109470005006D5DD4AF221BE4C61281FB266CAFCF7
-:109480007BB3B912EDF77C7F5B770EDA099D78A389
-:109490003D83F0E077384F67EDE38407572CE5FE16
-:1094A00091CEDAD3B1E1F1A036E2D2FC8C9B757299
-:1094B000D25BCBBF63D26957DE4CFB11783042C51B
-:1094C000034D4EA2BC417C3296051E463FF620C09D
-:1094D00087881494979C1F8BA0FF44C17EC45EFCB8
-:1094E0008F1A3D74C1DA2CFDF09E70683E400DADC0
-:1094F000FB7459B67F621FEBBBE83C00352EE95187
-:10950000E3920B6B79FE6AE71DDFE5E17A4F978105
-:109510007D0070D95CE660787ED340B10AD882E7DE
-:10952000392F6F358074ACC521B578FED662E7114E
-:109530003CD7EB00A712FA635EAF1AEF19A27E07C1
-:109540003A04FF01CF3FC77130DE837240F3A3338B
-:10955000D41BED88DFCA17583FD65C9328117EBB19
-:10956000BA71FC753BEEA4FC851EFF20CF87FBC9BA
-:10957000FEAD6833E5576AFE2DAF9DFBB72A5880D4
-:10958000FE9D3C8A2320DF6EB5D0F71AAA04D98C41
-:10959000EFF717BB8C85A4F738291FD635C72A915A
-:1095A0001F6CE9B644E417E58D22C9EBDEEC92F3BB
-:1095B000E9EC47F21995EE2E81CF0C2EBC383E9384
-:1095C00054A8E733C9853F217EB67E969EBFA0DEB4
-:1095D000590FF3E4A8F4746EDF6A1C1FE3571119E6
-:1095E00041FAA8BADF503A3A4F2FFDBF8FAE66223C
-:1095F0009CC3D0D5ACC21F4757A58503FAA4ABB90D
-:10960000857ABAFA1996FF17D2D5CF691F17A02B02
-:109610006321D3E749C7F2EF3C8F8935F03CCBFF9C
-:10962000C379D25FCDE4FE8BD03C69C66AA85C00EA
-:109630006743E7A3960BC73319E34C964DAFAD1DB7
-:109640002DF3F182FD9D2CC4CFC942FC9AA1FA5D95
-:10965000183FA8CEEFB9F789BFEC1D0D7F3EF9F496
-:109660007F915EBB6FAA40F7C90B477EB71375D0D9
-:10967000A23595EA3C7DFB3DFFD97E4EFC05FB55AE
-:1096800043F7D51875B77A6FE0C7F93999E356FAF9
-:10969000BEF9BA1AE640B85FC8EFB9AE8EE74D6BB7
-:1096A00079CDCE57AA1E2C1DCFF3E9D0EF19EAEFE2
-:1096B000D4F2953DB64AD2F38F2856EE8F0DF1774E
-:1096C00056C6CAB7D03DC6F3FD9DEF16FE03FC9DFE
-:1096D000930A64FE5DC610BF677CBEF261611F7EA7
-:1096E000B3CE1807437E9763F30918AF656733C994
-:1096F000AF33C816A0EF6B95D74E213DF06491EBC8
-:10970000535CA731B7FBAB97C653BE8103870AE50D
-:10971000CBA0671E2FFC27FA09FE597E3E5F01F79A
-:10972000735DECFD791FC23BAB8F7BF472E0912837
-:1097300078FF68BD9DBEAFB552D5A33B4DDD492D29
-:1097400050BFFFAE13BBD13FE16B3330BCDF76B10E
-:10975000FEA3860BE8C5E610FB68C339BDD8F7D673
-:10976000C420BDB86155FE8E6361C6D1F4E29B662C
-:10977000EBF5E2721BD78BCB6DDD26B40FCAE3BECF
-:109780007F1DF34E8DD5AC1DE5E220A586F4E17872
-:1097900089513EF1FF8FCBB37F685CBE78B63E2E19
-:1097A0003F56CD47411E8FDFFFE9D2FCA893B8DEBC
-:1097B000B0C6C8ED15AF02EFC2C4D143E3F243CF48
-:1097C0003E4371F975DBAD748F6FC38E663EDE1458
-:1097D00026619E792253F5B502EE2F0DD53F1E3539
-:1097E00029D694F188EF06BA4F88F704C92FB2DD65
-:1097F000BA09FD4DE9769ECF6DDEFFF256B73148CE
-:109800003F043D94F4E2B2007D97A95C7230E23BE4
-:109810007193FC141FAF1308BF46CCE6F4B330D7E6
-:1098200047FAE1A03249E0F7C4DCDC8E4FE671E78D
-:1098300048C42F682A8EE2715FE980E8C0B8F37DE2
-:10984000D87432DE5F65FC7B15930DF4EF50AC13DA
-:10985000BA13902FB70A4A223E4167A27B8F4FC7A7
-:109860002803F1DF93F22419E8DF93DA93D7988085
-:10987000EB6BAA6F4D40BD70CD6C1E4769CD3B4E62
-:10988000F90FA674D00753E819F6DF1D9DEB14D429
-:10989000BCC0F604FA1E026BF990F06A9499F17F4D
-:1098A000E7C7E15F84F474CC46FAC2AF041FBF2758
-:1098B00064B7D27DBC96CBCC8955B09E66BB99B4BB
-:1098C00009EF65530FA4C0FBE6015234C601BC2961
-:1098D000A912FA8FBC318D6FA21FA439259561BEE4
-:1098E0007F53D9048A9F379D0506033D3DA347EC6E
-:1098F000CF82F76B84007D37C83DD9C0309FB0ED73
-:10990000B2A989C1F7324529544E3A482E88B2810E
-:10991000EEF9896A3C5B3C2F9EAD8F4F7F3F9BEFFA
-:109920005B662DF3E81E689C59C2FD965F56FC21CC
-:10993000DD738B33535E50B989F1EF7E5CC6E85C12
-:1099400042E1E759A58F2B186DFAF5ADC1C034E59A
-:10995000619F5D82F8D18030A53CEEAF96205F6AB2
-:1099600038577F92D747F0F2CED94797A01C941969
-:10997000FFF7491A46F1BCCBF201C5C487CB4D8134
-:10998000B0DFF9BDD07A64E653D4F1D8FFE4786B48
-:109990002E33CFF3A55F78BC9E7301F5F912C6D5BF
-:1099A000DA858E1BDAEF7FAA7D6FFBFC68F6B9FBC8
-:1099B000719407412AA27A9F0DF564A3CA0F3DD97D
-:1099C000137C7E19F9819BD3458C419767FBDFA6F9
-:1099D000F2D6B800800000001F8B080000000000D5
-:1099E000000BCD3B0D545CD599DF9BF7E6CD10669F
-:1099F000E00D0CC910093E082831045F1288A04907
-:109A000079046240A94EF809B825E944A346DBB3BE
-:109A10009DBAD6923DD932094320989009A9256E66
-:109A20006D8BA9D9B5B547A9DBEDAA47BB9398F5CE
-:109A3000F81FDA5AAB7B3C16539BDDF6B83DF42792
-:109A4000969ED336FB7DDF7D0F6626432069F69C0C
-:109A50009D1C72E7BE77EF77EFFDFE7FEE9C3B87A4
-:109A60009F5A8073562B6B2A9865C09F73607DD672
-:109A7000E0736AF93FD0FD0B0114FAE6C047DD4DF3
-:109A8000F1A24AF1BC25404370BE1B4003889F935E
-:109A9000F0A9050F5FBD74AE182014C4877902AC1D
-:109AA000B67006EE4FBB56C7EFF4039C4538B9C6F7
-:109AB0000C1CDE47113040B0C763FF5A35FCEE9DE9
-:109AC000B4EE35601CD367C62BD6BA571F51216E32
-:109AD000CFC7BFCF5AEBFEB4AB353BE499396F6AC1
-:109AE000BB6C3479DE8774065C27E283D163F83D72
-:109AF000FA6E4CE24D3C837FB8DFE84A6D74109FEC
-:109B00003F688FF3E2B822315FC7FD66C0CC47598A
-:109B1000C878B05E428903E7EFBBBAE2519AFFF022
-:109B2000E3C3DFFA363E3EF29D3DBFA4764149C510
-:109B30005035C2CB341C86403B044A900E4EFA8608
-:109B400078F47CEAC814A21FFBC978DA5B7E678CC4
-:109B5000C99748471C7FC77EC9D4703D97C77354C7
-:109B6000A6FDB92593F62B1F5EC4FB0F6C4FA6FB19
-:109B70008864BE1DC0F19103121CC37E8691B00E95
-:109B8000FEA905C9E39B09BF55D44B18871B3F2885
-:109B900041E7581A7C3F1874303D886E9184FD1F50
-:109BA00072EAB7105E0FED932182200FED74012C45
-:109BB00006F846F0DFEFDE5D02F0853E27E37D64C8
-:109BC0009D3A2AE1FB11AFB6B993FA4B1CC6511D61
-:109BD0000463E2B90EAEB88ACF65AF3778ABCEEB8F
-:109BE000C5D6A9F9E0A1719381A097F9E88D2AE281
-:109BF000A3B765E6A3D4FDA7F2DD5C7C5618CCB113
-:109C0000F0300AC115C89EB279E20CEE0FAE763084
-:109C1000FF2CBFDAC1FB3B5B8003A4D9F9B0AF07CF
-:109C200017B87A866F548BEE7BFD2DA708FC6CF37A
-:109C3000D4D171B3A882D685F05839F27320797FD8
-:109C4000F6B8926979F83B5850C9723726E3595DE6
-:109C5000A371132AA81D37256CCB1EBD5FBB90BC1A
-:109C6000B820017E11C1053E7FAAFC3A21C448DC20
-:109C70009359781B9DBF6FA30AB29406DF73F40F4C
-:109C8000EDBCDB24FA473E0F4629EA096720992FED
-:109C9000832F9430FFC80332B8A444FE6A34895E2F
-:109CA0005FBAD539AD7FDCB61E23BA1B45E0C07D57
-:109CB0001D7E4B66BE391CDCFB0B99E4BB51D525E0
-:109CC000DC7F46ECEE87DAF1FDA1D765631087777C
-:109CD0003FB3EB67AF627BBABA788D544C44322302
-:109CE000DB71FCE9F56E63D010F2378D97626E4C34
-:109CF000F79A99F50E5517F37A515C4FBA001F2861
-:109D00008DEA0744875478D3FABAFBF858C3EA04BB
-:109D1000B95A187A2188E71BF2E0263CF4FE24BFEA
-:109D2000874AE4CBFCD9D7418C325E7E465F71DC3A
-:109D30005F5ACD9304A7A9B42A9249E7826C207C8C
-:109D40007CE8356EF4E190F79D86DB289F99DF1B58
-:109D50007342BC9CF080EB62DB0C135B5A88EF4BC8
-:109D60009CAC3F64FF4A7EBEDD1B541CB8AFFF0CA9
-:109D700016F37AF6FC26F8B2721FBEBFD639DA4067
-:109D8000FC11DD0E5A04A76CF3C614EA6FA00DE2B5
-:109D9000C21BF53A7711C26D7C9E1602A8F50DFB29
-:109DA000C90E553C77A42044EB47CC1F95219E7DDE
-:109DB0000255B0DC351EACC7F9BD6FC8C61E7EA209
-:109DC0001D0FE17C252003D1497A6A6D6002F7A35B
-:109DD00078CEBC075900EB26011A12F8A976CA0DF5
-:109DE0000D097AAE0E2127F6EBDDF949E337684518
-:109DF00049EF65308D38D277636059D2386F55A5F9
-:109E000046FB6DD257263DBFB9AC26693E3428A724
-:109E100027B0BF16FF11DD65107D5BAE3CE5D84F66
-:109E200098AF40421FDFFF25E8F59FC9C4CE75708B
-:109E30001DC94F33189D241F68BC8D63889785CF3B
-:109E4000B92732C9909826DB75C9E2CFAA4D454C97
-:109E50001FC973C641F87F0461C8C81715DA848327
-:109E6000E804DA98C4CF516F0C22B2038AC9E3D058
-:109E7000C069511C77056A6F0DFBDE00C4A8BF04E2
-:109E8000623C1E3FB1C335C8166E313FAB058C83B3
-:109E9000F83EB33C2249D8CF69044346781E635C40
-:109EA000A27D6A385F5E492C19E77E41238CF73228
-:109EB0007C730FCDCFEF06AD2F9FF997DF8F7641E3
-:109EC00084F6F32818E092091FA890969216097359
-:109ED0007B25E839A487BE09C62AEA97C204EB2588
-:109EE00034EF12F517C19826947D9CF5374C28BEA7
-:109EF000336EA1FFD3C9CD8CFC2870C6A60B0EBE55
-:109F0000FF56B37C13EAC1CDB7555DD0DF50BA5FC1
-:109F10004C92DFBB37E98C77A57B23CB8BD2FD122C
-:109F2000BF1FD814BC6E133E2755E05E75F1F8AF25
-:109F300050053EA31218E8CB40F4D99B02DBC85F62
-:109F400079D66D94B2C8233E892FAADD93AFD48809
-:109F5000F9440F3FD283F09D530E12E16009D10105
-:109F60009FAB48877D4CC718C32D0C83B1DB5A9734
-:109F7000FAF94807A2CB28680B08AF72F8E2E8C0EC
-:109F80001F84B3E81937FB470AD165E965A1CBA760
-:109F9000098F174B97547AC0AE5C809AB9F5E95790
-:109FA000A57886B494C882F4C1F348481FC26700FC
-:109FB000043DD0AE1B84A774F8A77E4625E87BB885
-:109FC0002FC6133D233533FC9F8DFC2FFA42BE7CF8
-:109FD0004807D11774F293BC603F101CE3F939DBDA
-:109FE0002178209FE86132F26CBBEC8249F66B8BE2
-:109FF0002583E9B55446070DFB9952DC727E46D99C
-:10A00000AE6781C6F4590C616EFDCEC9E3E7485FC7
-:10A010007B1CA391226A9FAEA3757A9B51C390CA01
-:10A02000F70ED7315FDE035A29F25DA16AB2FE2E28
-:10A03000BC4631227A22BEF608BF49378F90BD292F
-:10A04000747861B07266DDA8D308C4905EA7BC675F
-:10A050004E84F0F9827CB4EFC60C9E4F3BC5F908E4
-:10A06000A67C05C983908F4035EEC577BE7E0B2850
-:10A07000826F3D3B107F888FADF402F1240DFC1BF5
-:10A080003F7FA45EE8BBCF6E0A3D4EFC42FA89F1E9
-:10A09000678246FA493380F5A6438FB09F7076C039
-:10A0A000A5139F426CC424BF629BB5CEB601D707EF
-:10A0B0005256C239A3AE243BEED083D9CCCF86040E
-:10A0C000E41FCC77DEA5F23F74E7CDCB0FA87B6A07
-:10A0D0006DF644F9ECE354928FDCC479824EAA3FCA
-:10A0E000C47E874A72923B371C678AFF62C371063F
-:10A0F000820CC769FB2F64B7909E77A1DD1A447C60
-:10A100007FDA448788F972F23FC89EDF1ECE62BFB5
-:10A110008B5184E3EE8849A383C88F774258253E4C
-:10A1200095A02442F4DB1A91D87F2BDEB73D8BFD3E
-:10A130000568D0083F52FC06F9DCF28BC0A385A766
-:10A14000ADF15F3A752FE1D50B3F4F88B7ECF7BF04
-:10A15000EB5A7AAA4A27A5ED2923FA665AF445B59F
-:10A160001D790DF7E9FC53360C6AE4177FE98D5A27
-:10A17000DC5FDF8F6583E2B34C10F1D50210763CD3
-:10A1800093E47429F1CB58FC33C46FDDD91A9DD701
-:10A190001E07D6B80884D83FCE443D40701D99FBB9
-:10A1A000993F33B354DDF6B721F11C6E89FD608F02
-:10A1B000A572F3D4789CE42B0FFDD8DDC9F02511EE
-:10A1C000CF03C7437C0EE9FCF55758FE3ABEAA3BC5
-:10A1D000370FFF3ED57F87C47890C663DC194FC028
-:10A1E000EBB4BC587266EFDBE35193E525659E4DF9
-:10A1F0008F72A7E08FC5187FEDC6FD0E0C1CAD2336
-:10A200007D3392073A469AD0BFF59F248AB3D693FE
-:10A210002E26FBD300A3144778401F2CC3BEB3C027
-:10A22000C3FCB3E8BF83F1CF209CBBAB5D9A8E38F3
-:10A2300059FC91A9D5E1FBBB0ADC8689F48D5AE370
-:10A24000230DE86789E5DF26BFF44E6BBF4C0B9406
-:10A2500043B3A588F95DF1B5ED7D8DE2DEC532C869
-:10A26000A4D7E42E83ECD39D1830E4A2EB0E5F76E6
-:10A27000B2DF87FE1D9FC7D590ECF7DDF58833A9C7
-:10A28000EF4CF1136B5B92FDC0A616E075693FB908
-:10A29000ABFE7AF8E0F1B3FE5CA18C3BB43476D52A
-:10A2A000C6BFF49487F1FF421EE295F32441F37395
-:10A2B000D877211E895F11235955882793BEEAE478
-:10A2C000277FEF3E1AEF3A8BFC4BE3654FC3E788DD
-:10A2D0000E57587802B12F13FFD1BE53FD61578A34
-:10A2E0003F9CBA6F9B0E77D8F859036B083FE89FE5
-:10A2F000B37F609F2BF53CCF637CDE80BCF4831E74
-:10A3000037B7F11E8DDB133D016E4FF6E8D0808E1E
-:10A31000D54B3D65DCBEDC63F0F3577BAAB9B5F1E4
-:10A32000319BBEF1E639D85F38B4CBC17902A55C68
-:10A330007BE56AE2DBB764561F1AE819CA52B643D6
-:10A34000A0E0B82B1B955193CE62C53F8B2C3E5B92
-:10A35000EE9A3CEEC279B17C30F6D044B4DBDB2B14
-:10A3600067E29F75938E1939018A771624E50BEA07
-:10A370002037A95FEFBE2269FC066D69D27B9BBEC8
-:10A38000DFA81372B331B03C69FCA186F5F1BBC9FB
-:10A39000AFAF7169946F68D25727BDBFB9EC8624FF
-:10A3A0007820371BA4A773BA12E8C6E74FA6ABBA4A
-:10A3B000E3C271904DE7D11439988DBEA97C6BE34F
-:10A3C00035671AAF22AE8C525CA9D3B9CBA56D0804
-:10A3D0006A68DA2F3181F24BF6BA4A35C69715977B
-:10A3E0003FBECCA2F8B2285D7CF921E76DE68C2F48
-:10A3F0001B93E3CBAC14BCCD155FBE7A89F8DC5A55
-:10A4000028F26E39AFCBEC07CA8D61B67FB9E3B2E3
-:10A41000B191424FCB1FF392CCE3B8AD552AFB97D5
-:10A420008760220022AF984FF630B7DCC8277DF353
-:10A43000A4CF5C781BC5F94D0EE3284E79B1EE2B05
-:10A4400001F23BF6ED7E34804609FEA7C5C1FA2E27
-:10A450005677660BC995A2A31F27716B8EA6F14F85
-:10A46000ECF176BEF1E016916F3C68E51B0F5AEBFC
-:10A470002042D8DE8E54897CE3AF5B742BFF17E15A
-:10A48000FCE2E12D6BAC7C23F657D07083EDF8A095
-:10A49000D730EF20FEF9850722F8E880A4654964EB
-:10A4A0002FB63834CA1F8F34AE7A97F249FB3CAAD4
-:10A4B00041021FF5ADC927FE92B7A2DB83FDE1C6BD
-:10A4C000E19769BE52EAE07E74CB559C171CC9D354
-:10A4D0009A8A29CEDB504C9806F9993FF5505E23B5
-:10A4E000EA3B13A0F9BDD78BF9B3D12735FF2F93E2
-:10A4F00026A6F8ADC41157118EFCFC993F13BCF38E
-:10A50000F2F3297EC5A04FE5BC6DFE8FF77E2B527E
-:10A5100042AADCE47CF308CA3CE169EB96966C8ABB
-:10A52000A7B63A27F2D2D90B3BFF39ED6FFA93FD6C
-:10A530008454F8FCB1F36B0ED1D5EDBC2D7EA2B7DF
-:10A54000DC381A27BC41ACB198E25E8FB0CBB3E1E6
-:10A5500041F15CB80E22776798190978B0EB1DD7E6
-:10A56000B68A3CB8D1AADB79C6A47A89D2E8E07968
-:10A57000B67EB0F3E3A975127B1F35AD224F7BFD8C
-:10A580000CBCA4BA89BC56B5E0191C17A7E6B3E702
-:10A59000AAA3CC95CF6EB6CE73B175937B5B81E7E2
-:10A5A000FD7FCD7FDFDBFA7F93FF3EBF5E34CAF2D3
-:10A5B00003CF4CFE9CE43BBA6CA13E28EA4349F52C
-:10A5C0009CD43ACE60868033BC52F8A9C3563FB2C1
-:10A5D00042C04DADEF6458799548EB521187812107
-:10A5E00088AC9885C4171EE5BB110DF96181E71091
-:10A5F000F8B075F9B745A8AD2DD487AA715FC3CB64
-:10A600001C6CC786BDA147FB480F2DF3A4958F8313
-:10A61000AD422F0E10DF72FC04A683E44EB2850417
-:10A62000420EA4D708733EC0D1569FC86769B1EAED
-:10A63000DB118F5F25BEC8E3F3F0FC54F85F3B1FCE
-:10A64000FE63C4AF510B38C1D98670BED93A5D479D
-:10A650008CD07BB7B59E5B8F5593BFF058AB26F47B
-:10A66000B0B2D2A0F30FFBD2AFF798B59EE9084B7A
-:10A67000346E5197980F6E31EFA034D9795AD09338
-:10A68000E589D6A7F79946B27E48859B5176E17A4F
-:10A69000D9D3D3FB4F8E870E48E9F7F9634B0E6B86
-:10A6A0000B81ED11F1C59E347C912AEF2AE53F1113
-:10A6B000EE098B0EB6DEF128E3EB332BC9BE83D156
-:10A6C000CB883DCEE7DD93790BC7C97D378B3C87BF
-:10A6D000AA08BD5DD089606AA8BED210E1BAE1FDCA
-:10A6E000A0B97CE7E3E162E33DB2379184F93FB181
-:10A6F000F823B52E18A3BA20F9B15417A4FE4E576B
-:10A70000673ABBFD6E8BD3B2BFE9EB3B47A8BE8374
-:10A71000F38F545BF59DA0A8EFD43DF508ECC4F78A
-:10A72000BF331DECB74ED7771A8AD7480E9623A0B1
-:10A73000FAF47CEB3BB18679D67782175DDFF9635B
-:10A740002BE2E79047D459A6EB3B6DFE79E5757493
-:10A7500088C5BB49AF7401E3C1DB340C3B299F10B2
-:10A760001071C6892A97E0AF9D92159F4103D87A50
-:10A770000A3FCD5DFAC3B9645FDE714129BE5FFF58
-:10A78000C4EB0AF587F31D6B287EBE569D78F05A00
-:10A790007ABFC6C9FAA30E29194FE28FB8CBC145BB
-:10A7A000F0886AB5B268E312B5F5EECC247DBD4100
-:10A7B0004B8E3F86A64EC8D9C49F1A1812E279A8BC
-:10A7C000CE30B349F71813BDF47C68836E0CEAE40D
-:10A7D0000F27C729434DAAD0A745C2EE0C1FD71F8C
-:10A7E00026FFAABF3B83FDCF03050E71EE1218258D
-:10A7F0007E68D293E39AE1B1E27D2524673127E7B1
-:10A80000CBBF3326C66FDFBD7294E252CDF257B78D
-:10A81000E7AF673F14FAC4B89BCB96A79C7F5C2335
-:10A82000BE88ED7402E1BFBFE0F601CA877E1075F5
-:10A83000AE2671196AD3997F6DBA6DEBBB93EB4469
-:10A840007D2A70DD74688BCAFC3F94F7C1913B4848
-:10A850004FE72D603C8F6C51F34309F270A2CDC5D8
-:10A86000F41ED922FC8B3C0784C6D2BC3FD126F40F
-:10A87000D027EF013E4F16DA651D1FE94A38EE2258
-:10A880007C1400FC231D27F0E1437CFE460794E284
-:10A890001687FD5DECBFA5F2D9785B69525CEBAA27
-:10A8A0007624E1D1E90A8639CF7D33E8A4AF1A1ABC
-:10A8B000B14FF17D970AC46FAEC0FD7CCE1CEC6732
-:10A8C00060DFDD188B28D87797845693DFFAE2CEC5
-:10A8D0008E01CAB3B8FC0E8DF8CDD57557B095C6AC
-:10A8E000573A2103DFF7812E05689F1109485FEB76
-:10A8F000106A247F7D38E0D0286FD31C6DDF41EBD8
-:10A9000037FB1700D1796B9383D73B6BAA9CB4CAF2
-:10A91000234783F25F0B3D6C77DF77861FEEC0F134
-:10A92000EF23BD223073AE5D6DC54CA70C3D397E63
-:10A9300076438CEDF05A73BC8BD6595BAD52450310
-:10A940004ED49C3942FEFA4895CB70E1BE466A244B
-:10A95000C6F7C755CE51BAE7F003755CA6757FF010
-:10A9600031F246513AF9BDB0DCA48E1FAA6E7113C4
-:10A970003FEC458A107E22530EB65FA9E3FE6CD1F0
-:10A980007F2FE285F01CC1FD96525C34897285D020
-:10A990007D53C1C7EFC076559BC2E3BE90EF885090
-:10A9A0005DA8BF496539E9F78606E8FE4F3FF23BEF
-:10A9B000C743FE10F3F370BE9FE5D05E67B86673C1
-:10A9C00019F1CB1B5519ECB757B535DE4B7EFB7A29
-:10A9D000F9A37F798AE2A70295E9D9EF0CC65F2532
-:10A9E000BE6E12FEE2C9250FB0DCF575DD0E8437B0
-:10A9F0008884DFA1BA555F650DC3B7F30DC34B441F
-:10AA00003EA9CF7F5F84F21BF16A915F30F38E72B3
-:10AA10003ECFCE2BD5597A6CB92BFC4A29CDBB47FA
-:10AA2000117561B9204AFAC04579259AA724E7BB78
-:10AA3000D64D26C7C18B53E2E0D43C13B8C74B5A5E
-:10AA4000D19E3ED986F1F17298CE2BD111588E2B22
-:10AA50005D1C2F8E548B3828E60CE76BE5E7CBF1B5
-:10AA60009B961F3CDEE3460E00F8518FC6FD2CF38B
-:10AA700037BB7311D45B3D017E7EEBDA47A5C47909
-:10AA80004395ED6E9DF5C64480E0A6EA8B543E5892
-:10AA9000DBB6C0B20F26107D872681F1EBAD5915CC
-:10AAA000273E3DFB7BE038F4130DE31E283E7F7EFE
-:10AAB0009CF6E9A2FC97D8E749DAA78BF25F627FA0
-:10AAC0002FF7E8DCBEDA53C6ED827610797E5B1F85
-:10AAD0005C89FA00F1D65020FA24FF648773FCB732
-:10AAE0000789BF5C014523F97617C4E252823E18FC
-:10AAF000F186DF25BBDC9FE761FE4BDDD7AFDA1CBB
-:10AB0000D6B9C2B711DC21844B787F71E77F3DB4A1
-:10AB100094D6794B66BECAE9DABC83F50EEA850C99
-:10AB2000F637843E8CE57938EF30B2B354A2FB504F
-:10AB30005B770B47774EB9C7754671DE09D4D7D41A
-:10AB4000EF4739A7F3F4D77CF0195AE7E33F2EE03B
-:10AB5000FB4D235BDE66B97F030390DCCB28F7B6A1
-:10AB60009CC5DE5AFC6D117F073B9E11E7673D389F
-:10AB7000E21D8FD1F9FB7F22433ABC5D2A5DC19C67
-:10AB80009F1F32AA4C1E3FE74F53373445DDB07745
-:10AB9000EC7BDC8F34039462FFEB4ED34D7CF0F5FD
-:10ABA000DD8E0BD60DBFBEFBC275C3D12F3BC0A53A
-:10ABB000CDECE30A98E03C2B85F05407ECA357D882
-:10ABC00066B787AE6E673F52D415F51ACA39505F23
-:10ABD0005B40FEF3C026B38CDFFB73D8EE0794B165
-:10ABE00038D9F500D5CB75BABF10E1BA27E567E9CA
-:10ABF000FE42EAF97B9D13EBF97C3884EA95A9F5CE
-:10AC000049C9F37D51DF5F2AEA90767DB2429D38D3
-:10AC1000FA20E1E93637E3A1F7D9EBDFA1FA975D36
-:10AC2000C70F5875606D0768BBC539CC76F2FB9FBE
-:10AC300017F550B81ECFB192169928DEB482EB9B5F
-:10AC40001BE81C73ED7FBE75C3664BBF2173F33DDC
-:10AC5000C89F59F8B4C7FD4DBB90C76B5591B786D7
-:10AC60002C95F5FCFA273C2093BFEC558F929C6CF9
-:10AC700083890D244FBD3EE1B7450F39D96FFB5491
-:10AC8000BBCE74CD534DBEBF90F7F719C66E0413FB
-:10AC90003DAE65511EE92FADE6A7DA791FB1B616B4
-:10ACA000DAC780CCFAEEFDD20D7C8FA949CA66794D
-:10ACB0005434B330515FEE6A4F7F1FA9B670B2852E
-:10ACC000D7F73A80E2AD6886F1B24EF87E4161B8BE
-:10ACD0004D20EE2BC1764D1AC073F67A4E337D6A45
-:10ACE0004B5D2B493FED6A17715BD49B3EAE7BA059
-:10ACF0005DC49F852DA12F101D6E82C97AD26F2849
-:10AD0000DA4684EFB588786D17E94B11EFEE72AC37
-:10AD100099C96BBDE40CEDA2F39ADF11FE842B20E0
-:10AD2000FC7A8CD4381F74ACC5FC0782DB4C7C5E8B
-:10AD3000C98A0A8EAD3C7F1F519B2EED662FC13B09
-:10AD40006CE9E70ACDE4BA6B05388C5E7F425D5D45
-:10AD50009F5F5D5DD2BE2FEAE937083E86E723821A
-:10AD60000FD78346F284FC7798D6B3EF97543CB75D
-:10AD7000A388EB2E9758DF3ED5627E95E0BDB829BB
-:10AD8000F8353AF7FB3B3B80E1CDF3BE466D6138C9
-:10AD900010443AF56708BFF9C93AA3339890FF7990
-:10ADA000D3A2D79B165D97233B8D8B7B6F6CC7AF70
-:10ADB000826A37D12B157E5F0F8C511D68B6F5D591
-:10ADC0007DF7B9294FDC5BB0DE4DF7D1A29EF5D9F6
-:10ADD000D4EF2F3003B47E5F4FE3B31F96121F09E9
-:10ADE000BE8F2C11F98818EAE748429EF4C576997F
-:10ADF000F7555F0071CAA7BB3CC22F7261BCA8AFF8
-:10AE000020BFB99AED393E1FA3D4C16B963CC9A6A9
-:10AE10000126DD172C0089F0853A727A3E99BCFA3A
-:10AE20008230D0BE66832337E07C8A470B34F643FA
-:10AE30007EDDAE313E7DA663268E87F9E3EBD01C26
-:10AE4000F8CA99035FD37C6DC95D2A9ECE109E8897
-:10AE50004F7C0FF0B9E04FF52C672E547854CFFF9C
-:10AE6000C8C68BC7849097C37F89F013A50B36E5BE
-:10AE700033F8455F91F12B6B619EE72A3020B48255
-:10AE8000F0A149848FD4F3573CF77803E1ED956D39
-:10AE900042AFD62A96FE08E359903F6FB2D605CB53
-:10AEA0002E356508BBD30C3FF488BCB6E0D30A74DA
-:10AEB000C7DD39E7EB57BB7D72967BD74F6ECE105F
-:10AEC000FE903EC6FABDB751C0F77A851F7A74600E
-:10AED00015FB0F37E6972E48D48F97BB4E985A171D
-:10AEE0009CAB0E38C337A69BF6F93BEDBE085D95CB
-:10AEF0009B8D3F1E24FE7192DCB8B93DEF7D613021
-:10AF000060905C2D31238074DBEB0B07887FFA8E19
-:10AF1000EF7C87EA24CAEBB241FEA6A20481C6DD1B
-:10AF2000981766F9D8586002D5951EEC31BF9B087A
-:10AF3000F7969650F966A45BA63666121C0FC423DA
-:10AF4000648F6ECA35C3C13474A8DE2CF4C7B196C1
-:10AF5000E02A9A574BBA7315C0C39BCCD5D49FAF88
-:10AF6000BE3A5F9E1ADDA4F72F5D9E5ADC74BEFECA
-:10AF70008220DFD3EAFFA14C1ED6F4B87E4B9EFAA6
-:10AF8000973C00A104B90A6E4ED13B7E4BEFF84DC1
-:10AF9000968BCD9B752B0F1C64F970923C9527E81E
-:10AFA00019BFAD674C9647C56FCB93257F244F1EC5
-:10AFB000BA1F3C594F7E4A1F887B8CA9F2156E0937
-:10AFC0006DD94C762CEFB7AD45FACCFD4F5D17F23D
-:10AFD000D45F60F1FB92A799FFCF22FFD365E15EBA
-:10AFE0004F7112BFDBEDDA2919E2488A755312B7A7
-:10AFF0009F98CAE4B6762A835B732A97DBBA291F27
-:10B00000B7EBA7AEE0B67E2A9FDB8629E4FBD5C866
-:10B01000FF5345DCDE38B59CDB8D53CBB86D9C5AB5
-:10B02000CDE39AA656727BD3D40DDCDE3C5523D6F5
-:10B03000A19A504E5AFEA772D665E07F2342F5D101
-:10B04000BEE3F7BC43F8716A2AE751A2BE355CEF54
-:10B05000712A61E6FFA30542BF6FF408FAA4F2FF6C
-:10B06000B196D0FE74FC0F4E716F4BA17B5B95ECDB
-:10B07000E70C337F9FE7EFBEF447CA83A2FF7198C6
-:10B08000DF5FA2FD9FF62B1726FB95FD79C97E6534
-:10B09000DF12DBAF748D521D6CBBA4F33DB1532D99
-:10B0A000A17FE6F521B88DDE87DADC1AF95351DF8E
-:10B0B0008D010FF6B7EE9581F27DE85F7C8BF80C81
-:10B0C000503F90DD98AFBC3EBCC9D2EFD6F80A38ED
-:10B0D000ED085F847FF23E7DAD395FEE679B67CB05
-:10B0E000FD55509691CECEE638EB85DC6B42EEA353
-:10B0F00005C101CAB74453E4DEB6A3888724B93F2B
-:10B1000065CBBD25C7397E71EF2387E41EF9EA2799
-:10B110009BC579D1DF4EB2A38A35DED928EA5BF52B
-:10B120007EA1579546A12F142DD98E22DFBC4B74DA
-:10B130004995F78822FCE3A6D27F9DB667645773D2
-:10B14000FC3E291B97D67E3F11A13CD6716529CBC9
-:10B1500077AA1C45B555CCE7C7957A4827FFF396E3
-:10B16000239F6D474CB623A9E36C79EA3BDEC47894
-:10B17000B1EDCA713CB799604F366A020F684F3E15
-:10B1800026FE4A95A7DA4233144CB34FB543F8A5CF
-:10B19000AFAD0B0A7F11FD44F253A2CEF47E80DAEC
-:10B1A00021FC9F9C46EBF7153A8473510F3636C647
-:10B1B000EBA98681F2AC7620BC75E6442FC960AF5E
-:10B1C00067D84FFB47F97475FC15F2F9D126E117E2
-:10B1D00042772EFB2D763B17DFDBFE8ECDFFA9E3FA
-:10B1E0009E2C323BD3E1E5F3165E8E0E3C9DC41FD0
-:10B1F00043CAD29B0C3DAD5E358DCBA257E7E757D6
-:10B200001C473BC77A7576BFE2BA8E347C309B5FB1
-:10B21000F1890E91CF45BF621DCDAB2D177EC5E7DD
-:10B220003BE0F2FA0B35F731BE2ED55FD86CF1DF7B
-:10B230006CFE425787AD37C2AC375C96DEB8587F9C
-:10B24000218D7F703BF32F4CCA54FF43541B221FA8
-:10B2500022F408EA99BBE83DC6F1EC2F1CF5087E04
-:10B26000312D3D736D7B7007E175A85AF80B974B34
-:10B270000ED0EFBBAF236FFEF230DF71A58FAD1D97
-:10B2800098203F07BC31BA37DD4BF795287E7CCF3D
-:10B290002BEE11009451DEFF8BF23506D9B991CC1B
-:10B2A0002F7D83C6774714A07B83433D22FFF7C5DC
-:10B2B000055947017967C8197E6AC2CFBF770D1E4D
-:10B2C000C5F60F1985A39070EFF6B0256F2ED8C282
-:10B2D000F774B3B45B9EFD3037DDFEC4FD5CBABAD3
-:10B2E000728E7FD751A0F13D320B3F596A10227EFA
-:10B2F000922307D747D0DB83EA84BC475F4D5727AB
-:10B30000C7C1F922EF25837286F2EF03B49638178E
-:10B310009FB37FB1FB513A970E218677D0EFE0BC07
-:10B320007BFF5A11EFF47BC26E2D8DDED8D7937C54
-:10B33000FF28B595973D16A33BC287038A4169CF85
-:10B34000C1B2CA26CA4F4635AE0083EA7304D3D5CC
-:10B35000A7C72DF9D4C1607BAC7CB2253B9DBDB0A5
-:10B36000DB010BFF76DF5D326612DFA94566907F59
-:10B3700087E3F34B9184BCF11316FCBD9211AF45EA
-:10B3800064EDF50AFDEFD66326FDDEB82FEF2EAE95
-:10B3900033BAF5089CA1E72531F839E9A77C77E7AE
-:10B3A000689A7DBCD521E294BDCE10AFB7375FE17E
-:10B3B000FAE3DEA2F4F9ACE73B441E49F5AD0F72A7
-:10B3C0005EDFA7709D3875DC53169FF4AB6640E3D3
-:10B3D000B8FA81323A577409708E72EC9D379FD853
-:10B3E0008DFDFD3D41CE7B0C51FE0385B5BFF05E6A
-:10B3F000C6FBFE6B1C1A9D6383FC11DF47385C0D96
-:10B4000006E98FEC6A1C9710471E86D101BA0F77A8
-:10B41000782D70BED46B0493DEF723038E93FFA5C3
-:10B420004CB03E734237D7010EF855BEA73354795E
-:10B430009AFD231DC6394F315429E865D793FC1670
-:10B440003FFAFD773527CAC1018B6E0F52DE9CEFA4
-:10B45000318D41A2FF75A0709CEDF38175E39D5481
-:10B4600017CCF2BB0D0A45F6D70481E474A8CA9143
-:10B47000F67ED450D569DE67EA7E9C277EC9FA2F16
-:10B480004B99E0FC4456D96FD9AE3C64ED63E35A66
-:10B49000E0CD66570B3D9BDD1606FA7D58DE5BF26C
-:10B4A000A88EFDDD85BF8A38493E6E0358A4D37E41
-:10B4B0002778BF879B9F8EF3FEACFBBA203FCFF768
-:10B4C000712128E4D7BE77BDB04D4D8ADFB352EE6F
-:10B4D0004565A6F441EEBAE07DB2EEF7EE3975327D
-:10B4E00001DEA2CEE4FBD973CDFF43CF8E5327916B
-:10B4F0005F0E575E58BE0E59758D584F35D3C9E64D
-:10B50000339BEFB2E88839B3CF1FF28D75A6B3C372
-:10B510001D9D420E52F93195FF34D718DBF143EBF4
-:10B5200092E1DCD029E4F8060B4E4EA19E4FEFEDE0
-:10B530007B4C747FEAE934EB7EBA53E5F1337C6DE2
-:10B54000DBF9772ECDCE2F6B1176DEBF2A83EC3C54
-:10B55000E2F365BAC7F67B940F4890EB3E6FB29F5B
-:10B5600069DBF9C73B457CF062DE5512D9E91CCF97
-:10B5700004FBBF59D5C97980543BAD3A431C37AA67
-:10B58000F9AAAD6FB89EF55AC7FB4F4410CEFEF82E
-:10B590003EAE0F6522FF66484CA7483A3A4179F221
-:10B5A000BD9AF24E10BF63D3855EC85AAB70BD63BF
-:10B5B000C8F15EF587D82AB130042DB883CCB7FB2B
-:10B5C000C7F97E8EC5F773D1933E7F5A63FD2E85F2
-:10B5D000EA88F56F56A78B2BEC96EE4F25DF77BFE9
-:10B5E00038B9F8FB4EABBE9C0119422E9A1D7D6402
-:10B5F000EF9B1D7C2F85AEEF2A6BACD201D5F56990
-:10B6000067F8DE4FF77F24AB5EB474465EE0567198
-:10B61000AFE5EC0E714F867F47B8947EF739C1BF16
-:10B620000FBC926EB1CAEC07B3DC9C850207D583D0
-:10B6300023272469DA0FBA82AE341A0E9A570241D0
-:10B640006E53F77D1584F97919C4B8BD06C6B82DB7
-:10B6500087716E2B60925B9326E07E8D93A2AEB1D4
-:10B660000A0C999E574290DB3510E6B61A62DC7ED2
-:10B67000A5FE6F7F733B4EF9DA797811784D23DFA1
-:10B6800071043A7D7E1BCFAD9D3AF3C95CF4EEF3B5
-:10B690004DB01F5F5F3DCE7EA8D71364FE76FA05DE
-:10B6A0007FDB709CB3E4836D3F49253F69751AFECB
-:10B6B0009DC34F4AFD1DC9FF0229F7D0B3D04500F5
-:10B6C0000000000000000000000000180000000062
-:10B6D000000000000000004000000000000000002A
-:10B6E0000000002800000000000000000000001022
-:10B6F000000000000000000000000020000000002A
-:10B700000000000000000010000000000000000029
-:10B710000000000800000000000000000000000021
-:10B7200000000000000000000000003900000000E0
-:10B7300000000000000000380000000000000000D1
-:10B7400000000000000000000000000000000008F1
-:10B7500000000000000000000000000000000000E9
-:10B76000000000000000000C0000000000000000CD
-:10B770000000000E000000000000000000000004B7
-:10B7800000000000000000000000001800000000A1
-:10B79000000000000000001C00000000000000008D
-:10B7A0000000001C0000000000000000000000136A
-:10B7B00000000000000000000000003A000000004F
-:10B7C0000000000000000001000000000000000078
-:10B7D0000000000200000000000000000000000166
-:10B7E0000000000000000000000000100000000049
-:10B7F00000000000000000500000000000000000F9
-:10B800000000000000000000000000000000000335
-:10B810000000000000000000000000AB000000007D
-:10B820000000000000000008000000000000000010
-:10B830000000C00000100000000000080000C00868
-:10B8400000100000000000020000C0000010000016
-:10B850000000001000009FB0000000000000000881
-:10B860000000C08000100000000000040000C0883C
-:10B8700000100000000000020000C0800010000066
-:10B8800000000010000091200000000000000008EF
-:10B8900000009340000100040000000100009348F4
-:10B8A00000000000000000020000935000000000B3
-:10B8B0000000000800009354000000000000000297
-:10B8C00000009418000000000000000800009358D9
-:10B8D000000800000000000800009AB000400000CE
-:10B8E00000000040000093980008000000000008DD
-:10B8F000000093D800080000000000080000942019
-:10B9000000C8000000000098000095B000980000FA
-:10B9100000000028000095F00098000000000028BA
-:10B920000000C480054000300000054000009D205C
-:10B93000000800000000000100009D210008000038
-:10B9400000000001000020080010000000000010AE
-:10B9500000002000000000000000000800009CD84B
-:10B96000000800000000000200009D180000000018
-:10B9700000000001000000010000000000000000C5
-:10B9800000000009000000000000000000000002AC
-:10B9900000000000000000000000CF2000000000B8
-:10B9A000000000200000CF46000000000000000161
-:10B9B0000000600000200000000000200000730074
-:10B9C000000800000000000800009FA00000000028
-:10B9D0000000000100009FA800000000000000011E
-:10B9E00000009F60000000000000001000009F6346
-:10B9F000000000000000000100009F610000000046
-:10BA00000000000100009F6600000000000000012F
-:10BA100000009F67000000000000000000009F6819
-:10BA2000000000000000000400009F6C0000000007
-:10BA300000000004000000520000000000000000B0
-:10BA400000000003000000000000000000000003F0
-:10BA500000000000000000000000000500000000E1
-:10BA600000000000000000020000000000000000D4
-:10BA700000060000000000000000002000009F7091
-:10BA8000000000000000000100009F900000000086
-:10BA9000000000080000005300000000000000004B
-:10BAA00000009F98000000000000000200009F9C22
-:10BAB000000000000000000100009F9D0000000049
-:10BAC000000000010000000900000000000000006C
-:10BAD0000000000100000000000000000000004421
-:10BAE0000000000000000000000000010000000055
-:10BAF00000000000000000500000000000000000F6
-:10BB0000000000890000000000000000000012C8D2
-:10BB10000080000000000080000000010000000024
-:10BB2000000000000000A000071000000000071047
-:10BB300000001AC800000000000000080000AEC0AD
-:10BB400000080000000000080000AE4000080000EF
-:10BB5000000000080000AE8000080000000000089F
-:10BB6000000020080010000000000010000020006D
-:10BB700000000000000000080000A01007100040B6
-:10BB80000000004000001BF8000800000000000159
-:10BB900000001BF9000800000000000100001AD09E
-:10BBA000000000000000000100001AD800000000A2
-:10BBB0000000000200001ADA00000000000000028D
-:10BBC0008000000000000000000000000000AF0046
-:10BBD000000000000000002000001B78002800008A
-:10BBE000000000040000E000002000000000002031
-:10BBF0000000F300000800000000000800001AF038
-:10BC0000000000000000010800001B3700000000D9
-:10BC10000000000100001B0F0000000000000001F8
-:10BC200000001B70000000000000000400001B74F6
-:10BC300000000000000000040000005000000000B0
-:10BC400000000000000000030000000000000000F1
-:10BC500000000005000000000000000000000006D9
-:10BC600000000000000000000000000700000000CD
-:10BC70000000000000001BC80000000000000001E0
-:10BC800000001BE800000000000000080000005158
-:10BC9000000000000000000000001BD000000000B9
-:10BCA0000000000400001BD400000000000000049D
-:10BCB00000001BD8000000000000000400001BDC96
-:10BCC00000000000000000080000B00000180000A4
-:10BCD000000000180000C00000400000000000400C
-:10BCE0000000C00000400002000000010000C00190
-:10BCF00000400002000000000000E2000020000000
-:10BD0000000000200000E204000200080020000201
-:10BD10008000000000000000000000000000E200C1
-:10BD200000080020000000040000F40000280000CB
-:10BD3000000000280000F540001000000000001086
-:10BD40000000F5C000200000000000200000F5C049
-:10BD500000020020000000020000F30000200000AC
-:10BD6000000000200000200800100000000000106B
-:10BD70000000200000000000000000080000110882
-:10BD80000008000000000008000011680008000022
-:10BD900000000008000011A80008000000000008D2
-:10BDA00000001240000800000000000100001241E5
-:10BDB0000008000000000001000040000020000416
-:10BDC00000000010000059000030001800000010B2
-:10BDD0000000590800300018000000020000570061
-:10BDE00000080000000000010000570100080000EA
-:10BDF00000000001000011E8000000000000000148
-:10BE0000000011F00000000000000001000011F827
-:10BE100000000000000000100000124400080000B4
-:10BE2000000000040000400000200000000000208E
-:10BE30000000530000100000000000100000153842
-:10BE400000000000000000010000000300000000EE
-:10BE500000000000000000000000000000000000E2
-:10BE600000000001000000000000000000000004CD
-:10BE700000000000000000000000150800000000A5
-:10BE8000000000010000152800000000000000086C
-:10BE900000000050000000000000000000008308C7
-:10BEA0000080000000000080000000010000000091
-:10BEB000000000000000200800100000000000103A
-:10BEC00000002000000000000000000800008410B6
-:10BED0000008000000000008000084700008000056
-:10BEE0000000000800060000046000280000046054
-:10BEF00000008520000800000000000100008521EE
-:10BF000000080000000000018000000000000000A8
-:10BF10000000000000008408000000000000000194
-:10BF2000000084F40008000000000002000084F615
-:10BF3000000800000000000200008504001000005E
-:10BF400000000004000087600000000000000020E6
-:10BF500000006000002000000000002000007300CE
-:10BF600000080000000000080000000300000000BE
-:10BF700000000000000000050000000000000000BC
-:10BF800000000006000000000000000000000007A4
-:10BF90000000000000000000000088080000000011
-:10BFA00000000001000088280000000000000008D8
-:10BFB0000000005000000000000000000000881099
-:10BFC00000000000000000040000881400000000D1
-:10BFD00000000004000088180000000000000004B9
-:10BFE0000000881C00000000000000080000300075
-:10BFF0000040000000000008000030080040000081
-:10C00000000000280000339001C00010000000086C
-:10C010000000320000200000000000200000372057
-:10C02000000000000000000800001020062000387A
-:10C03000000000080000A000000000000000200038
-:10C0400000003EA9000000000000000100003EC802
-:10C05000000000000000000280000000000000005E
-:10C060000000000000006000002000000000000848
-:10C070000000400000080000000000010000400136
-:10C08000000800000000000100004040000800041B
-:10C0900000000002000040600008000400000004EE
-:10C0A0000000400000080000000000040000400400
-:10C0B00000080000000000040000404000000000F4
-:10C0C00000000008000040480000000000000008D8
-:10C0D0000000800000000000000000100000504040
-:10C0E00000010004000000010000500000000000FA
-:10C0F00000000020000050080010000000000004B4
-:10C100000000500C0010000000000001000052C7A9
-:10C110000000000000000001000052C60000000006
-:10C120000000000100003000003000180000000492
-:10C130000000300400300018000000040000300847
-:10C1400000300018000000020000300A0030001823
-:10C15000000000020000300C003000180000000158
-:10C160000000300D00300018000000010000300E0B
-:10C1700000300018000000010000301000300018EE
-:10C18000000000040000301400300018000000041B
-:10C19000000050000100008000080004000050046E
-:10C1A00001000080000800040000000A00000000F8
-:10C1B0000000000000005068010000800000000145
-:10C1C0000000506901000080000000010000506C78
-:10C1D00001000080000000020000506E010000809D
-:10C1E0000000000200005070010000800000000408
-:10C1F0000000507401000080000000040000506640
-:10C200000100008000000002000050640100008076
-:10C2100000000001000050600100008000000002EA
-:10C220000000506201000080000000020000505039
-:10C230000100008000000004000050540100008054
-:10C2400000000004000050580100008000000004BD
-:10C250000000505C01000080000000040000507CE1
-:10C2600001000080000000010000507D01000080FE
-:10C270000000000100004018001000000000000451
-:10C2800000004090001000000000000400004098F2
-:10C290000010000000000004000041100000000039
-:10C2A0000000000200004112000000000000000237
-:10C2B00000004114000000000000000200004116D0
-:10C2C00000000000000000020000604000080000C4
-:10C2D00000000002000060420008000000000002B0
-:10C2E00000006044000800000000000400006080BE
-:10C2F0000008000000000008000060C000400008C6
-:10C3000000000008000060000008000000000002BB
-:10C31000000060020008000000000001000060044E
-:10C320000008000000000002000063400008000058
-:10C330000000000800006380000800000000000406
-:10C34000000063840008000000000001000063C0DA
-:10C350000008000000000002000063C400080000A4
-:10C36000000000020000640000080000000000045B
-:10C3700000007000001000000000000400007004C5
-:10C380000010000000000004000070080010000011
-:10C3900000000004000090000008000000000002FF
-:10C3A000000090020008000000000001000090045E
-:10C3B000000800000000000200009040000800009B
-:10C3C000000000020000904400080000000000028D
-:10C3D000000090460008000000000002000096489F
-:10C3E0000008000000000008000090800008000025
-:10C3F000000000020000908400080000000000021D
-:10C40000000096880008000000000008000080403E
-:10C41000000800000000000100008041000800004A
-:10C420000000000100008042000800000000000140
-:10C4300000008043000800000000000100008000B0
-:10C440000008000000000002000080020008000058
-:10C45000000000010000800400080000000000024D
-:10C46000000080C00008000000000002000080C240
-:10C470000008000000000002000080C40008000066
-:10C4800000000002000080800008000000000001A1
-:10C490000000808100080000000000010000808290
-:10C4A0000008000000000001000080830008000078
-:10C4B000000000010000808400080000000000016E
-:10C4C0000000808500080000000000010000808658
-:10C4D00000080000000000010000600000080000EB
-:10C4E00000000002000060020008000000000001DF
-:10C4F000000060040008000000000002000060422C
-:10C5000000C00018000000020000604000C00018D9
-:10C51000000000020000604C00C00018000000088D
-:10C520000000604400C000180000000800006057D0
-:10C5300000C00018000000010000605400C0001896
-:10C54000000000020000605600C00018000000015A
-:10C55000000066400008000000000008000066803F
-:10C560000008000000000008000066C0000800008D
-:10C57000000000080000DA4200180000000000027D
-:10C580000000DE4000000000000000000000E000AD
-:10C5900000000000000000040000D0C00000000007
-:10C5A000000000040000D0C40000000000000004EF
-:10C5B0000000D0C800000000000000040000D0CC43
-:10C5C00000000000000000040000D0D000000000C7
-:10C5D000000000040000D0D40000000000000004AF
-:10C5E0000000D0D800000000000000040000D0C00F
-:10C5F00000000000000000200000DB000000000040
-:10C60000000000040000DB000000000000000068E3
-:10C610000000B94800000000000000000000D00049
-:10C6200000000000000000040000B0C00000000096
-:10C63000000000040000B0C400000000000000047E
-:10C640000000B0C800000000000000040000B0C0FE
-:10C6500000000000000000100000D6B00000000044
-:10C66000000000040000D6B4000000000000000438
-:10C670000000D6B800000000000000040000D6BC96
-:10C6800000000000000000040000D6B00000000020
-:10C69000000000100000D348000000000000000867
-:10C6A0000000D358000000000000008000000010CF
-:10C6B00000000000000000000000D358000000004F
-:10C6C0000000000800000000060209000000000051
-:00000001FF
--- /dev/null
+++ zfcpdump-kernel-4.4/firmware/bnx2x/bnx2x-e2-7.12.30.0.fw.ihex
@@ -0,0 +1,20088 @@
+:10000000000037E000000068000005D8000038500C
+:100010000000556400003E300000009000009398FE
+:100020000000F43000009430000000C40001886833
+:1000300000015EC800018930000000700002E80085
+:10004000000055CC0002E878000000AC00033E48F8
+:100050000001961400033EF80000120C0004D510B5
+:10006000000000040004E720021100B800000001B5
+:10007000020600DC000000010206005000000180C2
+:100080000306100001FF00000A0000010000000844
+:10009000020617FC003FE0010A000001000000100A
+:1000A000030617FC020101FF0A000001000000081E
+:1000B00003060200000304000A0000010000001013
+:1000C00003060200000304030A00000100002000F0
+:1000D0000406024C000000020A0000040000202078
+:1000E000030601E000040406030602440002040AB9
+:1000F000030602540002040C030602640002040E0C
+:100100000A00000300002040030601E00004041080
+:1001100003060240000304140206026400000028E3
+:10012000020600DC000000000A00000100000008D8
+:10013000030601D8000204170A0000020000202074
+:10014000030601C000020419030601D00004041BC9
+:100150000A00000200002040030601C00002041F44
+:10016000030601D0000404210A0000020000204020
+:1001700003060220000204250306023000040427BF
+:10018000020D004400000032030D004C0004042B5B
+:10019000040D005C00000004030D008C0004042F1B
+:1001A000030D00A000050433020D00B8000000029A
+:1001B000030D00C000040438020D015C00000001C2
+:1001C000030D01640002043C020D02040000000162
+:1001D000030D020C0003043E030D02200002044143
+:1001E000040D028000000012030D030000180443F8
+:1001F000040D400000000A000A0000010000000891
+:10020000040D03600000000C030D0004000F045BEC
+:10021000020D01140000000D020D01180000002D58
+:10022000020D01140000001D020D01180000003D28
+:10023000020D01140000004D020D01180000006DB8
+:10024000020D01140000005D020D01180000007D88
+:10025000031010000003046A021010500000000197
+:10026000071011000010046D081011400000000874
+:10027000071011600010047D081011A00000001884
+:10028000071018000200048D04104C00000001004B
+:1002900002107004000000010A00000100000008C4
+:1002A000031040D40002068D021040280000001008
+:1002B000031040400002068F021040580028000042
+:1002C000021040840084924A02104058000000004E
+:1002D0000210413800000001021041380000000106
+:1002E00002104138000000010210413800000001F6
+:1002F00002104138000000010210413800000001E6
+:1003000002104138000000010210413800000001D5
+:10031000030C200800030691030C201C0004069423
+:10032000030C203800040698040C20480000001D2F
+:10033000020C20BC00000001040C20C00000003FA3
+:10034000030C21BC0003069C040C21C80000001C07
+:10035000030C22380004069F010C22480000000014
+:10036000010C224C00000000010C22500000000093
+:10037000010C225400000000010C22580000000073
+:10038000010C225C00000000010C22600000000053
+:10039000010C226400000000010C22680000000033
+:1003A000010C226C00000000010C22700000000013
+:1003B000010C227400000000010C227800000000F3
+:1003C000010C227C00000000030C22D8000406A3CC
+:1003D0000A00000100000009020C2000000003E8F0
+:1003E0000A0000010000000A020C200000000003C7
+:1003F0000A0000010000000C020C200000000001B7
+:100400000A00000100001001020C2000000005DCC1
+:100410000A00000100001002020C2000000000048D
+:100420000A00000100001004020C2000000000017E
+:100430000A00000100002001020C2000000005DC81
+:100440000A00000100002002020C2000000000044D
+:100450000A00000100002004020C2000000000013E
+:10046000052004000070000006200780001006A789
+:1004700004220000000040000423240000001600B5
+:1004800003221170000806A9032211A8009006B1EA
+:100490000422C000000000060322C0180004074127
+:1004A0000422C0280000000C0322C05800040745A5
+:1004B0000422C0680000000C0322C0980004074911
+:1004C0000422C0A80000000C0322C0D80004074D7D
+:1004D0000422C0E80000000C0322C11800040751E8
+:1004E0000422C1280000000C0322C1580004075553
+:1004F0000422C1680000000C0322C19800040759BF
+:100500000422C1A80000000C0322C1D80004075D2A
+:100510000422C1E80000000C0322C2180004076195
+:100520000422C2280000000C0322C2580004076500
+:100530000422C2680000000C0322C298000407696C
+:100540000422C2A80000000C0322C2D80004076DD8
+:100550000422C2E80000000C0322C3180004077143
+:100560000422C3280000000C0322C35800040775AE
+:100570000422C3680000000C0322C398000407791A
+:100580000422C3A80000000C0322C3D80004077D86
+:100590000422C3E80000000C0322C41800040781F1
+:1005A0000422C4280000000C0322C458000407855C
+:1005B0000422C4680000000C0322C49800040789C8
+:1005C0000422C4A80000000C0322C4D80004078D34
+:1005D0000422C4E80000000C0322C518000407919F
+:1005E0000422C5280000000C0322C558000407950A
+:1005F0000422C5680000000C0322C5980004079976
+:100600000422C5A80000000C0322C5D80004079DE1
+:100610000422C5E80000000C0322C618000407A14C
+:100620000422C6280000000C0322C658000407A5B7
+:100630000422C6680000000C0322C698000407A923
+:100640000422C6A80000000C0322C6D8000407AD8F
+:100650000422C6E80000000C0322C718000407B1FA
+:100660000422C7280000000C0322C758000407B565
+:100670000422C7680000000C0322C798000407B9D1
+:100680000422C7A80000000C0322C7D8000407BD3D
+:100690000422C7E80000000C0322C818000407C1A8
+:1006A0000422C8280000000C0322C858000407C513
+:1006B0000422C8680000000C0322C898000407C97F
+:1006C0000422C8A80000000C0322C8D8000407CDEB
+:1006D0000422C8E80000000C0322C918000407D156
+:1006E0000422C9280000000C0322C958000407D5C1
+:1006F0000422C9680000000C0322C998000407D92D
+:100700000422C9A80000000C0322C9D8000407DD98
+:100710000422C9E80000000C0322CA18000407E103
+:100720000422CA280000000C0322CA58000407E56E
+:100730000422CA680000000C0322CA98000407E9DA
+:100740000422CAA80000000C0322CAD8000407ED46
+:100750000422CAE80000000C0322CB18000407F1B1
+:100760000422CB280000000C0322CB58000407F51C
+:100770000422CB680000000C0322CB98000407F988
+:100780000422CBA80000000C0322CBD8000407FDF4
+:100790000422CBE80000000C0322CC18000408015E
+:1007A0000422CC280000000C0322CC5800040805C9
+:1007B0000422CC680000000C0322CC980004080935
+:1007C0000422CCA80000000C0322CCD80004080DA1
+:1007D0000422CCE80000000C0322CD18000408110C
+:1007E0000422CD280000000C0322CD580004081577
+:1007F0000422CD680000000C0322CD9800040819E3
+:100800000422CDA80000000C0322CDD80004081D4E
+:100810000422CDE80000000C0322CE1800040821B9
+:100820000422CE280000000C0322CE580004082524
+:100830000422CE680000000C0322CE980004082990
+:100840000422CEA80000000C0322CED80004082DFC
+:100850000422CEE80000000C0322CF180004083167
+:100860000422CF280000000C0322CF5800040835D2
+:100870000422CF680000000C0322CF98000408393E
+:100880000422CFA80000000C0322CFD80004083DAA
+:100890000422CFE80000000C0322D0180004084115
+:1008A0000422D0280000000C0322D0580004084580
+:1008B0000422D0680000000C0322D09800040849EC
+:1008C0000422D0A80000000C0322D0D80004084D58
+:1008D0000422D0E80000000C0322D11800040851C3
+:1008E0000422D1280000000C0322D158000408552E
+:1008F0000422D1680000000C0322D198000408599A
+:100900000422D1A80000000C0322D1D80004085D05
+:100910000422D1E80000000C0322D2180004086170
+:100920000422D2280000000C0322D25800040865DB
+:100930000422D2680000000C0322D2980004086947
+:100940000422D2A80000000C0322D2D80004086DB3
+:100950000422D2E80000000C0322D318000408711E
+:100960000422D3280000000C0322D3580004087589
+:100970000422D3680000000C0322D39800040879F5
+:100980000422D3A80000000C0322D3D80004087D61
+:100990000422D3E80000000C0322D41800040881CC
+:1009A0000422D4280000000C0322D4580004088537
+:1009B0000422D4680000000C0322D49800040889A3
+:1009C0000422D4A80000000C0322D4D80004088D0F
+:1009D0000422D4E80000000C0322D518000408917A
+:1009E0000422D5280000000C0322D55800040895E5
+:1009F0000422D5680000000C0322D5980004089951
+:100A00000422D5A80000000C0322D5D80004089DBC
+:100A10000422D5E80000000C0322D618000408A127
+:100A20000422D6280000000C0322D658000408A592
+:100A30000422D6680000000C0322D698000408A9FE
+:100A40000422D6A80000000C0322D6D8000408AD6A
+:100A50000422D6E80000000C0322D718000408B1D5
+:100A60000422D7280000000C0322D758000408B540
+:100A70000422D7680000000C0322D798000408B9AC
+:100A80000422D7A80000000C0322D7D8000408BD18
+:100A90000422D7E80000000C0322D818000408C183
+:100AA0000422D8280000000C0322D858000408C5EE
+:100AB0000422D8680000000C0322D898000408C95A
+:100AC0000422D8A80000000C0322D8D8000408CDC6
+:100AD0000422D8E80000000C0322D918000408D131
+:100AE0000422D9280000000C0322D958000408D59C
+:100AF0000422D9680000000C0322D998000408D908
+:100B00000422D9A80000000C0322D9D8000408DD73
+:100B10000422D9E80000000C0322DA18000408E1DE
+:100B20000422DA280000000C0322DA58000408E549
+:100B30000422DA680000000C0322DA98000408E9B5
+:100B40000422DAA80000000C0322DAD8000408ED21
+:100B50000422DAE80000000C0322DB18000408F18C
+:100B60000422DB280000000C0322DB58000408F5F7
+:100B70000422DB680000000C0322DB98000408F963
+:100B80000422DBA80000000C0322DBD8000408FDCF
+:100B90000422DBE80000000C0322DC180004090139
+:100BA0000422DC280000000C0322DC5800040905A4
+:100BB0000422DC680000000C0322DC980004090910
+:100BC0000422DCA80000000C0322DCD80004090D7C
+:100BD0000422DCE80000000C0322DD1800040911E7
+:100BE0000422DD280000000C0322DD580004091552
+:100BF0000422DD680000000C0322DD9800040919BE
+:100C00000422DDA80000000C0322DDD80004091D29
+:100C10000422DDE80000000C0322DE180004092194
+:100C20000422DE280000000C0322DE5800040925FF
+:100C30000422DE680000000C0322DE98000409296B
+:100C40000422DEA80000000C0322DED80004092DD7
+:100C50000422DEE80000000C0322DF180004093142
+:100C60000422DF280000000C0322DF5800040935AD
+:100C70000422DF680000000C0322DF980004093919
+:100C80000422DFA80000000C0322DFD80004093D85
+:100C90000422DFE80000000C0322E01800040941F0
+:100CA0000422E0280000000C0322E058000409455B
+:100CB0000422E0680000000C0322E09800040949C7
+:100CC0000422E0A80000000C0322E0D80004094D33
+:100CD0000422E0E80000000C0322E118000409519E
+:100CE0000422E1280000000C0322E1580004095509
+:100CF0000422E1680000000C0322E1980004095975
+:100D00000422E1A80000000C0322E1D80004095DE0
+:100D10000422E1E8000000060422F6400000002062
+:100D20000223800000000010022380400000001217
+:100D30000223808000000030022380C00000000EEB
+:100D400002238BC0000000010A000002000000081E
+:100D50000223838000086470022383C000000226FF
+:100D60000A000002000000090223830000086470EA
+:100D700002238340000002260A0000020000000A4D
+:100D8000022383000000055F02238340000000016E
+:100D90000A0000020000000C02238300000001573B
+:100DA00002238340000000000A000002000010003F
+:100DB00002238380000C96A8022383C0000003391D
+:100DC0000A0000020000100102238300000C96A814
+:100DD00002238340000003390A00000200001002D1
+:100DE000022383000000080E02238340000000025B
+:100DF0000A00000200001004022383000000020326
+:100E000002238340000000000A00000200002000CE
+:100E100002238380000CF850022383C00000035299
+:100E20000A0000020000200102238300000CF85099
+:100E300002238340000003520A0000020000200247
+:100E4000022383000000084D0223834000000002BB
+:100E50000A000002000020040223830000000213A5
+:100E600002238340000000000524000033580000E6
+:100E70000524800022710CD60624C670659809618D
+:100E80000A0000010000000202231480000000009C
+:100E90000A0000010000000402231480000000008A
+:100EA0000A0000010000001102231480000000006D
+:100EB0000A00000100000008022000BC000000320F
+:100EC0000A00000400000010022000BC0000000224
+:100ED00002238840000000010120013800000000CA
+:100EE00002238840000000000A00000100000011F9
+:100EF0000223148000000001012000000000000017
+:100F00000120000400000000012000080000000093
+:100F10000120000C00000000012000100000000073
+:100F2000012000140000000003200020001A0963C3
+:100F3000032000A40002097D02200224000000001A
+:100F400002200234000000000220024C00000000D9
+:100F5000022002E40000FFFF08202000000008003B
+:100F60000A000001000000100820400000000200FC
+:100F700004221108000000020422340000000002D4
+:100F800004225900000000060422604000000030E6
+:100F90000422F300000000100422111000000002DF
+:100FA0000422340800000002042259180000000640
+:100FB00004226100000000300422F3400000001011
+:100FC0000422111800000002042234100000000264
+:100FD0000422593000000006042261C000000030E5
+:100FE0000422F380000000100422112000000002FF
+:100FF00004223418000000020422594800000006B0
+:1010000004226280000000300422F3C000000010BF
+:1010100004221128000000020422342000000002F3
+:1010200004225960000000060422634000000030E2
+:101030000422F4000000001004221130000000021D
+:10104000042234280000000204225978000000061F
+:1010500004226400000000300422F440000000106C
+:101060000422113800000002042234300000000283
+:101070000422599000000006042264C000000030E1
+:101080000422F4800000001004221140000000023D
+:101090000422343800000002042259A8000000068F
+:1010A00004226580000000300422F4C0000000101B
+:1010B00004102400000000E00310201C0002097F3F
+:1010C000021020C000000002031020040002098169
+:1010D00002170008000000020217002C00000003A5
+:1010E00002170038007C100403170044000609832F
+:1010F000021700700000000C031700780002098935
+:10110000021701C408100000021703440000000188
+:10111000031704000008098B031704300008099323
+:10112000031704800004099B0A0000010000000866
+:101130000217003C000000040A000001000000103B
+:101140000217003C00000008021700040000000F16
+:10115000021701EC00000002021701F40000000277
+:10116000021701EC00000002021701F40000000267
+:10117000021701EC00000002021701F40000000257
+:10118000021701EC00000002021701F40000000247
+:10119000021701EC00000002021701F40000000237
+:1011A000021701EC00000002021701F40000000227
+:1011B000021701EC00000002021701F40000000217
+:1011C000021701EC00000002021701F40000000207
+:1011D0000A0000010000000802130078000000323D
+:1011E0000213003C000061A8041301080000000382
+:1011F000021301040000000002130134000000008B
+:1012000004130108000000030213010400000000A1
+:101210000213013400000000041301080000000361
+:10122000021301040000000002130134000000005A
+:101230000413010800000003021301040000000071
+:101240000213013400000000041301080000000331
+:10125000021301040000000002130134000000002A
+:101260000413010800000003021301040000000041
+:101270000213013400000000041301080000000301
+:1012800002130104000000000213013400000000FA
+:101290000413010800000003021301040000000011
+:1012A00002130134000000000A0000010000008861
+:1012B0000200A5F8000000000A000001000001087B
+:1012C0000200A5F8000000010A00000100000090E3
+:1012D0000200AA84000000000A00000100000110C2
+:1012E0000200AA84000000010A0000010000009032
+:1012F0000200AA88000000000A000001000001109E
+:101300000200AA88000000010200A2700000000094
+:101310000200A274000000000200A27000000000A1
+:101320000200A274000000000200A2700000000091
+:101330000200A274000000000200A2700000000081
+:101340000200A2740000000002016204000000001C
+:101350000A000001000022000401602C00000007C8
+:10136000030100B40002099F030100CC000209A19F
+:10137000020100DC0000000103010100000209A3DA
+:101380000201007C003000000201008400000028FF
+:101390000201008C00000000020101300000000486
+:1013A0000201032800000000020105540000003083
+:1013B000020160580000FFFF0201606000000000B1
+:1013C0000201607000000007020160B00000000030
+:1013D000020160C000000001020160C800000000BE
+:1013E00002016208000000000401805400000003B4
+:1013F0000201807800000000020180E80000000780
+:10140000030180F8000209A50301810C000209A76D
+:1014100002018124000000000A0000020000000810
+:10142000020180E400004688030180EC000209A963
+:101430000A00000100000080020180380000000660
+:101440000A000001000002000201803800000007CD
+:101450000A000001000004000201803800000006BC
+:101460000A00000100000800020180380000000EA0
+:101470000A00000400002000020180EC0000003897
+:1014800002018100000025E40201811400004BC824
+:1014900003018680000409AB020100C400000001C2
+:1014A000020100F800000001020100F0000000014C
+:1014B00002010080003000000201008800000028C6
+:1014C000020100900000000002010134000000044D
+:1014D0000201032C0000000002010564000000303E
+:1014E0000201605C0000FFFF020160640000000078
+:1014F0000201607400000007020160B400000000F7
+:10150000020160C400000001020160CC0000000084
+:101510000201620C00000000040181A80000000428
+:10152000020181D0000000000201823400000007A7
+:1015300003018244000209AF03018258000209B18D
+:101540000A00000200000008020182300000468804
+:1015500003018238000209B30A0000010000008084
+:101560000201818C000000060A0000010000020058
+:101570000201818C000000070A0000010000040045
+:101580000201818C000000060A0000010000080032
+:101590000201818C0000000E0A00000400002000FF
+:1015A00002018238000000380201824C000025E46C
+:1015B0000201826000004BC8030186E0000409B507
+:1015C000020100C800000001020100FC000000014F
+:1015D000020100F4000000010401013800000011C4
+:1015E0000401017C00000011040101380000001119
+:1015F0000401017C00000011040101380000001109
+:101600000401017C000000110401013800000011F8
+:101610000401017C000000110215C0900000892621
+:101620000215C09C000000040A0000010000220016
+:101630000415C07000000007021400000000000143
+:101640000215C024000000000315C0EC000209B917
+:101650000315C100000209BB0A00000100002000C0
+:101660000315C1F4000809BD03140030000209C5C8
+:1016700002140040000000010900000200001008F0
+:1016800003140004000309C7021400440000FFFF14
+:101690000A0000040000200003140038000209CAF8
+:1016A00002140044000FFFFF0315C160000709CCBE
+:1016B0000315C198000209D30900000100001008B9
+:1016C00004140004000000030A00000100002000D0
+:1016D0000415C160000000070214000000000000B3
+:1016E000020090C40000E000020090CC0000F30073
+:1016F000030090D4000209D5020090E000007300BE
+:10170000030090E8000209D7020090F40000730083
+:10171000030090FC000209D9020091080000530068
+:10172000020091100000000403009128000709DB6B
+:101730000300916C000609E2040091840000000699
+:101740000300919C000509E80300942C000309EDB7
+:101750000300942C000309F00300942C000309F308
+:101760000300942C000309F60300942C000309F9EC
+:101770000300942C000309FC0300942C000309FFD0
+:101780000300942C00030A020304000400120A055B
+:1017900002040054000000430204005C0000000644
+:1017A00002040070000000040304007800040A171B
+:1017B00004040088000000050304009C00030A1BC9
+:1017C000040400A800000004030400B800110A1E6D
+:1017D00001040124000000000104012800000000B1
+:1017E0000104012C00000000010401300000000091
+:1017F000020401340000000F030401D000020A2F8C
+:101800000204022C000000040304025800040A3100
+:101810000A00000100002200040401AC00000007DF
+:101820000312049400210A350212038800000064A8
+:1018300002120390000000080312039C00030A56E2
+:10184000031203BC00030A59021203D00000000077
+:101850000212036C00000001031201BC003C0A5C90
+:10186000031202B000020A980312032400020A9A2B
+:10187000021205B400000001031205F800030A9CDF
+:101880000212066C00000001021201B0000000010B
+:10189000021207D800000000021207D80000000062
+:1018A000021207D800000000021207D80000000052
+:1018B000021207D800000000021207D80000000042
+:1018C000021207D800000000021207D80000000032
+:1018D000021030D8000000010710380000050A9FF0
+:1018E0000710392000050AA407103B0000050AA9CB
+:1018F00007103C0000050AAE0316803000080AB34A
+:1019000002168054000000020416807C00000005CE
+:101910000316809000020ABB0316809C00020ABDD9
+:10192000021680AC00000054041680B800000005C8
+:10193000031680CC00080ABF021680F000000007E2
+:101940000316810000060AC70316812800030ACD8A
+:101950000316814000060AD00316816800030AD6E8
+:10196000031681A800030AD9031681E800030ADCE4
+:10197000031681F800030ADF0316820800070AE253
+:101980000316823400020AE904168278000000047B
+:101990000316828800060AEB021688102020010137
+:1019A000021688202020010102168838202001011B
+:1019B00002168848202001010316E6BC00020AF145
+:1019C0000A000014000000080316806000070AF3F4
+:1019D000041680A400000002041680B0000000027B
+:1019E000031680F400030AFA0316811800040AFDA6
+:1019F0000316813400030B010316815800040B0405
+:101A000003168174000D0B08031681B4000D0B152D
+:101A1000021681F4000001FC02168204000000039B
+:101A20000316823C000B0B2204168268000000049F
+:101A30000216880C010101010316881400030B2D06
+:101A40000316882400050B300316883C00030B3571
+:101A50000316E6C400020B380316E6E800050B3A4D
+:101A60000216E794000000010A00001C00001000AC
+:101A70000316806000070B3F041680A400000002DC
+:101A8000041680B000000002031680F400030B4629
+:101A90000316811800040B490316813400030B4D13
+:101AA0000316815800040B500216817800000001D3
+:101AB00002168184000000010216819000000001DE
+:101AC000021681A400000004021681B80000000183
+:101AD000021681C400000001021681D0000000013E
+:101AE000021681E400000004021681F4000001FCEB
+:101AF00002168204000000030316823C00020B540D
+:101B0000021682480092009202168250012401249B
+:101B10000316825800040B56041682680000000465
+:101B20000216880C010101010316881400030B5AE8
+:101B30000316882400050B5D0316883C00030B6226
+:101B40000316E6E800020B650216E6F80000020440
+:101B50000A00000E00001020021681740000000030
+:101B60000316817C00020B670316818800020B6953
+:101B70000316819400040B6B021681B40000000070
+:101B8000031681BC00020B6F031681C800020B71A3
+:101B9000031681D400040B73021682440E490E49C9
+:101BA0000216824C009200920216825401240124F3
+:101BB0000316E6C400020B770316E6F000020B7969
+:101BC0000216E794000000010A00000E0000104019
+:101BD00002168174000000010316817C00020B7B59
+:101BE0000316818800020B7D0316819400040B7F8D
+:101BF000021681B400000001031681BC00020B83B1
+:101C0000031681C800020B85031681D400040B87DC
+:101C100002168244000000000216824C0FFF0FFFE4
+:101C200002168254000000000316E6C400020B8B6B
+:101C30000316E6F000020B8D0216E7940000000088
+:101C40000A000007000020000316806000070B8FC9
+:101C5000031680A400020B96031680B000020B98B6
+:101C6000021681F4000001C0021682040000003F49
+:101C70000216823C0000007F0316E7BC00080B9AA6
+:101C80000A00000F00004020031680F400030BA29E
+:101C90000316811800040BA50316813400030BA959
+:101CA0000316815800040BAC03168174000D0BB0B1
+:101CB000031681B4000D0BBD0316824000060BCA4B
+:101CC00004168258000000060316827000020BD032
+:101CD0000216880C010101010316881400030BD2BF
+:101CE0000316882400050BD50316883C00030BDA85
+:101CF0000316E6C400020BDD0216E79400000001A3
+:101D00000A00000D00004040031680F400030BDFC2
+:101D10000316811800040BE20316813400030BE65E
+:101D20000316815800040BE903168174000D0BEDB6
+:101D3000031681B4000D0BFA03168240000E0C0747
+:101D40000216880C010101010316881400030C150A
+:101D50000316882400050C180316883C00030C1D8C
+:101D60000316E6C400020C200216E79400000000EF
+:101D70000A00000D00008000031680F400030C220E
+:101D80000316811800040C250316813400030C2966
+:101D90000316815800040C2C03168174000D0C30BE
+:101DA000031681B4000D0C3D03168240000E0C4A50
+:101DB0000216880C010101200316881400030C5838
+:101DC0000316882400050C5B0316883C00030C6096
+:101DD0000316E6C400020C630216E794000000013B
+:101DE000021680EC000000FF0304040800140C65D8
+:101DF000020404CC000000010305004400020C7939
+:101E00000305005000080C7B0305009000070C83BD
+:101E1000030500B000020C8A030500C000020C8C10
+:101E2000030500D400020C8E02050114000000011D
+:101E30000305011C00020C900205020400000001D1
+:101E40000305020C00020C920205021C0000002097
+:101E5000040502400000000A0405400000000D00D7
+:101E60000A000002000000080305022000020C9492
+:101E70000305028000200C960A00000200000010FA
+:101E80000305022000020CB603050280001D0CB8F9
+:101E90000305000400100CD5020500E00000000E50
+:101EA000020500E40000002E020500E00000001E14
+:101EB000020500E40000003E020500E00000004EC4
+:101EC000020500E40000006E020500E00000005E74
+:101ED000020500E40000007E041640240000000219
+:101EE0000316403000030CE50216404400000020B9
+:101EF000021640700000001C02164208000000019B
+:101F000002164210000000010216422000000001EB
+:101F100002164228000000010216423000000001B3
+:101F20000216423800000001021642600000000262
+:101F30000A000001000000090216401C0003D090B6
+:101F40000A0000010000000A0216401C0000027195
+:101F50000A0000010000000C0216401C0000009C5A
+:101F60000A000001000010010216401C0005B8D84C
+:101F70000A000001000010020216401C000003A924
+:101F80000A000001000010040216401C000000EAD4
+:101F90000A000001000020010216401C0005B8D80C
+:101FA0000A000001000020020216401C000003A9E4
+:101FB0000A000001000020040216401C000000EA94
+:101FC0000216400000000001021640D80000000187
+:101FD0000316400800030CE802164240000000000F
+:101FE000021642480000000008164270000000027D
+:101FF0000216425000000000021642580000000085
+:1020000008164280000000020304200800040CEBC4
+:102010000304201C00040CEF0304203800020CF31E
+:10202000040420400000001E030420B800020CF548
+:10203000040420C00000005E0304223800040CF7F2
+:1020400001042248000000000104224C00000000AE
+:10205000010422500000000001042254000000008E
+:1020600001042258000000000104225C000000006E
+:10207000010422600000000001042264000000004E
+:1020800001042268000000000104226C000000002E
+:10209000010422700000000001042274000000000E
+:1020A00001042278000000000104227C00000000EE
+:1020B000030422C000040CFB0A0000010000000918
+:1020C00002042000000000FA0A0000010000000ADB
+:1020D00002042000000000010A0000010000000CC2
+:1020E00002042000000000000A00000100001001AE
+:1020F00002042000000001770A0000010000100225
+:1021000002042000000000010A0000010000100489
+:1021100002042000000000000A000001000020016D
+:1021200002042000000001770A00000100002002E4
+:1021300002042000000000010A0000010000200449
+:10214000020420000000000005180400008F0000B9
+:10215000061807B800090CFF041A00000000400030
+:10216000041B240000001600031A16C800020D010B
+:10217000031A17E000900D03031A404000040D936A
+:10218000041A405000000006031A406800020D9730
+:10219000031A52C000020D99031A800003F90D9B27
+:1021A000041A8FE400000007031B3D9000141194F3
+:1021B000021B800000000034021B80400000001859
+:1021C000021B80800000000C021B80C00000002069
+:1021D000021B8BC0000000010A0000030000000881
+:1021E000021A16D000000002021B838000086470EF
+:1021F000021B83C0000002260A0000020000000942
+:10220000021B830000086470021B8340000002264A
+:102210000A0000020000000A021B83000000055FA4
+:10222000021B8340000000010A0000020000000CB5
+:10223000021B830000000157021B834000000000C6
+:102240000A00000100000020021A16D4000000005D
+:102250000A00000100000040021A16D4000000012C
+:102260000A00000300001000021A16D0000000034C
+:10227000021B8380000C96A8021B83C00000033958
+:102280000A00000200001001021B8300000C96A847
+:10229000021B8340000003390A0000020000100204
+:1022A000021B83000000080E021B83400000000296
+:1022B0000A00000200001004021B83000000020359
+:1022C000021B8340000000000A0000030000200001
+:1022D000021A16D000000004021B8380000CF85084
+:1022E000021B83C0000003520A000002000020010C
+:1022F000021B8300000CF850021B834000000352B5
+:102300000A00000200002002021B83000000084DAA
+:10231000021B8340000000020A00000200002004AB
+:10232000021B830000000213021B83400000000018
+:102330000A00000100004000021A16D80000000048
+:102340000A00000100008000021A16D800000001F7
+:10235000041B944800000002051C000032C8000065
+:10236000051C8000373F0CB2051D000034501A8256
+:10237000051D8000356D2796051E0000206734F28C
+:10238000061E4D00366011A80A0000010000000280
+:10239000021B1480000000000A000001000000047D
+:1023A000021B1480000000000A0000010000001160
+:1023B000021B1480000000000A0000020000000858
+:1023C000021800BC00000032021B945C00000032C6
+:1023D0000A00000700000010021800BC0000000204
+:1023E000021B945C00000002021B884000000001F8
+:1023F000021B942C000000020118012800000000BC
+:10240000021B884000000000021B942C000000000A
+:10241000021B9440000000010A00000100000011AE
+:10242000021B1480000000010118000000000000E1
+:10243000011800040000000001180008000000005E
+:102440000118000C0000000001180010000000003E
+:10245000011800140000000003180020001A11AA3F
+:10246000031800A4000211C4021802240000000096
+:1024700002180234000000000218024C00000000A4
+:10248000021802E4000000FF081810000000040019
+:102490000A000001000000100818200000000600DB
+:1024A000031A1A30000411C6041A3000000000128A
+:1024B000041A309000000012041AD4C80000000270
+:1024C000041AD4D800000020041AD5D80000000255
+:1024D000031AD5F8000211CA041B440000000006CC
+:1024E000031A1A40000411CC041A304800000012EC
+:1024F000041A30D800000012041AD4D000000002E0
+:10250000041AD55800000020041AD5E0000000028B
+:10251000031AD600000211D0041B44180000000664
+:10252000031A4000000211D2041A500000000002F9
+:10253000041A508000000012031A6140000211D4F6
+:10254000041AA00000000002041B44300000000236
+:10255000031A4008000211D6041A501000000002AD
+:10256000041A50C800000012031A6148000211D872
+:10257000041AA00800000002041B443800000002F6
+:10258000031A4010000211DA041A50200000000261
+:10259000041A511000000012031A6150000211DCED
+:1025A000041AA01000000002041B444000000002B6
+:1025B000031A4018000211DE041A50300000000215
+:1025C000041A515800000012031A6158000211E069
+:1025D000041AA01800000002041B44480000000276
+:1025E000031A4020000211E2041A504000000002C9
+:1025F000041A51A000000012031A6160000211E4E5
+:10260000041AA02000000002041B44500000000235
+:10261000031A4028000211E6041A5050000000027C
+:10262000041A51E800000012031A6168000211E860
+:10263000041AA02800000002041B445800000002F5
+:10264000031A4030000211EA041A50600000000230
+:10265000041A523000000012031A6170000211ECDB
+:10266000041AA03000000002041B446000000002B5
+:10267000031A4038000211EE041A507000000002E4
+:10268000041A527800000012031A6178000211F057
+:10269000041AA03800000002041B44680000000275
+:1026A000020E004C00000032030E0054000811F22C
+:1026B000030E0094000711FA030E00B40002120189
+:1026C000020E00C400000000020E00CC0000000654
+:1026D000030E00D800021203020E014400000001A4
+:1026E000030E014C00021205020E0204000000015C
+:1026F000030E020C00021207030E021C0004120952
+:10270000030E0280001B120D040E030000000012D5
+:10271000040E2000000008000A000001000000086C
+:10272000040E02EC00000005030E00040011122844
+:10273000020E01100000000F020E01140000002F15
+:10274000020E01100000001F020E01140000003FE5
+:10275000020E01100000004F020E01140000006F75
+:10276000020E01100000005F020E01140000007F45
+:10277000020C100000000028030C4008000412396D
+:10278000030C401C0004123D030C403800061241AB
+:10279000040C40500000001F020C40CC000000015F
+:1027A000040C40D00000003A030C41B80006124768
+:1027B000040C41D00000001A030C42380004124DF2
+:1027C000010C424800000000010C424C00000000D7
+:1027D000010C425000000000010C425400000000B7
+:1027E000010C425800000000010C425C0000000097
+:1027F000010C426000000000010C42640000000077
+:10280000010C426800000000010C426C0000000056
+:10281000010C427000000000010C42740000000036
+:10282000010C427800000000010C427C0000000016
+:10283000010C428000000000030C42D80004125139
+:102840000A00000100000009020C4000000003E83B
+:102850000A0000010000000A020C40000000000312
+:102860000A0000010000000C020C40000000000102
+:102870000A00000100001001020C4000000005DC0D
+:102880000A00000100001002020C400000000004D9
+:102890000A00000100001004020C400000000001CA
+:1028A0000A00000100002001020C4000000005DCCD
+:1028B0000A00000100002002020C40000000000499
+:1028C0000A00000100002004020C4000000000018A
+:1028D0000530040000C30000063007E8000312556D
+:1028E0000432000000004000043324000000160001
+:1028F00003322C7000901257033234C0000812E7E4
+:102900000432408000000010033240C0000212EF89
+:1029100003337400000412F1023380000000001A37
+:10292000023380400000004E02338080000000101F
+:10293000023380C00000002002338BC00000000181
+:102940000A0000020000000802338380000864705F
+:10295000023383C0000002260A00000200000009C2
+:1029600002338300000864700233834000000226B3
+:102970000A0000020000000A023383000000055F25
+:1029800002338340000000010A0000020000000C36
+:10299000023383000000015702338340000000002F
+:1029A0000A0000020000100002338380000C96A889
+:1029B000023383C0000003390A0000020000100146
+:1029C00002338300000C96A80233834000000339D1
+:1029D0000A00000200001002023383000000080E0B
+:1029E00002338340000000020A00000200001004CD
+:1029F0000233830000000203023383400000000022
+:102A00000A0000020000200002338380000CF8500E
+:102A1000023383C0000003520A00000200002001BC
+:102A200002338300000CF85002338340000003524D
+:102A30000A00000200002002023383000000084D5B
+:102A400002338340000000020A000002000020045C
+:102A500002338300000002130233834000000000B1
+:102A600005340000367E00000534800034390DA0A6
+:102A70000535000031581AAF05358000386127054B
+:102A800005360000391A351E0536800034AC436522
+:102A9000053700001C8550900637416017D412F5A9
+:102AA0000A00000100000002023314800000000050
+:102AB0000A0000010000000402331480000000003E
+:102AC0000A00000100000011023314800000000021
+:102AD0000A00000100000008023000BC00000032C3
+:102AE0000A00000400000010023000BC00000002D8
+:102AF000023388400000000101300138000000006E
+:102B000002338840000000000A00000100000011AC
+:102B100002331480000000010130000000000000BA
+:102B20000130000400000000013000080000000037
+:102B30000130000C00000000013000100000000017
+:102B4000013000140000000003300020001A12F7CA
+:102B5000033000A400021311023002240000000020
+:102B600002300234000000000230024C000000007D
+:102B7000023002E40000FFFF0830200000000800DF
+:102B80000A000001000000100830400000000200B0
+:102B900004322C400000000203322C5000041313B6
+:102BA000043293C0000000020432940000000010C0
+:102BB0000432C000000000200432C10000000020E8
+:102BC0000432C200000000200432C30000000020D4
+:102BD0000432C400000000200432C50000000020C0
+:102BE0000432C600000000200432C70000000020AC
+:102BF0000432C800000000200432C9000000002098
+:102C00000432CA00000000200432CB000000002083
+:102C10000432CC00000000200432CD00000000206F
+:102C20000432CE00000000200432CF00000000205B
+:102C30000432DB800000000204322C480000000255
+:102C400003322C6000041317043293C80000000202
+:102C500004329440000000100432C08000000020C4
+:102C60000432C180000000200432C2800000002035
+:102C70000432C380000000200432C4800000002021
+:102C80000432C580000000200432C680000000200D
+:102C90000432C780000000200432C88000000020F9
+:102CA0000432C980000000200432CA8000000020E5
+:102CB0000432CB80000000200432CC8000000020D1
+:102CC0000432CD80000000200432CE8000000020BD
+:102CD0000432CF80000000200432DB8800000002B4
+:102CE000043210100000000204322C000000000228
+:102CF000043210200000000204322C080000000200
+:102D0000043210300000000204322C1000000002D7
+:102D1000043210400000000204322C1800000002AF
+:102D2000043210500000000204322C200000000287
+:102D3000043210600000000204322C28000000025F
+:102D4000043210700000000204322C300000000237
+:102D5000043210800000000204322C38000000020F
+:102D60000202005800000032030200600008131B3A
+:102D7000030200A0000B1323020200D00000000792
+:102D8000030200DC0003132E030200F000021331E3
+:102D9000020200FC0000000C020201200000000002
+:102DA0000202013400000002020201B00000000132
+:102DB0000202020C0000000103020214000213339D
+:102DC00002020404000000010302040C0002133597
+:102DD0000302041C00041337030204800020133B89
+:102DE0000402050000000012040280000000200020
+:102DF000030200040014135B02020108000000C873
+:102E00000202011800000002020201C400000000DA
+:102E1000020201CC00000000020201D40000000206
+:102E2000020201DC00000002020201E4000000FFD7
+:102E3000020201EC000000FF0202010C000000C8C9
+:102E40000202011C00000002020201C80000000092
+:102E5000020201D000000000020201D800000002BE
+:102E6000020201E000000002020201E8000000FF8F
+:102E7000020201F0000000FF02020108000000C889
+:102E80000202011800000002020201C4000000005A
+:102E9000020201CC00000000020201D40000000286
+:102EA000020201DC00000002020201E4000000FF57
+:102EB000020201EC000000FF0202010C000000C849
+:102EC0000202011C00000002020201C80000000012
+:102ED000020201D000000000020201D8000000023E
+:102EE000020201E000000002020201E8000000FF0F
+:102EF000020201F0000000FF02020108000000C809
+:102F00000202011800000002020201C400000000D9
+:102F1000020201CC00000000020201D40000000205
+:102F2000020201DC00000002020201E4000000FFD6
+:102F3000020201EC000000FF0202010C000000C8C8
+:102F40000202011C00000002020201C80000000091
+:102F5000020201D000000000020201D800000002BD
+:102F6000020201E000000002020201E8000000FF8E
+:102F7000020201F0000000FF02020108000000C888
+:102F80000202011800000002020201C40000000059
+:102F9000020201CC00000000020201D40000000285
+:102FA000020201DC00000002020201E4000000FF56
+:102FB000020201EC000000FF0202010C000000C848
+:102FC0000202011C00000002020201C80000000011
+:102FD000020201D000000000020201D8000000023D
+:102FE000020201E000000002020201E8000000FF0E
+:102FF000020201F0000000FF02161000000000288D
+:10300000031660080003136F0316601C000413729C
+:103010000316603800121376041660800000000E5C
+:10302000021660B800000001041660BC0000000831
+:10303000021660DC00000001041660E000000004DD
+:10304000021660F000000001041660F40000003178
+:10305000031661B800021388041661C0000000075F
+:10306000031661DC0006138A041661F400000011E7
+:103070000316623800041390011662480000000035
+:103080000116624C000000000116625000000000B2
+:103090000116625400000000011662580000000092
+:1030A0000116625C00000000011662600000000072
+:1030B0000116626400000000011662680000000052
+:1030C0000116626C00000000011662700000000032
+:1030D0000116627400000000011662780000000012
+:1030E0000116627C00000000011662D4000000009E
+:1030F000031662D8000413940A00000100000009BE
+:1031000002166000000003E80A0000010000000A47
+:1031100002166000000000030A0000010000000C1D
+:1031200002166000000000010A000001000010010A
+:1031300002166000000005DC0A0000010000100219
+:1031400002166000000000040A00000100001004E4
+:1031500002166000000000010A00000100002001CA
+:1031600002166000000005DC0A00000100002002D9
+:1031700002166000000000040A00000100002004A4
+:1031800002166000000000010528040000AB0000EA
+:10319000062807C800071398042A00000000400012
+:1031A000042B240000001600032A30000002139AAA
+:1031B000032A40000010139C032A8408000813AC63
+:1031C000032A9348000413B4032A9668000813B82E
+:1031D000032A98B8000213C0032A9950009013C222
+:1031E000032B4D9000141452022B800000000000AD
+:1031F000022B804000000018022B80800000000C91
+:10320000022B80C000000066022B8BC00000000172
+:103210000A00000300000008022A9CA80000000227
+:10322000022B838000086470022B83C000000226FA
+:103230000A00000200000009022B830000086470ED
+:10324000022B8340000002260A0000020000000A50
+:10325000022B83000000055F022B83400000000169
+:103260000A0000020000000C022B8300000001573E
+:10327000022B8340000000000A0000030000002031
+:10328000022A9CAC00000000032AC4E0000414667B
+:10329000032AC5000002146A0A0000020000004070
+:1032A000022A9CAC00000001032AC4E0000A146C4E
+:1032B0000A00000300001000022A9CA8000000037E
+:1032C000022B8380000C96A8022B83C000000339D8
+:1032D0000A00000200001001022B8300000C96A8D7
+:1032E000022B8340000003390A0000020000100294
+:1032F000022B83000000080E022B83400000000216
+:103300000A00000200001004022B830000000203E8
+:10331000022B8340000000000A0000030000200090
+:10332000022A9CA800000004022B8380000CF850A5
+:10333000022B83C0000003520A000002000020019B
+:10334000022B8300000CF850022B83400000035234
+:103350000A00000200002002022B83000000084D3A
+:10336000022B8340000000020A000002000020043B
+:10337000022B830000000213022B83400000000098
+:103380000A00000100004000022A9CB0000000007A
+:103390000A00000100008000022A9CB00000000129
+:1033A000042B944800000002052C000035FF0000AB
+:1033B000052C80003A950D80052D00002F111C264C
+:1033C000052D80003C3927EB052E00003FEE36FA34
+:1033D000052E80003C5646F6052F000034DD560CC5
+:1033E000052F800009026344062F93900D8E1476FA
+:1033F0000A00000100000002022B148000000000FF
+:103400000A00000100000004022B148000000000EC
+:103410000A00000100000011022B148000000000CF
+:103420000A00000200000008022800BC0000003270
+:10343000022B945C000000320A000007000000101C
+:10344000022800BC00000002022B945C0000000275
+:10345000022B884000000001022B942C0000000287
+:103460000128013800000000022B88400000000005
+:10347000022B942C00000000022B9440000000015D
+:103480000A00000100000011022B1480000000015E
+:1034900001280000000000000128000400000000D6
+:1034A00001280008000000000128000C00000000B6
+:1034B0000128001000000000012800140000000096
+:1034C00003280020001A1478032800A40002149294
+:1034D000022802240000000002280234000000003C
+:1034E0000228024C00000000022802E40000FFFF56
+:1034F00008282000000008000A0000010000001059
+:103500000828400000000200042A500000000002C9
+:10351000042A501000000002042A5020000000027B
+:10352000042A503000000002042A935800000020B2
+:10353000042A94580000000E032A94900002149468
+:10354000042A94D80000000E032A95100002149655
+:10355000042A95580000000E032A95900002149842
+:10356000042A95D80000000E032A96100002149A2F
+:10357000032A96880002149C042ABC9800000002CA
+:10358000042A500800000002042A5018000000021B
+:10359000042A502800000002042A503800000002CB
+:1035A000042A93D800000020042A94980000000EFA
+:1035B000032A94D00002149E042A95180000000EDD
+:1035C000032A9550000214A0042A95980000000ECA
+:1035D000032A95D0000214A2042A96180000000EB7
+:1035E000032A9650000214A4032A9690000214A6FF
+:1035F000042ABCA000000002042A50480000000E6B
+:10360000032A9698001014A8042A98D000000002FB
+:10361000042A991000000002042AC480000000025D
+:10362000042A50800000000E032A96D8001014B817
+:10363000042A98D800000002042A99180000000209
+:10364000042AC48800000002042A50B80000000EBA
+:10365000032A9718001014C8042A98E000000002FA
+:10366000042A992000000002042AC49000000002ED
+:10367000042A50F00000000E032A9758001014D8B6
+:10368000042A98E800000002042A99280000000299
+:10369000042AC49800000002042A51280000000EE9
+:1036A000032A9798001014E8042A98F000000002FA
+:1036B000042A993000000002042AC4A0000000027D
+:1036C000042A51600000000E032A97D8001014F855
+:1036D000042A98F800000002042A99380000000229
+:1036E000042AC4A800000002042A51980000000E19
+:1036F000032A981800101508042A990000000002F7
+:10370000042A994000000002042AC4B0000000020C
+:10371000042A51D00000000E032A985800101518F2
+:10372000042A990800000002042A994800000002B7
+:10373000042AC4B8000000020400A0000000000C2D
+:103740000400A050000000020300A0EC00081528AF
+:103750000300A19C000415300200A45C00000C00D2
+:103760000400A6A8000000020200A6D0000000008D
+:103770000200A61C000000030300A0700005153421
+:103780000400A084000000050200A0980FE00000E3
+:103790000400A09C000000070300A0B8000D15392C
+:1037A0000400A22C000000040200A688000000FC17
+:1037B0000400A68C000000070200A6F40000000030
+:1037C0000300A10C000615460400A124000000051A
+:1037D0000200A1380FE000000400A13C0000000737
+:1037E0000300A158000D154C0400A23C0000000489
+:1037F0000200A6B0000000FC0400A6B40000000710
+:103800000200A6F8000000000200A0300000000046
+:103810000200A034000000000200A03800000000F8
+:103820000200A03C000000000200A04000000000D8
+:103830000200A044000000000200A04800000000B8
+:103840000200A04C0000000000000000000000008A
+:103850000000000100000000000000000000000067
+:103860000000000000000000000000000000000058
+:10387000000000000000000000000000000100182F
+:1038800000180020002000230000000000000000BD
+:103890000000000000000000000000000000000028
+:1038A00000000000000000000023003500000000C0
+:1038B00000000000003500360036003700370038C1
+:1038C000003800390039003A003A003B003B003C28
+:1038D000003C003D003D00440000000000000000EE
+:1038E00000000000000000000000000000000000D8
+:1038F00000000000000000000000000000000000C8
+:103900000044004D0000000000000000004D004E8B
+:10391000004E004F004F0050005000510051005227
+:103920000052005300530054005400550055007FCE
+:103930000000000000000000000000000000000087
+:103940000000000000000000000000000000000077
+:103950000000000000000000007F01E10000000006
+:103960000000000001E101E601E601EB01EB01F0DE
+:1039700001F001F501F501FA01FA01FF01FF02046E
+:103980000204020900000000000000000000000026
+:103990000000000000000000000000000000000027
+:1039A0000000000000000000000000000000000017
+:1039B0000209020D000000000000000000000000ED
+:1039C00000000000000000000000000000000000F7
+:1039D000000000000000000000000000020D021DB9
+:1039E0000000000000000000021D021F021F022153
+:1039F000022102230223022502250227022702298F
+:103A00000229022B022B022D000000000000000002
+:103A100000000000000000000000000000000000A6
+:103A20000000000000000000000000000000000096
+:103A300000000000022D0230000000000000000025
+:103A40000230023302330236023602390239023CB6
+:103A5000023C023F023F0242024202450245024846
+:103A60000248024C024C02500250025402540255C9
+:103A7000025502560256025702570258025802597E
+:103A80000259025A025A025B025B025C025C026348
+:103A900002630289028902AE02AE02AF02AF02B037
+:103AA00002B002B102B102B202B202B302B302B476
+:103AB00002B402B502B502B602B602CF00000000A1
+:103AC00000000000000000000000000000000000F6
+:103AD00000000000000000000000000000000000E6
+:103AE0000000000002CF02DC000000000000000027
+:103AF00002DC02DD02DD02DE02DE02DF02DF02E0C6
+:103B000002E002E102E102E202E202E302E302E495
+:103B100002E402F7000000000000000000000000C6
+:103B20000000000000000000000000000000000095
+:103B300000000000000000000000000002F7030584
+:103B40000000000000000000030503060306030751
+:103B500003070308030803090309030A030A030B05
+:103B6000030B030C030C030D030D031200000000F4
+:103B70000000000000000000000000000000000045
+:103B80000000000000000000000000000000000035
+:103B900000000000031203B000000000000000005D
+:103BA0000000000000000000000000000000000015
+:103BB0000000000000000000000000000000000005
+:103BC00003B003B20000000000000000000000008D
+:103BD00000000000000000000000000000000000E5
+:103BE00000000000000000000000000003B203C657
+:103BF000000000000000000003C603C703C703C89D
+:103C000003C803C903C903CA03CA03CB03CB03CC4C
+:103C100003CC03CD03CD03CE03CE03EE03EE03F1BD
+:103C200003F103F4000000000000000000000000A9
+:103C30000000000000000000000000000000000084
+:103C40000000000003F4041C00000000000000005D
+:103C50000000000000000000000000000000000064
+:103C60000000000000000000000000000000000054
+:103C7000041C04870487048F048F04970497049D11
+:103C8000049D04A304A304A904A904AF04AF04B5CC
+:103C900004B504BB04BB04C104C104C704C704D9F0
+:103CA000000000000000000004D904DA04DA04DB9C
+:103CB00004DB04DC04DC04DD04DD04DE04DE04DFFC
+:103CC00004DF04E004E004E104E104E20000000099
+:103CD00000000000000000000000000000000000E4
+:103CE00000000000000000000000000000000000D4
+:103CF0000000000004E2050D0000000000000000CC
+:103D000000000000000000000000000000000000B3
+:103D100000000000000000000000000000000000A3
+:103D2000050D05650565057A057A058F058F0591F1
+:103D300005910593059305950595059705970599B3
+:103D40000599059B059B059D059D059F059F05B252
+:103D5000000000000000000005B205BA05BA05C267
+:103D600005C205CA05CA05D205D205DA05DA05E29B
+:103D700005E205EA05EA05F205F205F30000000098
+:103D80000000000000000000000000000000000033
+:103D90000000000000000000000000000000000023
+:103DA0000000000005F306240000000000000000F1
+:103DB0000000000000000000000000000000000003
+:103DC00000000000000000000000000000000000F3
+:103DD00006240694069406A306A306B206B206B706
+:103DE00006B706BC06BC06C106C106C606C606CB9B
+:103DF00006CB06D006D006D506D506DA06DA06E2E8
+:103E000006E206EB06EB06F406F406F506F506F602
+:103E100006F606F706F706F806F806F906F906FAB2
+:103E200006FA06FB06FB06FC00000000000000008E
+:103E30000000200000004000000060000000800042
+:103E40000000A0000000C0000000E0000001000031
+:103E5000000120000001400000016000000180001E
+:103E60000001A0000001C0000001E000000200000D
+:103E700000022000000240000002600000028000FA
+:103E80000002A0000002C0000002E00000030000E9
+:103E900000032000000340000003600000038000D6
+:103EA0000003A0000003C0000003E00000040000C5
+:103EB00000042000000440000004600000048000B2
+:103EC0000004A0000004C0000004E00000050000A1
+:103ED000000520000005400000056000000580008E
+:103EE0000005A0000005C0000005E000000600007D
+:103EF000000620000006400000066000000680006A
+:103F00000006A0000006C0000006E0000007000058
+:103F10000007200000074000000760000007800045
+:103F20000007A0000007C0000007E0000008000034
+:103F30000008200000084000000860000008800021
+:103F40000008A0000008C0000008E0000009000010
+:103F500000092000000940000009600000098000FD
+:103F60000009A0000009C0000009E000000A0000EC
+:103F7000000A2000000A4000000A6000000A8000D9
+:103F8000000AA000000AC000000AE000000B0000C8
+:103F9000000B2000000B4000000B6000000B8000B5
+:103FA000000BA000000BC000000BE000000C0000A4
+:103FB000000C2000000C4000000C6000000C800091
+:103FC000000CA000000CC000000CE000000D000080
+:103FD000000D2000000D4000000D6000000D80006D
+:103FE000000DA000000DC000000DE000000E00005C
+:103FF000000E2000000E4000000E6000000E800049
+:10400000000EA000000EC000000EE000000F000037
+:10401000000F2000000F4000000F6000000F800024
+:10402000000FA000000FC000000FE0000010000013
+:104030000010200000104000001060000010800000
+:104040000010A0000010C0000010E00000110000EF
+:1040500000112000001140000011600000118000DC
+:104060000011A0000011C0000011E00000120000CB
+:1040700000122000001240000012600000128000B8
+:104080000012A0000012C0000012E00000130000A7
+:104090000013200000134000001360000013800094
+:1040A0000013A0000013C0000013E0000014000083
+:1040B0000014200000144000001460000014800070
+:1040C0000014A0000014C0000014E000001500005F
+:1040D000001520000015400000156000001580004C
+:1040E0000015A0000015C0000015E000001600003B
+:1040F0000016200000164000001660000016800028
+:104100000016A0000016C0000016E0000017000016
+:104110000017200000174000001760000017800003
+:104120000017A0000017C0000017E00000180000F2
+:1041300000182000001840000018600000188000DF
+:104140000018A0000018C0000018E00000190000CE
+:1041500000192000001940000019600000198000BB
+:104160000019A0000019C0000019E000001A0000AA
+:10417000001A2000001A4000001A6000001A800097
+:10418000001AA000001AC000001AE000001B000086
+:10419000001B2000001B4000001B6000001B800073
+:1041A000001BA000001BC000001BE000001C000062
+:1041B000001C2000001C4000001C6000001C80004F
+:1041C000001CA000001CC000001CE000001D00003E
+:1041D000001D2000001D4000001D6000001D80002B
+:1041E000001DA000001DC000001DE000001E00001A
+:1041F000001E2000001E4000001E6000001E800007
+:10420000001EA000001EC000001EE000001F0000F5
+:10421000001F2000001F4000001F6000001F8000E2
+:10422000001FA000001FC000001FE00000200000D1
+:1042300000202000002040000020600000208000BE
+:104240000020A0000020C0000020E00000210000AD
+:10425000002120000021400000216000002180009A
+:104260000021A0000021C0000021E0000022000089
+:104270000022200000224000002260000022800076
+:104280000022A0000022C0000022E0000023000065
+:104290000023200000234000002360000023800052
+:1042A0000023A0000023C0000023E0000024000041
+:1042B000002420000024400000246000002480002E
+:1042C0000024A0000024C0000024E000002500001D
+:1042D000002520000025400000256000002580000A
+:1042E0000025A0000025C0000025E00000260000F9
+:1042F00000262000002640000026600000268000E6
+:104300000026A0000026C0000026E00000270000D4
+:1043100000272000002740000027600000278000C1
+:104320000027A0000027C0000027E00000280000B0
+:10433000002820000028400000286000002880009D
+:104340000028A0000028C0000028E000002900008C
+:104350000029200000294000002960000029800079
+:104360000029A0000029C0000029E000002A000068
+:10437000002A2000002A4000002A6000002A800055
+:10438000002AA000002AC000002AE000002B000044
+:10439000002B2000002B4000002B6000002B800031
+:1043A000002BA000002BC000002BE000002C000020
+:1043B000002C2000002C4000002C6000002C80000D
+:1043C000002CA000002CC000002CE000002D0000FC
+:1043D000002D2000002D4000002D6000002D8000E9
+:1043E000002DA000002DC000002DE000002E0000D8
+:1043F000002E2000002E4000002E6000002E8000C5
+:10440000002EA000002EC000002EE000002F0000B3
+:10441000002F2000002F4000002F6000002F8000A0
+:10442000002FA000002FC000002FE000003000008F
+:10443000003020000030400000306000003080007C
+:104440000030A0000030C0000030E000003100006B
+:104450000031200000314000003160000031800058
+:104460000031A0000031C0000031E0000032000047
+:104470000032200000324000003260000032800034
+:104480000032A0000032C0000032E0000033000023
+:104490000033200000334000003360000033800010
+:1044A0000033A0000033C0000033E00000340000FF
+:1044B00000342000003440000034600000348000EC
+:1044C0000034A0000034C0000034E00000350000DB
+:1044D00000352000003540000035600000358000C8
+:1044E0000035A0000035C0000035E00000360000B7
+:1044F00000362000003640000036600000368000A4
+:104500000036A0000036C0000036E0000037000092
+:10451000003720000037400000376000003780007F
+:104520000037A0000037C0000037E000003800006E
+:10453000003820000038400000386000003880005B
+:104540000038A0000038C0000038E000003900004A
+:104550000039200000394000003960000039800037
+:104560000039A0000039C0000039E000003A000026
+:10457000003A2000003A4000003A6000003A800013
+:10458000003AA000003AC000003AE000003B000002
+:10459000003B2000003B4000003B6000003B8000EF
+:1045A000003BA000003BC000003BE000003C0000DE
+:1045B000003C2000003C4000003C6000003C8000CB
+:1045C000003CA000003CC000003CE000003D0000BA
+:1045D000003D2000003D4000003D6000003D8000A7
+:1045E000003DA000003DC000003DE000003E000096
+:1045F000003E2000003E4000003E6000003E800083
+:10460000003EA000003EC000003EE000003F000071
+:10461000003F2000003F4000003F6000003F80005E
+:10462000003FA000003FC000003FE000004000004D
+:10463000004020000040400000406000004080003A
+:104640000040A0000040C0000040E0000041000029
+:104650000041200000414000004160000041800016
+:104660000041A0000041C0000041E0000042000005
+:1046700000422000004240000042600000428000F2
+:104680000042A0000042C0000042E00000430000E1
+:1046900000432000004340000043600000438000CE
+:1046A0000043A0000043C0000043E00000440000BD
+:1046B00000442000004440000044600000448000AA
+:1046C0000044A0000044C0000044E0000045000099
+:1046D0000045200000454000004560000045800086
+:1046E0000045A0000045C0000045E0000046000075
+:1046F0000046200000464000004660000046800062
+:104700000046A0000046C0000046E0000047000050
+:10471000004720000047400000476000004780003D
+:104720000047A0000047C0000047E000004800002C
+:104730000048200000484000004860000048800019
+:104740000048A0000048C0000048E0000049000008
+:1047500000492000004940000049600000498000F5
+:104760000049A0000049C0000049E000004A0000E4
+:10477000004A2000004A4000004A6000004A8000D1
+:10478000004AA000004AC000004AE000004B0000C0
+:10479000004B2000004B4000004B6000004B8000AD
+:1047A000004BA000004BC000004BE000004C00009C
+:1047B000004C2000004C4000004C6000004C800089
+:1047C000004CA000004CC000004CE000004D000078
+:1047D000004D2000004D4000004D6000004D800065
+:1047E000004DA000004DC000004DE000004E000054
+:1047F000004E2000004E4000004E6000004E800041
+:10480000004EA000004EC000004EE000004F00002F
+:10481000004F2000004F4000004F6000004F80001C
+:10482000004FA000004FC000004FE000005000000B
+:1048300000502000005040000050600000508000F8
+:104840000050A0000050C0000050E00000510000E7
+:1048500000512000005140000051600000518000D4
+:104860000051A0000051C0000051E00000520000C3
+:1048700000522000005240000052600000528000B0
+:104880000052A0000052C0000052E000005300009F
+:10489000005320000053400000536000005380008C
+:1048A0000053A0000053C0000053E000005400007B
+:1048B0000054200000544000005460000054800068
+:1048C0000054A0000054C0000054E0000055000057
+:1048D0000055200000554000005560000055800044
+:1048E0000055A0000055C0000055E0000056000033
+:1048F0000056200000564000005660000056800020
+:104900000056A0000056C0000056E000005700000E
+:1049100000572000005740000057600000578000FB
+:104920000057A0000057C0000057E00000580000EA
+:1049300000582000005840000058600000588000D7
+:104940000058A0000058C0000058E00000590000C6
+:1049500000592000005940000059600000598000B3
+:104960000059A0000059C0000059E000005A0000A2
+:10497000005A2000005A4000005A6000005A80008F
+:10498000005AA000005AC000005AE000005B00007E
+:10499000005B2000005B4000005B6000005B80006B
+:1049A000005BA000005BC000005BE000005C00005A
+:1049B000005C2000005C4000005C6000005C800047
+:1049C000005CA000005CC000005CE000005D000036
+:1049D000005D2000005D4000005D6000005D800023
+:1049E000005DA000005DC000005DE000005E000012
+:1049F000005E2000005E4000005E6000005E8000FF
+:104A0000005EA000005EC000005EE000005F0000ED
+:104A1000005F2000005F4000005F6000005F8000DA
+:104A2000005FA000005FC000005FE00000600000C9
+:104A300000602000006040000060600000608000B6
+:104A40000060A0000060C0000060E00000610000A5
+:104A50000061200000614000006160000061800092
+:104A60000061A0000061C0000061E0000062000081
+:104A7000006220000062400000626000006280006E
+:104A80000062A0000062C0000062E000006300005D
+:104A9000006320000063400000636000006380004A
+:104AA0000063A0000063C0000063E0000064000039
+:104AB0000064200000644000006460000064800026
+:104AC0000064A0000064C0000064E0000065000015
+:104AD0000065200000654000006560000065800002
+:104AE0000065A0000065C0000065E00000660000F1
+:104AF00000662000006640000066600000668000DE
+:104B00000066A0000066C0000066E00000670000CC
+:104B100000672000006740000067600000678000B9
+:104B20000067A0000067C0000067E00000680000A8
+:104B30000068200000684000006860000068800095
+:104B40000068A0000068C0000068E0000069000084
+:104B50000069200000694000006960000069800071
+:104B60000069A0000069C0000069E000006A000060
+:104B7000006A2000006A4000006A6000006A80004D
+:104B8000006AA000006AC000006AE000006B00003C
+:104B9000006B2000006B4000006B6000006B800029
+:104BA000006BA000006BC000006BE000006C000018
+:104BB000006C2000006C4000006C6000006C800005
+:104BC000006CA000006CC000006CE000006D0000F4
+:104BD000006D2000006D4000006D6000006D8000E1
+:104BE000006DA000006DC000006DE000006E0000D0
+:104BF000006E2000006E4000006E6000006E8000BD
+:104C0000006EA000006EC000006EE000006F0000AB
+:104C1000006F2000006F4000006F6000006F800098
+:104C2000006FA000006FC000006FE0000070000087
+:104C30000070200000704000007060000070800074
+:104C40000070A0000070C0000070E0000071000063
+:104C50000071200000714000007160000071800050
+:104C60000071A0000071C0000071E000007200003F
+:104C7000007220000072400000726000007280002C
+:104C80000072A0000072C0000072E000007300001B
+:104C90000073200000734000007360000073800008
+:104CA0000073A0000073C0000073E00000740000F7
+:104CB00000742000007440000074600000748000E4
+:104CC0000074A0000074C0000074E00000750000D3
+:104CD00000752000007540000075600000758000C0
+:104CE0000075A0000075C0000075E00000760000AF
+:104CF000007620000076400000766000007680009C
+:104D00000076A0000076C0000076E000007700008A
+:104D10000077200000774000007760000077800077
+:104D20000077A0000077C0000077E0000078000066
+:104D30000078200000784000007860000078800053
+:104D40000078A0000078C0000078E0000079000042
+:104D5000007920000079400000796000007980002F
+:104D60000079A0000079C0000079E000007A00001E
+:104D7000007A2000007A4000007A6000007A80000B
+:104D8000007AA000007AC000007AE000007B0000FA
+:104D9000007B2000007B4000007B6000007B8000E7
+:104DA000007BA000007BC000007BE000007C0000D6
+:104DB000007C2000007C4000007C6000007C8000C3
+:104DC000007CA000007CC000007CE000007D0000B2
+:104DD000007D2000007D4000007D6000007D80009F
+:104DE000007DA000007DC000007DE000007E00008E
+:104DF000007E2000007E4000007E6000007E80007B
+:104E0000007EA000007EC000007EE000007F000069
+:104E1000007F2000007F4000007F6000007F800056
+:104E2000007FA000007FC000007FE000007FE00165
+:104E300000000000000001FF000002000000000070
+:104E4000000003FF00000400000004010000040152
+:104E5000000002380000011C0000011C0000011CC1
+:104E60000000005000000050000000500000000151
+:104E700000000158000001A8000000C8000000A0C8
+:104E8000000000C800000000000000000000005A00
+:104E9000000000FA00000401000004010000000A04
+:104EA000000000320000040100000401000001586D
+:104EB000000001A80000001800000068000000B811
+:104EC0000000010800000158000001A800000018BF
+:104ED00000000068000000B80000010800000001A8
+:104EE0000000000200000000000000080215002081
+:104EF000021500200810000000000036000000002D
+:104F00000000000400000004000000000000000099
+:104F10000000000100000004000000020000000288
+:104F2000000000010000000200000020000000401E
+:104F300000000040000000030000001800002000F6
+:104F4000000040C000006180000082400000A3001B
+:104F50000000C3C00000E4800001054000012600FD
+:104F6000000146C000016780000188400001A900DF
+:104F70000001C9C00001EA8000020B4000022C00C1
+:104F800000024CC000026D8000028E400002AF00A3
+:104F90000002CFC00002F0800000114000000001BC
+:104FA00000000001000000010000000100000001FD
+:104FB00000000001000000010000000100000001ED
+:104FC00000000001000000010000000100000001DD
+:104FD00000000001000000010003D0000000003DBF
+:104FE00000000001000D0000000700D00002814019
+:104FF000000B81680002022000010240000F0250F5
+:1050000000010340000C0000000800C000028140C5
+:10501000000B8168000202200001024000070250DC
+:10502000000202C0001000000008010000028180A0
+:10503000000B81A80002026000018280000E8298AD
+:1050400000080380000F0000000100F00002810052
+:1050500000090128000201B8000101D8000E01E892
+:10506000000002C8FFFFFFF301AFFFFF00000000D8
+:105070000000000000000000000000000000000030
+:1050800000000000FFFFFFF100EFFFFF0000000045
+:10509000000000000000000000000000000100000F
+:1050A00000000000FFFFFFF6005FFFFF00000000B0
+:1050B00000000000000000000000000000020000EE
+:1050C00000000000FFFFF4061CBFFFFF000000050A
+:1050D00000000000000000140000000000040000B8
+:1050E00000000000FFFFFFF2004FFFFF0000000084
+:1050F00000000000000000000000000000080000A8
+:1051000000000000FFFFFFFA002FFFFF000000007B
+:10511000000000000000000000000000001000007F
+:1051200000000000FFFFFFF701EFFFFF000000009D
+:10513000000000000000000000000000002000004F
+:1051400000000000FFFFFFF5002FFFFF0000000040
+:10515000000000000000000000000000004000000F
+:1051600000000000FFFFFFF3018FFFFF00000000C1
+:10517000000000000000000000000000000000002F
+:1051800000000000FFFFFFF1010FFFFF0000000023
+:10519000000000000000000000000000000100000E
+:1051A00000000000FFFFFFF6005FFFFF00000000AF
+:1051B00000000000000000000000000000020000ED
+:1051C00000000000FFFFF4061CBFFFFF0000000509
+:1051D00000000000000000140000000000040000B7
+:1051E00000000000FFFFFFF2004FFFFF0000000083
+:1051F00000000000000000000000000000080000A7
+:1052000000000000FFFFFFFA002FFFFF000000007A
+:10521000000000000000000000000000001000007E
+:1052200000000000FFFFFFF700EFFFFF000000009D
+:10523000000000000000000000000000002000004E
+:1052400000000000FFFFFFF5004FFFFF000000001F
+:10525000000000000000000000000000004000000E
+:1052600000000000FFFFFFFF00CFFFFF0000000075
+:1052700000000000000000CC000000000000000062
+:1052800000000000FFFFFFFF00CFFFFF0000000055
+:1052900000000000000000CC000000000001000041
+:1052A00000000000FFFFFFFF00CFFFFF0000000035
+:1052B00000000000000000CC000000000002000020
+:1052C00000000000FFFFFFFF00CFFFFF0000000015
+:1052D00000000000000000CC0000000000040000FE
+:1052E00000000000FFFFFFFF00CFFFFF00000000F5
+:1052F00000000000000000CC0000000000080000DA
+:1053000000000000FFFFFFFF00CFFFFF00000000D4
+:1053100000000000000000CC0000000000100000B1
+:1053200000000000FFFFFFFF00CFFFFF00000000B4
+:1053300000000000000000CC000000000020000081
+:1053400000000000FFFFFFFF00CFFFFF0000000094
+:1053500000000000000000CC000000000040000041
+:1053600000000000FFFFFFF3020FFFFF000000003E
+:10537000000000000000000000000000000000002D
+:1053800000000000FFFFFFF1010FFFFF0000000021
+:10539000000000000000000000000000000100000C
+:1053A00000000000FFFFFFF6005FFFFF00000000AD
+:1053B00000000000000000000000000000020000EB
+:1053C00000000000FFFFF4061CBFFFFF0000000507
+:1053D00000000000000000140000000000040000B5
+:1053E00000000000FFFFFFF2004FFFFF0000000081
+:1053F00000000000000000000000000000080000A5
+:1054000000000000FFFFFF8A042FFFFF00000000E4
+:10541000000000000000000000000000001000007C
+:1054200000000000FFFFFF9705CFFFFF0000000016
+:10543000000000000000000000000000002000004C
+:1054400000000000FFFFFFF5010FFFFF000000005C
+:10545000000000000000000000000000004000000C
+:1054600000000000FFFFFFF301EFFFFF000000005E
+:10547000000000000000000000000000000000002C
+:1054800000000000FFFFFFF1002FFFFF0000000001
+:10549000000000000000000000000000000100000B
+:1054A00000000000FFFFFFF6005FFFFF00000000AC
+:1054B00000000000000000000000000000020000EA
+:1054C00000000000FFFFFF061CBFFFFF0000000000
+:1054D00000000000000000140000000000040000B4
+:1054E00000000000FFFFFFF2004FFFFF0000000080
+:1054F00000000000000000000000000000080000A4
+:1055000000000000FFFFFFFA002FFFFF0000000077
+:10551000000000000000000000000000001000007B
+:1055200000000000FFFFFFF701CFFFFF00000000B9
+:10553000000000000000000000000000002000004B
+:1055400000000000FFFFFFFF00CFFFFF0000000092
+:1055500000000000000000CC00000000004000003F
+:1055600000000000FFFFFFFF00CFFFFF0000000072
+:1055700000000000000000CC00000000000000005F
+:1055800000000000FFFFFFFF00CFFFFF0000000052
+:1055900000000000000000CC00000000000100003E
+:1055A00000000000FFFFFFFF00CFFFFF0000000032
+:1055B00000000000000000CC00000000000200001D
+:1055C00000000000FFFFFFFF00CFFFFF0000000012
+:1055D00000000000000000CC0000000000040000FB
+:1055E00000000000FFFFFFFF00CFFFFF00000000F2
+:1055F00000000000000000CC0000000000080000D7
+:1056000000000000FFFFFFFF00CFFFFF00000000D1
+:1056100000000000000000CC0000000000100000AE
+:1056200000000000FFFFFFFF00CFFFFF00000000B1
+:1056300000000000000000CC00000000002000007E
+:1056400000000000FFFFFFFF00CFFFFF0000000091
+:1056500000000000000000CC00000000004000003E
+:1056600000000000FFFFFFFF00CFFFFF0000000071
+:1056700000000000000000CC00000000000000005E
+:1056800000000000FFFFFFFF00CFFFFF0000000051
+:1056900000000000000000CC00000000000100003D
+:1056A00000000000FFFFFFFF00CFFFFF0000000031
+:1056B00000000000000000CC00000000000200001C
+:1056C00000000000FFFFFFFF00CFFFFF0000000011
+:1056D00000000000000000CC0000000000040000FA
+:1056E00000000000FFFFFFFF00CFFFFF00000000F1
+:1056F00000000000000000CC0000000000080000D6
+:1057000000000000FFFFFFFF00CFFFFF00000000D0
+:1057100000000000000000CC0000000000100000AD
+:1057200000000000FFFFFFFF00CFFFFF00000000B0
+:1057300000000000000000CC00000000002000007D
+:1057400000000000FFFFFFFF00CFFFFF0000000090
+:1057500000000000000000CC00000000004000003D
+:1057600000000000FFFFFFFF00CFFFFF0000000070
+:1057700000000000000000CC00000000000000005D
+:1057800000000000FFFFFFFF00CFFFFF0000000050
+:1057900000000000000000CC00000000000100003C
+:1057A00000000000FFFFFFFF00CFFFFF0000000030
+:1057B00000000000000000CC00000000000200001B
+:1057C00000000000FFFFFFFF00CFFFFF0000000010
+:1057D00000000000000000CC0000000000040000F9
+:1057E00000000000FFFFFFFF00CFFFFF00000000F0
+:1057F00000000000000000CC0000000000080000D5
+:1058000000000000FFFFFFFF00CFFFFF00000000CF
+:1058100000000000000000CC0000000000100000AC
+:1058200000000000FFFFFFFF00CFFFFF00000000AF
+:1058300000000000000000CC00000000002000007C
+:1058400000000000FFFFFFFF00CFFFFF000000008F
+:1058500000000000000000CC00000000004000003C
+:1058600000000000000000320000003200000200D2
+:1058700000003DFF000002110000020000000204D1
+:105880000000FFFF0000FFFF0000FFFF0000FFFF20
+:105890000000000000000037000000210000002090
+:1058A00000000001000000010000000107FFFFFFF1
+:1058B0000000007F07FFFFFF0000003F0000FFFF28
+:1058C0000000FFFF0000FFFF0000FFFF00007FF867
+:1058D00000007FF800000000000028AD000029183B
+:1058E000000029190000000500000007000000006A
+:1058F000000000000000FF00000000000000FF00AA
+:10590000000000000000FF00000000000000FF0099
+:10591000000000000000FF00000000000000FF0089
+:10592000000000000000FF00000000000000FF0079
+:10593000000000000000FF00000000000000FF0069
+:10594000000000000000FF00000000000000FF0059
+:10595000000000000000FF00000000000000FF0049
+:10596000000000000000FF00000000000000FF0039
+:10597000000000000000FF00000000000000FF0029
+:10598000000000000000FF00000000000000FF0019
+:10599000000000000000FF00000000000000FF0009
+:1059A000000000000000FF00000000000000FF00F9
+:1059B000000000000000FF00000000000000FF00E9
+:1059C000000000000000FF00000000000000FF00D9
+:1059D000000000000000FF00000000000000FF00C9
+:1059E000000000000000FF00000000000000FF00B9
+:1059F000000000000000FF00000000000000FF00A9
+:105A0000000000000000FF00000000000000FF0098
+:105A1000000000000000FF00000000000000FF0088
+:105A2000000000000000FF00000000000000FF0078
+:105A3000000000000000FF00000000000000FF0068
+:105A4000000000000000FF00000000000000FF0058
+:105A5000000000000000FF00000000000000FF0048
+:105A6000000000000000FF00000000000000FF0038
+:105A7000000000000000FF00000000000000FF0028
+:105A8000000000000000FF00000000000000FF0018
+:105A9000000000000000FF00000000000000FF0008
+:105AA000000000000000FF00000000000000FF00F8
+:105AB000000000000000FF00000000000000FF00E8
+:105AC000000000000000FF00000000000000FF00D8
+:105AD000000000000000FF00000000000000FF00C8
+:105AE000000000000000FF00000000000000FF00B8
+:105AF000000000000000FF00000000000000FF00A8
+:105B0000000000000000FF00000000000000FF0097
+:105B1000000000000000FF00000000000000FF0087
+:105B2000000000000000FF00000000000000FF0077
+:105B3000000000000000FF1C0FFFFFFF0000FF1C23
+:105B40000FFFFFFF0000FF1C0FFFFFFF0000FF1C07
+:105B50000FFFFFFF0000FF1C0FFFFFFF0000FF1CF7
+:105B60000FFFFFFF0000FF1C0FFFFFFF0000FF1CE7
+:105B70000FFFFFFF0000FF1C0FFFFFFF0000FF1CD7
+:105B80000FFFFFFF0000FF1C0FFFFFFF0000FF1CC7
+:105B90000FFFFFFF0000FF1C0FFFFFFF0000FF1CB7
+:105BA0000FFFFFFF0000FF1C0FFFFFFF0000FF1CA7
+:105BB0000FFFFFFF0000FF1C0FFFFFFF0000FF1C97
+:105BC0000FFFFFFF0000FF1C0FFFFFFF0000FF1C87
+:105BD0000FFFFFFF0000FF1C0FFFFFFF0000FF1C77
+:105BE0000FFFFFFF0000FF1C0FFFFFFF0000FF1C67
+:105BF0000FFFFFFF0000FF1C0FFFFFFF0000FF1C57
+:105C00000FFFFFFF0000FF1C0FFFFFFF0000FF1C46
+:105C10000FFFFFFF0000FF1C0FFFFFFF0000FF1C36
+:105C20000FFFFFFF0000FF1C0FFFFFFF0000FF1C26
+:105C30000FFFFFFF0000FF1C0FFFFFFF0000FF1C16
+:105C40000FFFFFFF0000FF1C0FFFFFFF0000FF1C06
+:105C50000FFFFFFF0000FF1C0FFFFFFF0000FF1CF6
+:105C60000FFFFFFF0000FF1C0FFFFFFF0000FF1CE6
+:105C70000FFFFFFF0000FF1C0FFFFFFF0000FF1CD6
+:105C80000FFFFFFF0000FF1C0FFFFFFF0000FF1CC6
+:105C90000FFFFFFF0000FF1C0FFFFFFF0000FF1CB6
+:105CA0000FFFFFFF0000FF1C0FFFFFFF0000FF1CA6
+:105CB0000FFFFFFF0000FF1C0FFFFFFF0000FF1C96
+:105CC0000FFFFFFF0000FF1C0FFFFFFF0000FF1C86
+:105CD0000FFFFFFF0000FF1C0FFFFFFF0000FF1C76
+:105CE0000FFFFFFF0000FF1C0FFFFFFF0000FF1C66
+:105CF0000FFFFFFF0000FF1C0FFFFFFF0000FF1C56
+:105D00000FFFFFFF0000FF1C0FFFFFFF0000FF1C45
+:105D10000FFFFFFF0000FF1C0FFFFFFF0000FF1C35
+:105D20000FFFFFFF0000FF1C0FFFFFFF0000FF1C25
+:105D30000FFFFFFF0000FF1C0FFFFFFF0000FF1C15
+:105D40000FFFFFFF0000FF1C0FFFFFFF0000FF1C05
+:105D50000FFFFFFF0000FF1C0FFFFFFF0000FF1CF5
+:105D60000FFFFFFF0000FF1C0FFFFFFF0000FF1CE5
+:105D70000FFFFFFF0000FF1C0FFFFFFF0000FF1CD5
+:105D80000FFFFFFF0000FF1C0FFFFFFF0000FF1CC5
+:105D90000FFFFFFF0000FF1C0FFFFFFF0000FF1CB5
+:105DA0000FFFFFFF0000FF1C0FFFFFFF0000FF1CA5
+:105DB0000FFFFFFF0000FF1C0FFFFFFF0000FF1C95
+:105DC0000FFFFFFF0000FF1C0FFFFFFF0000FF1C85
+:105DD0000FFFFFFF0000FF1C0FFFFFFF0000FF1C75
+:105DE0000FFFFFFF0000FF1C0FFFFFFF0000FF1C65
+:105DF0000FFFFFFF0000FF1C0FFFFFFF0000FF1C55
+:105E00000FFFFFFF0000FF1C0FFFFFFF0000FF1C44
+:105E10000FFFFFFF0000FF1C0FFFFFFF0000FF1C34
+:105E20000FFFFFFF0000FF1C0FFFFFFF0000FF1C24
+:105E30000FFFFFFF0000FF1C0FFFFFFF0000FF1C14
+:105E40000FFFFFFF0000FF1C0FFFFFFF0000FF1C04
+:105E50000FFFFFFF0000FF1C0FFFFFFF0000FF1CF4
+:105E60000FFFFFFF0000FF1C0FFFFFFF0000FF1CE4
+:105E70000FFFFFFF0000FF1C0FFFFFFF0000FF1CD4
+:105E80000FFFFFFF0000FF1C0FFFFFFF0000FF1CC4
+:105E90000FFFFFFF0000FF1C0FFFFFFF0000FF1CB4
+:105EA0000FFFFFFF0000FF1C0FFFFFFF0000FF1CA4
+:105EB0000FFFFFFF0000FF1C0FFFFFFF0000FF1C94
+:105EC0000FFFFFFF0000FF1C0FFFFFFF0000FF1C84
+:105ED0000FFFFFFF0000FF1C0FFFFFFF0000FF1C74
+:105EE0000FFFFFFF0000FF1C0FFFFFFF0000FF1C64
+:105EF0000FFFFFFF0000FF1C0FFFFFFF0000FF1C54
+:105F00000FFFFFFF0000FF1C0FFFFFFF0000FF1C43
+:105F10000FFFFFFF0000FF1C0FFFFFFF0000FF1C33
+:105F20000FFFFFFF0000FF1C0FFFFFFF0000FF1C23
+:105F30000FFFFFFF0000FF1C0FFFFFFF0000FF1C13
+:105F40000FFFFFFF0000FF1C0FFFFFFF0000FF1C03
+:105F50000FFFFFFF0000FF1C0FFFFFFF0000FF1CF3
+:105F60000FFFFFFF0000FF1C0FFFFFFF0000FF1CE3
+:105F70000FFFFFFF0000FF1C0FFFFFFF0000FF1CD3
+:105F80000FFFFFFF0000FF1C0FFFFFFF0000FF1CC3
+:105F90000FFFFFFF0000FF1C0FFFFFFF0000FF1CB3
+:105FA0000FFFFFFF0000FF1C0FFFFFFF0000FF1CA3
+:105FB0000FFFFFFF0000FF1C0FFFFFFF0000FF1C93
+:105FC0000FFFFFFF0000FF1C0FFFFFFF0000FF1C83
+:105FD0000FFFFFFF0000FF1C0FFFFFFF0000FF1C73
+:105FE0000FFFFFFF0000FF1C0FFFFFFF0000FF1C63
+:105FF0000FFFFFFF0000FF1C0FFFFFFF0000FF1C53
+:106000000FFFFFFF0000FF1C0FFFFFFF0000FF1C42
+:106010000FFFFFFF0000FF1C0FFFFFFF0000FF1C32
+:106020000FFFFFFF0000FF1C0FFFFFFF0000FF1C22
+:106030000FFFFFFF0000FF1C0FFFFFFF0000FF1C12
+:106040000FFFFFFF0000FF1C0FFFFFFF0000FF1C02
+:106050000FFFFFFF0000FF1C0FFFFFFF0000FF1CF2
+:106060000FFFFFFF0000FF1C0FFFFFFF0000FF1CE2
+:106070000FFFFFFF0000FF1C0FFFFFFF0000FF1CD2
+:106080000FFFFFFF0000FF1C0FFFFFFF0000FF1CC2
+:106090000FFFFFFF0000FF1C0FFFFFFF0000FF1CB2
+:1060A0000FFFFFFF0000FF1C0FFFFFFF0000FF1CA2
+:1060B0000FFFFFFF0000FF1C0FFFFFFF0000FF1C92
+:1060C0000FFFFFFF0000FF1C0FFFFFFF0000FF1C82
+:1060D0000FFFFFFF0000FF1C0FFFFFFF0000FF1C72
+:1060E0000FFFFFFF0000FF1C0FFFFFFF0000FF1C62
+:1060F0000FFFFFFF0000FF1C0FFFFFFF0000FF1C52
+:106100000FFFFFFF0000FF1C0FFFFFFF0000FF1C41
+:106110000FFFFFFF0000FF1C0FFFFFFF0000FF1C31
+:106120000FFFFFFF0000FF1C0FFFFFFF0000FF1C21
+:106130000FFFFFFF0000FF1C0FFFFFFF0000FF1C11
+:106140000FFFFFFF0000FF1C0FFFFFFF0000FF1C01
+:106150000FFFFFFF0000FF1C0FFFFFFF0000FF1CF1
+:106160000FFFFFFF0000FF1C0FFFFFFF0000FF1CE1
+:106170000FFFFFFF0000FF1C0FFFFFFF0000FF1CD1
+:106180000FFFFFFF0000FF1C0FFFFFFF0000FF1CC1
+:106190000FFFFFFF0000FF1C0FFFFFFF0000FF1CB1
+:1061A0000FFFFFFF0000FF1C0FFFFFFF0000FF1CA1
+:1061B0000FFFFFFF0000FF1C0FFFFFFF0000FF1C91
+:1061C0000FFFFFFF0000FF1C0FFFFFFF0000FF1C81
+:1061D0000FFFFFFF0000FF1C0FFFFFFF0000FF1C71
+:1061E0000FFFFFFF0000FF1C0FFFFFFF0000FF1C61
+:1061F0000FFFFFFF0000FF1C0FFFFFFF0000FF1C51
+:106200000FFFFFFF0000FF1C0FFFFFFF0000FF1C40
+:106210000FFFFFFF0000FF1C0FFFFFFF0000FF1C30
+:106220000FFFFFFF0000FF1C0FFFFFFF0000FF1C20
+:106230000FFFFFFF0000FF1C0FFFFFFF0000FF1C10
+:106240000FFFFFFF0000FF1C0FFFFFFF0000FF1C00
+:106250000FFFFFFF0000FF1C0FFFFFFF0000FF1CF0
+:106260000FFFFFFF0000FF1C0FFFFFFF0000FF1CE0
+:106270000FFFFFFF0000FF1C0FFFFFFF0000FF1CD0
+:106280000FFFFFFF0000FF1C0FFFFFFF0000FF1CC0
+:106290000FFFFFFF0000FF1C0FFFFFFF0000FF1CB0
+:1062A0000FFFFFFF0000FF1C0FFFFFFF0000FF1CA0
+:1062B0000FFFFFFF0000FF1C0FFFFFFF0000FF1C90
+:1062C0000FFFFFFF0000FF1C0FFFFFFF0000FF1C80
+:1062D0000FFFFFFF0000FF1C0FFFFFFF0000FF1C70
+:1062E0000FFFFFFF0000FF1C0FFFFFFF0000FF1C60
+:1062F0000FFFFFFF0000FF1C0FFFFFFF0000FF1C50
+:106300000FFFFFFF0000FF1C0FFFFFFF0000FF1C3F
+:106310000FFFFFFF0000FF1C0FFFFFFF0000FF1C2F
+:106320000FFFFFFF0000FF1C0FFFFFFF0000FF1C1F
+:106330000FFFFFFF0000FF1C0FFFFFFF0000FF1C0F
+:106340000FFFFFFF0000FF1C0FFFFFFF0000FF1CFF
+:106350000FFFFFFF0000FF1C0FFFFFFF0000FF1CEF
+:106360000FFFFFFF0000FF1C0FFFFFFF0000FF1CDF
+:106370000FFFFFFF0000FF1C0FFFFFFF0000FF1CCF
+:106380000FFFFFFF0000FF1C0FFFFFFF0000FF1CBF
+:106390000FFFFFFF0000FF1C0FFFFFFF0000FF1CAF
+:1063A0000FFFFFFF0000FF1C0FFFFFFF0000FF1C9F
+:1063B0000FFFFFFF000000020000150000000001B9
+:1063C00000000002000000030000000000000004C4
+:1063D00000000001000000000000000100000004B7
+:1063E00000000000000000010000000300000000A9
+:1063F0000000000100000004000000000000000197
+:106400000000000300000000000000010000000484
+:106410000000000000000004000000030000000075
+:106420000000000000007FFF000003FF00000000EC
+:106430000000000100000001000000010000000059
+:10644000000000020000009000000090008000901A
+:1064500008100000000009FF0000076C0000008A1F
+:106460000000008000000081000000800000008A21
+:106470000000008000000081000000800000008A11
+:106480000000008000000081000000800000008A01
+:106490000000008000000081000000800000008AF1
+:1064A000000000800000008100000080000000016A
+:1064B00000000001000000010000000100000001D8
+:1064C00000000001000025E4000025E400004BC8A6
+:1064D00000004BC8000000180000111A00543210D0
+:1064E000000000000021054300000000000025E43A
+:1064F000000025E400004BC800004BC80000001855
+:106500000000111A00543210000000000021054361
+:106510000000000000000001000000010000000178
+:106520000000000000000000000000010000000268
+:10653000000000000000000600000003000000044E
+:106540000000000500000001000000010000000143
+:106550000000000100000001000000010000000137
+:106560000000000100000001000000010000000127
+:106570000000000100000001000000010000000117
+:1065800000000001000000030000600000000003A4
+:106590000000600000000003000040000000030055
+:1065A00000000300000003000000030000000300DF
+:1065B00000000300000003000003F00800000000DA
+:1065C00000000000000000000000000100000001C9
+:1065D00000000001000000010000000100000001B7
+:1065E00000000001000000010000000100000001A7
+:1065F0000000000100000001000000010000000197
+:106600000000000100000001000000010000000186
+:106610000000000100000001000000010000000176
+:106620000000000100000001000000010000000166
+:106630000000000100000001000000010000000156
+:1066400000000001000000FF000000FF000000FF4C
+:10665000000000FF0000007F000000FF000000FFBE
+:10666000000000FF0000003E000000000000003FAE
+:106670000000003F0000003F0000003F0000003F1E
+:106680000000003F0000003F0000000F000000007D
+:106690001217000022170000321700001215000028
+:1066A000221500003215000002100000001000004A
+:1066B00010100000201000003010000040100000FA
+:1066C00000000000000000000000000000100000BA
+:1066D00012140000221400003214000042140000C2
+:1066E000000000000000000000000000000089061B
+:1066F0000000892600000036000000360810000067
+:1067000008100000FFFFFFFFFFFFFFFFFFFFFFFF7D
+:10671000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF89
+:10672000FFFFFFFFF000C000FFFFFFFFFFFFFFFFC5
+:10673000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF69
+:10674000FFFFFFFFF800C000FFFFFFFFFFFFFFFF9D
+:10675000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF49
+:10676000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF39
+:10677000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF29
+:10678000FFFFFFFF00003C100000000800000008B1
+:1067900000000002000000040000000500000004EA
+:1067A0000000004000001808000008030000080373
+:1067B0000000004000000003000008030000080380
+:1067C00000000803000100030000080300000803A4
+:1067D00000000003000000030000000300000003AD
+:1067E000000000030000000300000003000000039D
+:1067F000000000030000000300000003000000038D
+:106800000000000300000003000000030000240358
+:106810000000002F000000090000001900000184A2
+:1068200000000183000003060000001900000006BC
+:1068300000000306000003060000030600000C86AB
+:10684000000003060000030600000006000000062A
+:106850000000000600000006000000060000000620
+:106860000000000600000006000000060000000610
+:106870000000000600000006000000060000000600
+:1068800000000006000003060000001300000006E0
+:106890000000100400001004001064400010644068
+:1068A000000000400000001900000001000000008E
+:1068B00000000000000000000000000000002000B8
+:1068C00000000000000000000000000000000000C8
+:1068D0000400200000000000000000000000000094
+:1068E0000000000041002000000000000000000047
+:1068F0000000000000000000000020000000007CFC
+:106900000000003D0000003F0000009C0000000C63
+:10691000000000050000000A000000050000005310
+:10692000000025E3000000540000005400000004B3
+:106930000000000400000004000000040000000447
+:10694000000000040000000400000004000000003B
+:106950000000000100000002000000000000000133
+:1069600000000002000000090000000B0000000A07
+:106970000000000000000001000000020000000014
+:106980000000000100000002000000090000000BF0
+:106990000000000A000000090000000B0000000ACF
+:1069A000000000090000000B0000000A00000000C9
+:1069B00000000800000002000000040000000000C9
+:1069C000000000001FFF1FFF1FFF1FFF1FFF1FFF13
+:1069D0001FFF1FFF000025E40000800020002000B2
+:1069E00020002000800080008000800040004000E7
+:1069F000400040000000000000000002000001789C
+:106A00000000017800000000000000000000017894
+:106A10000000000000000000000000000000000175
+:106A20000000000200000000000000000000000064
+:106A3000000000040000000000000001000000024F
+:106A40000000000000000000000000000000000442
+:106A50000000000000000001000000020000000033
+:106A60000000000100000002000000000000000122
+:106A70000000000200000000000000000000000014
+:106A800000000004000000000000000100000002FF
+:106A900000000000000000010000000200000000F3
+:106AA00000000001000000020000000000000000E3
+:106AB0000000000000000004000000130E490E4911
+:106AC0000E490E4900920092009200920124012486
+:106AD000012401240000000000000000100010004C
+:106AE000100010002001012001011001010101012D
+:106AF00020010120010110012001012001011001EC
+:106B00000101010120010120010110010101010128
+:106B100000000004000000060200410402004104DD
+:106B2000020041040200410400000204000002CE01
+:106B3000000002CE0000000000000000000002CCB7
+:106B40000000000000000000000000000000000144
+:106B50000000000200000000000000000000000033
+:106B6000000000040000000000000001000000021E
+:106B70000000000000000000000000000000000411
+:106B8000000000130E490E49000000000000000044
+:106B90001000100010001000200101200101100160
+:106BA000010101012001012001011001200101204A
+:106BB0000101100101010101200101200101100169
+:106BC0000101010102004104020041040000000231
+:106BD00000000000000000020000000000000002B1
+:106BE00000000000000000000000000000000002A3
+:106BF0000000000000000002000000000000000291
+:106C00000000000000000000000000000000000480
+:106C100000000006020041040200410400000001DF
+:106C20000000000100000001000000010000000160
+:106C30000000000100000001000000010000000150
+:106C40000000000100000001000000010000000140
+:106C50000000000100000001000000010000000130
+:106C6000000000030255555502555555000002CE4F
+:106C7000000002CE000002CE000002CE000002CED4
+:106C8000000002CE000002CC0000005400000054BE
+:106C9000000000540000005400000000000000014B
+:106CA00000000002000000000000000600000003D9
+:106CB00000000004000000050000000000000001CA
+:106CC00000000002000000000000000000000000C2
+:106CD00000000006000000000000000100000002AB
+:106CE000000000000000000000000000000000069E
+:106CF0000000000000000001000000020000000091
+:106D0000000000010000000200000000000000017F
+:106D10000000000200000000000000000000000071
+:106D2000000000060000000000000001000000025A
+:106D30000000000000000001000000020000000050
+:106D40000000000100000002000000000000000040
+:106D500000000000000000060E490E490E490E49D1
+:106D60000092009200920092012401240124012447
+:106D7000100010001000100020010120010110017E
+:106D80000101010120010120010110012001012068
+:106D90000101100101010101200101200101100187
+:106DA00001010101000000040000000600000000D5
+:106DB00000000001000000020000000000000000D0
+:106DC00000000000000000060000000000000001BC
+:106DD00000000002000000000000000000000000B1
+:106DE0000000000600000003000000040000000591
+:106DF0000000000300000004000000050000000384
+:106E00000000000400000005000000030000000373
+:106E10000000000300000006000000030000000462
+:106E20000000000500000003000000040000000551
+:106E30000000000300000004000000050000000343
+:106E40000000000300000003000000060E490E4988
+:106E500000000000009200920000000001240124C4
+:106E600000000000000000000E490E490000000074
+:106E70000092009200000000012401241000100084
+:106E80001000100020010120010110010101010189
+:106E90002001012001011001200101200101100148
+:106EA0000101010120010120010110010101010185
+:106EB00000000001000000030000000400000003C7
+:106EC00000000004000000050000000300000006B0
+:106ED00000000005000000040000000300000004A2
+:106EE000000000050000000300000006000000058F
+:106EF0000000000400000003000000040000000087
+:106F0000000000010000000200000000000000017D
+:106F10000000000200000005000000030000000661
+:106F20000000000500000004000000030000000451
+:106F3000000000000000000100000002000000004E
+:106F40000000000100000002000000050000000336
+:106F50000000000600000005004800480048004806
+:106F6000009000900090009001200120012001205D
+:106F700004020402040204020005000500050005E5
+:106F80001200120012001200080008000800080099
+:106F90000120012001011020010101200120012018
+:106FA0000101102001200120010110200101012018
+:106FB0000120012001011020010101200000000436
+:106FC000000000060000012300000123000001234F
+:106FD0000000012300000123000001230000012321
+:106FE0000000012300000123000001230000012311
+:106FF0000000012300000123000001230000012301
+:1070000000000123000001230000012300000123F0
+:1070100000000123000000200000003200000007F3
+:107020000000000700000000000000080000000150
+:107030000000000000000000000000000215002019
+:10704000021500200000003008100000000000368B
+:1070500000000030000000310000000400000005C6
+:107060000000000000000004000000010000000615
+:10707000000000010000000200000040000000408D
+:107080000000001C000000200001000000020700BA
+:1070900000030E000004150000051C00000623007C
+:1070A00000072A000008310000093800000A3F00EC
+:1070B000000B4600000C4D00000D5400000E5B005C
+:1070C000000F6200001069000011700000127700CC
+:1070D00000137E000014850000158C00001693003C
+:1070E00000179A000018A1000019A800001AAF00AC
+:1070F000001BB600001CBD00001DC400001ECB001C
+:10710000001FD2000000D9000000001E0000001D7A
+:10711000000100000002078000030F000004168039
+:1071200000051E000006258000072D0000083480A1
+:1071300000093C00000A4380000B4B00000C528009
+:10714000000D5A00000E6180000F69000010708071
+:107150000011780000127F800013870000148E80D9
+:107160000015960000169D800017A5000018AC8041
+:107170000019B400001ABB80001BC300001CCA80A9
+:107180000000D2000000000100000001000000012A
+:1071900000000001000000010000000100000001EB
+:1071A00000000001000000010000000100000001DB
+:1071B00000000001000000010000000100000001CB
+:1071C00000000001000000280000002C000000303A
+:1071D0000000000100000001000000010000021199
+:1071E0000000020000000204000002190000FFFF7E
+:1071F0000000FFFF0000FFFF0000FFFF0000002075
+:1072000000000021000000010000000107FFFFFF57
+:107210000000007F07FFFFFF0000003F0000FFFFAE
+:107220000000FFFF0000FFFF0000FFFF00007FF8ED
+:1072300000007FF800000000000000010000FF00D7
+:10724000000000000000FF00000000000000FF0040
+:10725000000000000000FF00000000000000FF0030
+:10726000000000000000FF00000000000000FF0020
+:10727000000000000000FF00000000000000FF0010
+:10728000000000000000FF00000000000000FF0000
+:10729000000000000000FF00000000000000FF00F0
+:1072A000000000000000FF00000000000000FF00E0
+:1072B000000000000000FF00000000000000FF00D0
+:1072C000000000000000FF00000000000000FF00C0
+:1072D000000000000000FF00000000000000FF00B0
+:1072E000000000000000FF00000000000000FF00A0
+:1072F000000000000000FF00000000000000FF0090
+:10730000000000000000FF00000000000000FF007F
+:10731000000000000000FF00000000000000FF006F
+:10732000000000000000FF00000000000000FF005F
+:10733000000000000000FF00000000000000FF004F
+:10734000000000000000FF00000000000000FF003F
+:10735000000000000000FF00000000000000FF002F
+:10736000000000000000FF00000000000000FF001F
+:10737000000000000000FF00000000000000FF000F
+:10738000000000000000FF00000000000000FF00FF
+:10739000000000000000FF00000000000000FF00EF
+:1073A000000000000000FF00000000000000FF00DF
+:1073B000000000000000FF00000000000000FF00CF
+:1073C000000000000000FF00000000000000FF00BF
+:1073D000000000000000FF00000000000000FF00AF
+:1073E000000000000000FF00000000000000FF009F
+:1073F000000000000000FF00000000000000FF008F
+:10740000000000000000FF00000000000000FF007E
+:10741000000000000000FF00000000000000FF006E
+:10742000000000000000FF00000000000000FF005E
+:10743000000000000000FF00000000000000FF004E
+:10744000000000000000FF00000000000000FF003E
+:10745000000000000000FF00000000000000FF002E
+:10746000000000000000FF00000000000000FF001E
+:10747000000000000000FF000000000000201001DC
+:107480000000000001009000000001000000000169
+:107490000000000000000000140AFF00000090023D
+:1074A0000000000000000000000000000000900448
+:1074B0000000000000000000000000000000900636
+:1074C0000000000000000000000000000000900824
+:1074D0000000000000000000000000000000900A12
+:1074E0000000000000000000000000000000900C00
+:1074F0000000000000000000000000000000900EEE
+:1075000000000000000000000000000000009010DB
+:1075100000000000000000000000000000009012C9
+:1075200000000000000000000000000000009014B7
+:1075300000000000000000000000000000009016A5
+:107540000000000000000000000000000000901893
+:107550000000000000000000000000000000901A81
+:107560000000000000000000000000000000901C6F
+:107570000000000000000000000000000000901E5D
+:10758000000000000000000000000000000090204B
+:107590000000000000000000000000000000902239
+:1075A0000000000000000000000000000000902427
+:1075B0000000000000000000000000000000902615
+:1075C0000000000000000000000000000000902803
+:1075D0000000000000000000000000000000902AF1
+:1075E0000000000000000000000000000000902CDF
+:1075F0000000000000000000000000000000902ECD
+:1076000000000000000000000000000000009030BA
+:1076100000000000000000000000000000009032A8
+:107620000000000000000000000000000000903496
+:107630000000000000000000000000000000903684
+:107640000000000000000000000000000000903872
+:107650000000000000000000000000000000903A60
+:107660000000000000000000000000000000903C4E
+:107670000000000000000000000000000000903E3C
+:10768000000000000000000000000000000090402A
+:107690000000000000000000000000000000904218
+:1076A0000000000000000000000000000000904406
+:1076B00000000000000000000000000000009046F4
+:1076C00000000000000000000000000000009048E2
+:1076D0000000000000000000000000000000904AD0
+:1076E0000000000000000000000000000000904CBE
+:1076F0000000000000000000000000000000904EAC
+:107700000000000000000000000000000000905099
+:107710000000000000000000000000000000905287
+:107720000000000000000000000000000000905475
+:107730000000000000000000000000000000905663
+:107740000000000000000000000000000000905851
+:107750000000000000000000000000000000905A3F
+:107760000000000000000000000000000000905C2D
+:107770000000000000000000000000000000905E1B
+:107780000000000000000000000000000000906009
+:1077900000000000000000000000000000009062F7
+:1077A00000000000000000000000000000009064E5
+:1077B00000000000000000000000000000009066D3
+:1077C00000000000000000000000000000009068C1
+:1077D0000000000000000000000000000000906AAF
+:1077E0000000000000000000000000000000906C9D
+:1077F0000000000000000000000000000000906E8B
+:107800000000000000000000000000000000907078
+:107810000000000000000000000000000000907266
+:107820000000000000000000000000000000907454
+:107830000000000000000000000000000000907642
+:107840000000000000000000000000000000907830
+:107850000000000000000000000000000000907A1E
+:107860000000000000000000000000000000907C0C
+:107870000000000000000000000000000000907EFA
+:1078800000000000000000000000000000009080E8
+:1078900000000000000000000000000000009082D6
+:1078A00000000000000000000000000000009084C4
+:1078B00000000000000000000000000000009086B2
+:1078C00000000000000000000000000000009088A0
+:1078D0000000000000000000000000000000908A8E
+:1078E0000000000000000000000000000000908C7C
+:1078F0000000000000000000000000000000908E6A
+:107900000000000000000000000000000000909057
+:107910000000000000000000000000000000909245
+:107920000000000000000000000000000000909433
+:107930000000000000000000000000000000909621
+:10794000000000000000000000000000000090980F
+:107950000000000000000000000000000000909AFD
+:107960000000000000000000000000000000909CEB
+:107970000000000000000000000000000000909ED9
+:10798000000000000000000000000000000090A0C7
+:10799000000000000000000000000000000090A2B5
+:1079A000000000000000000000000000000090A4A3
+:1079B000000000000000000000000000000090A691
+:1079C000000000000000000000000000000090A87F
+:1079D000000000000000000000000000000090AA6D
+:1079E000000000000000000000000000000090AC5B
+:1079F000000000000000000000000000000090AE49
+:107A0000000000000000000000000000000090B036
+:107A1000000000000000000000000000000090B224
+:107A2000000000000000000000000000000090B412
+:107A3000000000000000000000000000000090B600
+:107A4000000000000000000000000000000090B8EE
+:107A5000000000000000000000000000000090BADC
+:107A6000000000000000000000000000000090BCCA
+:107A7000000000000000000000000000000090BEB8
+:107A8000000000000000000000000000000090C0A6
+:107A9000000000000000000000000000000090C294
+:107AA000000000000000000000000000000090C482
+:107AB000000000000000000000000000000090C670
+:107AC000000000000000000000000000000090C85E
+:107AD000000000000000000000000000000090CA4C
+:107AE000000000000000000000000000000090CC3A
+:107AF000000000000000000000000000000090CE28
+:107B0000000000000000000000000000000090D015
+:107B1000000000000000000000000000000090D203
+:107B2000000000000000000000000000000090D4F1
+:107B3000000000000000000000000000000090D6DF
+:107B4000000000000000000000000000000090D8CD
+:107B5000000000000000000000000000000090DABB
+:107B6000000000000000000000000000000090DCA9
+:107B7000000000000000000000000000000090DE97
+:107B8000000000000000000000000000000090E085
+:107B9000000000000000000000000000000090E273
+:107BA000000000000000000000000000000090E461
+:107BB000000000000000000000000000000090E64F
+:107BC000000000000000000000000000000090E83D
+:107BD000000000000000000000000000000090EA2B
+:107BE000000000000000000000000000000090EC19
+:107BF000000000000000000000000000000090EE07
+:107C0000000000000000000000000000000090F0F4
+:107C1000000000000000000000000000000090F2E2
+:107C2000000000000000000000000000000090F4D0
+:107C3000000000000000000000000000000090F6BE
+:107C4000000000000000000000000000000090F8AC
+:107C5000000000000000000000000000000090FA9A
+:107C6000000000000000000000000000000090FC88
+:107C7000000000000000000000000000000090FE76
+:107C80000000000000000000000000000000910063
+:107C90000000000000000000000000000000910251
+:107CA000000000000000000000000000000091043F
+:107CB000000000000000000000000000000091062D
+:107CC000000000000000000000000000000091081B
+:107CD0000000000000000000000000000000910A09
+:107CE0000000000000000000000000000000910CF7
+:107CF0000000000000000000000000000000910EE5
+:107D000000000000000000000000000000009110D2
+:107D100000000000000000000000000000009112C0
+:107D200000000000000000000000000000009114AE
+:107D3000000000000000000000000000000091169C
+:107D4000000000000000000000000000000091188A
+:107D50000000000000000000000000000000911A78
+:107D60000000000000000000000000000000911C66
+:107D70000000000000000000000000000000911E54
+:107D80000000000000000000000000000000912042
+:107D90000000000000000000000000000000912230
+:107DA000000000000000000000000000000091241E
+:107DB000000000000000000000000000000091260C
+:107DC00000000000000000000000000000009128FA
+:107DD0000000000000000000000000000000912AE8
+:107DE0000000000000000000000000000000912CD6
+:107DF0000000000000000000000000000000912EC4
+:107E000000000000000000000000000000009130B1
+:107E1000000000000000000000000000000091329F
+:107E2000000000000000000000000000000091348D
+:107E3000000000000000000000000000000091367B
+:107E40000000000000000000000000000000913869
+:107E50000000000000000000000000000000913A57
+:107E60000000000000000000000000000000913C45
+:107E70000000000000000000000000000000913E33
+:107E80000000000000000000000000000000914021
+:107E9000000000000000000000000000000091420F
+:107EA00000000000000000000000000000009144FD
+:107EB00000000000000000000000000000009146EB
+:107EC00000000000000000000000000000009148D9
+:107ED0000000000000000000000000000000914AC7
+:107EE0000000000000000000000000000000914CB5
+:107EF0000000000000000000000000000000914EA3
+:107F00000000000000000000000000000000915090
+:107F1000000000000000000000000000000091527E
+:107F2000000000000000000000000000000091546C
+:107F3000000000000000000000000000000091565A
+:107F40000000000000000000000000000000915848
+:107F50000000000000000000000000000000915A36
+:107F60000000000000000000000000000000915C24
+:107F70000000000000000000000000000000915E12
+:107F80000000000000000000000000000000916000
+:107F900000000000000000000000000000009162EE
+:107FA00000000000000000000000000000009164DC
+:107FB00000000000000000000000000000009166CA
+:107FC00000000000000000000000000000009168B8
+:107FD0000000000000000000000000000000916AA6
+:107FE0000000000000000000000000000000916C94
+:107FF0000000000000000000000000000000916E82
+:10800000000000000000000000000000000091706F
+:10801000000000000000000000000000000091725D
+:10802000000000000000000000000000000091744B
+:108030000000000000000000000000000000917639
+:108040000000000000000000000000000000917827
+:108050000000000000000000000000000000917A15
+:108060000000000000000000000000000000917C03
+:108070000000000000000000000000000000917EF1
+:1080800000000000000000000000000000009180DF
+:1080900000000000000000000000000000009182CD
+:1080A00000000000000000000000000000009184BB
+:1080B00000000000000000000000000000009186A9
+:1080C0000000000000000000000000000000918897
+:1080D0000000000000000000000000000000918A85
+:1080E0000000000000000000000000000000918C73
+:1080F0000000000000000000000000000000918E61
+:10810000000000000000000000000000000091904E
+:10811000000000000000000000000000000091923C
+:10812000000000000000000000000000000091942A
+:108130000000000000000000000000000000919618
+:108140000000000000000000000000000000919806
+:108150000000000000000000000000000000919AF4
+:108160000000000000000000000000000000919CE2
+:108170000000000000000000000000000000919ED0
+:10818000000000000000000000000000000091A0BE
+:10819000000000000000000000000000000091A2AC
+:1081A000000000000000000000000000000091A49A
+:1081B000000000000000000000000000000091A688
+:1081C000000000000000000000000000000091A876
+:1081D000000000000000000000000000000091AA64
+:1081E000000000000000000000000000000091AC52
+:1081F000000000000000000000000000000091AE40
+:10820000000000000000000000000000000091B02D
+:10821000000000000000000000000000000091B21B
+:10822000000000000000000000000000000091B409
+:10823000000000000000000000000000000091B6F7
+:10824000000000000000000000000000000091B8E5
+:10825000000000000000000000000000000091BAD3
+:10826000000000000000000000000000000091BCC1
+:10827000000000000000000000000000000091BEAF
+:10828000000000000000000000000000000091C09D
+:10829000000000000000000000000000000091C28B
+:1082A000000000000000000000000000000091C479
+:1082B000000000000000000000000000000091C667
+:1082C000000000000000000000000000000091C855
+:1082D000000000000000000000000000000091CA43
+:1082E000000000000000000000000000000091CC31
+:1082F000000000000000000000000000000091CE1F
+:10830000000000000000000000000000000091D00C
+:10831000000000000000000000000000000091D2FA
+:10832000000000000000000000000000000091D4E8
+:10833000000000000000000000000000000091D6D6
+:10834000000000000000000000000000000091D8C4
+:10835000000000000000000000000000000091DAB2
+:10836000000000000000000000000000000091DCA0
+:10837000000000000000000000000000000091DE8E
+:10838000000000000000000000000000000091E07C
+:10839000000000000000000000000000000091E26A
+:1083A000000000000000000000000000000091E458
+:1083B000000000000000000000000000000091E646
+:1083C000000000000000000000000000000091E834
+:1083D000000000000000000000000000000091EA22
+:1083E000000000000000000000000000000091EC10
+:1083F000000000000000000000000000000091EEFE
+:10840000000000000000000000000000000091F0EB
+:10841000000000000000000000000000000091F2D9
+:10842000000000000000000000000000000091F4C7
+:10843000000000000000000000000000000091F6B5
+:10844000000000000000000000000000000091F8A3
+:10845000000000000000000000000000000091FA91
+:10846000000000000000000000000000000091FC7F
+:10847000000000000000000000000000000091FE6D
+:10848000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC
+:10849000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC
+:1084A0000000FFFF00000000FFFFFFFFFFFFFFFFD6
+:1084B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCC
+:1084C000FFFFFFFFFFFFFFFF0000FFFF00000000B6
+:1084D0000000000200001500000000010000000282
+:1084E0000000000300000000000000040000000184
+:1084F0000000000000000001000000040000000077
+:108500000000000100000003000000000000000166
+:108510000000000400000000000000010000000353
+:108520000000000000000001000000040000000046
+:108530000000000400000003000000000000000034
+:1085400000007FFF000003FFFFFFFFFFFFFFFFFFB3
+:10855000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2B
+:10856000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1B
+:10857000FFFFFFFFFFFFFFFF0000000300BEBC2066
+:1085800000000000000000050000000300BEBC2049
+:1085900000000000000000050000000300BEBC2039
+:1085A00000000000000000050000000300BEBC2029
+:1085B00000000000000000050000000300BEBC2019
+:1085C00000000000000000050000000300BEBC2009
+:1085D00000000000000000050000000300BEBC20F9
+:1085E00000000000000000050000000300BEBC20E9
+:1085F00000000000000000050000000D0000000C5D
+:1086000000000000000000100000000F000000004B
+:1086100000000000000000000215002002150020EC
+:10862000000000300810000000000036000000309C
+:108630000000003100000003000000000000000105
+:1086400000000003000000010000000200000040E4
+:108650000000004000000004000000200000000FA7
+:108660000000001B00008000000103C000018780A3
+:1086700000020B4000028F00000312C0000396802E
+:1086800000041A4000049E00000521C00005A580DA
+:10869000000629400006AD00000730C00007B48086
+:1086A000000838400008BC0000093FC00009C38032
+:1086B000000A4740000ACB00000B4EC0000BD280DE
+:1086C000000C5640000CDA00000D5DC00000618017
+:1086D0000000000100000001000000010000000196
+:1086E0000000000100000001000000010000000186
+:1086F0000000000100000001000000010000000176
+:108700000000000100000001000000010000000165
+:10871000000000010000050E000004FD000005013E
+:108720000000051E0000FFFF0000FFFF0000FFFF2C
+:108730000000FFFF000000460000000C00000000E9
+:10874000000000000000001C000000F40000000118
+:108750000000000000000000000000000000000118
+:108760000000000107FFFFFF0000007F07FFFFFF81
+:108770000000003F0000FFFF0000FFFF0000FFFFC0
+:108780000000FFFF00007FF800007FF80000FF00FE
+:10879000000000000000FF00000000000000FF00DB
+:1087A000000000000000FF00000000000000FF00CB
+:1087B000000000000000FF00000000000000FF00BB
+:1087C000000000000000FF00000000000000FF00AB
+:1087D000000000000000FF00000000000000FF009B
+:1087E000000000000000FF00000000000000FF008B
+:1087F000000000000000FF00000000000000FF007B
+:10880000000000000000FF00000000000000FF006A
+:10881000000000000000FF00000000000000FF005A
+:10882000000000000000FF00000000000000FF004A
+:10883000000000000000FF00000000000000FF003A
+:10884000000000000000FF00000000000000FF002A
+:10885000000000000000FF00000000000000FF001A
+:10886000000000000000FF00000000000000FF000A
+:10887000000000000000FF00000000000000FF00FA
+:10888000000000000000FF00000000000000FF00EA
+:10889000000000000000FF00000000000000FF00DA
+:1088A000000000000000FF00000000000000FF00CA
+:1088B000000000000000FF00000000000000FF00BA
+:1088C000000000000000FF00000000000000FF00AA
+:1088D000000000000000FF00000000000000FF009A
+:1088E000000000000000FF00000000000000FF008A
+:1088F000000000000000FF00000000000000FF007A
+:10890000000000000000FF00000000000000FF0069
+:10891000000000000000FF00000000000000FF0059
+:10892000000000000000FF00000000000000FF0049
+:10893000000000000000FF00000000000000FF0039
+:10894000000000000000FF00000000000000FF0029
+:10895000000000000000FF00000000000000FF0019
+:10896000000000000000FF00000000000000FF0009
+:10897000000000000000FF00000000000000FF00F9
+:10898000000000000000FF00000000000000FF00E9
+:10899000000000000000FF00000000000000FF00D9
+:1089A000000000000000FF00000000000000FF00C9
+:1089B000000000000000FF00000000000000FF00B9
+:1089C000000000000000FF0000000000FFFFFFFFAC
+:1089D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7
+:1089E000FFFFFFFFFFFFFFFFFFFFFFFF000019007A
+:1089F0000000000000000001000000000000000076
+:108A0000000000000000000200001500000000014E
+:108A1000000000020000000300000000000000044D
+:108A20000000000100000000000000010000000440
+:108A30000000000000000001000000030000000032
+:108A40000000000100000004000000000000000120
+:108A5000000000030000000000000001000000040E
+:108A600000000000000000040000000300000000FF
+:108A70000000000000007FFF000003FF0000000076
+:108A800003938700000000000000000000000000C9
+:108A90000393870000000000000000000000000FAA
+:108AA00000000007000000000000000E0000000EA3
+:108AB000000000000000000000000000031500207E
+:108AC00003150020010000300810000000000036EF
+:108AD000000000300000003100000002000000052E
+:108AE000000000020000000200000000000000057D
+:108AF000000000030000000100000004000000016D
+:108B000000000002000000400000004000000004DF
+:108B10000000002000000002000000200000100003
+:108B20000000208000003100000041800000520061
+:108B30000000628000007300000083800000940049
+:108B40000000A4800000B5000000C5800000D60031
+:108B50000000E6800000F700000107800001180017
+:108B600000012880000139000001498000015A00FD
+:108B700000016A8000017B0000018B8000019C00E5
+:108B80000001AC800001BD000001CD800001DE00CD
+:108B90000001EE800001FF0000000F8000000001D6
+:108BA00000000001000000010000000100000001C1
+:108BB00000000001000000010000000100000001B1
+:108BC00000000001000000010000000100000001A1
+:108BD0000000000100000001000000010000000191
+:108BE000000000010000000100000001000012145C
+:108BF00000001200000012040000FFFF0000FFFF51
+:108C00000000FFFF0000FFFF000000200000003810
+:108C1000000000000000000000000023000000240D
+:108C20000000002500000026000000270000003999
+:108C30000000003A0000002B0000002C00000000A3
+:108C4000000000EC00000000000000290000002AE5
+:108C50000000000100000001000000010000000110
+:108C60000000000000000000000000000000000103
+:108C700007FFFFFF0000007F07FFFFFF0000003F2E
+:108C80000000FFFF0000FFFF0000FFFF0000FFFFEC
+:108C900000007FF800007FF80000000000000001E5
+:108CA000CCCC0201CCCCCCCCCCCC0201CCCCCCCC2E
+:108CB000CCCC0201CCCCCCCCCCCC0201CCCCCCCC1E
+:108CC000CCCC0201CCCCCCCCCCCC0201CCCCCCCC0E
+:108CD000CCCC0201CCCCCCCCCCCC0201CCCCCCCCFE
+:108CE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF94
+:108CF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF84
+:108D00000000000000010001001E0C07CCCCCCC903
+:108D100010000000000028AD0000291800002919EB
+:108D20000000000000000000000000050000000638
+:108D30007058103C000000000000FF000000000020
+:108D40000000FF00000000000000FF000000000025
+:108D50000000FF00000000000000FF000000000015
+:108D60000000FF00000000000000FF000000000005
+:108D70000000FF00000000000000FF0000000000F5
+:108D80000000FF00000000000000FF0000000000E5
+:108D90000000FF00000000000000FF0000000000D5
+:108DA0000000FF00000000000000FF0000000000C5
+:108DB0000000FF00000000000000FF0000000000B5
+:108DC0000000FF00000000000000FF0000000000A5
+:108DD0000000FF00000000000000FF000000000095
+:108DE0000000FF00000000000000FF000000000085
+:108DF0000000FF00000000000000FF000000000075
+:108E00000000FF00000000000000FF000000000064
+:108E10000000FF00000000000000FF000000000054
+:108E20000000FF00000000000000FF000000000044
+:108E30000000FF00000000000000FF000000000034
+:108E40000000FF00000000000000FF000000000024
+:108E50000000FF00000000000000FF000000000014
+:108E60000000FF00000000000000FF000000000004
+:108E70000000FF00000000000000FF0000000000F4
+:108E80000000FF00000000000000FF0000000000E4
+:108E90000000FF00000000000000FF0000000000D4
+:108EA0000000FF00000000000000FF0000000000C4
+:108EB0000000FF00000000000000FF0000000000B4
+:108EC0000000FF00000000000000FF0000000000A4
+:108ED0000000FF00000000000000FF000000000094
+:108EE0000000FF00000000000000FF000000000084
+:108EF0000000FF00000000000000FF000000000074
+:108F00000000FF00000000000000FF000000000063
+:108F10000000FF00000000000000FF000000000053
+:108F20000000FF00000000000000FF000000000043
+:108F30000000FF00000000000000FF000000000033
+:108F40000000FF00000000000000FF000000000023
+:108F50000000FF00000000000000FF000000000013
+:108F60000000FF00000000000000FF000000000003
+:108F70000000FF0000000000FFFFFFFFFFFFFFFFFA
+:108F8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1
+:108F9000FFFFFFFFFFFFFFFF0000FFFF00000000DB
+:108FA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1
+:108FB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1
+:108FC0000000FFFF0000000003231303130323131B
+:108FD00003030323A0B0904302000200060406042A
+:108FE000032313031303231303030323A0B09043AA
+:108FF000131313131313131313131313A0B090436A
+:109000000301020000000000000000020000150043
+:10901000000000010000000200000003000000004A
+:10902000000000040000000100000000000000013A
+:109030000000000400000000000000010000000328
+:10904000000000000000000100000004000000001B
+:10905000000000010000000300000000000000010B
+:1090600000000004000000000000000400000003F5
+:10907000000000000000000000007FFF000003FF70
+:10908000002625A000000000002625A0000000000A
+:10909000002625A000000000002625A000000000FA
+:1090A000000E0000011600D6002625A000000000DA
+:1090B000002625A000000000002625A000000000DA
+:1090C000002625A00000000000720000012300F32C
+:1090D0000000FFFF000000000000FFFF0000000094
+:1090E0000000FFFF000000000000FFFF0000000084
+:1090F0000000FFFF000000000000FFFF0000000074
+:1091000000000000000000000000FFFF0000000061
+:109110000000FFFF000000000000FFFF0000000053
+:109120000000FFFF000000000000FFFF0000000043
+:109130000000FFFF000000000000FFFF0000000033
+:1091400000000000000000000000FFFF0000000021
+:109150000000FFFF000000000000FFFF0000000013
+:109160000000FFFF000000000000FFFF0000000003
+:109170000000FFFF000000000000FFFF00000000F3
+:1091800000000000000000000000FFFF00000000E1
+:109190000000FFFF000000000000FFFF00000000D3
+:1091A0000000FFFF000000000000FFFF00000000C3
+:1091B0000000FFFF000000000000FFFF00000000B3
+:1091C00000000000000000000000FFFF00000000A1
+:1091D0000000FFFF000000000000FFFF0000000093
+:1091E0000000FFFF000000000000FFFF0000000083
+:1091F0000000FFFF000000000000FFFF0000000073
+:1092000000000000000000000000FFFF0000000060
+:109210000000FFFF000000000000FFFF0000000052
+:109220000000FFFF000000000000FFFF0000000042
+:109230000000FFFF000000000000FFFF0000000032
+:1092400000000000000000000000FFFF0000000020
+:109250000000FFFF000000000000FFFF0000000012
+:109260000000FFFF000000000000FFFF0000000002
+:109270000000FFFF000000000000FFFF00000000F2
+:1092800000000000000000000000FFFF00000000E0
+:109290000000FFFF000000000000FFFF00000000D2
+:1092A0000000FFFF000000000000FFFF00000000C2
+:1092B0000000FFFF000000000000FFFF00000000B2
+:1092C00000000000000000000000FFFF00000000A0
+:1092D000555400005555555500005555F0000000F7
+:1092E000555400005555555500005555F0000000E7
+:1092F0000000000000010000000050140000000009
+:10930000FFF55FFF0000FFFFF00003E0000000003A
+:109310000000A000000004000000000000000000A9
+:10932000000000000000100000000000000000002D
+:1093300000000000000040000000000000000000ED
+:109340000000000000010000FF5C0000FFF55FFF6F
+:109350000000FFFFF00003E0000000000000A0009C
+:1093600000000800000000000000000000000000F5
+:1093700000002000000000000000000000000000CD
+:10938000000080000000000000000000000000005D
+:1093900000020000000000001F8B08000000000019
+:1093A000000BFB51CFC0F003099F9240E57FE145E0
+:1093B000E5A3E345FCF8E509611E06A01DDCE4EB2E
+:1093C0008F011A9006C4F379D0DCCD08A10FB23317
+:1093D00030E4B33130F403E9ED2C08F9340608ED3C
+:1093E0006788105BAEC7C0C0AC03619BE850E6AFB6
+:1093F000513C34B0B60D2A5FC50A42AFB486D03AAC
+:1094000068F2AA50F95B66105AD706BBB9B7CD8887
+:10941000B37F82332A5FDC19BF7A260F080D002A3A
+:1094200039881AB8030000000000000000000000A6
+:109430001F8B080000000000000BCD7D0D781CD5AF
+:1094400075E89DBFDDD9DDD9DDB1B49257B224CF27
+:10945000CAB2BD0619C6B66C6462C248982012D161
+:109460002CC64D0575D3B5318E92989785B889680D
+:109470000C1A593F9625FFC88606FFB3363F2529AB
+:109480004D1742F2685E9AB7226E63FA68A3380EEF
+:1094900031AD49D6409CA4CDF7AA902626EF23F5FE
+:1094A000BBE7DC3BD2CC6A25630869D43AC39D9FF5
+:1094B0007BCF3DF7FC9F73EFFAB53AB2E07A422ECC
+:1094C000C21FBD5AD97B3B488C9032229A43F4DAB2
+:1094D0005BF32B9B18846C27F46F25210370ADA2DE
+:1094E000FFE265D8CE68F4E172426C61453E41DF2F
+:1094F000D72C755C320991B41C49371262747DEE29
+:109500009102BDFF4B5B26434DF4BDD6CC5F42DBE1
+:10951000DEE6D77BE9F5E1D0038F14E8FD2E59D5BF
+:10952000FD26749EB926B5988EDB4D487E21B6AFD8
+:1095300086B64C41CB354EC2E95CE71091900A7873
+:10954000AF463F1F22F8775182FFED2239DAAF7C18
+:109550005ACA0E2568F36CBA855452B8D82BF4DA7F
+:109560009EFF9FF479FC0632EE5F39D99FA4FB4839
+:109570005EE5FDE08BEBA2696DEAB8CEB5EBECFAE7
+:10958000EC09D7FB8D241C43386422031CF4919909
+:10959000A7E3F84F4BE61099BE9F0BDDE9EC89F984
+:1095A00080AF3F8EC27CA77BCFC14B7FB74AF27E94
+:1095B0004286BA75BC2A3574E9289C0AC5D333148F
+:1095C0004F4ACC26848E3B58537F3C2410E2030044
+:1095D000611D1A8CE343B4FD0122E0BA0DD6EC53B1
+:1095E000AD19E6471A283E927C7EF5D00FEB97D452
+:1095F00090ECE3D02F1DF7381DCF172F1E4FC5B6A7
+:1096000033DEDA77389E9FDC164D85E9322C2264F2
+:109610004C03BCD2715CDF1383AD976CB0F72F8520
+:109620003F591327FBA7FF7CB1A0A71D4A9679D706
+:10963000BF98AEE2242937019E8326CCEB7621BD6C
+:1096400019E8CF38F1C7561FC5EF1B16191FAA001E
+:10965000FCA709D00D017C217D120BE80FBBA2B045
+:10966000B6BC29E37A044D92857EC2A480C4192534
+:109670001451F30899450C8111AB29C0FC0959A577
+:109680009FBF927E1270E8FBDDF6B70EFB13ACBDF8
+:10969000E462E86DF427D3FEE6FD16FBBB047C0113
+:1096A0007218FBA3DC1DBB584EC80E4AEF9418E895
+:1096B000FF07185D3512E4EB5E4AFF707F7B771C75
+:1096C000AF44FE8A25821C327DC61095279AFE4C37
+:1096D0001EDED7BFE127D138F4CFE84B84F59C07D5
+:1096E000EB4DCE8957D1ABE9E57BB5C6E7A18B62DF
+:1096F0003AE8AF58303B5D421E4DD0251500097544
+:10970000F2FDE9DE7BAFAF202F128A9BFEEB5128E2
+:109710004D372FA931CD904352C4CD47B248D22006
+:109720007F7BB50D2ACC9BBC75F1A2B4C2254FB589
+:109730005473297C9C2209E47BA7ADE803F7081148
+:109740007A8D6FB40A2E384EC37F2C87FB9BADC237
+:109750000C7897E454C77A903F4DC47C9CD2D5DEF8
+:10976000D047C9B946D0231FC5751EA8A84CF841DB
+:10977000DE936DD81F5135A2AE98A4C3D18A8FC491
+:109780000BF4FDFEAA8FC4418EF42BA9788AB64F44
+:10979000567CD5827E07DE8A12D04303F1FA28CCAC
+:1097A00067E0AD79B33325E61502894AE10F025C23
+:1097B000094657243909A74DD28309DA5FE8249571
+:1097C000FB08E7372C89B67D869C81FE7D1A1D97A4
+:1097D0008EDFD694B3D6537AF5A5B5B45F9FDA8FF2
+:1097E000330EFD132E52BE21F08EC35782E7794906
+:1097F000388ADBBE0611F9478E916C6F89F71535F3
+:109800006287AE02F936715F87711B5E5C8C7215E0
+:10981000DE3754185AB0807F26E93DEB5967A28B9A
+:1098200093FDD60337D88302E841A266802F8BF1DF
+:1098300039E0239D405F44B63A00BE3EA16C29D872
+:109840000BD3CAF1F8E0CFA5ABA67FEED77D79A008
+:10985000333996B101BF141EF32614113BC784ABF4
+:10986000F0FA732902EFC9FFE6A6C30681EBEF6B9E
+:10987000C835808F5E8DD1C174E3F453FE220BA7EF
+:109880007FAEF8CC740AF540E68C10033C5C85F39F
+:10989000926BFEE14C82C2B15C607A518EF96C9899
+:1098A0000FD1E59F155C786B96ACE502E89320EB51
+:1098B000A7B8FF9BA5D69502FDFE25927A1FBC375F
+:1098C0009858C1F58E976FF4B4C9F9DA8A08958C67
+:1098D0006ED95F362F823E4B6B16AC8BD2749C4890
+:1098E000144EBD5A62F23229BF0AF058F4FF001E2E
+:1098F000C9FAC95942E18CACA2F75D7893AC20CA91
+:109900005185B0F71D7A9400CF57C1D57BFF56C063
+:10991000F3952E3C773F475E9BEFB2C3C0DE2B3101
+:109920005F22B5FE11CCB7787E7EE00D6AC7112D9F
+:10993000330878A65A627C88F2CA01581FAA171EFB
+:10994000EC4EE2F5E16E13D7EB507733B6FBBA2D50
+:109950006C0F77B761FB48770ADBBEAA3E15F0783B
+:10996000A06AE4800076A97DDA7A91E2E34078E4A7
+:10997000658276EA29EB45DAC5012A5BC9B584DC44
+:10998000DBF34F964DE9E4C02CD6FE5CCF77597BD4
+:10999000FEC8ED22BEFF75F67D2D7BDED7F33DF6CA
+:1099A0007C316B8FF4FC0B6B074807CC9BD4ACC5A8
+:1099B000F94C47578E7C0B0B06B32F6A6268974BA6
+:1099C000C60602B70E54D07E1A27FBA1E8546F0DCD
+:1099D0004FDFCF97041DFB71ECC4377419F5EB8191
+:1099E000C4E5C11390472CC48FFD23EB34C54F0051
+:1099F00068A49A90AF09E72C5BE3FA82CEF784F073
+:109A00009ACDE7CFFAA7FAE60F5DFAE6AB8282FDC0
+:109A10001D58E29DC7A5C67F0EE880CE23DA5E0002
+:109A20005B985C27A41F01BE08AFCBE77D142FDB3A
+:109A30006B9E41BFC4C1D7F4FDD9D8CFF3A03496F3
+:109A40004FBEAF99167EDF03F8A2F78F6C69453AD7
+:109A500079AAA80DF80679E9D8C10E3EA71D4F775F
+:109A6000C9F1FAA9F44D64AA8FE9FAFD25D13DF0B8
+:109A7000FC05D13DEB1FD018DFBC5D7C0D177DFFD1
+:109A8000D9A2F6DD45E3553D2592E6A57449378A0E
+:109A900033DA113D45FD9473FE74C6AFBC63451ABD
+:109AA000D7A1BD09EFFFC55AD1023C6D7C7CE171A5
+:109AB000A9049EA04780E3A8687D9FF13F9327A259
+:109AC0002DA01DF7792175EB8DE05F5E47ED020259
+:109AD00076A557DE10775B9ADAFE3197C3A49DC155
+:109AE0007BFD5BD7AB80EF60584C815F1554B27A39
+:109AF00059E3245D54727BC8817F1519FFE6C518B0
+:109B0000DA57E8EF7CFE8E0FC6376853E177FA1F0D
+:109B1000D6C4B62C7C5F24EF87E59CEA1E67BE9115
+:109B2000B94CFF3945409E7FF6C322DAD93BB9BF15
+:109B300038C4FDC541F017697B80DACB70EDB98E72
+:109B4000207D46CE86B2DBE8FB9158C1027957B141
+:109B50006D6E4B92CE2B12B7E271DAFE9BE552CFBF
+:109B6000EA5A30A10A8897079BD7444909F9EC5C67
+:109B7000C3A658E457053DF675C0F0FA59FE78F5CE
+:109B80008CF67684FA1F66235C197D4BD19FC5370E
+:109B9000B9F4B24F94105F92746B06F4E46E81C90D
+:109BA0000DE7F92DA288F81F12557C2F39B15E0CF4
+:109BB0004F5AB8D5CE839D2090CC7C7DEABA684AB6
+:109BC0001ED7FFBF6BFEBB679971B09FEC5E6AB496
+:109BD000BC9FEA598DDA0B60DF94AFB3EFA4F77B3B
+:109BE000A95D09711745D5CEC17D85EBDD7F12D208
+:109BF0009F13993F2A00BF513B9D5DA525E3109718
+:109C000050DEE7338F93A9F8FA538E2F1FE00BEC49
+:109C100013C057D324BE8634862F4AA525F1B540FC
+:109C200064FC3F2467558637F6FD6EF89EF2E34EDE
+:109C30006DE98E79F0FD698950B54F76CA797CEF70
+:109C40007785CF6278C2610A0FF815DF63F08495DB
+:109C500031FD7709CFB4EB5BD6F18ED6F7BF8B4ED3
+:109C6000A550AA03F86F12BF541E26181C22C489DF
+:109C70004426677771F9B74B1EFB9DAEFB1B23FD96
+:109C8000036007FF5449D581DFD7F9D0C2D560CF33
+:109C90006EE0FAE9DFBA4FEA3225808D7BFB2B4B71
+:109CA000C5FD3E29910CCA7D69E707309E46ECA4AC
+:109CB000B404DB0B3AE9FD6F89018F1F3421FFB338
+:109CC000CAF884BD5C3F356EF865D16B0FFF9234E6
+:109CD000466F37A6C78B03A713379C164E35E7038D
+:109CE000383BB78E048696B0F98ED0F9FE33978351
+:109CF00064B002F5D1279F7C41975D78EB1C51CE73
+:109D0000F9AF9A0AF7443CCBF98EAA177FD9D4EF62
+:109D1000A7FB2EA3A54F89143F966C55DE0E71E666
+:109D20005504FDE3D053A3763599EC77126E2A43A0
+:109D3000964CAED3E5C2A9C633162C6D10FEC7658E
+:109D4000EF7548E95745D73AF9EB9E8BBBFD3CD9F7
+:109D500047F53BD851C9B54C5F2FFE8CB19E3E4FA5
+:109D600050FD7CABCB4E75ECA8FEEE2CFA2FFE1A04
+:109D700016F7538D0CDA896A9764BCBE0CFA8921F8
+:109D80007D0D36327E54D51CD1E93534F2741EE295
+:109D9000559461309E0170AF5D0CAE08A3FBBFA26D
+:109DA0005766BF64797CC41BAF54BB7CD8FF50B7E7
+:109DB00021B8FDA7E034FED3AF39FF39F8F92CD034
+:109DC000097DEFC20363F21A7ABD25FFB25C4FC76B
+:109DD000AF91D87BA7BADFC4795D7880F9E7B7B4D3
+:109DE0007F47BEC185A7B9920FFBB9858F47C89839
+:109DF000ECF6331CBBE7FAB7A27958CF7F3A29A11A
+:109E0000FE988EAED7C46FC8CAE593ED534D12B31A
+:109E10009364E316F8FE9636492C654717C71FD69C
+:109E2000C43F80FD5CB87F4C063E3FD5AD0AAF29EC
+:109E30006C7E4618FAF98E0C71E84BC11D065BB1B9
+:109E400002ED27C4EF85FB7304E45B28FFB704FA37
+:109E50000925B39605F0411FE037258D6300DFF536
+:109E60006FFD8DBA66F1643F4EBFA1A2F90D27B90F
+:109E70001D28E7DA303EDA28BEADF985F8FC1CBCB7
+:109E8000EEB9045EF3DD56562E21279CAB751DB549
+:109E900073291C964262A5E471F1F82DA4252BBB11
+:109EA000E4D73B856374159D3FC5DDA8AC6BEF64BB
+:109EB0005C7F9DC0E29284F137FD3B21835DD766D4
+:109EC0003E0A785CCFE993CA9DF512D2BD95EF6941
+:109ED000C2E5C2385454CF11027986BA24C67988B3
+:109EE0005656D26FEAEF2ECC9695A970F52BDC3F33
+:109EF0007DEB8634C677C4E43D107718AA15D0AF41
+:109F00009D0EAE2D00D772846B8B84F901CBDE5091
+:109F100002AEA1450BDE2D5C9D6057F4898D08973C
+:109F2000038F1227685F38DF0D70788BE11CA8F271
+:109F3000215DF72D311F059130CCE1262487FE28C5
+:109F4000857F18E077FA91F571947FFD159B6CC0C1
+:109F5000F31BF415B05BA683DFA79E9F0D74ECC8BE
+:109F6000A33EF8CF95203F297C57533A6F647C3548
+:109F70005441B28D74FC40037DD604EDB1BF8636EA
+:109F80007D8FE8AEB6D3EF504536AEB9E45FFFA2A1
+:109F900027CEF821FE1A23C642FA9E92BF1DF9571A
+:109FA00089A5481AFC743967C1FA9146920039ECC8
+:109FB00053472CC01B69A06D7A19FA4D2FB6ED04DA
+:109FC0007B4EF4A59EF93C25B13CE4E43AD83CEF45
+:109FD000C3E2E84A92D9730F48E907810E959A8146
+:109FE00031B4E3789E684D917FEC5CBF3BCDBA7C89
+:109FF000F716BF675DBE31755DBE516A5DBE7BCB36
+:10A0000042464F6D1525E31F6BD4D766CBCBDCF0F2
+:10A01000B33C4E0D411D45F670FAF1C5F5DB015F0D
+:10A0200012AC2FA5ABC3B1FD49B0ABF6C59E044F32
+:10A030009A3E1F413BB4DB487F5B72F16F4D86E077
+:10A04000FD214E9F374AAB02AFD2EB83EDF551F0C5
+:10A0500097FF93EB9D62B876513F16E81CF29E7015
+:10A06000BDF0CAC219E3B2C7BB8947CE1C6F92517B
+:10A07000CE1E1F3C95BA81C2DD1F6B580AA2DDEAD5
+:10A08000FC4E07D8D765A6B114EC90F37C7C8ABF50
+:10A09000F3920B9F4A6C9CC755291C2E7CC8549C7C
+:10A0A00034C4301E3F9ED5011F39D4E7719D987985
+:10A0B00003E7FF1FB00ED58D4480F45455DA241009
+:10A0C0008772E64F88F9027CBFFF85F94BDDF9E125
+:10A0D0000FC83CAFBD8AF10D91CD78AA64FC8EAD5E
+:10A0E000D3518A9FC6F9C8FF983F1B86B64B2E3CBA
+:10A0F0002DA5890C70740531CE5CDD692A309F5323
+:10A10000DCEF13887AA20AE94B47FD75F4CF839CF4
+:10A11000BEF4638092A02C16D357505E3E95BEB617
+:10A12000CAE930DC0F366630D657D795C7FB0191A8
+:10A13000D95375F7B13CE070A7711CFAA5E09F02F6
+:10A14000FAAA15183E9B6401E7E3AF196BD90871B1
+:10A15000E8B46681FC30C643F8DD769E3F1CAE292C
+:10A160007C27C1FD47E0C79AA6C7466F007EB5D4DD
+:10A1700071885B0793F91668CFE1F50855A490F74D
+:10A1800025189E20EE519319174AD14F9D2F83F920
+:10A19000A0DA9A4DED606F0A7F7EA605E4C6F61E32
+:10A1A00062FA0DC05B3E0F79A2DA66BF0E743F6C97
+:10A1B0001011E4D1F6BB89D903B2C862CF43969A95
+:10A1C000923035991D85D874ED1682F12DBD863CEF
+:10A1D000EA8E6F6935E9BB619C4FCBE926C09B666F
+:10A1E00032BB315893CF43B87EBF42ED44DA0EAD57
+:10A1F0002A5800D7AEE59F21EB5D72ED464E27FE53
+:10A200004662A11DC1E9F3304FCCED6B7B3EF031CE
+:10A21000E03339C8FDF82D16F447CDBE3CF06F0889
+:10A22000E894209DAE06FAD033D95134951BCDBCAD
+:10A2300068205F629E73BF625781BDBA7FB9AF036A
+:10A24000F4355DB797C80A6A1F8964F20FEC971A54
+:10A25000EB31A09F5F4B2C7E1B5EFD44FE08F0C3DC
+:10A26000FBFCBA4CD76547E518A9A378288F4BC4E7
+:10A27000A0EB126ECAE6FF8E3EAF76F015378692DF
+:10A28000C08F31625A88EF6CFE15FA7C4E4788C049
+:10A290003AEA741D814428BEEE0078B5B6911601E5
+:10A2A000E4713DA3FBE372E687F7D3F78F9F944CED
+:10A2B000DB70F10FA1FCE3B2DBE70D52F9E0F11323
+:10A2C000191FB540A5091DBF7A0BCB2F3BF26F0EAE
+:10A2D0009F620D2908013AFE5C4244853E4FAC3531
+:10A2E000B6419C79DEBAECCB597AED0DBF54C5E48A
+:10A2F000C46AFD7C12F2E1E5C2C52BA79753B022D8
+:10A30000E73D71490647F5666F7E45DFE88A57D21B
+:10A310007F5AB3F779704ABC93F5338BFB3DC41871
+:10A3200049BAE5C7CE407E3F8BD3B7B5421E63A77F
+:10A3300090EF8090ADEFC1D6D6368AAF9DE17C1C00
+:10A3400042DA81E10FB6B641DCBB8E5AC868A7D2AB
+:10A3500051E9F50928B800795018C9435E33DCC2C9
+:10A36000E242BBAD3774783E5A7810E961A459CC0B
+:10A3700002FD4FBC9F2681F7C3FB8B4502F276B8E6
+:10A3800099BD3FF1DC18B105F61CFBBBB0983DBF91
+:10A3900030DF193F87E3132341FAE0BD95EC3DA779
+:10A3A0009F60A160019D3AFD5199DB036DBF95B59A
+:10A3B000257A2B68A5C93721DED92866B3022F1963
+:10A3C0000039D32467F320E79A33584B32FA8A3F97
+:10A3D0005070C9879146D63F591DE3F278C428557D
+:10A3E00067E2E0DD1A6921A857B83D076404F1DA95
+:10A3F000902167C00EA3F2F319E077D994CFF92327
+:10A4000060F78D13549CBCFFE9E985F5EFC8C3C321
+:10A4100067059C7F455D2AB110E4DF4B4C1EDAAD29
+:10A42000A904E821FB07211DF3BC72E69ADB5CEB73
+:10A43000DFCFE5602CC5EC8FE271145F2ADD13835A
+:10A440003885DFA41E2E392BA64F02BC4265D742A9
+:10A45000C04BC5DA147ED7452786FE6B8388F5404E
+:10A4600038510AC78EC766235C72793BC651763471
+:10A47000D4CF582FB1BB9B980D2E7DBD9BD219AC6C
+:10A48000DBEEE66D7A29F822719FD90075216DC641
+:10A490006CFD9DF5ABBAFB3D2AA65F972BA6F65F38
+:10A4A0009C67086AAB45B073A6F2DBCCF985FDEB7F
+:10A4B0003F1F87F162B3AD25C057091FC9A7A83C4C
+:10A4C0008C85ACA7810F0BFDE75A35BAEE31BF750D
+:10A4D0000F844E97F8B6B6EEA47C17A38206F267F7
+:10A4E000C9816F893D749E3188115D4BC8E28178C6
+:10A4F0002FE4CFBAB8FFBAB7DBA87E5D81787FB210
+:10A50000FA753A5F49617A611697CB24E3C3F5097E
+:10A510002806B32B64BD05E9E7469DC03A95ADA674
+:10A52000DFBBE54BD17744CE5BF8FE12F67ED84C0C
+:10A530007ADE27719227AE7A10AA4F220AC8B18E0E
+:10A5400091511852D28AED3E8DE5C5E2C67156AFE3
+:10A5500091AB5A43E97387E2B5FFF680DD379FE59B
+:10A560002FC0EE837A1FB8EEEA8EE3F5CDC29DF9D7
+:10A570003B63937EC61E259D073EB31372E6711D95
+:10A58000E54595275E132F54CAAE38D148EB27987E
+:10A590005D174F55BFEEBA7FF8EE4D1D70BF4F6F80
+:10A5A000D55B687FFBD2F54BD9DC8C1D60AF45F4E1
+:10A5B0007AB4D76EE5F01E12ECC0021877968CF9CB
+:10A5C000A7FEEEB1CAD7D14EDD1E7D7F0CF5E81295
+:10A5D000F8BE576078B5A93FF3389DF71BED6BCEF9
+:10A5E000DC49F1534E52D9F550CFA410C4B37D0BC2
+:10A5F000390ECF0F098C9FEC95E4D8E32EBB41694F
+:10A6000027EBC16E50B4F89DEC7AC55D84CA91D534
+:10A610000AABB7519ACD8FC17D29BACE9CA97E9144
+:10A62000CABE036E3DB84B60F4765BFFD75BED1995
+:10A63000F8AAF8BB3D81B138D0B1FAF0E3ADAB5721
+:10A64000C273FD80DB4F97634651DB2C392EB1BFBF
+:10A65000DE9A77C1BB87D34B57211175DB3D5F5322
+:10A66000440F9DF4772797B8FDE07EC1C92BDBFE30
+:10A670003ACCF32CC0F5BAF0CA8533402F52E48AA5
+:10A68000A5A00F3EA1307BB3A5529543F4FEA19B3C
+:10A6900009EA2BA0C73AB48F7CA8A7A4D800AB6363
+:10A6A000D0989D4BE5F727148F7FC5EC5C5FD35A9C
+:10A6B0005C2FE09CB9140FCAD91DCCCF6B52CFC10F
+:10A6C000F7BE1885D335EF370BF366F4637ABB29F1
+:10A6D0009EDD7511D43C692E83F978F13FB4D2A97F
+:10A6E0008F3404827C66E816D0D17A4667438B0C9F
+:10A6F000C107FC3BCB84881489DBBDC20AFADE7635
+:10A70000A592C5B7D6E7041FFDFE30AF1B100F188A
+:10A71000BAAF09EC64F309773C67E89E1CF63F4743
+:10A720001FF4CA8BD505F09D27F273C5F338A9B77E
+:10A73000EC56E87AED98BF1FE3AC137A23CDF5060B
+:10A740009D17E0EDE07AF1983BFEB53F7D797A63A5
+:10A750008F3C12007D70C078E866E4C755A2399F2F
+:10A76000AE9F9A60EDA1E68625B0EE13723EDC7ACC
+:10A77000CCBD8ED166DA9F8B4EF75FA67ED923E7DC
+:10A7800002A05F0E19CFBCB0A06972FC4168971E91
+:10A79000FF6905FD2AF233B0337D5C7EEE98BF0978
+:10A7A000EBEC8AE171BEDB20A7AFF5B9E8DF173724
+:10A7B0001DFF14E9586E73EC570BED6D6DD20EC989
+:10A7C000DFDFE4B143EE83F1E55504F34A8E1F77F2
+:10A7D00029BAECA7FAC64D978A9CC2FCAC2F46EF6B
+:10A7E000BBE0BD347D7BF9B697F3ED04BDFF20904F
+:10A7F000CEBADAFFCAF9F55FB97E03990AF508B255
+:10A8000046FB718DAB4CC4755349775CF74DB5E58C
+:10A8100087B0DE7BC068073D1827D922BDF5A39914
+:10A82000F55663F455173C737D5E7DE5E8A901AEEE
+:10A83000A78AE71BE2799981AA4D59B0AF0EAF5CA8
+:10A84000807A65A0FA13B951B0976F5E8072C9E93A
+:10A85000B78B307D41790BF9A44F7DADF2756A97C6
+:10A86000C8817FAF84B8BFA3670ECDFA08D6771D25
+:10A8700052722F6F02BAABF0A11E1AA8FA0CFA435B
+:10A88000CA2611F5CF9B854F8F813E3BA03798306C
+:10A89000CE61217312EA14ED5922BE4FEDDA9B818D
+:10A8A0006E4327E761BDFA6185EBABBB08E7D314C4
+:10A8B000C637AAAC3801FA39A4A46C90A7F6DFAB6E
+:10A8C000E471C84F5A0BEE427DB491E99F98AF0CEA
+:10A8D000E7B1EFE68F94D443732118E28E2314E995
+:10A8E0009543016F5EBAF8F95C9FC8EBE72E4FDF26
+:10A8F000EC51585D8B238F0E534349B81AE69BEEFB
+:10A90000483532F9BFC645371FE5EBE17CB7FF6E2E
+:10A9100066CF9D90D257FA28BDC81DE93CA06AB405
+:10A92000B103E32313FD87D97B6FAAA9AB7D6877B9
+:10A93000A5929EE7F30FE27350FB50071DBBADDD00
+:10A94000EAA7F8EFE7F68CD5C1F05FC6EB9D1D3D99
+:10A9500043F9768FE2C29B139F9A6A8F8F78F255E4
+:10A96000976B87175FA30249015FA989C754777D59
+:10A97000CB877C8C2F5FD0AC0FC13C8BE5D6E5DA62
+:10A98000E9D38D3B681CF78C7BC7E4B877941A77C2
+:10A990004A7E1AF271E590C7CB577D0CF2D3311184
+:10A9A000E9BCB779CDED77D1F62F63B209712849AB
+:10A9B0004D931FC5B0DC363302718791F5E4EF513A
+:10A9C0005F6968571E524C2227405E8B987FAE9875
+:10A9D000C8D399642D5DDF059CAE897B7F01D44F80
+:10A9E00042BEAE1CFC2EB6AE018364210EA6E66FFD
+:10A9F0006F51E8F86A8C98F41EFDB3D10EA4DDE81F
+:10AA00005F4CB03837B4D506C2F657C896C0D69951
+:10AA1000C5A72BF87325A63F2A025C6ABA07FA235A
+:10AA2000352CAF58C99FFB6BD87388A3635CBD8A74
+:10AA3000C5D595188FAB57B138BABF86C7D5799BA6
+:10AA400010B6EF6158089A40874355DEF8FA5082F5
+:10AA5000C7A9DF7A34BED6C53743BFF9721C90B898
+:10AA6000A8F6A65EB00B9D7CC690928DEB25E441C6
+:10AA7000713E63CA739174E238722E0EFC194B65F5
+:10AA800031AE4F7166405CAD188FFD8B0626F0B875
+:10AA9000F03DC4636F111E7B8BF0E8B427F45C9526
+:10AAA000E9C15FEF04FE9679F0D71B7E02E5432FE4
+:10AAB000C7E3491FC5E3B540BFA63AD33E178DD3C0
+:10AAC000F9445BCD9F3440AE9F9620823099773613
+:10AAD00059BD1CA1EE9B7BDC18A7EB8540D714EE7B
+:10AAE000CAB5DEBCB3C6E9F8A898FA47B04336CE7B
+:10AAF0003AFC51827977AFBF3C9B9863608792663E
+:10AB000086BF0871C5ADDE86DFFC1A97EFFBA4F4A3
+:10AB100019E0EF506AC40239EBD76C1B4C8158CA5C
+:10AB20006EF9E718C6E7C625747659BC0E536E3821
+:10AB30009E4DCEABA81A4DD84752B1D66E013BB34D
+:10AB4000868A5B78BFB2634C28552F3DCCF5C1B0E7
+:10AB500092E2FA80D385CEE2E3DB42DF38B301F242
+:10AB600008E56568CF9DF339FBD0A80B067E03B7D7
+:10AB7000BFA89C3EE773D9979A3E6E09205F785C28
+:10AB8000EE485BFA97F0FCD072B303EAAEE95FC619
+:10AB90001FA7E336991F9E68D7D176E3D292FBD0E8
+:10ABA00036B459BFF6A1FF49F53EE8E17302AEE7BE
+:10ABB000412577B3380F3ECF05DCF2FFD0E6CBB5A9
+:10ABC000A7732AC8ED61E3D993F51E7B9AB54BD8DC
+:10ABD000B321BF4B2F15CBE343976F4FF3F19FF199
+:10ABE0008C3FC8DB25C69FE3AF70E9C14611FD1F4E
+:10ABF0008A07AC7F2E8667B8F1BDD1878BFDCC5E0E
+:10AC0000A07A6931E063CAB8808719FCF277AA0F8D
+:10AC1000574D8EBB0AC6251A8B274EE74738572754
+:10AC2000AE08BA10E832DA96BA11BEFF4513B1A5E4
+:10AC300028C567D38005710A95EFC3240DB6CAF6FF
+:10AC400083D88857926471F641E3BD89F30D5E267F
+:10AC5000BE9C7EA7CE33EBB1379DFEFB801FC10E9D
+:10AC6000DECBFCE57D1C0F352427825DF6098ED7EF
+:10AC7000567FAAD38F7C3E8676DE63C6891DF32875
+:10AC80005E828B9E0DC2BC9D7D52441E236EFBF1E5
+:10AC90009E89EFAD4FC1F70D89137BF97765F01DE4
+:10ACA00095A39FF6CF2047FB042A47591CE81DC9EE
+:10ACB000D11E3EFE7FF8D23D308EBA779BBAD0804F
+:10ACC0007D78D9B12B0417DC6D4B71DE0D7B4FCC39
+:10ACD000BA09745982C7BDE4DCA90F42BC3DD980D2
+:10ACE00079D2497CF6F07EAD21A4B7B6D279FE6266
+:10ACF0003AB35B39BECBC42CC4C402291BE57A65C8
+:10AD000007CB7F51BD89F9FF093B85E7FF417FBB39
+:10AD1000F3FF1376CABBCEFF7BF3FD3ED566F5008D
+:10AD200006CBF70FFDE6D32CFF5FCBDAC5F3FA2B8A
+:10AD30003F93FFEBFDD6DFC2FA7E52B29EF2BBE438
+:10AD40007EDF7F499DA5F62F3FCBD7A5CFC7F58CDA
+:10AD5000CCE27F72D902D433026175FFCEFB503F43
+:10AD600000FD3AF50493FB4CBD7ACFFA098BAFC6D0
+:10AD70003B991E9A93CAB730FC3AFA8EEFD724AFAC
+:10AD800011C84FCD5EC7F5DB843DBA4380F88F4ACA
+:10AD9000ED9E00763F8D3D1A73ECA80CB3A3620CB8
+:10ADA0007F7183ADAF6327F9D49116E88FFADBA8E2
+:10ADB0009FAAF8F7BE387BAEB06FC930AC7382ADD6
+:10ADC0002BACF330AC2B7C1F67EBECB409B7471FFF
+:10ADD000E4F6E87045CEB3DEC3604F013EDFFA72A1
+:10ADE0007CAD4BFF0DFF665915C42917D58EA33DC9
+:10ADF0003ABC98D9A3C34AEE5DDAA326FA8BB3D73F
+:10AE0000E5CEF8191EB93DEAC563FFE2018C0F4E8D
+:10AE1000B1477FCB7874F8C5C1A3C31F0E1E2FC5E1
+:10AE20002FD3DAF38BBE8AFEF210E091DAA3D52A93
+:10AE3000C56335D8A3D9CBB54707EB291CE5DC1E84
+:10AE40002D1F59322ACF608FCEE6F6E802EE675505
+:10AE5000A5BD75C08E3D4AEDC45A95F25368DD0814
+:10AE6000D659F8291F43DE7F594DDA5041EEAE33F3
+:10AE700005B8EFD3D8FDBB6FB6122AC6DFD8BEE344
+:10AE800087FFE409E4A7F264CE2650DF276731EF9D
+:10AE90005EDE9E251B5CFCFB23A33509FD95CBA63E
+:10AEA0000074536E948E7BD6ABCC7EA572E12A18CB
+:10AEB000E749C3BA5A45FD9115FE00EC509B8C43FF
+:10AEC0007D2B29CA3353BF06F333B516B515E9F305
+:10AED000BAB5E33D108F32D6E922C03F8F18ADBE20
+:10AEE000848B8F799E79DE4EB6FE8FAC24D9CDF45B
+:10AEF000F9FC87C6AB5468DFFF92D64EDB573EC5E0
+:10AF00009E7F71397BDE98CB56C3F32F7E813D77D0
+:10AF1000E07EE40BBFAA3234F86EFCE58F81DDF5EC
+:10AF200005A6771EE9498BCB281E16E4BF20CEA3C9
+:10AF3000F8F9B0CAEA8E16E472A211E6C0AF8075C5
+:10AF4000227CBF615E04BC5E01FF49E9A477707199
+:10AF50001FEC037B64F4E3F8FE23BCFE84D8793154
+:10AF600044F151B7D5C038FD15B9424F90B61BBB5F
+:10AF70008C32E09BBAADE38208FD3C9515A13E758D
+:10AF8000EE93397103DAE5594FFFC46E599DA7F767
+:10AF90001339F23CEC719CFB50611478ECCA9DECC7
+:10AFA0007C04A38B5D135BD9B5539510FE3BF93A36
+:10AFB00039EDF9B96C2BD8DF754DC44C1850C76208
+:10AFC0003E0FF0CCDF4A74480BCEDD6A8AC00742E0
+:10AFD0002EF77C10DEDB4A4CC825FF298513F2A32F
+:10AFE000C2938551D03757E458DD88F0544E2C6811
+:10AFF00053F1F076E1BC5F65FB5BBA389C4E7B7E1B
+:10B000002EBD0DE16C2E82F34906E7154F7AE19CC7
+:10B01000DBC5E1ECCA223CC2FEF11EB8BFA008CEDF
+:10B0200005D39CB791511D3F87E9712565A37C2A03
+:10B03000B7585D0EBDB278A549B2F369FB3B84AE4B
+:10B040001A6D87ADCC17414E97379902F079797B0D
+:10B0500026087A4A85121E7CCEBED79BF236D413C0
+:10B06000400FCB4DD7F74DECFB967613F15BAE92CC
+:10B07000169877C24248488B6558E06752D986F9DE
+:10B080009BF0D99B4EC23E5FAD49FE95BB4EA29C44
+:10B09000B0766D9AD94D0968BBF2B80FB8DB58206D
+:10B0A000E6FA9ED965F81CCC45B0CB14EEC71179F1
+:10B0B000D9736B56F0BCA904D76C16F22379ED4B0B
+:10B0C000A771DF3679323B915FC4E7639685FED97D
+:10B0D00048B5E7FEAA318CCFC37EE51B9AA7C25FB5
+:10B0E0003CBE1CCBA37D7010EACF41C14B2F629CAC
+:10B0F00055EF4C45F3A4841C26F279E80FBF17A640
+:10B10000EE4338A16A9EFDCFE1AEBFCA62FD3A3F71
+:10B1100007854AD2E7D654021E09C62BC3EDACEE12
+:10B12000C819DFD98FF0BF389D567766D97A3711A5
+:10B130001DFCB4708CFB0FB1D368275E7865FBDC17
+:10B1400007E8F3DD2B9B97E1F3A6827EA706F31AAF
+:10B1500023B7A17F318074E6E88FB0B4B30796A51A
+:10B16000BCBD80766242360330FF9DED6BA2640663
+:10B17000BF23CEF5470DD71F11AB289EA11201FCAE
+:10B180004C7D441066D2438E9E71F011067C2631B0
+:10B19000DF80FD168F5B8CDF71C0AFB3CF6321F40E
+:10B1A000F760B5BB3F4D2ECD770E5E7FCCF1FA0533
+:10B1B000E8B302EA6C24E4B7A30DC12CE4D1FBC5CB
+:10B1C0004200F2CDF63FB23A907EC2E833C8E3CBFC
+:10B1D00084A47BC046903A09DAF17BBB3B308F33C5
+:10B1E000D09DAE063BE7787727B63F156071D56EE8
+:10B1F00023AD06589EC4729F9FA36B23A330E72103
+:10B2000025BB1FEA96EDF94186AF18F31F8AF32498
+:10B2100093F63FF3178AF3FACE73A9D1B2416D4486
+:10B2200083E305C8E3934D3EBE0ED432A6E3443417
+:10B2300056FFEAE4711DBAA90F303D64759AF96FA3
+:10B24000C626EB6E74CBCC3F4ADB1AEC9F62F9AE9C
+:10B250007A988FA415B06E2964B17D559166163F1A
+:10B260000FD6E46CE08D3DCA7807DBE77D70F5E929
+:10B2700038E4B709CAED4581A7516E4745D6BE6D82
+:10B28000C797FA204FBE7722DF4C50FF812D077EF3
+:10B290009C33AFCF04D8BA45791DA48327E7F9DDE5
+:10B2A000016F3E7BA2FEF6CD8B17FD2B26ED025DD6
+:10B2B000CE0B9067ABD9CCF442F4FA9F556D72E196
+:10B2C000D90A30BD10ED6679A6A3B563E857143FDF
+:10B2D000FF5060225E85785534267F95B3D720FED7
+:10B2E000088F4329AB18FED4848C6DAB339507B916
+:10B2F0005B46F106F8A5F8FC10E053B372206E3CF3
+:10B3000075B2C43977037025E708D8EB4705621F8B
+:10B31000A4EBD005C159CC87E470BCC33FD22CC884
+:10B32000278556FDDBFD9037BA5CB8281C7F12C01C
+:10B33000F527C8BF6526DF57A4B1789B33DE5EA72B
+:10B34000FEE23E1F8B0BC9FAED1B01AE7B16E0FB44
+:10B35000BF057CDC0D7014E3E3B301BE1F9A14AA91
+:10B36000C04E9EA0174E07C57443F542D59AC553EB
+:10B37000F986C8F47BB4B3F278DDDD9DC5BA1FE76A
+:10B380003D671F675741C079EE5CCEEA6C23D7FE5C
+:10B39000E449E483A5ACEEE130E7EF78F3C9DC37AC
+:10B3A0000D288BF939F21369F2995046BC5B241EC3
+:10B3B0007F753B7F7F674070EAA30FE3BA9BE4048D
+:10B3C000F823D136EA3726405FB17D0B87815F00D5
+:10B3D0005EE967E837FED222E360C7460A3F27B03E
+:10B3E000EF342E317C469BB39E3A82E9E4E6C301FA
+:10B3F000EFB91CBB45AADF84E9E5BD232F2332ED5D
+:10B40000AB0CC6DD8E7518D38DB7BB7B10F138A899
+:10B410005A8FC2FABD79EEA619F3D640263D2EBD4D
+:10B420003DDD7BEFF515E4688F027A24A4839E3E10
+:10B4300042C6883D0FF6D38EE54F837F4CF16E43B5
+:10B440005C9CDB11F2064BB8E8924BCE7713EDF61D
+:10B4500057D13FFE49E0B53E957E774060722E3D64
+:10B46000FC831B41EE1D91C7B0BEE188EA6B63F51A
+:10B47000EBB1568C5734971D6372F95B787E48DFC9
+:10B48000AC18C665FF37976B8EFEA67FAACFA5477F
+:10B4900076363F6F73FA40A3441F69211877E1FEA7
+:10B4A0002DC86FB00F3527BEAF31FEDDB194609D62
+:10B4B000B1937F6BE0790A8930BD2E6F60FAD8D1E5
+:10B4C000D7604F60BC523A6BE2FE8769CE752BD6CF
+:10B4D000E7C574F82F21977D44F5F72262451F4098
+:10B4E0003F6C641BC487E8A728DF9CF6C28D04E587
+:10B4F000DAA278A185C9352FDD2C8A8FB790C87F55
+:10B500001FFDEC858982FE5EC2E29E7FCDE9090CBB
+:10B510007338374983F5A7F41408B1755C3C38D605
+:10B5200003EB331F3EA1DF5DB533D51AA0D77959A0
+:10B5300062B6D0F5AE5599FDF26055F600BC5720C5
+:10B54000F7F8E5F7831F9AC3B66E67FC401F5F0FDD
+:10B5500006519ED4FE52E0754B055CDB23FF39D1CA
+:10B56000C63AA354738180BD1FE962CF0FDECDEAD6
+:10B57000CFC13646BFA08B1CC3FA7AFE5E5D90E950
+:10B5800035236820BC0F2ECFB7C27775CDB96D704B
+:10B590000DB7FF43AB01FD91DC3613FC9C9C8EFE86
+:10B5A00057E4A1310C2738FE57A2895D173433FBCD
+:10B5B0003619647EE11541915FD9BEB2C6A0EEECAA
+:10B5C000A7443BF45AD5BA32B81CE3D901A0B379E9
+:10B5D00084E187EC67FEF382C3518F7DB794F7F760
+:10B5E000B920B35FAE55534DF0FD95D46FFE7F1477
+:10B5F000EF912D05E60F51BF0DF21EC5EBD7166476
+:10B6000075F6912D0C5EC0CF31DAFF7E99E1677F30
+:10B61000977ECC66F1B23EF047E53603F763B70597
+:10B62000993CD72DCB82FBF453BB1CED202B0FFB99
+:10B630002E42AFB37D1772E7F9FB813EA9BC6F0BB9
+:10B64000429DC3E65F75031D3B7542FBDB7D24EF26
+:10B650005A3F677DEA9B0B36C41522CD8620B8E0A1
+:10B660008E3C4BE513852F5C3366B1739158DD64D6
+:10B67000C2AE477BF4F88ECA56889F6545635B3936
+:10B6800045EDC7399CB5B2FE3CC0554BE1EAA1F788
+:10B69000EBB6E8DB36215EA204CE1F58FCACFE3CC4
+:10B6A000E4BF8C8B5102769E33DE27397E1DB82293
+:10B6B000EDE7717E25E01240BED5025C143E6BAB17
+:10B6C000DE0AF097AD62FB82EABA8808ED9069A0C5
+:10B6D000FEFC1C872BA3591F87F5DACAE9A0AE8BA5
+:10B6E000C557EBA6D97F7B747A7866110F3C590158
+:10B6F000F054CDF1742978B6061DBD6C7D2E88F40A
+:10B700003826B0FCCCEF879E7A04E48A2B3F33F7CF
+:10B71000D98205F125E3B931DB403F8AC90DB1F08B
+:10B720007F91DECBBBF425EEFD5007395F47B8BFF4
+:10B7300059DCFF63C1897D9EC761FE96CDE8BF6C71
+:10B7400015B3E3421057A078EAE47261129FDC4E11
+:10B75000ECCAE371365F9AE06766A709ABFE03F5B2
+:10B76000465D33E32FA215AA6E73D9655F0A4A9E20
+:10B770007D7F75C0DFF09ECAED346AAF7DC4E53FC2
+:10B780001EBDEF25CC3F5753F905F652A4EBAB286D
+:10B79000E722D416D2AEC6734E04904B73BAD83C8F
+:10B7A000176F25429F8B8ECE717ED7395D54CBE3C8
+:10B7B000A3C02F739E3596DA2EFAF94550F4D89B24
+:10B7C00047B9BD1937BB44C06F1D31B6313D951126
+:10B7D000411ED76E345AD1FE0E31BA0E835D503EF3
+:10B7E000595F1EEF3CD30670D76DAEC7FA6FF853A2
+:10B7F00056E0BA61BEE1D0E65336C8116A2A9820F5
+:10B8000047C23CCE22884C8F12D3155771D91FCE18
+:10B810003813ED4E36EF5A794C70EF0776E0AA55A3
+:10B820007D2C7E404E109887AC313AB9F0CAF72D86
+:10B83000B7DDF16D3E7FEBA1428FDFE50F50FA08D7
+:10B84000852A26CFA775E4582D9FE7E2ADB6B0ADA7
+:10B85000D18D476E2773B940CD10C4B7AC3179B5DF
+:10B86000F859CB86712581C92BE77DABCFB241DF7B
+:10B870009571FD5FBBC5C27D2D1A45A8C4FC845FD0
+:10B8800004110E763FB495DD77E099B3B980F71FC8
+:10B89000EC91AC76940F850336ACE37DE7F1FE4185
+:10B8A000EA4795833FDC6C1E00B9B7FBCF7CA49DB3
+:10B8B0004CE58B232B5FC238EE11BEFE67FECC67D2
+:10B8C00031BD99F922E8CD7853A1E7C7F4BE1262E1
+:10B8D000FAB82EFF5301E2B24778DD5D1DA5C7D946
+:10B8E000F4AA517F53837D2A5D239F8673DE34B093
+:10B8F00067A00DF60B6DFF5D90FB3713FE49E1F776
+:10B900004AFE1C2C923F8BA99F08F2D5E12398E7B1
+:10B910002CD7BA27B9BD5367F94AC66334C71EEAA4
+:10B92000B4516F38F4616D196985F86BD92A4A975B
+:10B93000943E161EB6C520CA691DE972494874F4C2
+:10B940008619427CB17D5993FC660BBD4CDFA33D4B
+:10B95000B64BB67B06800EBAC871AEC73D7C57DDCC
+:10B9600039867C570F7CA74FE5BB60A3377E584BC9
+:10B97000CCE7A1646E0ADFB58B28DF8AF9EEC30E2F
+:10B98000DF3509BC9E565E1D689ADC275ACC77D7F6
+:10B990003B78EB9AA853FC70C8251F1DFA3E20E89F
+:10B9A00002E6150482F574A3852F633DD2E1388B3E
+:10B9B00043079379DC27E63F29A1AF30DDBA96AD86
+:10B9C000EEF0D41BFF5D2881F0061BD39EFBF3062F
+:10B9D0003BABE5127E9FE3FF50BCF76C73E13D9EED
+:10B9E0007EF3229C5F53B7C5E075D42751FE859B3B
+:10B9F0004532E45A0727D451B785F95B35D4DF12B5
+:10BA0000319F9327B02E47E8BA809C2D8EE3168F86
+:10BA10003FD16E1651FE819FE55E876D21A6DF8FB7
+:10BA200034096DB00ED608FD07F285D7236926DBF1
+:10BA3000F728CFAAC475F854C8D9AF4B9A04577DDC
+:10BA4000335D8F6D215C1FAF5F15D2C631267C4000
+:10BA5000617262A87BBF27AEB087D3AD9CCC5AF091
+:10BA6000D15EC1C4732341267DA5C4FA3CCCE9E66E
+:10BA7000E190C1BE1B34D00E97769ADB709F9E9EDC
+:10BA8000B50C8C9BE5F0DC56DA8FFE1563FA7EEA86
+:10BA90007503EDF6799AB90DED054EBF8E9DB30B8A
+:10BAA000EAFEB5A9FC11CE907CE0AAA97C114A96C9
+:10BAB0005E8F297CB1B1345F3CC3D7E3EDF2C53171
+:10BAC0008EBF50326FFB991E7A26B47C2A5F8C168B
+:10BAD0001EC57D87070BF3663CB7A998EEFDF1B74D
+:10BAE00047EF128F374FB4A78937BF32111FFCFDC4
+:10BAF00090DFBDDC2FA5787B25C0E2967D90D776C0
+:10BB0000EAEC248DC99BCB8DA7FF90C7277A218EA5
+:10BB1000E63D7F94EF2B281D2F9A80CBC9FFF33889
+:10BB20005EDFE8CDA4BEE4BE501EBF8BF1FDC8941D
+:10BB3000585F2B610F4DBE6F23FE7BBB73C887CE52
+:10BB40007ECF7ED8EF9980F3B09FC4FB7BBB9F6311
+:10BB5000FBFDEACC34EC8777F67FEEECCEE37DBAE2
+:10BB60007C4988877E56BA16CF2BEF154DC3D9175F
+:10BB70000AF5E1CE3ED0E9F07E879660FBC98AF6F1
+:10BB8000833AFB40618073BF07F4A1C4B32D70B446
+:10BB9000515532359626701E38B5955DEBD96DA49A
+:10BBA0000DCDA5879418DBD7F1FB023FACC339BAA2
+:10BBB0009EFBB8DFBE4F2359D0F73E839FEB5F93C8
+:10BBC000C983DDE78BEBCF082E3AF4C5D24474D19C
+:10BBD000B7CFCC5B205FF71213E58F4DBF01B9BA29
+:10BBE00077F51A4FFDC26A8DC955255EDA9FBA51A5
+:10BBF00063FE141D0FE318B378BDE1AC1B9B3CFD45
+:10BC0000DCC2FB91A6E9E70F2803F27E66413FFB09
+:10BC100074760EC7543A6B403A2B5BFDDC643E945D
+:10BC2000C03ED3BC87FFFA267E07C062CA5767F1C1
+:10BC30003A8A27A1D4B9A9766B06CFC7B4B7C9048D
+:10BC4000ECAA87430FE0F9995DB65F073B9EC4D825
+:10BC5000F99AFB6455073BFDB392712B1E6AC27FB4
+:10BC6000D7E282386E8362D448CE42AEBC447F179E
+:10BC7000027559B08B9DDFB1707EBF625F9CF60B81
+:10BC8000E7E7AB79D44B829CF39C0F96902D3CAFA9
+:10BC90004F556D15F85882BA18FA9E34B204F52340
+:10BCA00099381F8C201DA8BA857220484CF44FA3E8
+:10BCB0006DA2A71E26647AEB6364CD6679BFD3526A
+:10BCC000168E6477CE0D83B2131857D6A89E44B84B
+:10BCD000D9B9F74E7E795FDBBD24C7BF2B752EAB7C
+:10BCE0007395093B3F1FF6B0837EF593997F87A13B
+:10BCF000789CF8DA54B4D4F926D3BD4F05BB71DE75
+:10BD000095979FFE3BEFF90A4781662A609DFEA04A
+:10BD100012E49941ED4F386FF152E7AA1E15D34F47
+:10BD200082FCF8A992B986E551D9BA52F3E903F831
+:10BD3000FB1E24620EE195D56562DDA60061D491FB
+:10BD4000BC9580FD09DEF31A4250874AFBF914F7CF
+:10BD50003B4349EFF3E2FACDAF69CCDE58450AB870
+:10BD60005E1155CBE379E1CDDE73379D79DF1BF7AB
+:10BD7000D65B155F45A21A1AC478793E5CE06D6700
+:10BD8000FC3746048CEFDF4B39AC6BA9BB5F9EFFE1
+:10BD90002EE2B368228BE797911691805E1952C903
+:10BDA0000B207FF65A9B0C9063706687BB2EF4378E
+:10BDB000DA3C760EA4E513A1CE7ED7C91B67033FFC
+:10BDC0008F28FACDB89F62B9A81F2F416FFFAE31FF
+:10BDD000BB24D815321F5B36FDFC823E56CFBAAB72
+:10BDE000E98D14F417B92E360BE87768B4EA053CF0
+:10BDF000AFC2AA4C402A2B10E6767293571FEFE58C
+:10BE000072786F92C9E1605704C7BB147CDFE7F218
+:10BE100030D815301F9B01FFBF6DF81C3C9EE772A8
+:10BE20002BD8A5E1F80E5E212206E7E128FC5C7420
+:10BE300068C379A792A5625B295C93C7F34FE97346
+:10BE40007F33DA59FE30C4315EB708C89BE27CEA22
+:10BE5000298D9FEFAAEACCEED663AC6E3C2D633DF4
+:10BE60007524CDEAAA27F9D066EF275F4D813CDB28
+:10BE7000D5C8F6408492CCDF0973FA882AD993306A
+:10BE8000FF68CB827A98D7EA30A3FB1125A7429EA0
+:10BE900076A8276A1C47389F1D5C47870C8ECDC744
+:10BEA000FDD9CEB85698E39F68581FEBE0E1A0603B
+:10BEB0003CBC0EE4760BDBE7B8F0E4FAE7E10CA754
+:10BEC000F9634B5A6BE9F71FE4DFCD2A2C1985F68D
+:10BED000FC303F8F73195906F47DEFE1CCB7E05C7D
+:10BEE000907B5BB6DD04D74FEFB76E8294F2A33B35
+:10BEF000D778F24853F72F10DC8FBCCB1203706E4B
+:10BF000080B37F8134355DA24E9ADB8B53D62D45AD
+:10BF1000A05E46E2F50D72F31ACCA7EAF572264A46
+:10BF2000D7CD3A6B1218A7CC79BF89AD8BA3CF269A
+:10BF3000F69FF0F817218FA13CA90D73BA99C01B89
+:10BF4000A377F2CD9FDAB0CF2244E90452D8A4D12E
+:10BF50004B87B561162F75D69B0E68BF0A725A5073
+:10BF6000502E38F89C6E9EEFF47AA49BD8AF523CCA
+:10BF70001FE3D7DD705530CE8CD7217EDF79FF4FA0
+:10BF8000C33C7FCCD793328FFD2AE8ABB94C7E39C6
+:10BF9000EB5BB785DD77E4A0B3DEF57DDEFBD1E6B4
+:10BFA00018CED3691B5BBDCF4349EF73875E1CFA84
+:10BFB00070E8E6DDD2471338BA2E3F32CFED0129C3
+:10BFC000CEEAC3A5F820E6BD1DF97BAE3A65873100
+:10BFD000EE98C6BAC0D1AA05D1828B7F8BC719E86B
+:10BFE000CE2D71EFF376F64FF86492579682DF9973
+:10BFF000F39C673075FFA9953C46DB3B6295283F73
+:10C00000FCDAFF389327B03FC9F8A3FA19EC89DFAF
+:10C01000C23EA4C36197BDFF6EF7A3BE837D484FA8
+:10C02000C1F87DBC1EA3787C4B6FC4BC777586E5D8
+:10C0300073BEC1E55C2D29F4282CBE9E525DF5C06F
+:10C0400073D78D55FDBD01E72ABE94C07301481F0B
+:10C050009E2F45B543D3C519F460B1FDE3ECF368F9
+:10C06000496FDC0FE79455671A97F2BA17361E8CA2
+:10C070004DDB635C1ED692FCAFC1A6AB23E3F83B5D
+:10C080004D464A6F85F4707D87F93C5C293C8BDE18
+:10C09000CD7957D3EDD372DE7FAFF6679DE3F87E9F
+:10C0A00041B3CE8597FFEEF6678D4F8E3B5E6ADC1F
+:10C0B00062BB6AEF6D11B6DF94FAFD50DFF7F06DE9
+:10C0C0000FA03F103C1B30207E6FB75A02EC4FB5DB
+:10C0D000AB89D94BD7AD2B99B2A04EFCAC98FE2FB3
+:10C0E000E8BFE5072FC781BF772DCACC05BF700217
+:10C0F000DF9AF7BCA6DEA2F39A7AB5F7661F57EF70
+:10C100006FEFBCA6EAC8F2A9FD17EF9B92C20FB170
+:10C11000F3072FF3BCA658B9B5047FF785FCE34DB0
+:10C120002FBACE695A1C19BC49837399A088BA9A50
+:10C130009025BB5FDC0EF1FFD81CEB6978FFD5C8FA
+:10C14000FFB92906E738CD63CF57EE61CF25356BB0
+:10C150004190FEE1A8C1F46CDA87E7C10493ECF7E3
+:10C1600044489C14204EEB9CFFD16DA457442A26D2
+:10C17000CFA1F0C559BC62E2DC246AF7F967909F51
+:10C18000C7785D25FCFE0D5C8FF2F32886F9B9496E
+:10C19000C13E15CF81DCD56D601D26FC0E0E5C0FF7
+:10C1A0007777E0F569297523E0379864E744EEE78F
+:10C1B000E75F04B8DD7A8AC7895F8A30393179E56B
+:10C1C00071622E67765F7B47D41D2FF8C388E0D15C
+:10C1D0005703DDE6FB4EB8E2CCBE8DEC7790FC71E8
+:10C1E0007ADFC51755FCDC8C03F767C91A881FE78F
+:10C1F000BF8071B6BBF9B87BBA33D7413CACFFAE58
+:10C20000CF5B1097DADBDD751DC4BF02F2B80D718C
+:10C210006AEA382D01FF39A0921EA47F8BB609FC73
+:10C220005E8ACEDAABF973DDE8C1F7DB587BA0DBC1
+:10C23000BECE1D07D757D1715C70F99269B2BE119D
+:10C24000E2165D9EFBFEB8ED69275E7CB20DEAE466
+:10C25000B693B00E7EE250CDBE97213FF0460395D7
+:10C26000B6E01FE60FBC1C05BB5FF31901DAEEBD9B
+:10C27000DF7BEEC50EBA8EEEDF990A378CD90077D8
+:10C2800020995E06E4EBE89920FCBE976BDCC8FBC6
+:10C2900034762E759CD501F6727C39789E90CBF160
+:10C2A00091EB64975D27931CCA7BB9F1EB3D90A796
+:10C2B000A1F625D02839265878AE9D73DE87BCF1CB
+:10C2C0006B985F5DB3000E26A2F4FAF1D5F96FD139
+:10C2D00076F6C500E63313036D79D8276DDC16C4F6
+:10C2E000BA8CAA3A277E63AAE09744DED79E87BC21
+:10C2F0004BF625F6FC8B1196BFA9DAD4963F4EBFBC
+:10C300003B743B3BF771D12A13F7AF0F6C6EF0FC17
+:10C310008E666FBC7EC6BA6FD490AEF81E9E8CEE51
+:10C32000E1FBB2A27675D1FBF545CFAF287ABED43A
+:10C33000D31EBD8BDA538D989FE5E7BB3E46A08E9A
+:10C34000F3C05D4FC4810FBE1261F15443CF79CE6B
+:10C35000AB99A33EE769DF174E7D85F11FDBDF1741
+:10C360009247D0E80FF5EDC7DF8B53E932829F1675
+:10C37000DAF879DCA7083F1F04F594A1C6116C8791
+:10C3800055964F0EC44C0BE251819865419E361074
+:10C390004BF1761AAFF795A5BF09E3041AD8797E59
+:10C3A0004A8CF905878B7E0FC4B99EE6FCEB9C3B5B
+:10C3B000E3DC57F8EF0E250606B19EBF6F56E70A7D
+:10C3C000B0870EDCF51184A7AF6CF30A40D7E908FB
+:10C3D000AB97B0E0879A62E857A2DEA1FEE6E908D3
+:10C3E000FA3BEC7C59271FE29CDB396F8E7506E423
+:10C3F000E1F7224E9E999D871BA6FE10D0A9B2D1CF
+:10C4000087E7175D3F37FD0AF4A3C4B2AC9E3BC972
+:10C41000FAF9F81CEB07D8BFFC18DAC71372586397
+:10C4200072585259DD39A571DB7D0E1395C33F86D5
+:10C4300071831DACDEBD3A497A406DBE5D393CCC9E
+:10C44000E56F7F519DBB737D5A4AFF02FB6F549984
+:10C45000DF35216F47D2B0BF2EB4A7FF267925C89C
+:10C46000DB9401EDB776F76F5F8D3F9490C579044B
+:10C470001B191F076303634C9F307AB92F6CBD05EE
+:10C48000F31D5DEC63706A3E84D3397FA8188E3E3D
+:10C49000B0F35DF069A295473FBB551581CF9DFB79
+:10C4A000B25979A701797FC09F3B9EAE7BFD0067A3
+:10C4B0007D1CFF723A7C8F76886F0B8F01EBE9252C
+:10C4C000F20CF1148AC79A28E0B141F3E291D73D0A
+:10C4D00038FACA79BF29CAE22ACE95CAE741C523EC
+:10C4E0009F3714C9E78F17C9E731FC3D477B3EC929
+:10C4F000819EC8F3F5E80339ED077A61EB12D0D9D4
+:10C50000BE6239969E07E7E99EAB4E2F8D32BE463E
+:10C51000FF4B71FF4E22FDB73CEAD48933BA7FBB93
+:10C5200078A4749B265EFBE1FDD112745BACC71D41
+:10C530007CEC8932BE76AEB07FA330835C057DE4AF
+:10C54000F60B030DB630D33983A31BAE403FD3198E
+:10C550007F2AFD3DE7F1339DEBFA68C24B67BE349D
+:10C56000B9957EBF3F50BA9F7494D91F8A2FCB7E56
+:10C5700077919F2B1788EBC7DCE7D86DE0F3840336
+:10C5800069591C7704AF718E17AAD3CAF4E8E4FB8B
+:10C5900019FE7E3CE8C59B73FD94336ED03B6EB0B4
+:10C5A00046F79C67774F54E0EB9B216C5D19DD04E7
+:10C5B000E28C6FFDF10CBB26B316D2EFFA81C400FA
+:10C5C000CAD324D6F9D1793179BAED4A11F4663754
+:10C5D00087CBFA19F1C853D739DDDD406F72D2FE2F
+:10C5E000B9FB7C37671D14B296DCE39A4F3FEFCF5F
+:10C5F000C1AF02A65CD9245EE8679EF787F97C1C70
+:10C60000BCD0F7578B54258E70F9E0D0B1A27BF5E2
+:10C61000DBDBA5EB87A32CBE44DB96558F57EAC026
+:10C6200050FE0C5BFBA3B87E368E3390DA9CBA8B3F
+:10C6300076619DB66C888795A535E7BC3B1BE2F813
+:10C64000D4A5CA1C647557C7101FCE798D7147CF0A
+:10C65000D89E73757B799EB5A22E75CE70E555DF99
+:10C66000837375BF0C7C3AEDB9BA19C72F667EDAB1
+:10C6700061F0D312937EDAE1CC7BE3A71D7E87E7DE
+:10C680006D94F0D3BE1D7D1B7E5A403B51B5895C35
+:10C69000BE9F066802FA8A5D6DFD9CFDCEA6D68619
+:10C6A000FEDA42EB6968F76EF7B7C179D6B165D6A5
+:10C6B0003D605FD6E991B6B66BA79FD7049F9659A8
+:10C6C000AFC3BA4CF1979D732AC3DE732A2FD75F8D
+:10C6D000DE235B184FEA335663BE6F329EC5DA2500
+:10C6E000E249BF72E3B1386E70B97EB533FEFF0721
+:10C6F0006350C6C7008000001F8B080000000000C8
+:10C70000000BCD7D0D7854D599F099DF4C2633C9B7
+:10C710009DC9249949267033804C30E0240C103593
+:10C72000E84D0892406C478A3576D9DDE1C78AFB2F
+:10C73000D167A3628BBBD8B90921094990801182C6
+:10C74000603BFC8A6EED0EAC9FB55DBB9DE04F6318
+:10C750006BBF6F64ADABAEDD461679F6D9F5B15956
+:10C760003F6B691F5CBEF77DCFB9C9DC9B04B1EE9E
+:10C770003E8F791E9EC37BCFB9E7BCE73DEFFF3903
+:10C78000F74CA7DCE0A8F031A6D699237364C67AEB
+:10C7900004DC5B3BBBDA02F065FCBB99B17C7783C0
+:10C7A0005D2A62F8A7B062C6EC8CFF1DBAF7EB8E6B
+:10C7B00078156305B52C32DBC19F5D6613EFADB70D
+:10C7C000C6E7E27B1A6CF74758DCC55891049DC355
+:10C7D000738B2BA5DA2A182B599BA4E78A2BDE6EC4
+:10C7E0008BC2F32A16E96513CFF7CC548AB19FF3B5
+:10C7F0000512BD77283012C071B57ED469DEBBD575
+:10C80000A39C2FA0F7E0E122C66C803E9BC598EF69
+:10C810002B2DCA0E68BF83B1364B04C66D857A983E
+:10C82000B7B78A257B011FAB94A6F7DB5C717A5FF3
+:10C83000C3DFE61BA3E75BE11533B4676DE6E4F104
+:10C840000A9C753AF736F744BB436DA112C44F8377
+:10C850008DE5C309A0D79CE9EB0B4C2C9682711C8B
+:10C8600015C71CEB5D13CF6B2513CDF71597528BB6
+:10C87000F430D2FD50935C22B93EFFB83DF211DD99
+:10C88000B82B70DC4534EE0A69D1E471190B4A17F4
+:10C89000F2046C614C4AAB67907FAE7B9ED36B6FAA
+:10C8A0001DAB355D0765D33907C28C25A9BFBD49CE
+:10C8B000666605F8FC4309E9E56D4AB1A9E876C466
+:10C8C000936C8DC17BB3AA223F33C3BA3173F85442
+:10C8D000DE0C28ADF00FE0BEAAD0E15E13EF377B8F
+:10C8E0001D8EF61F511DB04E9EF619A72D50B68411
+:10C8F00093EC1CF4EFEC4FB2F559781CAD62372184
+:10C900001E47FBCF491CBF017A5EBE4531233CFC6C
+:10C91000F8E282D12BACA77BEBDF57372E8452395C
+:10C9200055DD58387D3B6DBCFD4BFEA5ED05C0BB0C
+:10C9300040724672E0698175548E5DA1FF3C16B964
+:10C94000E308CC2F6FB659CD5930B9BFF1765B2FC4
+:10C9500004EEBAC2F83BE72C2E895F813FDC5BFF17
+:10C9600095DE0789223EABFAA4E3CCB588A7C2E5E1
+:10C97000A2E0907DF81E80EFFF3FB9AAC38FCF7D64
+:10C98000EAB9F0041F541CF2BF720FD07937734B11
+:10C99000BD50FAB6DDFB760EB4977A988CEBB3A750
+:10C9A000CE4CEF7FF86AAECA22A84DB2DE0F311628
+:10C9B0004A3FF87601BC2735D9E55C186FEF43CCC8
+:10C9C0006485F6EA4E963A0EFCF454021A02C12A25
+:10C9D0004E5E74C4609D4327E5334EA89FF7BDF8B3
+:10C9E0002CB34CED5B5340C76B4F9A19CBC26B4FC6
+:10C9F0005DA880C1F38A67E0BDF993E7ADF5ABC1EF
+:10CA00009FB5DFE9E869EC573AC98645BF0B2DD4DD
+:10CA1000AF64EE47FD5BCFF5C8A4FE15E8FF0AEB57
+:10CA20003509EFEFC91DD8FFB52723D720DE46FE15
+:10CA300030F68FF5480F67A7F95D5B3E94B51F256B
+:10CA40001896ACAE7D7C5D48BFC13A81BCFF3264B4
+:10CA500026F9D6F803F520EA8B4EC7BF169F07BE0E
+:10CA6000B1E6FE47F1799083EDD82400CF6D4037D1
+:10CA7000922776E9E6C50CBB06D945E8B2250D70CC
+:10CA800017C2C017EF491EC2139E5FBE0CCF3BF109
+:10CA900079C5F4F3EE34F1F5E8CC65ADA7A7A0FFB6
+:10CAA000BB425F75BA793BFA033A5BFDF291DEACAB
+:10CAB0007EDF93CC340FC447C9B26B8847A298ABD2
+:10CAC00017067474B18CA282DDF8A1E9459606FAC6
+:10CAD000E6C55D6DBD608ADCEFFC348D7600F08DBF
+:10CAE00014D642BBA8F5E3D16CBD68795EC5717FF1
+:10CAF0000B38584CD83FD487C5F88087AB0A0C4711
+:10CB0000FEE4F7F21C29867ADCCAF8F34F6D0FF6C3
+:10CB10000AE5244F616DAA07E99C554FEF6514D4CF
+:10CB2000933097B6658129F014788518D7DF5BDFDD
+:10CB300059977C31AB3EC7E3F6917E5FC296D0FA3F
+:10CB40005BD616909E747919BB7E32FD7F9788273D
+:10CB50005F9C33C1277D82FEEA2013F63266467C55
+:10CB6000420E36DC5B4D446E68047896E238D50B95
+:10CB70007A21E8E1EB67B9F4E70DF85ED2C1D2BDE6
+:10CB8000302FA7EA752A306E48F0AB2B2C99B3F5FD
+:10CB900072856A762A00CF516B5EC6FA59AC95C68B
+:10CBA000011E93860308C7CE5C86FE0AD305633D4B
+:10CBB0004B016EBAE6CC2CBE7E63163FC2AD0DB300
+:10CBC000A28207082E35CF8E122B8E996B11AEEAFA
+:10CBD000C07AE9BE7C9921DCF8D533CB00AEEE12E9
+:10CBE000ED1BFDE646E8EFFE06C79803EB07833A28
+:10CBF000FD1812F215EAD43F9F44A717353A49169B
+:10CC0000C47F1ED2C943F2DA80FD47904EC07FF543
+:10CC10001EEE0F582ECD5C86EFED453A013D9D4D41
+:10CC20001D44877949A0D302A493AAA353B8299499
+:10CC30008BF5D54D4027A8DF5DE7A5719EC201E1C8
+:10CC4000FD9B2F152C5B06FD559B988AEBA1C9A572
+:10CC500097781AEC7AFD47CED9F0DF79B5671E34A4
+:10CC6000E54FE89979B5BE65484FE211A047759D3B
+:10CC7000AF8184DECF46CD8BE955FA1B12FA212114
+:10CC8000C7BFE281F74A5B07866D32FA83CC84F630
+:10CC9000BFD726E4365E43ED965BAA0ACE4DA107C8
+:10CCA000196BE77E04E8412BF0DB40C241E58E843E
+:10CCB000C4AC36C69E4DF8097E2A2153793211A69E
+:10CCC000F2442242F58713B5547E37A1D0F3C7133F
+:10CCD0004D543E9388D1F3D389568253893895DFDA
+:10CCE0004F6CA2E7DF4BB411BC3DB195CA7F48A899
+:10CCF000543E9FE8A1F24789012A9F4B0C51F970DD
+:10CD00002249EFF5274E52B93391A2D2EB940F6C22
+:10CD1000443FF26796C87128F6960E905F79744F7B
+:10CD20003CD2214F9EEF81C4C0526B96FF367CD718
+:10CD30003557F44B609CEAECF6B94D0ED5B2004B7A
+:10CD4000D587EB92DB3450CACBA497D1F3941FE183
+:10CD5000FD9E5944D7DCA6575BC91ECC867EB2F433
+:10CD6000C1510FD7EB7B3B4E0556678DBF5FC8EDBA
+:10CD7000419389D66FEFBC48E96AD7E4FAA315DA84
+:10CD8000FBABA7AC3F6E3253BD713E4F7BCC543FE3
+:10CD9000AB29D58EFA6ED404C6EF26F0CBFB631D0B
+:10CDA00056A4A36A633975A45FD276802DB2B50DFF
+:10CDB000F9D736C8DB4B1D76AA9FD3A450BD6C6251
+:10CDC0006DAC14786730D281F50E13BC1F8475C921
+:10CDD00089285F47BD60666D1DF0BEA5A9358D7EB3
+:10CDE000A4639DAB2D07F83ACF35A698B2D607E2DB
+:10CDF00084A7918FAD4D5DFF69C9C7F881BD58000B
+:10CE0000FDB99A58D282F1048B107E07D582782F13
+:10CE1000E9B9D56609E8D33018738E4E31CFE39B5C
+:10CE20006B9C2807124BE5A27D3EBAF9CA7E0059D9
+:10CE30002E4D9F8090FDDEAC3CEF01BDE0CD6B6BD5
+:10CE400043BFF24082A9E788EFA0047EB820E86CD7
+:10CE5000B58266047C0EF69BC9BFDB6B8BFDEC1ABA
+:10CE6000C0B3FB5173E408F475BCFF8C05FDB10F32
+:10CE700037B26AB483C3CD6F2C43F8F826569D238E
+:10CE8000E3FB69AA3F389BD5F4027C66F0EC329C48
+:10CE9000F7D130AB41BFB674A35DE76F1CDD7C4EAC
+:10CEA000B544C9DF8EA0FFE39CADAF97586C25EA6F
+:10CEB000B183836686F81CDDFC611ADB7F18066F80
+:10CEC00011DAE7440748879C196C207B761CF0CE6A
+:10CED0003161B9DA89F6C85905FD65DBADD97AF853
+:10CEE000F8A7D0F1C67FD3B7BF7E540F5B594CACC7
+:10CEF00063BE82EB382773235FC7FEC894EB787458
+:10CF0000F36ADD3A1EDFBCFA8AFE22AE635ABF8E98
+:10CF1000BF45BEDA5BDE467601966EACA37A621D33
+:10CF2000E748DCFFEA13EBDBDD6227F99EAEFF9CEE
+:10CF3000A6DE18CA794ED380C4CB24E981E9DACFC2
+:10CF4000F656109F7437A5A85D77F0B4635DD5C41D
+:10CF5000B8C6F645DE1C6A3FC7C1EBBB83474064D9
+:10CF6000B2FBE3F62AAB5EBA5B579FC3EBD1F1BAD3
+:10CF700001E464AFB453C5F1FCD0BE0ADB9F99BA9B
+:10CF8000BFF1FAD3D23DBAFA5C8E4F501BEF8C340E
+:10CF9000D5FBB3BD3CAFD01DDC4BF90C28291EB529
+:10CFA0005A61DDDCB88E53CBE30BCD8B69DD8F6628
+:10CFB000563B910FA6E34B4902B942BE7FDDC27AD0
+:10CFC000A7E07B97816F0FCAA95CF4FF3C0AF0438E
+:10CFD000D673BB2F8B3F483E57131E47E58813DBA4
+:10CFE000B3B8DE1F5BF2A6FEFD6B4FEA618D1FB585
+:10CFF000F18CEB5999D4B79F3B6478DF30BEF1FDDB
+:10D0000050A71E5F799B01FF4F197FC6167DFB4518
+:10D0100099A9C79F8E7F178EE8DB57A7A79EFF5160
+:10D020001C7F0AB9BCEE397DFBF9A9A9DF9F6E7C94
+:10D03000AB4BDFFEE68B7A58F3FB76C4D6C6EE0226
+:10D04000BE505E57548C2FBC185FA0DFC5147514FA
+:10D05000FD7A30318F45D0CEC85C6F8BFC94968FB3
+:10D060001A9A1F790BF322A3A81CC11E7E77FE28F3
+:10D07000C18AA580E083F3930427D138011C7EFE8A
+:10D080002CC1B9AA9BA11EABBA749A7D1DCA7C7033
+:10D090008471DCBC967D0CED1F6BCA253F2E6FDBC7
+:10D0A0008534FA292F6BF0D67DCA51801B308E074C
+:10D0B0003F373FFAA334BE7FFFC326867E6FFE6CE8
+:10D0C0007D5EC0B7ED948AFDE542BC857E6BEE3691
+:10D0D000FB9DA8D75777007E606F772F1AA0FE18A8
+:10D0E000F607F698CDE6F126BD0F4149DF035F5DF7
+:10D0F00089FA0A6328F407FB02A937D7C3FB3B9BD5
+:10D10000ED912332DAAD01CA0F6974FFBE97DB37A8
+:10D11000AD84BF463FFA03608F799E2892DEE0C35C
+:10D12000B88E113E00B38D98E7E8E4B025DA93415C
+:10D130003D6A893ADF4592595ABAEEA5F1E3FBEE12
+:10D14000473D68D97AE2012A373FFB2D2A37BDFCDB
+:10D1500020D56F79E3AF11067FE0FB5E8C5FB65D93
+:10D1600078889EBB785E6B2B93CEECC4F8A20EE25F
+:10D170007DC0E33BA6CCBFA1BD541FB2CBE8EFEF0F
+:10D18000FAF66833D2C1CFCAA50E78FE9DBAB3FFB6
+:10D190009683F65781D00CEAFDE95CB2037E453AEE
+:10D1A0009C8BF3107EB91FFF3F0BF36E810E5C4F1B
+:10D1B000A92594C4FCC94ECC0FCC057E784835A176
+:10D1C000BFA3AE63A7D0CF94C2AC1EFD4C49892C3F
+:10D1D000269FDCE523BD21C519B5CB0DC767619836
+:10D1E000FE98496AE8A3F738BECED9669D9EFA4EEE
+:10D1F0000BE087F679136007E395A6DF22B8B451F8
+:10D200000AE1F81A7EA5881F0CE411F87B1AE5C321
+:10D210007AFC92ED84DF3D801FACA7272C117E9E07
+:10D22000468E9FB6AE9E4D527B367E074DDC8F9C60
+:10D2300084575CD06D3360056397215E00976DD293
+:10D24000E35526E8568A7821DE9B8C78A58609AFBF
+:10D250006F70BA9586938457E9263D5EA59B93C36C
+:10D26000D9783D6E92CCFDB8AEDF98866E9B057E78
+:10D270002AA79B2CE8266FD1E3270BBA950BBA950A
+:10D280006F31E2C7CCE897AAED9C6EE5E10CE1575F
+:10D29000BE458F5FB99A31613BE7ECC83566C22263
+:10D2A000A9CB0B19F1DB73C777CE60BED419E47636
+:10D2B000CCE98ABF86FB027DAFD95807D40FCFFFD8
+:10D2C000A61FE38EFD777CA7C304CF7BE7F376DD53
+:10D2D000956FF851A8DEB3675A37C07C7A17994921
+:10D2E0003E2D985841F90ED98F203D8C7AB2A4B0CA
+:10D2F00082F4E0AEF935A44F993543795C8B53BC89
+:10D30000B758C4C3E2799FC464EB7550CAB8288487
+:10D31000B6827A88C6B9812B5607E89F47421AFC25
+:10D32000BDE64DE0F793ECDF20DAC338FDF6F1F708
+:10D33000559CFF230D5AFD096ADFEF34D49B4DA2A3
+:10D34000FE49AA77B394039C0216291C6A7680FCD6
+:10D35000FCBD3952E90078011BDAD9583E7DFD9FAA
+:10D36000150EED6C9A3131FFC1B5D6A6E494F16D7E
+:10D3700027AD93F362802517C2F8DEB64DA8E79C6F
+:10D38000D624EE554CACDFC5A0AE7E10F843015755
+:10D390002AD6FC3AE5BB1B0BB91E94A26D2AAEDB64
+:10D3A000CC688ACA9C5852C1F57286538A0DF3B56F
+:10D3B000B06698FE754763148777D99434F265D7C1
+:10D3C00022966C47572966664A169FB89B6AEFB645
+:10D3D000827E63517D1E57B36BCE8BB92C593819A1
+:10D3E000EF1B0A653DFF5D7451BBFFF9F69553D203
+:10D3F0007172FB2A6A373C6A5191BFBB7C2C99033E
+:10D40000FC67F30CA515985DB525EEB809F578997C
+:10D4100099A1DC4D5A379F756C54470FEB3984CD79
+:10D42000AA895D067D53C9629487CE15CFA95D0593
+:10D430008ED35042FC9FFDDC3219F6AFBD9BDD89D7
+:10D44000F271B190F0D4C6ED2A0CF3BC993542F9D3
+:10D4500043CBC562AADFCA841CB9B81CF9B7DCCDBE
+:10D460005667E5C12D7E96CE453B25F280261313E7
+:10D47000795F0E63020DF19E6E5FAAAF707C7FA88C
+:10D48000AFF02AF687C6F7CFAA78DEFBF40C8E5FE2
+:10D49000F77CF3E10E80BB3D1C56DD76AA6F5AFC8B
+:10D4A0005C0FC6E743556613EA994CBCE14D5C97A7
+:10D4B0001CBF5D46B8AF8AEFB7F983C0D780D7DC11
+:10D4C00085225FCDCCECF25CCC27A59809F571B331
+:10D4D00095A1FE7929C4EB5FF2707CF2AA640FC6B5
+:10D4E000055DB9F12113C8E7D247955556F033AC25
+:10D4F000CB92438CF2936F348F807E719A853E502D
+:10D5000037AC525C82AEA00FBAFC2DFDAA8BF2564E
+:10D5100054BFD3FFF64E8487DFED0EA09C0DFDEACD
+:10D52000413FFA69DD817800FD4CC9DAC66259FBDA
+:10D530005439AD5D19CAA305F572B4CB047A0AE972
+:10D540001070901DD1F6EFF69A143FDAAD87C5FE44
+:10D55000D7C3EFD8922AD0A9C714A7E761C7680F2D
+:10D56000E629F7C93EDA0F7DA738A4E3EF7CBF3D7B
+:10D57000327B8A7DA25E11576AF982E1F06907E287
+:10D580003FBCF1744F08D7276EC6ED06D66B6F6BA4
+:10D59000C278A67B8199619EA0AFB563E71C803FEE
+:10D5A0007AD546F972ADBF578B79BE6687ADAD357A
+:10D5B000467CCDE97E3BE08DFCA4B55B53C4E3B073
+:10D5C00003762197173D4C05BEB53EC44CAB814E4A
+:10D5D000AE62A1BFC28BEFB6623E6AC691B809D6F1
+:10D5E0006EC1BE0F9A1DA0679D4EA1B7D5DF342B2B
+:10D5F000A0978B849E5FB0EF37143F1AF7994ABC0F
+:10D600001C0F1BAE3FF0C75C8F80E7E9F11A48D4CE
+:10D61000569F077AEC4F28D5E7616A8F269AA89C17
+:10D62000CEDFBFDA52A3F3B4F5F99C0E95757CFDFD
+:10D63000EDCDD7E8F62D5E2ED2FC5A8E77A08CEF7A
+:10D64000CB5CEDF856EFC543D7C17A6DA9B4CB9842
+:10D650009FEA3575BC52827C6672A48E4339F48E83
+:10D6600085E2D86ED9CEE551E17CA6B672793C9FB1
+:10D6700018918E21AF3BF8F342D94EF859BDB51E33
+:10D68000E473E3FC7A2F1DED0941BBBE2607E535A7
+:10D6900087AB8E10DCED7346308FD49B9FDC44E368
+:10D6A000FD855D3E4276BE6DA402F9F7B542E2DF2C
+:10D6B000BB2C00A3BEF8BF36CA933E76CFD7DF8A15
+:10D6C00043FDFE225704D5A3ABE639FF3DB0CE4F54
+:10D6D000143B888F5C6616A77DA716D0C3597104CA
+:10D6E00070A4742C4B8FE617F1FD9FDDD69403E5F3
+:10D6F000B24F7E6604F95C3B0FE1A8E0F014E7212D
+:10D70000C23E3C4F6051EF0C205E961C761CF5D358
+:10D71000BA5BF25F0078DF9F5A255477DE3DDB87E6
+:10D72000EEC278AEC22EA35CF409791848A4AA3BD5
+:10D73000697F24E2473BF008C01B89BF9EABDE38FF
+:10D7400007ED6ECA4176C7E4505578BFC4145B003C
+:10D750002A9DDDBE2FB2CAB114FCAB505B00F5D2DE
+:10D760004F7CC77AADD7A35F92FABB4ED05BCF0C8C
+:10D77000CECDB3E7A2FFA5BCB21CEA4FFBEEECF5A1
+:10D7800055E2BC52D7320F87B1FD7ED413D0DF579C
+:10D790001EBD7115C20336213F2CDA877ACDA5E96B
+:10D7A00039F493807E5283A6F7DA56A2DF63B1C7BD
+:10D7B000FC128CF7868FA94D75597E941A5E89FBF1
+:10D7C0000A9ADF74D6F7BF7A51FE2CCEF426F48382
+:10D7D000868AE7D3F85ABD5CD2D1A7D2FE6086F420
+:10D7E000A1BBD149F92B375BC3E551D845B6E976E2
+:10D7F0009DFCB66EBE5DBF7F62053AC2FB7126D945
+:10D8000099F0610E81FECEF96990E0EE5BC11D8258
+:10D81000F9EFF0795F5E07741D8D399945CAF24BB7
+:10D82000BFA6F997AA09E95ECCC22AC651DD926467
+:10D8300047BF9E9DB133C70D98173277E139930DDD
+:10D8400077E6D1FB1B4D918C82F53B2C11F403E064
+:10D85000CFBE2E8A7E9593E26866655D1857E6BC5A
+:10D860005E4A71E576133361FE50BD9551FB7850E9
+:10D87000B2631CFABB379CB49F047F31473163AB62
+:10D88000F8D430FEB10EA35F16362531F6FDC5C8BB
+:10D89000595F3B3CFF72F347FDEBE0FD6B8A797EFD
+:10D8A000EE5C26B4E069781E5FB8ED967C19F988C5
+:10D8B000EBEF015176D9F8F918F57A13C9CF70BD9D
+:10D8C000DD8EF6F7FE7A1641BAC41BEDEB4C0B2643
+:10D8D000ECBBC6E73FF759483E5EF2713931DAF5E5
+:10D8E000AEC0B3FE38F9D140779CD72D4C3A0E7CB0
+:10D8F000B7CE920C9A664DF0F3BFC6D6DF822CB538
+:10D90000EF569002F0DBF705FC2F231DBA5F019F55
+:10D9100008E8521CF0BD8C74DBF212321BC94512B0
+:10D92000CFE774975F5381F2DF2FE2BCEEF2C5744C
+:10D93000EE0746923BF0FDF262CA3B3F22F683BB04
+:10D94000CBED0CF31AEBAFCD3982F4EAA9E8B2E4DF
+:10D9500043BB75072B6A507E1FF12A0B7F81EFF5C1
+:10D96000BA6BD06EED023F3909066D77C241E5937F
+:10D970003E6E8762CD1F91FE2B06DE46BF4F6A5575
+:10D98000DBD1AF98D9CAFD677F3443F1434EEDA890
+:10D990008AFE739F2D568FFEB35A6DA275CD8F9A56
+:10D9A00071CF729C4E529D5307FFA3D03B8CAD9517
+:10D9B0002E5C0BDE9572BDE532949642E566D42B63
+:10D9C00037234F2D42BF480DA01D18F268F255DED7
+:10D9D0009B764DF6CBDDEFD7911F3EC90F35F8E5AD
+:10D9E0005ABF9D6BE6AEC3F57207799EDD1DAC2173
+:10D9F000BB6A6C7FBD68FF8A2BF6535F11F7FB9003
+:10DA0000FE3B7D323D9F8E1F3AD7DC41FA3C07FC3E
+:10DA1000058CB972E2353C4E30F83705263EAF979B
+:10DA20007CCB56A29E90ECE956D4536F0C867B318A
+:10DA30005E92BC9A1E5AD2970E82FCD832140F6B9B
+:10DA40007AC2385F4D6F60B7974D9FAE37BE26E6FE
+:10DA5000B7DC72297D19F9EF5633F9F9329B4D760F
+:10DA60006D5798EF8B546CF9FBDCEC7323E01FB11E
+:10DA700063B47FE8A0727F42A2F2F1849F1D9B8372
+:10DA80007C2F53F9DD44989E1F4D44A874D9933BD5
+:10DA900043C4DF223EEDD97BAF07E4A5D89FD7EF83
+:10DAA00080791F2E95FE02F57CB1BF7DA52380F401
+:10DAB00048BE728D87E0DE4ED0EB8F015FA19EF6EF
+:10DAC000FBE7F7AA8062A8545E8FED6F1B2A6921DD
+:10DAD0007A09BD0A70BF0ABCEB72CA47D09FBDCE9F
+:10DAE000BF7525FAB3A15BC6F5743FEA69637B375E
+:10DAF0008BD59B2C787E2EA31C8BE23910D6867A90
+:10DB0000CEBD668D5EDF6E5DA3A3AB3FDE46F9AD95
+:10DB10009CF09A89BC1DD197E7D535FDDC6753F29F
+:10DB2000516ED572B38472E298A7CAE897F7557917
+:10DB3000BDE8BF764B6D3D28BFDDC19007E1F355D1
+:10DB4000668A8BBBD7B2A667C84EB43109F3766735
+:10DB5000EF3ACAF3785C7F7B6A2347699D7C76BE87
+:10DB60005F312A0DA37FA12A8EB1E348EF51D0D3B4
+:10DB7000D8AF12217FE2317C17EB2BB9DE2F0C1EC0
+:10DB8000A1731D2CEE6A039E66F78D540FA3FF51FF
+:10DB90000CEFE3FC975BEA7E1AC4F7D7303AAFD5B7
+:10DBA0000DE6A41CC6CDBF8D455419ED8D9DE4DB5B
+:10DBB00034504F7C2735DA75F2FEC0EBF7FE14DBEC
+:10DBC000E76C64A487F259567D05D219E0AC387031
+:10DBD000AC84EBA1ADA3ED26F4A79614B97DA827DC
+:10DBE000D842B610FD96FB5ADB56A0E9DA1A8FAC84
+:10DBF000401BF9DB60430ED94AC19F5A9C5021F863
+:10DC0000FB91442C897EECCD971214773E12340B95
+:10DC10007B7FB6390DBEF823D6C894F9F763181781
+:10DC2000679D7FF4B5403F59F31A1E7D84CE57F4AB
+:10DC3000C5B9DCF48D6EC845BDB82F0E71EC15F278
+:10DC4000F239172DBAB83507E2211C3FE7A29D9E95
+:10DC50006F2C54D6141521BE3F217C6DF3CDB12419
+:10DC6000F49B427EC8CA7B7CAD88FB53FB45FC30ED
+:10DC70009088917F9E499B0B5B60EE795146FEA593
+:10DC8000A4C43268EF7C41DC1386F56A041581FE7A
+:10DC9000603043E766240C356594E356E1E7C775C9
+:10DCA0007EFE40FD371DD8EEFEF67CC542FCD95005
+:10DCB00010CF8A674C3378DC5018D3E7BDFD6B7DFD
+:10DCC0003A7980782680FE4061DC4E7C087EF21036
+:10DCD000FA81431E1E1F39C3293A4F9413946AD008
+:10DCE000AF2D5EA37FFF8575CF32B43F79F1B809C0
+:10DCF000ED42715035B1F964E707D07FF45F3ACA5D
+:10DD000062AE09BCE83DCCBB3632B5E03AA403971D
+:10DD100097BE7296AC32D173E6C0F52BCF3C5D95C1
+:10DD20009597EB2B4FF95D5974DE31FF9B0ADABFF3
+:10DD3000BE87206E45394F3FC86437E209720FA590
+:10DD4000149486518EA5462984E7CEFA3EB1903DC3
+:10DD5000EEAB48F931BFD2377F71C97A289F16EBF5
+:10DD600034891F1C0B6FDC98C50F85C1C5DC5EB400
+:10DD7000E8EDC543A84BE05F44F04365A3888F3CC2
+:10DD8000C574FED3C817030995E2B747133DB49E87
+:10DD9000858D8AC9CA26E8639B619E72DD8C749F5B
+:10DDA000D0FB033ABE28DDA86F67A4FB27855CFE85
+:10DDB0007A2B4FD03E8D33CC54CB75B4CEAD2AEAFE
+:10DDC000C3E1075995A0E366843F399A46FF13F4EF
+:10DDD00052D55479A585220EEE9B7F42453EF90827
+:10DDE000F5B36FA2BFA9E8DA593899AEC6718D7440
+:10DDF000760693ACC545EB48F6E1078F0656A19F22
+:10DE0000AEC5CDCBD1F68222F429917AA4E7A7F151
+:10DE1000BD919E93E9C4ED44655D5C4279DF25FCCC
+:10DE20005690F8565CDFEDF3ED12AEEF70B4A664D9
+:10DE3000AA7D76ADD4E2A871783CAEF9C994714D53
+:10DE4000A116D7B033ABB2E39ADB4A0C710DFB7865
+:10DE500025BEAFC52D2BF79FA4B8458B6BBE56F2E0
+:10DE6000075D5C73CFFE67FBD09F19F757627F6435
+:10DE70005CC31AA50BE109FF70BA7963A071212B6D
+:10DE8000AEED13E72E8DED569458887FB60B7F7A52
+:10DE9000E1AB8CFCF62F2952359EFBD2DAEDF47102
+:10DEA0003E33C611C5ADCC8EF6F94B0A8B607B882C
+:10DEB000236E417D767FBD43CE8964BFCFE5F4807C
+:10DEC000B34DB72FA795BF2E3489FCF0449E07D7DA
+:10DED0007DFC9CE9420BC9A531DF337BBF9BE2DFB0
+:10DEE000897C4FFE2A253891EF99BD3FBF6FAA7CF0
+:10DEF0008F366ED811A7FD7C2DBFA53D1FDE78DAC9
+:10DF000041FA6DE37D0EB45BDDAD0DB40F71209F62
+:10DF1000AFA7B4EF37CDE81F7DE9D548C9D229E4D2
+:10DF2000320ECD8235E8970B7E51EFFA19F28BE66F
+:10DF3000DF760DAEA73858C25C4D0D2FCBBC1378E1
+:10DF4000CE015FEEB219E9C284DEDA24F4561B95E5
+:10DF50009A9C8DEB2D91B71CCFFFCCE0F91FA31C31
+:10DF6000DA760C9C41BBC50256F273F627B6527F97
+:10DF7000B65C163BED9A2C9746B99D2CA73C6E8952
+:10DF8000B0E7E8FCB5D11E6BA5D6EE13E13F444CDB
+:10DF9000F6183F071C976F9B3F45FC32CD3E82161B
+:10DFA000AF687E46B7F033BA47FFCE81EBD3F7298F
+:10DFB0007E86F3629ECECFD858185F57BC88E7FDA7
+:10DFC00025CA33E653BDD5EBE8CC8FF2FD61CC8793
+:10DFD000B5B9E25FC776058E34BB5E9ED8BFDD2F34
+:10DFE000F8EC2783415ACF815C885750FE7DF32996
+:10DFF0005EB1D8598589F2224BFA3A815FA4105F4D
+:10E000007F6B494B9F1AC4597DBE3CC79D821E5AE7
+:10E010007EAD4BC8F170F808E567EF6F76907FEA48
+:10E020005D59FB4F6B01DE71B690F256D53E2FADB8
+:10E0300043AFBD2D80F67B40E8C96A21A79DE5EA84
+:10E040009D48DF4E668EE0BEB375DD57E930B0F215
+:10E05000514C1DF5D1B9CFB6C7605E05BE149DDF2A
+:10E0600006FA1C2BCCB2E3DA79846385FAF5DA2759
+:10E07000F60FDF6B88E7DE8471F77A33C3FDC0A14A
+:10E08000A07EDD3E16764D836D93D76D08D7C366AF
+:10E090008DD1BAD9C4BA19E3418D9EF6ABA4E75726
+:10E0A00037EAE1356BF5F0EA35B71BE2193EBFC739
+:10E0B000B4BCBC881F9C9E4DEDB8BC45AFD69BCA76
+:10E0C000D9647F1FFD78F47F9CAC9FCE15B0B07EE5
+:10E0D0007FE84FFD7CFECF148B73D6C2CFDF129347
+:10E0E000BBF15CECB736AA397619FDFC9A15D97EDE
+:10E0F000BE96879DEEBB9EBB2CAC6D2A3B70BB9F32
+:10E10000E7493F2D3F8A7955E47BCD6EE63F2AAD46
+:10E1100054691F83CBE9DD2BB8DFFB92C89FAFA802
+:10E12000E7EF3D53C8843F0E120F0CF918C4C9F134
+:10E13000B9C00F102763A9F961362BEFE78E7C3643
+:10E14000A5FE2ADBA48759AB719F51AF9F7608FDCE
+:10E150007BB6F0A995286FA15827C5EDCDEBB8BFC8
+:10E16000A8C98D5616969884BE6D5BCAF3FC5B9762
+:10E1700072BDAB2E9D4AEF2E9FC6CFDF616B1BC6D3
+:10E18000FC5AF77246E726FD8D9FCDFFA92C993AE0
+:10E190009F6FF48B34BB3D49DF09F9B189FDD02C69
+:10E1A000B9B95C5C942D377C1FD476D164942F6B05
+:10E1B00089AE9DF58AF285EC7035F9953F56BED053
+:10E1C0003E61FC60B7C6736FCBCABBBC2BF2E7A93C
+:10E1D000566E77607574F94AAD5E2B252699703FAF
+:10E1E000EC7CB14C30B875269C4F318B5129397974
+:10E1F000BE09F533E55B0CFAFAD3EC757931E7F338
+:10E200009B2FED26BFC2867C06F8A4E266DD7EFE6B
+:10E2100075251C1F659CDFB87D7F6C1AFB3E9D3DFC
+:10E2200037CA43650BF0851BF975AB2E2EF9747F49
+:10E230009BD33922F0AD6C8C4BD9DFCD69F88EFBC6
+:10E24000631EB3EEBD89E7DC4FBB2CE2B2427BE438
+:10E25000DD4ECCFBCDB0931CF48B73FCDD1EEE07C2
+:10E26000BE2FF29EB789FE35783A3FF96AF3781FE0
+:10E270001571BCA6EBE77FCA1E68E3160A3EFA4694
+:10E28000C9D3C44785828F20E2D5E72D6357CE5B83
+:10E29000FE4FC99586E723C25FF9A8E80FC25F89E0
+:10E2A00090BFF2FEA327FB7AEA26F0FEDAFE67575C
+:10E2B00021FF8FE745EFD5E7450F625ED48479D122
+:10E2C0007F7664EF63FF77E5450F89BCE8A9FD6FB2
+:10E2D000F665E7454FED3FBB0AF12EB4279B67512A
+:10E2E000FDD9BECE4A90A3CD66C2FBEF200E53AD42
+:10E2F0001379D17F2F796F15AD8788CB0026B9D6DA
+:10E30000F2A23FDBFF0AED7F8DE745D96FFB302F8F
+:10E310006A6C9F9517A57DBECF9B17FDA8489F17D8
+:10E320003D51C2611C07F5D581F099E630E0FF014F
+:10E33000C6A1389F92F62711DFE192DFF5611E77C3
+:10E3400008F1A5B8F67714D7168A38F583FDA384AB
+:10E35000EF81A897E6F76B8C4B814E15E3F3FB58E2
+:10E3600037BFF7F7FFA62F3BEF3B63EBA7CC6F8BD5
+:10E370007E7E4F23DEA857D7F279BAD9403BF653B9
+:10E38000B486F7532ABEAF766FD4F713684D991C45
+:10E3900032FC675B165D30EF106F53F079D1D64CCD
+:10E3A0001A4D79F996389D432ADDACA75FB1A13F9C
+:10E3B000239E9F466F0DCF99DB389E65DA7C8D7862
+:10E3C000AE499AA89B7E3D9EBF2C91F9B92C9837F7
+:10E3D000FA65455B322AFADD3F17F4C0FE711D472E
+:10E3E0000DF0997198AF3308138D6732D9F8B99E43
+:10E3F000D13DC3E5F2F4F1CC1F5B6AFECE6E513E17
+:10E400002E4A2DCF72D0B05F6FF3EBF3CDE379CE10
+:10E4100099DC7EE485F57648AAD3C35A7E7AC6167F
+:10E42000BD1DCA8FEAE1E066FD7B5A3E7B227FCDAF
+:10E43000D74DCB6F5B8AF4F43B10AE213969F4EB16
+:10E44000E5E41A7FA85F2F27A17E941349C849A34A
+:10E45000BFB09FE46433C809BC7F8B7FBE5E4ED4DF
+:10E460004ADE5EC8C957FCB3FAB3F500C8C995F7D0
+:10E47000470C72E22C9A564EA89F2F8A9C18F76B75
+:10E48000E6FAF57A294B6E08EFCF2A3737F8659E02
+:10E49000F731C84D647C1C2E272B0C30C4E78D1837
+:10E4A0006FD926E2F3AFF9F19CC7C029059679FC34
+:10E4B0001CBC319E3983FED9A22FAE9CDD67903300
+:10E4C0002DDEFBACF2F659E54C8B278DF1A331BE66
+:10E4D000BCCBC2E5E7767F7C5547D6BE8216F7698E
+:10E4E00071DEC5D16557BCEFA22B11AE3E96E59FFC
+:10E4F0007619E2982E33DB84707339F747F7F97990
+:10E500007EF0A0888BB5F299422E471A7F6AF87484
+:10E5100037EBF1D9E18927DB311EFB552E9D3FAE4C
+:10E520002F0D7B30AF3ED46CA5F38376B39A3303C3
+:10E53000F3620B189D87187AF7948A47E07F676229
+:10E54000A791CFF2AA621E8CD77F2CF0E8D2F22DD1
+:10E55000A2A4BFC5E27B71E0337B7A8B521FA5A7D3
+:10E5600063057E80DFF916AB827E0E2D73D077C3F4
+:10E570004A2428D6C3C2CF3F8EAE535D51FC5EDB2A
+:10E580009142B9B70783BAF5B207EB74EB159383E1
+:10E59000C21FBE9CC0F78DED8DE71D8DE71BEBAB59
+:10E5A000583DEDD355F273AC7DBFDA19A0EF4602AA
+:10E5B0006D7ECA8305BB3226CA4BE8BFBBD0E839A3
+:10E5C000DD77DE5AA99DF7F58D4807908E491370C7
+:10E5D00017C4CA7B6E534C782E62E05D137DEFB793
+:10E5E000631D7B0BD761CF6B3619CF95EDA9E0FB8F
+:10E5F00061EAAF72681D068BA4B78AA2F89D8AB53E
+:10E60000DA7413C8EFF25B0277617BB79FF6F1DA39
+:10E61000EB3FAEC2FB0DBEB5DA6EC675DCB334EFB0
+:10E620004EEC6FB03D28E1FC40FE0EA07FA9625E7B
+:10E630001FFBADB127216666B92C2DA31E71DDFC31
+:10E64000CF7EDAF763B27939D4BB4BF9FEBE63F5FE
+:10E65000CBE18DD0BFCDFCC86005D0AC2570A2DF6A
+:10E660009ACBD897FF811D407FF9DF87522DE8476D
+:10E67000BECD523D8B61BD96973ED06205BF33EF54
+:10E680001E8BF0AB122DE9D99F9D2FA49138F1017B
+:10E69000033EC8BB61329F7C5EBE9094189DC7DB71
+:10E6A0005DA8FC971FE426109F43FB7F0F5771FF67
+:10E6B000FDC7B5DE861F209D82E6E41CA0C3D2CB39
+:10E6C0004CC17DBCEDD5F6C31D585FD521D3FD1BD4
+:10E6D0008D7686F567DC763A0F3D00F548FF1F071B
+:10E6E0001B32659807F39B65AC778C4901FC4E287B
+:10E6F0005776305C2F164CFB317E5F6AD9E0C0F84C
+:10E7000068EE6385BBD07FEF2F4A86D14EFFF8C0FD
+:10E71000BFF45BCBF19C6DAC15CFB369F076D3D869
+:10E72000FD8CEAF7F5F750FC1419A2FB4280445621
+:10E73000A0E37677C46F92B2E0A2C89029BBBE3C3A
+:10E74000E23703FCE300539A005E411FA36212F319
+:10E750005FC88E370A780BC2E0FF2ECFE17AEE2138
+:10E76000013788FA2ED17E99A8DF2D6045C043027B
+:10E77000AE17ED0F0BF82651FF94E84FC69B24907F
+:10E780004F6BF9F747CA6D66E24F369F25E7007C6D
+:10E79000D3EF1B73F15C43378434B89F97F3C9FA06
+:10E7A000912FCB349D5C3CA79D6F4D31A43BCC3960
+:10E7B000B20BCFEBC5CEA5E9DC9AC2C6F2C0083BCE
+:10E7C0002DA934F5B710F419D07940594FE315D578
+:10E7D000B3314B11F2DD4F1F44F9CEABD5DF3B60B7
+:10E7E00057F8FD0057CB6716E4B35993DB7F22F44B
+:10E7F00033B3A665CC5301BFB50460DC73CB945B27
+:10E8000003459F5F5F1AE5E4F3CAC5277E6E473470
+:10E81000F908C497DF897CDF0D1E07DE5BF37630D5
+:10E82000C4CF9FD772B9A8D8B22A80E738FB64BE9C
+:10E830006FCF1CEC4031D4F7B74BF4FDDCDBB50DEA
+:10E84000078A514E40FFE23968E652486FF5BB8BAC
+:10E85000A9FDDB555E5EAF9AD81C1F0966A60CE0C9
+:10E86000FE805746FD3320CEAFAD6D7B6D399EC324
+:10E87000F5C5E46A34BD7B4C12D78FF576FACE60CD
+:10E88000C07D8B09F38CDBE708696003F43DCCDBCA
+:10E8900066D58FF2A2C957174B93BCBC750060D0E8
+:10E8A0005BBD4E2582FEED5B07DE6FC1F3D23B6C94
+:10E8B000113F9D6B57DF6F1901FAFF694E84E4EF3A
+:10E8C000AD032FB6F440FBB539206F1E845F6BE9B2
+:10E8D000BC1EE56DF401EC6F89FA7E7F13BCFFE787
+:10E8E00082DF6F7CEC7DC1DF5BD81DA8A7613DF1A5
+:10E8F000DCE39F2DBF4F5982F3AC778CCD894C5E02
+:10E900007F58C89D38CF41269F42FA39BC71E50E29
+:10E910002CCD6C4C95901F7272918E872C2C65AE0D
+:10E920009BE00733E3F926E4EFD9C4DF603FA5CFCE
+:10E93000CFBF4EE1E7AC3CF0ED16DCD781F9A4EF98
+:10E9400020FCF87CD6DD761F5B12BDE27C9AFDD9F7
+:10E95000F309C5891E5F94F938C53E407F11F7BBA6
+:10E96000FA03BCFC7721B79702BC3C2FCAFEF2AC7D
+:10E970007B733E87DCDA47583BCAAD6466A9BCBAF4
+:10E98000FF4EB965A4FF8AAA1D872D6497BAE81CBB
+:10E99000D9C06D763AAF3958DF25339A37C88184AC
+:10E9A000F3037B8D76C7CD443CF8614B3ACBFFEC4B
+:10E9B000F7F0F96AF08B18542CFAE2CEBFA83E8D1E
+:10E9C00037A78DAFABD11FD3D6F50B8C7F1CF1775A
+:10E9D000083FCD7103A3EF57F2585B532BA0DEB570
+:10E9E000F5818125F264BB97EF4AD1BA4B1116D954
+:10E9F0007DFD647B463BF1C2EEF52E9AB07BFFDDD8
+:10EA0000F2F405A6AB1FE92AB34E19FD8841F0C305
+:10EA1000D0BEC4D1DF407D7C3DF737D0AFF047E9B1
+:10EA2000BBF25368EF1605647E6E72EB0319A43BCC
+:10EA30004CE397A4FFFC21B25FD61F9BE83C745FB8
+:10EA4000C49EEC203F4F0958353FCF84E39DA77308
+:10EA50007A7D2CB310FDAE5F97B6ED423FAED7CEB8
+:10EA6000EDCEC5C0256177C0AFF34CC0BD2136885F
+:10EA700079DC753756EE6AACA4E9F4E37ADB6BF91E
+:10EA80007D73964B7F99FE7274C2AEE45C3CCFBF3F
+:10EA90001BEBCF4BE139CD9D8DEBD30FA13FDA9628
+:10EAA0002FE3B8AC96D345C1B32830E59C4B5CAF9F
+:10EAB0004A0D0E6A3F795D4715BC0F8ABD503086FE
+:10EAC0007E93F67E9CF1F8271F3765A03E7F8D353B
+:10EAD000B9BD62F2FBCC3A9AC6F75D67AE1BA37B69
+:10EAE000ACC4FB31998F3F9D9FB40AF54B119E0337
+:10EAF0004DD1BE80AF54D0DFFF40A61AFEBBA2FCB2
+:10EB00002E3A676DF41B9BB475147EE38AF2E5B967
+:10EB1000DEE884DFA8AD638E6783E33699AF33FA0E
+:10EB20008FC67E6E31F89F8D9EE53B3DBE29FA294A
+:10EB3000DAD074A57E5618F0595EB4FC15CF54F89F
+:10EB4000E46EE8895DA19F46433F0DB9CB73A7EC06
+:10EB5000C7BD61E44AFD2C37CC6B997B79F394F304
+:10EB6000326D705CA99F06033E8A69F94E692A7C62
+:10EB70006C1B9AAED4CF32033EF5B6E5AF4853E1F5
+:10EB8000F3FBF53DD9FEBE51BFE45CDC98FEB26FED
+:10EB900042BF18FD07E0739203BC976C2A3E37EA28
+:10EBA00013D267D8DF1DFC5CD0D5FAF7AB0292CE4A
+:10EBB000CF37E269BFB445CDC613F460FABA29F481
+:10EBC000A086B7D312674857B6CC913AFE47F83DB6
+:10EBD000CC2A99E83CB8594EA11E9B8CB787E4CC4F
+:10EBE000D3C8FD7C4DEEE696EA4B37EAC429F21B0A
+:10EBF000279C3C2FA5DD73A83D1F2BE5FB97FF51FC
+:10EC0000CAE9226DE5F71EBE8FFD11CCEF43FC086B
+:10EC1000E53AEB9CCC40FD35018CA7779B5C9437A3
+:10EC2000C57E893F9AF87775BBF11E45E8A700EFCE
+:10EC300051CCDAC7DF9DCBFD93BD86BC597119C796
+:10EC4000A3B88CE3710DFA0355F8DDE9DC00DE971B
+:10EC5000B6372007BCAE89FA82ADAFE9FA2D10F3C2
+:10EC600002854EE7929834C6305E2F28D3E35DD0FC
+:10EC7000F4315D96B177294B23DFEED9C592981F09
+:10EC8000D86B8B3460BCBFD7638EA09F3BABF1E5E4
+:10EC900037D1DECE1A0ADFC5A814E778FBF5E736D0
+:10ECA000F63617D3B9764F1D53701F9F457DA66C5E
+:10ECB000FADBCB7275E781B4FCD2F0BB3934FE00CD
+:10ECC0008C8F7667E05701CA63ED8179E2F77B7B31
+:10ECD000978EF9E99ED8BA5B464CFC3C19DD173299
+:10ECE000ABEEEAF0D2C619CFBF1630DDF7A0BD8972
+:10ECF00081C07B36CCE70E51B92791A432993849AF
+:10ED0000E591442AF05E567ED798B735E665BD8614
+:10ED1000732215AABEFDAC1EC3F917435E581BE74C
+:10ED200048E23981579AC64F264608EE4D6408DE00
+:10ED300093789360ADBDB15F235E463C8CF330E2C7
+:10ED4000ADD16DBAFCA09B49BD2113DABBCC40A864
+:10ED5000826E9F2079F3A0FD03FAD678E26BCAE8B1
+:10ED6000BCC618C14E363AF250059D0BCDD0F9669F
+:10ED7000712FF3E14BFFE4A0EF83A3A715FCBE596D
+:10ED8000BB8776B8F32C7DA7BCABD3EB443E8DBCE0
+:10ED9000B84D875FD891A17DEA79CF6FD3CDE3706D
+:10EDA000B481EE0FF232FE9CF0C57302AA97F8C64A
+:10EDB0005965A4BFB82FF5A28FCEAD6AF336991668
+:10EDC00009FFCCC62E835385671FF0FDDF9B956F2F
+:10EDD0009441FD7191FF7F52944F1BCE2169FB033B
+:10EDE0004951FE8D78BE4794E191B50588FF1386A1
+:10EDF000FD05D6C3F3B2D70C9A75F70ACD3BE6D41E
+:10EE0000DD9BB4E019AF0ECE0B97EAE0FC68480733
+:10EE100087DFE1E34DB79E15AA59D7BEEA7B4EDDE9
+:10EE2000F8DE46FD78DA7D23E143A5BA76525D48E7
+:10EE3000074F37DEC052D6B408D6FB61B0A3E87FD7
+:10EE4000E6D5F2EFE5F36A41AEF18C6E955E8E7316
+:10EE5000843E07FA3F8EF4D7E8CC825C1FE456D696
+:10EE6000C8E8278FCB757E7213FF3E7D40DB5F9035
+:10EE7000575F61FEC3E18E0EFA3EAC8A9F6FEC0DC8
+:10EE80009FA5EF997F1835D3F725BBAAF8F9E11DA7
+:10EE9000F37EA4205FF67E3B49DF4D38D34FD27717
+:10EEA000134712C03939786E3FC9E2F3F13E490782
+:10EEB000C17956B983FCDB1E5681F9F03C47A48327
+:10EEC000EEBBEE0758C67B07D3BC3E256029C3E1E5
+:10EED0006778FB6442A27EE688F9CB6166AE77A1D3
+:10EEE000698E98310EFEEDC13F507EA88A6574B0E0
+:10EEF0008C53A77DCF3FEC4A039EEA9A65193C9F4D
+:10EF0000ABC9DD0F2F9598D15FD8057137DE3F670C
+:10EF1000943F8D2E467901FAFF229BFE5ABB1F8635
+:10EF2000F9F928FA837E3D55D2611C47839D0A87F3
+:10EF30007F2DEC1BE88737CB683F90EB07F77BE72B
+:10EF4000C8DF30CAB951BE8D72FDDB3226E26221C4
+:10EF5000C751B38276C0C9B64CF45341789F477D00
+:10EF6000F403218F6E718E2C25E6A18D7FFD3B2948
+:10EF70002ABF2F9E2F81B01CF96A9514FF00F12D36
+:10EF8000383FD680D35CF20EB3A09DAAF128BFC152
+:10EF9000E79117D7EAF09CF7FC5ABD5D601C1ED7BD
+:10EFA0004783C28EF598999AD56E7ECAC9D4AC7E35
+:10EFB0002A406FA93AB953AFA89787A3C0C7D075A5
+:10EFC0006F153FDFB32B7AA409D7F5E408E763E0B8
+:10EFD0008C9FE3B96267C6C2300E9C338D9F744A22
+:10EFE000F0DDAE4B73F388CF47A6A56B4110F0A9B7
+:10EFF00059C6FD88DAEBCC49FADEBF4AE1DF258548
+:10F0000043E437FFADA0FBB382AE7D61EE47F74529
+:10F01000197D077DDDF3FCDECA856133C1CF68DF72
+:10F020008B887B93686B6016DA97512A6FBE947851
+:10F03000C1ED433F8645F07BE1D5523C8478B80F63
+:10F0400087CEE0956A302E9D4786F5991544FE5887
+:10F050009A22FE88BC6847191AA767DE08FF4E7619
+:10F06000DEF3F03CDBFE89F5A981FF6EADC1F5E36F
+:10F07000F5DAFAD5E09641CD643DA5E945A84AE721
+:10F08000802AAF41BB5288F7D40ED179BE642249A1
+:10F09000656FE22495E1A46CE2F7D33313EA67E5E8
+:10F0A000CC810627FAFDE23B37F8AB473A16284CED
+:10F0B0007AAA62E27B2FA9891DC933E13DF3AA999F
+:10F0C000EE496DE2FAA252D4BBA3D25173059E77EA
+:10F0D0006766FC1E0CF40FEDC7C9A23ED423EA5D9F
+:10F0E0001049E3FB8DBCBE02EBA3E85F8B7A29A934
+:10F0F0000A7D45DF413B45FDAC7E5EEF6DE2FD3DA7
+:10F10000B1947F7FE68EF2EFCF9E58CABF3F0BF5DA
+:10F11000D05CC661FC3ECDEF9B8067F5034E59F590
+:10F12000C7031786DA65EA8FF75B0D02583171FF66
+:10F13000F813EB38DFA873C4F7FD972CBC5DB94218
+:10F140007C66C3DB8CE87C4B9CD6FB09FCDE89BE6D
+:10F150002BD9F0A5F415F6B3B5F22E49B907F96825
+:10F1600087F7AFE8FCAF54C7227365BCDF25338651
+:10F17000F77BC1D874AF9B3BBDD364877A771DAB57
+:10F1800006CF96CE9352FC3564A77B5D021BC7D891
+:10F19000BAACF10AA2630A9ED362D67869B61D3A68
+:10F1A00021F6099E7828C3F0DE5D77FA2D1602BCA1
+:10F1B0000F06F93E753EDE7B41EFF1F3E99D1E3F00
+:10F1C000DDCBB1E3F18FE9FBBD026B5A41B96311AD
+:10F1D000568DEB53E018E0F06C01BBDA381C049854
+:10F1E000E17AC639ECE7F53B1EFF2A7DFF58E06364
+:10F1F000D5384FC403FD31C403ED9A3B9AA1EF010A
+:10F2000081CF1AE8BD24E73318A701DF63C7B8DD53
+:10F210002A70315EAF0A589238DCC9DB3BA349DC67
+:10F22000B366E3DF4B1CE2F79ABA07EDEF62F96EC3
+:10F2300069FC319453776DD77FD2F368DC4CDF9D46
+:10F240004BCA417CFE84ADAD14F7B535797902BF68
+:10F250002FC2F33C6990972897175C871D8FDBC7F7
+:10F26000E565EE17585E4EA0BC544CC8CB09E4FFD0
+:10F270008A0979D1604D5E345893170D1EE7A3A516
+:10F28000F15257561C79621DBF6F995DDA50BA264C
+:10F29000EBBCF58903DF2C45FA9DF844DBE7AE793A
+:10F2A000F84A72519904BD95A5176795C55FC3F5D6
+:10F2B000A850418FE9FCCF93BA76C008E44F3D31A6
+:10F2C000C4F7E34F0C850AAE749E04FC67BAFFEEE8
+:10F2D0006FC06FC20B899E4C48044FD77EDEF64C40
+:10F2E0001BFF2E36F936CAE5C3957208E5DF997E15
+:10F2F00085517C5127D7203FFC21C8E3E41D4F3EB8
+:10F300004BF29267E5F1719E83DFCBCDEAB81CE446
+:10F31000B9DAD2B8DF300E4B71DA17D7603C8FA460
+:10F3200093E730C8338E6F1DF567CBF3C3429EE77A
+:10F330007933F1ECEFE4343C66979B443CAAC90175
+:10F34000FFFD8F9565F13F10FF0B797047F9EFDDF9
+:10F35000CC8F8C9A713E8B5F67329E25BE36983E6D
+:10F360008378465F0518F0AAF4C916D42B35234CD0
+:10F37000CD83D876F19B9CBF1EAEE4FCB5E875CE7C
+:10F380005F0F57727E017126FED2E085AF72FED20A
+:10F3900060E887F84B83C7E75539EACFE6AF1DD75A
+:10F3A0005F7813FDC9BC309351CE343F58F37FF3DF
+:10F3B000ACF1ED44DF3735BF37C6E1D705EC523845
+:10F3C0009CD1FCDE08875FE5F50F7F328B60F51579
+:10F3D0005E7FC2D546F7489F38E435A959785D531A
+:10F3E000CEFDC927146BD354FB26FF18E4E7D1EFF9
+:10F3F0002953AE2D87F293B218D1F9894367E97783
+:10F400006B34FABB6B39DD8F95C52FF375D0F410D3
+:10F410005F87637B6E09E13790C797DA537988EF8E
+:10F42000E009057FF704FEF8FDE1027654587530D7
+:10F43000680B1DECDFC0EF1B3FB67765CD2BA8A78F
+:10F440006E72527F8FDCBAF8DD4E8497F0FE1FF9A2
+:10F45000D20DFFF922EAA5C5BCBEA7C2CEF5D4CF16
+:10F460006D49D46373D9681AF58933CCF5E45C6BC4
+:10F470009B19F5237E7F8EE7BEE6AAFCFEE4FC70B6
+:10F48000FC8C99FBFDC42FB05E435559727A7339D9
+:10F49000A7CF5C2697A05FA5F5339759E97DE6E2F3
+:10F4A000F7F543BF03B3B3F20D4DE5217E6EB36AAA
+:10F4B0008CBE5B463E10FD0F544DE1AF0E579D1EB6
+:10F4C000C178AAB7C7CCEF87AAE2767CD7AB8CEC21
+:10F4D0007BD811D91E46BF155EC07B757685F7AE09
+:10F4E0009C07F51F3D47BB006CF89868DFC8F344E4
+:10F4F000BB8E9DA5EF3A7785F9776735F8DD69E131
+:10F50000845CD15DAA8077053CC7EF63BEFFDC5900
+:10F51000FA1DA08593FDD7BBCBB3E2192DAE3FA258
+:10F52000C5E9E1B6865CC0D73B249B9D32C5017F0F
+:10F5300089EDC387C6C86D8F24C73AACF07CE173F0
+:10F54000E01FE74FD9FFFD57EA1FFCD607B1DE3BAE
+:10F5500034DA81F45BF09C6C1671C55FE1F38A11BB
+:10F560006E272B46520AE6BB8C71066D865C8FF5C2
+:10F570003D31963F39EEA8181950303F3629FE101C
+:10F580007E6AC5C8A882EF55809F8A74FAE542EE6C
+:10F59000CFDAF0DB61D0C3D689B8BB3F7B1ED3E99D
+:10F5A000E5F1B85B5A43EFC138F41DA314F4D560FC
+:10F5B000BC616CCFF0F651C0636F993284FDEF2DC2
+:10F5C0008B1F2C0778B77BA897DC692BFF8E78B749
+:10F5D00089F7A3CE3793DDB5805F749AC689D23898
+:10F5E000100FD0F72EBDE1FBA4F555D9FDB753FFA1
+:10F5F0005F29578E61BF74D908E68CEB52C4277916
+:10F60000C7C43D3993FC7875CA38CBD913D9391B97
+:10F61000D6C92EF8CBDB7C2C17D7ABA73C7EBA3CE7
+:10F620002BBFD93BEF4794C7D4EEBBC899CFCF418E
+:10F6300032DCA4C3F159E4155C3ACB2D3EBAEF6835
+:10F64000C683AF37CFC53CA8329BEE89287FE0FC4C
+:10F650004E8477D771589B473ECB2822BF96467A77
+:10F66000F56D3A92467972979F1F79085AD5977728
+:10F6700076F0B84BDCDF11DC9249609CD509DC8563
+:10F68000EB6E4D111D2D67F9BDE51859A98BE9DC0D
+:10F6900033FFAB4BA6F15E67BC9F1AE530AFF308B2
+:10F6A000ED43DCFF7D9B8C790123FF395BF87923E7
+:10F6B00023DF39B79E5B3B15DF39379D7B88FF7EA3
+:10F6C00008E75B2DEF66DDA6FD6E115F8FC9793A05
+:10F6D000BE1E2E874A7E3780E45F69F747BB9BC614
+:10F6E0001494C30BE5FCBBD8D24DAC1387C86B6236
+:10F6F00087C5F9E20BB83E05F1B438DFC1D7DF8327
+:10F70000E728CD78AF88B51E7FE704C207BE1FC3C8
+:10F7100052698C9BBD00231D9E2A8F7F80EF87E25C
+:10F7200063F5384E79D5287DEF68D1EEA573AD111C
+:10F73000EB0A732916BF7784DD6D33913FE9AD93F2
+:10F74000AA39BD15DAFFCE8B00CC26F8BFCDA55C5B
+:10F750002CA77399BEAB3A9799DF32A6E0795F4D3B
+:10F760003E8F57C57F46F69301FEB52447D61994C0
+:10F770007F6DE379DAEB3BE9BE7B0D5FC08BE2097D
+:10F780006F4412BFB396A27D02E70C6E0F001F27D5
+:10F79000BEAFE5C576D7727ECAFDE477C43F4FD6CB
+:10F7A000995907CD678CEEA5D4F209CE633C4F6022
+:10F7B000C4BB50E8E77118DAB6C15215823F8671B2
+:10F7C000F2EE9B6EA07BC08CF98549FD44F7AE46F6
+:10F7D000BEFABD392E237E85EFFCE0AB982F2CAC12
+:10F7E0003D4FFCA6E9552DEF3A307896F237726717
+:10F7F000AC03BBFD8EA8F730B6A712F7670E7D28C5
+:10F80000CD63A487E7CD28C27B37FF29D600F30A52
+:10F810000DCA74DE1DF4F0B538CEA7E5778C7AC535
+:10F82000C8F7D3EB199E9F2C1479823C13BFD71BCA
+:10F83000C49DEB39C1DFA59B3214B749C04798C7B7
+:10F840005921D6291F7F070AFAF9A43CDE80F80760
+:10F85000D408F1A5B3369526BD7195FCC4D8A88A05
+:10F86000BF7B24897DF9FCA879B8C147E719481EF8
+:10F870006435A3607D087F57892C72268DF67C261F
+:10F88000CA4784E463358E3FA356A6F1216EA4389F
+:10F89000CD281F93E501347C94E4E170F67D9859FE
+:10F8A00072F127333E835C78965BF7605C3A20F018
+:10F8B000DCD3F8610FD2ADC0E410788F1E4039C997
+:10F8C000670EBA8FDF631DAB475DAEC99197BD4E22
+:10F8D000FA35E0C8DCB602D7A18ADB1BE7E651D2D5
+:10F8E000AF8F6FF17A904F67BAB87FA58D7FEF0C1D
+:10F8F000EED7DF27D685F9E400EA33B747D987FC8E
+:10F9000033E9FECCF0878EEC78A8377FE01E1ECF5F
+:10F9100044E83E05CDAE7D5BF437DD7C8D79EB5D53
+:10F92000E1B3748F8296AF9E8E5EDA3D1DE3E33FB6
+:10F93000686FC57DBBDD75FADFF7D83383FBD72B46
+:10F94000CB947E5A07C1E7167B92CE3968FADB88E2
+:10F95000D76EABDAF4BFD17E55B1A40A78E5D5896C
+:10F96000FBE20CFC8FFE11F6EB74A419E513367262
+:10F97000BDAED9D7D2386B477E4F8EEBA57812DB60
+:10F980002B3D87E9DE786F1DCFFFE5B134E505F348
+:10F99000AD4915DF55D8A882FABC5CE8EFFC5ACE19
+:10F9A000BF1EC117F119F127493F2A9C8FCB14CEF6
+:10F9B0001FEEE828CBD693CC3F8D5E5761FCABD2CF
+:10F9C000EB627F5DD83BB04BC3962C3CA4BA8166FA
+:10F9D000FA3D45C6ED0E78BC3D58EF453994C8DE7A
+:10F9E000139D0B963F437A4CE3D3720C6E913FF11B
+:10F9F000BE02CCAB59813FA13CE0624DBA736F337C
+:10FA000078DCF992C69712F0A59BF8F2BD1953F86D
+:10FA100073BD611E1765F973C4978A7A6A583F5F90
+:10FA2000BECFADC9ED6B1376E3356E37F83DC37DC0
+:10FA300050221F861D497E9E28DC70C5DFF798C4C2
+:10FA400097DF70125F3E0E2107FD2E8033B90EFD49
+:10FA5000CB51C19717C4FC2E087817F21DC9833803
+:10FA60007F169D5AEF02DFBD3C43B76FC0D49C7C2C
+:10FA70008C0FE3FF41FCB8C54ABF13E10C67881F38
+:10FA800034BEFF34FDE36C6426E4574D6FFBE31195
+:10FA900053B69C3BC57D9C9A3E477AA29ECEABE274
+:10FAA000F4CC8F4AE4AF5866F2F93C3323FE5F880A
+:10FAB0004F614B8661DE4AE3D3F268B2DDFA47E874
+:10FAC000F771BE8A86DAB3F5BB513E40BFAB213138
+:10FAD0001EB60779C99F09F804940C8D9B1F4DA68B
+:10FAE000D10F9AA4DFD5EA61EB67D3EF25333F83CB
+:10FAF0007ED7F83F2DC566E27B20E7B47EB09EF24C
+:10FB0000CC2C3D3BDD7AF5DA2332D7B3EA947AD5B3
+:10FB1000CD32EDF89300057599744394F6D1E8BEA3
+:10FB2000406D3D8333630B705C77543267DB374540
+:10FB30009D64D7989235EF45623D61BE8BE8FD30FC
+:10FB4000E737B7EAD4F20E3720FEEE2D2AFDDE9815
+:10FB50009677B85ABA38A391611E270C9851BE35D2
+:10FB60007CB576C199F11538AEB372B003D7FDA854
+:10FB700058E78A63F2DBC718CE2349FB9D6C9F9937
+:10FB8000DF7B0B7157F6FD01F70AFC214EBB15FB1D
+:10FB900031B657B64D5A77DDFC6F9F98FFEDF87E72
+:10FBA000EE2739A4BF0E87F9B91367278F9FA7D80F
+:10FBB0005FFA13A4CB77853F77607CFF6EE00CDAA9
+:10FBC000BBB91BE31DE8073F259E2BF822CA511540
+:10FBD0003FAFE5D97544DBBFFB3AD177CE470AC6C4
+:10FBE0003AD70DB1175085827F77F7CCABF0EFACE9
+:10FBF000DBA6F1EB3AA7B66BC38321CA4B1E6E623C
+:10FC0000749FFD8E9DC52B2BA398573233CCB37BAD
+:10FC1000D33BC96E7B3BCD49CC551CEFE4BF3F3590
+:10FC2000DD7A3F8CF9D11CFE7B889817755B4755B0
+:10FC3000BA07AA96E7F5DD8E31D59A95AF74BB5811
+:10FC40003BC18AA897240E37F2FA5ECCAF66FDCE90
+:10FC5000ACB3294574732ADE34DE0356506BD6FDEF
+:10FC60009E555E3FFF7D4E2D6FE0412A66D1272FC6
+:10FC7000ECD5C136C17F3B5CF78D28884F555AC5FE
+:10FC8000FC65428E0F21BDEDE6E430CA192BE5F983
+:10FC9000726923B7E3DAEF442EB7D415E0EF5CE0E6
+:10FCA0006F13A1DDC59FFD41613C3993FB596E592E
+:10FCB000A6F9E42A2C9284E7B9B3D3C44FA5C0D3E4
+:10FCC000F8D323DB815E8D361C2F760CC773450677
+:10FCD00074BF4369A4EFD33335BF8DD39F59E3F28B
+:10FCE00054BF2BACC9DB062996423E5E6E69A1DF8C
+:10FCF00021F87F5BF87E5D37D3DB5FAD9C5556FF07
+:10FD0000CC4CB237B1919BA17D5735A3EF44765CC3
+:10FD10005AE6407BD6E5B68B73EC374AC3D6E9E5A5
+:10FD20005D2B87607E2DFCBC09953B5CEA9DF83D10
+:10FD30004754666A6310F0B0B63521FC8BEF96C568
+:10FD40007CB00EDDB836A530845C3A80E79D772024
+:10FD5000ACFD6E0AFC7F289789FD80D2D8D5BC0FF8
+:10FD6000F681F232A72CF1D7900EE571FE3B94E5B7
+:10FD70005B2236D45B67C77F2738437A6468FDDB34
+:10FD800001CC9F4765BD3FFBD752FCAD995970F937
+:10FD90009601D27BBBA21F529CBF93154868276770
+:10FDA0008ADF97D3FCEE99228F5F2673FB1F16E53F
+:10FDB0001F66F232B0712C80EFE38F61E2FBDF153A
+:10FDC000F868F7717A1BB9DDC51BF2D18F943672D2
+:10FDD000BDF591E003F0D34C785F6CA1B82F16E22B
+:10FDE000AB0F70FDF29A92946700BF51F7BBE61A11
+:10FDF0003DCA6733CA27DF27C5A332D185EB776DAC
+:10FE00005E124B99D03F05BBFE01E9E3301FA740CE
+:10FE1000B3EBCA681AF3801FCC6484873FCE681E98
+:10FE200065380F8C6B6C1C7FEDBE71235FFC7F34DB
+:10FE3000ED1E2C00800000001F8B08000000000059
+:10FE4000000BED7D0B7854D5B9E8DAB367269364DF
+:10FE5000924CC2E409849D770249D8092180E5B11A
+:10FE60004388C642754878040C748000510367F0DB
+:10FE70005A0F5A2C130218A96254C4F414E80451FE
+:10FE8000B9AD8F80E9F9B0B5DE8060F5D4B69104E4
+:10FE9000C54A353E78D4524F8E2D2DEDE5D4FBFF6B
+:10FEA000FF5A3BB3F76442B0B5E7FBEEBD27FDEA6E
+:10FEB00066EDF5FAD7FFFEFFB5F69AEFAEFF4BAA57
+:10FEC000B790B1FB19ABEE7432F639FECD622C5609
+:10FED000B13096C858143E27C353ED640CFE19DDAB
+:10FEE00014F5811CCB58EE386F9402F5D18503CC04
+:10FEF0000BFD18EB649E18C6668DF33815681F332A
+:10FF00006FA0DB0E6F3F1DE7A2FEF75BDB1C2E2709
+:10FF1000F6F3B8141A8FD7C3FB6AD530AFFEFC7462
+:10FF20001C9F376BB49648E3C1F84CC6F1BDA934A9
+:10FF3000EF26FB07727170FE5B476B9F8E9B8CFDFB
+:10FF400018C19DDA30906A2F632C8DC532D9CDD877
+:10FF5000F76CAC0ED717951F68B6433966AAAB0489
+:10FF6000861B9C2F5BAC736A3A8C93181C6720DD50
+:10FF70004BE5D846D7518B82FD7B18E26BA479A262
+:10FF80000B037E0B94E3ABCDF39408BC9E196B9EE0
+:10FF9000E7719C6732CED3E3C7799C6A80D6B5DD22
+:10FFA000E64D41BC6D8F016C5DC7D85D813337373D
+:10FFB0005B19BB3BC153467868E86176685F06FF12
+:10FFC00047F819EB913C458C1D92BD33116F63BD11
+:10FFD0000E3FE269EC9DAA0DC73B29E00BC577995E
+:10FFE000802B651CF375C2FAB2596B09C2FF70769B
+:10FFF000F9A81D1263EDD77FE690A1DF2D8A9DE65B
+:020000021000EC
+:10000000698F77DDB812EA774A31AEFDF07C68CEB1
+:1000100023A723000F9F6D6219F03F76FFBD6DA7E8
+:10002000E3A0EC9A9EAB6C81FEE3BA236112786A7E
+:10003000AE8E48A8675760DE7228431DD275C7662A
+:1000400078E641FBEE3F1FC5715C9B944391B0A6DF
+:1000500087EE0578011E57216BB6E07B4D2D477C5E
+:10006000DEA12804870EBF6B133B1A017044E7AB77
+:10007000B988BF6C362612E9F290DFAEED80F7ED5D
+:10008000E9AED7B3A0DCF6BACCB640FF572AFE984B
+:10009000DAEFC4750CA4BE8AEBA8B0B3FDD0AFED07
+:1000A0005EF60E8E13B9C995B9252308576477E417
+:1000B0003BB89E482D49899482F0D3BFB30CEBDB4B
+:1000C000A4D0FADAEE6DD3107FFE1C76E8496832D0
+:1000D000AE7080E01FB789C3AFC33D2E7BA0C26264
+:1000E00080BB0CD79518AC8FCE07BAE433FAFB1C53
+:1000F000FE7F1FCA69E150FADD3ABAE21EA43773E7
+:10010000C360D386D6EB4F8088C6674C8B95921818
+:10011000928AFE2258BC251DBA5E4A91D90E10D98A
+:100120002A2436C01BBD910522A091A2B92DD95019
+:1001300006A6D4E2A6C27BD00673A07D7A8563C0F2
+:10014000AFE2082EEA3F5AF457B6DA59B7230877D8
+:100150006A23940DEB18CD1EF80FE4CB7466780F6C
+:10016000F38C3EF39B33204A506F7ECFE4FA38E4A1
+:10017000DF9DF822CCFA369E5911386E986FAF1277
+:10018000E33E3701FE31854DF95C0EF61F0E2F7FE1
+:10019000DAEC0D1CCF612C47D69E40B96253130098
+:1001A00068A07FC16EC51B06DF413C06A456C0CBCC
+:1001B0005850153B4A187B49D00FFE3C8E245C07F3
+:1001C000FF4B0399B596327634BE3CAEFF2A70C819
+:1001D0001B7F5C326794A1ECEC96707EC6E6B8CECD
+:1001E000013E24ED23F679F4D5E86B65E774BCC1D4
+:1001F000BA6D6EE68F8E437D82BCC1D8D6181628A4
+:10020000047C466633E628C372CFB3588E180314B5
+:100210003494ED29A00BDCC1328CC31443BD3EDF06
+:10022000D6182DC56958CFB6F8EB490FC80A53F256
+:10023000A09DA3FB7EA6805D70287EE685A76CED61
+:1002400066C8EF4C65192817B2A38D97B345D9E955
+:10025000E3E531500654CA2E2F2FA7F0FAADFF590F
+:100260004B657F222F87AEFF39A1C774FA54B97C42
+:100270005B918FAB60792D409FE47ACF56C443B534
+:100280008BB9E478A21FD79B576AE7E0FB9B6F64AA
+:10029000AE1DF1C1F20DF7000FC423785C9FB74D7E
+:1002A00065EA0EA86ED36AAECA4F0F83DEE8CE436E
+:1002B000FDE160DD1143EB1364D0B3D0FFE1B9EF92
+:1002C000B10F81BE31CE81941A285F512482E7E8B4
+:1002D0008CB752904F1E9FFBD7947EA87F70C6F6B6
+:1002E0001406E5D68C3F32E3BC208B5A200C1CDE72
+:1002F0000C89D69F7DF93E07DA8336C5521DAE1DA7
+:1003000063CD345F9B8345A29DF947AD2B59C0F364
+:10031000F7AEEB850C49C03BE0009BC01E9AFE6522
+:10032000C1BB93E07D7CEECE6EE497073372335110
+:10033000EF150BB8F5F64733B613DCAD93DF4A6122
+:1003400008FFE4EDCCA81F1C0877187D714687DBF9
+:10035000F55F03F7F562BEE1E17E8B85D36B31C3B8
+:10036000C06FCBE478684B19203FEE1F0DFFF22FD2
+:1003700019FE1D62BCF30AF747DB149DDF6161685B
+:10038000F7BCCC27970C2F2F09732C267B169D1FAB
+:10039000652A67667BE2B0DF70F8B880F888185984
+:1003A000BE7E27DAFD16F19687E3F6D8AF03BC5C74
+:1003B00042FB02A0376A167F44ECF0FD1B6DFE2461
+:1003C000D755C6BF35209BECF048F048199944F743
+:1003D000F55DB269BD4DCF449BCABABE7D68BA19FE
+:1003E0009F3A9E87D0FF4BC2E7487C38223EA70346
+:1003F0003E8BBF3C7C8E04CF79E1B78E84CF50BE5C
+:100400001C6EBCFF5FF9323943B926BE0CE5C77FCD
+:10041000341EFF6FE3C7E2FFC6E39782C7EB33AE3C
+:100420004DAE0FDA5923C66F797BEF3C7923E0B3E9
+:10043000B77AD224F095C16DD78A6A012FB766F2D8
+:10044000F83A4F629E7071FAADC20E9FACAE5C4737
+:10045000F4F04433195EF559D49F97C1FAFD35B2D3
+:100460001ACE2F3E29F0559D194FE3F779648A077C
+:100470002E55E704B0FF70EB62D5063C64E27FA323
+:10048000826518E2245366933FDE27079E9410AEE0
+:100490004931E1ECB24ED73E4FEDDF47578FFCA517
+:1004A000EA9991E0999279ADF6AF4DE45F34929379
+:1004B00083DFE27103444D36CC8BD59C89A03CCCC4
+:1004C000297C958AF919CF864C685F535D62CACB47
+:1004D00040F8A661FF8FEE2FD88F7917B6A096DA75
+:1004E000DF9D69F68706E923ECEE410BF015FAD99A
+:1004F000F57EDB0AC37A8E665A045CBEB108479764
+:100500005D9BF02C8C7FF2A608753FBC8DA89DF7F3
+:10051000ED18C06FDF927829C2C037BBC47CE5F507
+:10052000DC9FEA3AEDB5590C743D24F810FA2F0B14
+:1005300017CFB689FA455E89FC78E0EFB13531C155
+:10054000FA1F87D487F6EFC88CE57C2AF1FC4F6848
+:10055000FD1ED1BFAEEEEAFDD98251942F808033CB
+:100560003D9CDED1F1579CE97D12E9F1B6E4FBF543
+:1005700037508EF646A84F925CFA726B8A8278608A
+:10058000560FC59337CF551230DE8775C9482FBB3C
+:10059000AC7C86651D2E7DDE04A8B742FB291AF3CC
+:1005A0003543FD47362517F34561E6FF6166E2F006
+:1005B000F30FAEC3AA55E07C0DEB81BF4A86AE6B4C
+:1005C000302F21DAF7FEB9722EB6EF3A69716DC994
+:1005D00018BEBDAE9772DBCDFCF396E01FB7F0D727
+:1005E000019EB175063AF6644652FF2FCA575B5119
+:1005F00097C0337797CFA6C0B88B81EFF5F18D7C8C
+:1006000072AFC0E7EBA2BD5BF6478DC77CC0DB5C79
+:10061000CF1DDC7FCFD870FAE6A4D01FDFCACC375D
+:10062000C94D6D75C9097719F2DDC32A8A57D7C933
+:10063000EBC6A2FC2DC2F991CFEDFEDB90BE279751
+:1006400047C4EF97AE7D1D5DA73D368C630B1770D9
+:100650007EECB078AA12512F1E663310CE0F10D543
+:1006600086BC55419624F0EE6D895419FBCFCC7BA6
+:100670001E6E75901C539E37FD896F3DEC477C6C58
+:100680001D45F2BF70C17CCA5BE456F3BC45971DA3
+:10069000F404C0756A464C00F3ABCCA15520DFAC26
+:1006A000FD3C8EED5083FA68A5C5B71EF3ABBA1EAC
+:1006B0003A247BA5ACC9417D3444FF6CAD157CA6C2
+:1006C00010DF0D95972D34AECE2F07033571AB0C8F
+:1006D000FC725D96DD142FF76EE671E05B2171E030
+:1006E000E2D33CBEEFB2F37CCCAF6E74C56FE1F2E7
+:1006F000D47C17CAD7E7E3245CC775599CFF2E0545
+:10070000EEF857DC7FD0F101EB2AFEBEC16E2D98CA
+:1007100067D6EBFAFA17D6459BDF8BFEF9B2763B2C
+:10072000CECBE646284F825CB8AB17935C7F3E97F2
+:10073000B9B0FEA0DDB32506DEE72EF88F3B695E7B
+:1007400091275A1B21F06965941FCDFF766A6007D7
+:10075000B44B6CE9FF8607D6F307A7272EC1C08FDD
+:1007600093B3CC7A5BB7C3D80EED548D55B185B336
+:1007700057B5D57258B857C67A7D46FD112AC79924
+:10078000D98CDBF53D1104D712E6B761FBC54C9B54
+:10079000814F30A33694FF33822E7AFF33AC3B6611
+:1007A0000AEA9D6A99F4CE195F6DDC4A5847BDADDF
+:1007B00033A6149E370B7E7DF74E99E262DD9E8351
+:1007C0007D3E51CEEDF325B4CFF50199FCAEFA266E
+:1007D000F903A39D5EE633AF276F6FD93AC4DFFB01
+:1007E0006098909F0FDA393EFD35D1E44700BF3E57
+:1007F0005806EB783F9050B203E0E9B5F0B27F0DB8
+:10080000870FFFAC498C79F93FD9A27AF541DC0317
+:10081000599D954170AEDEE5DD0E9A09FC91AC2341
+:10082000FD880FFF44D598770F7D7A3799ED7BEEE1
+:10083000AE2813BCE5686748FF778F5D6E908B7FAD
+:10084000CD89E6766C811436EFF0C31C27D1BFF753
+:10085000AF7263387FEE67391CAF0B7785EFFFB35C
+:100860009C185EDF1EBE7E34CE8F76CEDA3916E956
+:10087000BAB02E7CBB8AEC58BEEFB4EEFC32CD8908
+:10088000FE22975FBD7E52368723319BCB5BEFFE06
+:10089000DBAE4F457CAF975C3980D7B5A37CC5C82C
+:1008A0003FB73495503E3A369BF3F519C5F3ED2C1E
+:1008B000E8B7A67DFEF622A05F728FC585FEACAEBE
+:1008C0001F42E178342BD49EE8F6AC2D12ED19FCD2
+:1008D000F3E3885202C51F978074E7FAD8BF3FCA76
+:1008E000857CD13B4FF8ADFE2293DFFABD10390B6A
+:1008F000A5E79A5D663DF03EFAAD6541BFF5FD4D59
+:1009000093881FDF9917ED92697F6A52D17C831D0E
+:10091000D2F9BDD7CEFDECDEB7B254FF55F869442D
+:100920003F769EFCA5C627BDF3B81F0BEB8859196F
+:10093000A6DF6B2817D7109FBCBFE9EAFEF0FB4289
+:100940006F9C15FA5CE723F4A3571AE8FD66083D8F
+:10095000EA1ACCF02EAA37CFABCB479FA7250AFDCA
+:100960000F90FF5CE467DDAF655B278DB0AFC5F32B
+:10097000D83A3C1AEA0FC0776D5F5629EA0F8C4BC4
+:10098000102F1F86C015BA9E5ECBC0CFA720DFEF09
+:10099000B3929EC9D9B5624B2A1BCA779F868C73C6
+:1009A000AD7CA7C7BFBA3E0FED3FC867F3FECE3898
+:1009B000E91FC45FC3E33F704DFCA5CBFD2DD64EB0
+:1009C000DBB442AE4F6EC5BC6E9683FAB76629F4AF
+:1009D000BC85717F0CCC43F9FC22D447514C427941
+:1009E000DD1713C80156EEABF966B1D1EF9B20F4C9
+:1009F000D72DBBE66F4B55900F026DE47FDD25339D
+:100A0000F4BF7E7DFAF0362C47BD69714958EF5925
+:100A100045E54BA71515F5557E368F8B172E58617A
+:100A200033AE33946F1786F0EDAE2C17F7B707E3AC
+:100A300002E6223D26D6097A91F4E8C2A687A7E10C
+:100A40003C6B761DB51500DC69D97CBDA3B315EAF6
+:100A50005F2FFC4FE680F582DE79176D20AEF76ED2
+:100A600089DB436BBFCDA88F96FBCE5785D3E34B75
+:100A7000051EAA841E3FA3787BB328FEF34838DE08
+:100A8000DA6F72F8162ED820E13A7BD12740B911DF
+:100A900078D7D7619FCBF7C16E8E509E42BD3F88FD
+:100AA000CFF51C9FEF9EAED99658363C3E6BB2C335
+:100AB000CBC748F8ECDBBF94E6F77F95B9724C7E64
+:100AC000EED800C62FBD591C5F067F57427ED7F96E
+:100AD000E1DD0DE797794D719A2B1ED79BA978E23E
+:100AE000908FD6E6F0FDC14F62CCE7207E25F4C0A2
+:100AF00070F9A9A5B7BD4E71C2AF6EFBD9D81585E7
+:100B0000C1F6C3C9C35291BF39784744E3FE30727E
+:100B1000F303811F988FE2844BED928A7A0AFF8C4F
+:100B20007E4D7FF4F2ED318AC14F1BCE6F5BC0E387
+:100B3000A1A0DF1688298579B78B797E857E5BA198
+:100B4000C96FDB56EE0EE3B73582DF66D01BA17EA0
+:100B5000DB29E6F9DA649C6F1E9FEF9D069E877A7B
+:100B60007FDE040BEAC5530B1E253DBB4FCCDB2BB0
+:100B7000F4F7A90566FBF058B6795F6D88DE3C6D29
+:100B8000F6BF86B333FBB2BF989D01BF7E2CEABD92
+:100B9000531DF5CBBE81FCDC11A5E62843E9737734
+:100BA0008E2CFCA028E23F5DEFE8FCD765577FD78D
+:100BB00005FD4FED1DAD6E21FD585981E31DBC3281
+:100BC0004E92019F076BA21BD14F3E28FAAFDD97D3
+:100BD000B71FF1A331885FA17C0BDA25E8F790F00D
+:100BE000FF747D116A0774BBF423A12FD6ECFA8041
+:100BF000E2E5E57ABC8C7F30EFF9BDA91DE8EFBFD7
+:100C00006B117AE3A99800C635189F19F1753C0459
+:100C10005FA17A3ED45EBD13C81CCCEFE56404E747
+:100C20005BDD9EC1F353A25C7F279433901FB89D78
+:100C30003CBB7122AD7730EF57F36D8ADBDF03BF2A
+:100C4000E96A7EF888762DF0E5E675113F57DDFFFD
+:100C5000CAB936BFE9AC383FC7AED4DE340DD77958
+:100C6000CF28A2EFD95D9C5F3F13787FCFDE5F6412
+:100C700084EFAC90E73382CE67037CDF11F475EC30
+:100C80007C831EFA8DD0E7EF0939786FA3590E3EA9
+:100C90000F91A735BBCCF02EF399E175E6F07DD02E
+:100CA000F736B644A1BEECD3F9660DF787FB3C9549
+:100CB0003193513F04324DF472E67C31795B2A69FD
+:100CC0006477D8BD8C3D09FA3C339FFBF3970269EA
+:100CD000AE1D06FFFDE7422F0FD1C7F95C1FA3BF72
+:100CE00060C49B0FEDA6018E5B1A43FC158B62C19D
+:100CF000F378FEB7649283DE9BBEB91CF972EDBE39
+:100D000008CA97430DC1E17D22CAB52323CCBC2A72
+:100D10009F77A935609AB754F0C3B0F38EE027FDF2
+:100D2000775C626E7FCB35CAD797159734E498E528
+:100D30006424FE5D27F47D687CD28B7E8A3BE8A725
+:100D4000DC1CE1FBB40BF9CAE92BC73CDB7D424E4E
+:100D500056EF9A4FFE64AFC5B32D06DB9FB4B83093
+:100D6000AEE89DB7AA05CB97766590BFA4C3D39B89
+:100D700065864FB73723D9C7530BF3B6A09ECE7FF6
+:100D80005B0E209F9C5AB8D8160E5F8B2E8F66DDA7
+:100D900086F3657ABE00E5ACD6A06F0E64F33CDE48
+:100DA0008110395B78399DFA0FFAB7BBB87F5BBF0A
+:100DB000E0E16992611D4D39DC5EADCB51CCFEADF9
+:100DC00095FBB7C3E5CBBE1B429F5382AE7ABE6C88
+:100DD000A1D513365FB668811CA277B8FF85EB32C8
+:100DE000CACBFFCCB198D6A38FAFEB996B1DBF2FA9
+:100DF0008BEB4F3D1F975908FD6386E7CFC17944C0
+:100E0000BBD0799E16781A6EBEBB859F3E5C1EE9EC
+:100E10005DC16FE5228FD47BD3577E8EF9B2BE9A27
+:100E200057A6237FBDBFE9F7A716BBD13E9F988E7B
+:100E3000FAFC5DCC2B4DA6FC9B3D05F58D57227F22
+:100E40006EF1AE15143F417B8A837BC14FC1FEEF2B
+:100E500008BA809E31D9AF50B95B8D7042BB7BF42C
+:100E6000B88875D2BED348F8F955087EBEA8BE5FD3
+:100E70002DE881FA11E978AB5E66DD94178338E2DC
+:100E8000EBC86F1B993697EC518FC582FAF59CE33E
+:100E9000A3A48F27011F47FE36E963E0EB9528C323
+:100EA000D3E07D4CF873D209051CCFE0C7E51E07DF
+:100EB000FCAC62B12A9E2FDE16EF5F83FA60A0239E
+:100EC000D285FB06193B9BA9BC2A10E1C2F3C06581
+:100ED000BD0F9463FB2889A932CC5FDE33FB07B8D2
+:100EE000AFB03A10ADE021DC7D797C9F31E181E645
+:100EF0007332F58B5424787F61863F1DE13E7C7010
+:100F0000652CEE071C6F5F158BFB6DDFC7A55D477A
+:100F1000CBF733E09373F8AF34FC4FC5A373A07ED7
+:100F20007C6297C50928D8925BF1A803C6D9D6EC94
+:100F30004971E139C6DCF8471D63194B4AD27A661C
+:100F4000A9E047E68EAAC57249963E9EBB561B0392
+:100F5000F8FA1751F6A73E8AE51F5BBC1912B4DFF9
+:100F60009D3BB5D69A0A622CCD29B1C078ED4F6D64
+:100F70007FD43103ECC213F797DF03F3BDF8547D40
+:100F8000AD3583F6CB44FF15B5955658E774BDBC17
+:100F90007A1496DDD11EC50271595A6E4CAD15E614
+:100FA000EF4AD0363028F7E6C6107C53BDDE576CCA
+:100FB000305EDA534DB5734164A7F6FBA5ABE9FF8C
+:100FC000D48D95EC23A0DF85D9BE4A2BF48B787A9B
+:100FD000FDA385918C4D79A0229A4139EEE96DB53A
+:100FE0001125B44F55A2C033FEE9569AA7BCDE3F87
+:100FF0009EC1BAECEC8147AB693F4DECE38E517278
+:10100000910F07CBF93C1F35584EE1E5375FBFAD77
+:1010100081F8C9C15C96AF4039DE5B28A19E4F8D37
+:1010200056296E777897BF01E53725D7861DD8CE2C
+:10103000EA7D0FDBBFF99DBC0CF47FE45CCED7C723
+:10104000BEB336FD0327BE4FA6F8B26B0BE7D7D071
+:10105000753E9BC7F5575754F8FABA5C2EA7FA7E2F
+:1010600065DC69A63D03CF13510377223F5A58CF61
+:10107000BDCDB8BFE350729701FCB3739DA6F3B228
+:1010800083FB9C0E2DE132C0B9B294FBF5837A2923
+:1010900097F37F96CAF54CA26C217F7FA0447A0219
+:1010A000F93E5196BE3E1FDE274531EF21AC1FC5EC
+:1010B000A83C0F44E6104C5595E53940E771935331
+:1010C0004B5A30552FCF4EB8CCFB77ECA7F82240C7
+:1010D000E307E1756D407813E59A920D8506FC17DC
+:1010E00072FA7425703C74FD85C71D5D2733F7E3E4
+:1010F0007E982DD7AC2FCA7B6AECB83F975809630E
+:10110000C2FC03F74706683E875735EAA5B5027F5C
+:101110004D972359C060279BACDD76D4474D979DF2
+:10112000F43EB1253CFEF53C64D3E578E69F647C53
+:10113000CFD7151CC74DF5000FC587C3C173F72066
+:101140003C052C30291C3C85F4FE1F054F0132065E
+:10115000E0F5CED4C280D15FD7C7DDC8781C7A67EE
+:101160008C969C7015F96CBA2C0D03BF95DE678CBC
+:1011700003954CFB01DD76561884AF60BA968C72ED
+:1011800076E7A18A64E634D0DF2AE82FF43AD2D792
+:10119000783EE16981B7D583FBF6FC5CC5CAB442F1
+:1011A0008A5BBBFE5239613E8DC7F733BBAC3C7ED8
+:1011B0002BB76AB45F5EDE93E0F24BE8D7799EA16D
+:1011C0007D42872BFEBE69413EEA4AF055109EBE25
+:1011D0002391BE0F5DEF73BA1C8A7D9BE47AAFBC8E
+:1011E000C2009F2E67C3C925630F72B8C4F71E4C97
+:1011F00055728DFBE23ADC91B9DCDE02FD39DD523D
+:101200009D9C8F047E86F2C1E811F8209DEACB7B7D
+:101210008ED13A9B049CC9A7BB63278875DC0ECF8F
+:10122000EFE4F1FDA4985C6EE7CB5EA88CFE8AC863
+:1012300007E2A8E583FAFE8DDED9D9D04F2F233FF0
+:1012400029846F61AFC0CD7104DB3FF0F41BB55B47
+:10125000B3113F5A09E11DFE72C29C374B14F84D81
+:10126000CB65C2CE87EA0DE6D3F169D4133ADEF539
+:1012700071FE24C6F9BDD06B41BD27D1FEE997A709
+:10128000E72AAE51CFCD177A8ED733B7A709EB93A4
+:101290002CE2BB04175FCFCAD76B7319B80C77A4C5
+:1012A000C80AFA2DAB25EF76F42356DAD5ED3106D0
+:1012B0007E5C030870829FB40166F81CDEAFEE8985
+:1012C000A27DFF55BB22E9BDEE3F7DD626119FDDF5
+:1012D00001336C2C1DCA1F77A4D8699E95F7E7C40B
+:1012E000798DF059413E30CF1A2DE07384D84DAB43
+:1012F000B9BC32D7BB42920DF54E6E479B32B584D6
+:101300003CA0C347923887D09A68DA1F5172CD71DA
+:10131000816EAF7E93A9A562BFD0F643F5A0B06FF2
+:101320003D35948F48DE04AFF07B904E46790FB682
+:1013300087E7F792EBBB2D4D06FE389857C4E54B77
+:10134000667E09F07276210037D190BF91387DFC1E
+:1013500091CC85F98D13F19E3217944F24C6A82D98
+:10136000A83F64FF711B3CA7E589FDD568CE8727A0
+:10137000227D7B705E2B5312884F857EFA653A3F43
+:10138000F7A5EBB5E0F72972F72C43FD0969FE18C4
+:101390003E4F72698B64E0A7C171990BC7BDE1AF85
+:1013A000BFBF380BBF03CAE4E3B961FE1A831C4C0C
+:1013B000A9E6E7306E10F0DD90C7F7B34F6478BA56
+:1013C000109E13F1CCD502EB7A15D82616CAAFE6DB
+:1013D0004A6A8B12D44FC8FF482FE04F2FF24F922A
+:1013E0009D97B7E57379FA493E1F5713E5A458DE78
+:1013F0002E943E8F897674D4029E8FCCCB9C8F71B5
+:1014000095CFC9ED789CA35B54F2EF4C7754C07A2A
+:10141000C28C539BC7F34860C768BD43ED8A6EB763
+:10142000FA5BB350BFE4F37DBED03820B4DF395B44
+:10143000DB31CA279DE2F9A49D2E4FDC68D477A743
+:10144000B2981FFADBA3F97793A1F0DC2BF06A17AF
+:10145000F1F256917F89BD1C4D71F44601AF35FF05
+:1014600063A2BF752AF03AFA2FCCE37719E86F73BD
+:10147000594CF14EECE558EADF747992C94F19AA3C
+:10148000CFCBA9BE2085C75597CE2C8E6361F012B5
+:101490000A77B780532F6BF9D639CC004F05736D9F
+:1014A000C5F12B58E8B99BE92EFAEE0E7C6F3C1F74
+:1014B0000A7A9DDB0F787638B99D457DA9C75928F2
+:1014C0004FAE38C6F2F22A1EC94B34D81DD14F9701
+:1014D000EBAEBFFCDE1FC3FDBB04CCB7C7097D1D4F
+:1014E00027EC9FAEDF43CF2DBD23F4862EFFBABF7E
+:1014F000124A6FBDFD39A17F0E1DAF49417A1C769E
+:10150000B8243CEFBC2DD293827AF992C81F5CCAF2
+:10151000E1F3563B2A3563FFBC3C85DEBFA6EB31C9
+:10152000E64947BB5D3EDD2B1721BF3D20310CF561
+:10153000A7CC317FDF7424CF49E31E11F2A7CBE79C
+:10154000AA107BF5521EF7D75FCA8BBE26BB37A801
+:101550007793B8DEEDF8CFCA009E871968B632FCE3
+:101560006E774AB516E82F437E8185421C54B164DC
+:101570008ED20C65DB1B363502E5FC4878BDEADC13
+:1015800028690DB0EE9FE5713A34B9399C4DEE6E85
+:101590007B368098D6C4D737A6F3A86435C03FA65B
+:1015A00091B7EBCBB351BFB43A2BE9DF349F760050
+:1015B000EDD769F1FEAD3C36F87D25CA19F463B864
+:1015C0003F96A6F2719D6A405A05E3AC177CD46A37
+:1015D000995F88FAB035299AF4EEB202EF7B790868
+:1015E000D799EE6E44C394333D568C1F371568EF80
+:1015F000E37B7D5D8AEC4A433D137D86C3D59660CF
+:10160000F6A319FBB6C0F37E0E8FD35382F026C526
+:101610002A167EFE9265227D9312841E4C62DEC3E2
+:1016200048778787FC97A4286867FCCE9079CA30F2
+:101630004F17482C2A453D9EF500F713E6B90B4A93
+:10164000312FFDA33DE1BFD3BB22F408C0FF272308
+:10165000FC23D93BBD9D6D987851D787D1C20E54DC
+:101660002C712F45B89BB6FE6B74044C99D6D921CA
+:101670004593DEDCC9F3B402DF0087231FE9D759A5
+:1016800041FC93E6B7328C7BAD51E901FC7ED79AE1
+:10169000303599EE051806CEA68DB2D6608C07B609
+:1016A000DA09FF1D21E786743F37239FEBC9C30585
+:1016B0009E947C78AE3FF2B09DBEFB3FF0813DDC56
+:1016C000F9CFC1FED78827A991DBF1261773619E58
+:1016D000A0624903D9D1DB21AE8F88C77CB444FA1C
+:1016E00099D53902980A6BEA3CF46A1A944737692B
+:1016F00093313F96043CD05318D4A7694DC0571678
+:10170000C4CFA16E8C37D336313A95A9E30FB46BB1
+:10171000FA71E46BF0EC317F74D1E66DC2F92EA65C
+:1017200046AB7E90839F1E7A5BF926BCDF0AF5727A
+:101730000AF2F7FE14FC5EB775BC5D457F725381FB
+:10174000F72B8887042BD869781FEF8E519B616C2B
+:10175000258295BAAE82F7D075EBF65F7F3F6513B1
+:10176000978375F9E2FC34F366E0BA15996DA273BC
+:1017700003F9FC3CDAAB36E67724601E88AFE72736
+:10178000F9DA57911F180A612AAE2B70D49E317472
+:101790005E03FF78F213BF089C9D7605E0BA5DE812
+:1017A0008F8A2507A48F0C74FF7A3EDFAF4D7BA68E
+:1017B0004352888F0F3457B9A93D433D96F60CF735
+:1017C000E36F87FAD526BDB1A21ED7D71AC5FD1C77
+:1017D000D01B6B701D272C1B5E417B73A294A92D1F
+:1017E0000CF548CF7152A702DE1376EF1EB2D7C0B8
+:1017F0001FCD50BE239FEBFD57ED5ECA07BD9AC6B5
+:10180000BF376EB56CC9F73983721D2A877708BE5A
+:101810004EAB3B2059C81FEBA175AEABB3125D8E2A
+:101820002D5EDE80F3AC73A796E07791D7F96FBC9D
+:101830001BF5E1DCAE7809F71737E7737BB4AE4DE3
+:10184000E2FBC16D6FDA171AECDFEE1FBE69578A33
+:10185000B03D3F97BCAEEB9015CFEB667C728CF839
+:101860006F1DF0576419D283C37FD1D69D8EFC13B0
+:1018700073F89FC720FF319785F82FBA9AEB33CCC6
+:1018800035E6C4737B4FFA6D4B2EE50574BDF91335
+:10189000B11ED093A4E792928A4A308E7A44C0A9AE
+:1018A000CF5315A51E437EAE2A9508BF199F9C24D1
+:1018B000381FCBD7F3C65CCF2AB1FC9CBB3EFE5091
+:1018C0007D3F81FCDF97847F09F4DB8B7C15AAF7D1
+:1018D000F5F133F6D5D0F7E883F4403C1BF8E899EE
+:1018E0007CFEFDCD33F9560187A6209E140BC82936
+:1018F000FAD5764F217E076F4D12721A7F5A6936DC
+:10190000C9E94AD223AD69DC0E019F3F8BFC746CA0
+:10191000F173723BEA974229807A75D70BF3099FDE
+:101920004D4833D42FDE06A2334B813802ED8A971F
+:10193000DBC5A6BA4514870EDAABC312E1BDC9EF09
+:101940000CE0DD13733BE7F3FCA33B52157A89E807
+:101950001BBC9FC09B81F1952EE73AFE747C7C9660
+:10196000C7E5FC97F9DACBE87FE9F1A4B37E80E222
+:10197000F450798C13F1A40FE349CCF3AA8EABC6D3
+:1019800091BADD1BE4771147DEBEF167E477DD969F
+:10199000F23A3D312E417F5E8F5306FD3741D763CA
+:1019A000E2D98F7206CFDBCB3A49CFDEFEB18FE4AE
+:1019B000C559CDF582F38C599FE9710A385E848F41
+:1019C000DBCB785CB316F4A514266FA33FD7E2FEF9
+:1019D000118C37EBCA2F638DFEE4BF0B3E3E7F10A8
+:1019E000FC5ED2F73EF257871FC7F70B3C0FC00EC5
+:1019F000F1F332FA7863BBE74C3B0B74FBEDC13873
+:101A0000BA4FE0E233B57763D97F208ECEA38CED59
+:101A10005E40FC70D13D4D45FABB5B387E2E76565C
+:101A200012DF7C92AC58D02F6DEE7C74E687C8C76D
+:101A3000051CAE4F5E9037E2FA3F79E1959D7F71CC
+:101A4000E37989922424F996A7FF971DBF9FB604D6
+:101A50001EFE2BDAADC603712EFC9EA1E507DF9BAF
+:101A600089E5DB0FC4919E6CE97C82D71FE4F59F6A
+:101A70003CD13113F17CECE9E7E5F6B220FF7EF2D0
+:101A800042C7CB7FC1B22756453E69F2EEFA1696A1
+:101A9000D982585A27F31EB72F34E49F761F3A4A4B
+:101AA000FCA6F3C3DC4ECEC7ACCE4E71B7CEB76743
+:101AB0005F8F6212C40367E3F9773FAB640BAD7BC2
+:101AC000952CD1F3BCD8E79A20F6618AC4BA2F6C62
+:101AD00056D33EB6A17FEFF9451DCF1BF53C598685
+:101AE000EF2BE83DBB3289BE7BB9B08B9F83C2EF41
+:101AF00060705FB0F131D983E5DFEC92F9399F076F
+:101B0000223A708A5B1F93FD24570FF232389CE90A
+:101B1000C67DC48F7E1D5917CE4FD3E11BF4BBED9C
+:101B2000DE4EFC5E6095C5C2E3932BB5BF980AF00C
+:101B30009DB52887D1EEEBFD2A0BB87F175C078F88
+:101B40005374F8F57641F83DC561E1DF156D86FF08
+:101B5000B168013F6FAF8F73F6BDC8C670F0EB7808
+:101B6000B5221ECB30AFC47A50EF9DDD65E3E7525E
+:101B70001A789EE291EA390750EFAF7A80D3314E5E
+:101B8000D50EE0BEF3D70A6CB40E9F53DF7FE3F1AE
+:101B90007ACBAEDA5FA07FF8D903910ADAB15509A2
+:101BA000EA39826F27FFFEE29507A7A41BBF233BFC
+:101BB000BB9969B61C03BEBF5392CB609C8F1E2B92
+:101BC000C9B5C1F34F47A7A5A31E5FB533E2EBDA52
+:101BD00055D6715EC46935B30BC7A21EF7CBA0A75B
+:101BE000673276F2464EBFF5E2BB83F54BE33B30FE
+:101BF000DF6B71B89806702EA88EEFC0F5DC5DC063
+:101C0000ED19E684709F94CD93C8FF6BB5FB0F92DE
+:101C1000FD7775A6A3FD8F2EECB68F86F2E2FA4310
+:101C20003331BD5504FA17EF6181DE073E073FB738
+:101C3000B66DED326CBF47662E3915DB3553FF7438
+:101C4000877E0F89D5754EDFEF95AFE60F99EF7759
+:101C500031DC43C3CFCFDAB95F06FE0C8B8467F962
+:101C60009D22CF2CADA4F30627BED13D1DEDED8FF7
+:101C70002EDC11D55468D48FBC7F5A17F793D675D4
+:101C800075D03D595FCD2FA1FB8AD689FD35B79020
+:101C9000C3F57EA7C96E3E22F837C9E5A17B531C68
+:101CA0009A27F13EB457111E2BD9F1AF7B6CCDF4BE
+:101CB0007DCF40FA4272A49E34D985DD366FEA6446
+:101CC0009CB755F83F0738DCD09FC6532A3537F606
+:101CD00087F1693C47BD66C5F1090150FEF79F2CAD
+:101CE0003E60DCA70AB53B387E9913FD187F1DF1D5
+:101CF0009D625751EF7C824D691C7FB131EF1E9A76
+:101D0000CF423B8AF273B8A0E2D982C4E053CF7FBE
+:101D100085D2E9DFB11EC6C91FAFD1931D1C754D19
+:101D2000F732E97EC2FA6AE127FCF803B273EBBD31
+:101D300056EEDF793F26FFEEB79B35F611F0F6EE53
+:101D4000173F20BD5A7384D36DB7D4BF1DFD43FF29
+:101D50008DD2A4270DF67BFDEC8BE946FEBFBDFAC4
+:101D600083358887CC23A92EB483EB67F6E7A27E60
+:101D7000FAF4452E17272C16C2EB89FD133AD08FA3
+:101D8000911AB9BFB7DEA7EC8FA07C238F1B214E21
+:101D90007AB80AFDC84646F982F55D1D64275821C8
+:101DA00097938C7D1F6E47B98887E806EFF33AB6A4
+:101DB000F8BDEB11BEF54D6C32DA97B439DA8B58B9
+:101DC00066472486A29AB4C45D6125BE5B3109F9D9
+:101DD0006EF7D8CEEDE827FAAB189D9BD96D6B9BBB
+:101DE0008DDF53EEAE525C8031C04B5FFA71AEEFC7
+:101DF000D527F1E95D3006FDB3F5EEC52AEAA72A3D
+:101E00003B8F8FAA9262286EDAFD6207C551EBF311
+:101E1000ED2AF94F475650DCC552A2891FD61F69DB
+:101E2000CE57609CB9CA752A9D13B3822B83766402
+:101E30008B93E17873E7F40FCE9703EF3FB5F5D0BE
+:101E4000B9B24F7F18C1FC863C6CFC1CDF9E6FA2B0
+:101E50009FEE2A556515E3B41E2FFAD320EA6A33A4
+:101E600094DB6C9E0815EA076E9402B89F102FFC55
+:101E700097AC6A4EC7CB429E2E0BFD73B9C06EB2B3
+:101E80002BCCE52F467BF63BC107F8A724015DE983
+:101E90001F408F866E92238C5B919EEE08ADE47F8F
+:101EA00018F8D45DC9FD097D1F2311EC2CED672CBA
+:101EB000B1129DD380CEA8FFC05F1E83F8F8AA3B65
+:101EC000AF14CF31A48CE77A352D5FA23C01F3DB50
+:101ED00019E22D7194F7618CB7060AA4F2FDCA507D
+:101EE000FE1E335EE4654779CAD00E2426F3FC78E3
+:101EF000A25C618974D3BE888AFD12E51ACA870C78
+:101F000024A6AAFB0DF8D4F32617808E74EE34F0C5
+:101F10004B6B8DC19F08EEB744129D2F58BAAD91FF
+:101F2000197C7DC8D7FAFA02CD517546BD9529D6E0
+:101F30001328E0FE067379881F922CEA28CCDB5424
+:101F40008D62DDB8CEAA276E7F82E7D95B681DB1AE
+:101F5000E319F54BCCF250DE6D203186E04DCC62BA
+:101F60002BB17F624B8A847004F1E9227B7258F8AE
+:101F70002B83728EFE5406CA39F7E3D7831FCF2412
+:101F80002EEFC497E0E7D3390221F783FA4CC8FD5E
+:101F9000DC239CBED1D55CEE41EE26A1FF88FA0C75
+:101FA000CF8F7E5A713117E59EB1E252947B5D6E00
+:101FB000D7DBFB73D5C291E5BE2A3A40F2523521F8
+:101FC000B7B42523D8FF539B42FB9F9F825C22DF3F
+:101FD000FFF4C5B703C67C854E9757ED7E92A75791
+:101FE00033A3548E3FE0DB98A03E5CFFA3FB73C39A
+:101FF0009DEB08DA353FF91B173219A7BB1817F705
+:102000000C634AE9E97796D23D75FC3BF36A8BF0A5
+:102010004FFA9EC5F6D1850AED5F3BA7F7CC407D10
+:10202000B2623CCFB3EAFE49FAC64EBA4728096C01
+:1020300025E17B7F34E5F7F53C5E285C0BC673B980
+:10204000D4F3657A5C8AFB1AD8FE5BE3397D3708E6
+:10205000BEBA6FBC64B2AFA1712D73F2F86C383B9D
+:10206000A2F7FFB2F28BFA3CBA3D0BE2BBD9B43F08
+:1020700083EB9A5F387CBBB6A35C7FD01FD2E74767
+:10208000FCFCF927A87C80AEFB84DE5A56E0B979C7
+:102090003CB44FA8EEA67CDD73222F9EE95D12575B
+:1020A00013665CBDFCD0E6AB7F5FE1FAAB4C70E23F
+:1020B000B6198EE39A5DADE2F9D2EF097C85B6B729
+:1020C00032EB1FFA0DF709667AFFCCF4FB4C107F58
+:1020D00043F92F601AC735DDBCFF82F05FED1E9318
+:1020E000D690FD93D6AC9789CFA21DB1C437B3303B
+:1020F0006884F9EF57C674209D70BCF9E4176D3100
+:10210000CD1B0A47A4628663247CB65A0E35227F13
+:102110003E27F099B9E7EA70FF50B4DBA99F0F6E34
+:10212000789DE179B54BA7199D676FB528CD687F7C
+:10213000FDBF6225688F6366B2FFC0FAD8A96DF94A
+:10214000745F6673671DD9158F19CEE43AF33D307D
+:10215000A9DE04537974639AA9FD585FA6A97EDCB1
+:10216000C6F1A6FA0C7FA9A99CD57A9DA97D4EDB64
+:102170006C5339AFFDABA6F605811A5379C2C1A5E0
+:10218000A6F6459D2BCDF4DE736B259D5BEF63F1C9
+:1021900048AF8982FF98A3BFD4784EFF8FE3F93907
+:1021A000BEF23EF33D38715343EEC119867F42E9DA
+:1021B0003DF14828DFDD487AEA5221A3BC50F44BB8
+:1021C00017B6201FA5AC62BE8869782FA799CF47A4
+:1021D0001A6F4B74B16537DAB73E99BE6B7C192B19
+:1021E000C2F8A9FA77EB7AB9AA3A8EEBDBCB3523A2
+:1021F000F8B59C9F6B22F8FE674DB4F93B974913E5
+:10220000B83E9D3081EB8B91F8F3FC66F37731CECD
+:102210003D19B3117E86DFA74898EF902A52013FFF
+:10222000095E27F95D8DD66E5662B0F7BB047FEF6D
+:1022300016FCDDBED945E3FCCBE6147AEED9ACD072
+:10224000FB7D9BF3E919D8ACD2FBFD9BA7D2F30031
+:10225000F85BF87C6A73353D0F6EF650BBEF6FAEDE
+:10226000A3E7339BBDFCFB2A2F04C26541FDC22EB0
+:102270002784CD730FF9CE5FFF8EDF3BCDD68DFA6D
+:1022800049B1FAF01E84E1F031A4FF08F79C86DE24
+:10229000933A7BC2DF764FEA48FA4FE717766552EA
+:1022A0004EB873BFC00774DE27E1078F3DE627FDF8
+:1022B00055C0BFD377F0EFE08AD1D6535CD69F6686
+:1022C0009C27745F7A368B0BFBBDFB8B13B81DD636
+:1022D00004DF69217CF7DD09DC4EDC23DAFDBFC2B7
+:1022E00077476D31E4DF1EB5B9C6241AD67BD41604
+:1022F0004DEF59BE8B617CC512B439C89798BAB7F7
+:1023000083FFF4D30936E16F65D33DB3FAFEFDF0E8
+:10231000726DCE4364EE4925BFEB928B69E8D768B6
+:10232000780817F091320F7C18A4A3D7C5F7CF6EA9
+:10233000137E8F15E88AF64E35E8C930F74B0DC786
+:1023400067BF9EA098CE03859E43C8F4A65AAF45AA
+:102350007E869C5FF882F2F3FD7F90FCE87CCEAE37
+:102360008CCA0E273F9A909F15137E42F2A3F379F1
+:1023700005DA25C3FC6F0BFDFAB6D0AF4707FD8524
+:10238000D47AD24FD6BC0463DEE497A2FDC8F88DA0
+:10239000B49AF45B889C8ED41F7754507E34901F7F
+:1023A0009C5F73C4FAA363BF087DAF8EBF21F31D8A
+:1023B000715F53FEC5CDFCB7209FAE6116DA975D05
+:1023C000E370D27939D66EBBD86FE0D3E24CEDC260
+:1023D0000494178D29AE2492238ABB99B8F7B94487
+:1023E0002FFB37901C4C6112DD0F2DF527C9EB3107
+:1023F0000FF83F62294E9AD2BF8689BCA02AE3BE5D
+:10240000F01C702992F4A39228373E1E97CC76F4E4
+:10241000637F07C6FF59204392DA2A23BFB9A5E399
+:1024200027A1BFFC0AA37DB85287DAE2B660178FF6
+:102430008CED24C6E3CFF28F79FD74D6D3E2867E8D
+:1024400033D900D54F7574B65801CE71EC8AEB1CA8
+:10245000F254F253EB3E87D0CC3FDBF73DDCD7F7AD
+:102460006FB1B216783E1EFDADA7513F6FF447B86D
+:10247000F07E7466E5F5BFB1395C285FFB2C5E67C2
+:1024800021E0A3217ED3147E4ECB37919F97B77E58
+:1024900088FE880582C4CF61BED9CEB2BAD5B81C39
+:1024A000F19EF099116CA7CB7D68F9B16D3C3E6F40
+:1024B000B99FF36F4B332FE714727E1D5D28F6032F
+:1024C0000AF5FBCE80324978AFB94E175FB71FE0EF
+:1024D0008EF4C5AAF89D9B965F4471A15DE1F73922
+:1024E00047E1EF0B007C918BDA093EC6EAE91C93C9
+:1024F000D4EDA1FBB643C7D3F2EFA5F1EC623C8764
+:10250000A34D73005F44D707FCB6F0FD8F6700BE94
+:10251000ACD5DC6FF339BD930A094E4D5B8DF97371
+:1025200078857874BA008ECC203FFE0D749881E3D4
+:102530008E44073966CE69CCC3CC0E4428989708E0
+:10254000A5C705D4D938EF9FEDE23E9EABD3A75E79
+:10255000E07DF6C61B03B89F37EBCAE6589CB772FE
+:10256000E3DC80F17CD4ECBD7CBF62B64D71278486
+:10257000B1DB83ED9C308EF17E3D6BFF681CEFE597
+:1025800061EE836B147CC0D818CEC7022EDB6CCFF3
+:102590006A7E8ED27B3DAED7CED224DCCF9063ABA9
+:1025A00069FDDB53533270FD8B04FC9A2793F822AC
+:1025B000613A13DFE3F3FD0BA0D742C4ABBD5DA2CC
+:1025C000DF9DB0A774D37DD587BE16FFAE1B4F76B7
+:1025D000F89F5BF406C8F3A18AF85BDCC00FE38BBD
+:1025E000A62DB2823C1F7A9391304716DDFCB81FAE
+:1025F000E03EB430FEBB89D0BEB9F8E26E1BDE030C
+:10260000B84CA27A6B31D4C3784F8FF7DE85F34C88
+:102610007A431B8B767A29B3D2F742274F5C770235
+:102620007F1FC05DE97BFF5E282FEC95E99E35FD9D
+:1026300077089EC07FCBBC3CAB1CF597F813F50721
+:10264000F0DF40F7ACF68CA378FF196B905C9836FE
+:102650005CD3CEF76FB2F64CA1EF06B3DB4BFA7149
+:102660003EE68D50D0AF59D3CEF557365307709F05
+:10267000A213F38D36BC2F4C6971423F7F11A3F337
+:1026800093E31AF8F998737B233A303F7C6A33D38B
+:10269000B6E6B061F5E314BD0CFC88F71DCC08A9C3
+:1026A000D7F5E739C9C5EEC27936C4AA4F02DEA60E
+:1026B00078DF96EF32E84F88CCA97C839043B595BC
+:1026C00055E2EF3E643630BA97C2CE7CDCDFD11CD7
+:1026D000FD2DA85F51F6CBE918833E1FE9DB2ABD2B
+:1026E000ECF559F15E099600FA5F45372890E2A0B3
+:1026F0007BB332E89E22F90646DF0BA757771FB35C
+:1027000041FB495A05E9D1C9CCFB4A0F3CA769876F
+:10271000845E0DB4E011770BC6F930DEF42B5CFF5C
+:102720006ACC65C5FAD94CB5F2FBB818D9D13929AC
+:10273000FCBC79356BA3F75F659DF49CC77AE8799B
+:10274000131BA0A787B9E83EAF990ED0FFA0278E34
+:10275000E165FC9371DF8A9FFF2FAD8EE8C0386E74
+:10276000E102B00B50AEEB6614D7D5562B746F80D8
+:102770002E2F3583F70728F47D1EB32A631719EC33
+:10278000E9C9BD8BE99E28C5623EAFFB5A21F723FC
+:102790007A85BCED96849EB855A2BCD9EE2576828A
+:1027A000A3EF5689F2C7504FF77AFB973878BDCD23
+:1027B000D39C84F5BF2B629807978B14939DEF9B56
+:1027C000BF967E8FA6635BAE0D9F355E71EF16F3ED
+:1027D0000B38FD638D79D0732B004E91A732E63F05
+:1027E0007E2DEC818CBA6F32F2E5E265741ECDC1AC
+:1027F000E14DBA299EF22E55ACCE8AE73A2F8A7562
+:102800000524CF1C82771DFF5E5D97A7469D3FACD8
+:102810007E7B1AD4D7AA19A41F74F89706781E765F
+:1028200069E37C92AF798DEB18DE0351B164018DC1
+:1028300057E7E1E7CAA4462F7D37BCC4C1CBC173BB
+:1028400063FC1C415D43C532B2F7ED110CE5AFCE20
+:10285000BBE23D3C77BCA4FE0605E9E8B0F2FDB062
+:10286000E4068011CF77D7AFA5F1B76A000BEA6C09
+:102870006B4F37F26F52A695E461DC3CF0F8C89ECE
+:1028800004E8F71E3A0A781E3541EC6BC483D2C1C6
+:1028900073634BF63C5C8574496B62B49FAF30AF99
+:1028A0001DF13D9CFFB3F7BE2BF1E4F7A2BF300E44
+:1028B000E0DA282B789E36C3AA50FEF8EDE3DCAEB2
+:1028C000B6D6B7903EBD344FA21F1BA96DE3F72FBC
+:1028D000C204E21EB76E0BEDE7B557907CB0D9DEAF
+:1028E000EDDD65A42F7C087F09E3F98A3BC4F70B73
+:1028F000A1F141A8BE706CB4131CF24C2FD1B94F9A
+:10290000622ADD2B1802BFE4F967AA07BFAB7F1468
+:10291000EA857C978CF777B03B6207E51EF5A956F0
+:102920005844EB515FE3EB99D4A3C9F8DE21FC2BAB
+:10293000C636717B13F9948476BED2E55FEE86F1DC
+:102940004F1E6FD88E47D76D6EC56A8C075E89990A
+:102950007206ED4EEFEA08A2E73BA9DC9F9975E508
+:10296000F918631E492BE2F6A814ED29ACA764639D
+:102970002DD95175E37C933D2DBD95DBD3129B6B17
+:1029800054387B5A85FC69C8FFA8C73D26BB3A5B13
+:10299000D8C7DE0ACF32E3B99BAA222E3FD78B27B6
+:1029A0007BC39F8EFC70E1E74CA1FC9F8D09BFC0EB
+:1029B0008C7FDA6380FAF33F67742F25EA5FE26762
+:1029C00008101E05FE94F624BF72B7517F8FF7934F
+:1029D000DD1A0EDF8B8B783EADAC7DBE8CFECC0B52
+:1029E0001D531EA56D8E11F833942E6C82B6BC0853
+:1029F000F789E479C46F9FB5F37D974327D610BF5D
+:102A00009D96980FE3F6D0714A1128A85FD2C302B1
+:102A1000012968FF3E0310B15FD92959F5A30AF0D7
+:102A2000E019FE205E93EB1C783670B0AC36B01621
+:102A300094BFD4566E9752BD2E53FDE8C61453FF73
+:102A4000B13EC5543F6E63BEA93EC3AF9ACA59ADED
+:102A5000534DED73DA345339AFBDDAD4BE20E031D3
+:102A600095271CAC33B5677EED64A1C14E17757A0E
+:102A70004DEDF1DAC674A493F8BD9F89471ACDFDD8
+:102A8000CF807FE8C073623EC26319E365AA07BCCA
+:102A9000034BBFB217FA2F9D1AE1EA86FE4B1B6C5F
+:102AA000417F12E5EC0D2663FC5EEB75FA508FAAB0
+:102AB00021FE69681CBEF635FFAB286FA5AF7969AA
+:102AC0009F616F11C4E54877119757C94EA2D76728
+:102AD0007DB28A3EFC5AF4E4DD41BA7EC638DF9608
+:102AE0001D6501DAC70D59BF1EB7370ABA2F8571A8
+:102AF000BAA12A22C54CF748C54CF7E87C339D6340
+:102B000054339DE3A69AE91CAF99E9AC9EB95BC624
+:102B1000DF55FA45AACCA4A98C8DAA36D35DC7F39C
+:102B200054F85F383C87E25515BFBB34123E4F1452
+:102B300085E6359C0AFA5197ACDC9F80BF058EF282
+:102B4000A172DF378CDCEBF8933CC9A46787957FD3
+:102B5000E7BAED789F84DAC3E57FF2BC0C3CAEC2E5
+:102B60004EAF98321AE99AC65ED2BF2FF1E2B91A77
+:102B700090EB7750AEA337AAFD7E6E37E9FCDCA15F
+:102B800013F6ADD9A8676F64CFCA61F6013F2CD2A6
+:102B9000F7013D1F162506F701CFCDF0D1399DD3A2
+:102BA0009245DDE246BF97119FAC7983FB6F2C34D1
+:102BB000BE0FF56FFD2B489F4C11F68B6EF2729392
+:102BC0007FAB529E2444BF947843EC5048FC2FD5F1
+:102BD000FFB3D9DF5D69C657CB546F869435546F08
+:102BE0000E1FFFF7D3FB59CCDF82F6F82BD5EABBDB
+:102BF0007702DCBD5F7B7B34AE3F340F00F8B51548
+:102C00002706F757B56A3D3EEA9981FE4F74613752
+:102C10005B07FD9CC583F874161BF0793852A578C4
+:102C2000E2D4DE0805F7C7CBDE6CE0E7862545C5B4
+:102C3000F38B87E3399F9C9258FF61284FEEE37135
+:102C400045566306DD3B7438437D05CBA7D6491452
+:102C5000EF949FD6643CC794EDE3F7A6946EF154CD
+:102C6000E23D0A0BEFE2E7077EFCBB3574CE29702C
+:102C70000FAF3F5CE1A373DCA7EEE5F553CEF0EFB9
+:102C8000D80AFC627CA9AD3216EDD93689FB234304
+:102C9000E8C9E393593A3DF6FCE995BBCB82F45879
+:102CA00079417D3516DE370C78AE8F6343E9A3FB9F
+:102CB000FF33ADDCBFD7FDFE39CC43CFEB998F9E00
+:102CC000D7EAF72F2ECEE7E7D9984A654DC401D150
+:102CD000D55AC573C8FFBE5886573B85FA016D09A2
+:102CE0009E75B82FE7AEF4D0BD2B8B8BB97F117CCE
+:102CF000EAFBCCDA5815EAFBF4FBA01D1EBACF3E66
+:102D0000E93655E6793E9F15E52C30B66412AE677C
+:102D10006E313F9792F5808FFCD09B9A60F9D0AED0
+:102D2000FB716B3C9E67A3BBA3C2C4F7C1BC5BC86D
+:102D30007936AB9FCE6996CACA04FC62624371F1D0
+:102D4000E31847236FE0F7C2AB9E9BBAD88FDF0A28
+:102D500033EE8F8CD4AE4F9C8F392CEE035AE0C9E2
+:102D6000B0A01E395C62F6773614F378467F4EEEDB
+:102D7000E3EBBC698CA4621C73839575639EFC6F46
+:102D80005D57E916FF72C4CFC2FD118C9F6B61695C
+:102D9000C673C5BA5E59C8F43FCF09E4B33522AE55
+:102DA0003D5FE4237A9FEFC83B5E03EFCFCD9702F0
+:102DB000783FC82207786240FFB74FECA6A73EDEF7
+:102DC0009AF69F9E9662AFC13F7A7CBCFCF904FAEA
+:102DD0008941D2EF6BAC3C3FA5C39338A8DFC12F2C
+:102DE00087FA93E0276D51D1BF3924A5C843C70D99
+:102DF000D5FB204F0CED44BA2E3FD58B9BEF34EA28
+:102E0000B3FCCEE63BB1BDF0BBF5FC26FC51FCBAF1
+:102E1000633ED75B490EBF8863F8F9CCD446FE7E8B
+:102E20002C1B90B0BDC25C5B12F11E1EDC50806793
+:102E3000F289E3CD08773CEA33B417F71F2B237DE3
+:102E4000C63C7ECC9F8156F4FD0BCC6773CCD39AE5
+:102E5000601E588B0F6DB9CFE97D0AF597368692C3
+:102E6000A82C41ECB33A5D039AA410DF115222362C
+:102E70004627A35F1E9A9F8BB0FA9EC632F347B8CF
+:102E8000F0FCF1E3D1DFA2FA8D56872B82BE00F26F
+:102E90004D41FEFE657182C853F2FC9CEC70257FAB
+:102EA0006CB0D336574AB2D14F2FE9564CF5935EEA
+:102EB000CB37D54FEE514DE529A7A79ADA4FEBD77F
+:102EC0004CE5AF5CA836B59F31E03195675DAE3318
+:102ED000B5AF602B4CF5958E5B4DF555AE0DA6F25A
+:102EE0000D29779BDADFA8349BEA99575B8EFCC4E7
+:102EF0002CB1F45DC5903C50881E9ED196CC8C714F
+:102F0000C3605E25C54E7C10817431DAC569AA4262
+:102F1000BF172B819E85E7FC09DEFEE2C9A46FC7BF
+:102F2000207FACCAFFA005C7CDD42E1C44FA3CEFCD
+:102F3000B732846367D4FAC615187F6E897549A0C5
+:102F40003F76E6EADFC9029783FE787EEA23C7D0A0
+:102F50009E3D7FC41A40E082DFD1F2FAED518CE74A
+:102F600043C63B283E7A1C3735A01C3BC14AE73993
+:102F7000D7CA1AFDFEC3798B8F3F255542F8565AA2
+:102F8000BC2A3EF759BC7F2CA6FC6D7B3AF2FBF3C2
+:102F9000AEFE47F03BE5E78FB8E93BE3E75FFAB009
+:102FA00015EF6BFB036303084757CFC5834FC0730F
+:102FB000E26B3C189E38F5C347E6223E7B6C2AA69E
+:102FC000DF7E6B670F30C3F7FCBFBD8B9FDBF13A31
+:102FD000648F15FD276B201DE3CE032AB703FD5236
+:102FE000F87B8F7E9D53A14EC4FAD4F0DF118E9AE8
+:102FF00068317DB79A99AF26DF62CCC7E4DC44FD27
+:10300000F5B2ED723CF31AE2589B152C9C13DFBB12
+:10301000E93D2CCF8F717225DE4B07F6242E3EDF63
+:103020008AF15F85F30F16C44B227A85503F20F159
+:10303000F393CCCAEF4D61D3AD03837E6D26F6E7E3
+:10304000FE30E5BDA15D85C3EC0F4F64E672685E9E
+:10305000BB6022B707B6907B3382F0F2FB3280C6AA
+:103060005BD1EF6BB180DF0770B58C9F9A8FF9361B
+:10307000CDF96FA725D4BF0CF4A401AE9DE3B547ED
+:10308000D5C9C1EFFC575AC4BD54272D09C837D63E
+:103090000407AD3F6E46029D1BD4E76D9A6831DD93
+:1030A0000B721EE885F74D84AEBBC25F5187F255A7
+:1030B000CF8A4B119E451325F37D2242BF2F13F279
+:1030C000B5CCF5EA9FD15E5C5425914F74253D0B3C
+:1030D000F02CF7C7D2F99FAFD7B3584C25780BDC4B
+:1030E000BFD0E0F9E1DEA2732FE2735FC11FEF866C
+:1030F0006783453D4A79D69DC28FD27FAFD43F9A30
+:10310000ECCBB5DAC919792B66AA80EFA8D88082F2
+:10311000BF931835FE029D0F5C3D91111D2AC14CD5
+:10312000A1DC0CA1ABE08B50FAE204C81723D1B9A3
+:1031300041E43981C3738DE7DD66E455CC443AB58B
+:10314000D9587702F2DB4F22F8FD2AAF0169A1FCC2
+:103150004F2F17501EF1B2EA9D8E70EBDF75B3E36F
+:1031600003745FCB4A719E8EA568F49DD843D3DD6E
+:1031700025FA3DBFC8BF958E783A37B743C88FBE92
+:103180008E2FCAC7EE2CAE7774791869BDB01E9326
+:103190001C4F57399FEB4F7D1DA1DF874E572DA246
+:1031A0001DBFFFE5B2EAA175FF53CDC07BF159F811
+:1031B000BD8B385F38C27AF7FE9DEBBD56BA16203C
+:1031C000DF00FD56465D1B5C9DFF4570E1DD6B0435
+:1031D00057F1B5C175FCEF844B639C3E23C105F4E8
+:1031E0009C85F4647306F83D3309D706DF05A19783
+:1031F000FE1EF812AE0DBED368475837876F11C454
+:1032000041E88786F9DEA68AF6D557815B007141D1
+:10321000949DC7FF513512E5EB24966DE3F723FC2F
+:103220006DDFDD0CD22F8975C7A3DE7B3982E743C2
+:10323000D5815C631EF7538197CBAAF6FB89897809
+:10324000FF8DD007D5E676BF0F69A7DF6FC2E659BD
+:10325000683FE591EA6CBAF7C5E260E27B2B7E3EFF
+:10326000FF7F0BFB14FABD956E8FB60B7BB47D7C94
+:1032700035DDEBB0FDDF6CF4BB475A0AB74BFF07F7
+:103280006AFCA102008000001F8B08000000000003
+:10329000000BED7D0B7854D5B5F03E73E695649246
+:1032A0009C249330E1E5998447C0104E92C90B02EB
+:1032B0009C3CC060431D1E6A10D401290F790D6823
+:1032C000356DFD9B09091153AB51BC152BDA81AA51
+:1032D000A5ADB746457F44A0830AC55EA51111B1CF
+:1032E000A21D9122CA232368D1BFDCCBBFD6DAE767
+:1032F00024732609F1D1FB7FBDFFD7F8E9769FBD86
+:10330000CF3E7BAFF75A7BED3D8C594E857318FD50
+:103310005DCC827FF16F12639F34EC938659BAEBD8
+:10332000B1E552F19962BFA3E7F36DA37D494A511C
+:1033300054BF2DAF4AC3ECDAF8F0EF18163631114E
+:103340006B11933711CB61D271FCFE006817FBFE45
+:103350001E6366765C9F27F4B3EDF36D7078180BEF
+:103360000A56990D65AC7E7028F22CB4B50C81FF1D
+:10337000C0F33B8BAC41D18DBD7D758293B1C4351B
+:1033800049522B94E2C0DBFE320F9E360E5948CFD5
+:103390006F5FE3906C50B664DE7618EB771FB0C8B1
+:1033A000FC3DF82B66CC8A6516FEC7AF5660BBC0E5
+:1033B00022AD123C0FDDCA72E13B4CB547925DF481
+:1033C0009DD0FF82F6387F92DCAAC0636570E0284A
+:1033D000AD5BA4F9427B00E76BAFB4B763BB75B0DC
+:1033E000DECEE1621D5C1E389AD35DF7CABC5D601B
+:1033F000171BF0FDD8FE309F8003BEE730B1F656B4
+:103400001837DE253EF4581A63F7A679F7B800FEA0
+:10341000B6C1DE141FE067C248EF44C447FCE8139E
+:1034200023B0BE62FBAF655F2E63E94D3033783F5A
+:1034300092181FDC0CEB6D1A5D9A2347E1739622FC
+:103440003006EF59BE1059A0B0FBB9C5EC65920328
+:103450009F5B0DCF430D7616B075D7D513E66A0680
+:10346000FD2A98D42C5199C00251EBEB1AEF0B8135
+:1034700005D27A1BDF4CCF7F27B0E610CC3320304B
+:10348000FFE3B04ED5F1C7C3421E8ED23BDD861A94
+:1034900042338E01DD363794CEC4F2A50675E6B10F
+:1034A000E18C5D3BB2E25E8443BA77DF8C6351709E
+:1034B0001C50D761A867FA0ECF381635CF418BC3A1
+:1034C00086F621FE1386F6CBEA2386BA3BF085A169
+:1034D0007FF63A3633BA3EBCCD3E33BAFF3A93BBA1
+:1034E000BA09F1203065339423374886768722372E
+:1034F0009AE1B9C529E78BD4DFD4CCB0FF3CE6DF35
+:103500009CCFD8A8A0CB307E6BA36C7E858F97BF55
+:1035100019E075F916D9305EC57FCD54F17D96CA94
+:10352000521E07BC8F69CF31BC6F914A0DFDAF1D94
+:1035300039EF5E259DB12A7B85711CB6DBB06E33F9
+:1035400053597D2A94E6BB3E15F3B0CE58790196C7
+:10355000E6CFBAF0E4C6F1541A2F560E04EE2C4F03
+:10356000397E39E3726012D2A7A4201F47E218C344
+:1035700075B21C26633F1DCFBF44FA847196C5D037
+:10358000E73273C88AF4B3EC5BD2E79C916AEB48EC
+:10359000183FBD8ADDE8ED45CEFD51FBFE496BEFDE
+:1035A000EDED5DFC13C782BDD2B7839E9FACE4EF07
+:1035B0008F62EA801951EBDBA98D9F24327F3BF0AB
+:1035C000EBAD89EA80D45EBED3CD47092CD82B9FC2
+:1035D00026D1F39359BD7FE78F5FFB3B621FEBB1B1
+:1035E000D273902BBDC2E35D1D5EA9BDB7BFADB563
+:1035F0005BBEC834C8837715993FEFFACE606AB7CF
+:103600007C91D2875C72D273A09C00CAF32AF89F87
+:10361000D614C6925372CCCC0478767C6642796E0E
+:103620004D00D28CD237ACDC1C89962755CC7C342B
+:103630000C7C6102C17311A65661B71C0D47D1C73E
+:103640005866AC33EC1FA59F468D6584FF2A269BE8
+:1036500059762FE369F3881D77D1003EAFFEC67718
+:10366000E6AB55638BE8B974DCDEFDFCABEACF78E2
+:103670009803CBA471847C184765CB16A39C9DCB83
+:103680009214D493F0E7B56730763DFE9F8CFC072B
+:103690000FCBE0BDA48EB59BE07FE357272901D077
+:1036A00063379A22E938DF792CBC169415FBCBCE10
+:1036B000382BC2B973E71F86A0BE61AC9AF4BB1069
+:1036C00048102F267CF5F98144E0788FE7F4C2AAF0
+:1036D000237521900763C5BC02D4BFC9A60B2E94E5
+:1036E0000F4C920BC44CECDF48F0CE7BE3EAE410C5
+:1036F000E2C79E144848827E208806811C4A4614F0
+:10370000A7627937C9A7E41DE64FA2E19B84F08048
+:10371000F5D51F99177C254A1E7ED6712E1ED731EE
+:10372000323FD1791CE6CF4A5809CEEF2C9B9B1C27
+:1037300042B8943A098E4FEDA84C46BD9AF742F52F
+:10374000002C5F6A58279941FF9C6FF0055F19DED6
+:1037500073BD957DC80D4F3EE7835251F5205E2A1B
+:10376000E37BEF5796CFE5CB54512DCB4FEF1E0F98
+:10377000FB4FCFED451EE59B685C1DAE807059CABE
+:1037800040FB42C32FD0A519EA13B4BAD0F6B6F85D
+:103790000358DAC65B921411ED1B9FCC10FEB0F0FB
+:1037A000602BC8F116C1CF90AEEDAC8DCA5641D991
+:1037B0002042299A22695CAE07697E93998FE87945
+:1037C000A2DD3F18E93D50E9FF4518C609AC31B309
+:1037D00026281F4CF8F1AFC2F09DFA808DECB0F3B3
+:1037E0007143830CF0C62EF75D934FF3F59778C7BE
+:1037F0005039164BEB4BEA0D388F8890A4A07E838E
+:103800009146E0737D9D7335B81CBD5C9D8BF09B2C
+:1038100094AF5E8FE581B8A12AD28B9CCF143688F5
+:10382000EA4106747060EA15C90CE0F5195393A5D6
+:103830005EE0A6973EBBE86D8E924BE11480772F39
+:10384000FDEBB5EF770EE9B0E2BA5B2B22437F8E3A
+:10385000F3DD699336239C6B0FECFD11D4EF5746D3
+:103860002848C7CCDCD182EB4915643FDA856CABC4
+:10387000D1AEF99D460F7E874CE326DB81BA4DD849
+:10388000DACE501FCE1EADFE00D777C2CA16B703E0
+:10389000FE4FC46B65129430BF666D3E4BB5711E12
+:1038A000D2EA274CBCFD442AEFAFCF5FEFF7B0560A
+:1038B0001E6BB07B9BA3FC00F9419B3F08FDD3B37B
+:1038C000399D11E7C2FC57EC18B009E96241DB07EA
+:1038D000D6F9D0FE487EC5529C17F643BA5C600EFE
+:1038E0005B53A1FFDA51BEFBF0F90A99A9CFE0FBC7
+:1038F00072D83A13F0D729B03A9C47A7054A78DE28
+:1039000019C74B7D3E8FE44F5F8AF4D039216C4557
+:103910007AD3EB2B58E40651C4BA97BE07F5476338
+:10392000EAEF9BA1AE0EFECF8508E7BEE49BC9DEA1
+:10393000B1E761787E831FE81DF0E2DBF6E99E1FA8
+:10394000C1F3C5488BF07C718B100CB8BFBD3C8BAC
+:10395000B573468D95383F9A7D0AF943FDF1E58EA2
+:10396000B75FFE51345FEE7A7510F255F9AED7D3DA
+:10397000B0EC852F0FBFE8EE9F2F9DD99C9E57A4DA
+:103980004FD980FC196C720AC244707DD41AAA7F88
+:103990006676A520BD7E897204DE6F0699D6817297
+:1039A000D91C94D08E5A11A7DE5B89FCF886C81EFC
+:1039B00087C27D99DE1EB232F237D464D4C7913704
+:1039C0004401FD8D51E5EA00E4DB5B9FAE1880EF1A
+:1039D000BFA7D1E57F973DB795B11AA4A715296672
+:1039E000E64CEE7E4F5FCF0A8179DB7BE167BDFD60
+:1039F000C5FF127BE5F7BA022E57FBB2133FD5E89D
+:103A000077C517A30C76D30AE0079CE78A2F722F9D
+:103A100069377DA9C16505DA3BBDBEEFA4E78F9A82
+:103A2000BC9717101DA9198D80878FC15F423A97E7
+:103A3000997719CABDC5A0295BC18E5E6CAFCD68F0
+:103A4000E4F4EFB795233918E58D59D383309E05FB
+:103A5000C7FBD8E2730BA4DF652BD7F3463B86493F
+:103A60005CFFDDE498457AFFA675166AD7E10E98EB
+:103A7000B1225D7FAF2DF6B9D19ED1F903BE5B5A5D
+:103A800050D4731DCBE36BF7A9D8CDD33114E966BD
+:103A9000056B23390092780AF2C3CD8A95E469B3A5
+:103AA0007474CAC3F0DE52589F88F2749B717D4BC8
+:103AB000B4EFEAF35FBAC538AF65AC83C65DDEDE4E
+:103AC000CF7C73B87FC2E281C7D03F61E512F17548
+:103AD0001C6F1F50C0E5F5E9A28E2742F01D31B1E1
+:103AE000DA8E76C4996D1F1F12319EE0E2F614CC77
+:103AF000FF67E351BE6C13A55699E0D0321EC6EDA8
+:103B0000CCE7EB596C7784D05E89C5930EAF93B741
+:103B1000F5AE87D235BADC52A84E40785AB2DAF701
+:103B20000E44FEFBBEA0901E626A3ECAB566331309
+:103B300070FEA5E1C82DB81E978B4922D49D097C43
+:103B40005CA6A876F41732EBABD8874067EF4995AF
+:103B500076199E67A498BCA8079AA5F9293745D17C
+:103B60006D8660F2A21CBF1E785346BD37DBFC3861
+:103B7000F2BBFBB6BF2F25783139D55686E3FBEE75
+:103B80009B8CED2922CDA762F667857698CFC00B76
+:103B90008E029BD03DDEA4AA48A19FE218BE3C5CE9
+:103BA000C790C3E1E302EA3F873A14E9EA371A5FB4
+:103BB000FF669FA966732F70B8BD80F3EFE874B3FA
+:103BC0003708ED978798BAA9173ED3FB65A4325FF3
+:103BD000FB25F8706B65F806E4D3926AA6F6F6BD8D
+:103BE0006505BCDF97481300FFADA9E18508C7ADA7
+:103BF0005782EC86F59DD93960F39AA8F55DD0E43B
+:103C0000CB99A95CDF159BBD37EC71A27A9084003B
+:103C1000C067C0DC90699EA35B0E8D1CA9A6221C08
+:103C20007479F360C2A326C2E31BC33747C34D9F19
+:103C30006FB3C0C7D5FDBA58B91C3BFF155F080666
+:103C400039F5653EA7E36E7963A6F6C962AED50A7B
+:103C5000DFFD18506803FFEAC1371F4DC2797CFCB5
+:103C600084C86CA427D5242103E505D75B1F3F96A4
+:103C700036653BAC6761A6C850BFCEF7492D080F2B
+:103C8000C9C7FCF782FC98DF1CEBEFB4E59D46BE8C
+:103C9000089819F2FF82234A0B850BC56556FCCEA6
+:103CA000E7F05D11BEBBE06E239F7E7CE01E2BEA39
+:103CB0007961BEC32F505C2E40DFFDDE36AB84F64B
+:103CC000D5C2078CDF59ACC933AABB917E59AF7EF0
+:103CD000C0AF0AC0FE47FE2E66C5C8DFDB1BB6B10B
+:103CE0000F87E37CE626235F8F8305B793BFD361FD
+:103CF0009E1EE55FEBF63F132B7F87789B66867EE3
+:103D0000B9088FEC01F3A3E8EC4F1E8E2FBDFE091E
+:103D1000E8B761F0DEA90689CA970AD4E7511EBF49
+:103D200051E0DBCEE57C64E86958D7CA351C3E9D7E
+:103D30006F6876731D97C73671D56284936D109343
+:103D40009A483EF9FD58CF30811E00B889E22D62B5
+:103D500012E1A98DD3FD5F3D2E94DFAD15EAD33F6F
+:103D600084715B534CAC09F0E46C924623DF3A4516
+:103D7000E66F82F76EFECD5D344E3095CB89EC2731
+:103D80002B4C604EB3515B05013F5F1A0EE4A04A15
+:103D900070C8F18A084B4A0E87E9B96E77A42704E8
+:103DA0005D26182FFD72ABD2E4C6712BF291BF6570
+:103DB00016243A3E83FE3A8CFBF0B6EC64D4E767F7
+:103DC000778CA4925D00B8143334DD81887BD2ED0A
+:103DD000A906783EB2BB3EBA7DBA3008F59CCFCA80
+:103DE000124A419E6F7DDAC4FD513E8F656B4219C8
+:103DF00073501EFEDAAC6C86A7CEDF4FCDC775BA06
+:103E0000CDB280F09B23485CBF68F6D76CA6FFB5A7
+:103E1000ED417D331FEC44A4A70F8520F9BD26B6E4
+:103E2000E3397CBFCEC5F5EC9C2A7806F5394D62A6
+:103E3000B009696AA92505ED41541DBDD98BFDD98D
+:103E40008DB1FD3EB18417FED9D31D373C234446C6
+:103E500070FBCE1FC47974A6B054C4B3AD50B31F69
+:103E600046805C43793E0CF439DAEB267935B6B3FB
+:103E700083601F20FD0812F5D7E1C3A4B6E7518F78
+:103E8000AE3449A487C03E0C24221DFC7EE4665C4F
+:103E9000CF194B7828C903906F02B4CB85ADB3CD51
+:103EA00000B71503413E43FD3B850FCE36031FADE2
+:103EB000C80A2F34417DF5B34FF1FAE8F071ACDF59
+:103EC00051B89DF72F082F4479F060E13E5E074618
+:103ED0006203197BACF04FB30330FE279A9F75C67F
+:103EE000C2E3D5675E18B5391085FFB642AEE73E2E
+:103EF00089E3FD3E71B31B67209E73C223A2E35C7E
+:103F0000B716EAFE2FA7F7252FC6859030F5F76084
+:103F10007C8A17C58E9FA7BDB7A44AD387E6C8B3CE
+:103F200008AF575C722AE9FD13206B10DEF05E2BA0
+:103F3000C0C55998CAE539C02735B7E7F76E463B83
+:103F4000D341DFAB8BD633E3353CB15C3EFE8A8197
+:103F5000520AE2232395DB6F8090943B29CEB189EE
+:103F6000E6E3CCE6F8718A523EF2E9A42AAE5F2677
+:103F7000A5A56D42BEEA6BBEFAF7A668DF5BD2A4C8
+:103F8000C10BC612912EB68FDAD4AAE1372517F1EC
+:103F9000C2F54E5B21B763B13F8D3B18E03BA69B5A
+:103FA0005EF471FB5B67DDFFA375320F7F0FE83CAA
+:103FB000BF55EA5E871E27FAA4517BAF549F874CFA
+:103FC000F4BFE4C51F6CA0F8B824A78A649FDDCFB6
+:103FD000E9C61E29C438FC2B17720BD0CF5DAED9B1
+:103FE0004382FA272BDAA3CBD77558D12E5ADE2E6F
+:103FF000A8681775F3997A6B345F39B3F93A9DA2C3
+:10400000EA6C22FE837912FFA9244F62E9A50BDE38
+:10401000B17CDB633C39D5389E4CE3F58587BBFE2C
+:10402000D17868EA1D9EFA3CA17F8051FFECCDD487
+:104030005FE73F7717FF85505EC6F2DF1D5D788B27
+:10404000E15BF737FC5E057F6FF90F007F1827965D
+:104050008D74BC7CABDB343FB7BBFFFD5BB2A6A36A
+:104060001EE88ABF6CDD1D401DB472C7D30CE37C13
+:1040700096352017518FEC14839B01A49DD0AD057C
+:10408000E5C1936E8A17ACD5E4CBDA9448924071BF
+:1040900020D184F67024DDDA8241C9481C3C87F7C0
+:1040A00003F0FCF1A875D7B3489205F1B04314F0C2
+:1040B00079B3FDC38C63406FE6B89319C7A2FCE0E7
+:1040C000E6442D5EE28A24A544E1D7F37B3109F76B
+:1040D000F3C241B08F7BB167196B22BC86196F9F09
+:1040E0002C5EF81DFAF96703C34C18873B6B8FFCF5
+:1040F0000EE37267CD39A901A99B6F8E05AEC8A8E2
+:1041000087DA5F99F7D078D46B01D59A09FAF1264E
+:104110004D3B2E7EB52909ED0831D1B3F745787FA7
+:10412000A10BEC3DA5A79D7633F32687DC3DED3151
+:10413000C08315E3D08B7C0E3FF93F1B8DED37EF2D
+:1041400038F9678CDBDD1CED8FC1383E2D9E1D6B71
+:10415000B7BD5FA8D96DF92C1FF529A04741FBF029
+:10416000EC4151696564C7DE4BFA721FD8AD02DAC3
+:104170001B22E1EFEC934210ED0C1648277B50B761
+:10418000E356321E7F8AB5377AD823CFBD57FC233A
+:10419000E8B2ECF977F31E86F2D4F3EF8C7811EBEA
+:1041A000FFFBEDA1EFB29EFDAB767D7903E9E15D0A
+:1041B000369A47E7AE3F0C453BA373BB4DC14977E9
+:1041C000AEB151FC32B02B31381CDB8770BC37EDFF
+:1041D0003C9F17263DD34CF889F35809AF6777FC0D
+:1041E000FD7DA4ABB33B6C32AE63E5AE0492F12B24
+:1041F000B7C705D15EE9DC79BED8174517DF763D34
+:104200002BACDC6FEA047A7C86CBE3A1F8FD15BB0E
+:1042100026A491BCDCBADB8A7E62D5EFFF332F8CFB
+:10422000FD9ED96D656348CF3CCA803E9C5BCF3F05
+:104230006401FC9D49E4FABF7D6BE97581DC9E70E9
+:104240008171CF60FC74E5EF13582B87CB62F4EBE0
+:10425000FA82C7E5FFA4F0E8B4744C198474F7B48B
+:10426000501890A3E122109E97ED480CDA055CFFF0
+:104270000B49D42FCBEC074A00389CCF437BB8BF07
+:10428000755F89EB2EFAFF60DD26F6B5D6BDE49F9B
+:1042900014DF3AFD7716723D12CB073DF9FF7FDF41
+:1042A00046F5DF252A34DFAFC8FF77FDCFC77B1E79
+:1042B000FA6D5F17EF5BFE49D7DD3FDE5FD5F09EFD
+:1042C0002861DCA473E77F0EA5F57EC575FFE17F4D
+:1042D000E8BA3D2C7203EA79A7B61FE3B40FA67DB6
+:1042E0002486F124B23B25667262D884B5935DE7DB
+:1042F000359FEAB21F28FE2985500F34AD4AE2FBF4
+:10430000685A7E486C1C76FD4EAF05E1EB03300920
+:10431000E3C15E9B760DD5A739982AC0B8D398D74C
+:1043200042F17000E7E3647F7B3B1640FD75CF7A76
+:1043300017EA178B203753FB5421F838C54B94DD0F
+:104340000950BF7A4D662ACE3BAD96599C589FE1E5
+:104350005644E8BF9F450ECE443EAD1395C7F97451
+:1043600067ED2B666C26FF7F764DE2AD9313A0DFE1
+:10437000790FF713AF2E6AB2A0BDF4DD26AF1FE3AD
+:1043800079570D8D0C4B898ACBFDDDE3E6FDCC5EC4
+:10439000CB2A787E35CE34B527BEAEC6C1E1F9D57D
+:1043A00092D7E2A73887B64FA58EFE46FB5463AD81
+:1043B000DCBE5F5A6B0B62BC72A9A2BCB714E1569B
+:1043C0006B93A007ABF4CC1B827438592C7FE4FBB1
+:1043D000B0DE034F82DC82E7271F7A7330FA418A0E
+:1043E000E7F62948BF0B0549247F6A9AC09E83A53A
+:1043F000CCAC9DB71FC79DF6A420609E9D45B3DB46
+:10440000B28A383CC42757EDCDF4205C53942BA0DE
+:10441000A971828DF6DF4E3E2404913FAA6A7D7B0E
+:10442000313EB5BED426D9085F6A12DA9F376BF0E9
+:10443000FD9345797518F6FF778BB246C62741EA9A
+:10444000BF18EC50F4874ED6DE6FC5FDAEBC229986
+:10445000D699E699571C92715D8D3F23F20BA80700
+:10446000720DE3F9EE298B1AAF71C2AF68BC4399A4
+:10447000602F02DD9DDCD03405CC72B6902902DAC3
+:10448000858B36CE6BF93EF45F02F3C3B8C634A613
+:10449000DC872864E232E2BFD8FD063D7E98E63133
+:1044A0003E5FFC98B1BE10FA2414E0778C766FACB6
+:1044B000BD5B5EE4E8CE5318D93D3E43222DEB8927
+:1044C000FFAEF8A49E6FA1E1635BA9588372676C8D
+:1044D000AAEA8BDE975A5AC4FD31BDDCB6E36F7F82
+:1044E0005E8AF4EEB129388CCA52AA31FE377B714C
+:1044F0008507C9A9D29EFF0AD6E7F8A12E23BD5B86
+:10450000E8BDEBA50F26A740FD4697B017CB79B2C3
+:104510007B4A2A948B8BB8BCB829A7622F5004AB76
+:1045200055A65B7DDC3FA944797616D68EF1E66D03
+:10453000E10383A3E5995E5680B03347F90B55F646
+:1045400038668E82CF6429C550BFC29569E83F5551
+:10455000761BDABF9333CAD05EABE41BDA9F28E246
+:10456000FBB74F157D547B0BACF3A932514210EED3
+:1045700047B838BBE1B2BFEC7C25D2F1EBA3BC1647
+:104580008C5BEBF35D5564D6F67FB91FB5A48BEE5B
+:104590003AE6E278EB37894477AF173DB87701D236
+:1045A0007126F7A7268B0E92EFEBBD9C2F1631DFFD
+:1045B0005E15CAF5CCBF17E5CFAC0A7B04FDB65833
+:1045C0003A9A817E9780740CF3C5F761BEC8B70B29
+:1045D000371AFB3D5534720F7EEFA9329B84F1BC34
+:1045E000593171F21998479384A5F1792C3DDE5326
+:1045F000A4F95F5ADECC5302F7BF026F71F9D89766
+:104600005CD2E93296FE9E28E2F138BD04FF2D19F6
+:10461000E5D058ABB19F5EBE037ACE0CE3BCDB6045
+:10462000A7F2BD0689CABF34B8A8FCA041A6F2C350
+:10463000861C2A9F28E271AEB47AC073D43E485AD1
+:10464000ADD77A293EEA96A7014D7E468E207CD3CF
+:10465000F6F3FD2D9DAFF438761AD6A3F2B5A6D5A4
+:10466000BFECAB06BF7E7F91169759B0690FEA4346
+:1046700098422011DE67CB76EFC1F85357FDD60F75
+:104680008CED77087B0DF566B7B17E77C5DEE8F770
+:10469000FB9A7F5AAD6CF1811E9DF1008F63C5B608
+:1046A000EBF37BBD51994DF117A72AE37E07737A8F
+:1046B000687DFB35B9D0175C66639E218C3BAD529B
+:1046C0009917BD6F795883FB610DAF3A9C99A2CAC7
+:1046D000D1F93DB1E3BDB368AC05E3303318DF5722
+:1046E00099B583A5CA63BBFB7DA48DFB4EB26F3227
+:1046F000E591311EAF3D342D63736B2FFB087AB902
+:104700007EF6BC2159305EA5375F40FA4A5B709552
+:1047100005F7CB0E4DFFC084E5D82C983F8C77DD94
+:104720004579C8F428387DAECDFFC04F8DF136BD38
+:104730001C54CCDBFF6CE279377F4EF20D996D781B
+:10474000DF4EED8712F9FB63CDCC2C1644D10D2E34
+:1047500000F4CC0DB54C45F97CDD4575C88CA8F747
+:10476000C562BEDE836BB9BD88F09917D53EA198AE
+:10477000E3478757ECFC261473FCEA7AF7D034162B
+:10478000E4FB794A23EAF919A0D7D0DE02F9437C89
+:104790007CE8A0A8D808AA5C0F2FC2FF05FA3A044B
+:1047A000FA10EDBB19F31C7ECC13043D3A04E1B5BD
+:1047B000A86E512DC66F98266FECF00FDA73F921B1
+:1047C000738C9C32CA95B47EE44C56B151EF4DCBFC
+:1047D000E2F4C572813EC774D3A78E9FBEE8E9009C
+:1047E000EEEB59BAD777565B5F5FF0D2E59404F6EB
+:1047F0008519F857D1E0CF4435B718F944CB671A7B
+:104800006B6171D1769DA2D1C1D80ABE8F3ED6C24E
+:10481000E5C5817DC30B6026EC40CDB9548C43EADD
+:10482000F8ECE2CFFA26DFB0A8F8DFFAA9B63AA48E
+:104830000399A989B8CE03DEC2B80A47379ED77B51
+:10484000CFA5B228B905CBB8243FED0F9B48EFEFB9
+:104850009FF839E9AB13399249C8EFCE0B995A9CAE
+:1048600042FD4E947EE81072510F1F7520FFCD66F9
+:10487000410BCAB3392C6441FABC9E85A97E231E24
+:10488000A188CA1FB989A9143F4B96BC54EEC74FE3
+:104890000FC4CF17CE0945D1699EB69F3A1653DE95
+:1048A000A3ECDD7B34B85516A97508DFB1A91D4707
+:1048B00050DFA54DB43094B32AD01DEEFBBC5E543E
+:1048C0001237BF177C8945F3E71547C9A7B45A9F2C
+:1048D00015FB3DA5ED9353E23A8C67CE1866900F19
+:1048E000CB343C1CF1A88B8A697FCCC9E539F3BA7B
+:1048F0002E05CFB1A95C4E609E3B8E9B96239B5AA2
+:10490000A3F47F4BB171DF77ACD56745BA5DA8F8EA
+:1049100069BFBD72637E5CB817392216F97E589C58
+:104920006E5C07B793B83EEC4BAEE97AEDEBEA4527
+:104930005DFFFDB648BD13D76F36F1FD44736A9D28
+:104940000BE1C7A459441FF7C4D06B2C3CF24A3F7B
+:10495000BCBB100DED5A93321CF095B74D7E0FFD88
+:10496000A9F581D912EEEFE9FDF7D71E7D6918F49C
+:10497000DBBF8D4902F45B5F5312877277BD233032
+:1049800014E1734250E27E88F6D5E3A2C4FDACC8C0
+:104990005CA4D745B5195988B7AB261475A850FF44
+:1049A000A8D65D8076E86BDABC3E661CBF012FF7A7
+:1049B000E74E4CBD73288EF37AD18002FC0E132F84
+:1049C0003C702BB47FBE514CC5F70E79165D7D0B44
+:1049D000941F3D26D27B1FD5B8292E3C593CE2209E
+:1049E0003F5CB3DBAED5E4DEEB4CDD83FEC20CCD29
+:1049F000FE6A9C70FB1EF4273F427F01E4E03573A2
+:104A000063F38A1401FDD6995EE3F3B48D1F1D4153
+:104A100026E82907B9DDD59F3CDC596CB4BB62E5BB
+:104A2000D9C70E1EF79FB183FDDC970C76728DDB24
+:104A3000721CFD907A81E843976B336A95DD683785
+:104A4000CCA899576887F525074B04F4EFAA6AE5C7
+:104A5000C90930DEB41AA118C7D3F136AD6615F90D
+:104A6000F7D336AEB2CA89C82FDEFD48A76693D702
+:104A70003B0EEDD48DF9AFE27B63027184EFABA600
+:104A80009D3521FCD76FB54A02C0677D706422E274
+:104A9000F9C063E79CD1F929DD7CD166C53CDDCA4C
+:104AA000C73E1D887CA1CB8F45C5A31EC6FDE24035
+:104AB00025CBF1131FBC3694FC85C1E02F80FCFA96
+:104AC0006EE9EEA168CFDE047E3EDACFA7861C3702
+:104AD000EF87EF86AAEC7E56CAEB791E3AEA15619B
+:104AE0002EA8677EB111F73F9A9A4020C018DBAC20
+:104AF000A1F7E779305FC9C436C3FB1322CCE017B6
+:104B00004CFAC26EF00B2A98D1CF58163EBA15C790
+:104B100093D6D8A4E4C1E89718FD8EC9923BC62F5E
+:104B200031FA1DA75EBDD08CEF0F37DB259CDF541B
+:104B300039DFD0FE9D9C32C3FBD359C44C7EB7CC29
+:104B4000F36BA62915C6F930C982F0B1A85224002A
+:104B5000ED57954E358C57F85A88F26CD2E07DCCE3
+:104B6000F3986EF71ADFAFFF1BD1C9F8FA0BA4F761
+:104B7000F243ED86F6C27DDB0CE3291D52159A89BE
+:104B800005879597B13C1FF75D17E6F7C902F3B3A8
+:104B900089C05A616F15E689149FF0BF8C65A0D259
+:104BA0004F79E10180179E8F7A30E1C794375E0F0D
+:104BB000EB473EBA5D64947771DEE45B8C7A4432F5
+:104BC000C98FCC13305F50CDC0F251936F68493A12
+:104BD0006E0FB65561EEFFF80BC1262CB77694AF79
+:104BE0001B87F146C4338CBBCC61223B77B2B82320
+:104BF0000FEDC2B34F261446E751E9F975CCA5BABB
+:104C0000E641FFB5CE61051817F25625AAB85FBE7A
+:104C1000FCF9919B31CFE55C59451E7E4FCFF36384
+:104C20004EE379927365EA00CCFF395021925D150D
+:104C3000986C21F9136F0A4A3C6F83511CD47A8512
+:104C400085F2A89F2DE1F2EAC0AB002298F881140A
+:104C50006E0F16776459A2F9628666074E29D1EC69
+:104C6000664D7F4D4F3FF824EEE33F5B9248CF8B7C
+:104C70006BE53D16A407C92CA13F9A76D82B8D81F0
+:104C8000F1B63A3DBBD14FD87AB86302CABF674B81
+:104C900064EA3FA0A6E2960A94D3396686FDB74A35
+:104CA000D509D83F6DAE628AC771F65982C3619E3D
+:104CB000AB27F0B8F4EA0AFBBFA35C4C3BCC089EE0
+:104CC0005BF1E024F2F5343BC58F9859715F3F06E4
+:104CD000F3C901E797883B1E6B4B4F47F932BD4242
+:104CE0004A57B0FC3791DB07948903E363EE1FE674
+:104CF00088B067DFAD86F62D5D751662006FC9CA94
+:104D0000F4FE2C0EEAD385AEFE73AAD19EC8EA6AE1
+:104D10000F20DFAF17F4FA73D49E16335EF7F8CF87
+:104D2000BD7B82E4BD941E7D0E4D2F9F2D61A4C7D7
+:104D30001798FCC5488F1F99FC23A814642ADF1B11
+:104D4000EE5B5582768323B2FB22C0EB9337443A65
+:104D50004771D985AB280F1AF4F6131B90FEAA2DC4
+:104D6000249FB75AFD7F7BC789FBC4F1949F64F9E8
+:104D7000C5D2C843809AAD66FFFB3F407CD58E50BC
+:104D80001AE1F90289F3A1AEF717895DEB53C1B4BB
+:104D9000668BBAD7A3223F7E64EA6EC773B952D43A
+:104DA0007AED509FAFD70307E71C0378C80BB6E432
+:104DB00060BCEE1C73501EEEB99C2BAF417C9F6B08
+:104DC000B3501ED656C6F11C70C5071F0758EEEF2C
+:104DD00030A9C8470167FCA6E154DF2C65C138ED56
+:104DE00080771516961D507F8279E2E73A4C26DCD3
+:104DF0007F3D573EA08AC6BB83E11E2D5B10B632B5
+:104E000019D6539CB340CC8AF60FF17DA01B719C40
+:104E1000FA6009E5F1E8F1CD1F7EBDF8A6396225FB
+:104E20003ECB667ECC135959DA988B7A7665B5F00D
+:104E3000810DCBFACF489E596DC1E01AA4FF17E34C
+:104E4000781CD7A10E9D1E65E7E594717E9B3052BC
+:104E5000CD29C37CB2FA7384073D8FFF94965F021D
+:104E600060A27312CBFE4BBC11FD44903BEB84025D
+:104E70002C5FB2AE8E5A1F6BFFB44B7E8E35F56F32
+:104E8000C7C5FB6A699ED305E96A067686F4C2F057
+:104E9000B9985F353D4EBA1AE33547B6A5F0FA101A
+:104EA000E96ACCB73A5FB2722EE6574DCF94FECD89
+:104EB00004F233B36C1D6F774B6F615D2A5DC7DB06
+:104EC000F3A5B7703FD65CB6666EF540B21BE8BC82
+:104ED000E8D99A38F203FB9ACFCCFA170DF1921E5B
+:104EE000EDA2C0E5681D974FA7A766929CD3F35A21
+:104EF000969B24CA6B39A4C9BDEEBC1626615ECB55
+:104F0000E9BF762C3451BEB73219F35B96F91C1405
+:104F1000F79F59BF8BBE7BC0240F41399A58EE7B57
+:104F20000FF96CB929FC3EF2DD9BB56F66903C969B
+:104F300022C3102F93C5B90192F35ADEAA25E56763
+:104F40001654FAD780DD86F1B3158A4C7ECB4C24FB
+:104F50009CEC9E72FCB20B9D7BD7C3F76F7D41909A
+:104F6000907EDB1B40EF012B3C037E2396EAB6DDEF
+:104F700087316F64764C9EF9ACBA98385CEDA5F336
+:104F8000CB553DEF3BE69CF3B523D58D486FB399E8
+:104F90008FE6D9E33B8E61B49F10FBBD992C44FE94
+:104FA000577FDF3D93D87103F006B368F85C9EEA43
+:104FB0001EAEC1D55E8AFA4890C760DDE2ECC8E05B
+:104FC000FEC69332C133C74EFB96F1A30FE7F97AC1
+:104FD000A1DB5838DD5EC6E5E50073D8AAC0382BE2
+:104FE00034BD31595C268EC1F1B6B959B45D9955BD
+:104FF000CAFDA4E46D3C2EE5CC06BA71227D84EE98
+:10500000A0BCA75C4E2FCB4DA1C1484759A589D460
+:105010005FA74BC0BF961F06EDF9981F047404FDEF
+:1050200027DDF49AD2144547EFA31C87756E8DE7F0
+:10503000722DF25C1C9D8F8F9D6769A9A0C51F8D85
+:10504000F32DD19E7FD579969472FDFC4DE7A9CBC7
+:105050001D1D4EBADC619A5C9E5DE7A6BC44BD3E58
+:10506000A3D64D7EAD3ECF9EF4F398DC1BFDF447F6
+:1050700037BF2C9178DC52937FFABC7439B655CB8C
+:10508000D3EF9E57CA26E3BC52481E24D7BF4072B6
+:105090004D4C34D3F35939AE4DB84F94DC7196EC86
+:1050A000D16499AD423DB1B0348BC3B9FDCB9634D8
+:1050B0000F3EB70828B792EB77D0FBDF96FF7E89CB
+:1050C0007650514FBD30010418C969D43902DAFD58
+:1050D0003E839D5B81274CA2C6ADB2AF8AD97FF8D3
+:1050E00081A1FF15AE4643FB54F9AE18BBFE3E430B
+:1050F0007D9AF290A1FF55A59B0CEDD3ED5B0CF5CD
+:10510000F27007D9D5FB1B6AC88F9F782242F675CB
+:1051100048F3F75FD2FCFD57D0DF07BEDC8BFE3EC5
+:1051200094FB1A147AFEC786522A5F6B50A9EC686A
+:10513000F05219CBCF9E8EB007F3954A9DC994DFEC
+:105140005F59EC7B06E545D9C1C83094AFE38F04C5
+:105150009BD0EE5FBBBBCC64C538C86B62300EED34
+:10516000E6F292E4DECE21E865F2172253A3E25D77
+:10517000C9B511A63AE83C2FC587A63B8E5553BE4C
+:1051800062BD2424834CB19915E681FA509FB42A5C
+:105190005086FB583C0EE6551BC9DFB906BAE2FE45
+:1051A0004B9D1DEC3B986FDD6221D844F1CD00B5DD
+:1051B000CFB1EBE779F8F9C0AB3512AD63DE3D94C2
+:1051C00023EB67CADD30EE33FB52ABF3918EBD4269
+:1051D00010EDFFBA3B03CBE7D138FAF9C03F9B2E65
+:1051E0005EFED5ED926D608B223DAF15148A5B0497
+:1051F00052CC6477C4DA01F7941AE3EB57A11D90FF
+:1052000086FBC7DCAE89B8997F734A37FF4D97009C
+:105210003E68AFD7CB2684CF32D62826A1FFD32134
+:105220002B4D40E265C7222D69D05E846A4FEAF6B5
+:10523000EBC69D884CC19069B16A8FA0BFACD33FCB
+:10524000F8492FE3FB678F30C506EFC74FBC4B44CF
+:10525000BFAAEC33EE5F4DBAD02EA2FCEFCF1FD425
+:10526000E7BFA3A18EE86757838FCA50C3628D2E14
+:10527000FD547FA5A19EEA7B1B0254EE6B58A7D17B
+:10528000651BB5BFD6B081EAFB1B821A7D6EA1E714
+:10529000BFD4E4E35F4AB5F395F60A8A7B32332F35
+:1052A0004DF6402C3DB0687A58E6E2F2383E95F76C
+:1052B0008B077D10F80A7401029CE8620ED005CAC3
+:1052C000B7D9ED4D63D04E670B0245FC1CF337A3F5
+:1052D0008FAFABEFC14E52900FC08EF1A39EF9AAD3
+:1052E000F2DB86C4ECC473230E82C3D7FDAED5A611
+:1052F00050FCB7FFEF71FC9812E652DEFD72133FCF
+:10530000CF73BAC82B211FE97E740FB8C4D86303CA
+:105310000A98A6C7BE367C2C888FFEE6F95E993ABD
+:105320001CEDAD2EFDC68232CED77AB99DB5521C8A
+:10533000F0C2EE8B681F77588268FFACD8FE4EAF84
+:10534000F68FCE8FB17273A5748EF8EA9460EAF589
+:105350001CDF4A13F3617E4D818DD98554C61E2D05
+:10536000AB2CC1F94C16CB3B54E443C9AC44DB49EC
+:105370003DDEAFFF94C6EFB3DDC4F37856EE2C925A
+:10538000A2CF23DD5EA6ED637CC3FB252644EA0C99
+:10539000FCFF4FA727D55F1BDA190B7B90EEAF738D
+:1053A00072F97F956F2AE16B366B277A9ECB3AA80C
+:1053B000BC8145A8F4317E3E683E53A85CC0F87EAF
+:1053C000C6118F6F7919C63BAD5E8AEB5CF5FC495F
+:1053D00007EA3F31E5E099F5ACA7BCFBAAF24D978F
+:1053E0006BBA9C6BB16AE7FB53ACC43F96F454B202
+:1053F00093747C349419F5442CDF74E673FFA6F3A0
+:10540000B9F126BC47AAF3753128707BEC15CAABFD
+:105410002AE0E74F0BE7F2FB97E0CF3F9CF26D8C61
+:10542000FEC8B9F26B49FF9EC3842D948F6625E7B1
+:10543000FA283FB949DBE7DC02E5D330DFA4B961E4
+:1054400073F43D530F697E74C5EC6A867ACE3C577F
+:1054500065B85F9524F1B8D6643BF3C4D1FEE7B9D3
+:105460005C1CF7BB9A3DD06A6121E48701A5F90273
+:10547000DA0FE017FD1CF9A2EB7C3DF8B2172FEB19
+:10548000592F1079BE61642AB7EB63E9F837DA7CEB
+:1054900096697CC17C7221C2B753900B34BB80E407
+:1054A000E3CA2B47911DFD52997E3E21A0F903E5E9
+:1054B0006B1FE6FEA51FF3834EC5F57E3EF7F9325E
+:1054C000BE8F36D3FE99C17E5F51FFA5815F57E441
+:1054D00072381434C98598FF758BB60FF77981F748
+:1054E000055CEF92FF78D23A48C6EF6EBC0DCF83D1
+:1054F0009DDDE720BDCC5E4BA735EBF72AE8E3CD79
+:10550000B47FCAFD0CED5C87FEFCCD696F93DC4275
+:10551000FFFA450FFA798CF2EFF5F91D30751C7F13
+:10552000D8DD2DC7C04F7CFF476E945BEE9FE03DFA
+:105530006891E72C14A75A86F34F437FD1BBBF8CE9
+:10554000FC0146F18303578E243F44B7673A3FEE90
+:105550007D7F5C9F9FFE1D7D5EA704C100C77735E0
+:105560003C959471B97C3A49B91EBF73FAF9412848
+:10557000FABB9EBF99D29187E722BEAABEFFBA7638
+:105580006085F3E5243CBF3D6B8140E709EA1605E1
+:10559000C64814CFFD667AFEABDECF02C674D00AD1
+:1055A000FD05C7A1977DCEEEFB204CC83C30BF72F5
+:1055B0009795EC0F1B8E27623A64D085A57E0F84E9
+:1055C0007EFF837EEEE50F42B889CE3BA88A0BFDB5
+:1055D000B7B5CE4AF2EB4F30871FE3DC57A7D44C68
+:1055E00080CFB3D90BA7FA901F663525D1FE8DD990
+:1055F000AA9877A3FD7D25DF4F7B66DF1AB243DFD4
+:1056000052F9BE810E3F3DFFD19C129842F6FA75C9
+:10561000809241B8CFA0503EE635004FECFFB6D99E
+:105620009F9EEBC6FDA907F2F09CF7123198340655
+:10563000D6F1C981DF14BF0EAF9D6421AB03F34BDC
+:105640005F09D37D032BBFE6BEF3F7301354C43C90
+:1056500085B64776C3B8EF64FCFCFBBB59371CEA40
+:10566000D45FFC7501D496A63417E3F8FA7ED2F91C
+:10567000B8EF66EC8EDAAFE86F7FE251932F6F5C84
+:1056800011DE9FE02FE1F714F0FB6B805386E23EC2
+:10569000D278180AEFEDEB4CE77418F89411FC3A45
+:1056A0002D0AE9F5C0E732D9FF9E2A13E1935D94F4
+:1056B00029BE3A3EE6FE05CFE5267A9FFD5DA6F7B8
+:1056C00027448C79149EB1F78BF4BE28B3C7319E62
+:1056D000F085F992F6CEE9719CAF3C69267FB4BFA4
+:1056E000DEE4CAE0F13AAD6E9325F2DFBFA7F767BB
+:1056F0009133B213EF6570F8715DF037CB5E4CEB10
+:10570000247A1DBFE324DD73B35104BA405F87B52B
+:1057100057E138E58077CCCB14543FBF97AE9E312C
+:10572000DCAF8ABDB741CF078E53593BF265ABD092
+:1057300021225C2782D988A5CA24D267954CA1B2C0
+:105740009A79A99CC2FC54D6B0362AAF64ED54D6DF
+:10575000B20EDEDF9510C07367E3989DE2F1E57647
+:105760004529A0EFDD21513EC9D445268C2F7BAEC3
+:10577000E5794BFDC1E34E0D1E2E8487E79BC303E5
+:10578000D78BFBAE53B4FBCBFE51F0B8820588EF4C
+:10579000A7B22095DF61211EE764F22B98E73CED6C
+:1057A0000423B9C14687481E94867D66AE1762E021
+:1057B00051A5D315638FA790DEDBC0CF8F0D48B105
+:1057C00079901F92E83CF7D657D337A15DFCC238D9
+:1057D000AE278B59CE83E5D05EB4CF0296349EA31C
+:1057E0005729DFE66CD4B92C90586CDC8260931D8D
+:1057F000EA99EBF8FEBFCD65627214DDC6C9F14CC3
+:105800008EB2E71272520DF512166C2AC77804F8A0
+:10581000AF21500589CA40C3FBC9A55986FEDB5993
+:10582000BB48F250CBFFD5E56C8A3ADAF01E5862DD
+:10583000E272C4B7964F9C5653606CFF8CF35729A5
+:10584000FC83781A77CAC86FA5613FDDA315E7030B
+:10585000B90AF38A3B68369C6FB3398E1FC173FC5B
+:10586000B67EF6F7E78CD7F6F707B3C15C6FB45195
+:105870009E758BC0F5962EF75B85362A3D0995E718
+:1058800064F8DE5BDBE75F8F717E4F61E52DD950F9
+:105890000F6F5FCEEBE32B9FCD82FAD1EDFEEB7164
+:1058A0005FC033B6B2D002EB6B6C5C757D35B4670C
+:1058B000CB8A0BEF6338ABDDC7D0F4C68FE97E012E
+:1058C000B0C12401DACF3A6E5324C4DF60878274FA
+:1058D00063B7011F79683BD2DF5886268B9FFA0396
+:1058E0006348189749ADE1F7110C65FC1E81ED0D79
+:1058F0008CCE236C1A2F13FF140C08BD648171D257
+:105900004F0466E3FECC9D05DEC3E3707F558671D0
+:1059100060DC87257E8FC1A6F19A7FEFBCEF659F83
+:1059200007ED3B4678F9B0C0FB1ECADFCE447B00D2
+:105930000314FAB85B347BB4CCDC26DEE2C0E78C1F
+:10594000E8B2AFD2315EFD2B7E37F63953253AAF40
+:10595000D0A4F3E76289CEFBB397383F769D4340EE
+:10596000BB13F8AB6C812A0299B3E23AFFCB58AE75
+:1059700014230B112F9F8FF39DC3792EF79E199A35
+:105980008F76F95FADFCB23A3698F31BE37279E596
+:10599000AE2FCFE07D203B4D202FB83DEE6551F27C
+:1059A00064E5AE3833D2D5CA4F5830C18DF2E5D751
+:1059B0004D68C797817C61FCFE8397D1AEDB710B8C
+:1059C000BFDF6AE5EF77BE8CFB28E5DF89A37C8823
+:1059D000096F1EC9463F65D29130C5E93A77BE3D91
+:1059E00088F3BDBECF765EF82676CC64F18E7B5010
+:1059F0002EAC6E34333C57BA5AF0F3BAC52EF1735D
+:105A0000A51D2D73D19E063EA5731C5A1EE1626D25
+:105A10005D30CEDE32E87F1AF90DDB83DC5F97E183
+:105A20001F9283E2053A2FFAB9C64F258763F55BCB
+:105A3000642FE6E32CD3EEFF88BDD767653FF9F40A
+:105A400023743E1BC2867CC37B3FC68C4FEFBEF7E0
+:105A500063B2E820B9B8FA91ECCDB89FB6FA915B81
+:105A6000886F560FC92D40BED1EF0161216934F610
+:105A70007B4AE0FB94EC81938C617EA536B725EBE5
+:105A80000426639C3C5B64A5E0076D7AE2FC7CCA5B
+:105A900087429B10ECC0A6B5FF87EAC880B6717438
+:105AA0009E83ECE7A7522259346E8ACC0240B74D50
+:105AB00071912CD423819D7685CEB76C4C239ACDE1
+:105AC0000E281BD0BE59DDE81490DFAF1BCFE5B721
+:105AD000FB702997F360E7203E56278EA0FBBBFAA8
+:105AE000A20B0FCE33CABFD9FDC6350968FF3F6789
+:105AF000F626607EDBD98359978CFF168560419727
+:105B0000885F780EDEDD81F9509E0D66824737DDB5
+:105B100019F39DBAF5118FD314B361063D74165F66
+:105B200025F9C582E83F749F8B003D82F61AD2A703
+:105B300082F7071BF5D0803AA31ECAF419F5D0A04E
+:105B4000C546BD33C46FD43B97D51BF58B3B60D4A2
+:105B500027D9EBC619FA0F6FAB34D4476EB8D2D041
+:105B60007F547086A17EF996EB0CFDC7B4CF37B495
+:105B70008FDD76B3A11DAFCD42386C0F33F673A421
+:105B800087187D981F5A6DEC2F1E217DF8B976CEAF
+:105B9000BB70DF0F7BD58701F8A7377DD814F7637B
+:105BA000D287E1790EBF308EF46308E5789C767E6B
+:105BB000A6877EEC472F6E1CAFDDD3A9E9C5CFC108
+:105BC000B343B916AB0F63F9B42FFA32255CB86151
+:105BD00005CA2791DF3F02F2FA2394D72B4DE1A1AA
+:105BE00085F06C4DC2FB561FE7EBB5B91E6D5F1912
+:105BF000E0E075B8F6A01D2F55DA23B652A4BFA178
+:105C0000E4E778B3991FF3D1CEC7E55990EFE446A6
+:105C1000214297DAC4F87B82A3FE57C8671B9B001A
+:105C20000E83315E653CD732B3C678AEA5BF787BB4
+:105C30005147C850CF3FC84494F345C7E4A644F841
+:105C40005EE1119E2715EB677AC2BE26DC2F1A7F14
+:105C5000AAE3E500CCB744BB1FB134A2C7FBFDBF2C
+:105C60004039311EE401DDB7E6EB24396595F8FBD8
+:105C7000C0773968C7D6B37805F9EE7691FBADE702
+:105C80004D3EF24763FDD3A60A2FD9A560B70F4654
+:105C9000BB7477BEEFF0F8743E19A41351BB7F7448
+:105CA00012FAAB042C7E0F66A710198A790F26F61C
+:105CB000E9F53598DFE26452B818E374FCEFA8C048
+:105CC000E376672A06593D72377ECF8C573F1C0F0B
+:105CD000F8FC50D3EB03E6B6D3BD0ED78E548F8DB0
+:105CE0004FEF3F0F23369EBBB521446542AE22A243
+:105CF0007E888D3F9DC4C994D1B849246FECACC354
+:105D000046F75618EFA30C9B3AD6E27E5A6075927E
+:105D100082E7122B9CD9749FC5DC7A1E6758EA3A39
+:105D200045F18AF98242FE2C53B91E112FE3F793F5
+:105D300074C71F06895F476FF7B7DEA5AE8F0DF1F9
+:105D40002AF624D7177D8F1FE0F7D475AFFBD15B00
+:105D5000399F503EECD1A9832AD1DEEDF99D331451
+:105D600007BBDEFF8681AE6FAC7FC740C7F3021F63
+:105D700018DAC3CE886510D045F8F9CC2973008EA7
+:105D8000A79FB3D1B9BB33E37D7279543C343C75E2
+:105D900054357EB7FFF59EA4791C69E820BCEAEB78
+:105DA0007DBFE130D5C30D612A63D7ABC70DF4D2F7
+:105DB000FA12BFF736027610DED7D45FFCE0C5F2E8
+:105DC0002CA2C7DB45F57DEE9F858660FEEAF916BD
+:105DD0002670FF3042F7E0CE159214F42F5B32F7B5
+:105DE000BE877185B74CC92487D9E2D07B98AFB8FC
+:105DF000B295DBC34C0D3D82FE5D675212D59FC943
+:105E0000F75597235FE56AFDD24CDCBE728686D0DB
+:105E10003D5CE9780718DE2FEBBD82FAE14D6D306D
+:105E2000FEE254F04F53F0FED8401EF2DBCFCABF63
+:105E30007303FA0B27E20367300FE99E1D53781DA9
+:105E4000F3F028AF6CD2A321B423D530DD93F396C1
+:105E50004924FBBBCDC2F75F232F089B300ECB1C20
+:105E6000612BDEC3B276943A13BFD7D77DB0379497
+:105E700073FBE8C672BE3FA197CBED3C1E74FFC614
+:105E8000ACE9C80FFA7D2D092CA20EC2BC9E6DBBD9
+:105E900019D2C18FCB399F4F16EF1E41E7A56B6D0D
+:105EA000745F1DCC4B253B68978DE228DDF7E03011
+:105EB00009EFC17166CBE7901F9D22A33C8C55E58D
+:105EC0006E9E5FA2C5475998C7394F4FCD24FF1921
+:105ED000F3BE28EFFF20CFEB3C3D95C78B1112B8E6
+:105EE000FF3DE3797E5FEEAA721E2F58FEEAD1F7DE
+:105EF00071FE89E5BEEF239DEA7936CB58C771293B
+:105F0000BB1B6E36913563DCBB3FBAD5E3A87AFD87
+:105F1000CD6977D2EF3F14601E562FF6DA83E5DCA9
+:105F2000BE3B626131795AFABCF53C2D7EFFD0331D
+:105F30001ADC1F2BE770DE63956F31717829E8EF6B
+:105F400039B3FD418487338DDF3FD717DC4F7FAFF7
+:105F5000E36718EF3B93280F473AD7D70D70B8BDCA
+:105F60003C2A3EAEC3411F479F27DED788FB0A0568
+:105F7000FFF19A65008CBBE4B73CDF5F5F973ECFD3
+:105F8000CF0BD447CBA3E2DD405FFC3E85A97184F3
+:105F9000EFE5BBDE791FCFBB2FF9D5984294FFFA0E
+:105FA0007BB1F38579529ED9015388E28930CFDFE6
+:105FB00022BE9ED97780F2A1F4F97E53FCE8F74621
+:105FC000776EFA01BFC72D13FC6B80F7F21D7FA01F
+:105FD000DFBD58AEE785C5DC131DAB6724E69B83A8
+:105FE0007E918D71F960D3DF1B6C36BC9797A5EE5F
+:105FF0002EA7FD0B26A39EB699B5F88FA68F8A34DF
+:10600000FD291CBEA669B927EADEE1D1A0BF795CF3
+:1060100093E669B7737FBC4B8F0B8A4CED3EF195CD
+:10602000B330AEF826D7DB25E8A188A80A7CA4BF48
+:106030006DE22A859F57D7E24B77ED253F13F90490
+:10604000ED8821DAF71F4D38F37408CA2CAF528956
+:106050006278589DF7250BB5046992BF98F737779A
+:106060000BD42A02FCDCDAE03BE20DEBD043756B8B
+:106070001286BE847EF466CD0FCE4A5866425135F4
+:106080007241600D96A396290317C9DDE366AF2E12
+:106090001D3D0FC76DB399507E5954EEC7ADEBBA95
+:1060A000FFD86FA7FBC335FE19649FF82737EB1B9A
+:1060B000EF7735B80E5547D99BF1E620FD6E81FE8E
+:1060C000BDF8FAC187F01CE8A0FA11545AAAB97FAA
+:1060D000B926E1C7FBDCB0AEC4D7D2F3F11CB5FEE4
+:1060E0007EE204E37936C0FCA10551FBB58CB90E04
+:1060F0002D88D2EFE08D19EACC93D3DD9FE28A8A16
+:10610000B19D95C68CA7C6D4831A91D4C4BCE7357B
+:10611000D42D35C675585E4BCB8FE6536831EC579E
+:10612000FEB421E75075945E4D32870D704AAACFB8
+:106130003D548DBF03515F4C25CD0CF09CA2E1393D
+:10614000A556FD18FDC214B06F8E46F90B2CBA2E61
+:10615000F252CEA06B7CC90E8DEF6E5731BEDE17AA
+:106160001EBF6AF9D306B071A2F09DC6A6137DFECC
+:10617000C4C7FC8D201777E76EB6A39CF86983FA35
+:1061800026FE4E4D6B6E01F9C389E60E86F9EF4986
+:106190001E786EF0CF82063859D4591DB87E2BABCD
+:1061A000B3237D6666CCB7A33F2E03D963BDC53943
+:1061B00083EECFD4CFEFC5CE6F2DCC2F14958F6F3C
+:1061C000D1E319684C9675C3957E2F02FFBD7051BF
+:1061D000443FC5A6E7EE69F0B3EAEDDA3D6109E5B3
+:1061E0004F046EE2712ABFCD85F52D01B473EC6EBC
+:1061F00033D5AD0BB6857E099F7055D9FD266AE76C
+:10620000E79AE27301FE467F8FEA343FC49FAB0BEF
+:106210003F7F8AFEDD9FFFEEB205F17889DFC36A1A
+:10622000B17A17A35E6DC92C16A2F3283227542E1B
+:106230009F80FCA19D17ECEBFDAE7D3FE6CEE4F721
+:106240009870B853484C86B2660AD1B3C4A2E0D362
+:10625000073D635CF0BF8B9E5B63E070BF45CE443F
+:10626000BEBCBF51E8753FF79609FABD9B7C7D9790
+:106270006F64740ED2D26C0ABA05F4A96513D27F8A
+:10628000A635D086F1FEB57799D81A9975C51DC681
+:106290006AEB1FEB5CC8CF0D33F94AFC2912CB41E6
+:1062A00091EEFF1216BA06E2FB96E6E34778BB973B
+:1062B000A1DE73E3FD7160E7E66D35B150947F8038
+:1062C000F7C247D74B0EA71AEA55F6412C64C83BD4
+:1062D000C936B44FFA62B4A17DB25468A84F888C15
+:1062E00033F4B7B1943539B0AECFB5F8665F7CC83A
+:1062F0007658E93D502F2487DDC0D1A1283CE73EE8
+:1063000069358C6B8969D7E3917DE12D364EB27B7F
+:1063100082F17C60D73D217DD069EC3D21A0D82B56
+:10632000374257ABD3447A3D336306C9ADAA1A2F1F
+:10633000C37379B1F8C39D539447419437B66E380F
+:106340005802AC12DFB33673BA70C378AA9BC74940
+:10635000911E5AD6318ADFE9722CD3EA75A1DDA7E6
+:10636000D383B0B0CE85F85F12140D78B0317705C5
+:10637000FA359FE37975857F1FE9C2A2D185C5658E
+:10638000A2BCDE58F8EBE7D163E1EB5E67358C9F8A
+:10639000FA2DE1FFE9B784BF5565BB9309FE4C4672
+:1063A000BB74F2C20D943F631DA6109C6A50F66246
+:1063B000FB3046F1CE58BA033C84A2ED10AB868781
+:1063C000C9E24695E0DECCD8001951D7C6F5C8B071
+:1063D0001964E7B0601B9D775E0BF8C0F9AE95DAE3
+:1063E000EAE6C377D61EB62901E87F97BBCD85F2D2
+:1063F000E0AE4D02F96BC2C20DF310AF77A567B8DE
+:10640000F93D026CA089EEE50EC59968DF3310C72F
+:10641000EB013BAF87CC581F19834F6837637BD69E
+:106420008678031FE0B1267C9E5A6BE463DBC42CA4
+:10643000DD78A5F1A4EA8131E3F909D4D2417E0ED9
+:106440000BC07A2017E4E6088D5EA5610B2B917EC8
+:10645000F6678A4CA0793101FD6D9D7ED8064E2FDE
+:106460007A5C53A7A71E741330F2ADCE17FA776487
+:10647000763FC147765AE5A01BE57B547FEE775502
+:10648000A25F2F69FB8DC2C27A9AF7DAB744C22B9A
+:1064900074A9C07637D07948EA39CF16D52B91DD6B
+:1064A0001433DF58FAEA6FDE3DE6F535E9FDAA89D7
+:1064B000DF8EDE9B125B6CD8BF5EB34F9AF03E540A
+:1064C000DCFFC0FB50C1FEC1B4551CA7498B13D0E3
+:1064D0001FF107DF97678E59DA797DC984FB34F79E
+:1064E0004EF85B18ED914D6B5D644FDF3B71E0E85A
+:1064F00079F41EB743F5FB36647C94CD7ADCBF811A
+:10650000E3209F40BB8AF1533788AF89E097BB17E0
+:10651000AC5B2546C5B3E461B2D006E3A65E18299C
+:10652000A0DC4AAD61261F95CA25E1D7D6C0DAABFB
+:106530002F616F48DAEFB5C53EFFC9443BCD5F6AB6
+:1065400066BDDEDF72DF44AE8F6DDA7D163A5C80A9
+:10655000745EB115F4669768F0C024C132DC0F8711
+:106560007945F151CFFE1C5F3ABCE2F011E03B6D82
+:10657000189F8F1C902AE81E1AA744707737FB18C3
+:10658000C23D45BB172676BCC7B5F5A434F33CB86D
+:10659000D8F6DFF6B19E145C4F2FF7A4FDE3D7C306
+:1065A000045A8F4B5F8F97D6936A9605E4BB546667
+:1065B000E7F302FD13BD3F981AE81D3F2B27723FFA
+:1065C000D266D6EC706D3D69B54AF2BC5ED61FBB93
+:1065D0001E8B0BD663EF7F3DFDF90BF6AFEB2FC89B
+:1065E0009E7EEE45E27E419BE6E774D1F11DFC7D87
+:1065F000C9CC848C2878FC7DA2C8F1AE427F83BCD4
+:10660000E77631E1C18D65AC7F07636568BFDBCAA2
+:10661000B0ECD98EFE8A59E36373B73DFD0FB18F9D
+:10662000BF6AD9DC60F40B7BB45B95C5DA39AEC1C7
+:1066300099C59467C085CD633C1F2CB59CCB35CBE9
+:106640002493F6FB605ECB2428131C21FA7D3029AD
+:1066500060C40BFCF95C48BF42EC3832E565C60DFE
+:10666000E3F2324191E93CBB8E2FBF433D34B10888
+:106670007F4724A511E3D50057FF7DB81FE16A537A
+:10668000AB500F69FB5DF867D6E10AE3AF75A9ACC3
+:10669000CA4379C1113A4F9A735B00FB4B2646FB04
+:1066A0006196DCD446D4530CF45432D51F50B39DBC
+:1066B0007CBF8CFF9EAEE6776A784C28BF8D656301
+:1066C0007F95EFA7B16AB5A38B6F419FC5973E1F1A
+:1066D000C2DF936332F72F6DC36A3AA2F93ABE94D0
+:1066E000FB9BF60A3BF73FD9D3A197E17B2DDAFD5F
+:1066F0004466A7D7D8DF05FE565E4F7F54A71F8B91
+:10670000467F172F72FA22BC619C03E43FFD3EAD29
+:10671000F31FEBA7C6D20B93B9DE6466F592F7CFF1
+:10672000801DBD06E3DAF7E498E8FCEE3D39058705
+:10673000717FF5A7B926C2DA4F3D9BD721DE3FCF47
+:1067400031910E6D4A3CBE2E0BF156CA7F9E35210B
+:10675000460EE0FE77B41D85FBDFD176C23DA53342
+:106760002EA9D7327DC6F7072D36BE9F5CE3BB1638
+:10677000E97888DF68CF5D566FB4DF1EA951EBB0B2
+:10678000DF4F720B7AFDDEFC1A75EEA4225C1F9FB0
+:106790000FCBEDDDCE784093673F6BB053D9DFFC74
+:1067A0003768FD7FAEF5DFD82051F968838B4A1D2D
+:1067B000EEC0BFC9F3017663FB90A309F5FFF16654
+:1067C0007554FC3741D75F3B747E5573A6F78A57E3
+:1067D000CE97E593BC4C253F6CDF9B5D747B89F3C2
+:1067E00019FF2AFF55FEABFC57195BFE5F5FF1B145
+:1067F00031008000000000001F8B08000000000036
+:10680000000BC57C0D7854D5B5E89A3367CECCE43F
+:106810006F4E420293887A2609219040070C187B1C
+:10682000839C4CFE2614BD0345A4DAF71C1069B402
+:10683000F635D77EF5C5D7F666F2FB420409142A71
+:1068400022DA49088A26DAD1AAD5EFA3BD03484B3C
+:106850005BDAC6162D6DFDEE45F4F9F5DDEBFB9A1E
+:10686000AB786B7BF1F2D65AFB9CCC99933FC4EF8B
+:10687000BB77FAD5C33A7B9FBDD75EFF6BEDBD53A7
+:1068800076E19EE3CFE603EC4C4AF1FE0040D7B13F
+:10689000F733A0129F2BDEFF5905BE4F9C710641B6
+:1068A00003B844BFD5939F0FB50324DDD82FB9DEBD
+:1068B00017CD9ABE5F3FF55B9882FB16299BE2D805
+:1068C0001F2E22BC12DBF19F50926A9FA73B0056FD
+:1068D00060BF25D8AF32D5EF41EAE74CCDB7003CD9
+:1068E0009991ECC9F365964B902C07FE5D82CBC75E
+:1068F000CFEC97902153B5F4CFB8F41A4410CED60C
+:10690000149DF181C4F8B5489F8C2A5523BAA5DEA1
+:106910004725A8C2F9ABF2E2FD8ED4F7892A294CAB
+:10692000ED76BCBE77F4BC0E38CE87D56AAE13C701
+:10693000B95A9778DD39007A02FBBF9ABD2DF4046D
+:10694000F1A12A6FD08DEDBEEAF4EFB752FF0280BD
+:10695000B27B3FBBA904E7FDDE1927F4CFC02F00AF
+:10696000FCDE637C4F743CBADE47FCBEDCFEB8E262
+:10697000D4FC0CE7D9E0225BFF625BFB625BFB723D
+:106980001BFC595BFF900D5E63EBBFDE06DF66EB21
+:10699000BFC5D67E8FADFD3E1BFCBFD2FA97C9B7EF
+:1069A000FBA6922FBBDC98FD32E438042B894AC841
+:1069B0003F8BFCD8F97EDFAADA569DF876B1DFBFAF
+:1069C00005F99638ED0A920E741D13FC80A3C8F4E5
+:1069D000429890FB0CFA90F183B1AD167C8F05566E
+:1069E000CE3B37835CA33C9EDD9AB6FE38CB174086
+:1069F000CB59EB3819069FF93B94B3BA583474104D
+:106A00005150F2A538C95DE15C9433C4F3C3180E4C
+:106A1000E020AE460C7CF49B0B113F167D0D40C66A
+:106A200036B801E019832E6E58E78B2CC1715E18C1
+:106A30000B5127C7B64DB14C1CB7F715D471ECDA22
+:106A4000E8CCEADC8C704FB55B75AB388F12F16423
+:106A5000E33CBDDB65E874D090A7B9DD7F9513DC1E
+:106A6000D5F84142613C3DF8BF4BC5004B5F50D269
+:106A7000E85A0C163840DF2B297E0688865F9CD1A9
+:106A80000EB4BDB939FEAA2735DE137A76FEBB995E
+:106A9000F88FEBA0EA5249EA7B50057FECDFFFB9A3
+:106AA0003D1A7F7501766B06D64B258C4FA623C405
+:106AB000DDB89E866D6DFC69EE1927C3C81F5D4663
+:106AC000B8F8B4D0DB4667E5311FAE7FB71F346A34
+:106AD0000FFBA370AE3245676369106F87643DCECC
+:106AE000B33BA2E5A9D8AEC4C0A4AFEE21FAF60824
+:106AF000FA02F289E8EFF2BFFB262C65FA4292E82F
+:106B0000BB39ABB513E95DEEDFB6968C0DC40DBA9B
+:106B100039C041740DC42C749B82AE2E1B6CD2C53F
+:106B2000E4FF6C747DCDA4EB1CB8EE4AE8DA11509A
+:106B300098AEBD0B045DDDB03BB699EDA85BED0FE3
+:106B4000229D9D592CAFBD9560D059CF299CCB7605
+:106B500095E5B4CF35A6CBD8DEE380F14EECDF0B64
+:106B600063CC87CC5ACF780CE9E285F7F4CD552970
+:106B7000B9CBAE4E97339F9E4E9F4C9B9C793F2541
+:106B80007D3E34E9733D5CCF7AFB09E9E331E6F9F8
+:106B9000AD1EBDA4A3BEE7C6A0C385EFE67D711CF4
+:106BA000681CA48F44F4DB592EF41BCD4A5F31AE30
+:106BB000D76BF80F88E9BFAE447A6519F256BBF17E
+:106BC000ACC76A674CBBD7DBEE61FF9FA9473613A2
+:106BD000BD5DE58A16C77970F5B12D38BED3EF8457
+:106BE00024D2D7B1B13A49F3F51742D0AD91E98833
+:106BF000F8922447F941EEE746BE61A4014AB00687
+:106C000092D42F9AD5DAAF127E7B544622289F3F2A
+:106C100087F454F17F249FF6F57B41B49BF456E64C
+:106C2000236CA1A7D3D66EA777496D3ABD5D61816C
+:106C3000DF7476C2A4F7BB35FAA2DA0292A9A9F9E9
+:106C400092B2C331E68B93F852C87C595E4B7C8973
+:106C5000438782F35C756F3A5F76774B2CB7F864A5
+:106C600039FFB014ED2EF69B4FB28074863A881F20
+:106C7000764C9EC7E44B9CF882CFDDED2AF3A7A7A4
+:106C8000DDCFF0AEE627489961FB556363C5C807C1
+:106C9000DF9AB3A742A4FEB1622FD98D1C8727E1EA
+:106CA000C4E78EFAF75B37E3FB3D6B0E241D38DF3C
+:106CB000AEFFF001F1A7BFF968B81CBF7BA8E08F59
+:106CC000D1416CCF6A7E3E124638CF09AD567FF770
+:106CD000F95A07AFF7F3B5223EC1DF68F65CD385FA
+:106CE00001B466453F4F74D387855FC9AB018E976A
+:106CF00032B3921472A03F2DF2923F2D6C34FCA15E
+:106D0000E107E7D0C7642FAAC793A4AF08C7B2B5FD
+:106D1000D4BCB91FA1BCCD999E0FBB8F2F72683810
+:106D2000EEEE9BB55AA26BC00FAA07E91A58AB3A10
+:106D30006288FFA81EBD8BF052EA41D211CE8B05AE
+:106D40001D1E1C7FB05665BF39E8D0BE40F30F163C
+:106D50008044F1615D4C2B24FBBCA779DBB5D119D4
+:106D6000E328DD21557FF2A7FD7BFBB86E68D55186
+:106D700025E0915AD0C3D8EE724682807CCAEF3F9C
+:106D8000A90D1521DFE75DE320B9CA2DCDD129DE9C
+:106D9000263C375BF8F45D833F26ACD5B00E8046C9
+:106DA00038A003D1AA8C67D0785F69C0E5027EB8AD
+:106DB0005663BA68BAF1BE54BC9F8D1E9F741EFB09
+:106DC000F871E207CB955648FE0D7F0773D2E5EBCD
+:106DD000BB33C917C8F81DCAC1A04B2D223E0E5E99
+:106DE0002DF42AD6A1B05E810C451B97A4F0DDD30B
+:106DF000B171934E7C76C026AB9C7FA956C4EB370D
+:106E00008584BC37382BBD2C0F1053695C933FB77A
+:106E1000ACF96D348C7A5FBBAD2534447E2B26EC07
+:106E20006E6F6CF931F243BBC3C079D687F592839C
+:106E3000F4F36F20EE2439BB0162FC5C013A3F138E
+:106E4000867E9F32ECEE75A0F1FB851097E8D9A500
+:106E5000477F48766511C418D6C2411EAF65789D3C
+:106E60001E15C67C830BE9D4C5A4B3D2471D24FAF2
+:106E70009C34E4A1352B7292E867D2AB301CF9093F
+:106E80008D5B39FC9C5444F6B4593F45ED277C5F3B
+:106E900065BBA518F28514548A707D7B06B5651C08
+:106EA000CFF8773712DC52AA2E7322FC8FC6F83F38
+:106EB0005915798DC66B9ABF5BA1EF3F32F4ABE9F0
+:106EC000D5A84CC3CC19054726F6FF9B17E25DF405
+:106ED000BC013AEAB007AC38AB9FC826131A8EFE45
+:106EE0009EBEBFCE133841EF2BE73FD7992BF0FA68
+:106EF00003BD3FE1F349247F1AE15529F8BD0EF99E
+:106F0000197744FD4417938F8DF31D9C7FB9FCCAFC
+:106F1000604940F07DBD25DEEF9D86EFBF31F8FE74
+:106F200027E3495F2AE9F2F727C2633AF92B1F1DCD
+:106F3000005AD792F7CE75E6101FDE51658A4D567E
+:106F40009E6975D2FA1E5A15FD37A26FE874B09B80
+:106F5000E851A9278ECB44CF646B3DC3A509298393
+:106F6000ECF02AFD2F344F58569B4B719E30E6EBC8
+:106F7000318D0C73FE947186372EA5C52D00038CC0
+:106F80007FB39699F61EE5541FC2F1E27E21A73821
+:106F9000647F00871C0C4B1C1FCC59AB35978B387A
+:106FA00096D7BC27BCDC3B555CFDBC591F30E4D5F3
+:106FB0007C1F34F223FC9D73CE208FF34213F238F2
+:106FC0002F6491478BBC5F15B2C87B2EDA6DE2BB94
+:106FD00029EF2D71217F15096D39C9DFF253C113D6
+:106FE000449A96E15C96C7B290E01FCA63098D9FF0
+:106FF0005BAFB1BD44795F4A70E5E944679645BE31
+:107000000AC3FA429A0FE5AC9C9E8DF3C53CD79D0E
+:10701000D6BA68DC26BF18D75CE702637CE4138F1E
+:107020008FDF7D869E1A7970F2F34950699DDFAE3D
+:107030007F3FE9A4FCEA05220DE635D5504FE3D4A5
+:1070400006A327247C5E5FAEC9B4EE268AA72C7106
+:10705000E8B264461ADF506E56115E75A55199F478
+:107060001E2927B37D9C461EECF109FEDECB599903
+:1070700026C7E1D04C76F432C7FDF3AAC8DFD23878
+:1070800073D68283F873B9DF99F1D29757EB1B69F6
+:107090005D180EB524F8FBAAB478EB7683CEFF4CCE
+:1070A000F95601C56591FF46FDA15EE43F9F743E20
+:1070B000FCFE2EC21774FC3E9BE3B5161A2FF79CFC
+:1070C000A3C315981C47EFA9918C3C43FB6909D9D0
+:1070D00013238E5640F34E553FD861C4650F515C63
+:1070E000E6A6385AE3E7F6F672B6EF03ED41861FDF
+:1070F00069AF66F8C1F630C3545F8A519E82F311BE
+:107100001F76B8226FD17C0ACED789AD0D1B3FE226
+:10711000387D57F87D8F48CA2187F24633EF01BF8B
+:1071200045FF593E44DCAE8415AE632955E7635BE9
+:10713000C917A39CF9FC1487DD933C447982EE695E
+:10714000A5BCAA60E5F3499AEF43DD330E1CD7B71F
+:10715000840E50FB2AB1FEB25717F17A5D55986F35
+:10716000E64C9ECF0DEB38BEFF90E27BFCBEACF44C
+:10717000F79EA9E803D5463E65E4A3DEF933E75B55
+:10718000F67CB4E046113796BDF7D729C7576DF5A1
+:10719000988235A27FEDC672F6DFF6FE85F5E9FD31
+:1071A000F75419E35FF8EC59AABBED24BB085C3730
+:1071B000F558EB69F679A025238D1E7BC233D725C0
+:1071C0007B0C7FBFAB46F4739976D38887B349E6CF
+:1071D0009CA9FEDB8DFEBF0805843EDBEAAB051BE8
+:1071E000F7C366AA4F5501FBEB828D4718B68FF7A0
+:1071F0008B90A8BF7A27FA79EA17537E1856879C96
+:107200009C2F42B57BA5A12F5AAA3FDA8B5F909E97
+:10721000F820C9E338B31240FAEE92C74F119D5CD3
+:10722000867F9A6EBD19A5E9FE6936FA28F9E9FD4F
+:1072300067ABD799F434FBB9E408509CE69245BD9E
+:107240007501947B294EB08FFB27C3BE9481B69DF8
+:10725000FCEC2E5C07D1748FAC79E97BD4FF70DC39
+:1072600082A7BD6EFAAEF1FD7DABF43F915DF139C1
+:10727000A3A1C749CF564B1C6F2A176F7B8BE5C85C
+:10728000CCBF0D7EB840F0C3841559F0D15757CE0E
+:10729000FCD520C875DF5DE13DFC9DCB56C7DB8387
+:1072A0007203567931E460121D6D799362F09D2C62
+:1072B00028F15D0E6B43FDCCF768CC81FAEB534BA4
+:1072C00097D37C39750ED36F947AD2E39F9CBA82A0
+:1072D00014FF6535C9F6B260630B3F351863BD34E2
+:1072E000F5683AFB6CDA0F86D95EC578BE47725BEB
+:1072F000BF7B2E9FE275190EE3F3E1CCBF7F92E0D6
+:107300008A985B75D3FB10B6533CAF78D4AE20B5EA
+:10731000E7B0FF6A7B339BEDD49FA5D8A65E7C2E99
+:10732000AE0B305FBA1DBA4674A99071BDF87D5797
+:10733000330C75B23D8751C9B2AE2C186700D7B770
+:10734000B8CE923799EB3C487162A5D55F22DDC477
+:107350003809C9A22FCB0DBA615CB3BCCE12D73CA1
+:107360002E45AAEA109FADB907FFBBF0DFA26E2140
+:10737000C51C407532FFEDC1319DE4A602828781B4
+:10738000EAB6E9750DB0C2CEC9F0DFD68978AAB0E9
+:107390000C608CE3E238EFF7B83C37EE5A0CD3EBD5
+:1073A0004D6F7BF51BF52E4BDE29B7B2DEB8DB6ADD
+:1073B000DEA8BF0EE395DAE85AC2DBD5D6C8306046
+:1073C0003BF9DD5B6ED46FA2F5FDC38DFACDD4FE23
+:1073D000668DFE003DFD77887A0112E365E29B1B16
+:1073E000F3837ECBFC77D6097D49E199C820391E0D
+:1073F000195D3E8BBDD4D3F054E428E389F84509E8
+:107400000FA5ADFE8D7A94736FDBCDFCBC6195BE8C
+:1074100099F0A9592DF0BBB90E983EFE5B113F9C27
+:10742000B733F3EFC19A2F7F6D1AFA3D7D6436BCF6
+:10743000826F50BDD68ED7CD751AAF5369AB62BA85
+:10744000B9DB6E64BCF05725A7C7618CDF747198F7
+:10745000FF8EE0398A0B6044091ED6C8CFEAC6C742
+:10746000AD22BF89406EFF328A4762ACFF5EDA0709
+:1074700070921F4D329C0DE718F691C745F8C13A3E
+:10748000E13F724173B01D8720BF37E9E2C9C77180
+:10749000118FFC36D5D1790349B793E7715E27E2A6
+:1074A0007628078DEA333821E3E938F2E3BF38382C
+:1074B00008F9A6CA75366FBDE352A6454F3B65E88D
+:1074C000AA4AE9719BA1C7058A68EF727954AA5745
+:1074D000FF4F676C538F83F4247A80F8F967498FE4
+:1074E000125ED3E98B337B98EDCD27D5138CD387F0
+:1074F00089DEFB1DFAB293644F0A15D6373B5FFF56
+:10750000C19087FC2621CFBDCD224FECAD1576E092
+:10751000B93AE117BF6FE8FB8B46FF2D213D41E3F0
+:10752000FFA6463F4DEBD860C009923F7CFEBB8E64
+:1075300070410A4ED961E07D5A1FE8EA49E1878F20
+:10754000382C7262DA21949784D53E99F6D71C2F95
+:10755000BF4EF091E2DB75963AC7CF0D3CCDF550AA
+:10756000FCBC2E7B8AF6CF19EDE1F4F684B1BE7730
+:107570006BC47A00BEA8BE5B81FC8F95382EE1F308
+:107580007FD32B9497C7C291D7A8FDC14AA137E6F4
+:10759000D34EDF2D61FD75EAD77775CC4F75E2DEEE
+:1075A0005F388314E776659775517DBE2D92A139BA
+:1075B000512E7AB3B7F9E9FBDEC2FBAFA56747E10D
+:1075C000FD0B298E53DA7EFE1BB647F3F338AE5718
+:1075D00026F2CE31BF75DDA65F793873A9D480F36A
+:1075E0008C0464F613238EC4EFEF21FE670BFE1F9D
+:1075F000F0BC3DF71DD4CF22EFBFCC7D07C77DC8BF
+:1076000058CF0107B0FCC75688FA516475E42B2F98
+:1076100022FCD09A8C60A746F8BEC4E3F42DC90BB7
+:1076200012AFCE370AFBD617E83D4BFEF46BFB14C6
+:107630008DE2AAC36F2DACBB1BD735BC4EAC6BEF34
+:10764000171B72898CFB22B7AC5BA189F56CC5F95D
+:10765000BFB3F5AEDDF4FEE14D5F7F8DDEEFBFB76A
+:107660002717C5001E89EE5BB712E10B6AF5AFA8BC
+:10767000BEAB805E7437E9E19B6EC6BF63B7A04BBB
+:1076800073408E58E3958F1B055F3F329E452D2238
+:107690008F9ECE9EC55D42CEE53AB82F621927ABCC
+:1076A000DEC9EBEA6832F6A5FD3F3F43F47FB4FD47
+:1076B00094DA4DC18C1C5D4374D2F662BC8CEBCD68
+:1076C000D8271527114F39CF93477C9BEF1472B9F8
+:1076D000C0FF4BFECE1CD7D7E81571464C1E3F6746
+:1076E000899F8BEA8DBA7D1082A4B7725ED837135A
+:1076F000DE261EE1957FACBD0BF1409AB4BA8362E1
+:107700003C1DFD3C9501A9CE7ECD86B38E9E2ADE22
+:10771000476975FB09FEBDE330C26AB1CCF0D8DE23
+:10772000F38EBB102EC53C86BEBFBA4D86F3D6BACB
+:10773000CAC54B4E752ED9CFD44F9BCBF695C7CF2C
+:1077400005D1DF8CD37CDA4B6B480EFC5D3E90A8F4
+:10775000365A3331DEAF689DFE81C44FCB28EEF23E
+:107760004BC126A4D7F1D12D1EEA3FD22701C9690A
+:107770004F6EA29FEA07F19B2418C2F146C2416FE7
+:107780001ED261A8E6D72AD5526BEBF3982FD9B950
+:1077900063EA72A4F3816C619F4622416F2EC52D6E
+:1077A0005BE09E083EBFFD42F414C5B7BEBE3C156B
+:1077B0003502865E567383D87FB521AF383FC785C3
+:1077C000BD9E604621F63FB4767DC6A24A6AF77038
+:1077D000FB61D5114E541A0B46FCAEB9377848C43C
+:1077E0003FC1EDE538AE7B74B993E2C6AF3629DC14
+:1077F000BFC1793443A2F8B54D56A9CEB43BF33F8F
+:107800003CF45DF1BD3210EC01B18FE318A8854B5B
+:1078100073C89E971EA7F6AB77087D41BAA7EC36D2
+:10782000903EDD9F6CC1F60BC67ED25536BBEF860F
+:107830001DFFEACCA1A7657FC8B2CF136F87319235
+:107840008F5ECC13CE5BE2882FA5E46C19F9950608
+:10785000E79BB7DC4A78B748414ACB77417CE74A97
+:10786000842FB4C841A2DBA32D2FBE467A78F09BAB
+:107870002773AF47F8B1D6D7D75D8F709EEE846E71
+:107880005CC7E3DDFF6737BDBFF65B1F6CBF15DF6D
+:10789000F73A9E3B45FB6FC368DF3AF0FD70B619BF
+:1078A0005FE81CBF6BC679905E45F069C2DED60BFF
+:1078B000FF623E9F683F75A69EF10F8F752FA0F562
+:1078C00044783D6A5BDD18CD7BF854E236DACF812F
+:1078D000980F32AF499D1F78488A86A9049BA8DF7C
+:1078E00034E44155538EDDE7596BC2489FF819695E
+:1078F000FD4DC114EC5EF0FDDB8E58E01147644D88
+:1079000039F57FB5614B3883ECCFFE9843227D6C0F
+:10791000594F7182F719098CBC31E2B1E84128EE68
+:1079200066BB991356D8AFF5B447CF6EA57DEDACC5
+:10793000ADBF5EAC515E363640F8BA50E7286F54A2
+:10794000F22DE719F8BFA8CF563F5E8AF6C18451E1
+:107950006F46CA65CECB163A2062ADDFDE65C8F34E
+:1079600013F5C24E2D1C95626E948B85FB917ED6CD
+:107970007CDDF45FC97F05F25F23A3F7654C655F8B
+:10798000CCF1EDDF9BED3B1BCD3A71FA787D816D3B
+:107990003AD9910FD00E91BD77475AF41EB2D79ABB
+:1079A000B033EEC83D3AE5379E5A0FC3661E5746C0
+:1079B00043A11CBA935B81EC98BA25ABD5578D9F38
+:1079C000B5659E11FE2E1AF3E6733FDE1F33F7BF37
+:1079D00017B121C2F96599E3C8CCC7447C163FFEB4
+:1079E0000589F6C5E2072221E247E9A8D8173B1925
+:1079F00068ECF462BF053B402739AFD8310EB42F95
+:107A0000A6D48C277DA4A703A0919E8607B410F569
+:107A10002B39ED04EAB700A2C789DF0DCECA0CF2FC
+:107A2000371D81FB3B49FF77D57AC6E99C87797E74
+:107A3000C1A44F099D5F60BF1C0979689C6EB45159
+:107A40001AEDD3078FDF89F0E11BDC2AEDD397C055
+:107A5000C110F9C789F320C3861E4F9C5B48DFF72E
+:107A60005D68D3FF129BDE9F27BDAE8009FFA14159
+:107A70002283F29621CC33089F78FBCBF0B6C50E5B
+:107A8000987A48E75B8820C9760F3F5F6A57415F65
+:107A90008876B9DDCFF086E6D07BF505A46FC1DB33
+:107AA000C84E9BFA76C2E7BB81FC5C9D73ACD38168
+:107AB000745872F23BC519A86FCFCE9736D4061909
+:107AC000667D4A26CFE7AD5553F04B67B67CFE2660
+:107AD0004BFBB1D2B7CBC184D1C9FC60A74247A749
+:107AE000709EEF0C254B53F8FEC0C8476BF74991C9
+:107AF000A12CF6B39CBF5F285507291795F3105F9B
+:107B000084BD4BF2195ED220E4548EAC137553BB86
+:107B10007E9108AEE4388A7F4AD61D5CCF43790D4A
+:107B200036F927EB9F8BECED52D25FF99FAD7CC904
+:107B30006D48F7DB17A086E39529EC03CBA9691FF5
+:107B40009CD9F95ED2BF9EF63EB5DB223F3D05CA09
+:107B500032AB5EBA72608B352E319FEB9AC4FA1E3F
+:107B60000BEB5AC38A94FD9B2EFE34ED512A1E8DD9
+:107B700056D077D98511CE7F947C81E764BB94AED3
+:107B8000E75A0C24A2FBB051B71DAA799EF3C6A1F7
+:107B900081627E8E8C86FAA904F2016552A42705C3
+:107BA00098D57D66323EB3C99DD9CF94331336E55F
+:107BB000ED1B277F98266F08A7C99B099BF266C219
+:107BC000A6BC314CF2B64AA1A37E286F3F9C5ADE78
+:107BD00076A3BC55CE2E6FDFF84F92B73BFE8BE4F9
+:107BE000ADBC7142DEFEC715CADB030D059F5CDE2E
+:107BF00046D44406D517303E64FF679E871A3EA8D8
+:107C0000F239D261FA84E2DBA7D4C118C2CB1A845C
+:107C10001FACDB2FCEFD95EC15FB7E7DFB8C737FBF
+:107C20007DE2FC498373C72682476A143E9F669EA5
+:107C3000C31AEE00E31C1148649F17D1392C94A796
+:107C4000D17630F62D40A27367E546DDBF2491342E
+:107C5000ECBD16A2F380252F087B3F025A865A9965
+:107C6000F2571506DF4BFA9E3F7E27F9B922B12F56
+:107C700001A3C2AE9BE7009724D2EDBEDDCE6B36EA
+:107C800078B021DDEE4F67E7EDFC41BBFE24F151FA
+:107C9000035DF88901515F9D2EDF18694F3FF75C46
+:107CA0009180D094F9498388DF0AC3FAF769FC4FC1
+:107CB00080CF2BD47F363FF3D7868FD3F41EE134A9
+:107CC000BD376153EF4DD8D47B86AD7E063EFE5462
+:107CD0007EE6AFFF497AFF8FFF457AAF360A7D42D5
+:107CE000BDFF7FA4BF57A0F71F5D89DE57F88F1D2A
+:107CF000A79CB391E46C8A799E37E8FE90B18F8A95
+:107D000078659CA73C4E0ECEA37CD1DB28E4D0FE48
+:107D10009DD276E7D9ADD6FD01A37EA9B46DE3F778
+:107D2000BFACD3331A29BEADCEBBAC7370D7D6036C
+:107D30003F5D0ADC3615FD7E6BD84D5706D2770ABB
+:107D4000B96F7686FC34DFF2E64811CF0B8920ED5F
+:107D50002720BDAF6ABC327A97355E01BDA7C3FF4D
+:107D6000B6D9F10F1AF86FB5E27F0578AFBA12BC39
+:107D70008F053666D03C07439135F45DFC972EAEF7
+:107D80001B98796F1FCE3146F6590EA6DD0F50DADB
+:107D9000369FDD7ADD5472B035EDFDAE7695EBF0B1
+:107DA000FBDAFDFC3C580C7CDE2E1E0289E6299095
+:107DB000230E92B75FD6456F21FCD51AEC6FC177C1
+:107DC000EE067F1A7CB97255EDD46F6F147467BFDD
+:107DD000A47D16E2345F4EE5E9B3547FCEC9576205
+:107DE0006427A05A7ECF6A3F901F5B080F3B3F502D
+:107DF0009E96133C22B772DDAA0CFD6107D5E928D7
+:107E0000AFACA4FB194FFC91CE4B1EEA2B2E267F64
+:107E1000B8903668919E0B0BB421F2AB270D7D1AFA
+:107E2000DA2105C9FF5D30EED3B8202BE69C22DFB6
+:107E30009C584FFED933DD16FCECE7551F68CC4A41
+:107E4000B36B1F54AEF725617AFA98E755CDFAC0A7
+:107E500074FDCA5C118E1B0E976F58B388EAF2FB53
+:107E6000E5E00231EDA9ACB9A9FD2BFBFED653F537
+:107E700013FB594FD55BF6B39E223D5FC1748A1048
+:107E8000FD0E8F4A5CD719A9091691DE1CDA179AE4
+:107E9000D17FF6B4231D66C017F52F3A955FFC918C
+:107EA000A17F23A3EB590E9ED430BF5E46FC493020
+:107EB0001F173E23F83852A315917E1EDA2EEE23AB
+:107EC000F51C6B068DFC1112E16D0BFD9F6F14FB11
+:107ED000218A952FF8FF21C27F867AE365E0CFFEE5
+:107EE000F460E31D87621C0FC15876FABECFCB8DBC
+:107EF00033ECFB5CEEF80037DF999C81CEB3D53DC7
+:107F0000E0843748FE97F6EFBDD49C8FF4B1D4617E
+:107F100017EE9562EEA593C7B1CBEDD8A794DBF62B
+:107F200046214FA8E767495FAF40CFFFC9D0F33480
+:107F3000BF51648C7BC01BFF1D9DD704D873E7AB7A
+:107F40001867F4D06231CFF96363C7A1580D409729
+:107F500043D0D3F593470FC52AA9AEBF529CCB3768
+:107F6000EA321C4F3827AF4369FBF7D7ADF56CA554
+:107F700006F85CA2E2573F5749FB023F2DE6F36942
+:107F8000AE7C9DF9FCD6D73489EC9DD424ECC7781F
+:107F90009D381F096A84DBB371DDFDB9976F17CD7A
+:107FA0007EB4EF31E5791BA3DFB8B11F597C0ACA53
+:107FB0001DB898E2BE989FE29DBDEDC1A277165014
+:107FC0003DCD11577CA9F52EA058AC84EAC822CF2C
+:107FD0001889C8CC8FD85E657001E9D706494F87EC
+:107FE000E5981586AC4891751F665E93B023873F70
+:107FF000766E9A4AAFAF32DA6F2E81FB486F8FED03
+:10800000DB58749EEC5576AF5FAA24FC85DEEF74D6
+:10801000057F150D4C4F1FA56DDDD9FA39D6F5C773
+:10802000C53EEC843FDBC0ED267FA7A3AFAFED0FCD
+:10803000AF533F77DBBF307F7DF2389FE38351B191
+:108040003FAFB4FD5F7EEF9E1F91681F798D517F1A
+:1080500030E95761C88B7B549CB750FC09698B652C
+:10806000DD3718EB35F95F313FE6D7991F7AD13B01
+:10807000A80F4A13A48D576A8CA70C88731A84C75B
+:10808000026D32DE2B9A26CEE527ADE71B503193E9
+:1080900019F9740C16C6294FD387433AD5F5F274F3
+:1080A000CF38E573688FC6693FCE078924DD033377
+:1080B000F715C78D7D739F47E42915B6FB6FBD8605
+:1080C0001C9BFB4C7A93B11E7FE438A9D47471D405
+:1080D000EDC677A8EF1B9B585FCFF179BCD9F47C34
+:1080E00086B8EB8E26A1FF9B9B0A52FA8F7E7E4BB1
+:1080F000D395C58D5F69BA827A50E7DE4EDECF1C1C
+:108100001E73F27D986179EC965B293E6A918243F9
+:10811000047BE23B57527B4B3EEF079871D9B03E50
+:10812000B86F23CEF36F5F91F81C95B95F71D55787
+:108130004EFCF456EC37FFEF7EE3A5FD04D430AFE0
+:1081400084BA79F5D7DF6EDE84D0350F887D86BF9F
+:10815000ABD798FEFFF4CD0F72697D6507CA97B162
+:10816000FDBA4C3BD2F7F19DACEF4A2493E9AE4403
+:10817000768E511C63AF4B2B1BDC6F315F201A23B3
+:10818000F9C1F77AF61472683ECB4A23D200E2B105
+:10819000E0E20F2492838AD128EF3F568C0667D401
+:1081A000BFBDED90B0D691EDCF7CE35E0AE1E74430
+:1081B000FC76C98227F93541A999EC469387D755B2
+:1081C000E217FA977FA9C3BFCE22372F19F2576063
+:1081D000EC4B9AE30C1BE3140C683CCEB34D62FFEE
+:1081E000ABD82FEC7A018D9335799C8AFDC6B9AA5C
+:1081F000EAE5BC6F5C2127A4BC29E414A043F40782
+:108200008F2EF6D31212EDB3F77DEC647F345EF758
+:10821000B33B295ED89D99235F44397146C53DB76C
+:1082200087336F4C921C3E9EAD686ECB7E0B9B7E5F
+:1082300087C0D93197EA26C071DCB1EC32B6C75D90
+:108240007703EF63753D20EA398F17887A4F999C41
+:10825000C170975F9C3B70D379F1121ADFA80B9520
+:108260008B7ED7548EF1BDA26B882EF83EAB1AE2FE
+:10827000B140EA3C4957BBA883A0FE7E81DA734136
+:108280000AF6D3B8B2AED1FD872E19E2148F755518
+:10829000AAB12F21FC686B4E500AD2ED6271EE0438
+:1082A00016EBC67995A0B8FF33718EE46DA07324E8
+:1082B0004807207B57FC4DC9A0C3D2E3344FD7F603
+:1082C00029E8407ED6F3EC2BE7F09FC7B697252828
+:1082D000AE19BA3B8BD73F94ADE874956BE8812C0F
+:1082E0005ED7D002731F2EE8A138F56BD9EF0FB619
+:1082F000B07E69B7D1F88F3AC43A78D0B9C07B1F45
+:1083000082CEAAFC00B56F11F15A577BF88DADAE45
+:10831000D4F91B590E721D4D463AC4E8D9B6F60D74
+:10832000CA9F2034702C8AB003D74FF6D7D5B651E8
+:10833000BC270F65C685FC1F35D642FB6AD44FA506
+:10834000F32D091E370BC6F89943E7D44AF8BE1C33
+:10835000D3CF4E47F35E688A8E4E3E8FA31C17E73D
+:108360006D9C9D32D03D9558A895CFE3C43ADD6A07
+:10837000573E9FCFE1F636D9A3D2BE7776B8D8F074
+:1083800023ADD78BF15A3F43CF979BF4AC7041CAD2
+:108390006EFCAE49CFB1C293F4DF382760C24FC83C
+:1083A000E31EAA03EEAA1952ADF516D34F4FF85F9C
+:1083B0003A2780FEF71035A13E7D661424BA571186
+:1083C00038A875D2FD88C509A18FC531A17781A3D1
+:1083D000E2B928EC643C8AC3C20F9A70D9B0265126
+:1083E00048599E10FDCCEFCA8E8A7116855DDC6FF0
+:1083F0005D58F8F17561599C0B1DF6B29EC4F70BE0
+:108400003DE908F4FA69BFEB7BAF8BFD30361C2BDE
+:10841000411C5112F7A6B9BEB954B016CA34F92D91
+:108420008A9F9F34F5C4B8EF5971500D69F8AC8C30
+:10843000AB9DB42FA67583560BB4BE56BEEFABC52D
+:1084400085BE2DEE86B84EF55A977AFCCB94CF1B9D
+:10845000FB654B6373B9EEFAE368562BD07ED9CB3C
+:10846000C67E98B15FB6F8607ADDB4CC56270DD8D9
+:10847000F6CF165EFC7688F8628FEB17A384D0FBEC
+:10848000B5E1A9EFAD4E679FCDF8BEE220F0DF4D1C
+:10849000D0FAA47880EA6FB1D800DD2F091CC57C22
+:1084A00011F9F8BDEE8838C7BA636A3F65DE374F09
+:1084B0001AF71E5F32CED71F37EE3DFE98CED7E3B8
+:1084C000F34774BE1EDFBF4AE7EB113E4AE7EBDD20
+:1084D00029B97CD090A3D9F2E4858EE87AE2373CC2
+:1084E0002203DF17AB14F6DCCC739F79B958223B1B
+:1084F000F46C4DB2687DE554F995B0EFA32FCE9C96
+:108500003F1E9925BF2B9FC8EF3E379CC4719E7DAF
+:10851000B9534ACF77CF897CF71591EF3E6BE4BB17
+:1085200043CF897CF7C8312F9F2B5B1C86412FD905
+:10853000C923E979EF4ED26FC473511CF1B0F07BBF
+:10854000E84561FF2FD4C020D9498C0B770AFD86FE
+:10855000F92E4B3C69E6A99F7E7DABB65AF357A82E
+:108560001472305DFDC41EB798F6C1DE3E7B3D241B
+:10857000CEF590A78D7ACFD347EECBD8CC7228F822
+:10858000FD8C610726E462129FC5FC4FCAC1B3513E
+:10859000E4C3D3A75D1CB73D3D513FBA9FE5E8E971
+:1085A00083A512FB29D4178AFF8FB44738CEECBFBE
+:1085B000712083E4E767E100CFF3D491CE10D33D7F
+:1085C000AE719C59DEB691EBAF743386E258FBFC7A
+:1085D000E5469D09E233D7934E843F5D5EFE07BAC0
+:1085E0007743F1B951272837EB04715B9DE0C8E56B
+:1085F000D5095E277C2AAE1C9FE9F939C0FC7CCAEC
+:10860000A0BFC947FC5D74AE9CBEBE45DB67C4A776
+:10861000CCA036C47D0CFD6DCD32F272C32EC9D212
+:10862000D4F5A8F1B0C3F093F385BFA5B538698A36
+:10863000E039F2FF391185EF1340E85C8CE887BD23
+:10864000F9FEBB3DAF218F4EE74564333E80A8C89D
+:108650001F49CE9C539DEB9D2E0E30E328914F0178
+:10866000D4707E8203305E3DB4FF6489ABCD7B273E
+:108670007DDF8A4AEB2D7A186816716D4FBBC741B2
+:10868000FDCB927773FD4CC9D724CA538B8DEF5C19
+:108690001AF0B9AD217F31D373F5C5AF66D03D4B2C
+:1086A000F37B7C2FF6C3FB2EEF3E8CD9AF67BF2444
+:1086B000EA0B7D4A9CEA093D72C433553C5DDCAC53
+:1086C000A5E9A9FD7E0732BD88E296BE40D98CE7B8
+:1086D000075D9EB7E7C996BA418F375A44E7E39ED4
+:1086E00070A5DF0F359FCB9AC539B721C7D4EDA64A
+:1086F0001C99F7D61E34EFB7F975AD03D7E51E2BDD
+:10870000E17B16725E9B4A76A1A6397D7F66D2BE5A
+:10871000D9FCF4F3918F85233736E3B81F64BD7419
+:108720000A2565A673B6A16696CFF4F3D3994EE3F6
+:10873000BE4109F0B9728F2D3E98ED1CF5FA6653D3
+:10874000EE6D79BB6ED8A549F29DAE1F71922BDA02
+:108750008FF8D638FFFD255FF22F40E7947C3195E6
+:10876000EFE7070CF9D2B2222021BD76750BF9B2E2
+:10877000D377B0268FE56BF5C56BD7505C61DEDF34
+:10878000994DCE06BB0D3933EEF74C275FCB49BE72
+:108790000AA6972FF3EF7120BEC7EFC27F0792BFE3
+:1087A000633DC98EC5755E47B7CA76BD2FBBAC9811
+:1087B000CE4D99E37C7975E8EBC49780ACF2DF1B72
+:1087C0000868A09BE72BD52A5A973AD86FE9FFD5BE
+:1087D00066E18F06BB67BE8FD0DF1E19A3BC79A0F0
+:1087E0005D1F9B2A7FCE34F2DDDD753F02AAAF3DCF
+:1087F0005CF723FEFB1D3B979415939F7AD8E0AB63
+:10880000D9FFD89297FC74CEEBC1156FF889CE3B97
+:108810008FBDC27C9A18CF58A7AF26C676754EB5C5
+:10882000C6F7C8D4BAF7FC5BB2268F37C13F9B7C32
+:1088300014AED21F267AF864F567848FAF5B02CA44
+:108840003307638E30E7F9F487042C7EFE1BCD924C
+:108850004D5F6269F3FC7FFDD039E3004D000000FD
+:1088600000000000000000001F8B08000000000056
+:10887000000BFB51CFC0F003092FE440E59F914569
+:10888000E5CF9346E5F3A2F14DD0F83B2550F966CC
+:1088900068E615A3A92715E7B33230540271332BCC
+:1088A000AA781303849684D2DC405A19498D283360
+:1088B00076F3224C20F45F6306067D203B1288A7E6
+:1088C00068333034EA32303C07D28BB529732F3A03
+:1088D0009EA1495DF3463169D8D31C951FE8C0C0FD
+:1088E000D0E6084CF74E10BE0392FC13A05890033C
+:1088F000846D66C5C09008E49B9B6337D71C289F96
+:108900000494FFEA84DFFE5A0F54FE5F7754BE667C
+:10891000082A7F039AFCE22454BE722A2A3F270DBC
+:10892000420300C47CA5ECE8030000000000000046
+:108930001F8B080000000000000BE57D0B7815D5AB
+:10894000B5F09EC7792439E764124EC201923027F0
+:1089500009104A80138810103F27E121F8231E11C7
+:10896000687C5C7A788A081AABB5A1B5CD843C0CDA
+:108970002160B0FC3658A507048B4ADBD457ED6D57
+:10898000ED3D28A568AD4645AB96FE3D0408A8E838
+:108990000D58ABF7BF78F9D75A7B26999924807D7B
+:1089A0005CEFF7FDF1C3C99EBD673FD65EEFB5F63C
+:1089B0008EC797C7D4CB193B873FF0D4E25FAF6433
+:1089C00041C65298186986A7D71B39B88431760FEB
+:1089D000FC6353186BC4E710F817CAA4F22697CAB1
+:1089E000581663528E78C413604CF655B11854EB88
+:1089F0001591042B85E72416A983B224C6147609A1
+:108A0000633EA55D13B00F25CEA27E78EF8BE9AF54
+:108A1000D078AC5BCAC00AA6B16CC63CF81B742DFA
+:108A20002B310DFB49D5A06D0963AE603B8B15C39F
+:108A3000933DA8748D614C842ECF0D622C5006EDB1
+:108A4000A19FD41C169760004FE23F12127CE729C9
+:108A5000649114153BABD2B0DE9DC394C7C2F03E07
+:108A600087B7F714B19D69D0DE2D271302B467458F
+:108A70002CBC1B1EE9580FE59442E56111DABBBD21
+:108A80004C904B694E91DDD09F627CEF55797D6AA9
+:108A9000112FB70C61F16201BF83BA522C77FC1819
+:108AA000CB5EFCC652C691B0BF4D426AA4398CEF72
+:108AB00013219FAF771F5AC242653B94D9D9174201
+:108AC0000BFC96F79FBF11620A638FE6E6E833005E
+:108AD000FE2D2523D3111E2DAE4448B17C6F3E1BC5
+:108AE0006BAA8AE5117DDFF7D48B6C158D23778413
+:108AF000E6FB118E89B73DA50447550AF785634308
+:108B0000C95D3D701CF54F84E3468463B8178E1B26
+:108B1000116EE15E389A65731D1B87B4DBE0B711F7
+:108B2000E1578CF07B32B460ACE5FDD803A118B4FA
+:108B3000DB88708C30760703380E652C2C27755C2B
+:108B4000E7465867338CE1D1F484A4F68597BB5A85
+:108B5000528F0DB294BDB183F9305FFF2189E930A6
+:108B60009CBFF5354D0A227DC0FA689B63CCBA7F65
+:108B700040572CE1656C243CCF21FCD4549628A2AC
+:108B800086EC1CC3FEDDD43FD0CB5D482FFEB24443
+:108B90004282F7A9DE76260B482FAA300FFACFD2F1
+:108BA000EDF432A8875ED472847736D20BD40F0EE0
+:108BB000EAB5B88E5FDF14D3B1BF21D3E2820CE5F2
+:108BC000CD539E213AF2231DA5111D15221D852B83
+:108BD000BFF9C324F4FF892EB366E8A7F6B2AA1F33
+:108BE0006159D63DCAFA20D275D50F9348D76EAFDA
+:108BF0005207F0FB7E5A80F6B7FAB03FEE81F9B526
+:108C0000D4309618C558738D972580889B6A142A8E
+:108C100037D684E809BBA77F03DA7F3A558C374300
+:108C20007B39C834DCA79E67217FBECBA012E6BB90
+:108C30009BA5D2F33758CE22B4F146613F37FBE60D
+:108C4000A7B3E281F1DA1F116D704D2B4A25B89B55
+:108C5000E51435D356F68486DADA33964370A132BA
+:108C60006C802C6B2C82F393617E803F52FADCD0B7
+:108C70004ACBF8F73389E62949E55551785F2F301B
+:108C8000C23FB37EA820D2FC8B052F3D83ACFB8571
+:108C900073004F970FE00078E0F3CFD71348170227
+:108CA000AB1AA1200DC8A792E6FCF2A1DE955032C6
+:108CB0008BBFBCF59BEBBAFCECE5DEF9167AFABF8C
+:108CC000C6BEA4FAC5681CE092EA025442FEE1CF97
+:108CD0008FEBE12F639E25DD084779903BB253ED82
+:108CE000BB0F2719DF87FB19DF0719F7A1B4771F1F
+:108CF0009A7D7C1F8096FBDD876790F9C23E37CB5B
+:108D0000716FA6010F94637E5C3FD213AE1FF90111
+:108D1000AE5FF812D65F575119F5E1BA22040797F2
+:108D200032724233C3F7F9ED0998575DD6C809EBA3
+:108D300019AE9FEF5B5DAD4872C69C8F73BD4EF858
+:108D40005D2B70BA2C473CBEA477FD1B7DE26C5CAA
+:108D5000FF4699AF7FA3EFCB59BF399F169C0FAC4D
+:108D6000AB45E6F8D8E2FB92F0314DABEC8F6E4CA0
+:108D7000F86F32E0B6C980DBA62F196E69061EA710
+:108D800019789CF625E1B1399F26033E4D067C9A61
+:108D9000BE24F884516703BDF78F42F46601F03EAC
+:108DA000AF5ABD5E40BD87F9AAA448EFB82E378BF5
+:108DB00091DE51BF80DAEFDCB0485DE243FD424D09
+:108DC000BDC6A20730B69EE8677B4D9C1D1D817A0B
+:108DD00054B7407A6DB08AE4725E7594A19EE2C980
+:108DE000490AF834DFBB0CFD83D50749FF6E6802E2
+:108DF0003860BD571551FFCB6F0DAF477D096065DA
+:108E0000E81F51D23F86330E8FC70DBD83B1388D19
+:108E1000EFA9B6C3C565E81FDF945815F2854FBFAB
+:108E2000ABB9E7C3B8CB1373DCF980BF3F34E8BFFD
+:108E3000B3E6339AF7A7DF05FD11EB5BCADDD32D4F
+:108E4000FBB1537053BBE58CCB73905CEE6BC65A91
+:108E5000D75F6BF08FF404EE6BE74189F8EF40FBCE
+:108E6000B92CF4E43879626FF968934478C1E4C8A6
+:108E70003CA4EFA52D92D8DFF7E63A7BFB7986FA82
+:108E8000F9F43B9A1BF964678D5738EAE2EB53011A
+:108E90004ECB9BCADD9AEFC2F36E457CC8C2FD8300
+:108EA000EF110EDFE916B0BFE189FF10B09FE1D5E9
+:108EB000C9720DBFF7D15EB033D5EA0E9CDFE5670E
+:108EC000FF3D05F980D98FD9EF705C9F45AFFC61FC
+:108ED000B568ACAF7B0E7E9F77B77851EB1B8EEBFE
+:108EE0001BD40BD70D08576160B8DE53D33EEE7C20
+:108EF000F6816704E7071E5715E91F171ADF9B0362
+:108F0000FD59E8C89CC73D17D8DF26C73C36E4F0BA
+:108F1000F56F905BBD17336E8A0ADF5BF1384F88BF
+:108F200021FEA2ED49F62A63FB65D4630B230FE310
+:108F30003C8E1BF809DBACD5121DB3AA6605EDD932
+:108F4000D871A46F59D189DE50BD463EE4CA2E22A5
+:108F50003B8BF9B8DDEB9CCF76879D65CE6FBB8BE5
+:108F60001976C8B571B4AB5C62D1EDCD915E3B1A98
+:108F7000EC2A5D1A675977AE61F7318E371E05E628
+:108F80000BFBB761C4ACD032E8E72CCE1BF04E9B94
+:108F9000DBCAA216BC84799F15B2FACEFB9EDCFB1D
+:108FA000B5F530EE19581FF229D36E77CE3FC57B49
+:108FB0005731D205693EA8CF19FC2EAD18E6371EF1
+:108FC000F829E7296C4B2EB7CB7C116E976DC9E55C
+:108FD0007618B423BBCC2C9BFD6EC95586F82CFBB0
+:108FE000D73033FB1D84430AD897643F26D631A47B
+:108FF000174F0EF03778A6C81DDC7E2C05FB51C537
+:10900000792512C867C156237B72CBE74F52591F8F
+:10901000CBEB595129CDD3EC3F57146D7861AE0796
+:10902000964FF0F0CC7013BCFF5D88C922F2BFA24E
+:10903000C60E2980E3B712BF2D34D6ED84CF63B9B5
+:10904000863DE9C023D8E70756D33E4D9A8876631C
+:1090500044E4FBE3FC1EF62722F6B33F8F3DCAED46
+:1090600077D61AEC775F467BEF289607F5C5F7476A
+:1090700077CFCAE7FD70FB8F501CC6F719F3F7E4F2
+:1090800044B7211C25DC77C0EB6DA13D2A037DEEA2
+:10909000FE50598588F22E471571BDFF392C365D7B
+:1090A000B4CC77C87285DE9B783B53BA3BA513CA14
+:1090B000DFBF313F7D293C578942BFEBBB0FEC3E00
+:1090C000C4FF46B0FB64E0A79FFE6914AD6B207A35
+:1090D0007FBC861563BB9EF26C99F4B5C7F7E66F4B
+:1090E0009901A06808164E40BB575B15DEB69CF090
+:1090F00045253DF67A91CB1F80E7F56296853E8344
+:10910000265C611E1678A468ADB523508F61AC3B18
+:10911000AE203CDA13229443201F138CD6BF0CF1EF
+:10912000A0A058A97043FBFC5884C10EF6D22DAB09
+:109130007A11BF6F7B71048D6FCEF797069EB108D1
+:10914000DF379043A1A8BF3F3EA51B72026CBF1141
+:10915000586E17906E9B8DB2D92E5F8CDD89F318F7
+:10916000569DAA233E0E5B1317713D8F1AFAB7C0A6
+:10917000BCFB8710DE293B38DE251FFD11E15D7643
+:1091800009E25D8D280E847735623FFCCC5BDCAA5A
+:10919000231EFC458ED5617DA610CD6005A8777095
+:1091A000FF5A338EEBA3E9BF8EF8952B70789A7C2B
+:1091B0006968A9BA13F9D2A3C67E04D5D672EC2F7A
+:1091C0005CF656F90AD4D3623E0DF95C5E6E32232A
+:1091D0001FE9F94D8921BDE6CCDE553E13CB9AB788
+:1091E0003B3D04DF4513B5B8DF6950463C053640CA
+:1091F000EB6E02F8A0FF60C8F204E94583AA40E2E2
+:109200008A1639E3D643286F73D5957319D0B39076
+:10921000FF76B907C76D6011F41D0E5DD5C196428A
+:1092200039B7CCA360BF7961A5C28BF56B59A41681
+:10923000E6A1EABC7EA8E68D627DF04E9D9C204CA6
+:10924000D6D9B516BEEA57636B5900F91F87DF31CF
+:1092500039F628C22BADB883CA99739EA2679BAB1F
+:109260009D29A8374FEBD050DFBF6F4E235B62B113
+:10927000ABFED5D81F6F31D3E2163CDD26F1DFEF10
+:10928000AFBC2FE5A6626CC7FD1D2E56AFA13E8771
+:109290005E25C4D734C45795F0F51788F7E1E5117A
+:1092A00051447C2D8E2470DA409F83F93CF421F8E0
+:1092B0005DDB1C77258DA3B3B7D82498A768DFBFE3
+:1092C0001455DB8578B45674D178298747D3BEBD51
+:1092D000B2C4A709B02FA9435B13CFC13E0D06F856
+:1092E000A80AD68F15F2A0FEADA112FAB640CEB7ED
+:1092F0006A38AF6C1F8B68D8677EFB4B5F41782E56
+:10930000E7FEB3206B67A244F07A15E135E8C6F6B4
+:109310005AF43B797D1D3ABA8C1F97ABFEFC1D6851
+:10932000FFF84129A2AB163A62404716F817EF053D
+:109330003E6191EB3DFC5CD75E2884755DC5CC9F9A
+:109340000E19E737372431C43B56EA3A9634F59084
+:109350007C82766F19E6F5E1BA17F63F8476FE1443
+:109360008FB25BE95B3F17CBE6B800A7B3069E3F21
+:10937000FFF41F46A2FC7935E251D1DFF5B2D0D11E
+:10938000457EEE7249DD1DE6F3F34EC2EF19122D54
+:10939000E718580698217DBDAA491AE27B47A91013
+:1093A000C77A0F3B527F29F607F88FFA47C7B4A355
+:1093B000F597427F5709AC1B5D0D73CF32B96C42F4
+:1093C0002F3CE63EE53982F26B2EAECF029779BF95
+:1093D000B2AC17B718F10AE7FBA7C157FD00FB674E
+:1093E000E95194BB6CC69DEC19ECBF8CEB636B032D
+:1093F000DD734BA13E3A4D428B84BD5AF646107543
+:10940000D6724D20BD6DDE3421EEE9675DF0DEA53C
+:10941000C23ECDD54ED3FCE1A7DB53067CFF085FEF
+:10942000CFCB22EBAE85F9CF7BF6635A0F501FD11D
+:10943000BB933FF559C7347BB967BF67707FB9CC21
+:10944000B8BFDC2BC78649B0BEF0DE2BF4E9A85FBD
+:1094500027587733F1B918C9F15EB9CFE52399726E
+:109460008067E59FC93C4E1061A417FB5992846444
+:109470003AAE0AF62783A902239A8C08C827199BBB
+:10948000467186600AC78BBFBFBF1BA93F41DBC2C5
+:10949000CEA55D447F7292F0E61FD6DF05E697D237
+:1094A0001B5709A23F7803C873548E3D18A101F8D9
+:1094B0007F52CC086FEA6A147A7F4F4D88076BE4BD
+:1094C000A7891FF8226E15E9CFA73C41F11FE5D708
+:1094D0001E86FBCE40AAA2FD896CE85C01DAE3ECB3
+:1094E0008808789C1671DBEC4F6F8EFBBC76784356
+:1094F000D6C8C1E7D32B1043C2DEDEF603B5FB6747
+:109500003FEB407E852DFA8DEC0326E41D785D52FD
+:10951000718C0307EC752BFF9345EE4FA8F32DF5E7
+:1095200092FC3E7BEE9C348931436C30C9172DEBA5
+:109530000F1EB518BCB1E88B2EA5F17601E4982B6F
+:10954000B45CB3D2571D769485EFD768C9F3C05D7C
+:1095500092A3954BB85E4E719B2D698BD99162F4A5
+:10956000FF2FA67D6ECCCA0E733EC1FD1AC0E889DE
+:109570005F9878B82F6B512809ED1B862C0A217F44
+:109580006970454328270F663DA361BF8D67D39956
+:1095900007EDA2503EE98D8D670B0657F5B3AE344B
+:1095A000D4CE60FEA98C197E0C37C69A7AE6095291
+:1095B000BA290CFDA5815C69A679FE5AC3B88E5BF9
+:1095C00095ABB07FB72F4A7AC3ECD2766D09C6B19E
+:1095D00062BE9847E9DB8F390EFC08E7908F631B6A
+:1095E00093AE045B7DBFF37096DD8522D10FD80E5C
+:1095F000F1BA7EDABBBC013D6D1CCAFD9EF70A8E36
+:109600005BF8F2D8F4E858DE5EF5E2D08286F4D357
+:109610008BEF71BBBDA388BDFDE62335C4DBD00E47
+:10962000F0306F5573A42F3C1BDDDC7FC364AD129B
+:10963000E7572F644EC0B8CF40782D879A4E5BED28
+:1096400055E7D3A3B813886772B04A47F8C27C22A3
+:1096500057108B68E910C6D1F334D95B8AFCBE156C
+:109660000FDF90FC41C2B7C96C32C2A3CE977F5EB8
+:10967000FBA101E88B8D1AB8DEE58EC4A22407AAEF
+:10968000DE46792DB371B42E39E7C0DB6198C7315E
+:1096900089DB317290DB834C914F59F5855F0ADA93
+:1096A00031942FAE54DE8FB3FF97858A93127CDFFF
+:1096B0002045DFC776CDA3271972C74E370AD813C6
+:1096C0009CAEB58090CDF196FFC41322FA030C3DF9
+:1096D000D955BA9361DC5001FD8AF86591DC89F3B4
+:1096E000D1E03F9C8FA49D3C8C7A6E601ABCB7C0C1
+:1096F0004DD252898FBA186F6FE2A384701E874FC4
+:10970000FB7B263BE05CF32CF9F1CC75498CC7B7A9
+:10971000FAF033A1C22D67F55D1FEA405C6FAB6ABA
+:109720004238631C1FF5986DB83F2017BE5753444D
+:10973000CFEFD74468BF7E505346E5FA1A8DCA1B57
+:109740006B6653F9A19A2895DD43EABD08C76D43BE
+:109750005AB709A8C7B1E28A97E1936DFED6773070
+:109760005ECBF4D1152F037CB6016F6553D1AF3AB0
+:10977000A242073CD996C1CB5F91C7F0F288D6EBE5
+:10978000446A3F88B7CFE5F513E5B1153AF63F9641
+:10979000972F9727F0F62986BD93B3A05F3BBC9720
+:1097A000DE387FFB15065591CFE504C9D894D4A5C2
+:1097B0004C8057DBB20CBBD1E8070D9D6BFAB50BA3
+:1097C000793FFF222B84876873929F509149BE6E28
+:1097D0000B7FB1F9A4C8AD1AC1875D5671A80CFD05
+:1097E00026F0EB50C66EAE2FA3F5124B82F5DE517C
+:1097F0003F75BDB17EC3CF14650B2DF266051AE52A
+:10980000309F6D25F6755C68FC9B40CDC067FADC27
+:1098100024C3AD3925C5E6C918BFBE319140BBFA96
+:109820009E9C27B8FD69C06BE0FE741AFF76846FBA
+:10983000566F7B1F5819F87D44E6F1B787EEAC20D0
+:109840003CB9C1809F59467823BF7423732EED85A0
+:10985000E780E329163E9EDF17BF991C257B79918F
+:10986000A4D8E633C3514EF171BAB958784D757C1E
+:109870003F52526CF894E3280FD92B32B403862E52
+:1098800017CFAB47441CFD7AEA6F6711F48F1F9224
+:10989000488FAF66EAAC10F2E52681EC7184B7021E
+:1098A000721A737C504E8B4D19B3100F9732F675A8
+:1098B0000FD0D4525975A33DB9A4C9E3D0CBF83E1B
+:1098C000ED4B0E5A8F76F4E17ADEFFE1FA17FC28B1
+:1098D000DF17AF7BC13F19FDFA87A40882B1D3C05F
+:1098E0006FBD5A88A39DD4D974D4CFF74BCD43F81C
+:1098F000FEB986E70DBC6BE40D2C34FC584C56F3D6
+:10990000302FE55D57FC5F38FD2F22FC7E3745CDBB
+:10991000C372ADBEBCA27E2AF6D3D27885651DB1D6
+:109920007A41437F921665EE10FA8FD4C8C46666FA
+:10993000FCA03CC8E17ED59DB2DBF027693B91BF1E
+:10994000850AA3E956FDCBF93C62F825CCF2DD721D
+:10995000EC71C4F358FD6917C6A3627A861BF1F453
+:1099600025034F991CCFC5F5751A7E9C50211FFF0A
+:109970009355A37658FDF22FC9824D8E3BC7F95AF5
+:109980007DC62C5C075B2344C88DE48DE72EB6CCE6
+:10999000F3453940DFEBB7F371F421822D6EFB6F95
+:1099A0003297772FC9DC6FF537ACF325844FDF751D
+:1099B00032C3CE4AFA39DD2568DF8F1CE2FAD78B35
+:1099C000477EEB4AE23E2FC8B2D145EC6EC9A6F7FE
+:1099D000DFB02ACD56BEB1FEDAF4583F72A8878EAA
+:1099E000AA3DBDEDF37BF1B11C243DD27DE6026EB4
+:1099F000A730477E4C90C50401DE0F667A2DAA0081
+:109A0000663E8CA9470D9BA1BE03BFB13AFFA221C0
+:109A1000863F519501AF304D89CB71594F9A7A21CC
+:109A2000C027A798692901AC87F716393B748D6C5C
+:109A3000B36383CBED65FF5CD966AF7B1DFE067318
+:109A40003DE67AB34D39ABC55584F3467F7B48007C
+:109A5000146BDD7CF7FA39F07EA3CBE0E7955B79F8
+:109A6000BB24E37018BD68577FF11F90C05C6E2463
+:109A700023E548DF83E6EA3C4F0BC4F020D46FF3C4
+:109A800018EBC0FEE40E2FEE7730CAFD5F1946BE1C
+:109A90009FB8574BC1796C8ACECFC0FA143DC69A95
+:109AA000E0FB4151311E0F731685FE36FF6C399E67
+:109AB000C03CAEB9BA862CFDF93FFDC19BB4E0A510
+:109AC000F93DAB0C1AF41E3FAF1F556B2D4F2CE523
+:109AD0007A06E9B3F02681F10D0FE8F7A877C8C53B
+:109AE000F211CF38F27BE6B9FAF17B9AE35C48FEDB
+:109AF00084CBDC048F86C302E1517A5E772C8C7CA8
+:109B0000F32DEEC7D42B226FC7D0EF33C11DA9535D
+:109B1000316FAE5B45FB37EF709A8278C5E4AAC916
+:109B2000D7FAB99E9A38AF9E1A8D61FCA9FAB02770
+:109B300082FE971542EC12178C2F64578F4238A57E
+:109B40004FE371E0C0185685F45C79690EFBF7208D
+:109B5000E6ABC41E41DD2B041BD385F14A97C4ED4F
+:109B6000B8C475144F7181C0C438A68B9568A8BF5E
+:109B7000BABC117A7ED5C5E9FF6B2EEE8F5CEEE2A2
+:109B80007C07C093403A31EDCAFF1C169B85F02B31
+:109B9000D0D40A2471C9E78C0BF8B87C0DAA3B3DE0
+:109BA00016F9BAC8658F0FDC03EB4795E2B3640181
+:109BB000E9F3AE1CAE6FBB72F484D58E60C1EE319A
+:109BC000B2859E9BF2AFE7FA74B07DFC318B5EDE0E
+:109BD000B28EE7EFC1CF299CAFDB986F4BC94A6FBC
+:109BE0007FF6C2BB726CADCB321F772842FD9689DF
+:109BF000B1A5F83E45ABD2707D72618CF0E3AB2E1F
+:109C0000CEB75BFC7C1C170006FD24814BE726EADF
+:109C1000302E61C4D1B44A8D91BE9BC322CDAC1706
+:109C2000BF00EFBE6A1DCF8C4B38F3EC7AF2E8D65A
+:109C3000CBACAE14EDE8EF529E5DB5EE51D08FCDBA
+:109C400082559487B741F62A88D7DF945AA3B8394A
+:109C500066BEEDA7A2AE338C9F314D63EA45F41783
+:109C6000FAC7F6F7694A5E1CFDE2008EC9DC3EAD1C
+:109C70001A8FCF0D39BC5FAFB78AF8AD206BB6BC79
+:109C800085B01C23FDCCE58D929D2E61DE24B4931E
+:109C90005A4BC88FD09BB700B042FB28A411FDA53A
+:109CA00082B0C7EFBC85F6BC0E39C79E3F19AA8C9F
+:109CB000513F9FC0DEA1FC31F319CCFD917D2C9169
+:109CC00042F3E67E262455B4A737147E9DB5076976
+:109CD0003E71E93CFAA2CCB8BF0AD320287F93DDBD
+:109CE000705E39EA1C27B400E46E3FFC6DA0F6CC30
+:109CF00027AB5D16BA18F83B997559FC09BF442586
+:109D00001CE9FAEC39F23F935E84FD19FEF54E43EF
+:109D1000BE7F224728DFFB139F9B615E4D5D86D28D
+:109D2000887A86DE20A8B80F4B5AAE49473C5F724E
+:109D3000480A8A61636382281F6753FCE0DF5CDCAA
+:109D40005E607252C6752D290BCF42BE237D37420D
+:109D5000FE0416700BA8EF959795C4C89FECAB74E2
+:109D600021BFF8EDDE8934EE6ADF2C19F9D84B2ECD
+:109D70001E87F8F0B19F4D6230BFBA1FFB5982FCBD
+:109D8000127137CA87D54F491437B9E5A77ECA077C
+:109D90005FFDC4DA87E7423FC2CFFD341FE9899BEC
+:109DA0001EE1FEA73A9ACFEA67AE7D55C779BE2974
+:109DB00051CE705D2DE75B6B3D3C6EDDED773FBCBA
+:109DC000D3B2CF263CCCF2B2967023EAC9ABF7846B
+:109DD0004B90279AEF57CBEC6BE8B75A02CFF9FDBF
+:109DE000F09B6E83AF9EF2F3F88BB067DF625A6729
+:109DF000FB575DB84EA13EC37D1CE073DC801BB4F5
+:109E0000A3F5E88F0AF111507FEA5181AFAF7DECE5
+:109E10008E94308EBFC3BD94FCBC3C5F04E6FF351E
+:109E2000E4E3CBF6841B8742BB654DE130C681A6D7
+:109E3000FFF4C78124B77FC8CF702BFE0AEF6FDB1A
+:109E40007374D61F711F42DCAF70CB4F3F6F9C0AFB
+:109E5000E55BA67BBBE746F07BC9463FB73C79C2D2
+:109E6000FD4B98EFFB315F550AD4DFF6ACCBE66FC4
+:109E700078BFE3B81BE7F73E2C5501FBA0F465BBA8
+:109E80003F824967A9FF4F346F02FD19CEEFE133DE
+:109E900037E2DF6DED1BC80F74DB531FBE8B7CE414
+:109EA00036879FE27DFC6508CAC5D7C6EDB7D2B735
+:109EB000DB1F44FFB4E9BF582345D351BF607B0685
+:109EC000F56B777D5AD3316E3FD28221D73F7AF638
+:109ED000E3ED3A8C7FEA890FB6EB00D7839F7FBC16
+:109EE000FDDB08FFE75214C4F7DB1E3BBEFD5B50F1
+:109EF000FEF0598F8878B3FAB1F7FE0FD6FFF51749
+:109F0000A332517F99E0E6F2F2A3F0A7D92867EFD8
+:109F10007C6EE660C4CF3B9F9E3E989D475FFD08E8
+:109F2000F02BEEB1D26B9CFA519F15501965EC578E
+:109F3000C6D3B17FECE56E37F2C1BF0AACBB19E006
+:109F40007D6BD5A76ED4330E68AC1BE1F3C25347CB
+:109F50000F7C0BCA1FC27E79FAD92F58D93091FCD9
+:109F6000EF896118B7BBF5A96BAFBEAC149FAE0803
+:109F7000767F1BEB6E44FDCFF9DD6D878ED23E2BD5
+:109F800022EBCEB9B49F7AC6E17E9BE167BAADEA17
+:109F9000C4BBE89F72EEE387F8CB94BEFB788DDB01
+:109FA000EE87FAEBA3D7A527B0F2A941FDEA67E651
+:109FB0003EAE7D7AE179ED828F1C743C109C57197E
+:109FC000FA749E5B5BE2BE04F1E1F1471E00387E4D
+:109FD000F48E27321700F3D18F3FC903A1CD4EBABB
+:109FE000BA17231CBA9FF3283BE19BD5CFFDC18D47
+:109FF000795D1F3DFD9A5B25B9C70202F0D78F58E6
+:10A00000CFCFEB186FBD55E085B56AF7AC77A1DF10
+:10A01000B5D0858EFBB3EB43F7374B7BFD7CB7C6E2
+:10A02000AF99ADA23C8A67D1BA6F8D73BAB835BE0D
+:10A030006F01FA4B9D70DFE6160D7BAB775F8532C3
+:10A04000DCCF23B310FF06DA4F73FD0AAE7F32CEAA
+:10A0500003F63738F0FEF6D069EFFEE6219EFD44A8
+:10A0600048578569B05E57B71BF98FFE3349D91D34
+:10A07000E9BBEF4CBA317D09E9DDEB6D76ADF974E2
+:10A08000E2C3F71C748DDF939E67C0E542747DE1E7
+:10A09000F57C3178D5A1D3EA92BE70AB9DE921FE63
+:10A0A000FC4AD843E71D5E73A9DFBF03F1E3451700
+:10A0B000C37CF379F92764B51F7DE055C04BD562A9
+:10A0C0000744CB4ED70F2AC5B82BC817B5174F7BFF
+:10A0D000EAA749E4EF37E723292F68C7260E8CF754
+:10A0E000526036E589B2A8DC85EB0099209C137B91
+:10A0F000E183FA01DAB137E1AF2AEA173E36A394D9
+:10A10000FC24A45F2D639A1BF503D4855DF07E4586
+:10A110009B40F1C255AC95DEAF66EDF45CC33AE806
+:10A12000E9C951DDDCAE9AA17491BEB246C2F8E332
+:10A13000C5EA27E6BC32E72CD051BF3883E7BF40E1
+:10A140002FFDDD90E48394EF25CA559E90357F4F17
+:10A150001531FEFBCE8B2E9A2F9E336174AE84C7D1
+:10A16000219B8C38E49B08678C47EE79ECB1C7B231
+:10A170000D954744BD3DF61BB447F52AAED7BC50FC
+:10A18000E3A57642D53EF24FFC4E48CCCCC2FADB7A
+:10A190008509DC2F16D9AF40B9A04599807AE42B08
+:10A1A000463E4C8152222EB5C8FD1B5B122ED47741
+:10A1B0006EAC2A198A72E5E1CF259BDFC57C52B2CD
+:10A1C00000ACB776D322CA47DFDE20F2B8BA2F79C7
+:10A1D000DD5D308EAA7918DA11FBCB3DB97742F9F3
+:10A1E000DD3512E5B1BC5BBFD38FF265DFBA473610
+:10A1F0004D82F7E143F05E1D18CE3B0D7B7397E176
+:10A20000477BC4387FB3C7387FF3588D4ACFBD35FD
+:10A210004554FF939A0895DB6BCAA8FC448D46E52C
+:10A22000A76A6653F9999A28959FADA9A4E7AF6AE2
+:10A2300056D1FB40B33786FACDAF6BAAE87D588F75
+:10A2400088280F1335D5547FC29D49F85CD0C228A9
+:10A250001FB900D8645AD042FF3A23FFDC4E57F2B0
+:10A260003A6B7CE584C1DF4679B89DFA3B21B23E6A
+:10A270000BF9CC75B06FB0EE025F490596A72F08B9
+:10A28000AB88DEBDFB522E57145FFC7E7C648CB322
+:10A290006881C48A2C7436C307650B5F7AA7BC3506
+:10A2A00017F9C33BA8F00F65EC7EEFDA3AF49F3F55
+:10A2B000D20DB639E24BC815DF8D7EC49458F368D1
+:10A2C000DCD72118C9817249EBD0F99675DDE6E13A
+:10A2D0007AC3A3197CBE935F90C87E8E378CDCB99D
+:10A2E0009E64C57F9D3B07F89A87BF03D2BE6EB4BC
+:10A2F0006745ADA956FB22BE0EF44AF2CB30FA7E7A
+:10A30000C73A85E8212EF0731CF024BB49DF2DEEFF
+:10A31000C4793155A0EF1FF5F1F96E5F2FEEC473CC
+:10A32000103B0CB8C59556316299671EEBF16F4929
+:10A33000C4C755A6BA27E17BF8C9EFAD87E113E79B
+:10A340000C1987794C540F4BCADBC5B49471B67E97
+:10A35000481E14C52D65F837668FC55F06FFC6B663
+:10A36000DBCBE39FB5974B12F6F2C483F6F2251DC3
+:10A37000F6F2E4B7EDE5FFF21872534DF2BC099D19
+:10A38000BD85F943C30D7E383C7944C054D2039A4D
+:10A39000B71BF524008988EDF2EEB6FBEDD4C3EFD0
+:10A3A000511CCE992FA41E4EA338DC94A4B3FDDA21
+:10A3B000B5D85E75F8F7F2AB3B66939D5A2A62AE4C
+:10A3C0001DBBDA979029F8B63576DF1CD8A7AB42CB
+:10A3D00052448079BDFCD05F8BEF846FF2DA404F3E
+:10A3E000B7E487CF5AC7F3B267859329B8DF5E35E4
+:10A3F00062B8427AE02C9E9B3CF0FE69C052701E0F
+:10A400009B3EE7F4973987E7899CD1D59D68FFAAE1
+:10A410008747D3798B5704551480FF06BD1C1FAFA7
+:10A420009AE6B2C1756EC865DBD7CBBAED70BFFCDA
+:10A43000337BD9323F430E7CB1F2BBABA4E79FE341
+:10A44000F64514FD30DB8DFC9414377BFE4FE8BFDE
+:10A45000BC3E8DA19E95C74EEFC37CA7682B8BC4D5
+:10A4600019EE73B216CBA3B7F2BCCFD15A9A3D8E78
+:10A4700062E0C368031FFE7877AB9847F42D31CABA
+:10A480000FDBC5F7CF6BC4639DFB5FB8D5B1EF7D24
+:10A49000FCB9F063D987FC26B0F3419EE72F4FEE5D
+:10A4A0009B84EB89A6B6A25F06F68775DABEB394E5
+:10A4B000619C3FAE79F2F728076E58533209C133D9
+:10A4C000FC3389FAB92131BAC28DEF0F2D8BA7C0A9
+:10A4D00056DD7077B7D088F131BDDD35B118EB7F2F
+:10A4E000E12A407CFE4C30C6E57E881BAA93425D83
+:10A4F0003FFAF4F0CFDCB67603C99BBCCF646A6741
+:10A500009631CFB5D37561BE3D148558565FFE3D7B
+:10A51000EE395144E2FB899E4415858D5FA750B901
+:10A52000BDBE959E91DD20CD8BF15CC1F0412857D9
+:10A53000465733929B4F562BF47E6203A376EAAEC6
+:10A54000A4807ABAA2B78A28DFA11DBD57744544FA
+:10A55000BFAA5A9F4C619C0F533E791CE4F17AE2EA
+:10A56000A39D1B46E1BEFF466C273D20C8FFEDA81A
+:10A5700056491F32F92CEB509A897F57A712FD22BA
+:10A580003F4F457E5C2B1AFC9CF345E22F05C86FBC
+:10A59000CF0845D8AFC0D4A72336FE28121FBD9BD5
+:10A5A000D3899735D5A2DEF68FE67F8B9DFC8F7120
+:10A5B0003A4EF50A5C4FBC003F2C67767EFECFE634
+:10A5C0008FB7A1F283FAA14BCD20FD501719CAAD68
+:10A5D000B83E9FDB05865FCB943B4EBCDC5563F7F2
+:10A5E000BB8FA8E6FA86B35D93C1D72436FEDE6939
+:10A5F00030CE688C5B419785BB18C9D770358BAB63
+:10A60000D0245CDF9DC0F3BA23778974BF0063C98F
+:10A610007D983F1A2EF3281487D059A07C524FEA18
+:10A620000D8BEF5A4FFC233C4462988730A2D5EE45
+:10A63000B764716E2F79E13FE42723A03FE46B51AB
+:10A64000E06B09681F6DB3FB55E27AE7BE3FA19F3F
+:10A65000AE328D21DF0B3BECAD3CA7FDE5804F9E7C
+:10A6600071EEFCBF70DDC23F9F8F9F992D8B8E785E
+:10A67000D980FCFC215C9791A76DF273F5F018D19D
+:10A68000F03F30D794BF9F9F8F4E0ACF23FC0E0020
+:10A69000FC109FFFC7F0F3BB410F40BE007A00EAF9
+:10A6A0006B263FCF5FDEFE7BEA678D3009F1F186D6
+:10A6B000C4B618C2E386C2550CFD823DFC7D8DA058
+:10A6C0004F4EEFE5EB37E86A851BDB1D9A18AF1597
+:10A6D0007AF9BE93CFFFDDFC1DE913F5D3CFCE9100
+:10A6E000DE4A702E20BA213A839F1968DF9AE71557
+:10A6F00002539B867F17D6599F11227B37EC35CEAC
+:10A700004F18E772CCFE37B962616F56DFB81DE5AE
+:10A710007492BD5878DE735878EE93D9F034CECF6A
+:10A7200039E2B927CB7EA6A8436DEDDE9A26537E8B
+:10A73000B1CE52232370BE83AAEEB2DA258B5379B1
+:10A740007C6D712A9FF7277367DC3B03BE0BD485B2
+:10A75000B7A01D7DD3EF243A6F1E1ACFE87C49675E
+:10A7600053C10EDD12776D36F811DAAD3AE6D37EBD
+:10A7700036069838BC2FCD0CA8304E67FD1DFC5C0A
+:10A78000D3611EDF1F683F3E75E91EF43F6FAA4884
+:10A790005D15B7D8356B32F9FD03EB32383F1BE757
+:10A7A0006B9D87E8262B4CC5F92D9119C53560E8BE
+:10A7B000A4508071AD8817F7EBE8B30B368FE1DB5F
+:10A7C00065D8F131F645ECF8372A545AFF89B7605D
+:10A7D000FDF02ED3AF3562BEE5191610D1FFBE1CB9
+:10A7E0000F4AC2F3ADEBC7ECC0F1EBA7B8A97C6C84
+:10A7F000E1981D68FFFADB04D26B8FB95AE74DC5AB
+:10A80000F759F9917A15CB9157CAA0FC66A090E24E
+:10A81000A2EFC90AE5ADE80A8F0FE1F9107E490CF5
+:10A82000237F8C6BD15892CF53732BFE88F8B36F74
+:10A83000522AF1EFAECB78FE7AD7BA6E99713FAA61
+:10A84000A29730F607372F9F083065279437B9BB9A
+:10A85000F7A3FDBF29E0C531E0A77BFF5350BF52EE
+:10A86000C9A4F304A7BC61035F6161E447D202623B
+:10A8700019636F5F9946EB59D2C6C759629E1B9503
+:10A8800063EE4AB0BB1ED8FAB18CF5EFA34F06C6F3
+:10A89000797FF95FA8AC07D3BB47407FB7CC3DBDFC
+:10A8A0001FF333E30B015187811DD0B6A53118C4C6
+:10A8B0007B2F80A8A741B9F296034194C3B8D81C56
+:10A8C000984FDBE97AF4ABA7374B0CF9E5D5B36FBA
+:10A8D00069C47A6F6D3A13B1FDEC1D07F0FBB43A11
+:10A8E00010F8D3787B2A4FF4517B59E9A6F255A58D
+:10A8F000BC7C7CEBC7543E50C6CBAFCFE6E5B997E6
+:10A90000F948CE5CC95AC92E99CDAAE8796AE17393
+:10A91000278172D869644200E79B77ED681C8AFD45
+:10A920008F73D379AD956D3F8B2CF5D9F8BCFB1C9B
+:10A93000AC8B682F9B9BAD2817368AED11CCDF912D
+:10A9400053993603E0B951685731C736BD79537D05
+:10A950003DD81BE946FD58AC2FA37A2A278B3EAE83
+:10A96000DF3FA5B7FC8CCBDFC0CB8CECF3FFD8303E
+:10A970007C26DAE7E9535894EE13615C6EC12B9D97
+:10A98000F42CF87DFDA4DE7954A6BA8D7B20783BAB
+:10A9900078F5336CF756E5B24D68577535490AE1DD
+:10A9A000ED682D20E30263D100F2A37BF74D09A0EF
+:10A9B0009F2F7DC3443A7F0CCC5BC1F8CDCDC9D667
+:10A9C00059E8175DAD0BED28773A6546719A0FEAA5
+:10A9D000CB551D9A4DCE184178B42419DB3C05E0C7
+:10A9E000B64AE776DE2A6F77079E63B8FA07FC3C23
+:10A9F000CC51B97D1EC2B5EB4149AD85EF925B9755
+:10AA0000BD3205E97897A4E0323A9B9605900F1E77
+:10AA1000655B886EF42689F2B229CE87F36992B815
+:10AA2000FD6FE4AFD0794E58DCF19CB886F1BDA340
+:10AA3000829A7F1FEEAFC12F525B7EFE4DF437F737
+:10AA4000E46915B3F86E8B9CC3BB7D70FFD39A2469
+:10AA50006D7400F02185FBB3528BBF985EB02AC99C
+:10AA6000FB5FB24B88ABD0FFB1AAD6590198CFB2E9
+:10AA7000AD02BB4FEDDB7E59FD0E867CE016204813
+:10AA800035D2B79E62A3485FD01FEA87A784F8E655
+:10AA900032E4E3A36523BFCD311F3941F0B939AAB0
+:10AAA00018F9418E7A9D1D28B49C9F70D6A7ED2A77
+:10AAB000DF87FA0A037D4508F5AD7F63EE932C0F1F
+:10AAC000FACF05BB11E907E063D32372AD7A06F92B
+:10AAD00001B47DCF05B93D8BFAC28A7AFBF997AEF6
+:10AAE000B6E9A4F7CDBA8EEB7D41C7F75DA7B81FD5
+:10AAF000C1D41F82869FA00B9EE8EF7939E47A04C7
+:10AB0000F19775277C8B005F675D63FA0D349BDFDF
+:10AB10002050C0E55D85B784FC9E571686899E67E8
+:10AB200028D7CCC880F2EC1C5EDEF479D5E268B19F
+:10AB30006DDD363F038206F5A120B3FB19AECAE0F6
+:10AB4000F8F2C67A89F8D9895A97BA33D8570F8557
+:10AB50002F2EC1BCF1CE0D833351EF39817887EBB5
+:10AB60002BE779834E3D156A5CD9D0FEA60733C822
+:10AB70004F3BA7C85E7FD383820BE5C61AE31CEC6C
+:10AB800015AABD3E738EDC508DF24A9529AF638DB8
+:10AB9000E6ECFF8BF927E857E82F4FE7F967070D39
+:10ABA0007D36431448CFCDBBD443F726CD66C2F3E0
+:10ABB000B8EFCB60DFE3643F687F407DF50ADE15C8
+:10ABC0009B03FC16F16805E011DA039BBF7554780E
+:10ABD00004E120B22AF447AC6849B3EB3939FCFCF4
+:10ABE00097A9CF7E7A64CB8C4CF4F7CD5722B51C55
+:10ABF0008F6DFAED6C55207F4936DA1378FEB1D2AD
+:10AC000081A7A55F2F2FA0CD544E533EFA8C63B57C
+:10AC10000F4379B8E6FD3ACAC3CC3977523DE0ED2F
+:10AC200019FCDEA91F9BDF2B1521FADEAB76D716A8
+:10AC30004239572B223F7FA6BFAABC80F40430EDD7
+:10AC400094BE76E4420FCF771A7CA73D4FCE79AF02
+:10AC5000C79F520CBB3614A578D50A1FCFFF625B85
+:10AC60005DDDD67CFE378D7BCECE1CBC96E252A637
+:10AC70003E332DC37E6E364515CF7F0F1473C81338
+:10AC800080ED7A8B5CB3C891B82147FCA80F9A720B
+:10AC900064548A4AE31DD3A29B5D189C5035CAC7F1
+:10ACA000084CE7F4B7726EC94CC49FE44CB03A410B
+:10ACB0006EA6617BD23B12A4AF1C98A108CD2528BB
+:10ACC00067799EC0C6B12349AFEA332F8069E3A4F8
+:10ACD0007EE7A5E3FEE0BC04CBBCEA3340BE15E052
+:10ACE000FC8CFCE1D95CCEF5E93764979F967E5BDE
+:10ACF0004DB92994F6BBDE00A6A8B19016FA22FD44
+:10AD00000273DA72DE7EA3D180BBA06FBFB08A5A15
+:10AD1000130E62FFF3EDD91F271C709E3D70A8042F
+:10AD2000388CEDFD2E60C0AF8F1CAA2CD87C896AB0
+:10AD3000DF5F89824F03ACF702FB23A6F27D1F6819
+:10AD40009FCCF699667F03CCA75E80F59C675F0772
+:10AD5000FAFE32637C673F17BB0EB7515F709E757A
+:10AD6000B82CF4947DB1708D01DD487DE10A43B7C4
+:10AD7000E3F723537AC6EB577FEBB5DB96E4A11CD0
+:10AD8000EB32FC8FA6DDD6D5C6ED36D35E433B4D08
+:10AD90001F64B1DB72AA3CE87F6A2ECDE7765B1BAD
+:10ADA000BF8746997C635EA1AFD73EBB2E93E73346
+:10ADB0001D5FC2F3809CF6DA421FAF3F3488EB5F21
+:10ADC000D7FB62F3CA615E9DC1FBDCB41D153C8FED
+:10ADD00059C8E1E736591EB7D75C4CD9BC4840BFCB
+:10ADE000C9C4803DFEFA45ED36D03F510E67CB64B5
+:10ADF000B7D2CF24CA53A0E4B395651D8D98EFA8B0
+:10AE00004B6A15EAD52BDB5E737F17DABF955F4877
+:10AE1000723273CE5FCEA13FEC2FBA40FE30D3AE7C
+:10AE2000EBDA12A6B8F85AC5E2E7807F5D2ECD8D29
+:10AE300072B84B50235B2378BF0ED41719F333F548
+:10AE40004CB413170DA3BCF82E974A7ADC9BD9F9A2
+:10AE500064FF75CA600FA2FCF38964FFA1DDA883BB
+:10AE6000FD2C354CD7D01E999A3BFFC1548A73F7FD
+:10AE7000D883E477D837E92BAF61BFC77FEFA2B3A0
+:10AE80004AE5938BB760FDD1D7A01CC6F28DDBD10C
+:10AE90008FD4F98E87EA8FFE02442CB4BF2BDB4D92
+:10AEA000F74C75EE8332DA8D0F7848BF6C70A9DBF2
+:10AEB0007D08B777FC0CF341D00E8D79300E0D0C68
+:10AEC00085EE37D445B40B811D66733B511DCC9F75
+:10AED000EDF4FC1EFA4F28813F21F2F71DD9BC7D0D
+:10AEE0006C307F76D3B32B85EB59E6FE950EE2727C
+:10AEF000EA33C5CCFF6079C8971A5218E1C989AB0B
+:10AF0000C4B8359FAD479E05B8BFA221C3D4DB228C
+:10AF1000D791FE3D375B44381F8A2E4BBD04CA755E
+:10AF20006DF922FA6546A6713DEDB51905B9E847F8
+:10AF3000FA79BD87EE013D126E9F877A9B2E78DBF2
+:10AF40007743FB7C6F6C3EF693DF26B33AF8448B75
+:10AF500065CC001A66F3CA76BCE20FE294BCEDE859
+:10AF60000728F471BBF9833DD37F7F25BC3FB557DC
+:10AF7000A671165CFB1D09CF891FD18ADA119F1EAD
+:10AF8000CFF2703D6F9387F2E07E93F5F3A1CB8013
+:10AF90009E76312D15E3AAFA2E89F6DDB9BED15978
+:10AFA0007CBEF9BB97113D7619F7BEDDBB6FDB2B7D
+:10AFB0002AF47FB4B54246101D95397EADD953BEF3
+:10AFC000AB16A674D2A0CF859E4423DA1FEC0712DD
+:10AFD000E5057421FE20DEEF1176A2BE79B46D592D
+:10AFE000201FE0F6DEA3E5DB87C2BCD719F0A9433A
+:10AFF000BAA7386CA409E9E8BD0D130759EF075942
+:10B000009766DE2F64D85FF81BFA190DFB2297991B
+:10B010003F8EF3046D0FEBD81F7E371CF02377D7DC
+:10B020006F6BD14EC4FB32306F25D5CA1F896E3A83
+:10B03000E85E866178EF81827CB9BD1CED2505EF65
+:10B040001300B8E6DC69D7ABDE982B91FD3214FD16
+:10B05000AD91BEE714C0FE233FB40E7A29EA99975A
+:10B060009E941DE7F1D93ED41B57578E21BF88E22D
+:10B07000D0FBC26942BFEBEEAA7FA116E735CCB880
+:10B08000D7C0B9EE63AEB88EF5CBE03BB44B9DEBC9
+:10B09000CC697A631FDAAD80FE4A7A59DF75759DF7
+:10B0A0004C503E8F733DAB4F451BF1FD8A76FBFD47
+:10B0B00008CE79EF6AE2F7CF4CF5F173BA535BC56E
+:10B0C0001DE8F7BF94B5D761FCDF9515A47C978682
+:10B0D00030A7A3CC3933D2ADF77BB4A471BA2C68B6
+:10B0E0001261AB7AC719D19ACA34CBB8A3DA326DE0
+:10B0F000E5D1F1A1B6F663F6E4DBEAC7B67FC55643
+:10B100003FFED909B6724962AAADFDC48315B6F2F5
+:10B11000251D57DADA4F7E7BBEAD3C2579BDADFDEE
+:10B12000A52797DAEA2FEB5E6DABBFFCB3AFDBCAA6
+:10B13000E5ECDBB6F6A6DE6EEADB267C1A0DBAF984
+:10B14000769A68F8634516B7F41348E3FA2FEAF7DE
+:10B15000BACD4F2BB298A5DD370DFCCA98B9E0BC2B
+:10B1600079807586FCBED7C883D964E4C134187968
+:10B1700030F71B79301B8D3C980D461E4CC6CCD247
+:10B180007730FFE9931BF95908B015B6D3FD2B456D
+:10B19000DC1D306824E3F7A780DCC37CF95824A1C8
+:10B1A00063DC51F6D9ED06659AFD5EBD4069A6FDEA
+:10B1B0009EDFE0505BFDE0CA7C5BD957FC155BFB72
+:10B1C000D4C209B67AA75D722A959F5BE864B1572D
+:10B1D000D0AF52CDF47D78CF2EDB2A187E1CBD1C5B
+:10B1E000F30E5D5B859DD6F390504EA4F0F3C37FC4
+:10B1F00045FA30F3DA9951466500F3D0AFC6B19005
+:10B20000AE2F6C67D139D36F6FFCD14C3C573B509C
+:10B210009ECC09CC9351314F46CFB3E6C9BC6EECFE
+:10B22000EF49479E4CD7A6513BD7D3BC789E8C6C38
+:10B23000F8A37E19E478B59C556D16C99EE27E0888
+:10B24000D263602E5D193C5FA64B10395FDFE4D9F5
+:10B2500081F3E8C23C192C3F64F8C9D425A4179F98
+:10B2600030F2648E3D20519ECC51433FEC52A26E91
+:10B270006B9E0CE82FA6DF82F264D61A65675E0C1F
+:10B28000CD03E6B576AB4079316B7BBFFB1F9117E1
+:10B29000732268E8138EF82F53BB49AEE4F5C895C6
+:10B2A000642DCA25D5902BFF5D7931F0332305FD40
+:10B2B000D1A58282FE9D971F5AD93247EDDD87A026
+:10B2C000332F6600FFD6DFEAB71AEDE3F87895F181
+:10B2D0005E82D99FEBC70FF5DF152F6533E4E731A9
+:10B2E000EE3C1CE3CE4AAF7FC9E93F32FD4B371B32
+:10B2F000FEA539986F09E5D5D58CCEE3ADDE65F7AF
+:10B300001F5D91E4FE20333EDA3965F5BC0280F31F
+:10B31000F03915E56023B2CDDFAA9333512FB89EE3
+:10B32000DFFF9121D68E7E04F1E3DBFCFC9B576DA1
+:10B3300075535CBE8F1FEA35C29BEDA272BA36D23E
+:10B34000173F9C7EA7C16D7718FA4EE80CFA8DF274
+:10B350009AFE4065A5A2E834DE2FE4C417B3BD22EF
+:10B360002AD43E73CED659E837FFCB9D8CFC954E40
+:10B370003C75FA9316D26561587A6126E60D9AFCFF
+:10B38000EBEA8DCF3520FF2A197FD5EFC7201FFDAF
+:10B3900037918D80751E427B16E8E548F4320CA982
+:10B3A000B3FF353E7722DECBD893A700F8887643EB
+:10B3B00057DBB5B63C851538443F790AF7D7D8F343
+:10B3C000D507039FB0DA89E6734726C7C33307273B
+:10B3D000B26EF4BB015F47BD3C7BEBE904DE5F7DF1
+:10B3E000CB2E89F214CC3C843C66FE24898E871BCC
+:10B3F000F7620DAE74FAB7BA491FCC36F0A96BD715
+:10B400001D02E249F60E81E190ACDA9EA7D0D5F696
+:10B41000F13E6BFED5AABDAE4E2B3CB399256F21F4
+:10B420008CF71A7793FF7A13E015FAF9863BEA8FC7
+:10B43000A771789A700A1A700A3AF21536462A48A5
+:10B44000BF3F96C366233F9E29F96E7F01FD87DAD1
+:10B45000B441B885E593D7E41D85F7BFF0F1788E48
+:10B4600022C5B6A7E1BEFDD1437EF1AE7DB15199B3
+:10B4700016FEBDDA279879F4647F291E7EDF2DEC55
+:10B48000868076996795C07C563DD267EAF3A65DC3
+:10B49000D721E077CE76181744F8930AAF52594275
+:10B4A0003FAEC7BC978C5531BC977B7CCC47E755EA
+:10B4B0005907878779CF0793EE4E58F3210657DA5D
+:10B4C000F340C61FBC83EE65532ABC51C4F7F10E8E
+:10B4D0007866B3DB135C3F4F6348F71E473D1D3171
+:10B4E000417F79A98FF880330FBF458D533CAFA5BD
+:10B4F00092511CEAA6076FA7BCF27B7C467E7E3188
+:10B500002B46BA05F847701D670EF13C65A520E192
+:10B510004579AAFC545210FF3F38FBDB00EA73A7C1
+:10B52000921EDA2F335FFF2780EF784F64BB714F95
+:10B53000E413A09761F929D0CBB0FC0CE865F87C46
+:10B5400016F4327CFE2BE86558FFAB9A322AFFBA1C
+:10B5500046A372A266369577FAB83EA9A4697978AF
+:10B560003FFFBE2D57E4AD83791D2FF7D1BC8EFF71
+:10B570002236BCBFBF8BD1EB17D15DC6B90017EE29
+:10B58000A7E9A7692ECDDF82F49C8C1788785EFC32
+:10B5900064FCDA74CCFBF6F9857ECF33BC5B63CFF9
+:10B5A000374AAEE2F6616AC9FE40A1859E7F6EF819
+:10B5B0007D4EAD7251FDC6C813FDD67FB0867FEFBC
+:10B5C0001C67B15F26BC9D90135DEC877637ACFDA0
+:10B5D00006DD7B51CD629BD08E676D3C0E58E7FD3A
+:10B5E000780C9E179052FE738CF5EF55D419E777BF
+:10B5F000DF526201EBBDBAFB0D3957E737F49D50BE
+:10B600002C5052DCAB97E7EFD503F32D791A7F3638
+:10B61000DAA7E339718A77B300DA5900AF00EAC3D9
+:10B62000AFA3FF06E673E2459E17D1E98BA65BE95F
+:10B630006FAD5FB0F9DD9F37E087EDF01EC50A59A9
+:10B6400095FBDBB7E95EFB79B5CE26CE67F17BEBE8
+:10B650007D40156D0533703ED359A41EFB717ED716
+:10B6600020C7284EAE3337DB5D4AF327FD70E1601B
+:10B670002FDD6BB9B2ED9AB1D8EFD4DC8AE3BEAC62
+:10B680005EBBC6399FCF0D3838ED1DF3F9A951DFE8
+:10B69000A38FEF15E23C2E6BE8E37B859DD6F3F993
+:10B6A00050A6F3A917D2C79926AB786F8760F01917
+:10B6B00017F015D433EB56B19897FCCEC6BD70A8E1
+:10B6C000E720DD5E406F37E5B2A8F3FEDF983B5D13
+:10B6D000C6F5CF70C41B9DF2DB5936E5E7872DDF39
+:10B6E0009EA55BE8E8C41E89211DBDBFE7FCF73AB3
+:10B6F00038E9E8C42AEE5F4D2D596EA313D5CFE982
+:10B70000A4AB878EF2FBADEF1C808EF2918E2E21C2
+:10B710003ACAF767F5D2D11643DFFF5E0EE02BE29F
+:10B72000B591DFB412010D7079CA41FFDB1DF3CD75
+:10B730006BEB5F7E3718F8BE6548E4458C83E96F94
+:10B74000727F566A49F0BAE5E8A7D252290FC09431
+:10B750008394DA5280F3E928C2A7394E1CEDD951FF
+:10B7600078CE4321BD619761CF3E62D8B37BD09E36
+:10B77000A5731E11AADF8BE73A46E17ADA9FC7FC70
+:10B78000D44F16B012E4EB4773E2EB53711E5156DF
+:10B79000629CB70E9467A3B6C00BE967D3B93F7735
+:10B7A0004D09DD93B2D89F4DF3F718F7C89B72F996
+:10B7B0007B6D921BE5DB0D98E7487E9D44470D7C31
+:10B7C000E7D92AA9145FD75DB67BAC82209F507F52
+:10B7D0008D817CC3FB78B3A28EF3A36A5502F5D6A4
+:10B7E0002DE53C1E7E83437E65B1AA04EA13CB415E
+:10B7F000BE25307F25F95B85CE3B44648676AE530B
+:10B80000DE05F56B043A3E145286E03D4C7DFCECBF
+:10B810000E3A0290C58055001D45490F39BA6AD0CD
+:10B82000E645B82F3D7E764E4F03CB13BB9FBD063A
+:10B830001D6000B7D72BAA6EA5FBE6158E573D7C81
+:10B8400074203E08ED906F5D341FF4F2F603CDAB2B
+:10B85000A75FA39D933FFED9A7DAF0DAD9BF8997F6
+:10B860004B0DBC1CDED43F9E8FF373792C33F579DE
+:10B87000BC27C07388DF33CA0657F5FBF7A94CBC59
+:10B88000CEBF1BF422D47B502FE27A4B57B2C8387C
+:10B89000070FFFCB939382F5FBE1D50E3DD6382FF2
+:10B8A00038D0FA9D7ACE0EBF5D9FE9396F68D0FB24
+:10B8B000CDD4673FFCDCD063903F9C0FDE7DF8C2A7
+:10B8C0002E0E2F138E471CFD9B701B5E2F10FFDC6E
+:10B8D000E8FF7EA35E88FC612BE9BDEFA1DE4BF69D
+:10B8E0002BD72F7739E8F4FDBBF97D467FF573FD43
+:10B8F000F77B7BB8DF64782E8BE3B9FDC2E4EDA45F
+:10B90000571E00BA63186768B5DF2F877AA755AF4F
+:10B9100077D2A5AFE44ED22B8F1AF9024E3D1EE826
+:10B920009AF66F39EC1FEA9D47CF7AE81CD291193D
+:10B930006ECAAB77D26516502FD6AF00BA4DC0BCD9
+:10B940008F24AF700FE1FC88F417E77E81FC9A85A5
+:10B95000F55B162A74AFD03B03ECDF40FB61EEDBF6
+:10B96000383FA74753CFB820BD18EDA6CB918BA386
+:10B9700043F922E950FEDBE8F0EFD5F3848011BFF4
+:10B980001850CF6301EBDFA9E9ABE769A4DFFDCE77
+:10B99000C7FD8DC774AEEFF5E4538A3C9FF26AA6EB
+:10B9A00052FEB60462B67608C6993EA6FCCA4E3070
+:10B9B00096107F165CFB39E5571E55442A4F29D651
+:10B9C000EB5075D884DE1AB417EF1329FE364A4CB3
+:10B9D00048C86F72038434EC3296947A2EA981762B
+:10B9E00097B70914E733F330971B79983D7FBFC3AE
+:10B9F000CCC3F49DA1BCCB93808362063C310FB3D2
+:10BA0000B4370F7335E66106AD7998B7535EA52557
+:10BA10000F93F2320FE8E9948779755982F4C74E93
+:10BA2000232FF3EAD91B0FF03C4C8F285AF32EC773
+:10BA3000F33CCA9EBCCB082FD7F9CEF0BCCB524703
+:10BA4000DEE5145E06BB9CCA574EF391DDF8C1C219
+:10BA5000E7F6A09BA23C904F7048DB7E5AC5B4CA63
+:10BA6000956DB56ECABF1C3F92FC1D03E5915C2825
+:10BA70007FE462F335DF507AF231295FB3AD75F4BC
+:10BA80003DF5537AF335958C9E7C4E2A6FDB7157CA
+:10BA9000D3FE21BDF999C3B66C9D8D7A619AC4CB52
+:10BAA0004CAFBE12CFE998F5F919775D89F503E639
+:10BAB0006FA20D6D892BED54B85D9E0AF36D9D400C
+:10BAC000EF357F263C61E2D999F45E4F4707565126
+:10BAD0009CF0A3FE2AA6E03D0A6F6119FDCA370259
+:10BAE0007E96205B0574437EB586A958CF8A383C84
+:10BAF00052991EA7F331B15623EFF366A2BF939A72
+:10BB00001CC1B862FAB63A9EFFB94550306F7C79D5
+:10BB100052233EB6BA9DE77F76C909B2A74F6C2D76
+:10BB20005751EF3A98CEF33F5724F579FC5E102930
+:10BB3000887AF16A6FEC2ABC37E3EAEF0B411DBA51
+:10BB40003BD15A1ED0B83F224071FA2D12F93F4F17
+:10BB50003281ECE91506FEB3D6FEF33CDFCB896BF0
+:10BB6000388F9398E709FBF4D5744EC7A9F19F7FEE
+:10BB700013EF673D667C3F609E672BCFF36C30F818
+:10BB8000C5EA242378AD88F3BCCDBE799F3AE57130
+:10BB9000BEF733813D00A5155BAFA17BFBDF73B51D
+:10BBA000E6215F7B2F6CFE3D05A77F530960FCFDFE
+:10BBB000E6784618E5574B80FBA3576DDD41E7D388
+:10BBC0005763DE27CCFFE6F6259B71BEABB64A4C29
+:10BBD00043FF82C0E7A3EFE6F18DE3305FBAE77A77
+:10BBE000B7B08391DE69CFE3F4B1760DF370D14540
+:10BBF00081F49496E4799CA63C74E66982FD4379CD
+:10BC000099B9863C74E66D9E1012EE6138FEBFF065
+:10BC10007CF4C10BE42F94B7F9725B5D1DA2FFBFEA
+:10BC2000223DC3BEAC8A0B19782FFC941689E8B864
+:10BC30002123E6A7BF83B1A12013CFC09BE711DC6E
+:10BC4000430E55E1225E2A2D1631EFC2EDAA5A4A63
+:10BC50007F8FF3A12234DDD803EED8D66B10DF1E20
+:10BC600010291F1F16FF0DC4D759DB0689189F6EB8
+:10BC700008C7026F9652FC2513EB2B63D76C47BEA7
+:10BC8000A5E9791998577EDDF292391A3CCBE7661F
+:10BC90000AC817DE48E77AC971975A41F8B201D647
+:10BCA0008B7E7AE04F58865A65D314BAAF773DF64B
+:10BCB00053B8219DE2CAF9532BC56C80FB4857D578
+:10BCC000503A847FF6E362A49F57D3C336F9967F38
+:10BCD000F88A83888FF3F3AB56E2FA86ADDD9F7165
+:10BCE00005F49BBFA190EEDDD9247778159F0D6FE9
+:10BCF0002ECA6F6FFAFB9DF2F7FAF41EBF1FF1EB2D
+:10BD0000A8EE52F15EE037D64B2EA4D3F70456B519
+:10BD100093FC743C0FF5E40E9E87EACC5385762E97
+:10BD2000BC27460FCB948F39505EEAAA38CF4B65BB
+:10BD30004596EFF3FBD2C19A78F8DE19EADF9F7FD0
+:10BD40006AC671CC38404F7C00F349613EAAE18756
+:10BD5000C4F800DA6137A11D46F10146F18295C6AB
+:10BD6000F9B3950F3ACE5339FCFA7DFCF8854B04B4
+:10BD700064B34E7F3E282C145738037A238EEBF49D
+:10BD8000DFBF1CB92313F984E4E5F75B34D7E81A65
+:10BD9000FAF7EA0C3BFCFE9A26CDFA77958618F85E
+:10BDA000F8B45B0BA5A33FD6F8BB2BC75DD16839B0
+:10BDB000EE4783407A91A967AF61961FF3FE0BA10E
+:10BDC000B74C76BD80E31FA0F1D3DA7724906FA63D
+:10BDD00015313C49C406B72DD987E5C1952A9D5B2D
+:10BDE0004A2B82F959F0607025CCCFB25E33CFC6B2
+:10BDF00089776F1AF336F3079CF58D46FDFFEFF94F
+:10BE000003985781F870A1B84C4DC0C86794391F8A
+:10BE100030F5810BC561081F2E260ED3DEBF7DFBDA
+:10BE20000D85F38F9E38CC1E230EB387C761D6C411
+:10BE3000FF417198F81D02FD1DDF872E2E0E7353F2
+:10BE4000BBFDFE9A2F1A87F97340BDA8384C7E358A
+:10BE50008F8F7F1272515EE223DDF6F3078FB42DD0
+:10BE60000D2EB7C0ED9F1D9FFD91B11F6FAC5F46BA
+:10BE7000FCFCA471AE807EE0196DF1907DB0609005
+:10BE8000BB01E9F8A8A056E1BDA9173AFF7A5260B4
+:10BE9000BFA9B6F077677CD7E4EFCB5A387F77C677
+:10BEA0007B975D808FFFB3E2BD3761BC57413C6932
+:10BEB000257B276F2FE86342DFF8EE2D0FDAE3BF13
+:10BEC0009D531E708BB08EAED2335BE88A62839F27
+:10BED000A7FA385E6CFED6A030FE7D37FD5B3E9241
+:10BEE000FF6D4BDF1F8274557FD95FE8DCD231B024
+:10BEF0004751CF3AD63A7D1EEAB1CAFF1614E497ED
+:10BF0000771978F58150B5985FC6A3513EF5217C2D
+:10BF10007F49AFDCFFC19AE7534659E4FE57D2B9D7
+:10BF20007DB984A9998561B4B3D4CDA351FF6813B9
+:10BF30008D733D5A9EF5DCE83843AE5F285FB0CE86
+:10BF4000C0979E7C41E3EF48DEBB6F34CDFBB891D8
+:10BF50002F78DCC8175CB98BE70B4E54F87D7D0B4E
+:10BF60003DF18D884766BE20935BDD682F77311EDB
+:10BF7000973CB5BB7631E6091E37F206CF187AB783
+:10BF80009927CC6495CE7D9DDC6DCF17FC389D9FA5
+:10BF9000DF7C8FC53697717DFCEFCB1B8CFF96E263
+:10BFA000EE17CA1BFC7F8D10CFA700800000000099
+:10BFB0001F8B080000000000000BED7D0D7814D5EC
+:10BFC000BDF799D9D98F249BCD24D9249B908FC9B3
+:10BFD0000712BE3721E14B6E9D8448510117448DF5
+:10BFE0008876415444BD77A154A9C5664202040C29
+:10BFF00061116C438BB8C46003177B534BEBC7C50F
+:10C00000DB25A0B5B6FA868ADFD06E225082DCE747
+:10C01000467BB5DC7B6D79CFFF7FCE24339BCD078C
+:10C020006A9FE7BDCFF3A6D5F1EC9973E69CFFF7C5
+:10C03000FF77CE9C19E5B190AD32214ED27E747A55
+:10C040001921B2EAE8DDEA25247BAD7426E220F866
+:10C050007799FEF3D63CCBD127DD84644DB7CB1660
+:10C060005A9FF580B9BE8790A32FD37A4D75F8F605
+:10C07000D3FEAE3E6FAEA77F474FD3FE57558F27F7
+:10C08000D0BF4C0CF5F98414CB0221E55854A4A977
+:10C0900084C4C37F151072AEF158C54CDAEF288105
+:10C0A000F4D246F44FD2783BE1B29D908BD6900A01
+:10C0B000F577D3768F7BA15D5F3DF69BDDFA564524
+:10C0C00026AD974522274D1F38AF73E7B53964C2B7
+:10C0D000C0F9ACBA18D804BFDF1BB29E8914F7FFB1
+:10C0E0001E3DEEEE86BB5CFE09386C976F2221ADDB
+:10C0F0000D654D33800E8D16325A216466B385105E
+:10C100003AEF9941719F42A7783569AF939DB41D6D
+:10C11000349909FFFAF7CD2A6DBF91F645B2082987
+:10C120004D3AB6599B45C8F6A3F72D80799D0D8AE7
+:10C13000248E567537DFB400FAE96E176481DEFB92
+:10C1400052FB0E17B4A3749FDB4EFB3BDBBAD355F7
+:10C1500040CB97E1EF1A4254A0671A9D5FAB656E22
+:10C16000C809D79B5C85CEFEFA0AD982F56749B02B
+:10C1700069863090EED17426F5E4D5225A9FC3A685
+:10C180004EE9FAB43AB38CB5CBF30CA47B4EE42859
+:10C19000F2ED552A4FC403BF8609013EAA24B435E7
+:10C1A0007F201F463552F902F99B69473E81BCBD8D
+:10C1B0004CCB59549E2CF240FE9C0579023A5727ED
+:10C1C0009058F216CDA7719C1ED1F3ECA1F2356305
+:10C1D00008F98ADFF556058C1BBAACCC1C38CF9E0B
+:10C1E000F3E18A19749C0FD0792AF2C0791112B246
+:10C1F000815C0C942F0DE56B65BB75987113A617C8
+:10C200009728DFD2095906158584A4D70B6A08E55B
+:10C210008E54A5D2E74B45F23EA0AB6B6643DEF7EA
+:10C22000E978EB933D25162A7FF726895CAF02C497
+:10C2300097D8CFFF6D56FFBD49941E92AC1126BF13
+:10C240002AD6DF9B44904E47773C9F1BA1BF8FB1FE
+:10C25000B5EF4DA7FDDFFB411C69A12414F656E79D
+:10C260004640DE3EF1E7C906793A2DE773FA065DEE
+:10C2700022F2BBD325523E2A991221D308B1593B51
+:10C280000340C70B654EA2D17E2E7CF1F07228DFF1
+:10C29000B7C74136D0F27D97BE7927D2396827FBE0
+:10C2A00069B935B8BC13E4BDA7CD225868F98F49E8
+:10C2B0000ACE437FDE85B6BB6418B704FC2806FBB4
+:10C2C00045B4CB20C7F4D91BA6C2EFF44FECAFB7EF
+:10C2D00011B203EAEF76B17EDEA1F75969FFE7EA12
+:10C2E0002DA15A6CA77A60FEF194F6C152940F35D5
+:10C2F0003185903BE0FE34262FE9A558AF25D1DFEC
+:10C3000053AC4AB240C7FB29D56F98CFB9E69B9290
+:10C31000FC7410E40B3A3EFAFC159C4FFA78F5EBEE
+:10C320000F6AA826D8FBCB1941CA47E7C0FBFEC855
+:10C33000E5F5D3D7A6905EFA9CCF1A859085923802
+:10C34000BDF193F0E532A09B2504F68468C4554105
+:10C350009F974BF4BF88904BEFCF03BB4EED6146E8
+:10C36000B548C206FB45482FDAF1746AC7C1EE9F93
+:10C37000DBF36D01E89CFE844052C006AD93BA81A8
+:10C380005E0EFABFCB607F9BFF8C7AF819E821ED37
+:10C39000EFEE566BB7D11EA6137ABF415EB749BD0B
+:10C3A000A897DBA85E6AB4FFBCA8FADD498C9E3A68
+:10C3B0009D50B52C70A5E3A4F7FD0DE62F8C9CAF26
+:10C3C000F43F83507F8F81AF92BB9FAFF599419728
+:10C3D00095F6BF4D96B13EE461F2A8EBD34A5D9F5E
+:10C3E0004223D3A7C3F2A0FA74588EA14F8765A643
+:10C3F0004F03E643FBDA901E733E21A87F87D64B9E
+:10C4000046F954A87C4E8479B27990EA20FA9B8D43
+:10C41000F9813B7DF479958E92E3321D6771AB8C87
+:10C42000E3AC92175625D3F2B843ACFC7CBC88E34E
+:10C4300098E039D1914C9B4F523EA9A4624CBCC5A7
+:10C44000C9C7E05AEA2D999D4AAF65D3171E83EB01
+:10C450000BF18C4F53D5D5B399F923B9F0BC01F347
+:10C46000A0C3D9145BDFB0FE7399F185C8FE448187
+:10C47000CEA77EB74506BA129FECBA92FE44A8CF6B
+:10C480008FD18F4AFB4934D0656E10CB7A3BFA6B63
+:10C49000ADDEAF18BB5FA4B73399D9D92B1D4F7A46
+:10C4A000B299BFE9FA3889C14F58FAE970AE3AD566
+:10C4B0006543FFCAEC8DDE2E457F5E54BBCC64D64F
+:10C4C000AE5EF037950BFD749B1EC77FFF07099585
+:10C4D00028D26E0F115A1FD985CA4496B55A420206
+:10C4E0002DAF23DAD1EF809F6E104260573D6BED88
+:10C4F000188F2C772BA1AD02D81766B7AC0D423838
+:10C50000CE45AF44FA1CC6036DF93C3E67FA2E9047
+:10C51000CB544FE294687B922D9F4BE81F6F659C34
+:10C52000CCF45B228ACDE06787B397CBB91E0E6B44
+:10C530002F1B62DBCB8E14163FF6D9CB7A6A2F0500
+:10C54000F093D45ED2F25DBBA8BD84F97C557BB973
+:10C550008BDA4B286FA1F612F8318CBD5CDE68EDEA
+:10C5600036FAF72BB5974D71CA88ECE5D6B2821D25
+:10C5700040DFF3872CC8BB8F0F31FA46D349BF7E0B
+:10C5800000741DD35F3EBF92C689D48EC49714B980
+:10C590008A0CEDB6255B91AEDD2BAD58FF98B73414
+:10C5A00066FD470FB0F6D1CFD99E2C617D69B66F7D
+:10C5B0007B329DC7ED0F7EC701E3DA21906A885B6D
+:10C5C0007766FB9252C05E727B7CB7C0E4C099C2B2
+:10C5D000FC9FDECFDEA8F1E6EE62F63AFA79A79389
+:10C5E00059BB1D99DEDF14417CF8B6C5BB9FC0BCAA
+:10C5F000DCB7ADA0E53FA9F15E54334E4F3B97BB8E
+:10C600006D62D0355BE87F4EA8C681D7961A19E5D2
+:10C61000AFB5C683E5676A14BCB6D514E3F5608D83
+:10C6200017EB0FD54CC7F2CEECF68E78E0FF6252D6
+:10C63000A251D68D6B23C83477553ACAE39FB259BD
+:10C64000BC4EFF5C15E9207D8CD776C2E44EE7E74F
+:10C650009BC9361E4FF5A2FCDA9B2DA8AFD4EF8400
+:10C66000411E6FE7F2683F9560CB85B839CB42AC8D
+:10C67000D4F7A52D0E8421CFBA83CA13C4CD3B9B1A
+:10C68000670B10E7DCFE5DC12B42738DF96F95FEE1
+:10C690000FE4F58E75667FEE263BDEAC01FBD06ABB
+:10C6A0005142F479B747C923517C28FF3B9E15C8F6
+:10C6B0008F687D4FE4D7B248EFD7BC12D99F0FF3F4
+:10C6C00030DFEF6E5878348BD28178E4CC85D4DEBD
+:10C6D0004D720617A0595125459E0A5685A02F5C1C
+:10C6E0002607D0A8923BBD0EA910EC90AF693CBDC7
+:10C6F00071D28B653CBFAA92CF815D227EE1F2F8B8
+:10C70000C1E51A0CCF397D3E544F5E83B194F7F3E7
+:10C71000DBCFF5274F8B6D477E9C2C723FA074D8E2
+:10C7200081EE272D98AF908C80478E71BF2E2F05FC
+:10C73000EB03240C76C7EF0C801DA17438877614A8
+:10C74000C641FF952B450463FBBC755176C6B27498
+:10C75000487D5D77EAC4A4E386FBFF2B39D17D8E4B
+:10C76000D281E61013609E7A7B5D8F068B3FFF526D
+:10C77000D339E9B895E95DACF90CAA6F3C4ED5E91F
+:10C78000D8C5E9184DB7BC7A01F3DA8F76BCD1A0D1
+:10C790001581DE2D7629902F80DCB3B808ED6F2B44
+:10C7A00097FBA42F92503F7AD67B9F06F9FE9714F1
+:10C7B0001BF6B3B395E5CD7939242452FA174556C3
+:10C7C000A3DCBF4AE59ED0BC820425931C13CBFAA0
+:10C7D000B0D1EEA6F92493DD7596AC45BD38CBF506
+:10C7E00022DACEBAC96AE4DF0ACABF106D7FF60B3F
+:10C7F000AA91F4FE8FAA6C21C84FA2E53A8D84510C
+:10C80000EEFD54EEC3B4FEA3C8376D99A0073EE217
+:10C81000DDAF0CE4178D5F6D1ED09B9B65EF565A04
+:10C820005F9242F997D0CFBF1D99C41B8E61AFBAFA
+:10C8300087B1573A3F7708BEFF53943F3C3FBF2E26
+:10C84000BBD69D1DDA10CFE65BB29F0CB467698B37
+:10C8500055C1EA06FB523205C4F3CDE474E46BB46F
+:10C860009DEBB36F8DB1EDDBBF41FC9336D0CEEDC8
+:10C870006CFC7618FCE6EDB72510518638C7BFADC5
+:10C880001C9C63B305E95FE7F8F3F83353A858C479
+:10C89000FDCFF833A9FD74A8B352BF43E5F01DD90D
+:10C8A000EF4A31F88F153C7EA84B647EE99CC7EFB8
+:10C8B0002AA1F5AE84C0433E5A2E38E4752D9A68FD
+:10C8C000C8CF9CECFE241A4874825C4BB20BF2F980
+:10C8D000DF3A591CDAD55888E5AF3AAE87B91F1C44
+:10C8E0007C5C41D3B81E4F891E57C805C1EC85D664
+:10C8F00042BCFEDEAA344D073FF81B8BB705F8E8B3
+:10C90000A4FED760073A797BBDDCC1E506EE932132
+:10C91000CF90142996DD98EDB098EC5977038B3FB2
+:10C92000A03D31D891CAE6C22A18C76CE2AD877E15
+:10C93000A2DB6D94FCAFBA410F6806B1BF0CCDB954
+:10C940000AF6E1E60C470BC8C73DCD0B2742BF33C3
+:10C95000732A9B53285D6EB69300DA154FC4B690C8
+:10C96000D2C19278267D19E0624ED1348F3EFFF01D
+:10C9700082B5B74F8FA9DD101289095FD1ED667AB4
+:10C980007064F9E054A7C8FDF4807C70AAB37C60A1
+:10C990003E38D5C99EF755E5E2A561E555752D4AA6
+:10C9A0001C4A2E08CAC3F75358BC1E093279D5E970
+:10C9B000A0FBC974EE2787A3C392E441E9B02439F0
+:10C9C000061D96F07CEBF795817F84F176CB2C0EDB
+:10C9D000D4DB7D23CD1CFFF5C9A1CCFCD688E5D0E6
+:10C9E00031B49FEBEB97DF172D9F8FA72826398A4D
+:10C9F000EEBFAEF92EC469EB82221114C06D77BB75
+:10CA0000142A873D52C0E6A5F379694F3EE2B4DDB2
+:10CA100084F9BF9E8642134EFB19D7EF730D2C7E0F
+:10CA20003ED7B0D35568A8FF3CC582CFEF214AD38B
+:10CA30000C0C9CAE10A76D785A9B3E344E5B0BF5E8
+:10CA400023C669EBD93AC04871DA9E2BC469C7A6E0
+:10CA5000C6C669BBEB875E07886F1D1AA7ED3E1F30
+:10CA6000C6F62B00A78DB1BE41E5D60672193DFE74
+:10CA70007B2FFA10A7BD3B38344EDBDA2021CE1EC7
+:10CA80008DF7D791760B8C4BBB48C82F10D74C69CC
+:10CA900002BCB8A7BE5004BDD1F93C3A81CDBB154C
+:10CAA0003ACCA27478E2818D1A7D6E4B1CC3775A02
+:10CAB0004AE4DC4506397E3895E9735732D3FF697D
+:10CAC000C7D8732FD68E69D98072F237D463B80D68
+:10CAD000F4F8929BDDFF71B16A03FB3636A4B852BD
+:10CAE000A8CA5E9C6FAB86715F1444B4B35AAD7D27
+:10CAF0001FE004B44C44283F6B69D9CFF02ACCE73F
+:10CB00001F84AE69BB8F699B245A7F66ABA505F273
+:10CB1000F908CFE7BA65D9E6358C730561F8068C5C
+:10CB200002E8F4202FD3AC307C99C70A523AEF9731
+:10CB30008EEBC17A41051CE2C1FE766C7D2864E073
+:10CB400027FD677C9BA19EFE33B1DD5C9EFC82B914
+:10CB50005C123697A7BC662E97779ACBD3DE3397B5
+:10CB60008BD238EEA7917740BFF25042E19F5EC46E
+:10CB70000F72FBD6D122B5E05F15BE8E96BBDE2CC0
+:10CB80004FCAA99E536412CEBA7F5DC902BF2774F3
+:10CB900089F4F71991E8FB1F7C10EE57A2E46DE3CE
+:10CBA000587F2ED8CD7371CC3F0C87FFD5A7B2F13B
+:10CBB0008F14FF9B56B5CC02EA54B08EF1F9338F37
+:10CBC00015E3B3677A3BE7829C696522E2F4CF34D0
+:10CBD0008B682FE69454203EADEEF23F7E1D2DCFA4
+:10CBE000F758BC027DAE9BEA439876F893275FCD59
+:10CBF00006FB3F67A1E8033B37275F8D83F8D9A188
+:10CC0000786D30A76D7F65726ED06BF1F2B47EB92E
+:10CC100043D52E802BAB57A95D013A6CE7723D9F3F
+:10CC2000FF6EA15483DFE779AC2679F9875E333F45
+:10CC3000AFB9642E47E36ED1E594EBEA51BF3E5D98
+:10CC400047308F1FEEFE6451C041E7D691501D1D45
+:10CC5000CF6B34EEC6E05D53DF05F9F926BB95CC0A
+:10CC600025AB25886BEFA5F213A2F2731DD5A4673F
+:10CC7000603D0902615A7E604F02804B7DE36C7A11
+:10CC8000C4D201EB641AB5BF604F49365B9F74F0A4
+:10CC90003CE82F5D4207D8E3BD951E5FAD3C50CE0A
+:10CCA000DC45CB04E0B7BBDA2C6739656B2A0A9107
+:10CCB000C8F22749D40FE44E8FEF00BB2D2F194F38
+:10CCC000ECE017AAD65614423EA63A3E05398F9696
+:10CCD00047BDBD5CE9C1F60EA5B716F0971CB5B807
+:10CCE00017FC029102D89EDA894F63E945C65AC9FA
+:10CCF000B4CEFA0218FEF27E5CAB9BE683B0EED9AE
+:10CD0000D37A65B856771FAEE536E156E753AD687E
+:10CD10006FBB06C1B5F4FAC170AD0BA912D6976608
+:10CD2000FB2EA4960F8F6BADE2B8D60AB739BE1EA4
+:10CD30009067B7C5C6B5CADD43E35A5D83E4893B56
+:10CD400084CE62B87EDDF95FD730F99F9ED75F78D9
+:10CD5000A004F3FAABDCB1F3BF9D6D16CCEB6ECF44
+:10CD6000B4601EE706C484965764935008F15A33A2
+:10CD70005EE5FCEBC3981F7E44F3C30D31F27CA249
+:10CD800004C2B00F614785C307721A8D5FA551B504
+:10CD900002B9BE9BC623612FE4EDC3E057C18515E0
+:10CDA0009950E0F8D512A77F41052D76BB1FB7E15A
+:10CDB00054A3702C4AB208AC37D5A93EF4BB1FADC2
+:10CDC0004C6DBA4581CA2F875FD5801E18F05F1D54
+:10CDD00027CF6B882D279FA7FEEFC0AF16BACDF8DF
+:10CDE00047347E750FF6F935E257CD3C9FE374EC7E
+:10CDF000E1748CA65B1E005334FEBADAFD3F5BAED5
+:10CE000004BFFA13E05794CE9F2732DC76E71EB6B4
+:10CE10000EF375E3575D805F7907C7AFEE06FC8AB6
+:10CE2000CA7D17E05780AB0D835FDDC5F1AB9EC8AF
+:10CE3000AD7386C6AFBCAF1AF1AB2D83F06F307EF9
+:10CE4000E87CFB3C95C9F370EB41FE41F83F603D47
+:10CE5000488BAD07B7F2FCB16F3D68175F3FDFF558
+:10CE6000775A3F3F30B2F5F3555F75FD3C5531E1E0
+:10CE7000D983AD074D7AF9D36330CFE57B8410C1F8
+:10CE80007C20B215F8977B48205B6969F2B3B53610
+:10CE9000C873DB433BF0EADDBFCF06794EC981A3FF
+:10CEA00058FE79FB322C4FD95D81E5157B564F99A1
+:10CEB00005F2D26C57409EE5A0108675D8BB291D9F
+:10CEC000EDC03F61D1AB1E909F670502F2231F1298
+:10CED00054E0EFF23D961656FFDC26ACDF6721E00A
+:10CEE0002FFE44C79A48EBF7FEC812D2607C21CDD2
+:10CEF00005F9D9B9E305ED5B3927202FF847AEA72F
+:10CF0000D38E7DB409F2A68F05A23C2E03BF0C710F
+:10CF100022F0F105ABC6E8DE507B59BCF2F8FF63A6
+:10CF20004144BF3D5C1E703441C739D8F3E21D82D5
+:10CF300000CFAB209229DF3C0ABA513EFCFA6E5971
+:10CF4000D4FAB16B90F5637D7F03AC1F4B22AC0725
+:10CF5000079B2C85FD7C5ED12E8498138AC4C37EEA
+:10CF6000B7DC5D94CFB4C9E4274A189F1B77203FF4
+:10CF7000BDFBF3B15CB285F17BDAB1298F65417CF1
+:10CF8000F5A44036005D9E647CBDBFCD8272D32D7A
+:10CF90003C671B057CDB2828C0379DAF2BDB285F57
+:10CFA000B17EC31C902B6D07E3FB05E02BC49F5B98
+:10CFB000295F059413124FEBFD0DECFE69C7662344
+:10CFC0000E7EFE090B3E2F9ACF67777DB409F0885D
+:10CFD0009F516F3AEAEFC0E7F323E4F33DA9FA3E2D
+:10CFE0008FA1F97C0FB76747B78DC17D51636CCABC
+:10CFF00088F64BDD9C963FA2FD526760BF14BDF5DD
+:10D000000CEC972A33EE979A76279449A31DE39662
+:10D01000BEFD52418B0076EEFD78C514679E09B2C5
+:10D02000FD523A8E3B989D8EC67B674BDE91E16C3C
+:10D03000D2087136E9CBE16C53D262EFDF59C6E515
+:10D0400066A4FBE1F6B807C529F7B863E0947BDC7A
+:10D050004C8FEBE0A74C4C4155901FCF4C87DFE83D
+:10D0600077EE4F63FDFE8D5F53AE2B4AC27E78FE96
+:10D070006A85F60503E9D248E902F878038DC321F1
+:10D0800078DC26753A64A749FF310FB61273DEDBF0
+:10D0900037EEBFFAAA0107E8F3A7F52902E8DDBEDB
+:10D0A000FA454980833FA7E316DC5F289C5E7AFB44
+:10D0B00096A838A950238C8E9CBE1BA3EE7F9CCFD4
+:10D0C000AFC04D46446FFDFE18F47E3C2D06BDFBFF
+:10D0D000FCB59BA0BF2E7033BC21AF4C24B07FA306
+:10D0E00090FA5F3B2D2B41E20DE364D8FA9175BDB8
+:10D0F00088F8446183D95F2B9A2F0CF97221DFB72E
+:10D100004C880FF30385FA63F0EFBAFFBF8A20AFB4
+:10D11000C8BEF5CB45F0FF0ACF474833F3BFBA3F4F
+:10D120002F0C9AE3324A67CC273EE3719912E5AFA0
+:10D13000AD44EAF7F7F9FD7C4079B0C0D5ECB7E72C
+:10D14000CFB29AEC50348E418A0DF566FC37260E2C
+:10D150003110C7E072395C3B8E538C613F91673967
+:10D160007E3126B26C1E38A989A46B4302F0A181DE
+:10D170007843946E9348676502F0A191F1C5AAC502
+:10D180009B708BCD60BBC18FD412DC8744AA24C4B2
+:10D1900031F2A68F91810FF4D60EE08B552D46BE4D
+:10D1A000FC475A32CA6DB2287440DC6BBD7D3CA985
+:10D1B000F302FEF1E7DA22E8A7D2D1BB1FF8B747A6
+:10D1C00032E11FD17887D5FF7A6521C3BF3F011CAB
+:10D1D000E32F5D3FAB049C62A3287F524BDB1734E7
+:10D1E0009A7188F1651D78BF5C598C384634CE61E0
+:10D1F0009DFE525FBD7D3AE01C6171B913DA89DA98
+:10D2000018D83F15856B8C6F37972F812E9433BAC2
+:10D21000A6960E3FFEE8F1458F47E7E760763711A7
+:10D22000767D18E449B75BC4598AF62CE5BAB5BFD8
+:10D23000CE8138AC552905B6CF5EDE60877CFCA96F
+:10D2400090526A57A05550F4D1F2C3EE8216CC2307
+:10D25000492D8EFF29B7180FF1434A6D4112743FD3
+:10D26000D8F375FBB6A94646F9D1EDDC8EBC3FCCB0
+:10D27000C5FC88EA35C4053FCCFBDB51285B4FC5B4
+:10D2800029102F56FCE1368C33425D8217B08C504A
+:10D290005A208F0C810FEAF635DA4E0E671F6F4E5B
+:10D2A000FF6AF6F129B8DF90A74CE5FD15AC2723FE
+:10D2B0005A37D3EF8FB57E981E633FE908EC23E61B
+:10D2C000378A5B0C85113F31DBB781F6D12F02BF66
+:10D2D0000B69BE63415C4FED007EECAB4FB93E1F66
+:10D2E0009EA3498A0589E223B0EF30DA1E5A01CFA6
+:10D2F000760DB48B56C0B35D31EC21E0D9AEFFCDD5
+:10D300007691E1FF23B58B130F4744906BB039A999
+:10D31000F903ED22C831F035DA0E0CB74E30C02ECD
+:10D320000CB24EF0B24D7D341DF645CE5DFB4D087E
+:10D33000098993662233E87CBFBBC10ED0D26076E8
+:10D3400062EFBA8221ED4AB45E0361709F46766F48
+:10D3500015CCF77A6A222DD48477245C96403EDF80
+:10D3600048222A94EF4EF3EF00B99E9F30710334A8
+:10D37000BB51085403BFE9B41539BD1F47A3CDB550
+:10D3800055600F1409D7550057B3C07D8AD78172F5
+:10D390004896CAB0FF49201102789A1E9FE9E3DB44
+:10D3A000CCD75B67D17C1ED6C1C5848B99CB69F97C
+:10D3B000E97433FEAA5F69DE7ED1B82FC02EF4E295
+:10D3C000B8E1E59BFD74DC378AA14A1C275125583A
+:10D3D00057C9F508A5905F5DEB6638FF3C4FFE3EF0
+:10D3E000D0C7ADE9FE9FA69773E100FCCD2BA0DE70
+:10D3F000DFE81C5785FCE4F41F8CAE3A1D293D2262
+:10D40000423AD707FA67779788B015469FE7FF8CAF
+:10D41000F2BD08742CC8962B051887C5C9D6275AA3
+:10D4200009E6E383F5FF1B2AAFD26866D7E07A8C62
+:10D43000F20FAE3FA37659A20F1B5B14A759E83831
+:10D44000FFB946C1F2DE9A62AC7FB6C68BD7576A87
+:10D45000A6E3757F8D8AD7976BE6E27DBFAAF1615F
+:10D460003954538DD702D1F7068C6F6C6B48043951
+:10D47000AAB39195C08F56BE9F411FCF3BE90CA721
+:10D48000D1AFEFA62BC89F0356463FEDDF6D2C5E54
+:10D4900090DA47011FE10AFC4F7A4DAD0376A5CA29
+:10D4A00025AF409836FE90FF43D83702B758C09E4C
+:10D4B00035063E74D36BB9968465458B849F2EC325
+:10D4C0007DE95E88D35CBF3F77BE8E3EEAC5139F81
+:10D4D0002BDB689B44D187ED899884FB4EA6141DF5
+:10D4E0002509C886AE30E0EB76BF13EDA3EBBD6730
+:10D4F000EE7B90965F065980759275913094DDEBC6
+:10D5000092182EB73E429EA5E5B433EC7E2AB6E1D2
+:10D510005DB45CB63211F1242245C287A17C31078B
+:10D52000E57A93C0E226ED3686BB4D7A2182B84873
+:10D5300046C085FDA52E38AF2DA3E379295914A146
+:10D54000BF1FD9BC5DF5B4FE97CB6DB87F67FBFC00
+:10D550006DABEFA2D7A4F2FA65DBE875F7C95D1FE2
+:10D560003C401F13F4762414D272664ECB6F00AF8A
+:10D570002ECD60F966A3B7C301B668CF0329E87F53
+:10D58000CADF3E8EE5C381A21298527989E803BFB3
+:10D59000757896645AF7B067B0F7C592336CDC5F64
+:10D5A000A968D3289B7A611E52D962F5C1327CCF1B
+:10D5B0002E00FB0224D9A7CEA765BBEAC0F51FEA5F
+:10D5C000CF9233683BB575A10AF8429C42BC0CE788
+:10D5D000617E2D2D83EFDF27BE54585738922DCA18
+:10D5E00010CF1FC9EE48803CF148F622C01A89D5F9
+:10D5F0002BA25F2D3F114E984C9FBF39B0665A2D1C
+:10D60000F6134EB895CA853B231EFBC9C920781D69
+:10D61000B4FD27B43D7DCEE607687BA5BF7D36B45B
+:10D62000A7F31C0DEDD386689F7F94B50FAC353DF5
+:10D63000BF883F7FE230CF8FD6CB09FCB9477A9FB6
+:10D640004B067D3920784713CAFF053FFCF1631272
+:10D65000D5F754D1DB0565B2E95F6EA89E61DCC7E2
+:10D6600013C438EC2651C1F519F2B818023CE04059
+:10D67000B020890C918FE322BEC9CFC5F7DB7F2C88
+:10D68000A74495B3A2EE2F30D52FC928E0FC1B1775
+:10D69000755FA9A97CD3C9ABAAC04FDE742ABD129D
+:10D6A000ECE160E37BEB7D9B0AF7BD050A8DEF495A
+:10D6B00052C3381DE8C0CBDABFDC5045E79DEA62B3
+:10D6C000E56FFDF0178FD53AB1DE0FF6E525BE2FD9
+:10D6D0004AEFEF5B19CCBEDC9FA1EFABF6861BCB0C
+:10D6E000701F4200E4D772660EEAB1432001C813EE
+:10D6F0002CF3E6A2DECA05129625D9AB3DC8EC4054
+:10D7000000F492CAF3FD196900069484490C793E2D
+:10D7100076F607A28FDEFF8B88188278EA5F055FB6
+:10D72000C224D0F3F745C4C93A16AC7A6C226D779F
+:10D73000F0350BC6B786FD7A282F854413A1DF9FED
+:10D740009F1271FDA6E090FFB189B4FD8B7325C4D3
+:10D75000DFA3FDEF351E46FF83BF5BF45BB82F757B
+:10D760003EEEF6262F9DA9447F955C2E94A01F695E
+:10D770000E6E8057FC6E782D5409AF62157DA16C3A
+:10D780004777CAE3BBB2ECC5B3AF67F9522FE43FAA
+:10D7900053DA2AEBB04CF518CA37587C96EBA03C0C
+:10D7A0009BE55FD660E9EC7186FAF2CE52531CD14C
+:10D7B0000E7241E964FDDD4CD3EF2FB53EFE1895A6
+:10D7C0001472295238649C71A0469D00FE452F1F9B
+:10D7D000E47EBD63EAD5489FC3342F01FA1E762F3D
+:10D7E0004A1201E7CC88EDDF0FF0758317B928A343
+:10D7F0003C51B97CB155E4E59309D716F5EFBFD19B
+:10D80000EB5BDBCCF52F91D00DD77BE139EFDDB0B1
+:10D8100098AA8CD4BA581D67A097145CA48D03B93C
+:10D82000A964F49064522F831D2C62FB062487A602
+:10D830000A0AC88FDA0EF6D057D4751CDCC484F6F9
+:10D84000801DFCDD2C85045229A7A6EC925F71286F
+:10D8500020079D12BCD2E0CB95673BC13F950AB82B
+:10D86000EE4B24A5CE0979D9E41294873713DB3B1C
+:10D870000067FDA55540BFE02B087C0BE8F3976ED1
+:10D880004181F7C76A4FFF1AEDD5C3DD22CADB8994
+:10D890000C965F1F8B94BE358FB69BDA5880BFF70E
+:10D8A000E531BF5B5107382E1D9317DE639EF2C62C
+:10D8B0006272AF814FD62A2BE64153DEA847B9DE0C
+:10D8C000E86E9D89615C235BBF8D934307416E4F7A
+:10D8D00064D819BE5D65D5EC2ED49B13306F873BA1
+:10D8E00040800EBABECCB3100D379CFC5964FE7E4E
+:10D8F0006E3861A1615FEB11C98AFBAB2AACAF94B2
+:10D90000BD05F9933C730AF8AFDF4EB44BC9A0C70D
+:10D9100063BC4F037D237DFA3D209F8A64C4CAA760
+:10D92000E64A22BE77F005A9FC39F81D6E0F92BEBB
+:10D9300048AA0CD0F20B8A84EBA13482489E44CBD7
+:10D94000F34F8ACA561CB7D97ECE712798E45B6C18
+:10D950004C319515102263BE13653FC9A9F1FDFD39
+:10D9600015C0B80E4BB8BF4F53715D7D110E81DAF3
+:10D9700013B9FD38E026F367D8650DE30BC50AF946
+:10D98000DB34BE5EB58FDB85BD3C2F39D2F0DC7158
+:10D99000C0557EA93A7C02AD7FF53DD11B2EC375E3
+:10D9A00061E4B77D5DFB71C057A6542710787F995D
+:10D9B000CCB59AF2BB69EBDB2558571C47ED9E4A64
+:10D9C000EBC7FDCE9CE7CD8FCAE36E882A47AF2315
+:10D9D000CA1EBE6E388D4C8379373D62C1F168EF47
+:10D9E000B0FD0C4766047F8C72402DB3E51B606F61
+:10D9F0006F4FF827B083242F792BC8A323FC21C8AD
+:10DA000057F239391FE2037D5DB1C0C370C68ED3B2
+:10DA1000F630E8D1C1F32C0EAE38137A7D4219AC42
+:10DA2000BF8A04F08CC91E05E5BEE8BC7603D8DFCA
+:10DA3000B173D9FBF5635BB5B1B85F79E6EBA300D1
+:10DA400027D8E8B4210E51270408ECABD272985FB6
+:10DA50003D92E87B2D1FECCE2991AD5F505A786145
+:10DA60003CCBE3717FF2644F0A93BF702001EC70EE
+:10DA7000F3F529B80EF322DF1742BED0C6421CEBE5
+:10DA80007ADA3F0AF63BFD721FFB5D9504EE4718FC
+:10DA90004E203A50F788942D635E31CDC370026AF0
+:10DAA00037A679E8D5557814DB1FC91746D4FE1A76
+:10DAB0004E1FDAFE1A4F1A842234BF813C86DEB72D
+:10DAC00015D6A048A416F870238DDF50DEA3F2A16E
+:10DAD00039242C41FE43F39BEBA1BD9DD07CA810C3
+:10DAE000CDDEF17FC47E048C67AF20BFD1C8D4FEE9
+:10DAF000FC264F5EAD9AF31BFF2DF09C7CB7B7035D
+:10DB0000E5345B11813FD75A26244586F01721C89A
+:10DB10006B306F91F14AC727809E1F87FC6634BC2B
+:10DB2000F7E3C0FC661FE44156CC5396033DF3D6A1
+:10DB3000EB798ABA04E2AC4D9ED9F3A419908744DC
+:10DB40004AA0FC80677663D54C886E823BE6527AA9
+:10DB5000EE15235BC6805CAC12B93D0E890B0DF649
+:10DB6000C6D516FE2EC42F55108FD071E78B11B27B
+:10DB70001AE43A4514C16F468F7B1F970F57DD2774
+:10DB8000AB81AF8F78981F7B84F35D2F77DAFC8FA2
+:10DB9000C07861C110D6CDF2B85DC85BEF27B87E02
+:10DBA0004E425930DF5984E5AF57CADF5C125093BB
+:10DBB000591EDB00CFB9B18DC56B303F880FBEE772
+:10DBC000D1DFEFA4CF9938727EE712657B55FEC096
+:10DBD0003CBDCF9F5CA2F62F75F07EAC161200FA0A
+:10DBE0006C4CBBA518F62D6CCE49172D867590028E
+:10DBF000D1BF07E42537DB86FCCD5DC7F929D2BC50
+:10DC000093B62BB2B1B850BFBF8DD355BFBAEA1689
+:10DC1000060027D4E99A2B30BAE6AEF313C00D3ACA
+:10DC20006D95CF40FF07F4F99300BEBF4BA400BE33
+:10DC300097FDE5E91D12418F28BD0F23BDB339BD06
+:10DC4000B9FF1A297D67E7069E8A807DDC2061FE88
+:10DC5000AA55B2B26673C8809B5B9D5DB5F00A722F
+:10DC600074FB8769939768C836BB2030D98BF167FE
+:10DC700060DA4D89F01EA6FFD71E431C557BFAE1E2
+:10DC80006F81BD7898C61360176F247E89E121618A
+:10DC900009C65999AA9409B89EB26ADEEF68DC53A6
+:10DCA000094A0B719376DF3CD8FF5E99C0CA96CCC7
+:10DCB0008DDB605F7325E44718C76F60F585ACDEC8
+:10DCC0000EF5B0FF205D3DE94933D98B1031E021DD
+:10DCD000D43E7C00E32B94F32B81DC56B7CCED8350
+:10DCE000B36F9FA63D7F283BC1709067B8BD88AEDB
+:10DCF000A7F2740EFACF057BE132C8D32038C67F75
+:10DD000070FDD4AFBDE067D20C38C6133A8EE1CBBC
+:10DD10006238860FF567383BDC9F177831CF8B96DA
+:10DD2000A363BB7F80F87C4BBD88FEAEE0506FD50F
+:10DD30007DB4BF56B0C78073FCADAE6B4B7EBFBC2D
+:10DD4000D941DEE8F5F52C85E76BCAF5C5F0FCB9DD
+:10DD500012EE0B793A98920CF9C7368F2A651AE8B9
+:10DD60007FA347B5659AF9E18FE287337304FCC856
+:10DD700075C699E8A9D3EF5DCE87B7B85D3EC1718E
+:10DD8000A902514D837EEB6CCA8E2A90E7D7D9FB4E
+:10DD90003283F175B0F5069D5FBA1D3892C5F2C1A8
+:10DDA000FE2BF38FEF5A991D2E984E66CA49FDFD42
+:10DDB0007A33195FDF8D33E795FA7572266BEFAA18
+:10DDC000F305701F331C1840C79BDF40FDB1018F66
+:10DDD0002BC914B8FD50448663CA78BDD5C6FC442F
+:10DDE000E174324B9EDC7FFF35FCB9B7C6B3FAE86D
+:10DDF000E77E437FAE65A1E9B9458D2C0ED0EF5388
+:10DE0000FB9EEB65783351F1B9F90DBD02F0A170BD
+:10DE10003D417E28419F0A7C7BF78E87CF3E017172
+:10DE2000505A7129C3FF23B580A3495ABEB895FE45
+:10DE3000BE90F7F7239B5783DFEB05816CA0BFAB48
+:10DE4000D90B35589F8D531D28BF56A7F609D863A7
+:10DE5000AB9BC5DD340E5F9889EBBE01531CAED37E
+:10DE6000DD25912A7B69FFB853B2CCEF71E9F3BC91
+:10DE70007569AD359D3E6FD2611971AB9BE6311C62
+:10DE8000769C9A8DF14E0FA7CBFE36794902CBCF07
+:10DE900010979A68EF5CF35B5A0E6DB379217E3B65
+:10DEA000D8D63276256D17A4FF0D79FD8F6CAA3573
+:10DEB0000DE64DA38016FA5B4655ED6DF7D3F94F8D
+:10DEC000FAD7435B21AFF37C5B64FB0832199E46B3
+:10DED000DBE3EF3F0EB8F1F7836DCF252FA3F3D827
+:10DEE000BDEBF1EBAE02BD6F13BDA3E1395178DAA2
+:10DEF000EA4C86A77D2F53CF5754756C99014F9BE1
+:10DF0000B598AC8CC2D3A03F039EF63DD0C7C1F0FC
+:10DF1000B49A4CDD4F05E3202F3CE86478DA416782
+:10DF20000BDA91834E8E47A922E671BB3B435B21FE
+:10DF30008FAD0BE8785828FE56DACFF733192EB597
+:10DF40001936C1A619DB770B70CDD5DBF786900E9D
+:10DF5000750FE8781C6BBF2993E161DBA17DF91097
+:10DF6000CF57F6B1F680A7199EDFC49FFFC301ED1E
+:10DF7000CDCF07BADF6BD08F1FF076935E085502C6
+:10DF80005DC752BA02DDC6B4F931756B249D5EE3FC
+:10DF9000BADD53FB9BFDAF2B80BB057E0FF8869649
+:10DFA00029A29D794A30DBF9362E57CF73BD3CB696
+:10DFB000671181FD3DD63D8B910F643D417E8F7988
+:10DFC000F23F05E378F25630DC6FCC936B5F1F3B7A
+:10DFD00044BEFC7CA69DED1B5B21EAF9F2F3C0E791
+:10DFE000E87C39E5BA939520B79F52B906B95D34FC
+:10DFF000F74407C8CB551C9F9A7858138DFB319571
+:10E000004B53689247C771A904E3ACDC4B5763D903
+:10E010007A690696DBC4DE5AA093261286EB344B4F
+:10E020009A7D12C4CBA5A6F5AA9ECC141C9F759D03
+:10E0300019CF190EC7D90B38CE6803BD398E534896
+:10E04000985D6F7DAD10D753F4FA1E6E5FAE1288E7
+:10E050000FEEDB0B76DCB00EDBF1E855F19007B488
+:10E0600004170D8973EAFB80FBFA7B94E1DBF80768
+:10E07000F8B5ACB602DD9F5ABF1CDF5BB1265795E1
+:10E08000811EF764B2732D54C78E681CA127D380FC
+:10E090005F880E15ED986EBFA9FDAA37DAAFDF7263
+:10E0A000BFD267BFB87FD0EDD7D8107B3F47B75FEF
+:10E0B00063C07E09FDFE68DF3E6F16E2BA3430832E
+:10E0C000FD06C576F29B38B05F02E9DD40E579B127
+:10E0D0006F1FDAAF74B05FB83E205F0BEB181BEF19
+:10E0E00024880335EFDBB41AE4FA277BD6A0DCE9F9
+:10E0F000B8FF3F652563FFFAEFD90F32FBB57B0F01
+:10E10000B55B6583DB2D47167B1F7141569FDD0A8A
+:10E1100043FB2BB05B0BB286B05BBA7F85D4C99E44
+:10E12000629487283AEAFE8EF33158CDFC9D5ECE8C
+:10E13000F0A7A3DF9DC7E9F8E9DC93222C2D792C09
+:10E14000E10DEE1871E170FAF1ACD82B8C37EA478B
+:10E150007B6CFD9897F5F5EA07AC4B2F37C8F73C79
+:10E160001EAF4C88D28B421289037FDEF1A82D1E90
+:10E17000EC51681DD58B219FC7F4A2AFBF41F5A21A
+:10E1800023E506835ECCCB1A542FE665C5D08B4EB3
+:10E190009BAF07FD94E4477C7951D608FDD21E66FB
+:10E1A0002F07F34B0BB3985F599235885FD2DB0F83
+:10E1B000E2976ECB62FE6179D6207E496F3F885F21
+:10E1C0005AC69FBF6A98E747FBA5FBF87327B58639
+:10E1D0003A0077B2811F421C25EC30D2F3A9179B7D
+:10E1E00043BFA5CFFBA9C0C6AFD5329C61DC81156A
+:10E1F0000EA06BB45FFA1E8F93B6727E1ED3A85F1B
+:10E200008279B42DC67D34BA5F1A7720B65F1A774B
+:10E21000408A2F1EC22F6DCDE2386EBF5FDA6AE4EE
+:10E2200077BF5FAA8FF24BB5E8972670BF541CEA00
+:10E23000BC22BF3452BD3BF235EBDD607EE9C82025
+:10E24000FAF765FD92DEDF53EDECFDE17EFDF33F75
+:10E2500063D6BF155341FF8E70FB1B43FF8EC4D2A4
+:10E26000BF94EB8EE3FBC77DEF2D4A34BF74E32AE6
+:10E270001DE2DCD1F964F5F21E01F813BD1FC40ED6
+:10E28000B8A681DE714A96A95EC72BB6A6AB71A36C
+:10E29000D2FAF3152A2AF5463B7E64107F389C1D7E
+:10E2A000B78ED2ED783DB7E3FE2F65C7471AE75822
+:10E2B00047FD7DEDB87554ECF8E6CBDA71BDBFA72C
+:10E2C0009ACD7234E9309523A13FBE99F40B2A47C9
+:10E2D000383F2647A283AD4F497C7D8ACA91759409
+:10E2E00021DFB21FD634806E3A6D54BE10F7A3FF03
+:10E2F00037BC2F03F818C31D357CFEEE749F7314D2
+:10E30000DA7B8E5FF1DFF3A7DBD09E6C3A25E07AF3
+:10E3100066526E6F08F69791772CB81EAA55463054
+:10E320008FD41E215ED89791047814E2710C8FDA95
+:10E33000C8E75997788F27D67B46569BCF5FEB86E9
+:10E34000F5063BE675770BFE5C188790BE6E0CE811
+:10E3500063D22C1F8ED335C6EB019CAB2E99D9CF3F
+:10E360007E7D63EF6FB9AEFE22520776509E8AE73C
+:10E37000D68C1BC5E21CB53A88FECBA06FE346C520
+:10E3800088CBF13F0CB8C8A6CC5B1CB1E4E503C94F
+:10E390005F3ACAA00756B717C79748F6E0797A548C
+:10E3A000DA8B2EA7A2DCEC01FBBD46B0C8B02ED2A2
+:10E3B00021906238175213E2BDB01EA1E7FB377AF5
+:10E3C000F25BD8F9393496A3CF9FCFF14BC05515E6
+:10E3D0002AFFD5A3F2F57315D87EA56276BFD5EDD9
+:10E3E000AB86F60F470405F87F779AFF5AE0FF1BCC
+:10E3F00009DFAFC675318E537408618663E5F0FDA1
+:10E40000BB24A0811DA9241CDFE4E3A874CBEC7D10
+:10E41000C36C6A570CFBF12AF97349366F1FB5DFDD
+:10E420004B70ACD6A07D633E49B140AEA7045428E2
+:10E43000D7F9490AE262B388C2E86BDEF745E572B4
+:10E44000E928362F4932AC2758DD4C2EDF15FD7EEA
+:10E45000A86F9A79E13D90AF7FFF459C02F8C03FDD
+:10E46000299105B03FE6FFD5797D3AB78A1D32592B
+:10E47000A96A208FD45E0500C795642627BADC6C94
+:10E48000AD2946BBF1C79AF7D433D4EE9CAA89A82C
+:10E4900067ACF01EF4792C1765FBBE0FF38F2F0EBF
+:10E4A000C01626E25FFFBE7AC660E76ECEF66F0446
+:10E4B0007EDF11E832FD7EFBCA1EF58CC1EEE9ED70
+:10E4C000757C5CE2F393644667CA8746A3DDF88BEC
+:10E4D00055B3FBD0EEB909E0999F3AD8798C946096
+:10E4E0009A8D9667BB05DCAF3F870424887FE69250
+:10E4F000205EAFD4EF5C4FDAB1DD3CD289D7058026
+:10E50000A716A2FF93985DE27455D78997A95E5923
+:10E510001CC754386747AB24C50167FFF93A6A1135
+:10E52000CBBFE214A5C5E87FA46C05F5E427A304DE
+:10E530007DFDED2730CF0295C9C59AD136940B8762
+:10E54000D38FFB8649DBC18307297DF0484CD1601E
+:10E550002FA8FD52289FEA6B1C44A1A154E2F400AD
+:10E56000C699F6EC4018DED374151305EC8D501CDB
+:10E57000423C21BEB8DDA351BD7BECAF16539CA736
+:10E580005F7BF8786A27DE82FB201E4B64F82F2120
+:10E59000EDD5CB419FB36D88E71ECF79C811896156
+:10E5A0002F373BD738E0F9F9D31FC2F5CCBA931611
+:10E5B000CCC306F333CEA0858429DD36672F1AF24B
+:10E5C0003D4F6703BB6FB0FACD5ED2204C86E73378
+:10E5D000BF36D6516E8A7B3797D0FA2458DF097838
+:10E5E000F0FC91D30932E8D5766EFF67973AF09C3C
+:10E5F00092CDA7127F0278B2DE8FDE3EC9D68BF6AF
+:10E600005BF703C23798FDB75F12F01C8A976DEA7B
+:10E610001F817F47274E453A5B9476A2D0E7274C6F
+:10E6200008103FBDDACB42F8FE5B22E587A80CCF8D
+:10E630008717785CE22A1349B1414E6D65410F9C02
+:10E64000436C2BB211B037569A10171BE4768B200F
+:10E65000607F36FE3E91DEDF41DEDFA5512C9E0756
+:10E6600099985E0A72FB2ACA2DA530CA33F6432B4D
+:10E670007F6153FF6B54F9C0DFE13D65D83F3A96A7
+:10E68000EBA99DECC07DDE9FF1734A745C3EAF99AF
+:10E69000AD9317D7EFAA2C069CC1EF54216FCFA3DF
+:10E6A0001A32978EFFAA0A472FDB6710C4F645BCC3
+:10E6B0007D71AB0DF767EBF3296834978B4823E244
+:10E6C000BE5711C3EF940E457CBF7811FC6EDC0F72
+:10E6D000C1DF1F0EC10F31D6BBA2F7116466F3F381
+:10E6E0000FF93E8291BE7FDC26A879D9E02FB414C1
+:10E6F0005C87DCFBDD3959B1DAE971CBC6C4392A54
+:10E70000C84FDDA35E02F6CC129E81F26271523BCD
+:10E710000CE7174BBDAFA0FD5F2FE4437E2639C841
+:10E72000AB58D678D9197E05F711077859EE64E50C
+:10E73000B5B4AC205D591EEB0C592BE8382E757D15
+:10E7400073C8F8F20F34BEAC37C4977FE4E7FFBB61
+:10E75000BE1F7903F478D9BAC2D20DB4DF65E14C9B
+:10E760005B01AE2FD462FFBA7FB0CE5CA782DCEB38
+:10E770007EC22EF55EEB41DC522881F1D81D640E7D
+:10E7800096355E7686AF85F735E9F85959EE64E53A
+:10E79000B5029EFBA0FB197D3CD1FE6549FD3E2BD9
+:10E7A000E0E1C3F9973B3D7326D4C3BB9444FA6FB1
+:10E7B0007E3E109E37DC00FF9186FBF2502E06F362
+:10E7C00073DF5ABF8CC7A12C0E533BE2F03D532997
+:10E7D0009B78D97B2CAACAE23C221FCCC77D59CC9E
+:10E7E000BE7B480B1CBD64957AAD98277B08F2C9A7
+:10E7F0002F33FB6ECF969F86F79DAD8EB035A30C61
+:10E80000051BF3F0A5BC3EAE88D73B3BAFCD80F6F1
+:10E810004E567F07EFDFE2E4F5726823BC170AFB70
+:10E82000A9A07E096F6F75B37A9B87DDBF2D998490
+:10E83000686E499F4BE75C06E5CE67A11C5744888C
+:10E840006C2883FA7ADCFD65386B5131D43F41E5A1
+:10E8500004E8B22D99F79BFF2ABECFBBB366EE0446
+:10E86000A0DBB665228B7B6E66FB5AE85FF81A5A0E
+:10E87000DE59666B35AE576D1BC4EE7D90CD71864B
+:10E8800072B6FEB8259BED73DC923D74BE52C7EDA7
+:10E89000F86370FEC818B0EBECFC914D70DE08BD5B
+:10E8A000FE10CE1BA1FEF18753BE817E6D5D36F357
+:10E8B0006B1D153F70801EAE2341F457E4247B8FFF
+:10E8C0007C976FF996D1E00FB20B701DA8CF8F48DF
+:10E8D0004C2FF4BC41FFFDBFB399DFDC58FECE7B6B
+:10E8E000B04E2539A95BCE07BD7EBF1AF955662308
+:10E8F00071C2D7A7DFBA5EEBF2B9ED5115ED8814FE
+:10E90000A6F259C6E41370A08DE573302E04F91CED
+:10E91000F355E47302DB47AECB67C284AF573EB713
+:10E92000807CE6F7CBE71690B77C780E934FBDACB2
+:10E93000CBA75ED6E5532FEBFCD8921CF4380DF232
+:10E94000B26599C8F2B22F767A161BE2822D7FDD6E
+:10E9500059BD1CE4B5DC1673FDB7219BF94B69B1B9
+:10E9600066877D73D1766838FBD320F9CF825FA8A4
+:10E9700027BE0A18ABB68EEDB36CB06A9E35C0AF39
+:10E9800079DA37219E4B9D17B1C6B2CFB4FD45D67B
+:10E990009EE5FB7ABB06BEAE4994C568BFD217534D
+:10E9A000BD343CD73D6FAEA9DCEF7F36B0F579C5FD
+:10E9B0008D7E2ADA2E0EEAAFE4350E38AF64F352BC
+:10E9C00011717B6BE25A87F15C237B0E3BD768F3B6
+:10E9D0005286EB6FA27160CC7ABF18F3DCA3A7B2AA
+:10E9E000257E7E6527EA0BA1FA02F1997DFE1A1FAA
+:10E9F000E8E1CEC54C0FFFBFBC7F45791FFD8E07F8
+:10EA0000E46CCB5F2DB84FE683ECAA26D83773733E
+:10EA1000B66F7A4E797FFE121DF789896B9B21CFE5
+:10EA20005D23B808D8374B62E834BC07F3A16023F4
+:10EA30001BCA06F2F3540D4D7D460FFCFD436BFBE4
+:10EA400093F8BE019CC044E3C1D38005D0D46BFED3
+:10EA5000936D388ED3427B0ED4D7E784173450B9E8
+:10EA60003E05FE998EF3AE277F8EF5A7F83EFD2773
+:10EA70009FEC6C82FD3C1F0804F360ED3B09FA3EFD
+:10EA8000986A78AFE5F443399877DC616FCF015C21
+:10EA9000E6747CFBE98740FF1E4AF4B2F888F1E196
+:10EAA000ED25E35B8C7E69470EB3E37758D8F9AF69
+:10EAB000D1E35F9FA3BF57D93991EDD3F2951BF3F3
+:10EAC0000C8C340DF9EA1D01412D32E861DF7857D5
+:10EAD000DB997FE4E33DB53A13F75B2FB5B1F19EC7
+:10EAE0008AA3E3C5FBE2861CEFBA1C16D76FE6B813
+:10EAF0003DEDCF5F0B7CB9797C29AE7F49ED774046
+:10EB0000F9D46DE353A0ACDFFFA1C0E452BB3921BF
+:10EB100064C47BDE5E320AF3CEA57C7F21F57239B8
+:10EB2000C6FD877770FA1042E78D71208B33079D01
+:10EB3000E777EC66BE7C87CDF30E9827EDFF741C5B
+:10EB4000E7CB77E2BCFCBCAF98F3FCA9CE17FE1E66
+:10EB500006A57F8E711FB73EAE4773F4752036BE93
+:10EB6000E1E8727A09A50B1D4F35E7EB7074C17AA5
+:10EB70002AAF4B73FE0DE5B19F9F09667EAE61F231
+:10EB8000B7D4CEE6792A9EF3734DE290F37C3987B1
+:10EB9000C53F4BF9BE444AFF89B1E87FC5F3BC8D40
+:10EBA000CDF3B111F2FF43BDBF41E8BC1D0E821D84
+:10EBB00089DC2D6172D73672FAF2E7C69EF72178AA
+:10EBC0002EBD7E36AF6A7B15417CD78BE7C46CB215
+:10EBD0002B75F4962EDEDE339920FED1555FB80FEB
+:10EBE000DECBDECAE335FBA5F1444B65FBB9A84794
+:10EBF000079C04F1A7AD6505781E57773DFBAE99DC
+:10EC00003C6D5E6ED1847EBCE94C1EF35F6796B1AD
+:10EC1000734DB755C6AF34FAB1F50A5BBF1CA508F2
+:10EC20003CEF92175428709E5B0B3BCFAD52C279DC
+:10EC30000AD9849D479EEB7500AE6325FEA65BE86E
+:10EC4000BC3F587953F4F70808E04A83C5BB24EA6F
+:10EC50003CB7B72AE50570BECDF97409D7E7F16F67
+:10EC60002A2E4D2068B86CBAB7B60EE86E51022055
+:10EC7000BFCBEA4B84EFD3F23B0545B87E9672DDFD
+:10EC80007F5E86F32EFE5363785AFD0C1BCA67D74E
+:10EC9000FE7C8C93536589741BE29C2E6B10F3A051
+:10ECA0002E41F1EEA2A2781F61F5383E03CEF5CEDB
+:10ECB0002DA3709DA58B9F0FFE767A01E227DD9232
+:10ECC0006F019CBBA439D9FA636233552438A77A03
+:10ECD000F76C0DB610CECC5994908B7686307F7E33
+:10ECE000CB445CBF4949547640F9DB27AC787ECDF4
+:10ECF000D1A9D7E3F7C42AA6CDDB0BE7D29D7DDFF0
+:10ED00008EEFFD574C5BBA17F66775BF1F87E50698
+:10ED1000CA6FBF1DF2016AA1E1DC417AEDA6FEA92E
+:10ED2000FBA87F329C47D3FD1BF94DC0BF1FB2909B
+:10ED3000A006FE9D68229C9BB3D326BF09F9CBF9A0
+:10ED4000745169C17905D3D9B93A4A06BBB6F36B98
+:10ED500058E4E7EDA443BB9E7C1D17F767409990EC
+:10ED60005EBC6EFCC282F9C371F722CC43CE060BA7
+:10ED7000F13D23AAC72EA047D3814211F4F44C3EA3
+:10ED8000B3033759424D707E157997BDC770A18D79
+:10ED90009DFFF6E7598E16C07F16DD5AB709F66556
+:10EDA0007CAC4D4A81FE3EF66DB365D1EBAEAAABAD
+:10EDB0004A41CCF473065AE17C463BEC4B95F97919
+:10EDC0008C1E7E1E233B9FF1109CCF48EB7FCAF325
+:10EDD000A5769E2F3D57A362F970CD5C2CFFB2C67D
+:10EDE00087E5176AAAF1FA528D9FAD37D6ACC4FAFF
+:10EDF0007FAB0960395CB30ECB7FE0F398BDA56AA9
+:10EE00001BAC8FADDA63C1F725C61C38FA07781F33
+:10EE1000F51E227A61DCF7781EBF13DF93A56588A3
+:10EE2000F73679440278D93DD3A7A23C2EE854DFC7
+:10EE30004885FA7984C07AF33D8B2D9877DF35CBFE
+:10EE4000B10FBE4B73D79E63B9DF837A55C2F78A81
+:10EE5000883778E723B4DCB47031FA9B16AB628153
+:10EE6000F79FDECABBE873D040718795D4A578A11F
+:10EE70004CB4B9546EA7947DB2EA395AAE79AA67F8
+:10EE8000BB83D2555E58D6912A43F957582E4AACC7
+:10EE90004CC4B845FBD5F6E3B07F568C4889707FEB
+:10EEA000DED4EDEEB1D47F8092CD84F277E53A09DD
+:10EEB000C6CBFCC47F857EB55D93E07B7B273A9211
+:10EEC000697F6FF1FE27783EA9C4E7F3F22425F9A4
+:10EED000588AA1DE5B2CF07DCE3DDBD522181FEBDE
+:10EEE000FF4CA807FB53FD1589A3E9FDEBF2A66FC4
+:10EEF0006F50063EFF6481F728E084E79BD87E1DB3
+:10EF000038E60BE8E5D2C684EA8481F6A46B06C134
+:10EF1000FDB37AB9C9AADD09FBD6BBE2D855FF7D9E
+:10EF20007921F31FF7E7B16B531CEBF73CCDF75B8F
+:10EF3000F207F6AB1430BBDF94CCFAA1727E1BDC77
+:10EF4000BF6C71BA0876E1A4EFAE7838AFBEAEB947
+:10EF500000CFADBE98CBECE789AAC21CC0F39FAF2F
+:10EF6000B7E3BA4A57BEB200E24D4D70B4EFA7F70F
+:10EF70001738FC8BA09F826689C07C547F7215EC89
+:10EF8000555A307DC79B205765C4D10EF1EA4D79A3
+:10EF90004C0FBB5B67BF713DD88743123E67F14D95
+:10EFA0008FCE86EF339E518BDBC1FEFD739A9DF9A8
+:10EFB000A5DDF6D068DADF2B69CF67DDE584F7F6EB
+:10EFC000D4785CD7AD8FBD3FB83A8FC977C1C6A79B
+:10EFD0005D0AB523179C22FA8FED4733DF5450BFEB
+:10EFE0002B2520D15989D1E9BEE68AD65A3AA47A8E
+:10EFF000EE4F6EB60737B9205FD86C51A0FF2E6E6A
+:10F00000EFB466A105FCE3D9FA543CD7FDC2EE92F9
+:10F01000BD90AEA9FC7975F5ECFC582279E7825DCC
+:10F02000BDB0654AAA116757F3F4F7A9A3CE75D707
+:10F03000C8AB45E9FDE7B81BCEA1C0F3CEB3EB9F4B
+:10F04000568DE7BAE7B4FDBA02CBAAA357983EF0B3
+:10F05000FC736AEFF05CC351FDDF7B1580AE5FF699
+:10F060007BAFDDF0BD5798FF20DF7B9D799E7DEF64
+:10F0700035937F6F25FABCF43FE50A31CF79EF0A6B
+:10F080001EC3F3E8073BE7FD236B08CFB31FF47BF8
+:10F09000AF0D6F55C03996837DEFB50B3EF050062E
+:10F0A000FC15F0FCC7E879DD73B11DCF7BBFBF75E0
+:10F0B00084E7BDC3F71FCA067EDFD59AE6B6419C3A
+:10F0C000D0946FD64BFD2AE7337D83F35854C37336
+:10F0D0004607E3896A88CFC734A798CA634359A60D
+:10F0E000FBC7B71598EA27B68F33D54F7EA1D45406
+:10F0F0002E09CF34DD3FE5B54A53B9BCF37AD3FDD1
+:10F10000D3DE5B642ACF882C31DD7FF5F9E5A6FAE2
+:10F110007FE85D65AABFE6D21A53B9827CCF74FF3F
+:10F12000CD76B6CF86BCC5F4F66DFEBE8E4EA7F981
+:10F1300079CCCE54E6317AD9A9BF0919FA7325687A
+:10F14000F8BD0B5837D44CEB84340131DCF70DAEED
+:10F150008FC9D72E1E729D40C727B7733FBC8DFB4A
+:10F16000E18DDC0FFF80FBE1C7B81FDEC2FD30ED93
+:10F17000F77DF8CED6674BD99ACDB209642FC4B5C6
+:10F1800009C5EC38933438808796E334761EA7DFC0
+:10F190001BD640CE24A7F93C1E7956BC691DC55527
+:10F1A0009662AAB7B9B34CF519D505A6B273C238A1
+:10F1B000D3FDF145A5A6FAE8EFF5FD2C97E527DD8F
+:10F1C000447E13E4B7EF7B81BB048E0B6B150F43BA
+:10F1D0005CB74B6831BE4F40CBE1B849C37F2F309D
+:10F1E0003D8F30FBE65105C87FDC4EA90BF6DB10E6
+:10F1F0009FD46B5C477F9BE30595798FDD08F95AB7
+:10F20000C9E4F96FC0BE2FF22B11BFA3BC3B5761FD
+:10F2100071BDEFC15CC0E16E989C33E52E7ADFD101
+:10F22000DDCFF37317D9776A57F69DBBF85E00BF41
+:10F230008750EE14212EBEF84900BF37FBF9930E1C
+:10F2400011E2519BD58FE7277ED43C06CBEF83FF9D
+:10F25000413B6C3E8FB13558FA660DC4CF6D6C7F63
+:10F26000C4AA4B765CAFB3257A5DC9F4BA17C6550C
+:10F27000DE7F6EE3478DEC9C455DEF873B97FFD1CA
+:10F280005CE69F873B97FF513EFFE8F3F97F6433CD
+:10F29000C70F8444F0BC938840D66CA571D45ADE65
+:10F2A000EE648186DF5971291102B8E4C98208E64B
+:10F2B0005DE745126831DC57388FE4821DD6EFDBFD
+:10F2C0007EF400E62BDDF01D6A7A4B5D5B217E87C4
+:10F2D000BAAE9E7F87BA3E19BF6F32204EE13868C2
+:10F2E00037F84583BE9DE0FA7C81FBC50BF585A60A
+:10F2F000EF529FC8B3C5F40BD17E60C0774EA2FC1D
+:10F3000061ACEF515FD1774E8257F69D936EFE7DD3
+:10F31000F3917EE7E4D53C21A6DF1FCEFFC553FF66
+:10F3200046D83C637EE7A4EB7C18DBAF1CF43B279C
+:10F33000E198DFA37E00BE7342F9707768847E0F88
+:10F34000F29BB2A1BE7352D904DF07EF0A168AC638
+:10F3500075998FB9DFD7CF59A8CEBB713BE8FBCEEB
+:10F360003C76FE0BB5434D3305944F0DDEF38C9682
+:10F37000CF8D5F4CE990848171B27E5EEA47FCFBE1
+:10F38000D21FF1EF4BAFE2E7A5AEBA742F3B2FB51A
+:10F39000D97C5E6A57233B2F55D763FD7C515D8F27
+:10F3A000FBBED354CFF2BAE1BFD324BB8CDFD3FA78
+:10F3B0000F3D0EE4E791747964FE9D268D7FA7C909
+:10F3C00067FA7E573CC725FADFFBF3E3779ACEED69
+:10F3D000327FBFEBFC20DFEFBA61AC7045DFEFFAA4
+:10F3E000BFDE1509DC008000000000001F8B080054
+:10F3F00000000000000BED7D0B7855D595F03EF731
+:10F40000DC5792CBCDC9930B8470F280843CC80D3D
+:10F410000409887812220D0CE24504636BE526A0EE
+:10F4200006411B506BDA32E58424185EF182D8A1C4
+:10F430008AF486878D2DF54FAB33E3CC57DB1B4029
+:10F440004A67B4C6173AFDB5FF4D4004E49F89886A
+:10F45000959962F9D75AFB9CE49E736F48A83AFFCE
+:10F46000CCF74DF8F4649DBDCFDE6BADBDF67AED03
+:10F4700047AE5C819F1B199BEB1459289FD1CF1578
+:10F48000F8AFAF6D49A2DFC5D8E10D00E4C13BADD7
+:10F490005E654B4E152B82FACCDB22B9A2BF6BB551
+:10F4A0004AC752CB1853999D1D8427B33285A53284
+:10F4B000B674B473DF1681B1DA96C5C5D8EEACF177
+:10F4C00095923C1DDE3B584317B4F7B685D577B906
+:10F4D00006FBF9651E5486F213932C8CA5413B8ADA
+:10F4E0005596AE634CC08E64C66CAC81B11CC69A96
+:10F4F000EB99DF99832FEF944E1752B9E50A3CB789
+:10F500009465EF10A0DFBE4E9109598C9DEBE4F499
+:10F51000E8ED9B9FBF073A431174F6D58BD541C0E8
+:10F520002BBE74A53BB768F07D896C23BC4ED7DB3E
+:10F53000AA83D0DE56EFADEE5C5774F9076BF8F78F
+:10F54000E67E4A652BD13335C3578AF47FE3FE87C5
+:10F550009D88D70E81D520FD8F67F81293E13B7609
+:10F5600009EAA7335687048B40F26481BED3DBD906
+:10F570006BC237B34D508231E8FB389FF371C71827
+:10F58000EF6F73811FEADBA2F72043BA52EF5809ED
+:10F59000F0074ABC57007EB2CB501FF8EB4056E64E
+:10F5A000203E3DF9F8D4FB096E70D273DF068985E1
+:10F5B000A0D2810D1E829FD920D3B373433E3D7FDD
+:10F5C000B2C14BE587369413FC7846D7E178908337
+:10F5D0004F6F63A52AF4F3414670633CE2E163A5F3
+:10F5E00007B9D8B82B80CEB0C081C4CB890CE5A5B3
+:10F5F0006F4DE9FE2D306EF7CBE944B7835948CE05
+:10F60000FE8C7441DDC7DB447B26D4FBC6189159C0
+:10F6100024FC32D4B3016047409451CE986AEB0B7E
+:10F62000437D05FE5DC9C626D7869E063CFCE50ED9
+:10F630002908F5D37CD6BEB073506E99DC107A09D8
+:10F64000BEDF51E1F46D81F26FB088F22C44A1214C
+:10F65000F43E94AFA84960212F63A7C2BF912C4804
+:10F6600087D7CA0E66217EC6FAA9EAE26E0FF2D5E6
+:10F67000238D593C8AB1AFBBA4451500F7A5EEB365
+:10F6800013A926790696856D30CECD8A8FC6FB8369
+:10F69000FA15EDCBA8B52AE9743ED6F30B28D7436B
+:10F6A000C92F4EB4D3FA3C84EFFF753CA371DFEA57
+:10F6B0009DEA96419E4E66B06A9C673789AEB54713
+:10F6C000800F1794D92938D6153332324FC2FB2D0B
+:10F6D000F976E2B3244A7B13802EF6BF1DEC20207E
+:10F6E000D7DBEDCF4B8E90E3ED329727A03CDD5278
+:10F6F0000EF571FEBA88FF82C50374D40BCC15C118
+:10F70000D7CE7C91CF5FA6B82B80DE328D5E80C5D0
+:10F710004C001C1E916DF122DCC0420097F85D0D7B
+:10F72000C87FD6C3F9A98F1F13D7879E06BC3E8515
+:10F73000F113A17C748D71FC4A8E3F187A09BE9733
+:10F740002A9DBE44C0A3C4341EE930FEEF43F96ACB
+:10F75000183F1C7FF3788DC65FA0FDFA3257300446
+:10F7600070E37BAF4F391AA1D7B6C95DC7C642F95E
+:10F77000B61AE64539AE0FAE1570DEFE441E957A18
+:10F780003A012A14B122E43BF0D78B745C784BF435
+:10F79000227FA59C9013E5447A5E945468F7FCE5BB
+:10F7A000BF71FB809F67C38E6AE4DB671B7AA61C70
+:10F7B0000595F11CCC33EB44C6BA609E5901FE0599
+:10F7C000CC33845F807986F0DFC13CC3E78B30CFD8
+:10F7D000F0F98F30CFB0FC9730CF10FED50685E022
+:10F7E000D0866A82B757C6D747EA9FA7353D707162
+:10F7F00012D723BA7E0CEFE1FAF1C33DD7A61FC39F
+:10F80000A81F5DA8477619F4E39B9AFE3B3BA01F17
+:10F810000F1BF4A35E7E7E08FDF8F6A07E7C3B52B3
+:10F820003F8E60FEF89D387FEA879A3FDC2E5CEBC6
+:10F83000FCB9DB59618F27A165DE25998CADDCC54C
+:10F84000F5ECC9382193F49890BED69139D8CE867C
+:10F8500009DC5E85B73B6A90BE0FE37664C6933DD4
+:10F860004C2E1563D43BFB34603E96B19ABDBF7EEF
+:10F870004C05D29FB47BBBADD0EE9976E6DD47F365
+:10F88000241CC24903FA71DD9652C61ECA94E9BB14
+:10F89000B7B2D5077C80875B0EB375D0CFEBEF2571
+:10F8A000DF5C86F8B4885E108301BB3AD81F1FF76F
+:10F8B000B82CCD9E32EB29D48F1655605740CF8F90
+:10F8C0005F98B2A80C9A1EAFBDD7E7058B84C568B8
+:10F8D00038DB295B1A5C884F9826F7190B6BD80721
+:10F8E00078F6B6E46C44F8EFDB9857CC1AC43B6763
+:10F8F00021CB64D983783FD30F3A1FF1F6D882A881
+:10F900006FF6C5F9B74CC676C6D8CA90FE7DA50D70
+:10F9100099B746C8CFB22C4EC78749DC5ECE382295
+:10F9200052BF273BF2F66D2461F833D94DAB6637F1
+:10F930000F4EE272FF51BE57407BC6E42CB7AF18A2
+:10F94000EA27D96B681C050BF9276A87A303F538EA
+:10F95000C08CF4FACFC47D880FC8966C07395B85DC
+:10F960004D03DE1FB938BE8F6F11F701EBD819B404
+:10F97000DB40479FE4B37B23F89DC2ACAAC62711A6
+:10F98000F9B80A61274A190B5DD16C9D355D6B177B
+:10F99000F05C057215E71EACA7F33F3F1801C37F6B
+:10F9A000859D03ED125CDC65844B5E34C2A521238A
+:10F9B0003CEDB8119EDE638467BC6B845F47FF0B30
+:10F9C000F5BDCA4EE4021F2668F38DC9FD02DADFD9
+:10F9D0004CD4DFA04F5D2CDC540EB0AC38FB519FF3
+:10F9E00067AE073989C05B7EEFEC7B6C4AB4FCC81C
+:10F9F000EF25F45AE0FDCCB0B9FEFDF7637D9945E3
+:10FA0000BC077E6437F654E3787F5A666168E76F17
+:10FA10007185ACC83F65977FE77CE8FF668F48FE3D
+:10FA2000CC2B4FFF714D163C5377837F9A32382E83
+:10FA3000F3165B7C382FE76529711668C7297BEDC3
+:10FA4000D8F6F6CFD5BB502FB341FE5BAECC181C19
+:10FA5000FF546DFC53B57285B16EC4E73B9A3EBD51
+:10FA600079B6CDC0B7851E9B61DC6EE837F2F5C66E
+:10FA70004B4638A25F7D9E19E0E4F92D24E7171A62
+:10FA800059501486AF9F641108E9CC66166C063C89
+:10FA90008F835D21E74E55DEC171FC1AAFCAAAD92A
+:10FAA0005A2BDAE17A1847B48BF341D33C534672B0
+:10FAB000D910027855108C5B041DEDDF150FA31FC4
+:10FAC000A5CE724807D14E67D8683C9D9A9DFEAC82
+:10FAD00057388C76786FA5C7D724458F776A6EAD77
+:10FAE000900CBFA7D618C77B7CD9BA8A1C62B2F427
+:10FAF00031DAEFCCF2F8C3E86F495F2F041F015EE3
+:10FB0000573D549103ED4E509C1750DECC72A17FAF
+:10FB10002F557AE87BA7DCDF84FEEE7825BF1FFD3A
+:10FB200085D6CB0FD2F72AB0F0600CF91CFD50043B
+:10FB30009E8885A62FE9E73A9CCF281120022BBD8D
+:10FB40001559287FBEF800E201F39CF519F525EB65
+:10FB50008B1887D6F5EA22B4B32A7337603C147F3A
+:10FB600089CB636B6872A51DDED7BDB52218075D12
+:10FB7000D5E5FB9C4E2C6FAB4D41DD5517BAA31A52
+:10FB8000FBA93B30CD1B076D75071FFF9D08F52FA7
+:10FB9000740AB203CAAD97046A277B2523FBF06978
+:10FBA0004008A2BF5CD19965C7FEEE95D85C1CEEFB
+:10FBB0007B03A0F0D16F85DFE392E0B96D871FE191
+:10FBC000BA5C274B10101F3BB5933C3FB7D20EEDEC
+:10FBD0005C7C4B24F91ACA4E5A2F590DF3690BF865
+:10FBE000057D367CAA0AFA1F2D1BDAE859972F1FCC
+:10FBF000C3F9155FC4640BCCC3847C288FE06F5DB0
+:10FC0000AA6C17A0DC26F1729B04DF458C47769B1B
+:10FC10009D292964C7C83E32F5995B141E2742F01E
+:10FC200008FEDC848EC7D422B23B2AD2A3DB9D5DC2
+:10FC30001A3E43D91B6685FADC9E4A5B92F87BB478
+:10FC40005F7A7D779B5D41BD832E270341DD04ED07
+:10FC500005F306CB59BE4CFC6C071EE1F730DC996E
+:10FC60003EF0EFDFA855A64F87F71FB68A6C2354E6
+:10FC7000FD308B856EC4714FB3905DDB34A970AFDE
+:10FC800084718D90BECE5136C8BF4D9BF332FBA020
+:10FC9000FFDE6D02F9E72079F665A306CBFF3DCBC9
+:10FCA0004EFA57877B6BB8DF84F5B05F6695EC182A
+:10FCB0005FF48DE27668C9A34DDF56A0BD380BF323
+:10FCC000A37D5CA2D93FF333ADF19F9553C0DFD440
+:10FCD000C6DFD233EDB690DD0F76714DD7628F0A55
+:10FCE000EDB57E2ED644C6E3FAF366EDFBA1E4A3A0
+:10FCF000952DAECE42BADB20CE043EB4A6EE2479DA
+:10FD00003B3DB13E5DA4F911B02F2B463C785CD051
+:10FD1000F7D7814DCDE447B106D427A7BB5765E29D
+:10FD20003CA8DD5D9B1207F56B6F0BD8BF0FE56933
+:10FD3000F2CA0611E6ED3DA11FCEC379718F6F5651
+:10FD4000200E619F22AC003C574911F390217DBFEA
+:10FD500023BACCF331275322FC531B5FA1F277EC7B
+:10FD6000FD56CD6F91507E6E017144580443DD34D1
+:10FD700006E4CBF7C9D1341C37086A508FDCB6E4EF
+:10FD8000F3A32F40F9079285E099456A338AE47618
+:10FD9000B422506FFB4E4B10FD823C4B48447FA376
+:10FDA0002C9B824776030B8B4CD4F409D4ABBD2C2F
+:10FDB00005D17EBDBB609C3D0CF8D78249E9328DF0
+:10FDC0006B0D3C9F745DB062FDB3408305F03BBB9F
+:10FDD000F222C16A6A62FF44A0E3BE851F1FC5F913
+:10FDE0001E5CCA826C1CE0DF52B12915E0830CE274
+:10FDF000E8D900D78CDB84F998632AC0190097777B
+:10FE0000517EA60F8D01C2D54F1DC3FACE2687C5E0
+:10FE1000321BF3331FB7209C50E262C86FABD44F44
+:10FE2000F0CD5E0E37BB2E107CACCC45F4BF51FD3F
+:10FE300009C10B677298315E7FC16C17C575E79772
+:10FE4000BED43916E4C091CFF990B0F3E330C2B517
+:10FE50002D3BE68DA57E264DE56C19B05FF62B4057
+:10FE600007D99C74F29748EF6EB5747919B4B772DC
+:10FE70001253AA20EEDC2A74C90CFAFBFA33A53B14
+:10FE80005A66824FA695BF95A79773BDF1C0A40F80
+:10FE900096A8C0DF0451D323EC3F96A01E81EFA9A2
+:10FEA0007E7BE0DF1E3F3A73B0FEE91F7F4EF51305
+:10FEB00067321F8E8795713B0DAF54F2DBBCDC1EA1
+:10FEC000C46353A024964EE271733CE01B984AEF42
+:10FED0009551A037E201F1F4647AAF26A2C1CB0FAD
+:10FEE000D2B8B7DCCCF5CE0984611C7AEF04394373
+:10FEF0003DA280D8007C7A0D93D1CF67F99C1FF189
+:10FF00004C0D5E4101F307DD28178F75AFDA4E7A8D
+:10FF100046B1925D486C7D70113927DB056922E09E
+:10FF2000B722EC3DE6C138F780D08528F65A031495
+:10FF3000B79E0954C82ACE8B491309DF95E186453F
+:10FF40008CEA89A9027CB7DAE9DF3E0BEADDF2B878
+:10FF5000908AF1ED996DA56E85E2FAC0EFD0AF3BC6
+:10FF6000B35D94B600F42113286E5D894518176DB2
+:10FF7000033F99E63593ADC817818FD7B98C201B05
+:10FF800003E51F0A72F64E1827ABE627C5EFF9FB0B
+:10FF90004704F0734F6ADF830E0F6ADF135F133479
+:10FFA000BF3D619BA84C063DFC4436FF6E7598CF63
+:10FFB0009B957B8420A620E28BCCFE53C33C37B4B8
+:10FFC000770E94ED9300AD0C54507C7ECE16CCC4CD
+:10FFD0003CE5B92CAE1FA3FD26BFDB01EDDEB72744
+:10FFE000290BE7E39E6C1E1FDD1BE86055F07E3594
+:10FFF00008B40C637EDF81A476C4F7DE80C8148C5D
+:020000022000DC
+:10000000E3058E8FFAAC40F89F027C118E7F56E894
+:1000100060488FCA8EE582FC261067A0AAAF4B1DF0
+:100020000BDF8FC1148B17E5A98BA1DF95AAF9CF40
+:10003000408FC11F7973E1DC6EF4B3C66BF90E73A8
+:100040005C764650BAD1CF522B9C3EF46756AD3405
+:100050007EDFDB32B71BFDA7797724D0BC4D357D21
+:10006000FF4A4BF3119C0EFF949D4DFAF0DE3D428A
+:1000700012D23B739748F3B13DC93FAA0ADA6FDF4A
+:100080009C93DC0CF8BB53D46F63BC691FF356031D
+:10009000D2F94F654516F413ECB6863A84ED4FE776
+:1000A000632809F1AB7FD7629497272DDE7D5C2C06
+:1000B0001E46799DD79A62D902EDB46749EEB779A9
+:1000C0007C978CE535FE8ABDA82F14353309FD9B3E
+:1000D0003B562E9EAFC0B3E2B66401EDC50713F9DF
+:1000E000789CB2C995242F9B9917F99D0D7A06FB30
+:1000F000855269FB4CD44BD91B51AFE56E4E24FEA3
+:1001000066CFAAB1A4437F936C0D63510F6FB7FA0A
+:100110006A6AA17CFBEC42CADF9C9B98C5E31ADDAE
+:10012000BFD7E436FBBDAF1D47F9BC355BBD07E962
+:10013000CD58FBC2EBF3A09FECCDA9C497A1E2047C
+:10014000735CD03491DBC93737AE207D7BA6C926DE
+:10015000EF4B1DD4FFBE3D8E0E94B7DB52ECAD636A
+:1001600052699E3408DEE83802E2CB97BF8372966C
+:100170006525FB688E2B30D1998EFEDE9EA4A9C822
+:100180005F961FF17D76B4BCAFD993F55815D45B5B
+:10019000A398DBB97A3C11056BF1A01E470CC4177C
+:1001A000ACC18A71A1ACE5F5AA9940F1C21A2DEF54
+:1001B0003A9FB1C39867BD4771FA308F7A4F17CC19
+:1001C00090C8796C8A27461A3FC8EFFD8CFCEC1367
+:1001D00016B717ED9A393EE8EE3CE29A86FEF31E1A
+:1001E000ABD701F48BCE23CAA969E09FA4A567FA17
+:1001F000613C9BB5FCBBEEC7FE40F3639FCFE5E3DC
+:10020000D87B03F7B36B41FF6C443FBBE5E7F630A7
+:100210007CB77ACF625F05EA8F16C11B27A39C06C5
+:1002200037A1BE550F0A5DE8FFAC0EFDF018E613CE
+:10023000D6801F8CFA7A4D7E68930DFDE21A568A9D
+:100240006C5C736783505714ED1F8FAE31FAC3EDAA
+:1002500049207731FCB13FE7F0F9D19E15BBFC375F
+:10026000B93C7ECF69B33025A2BD898178A644F41C
+:1002700097B73BD9004F0E8E35D42FECCC36941760
+:10028000771518CA4B5E9C6A804B43B30CF5A71DCB
+:10029000AF34C0D37B1618EACF78F756033C33FC53
+:1002A0007543FDEBCFD419CA6FE8BFCF507EE3A5ED
+:1002B0007506B8827DCF503F797E55228EF370F15E
+:1002C000C4BE383EBFF795AA86BCD333395C0ECE88
+:1002D00098F24E7DCF1AF34E299AFDCAD0ECDD87F5
+:1002E000F9013BC2F9C18005FBEFBBD94E79C13E94
+:1002F000CC3BA13E7BD6D181F1411FE69D107E5AB9
+:10030000CF3BF13CD5875ABEE92CE69BD0AE68FACC
+:100310004A8F47CF09B21BFD06758720A15ED4F135
+:100320008DC82351FE49CF4799F34FD40EE8C794A7
+:1003300000CF3F45E4ADFE4BE49FAAFF8BE59FDA7B
+:10034000274B9938CF7AE3B81CCCEEEF998BE3B307
+:1003500020378BECC39C4BFD4710AECEE070623E65
+:100360009783EC463E8E9F7A6CE4F73FD3CFF358E9
+:100370006A9985D6599ED96D09A15D9877434590B4
+:10038000C749AC2A0EFDEA324142BDAEE7B18EED5F
+:10039000BEB8068BE72D5EF7FB55E87F953ABC1398
+:1003A000E52F2F9FB52C6F64F9ACF9F946F86BF285
+:1003B000B5D993AF3A9FB5DA94CFAAC77C16C84592
+:1003C000FD21A3BDF9EF9ACF0ADB1AE8FBB0C02EDE
+:1003D000A823C867FD7526A379D4C7E4F6C9689F2A
+:1003E0007683DCC958EACD443DA3EB8D999A9E3BB8
+:1003F000C09478CCC3ABBBF97AB1D9AEECD5EC6282
+:10040000F60FF7BB65F4AFDB785EE2B1EEC9ED3312
+:10041000E1BB53814A2BD9430CE000BE6F77C58105
+:1004200026A0EBCE5CBEFEB3D411DC8A7692FD54DE
+:1004300094691DD8EAB7DF0A789C8321C47975F6E0
+:10044000876BF78EC1EF3BF7BBB3011E97CBE5B2CD
+:10045000AF53CB7F58E5768C573EFCE1B4942D1119
+:10046000F865E4F2BCC269166C2F8F8C4B3479D7D7
+:10047000FDF2F14CFF199033E10A86C49DFBD5597A
+:1004800065FCBB09C0F7F17B7ED34430E815A11CA5
+:10049000DB31E6E719EB213D346E400F755520FD49
+:1004A00092A687321E32FBF56237AE638E45BF1EC1
+:1004B000CAC7AE31969F867988FE910AFE11CAE3BB
+:1004C000F5678CE5F0D38DEB98F53585D49F649274
+:1004D0009BC5DAB898E93EB7EB48D34CC45360FDEE
+:1004E0004C8AA6FBAC2DA86239C47532C66B663A3D
+:1004F0003376BF29603C27599894581E4DD7B9339D
+:100500000DF3705F88999EFAF35D9B30785EBDC7EE
+:1005100066CCAF9AF0EE6BDBEFF693BE92C9EE1DA0
+:1005200068BB8DC657DD2532D46FB33AB9BD9D1572
+:10053000B07460FC773DEB6AC6B8AE0F3F9985E3B7
+:100540002AECC478B53D8BC337EC5FB153CD40790D
+:100550007CB61DE93A15B03094C7BECEB9142FF75A
+:100560001D10245CF7FCC703B56EF4034E6B727765
+:100570006AF70A92B7013BAAC9DDB9DD7CBDF3DC9D
+:10058000EEB9EE9C88759EFB50DE80DFA798BF7D9C
+:10059000562C7933F199B580FC5D37287F19BBF76C
+:1005A000AB3323E4CDCCF7F1E16E1AB763204F0CE7
+:1005B000F506B8A188FF388551BED73C0EE3768991
+:1005C00014374AA0CF709C50DE507F8D057942BD14
+:1005D000611E9F539A3CA935092C96BC99C769495D
+:1005E000EE405EDC40E7E95D4704A46328F98A0F2A
+:1005F000BC59C117FF41A58D89A6F3F49990807469
+:10060000AE023A65299A2EC090F262D1F2D540F23C
+:1006100075EF01DB3078331AA7EEED8F6662BE2DE1
+:10062000CFAEEE4DC779F4FB38B60F4812F65667D9
+:10063000A23F7FEA63FF0429627C974CCCD2E80D8D
+:10064000B82DC4FF1E37EE7B90C780629B81F16F8F
+:100650000FC5C3E7CB5C98C364E72F3F42F1F0EAD4
+:100660003D4E8671C2EA4B33EE2263BBCD41FB4463
+:100670000E04EA7A900FA7BB4401ED9E335736E48F
+:1006800053CF77AD90701EFCAD5D79213766DC519C
+:100690004A7986D560CF1CA5D71E7F88CE6314F714
+:1006A0000C15874CCFE1F80C178F0CEFCFD4A5AE0B
+:1006B0008CE0E357BD0EB77420DE6EA67CE6598C45
+:1006C000B7CBB44986F176DB40BC6DC33C4CDF1040
+:1006D000F1B6D9CF392BB0D6C6B2C1F8DBBC8EA7E4
+:1006E000C7DF756D3CFE36AFEBD529B6ABAEF37DFB
+:1006F000D57ED04A931F748FB6AE774FE07FD6F584
+:10070000BED8BA5E7011C55D7FE9BADE9E69345FFE
+:10071000BB3B1FE4EB7ADB8659D7DBC6D7F5EEC1CE
+:10072000753D19C72F8BD629400FB038D40387F8F1
+:10073000BADE1A5CD7CBFAEAD6F5406F5C755D6F0E
+:100740004D6AE84B59D7EBCCE5EB34410FD7B3C931
+:10075000363909E9BFD02632356B707FAABE6F11DA
+:10076000D73731CE36D3F503A003F723EAF0E86D8F
+:1007700082126BDFD11F35FD71E1F834D68F7A6DAF
+:1007800097407158FAAE8F435770DE74894199E7EC
+:1007900075691F5B26D37FC2E4FF4DD0F25DA36B6A
+:1007A0002C86FDB08CF593BF970EFE1ECA555FD701
+:1007B00083028E5BFACF04968CF3BDD1DAC7E7993A
+:1007C00093E6595FDB2764AF3F457B0DEDADDE6DF2
+:1007D00033EC734B37ED5BDB6EEDA73CEF76B0DFB0
+:1007E000AA84F1B1B1FCF79A7DD1F994AAF1291547
+:1007F000F7533A07F7530EF0B785F3B7B7C5C85F9D
+:100800007D9FCAB0FC3D109BBF0E2D1F32C0DF0381
+:100810001A7F0F68FCDD23525EFF8BF2B7770FF073
+:1008200017E18ED8FCED6D31F2B77E18FEBEB9F13E
+:1008300013E2EF993B12D83E6F347FCD7C65CC4FED
+:10084000F6C7A7DAE42D647F94E9B518A73C3D3AD2
+:1008500019E31433DFCF807D41BF5A5FFF34DBA340
+:10086000E4F9D697BF83F641B6D2FAE717CFFF0A6D
+:1008700016B49F5F55FEF76B61E1308EC731180FDC
+:10088000568E76A883F2B26B98DB1B2CFBEAF2BF84
+:10089000DD9DE261F4632FC03C7078A3EDC8766BF8
+:1008A000C8350DCAB7EFB17A553698FF35E77B23C7
+:1008B000F2C1A48F9E3FB07307EAA35A2627E762CE
+:1008C000FE2789BF87567728B3A3E38D5BB3C10F9B
+:1008D00002FAEAAFB3905F79AD7ECC536B0EC7E5F9
+:1008E000A5E27A436E295F6F60A4279B267E7B87F3
+:1008F0000AFDE9FBC2EFD3E42DBD93EF47849FAA25
+:1009000014A0CF9A2B75A0BD70CF6A9B80EBE62D0B
+:10091000499E5211E4A26EA2BEEFAF81F922F617F2
+:100920006CB7F9EB701DD92AA98CC75F0A95D7E17E
+:10093000264278FF5836D7C360FE08EF81B846C319
+:10094000E31E1D8FDD23C3A37DA296CF8BC6A37D9F
+:10095000625A341EED8807BC6FB9E162CF5C68E76C
+:10096000640BCC0268E7E4B669141F4A3B0409F93A
+:10097000B4295BE6FB4A05F52E3E0FBDB45E3AE5B1
+:10098000A50B4750BFDCBD4D08D2BA1C0B2FC0F9D8
+:1009900096794860381F4B7ED664C7F8A12BD84D96
+:1009A0004FEFCF77D8318E2D3DB8969ECFEFC9A2AD
+:1009B000E7B4CD15F45CB96DEDB4D9D0EFDD6D0EB3
+:1009C000195D31292084D0DEDDB74D0C3AD02E09D7
+:1009D000FBE6E17A8E0AFA07FD6F29282828FFAB8B
+:1009E000B789FB78F9465A8F557F2E52F94918FB83
+:1009F00051E8576D1169DF000B86DCD7637C7A34D0
+:100A0000BB8BE633E3795A5DBFCC3832B7A91CEA19
+:100A10007F24F0383D3352BEF07B1F879DACAD097B
+:100A2000D78DAF351FFB9160A1BCE67079D92772D5
+:100A3000F471E4FA26DE2908D85F0533C6754FE461
+:100A4000F0F14BF5C9763FCA555B6D26EE2F716804
+:100A5000E375FAF315B4DF434DB3537CC42E2FF185
+:100A6000E07E167D9F068CC874CC0798D7D7EFD749
+:100A7000BE47794C9F3AB8CE1EB55E0F3EE3C6EB3B
+:100A800006F711E8E5106CECC0F287B5764E403DF4
+:100A90008C877A778BC126FA4EF1A0FC8CB43DF896
+:100AA0003580E5DF8E680FF7F1EAEDB58C09BA7194
+:100AB0007F7F547B507D637ACCF682587E02CAAD2C
+:100AC0009178C9805731F6A3F1A72648F992E1FC45
+:100AD000A3BB35F919D67EEF8A6DBF4F9BEDB7C921
+:100AE0003F5A15F872EC775F40B3DFCF82FD46794D
+:100AF00018C63FBAEF003FE7A1B777ADFED1AA2CE9
+:100B000099EBC561FC235D8FACEA1AD423184766C4
+:100B100076821E81264A9EE5FAA12BC0F586F769EA
+:100B2000AE374A3797D293F578FFD983F35AD33B40
+:100B3000D350EF14A17E68B28F43FD7400FC7F4652
+:100B4000EB4A211CC7F31D22C5FBE7855BE7613F2C
+:100B5000EA0E4D9F04B83EB92FC8F5C979A192C7D6
+:100B6000FB4F833E81EFCF00CEF15C9FF0F5224D2D
+:100B70007F609C80EB3C1FEE797E13EA8F9F83247D
+:100B80008D93B0BFFD99186F47E991437C5EFFA537
+:100B90007AE41CEA91A2E1F5C84D5923D3233765C5
+:100BA000713DD2C8D4EE87D1AFEAE4FB2E3C0F39B9
+:100BB000787E3955A638C97C2E003D31E40FD4F239
+:100BC0003E29E1B931EB1FB11FDCF3A2C5757FE40B
+:100BD000F8F07DF06C93B7CD4EE7C97C0CE795F942
+:100BE0005C996EF7D6687292DE3532BBB769D290E7
+:100BF000F677D3A418F677D324467CD1CF699C39F5
+:100C00002412CE1F1DBAB6731A6706CEB1A51ACE2E
+:100C10006138F36C844F2F9ED3C0FD50DE6CC33916
+:100C20000EBDBC6F0DCF7B9AFB89CF1B38A7119FE0
+:100C30003782736CB502E7D7726D3D4C6F27EA1CA3
+:100C40005B4BEC736C5EEDBBFF6EE7D87AB5736CF3
+:100C50006F0F758EADC5788ECDC1822F93F09ACE71
+:100C6000AFB93E7F84CE3F9D023DB931C6F9353CD8
+:100C7000DF867EB51FF462D01B7D7E0DCFB7A11E2F
+:100C8000DC0171CC9618E79FFA52931755D0145394
+:100C900018FA332B3A056F88E1393787E2443A99DD
+:100CA00093EFD332CFAFFA9084F98066AF95F6E335
+:100CB0009FAE5FDA7E1DE2A3AE25236663BE6E0F94
+:100CC000D94D7E0EEE8B9EC7192E4E5DA98DFBB0C1
+:100CD000762E105BCE564F36D9B94ECDCE75723BBF
+:100CE000B7BAEB4B8A53F53CC048E3D44357B773CC
+:100CF000C9F32F76EBF18F18C3CE0D67DFBEEAF58F
+:100D0000DEE160FA15EDA9CAD735F47832C9C2E33D
+:100D1000C9CCEB1D52B3B69F08E57C35CA39E62134
+:100D20004D79CFF9B8FFA88C9F67C03C67FB774F20
+:100D300052DE53B5F0F8DABCFE1B9DE77C9DF2D87D
+:100D40007BAF4B664D3C7E1BE1FEA3FFDBB41FF087
+:100D50003A51E95C873EA239EFC9AADED2F39C1F63
+:100D6000E3F88F1EC86BE653B9395E9D50AD955BB5
+:100D7000D8055CC709DB54DA1F127E984D55D9C8D7
+:100D8000D77BAB163EBF4900BA56BBACBD0E37434E
+:100D9000BBDE3FF05D447CAD9F03ABBAC6F35F7A28
+:100DA000DEEEC433F13EDC371BE5DF02AD9B62FBB8
+:100DB000DF54FEC82499DB7FC93F0AF54E4BAB28B0
+:100DC000D1F95D9FDF1DD3FF1EA23D0B9667C5685D
+:100DD00047F1BB0DFE7275D0D02EBC6DD2DBB5C411
+:100DE0006E97FCF01EB001A817AE159FDF9BBE4B9F
+:100DF000D7F134C9BFCE87DE9A156E3B8D8B31FE9D
+:100E000048D6FB337DF77E9ECCE363416A9F9E15F7
+:100E1000CDB7A1BEBB64C2CB3D045E7A3C8378599A
+:100E20002DD84FB05D043971CFE5FB416B1796DECD
+:100E3000844A257C1368C5718C2DD6EA83B6A57DBE
+:100E4000F5C7AA2401F733D7825D47786BF1A40E6A
+:100E5000D4A7D98DFE9624D4AF5DCC8BFEB0F91CFF
+:100E6000E033BBDFA079386F7A25C3BCF554EFE2DD
+:100E70002329F2E03A527146AF05E7E1BCC53BAB2E
+:100E800092D11F7C89D13E985D72B02519DA7186A6
+:100E9000FC5EEEFF5D3DFF32ADACDB8A83758B4BB4
+:100EA000DD2809D1F998C9AE0E4B12B453989A7443
+:100EB00004FB2B2BAF1553019E5155BB6D3EC05FFC
+:100EC000BBACB624CAB88ED53337B10CD7F34A7150
+:100ED00087389BDDCFF7EF2C28E3F989D7D20FBFF6
+:100EE000B74A1ECCE72CFB71EF0ECC17E97AB90E8E
+:100EF0003F02BE4E688B1D7FA5E7713FD9CAE4C390
+:100F0000B85FD9F196C8FDDDD10D1E29861DD3FD30
+:100F10009DECF50D2C847CC673D55EB2FBA7C3DCBB
+:100F2000FE32948B4C6B5888FC7E42A3C96E897745
+:100F30005ED5DF349F935E986F3C0FAD7F6FCE5BC5
+:100F400099DBD1CF41A3DF188B9E21FDC54ECE2F5B
+:100F50009D8FA7353E9AF93661B7407CBF2E7FEB57
+:100F6000E378CE36BEF400DFB7A29D8BD7CFA71FA4
+:100F700030F96F1FADF792FFF6877C7E0EE7F143E5
+:100F8000643CD984F12C6881F7B9E1B5A1C87C270C
+:100F90000B580D7E1B9E5B8FB4E366BFCD55FA10D8
+:100FA0009D4BFF6008BB0D7E1D8DDF0A183FB47797
+:100FB0001F5C76901D385D650FE2BE43B31F97C678
+:100FC000B83FB612FC313CC77E3A3C83CE03809FCB
+:100FD0004AE771CCE3C53C8A1DF3553B964A5E8CCB
+:100FE000635B70FC0AA3C76FA8F1D0C72D5DD32740
+:100FF0008DCC4FE713580BF7CF9B9D9F14629E55E6
+:101000008CFB53E1A988F5A5661BDF8F7F4292DC3C
+:10101000C911ED3FA1F9F9CDA3781CD1EB91DCA565
+:1010200050CF9DC0F54DF6A106F7AD11F153BC763A
+:101030001F4122D8BB1EDA1704AA0CEAFD7102D7A1
+:10104000F7E13D396E8AB313BC995E17AEFFCFF856
+:101050004323FAD1152EDA077CEA1F8CEBFDD17EF3
+:10106000A86AE3EBFE211BAEFB6FAF8C277BF76B0F
+:10107000F9BB4B54DC53C002E9DABE0001CBCDF71B
+:101080001F0C7BEF81B89EEE3DC0F949E767CCF7B6
+:101090001EB00692AF12CD6F34DF7BE078EF4F1BAE
+:1010A0006797D1BD07FDB6FFC47B0F7E6B9293910E
+:1010B000DE7B60969B2FFBDE83B36187B6AEB8E81C
+:1010C000365C57348FD71795CFB3DA3D0A43CB2719
+:1010D00073DF5A7C35F9F41AE4F3A49A43B0AEBF37
+:1010E0006A753BD012DB0EDC205B34BBFD5FDB0E90
+:1010F0008C9A1C5B8FFCFFB2033ADF743BF059679C
+:101100006680DB812ABA1FE55406DFFFF53F768053
+:10111000DB819B8618BFE1ECC00DA8E3803F6F54D4
+:10112000F2FB2998557663BCBEF49D1C0BFAE37A5A
+:10113000FDEF98EE333AAC8D679FC4C7BDD22A5BF2
+:10114000638D7FD43D55CEABCBC940BB5ABDC1FBEF
+:10115000AB245AA79D0B9108EAAD56AB340FF3B3FD
+:10116000EA6D09C41F733FCCEA93D1EECC1A5F79C4
+:10117000EFE4E911FB17D81F9644EE5F4893573F01
+:10118000AE46C8B9BE2F217DDBC8F2842BF286CCD7
+:1011900013AEC88B91275C91C7B4F539F9776864B1
+:1011A00096BE23B2483E0FC90F17F003F960F58EC3
+:1011B0008CCFD611F2D9FAA5F179D748F82CBA1A02
+:1011C0007E1486F63C3099711F8D5AD9F06384D510
+:1011D0008D0E09CF15FF4DC2F77F142EC3F48A532D
+:1011E000C275E14744BF1FC7E3338B5FC2AB447E88
+:1011F00034D5BF1FFBD9221DA8EF90F1BCF254DA01
+:101200007F7767E3F742556017A414B63CD6B99AC6
+:101210003BB5F3D5CF6972FC9E2D343E09BE7B6D84
+:101220006AE57393D362D46FFC3EB5374734DECBA7
+:10123000A23F5F9ECCEDC453DA3D68B7DFFF8BB3AE
+:1012400098B748908BA60A80574251287509D0D389
+:10125000F65A0E9D2B7849ABCF3CAC0CE5607989F2
+:10126000FF9791FD3A65C94AFA9675CDC4F2397F68
+:101270002AFAF96BD05EDB5FB924943325C79BB89B
+:10128000242B1A0F68E765E487F3D2968FC529836C
+:10129000EDFC2A2EFC149D7D55E72D7D17FC8C5FFF
+:1012A0002585C7E1FEB9579F9DB4347526C069E115
+:1012B00071587E54FD6CD7D13100DBF838A5FCE4C1
+:1012C000B35D384E73169CDFFF18DADD4976BA9F9E
+:1012D00066B39627D6FB2D2BE0FB68CB0A383F750B
+:1012E0003EBCBA06F8903A341FDE8FE6C3FB93A7E4
+:1012F00047F3E1DE69CA1F903F8024D1DDB68185C6
+:1013000056028ECAE8AEF9D3A0893172D7B38FA145
+:10131000A8E5AA1417423BA7B1BEF352DBC7A27BD4
+:10132000B09D17A72A1FE2FB57D71C263CE25EE1BF
+:10133000F78DB05455417DABC0F83EE9A5EFFF9560
+:10134000F3D1F8BD3E1E37212FA19D6491DF9FB5DB
+:10135000C51EF02C86E7A62C565107ED6EFDC02564
+:10136000EC93A2C7E76C01D70F49785E1CEAB74837
+:10137000BF70D645C8D3288D7F55A5CA65C43341F3
+:10138000E0E798B79603DF003FF72B2953C90FCD4D
+:101390006565E8A7C8859C7F80AFB500EBCF0CA042
+:1013A000CE6771B91CDFAD9E5D0CE3A4B82278D284
+:1013B000FB30E99F38E69730F791F453FB132DE5A6
+:1013C0004847301FC7BFA8F0074F58411E3A92F94F
+:1013D000BC9D0430EE5BD80B6613E37475AC3D78AE
+:1013E0003086DCB90A39DEC525CA4D5EE48B23BCE4
+:1013F000FF31A8BFB9D8EE851161732C811AE40BB7
+:101400005BE022BD01EF6B22F3B78A46B752C0CF33
+:10141000176CFE77279DB3D2F90AF2545187FD9FCE
+:10142000760998071C4EAEF20BA2E42ABF20B65CE8
+:101430004DC6F751729538A45C9516C4962BA25BE5
+:10144000970BFD892763F1DC2AE0447E9BF5D2757A
+:10145000EAFFC23C83C01A70FFA4F552B9FA1AFA27
+:10146000D9D95682154FA57A14CAE3343F0FECC67A
+:101470009B2487CE06F2F5449742E3F7E664CD6EEF
+:101480005C63FB16A7A2201F9D18AFF0F6C7213D95
+:10149000D02F433B1F97C1F3397A3FE30A381D73BE
+:1014A00016B8FC385E73506F46C8EB470556C2E36A
+:1014B0001F35B9DE94D555E38BA11FC7175E5DEECE
+:1014C000AD9A1C83DC7F03C76338B99FAEC91B8C00
+:1014D000C70AAA3FA4DCBF40CF84222EF70928F711
+:1014E000C8A742A6567B68BE929CAF2B78EC09CC6D
+:1014F000E7E8F3A0B2B0C3300FAE0718CB87A22F36
+:1015000053A3CFADDD03B1B0D4A662FCF4092BDE4A
+:1015100087F92F77B964457ABF53A0E3AD341690AD
+:101520007C84C90FE860FDDD78AF88AA08343F6E7F
+:10153000517B1427D2CB020CD75D9A3479DE8BF61F
+:1015400013EDE324EDDCBD35C0901FE6F919971BC0
+:10155000F246FA7BC91ABF1616FADA0AA81D291E26
+:10156000FD6B7D3CCCF49CD1FAFB5329C8F5F4E12A
+:10157000F5FF739AFE7F4EA32FF94FCE86C8F93B35
+:10158000E781789ABF0CE6EF4498BF4F3DF0A4077F
+:10159000F133B77348EB77BFF6D4F57402EA69F21A
+:1015A00073D510F235424FEF477A9C6BB618E6239D
+:1015B000CCEB0331E7750ACCEBAC98F3FA50410C55
+:1015C0007D6F9ED75FC27C7E9CF487693E3F3E3034
+:1015D000CFAECEE74B1A9F2F7D413EFF8BF67D8F1E
+:1015E000F61C019F7B08EF683EBF5E10CB2E0FCD2F
+:1015F000E77F19427FFEBE607A0CBBEC89B2CBBD9F
+:10160000B1C6DB89FD0BDCEED3BCCA5055E4A3B2F6
+:1016100082DF47A9D74B467F14DA4BFE969BF6E351
+:10162000E8E3AADBAD2F719CFF186B9CE768FEEF27
+:10163000AD05DF7C42757D29FD8462F513D2E46936
+:1016400038BB9DAEE95DA03FBE707AB43EECD0CE13
+:10165000551597F8930AB9BE9A8FFA67EF779305F5
+:101660003ABFA48404F49B75BE6D2A90E9A97F97C4
+:10167000A1F0FA198DC902EE8F8B686FDCD5DA33D1
+:10168000E301F865227E0B0B953348EF990293FF37
+:10169000A5F99B1DC95DF5A89F8B0A79DEB848A303
+:1016A0004F875F2A55F20AB9BF5480CF4FBCB68727
+:1016B0002C16AE9FB97FC7F5715221B7AF165F17D1
+:1016C000C3734509E58CF213837AFD9B0775BD7ED4
+:1016D000B70BEB5B75BD3E0DDB2D2C943439E2ED81
+:1016E0000D8567A566372A35FDACC380E76C0DCF45
+:1016F0001B914F43E169E6D348F17DA06000DFF91B
+:10170000856943B7A78F175DDA0971C1AB2DBA9E02
+:10171000C8998AAF6E1BF03F7D4BB09D8A22F602BE
+:10172000AEC780C4C6637B4FD981DE22DC17BBB352
+:1017300002CF5574AC974AF97D41C126849F6A96C1
+:101740004A315F7197D68E593E07BEB7774D9E5688
+:1017500044FCA843BEDC389BFB7B89AF88B45E5356
+:10176000C1D84501CFE338540FE689DB04D543FEE9
+:10177000E27C17E50999E736C27FA8F897B18DD4C6
+:10178000BF4E2FC364CB55EB37517D29416DF05DC2
+:101790004B7D875A83F507F998528A7C4C286274EE
+:1017A000AF59051BDF81E3B4519303189FBF2E246B
+:1017B0003F162ACF1CE46B74FB2AD5AFF03508C85E
+:1017C000D7B87CBCDA179E3E95FC228B1C20B988CA
+:1017D000CFE572C13C6F517B83784C9B66C4E38636
+:1017E000FD91E74D4032747C1E237919213E10CFC4
+:1017F00053FCAE6EB4B2E6328AE729BE6F541D12B6
+:10180000E63F3F8BCB0CA2D30471FC1E2E870D3319
+:10181000F8BEAD86127CBA9844E7E56EF4825F5A52
+:101820000A4FA74BC5B8965DB69E37AE83EBFBBC9F
+:10183000C2C295846BEAF7A7C45F53BF23CD1FFCD8
+:101840009D26B711F983BF2B8C21C77AFEC0CDC26C
+:10185000AA88F659E2793C5A8046FFD62B137D7A46
+:10186000FDC39ABE4A1CC23F3BACF5ABCBEBEDAD22
+:10187000952C9BF44203DDA7D751C3EFA982F972DF
+:101880009CF466E9C3F4FE93462689D04F85C45E76
+:1018900048B50CD2A7D3ABB7FFB6693EDE69E77E89
+:1018A000FF7B3656F37317A7776A045EA7A756BC6B
+:1018B0005D98164DAF19EFE31B1A4355E01FA43492
+:1018C000CE65275330EFE427D8E1E4E36CAFE1F7CE
+:1018D000B65959CF5DEB0085772CFE5E6C37253FFE
+:1018E000B07227F029E585388A277B9C39DBBC500C
+:1018F000FF5B2F8AB40EE462FD228EDB97251FCD9D
+:10190000A3BE4D79A96E9B53E2F7A219E5A3F9A6F0
+:10191000D29A54CAA7C8CB5E01BBDCFCAAF75D17FC
+:10192000C0FFFE53799907EF337ADD5B9306DF152D
+:101930001CBAF2C436841797EEC6FA49FFF0E7B432
+:101940009B10BE43E0F99543F2323C9FD0DCCD6260
+:10195000DED78737F2E13CFAD154DF8C629453AB87
+:101960005FA6FE2B8421EA733DD6882100FA919769
+:101970002C7C9D44E9FB678CEFBA673B64DC772ADB
+:10198000BC98A6DE0EF0AFCB73E85C25CC034F11FC
+:101990007C77E40607C5178105F1B41FBEBB3CE5A3
+:1019A0009512849564D2EACD37F37E6DA961B1D6E4
+:1019B00015DDEF8FA62ADFC5769ABF29D4C4CA9356
+:1019C00045D45B8AF438AC3EDA57900CBC69427D52
+:1019D00022AF2539D87407C86F29C9AF5C847A4112
+:1019E000E1EF95EFF1F720B9D6C87B0F74B9D2E5D6
+:1019F000E9B713DFA17320203FF9888F595EE64FC6
+:101A0000FA9749DC8E1AE5229A6FC9C4A7D7CAC5CE
+:101A10000E3CDF27BCF8E936BC87E8D74AB68071B0
+:101A2000F26B97395F03E57932EE2B063E4E2F8A33
+:101A3000983747663A2687C96EF966201D60A7CA9F
+:101A4000468923C2FBC66BC3DBFBAE1FF1BE6C270E
+:101A5000BCF5F1FD9D36BEE2A88B2EC403E8884399
+:101A60007B00782E407CC4F1E10C9CFF3A9E23D58C
+:101A70007B4B8BA2F4DED2A2ABE83D18C79A22EED4
+:101A8000C75CFC968C7970EEC70CA57FEE2EBA660B
+:101A9000FD7377D135E89F18FCBE1FBF1F29BF9982
+:101AA000C264291DFC792C223DAE901E07DD41EB5E
+:101AB00079C2A5069257084CA4BF42B95EEFE3F085
+:101AC000547EEFE8A6D252A75D8C6E77A4FC6F2DF2
+:101AD0008ACA5BB746D26FE6C34DE2F966DCDF72B5
+:101AE00061B640742997980DE33195C98988D71C50
+:101AF000C546EB0E5629DC8CEB5437E37935D05FC5
+:101B0000B8772DF27C6892E26491E74153AA2503ED
+:101B10009CE6F330E3B973D9503EC69F6F281F5738
+:101B2000EF35C0E31BCA0DF527342A06384BAD3616
+:101B3000D4CF69F319E089811A43FDBCDD7E43F9F6
+:101B4000E460BDA1BCB0B3C1001777351AEA97BCF9
+:101B5000A81ACA4B436D86F269C70306787ACF6E1E
+:101B600043FD19EF060DE533C39D86F2EBCF7419E3
+:101B7000E01BFA5F34D49FC306F6DB0BB40F4C6551
+:101B80006FE0FD274B98FE6391ADBA1C5A0CF5B57A
+:101B9000FD7F5E1BEE6B9DA3EF5758C8F74BAAF075
+:101BA0000FEDA2CFB45F502933DEC300F27004D72B
+:101BB000452BB47B0CE798F63956B0EC4419E46A2F
+:101BC000CE71910501BE19E5CA122D570CE48FD6CE
+:101BD000AF35B98AA64B7903F7810ED2255C95AE55
+:101BE0005B902EE87711EE138DA04B5FAF55CA7B4B
+:101BF000451683BE39DA3D52663AE7B06D944F30F0
+:101C0000D3675E67ED2FD2F647813F1A6BDF848A78
+:101C100015911F0A3FF77D81C17C02D897656D50F1
+:101C2000A5683AF575D70AD5E945FE54403B412CE5
+:101C3000C0D83FC27F89938DF32E21DF38EF4679DC
+:101C40003DC3C9CD5F242732FC8B2527B730908B4D
+:101C500032BC8FD62121FF6FB1FE65FC1C5B6CE4AA
+:101C6000E7A76C7622F206E3B9D418FBC0757E4173
+:101C70001C2217A70D6D3F8A8B8DEBD323B01FC598
+:101C8000C591F6E6DAEDC7F4E26BB01F23D5F39504
+:101C9000C5517ABEB2F82A7A7E20BE98CDF3C82C00
+:101CA0007731F7A7C067E27E5398F2C58B8A797CBB
+:101CB00039547CB148EB7730BEB860C5F8A2DBF68A
+:101CC00008C511CA37781C01767D9597C76D3CEE23
+:101CD00068E4FE59C5ECD2C425D0FF2A94A5E923B7
+:101CE000A7D71F4DAFFF6AF4FEAA89E7017EF5AAC8
+:101CF00048F795BE9C2A86D280FE9DAC98EE4BD0CC
+:101D0000D72BAAFD8CFCDA0AEB8E4EC6F384F76162
+:101D1000BBD57285B0CA85EFD7D27328797AE4DA59
+:101D2000E5E9912F284F1B8AAFC1FF1B693CF328BF
+:101D3000C6333026CDAD9C1FEAFBA3B4FB7B795C98
+:101D4000F3E866BE6FEAD1261E8F0435BA1F2BD684
+:101D5000D667A670B9A9709793BFD92A8C22BD0700
+:101D60001AC283FB202A3C763A4F07FCFD01F2F7AA
+:101D7000E898EB12D1AFFCE49523A991EB11EF6940
+:101D8000749FD0E87EFFE101BAF712DD352B689F22
+:101D9000974EF737BFADD39D2191BE40FD01FAC2EA
+:101DA0002E75515E799EE822BDDB92CB820E4A6091
+:101DB0002B8B6EBA4E3B9700DFB764A80CF55BC265
+:101DC0001891CE118236A4FD366DF08FEFEFD94316
+:101DD0007F5F4AFFFB44368FD5705E230EF5D91422
+:101DE0005C3F32EED389437BE2C6F288FA31F4DC01
+:101DF000DF176BFB71EC6C34E2DDB2E1457612D794
+:101E0000D8B57D39566DDD68287DF7B2360ECD82A6
+:101E1000F26BE44F9FF6774BCCF5F57A663E1D0DDD
+:101E20009FDC5208F4AF1B6FD1C6CBEF898C9FF4B7
+:101E30006762797F41AEC1DFBB54906BF0F75861A8
+:101E4000249CE6731646D61F5D2319E0317E8FA1D0
+:101E5000FEB87AD9503EBE21DF503EA1D16B80B38F
+:101E6000D47243FD9C36C5004F0C541BEAE7EDF6D7
+:101E700019E0C9C11A43FDC24EBFA1BCB8ABDE50C8
+:101E8000FE1C0B2FC0948CE339FBED55602C37F50D
+:101E9000DEEEC1FD7DAD69CB9CFE18FCD69F47D31D
+:101EA000B89C0F55AECFF3A1CAAB35FD6771FAE808
+:101EB000FE7DA7943D95F679A4F6D1B8C549B974CD
+:101EC0003F84754AEC3CE9769BDF3A250DFDB5066B
+:101ED000C3FEA26A10AC591073CC97BF13AA8AA094
+:101EE000BB29A36E37CE974761BEE27C79140BE81D
+:101EF0001E36FBEDB84FE7513C103196B1F33F135E
+:101F00006FC7F5FF4D42431BA68474FECC9E92A57D
+:101F1000F1E76B1E8C278F2601FD31F4FA507AEE23
+:101F2000E886FA50D544C68E6D6820F8B8B63E559E
+:101F30006D37AE2FCFD2F48DFE04BD9285742E7C0A
+:101F400055BCE89711E911E701264FB98A3EBD6EED
+:101F50000ACFD7B70A6A2EAE8B56DB82D568071C2C
+:101F60006C01E9C94F25791FFA73AD69F3BC75A8F7
+:101F70006A8618072BEE938AD00F42D6D21AFCBE7F
+:101F80003A0DF80C7035AE6BC7E053A146DF88C739
+:101F90008965DD8EF7E5E9E3244DC9BC9DCE239824
+:101FA000E63DFC1CC5FB8AACB93C2E05B908F9CB53
+:101FB000482FD2BA18C8CD5F215FCC72A3E76F1B40
+:101FC000F105FA132EBE7E440A15FDDDE33CAF3069
+:101FD000D4783FBA01027CE0FF0549A6FD648F0A70
+:101FE000FAFDED5E4FE4FEEFAFAA9E0E8305A371EE
+:101FF00032D76FC45F311EF7B8882E3AFF3306FF21
+:10200000E7CFC7F5F6466D3CC67A95FBA7D0D3F768
+:102010002D7C32A73F9FEEB1F3FAD6122C0DC00FE4
+:102020004EA13C3DC098279424CA8F0FC51F9DBF69
+:10203000F0DD77A7F0BC9EDECE7A825DBC1D80BF4E
+:102040004FFDA40EC02A9567F0FA23ED6780DE1ECF
+:1020500091CEE75CB42A74BE7759E30AF24BEE687E
+:102060005C45CFB60D52D229E0DF1F3628452D3012
+:102070003F97DD314DC2FD1377DCBD829E7ABBCB2D
+:102080003539B66759E91E3831CBE23B40F699AF96
+:1020900073884250E3678BB64F254CE78C9C0AEB64
+:1020A000A7BC5E6345518B619F7D80CE6BC7C9D64F
+:1020B000FF888C23DAACCAD344BF2BF52FA4132698
+:1020C00000C8EB45576E909FA7AF9462AD57E8F4F8
+:1020D0000ED5FEF221E6AD4EAFCE37FDFDE65CBE7D
+:1020E0000F51973FFD7DDCC42A09F5CD7281CF23C6
+:1020F000364A3B97ABD5BB0BFAF905F2D1EAA57D81
+:10210000947769FB60446DFDED2E60E1FAA911FD45
+:102110005A7D47903F51FC1C21BFDE453D6C433F3B
+:10212000BF2B8EDFBB220991FAB446D0FF8E06A3E7
+:102130007B12FF4F5E8105F5C8E6BABF755A00BF36
+:10214000F7A7707F636BD185E9782FC856D6FF302B
+:10215000DE93AFAE1F45F71DD4D47E3ABD29A2BD94
+:10216000E5477E28C900D74C6C49C3F5EFE5CC7A2A
+:1021700031D29F32E359D3F800C9A5DAC4F3CE4C6B
+:102180001BDFE56A12E91F1D5ED19644FB7157798A
+:10219000353BA1F963742E92F29FA9761C8F5AD514
+:1021A000785FD48A3623CC22FD3871307E5171B3EA
+:1021B00000D2D5CAFF1ED053C027B413992C44CFE8
+:1021C00055DE64FDDE56AA377EBD40F8F899740CE2
+:1021D000FFDE84191F331E75CC6BC776468ACF2A63
+:1021E0002FB7570E275313A0EB54E07D0FC90DDF17
+:1021F00007B5CBA5C32A1D76F4E5F2F5BF3899974C
+:10220000EBEBB9A3FD5D0CEF978B2F038260BC2C29
+:10221000580FE3A0841E05FF5E4D7EC9AEDB3D93E3
+:1022200071DDD0EFC1F3ED00BF63A575770E434FAD
+:10223000EF1C9D8DF22315E07ED2ADADEDEF1C1F9E
+:102240004FFBA0B4731CEDEFA09DEAD061BC00155C
+:10225000E8E9881F8015A707E0EC01584578AFB67C
+:102260004F02DB3F85F3C8D9B3301FF0541CFC3E4E
+:10227000ED21E769899253720DEBA57ABDE1E6493C
+:1022800087676500EFE954650BDF97C39861BDF779
+:1022900096127EAEE079AF7F3AF63F6A7D3FA56742
+:1022A000EC634EB950EE06C7A787C663707CBAF8D8
+:1022B000F894F5D0F88C2AEAA1F199205F60D94012
+:1022C000EF84D95A7A393799F0EC90D709385E1DE6
+:1022D000E5021FAF3246F7088E02344767E13E2021
+:1022E000BE5EBEA88CD17E75C9C1E3D9EA12BE9E7E
+:1022F000787B89A83DF9BC4D9437D2FE3867B58507
+:10230000D68513F16958D769D1EA5BB5B882F3E392
+:10231000DE69FE252511EB8FAFB65848EE9D59B901
+:102320001D78CF45856C7D08E3B21F69FB819697C8
+:10233000F8A696C077AF96A5C4FBF97AC8D7699C72
+:102340004CE3AAD339DCB80D355E7A3C3954F9B286
+:102350003B445F90FC6CFF134B01DFFB5F4CA17DA6
+:10236000FB276AC4B21E801F786934ED4F58A7F16D
+:10237000EB5B96FE74D48B9B5D3B7DF874BCD8A45C
+:10238000E09F37DA6E930D787CEB9715E43F6D4C48
+:1023900070CF46FD6EC6E3C4E5DFB8701C5EB9E4DD
+:1023A000E0E715659E8F233B606103F7B1DDA5E98A
+:1023B000B41F9470FFF2AD0D353C4EB68629DF791F
+:1023C000C203F12BED7830DECFBB9C590DF7ADB0D9
+:1023D000469E8FD3EF23F0B3A479385D41EF18F216
+:1023E000747733D99E06F597DEB6F818C6BF2BB4BE
+:1023F000F817F490A99E31FF777B4DED809FFA0985
+:10240000FD3FA89D63506CB85FEB95C502E57D97D5
+:10241000FAEE085545C457EF7C2E2EC77D2F27F0C6
+:102420005BE0F7893BF3E8EF709AF9D13B40BF8F4F
+:10243000E28401FE30A64D88ABD31FC5AFFF647E9A
+:10244000CC1317121F56001F1C31F8A0E727747A0F
+:10245000DED0E964DE13F8F79B4F6EE3797331F455
+:102460006F03796EFABBCA8DDC3EE0E66DBEAE2D21
+:10247000B7E27994BB557E8FD112D578CF04681618
+:102480003BE695EBB4BFCB1C655FC43B8F45E63D97
+:10249000EE36E531CC789BE9BC59B32351E791ACDA
+:1024A000A10CF4234E9468798F293CBFFB8977698E
+:1024B0006208CBCBD262EA5D3DDF3138DFB95C2DFB
+:1024C0006F5C6C888B04E61F8025B09BEB3CA28C74
+:1024D000E7FFDEA899F8048AE11267D8CACFF33380
+:1024E000CACF2F7F4BA473514B985376019EDF8345
+:1024F00042B4C38BAAE3E4C8F39E17021FDBC8CE25
+:10250000FB5903DE47BB0E9A6F9C3A48E73A8F9D12
+:10251000FA31FB2D66FA3F2DD1F2DA53D8946BA134
+:10252000FBC112C6F709A5F07D21FDABF06F990C38
+:10253000E6235986C2FDDB741ECFFD3FDD0C35FB63
+:10254000008000001F8B080000000000000BED7DE4
+:10255000797C54D5D9F0B973EF6CC924B9D9030487
+:102560009809448340982413B21060C22656C001D3
+:102570005C820930615F02195C47C5322124028602
+:10258000EF8D4B2BB69877A0D0D2DA252AADB405C3
+:102590003B11A5D8BA846A15D1C208A820A8514415
+:1025A000C7A5E57B9EE7DC9BB97748006DDFF7F7B1
+:1025B000FDF1A5BF7A38E79EF5D9CF739E73C6EAC1
+:1025C0004C66AC98C19F8F791218AB31316FFB30DC
+:1025D000C6DE36B2AA276C9886FA17427A1EFFC664
+:1025E00032F65E61A5D5591CCDD7F8BF1F9A50C4ED
+:1025F000988D858DD87E8EC51612F3A13BBFF14C08
+:10260000388FD1DFF91CFC6F8DFCDE50C604E66507
+:10261000E7E3196BEEBBCCE9857E9BE312F359121D
+:1026200063EBB14A19637D9D9E34673A960F08B2F9
+:102630004428B3A730D687312B0B3226429A277D08
+:10264000D5DD2F8BCE83B10063D08E3DB760E7D64A
+:1026500034C6BC36896D84AC815902CC05F9BB8483
+:10266000E04601EBD99B3B203F1716BCD109A9DFFF
+:10267000F8A9B63F6FC26013D57700400A709E5725
+:10268000515EAC645D0C40C5F2BC799EE19A710369
+:10269000D0DE125DA717D23E85F01F8B2503E1C166
+:1026A000D66BFACFE9693C29830D8BF6179BC6F6EA
+:1026B0001FDB5FB3812D6907388A090B96E03C3F29
+:1026C000CDEA2B8B029FE77418BFD46920FCAAFDCA
+:1026D000CDB3A4CA526A347FAC8FAD2A68BB705C9C
+:1026E000B59D0AD714D19B659031EF3CF45C3663FD
+:1026F0005B997C9500F0DBD43CE4D081D18C50C553
+:10270000FA62F52187DCC3F0BB92672CC460BE5B24
+:10271000E3BAF36E4B16E473BAF301CCB7C170ACF5
+:102720009CF77F02E6F3C53FAE7633C0E3A73E26B3
+:10273000231E2426BB717D03AA186B007A60927D4C
+:1027400008C2579D6FAA7F3C3B0EEBB2F8FBE9D65F
+:10275000B7D469A7F9A7DADDCC00FDC1A77619D6F1
+:10276000912A390527CCF34113C06F18D17F00C7D8
+:102770007BB0AF9CBC11F18CE3415EAA92858D05C4
+:10278000D88F81F7A38CD33D6E9E5390A1BD9CCA78
+:10279000E67A6CC80FF7103FA8DF6F770A3AF85F48
+:1027A000067FDD8EF41FCB5F2F0ABEA3F7C2FA03AC
+:1027B0002F886C072C6976D65D547EA37F3EA5B327
+:1027C000FC4B295DA38CF786C1BB06F9B4B3EAD5EF
+:1027D000D977C23AEA77999D6658D54755AF2E7A90
+:1027E000C48E70023AC0F6B31EBA61247CDF6093D7
+:1027F00064249BF5FD5915D15383E0C17483DD3406
+:102800007917A44DF995BFC479D927FB8FDE8B7852
+:10281000C9F31891BF9AF22750F9A77981AC79448E
+:102820007F714E668FB66F8E03B8C07A9B4D3C6D3C
+:10283000734A34BF3685BE7EA8C075BDD19BE78381
+:10284000EF9688404852D76F91024CB661B944E583
+:10285000A200FD627F71DEBCDB357053FBB54440E6
+:102860004814F5D4DE44E5B81E6A9FC2E7A3D6FB40
+:1028700099D2FE67CABC2C91781AAF3905E665D3A8
+:10288000F693C8CB15BE8BE59B24E7F8C711EE4D38
+:10289000F9EE5F3A897F14B99875E090907839F233
+:1028A000312CA07C7C394BB220BD07560BC15C0794
+:1028B000631BF33E6DE272C9E213516E3129A0C869
+:1028C00005E13CC935669746925C638CFAEB6A2A4F
+:1028D00082FA6128FF91BE3E3B0FFD1D2D3DFB831B
+:1028E00022CCAC63FB0743BB39BC0F64F7FD8333D9
+:1028F000183BA2646B6D83270144D97515EF180747
+:10290000407FF3B3442672B979A2BB3FAC17D0E73E
+:102910006DCCDB5A0474B2304B9237023DCC5FAFC2
+:10292000FFBEB174E6FEC75C989A6506FD2D64D2C1
+:10293000896E7838A272A7C56F606EA89750260678
+:1029400005284F18127E612CE459B1D1BE83E45C96
+:1029500078CACC34FC5E44E36CC2A665549F21BCAB
+:10296000588195E0F772E9ABF27C0DBE128A4F0CEC
+:1029700041FDD3A6E011C452E2C40C0D1C006FB897
+:10298000DE8559830C1B49EE35105D3C77779C0141
+:10299000FB3DEA8A0B9AA1EE44D146E3CCDF2452F8
+:1029A0007E7EF1E14A33CC677E134A47C097CF93CE
+:1029B000148279CD5D3DD314827AF23C9B2FA99489
+:1029C000E0772C067EBA3C631E82CF3C800F8E0FD0
+:1029D000F0D37D07781DD3C2CBFFF6C1FCE7347A74
+:1029E000E59FCE84B4F7808E58212B3C0FA07865EC
+:1029F000CD6E76DCC8D859E70D4921C4272C98CB79
+:102A00003DBB69BA469F7DB1A633FF39A8D7288C54
+:102A1000930A60BDF324A887F071CD20B84E14CF7F
+:102A2000BC3016F9DF959383EBFD305F203C6DF2EF
+:102A30001FB600D2D9A66F44E22F268597A2FC9C30
+:102A4000727779EA46985FC7DD57651E87EF99056B
+:102A500026AADF66B03F5201DF037F31923CEB4D87
+:102A6000FF59FC221B0CFC66F50B94AA7848F05B1E
+:102A700099A4E1F304653DE9AE2E2147C3D7B9051A
+:102A80007C7EC9AB991BF55CBA8BB9ED30EECAC13F
+:102A900039DB04C4B56427FBC0EAB01722FDA8F5F2
+:102AA0003719654AA509BE403F281F08F3C0F1EC5D
+:102AB000300FD42F0E7F3CE573FCA9940EF2275300
+:102AC0003AD8DF8FBEE7FA07517A85DF41E557FA3A
+:102AD00087523ECF5F44E9107F01A557F947513A2D
+:102AE00014F40AD61BE6AFA474B8FF5A2ACFF7CF66
+:102AF000A474847F3AA54E7F357D2FF0CFA7B4D044
+:102B00005F4BE545FEE59477F96FA57CB17F15A590
+:102B100023FDF7505AE26FA4B4D4DF40F5CAFCF7A6
+:102B200053BEDCFF10A5A3FC0F505AE1FF317D57C7
+:102B3000F9CF8630027D3B2DF94999A18E66A1C15E
+:102B400068FFB4F522FF16147079FE9AD33DA520D4
+:102B50003D5A6F8A81EBBDD87ADE022E6F9319A79A
+:102B6000338325641904F859B17B50A108706F03B1
+:102B7000FEB7037E56E6E66C43BBA65AC18FD51856
+:102B800070F773209EEC1CBF13DCCC0BFDAFDCBDDB
+:102B90008A52E64C237AEDD5AE52D6776D819DEB05
+:102BA000232940F6419B8F390350641DDC29A07C0A
+:102BB000D89A254D46BA31F5F9AC03F97A6AB1DBFA
+:102BC00085F2D0D447325820FF724525E51F2A30C0
+:102BD000527F4F39DDCB916F06BAD2BF877269E061
+:102BE0003A830CDDB16497D180FC900CC3260B6452
+:102BF0001F4DC6F56E8DD3EBA116052E207F1EC688
+:102C0000F66DF983892E217F0DE7A71C86766C9BD4
+:102C1000292448A81F6E616C872AB3B07EF3BC9F3D
+:102C200022BFE5AC773E8BF31B187016E1FC5A907F
+:102C3000EF605E8E56FB382BF43768B3FB592B944C
+:102C4000E706BDE3E2207FE5CEC0B3980E690F8EA4
+:102C50008B8774E8EED0B3283E8687C2E36C901F62
+:102C60007180ED433150D0691F9F00F9A243EE7D82
+:102C700068DE1687BDE313114FA6606322CCA7ED73
+:102C800008733640BEAC2BB08F6C42050FDD74006C
+:102C9000F6CF13A8E7EDAD6E8477F66D728148EB41
+:102CA0006B55F010B62693FD08EBC5F501FE77C015
+:102CB0007AB2DD5D04FF6C172B0410B2ADEB0C0A89
+:102CC000FC1D85B8BEA70BB8DD03F0FF31C27F6BDA
+:102CD0009C5C9907DFBB2632791BF43FAD8F44F033
+:102CE000896FCA0922DFABF406701D323D410B7FAC
+:102CF0004E5F6DDD76E1C5E1FAB422CFFEB7E11A91
+:102D00000BCFAB153A8E85AB0ACF690A1F5F8A7F5E
+:102D10000F44F9F7392DFFC6D6FB5081772C9CDB89
+:102D200024F92A82978D19020588B7908076D349B5
+:102D300085CF2F17AEC7FE1F81EB9F0AB87CE90D28
+:102D4000AEAC345DA16F398E0DEA5DCE607FBDC93A
+:102D50003784C3CABD8E6D22C0E10B85FE36441E8A
+:102D6000F0607FAA7C93F634B8510FA9F26DDFA50D
+:102D7000E4160E8DFC33C11A44F960EAC67FE714ED
+:102D8000C4D741A39082F6BBB190E371EE088F588F
+:102D900088F62A589D481F2C8BF32D582C7168BF3C
+:102DA000DA44B95282223694397740E2717FF25C7C
+:102DB0002AE1CB4EFC077FB43F9B7277DC36C4A779
+:102DC00003EC0609F6C1F0CF10A649ACD32D62FB87
+:102DD00075AC10F53D936BB3B47CA7EAF5285FAAF8
+:102DE000F491B275A383D32DD6BFA690C32749AD66
+:102DF00087BB16A8D77C57DFAD1B357270ABB30FFE
+:102E0000B5BBA690FB37A64FEAD3BFD6D63B3DDF76
+:102E1000A9C061EBBABF117C132AB8BD90B42E854E
+:102E2000E83B69823703BBCF7673399CED9F670A15
+:102E300040C1785C7D71548EC3BE76EE74847F0A87
+:102E40004F61E34A7880F1B771B97D79F49F52F808
+:102E50003F4BFF29850AFDF4C207032BE40E11CA7C
+:102E6000074E60B21DCAB756A00E437D68223B9C38
+:102E7000A16B05F24940DE3F1208AE2103D29B212F
+:102E800081E86D8A29E846FDC44CC932E27BEE0830
+:102E9000EFF4C28BF0D141A3BD00F701B73C39621A
+:102EA000960DE8B4D901FC04A89B5B5836AB05FD30
+:102EB000052961A6E41FC5EFDFDDBF50F6E6098DE9
+:102EC000BE95E3F9BE1DFED57F86C60E5EACD0D999
+:102ED000DE02F7429C37F0C72DC81F958CDD6618BF
+:102EE00074A17F42F50BF4E6A788F54BF4E68F500A
+:102EF000F9EE52768B2A4FA2FC2F17A8FC5F3B8C71
+:102F0000E4F76A9CB7DA5F6F76584E2197CB2D8530
+:102F10005CEEF76E87A510FF839C52F89DF3EB06DD
+:102F2000F6A007FD72BDC9A97B543AEB454E255862
+:102F30005A376F87DE6EC912ED27C87FA3F7AF58E7
+:102F4000B39A3B71BF9C00946383FDCF6A203BDC46
+:102F5000EF58A7B077CC506E19CCCBF10FF73D9F4F
+:102F6000B60AB4FF00B348F6A31F0EFD861AFFCBC6
+:102F70002D59261AA7752DA7DFC0CB6210ED8BB394
+:102F80006EC329B42FCEBA043B13489AD965D80F23
+:102F90004EC12EEC441F0CE59D19F085FB69F67DB2
+:102FA000A7C5047430E52B81B9A1BF17BF122995BD
+:102FB0009887FCA8539D1DD90CE8A9A3E0CFD9613F
+:102FC00098CF8BEF401ED6FB5C414952D886FE9CC1
+:102FD000D06B15C285F8BDC95BABF31F45F1AE5F81
+:102FE000C74DB3FF6E43F8FE581E6771E03AEC061A
+:102FF000672E437C7039AFD6DBAFC891A79CDE103B
+:10300000D26FC282AE752614C3F2316ACF06A71002
+:103010007DF4B13F69CD81F5F5A9E3F66A5F166CE1
+:10302000906D17D2DDE222EF5FB09F1F2BF6EB4BC6
+:10303000755C7F591C83B7A25D5559DFB7621C745C
+:10304000F0E81A165A6024BEDF8BF5DDA9ED0548BD
+:10305000273FFE6AF735B8BD38C75E5C40FB89A2E2
+:1030600037D3EC00A79AE2E7D3713E5305FDFCD5B8
+:1030700054F583C5EE730F17C23E7728FC239FE5F6
+:10308000E33EF71CAB489A891F5DE93DF291EA9F48
+:1030900053F7B9E87F937BD007B1F056C7AF0174FF
+:1030A000E37A99512039F792026F900F6788DF2CED
+:1030B000207F5C28278693BF798AC1993413E5A5C0
+:1030C0002BF5A2F3013196ABF567767F1798A7270A
+:1030D0007D6528E2FAAAC6C8E597B0EAF90538AFD7
+:1030E0009A02AB80FB72897519519E7DAAC8B1B94D
+:1030F000CE0D9F201FCD65D2675A3FD0A785B22243
+:103100004F428365C51FE9ECC11FDD1B3CDE940205
+:10311000B371DC37BD663900FD4DA92DC9BC983FA0
+:10312000FB30D20510EA6BB8E6620DBE06F72CF74D
+:103130000EAD59129A608CE2EB82EFB556F25F57F2
+:10314000219C34E3E617F175D72B2933B7E6E1FA72
+:1031500036CCFBAD05F9F2FE619F160700DEF7B332
+:10316000AEDBB7A11F627502F921AA6ACF15370C31
+:10317000EF7DFE7301FDBB0B2F84636CBDFA222E25
+:103180000FE7EE7B5446FAAECA5D971E80F15F46AC
+:103190003F4C2E8ECB68BDD3BAED1DBD1FA6511876
+:1031A000E72A4AD7F85F8671FF0BDB67350460BEFC
+:1031B000D683B9DBAC30EE817C4E074C6CB9611C18
+:1031C000D0DD39AFD189F2D9DA0B1F55F957EAE4CE
+:1031D0004B7C4460418DBC8D97DAC9CF191F91A8F3
+:1031E0003C96DFE422C5AFA4F0DBEBDF3C22A3DD9D
+:1031F00063FDD2ECE17AC3FB831B607ED35C2905BF
+:10320000388FD7AB44D28709C3E5ADB87F5F5DC4C3
+:10321000F58D2AEFC13C72A25F6CEE6BA213F7B979
+:103220007359A003E9549DFF3494FB30FE3D28F709
+:10323000A12CDEC5F3BDC9FB58391F8BA7D8F5CC2F
+:103240008B598FEA1FEB8D1E553A54E9B2373A512C
+:10325000E932B65CA5CB68BD47F3EC489771DC2E2C
+:103260008CADDF58A43F3F787D8D5737EE1BFF14A0
+:1032700075FE03359DAC8C73D65B96897AA7CA140C
+:10328000C8BD1C39A7D247EC38B1E94D8AFD115BA6
+:103290007EBB32DFB3DE47E95CE1D6624946FD9989
+:1032A000E0687D698DD66F6B0FF4FF21FA6D6B4B73
+:1032B00064EEDF50FCAF8ABEED04395167447EE115
+:1032C000F2020FC2908E8EDB990FCF67A6BB85D01E
+:1032D000048DDEBFAED41A9AA0C12BEC388D03D07A
+:1032E0003F9025323CE70BD5BE4F7EE2F965A28CBC
+:1032F000E720096545199807C385E5DAD13F2C9287
+:103300001E4BF8414110F7612A1CE24AAE277A7839
+:1033100033AF86FCB7D65A9B0FED54EB3FCD54DF4D
+:10332000BA41086E83F5C499BD64E7C75D99166C10
+:1033300040792F78BBE767073B61FCD08A1B913F40
+:103340008FB6189919C60BAFF18526C0BA16BE7D87
+:10335000EA6D3C3C53E97DEE6A91EC9A4BF987BFEC
+:10336000AD3FF84F3174AECA2195DE7B93431A7F8F
+:10337000F0FE22AD3F78F0F534DFF143F7B063B6ED
+:10338000A81C52F9E2B0B2BE4343B66C7A16E074A0
+:103390006821B71A6F1EC6E9E0E6C1921D378700A3
+:1033A000474F4F746F51E888316F375E118EB3BC51
+:1033B0004BBBF348BED54B56E9F01EAB377AE7CF8F
+:1033C0008BF3DDFD45DC5FA6EA15667613BE377C20
+:1033D0007FC436D4731BE619490EDFDF99BBCDE2FB
+:1033E00088D2FDE5EA9558BD5055FB0327B6837496
+:1033F0006700CAAD57C6F982C37AD733EA78F111AC
+:103400009105B5E78DA8778AB572DC44DFE12F0F0F
+:10341000F7637E16E744BB645BBE9B4CA4A7F3DD59
+:1034200002A653F2DD0697460E341A5915AE5B34E8
+:10343000703F08ECF8B36668EC13878B8FDF54C9D4
+:10344000EB75A48FCC7A17D2C6770AB28C30EE9582
+:103450002E7E9EF65CC2C8A4F045EC81FF52E8E4E3
+:103460007E9437906E52F0A6EEEFC13A71E339695F
+:1034700093D19385FBC4C4B2273BD14E6D940DB25A
+:10348000004BB5B8B89C6B94A5C908AF753669F206
+:1034900076AACF881F9B12DC3B02B45F75B31B700A
+:1034A0001F86F3C27D8A4DFA4ACB3F7E296046785B
+:1034B000F92DFC1C21769EC395F59E57EC1675DD03
+:1034C000B1F51C2EAEDFF6E4BB87213C17E7BB1D30
+:1034D0002EF2E7DAE87C8FC60356088CF3FD7718E6
+:1034E000EDF6B5126B84F491F8EFFF2C0CEBF2C300
+:1034F00034701F22C9F01DED6AC922E379DB7F1702
+:103500007A4BB19FC6C43B4AF8F99E6F04FA6954DE
+:10351000FB513D7F8E9D4F8D81CBE9F10A9CD0BE42
+:103520004338BE52386EBC2BBD87FA8A5D0776FBE6
+:10353000523CD7ADB4B3CF82389CE4B5E3786A9CF3
+:1035400006D8BBDFA375597C37A07FC46D16B81CA5
+:1035500057E2351EBC843F4C3D5780FDF57417F78C
+:103560003FCDC4B4B214F6D7B83EC56FFCA021CC91
+:103570002ED64F601CA3F3D94BC193D9383C4D26AE
+:103580000B9DA7013CE771BCF84AC8DFF52DE1B9F6
+:10359000E24278AEB8183CBFF84726F71738417BAF
+:1035A00014F4CE0FEAB9BC9A5F9FAC9F477321CF4A
+:1035B000DFA58CFFF508BE6FDFA4D0A7BA7F365B0E
+:1035C00058C00AF690650A73235FA8710E6A3F9B84
+:1035D0005C0954BFB570DC26847BB343A073FFE65F
+:1035E000649EAAF526B92A37E1BAEE53FADF843A87
+:1035F0003C9DFBB9D0EE50FD056AFDEB94FAD7B9BE
+:10360000C66DE2F0B50F41B89A44B147783EE8E2A2
+:10361000F35FEAE47C3529E63C15BA9F367164D441
+:103620002E98BF979FCBCEEF23B200B651F4A40CD7
+:10363000FFC373F48578340FFC5E3BCC437AAD87CF
+:1036400073555308F030CF6BF3F578AEFAF65D742E
+:103650001EF8721993853E97D6ABBF7075EB55E790
+:10366000773C677DC2A5B5F359284F2B67CF2BE771
+:10367000ABE1987322353DA0D0418BB21F47B98989
+:10368000F23A45643E92DB12DFAF3E58C8FDA3DD3F
+:103690007458250B88BC032E7D5C8B04E2312925F0
+:1036A000EAAF826C00F3BDF9ABC2A6705326C0AB83
+:1036B0006B3873A2FF3F79F5AA0E239E730D63E466
+:1036C0007D6976B0C452FC5E60E0DFAF979B8D9061
+:1036D0004FB6B314446F383093F6072D554C16810E
+:1036E0002FFEE9E2FEDAB9AB3F61E84F4CAF80A5AF
+:1036F000D829DE685216F27715F73FBFB46E2DD386
+:103700009EF3BEA3D067929DFB6D31EC0BDBBBCD6E
+:10371000C9051B99B69E41F177BBC32EB22FB87F66
+:103720009B427E504E386DE40FF2B02E09E5CE413B
+:10373000A193E2CEBE2E18FF1EE249E5A316035B5D
+:10374000C2F5A2EFA271435DCA78BDC50D3DA8F8D0
+:10375000E50E623C10E18BC7F93CF8975401E72D68
+:1037600049BCBF6CE8AFA10CE1A3C7D7E5E229BE15
+:1037700086C325967E328A39DC84116E4331C2E3DA
+:103780009BF3E7C591E8C6E0FC165FE35C82FC6250
+:1037900065894E0153BB4CF118CC22047305F4E744
+:1037A000FA885FADA5CE5411D7BFC0C024B0E3C71F
+:1037B0002BEDDD554C782F8F40C8B8DC96D87B2A8E
+:1037C000FF60A1DBF95C10FA9D786BA213ED74D851
+:1037D0003F7A71BD13B240EF011E3207737F7166ED
+:1037E0005A12C5533CD88BFF5E8DCFEA8E530BFC2B
+:1037F000E8B02E4ECDF4F0615D9C1A7BF8F0BF1559
+:10380000A706FDFF6FC6A9A9F21128D388E7E187B3
+:1038100044D685F4F5F1DE9B8C888FE64AD68EF08F
+:103820000F7C05F0B644E16D1CE779FEC7F0DD784A
+:103830004BA2B39120C8FD3547E2998CEDD5FD9F91
+:10384000C0F2888EAFAF129C48771F9BB8DCF87827
+:103850009140FB99154FFFEA7768972EFBCD0F1229
+:1038600031D8E294D49A81F3AADBD19488703C29B0
+:103870000512D17E3A1514C90E8BC5CF9A62D59E1A
+:1038800077270A401F2B15FA600BBA9AEF86F97D4D
+:103890002EC07A607E2B777D49F9FD6E4B17CBC227
+:1038A0007EC393EE81FC52D87735C0F7FADD7A7982
+:1038B000BDEC673FC8B027D0BAFA19B2088DFDB089
+:1038C000DDCAED4627D2EDCAD744842CAB675DCD67
+:1038D00038BFD8F6F5EDC74DB84ED9C0BAB2475D7E
+:1038E000F81D38D884FAAB9EB590FFAC7ED7A9C33B
+:1038F0000CD318BDB0048559D985FA6165B1A21FF2
+:103900004A5809D23BC087FC1D0198176D6B83E9AB
+:10391000640735FEDCEC3641F9A9C3995BCDD0DFF5
+:1039200099ED7F4D148645F504636B097E67DA07D0
+:1039300025792F624F7FB48691933A6A2771FCDA1A
+:1039400077C3043321BB87A775C650E2285877DDBB
+:1039500056A33300C575BF12DD36947F6F9A89AFC9
+:10396000EB7E75D684745827B8BB04A21396288CB6
+:103970008CE26DF9AFDE9D8474B51CF4F014A0D315
+:10398000654F9DE3F5DDACCB0AF5973FF1CEA47B07
+:10399000300F7AD6D203DEC6B77798C2B61EF0D6FD
+:1039A000FECE24F41F36FEFC0BC2CBA9670496E9B9
+:1039B000B8B0FD921DA7292EF70C20484E463C8A30
+:1039C000B5A6A40BEB9DD91E4FF2E9CC1E81CEAD5E
+:1039D0002E85C769C59CCF80DE7FFD07187FC96132
+:1039E000B313CF0096FCFAD644F41BBE2FF938DD92
+:1039F0003FD694E186F92F310632644A79F992B6BE
+:103A0000DB891E171FBC9DE27A81DEFB184A699D87
+:103A10007D707D0BB7DC40EB5BF2D87C5A1F7B548A
+:103A200060C81AE72436F9891EF0FA99C23766B6DB
+:103A30002AFFEE34F49732B611D6F33E3AF1717F95
+:103A4000F93791FCD066B6ED8880FEBFCE7401CF09
+:103A500013C583468A1FBC6D6F32D1D38162AE8796
+:103A6000C61F3C3709F9EB3687E433CBB4FE1EE3BF
+:103A700008EBF15F39D8EFA7A6D950FF33258E5058
+:103A8000539FE0F5FE36739C3002D28CEE73CDBFAF
+:103A900031A413E52CB67EE7FB44272C6B9021095B
+:103AA000D63F68245F0F96FF282D1A0FF7D96BC7F2
+:103AB0004D7D912FD20C2C17E6B532F8098D3B4580
+:103AC000609F207DA8F0A8DF6D66212DFF6E7F37F7
+:103AD000867FF5DF413F13DCEAC132D8988670EB70
+:103AE0009AF4471C07C6DD01E32C7A18EA6BF83517
+:103AF0004A17A668B923CA7F4CAC49C273ABC50A42
+:103B0000BFC7E22B96FF3F2A56CE2714FE57DBB3E2
+:103B10002DE93DFA67A3FC1E207D50670CFE14E1E1
+:103B200054F7A699CECDEA7EC5F90C0476572ED06F
+:103B3000FDE95FEE7BFD6658CFE976631A9D55C5BA
+:103B4000C8D7254F029F427D6396C8AC245FBF3023
+:103B5000A15D94359E759961FEA7D33C0CE9FA02EC
+:103B6000FE84F21EF9338DFB6BFF637275D7FD9FE8
+:103B70008889BDF3E3E25EE46A9F917AB97A8E0D9B
+:103B80004B8261D807BF583E90CEB562E0ABC235DC
+:103B9000563EFEB6D8DEA37C84BFD799068ECB1ED8
+:103BA000FF90E8F8739077A21CA55FE6E5F40B7927
+:103BB000535F5C6F8681617E65B0E37A21BFA77534
+:103BC000EBE119FBFD6DA43198BAD1E024D7C6CD45
+:103BD000E9DB13F09CAC51B1EF1B6D06E2EBCE6C50
+:103BE0003BC58BE0BD8D3B60DC1BEC836F41FD3939
+:103BF0006FA4AA67391F4EE35D43FB5B18C63D8285
+:103C0000DE51E405F03187A7C2F706D2F79D69A51A
+:103C10003FC57DC20DDE5335B590CFEA273233C99B
+:103C20002F2E17CC5415F635EE5B992B8D970FCCB4
+:103C3000D2F5C7E5A8FB9F127ECF1A6FE9C2F68DB9
+:103C4000EE99C65DE8B72935CB827C21DDBFDC105B
+:103C5000CEF6F560D7A9E9B4B40355183F7D5DA948
+:103C60009EBF6F8EE1D39BAAF4DF6F64DBD2D1EFEE
+:103C700075E312230BE2BA62EA178FE4E75F37318C
+:103C80005F936C8BF2DD30D63507ED8744B07B5106
+:103C9000DE265AB299C4D7DB65A6381A99EC34717E
+:103CA0001C6B27BBBF548A89E7964368B734AE8242
+:103CB000F6688F66333BF733E8EFC14C146D141789
+:103CC000F84A29EC771D9492BE7A65BB1044FFE850
+:103CD000B98AA79A31D4070DF200C07F99824F1696
+:103CE00008D7603B91199C28D798DB6D9747323AEB
+:103CF000BA467A4D2A35E8E45AB23B4E0797D4C902
+:103D000029BA7CBAA7AFAE7E66558EEE7B1FEF5503
+:103D1000BAEFFD9614EAF2FD7DE5BAFA03FDE3740D
+:103D20007947E07BBAFA83D6CFD0E5735B6FD6D5FF
+:103D3000BF72F33CDDF721C165BAEF4377DEA2CB5A
+:103D40000F6FBF5B577FC4EEB5BAEF05A18DBAEF19
+:103D500045071ED4E58B3B7FA4AB5F72689BEE7B6F
+:103D600059F817BAEFA34E3EA9CB8FEEFA83AEFEF9
+:103D7000D8C8B3BA7C25FBABAEFE78CBABBAFC445B
+:103D8000F92D5DFDABB38EC7E8313970AB0BB7874A
+:103D90007C9F748DFDB4AE3EECA46B906E8C0A3D9E
+:103DA0005C9B7756F77DAAF36B5D7F26901BB8BFAF
+:103DB000B560DC25A471AC9D521BEBA474F038EF08
+:103DC000FE912847DA02CD48542F977D3100F5D671
+:103DD0002B15B7D23EE15C16DFAF4BB04F46BABEF3
+:103DE000CE620BA01C57F9353122B25011D061447C
+:103DF000A0548EC4B3106C6A9223564A5322A9541D
+:103E00009E1A49A6342DD28FCAD3237D28CD880C83
+:103E1000A23433E2A0342B3294D23E912194F68D19
+:103E20001451BB7E91024AB323A3A8BC7FA48CD2B9
+:103E30000191F1543E305249A93D722DA58EC835ED
+:103E400094E6446652BD4191E9940E8E5453796EC6
+:103E50006416A55744E6537A65A496D2BCC8724A44
+:103E6000874496527A55E4566A3734B28AD26191C1
+:103E70007BA87C78E42E4AF3238D948E883450EA14
+:103E80008CDC4FF50A221B282D8C3C44E54591071C
+:103E90002875457E4CE5C59147291D19F909A525C9
+:103EA00091AD9496461EA7B42CF2734ACB234F5182
+:103EB000BB51912728AD88FC91CA47477E4FE998AE
+:103EC000C83E2A1F1BE9A0D41DF92B9557465EA0BA
+:103ED000745CE4552A1F1F3948E984C85B543E319D
+:103EE000F226A59322C729BD3AF20EA59323A7294E
+:103EF000BD26728AD2EF45CE52BB6B239F503A2526
+:103F0000F235954F8D7C4969F7FEA3A2D77B808659
+:103F1000F3903E10DFC6F01C659A4F207FDF23F13F
+:103F20001F3D47F2AFCC6CC77C1336E9C3DB633C63
+:103F3000CE6CFC879DB18E327EFEF6F2BDBC5D7309
+:103F4000E5F1B76F45FDB6CACCD03F142B57D5F974
+:103F5000BC52BA2F1DCF439B0BC375E84FDBE4085F
+:103F6000D7607A5509F7A30D2EE1FA33AF84DBCB86
+:103F7000DF2FF5968D83F29A553B5EC7389B4F41F4
+:103F800045521CA32D7805EEEB7DA83F904FD278CB
+:103F90001C0DB3750DE0725E267D01F64317EA87AE
+:103FA000957B32C91FD582FB748AAB0C37A37E3157
+:103FB0002AF710D96E3D9CCCCC69B1001FF6A6370C
+:103FC0002EE5EFFEC2CAEF4FCA25DEB1253DF8B996
+:103FD000A3FEF3CBEE67F27FA89FE925C5BDF7737B
+:103FE0005FDA1D9E5ACC4A6ED354D067D50ABE996B
+:103FF000F8E26CA48B7301B39DEE0104164F417B74
+:10400000D15C678CDA8B0CEBFB58A503F1BF6762C0
+:10401000098C1B7683FDE1BCB01EFC25227EAAB371
+:104020000D8CC797B63F8FF8F5427DD4D7D56887FA
+:104030006AF6390DAB9EEE8FE758F3147BD45BF72D
+:104040003E9DDB7A95FDA4F7127EE2FA12BDBDCA51
+:10405000903E713D75229D37EF4BBFE3C048C88746
+:104060005F12E97C98C9EDFD092EEBB91DABDAAF03
+:10407000B5204FDDC06F6FA5FFAEBF1DE6B36FC5A6
+:104080009D5968A7DFD7F48411FD32E1FEABE83219
+:104090004CECFE3FDC9F99F0BCB13AB04A42FBD8F1
+:1040A00068605B681F318091BFD310BFDA8EF25D0C
+:1040B00034E8CFF5CF2A7CA0A647D1FF857CB69205
+:1040C000C73F190D3EBA77CA06C419F83D84401D92
+:1040D000E617B45C998376E4648959244D5C86C6FE
+:1040E0004E8CA37D9504636BECCA583BF2B112FD74
+:1040F000FDE4E302BF9F887FB8CFA176C82792CFA7
+:10410000DD80E332D9FE238D7D696E9DBE1CF17486
+:10411000B4FB9E17AC11E90AE70A78A85E1DEF1EF2
+:1041200002DFB729FC6F54E2AD805E025ABB1CE986
+:104130000AEB4BA54A3C91B24E6F8BD98EF4735C5F
+:10414000084CA078C24AC67614C4CCCFC0E75789C1
+:10415000F5717E408FC6FE1C8E273609C16D04079F
+:104160001F856ACE7FAD2FC52BCCCD3499504E79AB
+:10417000D7AD0A61B9179063877599252699009E76
+:10418000B58A3F9CB508E40FD7AD0BE4C789A627D5
+:104190009EC7EF61C19E23437F7F56D617C671B17C
+:1041A0007C138F5B68BA37C1CDD7216C453DAFC258
+:1041B000ADBAA5611523BA6E37DE85747226C18E3D
+:1041C000FBE56A65FCB922F35D0C4EE74ABAFD7D5A
+:1041D00047DE80FEE707CC0CCF0761FC391E0D1EC1
+:1041E00034F009BD81EB57E0D3A4E0D9ACCCA329CE
+:1041F000FD0E86F338FE61821DF75FE74B52F87AB9
+:104200001AEEA47DCB895ABB206ACED562E745322F
+:1042100044432FB174663470B8A8FCA0F2814A37C9
+:104220001F29F4AFA6A7BBD7A7F18788513A8DED18
+:104230005F956F576BEB43F9D5D93C4EF6A8E25723
+:104240003EF9F4B96A8C07682EE1FB1266F7D17D5E
+:1042500073753E0850E217857ECD368B7B08C0E72C
+:104260002B653E4D82A70AF76D814D66A28BD87DE6
+:10427000D45BDDF3665E932A5F0D586EA7F2EA16F3
+:10428000B3DB0AFD55B73E7D27EE5F8F09FC9C1B13
+:10429000861D80E75778204F7054E8EC69A5BFA7CA
+:1042A00095F68037867EA8C00366BECF54E8E52821
+:1042B0007601722CBDD42397E2F8923B9FE4DB6A2F
+:1042C0001E175963E8C8C5FD5FCDDA50AE761FA84A
+:1042D000C26D725F50BCB87EC999817CE1F09527B0
+:1042E000219CCFB61427A13FCD9BC8BF0B92B7042A
+:1042F000F393FF35BFC484747B3881EE0FCD1EC4A9
+:10430000E6CEC0780AE5DC7976E33593717D579681
+:10431000F2F9BFB2065678256307D758981B88E490
+:10432000D53532E5FFBE268BF26FACB153FAE69A73
+:104330003C4A4F98385DCC4EED8E1F37E17C869716
+:1043400072FA185EAAC2F9B62CDCE74FFED7ABC5ED
+:10435000782E31617766CD3563A2EB0B2B7116D7C2
+:10436000B901991A7D51757DBC7208C3F3B59E5190
+:10437000BAEF2CAF289ACFE17481F43B6FBD83CEA6
+:10438000F9664D49D5D5BF717D3F5D7E62A99DE03F
+:104390003A7DF2205DF9CD354375F95AE5DEB483F7
+:1043A0006519D642FFB71E148328EF6E5D7575D26E
+:1043B0009D3C4FBC150BFF3BE607E6E07CEEF88921
+:1043C000D989F724E66F16582095E0C6F5C7EB3C6F
+:1043D000EE7AC1669179A1FF0F92DD9949D0D54956
+:1043E0002B5FC7C9BF8B5B1B517FFCAB91FA810D63
+:1043F0008A9DCB5581F8F48383B974CF64F6A0C04D
+:10440000003C97EA4A67F66DF07D7E988FC3844240
+:10441000F2AF9CB2BE7DC59D30BF0FA7B62EC2B80D
+:104420007DB023D251EF7DF8A4C850EF2E5DF5F793
+:104430009132C06FD9FEF6D71165275A4526A33FA2
+:104440006DA799E21501AC9948F7D1F505F391FEF6
+:104450007E52EC598A577F3E5814CC27BFC1EA746C
+:104460006E17C4C001D6BB08E55AC09068DF81F260
+:10447000CDE82D413FFFFC37FBB306414BE78A7F78
+:1044800051E927C05C7D18F95D9E24FA39D1923B31
+:1044900089F4CB7A81A17F1EF8671AC9BDD654036F
+:1044A000E27B5E8B48E7FCEA39B3AAF7D903A2178F
+:1044B0006C0E6CE7E57E2DD910807EEE7BD9A8E0EE
+:1044C000B184E203E7F4E2CFFC0878C5ABF1972DA5
+:1044D000DB2B7AE87CD5251B9AD16EEF9CB803C7FD
+:1044E000FFF4C0A024B4A74EBD36D3C8E1B68EC633
+:1044F0005FDAD8918F715BA7A706DE93209D6BF2E0
+:104500003E80FC7FB24FFB0F4741BD8FF7FC64003C
+:10451000C63D85957834751C6FEF71B18F90FCF0B6
+:1045200073BB483D375FF60B2BD1CDE7FDAFDA2AE1
+:104530003AB4706DE07050EAC35F16F7C787320473
+:1045400080ABD7CE26E1396C356B57FC3F1C6E76BD
+:10455000245A809B5CC7FD81F30DCE39AF221DAE7E
+:104560004D90118F6AFFC715FEFDA5C2EFAA9C3BB7
+:10457000A9E4E7AB7AE5196E2F01625FC7FBF64B42
+:104580006869741E61423E52FD6C7F2C4D51EC8B6C
+:104590002E13BEDBB07CB789E2551629F79CEA766C
+:1045A0009A834158DFE7A55CDE2E33FDEA8778D099
+:1045B000BE18110BFDACD82E044302D6DF4AF452CC
+:1045C000070A295880DF83933AF1BB1D142DEE377B
+:1045D00082FC3EBE050C30941F01166C4E81FE1706
+:1045E0002AF62FDB693CA1DD8FAC68D7DFDFAFBFD8
+:1045F000E0BEBEA719FDC20BA07F6CBF90C59C2B6F
+:10460000B41A491F5A98A501FBF3C427901F73D908
+:10461000C37CFF169D8FC8CE03CC167983FBA7D130
+:104620007A0567905D389FC5385E5A743D979A5FEA
+:10463000EC7C1639B91CA96B1582C11EE6A7C237DE
+:10464000A982D9515E2C07B8225DC3B813F01ED4DD
+:104650000A985708AA2C0A78126F82FC2220A820F8
+:10466000F9073DD350FFD53F2CF27D4580FD0DDF8E
+:104670005350F1BD18F08A705AECB5D1BC97F8BE12
+:1046800020FCEF073C23BF2F7D226842BD7E9AB5F8
+:1046900026DA805FEA363F716319B6DB72D0847622
+:1046A000424D4A28D70026B1AD6CF5960963B07B20
+:1046B0000FE99D8596964EADFF454D9706F57059CD
+:1046C000BE539FFFB670638A1F7821FE0BE36DB661
+:1046D0008B642F68EAE9EC9D25812E8AB75902EB9D
+:1046E0006D94B1344074B9D0C9ECB82FFE77E7C7E8
+:1046F000C41AA2BB734007624F747799F38DDDAF84
+:10470000E59629FB35278FEBF9D4A7C485AFEEF9E1
+:104710001E47ECB9CDDB4699F46517E84BB4B33FBF
+:1047200093B8DCFDECC5DC208A96DEE4EE22454F32
+:104730002E44BD08E97B9B9F4AC47DD9BB0F3F95A2
+:1047400041E74EA85F8669F56CA83FD2CF1D4F5B4D
+:104750009D3032AB79CC1C427FF7995D66F21FC762
+:10476000CE7362B1B7B20CE58BA21F3F100E8E94D0
+:10477000512FFA7B3E8F8AB5C3BEEBBAE6E1BA8A07
+:10478000D00EE0EB3AB69EAFE7780B5FDF820BD638
+:10479000A5B71F4E5A43A4B74F3E21B246BECF9C89
+:1047A000437E480BD05101EE5F5BC80E38057600A2
+:1047B000EE03D4F5ADB8E58D2312E07DE9159DF942
+:1047C000218047CD0366D2EF4B7F9B40F0F940A894
+:1047D000CC447E3BD36A76DB106E3BAD541E9D4FBE
+:1047E000B7BE5F5CA6D5F797092FB685FB81C0C61B
+:1047F000263F90009BB89A427E2E83F78498CD4046
+:104800007A21B6FD63655C7FAC100D645FD699B804
+:104810009DF9B1B22F5AAD7C5F5DC6EDCDB565B2E5
+:10482000AA37DA106E07F79A65BA0F2BB11508A7E9
+:10483000838281CE31FA957B1BCAA0FEBA37CDB9EF
+:1048400028BF66581267235FAC4B5E44E766735817
+:10485000A711E131AD74D54E8A13E9CB648AEBC15F
+:1048600090288D3FE665E3DB136F437B04EA8A60A3
+:104870009B5797BEDF1FEB6FC13CE0FD88B57DE223
+:104880006DD8DE21318C3B09EC35931E358E831DAE
+:1048900020FAA9E34097E3FB5A95FB9A10DEFBB39D
+:1048A00052F364A83F578A7372FB814DF804FDDD13
+:1048B0004B04B253D8BA7031CAB9116C9D8CF12D2A
+:1048C000B0EA5DE7532F067F7D9C51DD38A6DCFF03
+:1048D00004C494125C75F93A93F23DF066CD67D941
+:1048E000044709CFCBFEC6789C4D5D4E97E4463B0E
+:1048F000B392B56F0378DC50EA330E7351FB4FAFC0
+:10490000033A0BBDA08F73BA4EB2D37D856C37F3DB
+:10491000896477D827227C0E81798DFD092C8FF24E
+:10492000D326B314CCCF600EF2ABCF703B9C8D007E
+:10493000DFBAB5973BDFF794F9B61B71BF3F47F17C
+:1049400037D6199EA4F1D5F9564B611A2FBB8209AF
+:10495000889FFA14D8DFE07A9672FF83C1C2BFD76E
+:104960002C6129C83F750681E86DB3F718957B1D4A
+:10497000F614EDFEFAAF2A7DAAFB1F294CEF131D9A
+:10498000AFE2717005304D2D9EEA4DDDFB243BF604
+:10499000B71CD42AD65BBEE7E95C8AFF13EC069C01
+:1049A000D71B65DC4FB15C7D27E9977ABFE897E8B4
+:1049B0003BBD085F7CAEB4FFBC8CC7831D2B53FD91
+:1049C00035EDA42797EFF9F321DCF7F5D6FF0A338D
+:1049D0000BE1FCBAF69A092E82A16B30C569308AC8
+:1049E000E0C07E7231BF0836C238FFCFCAB8BDA65C
+:1049F000D2F722453F1940689D277B21602A837E9C
+:104A0000966CD1D82FF0FFA58CEBF965DBF5E54C62
+:104A1000ABDFC89FA0F7970BA62EBAE7278CB13A59
+:104A2000510E569BDA69BF2CC08600E96F512FEDFD
+:104A30008CADDCDE31B608643F921FC485FE31B018
+:104A400017215F9BDD351CE5C0BC341F7F3F4AB199
+:104A50005317F1A9B045BE3B19EAD9FDA0C791FE95
+:104A6000CCBEF70F5330DD663E7F49B123E7B7C6B2
+:104A7000BC0BB55EBFBEA32630B160FE473318E95C
+:104A80000B33AE57A3878F1AA607D05E08E44814ED
+:104A90009F6164B1FADCC3C86F90C6CB25C55EB315
+:104AA000941B55BF9CEE7ED539F68D8444A8E63D17
+:104AB00013181B53D8BBDCB8CE1D1F42FAB8CE7DED
+:104AC000F5019E6EE8A473670964670AC5F3B28AAC
+:104AD000422A27BFAF67B21088C7EF6EE307DA75C7
+:104AE000BE82FFE8216EC159DE4B3C4845EA65C5F0
+:104AF00083A8F1EE3528A70745CF396A5EE0F1D2E9
+:104B00005F58FF35E035C8DB0500D400F2CB931FBA
+:104B10003EB0D62C37A6A11DF3FC6398AF69900870
+:104B2000FF5F585F7ED7EB423A4F6202E07576D264
+:104B3000FEC7D08FFFBE64217BF4115C9C0BD79124
+:104B4000C0FB378469DCB92C7C1AEF555C9DD69983
+:104B500080E2B966552EC5A53557166DC6FB51378F
+:104B6000970F9F6DE98F4E09A6BC0B58FA0F8C1357
+:104B7000BCFE1B5817E5CB66BB4700DF3EDF3507A1
+:104B80004662DF2F2F9F2D01BC3EFE41571BE67F63
+:104B9000583E81E737750DB052FE5A9E6F50FA634A
+:104BA000D7CEC6F8AB8F1FE5F93AF81E20F912CA26
+:104BB000457D3BCD6775A2DE50FD4935866729C529
+:104BC0008D33CA25954F3ECFFD64CE2D44575D747D
+:104BD0009E531F17326622FF3F2138B741E98ADB17
+:104BE0002A132B19D2213F2FAD53E4493D1AE590EA
+:104BF0000A6E1FC9ED809DC9FF85B2690B8F0B60DE
+:104C0000CFB2768AAF1C06F37145E733A7DCCEEF4F
+:104C1000EDC6CC2B58EE99539E8EEF389E48407AC5
+:104C2000F8EF0AF79C723A7FF2DC89E5ECB5604652
+:104C30003AF4BBCCC03A518FABF7B5EE33E8E3FAA8
+:104C4000E794737B404DD78DF2503F2A7EA0BF86FC
+:104C50007FA7BFD4517C9E6A7F2A3C172AF084FE2E
+:104C600037FD3BFDAB724CEDEF1F17CEFFD17FA799
+:104C7000FF9915FAF9AB76AABA8EE1688B019EA767
+:104C80008F61BAF9A8E54D4228FDA6347A87D1890B
+:104C9000F7BA1C9EEAAA5A18FF6CA9A300FDDB67AD
+:104CA0007D254906E8F70FE58A3FF65EEE1F684A64
+:104CB000BF310BEDBDD3BF5A9C8AF6CDCA087F2FFA
+:104CC000A03EC2DF0F38DDF1A609E306EB77BD3366
+:104CD000A91FEE4BDB0BAEA0E7B6143BB32EFA5E7A
+:104CE0009184F7039AD2DF936A691CF59D4EEEE733
+:104CF000388271423DC4111E28EFF657D33AF3951E
+:104D0000F5748E7677946BD6A996ABF7BF62FBB13C
+:104D10008DE2FD6C45DB233DDADF0881E3AB268EB7
+:104D2000EBE3E2D79C8B5EA57D71BE01DF111979A3
+:104D3000C8679A07E53B4AC7BD82F057C753DB45B2
+:104D4000FDBB5D7AFFEE1EEEDF55C7712AF3AB495E
+:104D5000E9BC0DE3AD6D7FAC7F0CE5CCB58FB0EE5B
+:104D6000B86DF49B4E36ABF9E6D9132AD08F285292
+:104D7000FEE33FAC792C00FD1D88EBBCFD55E4F350
+:104D80000D096C1BC897B0E3ADDB71BEE1FF4A268D
+:104D9000BBAAD29C7005BE1793505A691B45EB64A1
+:104DA000241F124A3D27115E6147BC018C51A0238C
+:104DB000E3228AFF0E58C99FE8CD8FF7A21FEE802D
+:104DC000814D602951B8BDA7E0C9368AC3ED807214
+:104DD0009F03FE063C897EBCB50305A46375DCF425
+:104DE000D2CAF851C5D171D34B3D91F2746DFD24F7
+:104DF0008A03ED6DFC58BC9D2BE7F650FC284ED77E
+:104E00009E0AA03F8D9E9E31215E97BF7E4A2A73E7
+:104E10006BFDC7D7F7D3E5AB6A06E9EADFBC60A84C
+:104E2000EEFB5473A74B6B97A878BBDC7D53678769
+:104E3000372D1DF71702EBFAAD0BE1D5EE7A0D53C6
+:104E400083EC413DB67CFD35E4974E8A54535AD7E6
+:104E50007A0D05CDAF88CCA4FC4AE5FDCE57C4CE73
+:104E60005D07B19F479264B42756489D9F61FCEB54
+:104E70000AD940F787000FC37761BF39A3C9EE5E37
+:104E8000B9ABE30A8C9764528213EF054F15FFE626
+:104E900042FD3775A06C68C438E38895FA9D4A8F47
+:104EA000F4009F14276C443AE88D5F8A147E3186A3
+:104EB000F97C2746A6EBDE372D1B95A3B3578CE96B
+:104EC000DB25E413751DC6B040E9F7224329ADDFA9
+:104ED000355DC273DFBFE4FD240DF504D4B761EA8C
+:104EE000F08CE2FC02F2875D248ECEACC89D6AE5B0
+:104EF0001C79EC68F734A4EF69ABC312BE3FC46CF5
+:104F00002619F7A3D34A0BB21669FA69EC98C55073
+:104F10003E99D39809F56E35A4E335DFBD31F7C06E
+:104F2000D4F4FA51EA7B765C3E75DF33F69FA273C8
+:104F3000A43932A719952E2A471974F7D13B513E4F
+:104F4000A3BCFD2D3F4FAA1AED5D8C7CD159C9AA97
+:104F50009E2479D13900DF85FA4FCD1F7A76D1BEF4
+:104F60004CE6FB934429CC5200DE75A35439CBE9BF
+:104F7000F352EB98A5D47F45647EA48B57C68EED83
+:104F8000C4FD56C73D4545F4DE9DDCF50DD255FD0B
+:104F900033A306E13E7DF5287EDFB8FE191EAF5E25
+:104FA000FF8C99E2D5A7A676BDC7F723563B9D1384
+:104FB000433BA4CF8FE123EA9B8431DED5A3A8DD58
+:104FC000A922D467EE3D5F1CC1B843B72D816E7B2B
+:104FD00004CBDDF7921CE9659E97E2438767791A57
+:104FE000EAD9B330058C773DEB7BDAF51ACF7B68D5
+:104FF0005FB89EF39D57E1BF5A856EE729FC674471
+:105000007A2B42BAE3F4561749E6F524CE97731F7C
+:105010004E9203C89711076FB75A207E046411FFA0
+:10502000CD53E83E960F574652A91F951F1F1AED04
+:105030007D9CCBE94E971FE6F53DE06F3C47F7AE10
+:10504000EDE342FEB8347D7C29617C84B14230229C
+:105050007D98211DAFE1678F82EFDA057C1F555BDC
+:10506000EAD8A63D2F6FFF9674FE98527F9E0DF4EE
+:10507000641ADA97890CFD6A35E976F28FDEB2415F
+:10508000A0C7D36E318672D19EBC659595FC608BAE
+:105090000F792725D82FC4D7AC483EB3039C66466A
+:1050A0000653BAA3D4FB0CE2BD3672A3828F7C7E7A
+:1050B0008E67CF52FC75FCFCE7335F49E69D3C4FA1
+:1050C0007E9D6237F7BB198366E75607FADDBC227F
+:1050D000E2F9647F263F44FE24FE5DF5BBA13F0F4D
+:1050E000FD7AEA391ED04DB71F0EF9C79C66D09DD8
+:1050F000275EE08FABE4F6D499ED461EDFDEF1B714
+:105100009178FFF703879BFC723F29F6BE81785D9B
+:105110003623F86B23FAC55B9F7A1D5DF32A1C6B5F
+:10512000C6B16B69FFF3AC81FC82ED2D22BDD709BE
+:105130007FF1D3357145AAFDF002E3F6462C5D2FD1
+:105140008B0C22F8A87A4595D74FAFA1E0E66EB94F
+:105150007D297D73D6F706D1F559A06BDC07C5EA2A
+:105160009B95BB9E20FE813F4FAE4BAB4FF4F41D91
+:105170002BA73BC7BD45726932FAD7E0FB3EB1FDB4
+:105180002134E9C63DFEF55387A1B3BA2767113F25
+:10519000560E1598D8833F51D5C3EAFA5578FC4589
+:1051A000C9FFABC29D54517C397C62253BD51C980C
+:1051B000CE488E42AA95A3C6183B552D4FABF87624
+:1051C000FC61A8D0EF07D479769A54BB89CFFFAFA2
+:1051D0008CDB15EA3855A3670CAD48E77A01C77731
+:1051E00056F0FDDA7F6E5D3DEB0767F7FA2E4F3F15
+:1051F000F457EAABEB53D7A1AEEB4565BD97AB3F98
+:105200002656F077BEBEADFE205F2BCA5B6B129DAB
+:10521000C78FF953D967F7D8518F9825B4233A47E8
+:105220008F9F58A1C1833A2F759E2F29F3063DF316
+:105230003D6D3DB5FC7F4AEFC4F26B2C9FC6F2A5D5
+:10524000CAAFD7DECFF50E437BB007FE8CDA83FD05
+:105250009D8D0CF9959FBBB23CFE0E7B2C9FC6EA40
+:1052600037953EF689DCCF7BACC2BB1AE971D4CF4F
+:1052700007EDFA03C0B5F2A92F9F3A6CBF1C7AFC68
+:10528000BD91F4519D40F68A1952AD3EF2F6C267C7
+:105290000DDF92CFEA95FAAF204ED1CE4A32919DE2
+:1052A00075297A7BA8E2BBD92B97416F0F21BC7A75
+:1052B000B3A73757707B1AE86D73C5BF65D7FC91EC
+:1052C000F613484FB88FBAF6AF4E8A67414060DC9C
+:1052D000D45471ED2F711D5307C51734C23CAF3D37
+:1052E000CFF723A093683F122B8FAB1579ED55F6BE
+:1052F000F37B467BFE88F33B10C7D77BC0D43F8847
+:10530000FD5CAE9D5A9DE663E82FF342AA9543E605
+:10531000EEF704F4780F7D4BBCFFBAE2DBD9A79D12
+:10532000DF51BE807D7AB822BD77FBD469940DEB46
+:10533000A0BEF3253188FEC44BED5FC4CD1CBEDD9D
+:10534000F00A49AABE4F457D0F74F116C9FFEF4818
+:105350001753C7B77F66017C7E5D71F71CF437DE9B
+:1053600088B122E447B8A7CD3D18E50753CF61C8FF
+:10537000CF407C43F9D54726C0FAAE7D8845CF693A
+:105380002C289793BAFD1202D3D6BFF7C819C4A32D
+:10539000372C697F4F26763EEABBD8CC05F5123410
+:1053A000F9D298FC16DE0FEA231EC7A29477EB2BE6
+:1053B000C6F8FB045D93307E61DA2EFE5ECBCD1520
+:1053C0001F9BD0BF32757C787F3F8C2BD8BB768EED
+:1053D0006D0894A3DC8379678FDED816A0376C0341
+:1053E000241FA6B5F3DFD131B7774C72F7C09FD930
+:1053F000A3F57A10FFF03D803A050DE6768161FC59
+:10540000535DA910CCE9E17CBAA7F678EE48ED73BC
+:10541000A87D08E3C92FB7FD4D153DBF7B70955A98
+:105420000FFDD16AFF809B99ED82BB27FF49A152F6
+:10543000BFD36058818F45948F6E6B43BFD344C6F2
+:10544000E9A362F46373B8FF19101DB3DE8BCDD7E7
+:10545000DEC37AEDFAF6A18BC1EB8A0BDA2B785F0B
+:10546000A2A78F8915E7294E766205E868E867A547
+:10547000C7DA828F854C1DAFD2F7CE39EE6C589FBC
+:1054800095E9FC68517AFDF91CA4EF954CFDFE7876
+:105490001BE2DF63E8AECFE97D8FD0DD3E4FA2F7A0
+:1054A00048A8FD8DA37FD1867E37C0077DA7BC7439
+:1054B00011FA6E8FC95770FA8ED235CF137FA25C66
+:1054C0002EE5EF51C4C267D5682EE73E54E2583B43
+:1054D000C771FBB15379BFA67534D7277EA55E404F
+:1054E000C5B3E61D08961DC53353DE89D0AC9BE0DD
+:1054F000342B4D5DF7813953605D9D296CB8007484
+:10550000B271F4736DEB884E3C12EE0724B6BFED1A
+:1055100045902BB314B8B48EFEF311840B2B05D336
+:10552000298DF892F665E65D077BE4AFD917D24B7B
+:1055300000E5DC0A221C6C27B8F17D9515482F3D4B
+:10554000C063FE68BD1F83E6AF6FCFF0FD96CB6FE3
+:10555000AFE0634A0CBE26C7E06B424CBE469F4F8D
+:1055600094B89C4AC41821B09B662D7134F7433B14
+:10557000EF9702497090CB267C8760C7DE8373F07B
+:10558000FDE75744BBB11F7CF9F9DE578F588066A1
+:10559000A7A3BCA2F3F0D7DADC00FF99C8D794FF29
+:1055A000FB1C7712D289AF290BEAFF66EFEB6D1671
+:1055B000A87AF3BA078C18CBFCD4DE436D128EE7C1
+:1055C000FACD7EEC4F6A387C648A7011BA6C8D59C2
+:1055D000C796987C20A6FEC39790DBEB62DAAF8E6D
+:1055E000F9DE1293DF1C935F1FCB17F2A40C94EF2C
+:1055F000EB04FAFDB34BF1C7F3A3553BA0DD85E700
+:105600006E2F8E7EBFAD09DA5CDBC8E9FBE5BDEF2E
+:10561000CFD1D1671A23F95F9DE671F7449F1DBD75
+:10562000C9A3BC58FDC4BF8F8D1F9E84F33B51CCD2
+:10563000ECC82F27ACF6243C2FA0DFB9423C583AE7
+:105640009B2BF07B6529BD0F82F7DBA76AE2279FC2
+:105650007BC04CEB5BB88B9F7F4E887F6C529F3436
+:105660003ADFEBC2F70D96F81E99D4C7157D4F644B
+:10567000D1DB1C1E8BF60841BB40F167FAFBD962F7
+:105680008B48FE8D2D024B053E5CBCF9C27BEB784E
+:105690003E8DEF5A6CE47187177CC7B8CDC6DF9B8F
+:1056A000E48DCE0BEFB31FC57FF4B9F05CF8EC6866
+:1056B0007DBC991A0FAB9E0F7B2FFD3EE357A311C4
+:1056C000DE4A7C5AF77B5252281DE3131B5F482D9C
+:1056D000447AF893815930C4B43B2E56A97F660DA5
+:1056E0008C7025DE8F5F4269F9AE07447CC7FB638F
+:1056F000E19DFF330ADA777D68A0F3D0336B7C64D9
+:10570000847E74C655817EE88FD6F8956002257E2A
+:1057100059899F1DBDAB43EC07B98F761F8F27FFBB
+:10572000341E16E0FEED8C44F473D6F7C5BEF39438
+:105730003750BC958345F69D87716E4D48527EA7C4
+:10574000CF998970FCD3CB46B22355B87D7017A38F
+:10575000F87B75DE8B15BF53C7E3A97BCA71FF12B7
+:105760009F2423D83ED8C9DFF33C6949FAE914F4F1
+:10577000636D999981F7A2161ABB4C4E988F73EFFF
+:10578000747AB7E65DA81722380545B483CA27B3F3
+:1057900099D8AE3C24313BB47B57720A480F1F9D09
+:1057A000004A86FCE9107F6770E1EFF93D6DD62174
+:1057B0006DC57DE1FB5B9E9A86F953DBD39371BC8B
+:1057C0008FB6FF3D03FD5ACB98DC8171B99E319CA9
+:1057D000CF4EEEE4FBC96540AFF87EEFA99DDC9F9C
+:1057E000B80CE8D1225C48DFE37736103D2DCB12B0
+:1057F00019D2F332377F7F6119BEBF60477073FAE9
+:10580000B3C0FF300E2259A1CFE54A7CE9F29D3D9D
+:10581000D367DD6E4E9FB1F41B4BAFB1743A798CF8
+:10582000FE77A52E372EF2CC1A4674A596A7EE72F7
+:1058300008FD98564E78B2503ED0EF8E91DCEEEBDC
+:1058400045FCECEBB63FB89EED1099124FD037FCFB
+:10585000DC45F609513B9AFB291E54CE199F51CEC7
+:1058600087F19CF4891EDAA7BBB9BF68DFD71F3C5C
+:10587000FE1B9443034DE487068AF9A60BE076AC41
+:10588000BFA918E9B15BDE0D34F9D1BEEC30AFC968
+:105890005AA89187FB06667C83E7C2FB32E9172A88
+:1058A000D8BE7B8AA87DA09EBFFBF3CC80F736E1F3
+:1058B000FDC467568AF89267D4CF54C7E3F88D6960
+:1058C000ED090B35F3DB575F44FCA6AEE79C729EF7
+:1058D000F656F61D32D26DC7C0DB3AF17E59205321
+:1058E000A2F99ABFAC91F1FDA0F1784F0BCF9FC701
+:1058F00070B97C24727327C68137D972E878B96988
+:105900000C5F6F53F68D167A7727CD40FB2963C263
+:105910006CD9A4598F3B4DE2F372E8DFD94E1CCB12
+:10592000E9FAF018EE0F78569469DD300FFEBB0FE0
+:105930005FD71CEA84718C0346DA310EE7CB3183E2
+:10594000947B847205C6538C17C3454CE34F9A650C
+:10595000E0EB8ABD9F88EFAC215D373A2492BB9A79
+:10596000FB55168A0BBAC43DC29F8E71F0FB6206CE
+:105970001EC7817F827A8F49C4FD39B707274B3E06
+:10598000E24FF97A1EEF654EB3B8AD89748F698224
+:1059900031257A3FD0D89FAD9C41F2B89D7EDFEF94
+:1059A000B70A1CD57ED57B55E1B57F9C5889F31687
+:1059B000983D95EEF5FD8EE2E9C25E26D835F1748C
+:1059C000074CED13295EAF9609DB34E5D5CAB873F1
+:1059D000457EBF101F56C37B30B1F7DB1AEF4DA0D9
+:1059E000798707D8499EEE1FA39EF7EBEFD985076D
+:1059F000F07B766103B33F29633C838FF605011882
+:105A00007787F6FE9CED777762DC5378ED3DF4BD49
+:105A100011BE63FC5F937A1EB742B9CF00A461CA7E
+:105A200088DE3BAC4E33D17DCA6A68EFC8D7F4F745
+:105A30002DEFE35D704F2E26AFFA19557AB9117923
+:105A4000BD18F9206335F159A685F8E099AFEE3E0F
+:105A500084F7E18E6658C8AFD1CDB7995915F8FED5
+:105A60006F477DEAEA2E0DDF3CF3D59E97F0DDEA25
+:105A7000408654847C3AE6EB6F86E3EF067664A6B4
+:105A800051FD316B4E9F7E3A0DE93A4E16A87EB914
+:105A90001DFD1AA2214CF2827D1547743F3EA92AB2
+:105AA000CBAEE1934F14FA9851E2FE780CA4620653
+:105AB000F0832D2AF7C48C1BBDC8BF8DFD892DD95D
+:105AC0007D4A1C47A312D7A8F6F3A5A247BE54F1FE
+:105AD0002BD9E9BEF9B3C843B88EFB04E21763FAC9
+:105AE000EE04AD1F256E2C1FBF233E89CBABFAD42D
+:105AF0006F709DB5D95E9360D7D613F97B5396240A
+:105B0000E2F70EF3582FF273ADED4623F98560BC32
+:105B10001BF07DE2B1FC1DDDC664BEAF3A6AF0D871
+:105B2000118F6B4ABC33C642F931239FB75BEE4CF1
+:105B3000C0FB10EEDB5293F1FC6A8C228F3A064ACE
+:105B40007EED3E3B47995FCE582EA73A06DE417860
+:105B500053F1D861FE13E1C598713DBD6F3F06E575
+:105B600033E2614DBC13E7DF91C9ED8B8E4CFEFB38
+:105B7000341DF55C3F07922C64F70247135D8CC916
+:105B800094487E7F39C6AE3B6756F1FBACE83BC418
+:105B9000E59785EE4FBE5597FA0DE2C5684C9271B8
+:105BA000FD470D5DC5282FBE1CC3E33E4583278BF3
+:105BB00069FCF63747E5D766D4FBAAFC32E3FD8CD7
+:105BC0007C1D9D9B2EE7FEF3E8B10E45AEF07BA554
+:105BD000DF556EE19F5173DF13E50DAEAB0BE4D2E1
+:105BE000934E6CDF6ED4B657E5CEFF34FFDE1CC398
+:105BF000BF6AB9AADF54B87EAEE41B56FD99C7ADA3
+:105C0000D6F17B43C784F6E7E9BE699999E23BD8B0
+:105C1000BAACFDDAB855E3BD2BE87ECD7D603FE13F
+:105C2000FEFBBEB44593F0775CEEDB62A23CFCB5B4
+:105C3000E0FD90F94AFD77419CE1FB01BF1DCBE3FC
+:105C400032BC27E549F87B4947B267781AD23095CC
+:105C500018D2DB9FFEC5DFB3ADE8EA1C9F847C143D
+:105C600070146AE58BF78C44EFBCD53299DEC73AE5
+:105C70009AE89F8CED1B1F130876C704DF7E2FD296
+:105C800037E4515E8CEAEFAAC27BD2A31AB2098F25
+:105C90004758E754B40F020F1B890E1B8D3EAEDF31
+:105CA00037A552DEBDE5E04B8E34E42B91DEFCA936
+:105CB000B6D4D1B9311B260BF8AE5740D1CBD59213
+:105CC00097DEE10210CA8D80D7178C9DA47F5EA855
+:105CD000055816507C26F9930F1880120BD19FABF4
+:105CE000FC5EAFD29E89BCDFEA227B0EFAB955B9C1
+:105CF0002425BBC85FFCD1EE8523911F8DE9D77B9E
+:105D0000717D1FEF593E12E1F000CA1180DF8696C7
+:105D100007E977CCCCBB1B02085FF57782EAD7DFB7
+:105D2000C7DFFDDA5349F79FCDCA3BEB97EA778B84
+:105D3000229F36B4F2DF1DBA64BF9BF5F1C88D8F88
+:105D40005A2DF85EDD828763CA95F386D8DFB1AD40
+:105D50006ED1E7995B850BDF97F56677C6DACDBF25
+:105D6000196B8B79FFE1E2EDBBE37E0141745EE1EB
+:105D7000BC47C673F5B3407F7CFF74A705E9FE6C92
+:105D8000B681E204405327F4E4470EAFE1FBA515CA
+:105D900063992ECEE8FFA7FF3FC5F4FF0299D441D7
+:105DA00038008000000000001F8B08000000000089
+:105DB000000BD57D7B7C54D5D5E83EE7CC2BC924A0
+:105DC0004C1EE004024E428C012778081183523D9C
+:105DD0007912F280E1210D4A618251828F76A4F618
+:105DE00033B6D89C3C89091F8D088A7EA80382524D
+:105DF0000B18107BA1B5ED109422BEA2558B564B0B
+:105E0000A04A5FB68D583FE9BDB6DCB5D6DE273374
+:105E1000E79044ED77FFB9E1A73BFBECF7DAEBBD88
+:105E2000D7DE91984D3B93CBD87F4B8C9D9FCCD8A0
+:105E3000118535F6FA193B2DB1DA7D6EC67EE1F09B
+:105E4000DDC9D2208D9F28E95087B1DED405898C29
+:105E50008DD164C6AEC072D680F51953672FCA8340
+:105E6000BC0C7937962B8C8D65ECA71FE5CF0E42C5
+:105E7000FEE7E7F267AF847AE7F1E75A1C67E0478D
+:105E8000571630A68F91D94E68DDCA58C533EE68D3
+:105E9000B991DE780DEF4712F3DC88F354703CC8FB
+:105EA000BB18BB5FCCBB2695AD08F82F6CEFD72491
+:105EB0006A3FD0D4C87E7749F47B90310DE739F33F
+:105EC00044A02411D6E74CF3E52BBE68F93F6715D3
+:105ED000676BB03E0DEBE1FA8E2C6599B03EB6765D
+:105EE0000663E9D8AF4CFD06D358B906FD306FC044
+:105EF000BB3031DA7EC7551C3EC6BC8D793216F0F8
+:105F000006A09FDFE2AF57C17FFAF8A0E627B8F3FB
+:105F10003C0E09EB3A8CF9F1985DF8FE07C3ACCB67
+:105F20009A1AF0B84FC047638347CE037C995B0E43
+:105F3000EF846FCB6456CAF2A3F56BC4FE9527CAF3
+:105F40008130F45FF5606427C3FADF8ECBDF9909F7
+:105F50009BE1642B16C0BA96A5442E59E38F6D279A
+:105F600051BBAA1FB010C2A5AA95A7D8CF3677B447
+:105F70007C59316F67E40D3818F3DB719587BEB338
+:105F8000B5A98CCD023014B3DC10B46F75841E1B20
+:105F900040BC68B1B19D69F83DF4E400A62D4E4FB8
+:105FA0002BA40F267C9FCA1B6D2E8F5365EC2EC52C
+:105FB000F30274CEDED232A9BFCF649F5D825F1739
+:105FC000A50D9422BA2A25B226A7218239C3B8AEDC
+:105FD00032C5ED427C3EAB256F73421EB6BC3D021E
+:105FE000F93599697774C194D68B7D7D3061DA83F8
+:105FF000B3619CD617EDCC89BBC66CFA808BF64793
+:106000003A4F74E01B83F00A1C53585726EE9A9DB2
+:10601000CA7DCCD57C3E0B76435FDA8EEDED9A6B74
+:10602000300CF3747A65E6E3EDD979F82FCE17CF0B
+:106030007CB9D1FC5B2C6867881FBAF646F64CC663
+:106040006A6908C61272534CF598B2FE8520F4FBBB
+:10605000A957610AF49BA88E37F50BDD7CC0E7E1F8
+:1060600063380FC07C1BAE37305B620FC3BCAFAB75
+:1060700085F298FE026CED1684A7B7D5E971CE863D
+:10608000F9CEFE98E0669FCDFB19AA9771E63D9682
+:10609000447088B6877537BEF7FAB4E763FAF3142D
+:1060A00025A69D49805FA6B029B8CFADD819EEDFEF
+:1060B0005846F0672CC4023174B249D0E7ED453E32
+:1060C000DA3F65864CF834606793A6235D31CF4490
+:1060D000ACBF2021E5531FEC4F38322F6803FA5B29
+:1060E0007075CA7726C3FA7FA85D17B401FE2C9895
+:1060F00091F26C16E47F1459C4F397A75C61877C16
+:10610000B3B424580AF57B35ED518DC6117827FAC2
+:1061100085EFDBF0FBCC2B823B31656CF066C487EE
+:10612000BF49496A17E24DF6E034A457A3DDC0CF5A
+:10613000264C64724C1EE6A9FA31CFC43A864FDF72
+:10614000D7B4BDC84FACDFA5E0891F23FCEF6CB608
+:10615000311C2F33F82EE53F05FCEE82F9AF79F6BE
+:10616000FD241F8CB71AE108EBF8685E2427027043
+:106170003C96F9CB49C8577FDFC4D46CE06BCFD9CC
+:10618000833FC3FE0DB8FE7E6B6BD255D0DF5FF64A
+:106190002A6A3534BD4D013A45787EAE44AE85EF6E
+:1061A0001559976E47BCFD68DFBA8C3A98FF0B8291
+:1061B0001F7C94C96A11FE1FED738A7A4B772830D1
+:1061C000F6AB4D074DFC739EE09F80698E0579D13B
+:1061D000EFAD52F14B388F953651BEE33A9AF75CEA
+:1061E000774823FE52EB4B5907FB73E34CBEEF4E4F
+:1061F0005B80BE7B71AF66617F3D7C7F7CDFA6EFFD
+:106200001DAB99A76B3AA15780015DCC1774A1A96A
+:10621000E74BB17C5E88A90827D93568237AAC00A2
+:106220001C4A46F4DBEA413C84556D3D9F8A74BFAD
+:106230007603C2750DC0D989F42E8578DEEEF2E8BA
+:106240001EECB4BF63197CFF16D06B17E5B5A41A1A
+:1062500018AF418C07187C7416D4FF0BD01D95879E
+:10626000EDA74D74A67CEE40BCF934E80E29503EF3
+:10627000CF633B1D4B3F8057476741F96D071DB406
+:10628000AFB7F7DA4DE5DF62507F14BAFA4C03BAC4
+:10629000BA0C7E99CEA6235D19FBC1946563100FDD
+:1062A00046DA8FCF9AFAA73D6FA77DF957ECBE006B
+:1062B0001F94912ED73C32793BF2C1358F2CF2D905
+:1062C000101E6373F35966747FD8415942B8AF12F8
+:1062D00073655B53693F6B0E4E603EF875F54189FF
+:1062E000F94024561F4CA57CD2B974CA0380681F9C
+:1062F0006B9E5CE5CD877E3391F0A1DD1F9FF8CDCD
+:106300009DDF8571ABBB61EA1E9A871A81F2B36F7C
+:106310002AAA93401DD862EC13D2838DF9880F2FDF
+:1063200039666761D887B38CEDC1F2B3BAD3A317CE
+:1063300044D7C7B2A11DF23927A79B3185667E9B42
+:10634000AC99F96D6A8599AF8E0D98F9E845B55904
+:10635000A6F2F4E05453F984867C537E62E82A5313
+:10636000FD8B1B8B4DF94CBDD2547F72E74253FE1F
+:10637000929EEB4DF52FDDB2D2543E257C8BA9FCCD
+:10638000B25D6B4CF9BCDEEF9AEA5F7EB0C5543E5D
+:106390003DD2652A9F716CA3297F45FFC3A6FA579A
+:1063A0009ED86E2A9F35F094A9FCEA3FEC37E5BFF2
+:1063B00036F81353FD6BCFF599F245EC2553FD12DA
+:1063C000D7AF4CF932CF6F4CF5E7787F672A9FEB58
+:1063D000FBB3A9BC2AF71353BE46FD3FA6FAFDAC9A
+:1063E000ED12E4933366068345808772C247240723
+:1063F0004F7C4362A980DA678F2DF20451AF13F40A
+:1064000033925E65A5C3068B7CFB94B997CB40FFA6
+:106410004E604F28BFADED87F01350F913C0D795EC
+:10642000855218F9AEECF2391A915FA90E15E538CC
+:10643000FC045CE3A2FC6DBECDD781FC2403E846DE
+:10644000F1C2B74EFB4743FC210B876FF3A0BE6739
+:10645000F0B751F44276C668873AA53EB81CFB6D8A
+:106460006520DF901F6FF5301BCA39990D7601DF6B
+:106470009440C82E033D517AEE97FF90A661AB651C
+:106480001EE43B120BCAE72F437AAD6612D25FAF10
+:1064900044F4FA37FB5AAEAFB5DA98720D80D3CD1B
+:1064A000FBFB26303C05F8B63DCDC350FFBA3DC2DC
+:1064B0007A912F8F298419C5C0335973315BCC3E33
+:1064C000A656784CF9B101AFA9FE45B53E53797A8D
+:1064D00030D7543EA14135E527860A4DF52F6ED4BD
+:1064E0004CF94CBDC2547F7267C094BFA4A7D65468
+:1064F000FFD22D4153F9947083A9FCB25D21533E24
+:10650000AFB7D154FFF283BAA97C7AA4D3543EE347
+:10651000588F297F45FF1653FD2B4F844DE5B30659
+:106520007699CAAFFE43AF29FFB5C183A6FAD79EBD
+:106530008B98F245EC4553FD12D7EBA67C99E71DED
+:1065400053FD39DE53A6F2B9BE3F9ACA6FFB33E85A
+:10655000EB8857A04FEE2C403AFDD854FE59DCA4EE
+:10656000C8F7E0BBB42649950A916EFF61EAEFC116
+:1065700084A45CC49F4616AF3A25D4EF4344577FAA
+:1065800028CA12FA3D1B88837CAB0EF44676E020C5
+:10659000F342FD14F805F50489FD9DF4CD248DF535
+:1065A000223E835E407A8407F404A433832E52E4AF
+:1065B000CC4CB43712A27494717EC697A7A3FF4641
+:1065C000FD0DE6935D1CFC33F2975B7AF7954F80E7
+:1065D0004F0DAE1E07CB423AF18F1900FEF26ADC76
+:1065E000F076E95C17C02D66BC17E37A32F247E11A
+:1065F00043735D1F51FDA17EEDBC5F09161B6B9FB0
+:106600006D68829902BFE96902BA02FD60639387EF
+:10661000F29B9ABC947FA0C947E996A65C4A1F6E7C
+:1066200052A97C6B5321E51F6DD2281F6EAAA0745E
+:106630007B5380BEEF68AAA5FC134D414A773535E0
+:1066400050FA545388CA77837D8DF9BD4D3AA5BD64
+:106650004D9DF47D7F530FE50F346DA1FC8F9BC2E0
+:10666000941E6CDA45E94F9A7AA9FC39D06730FF5D
+:10667000F3A608E5234DC728DFD7D44FF9E79B4E93
+:1066800050FE68D300A5C79AFE40E9F1A6412A7FD3
+:10669000B9E91CE53F12FE87AC62A1BF286EDAFFA4
+:1066A00040F1A5DB518F35BE4FB82A90550CFBD673
+:1066B0009290743B962F64B2AA201FB4F03BEB3E3D
+:1066C000FC49F46F2F66AC00EDBBF139DB5B819FB9
+:1066D00037839A8478D79CE2DB8E364F9E18675DAD
+:1066E0003CD3E3F2096D487F5D85BFF940594B6BA0
+:1066F0003AFA3DA87F7308F83099128087B98487E9
+:106700002F7F257ECE741A676761707631A437BB00
+:10671000430E324F999A83F64D8D3332F6EB30CFDC
+:10672000C1171575BB6FE47EBFD5331798EF28E509
+:106730003FFF6306CAC98A7F29415CFFABF6C45A92
+:10674000F41BCC13EB9C572C9BD2CB66056A10BE76
+:10675000AB7E7E37C9C765775C3206E52DC837B298
+:106760007317309F1DE97711D35EC844BB14ED5FEA
+:10677000C87F9DE9942616069760FBA5A068637EF6
+:1067800040624F7C5BC2F570BCB7CE637931F733A2
+:106790002C2F964D69F9ACC072ECA7FEAA39CB65D7
+:1067A000F8B4F22A1F7D9FC7061FC5797C6B52F093
+:1067B000E484C951FF03C32D00782D3BA6909C06AD
+:1067C000FD9451FE3B5218F95147D1B7B9BC6BE665
+:1067D000FE89BBE27F5B86E503AB016780019C0D10
+:1067E000BDF008EAA1CBA09CDADDC1F367C19E43EE
+:1067F000FEF3591CD487BCB412FE4B1F8EDF0DB8BC
+:10680000C7929D1CA17E3F9BCA18F2B5CBAECC248B
+:10681000B82E43E710F6BB560A73DB3A62C7FEFE9A
+:10682000768587EA7DBF30F8FD62B263C30FCC8006
+:10683000EFAFCAAC9FEC584F3807EDD87532C70799
+:10684000FDB8A2EE0450D83C014D423CDC9A3C1D00
+:10685000FD5F8837683F1C15FB68E0C5373B218D1D
+:10686000E157806F5D08D7BF1EBA3217F1E25B3F78
+:106870009FE5C3FD6DC5FED3A2FD337445C178CA43
+:1068800018FFB62EBE7F34FFC15989E1ED99E4E7C8
+:106890006ADC370C7F7C5AE0D5AB5E7B4598FAE525
+:1068A000746794EF12FBBB4BEC7B4DDF8B13EF82D5
+:1068B0007EBF79CCAE3A71DC82017FAC9F61088FDC
+:1068C0001B1F9F991DB38E6F1D3C45FE3B1BE3F3C1
+:1068D000B2174ED88EF3B4BBDC91D469D171589AFB
+:1068E000EDA3217B2D0BE1C3F9BF81878A2331B84A
+:1068F000CD1D3BFF213AD88BFBB12AA991E8E06C72
+:10690000E8C33B91C8070074111827F898C781782D
+:10691000B892A994D6B300A5AB98EE40BC5FCDC2A7
+:1069200094DECA063A6640FD805E3709E5CBB7D8EB
+:1069300060A917E0775D67F30BA81E2EEAB9AF2CAC
+:106940001DD6BD646BA67D3CA40B76DCD18EEE43D8
+:10695000A0A35FE0F8D7EF2E6A9FE0233A3AA34363
+:10696000BB790AC72F7625EC25E08D92E4223F59AA
+:10697000FD46CE278D751C15FB503E4B3B8AFBBD5B
+:10698000AC8511BE0CFECC49FB37444F85B79E9CAD
+:1069900020A33E08FB8DF8F8B329E166C263AE0F71
+:1069A000DE22E433E6711C3BCA67CA871E43FAB88D
+:1069B00055E7F69ED5DFF7273BF707FE09ECF456BF
+:1069C00015FBDF3D09E7AD031E2913887E68DF1A3A
+:1069D000DF4B24FAFC4CE6FA029B14F4E64F46F82F
+:1069E000E91D687CFE490ECF4C9A4CF2FA34AEE3B6
+:1069F000A817EC5D1C37CDA52A589E1C9EC4E97FC4
+:106A000088FFB3F309C8AC787F1B50CF4D8BEAB930
+:106A100077C54F62682F033C07A5AB49AFA1754905
+:106A2000C5AC17E95A2AFC8F20CE6B6B02F328B352
+:106A300086A3F3A077A682F3555DD83FC89308EAF2
+:106A4000D576D9C5E9DA320F20A35AD4DB9D426F3F
+:106A50003FF6CF5482AB0EE3EF4C8E8EEF2B62BD30
+:106A60000CE02279FE83F4B0ADA087291958FEFD11
+:106A700030CE478A671E9C1FC07917C1713CF3B4A2
+:106A8000260F0747AE5F259570BF6A2B2E95FCD762
+:106A90009E5C0FDAE5B67815E9E4094730B1E40AFF
+:106AA000F45B8D7F24D66E3F967911E5E73938DFA8
+:106AB000639FB76620FF71339F8EF8314F93D42EBA
+:106AC000E20F036D68FF2F004420BF4AA1DD446739
+:106AD000CCE2F701342AC5F60BD1EF03F5B5D96343
+:106AE00068DEF3AAC1AE92D02E7ACF801BD9453F83
+:106AF000107C03E64D7E91BAC59113C964D7B4D01A
+:106B0000BAEA5C6E5D81A5B336B37D65C855D09099
+:106B1000491E3CF9904CFDD34E809D96CC7F65C9B3
+:106B20005BCBFFA84CC3BC8D9D36E69DC9E5F450F8
+:106B30005E1195611DF46932A650CEC7D3CE4B23AA
+:106B4000CBDD2F9BA2DE773AC63FF7A43DD83505B3
+:106B5000E7FD96A2EA00B7278BEA2AEDB8DF0FC956
+:106B60000CFDB017EA15328B98E61BCF22263D2389
+:106B7000C5921F6FA99F65299F6A29CFB7E4AFB25D
+:106B8000D42FB6E42B2DF5175AF2D75BEAAFB494A5
+:106B9000DF62295F63C97FD752BFC552DE6529DF37
+:106BA00068CAE79464093FF2C39676DB2DED74C2A0
+:106BB000A3DD5318EB473CB481C941F2C64578F5D3
+:106BC000F40732E919BDCFF54DFD11E4F70624F2C3
+:106BD00006ECFDE074D765E84FECB5517E916BB9DA
+:106BE000BDCCC7FB1D1847FE3E72AACDEB759D427A
+:106BF000FC7B0EF63F7229EACF2E4AF780DE1F019A
+:106C00001EB90FF47E4C9F01BD1FD3A741EFC7D41F
+:106C1000FFE1C2316C9473A5AF0DCAD17531B41BBD
+:106C2000E3A3EB82FFA61D483195E73F3FDE545EAC
+:106C3000F0729629AF3E37D5547F77A2191E8B1775
+:106C4000CF3095E768FF8C47F9CDAAAF8E7ECF4253
+:106C500038E5D3BCADF8322F165F62F0FB38C04583
+:106C6000BB349A7FE96EA516F941DFFB77B11F03AC
+:106C70007CF71E48D986FCEE697F425B0AB0921F02
+:106C80009570B9BDF7B98D34AF97927AAA701F2E5F
+:106C9000FF40468EC18A9E6311DC37F520233EF902
+:106CA0006C898FEAAB07FB651FCC37EF40FFF820FC
+:106CB000B50B31E493870ECAE116984F5FDE83DD92
+:106CC000D8CF1EE807F5934307F6FB91DF1F723B11
+:106CD0007C8CF805CC0FF8431E0A737E6E52CBFDF8
+:106CE000F5FDE3F1BC350AAF81789C570E7369A5B9
+:106CF000D0BE7736E77B7B23674BA741FF9F68AE0B
+:106D00004146181394DF44BB27C2F16B6FA498C3AC
+:106D1000CDC77C8E99483D0C49969D12F061BAF61C
+:106D20006B3C77BA918390E0A6C3F713804F286B32
+:106D30005F067CC2F4A5BB8F5C4FE739871DBE9D03
+:106D4000C40F87CEC5E4F39763BF36710EC60EE35A
+:106D50003E2C5E6CD763CF9B58B55D37F3775B34C1
+:106D60004FFB189387F6ED6D331CB7219CBC0A735B
+:106D7000AA9C9E5C33A3F87FDC36507A2BC201E4D8
+:106D800007FAF16F8A143BFCA8D730CFC76310967F
+:106D9000EBF979974BF8E9EB230BA9DC539C4BE516
+:106DA0009F9D2A72F8494FF69C6DA6FE63CEB76090
+:106DB0003ECDFBCAA97C6F91EB631CFF906DE0A3F5
+:106DC0007C3EDE9A66186F69D07C4ED69BABB4E3EE
+:106DD0007CF6143A3DB2E7C2F3B23D11999F876D3C
+:106DE00092B65F02F09B673967ABDF64CE9F2BE101
+:106DF000FA577229C7B35A5D2FF3F8D12EEA69F713
+:106E0000E079AB2DACB7407F79B0CFA8D7E5A9AF7B
+:106E10001727E0FA0B24F5121FF612A1FDAA39E894
+:106E2000F1219E141DE4F6CDACE764C25F2BDDBFFB
+:106E30001279231EF164D641C042E85FED7D40C166
+:106E4000BCF4016B1D18855FF486CDF8B9E720D03E
+:106E50000FD43F24E875A4762704FE1DB785DD9E78
+:106E600051FC1F55B90AD34DE72961E2BF4B830995
+:106E70004C8FC1AF1A35D5946FDEE720781F3804E8
+:106E8000F44A74C6CF7566083CDF6D1F906F0778B3
+:106E9000EC9FE5F4B4E0392D9BDE8AF8F6A938E7DB
+:106EA00031ECBF03114EEF07D8808C7A985AE72651
+:106EB0007CCB3F00649144E92927F0E1FC971D2633
+:106EC000BEE754CD799539A27C0BE633CD9237FCE1
+:106ED000D105485BB32E8483D51F7D55A93817BAD9
+:106EE000925D89F8BAC7722E94679C0BF517507F94
+:106EF000BBEFF1290BDD51BF7454FE37133CF7345F
+:106F0000B9246C9F1FF9A3ECCB433E3F20637CC2A6
+:106F10003436D0928076E401A662BC86D19FCFED54
+:106F2000D1BF03DFF71FCCA2F3C4BDC7B21264E820
+:106F3000FFDACF2FEF26BA7973727E178BF6CFFA6E
+:106F4000D3E8FC68C84E42B9057C65FFB18534DFE3
+:106F5000A70FCA64EF3D6D1B8C4F19066F8C7D37F0
+:106F6000F2EA736639D58ABF40FF19A5C1E5A55776
+:106F7000E0FAFB582ACCABA6E00E86F6E9103CDC22
+:106F80000BA95ED5B4B9329E236D9E94B20DED9ED1
+:106F9000968479F2A3904F55210FEDD27485F63F78
+:106FA000AD70D236AE9773BDB16AAA19DFF766BC71
+:106FB000116F4779AD2712BE552599CBABA61DAAF7
+:106FC000C7EF3F5AECF261BFD2B4A5E9484F0F8832
+:106FD000F5BF76604DFC70F475913D943C1A5D5C94
+:106FE0003460631140E6D473192C02FA6E553EC822
+:106FF000F551EA3BCF2954DFC8AF8B1BF0A23FC548
+:10700000E9FDAFDF7C10FB3D23250EE195A3DDE319
+:107010004239BC3763747DC15887917F7048CE3A3E
+:107020007584DFFA5D192467D72D8B2739FB50292A
+:1070300097B3EB016E8CF62344F2D8A9723D7B8F97
+:10704000DA427CE8C1A47E3900E5458087089F1DAF
+:10705000C80701FED332220CF1D3AD06A607A91E44
+:1070600097B7EB3340DE42FBBE6FFCC71494AF7B97
+:10707000BC0E1F8ECB22916399901F3B43666877AD
+:1070800074488CE6A5FFD01DE6728CCBDFB1689307
+:10709000C296AF3FC0C7CF61B7CB3ACAED0C2E47FF
+:1070A00073D8A1FACB703D6F027F6017EEB3CFD3D8
+:1070B000CFF516770AD1C746A19719F033CE5DF701
+:1070C000427FCE183D6563E5535988FF061C37A201
+:1070D0001E07E983CBF6A7E0FAEE57F35FCC46BE76
+:1070E000B4CC4D52AA4CF1DF8BF9F53B6C740EF326
+:1070F000C0A4D0143566DF871B5786FAEB0EF271F9
+:107100005322BE22C4AB54A63663BA45D47F48E8A6
+:107110008FFF25F4C747507F84FC96605F05EA2FF8
+:10712000696F290CFD443E75E0DE4B11BE5B64B512
+:107130008B5D880F467FDBC53AC2D81FE4D3EB7561
+:1071400009D7F9A8E877DDC1AC1617AEAB1E58A376
+:107150000FE739BB0FF37B3B193F0FD65519D79F6C
+:10716000D9C6289DD4E891797BDEEF0ED1CFDE031E
+:107170001CEF776E5A998CE5698D6E0DE355B2EF71
+:107180002B6DC6F3FE076C368A97D9F94025E51FAB
+:1071900074D9E8FC39AD515581B9819ECCE19ED6B8
+:1071A000A8A9D8EE51B1FE3DA2FF9CFEBF343B71B1
+:1071B0009E3D8CECD64907027D38BF690707A56064
+:1071C0000C5DEC11EB7E5AC031A77FE20D88679F02
+:1071D0001E70B3AE51EC3C83AF4D3B205BF466B305
+:1071E000DEDDC9B85C00FEF6BF4B817EFC95FDB2CA
+:1071F0000BEC496769847C5843FCCDB790EA19F8D9
+:10720000D69ACDF5DC6C56589145F89B2A115F163D
+:10721000F146DDCCF86931F1D756B19E3143FC4ED1
+:1072200075219CEF15F0B7E9AA6B32D22DD0039EE1
+:10723000CFB7243C4AFC0FCF2CF19CB5F89A06D668
+:10724000897499CDF58DF5D97D2EC4C736016FE9C6
+:107250009A2DDE01E8AFDD16708DC6E7EC5B389F36
+:1072600053CE4D223EA7B3A08EF4ADA4F1FD7066BF
+:10727000A83AFA111C3E1BC55F282C462F45FAD6AA
+:1072800099CF364E1C196599CA49EE8E013581E0B9
+:10729000349111FF60CA5A86EBFA14F469C49B0456
+:1072A000F7CDD58827CC6FB3C457A90CFD1A4E660D
+:1072B000FB20B63F25FBCC7B58DFEEB599E2AD1441
+:1072C000B6FE63B4D7942F88A3BAA24C9C330BB9F3
+:1072D0006EC873E64B31C94F238D9E33EBC457A75D
+:1072E000BA0AC94E59E763449F18669109EBD9AEB3
+:1072F000CB44BF619DCBDBF5425E5AFB33F6DDC864
+:107300002B065EA9F9541F7EE273A1BF9EB75249B6
+:10731000BE1FEE94C9CFBB4ECBA178921CD6D89994
+:107320000BF90E3D4B36C97F8B9F212792D8857C68
+:10733000799DCEF9329025F5DBF1A6A2B6209FCE3D
+:1073400068710D27771E15F3DB25F0F02541AF9D01
+:10735000BE85A39EE71BEB32EA29605EABC3F46FE8
+:10736000739BF58A9C63DF18339C3FD948B70A7C2E
+:1073700036EA65D82212F69B21E2478D7A1343E65E
+:107380007EEF2CE3FEE5EC126D4DD9D8283E298D19
+:107390008E07501E2BF794CA8FA6E13E72FA713207
+:1073A0005F7C16870FC99F8BEFB9B313E1D7E9E66E
+:1073B000FBFAD8DA3B5DB1F2DF0AEF8B27CA22CEA7
+:1073C000F485ACC336840323FED0E9E5F643AB97DE
+:1073D000F3D156A0F3E1E8D1DA5F6786D15F64E5C7
+:1073E000E16C90BB9D2B89DE8DF9FA58C885FC664F
+:1073F000BB6AA3FD052DA507F182C1FC518F1C9925
+:107400001F8EEE8FDA5166F85F46F74BE5F48FBEBC
+:107410006F5F344E583F2B11FFC6780674FAA95C93
+:10742000AE4F815FD7A644FBB9B8D1BCAF063F9F32
+:107430001236F3EF6A7FAA296FD523B359EE41F4D0
+:107440009BEEE9E57C8DD50E54A2BEC1DEE6FBFDC8
+:1074500034361CC62ED823E8C0C8EF85FE46E3A705
+:10746000D3B6B8898FEEB5B38312E8634C03D56504
+:107470001CFA4D1919EF8F55048F223EFACF4D2378
+:10748000BE2B1D3C4AF120004FF2EF7FAAF2732978
+:10749000363BC0F9660DE4113EBD8BA8BCE33BCC86
+:1074A00043795B783CE2F36E411FC63C776746AE9A
+:1074B00047BD6EEF4F7F2BC7C685FFBA8C9FE7E4B1
+:1074C000B992B4F030747942943B6D4C8FC773D548
+:1074D000E7383FF4328F03F7F90BFDB9B5915A9CA9
+:1074E0001F93651EFF6259F71E4CD371FD810FCBB0
+:1074F000306E59E5EB5E1F08E8A83F054161625711
+:10750000439D031C0FFC2C40EBAD53F9FA5F53175E
+:1075100052DE0DF0704EC7F92C13718FCCE34CC7BF
+:107520007E781C64F056E6413FFD85F3E478330431
+:107530005701C7D754995D8372D4EBE0766CAE5A8D
+:107540004BFD8EB08E4D621D1F5404FE45EB70F353
+:1075500075FC00D094FC0F490E8AC7CD2809DACA01
+:10756000898E98A6403F3F58E2233B8EF90312FADA
+:107570009D582065587C8BD28F806BAE362A5C5B21
+:1075800093C6B33A28FFC19A248AC388995F4A39BF
+:10759000C6C1BABB02245FC578CC1D213F456B3BF9
+:1075A0008F97FAA27D8DEA2741572C1DB507B9FCAC
+:1075B0006B95821528FFF4B738DFD928C687B969DB
+:1075C000788ED3B1CF4BE35CC8172411B76FE60BAD
+:1075D000DE58BE437E85FFB7FEF015E599E2FC61FB
+:1075E00074BFB8E26041BA9F50C1EDD91C56EB8A16
+:1075F0008DFF8CAE87EB75513F22875347DA4A9255
+:10760000AF1D5E2E0F59C5F0FBBD4ED0AFA1F7B533
+:107610000A79DBE16D61B1FC71243C716598F55A22
+:1076200003CFE3B3E34D7CD30676536C3DB0D3D4A4
+:1076300008DF37EE77C01FC8D7AF4EDF4678CAD80D
+:107640006D09806727059E19E319FAD0F2726E67FB
+:107650001EAAD496239E75D8835E94CB8EFEDBE55E
+:10766000F761DEF6B714D3BE8FA42FAC13FA7C6B90
+:107670005CA036300C5F5DB7DFD110CBAFF472EE9B
+:10768000B7D3C5F830358A736DCFE0F692E20904BE
+:10769000506E2B20075B7D238F6FD5435C19667876
+:1076A0007DD5F8C5C5E5667FD1D565811684CBEE5D
+:1076B0007D3359ECFEF7483C0E7C247A475F89F015
+:1076C000B37423FFF017F7CB9386B343DC8BA99EEB
+:1076D0006187DC9F9B42F72EEE17FBD81DF26C43AF
+:1076E000BDA33B57E678D4E0D9C662FC2C137026C4
+:1076F000D0EF4578D209F3ED10FBF198D88FF50261
+:107700000FDBC439C786268DBE6F6BAAA0F491A685
+:1077100020A58F373550DAE13DADA1DDF05F60C8BF
+:1077200060BC4F526456318E9B52CD3C71308FD429
+:10773000AD033AF241168AA7F885CEA610B54BA93B
+:10774000E0F3DDDA10F738AE7D77B943E0557077B6
+:1077500039D1291BB0031EAE30709469E348EED9CD
+:1077600079BB84526E5714F943CC03FD27BDA91091
+:107770001F4FF287F1501494DE5DEC56A8B701C696
+:1077800041B92F55F4EA03746EC9FD95E3047E37C1
+:10779000EF7BC21BEB27EA86E6FD48FF36358E9F5E
+:1077A0008BA8F7A2DD9250C1F5E98D1529CDE82708
+:1077B0007014811D0376D191F57DE40FBEBF90FB5F
+:1077C0004512726F6EBE11CA5F4D5718C6E3253061
+:1077D000FF61ACEF55D8A0B310E1229F42FF664A8B
+:1077E000ADD98F39E94E87090F932D7ECC04E63051
+:1077F0009DC77C553C7DCB82A70CF107F123570E2A
+:1078000013FCA3E721C4BF1C1AF7BB6DF47379B155
+:10781000A162BFADB880F08CCE430C7EE09822F31D
+:107820007E0AE5303F77E92D5D09ED2A35179D3F4A
+:1078300067B35D36D4AFBBC53D80E8B95D98F8E568
+:1078400009C1075B250E67439E38C279246F36FA5B
+:107850003C44DFBBE7E6C74931FB84FEEB5878A127
+:10786000DFDAC40FD7C7F03D906B5DFED1FD6D5DD3
+:1078700016FBAC0BE6379ABE179EC3F5E5F82D0E46
+:10788000D2FB5CE7C6519A13F91AADA34BD813BBD0
+:10789000ED6A1CF2B7FB73B3E262ED88CCD966FEE9
+:1078A000BDB162743BAB53C0C9A8E7B2E96CB8F98B
+:1078B000C5F9BE9A9D75AF58B7512FCED643FDC6B8
+:1078C000D9CC76567CB679BE97CEE17C58F17E72E3
+:1078D000E907C3C479669704B3E78C8DB177BD8F90
+:1078E000FEE603800FFBFC3CF90587CEEDD12E832D
+:1078F000EFD903531E26FE95CB7C886FF1AE63EF64
+:10790000A29DB301E10874B77B16879FFDDA01865B
+:10791000FE556B3F2C5736EDB78F855DC82F36E689
+:1079200072FBEB97DE2C09E93CA902083C11F943F4
+:10793000642EE94385CC83F89F54D1AB61DCD22F10
+:10794000ABB793BEB9D12DCBC84F5EAE4E213E7AB8
+:107950007F2EF7F375E466DD9B8D785A2FAB782C7C
+:10796000E0621CDEB44EE4C3D5FB5D785E35A179E0
+:10797000CCCDC80F2BE7F0FB96DD2877FC51BCEF90
+:10798000F61A794E6F8BE678A8DE86EAED9DD8FF71
+:10799000849B64E24F32EB257F71879FFBF1E33ECE
+:1079A000FF9B6B1CA4470BF7BBCE503B85F0306EA2
+:1079B0006D2FB5DB502F338C4F78A9302B0ED7BBF2
+:1079C000B17A7F328EE76089242F361672BFEBEED4
+:1079D000B90B497FEB6EE0E7E1DD856B221887F498
+:1079E00069909F76E2F5922294E718670453731624
+:1079F0002C267DD353EC0A61CCB9C3773BEB2840EE
+:107A0000BAE2FDD933CC78B77B4A1FEDDFFD5E1BB0
+:107A1000ADE3FE42CE273FAD70F8501E39581CF141
+:107A200097FB3D8CDA3F54FD46C5649A8F4CE31FAB
+:107A3000719F3D8CFEC1FB97318A3F73EBE6FE1DC3
+:107A4000B3B647B2859E24669C54338E583FFDC41E
+:107A500057F7E9F538DFF10AC37349E3DC6A43BA43
+:107A6000716E65B6539DAC2E9225FC53B85E5B21BA
+:107A7000F737D9D0BF94144307AA994F5F1C34F34A
+:107A80007187856FDB2C7CDBD0931C5FA02719FEF0
+:107A90003C434F6AB3F7929E04F28BF0739DE299D8
+:107AA0004EF622D0693AF4674BC920FD2D3CC7D071
+:107AB0008F428528FFEE473E0CF071D4B4D0FA0116
+:107AC0005E21CF287AA5DDF305FA91476769334532
+:107AD0007C9F0F53DB19B41F3A31D6D524477A095E
+:107AE000AF7D2CC87492C31C4FBA2BB613FE77150A
+:107AF000727ECCDC69C3EAC71342C3DBFFE90DE643
+:107B0000F95C1434C74DDC27EEB3E6E93686F8F3AA
+:107B100060C26FFB907E9F7916E473E617DF7F3DAE
+:107B2000FC2CC7933DEFF3B82D58CDBBB741FEB346
+:107B3000FD0EE2E7AD89FDD723FF79CAAE4E980E60
+:107B4000E933AF3C31BE0ED6F3FC1CEE777A46C467
+:107B50001958D7736C0EB7B341BF393687EB371F4F
+:107B60002931FA4DBD14BE84F858AD7A43ACDDF727
+:107B70005845F055AA6FB1FFA497B9FDE9501631E9
+:107B8000B4A3F3C08EDE4E4154218A07CB6B10F7AD
+:107B9000FC5C01E25F79D53EF22F38857D3DE94EF0
+:107BA000E669063DF2F692E0BBD4BF6D8D86E7DC58
+:107BB000FEEF8EA1FB5E807D5391EFB85990F0B53A
+:107BC000EE4D8EAF8EFE89748FA6D7882FB3D88FD7
+:107BD000C67AF70AB9B24FE0EFDECC7EF24FEC7F07
+:107BE000C9EC9FF8DB1CB37F025AC9686FEDFDC971
+:107BF000F1F8BA61E4F59F2BEAFE3627C69FEEEF57
+:107C000055953AC2B301D243F0CE3BF94966AB7405
+:107C10002FDCA8D7FBF2E8E778971F34E35BFEF38D
+:107C200016BC1F8A1F0C4818C7FE5272C814B7FC36
+:107C30004578955061D89F8CF0EBAE5BE3B61BF1B5
+:107C40006F647FBD7F19C1F7506520A182D773C9CA
+:107C500033A3F83114BF62D45F3D65BBB0D7DC32CB
+:107C6000E291C4F122A54232ECB314ECE7C0AAE0E1
+:107C7000D80AB427A6BE3215FDF455D35E1C1F7B6F
+:107C8000BE62D81556789455707CAEBC217CC04E2F
+:107C9000F830AEFE65E0A3955F0FFFDD0EFB7E774B
+:107CA00045727D1BD06DA553A67BF5A163B377E824
+:107CB000D0CF069C07E4E71C9B5A8FF9EB4BB5C964
+:107CC00038FE6FCBB4EC0AF28B94525CBE01C791C4
+:107CD000F6C31A975F8AF682E99C98DBDB78BE8C44
+:107CE000E7CD60D785F11CB8C33DFA3E7758FC7AE2
+:107CF0001DD0CF687A5E5C79F06B386FC79624F23E
+:107D0000DBD9CEE5909E175D470FC5937ED975DC14
+:107D10005EA295713864D07D5AE37BC9B4B97218FC
+:107D2000FD266EEEE7FDA27528E7AE369D3B2B42A1
+:107D30005F63A577DD75D74C716E1F737FEEBA0A4E
+:107D4000A1AF9DBB86DAFD4FE1D86E81E30572C419
+:107D50001EF08C06D7CFCA820D889FF60103AED9DC
+:107D600094FEBB7035F0A3B74CBB83D3CFBF8767FE
+:107D700065D80FB743CB041DDEA6C4D061FD943D8A
+:107D800097201D01BD0FBDABD04A72E6FB44FF8DAD
+:107D9000BAD383E7A14957F3F8663FC6EB7A880E5A
+:107DA0003B70DFEF522253715F767FADF17216C3E5
+:107DB0002FF398EA453D66FDB1793BF0BEBDE21870
+:107DC000506D942FDB5181E70136E0C740AC497319
+:107DD000067A8FA03D9DEA207BBA6D2EF72BB41555
+:107DE00071FEB059D0FF83159CAF3E24F67D5DB97E
+:107DF000B609D703F8F708CE231DF3906E12EBFDFA
+:107E0000EF52731ED6BF49ACBF538A9553B376D396
+:107E1000FAADF8CB1A857FD5E0BF8CE79D19C2AFCC
+:107E20002DE4375E45BA2A855256960F2C2B574FB4
+:107E30004439E3AC5B342CBE59E3535C7E335FDEE4
+:107E40003CCEC0639DF48D6C6D35E9FD9DDED1EDBA
+:107E5000BDE34DE6F80A639C2A5BAF0DF1B6EA9CE0
+:107E6000CD445FD6B4E88E675DA85F7787AE18759E
+:107E70009C934DAEFE523BC505526A2D0FDAD938A0
+:107E8000F49FBDD7F9ECB0E772C1B571FDA5B1F1B2
+:107E900038FE3524E706D62AC427BA33D8ABF8EE25
+:107EA0004BF7EB0AC5537627727C609F3F7302ED58
+:107EB000F0A03F688A27C0F8448C43FC4D05B71BEF
+:107EC0004AFCBD0CFD2209FAC7768CFF3855E1A3A8
+:107ED000FD5FB1567204211F6C4B7668BC3F265182
+:107EE0007FA05748D86ED08EEB5FA1EFA3B8910466
+:107EF000C863FD159D99BCBE787760659B628A1F3B
+:107F000053F005188CCFC7176348EFD6298D43F877
+:107F10002BD17D006B9EDB75AC9F8D66BF3E1379C8
+:107F200091E2441920FFEF86F163372F89273CEC5B
+:107F3000BA5B127AFF40FB4A3C2F28740A3D87FB4C
+:107F400083EAF15758FA6647A81FE38EBA9AED0CF8
+:107F5000FD4BCB597507C2D13B4161E8BF613DFC88
+:107F60009D0117FCC3713275F3BB0441CBBB03CB3E
+:107F7000594C39EA4FC2CFE79C2BFC31F92C1FE951
+:107F8000C7B78CDBABCE29422FF60EAF1727887808
+:107F9000232B5D74FB57C6C7FA0F7A34D98578F264
+:107FA0000918C268DF6E76E83AEA6D1D99B6500B83
+:107FB000EA6D224E61A55837FCAFA30EEAAF1071EF
+:107FC0007A57FF41665ACCBABE3618CFB4987DBCFA
+:107FD000F65C8A295FC42698EA97B8269BCACB3CF0
+:107FE0009799CAE7786798F2737D579BEABB80A0A0
+:107FF000051C79BC019328DE809AC8A672EE0FEBAF
+:10800000E4719E1AFCC37D49D106ED18CFBB4CBC70
+:108010001763E0414726B7FF5658E2055299AEA3D1
+:108020007D7B03E04504EADF1032C78DBA841DE88A
+:10803000B2C42518FB5934D7125F30C2FE45F90D82
+:10804000C7CF91F9178FF3CCF1FD27D9FFB05F6F40
+:108050006743DD72B15FE58B1B287EC2712E996983
+:10806000880FCF5DF9740E949708F8386C41F2E3ED
+:1080700038CEA551F9E62C99DEE9F9C4CBC84FE713
+:1080800070ADEFC7F5389825AEC3C7E33A307C032F
+:10809000F97C4C39AD17EC013A4FAF003CC47EE798
+:1080A0009C939806FA9063317FCF867939DC0CFA7D
+:1080B0002811F05A553659C2F6737CE6F7721C2225
+:1080C0007EC361D98FFB1887EB6D56B8967EB9F3E6
+:1080D000B344795B3DDA1BEB972915B1E7086FCC08
+:1080E000E572F12E915EB80F9E24BE0F7149B8CE95
+:1080F00053FAA251F97BE5B9C9A40F0EC9952F888F
+:10810000BBAD14FAE3E624F37839AC22B90CF6E7F8
+:10811000DDC512F1EB530D93C9FFF94935BFBF908F
+:1081200083FE58C8BFAB717FECA906A5EC26A8FF5B
+:1081300077C057F27F8C14870E0B8CC4DC6F182924
+:108140000EDD1AAFFE4571E86CB125EEFC2BC6A121
+:10815000BB985ADE0EEB9927F8CD4B773F9E8FF1F7
+:1081600086FAAC4495DE35B2C499B7B73D5E8DF85A
+:10817000FB5E03F061E207E6B8F2F76C03A52F405F
+:108180007FEF83298271E49F9D5AD031B380E2D082
+:108190003FC638746B5C797D4349C74CB4B335EF47
+:1081A000598A6B2FFDE0A3FC34BA17B506E5C2FB74
+:1081B000B98BA8FD6F35D7C7E891B2C69D1BED3DC1
+:1081C000B287B76783B6A990BF49CB1DA4F68D4788
+:1081D000288E4BDF2A53DCF817C5A5BF29F0B1560E
+:1081E0000F57E33ED7E62A2C2C45E3D247D28BAC7F
+:1081F00071DCD6F8EDF6B9DCAF6807FB604C0AC657
+:10820000B7075663FF756B251FBE3F57A7269723F9
+:10821000AB32E2DB8BD64AC42797B74974AEB47948
+:10822000C9537A0BF2515D2139B27C6DB2A310F2C1
+:10823000D7DFC92F615D1F92481FB9A15109A373F0
+:1082400042BA8DB70F1648DBD0B41F890E06C2069E
+:10825000FE471251EF3B6EEB4FBC12DA1D5FAB20B5
+:1082600045B2938D33BE549CBB91FF77E3D973180D
+:108270003FE7786931A7ABB75B027FC4FB08F7BE65
+:10828000AA30BCDF7D1D0BD07D60C6724F6D00BE75
+:108290005334FDEF47CEA7A1BEC3F589EB7217B6E5
+:1082A0005F81E5AECC7D898007FD382F27729580F0
+:1082B0001DEF87C5CFB6137E27F8B791FCADF4D973
+:1082C00042788F219E59F8AEE0EF43F7F25C9C0FA5
+:1082D000C70B7A5ECC7A6DA80F5506074BDBA19FC2
+:1082E0004540373E733F9C3FDBB5B2EFA03E18746C
+:1082F0008774C0C3AAFAC1C338DF85B952189F0674
+:1083000063020F65F88774E5665AD966288F177E71
+:10831000C2EEDC6D1AF2952ABC6FA1D27D13139EBA
+:1083200056698F333C7765D0FF2550BEB0DA5C1EAE
+:108330006FA193A995FC9CC49093DDFE8514AF8139
+:10834000F11C78BEFDD202683206527BAFB707F04F
+:10835000E0B5BCF2C3A89FB937CB743FC55F29F421
+:10836000243FF37F15B9EAFC46A4390EFDC9CC358C
+:108370008076EDBB7730E29F4B75298CAE98927A70
+:1083800089F2198DFC1EFAC5217614FDBF4B415FA1
+:108390009803E3663444CAF8F91FD70F0D3D69E925
+:1083A0006D403FA827841C3E7C22AF79C954C72A60
+:1083B000C8BF930E7C09F5AA4EB37E087A84493F64
+:1083C0005C5EFF7B929317EA895CBFB0EA8BF10297
+:1083D0006E3595420E0EE98B3D89A42FDE34BA7CB2
+:1083E00032E2E84E5ADE1B5B619C2763F018C51F22
+:1083F000F6B2857948EF3F71C5FAE78C38C39757D5
+:10840000059757C69CE724F83D0E7AEF27F74BEA0D
+:108410003943F28E25F2FB567F70A35ED35FC8ED21
+:10842000BE6839FCDF4DCDDE407A5828E06E433817
+:10843000CC8A9ED3E5B00619AF3E74E772BFF2E670
+:10844000A9DC5FD1B585F99C632E9C47BF6857A610
+:10845000BCF732EE73FF9B0ABD4368ADD7557EB5BE
+:10846000DDE746B9C8E1B628326BA26F18FBE3E539
+:10847000F23FDB7CB0FE799143DCFEB1F57A63E339
+:108480001E5F15F3E89EF50CC373A5D7A771BC4911
+:108490002874FAF05CFC627F7F1BDA5D197E5FFB5B
+:1084A000B7610BAA919E01EF261648A4B757F95958
+:1084B00098E3D74F886FBC027A3BF91199452F0E8C
+:1084C000039F9889DF19E97D31E5228EA697ECA7F5
+:1084D00084028E779847FAAD01FA457AEFCFED4FD7
+:1084E000C3FB4FAC82D3712EFC8BF5E31A698D85EB
+:1084F000AEAB5433DD2758F4E28B3FFF4527D2DF84
+:108500002B407F787FB91BF61DC7E92F78C685F60B
+:1085100061206F651FEE032B720D5C0274F32B7BE1
+:10852000AF6B31D6CF93C735C37EBF328597F71770
+:10853000B9CE201FFA55D195137DB1E7F40FB16B79
+:1085400082A09774E7FDD87B7322B60FF621DFD0A7
+:10855000FF39C6B11363C7CA7F343133A6FEF4CAEC
+:10856000A20388BF74A901F07DAA239C355C9CAA54
+:1085700081AFD7F7FD90FC61E8F78E1B458E9D1605
+:10858000787242F8B9EB3A93CBB561FBE574747D30
+:108590000EA3F70DEAEFB33B62FDDBEF54723FCD64
+:1085A000907C5CCB2AD08EAF3F1CE7C889C1BF3717
+:1085B0002AF9796230984CEF2C58C7395569D66B37
+:1085C000EB9B9903D7198CA43B104FEBEABF5CBB24
+:1085D000EBA78A791E4E776426C6D6E37EE1BAF50C
+:1085E000C3F763C499683B8A1D88EF71E29D82FFDF
+:1085F000B4FBA85F17D32217A1FED4C3EF0F45F534
+:108600006EEE8774A99ABC09F1228DBFB3DA9196F8
+:108610004F74ED8AAC96310ED601DF87DB8FF542C1
+:10862000EE76813E8B7A81DB1621FBC77DCE4176CB
+:108630008A23374CF138F1E7C691BDD2B7E416F280
+:10864000DF18FD8FB4BF0F083DA35DF42B55713FBC
+:10865000FE385B504AF647ED2C978BF3D38B6C2199
+:10866000FA0E3FEEB1317EB38B6ACDF6F4A14A0E1D
+:108670000F475A8AE97B7D6678A74CEF1DB95BF0FE
+:10868000FD013C5F453DA3CBBF527EB700E33514EF
+:108690001167C12464DD8152AEB718FC714160706E
+:1086A00031DA852F097EB779EAE8F2C11AF710EFBF
+:1086B000DFA60DB7AFBE2ABEEF092A2F5F80CF8C91
+:1086C000C5C4EB665671BFE3021BC0221FF883903E
+:1086D0002FD59678EDA9A21F233D54199C5AC5FDAC
+:1086E0008C11CF30E76186BE159FCBF52D48CBEEC0
+:1086F000443E0AFC0BF528C0D6B24D0551FDC5EB32
+:108700000F13BF5C047A16F2D3AFAA675DA04F3196
+:10871000D0B7B07FE39D4A8BFE142835F3C1746057
+:10872000DBA83F2D147E840BF5236EEF5AF5A4B918
+:1087300055663B3787BD1220BF552E7F0F77F3D488
+:10874000B387F1FDE14F412EA09E7D3C7791498F8B
+:108750003AEE0FDBC8EF26F85BBF655F2B3585CEA1
+:10876000D78E83BEE501B974DC1ECEB80FF6272D77
+:10877000F7EB956081B2E3539E74D711DE864D7E90
+:10878000A5D7728F784EC1F727B6ECD0111F751F91
+:10879000233B214EE82547B6F8B6229F67BA574AD1
+:1087A000BA0612B1AF39EC67E4C7D83C6D743FAC80
+:1087B00031CFB3155A03E2C1887A0ACC0BDF8306A6
+:1087C0007BC4B512F26B04BE0DC9E355C1355531FA
+:1087D000F9F85CAE9F809C9884FA655F9EA3363C56
+:1087E0000C5E776FE9253905C8702A6952F4FB13CE
+:1087F0005B6C7F41F9A3FB1D32C679B06CAE277567
+:10880000FF303703D7D397F87856AC3C32F8FB8D5E
+:10881000955A7315C66354692D55C4EFC4B98C6855
+:10882000BFC4C69EB7A75C380FA3FD1D73C57BBA36
+:10883000D95CAFBA57622D78BEABD729145FEC5321
+:10884000431EB44B4FBE3999E2629CF7CC18230FFC
+:10885000B32E432E3D2CE084F6512C9FA951134C8E
+:10886000FEB6F985A9A6FC8DCC47EFE6C4F8A712A1
+:10887000853E2C23BDDD7B0F3F0F3EB196DB69713A
+:1088800097AEB70747D9E713F7F0F389B823FFB0DE
+:10889000A33C83B4DD8B766E67DD4C90116C4F1575
+:1088A000976B4BCF25107F36DA3D5BE5E3763108D9
+:1088B0004CEC7FE9B9242A8F6B1DB4A35C5B11B922
+:1088C00097FCD64BCFC5119F8F6BD55F401361C509
+:1088D0007A4905880E9547DBBBA9DE8D9DE6F83108
+:1088E000831FC34FC01D7BDE73C9EE9BF09DAB2180
+:1088F000FDB34AFB19EEAF2F97C7E538F3B8DE6931
+:10890000D09D75DDAEDC784B9CAE3E740E8CEF9E38
+:10891000E0710BE7E7FAF3886F73515ED2FB2EE745
+:10892000CFE3B993A1FF32D6D386FEA0398C851E42
+:108930000614A9C8B61BEF9D887EA11AF45786BFFE
+:10894000C05CCB5CDF6E4B2BA0B8C3500AFAAD33D2
+:10895000ECF47ECAF9F3CC761ED6C3D286DABF1603
+:10896000EB2FF721CAC23C5EF3F3B89CD55A2FDD3A
+:10897000035B0DFC34ECA177875EC1A5DEC25C838E
+:1089800011C897C8EA9BF82E16DEA7C0F328C3CEFD
+:108990006B4EFC7D466C5CE5CD9B14131C96DF99F9
+:1089A0006082FF7501F33D8E86AD134CF932CF64C2
+:1089B000537E8EF73253FBB93EF37B178B2AAE36CC
+:1089C000D5BF406F66DC9F3C92DE9C549D2CF42109
+:1089D0007519C2A3CC9F43F7FD0DBF7985807985BA
+:1089E0007F890DDFAD3B8AEF44A01F48F8370D3F6C
+:1089F00074C9AE7D2457CA2CFA714221D7C74B7671
+:108A000058F5686E075AF5E9C46A73FCE6C5205844
+:108A1000697EC24E32E68378847A7019CA2BF5C219
+:108A2000F9007ADB0A507E629C937AE1BC6ED9B57C
+:108A30004F477BA404E417DE2BF8B2F3FBB2767940
+:108A400051761DE9D547BCFCFCEA48F67DA5299086
+:108A5000EF4BE37ECE3E6F893B05FDD4805F0CF08B
+:108A60004B4A6B76A35FEE857489E2C00C7BD8E835
+:108A7000B74FE87D6F80FE8D690E9BE246B9837625
+:108A80007B598CFDD837299481FCE297E9D3DBD060
+:108A9000E5F3ABC4E919C3E97D47E266F078C1C3E9
+:108AA000B36CC8374A6C211BDE039EE39B6C43BD4D
+:108AB000E78F62BC392EEEE72AF171BDA46407F797
+:108AC00027AC7649611FFC3A373BB36D3C941FF9E4
+:108AD000A184CFBDB1D51146F5B13C0CF58FD8C3FB
+:108AE000A41F1F85F28D905FE85D679B1E8B471565
+:108AF000DC6F10807FB86FB7ECB09F8EF59B17A727
+:108B000071FCA9B0F8118A857E516CF97E5DB5596A
+:108B1000BFF0B110C1E9F90C6E7F8F64C7F709F996
+:108B2000FC6761DF7C28E2C3DF17F1E16FE23B38CD
+:108B300097E2BBE9FC1D9CE79B54CA1F6D2AA4F475
+:108B400018C68FD3FE54506AE081D1FF0689395090
+:108B50000EE8F748741F61C84FE49AB13E00BFFEAB
+:108B60004AD0E10AE197EC2BCCA5F88417AAB46FA0
+:108B7000568F1D19DFFEDDF47958EFE961CE698764
+:108B8000CA1DEC9B78AE90CDB40C8C3B3FE9BE3453
+:108B900025368EEF57D55CDE1EB9CE8823E771707F
+:108BA000DD6B9FE1A93F7FD438DF84F022924F2311
+:108BB0009577CBE2EF83286EBA6FFF7E9E7FBB1264
+:108BC00033FE23D566BD2821B284FAFB46E76292C4
+:108BD0009B0F549BFD483DDA7EC2DB4F822C84EF15
+:108BE0000B8F382FD18F95EEFE2CE8EE43611F21BD
+:108BF0005E608A7881DF112F308F788179C40B4CC9
+:108C0000112FF03BE205A6279B6A29DD20ABAF655B
+:108C1000491C6F513E46CF27B97C237E0D7AC92D62
+:108C2000FA7D472F825FEB7A4687575DC7DD5E94FA
+:108C3000FBEBA4CCA378BE7772413C9D0FAC8CBEFD
+:108C40001736ECFB620996F7C490930CE947E2BD36
+:108C50002C2DA6FEC9C3DC0F146C541E888D87868C
+:108C6000B1490F0D8AFBA7FF53FC3C69C1CF2FCB45
+:108C700077B3AB83BFAE263ADA175161BFE76AFC20
+:108C8000FE42825FB7213E8EA8777B0DFF20737076
+:108C9000FD3B3E69A53BB67FC33FE8E3F248CC27E6
+:108CA000A827D3BA7BB416BAC7F609BE070B5D7501
+:108CB000304EDFD678C6234BC6333C67BF3794A40B
+:108CC000A29F2B1B4FB2D2F01E2E8F1FB9D7B79287
+:108CD000DF93D458081F8B738497103E4B9E255406
+:108CE000CF3551F46BC49DA82C8871282E8C9342EB
+:108CF00006BC89C741C236EA148FD2A8537F785781
+:108D000008E5BA0BE3A24C715D9AFC55E28F98F727
+:108D1000CB9D4BB6897B4043EFE7F9BEDAFB798404
+:108D200072B80EB087D13FB2D9C1DF03ED98226D82
+:108D3000C777B10C7D20C09BB2CA5CA91DE5EBEBE7
+:108D4000D31D3E859F83B7231D1C4FE7EF3FBD2EEC
+:108D5000F1FEF474FEF7441CB95CAE18FA2E7AAA40
+:108D6000E9DC02FD8568FF6A167D029920C6016A6A
+:108D7000367AAFA7D2A21758CFD1ADE7BC06FE4CCA
+:108D8000A9117CC9F0F38FA04F5BE169C4397CEA7B
+:108D900065241752B420D9FFCB84BE9ACA7A4DE716
+:108DA0006718D710AB27625C43AC9E88710DB17910
+:108DB0008C6B88AD8F710D66BDD4AC87625C8359B6
+:108DC0002FBDDA121F6EF1473069D4F376639D39F7
+:108DD000BE57689F36A571BD7CF3C285DA4DC8B712
+:108DE000F1FC97E239D8DBA897260A7AD259BF86D8
+:108DF000E744E9437A20F7735C24C61987E7F780D4
+:108E0000EF69E2FCDE881F30FC20CE40408D403F01
+:108E10009BA49E6DF8AEEA26BB968E70DC2449A614
+:108E20007B6CE9CCAC575F649D7F81CD140F60F8FB
+:108E30003D8C780067ADF93D07BB053F6EA8914DAD
+:108E40007EC91CDF7F52BCD8E69533C4BB75B0FA2F
+:108E5000183D5EA9E3F64A2DEC3FBE2765CC739919
+:108E60008857B801D71BC38763F47E1BCEBF36A3D8
+:108E700057E371F64C771AEF78209E4BBD6C1CFAC5
+:108E8000839927F36180E74335DC5F6BB4B7316FBB
+:108E900033DF4F95E2FF826D0AF115925D3172ABBF
+:108EA000D5BDB013EF85ACC06799A561FCF57AED2F
+:108EB000D1D8B81C29B65CA1F73EE9DC3C41EC6B8B
+:108EC0005DA7399E02FA35E51316F37B0C563AB4CA
+:108ED000EAF136180CC7FF5F354CC01BE829E65C89
+:108EE00021BA7EE67B5835AD7B1BC7D3FFBFD73D8C
+:108EF00064978B79AF10FBFE767CE0D1B130EEEF5A
+:108F000024276B83F495C4C1171A611D67F02D7770
+:108F1000BC2FB0F9EB8F225DFEEE5E27E3F165BE5C
+:108F2000E577433EB8C949FE99E518290FF33F5E3E
+:108F300093497095136653FD152D8904870F377F6C
+:108F40009687F2F7ED94E072C4BB0FEDEA248CB380
+:108F50003BD99227E3F9FCDBF103F4AEF0199979E0
+:108F600030BEFFEDDADFD9D10FF78ECAD4587D0DB0
+:108F7000D6AFC7AED33B8FEB81D7CBDC8F0FDBB93E
+:108F800013CFA93FB869B2CCDF89E5F81D94F8FE8C
+:108F90002E98C7FDFFC186D576922FA560438C22FF
+:108FA000CF60BEDF1CEEDEEE4431EEDB1983DF481E
+:108FB0004D43B8314F0BC14FFDED5DE84F0338D144
+:108FC0003BD6788104BE3B268CDFC6E3E07DB46EE1
+:108FD0004713CC0F40F5971ADECF49AC8BEDBCF1AF
+:108FE000FC5D295B307749225FA714B34FB02FEDAA
+:108FF00057209C24E6DB0F74BFA2E7F7746EFF2CAA
+:10900000C00DE5C83B9EC1F6C390FF10808DE7E21E
+:109010002BBC7FA277C3BF9D0F3B9E8E719666F8D7
+:10902000CD9A9742F0F870D3FD8974CEE96141C7BB
+:1090300038FA3B77345E70FDFFBA0BEF5F0419E737
+:10904000772E111763C5DBA5B05F688F7BE259CF20
+:10905000181827A1E1C3B26ACC174B836366215E5F
+:109060000F94215E1B71774B1BCDF8DAEA3E5B86CD
+:109070007CBE5ED8E3F57E33BF849FF578FE17E4AF
+:10908000BF5F80EF2B98BBE38A82E8FD532B9DBC2A
+:10909000D3B0732CE7A31CFFDF4EE1FB72A6450A99
+:1090A0006FA77DD126C5C65F9E127C0F37CC1E03ED
+:1090B000FF15629D00889EE274827F5935C21FD6DB
+:1090C00049FAA005BE009732944FC6FDAC0BD7BD40
+:1090D0005F5F02E5F5424F75B3413BDAAB5FB4FE2B
+:1090E000158B1D1D88E7AFE23BD28517C2E39D8635
+:1090F0004FEDA81F5C5FE70E61DC94151E1761A0A1
+:1091000014ECFBE9898335A905F4771B3DDBD1CE4F
+:10911000DB54528EF9771013C85F1C70703F0390B8
+:10912000F7CC285EE085AF7428BF8979884F1A781C
+:109130003304A74E6739DED7FADE8D6E26C3FC8274
+:10914000DEAB56513C80814F1638213FB219FE48A4
+:1091500085E2164DF2D58A6F32CE9FF62748F81F6A
+:109160002C15F1D736D8C761DE31A0FD1E0FFBFAF2
+:109170004AD22A7D36EAE1F171E87A6E7D99FFFDE7
+:10918000A86CD0E848BF04BD1BF569E33D1BA3BD37
+:109190002D6CB60B2FBC97C0DF0332EE1D0CB58BC8
+:1091A00070BBCDDEB96058FBCDA6F0BF83D87E780A
+:1091B00029CBCAC3795DE53A4D78CAF5459B53ED95
+:1091C000C4FB8BEC357E5F98A5B9D9EF0CB8009C39
+:1091D0006DA9B3BDC8575BE3CCF7EE9B049F6B133F
+:1091E0007CCA36868F73A17EC9F57145F895A3DFD9
+:1091F000C3FC3BAC0BF52145F89315A1478D5CCF23
+:1092000046E58AC5BF7D613DEEDFF6956A05FB0A3E
+:10921000F0DEB4D383F180FD71EC75BC4F69DC8F57
+:1092200036EEBF2E157861E40D79EB29D30EE0BE42
+:109230009DD69CA9F81EC05271DF91C645FF238BB5
+:1092400037E5978AF7378CFC4FE6E58838ECF1A6CE
+:10925000EFA06F4FDC877698DF918AC31A71B50350
+:1092600075DC0FD66DD7DB313E4C2F720DE239FC29
+:10927000F3790EE682F20565373DCEE3F68264AF00
+:1092800024087CDAECE865F8779B4E8BF742E127FF
+:10929000A9681CE91984FBC1D2B11D286F918121F5
+:1092A0009F708417939D56ACB3F2C5C837457C6F49
+:1092B000B0CD1C675382710ED06E39D82D780EB7A1
+:1092C0007CADB9BCD612679360C91BFC10F5F2D90E
+:1092D0002917EE979137E6D3A371BF8E613759F105
+:1092E000E92BF875E83D19AB5FE7C4BCD1FD3AAF97
+:1092F000CF33C793FFBB7E1DA57391093F8D7B675D
+:10930000479654CAE1343C2FCFDA1EFBCEED5FC442
+:10931000BC7E22FC3FCFA1FFC789EF6673FF4F449D
+:10932000F87FFA84FFE779F4FF907F50137EA00A5C
+:109330004A8D73F86BFFB998C5FAC73C73837F9960
+:1093400017036FFBB91C9ADF06035EC2FEECD1F86F
+:109350003BC09FA899F4F716F007FD4755862E4AA3
+:109360003C02EC53BF4FDCBB6B36F45C7A479EEC9F
+:109370009E4C9EF51971E6404755B3ABE93DFA2A7C
+:10938000D57CDE92906B8FFA8B189EF3D82CE73148
+:10939000A3FB8BC6280B285E4811FEA2F6C3AB19AF
+:1093A000C619295E95D6AF58FC455DC2EFF365ED51
+:1093B000E25FCCD352E6237FAB09A4CDC775BA7563
+:1093C0008A036A4B2E5F8A78F18024FE3E8FF55E19
+:1093D00069E00C7F9763320BA5A23FC5EDD1F13C4C
+:1093E0005BF1D9483F19E9DE86715F038608CBB48B
+:1093F0005E8DC68BDE9BE4F7B9DAC5DF0D6647E20A
+:1094000048CE3840CEE0F99FF1CEAC232D40F10597
+:10941000CC2DDEC5B3A9EAC261DFDFE1FB573B2FEC
+:10942000A0E2FA94C862C2E3AA1A6D3AAE7B085F62
+:1094300087EED38D1EE7D12EF0F25A7B90A1BFDFCD
+:109440006EDCA75375163B7EC97C8EEF672A03D767
+:10945000E2388E73D9342EC0B92816CE17DC8F6A45
+:10946000FBE94F7F3A93DF7B4278D9411E221E9F52
+:10947000A90CCEC576463F381EB687FEAA46EB0F2E
+:10948000DA05E6C7F0038757A7789A0DC2BF64AC28
+:10949000FF814016BD1FF84060219D13AF982F99A2
+:1094A000F85794AECC727B68FDCFFFF5AF7F05FC1B
+:1094B00068C781E5187B633EB7CBED42AEFFDA119A
+:1094C000BA1DF5A95B5F7B6E551AECDBAFD1874502
+:1094D0007F6FF9E74FE27EFE006DC898BFC7DC26BC
+:1094E00089723DF264039E1FCB46FEF82ACD1FBD54
+:1094F000477ADF6BC757E9E83F75A9C77C80B78912
+:10950000B9FCFD2986FE8D027C0F52C46514C4F897
+:109510009DB22E8CAFB0C68BDBC57D05ABBFE146DF
+:109520000C0C01B87E6FBEF9BCC4F87EA83278E39B
+:109530007CAEFF7A2F19265EC5A81713D744EFC853
+:10954000C4C922AE69A14C7E36DC8FD1E222DAC5D5
+:10955000DF1718DADFA1FB1CD9246F3658DE13DAC7
+:109560002CF6D5480DFE68ED37797EF166C42BC028
+:10957000AF07691D23F18562467C4072737F132A11
+:10958000B26887D8C5DFD7C28700902F38045F182C
+:10959000851F88BF7362E50741E2075D517E407217
+:1095A000CFB52C218CF191C639902B57E7FC40F8B0
+:1095B000A147E67B9C1F00FDEFC3F5D5CC0F3C43D4
+:1095C000EB53F97D952FEB27473ECBE73397E20628
+:1095D000168BF18DF930EF624A0F0B3EC002634DDE
+:1095E000F7CE9E10FB7F64BEDB248F9F98EF31F98E
+:1095F000C7D9A6D0A8EFCD3D26EEE1491947FF21F6
+:1096000025A19FBB23C0922E9CB74BE81B5D555AEA
+:109610003FAEDB4AFFEFB4F1BF47FB4EDB22A2FFB8
+:1096200093F3CD7A8491D60A3FF950DEF87BC36D6F
+:109630004F3DF514F0AD1338AF98B8D093F3B91D82
+:10964000582BFCE639E147427D30DE897AFE7768A7
+:1096500036AF1C3EEEEC9D7BF8FCF01C03CF07E31D
+:109660008E3C44F1207F9BCFEF232E5D2BF1BFFF7B
+:10967000EE2BF882FDE2FBFD19C2FB0A8AFBB02348
+:10968000DFAEC538477CB75097280EF3CBF663F0B2
+:10969000AF7FCE3FCFF957BCC1AFE21B703E063F54
+:1096A0003B3F3F6117DE6BBFAD46FB17E2D7C1F909
+:1096B000DA7992B32512D911FF17A17C379B00806C
+:1096C000000000001F8B080000000000000BE57D7B
+:1096D0000B7C54D599F8B9F34E66920C098F414131
+:1096E0006FC2C311079CF01210E586248A40CAE4B9
+:1096F0004198BCC80441431A746CB1655D2B373C7A
+:10970000624CAC46572AB5AF01818288468B96BA27
+:10971000FDDB11D0B22DD4442D06151B7C06DA7565
+:10972000E3A35DB64BCB7EDF77CECDDC7B3321DA96
+:10973000F6DFDDFDFFA7BF7A39F79C7B1EDFF9DE80
+:10974000DF774E988BC5D974C61CD5176F6BCD6665
+:10975000EC3CFEE631961592189BC1D8A637587D91
+:109760004720F15E7BA669F5CFF17AE6837E8663BA
+:109770003F576C37F663A17636A714C57636377F28
+:109780006AF517897EB4A7634CF45F9995B1A22559
+:10979000CA45A1118CED5AA29C5F02CFF34B600C1D
+:1097A00078FE646184CAF02BF0CC64AC96F1DF4A99
+:1097B0002936818D63EC8905CAC521E827A5964520
+:1097C0003B3CF0FC318B3E9D64FEE3713CE827A5F9
+:1097D00094B733D74FC17943FDC1F2064B0BACEBC5
+:1097E000C4266BCC998DCF69192C497FDAD371D6F9
+:1097F000CD942C5DD916615E0FBE4FA7F7291616C2
+:10980000C1F1EEB318E11A15EBAF15F36A57A6666E
+:109810004492CC4B7BBA63A54C9936787D9BE89FEC
+:10982000593DB42F272707B65B75FBB2488CD3DFB1
+:109830005FBC9CFAAB6929A3791686D2867FE08645
+:10984000EFA7B2A9E7AD389FA719E2C9A71116B5CE
+:10985000E65E605EA29F43E5A929E361DCEE4E6B04
+:10986000D009DD8C678FA485D206B67F6EBD97A91F
+:109870009731F6D3F53EA642C3E7D7CBF48CAFF7CA
+:10988000D3FB83EB83543EBC7E16955F5AAF50F9F1
+:10989000C8FA05F49CF7A74D4533615EA99D56664D
+:1098A0009507F6DF10920DEB4C3D3B85A9303FD973
+:1098B000E34DC7F93837E75F703F7FBA9E8979B9C2
+:1098C000C4BCBCF43C28E67B18E74BF3E2F3DDB5FF
+:1098D00020720BE2EDB567E35609E6E5969982F052
+:1098E0009A7BCD46C50B70F0DEA0DC1A22FCED9110
+:1098F000439319BBC7C2E9465DEE8EED842D29B4B2
+:109900007A0E5A116E2BC76D477CEB5E599A610136
+:109910003C50057E98E7D70AF38B5FA6DBF7C93783
+:109920006DB0C0B893E6B31E6B90B189FEBE3C9695
+:10993000CE58EEC2888AE34EF433C5994EEF153601
+:1099400005E6BBD5B62006FD9FD8AA7E2F05C665C5
+:10995000AA4F4ABF16EAD9D8F46280CF6E41BF5BE6
+:109960009A4B2F08A74E318F4F16286D487FBF594D
+:109970007F80BD3B21510F74AA20DEC300AC04D60A
+:10998000BDA5BCD5B502FADB62C2C3A33747B68416
+:10999000746597EC7544A0DDA96FB34B5806C0639E
+:1099A000B3331C4B328F535BBDF7D1FC997C2AFD3E
+:1099B00092C47B58DF9A5908DF4D4ECB04AC0E445D
+:1099C00058318C7F6A4FCB58E6C1F565D2F8DDABD4
+:1099D0001ECD9103C4771EC5F933193E1A3DF87A9E
+:1099E000711DC43F043DD30F3E49BFDA6FE07F478E
+:1099F000C5FA347A871FD1C57DBF1A37B59525BE04
+:109A00005BECCFDEDE2A25DAE34F190974CA743F16
+:109A1000E077A9F8CCE64519EA5DF88F71F89F8EDA
+:109A2000C387A01F772835DA0A88B6286867EFF859
+:109A300079BBF3F07FB71FCAAE44D9E5B719EA196D
+:109A40002B618A56B6E27F2B99E24A9433AC4D6380
+:109A500083C8C7D659BFF51ED04FF70BDFB6CB0072
+:109A600047C7CA3A16A1F70E7AAFC7CB77EC8CDDA1
+:109A7000B8503986FB99B248F915C2F5070B94978F
+:109A800009FFD7A935B8EE8DCC126C9D8E8B65B2CF
+:109A900017D623D1C218BBED86C8EBD4EE212FFB1D
+:109AA0001AD67F253DD80AF82C799B4388CFB6A2D9
+:109AB000D009DA278FCA908E19ABF67E70057EAF7B
+:109AC00058CE03DF726047A3891E7F43E35BDA83CE
+:109AD0004D12C2AB83A17C39BAC44B78CD7C30899E
+:109AE000D989F6250B9E62886F20D7402831BED1D8
+:109AF0002E925BFD6517AC779EA3336001BACEED65
+:109B0000FAC16EDB358037E3447BF55BBB15F87E2D
+:109B10005EA155B47F70B76263ECB843D7DF2CC643
+:109B20005EEEB389F27DF5F5E3617F9453055E98AF
+:109B3000D2F950DB6E17ECAFB5C222EAEFE955A0BF
+:109B40007E8E5FD9ED867A77F146FF3DC3707C65E6
+:109B5000771A8CFFDB3DDBEA8F8CC672DFC5AF4224
+:109B6000B9BDF848BD2B05E79B17F502BC9E2DDE5D
+:109B700051EF82FA63397CFC5D5DBBEAD5B9B8FE72
+:109B800090548CF00DB507910FC17821A4AB39C06A
+:109B90001FF4F495596C257C7417DB095EF3EC71A6
+:109BA0002BEEDBBC6CA6A8308F3C3FDB6481FD7ADA
+:109BB00079EEA12C84DBB16246EDA0FF34EA3F0CC4
+:109BC000FDA70DFC2EB558A676E6EFE1BBE1C5B8C2
+:109BD0002F65FCBB39889373F8BA9B6C54EFA3FADA
+:109BE00028AFFF922DB77D02C025B36BFD6E4F7677
+:109BF000A2BDA36B737DD3786A7F09B5EFE0ED87D3
+:109C000086B3F17B4DBF39CAD8027C3E344C0D87F8
+:109C1000E0A91673FDC0FC64AC2F0BC739EEE8F366
+:109C20002C81755EA1AEDB5D9042F3B892E071804D
+:109C3000C35BC38FF15D5FAB57F9BAA6D13CEBF9BB
+:109C40003C07E33B7FE953C3CFC95DB7D7AB1CCE1D
+:109C500079345E359F8F861FB95D6B77AB63107F5C
+:109C60003EB62AC84FAD4CDD0978B578DA9F2ED6BE
+:109C7000EB23DBC47A8FE5A8F5088F547F1FEDAF87
+:109C800022CB4CAF1F3C5FCCE516D2B465A6E057A3
+:109C900032978B8867302F833EF89CE8F7A0781EB8
+:109CA00077F0FE01655DD6A91C4F56C03CAA44BDA5
+:109CB000F65D3F3DA9EF10BDCDCB7D97F6B9AEEB7C
+:109CC000A0699F9FEFC57A6D9FEBBB0E68787223EA
+:109CD000C163087AB813E901DADD86F440EBEF2BB3
+:109CE00045BDA8E5CF36B69D9817C773585FB03508
+:109CF00017E1029C0DEAF3026C9B5EFF9A17E828BD
+:109D000047F9ABA397AFEAE9E58BF61B457A1A3121
+:109D1000B07FE8F7AE64F4745BF17E8D9E3650FD43
+:109D20007EBEEEC1F077303AF8BED807F353EB476A
+:109D3000A3CF3BBB3A767BA4A4707F90D61DE1E312
+:109D40000FC5B7982FC2B01DC8E9ADC549F0AA44E8
+:109D5000E6FD83C6BB1BE959C3FBB2E253BB550FFB
+:109D60008DD7A65F6F1BC27F44C23ED1F05983E3FB
+:109D7000B3623D45028FE1FBDD34DF951C9E49F067
+:109D80007AA8F13BE87B4177F3988D299909FA1A73
+:109D90006AFD0F8B7DB6E5F3F9B231204FD0EEF2BC
+:109DA000C9DB487F5812FA29F52FF8A336FEC1E225
+:109DB000C7EAC5F8713D9F292AE67210F0C926F856
+:109DC0006F999E4F9525F0F3E7F45EF0D12F4A5F2F
+:109DD0009A9C1D4A9F72C48BC97E68662CA9FEE5B9
+:109DE000B0727B8DF9A6523DD819A43F75F9C69380
+:109DF000BE3C9EA5125DB4F965D2A76C99BE6339CD
+:109E000050FFFA2BE32CA4D6B0265ACFB3A09F283C
+:109E1000A0BF1F00BD1E9F688728C20E51841DA2CF
+:109E2000083B4411768822EC1045D8218AB043F0D3
+:109E300069B53FA5640D273CF0D27EC4CB681D8E6A
+:109E4000187FA69E9D4976872B1063A86732F9C8B4
+:109E5000612BE83B6E8137C7AEF4DA155857B1DC99
+:109E6000C1A2F03C158AFCBB1EBF438CFF8A83E372
+:109E70005E447909BF9FA68E4CD8BF3F59C8F18276
+:109E8000F93209CE9A3D9C802F3B68457BC46F898F
+:109E9000215C9C973FADA640F9F70AEB6141ACEE1F
+:109EA00050517F76DD09BA1BEA195B5595F432C033
+:109EB000A4741F632F943F47ED3B01079D415C074E
+:109EC000182E3A7D72227315ED443B59B630D46B8F
+:109ED0005B56DE68E9447B51B1C648A9B3852E9F25
+:109EE0000EE57B5EB1527D377EA8C38737713F2E6A
+:109EF000E37604DA5563A2717B32FBB7EBE04FD611
+:109F0000EC477BAFDEE94D812557ADED6841789C8C
+:109F10005CFB28E9A15D935495017E968F6B1F0B26
+:109F200018C9DA6C2A43BDD5B5F6470AC2F7F886D8
+:109F300076D23BDB2AD32CC8571376C2E18DBF46BD
+:109F40003BC16BC999101C386E5D09D7CBDF7861B6
+:109F50004F0BC2A95372F5E073D263AE1AE2D3ABD2
+:109F60009C5EE4C3272E7F702C8E535E9556F3358E
+:109F7000A86FCD83F730BFCE3D2EB25B3AF3EEF63D
+:109F8000DDA4E32FE5E31C51B4BFBA726E2AC47E90
+:109F90005217041D29A81FF93BBF6981EF8FAF9DA0
+:109FA000968578DB92BDCB7723B6BBE9F5A2ABA053
+:109FB0009D2B6C9D096C19ECA37682D3A5B2AAF6F1
+:109FC00040BF078A22D79400DE54445F28447BCDEB
+:109FD000D5F8D466B4732E3D773FCDFB0473F5B44A
+:109FE000E2BCB237B8F07DCBCA8D2E9C6F287B8542
+:109FF00005E984E5B97A905FB7289B5D13E1FD44DC
+:10A00000D9527773FA4078B47C9B5D1BB912E7D5BF
+:10A01000ECBB290DD779B36505C2EF4F190EFCDEF5
+:10A02000DC3E2CE03769D24DCF60BB49390EAF041E
+:10A0300070699154DF0A588F5A9116DCC9067EF771
+:10A040005409E7BB556BE376F423803D477CA5AE0E
+:10A05000246B8F0A7CE5786607F1EB721B73D933AA
+:10A0600013DFE52ECCAB2EA1F176915D577E45B383
+:10A070004FC6F566DF3403E1D52271BEF8D42B93C9
+:10A08000F6205FFC64416825B687757D13E104689E
+:10A09000DCC3AE1DDC8E3D01F6A83723F1FE3B2567
+:10A0A0005C4E001E84C99E0E3C487CC76C8FB681F6
+:10A0B0003D8AFE0A7525D8A348C7C80B74FEB7139E
+:10A0C0007B5A7C8CECD0E2DB711F5BF2B85DFABF8F
+:10A0D00000EFEEFDEFC0BB89F21FD647D269BD8409
+:10A0E00017E192CBF6A03EAD809D17223FC373AE21
+:10A0F000647CE4E8CD91ED257AFF5780FB19705F11
+:10A10000D995897D347F77626BFB3707F3337CCE3B
+:10A110007DEDD0EFEBED255CBEB248D6E7F237DC43
+:10A120006751A63F85E3AC707A915E42C26E950B93
+:10A13000A29D76947BCA3809C7FBA5A0376F216C16
+:10A1400031E2CD6B56EC81B173D01FC89308FEDBB2
+:10A150009A28931CD2C98B08E3FC9DCAD9589F6AE0
+:10A16000284758268BFBF5F51719CADD76752CE2C2
+:10A17000A1FA8C2BB813E101DFBAA03CF9A2E98F58
+:10A18000B6EAF8EE67250E5A7F9390E3DD9359CC3B
+:10A1900009F5EEC8551BF3603DBF92589F340B275D
+:10A1A000A7A4E7CD2490924CDCE208527D779EABC9
+:10A1B0006F8397EAAD38DE953E902FC0BFA775DA62
+:10A1C000DEE9D1C9A77C97DD5076B373169447BEFC
+:10A1D0007C579F13FABF92E9DAD37A8CE50F4B8C48
+:10A1E000FED0C1F882CC7AD2D0BFD4B9AE3443828B
+:10A1F000F21F4B2C49FD764F087F5907E81F71402D
+:10A20000DDA741FFC0F27ED03FB09C5ACAF1A25BED
+:10A210006261D4F30ED7DD5C487A4511939CC3701C
+:10A22000B93368DFBB44FF8D45BCFDE7C07BA97433
+:10A23000C640BCC779A35E87F3BE909F6FA87933F1
+:10A2400065C4E7D2F3E69DCB203F18E065B0350941
+:10A25000DF4F8CD722C66BA7E7D3EBB78AF1623406
+:10A260009ED6EE19C54A7ECC82AC7FF66507F4E334
+:10A270006D20B8B4D9018E1ED417175A62386E609B
+:10A28000EAA3A82FC233C30AED2F2F7518ECA77EBF
+:10A29000F89CB51AFCF9CF96703DCB6DEB20BFBE94
+:10A2A000FBAC83EA9F127651A2FF9CED5AFF164F3A
+:10A2B00042EFFC4BFB4FB7B61765717BDCBB73BA43
+:10A2C00050FA909EFCDE18D27B97D0A75CCCEB4076
+:10A2D000BA5E5C9A4DFD84596C02E8CCCCBA2ADF98
+:10A2E000938B7180FDB65C94BBFBD222BE10F47FD1
+:10A2F00070B4632CF2EFCE9F442EF55E20DE001B7F
+:10A30000EBB3F868D491E239DC427419B760D9DC58
+:10A31000BE73FF6B2390BFED7BC64544AB8EB6C4C6
+:10A3200026640F6CD756CAF9D4E467F613BEB64557
+:10A33000BA48CE5487AD41641B9D6BB7D881158157
+:10A340007EB7A5D087FD344AC42E4FAE7D95E4EB91
+:10A3500089FD365C1EABB9FD4692633537441C124D
+:10A36000D8C7F5A52309DECD8A95E0D4BC76DA2ED0
+:10A37000D4436B6E5F9586F8DEECE1FCB979AD14E1
+:10A38000433DF084F26A9AACC39BFA52AE77ECB3C9
+:10A3900073FA33CFFB5D517F1CF73D09DC0E14CD02
+:10A3A0006F443AAB913AD350BF6E2E3DB0DA361BB4
+:10A3B000E1D1EBC7F2F31FECDE538074CC3A2B7182
+:10A3C0001E93417EE13E76E6394FE27CF7AD72CADC
+:10A3D0005618E2E0AA1FFB7A102EB83F17A0CB2F29
+:10A3E000BC3FCAAB2310DE079ABA2ADB601E296580
+:10A3F000EE06DBE50057984F1BF0D3E2D243ABD11A
+:10A400008F789F85EB49F7976634A09E0404467CBD
+:10A4100027DDA92C5E94643F13722A79DCF0923216
+:10A420000EB7A1E25B8E58F105E35BCDD87F92EFCA
+:10A43000BF27F625A354F96E29CCE39E2F293FC0F0
+:10A440007D78B644F93E3EB5F2F11CAE37B282D209
+:10A4500021F815E71FA1B8B7196DFB7D92FAA23B51
+:10A46000C9BA3B051E00DE972C82FDAB999C3315C3
+:10A47000E94CABCF10EB6E16ED34FA8DACCBA67871
+:10A4800001306017FAF7499E03CC4B34FC4A8DEC3F
+:10A49000237B658A43D90EED4201C7755896D0CE0D
+:10A4A0008479875C1E07EA6BAE5C16748E463BD1DE
+:10A4B000A60AB965390F8D4E970EA3FD68F67D4249
+:10A4C000785F29E21595175968FCDFACBC6C3B77C7
+:10A4D000BA83D9857A00FE3B8731BB98AFBB7EB586
+:10A4E0001DDBB102C6E6CFA676B27DA4B047A15D62
+:10A4F000C86771A03E0FB36F9F8FE3AF745EB7184C
+:10A50000CACFCC97FA707E6EC5AEF6E8E20CB53EC7
+:10A51000CB759B01DFBD17595906E065AD6A7F4FCA
+:10A520005FBFD1F3CEE672F8BE5A71F561FCCA8303
+:10A53000F20CE452F53A68A793DFF0BBD7A6B38BD1
+:10A54000DD658ECDD93A7DC1E5B719DAFFA6FE19D2
+:10A550001687FACA3A4F14E90FE665A82F29E57E57
+:10A56000108D0FC1EF9BD9E86F53AC5E944FF5A5EA
+:10A5700032D57746A534D41B52057F723736A9CC25
+:10A5800033345C22876D04C75019D012C211E1A286
+:10A590008D9F33345C3CAC87E0E206B8A07EB3D13B
+:10A5A000F3B4B20AE1340BF47CEFD0F031C3C3CD85
+:10A5B0003C9B717DA02E91FE6386C7298407E24DE6
+:10A5C000FDCE11A80FBC84EB27BF5E84D6E1067CCC
+:10A5D0006845FE656B1F8BFB7352C83F56308DE894
+:10A5E000092035A238891F5B93838D45A1616523BE
+:10A5F000C86E8BDB32137C65703AE47C65BEC28822
+:10A600006FCFF75A633140D17CA634E27CF2BD6E45
+:10A61000169706E75F4CFDF99EF805F88DF6043EA7
+:10A62000310EE735187FD8596A8C576AF39A18713A
+:10A63000113DB5D64B248FF7FA417F86F2A76318F8
+:10A64000F93F0AADD52DE87F395D6F674E4E6F2D0E
+:10A6500048EFE5627F5A6634BD9D8976A76409A2FA
+:10A66000DDB9FCACC4FD60938BA95F06FA9DF56271
+:10A670008C5BB7A7133F186363A847877D9F5EF67F
+:10A680001E804E9D1FE272F66BCCBB11F6A586C5EF
+:10A69000EDA8CF57B1685A3ECC27C5B6760DEA056E
+:10A6A000A9AEBB66AC80EEEEDE76F33375F0744E89
+:10A6B0009E9A81F8BBCCDAF7DA42C0AB8AF0F71A7F
+:10A6C000BD2007D22D6AD17880A3651953D7C2D295
+:10A6D000EE93FACA0AA0FE97BF9EF8D826A8EF2EDE
+:10A6E0007887E4D83FBE71E31A672ED6733817BD5A
+:10A6F000F63EC9090DEE474FB99FC27218E3863086
+:10A700004FCDDED0E2966111070847242EA74FB047
+:10A71000ED1E0E1F8A7F66E1BF61FECF2FE570CF71
+:10A720009ABB6A638FF04B5DEAE3FD59A1BF7AA241
+:10A7300040FA8F84FA6F56B739BEC9E3A564E7A023
+:10A740007D513649BA683AE17F3413E5E4021BC50E
+:10A7500047CF9F67B6F338F740FFF72F237D0E856D
+:10A76000377FABE783EB79DC74D07A87BA06F1F2F6
+:10A77000C11B268EF6C2FC33C64DCC44FBDF86528D
+:10A7800003E0D70B7A27E2C52101AF96A5A8831273
+:10A790009DA6E33EDF2DB5A7CF41BB6C8F95A15D94
+:10A7A0007626F08E82719E6699F531C09B25D7BCC6
+:10A7B000AF603FC3EA58D40A657739D723BD7BAC75
+:10A7C000F7A0986AF6FD8DF2525C1DC1121D7F182C
+:10A7D000556E31F87F07FB5EF3FF9ADFEF28E3EB5E
+:10A7E000D5F4EFE6DD56B223E149FEE0CFDE023AD2
+:10A7F000A4B8798F21BE8661D93BA73276D5D9001E
+:10A80000F967CD7EDB7EBEB0FE6FEB2F7E707D984C
+:10A81000DE4F3E5B47FAFD13EBEBA9DCB13E4ACFBE
+:10A82000A7D7AFA3E7FEF52AB59F750723FA38B37C
+:10A83000CA19DB00EB3893127F17F344D4D10E7999
+:10A8400027F957239333609D27A44964FF364BBCF7
+:10A85000BD5AE7A4BC92E6B49E8E43D4DE4F7E364A
+:10A8600066537D19686F37F919FA798F3BD44BD24B
+:10A87000D19E0663653BBC3FFD718CCA110B30D184
+:10A880006B89CFBD29C1FBF42CBF8CFC6D637A743E
+:10A890000603BA3FF9FA771E47BDB665DB0FE31F23
+:10A8A000C1B8D34F94AEC178C009491D0B1A0A7BB9
+:10A8B000E0F5237B5D50BFFCBD7800F9C5D72BB711
+:10A8C00036BA01AF8E61EC640E27738C876B710E04
+:10A8D000A636ECAD1F03EBDBC9FD394CADFF32C62C
+:10A8E000516CA9511FF9A9D59F341E81F6E59746F1
+:10A8F0006EC7F243DDB736E0F8E5A3787F996F8540
+:10A900009E447E73774AD4079C949DABBC6B0DD656
+:10A91000DF9DCBFB3FBEECAE35586FAD63A10E7A29
+:10A92000462CAFA05DED5FB14B85796F993435C38F
+:10A9300001EF2361AB9687E1651ADF001475BBEE6A
+:10A94000EDB44E01798B761BE04795E0D3FDF80F0F
+:10A95000801572DB86FAD7EDA33BC8EFD836565D7B
+:10A960001EE27A02E9592DF82F5CB3A4AA08D76237
+:10A97000E6CD7E04E6FB58A5889F795904E5B743E8
+:10A980006BC722EC0ED88FD0EFD264DC5F97CF6616
+:10A99000D0AB88F78D14EDADF8B4A97AFF0553C399
+:10A9A0002F8D9F89F6206FEB616A21EA1B0EF497C9
+:10A9B000789125EAFA437BF1B688B20AEABB40BF38
+:10A9C0005061BC42CFF6F848F86EF3ACB87D14EA9B
+:10A9D0003193595095719C7B3F467898E9B1386224
+:10A9E000D45F0A4DFA456AC0A88FC07CA9BD0D2668
+:10A9F00087F3B539822F0E473E3F52E2F8CA8EC424
+:10AA0000305E92CAFA7F32C645968BF5A4940F2326
+:10AA1000BDE2D815DE02E48B35312917D9F82CD4E4
+:10AA200077318EDB1BDB980EF3AEF7B5CFD6E78917
+:10AA3000B9CA5D3CEF30D6D43D1CF10046C0BCAD78
+:10AA40004DCF291D18873B52BE92F0779E43C3D746
+:10AA5000F57B15C0CF9A7592287F632FE2E7B1F995
+:10AA60001AFEAEFB32D627F241BEB217F34106CD35
+:10AA7000FF50A35FC6FC8F79B9225F446DDC8BF178
+:10AA8000336B4D7002E2F7DC13698FA7607E0A0B0F
+:10AA90008EC5F2AF8E7FA7A100DA152CB8AD600489
+:10AAA000ACA32C5447713B33FCAF59EA198EF930F3
+:10AAB0009ABFEAF87C1EAF6D05BE827E2B76E81E3B
+:10AAC00007E6EFB896717C2B9DAFAEC27AB3DDA6D8
+:10AAD000D56BCF7A7F4CC5FCB23050630E8C3FD71C
+:10AAE000C2ED88B9737CDB9A486E472C9DC827F667
+:10AAF00066513C326519F74F857DDF7913F3833258
+:10AB000095F88DC88FAB190BC660CBBA6DF1712E5D
+:10AB1000D48BFA5C8ACAED20D9A1C77B95BD3E1EB5
+:10AB2000F6BD4EECF396C7B2484FFE14F016E1B1F5
+:10AB3000DAF7FD3749AF603ABBE7AA04FE2B8CBDBC
+:10AB400080F87475AF915EAEE93396E79D3596F364
+:10AB500098D16EC97719CB855E63F97A9FB17C83F2
+:10AB60006C2CB34D1CFF417A90BECF04BE6BF446F3
+:10AB70006F34FA855F168B907E5F05F417877556E4
+:10AB8000458DF493976B23B8A76E92282FD5A1EF2C
+:10AB90002F1BC1E6BDAE00E05401E21FF9C5E91D5F
+:10ABA000590EF40F3F30D7CED05EE814F26CDEB908
+:10ABB0001F6C46BBC821DBA2D82E15752AE8777515
+:10ABC00080C52CD9F8BDD19E848E8F231F592CF6B9
+:10ABD000031624F7CF3B6720DF716FFA7901EE97F8
+:10ABE000EF622B433B8305F93A2CF03F0E870E654D
+:10ABF0002BC6151417E5ADAD8EC469FC5A1F8BC961
+:10AC0000A8A76D32F211D74ACE9722001705E61B8E
+:10AC1000B9D3586F8683C7DEF7C27968DF0AEB5174
+:10AC2000257C86481F70C0022C807F0EE5D1961CC3
+:10AC3000E433415B90F2033D119F5E2FF96DB9241F
+:10AC4000F2805BC394FFCA2C4127EAE30F717D1B9E
+:10AC500073D1C80E32E5AF497239ADE3BB97022D0F
+:10AC6000835DE35C7771179A389297BF077B3D82CB
+:10AC70007685D316A2B233C4543597F2DE9E593A84
+:10AC800003DB5F42ED9D2CD8E204FCD824FCC020FD
+:10AC9000181CE85FAEF3BDD43D0CC6FEE9524E5F12
+:10ACA000752E8F6A4D273CFB5DFFFA09BEC6BC3886
+:10ACB0002D8FC39C877D6829A7EFFBCB252DAF5B2C
+:10ACC000E3578A21FF4D7DBFA180F4482E7F7FF995
+:10ACD000EBF71F43FED87C0D13F27AF8DE17A0DFE6
+:10ACE000870FFEC76BA5C86F7748418CD33EBCEB7E
+:10ACF000632ABB0A6CC105D06CD438F53AF2BFEDBB
+:10AD000091BC08B4E6D1231F407DFCD30093911C75
+:10AD1000AE0F845663FDEA9853E6F692925E38527F
+:10AD20005319F017B3A23CBC4AF8FB416F7EA5C093
+:10AD30008EA08F1ECA43FB08ED64CC0B8B473BB142
+:10AD4000EC526CC1988C7415EDC4FD762898780B84
+:10AD5000EF7764E7A15EDC54DE40FBD00276D628B4
+:10AD6000E443BDB677108E21F8DF79217FC9AE5854
+:10AD7000608C2B38E40FDE421CB8CA142FD0E4A23A
+:10AD800083F17EB4F77D4BD3385FBE8A5DC5F3AAED
+:10AD9000DF217DFB33987816F2438C2BE8F4FF30EB
+:10ADA000C615025CFF5485FEA93AFFFABCE9678428
+:10ADB000BE3C54BCA05FAF117182A3372BCF94CDA2
+:10ADC000C0EF19E1C9CC6E95DE672FE5FE8239BD73
+:10ADD000118AC3973B8D795DDAF3EE328EAF9FDB3C
+:10ADE0004EB019ED8407C5BC6B18E0FB948179EB7C
+:10ADF00063CA8D719A66DF17CB5BEFB70B86B643DC
+:10AE000008191F292B69C07CBA25D7ACF2A1DEB185
+:10AE10007AAE87A13DA6E1BB5BE0FBC307FFE16320
+:10AE2000949B0DB283213DB464EF22FCFFD4C7BCD8
+:10AE3000569DBD3B5360F7B0D17DAF95427D7DB748
+:10AE40002588F90DD7A3B303FB073B06F9BD86EFB1
+:10AE50003F76A74BA89766C62387B4FCDF18FAB7DE
+:10AE600076E44A885799F06D50423E7F3F7DEF0669
+:10AE7000BEF708E2B7B09B57B3C4AF3F9F58CC674B
+:10AE8000EECC843EB97A479382F91DED377A646B34
+:10AE900092F8FECCB78CF6B65BB119F28D41BE18B4
+:10AEA000EA33AC79DC9EC9B6C49AD09E413B15F515
+:10AEB000635B84E2C3328BB8D0BFDF1603FA96D14E
+:10AEC000AEE57AC6E96EEE4F39BDE3465AEFA720EC
+:10AED000B7703E675EA8584DF1B180434E41FAF31A
+:10AEE000A964E722DDBB5912FED12DF29D3116690E
+:10AEF00041BAAE4CE43F73FE7268854E3FAE1579A1
+:10AF0000CFCF0AFBBCA9FC8F76DCCFDE6F48B253F3
+:10AF1000C67A9EFF9C8C6F109F027985FD98F9C7B9
+:10AF200055CA4AF24B7A5778A219B392F11123FF0E
+:10AF300038BDE35D4581F6EDC82F009FEFD0F05D91
+:10AF4000F093C1E292A777F038C8A75E1FE50B9E89
+:10AF5000DE919F5107EFBFB4C2189FB4B59719E3B4
+:10AF6000517F73BEC3F986261F5C26F9A0D1CBA8FA
+:10AF70002B5592D3674633920F67F68C7A00F5F221
+:10AF80004F6312970F267A18281F400E109FE77202
+:10AF900040A317E7589B05BFF36EB3C6100E201FE2
+:10AFA000BC73C8AF6A61281FFAE966B7C482680F2C
+:10AFB0003A620EC23B900B0F66E3BE3F967F07E2FC
+:10AFC000E5682BE54199F77B807C087C31F9B0BFBF
+:10AFD000FCC2F261B0FDFDBCFB84FC1EF9A9B65FAA
+:10AFE000C8F7F11CC650FBE628CFE47C1BE400E662
+:10AFF000DF6AFB58B42472B45C9F8F381C34C4E9F8
+:10B00000897C44CD6EFAF3F17F6AC0BCE2A34B4267
+:10B0100057A17EC3023C8FF02AA07BE4E747974408
+:10B020007E8D7ED7F48BD74D467EC61EE7F987BF4F
+:10B0300016E30CA8DFCDBFD7EA93E4A7D6A03D73F3
+:10B04000BC92E3B7F9394DC82B2D4F15E6F56E3993
+:10B05000CEAB3FBF91DB63278E7FBB41E4677F5858
+:10B06000AECB8BECB7E7D4AD8FA1BDA7D973A78EBC
+:10B070006FA5F6CCD3E1437DBBB9298DFC2B3B9763
+:10B08000CA345E9B3DE66B07F8BD7CF9754DC85F21
+:10B090003C5B2C84475A3E1253B73C1647382EE08F
+:10B0A000E30C267F8E2E51CEE27C343BF3FDE3DFB2
+:10B0B0006A1079DDE7689E0522AF5BD8A51F1FDF08
+:10B0C000F298803F5B86EB54F83A353BF68FC71F0A
+:10B0D000A2795F778362C5FA5AB4D7747CE0377778
+:10B0E00066A5A09C37FB7953FD5CDED7FBF839C21F
+:10B0F00070B53B9693243EF6621D877B8B943C9EF5
+:10B100009ABB707EE632B243E3E3F0E84DF8139762
+:10B1100057E43DDF48E76AAC2C887AF6DC0DDCBEEC
+:10B120009C3BC9B20D7462F6C708D75B35FBD26C85
+:10B130003F662A6A117E5F0D7224467E10933D3968
+:10B1400029D3604FE6E54E97701DAE4689F4C07A6C
+:10B15000B42FB15FF6FF967D69B62719E376559D4A
+:10B16000905343D993BDB1CF674FBAD09E443D06AB
+:10B17000ED49E9EF674FAE467B12C6AF477B72FAE7
+:10B18000E0F6E4EA95DCCEFEBCF6E4A5E75E0E311F
+:10B19000D2E32C147F69D95D6CB22737BA2E644F85
+:10B1A000EEAEE5F615C547A09D3AC715DB992D36DD
+:10B1B00005F1FCEA548A07B72B5CDFF93498BD1D12
+:10B1C000F5C39DC29F8FBFBFE45CD842712E8C89AE
+:10B1D00078EADFFE7CD8533ECCB3AD13719EB61730
+:10B1E000F630F42FD5F9C16EA0F78E6FE9F98976A4
+:10B1F0003E6C27F27F8C8B8FE6F939CD931FA038F8
+:10B2000018933273ADBAFCBAC3826F9FCEE6FCA32B
+:10B210007958C497ABB3573A457DB3C8D7607E0E13
+:10B220004F47F5D58FEACFE36D5BE610724B892D62
+:10B230002378AA04D7C622653B9635BB589327DAF4
+:10B24000773F14FEAF3DCB24F17D680FF1D1E1DCF7
+:10B250002E649E78CC32521F87E2FE49CD5F79EC96
+:10B26000D16D0EF4033688F324ECA1F660898EBF0D
+:10B27000FF689924E4A0F223ECF7C012653FCE6783
+:10B28000AE6503F9DDE7E63864F4AFB5D8FB4AC92B
+:10B29000AFFF271BDB2925F066BE4FE41188F2F5CE
+:10B2A000323F4F08FCF310EA4D37C832F1CFB7EA0E
+:10B2B000B269FE8BAE3C46E7490ECE9019C6794284
+:10B2C000CA0B56F4F7E7EFBF9261DC7D4A51E845BF
+:10B2D0001CBF70415EC170588FA728F4735A2FD3DA
+:10B2E000CEDB713CFAC30D915F623BD0DB5427DAB1
+:10B2F000638118C98381F86D8CBBFC41C8831797A3
+:10B30000285DF8FD6D3728AF10FC8B42AFD1389E19
+:10B31000E4E7FA407E75637DCA6FA39311BF7FB2E5
+:10B3200030F2169F176B1F9BE43CB8B6BF47853DB4
+:10B33000792C0DF4021DDEFCB68ACFE326A1075B53
+:10B34000EB620B30CFAA0D5444159EE78A23BDD87B
+:10B350007F9B7F859DFC15A06F607ED149DFF6093C
+:10B36000C89FEA03D20129039E480BE4FFF80FF2BD
+:10B37000F79AFD279BDED0CAB7AFA90FE8FD295F7A
+:10B380005B8379B036272FFF6BE5EDFB508ED7CB73
+:10B39000E2BCEC5B8AACC7134798E3DF9B21E53F37
+:10B3A0002B67905F774D28B93C3D87F03C8EF6AF18
+:10B3B00085F68985670CDC2780BF84EF01FE167C4B
+:10B3C00002FC6DE11183C37F30FF913BCCE9E34C7C
+:10B3D000A49F3E7E57A9A38F0BCC7358D838CF11AA
+:10B3E000E124F804F31C29E6392ACCF164F485E65B
+:10B3F000E99EFEC0DB143F505364E95A4C5F89DA82
+:10B40000D08E7507395EBA7D12F9034F4BDABEBD97
+:10B41000F224EE83DB33FD7D9467E5E1118FBB46BB
+:10B4200024FCEEB397AE5DD3320BF597CE462CFFDE
+:10B43000C33BDF6DB08D0532CEE6FB7ACB3BDF7DC3
+:10B440000CCFE794E6042748486795631E775D2391
+:10B45000E4D89C041EBCAA8DC76EDB570FE3956A27
+:10B46000710535E77105BF4F557D18572BEE9EF0DE
+:10B47000B80DCFFFF4C70DEE8CA29EA98DF7618F9A
+:10B48000FF711C0FCFAB227F2800D8A29C28E95562
+:10B490009BD3617EF3C32C8E47DF1D0B049EB1EC62
+:10B4A000C731AE509AC9C77BA3D2D748F335959917
+:10B4B0009FEB8DC0878208DF20068C46609C818FC1
+:10B4C000731D8E037328F31AD75526F3F25B91D1BF
+:10B4D0008D2DB0AEA565BCFDF5625E4B19AC0BF3CE
+:10B4E00032BA6F8DF27529A3515E7E18B9335A00B6
+:10B4F0007CDE9AB689CEDDBA02C6F376DA73B6265A
+:10B50000FF6671BD15E6371BED88D9427EBC190A6E
+:10B510005511FEBE047CC14A7C81FC54C8A8468DEE
+:10B520001CC81734FBA5345D5D15D2C7016359DB18
+:10B53000548ADB852E9F837189635992046B3BAFDC
+:10B54000C5E54CF1C0D3633B54D4777AB36DD1EDEC
+:10B55000DE817141668AF799E3839F54897EFBE31C
+:10B56000804CC638E07F77FC6FA36705E983859838
+:10B570005F847181C6A718865837CF0A7AD1FF1D1C
+:10B580002AB4325567C79AF7EBAF8DFF6509BBD078
+:10B59000E6E0F96A804314AF3DD0D444769DA79A83
+:10B5A000C3ADB196E345C7724D3F529767C1BC4BDF
+:10B5B000018278DEC0BAEDC72ECCEB6C0B3C7D046B
+:10B5C000E5E0719F4346FC6D1E7D930FE199F27596
+:10B5D00027DD1B7172989C86F9956DDE8D97F0388A
+:10B5E000F3D5FF76448BA3035EEFEEB63D897CF97D
+:10B5F0001599D3DFECE50FFF1BE543CAB053BA7DC5
+:10B6000072B8E6529E962B8FE795EBF681F61B7F7C
+:10B61000765D7B80B33A633AE90972168EEBE3ED0F
+:10B620007DACA789F250000F1CFAF8B3D82797B069
+:10B630003BACB729F7CE4079E5B57A311EABED7357
+:10B6400089D867F3BE7A986CD87777F846CA53D210
+:10B65000FC4FEE05C67D4B5D6C2C839D62D8B7F91F
+:10B66000E11B497F9E0F7822D339329E77E612E3A1
+:10B67000E73395D6970F86761CC63B8CFC02F59770
+:10B68000591ED20B0A862D2D1806E5C3AE61B9B836
+:10B690000F603798ED924D585F90362C17FD80DD86
+:10B6A00061635C533B47A7D935C72EEEA07378A0E2
+:10B6B0008779D13FD785F14E3B9ECF6B72603915AC
+:10B6C000B308789CD170AE8E1D4AA17B381AC07E1B
+:10B6D0004D817D3A1A7C344EFE3D3FA373340D05F7
+:10B6E0009ABCB63C89FEB7CF7B3F4055CDB34F18CF
+:10B6F000EF07D8FB04CA99DE73DAF9FF5D4F60FCEF
+:10B7000078F0FB01B6DF526F43BBE25401C6A3AD34
+:10B7100015C33A8CE72DBFF53BFDFD00132A360714
+:10B72000F4F70358AE3FF084FE7E80B335E76ED168
+:10B73000DF0F20BDFDCFB7E8CF99FEBEE667B78823
+:10B74000FB01EC15484F439C870E54F03C890915CA
+:10B75000FC3CF450F703FCBDE2685AFC0CF450D5F5
+:10B76000897A68BA25C6F5E528E90B9B4C7E88B82E
+:10B77000F023BC12D1F8C800BDF33282C720F719FC
+:10B78000A457C883DD673085BE339DBFC67DE2E721
+:10B79000AF4D7EAD2346BF16E85133F17B8787EB73
+:10B7A000BB9A3E0BEF67D37B99CB3BEDFD33659A9C
+:10B7B0005FAB5DC67ECA588CEB4140F9E8BF2FF302
+:10B7C000C628CF81A993A87C66CFC36F63F9EEA684
+:10B7D00014D94AED3AE87E94EB2B381C48AE637BD3
+:10B7E000B0DF799E11F71F9E299232F13E9684FEBA
+:10B7F00094D1817A6FAB1DF41F98C2F2131BD6B897
+:10B80000C626F4A7FA0AA614F8601C3BD3F406A2D5
+:10B810001BE26B441733492F3E6337D2158A01DE92
+:10B82000FFB47D58AFE95FBF38F51DA3FE75E23B5D
+:10B83000A47F0DD6FF9ACA3D8D2D81847E04F389A5
+:10B840002F407EB3E0B630EA252515FB1F770D3378
+:10B85000B6A73CA2FEFEF63C8EEB33D7C3FE36D035
+:10B86000FE0A7FE650EDD9E27EFD258ADFCD167E09
+:10B8700041733E8726EFCC72F5D54AAE5FCF28558F
+:10B88000D6E1F78B0E6DBC3D94A45D5305C7E7452B
+:10B89000F33A7C282FDBC672FBDADCCE53C9F719EA
+:10B8A000FAB904DBF536256FB7AB426BF7289D1B61
+:10B8B000697D81B7C3FE8B75EDEFAFE076545B5ABF
+:10B8C000723F9FBF52B373430F54A07E762F8707FA
+:10B8D000D8BB0FE27AC0EEDC82EFFBE90B6819E916
+:10B8E0000BECCF8709CE3695EC89363BA777CAE5B6
+:10B8F000BA3A09DF0818F986995FF4F39D12A6E2B7
+:10B900007D0AB6A2C80E1C77E3BA283F1737885DB8
+:10B91000B1681E3F37D39CC6D76FF613348BF5172B
+:10B920000A3B48BB3F0DEF2DD0FB819E17FBA3F1D7
+:10B93000E503156F35EAF9F23F9FF047F57C99A9C9
+:10B94000133BD03E2872F2F2A113EF68F8F734C12E
+:10B95000E54E0EC7A72B38DF18EC7E80A225CACF94
+:10B96000B07DD120F1D9172BFAF7E745EA77ADE69C
+:10B97000EFE6F69BF91E8E972B06DCC3B180FC1B0D
+:10B980001D46FFC6CBFDFD2A2FD3FEE65A43C9F460
+:10B99000FC276A39FC58E048DCAA9D4B94899E1527
+:10B9A000833FE5CA98D19FD2D26E88139F4C8C7783
+:10B9B000B282DB010AEAC75ABCF3D80F9B0A510EC8
+:10B9C000334BCCA19FE703157CDF8EEDE5F5F31C2F
+:10B9D0003C2FCA5C3F5DE8ED80B7A72BB8DC1B8726
+:10B9E000F8340F7015E5CF5CCBD44E85FC3652B0E1
+:10B9F00009E6BFD0FF02F9B1E7834985FE96FC4016
+:10BA00009E0DD3960AA7D76DC2E794A2C867D8CF78
+:10BA1000F5734F05512F9CBB213EAE3D4078FF870B
+:10BA20000A9DDF45A377C4C362DDBCFE2CF0AE796E
+:10BA30006C72BABBAA4A936BFD7E1B4B65127FC02A
+:10BA400000BF8D87F3FFE6D96362FA739B7E212FD7
+:10BA5000C12E4FA9E476F98AAA1903E945CBDBD3B5
+:10BA6000FC62A58BBBE65E04FD15AE93642BDF572D
+:10BA7000F293D5887AADFFDE22C987E770B53CBC6A
+:10BA8000E76A4F3E4979A46B25C15FDF7C12EDD98F
+:10BA900044DE5DDFAD441FFD7AD66FC99E1F5CAFEB
+:10BAA000FAF0D67ABA27665AA71DFA5FD673EA4922
+:10BAB0001FEC4BA9765E80FDFEC90B9D17E815743F
+:10BAC00066A67FED394EC07B30FABF56F82B35FAAB
+:10BAD0009F5539668D9EFEAF7E63CB1A5C6F82FEEA
+:10BAE000EFDFA75F5FFE1B396B04FD4F253F8BA087
+:10BAF000FFA995EC82F78300FDCFC3F6E67B77B410
+:10BB000067A1902FD06F21F53B04FD2FA934C68F7C
+:10BB100007A3FF25FDFD2A4B2A470C4EFFA3AA8C45
+:10BB2000F4DFC0FA7F44FFFDF4BBB789E8BF7E872E
+:10BB3000A4E0B94F33FDD724C6ABA91C91A07FCD9B
+:10BB40002E39364E2DC4EF994575E8BFEBA7FF4758
+:10BB5000059EA9471A51DFD7E298BD158FEC13FA5D
+:10BB6000F16AEA773A87FB507A09B4BF95DA073968
+:10BB70003CFF5A3D6780DE1837C64BB5F8DDC0780C
+:10BB8000585F11E55F062C49E36159CC7BDD66C047
+:10BB9000972AB00FD15E6B0B6452DCCFFDFF491CBE
+:10BBA000CC51C6E3F5E6B88F39EE89FEFFCA247A98
+:10BBB00039C3C434CDFEC57DF91FEED771A1FE395E
+:10BBC0006370FF0EACF3255AA7D76867786F88FCBF
+:10BBD00012DFF7E753645B289FC2996D494199F1E1
+:10BBE00079E3C7D0FF2BD4FF78231C1B8B94D72A73
+:10BBF00049DFB4125DDC7922FEB8885F77131D89B6
+:10BC0000FB9BCC71FCFCB0280B3FE640FF28D3E83F
+:10BC10002E8EFFA9EF2FFB1A8F60DC3E70E1FBD761
+:10BC2000CC7ED165DA78E23BB3DF1BF48334F44B8E
+:10BC30006AFA163BAAC87A7EF36668FEC7B41E95F8
+:10BC4000A9D24803BF530DFC4AE377E2BC147BCD75
+:10BC5000D8CF7F561AE30230EED9659C8FFF19CBFF
+:10BC6000291F1AE17BAE389285FE536B9DFA25F4AD
+:10BC70009761BCA3693ACFB7F200BC4ED6A7C424E3
+:10BC80009D1F4EB39B8655697EE55CB2F386BDD998
+:10BC9000B2CF356368BBA734331AC6F3452527A056
+:10BCA000FDECA4765456956EDF86EA6FB07C8F5C0F
+:10BCB000A197999FA595463C616ABF1D968DE39A11
+:10BCC000E5AAA6F7B17546B9E2AFEA972B7EFC6EFE
+:10BCD0006A25A71FF33D5EC772FAAC4817DD40E343
+:10BCE000DBF1ECC9A6F6A0FE3CE43CE14F96AB9834
+:10BCF000266FC792FE24F07A6C1587BB96A701E3E6
+:10BD0000F5A21EA8E91D5ABE3EC697F5FDAE14EB7E
+:10BD1000FDA2F1E56AB12EFCFDCF8C2F37517C5985
+:10BD20003B47D822E2CB61BF4AF7D08407892FEB8B
+:10BD3000F4DD4855127D17F4D7BA2A9DFE6A2B0A06
+:10BD4000A5223D368F6EA678C496742D2F31467984
+:10BD50008913D9D6859360BD2D3BA420FA2381DDBC
+:10BD600053BC7FE16BFC5E2BCC432B9A49FC9EE8D5
+:10BD7000D659A3BAD0AFBC50B69CC271B5FB7A9964
+:10BD8000B53AE939BAD6F408DD57E5D8B1AD19EFBF
+:10BD9000B1CADF2D897815CF73BB34D0DE8CF701A3
+:10BDA000B8D77516F0BCE5475E42FFD6995C898D21
+:10BDB00092315F2DA2627EDAE9D94EEF06CAE3180E
+:10BDC0005378873E5FA280DF83E282FFA17C5C3CE8
+:10BDD000DD782FCAC221F20FD7BDD535E5B06EDFB1
+:10BDE0005AABD20CFE582D3F4D5B5F6DFFBDBF1DA2
+:10BDF000E2DE5F9E6FF6EFEB3BA71C86FD7948E81D
+:10BE0000C9476F8E3C54A5B32313F792C47AE93E19
+:10BE1000371FF322DEB6043E39741ED6F7FB984472
+:10BE200079A08E788A8BF200574A31CCFB5C1D7B5F
+:10BE30006033FAB31B645B14CF7F35D8781EB93BEF
+:10BE4000E6A4F8F951843FD8D072B8FD17E8DF3D79
+:10BE500003FA11EE5BBE1C6DC7784F2AEC23E67324
+:10BE6000A6069BE2988FB8181806FAB59D156A7C4D
+:10BE70001A945B15571F9E8742BD4A9FA7F225D98A
+:10BE800042F7DF687031E7B998E5B676DF4DCB68E9
+:10BE900091BFA82AAFA01CD7E8CE213F6BC37DFC81
+:10BEA000D5682BA3F3ECACDD41F416E0FE786DFF12
+:10BEB00098F55E15F3647F2FCECBBB98CE7F8EF0C6
+:10BEC000985E47FEFDA288278AF92D45417BD2B8AE
+:10BED000CB60FBFB5295319F7A8F8D0531DED5F615
+:10BEE0009A95CE7FB5EDD87F04C757775878BE0BAB
+:10BEF0008B907F3782F7FAA2DF300E1AC84C3C874E
+:10BF0000CCE9A1ADB863731DBC97BF7A4910F97B2A
+:10BF1000DBE467ED586ECB1ECED07FCD2CCA0B78FC
+:10BF20006EBEE6BB5689F31346706A5B372CC6F3C8
+:10BF300019620EFB703C1FEF61D8BF86474B049D12
+:10BF4000D4E37918F8E70A162478AD64217ADEC4C0
+:10BF5000A2F4945880F2132BA39C7EDB441E69CF7D
+:10BF60000E0BE5C52A57DB877DE0E22EA064F25F69
+:10BF70007B62A4EA031DBFBABA4AC81757C487FC3C
+:10BF8000E6CD50E4A32A837EAED07DDF89738F1F78
+:10BF9000D33931CDBE6B58F1F15E8ABFFE2FD31F6E
+:10BFA0005BC2F205F547906BE9D5A87FDCCAF50FB7
+:10BFB000ABD0FF187BF65685E2793C6EF248387CB0
+:10BFC0002BEA77D65C5648FEE91B2446E7FE3C4741
+:10BFD000DEB31AF5A2F19867A3F90BBEBF3C87FB4D
+:10BFE0003DCE6D4A47F3E4D8DE3A8AE32E0F58B6C9
+:10BFF00061BE59D8F3A01DE1B47956E834F2E98A5C
+:10C0000063E21EAC41CE756AF0A81683A58A78AEAD
+:10C010004BC473ABCBEA17A37D608EE3B276BE6FE1
+:10C02000E6389D8DF9B69DCF4EEC8376CF96EE7BAC
+:10C03000DA07339C5994D3B91F7AC038A0760F46DB
+:10C0400078A5917EDD68AF4C4976BFC3BD1F5BF913
+:10C050003CE9BD1657D5FC29BB9797913FC566D1E2
+:10C06000F0D14F71A97EFF8A7A39C5A5488EE9ECD7
+:10C07000549D3F45C1DCBE502FEBF7B7BBE8BE5324
+:10C08000F5BE6CE8DFB1F48A27165C8EE5C81AB4F9
+:10C0900063334E6E7A02E3019AFF25EFE4DDB7A821
+:10C0A000FCFED7F9D54837C3B9DE331F01CFF5A160
+:10C0B000027A2F73FDA720F13E8CF8A4E5E1F6FA91
+:10C0C0002C0B92F911580DF723CC85CD9E047A598B
+:10C0D0006DB5C7C0C7EE1671412DEEE710713FC7B1
+:10C0E0001895FC7EE6FE56570BFF779172338E0F44
+:10C0F0007AFE6A9A5F90EBF9B287DFD78B713D9435
+:10C1000053DE6D22DF7E3C3F773E77EE3F29983F3E
+:10C11000E9B5B01E8CB3AA8030983FE9F8A98DE844
+:10C12000ACB8A08EF208AEC5F30C00AF509FC5703E
+:10C130001E615E81DB50D6D1B1218F52D33BCC79C9
+:10C140009478131CD2B5539C9732F381BCEFAD5554
+:10C15000301F3915E404E5B51798F32AA3CA86E120
+:10C1600089BCCAD49638ADAF42E4553AC71BF16FCB
+:10C17000F5BD3CAF328C7995DE8178AB02DFC2F53C
+:10C18000BA61BC64F9A6DE149E57D102F04079ABC7
+:10C19000A317B15EA3BC6C2AAFA4F31F67263BC4F0
+:10C1A0007931C9B0FE4CA5E330CA956A587F2CC9D5
+:10C1B000FADD78239E4EBE2AC27FE09657A8C85F5C
+:10C1C000BD739C5E8A8F9BE46B96584715AC23D950
+:10C1D000394DF3BA424A9715F59AA7AA85DE14603D
+:10C1E00001C4C783E57794505CD46F61A80FB4EEA7
+:10C1F000D841E712D5EFDA82749F206B5F8EF597F6
+:10C2000049995CAEAA12F931B4F5B7167714A0BEFD
+:10C21000A008B9DA7A79F3C5785F56EBCE51328649
+:10C22000A6434A5E13AEDFE5B34A885F5A1C15E5A4
+:10C2300007CAD3563696E4E9E926C6ED86A592B03C
+:10C240001B9430C2B506F427C4EB25BE28E5BBBA63
+:10C250008157139CD1661E89714646C197A505FB7F
+:10C26000496FF1E6D858FAAC441C36DDD21344F8D5
+:10C2700016B11ECAC35AC2BC767C96B020DD53529A
+:10C280000E0C8FEE0361EDF4AC641DF4AC663D76EC
+:10C290006E67C804E75A3FBF5FA5AF3A9BE87BB122
+:10C2A0008B117F6F0D74A6D1BD9E43C48536493C6A
+:10C2B000EEA3022FC27BCDFBE3CBD358C40AFC50C4
+:10C2C000F90F26E9E5BF145BC6E346C580B2A319A2
+:10C2D000FBA89ACB1BF6AD608B739C90D3D05FDD2F
+:10C2E000187E0F9BC62F3EEF79CC39BD32BF277227
+:10C2F0008744FE9339E8CF0C50DEB4A2BF7FF28DA5
+:10C300006A1E677FA39AF3B5525B88EE03C40BDF06
+:10C310009A6663BE4B09954BEF04198D79F21F4F56
+:10C32000A7FBD0DE0E934C85EF64FAEEADCF0E8EF8
+:10C33000403157E569DAEC9507DACFDA7876C13F14
+:10C340009D35FDF120678DCEEF525D3DE0FC849B75
+:10C35000EA0F18FDC5663E7A8DE86F5EEE21CF3498
+:10C360008CBF8DB6107E9BDBCD10E3972CE07F5FFA
+:10C37000E2B803F005D635BEE6A15B506E8598BCE9
+:10C38000391DF9C6A67B6F095F4EE35F5C83FBE254
+:10C39000E2F2C2D19B3C8F2CBBC6A1AD279BDA7BBE
+:10C3A000F87C6B047CE6C2B0726622FE0274A7E5DC
+:10C3B000C34DC4F6211651D10FA28D5B8C17199372
+:10C3C0003CDCFA04C6230E20CD68F167C0FFAE3412
+:10C3D00051AF7EFB16BCD7C2FC3DCC6312C14D8C65
+:10C3E0003309151B1867428D80AF8DAF47F377680F
+:10C3F000F78769FBB56F39B7F7CDCFE1F8FD8CC48E
+:10C40000FE687E79333C326AFAFDFD19040F71FE35
+:10C410002503E7C1E1741DCD4FBC1F3A0F85AF3F27
+:10C42000F5C4838D4DC9FF7E02CD7BB5D85FF33354
+:10C4300071FFBC06B73B1ED79FAF29387947A3D001
+:10C440001B2A6AF47A80C8A7597C729D565F43F311
+:10C45000FEBFFCF714969DFCBAE6BF2AD1D34789EC
+:10C46000D847787F0BBD37FD9D85AA935FD3FC9994
+:10C470005FA175546BF7DF5FF8EF2EF409381DCB21
+:10C48000E1F4C5EAB99F29659C97B5EACEB77E432A
+:10C49000B403BCFD068EAFDDEF8E3CD0A28BAB3873
+:10C4A00076737E83F7C5EBE3359BFBE95ED95CA32E
+:10C4B0008B1721BCF5FEB0D644BB566C37589CE8B0
+:10C4C000819A017162B1BFBF20BAD1EE93DF5A7376
+:10C4D000E209978478B57DA305E9DBF6F247782772
+:10C4E0001EE60BE8F1F081047C1F21F899F294CC50
+:10C4F000FB154BD07D8CDA27F27192F2895D3536CF
+:10C50000ADFF5DD4BEFFEF32C435BF5E10FD7AF3E0
+:10C51000EC3115EFDF9B6797822A43FFC645C505BF
+:10C5200050764FCE998A32E4FF08FAD2FA7D6E41F6
+:10C53000249DE2DF7831E354F473F07BCED32B38C3
+:10C54000BD0D462FEF89FD343FCD7F67E1FB3547B9
+:10C550009FD0FF9D851D35AF4EC13CA3841F4B75F9
+:10C56000E17D6E9B9E8B58549483532C24E75B0291
+:10C570009FE493FE817B7C8173D277AFE7F7B4FFB2
+:10C5800042DC83A4BD7FA526C7B0BFAEC295E42F11
+:10C590005B64EF187EA17B4517F98D7AED46DF5776
+:10C5A000E81EABD3DAFD4D63DAEFC3F399CD5D56E8
+:10C5B000B641C6F1636FBE3721917F7168B4233EE7
+:10C5C0006F3A9E23ADDB857AD32F607E787EF1C3F0
+:10C5D0001A2E2F5D3B9E6232C0C735E600E5F33967
+:10C5E000625207DE5F5DEFDFC6D0AF9CEA8B115D64
+:10C5F000A457707EB9C80F84A7D3DF60FF0FD4E8BB
+:10C60000FCB207045F64E76EF4613EE9EADD12F90B
+:10C61000A5F2773731BC4775B0F14ED570F9521F8E
+:10C6200080713D386E878DFEDE43E2EF4E18E4A543
+:10C6300024F8F85D09FE7C17CD43FCDD89BB12FCB4
+:10C64000F98FF4DEF4F73306CBEBD3FDFD8CBB6A38
+:10C650004624FA392FE63758DC18EC1EC7726EF7FD
+:10C660007C88F10CCDEEF950C441D817CF839525C5
+:10C67000BD1FC394E7EA08FF4839887CF07769F268
+:10C680007CF45B9AF26207E6C1068FE0B9C1363FDF
+:10C69000BF9768A83CD8C3E171640F1D067B400AB0
+:10C6A000927DAD621EAD765EF82FC88325FD743E87
+:10C6B000D801C9F360B93D942FEE73392CF2628131
+:10C6C00067F4EDF4621EAC9DF4EAC3B3C6C4D04770
+:10C6D00062CE833D8E7E168073E1F03ACA879DEF6D
+:10C6E000E1F9B2408DC3315F0FC618CE74F6CEC9E2
+:10C6F000B1116E3F89BC741DFC1DE7B393C0DF16FA
+:10C70000A1F5DB2C4C7EC43B10DEB0E19BCBA72710
+:10C71000E0833FBDBF03F302D14E72302FF7539930
+:10C72000E0EFF6C9851857463F34748AF757328CC4
+:10C7300037A51E4DA1F346DAFE6BF3718F6F646867
+:10C74000AFFCE3BFA5C9787FADDBE4D71A90F70C47
+:10C75000FFEFF78B25F1730DCC83FEDFBDDF8785FF
+:10C760001E58306C956B8578E279FEF5826F140C5B
+:10C77000923FF86571FE90FEBE0ACE673FCFEB9CFC
+:10C780009CDA1345B85DE93A7510B7B7C33B2D7F06
+:10C79000988C798691BB97639CCB97D7968DE3DB7A
+:10C7A0003A7330DE34F936EE37ADF673FB1F246C86
+:10C7B0007C24940B1A25F6888CE77565DB28789F16
+:10C7C000DF98B7781994EF5F6EF4BFFCBDF3B6ED58
+:10C7D0006F7FB511CF7301BFBC96FC91593C9E7D14
+:10C7E0002DFA95381F7D14F95BCABBFDE7477EB86B
+:10C7F0009CC7C30263939C1F49E4E146946A3DDFF2
+:10C80000349D7F5712FD5FADD70FAF16FACB8C5218
+:10C81000E5291CA7FFEF036AEB93F8BFADF63A05D5
+:10C82000E3B3A968954C47BC9004BFE5F04BE4B373
+:10C83000C4C84FDCE0471713FDFD989F61BF000F90
+:10C84000825F718005D1BE7407643BCABBA1EF5FF4
+:10C850002E35DC03617E0E76FFB25F9CC73866DA48
+:10C86000EFBFE1DF3325BA31FF3DD3F7C5F98FFEC6
+:10C87000FE4CF7C2FC66B9314EF545FF9EE92BC56B
+:10C88000A10F091F5C0AE555BFB358995C3BE34211
+:10C89000E700BEFE647D20217F2FADFD19F9B701B1
+:10C8A0000E0ACF7FBFF0B8D696729AF755DD964440
+:10C8B0001C14FE3FBB27D5A02F5DDD9B69285FD3ED
+:10C8C0007791A1FDBCB33986FA3C7685A13EDF3570
+:10C8D000CD502EF45E6D687FBD2FDF50BE415E648B
+:10C8E000683FF9EC4A9AE795071A0CED72E35F315D
+:10C8F00094C35F8A64D6C2FE4C3B7287E1FB199DEC
+:10C900001B0CED0E96CFC9C0F8A6969FEF11F75DF0
+:10C9100059DC632E41FEA6F9AD34388DADE5FE1825
+:10C92000A72D4AF7E56BFEA6817E9731DE0FDCA2CC
+:10C930008CE7000B3EB38ABC7696319AE292DE64B5
+:10C94000F809FAFA47CB75FABBA6AF7FB49CD3358A
+:10C95000E0C524C40366EBC78B2BB03CB9D688FF77
+:10C96000E39728BDCBB99E94544EB7A29C0E0E946B
+:10C97000D3A065CB9CDF98E42DFC24BD7F57C85F16
+:10C9800017CA5F94F7E169A47F01B0FBE6E3197C65
+:10C99000933C3F1CFE1143BBE5302C464A267FBD2D
+:10C9A000F52AFA83BFFA519A8C7E0CBC6FFA20F2FA
+:10C9B00021D0C7F07CA4591E335BD08B71E8F42BD7
+:10C9C0002D4CDC677E41793C947EE616FA99761F01
+:10C9D000F61797CF87F83DD13E4D3E0D90CF24BF3F
+:10C9E000F385DF76A07C5E4571AEC3B346D1FDDA38
+:10C9F0005F543E6BF75A3716296B101F6EADFD9FC3
+:10CA000021FF74F90C741FB0D90E3C8376E0F0BF9F
+:10CA1000DC0EFC27418F7FBD1DB8DD857CA0DFDEED
+:10CA20001B1325BBB039DB42F7DF36A7F1BC0BB5D2
+:10CA30008BDF63ACD9810DFEC82EB41B1BFC1D6CB3
+:10CA400022EC4303DA61A8E7C5EA9E453B4CB30FED
+:10CA5000A32BACDC1EF33F407955AB851DF8D1F21A
+:10CA600041EDC01CB27BC673F99DA3D93D9ED8256C
+:10CA7000E83FD7EE79B915959D1998DFA9F27B5E4D
+:10CA8000B2AF93F4F7BC0C66DFC76BB9DE667EBE4F
+:10CA90005A61F4E3A13D8A7CD47CBFCBA9DAB47D92
+:10CAA000285F401F791EEB07D347B4F8DEB3B59E6D
+:10CAB00035E25E9BFDB53ABD643F2A3A33069FE7F7
+:10CAC0006B625EE6A7363F6B0D137E9D2B3AF23C00
+:10CAD000897CEAF195BF7F52DC4FD359ABF3330E1B
+:10CAE000967FAD6BFF2FFAF9FD8B981FBC3F51ABC2
+:10CAF000F3FFFDA579DEDA38BDFD71E9B47D98F765
+:10CB0000FD39EEDFE9AD9D91F003BE5E9BBE06FBF5
+:10CB10002963AA385F95CAF0EFB494793BBAF93922
+:10CB2000F4CB65FE775BDADFE6F7CC8EA1780BC637
+:10CB30005FD09FF699D0CBCBB473FFB608E5CBB4EA
+:10CB40008A73566DDAFC544B8742718EE004E4DB45
+:10CB5000AE9ED428C6554F9BF289FBCF9DABD551D5
+:10CB6000D4435A07C937FE2FEE36CF2E008000007F
+:10CB70001F8B080000000000000BE55B0D7454D50E
+:10CB8000B5DEF767666E92497213020E18F426043A
+:10CB9000186A0243083F02CA0502E40F99408080E8
+:10CBA000A037214050FB1C405A9ECF3E2E24867455
+:10CBB000821A2BF6476D1D28BEDA2EAD23DA56AD4C
+:10CBC000AF6F00A52E126AEAA34AFD798D1411B544
+:10CBD000B55045F1952EDEDEE7DC9B993B9904FBD1
+:10CBE000DAAED5F55E5CE17AEE39779FB3F7FECE2B
+:10CBF000FE3B2760AE883617039C167A6E8100C014
+:10CC0000F346EE17E56B00761700C008805C23F74B
+:10CC100071732640F7A2E0A7374EC677459D816025
+:10CC200009C0A737E2FF0F05587C3A22810AE0EDE0
+:10CC3000BDF0076522B6817F07E6855B6348178AEA
+:10CC4000717C26C045FA99D5FFD9BD48FF8CE87E96
+:10CC500046F4887E0D1F8FEF4FAFC0F6E915FCBD7F
+:10CC60003DCFE506C4CA0389F36446752FC092DC44
+:10CC7000C0682107A010E76DBD16DFFBF93A93E706
+:10CC8000CB34F8BA919FAA1509FC54ADE87B5F64D8
+:10CC9000E013427C1DD7C9133B47E3BCC5BFDEFE92
+:10CCA00098176532DD8F7DD301D27FFDB55BB61756
+:10CCB00001FBD187015443C2CF14ECA767016F6A0F
+:10CCC000D8AFD0FF8CA27FA22F1CCA03B87B717A89
+:10CCD000288C743FD20FCA20026440440609E9043C
+:10CCE0005C70C2CFBFBB88BF197E6C2BF1B6E297D8
+:10CCF0001DFD2409DD6E4BF4EF4AD095783B5BDADD
+:10CD00007E4500E553BF55FAFAC92128CF03DF72EB
+:10CD10006BC86FFDBEED2E83BD77B3F7B67CC2DB6B
+:10CD2000004EB8709E952AD787D7F0917C66B9CD12
+:10CD3000B541D2E7D6CEC0E2047D5619021B87FA70
+:10CD4000AA22B9ED5FA13139CE0219F45C54E7A4EF
+:10CD50003F5F4EF380D9A7D745346EA187EBEFD064
+:10CD6000AF4FDC6262FFD1C2331294011C2F04D892
+:10CD70008B3882D6CE406DC23CFFB14264F35C6713
+:10CD8000703CB8CBEEFDAFBC3CA29BA609A8EF72ED
+:10CD90000831F9B9111B80EFDD3E2162A2FCDF13DF
+:10CDA000B8BE004AA33AAEDFED2D7B47C231BB7B54
+:10CDB000274595C971DC3F697C7C8B3C328EFBC773
+:10CDC0008D8F1F33F3191E6E3012707283859F256D
+:10CDD000851C6F7B7AA74515DC2F4BDCD63CE635EE
+:10CDE000511DF7CB9274F30A403EEEE9D5A3F270E1
+:10CDF000E4CF6DE3757988FAED79BED3BB204AFBA9
+:10CE00006B71450308C87FB90F402A88E3FD67C9E5
+:10CE100078871B2DBCF3F9361837B2EF93DB7541D9
+:10CE20004E6F3ED14319D4A9B61C402730D669BCF9
+:10CE3000FDF5DEC9A176A4B7B48E8F5F60CDBF14B7
+:10CE400070FD2AADBF3C245F7DE9F5A39C3AD8BEB6
+:10CE500029E37A3E2D407DB4B8FFFEFB962132F9DE
+:10CE60004999AD6060BFE2033DE2ED3FEEF40A8117
+:10CE70008D9B7CBD85C369367E8237337D04B83E89
+:10CE80006EB6F471D46D7E91F0B9BBC05C1D4C9848
+:10CE9000F70983D3B9C71093EDCB3D067B6FD9B1AA
+:10CEA0007EF2B7E50D31B045C7F45B167AC9FBB920
+:10CEB000ECDA065AE7060BAF7D7C58F33F6CA86CA2
+:10CEC0005E28E77CF4F55B6DE4F3478CCF3E795E3A
+:10CED000D23EFFF9C604B9FCD9B2CF430C27DD47D7
+:10CEE000EDB6651F3BF5469DF6DD4768F1A4890365
+:10CEF000F373CD991171BB82BFB3CE17C6ED0EFE91
+:10CF0000CE86AB1CFD7395498EF63C758663FC029C
+:10CF1000DF5C47DBDDBE0C74B443AD166EBCA0BA5B
+:10CF20006B717D6246FE150D28EFD72DFD25AF0BE9
+:10CF30005A5DBFEBB5E914D2BFABD453570108A07B
+:10CF40008B1733985C4AEB87C6E5525A0F96BD0A99
+:10CF5000BE9D88D7766BDE641CD5D673FC9CB7EC7F
+:10CF60005C6D3DC76F028E6AEBD97B4E77A104A141
+:10CF700028E1A347D71627F89F3782733E64FA0447
+:10CF80006812A658FE00F7E0D1515044F62ABD18A9
+:10CF90002262017BB2FD00C7F1FB047CFD69259F85
+:10CFA000FF8DA0FEA79593A9CDF57B3A0947E3171E
+:10CFB000EA7F62F398F04A11FA9D855C3470BF9B5A
+:10CFC000DBC5F7C609911D486AE1BEEFC9E5A8F7C0
+:10CFD000C3BA720610F3F767E192695ED95480EC28
+:10CFE0007C99EB24C955C7FF48AEDB97A5B3EFDFAB
+:10CFF0001F0E110F7E3F069ACDDBB11D9EE651C973
+:10D000008F55817CB2D7D637F2D1EE6F8418D23FDC
+:10D010006778436447AE0FB9E2FDA46F1AEF8F8FB4
+:10D02000FFFEBEC51B887EF3A31E8DF61FF9A1D897
+:10D030005866AEB216A2BC6A2D7901A877DE8E744E
+:10D04000AB7C1284C9D697BB4E105D05FFA37586D5
+:10D05000B3423D2EB2FF9A08DB918E3B2204681D3D
+:10D060001B8E49810AC2E5BE3D7221F66720DF1E94
+:10D07000FCFECA62C3EC45BE33B6F69423E890CFFB
+:10D080009B621E1C7F7AA20097B1D5194072AD2910
+:10D09000E3F3F4AD3FF2EE9B90C5F83E91C8B71BA9
+:10D0A000769D95C633FE4E24F2B7F5CD5F8E7F2177
+:10D0B00001EF131B32F308A7500AA5E4A77FB3EDD5
+:10D0C00019F8ED686C4BABB2C95FE2F6D5198E204A
+:10D0D0000A84A3FB973DA734A25E3EDDD633FE054E
+:10D0E000F4CF331A382EBBD71B331A86C671925130
+:10D0F000ACBAC9AE6A70E6D045E4E37D1F44C238DD
+:10D10000BF6785D93E9DF4754C4268909C4C089051
+:10D11000FD8D7DD5AD21CE9A7D9D6EF22B1B64D801
+:10D12000E1C2EF322252643B4ED14D7A405FFDFDA9
+:10D13000E2903A1DDFDF84DF8BA887B98F62671921
+:10D14000B3DF110FD257028242ED1AC4B1865DCA15
+:10D15000CC1F992477D0E450F634F2D7DB6393B038
+:10D16000BD10E5AE231EAE43FDC412E31C049E2594
+:10D170002FF122F96C537FA5684A425CA521A56175
+:10D180002457FC294CC07301303CBBE9FB043D54DF
+:10D19000EFDB69929E6D7C4331C7B38D13C473205E
+:10D1A0004678FE9514F068713D2B4938763F8A7AAF
+:10D1B000467D2E0C24E3B74FCF2707D3F33F25E955
+:10D1C000F9FB32303C76201E4D9CB763DFD32FD164
+:10D1D0003ACD7D626034FBCAAC27BE0C1003618A75
+:10D1E0006F6202C82887EB2DFC77D4465D8DF8BDB1
+:10D1F000B6F98A00F9A38E921FBB1A705C47411ED4
+:10D2000064908F17F5038DD85EFD9024D0BE643FE7
+:10D21000D4BF35271216187D37E9F7460CBA88BEF9
+:10D220008DA74511818DDBD02A307D3642C04DF16E
+:10D230006A1304D9731D84D853806293F4BC3224DA
+:10D2400004C26CFDFCBBDE7DE21EDAB7FA0C57CEE1
+:10D2500029941385A2A9FC489FDDC6F8F05442DC4E
+:10D260003A0632B97D3104B6CEFB7FD032AF3C8F67
+:10D27000F9A51EB21FB327B6BA68DDCA4C17D0BED7
+:10D280009D75219BE1CD5DCCF1ADF8A20C6FCD88F1
+:10D290003711C7F7206E750FC3D1AB4509F1793F40
+:10D2A0009C294E5CE17E2BBF13E75D41F645ED8F77
+:10D2B0002BF498AE2F913D41BBC6EC8F852B11FF0F
+:10D2C000235C351B9DAEAF937C7525A405C88F7577
+:10D2D000CE77D33A4D011EC0E12B0C278EAEBC7029
+:10D2E000ABBE96EC3FD9511C6FDCE18AE3097FBDF0
+:10D2F0002E0C00B1BF1DE73303FDF1D6EE0F32FF58
+:10D30000EDAEC135603CEAD65B9442DA770199E133
+:10D31000E9BD5A485727E0D315F5DD8BFBFD4003E7
+:10D32000F75F2F97CC3F4038F2DE2F32791E229CD8
+:10D3300066C4717AEB722B4E5030FE47D5542FD411
+:10D340000F37907F5B147CA981F953BE5FB296734F
+:10D35000FFF3EA1CD31744FB71EB0AA73FBAE68C34
+:10D36000981437A427C50D431CEDB9CAE54971C30C
+:10D370002847BF67A42C12BFEA1E2942785BE073DE
+:10D38000C61D9E3D521AD9F11FD5015BFFAC319DE0
+:10D3900057901F7F6F34FA77B2F3E5B2795916B31D
+:10D3A000A76A438AF8F4B98A86771A2627DAD398C7
+:10D3B0008BC6CD014326FC2F0093E5199528E0BCD0
+:10D3C00002F2B7C607248FF2F2DAD63CDC0FD5138F
+:10D3D0004AF2C97E7B17067FCFE484D696E447766F
+:10D3E0009C9E9F541A67E93DADC3339EE84780C6B3
+:10D3F000DF8D6A21BECCE94AE41186B35E477CD951
+:10D40000B39CDB7BFAF9C7CE37F75C417EC5CE37DC
+:10D41000DF3FB001C8BFD4FBCC41F3CD1717E9B94A
+:10D420008DC8DFC64A7D4823CA5F5E181C4A6DF06E
+:10D43000DAF273C6753B05482B22791D95028F6081
+:10D44000EF320FC65D09FA1CD9C8E3C5D2462EB724
+:10D450008CC812D0270D6C8F3A4468A6EF41F23287
+:10D46000FBF65649F15EC297DD6FD3E9C3456C19EF
+:10D47000A3B7BABD8EC5AD57353AF74FA7BE9FE9E2
+:10D48000F32363F0B8DAA663B7DDB1DA41D7E9B6C2
+:10D49000E2CB43CBAAC408D9755FE15EB2D71D3E8B
+:10D4A0005127FBF9F19BDA5EC2C11B0D3C5EB471E2
+:10D4B00044F6ED8E5280A9E78BC14CA0FF63CB4EA2
+:10D4C0003EB34D61CFE7B6A9A063DCF5FC361F6B18
+:10D4D000FF6C9BC69EB16D7EF6FEE0B6006BBFB0E2
+:10D4E0006D1A6B1FDEA6B3F64BDB2AD8B32FDE6DA9
+:10D4F000D0789E1EAB63FCB823FCA9D33EB0E219E2
+:10D500002345DE87F1CCD246C7FEE3F1CC47FBE6EC
+:10D510002E9AAE91D7C034ACB4FF777227D743228E
+:10D520005FA6C59769F1655A7C99165FA6C597698C
+:10D53000F1655A7C99165FA6C5173DEF5EC6EDC929
+:10D54000D1429E1F24CF7F62B968C5E7C689E588AE
+:10D5500093ACCBB796D03E8347758DE47F6239306C
+:10D56000FC2CAF571DF9035C58E3A3BC335D039556
+:10D57000FCDE5C2DE2EE45FA37F9A340759A9BF28A
+:10D580009F8989792C8E8DA6E1F0BD3772B9361747
+:10D59000DFCBE3355F542639F6D1B5ECEEA12D058E
+:10D5A000BB448A1344384371824CBE0EF3F88EC7D5
+:10D5B000B7B7133D90302EC2FCB123D3531F21DCEB
+:10D5C000AB65AC7FF5B551DFE2147AC18889CDDB5C
+:10D5D000E1E276D41E7FC8D5338FE6E928D04A5BD6
+:10D5E000D1FF7C30B2C745B83F748D26EE40DCAF2A
+:10D5F0002EFEE4066D7CFCFB43D6F74BC704F26BB2
+:10D6000013E4F86023F74B8746F33CAC5D5BEC22F8
+:10D610003C878B5541CA21BCFC40A53CD01E17B7A6
+:10D62000D7C6838D09ED747F8CD9198008C3597AC8
+:10D630005DBA4971DAF16A2342E3D215E96DB2BBF2
+:10D64000E9FE804CB8FAA492CB13549C6C38CDBB45
+:10D6500057A1F7F3A43B1EEE453E8EA2B9F76057E3
+:10D66000961864F1095C07F0480ED1473F846D8F2E
+:10D670005F62F1C751087DAF97D66B7A54B38CECDB
+:10D68000DD4763C9CE310780F6789965AA3F4DBB67
+:10D6900081D111BE04AA80F2FB4646965FC6F656BB
+:10D6A000480F505EF56529544276FB53B153A3E70A
+:10D6B000EF1B0B18BFAF056EEBA4F024ECFF6E3B25
+:10D6C000F9F74E5DA6E8038E978B15911478FC59F7
+:10D6D000A3977DA756EA6789EFB38D1CBF77DB76EA
+:10D6E0000EE36937FA8D362222B255BE4671D2DB7F
+:10D6F000D63ACF5A72BECEF7E01BC447AEAECEA725
+:10D70000B86815C645119C7908F4D6909EAF0F48AD
+:10D7100014A20E68AF6A7CDF79E3E424262F3B8EE7
+:10D72000122F4E8DC7553A862414C7CC38DD179773
+:10D73000313F73CD19677BD679677B36B81CEDB95D
+:10D740008AB33D4F75B617F89CED4ACDD986561E63
+:10D75000972956BE0B897196C49F7D7122A4C86714
+:10D76000EB4EB17C30393EB3E53E909EE6572E3C01
+:10D770004BF6CE96F3DD42A86736F9B5E162E011CB
+:10D7800084E62FA60D493312BE73ADE17EA8CFFE0D
+:10D79000FB4516AF77F81767430AFAF653393F038C
+:10D7A0006209F65191ADFC529E346912F2D54E0BCE
+:10D7B0009612E7E1FA57CE5FCBBE9BB3E736B6458C
+:10D7C0006A8E496C3E3B2F9F0F0C4B7DF9D8918D93
+:10D7D000BCBE50D369B46E62F5340934CA437C1EB2
+:10D7E0008825E4E91994854A94871D999786E3BAB8
+:10D7F0003231DF463A73553ECE96AB52FC93D86C2D
+:10D80000A4FB8BD9CA19611A7DE78EF753DC4F79D7
+:10D8100058163D9DEFED3C7A207924E769A3D65850
+:10D82000FE7B2A4C257D9F83992FCF86785E6E7F65
+:10D8300067E7E514B794BBE2F953E99A1C2B3E8BDA
+:10D8400098645F33342D108641FD5CE99A147E6E36
+:10D850006D8D31650DD269F3157A89CE1C01CE48E4
+:10D860002AD14977131D0CCF783E374D89604A1174
+:10D87000CF1F2318EF6B8C9D67D2A7B075B29F673F
+:10D88000AB0C9DE8B55BFA59F93517AB8BE317B9CB
+:10D89000545F6BCF324F535D11CCFFDCD8EDB3C674
+:10D8A000B162E7F736927FB1DB556BBACE529DBEBF
+:10D8B0007D98D92CE0F89CA6599BF2C85E528D1435
+:10D8C0007F1F3C69EC37AD7A05F9B58C268DC75DB5
+:10D8D0009A687AB2E2712EF2574B7C1FD10E1E9DD0
+:10D8E0008D438CBA2F1C2339773D7E60D56594B764
+:10D8F000B4A012AFC0FDFD6D99D7F18B78BDA96BB7
+:10D90000E23780EC1EF2DC3B1AE74F0BF6B8483EDC
+:10D91000130A30E2BA9AEA879CBF15F910D10A803F
+:10D92000D538585EE4072BEF6D32634C2F722829EF
+:10D93000AFB3EA0DF06A51629D29292F4CCE033D09
+:10D9400045C3E6913DF45D2E810771896060F6C0A4
+:10D95000CE03BD10D277D0FA310FA4BCCE53243BF6
+:10D96000EC4546DD4DFA5AE217F33E0FCA3D7D57AE
+:10D9700014A692DFA0FA088EAF6F72DA978C629EBF
+:10D9800007CEC53C504A91071EAFD66F27B98E759A
+:10D99000F5AC22BEBB400C901FEADAF7747729C9B8
+:10D9A000EDA13E7C30398D7D47B5E422B2FAC254F8
+:10D9B0008BEFAEDAD0DCCD385EB7EA0B5D251E36D4
+:10D9C000BEEB3D3592C1F7FD814DD89EE1B3EA0B28
+:10D9D000182E52FEA1DB7243BF4BF5B79998CF5377
+:10D9E0007D6191DFD2C3C7BC4E1473834079BF5DA4
+:10D9F0001FB816E14D7EEE0E0B2F02F84D9A6F4ABE
+:10DA00002FB0FD3376786417ADFF80EC0A7033DCFD
+:10DA100097473DB02605BE3C2B8C792C6E58853C33
+:10DA2000E730BC3DCCF0AF48F3294F08FB0BF3685F
+:10DA30009F6560D847DFFD4BA3F15D8BCEDB89F995
+:10DA4000580BA6477C1FACDDA4CB649739CE3F3D75
+:10DA5000B16323E15C839E79C457B786EBC4793CFC
+:10DA6000133777527DA2AB4C6279D8B9E243770580
+:10DA700090A5EBEA9E7C11B709AC8CDCEBCAC176B1
+:10DA80007D5ECE9D143ECC552447FDEB96C7321CDF
+:10DA9000766FDDEE218EFE1B6EBBDCD1BF3438CA43
+:10DAA000D16E7EE82A477B9E3AC9F1FD02DF0C4722
+:10DAB0007FA536D7D15E5251ED181FCC3F2BE76AB8
+:10DAC0004C7E3F275C55ED1398FCE64C3ED43A4221
+:10DAD000E37122C5C11D99511F9D2FDA71A11DFF50
+:10DAE0007514185376E4C4EDDBB93592237E4CB639
+:10DAF00087BF5DC3E3E7A5855123557CDD672743D9
+:10DB00008239763CCFDF1B53E6EF8D6F39ED6ACC5F
+:10DB100045E3964EDB787818E9A1B996C59574E689
+:10DB20004D716579532D6D73985FBE91C230583435
+:10DB300073BB6C24DA318A1FB358FC789AE8669478
+:10DB400061FCC8F0C6E3C7AEE22583FA997730EFEF
+:10DB5000A0FAE95B9877D0F318E61D54D77E17F347
+:10DB60008E18CB3702AC7D18F30E7ABE847907BDD0
+:10DB70007F05F30E7A8A4DC0E4F2F79E6735F232E4
+:10DB8000A294D505DC4310BF55FE27F547A81E48D3
+:10DB9000E7422AE35F6922FEF3656B9F70FEFBE4B8
+:10DBA00094B40F3FA9D4BD4DB8AF96C91073955E1C
+:10DBB0007A3F21CEF2887E98FC02C4FD42DB965F5C
+:10DBC000BE39228FF2182FF30B4787BB79BE62D97B
+:10DBD000B1B47C6D2FC5DFB3BFBD1BC80FBA413BCD
+:10DBE000C1EA834D3CFF75B777327BB4E27999C5C2
+:10DBF000212658F62820B0B8FD1FDD2FD4905FC82D
+:10DC00001BD82FB8E1CD79943FFA4641C073752AED
+:10DC1000BF106C607AB3F4D560E189714272C8E7D5
+:10DC2000F553B7B689C981EAF559542F0783C94D11
+:10DC300046B9B17542BFFA3CABAB5E6DA9C2968BDB
+:10DC4000878D708C67EBB8BAAEC26CC0F90ED37911
+:10DC5000D034D257B9B99DE249948387FCC849D9D9
+:10DC6000514765C7AED85F6DADAFA63DC4E4320382
+:10DC7000E5427A947D4EB955EF0A31FF381DE9939C
+:10DC80009CA6FFCED9EF49AAEB37345975792BDE24
+:10DC90001BEB8AAD26791CB5FCE6D17DC76A26FD53
+:10DCA000057EF3686D48FA7282DF3C3A99FBCDA39A
+:10DCB00071BF397BF3A07ED370FA4D1FC769C6C709
+:10DCC0003CFE19C86FF6F397259176DA07B6BFECDC
+:10DCD0006AB2EA027911768F63B52832BAABC7030C
+:10DCE0003BDF39A83CC5F6B922F07DEE19F9748CFA
+:10DCF000F20F19E36D8A3370DFEFA47D6CE367B533
+:10DD0000CCED44821FEE60F8EA1FE7DD4DEF0F6AAD
+:10DD10004579B48FEDF835BCE549C77EEE1A67EF5B
+:10DD2000E763770A3C6E2E0D4FC4F973EA36D0BA1A
+:10DD3000324AC6944A281FAFB59F6D7B87EB62F6C7
+:10DD4000256EE7F9FABC846FE217D7F931CA37CDEF
+:10DD5000525DF796278F27CEDB3171AA5285FC1DC5
+:10DD60003959BB5F2EE86F8F565FDB934FF5ECA3FD
+:10DD70003901A50AE572A4A96EBF3CAEFFB89B6F3E
+:10DD80008FB0BA777878C0A2B72CE5B876ED951742
+:10DD900049EE8B0A2040F54086A084F3D92A88B248
+:10DDA000FA720DF4B2E74FAB8D1F93FCD283DB8187
+:10DDB000F9DB2DE7BC03F8A59F32FD24D9E5EBABD9
+:10DDC00083FFDEC4F639AF835CCAFEE28F3F6398FF
+:10DDD000236F384C74578AFAB0BD74CEA0FD3193CE
+:10DDE000E85E928E8FE30CEA0D768E05A21808236A
+:10DDF000DF0F5718BF247A08784D1D46B8E5B817CD
+:10DE00007C873F1370DDAF8A1093288FC972B3FAF5
+:10DE100077B27FDB5859F92AE7477513FF0DFEC328
+:10DE2000C7E9BB06C5CBE430F03D80A070119F452B
+:10DE3000BDEFBD44F8C23D7286EC99E27FE525B2A4
+:10DE40009B1F817286CE975AB2FE1B52F957CF792B
+:10DE5000C95157F450FE67F91FAAC3E71023F47B9A
+:10DE6000E1A2447CA5099CAF116B395E73A689AC15
+:10DE7000CE9F83803C91607F18FB769D5E209C3A0C
+:10DE8000FB9599E64681F8D2FAEAEF2F135F03F982
+:10DE9000FFBFF57327D5E5470FD2EF0E3513EE8B95
+:10DEA00020E4A3BAC057FD6372C30975209BFFF03D
+:10DEB00052FB5E4144A17399705169360C12C72818
+:10DEC0009DB50E79F7EB17C14875AFE84A6BBEEC0C
+:10DED00099217354199DCFF0BCB9A84663EF3D65F5
+:10DEE0003CBEF7E49B2CBEFBC0AA77BF63D5BB2921
+:10DEF0006ED2D97D0393D98F313D5F61F5BF732613
+:10DF0000FA3FF20373787DCFDCE1515BF2A86EF744
+:10DF1000AFAC7FABACA81E56890B4D25DCB76FE3C9
+:10DF2000E7E5D89EC0DAAE503DC9C903ABB313EFE5
+:10DF3000B34D5E6BD557D47FB3EA636E167F537AC9
+:10DF4000CFEB4DF92AAB47586DC5AD9A5B08BF239F
+:10DF50004596F7838A667F0AF707F4132E78EC9BC1
+:10DF6000749E670E4D67FE4A02F914F9BB7692253E
+:10DF70008ED7BC0698F47D8DC8E31E99FB973BB302
+:10DF800046B0F64EFF1C76EF4383A042EBBE2F6FE8
+:10DF9000F07AD23DDBF8FD8C369463CCD3BF5F9D25
+:10DFA0002DA7D1F96D4B9EC8D6883E2C487A936632
+:10DFB000DFC6FC629BBF702FF9B536BF9826E2FB27
+:10DFC0002D96FEEEF48A15A9EE83D9FD1A8414DA93
+:10DFD000FF9DF98B07C55187A5873EFF1008E9CC47
+:10DFE0007E69080DE4BB45CF15781DC4F0D13D9B7B
+:10DFF000C516FDB64C9E9F78035156770F8F9B3206
+:10E0000085D6AF1447E19497EE39C4E0B7F8BCF376
+:10E010000BEE66F25B6DAE4005D16BCB2C14CD04DC
+:10E02000BB75BB4DAF20F53DB8C6B5A2CD2F5B8FFC
+:10E03000A98B303A85DD5B66E1E43E6FA099C6DDD1
+:10E04000E773530D04DA864FF1138EDB4672FBBB88
+:10E0500066DD9EFDDB8B09B75F84B708B73E99E9A3
+:10E06000B545E7756A799C181152D0B7F17A17E96E
+:10E0700011F5A9284627C50FCA31095A80EAE06F71
+:10E08000C6A8CE18B6E2B4E4EFD392EE71B4643D04
+:10E090000054AF53ACFD17864E55C5756595A53B2D
+:10E0A000C6D9DFBFD564DCB736C18FA7158580DF41
+:10E0B0005FE17A768F1C1C87C9EB6F17D0C3E4E24F
+:10E0C0003387EFBB96AC74765E1C1E99BB27F13C80
+:10E0D000EFA025FF4BD14FE66F203E1E4FAA1396AF
+:10E0E0005875C2647A81755C9FE12D1B8F8F288BD8
+:10E0F000C7233B290E627147C4B738613DCFD9763B
+:10E1000054E0B80C233EF7A758EFABD6B881E6DD54
+:10E1100062F11BC7AB0884D7B6028E9FD0DA27AD59
+:10E12000FA9DC9EC42362A90EA1A1F54183F27FD7F
+:10E130006497713F963D3320190EB98AEC1CFEEFAF
+:10E140002847166F044EBDB689D75D4CA0F3A69D37
+:10E15000547761F3EE6071FF39C427F971B9B3D711
+:10E16000FCAC8CF9E9D0038144BFBDAB87E2854BA1
+:10E17000ADC3035B383DFB7E07B9F684FB7ACA3733
+:10E18000B3CD8CF1097435B7E3FBBFB4EEFCC7B572
+:10E19000CEBA73C13499DD4BDA794C62F76B06A2C3
+:10E1A00063D79DE1CAC1EDE05D497630F99999D513
+:10E1B00023627002C3D6894FB5625E9669DDF3AD06
+:10E1C00038356633DD2B4DB6271A449454F7EA935D
+:10E1D000F7A17BDC0E86A37384A99CFF3D2E6CFD0A
+:10E1E0006F59FB9B4D263B9FCFE7F70A83C07047D3
+:10E1F0000125E5458229B2388F2554C3AC523C0B2A
+:10E2000032F1CD3076B4C7F4972CFFCBC89A3227C1
+:10E21000AAB2F58EB885E79BF9D02B501C7E252538
+:10E220007AACA4673CFB19D21BA9366D5C83A3C7EB
+:10E23000AD73EAED527AB7F595CCCFE3DB1481F0FC
+:10E240001EFE0AC6E9D84E8FFD333BF7F53C1D0193
+:10E25000AABFA75BE709F034B07B0EB32E2C520A9D
+:10E26000183E469526E2E389B5CEFB094F58FA6879
+:10E270005517B3753D91CFFD6A099CA9223EE179FE
+:10E28000517C24C5B9DD136B0B1C7956E0797150B4
+:10E290007DFC54D02BD7511C437139763694B95339
+:10E2A000C6E399E9212398EA1C449853BB6E727F18
+:10E2B0009C01DD52413E4BFC3C5EF95BE12D6F9DC4
+:10E2C000C6E474693B7097BE87E8515D28108FD310
+:10E2D00092E95D2A6EC3B891C589E60E195ACA58EB
+:10E2E000DCC8E2C8ADA647A57365EFC4DB1EA67601
+:10E2F0000DC691946F7F590A65CE45BDBC26862612
+:10E3000010FEFAF6A9784099847C7DF5DD999B5B37
+:10E3100071BE5D94DDB3FBF85F7B2A86B15C97101C
+:10E32000CBA7F1EE49B085FD9D861CCB4F8C37BB4A
+:10E33000267A56A7C2E7B7D7737F344FF232F97502
+:10E34000E55BE72D60885407F18C9358BC19BF1F1B
+:10E350008CDE059F5DFE255CDE35F80EF3D9B1C07D
+:10E36000CFC78FDC066A989D8F3BCFBD29DE3C333B
+:10E370002C9E8F3F6EC58F03E929FCCC0B6C9E96BB
+:10E38000C0535EBA0FD19D1FDD558AF4BB7F25C1F6
+:10E390008E04DC7767F2F8EAD0C49FC8A7F0F9983A
+:10E3A000858B2BD7F37A737514A543F77703B335B1
+:10E3B000E25F1E207FF8781DF79F595480A2FD313F
+:10E3C0005E6279A87D8EEF29D9CCCE65ED73F769B1
+:10E3D000EBF97E1BE85C77FFFA4CE7797BD2F97AA0
+:10E3E000435D738D8A327D7D9D1587F49DB3C7E6AD
+:10E3F00051BC34040CE6A7AF2F962056007DE7F5FC
+:10E4000076DD3179BE6A3A6767F70DFE7F9EB3DB32
+:10E4100072B0E568D79BDA7CB98EF373B79FD7A942
+:10E42000D6D61827C86EB9A96E42F47C1ACB0B1544
+:10E430003F8F73EE5F165653ED97E72A8CF7D6257C
+:10E44000D84745E3F74DBAB7EC71D4B58E4CE4F735
+:10E450006A565F1BCD4F8CE76C9C7559F15CD700F9
+:10E46000F1DC3516BEFAECA257B4FC6F7415EDB3AF
+:10E470006EFB7EB0AE6BEA94783D05EAD5189DCF71
+:10E48000C1A6AC00D9AD366B9FF9E46076AABF5740
+:10E49000693BC8EFE7812F218E29A47957A71CDF9C
+:10E4A000F79D45B7DDB2BF2D81359FCBFE3E5C6148
+:10E4B0000C594FF9B8CF697FD3B474C779D4ABB4D2
+:10E4C0006F52C87F6365E565EB87B23A3AAB7B363E
+:10E4D000F8D1DE503D6DA6DA4671538B003C6EBB21
+:10E4E000443DA83B2722D33DC5B9FE2765B22FD5B1
+:10E4F0004FA39DC874D809E6E7F6AEBB7D33C59D32
+:10E50000BB1E3AC8EC9BD92A44460B5477EA667A7C
+:10E51000C06D56EAC9EF3FDF63EBB99E617790C9E2
+:10E520008530CBEC6292BE84C07246F7210C34A4D5
+:10E53000E1C49F3185E4035BB93D6D0980F600B30A
+:10E54000A7A194F72007B9573293E4F4FA3AE0F917
+:10E5500086FF1517D5BFE2F5C7203B07ABC26FC3D7
+:10E5600029EA91D510B3EB900B88CE7568C0462090
+:10E57000FE5EBEED11184A38B3EEB52AF13A640DCD
+:10E58000AD5BB1EA908AC6EB900797DD24B6135EC7
+:10E59000FD12F32B881A66C7B35E96A81637204E75
+:10E5A000A2549F415CFDD0AACF4C945549453D4CA7
+:10E5B0008C39EF0FFFB0C25845F38E977B45EA9F29
+:10E5C000F04CAEA3FFFAEAE00DEBF9BD0C5607FDE7
+:10E5D0003FB89FBE42FCFD15FB69FBDF623FDD3F9C
+:10E5E000ACAFCEE7A53CD03D491777E3FA8313A43F
+:10E5F00008D58F8FA01F63FC043C11265C19D87DC1
+:10E60000D5EE92CBD8798A0BD59D9D1B8F533CE7D5
+:10E610004739EE2B253F3DAE90AAA6E067FB3A674F
+:10E62000FCEA393F86D139E2E2FB89F6B23483F85D
+:10E63000E5ED867C0BFF497A6F5056F1FB7EB8FF03
+:10E640002E1B9E82FFDDAA49F79B6C5C7820D0EEE2
+:10E6500091FAEFCF67AB8CE87A7EDEF69890505F48
+:10E660006F4233C2EF673BE345B5527F9DFC8BBDE4
+:10E670006F4B20907D738A38BDCF9F299B8BCB1326
+:10E68000E4D4961662E7F1847792C34EFBBEA6DC13
+:10E69000232E43FCA9C4203BB4EB61FB3733763512
+:10E6A000CB37A4E2804E7F1F9B591680C473F519A7
+:10E6B000F3E6BC48F8C8947B80E49DA959F7C6F4FA
+:10E6C0003246C71E175BEFFCFB3CBB8E9ABCDEDFFD
+:10E6D00058F9CEDB774481F2818CD8B36CBF64DC0F
+:10E6E00021B0FBAC6E5ADF703A0DB3E6F195B1B6CE
+:10E6F000E6E5F5CF0E73143BEFED2D16B3A86E389B
+:10E70000EB4276D6347A6FE543F63DD3E479ED7C7F
+:10E71000A8D7E4E7E84F14F37CE809F94C7AEE2037
+:10E72000758BE4FCC7931EEAA554F1FDF5FFBD9976
+:10E73000FE2ED663E5CB7F78577D9AF2A1858B8C30
+:10E740000F49DF6F8BA0B3F38C11C0E2C8869D5FC9
+:10E7500029A12B99272BF4D1CD28179F7D8E31C06D
+:10E76000F9C587EBC1F2FF992C0F3A67F27BA61D22
+:10E770002E83D96D7315C7713F7B056A8CFEFE270A
+:10E780008B70A926DA2BC3CAAFACFA6F3D688979C2
+:10E790007CDBC14A86035C56DC6E7C0EBBD562D145
+:10E7A000DF69D9AD36BA5C9EF7B9EC561EC941F6A1
+:10E7B0003AE5ABE43BF33094D7501A3788FD1ADEC4
+:10E7C0003CF9AFB75FB84F3FE47E024C614A8A7DA7
+:10E7D0009AEF9457870B9E1126E0FB392ADB4742BC
+:10E7E000F1E1CFD8794D1F5D0368FFFF0FA1ACAEFB
+:10E7F0006460410000000000000000000000000014
+:10E800001F8B080000000000000B53E16360F8510B
+:10E810008FC035BCA87C42F82989EAD1F17526065B
+:10E82000066666CACC00610334779C636760D0E4F7
+:10E830006660B8C2C6C06009C45C40BC8B07212FAB
+:10E84000C201A1BD041062FBF82877C7281EDA5860
+:10E850004D9881415104C19F27822AAF2E8C602F91
+:10E8600094A0CCAE4D40FD00C0E9C2CD80030000B5
+:10E8700000000000000000001F8B080000000000E6
+:10E88000000BDD7D0F7C54D599E8B977EECCDC998F
+:10E89000CC2437C9244C4212EE840402049DD0805B
+:10E8A000C1E27A13A3A6FEE83A5AEAC616BB03B23F
+:10E8B000D66E591D2DAB54D1DC90FF21C08808C104
+:10E8C000BF03A8F55FDB68ABB55BDB37A03F97F60E
+:10E8D000F9DAAC6B5975695F2CAEAFEEF60FAD4B44
+:10E8E00049DF6279DFF79D7333F7DE4C825BDBF73C
+:10E8F0005E174B2FE79E73CFF9CE77BEFFE73B67DE
+:10E90000FCA11A563B8FB133F8E742C68CCCCD9DA3
+:10E910002CC25880C9F16178AA6AFCC83AC6D800EE
+:10E92000FC652B19EBC76705FC8D9650F9F680CE78
+:10E930005819639E2AF92D7F2163DE508A25E1D57F
+:10E94000435F7CEFAD8166C6CC7DBEF82350FED21E
+:10E950001D57BD897D1C7EE0D1BB2E817E1FDE52FE
+:10E96000BBCC0FE5CB99C4D872C61E0DA7640DDED3
+:10E970009B7D72E61178F570EF956F32F8FEE1DD60
+:10E98000B2CE62F8AC2D6221C63EC27CD4BEEF810D
+:10E990005BDEF443FDBC34D317427D5DF663B21EEB
+:10E9A00066AC724261AC34379F47BAB2A7DEF6322A
+:10E9B00096E93A72EAED7A68AF24E4007CC776B350
+:10E9C000A647E0314F4DF2F2A82887981C003898EE
+:10E9D00029CA9AC6CBBD5086793CDE354EFD600310
+:10E9E0007505D4E33FE1FD82DD308ECAE8CF19F82A
+:10E9F000BB289D96D7353216338F38DE2F7E18BE52
+:10EA00006FC895E731E5DF27AC32CC6302FF01F830
+:10EA10009C37CAE7B168D287939E365F6B5ED6BCDF
+:10EA2000FFD4E677F84773BE87F4F1302B4AF891AC
+:10EA30001E7AD7D37A3F32CA68BDFDC927399D985F
+:10EA40004087F0C9A9B7F653F94B77C8F16E282F64
+:10EA50005013C145344F99E13C1684983106F02C8F
+:10EA600050E00974D225E82A8B4F18EF21F1D459D0
+:10EA7000EA4D1CEFD12D4C1F9610AF570D2F82720F
+:10EA8000DD6B1EB610E1CDFE56427C5AF4633DF5B7
+:10EA9000511FCB7E6466BAAA531287FD36BCD7A934
+:10EAA000495E1678AF0BB1C37E1BDEEB348D975DEC
+:10EAB00078B7FA9F86EF2D80EFD0747CBBD7E983BF
+:10EAC000E25F674630B114E691BEB28835221E2E51
+:10EAD000699B084D9F37D261B614F17E424A847219
+:10EAE000F3B6F0F4A73B7F4E07FB910E6244079705
+:10EAF00035349F9D0E2A27FEABD1C1EFC70F286783
+:10EB0000B3B3C8D93F153C607BC4837B7ED67347C3
+:10EB1000977EB20EE6E537830CF5E2B6975806E924
+:10EB20006587A2FF532D9477C465EC01BA31FE319D
+:10EB30005ACE5084D1B84B99563A5FCAF553D40295
+:10EB4000FDD8E0B0DEEFEA029D0B8A706797CA8CB1
+:10EB500085B9F7696F268AFCD6DC70DD6A760E947B
+:10EB60007FC7DEC2CE879B7CFA56E87769FC9D633F
+:10EB7000F85EF38F6F5D0F708CB4AA89AD717C7FE6
+:10EB8000DDDF30D0C3A1CD9F2E7EDBB63E235ED627
+:10EB900089F291295E02B2F17A6D3FAEB7C4943723
+:10EBA00024FCBEAE3C86E5B9924C72938D2B3F9906
+:10EBB00000BC36C07F676A196B62BC6CE16D67D3BD
+:10EBC00081561CB711E0611AC2C1DE2DB2C157DAFD
+:10EBD000616BCF1F2CB2829B0E889FCA863DDDF3EE
+:10EBE000E1FB5F4A2CAEB520BEA0BD6D5D8A6A32E6
+:10EBF000D2B5D0DF909857E598AD1EFE56D45DF59E
+:10EC00007909E6C936D8C64138616C84FF7BAD3ED0
+:10EC10002301DF8F8CB18C5F9A3E9F1165F275A442
+:10EC2000B7C6453EDD8C4D9F9F1B5EF77C8A6AD23E
+:10EC3000DDF3A1FF41899DD8AA4D87BFA2C1B74E80
+:10EC400046F8C69CF055E800F739D3E1B6E8F0BFC6
+:10EC50007569440787BA1A882EF6415987E7A1F7E4
+:10EC60003D9DA8D7746C0AE3DEF5927E00D76B8ACF
+:10EC7000EE24DE574AE27AEEB097B7339F659947A4
+:10EC8000009E811A4EBFA3EB16ECF7C47274312AB2
+:10EC900031EAF7E68B777D0CDB8FAE952554951521
+:10ECA0005E6D2DB6DFDBBE80F0339ADC75A81ECA20
+:10ECB0004DADEAAF3D30DFD642E3A20DD85F858788
+:10ECC000E1FA54AC7D55BE0EF9B7658E5614857ABF
+:10ECD000BFF633A487D18B393D544C96331DE4E6FF
+:10ECE000D276DF5B8897A5494EA751179D8ECE48F7
+:10ECF000A7916312F6D7CEE9F426179D1AF01FE20A
+:10ED0000F19BEB0FB46EB0D1A57B5DA7E06A05B8AF
+:10ED1000A06C9C3E0B9D26F71CAA6F9E994E57CE69
+:10ED2000CB481BA07E0FD2A996874E3B675F6FEB47
+:10ED3000F93DAFDF48203E5DF43A35AF3BCD8F99CA
+:10ED4000509F7E5A6188CFB3D1AB7B5E156B65D384
+:10ED50007F4E3EF8D304FFDE56D540F8A7D1EBDA5C
+:10ED6000FC7C66C17D7757861DF7A29C8C12DD0E58
+:10ED700077E9F41C11F4BB0B9B564C97ABDB657623
+:10ED80003DAEF3F620BBFE195CEF8E6579DB594F83
+:10ED9000C6BA69BD77205D9F4F60180CD6A3683551
+:10EDA000FCAB92CAD9601D8CEF9D2A1BAC0AFA9766
+:10EDB000A6CAA018182B583DF5BD5900ED77047868
+:10EDC000F9C7DDD156B32A579EEC2E6A35574DAFA1
+:10EDD0001FF68E6595264093F4BAD11870F46F60D3
+:10EDE000FF76F8D455D3FB1B0EF0F621B980FA1B41
+:10EDF00092B251E6114FE0A36F48CC688F62BF50CA
+:10EE000086F57861F49FCD9756DAC6317F6E6481BE
+:10EE10005F07E4748F9D8FDDCF6592F1825486F099
+:10EE2000643A8158D82BD82F8C5FB08AF773587A00
+:10EE300087F5D8F075B4FBDF4D840FD114027982C9
+:10EE4000A480728075703F0FF076E8B3407F211484
+:10EE50003100A71C8732D04DB1A1A6FC50D6DA955F
+:10EE600077EC746FA7EF7CFD15ADE6DFABD81F54D0
+:10EE7000829747FD9FB53FF1FDCC74C2DB2D931205
+:10EE80002F48402F03BE748F0C787A41E885B6F383
+:10EE90005B7EB00AC60D8C7BE3E87F06564F905C24
+:10EEA0002C02770BF1049651F642D41B31961A8648
+:10EEB000F2D392CEE58C928E26C2A8C72B59C606F5
+:10EEC00097D5EF1F1A6F00FF495C3F6B9DCF361F30
+:10EED00015E703A0AA389F66DB7C14980F8C3F24AB
+:10EEE000E693B3479CF3180E989D09E0C3B6C52D71
+:10EEF0009733EAAF5E2639A464A8BF11AF2E0F176F
+:10EF000083FE94B95F65E1455D9DA1FE0BC090C491
+:10EF1000F10A1A9CFD5AFD01BE993F86F8E6FD15DF
+:10EF2000207CC5D47F7E7C33C0F7D2E9FDBD27E0CD
+:10EF3000D9046098F83DE3E35BDF5BDF59FD58F3EC
+:10EF40009DD6CF2BC7A7FAF1D8D6DD8D270908D3D8
+:10EF50006E1FBAF1763678ACEF7E5F78CE362F37FB
+:10EF60003CC5938B9801FAF46E7C01F427DFA9125B
+:10EF70007D0F7772BD327CE462F2F7EE92334790F8
+:10EF80006ECC57BD0CEDEDBB500E0391B2D5CBE866
+:10EF9000BB798599E8958D33CBE1BD60B79AC040C8
+:10EFA000697866E0392CEC88B4717337FAE97B989C
+:10EFB000F62B4F9CE40BE973AD75137F6F44F9FB9F
+:10EFC000007F7F57FB5667FB30EFA7F8E25E477B79
+:10EFD0006BFCE85AB0B7F3D8D1E53EB62E91C77FA7
+:10EFE000DD22CBB47EDF44FD04708E0AFD541E4C3E
+:10EFF000AE43BC683541FD00E065CFD52B2AD7C3B1
+:10F00000F707B72F90D7035CBB646E47A5857E3B9F
+:10F01000BCBD5C42FFB8D8609282FCBB16A535F43B
+:10F02000EB4D7517C2FAA46466A400AEE29F9A572E
+:10F03000A310E8925B243F7C5FD10E6568F9E5E19F
+:10F040000BA5BF5F8E6546F276B77C792BCADF8150
+:10F05000EFDFDD83706CFA17680543AE54D29E145F
+:10F06000AD43495E7D78F05FD4CE0CC0B772A47F0B
+:10F07000FC1385446F0E7A38FF6DA0079BDEFFA658
+:10F0800098EFA898FF5F023AF2C9E5952A974BB02E
+:10F09000F4A91E80B7B89DCBADF3414EA1BDA70D1D
+:10F0A0003AE514C07D911DEE3F14BCCB501994E598
+:10F0B000FA03B9B7575E8EF0A43D38DEF98AC51F52
+:10F0C0004EF8B52D3ED35348CFB73CE7E48157CC3B
+:10F0D0001BFADB9FAFBF3FD67CA0DF1789AF3F6431
+:10F0E000BFC5AE7E2FBAED7A19E1DD6FCA1994ABB8
+:10F0F0000FFAB46003C64F8F7A281E06261AC5770A
+:10F10000DCE354A71739FC76F7B3ED966810E97C79
+:10F11000BFC9E3420FDE565999B4F1D57EC1CFFB8A
+:10F1200005FFFEA3E0937F90BDF4FCA1283F5808A3
+:10F13000F65D1E7E646CAB25DFE9D93819A2784AEA
+:10F14000AEEC7395799C21572EA4B2D9C6F9D0ACF8
+:10F1500064F11E1DD733C592008FBF8A999E7361DB
+:10F160004D9187B8DECB34027E14201495E4FBF871
+:10F1700097B1EC45DEB7957D60734523B932F4C392
+:10F18000745BBD05FF502C1D0DD9E4625FFD9ED759
+:10F1900031AE11D4795C56CDEEEB5C8FFA738B2FC8
+:10F1A0008EA69EAA9B2C09764350893319FDA31085
+:10F1B0008BE1FA045583C9182CD0A00CF007430941
+:10F1C0005E8E887A2DC9DB477979E8FD2F50D9AC5E
+:10F1D000E6ED5FACBF8ED67F48AF3D80EB3FA42FFE
+:10F1E0002B9211DF423F0F4AC937E532F4774D15B4
+:10F1F000E900DACD4123E44DE403C2BFF2BF913F01
+:10F200003C484FF87F2CA4BDB344D09707EDF82CB1
+:10F21000C55F06453C6704E3315EC47B264B7E65D3
+:10F2200021C73B98DDB9F80BF57324176FA1F2B82D
+:10F23000A35CA09906FA714A84C53DF07DA83DCD36
+:10F24000701DFD515EC6F5F317E5D66FAF6BFDF689
+:10F25000BAD66FAF6BFDF6BAD66FAF6BFDF6C6527E
+:10F26000158EF5BBE696379CEBF7C537FEEA8FB0F7
+:10F270007E7B5DEBE7E68B1F287CDD1EAA5E4FEBF5
+:10F280006A5E2D93DFFEE21DFD541E5E2B93FE3E53
+:10F290007CC72DB44F72770B2F6F50E613BF0D77DD
+:10F2A0001E38827EEA7B47BCE4FFD5B2F810C65711
+:10F2B000B6BFF2576C38CF784F60DC89FC35EEA7CB
+:10F2C00059EF5F5CB4A068C2869F6DC24FDB26FC1D
+:10F2D000B4B6737EAAA27CD8D17C25EDC7947838C9
+:10F2E000BF0F437F18A718EC52E98971AD24F47F52
+:10F2F0001F9493507EB84BA3E7B3A087F0FD035053
+:10F300009F85E7DD0D7207CABD47A11D961FEB0261
+:10F31000930AE86D7797FA9E427EA546E56F75459C
+:10F32000A99CE9D2A90CFE253DBFDD15A7F7DFE8B2
+:10F330006AA1F2F9F295D778D02F5D2D13FD54DE36
+:10F34000D17000EDE7D2989CC800BCA51F5718D219
+:10F350009FF57E4A6ECB6DEB3D80FFFB1B1482E771
+:10F36000FE946CB0FCED3E8BEDAA620AF5577593E6
+:10F37000624891BCED36221C8F34C2FC306EBE5BFD
+:10F380003667E8EF266C575F0FF0C1B8F5F728E64F
+:10F390000CFDDD82E33ED7C8E17BEE7539CBF2B7D9
+:10F3A000BB1DFB5B51CFE15BF186929D61BE26F6F2
+:10F3B000B7B884DB4DB07AAD180F9BB3562BC1FDA7
+:10F3C00096C5A5EC26FE7EAC1BDF17B7F3F74BB056
+:10F3D0003DFAEBCCD88AFB4A251DE23DB6A7F7895A
+:10F3E00017713FA974B5E847D865F75CC3C8BE2D4F
+:10F3F000EFD40EA84032DB4579CE5A7D3F9617FBFD
+:10F40000F9786597689204FC56DE9E9424E82F0CE8
+:10F410006519CA4B7CA9560579FE334C3E009FDE28
+:10F4200073992E4920D7CA3B78BBED5096A1BCC436
+:10F430009FEA4679A2FD25B403BA2FBB3C4EED8668
+:10F4400085FD13BE3C7908FB29EDD42555477AD5B7
+:10F45000E9FD9CD52909E567F9C3492908B2A60346
+:10F46000D40E860A866F6264AF3DD6F33AF9EBE5B7
+:10F47000095EF6294B0E9B603B2CAECC109DB12053
+:10F48000D31F013B62F1DC89518C5BB2277D14D71D
+:10F490005E523991E9C1F213418A6B2F993BF1D841
+:10F4A000416CFF551F950B3FFAC262DC477BEF951D
+:10F4B0008BE624F3D8DB4B1E03C3D2A6F7DD7EC355
+:10F4C0009CDE94A402BC1101EF20C27B3E63DFE905
+:10F4D000394EF0CE89F3F2CF3C7338BC35A613DE3B
+:10F4E00079E39FBE316283B766FCDA9D111BBCF3E2
+:10F4F000C63FFFD5E61CBC179C12F02AC61CED03C4
+:10F50000C01BD09DF0FE5795EF7E3DC55A1B51CED6
+:10F510007B08DF3F50F6759B219A9F22813DB257B1
+:10F52000D84BEF2926C9814D01BD16FD450BCEBF35
+:10F53000F770F9BFB88625D16E5A7CCC67969E339A
+:10F54000B39DB6781E4B61BB253599C3DB11AE3632
+:10F55000F5A64700874B8E05CDD2C299BF5B82DFEF
+:10F560003562BBD05BF6FEBF8FCA77F9D9D76FC7BC
+:10F57000223E9F1D01EEA7055536A895D8FC5CA13B
+:10F580000F1657C23C1A911FC6FEF906073F8C1D85
+:10F59000DF61E387A771DC32E48BB17FFB8A8D2FBB
+:10F5A0003EFA4B4E67C3027F961F09F8333E10FEAA
+:10F5B000263F30FEB6EEB4E36FF203E26FF2F7C31C
+:10F5C000DF1E9C0FD0FF9EF0D47C488E9F753E13AB
+:10F5D0001F783EF20EFB7C263EE07C267EBFF9DCE7
+:10F5E0002DE8E16EAFA007E56CF470E275A77C3CF6
+:10F5F00031D193971E4EFCD42E278B2EE4F4B05DB0
+:10F600008CB75DE02F1882F196CD365E76EE8D8E4A
+:10F61000F1B2F377E61D2FBBE4ABB6F156BDC7C719
+:10F620005BA8FF47454D33DA293E8C71B061683BDA
+:10F630004EFB133AD9D387173D3A8AFB605FA80E79
+:10F64000523CF1D0A2A32ADA4FDB572F23FB68B03C
+:10F650008B9DAC237B25FB9B8DDE1C9CC3AEFD3EAE
+:10F66000F77358E6FED3B088CBB8EB2DBB6B30CE2A
+:10F67000ED2777FD6185D73325558171CB709C9D32
+:10F680006CCC1337B1E0B2E0FCB0703D2FECD8C1C8
+:10F69000F856ED22D03D3B7B2FDDAAA27FD2BC2BBA
+:10F6A00081E5EF98976E6D97FEDFC37540B9C20193
+:10F6B000D7E3EC8AFF2FE07AB6F7530EB8B6999FDE
+:10F6C0009A15AEBD22EE36137DBCC5922568E70DB6
+:10F6D0009403DD8672745B82BE19DA938AE6A01306
+:10F6E000B549213B74A8D949575B141E47B39E778F
+:10F6F000285C3E84EB15BEE97D8D2F531FE3FD5C36
+:10F7000009F6D641EC7779AEDFB4AB6CF99FE88EA1
+:10F710009E998F65A7FFA94E16D07E616832404F33
+:10F72000F7FC06855F32D2E4137EFE820338654F14
+:10F73000284BFE7871A35EEBA17D311EAFEC6B7A96
+:10F74000D498E0F289F28450BFA35DCCDA79BE414F
+:10F7500041F66AF24B8350C694366B9CE206ADD5F7
+:10F7600020BC99D12B6D79108312973F961D53AC15
+:10F7700097EFC7F1ADFADF093C853C5C2E8FD4A62C
+:10F78000A325367C0EDD9161682FF7D5EF21B802F5
+:10F7900002AE800BAE20C205FD07DC70D5CD0E9702
+:10F7A0001B5F161EACFD85F0E412A697227E17D1D2
+:10F7B0007326FA1D11F4BB7D39C773FA020BCFE330
+:10F7C000B47F5EDC0178966C785EFE0ECDA750E4C7
+:10F7D0006115E27C22B9F99488F914E27C6C7C55BD
+:10F7E000DC02F321B97A227AA52D6EB553D0F71435
+:10F7F0009E57953BF6AF9778399EC31EAEC7B6D7D6
+:10F80000B20A3B9EFB5A7D64FF157670FBEF0F0D2D
+:10F81000D7CC78CED03304BA7315E8A750F362A6DC
+:10F82000DBF46889D8F72E42DC5580BF2CFA6318C8
+:10F8300094B7C507CFF3CA8E38E0D4FAE13F914EB2
+:10F84000127C7F1FFCB1EE1E80BF3CEED3873128B7
+:10F85000AA5CDC8DFAB3EC053F1B8E6388B4BDFB5C
+:10F8600045687F97A126B0FC296FAD8013D674053B
+:10F87000A51A32867CE8F959671DF6F3170AA378B2
+:10F880000C5B2921DE4F6EC6DC0E842F9277FFAD14
+:10F890009CF9585615FC0C738AACE1656BBE0CEBF9
+:10F8A000B9DC7A1BF9DBCFAE2E4AE4C92BFAC0FDD6
+:10F8B000ADB6956DFBD16E78A7F50BE26A6EC97F88
+:10F8C000BEFFCF7AC391770AA0701E3B8FE25A33F6
+:10F8D000E0C1BD4EB1490FC92F7D52A2E73C21D7EF
+:10F8E0006A845CAB9E2C25FEAB9A2CA6E7DCC9B9DA
+:10F8F000F4BE72B2829E1593F3E9199D8C0979B812
+:10F90000849E05C8B7F0F409FA094E7E84CA81C9FD
+:10F9100026EAC78ADBB028A72775F2A354EF9F5CBD
+:10F9200049F58C7139B96BA55E3B6CE7DFA61564B0
+:10F930008F86DB597C21AC7F58F04BD8C52F854290
+:10F940005E86DDFCD26CF18B5E61E7975D6E3E6E8C
+:10F9500071CACB2F093ACFC9CB6C14EDC45D1F5BC4
+:10F96000D064DAE45EDFC716103F87139C9F67827E
+:10F970002F22F87966F8261C727387909B16BE6654
+:10F980005E578EA791A6E788CE7C20163D60B76BA8
+:10F99000CB36460F426DE1B2771A5E84F1CFF52681
+:10F9A000BFE245FDC826E20701CEFB6EF8D768929C
+:10F9B000F4D51E09F9B6D0C7F71D762CFB59FC20EB
+:10F9C00051D938437E80EF9EF5DAF87DC75F05AFE9
+:10F9D0007E146AF55ED9213F6AB680036FB303AA2D
+:10F9E000369538CA951B2B1DED9174510E91130D50
+:10F9F000741BDD50EB685F1077CAA740C33247BD68
+:10FA0000157FF7EBE73BDA55207D97227D4A429F31
+:10FA100014D0D3A2CB02A4737B1E9AD027169E19B2
+:10FA20001B233D3214E374E80969D2FAC6E9F8EE03
+:10FA30005B7A0BE915BF586FBF6BBD55418F7EF7E1
+:10FA40007A5759EB9D76C8EF21373DBAF4F76F85A9
+:10FA50005E29107A655BEDD8EB68E70FD5BBE851FE
+:10FA6000C4FFE1AFBE509A19BEF059E1CBAFC73F1A
+:10FA7000383DF633E497B4C452B85FBA6D697F1667
+:10FA8000E1F5D52A542E3877247B18632A6D7C3F04
+:10FA90000FE8CCE383F96D3B67387B00DEF7AF0BF3
+:10FAA000D1FB427D9C0B454127A4924A905E9CF479
+:10FAB00057100FBAE883CB3BB32DCEF70796F1FD75
+:10FAC0008160648CB6BD820D7C5F2614E7F8DE5E33
+:10FAD000C1E33E058D3CEEB3BD82C771A01DC57D5F
+:10FAE000ACB2354F284743367DDBB7FC28E13D30CB
+:10FAF00015D7196298A76AC573024A96C767E23C90
+:10FB00003E1350C778FCA691C773B6BF7F90C7E37A
+:10FB100017F17A4F88AF57A8516B42BDC7B404ADF7
+:10FB200057A0416BC2F8F9421FA787CEA0711EE211
+:10FB30004D7F8DEFABF7AFE5F9A0DB2B5E8D627FDC
+:10FB400027759F86F9EBDBABF93CCD1F49A49FA33A
+:10FB500075498951A83EB5AE1B10D2DFC5E3DF7BE6
+:10FB600063B79CBB1ED1A7A4CEFB846DFD8F16246A
+:10FB7000C3388ECF97CC74433F9B8FF9E35BA19939
+:10FB800054B979E104C559AB34D2478CDBCB161D8F
+:10FB9000AB752C83741CC87E8CE613A86271B41BF1
+:10FBA00071671ED7C557C7B427B0BE8EB787BA03D3
+:10FBB0000512C633E306E147E7F851B01EE9B54A3E
+:10FBC0003B88F9263E95E38345591CF1E515DFFB9B
+:10FBD000A2BC1E63A9581E11F13C8CCFE1BA8ED88D
+:10FBE000E2779AAD0C7F1A304EBB530AC691EF47AD
+:10FBF0006259C7BEDA484CE2F6D0E917A36B6C78BD
+:10FC00001979FF3DCA937ABCBAB1A77D25D2FD828E
+:10FC10002292ABDE6C54CB638FF5773D56AC7867A0
+:10FC2000E69F7E4B1E09FBCEF21F008F3ADA996EDB
+:10FC30003CF635ED99C2E3C23F221EB7211EA51C3A
+:10FC40001EB721DEA41C1EADB2358F6DB13107FE8B
+:10FC5000B621FE904E4E7F2DBAC626F7B62D7D39C1
+:10FC60008AFBB9DB108FC0EF77FB008FE7839DA283
+:10FC700070BEDD56C7E248EF8A66B27CF168FF6667
+:10FC80008FFEB6CD1FF3ABA92398075DF49A87A129
+:10FC90005C2C4AFF2AEBC1F901BE1E21BA4B31FB95
+:10FCA000F801102E68572D8427DA5D5E3DE8B0BB61
+:10FCB000FC9B7DD47FFAFD6B75DC9CD4E424E5C706
+:10FCC000750693A33EB40F425C9E04421943223A48
+:10FCD0004ACA08F7CE23DE0CD2D146AF711FB6BB9D
+:10FCE0003976A203F178F3053233E1FD4E5DEEA0E3
+:10FCF000756629F99908B62FA3BC520BAE7B057F18
+:10FD00001FF11A07E9FB80FB7BD691CFAF3AE0E306
+:10FD1000764B1AF373A13EDD7A1DF1EB4075C332C9
+:10FD200094235ADBF5A3EBB05CD3B80CCDC6AFF986
+:10FD300024E10783BE5F4A72F86B3E9BBEF7574DC6
+:10FD400010DEBFE5D3091E9F92CA328A87C719AE5B
+:10FD5000DBCE0B38BDCF44CFBECD4F152BA5240F26
+:10FD600048DE22FDE03C7696717AB2E2EC3BCB387D
+:10FD7000FDA0DCD06C65AB9F9D65279CF2F682DF11
+:10FD80009C45DEA6B87CADE2741F70C5CF77BEFF80
+:10FD9000112A9B612E6FDD703F27F0E8966B9A2148
+:10FDA000F8AB01E41AEA876C05ED0305754BAE6507
+:10FDB000881FFD0D20D784FEC0F6C13AE0C718E9C0
+:10FDC000E36E82A38E8F5B2CEA559DF39B5FD5BBC0
+:10FDD000B13F8B5E4B44BDC5AF167F0F2DE2F8439C
+:10FDE000FEA43C82451C5F885FCD56B6E4DA00CAAB
+:10FDF000358CE32C4A3BF0383425D7EE76C8B5A1D4
+:10FE0000F7BF40FCF8F8FD5F24B9067606ADF39025
+:10FE1000379D57AE0D9F45AE0D4FC9B514D9159AF4
+:10FE200091E672AD11E49A84F10EC06333EE2709B6
+:10FE3000B956FF9C41786E04B926F432960B748E45
+:10FE4000C780C20ED9E55A7123976BC1068127C4BA
+:10FE500023C733C9B512511FA873CAB5C1A51C8FDA
+:10FE6000B84E88C7C1A51C6F8867CD569EB28396D1
+:10FE70009A0EB9363825D77A1C726D30B687E4DA17
+:10FE800020E211F443E300E0B112E51ACF13198C1C
+:10FE900073B916EC183330747536B936A0F3FD6DAE
+:10FEA000906F0CF1EF4F4B86901F24CF42428E2D66
+:10FEB00040398674D7985F8E81DC3A17F3C0A6E488
+:10FEC000960A720BFE71999FF3B7F5DE1BC9107F7E
+:10FED0000F548B3880CEF1175D1B3FC8FD338EBFAA
+:10FEE000F235BC7C999F9F831C88B1B6ED643FCBF3
+:10FEF000996EA4B7FA5BA2B5F0DDDE1F7A28B7834E
+:10FF00004C8B72C66E15FF86FA73EDF93C03688759
+:10FF1000F867A623FFEFBE3081F28CFDD84FFC219D
+:10FF2000D56C4E225CB7FE44D2FDB6753A5AD076F7
+:10FF3000997FF9743B6F40E831CBCE1B107ACBB27E
+:10FF4000F3065C7A6C209672E6D754DFF2A1ECBC23
+:10FF500001979D67E98B0194FF36FB72999FCBFF58
+:10FF6000338A712DAED7CDB15407B6BBB91AE47F31
+:10FF70000CE94126F96FE90FF7F7EBC5F7FFA81871
+:10FF80009FA7EF03EEEF99D03F1C2F458646DF2356
+:10FF9000257B5680BD28AAFEDACFE5A0FE4A675130
+:10FFA000BEFC2DEBC904FD5972123774797CE50C47
+:10FFB00095F5E767FF7E08F32D60DDB77569648707
+:10FFC000EA1B3E356B7B8B4EFCECD3D4CEAF9B064D
+:10FFD000D251B0216DC8242FF526416F062B473D25
+:10FFE0006FFDD99D45FB29082B746F1CDF3F658E83
+:10FFF00040397A113BE15F89727D2A2EC4FD08CF1A
+:020000023000CC
+:10000000DAA2641E79673D371F7BB7F4255BFB7B63
+:10001000FDCEB8CC49F614CB523C28931D41BA31E1
+:10002000D889E1E2E9FD9CEAFA69E94B982A73A4D0
+:1000300073D638941FFC5BCC47B3E62D57990CFD63
+:1000400050359E22E708ECC26CA070FA3CB6A30FB4
+:1000500045E7028E5D84F9FA675BCF9DC21FD82EFB
+:10006000F260666A37D5AF79B427DB88703D49FA0C
+:10007000EF24E017E35D45212621BEC197A37CAAAA
+:100080007024E1B0E3DC705AF39A693C25E48C8B70
+:100090009DADBD2FE25A4F973ED7C7A2AF7BD04F41
+:1000A000D2F8794345493D341141F717147533951A
+:1000B000BF3481FC6BFAB547D05E68837A7CFA5412
+:1000C0000DF3522D3AEC13F47BDCCFF39FF61614AC
+:1000D00092BCDC7C2C4C7951A7E4B4BA0DAA3C4507
+:1000E000AB29EEE2F134A530BFE4C2D317AAF6384B
+:1000F000C02FFCDC1E1B08F1FD8E0125A5A2EED24F
+:1001000099A1225D0C693C0F72A6F9AA55B2033F72
+:10011000BE4870D6F9F70ABFBE3710A77C7BAB1F6D
+:10012000490D101CC7FD92389779E2C533309FDE28
+:10013000904CFEE56068971A43390676361ECF1E4E
+:10014000544CB5E40F08D785A72FA778568FC6C89B
+:100150008EF687DBCC2CAE83C452F5184FD6949F15
+:100160004DE5D3027FF9BD8CF2D2FCC5B519D3267B
+:1001700007FFD0F862496E4F298CDB53FE40B25224
+:1001800045FCB45C66F4C2F8BF46FE2E43BB36495C
+:10019000FA3377EE84CB21EA0AF8A07552E1766152
+:1001A0009CCF2F8C2760A1FF229CE17C3C8AA04B36
+:1001B0005C61C625BE3FB58AF6A322014BBE7ED840
+:1001C000FED6527F9271173B53F001FA5326281E38
+:1001D000FF07EBEF2CF005D8FDD41F66CD9D29E578
+:1001E000FA8191BC0F105F9D6CE4718E1ED017F8E0
+:1001F0007EA02B4A4FA63C4BF23F84FB0E71DCC520
+:100200007B86FC48ED3B7E86E700ADB8BFB5CF07E7
+:10021000F6E65BF239183F72CA15B56A76B9D1575E
+:10022000B6206F7E544E1F2A2C66D38733B5FB63EE
+:100230003F7B403EC56C76B912AAA5434E33CDCB69
+:10024000D398E4C861096697AB8ACCF3177A42EB7E
+:10025000D524D9BB67CEA09D60D9749E50A2251F1E
+:100260003E4CDC3CB6F9935EADFF263CBFE78D6E9D
+:1002700030ECE701B7E2BFCBF0FD46636216BC7B12
+:1002800094E4E83A9403CDDC3FBAABE033ECAD46FE
+:1002900094B79FA175EE2F2B8FF9C98E1179DD6A66
+:1002A00088CE5F5B7478A8ECAA28C6ABFA2AAE8A1F
+:1002B000A2BEECF326A228F78E943D6760BFFDA78F
+:1002C0008B189E83EA8FD692BFD37F7AFE9C549E72
+:1002D0007915E0BD1F2AD911E2BCA30F939BA7E0BB
+:1002E000046B703086FECC110FD9F977157CC7C02E
+:1002F00038844F57E89C952F94A0F3D41DCD630606
+:10030000FAE3BE6428E9D7A6F7638D037F248C4FF8
+:10031000D001038BAF24477D5E38DC655F9D4CFCCC
+:10032000033E66A6274F7BAF5A6816003F7873EFEF
+:10033000351CB7EE95A5A467B13DC65D25E074E414
+:100340009F1CBD679CFB829A9CEBB716B9C11CA48D
+:10035000F8255353B81FE8C667BF4FEC0F2946274F
+:10036000C2D72B952C1B6E9EC50E880EFECA334B32
+:10037000FE5140F365F19CAB12499B442F9A1CBF80
+:10038000348AE38F8C23FDC193BE0F68CABFDAE9BC
+:10039000ED55D569BFF5846A678D6F60DC94CD62D9
+:1003A0001FF97CF124CF5B4D75CAA437CEA1792902
+:1003B000552FBF1E83F18FAB5CBF2A519F89F0B8C8
+:1003C000F59A1C348EAB80575F90F7E3EEBF34D8BC
+:1003D000F6BFB0BE574DBC8B7A6830B642E81D57A9
+:1003E000DC2219177C6D144AE59C6EF99F4C16E1CE
+:1003F000F2264306CA4B6FF30186F69056E9E1F206
+:10040000B2819FCFB5CEFD7A8C9FD239FFC255CE37
+:10041000F3BC1E234872D4EB3ACFEB1178F6B8DE6A
+:100420009F71E3B9EB7976DC76BF02BC32F2ED67FF
+:100430007F2FD0E60DE489CBD0D9C095483F294124
+:1004400067A087353CAFCE482FDCDDD540CFBD5D02
+:10045000715AAFFBBA5AA8DCDB6550795B57079538
+:100460001FE84A50D957D1AB221EF755A4F7E139FE
+:1004700049663ED9FE0AE0635F38FD063F69F538FC
+:100480002F8BF3B5FAD0C3ED985FB9AF9897170DDE
+:100490003DD16E02DDECAB4F5F2D53FBBB79FB6AA8
+:1004A0005EBF6CE8295EBF9497FF6CE8695E1679C1
+:1004B0008CAC6ACD59F673B97CFB160632101F5509
+:1004C00011DA97F1E8EB9904AFF69589FD1AD10F8F
+:1004D0001EFFBD228F5F61F5B336C0F36E7CF80A54
+:1004E000ED184D21FDBA2FF69F8327A0A40DC28FD2
+:1004F000F942FB6BC86F4823E01F5C1F789EF043F6
+:1005000022E97CF447FFAE97F0B554F40FFAE69376
+:10051000367DB321C0CFEFEC6B72CEE36CE35F8727
+:100520008EDE723CCF3BC17069FE4D4D7E3C80F942
+:10053000096BB3590C610E543D43FE8785AF99FB9F
+:100540003369FC14E2B72CD73E1437E8FB73033C45
+:100550007FE8814D6D44279F12F8B3CA886F949746
+:100560003E14CECD397CCE389E6693E3B5D3E99B5D
+:100570002909DA8FFDA4AA39D6FB225573C01708C2
+:1005800071BEF9A0F85AE9EAAFDED5DF5C577DC548
+:1005900053326B59064BBA419ED58E38D7D58F0F43
+:1005A000E359A518FFE27E8C4F4D92FFE011717A5E
+:1005B0004FBA89F4B7B50F8108443BCEA719642F11
+:1005C0000681A8109F2AE82FBB5DE6AD72C6B994DC
+:1005D00090D9EDE5FD66304EEDC3B817E5171884E8
+:1005E0003F25C4FD63CB0E44B1817A6CA8EE66361C
+:1005F00026BE9BED1CBB22F23430668672EC6CFE8C
+:10060000A77B9CE89AC4ACFEBDBB3D0B29FA3B36E8
+:10061000BA98F93B85BD63D3E38F0B3E281072D1A6
+:100620005F9566F638862F9A7F3FA52998FC5AC0B9
+:10063000A6C7D5DA2351FB77FDD67D188D9CBE4623
+:100640009AFA75BA774BC93AE48B455FFD785E1527
+:100650001DC4464107517E2ECEA287A97EE33CBE33
+:10066000E953B314DF0CA50F318F831E926C4D3804
+:10067000B75FF3A488735A76875F77FA6DD6BADFCF
+:100680002AF2374EDD7942C1F3C397677FABD4C2FC
+:100690007ABD13E07EF62B5D9304DFA93BB9FD71B3
+:1006A00079F3AF948B6C787937E0233ABE9CF17C78
+:1006B00038F0F6952B96DAE7C9F7BB2F3C5D44710D
+:1006C0008F578E7866E5F38F47AFA5FD10ABFC3FE3
+:1006D000E21EF2F39932BE1ABF5FDDEC91F37DEFBB
+:1006E000B6AF3E1EBD8EFA3975C70905ED8257BA01
+:1006F0005409CF05E3FC301E7979FC570AE6E39DE7
+:100700000DEE7F1274D287DF231EEE48521EA02FFB
+:10071000FB398A6BFA220983E7F5312EC7223AC5E5
+:10072000092F3CFD9714B7B0FAC9D195737EFD111E
+:100730007EDE8829498A3F7AA3B26CDFE79A697E18
+:100740003E313F0BAF7D88D73CDF59CF9EAE64B1C1
+:10075000523F73BDA78C9FB7F278E35ABE38857BB2
+:100760007C2504FDD9E8C982A3E72C70F4221C364D
+:100770007FAB2FC4E7DFA724F2C647DCE37A35E777
+:10078000B8A8871ACA855E467AEFDD742EC537A3EE
+:1007900041C6E3B5CAAF27D49C3FEB57FF9C6DB170
+:1007A000E59FFBAAA0DED15F8AE4A05FE7E793990B
+:1007B000BDDE96B7A6D648E4EF512E25E5C5B09725
+:1007C000705F4AA98B1FC471CF0FF278FFED81E4EF
+:1007D000F9C1E55CBE125C2C44F6BDAA25E8D0AF99
+:1007E0005ADB40F6330B45F2EA23F77EB8858F29B2
+:1007F0003973FADA518C1FF64B0D37E5F31BACE772
+:1008000060757714CFB99AD5FC7EC7297BD005F7E0
+:100810001541CECF00F715C1323BDCCC01F7407556
+:100820003FDB8AF4CE78FECA4CF682AA7EA558F940
+:10083000480E6F0181AF69F925D5CE7D87EDD5CE04
+:100840007D07AB6CF50B65E7BE83C82F51AB445EEB
+:100850004FF68BC49FFEAA14ED3BA84A96CED559FD
+:10086000FB0EAA3A46716E5B7E0995A7F61DEA9AC1
+:100870001DF3B939283BEE95C8C5AD04BD34737A74
+:10088000690F26AFC6F5F6D7F58F63D95FE5D42398
+:100890001502EF56F9DE6AB13FE65A877B3FC7F390
+:1008A000777BABE30751DFF60A7AB2E20EB03EBDCA
+:1008B000413B3F6A7C9C7B3FC7F721D986FCEB51CB
+:1008C000A13EE9588F99E8A5B663FCF5A4CE38019E
+:1008D000007F95701660BB42D1C3B81FB78DF17908
+:1008E000F8E58923B8DF7E4F61720FD24B50CB1AE7
+:1008F000928EE70C393C7D824E2FF69C567F82FB10
+:10090000E1AB6A8BF0DE8617829283AFADE710F819
+:100910002328A77ABA54BA52EAD48F16CEEA5F3E99
+:10092000D4A53AE4DA4375FCBCE5435B7625DA00EE
+:10093000057D913ADAC71FAABF84E1B85F11E32AA7
+:100940001AEB2D6FC675E2F93780CFAF20FCDE08B9
+:1009500087DBC2334910DBFC6B0D9DEE11039172F6
+:1009600022A3A1C831893FB44116CFEA84876F60C2
+:100970003F215D935125A81D19520D161EE0B3238A
+:1009800078CE37FDDDFA65F673BEE1024E5FAC91BD
+:10099000DF37C09478349F1D64ADDB7D80A746BAF5
+:1009A000F7D390104E8CB337DAE4C4ADC1E41184B0
+:1009B00023B2314874194964249CD73E11CF9698CC
+:1009C000FA5205D11BDFD7BAEF86A0A0378DF2B55A
+:1009D0005F15F46EA3B757F3D19B574F6691A4F7F9
+:1009E000869247B13E208D6918AF9CBB91D70F58B6
+:1009F0007971267B15E9A8D2DA1B659CEF4B1BF4B5
+:100A00000338FE7F8875298EE8986EC5F4D71E6B73
+:100A1000BD16D70FFD6EC0F3DCEAB12BD01E663FCA
+:100A2000F4D0FD271575CD87DA909F0DF504FAE116
+:100A3000C5EDE9565C6F15CA981757B1615C42BBAA
+:100A4000ACAF8BEFD39474A469FEA10DBA84CA60D5
+:100A50004A9FF8789CA932C2EFED93CA1FEBF6A12A
+:100A60003EFD22A3FB794A576728FE54D9E2D750AE
+:100A7000CECD8D4DD0F9DABE2B18DD6B5ABD89D79E
+:100A80009782D98EE3165F9FE0CA06FC117B7E58E1
+:100A90003092A4FBD38643C9FF08D2BE6B82EC4DD3
+:100AA0005F24837729B1B4D724BB4E5D9531109E66
+:100AB000A1FAABD83A1BDD870AF83EA35767462652
+:100AC00094A3CB5D48DCF0FD8E96DAC067D12E2C66
+:100AD00008D2BAD5B235069EF78CB104E5D5AA394D
+:100AE000FA2C28C03C673D4360AA1D9C5F812F29DA
+:100AF0005E9BF6B20A84235DEFEBA4714C7694AD55
+:100B0000C0FBAF98B8CC8EAF9B1A311EC6753B1494
+:100B1000E47EA87AECBB06E6337E7F5DC89030D4D5
+:100B20005C6866BFDD8CFBA66A4207BC8426BAB34C
+:100B30003F82F2CB9D0568B3821ECF92FD5A98602A
+:100B4000E031A25F9EC862FE32EA16A28B761EBF1B
+:100B5000067CC50A105F2DD92CEE8F95449259045E
+:100B6000E12125F53FEF80EF1F3AE2899BCCC637A4
+:100B70002C1EB5FB1BFA16759ABD40F71F87F83877
+:100B8000DE28CF53F189BC31DF549E4A92E7A94455
+:100B9000799E0AE67151DE57C4CA5389D3B96FEB07
+:100BA0007CA982F5CDB93C152FAF637D15CE3C9461
+:100BB000BE0AAEC7CC36D680F7C6F455249C793B26
+:100BC00092952FF10947BE499FB84FD02D0FBE5FB8
+:100BD000C0E3637D985700FD6FAB9033288FE149E8
+:100BE000E39F3C26919FB7AD3AD189746AFEA880F5
+:100BF000FC8543653E9ADFB663E183F6BC002BCFEC
+:100C00007126793B537E63ADF939F2E7B7450FABF7
+:100C1000E8A78C80BF32DBBEF09018A75FEC0B4ECC
+:100C20008D3FC3398DDB847CC47834D2A7279420D0
+:100C30007DEFABE2797F7E5C3F5C2F5C3F94B765D4
+:100C4000B7507E8CB78AE7C7587955B09E94F7E7BE
+:100C500055E25CFF8BF3C08AA8B7D6CF5AEF91322A
+:100C6000E7FA8DB8F2AE46CAB28EF51B995A3F57D5
+:100C70001E64D355E4278E88F3C6DFDFB6BFCF24CA
+:100C80003ED6E5E771DCA84C76735F2C318A726E34
+:100C90007029BFA7745B637E3CAA3A97E7D67ADDDA
+:100CA0001A347A914FF689739D3E999F43B5F09916
+:100CB00014F2E39902493C79795BE37A6B3F3A8518
+:100CC000F9ED73307B0E402CAF4B7423CB1F2D48B6
+:100CD000EEC27E4FFDF8F60A84C31F75C617226266
+:100CE0001C8082F2EFFA7F389FFC175C27B4E793F1
+:100CF000054E3DEF1BE4F7C558EB07EBA1E7E3BF5B
+:100D0000BEB2EB0CEE0FF1BCCD29FEAB9A5A3F936D
+:100D1000EC3991BFE6E63F6BBDFFD8EB571B4C7C2F
+:100D20001DE529534CD2936EFAFC539D1F33F7F700
+:100D3000F17C856BFE53F19B69713996A6FDCA8AD9
+:100D4000637E8ADF4784FD7F6B30F1CF88B78A0DE1
+:100D5000C22E1174CB126BA8BE16910BF37924111D
+:100D60003D90DFDFE7F1935361EB7C6F3288FBD876
+:100D70008FEE5E1F44F9F3E8E8ECF207E3DE287734
+:100D8000F60BF9731FE6D5D8E4D07D42DEDEEF3AEC
+:100D90009FD711E272A824C4E5EEA36A2288EBCDA6
+:100DA0005EBCFA32710F33C99FB9778D15CF367E8D
+:100DB000D546F943E5D17842E1089DBFB4CE379DD1
+:100DC000E57B2B7FE6C3E2E57E5CBF4AC0C3C86F0C
+:100DD000FB301EEFC916111DD66EE2FBD61583C976
+:100DE00061C6F1803BD6ACE8F457E9FCCC8111F048
+:100DF0004DC81F370AD781DD42A62BD0ECA38357FD
+:100E0000CA35D0BEBAC2C3681F6037DF3751E13F71
+:100E1000EE6F675B197765E85EBDF969D73DA9B8E4
+:100E20007F027655B5FB3EDF63EFD23E4C85EBDEAD
+:100E3000D50F8BF76521D7B9B2FF4B78BF4F190B90
+:100E4000D8F34AE74A2C81F439F76FDE769CBFB9B4
+:100E500054D025DB1C62C76D71D1B952B602E5FAD8
+:100E6000FE8D22DE04A63EE66978EB26BE82EB36D6
+:100E7000BAEE965F7E1BED95B29FFE19DA599F0878
+:100E800015703F63E3CD0EFF15FC804F8496E7FCA1
+:100E9000A4FDBD578AFD347614EF35D6C5BADE778A
+:100EA000DA43EB5A1FF530BCA7B67DB729A15D5DCB
+:100EB000BB99DBD5CC74AE73F5DAB88C0669ED0658
+:100EC0002EE7EAD7B28C0EEB55BDD9793FEFFCEB9C
+:100ED00053871E80FA3AB0C70DA097BADD4E7A98B4
+:100EE000E3A283BA346B23FA89831C2E9E3EEEA3C1
+:100EF000EA18DDA37C7223CFFBABD7535216E93738
+:100F0000194AA17F57D6E9BA1F98C5B7E23AB8E99E
+:100F1000D03DEE87A5B3AE903B4FEEF4D58F01DE0A
+:100F2000E6F53FF50F0B08C969D9EE1F5A7456C094
+:100F30008CBE10AE7F2222F6FB8C583EF99D3B7F83
+:100F400079C5ACF2BD34E1CCFB28EE70E67D04E35C
+:100F5000CEB28FD9CAB1DC38612BDE944CE9F6F100
+:100F600006C3E6EBB81FF658E8F24B22C0E48362F2
+:100F70007FF0B191ABFA5105482C48FEF5709D42C7
+:100F8000F2853547847F9C7A08CF310C2C55D830B8
+:100F90008D7B80FC1DF4AB488F429FA5E46BF27300
+:100FA00070A138F7B7A6BE67A959FD6B23DD4AE3E8
+:100FB0000650EED0FEA48883E9BC0C7CF06CC81609
+:100FC0001FF3625E533CE7175BE3CC84576B1CEB6B
+:100FD0005C522FD8E938BFE21A2D867911EC28F738
+:100FE00073A7EECDAB61F11E46F73AC568DFE7584F
+:100FF0008146B147710EA9B76BF6BCE02702C9FF65
+:101000008EF02A3E43C7BCBD29FBBD04ECF7109A05
+:10101000C1296EF7B1043DB539ACE92584A394C765
+:101020000B7BC2FD319C576F99531FCE0973FBEEAA
+:1010300058C843F3D10AF87E0253CD0A7B3C5D0EBB
+:101040004B56FD4DB8DE75DBFFF6E5C1162817B12E
+:1010500026BC427257BAFB920EA00F6DBEF8BE6A54
+:1010600086EFE7B3A7B17D65F8E69715C0AF368F79
+:10107000D38B1EDED58FFA485BC8CFFFB1667D7F6C
+:101080002FC03F7A4D399D072BFDF3CD31FCFD81FB
+:10109000A97E5077821EABC5EF70BC24CB325BBEFD
+:1010A0000EF8C927105FA18E4C16E35D9E105FD726
+:1010B000FEA9785648EC5BEA07ECFE130B3BEDDD2E
+:1010C0007E11CF9A9C984F712C2B8F41899A597B16
+:1010D0007E06D33A727E2AC6576B2EE374A41D890E
+:1010E000BC6D7BDFB74E25BF26BADE4771ABA305CB
+:1010F000C639E1E5047FC605BF1ACE037F2E1ED791
+:1011000058F4139B3C2A71C1DD8BF1B759F60BFAE9
+:10111000CA6F237F400EF37DCCFE752AF9F3165C6F
+:10112000D1B0D8170D99151447D34CBA47C26A9F4E
+:10113000BEE84E8ACF0C0793D508BFB7C3C8629CE0
+:10114000EC92689CD9DBF5C07C255BBFD67B16E5AD
+:10115000FD4E953B78D90BFC88F127EDA2D5946F15
+:10116000D827E2D318EF439FDC8AF7B9E703FC2CBA
+:101170008797E78BFF39EDD9A9FCD6AD0AC37B7001
+:10118000F616DCF925CC87DD6CFA358C0B9D0AD47C
+:101190006418ED9FA6CEE3DFA7CEA5FB1CABD2095A
+:1011A0005C1CEBF7975435457A5252B85CFAFC97C1
+:1011B0004F3E6842BB9F3DF36F0F9A30FF8DBF7B60
+:1011C000EFC1DBD13FFD4E4043FEBBF1897F79F09B
+:1011D0003618EFE7CFFB65B4F5FFFA89777F7C3BE4
+:1011E000947FF3CD8525A8AF2F1774FD8BA77F5B68
+:1011F000AE433F9BBE7DF11CB487373D7B11DD1FA5
+:1012000032D33AFEA28BDF079C934B199ECFFEBCD4
+:10121000844A8D5F5C3D87E41CE5C5DC80FF44FDAE
+:10122000933EE1C3BC98DF483C5FFB86B1F77D2865
+:10123000975E06398872EFC5AF1F7FF93628FF1C0D
+:10124000F428E673DDF8BCD7756FBF3957A67CC3A9
+:10125000EC5C8C07DDF0F54F5C7E41333EBD71ECFC
+:10126000FE4676A21FF5ACFBBB1B5F3BEEA37C45A5
+:10127000999DA8FA689E7A9628CA82DEB9F1A921BA
+:10128000CAABB971ECE76FA21D78A34B3FFF9C710D
+:101290007DE4D6BB37849D76F56F1EBFBA288B954B
+:1012A0005F2FCD2BCF2DBDFB37CF7E7256FDFE0BB2
+:1012B000977C9E09CFA702779A485F603BA734BA14
+:1012C000979EE75BFB145543FD726BF0CE6C12CA20
+:1012D00013EB4229E97CCAA36EC07D83CDA089515E
+:1012E0000E819C1F40BEBFD563BC9144BFF3C7B7FE
+:1012F0009E8B76D56EC1F7BBC3CEF8CA2E4137D6CA
+:101300007337EA5FA4EF4F32FA5D2FA62424FBBEA9
+:1013100035A93C909BF76C9FB8C46CE4F548DFD6C8
+:101320007B664E5C92B5E9076B5C6F849FD70DEAD4
+:10133000E2BC6E924D482BF0E763F89F47C33C1E1A
+:101340000172EB21E44355CF125F58FA14E595FD85
+:101350009E4BF77340C8ABDEAE24ED1B3C8339B720
+:10136000B81F01FC4C6680908F8AA05F18E7A90F18
+:10137000378E464FD4E328AF6E0D269FA3FEAA58A2
+:101380001AE9CE8ACF787C3C2FD4D21B563F592104
+:101390006FADA7E5FF2A251D0DFB717FA035CAF1B2
+:1013A000C412A4070F89F5017C939CBB4762269D5C
+:1013B000CF9354BE4E06D3B572EE87E3FC3CA02615
+:1013C00050DE7861E28CEEEF30E91940BAA3BCC977
+:1013D0002CC9C9E3617EAF88956F0C1D917E298A67
+:1013E0003309F97A77384EF7DF99EB98F64853AE20
+:1013F000BEFF0271BF48032F47131AC3F63F0A9777
+:101400000862304C7C3F27A969D8EE6841E20DC4E0
+:101410004F194B927DD10C4F9C47B91AE2FBAC9D02
+:10142000CEBCBE297A2D76E2ED27025FC7C3DC0F62
+:1014300047DAAF2C71E44333CC87B6ECAA3EB4ABA9
+:10144000626457ADA3FD8399ECAADAD4B971B403F1
+:10145000843D65ED1B14B727593EBE063E3B897C93
+:10146000E6F525928E7868398F8746193F3F1E2D05
+:10147000BC4AC298B6762EFB15CF73532E7DA58538
+:10148000EC94A7B1DCD32B5D4A76CF4704FF30EF55
+:10149000A559DB78DA79C21E6A71DA43A142CE2FF0
+:1014A0000AE20EF5EC2AAEFF142D457A15EC82F215
+:1014B00042C44FA1D08F06D7BF53E576D1DE2A377D
+:1014C000F2FA0FA13FBD8579F7CF5C7996617E6F07
+:1014D000AAFB7BC646B8BE17E7207B4272056E6149
+:1014E0006A779437F173B92D477428CFFBEB8838AE
+:1014F000B7C4E33F054CB3EEA7267FE89EEAE43E7F
+:10150000B4170C39A04935C4275C9E5DE3A373FD75
+:101510007BA4CCF87CA2E75AD2ABA34999E72DACC7
+:10152000F5D17DABA318FFC4FA04BFCF7767C326FC
+:1015300092BFA3E66E925FA0FF49DF9B5BFD1ADEC0
+:10154000DFB33B7933D59B209FF1DCC5F4732D9934
+:10155000EFE2EF4AED28ACE1F97A0DED47304CB6F9
+:1015600033AE901F1E5CD4AEDAF7796E29E47C6E40
+:10157000D5BBF1345218E6726D657E3C5ADF5BF5DF
+:10158000C1450AF16F6FF2D52FE3BAED5C7558BB18
+:1015900008D735F2D22AC4E31AD19FB1B97510F732
+:1015A000D3ACBC50AB3FF77AA2FF4F74D522BF85B6
+:1015B000BF4F03F446F5A378EB20D17BF22FB07E2A
+:1015C000378BAB31C0DFDE6B5634509E68C3C3DF50
+:1015D0009DCFC9A0CD218725832DA0F5086978FF6F
+:1015E00021530D8217D6BC04E5C91E6BFD164DDDD7
+:1015F0009B4472A5B081D7EF95E2ACDEFEBD61E8F9
+:10160000DA8A9C1CC484706305A35C47FAB338492A
+:10161000F49D938763540EB1717ADE5E584BF828BF
+:1016200062998E0512BECF0C2D80F1CA5A2271FB31
+:101630007E6D9925B7D638E5965B0EED56CD211C0B
+:10164000275A98F822E2A5E7332BD418F4D329F8C7
+:10165000CEC28B8A748CE3E0B9D762847F6D379EEB
+:10166000E78958FEA76B1C9C17CE73AE989615B7EA
+:1016700047BC7AE1BB8AEB793CAE8A8D931CAA61A8
+:1016800027E8A9A3E58447B08C6437EE0B05D83171
+:10169000E24FD994A53300F7AD859C9F00EE00B6CC
+:1016A000EB410587F49D9405FE1901B53B293F8662
+:1016B00072B5B350E77CCBC47949D50874D2791799
+:1016C0006E2FD6884FFCEC2D09E34127A31E86F42C
+:1016D00065F94FBE8DFC772EAAF5B725F4E741D802
+:1016E0001A452DE8CF8F4BB89F3BB7553D6192DC33
+:1016F0009CA0EF2BF0FB38C685668F435871C1B9AB
+:10170000AE78442E2E688B6BE0BC447CC6CA8B71CD
+:10171000F395DB4EFC5AE1EF177FFD65C0F86621BB
+:10172000CA2B912FD357765D34DF77B9FB597E3FB3
+:101730007FA3A7B5E9F508E0A9EC9BD7927E39F421
+:10174000C9729273F78678FC0DEC9D37701DE732F5
+:10175000394E79842EFB61F27325EC3A78FF60AA4A
+:1017600030CE7FB481F391754E84694637AEAFC5F4
+:10177000C76C5982F8C707EE3DD2A18A76868DAF35
+:101780000AC12DC0A7474B67F14A85C39BDB8A314D
+:10179000EE50C0461CFC32E5576F62F43B090A5B11
+:1017A0005244E7AA37292C83C099C6ABD1153CD542
+:1017B0000BFF44939A6CD105EDBF1BF08D6D9D4AD4
+:1017C0003BC05EB3F9076560A7D8CB733AA38EF62A
+:1017D000AC97FB093AFC877C76928D90FE76C79792
+:1017E000BDCCA438E4DC16BF96A57C0393E28655F5
+:1017F000E0EF509E40CA191F8CBABE77D3D3FB16B8
+:101800003D015B233D011EE2C8FFBF7ECD43F7943F
+:101810002A137EC24B25E005F1F06BFC10CAD5EB14
+:10182000189DE773E3C5A237F85F1CE1AA817EB279
+:101830008CF6A31CF30DE84EFC143438F1138E3BE8
+:10184000F1139BE8A679BF0CF3A6DFF36AD11DED77
+:101850002DFC59BFDBE7C65BD5F563DD389FE9F8A2
+:10186000E1E720CE86A7DA22279E4EB2170E619DB1
+:10187000A464AE467AF658F40C0A4B2DCFFDBEDABE
+:1018800083E17437FEDE9D09F4ECA9CCE1C74DF786
+:1018900055DA782B99D38DD526FE9E4A14DAD3FDDE
+:1018A0007CCB922EBD9171D8D1B9F37A603843B90F
+:1018B00012ED6FDB39B10294B344E7C7D919BA37D7
+:1018C0003361D2395A60583C67ED5557935F0764CE
+:1018D0009CC235023DDB5A44F108F612C603AD7BCB
+:1018E00082BC2CC5245B5C5552B2248F3DF7F33C7F
+:1018F00006A52DB515D75B12F97AEC7ED01BF6BC88
+:10190000F95A83DF1BC8E2AFD3FEB8F8DD68406840
+:101910003689F258CCF76CF3F46827043EEEE7FA08
+:101920008371FE05ABB91BE5D55C9C17C90DE32897
+:10193000D2A5B5DF53B53941FC1A9DEB617EA09F5E
+:101940009A143B4CFB01AE7D9F9ACD63446731CC2A
+:10195000BBD1F03E3527BDCC1F74FD0EA0E705E2DC
+:10196000BF93497E2FD65C171D557B7519FDA5CCFD
+:1019700020A3FB61E66D1997F0F75716887CA1F953
+:10198000832CBEC14667D5C9C2F806B0C91FC317AC
+:1019900015D3E9F00B45CEF8FC17AE585394857972
+:1019A00064CC0379F7FD1EE852E31B80DE9EEC8ACF
+:1019B000C637D4D3FE0E95178C8D67830057632FDF
+:1019C000C74FAC73623FFECE726C8B2F8E74988BB8
+:1019D000EB27B716C17ACFBBEDEFDA70DA8B7A93CB
+:1019E000AD68177F43367AF03DCBF0DF2F6BDC5CC0
+:1019F00015DF00EBB064730D3DDDFAA4FA6F5FFBF9
+:101A000087AE08FE9E37BF5764DEA49FF29FEFC5E6
+:101A100026F0BD6E6A6D2ADAD99B75BA0FE79E2251
+:101A20006E4FAE2932D2488FEC7A9E6763E167260B
+:101A3000BDF5A0C83B7860D3AB575C8AF16D8DDBF8
+:101A4000ED31C508623CE1B122EEBF4CCB734F5B78
+:101A500079EE868CF19FBA742BFF3D6C579E3B6EDE
+:101A600016A15EBF55DC4BD45694FC12E1410B3AF3
+:101A7000EE81B4F2DCABFFB63D8876EAC3EA049DA2
+:101A80009BAE9658CA6CC27D1AE7BAD76E8CCB282B
+:101A90009F74F304F9EFD63CD714259FC1FE6BD495
+:101AA000109563BD13E46759FB9FF346B9BD0574F8
+:101AB0007808F7FD4FA6B93B3D2F3D2661C8EF12D0
+:101AC000CFEA20BF07CCF8F3753639FD30EA2F682E
+:101AD000BFA0C2C34CE417213F41BC093BCF90518A
+:101AE0007E546D71EE43D50979B9C0B5BF5987F6FB
+:101AF0004D21D6BBF7A380DE6CFC62CDCB9A8F9BC9
+:101B0000BE7F60C9D939AC02F7F54FB255732ED6F6
+:101B100073EB5F0382ABC5766FB845A7EEF896D539
+:101B20007F53D639BE84F7C24778FE03ED63C4CD38
+:101B3000AB291F47067944F688D38E97922FFF165C
+:101B4000CF2BFA3A4C4947FF7A7592F223A21D2C0B
+:101B5000AE43BDF15ACCE4F77A8D5F80FB41A5AB73
+:101B60004DC987FD578D5F8074FC6E5148E4351B6D
+:101B7000EF221D97A29C267BD9B25B52F45471BF11
+:101B8000683E9EA71963A62767BF0C16257F8DEBBD
+:101B90006FD9313AAC1BA60284588AD66721FA0362
+:101BA000783ED1256F0B5CF2D1AF24B3EBF5E9F3AE
+:101BB000037074FB7ED440357B1EEF4D97AA60DE28
+:101BC00085C8470AED73FC1FE344020E0080000045
+:101BD0001F8B080000000000000BE57C7B7C54D5C7
+:101BE000BDEF6F3FE69584644F32498657DC490864
+:101BF0000408382480E1D1BA0988885407B48A8F50
+:101C00008F0E88CA2324315AE5686FD92134C5E084
+:101C100095F8AAB107BD0315D42BF13340C0D40603
+:101C2000CE801403853628025ADBC67AEA41053293
+:101C3000C42ADA728FF7F7FBADBDCDCC2408FD9C2A
+:101C40007BFEBAC94757D6ECB5D7E3B7BEBFEFEFB7
+:101C5000B1D600A63ACB5001D6FE70AB3F5B03FA7B
+:101C6000896AE558BF4602980C50AC0D59639660DE
+:101C70007DAEA84FD07244FD16AC0F0228A7E769CD
+:101C800000B25B93C33E00B74F0E2BF900E7B26B77
+:101C9000DD80ED7E36645E46089F7F433F57F62D1C
+:101CA000EB57E280237ADBE5AB0103B09F9FE1DFD6
+:101CB0008D52DFF66A9A0CD1629E277C83FFAD1DA0
+:101CC00033D31881ED158098120070AE50F47FCF99
+:101CD000C2760FA81FBAD2011AB05F9A87D35D03EC
+:101CE0001A96AEA6FBA212B6073F0436712F21B892
+:101CF0007100CE1B44BF0F62F90DCEBF22232469B1
+:101D000013B05F2D05A2EEDEF19C2B9CDCBF44B22C
+:101D1000C2E725E3F18FF1D86F0002300E4B3D2A68
+:101D2000EB38F7921543028BB09D5B0D4200EB8EB2
+:101D30005935409FBBE6040D1ADF350B023A769108
+:101D40003507660CC5BA6318B42812C9D184E5D822
+:101D50006EA286FFCB0678C4634CA4799458E34DF9
+:101D6000D2342E0102527000953540E59A8CE01471
+:101D70006AA70FD1566137806F8384F31A91066189
+:101D80009223B65B15C53A6E754D23F5B55E3DD50C
+:101D900065AFAB40943011E74125AEDF89FD4221AC
+:101DA000C9A589CB14887099069D5C66401797A9D0
+:101DB000B05EFB3815E74DFDE07A1F771ADEAB7099
+:101DC0003D0DBF730436E202CD8A9AFFD585E39AB2
+:101DD000AB54A8C7F2D9D49FBCD485CF57982ECD89
+:101DE00085E5394F5E18709F36AE84C0A22280E729
+:101DF00057BA038B7012FFBA52E3F2D5957EFEFC00
+:101E0000612DDF5A77CD15C131D8EE015C09BEBF17
+:101E1000EE83D161290E27EB16C1AC4809E108F128
+:101E200088E3AD2D5EB8B991F03872618A133FFF37
+:101E3000174DE17E36375F1A2EED768A1A00AD9F78
+:101E4000F6C978541F904DD7D8BE3874BA431D05D3
+:101E500038DF11471530512E239AEEDBEB19DF17CF
+:101E60008776BF725F3CFE0BED2FC4E3B1A0178FE6
+:101E7000EF65180FD3F3C74B438B83FDCCB3C92B4E
+:101E8000339E9E7FE0698F8E72788EE494D62BA766
+:101E9000E6124B4E636A594E2F58727A69FDA5C9F6
+:101EA000C96EF7FF404EEEE1389F0C4B4E194D675F
+:101EB000A3CA3F27A717BE4B4E8DC18D6B681FCCA1
+:101EC000901C28C2FE9F0ECAD12BB1FEDC62790B9A
+:101ED000F1D6D3C18DEE22C255F3DE21A9F8FC0D57
+:101EE000EF0081172DD641EDCC61B2BE09F1F6A805
+:101EF0002AF4ABB159FEA599DF3B9FCDC5F2AC30BA
+:101F0000CAAFB17861CA5D7172D8DCDCE38F97E348
+:101F10006609E6134E93E5B4D02BF178BF5824330D
+:101F2000BE3D2108CBF8D18C61C0F5814320ECC2C5
+:101F3000FA4043D491FBC23AD6F77DAF619A8AF555
+:101F4000C64500B9F868A672C8A47536232F223793
+:101F5000E18F71DD02D4EF74FA13D7D51C8AF273C6
+:101F6000D73477CC443E48EF9A1B7D1EEBFBCB5D0C
+:101F70001A20FFA795AB7FE98AE33D506E87283E84
+:101F8000FF229456A360FB81EB139FBB20AE8EF221
+:101F9000D08C60F479E21BEC8F78D941CF8B7B9F9A
+:101FA000AFF8E093AC7D7178F0CE0800C9E7A836B1
+:101FB000C0477C828BB8EC1BE4979FAE6C838F8A02
+:101FC000787CC617528211E9075FE7569ECCDA8704
+:101FD0000FFF4A3827F905574906B65BB7A04922D3
+:101FE000FE1F785E3148DEA809FE5BC7F4BED783CA
+:101FF00038A1F6EB1C623FC6ED03258DEC89A68D5A
+:1020000053F4DE76314DECCB3A8F6837E1A8A10C62
+:10201000F8AE7603B01D8E3FE9DF4D25BD9F769D5E
+:10202000D63C418DCDA77D7CF47B4E8DF46F9D24F5
+:10203000F8D33CECB0F02EF679F3DDDA06E2F16D80
+:102040001D056B4B080721BD94FADBA687E482B41B
+:102050000BF3E7310B4FC367850C360ADFF617DD4C
+:1020600022EC42CC7F3BCAE3436F1AB7DB9682FC7B
+:10207000C1720A0D9A1B27A7DB2DFEB0E5B4530FE2
+:10208000AD1D83FDA4E03C249C47667118E492DEFC
+:10209000F1B615E37858DF7642667B3E70EAB12DE3
+:1020A00010A727F6783B53FAE7AB3B2CF9D8F27E22
+:1020B000430FAF1D1B375ECAACC4F1521689F50D34
+:1020C0003C299B648F2F34DE1B17182F64AFCFDAA7
+:1020D000B7DD7AD7DACBB19F541A0FA5914AE3A5A1
+:1020E000F533DE574F4A03E2F4B8CB2BECF66E5BC8
+:1020F0008E6A68D0BC38BEBADC7AFFA5E0B68EBB6B
+:10210000F0F1A3450D9E5009F141C43D9CF6FD7BC5
+:10211000326CC2F5AD5B5F01E427BC64006BAF3786
+:10212000CD9C4646F6496F26F7FFD2FA0A7E4F52FB
+:102130009BEA549CA7828A4E7800089F2079E78109
+:102140001C68243FC730740DF55EB2F47EE01CCDF0
+:102150005C88EDB36AD291A891569B6B0E8EC4BA7F
+:1021600067851CA0E7109540C5F603ADF66E306F8D
+:10217000619EB1FA1B187A7015F1C07A056A14E4F1
+:10218000897EFC8800F91183E92FAA971A201592FD
+:10219000DE86D8497381C9652A44D97F18407E8478
+:1021A00042FE44741A959711A52BF4C890E9791151
+:1021B00084EB68F2F9865EA1E27C8637872A683E66
+:1021C000990FE06BF9A45761EE4782C7D81F4A2DDB
+:1021D0007CDEFBF168CB1F9982BCEFD5585EB40F53
+:1021E000E437F892EA054975E3D034A07DF0A062A7
+:1021F000909FF48827B4D89B4D7E9961905D721BA7
+:10220000EE18F19F4B0BF2FA7E1194D9FFFBFF8D74
+:10221000A71FF526F2B4CDCF365F5F889FD9BFC424
+:1022200038E2AF4F2C9F4571C35719C64F3494EF16
+:102230004FC827CD263F36F4732FF1E28D4D7B0832
+:10224000D7F91407A01C943490FBC3BBBF19F14EFF
+:10225000F2477C52998C773720DE49FE8877F67BEF
+:1022600093F0DDECA8613C232A6B94C96C1FA47B1E
+:10227000B09F3CBBFD45F08D2E85AE205E55C283E0
+:1022800012EF3747B86EFBCBE910E372881A93A8B8
+:10229000D421C0381F0641C6F9208C9F08DF0533C2
+:1022A000F43A0FE1DCF22F86A2FF6EF2623420FFD7
+:1022B0003D2524FCF9A7837F61FD4FC6BBD139CDF5
+:1022C0002C189F80DF28C913F10BE4D724E3B73122
+:1022D00058E1A1CF374F9523C4AB9BB5F01A7A9F35
+:1022E000FC23B23FEBCE2BCC438FA29FB38AFD1EC3
+:1022F00083DB372E92032833F277A25752FBC57245
+:10230000B828FF92FC1E8E1B173E710BC791EBBCC9
+:10231000C0F6C12C728637E5933DD6190753639DED
+:10232000D3337CE4370ABBB9CE11F307B87D6C3EDA
+:10233000F197F9BCE0C99782C93C19615E1DE7F5C8
+:10234000723F4FAF5F75CD42E235D5647EB0C72F87
+:10235000F71EE0B815D2627ED2FB75736B5388CF3F
+:102360006D5E4D6E77D0637C4C723C7401BFED3373
+:102370006FC5A7C4137FB0702CA951D67B650670BA
+:102380003CAC5668758433C98EBF6624E14AC747A2
+:10239000C4D79976BC16601E77D83C0E5A3484EBAD
+:1023A000765AB8B479D403E17EF95421BC31DF26E2
+:1023B000C667DDBB8E0F3571BD7FBCFBF301D8183E
+:1023C000FEACC606905C4FFEF89D01E42FFDF1C700
+:1023D0000AFBAF77D01C2601DCB9F2FF4C5C88F514
+:1023E0008C4C89D7B52CD37065125FAEC866255A60
+:1023F00012C641E2F861D9CBA904FE6FEBCB235999
+:102400000975D6347C75B90B6AC8CE2EDBB2C739D4
+:1024100018D7B7E465EF38EC094E22EE498F4FB676
+:102420000EDD407EF5D599B2356E3097C6A5F91010
+:102430009EFEDCEE8228DBD74E87F06B8CEBA48906
+:10244000141D889FE479EDDF3DD82963BF774BC821
+:10245000B35EFEB861278EFB57BF028D81BEF3BE0F
+:10246000FB8F9A53C6E7774F8398398EE629353C20
+:1024700084EF2F245E0DF45DD702D391C0B377456E
+:10248000EE73B2D0959299B9C4C76B24E6ABBBD6B4
+:1024900024B64338ECFF35F6BB08FBA57DBDBB2950
+:1024A000F1794FC7FD0D3BF1F9B636A7467A7B6F40
+:1024B000127F27F3F3D44CE465E403E4A82B889758
+:1024C0007B3AE66544F50BC76F362F9FC4380EC1C3
+:1024D000029FAE7473796A25830C5C993AFB2BCB0F
+:1024E000DAF6EC67CE533B2792BE6CEBF828F55634
+:1024F0007C54EB17F1DBF7377C5EBF131F9741303D
+:10250000234A7887A883F4ED4A70EB6938BF4D14ED
+:102510009F2184CABEC27AFCFA9AF6FCE6D71C8FC9
+:10252000A5D56C42B9D622D05794F6CEAFD62FE2BD
+:10253000B6DB41FDDB77ADFBB64CCB1E5D81EB56C8
+:10254000FEEBEBBED07BCBD1EFE94FFF6DFD7065AD
+:102550000ABFB57ED7B33307E1BACE3C21055C385C
+:102560008F338E7003D79F9102753A4FFB18E4F4B6
+:10257000E21597CD78BB97781BF1195AFC08E362F6
+:102580003FCA85EC7CA87D283FF74F47FCA25EDE62
+:10259000BBF8B3F7859360FA653F9551BF5CDE0FDA
+:1025A0000E93F0968CAF338EAE3CD2FF645C9DB937
+:1025B00000CF556716F0FA16E9C64CCAA7DD0DC163
+:1025C000064DE8DFF1FF8EF5EC6DBD1F34C27F874D
+:1025D000CAFE54E9011117971E7686C9BF3F8DEFD9
+:1025E000A4D1F37D6961B24FDB1DFA5325641F0E40
+:1025F000A8C0F1D379E07860DCEFFD618AAF4E6767
+:102600009ACC2FDBBE82F0C67C6A5056A8617FE36D
+:10261000FE5112E0E72B146306BD7F1EC214E78F44
+:102620007BEBB1EBA8FDEE0D0A507E2E59BEA5073F
+:102630001EB88CFCB32BBF4E91E879B2BCCBC28ADA
+:102640003A99FD12772C03D7551AFE68D914E67310
+:10265000A8A57AF27ED8ED3519B83DB917542F33B5
+:102660008A63C453C9FBB4A4DDA5D2FC9774402986
+:102670007DF6FDF389FE5EE9A124FFD0E6DFD75B9E
+:1026800076921D58FA8727D301CB4FD4A61CC2419E
+:10269000CB8B3F4D37C81EA8663AEDEB2761610F23
+:1026A0009271F0B585775C58BA84FB5EC553C5FF5F
+:1026B000D6C41A1EC6F97C893C4BF3ADDAF777AE67
+:1026C000EFC7F5839FFAED9AF908AE67C982B49A0D
+:1026D0003A7C5EDD96B8FEA52F3D93A3735ED31CB6
+:1026E0006CE16030BD57F5A22340F6B3EAA8C27989
+:1026F000D36A8831EE92DFAF8E7CE4247C90FC8636
+:102700004CE9FB1CE1E824FEAA86C7CE2A63B1DCB3
+:10271000F729E3AE3AC9EF5D6CD9BF649E3969F31E
+:10272000ABC533289F00F96526CE8BD214101676E0
+:10273000B1FE1597E9C6797CF27EEE0617F677EAC8
+:10274000C5DFA64B25BDBC03B08AF5E854A43023F1
+:10275000D48F7CEDF28CC54F761DC8DE539EB74DED
+:10276000120144BB285BD06EBA711E95EFB9D85FD9
+:10277000AC3CD2C3FA855E45AC08F56FE789BD393C
+:1027800063F0F9B2AD0EDF1CB19C74B297F6BE2DAA
+:10279000DDFED7995BE87DB4871EDAB7D6736C2F60
+:1027A0006DFD5CB6554AA5BC4365D81170EB7DE55F
+:1027B0003A3DB2C7D995D6CFBE453E9C497980FAFD
+:1027C00057CEF1BE7CB25B82DCFCBEEF2FDEF4990B
+:1027D00093F4EC14A550BCB48FCA026746DF76A709
+:1027E0005E4C65FD3DD52E85A5FC8BEF630786CB42
+:1027F00002A7B13B689F1419FD27D247F4A7290E01
+:10280000AB279C8E23196840EB850A88105F49ED41
+:102810006F7D2D8DEDEB3F9915505C83EBAC77F61A
+:10282000E6B537F938CFCD796D73954BABF7719E1F
+:102830009B9FAF50DD1AC575FF9A65E7AF035192B4
+:10284000C3436F426923CFD260FFF5DC7EACA35C4B
+:102850001D3E5D89C74360BACC7ED255CAD430F5DF
+:10286000DF63E67A5DE3A9FF7499FA597D207B0363
+:10287000F1E29D59C2EE8CEB2A7E762A3E777438BF
+:1028800030E0C4F63404D67B4E621CC17C17AAA784
+:10289000E713501FC9DFD849F61ADF77F965D0E38F
+:1028A000E4ECD153408FC37D6A7166421D4CE36DE9
+:1028B000FF44B2F7E267406050C2FBA5105016E03B
+:1028C000FC0288A728AE3FA3BC20F1FD43629F8A8B
+:1028D000F197FCDF8947E3F60D480E6185F4FD0AA8
+:1028E000CBDF0A44C36F9A38EF722B4E2DFF20B115
+:1028F000FDE48BC4AD47B32CFF60100C22BDAD27A7
+:10290000FDA6FDF2A673DCE1B0CE3768C673917FF9
+:1029100006F9843C03A9F2E7080DF851D6CE6B54B2
+:10292000D4EB40997C7F21D6573FB547D4A7C8DB6D
+:102930000BB0DEF0D4DE6B54D493C0E5729903E79C
+:102940001736DFBC6606D65579EB6292BF2A8356EE
+:102950008FB85A9D1EA9A1BAC30FDAAA81348E2E50
+:1029600070A16F0FD17C1A068246F8532BC4BEA902
+:10297000E9CE30CD5595A7CD8FEF67ADD338C9F1EE
+:10298000AE0FF43AEC27D5150951DD89FD521DF43F
+:10299000C2E9546F188A3119AEAF54D5A7733E19E6
+:1029A000974938F8765C30FC84BF7AAF93ED9F5A34
+:1029B00061E8846FF255486F2EB544FDCA235E5519
+:1029C000948D2D84FB589D0A1B7D146FBCD442B896
+:1029D0003DEE74F3BEDD9CF19863140E5DEACEBB50
+:1029E0009F94EA7D69CB8FA8BCDA177A268BFBC14E
+:1029F000081DDFBFF50E6523C741693503683FC079
+:102A0000407DC5CFEB2D7F0242A8AF34F65ED4D710
+:102A1000714481A8A7A37BF534791E4AC6169EC7C8
+:102A2000CD2E318FF9E182FA2E9CC738577828F9DC
+:102A3000AB38FE261AFF5657B888E2268CF93A685A
+:102A40001EC7EFBC4CCC0386300F309E14D2C75348
+:102A5000AF517FD5D8BF8BEDB991BE2087B78CF928
+:102A6000F44CCA0B0A5524B44312271B8C7AF27318
+:102A7000A758F106740ABBACE32FC77FCAF91C6ADA
+:102A8000FFC52199FD8CD27D89F89E74681BEB836C
+:102A9000B630AD26A39C4C5322DEA7B4A1FF847CA4
+:102AA00035E522F14134490F2249F9F580955FC798
+:102AB000966A7CFED7B65B073D156F65216EE6A86A
+:102AC000A29D0E86C1FC12D065DA979E430BA1949D
+:102AD000EAA0D702D68766897C67B25D6B4DB26B80
+:102AE000361EC71CD5EE221E1F7314EEA4F55CA57E
+:102AF000A4B17DED41FB8ACDE378CFC1FEE038186B
+:102B0000FBEC54DF85F9AED7DE26F29ED748E4BB56
+:102B1000AC59897C971D4CE4BBDCF989FC363094B8
+:102B2000C86783178F4A783EB4A634A17ED98AC974
+:102B300009EDF3D190C4D70BD7CC4E685FD4342FB6
+:102B4000A13EA2F9D684F623C30B139E8F7E79692A
+:102B500022BFA2DF4872D81905F805E13789AFC74F
+:102B6000446A13DB2B539505843FC427E9C7E56D01
+:102B70000F27F46FF3B589BFFDF1B592F29A42FBCE
+:102B8000D4857E9D341979DB672A04A33E3C9D766B
+:102B9000F203DADF8BF175B62F11A75FC09C72CA02
+:102BA00057A5429079FA42F15CBD753EA1A40ABBDB
+:102BB000A964C8355B295F9925F2088D5956BE571F
+:102BC0001338E9DE3582CF55CE79F224E2171DFDA8
+:102BD000014AEE753B8648C42FE6748828E8473ED4
+:102BE0009492B787FCD6AEFBD203D2A0B8736DE443
+:102BF000B5FA00E392FB5BF1C100C6E53959E7BCC9
+:102C0000F5D34A50223EC12EF3659CF76A1916D3BC
+:102C1000FC1E97E53BE3CF2126F8843F3DC127E624
+:102C2000393835B284702E6B82CF57CB2C0BFA31EA
+:102C300028EF909E059C47057368E38CA9F8DCDBC0
+:102C400055ACA3BE4D7F7A68E3ACEFA37799FA1A2F
+:102C5000F35DA9A9029F9F4298EBE390FF08FFB79D
+:102C6000CAC87B38E47C5F8D43D289FF8C0A1F8DF4
+:102C7000EB0633BD94E578279D5F78C127D552FEDA
+:102C8000A7975FF56FCAFACAFFCDA55364F29F7A82
+:102C90001629BCFE9EC5CF9DFEC217A78FB8D64E83
+:102CA0000284AA6750BEE63DA77EFD4492DF4185BF
+:102CB000F378BFA37603FBF67BB1F87CF186A70619
+:102CC000D0BD8AF78AC579B6FDF93D963CEFF1890A
+:102CD00073ECEA459F396F6539A03F8BFC5915FEAF
+:102CE0009CFD4DAD006A32D04EC3EA1EAE3F6A086D
+:102CF0007FF0114AC2E2FB1E8769A6917FD07E9FBA
+:102D000049F98F9B8F8BF8FFE67F88FC953DDE436A
+:102D10003E078FF390355E69476802EDDFF5A488C2
+:102D20009C6F0A4D207B12D440A7FEE78716FCE873
+:102D300010D6E73E86F0D0C4736A3F6F0862149FD6
+:102D4000BF03817777E01256FBC43C6E84A083708A
+:102D50007F0C42A7DFC5F91CF78AF63109F48D71A3
+:102D6000FD5D6FF577FC8E653BC8AED378343ECD04
+:102D700087C69FAB4101D5ED7E92C7BD010C87F0A0
+:102D800083820EB2E7856432F0792DC615A427B58B
+:102D90004B5281E29ADA5DAE30E1BB7BE9B9969F96
+:102DA000E314FFB420B6438AD3CB5B9A15D0112726
+:102DB000FFE935FEA78FFC8CF22C8EA72E14E7D8E6
+:102DC000712961DB449EBA99290CE0B0858BF9ED3D
+:102DD0005965969FF01CF5F7FEEE96A1486D707050
+:102DE000E44B45E42FC3F84BEB1FF5FC55D25B1DBC
+:102DF000ED36E4B17D617BD21D9519B7A8E7AF929E
+:102E00009E7439DC1AF1D8C5F5DC6021D9FEA32205
+:102E100007FC2AD9D5762595E29E7472DE6CBD45F5
+:102E2000DCA52BB2D05BCA08607C34DAD66BF3EE3B
+:102E3000D9FBF8DC35D18FC0FAF42DF17E83B25E78
+:102E4000A1FCC617863BAAD0E714FF50DEC4F227C8
+:102E500082F84BFC3CA23931EEEFE32F50BC7409F1
+:102E6000FEC27E9F15EF5A3C6CFB0917CBAB6D235E
+:102E7000BF02CB48B1D0FF483485ED71A9C507101A
+:102E80004D63BF3BD9CF40FFE21DE221DBBF48EEDF
+:102E9000FF3D9FF027FE6CF99DAF648B52552326B2
+:102EA000ED63FA7CD04CF2BB21C2799F6C43F8D918
+:102EB000A9C86B1938F82C8A4DF17DA774A6D88D56
+:102EC0007AF091AFB2710DF2A77B98CDAF958D6F6F
+:102ED0002234AE3C7FA55C8AFD8D3FA070DEA867E2
+:102EE000DF28BE4776A1758F47BC93718DEE9F2C6E
+:102EF000B35DE9103CD892A9FF7E0AF9A10714A09E
+:102F0000FB501EB5CBE9ED675D3B89E746A05DCE82
+:102F1000167187BB4D3228EFE2D6457CE8A1FB0352
+:102F200064C743C071F8E9AD851C2FBE922DE4F152
+:102F30006F99C17F905E7C2A1D99A815F6CADFEEB5
+:102F4000BF94FCBA927EE52D65C7F97391E8DB1555
+:102F5000CCD7B3745919D757EE76BDBAB98C0FBF19
+:102F6000AA9AB3B81C49F908FCA83A2AE470A6AD9D
+:102F70003EB3BFBC46756EE75E9207FCDE0394EF7E
+:102F8000ADFEB73FB2FEBD3A17A185FBF1BFBF1A38
+:102F9000CDFD0DCAF65AF14927CF67545097C8BFE7
+:102FA000AC7609FE3DF395C2EDEC7EC7B44D5334CB
+:102FB000D4839268D35E8E73DA5D3AE1CDF3220852
+:102FC000F9B57B98AF542DF631D971B51DE37494E2
+:102FD0005F4B4AEC4FD47F6C974BDF48FBE56CE2CC
+:102FE000F6B12290A93E12E5B62D8DE4DF04997169
+:102FF000EBF1B43FCB97EC103746989EAB4DF0BD4C
+:10300000B87D7D255BDC1B9A922DF0D6921295D36C
+:1030100044BFB091E7D53B4F9A9747B3E73992F356
+:10302000372D4E9CA78FE7A5116E46829827B48F47
+:10303000D0496F549C0FF1B93A0C64A298E47955C9
+:103040008F85301A6D787C157CCB37C43FD529BD70
+:103050007537EA664B818DFB5F36CE18125F47C22B
+:103060002CEF7D7FEE339B1A57A39E9CB0EC11EAA8
+:103070009B11AF6F1ED510F7956E446AF592BE197D
+:10308000FC3C07FBA89BC4F528DBDB1B45BC5ABCFA
+:1030900041FD9C9E6F8DA605E87C2CE37C06BF5FFE
+:1030A000D5E9603B53F99F37649450DE4CDEFBE07A
+:1030B000162C3F5B10194EFECA9401A1DB08AFAF7E
+:1030C0007FB090EF9F7CDAE208CCC12915FF4A82DD
+:1030D00074EC7FE92B1E3E87FFD9899EE837A487D1
+:1030E000BF92C2947FEB76984F0E167574CC709C8D
+:1030F000F6FF70529EF3EAB60F9D5D58FE3D3BB45D
+:10310000281BD755DE56379DE437099AEA29BF8830
+:10311000FC1C62BDF05B7ECCD1E11BEB480F63A1D0
+:10312000CBE6A11E3D912DFC0C5BFEED961EEF261D
+:103130007F05CB1D961FB563CF2D857A9CDE99B098
+:1031400097F363AB60DF6092B3FD7977589D457864
+:103150001A7DCC7DA71187B7B5162FACB5F47D4885
+:103160004EE86192C3B23D7F71A6E3FA3F936233AA
+:10317000D3A57F4AEFCD04BD47BF2C1EDF7DF43DB4
+:1031800049DFAAD59893F3AF278179EAD5636D1CFF
+:1031900007BEFAB0E625DE8058F036AA7FF9AE9376
+:1031A000F30F3B2CBFBCEEDD2FC7529EF0CB5DCBA7
+:1031B0002E233957663B587EA81F1529A4875B81AB
+:1031C00079D2D6E312D26349DC7F25BC97907EE4A6
+:1031D000937E74CE66BDDD2183D053A12FA81F1A24
+:1031E000E5FD4B34D4177E7F04F3404BE7DBA3A807
+:1031F000BD89DB5244F3538D1BE879E46D95EF5D97
+:1032000095B41F4F213C95B47256E15BBD1E2F4112
+:1032100030FE1CE4842F9DE77BC2F22F3FB5EC50BB
+:103220002A5D0288D39B383B2FEAB61F609E6FFC55
+:103230001BEA59A1512693FF5B7B58D897DADF4CE4
+:10324000BE7E8BA8B3DD9F68D44CA7A3D0F2594DA6
+:10325000648E607230329DC258B2333AEEC3042C91
+:103260000DE4D9A9F33BDF7408751E4DE76DAD7B06
+:10327000AF194D714CF77B2EF0907FD632FB553A4B
+:1032800047EF7ECF03B2D4978F295F1B8FBFE4B285
+:103290005BEA4AA77C5767F6C9D9AA07F56692B5D3
+:1032A0002EF3E3D951F5C2EFD9E5DC1CA393F4AAC0
+:1032B0002A37C465F791BFE7200C61C7D1BFA4933B
+:1032C0001FD1EA34466B5C625CD48F5D7C235BF873
+:1032D000D5E3ADF362D243CADB9E6ECEDAC07A6824
+:1032E000745E47F6E41E49DB43E7E467B345FC64DC
+:1032F000C7BB770B570616B7DE3093FC286D9002DC
+:1033000074AE72CFD38E84B874B869B2FF5F859003
+:103310000A233E2AAD73CCC549FED108883A290F4D
+:10332000531D4AAB896A7DF3D395561EBAF222F13A
+:10333000EDD96CCBAF2A8442F2AB101F9CE788BD5D
+:10334000AB0436E2C7AFCA41D627F327206F623EEF
+:1033500085D519997DFDAC5FE41AB3FCB8DE3FF961
+:103360002C3B63E50D632D5298F5E265E07E269FC8
+:10337000D437D07919CAE5983F87D6058CB3C9AA46
+:10338000C979FFC9FE423029AF8A344E7A714FBBEA
+:10339000140E53FBB0589F8ABFE4577E015B1AC8D6
+:1033A000DD9C043196C3BD24073E3F4F9243F39109
+:1033B000FD94F65A1E493A9FB9409E7E1B40BFE7D6
+:1033C0002D3939969CF2202FDEFFE4C47E3FF16256
+:1033D0006FBEC7641C7CE610F7F9DEB6FAC79F74AF
+:1033E000BA5FF591B5FED21C0B2F1060399C243FBB
+:1033F0001BF7B5CA9243E5CB961C1E137871E32FD9
+:10340000C9A11AC2BCFEE5D6FA93D789E3EFA77823
+:10341000F35EF4D309978BD727E26DA92587A549D9
+:1034200072A80A4962DCB022C6B5E281BBC0FE11B7
+:10343000F35C6ACD33795ECB1CC0385A863832F5DE
+:10344000FFBE7926EFD3B53956BE66148C4AD8A78D
+:10345000595997B44F85A06750BC69FBD9361E9265
+:10346000DF9B69F9D957370B7FB3B573EF1AD2FFDA
+:10347000D25D8A467E406B674F3A9D7395ED522828
+:10348000ED02DDED656B4DE4C5ED1DC36EA07BEF78
+:10349000A54764D687B2C3A5610FC523874B530BDD
+:1034A000F9BC51CFA2F1BB0F09FBDB7D68D83B25EE
+:1034B000ECC7CF184F345377A83495FC84ED20F235
+:1034C0000CD2E1BFFD8EC62D3BA04EA4BC6403EE22
+:1034D00007F57BF5730B3693BFB13047E401F67700
+:1034E000D6DE48FBB9FC90ACD1E7670E89FB82952C
+:1034F000CF2B6199F657F9B1EF367CFE45BB4313EC
+:10350000F375F0F8D5BB8AB2EE4AEBDDFF85365E87
+:10351000BDFA5373C80F1C98CAF7B3AE1EEA60BB5E
+:10352000786A50EA2FE7607FC38DFC6FF111C6FD0A
+:103530003EF5C6FD22BE6D91C08F0BD9EFBFDF49AE
+:10354000F1C3A90A7794FA39B5F38893CE7FA7B768
+:103550001E11E777D6F9B58DA764F99FEE4CB1EE51
+:10356000DD3439699F961FB1EB5D4EB2E741CB9FC9
+:10357000AA7AF143AE2FA5B880E6F3A2C4F71FDF05
+:10358000DCF53A9F03566D11E7804BDB9E70125EAF
+:1035900097223E75E21168629E5ED6E6D4FAE39504
+:1035A0007B9B13EB4B2E82CB176CFE1809230997DC
+:1035B0005F4E13BC1E892EBCAC85F253275C8C93E6
+:1035C000EFC027DBC743561EAA272A1BCECB7BDBC7
+:1035D0009D39D4E3A47B5333DBCFB2FCE6B4EF993F
+:1035E0004172F901842A699D3F684FD5C86F9DD308
+:1035F00025F86476BB2B1C96E87964B5B83721F8BA
+:10360000E85E6B7FBB773FC4EB37D14E15A17E5789
+:1036100076DC3F93FDE652C8A73CD5294039D384D8
+:10362000D727EED3B5C58972990D67EFA0F7703C27
+:1036300008F3F94517CB799975CFE85AE8E271AEEE
+:10364000253963BD7BE0E8EBD9DE609C4AF7F82AB8
+:10365000B724F6579564072339C22E5F2C1F90BC00
+:103660001F9D49FB312726F86AF6512540F9FB8E4C
+:10367000E8AA12CAF3DAF249DE8F0EFDBBCFCB7F88
+:1036800067F9DF76FD7ACBFF8D68E19F97E17A0FCE
+:103690008076C4640F0FF87B1F0F6C1DC8F9DFA97B
+:1036A000B9C20E7C31ECCDB13AFE59F9D61B79CEB8
+:1036B000028E374EE6D0FD33B9FDE7E436BE354421
+:1036C000011FC51D186790BEFDCCFFD1E365E389DE
+:1036D00067A193CE81AAD5A63974FE51BDC511A0AC
+:1036E0003803D45803F1C467BB249DE2F5AB092726
+:1036F000389F60BB7415E104FDF8BFE5A01C83860C
+:10370000D7C1FEC70C09E8C864EE8CB34E92EBA19A
+:10371000247F7ECE85FDF9BFE7C4E54D0E0C2BCC92
+:103720005848A5AAE766A65DD89FAFFA4AF893F66F
+:10373000E755A8C724F7AA7689FDDF5E7F32576276
+:103740007F72D7434E8A53BB25ED6C2A0A6464AE60
+:10375000F53D06F42BE8FECF3DB6999256B3DEB4A4
+:10376000EEFDE426CE53FECA010584432CE10AE4B3
+:10377000D3B797324F9D419CD3F9F8BD5AA881FA2F
+:10378000D54250B30EEDC519223C8A1F76481C0F56
+:1037900027EB3D281F309EED7BCECB4A3634D051EF
+:1037A0007F1DACB2E2AAD55C8EDE7D9CC719FD867A
+:1037B000539335CE4B38395F188EEBAFA02FCF2CFB
+:1037C000BFD83DBBDC441CD7BD9DB29678B8FB800A
+:1037D000A251DEA775EFD72F0C223F0CFDF002E2BD
+:1037E00079CB5F69DDEBE1B8B8FB485A98E4F9A9F9
+:1037F00085D753567EBBAE5C61F9C89344397AF7DE
+:10380000EB058483EE5DE7F242B8DFAFEE7E7D9498
+:10381000C1FB1F16F7F25E4EBCE7B83C92788F11E1
+:10382000E7C5F766AA8F89F3339CD770A7AF775E99
+:103830003BD4AEF4403F7A26497B79FF6429313E80
+:10384000ADFE95128CBF0F84EBB993F8EF3A4B7F26
+:1038500010EF396447E7E5EA3CBFBA76B1DFF22EF4
+:1038600051E2F837897C8B83C7EFF3BCC2ACE47DAF
+:10387000CF4FE573EA0E15CC0CAC779CF070DCF7FB
+:10388000E0DB4B47C4E7E140127174B52396C3F106
+:10389000E81199E787FCC7F75D66B73B7C2829D814
+:1038A0005FF06B95F96DAC0413B01F93C6CDA53CCA
+:1038B000E03E7EFF9865AFAB2789F75759386A7DA0
+:1038C0007B762AC585DDBBB2F91EF27CCB5FACCA24
+:1038D0000D2EC9CDEE8D632EE48FC6C559FC5E3525
+:1038E000AE93F469FB0957788E4471F0B963B7D190
+:1038F0007A0FA8FCFD8BBA5D2E93E2B5EAF73D9CEA
+:10390000B78050E8728AEB1EDC7DEF08F1A5CE553A
+:10391000BC1F5FEE3EB086DFDBE9E0D383E5BBDEB4
+:10392000CD617BBC63C253E4EFA07F732DF93BDB19
+:10393000DB1DECEF941E1ECF78DB7E687C562105E4
+:10394000601048A57E971F5083A4E7CB0F8CFFED36
+:103950001CF2530E57B0BF231D1E9F453C5546F128
+:103960002FF93B078671DD5E8F99ABF07ABAF77855
+:10397000384F214181C00B0C4BC04B65EB6FD80F0A
+:10398000A86C538C78DCD8EF3D9DABB2DC9B6DBC52
+:10399000442483F1B05594956DDB73681DCB1C11E5
+:1039A000DEDFBA2D0EF1BC459440DF4FC5F7CC8069
+:1039B000CCFBF95BFA08F7E1A0145E4476F2A0E5CF
+:1039C000FF1F7C2F7419F1E0C169A1115416F9137E
+:1039D000F9D0840A9E3748F378DF4FB70A3F2C7935
+:1039E0001FF3FC22EE4FCF8284F33BBBF4FA053E7B
+:1039F000663B45DE88FCB78139D6F996CE767806E7
+:103A0000F1D13C7F9644F9FC3F587AF38E75BE03A2
+:103A1000E5C2FFB6F3F8685F1DF1DFE748CEEBFFC4
+:103A200070DF64B61BAF49E29E41A438901DE86781
+:103A30005E37FCC091E0B7F4793E2B91FF7E7811A0
+:103A4000BFEA80CD7FC361B8F0F7D35289BFBFE82A
+:103A5000403F96E396F0B0E098BEE3D8FCB21F7901
+:103A60004F47DEEB40DEA3F29FC85B1DCF9D70F198
+:103A7000F381BA91C739CF7470CF7BAF7999873D05
+:103A80006C7FAE3CFFE79CFEE65507F378FF57C11D
+:103A90008D09F8B571701AC4F78A937170D6B67F24
+:103AA000D0D5504B7A6BB86BF8DEA3D2B4A6B85021
+:103AB0009C1F52DC5DDD3E97BF37639F2B7E6B6F93
+:103AC000DBEE03B2477523CFAD26BB70DABA9F8E0B
+:103AD000F3CE73C5D98FD303CFF2F3072B2066E261
+:103AE000F33D235D6C1F97CF90F89C01017C8CBE49
+:103AF00097729D657E97471167A4CF1807505C3F6A
+:103B0000BCF5C3D5B43F37A17D35BC2407916F5DAB
+:103B10007EA3C4F9A7EBCB13F7BF0E324DC1FF3E16
+:103B20002E4740E74CBAA77FB321B19F36D7486CE8
+:103B30007FD3FCB98CD379D67DAD9B6F9F7B15E18C
+:103B4000FC06EBDEFAC5F035CA1FF2511EA3BBB36B
+:103B5000E7A6313A9DEBFD471EC9A5CAD2A3C0080E
+:103B6000BD8DCEE502BFD5C6D5E33B2F877B765210
+:103B7000BDDBF44974BEADFBC53E3CE90BE5F98500
+:103B80001DDA49E776554EB746FB61F7B73E579CBD
+:103B9000FF1F748487109FD87A1CC885B2FBD2E2BD
+:103BA000F757E8659E755E04259776BE5837F2ADE7
+:103BB000B1C49307F71C18EB8CDBBF53B5A1116C94
+:103BC0009F76BD99A3A7C5E34EB670A7722949F3A6
+:103BD0002CBB9B88C35384C3122ADFCDA1FBC3A790
+:103BE0005BA7674B7A9C5DDEF14E7A515CBFA7DB29
+:103BF000C5BD5D8CCB86FF7040FC3C7FCAF33C1D8D
+:103C000011FDA1E4F8DCAC6AE7B889E23E229894A1
+:103C100001AD1AB670B3B8F7546FFD3B04BA7D1E00
+:103C20006E0CCEA7F3CE1A93CA8813F87D73B78BA8
+:103C3000CFF3BAD11C4539DFA86D10DF5BAA5186DE
+:103C400060BD1CB4B3747E7397DFCEB7D428067EF4
+:103C50003EC910F7B790C7F9BEDA9439E21C1A9F33
+:103C6000F37DB5A93510E0734FEBF9E459E2F9F7AC
+:103C7000A08B03FC2B2935857A360D7495EAD3C1C8
+:103C8000ACA7F394F6D66D0AA523A239AAF7633739
+:103C90008818EF3BF294D4CDC7361EB1313A4B9C15
+:103CA000B797E0C70AD9EB89A0F758F3E27B35E56F
+:103CB00086BE8DD6D368D99129D0C9F309D0A0B4D6
+:103CC000EF5F03E7DFA6A89DBC8E01BA9E49E724FB
+:103CD0005BF7D5727D3746BB7CAF31CB6AFF89B8C5
+:103CE0008F7E851AE675E6D488F69320DAEF3AFFE0
+:103CF000873F9FC7B5D7DBED88B09DEF5E828A8B8B
+:103D0000F3AAF78B7F276272930427904C03856296
+:103D10003DD8BFC2E73256FFA96E511F04FAB6273D
+:103D2000E8DEB2B51E80191AC9438AE6C8DFA45E70
+:103D3000BADCBA7380E79B7E57ECCC23E37BCFAF32
+:103D400002EDB99CB77D4C92630ADD9B740F11F7AD
+:103D50006DA310A1FBC548F309DF877AD63FEF19A1
+:103D60003FCD23043AF929C9F7FB5E0E6FE4FB2C23
+:103D7000F3EDFB2D43004EE6F4DE1B701488FB2EA2
+:103D80000E3AB7D7F8BE6119C59574CF90FA7D5F2A
+:103D9000DA52C49DA9E109D4FF6A459CDF9FF3E490
+:103DA000F13CED7B400FA5E4F13CBBA641449AD227
+:103DB000F73E40AA2BB298BFB7E5068DCEB9FADE22
+:103DC0000F10DF0B442DD2E9FE8F5A01D12BB0BD6D
+:103DD0003A48DCEB4CBE5F7CCE23EEEDD8F7131EE9
+:103DE0004A798DEF31DAF711689D53ED75CA9772F4
+:103DF0003FC1748CCAEFBD6F89EBDF43FC68DFBB4A
+:103E0000443B5D24FE1D9128DB8354437CFF4CC35F
+:103E1000FD51459C1C735122D7C0FD29EEDD1FBA10
+:103E200040453CB17ABAADBF9197F9FB6A2807AE1D
+:103E30001704DC24CFE4F5FD5F7E40836A70460002
+:103E400000000000000000001F8B080000000000C0
+:103E5000000B93906760F8518FC04DC2A87C74EC42
+:103E60002A8ACADF2C825F3D213C9F05C1BE22C049
+:103E7000C0A0CA01C1CFD821782A103742B10707A4
+:103E800004877022F438F33330F80271383FAAB94E
+:103E90001E4C10DA879181A18B01682610EF45D264
+:103EA000A7C80CA1EF3B32302C774388F75B313049
+:103EB0005C03E29BD694F96B140F0DEC1B8ECA9F2A
+:103EC0001080CA5F14C4C0F00949CDC400D2CC6FC1
+:103ED0008800A6DD08DCF20F6250F9A969A8FC0889
+:103EE00034F96D05A8FCA5B1101A0022F46663C868
+:103EF00003000000000000001F8B0800000000000D
+:103F0000000BC57D0D8014C59968F5744F4FCF6CBB
+:103F1000CF4CEF320BB3EB823DCB02AB2ED2C08A3B
+:103F20008BC1D82C3F21892F19D1E8E219AF010F9D
+:103F300057451D09A79B4433CDFEB1BBEEC21038D7
+:103F40005C08EA80A06834593C4DF0DD253708F163
+:103F5000F0E2DDEDE5793EF30ECDE25FD433C9EA60
+:103F60000B81BCE0F9EAFBAA7AB7BB995DF4E25D8C
+:103F700036E735D5555DF5D5F77DF5FDD5573521B6
+:103F8000750AA93997908FE0EF3242CCFCBA26929D
+:103F900020442101A3A79E902099777425216423B2
+:103FA000FD8FCC27A4139E15F4BF64199657C675D0
+:103FB000422E2244AC0A1C0FC50891D48C4D746863
+:103FC000641608FDFE7C42323B1304FFDE9847482E
+:103FD0002D19FD932612721EFC2340C824CD7E1697
+:103FE000DAB70B2433C92064B3330EC90556D2EFB8
+:103FF0002F38A2901E8D903A3218205309B9900C98
+:10400000E3D3209A08CF39C4C0673D49E3F3370BA7
+:1040100087EE8467A7669D4BCA0959AB5AE746E805
+:104020003877BE36F8AA40DF7749A60EEFC90236C8
+:104030000F67FEFE272136817635CAF5A640E138A6
+:1040400031408C1E78DB68E0FCECC788D146CB8A17
+:104050003A1010C8E8779D59420A33E81CB50CB1F4
+:10406000EA28DC497B50A4F8A91BB088A5122227B6
+:10407000892DCEA2DF01AE68BF6DA5245F972224F3
+:104080005445DFD54379F00928D3764473959DFED6
+:10409000DB4A8DA45A375AEE88CE7B3904F4D28895
+:1040A0003E83B6930A9F277A14C63789459F41C934
+:1040B0002602ADA7B449EDA36306950C2B57B17248
+:1040C000DB87ABB16C57D03239130F6B8148140FBB
+:1040D000E7EF67F04A2AC98B74C262E1996723B49B
+:1040E0002C26891146AA1A26E025A812ED31A857D8
+:1040F000597B51237B4A048023FF2C9489C6C6BD7B
+:1041000080D7CB49EDA1400AE02A044AEAF19D019B
+:1041100070D4413DF49760F592E6C517E0C78DAFC6
+:1041200060E2E3E1AB2D25340D40DFA7E726AF8A3F
+:10413000BADE7F28B2F7F4EF6DE0570171867F2A6F
+:104140002D9F27B07FB71201F1E1E2B30DB00ED67B
+:1041500012CA67B47CE76383D7C37BBA0E489AF66A
+:10416000BF5DB632D05E52655BBC10E6312C031FDA
+:10417000FCBA94E0787E7C7F8BE3BB23BAD41CA28C
+:1041800070B7DD6390741DE07B3ED255540D62CD57
+:10419000A4FD003E015FFB193E256580E1F77146F5
+:1041A000C75914D100579D5A082CA4E3AC94AD59BB
+:1041B0005016002EFA7D5B746912F893AE8756781C
+:1041C0001F225F8DC3FBB1D7834C0A741147804710
+:1041D00044C48AF6D6050C27506E50F38B041DE9B3
+:1041E000542BD5C3D28A18626A940F64E01B2853FB
+:1041F000FE84F52426BC7C2301DFB8DA53BEDA53F3
+:10420000027497ECC338CF249BD77C5E3FC2174A19
+:10421000BE2DC6F8CA003C5CC2EB258DD5039F407D
+:10422000794B94F28DC0F804F8664B94F289C0F88B
+:104230004A739529D12B000F5BA25A85EAA2CF962B
+:1042400011BE9950E1E69B2D1F4EADA0C28818BB50
+:10425000BF622FA6F264CB92E971AB6E6C3CB6657F
+:10426000D33BA469AEB2C0F8A02D4C9A9EA44F7364
+:10427000AFB6E20680B14A9FD383FC67BC6CC17CB9
+:1042800012B44C4BCF00FF5D04F2D77C06F8A42D8E
+:10429000A0AD4079B45426FB52205CF58AE514FEAB
+:1042A0008621EDE7201728DE75B65E772C8AB9F0F7
+:1042B000DEB164DE08DE67FC17E2BDDB87F76E1F48
+:1042C000DE9DB2838FEE682EE9C67BF708DEB77AF3
+:1042D000D66BF7B48915B08EBA39FE7F6553FC5F93
+:1042E00042484AB2C518EDB78BCA25C09FF476DAAA
+:1042F0008CE967D2416C11F53726B8CA8AA15453AC
+:1043000018CB5E14894DDB97E5521B808F89CAE478
+:1043100011681CF7F8325DA705859019F4F911CCE6
+:104320002711C132AE0702FDCBD8FF67A8FC8D5123
+:104330007CDC255BEF03BD426F5836C043D434AEFE
+:104340004314141341DF72DD282C43BC9556917C35
+:104350000FFD6E89789D0970505D634CA2389B08F3
+:104360004B98AEB7A058150651D146329AA6C2FA5C
+:10437000FD33CFFA5512C40EC7E9D3D4058DF263CD
+:10438000B04AF6C0175C460A612A8F44219A78AB7E
+:1043900084BEB8985CCCD6B52E403F65928EF3179C
+:1043A0006B02C61E260A0584A3690AF2A133CE0455
+:1043B00081C9AB50B455A14A9A6CA899A380DCEA94
+:1043C0005297C7C938EB403C259202C58F764AC048
+:1043D000A7A85AF3819EDB43D6336FC2B83AC171A6
+:1043E000A94CD1810F1555DFF339019E39D248FB15
+:1043F0003504B60E16D730F911A67C1C4A41BD4DC6
+:104400004C5A1FD60DD4BFA5AA7508BF27CCBE989D
+:10441000A4DAA8BFBB53B21E12CE84EB50AA3389D4
+:10442000F04F9B9704F8DB0E85D9BAD0E57CB848ED
+:10443000FB0675C834813F253BB9DCC51F5DB0AEB6
+:10444000E9F7139B0CB2CA858712D2680817217E40
+:1044500005A05B99494C68B745D2C2A5AE7612C794
+:10446000EB16932C1B2882C7FFC7F5C4A3E5E625EE
+:104470004239A32BD859F3C8E81FE8AD8B0923DED6
+:1044800067C8F01489D2F7B650A13328A0DE5A04C9
+:1044900070FCEEE75C5F0D5933405F517DB018FA58
+:1044A000FBB8FA203CA20FAA34E4235EF6DB4917DE
+:1044B00068854610AF33D5A100E889CED470A340FB
+:1044C000E9F53F6473398C37220F0F7527753A6E03
+:1044D000D7A3F39A00AF5D071A9A4CD7FC57005E3A
+:1044E00040FE094C0F7754AC41FB87CA31B47F1CA6
+:1044F0003D2949834C1F3E456633FD38C4CA0759E0
+:1045000079963A1C5849FBED0C5A49A043A72367FA
+:10451000889DBCC235EF2B381D663EE5D763EFB4EE
+:10452000967C223DC6E1E1F2F4C233E4E9F0B32522
+:104530002E793A8BDB3F7E79DAE993A79D3E79DAD3
+:10454000E993A79D51CB234F47E6797AB5479E76ED
+:104550007ED8960493E1D005CFDA8BA9FDDD5931E1
+:10456000BE1EEBF5E9B1DE20E3F7CEC9ECE9BC7F76
+:1045700088AFD36D828CCFDE5256DF4BD7C79345C1
+:10458000FA77DA3BF2392559FD2BE9BC36D6327978
+:10459000DE5635C7063C9C005C81DD97BBC2143CEF
+:1045A00072BA905C0D78AF310DB79C8A70795DCB93
+:1045B000E535A98920FF22BF568FCAEBDE80D5845E
+:1045C0007C5BE9E853B6AE673E65313B7B449F7246
+:1045D000FA5751FAEBC08763E8D3848FFE092FFDA9
+:1045E00043551F8FFE41F62DB50B19FD1D7FA1C34D
+:1045F00047FF0E1FFD3BA2690FFD3B46E87FA587E5
+:10460000FE1DE56B92207F3B381FFC9B40F9A0927A
+:10461000C2F1B75A23C041FD3CE4FB994F19E45E57
+:104620005807BA94A1B63D091EA4FE9E4BBFFAF5E9
+:104630006A5BD5F87AC0D1A3D3812EA9227A5449D6
+:1046400013589F67D2D9AB8F1DFA513DFB2AC8136F
+:10465000E5A98C0DE228A85805C0FF2BE5E62F4000
+:10466000DEDDB02E7D1C9E4F3CFD16EA07B2DF203A
+:10467000432AEA9F269BAEFB4EC14A56D5B9D70BBB
+:10468000E3D733D70B15729780B8F8D02C8C333F13
+:10469000E7B92E9C1E06B83A2BB6A31F3822771E08
+:1046A000A54A09ED7ABBC906F95BD1E9A157578A3A
+:1046B000707AB525AF9AE97ECFE8D5057054023EF1
+:1046C0004ED80007FC0D4DF4FADBE8BF703DF09BBF
+:1046D00095D46F1147FD954E2D2D06CA47FD162A1C
+:1046E000FFA5C027F007D0F7457FC7EB0F4CB757A2
+:1046F000BD0C7C738228560FC8AD4B334A5A457E99
+:1047000040FB6063152D83BC48CA8A40FDE14E958D
+:10471000EA39C0477255570AFD426B2EA89536EE0E
+:104720004F2F4A5AE837D0F713422EFF0EDEBF0E46
+:104730007EB56625458A3F39D3A800DC1DDA72852F
+:10474000B8F028AB5652A6EF37AA4C9F76063347EF
+:1047500053202FABC8DC563A4E88FAEB73E9FB4383
+:10476000C94684AF435B57007EEBA42A12E6B1A88A
+:104770008A32287D8612ABF260377426285FABF050
+:104780003E83E3FBF1E3C0ED94436A86C82E7CC20E
+:1047900078A28B9F4252A620707F7A0FA513C9DDA5
+:1047A000672A6017723F34A0A76D8C4398D3E7F453
+:1047B0005096B934C0F4DF197449C81EB9D61936F9
+:1047C0009A00EF242D1065DED8FD51CB0DE5EED912
+:1047D000FA73E222D3AD750F0EC1F7B644205EB472
+:1047E000E1D2CC235096EC90D69A00FD9F797008C8
+:1047F000E4A8AC686DB4FFFB4A6228CF5A8E45111D
+:104800007F9B003F21D0230A3E7BB21A3EBBB249B8
+:104810007C126291E9B4FDC9C640BE07ED6B662704
+:104820008D3C6BD8F3A100D317B70422F8BC87974F
+:10483000A9F9887C903B8B1D1A6F088CCE8FFE17D0
+:1048400035BCF2A7A4B6CC530EEB959EF67EBB47C3
+:10485000924C62007C12850FE44AFCF2E41AD7F80D
+:10486000D70544C49F285E9101BAB40B5E7DF95A06
+:1048700080D93727020A3E0D327CF823B013D400CA
+:10488000FA03B1E872BB00BA40209969181391DEAF
+:104890001B72E0A3F45103E9B7603DC782435A1984
+:1048A000C40DC4D9C305D05B1364B4A7DB372C4750
+:1048B0007E70C61B0C30FBE63A8E37316418B5A803
+:1048C00047647D4F0AC637791C46DF0D7468DB30BC
+:1048D0006718C6B74B65D4534E3F416A78437CC3D3
+:1048E0000F8F7F7E7191F1ED87303FFABCECF4655C
+:1048F0000AD89D7D6A60599EB6EB93E83A4B40B961
+:104900003A6F0BFFFDF43B035F3EF87FCCE9731D6C
+:10491000A78F04F4A91FA54FAF4AE9538FAB04E951
+:10492000D32B31B9D10BF3498DCEC78FA7FFEA79CD
+:1049300039788E4703E93CA57F3CC8E08A47BD70C3
+:10494000FD77E1D98147E5F0A81C1EF54F0D4FC05A
+:10495000C2F5B389F3E32669488175F4A79227620B
+:10496000491AD72BC0B7DCA53F9CF5EAC0BB19E0BC
+:10497000A5ED364BC308EF5B944DA1DE995714F0BB
+:104980004CDF47836C7D45A37F9AF5E5C0D3C3E137
+:10499000EDE1EBA347FDD3D09D8E5D2B817C2511EE
+:1049A00003E45B42B2668810F77FE1ABA483BEFFED
+:1049B000C00C0CF75C04F28FC5EF1DFD4778DC06D8
+:1049C000BBD20959784A42FB3C6210D45751324459
+:1049D000C0CE8A83A4A6F65129D1316E03910B98DB
+:1049E0003F210BD05E4A841DFFF98FEDEF3AEC4F6B
+:1049F00030B7908F4A3E467F12ED6FEAA7D8DF5955
+:104A0000E00B935DD81F65CBC447D44EEFA67A9FC9
+:104A10001A99F4FFC2A85F4ED4B178571BB503E0D2
+:104A2000FD466A07C093484F9B013A8E6AC83AD840
+:104A300029AAF624C615B41F87481C7C626E87021B
+:104A4000BB831D5A524B8E07A81E2A31BCF12EA5DE
+:104A50004A1E970F3ACAA74F1ACFDF05499F524601
+:104A6000DB8FD5EEBFFA0976652A385A96D46A0CE0
+:104A70006E8D352FB1CE62C8212CDE38F25D8058A4
+:104A8000A0D7DAD4550AFA41A73FFA489C4718C97B
+:104A900008F823E98662F8E80327D0652706B5CE33
+:104AA0003B046ADA05933798432E38364347E5F0DE
+:104AB0007EAD39349E7C93D24DE0DF539AA23DB156
+:104AC000A5E47A72BC0EECC5EB91CE9DE513536064
+:104AD000EFC3CE0B8C4B1415ED58870F0F955F8DE0
+:104AE000F1BA8E8AAB93608F7704D349F02B8E9600
+:104AF000FFC0847E3B4FC749C800BFA21AE3199D7F
+:104B0000A7A74ECA14995709E523C023EE6FA4182E
+:104B10005F394E14C6B388D505FE42C95111E31062
+:104B20005B4A7E6C8AF5CC0F86FE65958E4BC75F1F
+:104B3000563F60C2BEA56CA956483BB31F671CFA1E
+:104B400027601C02DA38EB4AF0D41785C35F966BF6
+:104B5000022C4E9020F9B622ED834ACC2EB910E4F7
+:104B6000DBC87B0DC6AD7961669CC59F65A22B3005
+:104B7000B460C2FA19E5F7BC87CE440B8CF65B0D26
+:104B8000ABC1EE02FF2844940CAC4B3F3E3B65D2D8
+:104B90008C7EB36436B1FDDDB239E0278CC5D752C7
+:104BA000B2EB7DB01FC7AA0F697201F84C4A64ECE2
+:104BB00095182709189F4311D13B285C88CFF761CE
+:104BC0009F35A449EFBAF9F017A237BEDDA6568F7C
+:104BD0001BD7EAA0EB8BCC18BB3E281B16FA53243C
+:104BE000F332F84F12B910E725553DF7728AC231FA
+:104BF000CCED5B29C1F6FB8846ED3C17DE04D91CE1
+:104C000016419F44583FFEFECBE4C6DF82FED92208
+:104C1000A67F07CFAED43CAE77BCEB46B30CBEAE9E
+:104C2000CD983091F12DFBCB1702608F5AAA0974F1
+:104C300009D6EF811814D12A45262F6BA5D7001E5F
+:104C400093FE0FE35EE6DBC7088533B680BE77C709
+:104C50005DCC08CAD12061ED1D7E1401CFB06FE09C
+:104C60007BAF4A3E3C670F92D75DF141FACA2CB642
+:104C7000DFF97CB0B14C2A3F737EE023C2FE3C6575
+:104C80002FE433AA2586210F6007D087EA85ADD9A6
+:104C90005A7CDE9735905EDFC93660B93D6B62F9AC
+:104CA000DEEC322CDF9F4D6359AE6857008F3B2AF4
+:104CB000723B04F477E734BE403FD911CDFD1CF6BA
+:104CC0008F883DABF1058A9F1DB01173092133A573
+:104CD0000B1A6D685FCACAF3A4D98D36E59B1DD344
+:104CE000722B02D8BE82B59FCCEA2F93E6B2F63380
+:104CF00059F98B52036B1FE6F19BAAABCE926FC0A2
+:104D0000E4DB51516772AE2A817910A2BE8A08F4A1
+:104D1000D58E721E87E2FD50742A5744C7EEE726EF
+:104D200089EDFFCAF00AEC184D42FDBA23F5C9E03F
+:104D3000094B3913F1431635BE48F115061EA92457
+:104D4000E42FDB3F8BF3439144E79B6D375B71BEF0
+:104D50003379FF54DF7CC5A56FEE9082B82E76CCF8
+:104D6000F6CEE36CE37F8D9A19F08C5F3E847B6412
+:104D7000A744EB5A8996A3D7150AB20E71A42759F6
+:104D80001C8FE36BECFE6C1CFF1EC06FF9687BD5BB
+:104D900030F1FB051C5FF7AF6F443EB911CAE5A3C4
+:104DA00065C037C84B198473FD283EC71C4F73C9B3
+:104DB000F1EA33F99B4869CC0F58256A1E7AA7455A
+:104DC000CD035F5865EBE6E3E26BA9AFBF39BE7276
+:104DD000ADAFFF8AC703A4610E25E90D8171ED888F
+:104DE00005BEEF60A399CB0B9BC5FF46CA5C4F9DE8
+:104DF000AD7C7A86B7CCE81322D7C699FDC9ECCD35
+:104E00003F27BC8D7FBE86CB9E13A11D2BEBD42FDD
+:104E100042BD4ABCF54EFF2371A95689B4D5839D86
+:104E2000F12D8C5BB5D8212D449F27C353F22486E6
+:104E3000F1D947985CCA5CCCF4646616E64D08C5A7
+:104E4000F3361CFC77658DAD6FB8E49E52B581805A
+:104E50003C260B58DCDAE4717DA5CA78A807E11C72
+:104E60002E807C9612C65CD8AF785A929DFDFDA725
+:104E700081CFFFA7C4F815F6255701DF2D900D301F
+:104E80008BA3449FB40AE268F37F8771E0A834885B
+:104E900071F2688D80FC02F15BB77C382C05BCFA9E
+:104EA000DC879FC6205B671BB3E91D3514FECD93DD
+:104EB000539B17409CE71F451E6F1F463DBE69FE72
+:104EC000C400C0BD31C8F040F56501F681DAB24AD0
+:104ED0000196F8335235F6B3693EB3A70FCD9F1E46
+:104EE000C73C9668A409FCCFD094160BFA39397BDD
+:104EF000E00250959B53050276D4C9D70E7C660319
+:104F000081EF6338DF4DA93B703FC3FE57318FFB04
+:104F10003064A81FF675620D1AE6456C9ECCF068E9
+:104F20005F44F2FB683FE1068A7717FFC648CE84EC
+:104F3000ADA4C55189E525359087981D69C62A5CC1
+:104F40007E0CA5EB46185FB2D40CE89760CD00C28A
+:104F5000134E8A44A76561CA3202F19CBB56A91957
+:104F6000B0E7C4DFFF2F1BF721685F4FC3F775CC95
+:104F7000CFD0E8FFD83A370BF783FDD710D240FFE8
+:104F80002A355E3F443A760BD901FE4B63603838D0
+:104F90001FA8E0A203EC7F3458B702FF49C4F51DF7
+:104FA000E8DD0FE7A611FF0DEB221B806FC4EBE2DB
+:104FB0004077B181E5DF8956ACB0D8B5EFA21E0BC2
+:104FC000FFE488DBEE0E52FD0CF1799F7E1EE9674F
+:104FD0000CFD7C32ABFCE408A5EBD54166D73C1F49
+:104FE000349520A5EFBB416F5CCC795E1D64F1C4A4
+:104FF000AD92D908ED1CBE12671492868AFB7FA879
+:105000003F2A8203CF82BE14DBD249889776047D83
+:10501000EF17F1F7E1E2E3584111FBDD1C1C4C12E4
+:1050200097FF1CE274DD2C6408D889F61D31639F5C
+:1050300001EF33C80765CB74C1AE80C60DA760DD34
+:105040002BC918DAF34E7DC50DACBE3D35D804FC36
+:105050006657A88CFFDF3393E04F74CD9FE8D95794
+:105060006C08B2384C3B5F0F9B825EF9B098E3ED61
+:10507000A26090B58B72FDA7B525DDEB73A41F6E02
+:105080006F2C0B3ED20A78D84C5F637E5E4A463E58
+:105090002726DB8F74E4E498FAC0271F43BACFFFBA
+:1050A0004DFAE3FA5E79DF10D4197E056297BAC72C
+:1050B000D73624210E45A5FE471F4D04FC118C2335
+:1050C000B8DA33FD5FA0F5D44F5340578830AF3581
+:1050D0000590BBD4AECB4C30202EBED65C4DCB1B46
+:1050E000E9BA03D5B2326E3500BF983CCF4FD158E4
+:1050F0005C414EA6D1FEADC9AD18773FCABFDFD225
+:105100009E32711F33D6D1DB28CD07FA9849B0FB08
+:10511000121D5D8DB0AFD97EA94992B09F5A41F260
+:10512000AD29C0E75FA0BF7882620EE400B9AC9001
+:1051300064763E957CF3385FC1BEAB7A1B01BE201E
+:10514000BA84FE87CCED61D9975FE3ACABB1E06D7B
+:10515000F1ADCFF5BEF55993560C903B7D2F327FC4
+:1051600073AC7E9CF5492E66FB5163B5DB9865FBFD
+:105170002D5D41D3063C4B72E665F4BBE7C98E7CDE
+:10518000F7F063235FC795D037EAC11CB32388913A
+:10519000043A84E4B4057EB6C4ED74E7BB5DFCBBA1
+:1051A0005084D5FBE1A0FE4D0EC60FC5D2CC8F02B8
+:1051B000210FF6AC64EA5714A1AFB32F45E5C97DC2
+:1051C00041804373EC0F532FC60F8E9E4F120BE39B
+:1051D0001D942ECC0F4B7AE3EDD40FDB1D1C1FCE9C
+:1051E0007DFF1938B77379276BE902D32F06C241C7
+:1051F000757C0EE000D901F0CF93D34F42FFDDE57F
+:10520000CB0AC4254FDA1CBFB97639B6EB9E76B50A
+:10521000BE52853C889CC7DE77EC8DB66C9EC9F18A
+:105220005A96CF2CAACC9E3D631FBE86F187A8E478
+:10523000D04E08E7B6988122FBE9CE7EFC77F97E56
+:10524000BC1307182BBFED2E916460BD9FFC565E0A
+:105250005E4E9F37171E95ABE97CDFE4F2EC57D921
+:105260005308DFC96FB179DD7C70B7BCC8C5A76FC3
+:105270000799BD7333D73F743CD93BCF0D3C8E1D8E
+:105280002F805C78F7A88872612C3E6F4E1E3E22FC
+:10529000B9E6FDF67E11E3F844B2BF04DFDF9C17E8
+:1052A00003C5EC767FBCA339F91CF673F29EBC0CE7
+:1052B000FCF1ABAC22BC1E64F383FCA29B9FDA2DF5
+:1052C000832D7736B85FE2EB27CFBF3F79CF30E64B
+:1052D000F3C60BBFC73CA5B83D6C427E13D006FD9C
+:1052E000B405FA6E80EFB2D31F61BCDFBF2F1B86FF
+:1052F000F9CD1D2D772F60717422E596E17E4E4D1C
+:1053000020500C3FFEF985617E7347F1BA09F03AEF
+:105310008E3FD39B2D1C918263D7ABF3D9FE821AAB
+:105320002CE0BEE3D9C68F1AB43F173F3970F49E04
+:1053300085BE7D0087CBBEDE6478F769CE366EAC65
+:105340009E7EEF8947DAA47622C80B82361D695FFC
+:105350003F0BE2CD155684F420FF4B1F80DC70E23A
+:10536000CB15CA97C8DD7346FB4BDE40EB3DFDE530
+:1053700030DE5DD144E50EB5CB88BBDEB57FAE80B7
+:105380005C80BC0FBD13E356A21E413925D6486F81
+:105390000D295EF830CF97CB8D8DA504FB6D9F2C2A
+:1053A000303B829023B07F21E98E3F41E53AEC67A4
+:1053B00068F3D09F5824CB45F304A8BE5D245F3426
+:1053C0007A4EC1C9576F2F65795F442D7E3E02FC2E
+:1053D00003371F38F875FC01727AEEDB60AFB40555
+:1053E0006AEF003DDA3979653FDA61E54CCF80CD6F
+:1053F0000FF3302F275CCF33B8AFE1703A71330A27
+:10540000DF35005F906488901A85CFC94B236AA26C
+:10541000287CED63C0D73E0A5F12E113EAEE70C745
+:105420002D1DB846FA99BC10ED3D3BEAE84786E7EA
+:1054300020E019E171F2B2199E3363E33983F34836
+:1054400038784E3BF9F76403F873F453D1187B3E78
+:105450009272F50E90430E1F04399CFE7324DDBE3C
+:10546000BC3027AFDA394772B63CEB8E69DB8BE68E
+:10547000518E9E376079B34477CE1B6458999F2331
+:10548000E9FE7035AE5FE71C0949D47BF0B945F6FB
+:10549000FB9F36B72BB87EAC61EB65A56CB5C890A9
+:1054A0001F91E81CC4F5C0F5D96D3E3BC379FE667B
+:1054B000B293B7E95F07C3AF7ED3B50EF68E4D9FAB
+:1054C000BDC5D6C16F7E3483F1D9C1F2A271A5DB0F
+:1054D000942B3D74199D17F34330258BE265674289
+:1054E00059B192FEB38F30F87B04EDF31B287EFF99
+:1054F000EE42EBAF61DCDBAE1A9401DCCA661280CF
+:10550000F13673BF6A89D81B7E8DCEABDFAA8EAF12
+:10551000A2CF9FCB42D1FC9C7BA95D07FCDE9155BD
+:10552000F079F29519E3C6B7F7646D8FFCDC532769
+:10553000A1FCDCD3F5E46023D8C3899A397C0FA899
+:105540007D22F083AEEF017CFED4373EC5DB4FDD1C
+:105550007C7DEFCCAB799C9A9DEF72E62F99F98513
+:10556000350916BFCD1B80AA1CDA1D151A310A0495
+:10557000F1F022D0FBD61AD20AF1BCDB6E304C78A7
+:105580003A78A0F80D4FA7DFEF787EDA1CB71D7CC4
+:105590004188F113A92F63F6A044EDD2A2F1504641
+:1055A0009F07299EEA30C9BE80F2B91BCA2E3C6C07
+:1055B00097AD37018EAABB23C88755197E4E87E762
+:1055C0007F0844395281FCA5EDE6FCF5CE23C85F87
+:1055D0001367037F0DCB81B1F86B18FAF5F397527F
+:1055E00093B141A7F484ADDF021E4B84410DFCA4AE
+:1055F00073EF2E201EBB1D3FCA263F037E9AC2F3C7
+:10560000B6F08F8E7B8EC1E8521162FE65BC2A2FE8
+:1056100004687DCDFEF704383FB291C7FFCF9D3CB3
+:10562000FC2FB06F45FE5524B04E27D73DB5701105
+:10563000F82FA6320CFB01F105838780EE615A0634
+:10564000393479BD1680F11D7FA1B2795080726C1A
+:105650007D5E20AE3C95909C41FF684AD59ACB6117
+:10566000FF4098F2F606889F6DDC42303E75CEDA38
+:105670004201E4E794869006FEDDB9293310067FE7
+:10568000EF0E62409C27D5CEEACF3195348C1B6F4C
+:10569000C930252B65C8952EFB5AADB26E85FE57D5
+:1056A00087AD8A10E43B180C8F4A55C184E63B82D3
+:1056B000D49EA5E5F0828299463EBC93AC74C9B5F0
+:1056C000F343DC1FA92166DEC59F3B39936F59BCAC
+:1056D000277C631DB48BF07C9EF5A686716D968F3A
+:1056E00017063ED5914FCF0BD17EF4E6C1E780146B
+:1056F000B7D51826E09BAE4F8C7351382A348CFFF7
+:10570000CB18E7A2747B0992F1D580976E4A95B9C0
+:1057100017E8F6AACCE2013DE5057203C54392D233
+:105720004B8778D1B1E7C914DAEE9F2A4422C0969C
+:1057300046D22EFC88964B299EC037560DBBF00AE8
+:10574000F8D14D2570B68E906ABDA716F8A1999D27
+:105750004FA478FA2CE0294E86082C597571E11077
+:10576000C0BB47CAFCE21EDA6ECF51D1B075D7BAC2
+:10577000E1FE9C83AFA95DF619F61193D3A604ED63
+:10578000162B25B83E0E7379B65D4E7F11F0B258D8
+:105790007B1FD70B51277CAC38BCFFFD29C3880386
+:1057A000FE5627576EABA176E9AA962DDB6A68579D
+:1057B000CD2D8F6E053BF5B5DED531B73FFD56D704
+:1057C0005FC6D87ACAC4AEA5F35AD5CFFCE49341DC
+:1057D0002B76092DFFB25B345A619E7C5F7B0D27CF
+:1057E000C1A1FB431837FCE56E01F3109BFB051BC1
+:1057F00052134F965A53807F7EB9E3AE29C5FCE819
+:1058000035C784009905F52BA714CB4F69EEDF88C7
+:10581000FBE0CDD4C1368BD86F77058CA400790618
+:10582000D9FDBB203EECD81BDF08E9582F3B7E8416
+:1058300062607C65E1AB9F4F425E723A647D1DF011
+:10584000DB7EFC73B8BF7DB8746912ECA975AF84B8
+:10585000709DDD256766682E78EF8AC916F29FBABB
+:10586000CD4387F5A1A04F4FD93C1E4E9AE01CA70F
+:105870001D231AEC1F2F560DD4E31F0C09D87F07E8
+:10588000F72FFDF3955ABEBBD5ED67490983E8AE06
+:1058900038A258EB8D27E6607D415C30C4F21F6F63
+:1058A0000B595B615EB00C5BCA20EFF5F1AD4C9F0C
+:1058B0007AF388ED46ED65888FDBE7CB3AC0D733C6
+:1058C000D3D10B79B41B5A252A50619DD6923D90B5
+:1058D000AFB811E0A5535D5C9BB703AE798CC58F63
+:1058E0003DD996ADA00F5B816610F7AD0DECDE23C0
+:1058F00080BF93D90AFAB42F6B637D4FED9197C1A6
+:105900006EECA9D2E16C1269D57226C8BF563D7FF4
+:10591000B41AC70FCC81BCDDB66C17EBCFCC1F6DB2
+:1059200074BDEFC8E6D87B3BBF6CAAEB7DA8E57BD6
+:1059300038EF56B27BD922D77B07BE56AA99A71655
+:105940007DBFB70BDA77C37BE27EBFFFA85E7FE641
+:10595000FB1E75AF027684C0FD8E5635B70CFCCEAB
+:105960001EAD1AE5528FAA637EFFE8FBC5C5DF278F
+:105970005A09CBD7F2BF9784A2EF938140F1F70C7D
+:105980001E3F3D285FBC1472D91911CE1754B66161
+:105990007EB8641870B68D14A6EA1F043F33DAEEA1
+:1059A0008D10B34F5A1CFED30D94DF54F8DEB1D1E5
+:1059B000B50EC4C5069150DEFADE6BD4EFF2C83DD9
+:1059C0003F1F92FE30F0E144BE4E12693C177E3616
+:1059D000FEA2FCB895D9674DF80C1196B7EC6F771D
+:1059E000C2B1677CE3B6507A29CCEE1EDE371BECE1
+:1059F00062C366F3D2D66D44F99D99C1FC4836DF87
+:105A000033E695F0FA93CEFB76BE4E9CF26470249A
+:105A100040FFE973141DE27A9A8D7A76E1AB2B5838
+:105A20007E0DC89FBA33E5CF58F3BE37DBB40DF611
+:105A300091BAB3163EDB8C391AC8B3365522058CA1
+:105A400057A4E1503F09D6E4D9B9516A42113A3F0F
+:105A5000B9CEC47877B086ED3A4B89CC8DE8671C17
+:105A60000B936929B03773E44617FEC29CDE91D3CD
+:105A7000D99A16EA97875BD6A0DE88246F403D72DC
+:105A8000578C58C5F635828ACCE5507AAA42E7ADE4
+:105A9000B4EC2D2E7FB6B0F3CC2289181B503E32C9
+:105AA0003DFEC1B130EA0F51B543C5E2BC52CB6AED
+:105AB000D45B0B01F7E580C7F988C7BB6423F9AD58
+:105AC00004CA6990C0E47074DECB56FDD9F1196C3C
+:105AD000D98AF3125BBE89CF51FA1A183B12357678
+:105AE000DE0ECECF4FD3817E063B5F666686C55203
+:105AF000773FDB593FD6B671F173E1087ECCA54AFA
+:105B00007911BC3C415E06BD71324A34D88F3AFCF3
+:105B1000CAC538FEBAE36C3D2C566DB64F4EE91A35
+:105B20002AC5F5539B718DD39BB5B7D504415E361D
+:105B3000E3330CF802B80C3E9F1AA6872817E07CC6
+:105B40007AB2196CD791ED427E0AD79826E80555AE
+:105B5000CDA03C1E695F4FDB13A8CFE3FA8C423D1A
+:105B600071D573FC846B06701F2FE8FF3EE9D45B90
+:105B7000C8675183C2E95A3F541FDF02F890135D92
+:105B80009EF74A721BE2D58FA723C767C487C689D1
+:105B9000CBE7B2FDA8171C7D934B194D608774733A
+:105BA000BDB491EB9F4DA03F82B0AEBAF0B94F4962
+:105BB00071BB4CC37C388C2B53B831E103F5456283
+:105BC0000FC429FA82AC2C56913CE847850CA0D230
+:105BD00055215F732A1D4762F5DD0BF47C1BA5631D
+:105BE0005FD8403B9AEA096579117FAA5BFD36CA06
+:105BF000EDBE52D6AE2F9553EC049E139EB3C7153F
+:105C00005F88CA2C1EE9BC8F4672695696B03C5616
+:105C1000FFE1E8B735E83F5A66A07E8D56E734DBF2
+:105C2000F59DD3AE4FA6FD2546DFF745F2CBB05C20
+:105C30001B18B7FF1E750F83BF8CC35F9D67F0D71E
+:105C40007AE1EF91F2CABA71FCE8480DA58F27BF3F
+:105C500094D2C9A33FF22C3FBBAECBF33EDE90F310
+:105C6000940FBF3263D2906B9C234353C7E597B721
+:105C7000805F5C72FBADB0753DA1EBEB64D7F58B3B
+:105C8000DB17D072D09A22D0F214CD6E5F3699DA3B
+:105C9000AD5C6EDCD8B212D7D79ADED532D869ABFC
+:105CA0005A6E61E55D02FA456BB85C20C49241DF33
+:105CB000BC93CA9CECA1FDFC5261769BA357D768AC
+:105CC000D67328677C7A754DD25A5A4CFFACE90AD4
+:105CD0007AF4AAF37E55CB6A943F23E5DEA90C2E15
+:105CE000AE1F57811C9F8BE34C69A276DEAB4A182E
+:105CF000E1786DDF7D53402FBD23E4AEFF06E8E37E
+:105D00009B229E7328CED3899BA7434CFE12C97A4F
+:105D10000ECE69BCB6411CEE993D763F6BB8DEF005
+:105D2000F7F30A97E36B381E42A7E328DF56EDBB73
+:105D30006F3FC603A5DC941594DFFE59513C719268
+:105D400055D6368FBCFEA4F3FEDFBCBF57F9F81F53
+:105D5000F77BA77E4238ECDBBFCB9F07F6C27F966E
+:105D60002F765653BEA0F89B148E78ECAD3F962F3D
+:105D70001C7F64CDE92C013DEED0211DE2F94B12D0
+:105D8000857BA61BFFB326AE70ADEFFF50D879A27E
+:105D900072388C5B04FFFEF9BFD31C0940FCF49DF4
+:105DA000A34BF0BC4133C7C34E39777DBA6E140F95
+:105DB0006F513DD5EE5A6F37F6AE7EAE81CEF3A66B
+:105DC000BDA952C1C5CF37EDDDB2B43201782B9DEC
+:105DD00003FAA4792FC3DF8DFD1BB6B57BFC410709
+:105DE0008FB9DF031E178415EFFAAAB596068AD875
+:105DF000AD6B0CEBB94011BB752C3CDEC4FBDB1961
+:105E0000CB6D7A987EF73A7970452BACEBA38BE299
+:105E1000E1BA517CAD4A323FFB756E5FBF45F58EEE
+:105E20007BBEAF4BFAA6F91007EF1267BBEF077AFC
+:105E30005DD137AD28F65ED5FFA958FBD7764D8BDF
+:105E4000AD2C224FCFA017D7A376A3F1761EFA79F7
+:105E50003564B4D1260714EBDA30857743EC9266CB
+:105E600090F377BD26E0FD0DAFAB7BDE81F88C5F54
+:105E7000EFEECDEA82DB6FAD1923BFE5BAB0C0D734
+:105E800007C3DB39196F1E6CBCD95B561BBC65851B
+:105E9000B8CAA9D17E10A279A3F77A38FA00FEDE3B
+:105EA0009B88F62EEAEBE050E96AC8F7595893C38D
+:105EB000FC930FD480EE3EDF7AA65C238511BD8370
+:105EC000312CA530A24F3E467E737BB669BB3BFEAC
+:105ED0003B725E91CB0FA9E5FAEDC0F747683FC76B
+:105EE000D1CF6E75F6FDF97D25790FBDC49687710A
+:105EF0009D684EBE2EC97BE249BDE1C2CB9087B101
+:105F0000BBFB687BB06234FFE791F0CBED90DFE242
+:105F1000DC1B40CC6DEC7BDA3DD0B764DAD57B8BF3
+:105F2000EFD3B6E3F84AE138C6E9620D19964F4758
+:105F300075DF04C843A6B81D44FF2287E77FE30B43
+:105F400058BCF0BB9CCFC2CA293C7FD4BDE0671AC5
+:105F5000D49F9CEC6DEFB42343BA09EBA5E45276D1
+:105F6000AECF697FE8956B4817D84B0D813CD0893F
+:105F70003E21F79E44674A79DC3F34133C1E9D1B4B
+:105F8000371E6DE61612C87FA1A4C4BC33880BB7B8
+:105F900081BDAE4B984F2F1912E675AD8C5B07C3D0
+:105FA00045E2C7CE3863F3091BE7DB591DF3116BDC
+:105FB000F6AB88A7B66302CE675BB676EB1B41B43F
+:105FC000CB591EDDB5ECFCC08429C6711DE4CF4B56
+:105FD0002C5E4CE99E02B933E95889C6F45CE6E2CE
+:105FE0002BDDF7666559DE4DD932B64FE387439412
+:105FF0008D21B0AF5A8E850C3867FD78D0FA59984C
+:10600000E25788B5CC00BB67C2E506C6BBCB26E924
+:10601000B3058A87EE1252482769B9443F001E60D3
+:10602000EEDEE796A8749E6521C63743DD133A215C
+:10603000CFB86CAA3E9BE561972C853CEEB273F419
+:10604000F7E1FB8E1265E932CA47651426763EFFFA
+:10605000C812D8A72FBB80952B7BD9F78EBCCDD18A
+:10606000F50078D898B5B6039EDE0EB378B1261940
+:106070001857FE77E0078853D175F106DE534304C5
+:10608000986788D78B2D6BB6BF3117DE73FA24491A
+:1060900081B8D6FDDF5D680D03FD6E4D0F2D8514B3
+:1060A000A960C2D9E7197E19E8EF9CA35D22D6C585
+:1060B0005F73C9A76F46985C1225B62EFBB249DC08
+:1060C000DFE9A7F8C67814DFEFE9CAEA84F90FB56B
+:1060D000F894222C8E5042F4F8144AAF128BEDA79C
+:1060E00096585D83EEF315A4AED03F2247AAF1BEC9
+:1060F0001AC4EF9448CD1258972D63C8CB0887ABCC
+:10610000A4E5A7FD808F281C3CC0F2E1FE37E68E97
+:10611000CD8FF7AEFC81DE49E95516097780EBE2B9
+:106120001F4F2216FA23D2E5CD8556B423482644C4
+:10613000F940AA5B433A6959AB96B06C3E6E923512
+:106140001047E7F99A747D5445601F2A99C1BB082E
+:106150009CF5E1F44F397F09DC8B10AE1F403FF016
+:1061600064B478FE6E47F614C66517454AD9FE7CBE
+:10617000759301FA6AACF673222C8E7992CB2FDAE2
+:106180005E77EF3B2C8AB07894ABBE76B5A79E7D48
+:106190006F72FC9D2C67E328D5CDC5FB19AD4FFE72
+:1061A00085A79EC5754F568CD4D7BAF5ECC8F79322
+:1061B000193E1A7B521DC0FF8B22CCAEA27061FE2D
+:1061C00030FDCE70C7312E8FE81E392F27287E3C38
+:1061D000768CA4A8AE7358444B24ABE6B1FB80E0A8
+:1061E000EFF0D0D77E710FA5DBE6A3A20121EE2050
+:1061F000D1032C4F536F7CAE1EDD54CFB9A170DD9F
+:10620000C15D6EBF6833F583C63B071AD4A6EF02A3
+:10621000BD43FB8D7F763C7DD945EE1FE997F27932
+:106220007FD05E0172A5B367CE92049513FD61879E
+:106230004F162D81B8647F94C989AE4803E2A94BFB
+:106240004893A5E01F0864601F459932656818F3FC
+:1062500007A2D353AD14B59B08CFCF4C06304F796E
+:10626000D325D716202F40FEA1ACC3FECCA686E5D1
+:106270001A93DBD27F403E6407C87A8A874820831E
+:10628000F821FFC0F2AB3B21045536CE7C9383FD51
+:106290006E7F73C79A6BD97E6BE2D477DE70CD2F99
+:1062A00064F2F809971BB646ECCFC27AA9D176BB47
+:1062B000F5E9F3117ECF607619EA01E7BD215B9B1A
+:1062C0002310DF48068E8720AFD1BA7C2BACF30CAD
+:1062D000E7176ABF2A3C3F1FED1BC78EA1EBB2D068
+:1062E0009E18D56790F7102992BFF150B619E52D89
+:1062F000E1FBE429CE2FD5E4AA784180B84706E532
+:106300007047D6C667F5B1490188BB52AD6F4C687E
+:1063100080F675CF1E013B7851603844F542AA4B98
+:10632000FA9DDBFEF5E7553E18F1E65512B12EF069
+:106330009304DC7B11C0B8D8C62CC5DFB433E109A7
+:10634000E96623D0CDC9AF0CD7B0FD0451D5D8FE36
+:1063500038CFEF4CA9EC1EB514CF033D1B3C077C96
+:10636000F09C20758D26A55BACE521949FA196EF4E
+:10637000A05C0D3410B48362ED04ED0C078E405523
+:10638000DA86FC745853F05FACE561FC0EF0047AD9
+:10639000DAC153A8E501ECC70F8FDC50C0B82BA5BC
+:1063A0001CBE471F86CADD94C1E7E16BEFB43B72A8
+:1063B000C3446C77F72CF305E08F17406E41DE4F36
+:1063C000B6BFFF0D8C4FE5FB81AE0E7D0FBF32894E
+:1063D000DDD75947304E2A5DFE3705D87FDCA7054B
+:1063E00030BFB66DDB6B782EA26421DC088AFA869A
+:1063F000F0F81CAEA3A049E189B9F8BF8EC2E1E272
+:10640000FF7FE3FCDB95ED423E39C6E568573687F2
+:106410006522FE2DEE0B9DD0496602F5B3BAAB06A0
+:106420004CA07B0DA53B71C54395C9E900AC97E035
+:1064300036369E7F1C872F1C7D1ECC0DD8D00FA119
+:10644000FD2CAA80F78CEEFEEFFC741FF6D1FDB296
+:10645000D37103EED1A8E1F9BDA485FEB9CEDFFA70
+:10646000D7BF437FA77CF89519F1A171E46347B6C4
+:106470007F3BD8070F67F3F8EC48ACC3734CD4FEEE
+:10648000C8835D19E4F7F606550BEFDBA165038EB3
+:106490009AC849562FF37A59B57ACE4B6019EB83D7
+:1064A000E537B486719DB37C818EC4AA6721BFA0F5
+:1064B0009AE70F3CB26B15DE4BBAB19F98309760EC
+:1064C000F9FA67A1BDCEDB7726D73D0BE3A9A6F38A
+:1064D000FD3ABC172BB48BB50FE5ACDC42908B0DAD
+:1064E0002C8EEB9CBBAD6ED1707F5B71EA3323F5D4
+:1064F0003DE7D1B26EB27A35677DFBF3409F052C44
+:106500008EEBD44F69D610CF31A887EF2DA73EF37D
+:106510000F505FB58D7DAFE5323FC37AD55B5FC964
+:10652000FB8F43BD2B2E3D2D475191C0FE76C3FE00
+:106530008408E57AE49ADDD304E46B5636C86EC865
+:106540009F6F530EE3BA14C33FC575EBAC9F8EEC3F
+:1065500000AE9F87B307F1B937BB1F9FCE79A39ACF
+:106560007E96BF30356136829E5A52C2F8DFFF0CEC
+:106570004F1E40BE8FC388E06B41BCB71ED7D3709F
+:106580000F96D378DEA88AD6EFD48AF13B5BEF531F
+:10659000E81FF0A9C367478E5F8C4F7FBC92745190
+:1065A0003E73E737DA796FB965BFB79C19D8EEB695
+:1065B0003B49F3416FBD55F0D69B47BD6563D0D3D2
+:1065C000DE816367B67FEB62B487D9BED3CE7252E9
+:1065D00001F1E31C3F37D907FB50B87F90C3FA7E27
+:1065E000BE9FF040B605CBBB603F621AC6D7F17DB7
+:1065F00077B669EB62946BCDF85E6E7968EB624AB0
+:10660000AFB525FCFEC1B8B5B6E422C8732147403A
+:106610001E53DB1EEF459648C686BC8B9D61F35A20
+:10662000882345F4411270E1EBEB258277BF5FB21E
+:10663000883B9FFCEB9C8E8EFD6D4EB609E415DB0E
+:10664000299B403CBBA584D973866C7EBDA41CE607
+:1066500049C751C10F66E7C8AAD6EB187F92A95F58
+:106660000EF026E97291C19F36D8FBC919EF7EC69C
+:10667000CED221CCDBD95B4E70BF58ADA3F377C926
+:106680002D67BFE856657917CC37CAE38BEDA56B4C
+:106690002A985D93C3B8C076D93254F0AF8F853055
+:1066A0003F245CC3F2A7D685D3DDF0DDC957EE6386
+:1066B000794D6030821D41E58CCF4FFA2B6837A6AB
+:1066C0009F148DA09DE4F79362AA77DFB72FCBF2DA
+:1066D000E1BAB97FD4097ED334887B303FC9C98FF2
+:1066E000F3AFC33E9E1F7A6F96DA59B0EEA29D7843
+:1066F0003F72B73C60C3FEBBDDA81CD857E49CFBCF
+:10670000939C1FC221CAD9D06F5D81E9B180F62F59
+:10671000259F8173D1943FCA609F2A5098E8F2BFA9
+:10672000C0E46E2EC3E751710E9CCB28EE67FC844B
+:10673000F7DFC9FD08B9F2A8BD1BE8F9C3892990A4
+:106740009F321F570E150A2817458270B66BCF6A05
+:106750006E3FC2E9A79DB0FBCF1C7BB497DBA36360
+:10676000E911B58EE2C3C50F51D96BB78EF55D7BCC
+:1067700056F3DC0FD9279BF622A06380BC0F76B4BA
+:10678000F33E1A324D38D748162977B8F11BD4E8B2
+:10679000F72E3E3D45FD81F1E25AD42FBE1FE8267B
+:1067A000A89C1EAB781E0CC90460FFA8EDAFAAF729
+:1067B000B8F3CA05CE37FBB68D1F2F83FBDCE1FC97
+:1067C000783BDC573203E4B5E6B91F6023CF0FBC3A
+:1067D000EF9C7F22C75DF8FE035FC7EA9060021C52
+:1067E000C1AF99EBD245EAFF50E2C41F89549960CA
+:1067F0007284E517A7D1CF95B83D1DACE9C27BE403
+:1068000083AA7C9CE747FF01D6BF3FAF789F6AE031
+:1068100039CD7DAA0C3E0B695B1940F8C2D3BB2A67
+:10682000DC7EE171CE0F3D821D07FFC07E5EC43865
+:1068300044E4FC65C62ACFFA4A79F2862A2C8A6794
+:10684000175DCE966F2A992C7FB9BB849D1F6E8BE6
+:10685000DD8C72E331393D41A5E5445AEB027F1FDF
+:10686000EEAF00F939D22ECAE4CB3FC6CC6E98A762
+:106870002337BE1235932067FCEDDA785E9533AE90
+:10688000E89C9B863F3ABFEA76EB61A07FD9171759
+:106890001C073F654FFB9A79200FBB4B44272E7B8B
+:1068A000240870E8ECDCD92C55F7DE73D29EB121B8
+:1068B00045A2EC8B9717DA69BB0E9EB76D36D9A44B
+:1068C000589CCFA18BA4B1F36B4E1EF3CAB889F2CA
+:1068D000F0D77CBD974DC82467BBF07715E7DF91F3
+:1068E0007C7AC2E3C5601CE97C3E2037A14CF5DF11
+:1068F0009754067FD9A4742BCA1D91649EA6CF49D4
+:10690000DB08DE93BA372AA3FD0DF91637C13AF832
+:10691000492D61F7FD99580F7EF84E8C3FA6D16F37
+:106920000D59AA0EFCA6C07EC954B85762009F2A12
+:1069300019C4678C0CE3538388EFD4D1FB243B3517
+:10694000EB4AA0CB5AC53A17AECCBDF30B83AF428E
+:10695000BEDB952AA3DBDAB0F965A81FA7FDF5F029
+:10696000BE4B32AF02BED82A995F51912EDE738999
+:1069700063F159E9146D25D0B5D39631CED8A96A03
+:106980002B20AFD2BE9BE5EF379FD06EDA0B71871D
+:10699000F532BBBF65C94B6CDD48D24EF0DF4BD73B
+:1069A000D2B580F8D50E819F22733F455ECBFC2285
+:1069B00079B1CF2FAA77D94D940EF70B832B20CE28
+:1069C000BD41FDCC5289FA05F787077F0EE5FBD460
+:1069D000A54BE1FCE1FDA5832B203EF9847A0596C9
+:1069E0001F1486B17D41BD8E95C3C3D87E50BD8135
+:1069F000954B87B17D57682DC633F3F7307EC81F9E
+:106A00000A57C2FED1E4F5D604F77DD4930B3F5F5D
+:106A1000087A7CF27AE30710B274DE67381F4FAE53
+:106A20001DC4FAC87AEBAF21257572DD005954F701
+:106A300029F45B45FB057F14FA05FB42B73F9D7EB9
+:106A40000759BFF54EBF2FA6C54FA5DFA3ACDF3951
+:106A50004EBF2F189F4EBF7B59BFE739FDEECF07C2
+:106A60003E957E7B59BF539D7E7366D17E53EDDE8E
+:106A70007E7F09DFD375942A54B442DC22556BCC57
+:106A80008350578AD21DE2909FE0FB67617DA4AAE4
+:106A9000E8F7F4558AD2F7137E1F8842FD20FF9E47
+:106AA000D2F1137EDFAA42FD51FE3DA5D727FCBEE1
+:106AB0003102F57BF9F7942E1FE77B9837BEEFE59F
+:106AC000DF51BCC377951AD32B8736C8956E3BD45C
+:106AD000C91378D0775FA4F394A34CAE8F8E5B116B
+:106AE000983E13C6D5026B705F6D3BD6A7766502E4
+:106AF0004B81BE1FB27EF21B0685792AF0C9EF05D5
+:106B000068FF0755E4F6421EDB9F7B37B593A9FE6D
+:106B1000D1F376C0C47909FC3BA112CEFD9CB3D65B
+:106B200098B8C135AF730ACF08D3A3F07E40807107
+:106B3000CF510D02E3C1FBA9D1D17EA17E35D46B2B
+:106B4000A66F3D73B8299C6B503F75B2F38D23F04F
+:106B50006A018017E83E3DEA9A17856F4D11F8E407
+:106B6000A4173EB9701381EF640A17EB9FC103EFBE
+:106B7000013E99C2E38EA33BCFC34322FAB91D5510
+:106B80002CDED431F4353CFFDFD12BE810EF6D9FC4
+:106B9000B8CE396F85E5B6E89D76733D9C2713091D
+:106BA000E8F1F640861C027DF18048C00EDDD37D01
+:106BB00035BB0FDB77DFC797381D9D670FDF3718B1
+:106BC0006B9FE0CBD1526C17B9E06E7DBCFD8405A4
+:106BD00051EF7E42E4FC16DD6DAF7D392A78EA7B09
+:106BE000CEFF86EEC6C397A3CC0EF8429478F60B80
+:106BF0004A2E1CA31F5E7FEFCC3BF5BFF0F4C3CE43
+:106C00002538FB09F75EF88DE2DFF3FD84CBFB1E30
+:106C1000E984FD9B2F47993DD673DE9DBAE52A97FF
+:106C2000CCBA1BCB9D15ECBD7FDE67DC3356A5EFE0
+:106C3000F2F8FBBEFDB407E0FF55A0BFF867D1A294
+:106C4000FB6A7C3F1992482AC05F54311EF2813A98
+:106C50007D37C451814F603FF2F12A7D0F949788B0
+:106C600077635CF27B5AF59C90EB1EE44DDC8FDC85
+:106C7000057EE4343837A573BF92EDB33D3EF47A18
+:106C800004FBAD923088BA13EC4F5ADFBCB0757B71
+:106C90000DE523E37166472E117B274EA3ED9E3849
+:106CA000C8E2B81DD9DA5DF07D2EABE3735FD6D8AC
+:106CB00005FD2E810BE3E9770F2719FF2E11D7125F
+:106CC000907B07E0773FC0CFABF2C66942A419FDC5
+:106CD000B6D0B11B0B1157DC977EF705BC3F97C2AE
+:106CE00005FD546AF676189FF4B37B529688A72365
+:106CF000EEFC327FBF32C9101BEE953B9829A09F56
+:106D000047EDA045B4DF27948C06FB9DCD2B7F1665
+:106D10002866EF8ED94F7F06F1EBF47340E5FDDC7A
+:106D200054267EA27E9EF2C2D3A7B1DF3DF17F3F03
+:106D3000563F7444138E588678DCEBBB51764F0D6A
+:106D4000C51FF2477B9A1C1021FF403CFD05BC6724
+:106D5000FCDC049ED1F8B8FDFF04D61DC4E1C4F7E5
+:106D6000B6DF46E1FC5E81D19B9627DE0E747D9CEA
+:106D7000D175E47BDAFCAB73C6996FC13BDFEF25BD
+:106D80003FE97C5BD01F0C1DFBDC51B81FEFE12AF3
+:106D9000F63DE1F16C99AF27F9716EDF8EDC63E1AE
+:106DA000EBE713DE63F18F516F9C9BF235DE63F1ED
+:106DB000C18B22E6053BFAD3DF8F13DFEEC9B2FDAC
+:106DC000ED8D7CDD3D45FD6D783EC9F7BF1FE5715A
+:106DD0009C87601DD2F2312E8F1EC91A84DD43D4E8
+:106DE00080EF170E6D08C139AAEF3ECFC63D870C64
+:106DF0005442991C9131AFE1FBC24025F827441958
+:106E0000A884F336BD3C7EE0C0D33BFBB94A902753
+:106E10008F07AD4AC8EFB037C4F47D741E877E3447
+:106E2000F13B90A731F0B48CFB2F0776C8E7403ECA
+:106E3000F7F70E318C9EE2F06C8032D07D36E38322
+:106E400043C7FFDEBC05D6A540F01EA1872F7A09F7
+:106E5000E34B472E7A4E1F2F8E7F8D6A9D0239A7F6
+:106E60001E647EBF6A68781EEFE3F7FF12E69DF7A7
+:106E7000450BBA36FE38C1D845678E73E87808FDF1
+:106E8000E73E3E8EFA143BA74BFBAF84FA234FBF7D
+:106E900084E794FA2ACEDA7FE978FD3F319BAD8F03
+:106EA0000397365F7B0B9D57EF33324AE323CFBC0A
+:106EB000742DACC73E8A7FB083FBCED3FE0CE6A90F
+:106EC000CE8960FE7C9171A6C45CFA64749C49E72B
+:106ED0006C84EF816E4829EB5AB8C745AD9731AE47
+:106EE0004FE960C2B80EFEFAA60D5D0BFB166A6B89
+:106EF0004C87F8D18167DEAA2CB61F4DC7AB8B1526
+:106F0000A18F1F6F0F43FFC037B47FD8173E72E8C1
+:106F1000A54AA0CB1333CF8AB78662FD7F3F385C8A
+:106F200009EBF9FB4FC84DECFE87AE8970CE563E9B
+:106F300062EE65F1230BE56E506BAC073FF64DAE8C
+:106F4000D7672B6913F40A65792307F743267DFB7E
+:106F5000835213EA95925A9F5C3A768D09BF4FE2AD
+:106F6000E819FF77331562029EA653FD657BC6675D
+:106F70007EB452E56D3F5D49DB701EF482B3C07193
+:106F8000D1E019701422E3C071018763D61870CC68
+:106F90003DEAEDAF524B17F07707697F4F6B67F60D
+:106FA00047A4531857918F10BC0FE2FCBDDEFAAF17
+:106FB000C5CA987D4AF1A3BAF470909A055F2D7303
+:106FC000ED0FFAFAADE9F5C2716F8CE98FDBDEB92E
+:106FD0001AF9667A9A0C407EE85878F17F4FC747D5
+:106FE0007C8E8517E2DBC72452339BD7E310033C2A
+:106FF00013AFD44AF17C3FD63C24F58FD3175B63A3
+:10700000DE7B434F901730AEB5A7FB39BB8DC73F32
+:10701000F17E0452B0611F40E6F97172CD73F67EC5
+:1070200090E7968A79418EFEA0FE04C6DB0E0F4DD6
+:107030002801B97400F248C6812719B5F681BC2031
+:107040005A72977B5FC9B91712A6087256E6F75CA9
+:10705000CB35470B0017E1F94972B250C0DF1BE294
+:10706000BF8743FBFB1EAED7AE9EF7D97A1DE9471B
+:10707000F1F6F30F64A3B71F7263BDA79F1FA2BCF5
+:10708000F4F57304FC1CB467995C115BE45D987FB4
+:10709000463B827B496E0B593F8EB9E2B5A2C5CE05
+:1070A000CF39F97F7D90FF27609EDFCAA9C0F74ED8
+:1070B0009E5F0BBBEF634275669681713196E7E781
+:1070C000E4F7F9CF093B4FC77EF7E7F939F97D4778
+:1070D00086E616E0F72B3E2888780EC8B193BBE011
+:1070E000D3F908EF8BE3C1EBE42BFAF312FD703A0E
+:1070F000DFFBEF01F33FC7829348FC3E168ECF16AD
+:1071000032F4D2ED305E15B39B910928926F7BE289
+:1071100073284F425A35CA13C7BE69E3F60DF527E7
+:10712000308FB703EE264EC1BD2DA6C76E13ABBC84
+:10713000790DA2E65D3F22DCCC0BF762274D8FFD77
+:10714000B744BC0ECFD3746A12F61B82DF452AA265
+:1071500037FCFD11B218ED4089DB819D8A89F6B7B5
+:10716000230F46EEFB4EF0DF0374EEF7F5F5E35F19
+:10717000B791F8F876DE58F8EFE4F65D1BDF9FD3A1
+:10718000A9BD0BF039EBB79DDB7B7215DBEF16F970
+:10719000D3F9FE8D18F3BB9DA704F5301F7DCE59A2
+:1071A000EE47657E5DA5CAF2A288FE334FFEEC1B5A
+:1071B00031B1E8F9E82D253119E4C87D25313CDFEE
+:1071C000F0DA8610E69D1FF7C5790E517313F86843
+:1071D000A87B069E1F3FDC1D8AC1779D774F8DB926
+:1071E000EDBBA1AEF1E5D12F78DEC6FC38DB1F5A2E
+:1071F00008BFB34C9F96444507EDC7BA7BC776F7E7
+:107200007E9C7537DB5FB2F83968EBEE6BF6DA29F6
+:10721000F73CDA3DFEB5FFFBD17311C393810E67D6
+:10722000BB1F952432F8BB3F5D9282F75BDE25DA07
+:1072300069D807707E0FFA642063E3EFB211D3447C
+:107240002C9EADBFE4A7DB9F737FABFFDED6AE2ADB
+:10725000DAAFC8D60DFC0992F79EB49464E1FDBE86
+:107260006D49764F1AA9356C94D72AD38F624E6038
+:107270007CC3EF490BE901EFBD9EBEFBD1C063C0EB
+:10728000FDA417D9BD5ACE7D69119E470FF12D1C63
+:10729000C7F73B5A21F2C502FBDD2CEAA7D2265DD7
+:1072A00094AF8B9E2FE5F783C21DA770EEC0FFFB46
+:1072B0009F67F2BF779CE455E9F1EF8FF4FFBE972B
+:1072C0002AE96FB9E232637F2791B75CE711FAE2EE
+:1072D00084F1D7E98FF03E482422DE17CCF4C9E1CF
+:1072E0002CBB67E48464E0EF8F9F70F62D4BC911CF
+:1072F000BCFF551074D8BF31B52BE2E007982F8A38
+:10730000898093A4978038DE32B477B7C483FC9C1D
+:10731000D7A008FD9ABFD516433C54FC16DB0F25B9
+:10732000315980BCB285BF35F0FED94BD5A620AC13
+:10733000E3BF7F7C2E8E7BB3BA5482F2AE38B39318
+:107340007FF5D881796024B73D112505D40F7919CF
+:10735000ECFF9B9F1271BDDDF2FD28CAF99B9FBC1B
+:10736000F5A1CB69BFC20FA3EC9CE593373ECCEEF1
+:10737000996D43786EFEC195FF0CFAA6ED5F45BC92
+:10738000ABA96D03931BB786D83D4DC351F9A13D01
+:10739000AEF5EAE0C3292FD6661F812B0F6FDE9F63
+:1073A0009A2DBAE4EACD12F973C82F31E973791135
+:1073B0003DF06C9CC9C7F7A2EC3E1261FFA1EB71D6
+:1073C0009E03D7E0BC05BA02DEA4F8F9219F2F6D19
+:1073D00087F3B11F15F290B7F4DEA3029BDFC0CC98
+:1073E000DDE1148CBF5B5E151D95A314FE3F87FD88
+:1073F000ECC5FB67B757D6C379DF540AF627167D6D
+:10740000FF09947BCEBDF4B7C13FE9FBDBF7BFBEFC
+:10741000F4DF800E49760FFD2DDFFFB0F3125ABE68
+:107420006591327CB901DF8B9EFB496FF9EB5FCA36
+:107430007F43E17D97DA77615A7FFBC1A0E7DCCD1E
+:10744000BB836FCA00DFBB14851AB52B2E3BE53D0D
+:107450009743C4D3D8FF0953C1BC18FFF770630F1B
+:10746000F0C9ED03DD78FFDAED4FFDEAFF80DCB80F
+:10747000DD77AFFDBBF08F8A33F5DFBB71AFDDBACF
+:10748000564CC70B40F7FD138AEAA1917B3AB95ECF
+:10749000B9E589130FC0EF0DBEF7E4BF3F00BFFB96
+:1074A000B7F63FFEEF03705F15F9715803FBE6F680
+:1074B000C7DE7CE01B14FE5F1D0C05806F6E7EEC4A
+:1074C0009D57BF49CBBF7B664619EC5B4B1A8B338C
+:1074D000FCFAC0EF27C2EFA5AEFFD19249C09FEBE7
+:1074E0009F5E34693CFDF26BCA5F79CA5FFF1F562D
+:1074F0005AAAC100800000001F8B08000000000095
+:10750000000BDD7D6B7854D5B9F0DA7B6E7B924948
+:1075100066274C864932849D9040B00177202AB678
+:10752000D14E225250D411B10D16ED10EE081A2C86
+:1075300047D3A3363B096008131935843B0E682CEA
+:107540008AD4E8A796D3D6AF03528A9EB64FF07876
+:10755000A8F6501B526B6D1FABA3F5D6F3E8E17B89
+:10756000DF77AD9DEC994CC05ECE9F2F3F58ACBDF0
+:10757000D65E97F7B6DEDBDA73F62CFC7D95C15F3D
+:107580009CB18B18D30E4B8C8D85EA8F45C942B9BF
+:10759000929FB1DBF0BF1A63EF3CFD8953AE61EC03
+:1075A0006389256DD5F0BCEF73A7EC63EC78882573
+:1075B0005921632F3EFBBBE3FF0AF53F473C4D2EAD
+:1075C0009DB1DB0F3B060714467F67E95FA3580EAA
+:1075D0006099286650DEF6EC0DD75D5683A543878B
+:1075E000E1D9ED2CB951F58C7CEFF6577FE764D0EB
+:1075F0004F955932F8950CED2CEC4D9442F9E4A6D8
+:10760000F76D53A1ECFBF3AF1996CC3E385029FA35
+:1076100041FB9FF13F9732D67CDAFDD36395C3EFF0
+:107620004F50737C6F7D09FE7309BBE4AC0DF6F718
+:10763000F8026F021B9F1DC3705F67059CCCF2931D
+:1076400016E5A7C71C8CAD79EE466FC433B2DD2CAE
+:10765000DF6D819DBA86EBA3C17985C4D795F48689
+:10766000A6ABD0FECE33D94600F6FBEEEBAEF85C0F
+:10767000687B77C35F4A580E636F3B92B7201C92BA
+:107680002FB8D4FDF07CD10BBF728660FE779F3B94
+:10769000E9D4A6D07672A58BA1CE86FE5E6150BFDE
+:1076A0004DE295DB1FCD49B872B1FCF3F1FB109EA2
+:1076B0004536E6453CC4AF9FADE5E2F20A68BFB788
+:1076C000C5018EB9581E992F4D1D09EF558008DC54
+:1076D00087159FD20CC4E39959CC333A1ECD7DABAC
+:1076E000B8EF4BA0DDF8BD93F946C72BECD4199E3B
+:1076F00082E345395EEF79BB04E9EBFB9257936A6D
+:10770000619F8EA4B308F6613C6D537BF591F866DA
+:10771000B685DE4555586BA3F5A6E3279D0E96A4C6
+:10772000D101BE8FF835E1321A1DC00A182BF8229C
+:10773000FBF9DBE0355FD568DC74B8B56E70859019
+:107740000EDEA876C55DF0E88C43DB7617CC9B7C1B
+:10775000C9C1F6C32BB74CFB8343CB19B9DEDF029B
+:107760003D6A167A8C34BFBF612CBC17B9A7B4DA56
+:10777000C686E973A8FD1E1BD32CF0796F1C93708D
+:107780007FB7EF75C40D80AFEDFFBA13BCEE8EBBB3
+:10779000A0BEEDFF9C7D0CEBEFED7531ACFFE1B9C8
+:1077A0001F10DFFE41624D2C8FB1E57BEFFAF847E9
+:1077B000D0BE6C37CC06F8BACDD547ED6C316BEA4C
+:1077C0000579B23C3B49EF2F7FAA98B5C3FB2F3E0A
+:1077D000F7AB5BEE86FABB3FC9D15DB0AFF7FEED0C
+:1077E000F65B24A8AFDC0EBB96B0FD07B751FB5388
+:1077F000D90CB605FDFE7039B3F0E3F2ED0E6DC0A5
+:10780000B2FE95CCAE0DC117E9C35A8725DDDAD794
+:10781000D58F747F2B3EE7EF496705EF201FDD8A88
+:10782000E504280F7B43EEA929FD68BCDB5DC93B5D
+:10783000750FE1B9489E41782E427CDF7A20751D94
+:107840004F08FEB9DD995CC6FBC78A385DF4D37B6F
+:107850003F50A594F6F4F7CDFECFA96569E3F0F7A4
+:107860006F73B1A6BE0C72E9288E5B80E37D3E2962
+:10787000753C433C4F9F873F7F3717FE03705EF395
+:107880007C0EE17DCDF3BFFAF8BFA0FE0EC206F07C
+:10789000F84E41FFC777031EDFD96363860AEDAE5A
+:1078A00044C92E94534FBBD87EE8F28E2351925F89
+:1078B00035BC8E353F769F417E1EAAF701F6949126
+:1078C000F3B6B734F4BC59C1D8FA96089536D6F455
+:1078D000F0800F9BEDAC174A3B6BFA1EAF8F55B192
+:1078E0006ED4433BCA03A7A2B6C3BAB66503326BD4
+:1078F00090CF73884FFEAAE6D1B88C355D8872654B
+:1079000043CBEC87DE44FE550CA6FA713C46E79C5F
+:107910009DD9DF4238FCB7C0ABB94EA723A2EAB06D
+:107920000FA7C4C2085F873DD2510AE33B02BE6A7B
+:107930005831DB18981742FA8C56A9C44F9F209EE5
+:10794000613E178C8F74C38E75339C5709DA3FB034
+:10795000F2B987C542CFA3DC8073740BC819566E89
+:107960006907147BAAA06EC18BD307EB4EC1934766
+:1079700025B925E8F847921EF818E1D0EA527BA114
+:107980005CC0620EC41FB355BEBF05F6B16DF1D920
+:10799000890355F8BCFBCA109E0357043FD8327EBA
+:1079A000789F0B7E7C5FBF948B65E1623C471778C4
+:1079B00026FE1E4B40B69205FD5F94585F27943318
+:1079C00095BFEC7A733AD41DAC01E1710CEB638680
+:1079D000C73986CF619E76C6663F0DE58F1CB10D17
+:1079E000880F63A954DD0BF8B8F0C7E11BAE8175B1
+:1079F000DDBCA2621AC2ABAA2F7CF514A82F5C31A1
+:107A0000619A0DF0302E8FD3EB31475FC105885F4F
+:107A10009817F7730B4B3A109E11A63A09AE426EB7
+:107A200035325DD4E10FFA7F73CD847867E9C8F70A
+:107A30001726E2375E035D6E3E16BF068FCD5B4EA6
+:107A4000247F8AEC13E953676533CB7887F5E3D954
+:107A50006CE47800DFED0399E0CB7C1F207C75A6F9
+:107A60005C61E0F3A505FB3BA5D1F58305DE86ABA4
+:107A7000D8D473B40FC19DAF271D2FB0023901F3C5
+:107A8000BEBEC411C779DAB22FDF8EFCF05ABB4BF1
+:107A9000B5C1FC7FC12EA057DCC4FA085EAFE7F683
+:107AA0008CC375D603034897921CB93981F060B92D
+:107AB0007A27F0CBCD6CC0014CC6BE052486E522EA
+:107AC000A651B9988508AE4B596223CADD8D6AE488
+:107AD000AA3CC0CB6DB6C8783FC23BD85F8274CD9C
+:107AE0007E9E595F1AD67F385F9BF576411F4C0901
+:107AF0005D7C7D0EF2DE85751E90B3DB051FBAEB53
+:107B000039FF0412CA19D44396C61ED89542F7917C
+:107B100099A121BE284330C9CC037C1C102833DF37
+:107B20004BEF67CE1F68BE82FD0EE877535EA8312B
+:107B30002FC3BAD2D7BF268FCBED467CCF42E78D7D
+:107B400011CDA941FFC6CFBC217CCF5DEFA07E8BBC
+:107B500040DC7079133A8E74DF18614D9DD508F6BC
+:107B60006D21DCA7B9CEF47D3576DF2745919E42A5
+:107B70008A5EA1FEFDFBFC6E9E9DE637D7CBFA8E9A
+:107B8000D729179FFF3D1672B02FD2CF0D8484FBEB
+:107B9000EC916301A48FC6E6769A470730D1B99E6F
+:107BA000EB8CF766A0FF41A73615ED869E89FED2C5
+:107BB00036E027E0DA08C26D304B9B6AB73ECF173C
+:107BC000CFF3B5A98AE5B939CE2689CB1D933F7A83
+:107BD00064B6E219ACDBF5C03CA4479FF6C62FE1C2
+:107BE000BD25720EEB847250C8A9CA772FB8E55F25
+:107BF000516E1B53353908E7839D11DEFEDC726040
+:107C0000379D072C34711ED0E31A159E43FF259D26
+:107C10005F9BC8A0BDB9E36B131B2DF399EBF8D1A3
+:107C20008385F5C897CD8CF71F545EDC8E72B1D179
+:107C3000FDEFDBADF2703087D3D527BFF99AFF0295
+:107C4000E24FF569E453B33D91C7E97D099E2FD01A
+:107C5000EF8F2DEA8E9970EEFDA89E7D6B1EF28946
+:107C60003D3491F6D13AA50CE5EF92CEFBEA51FFF7
+:107C70001D94B4A7DDC0BF83BD9B79BD5A9364A892
+:107C8000573EFAF497100F39AA2AC985D88F3520A4
+:107C90007C2A1F3D19CA9B3A921F15A8A37DC78253
+:107CA0004CEFD5D098E0F2A3E0EB0702A8479F1471
+:107CB000EB2B982A135EB602BCB1EC1478F8459E03
+:107CC0008DDACD7E2785FC5EE48D9C44FE0A85C25C
+:107CD0008B36F8F0FC637AA786E76C98CEC5AD4E7C
+:107CE0001051F07CCB64A7D626215EFB8F2E4679FF
+:107CF000FD9F590CF57AF7F8FEB646B48740BF6889
+:107D0000037EA8DB182892A09E55EBD4F15C7F2F50
+:107D1000AF94E659113FD9867AC844901E361DC7E4
+:107D20008BCD2A82719ED8C3743C4F0A8067FA09B2
+:107D30008E03B988CFC9CA0105E5D6BB95F55EAB00
+:107D4000DE38526EC9CC30E99E14E52C6628D67A0E
+:107D50007E5ABD28AD7F594A7BB1AF9FF4683BF492
+:107D60006907F806EC7D47104F81854C6D079971C6
+:107D7000A8ADAF8EE0B18AB1FD79288C13545714A9
+:107D8000A6B6021EC7316887FE9E66A61AF0FE23BD
+:107D900072DF6C94D3723E87836A4FCE413806D827
+:107DA000617A0FF838BFBDDABAFFA482FB9DACBC84
+:107DB0009D1B063ADF7278BA8AF5312E7D25F67F53
+:107DC00017F10043753B126D8DB88E175CAC4D47B3
+:107DD000FAEE27F8B230C74BB713F004F5CE396E80
+:107DE0006AF7390DDEBFD44EF54DC80740FF6EE48B
+:107DF00003E08729B5C7EB15E85F2D2B7DB8289FD9
+:107E00002BDE908D786D85F1A1AC5A6FB4A13EFF49
+:107E10004EAF9DA11EDB29C51A703CA3D449F4D8EE
+:107E200091932A974BF3397D95E6CB42CE7ED6903F
+:107E30000DFD57182EE2F7D081D6E3484700FAA689
+:107E40004E95E8B0341FFA395888E86E457C2D8B82
+:107E5000C0782F0E7CFB67E3701F1A233BC35D12B3
+:107E6000572E47F9FB431BC3790F8D8B11BC3B1B6E
+:107E700098DA568DF4F28A8CF5FB55A6A25D035074
+:107E800095116EB7417B27D6EDFD47510FBCAD7BF9
+:107E90001AC37375CAE97F233C9CFA3A181497A257
+:107EA0003F65606331C251F3D0BEDC654DBFBD1785
+:107EB000E1DE5BA6B7C263B465487EC6417E021EA2
+:107EC0000E32E3C0DD12CA8DBBBE85CFBD41ADCC45
+:107ED00006CF678BFDD705078EDBE0FD2CC3CB5C9F
+:107EE000581E3E42EB7501BD3058EF27B0265ACFE1
+:107EF000935971A40BD76129F155EC1775C6F13C64
+:107F000067337C746ECFAC64F47CCBA62CD297B76D
+:107F1000540F94A05DFAEEE74D8130B75348EE95CB
+:107F2000079D0919E4C78703D38B4E30848FA05770
+:107F30003753F7C37C5B6F3C4EF5FD8D4C453F914D
+:107F400089AF780BDBB39EE42B2B42F93CF4DC01C8
+:107F5000FC0F70BA31FFE2393E5847DC0D3DBECC14
+:107F6000D89EFC459B0C98B7F33958FF85509AFA78
+:107F700042655CB9DEF2FE2DF9528A3CEE748B7ECE
+:107F8000E57105E91B465470BE4F1C0067F437D5F8
+:107F900032BD0DE0DE097844FD7702B0A70D6054D4
+:107FA00077781F1BF050BBCCBC08C7B5A89C03FC5E
+:107FB000E22C0CE3B92A930CE5C6CCDAA600F6BB9A
+:107FC000AFEB4000EBB17C8DF0D0F97992E0545EDC
+:107FD0000BF081F36093B35FC673CE781EE429E0A3
+:107FE0006BCAC4271AD03E77351FDC8DFCD09E2F7C
+:107FF000EC117B3C80FBD9E414F254ACDF25CE9F1E
+:10800000B67CAE4F7C57D0F93D62BF40CFF7E4431A
+:1080100019AA02C15D437295F440BB724BA88DE171
+:10802000F82AF7D328F100C201FAB721FD87AA6226
+:108030002BF65BE5B0E80F700AA03CEC9C7C27D1E6
+:10804000D9841F4A1AD259DDE1B504B7AC5ACE1F04
+:10805000E7874F3C3060E1D3CEAE4F03D86F0BD2F1
+:1080600051D530FD94CFBFDF5502EBF8A892AF6336
+:10807000CAF3CD814806BD6BC5A73696986EA90B8D
+:10808000B8D40F9C2C2B41F971A8681AD9FF67F658
+:108090000524787E349FEB6947F219C10BF0508FAD
+:1080A000F4685CCB18FA1998472FBBDEE21FF9BEC3
+:1080B00080A7097FD03CCA6E9C626D77F071B24494
+:1080C0007BE528EFE7423BF249797A3B5F8FC9BFF6
+:1080D000594146702D9FFFEE463C6F3F02BE4579E9
+:1080E000551704BC207F3FABE8B81FEF107C93040A
+:1080F0005F130EAEDA01273E9F79781FD1E10A3572
+:10810000FE5A07CAAB5A27EB65086783E07ADFA1FE
+:10811000AC6988D7E681BAA38B705E90DC782E9A22
+:10812000F0A91F58CBE97872DF0588B71E89D35DA7
+:10813000D09E684578C98A9687E74DA3F0276C855D
+:108140003DF5937E15A2F37250D063C5F637AF5D4F
+:108150008AFC0F9A06EEE3DD5A99E4D707CF4A71FD
+:1081600006FBDC7A6FF8752FCAA34A7EAEFCB9E134
+:10817000D5DB705DAE849BFAB90E4871B744F281CD
+:10818000845FE7BD5CFE19FB24D21F5D465308CF18
+:108190000D6D7D643A9EE348B176BF9093C84FF36E
+:1081A0004F1DDF83FB8F7854179C2BA506CC9FE2D5
+:1081B000F749901D337861441E837E0E16BFE52873
+:1081C0008E1B1C7022BDC963B81EBBF1C6AFB7CDF4
+:1081D000C1F55F2693FCDB7AEFC01B137C282F418F
+:1081E000EFC079120B5EF762BDD6A9B92D7AE8BB54
+:1081F00087277833D1AD45EED162B7DC4BAA01FCBD
+:10820000FDEB4B094B7F97910C852CFAC747F97C06
+:108210003DAEF5F09CE831497C09E776C02A37B7D6
+:1082200008BD2B54A31D1E207E56AB918F1A37DF3D
+:10823000BC00F161F7A9D508AFB3024F8BBCA1B365
+:10824000282FDE6E61C9F5A057BED3A250F9A7163C
+:10825000954A93FE65A57F16E27FE56A5542B9B857
+:10826000C6CED6BBA631963726954FCC7E2B5684EC
+:108270001DA2DF7C573EF64BE517B3DFEA2618AFA9
+:108280009AFA1DE3FD841F599C3F2BE35272BDC532
+:108290002FB2A6CF9D5C6FC1E3AD07F252EAA6FEF6
+:1082A0000ABA441CFD736EDE84FE191AEF275323AD
+:1082B000E311DFAEDA7E6721C0412B1F9885EE9572
+:1082C0002B6D73BD289F5C8CEBFDE9F8DA0AF82270
+:1082D00078B42854C65B5486E7D6DB2D01AA3FD478
+:1082E000A251FD923142FF90C14E013CEC13F83097
+:1082F000C7992AF667F6430C3A6BD0EBC8E5346AA7
+:10830000C4C8B70ED44F802FEDEB3792FFD16E3833
+:10831000C93F06F2FA125CBF5D6D223D05FA33716A
+:108320009E915FBCC719F9CA18187F55B96260FFE2
+:108330005507DE77A2BFFA7E279743EF3A52D773ED
+:108340008558C71563383D1CC9D338FC033ED2F3AA
+:108350005D4183CF23EACC1E290967F0235BE03E11
+:1083600080F106DF48B85F8BEB5A133B330BE1EE2D
+:108370000B3319C7BDD2E621BEFEB09691BF78344B
+:108380007E31E16EE221DE12A1F2ED96150477AFA7
+:10839000D8EF432D4D54EF7186BF89F3796B93E786
+:1083A000DC7F44D0EF52517ED17D0EE913D0732C87
+:1083B000DA8D9AFE4827F98FE3DB1B89CF2E9EDEEC
+:1083C00009B5A631CE8C7106C06313E2D1E133F159
+:1083D00018263FE091BCF01DB86E85C59E6984F1FA
+:1083E0007C4A9CF4525FF981C412E4E70D8013D0FB
+:1083F000837DF31F4BA05DAC3E2831946FBE703C73
+:10840000618775ACEE9618CAF3ACB99159E80FAA1A
+:10841000BF30722F8E9755A94B38CF98B97D4E2B10
+:108420003E47B76FF83E075B34F2870EF951DBEC3D
+:10843000AC1DCA375B2A1F42FFEBB6ECEF92BFB50B
+:10844000D970A92E423AF7C72EB32B2AD2EF938EBA
+:108450004817EEF3AE87E61AE83BB045D75EF8382A
+:108460009EA605E12DF87CDF868D25B89E46AFF6E9
+:1084700031EA7BB082393F9F41E70BE97BCCF8F9C9
+:108480001C94778DD9BC3EB13BD469607DAC76A796
+:1084900004FD3F1C736A8E0FF6D1389EB72BA27D68
+:1084A000F698D0CE31C45F8EBCB714F413C3C8198C
+:1084B000F639BC5F3B7BCB629F393BD62602746C9E
+:1084C000477A711C25F64008E544368B1B85402A07
+:1084D000B9682F403F7B47D619E4CF8935912738BB
+:1084E0005F72BAD60C46F05EA68736FBE0F9661FCF
+:1084F00013F405808573CA2BF803F8E2692B5F78C3
+:108500006BD3F8C26074EE8CB6EE74B9F490904BF5
+:10851000663BC88317705DDA7CCE1F9A716E7E3819
+:108520002AE4C1BF9BF249F0C1DF0BC70EB16FB7A0
+:108530009087E9FD5F31CF0F2127830AB76B65452F
+:10854000CD473DC36F033D03E071E4A6276EFA2AD1
+:10855000C063CC81896528277CB6F8AF91FED941EC
+:10856000E734D46FCCF19EF8EB2345F3609C2C39B3
+:108570005E84FE7FF604B46B6827E885E82FA99A2D
+:10858000FBF12D1AC0A1AA9CC52BA0F4C9897AD4ED
+:10859000C7D933AEB25E15ED5B384F3D6897FA1719
+:1085A00063BF17C5FA9A596801DA910CEC481C3779
+:1085B000DD8EED16EBDF547127E9ABF7A5D9A5E603
+:1085C000382F9AE71BDB4D76A97DC82EAD0B35A65B
+:1085D000DAA52F225D385813934A87E57CE198F09D
+:1085E000C79CAE93242FFE51BCC078CC87EBB1273B
+:1085F000D93F03CF6FA7E983539C1C9FAC9EA9A4CE
+:1086000067EBDC4FF14823E0246F78BC6EA1771450
+:10861000FB4A53E425BAFA9DF9380EF7FB15A08BF7
+:10862000217FB8BDD8C7EDA0295943ED76D44B863C
+:10863000DBF9B9165498A1C07B0561254D5FF8C7D9
+:10864000F67B17BE88FF6F67A497823E7F21EAEF13
+:108650000F5DE3976DA5297C3815E1ACCD751A281F
+:108660002F4C3E34F90FE0E52C84F7DEBA66623514
+:108670009E1BCE58F5EB2EA86FBA4C2D457AFF8E77
+:108680008FD38D37B1A06D0ED9FB721CF5CD4DE3A4
+:108690001E54504F7FE8F3D8EC32787EDF4B36BD66
+:1086A0008D8DBE0F53EFBCEF5E53BE96BE6CD53BB7
+:1086B000BD06D72FCDFA4CB14FEF7AAE8F02020B29
+:1086C000894EECC04F96F3F12161278CD43BAF71FA
+:1086D000165AF4CE6B7D437AE7B5088F8AED1F2AD0
+:1086E000B8EF4DC24E78F3DEE4EC32D4A74FD81881
+:1086F000B707E6BC81FAB5AF1CF46B09CF39382F48
+:1087000061DE4DF7F2F9BA713F93082D8AFD62528E
+:10871000FDB9FE1F6E0A396AF09C8C4C90A1AEC563
+:108720005C0477D0F723288F0BC2A9F6806670BD52
+:10873000FFCD34FA1D0D8E9B04BD0EED7F72723B92
+:10874000E23D8E945402F5CB66EDC0FA2689DB3DFE
+:108750009BAEBF93FC02F739D2F5736D5A2A9C3455
+:108760008A737DDB67DAF3A16FFBB89E384CB7E400
+:108770003F5486F562AAAB69F57F8CAEFFD17333A7
+:10878000FDBC843F19E906F8600BEE473BED4A3922
+:108790008F4C3E708EE7F2DE1CFF31412F8FF98641
+:1087A000F465A6F9C99F2B90CD58D42F4800E31447
+:1087B000AC49463BB7F298C2508E4EC6C008ACEBEF
+:1087C0004B2C21A31E35850D50FD42DC1AD4ABC1C4
+:1087D000ECC6FA74962C71DA307E95D888F6E946A4
+:1087E00035F228AEF3E31DFD6F48F0FCB1ECDBBEC3
+:1087F00027C1F8DFF371FF8987E9A46FAB58C2BEC8
+:10880000162B1EDA0F8B3ADEB1C6691FB2870E72C5
+:10881000FC05D5B7B2ADF881312E263D5FFCC5050C
+:10882000DC81362C7167C740DE625036D883A8875A
+:1088300001BD951FE07A41FB6989E28EDDA8879131
+:108840007EC6B87D7C138B639EC49812FD8C86B85F
+:108850003CC5FD95C0B7A5488F634F67ABA4A7DAA9
+:108860009B2EB9C1C2BFEDC047090062FEEC10CB20
+:1088700064B7DA9CFA80817ADE6917C917D0EB4EAB
+:10888000E0BEA4DCE64903A457EA0CF1987FA1F608
+:10889000BE4C7ADC9AAB7E8E4EE649DAD358B729C5
+:1088A000CBAF9A0D04917F09237BF794EFF697D114
+:1088B0008FF7AA4F23BCDA40CF75208AE7C7689CA0
+:1088C0009012921C3E0C4F733F90F9FCCE9AD07FD1
+:1088D000A2DC7016AD28E47A73131374F5077CEEEE
+:1088E0001274E50A72BA32C73746192FFFEAB989FE
+:1088F000F5001750AB9B506F0E35182C93DE6FEAC6
+:10890000E9702E9FC279EC6A98DEB77938BCD2F54F
+:1089100028B37C5FC8ED43BED03B08AFF7160DDC33
+:1089200089F406F495C471562B91F12822EEBCAA65
+:10893000FF167CDE610FBD8FFD806E3EC84437435D
+:108940007CA778281EB778887EA639D1EFB5E433A6
+:108950002FF997173327D314F2EF88BC96D0F1176D
+:108960006AA87F18F962F1E939C77F03F078A3D8C4
+:10897000C630EFC8ECCF447F838566A17EB278AE67
+:108980008BF868B132F7F81EF427D629E44F61312D
+:10899000D7701E5059CAFB29F931B4BED291E333C6
+:1089A0006BDD96A9CEF92BFDF96225D7C89E9A6991
+:1089B0003C5833F0CD9221B9C0DF1F94FA2E403BD2
+:1089C000A1BC20765507ACFB607E7F9102F589053E
+:1089D000DD9DEB6B012FAD9C1EA17E9511C4BA7677
+:1089E0000BFAD596D8D93187458F9852C0E5F194C6
+:1089F00002CEFFD06E60FB64AC039E30A610843ABA
+:108A0000DA6841D033DE7C72DA2F2FD046979B8B09
+:108A100063675D5A26BF4588693E809B64EEE3B874
+:108A20006EB86CC3713127D03B960AFADD27207EE1
+:108A3000FBA8F4B07E2A73412FC45265AA84653E18
+:108A4000D3A9F4B130957ED6446580C5A82C627D4B
+:108A50005406593F95252C49A586196B963C8A32B8
+:108A60008CE042BD8285A83C54CAEDC1C1563B434F
+:108A7000BF31D88764071A6D2EB5DD477621B5372B
+:108A8000831D88799FAB0BCA687F636FB693BEF472
+:108A9000E1E971711BE18DE7DD8C9037CA84DDEB74
+:108AA0002DFEDDF6C7958678D5307ECCE7AB055E2A
+:108AB0005617083E6BD55F8BE0BA1E5774CC333A1D
+:108AC00098CFFD4DC3FD79BF55E2BDF2F997BF8147
+:108AD000EBF9C8C8D550FF180D5FA3FB9BAB4BF05B
+:108AE000BC1914FEE6C133752512EA115D3FB800CA
+:108AF000FDCEA04F382530F6DE7CE0576524AF125E
+:108B00004E867E4A13BF36661FB0239C35386F2BC6
+:108B1000C5795BFCC5CF5BBD20745701C0F5C4F7B8
+:108B2000B328FE744797447E14D0CF36621E48A304
+:108B3000B027D2CFA50F7DA1EFE27B267CCAE7E765
+:108B4000328C9F7EF464514A7E4AB4809FBF87CAAC
+:108B5000B4DBACFEE629CF2B84C7DF758DDD8F78C3
+:108B60003C1F3C7EF70087C787BEC89602B22B35F4
+:108B7000E2CF13DFBF602CFA9BCFB78E3DFFE475C9
+:108B8000203BA0FC34E5C5C1CBF5128CD32C89BAAF
+:108B9000785E43ECCA90155E4B62DB58733EF13D44
+:108BA00073E48F6CC7CC2494D3A6BEE41271720018
+:108BB0003FC5933F0C0EB25C2E970299E87D9BD087
+:108BC00027D70B3F6C7AFB86C6CE3FA23DE0D698F6
+:108BD0003609F6E9B61B931F833A0B3875B47F95B7
+:108BE000C48E2B72513ECF60D5D087B915EEC7FC2D
+:108BF000F2DB036C91E55CCAD506B8FF58E4430C80
+:108C0000F197B05F378E4BB55B4F1570BDABBF8032
+:108C1000FBB102ED7A13C2C9AEEAACD1D22F9BD51B
+:108C20009F40BC066CD5D4EEF08D68FF7901BE6F15
+:108C3000E37183B10B75B6D2636D9FD35FC0F59FAF
+:108C4000BF49CFBDCFD3A4A8A8576BAED9E48F0B33
+:108C5000D6A4F8B50E0ABA19E61F2E6701CE3AE57A
+:108C60000F0AFF243CA77858475E049544E60CE8B9
+:108C70000D0694EDA517073C967DB4E709BFDF67A5
+:108C8000D303F3ADFAD3E7D35F8BF886E3D2C77390
+:108C90004ED5631CFBC319DA3497C03BDA4BB97E5F
+:108CA00029653D1B5B545DF86FF44C78DFF85DD0AF
+:108CB0006F004E1B8A5685904F9C222FC5A90CB47D
+:108CC000E1F80CF08DF87725FE7A14EB4EC43FB333
+:108CD000E03B30C0EDB651F0DD71E4F1583DBEE748
+:108CE000299B8674E3C4B31DF6E1ACD4F667C35286
+:108CF000DD7E2E27ED817802F5497B4849A23E971B
+:108D0000C560BD29E7AFAA5BF1D2E130021827EEBA
+:108D1000F8DC96316F6A40E0C5010AF49B16FFFE4D
+:108D2000E4EAC8183FEA77CF1A069C34CCFEE3B0D9
+:108D300041EA8FE78BF92B0BBEDE70550E74BD5FD9
+:108D40006671CCA3F1B9FA67E740D9B3295BC7389C
+:108D5000DA91EE79A5948F39234B46397948EA5751
+:108D600026A0DE7CA54C7A7296A087FB670D523E4A
+:108D7000C49C809BC675C77E3007C7DDCC947ECC73
+:108D8000B3B97F75FE9C722863B5DC6B19AB920991
+:108D90006EC642395E01638CB9EEB342AB1E3D092B
+:108DA000081FE178FFA77F59B014E76B66345F7D39
+:108DB000B34EEBDD2329A790BFB7DE7B6A07EA5DE0
+:108DC000BB5F5F4E7AD3CA20CF9FD9BDCFD910F7F2
+:108DD0007038E13C7BD6847B3BA5E17A49E5BC5EFB
+:108DE000D4EBCB033CBF2B169AF7AB4A78AE553188
+:108DF00095C7C742369E4F3C54BAADF57478568835
+:108E00007CA3F4E7AE20A7DF1DCCA89B03F3757607
+:108E1000CF97114E15CDFD1497CC89CA215CE70E72
+:108E20007B7F02E7DF5113F219307F4E5558B6C3EE
+:108E3000F39BFC3C0E54112DA37865A3E89F3E8F55
+:108E4000D96F873D5CEFAEC171980E186615300E74
+:108E5000DAD1E77B7F9EDF2ED6C9482EEC710C4815
+:108E60001867D9F31D55A2F5D4C415CCDB5A25E8F3
+:108E70003BB6446609E2938884E33E32541F907007
+:108E8000BE87FFE56303F1F3F065FCBCD8B1F09950
+:108E900056B427B6ADE6F5871D1C0F0FFF8B93F276
+:108EA000A181C22594F37DF644E172789ED3CD284A
+:108EB0008FA3A28685508FF9971B4F2D585E83CFC5
+:108EC00063974AB89EB9A7D96498EF81B10AAD27D4
+:108ED000A7A69F21FF98FDD3F777AA98AF1BE8526A
+:108EE000423A847E98AB82F350FFDD8E44A1DF02CC
+:108EF0009717C672FA33E9287DBCAFF8B91FAD7871
+:108F000075BF8847F4913CC4A465F2EB7F9BE7ED05
+:108F1000C11E0DF49746D73A0F20FD6D167E9F6D4A
+:108F2000F80AD2B5EEDC87790DF7055F0961FEC955
+:108F3000604D19E5F10EE91363F9BAEFAB9167E300
+:108F40003A1E76241720DC2A9A67D95BA149EED60F
+:108F5000DBDEF4603F8EFFBD5DE122C4476F1E2B58
+:108F60004478C4D61E2F447CECAE3E4EFE94688EF0
+:108F700087F442DBF43B67635CD636BE11316A99F5
+:108F80008FF34FB71C2F423BE0A99EEB36AF0FA2E9
+:108F9000139191DEFFC9AE6F6C463BB4E016C0374B
+:108FA0009D8B861BE73BBA70DE741DC68B879C1AAF
+:108FB0009EE53149CA9A88FBDB6453916F076BA623
+:108FC00065613F7F54362681BEB02D62FA8DFAE985
+:108FD000FD87A28D472AE0FD8742810F48429434E5
+:108FE0003E85722DFFE657664F8271F2E7E413DD8E
+:108FF000F81B98D428F81AF54254D5F039C05D42D0
+:109000007AC30477F29B32D68AF63B746946BF690D
+:109010006F4E44429B03B4F42603C6DFEC881C4128
+:1090200079D75BA724311F6E77EDC0EBB6321A8774
+:10903000FC2930B0847EEBBD1FDD4FF6E1FD9FDAE9
+:10904000E87D23A434F5920463752B11AFBFF7902C
+:10905000BDA70EBCDF82F123B5C162670971837EB3
+:109060000B337E817E68BADFC2D87F601EABDAFC2C
+:1090700031D181B2884DB0811C55677E1C42F9AA5E
+:10908000CA91FF7059E48CF755165F3615D797349F
+:10909000B09D5DA1DC89FE77E0B71D28AFF7B676FD
+:1090A000B9511FF7097D81D99306F24BF48549B474
+:1090B000FE0299FB7BA19DEEBDB0E9CEFD489FF875
+:1090C0001CF319BDFA5B0BD16F020A37E95BD5D8E7
+:1090D000CF37DC6F681DFAA9BBB19FF7F41F3FA71C
+:1090E00032E44CB9DF7273A15BF86564E267F57432
+:1090F00036E5A9A8A7D7CC25F83CABDF4CE569F746
+:1091000019CABFB6BE0FF07F3F187E07F1FEF0BD53
+:109110004E8A07F94C7FF115DC5F8C7F7A0A3C059B
+:109120001D605B196673F3FEFE191E8A0FDFFF5C7C
+:1091300092E01992C05003FA7DFA58632BEAF93194
+:10914000AD9CFC17A01E850E407BEE1595143F3E8E
+:1091500024455A09CF8B3C11C4B3BF36757F2568AF
+:10916000F7C19A2E0E169AFE27F2D3F9B205DD004A
+:10917000CE12B0BE658CAF07EBB25FD8F5F0DE154E
+:10918000C152F19EEA46FA5BD231219FCE25B59FAE
+:10919000F41D134F40D2CAF66954CE9E026520C01A
+:1091A000CF11CDC30C6F3EC5A7E8FE4CAE8D51DE8E
+:1091B0001CBB81789ED6437947AB35AD334F000851
+:1091C000D6B35CE2F3FF612C1FE78160D3C617E1E1
+:1091D000BD1E18EA1975B89FD75C37D0CF0C1C8715
+:1091E000A9DA4E6CDFEE22BA0631609C95D11E776B
+:1091F000A5C065F7CC0F12985FDC18F130941BDA2C
+:109200006E571A1F244398E7E879274743387B3382
+:10921000F823ECFEE1F91F0826E9FE5E97C4B407C7
+:10922000617E6FCDF1D978EEDF6D53FA31DF18F33F
+:1092300074B4147B22D5EF31AE39950F1D6A2A1E06
+:109240005566A9C3FC4F8B7C6BE30E2EB7A307ECCE
+:1092500042BE313ADF88334CF890BD9864184FDB3A
+:109260002D19E19DB09F8BE4F88357215F4D93C981
+:10927000BEF0366D5C8BF4EDED7EFE2E2C4DB96F9D
+:10928000F2515790EB49BF18CBED6B4FEDFFB8ACE7
+:10929000EBF5E58617FC3BE2B58DE723B53BD8AF90
+:1092A000919FDB9FF3303C179FC88B17DD01E3CD07
+:1092B0000EF2F3C11C9F55CE17FA39CFA7BC204F31
+:1092C00093793E65F8F563680F4D0C4A182F19F332
+:1092D000E22B32C6BF373FAB56D37EC4FDBE4ED65F
+:1092E0007702CF5FA3465671DEAE9A7974DEF475CD
+:1092F000B37CB417BBECE1A3B88EBEA826A35ED0A6
+:109300002CE8A93EAAAF453D6DF0329E53545FABA9
+:10931000ED45FDBAEB7517D9766E57FF76D4D3DCE1
+:10932000FFE5C63B2499F4D1347D2B218BD295499E
+:10933000DFCA9E2C4B785F607CA8CFC0F84731E82D
+:10934000D95F033CE4860642882F6D06B0CE2570B7
+:10935000BEAFEE37F0DCD36A781DDEE1E53DBCBC84
+:10936000E0E6FDF92C83BE30740E54FA2484E78CB9
+:109370009B07499F7D986D7F9D65F07B80E64EF051
+:10938000EB6A09F1FB50955CFFDEBBD0D48B1294E5
+:10939000D7D755F38A722D3475AE9335EB3D19CF7F
+:1093A0009BC94D188FBA7486AC21D3DFBFAE6D4C0C
+:1093B000A46A781C668F6999ECE0A1FC8A666D56F8
+:1093C000A67D04039C3ECCFD148BFC7AB37D27EA7A
+:1093D0004FF07E5980DB1725AB073A701DC12A4E2E
+:1093E0008BC1AA18FB0EEA5D06A33C3428495FDA5C
+:1093F00073EF9D73905F1EBEB9D189CF1B6BF97956
+:10940000E1AD5AF6183A6BCA84FE8E79A314FF6A4E
+:109410005A71F6ECC5343FC9A19CD5E17AD24B43D1
+:10942000F3C6923EB6BAAF58D286D7D5E6CFA5F7E7
+:109430002B40BF2AF791BEA6225C2A42FB4F204850
+:10944000FC9532D3A0BECD9E24BD795B2D53912FC8
+:1094500072447B4EE533D938DEF0384DB4DE8A8570
+:10946000B28AEBAB087D90A844FD00DED3B49170C6
+:109470007B726C36C1A30D6412F919C5FA49544EBA
+:10948000407A13EB37C26331AFAEA2E3E962AB1EA1
+:1094900065E0BC05F45C526A86D7AF75C74FD0BC97
+:1094A000A3ADBFA64FBA15C66D15EB3E3696CFEFEE
+:1094B000A94DD72BCEED0F3E982FE4D93446F9CFE6
+:1094C00023DAED0903FD8F076167311D4D91547952
+:1094D0007CC1D039C5FDC414EAD6881F298EEECBD5
+:1094E000EDA77B7AAC9EE978EE789E3CCAAE46F951
+:1094F000C7D40FF03E74CE93B2E102B9E7A9F99F49
+:1095000014BFEDD5B89F8B50BE333AA77BA22CBEBB
+:109510005FC8FF7FEAF923E4BBC28C043F5FFEFF14
+:109520003E7F2E78FC9882F222FDDCB908C7C57C0C
+:109530004963D6B5F51E3A27A83E67DB5BA4C7236F
+:109540000DA29EA18ED5F8BD7A958550DF30F50C21
+:1095500077EC5784EF62B4AB488EF51D41BB70F3D6
+:1095600045918B3B2D7CD33B96FBBB7AC772FFFEAC
+:1095700066A93FE12C45FED1C4F91457C8D9C7FAF2
+:10958000295E7497AD9FE0C9009EA8677F52C6F31D
+:10959000CAA3D513ABF15C39C46D27664C19D2FB55
+:1095A00062DBFCA4CF131D062E6D9B836EE0CF8A79
+:1095B00003347EF6F465EE72785E6A8F2B99E4A42C
+:1095C000BF2141F1277FB34D7BD3E297EEA99CE702
+:1095D000CD2437CD3200EA5402F0380F4AC453B6D6
+:1095E0009E45F5213EAC89B4D2BD139DEEF0304FBF
+:1095F000EC0843BD8E35F0FB3F8C45A4F9B09EFCD2
+:10960000F1912ABFC58FE56F76D23AAAFC9C1F0E56
+:10961000D54516A09F563F623710AFD1CAFC7D7862
+:10962000DE1EBDF154E00CAC7B829FCBE77DB9E63A
+:10963000FD131E6FF765F76FF7E07CFFE56204A787
+:10964000195C0E77D64CA47867D735DCDE1B1F700B
+:1096500027D75BEE51B509BF078E9476DEDAC4BD1D
+:109660006B39D3B9EB9592FD57E07C5B65B13F8ECA
+:10967000277F48DD87FBD78FBCDA8079B33DA122F5
+:1096800009FD28F704E4D4BC8FAF727964E27B70E3
+:10969000D324C2B7BF211942FD2180714575184FEF
+:1096A0006AE203A3199F4FB037515EB25DA3FB3648
+:1096B0003D1D37D0FEFD8AE6542DE75963AC742377
+:1096C000A6EA99F037F1779DC01FDD91C6F11AD84F
+:1096D000A3B85EC0CB3D01CCD708A5E2D5C44F9757
+:1096E00023317B32CA816A99E13A019E63F010D836
+:1096F00018A89AEB00FB2D3A53A6BC90DE4064AE4E
+:1097000051CE307A14CE14D7DC970E870B45FE8BE2
+:109710008043D7459CEE41B30A21FCFC220E915DAB
+:10972000B34CAAF2A17DE8A1FDFB1BD47ABA8FD677
+:109730002C533CC88413530C89E0D27C6E7A665655
+:1097400078D8707CD8B7452EF915EE47C9899D2485
+:109750007F44063ADE17B868241D031C6667F2933F
+:109760002484DD7297AD4FF03BEC9BF83D992823A4
+:10977000F9AA25F1BEFB27BF71115CBAA6A871F446
+:1097800031FB13C716A05DCB8C2CDD0BF2367BEEC4
+:109790006A09FD150CF43CCCE72CB5F7913C8F6AB7
+:1097A0007682534E43525DCE2CF00818647FFA95B2
+:1097B000889BECE9576DA82931352649F60CFB1A30
+:1097C000A26F019FEB05BDC07E1381820C7012FB5E
+:1097D00046BBDC0942F9815AE1CFAB3C8A3A26F319
+:1097E000DC2367F443790A5D4407517CEF4228D1BA
+:1097F000DFE641FFA94C7E4DAF143889F88D1BDCA4
+:109800003FBAA54A2539F0B6D0CFEEB271FCB3BB52
+:10981000E414FA31E566BA9C64357D146B0D443C62
+:1098200064DF8E2A07D79D9B6EBCE791837E25C19E
+:1098300030AE700EF9F7762083FC33F5D2C19FB2BB
+:1098400005682F68C66E37E6030D6EFA465B16EEA6
+:10985000BFF561B29327F8B99E6AAE7B080E8B4DB7
+:109860003824436E949BA5E54D9C9E96BBD1FF1476
+:10987000FDCF318CFCB93392146B0E841482835764
+:10988000DF48DF4331F519737FB78AFD79E276034C
+:10989000BFF3C2740BDECBBED03E1D8519F8E38149
+:1098A00099CFCC417AF632A51FF96A1B4BBE7E0CCC
+:1098B000FD13AB1F64DFF1913F9CF46BF28B7F19BA
+:1098C000FDDFFECDAD76D4E35489F48255FCDE8D08
+:1098D0002F3FB412F54F73FC9F09FDFE7CF1C0F1E0
+:1098E00085663C30B212CF192FC603C70CC703A33D
+:1098F000D57E8A077A551E2F397AE66781EF223F97
+:109900008A7860D7995F05301E18BDE8798A07DE2E
+:1099100027F7BD8CF76F8D67EC64EF9EF87E16F924
+:1099200095EE1897B5CF9A977E4D21977B01BCAFE6
+:1099300005F3ED6831D8EF2AA0AE66BE37707D2101
+:1099400097170765710F88251A306E176D9D2A7558
+:10995000927E19A3FB95202F4BF17C3B28EE51EC16
+:1099600058F632C3FBB55DD54C562F1C39EEC1FC01
+:109970004400F165C8B9E4D733FBA7F783F7EDF8E6
+:109980007EB49A6559C7E9AA5EB6206489276C0C33
+:1099900006E9BCC3B828DE23F74A9CDFAE2914F8D9
+:1099A000B89CDB4D9D8532DD1764E1F70DBC7FEB84
+:1099B000BA42A1EF04B0DAD47BE05E8C9782DEE598
+:1099C000C578E9B491ED0FE79C3E51AA21BE351A46
+:1099D000DF36FE9E0E3CCE5C2DCB664FD0ACF0E267
+:1099E000EB8B5E34713FC2678723B688D1F9C5EF30
+:1099F0007D9BF0EA5A9A68403D6EA01DCC96CB61E3
+:109A0000BA422D858EA24BFBA9DD904BA8FDF9CB68
+:109A1000816E383EB6A39C5259E5B44E923BCE9926
+:109A2000F8FD9B58A946F4B35CE0CFCCBF58E48D59
+:109A30002C2FB4F0BD1AE279413E5778D106C4E725
+:109A4000361EFF4BC7C3ABC57C1C9F57F833814FF5
+:109A5000ADF993663B00B614F9496D46DF056352D4
+:109A6000333BF2828F447118FD0177FD36E7C86FF2
+:109A700050CF28B431D42B54DD08E3BDC2F3F92113
+:109A800093E3C2F7E2BA4D3F24FE75A4FA1D9B98FA
+:109A900045CEC6D2FC8C7EE5B3D0011FE5FFD0B920
+:109AA0008DF201E54F61C413E9CCE057AC71B19D73
+:109AB000281FFC36A6637E48DBF359214EE7EA7E79
+:109AC000F49F1C697592DEB2678687F2DBF7281C6B
+:109AD000CF8F6C97E2E84F598A291213505FE1CF7C
+:109AE000BB2E53E3EB4B87EB39EBD438E27FC83F17
+:109AF000CCB8BD5328FCA64C55AFAE82F1739797F6
+:109B00004D43381E12F1CEBA9A7E05E3A88FD41CBD
+:109B1000A5BCD9AB8BDD665E3ED92324FA6436E45E
+:109B2000E7A4ADDA2CFE5090AAC877E3D0CF09F3B2
+:109B300047438CE4D360B77F3FC62F9E14F28174F5
+:109B4000AA8BF15EB6580F0B17852DFE502FFA43E6
+:109B5000F3A99C3D05CA5F88788E17ED14E41BF4C9
+:109B600087E6A23F34C9EFFD0A7FA8CA447DB5A6A7
+:109B7000BD78294D43FED49704FDA8C2CE51677825
+:109B8000E8FDA8B04BFD68970A7F33F94FCD7DDA29
+:109B9000F9F79B26845546DFA130381E4DBB7479FA
+:109BA000878DDAD96AA6D517023CD6A5DA8187F265
+:109BB0009B8EA33FA0A7D1C3F6EB23FDE751FD8EFB
+:109BC000591857C8013B15FDD3CBD3ECC4E7C4BE2D
+:109BD000A302FF81758CF01F08868B887E60811838
+:109BE000B765F6C40984F3B81ABFD629F45EF962E2
+:109BF0005C16876FAF949885F112639187F1784670
+:109C00006216EA532B857DBC8235D17DBFBEE27CD6
+:109C1000C167890E8A9BEA32233C2ABCEE5D077A33
+:109C20007129C733FA03D46EDEEE0DF66F42B8FB2E
+:109C3000238C71FB3EDC497A6B87447612256CA23B
+:109C40005ED6AC929F3E10E4EBF51B4E6DBFA9A70C
+:109C5000FBF1DEA1A0077BCC897A5B4E2448F1960C
+:109C600046134F2181277BF8659CBFA416F62B0D68
+:109C7000BFBF42E02D1A3436E27E7B40F9D9AFF205
+:109C8000F156E07ADF1947FB35E1338467512F1134
+:109C9000F347034DB3285E04EFA37EB1273820A11C
+:109CA000FFF411801FC68F7A8306DD938FFF39473B
+:109CB0006BD387E75F25F8C1AC9BFCB13CFA96B447
+:109CC00002DEBFFBBD1C0DEDACA8965050EF667DCB
+:109CD000DCCF014B48203DAD3C90EA475F1E4FADC5
+:109CE00007D2FC0C51FD1592AFCF0BFE3DF246168C
+:109CF000C179B036F638CA8D6850CB4538C7B63E04
+:109D0000E8C673E9F162AE57F5EA7216D8FC2CAEDC
+:109D1000CB57A13C8D3673B9561204BCA6E0318DE9
+:109D20001F188F27E5D4B27D1C8F4DCE4A6EBF68B9
+:109D3000CFE8C37498B34ED0A1CAE16ACA8DE5B525
+:109D4000AC1EE11A58EC21E044D52627CAC928D018
+:109D500021C2991C6E261E27E0FEE47A8A030BFEC0
+:109D6000785AE6E31B773A35D4034DB9D9BBD57899
+:109D70001CF59023AF5C908BF26B501970A3DEB68C
+:109D80005797DDA89FF73AC2728367243CEBBA93DA
+:109D90000AE6E7C66AA765A1BC7B449FC6E111E15C
+:109DA000F0080439DDFA6B52E583C56F457EC51CAA
+:109DB000E1B73A942FF4AD9AF04D68A707DAED12A7
+:109DC000C3315832847EF695487FD04F4B3B0FB657
+:109DD00016737D6D88CF613EE4B3213E59077C62E6
+:109DE000E1A39C785E7C343EC7F55BF91CE75D8E91
+:109DF0007CAE8EE4EBD8D0BCE2792495BFBD1D3695
+:109E0000E2DF92A0C1F9DB00BA203868F7D33ABA92
+:109E1000590A7F7BA39CBF355C37F1ABE06FBBF683
+:109E20004BACE73473BAA8081A2F51BBB9AF91FCF9
+:109E30007F9CEC00C1FF19F8FB387DDFC6E46F168C
+:109E4000732EC1F9853C63766323EEDB2BE0FD4581
+:109E5000F93D26F83D161CA078715CF0FB79F97B82
+:109E60001DF0B7EF9FCFDF8C71BFD9B8F52C8EFAFC
+:109E70005797CAE9A117EC0CC453AFCEEF4F3C5231
+:109E8000CBE212F27B94D7917E9864A1DFDD520A77
+:109E9000FD9AF402FC7A1CE9771CD2AFCE691EF75A
+:109EA00075EB10BFC3B901F32F8EF0B837D409AEEC
+:109EB000E3049C1FD107299EBF571D70233E1B0D35
+:109EC0004E3F8DC101B2E3FCB01E8E7F46F2DADB5D
+:109ED000CDF11F0FEA9DE40F8E087A32E9DA50E3E4
+:109EE00056B9B14AACF3D69A387DAFC3941BB77656
+:109EF0007F4C794B776FCED6E55ADC67B203CF0B38
+:109F00007FB74CDFF9DC3B83CBA9EDEBD83EC3B286
+:109F10006F55EC6B7BF7E04B24A7803E114E394127
+:109F2000FD65E2B30E97A05783DA359DAF5705F371
+:109F30007D89CF425F827E4C7A55BB1FA4F3158D7D
+:109F4000ED7A589F6AC436921F0BE881CD40787332
+:109F5000BCDA910E24D44B275E4BEB17FEE5554F30
+:109F6000A6FAB7F1CF6EEA9B32FABBDBE64C46B9F4
+:109F700004E7AF84387A3495AEA21D8B25CAD3820C
+:109F8000255FA48FF437EF0926085E8F48CAAB6DB2
+:109F9000304EDD6F571FC1F3682FECC70540393CC9
+:109FA00070B46312EAF53532CBC6F11B52F5E358B3
+:109FB0006DF2C5B3D0AE45385DA5FBBFBB0C46F610
+:109FC0006E10035C502EDD9E4AD76A5382F28B2AB4
+:109FD000D6310DF3FDD2FDE35D35F24B87A07D79DF
+:109FE000AB4CF95815EB0C8ABF357664EB482785E6
+:109FF00069FB3924E21D3D8F49144F386270BAEF76
+:10A000005AC2EF49AB1D2715F4074C6892293ED977
+:10A010001835C6601C6EEF12BB8E34DE5E5C3A747F
+:10A020005F06E9622996F0686FF351F21F2DEE7515
+:10A03000101CD2F5B1A5697104D33E49CFB75F9921
+:10A04000564F5F3FA08DF6874730F2F5A569FD0FAB
+:10A05000E527D814DC5FBD92DC9F215ED3FAE52CA6
+:10A060006EF7D53191CF0C5831BF3F06F8BA1BF7C8
+:10A07000877AE3C99703984F33781129D96CF0F3A5
+:10A08000D63AF4AB6DD9A02550AE0DD9BBB5CE23D1
+:10A09000E45FDB00860B3CEFFA2993B0AEF5DA43C0
+:10A0A000183F1861374B89C41A1F7D1FB0A997CB81
+:10A0B000055ACF383B53494FC6F827CA159FAA61A6
+:10A0C000FDFE4F5F4CE07E8D6E2F9D4BA0C7D6A14D
+:10A0D000FE7429CA5258B4E735A30EE5CCA4662F06
+:10A0E000D5D716DBCC38F7118A0B5CCA54D4EF03F2
+:10A0F000EC18D723C1ACE8B814FDE87C9E9E1C2662
+:10A10000EDB77C37C7834BCB1FB96EB3043BB61A90
+:10A11000F526328DF2A94CB073F6DF3819FD689E32
+:10A12000D31159CDC5520BA918EF3AAD5269C6E308
+:10A1300063D39861FD4EE7378AE594FB9A6A2473EE
+:10A140007C0CF77CD49F6A5F0DE11340B1EC17F3F0
+:10A1500073A74063CDC9F9FEA13C19BA9FF8DC355D
+:10A16000098B1FD6B4C3CCFAA3857C7C35E24C9313
+:10A170002FE78927A23C06B81FD499C8D74B6DF7A3
+:10A18000887B26E974897F99E287149FA4B8D47BE1
+:10A190009B31BFDABC573275F77B9B0D90DF284FA0
+:10A1A00031F66ADA834F0AFF0403BD04CF91DCCD98
+:10A1B0003615F58ADEC2D8F55512C19BEEC9E2B755
+:10A1C000BCD04FE6410E98760E7A1078BBA2988FDD
+:10A1D0009B8EBF11F47D726007F9AF25A6A33F6483
+:10A1E0006FF5C545A81F96E2FB684746FDF5785F09
+:10A1F000527D2D562F67783F9DDFD3E5C1F9E44AA4
+:10A20000BA3C7117733C6E2CE2F39BE78F551F919C
+:10A210002DF402C0BF05538255C3CEBFE367E68B62
+:10A2200008BD650B769930FC5E4CC0FD90A057537D
+:10A230000F1DD7CDF13FCED443A35C9F83763A5F09
+:10A24000A3DD70BE5AE4A0DA6DACC53C3135FAFC32
+:10A250005D784F20DDDEBD1F6900D6AF1769437EF4
+:10A26000009CDFD4F73561873E56ACA6ECD32BF6C5
+:10A270009565BE77DEFD837D8CFB07B240F9DAFB86
+:10A2800005F77F324D0F9FD0C1FD2D134C7DB69940
+:10A29000EBAB43FBEF9068FFA61DA676B4F2FD374B
+:10A2A000C3FE33E4CB8D2912FCA8F138EC0F0B056B
+:10A2B0003D8938ACE99FF0623B94CF083E403F2D8A
+:10A2C000FA414CFFC7F151E0D354289EAB091177F6
+:10A2D000E5FB60DFCC1C7F3A24E92FA3FD66ACE4EC
+:10A2E000794C45DF096755C1F38A6B56AF5C0AA507
+:10A2F0001CE4F15616EC6FC0F320D0B05B477F51E1
+:10A30000A9BD5FC9740FD0DFA0D13DE111F1869ADC
+:10A3100079E7BC2F5C84FEF84A74E3C80CF5A3C649
+:10A32000EEF438158FFBA5C7FB2C7EF83B33C55BDD
+:10A33000EF14F156F5D352161AC3D8B68565B4BEDC
+:10A34000A7449C5A5D2853FEB2FA6939B507226CBE
+:10A35000BD0FC6071D85E26D8BBCA9715C7B55D80E
+:10A360007068C3715C68A7794373F7B5A27E33F454
+:10A370007DB08670C8AD0DCF3F8487C5A9F1D0618F
+:10A380003CF0766329C7939F196EFC8EFD8E3B7A55
+:10A39000AA916C2B041E7A6E5CB668B1361C171D30
+:10A3A00009FFB89409FE7E25B2093F199423E262A1
+:10A3B000A3C5FBCCFEE971D4A225A9F800785FE91A
+:10A3C0002F1886B3198FBC72182ED41EAA6D959CB7
+:10A3D000BE54B880C63DD4EF502B8F83A7EFE3B7B0
+:10A3E000224FCE979B08A1DC31F34E729E7C25252F
+:10A3F000EFC4837927B9A3E79DF86CFA7FCCC57DBC
+:10A40000DE6DE7FB14E7AC355F73E81E26E0A83B82
+:10A410009847EF8D3BF9AA9B3E873AE4D7CC9CBF87
+:10A42000993596CB8BACB19AE03BEED7A47B5332F7
+:10A430007F0FED92AE4DFCFC3A981FFFF5E5786E6C
+:10A440003DE1D4284FC79EA4FB0EEE891EF267A7FC
+:10A45000C7731604C5BD3D11C71911BF11711D1376
+:10A460006EFFAC780EFD211F14E7939F675190EFAC
+:10A47000D38CE798796A0F07F7BF9660781EF3EFE1
+:10A480007A1BE3B81C718DFFF155F8BEED29399F99
+:10A49000EE1089EF20BABEB4EC04DE45DF7AEF633C
+:10A4A000648FF44A4A3FC9D1C42BDCAE8F7FFDA62E
+:10A4B00095384E87A45700480FEC3BAEA0BEEAD1BA
+:10A4C0004317A15D60EEB3516719EF35940714533C
+:10A4D000AF17790D6699705AEBE9EF158F12C7FF28
+:10A4E000A5B8CFF1B0A3EF7AE49787610FC8AF3971
+:10A4F000953CDEDB6767D918AF0FEAF32E4295C6AD
+:10A500007CEF4890E75B04BB9DD40F7494947CD09F
+:10A51000E78259048F9D229F737590DF9BED7584B0
+:10A520008B50CEB57EF94F644FED9140BFC7F23BE3
+:10A530001F2418D9FDFCFB949E6E79913377647EBD
+:10A540008FA94799F43744978ABAC9AA4775153233
+:10A55000D2A3EEB2F5D33CE97939669EC6905CAAE7
+:10A56000E6722B7051C48DE783FF9AE89C4950FE38
+:10A5700050C825CFE69FAD586AD97F5124D68A723C
+:10A58000D29443A576C36DC6E7D12E2B413904ED95
+:10A5900025B133AD64379B7248F82BCC7C8DD1CE7E
+:10A5A00007903F3F09629EDC92CC791CDE1A919F96
+:10A5B000B850267B75282FC91157F0DCBFBF86C75E
+:10A5C000EF43735B25ABDC06B945E3FA1BF8FD7579
+:10A5D000A03B3AD7370BFCF4258E52DE15E6AB6173
+:10A5E0001EEAB65A1E87CAA9DCAFA03F15FEEFC609
+:10A5F000FC46A386111FF4D9C372B585AE5AFD9CE3
+:10A600009F2B3A24A20B66EF0BD077BC591FDD3F7E
+:10A610006B13F76DCC3CC4A1736339CB18FF1FC219
+:10A62000CF4AF3DC88B9E7029E76F63C46E7C63BA4
+:10A63000C3E74629C93845A5EF3A060C399EE93BE0
+:10A64000EBFE86C468E7871B59DE23F0365A3C7C54
+:10A6500058FFE5F832CF0FC0570BC235B822735EF2
+:10A66000454B70E8DCA07EA1DA07EAD2CE0D03CF1D
+:10A670000DB39F3FF1A142791DF81330E86F492EC9
+:10A6800091AEC5F58414AA6F017B385C43F737920D
+:10A69000689FA6DFD3B8F070BA3DD44AE36E51424A
+:10A6A000BEEB119E0D3CDFE992D752FBCD2EFDA9EA
+:10A6B000EF06D403EBE469FCDE9878CFC30AE6D357
+:10A6C0007CFC9CF9CADBA9EF997019EAAFF27B57C1
+:10A6D0005FFDF43CFD7C3C5F247DFD5728E9FE22B4
+:10A6E000D13F102AB8B16678FD5F0BA4F66B58F421
+:10A6F000D3826F645A7F1050EF1B5EFFD595AE7307
+:10A70000AF4BE3EBBF6EC679FA95675EFF0DB347BB
+:10A71000597F657236FE5EC4371ACE33AE9DCFFFC9
+:10A72000CD15E7EEF7ADE6F4790C71FFAF5142BD00
+:10A7300000EC8024C589D952E9BA34FA213AF89B51
+:10A74000E9C7F0CDB3D04F3A1DCCAD7614CCCF488D
+:10A750003F026F02FEE7A50B413FE974F045E92790
+:10A760009D2E86E9C728F8BA857ED2E900CE51A28F
+:10A770001FB5A19CF87224FDF0F7CE4B17827ED254
+:10A78000E96024FD707A485F7F3A7DFCAFD185BADD
+:10A7900094E488952EE6FD5D749120B961C2351D63
+:10A7A000BFE1BA2B0B6ECC4817021F822ECE8B6FE7
+:10A7B0004117E9F8FDA2743112DF265D00DE2D7429
+:10A7C000918EDF48EBD23CFADDA7617AF862F8D5CA
+:10A7D00000BF9E2FCEEFE97EE9743CFFCDF8D59601
+:10A7E000129F5BF17BC3DF756E30E26B133EE9783D
+:10A7F0009A7FFD8682AF67C4AF80ABC0EF79F12648
+:10A80000F07B5EF93C0A7ED3F1368C5FC6F3D11B38
+:10A81000B89E978E37C0AF3B15BF7F1BDECEC78F6C
+:10A82000E9781D0D7F5B47F98ED047E3B87DF2BE16
+:10A83000D00FB6BA33F7FB6FD1EFD271A25FDA77E0
+:10A8400008874AD1EF1EEC07E561D1FF505BDF0AB4
+:10A85000B4C32EB2B5D3F712D3F7B15D92C5774F1B
+:10A860000DC99ABFE42BE176C49E1630D0260D3F69
+:10A870008FADEBAF43FF43A079A015CB9275F940A4
+:10A880008A23E1E4FF74020B4DB7CE17E7FE8B0578
+:10A89000FC3EB6FFD389D4BEA745A1F1717ED4B7E3
+:10A8A000478E9F35CAF885E7193F98DA6E9B4BDFD4
+:10A8B0006FC6CF5F64FAEEC0F69678CCFA9DCDF401
+:10A8C00032F0C1E245619197A4F8E91E3AFD1DBC42
+:10A8D0005C4FE27DCD9D4BF3ABF1FBD1EA788E87E7
+:10A8E000402EF71304B2B8DFCD9F9BB51FFD90ED4E
+:10A8F00039DB5B9741BDBD2EA053706FC9CC94EF7F
+:10A900008EDC27F3DF2130E699F7256347D04EB57B
+:10A91000C92C4971BCB4FEAF94F0F9DA457E5DA054
+:10A92000D946DF9DAFDCB744C2EF843C23DA95B84B
+:10A930009DFBDF9130619D531E718AFA822D2BCAD7
+:10A94000F1BB76067A8E59B464D675B333C44F46DC
+:10A95000C24B977E67815720EDDE9659464BFEB677
+:10A96000FCCAA325DC9E30F3057B96AEA2FCD2B8D0
+:10A970004DBD837D85E041F9953B57A6E757AEA2D3
+:10A98000FDEE5CC064D53B72DC83F9911DF8FDC01F
+:10A99000E1FC4ADE3FBD1FBC6FC7F77B16A4E6573C
+:10A9A0008EEC175910CAB0FEA858BF997749571DA9
+:10A9B00035A413A6239DF49CE4DF7374B1ADADE818
+:10A9C00047F928A4E89D19E880CD8E499877DBD314
+:10A9D0006A4FE2FDC89E9C1EA28B9DD73326E5657B
+:10A9E000E8FFD959BAFF45F157FA2E14D0B322D651
+:10A9F00085FE1114F6B018DB2A27D95FB69BF87DC7
+:10AA000039FC4B9A7E68B49795DB5A97E1F9A2CA54
+:10AA1000FAD7309F9F45FBD12FEE8F3853EF950823
+:10AA2000F9B6D311791D386EE8FB233D97A5CAA767
+:10AA30006D021ECF95D8CC7C488AAF381A8EBF865F
+:10AA4000E33ACCEFECF9EC29DF336A17F7A48D3B3E
+:10AA5000B89DD85391A07B2C0937CB7714C3BC1277
+:10AA60000B61BCC09094A17BD7F8FB6EC5822F7B95
+:10AA70008EF0DFABD8792F93F0F73C0EE687DA70D3
+:10AA80005F86CCC218CFDBF940BCD04DF69876BDBE
+:10AA900003932A4221CD67F98ED3CE0D4F16DA38B3
+:10AAA0009D55A3DFAABD997F676BE7E78CCE9D9D7F
+:10AAB0008B34CA57DC83DFDD82AD95AFE0BF779082
+:10AAC000FEDDA074FAE8C979AC10FD78ED92FE1AAB
+:10AAD000E6073DB8F7EAEB1A800FDB2F4BD870BDC5
+:10AAE000ED052CDE5A3A0C97F4F7D3E134044F0FFE
+:10AAF000C0337774786EC33D1658F37023C4573B48
+:10AB000025ED0E8C779A79B83B17F84B31EFCAE4F4
+:10AB1000AB9D4B393F01FF2CA07CDBB66C097F0F4E
+:10AB20000D9E2BC4274B8195CFC9278CE4CCED20FB
+:10AB300057F0F7D2CCFC5DA6F65D306FCAB03C157D
+:10AB4000DF94646F097A718DFFF19F10FE3B5638D8
+:10AB5000E97714D2DF33C72F5CE13C83FB4EE787F4
+:10AB600042F15DA7C200BFE737825FC6F3792E2BA3
+:10AB7000E17E12F3BB5587CA42F5BF8775F69CB2DA
+:10AB8000519CDEF45FF62CE0FECBA1F50A3A718D04
+:10AB9000DF4D7A4620CDAF1918F26B2E2FFC2EC256
+:10ABA0004BF835779EF95E21FA357B563E7F81540E
+:10ABB00065954F7D7FA2FCEF55C2CFAAC6E89C38B1
+:10ABC000585FA96792FBE7DBDF9B25663EFDB9F77F
+:10ABD00033E29CFB3BF771598996123736E1699E47
+:10ABE000AB1305FD99E76FA9335C301ECF85488410
+:10ABF000FC379A78DF9453CCAE57D2BD5CDB3D0C6A
+:10AC0000ED990F5FB5D1BD9B7439972EBF8C7AA398
+:10AC100095BE6B2EB3A687D49172D0CFEAB7CC463F
+:10AC2000F8564624FC5DBCF6523BC9DF74F9B6C940
+:10AC3000D1E4C2EFD3AE6F09EFC0EF383D0A7BC05D
+:10AC4000EFA4347B14CA975F2FF2968D9C2CD23FD1
+:10AC5000D3E1B8B88CC3FF89BCD802D41B0E490F0E
+:10AC6000A4C40D7A354E7F5B84BEC06A226EFEBDE1
+:10AC7000E6F5AFE0EFF36CAC95298FA723BEE404B3
+:10AC8000E677EC0AC8F409895D8146F72A9C779D2E
+:10AC9000AC56509DDFC3315446DF29DA18687B0576
+:10ACA000BFABBD6BC934E29B634B641DF7B943F581
+:10ACB000D0EF8DEC5A27FA0779FF59B6D37330DFFE
+:10ACC00062F76AE774FE5DABD0B5D5963CF2636B74
+:10ACD0006625F077371E99E1A2EFFE75455FE947DB
+:10ACE0003577E292FA04E6B14F0829614DC7EFB516
+:10ACF00026197E9F2D1000FA81FA2E493FAA703F37
+:10AD00002CF9158FECDB48719547AA18AD63F7C293
+:10AD10005002F3DEB7376433FCDEC9EDE3F9EFE44C
+:10AD2000ECDAB7FE25F4DB558E2BA7F90FECBBB898
+:10AD300008E963D7BE8DF4DD989C5A7BCAEFE71E05
+:10AD4000E97ABE10E92C5B4F7DBE6B41A210F3295E
+:10AD50005DCCF25CF02FE6851709FE3DB1F6943428
+:10AD600040C1F8D47EE356E832D90F510FFD5EF0B2
+:10AD70002A9017C85707E4908CE786F18644FB7A3F
+:10AD8000D461B8AC78BD722AC7ABF93DB2CA5239AA
+:10AD90008C7ED30DE27CB47B383F99F84F2FCB36B5
+:10ADA000CD3CE7EF8C142A37ECB07E477187B02F8B
+:10ADB000EC6ABFAC023C8B9F55ABF13B5FC5ABF976
+:10ADC000F788775F5982EEDC217ADC7DE4A542CCFE
+:10ADD0004FF53FE9D131DE777CED3209E3C477E40A
+:10ADE000F1DFFDB9CBA6B622BDB0C51ECA9331BFF7
+:10ADF0007F0DF222E5FBD779CD3EBD7C3AD96BF4CD
+:10AE00003B16AAE6D7CB416ED89B9D3AEA79B39E12
+:10AE1000AA1A3B708E7DC45A54BDDC817052A88C36
+:10AE20008978F7979E9AEB6DB4E8658F8E9752BE3E
+:10AE3000AFE66ACE8E59F7EF18C7E10B7F85D6DFF4
+:10AE40008B5A28E0199332DB4B663BAB0905EA606D
+:10AE5000FFBBD63A55F40FD5E53D5BB80AE317AB17
+:10AE60009D2AC263F79A539B16A23C396963C86F47
+:10AE7000BBD73E5FB8CCB2BE5D5266BBED4571BE7E
+:10AE80001C2834764A94D77AE006FC1D84036E634E
+:10AE9000277D3FC87882D72526F4F04337E0FD9D13
+:10AEA000032857803813E3AFBD01E32307F28C9BDF
+:10AEB00064157FB76DF743C7402E1EA8307E8DF90D
+:10AEC0004E759358622608BD03A5BCFFE449035B99
+:10AED000A8FF145E9F3AE9E91BF0771376E17E60E4
+:10AEE0007FF67D4E0212F0573EF2D1FABC470B318D
+:10AEF000CF786735485B584F5C0BF72B30BE5D8AC7
+:10AF000017A25DB2285E1D9EF9658447F936DCFF05
+:10AF10009E7E07D1C74E47FFA685082F80472BD4BA
+:10AF2000778DEB2FCC140F8DB604F42800AC53941E
+:10AF3000E6F31C3DA03F69E1D3ECCAD4FA2EA99FE9
+:10AF4000D65314D7C3F64BF13B5FFD3BB09EA5B97A
+:10AF5000793DA7BF10F7FFDFE3A5B0BD10BF23D930
+:10AF6000BF03E1FBC7F17FBD6E26EC7B97A3AF501B
+:10AF70003F07DDFDDDEB12E3FEBDEF8F36BF39EE9F
+:10AF8000FFD6FBFF0F9C21913D00800000000000D8
+:10AF90001F8B080000000000000BED7D0B7854D5DE
+:10AFA000B9F6DA7BEE6132B3139338930C30937BAE
+:10AFB000C2244C22A5811F7588FC16909E0E089A0B
+:10AFC000684F9FE122241A74D028D8A36527041063
+:10AFD0001B61C090E6DA0E097082800EFE8A97DA55
+:10AFE0007326882D5ADAA6E8B1470B16ACF51CFB80
+:10AFF0001F7BA2F5F67BD49EEF5B6BEDB9ECCC2406
+:10B0000020B61E9FE7CFF3F06CD65E97BD2EDFFA19
+:10B01000BEF7BBAC358410F217FC877F5712D2BE47
+:10B02000D1E6692F22E47EFEECD585ED1E3721E9BD
+:10B030001E9BE79091D03F2C3FA93431FD57AC5F68
+:10B04000EF314F5C7FB95320247B9C765CE7D74E71
+:10B05000AAFACAFBFF5FFFCBAD9FEBCC27E46BE7FF
+:10B06000430F84969344E20F03FD6DCEAA352E77ED
+:10B07000C7DA71578A347FEF54568E102FF1A5131B
+:10B08000D2D378B5D10F74D277CF88C95B4048E965
+:10B090009EBD264C97661C33B96610D21D10250242
+:10B0A0006D777FB2C9E8CA8267BB28B542BA4D3A0C
+:10B0B000B5A018F27BEB444903ADF5D555A72D8417
+:10B0C000B4DC2C4AD07DD25977CCB4D21CFB7E5F45
+:10B0D000B3383F04FDE90B9CB2AF8E7BDF2F90BAF3
+:10B0E000B019FBA38D18A0FDEDFEFC81FB5DB1FC4A
+:10B0F000536E81F6B7ADE1D42BF8BD1D4D221B3444
+:10B10000193D7125A40D734427963F7EE7D1DB09D5
+:10B11000A4FB1D6662802AC7E79C5A5002EDED9899
+:10B120002F7A0CD0DF629E76CCD77A9C90EE6DB8E9
+:10B130005DC4F25B9A61CEA0BE23E0A7ED596DA27B
+:10B140005303E9C9CD81483F944FAF31481A0F21CD
+:10B15000C35266449E41C7113240FE161288FC0459
+:10B16000F265AFD1B74FA21DB256E5107209FE0FBE
+:10B17000DABFFA111814941F74135ABEAFF9F6C847
+:10B18000992C9CA74984407BBD6E171D576F53B502
+:10B190003005CA6DB6698806DAE96B7F54225035EE
+:10B1A0007391F6F5B371EB9B3E27314DB43E1FB65C
+:10B1B0001FCCD692FB61BC93485C3E346D50A59584
+:10B1C000F9D449464F6169AC9D0CAF949056CA2999
+:10B1D000CFB68D4F92DFEB62692D104ED83DB65C35
+:10B1E00011A72F42C2765F05211B48E077F7C2788E
+:10B1F000C988C6B30FE9C5F86CD71B97417DD3CF7B
+:10B20000BBDE8049B26F98D487E9B68C99FFBE1A2D
+:10B21000CA75A4A779908EDA368E74B50101BDF790
+:10B22000ED198DAB217D18FA8EE3ECFEA6181AC03D
+:10B23000FF9320B91BD29993C510AEBBE6DA9D4EA1
+:10B240000215B3A582BE3668D7A4099412A0E35DA7
+:10B25000C45B86CF9FF1FD93413C3BE6C23C9D78A9
+:10B26000B8FCD2B330BFD946565EE9FFEE03C6BA8A
+:10B270009079ECB87A2A44CA670F6A23F566E867C2
+:10B2800027314848079DE1C7EACDF0EC215AA700D5
+:10B29000CFAC3B66BE83FDDDDE00E5719FD4E943A4
+:10B2A0002502611B0DF749BD7E00D7290B0789F3E5
+:10B2B000728B3EB40FF3B59E1BB09DDE960CE97EFB
+:10B2C000781E397CDDF2CDB88FF6A5798A68F5F065
+:10B2D0001F1F82F2BD8B6D9EFB611E0F0B9E1BB06C
+:10B2E000BEBC4C4F58FD90BD2E3DD6DFDEC6EB5C9C
+:10B2F0005E184707AC19C9A50DC804E840AB89A57D
+:10B300008D909F35C9BB0EE9B0E3B0E97AE32C68B4
+:10B31000378DE55F52F942A73C8790A165334B0911
+:10B32000D0635DBE7BA7A90AC62B046FC7744759BB
+:10B3300049A70DCA1F11E1E3B3F9F86AA0977BF49E
+:10B340002C2D9F7C691E1049366E539A3FDCE10517
+:10B350007AA98A7D9F88D09F874C4A7E786983032B
+:10B36000E67F58CFF26543F65CA87FA496E7CBAFA3
+:10B370002DF53AF07B89F58FE895FC8FAF6D80FE57
+:10B38000565DA5A43705B1BC3BFA7D56BEAA40C99F
+:10B39000FFE74EFC9E325EA5FF590625FD93CE06C3
+:10B3A00037D263285F82F1BE56665B36FF0AA4D3AC
+:10B3B000EB5CC817AB0A82EB7C945FF95C4BD2C79D
+:10B3C000D2CB4319CA771F3F85EB707089918FEB01
+:10B3D000BBBBBC8574DEAED1409945FB7EB8CB6C5F
+:10B3E0008F9B37F2D829AF16D797D5CFDD73E9B544
+:10B3F000AD669AA6FC51FD9DE9C5264AD730AF5EE1
+:10B400004D3C3D39C93537215DAE95A5FB2199A746
+:10B4100065FBB5A7517FC92228B773AD385B0374AC
+:10B42000448C11FB0DB04FCB5C6994BE77EBD877A1
+:10B430009E3C2B7E1FE9AB37206568A03D3110692B
+:10B440003907EF371767D2EF3922C7EC02A47B1D0B
+:10B4500003F522D261839E1441B99E75AB4DCF4155
+:10B46000BAC724D0FDDA937EBADA8DF98F379122EC
+:10B47000F8DE56C7EB54CE28FDFF41B186B6B7BD06
+:10B48000A93A8CFB7FABD92C61F737E9C20BB1FE2F
+:10B49000A6C3226981171D622857003ABDDAD51F5D
+:10B4A0006C8375EED0B375FA59C96050C67E484EAC
+:10B4B000930ECA77D58844067ED055B7644F01EE07
+:10B4C000CF76262706EB965CE681F677D5E89D4495
+:10B4D000887D7FBB20D0F166EA3CDB8A203FF39B6E
+:10B4E00099821CC7FFEEC957F81921E69984A4B1C7
+:10B4F000FF92ECEB86BCAB504E8924807221CB10BE
+:10B5000022FB903FBD6F210390EE4BF7B904C84F6B
+:10B510009B9D26CA945F9DAD43BE31091AC7FDBDF0
+:10B52000FDEF9E9671BC7D8404705C84449E47B997
+:10B53000666E1609AE575AC3D108A6A55AE3A8A14C
+:10B5400006DF0F10940FE4132BC822EC7784CA2572
+:10B55000F96EAB847227CDAD27CE38FE6D26908E66
+:10B56000E3FB7DF9997C1C308F28CF86F41EE443E1
+:10B5700061A03527B46BF39210CEB3747A5244AC09
+:10B58000C4E7DA45049F8F79FE9E3E4F9BCEE19340
+:10B5900078E3BE032CF51D87EF1617D08DCD4F0431
+:10B5A000BF9BBD7782FCB3F2792262A87E127C2F0A
+:10B5B00007240E8EDBDAB4A22582E3706A035618E4
+:10B5C00087B5EDE6169C076985D98FE3CC9993384A
+:10B5D0008E289FBC9284F6B9D87B2DB68F444297B3
+:10B5E00056BA06E9CB72A5587D3F4D124A77963B75
+:10B5F0009C542EF47A585A5EC5EAABF74F73899E75
+:10B60000CE8BB2BF880D5602D67905CC0BC96769BF
+:10B610003107BB0BFF87BEAC2E61FB2D6B1209847B
+:10B62000E978C3260DB45FD0949F89DF2352C88E7A
+:10B63000FCA0319FE1F26CD1B77C33F6FF2E3D9533
+:10B640007FEAEFDFC6CBD13FF8EE14C2BE63D19CD8
+:10B650009DBB6606FDBFF3711883E57F9DB6C7EFFE
+:10B660009B3BF385285D623D847328E7A636EBBDDE
+:10B67000A6CAD83C4D266C1C939B44FA7E72C3D15B
+:10B68000F58205DEDD67A0F30CA397FF02F3E86CFB
+:10B690008FA317F837E59EC47598ACA2277B20B11D
+:10B6A000BC4E4A2C6F55953F92C6D6B1BB968406C8
+:10B6B000983C9C8BFBC1EA07DC02E393B4E43E2B8D
+:10B6C00090E8932E361F5F43FC9A84DF3971FEB3F6
+:10B6D000C7D22189FF9E666CFA6026A783D984F1C0
+:10B6E0004755BEC5689127C1BC58485CBBD0EF55D3
+:10B6F00085AEE8FAC8F1744DCE52DC9C6519F5A20E
+:10B70000DC27B5C4B30FF8B9E5D0EBE49A1994106F
+:10B71000DFB5DA687EA43C8BD2EA28EE53CB9CCF0F
+:10B720000CCE2438EBB602B69E438F3F6377BA51F6
+:10B73000FF037A84A749350F95F98C5E2BF3191E08
+:10B74000D9793CB3EC39A0ABDA279E2132F2DD5730
+:10B75000341467F63CE5DC8478E283B9C42343BE45
+:10B76000F5E45902DD85F61D73F1BDC32F10418A42
+:10B770009B57600CA26DE267E773618A77FC807F5C
+:10B78000842B92E4EBC2AFE07EDEBDD8EC9149ECB5
+:10B790007D38F2A809F983232246F1026EDF38FCD6
+:10B7A000201B81AF9745F1C1C225E3E20579D6128E
+:10B7B0008A17D672BC406EC94CC40B372EF1CE1915
+:10B7C000072F90BF5B928017101F8D8B17B63D38E7
+:10B7D0003E5EB8E7C106C45BE94AF97BAF45B95F95
+:10B7E0002E0ADF27809BF206D63C689E8578CCEB3C
+:10B7F00041BC65D8B32988784BC15FC5F9B3AF8B1D
+:10B80000C75FCDEE4B7622FE0A1B47AA31BF7DA74C
+:10B8100061E7F398DFCAF2E70F942D66F9CAF70CD7
+:10B820003B87917F19C326C4DDEA7D73BEEBDCAB99
+:10B830000D9B2494A77C9DACF996C52D80570EECEA
+:10B840007FDACE708FD7B61CD6D77EBDD13340A756
+:10B850002111FFE89A5EBE41A88CE19F9B8BB60642
+:10B860005B601D2B34C02F93ECE7799CFF550CEAED
+:10B8700003A817D69698299FE85F7BDD5EA4E3DADC
+:10B88000274E77A3FCE87DA55E87FA5C6DBE969691
+:10B89000EF7DCA3F55A2F88BE919686FA1FD7EFCC8
+:10B8A000A440DC63C7E508E9BD88EBD5EF67E73363
+:10B8B0007EDE5BC4BE3BF4B839445C38CFC1465F22
+:10B8C00012FDE65ADEDFB68D400025F87DBF807C94
+:10B8D000E041C9EBC5EFE664F964D4DB74A0807B7A
+:10B8E00093E8F7DA8FF288374EDFC8CCF012ACA7B6
+:10B8F000FD680A7D7FC4E85B960FEDFF7EFE40E3A6
+:10B90000F7A15E8FC8F956B19EC93F6DD0B618C673
+:10B91000EB9CE2ADCF877E6F12BD3BE627916B318A
+:10B92000BDCDD7DD16674768D325C7919EA95CBFFB
+:10B93000E67A1EE823A5382E147B8CBEAFF3E17E99
+:10B94000DCC4F74759E5751477658B619316F9DB0D
+:10B95000ADA244F92AF0942D33A928A2F2B97FD9D7
+:10B96000901D9FBB5C0C47815C0B3F8BFC713DC8FD
+:10B9700043C218841827F794FE74BBC428DF4D26F1
+:10B98000C7422E27CBE7F515F9A7C8372F91E9BA9B
+:10B9900090297E19E7D35627CA86CA184EE958F26D
+:10B9A0002AA567FC9B00D779D7FC0FC675CB5D191C
+:10B9B0007C9E12711DF0A54032FD7C4B095BE72C8B
+:10B9C0002BDB8F543FCB42FCE71CC0F1087E328C4E
+:10B9D000F68C02E25CF20D29563EBC543F7C0671A7
+:10B9E000A24D43E586D42EFBC4F3C087A3937D8F7D
+:10B9F000209DC6E3C39A3839EAD58C8F0F67184665
+:10BA0000BD43C86FAE320606E0BB390D5BD6692C6C
+:10BA10006371E28F4A18BD94A60597E3BE25819015
+:10BA200069491C1FFC5109DBB751DCE687FCF48B2C
+:10BA3000C0979B18BEA47A1AAED7BD0C5714118FAD
+:10BA400088746CCB3A2B08409B8F73BC12FD2EC7B9
+:10BA50009737717A56F0E50A4EBFC74A14BC1132C7
+:10BA6000A13EB732A0E0CA113B8E279BDBF5A0A810
+:10BA7000B1AB9A3EE757C0F3B77C7C056622238EB4
+:10BA80002A586AA4FBC4A281FEE0F8AE2504F1099D
+:10BA9000ED1FA69B9CCE6767619AD5FF0DAF5FC473
+:10BAA000EB17D598BD260B5F24E8EF6ADEDF1E8713
+:10BAB0005F5F02E30795D5F928A56F1FB59F397C15
+:10BAC00040FFC8F3B53EDABEA34972D2748781D273
+:10BAD000AB823357B41B12D66D86C1AF37607B2B58
+:10BAE000CD747F157424E2CAD5CDB09F2BF1FB89AC
+:10BAF00074AFACB3B2BE23258CBF8C9428B838B4D5
+:10BB00000DFB35B90EFA05E5731CC1B9A8AF030EDC
+:10BB1000A57698EEBBC81E8A438D8C7FACE4E35BB0
+:10BB2000D9EC5F908EFB414306100F105BE879C49F
+:10BB30007783CDC54EDC573D46CFD5C80F7AFE235F
+:10BB4000DD29437F330BF87A61DFE2D671F8D4AB9D
+:10BB500026D4978FA01C81E7709D48904FF6B78B35
+:10BB60007B508EF5371C3339D1DEDA7ECA84FCBFB8
+:10BB7000C7C1E86A701D09B5227E6B5E21A01CC991
+:10BB8000718C6C437E616F10C90089AD07B509895E
+:10BB900074BE6B713D1C4472F648383EF6BDA280FF
+:10BBA000BC0EC02C296A67F357AA4F9CAF937CBD8B
+:10BBB000956774BE026CBE1C7CBE8876444079A337
+:10BBC000CC93C2D70B9AA1FD4AECF7889DEE373E85
+:10BBD000FE557CFC304FB56BB262F3A4EC2BBBD2AC
+:10BBE0006F12A6E3CA6912A97D424D173D8EE0305F
+:10BBF000E6F708C4B90BC655143424D045CEC90E97
+:10BC0000A637FE29DD897CA2605522DD4C9513D331
+:10BC1000B60D89E994FAC91584DA1773547A8075D8
+:10BC2000443C67B024A9A767F3ADCCEB370B181DD4
+:10BC30003EEC6274D832FB214A4FBD020919A85E5E
+:10BC400010EE2E46BD07D613ED78C021654C5BDAA9
+:10BC50004804F5A0DE5F7FEC4579D2F79485DA875A
+:10BC6000FB3E3D47D3832D5AD20AF3603D7E36D248
+:10BC700000ED7C6B2B407018774FFB0734BFF30F40
+:10BC80005ACA972D759D4B902F5B54FC7122FD482D
+:10BC9000D167CE572FC2BF64FA10D5B3A89DEB8DE4
+:10BCA00020E2DFC32D2CDDB0F78DA0EC18ABCF2840
+:10BCB000CF17393E80FA0DC8DF0A975A08EEBBF756
+:10BCC0000FE5527BA952AE85CFEFE17C86CF6C1F8A
+:10BCD0006948047053C551235DBFDEB5390368B7A9
+:10BCE000B749CCDE75ECDC13F6EF211D1ECEAD4658
+:10BCF000A8DE73EE1FED02EA578D47CBD17EB55516
+:10BD00000CBF508EF8EA512DC523271E4EA3FCE12F
+:10BD1000F6C9697B0C71B8EA11FE5DDB86837D682C
+:10BD2000B7EEDE2893DF17C5BEA31ECFC3956CFD0B
+:10BD30000F8A301E8653EBF753FB6EA5703FA58329
+:10BD40006023F6B7A7B1D885FBEDA09E8DBB7BF530
+:10BD5000D302FA6B7AD612519A3EB6DD8399E15737
+:10BD6000F4D85FD122ECCB8A95579783FA5AACDF8F
+:10BD7000BB96A4C5B7D3B3B6B3DECB710F7E7F8BB2
+:10BD8000C3B107E797F880DDE0FE64BA398C97F716
+:10BD9000FF0A6667DF6E17295F22BE9D2D2B216D7E
+:10BDA000B8CAE8417A25ABE679A3FE05E09FF6E044
+:10BDB0000FC806A0013B00475DE6D8FCF0D2BB4EA1
+:10BDC000A0FF28AF41F4084EB44B7A46A9BCF73324
+:10BDD0003CD8693BF6CA30BCDF6AAB1E1D86F43F17
+:10BDE000179453FEE419D6CAD47EDEBCFF21B447B3
+:10BDF0001A56AEBEAF9824B15736707B65C348CB98
+:10BE0000399897FF3B8DD9BD26474E517B65671307
+:10BE1000F33FA9E7EBCD693AA64F1785A81ED1736A
+:10BE2000E77E3BF2DFBE467D1D96EF6C3AD6BD7ACB
+:10BE300006DA27176531FB24B3D76F6AF16A5B66B0
+:10BE4000C4EAE3DF85D809FB114FCE88E1C9492454
+:10BE500042F9A78223FB1147C2BEEE6F7A34827C7F
+:10BE6000A2CF6B1C45BE90D6F053827C1FD48C11A0
+:10BE700003608841214471A4FCA995ECF38CC58D25
+:10BE8000803A22FD909FBEC12ADD2F8DC591EF948F
+:10BE900033FCF405D803DF2EF80AD9030BC8A840F9
+:10BEA00018FF13508F7CAB7CAC3D3041DEAAEC8395
+:10BEB000BF29E7F628C54E88E50A26B60F66177231
+:10BEC000BBB24A5FC2F288137AD6825C74C5F0DED8
+:10BED00014C47B99F439BF029E2F9633B93D05F106
+:10BEE0001AE0B72988F72C54BF12707C0ADE9B4AEF
+:10BEF000789AE3BDA91CEFFD8CD79FCAF1DED43838
+:10BF0000BC97A86FBD2BD0F9067C573B0BF5AB0F48
+:10BF100068FA1F6E234E11F1E37D8972F97F8A1D45
+:10BF2000717E61A21DB165765A0BE5B77707ED8684
+:10BF30002AE4BB4717A423BE20C10388B3E7171A1E
+:10BF400013E22862FC728509F980B54E5CAE47F9B0
+:10BF50007F7C6431E22AABF7C2E4EBE7B53FFEBC7D
+:10BF6000DC15B5F39E8FFDF1E0A1475F407BE38ECA
+:10BF70001A919ACE0E1E7ADDB82209BF539E6A7BB3
+:10BF8000E48B48A3D928B783F5C9EC1FCF73BD3C18
+:10BF9000CB72D68BFAA6F25DEBA17713EC9E96439B
+:10BFA0004CDF56B79F853446F1C15B412FB36FD24A
+:10BFB000F41D836F056548AFD730FF2AD944289F09
+:10BFC000FC303FF0BB7B91EFAF2DAE423BE6610111
+:10BFD000F807CE638B99E68364684D43BC2E5BC93A
+:10BFE000FD4817EB3ADF590DE53ADCA574DEBA6F70
+:10BFF000EE3C6784B44B2B67625C42AF7F17F59FC2
+:10C00000AAC7655F15A1FCCABE41E3447F74F4BDB5
+:10C010003148F5F79C97344486AFE50497B7E8B00C
+:10C020007FAB08B5E7831C1796C6E9990ED8C411F3
+:10C03000F8F42DF0A438C99F46D374FCB09F32A702
+:10C04000FA77157E0DBFA3A7DF2135CC4EA1F83DB1
+:10C050005FDEFBA90FA01E9A0C2386CCD4EB16B58D
+:10C060008BCA9F48B5E6985DF48EBD9FF81067AD0A
+:10C07000D748B71CC27EAE49A3FD1C3B8F6412F5A6
+:10C08000CBDD2452B90BB8A916E9D3BE5E3C80F8CB
+:10C0900089B865A11EFAF574A591CE636C9ECE0A8F
+:10C0A000683749324F0B501EE5E13C41FB79C12313
+:10C0B000C3885352CD5325CE13347D19CE9340E718
+:10C0C00045403BC19467D2E87B855E947912F219B2
+:10C0D0005D46C775E304E3AA4F1C57CE0E1817EE52
+:10C0E000BBC2B3AD287F6C4DC15948077F2861E3BF
+:10C0F000538FA7BB7D899524C1A9CA338FF7BF820F
+:10C10000F7DF6E0C0B923BF5B8617CA70AA1FF39F3
+:10C11000CFC4D143DCF8A2766A9964D4BA6376EAD4
+:10C12000BEBD6431AE6778A9E257FF742402F4D132
+:10C130001959D178C889F3C1EC3849E681CAAFDE14
+:10C14000B56FD2F1E6DC416621C9B8B4A3C770FF70
+:10C1500074E1F8219D51CAF8DE98F1FB61FC28BF1B
+:10C160009C8C3ED5E357E8DCC3C79FD3A45AB7895C
+:10C17000E7E3CF8571FC363A0FDC7EFFC4DECFA843
+:10C18000BE10E517E43E5F246E3D26D213F4455FF2
+:10C190008E9E30A388F1C7F3D5137E5CFED5D613EF
+:10C1A00066143139ABE809BDA827D0723B8711C7A7
+:10C1B0007D5E3DA137FDD0F3C8863453EFB90F9FA4
+:10C1C00086DB18DEBFD0B889CEE7C8D304C675C9F0
+:10C1D0008DFBA95F2097FB01D4F35099CFF6812DF9
+:10C1E000C73BAF287B623FDCC22286135FE17A7EC9
+:10C1F0008566A4DC0858AE53B2EF9C7739DD97947E
+:10C200000F912BC5147C8AF131F9F2B4043E65DD3F
+:10C21000C1F9AF83F1DFB74B12F7A7750EC3D5286D
+:10C22000974AB3CE9FDF4A7CBFDEC8E512ECBF550C
+:10C2300045545F89E3479AD83E8479AD4BA627E5FC
+:10C24000B8F4CC5FA31A6F872855A19EB2CBBD3539
+:10C25000A885F4CE2566BE2E0B3A31DE85E2762522
+:10C260004EC8887E4B91EFEB05D73540BE746234E3
+:10C2700062063AB9ABE8C7BB8CD03FCB88527EABE5
+:10C280002F02F9441BB6FBE2EDB577F038178EF7B5
+:10C290007B1A32AB919F5B7FD1D642E75D20A345ED
+:10C2A000E8371F096D43BD89CCCBF41439393DCF34
+:10C2B000A4A62A6E3FF3B750BD6AAE2D4CE994F8A0
+:10C2C00087B13E746D94DA63D6E959DCD903FA502C
+:10C2D0003EF5BFC82D8B209DEBB58DA21EB5E3E4C6
+:10C2E0008A615C5739607116A15DFCC4484B1AAE77
+:10C2F000833C9514C1D3EB75C8AFD3F985F983BEE0
+:10C30000E736C3F851AF7B40BF075D9F397EC88FCA
+:10C31000E39B3E1F2B2F6079500A7A1F60FB505D14
+:10C320000E5688EA2B39FE39BC7DFE1EC683DFCF50
+:10C330008315473C049345EBFD0BAE3B7C3FAF2E92
+:10C340006447DCD57367673DD2D173192CFFFA7946
+:10C350002CBFD468D4523BA4D749E32FFF9EEB09EE
+:10C36000A9E4E017FDECDD48E4D7815F6EC727A89C
+:10C37000D4C34DAD268CD3EB6A3A467178AF5E6E6E
+:10C38000C5B8BBEE1522C5FFC335C74CB87EBD2767
+:10C390007504F9766FCDA3B45C537926F313B6D741
+:10C3A0005E8AE91E81ED63653E84498CDEA3745D7F
+:10C3B000CCF505CD65B9282F06795C90BA7FBF2AE8
+:10C3C00065FC7DBB45912B192444833D2302DAE7AC
+:10C3D0005F2F1212F0926D4AEB7201EDE0F2DB4B2F
+:10C3E0004E803CB3A5C5ED03D06F771245BE111941
+:10C3F0004571D7E6342EE797EC9E0774BF9D977F73
+:10C40000BDA87637FA7BE3F391DFA9F31DF778C96E
+:10C4100006D0EF1C5A222FCA443FFFCC355A94A1B4
+:10C4200081AC189DE4C7EA0180DF1D817AC3E70C67
+:10C43000C397E03CD6B338D5DE338D73D1EFD2F756
+:10C440000B938C768B3EBB4CED22ED2F4528DDE91E
+:10C4500016B2F6740054914E1DFE2D236867CE0966
+:10C460006425D0E9F0B935765CBFCE334F517F5BA0
+:10C4700030EB4837CAEB9C263D898FEFCD6962F5DA
+:10C48000CF974E14FA4899CFD78768897D711C7E63
+:10C49000D9C8ED1C39246E3EC6F19F7E51CFF3ED15
+:10C4A000AFFABDD25F253E3A2832F9AFE43B4A19D4
+:10C4B000CEB9BE94D15D0FF244E4478BD3A87D433F
+:10C4C000890357CABB399D4B65ACDDC2A5DFB18E70
+:10C4D000172FA0E0A6683A8A977E93FF3DD49F1756
+:10C4E000DBAA31AE5AC14B3D8FCF77215ECA00FA2D
+:10C4F000D367C6E21EDF2FBCCF2703BDEE015A1C57
+:10C50000A1EBE2A5F8FAD8B2EBEAB1BF5D77EA6930
+:10C51000BC76D624B99BEA7FBF35D0B8D6EDF3E51B
+:10C52000056B704C35E412E4BBDB9BF2A9FED6151B
+:10C5300011691CA35C27D2F8D82936D3681BC8AD73
+:10C540009EC831D322E4A3C55A456F36A29F1FD59A
+:10C5500029F6247AB1866E371DA6FBEF84EF233EC1
+:10C560006E00ACE1A24F2FCABD2EFFA3A6AB91FE79
+:10C570009B32A979C826101FCE7F38728AF6B7A7DA
+:10C58000B958C4F2FD77AE36A17EBD8DDB7B3B236F
+:10C59000C9ED8B9717EB68BE6778158DABEF2464F8
+:10C5A0003ECEE36E1D934F93DB9DD53289956FACE4
+:10C5B000E4FEBCE6187F4071D51B50E466C9F5283F
+:10C5C00037B73729E9A197514E02FF13D0AF94B77F
+:10C5D000414C8A738C1506E6FF4D118FF1368FB3EF
+:10C5E000AFD224F71FE7BA12F5A5BEE798BC738255
+:10C5F000FE8DC629C03D02FA7D60D202E8BF766991
+:10C600003D37A0FEB15D365379F4613E998BF1FD63
+:10C61000BDAEC2800CF91F9EF9C1B6024CFFCB25FE
+:10C6200044C3E4F37003DA73BCC600CA5FBB910C69
+:10C63000A3DD35D76FA6E525EF28413D1EE4F72899
+:10C64000C6C9E706F7B4E8E3F4F11C95FE0D788956
+:10C65000E2056915D94BF53F6F9C9EC2F4F15C571A
+:10C66000127D3C97DB41769BD8BE7B6654BCE626A8
+:10C67000EC675D4E06F633ACF553BAB1B4E7082D5E
+:10C6800050F6F76EB69F2C4B7F4AE75F0C9C95CF18
+:10C69000A21C9915B123EEBCD838D96A8EBB4CCFF9
+:10C6A000EEF2236E99C88ED2BB76BF1DE57B8F2E2E
+:10C6B00044CFFF3C8AE74980041FE3CF088FF7503F
+:10C6C000F28FF2F3264FA6C87F9AE73FC39FEAFC9A
+:10C6D0007F52EAA5A87F8CD73B9EA2FE4F79BD135F
+:10C6E00029F25FE0F92753B4FF4B5E6F2445FD53F9
+:10C6F000BCDE4B29EABFCCEBFDEB987CB6FEAFF27B
+:10C70000FCD3AAF65FE3E5CFF2F7CF4E75B278A27D
+:10C710008CC7EC37C37A6A513FC17DBBA72D13F993
+:10C720005D1C0E96912EE2E2F3292E8EC69B415A95
+:10C730006B4B48D3F8B8F229A17C340EFDE7FEF527
+:10C740000F3A317E4CE3AD471BF2FBC5C43B3FA122
+:10C75000BCD0E98D8B0FCB1B30ECC438ACB0D15BB7
+:10C7600085FE034C6FA6F168D26522D4170F7DF7C2
+:10C7700041E3E5C9CA27A62FFC7BAAFA5669527C79
+:10C780009C8FFA596526B219E4C6BF15B3FD57351B
+:10C7900034B210E379D4EDC0F454A1DC8AC5DBE9EE
+:10C7A00077A27DE0C333DFB0FADD31FE46CCD2B3F1
+:10C7B000B8BFB2AE9132301E41F94ED74689C64558
+:10C7C000D9F35D09F8B6CB9F39295E4FEE3C2E4672
+:10C7D00074D618BFAEF29348761C4E711C27B982EE
+:10C7E00015E31A9F129CD09FAE5B838DB81F0FD7A5
+:10C7F00026CA7389C725D879DC6E957FC48B786784
+:10C80000ECFC26E7CB3A37F71798250D1D8F06F479
+:10C8100093AAD87C558549445789CF915A6C371AC9
+:10C82000A728EB16E33908254EF1A3FDBA9DC81FD2
+:10C830005A66BF90E097EE5D2752FBF8E006585D20
+:10C8400068D7DA3EBEBDFB69CE1F7B71FFB853EFE0
+:10C85000BF9FF0751CAA60F81BF9D24D71F332CC62
+:10C86000E5E25015B75745F74DB1A8EC1B11CA3F8B
+:10C870005FCCDA7B762A6F2F23D6DECAB8F60EF3AA
+:10C88000F3044ABF52F1AD03C589FD4FC55F9EC297
+:10C890007271EDA5E223C3AA72A9F8E16155B954FA
+:10C8A0007CEF7155B954FC799F6A1C0FF37261FEDD
+:10C8B000EC2F66726922BEA4E66FBD9C2F457EB444
+:10C8C000EA4199F22DCF8B8BA8DECDEC5FE8EF3AF1
+:10C8D000A6C4BB70BF18EAD55484034FF85D09D3D2
+:10C8E000BFBA4776657C93A230425A73627EAE0728
+:10C8F0005C4E1E3713DE86FE31CB6DCCDFD5631F59
+:10C90000F5B9A95F6FA27885443F953A3F1AEFAE1B
+:10C91000F21FA9CB4DE46F7A98D37936F7DFA05F89
+:10C9200034314E8EF8304EEE22E2E31E2CF91BC459
+:10C93000C7FD98C7AD2AF141C3A7662F64FE2F69D2
+:10C9400000F7FF70BB280B14D7E60FA0FE37CCF919
+:10C95000D4118C37CE8AC5C58094A2F3D05FE3A0F2
+:10C96000FED4A83D6693E2D752F96325E91A37AEA3
+:10C97000EF95F9D5ECDC1A491A2F374592E70A9062
+:10C98000FFCB7C1BD3771A06685C5494EE3625D215
+:10C990005D7CFC1CD29D12773554C9E221A7FEFABA
+:10C9A0003D13862DC5FCB0C9E3E97EC3E3E87F9360
+:10C9B000CFE991FB63957830ACA7C5F1AE63F499EC
+:10C9C000F6918B782F8BC58FB6F07A69DA1041FD1E
+:10C9D00038EDA3429A5F59C0F69B1237A5C4458132
+:10C9E0000620D2381BFE5EE937CC831E9F47A27A11
+:10C9F000F99BD7A23C2DE57E80FC8237AF457B3882
+:10CA000062438CFBFB433E6BBF08F431F4E72A71B1
+:10CA10007B053CFF0CEF5701CF57E20227F24B3F5B
+:10CA2000C0FD7B8D3876687FB9D5FF16D2A7F7B1E8
+:10CA3000B3ADE837303A08D5BFB475BEC824E7C4F3
+:10CA40007E0BA8FF0EADDFF44E04E73F5A1F1DCA50
+:10CA50000513DB6F2FDADFE366FD56FC3D97A6F288
+:10CA6000779CA7BFE7B2F3F7F7FC97731C7FCF7FE4
+:10CA700039A3F39B5D8AF3134931BF2A7F0894A73A
+:10CA8000ED7A4F262FAFB40B9C2582FAB285DB31AD
+:10CA90008DE49CB710F988D71846BBA565E43D52D4
+:10CAA00081FDF61A47D15FEB7526DA29E1EF93BFD6
+:10CAB000CC64DB8B9E473ABD662EFA7BFB2E0102CF
+:10CAC0009E857EDD447BA44DEB1FA671C41EE2D97A
+:10CAD0005435D65EA92E2F2FFD3341FC666D9BBDCC
+:10CAE000468B7C710EB31B7D1DF623F2C5F3B5ABEF
+:10CAF0005CE8F3BCED46244CED46F8C47DB180DB28
+:10CB000057B6B7A5CD47BD1AEDD11817A9B4576AC6
+:10CB10006CA0E72ED01E89F6AEBE1A16D7D95F5785
+:10CB20003B2E5DE57C9441E438FBCA76BDBF1EB068
+:10CB300010393C346D699B31CE4E277FBB03ED74B9
+:10CB4000442BD1788E8E9B79BCADE4758D67BF89FF
+:10CB5000C6E3A11DFD02FC67B7967E39FEB3BED2C7
+:10CB60000BF39FED29FD6AFBCFFA4A13FD673D7178
+:10CB7000717668F7F8A2FD670A3D507B9C3B7EDE2C
+:10CB8000583F7B1B8BA9DDBF5B175C4EED126B73AF
+:10CB90005CAD71F3D67353B81EE7E5ECA63C815C3F
+:10CBA00041C8F74B999C51E8A9F7A6503D9BB7297E
+:10CBB000343F2787C4F45DE05F39B1F353B2CAFE56
+:10CBC000EDC5101C057712795AC73C66EFA4E9BC85
+:10CBD000FDD396CA49D2EAFD13F577E46BA85DBA96
+:10CBE00073735AD2F3FC17CB3FB2CA38EEAF693534
+:10CBF000A19DA7ABA63A0DF77BA9F13E13CAF74159
+:10CC00003FDBF7DBB99DE629D8CF32DDBFBECB3C99
+:10CC1000303FC17A3DBDAFA253D0503D66F8DC37FE
+:10CC2000E6237FEDBDDC39807650DFF38FBD82E7F0
+:10CC30004072DA8BA97D757A19A393416E87B7A2EA
+:10CC4000BDDD12E39BCABA2BE3CFBE42A4E357FA81
+:10CC5000DDB5911C784387FE15E38137A87F45A297
+:10CC6000699B7F94F913EF49B4DBDB893CAC17D0A7
+:10CC7000AE9F95E05F7AB4EEAC8CB8C1D1443C086D
+:10CC8000F6AD4D89F5FECFC977093D571318F5A2CA
+:10CC90005DCE0E2B99EE8CF58B964BA2FF77DFF4D1
+:10CCA000D3057ABA6F2D5E6CFFBD40F5F578E6A02E
+:10CCB0003B23588F78B58BFB8594F23FDC4886DAAE
+:10CCC000989F28B40AC6D1B5E2E361B42B76AE23AF
+:10CCD000D5689FEB4A3BDB82B8B6FB76528571F391
+:10CCE0009D3AD68E52BFB08CF13727B783ABDB5756
+:10CCF0003FBBD2E44602FCD67CE0CADD6827E917D8
+:10CD000014BAB6D07B0DD474D9D5F6AA1DB1A463DC
+:10CD100008CA578DCD7717B37D13144884D9EB8D8E
+:10CD20000C3F033F47B9F3F9F7CDAA8E7949FA339F
+:10CD3000B67F6949EDD422A7B367D71E15508EE59B
+:10CD4000F901AF42B98240C48E0748FBB81FCDC27B
+:10CD5000EFFFB0E213CA55F0F9549E4A3B6299C402
+:10CD600070B596B8705FF46EB451BAEBDAE8A4749B
+:10CD700098D734CAF51E461F3AE019D49F1408D339
+:10CD800038A3ED1B4B6939253E2BEF9E447A54D3D3
+:10CD9000E7F0B97F931167F6DE443C2887ACAB120D
+:10CDA000F37BCF3C3F1FED1E7DB34808E5579F3D09
+:10CDB00012B122DD5D0E7A9D30964E2D4D1F788783
+:10CDC0001067A11FAC06714C627B5F145FF9BC7CDD
+:10CDD0002865BE65C48E761C4A7FF6B1EBFF79E309
+:10CDE000EC7230CE0EFD35EBB6D038BBA3652CCE41
+:10CDF000AEEBE62D34CEAE740FF36FA8F1B5CDCF08
+:10CE0000D62FA74EA2F83CCF2F86109F47E38C6AFF
+:10CE1000C68F338AC6D33525C6D39D070E97CB92CE
+:10CE2000C41929F176D687BE4BE3EDD66B7C5E1A2A
+:10CE30003770957114E3A7B54E5FA49C8E9B507C10
+:10CE4000AC9E1F54841742790DE067C4D3BA2C4FAF
+:10CE500084C6BB1016E70D383D5886B8FEDB730953
+:10CE6000F2756316E074A8A5317B09CE432C7EEFE2
+:10CE70006E09F526257ECF7FE06E9F4CCF414B7F1C
+:10CE8000A6F7797CCBEC443F1EC603EAABE9F3B8C6
+:10CE9000019E6F611F109F09026FE7AE20E2431BE6
+:10CEA000099A30AE60BD46CEC4FE91350C6FA5D454
+:10CEB0009B96B3F894DEB55BCA70DD5CDAE05CCAC1
+:10CEC00087EF61FA5279790A7DA989ADDB44F33F96
+:10CED00095AF5F75EA78C8C7CAE2FD2F0E4607CA4C
+:10CEE000BD31AD07D6539CA27C17E6F5C7745E0F23
+:10CEF000B508FA447D52D6B992ADEB85E98F954FCE
+:10CF0000B2F3EB8EBA3E7A0FD1F467C24223CCCB98
+:10CF1000B754F39053270B6CBEFC54DE77D78DAF1C
+:10CF20003F2A74ACC40BDA9A12F5425218A4F65791
+:10CF30005B13A1F7388D43CFAF26A3E7981E7E2F52
+:10CF40008D0755F4F0F7FFF15E4A4F5F94DFE1BDC6
+:10CF5000B28F3BE2FD0E9F1ED8E443FEA2944F7BAE
+:10CF6000E8B30E1AB777B1F9DC4F90CA1EAED8BD40
+:10CF70003B787C96F2DEC0E3B1F43CAEAE2D236785
+:10CF800013F2ADECA3A213F765AAF551DFE7A33EB8
+:10CF9000BFAEE4ABEB7DCAF143AA73F1EA766271EE
+:10CFA0009CDFBDA8384EE2043E4AE965D701C49132
+:10CFB000D75FE43E55C773029D95967F6D9C78556B
+:10CFC0006E97F8C9817F50EC129558DE7B02F88786
+:10CFD000CACE833852BD9FB334FC5EB017D9BD6052
+:10CFE000A9FC3451FCC5FD3506D7F8FE9A3EEEAFDC
+:10CFF000E94BE1AF998CFE9AE9781EE829C1999E28
+:10D00000DA5F73358F7B52E809E84883F3963D93E6
+:10D010005C141DC13C5D5B7E5EF6B4E4FB18EADF88
+:10D02000589E3DB1BD485997BF36FE509EEA380F15
+:10D0300005473D61216A3D84F84BA81E42FC06C4A9
+:10D04000F1127D46F9990ACF399A12D36443727D61
+:10D0500087A63518FF32C271F7B95D789F861AF737
+:10D0600028387422FC3E3C87C79DCD6171678A5E7B
+:10D07000D7E767F16418EF950CAF28F1604A3AAA38
+:10D080008FCED324CC83121776B47CE132E3648C48
+:10D090000B934CC85F27CB8B96CD9F75FE715CCAF6
+:10D0A000FD17A9D6276697AA4EC3F10CD6B0F1F4A6
+:10D0B000D5C138DC685F0ADB51AFB9EFA125CBDA07
+:10D0C0006AA83F90CFCB3B4B22DCCE85742FB5A610
+:10D0D0003911F7B5AC3DFA0AB503FE5AE344BB4D2E
+:10D0E0004560F5DBA80C8CFD7EE2BD13EAA7C5C048
+:10D0F000FDB30075D08E36A13E857ABC9BF527FE28
+:10D100005C7F4F39D337BACB09B3435CA43DA3004E
+:10D110000DECE3D833D08D46CFDD173AE977A7720F
+:10D12000FBBA728E4A393763C9225A47353B7F832F
+:10D13000FCA9BE90C989EFF07A5916164F1C3DAF75
+:10D1400033279F42C229D83EB49357C8FA3105DB32
+:10D15000CF8C9DF39AC8EFE6F84587A9C28971592B
+:10D160007D19DF74C6C97D79DDB2481C7F53FC0090
+:10D170004A3ABD9044CFB1C7FBE9B2797F53FBE98E
+:10D18000D47EB8117A6E1BFAE7ECF1C4FC3B65BCA7
+:10D190001DA7EABC5D96C147EF3954EE0351D3C9D0
+:10D1A000C7D3181F56EEAB202424C4AFBF920FFC88
+:10D1B000760FA5D37642CF550BED64F82733E8F40C
+:10D1C000F8BE01FDF8F0B549D43FD76767F76B4A61
+:10D1D0007ED9275AA83C9E4BFD038B0CCC6F97DA67
+:10D1E0004F679C96FDF9FD74139D6B9C61607243C3
+:10D1F0007DAFC16FA731BAF9AD320F934026A1DCE4
+:10D20000BC4564E71FFF4AF758ACC47B1DE2FC55E0
+:10D21000BF9AC6EEC999E8FE8A54FEB61E2FA17ABF
+:10D22000505F73CE00C64BCD989678FE31E66F1BEB
+:10D23000A1FC2CD53D173F9FC6E4F1E7BDE7E267AF
+:10D24000BCFE57F59E8B08A7874894EEFF36F75C27
+:10D25000DC36CD15F5677E95EEB97886AFB7F2EC82
+:10D2600031B2EFE70498BD27C7C1C66D6FD63B0743
+:10D27000E8B8597C7E4F80EC91E3E62D7AEF05FF0C
+:10D280009EFABE8B82667EAF1EF972EFB938EFF35D
+:10D29000B31779CFC5439C0EBF5E2824DC73D189B8
+:10D2A000F144B8EF88BF1BC795EA9E8B4EBCE7627E
+:10D2B000C6D87B2EFAF19E0B0FBDE7C28B71A4D1AD
+:10D2C0007B2E9A3FA0E507957B2EDA93DF73B19012
+:10D2D000CBB1EF4F7346E5D9E7F3BFBFB60CE3A67A
+:10D2E00014FFFBC669AF2D43FCADF8DF6B79FBA9DA
+:10D2F000FCEFB379BEDAFF3E51FC82F317EF51F930
+:10D30000DDBFF8131A3713D3DB3F1B577EBBA79142
+:10D310000B8AEFC89DA6C477B0F2C43B6242BB73D0
+:10D320002EF6FB6BB17695388C175DECFD412DB375
+:10D33000971C2C347B5A705DB5A157AF80764D0F8A
+:10D34000317F462C5EF651D3F2387A79977F6F772A
+:10D350003AD3D78F4B1A33DEC7DADBC4700FC8E17C
+:10D360006BE8B9984622A149AB5F179A8BF7D7F6BD
+:10D370003F4024D483C5F6500BFA59FA1B47683C4A
+:10D380006D278F7B7EB6E0CFCBD0CEF371B9C4E5ED
+:10D390004988E20A05C728FC6E061F173186B6A128
+:10D3A0005CB2DC01FB11BF833846481D6718C51D00
+:10D3B00051BFAB5354FCAE28772FE5F7E7287851DF
+:10D3C0008D5FD4F9A9FCAD0E1E3FFCB7F6B72E74E5
+:10D3D0005F98BF758B5B50E1ECAF96BF75A1D2FF34
+:10D3E000BF92BFF5D212B6EFD57ED7F7B27C3E37EB
+:10D3F0008DCB70EAF93D39E3D2C377BE607A782FDE
+:10D40000CBBFDC9D1DFBBE72FFF944FDB8CDFDC551
+:10D41000C6011C3C54DD8574E84ED74B68FF57FAB3
+:10D42000516660FBAEE340F308DA87728722D4FFCF
+:10D43000E0C54B3841EFCA6DF0DC80E9C9B285D058
+:10D440006760BF807A626E7BE75CB4C31ED85B7D89
+:10D4500003CA8FF7E4B27CD45306D3FDC21237DE81
+:10D46000ABC9F8CE20E73B5D1B9FEC6B03BDF8AA70
+:10D47000BA10F56FD9FCCC5E95D7E4BF0CF9500912
+:10D480008F9B52C69FDB1416D0EF75B17AE52CB78F
+:10D4900033E17E23B55EB9BE484AB8371FFE8EE73A
+:10D4A00066A11F8284E2D763B995DF1FB02A40FDD1
+:10D4B0000836BF8FFA5B7771B9D73B83E13ED9CB92
+:10D4C000FD899A3973B1BF86CBFCC59A38BBDA6E39
+:10D4D000A786969FE8F70526FA3D81897E47E011E9
+:10D4E000777AD69B9350EC120FDA67AE7EC4BD6B91
+:10D4F0003EF2A15F6BE8EF31ECD5794513A4379C80
+:10D50000163C186AA8DEEF76E3B5DD78AEA76D238A
+:10D510007C4787F3CDCF416D94681A36EE7C7ABE96
+:10D52000E386CC0C5C8F739C5E87EB5AE97DDE3D15
+:10D53000EDA244E9F0C44DDBF03CE67B592245F313
+:10D54000A53A3FCB6F123D32E6D7B5DE87F824F619
+:10D550003B172B697EB724D27EF534BC3E1FF34BBC
+:10D56000EF1425F42F0FF2DFB1E86FAE4E5B49EDFB
+:10D5700029A728CE55DE0FB6B3DFB7C0DFF1407A5A
+:10D5800053CE6F95B8FDAD62DC38D73B597F7BD168
+:10D590005E09F9BAEC97A85E316893045CAF69CF75
+:10D5A0009A28BDE565497B4C30BE102F6FD8A0F19D
+:10D5B00020BFD6B533BC96E70810DC37860D7AFA63
+:10D5C0007E9F93D19B8EC0BC25C4BF4AB1B406CB0D
+:10D5D00071BAE3F77D827CBE86D2CF2C22A11E19C0
+:10D5E0005EFAA617CFBD74AE23F45E7631A09C7BA5
+:10D5F000D1936F40FEF662F69D08B9CA5C45E579A5
+:10D600006635EE23E5DC8B93BC44ED6647F8BC1C25
+:10D61000399E49FD313BE6E456D1F33E59B280B81C
+:10D6200063158F538EDAC1CFAC9F2E523B780E3DDF
+:10D6300067153DFFDCB4E51D4D259EEB617E44A9D9
+:10D6400049A47E5CB59D5B995FB5BD5B39075DA75D
+:10D65000F8A3627E157D05E58FC9CF432BFEBA8600
+:10D66000E207A45637EE638607E49B610EAB6018B1
+:10D6700099DE461267DFF3F378F589F86B5EC5979C
+:10D6800023F717548817749FD9AD15C2573ACE6A3D
+:10D6900081D2FF2FF83EB3DEF4392F603371F2FEF2
+:10D6A00004924FCCEE76D775F1F7582BF4A3D0F354
+:10D6B0007A95DDC6A50D4CC77362830D7A11C7F14B
+:10D6C000E1990FBDF4771C04298076ABEEF61502C4
+:10D6D000C643BF0F0A15A19C6C5446DC2239B50124
+:10D6E000F443DB8DFE61E453B95EE328EAEDB94112
+:10D6F000A1A580AE0FA17EEDDC0622207EB7FBCD7A
+:10D70000D44FAD9C975BAAEC0733EB8F6D15D97B9B
+:10D710003FF30335E2BEB07A93DFCB123B6F585B29
+:10D7200085B69CB7DD6D2FEB3292EC978B949F35CD
+:10D7300015CE71E5E798F340C4B60CE7BD5C64FE16
+:10D740007183EB3F3BB81F34A93FF105BE0F2FF8A3
+:10D750007C4DCADF0D19BF1F5A8DF708AEDF250FAC
+:10D76000DF1ED4DAB1FEC843345DF942E7BC2B6258
+:10D77000F76DABFBF907E4EB71F844B96F5BB13BB4
+:10D78000EF5EB63F3F7EFFFCCC2926DCE7A4D653F4
+:10D790008EF0713F5221F0F3C0FF548FBFA3F1BE52
+:10D7A0006C71E2794DF5F79567EA73C1C9F953CF0A
+:10D7B0005AC69F0697113DFADF061F78391FF1CB35
+:10D7C00097F57B3AC01769F9DBD7EAA99DEAB0C0A3
+:10D7D0007E5F475E6CA4726250C7DADFDDA81F92DD
+:10D7E000E3F8A6FA777582876FA7F7604FA4276ED4
+:10D7F000AA489407EAF954E7A79217E7BE2479618B
+:10D80000ADBC303D7156E5575B4FB42AFDFF82F544
+:10D81000C44D9C8F29F202DA2377233ECF1329CE01
+:10D820002F180A533F82A2F714B48FD0742EEA3D0A
+:10D83000F86CE27A4F33E83D6ED47B4ED1FDA2E81E
+:10D840003DFDE91101AF5EE9E0F4D49FCE7067546D
+:10D85000EF0924D77B76573893EA3D9BF8FAA9E77E
+:10D86000F710C7A1CFEBBCE595A81F3A599CDF1F65
+:10D870000F3C41F9D666ADBC04E7B733A4A5BFDFC2
+:10D8800083766176AF883184FB6D5085C73BEB6A48
+:10D890008DC9F89D829FF74E4DEC9F82A32F56AE07
+:10D8A0007C36815C19D2C9B978AEEED89E2D761A35
+:10D8B000E7CB7F7720155F9CC9CFD9410B267EEF40
+:10D8C0008009EF1B50E43DDEFC4E71AB9FAD77B796
+:10D8D0005FA4F65F459E031E68C13459690EB0DF30
+:10D8E00093F353796FC5731C54BE07282ECE6DD6A3
+:10D8F0008B32C5076B04B48BF7CFB5B1F3F00DA332
+:10D90000142FD8791C5A6EF01D6A47453F14B6A7EC
+:10D91000C87B1F8FF320DC1E1E27EFD7E07AA6926C
+:10D92000F7CA7D03BEC3150FA2DD4D19974B4BF807
+:10D93000FA12EA4FEA6E17E938DE079C81B8208AAE
+:10D94000736E54CE89B178276B03F35B28712FFD7A
+:10D9500077B2B8979CC0BB54EF904442FD67A9CE04
+:10D96000F97F2B8AE347E938EDCE79F4DE0075FFC5
+:10D97000615C2D95D9717166461667D613A916514B
+:10D9800035DFAD1BA17AC3F9DEB77063F1D0CB32BE
+:10D990008D2F63EB43340C5FE17AE17A58795C6058
+:10D9A0002C5E8CAD9B0D701DF2E70FCF5C4AE9A099
+:10D9B000A73E93E92F75EFD275033AA0F33516D73A
+:10D9C00011FA7B4080EBE83D08EAF9803F8EEB16C8
+:10D9D000D1F1DBF87925657E92CCC760B2F988DD9C
+:10D9E0006FA127CAFD16F4BE8A081BF7B7F64FB918
+:10D9F00016D75D6D5F8D9E9F4B615FBDD87DFAC36D
+:10DA000002E7B87EF9E556767FE0987351AB585C33
+:10DA10008C727F2094B008D0EF26DE150319D64F04
+:10DA2000413C6DD3109CE7FFAD31533AB6EE15285B
+:10DA30009FBA453EAE2FC5FDE8377BA91F9784F5F9
+:10DA400068BF689CCBF0358665627D17AF7F4BD889
+:10DA50009030CFB73E6648889F729176AABF361243
+:10DA60007DEC3DE2FED36F9D46BF924BF59E68BEB6
+:10DA70006DC5F9C76B227053ABF9CD86D3A6E78E7F
+:10DA8000C7B57FA6323DEB4DF4057C9D7C9D9EE3A2
+:10DA9000E2F553F1AB0F371A9F3B0EFCF54F3AEF0F
+:10DAA000EF71DF133C24360BF4F3CBDF2CF5279119
+:10DAB000AB183E88F368F68E12933375BBD2E5DA65
+:10DAC000E7D1DDD2EE79D7C8FCE521CA17DB3DA44A
+:10DAD00006F15FBB87DD6F91312F42C6EB1F94BF0C
+:10DAE00002991F949792958B6B37A4A3ED6666B04D
+:10DAF000EFB17E6E059A1EA1B8CC3B6E7CA6C1C963
+:10DB0000EE8F51EAA52A176BCF43E36752F67BA34A
+:10DB100034BA4A771EED592EAC3DF5B8CD0E66FFEE
+:10DB200049F7407E1CDDA9EBBB3F693D360D96D61B
+:10DB300054CAEC8926C7FE08C62BDEF14B936CB4A1
+:10DB4000E1FBC4731C5BEF3D7B6239D0B989A44B08
+:10DB5000AD582F72F7BF629C7CDA1CBD1369B148C7
+:10DB6000DE2B233FDB564AC2B8CF76DCCBECABDBF7
+:10DB70000BF3E93C17B5771893C525F56CA49B2EDC
+:10DB80009A4E6B0845701FE736F90BC4B876F21051
+:10DB9000EFC7D1B5D26EAAF919D36E5348C676F342
+:10DBA0001A3CC5A233365F4ABEBA7D6B785D04D994
+:10DBB000FC1F274BAF629CC2594D3ABDCFA6F4194A
+:10DBC00091A64DB039511F0A0941F9BBC877169883
+:10DBD000E83DDB3B2607238390F6FFCA24237F74AE
+:10DBE0007FF2EEBFA3BFCD3024505C6B68D3BF8003
+:10DBF000F94BC4748980DEB7E37B81C820B4D37845
+:10DC0000B24C463FA7A13031BEEDE648BD88FCE5E9
+:10DC100066476608E779C7678C5FEED927ECC17B5A
+:10DC200015438E812D68177E77483882764AF2092F
+:10DC30008C67269447FE001BAE31527F8CF2A750B2
+:10DC400001ADBF87CFE7369C9F92D8F81B4B835717
+:10DC5000A39DA1716FD54C4D1CBD340EEDA4ED9B61
+:10DC60004AFD78E33DD9C1ED966918BF14471FA15D
+:10DC7000D09FE938A11F2EFC3DC59B23FF8FA66FC7
+:10DC8000DE9B914F79D5987E313B66E35E17B56395
+:10DC90002AFDD9736F684B2ECEE701E108EA1F1306
+:10DCA000F52BADD0C32E8650ADA7BA7F1BF8B99423
+:10DCB000CDF87BB36827C5DF9BBD8C1E77A07C7435
+:10DCC000738ADFD3DC399DE1FECD3CAE18C6A1C11D
+:10DCD00078171A331337AECD3CBD7BBA90D00FE521
+:10DCE000B9D9A4DC37C7D64F57EA4CD0E3764FE713
+:10DCF000F12FD0BE3727765F3CB6BF3107EDB6ECCB
+:10DD0000CF48825E19E6EF29B18D44A01D33E0298A
+:10DD100094EFA6D35B09E2FD36423C97805C321655
+:10DD20006A3F48F85D60CD497A5FFEFB1E76AF55CD
+:10DD30001A81FC52FE7D481B3D004C2D63EB996D12
+:10DD4000328DDF307B4940AEC27EA8EB05697C0492
+:10DD5000D05EE02A7B92EFF2F2286E51FEA8E5D366
+:10DD600091E9DC1FA0924F048D2CB352CB27858FF5
+:10DD7000A2A519F98A39209E437B8CB9E6BD8D286E
+:10DD800037CD644E4BFC7D6EB1738022BF2F42A90C
+:10DD90002FD3DFC93337333E689E734A409C05401A
+:10DDA000D383E73CCCF35E12B630DC4926E1EF3397
+:10DDB000D59C12F643BA6F2B71229E37D7BC24FC38
+:10DDC00014ED225719F9E168764E9AB218F4DFCFB4
+:10DDD00038357715B6779CE54F9E5743E33627CB0A
+:10DDE00089E79FCD5EF57D8E72829C2844F809FDFF
+:10DDF0000E7A6B6BE7417BFBBCC630E2FB1D735AAE
+:10DE00006BAF82EFEF850A1A4FECFB65FCFB0A7DD6
+:10DE100052A805F5A5B91DB568FFC33BA75879B64B
+:10DE20006F0A6B8EDD8D76A3423E7F63E421D23A8A
+:10DE3000ACC79FD2186E53F69392FFCE74660FF85C
+:10DE40000FBE5FAC1BD8FE7A1B64304BB37DF7FE70
+:10DE50007467C2FED871F9EA57906EB709666ACF47
+:10DE6000DCC0ED38A48ED96DB6F1FD6AE2FB55A990
+:10DE7000B78DEFA74E2131DEFF520FEBC7A51ED69F
+:10DE80008F5BF9BD6578EFE0EB58DEEEB7679A631C
+:10DE9000F9691B0ED0DF9BFE6FF1D576C0008000C4
+:10DEA000000000001F8B080000000000000BED7D4B
+:10DEB0007B7C54D5B5F03EF39EC94C721212924051
+:10DEC000126620C084063809939040C09310300A2F
+:10DED000DE3B2862783A11842841068B1A5A349323
+:10DEE000109EF2088A08147112C522ADDEE093225A
+:10DEF000DE3B04A568BD365A04B5A8812A2A524CD7
+:10DF0000B516FA7D58BFB5D63E2773CE9000DE7B9E
+:10DF1000FBFBDD3FBEF4670FEBEC7DF65E7BBDD710
+:10DF2000DAFB9CF9E107F8BB8631076372AB9331EA
+:10DF3000660B33BF0BAE62984D1E0A17C9CD580150
+:10DF4000633FA8FD2A9F622C97B12D6358C4E863F4
+:10DF50006CF30A166EF0006C160DB727C335D1208E
+:10DF60008524C63CFEC3EF0BF170DD97733BA3EB3A
+:10DF7000C8F926B8B2C6E4D0291BA3BF1FFA43FFD5
+:10DF800069138400CC9BEC657218C66519C9022B15
+:10DF90008ECE6795EC8CA54461C642041F3C698D0A
+:10DFA0001861BE8D30BF5580EB47D7A507E0F9CD8E
+:10DFB000E98174D189F885D3FC007BBC138E201EC7
+:10DFC000302E63E9085F1D5EEA3CEABCEBEA9A7218
+:10DFD0003E3333B6A16E2B5DB7D685E9BABD6E3739
+:10DFE0005D77D6B5E67C36508B271F4F48807B0384
+:10DFF000187349007B95F1E1BF84223D9C1ED0C37C
+:10E000007DABF570BF5A3DDC357E3F808DD1797791
+:10E01000D6ED53F08C103EDBEB8E10BCAEAE9DE027
+:10E02000AD75EF13ACF68F1D3716AF583C62D711A4
+:10E030008BB74AB778D6CE18E06502DE203FB77BB3
+:10E0400093046660EC0FC303932568175927634850
+:10E05000979C5347EE0711F33EB92C4A7FF82F7B6C
+:10E06000B31E76B265340FE10DF266BA3FFC461D71
+:10E07000B0D4E133B8D702CCC684E501208FCEB747
+:10E08000ECA1B5207F4E5FFE7CD3309093EA776D94
+:10E090001D200FEBAB5BEC3008F3DADEB7F941AED5
+:10E0A000B7FBCA12508E99C8E5C22125EBE6630C76
+:10E0B000F400FA392E24B3D088E8BA04A180D39DA5
+:10E0C00099D90F71D1F5CDB4CB77E2BA76D4B1D06E
+:10E0D00029A06F58B93E89D781487F7EDDA0DCDF5B
+:10E0E000AE5C5B94FB5B956BCE912909A87F3B15D9
+:10E0F000B849E9A7E2991934B08886DE9E90834535
+:10E1000034780F6C4AD2C12EA98FAE7F42517F5D09
+:10E110007BCE093E9F2A0FB1D7BED5FAF906ACD601
+:10E12000CF971ED0CF8774437BD1AF563F6FA2AC41
+:10E130009FB7A7F9368D611505A8D7C5605780B67A
+:10E14000F1252BDB85617805BD852BD3CA27E869CE
+:10E1500002D23F9DE8BF1DE9BF5EA5574932F18558
+:10E1600031C9AD5DDFFAF8F66AB40B4059C2939934
+:10E1700024F78D9759FF41A9A12104436DF019C8D7
+:10E18000CEAC934ED950CE9E2F3230A31BEF7339B5
+:10E190005A91FFA1DC01D7750F44188EEF8CBCC1DA
+:10E1A000DC30EE2FEA4072AC004B111600797AAAEF
+:10E1B000CE46B0CBD42AA0FD6235CCB30BF9648B2C
+:10E1C00008684F59106018D7E50C18A87DAB028B72
+:10E1D000410EEFE0FDB7D589348E2A7FE952935086
+:10E1E0000AF2DD974504502ED629D56EB5C1FD4102
+:10E1F0000C044603A7E3D2FBE0FFD56E8D009EA181
+:10E2000029E3DAADA8373E16463D7AFEE22F050631
+:10E21000F00699451AF2E07ED1BB215CEF4FDFB6E4
+:10E22000876C6951BA387D7ABD07FABF89F457E522
+:10E230005CEDF7BC64A8083B793F968C722036935E
+:10E24000BE2A704211874F4806E207D887F7701C34
+:10E2500006F603F9F6FC5BEF8AE81F7EAC7DE80466
+:10E260001B40FC6511D263679141467BE0644BA281
+:10E27000CF7908EF9338DF5E456E762BF8AB7AEBFB
+:10E2800062A2D101FD125907D9AB2F8605BE24FB2E
+:10E29000F5647B7B2EF025EF35D980F8FD61B87CE5
+:10E2A000462A403C67EAE892BD590F3BD94C9A5F39
+:10E2B000C553D5EB8C1A030B69D63378AB83853401
+:10E2C000CFF5999BA46BEFF2835E2E9FEB503E61DE
+:10E2D000BCB5DEB6D5FD017E02D86EA47E91EB06FC
+:10E2E000A09D6C37B2B52C2A2FB172FE0B94A7C13A
+:10E2F000F0DCC5DFDA517E1D414E2FC7A5F4B2E632
+:10E30000C1BC19E318F9DF9C9186700BAE23572628
+:10E310007EAE97FA87D70A28E79C9EEB91AF203F05
+:10E32000EB8B58D808F7AFB99840F295201948DE22
+:10E33000543AC373A9689F133783DF00BD6E55EE4F
+:10E34000FF6558202D0FF97811F02C44BFC1880FBC
+:10E350004FACE37201744F477CBC4F5A985B4777D0
+:10E360003DEC64006BE93E2642F2E50C723FD1C5FC
+:10E3700007D48C7CBACAD67C341FB1714198E40AA8
+:10E38000DA23D624B8A27FE885F65B7AFA5333DA2B
+:10E39000EB22BA3E5827D3352DD0C9024EFE1CCAF7
+:10E3A000A1DCB6ADD482FCC8609295460DCB480F77
+:10E3B000BB97897B803E0E2FD70B47096B89033CA7
+:10E3C000EDA650BD01ED4209D7FB746C07D89A2128
+:10E3D0003E61C0761B134CD8EE6712B68B4A7BB2F7
+:10E3E0005F69778AA526B41B45D00EF29AA88C1FC8
+:10E3F0005FA4B48BAD111ABF92B7C729CFF7AEE4B3
+:10E40000ED0925BCFFCE812C9C2BE0BC1022FA101C
+:10E410006E7F06E1643FCCA981E38B60CDC951B822
+:10E420007725636E4DFB639E63690D8CC6E3E3CE77
+:10E430008A8419CCB31C4901F4DF59C5E52574332E
+:10E440000BEF4259BD68E4FD6E9049AE9258BB9BFC
+:10E450000B7688F8B7F37B004621FC496544436797
+:10E4600047AD25648C477A0619C685AA9C7F3F4C28
+:10E47000BE15E56545D6876571308F03E83218D63D
+:10E48000ED3005BF403BC8B2991BE7B547BE6C886D
+:10E490008379ED452C0F2250E6B071BAB00C0BE138
+:10E4A00035FC4007AB7246C78DCFEE90659CDF14FC
+:10E4B0004CD3FA935502AB6C257FD3F1018EEFC894
+:10E4C00070F7C77558235F6E9B8F7CF40ECAB7C375
+:10E4D000FC0FE509A4CF2E030B60FF154BB7C8183E
+:10E4E000B7D84DC18302F26F26CB43FED86DFE83B1
+:10E4F00002E231056086FC9578FB240516DD1CAE32
+:10E50000E0FD6D1961793EC036392D681471DCD398
+:10E5100084873D83B9077B108FA7E539D06E0D380E
+:10E52000837689E815C1E7EFCA60ADE8DF40FEF801
+:10E5300078012E7F765B139F7F2EF74B7627E3EDD6
+:10E54000B2028B2287CB79FF53C3FD1B507FE3328E
+:10E550005A59696E943F19C3030FE1FD583EED34DB
+:10E560007750FCAEEACDCEFBC3E44F1D11456FB230
+:10E57000196604B08EA7486FACA037B88E58BDB1ED
+:10E58000A2DE245FAA37F66C2ED756D49BE49EF504
+:10E59000C68A7AE3EB596FACA837C957D69B553971
+:10E5A000A037A867D95C6F56E5801E78A27AA3C20F
+:10E5B000AADEA8B0AA372ADC254F39C134A746EE17
+:10E5C0005655192A296FBBF8D3B4294335F7334F71
+:10E5D000A723FD56A17E90BF7F666BC4D9739C9321
+:10E5E0001E00FBA5F5AF52E008F22751067BA6B549
+:10E5F000A3B9B20E063D24FFB33383DBF35519FDF7
+:10E6000013B4FA167B6D867888819F791CE220BC52
+:10E61000AE01BFC3AC3DF7772C0F07FD5CAFDF4702
+:10E62000B95D3F14F407E6898B2C3D680638AEC807
+:10E630009D8FF2700EF507F05D917398F4C66982B4
+:10E640007C16E3309BBFD4CCF948FAE1047D51EC51
+:10E6500021874577BD49D36E73C7E8752EE835CA63
+:10E66000ADA95DA7D7EB15BD762485037E4D7F153B
+:10E670008FB47C7E9D28F9CFA1BDD959DB6243BA06
+:10E680007866BADBCC30BF54C9DC06909B7E9358C9
+:10E690001BE2939CCB61BBBB89A11D017909C541DC
+:10E6A000EE086123F7AB8A1CA15CA01CAD8F9123FF
+:10E6B000158ECBE572A4C228776E4D7B17FE39ED1F
+:10E6C0003A395A51708CE8EBF4825D403F14799AE4
+:10E6D000E25787374C712BD07339F98908D727A7B0
+:10E6E0002D50AFC83FE9BDD32973D8AFB48BAD214E
+:10E6F000827379FBFAEF1F0EE1F3A181BC7D95B324
+:10E70000E33AD28FDA2421A4C1AB4FBE81ECE04EB4
+:10E71000D954D1DA8DBCBE99C7E3C47992DC2F1FDE
+:10E72000FA5D40FA1644E9EBA83584AC684F7C9654
+:10E730009368579AA5C0B7646796ACFC8B11E31930
+:10E740006F84ECCACA740BD1F5B137CC61B417969B
+:10E750003EAB65B4C72B05168C033BB8B2CF5A82CB
+:10E760002DFD4DC13810514BDF75BCBDCC46ED2B96
+:10E770005256F2F6394E82CDBD6D34DE8AA52C1C80
+:10E7800007F45BD1FBC3696877CD5916290ED66FA4
+:10E790004E3D41F08A2C1BC1ABEEBD37381FE8D08F
+:10E7A00098B892219DCC239904E9245B5DC77667D4
+:10E7B00043DC9065EA10D00E6685DA19D1DD0D7E56
+:10E7C00089F42D28239C952DBAD792BCB0DDB91AB7
+:10E7D000BDCD57E8674D76A7621CD5350E33913E07
+:10E7E00030673EF9D9C63A16CED6C4E925F9FD956B
+:10E7F000E7020CEDB759E4F208D7706E37F9FDC1A6
+:10E80000A253AB312F581734501CB3AE88FBED0D1B
+:10E810001146FEDC6BB31907635C0A0FAC05FA6D99
+:10E8200090F2DFF442FB5F771B24580B3BB84EE9B4
+:10E830000F7907C6AD7B769F3AE285FEAE621EB7C2
+:10E840006E90CA281E1C7E2191E22B5B4CDC9A053F
+:10E85000F7C3BDA2B074699C3A33BF209A8F372B9F
+:10E86000F1E4E30A0C71FC6DD89EDD28D6E36389E0
+:10E87000E54C40F99176F3B8B79BF1E65D6EBCBF0D
+:10E880000CF32F4079ECBF5A1494B8B406FB671D03
+:10E8900000FF360CAFAD32E6AFB1F90173F3B83318
+:10E8A000EBC06A3FD6A362F385AC034D321BD64D55
+:10E8B000DEA0C4A159073A647C2E0BE250A4C77BAA
+:10E8C00023785E6686DCED07ABAE3EF100E2A3E6A0
+:10E8D000C73DD9DBAEFC589CA2E4CFED15983F2490
+:10E8E0006624E7A3BCC5F667AC81F0D828C96BF3F2
+:10E8F000E91A588FD72657D1F503B0D9240A18A79B
+:10E900003509300EEA7FB181FCAD11E29CE7681E4B
+:10E910001FCD73CDC53A7132F45BEFBB5BBC2D5795
+:10E920003B7E3D8D7F6DBEBC05E9ABC6E9ACA483E3
+:10E93000E2BFF875F9BC7E17531788ADDFC55E9D41
+:10E940004B5A1D83A09745A91FA4551D7520FF7F15
+:10E95000961FD895AFADFBE59FE983FCBCE6E227A7
+:10E960005437B21618FC94CFA6F99464BAF5CD21A9
+:10E9700080927102A74FFAED4F52FED52467E7A3AC
+:10E980001C3B724C64173616B95B8C9EE87A20CF1C
+:10E990007D0EE7D970E2B88C7A6ACD3CAAE4B93F23
+:10E9A000327F848C285448F55BFA2BCD7C32B4003E
+:10E9B000ED3D180AAB44F5AE23A53C3FA4FC6FBD6A
+:10E9C000D412B91FF5F0D766370839B37EFFCB08EC
+:10E9D000E2BF43B6B5366072551296072563BE6C2A
+:10E9E00065A8B78E17DAD860E8FFF1EFED21F09156
+:10E9F000DCB9146BEA622639827EC33884D70F1CD7
+:10EA00004A3E75693D8DF343B435C9065EF7E07241
+:10EA1000A0D0DFB5A413C300763C9FDBF7AA84C067
+:10EA20007194237975733DC67D36C89790BE267064
+:10EA30003098FFC13F4C485731C0E7ED53CD4A51A4
+:10EA4000BE32655BA711D625CAEDF238CEA24E8C38
+:10EA50007B77E4073A90DEAE12C349F40F2E5F983D
+:10EA6000FC00CA21C54FCE290A3F61E8DE601F15B0
+:10EA70007ACACBF61EB4F8707E318FE617FDAC2A49
+:10EA8000372AF75509FE332497100053DDDC99DC53
+:10EA90006D7E1D95674E877839546A6251FD7CC240
+:10EAA00077DBF5E318E9CF77B8EE4416740CC0B8FD
+:10EAB000B0B891E4D268E0FAC39E3250BC292FABC3
+:10EAC00017B4781102009B92793DE57BC50F542560
+:10EAD000C8DFE378077D0D0D211FCA21AF13ACBF3E
+:10EAE000789EF47A4F898135B8F17E5902BB5C7CFF
+:10EAF000A8D8E12E18260C42FE9B0E7116E6C15BCB
+:10EB00006FDB9E7EB9B82FDDFBD08D68A740330E3A
+:10EB1000A2FC3940FEB04E9B1E6E09A1FCBD2D30FB
+:10EB200092AF6EEA0D29230A2EB5B740EA37BC40F2
+:10EB3000BB7E21B62907FA3E16AD17648E80756F2D
+:10EB4000DC71EAC8FD68D797B5FB87B8C91E678D29
+:10EB500048F9AFD76758895247DAADD40B2EA90BC5
+:10EB6000F07A62BA520F50E53AA1A495FC81536045
+:10EB70007E94B384928E10D64D1265310FF32B889C
+:10EB80002B4B292FF4011F011C3582F3EDEB7C7F09
+:10EB900001AE3B23C8E395AB952BC8334328F75808
+:10EBA000F243FAC6FB0C02C106D69990C6D85ADFCA
+:10EBB00093E20037E94319D223B3A6A91EED9428A6
+:10EBC0008784EEF42156FE49F3347216EB0740DEDB
+:10EBD0002622DE578B6FE278D326AC7B36A19E626D
+:10EBE000CDCED4B91AE14466E3F8B3CE7AB4D156A7
+:10EBF000454F76E6AC156420511F1B9777F88FF2CE
+:10EC0000F10D275227433AC1FA3979DCAFCE337B75
+:10EC1000048FC36F55E8CA9243E9C8C7FF182E2F67
+:10EC2000473C63EB95EBA46F6C5A395E171F56EAAD
+:10EC3000C5921BF7C35806F7570B461874FB62B111
+:10EC4000EB3A28BD6BC37AF07AB8627DD86B3B6231
+:10EC500043FBB05EBABC9E3950CF4644E1B54B2D64
+:10EC600095B82FB6B1A4C5A6CD4B1E50D633519240
+:10EC70009712BD95FD2DA3254CFB2EAA7D8EC56B4D
+:10EC8000A32954F122FA23898531EE769628FE33A2
+:10EC9000469E41EF02281F0E9B521FAAE679AEA5A1
+:10ECA0004BAE5923BA82BE6ED68C7E6DFD08D5DE82
+:10ECB00004D6E373D61AB0D386A85D8C37852316A5
+:10ECC0000F421D32DA1DB4D3E85FE28BB89D4E547B
+:10ECD000F8EF1F117804D7E392543BDDC1B8FD5320
+:10ECE000E432AD073B1DBA929D76F37AB0E2BFBA2B
+:10ECF000F02A0F33B4C3EABA329784EDA88F7D416E
+:10ED0000FED06FA4B1A344CFA622C326B4CF1976F8
+:10ED1000C6EB40C5207758170679ED0FCF9EFFE868
+:10ED2000731BEACF7627ABD0CADFB38AFCFD9B2AE0
+:10ED30007F22C89F8BE4EFF723BAA997AF03790925
+:10ED4000382F95BFD8F5C5DAFB57BAE82FBF82F444
+:10ED500053F72DD679957D0B5F9B0DE56E9D97EF53
+:10ED6000575CB5FC2D7490FCED607C5D0E07CF7791
+:10ED7000DF54E66B57D6D7AEE8C37A942F8C3F505A
+:10ED8000BE84E83E5C37F2D58A7842FEF62ED26128
+:10ED9000BD8FE76F2A7FAE64371C417610F393A8CE
+:10EDA0009D6D12B47AEB50ECAD6A5F5D25DCBE8AD6
+:10EDB0007213D5915CF780FD05F88C82B7E8150FCA
+:10EDC000A23D0E8F087C364213FFB97C111AF7C79B
+:10EDD000DADF34B4BF28DFBE86FAB2E4A8FD8D9531
+:10EDE00077885342182FF691B9BC81FC7F8774C98C
+:10EDF0000C84658BBB1BF957ED726853E98FB4CB5C
+:10EE0000FFC0755DED3AD4B8E4E5E17E8BAF80F4E8
+:10EE100096FC1FD6FF7D1AB955FD63EC38EB2C929A
+:10EE20009BD76D42DDC6E1F19011A0DD10E50EA289
+:10EE3000475F851E2A3F8D3E7F0ACE135FC4E9AF30
+:10EE4000AEBF1B3D60B266DD19BE2E3DC840BCE3BF
+:10EE50002546F580F81A875A0FF0D0FDB921AA0788
+:10EE6000C0F83FCABF3A8B9A0413CD1B34203D54DF
+:10EE70007CD57E465F60188EEFCC5B62C0753DA18D
+:10EE8000AC2B63877BFA530CD711A1FD43B69DC70A
+:10EE900071981F4DD6D4EDA6FA0C6A3EE5C371BA3F
+:10EEA000E2BEED6ADC7709DF75EB2FF1A9F1B35C07
+:10EEB00082F47BEAA295EC55B3C4F7539D8D90DFA5
+:10EEC000C677BB0F5686F3A9F1D536751F55912B22
+:10EED0005711A3FABBBB5A7CC7EB8EEE93411E3D84
+:10EEE00011E7C99EDBDE9403F7DD219E4743BC3565
+:10EEF000C97715F1966919DFE78B8DBB5C8D8ADDCB
+:10EF0000F0E9F3BA835BFB7F68055635973337DA50
+:10EF1000B5156B7AAFCD01FCE2B71A18D6F1132301
+:10EF20006BC8EE25361AC276DC876AEC4FFEB62730
+:10EF3000FE6E54EA915BB11E69453FD529537DB001
+:10EF400084D7CFE36D8CD781655E1F8C7786381CA4
+:10EF500050DAC5260ECFE5EDEB62EA99CEF276A245
+:10EF6000BF534E8A1821271721DE66DAF314EB0C03
+:10EF700027CD14178779FC18804C4EB77F9FA48348
+:10EF8000AD5EFF1137CC6B56E46EB573AE1BF3C7A5
+:10EF9000FF1816B81FF967CF6661ACCFDF15626145
+:10EFA000D4AF8519610C97D84633AF578E37962466
+:10EFB0009C223BCBFDA74BE063AFF7713B6E75B76F
+:10EFC000CB189F5A434C0AE37C1961CA5F17C233BE
+:10EFD000BDA0CB72A057B919E7F3AF41FEC6E576E5
+:10EFE0005890DFEAF8B1F47DC8A7C65D8ADF350521
+:10EFF000DCFEA13DEBD7C561FECDB80EC413EBB866
+:10F00000AB99DE9FAAD76CA974AB8FF677FD47AE9C
+:10F01000C1BADC50E646F95C71719C0DFDE54A977A
+:10F0200045D9177AAECFC1EC9EF55ABDAE81754D6C
+:10F03000E2E72DD82458DF0A675325E6C7FD0A58B2
+:10F04000A8BC04F000BF86F05EDFA6E9C9B08ED58B
+:10F05000C8933E8C0D7A71E3F610E0B902E1515C81
+:10F060001D915F6BECBC9D85364EBF9AE719E3F5A9
+:10F070008C2D96C08B649FB26DB42F125FD4694102
+:10F08000FB740EE9ABF4437BB166D099348C07FB7B
+:10F0900015E8E350D3F0C0AB3E8DBD8D2FE2FB2AC7
+:10F0A000CEBC27CB308E5BC512448CAF87D8F879A5
+:10F0B000AF214ABC3CC4C4616301DF87EA55C0E5A7
+:10F0C000E1131F871DDEF074AA3B82E5C6E7F798BF
+:10F0D000F9BE622847D93F9119C989AB466C469B56
+:10F0E000D8283E44797EDFF13CCF795FB14B626D29
+:10F0F00024847EFBEBFCC0BB5A3CFBD6F07C3C2A54
+:10F100000F4A7D2703EC37DAE9E1817E05E80FB28B
+:10F11000B91D57D7D597B53313D5B95B054F7234A1
+:10F12000FF073F4EE327FA583DCA7FDF1AEE47DE5E
+:10F13000455D4DC1FE9D95885F3F5C0FC6C366BEB1
+:10F14000DFA3AE27563E1E7F604F1F7C7E558C3C52
+:10F150007EABACEB6B45CE9DB97CFFDAB50CF01CF9
+:10F1600086FE3BF035F253F5E3B0A47AA4CF209F9E
+:10F17000FF2FC4672F3B6875235E228DB3CA14B47A
+:10F1800061BD169EFB1BE22F2E6B97D1DFC4E5728B
+:10F190003F05ED155237F9C3BB0A1ED992FC7F7D9E
+:10F1A0001487A8F92AAF833B253EFF205F40203A11
+:10F1B00016713BADD2799E24BF8BF8A8F4B994DFC9
+:10F1C0007CBF2C748FCA6FCE7F5790C751F6EC8EE0
+:10F1D0007AB4CB09459CDF09059C1E3F19E1E77C09
+:10F1E00028E7F8ABE31F57F8E39223A5B8BEF8DA97
+:10F1F0004ED9E08EB68B329F3F333A3FC97F62399A
+:10F20000AF1F6554F379E37299807A90A1E8C1DB6E
+:10F21000F9FA753476CDD34976D0911B217AAE3484
+:10F2200007D290CEAA9D98FBE2BF4CAF073B518618
+:10F230007206CF2FF0B6537F88FF48FFFA1530359E
+:10F24000BE53F5740897C7EEF534963FAA9EDAFBD5
+:10F25000B120CACF40D624E13A9A320A7BA1DD52CE
+:10F26000FB5D5760A179D6247654A21D5B5376F7D7
+:10F27000FB48D70DBB998741BF55F7B337AA606DDF
+:10F28000096CA8D8807A1CB1937F19522236A3BF8B
+:10F290001BB2BBC3960DFD871CE9C5703F2121B28F
+:10F2A000F4FD04EC5F34C86DA7FDF41FE81CC51025
+:10F2B000FC371070C3FD1CDF358A1F54F148F0760F
+:10F2C000129D134AA442A473A0C0AD8BE3127677BB
+:10F2D000861CC9B81F2B0D423AAD4964D721BF36F1
+:10F2E000D45BE416B8BF26CB6FC0B86463B181CEDF
+:10F2F000871E1AF3541FCC87F70CBC9886F9475326
+:10F30000D137B4DFF44D06AC8BF6A1FF4EEBB4EE73
+:10F3100016FB239E1BBFE7F664E3D3AC199F57F19E
+:10F32000B62A78ABF80E892C8DA0BF1B92E1DE8B3C
+:10F33000FBE81BEFE77E6888375C86F80FD9CDF1D4
+:10F3400057F11E92116E133478F7C37569ECA72339
+:10F35000DBA0F3B73DF99F7952697581C6AF5D298E
+:10F360006E9C533B8EFD09F2AA972C9D877E403BF5
+:10F37000B345A0FCF1E5CD7913508F6EFF02640315
+:10F380007ACF593AF1E14F7BC1909F72FD9AB32336
+:10F390005142FCEF6A0F4E407AB0209306827D4BBB
+:10F3A000357AF675C038A94FBC232D87253CD2C6C7
+:10F3B0006E4579396B0EE661481E9AE5CCA3F313CE
+:10F3C0004ED9ED04BA55212A6E7C2E7102EE87A625
+:10F3D000DE64911AA59EF1AE9AE92EC27A5D55EBD4
+:10F3E000D22A9A57849405E28D2A93B812619BDB46
+:10F3F0009D580F706143B019E1CE4496D49247FBFB
+:10F40000E3877F0EE3DF5E9D29523D47896BAA0E9D
+:10F41000BCF177DCC7B85DF65B90FF3FD96DD1D109
+:10F420007968AB1E1EBE4F0FE745F4F088237A18AB
+:10F43000D788F3D4B2E027F723BE6F19C94EBDF2C7
+:10F44000FDF316B4EF9D552C88F8BD34047255DADF
+:10F45000CF0D67D1F94F3FF01CDACFEC71B560FCEE
+:10F460007CAEAE7D6B39C4016D5F1818EED32ED81B
+:10F47000E36AC67AE94BFFF8D386D138CE337152AE
+:10F480000BD071DC825F3FBB14E0AF9E8E4BC4BAE1
+:10F49000F5996D2FEF443A9C7966301380EE5F1931
+:10F4A000021FBF8D7C30B8D82EA0C7C10FF79FDEDA
+:10F4B0000EF09DCFC6E561FFAF9E797910D627EE9D
+:10F4C000FCD5AB5968BFCEECF95521C17B9E1E8699
+:10F4D000D7334FFF7210DEFF0A8514E5658FB5192B
+:10F4E000F9B9E0D7F693BD86F5CCB7AB1D7781812E
+:10F4F000EB17C3713D38EEAAF65EC0EF05BB5D2188
+:10F50000BCAAE3DDB9FBC1BF68E1D8EB9DBB2F8F7F
+:10F51000CF9DBBF9B8A7CD610BAD43608B7741F2AE
+:10F52000BBE85CE5F589C3703EAB8E8F83B7EAF923
+:10F530009A13D6C3FB21ED781BC7D9DCDFB30BE4EC
+:10F54000EB1CEB3CBD01E164A1FFAE6EE4F91325B9
+:10F550008E59B44F3FCF7E53F77AFD9962A7BDCC49
+:10F56000128DD3717FC10A76BB1BBBFE95E2E7F615
+:10F57000ECE9EA6FFC811FBC636E88AF17287AF74D
+:10F580004AD73920B6A42FC8EA02D4CDFED1FB0B4E
+:10F5900098669D30DFB7B6F8163101EC9982CF79C5
+:10F5A00033D7EF3375F2C39F827C9EAE93E572CD65
+:10F5B0003EDEFC1D552BD3819F357B07E669ED5D53
+:10F5C000CDD34F1866C0FDB3101719803E67761F64
+:10F5D000DA82E7F4CFB49A19EE43D73C7DA8379E80
+:10F5E0003738DBFA7A3CF69BBFD543FEBB6BDCAD0C
+:10F5F000E3E5724DBEF263F5F6E5226EEF16B49ABE
+:10F60000C3B887BBA0F5BD097D51EEB60AD24098BC
+:10F61000A7D01430527EE993CD21DA07FC8FC37D49
+:10F62000A07DD1AB058598DFAE35F86FBA01F568DE
+:10F6300027D7E7178FDE6644B99D3F94198C204782
+:10F640006DDE872CA7D03F17723EAF9DEAACC6FD9A
+:10F65000B9F827ABC6917C437C30302FBA9E421359
+:10F660007BDF002915939B6647A0FD0B43BCB416B6
+:10F67000E6FFD2C5F521F48C91ECF2C88FFE6ABC8E
+:10F6800088FABFCB48E716E76FD5CB4FF50133C5F6
+:10F69000A52FFDE3DBA9A3D02E341B3D2D8CEA4B17
+:10F6A000166D1C5B6DC4B32040EF66D76A7C17E013
+:10F6B0004C4A384BCCC5E79EF898ECE6D356438BC2
+:10F6C000C6FF57EFFEEDDF719FF88EB07EBE58F992
+:10F6D00018AFAC17FEBC5A398BED8796CE54186D17
+:10F6E000AFA905FFA2A9EFD57CDA64C1FCF88E4969
+:10F6F00096CBCEF7ED899707B90D24AFB47F11DA19
+:10F700006BA4BAFB577F7EE929DACF33B152A52E1D
+:10F710002BD860BE33F8AF01E0B7D2FEB0B5BC174E
+:10F7200002AD83D09E7E6561656BF3783F0678DF1E
+:10F73000897A80F57C6384EC2B7BDEC830AFDECF2A
+:10F7400022F1745EA4D56820BBF7C5BABF609C7572
+:10F75000560C6F7816EE9F85C584C4E83AEA5B0FB5
+:10F76000C5637CB1A0B55799F132F66AFF33768351
+:10F7700001F870F68BA7E2BAABC3DFF9455299A541
+:10F780001BBBA4FAF193F84F90D38585727521FACB
+:10F79000FFC65E9487A7F60AE605BB194F7D2EC902
+:10F7A000F6F02F90EE554A5DED21F0D36EEEA7A551
+:10F7B0005D9E4B9F5B52C8EDCA8345FEFB701E9752
+:10F7C0002FE4C17820296093501EFF6494EE1581C8
+:10F7D000BEB7B380850E4C34A6101EF319F09336D5
+:10F7E000DEA509A857774E029D003D9933A589E211
+:10F7F00087CD8B99642C02D814263F3E07228A8736
+:10F8000045AC435899ACD1F3799B01D6AE7F87A61E
+:10F810001DECD69D4FEADB17B008CD5BF3EB1FACB8
+:10F82000DA71BACED933D98271F3770AFD1E2C92E0
+:10F830009B0AE1BE70A38DFCDB4F9F11685F32D93C
+:10F84000D24A7876029E2D80D774256EFACCE8A72E
+:10F85000F52E5A5A25CF05F8EBDA39F2DC5E8C4AE0
+:10F860003BA4E7AD3C9E5A50DE7A98EC0B139F9B6D
+:10F870009106F8D8FC3C6E7233F15A9877D4AF27D2
+:10F88000D3BA59351327F605B87A32D16954902284
+:10F890001C365DE1133BCAF9FA21D6C0500EB7F110
+:10F8A000F1E7B310D1FB0ED64EEB7DA63089F8748C
+:10F8B000E4203F4FF4EDBE44AAB7AB7CFC96490967
+:10F8C000A8EFA90E88EF92BA892363E85CBD23866E
+:10F8D000EE5A3AF747FAEAF974D70B40EF6EE4F4C0
+:10F8E00011C5AF7CCC645D7D523D7FF048BD40EDDD
+:10F8F0008FDC6CA192FB9669F39EC07AD146A00181
+:10F900003F2FC8F763D7629CC0EB1A111BCCE318DA
+:10F91000D105537B618302876E9F712103DF03E36F
+:10F92000EF5FA9F36D996C61111E6FD931DE6A2901
+:10F930000EBC83F23CC7E83F6C003ACD35C859266F
+:10F9400094DF5A4EEF47F38339C16EFCB2BAAE2D45
+:10F9500042BB8CF960E87E81FC41DC81BD11E4F79B
+:10F96000C20AB04E6037526E59574AE7CDF3DD06F2
+:10F97000ACB77DA9D8C904253EDE266C4AC7F66D12
+:10F98000E96E6139ACD5F78240EF9D6D4C6C9FD02C
+:10F9900017EE77BEC3C6A01D4F8D0B36A35D4BBDC2
+:10F9A000D59BBF1CE3C24237CF8B47341DC4E73B16
+:10F9B00017BB458C27D31A429EBB7371FC603DC9AF
+:10F9C000ED6446F7536E59568FFD1EECC392108FAF
+:10F9D00034562F60BF95299CEE2BAB58259E7F3166
+:10F9E00061E504FA65548A423DC867AA492639B2DE
+:10F9F00031712F60CA1E89E770E75296D802F8A6C7
+:10FA0000188CB74E46BEE5F3F5242D13E41652824A
+:10FA10004D845FAA95550849FC3EAE0B5826EFA5CC
+:10FA2000F630D121755C300FF1481DC0AF39B623D7
+:10FA30004E8C9F96082C887EF0AD64353E8E3891B2
+:10FA40005F5F9BE5D41168A7DE31935D4ECED2B7E0
+:10FA5000F7CFAE48C03AC35FA5715467DD67967FA4
+:10FA60004FF479C728B47463D7FA8CE4F5A445172A
+:10FA7000FAEACE6F2DAAFC1BE5058B2E64E9EE9FFA
+:10FA8000853C2FACC94B6BAADB2660BF85AC7D25BE
+:10FA9000CAD9C256230B6BF4619F1DE842EBE5798E
+:10FAA000C0A9B706EACE2DA9F2BFE88291F6B96ADD
+:10FAB00095F71EA3F35B74FB5F8B2EF4D29D7B88BE
+:10FAC000F6EBADBF7F41D0C3FBCE2BFD4C749F1531
+:10FAD00075C4A3FDFBD276682BE67777D87FB71580
+:10FAE000EDCC68A381F01DDD8FEFE775AE31366395
+:10FAF0003C30DA28A8700BC25F9A415E685DEE78F0
+:10FB00003C273509FC2ADAC15318C762DD411A10B7
+:10FB10003FC487F1307B0EE5E52CBE6704743BA53E
+:10FB2000E4AFCCE48EBF51537755EFF73176C4D3B1
+:10FB300079ED57B89F55DBCFB93BE293347A784ED5
+:10FB4000EC88477A9FAB54F53962427E6F970E9AE4
+:10FB5000DC00D7480727308D9C45F913A77B8FA57C
+:10FB6000F7F2F68801E43830F2DF7E919B03A2D0F1
+:10FB7000A6DA93BDBF904BA0DD68D0D9173CA3AFE8
+:10FB8000D655D1CC3D6250CF333FF78BF20C2DCC04
+:10FB9000FB479F7F7E06D65D7DB9FCF93B47BEF0F3
+:10FBA000C70693C61F993AB3E8BC8E0ADB6260278A
+:10FBB000C04335B018D39E1CD39E160367F0FEB326
+:10FBC000133A0A300FBE67E4BE1926D0EFD97D3B49
+:10FBD000EE11005EB77CFF8CF262F4EBD204B467E6
+:10FBE0008BF609224F1B38FDEE92988C71AC53EACC
+:10FBF000B0CCC9453A4887311EAA817E829BD70383
+:10FC0000D1EE2D6A85E7DC9AE75A057AAEA6F5248F
+:10FC10003DD7E3F85E03D987B5DE53D46F61ED9F1E
+:10FC20002D1887ADAE69F0A37F53F7CB4D2C28F785
+:10FC300005B9B86BDF64AADFFD71E881F7F0B84B56
+:10FC4000DC92BFD4631DEDA3859F17E0737FC4A131
+:10FC50008BD13E8773F0F999D5B7E5E0FDA4DCF6CA
+:10FC6000F7A642BF8FCD1D8F61FDFBD997DF9A614B
+:10FC700002BBF6B1AB235300FFDEFAF2710EA7749C
+:10FC80003C8674C9D9F73E87333B32315F79F1E561
+:10FC9000E49948B78F07763C86F0B997CFF3F6A181
+:10FCA0001D99B85F3A2274614639C0BB446E0F7724
+:10FCB0001A5835DAD53FC6F8BD2715BBF3C4F5F29F
+:10FCC000E323316EABE1FE66F6F6F669A82FB30DBD
+:10FCD0004C0C815CEE3AFBA767305FDF551BC75ABF
+:10FCE000B858F9317E4EE5220C7EA289EC7AA7073E
+:10FCF000EC3CF477813DA4FC659889EA5C2A7DD5CB
+:10FD00007963FDC8BC427948514AF43A723CBF0E4F
+:10FD100029722BF545880B61BC99339D12D6059944
+:10FD2000A9A300E56AA39DAF0FF481F8E644FE01A4
+:10FD30003F5E19C9FDDB2B23799EB8A1703C8DF77E
+:10FD4000D38FAEDD66E3F9258F5F169A297ED93C05
+:10FD5000594EC77AC7E6C9BD0DB83FFFD23FF8FB81
+:10FD6000359D9BECF41ED774B42BBDD02EC8E9F49E
+:10FD70003EE24D169D5DD87CC7B874B46BB54C4E51
+:10FD8000A773217EDE7E45BBB6D0ACB76B0BCD3101
+:10FD900076AD3565B2E67CFD0C33DFBF9FD16C08D4
+:10FDA0000D1CAEB98FFBFA647F5A53B4F6EC4AF7D8
+:10FDB0001FC997D305F2CF16CAB75297B7121EA91B
+:10FDC0008F7A92902F780804E3EB2D9B06B720DD05
+:10FDD0005B8A6F1C525480747ACA7E5B6E54BE8FED
+:10FDE0005F2F7F8EF233DDC8EB01AA1CE11FEE1FEF
+:10FDF000CC793895F6618714F1F81DE29B611827DC
+:10FE00003E50ACF299119F861489D43EDB1A31A37F
+:10FE1000BEFC7F7EFDD3F89559F4DFE0D7C2DACF80
+:10FE2000AFCA2EAA7ABA45889853917FAFF2F814D8
+:10FE3000EFE37B23C70A035291C62ECCFEF9423A68
+:10FE40002FA9E21377DFCB15B700F8F1F433BB9E8F
+:10FE500082E73FFE999DF2F5D8F8372EB7E399F582
+:10FE6000980732978879F8C7968EA112C6F986C08E
+:10FE7000132FE3BC7D8C22D84288FB99B2DFDA4194
+:10FE8000EBFCA438D01BE3A05545461A07E42D5DD2
+:10FE9000A93F85F07D92D064CBE5E5ED556318F977
+:10FEA0006057E46D735E78DB3CEC7773AE1472A33D
+:10FEB000FC81DC601C3183BF1FB779A02144F9E6C7
+:10FEC000344718F72D367BB85C6F9EE6A57367B58F
+:10FED000881FE561069AB71B79E4F30E34D0BC5D48
+:10FEE00072F92AC4471E8D5CBE0AF191472B979D7B
+:10FEF000F1DAF3145F2B75BEAFC32097099AFB8C20
+:10FF0000C74D1007C46BDFEBB9D2FDDECB412E7DB0
+:10FF100051B954E5F0D387408E682F5D1E847AB1C5
+:10FF2000A488DB63D55E3F501C588CF2148DC7F952
+:10FF30007AE66C1C4ACFAD7271FBBE43886CC3FB82
+:10FF4000069B9884F575C893EF41B969888BB720F3
+:10FF50003D3E0739EE057E671E63F70A9ABC292EDF
+:10FF6000374079ECEC20E4F7E027E783FB1B8BEFCD
+:10FF7000AF86F4F9236396286CBC14C63A973E7F8B
+:10FF8000FF8755DF3FA4F829EEE7B60A8BB7215E5D
+:10FF90005BD39988F9D4ECDCCE4C94ABDB308F0684
+:10FFA000D4BE3DEB3008600F4E29FB6247DE1A419C
+:10FFB000FBFA6A5EFCB042A723070B13B07EA3DEF8
+:10FFC0005F64EBA0F502953A57C1FA16C5770C426B
+:10FFD000BD043BC6F723422E7A4F53AD1F9C5E6390
+:10FFE000A4BC9B21897D18770A742EBCC67691EF3C
+:10FFF0005754B1A015BF4331A87302DAC1ED652C87
+:020000024000BC
+:1000000088FE9E5E28C63A143EE9A17DBD1C6DFEA9
+:10001000BAC8D19145716F4A27D5AFCF55C1D458D1
+:10002000BF0E7D5FC7BAA933619D594BBF7328E2EC
+:10003000F93DDB5BD0CF4138EEA93491EA3420E7BB
+:10004000DC0E5F21FEEF8AE395F8FF54586F77AF1F
+:1000500022EE1F2452DC6FCFD7FA8BD8EB5D0CDF7A
+:100060000DA2EB6B46AC9BB28EC2EEBE177197E150
+:10007000D4A0BBBBC9DBBBDAB77EFE3DD2EBAE176B
+:1000800062EA1B31F2571385851F04E48BA6DD134A
+:1000900095BF454A5D88F2035C47390B0F1430DE8B
+:1000A000E5705C453B9D7F4969EB9880F45CF40505
+:1000B0003FD702BE301FEBCEA30E341FC2F839A9C2
+:1000C000BC3D13C5669152178D8DDF8A0F6C32F2DD
+:1000D000BCA6F527E88FCA2CCC8D7C2A4BE2EFE931
+:1000E000963A72723F836BDB294FAE19FAFD9F225D
+:1000F000133D3FC12A9F457DEF693FF882E26FCAF9
+:100100003EB607308E2B73D8C94E6F7C68708B95C6
+:10011000D6D94AF674EE164F12CAF185221EBFB622
+:1001200014FB2F1491FE4985E86F3E2FE2E706CAC3
+:100130002CEE6C94D3571C8F96A3DC78C00E18D28B
+:10014000905CA5D9C920DF65694CF96B6A0C42FB4C
+:100150006498603BD8896D65ED69189F6E2BB44833
+:10016000CB618A1B9994897A36510837A2DD36B162
+:100170001D4B70BC8A6C978478BC232466629D9367
+:10018000DD614E3C6DA3AD5876B9733538C2695503
+:100190001FA0F316477B1A8EB7C502A8611D58E24F
+:1001A000701BCCC5EBC21C9E64E370DBB40FD39014
+:1001B0000E6D407301E36D036FA75A7D3AF6BBAF36
+:1001C00019E17502138DE9D176210DDF35C2F626CE
+:1001D000B24F2C9189A8FF4C329FEDD0D431531DE2
+:1001E000ED6E6C37C07C587F592FB08840729E915D
+:1001F00078FA27D1F5C52975DB078BFCDE62A03FB5
+:100200006E53D9492F0263A993E924D99979F7311B
+:1002100011E5235A270CF3FA6C6E32AFCFC6D8D74C
+:1002200073580483A673CF09618C6BB0EEAFB7BF70
+:1002300011B2EB0B819F789E94ED8EB5E7ED34EF14
+:1002400022481CB68B68F7F4CF2FDAD77D3DF61520
+:10025000ACEBE547FD93C62F113EB757F7A1FDD094
+:100260000E0C42E8BC343F478AF5276EB7E4F4DB56
+:10027000918F77F4CFC773B571261E4FDDDE34B88A
+:10028000A55EF183E83F1F89E77E4D95D796E2B2E0
+:100290009B917E334795F98B314FC6E2C8D59CAB15
+:1002A00055FA61DDEA7275F6514AFDF6EE3F83DFDD
+:1002B000017FBF5F399756F1C6C054F43B770BEE10
+:1002C00054F42FB715AB7E6790EEFE696380EACCDD
+:1002D00051FE4538FF143EDC897CA07DEDC04AE22A
+:1002E0004B35E7774D39F7BF2CC8C489C59CCFDAA9
+:1002F000EF4F205FB530F2D1DD0D1FEF423E4A9C3B
+:100300008F6E3DDF488E1789305F1EE7ABAE7D33C1
+:10031000A74F15DA454D1D2AB1B1D948FBDC0A7D3E
+:1003200012F265CF0AF42B6F98691FFB336CA27829
+:10033000582EC4B8E9C1A2B2E9C81F07FA2778EE5F
+:1003400053C8A7512E3626B25B6F443F58C7647C12
+:100350003F15F85FD8DD7773D6EEB757A33C6D280D
+:1003600036E8CE8BC8C56682A95E8C71DD1A2BC5B6
+:100370007585FDD5BA9795E2B8B956E5BD8E07F9F2
+:10038000BEF45D539D011CEF9452CFDE5ECCEDE0D8
+:10039000F6620BF14F85D5F5C1F8249F8E11FCAAAA
+:1003A000CE1FEEEAC7EBA4CC14A0F740B698C3F674
+:1003B000DB3D183FF969DF4E959F2D16F7EF9FC57E
+:1003C000FCA221C18DE74955393A726400C52F73EB
+:1003D000157BF0EBE224C2E31BE6A6B805E489DA5C
+:1003E00055B82BCEFDC210EE3EEFBA9BEA949DFFAE
+:1003F0006994A8DE80352A58FFFE2FFAD0795B88F1
+:1004000007E83DEACEBDF6B0126FCA187FEE7F61F5
+:1004100030C537D138D815E67170601BEA6568EFD2
+:10042000409E7FB0F0D34F21FE07D225D4D3D3789E
+:10043000BEC14CFBDFDC86EE8BA3F8BBB6A3390E46
+:10044000DFC3FA5A60CFA19F54E9B65F897B4F336F
+:100450001EDF87BE30B4D0B91253F8273769F8BF12
+:100460001FE404FBED67917994BFB6DA7579681FD4
+:100470002BDC473A3C0FF73575E157CCFC7E68AF73
+:100480005DD0DE7FC912798AC6798EDF7F5D0CBCB4
+:100490005FAC91A79AF8C8A044E7D5D0F79B78A4A1
+:1004A00047A7C0DA713F09E92B103D3215FA821DCA
+:1004B000E3F248FA00F124ADF3F49786162BCF7FD0
+:1004C000B9BCFE4608F338AC73E552C46BE97071F1
+:1004D00017D9814E2FD20BF845DF216B38E3E0FCB2
+:1004E0007B4AA07874BFA9E9F063D85FB6499897B2
+:1004F000ED57F21062756F8AE3E94FA5F316339753
+:10050000FF10CC8FEB7EC922537D2AB4D6DA4B4B39
+:100510009F45ABAD272FB7CFB9E8CC6D93BA8B4FC2
+:10052000BBDAAB2FCEC6F338B1E722CE557F938529
+:10053000F13BEE3B318D9FBCE479DB590BBE4F683C
+:100540003BC83AAD683F923B7B5FEE3B628BBE5847
+:10055000BB18F18D9D8FF2A742F25FE46C17C59C2A
+:10056000BB605AD878299C314A50F617F5F7B3B0DA
+:10057000065C80F4D58FF7A9D93F01CF4974BE2816
+:1005800010BF4F9BC32396C2FDED058181A352147A
+:1005900066407BF5570E9ECF819C63FCCC9AF8FE9B
+:1005A000EAA7667936DA95C4F28845FB9EF2E851EF
+:1005B000DC9FCCB1F2F37DE02F2C5AFBA8B6179646
+:1005C000E9ED927A1D358ADB27573BF7C7F7B0274D
+:1005D0008CDA3C76D4286E4F478F72F3EFAB7DC137
+:1005E000EBC3FD96F9AD920FEBBD55B47FD76F19F4
+:1005F0003FAFF8A93940F9D3A78221F81CC655EBC3
+:10060000F8398C79BF1248EE5FDE5D6A7441FB9D5C
+:100610003B0409CFCD8D52E2E979E0FFB4F927AE72
+:1006200083E8817E0FC619D5EAD9D701F0A817044F
+:100630007A8FBFC6D46ED9067046C01934A621BDC4
+:100640000387B19E0089D5DDABD2A3F6788EB523A2
+:1006500044F5A95F09746E7E9E8935C683E9BC5353
+:100660000ED33E49ECF90AA63DFF80F2B85B2F8F0E
+:10067000E81FF5FBF3FFB0EAE5247455F180EAFFCB
+:100680006E1FC5EDB81A07C4C6059087CF1BC5F904
+:10069000C7EDC15E817FF72A363E53FCB0EACFE753
+:1006A0002BFEFCB491C713F3AC9BE8FAB3511EC206
+:1006B000EF4ED6A1ECD7775AD01FF5C4FF9F29F291
+:1006C000F373E47F4A94FF35CB222BE389DE81E785
+:1006D00069BF7B198BB886217D835588571F881782
+:1006E000908FA9E302844FEA4F214F073ECEC3BD4E
+:1006F000DCFC1F1FA7C4C625B1714897BC2AF214A1
+:100700009B4F8D5A16A678E4709DFB61FC3E56A85F
+:100710002CF8389E630C3598D872B83E1AF7C02F63
+:1007200051BE6A435611CF839EB76785D18EDD6770
+:1007300094B6BE03723B6115E3EFDF7DC2FDD6F2D6
+:10074000353CBF5A5ECFF9FA92620F1E53AE6F2B43
+:10075000746BC3F90642125BE7A579CB6C79211C57
+:100760006702F0A717E61B629E09ED1EFA148C6360
+:100770008D07ACBC9E00F6C90976FA5AC5344CE820
+:100780003B2682743CE4B2B8F9FBFC20E9BD691C4D
+:100790003CD1C2AE75CE6BC4F61B0D2C985804F13B
+:1007A0008B35B212EFFF2DFD9DD9C8F77B1D934D00
+:1007B000C8EF9562E03994A7329B6CC2FAE25B798C
+:1007C00023B3516F579BE4E7D10E3D6C925F184500
+:1007D000762D433C1D17956B751D104F13FEE3508E
+:1007E000BE92116F7723E6F3C634817F572C066FD4
+:1007F000A3B2AEE5AF5A699F42A5C384BEF7BF1648
+:10080000C0F55C6757CE6BEAD703715223CE73975E
+:1008100091CB718D2DF078A281F07F13F1FBB3396C
+:10082000F04BDC5832D8DC2605FFDF29F8BFD51D98
+:10083000FEF0F79AC7876509FE3E11BED1D5EEA33B
+:10084000576682A83F550981F7F0397C7F937F373F
+:100850004D79AF5ED1E747E3E2BD586FAB650E0956
+:10086000F9932D3EF038CACBEB2113C3FDEBFB1CF3
+:10087000F12D2C212A371706AAFBD501DAAF3E9CB1
+:10088000CCEB99874FB8E83B25F885DB1278EE7CF6
+:100890006F2BBD3FF27A69F7F9FA578A7D7EFDA08A
+:1008A0007A8E2FB08EF2D63E0304EDF9ED0BAABC82
+:1008B00019FC1BF33C3DFBC347EBC07268F6B54720
+:1008C000DF6A09D277254CC10F305E693B974B79BF
+:1008D000554FCF8F9EB9DAEF89C77978DC953DE522
+:1008E000AE13F1B0AEEF42FDFBAFD5C46FD6D11C55
+:1008F000EFD146CF128CE7AFBD6064113051DEB34B
+:10090000ED62223C7FADC8DFFF28EBA8CAC8827920
+:100910000FD953F3517E0E9DF46408306E5BFA607C
+:10092000BA76CD6B4B9D83DFCFCD3E72C309B43B0E
+:10093000DF85806E283FE626FAAE1F70A9BDD76816
+:10094000621BD51D88C560B258A31809629C7677D2
+:100950003CE54FBF55D68F67FE911FDFCDE4F2F027
+:100960005B81C3A12AFE7EADD46623F8B5856E3ABD
+:1009700087C7F681D9D7C8752D0B9A16E3B8185FCB
+:10098000A1FC6658A3DF1DA5BC4A3E81CF6700A32A
+:10099000513EDA94F8B04C890F59513BE1BD7C09C6
+:1009A0007F7FA8CDC5F99FBDBAC68975F0434CDCE1
+:1009B0008BEB3BEFBA2941003A158DE67EF870CCFF
+:1009C000B970753DAF94B96BFC9AFBC346733B3469
+:1009D00062B472AE34632F9D77C473C771E9381E59
+:1009E000B7E7DE8C83F41D176FC63B32D2F7B759D9
+:1009F0000B4C0ED4EF90DD8D7E7382D3D3882F8F76
+:100A00009499DCE5E84FB11F9E9F8DCAB7DB8975CD
+:100A1000AA6C71AC13FD489B730EC9BB7068448609
+:100A200036DE38D4837C5FABE079E80AF23D455D81
+:100A30007FDA4D09816EC651AF6D0A3D80F9B988E4
+:100A4000CFE838AB22DFEE1DC1AB916FDB9A18F90E
+:100A50001EDBAD7CCF51F0BEB27CE7917CB7A573B5
+:100A6000F96E3B5945727DD8355F2FDF6920DF4035
+:100A7000D7D75C0137DAD3B674ABDCC28578C762EE
+:100A800078FE35C1C5707EC87F33B4FEF935FBE012
+:100A900099788ED68BE779A07D9CE4CEC7BA802169
+:100AA0002E97F4E450FDE0FE9827AC57F08DD51F4B
+:100AB000751CE6D4D7A7D4FBAF233DADA82F7E3A53
+:100AC0006FF3BA920F4B6DDE0C8C4359D3A332EA0D
+:100AD000C57845DFC6DBAC27E97BB9C9D6E87777AF
+:100AE000FBE3BCB312BA7BFFEECAF354F079B682D3
+:100AF000FE156AE611BB9F27B67E565814D8343AC5
+:100B000005CF31073FC1EF7F744EB651FC9D54D1E4
+:100B100049EF217D2270B9F432B9E104D2EF682F98
+:100B2000DA9733C44D52E897EA41FABD305AFFBE16
+:100B30005B4F743BF467D61FF71D7A5E4F51C66D4D
+:100B4000CE6EE8E684F5C4FFEFA1DBC004FF4B489E
+:100B5000B79342A78BBEEBA09E4F448B07E3DDA665
+:100B60008CB7D6DCC4F07D84D0ABFC5CEED7D5DF8F
+:100B7000C4E3B91CC7391EF74A6DBBDDDAEF47DCA9
+:100B8000E6B5D13A1DE7861CC673B71D46D669C0C7
+:100B90009C69F578B943870FB7B7EA3C5DF36FED11
+:100BA0008CC775AE35776EC0FD4A9857C47AC37648
+:100BB000C606AC433CBC368AF363E7BBED803182AA
+:100BC000EF63C7CE7354D18BB6697FA373BCDB0FC1
+:100BD0003C41E705B74C06FB4676438A47FBB6D750
+:100BE000E6FF661CD0E34FD5068A03FF54ED203F95
+:100BF000DE533CF916C639037B8E2B21EC18C9CF86
+:100C0000ED0487E375C2BF56FD3599E2A09B6E7D6A
+:100C10000BE2E909D7562D4178D3D801B73AC15E26
+:100C20004F1827D079A373AFCC0FE37B9B136EA92A
+:100C30005A9202EDE5D7B000BED7396186A09C4735
+:100C40009A12407B30E15681CE1FE544A07F2ED61C
+:100C50005B0366E4CB54F5FB84CAF9B3AEF861B428
+:100C600091E87041B1B37F47FF50A0A43AE8372A1A
+:100C7000F939548867CC9497B28019F13E3E06A2A8
+:100C8000C8041C3790D9A4F13FC7665967C9DC9ED8
+:100C90009BB5FB46CE121E17A8F5DF58798E2BE1C7
+:100CA0007AA69E33C1E76F1EAA6DE7FB1CCE12EE3B
+:100CB000BF9C6E9E8F205EF81D4ABC6AEB01C7A7E1
+:100CC0004D36E331B8329BB4E31D37CA7520A90411
+:100CD0009EFB8489B3311EBEC15765467FF2895998
+:100CE000A2EF3A853C2CF822E429E545FE462C5536
+:100CF0007D72FF7DB3C8AEC6C7C91877CB0A7E9B8D
+:100D0000E29E9D897499C60C12F215FFD6A9F101D5
+:100D1000C8D59B398FBE8ECFFDF60EABDBC8F7076B
+:100D2000595A6134BE3DF40E048E40F2EB58AB8943
+:100D3000E761C1C67BA1FFA40ABB88F1E80DAC83C3
+:100D4000DAFF953133B64F666E3AAF7113EBCC32A2
+:100D5000E1F97623C4F71E8AEF3FC6FD58888B87DA
+:100D60009614609CDF4CE335C4DD5542DFFF61AD76
+:100D70003379BC6EA0F70D62E3A371B61D1487C072
+:100D80005F7B6AFAA5F68CD0ED1D3D8784F1D4DD3A
+:100D9000D85F89A71E3605C6E0BC69AC5540FC3259
+:100DA000B14F327E2F9EBFF7CF8A241B9773BD7D34
+:100DB0007945901B3E417D798FBFF700F135C9D948
+:100DC000070BF979EC4D71F1E4CF26D6082DCAFE58
+:100DD000AAB1B150A12F0C7244F1F3139DC1D77A7F
+:100DE000C373474B6D0CBF2376EDDC55C4AF3C831A
+:100DF00041C2E0AB02E2B47B105FA0EB2EF1523EA9
+:100E000000DD4DF7621EE63629F5753EDE0D2F58E2
+:100E1000E83B64FFC23A899E7E26121F6697F0FC6B
+:100E200039A572AF90E4263ABB305E3A6CD4D72F26
+:100E30008F2975B56B6D1027E662BD51796F79B258
+:100E400040DF539022E238FC34C0F5B989F4DE4B20
+:100E5000FE11E910C2937C1CCE6D6D2FC3EF00FF15
+:100E60004B098787EDEB6C43D85FCEE1E1072206A3
+:100E700084277A3DF908F765FC7D151013FE7D0780
+:100E800026115ED709E273E8E7DFAFAB207BF4877A
+:100E900049374D1C0AF0759E01F47E5FE24C13D772
+:100EA000EF6CCE879BA76C32E2FA6FFC94D1B9BD90
+:100EB0009429402B806FF20B4FA11CFFBC84D7BF3D
+:100EC00047857E43FA9F58C3CFFD8D0A5D67BE09F3
+:100ED000E0AF4B3BEE55F2CC3AD433356FBBD7C1C4
+:100EE000E5F425E5FDAFD074D59EF0FAEED46A5E48
+:100EF00057260BD69BF24B92CFE378582F392A27EF
+:100F0000EF7D2035A6A0DC38B87D6336A9FC1E68CD
+:100F1000FFF091FE8CF34F9A85EB49437947BDADC5
+:100F20005E25A424D3771C5B312F66CE18BFF7A9AA
+:100F300025266E0F1D5C82F58A603CAFAB304D3BC1
+:100F4000E09F6A8B0FC581FF4C0D5874BF338075CD
+:100F5000206D3FC8431FC3F59BFBD80C328CF7BBF9
+:100F60006613C9F5EFCC8111FE6EECDEE87088F8EF
+:100F70009502781A4A805F4A9C7FFEA3F966CC07E7
+:100F8000BE09E5F4C7785CEDDF5E22E8E291DEB5EC
+:100F9000AFEC30817F4CA9FDCD0E1318BCA962C007
+:100FA0002C103DE6CE3E01EB9EAABCF7FF5CC99C2F
+:100FB000D9E83FA6E2BE2CD0EF3725B7CF46FF30A9
+:100FC000D5C6FD42EF193599F335F8BD5D62D5CD33
+:100FD00033D5C4C779ADA46AA7320EF99194A9D5C7
+:100FE000997738B5CFE97F3F656A86FEFB58EAF509
+:100FF0003F9575FCAE84EF276F99363513EDD6DB40
+:101000000ADC7B7A35C15DEDD3A7EBE0476EE6FDE8
+:101010001F99CAEFB72BF7474F79792AFAFD945BEE
+:101020006AE8FEE84A0EF71447BD22F0F34AA11B16
+:101030000411F5E79A8BFF5AF619D07DDA5123AFE8
+:101040005B4EDADB80F5FB8941966FCBA3E31B7225
+:1010500022C07B7E9DC1EBB5692C84EDCFEC49A30A
+:10106000736113E7EE7D2D09F5B18849543651DEE1
+:1010700023A652EF00FA1E3DC9F5C4401EC9BD9A11
+:101080003FBC94DF553730631C02F935BD77F65D00
+:101090002E7F9FE677530C7C3FA4C24AE70EA6FA48
+:1010A00079DDFEE680D08CE7A68E0BFCBDB610D0B5
+:1010B0006017E0699822D079A8E915D666B4A3D75D
+:1010C0008AB219F5874DE1DFD52ABB10C72223303C
+:1010D0004F695ED11BFA1DFFA0B784DF05387EB2D1
+:1010E000F4238C7FDFAC072B87F6F5E45ED2AB37B9
+:1010F00085FE12D55399603269FCC29B938F0B38E1
+:10110000CF9BF56298E561BE18FE88F74B60BB92F5
+:101110002FF53B98C8B042650B906040B3377D8F88
+:1011200087CEC3140616D7A31E3E936711F17CF534
+:10113000682F1F3F0FE863C087026204FD659AA213
+:10114000A7197E6908EE9F5AD8D9E5D8CFE2338433
+:10115000F15C41FA98FE4A9D9ED7ABFB4DE3DF6DF3
+:10116000648D015A1F6B3078B479D03121300B99DE
+:101170003BE8D575B3F1FCEF317B60169AA0B16303
+:10118000B671383DF011C20FC6ED9A5D518CFA79F7
+:10119000DFAD4897CA4A81EA72E7132533D2714618
+:1011A00028813568C62DADDC64C6F872DAA452E237
+:1011B000EB941A0F5DCB2B1667E2FDC01837E1796F
+:1011C0003C3DF811E27F2CC78AB108CBF65A238642
+:1011D0006197CE535A9967463B3D0DE6C1F863DAF5
+:1011E000A4C5FD707F6E4A8DE04622F7387E6630DA
+:1011F00053F8678EEF09CEC27EFFB4F17382248765
+:101200003D8E3F49197FD2261A7F0A8E8FD7B9307B
+:101210003EF2A5828F3FA302E2241CDF5B9589F595
+:101220007675FC63F66026D6DDB367FECF8C7B6CEB
+:10123000208C87D73CB90DE3906302F3E3FB83D99D
+:1012400095ABDA0D58CF12B3A80E78DCCFEB809AAD
+:10125000BAA10B83F4A3A581FF2C407D9EC6DF4F6E
+:101260008CB55B8BC670FB79345A3F594FE756A655
+:101270000F10B4DFE35A3686C7F5581F2C107AB624
+:10128000836A5CD5E59706A8F5935006C67D57ACF2
+:101290009FB863EB27FFFE5177F59307C7A8F513B7
+:1012A000E19ECBD74FF66662FDE4F875A9F9DC2E16
+:1012B0007932B11EF6EEC2C199BAFA4905AF9F9CC8
+:1012C00037BB0D18677DE03752FCF9817F39C5B710
+:1012D000DF4100C7F27AC6BB2D66DD654A7E349ACF
+:1012E000854AE97BAFB5EEA410FFEE6E3DF27BC3FD
+:1012F000DDEE7CDC97DAA3ACE3432148E7F34379E6
+:101300004C44BB9B9ADC4EF62A096282E5B80F6218
+:101310006AA2F7C3D244FC121FFEEE4E90BE5BEEF3
+:1013200072B37C3CBF08D104BDC765B3F17D934C5B
+:10133000D64430E437D4FF1994CF141CA79DFC4643
+:101340007AAE5B56F011310E4B33B58EC3F1B364F8
+:10135000C668FFCCD4E1C5FB57AA1FC4AEBB4DE89D
+:10136000BE4E37662CCFDBA438760FD6F554BD9829
+:1013700036C9D31FE3C2D249CDE3D1EE4D090D37B3
+:10138000A05EBCA1D0654A35D78F4A45AFEB3F5A26
+:10139000F53AEACF1FAE13E8BBBBE515CD19A8DFC0
+:1013A0006D37FC3203FDC57BB3AC0CE3A4F7ECC195
+:1013B0008F1290CED3AD6EF46B63C6F2F567578291
+:1013C0005EC647F547EAC566F949CE662768F73D28
+:1013D000557CBBF87941203FD7EA60BFC2F741DEB8
+:1013E0007BF5AFB3D3804EAD7DD85768CFDD638D2D
+:1013F000B7E2FB1DADBD795CF4D5AB598F635CD40E
+:10140000AAC831C661559AF8A553591FBE86CEBFEA
+:10141000B794F57824574B17C1CDE9523A1ED73B04
+:101420005DB173D3FD7A7A54D6549951CFCB2B3D0D
+:10143000642FF08AEDEFE5703A948CE576E9BDCC47
+:10144000F009A407E4D5440FD53E0D1CCBCFF32300
+:101450007E18E79499789D0BF2F56EBF27F47F15FF
+:101460003B30D5145A817131DA5FFC9E4BE9DC2A9E
+:1014700033DADF195EC18DF3CE0870FB7BA37731C1
+:10148000B7C333B93D53F139E6F2939D3C962E979D
+:1014900061FCADDAB5F3E670238E7BA3E2FF4A2B45
+:1014A000605CB8DE02761FE38F5BBC9369BD378357
+:1014B000FDA7754F6A26FBAE8EFB614E98DBF7C920
+:1014C0008A7DF7F375C6AEEBBC5926FC6F09F513A0
+:1014D000689E997C9E9BAB133DF43EEF589EA7DF20
+:1014E000ECCF23FC6FAADEC4E79B5B4FEB783FB1E8
+:1014F00095ECB23AEF1FBF0F64A21D52E5EBBC5949
+:101500005A8171D2CD2A7DA670FA4C0FF0754C9F8E
+:10151000C4C79B16A8E2F4A9DCABF06FEF63E4BF8D
+:10152000AFE3FC9394F1DFFD7B3883C6F776BF9E73
+:10153000583EE58F55F9D444784C57F1A8E67854D5
+:101540002AF4AC9CBB97F09851B998AF6FA687E886
+:1015500009D759488FA32847D0EFA8476EB85BE357
+:101560007F4AC6F238F918AE1BE5DBDC4AF4AC540E
+:10157000F916E0727AE34C2E0F37D670BF76FD4C29
+:101580001EBF94FBF368BD7FC89366A11D3B76B375
+:1015900095915C4ED1EB675B9DCCFE84E7B68A22C9
+:1015A00094672E77F2730065E552237E0761149DE0
+:1015B0005C63DDD41DF4F582D4B3A1151827665FF2
+:1015C00070F17D9B4A41D9C76386D5BDA37501568D
+:1015D000BE89D76B947AC7A342C449EF91BACC4471
+:1015E000E747E72450FC7C741AAF2BA8FE6ED39C0F
+:1015F0003ACA2B6F926DCC0AF8DCE4E475830F5F76
+:10160000B7B10689EA08549FE9A98E60B005CBB14D
+:10161000BDCC6D92F87E6690F4A05CA9238C67ED3A
+:10162000544788AD27548FF5101F26B1562109C69F
+:10163000797F4E9D0BF3BDD87AC271251F8CD613CE
+:1016400094EF5378CCFFAC7A02D50998DBA8D41379
+:10165000DC84D71B9042225DDFADE0FB99D7DDE053
+:10166000A1FD31C8FB0B91FE9A7DDAD058DCA7CDE5
+:10167000E4FBB4F487F2946DA67C09F2E3FAB15866
+:10168000BF63E1995A7EFDE8FA54A318BA1BF154DE
+:10169000EA51A9288546E5F7E8B0AE16B3CF162B78
+:1016A00057220BCCFA6FCDCFF879AABE4CFD13446C
+:1016B000DCC7CE509E172AE7533EB26334138D78B1
+:1016C0003E636590F07AD81478722C25833C4E489E
+:1016D00043FC40149EE89DB7DA68BC14CFE345F2A2
+:1016E0002F919EE38D4E2902F87C73D448FBED9335
+:1016F000E4A7C7A31DBB8135ADD0BE3F30782BE03A
+:10170000A5A94FE4846DCCA439B7F293DDA20E1ED7
+:10171000DA9AA6EB3F7C9F5BD79E17F1EADA471C6B
+:10172000917470417B91AEFFC8F7651D5CDC51A1DF
+:10173000EB3FFA0BBF0E1EC4C2F4031C633A2B75B9
+:10174000CF7DC3026D788E6D48B155C4DF776521BA
+:10175000F95D2FE8DD5085DAD75C08C48C73C28050
+:10176000F1625A5F23B342DE58CAEED08DC75E30B5
+:101770009D42FE05E17FC8BF210C60CD39FF69D5D0
+:10178000E6531DBAF1F4EDB527ECAFBFA669FFE350
+:101790005857329D33F0311FD67D2EE10F3393DD44
+:1017A0009BB19B85C31E5C0FE3DF4DDBC6BF831D72
+:1017B000BB9EF375B6D75F33233F41A5515F609C55
+:1017C00008C891354DCF4FBB5BCFCF38AF9E9F2E12
+:1017D00049CFCF84223D3F13653D3F7B55E8F999C2
+:1017E000E2D7F333B552CFCFF4809E9F7DABF5FCAB
+:1017F000CC0CEAF9D8AF56CF274FA85AD73E607520
+:1018000050070F3AF181210BD6FF76BA910945F8BE
+:10181000FBA2B5BAE7553E86E07FDDF1F1C69A58E6
+:101820003EF2EFB85C899F29D7E8F9C98C332FBB0A
+:10183000DFACF20BEC59DF6B789D6196AEDECEF437
+:10184000FB029BE266CF42BF72538695EA2C87D299
+:101850006F30F572F37E5A7F72832F8FF60FC65763
+:101860005BF9791FA57E84C7C0F8B970EE8F2A7026
+:10187000BF40C27D8430ED174CEC61DF20D63EAB1B
+:101880007619ECB4EF9A1494D3C0810E01F717DAED
+:10189000E979276BD2AF03EC229E97BC6ABB38492B
+:1018A00094EFFD3176D99D19B5777DA379F1D129D2
+:1018B00056B28BD1BC58A2BCF8BD52C985BFD7DA8D
+:1018C000535E7CE3353C3E7FEFA0FAFDD2EEF3E2BF
+:1018D0005BAFB9BABCF87FFEDCCCB3DD9E2BB8EBB6
+:1018E0009AABCD8B9BE95CC1D1593C2F3E7A7231CA
+:1018F000E5C5C773EED3E7C533795E5CFFD1B50D9F
+:1019000027A07FD951FEBEDA38DB628A3FCBDE32B8
+:10191000F37ADF9A701C7F9FA49AF83E5EE1FB2168
+:10192000657F795CED383FEEBF8E3FF128F92BD112
+:10193000C0F97E5DB210B00109CBC791CE30FF1C5B
+:10194000C6CF8BB39023D147DFB37F0EF97F5EF90B
+:101950009E4D67223FBF386E69298DD7F5DEF16253
+:10196000FE7B0A65CEC599F8BDA67133AD82CDC3A5
+:101970002EF1C7C79BC510E61BC7170F93308E7D8E
+:10198000E91F7F207C3AEF616E9CB7CD75CB474154
+:10199000E83A4EF94EC5F13CFEDDA8E3AEFE646FB9
+:1019A000DBB0CE9B4CEFE8D0BEF171D7F3F43B0334
+:1019B000C71FE1E74A8F431F8CAF8F6F1AAC7F5F61
+:1019C000749DEBF2EF8B2AEF453313FF5DB7FDCB30
+:1019D000443AF73EBA5FD34C8C4F3AA759E8DC0142
+:1019E0003335CD7D08DB2B87F076E3A625EF62FB50
+:1019F0001D0E6AFFD2DC54F31CD263B2573D471F61
+:101A00003759710EDA7D38F53B72EAB96E95DFFB16
+:101A1000BBDE230DC769F3E12BDD3F9E18CCD47EDE
+:101A200077E3F8AC6B330314E7AF6A47BB593EC5A5
+:101A30004ADF1B2D17EB4D97B3872DC5817F477B61
+:101A4000B2D9F374DEDD305D8567979D9FA78BD992
+:101A500087BCC42EFEFB09CC4F2AD12E323C1FB8C6
+:101A6000FE75EC7F6861F7FBA7EAF945DCAFC3FDC3
+:101A7000BBF1CABE69056BA2F8FA7A16213BF65F84
+:101A8000D8473D86F8DFEBD84BCFA9FBA860DF8FA6
+:101A9000A37D1F7D56A6BC00E27CFA5DCBA3892105
+:101AA00092DF729740BF3B006E9BF29A73023F57E2
+:101AB000186B17DBECE7B370BC2BD1938D0C7C7EDD
+:101AC0008DA67E519114B68B54DFD3C7853DF1E1CD
+:101AD0007FFBF5FF01CB627F220080000000000049
+:101AE0001F8B080000000000000BDDBD0B7854D5F3
+:101AF000B937BEF69E3DB76492EC84900B04B213E6
+:101B00006E0183EE048C80A893AB51020C880A5EB0
+:101B100070128206484284D6C616CB84C410103494
+:101B2000D48840512751F052B5034645C57640440C
+:101B3000CEE7A5B1B6FDACB59E44BC211747506AAF
+:101B40003FEDF1BF7EEFDA3B991982D8EFF23CE727
+:101B5000F9E71CBB597BADBD2EEF7AEFEFBBD66C1E
+:101B60008A7DF04696CCD80C26EB76FEC4DF861430
+:101B7000C62EC73FB219FBEBE2E70FA0FEB51BED87
+:101B80009A254BD4A7153056867F488C1539F49288
+:101B9000A1BC5D09F3286C145E361CF8E964C6CA62
+:101BA000CB9DEA7A9DB12B985F6116C62A580FD556
+:101BB000CF62217A7A986AC5732ED3E9F945616FAD
+:101BC00001DAD53ABC0F25CA8CB5AADE14F7858C8C
+:101BD0001D1FE17D54E5EF0FC6FE4EC17CEE55DCC6
+:101BE000A9EEA18CB998E746C6C729E6F35ECF9F58
+:101BF000CCCD4627A7D09418D3F87BC77609F5FC3F
+:101C0000AF27359DFFAFCB7AAC3747CCFFFB6CF1EC
+:101C10009478FB5466FCB5A86ECC9BAD88D731EFA9
+:101C2000341690301FFEB984F567FC8469EBD1F956
+:101C300014DDE19988F719899F9CC7A8C9F79771A6
+:101C400078585C0CE3BDA34A7E3BC1C93D2BBD0067
+:101C5000EB17F379A7AD5D19C9FB2949B7301FEF21
+:101C60009F8DB67ED8EB604CE7FF87F914314F4269
+:101C7000907F375317EF699EFCBFA2F7C7D33ADFB7
+:101C800092645D9A0E382B1FF6AF230BDF8975A681
+:101C900059C43A8BA2EAA3E1D2F8BEF3D5033903C3
+:101CA000FDF375FB7E923CB0EE54E6A3750F6741E1
+:101CB00089F6734A0FF5DF6CACBFDC1D97FC492C2D
+:101CC000F535EE7B5EBF7FF51E76780C2F5B6E4898
+:101CD000F0BA303E7307F8F37BFC5D36F0FCC76A60
+:101CE000C7AB07AC8C5DEFE69DF0FDFB0FABDB8374
+:101CF000FDFD5C62F3D15E65BA32378E3139767A9A
+:101D000046956BA05D743FD1FBC8F16101F0217A6B
+:101D10003FF858377A783FAF0EBDB67A135FDFB819
+:101D20008726E4A3EED594EB7FF236CA0F8ECDB7AB
+:101D300070785419E3EC1CB664F7ADBC5C224B8B95
+:101D4000F1DD01A7AFE85EDEAEE7595B76970A7C6E
+:101D5000A8E9980338E766E737A39D8D51BB1917AB
+:101D6000D44DAACA1D98DF0AF4C7D735C3C21AB02A
+:101D7000AEE18A80DFC81C55F2F1FD19C19862C935
+:101D8000E7CF34BFA29ECF984D614A4C127FA6B5D3
+:101D9000BBD478DE6F8CE8B7243B98B1928FEF7993
+:101DA000CE95DFC5C73B20ED929FC17C0A1D2B302D
+:101DB0001F73BC92A4C09A24DEBF4766F9BBF9FE2C
+:101DC0009514054763DE9E276CF95D0CEB09C8EF9F
+:101DD000607FE7C6ACD8C1BFBBECBB2F98C2CBD7E6
+:101DE000CFDF94BE9EF7FB7C6DA1753C87FB06B7E9
+:101DF00083E0708D4772FBF9F869BEDE962158EFDB
+:101E0000FCC2C958AF39DE5D6E2BB59B3745B49B1C
+:101E1000E7A9B45687ADFF1A7788315EBE667E9F0C
+:101E2000027CD814BB90F8CB3CF097C903FC650E3C
+:101E3000FEC1E9FCCF575FFE2AE0F37625E72FD2FB
+:101E4000007FF1E01F59C45F0E0C9507F804C7141A
+:101E5000EB6DBCBF6B0CFE722D6BA7F7D7B1003DCD
+:101E60006F603D829FF4F5F393CCE4EC013EC2F940
+:101E70004A27F0EE6AE6A676F3197BB9370BFC44E5
+:101E8000573C71E01B2E9F257E503CDB39189E6D20
+:101E90008ABD94D677DD59F8E76B332F6AC1FCAF62
+:101EA00073055D9378FDEB71567D0D1B8C8FBA1514
+:101EB000C003FC73056F578AF5F1FD2A67EDC42F47
+:101EC000AF3C2BFF0C8D54F864EA2DC156C0EB7467
+:101ED000FADB1F48BC7C5B4C9E9589F5FE1EEBAD82
+:101EE00060DEBDBD04DF8002FEC5D713147CB48163
+:101EF000E61FCE4795827F838F56A8C170BE19CD4D
+:101F00003F4670FE097C66DA8801B80DA7CF0F64E2
+:101F1000F1EF148DF989AF32B7AF8797ED1C0058F8
+:101F2000776582F72F989FA27A18F00813C3FE30C6
+:101F3000E623FCBB94339AF0E7DD05EE85A5FC199A
+:101F40003B99B9FDB978865A37F2FEACEC7C59E280
+:101F5000EB7BC0C9DA9C9CEE6E2E28DC5CC6DB2DC8
+:101F600057389FE2EDD6946944AFB13DCCDDC9C787
+:101F7000B12ABE4AACD7EA50139B12192B28EA09A2
+:101F8000CAFCFBD050A6820EE37A44FF0FC4311F77
+:101F9000FA5B5326E87D4D994A4FFE7D13E069CDEB
+:101FA000E1DFE7F17DBD5EC885D3EBEC7E3BD6A9D2
+:101FB000783313797DCADFEC0CEB3EBCDE5E033A6E
+:101FC000AAB2312FF845B2C137F8CED1BABE716787
+:101FD00051BF3E5694CE9910DF98F569F4646BE8D2
+:101FE0007D5522BBC9C3E7733A515B88714FAF4B34
+:101FF00095F80EB02AABBB6C2A1FF7F0A644698D8A
+:1020000036D03EE416EBADCA727FD9C8EB43735CA1
+:102010007A176D87376F0EC70BBB65F42C8705F2F7
+:102020006C55600FAFAF1BE152EDE07799EF6F9EFB
+:10203000C2CB47BAADD823B664C75509417CA6B810
+:10204000D3804FD17C7A893F528E2D7B2CB25C1786
+:10205000882C2F8F925BD1722AB590CB9DF30827E5
+:1020600075C89D8F2077382B32E54E3513FBC99804
+:10207000DF3627EE4CB9F31FD6A291857CDD4B8D60
+:102080007DB7DB1B3EEBE4F0B2DF353EBF89E013EA
+:10209000DA07FA4DB9372B1F7CF15D838F1F737BF5
+:1020A000C616F27DB0674E3F9FE45B6605E1C7E967
+:1020B000AD4E0D72FEB45312FBFBB2E4F7F172C7E2
+:1020C000C8EF5AB7F27E3AA6D9554927BC9D75216B
+:1020D000E70735063D25DBDC4BD0FE933931EA1AA4
+:1020E000C1EF1C32ED2767C0FC59DDDED47A3BAF6F
+:1020F000CFE402DDC251AA96F5C48368EA0AC5BEE0
+:10210000314BC5F826DEFFF2AB62889696B5F86DC6
+:1021100000A3F22FC503BC5C8BAEA672D6EA70ABEF
+:1021200085BC5DDD9EC43CB42B2A94099FDAA6AF22
+:10213000F1E0C3CA04D19FBD7B8E6F38FFE765FF16
+:102140002A615EFEFD2D8D17DFFBD124CC3334A434
+:1021500010F8B1CE42787FCBED53E9BD34B7BCE780
+:1021600032CC7F5DAC067C7E65AB9DD6FF095F3FC0
+:10217000CA9F3C20E0714B86CBEF90CE5C7F8B14E6
+:10218000B4093EDE130FBCF9F4819FC503AE9F7204
+:102190005647FBA736C4139D6B0DF173C3F0EAC31A
+:1021A000ED9672D0C9A7DB47DD3D05F09D7BE58547
+:1021B00090DF97258E8ED75C03F54C6134BE923448
+:1021C0006527E8EBB27F59883E0EAC3F2FBE97D70C
+:1021D0002B32F3EEE24FADAD7809E865A927265121
+:1021E00093685DB4AF1FAE73D2BA96B7AD6DDDC262
+:1021F000EBDFE2FA9A3485BF9F3B4CA6FA2725A66F
+:1022000042AFB27C5780797FA8E6C4333C99523EF6
+:1022100098DE23175A08EE07E6C6E841DEDF913F55
+:102220005974D04F61E6AAD03EF4B7C142F4546667
+:10223000C99DE500BDADE365F0055FCF66ACF33049
+:10224000A7371FC87EEE96B269BCFC61A12364D794
+:10225000FF7DFA3AB4E1542BE8FDF014BB6A57CF86
+:10226000A437FC0539DFAF32F6299AFEAA368CB2C4
+:1022700041AEB33641876D8512FB5EFEDFA2C37BA4
+:10228000404F261DB28CB984AF663B93EEFAF53D04
+:1022900083DFBB7264D2371C3A73EFE0CF543B73D9
+:1022A0004B9CFF76172A54DF5D68A3EF947FAE78CE
+:1022B000EC4D3EFFA985DE07314E2673E701DFB204
+:1022C000BE62720283BCE38204F26AB4CDBF83AF04
+:1022D0007BB3956B4EC047C5FBCC9BE0FB6D4B269B
+:1022E00081FE7719FD1D737B1F453FD5ABBC5FEEAB
+:1022F00063C0BB69C407AABF99276B7CFEAE0E46BC
+:10230000F372E99E2227F87EB26732F0D2E4E363EB
+:10231000F87C3B73CFC48B3F165AA9FF31C91EEA24
+:10232000E7A96295D6D1011D83F7B3AD31C60F7908
+:102330007ED97799B2CCE775372745C845C794B998
+:10234000B245E819A131BCBC22CDA27D34848F3FB7
+:102350002569FFF778EF4BF86A0CC941CFFEEFF91A
+:10236000772E5E968652BDF8CEEDA0EFC6E488F6D5
+:10237000EAFE84AF122E812AE6D05C1C5F36F07F25
+:10238000011FB23A44D9DCFF93ED12D1A7836976DD
+:10239000431FF86A479E90B7909B2BD26C340F7303
+:1023A0007D374C2B7C03FC96B9DDA3930B08EEF430
+:1023B000F7DCC51AAD93DB1DCC827E6416D8C6F15E
+:1023C0003936B7D70AFE63AE675A87BB1578180D42
+:1023D000B76A639E1B314F8E2AD3745ECE39739ECB
+:1023E0002BF8D21A397E040CBED9AF9F1BF3E4F24E
+:1023F000AEF7201FFF0196C0D6139FF6FAC157878C
+:102400002B710C70B638EEFD35F85DECE486877AFA
+:1024100009AE0A1BC3DB8F1856DED9CB9FFB9B3955
+:10242000DE65F0B2ECD5B05F4A32D7EF391E0FB798
+:10243000DCFA28DA0F6F4E559B613759F9F7FCE942
+:10244000E30A05F46F5F91BB13F53E9B436DE6E332
+:10245000DE1F1B4FFCAAF1FD38E29FFF903DA42434
+:10246000398BB269DEE9AC81F4A8A1CB0E4A127FA8
+:10247000A58F12F2FE0CBBA848D8311FAD6EFFF538
+:1024800047D681F7EB12BDB313793FD57CBA97726B
+:10249000782C6EDFF4EB8FC2E0A5178BFED64A3A9C
+:1024A000AD8313BFDC44EB984BF31A6ED14EDE9B29
+:1024B00088F988FE4128FD7C83CFF301CE9E9C499C
+:1024C000678E1BFD5C6C8C93D321F9C7C40FBC4F86
+:1024D00034FA7D22D19D54C49FA3D54BE707F9B8A8
+:1024E0002B25AE4FF2F9341AFC9CB5D9FD3B24C024
+:1024F00053BF16F4E07BD32AA16CF6D31CA7A762C6
+:10250000FED1EF573AF5D4C441E0D5AFA7B45998FE
+:1025100097EFF39276F13C5BBB8B1FB53708F9124E
+:1025200058B40D7C58D2B2812747763C3F09F6EA71
+:10253000875661C7467FB73DB1706211877F9A8128
+:102540004F1CE2EF3ECDE7BFCD97A041DFDE621525
+:10255000EBF32D89A1F5E9FB1D44FFCD6392FCE46B
+:102560006FD9C3692E65802FA7346B07BD90CB85CB
+:102570000EBD0B78DB56EAEEE7F3D0C71DBD4CE18C
+:10258000F59BA731753D2FDE529448F06D9EEA13FE
+:10259000F6BC418FCB0D7A94F64AC1B8F3617F88BF
+:1025A000F939DB6FE9C5FC629BC4FCF69BF3FBA920
+:1025B000C398DFA1AD989F2D46552D89D485DB1199
+:1025C0002637588BD60A3A82E106BAAACAADA6FEC9
+:1025D000385FD212A60F325F16B93E731EB15B3957
+:1025E0003E5A307EA07D27F675A2A2EED0047CD2A2
+:1025F000307E7D86800FEBC982BE5095E6E893E27F
+:10260000A99383457C3C9BCCF9E520F079BCD47D33
+:102610005311D9435A8605FE8B051332A03F543817
+:102620005E7B573A1F4F1620FB4F8FF61745DA7D1A
+:10263000F58DC51EA12735FCE71DB00FDEB4921E37
+:102640005D7F7BA147E8490E1FE4F9728F8DE8BAE0
+:10265000786F960CBB7BF91B16610718FB60AEFB0D
+:102660002549F5A501CE120B3CCBE7BD7C4F61BAE5
+:102670009597EB3D36097A5455DA3B5BAA79BF1D35
+:102680009D423E74AC1B43FAE673FF75D5073EE0EE
+:10269000036FD385F7795A13C6E9B843D37DBCDFFE
+:1026A000131267D980DF827892771DEB0E3FF80B0B
+:1026B000D42F71E918B7234BEC6F475C8E1F76431C
+:1026C000230B90BDC30D4F7D077F1C71BCB205FC71
+:1026D0007289F3F52D58D7C516F926D87317670AEE
+:1026E000391A5A67EDEC92F05E32CB5D281FE1F4A7
+:1026F000B09B98BE9612AE07545999077452D529CB
+:10270000FBC65C10F65EE2EFA10F285A4AB8DE77EE
+:10271000AEF71D89EDEC7682479698BFA1579C5283
+:10272000F4841FA2FBEA6F2CCC1D26AFAA15E1B7DB
+:10273000BA275E2F9813F6DDCC6299F8F022439EFB
+:102740003BDB1FFDDBD37CBCA2A6CCACF5C903F8F8
+:10275000FFA1414F6F1589F629C063DE7FD189DC67
+:10276000F781FFFEE6044DBE14FA0623FAF46DB2BB
+:1027700047D0FB8B9BD2FDF07FC42A627F176F8806
+:10278000F337F1BDA9FACCD607BC7CF1F884560F1B
+:10279000FFAED7C242F2B473D391393EDBA22543D8
+:1027A000CFDE6CF0273E1EEDD38B0B52887E4C782B
+:1027B00099E35439AC417BFC20FD276B93D1CFF1D9
+:1027C000D58F6D079FE7834C86BFAE4E15702B8A61
+:1027D0001D3F19FA61A363FC64F0C3AEA9DE8FA7A5
+:1027E00084F9EF5E8A195104FA7CC9C6087F9CED12
+:1027F000E33E025CCE064777B1B0574C7E60F6B33D
+:102800001FEBC8C53A72465786F1DB2A8793E8BFAB
+:10281000E8048753F28F8793D9BF09A773F57F36F2
+:10282000F81C2C757F0EF9C5EDBB4EECDF7EA7536F
+:102830005BC3E1BBCF79B9518E237B518A7112BD45
+:1028400015C5C4929F588A9DB8BD1DF814EB243B52
+:102850006091DD9D25815FC6DA35E0C77EE70B79A3
+:10286000F05F14D5737A95E01FBCA212FD15C5D890
+:10287000C94ED9E77C2D1DF4BEFF569B8EFEF63B5C
+:10288000277E44FDF3FED03E39C9BDAD1D7C5C62A0
+:1028900073D6A8A2FE2D7CDF1C9F857EC61567130C
+:1028A0009C4B62E308EF8A62859FA268B8C0C3A20E
+:1028B000BBEC9D82AEDC5D3D629F3C3B74C8E97819
+:1028C00037E6B5D21947FE9B73E285E25B8B753222
+:1028D000475C3EF8F8CA315A35ECA195D2481DFC48
+:1028E000ABC816F80DFC3F8C6B7DE8BF289ECB7300
+:1028F00094DFE2F23CEBBF953C1F57CCE1B528B624
+:10290000278DF425BE69D083374A3D1AE60BF900BE
+:102910003FEF4629701EEDA3C2B2A017E630DE7E5F
+:1029200032C917B63EACBDA288F6158EF7A91E7D3A
+:10293000DAE9FBF6AD28DB54A6A23E5A1E3DE29C26
+:10294000D1D5407AB83AC79AC6589C2CFA973344E6
+:102950007F5B8B7CE3555EDE5A15A3376781EE0201
+:10296000E735B8CE94638BECFA07E0678CF3A71DCC
+:10297000B0371305FE9BEB2D33E87046B1B0CB1694
+:10298000C5723E987B663B934FCE34DA8D99EA2E22
+:10299000849C2D847F8E3FE3723D591C83D97BEE4E
+:1029A00015BD31BCBF140B6F3F8D96E36353C88ECA
+:1029B00030CBF044B3FB643EC36128FEBAAB647A0B
+:1029C0007859B4EFFFDEF755554906D985FDF51066
+:1029D000AFDC5E34CB6E27C7B7B57103F50A8797B6
+:1029E000A34D32C6DB5D553A9AB18F25637CDF0B70
+:1029F0009D6EC801278B182F7C7E4A54FF56DEBF80
+:102A00004B33DAFB6ABDE8EFBE7CB3FC3FFC6E3EA5
+:102A1000FF7BAC91FD11EB30BE47C11CEF9D57D73A
+:102A2000766DC818B05BB91DFB33E09B16528B6006
+:102A3000BF9AF66DAC7A151955D66FE631D88FD698
+:102A400064E18FB7F23D1C0D3D43CBEE22FD48D132
+:102A50007CC00BC7082D1FFA6093B13F9509C25F78
+:102A6000A9EC9DE3861A6765DACE37B3C8DEBDB33D
+:102A700018F22BB3E220F8D180BDABB8819B63B8CC
+:102A8000DD2CF1768E0E2E7701930CD93F4612CBBA
+:102A900082DEB0EE3ECF8518E7EFC5DEBB8BC3EC20
+:102AA000AE311D6E1BECBBC3067FED58922D4B6102
+:102AB000F8F3B0813F6360E7E7A2BDBF2D1B7655F9
+:102AC000E23CB2A7CD76D9EA6819EBCECE10ED6222
+:102AD000B9FD0C3F5776873705B3C856BC0BB0DE3F
+:102AE000ECF937DBA01F3D5C2CFC2F93DBFC4EF890
+:102AF000B3588DCCC6F0FEEE2AD684BF56AD16FE76
+:102B0000DEF90E17ECED6D9E9D4EF43F26A78BC6A9
+:102B100067AAA2A33D53B87DCFDB3D98A45CB83E25
+:102B20006C3EEB55A51CF328B0786F257E30649A77
+:102B30001BFC6AB8E5EDAC4ED84F43F22DCD1CD44A
+:102B40009BA5487A319FC34BC57EB4481EDF6CE815
+:102B5000059C3740EF32EB3375E15F78B158F823CD
+:102B6000349F5AE4E0E34CFFCA43FEAF178B85FF66
+:102B7000E3774A6FAC8A7933F7AD5558A7C7A5817B
+:102B8000CF32439F4B5EADE998B723B9F7AE0B50F8
+:102B9000AFCB3AC276A6BFECC40BA95DE0E3134A03
+:102BA000BCAF01DF0A2CBDF7CEC67AEE5274F473C7
+:102BB000E2053BE90DC9BFC8253DC59ADC43705EFF
+:102BC00097C6C80EB874DD47B1302F1CC91E067DEC
+:102BD0003A966F13F474974BF2430E4DD6F512E20A
+:102BE0006F0D4C1FA3C35FC20504AFBFD2F1B6D0B7
+:102BF000E3A3FC0463383E7DE2A01051CBF7D06321
+:102C000074E12F2863C25F70E8BB79142F911D5EB9
+:102C1000F2E395CC8F619857BF7FA1B5F75519E3C3
+:102C2000F6F8955A0EF7383D40F26A31E89E37A91A
+:102C3000CAA9B261B09B3B24C2A36A03EF98A28FDA
+:102C4000843DF17171AC61EFB610DCAB998013DBA0
+:102C500060273DBAAABD90FC61E63E71CA12ED3A0A
+:102C6000041DDAD6083DA7CA884770400AFFBB4159
+:102C70007FA63F9EB176F134C6DD2CF5B82D020F4C
+:102C800048FF5E387AEEADAFF279274D9E908F798E
+:102C9000A729CC61E1F6B6B544D8CD09FB855DBD69
+:102CA00055DA948EF96D4DD7A466BE1F93CB05DE21
+:102CB000DC93C8ED01E8E56FB34B609FA4C63674A2
+:102CC000021F526FCAC9875C882911F08A99D4BE45
+:102CD0008FF4F75B35B58BE360DA9ADE52E07FDA8A
+:102CE000951A43FC2F617F03C535427318D50FBD7C
+:102CF000765513DADF358C2559D09E35492BF83CB3
+:102D00005A874A84E7AD955CFFCF057AA9843719C5
+:102D1000F355097E8554CE46D08F83A9BBF88CD954
+:102D20007DF1A21CBA9D2576C154952D3741FFE651
+:102D3000FC93D695C4F1BF0B71D492448253AA9DE3
+:102D4000954B49E2BD9FFC51CC0D7F6E6A71431ECD
+:102D5000C64F1D259EEBF3821427DBC6FC5B760075
+:102D60009E393615F07CE9F8C116D0C7177936DDE3
+:102D7000C2F128E5BA432D18FF84A434C0DF7E8653
+:102D8000DD7751F198120E9FFB9AE62C588C7E2627
+:102D9000BA881E986F977E15C5A322E5A962E8DD63
+:102DA000278FC5C81267D82D861E71E8D0A804F8F1
+:102DB0009F29D6C2D73DA92489D6739269092A9F33
+:102DC000EFA17D63A9DE2C37A21DE84F57C84E380E
+:102DD000D30E5B61D89D1611BF31E8D89598E25F9C
+:102DE0009F45F6998FE256BB9CFE2E8A3BB120D5BB
+:102DF0003F3B4ED45BE6103D847671BB550BB7D795
+:102E0000822AE2402756F76C291983709FE12F7DB3
+:102E1000398EE6916C0BAA13F8775F486CF71AC0ED
+:102E20006D42682C16EF92845D77C2F0AFFA74A5FC
+:102E30006B078DEB4EBB2ACC6E6B31F8A04B0ADED4
+:102E40004CFDEE72CAE1FE9A6176FE1EEB7E86BFF5
+:102E50000FD3FB5EB28AF7BE5DCE087DF0395B70A2
+:102E6000278DB75BBC7F55F5DE581226776AE38362
+:102E700063135D3F069EF97703DFB91DDD83F83AE2
+:102E800087970FED5D1B47907ECBE129F0749D4441
+:102E9000F0E4F63DC9C34FF2942EBBB07F89DE8FBC
+:102EA00058758ADFF86EBF40DD417E45DDB618FDFE
+:102EB00014A635C01F61CECB6515F6AB0B767042FC
+:102EC000D87B038E4C09AA73C3ECE645F9D5152CC3
+:102ED000FEECFAECA29AEF16326EBF2D6AB31BCA53
+:102EE00085F0EF99F5265EF6EF8381979CFF44F815
+:102EF000E9D7950839EC8FF2E72DF1B17DE45F79E0
+:102F0000C40E65B69F3E369630938FD9603F2D79BB
+:102F1000DF49766474BBD34ECE2F1197FED51C8A41
+:102F2000FFDCCC1AE859C3BF13F1A0813898CCF567
+:102F3000A3A52C40EFB53685FC22DABBB17EC4696F
+:102F4000B836A3B18B901AE021FCCDCA90F5203E93
+:102F50009338B7E7DF692DBC3E95AF779D42F4D03B
+:102F6000D926F925FEDDDA1659F8B13648FE311CAE
+:102F70004F7C2DB21BFDF0F1D2C0779F2A117AC28F
+:102F8000AB25869CE520C07CCCA7D93F871BED7381
+:102F900013938328CB9278AE851E3088BD60F6D718
+:102FA000626D70404F098D90299ED662F52E07FE06
+:102FB000B4FC3556869ED212D7D0562EEA89479C4D
+:102FC0007606CB299E9B270B85166C037ACD5F9DD9
+:102FD0009DC0C7874B845E1EBDDF8BDB23CBB76CE8
+:102FE000892C2FF147961731EF6FD32C881F45BEE0
+:102FF0007FB844C42316318DF6A1C5AAFD318BFCE0
+:103000003B0AC3FC9B3204FCE411E2999D58329FB9
+:10301000E839D1C6A00F6E30FC181BDA92C97E6C5D
+:103020004914F8F67F3ADFE879BE593256C0375175
+:103030008CD7C2E9D38017F1A1454FDA1F06BFD361
+:103040000CFC3F2A093EE95B672139CE5CFE7563C3
+:10305000F9778BD65928EEEBB786721027F16D8C75
+:1030600023FBFBB0A4EF445E96C4B414E0C95183C3
+:103070006FCBF75C52007EFD46149D54E9D2DB16FF
+:103080008EFFC5576D28C07CA60D61BA9DCFED455A
+:103090009B3F16A23F7AFDFC4F534C3F20DFD2CC22
+:1030A000555A19ECC63AFE7E08F850787BF25FD884
+:1030B00006E88AEFDBB60B3DDF423E4D2B16EB9A5E
+:1030C000F66BBBBF5982BD7478D76B9389FF137FB2
+:1030D000AF5F15DA897C94BA0BBD32F2248EDDFE27
+:1030E0005E99A4B17EB9F1C5CB42FF9BDC1246B715
+:1030F000F89F0D9174CCDA92285EC73A22DFD76C24
+:103100008FFA8EFD973D7C9EA69EB3D9E61D0F3D9E
+:10311000759BA7A000F3D96C6D2F075FE89AEA4D65
+:103120002EE5F51F957A0ECAE4D7758F053FF9DDB8
+:1031300077CDA467F87298BA83F2317A67A05CF011
+:10314000BF6409EB7C1D7A7C989FC9D4834DFD2B0D
+:103150009A1EB552A1374D2C75EF829E7BD977BF51
+:103160007763BF9BF74A2AE9C7AEFDC1E19013BC64
+:103170000CFDB85EEB3D88389ABA7FF9A984115CE2
+:103180002F7565935C60198CF4E7FA0E51CF7CBC07
+:10319000FE9281B8BAB2B7A93C9BAFCFBAA7C98398
+:1031A00075C24E811CB0D650920FE28E849F9BF95F
+:1031B0001C40FF939385BEC63150F80F6DC2DE48A8
+:1031C0004909921F17195EC0BF8B4ADDF3B17F1FFB
+:1031D000E315D723EE9AE29E8AB2D7F0637D0DBD48
+:1031E000E302C67A0D3BEBD09FAE22BDE26BE62137
+:1031F000BDA2B054F0F743FBAE49E8CD1D78FF897E
+:10320000C57B9BCAE9FC16E6233EBD84F9E9C93AB1
+:103210008688FD66DE32CCB7B682EB5689A20CFFFB
+:10322000749DC7467E7ED06D308A6EC3CB8CD36DC5
+:10323000300C5F6A959E56D20BB94530640AE2D5D0
+:1032400091EDEB5988F8CEF23DDFDB23FA31F0281F
+:10325000D5B2228FFC19FF667CF1DF6D7F446B4F86
+:1032600081EB81CB7BA293FD469E4399C5E536E277
+:10327000F5C29F7F469E47A8B581EF77D134BBBA90
+:1032800086F40011CF3FDE6D65C03366D9D00A7F6A
+:10329000D8F2E1166619249EBF94ED424611AB3573
+:1032A000F242FF4FF3675697F6E7CF64FD6FE6CF24
+:1032B000B49686E5CF44D3D5FF34E2F6AFB84E0DD1
+:1032C000F186D517E5FAC83F515034383D7618F4E9
+:1032D000186BE45539141F0BF7EF9DEDBBED061E7F
+:1032E000BF620BBD1B986CC43F90B72B8BFC2DD9D4
+:1032F000A12635A5C30FE17910F4E1D04CFF03B747
+:103300005B93C947A6C26FE7D002791AECFF5A97C0
+:103310000E3B3436972B20BC7E21CB21FFC9CA62DD
+:1033200031BF7E3C89C21F4967143F83BD8F7E87B2
+:1033300073B311F6974D0EEC425982FF8ED3CF76C0
+:10334000674F16CD8B6FAA88AF7AC9FF071F0BEAAC
+:10335000EF4934ECAB3C615F713CA73237AA554171
+:103360006F3DBD900B771538280FD78443AA2CE208
+:10337000AF67D30B53B91EEB4AA2278B4BA27C67D6
+:103380005FDC0FB437F94FEA8406F267A4CADCFEAB
+:10339000CB23BB91ECAAE1965B0B699D8B18BD1FFB
+:1033A0009114B815EB1891C4545A774C7081880F5A
+:1033B0008A72BAD25048FE279DA94D5307FA8FFB57
+:1033C000F0993CBC8F1B69C0CBD693053FB6ED3658
+:1033D000870EBEFEB752CF9F4BC9FE769F4FF94076
+:1033E00006DCEB0DFA0AA35B1FF1EB28BA85BF0ED2
+:1033F000762F6BB793BE47A442E574D2FF3F409946
+:10340000CFE797533D874B497F35F4857B26927EE6
+:10341000C51A87107F5D1B27ECD0ED52706B385EAC
+:103420000DC0CB47F32828EA217B207407C7C3B01F
+:10343000FDC934F03A64F879FAF1DA28EB65EE2F39
+:1034400031FEE4C9C10791AF58CF957CEC737DE0A4
+:10345000678FBD994CEB6DA032FC8D58A7C745FE18
+:10346000B6A985DE6FC5BC7B5BB1FECC645600BFE0
+:10347000DBFA9CB96C918BFC78DF037E5C9FD8896A
+:103480007E387D3740CE1D9EBB94F2580ABE2F6E0B
+:103490002D17F355A16F26DB855FD79CDFC832411E
+:1034A0005FE673B891E7788C73E9C22C8CE75E40D5
+:1034B000FE6DC39F16ABF5B8699EDD42F92A80EC1C
+:1034C000C07C7F9141F0AEEF2ECC831F83059C79A9
+:1034D000685FF03717C1FBD8EDC3C89F34A1C49B08
+:1034E0005C06BC981C92B07FC7765D913718BF4EC2
+:1034F000B52431AC23D5C202F7AA03789062F32E2B
+:1035000080BC5898CB45219FB2CDC8EBCC34E46A3F
+:10351000E62A0F5BEC1A28BB92C5BEF0F732C699BB
+:10352000585A6A435EA8AD4CA1EFCC3C148DA96BF0
+:1035300058D6997492C544DEC95D461E0AF385E5E6
+:10354000CB649F998762CEC7FCDECC4389FD46D809
+:1035500029D9AAF0ABC6B51978BA8A11DE4E0FF593
+:103560001427F0F58EEE084E87BF0FE986C04BBEDC
+:10357000EF775DC0DF270F51A6439E3CD898BF1F51
+:103580007C4B59D77309409FD5C164B894CDBC40DA
+:10359000FA4B86BF2B51E0B7D29003FBF2FA32C14F
+:1035A000DFA616BA8B00FFA23F5B453EE346119FA4
+:1035B0003A9D5878641FEC908D7194877636BEE101
+:1035C00063FB292F351B79622EAC43F8D5D8688E62
+:1035D000107CBECAC6BF513C5C59F7A71198CA4FB0
+:1035E000CA5C342EBE83BD17B7C12263FE8BDB24B9
+:1035F0008A4B834323EF6E715B7211BE5BDC2EE955
+:1036000098F6E22D8532F2ACF887A47F8DE95065FB
+:103610006F987C5866ACE7F7DF59281F4F76087F14
+:10362000789D96D469117E10A2D3BA51C99DB00B72
+:10363000161BF8AD74CCF1A56B03FA9BD95F5DF74F
+:10364000AD2C1C0FA3F9CFEF15C17F7ECF31BB5D31
+:103650001FC0BF16AB80B7EF5F32E17FA6215F0FBF
+:10366000DFFD6D3AF5D7EFFF13FC50B16AADB073D3
+:1036700095A6DE4B01E7EAF644B93E17FDE8F5A44E
+:10368000FF6E8C65B05732378CDA8F3CDCCC3695C8
+:10369000491AFAABCB841DEC7BCFCE802FCAC6581B
+:1036A00082A3B2C90D2C624A620AC14FB98F9779C1
+:1036B000FBB232917736DDC0C71629649C7371E77F
+:1036C00041DFD6CBBC6B810714EF009C1B63847F6A
+:1036D0005FE9217A7DB0A06704F0E7411BABC17AB6
+:1036E000F6DF7DDE5C9177AC48C09738E43783AF76
+:1036F000BF9B4A7AEDBD067C07C197E1842F2F5B03
+:103700003CA047C5C83351D6717B310B79DA5ECA0C
+:10371000D39EEEEB290659C1BF5CA8FDFB72A03F0A
+:10372000BEEBF645E4BDECB7AAA4E79BF916D1F3CE
+:10373000DB69CC5B97455E36DF2727E8C58C67DD04
+:103740000FBB6F0CF2B98CFCAE350A43BED7FDB18E
+:10375000BFA4FCAF469F5D453EF13F9C23FDF0DBDF
+:10376000A419F659E8EF71FE2EB26F7CB20DF5B2D6
+:103770006377B85FE819037F1B158DF245D81BC22C
+:103780004E3DA5083FEEA9552AD903C9316F515EB8
+:1037900081D6C4117624D6EFA6BC346673D0B901A5
+:1037A000B3BF24E43984C541930CFDEDA52456A292
+:1037B000E60FBC7FC558EF5183CF232F80F8BB4B5A
+:1037C000E4FD0CC477F577DFE2EF2D6BCED710B7B1
+:1037D00037E3BC96F8020D74DFE82AD0103F7D2253
+:1037E000D1FB5659D8BEBF149F5604BFD0FF0FF36C
+:1037F000BB8E609D6F18FE8D378EC7C859DCFE4AA0
+:10380000427ED010D801FEAD3743CE5EED223B3C68
+:1038100009F94143604F34FEE71D7C9DC3DEB05281
+:103820003E70710D9720BCDD30E40B65211F48C050
+:10383000C5F7B285E032ACDC4DF94049C807E2F586
+:1038400016E4030D413E5090F2283A9A2ED07CC9DE
+:10385000C8071A2593BFFF4D0BE159479EB6B53AED
+:1038600019F1B65CC29B5F49065FAA64221F284E0D
+:10387000F8C53A16338AD3F4E703D569945F04BFD9
+:1038800029E141033B8BDF54E825A11B99C06B451F
+:10389000E49F7D3145257BBADF6FBAC066FAA1850A
+:1038A000BF617E8EF0AB5A248A4F8616C4F88DBC59
+:1038B00021B1EE31D9C23F63C8AD2F7E92447E6BF9
+:1038C000939EBF30FC4BBE9A18A35D281E7EE96D07
+:1038D0008CED46DE5AF3146D1FE23F5F20AF9CF67D
+:1038E00035141FEE4F3DD7FBFD56773AF1D53936EB
+:1038F000F24F733C1DB50170D09D79E4FF37F2F2B1
+:103900008A8C2972FA54EE057DBAD3743ADFE7281F
+:103910007587C711A2F16666145DCE34E8323AFFAE
+:1039200068F6E591F94766FE8C593FEF7241AFE6C4
+:103930007391A1C799F868B6BBEC72E12FEC6F17D1
+:103940003B78BB92FE76C6B8768E5FE043467E40FB
+:103950004592E08766FB2B8D769551FD46B79BDD42
+:10396000DFCEC88F6A3E8B5D67F0A1970ADC4D976A
+:10397000F3796CCCEAA1BCD48D92B013CCBC09E035
+:1039800011ECA68D52FB02C3AE5245D9C8AB70985C
+:103990007910222F626B8AF93D67F9F9F40C228EB7
+:1039A000B4D1D993063FC240FEE345C4578BFBF325
+:1039B0001F755ABFAF49AC5FDFBFE73C9CCB7BE5CF
+:1039C0004E55A3789191B764E2410ED30E202FA3F8
+:1039D000C22DF21FD916ED00F2B65E918C7CC42880
+:1039E000BC30E552743E92D4B6AF05F931A0BC1993
+:1039F00053C2F392A68CAE34F4B970FC2B7219F951
+:103A00004F2E7BD07EFE20E39C239FD19C47B45C4D
+:103A10007D293F95E42A27B140D29401FDE61DB4EB
+:103A2000E3F0FDF872CFFACBA1375E3BB585F4B673
+:103A30000AE12FDA2F73FD007E389BB0AB6CD70CF8
+:103A4000EF6A0ED3A34DFDE725231EC4D202BB416E
+:103A50006F1392B47CD8BB489506DF79A27B18E936
+:103A6000ABF71B7833410AAC481CF5EFC827B7DC2D
+:103A70004772D46AF009BD17F9B31FC639C80FD30E
+:103A8000A8F85EF38A7EF2111F5C394637E493C8CA
+:103A90004B6AB6068EE2E9BB9369C8DFFE6F2C87DE
+:103AA0005E04BD34FB659F95CB9F66838FFDE3EF7E
+:103AB000D72A80C349DFC46CD84D66FB4306BD9648
+:103AC0001AF2FB95D57BB62B617EEC6257A1027B87
+:103AD000A9D4A52BA0D362D71C057EC452354F6153
+:103AE0005C4FBC383EAF8CE24151FBCD14CFC4F0EB
+:103AF0003C4D739FDFB9DCFD16E667B63FDBFA4D40
+:103B00007BDA66D397E25C21D74E1B108FFB13AA9A
+:103B1000E037B18716822E865BE2F566FE7C37764B
+:103B2000E1C1A17C1FBF55BDEFA3FFF9D75ED18ACC
+:103B3000B2B47F88B682CFE78BCADE02D885ADAA41
+:103B4000B717F5380F9AC251E9B6933D744E927982
+:103B50008618F69467E260E7D8CCF91C30F07D4C0B
+:103B600082F708F07DBF1C8AD3E9DC883A92CE83C5
+:103B7000AB625DFF69D0E93EABFE5D88CF7FDFA61B
+:103B8000CC3CC4CF8B62FF7EFD72D8E1F7A7E6C1C3
+:103B90008E33E15264D8738B654F4AD01231DFD334
+:103BA00018A7D65599992EE6BB9088D53154F8635D
+:103BB000152DD71377F6F9364BC1C799D06FC9CFFA
+:103BC00075130207E23C3BF1CBE71997CFFCBD5DD3
+:103BD0006EA6FCC450A54387FCFD830167C6C4F7ED
+:103BE0003B1C2C09F4E8297A81FC3C0FD7BB74D824
+:103BF0005195880B59101F72939FF6E3C26F5FEEC9
+:103C0000E5EB4A2AF7C695F3F16F1A228FFC13D120
+:103C10009BF73CF813D97401E773ED7B0E94483E93
+:103C2000EEDC9912E9078B0DF8CC631E3AEF7A0DA2
+:103C30006B30CE016BC7EB93E9FCAE717E439B8882
+:103C4000F92D6022BF2EFA3CF042A6BE8CF3AF7F66
+:103C50006C4AFDE9EDBCCD5C3934D216766E96C364
+:103C60007B743987F7E952717E96ADAA1C47FBDA5F
+:103C700031F447E1EB1C49C08DF3C35CF453346469
+:103C8000520B1DA24570263D9C3E7A9B13F83CE7E3
+:103C9000A464E5C15F73D9776A06D65BC654C9923E
+:103CA0003780179C21C7A79BE788F9DFFDA7E2595A
+:103CB000326FD7936D21FDB0BC709F0BEB2AB5D44A
+:103CC0000EFB82F7D7037B832CBE868C6EDE6E568E
+:103CD0009A85CEB1BCD6E46D813DF6DA7849E73CF1
+:103CE000815D913C87CE6DF6B0CF5A96E0BB2976C8
+:103CF000D547722CA84CE6DFCD703BE89C51798605
+:103D000075C09FCCFFBB727464B92237D2FFCC5808
+:103D1000AF02BA9CEA75519C7BD639FCD173CA8D2F
+:103D20007B0426B009880FBD12E58F2E3EB73F7A7F
+:103D30003EF0ACFF1C99CA2D3F3EFECE4B8674412F
+:103D40004FEC99FECAC580CBA9BD59C8C46337548E
+:103D5000087E7757B9C78BFDA9B7F52E04FC3E5CEA
+:103D6000CD071A077FB883B9B922FEC96A95CA9FE1
+:103D7000AD4EA3E7E7AB357A1E5B9D43F52756EBC7
+:103D800054FEB8DC5D83F135D6B005F6DECA268573
+:103D9000415F5819B74294AD0E15426CED8883729D
+:103DA0002C2FAFF50BBFC6926E7F2B96BD6CAFDB91
+:103DB000869CC19523928A5D687F9F382D7AF3A1F6
+:103DC00086834093FA3F7F340BE867AEBBEE1B89D6
+:103DD0007939090DA970FF0CE37EBA7A0ACDE7C8DC
+:103DE0006A37CDE7E8EA727ACA577856A1BEBE4D67
+:103DF0003A80739D339FEC53F02C754BE4F7B8D4A5
+:103E0000CDFCFE2C9C3BF17A412F5BD21D941F5AB6
+:103E10003871EE033F61E0D3DE56C0E7EAA445A562
+:103E200043B28097E21E80CB6E90F4A03680CFE73D
+:103E3000A2078DF59C80DE70DC27E0F24EF73B5444
+:103E40003EA970B8F0959EEC8E25BDE0E4BB3164D0
+:103E500077B064FDEA8B79D9FEBA888F8C567FF9EA
+:103E6000D95B04D77892E35CEF25BEF0D27A11DFFC
+:103E70003CCAF70DCE7373DCA34FFD2C2D3CEE70C6
+:103E8000342970FA3DF0B5BFCBE6F9E6C32FF2F264
+:103E9000F32D2AF18B13D6C02790AFBE110ECAB3F3
+:103EA000AA47FFA09F0FE42EE8094763C478A1BF8B
+:103EB000C6D079867E3BF5DD98CE487DA34187BC90
+:103EC00033ED607BE6CF7523DFF9B54EE81D192E83
+:103ED00043AF68A809CF775E6B0B1C855FCDD72AEF
+:103EE000F48AB546BEB3EF2DA157D80D7EF2DF4060
+:103EF000AF7815F8D088FDC4FAF97E420F3EFEBBBC
+:103F0000A624789824998BE84B185BF1EC79A97476
+:103F10003E34237950FCC07E69E306CAE377DFF2C2
+:103F2000E1CFB581B27DD7B3E7FD2D9960AEC54E27
+:103F3000C3FAC5FEB0AD36DA9FF1BFFDF5E7EFF18C
+:103F4000E7E3BBD6C55CCF9F1F950B3FC93FFE9EE5
+:103F50002A4D001EF99C1AE27789EAE0F1A97BA0BC
+:103F6000DF8C1928274C67D262DE2ED11562A4DFC0
+:103F70004C5725E83789B8BF82F39B8B2FD5CB28C8
+:103F80008FC5C0E7C31B9F1F8EFD19C7ED30F0E939
+:103F90004577BF30FC053EBF47B96C46FCEE25AB0C
+:103FA0007E620FF6F30107E5873DBAB12E1F72A6B8
+:103FB000FA570BCAD2C1979E63740EFBDB72A1C77E
+:103FC000DEBC65D7AFA0BFE6EA4C477F176CEF9326
+:103FD00087F1EFF21E919AF19CF4649685AE494800
+:103FE0000BFC1C743341663AFC5AECBB878785CBCB
+:103FF0007D768516E15F3B6F44F9219C5FCAEDF841
+:10400000B268180BD7A363489E9E97DA9904BE370F
+:1040100031F3B9CF9B40CF463CF5C297AF7EFD62EE
+:10402000067DDC97EE20FF00873BE4B75FE4141FBA
+:10403000EF1E457AF873B28FF4055F155F27E8C06D
+:10404000E3A3B8481D6F8FBC8BBABC9E3E9CC7A92A
+:104050004BCCA67B6E3EF3AF247DE322AE87609D02
+:10406000F5DDF7950DE3E5E3D3992EF1F16B9E3D78
+:104070004571655C8C023FE3F1EEE694EBF8F7776F
+:10408000E516517EABC712A0F1D87231DEF2BDBB8E
+:10409000E83C13520091779AB8B7F095E1B40EBF9F
+:1040A000C8CBE8BD3B0BFE87A15E6E7FF1F65BB22D
+:1040B0007CE9B0EF4CBD26A9DC937505F450F55EA4
+:1040C0003A47F1B164C4D77EA47E62931B28DF9483
+:1040D000A5097BD3EC77841CA473FD9C4D50BEFED8
+:1040E0000E55C41931D23D34AE37EF0AC4512C9568
+:1040F00064CF0EB70B7B94A95751DEE78F1DFFFEEF
+:10410000D8FF22FD77B91C4FF7A998FAE3FC21CD1F
+:10411000748FC9B844EF251867B1A1973145D7A06E
+:10412000C7D812DD975E41FA2FD77B64D2778A50C9
+:10413000AEB7707D7854983EECF871FA8EC6F42DC7
+:10414000F037F6CBBDAFF323E41E5327BD0BBBEA1C
+:10415000E3389941CF6107E4DA83DCBEBC04FF9603
+:10416000C3ECA6B87CE21BD04D065BFFEF38DFF056
+:10417000725805B97CF68E43A39E66C443DCFCFFEF
+:10418000E3F8BE5FFA8DCC0DD201BD22FA7B0E772B
+:104190002FD659C86223DAB95922C583992BE9472A
+:1041A000AE37F870A49CDFFF70F87AA79F7C3716B3
+:1041B000AA2B87432A9E675BCFCBC67AAEAEF0AE02
+:1041C000B8228C6E2FF94AA5FB72F87C6FC3FB4BAB
+:1041D00015CECFC3F3694C3CF991F3FDA924F23F0E
+:1041E000D99736B28FF71A7EB5BD4B72293FEA399F
+:1041F0009C5B14F286F8EBDE38E17FDC3B2785FC24
+:104200007E2F99F18B4AE17FDEEB14F8BC375D55C8
+:1042100091A33ECCCE3EE906DD5A12481EF4F73F8C
+:104220005415DF9BFECB0562FC8E39EEF498643C9E
+:1042300053641AFFBF2CEE70BF5FBF3F332F78DE91
+:104240006FA95D0EF92B8759441E266BB61BFECA5B
+:1042500015AF4F9C0C7F672CE94B1D59FEB66C9433
+:10426000EF1845ED1B59F0D794C711B251BCE49C2F
+:10427000E7172B2D91E7172B2D51E7177D71D03FB5
+:10428000FF6AECE7BB8AB0ABDFF5479E5F7CD7BC2B
+:10429000BF42F1C585DBBFE77AFF5E949FD1ACEFEB
+:1042A000486C1F8ABC9CE015DEE7810F0B16EF708F
+:1042B0007AC3E210BB1C9E1780D7DB62F459D7800B
+:1042C0004F570BFBF33DAB886FF9FE2913BC7E57AC
+:1042D000FDEA22ACEB77A134161EC734F1A43F2FC0
+:1042E000769568FF63F38C1F720D9E675C3E579C4A
+:1042F0002F3CB94A36F362459EF1B376D3BF2BE625
+:10430000F7F244C20B66C4DD1F0A0C25F91434F21F
+:104310008E1F5282C397037FF63A093F790F4EC82A
+:10432000F91332DB0D7DF02683EF3DC4B404C2B334
+:104330004316DAEFFB63E3A9FF2FEEE0E3F372B07D
+:104340001FFE7ADA556172B3D9B877EC2166E415AD
+:1043500007FEAFE7219F08A7EF33F290CF0A6F99CE
+:10436000FCEDA1DB2D863F9DEB58BCFD430D230CDE
+:10437000788B384F88F3219CF7658AB84FE0212568
+:1043800087E23E17C33807BCEB2403DEFE756331BA
+:10439000AF97C7101CCD3CA64FEE903B019F13ABCF
+:1043A0000E176CD1F03D3B1FF7FDF8BAEDD4EEA12E
+:1043B00028FC7EC880A3D7F0E7B15F0A3DF903B5BA
+:1043C000372E5C3FFDC0F3491CF8DFFB8D96A0ED56
+:1043D00007F2956FD8F2E9BF90AF7C83C7D6877C90
+:1043E000C9B3B6FB655505FBA17A23EFF986DAE878
+:1043F000BCCAC83CC9E22BDD23AFBC300CFE9FC950
+:10440000678D6710FCE364335E41F8F4E267C3CC68
+:104410003C7011AF38E232F6271044BCEAC5EE2CEE
+:104420001D72AE1FFE5BED543FC047FCB173C2E886
+:10443000FF4545C0F3457F64FEF78B86DFAE1FCE98
+:104440009FCB9447DFACEA8E70386FBBD03BED4A10
+:104450004EBF6B5CF90EE4F1D524141D823FCE7B78
+:10446000A5F752BC977B4F94C18FB99C89385B5D8F
+:104470006E7021DD2FB6EAC7C9F765317BEB71DFBE
+:10448000C4E77B773C87279F8F8803ED16F2C02B0C
+:1044900007E38D32D92BCBF83F2F4DC2D36FA379D1
+:1044A000BB59C3DAA967E6EB120B4911ED851F274B
+:1044B00060BB3819F96E4CDBA6E2BD6DA03DF98FEB
+:1044C000FCA41FF2F62BA0A72D4BDC73F7C5FCFD57
+:1044D0005297CBB12AE9CC7D5EDABDB667D4F967D5
+:1044E000BE3F731E629D4A7C4F19F6ABEF2E898149
+:1044F000BEA63516B3C39306FC5AEA948683B07BF6
+:1045000016F389AA5CE254FA7ED68AF28E86781D6A
+:10451000F1EB35B123CBEEE4E51A4F8C8E7840E514
+:104520003D9BE8BB697B051E4C7B4CF20F963F52CE
+:104530001978F46BC485ABA2F26DAB3744CDF31C94
+:1045400079B64B1FF9DE1E99772BD6B5D85887C59B
+:10455000378BF8C534C30EFF084DA6226FD4B306BF
+:10456000F430ADA350D42B428FA963220FB4CEE117
+:10457000BD8DF6D1C1D4CB79FB4371365ACFA92D6D
+:1045800009E47F3A65D0D1A9EDE2DE2B338FBF6E0F
+:1045900088785FF78CE4875FA1CE5249FB57B7520A
+:1045A000E483214FD41D365FE489869759BBE98F98
+:1045B0000DD2774B1B9888A3F0FD7347E441076D3C
+:1045C0009FF171EA7D52605BA2C81F8DE8C7F0734E
+:1045D0002E6742BF471E6964BD9FEC8587ACC2CF82
+:1045E000C9C95E1567EF428FEFE4F35EF9F7CBB709
+:1045F0003AB2C3F49825D6B3E93182DE373989DE81
+:10460000ADFD7A8C7B2CCEDF766C1AAF033EC32CCB
+:10461000863D305CF8633B86EE7F9CE2ACDCFE605E
+:10462000791477F521AFA563C904E31E0683FEE77D
+:10463000DBCEC2A7768B7BE9EE93FAE532E4C47554
+:104640009B524DB92CE6B5D1C83750DC631D543FA1
+:104650005E37E2AEA27E288BE65343C1A7606B6350
+:104660001FAE33CEA95C17754EE5BAFE732AFEA1C4
+:10467000E1F1D373BDEF4874A727E552BEF71FAF32
+:104680000C938F1D897E27F2B659CD8F8B0FEC309E
+:10469000F41013EE1F49226FBC3AC6B3FE32BEAE11
+:1046A000EACDD9D9C0BF0FAF147EBF8222B11FBCE3
+:1046B000BD4EF0708BFDF808F61F877F75B67B2C1A
+:1046C000F21BCD7CD30FF2841FDFBC4FF0A8D1CFFB
+:1046D000D12BE588272B11F6F0474E81678B2707F2
+:1046E000ADE0B33B349137586DF3FC8F4BC2E6F32A
+:1046F00000F00DFBCA34CA23FCDAE8B75A96DCB0E6
+:104700005BAB7F6527BAE1F3A0FD2F582175C1DFB0
+:10471000F591112733F7853171EFC8757F184AE796
+:1047200016CCF3871C5F29CF8AEB93425F3E1BBEFA
+:10473000727C867C4BECC757315EC782B1847FC3E5
+:104740002C02BEEC9E38D14F69513AEC34E407FCA0
+:104750002FB42BEDCF0F20BFD739F5EC25D64EC0A7
+:10476000BD5FCF5E62ED1A0CEFFAF1E5FF1DDE656D
+:10477000CD187A76BCE3DF5FF8437195BAE79F7A8C
+:10478000CEC7E7B9F4B7F7C5C34F7444694FD179C1
+:10479000BFB53BEE8C77F3E7678A2F1EFD1DF15BFB
+:1047A000E85C70743FDE199271AED41D8FFB87CD2B
+:1047B00078EBE74F7CDBFA73BE2FA72516821CA986
+:1047C000EFFE67EBCF399C0EBA1D21C899CF94DE5E
+:1047D000B25FF0F2924A574313DD0F13952FFEE8B4
+:1047E0007D299AB81F73B8384715A4FCAAFA47ACBC
+:1047F00074EF5CFD9F2C3AD064390BB5627ED1DF3B
+:104800002F0F1CB6012F549985322E3EB31E06156C
+:10481000FC08CBBBEFFA12FEA5E5DD47DE83DE1513
+:104820009D775E63F82DA3FDFDB36718FEFE8BD860
+:104830004590C71C3E3AF4131F9FD718B1FD84D78B
+:10484000CD8F3FFA34FCB447DE4BCD435ECCB1474D
+:104850005E8FC73971D3EF6FC6478E05462578073F
+:1048600081AFF93C11E51F36F9BDB64712973EEF0F
+:1048700015CF5A6B301EFA476DA755E73BCC6A9FA0
+:104880007A78E736E0FD5FED74EEBBF6A95336F0BB
+:10489000D95AC91D92283EC3E2A5B038F9B2A73E45
+:1048A0002EFB35F493740BABE0FBB6F499AF457B6C
+:1048B00037375878FB65BBFACA70DF4EADD7D5E005
+:1048C0001864DF8A03FB6CBDAE41F62DD057467EDF
+:1048D00091C7FF41FB72E477124BCD3AF3FB9A1D6F
+:1048E0004749DF3AC63748859C0B582A6D0967B699
+:1048F0003BF6482CD1F3B1BD12E5999E6B1F2F9862
+:10490000C10C7C8F63B8AFB4E63DBBBF02FB7BF745
+:104910004AC2FB4F950681F70FDC9982FB126AAC05
+:10492000BE14959EE27DCD833F35F0D19D8EFC4E29
+:10493000CAC6E0EB5ABCFD6A5A57CD038B685D6C62
+:10494000ABC42EE45BF135D787770DB29F7F32E899
+:10495000C5CE6E3D1FF4F135FF047ACCA7463CC0AE
+:10496000F747911F65675D1F401FFDBA67A804F9EF
+:104970006779DBEAC07A7FF27222D9398FCD10FCD9
+:10498000BAF8EDAFCB40573FC9521A8C7B107D0669
+:104990009CA4EF853D4AE7B1284F301BFD9EB4DD56
+:1049A000C8DB7F05FD548F684F70FAB4CB1E83F3CC
+:1049B000369FA6887C48FEF74706FC107DB1E58F40
+:1049C0007D7A702DF0296D949C9086EB3B05BFE7B6
+:1049D000EFCBE0DF56AB5C0D091C3E5FFDE9B00D8F
+:1049E0007E515FB2CC703F5FBDFF4B1A9737FF120D
+:1049F0007861C263F99EC87332CB1FF9388A6EA3FF
+:104A0000CEDDB00682DB72964071944F6D211BF8AB
+:104A1000818F8F8BB8C3CD1D61E772D0DFAACF0C19
+:104A20007CB00DBCCF1AA03B333E778B41E7D1FB66
+:104A3000154DF76F45D1BDF93DDB3E781C6980CE41
+:104A40007DB4EFB556E653413F7FB5935CAADD24B4
+:104A5000E891713E3986E3FBE10DAFA4E09EDBA354
+:104A6000016B72058D1AC9576B767F7C702D6F3F75
+:104A70002CCDC29CC457FF6183BD9656CC42763E76
+:104A8000FFA3357E09F90C67D0257F3F285DD6B09E
+:104A9000FFBBFC946DF812F6EF00DC23E9F096B34F
+:104AA000F0D37FCE30CEF31870FD9AE526C07FCFCD
+:104AB000D4CA4CF21346C1D7846B345FBC6F8626D0
+:104AC000FC9B517C91FFFD8585C191B15EC2E3D312
+:104AD0009CCF411F37F1977905FEF2B26D18D69B36
+:104AE000223394EBFDFBE6217E72E6BA23E1195DE9
+:104AF000BFD7E03B9E17441E7AED5EC9385FE523C1
+:104B00003B6C39FCBED4BAFDE0F0E4F0B23FAA1C25
+:104B1000886AEF8E2A7BA2DA7BA3CA0D11ED6BF7B0
+:104B2000BC621387108211EDEC8D33C8CE3A535F0F
+:104B3000F00B3AEFFED2E6037E6484E8BE88228B57
+:104B40007E288FEFEB8CB8675CE02F669E4EB34BF0
+:104B5000E451BE9696D565FCCE02F19162838FCC6E
+:104B6000AB107CB099E5B7E0BC938FE333E8D78E08
+:104B700093A9E07B19163AE7CA14AFB292978B1645
+:104B8000D5521CBE2463D1815DD8A7297615FB526E
+:104B90009C31F3405E32F0DF11B2F37273C62487AA
+:104BA0003648DCEF95263DA36190F7E6B3D8F1E6F1
+:104BB0007CF81B4A5C91FC664614DFB8428BAC2F34
+:104BC00067BB93A1E796E75A19A73C5686F661FCA6
+:104BD00054AF10F7D25CC1DA5B54417FB4EE4B0C9A
+:104BE000386728790AFC1D25CADBAFC0DE29FC8A9C
+:104BF00069023F04BC8BBFD215C0BBD095A8883CCE
+:104C0000FBD042E81916395EDC6FCECD2DE4553766
+:104C1000231F2F0FF7A07BAB2B282F49654580530F
+:104C2000110B408F97F6BEF64F11FF6B9041A7E333
+:104C3000B61CA4FB01C7395C41BA1F70BB722CE2E1
+:104C40005EB1A8FBCD6705769D801E336B5E2CC5DB
+:104C5000B966B1C05BB8BF97CDB3507CB0EFE9384F
+:104C60001BE27B33035F2AC0B399D3250A83F7394C
+:104C7000D591B7F279575A441EE5CF0C79D1EC148F
+:104C80007A7265EB88B1D9FCFDCCB3FCCEC2630669
+:104C90009E6436EB69C81709494EB56BF2407BF448
+:104CA000837E9FAE10799E6B2A845C34CB99C5C2FB
+:104CB000FEA96EB3F78D8AC7D31A1CC79F936617D8
+:104CC000B5024E15D9ECA0B0BB240DFA7B9F53F86A
+:104CD00085421BB3C89EF0F22DC5BDC9AC7114A3AB
+:104CE0007516EA369C5BEFDB94A5220F2A36D74D6A
+:104CF000DFDFDC2ED1EF89F41532618FC4D9C88E85
+:104D0000FB405547A2FD0769A3282F25D3B26F3476
+:104D1000D96D79C26E3B39D3BBAD0272E83BBEDEC2
+:104D200002E40332017416C801DFBBEBBA18162483
+:104D30003B40A77B9977393C0FA1FDE1460BC5119C
+:104D40000ED7887B75FF5221F85EA625389AE27649
+:104D5000AAC8177DD0D6BB00FDFDD223EA2B92D482
+:104D600002E46784EE74328C5F99A42E44FBCAD6A9
+:104D70007114EFAC5823ECBC754A80CEB9F9DD9ABA
+:104D8000ECE3F8F30BF4CFC7BDA149F1E07EDC0CF6
+:104D9000075370EEAE76B6770DE63333D0F401CE1E
+:104DA000072CF2093B7CD1864D36C8C5524B2E9D4F
+:104DB000CB35EF01391BFDED5C2DCE4C3CB6DA4115
+:104DC000CF275673BCE68AF493ABD3A8FCF46A8D64
+:104DD0009E81D539F47EF76A9DCADDABA750F9B93B
+:104DE000D56E2AEF595D4ECF17577BE8FD6826D662
+:104DF00031B2519C5334CBB66A5E4E473948E71204
+:104E0000531C4C4539DBF87D1495D3FCDA74DC9FD8
+:104E1000EBA67BB2152FD3F0BD0DBFE4C0EB6380D2
+:104E200032E9808346793A195ED680FA11801B2FC9
+:104E3000DB4AC478E6BE30A39F07EB9846F159A53C
+:104E4000773CF6B7D4726CE345FCFDC91A99F2E6DB
+:104E50004FB2DEA79EA7B28BE23F236DEC04CEBD1E
+:104E600073AEA1594682EEF5343BDFCFCC5F966737
+:104E7000811F5CCF0D14254C8EDED8E0A45C61B39D
+:104E80007C53636244B9F522EFA7C0FB1B57F53D85
+:104E9000F03F79FF1FFCF2938F1FD5681E3BEEC7D2
+:104EA000B8AB6274DC8F7F12628BAFE3648B95ECDE
+:104EB00062FC85DF335879C7041BF203FADC0E5D10
+:104EC0005281675A19CE03FBB87E807B42DEC37ED7
+:104ED00072F8BF6FECA7B3FD1FE497EB33FC76D1FC
+:104EE000F70D4A33B3094E1FFCFC5BE1FFB73A54A0
+:104EF000E421F4D524C56B420F8DB897B5CA172BA2
+:104F0000EE776CB188FCE0E87B1175C1173F045F58
+:104F10004C147C12F7A87A83821F7E78478A0F7A16
+:104F2000D487B7C6EBC854F2B6A5FA6EE1E50DB862
+:104F30004707F27C2F6BA57C6559FC7E03F3592350
+:104F4000F9636F4622F44033DF3876B29FF4738EF4
+:104F5000562AECAAAA9CFD74BF056B9754D85DB87D
+:104F60006FC99104FE639C2353BCE3E7E1FCCD4C85
+:104F70000BD1D5EC99E29C5EA691473E73B2F02B23
+:104F80002CF18FEBB284C5716A67178D9819CED753
+:104F9000E67D99477687AAC909B877AFC85D867D4F
+:104FA000AB28D256E09E2ECEE746CD445EAC652FB0
+:104FB000E1E5494E07B8BFE124EB11E534E127B440
+:104FC000B16E81B7D5228E9FE1307E2748177432AB
+:104FD0001C9C909795D1A2FCFF8A5E176A821ED313
+:104FE000383DAE15F444BFD7115322F81933E6917A
+:104FF0003D5EF8B94CFAB2B615CAF05399FCCEC969
+:1050000074D247AB3788FBABAADBF36C3787C99701
+:105010002AE3FDA21C710FBBF97E81B11F9B6DFEBF
+:10502000A634F8398D7BB450C67D3A9B97BA937DF0
+:105030006CA0FD95C6BE353B3D75CF824E9F8A253F
+:105040007958D97AE3CC0BC1579F1E42E7FC3E9FAB
+:10505000B58BF260AB5A16FCF4CFC0C3C79CF4BE4C
+:105060007AA67719E8F173495BF82CEC015FD63525
+:1050700017F2EFD3B0C9E45711F7C66D5E5F48F77A
+:10508000D071E4B7816F98F3AECAC96F45BCB86AF6
+:105090004361B220522FE56D342FB84E815FF44644
+:1050A000637EB36732617F187213F7DBC0AFF41908
+:1050B000320F08AEC2DFF6F913BFF90472FEF4E353
+:1050C00071F87919B6F40221B759AEBF40DC0F155B
+:1050D000698F94FCE638E9D1C7B9FE46F667F761F7
+:1050E0001BC5AB393F043E2EEFB6F4E17ED168BD5F
+:1050F000F8C0D37F8B1FD41EE9167E9473D923A5E5
+:10510000C6EF532D7F41E8D3FDF6A4F40DD9EDCBC6
+:105110005FBE33C53B883E013BB83169B0DF0BF859
+:1051200071F64BB4DDD23E33D26E31EDC1B3C93925
+:10513000D36E31CB358DE78F827F716963C128F8DB
+:105140001BEB1B2F1D157EAFD171238FD42CD79D48
+:10515000258FF43FAC457ED0B9993F5AD3789ED184
+:10516000EF24EA6FB7A177698A9600FC39E91F93AB
+:10517000C07E609ECBB7F0C5E0DE2FDE1EFE8FB096
+:10518000F345A4F72DFBFDA824E0E392BDF7DA6414
+:10519000FEFEB399424F3B1E658FD53F7998FC23A5
+:1051A00075AC87F691EF2F7384DBE75B6C344EF4BC
+:1051B000BC96FD268EF2FB960424F70EFEFD32BB54
+:1051C000760FE87ED9EB57597D61FB7DC0C0EFE8D3
+:1051D00079BF30538B788F7932EA2770027994EC5B
+:1051E000B7B1A4CF7DB157F88F3F7DD2F230F4B77D
+:1051F00025815DF5C44F9F8C5591BFF5B935F29E61
+:10520000C31E63BC9E9986BF9C05A8FDD127632958
+:10521000DE86F9825F98BF03667EF717E3BBBFCCDB
+:1052200014FB5063D0A3D97E89ABDD46F9A52F5E70
+:1052300095BC06F3DAF34EFC68FEBED7F8EE8BEEB3
+:1052400058BA8F6949F7B7B35E821DD95D9C2C852A
+:10525000F1A1E333C53958E617F1A6E37B85BFB664
+:105260000EF0E57870D4F02F1D7D7A48A790E7FE08
+:1052700008F81CED7E265ECE1DD8BFE50E5FDBB8BC
+:10528000EC81F3C30E6B830F0ABDB2778E0F7A3EAB
+:10529000D13F1FA72DC7E7015FEBFFFD15879BF2ED
+:1052A000A1EAF7CC6142FF73917EB4E2592BC5D9D4
+:1052B000165EA05D7B3DF8C3EB5682FF8AF12C0899
+:1052C000BBE754631CDDABF4816B6C2AFC21DBDE95
+:1052D000B4D27DBF0B2709FED388BC3FD2C3E33ACB
+:1052E000E1BFAF6D93E8BC595F967B0D7EF7C03C84
+:1052F0001FC805FF1F20D76BDF1A4579B7B57E9110
+:1053000047CAA604C786D3CBC82DE2BC5ACA2CB163
+:105310008F1FD8443E7BA665FF5823FF43EA0A8BC4
+:10532000731E93826329AF655764FE44EDDCE05839
+:10533000C4236A77A7533CE298718E18EFA1EFD689
+:10534000E68B3C89FEF63FDF3F1678585B15C84177
+:105350007D5F967A82EC8F67E3E89E05F979716F3D
+:1053600071DDA3CE2EF1BB7BFEB7A1FF35376548BB
+:10537000F0775D60CCF741A85A90378F38C539A0D7
+:10538000B3E4830C93DA45DEC78EC87C900F6CE2E1
+:10539000BD6F67E47A8E59DBE91E3BDF8EC87C90D7
+:1053A00063B676910FB233F2FD92F8765A5F9F950D
+:1053B00089BC98C7459E0073F59CA678E76F9C440E
+:1053C000179FA7FB4F635F3E7F6014E551F665B5FD
+:1053D000DB709F66A8D011C23D274B5B7F43F74B24
+:1053E0002D8514E7FAC7D2271E2DC0F747ACA2DCE3
+:1053F0007C878BE1FEC143719BC95E39F9885D02F0
+:10540000DF3FC9DA174A4619F03F22F9857F7989CB
+:105410004A768BD78CE7ECD83A12703FB2E3D132A0
+:10542000F80F1F2A723458063927BDF491C87874D2
+:105430005F56E4B93ECF2CC1E73CB38C7385B3848F
+:105440007DBF6CFC1F9F03DEF765093AE3FB49F65D
+:10545000E3B65D4E2A2F7B6A6817ECB44C4B970D70
+:10546000FE75BE6E3A0724FD728B0D79C7B0DFED75
+:1054700079A097EDE4FF3EC5E527F4348D1DA2DF4A
+:105480000F3A1578F82DE4919EC2510795EE834F9F
+:105490005507E1DF7D56FF5895F6C199DF65E8EDC8
+:1054A000B0F78EEC1C4EF7615524B19BE6021E4905
+:1054B000EDE7237EB4B4F1DB853F948FB2F4F93885
+:1054C000B7F81D02FF6DF8BD9DBA7B12E81C46DDE2
+:1054D0005AB15FE0B5F05B2EE5E424FDC03D2C4BF6
+:1054E0005D9F507E4C347CA3F31A76CE12F7BFD664
+:1054F000D9051C97ED14F79FD5727AC5798165ADF2
+:10550000C2EFCF9E10F7DEAD7406E39167BF7287DE
+:1055100045F7F1D7CB6C81B143F9FA36CD127C93C4
+:10552000B7F7820FF67F6FD3EFA77EDFBA9AEEA1AF
+:10553000DB342B99C63B16B83705F654747BE4ABC5
+:10554000ABAEF0760FC787C769CC76FDEB0C707DEC
+:10555000E77CEC53CF6DC8FFFEEA4927CD8BCB0922
+:10556000CA778C5E3F9F2FE1F3B2A7ED74BFC051A5
+:10557000E3FCEAA79C0FFBC6613E33EEA1F5FEF10A
+:105580002ACA27BEC51FF9FD29ADA700F87FAA7B4F
+:10559000A682EF37CF1272A06EEDC5B3E9BB3F58BC
+:1055A000E9BBE8FDB87D96F8DDC37EBA7D2A56E4F6
+:1055B00007B1C0D3E8EFE853B132E8B62FD16F435B
+:1055C0007E7F681F0BE13ED3A3D6C048D855479FC6
+:1055D0001A978738EED2460BDD1F7F343130520DDB
+:1055E0007BDF67DC2B888435FC2E602DFA1E35307E
+:1055F000FE32C7861EE859C89B29C8A767D09E748B
+:10560000665E0BF015FE8884D9426E522E2EF26D26
+:10561000D01FE177C08638AB49E7B54F46E7C5886C
+:10562000FAD76719DF73924A36F37540AFD6800D0B
+:10563000F7548424A6E1F72697B5DCBA04792CCB7D
+:105640001A365D0F7C5DA6B0721B9F579F247E7734
+:10565000ABCFC9E907FA57F838D9E2A9A60CACF3E1
+:10566000CFC6787F9D25E422D7BB593BFC252DD2A0
+:1056700006F46BF215CA3F0CFB0E792090537D8522
+:10568000467DD47AFB8C3CD6D0535267B87C8A5E78
+:1056900077E26C2127FAB2B47BA6270FE43BF2F243
+:1056A0001F2E13F252C67E3743899F2AFAC47F9B6E
+:1056B0009764505E7C8D8529E9F9823EFBF3542C7A
+:1056C00091FE1A9C7F80FD8727EC3FCD2EEC3F9406
+:1056D00061FFE109FB0FEF61FFA10CFB0F65D87FB4
+:1056E00028C3FEC313F61FDEE7CD9623F3387F20D1
+:1056F000AF8DEE05E8CF5B3B23AF4DC4EBCDF8FC9F
+:1057000011393A3E4FF96B9F483DADE9D2B9F3D715
+:10571000B65DE81D397B28ED7F447FD346F927210C
+:10572000CFE2F7861CA835EEF91CBBDD16B11F3998
+:105730008F4496273C1959CEED8E2C9FBF37B2ACC3
+:105740001F882C7F388B89FDBDF3B5B138A7DF2BBF
+:10575000C5D17D6F75177A47619EF55BBE5C087F8A
+:10576000FC316B6827E6D3DBC4F75DE081F0FBF129
+:10577000DE80D766FEF539EF493CE7FD8891786217
+:105780009EC378C81A4A57490F9CFE20FC3E2BA4A2
+:1057900038BA47E4B093ADB913FAC77F8878E7C940
+:1057A0004356DAEF931BA4AEF0FCB2CB6647DEB7EC
+:1057B000B2E89B492473FACB1B24995D007FB61C89
+:1057C000319FF1FE9808789DF758524479626058ED
+:1057D00044FB0BF66447D48FF6BACB861A72187165
+:1057E00087BCE08448BEBBAA4DC869BCE07CF1AA76
+:1057F0000D9322BFC74928BE9E959D920E3E5AED3D
+:10580000B938E2FB9577B4519EDE4A272740FE7DEA
+:10581000F516F1FB2D2325B686E2ABBB445EA299BB
+:1058200077BFC890334CF1D9282E9C2CFC8847A414
+:105830009E91F8DD9F2513DA374F97909FD6391246
+:10584000F96E2D33BC37CF167919B3286EBCCB9ABD
+:1058500008BA3876E8E33918F758C09A44FCD3D828
+:10586000FF9156E117ED9CC2E8CEF6CE76613F740B
+:10587000B60F89191D16B7E0EB4A811FFE24D743E6
+:10588000B09FA5965CD2B74F1D12BFFBA73596D32C
+:105890007DEE2BDEB6121D9AF3AFCD7FEDC124193C
+:1058A000E71219D917C7E4FDA7D7F2FAA37981B196
+:1058B00041C8916D9D29D7F1F98412BCAB66F3FD07
+:1058C0005EF166713CE2A05F3F69A5BCF88F3B1EAC
+:1058D0007E10792A6BDB1FB6C19FBC54F1DB282EEA
+:1058E000FF78A70D792A973FD649EF6F7EAC92ECEF
+:1058F000CDCFAC0DB43FBE0724F66CD83A4B2D1B70
+:10590000C626D3BEA527020FDF37F84D4D8CB8DF72
+:10591000E1AA8A422BFC674B9F4CA473CD57CF93CF
+:10592000D6201FB2F6D010BA6FE93E031F4FBE61FA
+:10593000213DE4E43C8B5FC8A1C1CF5B5FF54D1610
+:10594000E1EBBC6FCE233BECEAE07861EFE6864802
+:105950004F3DC9847FF2E41BA76C57A13FE4C77099
+:1059600056A2CD17799C2B258E7FBC7EE59BEFD070
+:105970007A5666B106E04B8DAD47E41B14B110EECC
+:1059800011F54CB744E0D7F292D8087C9CCF922214
+:10599000F250AFC18F338495E7558C8A687FEDBC98
+:1059A000F3A2E83B7FA09EE87B5A84DE463737446B
+:1059B00094AF8C685FC7E60ED4C34E7E44C409EA38
+:1059C000BA13293E58837B89F8BECDF78AF7F57B59
+:1059D000128DB8614CFFB991048BF01F849F7B61DD
+:1059E000465CB10EFFD2E017ED217F5428DD42F76F
+:1059F00027D6B7BFDD2A1BFE289C5BAAF3F5DA7019
+:105A00007EADCECD42B8EFAF4EE921B8BA74357B4A
+:105A10004DFA001ED477479E0FAE3F24E06FC6BFFD
+:105A2000A3EBB93C6945BCB8BE42CA83DDB9ECC939
+:105A30003E1BFC58F3BC19740FFB2D5B22FD57B5C0
+:105A4000813E9AE7D57B52C8CF5D0F3F53D87E6425
+:105A500078843C31E34238172ECE47BBF6633D9C39
+:105A6000DEC89E3EF9C6C39289472CEF4C78D4AD70
+:105A7000FACC06397910F57CFDC3F43FB7C2BE55A8
+:105A8000AB847F2E1A6F001F250C3EC3804761F543
+:105A9000373301AF9BB938F7E7FDFB70D2903B83FA
+:105AA000F9EE11E7E14FBE7198F2374E7A5D0D388D
+:105AB000477B0BE2F2BC7CCB1E9B1AD4CF845BF4F9
+:105AC000FAA2E1F6FF01116C07D30080000000008C
+:105AD0001F8B080000000000000BED7D0B7854D5F3
+:105AE000B5FF3E671E992493E42424904008272F95
+:105AF0000812C2040282501C928051A27708AF049F
+:105B00004298404040E086686BB4D84C48801840CA
+:105B1000C34BD14B25E0A3D6521A1F556AB51D10B1
+:105B2000110BB6687D560A017AADDAF69A62A9F1D0
+:105B3000DEB6FED76FED7392394380F6FE1FF77E17
+:105B4000F7FBC7AFDDECB3F7D98FB5D77BAD7D667B
+:105B5000A9FFE4D18D05422C4DB689768F1065DD05
+:105B60004E21C60871AB38B9414DA4D22F6A83F1DA
+:105B700042CCE9B6F3F32145279D2E7ADEF543C5E5
+:105B8000B34F1162B5EFE43441EF0B8F48BF3F458F
+:105B90008859A5D142B804FF7D25B8DD29A8BFE604
+:105BA0001119F74F106276777F1E67F5738E739D1C
+:105BB0003921FD8EFDD28971345574A54EBCB45D7A
+:105BC000884EA72F869E8BCD7FB4C5D2BA76517BE7
+:105BD000E83C6B3FFE958845BBBDF7793AD62B165E
+:105BE000FADC4234E101AD4FD82AE3AA73515927B8
+:105BF000C458EA83BFEB7BCBFA5391AF1E09997768
+:105C0000A82F26F123DA12F51DFB954DBEEFA7F163
+:105C1000843B41880997BEFF4583EBD5230EBC1D0D
+:105C200010224988A9B652D549FBAA7EDDD61E416D
+:105C3000EBD1CB737EB191E0E17FDD265A752AD797
+:105C40004F55B16FFFEB8E7641ED75F7E40C10EE1A
+:105C5000DEF1FCBB68D27EBDF5B4C67EFDD15E4DE3
+:105C6000CFF590E71B9A33D33A737BEBD5915A7FEC
+:105C70000FD5AB1B6DBE762ACFDD3BA0FF789AE730
+:105C8000DC7A476229ADEEDC5D05696224EA53B92E
+:105C90003CBF35A2BC9DC61DF22D97B0D1FA563D32
+:105CA0003F60AF4DC17EDDFDCBA9FE8767FAE5639E
+:105CB000FB8D3E95F7B572FD0F63C753FDB6F5BF7B
+:105CC0001CA765109CA6FB4B7D04CF4F95BD4F686C
+:105CD000E8A8EDCDF3D1B8CBEAF3327F43E7BDAA14
+:105CE0007E1C97FEC6EC383FADA7B3E1A0389F1DE0
+:105CF000B24F21BC1D80AB6877CE88E97DFEBAA388
+:105D00007036C65D61A7F65C8C3782C731DB0F97B2
+:105D10002ABC9E271AE8D508219E6C7071F954831D
+:105D200026C43021F6372473FD4083CE6547430EE9
+:105D30003FFFE75D632C70FD4C8812CC3FC4F6C773
+:105D4000FC3AE087D63105785BFD4D215A09FF6F9B
+:105D50007107B9FE9B48A1ADCB1762B09D564CF0C0
+:105D600074E608AD91F0AA7AFB0B5350AFBE55080C
+:105D700085DA53ED2715F44F259A42BB533CA770A3
+:105D80007F4D684DD45E1D1794FD17D378F112DF57
+:105D9000C43821B250123C078B0E7E3FAA983009BE
+:105DA000780B08513D235BAEC721B434C506FCD641
+:105DB000BEF13EE8717DA4671FF52A2D247C0FC13A
+:105DC00083474B55C673B38CBB5967783DA07A9215
+:105DD0004526EDAB79B853004FD6AF4FC37A561076
+:105DE000386DF98CBF5598EF8E48A163BE8F23455F
+:105DF000F07AAA7FFC74647B13F0C2D5C8FD7F9F44
+:105E00002434B4FB097735AA5F7C2CA63D40EDBF56
+:105E1000570FFD792395BFCB0F0CB5D13CF91AE193
+:105E200007CD7B9BFAD21CE0CD8AD6BD6982D61FF6
+:105E3000281439B56E49270FD1FBB7131D804E6E5C
+:105E4000576AF774D27CB737DA45A000FD6ABF8382
+:105E50007A605D84D644E583D1DFDAD349CFEBEDB8
+:105E60002E2DC283F5D65E0B7CFB5A97103521F49C
+:105E70007B7DB74BD484F0892922DE522F72A5583E
+:105E8000FA4FD5D22DED37240FB7B4DFA8E75BEA80
+:105E9000D3732658FADFEC9962A9FFD3F81B2DFDC6
+:105EA00067786758EA334B2A2CFD67FBAA2DED7300
+:105EB000CB975BDA2BFC6B2CF5F9CBEEB2F45F5091
+:105EC000DB6869FF4215769CF34B441F3AE1FF4FB4
+:105ED000883E501E3E9164176A2F9E4C2A526B3B9F
+:105EE000DC97F2B3A306BD47977977978DC5A827AE
+:105EF000D371EE83E85FADF9BDF5547B4F3D05E707
+:105F00003029FAF0E73A91E0756FDEB3CC4E7C723F
+:105F1000D2B587C76452FD5B330EC9FAC4C3CF66DE
+:105F2000507DC38CAF647DD4E1CFD1FED59BAFCA89
+:105F3000FA4C1AEA3A8C77ECC920ADEBB06BCC0086
+:105F4000F0DD49D7D33A095FDD240FCA689ED52E0C
+:105F500077303356EEAB86682348748FF230D13DEC
+:105F6000CA2344F735C48F8F12DDA33CD6E0E1E7A6
+:105F70003F6B18CFE589062F973F6F28E1F26483C6
+:105F80008FCBB71ACAB97CBBC1CFEFBDDBB08CCB0E
+:105F9000F71B6AF9F9AF1AEAB93CD510E0E7802F90
+:105FA000EA7FF0497E240E3A7EDF23BF32809E9A3C
+:105FB000B017B01CEA02BD8897345148782C0E8B7C
+:105FC0000E865BA73DFE233A37B0CE50F887978206
+:105FD0008EF323735CEABCDDEEFDD2C7E792AAB173
+:105FE0009C329E6FBCC1FF37D0DB3BE933B3C75057
+:105FF0007DEE5FFCEBE3A8ED1D552CEBEB9CDFF198
+:1060000049FE706686D73683CAAFB94E5780FEF513
+:1060100014A18989A8FF84F99F7237FD8FF8D1D721
+:10602000EC279B506FFA52E8EB885E0FC51CE5FE2B
+:106030004DC41F23683F4A7707F3B7C935C476F3C9
+:10604000D1AF83F9DF64E27F225FAE3394DF7D4D11
+:1060500093FC12BC11FCB0A73FF13FF42FEE3E5968
+:10606000C475B7538F5030DF47456A01CF2FC02F1B
+:106070001EFB52F253512B34C704AC578E37996034
+:10608000B58ED773D2CBF55C733DB2FF643FAD27BD
+:106090001EF3D772BDA9DA9C9FFAA31D63C6837F46
+:1060A00077AC413D8AC449238D3FC02EDB9D1E59EC
+:1060B000A7F555737F971CDF6C17E37BF87FBE4213
+:1060C000F33B57BA3DE09F93734FA6F07A92851643
+:1060D00008E9EF9E24C7CBFA773FF37B0008FBC9A2
+:1060E000507C0274FC8E4FE773DA3DE5643AC6DB00
+:1060F000FD75178F37C8F6743EF8A8DDEB15D0DBB9
+:1061000066DE6C6B6FA5E7C34BFCDE198407F644B3
+:1061100095C76FF2C6B4B712BCDE52FAFD3A9AC602
+:106120009BA10A7F47EE15F1612ADEFFFFF8F0DF41
+:10613000131F0AEC1D7BF13C62A5CB03B97B35FC38
+:1061400058D825A6C55197C137FADF01DFA8EED68A
+:106150008FA25E63CF27D5A4B77D28DA932E6DF783
+:10616000FFA9CB81BAF9FC06639CC562CA34B4DBD3
+:1061700013DF8A06FF37C731FB2DB9A4DF6817F498
+:10618000F9DBA776EC865C2F819CC7FE8437369FAF
+:106190004C8422FC53C7FFC9F69B48CEB7E245DBCF
+:1061A000A42375D033C85EB141EEBBA51DA0D37F3B
+:1061B000E0B3D777DB2D76C14D62B31D70A4EE5DE1
+:1061C0001104F712D80726FF243CB929F7B76C371A
+:1061D000DC14663784DB01DF994176C008FA47BAE0
+:1061E00048077F7D05FA2BF47CC31E2812523F0D11
+:1061F000D75F4D7B80F4D8033342F45853BF7CA261
+:106200005A53591E088F3A9AEA53BD7A1DEA95D01F
+:106210006BA97F0E947D7A5E9CA2303DDF200276D2
+:1062200008891B453B97D34590E53B4DFFFBD5B413
+:10623000CF9B2197094EB7882E7EEE139E973A6921
+:106240003F472E8E2B1843F02956831B60677C56E0
+:10625000DD390EED1B34FF2BA0EF3FC7BC791AFAD6
+:10626000A4E8F20FC3F91D2E96EBAB9B4D3A573EB7
+:10627000E46F26EBEDE17CE215927B5924F75E2575
+:10628000F99B45FB7C8DE42FEAAF93FCCD0AD1EF5F
+:10629000A7E98AB087C0F3A69C4681F1A66B45C2E8
+:1062A000DEEFF2F26E7ADE8F5201DFE3F1C38A7124
+:1062B0004EC7E3AF2D16792807A8B28C70A2BCDCBC
+:1062C000FB263D4CCFDD78D29687F9A6F17C875D21
+:1062D000BF7C1EFAE3058093CAACE6935CBFC32182
+:1062E000F16CD50B3717EAD8FF3BB676D8419F60E3
+:1062F000E1843F93EB27F2FBD7D74FE0F2B70D22B3
+:10630000807DAF74C97DFC217028CF4670BC2FCE34
+:10631000FF19CEFBB7BB6D9E20DB4F919E525ACA30
+:10632000C7EDCFC6623F26FEACB4E99B3DC0FBE3A0
+:1063300036CFE33AE351F07AF0898E887D8F2B9740
+:10634000E213E1D117163C72FB07CEA0F3128FCDFA
+:10635000E4F59978B3D235CD0257D31E1D77A397B4
+:10636000E95A1341E65FABE99FD03F56BB4E2C671D
+:10637000FE42F5880997EA2FE3A2A83FF8958BEC37
+:106380009D09BD701D14115CCEFA60B4B46B847F9E
+:10639000CC35A0EBF7C67BDD656CFFE6EE37E11C84
+:1063A00001FE161C1187FE25C76CA29D96FA5A5451
+:1063B000DE7ED07727C15D217DEF8611B5EE0CC260
+:1063C000CBBC52FF00D6376D7FB161DE13D98AE8AE
+:1063D00047FD2F1C1BE366FBDBA0BBCB9D7B38FD81
+:1063E0000E2933E8374FE4817EA7DADC9E20D6F50C
+:1063F000B6CD43EA30D913B12ACB1BC3FE982C8605
+:106400003E3889DA8B8E39443BB55FC040E89FAC9B
+:10641000B07D63D2F5F5C2D73C09F4E975750589FD
+:106420001F4524AB420FE13F917A94D043D6119D92
+:106430009360A9C778065AFAC78DCFB0B4C77BAFAF
+:10644000B1B4F72B196DA927F9AEB3F41F505E68EC
+:10645000A9A7F86FB2F41FB4ACCC521F5C3BCFD2EB
+:106460007F48FD224B7B7A6085A5FD55E18B0BA60D
+:10647000039DBC6FE58C033F957F992D75967ED467
+:10648000E1889FE03288182FE829BBED6ECBB84237
+:1064900097FE9D00FD07FC9A9A6CF5F70C1293DAB3
+:1064A0008137C94D115A04C9C0226DCA11B0FF22EB
+:1064B000CDEAF719E4FEF814F8C2A030BE1E7EFE45
+:1064C0000BCB0C3FCEDF7BFEFE6BFA3EFF95A23D71
+:1064D000901EEAE791E73F8DCEBF95CE7FD82EEB99
+:1064E000F90F6FB79EFF8827ADE73FB2C37AFEA3CF
+:1064F0000E5ACF3F3F683DFF31C7ACE73FF6A4F5EA
+:10650000FCAF7DBF30EC1CBA987E5ED514F1701FD5
+:10651000E736A1D38A1FC2B699CFCD94AF133F2ED1
+:10652000EBF3DCCAE9BFFF17E7F640D8B95D149B6F
+:10653000C7E6D3BCDFB8D095E6B45DDEFF363E9E3D
+:10654000EC55D86161F6AAC9B72E67B77E11F9B7C5
+:10655000BDE0473AE923224D883BA3A85ED0CB9FFC
+:106560000285B5EC7708385D5A9387F186F1A2FE73
+:10657000544C3BF4D02FD4CE18C8E5D36A9B82F29A
+:10658000966BFD3F001F5B985BABC0DE4EBA6D8320
+:1065900002FDF6B3C15DA7BF8971EE8A61BE0F1F10
+:1065A0000CC6A96A1AC072DEDC4FD520C1F6EEC156
+:1065B00032C9D785A7732CF8FD8FCBA47E1EE3D1FB
+:1065C0009CEC0FCC155EF8F9C83C4CABA2F6A7E2E8
+:1065D000FD41C97F27EDDA9208FC8D151105217860
+:1065E000BCD6CE789CA54DF6433EDDAEC47A5A1398
+:1065F000E14F91EDA225A21DF2C7E6F4CC853D2125
+:106600007EEE501E4FEF5D972DD63380FB853DBF4C
+:106610003DD23320BE0F3DC12C97B7D8484450D946
+:1066200026CBCBF59BF89D885AF82385BD63F1C333
+:1066300034FF3945CF001FF9E4F117C62CA2E7E774
+:106640001CA2BC2F3B7677FC940FB1EF7AEC13EBD6
+:106650005EA6B6637D9FB85ED9F51B9287CB238F6C
+:10666000EF82FF70A2ED2DB607BAA86D1FCE1FFEF8
+:106670003ADACFC3591AFBD7260E09460E43FB4E12
+:1066800095FD6AC280CBC32B75B69F26DA9400EACB
+:106690005DF738DBE1071FB64B58F49B4F1CB27F08
+:1066A000E0EB43198EC3DB5DC21E4A47C6FA529720
+:1066B000A97B71DE239ED42CED233B922DE33D6C10
+:1066C00097FEC95107754BBF87DBD540F628F08987
+:1066D0001C4BFF31C73CD6F7E1DFCC05BF186F7903
+:1066E000BFD321D80E0A2C5759DFB8F67DAF759D60
+:1066F0007AD7D343A9BD6A4F3FE6E3133A4B2CE365
+:10670000A6CECC60BD62C8672FB2BDD4F94DA1A89A
+:1067100029E01B3E4BBF41F693AC4FA6C0BE61FBC8
+:10672000E74823DB4BB5526F1824A47D66EFF19741
+:10673000061B518F74C9FED4CEE3C7E784F94387A3
+:106740004BFDE55D2857B40E87DDAB42AF7DC4D964
+:106750005901FAAB8A10ECD7A2F3E37D3E7277FFC2
+:10676000BDA1F4953153FAB7DE85539CE8E97197E2
+:10677000F49FD242DE7F0DFD817789BDFDAF99295F
+:10678000E9F09B377973668EC57B1ABFFF88B3EB40
+:1067900003E80555A3E47C95AABA70068D43B65765
+:1067A000F93321F43076A6F40FFDC72CC59857AE07
+:1067B000BB2A4EAE4F7CD3C9F82AEC01B61F1F8905
+:1067C00012F1C0C7059B3BB60CA3AE95CE36073B76
+:1067D0008944BB03FCAAB4B0D30E7B78B1AFFF935E
+:1067E0006ED2CB1E0101C36F16787679906CC552BC
+:1067F000D1C57073D7D2A3096C1F78FBA29BFB672E
+:10680000D9785FA5EBE4FEF5350EDF3EEA57AA8A9C
+:106810001265746FBF7DB324BCDAB3D412F09B8DC4
+:1068200031567FF3B333255FFA96B1CFA9B654271B
+:10683000ECF2250AD95FB48F257775F3BE96C4387C
+:1068400075C08BE4516CFE383E4DFEF3BBFB3BC183
+:106850006F8E7A4517EBDB5ECF2EF0E34581086D36
+:106860002FBD571DB0CA915BA18F28AC87719C6961
+:106870003191E421C0A325AC9FFB2396374BC2E4A2
+:10688000CDAD663CE92AF6DFA3330DFD71941825E2
+:10689000F58797189F2F10A3C1BE2E005FC157091F
+:1068A0009F03F1ECBF67B847D548B80B039F1D2E77
+:1068B00089AF74947CDE59F54EE6F7885FD81D32B7
+:1068C0007E8112F10B7BB68C5FA08EF8054AC42F37
+:1068D000F0FC99060FD79F6B18CFF5E71BBC5C3F08
+:1068E000D850C2E58B0D3E7E6EE2A7B0770E875E74
+:1068F0008E73C5B94DB59DC8E2F5266AAA5CBF1E68
+:1069000017EFEE3DDF70FCF8BFB5BE4176E9774981
+:1069100033E83C3CAE62B6A700AE137AE3226EAD1C
+:10692000878F70BBD34F7CE43F1147E9E11B82F8AE
+:1069300045662F9C84CDBD0E71BA8BED64FFA58793
+:106940009CB7C738EFF667657DAD607F50B8FE61D4
+:10695000D675C4EF42E41CD14D540EE442B3DD932E
+:10696000AD5F0A67936E68FDEBD6B3DD24FD7864F6
+:106970004771DCF0F7643745D07BBF0F7C7E96EB28
+:10698000CF457A804C7FC83F9907BD7C956D6F9A43
+:1069900096D91B37CCF28B401CC6793292C7B9B05E
+:1069A00096008D753F19DD2EA8DE1978B67F5F76CB
+:1069B00094BFD31A770C2F874EF71F07FFF3373A90
+:1069C000E6000EBF73AB1AE074AFFB707FAFFB1F26
+:1069D0008AEFBD3933C49E2DB577315C63EED05557
+:1069E0009C37E9E9EBD663BD81CC7DD0AFCC781F75
+:1069F000C185CFF1C22485E3A665C2C77AD73BAA79
+:106A0000E690FE906022F8E33F1A179CD99DCFE7ED
+:106A100035AB7B22EFDFDF3281EB438704D428F0F4
+:106A2000E7F98AE7712AE63E26D647D1AB9D8D73FA
+:106A3000C7027EFF61C885A186BC0987D7EC599241
+:106A40002F3EA12A1C8F7E82F86C19ED77C47EAF91
+:106A50001A49E3963FA7E5DB74ACBB7634E0D36A12
+:106A6000D0A1D99F565288FD7E67A16EF88B04EFA6
+:106A7000FF9682F47D38D7BA5972FEC53E29C70801
+:106A80006E4C47758D0ADB3375E0B5A86F5158EF32
+:106A900033EB9FB719F5A9B27EFB7A59A7BF2AD865
+:106AA000478B04E98505128EF0E7008E280147F830
+:106AB0003DF61B7E1EC01125E088E7A07FD441FF74
+:106AC000A883FE5107FDA304FDE3798DF0A521B055
+:106AD0008CB85D7108BF46DCAE3884FF226E175A51
+:106AE00047DC2EB43FE276A1ED88DB85B6236E1736
+:106AF0005A47DC2EB43FE276A17531FEC6DE3AE29B
+:106B000037DE1996FA4CB27F8A43E405E276A1E3B8
+:106B1000236E6719CFBFC6F2FE7CD25043DFCFACE5
+:106B20006DB4F45F58AF58E27A24D658DE2FDED524
+:106B30008FF131A1C4376116E1C7C2B95D2F774A21
+:106B4000FEC4FE9BBA55511E79DE6D25F2FC5581BF
+:106B5000F3DCE3D0595FDFF3864DC8F3F60CD0FACF
+:106B6000C053C4B18A1D329E8612F1349488A7A105
+:106B7000443CAD385BC6D350229E86E788A7A1442B
+:106B80003C0D25E26928114F4389781A4AC4D3F095
+:106B90001EE26928114FC373C4D350229E86E7A713
+:106BA000691D88ABB5CD94F83CB22DF02A7C70B746
+:106BB000EC3E7D04E5D0B8EA671422E5C56F8F5C32
+:106BC0006127BE3E34BA7A743CF16687326645313D
+:106BD000D5FDDD32BE9F27BA581FF46B12BFFD41B1
+:106BE000C1FAFAC82F53B87DB1CF908F063D8D3CC6
+:106BF000A2319F5C0C3B31A9F7FD7C84E6327BFB24
+:106C0000F7D6FBEE173EBFD9CFEFB2AE63089C8B31
+:106C100034EF90D7F4F6A674A6032FEC9E495D27B7
+:106C20008BE2E8B93F30652CF842A9D3D04B45ED53
+:106C300075B0FF460414EFBE90F35B6BE89323F648
+:106C40000B6732F8C49EAA027E2FAAE7BD7FFF849D
+:106C50009E578F4FF720EF64D27EE1DD4BEFAF37C9
+:106C6000F8CCA4AE8EC3E06FD5CD33F83D73DCEA2B
+:106C7000DD694EDDDDBBFE6A517B7732ECBE02453D
+:106C8000800F0E055FA2FA804A5D817C5D8DA9A808
+:106C90006CC909F8B0EF6A38FFE9FC225C5E01FBC1
+:106CA00077F5C11902FCF26B05F1531331CE4BC2DB
+:106CB000930DFA2B78D3B25F3E8E71185FB0B2E4B9
+:106CC0000FAC51B1AF5B6823FDE89C6FA63AE0E6DC
+:106CD000F78BDA7402FA9CF26AE68F39954241FE2C
+:106CE000C2F0CABD6A22BD37C27F48851E30B2AD30
+:106CF000934B731F9E49F136D467D883B3B0FE1906
+:106D00001E07D305C94B96FB179A1D6CE7212F81EF
+:106D1000F9E431E917BAB076FC3F9517703BAFAB99
+:106D2000EE9EEEB3C89FAAFBA1550EAF5CF3CE3822
+:106D300035037258617A35F3753E4D6F7F229EE0C0
+:106D4000F269C6D3B1E31596A3CF828ECF364B3905
+:106D50005CBDFED558F8C53F6FFEA113F032E321AC
+:106D600035061C44AEF728D6579D22FD6AC2F6921E
+:106D7000137CFAA2DF5D6BA3FA39A21BEF30E607A2
+:106D8000DCEFF3834E991FD126F561D36F53FD8657
+:106D9000CC230AD79397373BAA9D644F2E0FD393EA
+:106DA0006FBB8A7E7C7C96A11F7B8407FAF1B9B009
+:106DB000F8C8A2ABC747DE021C4C3D4017C1D90C36
+:106DC000F7DA6C15E750FD8621EF3BF47D90F7A6CE
+:106DD0001E50D958C4F253FC50E25165A3EC57F948
+:106DE000236FBB425D7E61C8FFB2EE417C0EBF34B3
+:106DF000E4FDECEE114C9FA59D91FC7C4E770A972B
+:106E000073BB87F3F332B7A4D3CE9745FB3AE84D73
+:106E10008108E937392258DF08C7CF19F67635518E
+:106E2000015E35AE4BA2FACDD01F68BC72E813FDEF
+:106E300080EF8766B17D477896AD5C8AEF732BD380
+:106E4000A7A27D788922A0475D09DF95F8107E22F0
+:106E5000028EFE1877BF60BD64A85D1C7190BD56A0
+:106E6000156DD8BD6EE92FEAF127D15AA47DD8BAA5
+:106E7000C29BCB76A71003793B5EE4EDC5E4CAF66E
+:106E800001EFB4AE68CE821E2AED98B47A230E6963
+:106E9000D49D35D24ECF32EC9AFE2EA9AF6718762C
+:106EA000BC46B8B191F5772FD30FA9F53ADE770A32
+:106EB0001F9F4F1409B4ADD49EEAD2795FA9B42FB5
+:106EC000B40FB6CBB893B3D89C4F04FB8F0EB5B3B9
+:106ED000A55D0FFB1A7AD1823B141E7F714BF65EC3
+:106EE000A9A7E70E384BCF8FCE299C3F9BFAD7DD61
+:106EF0009B6DC9A70B2F17D339812EABE23ABFAEDA
+:106F0000109CF3670B6F31A98615C28013CD2F68D3
+:106F10002FF38CBAE79DEF7EDAE266F81A707CE018
+:106F2000A920C1AC65ED3AE677112E9F17E7199DB0
+:106F3000EBE5F85635E09B7479FB7DE5B5DE1AACE0
+:106F40007371AEE4FB7C0E05C8D7FBEDF742FD1470
+:106F5000A6BF8BC0C67AFF0365C9F9AD7AAFDC7AEC
+:106F600078452AFB356E99ADF6E4C3E9C3A4BE8625
+:106F700012FA1AF27EA0AFA10E7D0D25F4353C87E2
+:106F8000BE863AF435D4A1AFA10E7D0D25F4353C73
+:106F9000BF76AAAF6436FB4FDB387E2B72BA1E7AFF
+:106FA0001CFEA10627E7339AF6D49E1551BC8F3DEF
+:106FB000773BD9CE30EDAA4AE7C9575D744E9ED9CA
+:106FC000B2DF87F5DB1CE073749E926E57282C07A6
+:106FD0008FCEF1CDC63CD1B91E27F8873FB75DD122
+:106FE000099E03356947946674E5ABEC7F738FDDCA
+:106FF0001702A72136714424D038196D3C5ED7564C
+:10700000A53DB4BDC7EF3347F28FEC39523ECD6B8F
+:107010005318FE91A27D3DE869514BFE38ECE7E83C
+:107020001CFFAD7C3E2FA51F1DA4437EC53B71AE4A
+:107030005503A45F9666482B0BE16777CF967AF8E5
+:10704000357305979FE1DCB89FA49B8A7A4D69CD83
+:10705000EFF567A5E4680AEC9CBB674BFBC029DE33
+:1070600096F89F2CEDD954236F4135FC62267C5B4A
+:107070007316F1FE1C4420B6F810BA706A47D92F77
+:1070800019E3D4B1EF6AF7D06903E03769531214FA
+:107090007AB5C62DD89EAAD991B90F791ADF33D601
+:1070A0004B74E34C811CBB57D1100F294DD0E74ED8
+:1070B000C038AF3BC43E7A6FD11D87B299CE84CC25
+:1070C0006F0C8767CDAE094C4735ED545EC1AF7B81
+:1070D0006AEB8F9326006F835ECEE7ADD1BCCE8482
+:1070E00010FFD162E31CC2EBFF32DB26F9BD38E6AC
+:1070F000C03A2AB374057EC3EFCD96E7B7E08E742D
+:1071000027FCC29534B23A1AF821241CB62ADABEFA
+:107110007439CFE890711761DC9079A93FEB498F02
+:10712000CF8EE17916B5C53B15C8494DE3F5D1FEC3
+:107130001DEC5FCA92FB2F4DF038DD187F398D4F63
+:10714000209CA705997FCFCBD54523DB67FA34F088
+:10715000EF9ACD8A68A59A7FB39CCFDF12EF1C8986
+:10716000754669D3183FD72B31585F6982D7E966D6
+:107170007C4D5743F1351C3ED5C6BA6B687D4B2C10
+:10718000CFB73A401F15869DBDA87946DA83B4BEB5
+:107190009AC0C804CC536397FB7FD7386FBF01D721
+:1071A000CA84B6A97781EE96C6C737E9BDE3BD6646
+:1071B000E0E3BB067C4DF854686D8ED1EE10F8EE1E
+:1071C00094FB5FA205B331CF1297DC7FCFFA77C86B
+:1071D000796A76543B73A95C6AF7A53D48FD96062B
+:1071E000DE4845BEC7BB80F7585EC7FA145E87A26B
+:1071F000611D42F3A7013F3EDA39378DF7B5E34110
+:1072000087E07DBDC9F17AC01572D7C48FAA3192CB
+:107210001ECD793F9DEDE673FCD4D8872957A2EAAD
+:10722000A51FA866F39B5C5F4C74A6C487F8A35D9A
+:10723000567F748AC7F4DFF999DE2AB264BCC8A409
+:10724000C3471C9DCB41778B374BBDD6E40B2457EE
+:107250006B9FE943EECC37D633CF38A74A55F22B94
+:10726000B33DDEE04B9519326FBD476EC719FB9BEE
+:107270006DB41706B3D7E4F6F637E7AD4C90EFE1FF
+:10728000BCA0C37C65C803F4AFE3FEAAE197957E7A
+:1072900095BA2D368E5BD56D7994F95EDDD30AEB08
+:1072A000B1BFAB7BE1E7608D9F3ADA57A764F6AEDA
+:1072B0006309E933A0F3A586DCAC09F64DEF353759
+:1072C000FB63E784E4D7D76CFFFE50F0CDDF1D38B9
+:1072D000CE7CE4548CE45BF344C73BD7A5F7AE7F88
+:1072E00051CBDE968C44C8CBF8D190A366DC202D20
+:1072F0004757716EF30DFC5DDC2CCF4FD0F965C79D
+:10730000C36EA9165EF0A7648F077AC020432F4989
+:1073100071997E43797EEE2C79FE973BBF8A1E39A8
+:10732000D03635540EF4F8A1363B185E1736676F29
+:1073300048667D54C2EB365B47DE9D34EFEF563E28
+:10734000BE3A2583E57B1AE4FB12C39FB4D4D00771
+:107350006F2578F5E55723781584C2EBD63D125E8C
+:1073600095191DFFF622F8C29A088E43FD6EFF188C
+:10737000F673CF57442DEC9C791D5B1D83C0776A53
+:10738000D2E32166BD73D22DFEDBC5B5F91AFCDE52
+:107390005E53CE85E19D59AF10DE01A04B1148151B
+:1073A00090E7BDEFC727687942AC9AA35AF880D915
+:1073B0007E7E4DF57DC8BF391F29F16D258D8778FB
+:1073C00047A53A3A0DF9AE5D5B2246833F88C4205B
+:1073D0009F7BD5105D65F917EDD7B18F41D17A024A
+:1073E000E86DB181C75959FA35781EAB929E8B3C36
+:1073F000373A9BF1A381077426A32F2F57FE25AAA6
+:107400006378ED15F4BCAC959D7FC43A71FC180708
+:10741000650CED7FD31CDDF4B78AFEA37BF5CD7040
+:107420007E71A95C967E65B546EAA9E638E178D614
+:107430009A53C67865EAABB4EF76992F23F74DEBF4
+:10744000E63CC97F4990F5C01C89DFE7D3BD85AC18
+:10745000DF4C7069FB48F5DDA7EA751C6F257B00E2
+:107460007AB5C8F11E7642EFFA66AE86BC0391E5A6
+:10747000653DBA6A90C6F9F8E71BA5DE7DBE42F20B
+:10748000B3BF779FE7D325BD75A5080D71D1ABF1CB
+:10749000C58A9A6A8B1E22723AC7222FBB875EDA90
+:1074A000E4BD970B6D63F8BEC005D89058DF9A48CD
+:1074B000CEDF3A9F6EFA27BCB19057A70323E311A2
+:1074C0006FFB47FDB6DF31F0B3324AF23FD2DA79D3
+:1074D0005DA7EB33592F369F9726483CAD4CE88C7F
+:1074E0005100DFBB6C2C6F4DBC3DDD71360672E682
+:1074F000FC94CE9809667B885C3CAD75C6401EDF67
+:10750000E190E38B1827C77717DC31C3897B450BE4
+:10751000EA7FE950A87CC6C0E721991DDE0189AC4D
+:107520008F6918A729C693CCF791E23DC9A1723D96
+:10753000DA3D87FD2CE7D38359F0CF77E5477AA072
+:10754000179C76CF9906B9787A57BC07647487E29E
+:10755000395D0F3C581FC1F6DECA8E43596C1726A1
+:107560000B15FCE07C7AC79F7F8575AF8FF660BEF8
+:107570000B37FB0F81AF0CB1C97E74AE2AC7BBFFBE
+:1075800042F392FD7A0D06B5F5F243619772FC1154
+:10759000878C8FF4D413647D88D3CBF799BA5EB708
+:1075A000B15E6DC629EAF6DA0C7F898C532C795DC1
+:1075B000C62996ECCD7C4FD63959A6E71E56AFDECC
+:1075C00028E3234BE01F0991231B7614F5C77DA602
+:1075D0009AAD531F08103EA529C2073E95E6F0DE7E
+:1075E000023CFA78EFB0F8C6103DE9C3F6088E47C2
+:1075F0007EBCF78537C6D17CFF763089EF2B89803A
+:10760000CA76488B9EC87870CE907FA65FCA7EC728
+:107610009A00BA997EA99ABD1BF93E54CDAAA6A19B
+:10762000283FDE1BC9F7A28AB519C5F1D05B76C722
+:10763000B39FFEC395D2CFB0E2CDEC7D90377F36BD
+:10764000CE7BE5DF5E7904F19725E9C67D988E68EB
+:10765000CE175BD97030CD465377C5F9FF3827492F
+:10766000DE83811EBCE2E1BD6982FBEB7DFA63CD66
+:10767000F2A306797F63D5B7DEE771FEA09EB8A5B9
+:1076800082DE5FB9EAD9588C73DBCE5F8ED354F6B5
+:1076900027FD15E7DD730F6B97BC87F569583C66CE
+:1076A000C5E5E331B6B9217E98F075D80DF95B9A3E
+:1076B000E09B5321F1C0134A1FE1E5B2838A25FE06
+:1076C000B5A03D8EEF1BF983C2A9E1BC6CC2093A9B
+:1076D0000C34292AE2DEA6DEE2D704EBBD03E74A3A
+:1076E000B87E1CD79606BA59FEC48369A0934F6230
+:1076F00064DDFFD86B4BEEA6F7FD3B5464920BBFE5
+:107700005D3871EF6D7140EAC9E1F7F4B2E646F316
+:10771000FA9787DDFF12C8F2A2E79FD8659E04EEB4
+:107720008141BFFAD01E5C02FCF9B036D213E0737F
+:1077300036ECD6361BDF7B0CDCA1B03FE7C3B66767
+:1077400063B2DCCCF7980FD7FD48FA0BABE2F40735
+:10775000E7834F1C7708E4F944E79EF4F2FDBAE7AB
+:10776000D2193FCDF9FDCF1D62FA5F61E8552BEDCF
+:107770004127F061C5734F3BA1FFAEDCBF55E6E585
+:107780003CA7B467C31FB7FF9013727FF5C1FC71AC
+:10779000A1E3AC7E4EEE3B52743A67869C6B754E0D
+:1077A000C28641C4B3A7CE7D7EC54E5A4735CE852D
+:1077B000FD1BCF5F7308B92DF62ED6B7C3CF6FE58B
+:1077C0006C69C7B6E6BCC576EFAA6639FEAA9CB757
+:1077D0003664F03EF21D4AC8F94F9BEB90F9A7B30F
+:1077E000A5BF66D573D25EEEC99B5A67174D057C5F
+:1077F0007F8BEF73D5072234E4853EBCFC1B7CDF16
+:107800002B29C2A521EFECA978FF9CB9EC9797F73B
+:10781000BAA81C85324B9B5C0E7FE7E5F2959A1C5B
+:107820009EB9909B81371CCAE321FC81F8EE00CE03
+:1078300073097BFEDF205F690DF6195CF5B3118CCF
+:107840004F36D27B4855F4AE9EF4FE511A27D8E449
+:107850004632AAD85D7BF87707A8DDDB18A7033E80
+:10786000DF1632BFEC7A23AFEC966BFD6B314E32F4
+:10787000E2DDCCF8820ACEF3B3977F3B06F047BE39
+:1078800019E8C3D1F8D3DB8A891E9AE76A329F2CA4
+:10789000B7730CE09A74D8909BF693AC8F3892F53E
+:1078A00004F0FBA011270C7C29F3A85E52828FF212
+:1078B000F89AEDEBC81B3BA9E68DC639FC78AEE41F
+:1078C0000BFF71836F339F9B6ECBC6B89F394EA55C
+:1078D00033DC89EC6C83488F18389EF339A634D199
+:1078E000C14D22FD49491276AA6F122AE7870C364C
+:1078F000DA7F437880BB12939C9A28A4F9271D163F
+:107900001D9C879EBB486FE3FE24FEE1FFAED7823D
+:10791000C8A31375840F1EDC73F8E32B88770FBAA6
+:1079200053F140D6545DF86839E073FACBFD91F01D
+:10793000F76FB8D6BF6F2EAD73A0CD7B1677163715
+:1079400069C1CCFBA9FFA6FA684FA3CE224AB8FAB8
+:107950000B5128FF295EBAEBCBD824E4EB750DB5AB
+:10796000FF80FA7DE67579E0273C7DF7882313B127
+:107970002E5574C1EF2E5C53BD96FB5E7454AE71F0
+:10798000BDE344B60DEB799FF5B55CFDC8C444E397
+:107990003E98E7D2F70B45572CEE4D7ED6D51D0B02
+:1079A000BE50F8D22BEF2BA42F15BADC41E4AB0864
+:1079B00097E3F73DFE78CC7772703CFCEFCC0B0878
+:1079C000CEFD9BE4794E8EB3DAC527E64A3DE984C5
+:1079D000715E765DE6D7203F1BE7A80BAA639DE6A4
+:1079E0007D0BA1FFC24FF55FE1BE32D52EBC9419CD
+:1079F00027AE402FBF84DE46FAD8376FF49E001EB4
+:107A00007CE698C4E305E8BC6D93711F288DCF5BBD
+:107A100051D52EE8F7747E7CBEE63DB8EBFF22CF51
+:107A200073416DAC0770A5F31B79BF60FFD6B77FBC
+:107A3000A1F0F97D80F37BB89BB41815743D2DDD62
+:107A40009FFB3FE7DCBE888C7D02F0EACD3FA57A44
+:107A5000E23F927FEA8B1A96CEFCF36F80538AE85E
+:107A60007A554D075FA865BEF03F907FA6948F0DB5
+:107A7000C9F774ABBC8FBF37DFB309F99EF9C8F7FC
+:107A8000244D11ED77C5B05E4B84D1C8F735D7EAE8
+:107A90001EE0FD44234EDB755734B7F7E477DE95DF
+:107AA000D92EEF6908CE076D0AC8FCDD4E55F2618C
+:107AB000B039865BAD90797DC2E3BA86EADF56C401
+:107AC00033C8ABE881AF71FF9CE8D62BFDB7EA3E27
+:107AD000E8FFC24EF614F1717F5CDD2DB097A694DD
+:107AE000C7B35C8D6C8BF8F301E06160940E386D68
+:107AF0005A172394B85EFCE5900EF1B381B9516733
+:107B0000154291816E351801FC5B56EC0DC5BF7BAB
+:107B1000CA058F77FBAF6F78C845F51F9BFCFE65E4
+:107B20001BEF6BC70C6F0AE2C23B66F457A1C73E5E
+:107B3000FFB7471F5A0A38CC76B3DE674BFEE5AE77
+:107B40001A82F38E7CB9CF1D154359DF3DAD123C2F
+:107B5000B0EF7951729C1895C7DDB13C8AE3013BC7
+:107B6000D2E53C3BB233B83F9DDFD05D383F9F8BC1
+:107B7000F3A12F3D3F191FE85AEE36CE47BEFFD97D
+:107B8000E6C10C6F3A3FA35D6D07DCE8BC241C5FC7
+:107B9000B6311CE9BCCA9F91F193D8D078D86786DA
+:107BA000BEF719F268E3429E1BE7417A516CA87F49
+:107BB000FF72CF7F3CCEBFB23CA9B77D47BC370533
+:107BC000FA6B64DB0B39EF4B7EA1E3BC7736E6B78B
+:107BD000209F3610A36A8F8B4BCF6BE7EC270EEDFF
+:107BE000A3F6E82217F33F11D87B08F790A26D1E89
+:107BF000E6370F28FEEF3E8EF36994F65FF879764C
+:107C00001AF9E72255E28DB93ED3BE1B1238FB901C
+:107C1000603ED7391CF2D9BC7F7FDA718AE92390A4
+:107C200029E5F417069FD615D185E4F9C142F2E99A
+:107C3000C820C9E109E04B69813BA9DEB926D6A37A
+:107C40000CFC7BF892A487547A05F74E893F6D03AC
+:107C5000DDDA544F7204EB2B32FF3E4BCBABB81244
+:107C60007FDA7619FEB4EDBF2F7FFA3EF6396EBC8F
+:107C7000FF99728E9B79F93EC1C026296FCDFAC358
+:107C80004E296FCDF7CE2872BC1CD1E5807DB69011
+:107C9000E4473FDC772B97F6AB581B26470C3CAAF2
+:107CA00032F028B2ED8B5F833F2C247D11F354AD6D
+:107CB0008D380B3954B5D621F940FD546FD8FB2CC3
+:107CC0003FCDF785EFECAB77E2FD2952EE2D5CFE60
+:107CD000EF499067977DBF33351EF734CCFBEBD966
+:107CE00071BE37400F6795AE180F3D3CF1571BC76B
+:107CF000C1B2EC098F60BF758D592AD675227F00FD
+:107D0000D7AB9C3909C0F777CAA5BD77A7E67D1B1D
+:107D1000EF8BBFBC920A3DF6DD71BEF700BF7BB3AF
+:107D20002E703C70A1E81C0C397BBAE2D3C158D745
+:107D3000C2FAD758CE2E34E5ECD5E193C4F7549768
+:107D40005FE88193F25F00A7A2A184F9B9CC4FD874
+:107D5000EF945DFE1337D6752677661CD7C541773D
+:107D60005F76D999068F08929EB52E3A56C2C3DE29
+:107D7000E580BDB8B07B9C0812DF2C8AB58EEBEF96
+:107D80002E10C131BDE35E0ECFCF90FE8671C39F32
+:107D90009BF6B1595FD8B0AA007A57EFFAFD2E8C46
+:107DA0006BD77CEBFE95CE332551E5BCD914AFBF24
+:107DB000241D78FEB68DF3852E376F7383C6F33E90
+:107DC000DCA073995221F5D475D1B7709EB483703D
+:107DD00083BF4763ACC3DEDD9FF7E9E84EE432A51D
+:107DE00058FA2BD645E729D521F4EEA930E8859439
+:107DF000C5A0790ECC6FA2443027B49E60A927108D
+:107E000047467F4CF915CF9B11D6FF9AB0F14687B4
+:107E1000D5DB8D7B46D785BD5768A9A79498EB3EE7
+:107E2000C07ED741CB34C5A684C27D9D318E1C6FE8
+:107E300060F750DEEFA0EE2C2EF1B7B93FEE01F364
+:107E400012C52B3137B0DC3DAE88DA7E54C61B79C3
+:107E50006F768FC27C187F6DE370DF59F0FD71BBC8
+:107E6000BBBD19EDCDD47F9B16F29D24D161AFA689
+:107E7000E7379744B27FB9F73EB1CCAF2D43220B21
+:107E800095B3848FCB39A296CBCF1A3BC701B937B4
+:107E900068FE5B2AE00770F9F724D0117C23CAB88A
+:107EA0005F7C99EF26F5EE37D067FE399F7D8A5CBF
+:107EB0007FA07FEFFAF1E71E67EC5FF0FCDF30EEAA
+:107EC0003557552459E6AF9276B15D37E831F05514
+:107ED000A6A52ECF0741D8097D3CBFA4FE9761D649
+:107EE000BA5C7776FD3F09F8B35AB204E7D9D935C1
+:107EF000AFC8A07A2BE17F685E5D78D914467736EB
+:107F0000C33F1769C8BF7BDD43F7220F29BB74B29B
+:107F10000B725D8846032FAC787DAFBBEC8AF47D95
+:107F2000C93C768F80BFCCEE567BF192FE973DAB7D
+:107F30002AAE2FBE73B571CC755F32DE91CA38C8D8
+:107F4000B19D157DDF2FB81A7D1ECA2953112FDE72
+:107F500098A5B25F6DA8A86F015C9B7495EDD29651
+:107F6000AC752ED8A52D7AD915EF05DF6FAC7B73D4
+:107F7000834B042384580FBE1311B28F29F6F8E205
+:107F8000029E87EF856E043C69DC36EF1DCCDFB4C2
+:107F9000C1AAE1377B3FF75016C15B6F7385FA6D5D
+:107FA000C3F771D1EE8B0B6DBF37553594BDB75705
+:107FB000C2EFD6A2AB6C875CC445CD78B9CF16E0D2
+:107FC0000BD931117DE4AD6893AC708DF144F5CEE1
+:107FD00047FF73262658DA5B0D7C200690DCD779A4
+:107FE000F6F2A92BC35F898D64FDFA070F09838F11
+:107FF000F80FDF46F5E1E323586F996A5BCBFEEE9D
+:108000001FBC6D33DA65DEA2C7A0CB1F64796AB0EE
+:10801000CFE14FCB7B3F3FD82F6CB741AF4BB689F9
+:10802000B8649CA7BC879363D0B9B9BE51FBC5D9CE
+:108030000892C7A3824ECB3EA76A1196FA7011D25E
+:10804000CEF861ADFFA3F7C5FFB5C2B8777AADB87A
+:1080500016FB7F222C9F71A899CFD85EC0EB2DFA1A
+:108060005650453E7FF8FD0F934E9F687029783F2C
+:10807000377897AA8FC47DC15A15F7248689DAC349
+:108080009CBFB84BC87BA0C678BADB2F6027ECDF5B
+:108090009DB10F7195EF741C8E52DDF08FFC226A3A
+:1080A000043DFFCEDB99A35B45081F684FB4F0D5B4
+:1080B000EF02CF91EFD521E9E1BBBBE57DADEFDA72
+:1080C000DBA242E34EE17860D6AF794CB5C077B31E
+:1080D00090E7F26A85CF350FF234D0A1029F7AE0A3
+:1080E000E029B39C5BCC3CE95F8AAE1366BE4121BC
+:1080F000ECEB66B7A4DF6683AE2E771EEB0D3A6D10
+:1081000032E8D455E14FC6BCF6127FA3928EEB390C
+:108110003E85FD3EC67D66FEF411C1AFC829985F5D
+:1081200036258976E4374D89FD5110F7999B09CFA3
+:10813000E02F34F1B829DBC0635B25B75F243C86B0
+:10814000FEE908940BF8359BFCEE5AF67FE5CABCB5
+:10815000570417A0BF35BB494A5E018F22C3F266A0
+:1081600093CAED96FBD18EABDC772E9867C5BB9E8C
+:10817000EF0D7AAEFCBDC19948581C7B757DF22687
+:10818000ECB98F71CE347819CEE1FAE41F57F86F4D
+:1081900000DC17764F63FDD1DF5DCC7AC7C618F9D6
+:1081A0003D9EE3F0A770BE938C874FF7C8FC9841C3
+:1081B00022C0F558AFCCBF18047F35F5D796C9FA61
+:1081C00074977C3F7996CC139D6EE4C725FB35AE42
+:1081D0001FBDCD3F771EE3F5B33CCEA3DF92E34E48
+:1081E000CF55787D9027BE91973F87B306FE9F318C
+:1081F000F0E76C7A4725E2CC9D4D3FB52F0AC1BB15
+:108200005B0D3C9DEE8A95F1A29CB157D14F0C7A43
+:10821000CB49627CC7FD7177425FFD028CF7A63EB9
+:108220004574F3CFBC1FF18C856EC2DFD3EB0A6FB0
+:1082300047BFADD13F51BC80E74AE1019E3E18FDEA
+:10824000932380CF9991113AE8E7CC3DF27B837973
+:108250006364DC5D17328E9F3E5EC6690F8D7CE1E4
+:10826000541DFC862F3B598EF5E2054967825FA7B6
+:10827000F1FE01383A09AE875E9CC77A7BF93D3240
+:108280005E7F7CEDF9A7BE07BAF0DB4C16CEF7EAAD
+:1082900074292A445E600DE7BBE57911CBA6F10E87
+:1082A00006787E7F1111CA20926B0D390C77E1722E
+:1082B000B9EC2179D2BF0834B15FE638FD1BFB72FF
+:1082C00075E7315EAD8B7E84DF8F24FCB0C9FB4D3A
+:1082D000AAE8CF79C242FA2B247E5CB358EE2FB2C3
+:1082E0003B97DF1B31C873CD844CC697DDC0D3F4F8
+:1082F00091B69F8DD6E14C128C2745B11358EE4CA8
+:108300005FABE8D021A7AC558E26C05E0BC4F1F759
+:10831000488A12BA1CC9B21D9AB658987BF630EF3B
+:10832000E320BE682A44716006EB1DC70DB8247BAC
+:108330003A39BE97ACC97D1F1F2EEB9D83E9C4E37C
+:1083400043ED2E09E7E36B8BD4FA4496EF3E0843E6
+:10835000930F9E09483999EC95E7965C22BF759575
+:108360006A37E86099CCF7DC6EE0710BF07818BFE3
+:10837000C7FCEB628BCA7E348C877C3873BCE337D6
+:108380009F48C8D0A1FF07347C5F2EF0B29DFD440A
+:108390003B0C7EBABD679C99531C18C7274534C651
+:1083A000B187ACAB5FA9CEDF114BAA95F71F933114
+:1083B00019D67587CCCF7D226C5D2F1A7AD499C0DF
+:1083C000762FDEBB582E382FEABA8F05AFB7DFDA2B
+:1083D000088E933FB1EB7054A81C6E31C679D1A0C2
+:1083E000D30E639CBC8FBBBE1D4BEFD91B69E2490A
+:1083F000D84F5BED61EC6781FC5EC2BDD91B54F8C0
+:10840000819E52440730F4C54F64FD7BB88043F52C
+:10841000BC1F6FE67A7D81E078D9DCB5DF7144510D
+:108420003D7F5DA44E9BA13F39FE99465D613F9320
+:10843000687F3509FA883B523C4EFDEF35FC8F9141
+:1084400086FF71C4A7079F3A40CDF73ABA7E0DBFA9
+:1084500057604D0CC3F58CA3AD7C11D52B7F9AECE6
+:10846000218A174F0D7D6A11F02865BED4738F2BBA
+:108470007DFB8594F9D2CF719DCDC8D3171D6EC0F9
+:10848000EDB808FC08EB319FCFCBB59D75C4727B6E
+:108490006A7988FE769DAD2315FB134D91C343F396
+:1084A000B5E6E5BEF74DF82FD01FEDC795D6C856F7
+:1084B0004BFB6B77211FEC3D1016E9B1D1F337AFC1
+:1084C0000AA40A91B5EC25961307F2665E512E9B1D
+:1084D000E765D6EFCDDA9704396C8E479AC2AA20A9
+:1084E0009DD717BFFEC201BFF1E781481DF1EE85A0
+:1084F000EEAE57D93F1F5074F8E78A027F74745A62
+:10850000F0E0E0EEE290FC0497DEC678343D77EFD1
+:10851000B5A176D342E2FFC8CB98177893F7396FAD
+:10852000D994D1F06F037F1DD8EF5A89BFA3623B66
+:108530004E5C8BF9DEB571DC3D6F98952E75F1DCE4
+:1085400021BE2F345B7EBF345C6E5C82D70DC95C6C
+:10855000CF3E92FB08D3F3634E8E0B0CDFF4EDA7F6
+:108560000EA26C5DBE6211CD336CE8DA79F08B9FA0
+:1085700033C6891C9A7C1A79C24337C5F0BD8EC8B0
+:1085800040F5C045D43FCB7D9FBE0EFED35D2E1E71
+:10859000E778A0C903FCFE7CB79BE971718BCDA283
+:1085A000C71F78B135077EE18BBB077A008F856BDB
+:1085B000E5F7B3B05EDCF73943EB4439677E86C537
+:1085C000BE3A73CF9DD9A0B7730D2777414F782F4F
+:1085D000AA93F9FAF17765DE469E786633F85F9ED6
+:1085E00048EEC077558FE7DE2EF398A70AC526F32D
+:1085F0007FF8FEC8B906EDA123743EBEB0F1735AF0
+:10860000DEF4E21CB0547F02E0DA9C7025BB31A797
+:108610004509029F735A0E7911CFA816FEC054E087
+:10862000718D83FDBBB5F375C35FD371047953A717
+:10863000D6A5F1F717A6E71E1A09B95DDD738F48B5
+:108640009CE67655E3F679818D87517FF985A119EE
+:108650002AD1F73283BE463985BF2FFA5B325FCA13
+:10866000FDF7A23A56422FC811B5BC6F51AC299BF9
+:10867000A17F8B235F07BFCB59335881FE6DBE4767
+:1086800072C2A98C92EBE1BC3E5BF022BFD7A0087E
+:10869000C4770A498E202FEF83A5317B212F444DCB
+:1086A0001BE7C3D51AEBA98C30EE0DF8DBC6C21E52
+:1086B000566EF3AE994FEB3810E6AF3B56375FCAB4
+:1086C0001D831F9F093C7B02DF87FBBCC6C67CD590
+:1086D000F4A37C50F8F4097C2F6CFE2A1B7FFFEF7B
+:1086E00083B40E3BF436F8F1BCD07B088F5176068C
+:1086F0006C49324EDACEFBB6E5A6DF371E72AED439
+:10870000E1B941C7FD8AAE3FBC40E3BCB73CD213E0
+:10871000A0FA36E31C1067677F88EE63FB71BD2209
+:10872000F87B6681776C1E237EE18A1E27FD99F80F
+:10873000F33E26E33CAE548DF3AD700D19F0B12736
+:108740006AFC3D69535FDD3ADFCCC3F26EC5FED7EC
+:108750003B7CC9F01F5C4DAFDB1066176C88F4944E
+:10876000FBFA38DFA66B229785E6F7FFC038EF1FCC
+:10877000CC37EE596882BFFFE474AB9C2780EF765C
+:1087800085D25BF87876B7D5CEFE47EDC90DF38D6F
+:10879000FB71865EBFA2C2F7F4FC24E80B37321DE2
+:1087A00037197242E48EB6E89FCF1B7032ED28571E
+:1087B00085EF20E0258ABDB8F14E7ABF717F35374D
+:1087C00081F5CC107DF3658C2F3A9F5601CFCBE914
+:1087D0009BD1758587E6CB715FC1B8766F3B1FA6CD
+:1087E000A9A76C1B2FEDB5ECD2BC7B33A97EFFDBB8
+:1087F000320FE06AE763F2CF4D865F779BC13F8B14
+:108800009C7A24CE6BDBA42BFBA99AC3E48CDDAE4F
+:1088100029C8178B7769531097252D53DACB765FCC
+:10882000E08B027C2F64F413C0B77ED777E4CCA131
+:1088300071CB2AE57D1147B1D58E2D2A2C2B849E34
+:10884000BBF56D1BEB4FFDAE170AE7BD18F9909C09
+:10885000A568EB9D774BD83A62EC2705E82BB6C0AC
+:108860003AAE2E4EBA42F9DED60269DFBE967CE100
+:1088700095AF086EF10582E1A81577D12042DC376B
+:10888000C97F127C5C0B7E1984DEA591F2003F400B
+:10889000F4F51D2EB8FCB402A1C03F009515F4B448
+:1088A0006512C9297A3FAEB8CD8BE7AF959CE3FB43
+:1088B000DD5B93ED2AC6DD5090706316F4921C9533
+:1088C000BF2BE130FC39BC1E6A3F51B2A8259DDAAE
+:1088D000B725AA1EE4654655F663F86C2BB970AC53
+:1088E000AD007941714B6D217AC2FDC9761194F9C1
+:1088F00040EC57BB1FF4C1F54EAEF7AB94F943F70C
+:1089000095BC559245EF3986F365559AB593E1B01C
+:1089100061BCF437D8D77A835FD1F86DE31739C1DA
+:108920009F8E8E7FCBF511BF2FCF674BF13EF6ABFD
+:108930001DF7264422DF736B499986F17BF5683D6C
+:1089400012ED0EE1623D7BAB57E53CD36DC5850270
+:10895000F8781F2972D060EFF31606B1FF8B5E170F
+:10896000D71DFE72B119F85AAC727CB828A5E03751
+:10897000E8BFC56D47DAB0682DAE0B22DE735F9697
+:10898000D47F1DB956FA8FD2ACF4EE4AB5FAD56C45
+:1089900053F679330BA4DFCE7072F1776C7AFD1049
+:1089A000EDDCDE36C5D5B58EFD0E3F1235A0A71421
+:1089B000E98708F7B74508995F703159F07A710374
+:1089C00014EBB51BDF95B397C8EFD7D80D3F5954BB
+:1089D000AED51FE6CAB2D69DF07F85F819EC61FED0
+:1089E000B0ABF15993FE36187CB699F45C234F9BDB
+:1089F000E3311B6C5ABECC0F16C16CAC3321752F02
+:108A0000CEA5AC52F257C0F86048BEFE8EDBFC65C6
+:108A100095A047CD0AE788642B9C67567867A2DF4C
+:108A2000DF1B27B85A5EE1179169ED805BAFFEA7A7
+:108A3000C702BFCE197EF5CF4FC9EFD59BF985E1AF
+:108A4000F354D567EE2E0E890B9F5E20F381C3FB96
+:108A5000BD7D5BE10AACDBFC2ED223F5F612F4DB24
+:108A6000E193E5370CB8849743FE1217053EEB6F90
+:108A700051BC88172C0A28D3BC7DF0E9B5958AE152
+:108A8000A7154F3AFAF7CADBEA38FFDACAB1A17282
+:108A900057E28FDDED633BFDC1E8476E1E073D9356
+:108AA000E435E85EB8DC3988832E35DEFFA066B198
+:108AB00013FAEC85BFC409F8BFB646E755F1F709CC
+:108AC00004F18944F493781465E0CD0735B6A38C9E
+:108AD000A781085DC6E3A4DF67A92EEDF2A5811783
+:108AE000B87E7A22E1FC048C771FFB79FC5EF91DCD
+:108AF000E8A5617849E3B9D8FFBD4B613BD3EFF6F8
+:108B00006F805CEE4CB7D7AE633A714AE5D2A09362
+:108B1000A58107A5DFE836A1392758C65310A7BBA2
+:108B2000586393F7E6F16E7F639FE9F27D6F7FC430
+:108B30008DE59FDFDEB51E78938AFBD5E3FB5A9760
+:108B4000F43B5DF41ABF8790A308C0ED5683BE8541
+:108B500057E8B8FFAD98F597B400E7E51B79882290
+:108B6000745D9996BAE15FB7D61706222C74716AC4
+:108B700072DB1BD71BE7063FE6AD011997BE940ECB
+:108B8000ACE3A8BAEF8A742D7687F8CD337AFB8BE5
+:108B9000B607BD886B9BFB0B9F2FFCBD3FAEF01E45
+:108BA00003BE1FBDCD77BC92F152DEB7F2FB850745
+:108BB0007EBAEC23A5CCAF2F362BCCAFAB5DEE004D
+:108BC000C7E59BADDF9535C73F6FE80DA70DBDE14C
+:108BD0007CBAA8F2B11E1BE70CF5D77D58A918DFA7
+:108BE000D190FEBAF3F7453B43E3BD93574EF910DE
+:108BF000EB5A8C1B2009B8E767B5A3C2E3EF66BE4A
+:108C0000F6E9B5D2BF4325D3D145B7BCE77F35FEE2
+:108C100042E8C379CB76235FB2C8659D6FAA166D13
+:108C2000E16F3724F7B3D46FD40759FA4FCFC9B4E3
+:108C3000B467B5497FF545E253AD9C47E3E3C53BD7
+:108C4000452DC73F5DA28DCBC306FC8E18FC3A4A6A
+:108C500074F073B738C9E505F727EC478B03CA668C
+:108C6000E20A8ECEF938FD8497EB36D7CC87EC63D9
+:108C7000005ABFCC5BA369D9DFB840B437C2DF6804
+:108C8000E6BB55CB3CB6147CBDD7C6F7ECF8FDC1AE
+:108C9000A293EB43C0756C20399DCB4C21BFC7A775
+:108CA000D72DD516203E8A0C7D7A7E3AF2FBA7B0EE
+:108CB0009EC2F9FA730ED04B60EBEA1344878573BA
+:108CC000F53F21D6BF2762D3EA23A4C71646C8784A
+:108CD000DBE85F3F7C2040E7BC729E77C002C6B7EE
+:108CE000AE05584F35F129E455895A6D03BE0BDEA8
+:108CF000E4714AFA0BA3CF6A576AF04EEE17EB897C
+:108D0000187F291E6EB7FB26627DE225B274881E8D
+:108D1000BACA691EAA0F582018DFAEE657BF1CBD9D
+:108D20009D6918DFA75F7DC0029DF9F9C2EEC98673
+:108D30005F7D12FBD5AF9BE71D83FD0D5820F5AB82
+:108D40009F39DA5335F60F898F6DE32C7C9FE170E4
+:108D500039BE0FFD1DFACD995CC37E34D669E2BBE6
+:108D6000F93C7CBD57C35F118ABFEC971D68D16386
+:108D7000AE068F703C3D6AD807C70CFBE06746FE25
+:108D8000470FDFF94FFE2E46F8FE4FCFEE7A03F67F
+:108D9000F3E9776CA25107FEF5ED97BBDAFAC657F7
+:108DA0004CBB55E29FF5F7367AE83459F23BF33B7A
+:108DB000EDC458EDA17641F8F8E1F3DF143BFC1760
+:108DC0006DFAE5F769D2A9596F8AF4267BDC40E792
+:108DD000BEF7135D37ED9E05D2CE3CFC5CE2DF1F93
+:108DE0007FDB00FF7DC839387BEE0B910248E31C26
+:108DF0004DC9DC1BEA17092F8F2AFA1D7642E1873D
+:108E00007E7DEC00BECF5488040DFE5EC61BAB61B8
+:108E1000BF141631EA88077FFDF3030137C7F776E1
+:108E200002AEF45CFA478A05FF5E8A5DD3D98F40B3
+:108E30007AE10368DF6EF73E8AFDBC385FD61F30EB
+:108E4000E8B329ACEE9867AD4382A956BDE9812B02
+:108E5000D14FF8F96E6BD0B7FF269BCEF949B78C8E
+:108E60002F9E92E76CE64F9AFBEE97E639AB87F8B8
+:108E70001DFB65D48EF230DFA8BD36F43E8E993FDF
+:108E8000915022BF1372C9393B3D9DF0FFD49F8A98
+:108E9000F0C09FBCDFE13F887D2BB1F5C36027F5B3
+:108EA0002BF5F07DB584220FFB4D9A22E57726C283
+:108EB000C7F9E9029BBCEFB4C0FB13E66F86DE9CEA
+:108EC00030BD34D84CFB584F1C11FE716F7940F403
+:108ED000E5B77324D61ADF31F11FC3FB76CDC7F394
+:108EE000DADC72DDE678F883FEE032F8ADF0A50B4F
+:108EF000F89FD7BF2DEF05AED7B6097C67A02555E3
+:108F0000E5EFF29C9ADC510E7A59AFA81EF84109A0
+:108F1000ABF4C4FEBDFC7A94530B2E32F4A9C709FE
+:108F20008F0A635BBCC847DAE47579D87ED29D614D
+:108F30007C48E6F799F36F7467F1FC2D343FE6DB6C
+:108F4000E4B607A313E1CF72B1DD9FE7EE3886FBED
+:108F50004B796E3BFB7F4ED57D6F38F2385D894E85
+:108F6000D67B2E19BF4AEADFD9818F9F398E7D7556
+:108F70002AECB73DF062EB6CD8D55FBC6163DCB224
+:108F800095919C603BB996EDE48DEE82D8507EB809
+:108F9000CDF0CB99F5A75DFE8BC043DB4D9E93C012
+:108FA000F78452B9FE7E252A6DA897EF6E1AAE3966
+:108FB00031C1A698631C2FDA1229BF5B505DF03CCB
+:108FC000EBA99B97D018C88F223908FD99F624E3A6
+:108FD000D761722E5CFFB9BEEBB3678E27F6EEC782
+:108FE000D6DFB4F3E5FAB303078F617FEBC96E8672
+:108FF0007D529E74EEA9EFB1DD247F75EBD2FD1E8C
+:1090000019093FE2F96551DC7E857D2756FD17EE93
+:10901000DBE694BF7B4374A6877E17647895D42FD4
+:109020005F5FE0CDAA025EE3326ECAE5F99C89FF7C
+:109030003F1B2CEF0F6CBA2B9AF30E36C1364EE461
+:10904000EF7BB73FDE879C2DA8927EBD27FFD99B83
+:109050000F384CACD20D3AD2F8BB28D5F5C7DF4754
+:109060005C635352DF74ED35DE5F5AEB9D50D5C71C
+:109070007B97D3B7C3F9DA076FB5A7E23B068FFA40
+:109080009C3AEE378EDA72C1067FD5C65249A71BCD
+:109090003BEA8E217F33906AE7EF6BEDEF38C7FA3A
+:1090A0004344A487EDA21D8DFE07700F343058FE97
+:1090B0007E45C4CD657C5F798BAE7854AA3FBA7982
+:1090C000DBB481C02F8FC2DF7398B230C1FCFE7A4F
+:1090D00009FC1B6FA466719EDCA1820C05F1A0E562
+:1090E00025F23BE6CB1F93DF752A4D1DFD04ECCC2A
+:1090F000D3A9876DF85ED69FB2FCE3048F23F95A9B
+:10910000B6BF9BFD6B7B0A04F399F7D796CDC57C60
+:109110009F973835F43B94B86D1AE2A33B370B1D8B
+:10912000F6EFA105736F1C083E3256651FC5A4CD2E
+:10913000278B705F6C922E3C605BF66E9BF0921EEC
+:1091400066EB56B8B4DB651CB41FF111C0079F83F2
+:109150000BC5CF05A51D47A88BD816D3F13EE6D980
+:109160007E8F53E0FCB7943EC0FC6ECB66D5FC5EB0
+:1091700018F327BBC19FB6E827F9BBFC1BFF443699
+:1091800032B56F07E3031C47CAFBE48FA6AA1C276E
+:109190006FCE75EE93FCB2733AF6F5E897AA0679AE
+:1091A000B067E41359C8B7DA393CD2CBE3FBB6DA7F
+:1091B00031DE1EDC4BA27359BE634A7019D54B8851
+:1091C0005FB27F4ABB845F32BF36D7B367D650E603
+:1091D00097CD06BF34F36A6E33DA0F386B8FE2FB3C
+:1091E000407B9E563CEB0028D171F4561A7F157EC9
+:1091F000DF01FEA9CDEF6EB896DAB54257972DF98B
+:10920000D2F9BED6A58A4008DCAEEF8E1281103DA1
+:10921000730A5922A1F522D7204BFFA95AA6A5FD12
+:1092200086E41196F61BF53196FA829C89963A09E6
+:1092300050CEE3F1D27F584FE38B510CEF9DDF9678
+:1092400079B1ABC2BE6FB7AC7DCDB425F06B1879E8
+:10925000414B3BACBF73B0FDE66FF077F7B6E1BBB7
+:109260007B9E4BBF1FFDFD2AABBF3F2249EA193B46
+:10927000939D8C0FEF2DB87301F244370C74735C1F
+:10928000B06299FF39F081E6D4E21CE81F3B359FBC
+:10929000E691FA5672D6B89E1466FEB3F7EFBD2F6C
+:1092A0002244FB21DC274AC3B97328C029BC217E94
+:1092B0008CED377FD488F60D8AE8B2197E09E02F4D
+:1092C000441CD63570FFA78D4F25F2B9D546705C8A
+:1092D000BCE3FDAF53BDFF5AF93DAF4F5267B9B084
+:1092E000CE474B550D795703EB43C6A7FFD952170D
+:1092F000376E829C2638C4915DB57DF3E8C06C2939
+:10930000A7A55FB45CF6A7295D807B4476470BFC7C
+:10931000B49189765EBE6D4784859EF0500FA1138F
+:1093200073BFBC7F560E7C47A7D0FA120282E310AF
+:10933000D86F2064BF7BEEF9F343AA15AE67C01F58
+:109340009B37172E83BD99A0070222B717AE307343
+:10935000F13CD2808B398E37C3CF7EF77EE6EFF5B6
+:1093600019EDE30CB86D50FCEF436E0566CB384445
+:10937000385CECB344209A806C2F775AF6670B5810
+:10938000FB5DAC8AB7E84F1C7F48EF9D4F18F3395F
+:10939000FD4FFAB09E4767A9027AAA236CBDF80B6D
+:1093A00098F44CED07EEBB70087EF74D25324F2444
+:1093B0007CBC5772E57DAA665DC625C2DB09CEF787
+:1093C000E29C1CC9765D7E67CEDAEEB2FB02F07BD2
+:1093D00098FEB3DC94DFCCE33828F13FDC8777E8F4
+:1093E000D67DEE8991792EDB6F94BFBFB680F843AE
+:1093F000287DE6953E207FAF6D19C9777C077C619B
+:1094000006F3F70C677009DECBA88B14F043ECA4CD
+:10941000FDE37CA3D644CADFA7159E87A2A99EA11F
+:10942000C608F801B63BF49436A29B5FDCF8D1BACB
+:109430001AF483BF9DF0B0FE60ED1EE87F42213C30
+:10944000BF4EEA7BA17A779EB32B0576F69E057F09
+:10945000FD007C2DF02317CBBB51463EA178D1B542
+:10946000177C7963EA5BAE6AD68BEA39CEB1A53D4B
+:10947000F00EE4E3F91336680297D513FAD07F0AA9
+:1094800016D2FE125C278F21FE03FD07EF87EB3F0C
+:10949000BAF0F27DEC1E3F47989E5CED3A21BF8307
+:1094A000E4121A7EDF2C5CDE2BBEE7D95FBAFB56D6
+:1094B000A92735D58ACE689C6F983EF49B65528F5C
+:1094C000B0AD768820DB2BED1C97A9887319751F2A
+:1094D000D74D3C0DD7F321378097CD89563D7F94EA
+:1094E00033F807C84591E0E4BC8FC2D88F597F5844
+:1094F0002FA43FF8545D7410E7F7B09AC3BFB3E5EB
+:10950000D29C7C5FF1AAFA7D4E8645BF5F9F738E29
+:10951000F5D8D64EFC5A01F4F2BB8784FA0D2F37EA
+:109520006EF839B538C441C4F71B16A64BBA0C8384
+:10953000B7A21FFD12E364075AF8FCCBD347B3BFB1
+:10954000235C0F6E4D1D7D35BDFF8E8580F74DED83
+:10955000C7AEA4FF361BFA6FB3A1FFB642FFCDC75B
+:10956000F71CE4B9FE9FD7FB0372FDBAD4F35BA1ED
+:10957000E7EB38A7F99C97FE7086CAE7F4BFB1EF16
+:10958000EDFF95FBCE50838F231F47FC2A82F335D6
+:10959000EC38D80988C3FCD4853C9721D592EFB428
+:1095A000E696454E91F12E4525FE1635F21917FC2B
+:1095B000163B73558EE7E48E2C7B1DF6E3A6DCB2DA
+:1095C0004445EFDDDFA659CFB05DB9735659810828
+:1095D00079BED3F8FD96707CCBAA9676E58BCBFC52
+:1095E000CF032E9BB2A45D4AE825F32B74C9373311
+:1095F0006EF272FE6BE5CFFC43AEF49D1873BD9B1B
+:109600001249DF8DC3FA162585F2B97969FE9DB33B
+:1096100069BC1D2385A75147E94D5942F088488D03
+:10962000F094503D3B38FE0F90F73B7D52FEBF76E5
+:10963000E8C60AC4F7A289BF45523DDAB8CF1CD1AB
+:109640002DFDC27306CB7A529768C73DF31B66495E
+:109650007E99982AE5CA6F1B647E12EE038C1DD793
+:10966000FBBB8E89BBCF36213FEB56D213747CDB1C
+:10967000F2C5BB05F4F29D7B153100F4EB0C1641ED
+:10968000FFDA3821425BE7C1A722261DA9A67AF29C
+:1096900020E2E7F0DFBAADDF335EB6DBAA9F4D0E06
+:1096A000D3C72685E55D9F5D68E867E3C438C833A6
+:1096B000F3FB38A2ED41DF5FC7E1774204238DF968
+:1096C0009D9C70388FAC2BFC18FCFB74FD982BE62E
+:1096D0008198DF4537BFABFEB36F4F49415C6347AD
+:1096E000A3B4EBFED1EFAC2FAD9F2E108F5C5E7F4D
+:1096F000A32826E56449FD4CAE972C92F1C40FDEF9
+:10970000EAB241EEEF98A5B2BD326A46616436F422
+:10971000804495BF1FB5A943E2A769CFFD2F7DD92E
+:1097200057250080000000001F8B0800000000008B
+:10973000000BDD7D0B5C14579AEFA9EAEEEA6E6828
+:10974000A07806086A21302113C456D1681EA6C02D
+:1097500047D03099D6A083B91A9B87808A064D32AC
+:109760006BB2B816823C1412A28D41AFABAD4876F5
+:109770003633E3258FC9FB664167DD3C1DF2B81324
+:109780009D710D4A2471EECC0EC6987176DD5FEEA8
+:10979000F77DA70ABA0B50636666F70EF925955355
+:1097A000E7D4797EE7FBFEDFE39CFE49E71991C52C
+:1097B000306677BA99651263B9BE754D4B18A41718
+:1097C000E5385517632B3DA2EA87A7C2BA2C115979
+:1097D0008CF952BDD3B642FE29CF07B330FDA5E2C6
+:1097E0009D0649965B64612C96B1BB2E2FFF4122EA
+:1097F000D4179B21C9586E657EE771AC3F26435252
+:109800004481B13B3C9DC78B207D47BCE45614C6C8
+:10981000D2BCC72D0CEBFD92B1DDC98C6D135AE69D
+:1098200026405A4B1658077C7FDC73205586F2176A
+:10983000D29D2A83EFDF3808FF81F41BA916BF00F1
+:10984000FFFB35FEDD35F44CBC64616A346371970F
+:1098500004A64E81B4D523C8D0FFB87C91A9E98C69
+:10986000FEBE867FEFC9EF996383F6B7C81EA71BBC
+:10987000F25B0F2E70327C662C76B20CC66C8B9E1F
+:109880008B67E319AB816AB07FDA04E94007F44FD4
+:1098900054DC9E34485F74A50A38BE6DCBEE4EC0D2
+:1098A000EF66799369FCBE05737789D0BFBA4C899E
+:1098B00059A07FDB26BC189F0CE5A56851B028D4C1
+:1098C000BCEA80194BC4FF83F4C9992DEC51C8DF61
+:1098D000B640F46F862A7CF9079C0AD4C73C0B9CDF
+:1098E0009EB011C697219D16C221BF5C625D0E7DA0
+:1098F0003CE3F9D3113754AFA8781ABBA11F17CB9B
+:10990000455A07733D57ABEFCE019169461AFEBD2C
+:10991000EB5208D302E62F9B4507A567396E0C2A48
+:109920003F474E09CABF3BFE96A07CA6A91FA4C311
+:109930003CACD6FB3B4F9912947F48AA3C8A74D02A
+:10994000FAACE0DE0CF9CBD26F0FFE9E75CE5D0156
+:10995000E35B136F615BDD90FC89ED4C2FE4ABF0B2
+:109960000FF6BFFAD55FD5DD0AF9DBB21D0376C865
+:109970002FF5AF93703DD7302B95A37A60BECB32D5
+:10998000FA4FB24CC8EF84EF03FA5BC69ACE5BC2C3
+:10999000F1195CBEDC1B16D31F0A895BD9AD5F5B76
+:1099A000F06D0CCD7B0C2FC24E94CCAADE8FF4CA86
+:1099B00058A545A6E5AE7E07F7C3E508EA67ECC102
+:1099C00059D5B82E728EA332623A96BFAFBA1BC673
+:1099D000F9059687FC987C29884EEB046A82690B0E
+:1099E000981FE9EFD715B3B2B371DF31D643E55F06
+:1099F000EFFF4F168E45E0BB807E02C53166D483F3
+:109A0000FD3C681FCA877970A406B7437FB01E5417
+:109A100044E44905C6E5D4B39C31B51A8E0B2AA19E
+:109A20007E3B1C4D3D96CCABD493C2AB8931EA81D1
+:109A3000769D07ABD517B3F8FB85F1588E7F0F5392
+:109A4000D5F5358E35958F03B28E623FC717C2CBE1
+:109A5000A9BC5A396EA85E47BCA43A3387BE1F1C06
+:109A600037CEB9514E18CAB7EAF54F7CE365E685A3
+:109A7000FD7D535B70BF435D4CED84F7A15678BA12
+:109A800086F6C7BD45BCFD654522EDEF8F43D4CDBD
+:109A900047A1FFF50B45FF01C83AB4706104F28B92
+:109AA000D1F657FF2668F8A6A17459B94DB343BF44
+:109AB0006FDE13B01EF0EF0B5E81EA4FDF2305BDB2
+:109AC00087BFF8D4693A7DE9FBDC1AA74FAD82FF66
+:109AD000711FFE2E64A6313680F465A60375BC673F
+:109AE00033E6C7EAF94CCFCF34E8425FE7B1FAD2A8
+:109AF000A5FCE4FECDCF6471FAB4C7E31B6F810D02
+:109B0000D2E332987B2BB497E20BEE5F5CD285EA0E
+:109B10006DD839AF8BE8A24EE8ED16915F0AACF232
+:109B200067D0DED8AAE0798E2BB09DB603BDC6F90A
+:109B3000EC41EF7FE98DA44EE29F2360FD58E07871
+:109B4000A0BF92F7F3FB71327C1912DB2AF0F79A6F
+:109B5000415FC9B81EB04EC837CA991FBF3F92FFB8
+:109B600045F7D7906EF4887EBB309C5EB6018FA51A
+:109B7000F24B18F15F737B21367F36B6B7AD92B9E1
+:109B800035F7F0FC6D9EA2EA5EC89760BC5123E4F5
+:109B90006724BC40DFB379B04630C4B8F2E0F95B6B
+:109BA00006F41EC82733F37766637F58399385041C
+:109BB000C6A61471B9325EEA5A81F58C5FEF64D59E
+:109BC000D8EF8C0332D271A6D4198FF26DDBB2FFBD
+:109BD0004D72557BC5E1065A40B9C5F9C62B8EFDBD
+:109BE0001DB42FA0D219A3D329704CA2F334ADC059
+:109BF00083FCC59721BA516E4C94B4D834ECFF3134
+:109C00000BEB80F5B745F63E87FCCC765A706B0CB3
+:109C1000FB71E6991F63FA5F6F7023399D5CFFE368
+:109C20009BB15FDB81EE553BBC5FE00E9721FDAC45
+:109C3000C31B5508F547593D3D56A83F2A0FFA0664
+:109C4000E5A373C5A0F948659505D8EF4206EDE395
+:109C50003CA82AF10F41A7F742C7BB7C3E1D4CB67A
+:109C6000C3FCB05ADB6F07F936EC0F21E94501F36D
+:109C7000F794316681FC9A4AD61B8A1DEB4D8A44C3
+:109C8000BE8DFF8BE37D63B942F3DA1AC3147B0404
+:109C90003CF38B62B1DF6D5E59E7371A43F96B9184
+:109CA0009817F902B37652BB35F36461EB244CC3C9
+:109CB0007A64E17A24446E85F97D7639E70FE1A272
+:109CC000DA68C1FE89ACB703E9D473E0AC00CFC554
+:109CD0008BA404C4033ECF42B109F150D2F67FB445
+:109CE00024633F1CBC1F0B1486FB26F4238B3F17F9
+:109CF000CAB576CFF81DE288588FC49CD055DF983E
+:109D000085D4FE850CE070F0DDE2099007E5EDF901
+:109D1000A25F84F4DD499C8E633298DF0EE9131F45
+:109D2000F48A98AE87EA35A0BBCF703D800FD52767
+:109D30001DF8F92CA8670BF003944F317BF6D7621E
+:109D4000B9B2E94C56A05CA89FE3AB7217F3AB50D5
+:109D5000CFC4315FBC9982F47F50700BD08F6D9D62
+:109D60000BC53AA4AB24D19F06F9C793167E9C92EB
+:109D700085FD9248DA3D11F3C57B2877EB93403A95
+:109D800041F9B02CC07F90EF00FC47784800FC8779
+:109D9000FC21417223BE1B8ED75401E925CE134C02
+:109DA00017F7787A6C88D7EA6595F09A2FE3870ED3
+:109DB000C45DB631390928AFCA7A394E2BF348074A
+:109DC000FCB48F83715639534F3C82E302BED105F8
+:109DD000AF9C2D2FB5E1FCFAE25D0CD76FDB84B9A7
+:109DE0006F214EAB5B25CA88D30E495DBFB3E03E01
+:109DF000182329C81786E1A6A4EBC361807B7E994E
+:109E00001EA7B33A24414F691E32E3ABD69BCF71F4
+:109E10008803FEE1F8E6B1F8DE0CC445C1B8C5928E
+:109E2000047806BE2FDF637A8F7826139FD6A1F7BA
+:109E300030AECD857F2578C6FDFF079E995B240C4B
+:109E4000CAB93F0D9E291046C233B13A9E8935E109
+:109E500019AF8E6776229E99FAE7C333C70AAF0D12
+:109E6000CF0C5FE72BE31B03CFC4605AE674F10D00
+:109E7000F14CBC0D3E1E973F0A9EA91A8667B26D33
+:109E8000D782674CEB3650F80DF14CD29F06CFD4F9
+:109E90005F239EA91F05CFD4FF99F1CC83A3E0993E
+:109EA000FAA4859E6C48872C102723FF4DD33E2FA4
+:109EB000A271E0BC407EC1A2F5C70B910FBDEC20A2
+:109EC000B952BF6C998C725503024FA371725C92A8
+:109ED000792692D675A2D4FBCC8FB1DD537637E2CA
+:109EE00016038F9C5C7F8F13F1CCEE38EB246C272C
+:109EF000CAAA907D00F0C9778A6211AF707CD287C0
+:109F0000F84419099F747E3B7C92716DF88429EAAC
+:109F1000AE50A87FA918C6A81DA62E21BCB15852C4
+:109F2000713E7EB1A83F6705A443122C0CF5DBD12E
+:109F3000F6EBF5E243B190E399217CA851FAB9C25E
+:109F4000607C34EE01751ECE1B43234DC295F0A5F7
+:109F5000A6EF07EFDC5528A7413EE0FE2DF37BE797
+:109F6000E2F8E4F1D6CAD0789E7E06AA4A82FDCAFB
+:109F7000A6F3F4DB901E53E4AA14215D3A488FDF68
+:109F800069447A575889E4012C545A6E3B6D837D9D
+:109F900058BA2758AF78C1CBA8BF37FBA511DFFF50
+:109FA000A5FB73AC90B7BB74BC321E999C81978D96
+:109FB00079F2BD02A806F0A8CFE64968710D5F6787
+:109FC0005B6CBED880B804701FE2295BA447C6F55D
+:109FD0002D58343902F150A6C4F741BD8ECFEB970E
+:109FE0006DA47D63AC3B101AE1F5CC5337E8FB045C
+:109FF000F0AD6B687F003E950B5D41FBA2F1BFD3D6
+:10A00000BE30AFA3319FDDDA1747902FAA031CFFA4
+:10A01000C29F15ED9333AD8282E394AD02F1C5B9D1
+:10A0200090AF24237E4A1430DD152BB01B203DD782
+:10A03000F2AEA512DAEF9E6E97ED1CE7DC3B09E469
+:10A04000D42CBDFF8724F95D17E477FDD1CA36A370
+:10A050001D93DD61C5F2F137C2BA001D3017B73F5D
+:10A06000C9F00F8E674E7C30FE9A69B223DD61C263
+:10A07000613FC7FF8171BF50A4E3B1C92C0BF9ED5B
+:10A080006F36BDCCFA70E15A9EF2FC27F467059654
+:10A0900083F7AB58B05C379E13D6E7BC86EB35EE42
+:10A0A000F23FD17C77E732B615F874B2CD32DF0DCE
+:10A0B000E37DEE5D5111157AD27C689576C2F14C44
+:10A0C0008EA6FDFFDCBB873FC880EF9E7B73721CB2
+:10A0D000AEDD0B7BEE7B67099657946D1958BE4138
+:10A0E000227EFAA2FFA1D0FBE1F9F2C11DF7E093B5
+:10A0F0008178C27528DD65233DE6F906A91DE9B31F
+:10A10000BF2D25D4EB1AD2A31EC04A6760DAAD4C2E
+:10A1100086F71FEA782867B9CCF9C386589A87B7BB
+:10A12000C7300DF1F9F20DA17E9CEFE5F2804D40B4
+:10A1300079A4AD5B7712F6E572C7C01C013E09DF5A
+:10A14000B266D251A86F39CAF6DB40CF39F3F0B30B
+:10A150001AB4D3F4A07AB288F6B72C219F2ADCF087
+:10A16000CE71C4D5850E9786763D33FDC10E9769B5
+:10A17000DE199773F64AF81EBA72B288D3D793A63F
+:10A180007496290D7F5DCE699C4EF1AF30C24BF9BC
+:10A19000EA413ECF8E24E647F96E7579088F1E108E
+:10A1A000BAFEDE85F379C2CE3AE0FD27FAFA1BEB60
+:10A1B000F87449B289FFB208E437F78F6D0947BADE
+:10A1C0003E2BB0DE6A78161F2C5E741BCCFFD9E6DE
+:10A1D00005A457966A5C7F3CDB3DE3A709905E01CE
+:10A1E0003819B1C4B9EAFBE692FED804B306F98B7C
+:10A1F0009BF97E28F5097EB4CBDFDDC6F53EEF2561
+:10A2000063FFA8E15303E8DFD01FAB5F0DA1EFFAB6
+:10A21000CE33C21FDE3DA76B50DF2B531D038A1BBD
+:10A22000F7894742FB7FEF7E816D874FEF68BAD594
+:10A23000BA01CA1F03FE2504EC9302F807E7DDAC60
+:10A24000A70CDF275C6F31EF9784627D9F4C63D34F
+:10A25000AE739F28C5B12807DD4FDC3A827E673C8C
+:10A26000DFDE349DCDB631F63A8C1F9F6F8F697952
+:10A27000C003F475CE06FA26F2D530693FAEDF1B77
+:10A280009B1C94DFB549A6E7E14DF1F4FCF9268566
+:10A29000CD867E1DDD944ECF3737B9E9FDAA0DB3CB
+:10A2A000D86CD872A51BEE61B341EFFD698985DBDF
+:10A2B0005FBC8EBDA1506F1F2841C8477B05EDBD17
+:10A2C000E94827EF59C81F32FFE5CAB9A81F0DE2B8
+:10A2D000F9029B7613CC4F89AE47CFD771CFFCCD17
+:10A2E000B6C9B550BE18F56A785F62F54AA8571727
+:10A2F000B75982F8E79CD545B38AD1BED9F66C6DC3
+:10A3000002ACB3579B241565E0BCB4CC8EC2F16D92
+:10A310001168BFCF17ABAD5158EF56C15DABE844E4
+:10A320008EEB9C1A4D741D5AC2F1C2850D478E6288
+:10A330003D66FBFE20DDFC4CD0E9ABA7EED62C4EF3
+:10A340003788EB4BD367B0D901FD42FBFF06A8BFAE
+:10A350007F865DDE2C23DC84790BB4DBB3D7EB1E68
+:10A360000DE4BF26FBBFD9CE5FEE2F94900F0DB743
+:10A37000F307972B290ED68727862B75F128B7C6AA
+:10A38000F37998575BB8F71DDC4F2553BE3F0DD2CC
+:10A39000D9251CE7831E1B81727CA9BD6BEAC728E7
+:10A3A000FF9EB0937DA34F600581F45757C2F95DBE
+:10A3B000BE3E5F4C7579D14E51A4CFD3B983297578
+:10A3C000E80FFA02F46BD2B72B2325B4431443EE03
+:10A3D000EE49588ECBBF78BDBFC5BABE5C3C5C8F22
+:10A3E00052516FA47A49FF0DD69F8B747DD7A86F09
+:10A3F0002914C0EF26BE112FE13AADCCB374A13FB2
+:10A40000B0D0ACCFF642DB71D41FDA5F46BBA08F71
+:10A41000AA81FA2AB59B3254BFD12FB39EBAD2C5B6
+:10A42000F7E74A2BD7578D797A5E9FA7AF4B82F516
+:10A43000D4DE9D16FF01D48B76DEF727D153DB8B5C
+:10A44000AFACA7D238C78F34BFC3F4CE8338EE5237
+:10A4500036F4877A68A1BEAE303175E8CF8279A92B
+:10A46000DC0DF47ECB8F82E7E1AECB13EB50EF2C0B
+:10A4700006BD13F7436143703F332577DD22F8FEB5
+:10A480005CB663409387F76796231867CE9183D3B2
+:10A4900077C707A7E729F661760E87B1AEC9C3EB88
+:10A4A00097BC97BABF46BED466F107EAA9B4CE6896
+:10A4B00037787CC7038FA15C42FD8C0DCD8F416F37
+:10A4C000477C96F9C82FCE34C17E1D412F3DB7EC95
+:10A4D000CEC767209FDB6853D294E1F98C75921E3A
+:10A4E000999923139EC9D8F8B3203DD45C7E19CC2A
+:10A4F0005FA0BF70972E4F4FDA14D2B74F364AB2D3
+:10A5000006AFFA9A2C21C8176AF47DCAAAA65C4540
+:10A510008FE176F28952CB03D4BE28BA3BC88E14A1
+:10A520008C7773C23F27BF7A1F2CBC1DF65119B61A
+:10A530008F38E175597D0CCBAF0F77E33AF736DDF5
+:10A540004778BEF7A0E5007EBCE1E5AA7D3F66A89E
+:10A55000176C5B741BBCDF7DCCC2504FB52C048ED6
+:10A5600089FDB37AC211E7F7FAA68407D2BF81DF6B
+:10A570008D34E0765602EDC1AC1F33ECEDD82F33AD
+:10A580006EEFBF5996709FF687BD49F3DBEB043D34
+:10A590001DF7BDF612E1E3A6151C8FB34AB9AE0B49
+:10A5A000D235BA9E340C3F9970BA65AD8D7591DD88
+:10A5B0009C517F974438F4B49BD206BD9518FBC3D9
+:10A5C000934CB8B1FF23A02F98AAFEA623BF433B0C
+:10A5D000FAA73EBB2224A3BDF6B3669417E7DEB507
+:10A5E000B8753B6A907C31FCC5FDE82F865725BEC7
+:10A5F00097483EC889307FC82C5BEC663B2DD987D5
+:10A600008DF6CF69290CF1E6A71FF1B882ABC9AB73
+:10A6100072FFBAA3886B4A415F403E5DC6F2E69284
+:10A620003C9AE570933C32B5B70CE55BC0BC9BE54A
+:10A63000D9D5E4D7D5E4D6ED2520B76E61D72CB7B0
+:10A64000561547113D1A728BCD76955C510EB54566
+:10A65000D6A1DDCC2C879034502E5C410ECD66D334
+:10A66000AE5D0E95EA72683332A2A957EF97B91F13
+:10A67000AC2552C27E16613F812F1461BF3287CB59
+:10A6800021A35F067F37F7AB18FB15309E12EC97BE
+:10A6900030D4AFBB067E4F7A765FAF40F46879DC8A
+:10A6A000C2BA687FB6F0FD79B08FF4ECDE9376B273
+:10A6B000579D5CFF3F689FEF7EDAE247BF4F41C77F
+:10A6C00014925FD7B1AFFFF6BF725F5F0DAF98F125
+:10A6D00009D32225EBB5AD07E1956B5D0FAF894E30
+:10A6E00000C7136ED6AAC318F2E33EC0D8B89FCFF6
+:10A6F000AEB3FB6BB97D3007F7E7815691E1383F88
+:10A70000D3E9FF17ADF6905EE2FBD157F18F6A24D3
+:10A710003F7615A9FF80F37FF22DEF387904FCF125
+:10A72000559142F59AF5B6F78AD44325B1D7DE8E16
+:10A73000D92E557A708314827A64B6A313EDD8A506
+:10A74000071F934290BFAD7710FE2D3D5845E9F8A5
+:10A75000BF7128F611ED5256C2EBA50D02F1D7D20A
+:10A76000F2B4BA6D68E72A72919DCB6CA762DF1CC8
+:10A77000FF98F04E301E1A8E77C6111E2A463C24D2
+:10A78000FF77C43B2F13BEE85319237F2F33E39D7C
+:10A790000B8487CE021E6223E099233E8E87CE0073
+:10A7A0001EB2B3E1F9574B9F5B164678496BB690E2
+:10A7B0007DDB8C674EDAB83FFA24E01F0DFA770094
+:10A7C000E81DF7F581571CFBD19EDED736E5D8741E
+:10A7D000B49F548B6E64BB191B6DE494DCF5E9C027
+:10A7E000B39A75B81DED3AD6FBAF1CEFFE75AFFFFF
+:10A7F00021E0A53D84C7A0D50CF4AF5D22BF524334
+:10A800008648F8BE5639F3FE78485F8C116935F7F3
+:10A8100066703B966D09237BD1A98CDE551417A376
+:10A82000488A4678E9378D3741FE27D556B75DE12E
+:10A83000720BF5AF0C5B25B916A2015755A3FD4B62
+:10A84000B7FF8D7D342684E244C25B18FAF39D790C
+:10A850009E5CF4BF17E532772E7CEFCC756B2C0C29
+:10A860009E5DF31C0A3C6BADBADF3F66A15345FB0E
+:10A8700044A39DDB2F17307F1AD499119B938B71C2
+:10A8800099B57254143671243FA77B3CF46F9CCA6F
+:10A89000E3FF6A5DAA2319E7D325925EBE25C6CAE7
+:10A8A000842C4AB7E3F7B6D885F23D906ECE2AB233
+:10A8B00008CA103F6E8EF9C09112A0BF37BBC45CAE
+:10A8C0003FB43FAEAB2717E31E9C2E711A4D10F319
+:10A8D00066A37D382C09643CB6EFFAA0EB6F20BD6F
+:10A8E0007DC89E1C3E298E5463DA1FA1B94502FA29
+:10A8F0006358BC854500FF0D63AF6BA959841F07E2
+:10A90000907F871648AC2B805EEDA901F1008CFB8F
+:10A910004D07F393F1FB807C486F5CA1E3C1EBB77B
+:10A920008FD5AE003976626CCB04B453C664490C43
+:10A93000F5258B871D46B91ADD60F1DF0DF3169DF5
+:10A94000CEE96E5B9AE8473AD8BE605D3CD6DB3C08
+:10A950007527C5B5367BB89F223AABB719E971C7E1
+:10A960001291E27EEA975CD9CF3CF612E02910956D
+:10A9700053567B9F5A11204FF76EE0713A174ADA0F
+:10A98000852EC209FEEA77A09DB1188F20633C6B2B
+:10A990007F7749164D03F97B4F1CF67797A0DE9918
+:10A9A000EDA8443E92B821980F9D69F807C188AB85
+:10A9B0008B9F36E4373E51D25E8D76B72FF4B88444
+:10A9C0005F57B477AF867ABEDC1021633AD1845FDB
+:10A9D0004E49CAA9BBA0FCA9C744A55AD78F991153
+:10A9E0007F22F2385BC4B9665C93A8E35F73BF82D1
+:10A9F000BE071C9758124AF10146BB83F6182FEF89
+:10AA0000F760B9A1F880207B8C39DFE8F757159EF5
+:10AA1000C32B62D1EEF3238A23286403362CA76468
+:10AA2000C875DFCD22BBB41E37C8E5C3387D3CE313
+:10AA3000CCE3AF8AAE433FFB19D551896DD6375E63
+:10AA4000B0215D5C84EF59807E1E88175CD3A8FB23
+:10AA5000F4B7FC65C751F4EBC37620FADFABF30F14
+:10AA6000DA2E01F100DE9F3C537D530CF9F3A95C13
+:10AA7000E206E647BBCEB8AA5EC1CBF5CA121CEF10
+:10AA800038A37C6D30DF4FA9625A68263E83DF8F82
+:10AA900034FF83713C029F372D60BCBB56AB9F23B4
+:10AAA0005DD6DB9413486FF5F3245983F6EAC7CCDF
+:10AAB0009D877C21C5C3E388525CDB894FB05491EC
+:10AAC00071FF1BD73BB7E96DF83C8749CFDD961F77
+:10AAD000978C7AC1132BB8BDABC6359EF06B18F0BE
+:10AAE0004DDC3F06FD87E6F3F8A041BC983172FCCF
+:10AAF00051A83E7E51517621FD5FC4783E65F4FD3C
+:10AB000066D46BAE6FEC6AD5564AF60EF79B77911A
+:10AB10003E292AE82F3EAC7C614179B13357DC8F66
+:10AB20007E80C682ED148F155ECAFBDF00FA08D75F
+:10AB3000F77B48BE3466F1FC9B57AB11A5406F0D07
+:10AB40001E43FE54523EE835B1D88E61FF684C3A40
+:10AB50003CE125D4BFCB4388FA6A629E233D660B55
+:10AB6000EAD6404F5B3AADC487B774D61EC738B833
+:10AB70002D2CD78AFCBC21B92EBE64029497D74FE6
+:10AB8000A0383368214D1E926FBE5C793FE2DF8FA3
+:10AB9000611BA2FC8A76B1FD1827B1B0743CE1EECE
+:10ABA000EFE7815C43BE2E4BC9A8F757BF7A7F2ED3
+:10ABB000AE43FB962892E34372D34DE7047678A226
+:10ABC000B6A27E73315F47BD3A9F8FD2D7D7D2F4FA
+:10ABD0001D01FDAF86FFC388C3AA47FA860AED6C44
+:10ABE0004104FA8BCDEB511FDE4372312C9FF733BA
+:10ABF0002E89F97311F714546A688728D2E5DAB8F8
+:10AC000086F35B507F296AE954B13F2C97CB05232B
+:10AC10004E6CB9AF45C379776604CB0FBB495E581C
+:10AC20004CF2644E69B07F45616E07F6F3948BF386
+:10AC30006DFCBB1C2047CCFDEFD4F7AF21778CF720
+:10AC40005790370B892E6C5D846B00EBC896DBD96F
+:10AC500030BB9AA08CE627B646F63B86F4D4D1F5F5
+:10AC60002B2BEB0FE0BFD71AB730C752714A423CCB
+:10AC7000CA24D94E4F4672EF540523B9571FD6AB9D
+:10AC8000A19DFEDC9DCC7D00FA79A3B593F46C9771
+:10AC90005B1134A8BF411143D2A1A9E42DA993B0FF
+:10ACA000D9782FB7672EAF62A22512ED3595EFCF79
+:10ACB000C1FD759B48F61A2DA785C6A989AC670703
+:10ACC000E24FB987EA4B7A982988CFB67A0EC873D3
+:10ACD000E0F584326ED73CA059E7E3F6BF01239537
+:10ACE000A081CC9B0C3AE5F688735677C448FAAA43
+:10ACF000F12CDC90B207FD5046FAF43267817F8474
+:10AD000075FA68754E3DAE134B6F217DFB94C86498
+:10AD1000F453F50BBD89E88F3D58F6FCF38E3B519B
+:10AD20004EFB4E31DAB9FFEBF937E1999C96E39C83
+:10AD300003CFEE7F9AF7FCEC64E47B56F2D70282F5
+:10AD40007D5EB562BE48E92FCB1A1F427CFAFB221A
+:10AD50004F2BF203D8670AD25D72B5E8C1FD8E7E33
+:10AD6000E3A880712C291388DFFCBE48DD8DFDBA75
+:10AD70008672FBB0DC232B2670FB00DAFBA03F675A
+:10AD80004BDEA378CFB307ED8A200CF1D1E5FA3E74
+:10AD9000CE5EB3281CF94CBFCFC290DF9D2D5973F6
+:10ADA0006C317CFF491BEC6B85EC93146F7B165662
+:10ADB0000AF5858952178F7B0A617207AEDFEB9C1B
+:10ADC0001E5061227DA272600EEA0735AA83ECC094
+:10ADD0000CE4D1E0FE0BB04F1AED9F6DE3F6C94FC6
+:10ADE000F4FEF6BB3D647FEE67E3DD5ACCF07D7286
+:10ADF00072FD8D2AE2AFDDEBC3DD6897C97CEDF211
+:10AE00001CB43B6F80F610BFA4699F939FF0DC4990
+:10AE10003BD9AFFA07B445B7A1BEF3AE85F099B9F7
+:10AE20003F663A18C12E750CD72BCAE53D86FC70DB
+:10AE3000B4F8EE24F4C74FB8821FDE6C6FB2F2385C
+:10AE4000668BC8E775EF72EF89526EEF9139285023
+:10AE5000892F6D4D0779E01ABEEE779671FFCEDE31
+:10AE6000E5EA29FCEE1ACAF59506C4ED19F36FD888
+:10AE7000A7CFE9F6E973F261A2974FDA38BDC0FABD
+:10AE80001F263BDBCBCC8DF9E6F53F67E3EBAF95B7
+:10AE900040DB37223D0C6CC1F56139D7B6FEBDAE43
+:10AEA000D4A0F54F0306698FC1F75C5F2BA83E4223
+:10AEB000F2F202CA4B65383D2C6FBB41457A939143
+:10AEC0001EE287B7D7EFAAAD47FBF0A1576F93718A
+:10AED0005C7F08B3D2F935639DFBDBA6F0B8209701
+:10AEE00022E8F1FCAE32B4439E775F312EE89BAE90
+:10AEF000B7A874111EBA08FB10E711F41535701DC0
+:10AF0000961FB43F80F3288BA2DB9284509ACB8BA0
+:10AF1000429017E817328F4B54E4BAAE18C2A164BE
+:10AF200067601E8105CEEBF2832F119F954B757BD9
+:10AF3000A869DE86AD8BB9FFAFCB0CFDD4863F8709
+:10AF4000557239691ED72181C75D69EF5948FF1CC9
+:10AF50008D0FF76EEA69C3F800588708C4B36735E8
+:10AF6000C16F9B084F5F7B6C609C58EF2679D7ECD4
+:10AF700000B99AAEBDAF227EFBDB5285FB3335A113
+:10AF8000AB35139FDD2A4800F6D6327526AED75F63
+:10AF9000EBFCE62C57EF2F9B3A7C3E61BF935CF9AC
+:10AFA000A894CB95BB56A8CBCBBE455CD03795AB10
+:10AFB00056935CAD1D5DAEAEC77EA5FDBCA27511FE
+:10AFC000CEA78FFBB9341BDF3FE6F2359B82FDDB5A
+:10AFD000C6F3E10AEFC6B280B8216B6409D14DAF68
+:10AFE000AD4BB812AEBA917555637E82CA646D06D8
+:10AFF000D25B3443FFD6E2755C7E7C5B9C6593AD8F
+:10B00000E47F3FF4EAFDB27784F99AB3DAEB0B5CA4
+:10B010003F5B8C9BE23566567876E2FB9AF0104AED
+:10B02000E754A84F95C55EFBFA19F56DD9D4F0CA5F
+:10B03000A701FB05437510A44B31F03EC8EF1FBCC0
+:10B04000DE5356AB1DD8DEDB63BC14F773D7C0BE2E
+:10B05000096188030E460BC8772776ECB817FDB454
+:10B060006763A22609308F93CB795CC7D9CE85F769
+:10B07000923F3BC94A71973FE95C2F1743FF3F2D31
+:10B08000F73E1B384EFBAE8764D575FDF408F2F031
+:10B0900035E2C3929BEC2EB58CCBC5D1E4DC6DE5DB
+:10B0A0001C07819CEBC2715D43B97F2EBB823C1CA7
+:10B0B000F4D71AF2F0E0B5C9C3FEE1F290F0D05F28
+:10B0C0004C1E1EBC417BF40AF2F0DC55E4E1B9836E
+:10B0D000C3E4E1BFFD39E421E0E03F10BFB2F6D2A6
+:10B0E0007C5A5EE5F3391ACEBDB39CE318C0B9971C
+:10B0F000F1BB6B282794FF15E0E134AD3C1CE5DA89
+:10B10000D9368B48E7055A83D7DFB02BF40FF0769A
+:10B11000FAA01D6D8476CED9D8CB42C4D03A9BE933
+:10B12000A63F4FE926BB412EA397B0EE19387FC248
+:10B13000C17FF9A390F9EDD7BBDFE91DEBCEC0FDD0
+:10B14000C10A3A47E093331E9C7B2BB6F77C99A249
+:10B15000FB0983F906C8F9DBCBF9BA93F1CAD0A78A
+:10B16000403ECEC4EFFE5AE5BFC07CDF9B06E562E1
+:10B170008DF810E8089EEF1AF7A98B9F538BFF7785
+:10B180002199F4246E378C7DF9329D5B031E4A7140
+:10B19000FD83E7D654079D5B8BAD0A8E078B650355
+:10B1A0004272329E07F264E33915D0B27B3A64B43E
+:10B1B0000BDF1764178E1DE6D7369D5B0B3C3FA453
+:10B1C000DBEBD0CE4B4B19704ECDB05F8E8BC9AF41
+:10B1D000DE9FC586CEA999CEA7C5EAF663737F83A5
+:10B1E000EA0D38B73668BF951766BF18C3DFE3B9F5
+:10B1F000B558B35DB96AD08F4FE7D69ED6E50151F9
+:10B200005CDC50BDB1FAB9B561E3D6EDCE544E1851
+:10B21000CA1F3AB7365D1CE9DC5A8A7E6E2DC574AA
+:10B220006EED473ABF7AA93C381EB076B1C8E3014B
+:10B23000172FA4F30FA3E1916B8D0734E2BB86C7F0
+:10B24000036AD47E63B91EA70EF485FBEE2F7D7EC4
+:10B25000C4E8C770FF2D7F9F7DF39747D02F694BC0
+:10B26000E271DC36FD5CB0B380D13961672EB76F17
+:10B270008626490A9E83986B71517EA3C2E3B98DDD
+:10B28000730F861FA4F1DDDE6EB45FC6255818FA71
+:10B290004FD8061E876D9C7330E2A4B62CE0DF3BCE
+:10B2A000F2D46C2CEF986E975519CFFD5A83E29625
+:10B2B000E24C714B31BA3D34C614DF2D615F805FC3
+:10B2C000FCB25CF7635DFF79887F45BEC730180A22
+:10B2D00070EDE45D5376E07986ACBFBFEF437C4E02
+:10B2E000DBFF5074E0F985E91D3BEEE3E9AE345C29
+:10B2F000DFB7ABCF2778A0DE7DD53C3ED0A2F7CB21
+:10B30000A8FFE82A4E97B7AE557F83EDBC5D9D9DA3
+:10B310008038D1573D32FFAE5AC5F751AD6DA01AF6
+:10B32000CF77B5B208561D83E7DCAC7AFC905F207E
+:10B330007BADB2CE817EA93CE617300E1BE718ED3F
+:10B34000820DA90F1D47B1949BA5F5A0D8DCBE8A3C
+:10B35000DBFF6AD38E58A3A1CC5B558CE49D7DAAFC
+:10B360006615F13CD0AB0514EFF88005F839F243CF
+:10B37000C6ED29782091E4B0991FBF2EAB2B315F29
+:10B38000E7B7892BA3A8FE4C99FB9B337315A166E5
+:10B39000129E231C207B7A33E02DF40B36BBB69330
+:10B3A0007C975682E8C0F8CC84543ABFC71A1D3245
+:10B3B000FAAF0FD9F879F9DDEB9CC83B5973D68108
+:10B3C00013980E795452D0EFF1FEAA489A97CC0DFB
+:10B3D0005257E07968F333537227E2B9A4F66577E0
+:10B3E000FEAA3C26E85CD3F805B06F92D0EE0AEFD7
+:10B3F00045C095D5B0DE43F2E2FAF4960B25B37E54
+:10B4000081171C7DBCECB330C4BB3B22390E6C668B
+:10B41000BD0958598DA024F0431F6A02B67364C158
+:10B420005763D01E7F28D2733FD2C12713D4043C68
+:10B43000BF75B6954D7228B8EE953D283F12ABA268
+:10B44000DDD5909EBA92EB0B69E54CF58F402FB796
+:10B45000EBF4027441F56FC13D08DF77A4333FFA86
+:10B46000F93BAADABBF0FC453BC835B4B79E0DD317
+:10B47000F31318ADCB76C1ABA1FF473BEB621D9038
+:10B48000BFA3B5B40BFD55FB04907B900EA92A55C4
+:10B4900057227D2956F297EE8BF56AE84FDDFA9F29
+:10B4A0001319E2A376D74E92ABED6FF2F3FCCD4DBC
+:10B4B0001F901FE7ACE06FA3F3841BA5C968CF38CA
+:10B4C0006BF3244E86FEEFDD58DA5506EFF7667310
+:10B4D0003FA0946EE6A39E5F119DF8A4F15B89DF07
+:10B4E00079BBD2B13F4CE941FE69DD58D4B51AD2DF
+:10B4F00017374C94B17FD255CE81EF5DC9E7E77124
+:10B50000DD9FC2ACAA07C73F4EB6D2B9D188E9C108
+:10B510007C12FB89F556AFFCC5C356D8C71D36CF84
+:10B520006E4C57AC7CEDE1D9B7617F06E8DE25EBC8
+:10B53000462E4F9823B83EF3FA18ED1A69737BE351
+:10B54000AC8CF6DB381FDF27D6565EAFD5A6D2B956
+:10B55000BD3F577D67374A6467B85A7DC6FC8D93F7
+:10B56000AFAF5EA39CB95EF3777FA9F2A38DB35A08
+:10B57000DF67F4370DD51036789F0EE22D49CF0ADC
+:10B58000C92B257A9445EE87AE11FC1AC6476AC9C5
+:10B59000D64AC47B21F123E32CFA9EFBB5899F1A7E
+:10B5A000F54B253FEE427F1DD3719641CF83382B5B
+:10B5B0003DF87E8039C67E671C6719F5D68495767E
+:10B5C00079897F33255A1E615FE8788BCA270FE59A
+:10B5D00007DC1340F61333DE5AA19FBF58613A7F50
+:10B5E0007146976B9FAC0AC65B1D7F67E1F704FC51
+:10B5F000DD9FE6FCC5873AFD99F1563DCE0DCEFBA9
+:10B60000CDFC9E0890CF5A580CFAB70067450EAD96
+:10B610005B84BE0437FCE88016CAF1ECBA08E0FB94
+:10B62000BB8DEFB3E17BAEBF52FC822B60DDF19EA0
+:10B630008148630D15968AFAE4137765EE47FB811E
+:10B64000CB34BF913F595FFD0CD71F0887B340BE75
+:10B6500006F5C94A54F73301389DB181EE3E282FD3
+:10B660009533D2472297068FCFA558AB3FC6FAF441
+:10B670007B0698F5BC86FE45C9A250BC1C73746B52
+:10B6800018FF26CD8AA7F88B1AA145C5FE69331885
+:10B69000F90723D4E0757499E89DE9F2D49EC6EFCA
+:10B6A00045712649FE91EE1FD8AE9F7B68B0AA4B2C
+:10B6B00090CF3578E20494CFC6BADDBD8AEF1B5F28
+:10B6C00024DFF748575AC0BC18E5BEBBD21674DF5A
+:10B6D000412C9FD3413BD1CE8FF8B9919D1B8E92C7
+:10B6E000FED99A27915D61A2D4C2302E973D26D211
+:10B6F0003A1F8E5C2C3640DA57653980F8B56063A6
+:10B70000DF73288F2EF4264FC62A0FBD7A3FC5F36C
+:10B71000FC213B9DEC922C7F58FC03D9098CF6F759
+:10B72000668DA7F65BF5B8FE93EB7FEDC038B1DD13
+:10B73000D3C6732C60A2DBD83C3D0EC254AF57DF9A
+:10B740000F31FA79BADA05C171DBCF3ABC13564131
+:10B750007EB3EF4307DE17D1E7E1EDC75CB252F9E4
+:10B76000346D3AE19082B0C957DC37B1FA39BEC1C5
+:10B77000B4BC58C0F2B197247ACF5C31D7143FFCE7
+:10B7800048AC95E8BF669E44E3AE09F3D0FD0A35A8
+:10B790001B2DEE037C584417BBE74907B606ACF7F0
+:10B7A000B4950A7DBF63DE34BAD7D03E363D01F989
+:10B7B000C64B2BB9DE330E237652303ED2C131E96F
+:10B7C0007446F6BFE1729AC74B121F44FCB753246C
+:10B7D0005CB2CFCD468E97AC3A43E729B7022AB187
+:10B7E000CBC3F3CD699FAD4BEB85F67D80635AE407
+:10B7F000E1F4BF2C3DF81E8A06ABE6407901744C9B
+:10B8000076919055AD0F57A7A23D7739C5E56FAF3B
+:10B81000E2F4593B4FD471B887E23B0A367E487157
+:10B820008517B2B8726E5E77C3AED4EC3B1214AF1C
+:10B8300062D08931AF401F95ABA6623C9C4AF8FEAE
+:10B84000DBD2C5B4557C9DCCF471B99CDFCF90E7B9
+:10B850003E4FF15CB536E5F189B8DF1A2C72B5328E
+:10B860005CCF78A345A0752CC9E5E7E27395F3A4F6
+:10B87000973881B3D23D56A87F40BA1E3121A4A289
+:10B880009A9ECC9B0CEF8B15D1AD2AA89F0C7463AC
+:10B890003C044BE2E7C273B30666A13955D5AA4909
+:10B8A0003FB9A3E5744DBC82FDE2F135C54DD90524
+:10B8B00093A1FC9DA9FC5C937D6A17E92DB9550AFB
+:10B8C000CD5B9AD74138E4933C91E8EA78557BD038
+:10B8D000FD9FB6E427AD4827B9465CD928E780CE5E
+:10B8E000EAE7808C7933D623D6DA3917EDBE51F1E9
+:10B8F0005C9F8DC90DBE17F4541EA7D30B2F08C42F
+:10B900002F8D7B24DBF57B24CB98574A44FAB55620
+:10B910001E2D877AECB7D965E4CF785F66207FC7A4
+:10B92000FB3203EBC5FB3203D3785F666079BC2F33
+:10B9300033387EF996A07CBC1F33301D957E7B305A
+:10B94000BFFF86E787A2722B25C435CB40FE58DCAB
+:10B95000C3CF1345E5765A71DF3FB62AF83C6CCF6A
+:10B96000A5F175110A15B35AA7E1796D3EEFDF63B2
+:10B970005F5A23E0BB7BBF542594C9B7AEF51E4385
+:10B980007E58FCA57C14D3B078843F02F463DA8738
+:10B9900055BFF99B17F0BC3E530676A1FC1EBAEFCB
+:10B9A0006480E4D137BFEF84EB8789C8C7A68EAE29
+:10B9B000279AED271FAE64FF25F79318EDFE4F4140
+:10B9C00073929D4EE6713F7B186BC1F332C0DD2848
+:10B9D0005D53C9EDAF6388B9C07329BFDF279E717E
+:10B9E0007D372A9529CD09686FE67675DCB398BE58
+:10B9F000116098258A9EAA9582D2FC342FF83E5574
+:10BA00007F9F09923535FF8111E3D08C67B11E8F7E
+:10BA10003B9896395ECC79EDDD9FE239A877D6DD8B
+:10BA200038D9AE0CD5FFCE2BAF2709907F32F35F0C
+:10BA300026E0D3B0176C91B97EB1457E8EEC09B586
+:10BA4000B091456014B59D3E1EF755CE643CCFB90C
+:10BA500054528A30BD74AB83CE696E8911498E878A
+:10BA6000AC73EE271B0CDBACE3644F1BD2CDF8416B
+:10BA7000BAE1ED6FB1A9F1747F4A64BF581840373D
+:10BA8000DDAFDE4FFC7E5B12BF3F695BD2E42BDA99
+:10BA90000DED26BE6BD46FCFAA64C877ED3ADF4DAB
+:10BAA000D33638506F2C1873B5FAF83D77C3EA4B8C
+:10BAB0005DAFD767A5FCC54B3AE8DEC0E507ED32C0
+:10BAC0008EF75CC70F3271FF9CDBF8641D0BB81753
+:10BAD000F8C3A7CF8FC1F6D2BADAC2B1FD4FF47363
+:10BAE00065670FEF929480722BAD2D12FA158C7B47
+:10BAF0001C16779CB7A1DFF1EEAA27A5DE8CA17EEC
+:10BB0000ACDCC3E541599540F260B9BFBA8E9F0FD6
+:10BB100028081FE93EE2ECE6D870FCFE74531A9D3B
+:10BB20005B3BE39B724539765A6FBF57F7C77E87F9
+:10BB3000C58707D25D5F03AFA7A6E13EAAF74C9287
+:10BB4000E75E8C1B3FF3BE05577C483F09E3F635A3
+:10BB50007639652FFA070A1B0A29BEB50FEAD740C6
+:10BB60000F2C5E6DA17D35AB2159A2F8C8DA48498A
+:10BB700081768AB484B9680A2CAA153A9D507EF55C
+:10BB80006A85CA1536454A78AEA0B06112F129A877
+:10BB90005712A85E4146FE73B57A0A5BE07B1796A2
+:10BBA000CF96E83C256BA1F92C69B2049DDB486374
+:10BBB000E923DEEB9CBDE023078EB7D99345B8E3BC
+:10BBC0003B6C7A239E07687ED7C2AE14B76B8EC3D8
+:10BBD000323F7D79BCBE9ABCF14EAC7F4792320FAA
+:10BBE000EF73DC619ACF1D83F339E504E2EBA83CE7
+:10BBF0002FE92D18A7AAC17A6D33E633CF2DE03C8B
+:10BC000044E7F630A4AF27F5F90BCB720B5E48473B
+:10BC1000275532F2675F9E2208540FF02D01BFEBCB
+:10BC200061F85D58AE5BC0EFA2218DE5C3148D971E
+:10BC3000D7E7CB912406E13696A1B1E971A4C7926A
+:10BC40009CB1326B3FCAB106DC93C407346E9F943B
+:10BC5000FC09B26B888E772FFBE9AED211F8BE8D4E
+:10BC600055EAFE10BF6E87EDA4F4890F7AD7901DB8
+:10BC70007B4328F19B7A5B2F9DDF86DA65F24F9B31
+:10BC8000ECA4861DF8FC2ACF8F57A3DC785DEE422A
+:10BC90003E63D84D4FCE54C83F59FF7F2C747F8DE3
+:10BCA000E167B3F1A1311BDEF31860E7643192C99B
+:10BCB000AFE6217E6CF8D3AEF5BBEB8E83BD46BDFF
+:10BCC000022682E665793C9747A9A80F403A3C9D39
+:10BCD000C9686F4DD5CFE9C79530D69880F797A83A
+:10BCE00022EE4FEDD10819ED27CCAA8A6DF8FDF4AC
+:10BCF0001B647E7F1F5F8754ED1DE1387CF7B7A181
+:10BD0000822C829CCDAC9A44F79C0CC5DBB889AFE1
+:10BD10008C26A7CE6C8ADF83F150BD9BD2F760FCE6
+:10BD2000D4A09CD204499888B8B37B02EEEBABC98F
+:10BD3000B13E5D8EF5BD72C758925F8F73F9659401
+:10BD40007F73FDEDE148C77D97A71CC3F321BF2E8C
+:10BD5000B1B86B189E0B1B38433698DF7EF5482D23
+:10BD6000F4FF0778480AF0CD1F57B31F6AE847D59C
+:10BD7000FEC1D606E57F7A315CC1F119F76E7D1CF4
+:10BD800032B0C613503FABE07A26ABD0ED55157CF0
+:10BD90007FA5B3CA3974DFC06CC69A1290047FFEC7
+:10BDA00008CE73FABA30C6E32BB4CD3F44FA7B51C8
+:10BDB00052D0CE7B7FF9FB0FA11EFB83F2C8BD7171
+:10BDC000F0DDFBD5E1080ED8E92DFF3215E7E1B42F
+:10BDD000AD6B6AA40BE38ED958F2AF3EE024FCCEE3
+:10BDE0007ABB2E92DEB82599FCE839B593C69E2120
+:10BDF0007EC6FD624B2DEE7809CBD75B18EAEB7D52
+:10BE0000CD7686E913A5615C2E97C8C7306E68C9E8
+:10BE10008369A42F44E8E3596A6795C45FBC2D5336
+:10BE20001784E1B92299EEA331D6DF523BA90EF96E
+:10BE3000537146E5187CEFB70ED0F9BAE654DDBF72
+:10BE400090CAF182351BF606D09DF5D917783C8152
+:10BE50007EFF83F95E87E62C8E17FC9576135EE8ED
+:10BE60006943FDE64075305E68B6B570BC90D69FFC
+:10BE700083E706FC3E91A11E7A087004F6A7364CB3
+:10BE80008D473FD016C6F77D7485E7E60AF457C89C
+:10BE90005217D269D86ADD2F181345FBA8D1C6FD09
+:10BEA0002CA3F10FF4B3D0F92F9D5F18FEAE4CA96F
+:10BEB000F7009E8B6C7C34CC0DDF423BDEE9D84E24
+:10BEC000E3B2BF2FA0F30C267E66F8B546F37B984D
+:10BED000F7AFB7CB49B8806961AC2FC86EC2F32FFA
+:10BEE00094A4D0FD00CCE14A47BE13ADF7F7C4E5FA
+:10BEF0002974EFEB979723588D1BDD4795C464A2F7
+:10BF000075BF2EEAF95CEFE77C2F5A8F0B8A7EBD56
+:10BF10008EF4FA530F31B7103F549EE9E53556A918
+:10BF2000E17D93D1FA3951B37DFFE44C7735C617E3
+:10BF3000D4265B2B37BB83BE1788FFEB764FEAA76F
+:10BF400030BCFE093A1E87ACECAF47B07F99D37680
+:10BF5000C564DF4DE7FC3786197F01F62F0B9EFB8A
+:10BF60005205E4FBA7721CEE6AEC8B67143EAEF33D
+:10BF70007FA39E18D9C4C74DDF19EBE15862233C5B
+:10BF8000D6BF5120BC9A61F3EE45FDB5B82AD48DD9
+:10BF90002A54F10B8C2A2DD204F2EFE63470FC56B1
+:10BFA000DAC4CB977EEEA578C2A2AA30372E6BF109
+:10BFB0006FE5C50590BFB6CA49FAFB69BC0D19F912
+:10BFC0003394273BA9C67E89FAF41A7DDD8B5FFF87
+:10BFD000651DAEBB717EA546A7FFA72AB8DFB1B726
+:10BFE000C0B6B600DF594ED2FD62C553D8783CCFFB
+:10BFF0003038AE17B85E0A729B9F47D182F5D0B534
+:10C000000DC1E962931F786745F0BD16FB2B58D030
+:10C01000BD68D8CFE8A86FDF0E73F17D3BC1DA238E
+:10C020008EE49731D6C3F077B74E35FCE53D2AFE56
+:10C030000E45F474BB2ECFF8BD6986FFFC90E4AECC
+:10C0400046FB416BB66300EFB10A63BFCDC6F28316
+:10C05000F756E9FEF4D1EE438B36E9E561A6B4C1AB
+:10C06000375EAB083EEF796AC3148A1F36F88379CE
+:10C070003CC67D66DFF4DE32E33E34E3DE32635EEF
+:10C0800090B6705E4EEBF70B9CAAEDA338830B5570
+:10C09000204DC98EF218D9654EEF12F87968DD6E21
+:10C0A000E3D5E7C95B75D35C944347611E51AFFE8E
+:10C0B0004BDB53EE31DB539842F691423C9F8EEBC3
+:10C0C000AAD393615F29DC60398DFE8C42F33D6316
+:10C0D0006DB6A134435C109C6FEC9FF315A67BB743
+:10C0E00075FABB1AFE4AD4E363CC7E9C7FECD85928
+:10C0F000B415E6AF7F5702DD6BEB5C23EAF2AE923C
+:10C10000E2C3CAFC8CEC0F7FAE789444EBC8F11705
+:10C11000F21AE18AF12A865FA9EE313D8EE7B13F3E
+:10C12000CDFDD3578BE33931B6E57BD3A0DD1BDEE4
+:10C13000B5B835982FCBD2CEF7D0CF1DD76371DFEE
+:10C14000CD86D6E994C2E9DA1AE9A0735EADAC27D0
+:10C150009EEB0FDE6EBA3F7E09BF9F18E659F7FFD0
+:10C160002F4E441C7328B27709E2850EF4FF43B9C1
+:10C17000DDCD4290FF3FCA17E5AE86F49C351CE743
+:10C1800015E772FFFF23B1F9F4FB0BFDAD3C9EB840
+:10C190003FAC326141C65039BB68FC1E81222C9CE9
+:10C1A0008071C90AE5CFD4F307F542A7AECF314578
+:10C1B00020F9A3977F0AF905F2FB663BF95BA272AF
+:10C1C000B91FC0FAB8FD00E2A4B96B14C37942E309
+:10C1D000D9D95C467E00F83E01E9C8883FE86BE2A9
+:10C1E000F1078094288E636C9B9DEEAFEEF34DCEED
+:10C1F000B919F54B3D1E61E7AECF04BCA7B2EF2CD9
+:10C20000540269ABD85B8D763C26B24AC4A97DCD79
+:10C210009F55A3FFA71DE43BDA21FB627B0967B4AE
+:10C2200063FC818C717953DEC2F9FB224F247B3190
+:10C23000489C6EB4BB16AB0E8A376CCDFBE038DA87
+:10C24000F75AB3246242639BCC74D64BE31F9B27FF
+:10C250007649402763F57B8AC65E25AE6037E05A93
+:10C260003AFCABBDFCC3AE54680FFDEE31747F22C7
+:10C27000F78FEFE2FECFD1FCF89F98E8D45B154C26
+:10C280009F43F53FF722D64F331E706F39FD059C53
+:10C290001F1F9B77A01AE761C8BFC8F309F7003DCD
+:10C2A00076C072204ED2142BCDABF93C73B47E7E97
+:10C2B000DCC04786FF798BBE3FEB06D79DFBAF07FF
+:10C2C000CFADFB44FA0EFD00B8FE4F19F7A4950759
+:10C2D000C707E21FFAABA391BE60FE1E5FC3FDBAA3
+:10C2E0004FACE1B8387AA9A4D7E3A67ACC386D343C
+:10C2F0001C67F8AFBFAAF03CB566EAD03975E8CF45
+:10C3000049B42F2436D9E93C64BDE0AF46FF30EC98
+:10C31000D14A8C6BEA73FAABD12E0898665D35BFB3
+:10C32000BF83FCBF34BFD0DF0EA7BE0F5A05DA07AC
+:10C33000C3E8A13C384EB304E4018EAB100905E616
+:10C34000FBD09A141AD772FCBD12C2914A2DFA2959
+:10C35000C6FA846968AF2971254B91F02C8C11EADB
+:10C36000F07977D2791BD9BFC7680EBC97A2A3D149
+:10C3700042BF6BD511D6FB33BC2F526B0C23FDCBC8
+:10C380004C476FE87CDCF0D3220588308E34619016
+:10C390004ABC22CCDB0E3DD1B386FB7DA3F33C39F6
+:10C3A0004E68E774FDB8C9D8BDB71128C5D2B80B1F
+:10C3B00046E2D3EF0E6F87EE77E9A7A101DF6F8B1F
+:10C3C0009C599881F50B069D682CE09C7354AE3CFB
+:10C3D00013C7F7FE1A598F573A3D09F75D4724AF47
+:10C3E0004F15E5990B02EC5EEF1BF2C9C1CB3D2561
+:10C3F000542EB984EB01F800E3894A4CBF0F54D89E
+:10C400002668A1E1C3EF8959AE05A7FF55A73B33C5
+:10C41000AEB71A7C93F1752FAA4D3E60DC6388E9B4
+:10C42000C43C85D2E25A637C9CBEA29A789C749FDD
+:10C43000CE4F87F30D8570EFD80661327EFF6F46D1
+:10C44000FBD6D3A49F1681DE83F8A1F005FF2BBD98
+:10C450004A00FF66DC3F4AFB05719C77BA13F9F38B
+:10C460001FF4F935E6E9D0BDE3C97E772477B2132E
+:10C47000ED0ECB1E4EA67B0ECCF37035BDC6CC0F99
+:10C48000A2F282FDA3D6B58CFA3DD6E4DF1F8A0B5B
+:10C4900090286ECF880330FCFAFB3E9A75D09847FF
+:10C4A000D46FEC7A0CF377D7D8A8BE7D593BC9BFBF
+:10C4B0005F0F7ABC40760AFEBB2A6C9AA4A0BE71BC
+:10C4C00038F22BBA47C0D766D98FFE7E63DCF62CD4
+:10C4D000DD0F9F34B27FDFAED3A5A8B4907FF662A4
+:10C4E00012FF7D9556CF42E748F861B4FA52D772F1
+:10C4F0003AACDD65DCDFE6A5EF5B0B16D2EF01A6FB
+:10C50000699F53FCC16EBCE70DDA2B58C97FEFE879
+:10C5100002DEEBC602FDC195FCF7039706DF5B6008
+:10C52000B46F1BEE0F9EBC36167F7FC84341293681
+:10C53000DD1F7CAD38B07BEA5374BFCACE4522C53F
+:10C54000F9EE9CFA03D2FFDBC788E4B76C9FB1AE6B
+:10C550000771C457B156C237CE96CFB64D84744AD0
+:10C56000968DC6C1F4FBEF0C7D34AFA9CB12818947
+:10C570003CA6DB1734BB4872469344FADD0CCD86EB
+:10C58000CF3CB7A045A3BC4D2A7FDA128067ED8B64
+:10C590003E9845DFCFE3DF875DD2487E3899AAE336
+:10C5A000A55E8A9F0CD5E3E85AF38B1AD12F6D5BF9
+:10C5B0003099EEC9786F2A3F17678BCD8FF406F05C
+:10C5C000A74E7D3FD6DBD495146FB091D3A1FDEF7C
+:10C5D000BE3A518674B43084DAEB68FD617CE0B910
+:10C5E00032E14189F3BB657CDF9E1259796750BE09
+:10C5F0009DD65D7890EFD7EFADE47C601CE01A0526
+:10C60000E93C3F6B339E27D20AF87656ACEABC3938
+:10C61000D05EBB478C413A8B9DBA681EE2B8EF2DC5
+:10C62000CAA129B4361F9E8DE90E37700D184F87A9
+:10C63000278FFA7BD11362C5F53825F1DFB53A357E
+:10C6400076AEB53A80CEA507D382F67B5C95187C92
+:10C65000CF8F5D5D478BB489D1BD1BB3AB783A05F5
+:10C66000C025AE7B4AFE6C4AC7F924E684B4A3A079
+:10C6700045C3F81347AA770ACEEB914889EC5029B5
+:10C68000059C4E7C5831CA1B8F8BF4FD14DFDC16E1
+:10C69000FC3D8C948F2C0CFD18B5364F22D24D6D7D
+:10C6A000A495CE6FA764F07909CDB2EDC771BC2116
+:10C6B000F52CC5EFDF789CC709ED59CBFDFA4E4547
+:10C6C0000CBAAFC881F67C58F7EEE669BF42BCD61B
+:10C6D00031D54E7ADF1DAA87D277144830D1A0E732
+:10C6E00031EF2EA4A73B8FDB5957F215E97E447A30
+:10C6F0001CADFCCE821C27D203E0F5FCFB701D2F85
+:10C70000F17B15EE18E8213A8DCE55E877467C731B
+:10C710003D89782E2A4BA783D6984F6BF07E752DD6
+:10C720000BE818D7B175F13C9C1F5F9C752A967F6A
+:10C730006491A8A15CD8D7BCB803E36A16ACB5D2A3
+:10C74000F8F78579E6211FDAB7C8CAE36B62DC899E
+:10C750000B02EC6FEDAD736FC67D0E74AEE3BEEFF2
+:10C76000BE84B86FE67F84D0FCB6AF6414A7D3EE66
+:10C7700074737FF5546E8F457B03DEBFB42FC1DA2F
+:10C780008EF6869F373FDD8D742FCD28E3F74ADD87
+:10C7900068D8C739DF32EC0F0B74FE687BF7722D57
+:10C7A000D265BBFE7B3987A4815A5CDF7DBA3D62CE
+:10C7B0006753D43F63BCEECE780BE1F3EFCF0EB6F8
+:10C7C0003F20EE433D3845D783EF1CB006E9B7CC98
+:10C7D000E5DE8CE3FE5ECE748A534B31E9BB89A65D
+:10C7E00074CFDA6F7D2FD5C76B39FE20BA7E6F23E9
+:10C7F0003FEFB7CFE17D0BEF1F6BF78974EE6E67EC
+:10C80000D3C2F9A887B47F6409E2C3E6E7311DA764
+:10C8100077F81692BD44917B6B911E3B36F0DF0793
+:10C82000FAFE1D85F3B09EC42AAE7FD4C3FE40BC81
+:10C830001FD316CABAA640BA75F12F70BA3C1E5162
+:10C84000C3DF01F2A88542201F7A7F138F4B6D6FE3
+:10C85000E2F58FD60FA3BE7D55BC9CCF33396CA4B7
+:10C8600073B21FE9F50D96930612D03E6DE687E68A
+:10C870007A8DF4D2B52944E73E4F11D5BF336B8E84
+:10C8800053C918923B77E4F5D4A0AFED3DD63B2BCE
+:10C89000F0DE2143EE0CF2A327747ED4C4D3E36010
+:10C8A0003F237D8EF32C8C447A48CBB7CA08B11D48
+:10C8B000BE16D519C08F76867977A1FEB76F818BAA
+:10C8C000F6C94E9DAFEF5C9028A05E7524F287C438
+:10C8D00027C725C509589FF22097CF503FE7633EF1
+:10C8E000D1EF14302E98C7E95C043E86F86967647E
+:10C8F000D661942FD6099CEECDF366E64F4E1C4FC1
+:10C900000AF223E067313A3F827ABB979452FF0CD8
+:10C910007ED501FA3DEDCFA9366AA77DC6E9D5D807
+:10C920008FAFFE184272E84ED653338ABDF0BAF884
+:10C9300095C11F3AFFEDBB2FE1B93D635D1E89BD77
+:10C940002D117F17B83D6C604990BF485F973CC67A
+:10C95000ED42E6F3298B1EE47681BDABD5990F62DB
+:10C960005C186BD1D0FF8191B3784F6A3DD37227A9
+:10C97000C3B89CA92AC565D5A7F1B8AC7C7DDEDF1C
+:10C980001ED3427E8F461DFFA6791D642F684C8AF8
+:10C99000A77B94E68BFB539F84FCE57A3BC753AFA0
+:10C9A0001CC7E6C2780AA0C7101D0FB9AC2D0CE752
+:10C9B0002F24D5F4FBCCA93D73F0E6C1B72AD435BA
+:10C9C000D8EF131FB43890CE1B53173A709E26A68B
+:10C9D0006D7720DD36766ECFC57B0A8D73D6770DE9
+:10C9E000FC22E49618EC9F750ACAE95BD77A673E89
+:10C9F00018205FED69EBE9BC756398A1E7F84B700F
+:10CA00003C85E909D981719065FAF81FAEF0E4E33D
+:10CA1000F7F3E300C84CC6796186FE532906FFDEB2
+:10CA2000473EF673B4DFFBC8339DBB31CFCBC3FAAF
+:10CA3000FCDD52A16EC4F636623BE45F6AA1FD9054
+:10CA4000C944770DE9FFC17EA4617E1F935FE98130
+:10CA5000D7A63BECDFC22F3C6E8DBA05C73576B545
+:10CA6000A71EFB551BF94BFAFDDC6BF517BF3D46C6
+:10CA70008D477A357062ADAE7F1ECA560B02E978DB
+:10CA8000BF3EDFFB75396C2DB0E9F705CC9747E267
+:10CA90009B73567B7763BF8CB455E6F705CC97F84C
+:10CAA0003C0B30D69A84A1FDF316AB6C5A928CE7FE
+:10CAB0006715BE5F7EF4BE0BED00F3257F6A4BC6A3
+:10CAC000D5DB5B3BAC3D95F4302583FB576A64FEB8
+:10CAD0007BA9AAADF73D05D28580A7E85E68D37E25
+:10CAE000349E68DF0EE44768DF0EC47D68DF0E4CBD
+:10CAF000A37D3BB03CDAB703F3D1BE1D98FF708530
+:10CB0000B70BFB8B76EEC0F768E70EFC6ECA6ACFF8
+:10CB1000612C77F79815744FC4D315EA115CE7EBD5
+:10CB200090CB6F633DA5333DB4DE5B62F5757E75DA
+:10CB300015CD8F2D366A5260BCF5459DDE615E3F96
+:10CB40000CDC9FB6183EAFB5B248F74C2E0E13E979
+:10CB5000BE6CE3DEB1D1E8ED0EDDAF7F27F0157CD2
+:10CB6000CEBC144ACFBB2E39E9A95E8AA667F6A5CA
+:10CB7000487AE65CBA919EB32E25D073F6A514923E
+:10CB800093732E25D373EEA55BE879F7A59BE999FE
+:10CB90007B690A959B7769123DE75FBA9D9EF75CBA
+:10CBA0009A41CFBDAB3DFF97C6BFEB1117CEE3B89F
+:10CBB000359EDF61BA5E006D3A85F6CFEF1F24BB6C
+:10CBC000400F237BECEB6A01F10391FF5ED6F95530
+:10CBD000DEAF701E86DD77261FFD23EAAD39152AEC
+:10CBE0007D7F74B5F7DFA99CC3E1B006C685C4306C
+:10CBF000A2FFD40AF53FA89D6BDCEFFF0F9076747F
+:10CC0000D0008000000000001F8B08000000000022
+:10CC1000000BB5587B4C1CE7119F7DDCDD5E728FED
+:10CC200085C33604701703C6AE215E6CC010616701
+:10CC3000C158B622FEB8D22A3A2A5B5E886D55707A
+:10CC4000B50E14B554757CEBE0D4801F1C21ADFDEE
+:10CC50004F95935BBBB594BAB46A555CA5D2963A2E
+:10CC600029F48F0A5556AB4A5173562895822D41A7
+:10CC7000AB287195C89DF976973BEE78B8A97A965E
+:10CC80003D3BDF63BE99DF3CBEF90C20C2FC0E6069
+:10CC9000BFC702FEE32B0068C26FFA3D9F4B010C39
+:10CCA000804D00B7CB168F857D007FA7A12280CA5B
+:10CCB000C8596F871F60738CB3E6B703CC56E39CEB
+:10CCC000B8E8075CF7FED18E20517823B4AA7CE146
+:10CCD0001301CC509AFF41AF02508FE3A20AB28FEA
+:10CCE000E6DD6CFE70E98D13500730BDC3AB0965FE
+:10CCF000B972F6F6EAA5B1FA34FF8202DA33F90026
+:10CD000033516D2B8DBF1C0D2B44C125BBC3A8EF28
+:10CD1000FBAE144FF2D02A59280658EAD1ABD8BC42
+:10CD2000A629059B0138B20F5581B765F39B080D05
+:10CD3000F407D41115E0DD5E7D175B079224E1BA9C
+:10CD4000E3168470FC0CE7D6C9CE9498372FA1DE89
+:10CD500084EB2A38A6F15C897F6B5466F839380970
+:10CD60009C852FEABD8FCE3345D4BB066050F9A514
+:10CD700086668177D1D082C0EC6EA679CF27619389
+:10CD8000F817CB0E024A829B516D7F0CE57D189FF0
+:10CD9000840F2A71207135FC5903C0493A10CFEB3A
+:10CDA000414B277CB97AD5F4B7B6D1BE5307660B91
+:10CDB000C9CF97FDB3852A51174468FD1F4A6723E1
+:10CDC000E18C7D9198C0FC158EF18CCEF85EBD8B08
+:10CDD0005FD05C312B109D89EA619277A064F120CD
+:10CDE0009924CA20EA181FB75B500E5231E232AACA
+:10CDF00002C8FFFA05B9BB3A579F43BDDD11DAEF10
+:10CE0000F0A2ACBA69DDAEA8D6C9FCF0B9F1D6BAC9
+:10CE100048EE93C67D863F7A689F211ABE3DB8B51D
+:10CE20004BE6D511E6877094F499565EDA44F62104
+:10CE3000FE5FFF9CF8BF6CE1AF16123E8365887BF6
+:10CE400035852D6F6C61387D55EE5A65DFE9DEAEB4
+:10CE50005732E3DF55A0715D94876F6B118A73E0E1
+:10CE600051CF3A16E783CCEEAC38E7E4771F710177
+:10CE700016DF1718AE18DE22EAEBB2E3DB55002C02
+:10CE8000BE2BA2DAD0FF86BB1DE736EE4E3DF91B66
+:10CE90002D684AD79324D593FA75EAC94088F923B7
+:10CEA000B79E7060EE5DAF9E886C1EFD789DECD0E5
+:10CEB000C435EBC1AD27AC073F6178FEBFEA816D99
+:10CEC00067E5DD336FA6F0DC8F0C11C88F466BEC85
+:10CED00047C41BAF7AE441A4579F3EFB660AC707CD
+:10CEE0004449F6A82425B68FEAC5781C6B8787F1DC
+:10CEF000BB19EF824EC2DB03C7825FF2A7CF9FA6AA
+:10CF0000FCC5F342F2953B73215A8F7517F50990D2
+:10CF10003EE5C497C8F34FA7F57BA3579B217C42FE
+:10CF20006E1DB6E3F9633BF9A4817559F1C99D27DC
+:10CF3000508F0B1512CB8BD0E117C120BC827CB275
+:10CF4000B28C7627A7CB707E78270F23CCEC844257
+:10CF50007A0C97E2F73334C03D32ABE9748907921B
+:10CF60005BC2274770DF6009FA7D95FAE0D0D7C829
+:10CF7000CEAAB5E785A21389169497F0892AC191A4
+:10CF800068EB1E6A413DBC453CB3C94DF439FAFA21
+:10CF90006CC014C9D58B12E1E5DD6FC5DB5A72CFC9
+:10CFA000DBF82ED7A70268A1FC0750651ECFBBE8AF
+:10CFB000AFE046B8F4FCC77D565C5FF4DB795DA05A
+:10CFC0000187EB2E943634508C48B206F3789E5489
+:10CFD00010860F905EA89422495C7748684E90BEF8
+:10CFE000634A7E9E87E210B4403DE6E777ED785BCA
+:10CFF000EAB3EAEF787CE8CE1C26EDE5788251D4DE
+:10D00000E31CE1E86B079570F457B8EF0BE8D482A6
+:10D01000765CE7C41BFE0DD4E17A29CD0FFB97F3B4
+:10D020004E22FB87940E30F07C7F239FA45A38DA7F
+:10D03000F84F36AE404AA2FC196D5CDF3F576C9C3E
+:10D040005E8F4B2BF05A9EDF9A2A5471FF95FAD4CB
+:10D05000B59750DF6089A41EA1BA6336FE5540FE25
+:10D060004AB31B4698DD2A47E785DAF8FB1EB4630E
+:10D07000B409F5A8CED5C333F50814E483E22290B1
+:10D08000DCA0F227D050DFEFD97A1CAE8B818CF672
+:10D0900004EF09490FDA138CA068E437D7415241F5
+:10D0A000FE5CE59F4DAC79307A0C600BE1E1B2EEAD
+:10D0B000435FF3FC7BF02C5238DA427A16160BE011
+:10D0C00069C4055FC17C41FC22F8E7F136DC13B18D
+:10D0D0007807CF1064F065B4DFCA2F8707E1685086
+:10D0E0005F27CE06DEF3BE7337C35FCFF5F90BE6DD
+:10D0F00077E1470334B0FE6D83FD1FC7A577EE626D
+:10D100003C8C6DE0A74BF14686CF585C6374347E4F
+:10D1100084E5D54DBAC75CE975DBE9FE4239C3AF9A
+:10D12000CC420752BFF92DD886F9A2F7597DE0CD40
+:10D13000B8C465AEF75C038EF0C7AAC689741F5DDC
+:10D1400003F506FAF3F94F7F3AB48DF2FC5EF91E4F
+:10D15000AA07CE7A478EC3DFB2FD36B2A383D97950
+:10D16000AB8D3F4279714B4C3C95BF8E3D5FFC21AE
+:10D17000BFC20FCE78769E8C73A0013656E37956E7
+:10D180007DBC6C0EB7503CC8F7CAAF7B33F2B7D743
+:10D19000CEDF105D15D48869197E45BF8FD6A28970
+:10D1A000BB37CE2F47DED87ED80AD8B88D1E72B3D3
+:10D1B0003C0F1E908B3A32FC38659F379667D58BB3
+:10D1C0004BA550D4519D3B9FC8B3FAB38417223F5F
+:10D1D0005F058FA93E81E17989B3D639FE4BCF4BEC
+:10D1E0004CCE945D47428AC6915F429AB438A89269
+:10D1F000BD0F8C39C28387D896C65CFBC4440CC271
+:10D200005467309FA8DE65DBEB834BB3D45FD0EF70
+:10D2100053AC5B7E56EA911EF92398743FE8BED862
+:10D220006194EBAB5B9937FF6D5E7C9FF282EE29D8
+:10D230002F78ADBC68E75F43BD3FAAC3BAC5EE1FF8
+:10D240009D0FFBD7CE0FD8B77EBD1FDDE09E090630
+:10D250001675A805F8C5D25F06CE97309CD9BDF6E5
+:10D260009BA5B90103E5726E6DA20FFD2081D5CF9C
+:10D270007735BB0D01EB099C773D483976601C057D
+:10D280009F82AEF02A7ECC77B74EF6515F22A21D68
+:10D2900035B97E74E88C9D3F4E9C3BE318B726EC75
+:10D2A000C9F59F47E10DAAA7C395DF9057C3FB744B
+:10D2B000AFFEB02FA3BFF494681CEB6F84763009E7
+:10D2C000DF30307C8D298E5BEE778A293F50D50682
+:10D2D000AB95217F6F0183A3C96CBF1541928D1758
+:10D2E00083C901F61BA59062FC17B073255A060A84
+:10D2F000A3E5A0F1345F897E24BE0A0C46774292F2
+:10D30000D15D60B2F91A48319E90A23CDE6D02EB0D
+:10D31000236A4111687C2F6802ADAB079DF1FBC009
+:10D3200060B409F43B7374BFED3F554BF7F83F9C75
+:10D330003ABB1C4F4F566797FA8019BD967FFEDDAA
+:10D3400067F55B826B2242F7B350E32664E0629993
+:10D35000959FD9EB17EDF795D79590591FBBDCAF8B
+:10D36000F44F9A156BEBE3D061973A4DE70CFB79DC
+:10D37000A03E2DDD6FF54CFE36433FEA0B59DF43EF
+:10D380007DE0DE5C391BF585E3A2E6EBAFCF1DBF88
+:10D39000491F4DD4576B72FF26F2335A8BFA481A45
+:10D3A000C84613F1098EFCE4FB1AF2452C0E58DF37
+:10D3B00012D041A579ECB38BFB59104DB07D831889
+:10D3C0005723B5695ED76DFE5AFEAAEF82B4FE867A
+:10D3D000158CEDB14EDAE7BC8B02FDFA76A6B706E6
+:10D3E0008A98F92E3A8AEFA267995D55342F3B79D6
+:10D3F0002BF90CEAA3B2F31694D23C8A1727FE3F0E
+:10D40000A47B10DF7FB7CF9A6ECAE7A839E3A6BE28
+:10D4100024FAE39FB9E93E3C6EBF2B7BED388133A4
+:10D42000F58C77EBFC14E9B730517E9DE2766142D2
+:10D4300060FDC9C2F9B2EBA4DCC25BFFFADD637A1E
+:10D440000FE03C7B9BC239161F6481D440416FE9D9
+:10D450000FED9AD6C4DE7FB048EF15E71E5D78EB7E
+:10D46000CBD63D3A21D8F7A8F950A823BE4AA13817
+:10D470003CF9F8207C9BF61D94D41BB8EFE4D587CB
+:10D4800035DD1971997DAFF28AFC9D5F913EAA5BF3
+:10D490001D91D3F8E4E02FAFBC2FE947EF26475F9B
+:10D4A0005E099FBE4372E85DADACED4771C2739FEC
+:10D4B000FCF2C005935C7015B9597ECCF653A03FC1
+:10D4C000DC4DFEE4267ECFFC9BEDB78B76BCA260E4
+:10D4D0008EFC9D6736B17E526854350DF1CA6BD310
+:10D4E00020138F9ECED65E8ACF3C51E6283FF314A0
+:10D4F000DB9FD57B56FCFFC2A97E7E455FE3C4E37C
+:10D500007F00F33D945E90130000000000000000D7
+:10D51000000000400000000000000000000000408B
+:10D5200000000000000000000000002800000000D3
+:10D5300000000000000000100000000000000000DB
+:10D54000000000400000000000000000000000108B
+:10D5500000000000000000000000000800000000C3
+:10D5600000000000000000000000000000000000BB
+:10D570000000003D00000000000000000000003C32
+:10D58000000000000000000000000000000000009B
+:10D590000000000000000008000000000000000083
+:10D5A0000000000000000000000000000000000C6F
+:10D5B00000000000000000000000000E000000005D
+:10D5C0000000000000000004000000000000000057
+:10D5D0000000001800000000000000000000001C17
+:10D5E00000000000000000000000001C000000001F
+:10D5F0000000000000000013000000000000000018
+:10D600000000003E000000000000000000000001DB
+:10D610000000000000000000000000020000000008
+:10D6200000000000000000010000000000000000F9
+:10D63000000000100000000000000000000000508A
+:10D6400000000000000000000000000000000000DA
+:10D6500000000000000000030000000000000000C7
+:10D66000000000AB00000000000000000000000807
+:10D6700000000000000000000000C00000100000DA
+:10D68000000000080000C0080010000000000002B8
+:10D690000000C000001000000000001000009C0806
+:10D6A00000040000000000040000C0800010000022
+:10D6B000000000040000C08800100000000000020C
+:10D6C0000000C0800010000000000010000093382F
+:10D6D0000001000400000001000093400000000071
+:10D6E0000000000200009348000000000000000855
+:10D6F0000000934C00000000000000020000935066
+:10D7000000000000000000080000969800400000A3
+:10D710000000004000009358008000000000004816
+:10D7200000009458004000000000000800009468C9
+:10D730000040000000000018000630100028000023
+:10D7400000000028000099500008000000000001BF
+:10D7500000009951000800000000000100009952EB
+:10D760000008000000000001000020080010000078
+:10D770000000001000002000000000000000000871
+:10D7800000009BB80000000000000008000000013D
+:10D790000000000000000000000000020000000087
+:10D7A0000000000000000003000000000000000076
+:10D7B0000000000400000000000000000000000560
+:10D7C0000000000000000000000000060000000053
+:10D7D0000000000000000007000000000000000042
+:10D7E0000000000800000000000000000000000928
+:10D7F00000000000000000000000000A000000001F
+:10D80000000000000000000B00000000000000000D
+:10D810000000000C000000000000000000000001FB
+:10D8200000000000000000000000000900000000EF
+:10D8300000000000000000020000000000000000E6
+:10D840000000C4C000000000000000200000C4E68A
+:10D850000000000000000001000060000020000047
+:10D860000000002000007300000800000000000815
+:10D8700000009BF0000000000000000100009B90F1
+:10D88000000000000000000800009B930000000062
+:10D890000000000100009B9100000000000000015A
+:10D8A00000009B96000000000000000100009B9714
+:10D8B00000000000000000008000000000000000E8
+:10D8C00000000000800000000000000000000000D8
+:10D8D0000000000000000000000000000000000048
+:10D8E0000000000000000000000000000000000038
+:10D8F0000000000000000000000000000000000028
+:10D900000000000000000000000000000006000011
+:10D91000000000000000002000009B9800000000B4
+:10D920000000000100009BD800000000000000087B
+:10D9300000000053000000000000000000009BE019
+:10D94000000000000000000200009BE40000000056
+:10D950000000000100009BE5000000000000000145
+:10D9600000000009000000000000000000000001AD
+:10D970000000000000000000000000440000000063
+:10D980000000000000000001000000000000000096
+:10D9900000000050000000000000000000000089AE
+:10D9A00000000000000000008000000000000000F7
+:10D9B0000000000000000000000000000000000067
+:10D9C000000016C800000000000000080000200849
+:10D9D0000010000000000010000020000000000007
+:10D9E0000000000800001AA800000000000000105D
+:10D9F00000001AB800000000000000100000000144
+:10DA00000000000000000000000000020000000014
+:10DA100000000000000017E0000800000000000106
+:10DA2000000017E10008000000000001000017E2FC
+:10DA30000008000000000001000620780038000007
+:10DA400000000038000016F0000000000000000296
+:10DA5000000016F200000000000000020000A040DC
+:10DA60000000000000000020800000000000000016
+:10DA7000000000000000E000002000000000002086
+:10DA80000000F30000080000000000080000170874
+:10DA900000000000000000D80000174F0000000048
+:10DAA0000000000100001727000000000000000136
+:10DAB0008000000000000000000000008000000066
+:10DAC0000000000000000000000000000000000056
+:10DAD0000000000000000000000000000000000046
+:10DAE0000000000000000000000000000000000036
+:10DAF0000000000000000000000000000000000026
+:10DB00000000000000001788000000000000000175
+:10DB1000000017C8000000000000000800000051CD
+:10DB20000000000000000000000017B0000000002E
+:10DB300000000004000017B4000000000000000412
+:10DB4000000017B80000000000000004000017BC2F
+:10DB50000000000000000008000017A800000000FE
+:10DB600000000008000017D80000000000000002BC
+:10DB70000006000000400000000000400000C0005F
+:10DB800000400000000000400000C02E00400000E7
+:10DB9000000000010000C000004000020000000181
+:10DBA0000000C00100400002000000000000E20090
+:10DBB00000200000000000200000E2040002000835
+:10DBC00000200002800000000000000000000000B3
+:10DBD0000000E20000080020000000040000F50042
+:10DBE00000280000000000280000F640001000009F
+:10DBF000000000100000F64A0010000000000001C4
+:10DC00000000F6C000200000000000200000F6C068
+:10DC100000020020000000020000F30000400000AD
+:10DC2000000000400000200800100000000000106C
+:10DC3000000020000000000000000008000011A803
+:10DC40000008000000000001000011A90008000009
+:10DC500000000001000011AA0008000000000001FF
+:10DC600000004000002000040000001000005900E7
+:10DC700000300018000000100000590800300018A3
+:10DC80000000000200005700000800000000000132
+:10DC900000005701000800000000000100001158BA
+:10DCA0000000000000000001000011600000000002
+:10DCB00000000010000011AC00080000000000048B
+:10DCC0000000400000200000000000200000530081
+:10DCD0000010000000000010000000000000000024
+:10DCE0000000000000000000000000000000000034
+:10DCF0000000000000000000000000000000000024
+:10DD0000000000000000000000001470000000008F
+:10DD100000000001000014B0000000000000000836
+:10DD20000000005000000000000000000000147817
+:10DD300000000000000000040000147C000000004F
+:10DD40000000000400001480000000000000000437
+:10DD5000000014840000000000000004000014888B
+:10DD6000000000000000000800002AF00080000011
+:10DD70000000008000000001000000000000000022
+:10DD8000000020080010000000000010000020002B
+:10DD9000000000000000000800002C7000080000D7
+:10DDA0000000000100002C710008000000000001CC
+:10DDB00000002C7200080000000000010000415823
+:10DDC0000038000000000038800000000000000063
+:10DDD0000000000000002C440008000000000002C9
+:10DDE00000002C46000800000000000200002C5437
+:10DDF000001000000000000400002EB00000000031
+:10DE00000000002000006000002000000000002052
+:10DE1000000073000008000000000008000000007F
+:10DE200000000000000000000000000000000000F2
+:10DE300000000000000000000000000000000000E2
+:10DE400000000000000000000000000000002F584B
+:10DE5000000000000000000100002F9800000000FA
+:10DE6000000000080000005000000000000000005A
+:10DE700000002F80000000000000000400002F843C
+:10DE8000000000000000000400002F8800000000D7
+:10DE90000000000400002F8C0000000000000008BB
+:10DEA00000002FA800000000000000028000000019
+:10DEB00000000000000000008000000000000000E2
+:10DEC00000000000800000000000000000000000D2
+:10DED0008000000000000000000000000000312869
+:10DEE00000080000000000010000312900080000C7
+:10DEF0000000000100062A20260000400000000863
+:10DF00000000A0000000000000002000000040C150
+:10DF10000000000000000001000040F000000000D0
+:10DF2000000000028000000000000000000000006F
+:10DF30000000600000200000000000080000400019
+:10DF4000000800000000000100004001000800007F
+:10DF50000000000100004040000800040000000232
+:10DF60000000406000080004000000040000408041
+:10DF7000000800000000000400004000000800004D
+:10DF8000000000040000400400080000000000043D
+:10DF90000000404000000000000000080000404871
+:10DFA00000000000000000080000800000000000E9
+:10DFB00000000010000050400001000400000001BB
+:10DFC0000000500000000000000000200000500889
+:10DFD00000100000000000040000500C00100000C1
+:10DFE00000000001000052C7000000000000000116
+:10DFF000000052C6000000000000000100003000D8
+:10E000000040002000000004000030040040002018
+:10E010000000000400003008004000200000000262
+:10E020000000300A00400020000000020000300C18
+:10E0300000400020000000010000300D00400020E2
+:10E04000000000010000300E004000200000000130
+:10E0500000003010004000200000000400003014D8
+:10E0600000400020000000040000301800400020A4
+:10E07000000000040000301C0040002000000004EC
+:10E080000000C00001000080000800040000C0047F
+:10E0900001000080000800040000000A00000000E9
+:10E0A000000000000000C0680100008000000001C6
+:10E0B0000000C06901000080000000010000C06C89
+:10E0C00001000080000000020000C06E010000801E
+:10E0D000000000020000C070010000800000000489
+:10E0E0000000C07401000080000000040000C06651
+:10E0F00001000080000000020000C06401000080F8
+:10E10000000000010000C06001000080000000026B
+:10E110000000C06201000080000000020000C0504A
+:10E1200001000080000000040000C05401000080D5
+:10E13000000000040000C05801000080000000043E
+:10E140000000C05C01000080000000040000C07CF2
+:10E1500001000080000000010000C07D010000807F
+:10E160000000000100001018001000000000000472
+:10E170000000109000100000000000040000109843
+:10E18000001000000000000400001110000000005A
+:10E190000000000200001112000000000000000258
+:10E1A0000000111400000000000000020000111621
+:10E1B00000000000000000020000604000080000B5
+:10E1C00000000002000060420008000000000002A1
+:10E1D00000006044000800000000000200006046EB
+:10E1E000000800000000000200006080000800003D
+:10E1F00000000008000060000008000000000002AD
+:10E20000000060020008000000000001000060043F
+:10E210000008000000000002000060C000080000CC
+:10E220000000000800006100000800000000000479
+:10E2300000006104000800000000000100006140CF
+:10E240000008000000000002000061440008000017
+:10E25000000000020000614200080000000000020F
+:10E260000000618000080000000000040000300091
+:10E27000000800000000000200003002000800005A
+:10E28000000000010000300400080000000000024F
+:10E290000000304000080000000000020000304490
+:10E2A00000080000000000020000304600080000E6
+:10E2B00000000002000036600008000000000008B6
+:10E2C00000003080000800000000000200003084E0
+:10E2D0000008000000000002000036A00008000056
+:10E2E000000000080000804000080000000000015D
+:10E2F0000000804100080000000000010000804292
+:10E300000008000000000001000080430008000039
+:10E310000000000100008000000800000000000272
+:10E3200000008002000800000000000100008004DE
+:10E330000008000000000002000080C0000800008B
+:10E3400000000002000080C200080000000000027F
+:10E35000000080C40008000000000002000080806F
+:10E36000000800000000000100008081000800009B
+:10E370000000000100008082000800000000000191
+:10E38000000080830008000000000001000080847D
+:10E390000008000000000001000080850008000067
+:10E3A000000000010000808600080000000000015D
+:10E3B0000000600000080000000000020000600291
+:10E3C00000080000000000010000600400080000D8
+:10E3D000000000020000604200C0001800000002BF
+:10E3E0000000604000C00018000000020000604C07
+:10E3F00000C00018000000080000604400C00018C1
+:10E40000000000080000605700C000180000000174
+:10E410000000605400C000180000000200006056B8
+:10E4200000C0001800000001000066400008000065
+:10E4300000000008000066800008000000000008DE
+:10E44000000066C000080000000000080000DA823A
+:10E4500000180000000000020000DBA00000000027
+:10E46000000000000000E0000000000000000004C8
+:10E470000000D10000000000000000040000D104F2
+:10E4800000000000000000040000D10800000000AF
+:10E49000000000040000D10C000000000000000497
+:10E4A0000000D11000000000000000040000D114A2
+:10E4B00000000000000000040000D118000000006F
+:10E4C000000000040000D100000000000000002057
+:10E4D0000000928000000000000000040000928014
+:10E4E00000000000000000280000805000A800008C
+:10E4F000000000010000805400A80000000000019E
+:10E50000000080000000000000000050000080506B
+:10E510000000000000000010000096000000000055
+:10E52000000000040000940000000000000000044F
+:10E5300000009404000000000000000400009408A3
+:10E5400000000000000000040000940C0000000027
+:10E55000000000040000941000000000000000040F
+:10E560000000941400000000000000040000941853
+:10E570000000000000000004000094000000000003
+:10E580000000004000009420000000000000000493
+:10E590000000942400000000000000040000942803
+:10E5A00000000000000000040000941C00000000B7
+:10E5B000000000040000943000000000000000048F
+:10E5C0000000942C000000000000000400009434BF
+:10E5D0000000000000000004000092840000000021
+:10E5E0000000000400009280000000000000000411
+:10E5F000000092900000000000000004000092A4BF
+:10E60000000000000000000400009438000000003A
+:10E61000000000040000943C000000000000000422
+:10E620000000B98800000000000000000000D000D9
+:10E6300000000000000000040000B1000000000025
+:10E64000000000040000B10400000000000000040D
+:10E650000000B10800000000000000040000B1004C
+:10E6600000000000000000100000BCB0000000002E
+:10E67000000000040000BCB4000000000000000422
+:10E680000000BCB000000000000000480000D86896
+:10E6900000000000000000040000D860000000003E
+:10E6A000000000040000D864000000000000000426
+:10E6B0000000D86C00000000000000040000D860DA
+:10E6C00000000000000000100000D8500000000012
+:10E6D000000000040000D854000000000000000406
+:10E6E0000000D85000000000000000080000D4C85E
+:10E6F00000000000000000080000D4D80000000066
+:10E700000000008000000010000000000000000079
+:10E710000000D4D800000000000000080000000045
+:08E72000070C1E0000000000C0
+:00000001FF
--- zfcpdump-kernel-4.4.orig/firmware/cis/3CCFEM556.cis.ihex
+++ /dev/null
@@ -1,13 +0,0 @@
-:1000000001030000FF152D050033436F6D004D65A2
-:100010006761686572747A2033434346454D3535D0
-:1000200036004C414E202B2035366B204D6F6465D9
-:100030006D0000FF20040101560521020000060B9F
-:1000400002004D000000006B000000FF001303439E
-:100050004953210206001A060507001067021B0912
-:1000600087011901556430FFFFFF00130343495313
-:10007000210202001A060527001177021B09A701B9
-:090080001901552330FFFFFF00B8
-:00000001FF
-#
-# This card is MFC-compliant, but identifies itself as single function
-#
--- zfcpdump-kernel-4.4.orig/firmware/cis/3CXEM556.cis.ihex
+++ /dev/null
@@ -1,13 +0,0 @@
-:1000000001030000FF152C050033436F6D004D65A3
-:100010006761686572747A20334358454D353536CB
-:10002000004C414E202B2035366B204D6F64656DA2
-:100030000000FF20040101350021020000060B0230
-:10004000004C0000000069000000FF00130343495A
-:1000500053210206001A0501070008631B098701E6
-:100060001901556430FFFFFF001303434953210278
-:1000700002001A0501270009631B09A70119015590
-:060080002330FFFFFF002A
-:00000001FF
-#
-# This card is MFC-compliant, but identifies itself as single function
-#
--- zfcpdump-kernel-4.4.orig/firmware/cis/COMpad2.cis.ihex
+++ /dev/null
@@ -1,11 +0,0 @@
-:1000000001030000FF151F0401414456414E5445B1
-:10001000434800434F4D7061642D33322F38350013
-:10002000312E300000FF210202011A0501050001F6
-:10003000031B0EC18118AA61E80207E8030730B864
-:100040009E1B08820108AA6030030F1B0883010869
-:10005000AA6040030F1B08840108AA6050030F1B0D
-:0D00600008850108AA6060030F1400FF006E
-:00000001FF
-#
-# Replacement CIS for Advantech COMpad-32/85
-#
--- zfcpdump-kernel-4.4.orig/firmware/cis/COMpad4.cis.ihex
+++ /dev/null
@@ -1,9 +0,0 @@
-:1000000001030000FF151F0401414456414E5445B1
-:10001000434800434F4D7061642D33322F383542D1
-:100020002D34000000FF210202011A050102000127
-:10003000011B0BC18118AA6040021F30B89E1B082B
-:0C004000820108AA6040031F1400FF00AA
-:00000001FF
-#
-# Replacement CIS for Advantech COMpad-32/85B-4
-#
--- zfcpdump-kernel-4.4.orig/firmware/cis/DP83903.cis.ihex
+++ /dev/null
@@ -1,14 +0,0 @@
-:1000000001030000FF152904014D756C74696675C4
-:100010006E6374696F6E20436172640000004E531A
-:1000200043204D46204C414E2F4D6F64656D00FFBF
-:1000300020047501000021020000060B02004900A7
-:100040000000006A000000FF00130343495321022F
-:1000500006001A060517201077021B0C970179017C
-:10006000556530FFFF284000FF001303434953212B
-:100070000202001A060507401077021B09870119C2
-:0800800001552330FFFFFF00D2
-:00000001FF
-#
-# This CIS is for cards based on the National Semiconductor
-# DP83903 Multiple Function Interface Chip
-#
--- zfcpdump-kernel-4.4.orig/firmware/cis/LA-PCM.cis.ihex
+++ /dev/null
@@ -1,20 +0,0 @@
-:100000000105D4F953E9FF17035338FF20040FC04B
-:1000100002002102060315390401416C6C69656414
-:100020002054656C657369732C4B2E4B00457468C6
-:1000300065726E6574204C414E20436172640043CA
-:10004000656E747265434F4D004C412D50434D0019
-:10005000FF1A0602100000020B1B08810108E06075
-:1000600000021F1B08820108E06020021F1B08839A
-:100070000108E06040021F1B08840108E060600284
-:100080001F1B08850108E06080021F1B088601080D
-:10009000E060A0021F1B08870108E060C0021F1B70
-:1000A00008880108E060E0021F1B08890108E06081
-:1000B00000031F1B088A0108E06020031F1B088B38
-:1000C0000108E06040031F1B088C0108E06060032A
-:1000D0001F1B088D0108E06080031F1B088E0108AC
-:1000E000E060A0031F1B088F0108E060C0031F1B16
-:0D00F00008900108E060E0031F1400FF000D
-:00000001FF
-#
-# Replacement CIS for Allied Telesis LA-PCM
-#
--- zfcpdump-kernel-4.4.orig/firmware/cis/MT5634ZLX.cis.ihex
+++ /dev/null
@@ -1,11 +0,0 @@
-:100000000101FF152204014D756C74695465636824
-:100010000050434D4349412035364B2044617461C3
-:10002000466178000000FF20040002010021020266
-:10003000001A05012780FF671B0FCF418B01550177
-:10004000550155AA60F80307281B08970108AA6004
-:10005000F802071B089F0108AA60E803071B08A70E
-:0B0060000108AA60E802071400FF007E
-:00000001FF
-#
-# Replacement CIS for Multitech MT5634ZLX modems
-#
--- zfcpdump-kernel-4.4.orig/firmware/cis/NE2K.cis.ihex
+++ /dev/null
@@ -1,8 +0,0 @@
-:1000000001030000FF1515040150434D4349410011
-:1000100045746865726E6574000000FF2102060079
-:100020001A050120F803031B09E001190155653089
-:06003000FFFF1400FF00B9
-:00000001FF
-#
-# Replacement CIS for various busted NE2000-compatible cards
-#
--- zfcpdump-kernel-4.4.orig/firmware/cis/PCMLM28.cis.ihex
+++ /dev/null
@@ -1,18 +0,0 @@
-:1000000001030000FF151504014C494E4B53595391
-:100010000050434D4C4D3238000000FF2004430196
-:10002000ABC0210200001A05012FF803031B10E4E6
-:1000300001190155E06100031FF8020730FFFF1BA3
-:100040000BA50108E06120031FF802071B0BA601A6
-:1000500008E06140031FF802071B0BA70108E061DD
-:1000600060031FF802071B0BA80108E06100031FD3
-:10007000E803071B0BA90108E06120031FE8030741
-:100080001B0BAA0108E06140031FE803071B0BAB31
-:100090000108E06160031FE803071B0BAC0108E0E7
-:1000A0006100031FE802071B0BAD0108E06120039C
-:1000B0001FE802071B0BAE0108E06140031FE802C6
-:1000C000071B0BAF0108E06160031FE80207140083
-:0200D000FF002F
-:00000001FF
-#
-# The on-card CIS says it is MFC-compliant, but it is not
-#
--- zfcpdump-kernel-4.4.orig/firmware/cis/PE-200.cis.ihex
+++ /dev/null
@@ -1,9 +0,0 @@
-:1000000001030000FF151E0401504D582020200060
-:1000100050452D3230300045544845524E4554002D
-:1000200052303100FF210206031A050101000101CF
-:100030001B0EC181190155E051000F100F30FFFF59
-:040040001400FF00A9
-:00000001FF
-#
-# Replacement CIS for PE-200 ethernet card
-#
--- zfcpdump-kernel-4.4.orig/firmware/cis/PE520.cis.ihex
+++ /dev/null
@@ -1,9 +0,0 @@
-:1000000001030000FF152304014B544900504535FE
-:10001000323020504C55530050434D434941204508
-:10002000746865726E65740000FF20046101100041
-:10003000210206001A050101D00F0B1B09C101198D
-:0A00400001556530FFFF1400FF00BA
-:00000001FF
-#
-# Replacement CIS for PE520 ethernet card
-#
--- zfcpdump-kernel-4.4.orig/firmware/cis/RS-COM-2P.cis.ihex
+++ /dev/null
@@ -1,10 +0,0 @@
-:1000000001030000FF1516040150434D4349410010
-:1000100052532D434F4D203250000000FF21020269
-:10002000011A0501030001011B0EC18118AA61E834
-:100030000307E8020730B89E1B0B820108AA615033
-:1000400002075802071B0B830108AA6160020768B8
-:0600500002071400FF008E
-:00000001FF
-#
-# Replacement CIS for dual-serial-port IO card
-#
--- zfcpdump-kernel-4.4.orig/firmware/cis/SW_555_SER.cis.ihex
+++ /dev/null
@@ -1,12 +0,0 @@
-:100000000101FF17034100FF20043F0110072102F7
-:100010000200152A070053696572726120576972E0
-:10002000656C657373004169724361726420353594
-:1000300035004135353500526576203100FF1A050F
-:1000400001030007731B0BE00118A360F8030730DE
-:10005000BC3F1B08A10108A360F802071B08A2010E
-:1000600008A360E803071B08A30108A360E80207D0
-:0A0070001B04A40108231400FF0084
-:00000001FF
-#
-# Replacement CIS for AC555 provided by Sierra Wireless
-#
--- zfcpdump-kernel-4.4.orig/firmware/cis/SW_7xx_SER.cis.ihex
+++ /dev/null
@@ -1,13 +0,0 @@
-:100000000101FF17034100FF2004920110072102A4
-:1000100002001537070053696572726120576972D3
-:10002000656C6573730041433731302F4143373579
-:10003000300047505253204E6574776F726B2041E9
-:1000400064617074657200523100FF1A050103008B
-:1000500007731B10E00119784D555D25A360F80367
-:100060000730BC861B08A10108A360F802071B0823
-:10007000A20108A360E803071B08A30108A360E826
-:0C00800002071B04A40108231400FF0069
-:00000001FF
-#
-# Replacement CIS for AC7xx provided by Sierra Wireless
-#
--- zfcpdump-kernel-4.4.orig/firmware/cis/SW_8xx_SER.cis.ihex
+++ /dev/null
@@ -1,13 +0,0 @@
-:100000000101FF17034100FF2004920110072102A4
-:100010000200152F070053696572726120576972DB
-:10002000656C657373004143383530003347204EAB
-:100030006574776F726B20416461707465720052F1
-:100040003100FF1A0501030007731B10E001197846
-:100050004D555D25A360F8480730BC861B08A101FB
-:1000600008A360F847071B08A20108A360E8480737
-:100070001B08A30108A360E847071B04A401082389
-:040080001400FF0069
-:00000001FF
-#
-# Replacement CIS for AC8xx provided by Sierra Wireless
-#
--- zfcpdump-kernel-4.4.orig/firmware/cis/tamarack.cis.ihex
+++ /dev/null
@@ -1,10 +0,0 @@
-:100000000103D400FF17034100FF152404015441EC
-:100010004D415241434B0045746865726E657400F2
-:10002000410030303437343331313830303100FF33
-:10003000210206001A050120F803031B14E08119B0
-:100040003F554D5D06864626E551000F100F30FFE7
-:05005000FF1400FF0099
-:00000001FF
-#
-# Replacement CIS for Surecom, Tamarack NE2000 cards
-#
--- zfcpdump-kernel-4.4.orig/firmware/cpia2/stv0672_vp4.bin.ihex
+++ /dev/null
@@ -1,73 +0,0 @@
-:1000000001BCE302E303E304E305E306E3079344EF
-:1000100056D4934E5651934E51D6934E4F54934EC1
-:10002000924F92A4930592F4931B929291E692368A
-:100030009274924A928C928EC8D00B4202A0CA92BD
-:100040000902C9100A0A0A81E3B8E3B0E3A8E3A0F1
-:10005000E398E390E100CFD70A12CC9508B20A18D2
-:10006000E10001EE0C084A12C818F09AC022F31CF5
-:100070004A13F314C8A0F214F21CEB13D3A26316B4
-:10008000489EF018A403F393C058F713519CE9203D
-:10009000CFEF63F9922ED35F63FA922ED36763FB9F
-:1000A000922ED36FE91A631648A7F020A406F394A2
-:1000B000C027F714F513519DF6136318C420CBEF36
-:1000C00063FC922ED37763FD922ED37F63FE922E34
-:1000D000D38763FF922ED38F6438922ED3976439DF
-:1000E000922ED39FE100F53AF43BF7BFF2BCF23D0C
-:1000F000E1008087908051D5022202324BD3F71164
-:100100000BDAE1000E0202400DB5E3024855E5129C
-:10011000A401E81BE390F018A401E8BF8DB84BD10F
-:100120004BD80BCB0BC2E100E302E30352D360597F
-:10013000E6930D2252D4E6930D2AE398E390E10072
-:10014000025D0263E302C81202CAC85202C2826898
-:10015000E302C81402CAC89002C20AD0C9930ADADC
-:10016000CCD20AE2631202DA0A980AA00AA8E39043
-:10017000E100E3020AD0C9930ADACCD20AE26312A0
-:1001800002DA0A980AA00AA84991E56AA404C812EA
-:1001900002CAC8528289C81402CAC89002C2E39037
-:1001A000E1000860E1004853E897085AE100E302E3
-:1001B000E30354D36059E6930D52E398E390E100D2
-:1001C000029CE3025513931755139317E390E10034
-:1001D0007530E302E30355556059E6930DB2E39899
-:1001E000E390E10002AEE792E918EA9AE898E81095
-:1001F000E811E851D2DAD2F3E813D2FAE850D2EAA1
-:10020000E8D0E8D1D30A03094823E52CA003482409
-:10021000EA1C0308D2E3D303D313E10002CB059316
-:100220005793F09AAC0BE30792EAE29FE506E3B03E
-:10023000A002EB1E82D7EA1EE23B859BE91EC89016
-:10024000859402DE05805793F0BAAC0692EAE2BFCD
-:10025000E506A001EBBF8588E93EC8908581E93EAF
-:10026000F0BAF339F03A6017F03AC090F0BAE10012
-:10027000003FE302E30358106059E6930DA25812C1
-:10028000E6930DAAE398E390E1000301E100030384
-:100290009B7D8B8BE302E30358566059E6930DBABE
-:1002A000E398E390E100030F9311E100E3024A11A8
-:1002B0000B4291AFE390E100F291F091A3FEE100D7
-:1002C0006092C05FF013F013595BE213F0115A19FA
-:1002D000E213E10000000327686176616E610006A9
-:1002E000032CE302E303E9385915595AF29ABC0B7F
-:1002F000A40A591EF311F01AE2BB5915F011192A7C
-:10030000E502A401EBBFE398E390E1000342192862
-:10031000E100E9306079E100E303E3076079934E9F
-:10032000E3B8E398E100E91AF01FE233F091E292BA
-:08033000E032F031E1000000B1
-:00000001FF
-
-  Copyright 2001, STMicrolectronics, Inc.
-  Contact:  steve.miller@st.com
-
-  Description:
-     This file contains patch data for the CPiA2 (stv0672) VP4.
-
-  This program is free software; you can redistribute it and/or modify
-  it under the terms of the GNU General Public License as published by
-  the Free Software Foundation; either version 2 of the License, or
-  (at your option) any later version.
-
-  This program is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-  GNU General Public License for more details.
-
-  You should have received a copy of the GNU General Public License
-  along with this program; if not, write to the Free Software
-  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
--- zfcpdump-kernel-4.4.orig/firmware/cxgb3/ael2005_opt_edc.bin.ihex
+++ /dev/null
@@ -1,69 +0,0 @@
-:10000000CC002FF4CC013CD4CC022015CC0331051C
-:10001000CC046524CC0527FFCC06300FCC072C8BF5
-:10002000CC08300BCC094009CC0A400ECC0B2F7207
-:10003000CC0C3002CC0D1002CC0E2172CC0F301241
-:10004000CC101002CC1125D2CC123012CC131002DD
-:10005000CC14D01ECC1527D2CC163012CC171002DF
-:10006000CC182004CC193C84CC1A6436CC1B200755
-:10007000CC1C3F87CC1D8676CC1E40B7CC1FA74634
-:10008000CC204047CC215673CC222982CC2330028D
-:10009000CC2413D2CC258BBDCC262862CC273012A1
-:1000A000CC281002CC292092CC2A3012CC2B100262
-:1000B000CC2C5CC3CC2D0314CC2E2942CC2F300287
-:1000C000CC301002CC31D019CC322032CC333012AB
-:1000D000CC341002CC352A04CC363C74CC37643591
-:1000E000CC382FA4CC393CD4CC3A6624CC3B5563D5
-:1000F000CC3C2D42CC3D3002CC3E13D2CC3F464DC1
-:10010000CC402862CC413012CC421002CC43203289
-:10011000CC443012CC451002CC462FB4CC473CD452
-:10012000CC486624CC495563CC4A2D42CC4B300296
-:10013000CC4C13D2CC4D2ED2CC4E3002CC4F100230
-:10014000CC502FD2CC513002CC521002CC530004F0
-:10015000CC542942CC553002CC561002CC572092B8
-:10016000CC583012CC591002CC5A5CC3CC5B03176C
-:10017000CC5C2F72CC5D3002CC5E1002CC5F294289
-:10018000CC603002CC611002CC6222CDCC63301D39
-:10019000CC642862CC653012CC661002CC672ED2BB
-:1001A000CC683002CC691002CC6A2D72CC6B300264
-:1001B000CC6C1002CC6D628FCC6E2112CC6F3012E1
-:1001C000CC701002CC715AA3CC722DC2CC73300209
-:1001D000CC741312CC756F72CC761002CC772807D2
-:1001E000CC7831A7CC7920C4CC7A3C24CC7B672452
-:1001F000CC7C1002CC7D2807CC7E3187CC7F20C4FC
-:10020000CC803C24CC816724CC821002CC83251482
-:10021000CC843C64CC856436CC86DFF4CC876436F1
-:10022000CC881002CC8940A4CC8A643CCC8B40168C
-:10023000CC8C8C6CCC8D2B24CC8E3C24CC8F643518
-:10024000CC901002CC912B24CC923C24CC93643AD9
-:10025000CC944025CC958A5ACC961002CC97273165
-:10026000CC983011CC991001CC9AC7A0CC9B01003E
-:10027000CC9CC502CC9D53ACCC9EC503CC9FD5D5A0
-:10028000CCA0C600CCA12A6DCCA2C601CCA32A4C1E
-:10029000CCA4C602CCA50111CCA6C60CCCA7590093
-:1002A000CCA8C710CCA90700CCAAC718CCAB0700B4
-:1002B000CCACC720CCAD4700CCAEC801CCAF7F5092
-:1002C000CCB0C802CCB17760CCB2C803CCB37FCE7F
-:1002D000CCB4C804CCB55700CCB6C805CCB75F11B8
-:1002E000CCB8C806CCB94751CCBAC807CCBB57E18B
-:1002F000CCBCC808CCBD2700CCBEC809CCBF000010
-:10030000CCC0C821CCC10002CCC2C822CCC30014CE
-:10031000CCC4C832CCC51186CCC6C847CCC71E02D7
-:10032000CCC8C013CCC9F341CCCAC01ACCCB04464C
-:10033000CCCCC024CCCD1000CCCEC025CCCF0A0074
-:10034000CCD0C026CCD10C0CCCD2C027CCD30C0C3A
-:10035000CCD4C029CCD500A0CCD6C030CCD70A0094
-:10036000CCD8C03CCCD9001CCCDAC005CCDB7A069A
-:10037000CCDC0000CCDD2731CCDE3011CCDF10012D
-:10038000CCE0C620CCE10000CCE2C621CCE3003FAB
-:10039000CCE4C622CCE50000CCE6C623CCE70000C6
-:1003A000CCE8C624CCE90000CCEAC625CCEB0000A2
-:1003B000CCECC627CCED0000CCEEC628CCEF00007C
-:1003C000CCF0C62CCCF10000CCF20000CCF3280617
-:1003D000CCF43CB6CCF5C161CCF66134CCF76135D8
-:1003E000CCF85443CCF90303CCFA6524CCFB000BC6
-:1003F000CCFC1002CCFD2104CCFE3C24CCFF21051A
-:10040000CD003805CD016524CD02DFF4CD034005D4
-:10041000CD046524CD051002CD065DD3CD070306BE
-:10042000CD082FF7CD0938F7CD0A60B7CD0BDFFD2A
-:10043000CD0C000ACD0D1002CD0E00007CC7AE59C8
-:00000001FF
--- zfcpdump-kernel-4.4.orig/firmware/cxgb3/ael2005_twx_edc.bin.ihex
+++ /dev/null
@@ -1,93 +0,0 @@
-:10000000CC004009CC0127FFCC02300FCC0340AA22
-:10001000CC04401CCC05401ECC062FF4CC073CD4AD
-:10002000CC082035CC093145CC0A6524CC0B26A25E
-:10003000CC0C3012CC0D1002CC0E29C2CC0F3002E9
-:10004000CC101002CC112072CC123012CC13100242
-:10005000CC1422CDCC15301DCC162E52CC1730121C
-:10006000CC181002CC1928E2CC1A3002CC1B10029A
-:10007000CC1C628FCC1D2AC2CC1E3012CC1F1002A9
-:10008000CC205553CC212AE2CC223002CC231302BF
-:10009000CC24401ECC252BE2CC263012CC271002DB
-:1000A000CC282DA2CC293012CC2A1002CC2B2BA28A
-:1000B000CC2C3002CC2D1002CC2E5EE3CC2F0305CD
-:1000C000CC30400ECC312BC2CC323002CC331002BB
-:1000D000CC342B82CC353012CC361002CC37566360
-:1000E000CC380302CC39401ECC3A6F72CC3B1002A4
-:1000F000CC3C628FCC3D2BE2CC3E3012CC3F100288
-:10010000CC4022CDCC41301DCC422E52CC433012BB
-:10011000CC441002CC452522CC463012CC471002EC
-:10012000CC482DA2CC493012CC4A1002CC4B2CA288
-:10013000CC4C3012CC4D1002CC4E2FA4CC4F3CD422
-:10014000CC506624CC51410BCC5256B3CC5303C493
-:10015000CC542FB2CC553002CC561002CC57220BC7
-:10016000CC58303BCC5956B3CC5A03C3CC5B866BCE
-:10017000CC5C400CCC5D23A2CC5E3012CC5F100274
-:10018000CC602DA2CC613012CC621002CC632CA2C8
-:10019000CC643012CC651002CC662FB4CC673CD452
-:1001A000CC686624CC6956B3CC6A03C3CC6B866B2F
-:1001B000CC6C401CCC6D2205CC6E3035CC6F5B53C3
-:1001C000CC702C52CC713002CC7213C2CC735CC395
-:1001D000CC740317CC752522CC763012CC77100264
-:1001E000CC782DA2CC793012CC7A1002CC7B2B8229
-:1001F000CC7C3012CC7D1002CC7E5663CC7F0303C6
-:10020000CC80401ECC810004CC822C42CC833012A6
-:10021000CC841002CC856F72CC861002CC87628FA2
-:10022000CC882304CC893C84CC8A6436CC8BDFF424
-:10023000CC8C6436CC8D2FF5CC8E3005CC8F865689
-:10024000CC90DFBACC9156A3CC92D05ACC9321C299
-:10025000CC943012CC951392CC96D05ACC9756A30E
-:10026000CC98DFBACC990383CC9A6F72CC9B1002E6
-:10027000CC9C28C5CC9D3005CC9E4178CC9F565354
-:10028000CCA00384CCA122B2CCA23012CCA3100209
-:10029000CCA42BE5CCA53005CCA641E8CCA7565381
-:1002A000CCA80382CCA90002CCAA4258CCAB2474BF
-:1002B000CCAC3C84CCAD6437CCAEDFF4CCAF64378F
-:1002C000CCB02FF5CCB13C05CCB28757CCB3B888B5
-:1002D000CCB49787CCB5DFF4CCB66724CCB7866AAC
-:1002E000CCB86F72CCB91002CCBA2D01CCBB301196
-:1002F000CCBC1001CCBDC620CCBE14E5CCBFC62101
-:10030000CCC0C53DCCC1C622CCC23CBECCC3C623EA
-:10031000CCC44452CCC5C624CCC6C5C5CCC7C625A2
-:10032000CCC8E01ECCC9C627CCCA0000CCCBC6289E
-:10033000CCCC0000CCCDC62BCCCE0000CCCFC62C74
-:10034000CCD00000CCD10000CCD22D01CCD33011C8
-:10035000CCD41001CCD5C620CCD60000CCD7C62139
-:10036000CCD80000CCD9C622CCDA00CECCDBC62358
-:10037000CCDC007FCCDDC624CCDE0032CCDFC62551
-:10038000CCE00000CCE1C627CCE20000CCE3C628DC
-:10039000CCE40000CCE5C62BCCE60000CCE7C62CB4
-:1003A000CCE80000CCE90000CCEA2D01CCEB301108
-:1003B000CCEC1001CCEDC502CCEE609FCCEFC600BA
-:1003C000CCF02A6ECCF1C601CCF22A2CCCF3C60CB0
-:1003D000CCF45400CCF5C710CCF60700CCF7C71806
-:1003E000CCF80700CCF9C720CCFA4700CCFBC728D3
-:1003F000CCFC0700CCFDC729CCFE1207CCFFC801FE
-:10040000CD007F50CD01C802CD027760CD03C80377
-:10041000CD047FCECD05C804CD06520ECD07C8054C
-:10042000CD085C11CD09C806CD0A3C51CD0BC807DB
-:10043000CD0C4061CD0DC808CD0E49C1CD0FC80906
-:10044000CD103840CD11C80ACD120000CD13C821FF
-:10045000CD140002CD15C822CD160046CD17C844D4
-:10046000CD18182FCD19C013CD1AF341CD1BC01ACA
-:10047000CD1C0446CD1DC024CD1E1000CD1FC025AF
-:10048000CD200A00CD21C026CD220C0CCD23C027C3
-:10049000CD240C0CCD25C029CD2600A0CD27C03001
-:1004A000CD280A00CD29C03CCD2A001CCD2B000050
-:1004B000CD2C2B84CD2D3C74CD2E6435CD2FDFF487
-:1004C000CD306435CD312806CD323006CD3385654B
-:1004D000CD342B24CD353C24CD366436CD371002B7
-:1004E000CD382B24CD393C24CD3A6436CD3B404524
-:1004F000CD3C8656CD3D1002CD3E2807CD3F31A7DD
-:10050000CD4020C4CD413C24CD426724CD431002D0
-:10051000CD442807CD453187CD4620C4CD473C2466
-:10052000CD486724CD491002CD4A2514CD4B3C64FB
-:10053000CD4C6436CD4DDFF4CD4E6436CD4F100238
-:10054000CD502806CD513CB6CD52C161CD5361345A
-:10055000CD546135CD555443CD560303CD57652455
-:10056000CD58000BCD591002CD5AD019CD5B2104C6
-:10057000CD5C3C24CD5D2105CD5E3805CD5F652485
-:10058000CD60DFF4CD614005CD626524CD632E8D55
-:10059000CD64303DCD655DD3CD660306CD672FF7C5
-:1005A000CD6838F7CD6960B7CD6ADFFDCD6B000A45
-:0C05B000CD6C1002CD6D000052A76B0E48
-:00000001FF
--- zfcpdump-kernel-4.4.orig/firmware/cxgb3/ael2020_twx_edc.bin.ihex
+++ /dev/null
@@ -1,100 +0,0 @@
-:10000000D8004009D8012FFFD802300FD80340AAEA
-:10001000D804401CD805401ED8062FF4D8073DC48C
-:10002000D8082035D8093035D80A6524D80B2CB229
-:10003000D80C3012D80D1002D80E26E2D80F30227C
-:10004000D8101002D81127D2D8123022D81310029B
-:10005000D8142822D8153012D8161002D817249296
-:10006000D8183022D8191002D81A2772D81B30128B
-:10007000D81C1002D81D23D2D81E3022D81F10023F
-:10008000D82022CDD821301DD82227F2D8233022E3
-:10009000D8241002D8255553D8260307D82725225F
-:1000A000D8283022D8291002D82A2142D82B301241
-:1000B000D82C1002D82D4016D82E5E63D82F0344BA
-:1000C000D8302142D8313012D8321002D833400E05
-:1000D000D8342522D8353022D8361002D8372B52C2
-:1000E000D8383012D8391002D83A2742D83B3022BB
-:1000F000D83C1002D83D25E2D83E3022D83F10022D
-:10010000D8402FA4D8413DC4D8426624D843414B9F
-:10011000D84456B3D84503C6D846866BD847400C5A
-:10012000D8482712D8493012D84A1002D84B2C4B45
-:10013000D84C309BD84D56B3D84E03C3D84F866B9E
-:10014000D850400CD8512272D8523022D8531002C5
-:10015000D8542742D8553022D8561002D85725E215
-:10016000D8583022D8591002D85A2FB4D85B3DC481
-:10017000D85C6624D85D56B3D85E03C3D85F866B5F
-:10018000D860401CD8612C45D8623095D8635B5349
-:10019000D8642372D8653012D86613C2D8675CC39E
-:1001A000D8682712D8693012D86A1312D86B2B522C
-:1001B000D86C3012D86D1002D86E2742D86F30221A
-:1001C000D8701002D8712582D8723022D8731002EC
-:1001D000D8742142D8753012D8761002D877628F41
-:1001E000D8782985D87933A5D87A25E2D87B3022EA
-:1001F000D87C1002D87D5653D87E03D2D87F401EBB
-:10020000D8806F72D8811002D882628FD88323047D
-:10021000D8843C84D8856436D886DFF4D8876436A1
-:10022000D8882FF5D8893005D88A8656D88BDFBA7A
-:10023000D88C56A3D88DD05AD88E2972D88F301228
-:10024000D8901392D891D05AD89256A3D893DFBAA7
-:10025000D8940383D8956F72D8961002D8972B45FF
-:10026000D8983005D8994178D89A5653D89B0384AA
-:10027000D89C2A62D89D3012D89E1002D89F2F0594
-:10028000D8A03005D8A141C8D8A25653D8A303821C
-:10029000D8A40002D8A54218D8A62474D8A73C84B4
-:1002A000D8A86437D8A9DFF4D8AA6437D8AB2FF51B
-:1002B000D8AC3C05D8AD8757D8AEB888D8AF9787AB
-:1002C000D8B0DFF4D8B16724D8B2866AD8B36F72D9
-:1002D000D8B41002D8B52641D8B63021D8B710010D
-:1002E000D8B8C620D8B90000D8BAC621D8BB0000FB
-:1002F000D8BCC622D8BD00CED8BEC623D8BF007F8A
-:10030000D8C0C624D8C10032D8C2C625D8C3000080
-:10031000D8C4C627D8C50000D8C6C628D8C700008C
-:10032000D8C8C62CD8C90000D8CA0000D8CB2641EE
-:10033000D8CC3021D8CD1001D8CEC502D8CF53ACFF
-:10034000D8D0C503D8D12CD3D8D2C600D8D32A6EE2
-:10035000D8D4C601D8D52A2CD8D6C605D8D7555753
-:10036000D8D8C60CD8D95400D8DAC710D8DB0700C3
-:10037000D8DCC711D8DD0F06D8DEC718D8DF0700D4
-:10038000D8E0C719D8E10F06D8E2C720D8E3470064
-:10039000D8E4C721D8E50F06D8E6C728D8E7070074
-:1003A000D8E8C729D8E91207D8EAC801D8EB7F50A6
-:1003B000D8ECC802D8ED7760D8EEC803D8EF7FCE6E
-:1003C000D8F0C804D8F1520ED8F2C805D8F35C11A1
-:1003D000D8F4C806D8F53C51D8F6C807D8F740611C
-:1003E000D8F8C808D8F949C1D8FAC809D8FB3840A4
-:1003F000D8FCC80AD8FD0000D8FEC821D8FF0002EA
-:10040000D900C822D9010046D902C844D903182FFF
-:10041000D904C013D905F341D906C084D9070030E7
-:10042000D908C904D9091401D90ACB0CD90B000485
-:10043000D90CCB0ED90DA00AD90ECB0FD90FC0C045
-:10044000D910CB10D911C0C0D912CB11D91300A02B
-:10045000D914CB12D9150007D916C241D917A0005B
-:10046000D918C243D9197FE0D91AC604D91B000E86
-:10047000D91CC609D91D00F5D91EC611D91F000EF9
-:10048000D920C660D9219600D922C687D923000475
-:10049000D924C60AD92504F5D9260000D927264132
-:1004A000D9283021D9291001D92AC620D92B14E501
-:1004B000D92CC621D92DC53DD92EC622D92F3CBE57
-:1004C000D930C623D9314452D932C624D933C5C50F
-:1004D000D934C625D935E01ED936C627D93700000C
-:1004E000D938C628D9390000D93AC62CD93B0000E2
-:1004F000D93C0000D93D2B84D93E3C74D93F6435AA
-:10050000D940DFF4D9416435D9422806D9433006B1
-:10051000D9448565D9452B24D9463C24D94764362E
-:10052000D9481002D9492B24D94A3C24D94B6436E6
-:10053000D94C4045D94D8656D94E5663D94F030202
-:10054000D950401ED9511002D9522807D95331A78A
-:10055000D95420C4D9553C24D9566724D957100200
-:10056000D9582807D9593187D95A20C4D95B3C2496
-:10057000D95C6724D95D1002D95E24F4D95F3C644C
-:10058000D9606436D961DFF4D9626436D963100268
-:10059000D9642006D9653D76D966C161D9676134D1
-:1005A000D9686135D9695443D96A0303D96B652485
-:1005B000D96C00FBD96D1002D96E20D4D96F3C24C0
-:1005C000D9702025D9713005D9726524D9731002EC
-:1005D000D974D019D9752104D9763C24D97721054D
-:1005E000D9783805D9796524D97ADFF4D97B4005E3
-:1005F000D97C6524D97D2E8DD97E303DD97F2408C4
-:10060000D98035D8D9815DD3D9820307D98388872A
-:10061000D98463A7D9858887D98663A7D987DFFD61
-:10062000D98800F9D9891002D98A0000878C30D97D
-:00000001FF
--- zfcpdump-kernel-4.4.orig/firmware/cxgb3/t3b_psram-1.1.0.bin.ihex
+++ /dev/null
@@ -1,162 +0,0 @@
-:10000000FFFFFFFC000000000000000300000000F4
-:1000100000010100FFFFFFFC0000000000000003E2
-:100020000000000000000000FFFFFFFC00000000D7
-:10003000000000030000000000000000FFFFFFFCC4
-:1000400000000000000000030000000000000000AD
-:10005000FFFFFFFC000000000000000300000000A4
-:1000600000000000FFFFFFFC000000000000000394
-:100070000000000000000000FFFFFFFC0000000087
-:10008000000000030000000000000000FFFFFFFC74
-:10009000000000000000000300000000000000005D
-:1000A000FFFFFFFC00000000000000030000000054
-:1000B00000000000FFFFFFFC000000000000000344
-:1000C0000000000000000000FFFFFFFC0000000037
-:1000D000000000030000000000000000FFFFFFFC24
-:1000E000000000000000000300000000000000000D
-:1000F000FFFFFFFC00000000000000030000000004
-:1001000000000000FFFFFFFC0000000000000003F3
-:100110000000000000000000FFFFFFFBD03403E6FA
-:1001200080262A430000000000000000FFFFFFF8C7
-:10013000007000000000000200000081C604000002
-:10014000FFFFFFFC000000000000000300000000B3
-:1001500000000000FFFFFFFC0000000000000003A3
-:100160000000000000000000FFFFFFFC0000000096
-:10017000000000030000000000000000FFFFFFFC83
-:10018000000000000000000300000000000000006C
-:10019000FFFFFFFC00000000000000030000000063
-:1001A00000000000FFFFFFFC000000000000000353
-:1001B0000000000000000000FFFFFFFBD03403E25E
-:1001C000802829230000000000000000FFFFFFF846
-:1001D0000600023701C5C00013940481C6057000F3
-:1001E000FFFFFFF88200020637030803000000004B
-:1001F00000000000FFFFFFFC000000000000000204
-:10020000208000818DF40000FFFFFFFC0000000053
-:10021000000000030000000000000000FFFFFFFCE2
-:1002200000000000000000030000000000000000CB
-:10023000FFFFFFFC000000000000000300000000C2
-:1002400000000000FFFFFFFC0000000000000003B2
-:100250000000000000000000FFFFFFF9C4310000B3
-:1002600000282C830000000000000000FFFFFFF0CA
-:100270004E70021D00C5C00000000001C118000042
-:10028000FFFFFFFC00000000000000030000000072
-:1002900000000000FFFFFFFC000000000000000362
-:1002A0000000000000000000FFFFFFFC0000000055
-:1002B000000000030000000000000000FFFFFFFC42
-:1002C000000000000000000300000000000000002B
-:1002D000FFFFFFFC00000000000000030000000022
-:1002E00000000000FFFFFFFC000000000000000312
-:1002F0000000000000000000FFFFFFF1C00003E667
-:10030000802828230000000000000000FFFFFFFC01
-:1003100000000000000000021394040000017000BF
-:10032000FFFFFFFC000000000000000300000000D1
-:1003300000000000FFFFFFFC0000000000000003C1
-:100340000000000000000000FFFFFFFC00000000B4
-:10035000000000030000000000000000FFFFFFFCA1
-:10036000000000000000000300000000000000008A
-:10037000FFFFFFFC00000000000000030000000081
-:1003800000000000FFFFFFFC000000000000000371
-:100390000000000000000000FFFFFFFA103400041E
-:1003A000000001030000000000000000FFFFFFF05C
-:1003B0006000000620030802700000F080259A907B
-:1003C000FFFFFFFC00000000000000030000000031
-:1003D00000000000FFFFFFFC000000000000000321
-:1003E0000000000000000000FFFFFFFC0000000014
-:1003F000000000030000000000000000FFFFFFFC01
-:1004000000000000000000030000000000000000E9
-:10041000FFFFFFF1C83102060A000242000000811E
-:1004200080000000FFFFFFF9C83103C60A962A4288
-:100430000000008180000000FFFFFFF00431000495
-:10044000000004030000000000000000FFFFFFF0B8
-:1004500020B000000000000213940401C1197000D4
-:10046000FFFFFFFC00000000000000000000000192
-:1004700000001000FFFFFFFC000000000000000370
-:100480000000000000000000FFFFFFFC0000000073
-:10049000000000030000000000000000FFFFFFFC60
-:1004A0000000000000000003000000000000000049
-:1004B000FFFFFFF00000000400004000680C200176
-:1004C00000001090FFFFFFF9C031C3E600266A402C
-:1004D0000000000100001000FFFFFFFA10F4000010
-:1004E000000002430000000000000000FFFFFFF8D2
-:1004F0006050080000000000700C20F080259A90E9
-:10050000FFFFFFF0060000000100400000000001B6
-:1005100000001000FFFFFFFC0000000000000002D0
-:10052000288C108085C01000FFFFFFFC0000000039
-:10053000000000030000000000000000FFFFFFFCBF
-:1005400000000000000000030000000000000000A8
-:10055000FFFFFFFC0000000000000003000000009F
-:1005600000000000FFFFFFFC00000000000000038F
-:100570000000000000000000FFFFFFF04E00000040
-:10058000000000030000000000000000FFFFFFF17A
-:10059000C00002DE00061A40000000829035C00054
-:1005A000FFFFFFFC0000000000000003000000004F
-:1005B00000000000FFFFFFFC00000000000000033F
-:1005C0000000000000000000FFFFFFFC0000000032
-:1005D000000000030000000000000000FFFFFFFC1F
-:1005E0000000000000000003000000000000000008
-:1005F000FFFFFFFC000000000000000300000000FF
-:1006000000000000FFFFFFF1CA31C3C20A966A432F
-:100610000000000000000000FFFFFFF84E501439FA
-:100620001CC5C0030000000000000000FFFFFFF039
-:100630000000000000000002288C108085C010001F
-:10064000FFFFFFFC000000000000000300000000AE
-:1006500000000000FFFFFFFC00000000000000039E
-:100660000000000000000000FFFFFFFC0000000091
-:10067000000000030000000000000000FFFFFFFC7E
-:100680000000000000000003000000000000000067
-:10069000FFFFFFFC0000000000000003000000005E
-:1006A00000000000FFFFFFF3CA3323D60E966A4313
-:1006B0000000000000000000FFFFFFF8000004063B
-:1006C00020D002430000000000000000FFFFFFF800
-:1006D00000D0000000000000000000839031C00046
-:1006E000FFFFFFFC0000000000000003000000000E
-:1006F00000000000FFFFFFFC0000000000000003FE
-:100700000000000000000000FFFFFFFC00000000F0
-:10071000000000030000000000000000FFFFFFFCDD
-:1007200000000000000000030000000000000000C6
-:10073000FFFFFFFC000000000000000300000000BD
-:1007400000000000FFFFFFF3CA33E3D60E966A43B2
-:100750000000000000000000FFFFFFF000501A1032
-:10076000003002430000000000000000FFFFFFF81F
-:100770000000020620030800700000F990118A9022
-:10078000FFFFFFFC0000000000000003000000006D
-:1007900000000000FFFFFFFC00000000000000035D
-:1007A0000000000000000000FFFFFFFC0000000050
-:1007B000000000030000000000000000FFFFFFFC3D
-:1007C0000000000000000003000000000000000026
-:1007D000FFFFFFFC0000000000000003000000001D
-:1007E00000000000FFFFFFFC00000000000000030D
-:1007F0000000000000000000FFFFFFF9C0501BA632
-:1008000000D202430000000000000000FFFFFFF0E4
-:100810004000020700100002700000E890344A9087
-:10082000FFFFFFFC000000000000000300000000CC
-:1008300000000000FFFFFFFC0000000000000003BC
-:100840000000000000000000FFFFFFFC00000000AF
-:10085000000000030000000000000000FFFFFFFC9C
-:100860000000000000000003000000000000000085
-:10087000FFFFFFFC0000000000000003000000007C
-:1008800000000000FFFFFFFC00000000000000036C
-:100890000000000000000000FFFFFFFA10F4020853
-:1008A00000C002430000000000000000FFFFFFF056
-:1008B0000000000000000000728CC8D893891090DE
-:1008C000FFFFFFF082900000030000030000000023
-:1008D00000000000FFFFFFFC00000000000000031C
-:1008E0000000000000000000FFFFFFFC000000000F
-:1008F000000000030000000000000000FFFFFFFCFC
-:1009000000000000000000030000000000000000E4
-:10091000FFFFFFFC000000000000000300000000DB
-:1009200000000000FFFFFFFC0000000000000003CB
-:100930000000000000000000FFFFFFF000000000CA
-:10094000000000030000000000000000FFFFFFF2B5
-:1009500000000320002612430000000000000000F9
-:10096000FFFFFFF040000203101000030000000032
-:1009700000000000FFFFFFFC00000000000000037B
-:100980000000000000000000FFFFFFFC000000006E
-:10099000000000030000000000000000FFFFFFFC5B
-:1009A0000000000000000003000000000000000044
-:1009B000FFFFFFFC0000000000000003000000003B
-:1009C00000000000FFFFFFFC00000000000000032B
-:1009D0000000000000000000FFFFFFF1D03403E63C
-:1009E00080262A430000000000000000FFFFFFF205
-:1009F0000834023000C005030000000000000000C1
-:040A000070EAA57F74
-:00000001FF
--- zfcpdump-kernel-4.4.orig/firmware/cxgb3/t3c_psram-1.1.0.bin.ihex
+++ /dev/null
@@ -1,162 +0,0 @@
-:10000000FFFFFFF4000000040000000100000001F9
-:1000100000010100FFFFFFF40000000400000001E8
-:100020000000000100000000FFFFFFF400000004DA
-:10003000000000010000000100000000FFFFFFF4CD
-:1000400000000004000000010000000100000000AA
-:10005000FFFFFFF4000000040000000100000001A9
-:1000600000000000FFFFFFF400000004000000019A
-:100070000000000100000000FFFFFFF4000000048A
-:10008000000000010000000100000000FFFFFFF47D
-:10009000000000040000000100000001000000005A
-:1000A000FFFFFFF400000004000000010000000159
-:1000B00000000000FFFFFFF400000004000000014A
-:1000C0000000000100000000FFFFFFF4000000043A
-:1000D000000000010000000100000000FFFFFFF42D
-:1000E000000000040000000100000001000000000A
-:1000F000FFFFFFF400000004000000010000000109
-:1001000000000000FFFFFFF40000000400000001F9
-:100110000000000100000000FFFFFFF3D03403E205
-:1001200080262A410000000100000000FFFFFFF8C8
-:10013000007000000000000000000080C604000005
-:10014000FFFFFFF4000000040000000100000001B8
-:1001500000000000FFFFFFF40000000400000001A9
-:100160000000000100000000FFFFFFF40000000499
-:10017000000000010000000100000000FFFFFFF48C
-:100180000000000400000001000000010000000069
-:10019000FFFFFFF400000004000000010000000168
-:1001A00000000000FFFFFFF4000000040000000159
-:1001B0000000000100000000FFFFFFFBD03403E25D
-:1001C000802829210000000100000000FFFFFFF847
-:1001D0000600023701C5C00213940480C6057000F2
-:1001E000FFFFFFF88200020637030801000000014C
-:1001F00000000000FFFFFFF400000004000000000A
-:10020000208000808DF40000FFFFFFF40000000458
-:10021000000000010000000100000000FFFFFFF4EB
-:1002200000000004000000010000000100000000C8
-:10023000FFFFFFF4000000040000000100000001C7
-:1002400000000000FFFFFFF40000000400000001B8
-:100250000000000100000000FFFFFFF9C4310000B2
-:1002600000282C810000000100000000FFFFFFF0CB
-:100270004E70021D00C5C00200000000C118000041
-:10028000FFFFFFF400000004000000010000000177
-:1002900000000000FFFFFFF4000000040000000168
-:1002A0000000000100000000FFFFFFF40000000458
-:1002B000000000010000000100000000FFFFFFF44B
-:1002C0000000000400000001000000010000000028
-:1002D000FFFFFFF400000004000000010000000127
-:1002E00000000000FFFFFFF4000000040000000118
-:1002F0000000000100000000FFFFFFF1C00003E666
-:10030000802828210000000100000000FFFFFFF40A
-:1003100000000004000000021394040000017000BB
-:10032000FFFFFFF4000000040000000100000001D6
-:1003300000000000FFFFFFF40000000400000001C7
-:100340000000000100000000FFFFFFF400000004B7
-:10035000000000010000000100000000FFFFFFF4AA
-:100360000000000400000001000000010000000087
-:10037000FFFFFFF400000004000000010000000186
-:1003800000000000FFFFFFF4000000040000000177
-:100390000000000100000000FFFFFFFA103400041D
-:1003A000000001010000000100000000FFFFFFF05D
-:1003B0006000000620030802700000F080259A907B
-:1003C000FFFFFFF400000004000000010000000136
-:1003D00000000000FFFFFFF4000000040000000127
-:1003E0000000000100000000FFFFFFF40000000417
-:1003F000000000010000000100000000FFFFFFF40A
-:1004000000000004000000010000000100000000E6
-:10041000FFFFFFF9C83102020A000242000000811A
-:1004200080000000FFFFFFF1C83103C20A962A4294
-:100430000000008180000000FFFFFFF00431000495
-:10044000000004010000000100000000FFFFFFF8B1
-:1004500020B000040000000013940400C1197000D3
-:10046000FFFFFFF400000004000000020000000095
-:1004700000001000FFFFFFF4000000040000000176
-:100480000000000100000000FFFFFFF40000000476
-:10049000000000010000000100000000FFFFFFF469
-:1004A0000000000400000001000000010000000046
-:1004B000FFFFFFF80000000000004000680C200172
-:1004C00000001090FFFFFFF9C031C3E600266A422A
-:1004D0000000000000001000FFFFFFF210F4000415
-:1004E000000002410000000100000000FFFFFFF0DB
-:1004F0006050080400000002700C20F180259A90E2
-:10050000FFFFFFF8060000040100400200000000A9
-:1005100000001000FFFFFFF40000000400000002D4
-:10052000288C108085C01000FFFFFFF4000000043D
-:10053000000000010000000100000000FFFFFFF4C8
-:1005400000000004000000010000000100000000A5
-:10055000FFFFFFF4000000040000000100000001A4
-:1005600000000000FFFFFFF4000000040000000195
-:100570000000000100000000FFFFFFF04E0000003F
-:10058000000000010000000100000000FFFFFFF973
-:10059000C00002DA00061A42000000839035C00055
-:1005A000FFFFFFF400000004000000010000000154
-:1005B00000000000FFFFFFF4000000040000000145
-:1005C0000000000100000000FFFFFFF40000000435
-:1005D000000000010000000100000000FFFFFFF428
-:1005E0000000000400000001000000010000000005
-:1005F000FFFFFFF400000004000000010000000104
-:1006000000000000FFFFFFF9CA31C3C60A966A4125
-:100610000000000100000000FFFFFFF84E501439F9
-:100620001CC5C0010000000100000000FFFFFFF03A
-:100630000000000000000002288C108085C010001F
-:10064000FFFFFFF4000000040000000100000001B3
-:1006500000000000FFFFFFF40000000400000001A4
-:100660000000000100000000FFFFFFF40000000494
-:10067000000000010000000100000000FFFFFFF487
-:100680000000000400000001000000010000000064
-:10069000FFFFFFF400000004000000010000000163
-:1006A00000000000FFFFFFF3CA3323D60E966A4115
-:1006B0000000000100000000FFFFFFF8000004063A
-:1006C00020D002410000000100000000FFFFFFF801
-:1006D00000D0000000000000000000839031C00046
-:1006E000FFFFFFF400000004000000010000000113
-:1006F00000000000FFFFFFF4000000040000000104
-:100700000000000100000000FFFFFFF400000004F3
-:10071000000000010000000100000000FFFFFFF4E6
-:1007200000000004000000010000000100000000C3
-:10073000FFFFFFF4000000040000000100000001C2
-:1007400000000000FFFFFFFBCA33E3D20E966A41B0
-:100750000000000100000000FFFFFFF000501A1031
-:10076000003002410000000100000000FFFFFFF028
-:100770000000020220030800700000F990118A9026
-:10078000FFFFFFF400000004000000010000000172
-:1007900000000000FFFFFFF4000000040000000163
-:1007A0000000000100000000FFFFFFF40000000453
-:1007B000000000010000000100000000FFFFFFF446
-:1007C0000000000400000001000000010000000023
-:1007D000FFFFFFF400000004000000010000000122
-:1007E00000000000FFFFFFF4000000040000000113
-:1007F0000000000100000000FFFFFFF1C0501BA23D
-:1008000000D202410000000100000000FFFFFFF8DD
-:100810004000020300100002700000E890344A908B
-:10082000FFFFFFF4000000040000000100000001D1
-:1008300000000000FFFFFFF40000000400000001C2
-:100840000000000100000000FFFFFFF400000004B2
-:10085000000000010000000100000000FFFFFFF4A5
-:100860000000000400000001000000010000000082
-:10087000FFFFFFF400000004000000010000000181
-:1008800000000000FFFFFFF4000000040000000172
-:100890000000000100000000FFFFFFFA10F4020852
-:1008A00000C002410000000100000000FFFFFFF057
-:1008B0000000000000000002728CC8D993891090DB
-:1008C000FFFFFFF082900000030000010000000124
-:1008D00000000000FFFFFFF4000000040000000122
-:1008E0000000000100000000FFFFFFF40000000412
-:1008F000000000010000000100000000FFFFFFF405
-:1009000000000004000000010000000100000000E1
-:10091000FFFFFFF4000000040000000100000001E0
-:1009200000000000FFFFFFF40000000400000001D1
-:100930000000000100000000FFFFFFF000000000C9
-:10094000000000010000000100000000FFFFFFF2B6
-:1009500000000320002612410000000100000000FA
-:10096000FFFFFFF040000203101000010000000133
-:1009700000000000FFFFFFF4000000040000000181
-:100980000000000100000000FFFFFFF40000000471
-:10099000000000010000000100000000FFFFFFF464
-:1009A0000000000400000001000000010000000041
-:1009B000FFFFFFF400000004000000010000000140
-:1009C00000000000FFFFFFF4000000040000000131
-:1009D0000000000100000000FFFFFFF9D03403E237
-:1009E00080262A410000000100000000FFFFFFF206
-:1009F0000834023000C005010000000100000000C2
-:040A000070EAA741B0
-:00000001FF
--- zfcpdump-kernel-4.4.orig/firmware/dsp56k/bootstrap.asm
+++ /dev/null
@@ -1,98 +0,0 @@
-; Author: Frederik Noring <noring@nocrew.org>
-;
-; This file is subject to the terms and conditions of the GNU General Public
-; License.  See the file COPYING in the main directory of this archive
-; for more details.
-
-; DSP56k loader
-
-; Host Interface
-M_BCR   EQU     $FFFE           ; Port A Bus Control Register
-M_PBC   EQU     $FFE0           ; Port B Control Register
-M_PBDDR EQU     $FFE2           ; Port B Data Direction Register
-M_PBD   EQU     $FFE4           ; Port B Data Register
-M_PCC   EQU     $FFE1           ; Port C Control Register
-M_PCDDR EQU     $FFE3           ; Port C Data Direction Register
-M_PCD   EQU     $FFE5           ; Port C Data Register
-
-M_HCR   EQU     $FFE8           ; Host Control Register
-M_HSR   EQU     $FFE9           ; Host Status Register
-M_HRX   EQU     $FFEB           ; Host Receive Data Register
-M_HTX   EQU     $FFEB           ; Host Transmit Data Register
-
-; SSI, Synchronous Serial Interface
-M_RX    EQU     $FFEF           ; Serial Receive Data Register
-M_TX    EQU     $FFEF           ; Serial Transmit Data Register
-M_CRA   EQU     $FFEC           ; SSI Control Register A
-M_CRB   EQU     $FFED           ; SSI Control Register B
-M_SR    EQU     $FFEE           ; SSI Status Register
-M_TSR   EQU     $FFEE           ; SSI Time Slot Register
-
-; Exception Processing
-M_IPR   EQU     $FFFF           ; Interrupt Priority Register
-
-        org     P:$0
-start   jmp     <$40
-
-        org     P:$40
-;       ; Zero 16384 DSP X and Y words
-;       clr     A #0,r0
-;       clr     B #0,r4
-;       do      #64,<_block1
-;       rep     #256
-;       move    A,X:(r0)+ B,Y:(r4)+
-;_block1        ; Zero (32768-512) Program words
-;       clr     A #512,r0
-;       do      #126,<_block2
-;       rep     #256
-;       move    A,P:(r0)+
-;_block2
-
-        ; Copy DSP program control
-        move    #real,r0
-        move    #upload,r1
-        do      #upload_end-upload,_copy
-        movem    P:(r0)+,x0
-        movem    x0,P:(r1)+
-_copy   movep   #4,X:<<M_HCR
-        movep   #$c00,X:<<M_IPR
-        and     #<$fe,mr
-        jmp     upload
-
-real
-        org     P:$7ea9
-upload
-        movep   #1,X:<<M_PBC
-        movep   #0,X:<<M_BCR
-
-next    jclr    #0,X:<<M_HSR,*
-        movep   X:<<M_HRX,A
-        move    #>3,x0
-        cmp     x0,A #>1,x0
-        jeq     <$0
-_get_address
-        jclr    #0,X:<<M_HSR,_get_address
-        movep   X:<<M_HRX,r0
-_get_length
-        jclr    #0,X:<<M_HSR,_get_length
-        movep   X:<<M_HRX,y0
-        cmp     x0,A #>2,x0
-        jeq     load_X
-        cmp     x0,A
-        jeq     load_Y
-
-load_P  do      y0,_load_P
-        jclr    #0,X:<<M_HSR,*
-        movep   X:<<M_HRX,P:(r0)+
-_load_P jmp     next
-load_X  do      y0,_load_X
-        jclr    #0,X:<<M_HSR,*
-        movep   X:<<M_HRX,X:(r0)+
-_load_X jmp     next
-load_Y  do      y0,_load_Y
-        jclr    #0,X:<<M_HSR,*
-        movep   X:<<M_HRX,Y:(r0)+
-_load_Y jmp     next
-
-upload_end
-        end
--- zfcpdump-kernel-4.4.orig/firmware/dsp56k/bootstrap.bin.ihex
+++ /dev/null
@@ -1,26 +0,0 @@
-:100000000C004000000000000000000000000000A4
-:1000100000000000000000000000000000000000E0
-:1000200000000000000000000000000000000000D0
-:1000300000000000000000000000000000000000C0
-:1000400000000000000000000000000000000000B0
-:1000500000000000000000000000000000000000A0
-:100060000000000000000000000000000000000090
-:100070000000000000000000000000000000000080
-:100080000000000000000000000000000000000070
-:100090000000000000000000000000000000000060
-:1000A0000000000000000000000000000000000050
-:1000B0000000000000000000000000000000000040
-:1000C00060F40000004F61F400007EA9062E80005D
-:1000D000004707D88407598408F4A800000408F4EE
-:1000E000BF000C0000FEB80AF080007EA908F4A052
-:1000F00000000108F4BE0000000AA980007EAD08DF
-:100100004E2B44F40000000344F4450000010EA00F
-:10011000000AA980007EB508502B0AA980007EB88D
-:1001200008462B44F4450000020AF0AA007EC920CC
-:1001300000450AF0AA007ED006C600007EC60AA9C5
-:1001400080007EC408586B0AF080007EAD06C600B1
-:10015000007ECD0AA980007ECB0858AB0AF0800053
-:100160007EAD06C600007ED40AA980007ED2085863
-:07017000EB0AF080007EADF8
-:00000001FF
-/* DSP56001 bootstrap code */
--- zfcpdump-kernel-4.4.orig/firmware/edgeport/boot.H16
+++ /dev/null
@@ -1,29 +0,0 @@
-:0004000000010C0002ED
-:000200000400FFFB
-:000600000002008002000373
-:0003000B0002000BE5
-:00030013000201B82F
-:0003001B0002001BC5
-:0003002300020023B5
-:0003002B0002002BA5
-:000300330002003395
-:0003003B0002003B85
-:00030043000201BDFA
-:0003004B000201D0DF
-:000300530002012186
-:0003007B0002007B05
-:01660080007EB0007AB33FF27EF800237E00017E100012075F6920000ABE240000780575900D800375901DD2B57E0000A5D8FD75A80075B100A9D587CA291209CC1209A0F5097AA1201201E6DA29A9D0C77E00057A01F175E110A9D7F4A9D7E4A5D8F175F10075E13F75A20375A30075C00075C100A9D1B1A9D0B1A9D5D3D2AFE47E0428008DEF1B0478FA04A934D30330E0EEBE240000780563903080E3B29580DFBEB00222C0D0A920DF0FA931DF030201B575080112083380FE7508FE12083375A8007EB33FF230E04B300146C2927E2480007E1109740819B20010740E19B200042E240100A5D9ED7E2480007E1109E4D5E0FD09B2000820E00A09B2000009B2001880EB2E240100A5D9E4439030D2AA8005D2AA439034D2AFA9D1870000000000A911DF03A9D2DF7508FF120833C0D1CA02FFCA06830032D0D032C28BC2AA32750808120833A9C0B1A9C5D3A9C6D3A9D2B132CAB8750802120833E5C0540368051201EE80F5DAB832AE
-:00011BCA00001A
-:064D01E600E47AB33FF1020263CA0BCA1BCA2BCA3BCA4BCA5BCA6BCA7BCAEBC0F17EB3012BB400028019B4011630C00875F10012024D801F30C11C75F1001202DE801430C10875F1001202DE800930C00675F10012024DD0F1DAEBDA7BDA6BDA5BDA4BDA3BDA2BDA1BDA0B22C2C07EB3012BB4020712026F02026322B401FC0202A97E00007A03012B7A03012C227EB3012354606005B4401580137EB30124B4050C7508711208337EB30126F58F2275F60022BE57012928047E5701297A0F012E7A5701320202A97EEF012E7EF701327E0701324D0068217E00007EEBB0F5F3A3A5081BF46804A5B808F07AEF012E7AF701327508061208337A01F622C2C1750803120833A936E216E5F554C06807A9D7F4A927F4FC53E13F43F2880203557EB3012CB4020FA9D4E47EB0007AB3012C7AB3012B22B401397E21E67C327E13012D2C217A23012D7E00002E040134E5E37A09B00B04A5DBF6A9D4E47508701208337EB3012D7EA3012ABCAB78031203EC22020755E5E6B40865A9C4E27E01E37E11E37E31E37E21E37E51E37E41E37E71E37E61E37A0F01237A1F01277508041208337A01081208337A11081208337A21081208337A31081208337A41081208337A51081208337A61081208337A7108120833A9D4E4A9D7F4A9C6E21203C0226D007E1401027A0701327A03012D7EB3012320E70F7A23012C7A33012BBE0701296809227A33012C7A23012B7EB3012354E3232330E002D2E530E702D2E430E50630E403020755543EF5F003541FC325F09004187584FF7302056C0204600206090206240205050204C602063D02063D0206400206400206400206400206400206400206400206400206460206FA0206430206430206430206430206430206437EB30124B4062A7EB3012560567C0B7E1301267E1701277508721208337A01081208337A110812083312075F4035020294B408107508741208337EB33FF1F5F375F60122B4001C7508751208337EB33FF230E00575F302800375F30075F30075F602220207557EB30124B400357508761208337EB30128540FF5F17EB3012820E709E5E130E70D7401800BE5E130E60474018002740053F180F5F375F30075F60222020755C0F17EB30128540F42F17EB30126B400457EB30124B401247508771208337EB30128540F780553E13F80377EB3012820E70553E17F802B53E1BF8026B403177508781208337EB3012820E70543E180801143E140800C43E1C0D0F175080712083322D0F10202907EB30124B409237508791208337EB30126BEB33FF16811CAB8C0F112011DD0F1DAB850767AB33FF1806DB4050875087A1208338062B4031975087B1208337EB30126B401557EB33FF244017AB33FF28046B4011975087C1208337EB30126B401397EB33FF254FE7AB33FF2802AB4072A7EB3012560247C0B7E1301267E1701277508731208337A01081208337A110812083312078B40030202900207557EB30124B40BF675087D1208337EB301267EA301284CAB78E480DF7EB30124B40ADB75087E1208337EB3012670CFF5F375F601220207550207550207557EB30124B404207508C31208337E0400017E1701257E1801347A1C00007E47012912083F0206F4B4063A7508C11208337E5800007A5C00FE7DCA7ED701257E7801347A7C00007E7701297508C1120833C0A8C087C2AFA9D5871208D6D087D0A8404F804AB4001CC2AFA9D587120290E48DEF8DEF8DEFD5E0F7C0D1CA02FFCA06000032B409127E5701254D556805A9D2B18003A9C2B18016B40716C2AF7E0701277E170125C0D1CA18CA38CA28320202900207557EB30124B403157508C21208337E0400017E1701257E570129020294B405397508C0120833C0A8C087C2AFA9D5877E0801347A0C00007E2400FE7E3701257E47012912083FD087D0A87E0801347A0C00007E57012902029402075575080712083343E1C022C0A8C087C2AFA9D5871207CA40197E0801347A0C0000CA0BCA4912083FDA59DA0BD087D0A8C322D087D0A822C0A8C087C2AFA9D5871207CA402B7E5800007A5C00FE7F617E7801347A7C00007E770129BD7478117508C11208331208D64006D087D0A8C322D087D0A8D3227E2400FE7E347FCA0B1A50C5F07D627D757D877E347F037E1BB0BC0B50493E003E000A502D750B3A3069530002BD3850022D38BC1B50303E103E100A512D35694100020B1A30BD3850022D38BE44FFFF78057E1B900A494D44680CBE4400FF28047E4400FFC322D32234
-:00407FC00040010200CA1B010C0200007C0000010000000000000000000000000000000000000000000000000000000000000000000000000000000000F17F0000000000005D
-:1397083300CA087E01087A033FF0DA082280500B1A600B350B1A700B350B1A800B350B1A900B350B1AA00B350B1AB00B350B1AC00B350B1AD00B351B0A600B151B0A700B151B0A800B151B0A900B151B0AA00B151B0AB00B151B0AC00B151B0AD00B159E44001050AA2E440010680E7E1BC07A0BC00B140B341B4478F2227F6F7FF01BFC7C547D328008CA1BCA1BCA1BCA1B9E44001050F22E4400106806CA481B4478FA7FF689E4CA6B5ED4003F68207E8400409D8DDA6BBD873816CA797D78120900DA7940089D7868028005C2D722DA6B43903074AA39B55555745539B52AAA74A039B555557E0400409D7050062D707D076D777C317E7B007A6B000B7C0B6CA5D9F37F161B1C7E5427107E1B10BC1068061B5478F5802C6D007C207F169F107F279F207E2B007E1B10BC0178160B2C0B1CA5DBEF7CB620E0036390304D777893C2D722D2D7220004000400000604020400020104010200000000000000000202020202040008100210040208000101087E187FBD7A1C00FF0B1A00BE1014381A0A51237E1809767A1C00FF2D350B1A506008A5B802034EA0082280FE7EE87FBF7AEC00FFE0F52254C068167EE87FBE7AEC00FFE0600C1209A0F5097AA120020F0A22C295D2941219FB5390CF1219FB80F10D0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0D0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A45646765706F72742F34202D20486172647761726520446961676E6F73746963732C2052657620312E30303B20436F70797269676874203139393820496E73696465204F7574204E6574776F726B730D0A0050617373004641494C202121005061737320202020004641494C20212120000D0A4465746563742052616D3A2020202020202020202020202020202020202020000D0A52616D20546573743A20202020202020202020202020202020202020202020000D0A416464726573732062697420302D313420746573743A202020202020202020000D0A57726F746520416464726573733A2030303A0020207769746820646174613A20002C20616E6420726561643A20000D0A4F6E65206F7220626F7468206F662074686520666F6C6C6F77696E6720416464726573732062697473206C6973746564206172652073686F727465640D0A746F20736F6D657468696E673A200020616E6420000D0A44657465637420556172743A20202020202020202020202020202020202020000D0A53637261746368205061642C4669466F20456E61626C652026205253543A20000D0A0A202020556172742054657374732020202020202020202020202020202020202020506F727431202020506F727432202020506F727433202020506F7274340D0A2020202020202020202020202020202020202020202020202020202020202020202D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D000D0A506F7274204465636F6465723A2020202020202020202020202020202020202020000D0A4469676974616C204C6F6F706261636B3A20202020202020202020202020202020000D0A416E616C6F67204C6F6F706261636B3A2020202020202020202020202020202020000D0A5258442C54584420746F205254532C4354532C52492053686F72743A2020202020000D0A5258442C54584420746F204454522C4453522C43442053686F72743A2020202020000D0A5254535B4354532C52495D20746F204454522C4453522C43442053686F72743A20000D0A5254535B4354532C43445D20746F204453522C52492053686F72743A2020202020000D0A4454525B4453522C43445D20746F205254532C4354532C52492053686F72743A20000D0A44545220746F204354532C43442053686F72743A20202020202020202020202020000D0A52545320746F204354532C5249204C6F6F706261636B3A20202020202020202020000D0A52545320746F204354532C4344204C6F6F706261636B3A20202020202020202020000D0A44545220746F204453522C4344204C6F6F706261636B3A20202020202020202020000D0A0A2020204520522052204F2052202121212C204520522052204F205220212121202C204520522052204F2052202121210D0A0A446961676E6F7374696373206E6F772077696C6C20656E7465722061206465627567206C6F6F70206F6620746865206669727374206465746563746564206572726F722E000D0A0A4E6F204861726477617265206572726F72732064657465637465642E0D0A00436F7079696E6720636F64652066726F6D204D617374657220746F20536C617665277320454570726F6D202E2E2E00446F6E650D0A0A2D3E205475726E20756E6974206F66662C20646973636F6E6E656374206361626C6520616E642072756E207374616E64616C6F6E6520646961676E6F73746963732E00C2AFC209C20A75900D201702D2B54390306C007E1003120F387E680A017A6C00FF121A930B0030B4028024021B3C20091DC294D2951219FB5390CF1219FBC295D2941219FBA5D9E64390301219FB227E680A947A6C00FF121A937EE410007E40557AE9400BE47E50AA7AE9501BE4BEE94068197E680A7A7A6C00FF121A93121A083009137AE9407EE91080F87E680A757A6C00FF121A930B007E680AD87A6C00FF121A937E7800007E700E7EA4FFFF7EB4BFFF7DCB0EC47DDC5DDB6CBB7DFA5EF47FFF7A7BB00BB07DFB5EF47FFF7A7BB00BB07DFC5EF47FFF7A7BB00BB07DFD5EF47FFF7A7BB06CBB7DFA5EF47FFFBE7BB078410BB07DFB5EF47FFFBE7BB078340BB07DFC5EF47FFFBE7BB078270BB07DFD5EF47FFFBE7BB0781A0BB0BEC4FFFE78920EB4A5DF8B7E680A827A6C00FF121A938077CA5BCA6B7E680A8B7A6C00FF121A937E680B2A7A6C00FF121A930A47121AC97E680B797A6C00FF121A936C77DA6BCA6B0B700EC4BEC4FFFF78F61B700A47121AC9121A08300930DA6BDA5B6CBB7E7800007DFA5EF47FFF7A7BB07DFB5EF47FFF7A7BB07DFC5EF47FFF7A7BB07DFD5EF47FFF7A7BB080D47E680AB67A6C00FF121A9330170E7E7804207A7C00007E447BE0800C7E7800007A7C00017E4480000B007E403A7C547F577D846C667A5B500B5C0B50A5DE020B501B8478F07C547F577D846C66BE5B50781A0B5C0B50A5DE020B501B8478EE7E680A757A6C00FF121A93804B7F457E680A7A7A6C00FF121A937E680AFA7A6C00FF121A937D4B121AC97E680B0F7A6C00FF121A936C887C95121AC97E680B1D7A6C00FF121A937E4B90121AC9121A083009057E4B9080FB7E680B7F7A6C00FF121A930B00D2927E24800009B20008BEB001780B09B20014BEB060780280177E680A7A7A6C00FF121A93121A0830091109B2000880FA7E680A757A6C00FF121A937E680BA17A6C00FF121A930B00C2921219EE7E2480007EA05519A2001C7EB00119B2000809B2001CBCAB783709B200085EB0C0BEB0C0782B7EA0AA19A2001C6CBB19B2000809B2001CBCAB781609B200085EB0C0780D7E680A757A6C00FF121A93801B7E680A7A7A6C00FF121A93121A0830090A19A2001C09B2001C80F67E680BC37A6C00FF121A937E680C457A6C00FF121A937E2480007E11097EB00119B2001C2E2401000BB0A5D9F37E2480007E11097EB0010B0009A2001CBCAB78167E680A827A6C00FF121A932E2401000BB0A5D9E280257E680A8B7A6C00FF121A93121A083009E47E2480007E110909A2001C2E240100A5D9F580EC7E680C697A6C00FF121A9312138A7E2480007E11090B00741019B200101213032E240100A5D9EE7E680C8D7A6C00FF121A937E2480007E11090B00E419B200101213032E240100A5D9EF3000030218B70213BB740719B200081219FB09B2000009B2001409B2000009B2001409B2000009B2001409B2000009B20014C20B7EB0551213647EB0AA1213647EB0001213647EB0FF121364300B0F7E680A8B7A6C00FF121A93121A08227E680A827A6C00FF121A932219B200001219EE09A20000BCAB780122200903D20B22121A0819B200001219EE09A2000080F3D2921219EEC2921219EE7E2480007E1109748019B2000C7E54000219A2000419B20000740319B2000C2E240100A5D9E1227E680CB17A6C00FF121A937E2480007E11090B001219EE09B200187EA05519A200001219EE09B200185EB005780D7E680A827A6C00FF121A93801A7E680A8B7A6C00FF121A93121A0830090919A200001219EE80F72E240100A5D9B67E680CD57A6C00FF121A937E2480007E11090B001219EE09B200187EA05519A200001219EE09B200185EB00A780D7E680A827A6C00FF121A93801A7E680A8B7A6C00FF121A93121A0830090919A200001219EE80F72E240100A5D9B630040302168C7E680CF97A6C00FF121A937E2480007E11090B006CAA19A200101219EE09B200187EA00219A200106CAA19A200101219EE09B200185EB00A783C7EA00119A200101219EE09B200187EA00319A200107EA00119A200101219EE09B200185EB00A78147E680A827A6C00FF121A932E240100A5D99E80207E680A8B7A6C00FF121A93121A083009E67EA00219A200106CAA19A2001080F17E680D417A6C00FF121A937E2480007E11090B006CAA19A200101219EE09B200187EA00119A200106CAA19A200101219EE09B200185EB005783C7EA00219A200101219EE09B200187EA00319A200107EA00219A200101219EE09B200185EB00578147E680A827A6C00FF121A932E240100A5D99E80207E680A8B7A6C00FF121A93121A083009E67EA00119A200106CAA19A2001080F17E680D897A6C00FF121A937E2480007E11090B007EA00219A200101219EE09B200185EB050BEB050781F6CAA19A200101219EE09B200185EB050780D7E680A827A6C00FF121A9380207E680A8B7A6C00FF121A93121A0830090F7EA00219A200106CAA19A2001080F12E240100A5D9A27E680DD17A6C00FF121A937E2480007E11090B0009B200187EA00119A200101219EE09B200185EB0A0BEB0A0781F6CAA19A200101219EE09B200185EB0A0780D7E680A827A6C00FF121A9380207E680A8B7A6C00FF121A93121A0830090F7EA00119A200106CAA19A2001080F12E240100A5D99E02182B7E680D1D7A6C00FF121A937E2480007E11090B006CAA19A200101219EE09B200187EA00219A200106CAA19A200101219EE09B200185EB006783C7EA00119A200101219EE09B200187EA00319A200107EA00119A200101219EE09B200185EB00678147E680A827A6C00FF121A932E240100A5D99E80207E680A8B7A6C00FF121A93121A083009E67EA00219A200106CAA19A2001080F17E680D657A6C00FF121A937E2480007E11090B006CAA19A200101219EE09B200187EA00119A200106CAA19A200101219EE09B200185EB009783C7EA00219A200101219EE09B200187EA00319A200107EA00219A200101219EE09B200185EB00978147E680A827A6C00FF121A932E240100A5D99E80207E680A8B7A6C00FF121A93121A083009E67EA00119A200106CAA19A2001080F17E680DAD7A6C00FF121A937E2480007E11090B007EA00219A200101219EE09B200185EB090BEB090781F6CAA19A200101219EE09B200185EB090780D7E680A827A6C00FF121A9380207E680A8B7A6C00FF121A93121A0830090F7EA00219A200106CAA19A2001080F12E240100A5D9A20218B730170302193BC28A1219227E2480007E11096CAA19A200041219EE0B007EA00819A200101219EE208B3E20893B7EA00819A2000409A200104EA00219A200101219EE308B2330892009A200105EA0FD19A200101219EE7EA00019A200041219EE208B05208902801A121A083009147EA00219A2001000005EA0FD19A20010000080EC2E240100A5D98902193B2017FA12138A1219227E2480007E11090B002089267EA0FF19A200041219EE7EB05519B200001219EE30890F7EA00019A200041219EE2089028026121A083009207EA0FF19A200041219EE7EB05519B200001219EE7EA00019A200041219EE80E02E240100A5D9A802193B7E2480007E11097EA00819A200101219EE2E240100A5D9EF22300A197E680DF57A6C00FF121A93D2091219EE1219EE1219EE020F1030171C7E680E6F7A6C00FF121A937E680E917A6C00FF121A93121B3C0219E60B007E7819A07A7C00FF7F677A6C00007E703E7E7BB07A6BB00B7C0B6CA5DFF37E7819A07A7C000089787E7800007A7C00FE7E687FBF7A6C00FE74AA39B75555745539B72AAA74A039B755556C997A6B907E5427107E6B80BC8968081B5478F58AFF19DE8AFF19E6121A087E6B8080FB7E10FF121A8580F8CAF97EF400FF1BF478FCDAF922CAF97EF400001BF478FCDAF922200919D20A1219FBC295D2941219FB1219FB1219FB1219FB43903022CA0B7E10037C306C220B209E300A50F92E300B1B2068181219FB1219FB5390CF1219FB1219FB1219FB439030A5DAE81219FB1219FB1B3068191219FB1219FBC295D2941219FB1219FB1219FB439030A5DBE77E200A1219FBA5DAFAA5D9A7DA0B2220090A1219FBB2941219FBB2942230173220092FCA2BCA7B7E7880007A7C00FE121B1C7E6BA05CAA681029B70014546068F839A700000B6C80E91219EED2B5DA7BDA2B22121AD47E68000B121A9322CA59CA5B7EB4000B7CB8C4121B047CB8121B047CB9C4121B047CB9121B047EB0687AB9B00BB46CBB7AB9B0DA59DA5B225EB00F7CAB9EA00A40052EB03780032EB0307AB9B00BB422C2B5C2921219EE748039B7000C7E54000639A7000439B70000740339B7000C227E7800007A7C00FF7E5800007A5C00017F657E7420001208D640547E787C007A7C00FF7E5800007A5C00017E687C007A6C00017E7404001208D640337480121BB1402C5390CFD2087E0400087E14000084A5DBFCA5DAF9A5D9F67440121BB1400E7E680EC07A6C00FF121A930219E6C295D29480FEF50A7E78000A7A7C00007E687FBF7A6C00017E7400010208D6D2
-:0000000001FF
-//**************************************************************
-//* Edgeport/4 Binary Image
-//* Generated by HEX2C v1.06
-//* Copyright (C) 1998 Inside Out Networks, All rights reserved.
-//*	This program is free software; you can redistribute it and/or modify
-//*	it under the terms of the GNU General Public License as published by
-//*	the Free Software Foundation; either version 2 of the License, or
-//*	(at your option) any later version.
-//**************************************************************
--- zfcpdump-kernel-4.4.orig/firmware/edgeport/boot2.H16
+++ /dev/null
@@ -1,28 +0,0 @@
-:000400000002000003F7
-:000200000400FFFB
-:000600000002008002000373
-:0003000B0002000BE5
-:000300130002025690
-:0003001B0002001BC5
-:0003002300020023B5
-:0003002B0002002BA5
-:000300330002003395
-:0003003B0002003B85
-:000300430002004375
-:0003004B0002004B65
-:00030053000201F5B2
-:0003007B0002007B05
-:02160080007EB3910120E30C7EB33FF254FE7AB33FF2800A7EB33FF244017AB33FF274007AB3910074017AB391127EF800247E00017E10001209D06920000A5E401FBE24000078097E00037A03900080077E00027A03900075B0DF7E00017A0394007A0301247E00017A0393007E0000A5D8FD75A80075B100CA29120C66120C37F5217AA120200908200A0A7EB00C80087EB00080037EB0087AB39200120296DA2974107AB391017E20047CB2C2D7131313137AB3910074007AB3911074607AB3911C74027AB39112A5DADF74007AB3910074607AB3911C74107AB3910674107AB3910774347AB39113743F7AB3911474027AB3910674017AB3910774037AB3910674447AB3910774EF7AB3910474077AB391067EB391077AB10A750901D2AAD2AFE47E60024D2278037E60037C767E0428008DEF1B0478FA047E20077A2391067E2391077E310ABC3268227A210A7E21096817CAB874037AB391067EB3910744027AB39107DAB875090030E0C16C677A63900080B9BEB00222C0D07508FE120AC074027AB3910674007AB3910774037AB3910674007AB3910774027AB391047EB33FF230E00874187AB39101800674107AB3910174107AB391040202367508FF120AC074017AB3910474037AB391067EB3910754FC7AB3910732CAB8750802120AC07EB3910320E50830E02B12029E80F17EB3910430E005DAB802023930E105DAB80201F530E60512040380D530E205DAB802008080CBDAB8326D
-:082A029600E47AB33FF1020341CA0BCA1BCA2BCA3BCA4BCA5BCA6BCA7BCAEB74007AB391007EB3012EB40002801CB401197EB391145414680512030580237EB3911430E51C12044380177EB3911430E505120443800B7EB3911454146803120305DAEBDA7BDA6BDA5BDA4BDA3BDA2BDA1BDA0B2220E41975080A120AC07EB3012D700A7EB3012EB4011F02039D02098B75080B120AC074147AB391147EB3012EB4020C12034D02034174047AB39114227E00007A03012E7A03012F227EB3012554606005B4401E801C7EB30126B40515750871120AC07EB301287EA0017AA391067AB391072274007AB3910074107AB3911222BE57012B28047E57012B7A0F01317A57013574107AB391122274007AB391007EB3911A70537EB3911420E44C7EEF01317EF701357E0701354D0068217E0000E07AB39117A3A5081BF46806A5B810F080197EB0007AB3012EBE0010680D7EB0007AB3012E74807AB3911E7AEF01317AF70135750806120AC074047AB3911422CA0BCA1BCA2BCA3BCA4BCA5BCA6BCA7BCAEB750803120AC074007AB3012D74007AB3910074017AB391121204B2DAEBDA7BDA6BDA5BDA4BDA3BDA2BDA1BDA0B22750803120AC07EB3012FB4021174007AB3012F7AB3012E74207AB3911422B401467EB3910420E6427E23911A7C327E1301302C217A2301307E00002E0401377EB391167A09B00B04A5DBF474207AB39114750870120AC07EB301307EA3012CBCAB78031205522202098BDA5902041574E07AB391007E0391107E1391117E3391127E2391137E5391147E4391157E7391167E6391177A0F01257A1F0129750804120AC07A0108120AC07A1108120AC07A2108120AC07A3108120AC07A4108120AC07A5108120AC07A6108120AC07A7108120AC074007AB3910074407AB39104120526226D007E1401027A0701357A0301307EB3012520E70F7A23012F7A33012EBE07012B6809227A33012F7A23012E7EB3012554E3232330E002D2E530E702D2E430E50630E40302098B543EF5F003541FC325F090057E7584FF730207390205C60207D20207ED0206D002065B02081E02081E0208210208210208210208210208210208210208210208210208270208F902082402082402082402082402082402082474007AB3910074607AB3911C7EB30126B4062A7EB3012760797C0B7E1301287E170129750872120AC07A0108120AC07A1108120AC01209D04058020384B4081C750874120AC07EB33FF17E0801377A0C00007A0BB07E540001020384B40033750875120AC07E0801377A0C0000CA0B7EB33FF230E00774027A0BB0800574007A0BB00B1474007A0BB07E540002DA0B02038402098B74007AB3910074607AB3911C7EB30126B4005F750876120AC07EB3012A540FB402057EB0608017B400057EB000800F7EB3012A20E7057EB04080037EB0207AB391007EB3911130E0047401800274007E0801377A0C0000CA0B7A0BB00B1474007A0BB074007AB391007E540002DA0B02038402098B7EB3012A540FB402057EB0608017B400057EB000800F7EB3012A20E7057EB04080037EB0207AB391007EB30128B400267EB30126B4010E750877120AC074017AB39112801BB4030E750878120AC074017AB39111800A74007AB3910012098B2274007AB391000203777EB30126B4091F750879120AC07EB30128BEB33FF1680DCAB81201F1DAB850767AB33FF1806DB4050875087A120AC08062B4031975087B120AC07EB30128B401557EB33FF244017AB33FF28046B4011975087C120AC07EB30128B401397EB33FF254FE7AB33FF2802AB4072A7EB3012760247C0B7E1301287E170129750873120AC07A0108120AC07A1108120AC0120A0A400302037702098B7EB30126B40BF675087D120AC07EB301287EA3012A4CAB78E480DF74007AB3910074607AB3911C7EB30126B40ACF75087E120AC07EB3012870C37E0801377A0C00007A0BB07E54000102038402098B02098B02098B7EB30126B404207508C3120AC07E0400017E1701277E1801377A1C00007E47012B120ACC0208F3B406427508C1120AC07E5800007A5C00FE7DCA7ED701277E7801377A7C00007E77012B7508C1120AC0C0A8C2AF7E40017A439400120B637E4301247A439400D0A840658060B40024C2AF7EB0017AB394007AB30124120377E48DEF8DEF8DEFD5E0F7C0D1CA02FFCA06000032B4092074037AB391067E2391077E5701274D5568054E200280035E20FD7A2391078016B40716C2AF7E0701297E170127C0D1CA18CA38CA283202037702098B74007AB3910074607AB3911C7EB30126B403157508C2120AC07E0400017E1701277E57012B020384B405417508C0120AC0C0A8C2AF7E40017A4394007E0801377A0C00007E2400FE7E3701277E47012B120ACC7E4301247A439400D0A87E0801377A0C00007E57012B020384B401207E00007E1001750872120AC07A0108120AC07A1108120AC01209D0400302038402098B750807120AC07EB0027AB3900074007AB3910074407AB3911574017AB391117EB391155460BEB040680874207AB3911580ED74017AB3911274047AB3911474FF7AB3012D22C0A8C2AF7E40017A439400120A57401F7E0801377A0C0000CA0BCA49120ACCDA59DA0B7E4301247A439400D0A8C3227E4301247A439400D0A822C0A8C2AF7E40017A439400120A5740317E5800007A5C00FE7F617E7801377A7C00007E77012BBD7478177508C1120AC0120B63400C7E4301247A439400D0A8C3227E4301247A439400D0A8D3227E2400FE7E347FCA0B1A50C5F07D627D757D877E347F037E1BB0BC0B50493E003E000A502D750B3A3069530002BD3850022D38BC1B50303E103E100A512D35694100020B1A30BD3850022D38BE44FFFF78057E1B900A494D44680CBE4400FF28047E4400FFC322D32248
-:00407FC00040010200D73102000300007C0000010000000000000000000000000000000000000000000000000000000000000000000000000000000000F17F00000000000044
-:10430AC000CA087E01087A033FF0DA082280500B1A600B350B1A700B350B1A800B350B1A900B350B1AA00B350B1AB00B350B1AC00B350B1AD00B351B0A600B151B0A700B151B0A800B151B0A900B151B0AA00B151B0AB00B151B0AC00B151B0AD00B159E44001050AA2E440010680E7E1BC07A0BC00B140B341B4478F2227F6F7FF01BFC7C547D328008CA1BCA1BCA1BCA1B9E44001050F22E4400106806CA481B4478FA7FF689E4CA6B5ED4003F68207E8400409D8DDA6BBD873816CA797D78120B8DDA7940089D7868028005C2D722DA6B7EC0037ED0007AD3900074AA39B55555745539B52AAA74A039B555557E0400409D7050062D707D076D777C317E7B007A6B000B7C0B6CA5D9F37F161B1C7E5427107E1B10BC1068061B5478F5802F6D007C207F169F107F279F207E2B007E1B10BC0178190B2C0B1CA5DBEF7CB620E0066CDC7AD390004D777890C2D722D2D7220004000400000604020400020104010200000000000000000202020202040008100210040208000101087E187FBD7A1C00FF0B1A005E101FBE1014381A0A51237E180C0D7A1C00FF2D350B1A506008A5B802034EA0082280FE7EE87FBF7AEC00FFE0F52354C068387EE87FBE7AEC00FFE0602E120C37F5217AA12020090C200A127EB00E7AB3920080107EB0027AB3920080077EB00A7AB392007AB10D020CC4227EB0027AB3900012190C7EB0037AB3900012190C80EAC2AFC211C21275B0DF7E00017A0393007E00007A0390006C007E1003120CF57E682C667A6C00FF1219C40B008032021A6E20112B7EB0017AB3900012190C7EB0037AB3900012190C7EB0027AB3900012190CA5D9DC7EB0007AB3900012190C227E682CF97A6C00FF1219C47EE410007E40557AE9400BE47E50AA7AE9501BE4BEE94068197E682CDF7A6C00FF1219C41219193011137AE9407EE91080F87E682CDA7A6C00FF1219C40B007E682D3D7A6C00FF1219C47E7800007E700E7EA4FFFF7EB4BFFF7DCB0EC47DDC5DDB6CBB7DFA5EF47FFF7A7BB00BB07DFB5EF47FFF7A7BB00BB07DFC5EF47FFF7A7BB00BB07DFD5EF47FFF7A7BB06CBB7DFA5EF47FFFBE7BB078410BB07DFB5EF47FFFBE7BB078340BB07DFC5EF47FFFBE7BB078270BB07DFD5EF47FFFBE7BB0781A0BB0BEC4FFFE78920EB4A5DF8B7E682CE77A6C00FF1219C48077CA5BCA6B7E682CF07A6C00FF1219C47E682D8F7A6C00FF1219C40A471219FA7E682DDE7A6C00FF1219C46C77DA6BCA6B0B700EC4BEC4FFFF78F61B700A471219FA121919301130DA6BDA5B6CBB7E7800007DFA5EF47FFF7A7BB07DFB5EF47FFF7A7BB07DFC5EF47FFF7A7BB07DFD5EF47FFF7A7BB080D47E682D1B7A6C00FF1219C4301F0E7E7804207A7C00007E447BE0800C7E7800007A7C00017E4480000B007E403A7C547F577D846C667A5B500B5C0B50A5DE020B501B8478F07C547F577D846C66BE5B50781A0B5C0B50A5DE020B501B8478EE7E682CDA7A6C00FF1219C4804B7F457E682CDF7A6C00FF1219C47E682D5F7A6C00FF1219C47D4B1219FA7E682D747A6C00FF1219C46C887C951219FA7E682D827A6C00FF1219C47E4B901219FA1219193011057E4B9080FB7E682E287A6C00FF1219C40B007EB0807AB391007EA0557AA391107EB391077EB39110BCAB78207EA0AA7AA391107EB391077EB39110BCAB780D7E682CDA7A6C00FF1219C4801B7E682CDF7A6C00FF1219C412191930110A7AA391107EB3911080F67E682E4A7A6C00FF1219C41212310B007EE410007EA0A5CAA87AE9A07EB0307AB395007EE9A07EB0007AB3950012190C0BE57EB0207AB395007EE9B07EB0007AB395007EE9B0DAA8BCAB780D7E682CDA7A6C00FF1219C4801D7E682CDF7A6C00FF1219C412191930110C7EB0387AB395007EE9B080FB80007E682DE47A6C00FF1219C40B0075B0DF7E24800009B20008BEB001780B09B20014BEB060780280177E682CDF7A6C00FF1219C412191930111109B2000880FA7E682CDA7A6C00FF1219C47E682E067A6C00FF1219C40B0075B0EF1218FF7E2480007EA05519A2001C7EB00119B2000809B2001CBCAB783709B200085EB0C0BEB0C0782B7EA0AA19A2001C6CBB19B2000809B2001CBCAB781609B200085EB0C0780D7E682CDA7A6C00FF1219C4801B7E682CDF7A6C00FF1219C412191930110A19A2001C09B2001C80F67E682E6C7A6C00FF1219C47E682EEE7A6C00FF1219C47E2480007E11217EB00119B2001C2E2401000BB0A5D9F37E2480007E11217EB0010B0009A2001CBCAB78167E682CE77A6C00FF1219C42E2401000BB0A5D9E280257E682CF07A6C00FF1219C41219193011E47E2480007E112109A2001C2E240100A5D9F580EC7E682F127A6C00FF1219C41212317E2480007E11210B00741019B200101211AA2E240100A5D9EE7E682F367A6C00FF1219C47E2480007E11210B00E419B200101211AA2E240100A5D9EF30000302173B02126A740719B2000812190C09B2000009B2001409B2000009B2001409B2000009B2001409B2000009B20014C2137EB05512120B7EB0AA12120B7EB00012120B7EB0FF12120B30130F7E682CF07A6C00FF1219C4121919227E682CE77A6C00FF1219C42219B200001218FF09A20000BCAB780122201103D2132212191919B200001218FF09A2000080F375B0DF1218FF75B0EF1218FF7E2480007E1121748019B2000C7E54000219A2000419B20000740319B2000C740619B200082E240100A5D9DB227E682F5A7A6C00FF1219C47E2480007E11210B001218FF09B200187EA05519A200001218FF09B200185EB005780D7E682CE77A6C00FF1219C4801A7E682CF07A6C00FF1219C412191930110919A200001218FF80F72E240100A5D9B67E682F7E7A6C00FF1219C47E2480007E11210B001218FF09B200187EA05519A200001218FF09B200185EB00A780D7E682CE77A6C00FF1219C4801A7E682CF07A6C00FF1219C412191930110919A200001218FF80F72E240100A5D9B630040302159F7E682FA27A6C00FF1219C47E2480007E11210B006CAA19A200101218FF09B200187EA00219A200106CAA19A200101218FF09B200185EB00A783C7EA00119A200101218FF09B200187EA00319A200107EA00119A200101218FF09B200185EB00A78147E682CE77A6C00FF1219C42E240100A5D99E80207E682CF07A6C00FF1219C41219193011E67EA00219A200106CAA19A2001080F17E682FEA7A6C00FF1219C47E2480007E11210B006CAA19A200101218FF09B200187EA00119A200106CAA19A200101218FF09B200185EB005783C7EA00219A200101218FF09B200187EA00319A200107EA00219A200101218FF09B200185EB00578147E682CE77A6C00FF1219C42E240100A5D99E80207E682CF07A6C00FF1219C41219193011E67EA00119A200106CAA19A2001080F17E6830327A6C00FF1219C47E2480007E11210B007EA00219A200101218FF09B200185EB050BEB050781F6CAA19A200101218FF09B200185EB050780D7E682CE77A6C00FF1219C480207E682CF07A6C00FF1219C412191930110F7EA00219A200106CAA19A2001080F12E240100A5D9A27E68307A7A6C00FF1219C47E2480007E11210B0009B200187EA00119A200101218FF09B200185EB0A0BEB0A0781F6CAA19A200101218FF09B200185EB0A0780D7E682CE77A6C00FF1219C480207E682CF07A6C00FF1219C412191930110F7EA00119A200106CAA19A2001080F12E240100A5D99E7E68309E7A6C00FF1219C47E2480007E11210B0020B1267EA00219A200101218FF30B1196CAA19A200101218FF20B10D7E682CE77A6C00FF1219C480207E682CF07A6C00FF1219C412191930110F7EA00219A200106CAA19A2001080F12E240100A5D9AE02173B7E682FC67A6C00FF1219C47E2480007E11210B006CAA19A200101218FF09B200187EA00219A200106CAA19A200101218FF09B200185EB006783C7EA00119A200101218FF09B200187EA00319A200107EA00119A200101218FF09B200185EB00678147E682CE77A6C00FF1219C42E240100A5D99E80207E682CF07A6C00FF1219C41219193011E67EA00219A200106CAA19A2001080F17E68300E7A6C00FF1219C47E2480007E11210B006CAA19A200101218FF09B200187EA00119A200106CAA19A200101218FF09B200185EB009783C7EA00219A200101218FF09B200187EA00319A200107EA00219A200101218FF09B200185EB00978147E682CE77A6C00FF1219C42E240100A5D99E80207E682CF07A6C00FF1219C41219193011E67EA00119A200106CAA19A2001080F17E6830567A6C00FF1219C47E2480007E11210B007EA00219A200101218FF09B200185EB090BEB090781F6CAA19A200101218FF09B200185EB090780D7E682CE77A6C00FF1219C480207E682CF07A6C00FF1219C412191930110F7EA00219A200106CAA19A2001080F12E240100A5D9A2201F681212311217A97E2480007E11210B002089267EA0FF19A200041218FF7EB05519B200001218FF30890F7EA00019A200041218FF20890280261219193011207EA0FF19A200041218FF7EB05519B200001218FF7EA00019A200041218FF80E02E240100A5D9A80217C202184C7E2480007E11217EA00819A200101218FF2E240100A5D9EF22301F0302184CC28A1217A90B00121816208B2474037AB3910674027AB39107740C7AB3910674007AB3910712190C308B06121816308BAD1219193011A712181674037AB3910674027AB3910712190C12181680E97EA00074027AB391067AA3910774037AB391067AA391071218FF74EF7AB3910474807AB39103740C7AB3910674087AB3910712190C223012197E6830C27A6C00FF1219C4D2111218FF1218FF1218FF020CCA301F1C7E68313C7A6C00FF1219C47E68315E7A6C00FF1219C4121A6E0218F70B007E7818B17A7C00FF7F677A6C00007E703E7E7BB07A6BB00B7C0B6CA5DFF37E7818B17A7C000089787E7800007A7C00FE7E687FBF7A6C00FE74AA39B75555745539B72AAA74A039B755556C997A6B907E5427107E6B80BC8968081B5478F58AFF18EF8AFF18F71219197E6B8080FB7E10FF1219AC80F8CAF97EF400FF1BF478FCDAF922CAF97EF400001BF478FCDAF922201120D21212190C7EB0027AB3900012190C12190C12190C12190C7EB0007AB3900022CA0B7E10037C306C220B209E300A50F92E300B1B20682012190C12190C7EB0037AB3900012190C12190C12190C7EB0007AB39000A5DAE012190C12190C1B30682012190C12190C7EB0027AB3900012190C12190C12190C7EB0007AB39000A5DBE07E200A12190CA5DAFAA5D998DA0B2220111412190C7EB0017AB3900012190C7EB0007AB3900022301F3220112FCA2BCA7B7E7880007A7C00FE121A4D7E6BA05CAA681029B70014546068F839A700000B6C80E91218FFD2B5DA7BDA2B22121A057E68000C1219C422CA59CA5B7EB4000C7CB8C4121A357CB8121A357CB9C4121A357CB9121A357EB0687AB9B00BB46CBB7AB9B0DA59DA5B225EB00F7CAB9EA00A40052EB03780032EB0307AB9B00BB422C2B575B0EF1218FF748039B7000C7E54000639A7000439B70000740339B7000C227E7800007A7C00FF7E5800007A5C00017F657E742000120B6340587E787C007A7C00FF7E5800007A5C00017E687C007A6C00017E740400120B6340377480121AEA40307E00037A039000D2107E0400087E14000084A5DBFCA5DAF9A5D9F67440121AEA400E7E68318D7A6C00FF1219C40218F77EB0027AB3900080FEF50B7E78000B7A7C00007E687FBF7A6C00017E740001020B6374
-:0000000001FF
-//**************************************************************
-//* Edgeport/4 Binary Image
-//* Generated by HEX2C v1.06
-//* Copyright (C) 1998 Inside Out Networks, All rights reserved.
-//*	This program is free software; you can redistribute it and/or modify
-//*	it under the terms of the GNU General Public License as published by
-//*	the Free Software Foundation; either version 2 of the License, or
-//*	(at your option) any later version.
-//**************************************************************
--- zfcpdump-kernel-4.4.orig/firmware/edgeport/down.H16
+++ /dev/null
@@ -1,29 +0,0 @@
-:000400000001100004E7
-:000200000400FFFB
-:00060000000200800244B082
-:0003000B000244723A
-:0003001300020013D5
-:0003001B0002001BC5
-:0003002300020023B5
-:0003002B0002002BA5
-:000300330002003395
-:0003003B0002003B85
-:000300430002004375
-:0003004B00026EC47E
-:000300530002758DA6
-:0003007B0002007B05
-:00070080007E14000002405154
-:088230000012372812303E1230541230E51231681235201238581231151231401230A080E0E52360197E14000009B101CFB4000280051419B101CFA50BBE312F78EB22C2AF7EB33FF1B4010AC0F175F1021270EFD0F1D2AF22C2AFE52260437E0701E1BE04038038397E0480007E200013502109A000044EA00519A000040A320953678E5E5127680B09A000104EA00119A000102E040100A50ABE212F78D1752200D2AF22C2AF7E20007E30017CB2230A2B4932018FBE34000068127EB121A54B7AB121CA19492230D59924DA193E30A50ABE212F78D6D2AF22460F49674CBF5017536F56C75A1F5D77C2AFE53260147E2000135007CAB8123102DAB8A50ABE212F78EFD2AF22CA281267ABDA2840090A2209B2678EF4523222C2AFE53460147E2000135007CAB8123132DAB8A50ABE212F78EFD2AF22CA280A220942003E1269C2DA2822C2AFE53560147E2000135007CAB812315DDAB8A50ABE212F78EFD2AF22CA287E4000126C5BDA2822C2AFE52360147E2000135007CAB8123185DAB8A50ABE212F78EFD2AF227CB2230A2B49223190892431A03210328032F0336033D0344034B07E27018FBE24000078247E24800009B20014CAB85EB01EDAB8680BCA197D121249307D21DA1930E6187E6000801EBE27019F680D7A27019F7E609C7A6301CF802E7E6301CFA5BE00267E60017EB0007EA0C81262B640187531B3127C15C2186C007A0301CFC0F175F101126FD9D0F1227E270191BE24000078247E24810009B20014CAB85EB01EDAB8680BCA197D12124C887D21DA1930E6187E6000801EBE2701A1680D7A2701A17E609C7A6301D0802E7E6301D0A5BE00267E60017EB0007EA0C81262B640187531B3127C15C2196C007A0301D0C0F175F101126FD9D0F1227E270193BE24000078247E24820009B20014CAB85EB01EDAB8680BCA197D12124FE07D21DA1930E6187E6000801EBE2701A3680D7A2701A37E609C7A6301D1802E7E6301D1A5BE00267E60017EB0007EA0C81262B640187531B3127C15C21A6C007A0301D1C0F175F101126FD9D0F1227E270195BE24000078247E24830009B20014CAB85EB01EDAB8680BCA197D121253387D21DA1930E6187E6000801EBE2701A5680D7A2701A57E609C7A6301D2802E7E6301D2A5BE00267E60017EB0007EA0C81262B640187531B3127C15C21B6C007A0301D2C0F175F101126FD9D0F1227E270197BE24000078247E24840009B20014CAB85EB01EDAB8680BCA197D121256907D21DA1930E6187E6000801EBE2701A7680D7A2701A77E609C7A6301D3802E7E6301D3A5BE00267E60017EB0007EA0C81262B640187531B3127C15C21C6C007A0301D3C0F175F101126FD9D0F1227E270199BE24000078247E24850009B20014CAB85EB01EDAB8680BCA197D121259E87D21DA1930E6187E6000801EBE2701A9680D7A2701A97E609C7A6301D4802E7E6301D4A5BE00267E60017EB0007EA0C81262B640187531B3127C15C21D6C007A0301D4C0F175F101126FD9D0F1227E27019BBE24000078247E24860009B20014CAB85EB01EDAB8680BCA197D12125D407D21DA1930E6187E6000801EBE2701AB680D7A2701AB7E609C7A6301D5802E7E6301D5A5BE00267E60017EB0007EA0C81262B640187531B3127C15C21E6C007A0301D5C0F175F101126FD9D0F1227E27019DBE24000078247E24870009B20014CAB85EB01EDAB8680BCA197D121260987D21DA1930E6187E6000801EBE2701AD680D7A2701AD7E609C7A6301D6802E7E6301D6A5BE00267E60017EB0007EA0C81262B640187531B3127C15C21F6C007A0301D6C0F175F101126FD9D0F122C2AFE52460147E2000135007CAB812353DDAB8A50ABE212F78EFD2AF227CB2230A2B4922354889243558359235CC36063640367A36B436EE7E24800009B20014CAB85EB01EDAB8680BCA197D121249307D21DA195EB0017EA09012629340127531B8127C15C220C0F175F101126FD9D0F1227E24810009B20014CAB85EB01EDAB8680BCA197D12124C887D21DA195EB0017EA09012629340127531B8127C15C221C0F175F101126FD9D0F1227E24820009B20014CAB85EB01EDAB8680BCA197D12124FE07D21DA195EB0017EA09012629340127531B8127C15C222C0F175F101126FD9D0F1227E24830009B20014CAB85EB01EDAB8680BCA197D121253387D21DA195EB0017EA09012629340127531B8127C15C223C0F175F101126FD9D0F1227E24840009B20014CAB85EB01EDAB8680BCA197D121256907D21DA195EB0017EA09012629340127531B8127C15C224C0F175F101126FD9D0F1227E24850009B20014CAB85EB01EDAB8680BCA197D121259E87D21DA195EB0017EA09012629340127531B8127C15C225C0F175F101126FD9D0F1227E24860009B20014CAB85EB01EDAB8680BCA197D12125D407D21DA195EB0017EA09012629340127531B8127C15C226C0F175F101126FD9D0F1227E24870009B20014CAB85EB01EDAB8680BCA197D121260987D21DA195EB0017EA09012629340127531B8127C15C227C0F175F101126FD9D0F122C2AFE53360147E2000135007CAB8123745DAB8A50ABE212F78EFD2AF227CB2230A2B4922375089243760377F379E37BD37DC37FB381A38397E248000CA197D1212481BDA19100402800CD201C0F175F101126FD9D0F1227E248100CA197D12124B73DA19100402800CD201C0F175F101126FD9D0F1227E248200CA197D12124ECBDA19100402800CD201C0F175F101126FD9D0F1227E248300CA197D12125223DA19100402800CD201C0F175F101126FD9D0F1227E248400CA197D1212557BDA19100402800CD201C0F175F101126FD9D0F1227E248500CA197D121258D3DA19100402800CD201C0F175F101126FD9D0F1227E248600CA197D12125C2BDA19100402800CD201C0F175F101126FD9D0F1227E248700CA197D12125F83DA19100402800CD201C0F175F101126FD9D0F122C2AFC0F175F101A932F21A7E0701E1BE0400007810E5F53382E74009853131127C1575F600D0F1D2AF2247
-:3C154000007E0400017E147FF87E2400FE7D310B1A501B0A507E14401B02406A7EF8006FD204C294D2957EF4402C02407C127D30F52F7AA1307A116E1275CA1240DC7EB33FF160031243D475F10012766FD2AF0230007E0400FF7E18405F7A1C00018918A9258703A9D587D29389087E0400FF7E1840787A1C00018918C29389087E0800207E4404007E40007EE4408E027C307E08016F7E44287C7E40007EE440A0027C307E08006F7E4401007E40537EE440B2027C30756D20756C307E040008756A58756B08756708756901758901758A01758C00D28C7E0400027A055889F475B77F75B87F75B30775B207D2A922D292E4D5E0FDC2927E2480007E112F7EA00819A200102E240100A5D9F27E200012417E0B20BE212F78F6227E0480004C0274BF19B0000C741019B00008748019B0000C7E54000219A0000419B00000740319B0000C7407A920300BA9353005BE20012802740F19B00004A933301874BF19B0000C7428A9203002742019B00004740319B0000C74A719B00008740C19B00010227E0480004C02E419B0000409B00010540819B0001074A719B00008227CB2230A2B492241A5892441B541D441F3421242314250426F428EC210C218C220C2087E0409E37A07016F7A07017F6D007A07018F7A07019F22C211C219C221C2097E040DE37A0701717A0701816D007A0701917A0701A122C212C21AC222C20A7E0411E37A0701737A0701836D007A0701937A0701A322C213C21BC223C20B7E0415E37A0701757A0701856D007A0701957A0701A522C214C21CC224C20C7E0419E37A0701777A0701876D007A0701977A0701A722C215C21DC225C20D7E041DE37A0701797A0701896D007A0701997A0701A922C216C21EC226C20E7E0421E37A07017B7A07018B6D007A07019B7A0701AB22C217C21FC227C20F7E0425E37A07017D7A07018D6D007A07019D7A0701AD227CB2230A2B492242B8892442C842E9430A432B434C436D438E43AF305007206804C2288016304007206004C228800C304807205804C2288002D22822305107206904C2298016304107206104C229800C304907205904C2298002D22922305207206A04C22A8016304207206204C22A800C304A07205A04C22A8002D22A22305307206B04C22B8016304307206304C22B800C304B07205B04C22B8002D22B22305407206C04C22C8016304407206404C22C800C304C07205C04C22C8002D22C22305507206D04C22D8016304507206504C22D800C304D07205D04C22D8002D22D22305607206E04C22E8016304607206604C22E800C304E07205E04C22E8002D22E22305707206F04C22F8016304707206704C22F800C304F07205F04C22F8002D22F22443843E5BEB002400122230A5B495543D09954D322A9C5871244437E0405E37A0701D77A0701D97E0401E37A0701DD7A0701DF7E0474AD7A056175F10175E11F75E40475F40475F10275E10375E40475F40443A21C1240EB7E200012419A0B20BE212F78F6D2A822A9D587124443D292C2A82275A30053A20375C10053C0037E00057A01F143F48043E480E5F2547F4408F5F2E5E2547F4408F5E275E110A5D8E122CA09123020100112D5671E6369017E006A2E0169A5E6F567801220021E756900856A67D2027400800D30020FC2027E006C2E0169A5E65390CF4290DA0932C0D0C0D1C0E0C0F0CA0BCA1BCA2BD201753189127C157E14800009B1000820E00302454F20785AA50A09B1000820E00302456720794BA50A09B1000820E00302457FA50A09B1000820E003024597207A30A50A09B1000820E0030245AFA50A09B1000820E0030245C7A50A09B1000820E0030245DFA50A09B1000820E0030245F730040CC204C0F175F101126FD9D0F1DA2BDA1BDA0BD0F0D0E0D0D1D0D032753180127C15543E0A5B7E4400FF6952632BCA06C6448954753181127C15543E0A5B7E4400FF6952636BCA06C6448954753182127C15543E0A5B7E4400FF695263ABCA06C6448954753183127C15543E0A5B7E4400FF695263EBCA06C6448954753184127C15543E0A5B7E4400FF6952642BCA06C6448954753185127C15543E0A5B7E4400FF6952646BCA06C6448954753186127C15543E0A5B7E4400FF695264ABCA06C6448954753187127C15543E0A5B7E4400FF695264EBCA06C644895410080122202803D208227531A0127C157E1480008006202803D2082209B10014CAB85EB01EDAB8680312493020E603D20822303049D2707E37018F7E2701AF9D3240317D022E05487A05487A37018F7E37016F7D432D42BE440DE238687A47016F753194127C157A5131127C1512652B1070C422C2702D2368786D33801A7E27018FBE240000686ABE2701AF28047E2701AF7E37018F9D327D022E05487A05487A37018F7E37016F7D432D42BE440DE238137A47016F753194127C157A5131127C1502652B753194127C157A5131127C159E440DE39D2412652B7E3409E37D242D437A47016F12652BBE2520780302467F22D2087E0409E37A07016F7A07017F753194127C15753100127C1522753192127C15D20409B10014CAB85482DAB878707E3701E17E2701BF2E2400022D32BE340400383C7D022E05467A05467A3701E17E3701DF7D432D42BE4405E238447A4701DF7E2400002E2701BF1B38200B357A5131127C15BE503878030266160265FB753199127C1509B1000454FA19B1000430380A09B1001054FE19B10010D21022807D7A5131127C159E4405E39D247E6400002E6701BF9E24000240171B38600B351265FB7E3401E37D242D437A4701DF0265FB7A39C07E3401E37A39D00B341B4480E59D327CB6540F23232344007A69B07A79700B35753193127C157A7131127C15BD0468297A0701DF7E4701E12D437A4701E12E35467A35462209B1001420E013227E0401E3802A7E0401E3802C7E0401E380D1D2047E0701E17E2403FE9D2028407E0701DF7E4405E37D600B04BD0468D07D700B04BD0468CE7D549D50BD2540027D257D3209B10014CAB8541FB40131DAB87E19B07A09B00B041B2478E70247E3753199127C1509B1000454FA19B1000430380A09B1001054FE19B10010D21022DAB830E0D8BD326807CAB81247E3DAB802493009B100187EA088753190127C15F531127C15A5FC5EB0F0A5FD09B100184C4B5EB0F0BCB578F15E400F4C547CB55E500B682AA5FD5E50106804D2688002C268A5FD5E50206804D2608002C260A5FD5E50806804D2588002C2581242C8026293753191127C1509B100147AB131127C1520E008D2047EA080026293D20430E1067EA080126293CAB85EB01CDAB868127EA0C0096100001262B609B1001420E0DB22024835753195127C1522753196127C152210090122202903D209227531A1127C157E1481008006202903D2092209B10014CAB85EB01EDAB86803124C8820E603D20922303149D2717E3701917E2701B19D3240317D022E054A7A054A7A3701917E3701717D432D42BE4411E238687A470171753194127C157A5131127C1512652B1071C422C2712D2368786D33801A7E270191BE240000686ABE2701B128047E2701B17E3701919D327D022E054A7A054A7A3701917E3701717D432D42BE4411E238137A470171753194127C157A5131127C1502652B753194127C157A5131127C159E4411E39D2412652B7E340DE37D242D437A47017112652BBE252078030249D722D2097E040DE37A0701717A070181753194127C15753100127C1522753192127C15D20409B10014CAB85482DAB878707E3701E17E2701C12E2400022D32BE340400383C7D022E05467A05467A3701E17E3701DF7D432D42BE4405E238447A4701DF7E2401002E2701C11B38200B357A5131127C15BE503878030266160265FB753199127C1509B1000454FA19B1000430390A09B1001054FE19B10010D21122807D7A5131127C159E4405E39D247E6401002E6701C19E24000240171B38600B351265FB7E3401E37D242D437A4701DF0265FB7A39C07E3401E37A39D00B341B4480E59D327CB6540F23232344017A69B07A79700B35753193127C157A7131127C15BD0468297A0701DF7E4701E12D437A4701E12E35467A35462209B1001420E013227E0401E3802A7E0401E3802C7E0401E380D1D2047E0701E17E2403FE9D2028407E0701DF7E4405E37D600B04BD0468D07D700B04BD0468CE7D549D50BD2540027D257D3209B10014CAB8541FB40131DAB87E19B07A09B00B041B2478E7024B3B753199127C1509B1000454FA19B1000430390A09B1001054FE19B10010D21122DAB830E0D8BD326807CAB8124B3BDAB8024C8809B100187EA088753190127C15F531127C15A5FC5EB0F0A5FD09B100184C4B5EB0F0BCB578F15E400F4C547CB55E500B682AA5FD5E50106804D2698002C269A5FD5E50206804D2618002C261A5FD5E50806804D2598002C2591242E9026293753191127C1509B100147AB131127C1520E008D2047EA080026293D20430E1067EA080126293CAB85EB01CDAB868127EA0C0096100001262B609B1001420E0DB22024B8D753195127C1522753196127C1522100A0122202A03D20A227531A2127C157E1482008006202A03D20A2209B10014CAB85EB01EDAB86803124FE020E603D20A22303249D2727E3701937E2701B39D3240317D022E054C7A054C7A3701937E3701737D432D42BE4415E238687A470173753194127C157A5131127C1512652B1072C422C2722D2368786D33801A7E270193BE240000686ABE2701B328047E2701B37E3701939D327D022E054C7A054C7A3701937E3701737D432D42BE4415E238137A470173753194127C157A5131127C1502652B753194127C157A5131127C159E4415E39D2412652B7E3411E37D242D437A47017312652BBE25207803024D2F22D20A7E0411E37A0701737A070183753194127C15753100127C1522753192127C15D20409B10014CAB85482DAB878707E3701E17E2701C32E2400022D32BE340400383C7D022E05467A05467A3701E17E3701DF7D432D42BE4405E238447A4701DF7E2402002E2701C31B38200B357A5131127C15BE503878030266160265FB753199127C1509B1000454FA19B10004303A0A09B1001054FE19B10010D21222807D7A5131127C159E4405E39D247E6402002E6701C39E24000240171B38600B351265FB7E3401E37D242D437A4701DF0265FB7A39C07E3401E37A39D00B341B4480E59D327CB6540F23232344027A69B07A79700B35753193127C157A7131127C15BD0468297A0701DF7E4701E12D437A4701E12E35467A35462209B1001420E013227E0401E3802A7E0401E3802C7E0401E380D1D2047E0701E17E2403FE9D2028407E0701DF7E4405E37D600B04BD0468D07D700B04BD0468CE7D549D50BD2540027D257D3209B10014CAB8541FB40131DAB87E19B07A09B00B041B2478E7024E93753199127C1509B1000454FA19B10004303A0A09B1001054FE19B10010D21222DAB830E0D8BD326807CAB8124E93DAB8024FE009B100187EA088753190127C15F531127C15A5FC5EB0F0A5FD09B100184C4B5EB0F0BCB578F15E400F4C547CB55E500B682AA5FD5E50106804D26A8002C26AA5FD5E50206804D2628002C262A5FD5E50806804D25A8002C25A12430A026293753191127C1509B100147AB131127C1520E008D2047EA080026293D20430E1067EA080126293CAB85EB01CDAB868127EA0C0096100001262B609B1001420E0DB22024EE5753195127C1522753196127C1522100B0122202B03D20B227531A3127C157E1483008006202B03D20B2209B10014CAB85EB01EDAB8680312533820E603D20B22303349D2737E3701957E2701B59D3240317D022E054E7A054E7A3701957E3701757D432D42BE4419E238687A470175753194127C157A5131127C1512652B1073C422C2732D2368786D33801A7E270195BE240000686ABE2701B528047E2701B57E3701959D327D022E054E7A054E7A3701957E3701757D432D42BE4419E238137A470175753194127C157A5131127C1502652B753194127C157A5131127C159E4419E39D2412652B7E3415E37D242D437A47017512652BBE2520780302508722D20B7E0415E37A0701757A070185753194127C15753100127C1522753192127C15D20409B10014CAB85482DAB878707E3701E17E2701C52E2400022D32BE340400383C7D022E05467A05467A3701E17E3701DF7D432D42BE4405E238447A4701DF7E2403002E2701C51B38200B357A5131127C15BE503878030266160265FB753199127C1509B1000454FA19B10004303B0A09B1001054FE19B10010D21322807D7A5131127C159E4405E39D247E6403002E6701C59E24000240171B38600B351265FB7E3401E37D242D437A4701DF0265FB7A39C07E3401E37A39D00B341B4480E59D327CB6540F23232344037A69B07A79700B35753193127C157A7131127C15BD0468297A0701DF7E4701E12D437A4701E12E35467A35462209B1001420E013227E0401E3802A7E0401E3802C7E0401E380D1D2047E0701E17E2403FE9D2028407E0701DF7E4405E37D600B04BD0468D07D700B04BD0468CE7D549D50BD2540027D257D3209B10014CAB8541FB40131DAB87E19B07A09B00B041B2478E70251EB753199127C1509B1000454FA19B10004303B0A09B1001054FE19B10010D21322DAB830E0D8BD326807CAB81251EBDAB802533809B100187EA088753190127C15F531127C15A5FC5EB0F0A5FD09B100184C4B5EB0F0BCB578F15E400F4C547CB55E500B682AA5FD5E50106804D26B8002C26BA5FD5E50206804D2638002C263A5FD5E50806804D25B8002C25B12432B026293753191127C1509B100147AB131127C1520E008D2047EA080026293D20430E1067EA080126293CAB85EB01CDAB868127EA0C0096100001262B609B1001420E0DB2202523D753195127C1522753196127C1522100C0122202C03D20C227531A4127C157E1484008006202C03D20C2209B10014CAB85EB01EDAB8680312569020E603D20C22303449D2747E3701977E2701B79D3240317D022E05507A05507A3701977E3701777D432D42BE441DE238687A470177753194127C157A5131127C1512652B1074C422C2742D2368786D33801A7E270197BE240000686ABE2701B728047E2701B77E3701979D327D022E05507A05507A3701977E3701777D432D42BE441DE238137A470177753194127C157A5131127C1502652B753194127C157A5131127C159E441DE39D2412652B7E3419E37D242D437A47017712652BBE252078030253DF22D20C7E0419E37A0701777A070187753194127C15753100127C1522753192127C15D20409B10014CAB85482DAB878707E3701E17E2701C72E2400022D32BE340400383C7D022E05467A05467A3701E17E3701DF7D432D42BE4405E238447A4701DF7E2404002E2701C71B38200B357A5131127C15BE503878030266160265FB753199127C1509B1000454FA19B10004303C0A09B1001054FE19B10010D21422807D7A5131127C159E4405E39D247E6404002E6701C79E24000240171B38600B351265FB7E3401E37D242D437A4701DF0265FB7A39C07E3401E37A39D00B341B4480E59D327CB6540F23232344047A69B07A79700B35753193127C157A7131127C15BD0468297A0701DF7E4701E12D437A4701E12E35467A35462209B1001420E013227E0401E3802A7E0401E3802C7E0401E380D1D2047E0701E17E2403FE9D2028407E0701DF7E4405E37D600B04BD0468D07D700B04BD0468CE7D549D50BD2540027D257D3209B10014CAB8541FB40131DAB87E19B07A09B00B041B2478E7025543753199127C1509B1000454FA19B10004303C0A09B1001054FE19B10010D21422DAB830E0D8BD326807CAB8125543DAB802569009B100187EA088753190127C15F531127C15A5FC5EB0F0A5FD09B100184C4B5EB0F0BCB578F15E400F4C547CB55E500B682AA5FD5E50106804D26C8002C26CA5FD5E50206804D2648002C264A5FD5E50806804D25C8002C25C12434C026293753191127C1509B100147AB131127C1520E008D2047EA080026293D20430E1067EA080126293CAB85EB01CDAB868127EA0C0096100001262B609B1001420E0DB22025595753195127C1522753196127C1522100D0122202D03D20D227531A5127C157E1485008006202D03D20D2209B10014CAB85EB01EDAB868031259E820E603D20D22303549D2757E3701997E2701B99D3240317D022E05527A05527A3701997E3701797D432D42BE4421E238687A470179753194127C157A5131127C1512652B1075C422C2752D2368786D33801A7E270199BE240000686ABE2701B928047E2701B97E3701999D327D022E05527A05527A3701997E3701797D432D42BE4421E238137A470179753194127C157A5131127C1502652B753194127C157A5131127C159E4421E39D2412652B7E341DE37D242D437A47017912652BBE2520780302573722D20D7E041DE37A0701797A070189753194127C15753100127C1522753192127C15D20409B10014CAB85482DAB878707E3701E17E2701C92E2400022D32BE340400383C7D022E05467A05467A3701E17E3701DF7D432D42BE4405E238447A4701DF7E2405002E2701C91B38200B357A5131127C15BE503878030266160265FB753199127C1509B1000454FA19B10004303D0A09B1001054FE19B10010D21522807D7A5131127C159E4405E39D247E6405002E6701C99E24000240171B38600B351265FB7E3401E37D242D437A4701DF0265FB7A39C07E3401E37A39D00B341B4480E59D327CB6540F23232344057A69B07A79700B35753193127C157A7131127C15BD0468297A0701DF7E4701E12D437A4701E12E35467A35462209B1001420E013227E0401E3802A7E0401E3802C7E0401E380D1D2047E0701E17E2403FE9D2028407E0701DF7E4405E37D600B04BD0468D07D700B04BD0468CE7D549D50BD2540027D257D3209B10014CAB8541FB40131DAB87E19B07A09B00B041B2478E702589B753199127C1509B1000454FA19B10004303D0A09B1001054FE19B10010D21522DAB830E0D8BD326807CAB812589BDAB80259E809B100187EA088753190127C15F531127C15A5FC5EB0F0A5FD09B100184C4B5EB0F0BCB578F15E400F4C547CB55E500B682AA5FD5E50106804D26D8002C26DA5FD5E50206804D2658002C265A5FD5E50806804D25D8002C25D12436D026293753191127C1509B100147AB131127C1520E008D2047EA080026293D20430E1067EA080126293CAB85EB01CDAB868127EA0C0096100001262B609B1001420E0DB220258ED753195127C1522753196127C1522100E0122202E03D20E227531A6127C157E1486008006202E03D20E2209B10014CAB85EB01EDAB86803125D4020E603D20E22303649D2767E37019B7E2701BB9D3240317D022E05547A05547A37019B7E37017B7D432D42BE4425E238687A47017B753194127C157A5131127C1512652B1076C422C2762D2368786D33801A7E27019BBE240000686ABE2701BB28047E2701BB7E37019B9D327D022E05547A05547A37019B7E37017B7D432D42BE4425E238137A47017B753194127C157A5131127C1502652B753194127C157A5131127C159E4425E39D2412652B7E3421E37D242D437A47017B12652BBE25207803025A8F22D20E7E0421E37A07017B7A07018B753194127C15753100127C1522753192127C15D20409B10014CAB85482DAB878707E3701E17E2701CB2E2400022D32BE340400383C7D022E05467A05467A3701E17E3701DF7D432D42BE4405E238447A4701DF7E2406002E2701CB1B38200B357A5131127C15BE503878030266160265FB753199127C1509B1000454FA19B10004303E0A09B1001054FE19B10010D21622807D7A5131127C159E4405E39D247E6406002E6701CB9E24000240171B38600B351265FB7E3401E37D242D437A4701DF0265FB7A39C07E3401E37A39D00B341B4480E59D327CB6540F23232344067A69B07A79700B35753193127C157A7131127C15BD0468297A0701DF7E4701E12D437A4701E12E35467A35462209B1001420E013227E0401E3802A7E0401E3802C7E0401E380D1D2047E0701E17E2403FE9D2028407E0701DF7E4405E37D600B04BD0468D07D700B04BD0468CE7D549D50BD2540027D257D3209B10014CAB8541FB40131DAB87E19B07A09B00B041B2478E7025BF3753199127C1509B1000454FA19B10004303E0A09B1001054FE19B10010D21622DAB830E0D8BD326807CAB8125BF3DAB8025D4009B100187EA088753190127C15F531127C15A5FC5EB0F0A5FD09B100184C4B5EB0F0BCB578F15E400F4C547CB55E500B682AA5FD5E50106804D26E8002C26EA5FD5E50206804D2668002C266A5FD5E50806804D25E8002C25E12438E026293753191127C1509B100147AB131127C1520E008D2047EA080026293D20430E1067EA080126293CAB85EB01CDAB868127EA0C0096100001262B609B1001420E0DB22025C45753195127C1522753196127C1522100F0122202F03D20F227531A7127C157E1487008006202F03D20F2209B10014CAB85EB01EDAB8680312609820E603D20F22303749D2777E37019D7E2701BD9D3240317D022E05567A05567A37019D7E37017D7D432D42BE4429E238687A47017D753194127C157A5131127C1512652B1077C422C2772D2368786D33801A7E27019DBE240000686ABE2701BD28047E2701BD7E37019D9D327D022E05567A05567A37019D7E37017D7D432D42BE4429E238137A47017D753194127C157A5131127C1502652B753194127C157A5131127C159E4429E39D2412652B7E3425E37D242D437A47017D12652BBE25207803025DE722D20F7E0425E37A07017D7A07018D753194127C15753100127C1522753192127C15D20409B10014CAB85482DAB878707E3701E17E2701CD2E2400022D32BE340400383C7D022E05467A05467A3701E17E3701DF7D432D42BE4405E238447A4701DF7E2407002E2701CD1B38200B357A5131127C15BE503878030266160265FB753199127C1509B1000454FA19B10004303F0A09B1001054FE19B10010D21722807D7A5131127C159E4405E39D247E6407002E6701CD9E24000240171B38600B351265FB7E3401E37D242D437A4701DF0265FB7A39C07E3401E37A39D00B341B4480E59D327CB6540F23232344077A69B07A79700B35753193127C157A7131127C15BD0468297A0701DF7E4701E12D437A4701E12E35467A35462209B1001420E013227E0401E3802A7E0401E3802C7E0401E380D1D2047E0701E17E2403FE9D2028407E0701DF7E4405E37D600B04BD0468D07D700B04BD0468CE7D549D50BD2540027D257D3209B10014CAB8541FB40131DAB87E19B07A09B00B041B2478E7025F4B753199127C1509B1000454FA19B10004303F0A09B1001054FE19B10010D21722DAB830E0D8BD326807CAB8125F4BDAB802609809B100187EA088753190127C15F531127C15A5FC5EB0F0A5FD09B100184C4B5EB0F0BCB578F15E400F4C547CB55E500B682AA5FD5E50106804D26F8002C26FA5FD5E50206804D2678002C267A5FD5E50806804D25F8002C25F1243AF026293753191127C1509B100147AB131127C1520E008D2047EA080026293D20430E1067EA080126293CAB85EB01CDAB868127EA0C0096100001262B609B1001420E0DB22025F9D753195127C1522753196127C15227C027E1480004C2009B10018A5FD5E50106804D2688002C268A5FD5E50206804D2608002C260A5FD5E50806804D2588002C25802627F7C027E1480004C2009B10018A5FD5E50106804D2698002C269A5FD5E50206804D2618002C261A5FD5E50806804D2598002C25902627F7C027E1480004C2009B10018A5FD5E50106804D26A8002C26AA5FD5E50206804D2628002C262A5FD5E50806804D25A8002C25A02627F7C027E1480004C2009B10018A5FD5E50106804D26B8002C26BA5FD5E50206804D2638002C263A5FD5E50806804D25B8002C25B02627F7C027E1480004C2009B10018A5FD5E50106804D26C8002C26CA5FD5E50206804D2648002C264A5FD5E50806804D25C8002C25C02627F7C027E1480004C2009B10018A5FD5E50106804D26D8002C26DA5FD5E50206804D2658002C265A5FD5E50806804D25D8002C25D02627F7C027E1480004C2009B10018A5FD5E50106804D26E8002C26EA5FD5E50206804D2668002C266A5FD5E50806804D25E8002C25E02627F7C027E1480004C2009B10018A5FD5E50106804D26F8002C26FA5FD5E50206804D2678002C267A5FD5E50806804D25F8002C25F02627F54F0C4A5FFC4A54F753190127C15F531127C1522CA195E20074CA27E7429E3CA797A79A00B747A79B00B74DA797E30027E6400020262DECA195E20074CA27E7429E3CA797A79A00B747A79B00B747A79600B74DA797E30037E6400030262DED2047E2701E12D26BE240400382E7E0701DF7E4405E37E79A07A09A00B040B74BD046823A5DBEF7A2701E17E25462D267A25467A0701DFDA19C2D72275319A127C15DA19D2D7227E0401E380D748B64625471C491544C644C6481B44C6495944C644C644C644C644C644C644C6496044C644C644C644C644C644C644C644C644C644C644C644C644C644C644C64C0E497D4A744C6D44C644C64B7344C64CB144C644C644C644C644C644C644C64CB844C644C644C644C644C644C644C644C644C644C644C644C644C644C644C64F664CD54DCC4FC544C644C64ECB44C6500944C644C644C644C644C644C644C6501044C644C644C644C644C644C644C644C644C644C644C644C644C644C644C652BE502D5124531D44C644C6522344C6536144C644C644C644C644C644C644C6536844C644C644C644C644C644C644C644C644C644C644C644C644C644C644C656165385547C567544C644C6557B44C656B944C644C644C644C644C644C644C656C044C644C644C644C644C644C644C644C644C644C644C644C644C644C644C6596E56DD57D459CD44C644C658D344C65A1144C644C644C644C644C644C644C65A1844C644C644C644C644C644C644C644C644C644C644C644C644C644C644C65CC65A355B2C5D2544C644C65C2B44C65D6944C644C644C644C644C644C644C65D7044C644C644C644C644C644C644C644C644C644C644C644C644C644C644C6601E5D8D5E84607D44C644C65F8344C660C144C644C644C644C644C644C644C660C844C644C644C644C644C644C644C644C644C644C644C644C644C644C644C6CA291E50400D7E540B109CB5A42E54654889547E39007A19000B3480E90B38007A19007A19100B350B38007A19007A19100B350B38007A19007A19100B350B38007A19007A19100B350B38007A19007A19100B350B38007A19007A19100B350B38007A19007A19100B350B38007A19007A19100B350B38007A19007A19100B350B38007A19007A19100B350B38007A19007A19100B350B38007A19007A19100B350B38007A19007A19100B350B38007A19007A19100B350B38007A19007A19100B350B38007A19007A19100B35DA29221E50400D7E540B1C9CB5A42E54661689547E19007A39000B3480E97E19007E19101B38000B357E19007E19101B38000B357E19007E19101B38000B357E19007E19101B38000B357E19007E19101B38000B357E19007E19101B38000B357E19007E19101B38000B357E19007E19101B38000B357E19007E19101B38000B357E19007E19101B38000B357E19007E19101B38000B357E19007E19101B38000B357E19007E19101B38000B357E19007E19101B38000B357E19007E19101B38000B357E19007E19101B38000B357E19007E19101B38000B357E19007E19101B38000B357E19007E19101B38000B357E19007E19101B38000B357E19007E19101B38000B357E19007E19101B38000B357E19007E19101B38000B357E19007E19101B38000B357E19007E19101B38000B357E19007E19101B38000B357E19007E19101B38000B357E19007E19101B38000B352267966963697B6A496AE46B8E6BA96C3B6BC46C05699669AA7CB3BEB00B2814753109127C15756D10C0F175F10143E1C0D0F122C0A8C2AF236CAA2E54674B0B5850895401020408102040807531B0127C150A3209B3678E423219430036D0A8227CB2230A3B493367CB0A220932003609B2678EA5BB0005F4523380024233893467DB680968376865689368C168EF691D1241B5D228D208C240C248C238C2306D007A0301CF7E0400207A0701AF7E0400387A0701BF1241161260CF02694B1241D4D229D209C241C249C239C2316D007A0301D07E0400207A0701B17E0400387A0701C112411612610502694B1241F3D22AD20AC242C24AC23AC2326D007A0301D17E0400207A0701B37E0400387A0701C312411612613B02694B124212D22BD20BC243C24BC23BC2336D007A0301D27E0400207A0701B57E0400387A0701C512411612617102694B124231D22CD20CC244C24CC23CC2346D007A0301D37E0400207A0701B77E0400387A0701C71241161261A702694B124250D22DD20DC245C24DC23DC2356D007A0301D47E0400207A0701B97E0400387A0701C91241161261DD02694B12426FD22ED20EC246C24EC23EC2366D007A0301D57E0400207A0701BB7E0400387A0701CB12411612621302694B12428ED22FD20FC247C24FC23FC2376D007A0301D67E0400207A0701BD7E0400387A0701CD12411612624902694B7EA0D07E600F1262B6400CC0F175F101126FD9D0F1C2D7227531B1127C150A52236D005905004812417E12419AD0A8227531B2127C150A2209B2678E42237EB09C19B201CF123185D0A8227531B7127C150A2209B2678E422412353DD0A8227531B9127C150A3209B3678E42341943003E1269C2D0A8227CB2230A0B7CB420E0046D3380044930018F7EA0D8A5EFCA0BCA291262B6DA29DA0B40627531BA127C157CB430E01E6D335930018F7E3409E30A827E940400AD892D395930016F5930017F7CB430E1107E0480004C0209B00008440419B000080A0209B0678E4221F452347CB2230A0BCA19490030D59904DA19C0F175F101126FD9D0F1C2D7227E0480004C020930000C74BF19B0000C09B000081930000C7C745E700168124440CAB809B00010440219B00010DAB8800254BF7C745E700868044408800254F70930000CCAB874BF19B0000CDAB819B000081930000C0A6209B6678E3E200A627C745E700268204227CAB8746119B000087E440010594601BF09B00010440119B00010DAB88011F4522774A119B000087E440038594601BFD0A8227C747E0480004C020A6209B6678EA5FDF4A5FECA283E200A62A5EE52267E440020594601AFDA280930000C74BF19B0000C09B000087C745E7001680C4480CAB8A5ED422ADAB8800A547FCAB8A5EE522ADAB87C745E700868044402800254FD19B000081930000C7C745E70026810A5ED422842267E440008594601AF8004A5EE52287C745E70046810A5ED422942267E440008594601AF800BA5EE52297C745E700278001242ADD0A8227E0480004C020930000C74BF19B0000C194000101930000CD0A8227E0480004C020930000C74BF19B0000C194000181930000CD0A8227531B5127C157E0480004C0209B0000C444019B0000CE56EB4072309B000104EB00219B000100930000C74BF19B0000C09B0000454F719B000041930000CD0A8227531B6127C157E0480004C02E56EB407180930000C74BF19B0000C09B00004440819B000041930000C09B0000C54BF19B0000CD0A8227531B4127C157A2131127C157A4131127C150A3209B3678E4235126C5BD0A8227EB0017EA0C87C641262B640130A3209B3678EF45235C0F175F101126FD9D0F1226C8C6CD36D1A6D616DA86DEF6E366E7D753155127C15753100127C157A6131127C157A7131127C157E17017F7E27018F2D237E09B00B047A19B00B14BE140DE2380F1B3478EC7A17017F7A27018F02460F7E1409E380EB753155127C15753101127C157A6131127C157A7131127C157E1701817E2701912D237E09B00B047A19B00B14BE1411E2380F1B3478EC7A1701817A2701910249677E140DE380EB753155127C15753102127C157A6131127C157A7131127C157E1701837E2701932D237E09B00B047A19B00B14BE1415E2380F1B3478EC7A1701837A270193024CBF7E1411E380EB753155127C15753103127C157A6131127C157A7131127C157E1701857E2701952D237E09B00B047A19B00B14BE1419E2380F1B3478EC7A1701857A2701950250177E1415E380EB753155127C15753104127C157A6131127C157A7131127C157E1701877E2701972D237E09B00B047A19B00B14BE141DE2380F1B3478EC7A1701877A27019702536F7E1419E380EB753155127C15753105127C157A6131127C157A7131127C157E1701897E2701992D237E09B00B047A19B00B14BE1421E2380F1B3478EC7A1701897A2701990256C77E141DE380EB753155127C15753106127C157A6131127C157A7131127C157E17018B7E27019B2D237E09B00B047A19B00B14BE1425E2380F1B3478EC7A17018B7A27019B025A1F7E1421E380EB753155127C15753107127C157A6131127C157A7131127C157E17018D7E27019D2D237E09B00B047A19B00B14BE1429E2380F1B3478EC7A17018D7A27019D025D777E1425E380EBCAB8C0F1753102127C15E5C0540368051275CD80F530C20875F101126FD9801430C30875F101126EFD800930C40675F1021270E9D0F1DAB832753110127C15CA0BCA39CA59C2C3A921E25CE5E554C0684FE5E66CAA7E3701DB2D35BE340400384A7A3701DB7E3701D97D432D45BE4409E238407A4701D9753111127C157AB131127C151271B8A921E51FA9D4E4A924E4FCC2C3A921E23BE5E554C078B412745ADA59DA39DA0B2280298058753116127C1580ED753112127C157AB131127C159E4409E39D541271B87E3405E37D542D4380A1E5E554037812753113127C157E0F29FF0B0C7A0F29FF80A7753114127C157E0F2A030B0C7A0F2A03A9D7E4A927E4FC809D753115127C157E0F2A070B0C7A0F2A0780E5753118127C15CA09CA39CA2BC2C2A921F252E5F53382E740447E3701E17E5400409D3540437A3701E17E3701DD7D432D45BE4405E238527A4701DD7D45127316A920F522753119127C157A9131127C157A81F77A91F6E5F53382E750BCDA2BDA39DA0922804180642D536D3370B77E0401E37A0701DF7A0701DDA932F2DF853031127C1575F60080D4CA599E4405E39D541273167E3401E37D542D437A4701DD127316DA498099E5F55403781F7E0F29EF0B0C7A0F29EF809D7E0F29F70B0C7A0F29F7A9D7F4A927F4FC808A7E0F29F30B0C7A0F29F380EBE5F55403781F7E2F2A0F0B2C7A2F2A0F80347E2F2A170B2C7A2F2A17A9D7F4A927F4FC80217E2F2A130B2C7A2F2A1380EBDA2BDA1BDA0B22753128127C15CA0BCA1BCA2BC2C4A921F2B6E5F53372E740E07E0D467E1D4A7E2D4E7E3D527E85567D904D914D924D934D944D954D964D974D9868727A11F37A01F37A31F37A21F37A51F37A41F37A71F37A61F37A91F37A81F3307B1A7AB1F37AA1F37AD1F37AC1F37AF1F37AE1F37D787AF1F37AE1F3A930F5030270D6753129127C15207B0B75310A127C1575F60A8009753112127C1575F6126D007D107A0D467A0D4A7A0D4E7A0D527A0556DA2BDA1BDA0B221EB0400C7EA00AA47E0472FB9D0589047EA1E37A39A00B3480EAB440E37EA1E3E5E31B38500B357EA1E3E5E31B38500B357EA1E3E5E31B38500B357EA1E3E5E31B38500B357EA1E3E5E31B38500B357EA1E3E5E31B38500B357EA1E3E5E31B38500B357EA1E3E5E31B38500B357EA1E3E5E31B38500B357EA1E3E5E31B38500B357EA1E3E5E31B38500B357EA1E3E5E31B38500B357EA1E3E5E31B38500B357EA1E3E5E31B38500B357EA1E3E5E31B38500B357EA1E3E5E31B38500B357EA1E3E5E31B38500B357EA1E3E5E31B38500B357EA1E3E5E31B38500B357EA1E3E5E31B38500B357EA1E3E5E31B38500B357EA1E3E5E31B38500B357EA1E3E5E31B38500B357EA1E3E5E31B38500B357EA1E3E5E31B38500B357EA1E3E5E31B38500B357EA1E3E5E31B38500B357EA1E3E5E31B38500B357EA1E3E5E31B38500B357EA1E3E5E31B38500B357EA1E3E5E31B38500B357EA1E3E5E31B38500B35221EB0400C7EA00AA47E0474599D0589047E39A07AA1F30B3480EAB440E30B38507AA1F3F5F30B350B38507AA1F3F5F30B350B38507AA1F3F5F30B350B38507AA1F3F5F30B350B38507AA1F3F5F30B350B38507AA1F3F5F30B350B38507AA1F3F5F30B350B38507AA1F3F5F30B350B38507AA1F3F5F30B350B38507AA1F3F5F30B350B38507AA1F3F5F30B350B38507AA1F3F5F30B350B38507AA1F3F5F30B350B38507AA1F3F5F30B350B38507AA1F3F5F30B350B38507AA1F3F5F30B350B38507AA1F3F5F30B350B38507AA1F3F5F30B350B38507AA1F3F5F30B350B38507AA1F3F5F30B350B38507AA1F3F5F30B350B38507AA1F3F5F30B350B38507AA1F3F5F30B350B38507AA1F3F5F30B350B38507AA1F3F5F30B350B38507AA1F3F5F30B350B38507AA1F3F5F30B350B38507AA1F3F5F30B350B38507AA1F3F5F30B350B38507AA1F3F5F30B350B38507AA1F3F5F30B350B38507AA1F3F5F30B3522C2AF7E3701DB4D33683B7E0701D77E5409E39D50BD3540027D35CA397E65619964DA397E0701DB9D037A0701DB2E3701D77A3701D7BE3409E228C77E3405E37A3701D780BDD2AF22753153127C157E15638011753151127C150B08100B059E340002284D7CB220E7275407230A2B49226C7C7CB254780303037C2B9D13401A68127A15637A25657E6475377A656189240275457E6474AD80F22D139D31CA397D312D10CA19CA299924DA29DA09DA3980A27A15637E6475234D3378097CB220E72A7E6474A27A656122753152127C157E21637E09300B041B34788980D4753154127C157E15637E256580905E200754787E4475C130E6164D3368261B347E09400B047E44676320E3047E4475C9CA09CA399944DA39DA097E6474AD4D3368A689647A1563F5657E64758680997E1563E56580C4C0D0C0D1C0E0CA19A920DF12A921DF1B753101127C1553DFF71240DC800D7531FE127C157E140053024051DA19D0E0D0D1D0D03203A5CB19B180002222027642CA0BCA1BCA2BCA3BCA4BCA5BCA6BCA7BCAEBC0F17EB32A33B400028019B4011630C00875F10012762C801F30C11C75F1001276BD801430C10875F1001276BD800930C00675F10012762CD0F1DAEBDA7BDA6BDA5BDA4BDA3BDA2BDA1BDA0B22C2C07EB32A33B4020712764E02764222B401FC0276887E00007A032A337A032A34227EB32A2B54606005B4401580137EB32A2CB4050C753171127C157EB32A2EF58F2275F60022BE572A3128047E572A317A0F2A367A572A3A0276887EEF2A367EF72A3A7E072A3A4D0068217E00007EEBB0F5F3A3A5081BF46804A5B808F07AEF2A367AF72A3A753106127C157A01F622C2C1753103127C15A936E216E5F554C06807A9D7F4A927F4FC53E13F43F2880277297EB32A34B40204A9D4E422B401397E21E67C327E132A352C217A232A357E00002E042A3CE5E37A09B00B04A5DBF6A9D4E4753170127C157EB32A357EA32A32BCAB78031277C022027B29E5E6B40865A9C4E27E01E37E11E37E31E37E21E37E51E37E41E37E71E37E61E37A0F2A2B7A1F2A2F753104127C157A0131127C157A1131127C157A2131127C157A3131127C157A4131127C157A5131127C157A6131127C157A7131127C15A9D4E4A9D7F4A9C6E2127794226D007E1401027A072A3A7A032A357EB32A2B20E70F7A232A347A332A33BE072A316809227A332A347A232A337EB32A2B54E3232330E002D2E530E702D2E430E50630E403027B29543EF5F003541FC325F09077EC7584FF730279400278340279DD0279F80278D902789A027A11027A11027A14027A14027A14027A14027A14027A14027A14027A14027A1A027ACE027A17027A17027A17027A17027A17027A177EB32A2CB4062A7EB32A2D60567C0B7E132A2E7E172A2F753172127C157A0131127C157A1131127C15127B334035027673B40810753174127C157EB33FF1F5F375F60122B4001C753175127C157EB33FF230E00575F302800375F30075F30075F60222027B297EB32A2CB40035753176127C157EB32A30540FF5F17EB32A3020E709E5E130E70D7401800BE5E130E60474018002740053F180F5F375F30075F60222027B29C0F17EB32A30540F42F17EB32A2EB400457EB32A2CB40124753177127C157EB32A30540F780553E13F80377EB32A3020E70553E17F802B53E1BF8026B40317753178127C157EB32A3020E70543E180801143E140800C43E1C0D0F1753107127C1522D0F102766F7EB32A2CB40923753179127C157EB32A2EBEB33FF16811CAB8C0F11243D4D0F1DAB850767AB33FF1806DB4050875317A127C158062B4031975317B127C157EB32A2EB401557EB33FF244017AB33FF28046B4011975317C127C157EB32A2EB401397EB33FF254FE7AB33FF2802AB4072A7EB32A2D60247C0B7E132A2E7E172A2F753173127C157A0131127C157A1131127C15127B5F400302766F027B297EB32A2CB40BF675317D127C157EB32A2E7EA32A304CAB78E480DF7EB32A2CB40ADB75317E127C157EB32A2E70CFF5F375F60122027B29027B29027B297EB32A2CB404207531C3127C157E0400017E172A2D7E182A3C7A1C00007E472A31127C21027AC8B4063A7531C1127C157E5800007A5C00FE7DCA7ED72A2D7E782A3C7A7C00007E772A317531C1127C15C0A8C087C2AFA9D587127C5AD087D0A8404F804AB4001CC2AFA9D58712766FE48DEF8DEF8DEFD5E0F7C0D1CA02FFCA06000032B409127E572A2D4D556805A9D2B18003A9C2B18016B40716C2AF7E072A2F7E172A2DC0D1CA18CA38CA283202766F027B297EB32A2CB403157531C2127C157E0400017E172A2D7E572A31027673B405397531C0127C15C0A8C087C2AFA9D5877E082A3C7A0C00007E2400FE7E372A2D7E472A31127C21D087D0A87E082A3C7A0C00007E572A31027673027B29753107127C1543E1C022C0A8C087C2AFA9D587127B9E40197E082A3C7A0C0000CA0BCA49127C21DA59DA0BD087D0A8C322D087D0A822C0A8C087C2AFA9D587127B9E402B7E5800007A5C00FE7F617E782A3C7A7C00007E772A31BD7478117531C1127C15127C5A4006D087D0A8C322D087D0A8D3227E2400FE7E347FCA0B1A50C5F07D627D757D877E347FC27E1BB07E347F03B401047E347FCC7E1BB0BC0B50493E003E000A502D750B3A3069530002BD3850022D38BC1B50303E103E100A512D35694100020B1A30BD3850022D38BE44FFFF78057E1B900A494D44680CBE4400FF28047E4400FFC322D322FA
-:00047FC60001100400A2
-:014A7C1500CA087E01317A033FF0DA08227E1BC07A0BC00B140B341B4478F2227F6F7FF01BFC7C547D328008CA1BCA1BCA1BCA1B9E44001050F22E4400106806CA481B4478FA7FF689E4CA6B5ED4003F68207E8400409D8DDA6BBD873816CA797D78127C84DA7940089D7868028005C2D722DA6B43903074AA39B55555745539B52AAA74A039B555557E0400409D7050062D707D076D777C317E7B007A6B000B7C0B6CA5D9F37F161B1C7E5427107E1B10BC1068061B5478F5802C6D007C207F169F107F279F207E2B007E1B10BC0178160B2C0B1CA5DBEF7CB620E0036390304D777893C2D722D2D7220004000442080604020400020104010282080000000000000202020202040208100210040208000101080001000200020208020420047E187FBD7A1C00FE0B1A005E101FBE101A381A0A51237E187CFA7A1C00FF2D350B1A506008A5B802034EA0082280FE73
-:0000000001FF
-//**************************************************************
-//* Edgeport/4 Binary Image
-//* Generated by HEX2C v1.06
-//* Copyright (C) 1998 Inside Out Networks, All rights reserved.
-//*	This program is free software; you can redistribute it and/or modify
-//*	it under the terms of the GNU General Public License as published by
-//*	the Free Software Foundation; either version 2 of the License, or
-//*	(at your option) any later version.
-//**************************************************************
--- zfcpdump-kernel-4.4.orig/firmware/edgeport/down2.H16
+++ /dev/null
@@ -1,29 +0,0 @@
-:000400000002000003F7
-:000200000400FFFB
-:00060000000200800245141D
-:0003000B000244A507
-:00030013000263ABDA
-:0003001B0002001BC5
-:0003002300020023B5
-:0003002B0002002BA5
-:000300330002003395
-:0003003B0002003B85
-:000300430002004375
-:0003004B0002004B65
-:000300530002675FE2
-:0003007B0002007B05
-:00070080007E14000002405253
-:0B663000001230641230FF12312F1230B080F2E52360197E14000009B101B9B4000280051419B101B9A50ABE212E78EB22C2AF7EB33FF1B40103126567D2AF22C2AF7EB33FF1B4011D74407AB391007EB3911A6CAA600FCA0BCA39CA59126424DA59DA39DA0BD2AF22C2AFE52260437E0701CBBE04038038397E0480007E200013502109A000044EA00519A000040A32095335335E5127680B09A000104EA00119A000102E040100A50ABE212E78D1752200D2AF22C2AFE52660367E20007E3001E526A55B68217CB2230A2B49320179BE34000068127EB121A54B7AB121CA19492230EF9924DA193E30A50ABE212E78D0D2AF22464F497C4CA94FD653035630595D5C8AC2AFE52460147E2000135007CAB812311CDAB8A50ABE212E78EFD2AF22CA2812354CDA2840090A2209B23533F4522422C2AFE52360147E2000135007CAB812314CDAB8A50ABE212E78EFD2AF227CB2230A2B492231578924316731D0323932A2330B337433DD34467E270179BE24000078247E24800009B20014CAB85EB01EDAB8680BCA197D121249457D21DA1930E6187E6000801EBE270189680D7A2701897E609C7A6301B980277E6301B9A5BE001F7E60017EB0007EA0C81261364011752FB3127335C2186C007A0301B9126486227E27017BBE24000078247E24810009B20014CAB85EB01EDAB8680BCA197D12124C727D21DA1930E6187E6000801EBE27018B680D7A27018B7E609C7A6301BA80277E6301BAA5BE001F7E60017EB0007EA0C81261364011752FB3127335C2196C007A0301BA126486227E27017DBE24000078247E24820009B20014CAB85EB01EDAB8680BCA197D12124F9F7D21DA1930E6187E6000801EBE27018D680D7A27018D7E609C7A6301BB80277E6301BBA5BE001F7E60017EB0007EA0C81261364011752FB3127335C21A6C007A0301BB126486227E27017FBE24000078247E24830009B20014CAB85EB01EDAB8680BCA197D121252CC7D21DA1930E6187E6000801EBE27018F680D7A27018F7E609C7A6301BC80277E6301BCA5BE001F7E60017EB0007EA0C81261364011752FB3127335C21B6C007A0301BC126486227E270181BE24000078247E24840009B20014CAB85EB01EDAB8680BCA197D121255F97D21DA1930E6187E6000801EBE270191680D7A2701917E609C7A6301BD80277E6301BDA5BE001F7E60017EB0007EA0C81261364011752FB3127335C21C6C007A0301BD126486227E270183BE24000078247E24850009B20014CAB85EB01EDAB8680BCA197D121259267D21DA1930E6187E6000801EBE270193680D7A2701937E609C7A6301BE80277E6301BEA5BE001F7E60017EB0007EA0C81261364011752FB3127335C21D6C007A0301BE126486227E270185BE24000078247E24860009B20014CAB85EB01EDAB8680BCA197D12125C537D21DA1930E6187E6000801EBE270195680D7A2701957E609C7A6301BF80277E6301BFA5BE001F7E60017EB0007EA0C81261364011752FB3127335C21E6C007A0301BF126486227E270187BE24000078247E24870009B20014CAB85EB01EDAB8680BCA197D12125F807D21DA1930E6187E6000801EBE270197680D7A2701977E609C7A6301C080277E6301C0A5BE001F7E60017EB0007EA0C81261364011752FB3127335C21F6C007A0301C012648622C2AF7E0701CBBE040000782874207AB391007EB3911530E51B7EB3911ABEB03F380C85312F12733574807AB3911E74207AB39115D2AF22353B36E83700371B37B6384E386938FB388438C57CB3BEB0092822752F0912733575570274207AB3910074017AB3911174407AB3910074017AB3911122C0A8C2AF236CAA2E5434E60B585089540102040810204080752FB01273350A2209B235334224D0A8227CB2230A3B4933355789343567359535C335F1361F364D367B36A91241BAD228D208C240C248C238C2306D007A0301B97E0400207A0701997E0400387A0701A9124127125FB70236D71241D7D229D209C241C249C239C2316D007A0301BA7E0400207A07019B7E0400387A0701AB124127125FE00236D71241F4D22AD20AC242C24AC23AC2326D007A0301BB7E0400207A07019D7E0400387A0701AD1241271260090236D7124211D22BD20BC243C24BC23BC2336D007A0301BC7E0400207A07019F7E0400387A0701AF1241271260320236D712422ED22CD20CC244C24CC23CC2346D007A0301BD7E0400207A0701A17E0400387A0701B112412712605B0236D712424BD22DD20DC245C24DC23DC2356D007A0301BE7E0400207A0701A37E0400387A0701B31241271260840236D7124268D22ED20EC246C24EC23EC2366D007A0301BF7E0400207A0701A57E0400387A0701B51241271260AD0236D7124285D22FD20FC247C24FC23FC2376D007A0301C07E0400207A0701A77E0400387A0701B71241271260D60236D77EA0D07E600F1261364005126486C2D722752FB11273350A52236D005905003212418312419FD0A822752FB21273350A2209B2353342237EB09C19B201B912314CD0A8227E0480004C020930000C74BF19B0000C09B000081930000C7C745E700168124440CAB809B00010440219B00010DAB8800254BF7C745E700868044408800254F70930000CCAB874BF19B0000CDAB819B000081930000C0A6209B635333E200A627C745E700268204227CAB8746119B000087E440010594601A909B00010440119B00010DAB88011F4522774A119B000087E440038594601A9D0A8227C747E0480004C020930000C74BF19B0000C09B000087C745E7001680444808002547F7C745E700868044402800254FD19B000081930000C0A6209B63533A5FDF4A5FECA283E200A62DA287C745E70026810A5ED422842267E440008594601998004A5EE52287C745E70046810A5ED422942267E440008594601998015A5EE52297C745E7002780A52267E440020594601991242A2D0A8227E0480004C020930000C74BF19B0000C194000101930000CD0A8227E0480004C020930000C74BF19B0000C194000181930000CD0A822752FB51273357E0480004C0209B0000C444019B0000CE558B4072309B000104EB00219B000100930000C74BF19B0000C09B0000454F719B000041930000CD0A822752FB61273357E0480004C02E558B407180930000C74BF19B0000C09B00004440819B000041930000C09B0000C54BF19B0000CD0A822752FB41273357A212F1273357A412F1273357EB0017EA0C87C64126136126486D0A822392E397539BC3A033A4A3A913AD83B1F752F55127335752F001273357A612F1273357A712F1273357E1701697E2701792D237E09B00B047A19B00B14BE14082C380F1B3478EC7A1701697A27017902464F7E14042D80EB752F55127335752F011273357A612F1273357A712F1273357E17016B7E27017B2D237E09B00B047A19B00B14BE140C2C380F1B3478EC7A17016B7A27017B02497C7E14082D80EB752F55127335752F021273357A612F1273357A712F1273357E17016D7E27017D2D237E09B00B047A19B00B14BE14102C380F1B3478EC7A17016D7A27017D024CA97E140C2D80EB752F55127335752F031273357A612F1273357A712F1273357E17016F7E27017F2D237E09B00B047A19B00B14BE14142C380F1B3478EC7A17016F7A27017F024FD67E14102D80EB752F55127335752F041273357A612F1273357A712F1273357E1701717E2701812D237E09B00B047A19B00B14BE14182C380F1B3478EC7A1701717A2701810253037E14142D80EB752F55127335752F051273357A612F1273357A712F1273357E1701737E2701832D237E09B00B047A19B00B14BE141C2C380F1B3478EC7A1701737A2701830256307E14182D80EB752F55127335752F061273357A612F1273357A712F1273357E1701757E2701852D237E09B00B047A19B00B14BE14202C380F1B3478EC7A1701757A27018502595D7E141C2D80EB752F55127335752F071273357A612F1273357A712F1273357E1701777E2701872D237E09B00B047A19B00B14BE14242C380F1B3478EC7A1701777A270187025C8A7E14202D80EB64
-:33354000007E0400017E147FF87E2400FE7D310B1A501B0A507E14401B0240747EF8005975B0DF7EB0017AB390007EF4403002408B12744EF52E7AA12D7A1158126B021240EB7EB33FF16003124379126BDED2AF0230007E0400FF7E1840607A1C000189187EB0017AB394007AB32C357EB0017AB3930089087E0400FF7E1840827A1C000189187EB0007AB3930089087E0800207E4404007E40007EE4409D0273507E0801597E442ADD7E40007EE440AF0273507E0800597E4401007E40537EE440C10273507557017556007E040008755458755508755108755301758901758A01758C00D28C7E0400027A054289F475B77F75B87F75B30175B201D2A92275B0DFE4D5E0FD75B0EF7E2480007E112E7EA00819A200102E240100A5D9F27E20001241830B20BE212E78F6227E0480004C0274BF19B0000C741019B00008748019B0000C7E54000219A0000419B00000740319B0000C7407206802740F19B00004306B1774BF19B0000C7428206802742019B00004740319B0000C74A719B00008740C19B00010227E0480004C02E419B0000409B00010540819B0001074A719B00008227CB2230A2B492241AA892441BA41D741F44211422E424B42684285C210C218C2087E04042D7A0701597A0701696D007A0701797A07018922C211C219C2097E04082D7A07015B7A07016B6D007A07017B7A07018B22C212C21AC20A7E040C2D7A07015D7A07016D6D007A07017D7A07018D22C213C21BC20B7E04102D7A07015F7A07016F6D007A07017F7A07018F22C214C21CC20C7E04142D7A0701617A0701716D007A0701817A07019122C215C21DC20D7E04182D7A0701637A0701736D007A0701837A07019322C216C21EC20E7E041C2D7A0701657A0701756D007A0701857A07019522C217C21FC20F7E04202D7A0701677A0701776D007A0701877A070197227CB2230A2B492242AD892442BD42D442EB4302431943304347435E304007205804C228800C304807205004C2288002D22822304107205904C229800C304907205104C2298002D22922304207205A04C22A800C304A07205204C22A8002D22A22304307205B04C22B800C304B07205304C22B8002D22B22304407205C04C22C800C304C07205404C22C8002D22C22304507205D04C22D800C304D07205504C22D8002D22D22304607205E04C22E800C304E07205604C22E8002D22E22304707205F04C22F800C304F07205704C22F8002D22F224466438ABEB002400122230A5B495543759954D3227EB0007AB394007AB32C3512447A7E04282D7A0701C17A0701C37E04242D7A0701C77A0701C97E04667F7A054B74207AB3910074607AB3911C74127AB3910674407AB39107741E7AB3911074487AB3911274107AB39113743F7AB3911474407AB3910074607AB3911C74147AB3910674407AB3910774167AB3911074087AB3911174207AB39113743F7AB3911474607AB3910074607AB3911C74167AB3910674207AB39107742F7AB3911074487AB3911274107AB39113743F7AB3911474027AB39106740F7AB391071240FA7E200012419F0B20BE212E78F6D2A8227EB0017AB394007AB32C3512447A75B0DFC2A82274027AB3910674017AB391077E20047CB2C2D7131313137AB3910074607AB3911C74027AB39112A5DAE522CA0912300E100134D5514074007AB3910074027AB391067EB3910774037AB391067EB391077EB391147EB391046353017E00542E0153A5E6F551801220021D755300855451D2027403800D30020EC2027E00562E0153A5E67AB39000DA0932456F458B45A745C345DF45FB46174633C0D0C0D1C0E0C0F0CA0BCA1BCA2BD201752F891273357EB3900060287E1480007E0000135013CA0BCA597CB0230A2B492245049924DA59DA0BA50AA508BE012E78E180D2300405C204126486DA2BDA1BDA0BD0F0D0E0D0D1D0D03209B1000820E014752F80127335543E0A5B7E4400FF695261AB89542209B1000820E014752F81127335543E0A5B7E4400FF695261EB89542209B1000820E014752F82127335543E0A5B7E4400FF6952622B89542209B1000820E014752F83127335543E0A5B7E4400FF6952626B89542209B1000820E014752F84127335543E0A5B7E4400FF695262AB89542209B1000820E014752F85127335543E0A5B7E4400FF695262EB89542209B1000820E014752F86127335543E0A5B7E4400FF6952632B89542209B1000820E014752F87127335543E0A5B7E4400FF6952636B89542210080122202803D20822752FA01273357E1480008006202803D2082209B10014CAB85EB01EDAB8680312494530300620E64FD2082230E602D2607E3701797E2701999D3240317D022E05327A05327A3701797E3701597D432D42BE44082C38687A470159752F941273357A512F1273351269F01060C422C2602D2368786D33801A7E270179BE240000686ABE27019928047E2701997E3701799D327D022E05327A05327A3701797E3701597D432D42BE44082C38137A470159752F941273357A512F1273350269F0752F941273357A512F1273359E44082D9D241269F07E34042D7D242D437A4701591269F0BE252078030246C222D2087E04042D7A0701597A070169752F94127335752F0012733522752F92127335D20409B10014CAB85482DAB878687E3701CB7E2701A92E2400022D32BE34040038347D022E05307A05307A3701CB7E3701C97D432D42BE44282C383C7A4701C97E2400002E2701A91B38200B357A512F127335026A63752F9912733509B1000454FA19B1000430380A09B1001054FE19B10010D21022807F7A512F1273359E44282D9D247E6400002E6701A99E24000240171B38600B35126A637E34242D7D242D437A4701C9026A637A39C07E34242D7A39D00B341B4480E59D327CB6540F23232344007A69B07A79700B35752F931273357A712F127335BD04682B7A0701C97E4701CB2D437A4701CB2E35307A353022D20409B1001420E013227E04242D80287E04242D802A7E04242D80CF7E0701CB7E2403FE9D2028407E0701C97E44282D7D600B04BD0468D27D700B04BD0468D07D549D50BD2540027D257D3209B10014CAB8541FB40131DAB87E19B07A09B00B041B2478E702481E752F9912733509B1000454FA19B1000430380A09B1001054FE19B10010D21022DAB830E0D8BD326807CAB812481EDAB802494509B100187EA088752F90127335F52F127335A5FD5E500A681DA5FD5E50206804D2588002C258A5FD5E50806804D2508002C2501242BD026113752F9112733509B100147AB12F12733520E008D2047EA080026113D20430E1067EA080126113CAB85EB01CDAB868127EA0C00961000012613609B1001420E0DB22024872752F9512733522752F961273352210090122202903D20922752FA11273357E1481008006202903D2092209B10014CAB85EB01EDAB86803124C7230310620E64FD2092230E602D2617E37017B7E27019B9D3240317D022E05347A05347A37017B7E37015B7D432D42BE440C2C38687A47015B752F941273357A512F1273351269F01061C422C2612D2368786D33801A7E27017BBE240000686ABE27019B28047E27019B7E37017B9D327D022E05347A05347A37017B7E37015B7D432D42BE440C2C38137A47015B752F941273357A512F1273350269F0752F941273357A512F1273359E440C2D9D241269F07E34082D7D242D437A47015B1269F0BE252078030249EF22D2097E04082D7A07015B7A07016B752F94127335752F0012733522752F92127335D20409B10014CAB85482DAB878687E3701CB7E2701AB2E2400022D32BE34040038347D022E05307A05307A3701CB7E3701C97D432D42BE44282C383C7A4701C97E2401002E2701AB1B38200B357A512F127335026A63752F9912733509B1000454FA19B1000430390A09B1001054FE19B10010D21122807F7A512F1273359E44282D9D247E6401002E6701AB9E24000240171B38600B35126A637E34242D7D242D437A4701C9026A637A39C07E34242D7A39D00B341B4480E59D327CB6540F23232344017A69B07A79700B35752F931273357A712F127335BD04682B7A0701C97E4701CB2D437A4701CB2E35307A353022D20409B1001420E013227E04242D80287E04242D802A7E04242D80CF7E0701CB7E2403FE9D2028407E0701C97E44282D7D600B04BD0468D27D700B04BD0468D07D549D50BD2540027D257D3209B10014CAB8541FB40131DAB87E19B07A09B00B041B2478E7024B4B752F9912733509B1000454FA19B1000430390A09B1001054FE19B10010D21122DAB830E0D8BD326807CAB8124B4BDAB8024C7209B100187EA088752F90127335F52F127335A5FD5E500A681DA5FD5E50206804D2598002C259A5FD5E50806804D2518002C2511242D4026113752F9112733509B100147AB12F12733520E008D2047EA080026113D20430E1067EA080126113CAB85EB01CDAB868127EA0C00961000012613609B1001420E0DB22024B9F752F9512733522752F9612733522100A0122202A03D20A22752FA21273357E1482008006202A03D20A2209B10014CAB85EB01EDAB86803124F9F30320620E64FD20A2230E602D2627E37017D7E27019D9D3240317D022E05367A05367A37017D7E37015D7D432D42BE44102C38687A47015D752F941273357A512F1273351269F01062C422C2622D2368786D33801A7E27017DBE240000686ABE27019D28047E27019D7E37017D9D327D022E05367A05367A37017D7E37015D7D432D42BE44102C38137A47015D752F941273357A512F1273350269F0752F941273357A512F1273359E44102D9D241269F07E340C2D7D242D437A47015D1269F0BE25207803024D1C22D20A7E040C2D7A07015D7A07016D752F94127335752F0012733522752F92127335D20409B10014CAB85482DAB878687E3701CB7E2701AD2E2400022D32BE34040038347D022E05307A05307A3701CB7E3701C97D432D42BE44282C383C7A4701C97E2402002E2701AD1B38200B357A512F127335026A63752F9912733509B1000454FA19B10004303A0A09B1001054FE19B10010D21222807F7A512F1273359E44282D9D247E6402002E6701AD9E24000240171B38600B35126A637E34242D7D242D437A4701C9026A637A39C07E34242D7A39D00B341B4480E59D327CB6540F23232344027A69B07A79700B35752F931273357A712F127335BD04682B7A0701C97E4701CB2D437A4701CB2E35307A353022D20409B1001420E013227E04242D80287E04242D802A7E04242D80CF7E0701CB7E2403FE9D2028407E0701C97E44282D7D600B04BD0468D27D700B04BD0468D07D549D50BD2540027D257D3209B10014CAB8541FB40131DAB87E19B07A09B00B041B2478E7024E78752F9912733509B1000454FA19B10004303A0A09B1001054FE19B10010D21222DAB830E0D8BD326807CAB8124E78DAB8024F9F09B100187EA088752F90127335F52F127335A5FD5E500A681DA5FD5E50206804D25A8002C25AA5FD5E50806804D2528002C2521242EB026113752F9112733509B100147AB12F12733520E008D2047EA080026113D20430E1067EA080126113CAB85EB01CDAB868127EA0C00961000012613609B1001420E0DB22024ECC752F9512733522752F9612733522100B0122202B03D20B22752FA31273357E1483008006202B03D20B2209B10014CAB85EB01EDAB868031252CC30330620E64FD20B2230E602D2637E37017F7E27019F9D3240317D022E05387A05387A37017F7E37015F7D432D42BE44142C38687A47015F752F941273357A512F1273351269F01063C422C2632D2368786D33801A7E27017FBE240000686ABE27019F28047E27019F7E37017F9D327D022E05387A05387A37017F7E37015F7D432D42BE44142C38137A47015F752F941273357A512F1273350269F0752F941273357A512F1273359E44142D9D241269F07E34102D7D242D437A47015F1269F0BE2520780302504922D20B7E04102D7A07015F7A07016F752F94127335752F0012733522752F92127335D20409B10014CAB85482DAB878687E3701CB7E2701AF2E2400022D32BE34040038347D022E05307A05307A3701CB7E3701C97D432D42BE44282C383C7A4701C97E2403002E2701AF1B38200B357A512F127335026A63752F9912733509B1000454FA19B10004303B0A09B1001054FE19B10010D21322807F7A512F1273359E44282D9D247E6403002E6701AF9E24000240171B38600B35126A637E34242D7D242D437A4701C9026A637A39C07E34242D7A39D00B341B4480E59D327CB6540F23232344037A69B07A79700B35752F931273357A712F127335BD04682B7A0701C97E4701CB2D437A4701CB2E35307A353022D20409B1001420E013227E04242D80287E04242D802A7E04242D80CF7E0701CB7E2403FE9D2028407E0701C97E44282D7D600B04BD0468D27D700B04BD0468D07D549D50BD2540027D257D3209B10014CAB8541FB40131DAB87E19B07A09B00B041B2478E70251A5752F9912733509B1000454FA19B10004303B0A09B1001054FE19B10010D21322DAB830E0D8BD326807CAB81251A5DAB80252CC09B100187EA088752F90127335F52F127335A5FD5E500A681DA5FD5E50206804D25B8002C25BA5FD5E50806804D2538002C253124302026113752F9112733509B100147AB12F12733520E008D2047EA080026113D20430E1067EA080126113CAB85EB01CDAB868127EA0C00961000012613609B1001420E0DB220251F9752F9512733522752F9612733522100C0122202C03D20C22752FA41273357E1484008006202C03D20C2209B10014CAB85EB01EDAB868031255F930340620E64FD20C2230E602D2647E3701817E2701A19D3240317D022E053A7A053A7A3701817E3701617D432D42BE44182C38687A470161752F941273357A512F1273351269F01064C422C2642D2368786D33801A7E270181BE240000686ABE2701A128047E2701A17E3701819D327D022E053A7A053A7A3701817E3701617D432D42BE44182C38137A470161752F941273357A512F1273350269F0752F941273357A512F1273359E44182D9D241269F07E34142D7D242D437A4701611269F0BE2520780302537622D20C7E04142D7A0701617A070171752F94127335752F0012733522752F92127335D20409B10014CAB85482DAB878687E3701CB7E2701B12E2400022D32BE34040038347D022E05307A05307A3701CB7E3701C97D432D42BE44282C383C7A4701C97E2404002E2701B11B38200B357A512F127335026A63752F9912733509B1000454FA19B10004303C0A09B1001054FE19B10010D21422807F7A512F1273359E44282D9D247E6404002E6701B19E24000240171B38600B35126A637E34242D7D242D437A4701C9026A637A39C07E34242D7A39D00B341B4480E59D327CB6540F23232344047A69B07A79700B35752F931273357A712F127335BD04682B7A0701C97E4701CB2D437A4701CB2E35307A353022D20409B1001420E013227E04242D80287E04242D802A7E04242D80CF7E0701CB7E2403FE9D2028407E0701C97E44282D7D600B04BD0468D27D700B04BD0468D07D549D50BD2540027D257D3209B10014CAB8541FB40131DAB87E19B07A09B00B041B2478E70254D2752F9912733509B1000454FA19B10004303C0A09B1001054FE19B10010D21422DAB830E0D8BD326807CAB81254D2DAB80255F909B100187EA088752F90127335F52F127335A5FD5E500A681DA5FD5E50206804D25C8002C25CA5FD5E50806804D2548002C254124319026113752F9112733509B100147AB12F12733520E008D2047EA080026113D20430E1067EA080126113CAB85EB01CDAB868127EA0C00961000012613609B1001420E0DB22025526752F9512733522752F9612733522100D0122202D03D20D22752FA51273357E1485008006202D03D20D2209B10014CAB85EB01EDAB8680312592630350620E64FD20D2230E602D2657E3701837E2701A39D3240317D022E053C7A053C7A3701837E3701637D432D42BE441C2C38687A470163752F941273357A512F1273351269F01065C422C2652D2368786D33801A7E270183BE240000686ABE2701A328047E2701A37E3701839D327D022E053C7A053C7A3701837E3701637D432D42BE441C2C38137A470163752F941273357A512F1273350269F0752F941273357A512F1273359E441C2D9D241269F07E34182D7D242D437A4701631269F0BE252078030256A322D20D7E04182D7A0701637A070173752F94127335752F0012733522752F92127335D20409B10014CAB85482DAB878687E3701CB7E2701B32E2400022D32BE34040038347D022E05307A05307A3701CB7E3701C97D432D42BE44282C383C7A4701C97E2405002E2701B31B38200B357A512F127335026A63752F9912733509B1000454FA19B10004303D0A09B1001054FE19B10010D21522807F7A512F1273359E44282D9D247E6405002E6701B39E24000240171B38600B35126A637E34242D7D242D437A4701C9026A637A39C07E34242D7A39D00B341B4480E59D327CB6540F23232344057A69B07A79700B35752F931273357A712F127335BD04682B7A0701C97E4701CB2D437A4701CB2E35307A353022D20409B1001420E013227E04242D80287E04242D802A7E04242D80CF7E0701CB7E2403FE9D2028407E0701C97E44282D7D600B04BD0468D27D700B04BD0468D07D549D50BD2540027D257D3209B10014CAB8541FB40131DAB87E19B07A09B00B041B2478E70257FF752F9912733509B1000454FA19B10004303D0A09B1001054FE19B10010D21522DAB830E0D8BD326807CAB81257FFDAB802592609B100187EA088752F90127335F52F127335A5FD5E500A681DA5FD5E50206804D25D8002C25DA5FD5E50806804D2558002C255124330026113752F9112733509B100147AB12F12733520E008D2047EA080026113D20430E1067EA080126113CAB85EB01CDAB868127EA0C00961000012613609B1001420E0DB22025853752F9512733522752F9612733522100E0122202E03D20E22752FA61273357E1486008006202E03D20E2209B10014CAB85EB01EDAB86803125C5330360620E64FD20E2230E602D2667E3701857E2701A59D3240317D022E053E7A053E7A3701857E3701657D432D42BE44202C38687A470165752F941273357A512F1273351269F01066C422C2662D2368786D33801A7E270185BE240000686ABE2701A528047E2701A57E3701859D327D022E053E7A053E7A3701857E3701657D432D42BE44202C38137A470165752F941273357A512F1273350269F0752F941273357A512F1273359E44202D9D241269F07E341C2D7D242D437A4701651269F0BE252078030259D022D20E7E041C2D7A0701657A070175752F94127335752F0012733522752F92127335D20409B10014CAB85482DAB878687E3701CB7E2701B52E2400022D32BE34040038347D022E05307A05307A3701CB7E3701C97D432D42BE44282C383C7A4701C97E2406002E2701B51B38200B357A512F127335026A63752F9912733509B1000454FA19B10004303E0A09B1001054FE19B10010D21622807F7A512F1273359E44282D9D247E6406002E6701B59E24000240171B38600B35126A637E34242D7D242D437A4701C9026A637A39C07E34242D7A39D00B341B4480E59D327CB6540F23232344067A69B07A79700B35752F931273357A712F127335BD04682B7A0701C97E4701CB2D437A4701CB2E35307A353022D20409B1001420E013227E04242D80287E04242D802A7E04242D80CF7E0701CB7E2403FE9D2028407E0701C97E44282D7D600B04BD0468D27D700B04BD0468D07D549D50BD2540027D257D3209B10014CAB8541FB40131DAB87E19B07A09B00B041B2478E7025B2C752F9912733509B1000454FA19B10004303E0A09B1001054FE19B10010D21622DAB830E0D8BD326807CAB8125B2CDAB8025C5309B100187EA088752F90127335F52F127335A5FD5E500A681DA5FD5E50206804D25E8002C25EA5FD5E50806804D2568002C256124347026113752F9112733509B100147AB12F12733520E008D2047EA080026113D20430E1067EA080126113CAB85EB01CDAB868127EA0C00961000012613609B1001420E0DB22025B80752F9512733522752F9612733522100F0122202F03D20F22752FA71273357E1487008006202F03D20F2209B10014CAB85EB01EDAB86803125F8030370620E64FD20F2230E602D2677E3701877E2701A79D3240317D022E05407A05407A3701877E3701677D432D42BE44242C38687A470167752F941273357A512F1273351269F01067C422C2672D2368786D33801A7E270187BE240000686ABE2701A728047E2701A77E3701879D327D022E05407A05407A3701877E3701677D432D42BE44242C38137A470167752F941273357A512F1273350269F0752F941273357A512F1273359E44242D9D241269F07E34202D7D242D437A4701671269F0BE25207803025CFD22D20F7E04202D7A0701677A070177752F94127335752F0012733522752F92127335D20409B10014CAB85482DAB878687E3701CB7E2701B72E2400022D32BE34040038347D022E05307A05307A3701CB7E3701C97D432D42BE44282C383C7A4701C97E2407002E2701B71B38200B357A512F127335026A63752F9912733509B1000454FA19B10004303F0A09B1001054FE19B10010D21722807F7A512F1273359E44282D9D247E6407002E6701B79E24000240171B38600B35126A637E34242D7D242D437A4701C9026A637A39C07E34242D7A39D00B341B4480E59D327CB6540F23232344077A69B07A79700B35752F931273357A712F127335BD04682B7A0701C97E4701CB2D437A4701CB2E35307A353022D20409B1001420E013227E04242D80287E04242D802A7E04242D80CF7E0701CB7E2403FE9D2028407E0701C97E44282D7D600B04BD0468D27D700B04BD0468D07D549D50BD2540027D257D3209B10014CAB8541FB40131DAB87E19B07A09B00B041B2478E7025E59752F9912733509B1000454FA19B10004303F0A09B1001054FE19B10010D21722DAB830E0D8BD326807CAB8125E59DAB8025F8009B100187EA088752F90127335F52F127335A5FD5E500A681DA5FD5E50206804D25F8002C25FA5FD5E50806804D2578002C25712435E026113752F9112733509B100147AB12F12733520E008D2047EA080026113D20430E1067EA080126113CAB85EB01CDAB868127EA0C00961000012613609B1001420E0DB22025EAD752F9512733522752F96127335227C027E1480004C2009B10018A5FD5E50206804D2588002C258A5FD5E50806804D2508002C2500260FF7C027E1480004C2009B10018A5FD5E50206804D2598002C259A5FD5E50806804D2518002C2510260FF7C027E1480004C2009B10018A5FD5E50206804D25A8002C25AA5FD5E50806804D2528002C2520260FF7C027E1480004C2009B10018A5FD5E50206804D25B8002C25BA5FD5E50806804D2538002C2530260FF7C027E1480004C2009B10018A5FD5E50206804D25C8002C25CA5FD5E50806804D2548002C2540260FF7C027E1480004C2009B10018A5FD5E50206804D25D8002C25DA5FD5E50806804D2558002C2550260FF7C027E1480004C2009B10018A5FD5E50206804D25E8002C25EA5FD5E50806804D2568002C2560260FF7C027E1480004C2009B10018A5FD5E50206804D25F8002C25FA5FD5E50806804D2578002C2570260FF54F0C4A5FFC4A54F752F90127335F52F12733522CA195E20074CA27E742C2DCA797A79A00B747A79B00B74DA797E30027E64000202615ECA195E20074CA27E742C2DCA797A79A00B747A79B00B747A79600B74DA797E30037E64000302615ED2047E2701CB2D26BE240400382E7E0701C97E44282D7E79A07A09A00B040B74BD046823A5DBEF7A2701CB7E25302D267A25307A0701C9DA19C2D722752F9A127335DA19D2D7227E04242D80D748F14665475F492A452A452A4856452A496E452A452A452A452A452A452A452A4975452A452A452A452A452A452A452A452A452A452A452A452A452A452A452A4C1E49924A8C4C57452A452A4B83452A4C9B452A452A452A452A452A452A452A4CA2452A452A452A452A452A452A452A452A452A452A452A452A452A452A452A4F4B4CBF4DB94F84452A452A4EB0452A4FC8452A452A452A452A452A452A452A4FCF452A452A452A452A452A452A452A452A452A452A452A452A452A452A452A52784FEC50E652B1452A452A51DD452A52F5452A452A452A452A452A452A452A52FC452A452A452A452A452A452A452A452A452A452A452A452A452A452A452A55A55319541355DE452A452A550A452A5622452A452A452A452A452A452A452A5629452A452A452A452A452A452A452A452A452A452A452A452A452A452A452A58D256465740590B452A452A5837452A594F452A452A452A452A452A452A452A5956452A452A452A452A452A452A452A452A452A452A452A452A452A452A452A5BFF59735A6D5C38452A452A5B64452A5C7C452A452A452A452A452A452A452A5C83452A452A452A452A452A452A452A452A452A452A452A452A452A452A452A5F2C5CA05D9A5F65452A452A5E91452A5FA9452A452A452A452A452A452A452A5FB0452A452A452A452A452A452A452A452A452A452A452A452A452A452A452ACAB8752F021273357EB3910320E52030E005126B05803030E105126486802830E2051263F5802030E31D12656180187EB3910430E10302675F30E605126C6A800620E203020080DAB832752F10127335CA0BCA39CA5974407AB391007EB3911A6CAABEB040280A126424DA59DA39DA0B2274207AB3911480F17E3701C52D35BE340400382F7A3701C57E3701C37D432D45BE442C2C38257A4701C3752F111273357AB12F12733512679F74207AB3911412663022752F1612733580F4752F121273357AB12F1273359E442C2D9D5412679F7E34282D7D542D4380BC752F18127335CA09CA39CA2B74207AB391007E63911A74107AB391147EB0809CB660386CAA7E3701CB9D3540377A3701CB7E3701C77D432D45BE44282C383B7A4701C77D451268D47EB3911E20E513752F191273357A912F127335DA2BDA39DA092280342D536D33600280C17E04242D7A0701C97A0701C780E1CA599E44282D9D541268D47E34242D7D542D437A4701C71268D4DA4980B07E0F2C3E0B0C7A0F2C3E74207AB3911E74607AB3911C74027AB3911280A57E2F2C5E0B2C7A2F2C5E74207AB3911E74607AB3911C74027AB39112801FDA2BDA1BDA0B22752F28127335CA0BCA1BCA2B74607AB3910074107AB391147EB3911A70DB7E0D307E1D347E2D387E3D3C7E85407D904D914D924D934D944D954D964D974D9868B87A1391177A0391177A3391177A2391177A5391177A4391177A7391177A6391177A9391177A8391173073227AB391177AA391177AD391177AC391177AF391177AE391177D787AF391177AE391177EB3911E30E50302653C752F29127335207308752F0A1273358006752F1212733574807AB3911E6D007D107A0D307A0D347A0D387A0D3C7A0540DA2BDA1BDA0B227E3701C54D33683B7E0701C17E542C2D9D50BD3540027D35CA397E654B9964DA397E0701C59D037A0701C52E3701C17A3701C1BE342C2C28C77E34282D7A3701C180BD22752F531273357E154D8011752F511273350B08100B059E340002284D7CB220E7275407230A2B4922391E7CB254780303037C2B9D13401A68127A154D7A254F7E6467097A654B89240267177E64667F80F22D139D31CA397D312D10CA19CA299924DA29DA09DA3980A27A154D7E6466F54D3378097CB220E72A7E6466747A654B22752F521273357E214D7E09300B041B34788980D4752F541273357E154D7E254F80905E200754787E44677D30E6164D3368261B347E09400B047E4434FA20E3047E446785CA09CA399944DA39DA097E64667F4D3368A689647A154DF54F7E64675880997E154DE54F80C4C0D0C0D1C0E0CA19752FFE1273357E140053024052DA19D0E0D0D1D0D03203A5CB19B1800022227E2400007FE17EA002A47E0468B19D057EB0287AB395008904CA29B480E27E2400007FE17E00287A039500E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A37E00007A039500DA29227E2400007FE17EA002A47E0469E69D057EB0387AB395008904CA29B480E27E2400007FE17E00387A039500E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A37E00007A039500DA2922CA29CA19CA587E2400007FE1DA587E5402209CB5A47E50305E20072C527A5395002E546A178954E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A37E00007A039500DA19DA2922CA19CA587E2400007FE1DA587E5402389CB5A47E50205E20072C527A5395002E546A888954E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A37E00007A039500DA1922026BA8CA0BCA1BCA2BCA3BCA4BCA5BCA6BCA7BCAEB74007AB391007EB32C7FB40002801CB401197EB3911454146805126B6C80237EB3911430E51C126CAA80177EB3911430E505126CAA800B7EB3911454146803126B6CDAEBDA7BDA6BDA5BDA4BDA3BDA2BDA1BDA0B2220E419752F0A1273357EB32C7E700A7EB32C7FB4011F026C040271F2752F0B12733574147AB391147EB32C7FB4020C126BB4026BA874047AB39114227E00007A032C7F7A032C80227EB32C7654606005B4401E801C7EB32C77B40515752F711273357EB32C797EA0017AA391067AB391072274007AB3910074107AB3911222BE572C7C28047E572C7C7A0F2C827A572C8674107AB391122274007AB391007EB3911A70537EB3911420E44C7EEF2C827EF72C867E072C864D0068217E0000E07AB39117A3A5081BF46806A5B810F080197EB0007AB32C7FBE0010680D7EB0007AB32C7F74807AB3911E7AEF2C827AF72C86752F0612733574047AB3911422CA0BCA1BCA2BCA3BCA4BCA5BCA6BCA7BCAEB752F0312733574007AB32C7E74007AB3910074017AB39112126D19DAEBDA7BDA6BDA5BDA4BDA3BDA2BDA1BDA0B22752F031273357EB32C80B4021174007AB32C807AB32C7F74207AB3911422B401467EB3910420E6427E23911A7C327E132C812C217A232C817E00002E042C887EB391167A09B00B04A5DBF474207AB39114752F701273357EB32C817EA32C7DBCAB7803126DB9220271F2DA59026C7C74E07AB391007E0391107E1391117E3391127E2391137E5391147E4391157E7391167E6391177A0F2C767A1F2C7A752F041273357A012F1273357A112F1273357A212F1273357A312F1273357A412F1273357A512F1273357A612F1273357A712F12733574007AB3910074407AB39104126D8D226D007E1401027A072C867A032C817EB32C7620E70F7A232C807A332C7FBE072C7C6809227A332C807A232C7F7EB32C7654E3232330E002D2E530E702D2E430E50630E4030271F2543EF5F003541FC325F0906DE57584FF73026FA0026E2D027039027054026F37026EC202708502708502708802708802708802708802708802708802708802708802708E02716002708B02708B02708B02708B02708B02708B74007AB3910074607AB3911C7EB32C77B4062A7EB32C7860797C0B7E132C797E172C7A752F721273357A012F1273357A112F1273351272374058026BEBB4081C752F741273357EB33FF17E082C887A0C00007A0BB07E540001026BEBB40033752F751273357E082C887A0C0000CA0B7EB33FF230E00774027A0BB0800574007A0BB00B1474007A0BB07E540002DA0B026BEB0271F274007AB3910074607AB3911C7EB32C77B4005F752F761273357EB32C7B540FB402057EB0608017B400057EB000800F7EB32C7B20E7057EB04080037EB0207AB391007EB3911130E0047401800274007E082C887A0C0000CA0B7A0BB00B1474007A0BB074007AB391007E540002DA0B026BEB0271F27EB32C7B540FB402057EB0608017B400057EB000800F7EB32C7B20E7057EB04080037EB0207AB391007EB32C79B400267EB32C77B4010E752F7712733574017AB39112801BB4030E752F7812733574017AB39111800A74007AB391001271F22274007AB39100026BDE7EB32C77B4091F752F791273357EB32C79BEB33FF1680DCAB8124379DAB850767AB33FF1806DB40508752F7A1273358062B40319752F7B1273357EB32C79B401557EB33FF244017AB33FF28046B40119752F7C1273357EB32C79B401397EB33FF254FE7AB33FF2802AB4072A7EB32C7860247C0B7E132C797E172C7A752F731273357A012F1273357A112F1273351272714003026BDE0271F27EB32C77B40BF6752F7D1273357EB32C797EA32C7B4CAB78E480DF74007AB3910074607AB3911C7EB32C77B40ACF752F7E1273357EB32C7970C37E082C887A0C00007A0BB07E540001026BEB0271F20271F20271F27EB32C77B40420752FC31273357E0400017E172C787E182C887A1C00007E472C7C12734102715AB40642752FC11273357E5800007A5C00FE7DCA7ED72C787E782C887A7C00007E772C7C752FC1127335C0A8C2AF7E40017A43940012737A7E432C357A439400D0A840658060B40024C2AF7EB0017AB394007AB32C35126BDEE48DEF8DEF8DEFD5E0F7C0D1CA02FFCA06000032B4092074037AB391067E2391077E572C784D5568054E200280035E20FD7A2391078016B40716C2AF7E072C7A7E172C78C0D1CA18CA38CA2832026BDE0271F274007AB3910074607AB3911C7EB32C77B40315752FC21273357E0400017E172C787E572C7C026BEBB40541752FC0127335C0A8C2AF7E40017A4394007E082C887A0C00007E2400FE7E372C787E472C7C1273417E432C357A439400D0A87E082C887A0C00007E572C7C026BEBB401207E00007E1001752F721273357A012F1273357A112F1273351272374003026BEB0271F2752F071273357EB0027AB3900074007AB3910074407AB3911574017AB391117EB391155460BEB040680874207AB3911580ED74017AB3911274047AB3911474FF7AB32C7E22C0A8C2AF7E40017A4394001272BE401F7E082C887A0C0000CA0BCA49127341DA59DA0B7E432C357A439400D0A8C3227E432C357A439400D0A822C0A8C2AF7E40017A4394001272BE40317E5800007A5C00FE7F617E782C887A7C00007E772C7CBD747817752FC112733512737A400C7E432C357A439400D0A8C3227E432C357A439400D0A8D3227E2400FE7E347FCA0B1A50C5F07D627D757D877E347FC27E1BB07E347F03B401047E347FCC7E1BB0BC0B50493E003E000A502D750B3A3069530002BD3850022D38BC1B50303E103E100A512D35694100020B1A30BD3850022D38BE44FFFF78057E1B900A494D44680CBE4400FF28047E4400FFC322D32274
-:00047FC60002000300B2
-:0148733500CA087E012F7A033FF0DA08227E1BC07A0BC00B140B341B4478F2227F6F7FF01BFC7C547D328008CA1BCA1BCA1BCA1B9E44001050F22E4400106806CA481B4478FA7FF689E4CA6B5ED4003F68207E8400409D8DDA6BBD873816CA797D781273A4DA7940089D7868028005C2D722DA6B7EC0037ED0007AD3900074AA39B55555745539B52AAA74A039B555557E0400409D7050062D707D076D777C317E7B007A6B000B7C0B6CA5D9F37F161B1C7E5427107E1B10BC1068061B5478F5802F6D007C207F169F107F279F207E2B007E1B10BC0178190B2C0B1CA5DBEF7CB620E0066CDC7AD390004D777890C2D722D2D7220004000400000604020400020104010200000000000000000202020202040008100210040208000101087E187FBD7A1C00FE0B1A005E101FBE1014381A0A51237E1874247A1C00FF2D350B1A506008A5B802034EA0082280FECB
-:0000000001FF
-//**************************************************************
-//* Edgeport/4 Binary Image
-//* Generated by HEX2C v1.06
-//* Copyright (C) 1998 Inside Out Networks, All rights reserved.
-//*	This program is free software; you can redistribute it and/or modify
-//*	it under the terms of the GNU General Public License as published by
-//*	the Free Software Foundation; either version 2 of the License, or
-//*	(at your option) any later version.
-//**************************************************************
--- zfcpdump-kernel-4.4.orig/firmware/edgeport/down3.bin.ihex
+++ /dev/null
@@ -1,815 +0,0 @@
-:100000000450000087329A0227BF0221B20000008C
-:10001000000002001E0000000000000000000000C0
-:10002000000002011A853F8C85408AC0E0C0D0C024
-:10003000F0C082C083C000C001C002C003C004C0C1
-:1000400005C006C007E53E2408F8E6602BE53E241F
-:1000500010F8A681E53E75F021A42405F582E4346C
-:10006000F8F583788CE58104C398F9942240030263
-:1000700011DCE6F008A3D9FA7408253EF8053E081D
-:10008000E65480700CE53EB407F37808753E0080B6
-:10009000EFE53E2410F88681E53E75F021A42405A5
-:1000A000F582E434F8F583788CE58104C398F9E0AF
-:1000B000F608A3D9FAD007D006D005D004D003D0D3
-:1000C00002D001D000D083D082D0F0D0D0D0E032A6
-:1000D00030014D30B44810004590FF08E05420F83E
-:1000E00090FF48E05420F990FF10E05420FA90FF70
-:1000F00050E05420FB7400F58274F8F583E0C8F0FA
-:100100006860027E04A3E0C9F06960027E04A3E097
-:10011000CAF06A60027E04A3E0CBF06B60027E044A
-:1001200022C0E0C0D0C0F0C082C083C000C001C007
-:1001300002C003C004C005C006C0077415F5827470
-:10014000F9F583E060237466F58274F9F583E014B1
-:10015000F0701674FFF0741CF58274F9F583E0609A
-:100160000414F07004C29080FC90FF937481F0E559
-:100170008194FD40030211DC85418D85428B74B270
-:10018000F58274FAF583E0B4011BC082C08390FF4E
-:100190004AE030E72C90FF4EE030E725D083D08254
-:1001A0007402F08020B4021DC082C08390FF7AE008
-:1001B00030E70512284E8009D083D0827403F08086
-:1001C00004D083D082A3E0B4011BC082C08390FF1F
-:1001D00052E030E72C90FF56E030E725D083D08204
-:1001E0007402F08025B40222C082C08390FF7AE0BE
-:1001F00030E70512284E8009D083D0827403F08046
-:1002000009D083D08280030202907416F58274F9BB
-:10021000F583E02004F12002033001EB7419F5822C
-:1002200074F9F583E014FCF0A3E0FDA3E0FE6404A0
-:10023000700FEC70627E011200C97C0A7DFA020226
-:10024000611200C9EE6404601DEC704B7C0AED1471
-:10025000FD7015EE640260077E027D320202617E4F
-:10026000017DFA0202617C0A7419F58274F9F58342
-:10027000ECF0A3EDF0A3EEF014601820E10F2001E4
-:1002800006D2B1C2B08010C2B1D2B0800AC2B1C22F
-:10029000B08004D2B0D2B1781979097A07E7700436
-:1002A000A600800BE6600816E67004E74480F708B5
-:1002B00009DAEAE53D601314F53D700EE53E2408C9
-:1002C000F87600121157D28CD28DD007D006D00507
-:1002D000D004D003D002D001D000D083D082D0F09F
-:1002E000D0D0D0E03290FF04E090FAB9F090FF0651
-:1002F000E0FCA3E0FAECFFEAFEEFC39408EE940101
-:10030000500280047E017F088E3B8F3C90FF02E00C
-:10031000FCA3E0FAECFFEA90FABDF0EFA3F0121CA8
-:10032000E0E4F54DE54DC39402500F121CC1E412F8
-:100330001AE8054D04121CB280EA121CE090FF007E
-:10034000E0FF546024C070030208F32440600302FD
-:100350000F6E90FAB9E0FE540FF54DEE30E703D37F
-:100360008001C3920A90FF01E0121BFC0384000489
-:100370005701056A0306310506730607D508081DEF
-:100380000908790A08B90B00000F6EE53520E7036C
-:10039000020F6E90FABDE07002A3E06003020F6EE0
-:1003A000E53C6402453B6003020F6EEF541F14608E
-:1003B0002B14604724026003020F6EEE6003020FED
-:1003C0006E121CC17401121AE87867E630E0081258
-:1003D0001CC17402121AE87F0202326EE53520E178
-:1003E0000990FAB9E06003020F6E90FAB9E0D39475
-:1003F000014003020F6E7F0202326EE53520E10EEE
-:1004000090FAB9E0FF600764806003020F6E120F7C
-:10041000FA4003020F6EE54D7019300A0B90FF8011
-:10042000121CBE121AE8802490FF82121CBE121AFF
-:10043000E88019154D300A0B121D55121CBC121AFA
-:10044000E88009121D63121CBC121AE8121CC112AA
-:100450001AA260057401121AE87F0202326EE535B5
-:1004600030E703020F6EE53C453B6003020F6E125E
-:100470001D7914602D14605924026003020F6E90E0
-:10048000FABDE07004A3E064016003020F6E90FA0D
-:10049000B9E06003020F6E7867E654FEF6E4FF02EF
-:1004A000326EE53520E10620E003020F6EE53530BF
-:1004B000E00990FAB9E06003020F6EE53530E10C17
-:1004C00090FAB9E0D394014003020F6EE4FF0232C8
-:1004D0006E90FABDE07002A3E06003020F6E120F8F
-:1004E000FA4003020F6EE53520E10620E003020F1B
-:1004F0006EE53530E007E54D6003020F6EE54D70A7
-:100500000F90FF82E054F7F090FF80E054F7F02264
-:10051000E54D24FE602024FB603424067035300A4B
-:100520000CA20AE433FD7F03122E798026E4FD7FBE
-:1005300003122E79801D300A0CA20AE433FD7F04D9
-:10054000122E79800EE4FD7F04122E7980057F87BC
-:100550001231EF154D300A0B121D55F583E054F79B
-:10056000F08009121D63F583E054F7F0E4FF0232D6
-:100570006EE53530E703020F6EE53C453B60030254
-:100580000F6E121D7914602D146055240260030251
-:100590000F6E90FABDE07004A3E064016003020FE7
-:1005A0006E90FAB9E06003020F6E7867E64401F6D8
-:1005B000E4FF02326EE53520E10620E003020F6E13
-:1005C000E53530E007E54D6003020F6EE53530E1BB
-:1005D0000AE54DD394014003020F6EE4FF02326E30
-:1005E00090FABDE07002A3E06003020F6E90FAB9CA
-:1005F000E0FF12323F4003020F6EE53520E1062096
-:10060000E003020F6EE54D7009300A03021E14026A
-:100610001DDFE53520E103020F6E154D300A0B1288
-:100620001D55F583E04408F08009121D63F583E051
-:100630004408F0E4FF02326EE53530E703020F6E46
-:10064000E53C453B6003020F6E90FAB9E06003029F
-:100650000F6E121D796003020F6EE53530E1030263
-:100660000F6E90FABEE090FFFFF0E06005433501A9
-:1006700080035335FEE4FF02326EE53520E70302C6
-:100680000F6EE53C453B7003020F6E121D7960034F
-:10069000020F6E90FABDE0FCA3E0FDEC24FE603A90
-:1006A00014607524026003020F6EED6003020F6E8A
-:1006B000121CE0121E0D7D03120FB56003020F6EB7
-:1006C000120F7290FAB6E0FDA3121D2B120FD1503B
-:1006D000028004AE3BAF3C021002121CE090F916FF
-:1006E000E030E40D121E0D7D14120FB56010020FE4
-:1006F0006E121E0D7D041210096003020F6E120FA0
-:100700007290FAB6E0FDA3121D2B120FD150028099
-:1007100004AE3BAF3C021002121E0D7D0512100903
-:100720006003020F6E7B017AFA79B6121D287D01F3
-:1007300012269890FAB7E475F003121B1C90FABECB
-:10074000E090FAB5F0E4F54C90FAB5E0FFE54CC363
-:100750009F5024121D22121014FFFD90FAB7E48D51
-:10076000F0121B1C90FAB6E0C39FF0D39400500324
-:10077000020F6E054C80D1121D2212101424FEFFB0
-:1007800090FAB6F0FDA3E475F002121B1C7AF97919
-:10079000727B018B368A378938E92402F9E43AFA08
-:1007A000121D281226988F4C054C054C121CC1E5D1
-:1007B0004C121AE8121CC19000017403121AFAAF0D
-:1007C0004C7E00C3EF953CEE953B50028004AE3B5F
-:1007D000AF3C8E398F3A022CD8020F6EE53520E7F8
-:1007E00003020F6EE53C6401453B6003020F6E900F
-:1007F000FAB9E06003020F6E90FABDE07002A3E068
-:100800006003020F6E121D796003020F6EE5352042
-:10081000E00620E103020F6E75360075370075386B
-:1008200032020FF1E53530E703020F6EE53C453B40
-:100830006003020F6E90FAB9E06003020F6ED3906E
-:10084000FABEE0940190FABDE094004003020F6EFE
-:10085000121D796003020F6EE53520E00620E103EA
-:10086000020F6E90FABEE0F532E5327008433501B2
-:100870005335FD80065335FE433502E4FF02326EE8
-:10088000E53520E703020F6EE53C6401453B60035C
-:10089000020F6E90FAB9E06003020F6E90FABDE0AD
-:1008A0007002A3E06003020F6E121D796401600301
-:1008B000020F6EE53520E103020F6E7F0102326EFA
-:1008C000E53530E703020F6EE53C453B6003020F60
-:1008D0006ED390FABEE0940090FABDE0940040031D
-:1008E000020F6E121D7964016003020F6EE5352060
-:1008F000E103020F6EE4FF02326E90FF01121E242C
-:10090000EF121AE890FAB9121E24900001EF121AA1
-:10091000FA900002E4121AFA7403121CB290FABDA3
-:10092000E0FFA3E0853882853783CFF0A3EFF09016
-:10093000FF01E0121BFC097B02099D0409BF0509A8
-:10094000EB060A09070A27080A45090A630B0B1870
-:10095000800DB7810DE8820B5F830BA8840BC785E0
-:100960000C0C860C57870CE8880D73890A81920A53
-:1009700081930DA0B00E9BC00EC7C10ED8C200005F
-:100980000F5DE53520E7057F050231A9121D716075
-:1009900003047009EFFD7C007F0702115EE4FD7F18
-:1009A00007022FB4E53520E7057F050231A9121DA6
-:1009B000716003047009EFFD7C007F0C02115EE49E
-:1009C000FD7F07022FB4E53530E703020F71121ED9
-:1009D000425006E53C453B70057F020231A990FA82
-:1009E000B9E024FE24FD5002800302322C7F07026E
-:1009F00031A9E53530E703020F71121D7160030460
-:100A00007009EFFD7C007F0802115E7F070231A9AB
-:100A1000E53530E703020F71121D716003047009A0
-:100A2000EFFD7C007F0902115E7F070231A9E535E9
-:100A300030E703020F71121D716003047009EFFDAE
-:100A40007C007F0A02115E7F070231A9E53530E79D
-:100A500003020F71121D716003047009EFFD7C0029
-:100A60007F0B02115E7F070231A9E53530E70302F3
-:100A70000F71121D716003047009EFFD7C007F0E81
-:100A800002115E7F070231A9E53530E756121D7964
-:100A9000704A90FF02E0F54CE54CB48205754C615C
-:100AA0008012E54CB48305754C628008E54CC45453
-:100AB000F004F54C121C22121E3B1225FA121D895D
-:100AC000121ABB600512327A800685333985343AB2
-:100AD0007536017537F9753875022CD8E4FD7F0538
-:100AE000022FB4121D7960057F050231A9121E4242
-:100AF00040057F030231A990FF02E0F54CE54CB4BC
-:100B00008205754C618012E54CB48305754C62809A
-:100B100008E54CC454F004F54C121C2202322C128D
-:100B20001E4C122AC7121D33E0547FF0000000E073
-:100B300090FABAF07868121BD8900002121ABB30F3
-:100B4000E7F2900002E4121AFA90FABAE04480FF49
-:100B5000F0787CE6FC08E68C83121D3BEFF0123245
-:100B600084E4FF0231A990FAB9E06401701F90FAA1
-:100B7000BDE0FF7E007006A3E0F590802DC2AFEFD0
-:100B8000F4529090FABEE04290D2AF801D90FABD30
-:100B9000E0FF7E007006A3E0F5B0800EC2AFEFF478
-:100BA00052B090FABEE042B0D2AFE4FF0231A912D7
-:100BB0001CE090FAB9E0B4010A121CC1E590121AC7
-:100BC000E88008121CC1E5B0121AE8020FF190FA91
-:100BD000B9E0FF2413121CF120E133121D80EF2431
-:100BE000FC601804702890FABAE0600990FFA4E055
-:100BF0004410F08019121E56F0801390FABAE0608B
-:100C00000990FFB4E04410F08004121E5DF0E4FF90
-:100C10000231A990FAB9E0FF2413121CF120E13946
-:100C2000121D80EF24FC601B04702E90FABAE06065
-:100C30000990FFA4E04420F0801F90FFA4E054DF5F
-:100C4000F0801690FABAE0600990FFB4E04420F01A
-:100C5000800790FFB4E054DFF0E4FF0231A9121DD9
-:100C600080121D71604D046003020CE390FABAE03B
-:100C7000600F90FFA4121CEA30E16F121E2C020CD0
-:100C8000E390FFA4E054FB121CEDFE30E15C30E287
-:100C90001130B405121E2C805190FFA4E054FDF0D9
-:100CA0008048309505121E2C804090FFA4E054FD32
-:100CB000F0803790FABAE0601290FFB4121CEA306C
-:100CC000E12890FFB4E04402F0801F90FFB4E054AC
-:100CD000FB121CED30E11330930990FFB4E04402A5
-:100CE000F0800790FFB4E054FDF0E4FF0231A91258
-:100CF0001D8090FAB9E024FC604004707890FABA44
-:100D0000E0601D90FFA2E04440F0A3E0FF30E76503
-:100D1000D203A3E054DFF090FFA3EF547FF080559F
-:100D200030030E90FFA3E04480F0C203A3E0442010
-:100D3000F090FFA2E054BFF0803B90FABAE0601D53
-:100D400090FFB2E04440F0A3E0FF30E728D204A3D4
-:100D5000E054DFF090FFB3EF547FF0801830040EC2
-:100D600090FFB3E04480F0C204A3E04420F090FF81
-:100D7000B2E054BFF0E4FF0231A9121CE090FAB9CE
-:100D8000E024FC600F04701690FFA6E0121CC11254
-:100D90001AE8800A90FFB6E0121CC1121AE87539F1
-:100DA00000753A01022CD890F9157401F090F91CE5
-:100DB0007419F090F96674FFF0E4FF0231A9E4FFC2
-:100DC0001231A9121DE77F0312126190F916E0306B
-:100DD000E40890FF937480F0801090FFFCE0547F53
-:100DE000F07FFF7E001230D3C290C2AF0080FDE4DE
-:100DF000F54EF54F90FABF743EF0A3E4F090FAB7C9
-:100E0000F0A37415F0E0543FFFC374409F90FABC08
-:100E1000F0D39400E4943E400890FAC0E090FABC0D
-:100E2000F0120F98E53145307073121CFA90FABF3A
-:100E3000121E066027D3EF9440EE9400400890FA0B
-:100E4000BC7440F0800890FAC0E090FABCF0120F39
-:100E500098E53145307046121CFA80D1754C0290ED
-:100E6000FABFE4F0A304F090FAB7E4F0A3740FF033
-:100E70007B007A00794C90FAC0E0F54A7D0F7C0047
-:100E80001229607530008F317B007A00794CE4F5CF
-:100E90002DF52E7D01122698E4F530F531AF3102A3
-:100EA00031A9121D8030E710E0540F90F967F0D39C
-:100EB00094004015C295801190FABAE0540F90F951
-:100EC00065F0D394004002C294E4FF0231A9121EDF
-:100ED0004CBF0104D2938002C293E4FF0231A912F5
-:100EE0001D80540314600A14600F146008240370FA
-:100EF0002BD2918027C2918023121E56120FC06000
-:100F000004D291801790FFA4E04410120FC0FFBFDD
-:100F1000A004C2918002D291121E56F090FABAE05B
-:100F2000540CFF1313543F14600A14600F1460082C
-:100F30002403702BD2928027C2928023121E5D124E
-:100F40000FE06004D292801790FFB4E04410120FBB
-:100F5000E0FFBFA004C2928002D292121E5DF0E4B4
-:100F6000FF0231A9E53530E707E4FD7F05022FB424
-:100F70007F050231A912327A227B017AFA79B69082
-:100F8000FAB7E0F52DA3E0F52E7D0112269890FA30
-:100F9000B7E475F003121B1CAB36AA37A93822AA96
-:100FA0004EA94F7BFF90FAB7E0FCA3E0FD90FABC9E
-:100FB000E0F54A1229607530008F31221223617EDC
-:100FC000008E308F31EF22F07F0112126190FFA668
-:100FD000E090FABBF054A0221226988F4C7E00C3FA
-:100FE000EF953CEE953B22F07F0112126190FFB627
-:100FF000E090FABBF054A022753900753A01022C3A
-:10100000D890FAB9E0FF02323F8E398F3A022CD8DD
-:101010001223617E008E308F31EF227D01122698DF
-:1010200090FAB4E022EF90F804F022C0A8C2AFEE2C
-:10103000600AC0057D7FDDFEDEFAD005EFC39415A2
-:101040005003D0A822137003D0A822FFD507FDD0EB
-:10105000A822C000C001C002C004C005E53E2408AB
-:10106000F8860553057F7CFF1210C07F007E00E5E7
-:10107000436046FC90F91DE0547F6D700FC083C043
-:1010800082A3E0FEA3E0FFA315438007A3A3A3DC94
-:10109000E68026DC06D082D083801EE0F8A3E0F94B
-:1010A000A3E0FAD082D083E8F0A3E9F0A3EAF0A3AA
-:1010B000C083C082A3A3A380DA121157D005D00445
-:1010C000D002D001D0002285A84475A888EC700217
-:1010D0007C3F8C3D22E53E2408F876001211AE805C
-:1010E000FBC000C001C002C004C0067CFF1210C0DB
-:1010F000E5436042FE90F91DE0547F6F700BC083A2
-:10110000C082A3A3A315438007A3A3A3DEEA80267E
-:10111000DE06D082D08380D8E0F8A3E0F9A3E0FA1D
-:10112000D082D083E8F0A3E9F0A3EAF0A3C083C0A3
-:1011300082A3A3A380DA7808087918097C01E65411
-:101140007F6F700676007700800608090CBC08EEF9
-:10115000121157D006D004D002D001D00022753D24
-:10116000008544A822C0F0C082C083C3E54324E8C0
-:1011700050051211AE80F4EF6031903111E493C349
-:101180009F402FC0047CFF1210C0D004430780E5AD
-:101190004375F003A4241DF582E434F9F583EFF0E0
-:1011A000ECA3F0EDA3F00543121157D083D082D009
-:1011B000F0220211DCC0047C20D28CD28DD504FD3B
-:1011C000D0042275A80075880075B80075F0007508
-:1011D000D000E4F890F804F0900000F608B800FBA6
-:1011E000020000C2AFE490FF48F090FF50F090FF83
-:1011F00008F090FF10F090FF80F0A3A3F0D2B1C2EE
-:10120000B07EFF7FFF1210247EFF7FFF1210247E2E
-:10121000FF7FFF121024D2B0D2B17EFF7FFF1210E9
-:10122000247EFF7FFF1210247EFF7FFF1210248098
-:10123000CCC3EE940250047E037FE8EFF4FFEEF49B
-:10124000FE0FBF00010E8F428E4122C3EF94BCEE11
-:10125000940250047E077FD0EFF4FFEEF4FE0FBF40
-:1012600000010E8F408E3F22EF700122C000C0A807
-:10127000C2AFE53E2418F8A607E53E2408F8C65498
-:101280007FF6D0A8E630E703D000221211AE80F43A
-:10129000C0007F01EF2408F8E660090FBF08F512CF
-:1012A00011AE80EED00022C0F0C082C083C000C06A
-:1012B00006C004ED2410F8769AED75F021A42405FB
-:1012C000F582E434F8F583C082C083A3A3E4780DEB
-:1012D000F0A3D8FCEF547F75F002A424F3F582E567
-:1012E000F03430F583E493FE740193FCD083D08214
-:1012F000ECF0A3EEF0ED2408F8EF4480F6D004D033
-:1013000006D000D083D082D0F022753E0075430015
-:101310007A0879187808760077000809DAF890F8E2
-:1013200004E0FC903111E493C39C5005E490F80470
-:10133000F078087480447FF674014410F58975B81C
-:1013400000D2ABD2A92275818BD28ED28CD2AFE5DE
-:10135000436036FF90F91DE05480602878087908D2
-:10136000E0547FFA7B00E6547FB502027BFF08D988
-:10137000F5EB7010EAF0C007121289AD07AF021248
-:1013800012A0D007A3A3A3DFCE1211AE80C18F2479
-:10139000122AC71222B5A3A3E0A330E728787E1251
-:1013A0002299E04401F01222FA12229DE020E0F698
-:1013B0001223507402F01222DAE0A330E507122360
-:1013C00050E04401F07880E6FE08E6FF8E832408B2
-:1013D0001222A1E0FD1223398A83240A1222A1EDF0
-:1013E000F012230624071222A1E0FF12235A240937
-:1013F0001222A1EFF090F916E030E420081222B793
-:10140000C083C082A3E025E0FF0582D58202158358
-:101410001582E033D082D083F0A3EFF01222B5E042
-:10142000FCA3E0FDECFF1223398A8324081222A1D9
-:10143000EFF0ED12235A24071222A1EDF01222A997
-:10144000E030E60A12234124091222A1E4F012221C
-:10145000A9E0FF30E71B12231E24091222A1E0603D
-:10146000091222A9EF4402F080071222A9EF54FDCD
-:10147000F0787E1222B7A3A3E0FF5307C708E6FC6B
-:1014800008E6FD1222E0A3E030E3128D828C83E5B2
-:101490008224051222A1E09032519342075307FBA8
-:1014A00012231E24061222A1E060034307045307FF
-:1014B000FC788012232924041222A1E0420743076A
-:1014C00080122339F5828A83A3A3EFF012235A24D2
-:1014D000041222A1E0FF8D828C83A3A3E0FCA3E091
-:1014E000FD30E1055307DF8003430720EC30E405BE
-:1014F0005307EF80034307101222A9E0FE54036054
-:10150000735307DFEE30E16912231E24091222A172
-:10151000E0121BFC152C0015600115650315600514
-:1015200015650715600915650B15600D15650F002C
-:1015300000156DE5246403702190F916E030E20D8A
-:1015400030B405430702802C5307FD8027309505F2
-:10155000430702801F5307FD801A3093054307029B
-:1015600080125307FD800D43070280085307FD805A
-:10157000035307FD12232724041222A1EFF08D82CA
-:101580008C83A3A3A3E0FF1222A9E0FE54037003FF
-:10159000021660EE20E10302165D081223202409E2
-:1015A0001222A1E0121BFC15BF0015F50115F50371
-:1015B000162905162907160F09160F0B16430D16C7
-:1015C000430F00001660E5246403702390F916E0D1
-:1015D00030E20F30B10653077F02166043078002E6
-:1015E000166030940553077F807D430780807830F4
-:1015F000920553077F8070430780806BE524B40316
-:101600000990FF9EE054EFF0800790FF9EE054DFCA
-:10161000F053077F8051E524B4030990FF9EE04416
-:1016200010F0800790FF9EE04420F053077F803742
-:10163000E524B4030990FF9EE054EFF0800790FF8B
-:101640009EE054DFF0430780801DE524B403099039
-:10165000FF9EE04410F0800790FF9EE04420F0439E
-:101660000780800353077F1222DAE0FCA3E0FD30FD
-:10167000E00543072080035307DFEC30E305430711
-:101680004080035307BFEC30E0054307108003534D
-:1016900007EFED30E40543070880035307F7ED300B
-:1016A000E50543070480035307FBED30E6054307D8
-:1016B0000180035307FEED30E70543070280035323
-:1016C00007FD787E1222DCA3EFF01232847F002225
-:1016D00090FFFA7408F0A37416F090FFF97402F00A
-:1016E0007B017AFA79CFE4FD12236190FACFE47599
-:1016F000F003121B1C121992E52330E702D2027B81
-:10170000007A00792490FACFE0F52DA3E0F52E7D44
-:101710000112269890FACFE4F0A3740BF07B007AC4
-:10172000007923752D00F52E7D01122698E52324DE
-:101730008090FFF8F0E5236407601EE523640660EF
-:1017400018E52364146012E5236441600CE523640A
-:101750001A7046E52464027040E523B40716D2945B
-:10176000D295D292D29390F916E04402F0A3E044CD
-:1017700002F0801EE523B4411290F916E04406F011
-:10178000A3E04406F0D2B1D2B4800790F916E04449
-:1017900001F090F917E04401F0E5236442600CE5A4
-:1017A0002364436006E5236444702E90F916E0FF3D
-:1017B000E523B444047E4080027E00EE24804F90F6
-:1017C000F916F0A3E0FFE523B444047E4080027ED6
-:1017D00000EE24804F90F917F090FACFE4F0A37454
-:1017E0000DF012199290FFF5E523F0E4F535F5338D
-:1017F000F534F532121E34121CE0121E3B90F96AC9
-:10180000121BF390F96F121BF390FFFFE4F090FFAF
-:1018100083E0E4F090FF817480F0A37484F090FF83
-:1018200080F0E4F523E523121D57F583E4F0E5236A
-:10183000121D65F583E4F00523E523B407E7787A04
-:1018400076FE0876F090320AE493FF7878F6FDADE4
-:1018500007903217E493FF08F6FFED540FFD121DB9
-:10186000477484F0ED75F008A42447F582E434FF52
-:10187000F583EFF0C374F09F787BF674FE94001844
-:10188000121CD8CEC313CE13D8F9FFED121DA8EF4A
-:10189000F0ED121DCEE4F523E52390320493FF789A
-:1018A00078F6FDE52325E0240BF582E43432F58358
-:1018B000E49308F6ED30E75318E6540FF9121D478C
-:1018C000121DB62447F582E434FF121CC8CEC313A0
-:1018D000CE13D8F9FFE9121DA8EFF0121CCFCEC32A
-:1018E00013CE13D8F9121DBB2445F582E434FFF55D
-:1018F00083EFF0E9121DCEE975F008A42446F582C5
-:10190000E434FFF5837480F00219677878E6540FA9
-:10191000F9121D9A121DB62407F582E434FF121C39
-:10192000C8CEC313CE13D8F9121DBB2401F582E42F
-:1019300034FFF583EFF0121CCFCEC313CE13D8F9CA
-:10194000121DBB2405F582E434FFF583EFF0E97541
-:10195000F008A42402F582E434FFF583E4F0E9758D
-:10196000F008A42406F582E434FFF583E4F00523AF
-:10197000E52364046003021891903209E493FF7830
-:1019800078F6121D98E4F090320893FFF6121D4588
-:10199000E4F090FFFD7405F0227B007A007923903B
-:1019A000FACFE475F001121B3285F02EF52D7D0182
-:1019B000022698E709F608DFFA8046E709F208DF11
-:1019C000FA803E88828C83E709F0A3DFFA8032E355
-:1019D00009F608DFFA8078E309F208DFFA807088F8
-:1019E000828C83E309F0A3DFFA806489828A83E032
-:1019F000A3F608DFFA805889828A83E0A3F208DF21
-:101A0000FA804C80D280FA80C680D4806980F280CF
-:101A100033801080A680EA809A80A880DA80E280F5
-:101A2000CA803389828A83ECFAE493A3C8C582C84A
-:101A3000CCC583CCF0A3C8C582C8CCC583CCDFE9B4
-:101A4000DEE7800D89828A83E493A3F608DFF9EC50
-:101A5000FAA9F0EDFB2289828A83ECFAE0A3C8C5DB
-:101A600082C8CCC583CCF0A3C8C582C8CCC583CC02
-:101A7000DFEADEE880DB89828A83E493A3F208DF71
-:101A8000F980CC88F0EF60010E4E60C388F0ED2441
-:101A900002B4040050B9F582EB2402B4040050AF44
-:101AA00023234582239019FC73BB010689828A8314
-:101AB000E0225002E722BBFE02E32289828A83E40D
-:101AC0009322BB010CE58229F582E5833AF583E098
-:101AD000225006E92582F8E622BBFE06E92582F8B7
-:101AE000E222E58229F582E5833AF583E49322BB7D
-:101AF000010689828A83F0225002F722BBFE01F39D
-:101B000022F8BB010DE58229F582E5833AF583E8E9
-:101B1000F0225006E92582C8F622BBFE05E925829F
-:101B2000C8F222C5F0F8A3E028F0C5F0F8E5821568
-:101B30008270021583E038F022A3F8E0C5F025F0AA
-:101B4000F0E582158270021583E0C838F0E822BB08
-:101B50000110E58229F582E5833AF583E0F5F0A3EB
-:101B6000E0225009E92582F886F008E622BBFE0A49
-:101B7000E92582F8E2F5F008E222E5832AF583E917
-:101B800093F5F0A3E99322BB010A89828A83F0E5E9
-:101B9000F0A3F0225006F709A7F01922BBFE06F3C6
-:101BA000E5F009F31922F8BB0111E58229F582E578
-:101BB000833AF583E8F0E5F0A3F0225009E92582A5
-:101BC000C8F608A6F022BBFE09E92582C8F2E5F0B6
-:101BD00008F222A42582F582E5F03583F58322E61A
-:101BE000FB08E6FA08E6F922EBF608EAF608E9F659
-:101BF00022E0FBA3E0FAA3E0F922EBF0A3EAF0A3D2
-:101C0000E9F022D083D082F8E493701274019370CB
-:101C10000DA3A393F8740193F5828883E47374028F
-:101C2000936860EFA3A3A380DFAB36AA37A938E59A
-:101C30004C121AE874012538F538E43537F537AB1E
-:101C400036FAA9387411121AE874012538F538E407
-:101C50003537F53790FF06E0AB36AA37A938121AA8
-:101C6000E874012538F538E43537F537AB36FAA98D
-:101C700038E4121AE8042538F538E43537F537AB7F
-:101C800036FAA938E4121AE8042538F538E435376D
-:101C9000F53790FF04E0AB36AA37A938121AE8747A
-:101CA000012538F538E43537F53790FF05E0AB36D8
-:101CB000AA37A938121AE874012538F538E43537FF
-:101CC000F53722F583E05408AB36AA37A93822F558
-:101CD00083EFF0FD7C00C3787BE69DF618E69CF66A
-:101CE000E6FE08E67803227536017537F975387215
-:101CF00022E04404F074132FF582E434F9F583E014
-:101D00002290FABCE0FF7E00C390FAC0E09FF09002
-:101D1000FABFE09EF090FAB7EE8FF0121B1CEF2591
-:101D20004FF54FEE354EF54E227B017AFA79B4909D
-:101D3000FAB7E0F52DA3E0F52E22787CE6FE08E662
-:101D40008E832404F582E43583F58322540F75F0E5
-:101D500008A42440F582E434FFF58322E54D75F0B4
-:101D600008A42448F582E434FF22E54D75F008A468
-:101D70002408F582E434FF2290FAB9E0FF24FC2223
-:101D800090FF00E0541F2290FABEE090FABAF022D1
-:101D90007533008F3490F96F121BEA9000022254C1
-:101DA0000F75F008A42400F582E434FFF583227552
-:101DB000F008A42441F582E434FFF583227480F016
-:101DC00008E6FFE975F008A42274B22522F582E442
-:101DD00034FAF5832275F008A42442F582E434FF36
-:101DE000F5837480F02290FF82E04408F02290FF97
-:101DF000FEE04403F090FFFCE054FDF0227867E63B
-:101E000054FDF690FFFD7465F022121BCCE0FEA39A
-:101E1000E0FF4E227B017AFA79B72290FF80E044FE
-:101E200008F02290FF83E0547FF022E0FF90F96AEF
-:101E3000021BEA90FFA4E04402F022753901753AD2
-:101E400009227B017AF9797222D3E53C9408E53BBB
-:101E500094012290FABEE0FF90FABAF02290FFA41B
-:101E6000E054EF2290FFB4E054EF2212104B788838
-:101E7000EFF6122AC71222FA8E8324091222A1E059
-:101E8000FD1222E890000A122302240A1222A1E085
-:101E900090000B121AFA1222FAF5828E83A3A3A3E2
-:101EA000E0F55312230624041222A1E0F5548F8298
-:101EB0008E83A3A3E0F555E553C41313135401789F
-:101EC00088F6D394004006E55430E101067888E6B0
-:101ED0001222E790000CEF121AFA1222B5A3A3E027
-:101EE000FEA3E0FF53070C5306E6E55330E503433A
-:101EF0000701E55420E50EE553547F7008E55320B3
-:101F0000E703430702E55330E303430710E553308B
-:101F1000E203430720E55354036003430740E553BE
-:101F200030E103430780E55330E403430601E55302
-:101F300030E603430608E55420E40EE553547F7071
-:101F400008E55320E7034306105307FB5306799037
-:101F50000005EE8FF0121B9FE55530E3125430FF61
-:101F6000C4540F1222E7900008EF121AFA800A12E6
-:101F700022E8900008E4121AFAE55554031222E709
-:101F8000900007EF121AFAE5555404FFC3139000AE
-:101F900009121AFA900007121ABB70131222E8E90C
-:101FA0002409F9E43AFA121AA2FFC313121AE8122A
-:101FB000232724081222A1E0FE8D828C83E582244F
-:101FC000071222A1E0FDEEED1222E7900003EE8F52
-:101FD000F0121B9F1232847D0AE4FF122FB402100C
-:101FE000CE90FAE6E0B403067E007F4080047E00D7
-:101FF0007F0890FADAEEF0A3EFF0900005121ABB1A
-:10200000FF7E0090FAD6EEF0A3EFF070037F082277
-:10201000900008121B48FF90FAD8E5F0F0A3EFF00B
-:10202000AE02AF018E508F51740A2551F551E4353F
-:1020300050F55090FADBE0FF14FE90FAD9E05EFE16
-:10204000C3EF9EFF90FADDF0C390FAD7E09F90FABD
-:10205000D6E094005006A3E090FADDF01220A960CB
-:1020600003E0FF22122E2B90FAD6E0FEA3E0FF4EF3
-:10207000602B90FADAE0FCA3E0FDD3EF9DEE9C40EC
-:1020800007E090FADDF0800890FAD7E090FADDF0F2
-:102090001220A96003E0FF22122E2B80CA7B007A57
-:1020A000007952E4F52DF52E7D011226987F00224D
-:1020B000AA50A9517B0190FAD8E0FCA3E0FD90FA68
-:1020C000DDE0F54A12296090FADCEFF022EF24AE51
-:1020D000605224FE602E24FE7003022169240660F3
-:1020E000030221B17871E654FBF690FFA5E0F522DA
-:1020F000440FF0743390FA94F0E522A3F090FAB212
-:102100007401F0227872E654FBF690FFB5E0F522F8
-:10211000440FF0744390FA96F0E522A3F090FAB3DE
-:102120007401F02290FAA0E0A320E5030221B1900F
-:10213000FFA6E090FACDF0A3F090FACDE0FF540FA7
-:10214000FE601090FFA612230D90FFA6E090FACD3E
-:10215000F080E690FACEE0FF7434FE122D85EF7029
-:102160005790FACEE0FF743490FA98F0EFA3F02283
-:1021700090FAAAE0A330E54090FFB6E090FACDF0E7
-:10218000A3F090FACDE0FF540FFE601090FFB6125E
-:10219000230D90FFB6E090FACDF080E690FACEE005
-:1021A000FF7444FE122D85EF700E90FACEE0FF749E
-:1021B0004490FA9AF0EFA3F022C0E0C0F0C083C0D0
-:1021C00082C0D075D000C000C001C002C003C004EE
-:1021D000C005C006C00790FF92E0FF90FACCF090D7
-:1021E000FF92E4F0EF121BFC22692622692E220CDA
-:1021F00030220C32221A38222C3A225E3E224944E6
-:10220000223E462254502254522254542254560004
-:1022100000226E90FACCE0FD7C007F0112115E80FE
-:10222000627C007D017F0312115E90FFFEE044207E
-:10223000F080507C007D017F0212115E90FFFEE075
-:102240004440F0803E7C007D017F0512115E8033AA
-:102250007C007D017F0612115E802890FACCE0FFA1
-:102260001220C6801E7C007D017F0412115E801347
-:1022700012284E800E90FACCE02400FFE434FFFEDA
-:10228000122D85D007D006D005D004D003D002D0BF
-:1022900001D000D0D0D082D083D0F0D0E032787C92
-:1022A000E6FE08E624048E83F582E43583F5832276
-:1022B00074132524F582E434F9F583227880E6FE50
-:1022C00008E6F5828E83227880E6FE08E6AA06F804
-:1022D000AC027D017BFF7A3279567E007F0A021ABA
-:1022E0007C7880E6FC08E6F5828C83A3A322FF902D
-:1022F000F96F021BEA90F96A121BEA900004021AB5
-:10230000BB787EE6FE08E6FF22ED121AFA8F828E77
-:1023100083E58222EFF090FACEE0540F4EFEF0EF0C
-:1023200054F04EF0227880E6FC08E68C8322787E1A
-:10233000E6FC08E6FD8C8322A607E6246EF8E6227A
-:10234000787EE6FA08E6FB2208E6FE08E68E83229F
-:1023500026F618EE36F622EF240BF582E43EF583DE
-:10236000228B828A83E582228B258A2689278D28E3
-:1023700090FAD2E4F0A37402F07B017AFA79D1905A
-:10238000FAD2E0F52DA3E0F52E7D0112269890FA01
-:10239000D1E065286046A3E0FFA3E0A3CFF0A3EF60
-:1023A000F01223F090FAD1E0FF90FAD4E48FF0120B
-:1023B0001B1C1223F090FAD4E0FFA3E090FAD2CFD6
-:1023C000F0A3EFF090FAD1E0A375F000121B1C907F
-:1023D000FAD2E475F004121B1C02237290FAD3E0C7
-:1023E0002401FF90FAD2E03400AB25AA26A9278F5A
-:1023F000F0121B807F00227B017AFA79D190FAD209
-:10240000E475F001121B1C85F02EF52D7D010226CE
-:10241000988F62122AC71222FA8E83240B1222A1ED
-:10242000E054FBF04402F0081222DCE0A330E50C9B
-:10243000122306240B1222A1E04401F0787CE6FE70
-:1024400008E6FFF5828E83E054B8FDF0E56224FED5
-:102450004420FC4DF0E58224041222A1E054B8F09F
-:102460004CF08F828E83A37403F018E6FE08E6FF1B
-:102470008E8324051222A1C083C082E0FD749925B9
-:1024800062F582E434FAF583E054FC4403FCED4C3D
-:10249000D082D083F08F828E83E04480F0E5822466
-:1024A000041222A1E04480F0123284746E2562F896
-:1024B000740446F67F002212104B7F0212126178DC
-:1024C00067E64402F6D2B0D2B190F916E030E707E1
-:1024D00090FF9EE4F08036D2B390FFA4E090FA7EA5
-:1024E000F090FFB4E090FA7FF090FFA2E090FA7CC9
-:1024F000F090FFB2E090FA7DF090FFA47430F0907D
-:10250000FFB4F090FFA27440F090FFB2F090FAE7B1
-:10251000E5A8F075A88190FF92E06004E4F080F6F1
-:1025200090FFFD743AF043870100000090FA7EE0CE
-:1025300090FFA4F090FA7FE090FFB4F090FA7CE076
-:1025400090FFA2F090FA7DE090FFB2F090F918E0D1
-:102550006002C2B390FAE7E0F5A80210CE8B5C8A65
-:102560005D895E122E0D90FAC3121BF3AA5DA95E5F
-:1025700090FAC6121BF390FAC7E475F00A121B1CFE
-:1025800090FAC6121BEAE92401F9E43AFA90FAC972
-:10259000121BF3AB5CAA5DA95E122E19E0FFC313F8
-:1025A000F0E47882F690FAC1E0FF7882E6C39F50AB
-:1025B0004A90FAC3122DEEFF7883F690FAC6122DD8
-:1025C000EEFEF45FFF7883F6122DEB5E4FFF78830B
-:1025D000F6122DF475F002121B1C90FAC7E475F088
-:1025E00002121B1CAB5CAA5DA95E900004121ABB10
-:1025F00030E403122E0378820680AAE490FAC2F037
-:10260000228B568A57895890FAC27406F0E490FAE1
-:10261000C1F0121AA2246E6026147070122DDA60B6
-:1026200009243070121225568062122E24121FDAED
-:1026300090FAC2EFF0805590FAC27481F0804D128A
-:102640002DDA60092430703E122D30803FE5582489
-:1026500003F9E43557FA7B01C003C002C001122E12
-:1026600024900005121ABBFD900008121B48F52E9D
-:1026700085F02DD001D002D00312269890FAC1EF38
-:10268000F0E4A3F0800690FAC27481F090FAC2E000
-:10269000122E24900002121AFA90FAC1E0FF228B47
-:1026A000298A2A892B8D2CE52C7003AF2C22122E1F
-:1026B000537016122E72E52D90FFF1F01231D850A2
-:1026C000F2122725400B7F0022122E72122725506E
-:1026D000F890FFF374A1F0E52CB4010790FFF0E04F
-:1026E0004402F090FFF1E4F0F52FE52C14FFE52F04
-:1026F000C39F502A1231C14003AF2F22C3E52C954E
-:102700002FFFBF020790FFF0E04402F0122E650594
-:102710002F7401252BF52BE4352AF52A80CC1231B4
-:10272000C140037F1822122E65AF2C2290FFF1E5E5
-:102730002EF00231D812104B788412233130E10888
-:102740007F131231A90227BC7884E6F924131222E0
-:10275000ADE0FF30E7405403601EE9B4030D90FF85
-:102760009EE054FEF0E04404F0804690FF9EE0546A
-:10277000FDF0E04408F08039E9B4030D90FF9EE0DD
-:1027800054FBF0E04401F0802890FF9EE054F7F005
-:10279000E04402F0801BEF54036014E9B403099095
-:1027A000FFA4E054DFF0800790FFB4E054DFF0C2F4
-:1027B000B390F918E004F0AF011222EEFD122FE5FC
-:1027C0001231A90210CE75A840787FE4F6D8FD75C5
-:1027D000818B02280902318CE493A3F8E493A3408F
-:1027E00003F68001F208DFF48029E493A3F854078C
-:1027F000240CC8C333C4540F4420C8834004F45687
-:10280000800146F6DFE4800B0102040810204080BE
-:10281000902BA9E47E019360BCA3FF543F30E509EF
-:10282000541FFEE493A360010ECF54C025E060A8BE
-:1028300040B8E493A3FAE493A3F8E493A3C8C58251
-:10284000C8CAC583CAF0A3C8C582C8CAC583CADFBF
-:10285000E9DEE780BEE4F522121DC2E0B4040DE516
-:10286000222403FF123013121DC2E4F00522E522D8
-:10287000C3940240E3E4F52275F002E52290FA9455
-:10288000121E03602C122D85EF605275F002E522B6
-:1028900090FA94121BCCE4F0A3F075F00AE52290B4
-:1028A000FAA0121BCCE0A330E633121DC27404F070
-:1028B0002275F002E52290FA98121E036016122D7E
-:1028C00085EF601975F002E52290FA98121BCCE4AE
-:1028D000F0A3F0220522E522C39402409B22E4FFEC
-:1028E00090FF83E0540FFEEFC39E501774F02FF556
-:1028F00082E434FEF583E0121CC1121AE80F121CA8
-:10290000B080DDEFFDC3E53A9DF53AE5399400F579
-:1029100039D3E53A9400E53994004006E490FF830A
-:10292000F022121DDF121E34121E26121AA2246E6D
-:10293000601E14601B248E702D900001121ABBFFC4
-:1029400024FC600304701FEFFD7C007F0D02115E0C
-:10295000121E3B1225FA121D89121ABB60030232A5
-:102960007AE4FF12326E228B458A4689478C488D65
-:1029700049D200122E537016122E72E54890FFF1C4
-:10298000F01231D850F21229D5400B7F1822122EA6
-:10299000721229D550F8E4F54BE54A14FFE54BC314
-:1029A0009F50171229C540037F1822054B7401253B
-:1029B00047F547E43546F54680DF90FFF0E04401F7
-:1029C000F01229C540037F18227F0022AB45AA469A
-:1029D000A947121AA290FFF1F00231D890FFF1E559
-:1029E00049F00231D87B017AFA79CFE4FD122361F4
-:1029F00090FACFE475F009121B1C7B007A00792352
-:102A000090FACFE475F001121B3285F02EF52D7D82
-:102A10000112269890FFF7E523122A3990FFF6E578
-:102A200023F090FACFE4F0A37406122A39E523309C
-:102A3000E00790FFFC7494F02290FFFC7490F02269
-:102A4000F07B007A00792390FACFE475F001121B35
-:102A50003285F02EF52D7D0102269890FF9374812A
-:102A6000F090FFFFE0600690FFFC7410F090FF9183
-:102A7000E04490F0E490F916F0A3F0122B3912160E
-:102A8000C91230697E077FD012122A7E0F7FA012F2
-:102A90001244E47877F67877E6FFC39406500B7417
-:102AA0006E2FF8E4F678770680EC7F031230B29050
-:102AB000F916E020E4057F041230B290FF9BE4F0A9
-:102AC00090FF9AF090FFE8E0541FF0D2A82215651D
-:102AD000A865A6073008051211AE80F8D208A865CF
-:102AE000E6FFB4030F787C76FF0876E00876FF08EF
-:102AF00076A0800D787C76FF0876E20876FF08766F
-:102B0000B0788076FA08769EEF24FD75F00AA4AEC0
-:102B1000F01223497B017AFF79487868121BE1A8FB
-:102B200065E624FD75F008A4FFAEF0786A1223492B
-:102B30007908786B121BE1786DEF12234905652245
-:102B400090FFF0E054ABF0E04420F090FAE674021D
-:102B5000F07B017AFA79CFE4F52DF52E7D0112266E
-:102B6000987E0090FAE4EEF0A3EFF064017010900C
-:102B7000FACFE0B4520990F916E054EFF0802990B2
-:102B8000FAE4E07004A3E06401701090FACFE0B4BE
-:102B9000100990F916E04410F0800D90FAE67403E5
-:102BA000F090F916E054EFF090FFF0E04420F022AE
-:102BB000036801FF48036B01FF080266000044FA46
-:102BC000980000000044FA940000000042FAB200AD
-:102BD0000042FA7E000042FA7C000042F96DFFFFDD
-:102BE00042FA7A000041F966FF41F91C1941F915D2
-:102BF0000043F9190A320241F9682041F96920417C
-:102C0000F9650041F9670044F8000000000042F94E
-:102C100016000041F9180001200041F804000012DC
-:102C2000104B788AEFF6122AC71222EE30E029788C
-:102C30007C1222B7E0547FF0786B121BD890000210
-:102C4000121ABB30E709900002E4121AFA80E97800
-:102C50007C1222B7E04480F01222EE30E11E1222F4
-:102C600097E0547FF01232197868121BD890000256
-:102C70007480121AFA122297E04480F0123284E42F
-:102C8000FF1231A90210CE12104B7885EFF61231E7
-:102C9000501231A97885E6FF24131222ADE0FE30F0
-:102CA000E716EFB4030990FF9EE054FAF0802290FB
-:102CB000FF9EE054F5F08019EE54036014EFB40366
-:102CC0000990FFA4E04420F0800790FFB4E0442086
-:102CD000F090F918E014F0E07002D2B30210CE12B6
-:102CE0001E1CE53A64097004E53964016048C3E5D7
-:102CF0003A9408E539940040117F08EFE53A9408CA
-:102D0000F53AE5399400F5398005AF3A121E34E4FE
-:102D1000FEEEC39F5019121CC1121AA2FD74F82EA8
-:102D2000F582E434FEF583EDF00E121CB080E2EF84
-:102D3000547F90FF81F0228B598A5A895B122E1999
-:102D40007005A37408F022AB59AA5AA95B122E0D84
-:102D500090FAC9121BF3E55B2403F9E4355AFA90A3
-:102D6000FAC3121BF3E490FAC2F0788BF690FAC122
-:102D7000E0FF788BE6C39F5012122DEBFF122DF46B
-:102D8000122E07788B06122E0380E222AD07AC06C6
-:102D900090320AE493FF7874F6540F121DA8E008ED
-:102DA000760008F618121CD9C333CE33CED8F9FFFB
-:102DB0007875EEF608EFF6EE44F818F6EF08F690A0
-:102DC000FF7AE020E7037F00227875E6FE08E6F54B
-:102DD000828E83ECF0A3EDF090FF7A7402F07F0115
-:102DE00022AB56AA57A958900003121ABB54F024DC
-:102DF000A02290FAC9121BEA021AA290FAC3121B6F
-:102E0000EAEF121AE890FACAE42290FAC4E475F0E4
-:102E100001021B1C900008121B48AAF0F97B01223A
-:102E2000900005121ABB90FAC1F022AB56AA57A91E
-:102E3000582290FADDE0FF7E00C390FAD7E09FF0C1
-:102E400090FAD6E09EF090FAD8EE8FF0121B1CEFAD
-:102E50002551F551EE3550F5502290FFF0E054FE2B
-:102E6000F0E054FDF090FAE6E064032290FFF2E017
-:102E7000AB29AA2AA92B021AE890FFF374A0F0222A
-:102E80008F64ED700FE564B403057F010231EF7FBD
-:102E9000020231EFAF64122AC7746E2564F8E6307F
-:102EA000E20BD209121D33E0547FF08002C209E523
-:102EB00064B403077F811231EF80057F821231EF06
-:102EC000300907121D33E04480F0123284221210C0
-:102ED0004B90FFFDE04460F0D20190FFFCE0440223
-:102EE000F090FF00E030E71390FF83E04480F04370
-:102EF000358090FFFCE04401F0800D121DDF53355A
-:102F00007F90FFFCE054FEF090FF81E04480F012DF
-:102F100002DE121DE70210CE12104B7889EFF6D2B6
-:102F200000122AC790F96A121BEAE92403F9E43A6D
-:102F3000FAC0027880E6FE08E6AA06F8AC027D0137
-:102F4000D0021222D31232847889E6FF121387123C
-:102F500031A90210CE8F63122AC7787C1222B7E003
-:102F6000543FF0E58224041222A1E0543FF01223E2
-:102F700041240B1222A1E054F8F0123284746E2521
-:102F800063F874FB56F67F002212104B122AC71208
-:102F900022FA240612229FE0FD1222E8900003127A
-:102FA000230224051222A1E0900004121AFA123220
-:102FB000847D02E4FF122FB40210CEAE05121D8EE6
-:102FC000EF121AFA0E0E0EEED3953CE4953B40023A
-:102FD000AE3CEED3940874809481400A7E03900046
-:102FE000027402121AFAAF0612326E22AE07ED54C4
-:102FF00003640160037F1022ED547CC394045003EA
-:103000007F0B22746E2EF8740246F674992EF582A8
-:10301000E434FAF583EDF07F0022BF03067CFF7DE8
-:10302000E080047CFF7DE28D828C83E04480F0E5CB
-:103030008224041222A1E04480F0746E2FF87404FC
-:1030400046F67F002212104BE53A64097004E53918
-:103050006401601690FF83E0540FFFC3E53A9FE5DB
-:1030600039940040051228D7800312327A0210CE1C
-:1030700090FFFCE020E71FC2AF7DFFAC051DEC60B8
-:10308000157E047F00EF1FAA0670011E4A60EC90B7
-:10309000FF92E4F080EF2212104B7866E6FE08E61D
-:1030A000FF30E01230E10F90FFFCE04420F07F049D
-:1030B000121261121DF60210CE8F23C208122AC707
-:1030C0001222C0787E122342240B1222A1E054F86F
-:1030D000F0123284AF23121387228E5F8F60E56077
-:1030E0001560AE5F7002155FD39400EE9400400946
-:1030F0007E077FD012102480E52211DC2EC724B079
-:1031000032603090303E316F2F82272E2C8031126A
-:1031100031311E642F112C180E12104B7886122399
-:103120003120E1077F121231A9800A7886E6FF126A
-:10313000240A1231A90210CE12104B7887122331C3
-:1031400020E2077F111231A9800A7887E6FF122F4B
-:103150004E1231A90210CE8F61122F4EAF61122A8A
-:10316000C71222C0123284746E2561F874FD56F6BF
-:10317000AF611213872212104BE53A64097004E51F
-:103180003964016005122CD88006121E14121E1C10
-:103190000210CE122A5412130390F804E0FF6005C7
-:1031A0007D011212A01229DE12133F1211BC80E31E
-:1031B000121D8EEF121AFAE4F533F534EF600302B4
-:1031C000327AE4FF12326E2290FFF0E0FF54A060EA
-:1031D000F7EF30E50890FFF04420F0C322D32290AF
-:1031E000FFF0E0FF542860F7EF30E50890FFF0446F
-:1031F00020F0C322D322EF30E708121D45E054DF50
-:10320000F022EF121D98E054DFF022810182028348
-:10321000038740004000400040004000400008009C
-:10322000787E1222B7A3A3E0FF30E706547FF04474
-:1032300080F022853B39853C3A90FF82E054F7F0DC
-:10324000A3E0547FF022E4FEEE90320493B507022F
-:10325000D3220EBE07F2C32200081828380181903D
-:103260000A02000011130012104B7F021210DA1232
-:103270001DF60210CE7539008F3A121CE0122CD8C0
-:0E32800022121E1C121DDF121E1422C2082272
-:00000001FF
-//**************************************************************
-//* Edgeport Binary Image (for TI based products)
-//* Generated by TIBin2C v2.00 (watchport)
-//* Copyright (C) 2001 Inside Out Networks, All rights reserved.
-//**************************************************************
--- zfcpdump-kernel-4.4.orig/firmware/ess/maestro3_assp_kernel.fw.ihex
+++ /dev/null
@@ -1,120 +0,0 @@
-:10000000807930008079B4038079B4038079FB0073
-:100010008079DD008079B4038079320380798702AA
-:100020008079B4038079B4038079B4038079B40310
-:1000300080791A038079B40380792F028079B40320
-:100040008079B4038079B4038079B4038079B403F0
-:100050008079630080796B008079B4038079B40380
-:1000600080BF7C2C0688048840BE20BC09AE0010EE
-:100070000AAE0100386908EB53005A6908EBD60054
-:100080000900888B806988E3360030BE20BC09698E
-:1000900001B8099041BE41BE286988EB780041BE95
-:1000A00040BE8079380041BE41BE3A90386908E3CD
-:1000B00056003A9041BE40BE00EF3A90396908E3DD
-:1000C0005E003A9000EF0B690C668CEF0A690C66D3
-:1000D0000B62096600EF10690F6604EF88E3750094
-:1000E0000E690F6610620D6600EF0E690D6600EF77
-:1000F00070AE010020BC27AE0100396908EB5D003D
-:10010000266901B826902600888B806988E3CB0099
-:100110002890280D114200E17A00114700E1A0006B
-:10012000807A630011B80A66096204E37A000B0C56
-:1001300005400A1001BA1290120C02408079AF00FB
-:10014000807A6B0002BE0E620D6610BA44E37A003C
-:10015000100C05400E1001BA1290120C0240031050
-:1001600002BA1290120C0040031088E3BA00041087
-:100170008079BC00041001BA1290120C0140050CE9
-:100180000340060C04401110B0BFFF011290120C86
-:10019000064020BC00EF26AE28107069D0BF0100D9
-:1001A000709088E37A0028AE000000EF70AE000384
-:1001B000700C0CB05AAE000000EF807A8A037F69A1
-:1001C00001B87F905600888BA00C08B071AF00B0CA
-:1001D000714E00E2F30056AE57105600A00C08B066
-:1001E00056808079A1031008A0BF591004E3A10331
-:1001F00056808079A103807A8A0301BF43BE59BE2D
-:100200007C90376988E30D0101BA08E30C0171AEF7
-:100210000400710C0050366937900ABF9E108A8B1B
-:1002200080AF1480804C0ABF600500F50ABF20052E
-:1002300000B917BBA090176988E34801170D00E1CA
-:1002400027010CBF78050DBF7C0580792B010CBF01
-:1002500038050DBF3C05006908E335018C8B59BE9C
-:1002600007BBA09020BC807957010C038B8B03B98E
-:100270000988C6BE3E01AC69AB90AD69AB9013086E
-:100280000A6644E3440109030C8320BC80795701CA
-:10029000556988E35701387C0BBF780500F50BBF23
-:1002A000380507B90988C6BE5601AB10AA90746913
-:1002B00088E3630172AE400500F572AE000561AEE1
-:1002C0003B10807AF602786988E382018C8B0CBF40
-:1002D000600500E5407C140820BA12883D73807ADE
-:1002E00080033E73807A80038C8B0CBF6C0500E525
-:1002F000407C14082CBA12883F73807A80034073C4
-:10030000807A8003756988E38E0172AE480500F536
-:1003100072AE080561AE4110807AF602796988E311
-:10032000AD018C8B0CBF600500E5407C140818BA49
-:1003300012884373807A80034473807A80038C8BA5
-:100340000CBF6C0500E5407C140824BA1288457384
-:10035000807A80034673807A8003766988E3B901E6
-:1003600072AE580500F572AE180561AE4710807A7E
-:10037000F6027A6988E3D8018C8B0CBF600500E532
-:10038000407C140808BA12884973807A80034A7343
-:10039000807A80038C8B0CBF6C0500E5407C1408D0
-:1003A00014BA12884B73807A80034C73807A80036E
-:1003B00021BC1CAE90108A8B0ABF600500E5407C12
-:1003C000120804B813888D8B0DBF6C0500E5407CC6
-:1003D000150804B81188807A4A038A8B0ABF600521
-:1003E00000E5407C1F7303B90988C6BEF9018A5431
-:1003F00003BEA098207303B90988C6BE01028A54BF
-:1004000003BEA098201F1F2F269820BC356988E3C3
-:10041000A103336901B83390A0BFEE0208E3A10342
-:10042000339000BF516988E31F02347380BE605768
-:1004300003BE7E9F59BE34907E69510D139020BC3F
-:100440005C6988E3A1035E7380BE605703BE7E9F34
-:1004500059BE5E907E695C0D13908079A103807A0D
-:100460008A0301BF43BE776988E34E0261AE4D1037
-:100470006100888B806988E34E027190710D0B00DA
-:10048000A0AF1080A0AF108010080A6608E34902F0
-:10049000090010080C6688E34E020B8020BC7B69C3
-:1004A00088E3A1030ABF9E108A8B80AF1480804C22
-:1004B00000E166027C6990BF6005729072037C69FE
-:1004C00090BF640573907304807970027C6990BF5B
-:1004D0002005729072037C6990BF240573907304A9
-:1004E0007C6901B87C900ABFFD108A8B80AF1080B8
-:1004F0004F738A5403BE809821BC26738B5403BE6D
-:100500008B618C9803BE806180988079A103807A8A
-:100510008A03280D114700E1BE0212AF064012699E
-:10052000B0BF000C88E3B602A0BF000888E3B202A7
-:100530001269B0BF000CA0BF000488E3A3020969E0
-:100540000B908079A5020BAF054001690590026907
-:100550000690114300E1ED021169C0BF0020119027
-:100560008079ED0209690B908079B8020BAF0540E4
-:1005700005AF034006AF04408079ED0212AF06409C
-:100580001269B0BF000C88E3E702A0BF000888E34F
-:10059000E3021269B0BF000CA0BF000488E3D402DC
-:1005A0000D6910908079D60210AF05400169059061
-:1005B00002690690114300E1ED021169C0BF0020FD
-:1005C00011908079ED020D6910908079E90210AFE9
-:1005D000054005AF034006AF044020BC7069719030
-:1005E000807A7800716970908079A10320BC6103E2
-:1005F0008B8B806988EF7202720304787190710DA1
-:100600008A8B0B0003B90988C6BE0903A869AB90A1
-:10061000A869AA9010080A6644E30F0309001008AD
-:100620000C6688E314030B8020BC616901B86190FB
-:100630008079F702807A8A03355D0100346901B858
-:1006400034900ABF9E108A8B80AF1480804872AEAF
-:10065000500500F572AE100561AE5110807AF602B9
-:100660008079A103807A8A03355D02005E6901B852
-:100670005E900ABF9E108A8B80AF1480804772AE56
-:10068000580500F572AE180561AE5C10807AF6026E
-:100690008079A1031C00888B806988EF1D901D0D57
-:1006A0000F1010668CE358030E6910660F620D661A
-:1006B0000FBA01E37A0310048A8B03B90988C6BE16
-:1006C0006C038C6AAA61AB988C6AAB61AD988C6A3A
-:1006D000AD61A9988C6AA961AA98047C8B8B047C73
-:1006E0008D8B047C898B047C14080E6608E37903E7
-:1006F0000D04108421BC1C6901B81C9080794A0348
-:1007000003B909888A8BC6BE8803AC5403BE8C61CA
-:10071000AA9800EF20BC46BE09086B900A086C90AE
-:100720000B086D901A0862901B0863901E08649075
-:1007300059BE1E88658066816782688369846A8580
-:1007400000EF20BC6B6909886C690A886D690B88A9
-:1007500062691A8863691B8864691E88650066017E
-:0A0760006702680369046A053ABEE7
-:00000001FF
--- zfcpdump-kernel-4.4.orig/firmware/ess/maestro3_assp_minisrc.fw.ihex
+++ /dev/null
@@ -1,51 +0,0 @@
-:1000000080BF1E106E906E00888B806988EF6F90A5
-:100010006F0D006908EB120420BC6E6901B86E9088
-:10002000807903040EB9078843BE01BF47BE41BEB5
-:10003000807A2A0040BE2930CCEF41BE807A280069
-:1000400040BE2830CCEF076908E32A0409692C90E8
-:1000500080792C040D692C9009101A880A1001BAB5
-:100060001B880D101C880E1001BA1D8880BFED0082
-:100070001E880C05240104B92790186908E3B3040D
-:100080002D901369A0BF987504F72DAEFF008D8BDE
-:10009000196908E363041A6908E3560407B9098873
-:1000A000C6BE5304A910AD9080797C0403B90988B9
-:1000B000C6BE60048918226CAD90A910236E226C14
-:1000C000AD9080797C041A1008E36F0403B90988A5
-:1000D000C6BE6C04A910A090AD9080797C0401B9D3
-:1000E0000988C6BE7B048918226CA090AD90A91027
-:1000F000236E226CA090AD902D6908E39C0424012E
-:1001000003B702B91888898B2C028A10047CA0904E
-:100110002B691F88807E5B052A690988898BA099D5
-:100120008A10A0902B691F88807E5B052A69098848
-:10013000898BAF99997B840424010F061B1013202F
-:100140001B90A0BFFF7F44E3AC041B90898B807A97
-:100150001A05276901BA2790807A2305276908E3E1
-:100160009E0480790F052406261013202690A0BF38
-:10017000FF7F04E3C0048D8B807A1A058079B40474
-:100180002690131026301B908D8B807A1A05807A6A
-:100190002305271001BA279008E3B40424010F06B1
-:1001A000898B1A6908E3EA04196988E3E00403B952
-:1001B0000988C6BEDD04A01FAE2FA99880790F055F
-:1001C00001B9188807B90988C6BEE704EE10A990DE
-:1001D00080790F05196908E3FE0403B9098846BE52
-:1001E000C6BEFA04A0171EBEAE1FBFBF00FF13BEDF
-:1001F000DFBF8080A99947BE80790F0501B90988C2
-:10020000C6BE0E05A016A026B7BF00FF1EBEA01ECC
-:10021000AE2EBFBF00FF13BEDFBF8080A9990C8543
-:100220000F86076988E31605070D108559BE1E88DD
-:100230004ABE00EF1E101C901F101D90A0101E90B3
-:10024000A0101F9000EF1E101C3020901B73205434
-:1002500003BE259825101C2025902573145403BE39
-:100260008E8B80982F6988E3390559BE07BB806162
-:100270008098A08B1F101D3021901B73215403BE4A
-:100280002E982E101D202E902E73155403BE80988C
-:100290002F6988E34F0559BE07BB80618098A08B0A
-:1002A000186908EF2573165403BEA0982E731754CF
-:1002B00003BEA09800EFA08BC6BE6B0559BE04BB61
-:1002C00090AA04BE1EBEE099E08BA069D090A06900
-:1002D000D0901F0805B81F88908BA069D090A069A6
-:1002E0009090D08BD88B1FBE00EF00000000000064
-:1002F00000000000000000000000000000000000FE
-:1003000000000000000000000000000000000000ED
-:020310000000EB
-:00000001FF
--- zfcpdump-kernel-4.4.orig/firmware/kaweth/new_code.bin.ihex
+++ /dev/null
@@ -1,206 +0,0 @@
-:10000000B6C3AABBCCDD9FCFDE06E7570000C4060F
-:1000100097C1E767FF1F28C0E787000424C0E76790
-:10002000FFF922C097CFD70900C0E709A2C0BE06DA
-:100030009FAF3600E70500C0A7CFBC0697CFE757B4
-:100040000000B806A7A1B80697CFE757000014082C
-:100050000AC0E7570000A4C0A7C07A069FAF920766
-:10006000E70700001408E757FFFFBA069FA0380013
-:10007000E759BA06BE069FA03800C809CA0608623A
-:100080009FA13608C00976060060A7C07A069FAF18
-:10009000CC02E7570000B806A7C17A069FAF04005C
-:1000A000E75700008E060AC1E70920C01008E7D014
-:1000B0001008E767400010089FAF920CC009D006F7
-:1000C000006005C4C059BE0602C09FAFEC009FAFE0
-:1000D0003402E7570000A6069FA07A02A7CF7A064F
-:1000E0004802E709BE06D006C83704009FAF0803E0
-:1000F00097CFE7570000CE0697C0D70900C0C1DFF1
-:10010000C809C606086214C02704C6061094F00782
-:1001100010080200C107010070000400F007300160
-:10012000060050AFE707FFFFD006E7070000CE0646
-:10013000E70500C097CFD70900C0C1DF4802D0094A
-:10014000C6062702C606E70500C097CF4802C83793
-:100150000400000C0C00006021C0C0373E0023C921
-:10016000C057B4051BC8C0173F00C067C0FF3000B0
-:100170000800F007000004000002C0174C00300027
-:100180000600F007A0010A004802C1070200D709D3
-:1001900000C0C1DF51AFE70500C097CF9FAF080394
-:1001A0009FAF7A0297CF9FAF7A02C9370400C1DFB1
-:1001B000C809A20650026702A206D107000027D88C
-:1001C000AA06C0DF9FAFC40197CFE7570000D20651
-:1001D00097C1E7570100A80697C0C809A0060862A2
-:1001E00097C00002C0170E0027003401270C0C0036
-:1001F0003601E70750C312C0E707CC0B0200E70740
-:100200000100A806E707050090C097CFC809A4061B
-:10021000086202C0106407C1E70700009E06E707F6
-:100220007204240097CF2704A406C8170E002702E3
-:100230009E06E7078004240097CFD70900C0C1DFDE
-:10024000E7570000900613C19FAF0602E757000072
-:100250009E0613C0E7099E063001E707F20532014A
-:10026000E707100096C0E7099E06900604CFE757FF
-:1002700000009E0602C19FAF0602E70500C097CFAF
-:10028000D70900C0C1DF0892E7570200AA0602C3DF
-:10029000C809A4062702A606086203C1E70500C034
-:1002A00097CF2704A406E70500C0F0074000080028
-:1002B000F007000004000002C0170C003000060028
-:1002C000F00746010A00C8170400C107020051AF39
-:1002D00097CFE7570000960697C0C1DFC80996067A
-:1002E000270496062752980603C1E7079606980644
-:1002F000C0DF1702C8170E009FAFBA03C805006021
-:1003000003C09FAF240397CF9FAF080397CF570237
-:10031000C907A406D70900C0C1DF08621BC050048A
-:100320001102E70500C0C90597CF9702CA09D60692
-:10033000F21701000400F22700000600CA172C0083
-:10034000F87701000E0006C0CAD9F857FF000E006A
-:1003500001C1CAD9221C0C00E2270000E2170100EB
-:10036000E2270000CA05000C0C00C0174100C0675E
-:10037000C0FF300008000002C0170C00300006006B
-:10038000F007DA000A00F00700000400000C080083
-:1003900040D10100C019CE06C059C20604C949AFF8
-:1003A0009FAFEC004AAF6710CE06C8170400C10724
-:1003B0000100D70900C0C1DF50AFE70500C097CFEB
-:1003C000C0070100C109AC06C177010097C1D87709
-:1003D000010012C0C9076A069FAF080404C1C177B3
-:1003E000080013C097CFC177020097C1C1771000F2
-:1003F0000CC09FAF2C0497CFC177040006C0C9077B
-:1004000070069FAF080497C000CF009097CF50545C
-:1004100097C1705C0200020097C1705C0400040088
-:1004200097CF8001C0006000300018000C0006006B
-:100430000000CB09B206CC09B4060B5311C0C902A7
-:10044000CA071C049FAF080497C00AC882080ACFD5
-:1004500082089FAF080497C005C28930826078C1C6
-:10046000009097CF8910095379C2893082087ACFDA
-:10047000C0DF97CFC0DF97CFE70996C09206E709A4
-:1004800098C094060FCFE70996C09206E70998C076
-:100490009406E7099E063001E707F2053201E707F7
-:1004A000100096C0D70900C01702C8099006C837C7
-:1004B0000E00E7772A00920630C09702CA09D606D6
-:1004C000E777200092060EC0F21701001000F22715
-:1004D00000001200E7770A009206CA051EC09702C4
-:1004E000CA09D606F21701000C00F22700000E0020
-:1004F000E7770200920607C0F21701004400F227D6
-:100500000000460006CFF21701006000F22700004D
-:100510006200CA059FAF08030FCF57020902F10915
-:1005200094060C00F1DA0C00C80998065002670224
-:100530009806D1070000C905E7099E069006E7570F
-:100540000000900602C09FAF0602C805E70500C084
-:10055000C0DF97CFD70900C0170017029702C00964
-:1005600092C0E707040090C0CA09D606E70700005A
-:10057000A806E7076A040200C077020008C0F21765
-:1005800001005000F227000052009FCF2406C077E0
-:10059000100006C0F21701005800F22700005A00B0
-:1005A000C077800006C0F21701007000F22700003B
-:1005B0007200C07708001DC1F21701000800F22781
-:1005C00000000A00C077000206C0F21701006400B4
-:1005D000F22700006600C077400006C0F217010055
-:1005E0005C00F22700005E00C077010001C01BCF55
-:1005F0001ACFF21701000000F22700000200C8091C
-:100600003401CA171400D877010005C0CAD9D857D9
-:10061000FF0001C0CAD9E21994C0E2270000E21726
-:100620000100E22700009FAF40069FAFC401E757DB
-:100630000000D2069FA10E0ACA05C805C005E7053D
-:1006400000C0C0DF97CFC809A006086297C0270482
-:10065000A0062752A20603C1E707A006A2069FAF85
-:100660000803E7570000AA0602C027DAAA0697CFB8
-:10067000FFFFFFFFFFFF0000000000000000000080
-:10068000000000000000000000000000000000006A
-:10069000000000000000000000000000000000005A
-:1006A000000000000000000000000000000000004A
-:1006B000000000000000000000000000000000003A
-:1006C00000000000000000003F00000000000000EB
-:1006D000000000000000FFFF01000000000000001B
-:1006E000FFFFFB13E7570080B20006C2E707EE0BDF
-:1006F0001200E707340CB200E707C607F202C80988
-:10070000B400F80702000D00D7090EC0E70700008B
-:100710000EC0C809DE00C8170900C907DA06C007FD
-:100720000400680A00DA7DC1E709C0007C06E70919
-:10073000BE007806E7091000BC06C807D6079FAFC1
-:10074000AE079FAF000AC809DE00000E0F004190FF
-:100750009FDE060044AF2700B2062700B40627003C
-:10076000B606C007740044AF2700D6060800009004
-:10077000C1073A00200001DA7DC19FAFBA09C00766
-:10078000440048AF27007A069FAF960AE7070100AA
-:10079000C006E7050EC097CF49AFE78743000EC0FC
-:1007A000E707FFFFBE069FAFAE0AC007010060AFBC
-:1007B0004AAF97CF00080908110800DA7CC197CF2B
-:1007C0006704CC02C0DF5194B1AF0600C1DFC90994
-:1007D000CC02496275C1C0DFA7CFD6020E0024004B
-:1007E000800422004E05D0000E0AAA003008BE0088
-:1007F0004A0A1000200004006E0402006A04060089
-:10080000000024C0040428C0FEFB1EC0000422C057
-:10081000FFF4C000900900000000FFFF56086008C8
-:10082000D008DA0800090409080932094209500908
-:1008300052095A095A092702CA0697CFE70700004A
-:10084000CA060A0E0100CA570E009FC35A09CA37CA
-:1008500000009FC25A090AD2B2CF1608C809DE00AA
-:1008600007069FCF6C091702C809DE00000E0F00B3
-:1008700041909FDE0600C805305006009FC85A0907
-:10088000270C0200B006C009B2062700B406E7072D
-:100890000000AE0627008006001C06002700B606F2
-:1008A00041906750B0060DC067007E06270C060019
-:1008B0008206E707BC088406C8077E06419051AF50
-:1008C00097CF9FAF480CE709B606B406E709B00614
-:1008D000AE0659AF97CF270C0200AC0659AF97CFA1
-:1008E000090C020009DA49D2C919D606C8077E06E2
-:1008F000E00700006002E0070400D007CC0848DBF6
-:10090000419050AF97CF59AF97CF59AF97CFF0578E
-:100910000600060025C1E7077006800641906700C3
-:100920007E06270C06008206E7078C098406C807A6
-:100930007E06419051AF97CF070C0600C7570600BF
-:100940000FC1C807700615CF000C020000DA40D1B5
-:100950002700C2061ECF1DCF270C0200CC0619CFE0
-:1009600027022001E70708002201E7071300B0C0B3
-:1009700097CF419067007E06E70182062702800636
-:10098000E7078C098406C8077E06C107008050AFC0
-:1009900097CF59AF97CF006005C0E7070000C406A6
-:1009A000A7CF7C069FAF000AE7070100C40649AF46
-:1009B000D70900C007AFE70500C04AAFA7CF7C0644
-:1009C000C007FE7F44AF4000C03700014190C037F0
-:1009D0000800DFDE5006C057100002C2C00710003A
-:1009E00027009A0641909FDE400644AF27009C06F0
-:1009F000C0099A06419000D200D89FDE080044AF9B
-:100A00002700C80697CFE787008428C0E767FFFB69
-:100A100024C097CFE7870100D206E7570000A80659
-:100A200097C19FAF000AE787000622C0E7070000D2
-:100A300090C0E767FEFF3EC0E70726000AC0E787D1
-:100A400001003EC0E707FFFFBE069FAF100B97CF28
-:100A50001700A7AF7806C00527007606E7870100D4
-:100A6000D2069FAF000AE7070C0040C09FAF100BF3
-:100A700000902700A6062700AA06E709B206B406DA
-:100A80002700AE062700AC069FAFAE0AC0070000E5
-:100A90002700B2022700B40227008E06C007060016
-:100AA000C809DE00C8170300C9077006290A00DA62
-:100AB0007DC197CFD70900C0C1DF009027009606FF
-:100AC000E707960698062700A006E707A006A206F5
-:100AD0002700A6062700900627009E06C8099C0648
-:100AE000C1099A06C907A40611020902C8174006DF
-:100AF00001DA7AC15194C809C806C907C606C109F6
-:100B00009A0611020902C817080001DA7AC1519445
-:100B1000E70500C097CFE7570000760697C09FAF64
-:100B20000400E709BE06BA06E757FFFFBA0604C18C
-:100B3000E707100BB80697CFE7173200BA06E7674A
-:100B4000FF07BA06E707460BB80697CFE75700003E
-:100B5000C00623C0E707040090C0E707008080C0FC
-:100B6000E707000080C0E707008080C0C0070000E2
-:100B7000C0070000C0070000E707000080C0E707CB
-:100B8000008080C0E707008040C0C0070000E70782
-:100B9000000040C0E707000080C0E707040090C0E5
-:100BA000E707000240C0E7070C0240C0E70700006B
-:100BB000C006E7070000B806E7070000D206D7091D
-:100BC00000C0C1DF9FAF3402E70500C09FAFC40182
-:100BD00097CFD70900C0170017029702E757000008
-:100BE000A80606C0C00992C0C07709029FC15C0573
-:100BF0009FCF3206D7090EC0E70700000EC09FAF97
-:100C0000020CE7050EC097CFD70900C01702C8092C
-:100C1000B0C0E767FE7FB0C0C87700209FC164EB1B
-:100C2000E7570000C8029FC180EBC899CA02C86795
-:100C300004009FC196EB9FCF4CEBE7070000A6C0D6
-:100C4000E709B0C0C802E7070300B0C097CFC009EA
-:100C5000B006C037010097C9C909B2060200419029
-:100C60004802C91706009FAF08049FA2720C02DA5F
-:100C700077C1416071C197CF170257024304210425
-:100C8000E00043042104E00043042104E000C10724
-:100C90000100C905C80597CFE70701008E06C80700
-:100CA0008606E70700008606E70710088806E707BC
-:100CB00004008A06E707BC0C8C06C107038050AF0E
-:0C0CC00097CFE70700008E0697CF0000DA
-:00000001FF
--- zfcpdump-kernel-4.4.orig/firmware/kaweth/new_code_fix.bin.ihex
+++ /dev/null
@@ -1,40 +0,0 @@
-:10000000B6C3AABBCCDD0200080028002C003400D7
-:100010003C0040004800540058005E006400680046
-:100020006E006C00720076007C00800086008A0002
-:100030009000940098009E00A600AA00B000B400B2
-:10004000B800C000C600CA00D000D400D800E0004C
-:10005000DE00E800F000FC0004010A0118012201A2
-:1000600028013A013E017E0198019C01A201AC01E8
-:10007000B201BA01C001C801D001D601F401FC01EE
-:10008000080216021A0222022A022E023E0244022C
-:100090004A025002640262026C02720286028C0200
-:1000A00090029E02BC02D002D802DC02E002E8020A
-:1000B000E602F402FE0204030C0328037C0390030F
-:1000C00094039C03A203C003D003D403EE03FA03FA
-:1000D000FE032E0432043C0440044E0476047C04E7
-:1000E00084048A048E04A604B004B804BE04D204B6
-:1000F000DC04EE0410051A0524052A05360534052E
-:100100003C05420564056A056E058605220626063D
-:100110002C06300642064A064E06560654065A0675
-:1001200060066606E806EE06F406160726072C07A4
-:10013000320736073A073E07520756075A07640741
-:1001400076077A07800784078A079E07A207DA07DF
-:10015000DE07E207E607EA07EE07F207F6070E08F2
-:10016000160818081A081C081E0820082208240867
-:10017000260828082A082C082E0832083A084608BB
-:100180004E0854085E0878087E08820886088C08A5
-:10019000900898089E08A408AA08B008AE08B408F9
-:1001A000BE08C408C208CA08C808D408E408E80899
-:1001B000F608140912091A092009260924092A092E
-:1001C0003E094C0956097009740978097E097C09B1
-:1001D000820998099C09A009A609B809DC09E8095F
-:1001E000EC09FC09120A180A1E0A420A460A4E0ABB
-:1001F000540A5A0A5E0A680A6E0A720A780A760A6D
-:100200007C0A800A840A940AA40AB80ABE0ABC0AB4
-:10021000C20AC80AC60ACC0AD00AD40AD80ADC0A1A
-:10022000E00AF20AF60AFA0A140B1A0B200B1E0B4C
-:10023000260B2E0B2C0B360B3C0B420B400B4A0BA8
-:10024000AA0BB00BB60BC00BC80BDA0BE80BEC0B10
-:10025000FA0B4A0C540C620C660C960C9A0CA00C0F
-:0E026000A60CA40CAC0CB20CB00CC00C000030
-:00000001FF
--- zfcpdump-kernel-4.4.orig/firmware/kaweth/trigger_code.bin.ihex
+++ /dev/null
@@ -1,13 +0,0 @@
-:10000000B6C3AABBCCDDC807A000F0075E0006009F
-:10001000F0070A000800F00900000200E7073600B8
-:100020000000F00700000400E70750C310C0F0090B
-:100030000EC00000E78701000EC097CFD70900C0AF
-:100040001702C807A000E71750C310C030D804003B
-:10005000305C08000400B0C00600C805E70500C019
-:10006000C0DF97CF49AFC007000060AF4AAF000CB8
-:100070000C0040D2001C0C0040D230000800F007F9
-:1000800000000400F0078600060067CF270C02007E
-:100090000000270C00000EC049AF64AFC00700008D
-:1000A0004BAF4AAF5ACF0000000000000000000034
-:0600B000940005000000B1
-:00000001FF
--- zfcpdump-kernel-4.4.orig/firmware/kaweth/trigger_code_fix.bin.ihex
+++ /dev/null
@@ -1,3 +0,0 @@
-:10000000B6C3AABBCCDD0200060018003E0080008B
-:060010009800AA000000A8
-:00000001FF
--- zfcpdump-kernel-4.4.orig/firmware/keyspan/mpr.HEX
+++ /dev/null
@@ -1,104 +0,0 @@
-:0300330002001AAE
-:04001A0053D8EF3296
-:100003008E568F57E5571557AE56700215564E60EC
-:0700130005120FA280EE228E
-:0300230002004692
-:10004600C0E0C083C082C086758600C0D075D00867
-:1000560030990E300B07A20E929B853699C299D223
-:10006600122012030202F9C2123003197E7E7F406B
-:10007600751A7E751B407517007E7D7FC075187DCD
-:100086007519C080177E7D7FC0751A7D751BC0757A
-:1000960017017E7E7F4075187E751940200B03027E
-:1000A6000184E53AC39553503C200C342009319025
-:1000B6007F9BE055387029301012AF3A053AE51BA0
-:1000C6002FF582E4351AF583E013920EAF3A053A1E
-:1000D600E51B2FF582E4351AF583E0F5360202F7C3
-:1000E600C20B0202F7300311907FC7E4F0A3E0547D
-:1000F60002F51DA3E0F51C8011907FC9E4F0907F06
-:03004300020F00A9
-:03000000020026D5
-:0C002600787FE4F6D8FD75815A020A3399
-:40010600C6E05402F51DA3E0F51CE51724FF9203300D0DC20D907FBB7401F0C20B0202F7E51D6005C20B0202F7851C53851982851883E013920D7512FF200C3A2009379082
-:400146007F9BE05538702F30101C851982851883A3E013920E851982851883A3A3E0F536753A030202F7753A02851982851883A3E0F5360202F7753A01C20B0202F73003FE
-:400186000E907FC6E05402F51DA3E0F51C800C907FC8E05402F51DA3E0F51CE53AC395535003020268E51D6007C214C2050202F7851C53851B82851A83E013920D7512FF61
-:4001C600300C03020260300903020260907F9BE05538600302026030101B851B82851A83A3E013929B851B82851A83A3A3E0F599753A03800D851B82851A83A3E0F5997575
-:400206003A02E53AC395534026300307907FC7E4F08005907FC9E4F0E51724FF9203200D030202F7C20D907FBB7401F00202F7301012AF3A053AE51B2FF582E4351AF58394
-:40024600E013920EAF3A053AE51B2FF582E4351AF583E0F536D20B0202F7753A01C2140202F7300C030202F53009030202F5907F9BE055387079301012AF3A053AE51B2FF2
-:40028600F582E4351AF583E013929BAF3A053AE51B2FF582E4351AF583E0F599E53AC395534022300307907FC7E4F08005907FC9E4F0E51724FF9203300D36C20D907FBB0E
-:4002C6007401F0802C301012AF3A053AE51B2FF582E4351AF583E013920EAF3A053AE51B2FF582E4351AF583E0F536D20B8002C214D201209803020435C298200203020383
-:40030600A2201527AF39053974802FF582E4347EF583E599F030104DAF39053974802FF582E4347EF583E598F0803A859955E555B54704D209802EE555B54604C20980251C
-:40034600AF39053974802FF582E4347EF583E555F0301011AF39053974802FF582E4347EF583E598F0D20FE539C395435003020433907FB8E030E116E539C39440500302F5
-:40038600043315391539052B433401020433907FB7E539F0753900C202020433201527AF39053974002FF582E4347EF583E599F030104DAF39053974002FF582E4347EF594
-:4003C60083E598F0803A859955E555B54704D209802EE555B54604C2098025AF39053974002FF582E4347EF583E555F0301011AF39053974002FF582E4347EF583E598F0EA
-:40040600D20FE539C395434024907FB6E030E112E539C39440401615391539052B433401800B907FB9E539F0753900D202D201300105C201020056D0D0D086D082D083D02F
-:40044600E032907FBCE020E154E5346050E531704CE53430E10BE4F52F753401753102800EA208E433F52FC208E4F534753110E4F5567E007B0074242556F9EE3400FA12D8
-:400486000C79FF74002556F582E4347DF583EFF00556E556B40CDB907FBD740CF0907FCAE030E1030205D1E4F55674402556F582E4347DF583E0FFE5567C007B00243BF903
-:4004C600EC3400FAEF120C920556E556B418DBE53B601175C92075C836853CCA853DCBE4907F9FF0E53E139210929F853F38E540139215E5416009907F98E054FBF0800744
-:40050600907F98E04404F0E5426009907F98E0547FF08007907F98E04480F0E548600BC20CC209907F95E04402F0E549600CD209433401907F95E04402F0E54A600DC2AFBB
-:40054600C20BD200E4F553F53AD2AFE54B6005301502D209E54C6015907F95E054FDF0907F9EE04402F0907F98E054FDF0E54D600AD29CC298752C0175311EE54E6007C227
-:400586009CE4F539F52CE54F6003E4F539E5506002D207E551600AE54D7002F531E5514234E552601F907FD77411F07431F07412F07432F07413F07433F07414F07434F067
-:4005C600D203D202D208E4907FCBF0A20CE433FF652960058F29433401A209E433FF652A60058F2A433401907F9BE0FF54086408F55765256006855725433401EF5410643A
-:4006060010F55765266006855726433401EF54406440F55765276006855727433401EF54206420F55765286006855728433401907F9AE054406440F557652E600685572E5B
-:40064600433401300735C2AF300218907FB8E020E127E5396009907FB7F0E4F539C202C2078016907FB6E020E10FE5396009907FB9F0E4F539D202C207D2AF20053D3003DB
-:400686001E907FC6E020E133907E40E013920D753A01907FC7E0F553D2057512FF801C907FC8E020E115907DC0E013920D753A01907FC9E0F553D2057512FF2014332000E6
-:4006C60006E53A6553702A30051A300309E4907FC7F0C2038007E4907FC9F0D203C205E4F553F53A300D0AC20DC200907FBB7401F03014030207BF2005030207BF300C0314
-:400706000207BF3009030207BF907F9BE0553860030207BF30030C7E7E7F4075587E755940800A7E7D7FC075587D7559C0301012AF3A053AE5592FF582E43558F583E0137C
-:40074600921AAF3A053AE5592FF582E43558F583E0F557E53AC39553502A301012AF3A053AE5592FF582E43558F583E013920EAF3A053AE5592FF582E43558F583E0F53688
-:40078600D20B8015C20B300309E4907FC7F0C2038007E4907FC9F0D203301004A21A929BD214C2AF855799200B0D300D0AC20DC200907FBB7401F0D2AF22907FE9E0120C70
-:4007C600A4091C0009890109E60307E306090D0809010908E90A08F80B00000A24907FEBE024FE601C14700302087924026003020A24740D907FD4F07487907FD5F0020AE6
-:400806002B907FEAE0B401047F0280027F037582D875830DEFF07582D175830DF07582CA75830DF07582C375830DF0907FEAE00475829E75830DF0907FEFE0FE907FEEE07B
-:400846007C002400F55AEC3EF55975150D75169975829B75830DE0751300F514D3E514955AE51395594006855913855A14120BBA020A2B907FEAE0700B7556FF75570D7503
-:4008860058DC802D907FEAE0B4010B7556FF75570D7558E0801B907FEAE0B4020B7556FF75570D7558F080097556FF75570E75581E907FEEE0755900F55AAE57AF588E1512
-:4008C6008F168F828E83E0FEA3E08E13F514D3955AE51395594006855913855A14120BBA020A2B907F00E511F0907FB57401F0020A2B907FEAE0F511020A2B120C24907F84
-:40090600EAE0F510020A2B907F00E510F0907FB57401F0020A2B907FE8E0247F602714603424026003020A24A216E433FF25E0FFA218E4334F907F00F0E4A3F0907FB57455
-:4009460002F0020A2BE4907F00F0A3F0907FB57402F0020A2B907FECE0F45480FFC4540FFFE054072F25E024B4F582E4347FF583E054FD907F00F0E4A3F0907FB57402F00B
-:40098600020A2B907FE8E024FE601724026003020A2B907FEAE064016003020A24C216020A2B907FEAE07076907FECE0F45480FFC4540FFFE054072F25E024B4F582E4348D
-:4009C6007FF583E4F0907FECE05480FF131313541FFFE054072F907FD7F0E04420F08045907FE8E024FE601024027039907FEAE06401702AD216802D907FEAE07020907F77
-:400A0600ECE0F45480FFC4540FFFE054072F25E024B4F582E4347FF5837401F08007907FB4E04401F0907FB4E04402F022C210E4F510F534C209C20CC20BC214C20DC215A5
-:400A4600C211C207C212C20FC208F535F539F553F53AF533F530F52FF52EF52DF52CF52BF52AF529F528F527F526F525F524C205C217C219C216C218C204D213C206C20178
-:400A8600907F92E054FDF0D2E843D820907FDE7401F0907FDFF0907FAB74FFF0907FA9F0907FAAF05391EF907FAFE04401F0907FAEE0440FF0907FAC740EF0D2AFD2BCD247
-:400AC6001A120F7DC21730040312044830042A300627C206E51260161512907FD8E030E6047F0080027F20907F96EFF08006907F967420F0120B1480CD301707C217120741
-:400B0600C080C33019C0C219120EDC80B922E53160021531E53960556535704BE533F460020533E533C395444043C2AF30021B907FB8E020E12D907FB7E539F0C202E4F5AA
-:400B460039F533F5357512FF8019907FB6E020E112907FB9E539F0D202E4F539F533F5357512FFD2AF8006853935E4F533E52C6030200F07907F9BE030E00FE52D6006E497
-:400B8600F52D433401E4F5308014E530D39545500DE530B54506752D014334010530C20F22907FD9E030E2047F0080027F20907F96EFF022E51445136057AE13AF14D3EF0F
-:400BC6009440EE940040047E007F40C3E5149FF514E5139EF513E4FDEDC39FE49E501F851682851583E0FC74002DF582E4347FF583ECF00D0516E5167002051580DA907FC4
-:400C0600A97401F0907FACE04401F0907FB5EFF022907FACE054FEF0E4907FB5F022E4907F93F0907F9C7430F0907F967420F0907F947401F0907F9D74FFF0907F977486DF
-:400C4600F0907F957403F0907F9E7484F0907F98F0E4907FC7F0907FC9F0907FCBF075984043A810907FDE741FF0907FDF740FF0D20422BB010689828A83E0225002E722C3
-:400C8600BBFE02E32289828A83E49322BB010689828A83F0225002F722BBFE01F322D083D082F8E4937012740193700DA3A393F8740193F5828883E4737402936860EFA367
-:400CC600A3A380DFE4907F95F0907F94F0907F93F0907F9DE04402F0907F97E04442F0907F9C7410F0E4907F96F0907F9D74BEF03016047F8080027F00907F97EFF0E49045
-:400D06007F95F0907F9EF0907F98F022C0E0C0F0C083C082C085C084C086758600C0D075D0085391EF907FA97401F0120BBAD0D0D086D084D085D082D083D0F0D0E032C06A
-:400D4600E0C083C082C085C084C086758600907FC4E4F05391EF907FAB7404F0D086D084D085D082D083D0E03200000000000000000000000000000000000000000000001C
-:400D86000012011001FFFFFF40CD061C010100010200020902430001010080320904000007FF00000007050102400000070502024000000705030240000007058102400002
-:400DC600010705820240000107058302400001070584024000010403090410034B00650079007300700061006E002E034B00650079007300700061006E00200055005000A3
-:400E0600530048003100310032002D00530065007200690061006C0022035500530041002D003500330020003200300030003200610070007200320036000000C0E0C083DB
-:400E4600C082C085C084C0867586005391EF907FAB7402F0D206D086D084D085D082D083D0E032C0E0C083C082C085C084C086758600D2175391EF907FAB7401F0D086D01F
-:400E860084D085D082D083D0E032C0E0C083C082C085C084C086758600D2195391EF907FAB7408F0D086D084D085D082D083D0E032C0E0C083C082C085C084C08675860084
-:400EC6005391EF907FA97402F0D086D084D085D082D083D0E032120CCA120FB3907FD6E030E712E04401F07F0D7E00120003907FD6E054FEF0120C242200020E6900020EA3
-:400F06004200020D4500020E9000020F1000020F1400020D1200020F1C00020EB700020F2400020F3300020F2C00020F58C0E0C083C082C085C084C0867586005391EF90A9
-:400F46007FA97404F0D086D084D085D082D083D0E032C0E0C083C082C085C084C0867586005391EF907FA97408F0D086D084D085D082D083D0E032907FD6E054FBF0E044C1
-:3D0F860008F0301A04E04402F07FF47E01120003907FD6E054F7F0E04404F0227400F58690FDA57C05A3E582458370F922907FD6E04480F04387010000000000222C
-:00000001FF
-
-	The firmware contained herein is
-
-		Copyright (C) 1999-2001
-		Keyspan, A division of InnoSys Incorporated ("Keyspan")
-
-	as an unpublished work. This notice does not imply unrestricted or
-	public access to the source code from which this firmware image is
-	derived.  Except as noted below this firmware image may not be
-	reproduced, used, sold or transferred to any third party without
-	Keyspan's prior written consent.  All Rights Reserved.
-
-	Permission is hereby granted for the distribution of this firmware
-	image as part of a Linux or other Open Source operating system kernel
-	in text or binary form as required.
-
-	This firmware may not be modified and may only be used with
-	Keyspan hardware.  Distribution and/or Modification of the
-	keyspan.c driver which includes this firmware, in whole or in
-	part, requires the inclusion of this statement."
-
-static char theFirmwareDate53[] =
-	"04/26/2002  02:47p              11,570 USA53";
-
--- zfcpdump-kernel-4.4.orig/firmware/keyspan/usa18x.HEX
+++ /dev/null
@@ -1,141 +0,0 @@
-:030033000212F7BF
-:10000300E4907F93F0907F9C7430F0E4907F96F0BF
-:10001300907F94F0907F9D74FFF0E4907F97F09031
-:0F0023007F95F0907F9E7407F0E4907F98F02215
-:1000460030091812131BEFC3953C40030200D890E9
-:100056007FBF7401F0C209C200807730033B907FF6
-:10006600C6E020E16D12131BEFC394405064907EEE
-:1000760040E0139209907FC7E014F5192000116043
-:100086000FF5087E7E7F41750C7E750D41120CBA08
-:10009600C203E4907FC7F08039907FC8E020E13248
-:1000A60012131BEFC394405029907DC0E0139209B0
-:1000B600907FC9E014F519200011600FF5087E7DC8
-:1000C6007FC1750C7D750DC1120CBAD203E4907F09
-:1000D600C9F0907FB6E030E1030201601211D68FBD
-:1000E600191213278F36E519C3953A500F1212EBE2
-:1000F600EF30E008E53620E703300B5EC20BE5196A
-:0C003600907F987410F090C000E0FF2252
-:03004300021300A5
-:03000000020E00ED
-:400106006058B48003433602E53630E726E519D3942040037519208519087E7E7F80750C7E750D80AF36120F4BE51925E0907FB7F08027E519D3943F400375193F851908D4
-:40014600907E80E536F07E7E7F81750C7E750D81120CDFE51904907FB7F0907FCEE030E1062005030203C1C205E4F51874402518F582E4347CF583E0FFE5187C007B017AF1
-:400186007E79002400F9EC347EFAEF120ED20518E518B420D7907E00E06068907E03E060247F01E4FD1211B17F037DCD1211B1434680907F987414F090C000E546F0E490E0
-:4001C6007E13F08030907E01E0FF121035907E02E0FF12105B7F01907E11E0FD1211B17F037D071211B1434680907F987414F090C000E546F0907F987412F0E5404406903E
-:40020600C000F0907E03E07006907E13E07008E4907E13F07525FF907E05E06012A3E0543FF544907F987413F090C000E544F0907E07E0602BA3E0600543428080035342DA
-:400246007F5342FC907E09E06011434202A3E0FF1210A7907E0BE0FF1210CDAF42121081907E03E0600853427FAF42121081907E0CE06018A3E0600543460280035346FDB4
-:40028600907F987414F090C000E546F0907E0EE06018A3E0600543460180035346FE907F987414F090C000E546F0907E12E0F53AA3E013920DA3E0F53CA3E060054346108B
-:4002C60080035346EF907F987414F090C000E546F0907E16E060325344BF907F987413F0E544547F90C000F0907F987411F01212DFEF54FE90C000F0533EFDE4FFAD3E120F
-:4003060011B1E4F52AF529D207907E17E0600F433E02E4FFAD3E1211B1752901D207907E18E06010907F987412F0E540440490C000F0D200907E19E06011434440907F98F2
-:400346007413F0E544547F90C000F0907E1AE0600F533EFEE4FFAD3E1211B1752B01D207907E1BE0600F433E01E4FFAD3E1211B1E4F52BD207907E1CE0600E907F98741284
-:40038600F0E540440290C000F0907E1DE06002D20B907E1EE06008752C01E4F538D207907E1FE06011907FD77411F07431F07415F07435F0D203E4907FCFF0301A52E53892
-:4003C60060021538201349E513D3940040041513803E75130A301B02D2131212DFEF5401F519652A600585192AD207121333EF5480F51965266005851926D207300D11127F
-:400406001333EF5410F51965256005851925D207201B030207EC300A1812136FEFC3953D40030204AE907FC17401F0C20AC200807730043B907FCAE020E16D12136FEFC35A
-:4004460094405064907D40E013920A907FCBE014F519200011600FF5087E7D7F41750C7D750D41120D04C204E4907FCBF08039907FCCE020E13212136FEFC39440502990BC
-:400486007CC0E013920A907FCDE014F519200011600FF5087E7C7FC1750C7C750DC1120D04D204E4907FCDF0907FBAE030E1030205361212208F1912137B8F37E519C3952B
-:4004C6003B500F121357EF30E008E53720E703300C5EC20CE5196058B48003433702E53730E726E519D3942040037519208519087E7D7F80750C7D750D80AF37120F84E503
-:400506001925E0907FBBF08027E519D3943F400375193F851908907D80E537F07E7D7F81750C7D750D81120D29E51904907FBBF0907FD0E030E106200603020797C206E4F8
-:40054600F51874C02518F582E4347BF583E0FFE5187C007B017A7E79202420F9EC347EFAEF120ED20518E518B420D7907E20E06068907E23E060247F01E4FD1211FB7F0329
-:400586007DCD1211FB434780907F98740CF090C000E547F0E4907E33F08030907E21E0FF121119907E22E0FF12113F7F01907E31E0FD1211FB7F037D071211FB4347809048
-:4005C6007F98740CF090C000E547F0907F98740AF0E541440690C000F0907E23E07006907E33E07008E4907E33F0752EFF907E25E06012A3E0543FF545907F98740BF090EB
-:40060600C000E545F0907E27E0602BA3E06005434380800353437F5343FC907E29E06011434302A3E0FF121165907E2BE0FF12118BAF431210F3907E23E0600853437FAFFE
-:40064600431210F3907E2CE06018A3E0600543470280035347FD907F98740CF090C000E547F0907E2EE06018A3E0600543470180035347FE907F98740CF090C000E547F0D4
-:40068600907E32E0F53BA3E013920EA3E0F53DA3E0600543471080035347EF907F98740CF090C000E547F0907E36E060325345BF907F98740BF0E545547F90C000F0907F79
-:4006C600987409F012134BEF54FE90C000F0533FFDE4FFAD3F1211FBE4F533F532D208907E37E0600F433F02E4FFAD3F1211FB753201D208907E38E06010907F98740AF043
-:40070600E541440490C000F0D200907E39E06011434540907F98740BF0E545547F90C000F0907E3AE0600F533FFEE4FFAD3F1211FB753401D208907E3BE0600F433F01E4E9
-:40074600FFAD3F1211FBE4F534D208907E3CE0600E907F98740AF0E541440290C000F0907E3DE06002D20C907E3EE06008753501E4F539D208907E3FE06011907FD7741389
-:40078600F07433F07416F07436F0D204E4907FD1F0301A52E53960021539301349E513D3940040041513803E75130A301B02C21312134BEF5401F51965336005851933D279
-:4007C60008121387EF5480F519652F600585192FD208300E11121387EF5410F519652E600585192ED208301A2A907FD2E020E123907B40E06009E0F515907B42E0F5169035
-:400806007B41E06009907FD77417F07437F0E4907FD3F0907FC2E030E103020920E50A7040300739E5387035C207F5187E007B0074242518F9EE3400FA120E8CFF748025BD
-:4008460018F582E4347BF583EFF00518E518B409DB907FC37409F0753810E4F52C750A0122E50A64017040300839E5397035C208F5187E007B00742D2518F9EE3400FA1297
-:400886000E8CFF74802518F582E4347BF583EFF00518E518B409DB907FC37409F0753910E4F535750A0222E50A6402703630142FC214F5187E007B00740E2518F9EE340083
-:4008C600FA120E8CFF74802518F582E4347BF583EFF00518E518B405DB907FC37405F0750A0322E51560301515E4F5187E007B0074142518F9EE3400FA120E8CFF748025F2
-:4009060018F582E4347BF583EFF00518E518B403DB907FC37403F0E4F50A22907FE9E0120EE40A08000A7C010AE80309440609FB0809F50909DD0A09EC0B00000B37907F3D
-:40094600EBE024FE6019146061240260030209D37419907FD4F07400907FD5F0020B3E907FEAE070047F0280027F03758282758319EFF075827B758319F0758274758319B2
-:40098600F0758266758319F0758258758319F0907FEAE004758217758319F07419907FD4F07412907FD5F0020B3E907FEAE0FF120F0AEA49600DEA907FD4F0E9907FD5F085
-:4009C600020B3E907FB4E04401F0020B3E907FB4E04401F0020B3E907F00E509F0907FB57401F0020B3E907FEAE0F509020B3E120B46020B3E907F007401F0907FB5F00205
-:400A06000B3E907FE8E0247F60241460312402705BA210E433FF25E0FFA216E4334F907F00F0E4A3F0907FB57402F0020B3EE4907F00F0A3F0907FB57402F0020B3E907F04
-:400A4600ECE0F45480FFC4540FFFE054072F25E024B4F582E4347FF583E054FD907F00F0E4A3F0907FB57402F0020B3E907FB4E04401F0020B3E907FE8E024FE601D24020F
-:400A86006003020B3E907FEAE0B40105C210020B3E907FB4E04401F0020B3E907FEAE07038907FECE0F45480FFC4540FFFE054072F25E024B4F582E4347FF583E4F0907FB6
-:400AC600ECE05480FF131313541FFFE054072F907FD7F0E04420F0805F907FB4E04401F08056907FE8E024FE60182402704A907FEAE0B40104D210803F907FB4E04401F049
-:400B06008036907FEAE07020907FECE0F45480FFC4540FFFE054072F25E024B4F582E4347FF5837401F08010907FB4E04401F08007907FB4E04401F0907FB4E04402F022D4
-:400B4600E4907F93F0907F9C7430F0E4907F96F0907F9574C0F0907F9E743FF0907F987418F0E4F58E907FDF74FFF0907FDEF0E4F5247518017B0074242518F9E43400FA8B
-:400B8600E4120ED20518E518B409EA753A01E4F538F513F536C207C20BC205C200C209C213907F987413F075440390C0007403F07F0CE4FD1211B17F108F42121081907F02
-:400BC600987412F07F018F40EF440690C000F0907F987414F075468090C0007480F00FE4FD1211B1E4FF7EA3AD068D3E1211B1907F987411F090C000E4F07F057D7F12118E
-:400C0600B17F0112126A7F037D071211B1201B03020CB7752D017518017B00742D2518F9E43400FAE4120ED20518E518B409EA753B01E4F539F513F537C208C20CC206C2CD
-:400C460000C20AC213907F98740BF075450390C0007403F07F0CE4FD1211FB7F108F431210F3907F98740AF07F018F41EF440690C000F0907F98740CF075478090C000744E
-:400C860080F00FE4FD1211FBE4FF7EA3AD068D3F1211FB907F987409F090C000E4F07F057D7F1211FB7F0112128B7F037D071211FBD21222907F987410F0AF08E50DF582A5
-:400CC600E50CF583C2AF058690C0000586E0A30586F00586DFF7D2AF22907F987410F0AF08E50DF582E50CF583C2AF058690C000E00586F0A30586DFF70586D2AF22907F20
-:400D0600987408F0AF08E50DF582E50CF583C2AF058690C0000586E0A30586F00586DFF7D2AF22907F987408F0AF08E50DF582E50CF583C2AF058690C000E00586F0A3055C
-:400D460086DFF70586D2AF227400F58690FDA57C05A3E582458370F922907FD6E04480F0438701000000000022D219907F92E04402F0907FAEE0FFD39210E433FEEF4EF089
-:400D8600D2E843D820907FDE7401F0907FDFF0907FAB74FFF0907FA9F0907FAAF05391EF907FAFE04401F0907FAEE0440DF0D2AFD21A121245C211E4F50BF513C217C212D4
-:400DC600907FA104F0907FD8E065176010301205D21A120046907FD8E0F5178008301205C21A120046301107C21112092180D63018D3C21812139380CC22787FE4F6D8FDC7
-:400E0600758147020E47020D6FE493A3F8E493A34003F68001F208DFF48029E493A3F85407240CC8C333C4540F4420C8834004F456800146F6DFE4800B01020408102040F5
-:400E4600809012ACE47E019360BCA3FF543F30E509541FFEE493A360010ECF54C025E060A840B8E493A3FAE493A3F8E493A3C8C582C8CAC583CAF0A3C8C582C8CAC583CA1E
-:400E8600DFE9DEE780BEBB010689828A83E0225002E722BBFE02E32289828A83E49322BB010CE58229F582E5833AF583E0225006E92582F8E622BBFE06E92582F8E222E5B8
-:400EC6008229F582E5833AF583E49322BB010689828A83F0225002F722BBFE01F322D083D082F8E4937012740193700DA3A393F8740193F5828883E4737402936860EFA3C1
-:400F0600A3A380DF8F18E4F519751AFF751B19751C86AB1AAA1BA91C900001120EA5B4031DAF190519EFB5180122120E8C7E0029FFEE3AA907751AFFF51B891C80D47B00A5
-:400F46007A007900228F1A050DE50DAE0C7002050C14F5828E83E51AF0120036050DE50DAC0C7002050C14F5828C83EFF01508E508600A1213278F1AEF423680CA228F1AFC
-:400F8600050DE50DAE0C7002050C14F5828E83E51AF012133F050DE50DAC0C7002050C14F5828C83EFF01508E508600A12137B8F1AEF423780CA22C0E0C083C082C085C088
-:400FC60084C086758600907FC4E4F05391EF907FAB7404F0D086D084D085D082D083D0E032C0E0C083C082C085C084C086758600D2115391EF907FAB7401F0D086D084D0C6
-:4010060085D082D083D0E032C0E0C083C082C085C084C086758600D2185391EF907FAB7408F0D086D084D085D082D083D0E032907F987413F090C00074BFF0907F9874108A
-:40104600F090C000EFF0907F987413F0E544547F90C000F022907F987413F090C00074BFF0907F987411F090C000EFF0907F987413F0E544547F90C000F022907F98741349
-:40108600F090C00074BFF0907F987412F090C000EFF0907F987413F0E544547F90C000F022907F987413F090C00074BFF0907F987414F090C000EFF0907F987413F0E544D9
-:4010C600547F90C000F022907F987413F090C00074BFF0907F987416F090C000EFF0907F987413F0E544547F90C000F022907F98740BF090C00074BFF0907F98740AF0902A
-:40110600C000EFF0907F98740BF0E545547F90C000F022907F98740BF090C00074BFF0907F987408F090C000EFF0907F98740BF0E545547F90C000F022907F98740BF090AF
-:40114600C00074BFF0907F987409F090C000EFF0907F98740BF0E545547F90C000F022907F98740BF090C00074BFF0907F98740CF090C000EFF0907F98740BF0E545547FEC
-:4011860090C000F022907F98740BF090C00074BFF0907F98740EF090C000EFF0907F98740BF0E545547F90C000F022907F987413F0E544547F90C000F0907F987417F09075
-:4011C600C000EFF0907F987415F090C000EDF02212130F8F1A12130F8F1BE51A651B601212130F8F1AE51A651B600712130F8F1B80E8AF1A22907F98740BF0E545547F9098
-:40120600C000F0907F98740FF090C000EFF0907F98740DF090C000EDF0221213638F1A1213638F1BE51A651B60121213638F1AE51A651B60071213638F1B80E8AF1A2290C8
-:401246007FD6E054FBF0E04408F0301A04E04402F07FF47E011212C8907FD6E054F7F0E04404F022AE07E4FFE53E547FFD1211B1907F987411F090C000EEF0E4E53E4480E8
-:40128600FD1211B122AE07E4FFE53F547FFD1211FB907F987409F090C000EEF0E4E53F4480FD1211FB22050E02000000000314030000C111C118C195C110C116010A00C19C
-:4012C6001B008E188F19E5191519AE18700215184E6005120D4E80EE22907F987411F090C000E0FF22907F987412F090C000E0FF2253D8EF320000000000020FE70002130A
-:401306000400020FBD0002100E907F987413F090C000E0FF22907F987414F090C000E0FF22907F987415F090C000E0FF22907F987416F090C000E0FF22907F987408F09050
-:40134600C000E0FF22907F987409F090C000E0FF22907F98740AF090C000E0FF22907F98740BF090C000E0FF22907F98740CF090C000E0FF22907F98740DF090C000E0FFC5
-:4013860022907F98740EF090C000E0FF22120003120D5F120B4622000000000000000000000000000000000000000000000000000000000000000000000000000000000083
-:4013C60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E7
-:4014060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A6
-:401446000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000066
-:401486000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000026
-:4014C60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E6
-:4015060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A5
-:401546000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000065
-:401586000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000025
-:4015C60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E5
-:4016060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A4
-:401646000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000064
-:401686000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024
-:4016C60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E4
-:4017060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A3
-:401746000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000063
-:401786000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000023
-:4017C60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E3
-:4018060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A2
-:401846000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000062
-:401886000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000022
-:4018C6000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012011001FF00BF
-:401906000040CD06120100000102000209027400010100A032090400000EFF0000000705010240000007050202400000070503024000000705040240000007050502400074
-:4019460000070506024000000705070240000007058102400001070582024000010705830240000107058402400001070585024000010705860240000107058702400001F3
-:401986000403090448034B00650079007300700061006E002C002000610020006400690076006900730069006F006E0020006F006600200049006E006E006F005300790040
-:4019C6007300200049006E0063002E0036034B00650079007300700061006E0020005500530042002000530065007200690061006C002000410064006100700074006500F9
-:141A06007200100330003000300030003000300030000000F7
-:00000001FF
-
-	The firmware contained herein is
-
-		Copyright (C) 1999-2001
-		Keyspan, A division of InnoSys Incorporated ("Keyspan")
-
-	as an unpublished work. This notice does not imply unrestricted or
-	public access to the source code from which this firmware image is
-	derived.  Except as noted below this firmware image may not be
-	reproduced, used, sold or transferred to any third party without
-	Keyspan's prior written consent.  All Rights Reserved.
-
-	Permission is hereby granted for the distribution of this firmware
-	image as part of a Linux or other Open Source operating system kernel
-	in text or binary form as required.
-
-	This firmware may not be modified and may only be used with
-	Keyspan hardware.  Distribution and/or Modification of the
-	keyspan.c driver which includes this firmware, in whole or in
-	part, requires the inclusion of this statement."
--- zfcpdump-kernel-4.4.orig/firmware/keyspan/usa19.HEX
+++ /dev/null
@@ -1,101 +0,0 @@
-:0A002600120DBF120F47120D6B22DE
-:0300330002001AAE
-:04001A0053D8EF3296
-:100003008E138F14E5141514AE13700215134E607E
-:0700130005120F3680EE22FA
-:0300230002004692
-:10004600C0E0C083C082C086758600C0D075D00867
-:1000560030990E300807A20B929B853599C299D22A
-:100066000F200F03020431C20F20020302025620A2
-:100076000803020127E537C39550503E2009362074
-:100086000633907F9BE030E303200E29300D12AF3C
-:1000960037053774402FF582E4347EF583E01392FA
-:1000A6000BAF37053774402FF582E4347EF583E0D5
-:1000B600F53502042FC20802042F907FC7E4F0C270
-:1000C60002300A0CC20A907FBB04F0C20802042F59
-:1000D600907FC8E030E105C20802042F907FC9E096
-:1000E600F550907DC0E013920A20092D20062A9033
-:1000F6007F9BE030E303200E20300D11907DC1E0A0
-:03004300020F00A9
-:03000000020C618E
-:4001060013920BA3E0F53575370302042F753702907DC1E0F53502042F753701C20802042FE537C3955050030201CF907FC6E030E107C210C20302042F907FC7E0F5509004
-:400146007E40E013920A3009030201C720067220006F907F9BE030E303200E65300D10907E41E013929BA3E0F5997537038009907E41E0F599753702E537C39550401790B1
-:400186007FC7E4F0C202200A0302042FC20A907FBB04F002042F300D12AF37053774402FF582E4347EF583E013920BAF37053774402FF582E4347EF583E0F535D20802045D
-:4001C6002F753701C21002042F300903020251200679907F9BE030E303200E6F300D12AF37053774402FF582E4347EF583E013929BAF37053774402FF582E4347EF583E046
-:40020600F599E537C395504017907FC7E4F0C202200A0302042FC20A907FBB04F002042F300D12AF37053774402FF582E4347EF583E013920BAF37053774402FF582E43483
-:400246007EF583E0F535D20802042FC21002042F200803020308E537C39550503E200936200633907F9BE030E303200E29300D12AF37053774C02FF582E4347DF583E013DE
-:40028600920BAF37053774C02FF582E4347DF583E0F53502042FC20802042F907FC9E4F0D202300A0CC20A907FBB04F0C20802042F907FC6E030E105C20802042F907FC765
-:4002C600E0F550907E40E013920A20092D20062A907F9BE030E303200E20300D11907E41E013920BA3E0F53575370302042F753702907E41E0F53502042F753701C20802EF
-:40030600042FE537C3955050030203B0907FC8E030E107C210C20302042F907FC9E0F550907DC0E013920A3009030203A820067220006F907F9BE030E303200E65300D1034
-:40034600907DC1E013929BA3E0F5997537038009907DC1E0F599753702E537C395504017907FC9E4F0D202200A0302042FC20A907FBB04F002042F300D12AF37053774C0F5
-:400386002FF582E4347DF583E013920BAF37053774C02FF582E4347DF583E0F535D20802042F753701C21002042F30090302042D200674907F9BE030E303200E6A300D128E
-:4003C600AF37053774C02FF582E4347DF583E013929BAF37053774C02FF582E4347DF583E0F599E537C395504013907FC9E4F0D202300A35C20A907FBB04F0802C300D12CC
-:40040600AF37053774C02FF582E4347DF583E013920BAF37053774C02FF582E4347DF583E0F535D2088002C210D21220980302056DC2982001030204DA201127AF360536F3
-:4004460074802FF582E4347EF583E599F0300D4DAF36053674802FF582E4347EF583E598F0803A859910E510B54404D206802EE510B54304C2068025AF36053674802FF5AB
-:4004860082E4347EF583E510F0300D11AF36053674802FF582E4347EF583E598F0D20CE536C39540500302056B907FB8E030E116E536C39440500302056B15361536052BDD
-:4004C60043330102056B907FB7E536F0753600C20102056B201127AF36053674002FF582E4347EF583E599F0300D4DAF36053674002FF582E4347EF583E598F0803A859937
-:4005060010E510B54404D206802EE510B54304C2068025AF36053674002FF582E4347EF583E510F0300D11AF36053674002FF582E4347EF583E598F0D20CE536C3954040CE
-:4005460024907FB6E030E112E536C39440401615361536052B433301800B907FB9E536F0753600D201D212301205C212020056D0D0D086D082D083D0E032907FCAE030E1CA
-:40058600030206ABE4F51374402513F582E4347DF583E0FFE5137C007B002438F9EC3400FAEF120D330513E513B418DBE538600C75C92075C8348539CA853ACBE53B1392BF
-:4005C6000D929FE53C13920EE53D139211E53E6009907F98E054FBF08007907F98E04404F0E53F6009907F98E0547FF08007907F98E04480F0E545600BC209C206907F950E
-:40060600E04402F0E546600CD206433301907F95E04402F0E547600DC2AFC208D200E4F550F537D2AFE5486005301102D206E5496015907F95E054FDF0907F9EE04402F0AA
-:40064600907F98E054FDF0E54A600AD29CC298752C0175311EE54B6007C29CE4F536F52CE54C6003E4F536E54D6002D204E54E600AE54A7002F531E54E4233E54F601F9064
-:400686007FD77411F07431F07412F07432F07413F07433F07414F07434F0D202D201D205E4907FCBF0A209E433FF652960058F29433301A206E433FF652A60058F2A4333BA
-:4006C60001907F9BE05408B5250AE054086408F525433301907F9BE05410B5260AE054106410F526433301907F9BE05440B5270AE054406440F527433301907F9BE0542026
-:40070600B5280AE054206420F528433301300435C2AF300118907FB8E020E127E5366009907FB7F0E4F536C201C2048016907FB6E020E10FE5366009907FB9F0E4F536D234
-:4007460001C204D2AF20033730021B907FC6E020E12D907E40E013920A753701907FC7E0F550D2038019907FC8E020E112907DC0E013920A753701907FC9E0F550D20320E9
-:400786001033200006E5376550702A30031A300209E4907FC7F0C2028007E4907FC9F0D202C203E4F550F537300A0AC20AC200907FBB7401F03010030208C5200303020805
-:4007C600C5300E0A907F9BE030E3030208C53006030208C53009030208C5300262300D12AF37053774402FF582E4347EF583E0139219AF37053774402FF582E4347EF583CF
-:40080600E0F514E537C39550502A300D12AF37053774402FF582E4347EF583E013920BAF37053774402FF582E4347EF583E0F535D208806BC208E4907FC7F0C20280603081
-:400846000D12AF37053774C02FF582E4347DF583E0139219AF37053774C02FF582E4347DF583E0F514E537C39550502A300D12AF37053774C02FF582E4347DF583E013929F
-:400886000BAF37053774C02FF582E4347DF583E0F535D2088009C208E4907FC9F0D202300D04A219929BD210C2AF85149920080D300A0AC20AC200907FBB7401F0D2AF9072
-:4008C6007FBCE020E151E533604DE5317049E53330E108E4F52F753301800BA205E433F52FC205E4F533E4F5137E007B0074242513F9EE3400FA120CEDFF74002513F582D8
-:40090600E4347DF583EFF00513E513B40CDB907FBD740CF075311022907FE9E0120D450A03000A77010AE30309410609F40809E80909D00A09DF0B00000B32907FEBE024EB
-:40094600FE601614605724027076740F907FD4F07464907FD5F0020B39907FEAE070047F0280027F037582B575830FEFF07582AE75830FF07582A775830FF07582A07583BA
-:400986000FF0907FEAE00475827B75830FF0740F907FD4F07476907FD5F0020B39907FEAE0FF120E48EA49600DEA907FD4F0E9907FD5F0020B39907FB4E04401F0020B39D4
-:4009C600907FB4E04401F0020B39907F00E519F0907FB57401F0020B39907FEAE0F519020B39907FEAE0F518120D6B020B39907F00E518F0907FB57401F0020B39907FE822
-:400A0600E0247F60241460312402705BA213E433FF25E0FFA217E4334F907F00F0E4A3F0907FB57402F0020B39E4907F00F0A3F0907FB57402F0020B39907FECE0F45480B6
-:400A4600FFC4540FFFE054072F25E024B4F582E4347FF583E054FD907F00F0E4A3F0907FB57402F0020B39907FB4E04401F0020B39907FE8E024FE601D24026003020B3904
-:400A8600907FEAE0B40105C213020B39907FB4E04401F0020B39907FEAE07038907FECE0F45480FFC4540FFFE054072F25E024B4F582E4347FF583E4F0907FECE05480FFCC
-:400AC600131313541FFFE054072F907FD7F0E04420F0805F907FB4E04401F08056907FE8E024FE60182402704A907FEAE0B40104D213803F907FB4E04401F08036907FEA36
-:400B0600E07020907FECE0F45480FFC4540FFFE054072F25E024B4F582E4347FF5837401F08010907FB4E04401F08007907FB4E04401F0907FB4E04402F022201503020B3E
-:400B4600D3E53160021531E536604F65347045E532F460020532E532C39541403DC2AF300118907FB8E020E127907FB7E536F0C201E4F536F532F5348016907FB6E020E13D
-:400B86000F907FB9E536F0D201E4F536F532F534D2AF8006853634E4F532E52C602F200C07907F9BE030E00FE52D6006E4F52D433301E4F5308014E530D39542500DE530DB
-:400BC600B54206752D014333010530C20C22751201C214C218C213C217C215C212D216E4F518907F92E054FDF0907FAEE0FFD39213E433FEEF4EF0D2E843D820907FDE74DB
-:400C060001F0907FDFF0907FAB74FFF0907FA9F0907FAAF05391EF907FAFE04401F0907FAEE0440DF0D2AFD2BCD219120EDAC214301503120580907FD8E065116008E0F5CA
-:400C460011120B4180EA301407C21412091E80E03018DDC21812002680D622787FE4F6D8FD758150020CA8020BD4E493A3F8E493A34003F68001F208DFF48029E493A3F83B
-:400C86005407240CC8C333C4540F4420C8834004F456800146F6DFE4800B0102040810204080900E04E47E019360BCA3FF543F30E509541FFEE493A360010ECF54C025E08E
-:400CC60060A840B8E493A3FAE493A3F8E493A3C8C582C8CAC583CAF0A3C8C582C8CAC583CADFE9DEE780BEBB010689828A83E0225002E722BBFE02E32289828A83E4932242
-:400D0600BB010CE58229F582E5833AF583E0225006E92582F8E622BBFE06E92582F8E222E58229F582E5833AF583E49322BB010689828A83F0225002F722BBFE01F322D0E1
-:400D460083D082F8E4937012740193700DA3A393F8740193F5828883E4737402936860EFA3A3A380DFE4907F93F0907F9C7430F0907F967410F0907F947401F0907F9D04E2
-:400D8600F0907F977420F0907F957403F0907F9E7484F0E4907F98F0907FC7F0907FC9F0907FCBF075984043A810907FDE741FF0907FDF740FF0D21522E4907F95F0907FF7
-:400DC60094F0907F93F0907F9DE04402F0907F97E04402F0907F9DE054FDF0907F9C7420F0E4907F96F0907F9DE044FDF0E4907F97F0907F9E74FFF0E4907F98F0220C24D0
-:400E0600000000000000000000000000013000013301013200013700015000013600013400C105C10CC103C10FC104C10EC111C10AC110C108C109C106C100C10DC181C109
-:400E460082008F13E4F5147515FF75160F7517B9AB15AA16A917900001120D06B4031DAF140514EFB5130122120CED7E0029FFEE3AA9077515FFF516891780D47B007A006D
-:400E8600790022C0E0C083C082C085C084C086758600907FC4E4F05391EF907FAB7404F0D086D084D085D082D083D0E032C0E0C083C082C085C084C086758600D2145391C7
-:400EC600EF907FAB7401F0D086D084D085D082D083D0E032907FD6E054FBF0E04408F0301904E04402F07FF47E01120003907FD6E054F7F0E04404F02200020EB300020FC0
-:400F06000400020E8900020F0FC0E0C083C082C085C084C086758600D2185391EF907FAB7408F0D086D084D085D082D083D0E0327400F58690FDA57C05A3E582458370F9B9
-:400F460022907FD6E04480F04387010000000000220000000000000000000000000012011001FF000040CD0607010100010200020902430001010080320904000007FF008A
-:400F86000000070501024000000705020240000007050302400000070581024000010705820240000107058302400001070584024000010403090410034B00650079007332
-:170FC60000700061006E000E03530065007200690061006C00000064
-:00000001FF
-
-	The firmware contained herein is
-
-		Copyright (C) 1999-2001
-		Keyspan, A division of InnoSys Incorporated ("Keyspan")
-
-	as an unpublished work. This notice does not imply unrestricted or
-	public access to the source code from which this firmware image is
-	derived.  Except as noted below this firmware image may not be
-	reproduced, used, sold or transferred to any third party without
-	Keyspan's prior written consent.  All Rights Reserved.
-
-	Permission is hereby granted for the distribution of this firmware
-	image as part of a Linux or other Open Source operating system kernel
-	in text or binary form as required.
-
-	This firmware may not be modified and may only be used with
-	Keyspan hardware.  Distribution and/or Modification of the
-	keyspan.c driver which includes this firmware, in whole or in
-	part, requires the inclusion of this statement."
--- zfcpdump-kernel-4.4.orig/firmware/keyspan/usa19qi.HEX
+++ /dev/null
@@ -1,101 +0,0 @@
-:0300330002001AAE
-:04001A0053D8EF3296
-:100003008E118F12E5121512AE11700215114E608A
-:0700130005120F8480EE22AC
-:0300230002004692
-:10004600C0E0C083C082C086758600C0D075D00867
-:1000560030990E300B07A20E929B853699C299D223
-:100066001220120302041EC21220030302024E20B3
-:100076000B03020126E53AC39553503C200C34206D
-:100086000931907F9BE055387029301012AF3A0540
-:100096003A74402FF582E4347EF583E013920EAF76
-:1000A6003A053A74402FF582E4347EF583E0F5365E
-:1000B60002041CC20B02041C907FC7E4F0C203308A
-:1000C6000D0CC20D907FBB04F0C20B02041C907F86
-:1000D600C8E030E105C20B02041C907FC9E0F5536D
-:1000E600907DC0E013920D7516FF200C2B20092879
-:1000F600907F9BE055387020301011907DC1E01341
-:03004300020E00AA
-:03000000020026D5
-:0C002600787FE4F6D8FD758154020B28A9
-:40010600920EA3E0F536753A0302041C753A02907DC1E0F53602041C753A01C20B02041CE53AC3955350030201C9907FC6E030E107C214C20502041C907FC7E0F553907ECB
-:4001460040E013920D7516FF200C7020096D907F9BE055387065301010907E41E013929BA3E0F599753A038009907E41E0F599753A02E53AC395534017907FC7E4F0C203F6
-:40018600200D0302041CC20D907FBB04F002041C301012AF3A053A74402FF582E4347EF583E013920EAF3A053A74402FF582E4347EF583E0F536D20B02041C753A01C214A3
-:4001C60002041C300C03020249200977907F9BE05538706F301012AF3A053A74402FF582E4347EF583E013929BAF3A053A74402FF582E4347EF583E0F599E53AC3955340AB
-:4002060017907FC7E4F0C203200D0302041CC20D907FBB04F002041C301012AF3A053A74402FF582E4347EF583E013920EAF3A053A74402FF582E4347EF583E0F536D20B44
-:4002460002041CC21402041C200B030202FFE53AC39553503C200C34200931907F9BE055387029301012AF3A053A74C02FF582E4347DF583E013920EAF3A053A74C02FF5F9
-:4002860082E4347DF583E0F53602041CC20B02041C907FC9E4F0D203300D0CC20D907FBB04F0C20B02041C907FC6E030E105C20B02041C907FC7E0F553907E40E013920DAF
-:4002C6007516FF200C2B200928907F9BE055387020301011907E41E013920EA3E0F536753A0302041C753A02907E41E0F53602041C753A01C20B02041CE53AC39553500381
-:400306000203A2907FC8E030E107C214C20502041C907FC9E0F553907DC0E013920D7516FF200C7020096D907F9BE055387065301010907DC1E013929BA3E0F599753A037A
-:400346008009907DC1E0F599753A02E53AC395534017907FC9E4F0D203200D0302041CC20D907FBB04F002041C301012AF3A053A74C02FF582E4347DF583E013920EAF3A81
-:40038600053A74C02FF582E4347DF583E0F536D20B02041C753A01C21402041C200C75200972907F9BE05538706A301012AF3A053A74C02FF582E4347DF583E013929BAF02
-:4003C6003A053A74C02FF582E4347DF583E0F599E53AC395534013907FC9E4F0D203300D35C20D907FBB04F0802C301012AF3A053A74C02FF582E4347DF583E013920EAF3D
-:400406003A053A74C02FF582E4347DF583E0F536D20B8002C214D20120980302055AC2982002030204C7201627AF39053974802FF582E4347EF583E599F030104DAF3905C8
-:400446003974802FF582E4347EF583E598F0803A859910E510B54704D209802EE510B54604C2098025AF39053974802FF582E4347EF583E510F0301011AF39053974802F11
-:40048600F582E4347EF583E598F0D20FE539C395435003020558907FB8E030E116E539C39440500302055815391539052B433401020558907FB7E539F0753900C2020205D3
-:4004C60058201627AF39053974002FF582E4347EF583E599F030104DAF39053974002FF582E4347EF583E598F0803A859910E510B54704D209802EE510B54604C209802573
-:40050600AF39053974002FF582E4347EF583E510F0301011AF39053974002FF582E4347EF583E598F0D20FE539C395434024907FB6E030E112E539C3944040161539153909
-:40054600052B433401800B907FB9E539F0753900D202D201300105C201020056D0D0D086D082D083D0E032907FBCE020E151E534604DE5317049E53430E108E4F52F7534D4
-:4005860001800BA208E433F52FC208E4F534E4F5117E007B0074242511F9EE3400FA120D06FF74002511F582E4347DF583EFF00511E511B40CDB907FBD740CF075311090CD
-:4005C6007FCAE030E1030206F3E4F51174402511F582E4347DF583E0FFE5117C007B00243BF9EC3400FAEF120D1F0511E511B418DBE53B601175C92075C836853CCA853D98
-:40060600CBE4907F9FF0E53E139210929F853F38E540139216E5416009907F98E054FBF08007907F98E04404F0E5426009907F98E0547FF08007907F98E04480F0E54860BE
-:400646000BC20CC209907F95E04402F0E549600CD209433401907F95E04402F0E54A600DC2AFC20BD200E4F553F53AD2AFE54B6005301602D209E54C6015907F95E054FDB4
-:40068600F0907F9EE04402F0907F98E054FDF0E54D600AD29CC298752C0175311EE54E6007C29CE4F539F52CE54F6003E4F539E5506002D207E551600AE54D7002F531E55C
-:4006C600514234E552601F907FD77411F07431F07412F07432F07413F07433F07414F07434F0D203D202D208E4907FCBF0A20CE433FF652960058F29433401A209E433FF84
-:40070600652A60058F2A433401907F9BE0FF54086408FE652560058E25433401EF54106410FE652660058E26433401EF54406440FE652760058E27433401EF54206420FE1C
-:40074600652860058E28433401907F9AE054406440FE652E60058E2E433401300735C2AF300218907FB8E020E127E5396009907FB7F0E4F539C202C2078016907FB6E0203B
-:40078600E10FE5396009907FB9F0E4F539D202C207D2AF20053D30031E907FC6E020E133907E40E013920D753A01907FC7E0F553D2057516FF801C907FC8E020E115907DD3
-:4007C600C0E013920D753A01907FC9E0F553D2057516FF201433200006E53A6553702A30051A300309E4907FC7F0C2038007E4907FC9F0D203C205E4F553F53A300D0AC265
-:400806000DC200907FBB7401F0301403020914200503020914300C03020914300903020914907F9BE055386003020914300361301012AF3A053A74402FF582E4347EF5833F
-:40084600E013921BAF3A053A74402FF582E4347EF583E0FEE53AC39553502A301012AF3A053A74402FF582E4347EF583E013920EAF3A053A74402FF582E4347EF583E0F546
-:4008860036D20B806AC20BE4907FC7F0C203805F301012AF3A053A74C02FF582E4347DF583E013921BAF3A053A74C02FF582E4347DF583E0FEE53AC39553502A301012AFE7
-:4008C6003A053A74C02FF582E4347DF583E013920EAF3A053A74C02FF582E4347DF583E0F536D20B8009C20BE4907FC9F0D203301004A21B929BD214C2AF8E99200B0D301D
-:400906000D0AC20DC200907FBB7401F0D2AF22907FE9E0120D310A11000A7E010ADB030938060A020809F60909DE0A09ED0B00000B19907FEBE024FE601914605A24026041
-:4009460003020B19740D907FD4F07487907FD5F0020B20907FEAE070047F0280027F037582D875830DEFF07582D175830DF07582CA75830DF07582C375830DF0907FEAE078
-:400986000475829E75830DF0740D907FD4F07499907FD5F0020B20907FEAE0700B7511FF75120D7513DC801B907FEAE0B4010B7511FF75120D7513E080097511FF75120D19
-:4009C6007513F0AA12A913AE02EE907FD4F0AF01EF907FD5F0020B20907F00E515F0907FB57401F0020B20907FEAE0F515020B20120CB1907FEAE0F514020B20907F00E5BF
-:400A060014F0907FB57401F0020B20907FE8E0247F602714603424026003020B19A217E433FF25E0FFA219E4334F907F00F0E4A3F0907FB57402F0020B20E4907F00F0A3B7
-:400A4600F0907FB57402F0020B20907FECE0F45480FFC4540FFFE054072F25E024B4F582E4347FF583E054FD907F00F0E4A3F0907FB57402F0020B20907FE8E024FE601726
-:400A860024026003020B20907FEAE064016003020B19C217020B20907FEAE07076907FECE0F45480FFC4540FFFE054072F25E024B4F582E4347FF583E4F0907FECE05480D6
-:400AC600FF131313541FFFE054072F907FD7F0E04420F08045907FE8E024FE601024027039907FEAE06401702AD217802D907FEAE07020907FECE0F45480FFC4540FFFE056
-:400B060054072F25E024B4F582E4347FF5837401F08007907FB4E04401F0907FB4E04402F022C210E4F514F534C209C20CC20BC214C20DC216C211C207C212C20FC208F538
-:400B460035F539F553F53AF533F530F52FF52EF52DF52CF52BF52AF529F528F527F526F525F524C205C218C21AC217C219C215C204D213C206C201907F92E054FDF0D2E820
-:400B860043D820907FDE7401F0907FDFF0907FAB74FFF0907FA9F0907FAAF05391EF907FAFE04401F0907FAEE0440FF0907FAC740EF0D2AFD2BCD21B120F5FC21830040316
-:400BC60012056D30042A300627C206E51660161516907FD8E030E6047F0080027F20907F96EFF08006907F967420F0120C0B80CD301807C21812091580C3301AC0C21A128E
-:400C06000FBB80B922E53160021531E53960556535704BE533F460020533E533C395444043C2AF30021B907FB8E020E12D907FB7E539F0C202E4F539F533F5357516FF802D
-:400C460019907FB6E020E112907FB9E539F0D202E4F539F533F5357516FFD2AF8006853935E4F533E52C6030200F07907F9BE030E00FE52D6006E4F52D433401E4F5308000
-:400C860014E530D39545500DE530B54506752D014334010530C20F22907FD9E030E2047F0080027F20907F96EFF022E4907F93F0907F9C7430F0907F967420F0907F94748A
-:400CC60001F0907F9D74BFF0907F977486F0907F957403F0907F9E7484F0907F98F0E4907FC7F0907FC9F0907FCBF075984043A810907FDE741FF0907FDF740FF0D204221A
-:400D0600BB010689828A83E0225002E722BBFE02E32289828A83E49322BB010689828A83F0225002F722BBFE01F322D083D082F8E4937012740193700DA3A393F8740193EB
-:400D4600F5828883E4737402936860EFA3A3A380DFC0E0C083C082C085C084C086758600907FC4E4F05391EF907FAB7404F0D086D084D085D082D083D0E03200000000007B
-:400D86000012011001FF000040CD060C010100010200020902430001010080320904000007FF00000007050102400000070502024000000705030240000007058102400010
-:400DC600010705820240000107058302400001070584024000010403090410034B00650079007300700061006E000E03530065007200690061006C000000020EA200020E41
-:400E06007B00020D5700020EC900020E1000020E1400020E1800020E1C00020EF000020E2400020F1500020E2C00020F3AE4907F95F0907F94F0907F93F0907F9DE044020A
-:400E4600F0907F97E04402F0907F9C7410F0E4907F96F0907F9D74FEF03017047F8080027F00907F97EFF0E4907F95F0907F9EF0907F98F022C0E0C083C082C085C084C00E
-:400E8600867586005391EF907FAB7402F0D206D086D084D085D082D083D0E032C0E0C083C082C085C084C086758600D2185391EF907FAB7401F0D086D084D085D082D083EB
-:400EC600D0E032C0E0C083C082C085C084C086758600D21A5391EF907FAB7408F0D086D084D085D082D083D0E032C0E0C083C082C085C084C0867586005391EF907FA974C2
-:400F060002F0D086D084D085D082D083D0E032C0E0C083C082C085C084C0867586005391EF907FA97404F0D086D084D085D082D083D0E032C0E0C083C082C085C084C086D7
-:400F46007586005391EF907FA97408F0D086D084D085D082D083D0E032907FD6E054FBF0E04408F0301B04E04402F07FF47E01120003907FD6E054F7F0E04404F0227400B9
-:400F8600F58690FDA57C05A3E582458370F922907FD6E04480F0438701000000000022907FD6E04401F07F0D7E00120003907FD6E054FEF022120E33120F95907FD6E030FA
-:090FC600E703120FA5120CB12281
-:00000001FF
-
-	The firmware contained herein is
-
-		Copyright (C) 1999-2001
-		Keyspan, A division of InnoSys Incorporated ("Keyspan")
-
-	as an unpublished work. This notice does not imply unrestricted or
-	public access to the source code from which this firmware image is
-	derived.  Except as noted below this firmware image may not be
-	reproduced, used, sold or transferred to any third party without
-	Keyspan's prior written consent.  All Rights Reserved.
-
-	Permission is hereby granted for the distribution of this firmware
-	image as part of a Linux or other Open Source operating system kernel
-	in text or binary form as required.
-
-	This firmware may not be modified and may only be used with
-	Keyspan hardware.  Distribution and/or Modification of the
-	keyspan.c driver which includes this firmware, in whole or in
-	part, requires the inclusion of this statement."
--- zfcpdump-kernel-4.4.orig/firmware/keyspan/usa19qw.HEX
+++ /dev/null
@@ -1,142 +0,0 @@
-:0300330002002D9B
-:04002D0053D8EF3283
-:10004600301019120E0FEFC3951440030200DF9013
-:100056007FBF7401F0C210C20B0200DF300D3E906C
-:100066007FC6E020E173120E0FEFC39440506A90F2
-:100076007E40E0139210907FC7E014F536200B11F6
-:10008600600FF5247E7E7F4175297E752A4112090F
-:1000960010C20DE4907FC7F07526FF803C907FC8A4
-:1000A600E020E135120E0FEFC39440502C907DC036
-:1000B600E0139210907FC9E014F536200B11600F03
-:1000C600F5247E7D7FC175297D752AC1120910D25E
-:1000D6000DE4907FC9F07526FF907FB6E030E1030E
-:1000E600020168120CFF8F36120E1B8F11E536C304
-:1000F6009513500F120DDEEF30E008E51120E703EF
-:0C003600907F987410F090C000E0FF2252
-:03004300020E00AA
-:10000300C0E0C083C082C085C084C086758600906E
-:100013007FC4E4F05391EF907FAB7404F0D086D0AB
-:0A00230084D085D082D083D0E03273
-:030000000209C52D
-:4001060030135FC213E5366059B48003431102E51130E724E536D3942040037536208536247E7E7F8075297E752A80120B9AE53625E0907FB7F0802AE536D3943F4003753B
-:40014600363F853624907E80E511F07E7E7F8175297E752A81120935E53604907FB7F07526FF907FCEE030E106200E030203C4E4F53574402535F582E4347CF583E0FFE589
-:40018600357C007B017A7E79002400F9EC347EFAEF120A970535E535B420D7907E00E0606E7F01907E11E0FD120CDA907E01E0FF120C1C907E02E0FF120C42D211D2127562
-:4001C6003604907E03E06005C2124336C0907E04E0B40107C21243360B8010907E04E06007C21143360980034336027F03AD36120CDA431A80907F987414F090C000E51A72
-:40020600F0907F987412F0E517440690C000F0907E05E06012A3E0543FF519907F987413F090C000E519F0907E07E06042907E13E0600543160480035316FBE4FFAD161247
-:400246000CDA907E08E06005431880800353187F5318FC907E09E06011431802A3E0FF120C8E907E0BE0FF120CB4AF18120C68907E0EE06018A3E06005431A018003531AD4
-:40028600FE907F987414F090C000E51AF0907E0CE06018A3E06005431A028003531AFD907F987414F090C000E51AF0907E12E0F513A3E0139214A3E0F514A3E06005431AC3
-:4002C600108003531AEF907F987414F090C000E51AF0907E16E060325319BF907F987413F0E519547F90C000F0907F987411F0120DD2EF54FE90C000F05316FDE4FFAD1621
-:40030600120CDAE4F50EF50DD20F907E17E0600F431602E4FFAD16120CDA750D01D20F907E18E06010907F987412F0E517440490C000F0D20B907E19E06011431940907F0D
-:40034600987413F0E519547F90C000F0907E1AE0600F5316FEE4FFAD16120CDA750F01D20F907E1BE0600F431601E4FFAD16120CDAE4F50FD20F907E1CE0600E907F9874A9
-:4003860012F0E517440290C000F0907E1DE06002D213907E1EE06008751001E4F512D20F907E1FE06011907FD77411F07431F07415F07435F0D20DC20EE4907FCFF0301674
-:4003C60071E51260021512E530D3940040041530806075300A120DD2EF5401F536650E600785360ED20F8011120E27EF5410F53665096005853609D20F120E27EF5480F5C1
-:4004060036650A600585360AD20F120E27EF5420F536650B600885360B301102D20F120E27EF5440F536650C600885360C301202D20F30162A907FD2E020E123907B40E035
-:400446006009E0F532907B42E0F533907B41E06009907FD77417F07437F0E4907FD3F0907FC2E030E103020529E5277040300F39E5127035C20FF5357E007B0074082535DB
-:40048600F9EE3400FA120A51FF74802535F582E4347BF583EFF00535E535B409DB907FC37409F0751210E4F51075270222E5276402703630052FC205F5357E007B00742B96
-:4004C6002535F9EE3400FA120A51FF74802535F582E4347BF583EFF00535E535B405DB907FC37405F075270322E53260337531031532E4F5357E007B0074312535F9EE34CD
-:4005060000FA120A51FF74802535F582E4347BF583EFF00535E535B403DB907FC37403F0E4F52722907FE9E0120AA9060800067C0106E903054D0605F90805ED0905D50A02
-:4005460005E40B00000739907FEBE024FE60161460502402706F7419907FD4F07400907FD5F0020740907FEAE070047F0280027F03758282758319EFF0758274758319F06E
-:40058600758258758319F0907FEAE004758217758319F07419907FD4F07412907FD5F0020740907FEAE0FF120B1CEA49600DEA907FD4F0E9907FD5F0020740907FB4E0449B
-:4005C60001F0020740907FB4E04401F0020740907F00E525F0907FB57401F0020740907FEAE0F525020740120748907FEAE0F523020740907F00E523F0907FB57401F00216
-:400606000740907FE8E0247F60241460312402705BA201E433FF25E0FFA207E4334F907F00F0E4A3F0907FB57402F0020740E4907F00F0A3F0907FB57402F0020740907F2C
-:40064600ECE0F45480FFC4540FFFE054072F25E024B4F582E4347FF583E054FD907F00F0E4A3F0907FB57402F0020740907FB4E04401F0020740907FE8E024FE601E240216
-:400686006003020740907FEAE0B40106120DF9020740907FB4E04401F0020740907FEAE07038907FECE0F45480FFC4540FFFE054072F25E024B4F582E4347FF583E4F090F8
-:4006C6007FECE05480FF131313541FFFE054072F907FD7F0E04420F08060907FB4E04401F08057907FE8E024FE60192402704B907FEAE0B40105120DF6803F907FB4E04487
-:4007060001F08036907FEAE07020907FECE0F45480FFC4540FFFE054072F25E024B4F582E4347FF5837401F08010907FB4E04401F08007907FB4E04401F0907FB4E04402F9
-:40074600F022E4907F93F0907F9C7430F0907F967420F0907F9574C0F0907F9E743FF0907F987410F0E4F58E907FDF74FFF0907FDEF0E4F5087F017B0074082FF9E4340023
-:40078600FAE4120A970FBF09EE751301E4F512F530F511C20FC213C20EC20BC210C204907F987413F075190390C0007403F07F0CE4FD120CDA7F108F18120C68907F9874C2
-:4007C60012F07F018F17EF440690C000F00FE4FD120CDAE4FF7EA3AD068D16120CDA907F987411F090C000E4F07F057D7F120CDA7F01120D6A7F037D07120CDAE4FFE5167B
-:40080600547FFD120CDA120E0F8F15E4FFE5164480FD120CDAE51530E704C2088002D208907F987414F0751A8090C0007480F0D20322D215907F92E04402F0120DF9D2E87C
-:4008460043D820907FDE7401F0907FDFF0907FAB74FFF0907FA9F0907FAAF05391EF907FAFE04401F0907FAE740DF0D2AFD216120D24C202E4F528F530C209F523C20390F7
-:400886007FA104F0907FD8E065346048300305D216120046E50F6022E52660161526907FD8E030E6047F2080027F30907F96EFF0801A907F967430F08012907FD9E030E2F8
-:4008C600047F3080027F20907F96EFF0907FD8E0F5348020300307C2161200468016E50F7012907FD9E030E2047F3080027F20907F96EFF0300207C20212052A8086300AE4
-:4009060083C20A120B5D02088A22907F987410F0AF24E52AF582E529F583C2AF058690C0000586E0A30586F00586DFF7D2AF22907F987410F0AF24E52AF582E529F583C2A3
-:40094600AF058690C000E00586F0A30586DFF70586D2AF22907F987408F0AF24E52AF582E529F583C2AF058690C0000586E0A30586F00586DFF7D2AF22907F987408F0AFCD
-:4009860024E52AF582E529F583C2AF058690C000E00586F0A30586DFF70586D2AF227400F58690FDA57C05A3E582458370F922907FD6E04480F0438701000000000022784B
-:4009C6007FE4F6D8FD758139020A0C020838E493A3F8E493A34003F68001F208DFF48029E493A3F85407240CC8C333C4540F4420C8834004F456800146F6DFE4800B010211
-:400A0600040810204080900D8BE47E019360BCA3FF543F30E509541FFEE493A360010ECF54C025E060A840B8E493A3FAE493A3F8E493A3C8C582C8CAC583CAF0A3C8C582B0
-:400A4600C8CAC583CADFE9DEE780BEBB010689828A83E0225002E722BBFE02E32289828A83E49322BB010CE58229F582E5833AF583E0225006E92582F8E622BBFE06E925BB
-:400A860082F8E222E58229F582E5833AF583E49322BB010689828A83F0225002F722BBFE01F322D083D082F8E4937012740193700DA3A393F8740193F5828883E47374028F
-:400AC600936860EFA3A3A380DFE4907F93F0907F9C7420F0300103FF80027F00907F96EFF0E4907F94F0907F9D74FFF0E4907F97F0300811907F95F0907F9E74FFF0907F05
-:400B0600987420F022E4907F95F0907F9E74DFF0E4907F98F0228F35E4F5367537FF753819753986AB37AA38A939900001120A6AB4031DAF360536EFB5350122120A517E5C
-:400B46000029FFEE3AA9077537FFF538893980D47B007A00790022907FD8E0F535120ACF200807907F92E054FDF0907FD6E04480F01209B5907FD6E030E70E300105120D9C
-:400B8600BC8006120D49EF60E1907F92E04402F012074822052AE52AAE297002052914F5828E83E511F0120036052AE52AAC297002052914F5828C83EFF01524E5246007C7
-:400BC600120E1B8F1180CD22C0E0C083C082C085C084C086758600D2025391EF907FAB7401F0D086D084D085D082D083D0E032C0E0C083C082C085C084C086758600D20A9F
-:400C06005391EF907FAB7408F0D086D084D085D082D083D0E032907F987413F090C00074BFF0907F987410F090C000EFF0907F987413F0E519547F90C000F022907F9874E8
-:400C460013F090C00074BFF0907F987411F090C000EFF0907F987413F0E519547F90C000F022907F987413F090C00074BFF0907F987412F090C000EFF0907F987413F0E57C
-:400C860019547F90C000F022907F987413F090C00074BFF0907F987414F090C000EFF0907F987413F0E519547F90C000F022907F987413F090C00074BFF0907F987416F0FE
-:400CC60090C000EFF0907F987413F0E519547F90C000F022907F987413F0E519547F90C000F0907F987417F090C000EFF0907F987415F090C000EDF022120DEA8F37120D91
-:400D0600EA8F38E53765386012120DEA8F37E53765386007120DEA8F3880E8AF3722907FD6E054FBF0E04408F0301604E04402F07FF47E01120DA5907FD6E054F7F0E04448
-:400D460004F022907FD8E0F536120748120E27EF30E60B907FD8E0653660F17F0122120ACF7F0022AE07E4FFE516547FFD120CDA907F987411F090C000EEF0E4E516448084
-:400D8600FD120CDA22052B02000000000331030000C186C102C10AC101C107012700008E368F37E5371537AE36700215364E60051209A480EE22907FD6E04401F07F0D7E8D
-:400DC60000120DA5907FD6E054FEF022907F987411F090C000E0FF22907F987412F090C000E0FF22907F987413F090C000E0FF22D20122C2012200000000020BCE00020EF1
-:400E0600040002000300020BF5907F987414F090C000E0FF22907F987415F090C000E0FF22907F987416F090C000E0FF22000000000000000000000000000000000000004E
-:400E4600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006C
-:400E8600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002C
-:400EC60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000EC
-:400F060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000AB
-:400F4600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006B
-:400F8600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002B
-:400FC60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000EB
-:4010060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000AA
-:40104600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006A
-:40108600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002A
-:4010C60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000EA
-:4011060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A9
-:401146000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000069
-:401186000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000029
-:4011C60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E9
-:4012060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A8
-:401246000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000068
-:401286000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028
-:4012C60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E8
-:4013060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A7
-:401346000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000067
-:401386000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000027
-:4013C60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E7
-:4014060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A6
-:401446000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000066
-:401486000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000026
-:4014C60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E6
-:4015060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A5
-:401546000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000065
-:401586000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000025
-:4015C60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E5
-:4016060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A4
-:401646000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000064
-:401686000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024
-:4016C60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E4
-:4017060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A3
-:401746000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000063
-:401786000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000023
-:4017C60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E3
-:4018060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A2
-:401846000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000062
-:401886000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000022
-:4018C6000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012011001FF00BF
-:401906000040CD06190100000102000209027400010100A032090400000EFF000000070501024000000705020240000007050302400000070504024000000705050240006D
-:4019460000070506024000000705070240000007058102400001070582024000010705830240000107058402400001070585024000010705860240000107058702400001F3
-:401986000403090448034B00650079007300700061006E002C002000610020006400690076006900730069006F006E0020006F006600200049006E006E006F005300790040
-:4019C6007300200049006E0063002E0036034B00650079007300700061006E0020005500530042002000530065007200690061006C002000410064006100700074006500F9
-:041A0600720000006A
-:00000001FF
-
-	The firmware contained herein is
-
-		Copyright (C) 1999-2001
-		Keyspan, A division of InnoSys Incorporated ("Keyspan")
-
-	as an unpublished work. This notice does not imply unrestricted or
-	public access to the source code from which this firmware image is
-	derived.  Except as noted below this firmware image may not be
-	reproduced, used, sold or transferred to any third party without
-	Keyspan's prior written consent.  All Rights Reserved.
-
-	Permission is hereby granted for the distribution of this firmware
-	image as part of a Linux or other Open Source operating system kernel
-	in text or binary form as required.
-
-	This firmware may not be modified and may only be used with
-	Keyspan hardware.  Distribution and/or Modification of the
-	keyspan.c driver which includes this firmware, in whole or in
-	part, requires the inclusion of this statement."
--- zfcpdump-kernel-4.4.orig/firmware/keyspan/usa19w.HEX
+++ /dev/null
@@ -1,141 +0,0 @@
-:03003300020D5C5F
-:10000300E4907F93F0907F9C7430F0E4907F96F0BF
-:10001300907F94F0907F9D74FFF0E4907F97F09031
-:0F0023007F95F0907F9E7417F0E4907F98F02205
-:10004600300F18120D38EFC3951440030200D890F4
-:100056007FBF7401F0C20FC20A8077300C3B907FDD
-:10006600C6E020E16D120D38EFC394405064907ED7
-:1000760040E013920F907FC7E014F51C200A116030
-:100086000FF5237E7E7F4175277E75284112080174
-:10009600C20CE4907FC7F08039907FC8E020E1323F
-:1000A600120D38EFC394405029907DC0E013920F93
-:1000B600907FC9E014F51C200A11600FF5237E7DA0
-:1000C6007FC175277D7528C1120801D20CE4907F87
-:1000D600C9F0907FB6E030E10302015E120C418F59
-:1000E6001C120D448F11E51CC39513500F120D20E1
-:1000F600EF30E008E51120E70330125CC212E51C80
-:0C003600907F987410F090C000E0FF2252
-:03004300020E00AA
-:030000000208B63D
-:400106006056B48003431102E51130E724E51CD394204003751C20851C237E7E7F8075277E752880120A86E51C251C907FB7F08027E51CD3943F4003751C3F851C23907E06
-:4001460080E511F07E7E7F8175277E752881120826E51C04907FB7F0907FCEE030E106200D030203BAE4F51B7440251BF582E4347CF583E0FFE51B7C007B017A7E7900244A
-:4001860000F9EC347EFAEF120A0D051BE51BB420D7907E00E0606E7F01907E11E0FD120C1C907E01E0FF120B5E907E02E0FF120B84D210D211751C04907E03E06005C211D7
-:4001C600431CC0907E04E0B40107C211431C0B8010907E04E06007C210431C098003431C027F03AD1C120C1C431980907F987414F090C000E519F0907F987412F0E51644CE
-:400206000690C000F0907E05E06012A3E0543FF518907F987413F090C000E518F0907E07E06042907E13E0600543150480035315FBE4FFAD15120C1C907E08E060054317BC
-:4002460080800353177F5317FC907E09E06011431702A3E0FF120BD0907E0BE0FF120BF6AF17120BAA907E0EE06018A3E0600543190180035319FE907F987414F090C00046
-:40028600E519F0907E0CE06018A3E0600543190280035319FD907F987414F090C000E519F0907E12E0F513A3E0139213A3E0F514A3E0600543191080035319EF907F98742D
-:4002C60014F090C000E519F0907E16E060325318BF907F987413F0E518547F90C000F0907F987411F0120D14EF54FE90C000F05315FDE4FFAD15120C1CE4F50EF50DD20EEB
-:40030600907E17E0600F431502E4FFAD15120C1C750D01D20E907E18E06010907F987412F0E516440490C000F0D20A907E19E06011431840907F987413F0E518547F90C064
-:4003460000F0907E1AE0600F5315FEE4FFAD15120C1C750F01D20E907E1BE0600F431501E4FFAD15120C1CE4F50FD20E907E1CE0600E907F987412F0E516440290C000F0D8
-:40038600907E1DE06002D212907E1EE06008751001E4F512D20E907E1FE06011907FD77411F07431F07415F07435F0D20CC20DE4907FCFF0301571E51260021512E52ED326
-:4003C60094004004152E8060752E0A120D14EF5401F51C650E6007851C0ED20E8011120D50EF5410F51C65096005851C09D20E120D50EF5480F51C650A6005851C0AD20EFB
-:40040600120D50EF5420F51C650B6008851C0B301002D20E120D50EF5440F51C650C6008851C0C301102D20E30152A907FD2E020E123907B40E06009E0F530907B42E0F572
-:4004460031907B41E06009907FD77417F07437F0E4907FD3F0907FC2E030E10302051FE5257040300E39E5127035C20EF51B7E007B007408251BF9EE3400FA1209C7FF7447
-:4004860080251BF582E4347BF583EFF0051BE51BB409DB907FC37409F0751210E4F51075250222E5256402703630052FC205F51B7E007B007429251BF9EE3400FA1209C7C2
-:4004C600FF7480251BF582E4347BF583EFF0051BE51BB405DB907FC37405F075250322E5306033752F031530E4F51B7E007B00742F251BF9EE3400FA1209C7FF7480251B26
-:40050600F582E4347BF583EFF0051BE51BB403DB907FC37403F0E4F52522907FE9E0120A1F05F600066A0106D70305430605E90805E30905CB0A05DA0B00000727907FEBC9
-:40054600E024FE60161460502402706F7419907FD4F07400907FD5F002072E907FEAE070047F0280027F03758282758319EFF0758274758319F0758258758319F0907FEA65
-:40058600E004758217758319F07419907FD4F07412907FD5F002072E907FEAE0FF120A45EA49600DEA907FD4F0E9907FD5F002072E907FB4E04401F002072E907FB4E044D1
-:4005C60001F002072E907F00E524F0907FB57401F002072E907FEAE0F52402072E12073602072E907F007401F0907FB5F002072E907FE8E0247F60241460312402705BA221
-:4006060001E433FF25E0FFA207E4334F907F00F0E4A3F0907FB57402F002072EE4907F00F0A3F0907FB57402F002072E907FECE0F45480FFC4540FFFE054072F25E024B4CD
-:40064600F582E4347FF583E054FD907F00F0E4A3F0907FB57402F002072E907FB4E04401F002072E907FE8E024FE601E2402600302072E907FEAE0B40106120D6302072E53
-:40068600907FB4E04401F002072E907FEAE07038907FECE0F45480FFC4540FFFE054072F25E024B4F582E4347FF583E4F0907FECE05480FF131313541FFFE054072F907F69
-:4006C600D7F0E04420F08060907FB4E04401F08057907FE8E024FE60192402704B907FEAE0B40105120D60803F907FB4E04401F08036907FEAE07020907FECE0F45480FFAD
-:40070600C4540FFFE054072F25E024B4F582E4347FF5837401F08010907FB4E04401F08007907FB4E04401F0907FB4E04402F022E4907F93F0907F9C7430F0E4907F96F06B
-:40074600907F9574C0F0907F9E743FF0907F987418F0E4F58E907FDF74FFF0907FDEF0E4F5087F017B0074082FF9E43400FAE4120A0D0FBF09EE751301E4F512F52EF511A2
-:40078600C20EC212C20DC20AC20FC204907F987413F075180390C0007403F07F0CE4FD120C1C7F108F17120BAA907F987412F07F018F16EF440690C000F00FE4FD120C1C71
-:4007C600E4FF7EA3AD068D15120C1C907F987411F090C000E4F07F057D7F120C1C7F01120CAC7F037D07120C1C907F987414F075198090C0007480F0D20322907F98741059
-:40080600F0AF23E528F582E527F583C2AF058690C0000586E0A30586F00586DFF7D2AF22907F987410F0AF23E528F582E527F583C2AF058690C000E00586F0A30586DFF76F
-:400846000586D2AF22907F987408F0AF23E528F582E527F583C2AF058690C0000586E0A30586F00586DFF7D2AF22907F987408F0AF23E528F582E527F583C2AF058690C045
-:4008860000E00586F0A30586DFF70586D2AF227400F58690FDA57C05A3E582458370F922907FD6E04480F0438701000000000022787FE4F6D8FD7581310208FD020942E43B
-:4008C60093A3F8E493A34003F68001F208DFF48029E493A3F85407240CC8C333C4540F4420C8834004F456800146F6DFE4800B0102040810204080900CCDE47E019360BC36
-:40090600A3FF543F30E509541FFEE493A360010ECF54C025E060A840B8E493A3FAE493A3F8E493A3C8C582C8CAC583CAF0A3C8C582C8CAC583CADFE9DEE780BED214907F83
-:4009460092E04402F0120D63D2E843D820907FDE7401F0907FDFF0907FAB74FFF0907FA9F0907FAAF05391EF907FAFE04401F0907FAE740DF0D2AFD215120C66C202E4F557
-:4009860026F52EC208C203907FA104F0907FD8E0651A6010300305D215120046907FD8E0F51A8008300305C215120046300207C20212052080D63009D3C209120ABA80CC40
-:4009C60022BB010689828A83E0225002E722BBFE02E32289828A83E49322BB010CE58229F582E5833AF583E0225006E92582F8E622BBFE06E92582F8E222E58229F582E51F
-:400A0600833AF583E49322BB010689828A83F0225002F722BBFE01F322D083D082F8E4937012740193700DA3A393F8740193F5828883E4737402936860EFA3A3A380DF8F58
-:400A46001BE4F51C751DFF751E19751F86AB1DAA1EA91F9000011209E0B4031DAF1C051CEFB51B01221209C77E0029FFEE3AA907751DFFF51E891F80D47B007A00790022F3
-:400A86000528E528AE277002052714F5828E83E511F01200360528E528AC277002052714F5828C83EFF01523E5236007120D448F1180CD22907FD8E0F51B120003907FD6AB
-:400AC600E04480F01208A6907FD6E030E70E300105120CFE8006120C8BEF60E112073622C0E0C083C082C085C084C086758600907FC4E4F05391EF907FAB7404F0D086D0DF
-:400B060084D085D082D083D0E032C0E0C083C082C085C084C086758600D2025391EF907FAB7401F0D086D084D085D082D083D0E032C0E0C083C082C085C084C08675860025
-:400B4600D2095391EF907FAB7408F0D086D084D085D082D083D0E032907F987413F090C00074BFF0907F987410F090C000EFF0907F987413F0E518547F90C000F022907FDB
-:400B8600987413F090C00074BFF0907F987411F090C000EFF0907F987413F0E518547F90C000F022907F987413F090C00074BFF0907F987412F090C000EFF0907F98741307
-:400BC600F0E518547F90C000F022907F987413F090C00074BFF0907F987414F090C000EFF0907F987413F0E518547F90C000F022907F987413F090C00074BFF0907F9874F2
-:400C060016F090C000EFF0907F987413F0E518547F90C000F022907F987413F0E518547F90C000F0907F987417F090C000EFF0907F987415F090C000EDF022120D2C8F1D44
-:400C4600120D2C8F1EE51D651E6012120D2C8F1DE51D651E6007120D2C8F1E80E8AF1D22907FD6E054FBF0E04408F0301504E04402F07FF47E01120CE7907FD6E054F7F0D8
-:400C8600E04404F022907FD8E0F51C120736120D50EF30E60B907FD8E0651C60F17F01221200037F0022AE07E4FFE515547FFD120C1C907F987411F090C000EEF0E4E51599
-:400CC6004480FD120C1C2205290200000000032F030000C186C102C109C101C107012500008E1C8F1DE51D151DAE1C7002151C4E600512089580EE22907FD6E04401F07F86
-:400D06000D7E00120CE7907FD6E054FEF022907F987411F090C000E0FF22907F987412F090C000E0FF22907F987413F090C000E0FF22907F987414F090C000E0FF22907F2B
-:400D4600987415F090C000E0FF22907F987416F090C000E0FF2253D8EF32D20122C20122000000000000000000000000000000000000000000000000000000000000000073
-:400D8600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002D
-:400DC60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020B1000020EC0
-:400E06000400020AE600020B370000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000072
-:400E4600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006C
-:400E8600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002C
-:400EC60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000EC
-:400F060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000AB
-:400F4600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006B
-:400F8600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002B
-:400FC60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000EB
-:4010060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000AA
-:40104600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006A
-:40108600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002A
-:4010C60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000EA
-:4011060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A9
-:401146000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000069
-:401186000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000029
-:4011C60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E9
-:4012060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A8
-:401246000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000068
-:401286000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028
-:4012C60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E8
-:4013060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A7
-:401346000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000067
-:401386000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000027
-:4013C60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E7
-:4014060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A6
-:401446000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000066
-:401486000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000026
-:4014C60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E6
-:4015060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A5
-:401546000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000065
-:401586000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000025
-:4015C60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E5
-:4016060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A4
-:401646000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000064
-:401686000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024
-:4016C60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E4
-:4017060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A3
-:401746000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000063
-:401786000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000023
-:4017C60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E3
-:4018060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A2
-:401846000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000062
-:401886000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000022
-:4018C6000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012011001FF00BF
-:401906000040CD06080100000102000209027400010100A032090400000EFF000000070501024000000705020240000007050302400000070504024000000705050240007E
-:4019460000070506024000000705070240000007058102400001070582024000010705830240000107058402400001070585024000010705860240000107058702400001F3
-:401986000403090448034B00650079007300700061006E002C002000610020006400690076006900730069006F006E0020006F006600200049006E006E006F005300790040
-:4019C6007300200049006E0063002E0036034B00650079007300700061006E0020005500530042002000530065007200690061006C002000410064006100700074006500F9
-:041A0600720000006A
-:00000001FF
-
-	The firmware contained herein is
-
-		Copyright (C) 1999-2001
-		Keyspan, A division of InnoSys Incorporated ("Keyspan")
-
-	as an unpublished work. This notice does not imply unrestricted or
-	public access to the source code from which this firmware image is
-	derived.  Except as noted below this firmware image may not be
-	reproduced, used, sold or transferred to any third party without
-	Keyspan's prior written consent.  All Rights Reserved.
-
-	Permission is hereby granted for the distribution of this firmware
-	image as part of a Linux or other Open Source operating system kernel
-	in text or binary form as required.
-
-	This firmware may not be modified and may only be used with
-	Keyspan hardware.  Distribution and/or Modification of the
-	keyspan.c driver which includes this firmware, in whole or in
-	part, requires the inclusion of this statement."
--- zfcpdump-kernel-4.4.orig/firmware/keyspan/usa28.HEX
+++ /dev/null
@@ -1,148 +0,0 @@
-:0A0026001217DB1218B51214C322E2
-:0300330002001DAB
-:04001D0053D8EF3293
-:100006008E128F13E5131513AE12700215124E6081
-:07001600051218A480EE2280
-:03000300020046B2
-:10004600C0E0C083C082C086758600C0D075D00867
-:1000560030990E301107A217929B854699C299D204
-:100066001F30C10E301207A21892C38547C1C2C104
-:10007600D220201F03020442C21F2003030202678C
-:10008600201103020138E54AC3957C503E20133601
-:10009600200B33907F9BE020E303201C29301B12AA
-:1000A600AE4A054A74402EF582E4347EF583E013A9
-:1000B6009217AE4A054A74402EF582E4347EF583E3
-:1000C600E0F546020440C211020440907FC7E4F006
-:1000D600C20330150CC215907FBF04F0C211020492
-:1000E60040907FC8E030E105C211020440907FC90C
-:1000F600E0F57C907DC0E013921520132D200B2A8D
-:03004300021B009D
-:0300230002004692
-:03003B000200467A
-:0300000002163DA8
-:40010600907F9BE020E303201C20301B11907DC1E0139217A3E0F546754A03020440754A02907DC1E0F546020440754A01C211020440E54AC3957C50030201E0907FC6E08A
-:4001460030E107C221C205020440907FC7E0F57C907E40E01392153013030201D8200B7220006F907F9BE020E303201C65301B10907E41E013929BA3E0F599754A038009BE
-:40018600907E41E0F599754A02E54AC3957C4017907FC7E4F0C203201503020440C215907FBF04F0020440301B12AE4A054A74402EF582E4347EF583E0139217AE4A054AA7
-:4001C60074402EF582E4347EF583E0F546D211020440754A01C221020440301303020262200B79907F9BE020E303201C6F301B12AE4A054A74402EF582E4347EF583E013DC
-:40020600929BAE4A054A74402EF582E4347EF583E0F599E54AC3957C4017907FC7E4F0C203201503020440C215907FBF04F0020440301B12AE4A054A74402EF582E4347EB6
-:40024600F583E0139217AE4A054A74402EF582E4347EF583E0F546D211020440C221020440201103020319E54AC3957C503E201336200B33907F9BE020E303201C29301B5F
-:4002860012AE4A054A74C02EF582E4347DF583E0139217AE4A054A74C02EF582E4347DF583E0F546020440C211020440907FC9E4F0D20330150CC215907FBF04F0C2110276
-:4002C6000440907FC6E030E105C211020440907FC7E0F57C907E40E013921520132D200B2A907F9BE020E303201C20301B11907E41E0139217A3E0F546754A03020440759E
-:400306004A02907E41E0F546020440754A01C211020440E54AC3957C50030203C1907FC8E030E107C221C205020440907FC9E0F57C907DC0E01392153013030203B9200B48
-:400346007220006F907F9BE020E303201C65301B10907DC1E013929BA3E0F599754A038009907DC1E0F599754A02E54AC3957C4017907FC9E4F0D203201503020440C21573
-:40038600907FBF04F0020440301B12AE4A054A74C02EF582E4347DF583E0139217AE4A054A74C02EF582E4347DF583E0F546D211020440754A01C221020440301303020463
-:4003C6003E200B74907F9BE020E303201C6A301B12AE4A054A74C02EF582E4347DF583E013929BAE4A054A74C02EF582E4347DF583E0F599E54AC3957C4013907FC9E4F09D
-:40040600D203301535C215907FBF04F0802C301B12AE4A054A74C02EF582E4347DF583E0139217AE4A054A74C02EF582E4347DF583E0F546D2118002C221D2252020030230
-:40044600080CC220200403020631201203020502E54BC3957D503E201436200D33907F9AE020E503201E29301D12AE4B054B74402EF582E4347DF583E0139218AE4B054B99
-:4004860074402EF582E4347DF583E0F54702080AC21202080A907FCBE4F0C20430160CC216907FC104F0C21202080A907FCCE030E105C21202080A907FCDE0F57D907CC0BB
-:4004C600E013921620142D200D2A907F9AE020E503201E20301D11907CC1E0139218A3E0F547754B0302080A754B02907CC1E0F54702080A754B01C21202080AE54BC39566
-:400506007D50030205AA907FCAE030E107C222C20602080A907FCBE0F57D907D40E01392163014030205A2200D7220006F907F9AE020E503201E65301D10907D41E013920D
-:40054600C3A3E0F5C1754B038009907D41E0F5C1754B02E54BC3957D4017907FCBE4F0C20420160302080AC216907FC104F002080A301D12AE4B054B74402EF582E4347D24
-:40058600F583E0139218AE4B054B74402EF582E4347DF583E0F547D21202080A754B01C22202080A30140302062C200D79907F9AE020E503201E6F301D12AE4B054B7440E9
-:4005C6002EF582E4347DF583E01392C3AE4B054B74402EF582E4347DF583E0F5C1E54BC3957D4017907FCBE4F0C20420160302080AC216907FC104F002080A301D12AE4B91
-:40060600054B74402EF582E4347DF583E0139218AE4B054B74402EF582E4347DF583E0F547D21202080AC22202080A2012030206E3E54BC3957D503E201436200D33907F1A
-:400646009AE020E503201E29301D12AE4B054B74C02EF582E4347CF583E0139218AE4B054B74C02EF582E4347CF583E0F54702080AC21202080A907FCDE4F0D20430160C43
-:40068600C216907FC104F0C21202080A907FCAE030E105C21202080A907FCBE0F57D907D40E013921620142D200D2A907F9AE020E503201E20301D11907D41E0139218A352
-:4006C600E0F547754B0302080A754B02907D41E0F54702080A754B01C21202080AE54BC3957D500302078B907FCCE030E107C222C20602080A907FCDE0F57D907CC0E013AC
-:400706009216301403020783200D7220006F907F9AE020E503201E65301D10907CC1E01392C3A3E0F5C1754B038009907CC1E0F5C1754B02E54BC3957D4017907FCDE4F0AE
-:40074600D20420160302080AC216907FC104F002080A301D12AE4B054B74C02EF582E4347CF583E0139218AE4B054B74C02EF582E4347CF583E0F547D21202080A754B0173
-:40078600C22202080A301403020808200D74907F9AE020E503201E6A301D12AE4B054B74C02EF582E4347CF583E01392C3AE4B054B74C02EF582E4347CF583E0F5C1E54B3F
-:4007C600C3957D4013907FCDE4F0D204301635C216907FC104F0802C301D12AE4B054B74C02EF582E4347CF583E0139218AE4B054B74C02EF582E4347CF583E0F547D2122A
-:400806008002C222D22520980302093EC2982001030208B0202327AE48054874802EF582E4347EF583E599F0301B49AE48054874802EF582E4347EF583E598F08036AF996E
-:40084600EFB55804D20B802CEFB55704C20B8024AE48054874802EF582E4347EF583EFF0301B11AE48054874802EF582E4347EF583E598F0D219E548C39554500302093C9F
-:40088600907FB8E030E115E548C39440500302093C15481548052DD20C02093C907FB7E548F0754800C20102093C202327AE48054874002EF582E4347EF583E599F0301BBF
-:4008C60049AE48054874002EF582E4347EF583E598F08036AF99EFB55804D20B802CEFB55704C20B8024AE48054874002EF582E4347EF583EFF0301B11AE48054874002E51
-:40090600F582E4347EF583E598F0D219E548C395544023907FB6E030E111E548C39440401515481548052DD20C800B907FB9E548F0754800D201D22520C003020A70C2C016
-:400946002002030209E2202427AE49054974802EF582E4347DF583E5C1F0301D49AE49054974802EF582E4347DF583E5C0F08036AFC1EFB57004D20D802CEFB56F04C20DAE
-:400986008024AE49054974802EF582E4347DF583EFF0301D11AE49054974802EF582E4347DF583E5C0F0D21AE549C3956C5003020A6E907FBCE030E115E549C39440500351
-:4009C600020A6E154915490539D20E020A6E907FBBE549F0754900C202020A6E202427AE49054974002EF582E4347DF583E5C1F0301D49AE49054974002EF582E4347DF555
-:400A060083E5C0F08036AFC1EFB57004D20D802CEFB56F04C20D8024AE49054974002EF582E4347DF583EFF0301D11AE49054974002EF582E4347DF583E5C0F0D21AE54983
-:400A4600C3956C4023907FBAE030E111E549C394404015154915490539D20E800B907FBDE549F0754900D202D225302505C225020056D0D0D086D082D083D0E032907FCE99
-:400A8600E030E103020BA5E4F51274402512F582E4347CF583E0FFE5127C007B00244CF9EC3400FAEF1215CD0512E512B418DBE54C600C75C92075C836854DCA854ECBE5BC
-:400AC6004F13921B929FE55013921CE551139223E5526009907F98E054FBF08007907F98E04404F0E5536009907F98E0547FF08007907F98E04480F0E559600BC213C20B18
-:400B0600907F95E04402F0E55A600BD20BD20C907F95E04402F0E55B600DC2AFC211D200E4F57CF54AD2AFE55C6005302302D20BE55D6015907F95E054FDF0907F9EE044D9
-:400B460002F0907F98E054FDF0E55E600AD29CC298752E01754028E55F6007C29CE4F548F52EE5606003E4F548E5616002D207E5626008E55E7002F540D20CE56360199060
-:400B86007FD77411F07431F07412F07432F07415F07435F0D203D201D209E4907FCFF0A213E433FF652B60048F2BD20CA20BE433FF652C60048F2CD20C907F9BE054086589
-:400BC600276007E05408F527D20C907F9BE05440B52909E054406440F529D20C300735C2AF300118907FB8E020E127E5486009907FB7F0E4F548C201C2078016907FB6E0E9
-:400C060020E10FE5486009907FB9F0E4F548D201C207D2AF20053730031B907FC6E020E12D907E40E0139215754A01907FC7E0F57CD2058019907FC8E020E112907DC0E0CF
-:400C4600139215754A01907FC9E0F57CD205202133200006E54A657C702A30051A300309E4907FC7F0C2038007E4907FC9F0D203C205E4F57CF54A30150AC215C200907F5C
-:400C8600BF7401F0302103020D94200503020D94301C0A907F9BE020E303020D94300B03020D94301303020D94300362301B12AF4A054A74402FF582E4347EF583E01392CE
-:400CC6002DAF4A054A74402FF582E4347EF583E0F513E54AC3957C502A301B12AF4A054A74402FF582E4347EF583E0139217AF4A054A74402FF582E4347EF583E0F546D266
-:400D060011806BC211E4907FC7F0C2038060301B12AF4A054A74C02FF582E4347DF583E013922DAF4A054A74C02FF582E4347DF583E0F513E54AC3957C502A301B12AF4A67
-:400D4600054A74C02FF582E4347DF583E0139217AF4A054A74C02FF582E4347DF583E0F546D2118009C211E4907FC9F0D203301B04A22D929BD221C2AF85139920110D3043
-:400D8600150AC215C200907FBF7401F0D2AF907FD0E030E103020EB5E4F51274C02512F582E4347BF583E0FFE5127C007B002464F9EC3400FAEF1215CD0512E512B418DB51
-:400DC600E564600B758960758840D2DF85658DE56713921D92C7E56813921EE569139224E56A6009907F97E054EFF08007907F97E04410F0E56B6009907F97E0547FF080A4
-:400E060007907F97E04480F0E571600BC214C20D907F94E04408F0E572600BD20DD20E907F94E04408F0E573600DC2AFC212D200E4F57DF54BD2AFE5746005302402D20D20
-:400E4600E5756015907F94E054F7F0907F9DE04408F0907F97E054F7F0E576600AD2C4C2C0753A01754128E5776007C2C4E4F549F53AE5786003E4F549E5796002D208E5F0
-:400E86007A6008E5767002F541D20EE57B6019907FD77413F07433F07414F07434F07416F07436F0D204D202D20AE4907FD1F0A214E433FF653760048F37D20EA20DE43304
-:400EC600FF653860048F38D20E907F9AE0542065336007E05420F533D20E907F9AE05440B53509E054406440F535D20E300835C2AF300218907FBCE020E127E54960099099
-:400F06007FBBF0E4F549C202C2088016907FBAE020E10FE5496009907FBDF0E4F549D202C208D2AF20063730041B907FCAE020E12D907D40E0139216754B01907FCBE0F503
-:400F46007DD2068019907FCCE020E112907CC0E0139216754B01907FCDE0F57DD206202233200006E54B657D702A30061A300409E4907FCBF0C2048007E4907FCDF0D2042C
-:400F8600C206E4F57DF54B30160AC216C200907FC17401F03022030210A42006030210A4301E0A907F9AE020E5030210A4300D030210A43014030210A4300462301D12AF8E
-:400FC6004B054B74402FF582E4347DF583E013922DAF4B054B74402FF582E4347DF583E0F513E54BC3957D502A301D12AF4B054B74402FF582E4347DF583E0139218AF4B78
-:40100600054B74402FF582E4347DF583E0F547D212806BC212E4907FCBF0C2048060301D12AF4B054B74C02FF582E4347CF583E013922DAF4B054B74C02FF582E4347CF5F2
-:4010460083E0F513E54BC3957D502A301D12AF4B054B74C02FF582E4347CF583E0139218AF4B054B74C02FF582E4347CF583E0F547D2128009C212E4907FCDF0D204301DF4
-:4010860004A22D92C3D222C2AF8513C120120D30160AC216C200907FC17401F0D2AF907FC2E030E10302117AE51A7046300C3FE540703BA20933F531C209C20CE4F5127E0D
-:4010C600007B0074262512F9EE3400FA121587FF74802512F582E4347BF583EFF00512E512B40CDB907FC3740CF075401022751A0122E51A64017045300E3EE541703AA2C5
-:401106000A33F53DC20AC20EE4F5127E007B0074322512F9EE3400FA121587FF74802512F582E4347BF583EFF00512E512B40CDB907FC3740CF0754110751A0222E51C60CA
-:4011460030151CE4F5127E007B00741B2512F9EE3400FA121587FF74802512F582E4347BF583EFF00512E512B403DB907FC37403F0E4F51A22907FE9E012161712400012A7
-:40118600B401132003119E06123308122D0912200A13760B0000136F907FEBE024FE6016146040240270697419907FD4F07400907FD5F0021376907FEAE0FF12174B8B1261
-:4011C6008A138914EA496011AE02EE907FD4F0AF01EF907FD5F0021376907FB4E04401F0021376907FEAE0FF12179A8B128A138914EA496011AE02EE907FD4F0AF01EF9083
-:401206007FD5F0021376907FB4E04401F0021376907FB4E04401F0021376907F007401F0907FB5F00213761214C3021376907F007401F0907FB5F0021376907FE8E0247FBF
-:4012460060241460312402705BA226E433FF25E0FFA22BE4334F907F00F0E4A3F0907FB57402F0021376E4907F00F0A3F0907FB57402F0021376907FECE0F45480FFC45429
-:401286000FFFE054072F25E024B4F582E4347FF583E054FD907F00F0E4A3F0907FB57402F0021376907FB4E04401F0021376907FE8E024FE601D24026003021376907FEA0B
-:4012C600E0B40105C226021376907FB4E04401F0021376907FEAE07038907FECE0F45480FFC4540FFFE054072F25E024B4F582E4347FF583E4F0907FECE05480FF131313A7
-:40130600541FFFE054072F907FD7F0E04420F0805F907FB4E04401F08056907FE8E024FE60182402704A907FEAE0B40104D226803F907FB4E04401F08036907FEAE07020A3
-:40134600907FECE0F45480FFC4540FFFE054072F25E024B4F582E4347FF5837401F08010907FB4E04401F08007907FB4E04401F0907FB4E04402F0222028030214C2E54063
-:4013860060021540E548604F65447045E542F460020542E542C39555403DC2AF300118907FB8E020E127907FB7E548F0C201E4F548F542F5448016907FB6E020E10F907F07
-:4013C600B9E548F0D201E4F548F542F544D2AF8006854844E4F542E52E602D201907907F9BE030E00EE52F6005E4F52FD20CE4F53E8013E53ED39556500CE53EB556057504
-:401406002F01D20C053EC219E54160021541E549604F65457045E543F460020543E543C3956D403DC2AF300218907FBCE020E127907FBBE549F0C202E4F549F543F54580E2
-:4014460016907FBAE020E10F907FBDE549F0D202E4F549F543F545D2AF8006854945E4F543E53A602D201A07907F9AE030E20EE53B6005E4F53BD20EE4F53F8013E53FD35E
-:40148600956E500CE53FB56E05753B01D20E053FC21A907FD2E020E123907B40E06009E0F51C907B42E0F51D907B41E06009907FD77417F07437F0E4907FD3F022E4907FC5
-:4014C60093F0907F9C7430F0907F96E04410F0907F94740DF0907F9D749AF0907F97E054FDF0907F957423F0907F9E7484F0E4907FC7F0907FC9F0907FCFF075984043A89E
-:4015060010C21BC205C221C20BC213F57CF54AC211C215F542C219F544F548C223C21CF52DF52FC207C200C21FF53EC209D20CF526907FCBF0907FCDF0907FD1F075C04043
-:4015460043A840C21DC206C222C20DC214F57DF54BC212C216F543C21AF545F549C224C21EF539F53BC208C200C220F53FC20AD20E753201907FDF74FFF0907FDEF0D228DE
-:4015860022BB010689828A83E0225002E722BBFE02E32289828A83E49322BB010CE58229F582E5833AF583E0225006E92582F8E622BBFE06E92582F8E222E58229F582E553
-:4015C600833AF583E49322BB010689828A83F0225002F722BBFE01F322BB0110E58229F582E5833AF583E0F5F0A3E0225009E92582F886F008E622BBFE0AE92582F8E2F511
-:40160600F008E222E5832AF583E993F5F0A3E99322D083D082F8E4937012740193700DA3A393F8740193F5828883E4737402936860EFA3A3A380DF787FE4F6D8FD75817D0E
-:401646000216840216C9E493A3F8E493A34003F68001F208DFF48029E493A3F85407240CC8C333C4540F4420C8834004F456800146F6DFE4800B010204081020408090181A
-:40168600C5E47E019360BCA3FF543F30E509541FFEE493A360010ECF54C025E060A840B8E493A3FAE493A3F8E493A3C8C582C8CAC583CAF0A3C8C582C8CAC583CADFE9DE39
-:4016C600E780BE751101907F92E054FDF0907FAEE0FFD39226E433FEEF4EF0D2E843D820907FDE7401F0907FDFF0907FAB74FFF0907FA9F0907FAAF05391EF907FAFE044C5
-:4017060001F0907FAEE0440DF0D2AFD2BCD2BED22D12187FC227C225C228302803120A83907FD8E065106008E0F51012137E80EA302707C22712117B80E0302CDDC22C12C5
-:40174600002680D622E4FE7517FF751819751912AB17AA18A9199000011215A06402702DAD060EEDB50701229000021215DF85F015F5166215E5156216E516621529FDE551
-:40178600153AA9057517FFF518891980C37B007A007900228F15E4F5167517FF751819751986AB17AA18A9199000011215A0B4031DAF160516EFB51501221215877E0029BE
-:4017C600FFEE3AA9077517FFF518891980D47B007A00790022E4907F93F0907F9CF0907F94F0907F9D7402F0907F97F0E4907F95F0907F9E74FFF0E4907F98F0907F9DF003
-:4018060022C0E0C083C082C085C084C086758600907FC4E4F05391EF907FAB7404F0D086D084D085D082D083D0E032C0E0C083C082C085C084C086758600D2275391EF9024
-:401846007FAB7401F0D086D084D085D082D083D0E032C0E0C083C082C085C084C086758600D22C5391EF907FAB7408F0D086D084D085D082D083D0E032907FD6E054FBF0DD
-:40188600E04408F0302D04E04402F07FF47E01120006907FD6E054F7F0E04404F0227400F58690FDA57C05A3E582458370F922907FD6E04480F0438701000000000022C125
-:4018C600AA011A00031B030000C127C12CC126C12B000000000000000000000000000000000000000000000000000000000000000000000000000000000012011001FF0031
-:401906000040CD060F0100000102000109027400010100A032090400000EFF0000000705010240000007050202400000070503024000000705040240000007050502400078
-:4019460000070506024000000705070240000007058102400001070582024000010705830240000107058402400001070585024000010705860240000107058702400001F3
-:401986000403090448034B00650079007300700061006E002C002000610020006400690076006900730069006F006E0020006F006600200049006E006E006F005300790040
-:4019C6007300200049006E0063002E0036034B00650079007300700061006E0020005500530042002000530065007200690061006C002000410064006100700074006500F9
-:401A0600720000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002E
-:401A46000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000060
-:401A86000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020
-:401AC6000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002183100021B78
-:091B06000400021807000218583F
-:00000001FF
-
-	The firmware contained herein is
-
-		Copyright (C) 1999-2001
-		Keyspan, A division of InnoSys Incorporated ("Keyspan")
-
-	as an unpublished work. This notice does not imply unrestricted or
-	public access to the source code from which this firmware image is
-	derived.  Except as noted below this firmware image may not be
-	reproduced, used, sold or transferred to any third party without
-	Keyspan's prior written consent.  All Rights Reserved.
-
-	Permission is hereby granted for the distribution of this firmware
-	image as part of a Linux or other Open Source operating system kernel
-	in text or binary form as required.
-
-	This firmware may not be modified and may only be used with
-	Keyspan hardware.  Distribution and/or Modification of the
-	keyspan.c driver which includes this firmware, in whole or in
-	part, requires the inclusion of this statement."
--- zfcpdump-kernel-4.4.orig/firmware/keyspan/usa28x.HEX
+++ /dev/null
@@ -1,141 +0,0 @@
-:030033000212F7BF
-:10000300E4907F93F0907F9C7430F0E4907F96F0BF
-:10001300907F94F0907F9D74FFF0E4907F97F09031
-:0F0023007F95F0907F9E7407F0E4907F98F02215
-:1000460030091812131BEFC3953C40030200D890E9
-:100056007FBF7401F0C209C200807730033B907FF6
-:10006600C6E020E16D12131BEFC394405064907EEE
-:1000760040E0139209907FC7E014F5192000116043
-:100086000FF5087E7E7F41750C7E750D41120CBA08
-:10009600C203E4907FC7F08039907FC8E020E13248
-:1000A60012131BEFC394405029907DC0E0139209B0
-:1000B600907FC9E014F519200011600FF5087E7DC8
-:1000C6007FC1750C7D750DC1120CBAD203E4907F09
-:1000D600C9F0907FB6E030E1030201601211D68FBD
-:1000E600191213278F36E519C3953A500F1212EBE2
-:1000F600EF30E008E53620E703300B5EC20BE5196A
-:0C003600907F987410F090C000E0FF2252
-:03004300021300A5
-:03000000020E00ED
-:400106006058B48003433602E53630E726E519D3942040037519208519087E7E7F80750C7E750D80AF36120F4BE51925E0907FB7F08027E519D3943F400375193F851908D4
-:40014600907E80E536F07E7E7F81750C7E750D81120CDFE51904907FB7F0907FCEE030E1062005030203C1C205E4F51874402518F582E4347CF583E0FFE5187C007B017AF1
-:400186007E79002400F9EC347EFAEF120ED20518E518B420D7907E00E06068907E03E060247F01E4FD1211B17F037DCD1211B1434680907F987414F090C000E546F0E490E0
-:4001C6007E13F08030907E01E0FF121035907E02E0FF12105B7F01907E11E0FD1211B17F037D071211B1434680907F987414F090C000E546F0907F987412F0E5404406903E
-:40020600C000F0907E03E07006907E13E07008E4907E13F07525FF907E05E06012A3E0543FF544907F987413F090C000E544F0907E07E0602BA3E0600543428080035342DA
-:400246007F5342FC907E09E06011434202A3E0FF1210A7907E0BE0FF1210CDAF42121081907E03E0600853427FAF42121081907E0CE06018A3E0600543460280035346FDB4
-:40028600907F987414F090C000E546F0907E0EE06018A3E0600543460180035346FE907F987414F090C000E546F0907E12E0F53AA3E013920DA3E0F53CA3E060054346108B
-:4002C60080035346EF907F987414F090C000E546F0907E16E060325344BF907F987413F0E544547F90C000F0907F987411F01212DFEF54FE90C000F0533EFDE4FFAD3E120F
-:4003060011B1E4F52AF529D207907E17E0600F433E02E4FFAD3E1211B1752901D207907E18E06010907F987412F0E540440490C000F0D200907E19E06011434440907F98F2
-:400346007413F0E544547F90C000F0907E1AE0600F533EFEE4FFAD3E1211B1752B01D207907E1BE0600F433E01E4FFAD3E1211B1E4F52BD207907E1CE0600E907F98741284
-:40038600F0E540440290C000F0907E1DE06002D20B907E1EE06008752C01E4F538D207907E1FE06011907FD77411F07431F07415F07435F0D203E4907FCFF0301A52E53892
-:4003C60060021538201349E513D3940040041513803E75130A301B02D2131212DFEF5401F519652A600585192AD207121333EF5480F51965266005851926D207300D11127F
-:400406001333EF5410F51965256005851925D207201B030207EC300A1812136FEFC3953D40030204AE907FC17401F0C20AC200807730043B907FCAE020E16D12136FEFC35A
-:4004460094405064907D40E013920A907FCBE014F519200011600FF5087E7D7F41750C7D750D41120D04C204E4907FCBF08039907FCCE020E13212136FEFC39440502990BC
-:400486007CC0E013920A907FCDE014F519200011600FF5087E7C7FC1750C7C750DC1120D04D204E4907FCDF0907FBAE030E1030205361212208F1912137B8F37E519C3952B
-:4004C6003B500F121357EF30E008E53720E703300C5EC20CE5196058B48003433702E53730E726E519D3942040037519208519087E7D7F80750C7D750D80AF37120F84E503
-:400506001925E0907FBBF08027E519D3943F400375193F851908907D80E537F07E7D7F81750C7D750D81120D29E51904907FBBF0907FD0E030E106200603020797C206E4F8
-:40054600F51874C02518F582E4347BF583E0FFE5187C007B017A7E79202420F9EC347EFAEF120ED20518E518B420D7907E20E06068907E23E060247F01E4FD1211FB7F0329
-:400586007DCD1211FB434780907F98740CF090C000E547F0E4907E33F08030907E21E0FF121119907E22E0FF12113F7F01907E31E0FD1211FB7F037D071211FB4347809048
-:4005C6007F98740CF090C000E547F0907F98740AF0E541440690C000F0907E23E07006907E33E07008E4907E33F0752EFF907E25E06012A3E0543FF545907F98740BF090EB
-:40060600C000E545F0907E27E0602BA3E06005434380800353437F5343FC907E29E06011434302A3E0FF121165907E2BE0FF12118BAF431210F3907E23E0600853437FAFFE
-:40064600431210F3907E2CE06018A3E0600543470280035347FD907F98740CF090C000E547F0907E2EE06018A3E0600543470180035347FE907F98740CF090C000E547F0D4
-:40068600907E32E0F53BA3E013920EA3E0F53DA3E0600543471080035347EF907F98740CF090C000E547F0907E36E060325345BF907F98740BF0E545547F90C000F0907F79
-:4006C600987409F012134BEF54FE90C000F0533FFDE4FFAD3F1211FBE4F533F532D208907E37E0600F433F02E4FFAD3F1211FB753201D208907E38E06010907F98740AF043
-:40070600E541440490C000F0D200907E39E06011434540907F98740BF0E545547F90C000F0907E3AE0600F533FFEE4FFAD3F1211FB753401D208907E3BE0600F433F01E4E9
-:40074600FFAD3F1211FBE4F534D208907E3CE0600E907F98740AF0E541440290C000F0907E3DE06002D20C907E3EE06008753501E4F539D208907E3FE06011907FD7741389
-:40078600F07433F07416F07436F0D204E4907FD1F0301A52E53960021539301349E513D3940040041513803E75130A301B02C21312134BEF5401F51965336005851933D279
-:4007C60008121387EF5480F519652F600585192FD208300E11121387EF5410F519652E600585192ED208301A2A907FD2E020E123907B40E06009E0F515907B42E0F5169035
-:400806007B41E06009907FD77417F07437F0E4907FD3F0907FC2E030E103020920E50A7040300739E5387035C207F5187E007B0074242518F9EE3400FA120E8CFF748025BD
-:4008460018F582E4347BF583EFF00518E518B409DB907FC37409F0753810E4F52C750A0122E50A64017040300839E5397035C208F5187E007B00742D2518F9EE3400FA1297
-:400886000E8CFF74802518F582E4347BF583EFF00518E518B409DB907FC37409F0753910E4F535750A0222E50A6402703630142FC214F5187E007B00740E2518F9EE340083
-:4008C600FA120E8CFF74802518F582E4347BF583EFF00518E518B405DB907FC37405F0750A0322E51560301515E4F5187E007B0074142518F9EE3400FA120E8CFF748025F2
-:4009060018F582E4347BF583EFF00518E518B403DB907FC37403F0E4F50A22907FE9E0120EE40A08000A7C010AE80309440609FB0809F50909DD0A09EC0B00000B37907F3D
-:40094600EBE024FE6019146061240260030209D37419907FD4F07400907FD5F0020B3E907FEAE070047F0280027F03758282758319EFF075827B758319F0758274758319B2
-:40098600F0758266758319F0758258758319F0907FEAE004758217758319F07419907FD4F07412907FD5F0020B3E907FEAE0FF120F0AEA49600DEA907FD4F0E9907FD5F085
-:4009C600020B3E907FB4E04401F0020B3E907FB4E04401F0020B3E907F00E509F0907FB57401F0020B3E907FEAE0F509020B3E120B46020B3E907F007401F0907FB5F00205
-:400A06000B3E907FE8E0247F60241460312402705BA210E433FF25E0FFA216E4334F907F00F0E4A3F0907FB57402F0020B3EE4907F00F0A3F0907FB57402F0020B3E907F04
-:400A4600ECE0F45480FFC4540FFFE054072F25E024B4F582E4347FF583E054FD907F00F0E4A3F0907FB57402F0020B3E907FB4E04401F0020B3E907FE8E024FE601D24020F
-:400A86006003020B3E907FEAE0B40105C210020B3E907FB4E04401F0020B3E907FEAE07038907FECE0F45480FFC4540FFFE054072F25E024B4F582E4347FF583E4F0907FB6
-:400AC600ECE05480FF131313541FFFE054072F907FD7F0E04420F0805F907FB4E04401F08056907FE8E024FE60182402704A907FEAE0B40104D210803F907FB4E04401F049
-:400B06008036907FEAE07020907FECE0F45480FFC4540FFFE054072F25E024B4F582E4347FF5837401F08010907FB4E04401F08007907FB4E04401F0907FB4E04402F022D4
-:400B4600E4907F93F0907F9C7430F0E4907F96F0907F9574C0F0907F9E743FF0907F987418F0E4F58E907FDF74FFF0907FDEF0E4F5247518017B0074242518F9E43400FA8B
-:400B8600E4120ED20518E518B409EA753A01E4F538F513F536C207C20BC205C200C209C213907F987413F075440390C0007403F07F0CE4FD1211B17F108F42121081907F02
-:400BC600987412F07F018F40EF440690C000F0907F987414F075468090C0007480F00FE4FD1211B1E4FF7EA3AD068D3E1211B1907F987411F090C000E4F07F057D7F12118E
-:400C0600B17F0112126A7F037D071211B1201B03020CB7752D017518017B00742D2518F9E43400FAE4120ED20518E518B409EA753B01E4F539F513F537C208C20CC206C2CD
-:400C460000C20AC213907F98740BF075450390C0007403F07F0CE4FD1211FB7F108F431210F3907F98740AF07F018F41EF440690C000F0907F98740CF075478090C000744E
-:400C860080F00FE4FD1211FBE4FF7EA3AD068D3F1211FB907F987409F090C000E4F07F057D7F1211FB7F0112128B7F037D071211FBD21222907F987410F0AF08E50DF582A5
-:400CC600E50CF583C2AF058690C0000586E0A30586F00586DFF7D2AF22907F987410F0AF08E50DF582E50CF583C2AF058690C000E00586F0A30586DFF70586D2AF22907F20
-:400D0600987408F0AF08E50DF582E50CF583C2AF058690C0000586E0A30586F00586DFF7D2AF22907F987408F0AF08E50DF582E50CF583C2AF058690C000E00586F0A3055C
-:400D460086DFF70586D2AF227400F58690FDA57C05A3E582458370F922907FD6E04480F0438701000000000022D219907F92E04402F0907FAEE0FFD39210E433FEEF4EF089
-:400D8600D2E843D820907FDE7401F0907FDFF0907FAB74FFF0907FA9F0907FAAF05391EF907FAFE04401F0907FAEE0440DF0D2AFD21A121245C211E4F50BF513C217C212D4
-:400DC600907FA104F0907FD8E065176010301205D21A120046907FD8E0F5178008301205C21A120046301107C21112092180D63018D3C21812139380CC22787FE4F6D8FDC7
-:400E0600758147020E47020D6FE493A3F8E493A34003F68001F208DFF48029E493A3F85407240CC8C333C4540F4420C8834004F456800146F6DFE4800B01020408102040F5
-:400E4600809012ACE47E019360BCA3FF543F30E509541FFEE493A360010ECF54C025E060A840B8E493A3FAE493A3F8E493A3C8C582C8CAC583CAF0A3C8C582C8CAC583CA1E
-:400E8600DFE9DEE780BEBB010689828A83E0225002E722BBFE02E32289828A83E49322BB010CE58229F582E5833AF583E0225006E92582F8E622BBFE06E92582F8E222E5B8
-:400EC6008229F582E5833AF583E49322BB010689828A83F0225002F722BBFE01F322D083D082F8E4937012740193700DA3A393F8740193F5828883E4737402936860EFA3C1
-:400F0600A3A380DF8F18E4F519751AFF751B19751C86AB1AAA1BA91C900001120EA5B4031DAF190519EFB5180122120E8C7E0029FFEE3AA907751AFFF51B891C80D47B00A5
-:400F46007A007900228F1A050DE50DAE0C7002050C14F5828E83E51AF0120036050DE50DAC0C7002050C14F5828C83EFF01508E508600A1213278F1AEF423680CA228F1AFC
-:400F8600050DE50DAE0C7002050C14F5828E83E51AF012133F050DE50DAC0C7002050C14F5828C83EFF01508E508600A12137B8F1AEF423780CA22C0E0C083C082C085C088
-:400FC60084C086758600907FC4E4F05391EF907FAB7404F0D086D084D085D082D083D0E032C0E0C083C082C085C084C086758600D2115391EF907FAB7401F0D086D084D0C6
-:4010060085D082D083D0E032C0E0C083C082C085C084C086758600D2185391EF907FAB7408F0D086D084D085D082D083D0E032907F987413F090C00074BFF0907F9874108A
-:40104600F090C000EFF0907F987413F0E544547F90C000F022907F987413F090C00074BFF0907F987411F090C000EFF0907F987413F0E544547F90C000F022907F98741349
-:40108600F090C00074BFF0907F987412F090C000EFF0907F987413F0E544547F90C000F022907F987413F090C00074BFF0907F987414F090C000EFF0907F987413F0E544D9
-:4010C600547F90C000F022907F987413F090C00074BFF0907F987416F090C000EFF0907F987413F0E544547F90C000F022907F98740BF090C00074BFF0907F98740AF0902A
-:40110600C000EFF0907F98740BF0E545547F90C000F022907F98740BF090C00074BFF0907F987408F090C000EFF0907F98740BF0E545547F90C000F022907F98740BF090AF
-:40114600C00074BFF0907F987409F090C000EFF0907F98740BF0E545547F90C000F022907F98740BF090C00074BFF0907F98740CF090C000EFF0907F98740BF0E545547FEC
-:4011860090C000F022907F98740BF090C00074BFF0907F98740EF090C000EFF0907F98740BF0E545547F90C000F022907F987413F0E544547F90C000F0907F987417F09075
-:4011C600C000EFF0907F987415F090C000EDF02212130F8F1A12130F8F1BE51A651B601212130F8F1AE51A651B600712130F8F1B80E8AF1A22907F98740BF0E545547F9098
-:40120600C000F0907F98740FF090C000EFF0907F98740DF090C000EDF0221213638F1A1213638F1BE51A651B60121213638F1AE51A651B60071213638F1B80E8AF1A2290C8
-:401246007FD6E054FBF0E04408F0301A04E04402F07FF47E011212C8907FD6E054F7F0E04404F022AE07E4FFE53E547FFD1211B1907F987411F090C000EEF0E4E53E4480E8
-:40128600FD1211B122AE07E4FFE53F547FFD1211FB907F987409F090C000EEF0E4E53F4480FD1211FB22050E02000000000314030000C111C118C195C110C116010A00C19C
-:4012C6009B008E188F19E5191519AE18700215184E6005120D4E80EE22907F987411F090C000E0FF22907F987412F090C000E0FF2253D8EF320000000000020FE70002138A
-:401306000400020FBD0002100E907F987413F090C000E0FF22907F987414F090C000E0FF22907F987415F090C000E0FF22907F987416F090C000E0FF22907F987408F09050
-:40134600C000E0FF22907F987409F090C000E0FF22907F98740AF090C000E0FF22907F98740BF090C000E0FF22907F98740CF090C000E0FF22907F98740DF090C000E0FFC5
-:4013860022907F98740EF090C000E0FF22120003120D5F120B4622000000000000000000000000000000000000000000000000000000000000000000000000000000000083
-:4013C60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E7
-:4014060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A6
-:401446000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000066
-:401486000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000026
-:4014C60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E6
-:4015060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A5
-:401546000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000065
-:401586000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000025
-:4015C60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E5
-:4016060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A4
-:401646000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000064
-:401686000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024
-:4016C60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E4
-:4017060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A3
-:401746000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000063
-:401786000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000023
-:4017C60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E3
-:4018060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A2
-:401846000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000062
-:401886000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000022
-:4018C6000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012011001FF00BF
-:401906000040CD06100100000102000209027400010100A032090400000EFF0000000705010240000007050202400000070503024000000705040240000007050502400076
-:4019460000070506024000000705070240000007058102400001070582024000000705830240000107058402400001070585024000010705860240000107058702400001F4
-:401986000403090448034B00650079007300700061006E002C002000610020006400690076006900730069006F006E0020006F006600200049006E006E006F005300790040
-:4019C6007300200049006E0063002E0036034B00650079007300700061006E0020005500530042002000530065007200690061006C002000410064006100700074006500F9
-:041A0600720000006A
-:00000001FF
-
-	The firmware contained herein is
-
-		Copyright (C) 1999-2001
-		Keyspan, A division of InnoSys Incorporated ("Keyspan")
-
-	as an unpublished work. This notice does not imply unrestricted or
-	public access to the source code from which this firmware image is
-	derived.  Except as noted below this firmware image may not be
-	reproduced, used, sold or transferred to any third party without
-	Keyspan's prior written consent.  All Rights Reserved.
-
-	Permission is hereby granted for the distribution of this firmware
-	image as part of a Linux or other Open Source operating system kernel
-	in text or binary form as required.
-
-	This firmware may not be modified and may only be used with
-	Keyspan hardware.  Distribution and/or Modification of the
-	keyspan.c driver which includes this firmware, in whole or in
-	part, requires the inclusion of this statement."
--- zfcpdump-kernel-4.4.orig/firmware/keyspan/usa28xa.HEX
+++ /dev/null
@@ -1,141 +0,0 @@
-:030033000212F9BD
-:10000300E4907F93F0907F9C7430F0E4907F96F0BF
-:10001300907F94F0907F9D74FFF0E4907F97F09031
-:0F0023007F95F0907F9E7407F0E4907F98F02215
-:10004600300918121327EFC3953C40030200D890DD
-:100056007FBF7401F0C209C200807730033B907FF6
-:10006600C6E020E16D121327EFC394405064907EE2
-:1000760040E0139209907FC7E014F5192000116043
-:100086000FF5087E7E7F41750C7E750D41120CC8FA
-:10009600C203E4907FC7F08039907FC8E020E13248
-:1000A600121327EFC394405029907DC0E0139209A4
-:1000B600907FC9E014F519200011600FF5087E7DC8
-:1000C6007FC1750C7D750DC1120CC8D203E4907FFB
-:1000D600C9F0907FB6E030E1030201601211E48FAF
-:1000E600191213338F36E519C3953A500F12130FB1
-:1000F600EF30E008E53620E703300B5EC20BE5196A
-:0C003600907F987410F090C000E0FF2252
-:03004300021300A5
-:03000000020E0EDF
-:400106006058B48003433602E53630E726E519D3942040037519208519087E7E7F80750C7E750D80AF36120F59E51925E0907FB7F08027E519D3943F400375193F851908C6
-:40014600907E80E536F07E7E7F81750C7E750D81120CEDE51904907FB7F0907FCEE030E1062005030203C1C205E4F51874402518F582E4347CF583E0FFE5187C007B017AE3
-:400186007E79002400F9EC347EFAEF120EE00518E518B420D7907E00E06068907E03E060247F01E4FD1211BF7F037DCD1211BF434680907F987414F090C000E546F0E490B6
-:4001C6007E13F08030907E01E0FF121043907E02E0FF1210697F01907E11E0FD1211BF7F037D071211BF434680907F987414F090C000E546F0907F987412F0E54044069006
-:40020600C000F0907E03E07006907E13E07008E4907E13F07525FF907E05E06012A3E0543FF544907F987413F090C000E544F0907E07E0602BA3E0600543428080035342DA
-:400246007F5342FC907E09E06011434202A3E0FF1210B5907E0BE0FF1210DBAF4212108F907E03E0600853427FAF4212108F907E0CE06018A3E0600543460280035346FD7C
-:40028600907F987414F090C000E546F0907E0EE06018A3E0600543460180035346FE907F987414F090C000E546F0907E12E0F53AA3E013920DA3E0F53CA3E060054346108B
-:4002C60080035346EF907F987414F090C000E546F0907E16E060325344BF907F987413F0E544547F90C000F0907F987411F01212EDEF54FE90C000F0533EFDE4FFAD3E1201
-:4003060011BFE4F52AF529D207907E17E0600F433E02E4FFAD3E1211BF752901D207907E18E06010907F987412F0E540440490C000F0D200907E19E06011434440907F98D6
-:400346007413F0E544547F90C000F0907E1AE0600F533EFEE4FFAD3E1211BF752B01D207907E1BE0600F433E01E4FFAD3E1211BFE4F52BD207907E1CE0600E907F98741268
-:40038600F0E540440290C000F0907E1DE06002D20B907E1EE06008752C01E4F538D207907E1FE06011907FD77411F07431F07415F07435F0D203E4907FCFF0301A52E53892
-:4003C60060021538201349E513D3940040041513803E75130A301B02D2131212EDEF5401F519652A600585192AD20712133FEF5480F51965266005851926D207300D111265
-:40040600133FEF5410F51965256005851925D207201B030207EC300A1812137BEFC3953D40030204AE907FC17401F0C20AC200807730043B907FCAE020E16D12137BEFC336
-:4004460094405064907D40E013920A907FCBE014F519200011600FF5087E7D7F41750C7D750D41120D12C204E4907FCBF08039907FCCE020E13212137BEFC39440502990A2
-:400486007CC0E013920A907FCDE014F519200011600FF5087E7C7FC1750C7C750DC1120D12D204E4907FCDF0907FBAE030E10302053612122E8F191213878F37E519C39503
-:4004C6003B500F121363EF30E008E53720E703300C5EC20CE5196058B48003433702E53730E726E519D3942040037519208519087E7D7F80750C7D750D80AF37120F92E5E9
-:400506001925E0907FBBF08027E519D3943F400375193F851908907D80E537F07E7D7F81750C7D750D81120D37E51904907FBBF0907FD0E030E106200603020797C206E4EA
-:40054600F51874C02518F582E4347BF583E0FFE5187C007B017A7E79202420F9EC347EFAEF120EE00518E518B420D7907E20E06068907E23E060247F01E4FD1212097F030C
-:400586007DCD121209434780907F98740CF090C000E547F0E4907E33F08030907E21E0FF121127907E22E0FF12114D7F01907E31E0FD1212097F037D0712120943478090FF
-:4005C6007F98740CF090C000E547F0907F98740AF0E541440690C000F0907E23E07006907E33E07008E4907E33F0752EFF907E25E06012A3E0543FF545907F98740BF090EB
-:40060600C000E545F0907E27E0602BA3E06005434380800353437F5343FC907E29E06011434302A3E0FF121173907E2BE0FF121199AF43121101907E23E0600853437FAFD3
-:4006460043121101907E2CE06018A3E0600543470280035347FD907F98740CF090C000E547F0907E2EE06018A3E0600543470180035347FE907F98740CF090C000E547F0C5
-:40068600907E32E0F53BA3E013920EA3E0F53DA3E0600543471080035347EF907F98740CF090C000E547F0907E36E060325345BF907F98740BF0E545547F90C000F0907F79
-:4006C600987409F0121357EF54FE90C000F0533FFDE4FFAD3F121209E4F533F532D208907E37E0600F433F02E4FFAD3F121209753201D208907E38E06010907F98740AF019
-:40070600E541440490C000F0D200907E39E06011434540907F98740BF0E545547F90C000F0907E3AE0600F533FFEE4FFAD3F121209753401D208907E3BE0600F433F01E4DA
-:40074600FFAD3F121209E4F534D208907E3CE0600E907F98740AF0E541440290C000F0907E3DE06002D20C907E3EE06008753501E4F539D208907E3FE06011907FD774137A
-:40078600F07433F07416F07436F0D204E4907FD1F0301A52E53960021539301349E513D3940040041513803E75130A301B02C213121357EF5401F51965336005851933D26D
-:4007C60008121393EF5480F519652F600585192FD208300E11121393EF5410F519652E600585192ED208301A2A907FD2E020E123907B40E06009E0F515907B42E0F516901D
-:400806007B41E06009907FD77417F07437F0E4907FD3F0907FC2E030E103020920E50A7040300739E5387035C207F5187E007B0074242518F9EE3400FA120E9AFF748025AF
-:4008460018F582E4347BF583EFF00518E518B409DB907FC37409F0753810E4F52C750A0122E50A64017040300839E5397035C208F5187E007B00742D2518F9EE3400FA1297
-:400886000E9AFF74802518F582E4347BF583EFF00518E518B409DB907FC37409F0753910E4F535750A0222E50A6402703630142FC214F5187E007B00740E2518F9EE340075
-:4008C600FA120E9AFF74802518F582E4347BF583EFF00518E518B405DB907FC37405F0750A0322E51560301515E4F5187E007B0074142518F9EE3400FA120E9AFF748025D6
-:4009060018F582E4347BF583EFF00518E518B403DB907FC37403F0E4F50A22907FE9E0120EF20A08000A7C010AE80309440609FB0809F50909DD0A09EC0B00000B37907F2F
-:40094600EBE024FE6019146061240260030209D37419907FD4F07400907FD5F0020B3E907FEAE070047F0280027F03758282758319EFF075827B758319F0758274758319B2
-:40098600F0758266758319F0758258758319F0907FEAE004758217758319F07419907FD4F07412907FD5F0020B3E907FEAE0FF120F18EA49600DEA907FD4F0E9907FD5F077
-:4009C600020B3E907FB4E04401F0020B3E907FB4E04401F0020B3E907F00E509F0907FB57401F0020B3E907FEAE0F509020B3E120B46020B3E907F007401F0907FB5F00205
-:400A06000B3E907FE8E0247F60241460312402705BA210E433FF25E0FFA216E4334F907F00F0E4A3F0907FB57402F0020B3EE4907F00F0A3F0907FB57402F0020B3E907F04
-:400A4600ECE0F45480FFC4540FFFE054072F25E024B4F582E4347FF583E054FD907F00F0E4A3F0907FB57402F0020B3E907FB4E04401F0020B3E907FE8E024FE601D24020F
-:400A86006003020B3E907FEAE0B40105C210020B3E907FB4E04401F0020B3E907FEAE07038907FECE0F45480FFC4540FFFE054072F25E024B4F582E4347FF583E4F0907FB6
-:400AC600ECE05480FF131313541FFFE054072F907FD7F0E04420F0805F907FB4E04401F08056907FE8E024FE60182402704A907FEAE0B40104D210803F907FB4E04401F049
-:400B06008036907FEAE07020907FECE0F45480FFC4540FFFE054072F25E024B4F582E4347FF5837401F08010907FB4E04401F08007907FB4E04401F0907FB4E04402F022D4
-:400B4600E4907F93F0907F9C7430F0E4907F96F0907F9574C0F0907F9E743FF0907F987418F0E4F58E907FDF74FFF0907FDEF0E4F5247518017B0074242518F9E43400FA8B
-:400B8600E4120EE00518E518B409EA753A01E4F538F513F536C207C20BC205C200C209C213907F987413F075440390C0007403F07F0CE4FD1211BF7F108F4212108F907FD8
-:400BC600987412F07F018F40EF440690C000F0907F987414F075468090C0007480F00FE4FD1211BFE4FF7EA3AD068D3E1211BF907F987411F090C000E4F07F057D7F121172
-:400C0600BF7F011212787F037D071211BF7F137D011211BF201B03020CC5752D017518017B00742D2518F9E43400FAE4120EE00518E518B409EA753B01E4F539F513F537B7
-:400C4600C208C20CC206C200C20AC213907F98740BF075450390C0007403F07F0CE4FD1212097F108F43121101907F98740AF07F018F41EF440690C000F0907F98740CF00E
-:400C860075478090C0007480F00FE4FD121209E4FF7EA3AD068D3F121209907F987409F090C000E4F07F057D7F1212097F011212997F037D071212097F137D01121209D28D
-:400CC6001222907F987410F0AF08E50DF582E50CF583C2AF058690C0000586E0A30586F00586DFF7D2AF22907F987410F0AF08E50DF582E50CF583C2AF058690C000E00568
-:400D060086F0A30586DFF70586D2AF22907F987408F0AF08E50DF582E50CF583C2AF058690C0000586E0A30586F00586DFF7D2AF22907F987408F0AF08E50DF582E50CF577
-:400D460083C2AF058690C000E00586F0A30586DFF70586D2AF227400F58690FDA57C05A3E582458370F922907FD6E04480F0438701000000000022D219907F92E04402F00A
-:400D8600907FAEE0FFD39210E433FEEF4EF0D2E843D820907FDE7401F0907FDFF0907FAB74FFF0907FA9F0907FAAF05391EF907FAFE04401F0907FAEE0440DF0D2AFD21A56
-:400DC600121253C211E4F50BF513C217C212907FA104F0907FD8E065176010301205D21A120046907FD8E0F5178008301205C21A120046301107C21112092180D63018D38A
-:400E0600C21812139F80CC22787FE4F6D8FD758147020E55020D7DE493A3F8E493A34003F68001F208DFF48029E493A3F85407240CC8C333C4540F4420C8834004F4568031
-:400E46000146F6DFE4800B01020408102040809012BAE47E019360BCA3FF543F30E509541FFEE493A360010ECF54C025E060A840B8E493A3FAE493A3F8E493A3C8C582C828
-:400E8600CAC583CAF0A3C8C582C8CAC583CADFE9DEE780BEBB010689828A83E0225002E722BBFE02E32289828A83E49322BB010CE58229F582E5833AF583E0225006E92548
-:400EC60082F8E622BBFE06E92582F8E222E58229F582E5833AF583E49322BB010689828A83F0225002F722BBFE01F322D083D082F8E4937012740193700DA3A393F87401DE
-:400F060093F5828883E4737402936860EFA3A3A380DF8F18E4F519751AFF751B19751C86AB1AAA1BA91C900001120EB3B4031DAF190519EFB5180122120E9A7E0029FFEEB6
-:400F46003AA907751AFFF51B891C80D47B007A007900228F1A050DE50DAE0C7002050C14F5828E83E51AF0120036050DE50DAC0C7002050C14F5828C83EFF01508E508607B
-:400F86000A1213338F1AEF423680CA228F1A050DE50DAE0C7002050C14F5828E83E51AF012134B050DE50DAC0C7002050C14F5828C83EFF01508E508600A1213878F1AEFF8
-:400FC600423780CA22C0E0C083C082C085C084C086758600907FC4E4F05391EF907FAB7404F0D086D084D085D082D083D0E032C0E0C083C082C085C084C086758600D21123
-:401006005391EF907FAB7401F0D086D084D085D082D083D0E032C0E0C083C082C085C084C086758600D2185391EF907FAB7408F0D086D084D085D082D083D0E032907F9833
-:401046007413F090C00074BFF0907F987410F090C000EFF0907F987413F0E544547F90C000F022907F987413F090C00074BFF0907F987411F090C000EFF0907F987413F0C0
-:40108600E544547F90C000F022907F987413F090C00074BFF0907F987412F090C000EFF0907F987413F0E544547F90C000F022907F987413F090C00074BFF0907F987414B3
-:4010C600F090C000EFF0907F987413F0E544547F90C000F022907F987413F090C00074BFF0907F987416F090C000EFF0907F987413F0E544547F90C000F022907F98740BCC
-:40110600F090C00074BFF0907F98740AF090C000EFF0907F98740BF0E545547F90C000F022907F98740BF090C00074BFF0907F987408F090C000EFF0907F98740BF0E54582
-:40114600547F90C000F022907F98740BF090C00074BFF0907F987409F090C000EFF0907F98740BF0E545547F90C000F022907F98740BF090C00074BFF0907F98740CF090C3
-:40118600C000EFF0907F98740BF0E545547F90C000F022907F98740BF090C00074BFF0907F98740EF090C000EFF0907F98740BF0E545547F90C000F022907F987413F0E5CC
-:4011C60044547F90C000F0907F987417F090C000EFF0907F987415F090C000EDF02212131B8F1A12131B8F1BE51A651B601212131B8F1AE51A651B600712131B8F1B80E8ED
-:40120600AF1A22907F98740BF0E545547F90C000F0907F98740FF090C000EFF0907F98740DF090C000EDF02212136F8F1A12136F8F1BE51A651B601212136F8F1AE51A65AD
-:401246001B600712136F8F1B80E8AF1A22907FD6E054FBF0E04408F0301A04E04402F07FF47E011212D6907FD6E054F7F0E04404F022AE07E4FFE53E547FFD1211BF907F2F
-:40128600987411F090C000EEF0E4E53E4480FD1211BF22AE07E4FFE53F547FFD121209907F987409F090C000EEF0E4E53F4480FD12120922050E02000000000314030000DF
-:4012C600C111C118C195C110C116010A00C19B008E188F19E5191519AE18700215184E6005120D5C80EE22907F987411F090C000E0FF2253D8EF32000000020FF500021367
-:401306000400020FCB0002101C907F987412F090C000E0FF22907F987413F090C000E0FF22907F987414F090C000E0FF22907F987415F090C000E0FF22907F987416F0902A
-:40134600C000E0FF22907F987408F090C000E0FF22907F987409F090C000E0FF22907F98740AF090C000E0FF22907F98740BF090C000E0FF22907F98740CF090C000E0FFCA
-:4013860022907F98740DF090C000E0FF22907F98740EF090C000E0FF22120003120D6D120B462200000000000000000000000000000000000000000000000000000000000C
-:4013C60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E7
-:4014060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A6
-:401446000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000066
-:401486000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000026
-:4014C60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E6
-:4015060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A5
-:401546000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000065
-:401586000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000025
-:4015C60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E5
-:4016060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A4
-:401646000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000064
-:401686000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024
-:4016C60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E4
-:4017060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A3
-:401746000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000063
-:401786000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000023
-:4017C60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E3
-:4018060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A2
-:401846000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000062
-:401886000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000022
-:4018C6000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012011001FF00BF
-:401906000040CD06150100000102000209027400010100A032090400000EFF0000000705010240000007050202400000070503024000000705040240000007050502400071
-:4019460000070506024000000705070240000007058102400001070582024000010705830240000107058402400001070585024000010705860240000107058702400001F3
-:401986000403090448034B00650079007300700061006E002C002000610020006400690076006900730069006F006E0020006F006600200049006E006E006F005300790040
-:4019C6007300200049006E0063002E0036034B00650079007300700061006E0020005500530042002000530065007200690061006C002000410064006100700074006500F9
-:041A0600720000006A
-:00000001FF
-
-	The firmware contained herein is
-
-		Copyright (C) 1999-2001
-		Keyspan, A division of InnoSys Incorporated ("Keyspan")
-
-	as an unpublished work. This notice does not imply unrestricted or
-	public access to the source code from which this firmware image is
-	derived.  Except as noted below this firmware image may not be
-	reproduced, used, sold or transferred to any third party without
-	Keyspan's prior written consent.  All Rights Reserved.
-
-	Permission is hereby granted for the distribution of this firmware
-	image as part of a Linux or other Open Source operating system kernel
-	in text or binary form as required.
-
-	This firmware may not be modified and may only be used with
-	Keyspan hardware.  Distribution and/or Modification of the
-	keyspan.c driver which includes this firmware, in whole or in
-	part, requires the inclusion of this statement."
--- zfcpdump-kernel-4.4.orig/firmware/keyspan/usa28xb.HEX
+++ /dev/null
@@ -1,142 +0,0 @@
-:0300330002002D9B
-:04002D0053D8EF3283
-:10004600300918121333EFC3953C40030200D890D1
-:100056007FBF7401F0C209C200807730033B907FF6
-:10006600C6E020E16D121333EFC394405064907ED6
-:1000760040E0139209907FC7E014F5192000116043
-:100086000FF5087E7E7F41750C7E750D41120CCCF6
-:10009600C203E4907FC7F08039907FC8E020E13248
-:1000A600121333EFC394405029907DC0E013920998
-:1000B600907FC9E014F519200011600FF5087E7DC8
-:1000C6007FC1750C7D750DC1120CCCD203E4907FF7
-:1000D600C9F0907FB6E030E1030201601211F58F9E
-:1000E6001912133F8F36E519C3953A500F12131B99
-:1000F600EF30E008E53620E703300B5EC20BE5196A
-:0C003600907F987410F090C000E0FF2252
-:03004300021300A5
-:10000300C0E0C083C082C085C084C086758600906E
-:100013007FC4E4F05391EF907FAB7404F0D086D0AB
-:0A00230084D085D082D083D0E03273
-:03000000020E12DB
-:400106006058B48003433602E53630E726E519D3942040037519208519087E7E7F80750C7E750D80AF36120F5DE51925E0907FB7F08027E519D3943F400375193F851908C2
-:40014600907E80E536F07E7E7F81750C7E750D81120CF1E51904907FB7F0907FCEE030E1062005030203C1E4F51874402518F582E4347CF583E0FFE5187C007B017A7E79AF
-:40018600002400F9EC347EFAEF120EE40518E518B420D7907E00E06068907E03E060247F01E4FD1211D07F037DCD1211D0434680907F987414F090C000E546F0E4907E13F6
-:4001C600F08030907E01E0FF121054907E02E0FF12107A7F01907E11E0FD1211D07F037D071211D0434680907F987414F090C000E546F0907F987412F0E540440690C00093
-:40020600F0907E03E07006907E13E07008E4907E13F07525FF907E05E06012A3E0543FF544907F987413F090C000E544F0907E07E0602BA3E06005434280800353427F53C8
-:4002460042FC907E09E06011434202A3E0FF1210C6907E0BE0FF1210ECAF421210A0907E03E0600853427FAF421210A0907E0CE06018A3E0600543460280035346FD907FFB
-:40028600987414F090C000E546F0907E0EE06018A3E0600543460180035346FE907F987414F090C000E546F0907E12E0F53AA3E013920DA3E0F53CA3E06005434610800317
-:4002C6005346EF907F987414F090C000E546F0907E16E060325344BF907F987413F0E544547F90C000F0907F987411F012130FEF54FE90C000F0533EFDE4FFAD3E1211D080
-:40030600E4F52AF529D207907E17E0600F433E02E4FFAD3E1211D0752901D207907E18E06010907F987412F0E540440490C000F0D200907E19E06011434440907F9874130E
-:40034600F0E544547F90C000F0907E1AE0600F533EFEE4FFAD3E1211D0752B01D207907E1BE0600F433E01E4FFAD3E1211D0E4F52BD207907E1CE0600E907F987412F0E5F8
-:4003860040440290C000F0907E1DE06002D20B907E1EE06008752C01E4F538D207907E1FE06011907FD77411F07431F07415F07435F0D203C205E4907FCFF0301A54E5389E
-:4003C6006002153820134BE513D3940040041513804075130A301B02D21312130FEF5401F519652A600585192AD20712134BEF54806480F51965266005851926D207300D71
-:400406001112134BEF5410F51965256005851925D207201B030207F0300A18121387EFC3953D40030204B0907FC17401F0C20AC200807730043B907FCAE020E16D1213879B
-:40044600EFC394405064907D40E013920A907FCBE014F519200011600FF5087E7D7F41750C7D750D41120D16C204E4907FCBF08039907FCCE020E132121387EFC394405099
-:4004860029907CC0E013920A907FCDE014F519200011600FF5087E7C7FC1750C7C750DC1120D16D204E4907FCDF0907FBAE030E10302053812123F8F191213938F37E5197F
-:4004C600C3953B500F12136FEF30E008E53720E703300C5EC20CE5196058B48003433702E53730E726E519D3942040037519208519087E7D7F80750C7D750D80AF37120FFC
-:4005060096E51925E0907FBBF08027E519D3943F400375193F851908907D80E537F07E7D7F81750C7D750D81120D3BE51904907FBBF0907FD0E030E106200603020799E431
-:40054600F51874C02518F582E4347BF583E0FFE5187C007B017A7E79202420F9EC347EFAEF120EE40518E518B420D7907E20E06068907E23E060247F01E4FD12121A7F03F7
-:400586007DCD12121A434780907F98740CF090C000E547F0E4907E33F08030907E21E0FF121138907E22E0FF12115E7F01907E31E0FD12121A7F037D0712121A43478090AA
-:4005C6007F98740CF090C000E547F0907F98740AF0E541440690C000F0907E23E07006907E33E07008E4907E33F0752EFF907E25E06012A3E0543FF545907F98740BF090EB
-:40060600C000E545F0907E27E0602BA3E06005434380800353437F5343FC907E29E06011434302A3E0FF121184907E2BE0FF1211AAAF43121112907E23E0600853437FAFA0
-:4006460043121112907E2CE06018A3E0600543470280035347FD907F98740CF090C000E547F0907E2EE06018A3E0600543470180035347FE907F98740CF090C000E547F0B4
-:40068600907E32E0F53BA3E013920EA3E0F53DA3E0600543471080035347EF907F98740CF090C000E547F0907E36E060325345BF907F98740BF0E545547F90C000F0907F79
-:4006C600987409F0121363EF54FE90C000F0533FFDE4FFAD3F12121AE4F533F532D208907E37E0600F433F02E4FFAD3F12121A753201D208907E38E06010907F98740AF0EB
-:40070600E541440490C000F0D200907E39E06011434540907F98740BF0E545547F90C000F0907E3AE0600F533FFEE4FFAD3F12121A753401D208907E3BE0600F433F01E4C9
-:40074600FFAD3F12121AE4F534D208907E3CE0600E907F98740AF0E541440290C000F0907E3DE06002D20C907E3EE06008753501E4F539D208907E3FE06011907FD7741369
-:40078600F07433F07416F07436F0D204C206E4907FD1F0301A54E5396002153930134BE513D3940040041513804075130A301B02C213121363EF5401F51965336005851998
-:4007C60033D20812139FEF54806480F519652F600585192FD208300E1112139FEF5410F519652E600585192ED208301A2A907FD2E020E123907B40E06009E0F515907B4297
-:40080600E0F516907B41E06009907FD77417F07437F0E4907FD3F0907FC2E030E103020924E50A7040300739E5387035C207F5187E007B0074242518F9EE3400FA120E9E44
-:40084600FF74802518F582E4347BF583EFF00518E518B409DB907FC37409F0753810E4F52C750A0122E50A64017040300839E5397035C208F5187E007B00742D2518F9EEBF
-:400886003400FA120E9EFF74802518F582E4347BF583EFF00518E518B409DB907FC37409F0753910E4F535750A0222E50A6402703630142FC214F5187E007B00740E25184C
-:4008C600F9EE3400FA120E9EFF74802518F582E4347BF583EFF00518E518B405DB907FC37405F0750A0322E51560301515E4F5187E007B0074142518F9EE3400FA120E9ECB
-:40090600FF74802518F582E4347BF583EFF00518E518B403DB907FC37403F0E4F50A22907FE9E0120EF60A0C000A80010AEC0309480609FF0809F90909E10A09F00B000044
-:400946000B3B907FEBE024FE6019146061240260030209D77419907FD4F07400907FD5F0020B42907FEAE070047F0280027F03758282758319EFF075827B758319F07582DA
-:4009860074758319F0758266758319F0758258758319F0907FEAE004758217758319F07419907FD4F07412907FD5F0020B42907FEAE0FF120F1CEA49600DEA907FD4F0E9BE
-:4009C600907FD5F0020B42907FB4E04401F0020B42907FB4E04401F0020B42907F00E509F0907FB57401F0020B42907FEAE0F509020B42120B4A020B42907F007401F0903B
-:400A06007FB5F0020B42907FE8E0247F60241460312402705BA210E433FF25E0FFA216E4334F907F00F0E4A3F0907FB57402F0020B42E4907F00F0A3F0907FB57402F0022E
-:400A46000B42907FECE0F45480FFC4540FFFE054072F25E024B4F582E4347FF583E054FD907F00F0E4A3F0907FB57402F0020B42907FB4E04401F0020B42907FE8E024FE4E
-:400A8600601D24026003020B42907FEAE0B40105C210020B42907FB4E04401F0020B42907FEAE07038907FECE0F45480FFC4540FFFE054072F25E024B4F582E4347FF583EA
-:400AC600E4F0907FECE05480FF131313541FFFE054072F907FD7F0E04420F0805F907FB4E04401F08056907FE8E024FE60182402704A907FEAE0B40104D210803F907FB47B
-:400B0600E04401F08036907FEAE07020907FECE0F45480FFC4540FFFE054072F25E024B4F582E4347FF5837401F08010907FB4E04401F08007907FB4E04401F0907FB4E017
-:400B46004402F022E4907F93F0907F9C7430F0E4907F96F0907F9574C0F0907F9E743FF0907F987418F0E4F58E907FDF74FFF0907FDEF0E4F5247518017B0074242518F945
-:400B8600E43400FAE4120EE40518E518B409EA753A01E4F538F513F536C207C20BC205C200C209C213907F987413F075440390C0007403F07F0CE4FD1211D07F108F42125F
-:400BC60010A0907F987412F07F018F40EF440690C000F0907F987414F075468090C0007480F00FE4FD1211D0E4FF7EA3AD068D3E1211D0907F987411F090C000E4F07F05B0
-:400C06007D7F1211D07F011212897F037D071211D07F137D091211D0201B03020CC9752D017518017B00742D2518F9E43400FAE4120EE40518E518B409EA753B01E4F53978
-:400C4600F513F537C208C20CC206C200C20AC213907F98740BF075450390C0007403F07F0CE4FD12121A7F108F43121112907F98740AF07F018F41EF440690C000F0907FC0
-:400C860098740CF075478090C0007480F00FE4FD12121AE4FF7EA3AD068D3F12121A907F987409F090C000E4F07F057D7F12121A7F011212AA7F037D0712121A7F137D0927
-:400CC60012121AD21222907F987410F0AF08E50DF582E50CF583C2AF058690C0000586E0A30586F00586DFF7D2AF22907F987410F0AF08E50DF582E50CF583C2AF058690FD
-:400D0600C000E00586F0A30586DFF70586D2AF22907F987408F0AF08E50DF582E50CF583C2AF058690C0000586E0A30586F00586DFF7D2AF22907F987408F0AF08E50DF53A
-:400D460082E50CF583C2AF058690C000E00586F0A30586DFF70586D2AF227400F58690FDA57C05A3E582458370F922907FD6E04480F0438701000000000022D219907F92B8
-:400D8600E04402F0907FAEE0FFD39210E433FEEF4EF0D2E843D820907FDE7401F0907FDFF0907FAB74FFF0907FA9F0907FAAF05391EF907FAFE04401F0907FAEE0440DF0AD
-:400DC600D2AFD21A121264C211E4F50BF513C217C212907FA104F0907FD8E065176010301205D21A120046907FD8E0F5178008301205C21A120046301107C21112092580F9
-:400E0600D63018D3C2181213AB80CC22787FE4F6D8FD758147020E59020D81E493A3F8E493A34003F68001F208DFF48029E493A3F85407240CC8C333C4540F4420C88340FA
-:400E460004F456800146F6DFE4800B01020408102040809012CBE47E019360BCA3FF543F30E509541FFEE493A360010ECF54C025E060A840B8E493A3FAE493A3F8E493A320
-:400E8600C8C582C8CAC583CAF0A3C8C582C8CAC583CADFE9DEE780BEBB010689828A83E0225002E722BBFE02E32289828A83E49322BB010CE58229F582E5833AF583E022D5
-:400EC6005006E92582F8E622BBFE06E92582F8E222E58229F582E5833AF583E49322BB010689828A83F0225002F722BBFE01F322D083D082F8E4937012740193700DA3A37A
-:400F060093F8740193F5828883E4737402936860EFA3A3A380DF8F18E4F519751AFF751B19751C86AB1AAA1BA91C900001120EB7B4031DAF190519EFB5180122120E9E7EC4
-:400F46000029FFEE3AA907751AFFF51B891C80D47B007A007900228F1A050DE50DAE0C7002050C14F5828E83E51AF0120036050DE50DAC0C7002050C14F5828C83EFF015BA
-:400F860008E508600A12133F8F1AEF423680CA228F1A050DE50DAE0C7002050C14F5828E83E51AF0121357050DE50DAC0C7002050C14F5828C83EFF01508E508600A1213AA
-:400FC600938F1AEF423780CA22E4907F93F0907F9C7430F0E4907F96F0907F95F0907F9E7427F0907F987420F0907F9E7407F0E4907F94F0907F9D74FFF0E4907F97F0227C
-:40100600C0E0C083C082C085C084C086758600D2115391EF907FAB7401F0D086D084D085D082D083D0E032C0E0C083C082C085C084C086758600D2185391EF907FAB74087E
-:40104600F0D086D084D085D082D083D0E032907F987413F090C00074BFF0907F987410F090C000EFF0907F987413F0E544547F90C000F022907F987413F090C00074BFF00C
-:40108600907F987411F090C000EFF0907F987413F0E544547F90C000F022907F987413F090C00074BFF0907F987412F090C000EFF0907F987413F0E544547F90C000F0220A
-:4010C600907F987413F090C00074BFF0907F987414F090C000EFF0907F987413F0E544547F90C000F022907F987413F090C00074BFF0907F987416F090C000EFF0907F9807
-:401106007413F0E544547F90C000F022907F98740BF090C00074BFF0907F98740AF090C000EFF0907F98740BF0E545547F90C000F022907F98740BF090C00074BFF0907FFA
-:40114600987408F090C000EFF0907F98740BF0E545547F90C000F022907F98740BF090C00074BFF0907F987409F090C000EFF0907F98740BF0E545547F90C000F022907F71
-:4011860098740BF090C00074BFF0907F98740CF090C000EFF0907F98740BF0E545547F90C000F022907F98740BF090C00074BFF0907F98740EF090C000EFF0907F98740BFD
-:4011C600F0E545547F90C000F022907F987413F0E544547F90C000F0907F987417F090C000EFF0907F987415F090C000EDF0221213278F1A1213278F1BE51A651B60121292
-:4012060013278F1AE51A651B60071213278F1B80E8AF1A22907F98740BF0E545547F90C000F0907F98740FF090C000EFF0907F98740DF090C000EDF02212137B8F1A121325
-:401246007B8F1BE51A651B601212137B8F1AE51A651B600712137B8F1B80E8AF1A22907FD6E054FBF0E04408F0301A04E04402F07FF47E011212E7907FD6E054F7F0E044E1
-:4012860004F022AE07E4FFE53E547FFD1211D0907F987411F090C000EEF0E4E53E4480FD1211D022AE07E4FFE53F547FFD12121A907F987409F090C000EEF0E4E53F448095
-:4012C600FD12121A22050E02000000000314030000C111C118C195C110C116010A00C19B008E188F19E5191519AE18700215184E6005120D6080EE2200000210060002137E
-:4013060004000200030002102D907F987411F090C000E0FF22907F987412F090C000E0FF22907F987413F090C000E0FF22907F987414F090C000E0FF22907F987415F090F5
-:40134600C000E0FF22907F987416F090C000E0FF22907F987408F090C000E0FF22907F987409F090C000E0FF22907F98740AF090C000E0FF22907F98740BF090C000E0FFC0
-:4013860022907F98740CF090C000E0FF22907F98740DF090C000E0FF22907F98740EF090C000E0FF22120FCF120D71120B4A220000000000000000000000000000000000C1
-:4013C60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E7
-:4014060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A6
-:401446000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000066
-:401486000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000026
-:4014C60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E6
-:4015060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A5
-:401546000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000065
-:401586000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000025
-:4015C60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E5
-:4016060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A4
-:401646000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000064
-:401686000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024
-:4016C60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E4
-:4017060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A3
-:401746000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000063
-:401786000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000023
-:4017C60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E3
-:4018060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A2
-:401846000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000062
-:401886000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000022
-:4018C6000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012011001FF00BF
-:401906000040CD06100100000102000209027400010100A032090400000EFF0000000705010240000007050202400000070503024000000705040240000007050502400076
-:4019460000070506024000000705070240000007058102400001070582024000000705830240000107058402400001070585024000010705860240000107058702400001F4
-:401986000403090448034B00650079007300700061006E002C002000610020006400690076006900730069006F006E0020006F006600200049006E006E006F005300790040
-:4019C6007300200049006E0063002E0036034B00650079007300700061006E0020005500530042002000530065007200690061006C002000410064006100700074006500F9
-:041A0600720000006A
-:00000001FF
-
-	The firmware contained herein is
-
-		Copyright (C) 1999-2001
-		Keyspan, A division of InnoSys Incorporated ("Keyspan")
-
-	as an unpublished work. This notice does not imply unrestricted or
-	public access to the source code from which this firmware image is
-	derived.  Except as noted below this firmware image may not be
-	reproduced, used, sold or transferred to any third party without
-	Keyspan's prior written consent.  All Rights Reserved.
-
-	Permission is hereby granted for the distribution of this firmware
-	image as part of a Linux or other Open Source operating system kernel
-	in text or binary form as required.
-
-	This firmware may not be modified and may only be used with
-	Keyspan hardware.  Distribution and/or Modification of the
-	keyspan.c driver which includes this firmware, in whole or in
-	part, requires the inclusion of this statement."
--- zfcpdump-kernel-4.4.orig/firmware/keyspan/usa49w.HEX
+++ /dev/null
@@ -1,145 +0,0 @@
-:030033000218FBB5
-:0C0036009078417401F090C000E0FF22BF
-:10004600E4FF74402FF582E4347BF583E0FEE5158A
-:100056002404FDE43514FAA9057B01EF7C0029F997
-:10006600EC3AFAEE1211F10FBF22D7E5152405F589
-:1000760082E43514F583E07003020134E5152409A2
-:10008600F582E43514F583E0700EE515240AF58251
-:10009600E43514F583E060187F01E4FD121647E5A8
-:1000A600152431F582E43514F583E054CFF0804110
-:1000B600E5152406F582E43514F583E0FF1216767D
-:1000C600E5152407F582E43514F583E0FF120003F5
-:1000D6007F01E5152408F582E43514F583E0FD1269
-:1000E6001647E5152431F582E43514F583E04430EE
-:1000F600F0E5152439F582E43514F583E04480F003
-:100003009078417403F090C00074BFF0907841740D
-:1000130001F090C000EFF09078417403F0E51524EF
-:1000230037F582E43514F583E0547F90C000F02265
-:03004300021B009D
-:0300000002109556
-:400106009078417404F0E5152439F582E43514F583E090C000F09078417402F0E5152436F582E43514F583E0440690C000F0E515240BF582E43514F583E06032E515240C0B
-:40014600F582E43514F583E0543FFFE5152437F582E43514F583EFF09078417403F0E5152437F582E43514F583E090C000F0E515240DF582E43514F583E0700302024FE588
-:40018600152417F582E43514F583E06011E5152432F582E43514F583E04404F0800FE5152432F582E43514F583E054FBF0E4FFE5152432F582E43514F583E0FD121647E55E
-:4001C60015240EF582E43514F583E06011E5152433F582E43514F583E04480F0800FE5152433F582E43514F583E0547FF0E5152433F582E43514F583E054FCF0E515240FEB
-:40020600F582E43514F583E0602FE5152433F582E43514F583E04402F0E5152410F582E43514F583E0FF1215E7E5152411F582E43514F583E0FF121617E5152433F582E45E
-:400246003514F583E0FF1215B7E5152414F582E43514F583E06044E5152415F582E43514F583E06011E5152439F582E43514F583E04401F0800FE5152439F582E43514F581
-:4002860083E054FEF09078417404F0E5152439F582E43514F583E090C000F0E5152412F582E43514F583E06044E5152413F582E43514F583E06011E5152439F582E43514E6
-:4002C600F583E04402F0800FE5152439F582E43514F583E054FDF09078417404F0E5152439F582E43514F583E090C000F0E5152416F582E43514F583E0FFE5152435F5820A
-:40030600E43514F583EFF0E5152417F582E43514F583E030E011E5152431F582E43514F583E04440F0800FE5152431F582E43514F583E054BFF0E5152418F582E43514F576
-:4003460083E0FFE515243BF582E43514F583EFF0E5152419F582E43514F583E06011E5152439F582E43514F583E04410F0800FE5152439F582E43514F583E054EFF0907869
-:40038600417404F0E5152439F582E43514F583E090C000F0E515241AF582E43514F583E0606BE5152437F582E43514F583E054BFF09078417403F0E5152437F582E43514FF
-:4003C600F583E0547F90C000F09078417401F0120036EF54FE90C000F0E5152432F582E43514F583E054FDFFF0FDE4FF121647E515242CF582E43514F583E4F0E515242BB7
-:40040600F582E43514F583E4F0E5164213E515241BF582E43514F583E0700EE5152425F582E43514F583E06028E5152432F582E43514F583E04402FFF0FDE4FF121647E547
-:4004460015242BF582E43514F5837401F0E5164213E515241CF582E43514F583E0FF700EE5152425F582E43514F583E0602A9078417402F0E5152436F582E43514F583E0C6
-:40048600440490C000F0EF600FE5152431F582E43514F583E04404F0E515241DF582E43514F583E06027E5152437F582E43514F583E04440F09078417403F0E5152437F550
-:4004C60082E43514F583E0547F90C000F0E515241EF582E43514F583E06028E5152432F582E43514F583E054FEFFF0FDE4FF121647E515242DF582E43514F5837401F0E58F
-:40050600164213E515241FF582E43514F583E0700EE5152425F582E43514F583E06027E5152432F582E43514F583E04401FFF0FDE4FF121647E515242DF582E43514F58397
-:40054600E4F0E5164213E5152420F582E43514F583E0700EE5152425F582E43514F583E060189078417402F0E5152436F582E43514F583E0440290C000F0E5152421F582A7
-:40058600E43514F583E0600FE5152431F582E43514F583E04402F0E5152422F582E43514F583E0601FE515242EF582E43514F5837401F0E515243AF582E43514F583E4F0F0
-:4005C600E5164213E5152423F582E43514F583E06003121885E5152424F582E43514F583E0601BE5152431F582E43514F583E04408F0907F98E0FFE516F4FEEF5EF0E5156C
-:400606002425F582E43514F583E06016E5152431F582E43514F583E054F7F0907F98E04516F022907FE9E012120307830007F701086303064C0607740807680907500A07CE
-:400646005F0B000008B2907FEBE024FE601C1470030206FE240260030207467419907FD4F07400907FD5F00208B9907FEAE004758217758319F0907FEAE030E0047F03802D
-:40068600027F02758282758319EFF075826D758319F0758266758319F075825F758319F0758258758319F0907FEAE030E1047F6480027F3275821A758319EFF0907FEFE0FB
-:4006C600FE907FEEE07C002400F519EC3EF518753319753412758214758319E0752700F528D3E5289519E527951840068518278519281213120208B9907FEAE0FF12142BC9
-:40070600EA496032907FEEE0751800F519AE02AF018E338F348F828E83E0FEA3E08E27F528D39519E527951840068518278519281213120208B9907FB4E04401F00208B99E
-:40074600907FB4E04401F00208B9907F00E525F0907FB57401F00208B9907FEAE0F5250208B9907FEAE0F522120AB80208B9907F00E522F0907FB57401F00208B9907FE8BD
-:40078600E0247F60241460312402705BA200E433FF25E0FFA206E4334F907F00F0E4A3F0907FB57402F00208B9E4907F00F0A3F0907FB57402F00208B9907FECE0F4548063
-:4007C600FFC4540FFFE054072F25E024B4F582E4347FF583E054FD907F00F0E4A3F0907FB57402F00208B9907FB4E04401F00208B9907FE8E024FE601D240260030208B910
-:40080600907FEAE0B40105C2000208B9907FB4E04401F00208B9907FEAE07038907FECE0F45480FFC4540FFFE054072F25E024B4F582E4347FF583E4F0907FECE05480FF67
-:40084600131313541FFFE054072F907FD7F0E04420F0805F907FB4E04401F08056907FE8E024FE60182402704A907FEAE0B40104D200803F907FB4E04401F08036907FEACB
-:40088600E07020907FECE0F45480FFC4540FFFE054072F25E024B4F582E4347FF5837401F08010907FB4E04401F08007907FB4E04401F0907FB4E04402F022E511540F703D
-:4008C600030209B21216A5EF20E175121703EF14F5191218CCEF2519FFE433FEC3EF9480EE648094805059851582851483E0FEA3E0FFF5828E83E030E011E5152431F58250
-:40090600E43514F583E04480F0800FE5152431F582E43514F583E0547FF0E5152431F582E43514F583E020E212E519600EF523EF2401F52DE43EF52C1214ADE4FF1214E3C0
-:40094600E5152431F582E43514F583E030E75D1218CCE515243BF582E43514F583E0FEEFC39E5048E515242FF582E43514F5837401F0E5152431F582E43514F583E0547B99
-:40098600F0E515243AF582E43514F583E4F0E5164213907FC2E030E110E5152426F582E43514F583E0F52480031212A11216D4EF30E103020AB71217D28F191218D8E515D5
-:4009C6002438F582E43514F583EFF0E5152435F582E43514F583E0FFE519C39F50281218B4EF30E021E5152438F582E43514F583E020E712E5152431F582E43514F583E0C0
-:400A060020E103020AB7E5152431F582E43514F583E054FDF0E5197003020AB7B4800FE5152438F582E43514F583E04402F0E5152438F582E43514F583E0FF30E729E519CF
-:400A4600D394204003751920851923851582851483A3A3E0FCA3E08C2CF52D1213DDE51925E0FF12151922E519D3943F400375193F851923E5152438F582E43514F583E053
-:400A8600FF851582851483A3A3E0FCA3E0F5828C83EFF0851582851483A3A3E0FEA3E02401F52DE43EF52C12146CE51904FF12151922E4907F93F0907F9C74F0F0907F9677
-:400AC600F0E4907F94F090784A04F0F58E907F9574C0F0907F9E743FF0907F98741FF090784374FFF0E4907841F0907FDF749FF0907FDEF0907F92E04402F07E7B7FC07581
-:400B0600147B7515C0907F9674EFF0751601120F127E7B7FC075147B7515C0907F9674EFF0751601E5152426F582E43514F583E4F07E7E7F40851582851483747EF0A374F5
-:400B460040F07E7E7F80851582851483A3A3747EF0A37480F07E7C7F0075147C751500907F9674DFF0751602120F127E7C7F0075147C751500907F9674DFF0751602E51536
-:400B86002426F582E43514F5837401F07E7D7FC0851582851483747DF0A374C0F07E7E7F00851582851483A3A3747EF0A37400F07E7C7F4075147C751540907F9674BFF018
-:400BC600751604120F127E7C7F4075147C751540907F9674BFF0751604E5152426F582E43514F5837402F07E7D7F40851582851483747DF0A37440F07E7D7F8085158285D3
-:400C06001483A3A3747DF0A37480F07E7C7F8075147C751580907F96747FF0751608120F127E7C7F8075147C751580907F96747FF0751608E5152426F582E43514F583741C
-:400C460003F07E7C7FC0851582851483747CF0A374C0F07E7D7F00851582851483A3A3747DF0A37400F0C20AC209D20222E510045403F51014601F1460311460432403701B
-:400C8600527E7B7FC075147B7515C0907F9674EFF0751601803D7E7C7F0075147C751500907F9674DFF075160280287E7C7F4075147C751540907F9674BFF075160480137E
-:400CC6007E7C7F8075147C751580907F96747FF0751608E53255167003020E11E516F4FF5232E526547FFE700FE52A55166024907F98E04516F0801BBE2018E5152431F543
-:400D060082E43514F583E030E309E4F52A907F98E05FF0E515243AF582E43514F583E06003E014F0E5152434F582E43514F583E06003E014F0E06003020E11740AF012009D
-:400D460036EF5401FFF519E515242CF582E43514F583E06F6007E519F0E51642131218E48F19E5152427F582E43514F583E0FFE5195410FE6F6006EEF0E5164213E5152415
-:400D860028F582E43514F583E0FFE5195480FE6F6006EEF0E5164213E5152429F582E43514F583E0FFE5195420FE6F6015EEF0E5152431F582E43514F583E030E404E51665
-:400DC6004213E5125516FFF519E515242AF582E43514F583E06F6016E519F0E5152431F582E43514F583E030E504E5164213E5175516FFF519E5152430F582E43514F58380
-:400E0600E06F6007E519F0E516421322300903020F11E52414602A14604114605814606F24046003020ECF7E7B7FC075147B7515C0907F9674EFF07516011212A17524015A
-:400E4600227E7C7F0075147C751500907F9674DFF07516021212A1752402227E7C7F4075147C751540907F9674BFF07516041212A1752403227E7C7F8075147C7515809051
-:400E86007F96747FF07516081212A175240422300433C2045313DFE4F5197E007B00742E2519F9EE3400FA1211ABFF74802519F582E4347BF583EFF00519E519B403DB902D
-:400EC6007FC37403F075240522E536603BD5360A5313EF300A04D209C20AE4F5197E007B0074352519F9EE3400FA1211ABFF74802519F582E4347BF583EFF00519E519B467
-:400F060003DB907FC37403F0E4F52422E4F51A7E007B01E515251AF9EE3514FAE41211F1051AE51AB43CE8E5152435F582E43514F5837401F09078417403F0E5152437F569
-:400F460082E43514F5837403F090C000F07F0CE4FD1216477F10E5152433F582E43514F583EFF01215B79078417402F07F01E5152436F582E43514F583EFF0440690C000F1
-:400F8600F09078417404F0E5152439F582E43514F5837480F090C000F00FE4FD121647E4FF7EA3E5152432F582E43514F583EEF0FD1216479078417401F090C000E4F07F89
-:400FC600057D7F1216477F0112154F7F037D071216472253133F907BF1E030E3167E7B7FC075147B7515C0907F9674EFF07516011208C1907C31E030E3167E7C7F00751417
-:401006007C751500907F9674DFF07516021208C1907C71E030E3167E7C7F4075147C751540907F9674BFF07516041208C1907CB1E030E3167E7C7F8075147C751580907F37
-:4010460096747FF07516081208C10511E511540FF518701F907841E054F7F0907F99E0F517907841E04408F0907F99E0F4F51212112122E518B40104120C7322907FC2E018
-:4010860020E108E5136004120E1222120C7322787FE4F6D8FD7581370210DC021229E493A3F8E493A34003F68001F208DFF48029E493A3F85407240CC8C333C4540F44207E
-:4010C600C8834004F456800146F6DFE4800B0102040810204080901850E47E019360BCA3FF543F30E509541FFEE493A360010ECF54C025E060A840B8E493A3FAE493A3F8A2
-:40110600E493A3C8C582C8CAC583CAF0A3C8C582C8CAC583CADFE9DEE780BE907FD2E030E1030211AAC209907B40E014602614603B14605024836064248070637E7B7FC01C
-:4011460075147B7515C0907F9674EFF0751601120046804B7E7C7F0075147C751500907F9674DFF075160212004680337E7C7F4075147C751540907F9674BFF075160412FB
-:401186000046801B7E7C7F8075147C751580907F96747FF0751608120046800312175CE4907FD3F022BB010689828A83E0225002E722BBFE02E32289828A83E49322BB0189
-:4011C6000CE58229F582E5833AF583E0225006E92582F8E622BBFE06E92582F8E222E58229F582E5833AF583E49322BB010689828A83F0225002F722BBFE01F322D083D086
-:4012060082F8E4937012740193700DA3A393F8740193F5828883E4737402936860EFA3A3A380DF907FAEE0FFD39200E433FEEF4EF0D2E843D820907FDE7401F0907FDFF08E
-:40124600907FAB74FFF0907FA9F0907FAAF05391EF907FAF7401F0907FAE740DF0D2AFD20B121814C201E4F52BF531C207C2027529F0907FD8E06526600675320FE0F526C9
-:40128600300203120FD9300107C20112062980E23008DFC20812183580D822E5135516606AE515243AF582E43514F583E0705CE516F45213E5152426FFE43514FEE4FD0FA2
-:4012C600EFAA0670010E14F5828A83E0FC74802DF582E4347BF583ECF00DBD0BE2907FC3740BF0E515243AF582E43514F5837410F0E515242EF582E43514F583E4F0E515C1
-:40130600242FF582E43514F583E4F022E52845276057AE27AF28D3EF9440EE940040047E007F40C3E5289FF528E5279EF527E4FDEDC39FE49E501F853482853383E0FC7494
-:40134600002DF582E4347FF583ECF00D0534E5347002053380DA907FA97401F0907FACE04401F0907FB5EFF022907FACE054FEF0E4907FB5F022E4907F93F0907F9C74F0A7
-:40138600F0907F96F0E490784AF0907F94F0907F9D74FFF0E4907F97F0300007E52954F0FF80027F00EF4408907841F0E4907F98F0907F95F0907F9E74FFF0E4907F98F0C9
-:4013C600907F93F0907F9C74F0F0E4907F96F0907F92E054FDF0228F1A052DE52DAE2C7002052C14F5828E83E51AF01218F0052DE52DAC2C7002052C14F5828C83EFF0159D
-:4014060023E523601FE5152438F582E43514F583C083C082E0FE1218D88F1AEE4FD082D083F080B5228F1AE4F51B751CFF751D19751E86AB1CAA1DA91E9000011211C4B4E1
-:40144600031DAF1B051BEFB51A01221211AB7E0029FFEE3AA907751CFFF51D891E80D47B007A00790022E4907841F090784F74C0F0E4907850F0E52C907851F0AE2CE52DF8
-:40148600907852F0907854E523F09078577404F0907FE2E04410F0E054F7F0E4907855F0907855E060FA22E4907841F0E52C90784FF0AE2CE52D907850F090785174C0F081
-:4014C600E4907852F0907854E523F09078577404F0E4907855F0907855E060FA22E5152404F582E43514F583E014600F1460131460178000907FC7EFF08013907FC9EFF081
-:40150600800C907FCBEFF08005907FCDEFF0E516422A22E5152404F582E43514F583E014600F1460131460178000907FB7EFF08013907FB9EFF0800C907FBBEFF08005903B
-:401546007FBDEFF0E516422A22AE07E4FFE5152432F582E43514F583E0547FFD1216479078417401F090C000EEF0E4E5152432F582E43514F583E04480FD12164722C0E0A0
-:40158600C0F0C083C082C085C084C086758600C0D075D0085391EF907FA97401F0121312D0D0D086D084D085D082D083D0F0D0E0329078417403F090C00074BFF0907841D0
-:4015C6007402F090C000EFF09078417403F0E5152437F582E43514F583E0547F90C000F0229078417403F090C00074BFF09078417404F090C000EFF09078417403F0E5156D
-:401606002437F582E43514F583E0547F90C000F0229078417403F090C00074BFF09078417406F090C000EFF09078417403F0E5152437F582E43514F583E0547F90C000F0FF
-:40164600229078417403F0E5152437F582E43514F583E0547F90C000F09078417407F090C000EFF09078417405F090C000EDF0229078417403F090C00074BFF0E4907841FA
-:40168600F090C000EFF09078417403F0E5152437F582E43514F583E0547F90C000F022E5152404F582E43514F583E014600E1460111460148000907FC6E0FF22907FC8E015
-:4016C600FF22907FCAE0FF22907FCCE0FF22E5152404F582E43514F583E014600E1460111460148000907FB6E0FF22907FB8E0FF22907FBAE0FF22907FBCE0FF22E515249E
-:4017060004F582E43514F583E014600E1460111460148000907FC7E0FF22907FC9E0FF22907FCBE0FF22907FCDE0FF22C0E0C083C082C085C084C086758600907FC4E4F096
-:401746005391EF907FAB7404F0D086D084D085D082D083D0E032907B41E0F536431310A3E06009907FD77417F07437F0907B43E0F537A3E054F0F529E06002D20A22C0E024
-:40178600C083C082C085C084C086758600D2015391EF907FAB7401F0D086D084D085D082D083D0E032C0E0C083C082C085C084C086758600D2085391EF907FAB7408F0D0F7
-:4017C60086D084D085D082D083D0E0321218C0AE071218C0AD07EE6D60101218C0AE07EE6D60071218C0AD0780ECAF06227400F58690FDA57C05A3E582458370F922907FD5
-:40180600D6E04480F0438701000000000022907FD6E04404F0E04408F0300B04E04402F07FF47E0112186B907FD6E054F7F02212137C121804907FD6E030E70A7F057E007D
-:4018460012186B12189E120AB8220335800000032E810000C185C181C108C100C106012200012400008E188F19E5191519AE18700215184E60081217F31217F380EB22E545
-:40188600152404F582E43514F583E004FF4410907FD7F0EF4430F022907FD6E04401F07F0D7E0012186B907FD6E054FEF0229078417402F090C000E0FF229078417403F0D5
-:4018C60090C000E0FF229078417404F090C000E0FF229078417405F090C000E0FF229078417406F090C000E0FF22E4907841F090C000E0FF2253D8EF320012011001FF00AB
-:401906000040CD060A0100000102000409027400010100A032090400000EFF000000070501024000000705020240000007050302400000070504024000000705050240007A
-:4019460000070506024000000705070240000007058102400001070582024000010705830240000107058402400001070585024000010705860240000107058702400001F3
-:401986000403090448034B00650079007300700061006E002C002000610020006400690076006900730069006F006E0020006F006600200049006E006E006F005300790040
-:4019C6007300200049006E0063002E003603550053004200200034002D0070006F00720074002000530065007200690061006C00200041006400610070007400650072003C
-:401A060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A0
-:401A46000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000060
-:401A86000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020
-:401AC6000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002178400021B26
-:151B06000400021732000217AB00021B1000021B1400021584BE
-:00000001FF
-
-	The firmware contained herein is
-
-		Copyright (C) 1999-2001
-		Keyspan, A division of InnoSys Incorporated ("Keyspan")
-
-	as an unpublished work. This notice does not imply unrestricted or
-	public access to the source code from which this firmware image is
-	derived.  Except as noted below this firmware image may not be
-	reproduced, used, sold or transferred to any third party without
-	Keyspan's prior written consent.  All Rights Reserved.
-
-	Permission is hereby granted for the distribution of this firmware
-	image as part of a Linux or other Open Source operating system kernel
-	in text or binary form as required.
-
-	This firmware may not be modified and may only be used with
-	Keyspan hardware.  Distribution and/or Modification of the
-	keyspan.c driver which includes this firmware, in whole or in
-	part, requires the inclusion of this statement."
--- zfcpdump-kernel-4.4.orig/firmware/keyspan/usa49wlc.HEX
+++ /dev/null
@@ -1,153 +0,0 @@
-:017F920001ED
-:030033000218FBB5
-:0D003600E51104907841F090C000E0FF2239
-:10004600E4FF74402FF582E4347BF583E0FEE5158A
-:100056002404FDE43514FAA9057B01EF7C0029F997
-:10006600EC3AFAEE1211EC0FBF22D7E5152405F58E
-:1000760082E43514F583E07003020134E5152409A2
-:10008600F582E43514F583E0700EE515240AF58251
-:10009600E43514F583E060187F01E4FD12166BE584
-:1000A600152431F582E43514F583E054CFF0804110
-:1000B600E5152406F582E43514F583E0FF12000306
-:1000C600E5152407F582E43514F583E0FF1215AB38
-:1000D6007F01E5152408F582E43514F583E0FD1269
-:1000E600166BE5152431F582E43514F583E04430CA
-:1000F600F0E5152439F582E43514F583E04480F003
-:1000030090784174F3F090C00074BFF0907841741D
-:10001300F0F090C000EFF090784174F3F0E5152410
-:1000230037F582E43514F583E0547F90C000F02265
-:03004300021B009D
-:030000000210905B
-:4001060090784174F4F0E5152439F582E43514F583E090C000F090784174F2F0E5152436F582E43514F583E0440690C000F0E515240BF582E43514F583E06032E515240C2B
-:40014600F582E43514F583E0543FFFE5152437F582E43514F583EFF090784174F3F0E5152437F582E43514F583E090C000F0E515240DF582E43514F583E0700302024FE598
-:40018600152417F582E43514F583E06011E5152432F582E43514F583E04404F0800FE5152432F582E43514F583E054FBF0E4FFE5152432F582E43514F583E0FD12166BE53A
-:4001C60015240EF582E43514F583E06011E5152433F582E43514F583E04480F0800FE5152433F582E43514F583E0547FF0E5152433F582E43514F583E054FCF0E515240FEB
-:40020600F582E43514F583E0602FE5152433F582E43514F583E04402F0E5152410F582E43514F583E0FF12160BE5152411F582E43514F583E0FF12163BE5152433F582E415
-:400246003514F583E0FF1215DBE5152414F582E43514F583E06044E5152415F582E43514F583E06011E5152439F582E43514F583E04401F0800FE5152439F582E43514F55D
-:4002860083E054FEF090784174F4F0E5152439F582E43514F583E090C000F0E5152412F582E43514F583E06044E5152413F582E43514F583E06011E5152439F582E43514F6
-:4002C600F583E04402F0800FE5152439F582E43514F583E054FDF090784174F4F0E5152439F582E43514F583E090C000F0E5152416F582E43514F583E0FFE5152435F5821A
-:40030600E43514F583EFF0E5152417F582E43514F583E030E011E5152431F582E43514F583E04440F0800FE5152431F582E43514F583E054BFF0E5152418F582E43514F576
-:4003460083E0FFE515243BF582E43514F583EFF0E5152419F582E43514F583E06011E5152439F582E43514F583E04410F0800FE5152439F582E43514F583E054EFF0907869
-:400386004174F4F0E5152439F582E43514F583E090C000F0E515241AF582E43514F583E0606BE5152437F582E43514F583E054BFF090784174F3F0E5152437F582E435141F
-:4003C600F583E0547F90C000F090784174F1F0120036EF54FE90C000F0E5152432F582E43514F583E054FDFFF0FDE4FF12166BE515242CF582E43514F583E4F0E515242BA3
-:40040600F582E43514F583E4F0E5164213E515241BF582E43514F583E0700EE5152425F582E43514F583E06028E5152432F582E43514F583E04402FFF0FDE4FF12166BE523
-:4004460015242BF582E43514F5837401F0E5164213E515241CF582E43514F583E0FF700EE5152425F582E43514F583E0602A90784174F2F0E5152436F582E43514F583E0D6
-:40048600440490C000F0EF600FE5152431F582E43514F583E04404F0E515241DF582E43514F583E06027E5152437F582E43514F583E04440F090784174F3F0E5152437F560
-:4004C60082E43514F583E0547F90C000F0E515241EF582E43514F583E06028E5152432F582E43514F583E054FEFFF0FDE4FF12166BE515242DF582E43514F5837401F0E56B
-:40050600164213E515241FF582E43514F583E0700EE5152425F582E43514F583E06027E5152432F582E43514F583E04401FFF0FDE4FF12166BE515242DF582E43514F58373
-:40054600E4F0E5164213E5152420F582E43514F583E0700EE5152425F582E43514F583E0601890784174F2F0E5152436F582E43514F583E0440290C000F0E5152421F582B7
-:40058600E43514F583E0600FE5152431F582E43514F583E04402F0E5152422F582E43514F583E0601FE515242EF582E43514F5837401F0E515243AF582E43514F583E4F0F0
-:4005C600E5164213E5152423F582E43514F583E0600312187AE5152424F582E43514F583E06023E5152431F582E43514F583E04408F0E516C454F0FF4211907F96E04FF000
-:40060600907841E04FF0E5152425F582E43514F583E06024E5152431F582E43514F583E054F7F0E516C454F0F4FF5211907F96E05FF0907841E05FF022907FE9E01211FE43
-:40064600079900080D01087903066206078A08077E0907660A07750B000008C8907FEBE024FE601C1470030207142402600302075C7419907FD4F07400907FD5F00208CF4C
-:40068600907FEAE004758217758319F0907FEAE030E0047F0280027F03758282758319EFF075826D758319F0758266758319F075825F758319F0758258758319F0907FEA0A
-:4006C600E030E1047F6480027F3275821A758319EFF0907FEFE0FE907FEEE07C002400F518EC3EF517753319753412758214758319E0752700F528D3E5289518E5279517D6
-:40070600400685172785182812130D0208CF907FEAE0FF12145FEA496032907FEEE0751700F518AE02AF018E338F348F828E83E0FEA3E08E27F528D39518E527951740068B
-:4007460085172785182812130D0208CF907FB4E04401F00208CF907FB4E04401F00208CF907F00E525F0907FB57401F00208CF907FEAE0F5250208CF907FEAE0F522120A9B
-:40078600CE0208CF907F00E522F0907FB57401F00208CF907FE8E0247F60241460312402705BA200E433FF25E0FFA206E4334F907F00F0E4A3F0907FB57402F00208CFE4C9
-:4007C600907F00F0A3F0907FB57402F00208CF907FECE0F45480FFC4540FFFE054072F25E024B4F582E4347FF583E054FD907F00F0E4A3F0907FB57402F00208CF907FB45C
-:40080600E04401F00208CF907FE8E024FE601D240260030208CF907FEAE0B40105C2000208CF907FB4E04401F00208CF907FEAE07038907FECE0F45480FFC4540FFFE05490
-:40084600072F25E024B4F582E4347FF583E4F0907FECE05480FF131313541FFFE054072F907FD7F0E04420F0805F907FB4E04401F08056907FE8E024FE60182402704A90CA
-:400886007FEAE0B40104D200803F907FB4E04401F08036907FEAE07020907FECE0F45480FFC4540FFFE054072F25E024B4F582E4347FF5837401F08010907FB4E04401F046
-:4008C6008007907FB4E04401F0907FB4E04402F022E512540F70030209C812169AEF20E1751216F8EF14F5181218C5EF2518FFE433FEC3EF9480EE64809480505985158201
-:40090600851483E0FEA3E0FFF5828E83E030E011E5152431F582E43514F583E04480F0800FE5152431F582E43514F583E0547FF0E5152431F582E43514F583E020E212E5CC
-:4009460018600EF523EF2401F52DE43EF52C1214A0E4FF1214D7E5152431F582E43514F583E030E75D1218C5E515243BF582E43514F583E0FEEFC39E5048E515242FF58207
-:40098600E43514F5837401F0E5152431F582E43514F583E0547BF0E515243AF582E43514F583E4F0E5164213907FC2E030E110E5152426F582E43514F583E0F524800312C5
-:4009C600129C1216C9EF30E103020ACD1217C78F181218D3E5152438F582E43514F583EFF0E5152435F582E43514F583E0FFE518C39F50281218A9EF30E021E5152438F52E
-:400A060082E43514F583E020E712E5152431F582E43514F583E020E103020ACDE5152431F582E43514F583E054FDF0E5187003020ACDB4800FE5152438F582E43514F583DE
-:400A4600E04402F0E5152438F582E43514F583E0FF30E729E518D394204003751820851823851582851483A3A3E0FCA3E08C2CF52D1213CFE51825E0FF12150D22E518D3C3
-:400A8600943F400375183F851823E5152438F582E43514F583E0FF851582851483A3A3E0FCA3E0F5828C83EFF0851582851483A3A3E0FEA3E02401F52DE43EF52C12141D4F
-:400AC600E51804FF12150D22E4907F93F0907F9C74FFF0E4907F96F0907F94F090784A04F0F58E907F9574C0F0907F9E743FF0907F98742FF090784374F7F0E4907841F02C
-:400B0600907FDF749FF0907FDEF0907F92E04402F07E7B7FC075147B7515C0907F98742EF0751601120F287E7B7FC075147B7515C0907F98742EF0751601E5152426F58290
-:400B4600E43514F583E4F07E7E7F40851582851483747EF0A37440F07E7E7F80851582851483A3A3747EF0A37480F07E7C7F0075147C751500907F98742DF0751602120F0A
-:400B8600287E7C7F0075147C751500907F98742DF0751602E5152426F582E43514F5837401F07E7D7FC0851582851483747DF0A374C0F07E7E7F00851582851483A3A374EE
-:400BC6007EF0A37400F07E7C7F4075147C751540907F98742BF0751604120F287E7C7F4075147C751540907F98742BF0751604E5152426F582E43514F5837402F07E7D7F57
-:400C060040851582851483747DF0A37440F07E7D7F80851582851483A3A3747DF0A37480F07E7C7F8075147C751580907F987427F0751608120F287E7C7F8075147C751590
-:400C460080907F987427F0751608E5152426F582E43514F5837403F07E7C7FC0851582851483747CF0A374C0F07E7D7F00851582851483A3A3747DF0A37400F0C20AC209D3
-:400C8600E4F511D20222E510045403F51014601F146031146043240370527E7B7FC075147B7515C0907F98742EF0751601803D7E7C7F0075147C751500907F98742DF07564
-:400CC600160280287E7C7F4075147C751540907F98742BF075160480137E7C7F8075147C751580907F987427F0751608E53255167003020E27E516F45232E526547FFF7095
-:400D060017E52A55166034907F96E0FEE516C454F0F4FDEE5DF08023BF2020E5152431F582E43514F583E030E311E4F52A907F96E0FFE516C454F0FEEF4EF0E515243AF5C3
-:400D460082E43514F583E06003E014F0E5152434F582E43514F583E06003E014F0E06003020E27740AF0120036EF5401FFF518E515242CF582E43514F583E06F6007E518F1
-:400D8600F0E51642131218E18F18E5152427F582E43514F583E0FFE5185410FE6F6006EEF0E5164213E5152428F582E43514F583E0FFE5185480FE6F6006EEF0E516421386
-:400DC600E5152429F582E43514F583E0FFE5185420FE6F6015EEF0E5152431F582E43514F583E030E404E5164213E515242AF582E43514F583E0FFE5185440FE6F6015EE23
-:400E0600F0E5152431F582E43514F583E030E504E5164213E5152430F582E43514F583E4F022300903020F27E52414602A14604114605814606F24046003020EE57E7B7F31
-:400E4600C075147B7515C0907F98742EF075160112129C752401227E7C7F0075147C751500907F98742DF075160212129C752402227E7C7F4075147C751540907F98742B05
-:400E8600F075160412129C752403227E7C7F8075147C751580907F987427F075160812129C75240422300433C2045313DFE4F5187E007B00742E2518F9EE3400FA1211A6CA
-:400EC600FF74802518F582E4347BF583EFF00518E518B403DB907FC37403F075240522E536603BD5360A5313EF300A04D209C20AE4F5187E007B0074352518F9EE3400FACC
-:400F06001211A6FF74802518F582E4347BF583EFF00518E518B403DB907FC37403F0E4F52422E4F5197E007B01E5152519F9EE3514FAE41211EC0519E519B43CE8E51524FA
-:400F460035F582E43514F5837401F090784174F3F0E5152437F582E43514F5837403F090C000F07F0CE4FD12166B7F10E5152433F582E43514F583EFF01215DB9078417464
-:400F8600F2F07F01E5152436F582E43514F583EFF0440690C000F090784174F4F0E5152439F582E43514F5837480F090C000F00FE4FD12166BE4FF7EA3E5152432F582E486
-:400FC6003514F583EEF0FD12166B90784174F1F090C000E4F07F057D7F12166B7F011215437F037D0712166B2253133F907BF1E030E3167E7B7FC075147B7515C0907F986B
-:40100600742EF07516011208D7907C31E030E3167E7C7F0075147C751500907F98742DF07516021208D7907C71E030E3167E7C7F4075147C751540907F98742BF0751604C4
-:401046001208D7907CB1E030E3167E7C7F8075147C751580907F987427F07516081208D70512E512540FF517700412111C22E517B40104120C8C22907FC2E020E108E51370
-:401086006004120E2822120C8C22787FE4F6D8FD7581370210D7021224E493A3F8E493A34003F68001F208DFF48029E493A3F85407240CC8C333C4540F4420C8834004F4D7
-:4010C60056800146F6DFE4800B0102040810204080901845E47E019360BCA3FF543F30E509541FFEE493A360010ECF54C025E060A840B8E493A3FAE493A3F8E493A3C8C589
-:4011060082C8CAC583CAF0A3C8C582C8CAC583CADFE9DEE780BE907FD2E030E1030211A5C209907B40E014602614603B14605024836064248070637E7B7FC075147B75153A
-:40114600C0907F98742EF0751601120046804B7E7C7F0075147C751500907F98742DF075160212004680337E7C7F4075147C751540907F98742BF0751604120046801B7E2B
-:401186007C7F8075147C751580907F987427F07516081200468003121751E4907FD3F022BB010689828A83E0225002E722BBFE02E32289828A83E49322BB010CE58229F5B8
-:4011C60082E5833AF583E0225006E92582F8E622BBFE06E92582F8E222E58229F582E5833AF583E49322BB010689828A83F0225002F722BBFE01F322D083D082F8E49370B6
-:4012060012740193700DA3A393F8740193F5828883E4737402936860EFA3A3A380DF907FAEE0FFD39200E433FEEF4EF0D2E843D820907FDE7401F0907FDFF0907FAB74FFC2
-:40124600F0907FA9F0907FAAF05391EF907FAF7401F0907FAE740DF0D2AFD20B121809C201E4F52BF531C207C20275290F907FD8E06526600675320FE0F526300203120F8C
-:40128600EF300107C20112063F80E23008DFC20812182A80D822E5135516606AE515243AF582E43514F583E0705CE516F45213E5152426FFE43514FEE4FD0FEFAA067001C7
-:4012C6000E14F5828A83E0FC74802DF582E4347BF583ECF00DBD0BE2907FC3740BF0E515243AF582E43514F5837410F0E515242EF582E43514F583E4F0E515242FF582E423
-:401306003514F583E4F022E52845276057AE27AF28D3EF9440EE940040047E007F40C3E5289FF528E5279EF527E4FDEDC39FE49E501F853482853383E0FC74002DF582E4BA
-:40134600347FF583ECF00D0534E5347002053380DA907FA97401F0907FACE04401F0907FB5EFF022907FACE054FEF0E4907FB5F022907F98740FF0E490784AF0907F94F0E1
-:40138600907F9D74FFF0E4907F97F0907841F0907F93F0907F9C74FFF0300007E529540FFF80027F00907F96EFF0907F98741FF0E4907F95F0907F9E743FF0907F9874DFAD
-:4013C600F0907F92E054FDF0228F19052DE52DAE2C7002052C14F5828E83E519F01218EF052DE52DAC2C7002052C14F5828C83EFF01523E523601FE5152438F582E4351416
-:40140600F583C083C082E0FE1218D38F19EE4FD082D083F080B522907841E511F090784F74C0F0E4907850F0E52C907851F0AE2CE52D907852F0907854E523F09078577470
-:4014460004F0907FE2E04410F0E054F7F0E4907855F0907855E060FA228F19E4F51A751BFF751C19751D86AB1BAA1CA91D9000011211BFB4031DAF1A051AEFB519012212F9
-:4014860011A67E0029FFEE3AA907751BFFF51C891D80D47B007A00790022907841E511F0E52C90784FF0AE2CE52D907850F090785174C0F0E4907852F0907854E523F0907D
-:4014C60078577404F0E4907855F0907855E060FA22E5152404F582E43514F583E014600F1460131460178000907FC7EFF08013907FC9EFF0800C907FCBEFF08005907FCDED
-:40150600EFF0E516422A22E5152404F582E43514F583E014600F1460131460178000907FB7EFF08013907FB9EFF0800C907FBBEFF08005907FBDEFF0E516422A22AE07E4A4
-:40154600FFE5152432F582E43514F583E0547FFD12166B90784174F1F090C000EEF0E4E5152432F582E43514F583E04480FD12166B22C0E0C0F0C083C082C085C084C086A1
-:40158600758600C0D075D0085391EF907FA97401F012130DD0D0D086D084D085D082D083D0F0D0E03290784174F3F090C00074BFF090784174F1F090C000EFF090784174A8
-:4015C600F3F0E5152437F582E43514F583E0547F90C000F02290784174F3F090C00074BFF090784174F2F090C000EFF090784174F3F0E5152437F582E43514F583E0547FD7
-:4016060090C000F02290784174F3F090C00074BFF090784174F4F090C000EFF090784174F3F0E5152437F582E43514F583E0547F90C000F02290784174F3F090C00074BF16
-:40164600F090784174F6F090C000EFF090784174F3F0E5152437F582E43514F583E0547F90C000F02290784174F3F0E5152437F582E43514F583E0547F90C000F09078412F
-:4016860074F7F090C000EFF090784174F5F090C000EDF022E5152404F582E43514F583E014600E1460111460148000907FC6E0FF22907FC8E0FF22907FCAE0FF22907FCC19
-:4016C600E0FF22E5152404F582E43514F583E014600E1460111460148000907FB6E0FF22907FB8E0FF22907FBAE0FF22907FBCE0FF22E5152404F582E43514F583E0146000
-:401706000E1460111460148000907FC7E0FF22907FC9E0FF22907FCBE0FF22907FCDE0FF22C0E0C083C082C085C084C086758600907FC4E4F05391EF907FAB7404F0D086BF
-:40174600D084D085D082D083D0E032907B41E0F536431310A3E06009907FD77417F07437F0907B43E0F537A3E054F0F529E06002D20A22C0E0C083C082C085C084C08675A6
-:401786008600D2015391EF907FAB7401F0D086D084D085D082D083D0E032C0E0C083C082C085C084C086758600D2085391EF907FAB7408F0D086D084D085D082D083D0E03C
-:4017C600321218B7AE071218B7AD07EE6D60101218B7AE07EE6D60071218B7AD0780ECAF06227400F58690FDA57C05A3E582458370F922907FD6E04480F043870100000048
-:40180600000022907FD6E04404F0E04408F0300B04E04402F07FF47E01121860907FD6E054F7F0221213771217F9907FD6E030E70A7F057E00121860121893120ACE220378
-:4018460035800000032E810000C185C181C108C100C106012200012400008E178F18E5181518AE17700215174E60081217E81217E880EB22E5152404F582E43514F583E07E
-:4018860004FF4410907FD7F0EF4430F022907FD6E04401F07F0D7E00121860907FD6E054FEF022E5112402907841F090C000E0FF22E5112403907841F090C000E0FF22E597
-:4018C600112404907841F090C000E0FF22E5112405907841F090C000E0FF22E5112406907841F090C000E0FF22907841E511F090C000E0FF2253D8EF320012011001FFFFDE
-:40190600FF40CD062A0100000102000409027400010100A032090400000EFF000000070501024000000705020240000007050302400000070504024000000705050240005B
-:4019460000070506024000000705070240000007058102400001070582024000010705830240000107058402400001070585024000010705860240000107058702400001F3
-:401986000403090448034B00650079007300700061006E002C002000610020006400690076006900730069006F006E0020006F006600200049006E006E006F005300790040
-:4019C6007300200049006E0063002E0024034B00650079007300700061006E0020005500530041002D003400390057004C00430022035500530041002D00360035002000B5
-:401A060032003000300033006A0061006E0033003100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003E
-:401A46000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000060
-:401A86000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020
-:401AC6000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002177900021B31
-:151B06000400021727000217A000021B1000021B1400021578E0
-:00000001FF
-
-	The firmware contained herein is
-
-		Copyright (C) 1999-2003
-		Keyspan, A division of InnoSys Incorporated ("Keyspan")
-
-	as an unpublished work. This notice does not imply unrestricted or
-	public access to the source code from which this firmware image is
-	derived.  Except as noted below this firmware image may not be
-	reproduced, used, sold or transferred to any third party without
-	Keyspan's prior written consent.  All Rights Reserved.
-
-	Permission is hereby granted for the distribution of this firmware
-	image as part of a Linux or other Open Source operating system kernel
-	in text or binary form as required.
-
-	This firmware may not be modified and may only be used with
-	Keyspan hardware.  Distribution and/or Modification of the
-	keyspan.c driver which includes this firmware, in whole or in
-	part, requires the inclusion of this statement."
-
-static char theFirmwareDate49[] =
-        "02/14/2002  02:37p              19,347 USA49";
-
-static char theFirmwareDate65[] =
-        "01/31/2003  09:34a              19,331 USA65";
-
--- zfcpdump-kernel-4.4.orig/firmware/keyspan_pda/keyspan_pda.HEX
+++ /dev/null
@@ -1,83 +0,0 @@
-:03000000020200F9
-:0400230002055F0073
-:0400430002010000B6
-:050030000000000000CB
-:10010000020296000200000002000000020000004F
-:1001100002000000020000000200000002000000D7
-:1001200002000000020000000204610002048900D5
-:1002000075815EE4F532F533F530F531F534C20031
-:10021000C201A90074FE901000F0A3D9FC74FD90F7
-:100220001100F0A3D9FC7402907F9DF07400907FC0
-:1002300097F07486907F9EF0907F957403F0907F86
-:10024000AFE0D2E0F07401907FABF0907FAEF09021
-:100250007FAC7404F0907FAD7404F0907FC9F074AB
-:1002600084907F98F07400F59875C8307B059120D4
-:10027000D2CA759850D2E8D2AFD2AC7400F586904D
-:100280007FD67402F0792E7A007B00DBFEDAFAD991
-:10029000F67406F080FEC086C082C083C084C0852C
-:1002A000C0E0E591C2E4F591907FAB7401F0907FDE
-:1002B000E8E0F9A3E0FAA3E0FBA3E0FCE95460B4B2
-:1002C0000003020339B4406EBA000B12042040034D
-:1002D00002040202040ABA010302040ABA02030277
-:1002E000040ABA0303020444BA041EBB000A907F46
-:1002F00095E04402F0020402907F98E054FDF090F3
-:100300007F95E054FDF0020402BA050302040ABA24
-:100310000619BB0008E533D395320203DEBB0108A2
-:10032000E532C395330203DE02040ABA07058B34B3
-:1003300002040202040A02040ABA0020B9801090E2
-:100340007F00E4F0A3F0907FB57402F0020402B9DC
-:10035000820280EBB9810280E602040ABA010FBB77
-:10036000000302040ABB010302040202040ABA03E6
-:100370000FBB000302040ABB010302040202040AC9
-:10038000BA0656BC010F907FD47406F0907FD574E6
-:1003900012F0020402BC0212BB006F907FD47406FC
-:1003A000F0907FD57424F0020402BC03297404C3C6
-:1003B0009B40576055EB2B9006442582F5827400D4
-:1003C0003583F583E0F9A3E0FA907FD4E9F0907FDC
-:1003D000D5EAF002040202040ABA080F7401907F01
-:1003E00000F07401907FB5F0020402BA0903020420
-:1003F00002BA0A0574000203DEBA0B030204020209
-:10040000040A907FB47402F08009907FB4E0440144
-:10041000F08000D0E0D085D084D083D082D08632E6
-:10042000EB20E71EC3940A5019EB2324FEF58274D7
-:10043000053400F583E0F5CBF5CDA3E0F5CAF5CCA6
-:10044000C322D322B94111EB64FF5484FB907F98FF
-:10045000E0547B4BF0020402907F9BE064FF0203B8
-:10046000DEC086C082C083C084C085C0E0E591C282
-:10047000E4F591907FA97404F01205A0D0E0D08536
-:10048000D084D083D082D08632C086C082C083C060
-:1004900084C085C0E0E591C2E4F591907FAA740420
-:1004A000F0907FC9E0F9E4F586907DC075851085F0
-:1004B0003284E005860584F0E584B53302800905C1
-:1004C000320586A3D9EC8000907FC9F0B131D0E02D
-:1004D000D085D084D083D082D08632E4F586907FD8
-:1004E000BCE020E14B907D00E532F0A3E533F0A3C2
-:1004F000E530F0A3E531F0A3E430000104F0A305FA
-:10050000869010007910E0A30586F0A30586D9F641
-:10051000058674FCF0A305869011007910E0A30510
-:1005200086F0A30586D9F6E4F586907FBD7426F0A3
-:1005300022200013E532B53301220533758310857F
-:100540003382E0F599D2007400B5340122E533D34B
-:100550009532C3953440F5753400D2010205A0C030
-:1005600086C082C083C084C085C0E0309907C2992C
-:10057000C20012053430980512058AC298D0E0D026
-:1005800085D084D083D082D0863275831185308225
-:100590000582E599F0E582B53101220530B1A0224E
-:1005A000907FB8E020E138200136E530B5310122F6
-:1005B000E4F5867583110586907E00F0A3058679A3
-:1005C00001E530B5310280100531853182E00586C4
-:1005D000F0A3058609B940E9907FB9E96001F022EE
-:1005E000C201E4F586907E007401F0A37402F090DD
-:1005F0007FB9F022C299F5993099FDC29922E55E42
-:10060000F63CFD8FFEC8FF64FFB2FFD9FFEDFFF39C
-:10061000FFFA12010001FFFFFF40CD06040189AB84
-:1006200001020301090220000101008032090400D7
-:100630000002FFFFFF0007058203400001070502DB
-:1006400002400000064C0650067206A0040300009B
-:100650002203410043004D00450020007500730057
-:100660006200200077006900640067006500740084
-:1006700073002E03410043004D004500200055004B
-:1006800053004200200073006500720069006100A1
-:100690006C0020007700690064006700650074004A
-:0606A000060334003700E0
-:00000001FF
--- zfcpdump-kernel-4.4.orig/firmware/keyspan_pda/keyspan_pda.S
+++ /dev/null
@@ -1,1124 +0,0 @@
-/*  $Id: loop.s,v 1.23 2000/03/20 09:49:06 warner Exp $
- * 
- *  Firmware for the Keyspan PDA Serial Adapter, a USB serial port based on
- *  the EzUSB microcontroller.
- * 
- *  (C) Copyright 2000 Brian Warner <warner@lothar.com>
- * 
- * 	This program is free software; you can redistribute it and/or modify
- * 	it under the terms of the GNU General Public License as published by
- * 	the Free Software Foundation; either version 2 of the License, or
- * 	(at your option) any later version.
- * 
- *  "Keyspan PDA Serial Adapter" is probably a copyright of Keyspan, the
- *  company.
- * 
- *  This serial adapter is basically an EzUSB chip and an RS-232 line driver
- *  in a little widget that has a DB-9 on one end and a USB plug on the other.
- *  It uses the EzUSB's internal UART0 (using the pins from Port C) and timer2
- *  as a baud-rate generator. The wiring is:
- *   PC0/RxD0 <- rxd (DB9 pin 2)         PC4 <- dsr pin 6
- *   PC1/TxD0 -> txd pin 3               PC5 <- ri  pin 9
- *   PC2      -> rts pin 7               PC6 <- dcd pin 1
- *   PC3      <- cts pin 8               PC7 -> dtr pin 4
- *   PB1 -> line driver standby
- *
- *  The EzUSB register constants below come from their excellent documentation
- *  and sample code (which used to be available at www.anchorchips.com, but
- *  that has now been absorbed into Cypress' site and the CD-ROM contents
- *  don't appear to be available online anymore). If we get multiple
- *  EzUSB-based drivers into the kernel, it might be useful to pull them out
- *  into a separate .h file.
- * 
- * THEORY OF OPERATION:
- *
- *   There are two 256-byte ring buffers, one for tx, one for rx.
- *
- *   EP2out is pure tx data. When it appears, the data is copied into the tx
- *   ring and serial transmission is started if it wasn't already running. The
- *   "tx buffer empty" interrupt may kick off another character if the ring
- *   still has data. If the host is tx-blocked because the ring filled up,
- *   it will request a "tx unthrottle" interrupt. If sending a serial character
- *   empties the ring below the desired threshold, we set a bit that will send
- *   up the tx unthrottle message as soon as the rx buffer becomes free.
- *
- *   EP2in (interrupt) is used to send both rx chars and rx status messages
- *   (only "tx unthrottle" at this time) back up to the host. The first byte
- *   of the rx message indicates data (0) or status msg (1). Status messages
- *   are sent before any data.
- *
- *   Incoming serial characters are put into the rx ring by the serial
- *   interrupt, and the EP2in buffer sent if it wasn't already in transit.
- *   When the EP2in buffer returns, the interrupt prompts us to send more
- *   rx chars (or status messages) if they are pending.
- *
- *   Device control happens through "vendor specific" control messages on EP0.
- *   All messages are destined for the "Interface" (with the index always 0,
- *   so that if their two-port device might someday use similar firmware, we
- *   can use index=1 to refer to the second port). The messages defined are:
- *
- *    bRequest = 0 : set baud/bits/parity
- *               1 : unused
- *               2 : reserved for setting HW flow control (CTSRTS)
- *               3 : get/set "modem info" (pin states: DTR, RTS, DCD, RI, etc)
- *               4 : set break (on/off)
- *               5 : reserved for requesting interrupts on pin state change
- *               6 : query buffer room or chars in tx buffer
- *               7 : request tx unthrottle interrupt
- *
- *  The host-side driver is set to recognize the device ID values stashed in
- *  serial EEPROM (0x06cd, 0x0103), program this firmware into place, then
- *  start it running. This firmware will use EzUSB's "renumeration" trick by
- *  simulating a bus disconnect, then reconnect with a different device ID
- *  (encoded in the desc_device descriptor below). The host driver then
- *  recognizes the new device ID and glues it to the real serial driver code.
- *
- * USEFUL DOCS:
- *  EzUSB Technical Reference Manual: <http://www.cypress.com/>
- *  8051 manuals: everywhere, but try www.dalsemi.com because the EzUSB is
- *   basically the Dallas enhanced 8051 code. Remember that the EzUSB IO ports
- *   use totally different registers!
- *  USB 1.1 spec: www.usb.org
- *
- * HOW TO BUILD:
- *  gcc -x assembler-with-cpp -P -E -o keyspan_pda.asm keyspan_pda.s
- *  as31 -l keyspan_pda.asm
- *  mv keyspan_pda.obj keyspan_pda.hex
- *  perl ezusb_convert.pl keyspan_pda < keyspan_pda.hex > keyspan_pda_fw.h
- * Get as31 from <http://www.pjrc.com/tech/8051/index.html>, and hack on it
- * a bit to make it build.
- *
- * THANKS:
- *  Greg Kroah-Hartman, for coordinating the whole usb-serial thing.
- *  AnchorChips, for making such an incredibly useful little microcontroller.
- *  KeySpan, for making a handy, cheap ($40) widget that was so easy to take
- *           apart and trace with an ohmmeter.
- *
- * TODO:
- *  lots. grep for TODO. Interrupt safety needs stress-testing. Better flow
- *  control. Interrupting host upon change in DCD, etc, counting transitions.
- *  Need to find a safe device id to use (the one used by the Keyspan firmware
- *  under Windows would be ideal.. can anyone figure out what it is?). Parity.
- *  More baud rates. Oh, and the string-descriptor-length silicon bug
- *  workaround should be implemented, but I'm lazy, and the consequence is
- *  that the device name strings that show up in your kernel log will have
- *  lots of trailing binary garbage in them (appears as ????). Device strings
- *  should be made more accurate.
- *
- * Questions, bugs, patches to Brian.
- *
- *  -Brian Warner <warner@lothar.com>
- *
- */
-	
-#define HIGH(x) (((x) & 0xff00) / 256)
-#define LOW(x) ((x) & 0xff)
-
-#define dpl1 0x84
-#define dph1 0x85
-#define dps 0x86
-
-;;; our bit assignments
-#define TX_RUNNING 0
-#define DO_TX_UNTHROTTLE 1
-	
-	;; stack from 0x60 to 0x7f: should really set SP to 0x60-1, not 0x60
-#define STACK #0x60-1
-
-#define EXIF 0x91
-#define EIE 0xe8
-	.flag EUSB, EIE.0
-	.flag ES0, IE.4
-
-#define EP0CS #0x7fb4
-#define EP0STALLbit #0x01
-#define IN0BUF #0x7f00
-#define IN0BC #0x7fb5
-#define OUT0BUF #0x7ec0
-#define OUT0BC #0x7fc5		
-#define IN2BUF #0x7e00
-#define IN2BC #0x7fb9
-#define IN2CS #0x7fb8
-#define OUT2BC #0x7fc9
-#define OUT2CS #0x7fc8
-#define OUT2BUF #0x7dc0
-#define IN4BUF #0x7d00
-#define IN4BC #0x7fbd
-#define IN4CS #0x7fbc
-#define OEB #0x7f9d
-#define OUTB #0x7f97
-#define OEC #0x7f9e
-#define OUTC #0x7f98
-#define PINSC #0x7f9b
-#define PORTCCFG #0x7f95
-#define IN07IRQ #0x7fa9
-#define OUT07IRQ #0x7faa
-#define IN07IEN #0x7fac
-#define OUT07IEN #0x7fad
-#define USBIRQ #0x7fab
-#define USBIEN #0x7fae
-#define USBBAV #0x7faf
-#define USBCS #0x7fd6
-#define SUDPTRH #0x7fd4
-#define SUDPTRL #0x7fd5
-#define SETUPDAT #0x7fe8
-		
-	;; usb interrupt : enable is EIE.0 (0xe8), flag is EXIF.4 (0x91)
-
-	.org 0
-	ljmp start
-	;; interrupt vectors
-	.org 23H
-	ljmp serial_int
-	.byte 0
-	
-	.org 43H
-	ljmp USB_Jump_Table
-	.byte 0			; filled in by the USB core
-
-;;; local variables. These are not initialized properly: do it by hand.
-	.org 30H
-rx_ring_in:	.byte 0
-rx_ring_out:	.byte 0
-tx_ring_in:	.byte 0
-tx_ring_out:	.byte 0
-tx_unthrottle_threshold:	.byte 0
-		
-	.org 0x100H		; wants to be on a page boundary
-USB_Jump_Table:
-	ljmp	ISR_Sudav	; Setup Data Available
-	.byte 0
-	ljmp	0		; Start of Frame
-	.byte 0
-	ljmp	0		; Setup Data Loading
-	.byte 0
-	ljmp	0		; Global Suspend
-	.byte 	0
-	ljmp	0		; USB Reset  	
-	.byte	0
-	ljmp	0		; Reserved
-	.byte	0
-	ljmp	0		; End Point 0 In
-	.byte	0
-	ljmp	0		; End Point 0 Out
-	.byte	0
-	ljmp	0		; End Point 1 In
-	.byte	0
-	ljmp	0		; End Point 1 Out
-	.byte	0
-	ljmp	ISR_Ep2in
-	.byte	0
-	ljmp	ISR_Ep2out
-	.byte	0
-
-
-	.org 0x200
-		
-start:	mov SP,STACK-1 ; set stack
-	;; clear local variables
-	clr a
-	mov tx_ring_in, a
-	mov tx_ring_out, a
-	mov rx_ring_in, a
-	mov rx_ring_out, a
-	mov tx_unthrottle_threshold, a
-	clr TX_RUNNING
-	clr DO_TX_UNTHROTTLE
-	
-	;; clear fifo with "fe"
-	mov r1, 0
-	mov a, #0xfe
-	mov dptr, #tx_ring
-clear_tx_ring_loop:
-	movx @dptr, a
-	inc dptr
-	djnz r1, clear_tx_ring_loop
-
-	mov a, #0xfd
-	mov dptr, #rx_ring
-clear_rx_ring_loop:
-	movx @dptr, a
-	inc dptr
-	djnz r1, clear_rx_ring_loop
-
-;;; turn on the RS-232 driver chip (bring the STANDBY pin low)
-	;; set OEB.1
-	mov a, #02H
-	mov dptr,OEB
-	movx @dptr,a
-	;; clear PB1
-	mov a, #00H
-	mov dptr,OUTB
-	movx @dptr,a
-	;; set OEC.[127]
-	mov a, #0x86
-	mov dptr,OEC
-	movx @dptr,a
-	;; set PORTCCFG.[01] to route TxD0,RxD0 to serial port
-	mov dptr, PORTCCFG
-	mov a, #0x03
-	movx @dptr, a
-	
-	;; set up interrupts, autovectoring
-	mov dptr, USBBAV
-	movx a,@dptr
-	setb acc.0		; AVEN bit to 0
-	movx @dptr, a
-
-	mov a,#0x01		; enable SUDAV:	setup data available (for ep0)
-	mov dptr, USBIRQ
-	movx @dptr, a		; clear SUDAVI
-	mov dptr, USBIEN
-	movx @dptr, a
-	
-	mov dptr, IN07IEN
-	mov a,#0x04		; enable IN2 int
-	movx @dptr, a
-	
-	mov dptr, OUT07IEN
-	mov a,#0x04		; enable OUT2 int
-	movx @dptr, a
-	mov dptr, OUT2BC
-	movx @dptr, a		; arm OUT2
-
-	mov a, #0x84		; turn on RTS, DTR
-	mov dptr,OUTC
-	movx @dptr, a
-	;; setup the serial port. 9600 8N1.
-	mov a,#01010011		; mode 1, enable rx, clear int
-	mov SCON, a
-	;;  using timer2, in 16-bit baud-rate-generator mode
-	;;   (xtal 12MHz, internal fosc 24MHz)
-	;;  RCAP2H,RCAP2L = 65536 - fosc/(32*baud)
-	;;  57600: 0xFFF2.F, say 0xFFF3
-	;;   9600: 0xFFB1.E, say 0xFFB2
-	;;    300: 0xF63C
-#define BAUD 9600
-#define BAUD_TIMEOUT(rate) (65536 - (24 * 1000 * 1000) / (32 * rate))
-#define BAUD_HIGH(rate) HIGH(BAUD_TIMEOUT(rate))
-#define BAUD_LOW(rate) LOW(BAUD_TIMEOUT(rate))
-		
-	mov T2CON, #030h	; rclk=1,tclk=1,cp=0,tr2=0(enable later)
-	mov r3, #5
-	acall set_baud
-	setb TR2
-	mov SCON, #050h
-	
-#if 0
-	mov r1, #0x40
-	mov a, #0x41
-send:	
-	mov SBUF, a
-	inc a
-	anl a, #0x3F
-	orl a, #0x40
-;	xrl a, #0x02
-wait1:	
-	jnb TI, wait1
-	clr TI
-	djnz r1, send
-;done:	sjmp done
-
-#endif
-	
-	setb EUSB
-	setb EA
-	setb ES0
-	;acall dump_stat
-
-	;; hey, what say we RENUMERATE! (TRM p.62)
-	mov a, #0
-	mov dps, a
-	mov dptr, USBCS
-	mov a, #0x02		; DISCON=0, DISCOE=0, RENUM=1
-	movx @dptr, a
-	;; now presence pin is floating, simulating disconnect. wait 0.5s
-	mov r1, #46
-renum_wait1:
-	mov r2, #0
-renum_wait2:
-	mov r3, #0
-renum_wait3:
-	djnz r3, renum_wait3
-	djnz r2, renum_wait2
-	djnz r1, renum_wait1	; wait about n*(256^2) 6MHz clocks
-	mov a, #0x06		; DISCON=0, DISCOE=1, RENUM=1
-	movx @dptr, a
-	;; we are back online. the host device will now re-query us
-	
-	
-main:	sjmp main
-
-	
-
-ISR_Sudav:
-	push dps
-	push dpl
-	push dph
-	push dpl1
-	push dph1
-	push acc
-	mov a,EXIF
-	clr acc.4
-	mov EXIF,a		; clear INT2 first
-	mov dptr, USBIRQ	; clear USB int
-	mov a,#01h
-	movx @dptr,a
-
-	;; get request type
-	mov dptr, SETUPDAT
-	movx a, @dptr
-	mov r1, a		; r1 = bmRequestType
-	inc dptr
-	movx a, @dptr
-	mov r2, a		; r2 = bRequest
-	inc dptr
-	movx a, @dptr
-	mov r3, a		; r3 = wValueL
-	inc dptr
-	movx a, @dptr
-	mov r4, a		; r4 = wValueH
-
-	;; main switch on bmRequest.type: standard or vendor
-	mov a, r1
-	anl a, #0x60
-	cjne a, #0x00, setup_bmreq_type_not_standard
-	;; standard request: now main switch is on bRequest
-	ljmp setup_bmreq_is_standard
-	
-setup_bmreq_type_not_standard:	
-	;; a still has bmreq&0x60
-	cjne a, #0x40, setup_bmreq_type_not_vendor
-	;; Anchor reserves bRequest 0xa0-0xaf, we use small ones
-	;; switch on bRequest. bmRequest will always be 0x41 or 0xc1
-	cjne r2, #0x00, setup_ctrl_not_00
-	;; 00 is set baud, wValue[0] has baud rate index
-	lcall set_baud		; index in r3, carry set if error
-	jc setup_bmreq_type_not_standard__do_stall
-	ljmp setup_done_ack
-setup_bmreq_type_not_standard__do_stall:
-	ljmp setup_stall
-setup_ctrl_not_00:
-	cjne r2, #0x01, setup_ctrl_not_01
-	;; 01 is reserved for set bits (parity). TODO
-	ljmp setup_stall
-setup_ctrl_not_01:
-	cjne r2, #0x02, setup_ctrl_not_02
-	;; 02 is set HW flow control. TODO
-	ljmp setup_stall
-setup_ctrl_not_02:
-	cjne r2, #0x03, setup_ctrl_not_03
-	;; 03 is control pins (RTS, DTR).
-	ljmp control_pins	; will jump to setup_done_ack,
-				;  or setup_return_one_byte
-setup_ctrl_not_03:
-	cjne r2, #0x04, setup_ctrl_not_04
-	;; 04 is send break (really "turn break on/off"). TODO
-	cjne r3, #0x00, setup_ctrl_do_break_on
-	;; do break off: restore PORTCCFG.1 to reconnect TxD0 to serial port
-	mov dptr, PORTCCFG
-	movx a, @dptr
-	orl a, #0x02
-	movx @dptr, a
-	ljmp setup_done_ack
-setup_ctrl_do_break_on:
-	;; do break on: clear PORTCCFG.0, set TxD high(?) (b1 low)
-	mov dptr, OUTC
-	movx a, @dptr
-	anl a, #0xfd		; ~0x02
-	movx @dptr, a
-	mov dptr, PORTCCFG
-	movx a, @dptr
-	anl a, #0xfd		; ~0x02
-	movx @dptr, a
-	ljmp setup_done_ack
-setup_ctrl_not_04:
-	cjne r2, #0x05, setup_ctrl_not_05
-	;; 05 is set desired interrupt bitmap. TODO
-	ljmp setup_stall
-setup_ctrl_not_05:
-	cjne r2, #0x06, setup_ctrl_not_06
-	;; 06 is query room
-	cjne r3, #0x00, setup_ctrl_06_not_00
-	;; 06, wValue[0]=0 is query write_room
-	mov a, tx_ring_out
-	setb c
-	subb a, tx_ring_in	; out-1-in = 255 - (in-out)
-	ljmp setup_return_one_byte
-setup_ctrl_06_not_00:
-	cjne r3, #0x01, setup_ctrl_06_not_01
-	;; 06, wValue[0]=1 is query chars_in_buffer
-	mov a, tx_ring_in
-	clr c
-	subb a, tx_ring_out	; in-out
-	ljmp setup_return_one_byte
-setup_ctrl_06_not_01:	
-	ljmp setup_stall
-setup_ctrl_not_06:
-	cjne r2, #0x07, setup_ctrl_not_07
-	;; 07 is request tx unthrottle interrupt
-	mov tx_unthrottle_threshold, r3; wValue[0] is threshold value
-	ljmp setup_done_ack
-setup_ctrl_not_07:
-	ljmp setup_stall
-	
-setup_bmreq_type_not_vendor:
-	ljmp setup_stall
-
-
-setup_bmreq_is_standard:	
-	cjne r2, #0x00, setup_breq_not_00
-	;; 00:	Get_Status (sub-switch on bmRequestType: device, ep, int)
-	cjne r1, #0x80, setup_Get_Status_not_device
-	;; Get_Status(device)
-	;;  are we self-powered? no. can we do remote wakeup? no
-	;;   so return two zero bytes. This is reusable
-setup_return_two_zero_bytes:
-	mov dptr, IN0BUF
-	clr a
-	movx @dptr, a
-	inc dptr
-	movx @dptr, a
-	mov dptr, IN0BC
-	mov a, #2
-	movx @dptr, a
-	ljmp setup_done_ack
-setup_Get_Status_not_device:
-	cjne r1, #0x82, setup_Get_Status_not_endpoint
-	;; Get_Status(endpoint)
-	;;  must get stall bit for ep[wIndexL], return two bytes, bit in lsb 0
-	;; for now: cheat. TODO
-	sjmp setup_return_two_zero_bytes
-setup_Get_Status_not_endpoint:
-	cjne r1, #0x81, setup_Get_Status_not_interface
-	;; Get_Status(interface): return two zeros
-	sjmp setup_return_two_zero_bytes
-setup_Get_Status_not_interface:	
-	ljmp setup_stall
-	
-setup_breq_not_00:
-	cjne r2, #0x01, setup_breq_not_01
-	;; 01:	Clear_Feature (sub-switch on wValueL: stall, remote wakeup)
-	cjne r3, #0x00, setup_Clear_Feature_not_stall
-	;; Clear_Feature(stall). should clear a stall bit. TODO
-	ljmp setup_stall
-setup_Clear_Feature_not_stall:
-	cjne r3, #0x01, setup_Clear_Feature_not_rwake
-	;; Clear_Feature(remote wakeup). ignored.
-	ljmp setup_done_ack
-setup_Clear_Feature_not_rwake:
-	ljmp setup_stall
-	
-setup_breq_not_01:
-	cjne r2, #0x03, setup_breq_not_03
-	;; 03:	Set_Feature (sub-switch on wValueL: stall, remote wakeup)
-	cjne r3, #0x00, setup_Set_Feature_not_stall
-	;; Set_Feature(stall). Should set a stall bit. TODO
-	ljmp setup_stall
-setup_Set_Feature_not_stall:
-	cjne r3, #0x01, setup_Set_Feature_not_rwake
-	;; Set_Feature(remote wakeup). ignored.
-	ljmp setup_done_ack
-setup_Set_Feature_not_rwake:
-	ljmp setup_stall
-	
-setup_breq_not_03:	
-	cjne r2, #0x06, setup_breq_not_06
-	;; 06:	Get_Descriptor (s-switch on wValueH: dev, config[n], string[n])
-	cjne r4, #0x01, setup_Get_Descriptor_not_device
-	;; Get_Descriptor(device)
-	mov dptr, SUDPTRH
-	mov a, #HIGH(desc_device)
-	movx @dptr, a
-	mov dptr, SUDPTRL
-	mov a, #LOW(desc_device)
-	movx @dptr, a
-	ljmp setup_done_ack
-setup_Get_Descriptor_not_device:
-	cjne r4, #0x02, setup_Get_Descriptor_not_config
-	;; Get_Descriptor(config[n])
-	cjne r3, #0x00, setup_stall; only handle n==0
-	;; Get_Descriptor(config[0])
-	mov dptr, SUDPTRH
-	mov a, #HIGH(desc_config1)
-	movx @dptr, a
-	mov dptr, SUDPTRL
-	mov a, #LOW(desc_config1)
-	movx @dptr, a
-	ljmp setup_done_ack
-setup_Get_Descriptor_not_config:
-	cjne r4, #0x03, setup_Get_Descriptor_not_string
-	;; Get_Descriptor(string[wValueL])
-	;;  if (wValueL >= maxstrings) stall
-	mov a, #((desc_strings_end-desc_strings)/2)
-	clr c
-	subb a,r3		; a=4, r3 = 0..3 . if a<=0 then stall
-	jc  setup_stall
-	jz  setup_stall
-	mov a, r3
-	add a, r3		; a = 2*wValueL
-	mov dptr, #desc_strings
-	add a, dpl
-	mov dpl, a
-	mov a, #0
-	addc a, dph
-	mov dph, a		; dph = desc_strings[a]. big endian! (handy)
-	;; it looks like my adapter uses a revision of the EZUSB that
-	;; contains "rev D errata number 8", as hinted in the EzUSB example
-	;; code. I cannot find an actual errata description on the Cypress
-	;; web site, but from the example code it looks like this bug causes
-	;; the length of string descriptors to be read incorrectly, possibly
-	;; sending back more characters than the descriptor has. The workaround
-	;; is to manually send out all of the data. The consequence of not
-	;; using the workaround is that the strings gathered by the kernel
-	;; driver are too long and are filled with trailing garbage (including
-	;; leftover strings). Writing this out by hand is a nuisance, so for
-	;; now I will just live with the bug.
-	movx a, @dptr
-	mov r1, a
-	inc dptr
-	movx a, @dptr
-	mov r2, a
-	mov dptr, SUDPTRH
-	mov a, r1
-	movx @dptr, a
-	mov dptr, SUDPTRL
-	mov a, r2
-	movx @dptr, a
-	;; done
-	ljmp setup_done_ack
-	
-setup_Get_Descriptor_not_string:
-	ljmp setup_stall
-	
-setup_breq_not_06:
-	cjne r2, #0x08, setup_breq_not_08
-	;; Get_Configuration. always 1. return one byte.
-	;; this is reusable
-	mov a, #1
-setup_return_one_byte:	
-	mov dptr, IN0BUF
-	movx @dptr, a
-	mov a, #1
-	mov dptr, IN0BC
-	movx @dptr, a
-	ljmp setup_done_ack
-setup_breq_not_08:
-	cjne r2, #0x09, setup_breq_not_09
-	;; 09: Set_Configuration. ignored.
-	ljmp setup_done_ack
-setup_breq_not_09:
-	cjne r2, #0x0a, setup_breq_not_0a
-	;; 0a: Get_Interface. get the current altsetting for int[wIndexL]
-	;;  since we only have one interface, ignore wIndexL, return a 0
-	mov a, #0
-	ljmp setup_return_one_byte
-setup_breq_not_0a:
-	cjne r2, #0x0b, setup_breq_not_0b
-	;; 0b: Set_Interface. set altsetting for interface[wIndexL]. ignored
-	ljmp setup_done_ack
-setup_breq_not_0b:
-	ljmp setup_stall
-
-		
-setup_done_ack:	
-	;; now clear HSNAK
-	mov dptr, EP0CS
-	mov a, #0x02
-	movx @dptr, a
-	sjmp setup_done
-setup_stall:	
-	;; unhandled. STALL
-	;EP0CS |= bmEPSTALL
-	mov dptr, EP0CS
-	movx a, @dptr
-	orl a, EP0STALLbit
-	movx @dptr, a
-	sjmp setup_done
-	
-setup_done:	
-	pop acc
-	pop dph1
-	pop dpl1
-	pop dph
-	pop dpl
-	pop dps
-	reti
-
-;;; ==============================================================
-	
-set_baud:			; baud index in r3
-	;; verify a < 10
-	mov a, r3
-	jb ACC.7, set_baud__badbaud
-	clr c
-	subb a, #10
-	jnc set_baud__badbaud
-	mov a, r3
-	rl a			; a = index*2
-	add a, #LOW(baud_table)
-	mov dpl, a
-	mov a, #HIGH(baud_table)
-	addc a, #0
-	mov dph, a
-	;; TODO: shut down xmit/receive
-	;; TODO: wait for current xmit char to leave
-	;; TODO: shut down timer to avoid partial-char glitch
-	movx a,@dptr		; BAUD_HIGH
-	mov RCAP2H, a
-	mov TH2, a
-	inc dptr
-	movx a,@dptr		; BAUD_LOW
-	mov RCAP2L, a
-	mov TL2, a
-	;; TODO: restart xmit/receive
-	;; TODO: reenable interrupts, resume tx if pending
-	clr c			; c=0: success
-	ret
-set_baud__badbaud:
-	setb c			; c=1: failure
-	ret
-	
-;;; ==================================================
-control_pins:
-	cjne r1, #0x41, control_pins_in
-control_pins_out:
-	mov a, r3 ; wValue[0] holds new bits:	b7 is new DTR, b2 is new RTS
-	xrl a, #0xff		; 1 means active, 0V, +12V ?
-	anl a, #0x84
-	mov r3, a
-	mov dptr, OUTC
-	movx a, @dptr		; only change bits 7 and 2
-	anl a, #0x7b		; ~0x84
-	orl a, r3
-	movx @dptr, a		; other pins are inputs, bits ignored
-	ljmp setup_done_ack
-control_pins_in:
-	mov dptr, PINSC
-	movx a, @dptr
-	xrl a, #0xff
-	ljmp setup_return_one_byte
-
-;;; ========================================
-	
-ISR_Ep2in:
-	push dps
-	push dpl
-	push dph
-	push dpl1
-	push dph1
-	push acc
-	mov a,EXIF
-	clr acc.4
-	mov EXIF,a		; clear INT2 first
-	mov dptr, IN07IRQ	; clear USB int
-	mov a,#04h
-	movx @dptr,a
-
-	;; do stuff
-	lcall start_in
-	
-	pop acc
-	pop dph1
-	pop dpl1
-	pop dph
-	pop dpl
-	pop dps
-	reti
-
-ISR_Ep2out:
-	push dps
-	push dpl
-	push dph
-	push dpl1
-	push dph1
-	push acc
-	mov a,EXIF
-	clr acc.4
-	mov EXIF,a		; clear INT2 first
-	mov dptr, OUT07IRQ	; clear USB int
-	mov a,#04h
-	movx @dptr,a
-
-	;; do stuff
-
-	;; copy data into buffer. for now, assume we will have enough space
-	mov dptr, OUT2BC	; get byte count
-	movx a,@dptr
-	mov r1, a
-	clr a
-	mov dps, a
-	mov dptr, OUT2BUF	; load DPTR0 with source
-	mov dph1, #HIGH(tx_ring)	; load DPTR1 with target
-	mov dpl1, tx_ring_in
-OUT_loop:
-	movx a,@dptr		; read
-	inc dps			; switch to DPTR1: target
-	inc dpl1		; target = tx_ring_in+1
-	movx @dptr,a		; store
-	mov a,dpl1
-	cjne a, tx_ring_out, OUT_no_overflow
-	sjmp OUT_overflow
-OUT_no_overflow:	
-	inc tx_ring_in		; tx_ring_in++
-	inc dps			; switch to DPTR0: source
-	inc dptr
-	djnz r1, OUT_loop
-	sjmp OUT_done
-OUT_overflow:
-	;; signal overflow
-	;; fall through
-OUT_done:	
-	;; ack
-	mov dptr,OUT2BC
-	movx @dptr,a
-
-	;; start tx
-	acall maybe_start_tx
-	;acall dump_stat
-	
-	pop acc
-	pop dph1
-	pop dpl1
-	pop dph
-	pop dpl
-	pop dps
-	reti
-
-dump_stat:
-	;; fill in EP4in with a debugging message:
-	;;   tx_ring_in, tx_ring_out, rx_ring_in, rx_ring_out
-	;;   tx_active
-	;;   tx_ring[0..15]
-	;;   0xfc
-	;;   rx_ring[0..15]
-	clr a
-	mov dps, a
-	
-	mov dptr, IN4CS
-	movx a, @dptr
-	jb acc.1, dump_stat__done; busy: cannot dump, old one still pending
-	mov dptr, IN4BUF
-	
-	mov a, tx_ring_in
-	movx @dptr, a
-	inc dptr
-	mov a, tx_ring_out
-	movx @dptr, a
-	inc dptr
-
-	mov a, rx_ring_in
-	movx @dptr, a
-	inc dptr
-	mov a, rx_ring_out
-	movx @dptr, a
-	inc dptr
-	
-	clr a
-	jnb TX_RUNNING, dump_stat__no_tx_running
-	inc a
-dump_stat__no_tx_running:
-	movx @dptr, a
-	inc dptr
-	;; tx_ring[0..15]
-	inc dps
-	mov dptr, #tx_ring	; DPTR1: source
-	mov r1, #16
-dump_stat__tx_ring_loop:
-	movx a, @dptr
-	inc dptr
-	inc dps
-	movx @dptr, a
-	inc dptr
-	inc dps
-	djnz r1, dump_stat__tx_ring_loop
-	inc dps
-	
-	mov a, #0xfc
-	movx @dptr, a
-	inc dptr
-	
-	;; rx_ring[0..15]
-	inc dps
-	mov dptr, #rx_ring	; DPTR1: source
-	mov r1, #16
-dump_stat__rx_ring_loop:
-	movx a, @dptr
-	inc dptr
-	inc dps
-	movx @dptr, a
-	inc dptr
-	inc dps
-	djnz r1, dump_stat__rx_ring_loop
-	
-	;; now send it
-	clr a
-	mov dps, a
-	mov dptr, IN4BC
-	mov a, #38
-	movx @dptr, a
-dump_stat__done:	
-	ret
-		
-;;; ============================================================
-	
-maybe_start_tx:
-	;; make sure the tx process is running.
-	jb TX_RUNNING, start_tx_done
-start_tx:
-	;; is there work to be done?
-	mov a, tx_ring_in
-	cjne a,tx_ring_out, start_tx__work
-	ret			; no work
-start_tx__work:	
-	;; tx was not running. send the first character, setup the TI int
-	inc tx_ring_out		; [++tx_ring_out]
-	mov dph, #HIGH(tx_ring)
-	mov dpl, tx_ring_out
-	movx a, @dptr
-	mov sbuf, a
-	setb TX_RUNNING
-start_tx_done:
-	;; can we unthrottle the host tx process?
-	;;  step 1: do we care?
-	mov a, #0
-	cjne a, tx_unthrottle_threshold, start_tx__maybe_unthrottle_tx
-	;; nope
-start_tx_really_done:
-	ret
-start_tx__maybe_unthrottle_tx:
-	;;  step 2: is there now room?
-	mov a, tx_ring_out
-	setb c
-	subb a, tx_ring_in
-	;; a is now write_room. If thresh >= a, we can unthrottle
-	clr c
-	subb a, tx_unthrottle_threshold
-	jc start_tx_really_done	; nope
-	;; yes, we can unthrottle. remove the threshold and mark a request
-	mov tx_unthrottle_threshold, #0
-	setb DO_TX_UNTHROTTLE
-	;; prod rx, which will actually send the message when in2 becomes free
-	ljmp start_in
-	
-
-serial_int:
-	push dps
-	push dpl
-	push dph
-	push dpl1
-	push dph1
-	push acc
-	jnb TI, serial_int__not_tx
-	;; tx finished. send another character if we have one
-	clr TI			; clear int
-	clr TX_RUNNING
-	lcall start_tx
-serial_int__not_tx:
-	jnb RI, serial_int__not_rx
-	lcall get_rx_char
-	clr RI			; clear int
-serial_int__not_rx:	
-	;; return
-	pop acc
-	pop dph1
-	pop dpl1
-	pop dph
-	pop dpl
-	pop dps
-	reti
-
-get_rx_char:
-	mov dph, #HIGH(rx_ring)
-	mov dpl, rx_ring_in
-	inc dpl			; target = rx_ring_in+1
-	mov a, sbuf
-	movx @dptr, a
-	;; check for overflow before incrementing rx_ring_in
-	mov a, dpl
-	cjne a, rx_ring_out, get_rx_char__no_overflow
-	;; signal overflow
-	ret
-get_rx_char__no_overflow:	
-	inc rx_ring_in
-	;; kick off USB INpipe
-	acall start_in
-	ret
-
-start_in:
-	;; check if the inpipe is already running.
-	mov dptr, IN2CS
-	movx a, @dptr
-	jb acc.1, start_in__done; int will handle it
-	jb DO_TX_UNTHROTTLE, start_in__do_tx_unthrottle
-	;; see if there is any work to do. a serial interrupt might occur
-	;; during this sequence?
-	mov a, rx_ring_in
-	cjne a, rx_ring_out, start_in__have_work
-	ret			; nope
-start_in__have_work:	
-	;; now copy as much data as possible into the pipe. 63 bytes max.
-	clr a
-	mov dps, a
-	mov dph, #HIGH(rx_ring)	; load DPTR0 with source
-	inc dps
-	mov dptr, IN2BUF	; load DPTR1 with target
-	movx @dptr, a		; in[0] signals that rest of IN is rx data
-	inc dptr
-	inc dps
-	;; loop until we run out of data, or we have copied 64 bytes
-	mov r1, #1		; INbuf size counter
-start_in__loop:
-	mov a, rx_ring_in
-	cjne a, rx_ring_out, start_inlocal_irq_enablell_copying
-	sjmp start_in__kick
-start_inlocal_irq_enablell_copying:
-	inc rx_ring_out
-	mov dpl, rx_ring_out
-	movx a, @dptr
-	inc dps
-	movx @dptr, a		; write into IN buffer
-	inc dptr
-	inc dps
-	inc r1
-	cjne r1, #64, start_in__loop; loop
-start_in__kick:
-	;; either we ran out of data, or we copied 64 bytes. r1 has byte count
-	;; kick off IN
-	mov dptr, IN2BC
-	mov a, r1
-	jz start_in__done
-	movx @dptr, a
-	;; done
-start_in__done:
-	;acall dump_stat
-	ret
-start_in__do_tx_unthrottle:
-	;; special sequence: send a tx unthrottle message
-	clr DO_TX_UNTHROTTLE
-	clr a
-	mov dps, a
-	mov dptr, IN2BUF
-	mov a, #1
-	movx @dptr, a
-	inc dptr
-	mov a, #2
-	movx @dptr, a
-	mov dptr, IN2BC
-	movx @dptr, a
-	ret
-	
-putchar:
-	clr TI
-	mov SBUF, a
-putchar_wait:
-	jnb TI, putchar_wait
-	clr TI
-	ret
-
-	
-baud_table:			; baud_high, then baud_low
-	;; baud[0]: 110
-	.byte BAUD_HIGH(110)
-	.byte BAUD_LOW(110)
-	;; baud[1]: 300
-	.byte BAUD_HIGH(300)
-	.byte BAUD_LOW(300)
-	;; baud[2]: 1200
-	.byte BAUD_HIGH(1200)
-	.byte BAUD_LOW(1200)
-	;; baud[3]: 2400
-	.byte BAUD_HIGH(2400)
-	.byte BAUD_LOW(2400)
-	;; baud[4]: 4800
-	.byte BAUD_HIGH(4800)
-	.byte BAUD_LOW(4800)
-	;; baud[5]: 9600
-	.byte BAUD_HIGH(9600)
-	.byte BAUD_LOW(9600)
-	;; baud[6]: 19200
-	.byte BAUD_HIGH(19200)
-	.byte BAUD_LOW(19200)
-	;; baud[7]: 38400
-	.byte BAUD_HIGH(38400)
-	.byte BAUD_LOW(38400)
-	;; baud[8]: 57600
-	.byte BAUD_HIGH(57600)
-	.byte BAUD_LOW(57600)
-	;; baud[9]: 115200
-	.byte BAUD_HIGH(115200)
-	.byte BAUD_LOW(115200)
-
-desc_device:
-	.byte 0x12, 0x01, 0x00, 0x01, 0xff, 0xff, 0xff, 0x40
-	.byte 0xcd, 0x06, 0x04, 0x01, 0x89, 0xab, 1, 2, 3, 0x01
-;;; The "real" device id, which must match the host driver, is that
-;;; "0xcd 0x06 0x04 0x01" sequence, which is 0x06cd, 0x0104
-	
-desc_config1:
-	.byte 0x09, 0x02, 0x20, 0x00, 0x01, 0x01, 0x00, 0x80, 0x32
-	.byte 0x09, 0x04, 0x00, 0x00, 0x02, 0xff, 0xff, 0xff, 0x00
-	.byte 0x07, 0x05, 0x82, 0x03, 0x40, 0x00, 0x01
-	.byte 0x07, 0x05, 0x02, 0x02, 0x40, 0x00, 0x00
-
-desc_strings:
-	.word string_langids, string_mfg, string_product, string_serial
-desc_strings_end:
-
-string_langids:	.byte string_langids_end-string_langids
-	.byte 3
-	.word 0
-string_langids_end:
-
-	;; sigh. These strings are Unicode, meaning UTF16? 2 bytes each. Now
-	;; *that* is a pain in the ass to encode. And they are little-endian
-	;; too. Use this perl snippet to get the bytecodes:
-	/* while (<>) {
-	    @c = split(//);
-	    foreach $c (@c) {
-	     printf("0x%02x, 0x00, ", ord($c));
-	    }
-	   }
-	*/
-
-string_mfg:	.byte string_mfg_end-string_mfg
-	.byte 3
-;	.byte "ACME usb widgets"
-	.byte 0x41, 0x00, 0x43, 0x00, 0x4d, 0x00, 0x45, 0x00, 0x20, 0x00, 0x75, 0x00, 0x73, 0x00, 0x62, 0x00, 0x20, 0x00, 0x77, 0x00, 0x69, 0x00, 0x64, 0x00, 0x67, 0x00, 0x65, 0x00, 0x74, 0x00, 0x73, 0x00
-string_mfg_end:
-	
-string_product:	.byte string_product_end-string_product
-	.byte 3
-;	.byte "ACME USB serial widget"
-	.byte 0x41, 0x00, 0x43, 0x00, 0x4d, 0x00, 0x45, 0x00, 0x20, 0x00, 0x55, 0x00, 0x53, 0x00, 0x42, 0x00, 0x20, 0x00, 0x73, 0x00, 0x65, 0x00, 0x72, 0x00, 0x69, 0x00, 0x61, 0x00, 0x6c, 0x00, 0x20, 0x00, 0x77, 0x00, 0x69, 0x00, 0x64, 0x00, 0x67, 0x00, 0x65, 0x00, 0x74, 0x00
-string_product_end:
-	
-string_serial:	.byte string_serial_end-string_serial
-	.byte 3
-;	.byte "47"
-	.byte 0x34, 0x00, 0x37, 0x00
-string_serial_end:
-		
-;;; ring buffer memory
-	;; tx_ring_in+1 is where the next input byte will go
-	;; [tx_ring_out] has been sent
-	;; if tx_ring_in == tx_ring_out, theres no work to do
-	;; there are (tx_ring_in - tx_ring_out) chars to be written
-	;; dont let _in lap _out
-	;;   cannot inc if tx_ring_in+1 == tx_ring_out
-	;;  write [tx_ring_in+1] then tx_ring_in++
-	;;   if (tx_ring_in+1 == tx_ring_out), overflow
-	;;   else tx_ring_in++
-	;;  read/send [tx_ring_out+1], then tx_ring_out++
-
-	;; rx_ring_in works the same way
-	
-	.org 0x1000
-tx_ring:
-	.skip 0x100		; 256 bytes
-rx_ring:
-	.skip 0x100		; 256 bytes
-	
-	
-	.END
-	
--- zfcpdump-kernel-4.4.orig/firmware/keyspan_pda/xircom_pgs.HEX
+++ /dev/null
@@ -1,87 +0,0 @@
-:03000000020200F9
-:0400230002059B0037
-:050030000000000000CB
-:0400430002010000B6
-:100100000202BA000200000002000000020000002B
-:1001100002000000020000000200000002000000D7
-:100120000200000002000000020485000204B90081
-:1002000075815EE4F532F533F530F531F534C20031
-:10021000C201A90074FE901000F0A3D9FC74FD90F7
-:100220001100F0A3D9FC907F9474BFF0907F957477
-:10023000EFF07410907F9EF07400907F98F07440FF
-:10024000907F9DF07400907F97F07482907F9EF075
-:10025000907F957403F0907FAFE0D2E0F07401904E
-:100260007FABF0907FAEF0907FAC7404F0907FADE8
-:100270007404F0907FC9F07407907FAFF074209001
-:100280007F9CF07480907F98F07453F59875C83017
-:100290007B059144D2CA759850D2E8D2AFD2AC74E3
-:1002A00000F586907FD67402F0792E7A007B00DB11
-:1002B000FEDAFAD9F67406F080FEC086C082C083EA
-:1002C000C084C085C0E0E591C2E4F591907FAB7435
-:1002D00001F0907FE8E0F9A3E0FAA3E0FBA3E0FCE3
-:1002E000E95460B4000302035DB4406EBA000B121F
-:1002F0000444400302042602042EBA010302042E21
-:10030000BA020302042EBA0303020468BA041EBB35
-:10031000000A907F95E04402F0020426907F98E066
-:1003200054FDF0907F95E054FDF0020426BA0503D9
-:1003300002042EBA0619BB0008E533D39532020435
-:1003400002BB0108E532C3953302040202042EBA4F
-:1003500007058B3402042602042E02042EBA002064
-:10036000B98010907F00E4F0A3F0907FB57402F0A4
-:10037000020426B9820280EBB9810280E602042ED3
-:10038000BA010FBB000302042EBB010302042602C4
-:10039000042EBA030FBB000302042EBB01030204A8
-:1003A0002602042EBA0656BC010F907FD47406F0C4
-:1003B000907FD5745AF0020426BC0212BB006F90E5
-:1003C0007FD47406F0907FD5746CF0020426BC03D1
-:1003D000297404C39B40576055EB2B90068C2582F3
-:1003E000F58274003583F583E0F9A3E0FA907FD4B9
-:1003F000E9F0907FD5EAF002042602042EBA080F35
-:100400007401907F00F07401907FB5F0020426BA69
-:100410000903020426BA0A057400020402BA0B0397
-:1004200002042602042E907FB47402F08009907FAB
-:10043000B4E04401F08000D0E0D085D084D083D0F7
-:1004400082D08632EB20E71EC3940A5019EB232496
-:1004500046F58274063400F583E0F5CBF5CDA3E0D4
-:10046000F5CAF5CCC322D322B94111EB64FF548005
-:10047000FB907F98E0547F4BF0020426907F9BE036
-:1004800064FF020402C086C082C083C084C085C0ED
-:10049000E0E591C2E4F591907FA97404F074209096
-:1004A0007F9CF01205DC7420907F9CF0D0E0D0851A
-:1004B000D084D083D082D08632C086C082C083C030
-:1004C00084C085C0E07410907F9CF0E591C2E4F593
-:1004D00091907FAA7404F0907FC9E0F9E4F58690CA
-:1004E0007DC0758510853284E005860584F0E5843D
-:1004F000B53302800905320586A3D9EC8000907FD0
-:10050000C9F0B16D7420907F9CF0D0E0D085D0848C
-:10051000D083D082D08632E4F586907FBCE020E1A3
-:100520004B907D00E532F0A3E533F0A3E530F0A376
-:10053000E531F0A3E430000104F0A305869010003B
-:100540007910E0A30586F0A30586D9F6058674FC2C
-:10055000F0A305869011007910E0A30586F0A305AD
-:1005600086D9F6E4F586907FBD7426F0222000132C
-:10057000E532B53301220533758310853382E0F50A
-:1005800099D2007400B5340122E533D39532C39576
-:100590003440F5753400D2010205DCC086C082C04B
-:1005A00083C084C085C0E0309907C299C20012059B
-:1005B000703098051205C6C298D0E0D085D084D09E
-:1005C00083D082D086327583118530820582E59989
-:1005D000F0E582B53101220530B1DC227410907F44
-:1005E0009CF0907FB8E020E13E20013CE530B53141
-:1005F0000122E4F5867583110586907E00F0A3053F
-:10060000867901E530B5310280100531853182E00F
-:100610000586F0A3058609B940E97410907F9CF027
-:10062000907FB9E96001F022C201E4F586907E0076
-:100630007401F0A37402F0907FB9F022C299F59989
-:100640003099FDC29922E55EF63CFD8FFEC8FF643D
-:10065000FFB2FFD9FFEDFFF3FFFA12010001FFFF28
-:10066000FF40CD06040189AB01020301090220000D
-:1006700001010080320904000002FFFFFF000705AE
-:10068000820340000107050202400000069406981C
-:1006900006BA06E8040300002203410043004D00AF
-:1006A000450020007500730062002000770069009B
-:1006B000640067006500740073002E03410043006E
-:1006C0004D004500200055005300420020007300FB
-:1006D00065007200690061006C002000770069000D
-:0E06E0006400670065007400060334003700F4
-:00000001FF
--- zfcpdump-kernel-4.4.orig/firmware/keyspan_pda/xircom_pgs.S
+++ /dev/null
@@ -1,1192 +0,0 @@
-/*  $Id: loop.s,v 1.23 2000/03/20 09:49:06 warner Exp $
- * 
- *  Firmware for the Keyspan PDA Serial Adapter, a USB serial port based on
- *  the EzUSB microcontroller.
- * 
- *  (C) Copyright 2000 Brian Warner <warner@lothar.com>
- * 
- * 	This program is free software; you can redistribute it and/or modify
- * 	it under the terms of the GNU General Public License as published by
- * 	the Free Software Foundation; either version 2 of the License, or
- * 	(at your option) any later version.
- * 
- *  "Keyspan PDA Serial Adapter" is probably a copyright of Keyspan, the
- *  company.
- * 
- *  This serial adapter is basically an EzUSB chip and an RS-232 line driver
- *  in a little widget that has a DB-9 on one end and a USB plug on the other.
- *  It uses the EzUSB's internal UART0 (using the pins from Port C) and timer2
- *  as a baud-rate generator. The wiring is:
- *   PC0/RxD0 <- rxd (DB9 pin 2)         PC4 <- dsr pin 6
- *   PC1/TxD0 -> txd pin 3               PC5 <- ri  pin 9
- *   PC2      -> rts pin 7               PC6 <- dcd pin 1
- *   PC3      <- cts pin 8               PC7 -> dtr pin 4
- *   PB1 -> line driver standby
- *
- *  The EzUSB register constants below come from their excellent documentation
- *  and sample code (which used to be available at www.anchorchips.com, but
- *  that has now been absorbed into Cypress' site and the CD-ROM contents
- *  don't appear to be available online anymore). If we get multiple
- *  EzUSB-based drivers into the kernel, it might be useful to pull them out
- *  into a separate .h file.
- * 
- * THEORY OF OPERATION:
- *
- *   There are two 256-byte ring buffers, one for tx, one for rx.
- *
- *   EP2out is pure tx data. When it appears, the data is copied into the tx
- *   ring and serial transmission is started if it wasn't already running. The
- *   "tx buffer empty" interrupt may kick off another character if the ring
- *   still has data. If the host is tx-blocked because the ring filled up,
- *   it will request a "tx unthrottle" interrupt. If sending a serial character
- *   empties the ring below the desired threshold, we set a bit that will send
- *   up the tx unthrottle message as soon as the rx buffer becomes free.
- *
- *   EP2in (interrupt) is used to send both rx chars and rx status messages
- *   (only "tx unthrottle" at this time) back up to the host. The first byte
- *   of the rx message indicates data (0) or status msg (1). Status messages
- *   are sent before any data.
- *
- *   Incoming serial characters are put into the rx ring by the serial
- *   interrupt, and the EP2in buffer sent if it wasn't already in transit.
- *   When the EP2in buffer returns, the interrupt prompts us to send more
- *   rx chars (or status messages) if they are pending.
- *
- *   Device control happens through "vendor specific" control messages on EP0.
- *   All messages are destined for the "Interface" (with the index always 0,
- *   so that if their two-port device might someday use similar firmware, we
- *   can use index=1 to refer to the second port). The messages defined are:
- *
- *    bRequest = 0 : set baud/bits/parity
- *               1 : unused
- *               2 : reserved for setting HW flow control (CTSRTS)
- *               3 : get/set "modem info" (pin states: DTR, RTS, DCD, RI, etc)
- *               4 : set break (on/off)
- *               5 : reserved for requesting interrupts on pin state change
- *               6 : query buffer room or chars in tx buffer
- *               7 : request tx unthrottle interrupt
- *
- *  The host-side driver is set to recognize the device ID values stashed in
- *  serial EEPROM (0x06cd, 0x0103), program this firmware into place, then
- *  start it running. This firmware will use EzUSB's "renumeration" trick by
- *  simulating a bus disconnect, then reconnect with a different device ID
- *  (encoded in the desc_device descriptor below). The host driver then
- *  recognizes the new device ID and glues it to the real serial driver code.
- *
- * USEFUL DOCS:
- *  EzUSB Technical Reference Manual: <http://www.cypress.com/>
- *  8051 manuals: everywhere, but try www.dalsemi.com because the EzUSB is
- *   basically the Dallas enhanced 8051 code. Remember that the EzUSB IO ports
- *   use totally different registers!
- *  USB 1.1 spec: www.usb.org
- *
- * HOW TO BUILD:
- *  gcc -x assembler-with-cpp -P -E -o keyspan_pda.asm keyspan_pda.s
- *  as31 -l keyspan_pda.asm
- *  mv keyspan_pda.obj keyspan_pda.hex
- *  perl ezusb_convert.pl keyspan_pda < keyspan_pda.hex > keyspan_pda_fw.h
- * Get as31 from <http://www.pjrc.com/tech/8051/index.html>, and hack on it
- * a bit to make it build.
- *
- * THANKS:
- *  Greg Kroah-Hartman, for coordinating the whole usb-serial thing.
- *  AnchorChips, for making such an incredibly useful little microcontroller.
- *  KeySpan, for making a handy, cheap ($40) widget that was so easy to take
- *           apart and trace with an ohmmeter.
- *
- * TODO:
- *  lots. grep for TODO. Interrupt safety needs stress-testing. Better flow
- *  control. Interrupting host upon change in DCD, etc, counting transitions.
- *  Need to find a safe device id to use (the one used by the Keyspan firmware
- *  under Windows would be ideal.. can anyone figure out what it is?). Parity.
- *  More baud rates. Oh, and the string-descriptor-length silicon bug
- *  workaround should be implemented, but I'm lazy, and the consequence is
- *  that the device name strings that show up in your kernel log will have
- *  lots of trailing binary garbage in them (appears as ????). Device strings
- *  should be made more accurate.
- *
- * Questions, bugs, patches to Brian.
- *
- *  -Brian Warner <warner@lothar.com>
- *
- */
-	
-#define HIGH(x) (((x) & 0xff00) / 256)
-#define LOW(x) ((x) & 0xff)
-
-#define dpl1 0x84
-#define dph1 0x85
-#define dps 0x86
-
-;;; our bit assignments
-#define TX_RUNNING 0
-#define DO_TX_UNTHROTTLE 1
-	
-	;; stack from 0x60 to 0x7f: should really set SP to 0x60-1, not 0x60
-#define STACK #0x60-1
-
-#define EXIF 0x91
-#define EIE 0xe8
-	.flag EUSB, EIE.0
-	.flag ES0, IE.4
-
-#define EP0CS #0x7fb4
-#define EP0STALLbit #0x01
-#define IN0BUF #0x7f00
-#define IN0BC #0x7fb5
-#define OUT0BUF #0x7ec0
-#define OUT0BC #0x7fc5		
-#define IN2BUF #0x7e00
-#define IN2BC #0x7fb9
-#define IN2CS #0x7fb8
-#define OUT2BC #0x7fc9
-#define OUT2CS #0x7fc8
-#define OUT2BUF #0x7dc0
-#define IN4BUF #0x7d00
-#define IN4BC #0x7fbd
-#define IN4CS #0x7fbc
-#define OEB #0x7f9d
-#define OUTB #0x7f97
-#define OEC #0x7f9e
-#define OUTC #0x7f98
-#define PINSC #0x7f9b
-#define PORTBCFG #0x7f94
-#define PORTCCFG #0x7f95
-#define OEA	#0x7f9c
-#define IN07IRQ #0x7fa9
-#define OUT07IRQ #0x7faa
-#define IN07IEN #0x7fac
-#define OUT07IEN #0x7fad
-#define USBIRQ #0x7fab
-#define USBIEN #0x7fae
-#define USBBAV #0x7faf
-#define USBCS #0x7fd6
-#define SUDPTRH #0x7fd4
-#define SUDPTRL #0x7fd5
-#define SETUPDAT #0x7fe8
-		
-	;; usb interrupt : enable is EIE.0 (0xe8), flag is EXIF.4 (0x91)
-
-	.org 0
-	ljmp start
-	;; interrupt vectors
-	.org 23H
-	ljmp serial_int
-	.byte 0
-	
-	.org 43H
-	ljmp USB_Jump_Table
-	.byte 0			; filled in by the USB core
-
-;;; local variables. These are not initialized properly: do it by hand.
-	.org 30H
-rx_ring_in:	.byte 0
-rx_ring_out:	.byte 0
-tx_ring_in:	.byte 0
-tx_ring_out:	.byte 0
-tx_unthrottle_threshold:	.byte 0
-		
-	.org 0x100H		; wants to be on a page boundary
-USB_Jump_Table:
-	ljmp	ISR_Sudav	; Setup Data Available
-	.byte 0
-	ljmp	0		; Start of Frame
-	.byte 0
-	ljmp	0		; Setup Data Loading
-	.byte 0
-	ljmp	0		; Global Suspend
-	.byte 	0
-	ljmp	0		; USB Reset  	
-	.byte	0
-	ljmp	0		; Reserved
-	.byte	0
-	ljmp	0		; End Point 0 In
-	.byte	0
-	ljmp	0		; End Point 0 Out
-	.byte	0
-	ljmp	0		; End Point 1 In
-	.byte	0
-	ljmp	0		; End Point 1 Out
-	.byte	0
-	ljmp	ISR_Ep2in
-	.byte	0
-	ljmp	ISR_Ep2out
-	.byte	0
-
-
-	.org 0x200
-		
-start:	mov SP,STACK-1 ; set stack
-	;; clear local variables
-	clr a
-	mov tx_ring_in, a
-	mov tx_ring_out, a
-	mov rx_ring_in, a
-	mov rx_ring_out, a
-	mov tx_unthrottle_threshold, a
-	clr TX_RUNNING
-	clr DO_TX_UNTHROTTLE
-	
-	;; clear fifo with "fe"
-	mov r1, 0
-	mov a, #0xfe
-	mov dptr, #tx_ring
-clear_tx_ring_loop:
-	movx @dptr, a
-	inc dptr
-	djnz r1, clear_tx_ring_loop
-
-	mov a, #0xfd
-	mov dptr, #rx_ring
-clear_rx_ring_loop:
-	movx @dptr, a
-	inc dptr
-	djnz r1, clear_rx_ring_loop
-
-;;; turn on the RS-232 driver chip (bring the STANDBY pin low)
-;;; on Xircom the STANDBY is wired to PB6 and PC4 
-	mov dptr, PORTBCFG
-        mov a, #0xBf
-        movx @dptr, a
-	mov dptr, PORTCCFG
-        mov a, #0xef
-        movx @dptr, a
-	
-	;; set OEC.4
-        mov a, #0x10
-        mov dptr,OEC
-        movx @dptr,a
-
-        ;; clear PC4
-        mov a, #0x00
-        mov dptr,OUTC
-        movx @dptr,a
-
-	;; set OEB.6
-	mov a, #0x40
-	mov dptr,OEB
-	movx @dptr,a
-
-	;; clear PB6
-	mov a, #0x00
-	mov dptr,OUTB
-	movx @dptr,a
-
-	;; set OEC.[17]
-	mov a, #0x82
-	mov dptr,OEC
-	movx @dptr,a
-
-
-	;; set PORTCCFG.[01] to route TxD0,RxD0 to serial port
-	mov dptr, PORTCCFG
-	mov a, #0x03
-	movx @dptr, a
-	
-	;; set up interrupts, autovectoring
-	;; set BKPT
-	mov dptr, USBBAV
-	movx a,@dptr
-	setb acc.0		; AVEN bit to 0
-	movx @dptr, a
-
-	mov a,#0x01		; enable SUDAV:	setup data available (for ep0)
-	mov dptr, USBIRQ
-	movx @dptr, a		; clear SUDAVI
-	mov dptr, USBIEN
-	movx @dptr, a
-	
-	mov dptr, IN07IEN
-	mov a,#0x04		; enable IN2 int
-	movx @dptr, a
-	
-	mov dptr, OUT07IEN
-	mov a,#0x04		; enable OUT2 int
-	movx @dptr, a
-	mov dptr, OUT2BC
-	movx @dptr, a		; arm OUT2
-
-;;	mov a, #0x84		; turn on RTS, DTR
-;;	mov dptr,OUTC
-;;	movx @dptr, a
-
-	mov a, #0x7             ; turn on  DTR
-        mov dptr,USBBAV
-        movx @dptr, a
-
-	mov a, #0x20             ; turn on the RED led 
-        mov dptr,OEA
-        movx @dptr, a
-
-	mov a, #0x80            ; turn on  RTS
-        mov dptr,OUTC
-        movx @dptr, a
-
-	;; setup the serial port. 9600 8N1.
-	mov a,#0x53		; mode 1, enable rx, clear int
-	mov SCON, a
-	;;  using timer2, in 16-bit baud-rate-generator mode
-	;;   (xtal 12MHz, internal fosc 24MHz)
-	;;  RCAP2H,RCAP2L = 65536 - fosc/(32*baud)
-	;;  57600: 0xFFF2.F, say 0xFFF3
-	;;   9600: 0xFFB1.E, say 0xFFB2
-	;;    300: 0xF63C
-#define BAUD 9600
-#define BAUD_TIMEOUT(rate) (65536 - (24 * 1000 * 1000) / (32 * rate))
-#define BAUD_HIGH(rate) HIGH(BAUD_TIMEOUT(rate))
-#define BAUD_LOW(rate) LOW(BAUD_TIMEOUT(rate))
-		
-	mov T2CON, #030h	; rclk=1,tclk=1,cp=0,tr2=0(enable later)
-	mov r3, #5
-	acall set_baud
-	setb TR2
-	mov SCON, #050h
-	
-#if 0
-	mov r1, #0x40
-	mov a, #0x41
-send:	
-	mov SBUF, a
-	inc a
-	anl a, #0x3F
-	orl a, #0x40
-;	xrl a, #0x02
-wait1:	
-	jnb TI, wait1
-	clr TI
-	djnz r1, send
-;done:	sjmp done
-
-#endif
-	
-	setb EUSB
-	setb EA
-	setb ES0
-	;acall dump_stat
-
-	;; hey, what say we RENUMERATE! (TRM p.62)
-	mov a, #0
-	mov dps, a
-	mov dptr, USBCS
-	mov a, #0x02		; DISCON=0, DISCOE=0, RENUM=1
-	movx @dptr, a
-	;; now presence pin is floating, simulating disconnect. wait 0.5s
-	mov r1, #46
-renum_wait1:
-	mov r2, #0
-renum_wait2:
-	mov r3, #0
-renum_wait3:
-	djnz r3, renum_wait3
-	djnz r2, renum_wait2
-	djnz r1, renum_wait1	; wait about n*(256^2) 6MHz clocks
-	mov a, #0x06		; DISCON=0, DISCOE=1, RENUM=1
-	movx @dptr, a
-	;; we are back online. the host device will now re-query us
-	
-	
-main:	sjmp main
-
-	
-
-ISR_Sudav:
-	push dps
-	push dpl
-	push dph
-	push dpl1
-	push dph1
-	push acc
-	mov a,EXIF
-	clr acc.4
-	mov EXIF,a		; clear INT2 first
-	mov dptr, USBIRQ	; clear USB int
-	mov a,#01h
-	movx @dptr,a
-
-	;; get request type
-	mov dptr, SETUPDAT
-	movx a, @dptr
-	mov r1, a		; r1 = bmRequestType
-	inc dptr
-	movx a, @dptr
-	mov r2, a		; r2 = bRequest
-	inc dptr
-	movx a, @dptr
-	mov r3, a		; r3 = wValueL
-	inc dptr
-	movx a, @dptr
-	mov r4, a		; r4 = wValueH
-
-	;; main switch on bmRequest.type: standard or vendor
-	mov a, r1
-	anl a, #0x60
-	cjne a, #0x00, setup_bmreq_type_not_standard
-	;; standard request: now main switch is on bRequest
-	ljmp setup_bmreq_is_standard
-	
-setup_bmreq_type_not_standard:	
-	;; a still has bmreq&0x60
-	cjne a, #0x40, setup_bmreq_type_not_vendor
-	;; Anchor reserves bRequest 0xa0-0xaf, we use small ones
-	;; switch on bRequest. bmRequest will always be 0x41 or 0xc1
-	cjne r2, #0x00, setup_ctrl_not_00
-	;; 00 is set baud, wValue[0] has baud rate index
-	lcall set_baud		; index in r3, carry set if error
-	jc setup_bmreq_type_not_standard__do_stall
-	ljmp setup_done_ack
-setup_bmreq_type_not_standard__do_stall:
-	ljmp setup_stall
-setup_ctrl_not_00:
-	cjne r2, #0x01, setup_ctrl_not_01
-	;; 01 is reserved for set bits (parity). TODO
-	ljmp setup_stall
-setup_ctrl_not_01:
-	cjne r2, #0x02, setup_ctrl_not_02
-	;; 02 is set HW flow control. TODO
-	ljmp setup_stall
-setup_ctrl_not_02:
-	cjne r2, #0x03, setup_ctrl_not_03
-	;; 03 is control pins (RTS, DTR).
-	ljmp control_pins	; will jump to setup_done_ack,
-				;  or setup_return_one_byte
-setup_ctrl_not_03:
-	cjne r2, #0x04, setup_ctrl_not_04
-	;; 04 is send break (really "turn break on/off"). TODO
-	cjne r3, #0x00, setup_ctrl_do_break_on
-	;; do break off: restore PORTCCFG.1 to reconnect TxD0 to serial port
-	mov dptr, PORTCCFG
-	movx a, @dptr
-	orl a, #0x02
-	movx @dptr, a
-	ljmp setup_done_ack
-setup_ctrl_do_break_on:
-	;; do break on: clear PORTCCFG.0, set TxD high(?) (b1 low)
-	mov dptr, OUTC
-	movx a, @dptr
-	anl a, #0xfd		; ~0x02
-	movx @dptr, a
-	mov dptr, PORTCCFG
-	movx a, @dptr
-	anl a, #0xfd		; ~0x02
-	movx @dptr, a
-	ljmp setup_done_ack
-setup_ctrl_not_04:
-	cjne r2, #0x05, setup_ctrl_not_05
-	;; 05 is set desired interrupt bitmap. TODO
-	ljmp setup_stall
-setup_ctrl_not_05:
-	cjne r2, #0x06, setup_ctrl_not_06
-	;; 06 is query room
-	cjne r3, #0x00, setup_ctrl_06_not_00
-	;; 06, wValue[0]=0 is query write_room
-	mov a, tx_ring_out
-	setb c
-	subb a, tx_ring_in	; out-1-in = 255 - (in-out)
-	ljmp setup_return_one_byte
-setup_ctrl_06_not_00:
-	cjne r3, #0x01, setup_ctrl_06_not_01
-	;; 06, wValue[0]=1 is query chars_in_buffer
-	mov a, tx_ring_in
-	clr c
-	subb a, tx_ring_out	; in-out
-	ljmp setup_return_one_byte
-setup_ctrl_06_not_01:	
-	ljmp setup_stall
-setup_ctrl_not_06:
-	cjne r2, #0x07, setup_ctrl_not_07
-	;; 07 is request tx unthrottle interrupt
-	mov tx_unthrottle_threshold, r3; wValue[0] is threshold value
-	ljmp setup_done_ack
-setup_ctrl_not_07:
-	ljmp setup_stall
-	
-setup_bmreq_type_not_vendor:
-	ljmp setup_stall
-
-
-setup_bmreq_is_standard:	
-	cjne r2, #0x00, setup_breq_not_00
-	;; 00:	Get_Status (sub-switch on bmRequestType: device, ep, int)
-	cjne r1, #0x80, setup_Get_Status_not_device
-	;; Get_Status(device)
-	;;  are we self-powered? no. can we do remote wakeup? no
-	;;   so return two zero bytes. This is reusable
-setup_return_two_zero_bytes:
-	mov dptr, IN0BUF
-	clr a
-	movx @dptr, a
-	inc dptr
-	movx @dptr, a
-	mov dptr, IN0BC
-	mov a, #2
-	movx @dptr, a
-	ljmp setup_done_ack
-setup_Get_Status_not_device:
-	cjne r1, #0x82, setup_Get_Status_not_endpoint
-	;; Get_Status(endpoint)
-	;;  must get stall bit for ep[wIndexL], return two bytes, bit in lsb 0
-	;; for now: cheat. TODO
-	sjmp setup_return_two_zero_bytes
-setup_Get_Status_not_endpoint:
-	cjne r1, #0x81, setup_Get_Status_not_interface
-	;; Get_Status(interface): return two zeros
-	sjmp setup_return_two_zero_bytes
-setup_Get_Status_not_interface:	
-	ljmp setup_stall
-	
-setup_breq_not_00:
-	cjne r2, #0x01, setup_breq_not_01
-	;; 01:	Clear_Feature (sub-switch on wValueL: stall, remote wakeup)
-	cjne r3, #0x00, setup_Clear_Feature_not_stall
-	;; Clear_Feature(stall). should clear a stall bit. TODO
-	ljmp setup_stall
-setup_Clear_Feature_not_stall:
-	cjne r3, #0x01, setup_Clear_Feature_not_rwake
-	;; Clear_Feature(remote wakeup). ignored.
-	ljmp setup_done_ack
-setup_Clear_Feature_not_rwake:
-	ljmp setup_stall
-	
-setup_breq_not_01:
-	cjne r2, #0x03, setup_breq_not_03
-	;; 03:	Set_Feature (sub-switch on wValueL: stall, remote wakeup)
-	cjne r3, #0x00, setup_Set_Feature_not_stall
-	;; Set_Feature(stall). Should set a stall bit. TODO
-	ljmp setup_stall
-setup_Set_Feature_not_stall:
-	cjne r3, #0x01, setup_Set_Feature_not_rwake
-	;; Set_Feature(remote wakeup). ignored.
-	ljmp setup_done_ack
-setup_Set_Feature_not_rwake:
-	ljmp setup_stall
-	
-setup_breq_not_03:	
-	cjne r2, #0x06, setup_breq_not_06
-	;; 06:	Get_Descriptor (s-switch on wValueH: dev, config[n], string[n])
-	cjne r4, #0x01, setup_Get_Descriptor_not_device
-	;; Get_Descriptor(device)
-	mov dptr, SUDPTRH
-	mov a, #HIGH(desc_device)
-	movx @dptr, a
-	mov dptr, SUDPTRL
-	mov a, #LOW(desc_device)
-	movx @dptr, a
-	ljmp setup_done_ack
-setup_Get_Descriptor_not_device:
-	cjne r4, #0x02, setup_Get_Descriptor_not_config
-	;; Get_Descriptor(config[n])
-	cjne r3, #0x00, setup_stall; only handle n==0
-	;; Get_Descriptor(config[0])
-	mov dptr, SUDPTRH
-	mov a, #HIGH(desc_config1)
-	movx @dptr, a
-	mov dptr, SUDPTRL
-	mov a, #LOW(desc_config1)
-	movx @dptr, a
-	ljmp setup_done_ack
-setup_Get_Descriptor_not_config:
-	cjne r4, #0x03, setup_Get_Descriptor_not_string
-	;; Get_Descriptor(string[wValueL])
-	;;  if (wValueL >= maxstrings) stall
-	mov a, #((desc_strings_end-desc_strings)/2)
-	clr c
-	subb a,r3		; a=4, r3 = 0..3 . if a<=0 then stall
-	jc  setup_stall
-	jz  setup_stall
-	mov a, r3
-	add a, r3		; a = 2*wValueL
-	mov dptr, #desc_strings
-	add a, dpl
-	mov dpl, a
-	mov a, #0
-	addc a, dph
-	mov dph, a		; dph = desc_strings[a]. big endian! (handy)
-	;; it looks like my adapter uses a revision of the EZUSB that
-	;; contains "rev D errata number 8", as hinted in the EzUSB example
-	;; code. I cannot find an actual errata description on the Cypress
-	;; web site, but from the example code it looks like this bug causes
-	;; the length of string descriptors to be read incorrectly, possibly
-	;; sending back more characters than the descriptor has. The workaround
-	;; is to manually send out all of the data. The consequence of not
-	;; using the workaround is that the strings gathered by the kernel
-	;; driver are too long and are filled with trailing garbage (including
-	;; leftover strings). Writing this out by hand is a nuisance, so for
-	;; now I will just live with the bug.
-	movx a, @dptr
-	mov r1, a
-	inc dptr
-	movx a, @dptr
-	mov r2, a
-	mov dptr, SUDPTRH
-	mov a, r1
-	movx @dptr, a
-	mov dptr, SUDPTRL
-	mov a, r2
-	movx @dptr, a
-	;; done
-	ljmp setup_done_ack
-	
-setup_Get_Descriptor_not_string:
-	ljmp setup_stall
-	
-setup_breq_not_06:
-	cjne r2, #0x08, setup_breq_not_08
-	;; Get_Configuration. always 1. return one byte.
-	;; this is reusable
-	mov a, #1
-setup_return_one_byte:	
-	mov dptr, IN0BUF
-	movx @dptr, a
-	mov a, #1
-	mov dptr, IN0BC
-	movx @dptr, a
-	ljmp setup_done_ack
-setup_breq_not_08:
-	cjne r2, #0x09, setup_breq_not_09
-	;; 09: Set_Configuration. ignored.
-	ljmp setup_done_ack
-setup_breq_not_09:
-	cjne r2, #0x0a, setup_breq_not_0a
-	;; 0a: Get_Interface. get the current altsetting for int[wIndexL]
-	;;  since we only have one interface, ignore wIndexL, return a 0
-	mov a, #0
-	ljmp setup_return_one_byte
-setup_breq_not_0a:
-	cjne r2, #0x0b, setup_breq_not_0b
-	;; 0b: Set_Interface. set altsetting for interface[wIndexL]. ignored
-	ljmp setup_done_ack
-setup_breq_not_0b:
-	ljmp setup_stall
-
-		
-setup_done_ack:	
-	;; now clear HSNAK
-	mov dptr, EP0CS
-	mov a, #0x02
-	movx @dptr, a
-	sjmp setup_done
-setup_stall:	
-	;; unhandled. STALL
-	;EP0CS |= bmEPSTALL
-	mov dptr, EP0CS
-	movx a, @dptr
-	orl a, EP0STALLbit
-	movx @dptr, a
-	sjmp setup_done
-	
-setup_done:	
-	pop acc
-	pop dph1
-	pop dpl1
-	pop dph
-	pop dpl
-	pop dps
-	reti
-
-;;; ==============================================================
-	
-set_baud:			; baud index in r3
-	;; verify a < 10
-	mov a, r3
-	jb ACC.7, set_baud__badbaud
-	clr c
-	subb a, #10
-	jnc set_baud__badbaud
-	mov a, r3
-	rl a			; a = index*2
-	add a, #LOW(baud_table)
-	mov dpl, a
-	mov a, #HIGH(baud_table)
-	addc a, #0
-	mov dph, a
-	;; TODO: shut down xmit/receive
-	;; TODO: wait for current xmit char to leave
-	;; TODO: shut down timer to avoid partial-char glitch
-	movx a,@dptr		; BAUD_HIGH
-	mov RCAP2H, a
-	mov TH2, a
-	inc dptr
-	movx a,@dptr		; BAUD_LOW
-	mov RCAP2L, a
-	mov TL2, a
-	;; TODO: restart xmit/receive
-	;; TODO: reenable interrupts, resume tx if pending
-	clr c			; c=0: success
-	ret
-set_baud__badbaud:
-	setb c			; c=1: failure
-	ret
-	
-;;; ==================================================
-control_pins:
-	cjne r1, #0x41, control_pins_in
-control_pins_out:
-		;TODO BKPT is DTR
-	mov a, r3 ; wValue[0] holds new bits:	b7 is new RTS
-	xrl a, #0xff		; 1 means active, 0V, +12V ?
-	anl a, #0x80
-	mov r3, a
-	mov dptr, OUTC
-	movx a, @dptr		; only change bit 7 
-	anl a, #0x7F		; ~0x84
-	orl a, r3
-	movx @dptr, a		; other pins are inputs, bits ignored
-	ljmp setup_done_ack
-control_pins_in:
-	mov dptr, PINSC
-	movx a, @dptr
-	xrl a, #0xff
-	ljmp setup_return_one_byte
-
-;;; ========================================
-	
-ISR_Ep2in:
-	push dps
-	push dpl
-	push dph
-	push dpl1
-	push dph1
-	push acc
-	mov a,EXIF
-	clr acc.4
-	mov EXIF,a		; clear INT2 first
-	mov dptr, IN07IRQ	; clear USB int
-	mov a,#04h
-	movx @dptr,a
-
-	mov a, #0x20             ; Turn off the green LED
-        mov dptr,OEA
-        movx @dptr, a
-
-
-	;; do stuff
-	lcall start_in
-
-	mov a, #0x20             ; Turn off the green LED
-        mov dptr,OEA
-        movx @dptr, a
-
-
-	
-	pop acc
-	pop dph1
-	pop dpl1
-	pop dph
-	pop dpl
-	pop dps
-	reti
-
-ISR_Ep2out:
-	push dps
-	push dpl
-	push dph
-	push dpl1
-	push dph1
-	push acc
-
-        mov a, #0x10             ; Turn the green LED
-        mov dptr,OEA
-        movx @dptr, a
-
-
-
-	mov a,EXIF
-	clr acc.4
-	mov EXIF,a		; clear INT2 first
-	mov dptr, OUT07IRQ	; clear USB int
-	mov a,#04h
-	movx @dptr,a
-
-	;; do stuff
-
-	;; copy data into buffer. for now, assume we will have enough space
-	mov dptr, OUT2BC	; get byte count
-	movx a,@dptr
-	mov r1, a
-	clr a
-	mov dps, a
-	mov dptr, OUT2BUF	; load DPTR0 with source
-	mov dph1, #HIGH(tx_ring)	; load DPTR1 with target
-	mov dpl1, tx_ring_in
-OUT_loop:
-	movx a,@dptr		; read
-	inc dps			; switch to DPTR1: target
-	inc dpl1		; target = tx_ring_in+1
-	movx @dptr,a		; store
-	mov a,dpl1
-	cjne a, tx_ring_out, OUT_no_overflow
-	sjmp OUT_overflow
-OUT_no_overflow:	
-	inc tx_ring_in		; tx_ring_in++
-	inc dps			; switch to DPTR0: source
-	inc dptr
-	djnz r1, OUT_loop
-	sjmp OUT_done
-OUT_overflow:
-	;; signal overflow
-	;; fall through
-OUT_done:	
-	;; ack
-	mov dptr,OUT2BC
-	movx @dptr,a
-
-	;; start tx
-	acall maybe_start_tx
-	;acall dump_stat
-
-        mov a, #0x20             ; Turn off the green LED
-        mov dptr,OEA
-        movx @dptr, a
-	
-	pop acc
-	pop dph1
-	pop dpl1
-	pop dph
-	pop dpl
-	pop dps
-	reti
-
-dump_stat:
-	;; fill in EP4in with a debugging message:
-	;;   tx_ring_in, tx_ring_out, rx_ring_in, rx_ring_out
-	;;   tx_active
-	;;   tx_ring[0..15]
-	;;   0xfc
-	;;   rx_ring[0..15]
-	clr a
-	mov dps, a
-	
-	mov dptr, IN4CS
-	movx a, @dptr
-	jb acc.1, dump_stat__done; busy: cannot dump, old one still pending
-	mov dptr, IN4BUF
-	
-	mov a, tx_ring_in
-	movx @dptr, a
-	inc dptr
-	mov a, tx_ring_out
-	movx @dptr, a
-	inc dptr
-
-	mov a, rx_ring_in
-	movx @dptr, a
-	inc dptr
-	mov a, rx_ring_out
-	movx @dptr, a
-	inc dptr
-	
-	clr a
-	jnb TX_RUNNING, dump_stat__no_tx_running
-	inc a
-dump_stat__no_tx_running:
-	movx @dptr, a
-	inc dptr
-	;; tx_ring[0..15]
-	inc dps
-	mov dptr, #tx_ring	; DPTR1: source
-	mov r1, #16
-dump_stat__tx_ring_loop:
-	movx a, @dptr
-	inc dptr
-	inc dps
-	movx @dptr, a
-	inc dptr
-	inc dps
-	djnz r1, dump_stat__tx_ring_loop
-	inc dps
-	
-	mov a, #0xfc
-	movx @dptr, a
-	inc dptr
-	
-	;; rx_ring[0..15]
-	inc dps
-	mov dptr, #rx_ring	; DPTR1: source
-	mov r1, #16
-dump_stat__rx_ring_loop:
-	movx a, @dptr
-	inc dptr
-	inc dps
-	movx @dptr, a
-	inc dptr
-	inc dps
-	djnz r1, dump_stat__rx_ring_loop
-	
-	;; now send it
-	clr a
-	mov dps, a
-	mov dptr, IN4BC
-	mov a, #38
-	movx @dptr, a
-dump_stat__done:	
-	ret
-		
-;;; ============================================================
-	
-maybe_start_tx:
-	;; make sure the tx process is running.
-	jb TX_RUNNING, start_tx_done
-start_tx:
-	;; is there work to be done?
-	mov a, tx_ring_in
-	cjne a,tx_ring_out, start_tx__work
-	ret			; no work
-start_tx__work:	
-	;; tx was not running. send the first character, setup the TI int
-	inc tx_ring_out		; [++tx_ring_out]
-	mov dph, #HIGH(tx_ring)
-	mov dpl, tx_ring_out
-	movx a, @dptr
-	mov sbuf, a
-	setb TX_RUNNING
-start_tx_done:
-	;; can we unthrottle the host tx process?
-	;;  step 1: do we care?
-	mov a, #0
-	cjne a, tx_unthrottle_threshold, start_tx__maybe_unthrottle_tx
-	;; nope
-start_tx_really_done:
-	ret
-start_tx__maybe_unthrottle_tx:
-	;;  step 2: is there now room?
-	mov a, tx_ring_out
-	setb c
-	subb a, tx_ring_in
-	;; a is now write_room. If thresh >= a, we can unthrottle
-	clr c
-	subb a, tx_unthrottle_threshold
-	jc start_tx_really_done	; nope
-	;; yes, we can unthrottle. remove the threshold and mark a request
-	mov tx_unthrottle_threshold, #0
-	setb DO_TX_UNTHROTTLE
-	;; prod rx, which will actually send the message when in2 becomes free
-	ljmp start_in
-	
-
-serial_int:
-	push dps
-	push dpl
-	push dph
-	push dpl1
-	push dph1
-	push acc
-	jnb TI, serial_int__not_tx
-	;; tx finished. send another character if we have one
-	clr TI			; clear int
-	clr TX_RUNNING
-	lcall start_tx
-serial_int__not_tx:
-	jnb RI, serial_int__not_rx
-	lcall get_rx_char
-	clr RI			; clear int
-serial_int__not_rx:	
-	;; return
-	pop acc
-	pop dph1
-	pop dpl1
-	pop dph
-	pop dpl
-	pop dps
-	reti
-
-get_rx_char:
-	mov dph, #HIGH(rx_ring)
-	mov dpl, rx_ring_in
-	inc dpl			; target = rx_ring_in+1
-	mov a, sbuf
-	movx @dptr, a
-	;; check for overflow before incrementing rx_ring_in
-	mov a, dpl
-	cjne a, rx_ring_out, get_rx_char__no_overflow
-	;; signal overflow
-	ret
-get_rx_char__no_overflow:	
-	inc rx_ring_in
-	;; kick off USB INpipe
-	acall start_in
-	ret
-
-start_in:
-	;; check if the inpipe is already running.
-	mov  a,#0x10
-	mov dptr, OEA
-	movx @dptr,a
-
-	mov dptr, IN2CS
-	movx a, @dptr
-	jb acc.1, start_in__done; int will handle it
-	jb DO_TX_UNTHROTTLE, start_in__do_tx_unthrottle
-	;; see if there is any work to do. a serial interrupt might occur
-	;; during this sequence?
-	mov a, rx_ring_in
-	cjne a, rx_ring_out, start_in__have_work
-	ret			; nope
-start_in__have_work:	
-	;; now copy as much data as possible into the pipe. 63 bytes max.
-	clr a
-	mov dps, a
-	mov dph, #HIGH(rx_ring)	; load DPTR0 with source
-	inc dps
-	mov dptr, IN2BUF	; load DPTR1 with target
-	movx @dptr, a		; in[0] signals that rest of IN is rx data
-	inc dptr
-	inc dps
-	;; loop until we run out of data, or we have copied 64 bytes
-	mov r1, #1		; INbuf size counter
-start_in__loop:
-	mov a, rx_ring_in
-	cjne a, rx_ring_out, start_inlocal_irq_enablell_copying
-	sjmp start_in__kick
-start_inlocal_irq_enablell_copying:
-	inc rx_ring_out
-	mov dpl, rx_ring_out
-	movx a, @dptr
-	inc dps
-	movx @dptr, a		; write into IN buffer
-	inc dptr
-	inc dps
-	inc r1
-	cjne r1, #64, start_in__loop; loop
-start_in__kick:
-	;; either we ran out of data, or we copied 64 bytes. r1 has byte count
-	;; kick off IN
-	mov a, #0x10             ; Turn the green LED
-        mov dptr,OEA
-        movx @dptr, a
-	mov dptr, IN2BC
-	mov a, r1
-	jz start_in__done
-	movx @dptr, a
-	;; done
-start_in__done:
-	;acall dump_stat
-	ret
-start_in__do_tx_unthrottle:
-	;; special sequence: send a tx unthrottle message
-	clr DO_TX_UNTHROTTLE
-	clr a
-	mov dps, a
-	mov dptr, IN2BUF
-	mov a, #1
-	movx @dptr, a
-	inc dptr
-	mov a, #2
-	movx @dptr, a
-	mov dptr, IN2BC
-	movx @dptr, a
-	ret
-	
-putchar:
-	clr TI
-	mov SBUF, a
-putchar_wait:
-	jnb TI, putchar_wait
-	clr TI
-	ret
-
-	
-baud_table:			; baud_high, then baud_low
-	;; baud[0]: 110
-	.byte BAUD_HIGH(110)
-	.byte BAUD_LOW(110)
-	;; baud[1]: 300
-	.byte BAUD_HIGH(300)
-	.byte BAUD_LOW(300)
-	;; baud[2]: 1200
-	.byte BAUD_HIGH(1200)
-	.byte BAUD_LOW(1200)
-	;; baud[3]: 2400
-	.byte BAUD_HIGH(2400)
-	.byte BAUD_LOW(2400)
-	;; baud[4]: 4800
-	.byte BAUD_HIGH(4800)
-	.byte BAUD_LOW(4800)
-	;; baud[5]: 9600
-	.byte BAUD_HIGH(9600)
-	.byte BAUD_LOW(9600)
-	;; baud[6]: 19200
-	.byte BAUD_HIGH(19200)
-	.byte BAUD_LOW(19200)
-	;; baud[7]: 38400
-	.byte BAUD_HIGH(38400)
-	.byte BAUD_LOW(38400)
-	;; baud[8]: 57600
-	.byte BAUD_HIGH(57600)
-	.byte BAUD_LOW(57600)
-	;; baud[9]: 115200
-	.byte BAUD_HIGH(115200)
-	.byte BAUD_LOW(115200)
-
-desc_device:
-	.byte 0x12, 0x01, 0x00, 0x01, 0xff, 0xff, 0xff, 0x40
-	.byte 0xcd, 0x06, 0x04, 0x01, 0x89, 0xab, 1, 2, 3, 0x01
-;;; The "real" device id, which must match the host driver, is that
-;;; "0xcd 0x06 0x04 0x01" sequence, which is 0x06cd, 0x0104
-	
-desc_config1:
-	.byte 0x09, 0x02, 0x20, 0x00, 0x01, 0x01, 0x00, 0x80, 0x32
-	.byte 0x09, 0x04, 0x00, 0x00, 0x02, 0xff, 0xff, 0xff, 0x00
-	.byte 0x07, 0x05, 0x82, 0x03, 0x40, 0x00, 0x01
-	.byte 0x07, 0x05, 0x02, 0x02, 0x40, 0x00, 0x00
-
-desc_strings:
-	.word string_langids, string_mfg, string_product, string_serial
-desc_strings_end:
-
-string_langids:	.byte string_langids_end-string_langids
-	.byte 3
-	.word 0
-string_langids_end:
-
-	;; sigh. These strings are Unicode, meaning UTF16? 2 bytes each. Now
-	;; *that* is a pain in the ass to encode. And they are little-endian
-	;; too. Use this perl snippet to get the bytecodes:
-	/* while (<>) {
-	    @c = split(//);
-	    foreach $c (@c) {
-	     printf("0x%02x, 0x00, ", ord($c));
-	    }
-	   }
-	*/
-
-string_mfg:	.byte string_mfg_end-string_mfg
-	.byte 3
-;	.byte "ACME usb widgets"
-	.byte 0x41, 0x00, 0x43, 0x00, 0x4d, 0x00, 0x45, 0x00, 0x20, 0x00, 0x75, 0x00, 0x73, 0x00, 0x62, 0x00, 0x20, 0x00, 0x77, 0x00, 0x69, 0x00, 0x64, 0x00, 0x67, 0x00, 0x65, 0x00, 0x74, 0x00, 0x73, 0x00
-string_mfg_end:
-	
-string_product:	.byte string_product_end-string_product
-	.byte 3
-;	.byte "ACME USB serial widget"
-	.byte 0x41, 0x00, 0x43, 0x00, 0x4d, 0x00, 0x45, 0x00, 0x20, 0x00, 0x55, 0x00, 0x53, 0x00, 0x42, 0x00, 0x20, 0x00, 0x73, 0x00, 0x65, 0x00, 0x72, 0x00, 0x69, 0x00, 0x61, 0x00, 0x6c, 0x00, 0x20, 0x00, 0x77, 0x00, 0x69, 0x00, 0x64, 0x00, 0x67, 0x00, 0x65, 0x00, 0x74, 0x00
-string_product_end:
-	
-string_serial:	.byte string_serial_end-string_serial
-	.byte 3
-;	.byte "47"
-	.byte 0x34, 0x00, 0x37, 0x00
-string_serial_end:
-		
-;;; ring buffer memory
-	;; tx_ring_in+1 is where the next input byte will go
-	;; [tx_ring_out] has been sent
-	;; if tx_ring_in == tx_ring_out, theres no work to do
-	;; there are (tx_ring_in - tx_ring_out) chars to be written
-	;; dont let _in lap _out
-	;;   cannot inc if tx_ring_in+1 == tx_ring_out
-	;;  write [tx_ring_in+1] then tx_ring_in++
-	;;   if (tx_ring_in+1 == tx_ring_out), overflow
-	;;   else tx_ring_in++
-	;;  read/send [tx_ring_out+1], then tx_ring_out++
-
-	;; rx_ring_in works the same way
-	
-	.org 0x1000
-tx_ring:
-	.skip 0x100		; 256 bytes
-rx_ring:
-	.skip 0x100		; 256 bytes
-	
-	
-	.END
-	
--- zfcpdump-kernel-4.4.orig/firmware/matrox/g200_warp.H16
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * WARP pipes are named according to the functions they perform, where
- *
- *   - T stands for computation of texture stage 0
- *   - T2 stands for computation of both texture stage 0 and texture stage 1
- *   - G stands for computation of triangle intensity (Gouraud interpolation)
- *   - Z stands for computation of Z buffer interpolation
- *   - S stands for computation of specular highlight
- *   - A stands for computation of the alpha channel
- *   - F stands for computation of vertex fog interpolation
- */
-/* TGZ */
-:04B8000000008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E80098A0E94040D8ECFF80C0E9008000E81FD718BD3FD722BD8104890401040904C941C0EC110400E041CC41CD49CC49CDD141C0EC51CC51CD80041004080400E000CCC0CDD149C0EC8A1F20E98B3F20E9413C41AD493C49AD10CC10CD08CC08CDB94149BB1FF041CD513C51AD009880E9728007EA241F20E9154149BD1D4151BD2E412AB83453A0E815301D3058E300E0B54048BD3D4050BD2443A0E82C4BA0E8157209E300E01D723530B530BD303D309C97579F008000E86C64C8EC98E1B505BD052E3032C0A0E833C0A0E87464C8EC403C40AD326A2A302073336A00E028731C7283E2608015EAB83D28DF303520DF403000E0CCE26472254252BF2D424ABF302E30DF382E38DF181D45E91E1545E92B4951BD00E01F73383840AF303040AF241F24DF1D3220E92C1F2CDF1A3320E9B01008E34010B81026F030CD2FF038CD2B8020E92A8020E9A62088E200E0AF20282A26AF202AC0AF341F34DF462446DF283080BF203880BF472447DF4E2C4EDF4F2C4FDF563456DF281528DF201D20DF573457DF00E01D05048010EA89E22B303FC11DBD008000E8008000E8008000E8A068BF25008000E820C020AF2805977400E02A1016C020E9048010EA8CE2950528C128AD1FC115BD008000E8008000E8A8679F6B008000E828C028AD1D252005283280AD402A40BD1C8020E9203320AD207300E0B64951BB262FB0E8192020E9352035DF3D203DDF152015DF1D201DDF26D026CD29492AB8264080BD3B4850BD3E54579F00E082E11EAF599F008000E826302930483C48AD2B72C2E12CC044C2052434BF0D242CBF2D464EBF254656BF201D6F8F323E5FE93E50569F00E03B301E8F519F331E5FE9054454B20D444CB219C0B0E834C044C4337300E03E62579F1EAF599F00E00D20843E58E9281D6F8F052000E0851E58E99B3B33DF202042AF3042569F803E57E93F8F519F30805FE9282824AF811E57E9054757BF0D474FBF888058E91B291BDF301D6F8F3A304FE91C3026DF09E33B053E50569F3B3F4FE91E8F519F00E0AC202D444CB42C1CC0AF254454B400E0C830304630AF1B1B48AF00E02520382C4FE9868057E9381D6F8F287400E00D444CB0054454B02D209B10823E57E932F01BCD1EBD599F831E57E9384738AF34202A3000E00D2032200520878057E91F54579F1742569F00E03B6A3F8F519F371E4FE937322AAF00E03200008000E827C044C0361F4FE91F1F26DF371B37BF172617DF3E174FE93F3F4FE9341F34AF2B05A720332B37DF2717C0AF34804FE9008000E803800AEA17C12BBD008000E8008000E8B3689725008000E833C033AF3C274FE9573920E9281960EC2B3220E91D3B20E9B30500E0162820E9233B33AD1E2B20E91C8020E9573620E90080A0E94040D8ECFF80C0E990E200E085FF20EA19C8C1CD1FD718BD3FD722BD9F4149BD008000E8254149BD2D4151BD0D8007EA008000E8354048BD3D4050BD008000E825302D303530B530BD303D309CA75B9F008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E884FF0AEA008000E8C941C8EC42E100E082FF20EA008000E8008000E8008000E8C840C0EC008000E87FFF20EA008000E8008000E8008000E871
-/* TGZF */
-:0548000000008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E80098A0E94040D8ECFF80C0E9008000E81FD718BD3FD722BD8104890401040904C941C0EC110400E041CC41CD49CC49CDD141C0EC51CC51CD80041004080400E000CCC0CDD149C0EC8A1F20E98B3F20E9413C41AD493C49AD10CC10CD08CC08CDB94149BB1FF041CD513C51AD009880E97F8007EA241F20E9214580E81A4D80E8315580E8008000E8154149BD1D4151BD2E412AB83453A0E815301D3058E300E0B54048BD3D4050BD2443A0E82C4BA0E8157209E300E01D723530B530BD303D309C97579F008000E86C64C8EC98E1B505BD052E3032C0A0E833C0A0E87464C8EC403C40AD326A2A302073336A00E028731C7283E26B8015EAB83D28DF303520DF403000E0CCE26472254252BF2D424ABF302E30DF382E38DF181D45E91E1545E92B4951BD00E01F73383840AF303040AF241F24DF1D3220E92C1F2CDF1A3320E9B01008E34010B81026F030CD2FF038CD2B8020E92A8020E9A62088E200E0AF20282A26AF202AC0AF341F34DF462446DF283080BF203880BF472447DF4E2C4EDF4F2C4FDF563456DF281528DF201D20DF573457DF00E01D05048010EA89E22B303FC11DBD008000E8008000E8008000E8A068BF25008000E820C020AF2805977400E02A1016C020E9048010EA8CE2950528C128AD1FC115BD008000E8008000E8A8679F6B008000E828C028AD1D252005283280AD402A40BD1C8020E9203320AD207300E0B64951BB262FB0E8192020E9352035DF3D203DDF152015DF1D201DDF26D026CD29492AB8264080BD3B4850BD3E54579F00E082E11EAF599F008000E826302930483C48AD2B72C2E12CC044C2052434BF0D242CBF2D464EBF254656BF201D6F8F323E5FE93E50569F00E03B301E8F519F331E5FE9054454B20D444CB219C0B0E834C044C4337300E03E62579F1EAF599F00E00D20843E58E9281D6F8F052000E0851E58E99B3B33DF202042AF3042569F803E57E93F8F519F30805FE9282824AF811E57E9054757BF0D474FBF888058E91B291BDF301D6F8F3A304FE91C3026DF09E33B053E50569F3B3F4FE91E8F519F00E0AC202D444CB42C1CC0AF254454B400E0C830304630AF1B1B48AF00E02520382C4FE9868057E9381D6F8F287400E00D444CB0054454B02D209B10823E57E932F01BCD1EBD599F831E57E9384738AF34202A3000E00D2032200520878057E91F54579F1742569F00E03B6A3F8F519F371E4FE937322AAF00E03200008000E827C044C0361F4FE91F1F26DF371B37BF172617DF3E174FE93F3F4FE9341F34AF2B05A720332B37DF2717C0AF34804FE9008000E80D211AB6052131B603802AEA17C12BBD0D2005202FC021C6B3689725008000E833C033AF3C274FE91750569F008000E8370F5C9F00E02F20008000E8281960ECB30500E0008000E8233B33AD008000E8172617DF35174FE9008000E8008000E8008000E839374FE92F2F17AF008000E8008000E8008000E831804FE9008000E8008000E8573920E9162820E91D3B20E91E2B20E92B3220E91C2320E9573620E90080A0E94040D8ECFF80C0E990E200E078FF20EA19C8C1CD1FD718BD3FD722BD9F4149BD008000E8254149BD2D4151BD0D8007EA008000E8354048BD3D4050BD008000E825302D303530B530BD303D309CA75B9F008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E877FF0AEA008000E8C941C8EC42E100E075FF20EA008000E8008000E8008000E8C840C0EC008000E872FF20EA008000E8008000E8008000E8BB
-/* TGZA */
-:04E80000000098A0E94040D8ECFF80C0E9008000E81FD718BD3FD722BD8104890401040904C941C0EC110400E041CC41CD49CC49CDD141C0EC51CC51CD80041004080400E000CCC0CDD149C0EC8A1F20E98B3F20E9413C41AD493C49AD10CC10CD08CC08CDB94149BB1FF041CD513C51AD009880E97D8007EA241F20E9154149BD1D4151BD2E412AB83453A0E815301D3058E300E0B54048BD3D4050BD2443A0E82C4BA0E8157209E300E01D723530B530BD303D309C97579F008000E86C64C8EC98E1B505BD052E3032C0A0E833C0A0E87464C8EC403C40AD326A2A302073336A00E028731C7283E26B8015EAB83D28DF303520DF403000E0CCE26472254252BF2D424ABF302E30DF382E38DF181D45E91E1545E92B4951BD00E01F73383840AF303040AF241F24DF1D3220E92C1F2CDF1A3320E9B01008E34010B81026F030CD2FF038CD2B8020E92A8020E9A62088E200E0AF20282A26AF202AC0AF341F34DF462446DF283080BF203880BF472447DF4E2C4EDF4F2C4FDF563456DF281528DF201D20DF573457DF00E01D05048010EA89E22B303FC11DBD008000E8008000E8008000E8A068BF25008000E820C020AF2805977400E02A1016C020E9048010EA8CE2950528C128AD1FC115BD008000E8008000E8A8679F6B008000E828C028AD1D252005283280AD402A40BD1C8020E9203320AD207300E0B64951BB262FB0E8192020E9352035DF3D203DDF152015DF1D201DDF26D026CD29492AB8264080BD3B4850BD3E54579F00E082E11EAF599F008000E826302930483C48AD2B72C2E12CC044C2052434BF0D242CBF2D464EBF254656BF201D6F8F323E5FE93E50569F00E03B301E8F519F331E5FE9054454B20D444CB219C0B0E834C044C4337300E03E62579F1EAF599F00E00D20843E58E9281D6F8F052000E0851E58E99B3B33DF202042AF3042569F803E57E93F8F519F30805FE9282824AF811E57E9054757BF0D474FBF888058E91B291BDF301D6F8F3A304FE91C3026DF09E33B053E50569F3B3F4FE91E8F519F00E0AC202D444CB42C1CC0AF254454B400E0C830304630AF1B1B48AF00E02520382C4FE9868057E9381D6F8F287400E00D444CB0054454B02D209B10823E57E932F01BCD1EBD599F831E57E9384738AF34202A3000E00D2032200520878057E91F54579F1742569F00E03B6A3F8F519F371E4FE937322AAF00E03200008000E827C044C0361F4FE91F1F26DF371B37BF172617DF3E174FE93F3F4FE9341F34AF2B05A720332B37DF2717C0AF34804FE9008000E82D444CB6254454B603802AEA17C12BBD2D20252007C044C6B3689725008000E833C033AF3C274FE91F62579F008000E83F3D5D9F00E00720008000E8281960ECB30500E0008000E8233B33AD008000E81F261FDF9D1F4FE9008000E8008000E8008000E89E3F4FE907071FAF008000E8008000E8008000E89C804FE9008000E8008000E8573920E9162820E91D3B20E91E2B20E92B3220E91C2320E9573620E90080A0E94040D8ECFF80C0E990E200E07AFF20EA19C8C1CD1FD718BD3FD722BD9F4149BD008000E8254149BD2D4151BD0D8007EA008000E8354048BD3D4050BD008000E825302D303530B530BD303D309CA75B9F008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E879FF0AEA008000E8C941C8EC42E100E077FF20EA008000E8008000E8008000E8C840C0EC008000E874FF20EA008000E8008000E8008000E8D9
-/* TGZAF */
-:0568000000008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E80098A0E94040D8ECFF80C0E9008000E81FD718BD3FD722BD8104890401040904C941C0EC110400E041CC41CD49CC49CDD141C0EC51CC51CD80041004080400E000CCC0CDD149C0EC8A1F20E98B3F20E9413C41AD493C49AD10CC10CD08CC08CDB94149BB1FF041CD513C51AD009880E9838007EA241F20E9214580E81A4D80E8315580E8008000E8154149BD1D4151BD2E412AB83453A0E815301D3058E300E0B54048BD3D4050BD2443A0E82C4BA0E8157209E300E01D723530B530BD303D309C97579F008000E86C64C8EC98E1B505BD052E3032C0A0E833C0A0E87464C8EC403C40AD326A2A302073336A00E028731C7283E26F8015EAB83D28DF303520DF403000E0CCE26472254252BF2D424ABF302E30DF382E38DF181D45E91E1545E92B4951BD00E01F73383840AF303040AF241F24DF1D3220E92C1F2CDF1A3320E9B01008E34010B81026F030CD2FF038CD2B8020E92A8020E9A62088E200E0AF20282A26AF202AC0AF341F34DF462446DF283080BF203880BF472447DF4E2C4EDF4F2C4FDF563456DF281528DF201D20DF573457DF00E01D05048010EA89E22B303FC11DBD008000E8008000E8008000E8A068BF25008000E820C020AF2805977400E02A1016C020E9048010EA8CE2950528C128AD1FC115BD008000E8008000E8A8679F6B008000E828C028AD1D252005283280AD402A40BD1C8020E9203320AD207300E0B64951BB262FB0E8192020E9352035DF3D203DDF152015DF1D201DDF26D026CD29492AB8264080BD3B4850BD3E54579F00E082E11EAF599F008000E826302930483C48AD2B72C2E12CC044C2052434BF0D242CBF2D464EBF254656BF201D6F8F323E5FE93E50569F00E03B301E8F519F331E5FE9054454B20D444CB219C0B0E834C044C4337300E03E62579F1EAF599F00E00D20843E58E9281D6F8F052000E0851E58E99B3B33DF202042AF3042569F803E57E93F8F519F30805FE9282824AF811E57E9054757BF0D474FBF888058E91B291BDF301D6F8F3A304FE91C3026DF09E33B053E50569F3B3F4FE91E8F519F00E0AC202D444CB42C1CC0AF254454B400E0C830304630AF1B1B48AF00E02520382C4FE9868057E9381D6F8F287400E00D444CB0054454B02D209B10823E57E932F01BCD1EBD599F831E57E9384738AF34202A3000E00D2032200520878057E91F54579F1742569F00E03B6A3F8F519F371E4FE937322AAF00E03200008000E827C044C0361F4FE91F1F26DF371B37BF172617DF3E174FE93F3F4FE9341F34AF2B05A720332B37DF2717C0AF34804FE9008000E80D211AB6052131B62D444CB6254454B603802AEA17C12BBD0D2005202FC021C6B3689725008000E833C033AF3C274FE900E0252007C044C61750569F00E02D20370F5C9F00E02F201F62579F00E007203F3D5D9F008000E8008000E8281960ECB30500E0172617DF233B33AD35174FE91F261FDF9D1F4FE99E3F4FE939374FE92F2F17AF008000E807071FAF008000E831804FE9008000E89C804FE9008000E8008000E8573920E9162820E91D3B20E91E2B20E92B3220E91C2320E9573620E90080A0E94040D8ECFF80C0E990E200E074FF20EA19C8C1CD1FD718BD3FD722BD9F4149BD008000E8254149BD2D4151BD0D8007EA008000E8354048BD3D4050BD008000E825302D303530B530BD303D309CA75B9F008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E873FF0AEA008000E8C941C8EC42E100E071FF20EA008000E8008000E8008000E8C840C0EC008000E86EFF20EA008000E8008000E8008000E830
-/* TGZS */
-:05C0000000008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E80098A0E94040D8ECFF80C0E9008000E81FD718BD3FD722BD8104890401040904C941C0EC110400E041CC41CD49CC49CDD141C0EC51CC51CD80041004080400E000CCC0CDD149C0EC8A1F20E98B3F20E9413C41AD493C49AD10CC10CD08CC08CDB94149BB1FF041CD513C51AD009880E98B8007EA241F20E9214580E81A4D80E8315580E8008000E8154149BD1D4151BD2E412AB83453A0E815301D3058E300E0B54048BD3D4050BD2443A0E82C4BA0E8157209E300E01D723530B530BD303D309C97579F008000E86C64C8EC98E1B505BD052E3032C0A0E833C0A0E87464C8EC403C40AD326A2A302073336A00E028731C7283E2778015EAB83D28DF303520DF403000E0CCE26472254252BF2D424ABF302E30DF382E38DF181D45E91E1545E92B4951BD00E01F73383840AF303040AF241F24DF1D3220E92C1F2CDF1A3320E9B01008E34010B81026F030CD2FF038CD2B8020E92A8020E9A62088E200E0AF20282A26AF202AC0AF341F34DF462446DF283080BF203880BF472447DF4E2C4EDF4F2C4FDF563456DF281528DF201D20DF573457DF00E01D05048010EA89E22B303FC11DBD008000E8008000E8008000E8A068BF25008000E820C020AF2805977400E02A1016C020E9048010EA8CE2950528C128AD1FC115BD008000E8008000E8A8679F6B008000E828C028AD1D252005283280AD402A40BD1C8020E9203320AD207300E0B64951BB262FB0E8192020E9352035DF3D203DDF152015DF1D201DDF26D026CD29492AB8264080BD3B4850BD3E54579F00E082E11EAF599F008000E826302930483C48AD2B72C2E12CC044C2052434BF0D242CBF2D464EBF254656BF201D6F8F323E5FE93E50569F00E03B301E8F519F331E5FE9054454B20D444CB219C0B0E834C044C4337300E03E62579F1EAF599F00E00D20843E58E9281D6F8F052000E0851E58E99B3B33DF202042AF3042569F803E57E93F8F519F30805FE9282824AF811E57E9054757BF0D474FBF888058E91B291BDF301D6F8F3A304FE91C3026DF09E33B053E50569F3B3F4FE91E8F519F00E0AC202D444CB42C1CC0AF254454B400E0C830304630AF1B1B48AF00E02520382C4FE9868057E9381D6F8F287400E00D444CB0054454B02D209B10823E57E932F01BCD1EBD599F831E57E9384738AF34202A3000E00D2032200520878057E91F54579F1742569F00E03B6A3F8F519F371E4FE937322AAF00E03200008000E827C044C0361F4FE91F1F26DF371B37BF172617DF3E174FE93F3F4FE9341F34AF2B05A720332B37DF2717C0AF34804FE9008000E82D211AB0252131B00D211AB2052131B203802AEA17C12BBD2D20252005200D20B3689725008000E833C033AF2FC021C01642569F3C274FE91E62579F008000E8252131B42D211AB43F2F5D9F008000E8330500E0281960EC370F5C9F00E02F20233B33AD1E261EDFA71E4FE9172616DF2D2000E0A83F4FE92F2F1EAF252000E0A4164FE90FC021C2A6804FE91F62579F3F2F5D9F00E08F20A5374FE90F170FAF06C021C4008000E8008000E8A3804FE9062000E01F261FDFA11F4FE9A23F4FE9008000E8008000E806061FAF008000E8008000E8008000E8A0804FE9008000E8008000E8573920E9162820E91D3B20E91E2B20E92B3220E91C2320E9573620E90080A0E94040D8ECFF80C0E990E200E06CFF20EA19C8C1CD1FD718BD3FD722BD9F4149BD008000E8254149BD2D4151BD0D8007EA008000E8354048BD3D4050BD008000E825302D303530B530BD303D309CA75B9F008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E86BFF0AEA008000E8C941C8EC42E100E069FF20EA008000E8008000E8008000E8C840C0EC008000E866FF20EA008000E8008000E8008000E85C
-/* TGZSF */
-:05E0000000008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E80098A0E94040D8ECFF80C0E9008000E81FD718BD3FD722BD8104890401040904C941C0EC110400E041CC41CD49CC49CDD141C0EC51CC51CD80041004080400E000CCC0CDD149C0EC8A1F20E98B3F20E9413C41AD493C49AD10CC10CD08CC08CDB94149BB1FF041CD513C51AD009880E98F8007EA241F20E9214580E81A4D80E8315580E8008000E8154149BD1D4151BD2E412AB83453A0E815301D3058E300E0B54048BD3D4050BD2443A0E82C4BA0E8157209E300E01D723530B530BD303D309C97579F008000E86C64C8EC98E1B505BD052E3032C0A0E833C0A0E87464C8EC403C40AD326A2A302073336A00E028731C7283E27B8015EAB83D28DF303520DF403000E0CCE26472254252BF2D424ABF302E30DF382E38DF181D45E91E1545E92B4951BD00E01F73383840AF303040AF241F24DF1D3220E92C1F2CDF1A3320E9B01008E34010B81026F030CD2FF038CD2B8020E92A8020E9A62088E200E0AF20282A26AF202AC0AF341F34DF462446DF283080BF203880BF472447DF4E2C4EDF4F2C4FDF563456DF281528DF201D20DF573457DF00E01D05048010EA89E22B303FC11DBD008000E8008000E8008000E8A068BF25008000E820C020AF2805977400E02A1016C020E9048010EA8CE2950528C128AD1FC115BD008000E8008000E8A8679F6B008000E828C028AD1D252005283280AD402A40BD1C8020E9203320AD207300E0B64951BB262FB0E8192020E9352035DF3D203DDF152015DF1D201DDF26D026CD29492AB8264080BD3B4850BD3E54579F00E082E11EAF599F008000E826302930483C48AD2B72C2E12CC044C2052434BF0D242CBF2D464EBF254656BF201D6F8F323E5FE93E50569F00E03B301E8F519F331E5FE9054454B20D444CB219C0B0E834C044C4337300E03E62579F1EAF599F00E00D20843E58E9281D6F8F052000E0851E58E99B3B33DF202042AF3042569F803E57E93F8F519F30805FE9282824AF811E57E9054757BF0D474FBF888058E91B291BDF301D6F8F3A304FE91C3026DF09E33B053E50569F3B3F4FE91E8F519F00E0AC202D444CB42C1CC0AF254454B400E0C830304630AF1B1B48AF00E02520382C4FE9868057E9381D6F8F287400E00D444CB0054454B02D209B10823E57E932F01BCD1EBD599F831E57E9384738AF34202A3000E00D2032200520878057E91F54579F1742569F00E03B6A3F8F519F371E4FE937322AAF00E03200008000E827C044C0361F4FE91F1F26DF371B37BF172617DF3E174FE93F3F4FE9341F34AF2B05A720332B37DF2717C0AF34804FE9008000E82D211AB0252131B00D211AB2052131B203802AEA17C12BBD2D20252005200D20B3689725008000E833C033AF2FC021C01642569F3C274FE91E62579F008000E8252131B42D211AB43F2F5D9F008000E8330500E0281960EC0D211AB6052131B6370F5C9F00E02F20233B33AD1E261EDFA71E4FE9172616DF2D2000E0A83F4FE92F2F1EAF252000E0A4164FE90FC021C2A6804FE91F62579F0D2005202FC021C63F2F5D9F00E00F201750569FA5374FE906C021C40F170FAF370F5C9F008000E82F2000E0A3804FE9062000E01F261FDF172617DF35174FE9A11F4FE9A23F4FE906061FAF39374FE92F2F17AF008000E8A0804FE9008000E831804FE9008000E8008000E8573920E9162820E91D3B20E91E2B20E92B3220E91C2320E9573620E90080A0E94040D8ECFF80C0E990E200E068FF20EA19C8C1CD1FD718BD3FD722BD9F4149BD008000E8254149BD2D4151BD0D8007EA008000E8354048BD3D4050BD008000E825302D303530B530BD303D309CA75B9F008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E867FF0AEA008000E8C941C8EC42E100E065FF20EA008000E8008000E8008000E8C840C0EC008000E862FF20EA008000E8008000E8008000E8F9
-/* TGZSA */
-:05E0000000008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E80098A0E94040D8ECFF80C0E9008000E81FD718BD3FD722BD8104890401040904C941C0EC110400E041CC41CD49CC49CDD141C0EC51CC51CD80041004080400E000CCC0CDD149C0EC8A1F20E98B3F20E9413C41AD493C49AD10CC10CD08CC08CDB94149BB1FF041CD513C51AD009880E98F8007EA241F20E9214580E81A4D80E8315580E8008000E8154149BD1D4151BD2E412AB83453A0E815301D3058E300E0B54048BD3D4050BD2443A0E82C4BA0E8157209E300E01D723530B530BD303D309C97579F008000E86C64C8EC98E1B505BD052E3032C0A0E833C0A0E87464C8EC403C40AD326A2A302073336A00E028731C7283E27B8015EAB83D28DF303520DF403000E0CCE26472254252BF2D424ABF302E30DF382E38DF181D45E91E1545E92B4951BD00E01F73383840AF303040AF241F24DF1D3220E92C1F2CDF1A3320E9B01008E34010B81026F030CD2FF038CD2B8020E92A8020E9A62088E200E0AF20282A26AF202AC0AF341F34DF462446DF283080BF203880BF472447DF4E2C4EDF4F2C4FDF563456DF281528DF201D20DF573457DF00E01D05048010EA89E22B303FC11DBD008000E8008000E8008000E8A068BF25008000E820C020AF2805977400E02A1016C020E9048010EA8CE2950528C128AD1FC115BD008000E8008000E8A8679F6B008000E828C028AD1D252005283280AD402A40BD1C8020E9203320AD207300E0B64951BB262FB0E8192020E9352035DF3D203DDF152015DF1D201DDF26D026CD29492AB8264080BD3B4850BD3E54579F00E082E11EAF599F008000E826302930483C48AD2B72C2E12CC044C2052434BF0D242CBF2D464EBF254656BF201D6F8F323E5FE93E50569F00E03B301E8F519F331E5FE9054454B20D444CB219C0B0E834C044C4337300E03E62579F1EAF599F00E00D20843E58E9281D6F8F052000E0851E58E99B3B33DF202042AF3042569F803E57E93F8F519F30805FE9282824AF811E57E9054757BF0D474FBF888058E91B291BDF301D6F8F3A304FE91C3026DF09E33B053E50569F3B3F4FE91E8F519F00E0AC202D444CB42C1CC0AF254454B400E0C830304630AF1B1B48AF00E02520382C4FE9868057E9381D6F8F287400E00D444CB0054454B02D209B10823E57E932F01BCD1EBD599F831E57E9384738AF34202A3000E00D2032200520878057E91F54579F1742569F00E03B6A3F8F519F371E4FE937322AAF00E03200008000E827C044C0361F4FE91F1F26DF371B37BF172617DF3E174FE93F3F4FE9341F34AF2B05A720332B37DF2717C0AF34804FE9008000E82D211AB0252131B00D211AB2052131B203802AEA17C12BBD2D20252005200D20B3689725008000E833C033AF2FC021C01642569F3C274FE91E62579F008000E8252131B42D211AB43F2F5D9F008000E8330500E0281960EC0D444CB6054454B6370F5C9F00E02F20233B33AD1E261EDFA71E4FE9172616DF2D2000E0A83F4FE92F2F1EAF252000E0A4164FE90FC021C2A6804FE91F62579F0D200520008000E83F2F5D9F00E00F201750569FA5374FE906C021C40F170FAF370F5C9F008000E82FC044C6A3804FE9062000E01F261FDF172617DF9D174FE9A11F4FE9A23F4FE906061FAF00E0AF209E374FE92F172FAFA0804FE9008000E8008000E89C804FE9008000E8573920E9162820E91D3B20E91E2B20E92B3220E91C2320E9573620E90080A0E94040D8ECFF80C0E990E200E068FF20EA19C8C1CD1FD718BD3FD722BD9F4149BD008000E8254149BD2D4151BD0D8007EA008000E8354048BD3D4050BD008000E825302D303530B530BD303D309CA75B9F008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E867FF0AEA008000E8C941C8EC42E100E065FF20EA008000E8008000E8008000E8C840C0EC008000E862FF20EA008000E8008000E8008000E883
-/* TGZAF */
-:05B8000000008000E8008000E8008000E8008000E8008000E8008000E80098A0E94040D8ECFF80C0E9008000E81FD718BD3FD722BD8104890401040904C941C0EC110400E041CC41CD49CC49CDD141C0EC51CC51CD80041004080400E000CCC0CDD149C0EC8A1F20E98B3F20E9413C41AD493C49AD10CC10CD08CC08CDB94149BB1FF041CD513C51AD009880E9948007EA241F20E9214580E81A4D80E8315580E8008000E8154149BD1D4151BD2E412AB83453A0E815301D3058E300E0B54048BD3D4050BD2443A0E82C4BA0E8157209E300E01D723530B530BD303D309C97579F008000E86C64C8EC98E1B505BD052E3032C0A0E833C0A0E87464C8EC403C40AD326A2A302073336A00E028731C7283E2808015EAB83D28DF303520DF403000E0CCE26472254252BF2D424ABF302E30DF382E38DF181D45E91E1545E92B4951BD00E01F73383840AF303040AF241F24DF1D3220E92C1F2CDF1A3320E9B01008E34010B81026F030CD2FF038CD2B8020E92A8020E9A62088E200E0AF20282A26AF202AC0AF341F34DF462446DF283080BF203880BF472447DF4E2C4EDF4F2C4FDF563456DF281528DF201D20DF573457DF00E01D05048010EA89E22B303FC11DBD008000E8008000E8008000E8A068BF25008000E820C020AF2805977400E02A1016C020E9048010EA8CE2950528C128AD1FC115BD008000E8008000E8A8679F6B008000E828C028AD1D252005283280AD402A40BD1C8020E9203320AD207300E0B64951BB262FB0E8192020E9352035DF3D203DDF152015DF1D201DDF26D026CD29492AB8264080BD3B4850BD3E54579F00E082E11EAF599F008000E826302930483C48AD2B72C2E12CC044C2052434BF0D242CBF2D464EBF254656BF201D6F8F323E5FE93E50569F00E03B301E8F519F331E5FE9054454B20D444CB219C0B0E834C044C4337300E03E62579F1EAF599F00E00D20843E58E9281D6F8F052000E0851E58E99B3B33DF202042AF3042569F803E57E93F8F519F30805FE9282824AF811E57E9054757BF0D474FBF888058E91B291BDF301D6F8F3A304FE91C3026DF09E33B053E50569F3B3F4FE91E8F519F00E0AC202D444CB42C1CC0AF254454B400E0C830304630AF1B1B48AF00E02520382C4FE9868057E9381D6F8F287400E00D444CB0054454B02D209B10823E57E932F01BCD1EBD599F831E57E9384738AF34202A3000E00D2032200520878057E91F54579F1742569F00E03B6A3F8F519F371E4FE937322AAF00E03200008000E827C044C0361F4FE91F1F26DF371B37BF172617DF3E174FE93F3F4FE9341F34AF2B05A720332B37DF2717C0AF34804FE9008000E82D211AB0252131B00D211AB2052131B203802AEA17C12BBD2D20252005200D20B3689725008000E833C033AF2FC021C01642569F3C274FE91E62579F008000E8252131B42D211AB43F2F5D9F008000E8330500E0281960EC0D211AB6052131B6370F5C9F00E02F20233B33AD1E261EDFA71E4FE9172616DF2D2000E0A83F4FE92F2F1EAF252000E0A4164FE90FC021C2A6804FE91F62579F0D2005202FC021C62D444CB6254454B63F2F5D9F00E00F202D20252007C044C61750569FA5374FE906C021C40F170FAF370F5C9F008000E81E62579F008000E83E3D5D9F00E007202F2000E0A30F4FE9062000E01F261FDF172617DFA11F4FE91E261EDF9D1E4FE935174FE9A23F4FE906061FAF39374FE92F2F17AF07071EAFA0804FE99E3E4FE931804FE99C804FE9008000E8573920E9162820E91D3B20E91E2B20E92B3220E91C2320E9573620E90080A0E94040D8ECFF80C0E990E200E063FF20EA19C8C1CD1FD718BD3FD722BD9F4149BD008000E8254149BD2D4151BD0D8007EA008000E8354048BD3D4050BD008000E825302D303530B530BD303D309CA75B9F008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E862FF0AEA008000E8C941C8EC42E100E060FF20EA008000E8008000E8008000E8C840C0EC008000E85DFF20EA008000E8008000E8008000E8D8
-:0000000001FF
--- zfcpdump-kernel-4.4.orig/firmware/matrox/g400_warp.H16
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * WARP pipes are named according to the functions they perform, where
- *
- *   - T stands for computation of texture stage 0
- *   - T2 stands for computation of both texture stage 0 and texture stage 1
- *   - G stands for computation of triangle intensity (Gouraud interpolation)
- *   - Z stands for computation of Z buffer interpolation
- *   - S stands for computation of specular highlight
- *   - A stands for computation of the alpha channel
- *   - F stands for computation of vertex fog interpolation
- */
-/* TGZ */
-:0338000000008898E9008000E80080A0E90000D8ECFF80C0E9008000E8224048BF2A4050BF324149BF3A4151BFC36BCB6B008898E9737BC8EC96E241047B43A0E8734BA0E8ADEE299F00E0490490E251043146B1E84941C0EC3957B1E8000446E27353A0E85141C0EC31003900588015EA080410045149C0EC2F4160EA312039201F42A0E82A424ABF274AA0E81A4252BF1E4960EA737BC8EC265160EA324048BD224050BD124149BD3A4151BDBF2F26BD00E07B723220222012203A20463146BF4E314EBFB3E22D9F008000E8563156BF473947BF4F394FBF573957BF4A8007EA244120E94273F8EC00E02D7333720CE3A52F1EBD43432DDF4B4B2DDFAE1E26BD58E3336653532DDF008000E8B83833BF00E059E31E1241E91A2241E92B403DE93F4BA0E82D73307605803DEA3743A0E83D53A0E84870F8EC2B483CE91F27BCE8008000E8008000E8008000E815C020E915C020E915C020E915C020E9183A41E91D3241E92A4020E9563D56DF463746DF4E3F4EDF163020E94F3F4FDF32322DDF22222DDF12122DDF3A3A2DDF473747DF573D57DF3DCF74C037CF74C431532F9F348020E939E52C9F3C3D20E90A444CB0024454B02A444CB21A4454B21D803AEA0A2002203DCF74C22A201A2030502E9F32315FE938212C9F33395FE931532F9F008000E82A444CB41A4454B439E52C9F383D20E988735EE92A201A202A464EBF1A4656BF31532F9F3E304FE939E52C9F3F384FE90A474FBF024757BF31532F9F3A314FE939E52C9F3B394FE92A434BBF1A4353BF30502E9F36314FE938212C9F37394FE931532F9F803157E939E52C9F813957E9374850BD8A3620E9867657E98B3E20E9823057E9877757E9833857E9354951BD84315EE9301F5FE985395EE9572520E92B4820E91D37E1EA1E35E1EA00E02677244920E9AFFF20EA162620E9572EBFEA1C46A0E8234EA0E82B56A0E81D47A0E8244FA0E82C57A0E81C0023002B0000E01D0024002C0000E01C6523652B6500E01D6524652C6500E01C2360EC36D736AD2B8060EC1D2460EC3ED73EAD2C8060EC1C2BDEE82380DEE8368036BD3E803EBD33D71CBD3BD723BD468046CF4F804FCF563356CF473B47CFD6FF20EA008000E84E334ECF573B57CF9DFF20EA57C0BFEA0080A0E90000D8EC59
-/* TGZF */
-:0360000000008898E9008000E80080A0E90000D8ECFF80C0E9008000E8224048BF2A4050BF324149BF3A4151BFC36BCB6B008898E9737BC8EC96E241047B43A0E8734BA0E8ADEE299F00E0490490E251043146B1E84941C0EC3957B1E8000446E27353A0E85141C0EC310039005D8015EA080410045149C0EC2F4160EA312039201F42A0E82A424ABF274AA0E81A4252BF1E4960EA737BC8EC265160EA324048BD224050BD124149BD3A4151BDBF2F26BD00E07B723220222012203A20463146BF4E314EBFB3E22D9F008000E8563156BF473947BF4F394FBF573957BF4F8007EA244120E94273F8EC00E02D7333720CE3A52F1EBD43432DDF4B4B2DDFAE1E26BD58E3336653532DDF008000E8B83833BF00E059E31E1241E91A2241E92B403DE93F4BA0E82D73307605803DEA3743A0E83D53A0E84870F8EC2B483CE91F27BCE8008000E8008000E8008000E815C020E915C020E915C020E915C020E9183A41E91D3241E92A4020E9563D56DF463746DF4E3F4EDF163020E94F3F4FDF32322DDF22222DDF12122DDF3A3A2DDF473747DF573D57DF3DCF74C037CF74C439E52C9F348020E931532F9F008000E888735EE9008000E827CF75C63C3D20E90A444CB0024454B02A444CB21A4454B220803AEA0A2002203DCF74C22A201A2030502E9F32315FE938212C9F33395FE931532F9F312720E90A444CB4024454B42A454DB61A4555B639E52C9F383D20E90A2002202A201A200A474FBF024757BF30502E9F3E304FE938212C9F3F384FE92A464EBF1A4656BF31532F9F3A314FE939E52C9F3B394FE931532F9F36304FE939E52C9F37384FE92A434BBF1A4353BF30502E9F35314FE938212C9F39394FE931532F9F803157E939E52C9F813957E9374850BD8A3620E9867657E98B3E20E9823057E9877757E9833857E9354951BD84315EE9301F5FE985395EE9572520E92B4820E91D37E1EA1E35E1EA00E02677244920E9AAFF20EA162620E9572EBFEA1C46A0E8234EA0E82B56A0E81D47A0E8244FA0E82C57A0E81C0023002B0000E01D0024002C0000E01C6523652B6500E01D6524652C6500E01C2360EC36D736AD2B8060EC1D2460EC3ED73EAD2C8060EC1C2BDEE82380DEE8368036BD3E803EBD33D71CBD3BD723BD468046CF4F804FCF563356CF473B47CFD3FF20EA008000E84E334ECF573B57CF98FF20EA57C0BFEA0080A0E90000D8EC90
-/* TGZA */
-:0358000000008898E9008000E80080A0E90000D8ECFF80C0E9008000E8224048BF2A4050BF324149BF3A4151BFC36BCB6B008898E9737BC8EC96E241047B43A0E8734BA0E8ADEE299F00E0490490E251043146B1E84941C0EC3957B1E8000446E27353A0E85141C0EC310039005C8015EA080410045149C0EC2F4160EA312039201F42A0E82A424ABF274AA0E81A4252BF1E4960EA737BC8EC265160EA324048BD224050BD124149BD3A4151BDBF2F26BD00E07B723220222012203A20463146BF4E314EBFB3E22D9F008000E8563156BF473947BF4F394FBF573957BF4E8007EA244120E94273F8EC00E02D7333720CE3A52F1EBD43432DDF4B4B2DDFAE1E26BD58E3336653532DDF008000E8B83833BF00E059E31E1241E91A2241E92B403DE93F4BA0E82D73307605803DEA3743A0E83D53A0E84870F8EC2B483CE91F27BCE8008000E8008000E8008000E815C020E915C020E915C020E915C020E9183A41E91D3241E92A4020E9563D56DF463746DF4E3F4EDF163020E94F3F4FDF32322DDF22222DDF12122DDF3A3A2DDF473747DF573D57DF3DCF74C037CF74C431532F9F348020E939E52C9F3C3D20E927CF74C63DCF74C20A444CB0024454B02A444CB21A4454B220803AEA0A20022088735EE92A201A2030502E9F32315FE938212C9F33395FE931532F9F9C2720E90A444CB4024454B42A444CB61A4454B639E52C9F383D20E90A2002202A201A200A474FBF024757BF30502E9F3E304FE938212C9F3F384FE92A464EBF1A4656BF31532F9F3A314FE939E52C9F3B394FE931532F9F36304FE939E52C9F37384FE92A434BBF1A4353BF30502E9F9D314FE938212C9F9E394FE931532F9F803157E939E52C9F813957E9374850BD8A3620E9867657E98B3E20E9823057E9877757E9833857E9354951BD84315EE9301F5FE985395EE9572520E92B4820E91D37E1EA1E35E1EA00E02677244920E9ABFF20EA162620E9572EBFEA1C46A0E8234EA0E82B56A0E81D47A0E8244FA0E82C57A0E81C0023002B0000E01D0024002C0000E01C6523652B6500E01D6524652C6500E01C2360EC36D736AD2B8060EC1D2460EC3ED73EAD2C8060EC1C2BDEE82380DEE8368036BD3E803EBD33D71CBD3BD723BD468046CF4F804FCF563356CF473B47CFD3FF20EA008000E84E334ECF573B57CF99FF20EA57C0BFEA0080A0E90000D8EC35
-/* TGZAF */
-:0380000000008898E9008000E80080A0E90000D8ECFF80C0E9008000E8224048BF2A4050BF324149BF3A4151BFC36BCB6B008898E9737BC8EC96E241047B43A0E8734BA0E8ADEE299F00E0490490E251043146B1E84941C0EC3957B1E8000446E27353A0E85141C0EC31003900618015EA080410045149C0EC2F4160EA312039201F42A0E82A424ABF274AA0E81A4252BF1E4960EA737BC8EC265160EA324048BD224050BD124149BD3A4151BDBF2F26BD00E07B723220222012203A20463146BF4E314EBFB3E22D9F008000E8563156BF473947BF4F394FBF573957BF538007EA244120E94273F8EC00E02D7333720CE3A52F1EBD43432DDF4B4B2DDFAE1E26BD58E3336653532DDF008000E8B83833BF00E059E31E1241E91A2241E92B403DE93F4BA0E82D73307605803DEA3743A0E83D53A0E84870F8EC2B483CE91F27BCE8008000E8008000E8008000E815C020E915C020E915C020E915C020E9183A41E91D3241E92A4020E9563D56DF463746DF4E3F4EDF163020E94F3F4FDF32322DDF22222DDF12122DDF3A3A2DDF473747DF573D57DF3DCF74C037CF74C40A444CB0024454B031532F9F343720E939E52C9F3C3D20E92A444CB21A4454B226803AEA0A20022088735EE92A201A203DCF74C227CF74C630502E9F32315FE938212C9F33395FE931532F9F9C2720E90A444CB4024454B42A444CB61A4454B639E52C9F383D20E90A2002202A201A203DCF75C6008000E830502E9F3E304FE938212C9F3F384FE90A454DB6024555B631532F9F3A314FE939E52C9F3B394FE9313D20E90A2002202A464EBF1A4656BF0A474FBF024757BF30502E9F36304FE938212C9F37384FE931532F9F9D314FE939E52C9F9E394FE92A434BBF1A4353BF30502E9F35304FE938212C9F39384FE931532F9F803157E939E52C9F813957E9374850BD8A3620E9867657E98B3E20E9823057E9877757E9833857E9354951BD84315EE9301F5FE985395EE9572520E92B4820E91D37E1EA1E35E1EA00E02677244920E9A6FF20EA162620E9572EBFEA1C46A0E8234EA0E82B56A0E81D47A0E8244FA0E82C57A0E81C0023002B0000E01D0024002C0000E01C6523652B6500E01D6524652C6500E01C2360EC36D736AD2B8060EC1D2460EC3ED73EAD2C8060EC1C2BDEE82380DEE8368036BD3E803EBD33D71CBD3BD723BD468046CF4F804FCF563356CF473B47CFCDFF20EA008000E84E334ECF573B57CF94FF20EA57C0BFEA0080A0E90000D8EC89
-/* TGZS */
-:03A0000000008898E9008000E80080A0E90000D8ECFF80C0E9008000E8224048BF2A4050BF324149BF3A4151BFC36BCB6B008898E9737BC8EC96E241047B43A0E8734BA0E8ADEE299F00E0490490E251043146B1E84941C0EC3957B1E8000446E27353A0E85141C0EC31003900658015EA080410045149C0EC2F4160EA312039201F42A0E82A424ABF274AA0E81A4252BF1E4960EA737BC8EC265160EA324048BD224050BD124149BD3A4151BDBF2F26BD00E07B723220222012203A20463146BF4E314EBFB3E22D9F008000E8563156BF473947BF4F394FBF573957BF578007EA244120E94273F8EC00E02D7333720CE3A52F1EBD43432DDF4B4B2DDFAE1E26BD58E3336653532DDF008000E8B83833BF00E059E31E1241E91A2241E92B403DE93F4BA0E82D73307605803DEA3743A0E83D53A0E84870F8EC2B483CE91F27BCE8008000E8008000E8008000E815C020E915C020E915C020E915C020E9183A41E91D3241E92A4020E9563D56DF463746DF4E3F4EDF163020E94F3F4FDF473747DF573D57DF32322DDF22222DDF12122DDF3A3A2DDF27CF74C237CF74C40A444CB0024454B03DCF74C0343720E931532F9F382720E939E52C9F3C3D20E92A444CB21A4454B229803AEA0A20022027CF75C02A201A2030502E9F32315FE938212C9F33395FE93DCF75C237CF75C431532F9FA62720E939E52C9FA33D20E92A444CB41A4454B40A454DB0024555B088735EE92A201A20A03720E90A20022031532F9F3E304FE939E52C9F3F384FE930502E9F3A314FE92A454DB21A4555B20A454DB4024555B438212C9F3B394FE90A2002202A201A202A464EBF1A4656BF31532F9F36314FE939E52C9F37394FE930502E9FA7304FE938212C9FA8384FE90A474FBF024757BF31532F9FA4314FE939E52C9FA5394FE92A434BBF1A4353BF30502E9FA1304FE938212C9FA2384FE931532F9F803157E939E52C9F813957E9374850BD8A3620E9867657E98B3E20E9823057E9877757E9833857E9354951BD84315EE9301F5FE985395EE9572520E92B4820E91D37E1EA1E35E1EA00E02677244920E9A2FF20EA162620E9572EBFEA1C46A0E8234EA0E82B56A0E81D47A0E8244FA0E82C57A0E81C0023002B0000E01D0024002C0000E01C6523652B6500E01D6524652C6500E01C2360EC36D736AD2B8060EC1D2460EC3ED73EAD2C8060EC1C2BDEE82380DEE8368036BD3E803EBD33D71CBD3BD723BD468046CF4F804FCF563356CF473B47CFCAFF20EA008000E84E334ECF573B57CF90FF20EA57C0BFEA0080A0E90000D8ECD8
-/* TGZSF */
-:03C8000000008898E9008000E80080A0E90000D8ECFF80C0E9008000E8224048BF2A4050BF324149BF3A4151BFC36BCB6B008898E9737BC8EC96E241047B43A0E8734BA0E8ADEE299F00E0490490E251043146B1E84941C0EC3957B1E8000446E27353A0E85141C0EC310039006A8015EA080410045149C0EC2F4160EA312039201F42A0E82A424ABF274AA0E81A4252BF1E4960EA737BC8EC265160EA324048BD224050BD124149BD3A4151BDBF2F26BD00E07B723220222012203A20463146BF4E314EBFB3E22D9F008000E8563156BF473947BF4F394FBF573957BF5C8007EA244120E94273F8EC00E02D7333720CE3A52F1EBD43432DDF4B4B2DDFAE1E26BD58E3336653532DDF008000E8B83833BF00E059E31E1241E91A2241E92B403DE93F4BA0E82D73307605803DEA3743A0E83D53A0E84870F8EC2B483CE91F27BCE8008000E8008000E8008000E815C020E915C020E915C020E915C020E9183A41E91D3241E92A4020E9563D56DF463746DF4E3F4EDF163020E94F3F4FDF473747DF573D57DF32322DDF22222DDF12122DDF3A3A2DDF27CF74C237CF74C40A444CB0024454B03DCF74C0343720E931532F9F382720E939E52C9F3C3D20E92A444CB21A4454B22E803AEA0A20022027CF75C02A201A2030502E9F32315FE938212C9F33395FE93DCF75C237CF75C431532F9FA62720E939E52C9FA33D20E92A444CB41A4454B40A454DB0024555B088735EE92A201A20A03720E90A20022031532F9F3E304FE939E52C9F3F384FE930502E9F3A314FE938212C9F3B394FE92A454DB21A4555B20A454DB4024555B427CF75C62A201A20A7304FE90A20022031532F9F312720E939E52C9FA8384FE92A454DB61A4555B630502E9F36314FE938212C9F37394FE9008000E82A201A202A464EBF1A4656BF31532F9FA4314FE939E52C9FA5394FE90A474FBF024757BF31532F9FA1304FE939E52C9FA2384FE92A434BBF1A4353BF30502E9F35314FE938212C9F39394FE931532F9F803157E939E52C9F813957E9374850BD8A3620E9867657E98B3E20E9823057E9877757E9833857E9354951BD84315EE9301F5FE985395EE9572520E92B4820E91D37E1EA1E35E1EA00E02677244920E99DFF20EA162620E9572EBFEA1C46A0E8234EA0E82B56A0E81D47A0E8244FA0E82C57A0E81C0023002B0000E01D0024002C0000E01C6523652B6500E01D6524652C6500E01C2360EC36D736AD2B8060EC1D2460EC3ED73EAD2C8060EC1C2BDEE82380DEE8368036BD3E803EBD33D71CBD3BD723BD468046CF4F804FCF563356CF473B47CFC5FF20EA008000E84E334ECF573B57CF8BFF20EA57C0BFEA0080A0E90000D8ECD3
-/* TGZSA */
-:03C8000000008898E9008000E80080A0E90000D8ECFF80C0E9008000E8224048BF2A4050BF324149BF3A4151BFC36BCB6B008898E9737BC8EC96E241047B43A0E8734BA0E8ADEE299F00E0490490E251043146B1E84941C0EC3957B1E8000446E27353A0E85141C0EC310039006A8015EA080410045149C0EC2F4160EA312039201F42A0E82A424ABF274AA0E81A4252BF1E4960EA737BC8EC265160EA324048BD224050BD124149BD3A4151BDBF2F26BD00E07B723220222012203A20463146BF4E314EBFB3E22D9F008000E8563156BF473947BF4F394FBF573957BF5C8007EA244120E94273F8EC00E02D7333720CE3A52F1EBD43432DDF4B4B2DDFAE1E26BD58E3336653532DDF008000E8B83833BF00E059E31E1241E91A2241E92B403DE93F4BA0E82D73307605803DEA3743A0E83D53A0E84870F8EC2B483CE91F27BCE8008000E8008000E8008000E815C020E915C020E915C020E915C020E9183A41E91D3241E92A4020E9563D56DF463746DF4E3F4EDF163020E94F3F4FDF473747DF573D57DF32322DDF22222DDF12122DDF3A3A2DDF27CF74C237CF74C40A444CB0024454B03DCF74C0343720E931532F9F382720E939E52C9F3C3D20E92A444CB21A4454B22E803AEA0A20022027CF75C02A201A2030502E9F32315FE938212C9F33395FE93DCF75C237CF75C431532F9FA62720E939E52C9FA33D20E92A444CB41A4454B40A454DB0024555B088735EE92A201A20A03720E90A20022031532F9F3E304FE939E52C9F3F384FE930502E9F3A314FE938212C9F3B394FE92A454DB21A4555B20A454DB4024555B427CF74C62A201A20A7304FE90A20022031532F9F9C2720E939E52C9FA8384FE92A444CB61A4454B630502E9F36314FE938212C9F37394FE9008000E82A201A202A464EBF1A4656BF31532F9FA4314FE939E52C9FA5394FE90A474FBF024757BF31532F9FA1304FE939E52C9FA2384FE92A434BBF1A4353BF30502E9F9D314FE938212C9F9E394FE931532F9F803157E939E52C9F813957E9374850BD8A3620E9867657E98B3E20E9823057E9877757E9833857E9354951BD84315EE9301F5FE985395EE9572520E92B4820E91D37E1EA1E35E1EA00E02677244920E99DFF20EA162620E9572EBFEA1C46A0E8234EA0E82B56A0E81D47A0E8244FA0E82C57A0E81C0023002B0000E01D0024002C0000E01C6523652B6500E01D6524652C6500E01C2360EC36D736AD2B8060EC1D2460EC3ED73EAD2C8060EC1C2BDEE82380DEE8368036BD3E803EBD33D71CBD3BD723BD468046CF4F804FCF563356CF473B47CFC5FF20EA008000E84E334ECF573B57CF8BFF20EA57C0BFEA0080A0E90000D8ECA0
-/* TGZSAF */
-:03E8000000008898E9008000E80080A0E90000D8ECFF80C0E9008000E8224048BF2A4050BF324149BF3A4151BFC36BCB6B008898E9737BC8EC96E241047B43A0E8734BA0E8ADEE299F00E0490490E251043146B1E84941C0EC3957B1E8000446E27353A0E85141C0EC310039006E8015EA080410045149C0EC2F4160EA312039201F42A0E82A424ABF274AA0E81A4252BF1E4960EA737BC8EC265160EA324048BD224050BD124149BD3A4151BDBF2F26BD00E07B723220222012203A20463146BF4E314EBFB3E22D9F008000E8563156BF473947BF4F394FBF573957BF608007EA244120E94273F8EC00E02D7333720CE3A52F1EBD43432DDF4B4B2DDFAE1E26BD58E3336653532DDF008000E8B83833BF00E059E31E1241E91A2241E92B403DE93F4BA0E82D73307605803DEA3743A0E83D53A0E84870F8EC2B483CE91F27BCE8008000E8008000E8008000E815C020E915C020E915C020E915C020E9183A41E91D3241E92A4020E9563D56DF463746DF4E3F4EDF163020E94F3F4FDF473747DF573D57DF32322DDF22222DDF12122DDF3A3A2DDF27CF74C237CF74C40A444CB0024454B03DCF74C0343720E931532F9F382720E939E52C9F3C3D20E92A444CB21A4454B232803AEA0A20022027CF75C02A201A2030502E9F32315FE938212C9F33395FE93DCF75C237CF75C431532F9FA62720E939E52C9FA33D20E92A444CB41A4454B40A454DB0024555B088735EE92A201A20A03720E90A20022031532F9F3E304FE939E52C9F3F384FE930502E9F3A314FE938212C9F3B394FE92A454DB21A4555B20A454DB4024555B427CF74C62A201A20A7304FE90A20022031532F9F9C2720E939E52C9FA8384FE92A444CB61A4454B630502E9F36314FE938212C9F37394FE90A454DB6024555B63DCF75C62A201A202A464EBF1A4656BF31532F9FA4314FE939E52C9FA5394FE9313D20E90A2002200A474FBF024757BF30502E9FA1304FE938212C9FA2384FE931532F9F9D314FE939E52C9F9E394FE92A434BBF1A4353BF30502E9F35304FE938212C9F39384FE931532F9F803157E939E52C9F813957E9374850BD8A3620E9867657E98B3E20E9823057E9877757E9833857E9354951BD84315EE9301F5FE985395EE9572520E92B4820E91D37E1EA1E35E1EA00E02677244920E999FF20EA162620E9572EBFEA1C46A0E8234EA0E82B56A0E81D47A0E8244FA0E82C57A0E81C0023002B0000E01D0024002C0000E01C6523652B6500E01D6524652C6500E01C2360EC36D736AD2B8060EC1D2460EC3ED73EAD2C8060EC1C2BDEE82380DEE8368036BD3E803EBD33D71CBD3BD723BD468046CF4F804FCF563356CF473B47CFC1FF20EA008000E84E334ECF573B57CF87FF20EA57C0BFEA0080A0E90000D8EC83
-/* T2GZ */
-:0438000000008A98E9008000E80080A0E90000D8ECFF80C0E9008000E80A4050BF2A4060BF324151BF3A4161BFC36BD36B008A98E9737BC8EC96E241047B43A0E87353A0E8ADEE239F00E0510490E261043146B1E85141E0EC3967B1E8000446E27363A0E86141E0EC31003900788015EA100420046151E0EC2F4160EA312039201F42A0E82A4252BF0F52A0E81A4262BF1E5160EA737BC8EC0E6160EA324050BD224060BD124151BD3A4161BDBF2F0EBD97E27B723220222012203A203548B1E83D59B1E8463146BF563156BFB3E22D9F008000E8663166BF473947BF573957BF673967BF698007EA244120E935003D0000E02D7333720CE38D2F1EBD4375F8EC35203D2043432DDF53532DDFAE1E0EBD58E33366483548BF583558BF683568BF493D49BF593D59BF693D69BF63632DDF4D7DF8EC59E300E0B83833BF2D733076183A41E93F53A0E805803DEA3743A0E83D63A0E85070F8EC2B503CE91F0FBCE8008000E85978F8EC008000E815C020E915C020E915C020E915C020E91E1241E91A2241E9463746DF563F56DF2B403DE9663D66DF1D3241E9673D67DF473747DF573F57DF2A4020E9593F59DF163020E9693D69DF483748DF583F58DF12122DDF22222DDF32322DDF3A3A2DDF683D68DF493749DF3DCF74C037CF74C431532F9F348020E939E52C9F3C3D20E90A4454B0024464B02A4454B21A4464B225803AEA0A2002203DCF74C22A201A2030502E9F32315FE938212C9F33395FE931532F9F008000E82A4454B41A4464B439E52C9F383D20E988735EE92A201A202A4656BF1A4666BF31532F9F3E304FE939E52C9F3F384FE90A4757BF024767BF31532F9F3A314FE939E52C9F3B394FE92A4353BF1A4363BF30502E9F36314FE938212C9F37394FE90A4858BF024868BF31532F9F803157E939E52C9F813957E92A4959BF1A4969BF30502E9F823057E938212C9F833857E931532F9F84315EE939E52C9F85395EE9867657E98A3620E9877757E98B3EBFEA803057E9813857E9823157E9867857E9833957E9877957E9301F5FE98A3420E98B3C20E9375060BD570D20E9355161BD2B5020E91D37E1EA1E35E1EA00E00E77245120E99FFF20EA160E20E9572EBFEA0B46A0E81B56A0E82B66A0E80C47A0E81C57A0E82C67A0E80B001B002B0000E00C001C002C0000E00B651B652B6500E00C651C652C6500E00B1B60EC36D736AD2B8060EC0C1C60EC3ED73EAD2C8060EC0B2BDEE81B80DEE8368036BD3E803EBD33D70BBD3BD71BBD468046CF578057CF663366CF473B47CF563356CF673B67CF0B48A0E81B58A0E82B68A0E80C49A0E81C59A0E82C69A0E80B001B002B0000E00C001C002C0000E00B651B652B6500E00C651C652C6500E00B1B60EC34D734AD2B8060EC0C1C60EC3CD73CAD2C8060EC0B2BDEE81B80DEE8348034BD3C803CBD33D70BBD3BD71BBD488048CF598059CF683368CF493B49CFBEFF20EA008000E8583358CF693B69CF7DFF20EA57C0BFEA0080A0E90000D8ECAC
-/* T2GZF */
-:0460000000008A98E9008000E80080A0E90000D8ECFF80C0E9008000E80A4050BF2A4060BF324151BF3A4161BFC36BD36B008A98E9737BC8EC96E241047B43A0E87353A0E8ADEE239F00E0510490E261043146B1E85141E0EC3967B1E8000446E27363A0E86141E0EC310039007D8015EA100420046151E0EC2F4160EA312039201F42A0E82A4252BF0F52A0E81A4262BF1E5160EA737BC8EC0E6160EA324050BD224060BD124151BD3A4161BDBF2F0EBD97E27B723220222012203A203548B1E83D59B1E8463146BF563156BFB3E22D9F008000E8663166BF473947BF573957BF673967BF6E8007EA244120E935003D0000E02D7333720CE38D2F1EBD4375F8EC35203D2043432DDF53532DDFAE1E0EBD58E33366483548BF583558BF683568BF493D49BF593D59BF693D69BF63632DDF4D7DF8EC59E300E0B83833BF2D733076183A41E93F53A0E805803DEA3743A0E83D63A0E85070F8EC2B503CE91F0FBCE8008000E85978F8EC008000E815C020E915C020E915C020E915C020E91E1241E91A2241E9463746DF563F56DF2B403DE9663D66DF1D3241E9673D67DF473747DF573F57DF2A4020E9593F59DF163020E9693D69DF483748DF583F58DF12122DDF22222DDF32322DDF3A3A2DDF683D68DF493749DF3DCF74C037CF74C439E52C9F348020E931532F9F008000E888735EE9008000E80FCF75C63C3D20E90A4454B0024464B02A4454B21A4464B228803AEA0A2002203DCF74C22A201A2030502E9F32315FE938212C9F33395FE931532F9F310F20E90A4454B4024464B42A4555B61A4565B639E52C9F383D20E90A2002202A201A200A4757BF024767BF30502E9F3E304FE938212C9F3F384FE92A4656BF1A4666BF31532F9F3A314FE939E52C9F3B394FE931532F9F36304FE939E52C9F37384FE92A4353BF1A4363BF30502E9F35314FE938212C9F39394FE90A4858BF024868BF31532F9F803157E939E52C9F813957E92A4959BF1A4969BF30502E9F823057E938212C9F833857E931532F9F84315EE939E52C9F85395EE9867657E98A3620E9877757E98B3EBFEA803057E9813857E9823157E9867857E9833957E9877957E9301F5FE98A3420E98B3C20E9375060BD570D20E9355161BD2B5020E91D37E1EA1E35E1EA00E00E77245120E99AFF20EA160E20E9572EBFEA0B46A0E81B56A0E82B66A0E80C47A0E81C57A0E82C67A0E80B001B002B0000E00C001C002C0000E00B651B652B6500E00C651C652C6500E00B1B60EC36D736AD2B8060EC0C1C60EC3ED73EAD2C8060EC0B2BDEE81B80DEE8368036BD3E803EBD33D70BBD3BD71BBD468046CF578057CF663366CF473B47CF563356CF673B67CF0B48A0E81B58A0E82B68A0E80C49A0E81C59A0E82C69A0E80B001B002B0000E00C001C002C0000E00B651B652B6500E00C651C652C6500E00B1B60EC34D734AD2B8060EC0C1C60EC3CD73CAD2C8060EC0B2BDEE81B80DEE8348034BD3C803CBD33D70BBD3BD71BBD488048CF598059CF683368CF493B49CFBBFF20EA008000E8583358CF693B69CF78FF20EA57C0BFEA0080A0E90000D8ECFB
-/* T2GZA */
-:0458000000008A98E9008000E80080A0E90000D8ECFF80C0E9008000E80A4050BF2A4060BF324151BF3A4161BFC36BD36B008A98E9737BC8EC96E241047B43A0E87353A0E8ADEE239F00E0510490E261043146B1E85141E0EC3967B1E8000446E27363A0E86141E0EC310039007C8015EA100420046151E0EC2F4160EA312039201F42A0E82A4252BF0F52A0E81A4262BF1E5160EA737BC8EC0E6160EA324050BD224060BD124151BD3A4161BDBF2F0EBD97E27B723220222012203A203548B1E83D59B1E8463146BF563156BFB3E22D9F008000E8663166BF473947BF573957BF673967BF6D8007EA244120E935003D0000E02D7333720CE38D2F1EBD4375F8EC35203D2043432DDF53532DDFAE1E0EBD58E33366483548BF583558BF683568BF493D49BF593D59BF693D69BF63632DDF4D7DF8EC59E300E0B83833BF2D733076183A41E93F53A0E805803DEA3743A0E83D63A0E85070F8EC2B503CE91F0FBCE8008000E85978F8EC008000E815C020E915C020E915C020E915C020E91E1241E91A2241E9463746DF563F56DF2B403DE9663D66DF1D3241E9673D67DF473747DF573F57DF2A4020E9593F59DF163020E9693D69DF483748DF583F58DF12122DDF22222DDF32322DDF3A3A2DDF683D68DF493749DF3DCF74C037CF74C431532F9F348020E939E52C9F3C3D20E90A4454B0024464B02A4454B21A4464B229803AEA0A2002200FCF74C63DCF74C288735EE92A201A2030502E9F32315FE938212C9F33395FE931532F9F9C0F20E90A4454B4024464B42A4454B61A4464B639E52C9F383D20E90A2002202A201A200A4757BF024767BF30502E9F3E304FE938212C9F3F384FE92A4656BF1A4666BF31532F9F3A314FE939E52C9F3B394FE931532F9F36304FE939E52C9F37384FE92A4353BF1A4363BF30502E9F9D314FE938212C9F9E394FE90A4858BF024868BF31532F9F803157E939E52C9F813957E92A4959BF1A4969BF30502E9F823057E938212C9F833857E931532F9F84315EE939E52C9F85395EE9867657E98A3620E9877757E98B3EBFEA803057E9813857E9823157E9867857E9833957E9877957E9301F5FE98A3420E98B3C20E9375060BD570D20E9355161BD2B5020E91D37E1EA1E35E1EA00E00E77245120E99BFF20EA160E20E9572EBFEA0B46A0E81B56A0E82B66A0E80C47A0E81C57A0E82C67A0E80B001B002B0000E00C001C002C0000E00B651B652B6500E00C651C652C6500E00B1B60EC36D736AD2B8060EC0C1C60EC3ED73EAD2C8060EC0B2BDEE81B80DEE8368036BD3E803EBD33D70BBD3BD71BBD468046CF578057CF663366CF473B47CF563356CF673B67CF0B48A0E81B58A0E82B68A0E80C49A0E81C59A0E82C69A0E80B001B002B0000E00C001C002C0000E00B651B652B6500E00C651C652C6500E00B1B60EC34D734AD2B8060EC0C1C60EC3CD73CAD2C8060EC0B2BDEE81B80DEE8348034BD3C803CBD33D70BBD3BD71BBD488048CF598059CF683368CF493B49CFBAFF20EA008000E8583358CF693B69CF79FF20EA57C0BFEA0080A0E90000D8ECA0
-/* T2GZAF */
-:0480000000008A98E9008000E80080A0E90000D8ECFF80C0E9008000E80A4050BF2A4060BF324151BF3A4161BFC36BD36B008A98E9737BC8EC96E241047B43A0E87353A0E8ADEE239F00E0510490E261043146B1E85141E0EC3967B1E8000446E27363A0E86141E0EC31003900818015EA100420046151E0EC2F4160EA312039201F42A0E82A4252BF0F52A0E81A4262BF1E5160EA737BC8EC0E6160EA324050BD224060BD124151BD3A4161BDBF2F0EBD97E27B723220222012203A203548B1E83D59B1E8463146BF563156BFB3E22D9F008000E8663166BF473947BF573957BF673967BF728007EA244120E935003D0000E02D7333720CE38D2F1EBD4375F8EC35203D2043432DDF53532DDFAE1E0EBD58E33366483548BF583558BF683568BF493D49BF593D59BF693D69BF63632DDF4D7DF8EC59E300E0B83833BF2D733076183A41E93F53A0E805803DEA3743A0E83D63A0E85070F8EC2B503CE91F0FBCE8008000E85978F8EC008000E815C020E915C020E915C020E915C020E91E1241E91A2241E9463746DF563F56DF2B403DE9663D66DF1D3241E9673D67DF473747DF573F57DF2A4020E9593F59DF163020E9693D69DF483748DF583F58DF12122DDF22222DDF32322DDF3A3A2DDF683D68DF493749DF3DCF74C037CF74C40A4454B0024464B031532F9F343720E939E52C9F3C3D20E92A4454B21A4464B22E803AEA0A20022088735EE92A201A203DCF74C20FCF74C630502E9F32315FE938212C9F33395FE931532F9F9C0F20E90A4454B4024464B42A4454B61A4464B639E52C9F383D20E90A2002202A201A203DCF75C6008000E830502E9F3E304FE938212C9F3F384FE90A4555B6024565B631532F9F3A314FE939E52C9F3B394FE9313D20E90A2002202A4656BF1A4666BF0A4757BF024767BF30502E9F36304FE938212C9F37384FE931532F9F9D314FE939E52C9F9E394FE92A4353BF1A4363BF30502E9F35304FE938212C9F39384FE90A4858BF024868BF31532F9F803157E939E52C9F813957E92A4959BF1A4969BF30502E9F823057E938212C9F833857E931532F9F84315EE939E52C9F85395EE9867657E98A3620E9877757E98B3EBFEA803057E9813857E9823157E9867857E9833957E9877957E9301F5FE98A3420E98B3C20E9375060BD570D20E9355161BD2B5020E91D37E1EA1E35E1EA00E00E77245120E996FF20EA160E20E9572EBFEA0B46A0E81B56A0E82B66A0E80C47A0E81C57A0E82C67A0E80B001B002B0000E00C001C002C0000E00B651B652B6500E00C651C652C6500E00B1B60EC36D736AD2B8060EC0C1C60EC3ED73EAD2C8060EC0B2BDEE81B80DEE8368036BD3E803EBD33D70BBD3BD71BBD468046CF578057CF663366CF473B47CF563356CF673B67CF0B48A0E81B58A0E82B68A0E80C49A0E81C59A0E82C69A0E80B001B002B0000E00C001C002C0000E00B651B652B6500E00C651C652C6500E00B1B60EC34D734AD2B8060EC0C1C60EC3CD73CAD2C8060EC0B2BDEE81B80DEE8348034BD3C803CBD33D70BBD3BD71BBD488048CF598059CF683368CF493B49CFB5FF20EA008000E8583358CF693B69CF74FF20EA57C0BFEA0080A0E90000D8ECDC
-/* T2GZS */
-:04A0000000008A98E9008000E80080A0E90000D8ECFF80C0E9008000E80A4050BF2A4060BF324151BF3A4161BFC36BD36B008A98E9737BC8EC96E241047B43A0E87353A0E8ADEE239F00E0510490E261043146B1E85141E0EC3967B1E8000446E27363A0E86141E0EC31003900858015EA100420046151E0EC2F4160EA312039201F42A0E82A4252BF0F52A0E81A4262BF1E5160EA737BC8EC0E6160EA324050BD224060BD124151BD3A4161BDBF2F0EBD97E27B723220222012203A203548B1E83D59B1E8463146BF563156BFB3E22D9F008000E8663166BF473947BF573957BF673967BF768007EA244120E935003D0000E02D7333720CE38D2F1EBD4375F8EC35203D2043432DDF53532DDFAE1E0EBD58E33366483548BF583558BF683568BF493D49BF593D59BF693D69BF63632DDF4D7DF8EC59E300E0B83833BF2D733076183A41E93F53A0E805803DEA3743A0E83D63A0E85070F8EC2B503CE91F0FBCE8008000E85978F8EC008000E815C020E915C020E915C020E915C020E91E1241E91A2241E9463746DF563F56DF2B403DE9663D66DF1D3241E9673D67DF473747DF573F57DF2A4020E9593F59DF163020E9693D69DF483748DF583F58DF683D68DF493749DF32322DDF22222DDF12122DDF3A3A2DDF0FCF74C237CF74C40A4454B0024464B03DCF74C0343720E931532F9F380F20E939E52C9F3C3D20E92A4454B21A4464B231803AEA0A2002200FCF75C02A201A2030502E9F32315FE938212C9F33395FE93DCF75C237CF75C431532F9FA60F20E939E52C9FA33D20E92A4454B41A4464B40A4555B0024565B088735EE92A201A20A03720E90A20022031532F9F3E304FE939E52C9F3F384FE930502E9F3A314FE92A4555B21A4565B20A4555B4024565B438212C9F3B394FE92A201A200A2002202A4656BF1A4666BF31532F9F36314FE939E52C9F37394FE930502E9FA7304FE938212C9FA8384FE90A4757BF024767BF31532F9FA4314FE939E52C9FA5394FE92A4353BF1A4363BF30502E9FA1304FE938212C9FA2384FE90A4858BF024868BF31532F9F803157E939E52C9F813957E92A4959BF1A4969BF30502E9F823057E938212C9F833857E931532F9F84315EE939E52C9F85395EE9867657E98A3620E9877757E98B3EBFEA803057E9813857E9823157E9867857E9833957E9877957E9301F5FE98A3420E98B3C20E9375060BD570D20E9355161BD2B5020E91D37E1EA1E35E1EA00E00E77245120E992FF20EA160E20E9572EBFEA0B46A0E81B56A0E82B66A0E80C47A0E81C57A0E82C67A0E80B001B002B0000E00C001C002C0000E00B651B652B6500E00C651C652C6500E00B1B60EC36D736AD2B8060EC0C1C60EC3ED73EAD2C8060EC0B2BDEE81B80DEE8368036BD3E803EBD33D70BBD3BD71BBD468046CF578057CF663366CF473B47CF563356CF673B67CF0B48A0E81B58A0E82B68A0E80C49A0E81C59A0E82C69A0E80B001B002B0000E00C001C002C0000E00B651B652B6500E00C651C652C6500E00B1B60EC34D734AD2B8060EC0C1C60EC3CD73CAD2C8060EC0B2BDEE81B80DEE8348034BD3C803CBD33D70BBD3BD71BBD488048CF598059CF683368CF493B49CFB2FF20EA008000E8583358CF693B69CF70FF20EA57C0BFEA0080A0E90000D8EC43
-/* T2GZSF */
-:04C8000000008A98E9008000E80080A0E90000D8ECFF80C0E9008000E80A4050BF2A4060BF324151BF3A4161BFC36BD36B008A98E9737BC8EC96E241047B43A0E87353A0E8ADEE239F00E0510490E261043146B1E85141E0EC3967B1E8000446E27363A0E86141E0EC310039008A8015EA100420046151E0EC2F4160EA312039201F42A0E82A4252BF0F52A0E81A4262BF1E5160EA737BC8EC0E6160EA324050BD224060BD124151BD3A4161BDBF2F0EBD97E27B723220222012203A203548B1E83D59B1E8463146BF563156BFB3E22D9F008000E8663166BF473947BF573957BF673967BF7B8007EA244120E935003D0000E02D7333720CE38D2F1EBD4375F8EC35203D2043432DDF53532DDFAE1E0EBD58E33366483548BF583558BF683568BF493D49BF593D59BF693D69BF63632DDF4D7DF8EC59E300E0B83833BF2D733076183A41E93F53A0E805803DEA3743A0E83D63A0E85070F8EC2B503CE91F0FBCE8008000E85978F8EC008000E815C020E915C020E915C020E915C020E91E1241E91A2241E9463746DF563F56DF2B403DE9663D66DF1D3241E9673D67DF473747DF573F57DF2A4020E9593F59DF163020E9693D69DF483748DF583F58DF683D68DF493749DF32322DDF22222DDF12122DDF3A3A2DDF0FCF74C237CF74C40A4454B0024464B03DCF74C0343720E931532F9F380F20E939E52C9F3C3D20E92A4454B21A4464B236803AEA0A2002200FCF75C02A201A2030502E9F32315FE938212C9F33395FE93DCF75C237CF75C431532F9FA60F20E939E52C9FA33D20E92A4454B41A4464B40A4555B0024565B088735EE92A201A20A03720E90A20022031532F9F3E304FE939E52C9F3F384FE930502E9F3A314FE938212C9F3B394FE92A4555B21A4565B20A4555B4024565B40FCF75C62A201A20A7304FE90A20022031532F9F310F20E939E52C9FA8384FE92A4555B61A4565B630502E9F36314FE938212C9F37394FE9008000E82A201A202A4656BF1A4666BF31532F9FA4314FE939E52C9FA5394FE90A4757BF024767BF31532F9FA1304FE939E52C9FA2384FE92A4353BF1A4363BF30502E9F35314FE938212C9F39394FE90A4858BF024868BF31532F9F803157E939E52C9F813957E92A4959BF1A4969BF30502E9F823057E938212C9F833857E931532F9F84315EE939E52C9F85395EE9867657E98A3620E9877757E98B3EBFEA803057E9813857E9823157E9867857E9833957E9877957E9301F5FE98A3420E98B3C20E9375060BD570D20E9355161BD2B5020E91D37E1EA1E35E1EA00E00E77245120E98DFF20EA160E20E9572EBFEA0B46A0E81B56A0E82B66A0E80C47A0E81C57A0E82C67A0E80B001B002B0000E00C001C002C0000E00B651B652B6500E00C651C652C6500E00B1B60EC36D736AD2B8060EC0C1C60EC3ED73EAD2C8060EC0B2BDEE81B80DEE8368036BD3E803EBD33D70BBD3BD71BBD468046CF578057CF663366CF473B47CF563356CF673B67CF0B48A0E81B58A0E82B68A0E80C49A0E81C59A0E82C69A0E80B001B002B0000E00C001C002C0000E00B651B652B6500E00C651C652C6500E00B1B60EC34D734AD2B8060EC0C1C60EC3CD73CAD2C8060EC0B2BDEE81B80DEE8348034BD3C803CBD33D70BBD3BD71BBD488048CF598059CF683368CF493B49CFADFF20EA008000E8583358CF693B69CF6BFF20EA57C0BFEA0080A0E90000D8EC56
-/* T2GZSA */
-:04C8000000008A98E9008000E80080A0E90000D8ECFF80C0E9008000E80A4050BF2A4060BF324151BF3A4161BFC36BD36B008A98E9737BC8EC96E241047B43A0E87353A0E8ADEE239F00E0510490E261043146B1E85141E0EC3967B1E8000446E27363A0E86141E0EC310039008A8015EA100420046151E0EC2F4160EA312039201F42A0E82A4252BF0F52A0E81A4262BF1E5160EA737BC8EC0E6160EA324050BD224060BD124151BD3A4161BDBF2F0EBD97E27B723220222012203A203548B1E83D59B1E8463146BF563156BFB3E22D9F008000E8663166BF473947BF573957BF673967BF7B8007EA244120E935003D0000E02D7333720CE38D2F1EBD4375F8EC35203D2043432DDF53532DDFAE1E0EBD58E33366483548BF583558BF683568BF493D49BF593D59BF693D69BF63632DDF4D7DF8EC59E300E0B83833BF2D733076183A41E93F53A0E805803DEA3743A0E83D63A0E85070F8EC2B503CE91F0FBCE8008000E85978F8EC008000E815C020E915C020E915C020E915C020E91E1241E91A2241E9463746DF563F56DF2B403DE9663D66DF1D3241E9673D67DF473747DF573F57DF2A4020E9593F59DF163020E9693D69DF483748DF583F58DF683D68DF493749DF32322DDF22222DDF12122DDF3A3A2DDF0FCF74C237CF74C40A4454B0024464B03DCF74C0343720E931532F9F380F20E939E52C9F3C3D20E92A4454B21A4464B236803AEA0A2002200FCF75C02A201A2030502E9F32315FE938212C9F33395FE93DCF75C237CF75C431532F9FA60F20E939E52C9FA33D20E92A4454B41A4464B40A4555B0024565B088735EE92A201A20A03720E90A20022031532F9F3E304FE939E52C9F3F384FE930502E9F3A314FE938212C9F3B394FE92A4555B21A4565B20A4555B4024565B40FCF74C62A201A20A7304FE90A20022031532F9F9C0F20E939E52C9FA8384FE92A4454B61A4464B630502E9F36314FE938212C9F37394FE9008000E82A201A202A4656BF1A4666BF31532F9FA4314FE939E52C9FA5394FE90A4757BF024767BF31532F9FA1304FE939E52C9FA2384FE92A4353BF1A4363BF30502E9F9D314FE938212C9F9E394FE90A4858BF024868BF31532F9F803157E939E52C9F813957E92A4959BF1A4969BF30502E9F823057E938212C9F833857E931532F9F84315EE939E52C9F85395EE9867657E98A3620E9877757E98B3EBFEA803057E9813857E9823157E9867857E9833957E9877957E9301F5FE98A3420E98B3C20E9375060BD570D20E9355161BD2B5020E91D37E1EA1E35E1EA00E00E77245120E98DFF20EA160E20E9572EBFEA0B46A0E81B56A0E82B66A0E80C47A0E81C57A0E82C67A0E80B001B002B0000E00C001C002C0000E00B651B652B6500E00C651C652C6500E00B1B60EC36D736AD2B8060EC0C1C60EC3ED73EAD2C8060EC0B2BDEE81B80DEE8368036BD3E803EBD33D70BBD3BD71BBD468046CF578057CF663366CF473B47CF563356CF673B67CF0B48A0E81B58A0E82B68A0E80C49A0E81C59A0E82C69A0E80B001B002B0000E00C001C002C0000E00B651B652B6500E00C651C652C6500E00B1B60EC34D734AD2B8060EC0C1C60EC3CD73CAD2C8060EC0B2BDEE81B80DEE8348034BD3C803CBD33D70BBD3BD71BBD488048CF598059CF683368CF493B49CFADFF20EA008000E8583358CF693B69CF6BFF20EA57C0BFEA0080A0E90000D8EC23
-/* T2GZSAF */
-:04E8000000008A98E9008000E80080A0E90000D8ECFF80C0E9008000E80A4050BF2A4060BF324151BF3A4161BFC36BD36B008A98E9737BC8EC96E241047B43A0E87353A0E8ADEE239F00E0510490E261043146B1E85141E0EC3967B1E8000446E27363A0E86141E0EC310039008E8015EA100420046151E0EC2F4160EA312039201F42A0E82A4252BF0F52A0E81A4262BF1E5160EA737BC8EC0E6160EA324050BD224060BD124151BD3A4161BDBF2F0EBD97E27B723220222012203A203548B1E83D59B1E8463146BF563156BFB3E22D9F008000E8663166BF473947BF573957BF673967BF7F8007EA244120E935003D0000E02D7333720CE38D2F1EBD4375F8EC35203D2043432DDF53532DDFAE1E0EBD58E33366483548BF583558BF683568BF493D49BF593D59BF693D69BF63632DDF4D7DF8EC59E300E0B83833BF2D733076183A41E93F53A0E805803DEA3743A0E83D63A0E85070F8EC2B503CE91F0FBCE8008000E85978F8EC008000E815C020E915C020E915C020E915C020E91E1241E91A2241E9463746DF563F56DF2B403DE9663D66DF1D3241E9673D67DF473747DF573F57DF2A4020E9593F59DF163020E9693D69DF483748DF583F58DF683D68DF493749DF32322DDF22222DDF12122DDF3A3A2DDF0FCF74C237CF74C40A4454B0024464B03DCF74C0343720E931532F9F380F20E939E52C9F3C3D20E92A4454B21A4464B23A803AEA0A2002200FCF75C02A201A2030502E9F32315FE938212C9F33395FE93DCF75C237CF75C431532F9FA60F20E939E52C9FA33D20E92A4454B41A4464B40A4555B0024565B088735EE92A201A20A03720E90A20022031532F9F3E304FE939E52C9F3F384FE930502E9F3A314FE938212C9F3B394FE92A4555B21A4565B20A4555B4024565B40FCF74C62A201A20A7304FE90A20022031532F9F9C0F20E939E52C9FA8384FE92A4454B61A4464B630502E9F36314FE938212C9F37394FE90A4555B6024565B63DCF75C62A201A202A4656BF1A4666BF31532F9FA4314FE939E52C9FA5394FE9313D20E90A2002200A4757BF024767BF30502E9FA1304FE938212C9FA2384FE931532F9F9D314FE939E52C9F9E394FE92A4353BF1A4363BF30502E9F35304FE938212C9F39384FE90A4858BF024868BF31532F9F803157E939E52C9F813957E92A4959BF1A4969BF30502E9F823057E938212C9F833857E931532F9F84315EE939E52C9F85395EE9867657E98A3620E9877757E98B3EBFEA803057E9813857E9823157E9867857E9833957E9877957E9301F5FE98A3420E98B3C20E9375060BD570D20E9355161BD2B5020E91D37E1EA1E35E1EA00E00E77245120E989FF20EA160E20E9572EBFEA0B46A0E81B56A0E82B66A0E80C47A0E81C57A0E82C67A0E80B001B002B0000E00C001C002C0000E00B651B652B6500E00C651C652C6500E00B1B60EC36D736AD2B8060EC0C1C60EC3ED73EAD2C8060EC0B2BDEE81B80DEE8368036BD3E803EBD33D70BBD3BD71BBD468046CF578057CF663366CF473B47CF563356CF673B67CF0B48A0E81B58A0E82B68A0E80C49A0E81C59A0E82C69A0E80B001B002B0000E00C001C002C0000E00B651B652B6500E00C651C652C6500E00B1B60EC34D734AD2B8060EC0C1C60EC3CD73CAD2C8060EC0B2BDEE81B80DEE8348034BD3C803CBD33D70BBD3BD71BBD488048CF598059CF683368CF493B49CFA9FF20EA008000E8583358CF693B69CF67FF20EA57C0BFEA0080A0E90000D8ECEE
-:0000000001FF
--- zfcpdump-kernel-4.4.orig/firmware/mts_cdma.fw.ihex
+++ /dev/null
@@ -1,867 +0,0 @@
-:1000000014360002001E021AF9FFFFFFFFFF023341
-:100010001DFFFFFFFFFFFFFFFFFFFFFFFFFF02339B
-:10002000C87581CE90FDE88583A012353CEC4D600B
-:100030007378AB8003760018B89CFA787F800376DB
-:100040000018B865FA78208003760018B820FA788E
-:10005000208003760018B81FFA90FDDDAE83AF82D2
-:1000600090FBF81200AA6005E4F0A380F690FDE88A
-:10007000A88290FDE8A982E8696005E4F20880F7AB
-:100080009001081200B390010C1200B390011012FD
-:1000900000B39001141200D190011A1200D1900106
-:1000A000201200D175D00012341A020126EF6582A9
-:1000B0007003EE658322E493F8740193F97402935C
-:1000C000FE740393F5828E83E869700122E493F64F
-:1000D000A30880F4E493FC740193FD740293FE740E
-:1000E0000393FF740493F8740593F58288831200D8
-:1000F000AA700122E493A3A883A9828C838D82F045
-:10010000A3AC83AD828883898280E32121049B8014
-:1001100080049BACAE049BFDE8049D049DFBF304AE
-:10012000A2049DFBF30502050280FED0F030F00929
-:1001300020F303F68010F7800D30F10920F303F26D
-:100140008004F38001F020F404FCD0E0CC22CCC089
-:10015000E0120163020154BC0005D0F0ACF022C3F0
-:1001600013DCFC02012ABF0009ED258275F001F8BD
-:10017000E622BF010FED2582F582EE3583F583750A
-:10018000F004E022ED258275F002F8E222D083D05F
-:1001900082F5F0C3E493A3C5F095F0C0E0C3D0F0BE
-:1001A000E493A395F04012A3A3C3E5F033500205F6
-:1001B000832582F58250020583740193C0E0E493A5
-:1001C000C0E022D083D082F5F0E4937009740193EB
-:1001D0007004A3A3800C74029365F06005A3A3A32D
-:1001E00080E7740193C0E0E493C0E022120264024D
-:1001F00001FB1202B80201FB1202DC0201FB30E03B
-:100200000720E302E622E72230E10720E302E222B0
-:10021000E32230E202E022E493221202DC02022313
-:100220001202B8020223ABF012022DCBC5F0CB2292
-:1002300030E01020E306E6F5F008E622E7F5F009E5
-:10024000E7192230E11020E306E2F5F008E222E3AC
-:10025000F5F009E3192230E206E0F5F0A3E022E42C
-:1002600093F5F074019322BB0003740922BB0107CC
-:1002700089828A83740422BB020789828A8374106C
-:1002800022740A22020284BB0007E92582F8740165
-:1002900022BB010DE92582F582EA3583F5837404DA
-:1002A00022BB020DE92582F582EA3583F5837410BD
-:1002B00022E92582F87402220202B8BF0005EDF897
-:1002C000740122BF01078D828E83740422BF02074E
-:1002D0008D828E83741022EDF87402220202DCBF3C
-:1002E0000007ED2582F8740122BF010DED2582F58E
-:1002F00082EE3583F583740422BF020DED2582F56D
-:1003000082EE3583F583741022ED2582F874022283
-:10031000020310C0E0120264020328C0E01202B817
-:10032000020328C0E01202DC02032830E00B20E3C5
-:1003300004D0E0F622D0E0F72230E10B20E304D035
-:10034000E0F222D0E0F322D0E0F022C9CDC9CACE3B
-:10035000CACBCFCB12035BEDF9EEFAEFFB22BB0069
-:100360002FBF000AFAEDF8E7F60809DAFA22BF0112
-:10037000128D828E83F802037809A3E7F0D8FA225F
-:10038000020383FAEDF8E7F20809DAFA2202038D94
-:10039000BB014DBF001489828A83F9EDF802039FE7
-:1003A00008A3E0F6D9FA220203B0BF01228D828EA3
-:1003B00083FB08C9C582C9CAC583CAE0A3C9C5826F
-:1003C000C9CAC583CAF0A3DBEAD8E8220203D38DE9
-:1003D000828E83F9EDF8E0F208A3D9FA220203DD58
-:1003E000BB024DBF001289828A83F9EDF80203EF48
-:1003F00008A3E493F6D9F922BF01238D828E83FBF3
-:1004000008C9C582C9CAC583CAE493A3C9C582C93C
-:10041000CAC583CAF0A3DBE9D8E722020422898295
-:100420008A83F9EDF8E493F208A3D9F922020433A0
-:10043000BF000DFAEDF8E3F60809DAFA2202043DEE
-:10044000BF01128D828E83F802044A09A3E3F0D81B
-:10045000FA22020455FAEDF8E3F20809DAFA220268
-:10046000045FE6FB08E6FA08E6F904F618700106F0
-:1004700022E6FF08E6FE08E6FD22EFF0A3EEF0A379
-:10048000EDF022EBF0A3EAF0A3E9F022E0FFA3E015
-:10049000FEA3E0FD22E0FBA3E0FAA3E0F9220000C6
-:1004A00000000000000502006105710026059800AB
-:1004B000330A0900610A750066154400610CF900F1
-:1004C0006109A9006109E000610DC000610BF10044
-:1004D000610A1C00610A510061173C0033174F008C
-:1004E000341E1400431EBF0044202C0044201A0078
-:1004F000471EE600471F8B004D1FDC004F1F080002
-:100500005832A800617CCC7DFF121CC52290FFFCF4
-:10051000E020E72DC2AFAE59AF58755A20E55A1406
-:10052000C55A6019E4FE7F05EE4FCE24FFCECF34CE
-:10053000FFCF6007E490FF92F080ED80E08E598F4E
-:10054000582212050A7D077CB71232C47D0F7C6EDB
-:100550001232DE789D7A06E4F608DAFC7A06120595
-:10056000CD7C03120E55122168E4FEFF7C0F12327F
-:100570004DD2A822123138E490FC38F090FFF0E020
-:1005800030E408740190FC39F08005E490FC39F007
-:100590007D0A7C001225461231BB2212313890FCB4
-:1005A00039E014700E90FFF0E04410F07C0012254A
-:1005B000DF801990FC39E0700E90FFF0E054EFF00E
-:1005C0007C001225DF80057C171225DF1231BB224B
-:1005D00090FFF0E054ABF090FFF0E04420F0228C6C
-:1005E000378D367882EDF608ECF6EDFEECFD7F01F6
-:1005F0009000051201F57880F67882E6FD08E6FCA9
-:10060000EDFEECFD7F019000041201F5540FFC7D1E
-:100610008012176D7880E6700DAD3AAE39AF38E4D0
-:100620001203187C082290FFF0E054FEF090FFF0D7
-:10063000E054FDF0801E7882E6FD08E6FCEDFEEC5D
-:10064000FD7F0190000812021725E0440190FFF39E
-:10065000F00206D97882E6FD08E6FCEDFEECFD7FAF
-:100660000190000612021754FE90FFF3F0802B78E1
-:1006700082E6FD08E6FCEDFEECFD7F01900008122D
-:100680000217FAEB90FFF1F01208C8400DAD3AAE38
-:1006900039AF38E41203187C18227882E6FD08E6A8
-:1006A000FCEDFEECFD7F0190000812021790FFF1B7
-:1006B000F01208C8400DAD3AAE39AF38E412031855
-:1006C0007C18227882E6FD08E6FCEDFEECFD7F0159
-:1006D000900006120217440190FFF3F07883E6249D
-:1006E00003F618E63400F67880E624FE500990FF01
-:1006F000F0E054FDF0800790FFF0E04402F0E49059
-:10070000FFF1F0788176007880E624FFFCE434FF86
-:10071000FD7881E67F00FEECD39EEF6480CD64809F
-:100720009D402F1208AD400F7881E6AD3AAE39AF4B
-:10073000381203187C182290FFF2E0FC788286833E
-:10074000088682ECF0788106A37882A68308A682C8
-:1007500080B51208AD400F7881E6AD3AAE39AF38BA
-:100760001203187C182290FFF2E0FC78828683083E
-:100770008682ECF07880E6AD3AAE39AF38120318D5
-:100780007C00228C378D367882EDF608ECF6EDFE93
-:10079000ECFD7F019000051201F57881F67882E684
-:1007A000FD08E6FCEDFEECFD7F019000041201F572
-:1007B000540FFC7D8112176D7881E670037C08224E
-:1007C00090FFF0E054FEF090FFF0E054FDF0801B4D
-:1007D0007882E6FD08E6FCEDFEECFD7F0190000866
-:1007E00012021725E090FFF3F0805B7882E6FD08A7
-:1007F000E6FCEDFEECFD7F0190000612021754FEB0
-:1008000090FFF3F080217882E6FD08E6FCEDFEEC37
-:10081000FD7F01900008120217FAEB90FFF1F01231
-:1008200008C840037C18227882E6FD08E6FCEDFE4D
-:10083000ECFD7F0190000812021790FFF1F0120802
-:10084000C840037C18227883E6240AF618E63400B0
-:10085000F6788076007881E624FFFCE434FFFD78AA
-:1008600080E67F00FEECD39EEF6480CD64809D40E7
-:100870002178828683088682E090FFF1F01208C812
-:1008800040037C1822788006788306E618700106FB
-:1008900080C390FFF0E04401F0788286830886826E
-:1008A000E090FFF1F01208C840037C18227C00227F
-:1008B00090FFF0E020E71290FFF0E030E50990FFB4
-:1008C000F0E04420F0C32280E7D32290FFF0E02044
-:1008D000E31290FFF0E030E50990FFF0E04420F0F3
-:1008E000C32280E7D3228C428D417C00ED54F0FD81
-:1008F000EC7003ED64307005753E038003753E04B3
-:10090000AC3E120F72758300858340E541540FF5AC
-:100910003FE5407004E53F64037035E53E24FD7516
-:10092000F00AA42402F582E434FCF583E030E60505
-:100930001210598019E53E249DF8E654FBF678A97B
-:10094000E62405F58218E63400F583740FF080592B
-:10095000E5407004E53F64047048E53E24FD75F011
-:100960000AA42402F582E434FCF583E030E507AC08
-:1009700042AD41121C5AE54230E21578ADE630E056
-:100980000F78ADE630E109E4FF04FE7C0412324D3D
-:1009900078A9E62406F58218E63400F583740FF092
-:1009A0008007E4FC7DEE121C5AC203221231381279
-:1009B0000F7278A9E62406F58218E63400F583E084
-:1009C00090FC38F078A9E62405F58218E63400F5A5
-:1009D00083E090FC39F0C2037D027C0012254612B0
-:1009E00031BB221231387895ECF6EC249DF8E630D4
-:1009F000E1077C131225DF800F90FC39E0FD78952C
-:100A0000E6FC1213EF1225DF1231BB2212313878C7
-:100A100095ECF67D00120F121225DF1231BB221267
-:100A200031387895ECF6EC249DF8E630E2077C133B
-:100A30001225DF801B7895E6249DF8E620E1077CEF
-:100A4000121225DF800A7895E6FC1214131225DFB6
-:100A50001231BB221231387895ECF6EC249DF8E681
-:100A600020E2077C111225DF800A7895E6FC12153A
-:100A7000141225DF1231BB221231387895ECF612B0
-:100A80000F7278A9E62409F58218E63400F583E0B0
-:100A900090FC3FF078A9E6240AF58218E63400F5C8
-:100AA00083E090FC40F078A9E62403F58218E63450
-:100AB00000F583E0FC78A9E62404F58218E634000A
-:100AC000F583E0F56278A9E62402F58218E63400A1
-:100AD000F583E0F5638C61E4EC333354017895F6EB
-:100AE0006008E56230E1037895067895E690FC4170
-:100AF000F078A7E62402F58218E63400F583E0FDDD
-:100B0000A3E0540CFCED54E68C65F564E56130E53A
-:100B100003436501E56220E50EE561547F7008E559
-:100B20006120E703436502E56130E303436510E5B7
-:100B30006130E203436520E561540360034365408F
-:100B4000E56130E103436580E56130E4034364011E
-:100B5000E56130E603436408E56220E40EE5615494
-:100B60007F7008E56120E7034364105365FB53641D
-:100B7000F9AD64E56590FC3ACDF0A3CDF0E56330C6
-:100B8000E30DE5635430C4540F90FC3DF08005E460
-:100B900090FC3DF0E563540390FC3CF0E5635404A5
-:100BA000C31390FC3EF090FC3CE0700E7D357EFC63
-:100BB0007F01740190000912014B78A9E62408F521
-:100BC0008218E63400F583E07C00FD78A9E624076E
-:100BD000F58218E63400F583E07F004CFEEF4D907F
-:100BE000FC38F0A3CEF0CEC2037D0A7C001225466D
-:100BF0001231BB221231387895ECF6789A760108DA
-:100C000076FC0876387897760C789A12046E120281
-:100C10001D7898CBF6CB08F67F00EF24EA401FE45E
-:100C2000EF25E090357EFD93CD04937899667003AF
-:100C3000ED186670067897760080030F80DC789652
-:100C4000EFF6789A12046E9000021202177898CB91
-:100C5000F6CB08F65404CB54064B60047897760B19
-:100C60007899E630E313789A12046E900005120129
-:100C7000F524FB50047897760D7899E654C07D00F2
-:100C800064C04D70047897760B789A12046E9000C9
-:100C9000041201F524FC50047897760F789A120418
-:100CA0006E9000061201F524FD50047897760E78B8
-:100CB0009A12046E9000091201F524FD50047897F1
-:100CC000760A7897E6702A7895E6FC120F72789A81
-:100CD00012046E78A7E6F978A6E6FA7B01740A7822
-:100CE00000120348C2037895E6FC1211157897ECC0
-:100CF000F67897E6FC1225DF1231BB2212313878E4
-:100D000095ECF6120F727895E624FD75F00AA4248E
-:100D100014F582E434FCF583AC82AD8378A6868337
-:100D2000088682ECF9EDFA7B0A78011203B0C2035F
-:100D30007895E6FC1211151231BB228D2B8C2AED11
-:100D400060407527017529487528FFE52A24FDFCB8
-:100D5000E434FFFDEC7C0325E0CD33CDDCF9FCE58C
-:100D6000292CF529E5283DF528AD29AE28AF2774B3
-:100D7000809000061203207480900002120320125B
-:100D80000FC5E52B14603B7527017529087528FFF1
-:100D9000E52A24FDFCE434FFFDEC7C0325E0CD33A3
-:100DA000CDDCF9FCE5292CF529E5283DF528AD2910
-:100DB000AE28AF27E4900006120320E49000021250
-:100DC0000320221231387895ECF6EC249DF8E630B9
-:100DD000E2097895E6FC121514D2007895E6FC122B
-:100DE0000F727896760090FC39E030E704789676BA
-:100DF000017896E6FD7895E6FC120D38C2033000C6
-:100E0000077895E6FC1214137C001225DF1231BB23
-:100E10002278A9E62404F58218E63400F583E0443C
-:100E200001F078A9E62404F58218E63400F583E0A1
-:100E300030E00280ED78A9E6240BF58218E6340054
-:100E4000F583E054F8F078A9E62402F58218E63438
-:100E500000F583E04480F022C2038C58120F7278B0
-:100E6000A6868308868279AF7A357B0A78011203D9
-:100E7000FE120E0EAC587D02120D38C203AC581291
-:100E80001115228D538E528F518C50120F72754F47
-:100E90000078A9E62405F58218E63400F583E02001
-:100EA000E41FE54F24F64019054FC2037C181232A7
-:100EB000FB90FF93E04401F0B2B3AC50120F72808C
-:100EC000D078A9E62405F58218E63400F583E02001
-:100ED000E405C2037C022278A9E62405F58218E61F
-:100EE0003400F583E0540F601678A9E62405F582F6
-:100EF00018E63400F583E0540FF0C2037C01227839
-:100F0000A88683088682E0AD53AE52AF5112031813
-:100F1000C2037C00228D318C30121514E531600F34
-:100F2000E530B4030A7C0112250E7C8112250EAC3B
-:100F300030120F72E531601A78AA8683088682E043
-:100F400054E7F0A3A3A3A3E054E7F0AC307D021272
-:100F50000D3878A6868308868279B97A357B0A7837
-:100F6000011203FEC203E530249DF8E654FDF6AC01
-:100F700030121115228C2630030512329A80F87C2B
-:100F80000A1231ADD203E52624FD78A3F670077866
-:100F9000AA76FF0876E078A3E67D007C0425E0CD04
-:100FA00033CDDCF9FC24A078A9F6ED34FF18F678EF
-:100FB000A3E675F00AA42400FCE434FCFD78A6ED59
-:100FC000F608ECF61232462278A9E62402F58218D9
-:100FD000E63400F583E030E72278A9E62402F582C2
-:100FE00018E63400F583E0547FF078A9E62402F592
-:100FF0008218E63400F583E04480F02278AA8683E4
-:10100000088682E0547FF0AD83E5822404FCE43D51
-:101010008C82F583E0547FF078A9E6240BF58218E2
-:10102000E63400F583E054F8F078ABE62401F5826D
-:1010300018E63400F583E04403F078ABE62405F5C8
-:101040008218E63400F583E04403F078A9E624052D
-:10105000F58218E63400F583740FF02278AA8683AF
-:10106000088682E0543FF0AD83E5822404FCE43D31
-:101070008C82F583E0543FF078A3E624A4F8E6FCE4
-:1010800078ABE62401F58218E63400F583ECF078BD
-:10109000A3E624A4F8E6FC78ABE62405F58218E67E
-:1010A0003400F583ECF078A9E6240BF58218E634D9
-:1010B00000F583E054FB4402F52678A7E62402F508
-:1010C0008218E63400F583E030E50343260178A971
-:1010D000E62405F58218E63400F583E030E00312DB
-:1010E0000FC5E526FC78A9E6240BF58218E6340046
-:1010F000F583ECF078A9E62405F58218E63400F5CE
-:1011000083740FF078AA8683088682E04480F0A377
-:10111000A3A3A3E04480F0228C2A120F7278A7E6E2
-:101120002408F58218E63400F583E0FC78A9E6246B
-:101130000AF58218E63400F583ECF078A7E6240778
-:10114000F58218E63400F583E0FC78A9E62409F579
-:101150008218E63400F583ECF078A6868308868250
-:10116000E0FDA3E0FCEDFE78A9E62408F58218E690
-:101170003400F583EEF0ECFE78A9E62407F582183A
-:10118000E63400F583EEF08C298D28C3EC9405ED50
-:10119000940C400575277C8033D3E5299401E5281C
-:1011A0009403400575273C8023D3E5299481E528E5
-:1011B000940140057527188013D3E5299460E5282C
-:1011C0009400400575270C8003752708AF27E4EFCE
-:1011D000547C4483FF8F27E527FC78ABE62401F598
-:1011E0008218E63400F583ECF0E527FC78ABE624C2
-:1011F00005F58218E63400F583ECF0E527FC78A3CA
-:10120000E624A4F8ECF678A9E62402F58218E63480
-:1012100000F583E0F52778A7E62402F58218E63486
-:1012200000F583A3E030E3175327C778A7E624052A
-:10123000F58218E63400F583E09035AA93422778CA
-:10124000A7E62402F58218E63400F583E030E705CE
-:1012500043274080035327BF5327FB78A7E6240684
-:10126000F58218E63400F583E06003432704532732
-:10127000FC78A7E62404F58218E63400F583E04202
-:1012800027432780E527FC78A9E62402F58218E6A3
-:101290003400F583ECF078A9E62404F58218E634EE
-:1012A00000F583E0F52778A7E62402F58218E634F6
-:1012B00000F583A3E030E1055327DF8003432720B7
-:1012C00078A7E62402F58218E63400F583E030E4DE
-:1012D000055327EF800343271078A7E62409F582FA
-:1012E00018E63400F583E0B40203432702E527FC47
-:1012F00078A9E62404F58218E63400F583ECF0784A
-:10130000A9E62403F58218E63400F583E0F5277892
-:10131000A7E62409F58218E63400F583E07005534A
-:10132000277F800343278078A7E62402F58218E60A
-:101330003400F583A3E030E00543272080035327E2
-:10134000DF78A7E62402F58218E63400F583E03062
-:10135000E30543274080035327BF78A7E62402F51F
-:101360008218E63400F583E030E00543271080035F
-:101370005327EF78A7E62402F58218E63400F583B8
-:10138000A3E030E40543270880035327F778A7E656
-:101390002402F58218E63400F583A3E030E5054326
-:1013A000270480035327FB78A7E62402F58218E67A
-:1013B0003400F583A3E030E605432701800353277B
-:1013C000FE78A7E62402F58218E63400F583A3E050
-:1013D00030E70543270280035327FDE527FC78A962
-:1013E000E62403F58218E63400F583ECF0C2037CB2
-:1013F00000228D278C26ED54031460037C1022E517
-:1014000027547C24FC40037C0B22E526249DF8E62F
-:101410004402F67C00228C30120F72E530249DF8D5
-:10142000E620E24FAC307D02120D38E53024FE4458
-:1014300028FC78AA8683088682ECF0AF83E58224B4
-:1014400004FEE43FFFEC8E828F83F07C038C2CE55E
-:101450002CFC78ABE62401F58218E63400F583EC29
-:10146000F0E52CFC78ABE62405F58218E63400F5AF
-:1014700083ECF0752D01752F48752EFFE53024FDA6
-:10148000FCE434FFFDEC7C0325E0CD33CDDCF9FC3E
-:10149000E52F2CF52FE52E3DF52E78ABE62404F54F
-:1014A0008218E63400F583E054E7F52CAD2FAE2E1C
-:1014B000AF2DE4900002120320E4900006120320F6
-:1014C0001201EF30E503432C10E52CFC78ABE62449
-:1014D00004F58218E63400F583ECF012105978A96F
-:1014E000E62406F58218E63400F583E0C203FCE545
-:1014F00030249DF8E64404F68C2CE530540FC45497
-:10150000F07E00FFEEEF44047D00FFEC4EFCED4F5B
-:10151000FD121CC57C00228C2F120F72120FF9785D
-:10152000AA8683088682E05408F0A3A3A3A3E0540C
-:1015300008F0AC2F7D02120D38C203E52F249DF870
-:10154000E654FBF67C00221231387896ECF6EC2457
-:101550009DF8E630E10A7D007C131225461231BB6E
-:101560007896E6249DF8E64401F67896E6FC120F9C
-:10157000727896E624FD75F00AA42414F582E4340A
-:10158000FCF58378A6E6FA08E6F97B0A78011203EF
-:10159000B078A6868308868279B97A357B0A780185
-:1015A0001203FE120FC5C2037896E6FC12111578DD
-:1015B00095ECF6EC600A7D007C081225461231BBE2
-:1015C0007896E6FC120F7278A9E62404F58218E6F4
-:1015D0003400F583E0441054DFFC78A9E62404F5D8
-:1015E0008218E63400F583ECF07895ECF6C2037CC3
-:1015F000C81232FB7896E6FC120F7278A9E6240432
-:10160000F58218E63400F583E054EFF0C2037CC89D
-:101610001232FB7896E6FC120F7278A9E62404F5E4
-:101620008218E63400F583E04410F0C2037CC8124F
-:1016300032FB7896E6FC120F7278A9E62404F58254
-:1016400018E63400F583E04420F0C2037CF0123247
-:10165000FB7896E6FC120F7278A9E62405F582184D
-:10166000E63400F583E030E415C2037896E64410D2
-:101670007F00FE7C0712324D1231BB02173B78A966
-:10168000E62404F58218E63400F583E054CFF0C276
-:10169000037CC81232FB7896E6FC120F7278A9E63A
-:1016A0002404F58218E63400F583E04430F0C203E8
-:1016B0007CF01232FB7896E6FC120F7278A9E624D1
-:1016C00005F58218E63400F583E030E414C20378AF
-:1016D00096E644107F00FE7C0712324D1231BB802B
-:1016E0005D78A9E62404F58218E63400F583E05419
-:1016F000EFF078A9E62404F58218E63400F583E0DB
-:1017000054DFF07896E624FD75F00AA42414F582DF
-:10171000E434FCF583AC82AD8378A68683088682A8
-:10172000ECF9EDFA7B0A78011203B0C2037896E671
-:10173000FC1211157D007C0B1225461231BB2212C2
-:101740003138E490FC39F07D027C001225461231DC
-:10175000BB221231387C001225DF1231BB22743CCF
-:1017600090FBE0F0743E90FBE0F0E490FC28F02267
-:101770008D358C34ECB401028003D340028028B450
-:1017800002028003D34008A835E625E0F68018B4AD
-:1017900004028003D3400AA835E625E025E0F68060
-:1017A00006A83576008000228C3C8D3BEDFEECFDDA
-:1017B0007F0175660675670090FC29120477120197
-:1017C000EFB480028006D3500302186E90FC2912F9
-:1017D00004899000031201F554F0B430028003D361
-:1017E000405F90FC29120489900008120217FAFD4C
-:1017F000EBFE7F0190FC2C120477EECD9035C3FCFC
-:10180000E493FF740193FEF9EFFA7B01EAFFE9FE2E
-:10181000ECC39EED9F40259035C5E493FD74019384
-:10182000FCEDFEECFD7F01EECDFC90FC2EE0D39CA8
-:1018300090FC2DE09D5005756680803312198C80D8
-:101840002EB460028003D3400BAC3CAD3B1207804A
-:101850008C66801BB41003B34010C3B42003B340A4
-:1018600009C3B440028003D34000756681800080C4
-:1018700075B481028003D3406B90FC2912048990D7
-:1018800000031201F554F0B430028003D3401D90E0
-:10189000FC29120489900008120217FAFDEBFE7F62
-:1018A0000190FC2F1204771218F68036B460028083
-:1018B00003D34013753A67E4F539F538AC3CAD3BDA
-:1018C0001205DC8C66801BB41003B34010C3B42037
-:1018D00003B34009C3B440028003D340007566815E
-:1018E000800080028000E566FC90FC29120489ECEF
-:1018F000900002120320AC672290FC291204899008
-:1019000000041201F5600474018001E4A2E0920178
-:1019100090FC29120489ED2403FD50010E90FC2C4B
-:1019200012047790FC291204899000051201F5F544
-:10193000679000041201F5540FFC7D6712176DE5E6
-:10194000677004756608227566007884760078846E
-:10195000E6C39567503890FC2F1204891201EFFC02
-:1019600090FC2C120489EC12031830010E90FC310B
-:10197000E004F090FC307003E004F078840690FC02
-:101980002EE004F090FC2D7003E004F080C0229063
-:10199000FC2AE0FDA3E0FCEDFEECFD7F01ED240A56
-:1019A000FD50010E90FC3212047790FC291204893C
-:1019B0009000041201F5540FB401028003D34017C4
-:1019C00090FC321204890DED70010E90FC2F120470
-:1019D0007778887601804EB402028003D340199054
-:1019E000FC32120489ED2402FD50010E90FC2F12EE
-:1019F000047778887602802DB404028003D34019DE
-:101A000090FC32120489ED2404FD50010E90FC2F4D
-:101A100012047778887604800CB400028003D340E7
-:101A2000007566082290FC291204899000051201B5
-:101A3000F5F567788576007885E6C39567400302FB
-:101A40001AF4788676007886E6C378889650769081
-:101A5000FC2C1204891201EFFC90FC321204921249
-:101A600001E9F45CFC1201E9F890FC2F120489E80A
-:101A7000C0E01201EFC8D0E0C8584CFC90FC2C121A
-:101A80000489EC1203187887ECF690FC31E004F03E
-:101A900090FC307003E004F009E970010A90FC3218
-:101AA00012048090FC291204899000041201F53080
-:101AB000E40E90FC2EE004F090FC2D7003E004F0A6
-:101AC00078860680817888E6FDE4FEFFEECDFC9006
-:101AD000FC31E02CF090FC30E03DF07888E6FDE44D
-:101AE000FEFFEECDFC90FC34E02CF090FC33E03DAA
-:101AF000F0788506021A347566002222C0E0C0F034
-:101B0000C082C083C0D0E8C0E0E9C0E0EAC0E0EB3A
-:101B1000C0E0ECC0E0EDC0E0EEC0E0EFC0E090FF60
-:101B200092E01201C01B47301B47321B56381B681E
-:101B30003A1B7A3E1B92441B86461B9E501BE0526A
-:101B40001BBF541C015600001C2290FF92E07F0036
-:101B5000FE7C0112324D021C32E4FF04FE7C0312B3
-:101B6000324D742090FFFEF0021C32E4FF04FE7C34
-:101B70000212324D744090FFFEF0021C32E4FF046A
-:101B8000FE7C0412324D021C32E4FF04FE7C05127E
-:101B9000324D021C32E4FF04FE7C0612324D021C60
-:101BA0003290FFA5E07D0090FBF8CDF0A3CDF09042
-:101BB000FBF9E0FCF58390FBF8E04433FD121CC513
-:101BC000807390FFB5E07D0090FBFACDF0A3CDF0DF
-:101BD00090FBFBE0FCF58390FBFAE04443FD121C14
-:101BE000C5805290FFA6E07D0090FBFCCDF0A3CD18
-:101BF000F090FBFDE0FCF58390FBFCE04434FD122B
-:101C00001CC5803190FFB6E07D0090FBFECDF0A3B7
-:101C1000CDF090FBFFE0FCF58390FBFEE04444FD3B
-:101C2000121CC5801090FF92E07D00FCED44AAFDDF
-:101C3000121CC58000E490FF92F0D0E0FFD0E0FEDF
-:101C4000D0E0FDD0E0FCD0E0FBD0E0FAD0E0F9D06D
-:101C5000E0F8D0D0D083D082D0F0D0E0320581053A
-:101C60008105810581A881181818EDF608ECF69019
-:101C7000FF5AE020E70280F790FF59E07D00A8813D
-:101C800018CDF6CD08F67D03A881E618FCE6CC2534
-:101C9000E0CC33CCDDF9CCF6CC08F6A88118E644CC
-:101CA000F8F6A881181818E6FD08E6FCA881188641
-:101CB00083088682EDF0A3ECF0740290FF5AF015D1
-:101CC0008115811581158122E5812405F581E4A81E
-:101CD0008118F6A88118181818EDF608ECF690FB94
-:101CE000F5E024F85003021DE6E4A8811818F6A8D0
-:101CF0008118E6FEA88118181818E6FD08E6FC7F92
-:101D000000EF24F8404DE4EF25E0247DF582E43433
-:101D1000FCF583E0FBA3E06C7003FAEB6D700974D3
-:101D200001A8811818F6802BE4EF25E0247DF582C8
-:101D3000E434FCF5837A00E054F0CCF8CCCDF9CD56
-:101D4000FB7800E954F0F9EA687002EB6970010E63
-:101D50000F80AEA88118EEF6A88118181818EDF6B5
-:101D600008ECF6A881EFF6A8811818E67079A8812A
-:101D700018E624F74071A88118181818E6540FA81F
-:101D800081F664046017A881E664036010A88118D6
-:101D9000181818E6FD08E6FC121C5A804A7C0A1244
-:101DA00031ADA88118181818E6FD08E6FC90FBF480
-:101DB000E025E0247DF582E434FCF583EDF0A3EC2E
-:101DC000F090FBF4E0FFE4EF045407FF90FBF4F025
-:101DD00090FBF5E004F012324690FBF6E07008E468
-:101DE000FEFF7C0F12324D802790FBF7E004F05489
-:101DF0003F701D90FBF7E044FE7D00FC90FBF4E09B
-:101E000025E0247DF582E434FCF583EDF0A3ECF0CD
-:101E1000E58124FBF58122788B7600788C7600743E
-:101E20000190FBF6F012313890FBF5E060577C0A28
-:101E30001231AD90FBF3E025E0247DF582E434FC23
-:101E4000F583E0FDA3E0FC90FBF3E025E0247DF5C5
-:101E500082E434FCF583E4F0A3F090FBF3E0FFE4CC
-:101E6000EF045407FF90FBF3F090FBF5E014F078DB
-:101E700089EDF608ECF61232467889E6FD08E6FCB4
-:101E80001208E380A312329A90FF93E04401F0B26B
-:101E9000B3788B06B60011788B7600788CE6F40464
-:101EA00004A2E092B4788CF6021E25E490FBF6F0D2
-:101EB00090FBF5E07D00FCED44CFFD121C5A123181
-:101EC000BB22123138E5706449456F601590FF837D
-:101ED000E0540F7D00D39570ED956F5005122F8162
-:101EE00080031230511231BB22123138E57064493F
-:101EF000456F600512308B800E90FF80E04408F043
-:101F000090FF83E0547FF01231BB221231388C54A1
-:101F1000EC54F0B41015756A357569FC756801E507
-:101F20006A2403F56AE5693400F569E4F557F55666
-:101F3000E556C394015027E554540FFCAD6AAE69D1
-:101F4000AF68120E808C55EC60028012056AE56A5B
-:101F5000700205690557E5577002055680D2E554B1
-:101F6000540F249DF8E654FEF6E554540F7F00FE0E
-:101F70007C1212324DE5551470097D007C09122542
-:101F8000468007AD577C001225461231BB22123124
-:101F90003890FFFCE04402F090FF00E030E713903F
-:101FA000FF83E04480F0436D8090FFFCE04401F04B
-:101FB000801190FF82E04408F0536D7F90FFFCE0B9
-:101FC00054FEF090FF81E04480F01225F990FFFE6E
-:101FD000E04405F090FFFCE054FDF01231BB22120A
-:101FE00031387C011232FB78ADE64402F674FEFC17
-:101FF00004FD121CC590FF5AE030E70280F7E4F5BB
-:102000004E754D10AC4EAD4DE54E154E7002154D52
-:10201000EC4D600280EE4387011231BB2212313851
-:102020007C021231C778ADE654FDF61231BB2212A4
-:10203000313878ADE630E02C78ADE630E12678AD89
-:10204000E6FCF58318E644F0FD121C5A90FFFCE014
-:102050004420F07C021232FB78ADE654FDF6741A8F
-:1020600090FFFEF078ADE6FCF58318E644F1FD1232
-:102070001C5A1231BB22756D0090FFFFE0600343D4
-:102080006D01756E00E4F56CF56BE4F56F757049E4
-:10209000748490FF82F0748490FF80F0748090FFCD
-:1020A00058F0748090FF5AF0AD46AF457E00EE24A4
-:1020B000FE5003022142E4EE75F007A4247FF5826E
-:1020C000E434F8F583E0FFE4EF5480FDE4EF540FCF
-:1020D00014FFED6038E4EF75F008A42448F582E4BD
-:1020E00034FFF5837490F0E4EF75F008A4244AF50A
-:1020F00082E434FFF5837480F0E4EF75F008A424E3
-:102100004EF582E434FFF5837480F08034E4EF759B
-:10211000F008A42408F582E434FFF5837490F0E419
-:10212000EF75F008A4240AF582E434FFF583E4F0A7
-:10213000E4EF75F008A4240EF582E434FFF583E49F
-:10214000F00E0220AB8D468E448F45747F90FFFDCC
-:10215000F0749090FFFCF0228C58EC24F65006E5C9
-:10216000582437FC22E5582430FC22D2B0122543F3
-:10217000EC700302227E755C03AE5B7F00E55C15AC
-:102180005C6480247F5035EF2400F582E434FBF555
-:1021900083E0FE24FE501EEF7D00FCE4FB7474C35C
-:1021A0009CFAEB9DFBEE7D00FCEAC39CED6480CBCA
-:1021B00064809B50028005EF2EFF80C18E5B8F5A9A
-:1021C000E55C6480247F500302227EE55A248E5011
-:1021D0000302227E855A5D755B00AE5AAF5B903577
-:1021E000EEE493F55CE55C155C6480247F5018EEAA
-:1021F0002400F582E434FBF583E0FCEF9035EE93A8
-:102200006C70040E0F80DE8E5A8F5BE55C64802458
-:102210007F406E755E017560E8755FFFE55D2402C5
-:10222000F55A755C07E55C334057AD60AE5FAF5E55
-:10223000E55CF5823395E0F5831201F5C4540FFC9B
-:10224000122155E55A2400F582E434FBF583ECF0C5
-:10225000055A055AAD60AE5FAF5EE55CF582339519
-:10226000E0F5831201F5540FFC122155E55A2400C4
-:10227000F582E434FBF583ECF0055A055A155C80D1
-:10228000A4740290F851F090F86B79C77A357B27E7
-:1022900078011203FE756A357569FC756801E49072
-:1022A000FF83F0748090FF81F0755902E55975F055
-:1022B00007A4247FF582E434F8F583E0788FF6FCF8
-:1022C000540F14FC788FECF6E55975F007A42481BF
-:1022D000F582E434F8F583E0789276FD0876E8FC40
-:1022E000788FE675F008A42448F582E434FFF5837E
-:1022F000E4F0788FE675F008A4244FF582E434FF0B
-:10230000F583ECF07892E6FF08E67E03CFC313CFA7
-:1023100013DEF9FE788FE675F008A42449F582E40F
-:1023200034FFF583EEF0788FE675F008A4244AF5C3
-:1023300082E434FFF5837480F07890ECF67D0078C9
-:1023400093E62CF618E63DF67892E6FD08E67C0367
-:10235000CDC313CD13DCF9FC788FE675F008A42407
-:102360004DF582E434FFF583ECF0788FE675F008E4
-:10237000A4244EF582E434FFF583E4F07892E6FD80
-:1023800008E6FC788FE6FF7E00EE24FE5003022470
-:10239000FDE4EE75F007A4247FF582E434F8F583BC
-:1023A000E0FFE4EF5480FAE4EF540F14FFE4EE751D
-:1023B000F007A42481F582E434F8F583E07890F600
-:1023C000E4EE1313548024F0F8E434FDF9E8FCE95A
-:1023D000FD8A5AEA700302246AE4EF75F008A42427
-:1023E00048F582E434FFF583E4F07890E6FAE4EF10
-:1023F00075F008A4244FF582E434FFF583EAF0ED8C
-:10240000FBEC7A03CBC313CB13DAF9FAE4EF75F0E4
-:1024100008A42449F582E434FFF583EAF07890E6D5
-:102420007B00FAEC2AFCED3BFDFBEC7A03CBC313FB
-:10243000CB13DAF9FAE4EF75F008A4244DF582E441
-:1024400034FFF583EAF0E4EF75F008A4244AF5823E
-:10245000E434FFF5837480F0E4EF75F008A4244EB3
-:10246000F582E434FFF5837480F00224F9E4EF751B
-:10247000F008A42408F582E434FFF583E4F07890B2
-:10248000E6FAE4EF75F008A4240FF582E434FFF5D2
-:1024900083EAF0EDFBEC7A03CBC313CB13DAF9FA42
-:1024A000E4EF75F008A42409F582E434FFF583EA2B
-:1024B000F07890E67B00FAEC2AFCED3BFDFBEC7A31
-:1024C00003CBC313CB13DAF9FAE4EF75F008A424B5
-:1024D0000DF582E434FFF583EAF0E4EF75F008A42B
-:1024E000240AF582E434FFF583E4F0E4EF75F008A4
-:1024F000A4240EF582E434FFF583E4F00E02238673
-:102500008E597892EDF608ECF6788FEFF61220737C
-:10251000228C26EC30E718E526540F1475F008A439
-:102520002448F582E434FFF583E054DFF08016E5BB
-:1025300026540F1475F008A42408F582E434FFF53E
-:1025400083E054DFF0227C0022EC90FC37F08C24F6
-:10255000ED2403F5257D00D39572ED95714003853B
-:102560007225E52524B75009752503740290FC37C0
-:10257000F0AC2512307622E4F56CF56B12257D2245
-:1025800090FC35E06573600E740490FC37F0E4F560
-:102590006B756C0380467D73E4FEFF79357AFC7BB6
-:1025A0000174057800120348E56C2403F56CE56BB3
-:1025B0003400F56BE56CD39572E56B95714006853B
-:1025C000726C85716BD3E56C9448E56B9400400C9C
-:1025D000740290FC37F0E4F56B756C03AC6C123050
-:1025E0007622EC90FC37F0E4F56CF56B8C32EC6005
-:1025F0000512306780057C001230762290FF93E050
-:102600004401F0B2B390FF04E0F54A90FF06E0FD0C
-:10261000A3E0ED7D00FC7D00FC90FF06E0FFA3E061
-:102620007E00FFE4FEEC4EFCED4FFDC3EC9448ED64
-:102630009400502290FF06E0FDA3E0ED7D00FC7DBC
-:1026400000FC90FF06E0FFA3E07E00FFE4FEEC4EFE
-:10265000FCED4FFD8004E4FD7C488C728D7190FF91
-:1026600002E0FDA3E0ED7D00FC7D00FC90FF02E0B8
-:10267000FFA3E07E00FFE4FEEC4EF54CED4FF54B82
-:10268000756A357569FC7568017D357EFC7F017959
-:1026900073E4FAFB74057800120348754900E549B4
-:1026A00024FE4019AD6AAE69AF68E412031805490B
-:1026B0000DED70010E8D6A8E698F6880E1756A3547
-:1026C0007569FC75680190FF00E05460B4000280F9
-:1026D00006D35003022CBFE54A540FF549E54A548E
-:1026E00080A2E0920290FF01E012018A000B2CBA56
-:1026F000270528232CBA292F2CBA2A122A462BADBB
-:102700002BB02BF02C632C91E56D30E70EE54C459A
-:102710004B7008E572640245716003022CBC90FFA7
-:1027200000E0541FB400028003D34029E54A60034F
-:10273000022820AD6AAE69AF68740112031878AD43
-:10274000E630E00BAD6AAE69AF6874021203187C24
-:102750000212307622B401028003D3401BE56D20C3
-:10276000E107E54A6003022820E54A24FE500302FF
-:1027700028207C0212307622B402028006D3500355
-:1027800002281EE56D20E10DE54A6009E54A6480F6
-:102790006003022820AC4A1230FD4003022820E5E5
-:1027A00049702530021190FF80E05408AD6AAE698F
-:1027B000AF68120318800F90FF82E05408AD6AAE34
-:1027C00069AF68120318803D154930021DE549754F
-:1027D000F008A42448F582E434FFF583E05408AD02
-:1027E0006AAE69AF68120318801BE54975F008A44A
-:1027F0002408F582E434FFF583E05408AD6AAE693D
-:10280000AF68120318AD6AAE69AF681201EF600BD2
-:10281000AD6AAE69AF6874011203187C021230769B
-:10282000228000022CBCE56D20E706E57245716050
-:1028300003022CBC90FF00E0541FB400028003D3BD
-:10284000401AE54C14454B7004E54A600302292CFC
-:1028500078ADE654FEF67C0012307622B401028098
-:1028600003D3402AE56D20E108E56D20E00302294D
-:102870002CE56D30E004E54A700BE56D30E109E5CB
-:102880004A24FE500302292C7C0012307622B40226
-:10289000028006D3500302292AE54C454B6003020F
-:1028A000292CAC4A1230FD400302292CE56D20E1B1
-:1028B00007E56D20E0028077E56D30E006E54960D0
-:1028C00002806CE549700F90FF82E054F7F090FFB2
-:1028D00080E054F7F022E549B401028003D34009B7
-:1028E0007D017C03120F128011B402028003D340D9
-:1028F000097D017C04120F1280001549300215E594
-:102900004975F008A42448F582E434FFF583E054C7
-:10291000F7F08013E54975F008A42408F582E43443
-:10292000FFF583E054F7F07C00123076228000023D
-:102930002CBCE56D20E706E57245716003022CBCF6
-:1029400090FF00E0541FB400028003D3401AE54C0E
-:1029500014454B7004E54A6003022A0F78ADE64443
-:1029600001F67C0012307622B401028003D34029A4
-:10297000E56D20E108E56D20E003022A0FE56D30EA
-:10298000E004E549700BE56D30E108E54924FE50AF
-:1029900002807F7C0012307622B402028003D34092
-:1029A0006FE54C454B60028069AC4A1230FD400235
-:1029B0008060E56D20E107E56D20E0028054E54987
-:1029C000701430020990FF80E04408F0800790FF07
-:1029D00082E04408F022E56D30E1331549300215FC
-:1029E000E54975F008A42448F582E434FFF583E056
-:1029F0004408F08013E54975F008A42408F582E442
-:102A000034FFF583E04408F07C0012307622800227
-:102A10008000022CBCE56D20E712E5724571700C58
-:102A2000E54A700890FF00E0541F6003022CBCE5EB
-:102A30004C90FFFFF090FFFFE06005436D018003C5
-:102A4000536DFE7C0012307622E56D30E70EE572A4
-:102A50004571600890FF00E0541F6003022CBCAD7C
-:102A60004BE54CED7D00FC7D00FCBD0002800302C7
-:102A70002BA8B401028003D34032E54A7005E54C2F
-:102A8000FC6003022BAA756A407569F8756801D36A
-:102A9000E5729412E57194004006E4FD7C12800416
-:102AA000AC72AD718C708D6F12308B22B4020280CB
-:102AB00003D34059E54A6003022BAAE54CFC70277A
-:102AC000756A527569F8756801D3E5729419E571F4
-:102AD00094004006E4FD7C198004AC72AD718C70EA
-:102AE0008D6F12308B8025756A6B7569F87568017A
-:102AF000D3E5729427E57194004006E4FD7C2780BD
-:102B000004AC72AD718C708D6F12308B22B40302E5
-:102B10008006D35003022BA8E54CF549700F90FFB7
-:102B200004E0FDA3E04D6003022BAA801890FB0295
-:102B3000E0FDA3E0FC90FF05E06C700790FF04E06F
-:102B40006D60028068E4F570F56F7F00E54914C59B
-:102B500049600FEF2400F582E434FBF583E02FFF9A
-:102B600080EA8F4AE54A2400F582E434FBF583E0ED
-:102B70007D00D39572ED95714006AC72AD71800FFA
-:102B8000E54A2400F582E434FBF583E07D00FC8C0B
-:102B9000708D6FE54A2400FCE434FBFDFEECFD7F04
-:102BA000018D6A8E698F6812308B228000022CBCE6
-:102BB000022CBCE56D30E719E5721445717012E521
-:102BC0004A700EE54C454B700890FF00E0541F60C2
-:102BD00003022CBCE56D20E008E56D20E103022C2A
-:102BE000BC756A6EE4F569F568E4F56F04F570127A
-:102BF000308B22E56D20E727E57245717021E54AAB
-:102C0000701DE54C6402454B600DE54C14454B606E
-:102C100006E54C454B700890FF00E0541F6003022E
-:102C20002CBCE56D20E008E56D20E103022CBC859D
-:102C30004C6EE56E700A436D01536DFDD2B080207D
-:102C4000E56E64026007E56E1460028072536DFEEB
-:102C5000436D02E56E64026005E56E147002C2B059
-:102C60007C0012307622E56D30E71AE5721445716A
-:102C70007013E54A700FE54C454B700990FF00E07A
-:102C8000541F1460028038E56D20E10280317C0120
-:102C900012307622E56D20E715E5724571700FE57B
-:102CA0004C454B700990FF00E0541F146002800FE8
-:102CB000E56D20E10280087C00123076228000025F
-:102CC0002F7DB440028006D35003022F7390FF0182
-:102CD000E090FC35F0E54A90FC36F0E490FC37F0EB
-:102CE000E56A2403F56AE5693400F569AD4BE54C06
-:102CF000856A82856983CDF0A3CDF090FF01E01253
-:102D000001C02D2A012D50022D7A032DA4042DF28D
-:102D1000052E2F062E55072E7B082EA7092ECD0B2C
-:102D20002EF30C2F02802F028100002F60E56D2012
-:102D3000E7067C051225DF227D767E357F02793815
-:102D40007AFC7B01740878001203487D087C00122D
-:102D5000254622E56D20E7067C051225DF22E54A9F
-:102D6000B403004010B40500500BE54A7F00FE7C20
-:102D70001012324D227D007C0712254622E56D207F
-:102D8000E7067C051225DF22E54AB403004010B4B3
-:102D90000500500BE54A7F00FE7C1112324D227D6A
-:102DA000007C0712254622E56D20E7067C051225EA
-:102DB000DF22E54AB405028003D3400AE4FF04FEA3
-:102DC0007C0A12324D22B401028003D3400AE4FF90
-:102DD00004FE7C0812324D22B403004010B40500FA
-:102DE000500BE54A7F00FE7C1312324D227D007CA1
-:102DF0000712254622E56D20E734D3E5729448E5B5
-:102E00007194005006E572457170067C021225DF50
-:102E100022E54AB40103B3400BC3B403004009B434
-:102E200006005004123123227C071225DF221225CE
-:102E30007D22E56D20E71DE54AB403004010B4058E
-:102E400000500BE54A7F00FE7C1612324D227C07B3
-:102E50001225DF2212257D22E56D20E71DE54AB40B
-:102E600003004010B40500500BE54A7F00FE7C19BA
-:102E700012324D227C071225DF2212257D22E56DBC
-:102E800020E723748190FF93F0E54AB403004010DB
-:102E9000B40500500BE54A7F00FE7C1712324D222C
-:102EA0007C071225DF2212257D22E56D20E71DE536
-:102EB0004AB403004010B40500500BE54A7F00FE01
-:102EC0007C1812324D227C071225DF2212257D222A
-:102ED000E56D20E71DE54AB403004010B40500503D
-:102EE0000BE54A7F00FE7C1512324D227C0712252D
-:102EF000DF2212257D22E56D20E7067C071225DF03
-:102F00002212257D22E56D30E72090FF00E0541F5E
-:102F1000701090FF01E0B480051225748003122523
-:102F20007D227D007C051225462290FF00E0541F83
-:102F300060067C051225DF22D3E5729448E5719482
-:102F400000500BC3E5729407E571940050067C03B2
-:102F50001225DF22E54AB40504123123227C071230
-:102F600025DF22E56D30E7087D007C05122546222D
-:102F70007C051225DF22B420028003D340008000AC
-:102F80001230512275430090FF83E0540FD39543D4
-:102F90004024E54324F0F582E434FEF583E0AD6A95
-:102FA000AE69AF6812031805430DED70010E8D6A0E
-:102FB0008E698F6880D1E5437D00FCC3E5709CF588
-:102FC00070E56F9DF56FE570456F6006E490FF83D7
-:102FD000F02290FF82E04408F0E4F56F75704990AC
-:102FE000FC35E0B405028003D3404090FC36E0F5A8
-:102FF00043B405028003D3400AE4FF04FE7C0B12B5
-:10300000324D22B401028003D3400AE4FF04FE7C67
-:103010000912324D22B403004010B40500500BE5F4
-:10302000437F00FE7C1412324D2222B480004023E4
-:10303000B48200501E7C357DFC1217A57D008C6C7F
-:103040008D6B90FC37E0600512305180057C0012DA
-:103050003076222290FF83E0547FF090FF82E0449C
-:1030600008F090FF80E04408F02290FF82E04408DE
-:10307000F090FF80E04408F0228C237D008C708D5E
-:103080006F756A357569FC75680112308B2290FF87
-:1030900083E0547FF0E5706449456F700122C3E519
-:1030A000709408E56F94004015752108E5217D00B6
-:1030B000FCC3E5709CF570E56F9DF56F8009857028
-:1030C00021E4F56F757049752200E522C395215002
-:1030D00026AD6AAE69AF681201EFFCE52224F8F56F
-:1030E00082E434FEF583ECF005220DED70010E8DC7
-:1030F0006A8E698F6880D3E521547F90FF81F0222A
-:103100008C487F00EF24FD4019E4EF75F007A424FC
-:103110007FF582E434F8F583E065487002D3220F2E
-:1031200080E28F47C32285727085716F90FF82E0C5
-:1031300054F7F090FF83E0547FF022C000C001C03C
-:1031400002C006C007E5782408F8860653067F7C8F
-:10315000FF1231AD7C007D00E57B6046FF90FD9560
-:10316000E0547F6E700FC083C082A3E0FDA3E0FC3B
-:10317000A3157B8007A3A3A3DFE68026DF06D0820A
-:10318000D083801EE0F8A3E0F9A3E0FAD082D083D8
-:10319000E8F0A3E9F0A3EAF0A3C083C082A3A3A34D
-:1031A00080DA123246D007D006D002D001D00022F9
-:1031B00085A87A75A888EC70027C3F8C7922E57826
-:1031C0002408F8760012329A80FBC000C001C002C9
-:1031D000C006C007AE047CFF1231ADE57B6042FF44
-:1031E00090FD95E0547F6E700BC083C082A3A3A3B3
-:1031F000157B8007A3A3A3DFEA8026DF06D082D059
-:103200008380D8E0F8A3E0F9A3E0FAD082D083E885
-:10321000F0A3E9F0A3EAF0A3C083C082A3A3A38034
-:10322000DA7808087918097C01E6547F6E70067612
-:10323000007700800608090CBC08EE123246D00761
-:10324000D006D002D001D00022757900857AA8225C
-:10325000C0F0C082C083C3E57B24E8500512329AD7
-:1032600080F4EC6031903575E493C39C4028C00431
-:103270007CFF1231ADD004430480E57B75F003A4DC
-:103280002495F582E434FDF583ECF0EFA3F0EEA392
-:10329000F0057B123246D083D082D0F022C0047C6D
-:1032A00020D28CD28DD504FDD0042275A80075885B
-:1032B0000075B80075F00075D000E4F8900000F6D5
-:1032C00008B800FB020000C3ED940250047D037CAB
-:1032D000E8ECF4FCEDF4FD0CBC00010D8C7F8D7E60
-:1032E00022C3EC94BCED940250047D077CD0ECF436
-:1032F000FCEDF4FD0CBC00010D8C7D8D7C22EC708E
-:103300000122C000E5782418F8A604E5782408F81E
-:10331000C6547FF6E630E703D0002212329A80F4DA
-:10332000C28C857C8C857D8AD28CC0E0C0D0C0F0F8
-:10333000C082C083C000C001C002C003C004C00579
-:10334000C006C007121AF8E5782408F8E66024E5FC
-:10335000782410F8A681E57875F021A4248DF582F3
-:10336000E434FCF58378AEE58104C398F9E6F0080F
-:10337000A3D9FA74082578F8057808E65480700C0B
-:10338000E578B407F3780875780080EFE5782410C5
-:10339000F88681E57875F021A4248DF582E434FC6B
-:1033A000F58378AEE58104C398F9E0F608A3D9FA6D
-:1033B000D007D006D005D004D003D002D001D00071
-:1033C000D083D082D0F0D0D0D0E032C0E0C0D0C026
-:1033D00000C001C002C28E857E8D857F8BD28E7823
-:1033E0001979097A07E77004A600800BE6600816D1
-:1033F000E67004E74480F70809DAEAE57960131417
-:10340000F579700EE5782408F87600123246D28CF1
-:10341000D28DD002D001D000D0D0D0E0327581ADB5
-:10342000742A90FF93F0757F30757EF8757D607516
-:103430007CF012053F1234CE12175B90FF93E044EC
-:1034400001F0B2B31234F81232A880DA22C0007C44
-:1034500001EC2408F8E660090CBC08F512329A80E9
-:10346000EED00022C0F0C082C083C000C006C007FA
-:10347000ED2410F876BCED75F021A4248DF582E4DE
-:1034800034FCF583C082C083A3A3E4780DF0A3D8F5
-:10349000FCEC547F75F002A42441F582E5F034354C
-:1034A000F583E493FE740193F5828E83E493FE74B6
-:1034B0000193FFD083D082EFF0A3EEF0ED2408F863
-:1034C000EC4480F6D007D006D000D083D082D0F074
-:1034D00022757800757B007A08791878087600776D
-:1034E000000809DAF8E478087480447FF67401442F
-:1034F00010F58975B808D2ABD2A9227581ADD28EEC
-:10350000D28CD2AFE57B6032FF90FD95E0548060B5
-:103510002478087908E0547FFA7B00E6547FB502EE
-:10352000027BFF08D9F5EB700CEAF012344AAD04C7
-:10353000AC02123461A3A3A3DFD212329A80C57CFD
-:10354000017D002204FE04F204F604EA04E604E22B
-:1035500004EE04FA04A604AA04D604DA04A204A21F
-:1035600004A204DE04BE04B604BA04B204CA04C64B
-:1035700004C204CE04D204AE1901030022004802A2
-:1035800000480E301420C81AD0180A0C0506020391
-:1035900001020001CE0181010000C0008000600036
-:1035A0003000180010000800040002000100081894
-:1035B00028380C05100A0200000000000301100A60
-:1035C000020000000000FBE0FBF2090227000102FC
-:1035D00000A0FA0904000003FF00000007058102B3
-:1035E00040000007050102400000070583030200B8
-:1035F00001220354005500530042003300340031CF
-:1036000000300020002000200020002000200020AA
-:073610000020000000000093
-:00000001FF
--- zfcpdump-kernel-4.4.orig/firmware/mts_edge.fw.ihex
+++ /dev/null
@@ -1,881 +0,0 @@
-:10000000F0360002001E021AFBFFFFFFFFFF023363
-:10001000F9FFFFFFFFFFFFFFFFFFFFFFFFFF0234BE
-:10002000A47581D490FDE88583A0123618EC4D604C
-:100030007378AF8003760018B8A0FA787F800376D3
-:100040000018B865FA78208003760018B820FA788E
-:10005000208003760018B81FFA90FDDDAE83AF82D2
-:1000600090FBF81200AA6005E4F0A380F690FDE88A
-:10007000A88290FDE8A982E8696005E4F20880F7AB
-:100080009001081200B390010C1200B390011012FD
-:1000900000B39001141200D190011A1200D1900106
-:1000A000201200D175D0001234F6020126EF6582CD
-:1000B0007003EE658322E493F8740193F97402935C
-:1000C000FE740393F5828E83E869700122E493F64F
-:1000D000A30880F4E493FC740193FD740293FE740E
-:1000E0000393FF740493F8740593F58288831200D8
-:1000F000AA700122E493A3A883A9828C838D82F045
-:10010000A3AC83AD828883898280E32121049B8014
-:1001100080049BB0B4049BFDE8049F049FFBF304A0
-:10012000A4049FFBF30504050480FED0F030F00921
-:1001300020F303F68010F7800D30F10920F303F26D
-:100140008004F38001F020F404FCD0E0CC22CCC089
-:10015000E0120163020154BC0005D0F0ACF022C3F0
-:1001600013DCFC02012ABF0009ED258275F001F8BD
-:10017000E622BF010FED2582F582EE3583F583750A
-:10018000F004E022ED258275F002F8E222D083D05F
-:1001900082F5F0C3E493A3C5F095F0C0E0C3D0F0BE
-:1001A000E493A395F04012A3A3C3E5F033500205F6
-:1001B000832582F58250020583740193C0E0E493A5
-:1001C000C0E022D083D082F5F0E4937009740193EB
-:1001D0007004A3A3800C74029365F06005A3A3A32D
-:1001E00080E7740193C0E0E493C0E022120264024D
-:1001F00001FB1202B80201FB1202DC0201FB30E03B
-:100200000720E302E622E72230E10720E302E222B0
-:10021000E32230E202E022E493221202DC02022313
-:100220001202B8020223ABF012022DCBC5F0CB2292
-:1002300030E01020E306E6F5F008E622E7F5F009E5
-:10024000E7192230E11020E306E2F5F008E222E3AC
-:10025000F5F009E3192230E206E0F5F0A3E022E42C
-:1002600093F5F074019322BB0003740922BB0107CC
-:1002700089828A83740422BB020789828A8374106C
-:1002800022740A22020284BB0007E92582F8740165
-:1002900022BB010DE92582F582EA3583F5837404DA
-:1002A00022BB020DE92582F582EA3583F5837410BD
-:1002B00022E92582F87402220202B8BF0005EDF897
-:1002C000740122BF01078D828E83740422BF02074E
-:1002D0008D828E83741022EDF87402220202DCBF3C
-:1002E0000007ED2582F8740122BF010DED2582F58E
-:1002F00082EE3583F583740422BF020DED2582F56D
-:1003000082EE3583F583741022ED2582F874022283
-:10031000020310C0E0120264020328C0E01202B817
-:10032000020328C0E01202DC02032830E00B20E3C5
-:1003300004D0E0F622D0E0F72230E10B20E304D035
-:10034000E0F222D0E0F322D0E0F022C9CDC9CACE3B
-:10035000CACBCFCB12035BEDF9EEFAEFFB22BB0069
-:100360002FBF000AFAEDF8E7F60809DAFA22BF0112
-:10037000128D828E83F802037809A3E7F0D8FA225F
-:10038000020383FAEDF8E7F20809DAFA2202038D94
-:10039000BB014DBF001489828A83F9EDF802039FE7
-:1003A00008A3E0F6D9FA220203B0BF01228D828EA3
-:1003B00083FB08C9C582C9CAC583CAE0A3C9C5826F
-:1003C000C9CAC583CAF0A3DBEAD8E8220203D38DE9
-:1003D000828E83F9EDF8E0F208A3D9FA220203DD58
-:1003E000BB024DBF001289828A83F9EDF80203EF48
-:1003F00008A3E493F6D9F922BF01238D828E83FBF3
-:1004000008C9C582C9CAC583CAE493A3C9C582C93C
-:10041000CAC583CAF0A3DBE9D8E722020422898295
-:100420008A83F9EDF8E493F208A3D9F922020433A0
-:10043000BF000DFAEDF8E3F60809DAFA2202043DEE
-:10044000BF01128D828E83F802044A09A3E3F0D81B
-:10045000FA22020455FAEDF8E3F20809DAFA220268
-:10046000045FE6FB08E6FA08E6F904F618700106F0
-:1004700022E6FF08E6FE08E6FD22EFF0A3EEF0A379
-:10048000EDF022EBF0A3EAF0A3E9F022E0FFA3E015
-:10049000FEA3E0FD22E0FBA3E0FAA3E0F9220000C6
-:1004A000000000000000000504006105730026053F
-:1004B0009A00330A0B00610A770066154600610C4A
-:1004C000FB006109AB006109E200610DC200610B34
-:1004D000F300610A1E00610A530061173E003317E2
-:1004E0005100341E1600431EBC0044202900442045
-:1004F0001700471EE300471F88004D1FD9004F1FFC
-:10050000050058338400617CCC7DFF121CC722900B
-:10051000FFFCE020E72DC2AFAE59AF58755A20E579
-:100520005A14C55A6019E4FE7F05EE4FCE24FFCE63
-:10053000CF34FFCF6007E490FF92F080ED80E08E33
-:10054000598F582212050C7D077CB71233A07D0FFE
-:100550007C6E1233BA78A17A06E4F608DAFC7A06E1
-:100560001205CF7C03120E57122165E4FEFF7C0FAB
-:10057000123329D2A822123214E490FC38F090FFF2
-:10058000F0E030E408740190FC39F08005E490FC60
-:1005900039F07D0A7C00122547123297221232145C
-:1005A00090FC39E014700E90FFF0E04410F07C00F5
-:1005B0001225E0801990FC39E0700E90FFF0E054B5
-:1005C000EFF07C001225E080057C171225E0123246
-:1005D000972290FFF0E054ABF090FFF0E04420F061
-:1005E000228C378D367882EDF608ECF6EDFEECFDC8
-:1005F0007F019000051201F57880F67882E6FD080B
-:10060000E6FCEDFEECFD7F019000041201F5540FB5
-:10061000FC7D8012176F7880E6700DAD3AAE39AF71
-:1006200038E41203187C082290FFF0E054FEF090AA
-:10063000FFF0E054FDF0801E7882E6FD08E6FCED58
-:10064000FEECFD7F0190000812021725E0440190A6
-:10065000FFF3F00206DB7882E6FD08E6FCEDFEEC37
-:10066000FD7F0190000612021754FE90FFF3F08008
-:100670002B7882E6FD08E6FCEDFEECFD7F019000A4
-:1006800008120217FAEB90FFF1F01208CA400DAD04
-:100690003AAE39AF38E41203187C18227882E6FDAE
-:1006A00008E6FCEDFEECFD7F0190000812021790B9
-:1006B000FFF1F01208CA400DAD3AAE39AF38E4127E
-:1006C00003187C18227882E6FD08E6FCEDFEECFDBE
-:1006D0007F01900006120217440190FFF3F0788327
-:1006E000E62403F618E63400F67880E624FE500986
-:1006F00090FFF0E054FDF0800790FFF0E04402F03E
-:10070000E490FFF1F0788176007880E624FFFCE445
-:1007100034FFFD7881E67F00FEECD39EEF6480CD50
-:1007200064809D402F1208AF400F7881E6AD3AAE4D
-:1007300039AF381203187C182290FFF2E0FC78825F
-:100740008683088682ECF0788106A37882A68308E7
-:10075000A68280B51208AF400F7881E6AD3AAE3977
-:10076000AF381203187C182290FFF2E0FC788286E2
-:1007700083088682ECF07880E6AD3AAE39AF381265
-:1007800003187C00228C378D367882EDF608ECF663
-:10079000EDFEECFD7F019000051201F57881F67801
-:1007A00082E6FD08E6FCEDFEECFD7F019000041200
-:1007B00001F5540FFC7D8112176F7881E670037C80
-:1007C000082290FFF0E054FEF090FFF0E054FDF0BE
-:1007D000801B7882E6FD08E6FCEDFEECFD7F0190D3
-:1007E000000812021725E090FFF3F0805B7882E6A4
-:1007F000FD08E6FCEDFEECFD7F01900006120217FD
-:1008000054FE90FFF3F080217882E6FD08E6FCEDCF
-:10081000FEECFD7F01900008120217FAEB90FFF149
-:10082000F01208CA40037C18227882E6FD08E6FC34
-:10083000EDFEECFD7F0190000812021790FFF1F031
-:100840001208CA40037C18227883E6240AF618E6C8
-:100850003400F6788076007881E624FFFCE434FFEB
-:10086000FD7880E67F00FEECD39EEF6480CD64804F
-:100870009D402178828683088682E090FFF1F01205
-:1008800008CA40037C1822788006788306E6187030
-:10089000010680C390FFF0E04401F078828683086F
-:1008A0008682E090FFF1F01208CA40037C18227C97
-:1008B000002290FFF0E020E71290FFF0E030E50921
-:1008C00090FFF0E04420F0C32280E7D32290FFF0B5
-:1008D000E020E31290FFF0E030E50990FFF0E04403
-:1008E00020F0C32280E7D3228C428D417C00ED545E
-:1008F000F0FDEC7003ED64307005753E0380037508
-:100900003E04AC3E120F74758300858340E541546C
-:100910000FF53FE5407004E53F64037035E53E2484
-:10092000FD75F00AA42402F582E434FCF583E0307E
-:10093000E60512105B8019E53E24A1F8E654FBF6AB
-:1009400078ADE62405F58218E63400F583740FF0DF
-:100950008059E5407004E53F64047048E53E24FD9D
-:1009600075F00AA42402F582E434FCF583E030E556
-:1009700007AC42AD41121C5CE54230E21578B1E6AD
-:1009800030E00F78B1E630E109E4FF04FE7C0412A8
-:10099000332978ADE62406F58218E63400F5837431
-:1009A0000FF08007E4FC7DEE121C5CC203221232C1
-:1009B00014120F7478ADE62406F58218E63400F5BB
-:1009C00083E090FC38F078ADE62405F58218E63433
-:1009D00000F583E090FC39F0C2037D027C00122513
-:1009E00047123297221232147899ECF6EC24A1F8CF
-:1009F000E630E1077C131225E0800F90FC39E0FD22
-:100A00007899E6FC1213F11225E012329722123285
-:100A1000147899ECF67D00120F141225E01232972B
-:100A2000221232147899ECF6EC24A1F8E630E207B1
-:100A30007C131225E0801B7899E624A1F8E620E1DA
-:100A4000077C121225E0800A7899E6FC1214151230
-:100A500025E0123297221232147899ECF6EC24A198
-:100A6000F8E620E2077C111225E0800A7899E6FC7E
-:100A70001215161225E0123297221232147899ECD0
-:100A8000F6120F7478ADE62409F58218E63400F505
-:100A900083E090FC3FF078ADE6240AF58218E63456
-:100AA00000F583E090FC40F078ADE62403F5821871
-:100AB000E63400F583E0FC78ADE62404F58218E620
-:100AC0003400F583E0F56278ADE62402F58218E69D
-:100AD0003400F583E0F5638C61E4EC333354017842
-:100AE00099F66008E56230E1037899067899E69016
-:100AF000FC41F078ABE62402F58218E63400F58379
-:100B0000E0FDA3E0540CFCED54E68C65F564E56172
-:100B100030E503436501E56220E50EE561547F7031
-:100B200008E56120E703436502E56130E3034365BF
-:100B300010E56130E203436520E56154036003433F
-:100B40006540E56130E103436580E56130E40343DE
-:100B50006401E56130E603436408E56220E40EE5E4
-:100B600061547F7008E56120E7034364105365FB1F
-:100B70005364F9AD64E56590FC3ACDF0A3CDF0E5A2
-:100B80006330E30DE5635430C4540F90FC3DF080B6
-:100B900005E490FC3DF0E563540390FC3CF0E56314
-:100BA0005404C31390FC3EF090FC3CE0700E7D3585
-:100BB0007EFC7F01740190000912014B78ADE624A0
-:100BC00008F58218E63400F583E07C00FD78ADE698
-:100BD0002407F58218E63400F583E07F004CFEEF31
-:100BE0004D90FC38F0A3CEF0CEC2037D0A7C0012FB
-:100BF0002547123297221232147899ECF6789E76B5
-:100C0000010876FC087638789B760C789E12046E84
-:100C100012021D789CCBF6CB08F67F00EF24EA4049
-:100C20001FE4EF25E090365AFD93CD0493789D663E
-:100C30007003ED18667006789B760080030F80DCE9
-:100C4000789AEFF6789E12046E90000212021778DE
-:100C50009CCBF6CB08F65404CB54064B6004789B2F
-:100C6000760B789DE630E313789E12046E900005B3
-:100C70001201F524FB5004789B760D789DE654C054
-:100C80007D0064C04D7004789B760B789E12046ED4
-:100C90009000041201F524FC5004789B760F789E96
-:100CA00012046E9000061201F524FD5004789B7624
-:100CB0000E789E12046E9000091201F524FD500476
-:100CC000789B760A789BE6702A7899E6FC120F7476
-:100CD000789E12046E78ABE6F978AAE6FA7B017486
-:100CE0000A7800120348C2037899E6FC12111778BB
-:100CF0009BECF6789BE6FC1225E01232972212322A
-:100D0000147899ECF6120F747899E624FD75F00AC0
-:100D1000A42414F582E434FCF583AC82AD8378AA74
-:100D20008683088682ECF9EDFA7B0A78011203B01B
-:100D3000C2037899E6FC121117123297228D2B8C80
-:100D40002AED60407527017529487528FFE52A249A
-:100D5000FDFCE434FFFDEC7C0325E0CD33CDDCF974
-:100D6000FCE5292CF529E5283DF528AD29AE28AF6D
-:100D700027748090000612032074809000021203F2
-:100D800020120FC7E52B14603B75270175290875E4
-:100D900028FFE52A24FDFCE434FFFDEC7C0325E07C
-:100DA000CD33CDDCF9FCE5292CF529E5283DF528E6
-:100DB000AD29AE28AF27E4900006120320E490008E
-:100DC00002120320221232147899ECF6EC24A1F8D6
-:100DD000E630E2097899E6FC121516D2007899E619
-:100DE000FC120F74789A760090FC39E030E70478B2
-:100DF0009A7601789AE6FD7899E6FC120D3AC203DC
-:100E00003000077899E6FC1214157C001225E012D8
-:100E100032972278ADE62404F58218E63400F58393
-:100E2000E04401F078ADE62404F58218E63400F5DC
-:100E300083E030E00280ED78ADE6240BF58218E621
-:100E40003400F583E054F8F078ADE62402F582181A
-:100E5000E63400F583E04480F022C2038C58120F80
-:100E60007478AA8683088682798B7A367B0A780121
-:100E70001203FE120E10AC587D02120D3AC203ACE2
-:100E800058121117228D538E528F518C50120F749D
-:100E9000754F0078ADE62405F58218E63400F58339
-:100EA000E020E41FE54F24F64019054FC2037C18EB
-:100EB0001233D790FF93E04401F0B2B3AC50120F5D
-:100EC0007480D078ADE62405F58218E63400F58309
-:100ED000E020E405C2037C022278ADE62405F58219
-:100EE00018E63400F583E0540F601678ADE624056B
-:100EF000F58218E63400F583E0540FF0C2037C015C
-:100F00002278AC8683088682E0AD53AE52AF511290
-:100F10000318C2037C00228D318C30121516E53186
-:100F2000600FE530B4030A7C0112250F7C81122585
-:100F30000FAC30120F74E531601A78AE86830886E4
-:100F400082E054E7F0A3A3A3A3E054E7F0AC307D24
-:100F500002120D3A78AA868308868279957A367BC2
-:100F60000A78011203FEC203E53024A1F8E654FD1D
-:100F7000F6AC30121117228C26300305123376801E
-:100F8000F87C0A123289D203E52624FD78A7F67090
-:100F90000778AE76FF0876E078A7E67D007C04252A
-:100FA000E0CD33CDDCF9FC24A078ADF6ED34FF18AC
-:100FB000F678A7E675F00AA42400FCE434FCFD787A
-:100FC000AAEDF608ECF61233222278ADE62402F5FB
-:100FD0008218E63400F583E030E72278ADE624029B
-:100FE000F58218E63400F583E0547FF078ADE6240E
-:100FF00002F58218E63400F583E04480F02278AEF2
-:101000008683088682E0547FF0AD83E5822404FC69
-:10101000E43D8C82F583E0547FF078ADE6240BF557
-:101020008218E63400F583E054F8F078AFE6240146
-:10103000F58218E63400F583E04403F078AFE62447
-:1010400005F58218E63400F583E04403F078ADE658
-:101050002405F58218E63400F583740FF02278AE8B
-:101060008683088682E0543FF0AD83E5822404FC49
-:10107000E43D8C82F583E0543FF078A7E624A8F89D
-:10108000E6FC78AFE62401F58218E63400F583EC3F
-:10109000F078A7E624A8F8E6FC78AFE62405F58208
-:1010A00018E63400F583ECF078ADE6240BF58218F1
-:1010B000E63400F583E054FB4402F52678ABE624E1
-:1010C00002F58218E63400F583E030E5034326019B
-:1010D00078ADE62405F58218E63400F583E030E0CB
-:1010E00003120FC7E526FC78ADE6240BF58218E65F
-:1010F0003400F583ECF078ADE62405F58218E6348B
-:1011000000F583740FF078AE8683088682E0448011
-:10111000F0A3A3A3A3E04480F0228C2A120F7478DA
-:10112000ABE62408F58218E63400F583E0FC78ADE0
-:10113000E6240AF58218E63400F583ECF078ABE695
-:101140002407F58218E63400F583E0FC78ADE62448
-:1011500009F58218E63400F583ECF078AA86830856
-:101160008682E0FDA3E0FCEDFE78ADE62408F58282
-:1011700018E63400F583EEF0ECFE78ADE62407F5D2
-:101180008218E63400F583EEF08C298D28C3EC94A8
-:1011900005ED940C400575277C8033D3E529940137
-:1011A000E5289403400575273C8023D3E5299481E5
-:1011B000E528940140057527188013D3E52994602C
-:1011C000E5289400400575270C8003752708AF2794
-:1011D000E4EF547C4483FF8F27E527FC78AFE624B7
-:1011E00001F58218E63400F583ECF0E527FC78AFD2
-:1011F000E62405F58218E63400F583ECF0E527FCDB
-:1012000078A7E624A8F8ECF678ADE62402F5821873
-:10121000E63400F583E0F52778ABE62402F5821882
-:10122000E63400F583A3E030E3175327C778ABE635
-:101230002405F58218E63400F583E0903686934263
-:101240002778ABE62402F58218E63400F583E03017
-:10125000E70543274080035327BF5327FB78ABE6BE
-:101260002406F58218E63400F583E0600343270482
-:101270005327FC78ABE62404F58218E63400F583A6
-:10128000E04227432780E527FC78ADE62402F5827B
-:1012900018E63400F583ECF078ADE62404F5821806
-:1012A000E63400F583E0F52778ABE62402F58218F2
-:1012B000E63400F583A3E030E1055327DF800343E4
-:1012C000272078ABE62402F58218E63400F583E0A7
-:1012D00030E4055327EF800343271078ABE6240959
-:1012E000F58218E63400F583E0B40203432702E5F3
-:1012F00027FC78ADE62404F58218E63400F583EC8B
-:10130000F078ADE62403F58218E63400F583E0F5C5
-:101310002778ABE62409F58218E63400F583E070FF
-:101320000553277F800343278078ABE62402F582AC
-:1013300018E63400F583A3E030E00543272080035E
-:101340005327DF78ABE62402F58218E63400F583F4
-:10135000E030E30543274080035327BF78ABE62402
-:1013600002F58218E63400F583E030E005432710EB
-:1013700080035327EF78ABE62402F58218E63400A9
-:10138000F583A3E030E40543270880035327F7786B
-:10139000ABE62402F58218E63400F583A3E030E5DD
-:1013A0000543270480035327FB78ABE62402F5822C
-:1013B00018E63400F583A3E030E6054327018003F7
-:1013C0005327FE78ABE62402F58218E63400F58355
-:1013D000A3E030E70543270280035327FDE527FC00
-:1013E00078ADE62403F58218E63400F583ECF0C20C
-:1013F000037C00228D278C26ED54031460037C109F
-:1014000022E527547C24FC40037C0B22E52624A102
-:10141000F8E64402F67C00228C30120F74E530248A
-:10142000A1F8E620E24FAC307D02120D3AE53024FF
-:10143000FE4428FC78AE8683088682ECF0AF83E514
-:10144000822404FEE43FFFEC8E828F83F07C038CC9
-:101450002CE52CFC78AFE62401F58218E63400F583
-:1014600083ECF0E52CFC78AFE62405F58218E63431
-:1014700000F583ECF0752D01752F48752EFFE530D2
-:1014800024FDFCE434FFFDEC7C0325E0CD33CDDC12
-:10149000F9FCE52F2CF52FE52E3DF52E78AFE6244F
-:1014A00004F58218E63400F583E054E7F52CAD2FFF
-:1014B000AE2EAF2DE4900002120320E4900006123D
-:1014C00003201201EF30E503432C10E52CFC78AF2C
-:1014D000E62404F58218E63400F583ECF012105B84
-:1014E00078ADE62406F58218E63400F583E0C20301
-:1014F000FCE53024A1F8E64404F68C2CE530540FCA
-:10150000C454F07E00FFEEEF44047D00FFEC4EFC7F
-:10151000ED4FFD121CC77C00228C2F120F74120F8E
-:10152000FB78AE8683088682E05408F0A3A3A3A3C9
-:10153000E05408F0AC2F7D02120D3AC203E52F24CF
-:10154000A1F8E654FBF67C0022123214789AECF6ED
-:10155000EC24A1F8E630E10A7D007C131225471245
-:101560003297789AE624A1F8E64401F6789AE6FCE8
-:10157000120F74789AE624FD75F00AA42414F582FB
-:10158000E434FCF58378AAE6FA08E6F97B0A7801E8
-:101590001203B078AA868308868279957A367B0A08
-:1015A00078011203FE120FC7C203789AE6FC1211EB
-:1015B000177899ECF6EC600A7D007C08122547123A
-:1015C0003297789AE6FC120F7478ADE62404F5821F
-:1015D00018E63400F583E0441054DFFC78ADE624CF
-:1015E00004F58218E63400F583ECF07899ECF6C245
-:1015F000037CC81233D7789AE6FC120F7478ADE6F4
-:101600002404F58218E63400F583E054EFF0C203B9
-:101610007CC81233D7789AE6FC120F7478ADE624B2
-:1016200004F58218E63400F583E04410F0C2037C30
-:10163000C81233D7789AE6FC120F7478ADE624040A
-:10164000F58218E63400F583E04420F0C2037CF014
-:101650001233D7789AE6FC120F7478ADE62405F5BC
-:101660008218E63400F583E030E415C203789AE688
-:1016700044107F00FE7C0712332912329702173D77
-:1016800078ADE62404F58218E63400F583E054CF03
-:10169000F0C2037CC81233D7789AE6FC120F747834
-:1016A000ADE62404F58218E63400F583E04430F01A
-:1016B000C2037CF01233D7789AE6FC120F7478AD2F
-:1016C000E62405F58218E63400F583E030E414C220
-:1016D00003789AE644107F00FE7C07123329123209
-:1016E00097805D78ADE62404F58218E63400F58332
-:1016F000E054EFF078ADE62404F58218E63400F506
-:1017000083E054DFF0789AE624FD75F00AA42414EF
-:10171000F582E434FCF583AC82AD8378AA86830835
-:101720008682ECF9EDFA7B0A78011203B0C20378E5
-:101730009AE6FC1211177D007C0B12254712329796
-:1017400022123214E490FC39F07D027C001225470D
-:10175000123297221232147C001225E012329722A4
-:10176000743C90FBE0F0743E90FBE0F0E490FC28C9
-:10177000F0228D358C34ECB401028003D34002801A
-:1017800028B402028003D34008A835E625E0F6809D
-:1017900018B404028003D3400AA835E625E025E00A
-:1017A000F68006A83576008000228C3C8D3BEDFE4D
-:1017B000ECFD7F0175660675670090FC29120477C1
-:1017C0001201EFB480028006D3500302187090FC1F
-:1017D000291204899000031201F554F0B4300280FC
-:1017E00003D3405F90FC291204899000081202176D
-:1017F000FAFDEBFE7F0190FC2C120477EECD9036C3
-:101800009FFCE493FF740193FEF9EFFA7B01EAFF7A
-:10181000E9FEECC39EED9F40259036A1E493FD7454
-:101820000193FCEDFEECFD7F01EECDFC90FC2EE083
-:10183000D39C90FC2DE09D50057566808033121975
-:101840008E802EB460028003D3400BAC3CAD3B12C3
-:1018500007828C66801BB41003B34010C3B420030E
-:10186000B34009C3B440028003D340007566818051
-:10187000008075B481028003D3406B90FC29120470
-:10188000899000031201F554F0B430028003D34074
-:101890001D90FC29120489900008120217FAFDEB32
-:1018A000FE7F0190FC2F1204771218F88036B46086
-:1018B000028003D34013753A67E4F539F538AC3C40
-:1018C000AD3B1205DE8C66801BB41003B34010C321
-:1018D000B42003B34009C3B440028003D340007571
-:1018E0006681800080028000E566FC90FC2912047D
-:1018F00089EC900002120320AC672290FC291204AC
-:10190000899000041201F5600474018001E4A2E0F2
-:10191000920190FC29120489ED2403FD50010E90E0
-:10192000FC2C12047790FC29120489900005120106
-:10193000F5F5679000041201F5540FFC7D6712174E
-:101940006FE5677004756608227566007884760016
-:101950007884E6C39567503890FC2F1204891201F1
-:10196000EFFC90FC2C120489EC12031830010E904D
-:10197000FC31E004F090FC307003E004F078840661
-:1019800090FC2EE004F090FC2D7003E004F080C089
-:101990002290FC2AE0FDA3E0FCEDFEECFD7F01EDD2
-:1019A000240AFD50010E90FC3212047790FC29129B
-:1019B00004899000041201F5540FB401028003D38E
-:1019C000401790FC321204890DED70010E90FC2F2F
-:1019D00012047778887601804EB402028003D340E7
-:1019E0001990FC32120489ED2402FD50010E90FC86
-:1019F0002F12047778887602802DB404028003D3F6
-:101A0000401990FC32120489ED2404FD50010E901F
-:101A1000FC2F12047778887604800CB400028003CF
-:101A2000D340007566082290FC29120489900005B5
-:101A30001201F5F567788576007885E6C3956740ED
-:101A400003021AF6788676007886E6C37888965080
-:101A50007690FC2C1204891201EFFC90FC321204E7
-:101A6000921201E9F45CFC1201E9F890FC2F1204D7
-:101A700089E8C0E01201EFC8D0E0C8584CFC90FCE7
-:101A80002C120489EC1203187887ECF690FC31E0F4
-:101A900004F090FC307003E004F009E970010A9052
-:101AA000FC3212048090FC29120489900004120177
-:101AB000F530E40E90FC2EE004F090FC2D7003E075
-:101AC00004F078860680817888E6FDE4FEFFEECD9E
-:101AD000FC90FC31E02CF090FC30E03DF07888E6A2
-:101AE000FDE4FEFFEECDFC90FC34E02CF090FC33E6
-:101AF000E03DF0788506021A367566002222C0E0C5
-:101B0000C0F0C082C083C0D0E8C0E0E9C0E0EAC055
-:101B1000E0EBC0E0ECC0E0EDC0E0EEC0E0EFC0E024
-:101B200090FF92E01201C01B49301B49321B58380C
-:101B30001B6A3A1B7C3E1B94441B88461BA0501B0F
-:101B4000E2521BC1541C035600001C2490FF92E07B
-:101B50007F00FE7C01123329021C34E4FF04FE7C6A
-:101B600003123329742090FFFEF0021C34E4FF04BA
-:101B7000FE7C02123329744090FFFEF0021C34E414
-:101B8000FF04FE7C04123329021C34E4FF04FE7CB3
-:101B900005123329021C34E4FF04FE7C06123329AB
-:101BA000021C3490FFA5E07D0090FBF8CDF0A3CDA2
-:101BB000F090FBF9E0FCF58390FBF8E04433FD1274
-:101BC0001CC7807390FFB5E07D0090FBFACDF0A3B9
-:101BD000CDF090FBFBE0FCF58390FBFAE04443FD85
-:101BE000121CC7805290FFA6E07D0090FBFCCDF058
-:101BF000A3CDF090FBFDE0FCF58390FBFCE04434CA
-:101C0000FD121CC7803190FFB6E07D0090FBFECD39
-:101C1000F0A3CDF090FBFFE0FCF58390FBFEE044E9
-:101C200044FD121CC7801090FF92E07D00FCED4443
-:101C3000AAFD121CC78000E490FF92F0D0E0FFD014
-:101C4000E0FED0E0FDD0E0FCD0E0FBD0E0FAD0E058
-:101C5000F9D0E0F8D0D0D083D082D0F0D0E03205F7
-:101C600081058105810581A881181818EDF608EC19
-:101C7000F690FF5AE020E70280F790FF59E07D00E0
-:101C8000A88118CDF6CD08F67D03A881E618FCE6FC
-:101C9000CC25E0CC33CCDDF9CCF6CC08F6A8811805
-:101CA000E644F8F6A881181818E6FD08E6FCA881B5
-:101CB000188683088682EDF0A3ECF0740290FF5A38
-:101CC000F0158115811581158122E5812405F581A5
-:101CD000E4A88118F6A88118181818EDF608ECF693
-:101CE00090FBF5E024F85003021DE8E4A8811818E1
-:101CF000F6A88118E6FEA88118181818E6FD08E66F
-:101D0000FC7F00EF24F8404DE4EF25E0247DF582D0
-:101D1000E434FCF583E0FBA3E06C7003FAEB6D7038
-:101D2000097401A8811818F6802BE4EF25E0247DC2
-:101D3000F582E434FCF5837A00E054F0CCF8CCCDA5
-:101D4000F9CDFB7800E954F0F9EA687002EB6970AC
-:101D5000010E0F80AEA88118EEF6A8811818181889
-:101D6000EDF608ECF6A881EFF6A8811818E6707970
-:101D7000A88118E624F74071A88118181818E654AD
-:101D80000FA881F664046017A881E664036010A8B8
-:101D90008118181818E6FD08E6FC121C5C804A7CC5
-:101DA0000A123289A88118181818E6FD08E6FC9076
-:101DB000FBF4E025E0247DF582E434FCF583EDF0CE
-:101DC000A3ECF090FBF4E0FFE4EF045407FF90FB7A
-:101DD000F4F090FBF5E004F012332290FBF6E07093
-:101DE00008E4FEFF7C0F123329802790FBF7E00404
-:101DF000F0543F701D90FBF7E044FE7D00FC90FB2B
-:101E0000F4E025E0247DF582E434FCF583EDF0A3D5
-:101E1000ECF0E58124FBF58122788B7600788C76D6
-:101E200000740190FBF6F012321490FBF5E060575D
-:101E30007C0A12328990FBF3E025E0247DF582E4F0
-:101E400034FCF583E0FDA3E0FC90FBF3E025E02407
-:101E50007DF582E434FCF583E4F0A3F090FBF3E03D
-:101E6000FFE4EF045407FF90FBF3F090FBF5E01460
-:101E7000F07889EDF608ECF61233227889E6FD0851
-:101E8000E6FC1208E580A312337690FF93E044014C
-:101E9000F0B2B3788B06B6000D788B7600788CE6BE
-:101EA000F40404788CF68082E490FBF6F090FBF565
-:101EB000E07D00FCED44CFFD121C5C123297221233
-:101EC0003214E5706449456F601590FF83E0540F4C
-:101ED0007D00D39570ED956F500512305D80031233
-:101EE000312D12329722123214E5706449456F6029
-:101EF00005123167800E90FF80E04408F090FF8368
-:101F0000E0547FF0123297221232148C54EC54F0C9
-:101F1000B41015756A357569FC756801E56A2403A6
-:101F2000F56AE5693400F569E4F557F556E556C3F9
-:101F300094015027E554540FFCAD6AAE69AF6812A6
-:101F40000E828C55EC60028012056AE56A7002050B
-:101F5000690557E5577002055680D2E554540F24A1
-:101F6000A1F8E654FEF6E554540F7F00FE7C1212F1
-:101F70003329E5551470097D007C09122547800737
-:101F8000AD577C001225471232972212321490FF6F
-:101F9000FCE04402F090FF00E030E71390FF83E0A4
-:101FA0004480F0436D8090FFFCE04401F08011908C
-:101FB000FF82E04408F0536D7F90FFFCE054FEF098
-:101FC00090FF81E04480F01225FA90FFFEE0440586
-:101FD000F090FFFCE054FDF0123297221232147C94
-:101FE000011233D778B1E64402F674FEFC04FD1208
-:101FF0001CC790FF5AE030E70280F7E4F54E754DBC
-:1020000010AC4EAD4DE54E154E7002154DEC4D60C9
-:102010000280EE438701123297221232147C0212A0
-:1020200032A378B1E654FDF61232972212321478B8
-:10203000B1E630E02C78B1E630E12678B1E6FCF587
-:102040008318E644F0FD121C5C90FFFCE04420F095
-:102050007C021233D778B1E654FDF6741A90FFFE75
-:10206000F078B1E6FCF58318E644F1FD121C5C1231
-:10207000329722756D0090FFFFE06003436D01759C
-:102080006E00E4F56CF56BE4F56F7570497484903F
-:10209000FF82F0748490FF80F0748090FF58F07499
-:1020A0008090FF5AF0AD46AF457E00EE24FE50030F
-:1020B00002213FE4EE75F007A4247FF582E434F8B2
-:1020C000F583E0FFE4EF5480FDE4EF540F14FFEDDF
-:1020D0006038E4EF75F008A42448F582E434FFF595
-:1020E000837490F0E4EF75F008A4244AF582E43498
-:1020F000FFF5837480F0E4EF75F008A4244EF582B8
-:10210000E434FFF5837480F08034E4EF75F008A4C4
-:102110002408F582E434FFF5837490F0E4EF75F061
-:1021200008A4240AF582E434FFF583E4F0E4EF75B3
-:10213000F008A4240EF582E434FFF583E4F00E02E7
-:1021400020A88D468E448F45747F90FFFDF07490DB
-:1021500090FFFCF0228C58EC24F65006E55824370A
-:10216000FC22E5582430FC22D2B0D2B1C2B41225F0
-:1021700044EC700302227F755C03AE5B7F00E55C7C
-:10218000155C6480247F5035EF2400F582E434FB35
-:10219000F583E0FE24FE501EEF7D00FCE4FB74742A
-:1021A000C39CFAEB9DFBEE7D00FCEAC39CED6480D2
-:1021B000CB64809B50028005EF2EFF80C18E5B8F29
-:1021C0005AE55C6480247F500302227FE55A248E06
-:1021D000500302227F855A5D755B00AE5AAF5B905B
-:1021E00036CAE493F55CE55C155C6480247F501886
-:1021F000EE2400F582E434FBF583E0FCEF9036CA70
-:10220000936C70040E0F80DE8E5A8F5BE55C6480E9
-:10221000247F406E755E017560E8755FFFE55D24A3
-:1022200002F55A755C07E55C334057AD60AE5FAFB1
-:102230005EE55CF5823395E0F5831201F5C4540F39
-:10224000FC122152E55A2400F582E434FBF583ECBC
-:10225000F0055A055AAD60AE5FAF5EE55CF58233BE
-:1022600095E0F5831201F5540FFC122152E55A2432
-:1022700000F582E434FBF583ECF0055A055A155C51
-:1022800080A4740290F851F090F86B79A37A367BB1
-:102290002778011203FE756A357569FC756801E4DB
-:1022A00090FF83F0748090FF81F0755902E55975B5
-:1022B000F007A4247FF582E434F8F583E07893F600
-:1022C000FC540F14FC7893ECF6E55975F007A42440
-:1022D00081F582E434F8F583E0789676FD0876E8B7
-:1022E000FC7893E675F008A42448F582E434FFF501
-:1022F00083E4F07893E675F008A4244FF582E43483
-:10230000FFF583ECF07896E6FF08E67E03CFC31373
-:10231000CF13DEF9FE7893E675F008A42449F58220
-:10232000E434FFF583EEF07893E675F008A4244AD0
-:10233000F582E434FFF5837480F07894ECF67D0048
-:102340007897E62CF618E63DF67896E6FD08E67CEA
-:1023500003CDC313CD13DCF9FC7893E675F008A424
-:10236000244DF582E434FFF583ECF07893E675F0C4
-:1023700008A4244EF582E434FFF583E4F07896E671
-:10238000FD08E6FC7893E6FF7E00EE24FE50030293
-:1023900024FEE4EE75F007A4247FF582E434F8F51A
-:1023A00083E0FFE4EF5480FAE4EF540F14FFE4EE0F
-:1023B00075F007A42481F582E434F8F583E078947D
-:1023C000F6E4EE1313548024F0F8E434FDF9E8FC4D
-:1023D000E9FD8A5AEA700302246BE4EF75F008A461
-:1023E0002448F582E434FFF583E4F07894E6FAE4D7
-:1023F000EF75F008A4244FF582E434FFF583EAF08A
-:10240000EDFBEC7A03CBC313CB13DAF9FAE4EF75E7
-:10241000F008A42449F582E434FFF583EAF07894C7
-:10242000E67B00FAEC2AFCED3BFDFBEC7A03CBC328
-:1024300013CB13DAF9FAE4EF75F008A4244DF58212
-:10244000E434FFF583EAF0E4EF75F008A4244AF5DC
-:1024500082E434FFF5837480F0E4EF75F008A4247F
-:102460004EF582E434FFF5837480F00224FAE4EF41
-:1024700075F008A42408F582E434FFF583E4F078CD
-:1024800094E6FAE4EF75F008A4240FF582E434FF33
-:10249000F583EAF0EDFBEC7A03CBC313CB13DAF947
-:1024A000FAE4EF75F008A42409F582E434FFF5831B
-:1024B000EAF07894E67B00FAEC2AFCED3BFDFBECBD
-:1024C0007A03CBC313CB13DAF9FAE4EF75F008A45F
-:1024D000240DF582E434FFF583EAF0E4EF75F008AB
-:1024E000A4240AF582E434FFF583E4F0E4EF75F008
-:1024F00008A4240EF582E434FFF583E4F00E0223F1
-:10250000878E597896EDF608ECF67893EFF6122060
-:1025100070228C26EC30E718E526540F1475F0086D
-:10252000A42448F582E434FFF583E054DFF08016FC
-:10253000E526540F1475F008A42408F582E434FF4E
-:10254000F583E054DFF0227C0022EC90FC37F08C25
-:1025500024ED2403F5257D00D39572ED957140039C
-:10256000857225E52524B75009752503740290FC72
-:1025700037F0AC2512315222E4F56CF56B12257E52
-:102580002290FC35E06573600E740490FC37F0E433
-:10259000F56B756C0380467D73E4FEFF79357AFC3C
-:1025A0007B0174057800120348E56C2403F56CE5A3
-:1025B0006B3400F56BE56CD39572E56B9571400655
-:1025C00085726C85716BD3E56C9448E56B94004023
-:1025D0000C740290FC37F0E4F56B756C03AC6C1274
-:1025E000315222EC90FC37F0E4F56CF56B8C32EC58
-:1025F000600512314380057C001231522290FF9316
-:10260000E04401F0B2B390FF04E0F54A90FF06E029
-:10261000FDA3E0ED7D00FC7D00FC90FF06E0FFA344
-:10262000E07E00FFE4FEEC4EFCED4FFDC3EC944871
-:10263000ED9400502290FF06E0FDA3E0ED7D00FC4C
-:102640007D00FC90FF06E0FFA3E07E00FFE4FEECCF
-:102650004EFCED4FFD8004E4FD7C488C728D719042
-:10266000FF02E0FDA3E0ED7D00FC7D00FC90FF0299
-:10267000E0FFA3E07E00FFE4FEEC4EF54CED4FF5ED
-:102680004B756A357569FC7568017D357EFC7F0187
-:102690007973E4FAFB74057800120348754900E584
-:1026A0004924FE4019AD6AAE69AF68E4120318050B
-:1026B000490DED70010E8D6A8E698F6880E1756A33
-:1026C000357569FC75680178B3E614184660030235
-:1026D00027927890E6FF08E6FE788EE4F608F6C3C7
-:1026E000788FE6940218E69400501DE4FEFFC3EED6
-:1026F00094E8EF940350070EBE00010F80F0788F2E
-:1027000006E61870010680D77890EFF608EEF6D24C
-:10271000B47890E6FF08E6FE788EE4F608F6C37813
-:102720008FE6941E18E69400501DE4FEFFC3EE945D
-:10273000E8EF940350070EBE00010F80F0788F067B
-:10274000E61870010680D77890EFF608EEF6C2B171
-:102750007890E6FF08E6FE788EE4F608F6C3788FF8
-:10276000E6943A18E69400501DE4FEFFC3EE94E8A8
-:10277000EF940350070EBE00010F80F0788F06E63D
-:102780001870010680D77890EFF608EEF6D2B1788F
-:10279000B2E4F608F690FF00E05460B40002800650
-:1027A000D35003022D9BE54A540FF549E54A548066
-:1027B000A2E0920290FF01E012018A000B2D962701
-:1027C000D428F22D9629FE2D962AE12B152C7C2C4F
-:1027D0007F2CBF2D3F2D6DE56D30E70EE54C454B51
-:1027E0007008E572640245716003022D9890FF0045
-:1027F000E0541FB400028003D34029E54A6003027D
-:1028000028EFAD6AAE69AF68740112031878B1E6BB
-:1028100030E00BAD6AAE69AF6874021203187C0237
-:1028200012315222B401028003D3401BE56D20E136
-:1028300007E54A60030228EFE54A24FE5003022818
-:10284000EF7C0212315222B402028006D3500302FE
-:1028500028EDE56D20E10DE54A6009E54A648060F8
-:10286000030228EFAC4A1231D940030228EFE549B0
-:10287000702530021190FF80E05408AD6AAE69AF58
-:1028800068120318800F90FF82E05408AD6AAE69A9
-:10289000AF68120318803D154930021DE54975F0F7
-:1028A00008A42448F582E434FFF583E05408AD6AB7
-:1028B000AE69AF68120318801BE54975F008A424BF
-:1028C00008F582E434FFF583E05408AD6AAE69AFE1
-:1028D00068120318AD6AAE69AF681201EF600BAD04
-:1028E0006AAE69AF6874011203187C021231522279
-:1028F0008000022D98E56D20E706E57245716003C2
-:10290000022D9890FF00E0541FB400028003D340D2
-:102910001AE54C14454B7004E54A60030229FB7824
-:10292000B1E654FEF67C0012315222B4010280035B
-:10293000D3402AE56D20E108E56D20E0030229FB84
-:10294000E56D30E004E54A700BE56D30E109E54ADC
-:1029500024FE50030229FB7C0012315222B40202F1
-:102960008006D350030229F9E54C454B6003022948
-:10297000FBAC4A1231D940030229FBE56D20E10787
-:10298000E56D20E0028077E56D30E006E549600204
-:10299000806CE549700F90FF82E054F7F090FF8063
-:1029A000E054F7F022E549B401028003D340097DE9
-:1029B000017C03120F148011B402028003D340097A
-:1029C0007D017C04120F1480001549300215E54981
-:1029D00075F008A42448F582E434FFF583E054F749
-:1029E000F08013E54975F008A42408F582E434FF6B
-:1029F000F583E054F7F07C00123152228000022D62
-:102A000098E56D20E706E57245716003022D989008
-:102A1000FF00E0541FB400028003D3401AE54C14B9
-:102A2000454B7004E54A6003022ADE78B1E64401B2
-:102A3000F67C0012315222B401028003D34029E512
-:102A40006D20E108E56D20E003022ADEE56D30E04F
-:102A500004E549700BE56D30E108E54924FE5002BC
-:102A6000807F7C0012315222B402028003D3406F77
-:102A7000E54C454B60028069AC4A1231D940028076
-:102A800060E56D20E107E56D20E0028054E54970C6
-:102A90001430020990FF80E04408F0800790FF8224
-:102AA000E04408F022E56D30E1331549300215E5C8
-:102AB0004975F008A42448F582E434FFF583E04426
-:102AC00008F08013E54975F008A42408F582E43481
-:102AD000FFF583E04408F07C00123152228002802E
-:102AE00000022D98E56D20E712E5724571700CE546
-:102AF0004A700890FF00E0541F6003022D98E54CD7
-:102B000090FFFFF090FFFFE06005436D01800353ED
-:102B10006DFE7C0012315222E56D30E70EE5724504
-:102B200071600890FF00E0541F6003022D98AD4BC8
-:102B3000E54CED7D00FC7D00FCBD00028003022C15
-:102B400077B401028003D34032E54A7005E54CFCBE
-:102B50006003022C79756A407569F8756801D3E5E0
-:102B6000729412E57194004006E4FD7C128004AC7E
-:102B700072AD718C708D6F12316722B402028003C6
-:102B8000D34059E54A6003022C79E54CFC70277567
-:102B90006A527569F8756801D3E5729419E5719404
-:102BA000004006E4FD7C198004AC72AD718C708D20
-:102BB0006F1231678025756A6B7569F8756801D386
-:102BC000E5729427E57194004006E4FD7C278004BB
-:102BD000AC72AD718C708D6F12316722B4030280BC
-:102BE00006D35003022C77E54CF549700F90FF0493
-:102BF000E0FDA3E04D6003022C79801890FB02E019
-:102C0000FDA3E0FC90FF05E06C700790FF04E06D11
-:102C100060028068E4F570F56F7F00E54914C549EE
-:102C2000600FEF2400F582E434FBF583E02FFF8092
-:102C3000EA8F4AE54A2400F582E434FBF583E07D1F
-:102C400000D39572ED95714006AC72AD71800FE5C1
-:102C50004A2400F582E434FBF583E07D00FC8C70AF
-:102C60008D6FE54A2400FCE434FBFDFEECFD7F01A2
-:102C70008D6A8E698F68123167228000022D98025A
-:102C80002D98E56D30E719E5721445717012E54A2B
-:102C9000700EE54C454B700890FF00E0541F600338
-:102CA000022D98E56D20E008E56D20E103022D98E6
-:102CB000756A6EE4F569F568E4F56F04F570123134
-:102CC0006722E56D20E727E57245717021E54A70BE
-:102CD0001DE54C6402454B600DE54C14454B600608
-:102CE000E54C454B700890FF00E0541F6003022D37
-:102CF00098E56D20E008E56D20E103022D98854CF4
-:102D00006EE56E7010436D01536DFDD2B078B2E484
-:102D1000F608F68027E56E64026007E56E1460022F
-:102D20008079536DFE436D02E56E64026005E56EC9
-:102D300014700978B2E4F60804F6C2B07C001231CF
-:102D40005222E56D30E71AE5721445717013E54AB9
-:102D5000700FE54C454B700990FF00E0541F146064
-:102D6000028038E56D20E10280317C01123152226F
-:102D7000E56D20E715E5724571700FE54C454B7028
-:102D80000990FF00E0541F146002800FE56D20E100
-:102D90000280087C00123152228000023059B44077
-:102DA000028006D3500302304F90FF01E090FC35C3
-:102DB000F0E54A90FC36F0E490FC37F0E56A240335
-:102DC000F56AE5693400F569AD4BE54C856A8285A5
-:102DD0006983CDF0A3CDF090FF01E01201C02E0673
-:102DE000012E2C022E56032E80042ECE052F0B060C
-:102DF0002F31072F57082F83092FA90B2FCF0C2F07
-:102E0000DE802FDE810000303CE56D20E7067C058A
-:102E10001225E0227D527E367F0279387AFC7B01D2
-:102E2000740878001203487D087C0012254722E5CB
-:102E30006D20E7067C051225E022E54AB403004038
-:102E400010B40500500BE54A7F00FE7C10123329B8
-:102E5000227D007C0712254722E56D20E7067C05D0
-:102E60001225E022E54AB403004010B40500500BDF
-:102E7000E54A7F00FE7C11123329227D007C071277
-:102E8000254722E56D20E7067C051225E022E54A6C
-:102E9000B405028003D3400AE4FF04FE7C0A123327
-:102EA0002922B401028003D3400AE4FF04FE7C0817
-:102EB00012332922B403004010B40500500BE54A38
-:102EC0007F00FE7C13123329227D007C07122547E8
-:102ED00022E56D20E734D3E5729448E57194005003
-:102EE00006E572457170067C021225E022E54AB4BF
-:102EF0000103B3400BC3B403004009B406005004FF
-:102F00001231FF227C071225E02212257E22E56D78
-:102F100020E71DE54AB403004010B40500500BE55E
-:102F20004A7F00FE7C16123329227C071225E022FC
-:102F300012257E22E56D20E71DE54AB4030040100E
-:102F4000B40500500BE54A7F00FE7C19123329229C
-:102F50007C071225E02212257E22E56D20E72374EE
-:102F60008190FF93F0E54AB403004010B40500508F
-:102F70000BE54A7F00FE7C17123329227C071225BD
-:102F8000E02212257E22E56D20E71DE54AB403000C
-:102F90004010B40500500BE54A7F00FE7C18123348
-:102FA00029227C071225E02212257E22E56D20E7EA
-:102FB0001DE54AB403004010B40500500BE54A7FFC
-:102FC00000FE7C15123329227C071225E0221225EF
-:102FD0007E22E56D20E7067C071225E02212257E81
-:102FE00022E56D30E72090FF00E0541F701090FF45
-:102FF00001E0B48005122575800312257E227D0034
-:103000007C051225472290FF00E0541F60067C05D6
-:103010001225E022D3E5729448E5719400500BC369
-:10302000E5729407E571940050067C031225E022B6
-:10303000E54AB405041231FF227C071225E022E59F
-:103040006D30E7087D007C05122547227C0512259E
-:10305000E022B420028003D34000800012312D22F0
-:1030600075430090FF83E0540FD395434024E5431C
-:1030700024F0F582E434FEF583E0AD6AAE69AF6812
-:1030800012031805430DED70010E8D6A8E698F686D
-:1030900080D1E5437D00FCC3E5709CF570E56F9D34
-:1030A000F56FE570456F6006E490FF83F02290FFB6
-:1030B00082E04408F0E4F56F75704990FC35E0B4A7
-:1030C00005028003D3404090FC36E0F543B405028E
-:1030D0008003D3400AE4FF04FE7C0B12332922B4A0
-:1030E00001028003D3400AE4FF04FE7C0912332965
-:1030F00022B403004010B40500500BE5437F00FEEE
-:103100007C141233292222B480004023B482005060
-:103110001E7C357DFC1217A77D008C6C8D6B90FC9E
-:1031200037E0600512312D80057C001231522222D9
-:1031300090FF83E0547FF090FF82E04408F090FF1E
-:1031400080E04408F02290FF82E04408F090FF8085
-:10315000E04408F0228C237D008C708D6F756A35F9
-:103160007569FC7568011231672290FF83E0547F16
-:10317000F0E5706449456F700122C3E5709408E57D
-:103180006F94004015752108E5217D00FCC3E570B2
-:103190009CF570E56F9DF56F8009857021E4F56FF2
-:1031A000757049752200E522C395215026AD6AAE9F
-:1031B00069AF681201EFFCE52224F8F582E434FEE1
-:1031C000F583ECF005220DED70010E8D6A8E698F8E
-:1031D0006880D3E521547F90FF81F0228C487F00E6
-:1031E000EF24FD4019E4EF75F007A4247FF582E495
-:1031F00034F8F583E065487002D3220F80E28F47F0
-:10320000C32285727085716F90FF82E054F7F09051
-:10321000FF83E0547FF022C000C001C002C006C09E
-:1032200007E5782408F8860653067F7CFF1232896A
-:103230007C007D00E57B6046FF90FD95E0547F6E4D
-:10324000700FC083C082A3E0FDA3E0FCA3157B80C8
-:1032500007A3A3A3DFE68026DF06D082D083801EEB
-:10326000E0F8A3E0F9A3E0FAD082D083E8F0A3E984
-:10327000F0A3EAF0A3C083C082A3A3A380DA123331
-:1032800022D007D006D002D001D0002285A87A75BE
-:10329000A888EC70027C3F8C7922E5782408F876C7
-:1032A0000012337680FBC000C001C002C006C00718
-:1032B000AE047CFF123289E57B6042FF90FD95E011
-:1032C000547F6E700BC083C082A3A3A3157B8007BD
-:1032D000A3A3A3DFEA8026DF06D082D08380D8E0D4
-:1032E000F8A3E0F9A3E0FAD082D083E8F0A3E9F0F4
-:1032F000A3EAF0A3C083C082A3A3A380DA7808085E
-:103300007918097C01E6547F6E700676007700809C
-:103310000608090CBC08EE123322D007D006D002F2
-:10332000D001D00022757900857AA822C0F0C08231
-:10333000C083C3E57B24E8500512337680F4EC604B
-:1033400031903651E493C39C4028C0047CFF123274
-:1033500089D004430480E57B75F003A42495F582AD
-:10336000E434FDF583ECF0EFA3F0EEA3F0057B125F
-:103370003322D083D082D0F022C0047C20D28CD2E1
-:103380008DD504FDD0042275A80075880075B8009D
-:1033900075F00075D000E4F8900000F608B800FB66
-:1033A000020000C3ED940250047D037CE8ECF4FCC1
-:1033B000EDF4FD0CBC00010D8C7F8D7E22C3EC94DE
-:1033C000BCED940250047D077CD0ECF4FCEDF4FDE0
-:1033D0000CBC00010D8C7D8D7C22EC700122C000A4
-:1033E000E5782418F8A604E5782408F8C6547FF692
-:1033F000E630E703D0002212337680F4C28C857C5D
-:103400008C857D8AD28CC0E0C0D0C0F0C082C083E1
-:10341000C000C001C002C003C004C005C006C00790
-:10342000121AFAE5782408F8E66024E5782410F802
-:10343000A681E57875F021A4248DF582E434FCF5AD
-:103440008378B4E58104C398F9E6F008A3D9FA7447
-:10345000082578F8057808E65480700CE578B407FC
-:10346000F3780875780080EFE5782410F88681E518
-:103470007875F021A4248DF582E434FCF58378B4CA
-:10348000E58104C398F9E0F608A3D9FAD007D0067D
-:10349000D005D004D003D002D001D000D083D08298
-:1034A000D0F0D0D0D0E032C0E0C0D0C000C001C069
-:1034B00002C28E857E8D857F8BD28E781979097AAE
-:1034C00007E77004A600800BE6600816E67004E7C4
-:1034D0004480F70809DAEAE579601314F579700E8B
-:1034E000E5782408F87600123322D28CD28DD002EF
-:1034F000D001D000D0D0D0E0327581B3742A90FFD3
-:1035000093F0757F30757EF8757D60757CF01205DF
-:10351000411235AA12175D90FF93E04401F0B2B357
-:103520001235D412338480DA22C0007C01EC2408E6
-:10353000F8E660090CBC08F512337680EED0002264
-:10354000C0F0C082C083C000C006C007ED2410F8E0
-:1035500076C2ED75F021A4248DF582E434FCF58368
-:10356000C082C083A3A3E4780DF0A3D8FCEC547F01
-:1035700075F002A4241DF582E5F03436F583E4935A
-:10358000FE740193F5828E83E493FE740193FFD061
-:1035900083D082EFF0A3EEF0ED2408F8EC4480F63F
-:1035A000D007D006D000D083D082D0F0227578002A
-:1035B000757B007A0879187808760077000809DAB0
-:1035C000F8E478087480447FF674014410F5897536
-:1035D000B808D2ABD2A9227581B3D28ED28CD2AF29
-:1035E000E57B6032FF90FD95E05480602478087997
-:1035F00008E0547FFA7B00E6547FB502027BFF08A7
-:10360000D9F5EB700CEAF0123526AD04AC02123598
-:103610003DA3A3A3DFD212337680C57C017D0022B7
-:10362000050004F404F804EC04E804E404F004FCE9
-:1036300004A804AC04D804DC04A404A404A404E096
-:1036400004C004B804BC04B404CC04C804C404D04A
-:1036500004D404B0190103002200480200480E30CF
-:103660001420C81AD0180A0C050602030102000132
-:10367000CE0181010000C000800060003000180011
-:1036800010000800040002000100081828380C058A
-:10369000100A0200000000000301100A02000000EE
-:1036A0000000FBE0FBF209022700010200A0FA097A
-:1036B00004000003FF00000007058102400000072E
-:1036C00005010240000007058303020001220354A4
-:1036D0000055005300420033003400310030002018
-:1036E00000200020002000200020002000200000FA
-:0336F000000000D7
-:00000001FF
--- zfcpdump-kernel-4.4.orig/firmware/mts_gsm.fw.ihex
+++ /dev/null
@@ -1,867 +0,0 @@
-:1000000014360002001E021AF9FFFFFFFFFF023341
-:100010001DFFFFFFFFFFFFFFFFFFFFFFFFFF02339B
-:10002000C87581CE90FDE88583A012353CEC4D600B
-:100030007378AB8003760018B89CFA787F800376DB
-:100040000018B865FA78208003760018B820FA788E
-:10005000208003760018B81FFA90FDDDAE83AF82D2
-:1000600090FBF81200AA6005E4F0A380F690FDE88A
-:10007000A88290FDE8A982E8696005E4F20880F7AB
-:100080009001081200B390010C1200B390011012FD
-:1000900000B39001141200D190011A1200D1900106
-:1000A000201200D175D00012341A020126EF6582A9
-:1000B0007003EE658322E493F8740193F97402935C
-:1000C000FE740393F5828E83E869700122E493F64F
-:1000D000A30880F4E493FC740193FD740293FE740E
-:1000E0000393FF740493F8740593F58288831200D8
-:1000F000AA700122E493A3A883A9828C838D82F045
-:10010000A3AC83AD828883898280E32121049B8014
-:1001100080049BACAE049BFDE8049D049DFBF304AE
-:10012000A2049DFBF30502050280FED0F030F00929
-:1001300020F303F68010F7800D30F10920F303F26D
-:100140008004F38001F020F404FCD0E0CC22CCC089
-:10015000E0120163020154BC0005D0F0ACF022C3F0
-:1001600013DCFC02012ABF0009ED258275F001F8BD
-:10017000E622BF010FED2582F582EE3583F583750A
-:10018000F004E022ED258275F002F8E222D083D05F
-:1001900082F5F0C3E493A3C5F095F0C0E0C3D0F0BE
-:1001A000E493A395F04012A3A3C3E5F033500205F6
-:1001B000832582F58250020583740193C0E0E493A5
-:1001C000C0E022D083D082F5F0E4937009740193EB
-:1001D0007004A3A3800C74029365F06005A3A3A32D
-:1001E00080E7740193C0E0E493C0E022120264024D
-:1001F00001FB1202B80201FB1202DC0201FB30E03B
-:100200000720E302E622E72230E10720E302E222B0
-:10021000E32230E202E022E493221202DC02022313
-:100220001202B8020223ABF012022DCBC5F0CB2292
-:1002300030E01020E306E6F5F008E622E7F5F009E5
-:10024000E7192230E11020E306E2F5F008E222E3AC
-:10025000F5F009E3192230E206E0F5F0A3E022E42C
-:1002600093F5F074019322BB0003740922BB0107CC
-:1002700089828A83740422BB020789828A8374106C
-:1002800022740A22020284BB0007E92582F8740165
-:1002900022BB010DE92582F582EA3583F5837404DA
-:1002A00022BB020DE92582F582EA3583F5837410BD
-:1002B00022E92582F87402220202B8BF0005EDF897
-:1002C000740122BF01078D828E83740422BF02074E
-:1002D0008D828E83741022EDF87402220202DCBF3C
-:1002E0000007ED2582F8740122BF010DED2582F58E
-:1002F00082EE3583F583740422BF020DED2582F56D
-:1003000082EE3583F583741022ED2582F874022283
-:10031000020310C0E0120264020328C0E01202B817
-:10032000020328C0E01202DC02032830E00B20E3C5
-:1003300004D0E0F622D0E0F72230E10B20E304D035
-:10034000E0F222D0E0F322D0E0F022C9CDC9CACE3B
-:10035000CACBCFCB12035BEDF9EEFAEFFB22BB0069
-:100360002FBF000AFAEDF8E7F60809DAFA22BF0112
-:10037000128D828E83F802037809A3E7F0D8FA225F
-:10038000020383FAEDF8E7F20809DAFA2202038D94
-:10039000BB014DBF001489828A83F9EDF802039FE7
-:1003A00008A3E0F6D9FA220203B0BF01228D828EA3
-:1003B00083FB08C9C582C9CAC583CAE0A3C9C5826F
-:1003C000C9CAC583CAF0A3DBEAD8E8220203D38DE9
-:1003D000828E83F9EDF8E0F208A3D9FA220203DD58
-:1003E000BB024DBF001289828A83F9EDF80203EF48
-:1003F00008A3E493F6D9F922BF01238D828E83FBF3
-:1004000008C9C582C9CAC583CAE493A3C9C582C93C
-:10041000CAC583CAF0A3DBE9D8E722020422898295
-:100420008A83F9EDF8E493F208A3D9F922020433A0
-:10043000BF000DFAEDF8E3F60809DAFA2202043DEE
-:10044000BF01128D828E83F802044A09A3E3F0D81B
-:10045000FA22020455FAEDF8E3F20809DAFA220268
-:10046000045FE6FB08E6FA08E6F904F618700106F0
-:1004700022E6FF08E6FE08E6FD22EFF0A3EEF0A379
-:10048000EDF022EBF0A3EAF0A3E9F022E0FFA3E015
-:10049000FEA3E0FD22E0FBA3E0FAA3E0F9220000C6
-:1004A00000000000000502006105710026059800AB
-:1004B000330A0900610A750066154400610CF900F1
-:1004C0006109A9006109E000610DC000610BF10044
-:1004D000610A1C00610A510061173C0033174F008C
-:1004E000341E1400431EBF0044202C0044201A0078
-:1004F000471EE600471F8B004D1FDC004F1F080002
-:100500005832A800617CCC7DFF121CC52290FFFCF4
-:10051000E020E72DC2AFAE59AF58755A20E55A1406
-:10052000C55A6019E4FE7F05EE4FCE24FFCECF34CE
-:10053000FFCF6007E490FF92F080ED80E08E598F4E
-:10054000582212050A7D077CB71232C47D0F7C6EDB
-:100550001232DE789D7A06E4F608DAFC7A06120595
-:10056000CD7C03120E55122168E4FEFF7C0F12327F
-:100570004DD2A822123138E490FC38F090FFF0E020
-:1005800030E408740190FC39F08005E490FC39F007
-:100590007D0A7C001225461231BB2212313890FCB4
-:1005A00039E014700E90FFF0E04410F07C0012254A
-:1005B000DF801990FC39E0700E90FFF0E054EFF00E
-:1005C0007C001225DF80057C171225DF1231BB224B
-:1005D00090FFF0E054ABF090FFF0E04420F0228C6C
-:1005E000378D367882EDF608ECF6EDFEECFD7F01F6
-:1005F0009000051201F57880F67882E6FD08E6FCA9
-:10060000EDFEECFD7F019000041201F5540FFC7D1E
-:100610008012176D7880E6700DAD3AAE39AF38E4D0
-:100620001203187C082290FFF0E054FEF090FFF0D7
-:10063000E054FDF0801E7882E6FD08E6FCEDFEEC5D
-:10064000FD7F0190000812021725E0440190FFF39E
-:10065000F00206D97882E6FD08E6FCEDFEECFD7FAF
-:100660000190000612021754FE90FFF3F0802B78E1
-:1006700082E6FD08E6FCEDFEECFD7F01900008122D
-:100680000217FAEB90FFF1F01208C8400DAD3AAE38
-:1006900039AF38E41203187C18227882E6FD08E6A8
-:1006A000FCEDFEECFD7F0190000812021790FFF1B7
-:1006B000F01208C8400DAD3AAE39AF38E412031855
-:1006C0007C18227882E6FD08E6FCEDFEECFD7F0159
-:1006D000900006120217440190FFF3F07883E6249D
-:1006E00003F618E63400F67880E624FE500990FF01
-:1006F000F0E054FDF0800790FFF0E04402F0E49059
-:10070000FFF1F0788176007880E624FFFCE434FF86
-:10071000FD7881E67F00FEECD39EEF6480CD64809F
-:100720009D402F1208AD400F7881E6AD3AAE39AF4B
-:10073000381203187C182290FFF2E0FC788286833E
-:10074000088682ECF0788106A37882A68308A682C8
-:1007500080B51208AD400F7881E6AD3AAE39AF38BA
-:100760001203187C182290FFF2E0FC78828683083E
-:100770008682ECF07880E6AD3AAE39AF38120318D5
-:100780007C00228C378D367882EDF608ECF6EDFE93
-:10079000ECFD7F019000051201F57881F67882E684
-:1007A000FD08E6FCEDFEECFD7F019000041201F572
-:1007B000540FFC7D8112176D7881E670037C08224E
-:1007C00090FFF0E054FEF090FFF0E054FDF0801B4D
-:1007D0007882E6FD08E6FCEDFEECFD7F0190000866
-:1007E00012021725E090FFF3F0805B7882E6FD08A7
-:1007F000E6FCEDFEECFD7F0190000612021754FEB0
-:1008000090FFF3F080217882E6FD08E6FCEDFEEC37
-:10081000FD7F01900008120217FAEB90FFF1F01231
-:1008200008C840037C18227882E6FD08E6FCEDFE4D
-:10083000ECFD7F0190000812021790FFF1F0120802
-:10084000C840037C18227883E6240AF618E63400B0
-:10085000F6788076007881E624FFFCE434FFFD78AA
-:1008600080E67F00FEECD39EEF6480CD64809D40E7
-:100870002178828683088682E090FFF1F01208C812
-:1008800040037C1822788006788306E618700106FB
-:1008900080C390FFF0E04401F0788286830886826E
-:1008A000E090FFF1F01208C840037C18227C00227F
-:1008B00090FFF0E020E71290FFF0E030E50990FFB4
-:1008C000F0E04420F0C32280E7D32290FFF0E02044
-:1008D000E31290FFF0E030E50990FFF0E04420F0F3
-:1008E000C32280E7D3228C428D417C00ED54F0FD81
-:1008F000EC7003ED64307005753E038003753E04B3
-:10090000AC3E120F72758300858340E541540FF5AC
-:100910003FE5407004E53F64037035E53E24FD7516
-:10092000F00AA42402F582E434FCF583E030E60505
-:100930001210598019E53E249DF8E654FBF678A97B
-:10094000E62405F58218E63400F583740FF080592B
-:10095000E5407004E53F64047048E53E24FD75F011
-:100960000AA42402F582E434FCF583E030E507AC08
-:1009700042AD41121C5AE54230E21578ADE630E056
-:100980000F78ADE630E109E4FF04FE7C0412324D3D
-:1009900078A9E62406F58218E63400F583740FF092
-:1009A0008007E4FC7DEE121C5AC203221231381279
-:1009B0000F7278A9E62406F58218E63400F583E084
-:1009C00090FC38F078A9E62405F58218E63400F5A5
-:1009D00083E090FC39F0C2037D027C0012254612B0
-:1009E00031BB221231387895ECF6EC249DF8E630D4
-:1009F000E1077C131225DF800F90FC39E0FD78952C
-:100A0000E6FC1213EF1225DF1231BB2212313878C7
-:100A100095ECF67D00120F121225DF1231BB221267
-:100A200031387895ECF6EC249DF8E630E2077C133B
-:100A30001225DF801B7895E6249DF8E620E1077CEF
-:100A4000121225DF800A7895E6FC1214131225DFB6
-:100A50001231BB221231387895ECF6EC249DF8E681
-:100A600020E2077C111225DF800A7895E6FC12153A
-:100A7000141225DF1231BB221231387895ECF612B0
-:100A80000F7278A9E62409F58218E63400F583E0B0
-:100A900090FC3FF078A9E6240AF58218E63400F5C8
-:100AA00083E090FC40F078A9E62403F58218E63450
-:100AB00000F583E0FC78A9E62404F58218E634000A
-:100AC000F583E0F56278A9E62402F58218E63400A1
-:100AD000F583E0F5638C61E4EC333354017895F6EB
-:100AE0006008E56230E1037895067895E690FC4170
-:100AF000F078A7E62402F58218E63400F583E0FDDD
-:100B0000A3E0540CFCED54E68C65F564E56130E53A
-:100B100003436501E56220E50EE561547F7008E559
-:100B20006120E703436502E56130E303436510E5B7
-:100B30006130E203436520E561540360034365408F
-:100B4000E56130E103436580E56130E4034364011E
-:100B5000E56130E603436408E56220E40EE5615494
-:100B60007F7008E56120E7034364105365FB53641D
-:100B7000F9AD64E56590FC3ACDF0A3CDF0E56330C6
-:100B8000E30DE5635430C4540F90FC3DF08005E460
-:100B900090FC3DF0E563540390FC3CF0E5635404A5
-:100BA000C31390FC3EF090FC3CE0700E7D357EFC63
-:100BB0007F01740190000912014B78A9E62408F521
-:100BC0008218E63400F583E07C00FD78A9E624076E
-:100BD000F58218E63400F583E07F004CFEEF4D907F
-:100BE000FC38F0A3CEF0CEC2037D0A7C001225466D
-:100BF0001231BB221231387895ECF6789A760108DA
-:100C000076FC0876387897760C789A12046E120281
-:100C10001D7898CBF6CB08F67F00EF24EA401FE45E
-:100C2000EF25E090357EFD93CD04937899667003AF
-:100C3000ED186670067897760080030F80DC789652
-:100C4000EFF6789A12046E9000021202177898CB91
-:100C5000F6CB08F65404CB54064B60047897760B19
-:100C60007899E630E313789A12046E900005120129
-:100C7000F524FB50047897760D7899E654C07D00F2
-:100C800064C04D70047897760B789A12046E9000C9
-:100C9000041201F524FC50047897760F789A120418
-:100CA0006E9000061201F524FD50047897760E78B8
-:100CB0009A12046E9000091201F524FD50047897F1
-:100CC000760A7897E6702A7895E6FC120F72789A81
-:100CD00012046E78A7E6F978A6E6FA7B01740A7822
-:100CE00000120348C2037895E6FC1211157897ECC0
-:100CF000F67897E6FC1225DF1231BB2212313878E4
-:100D000095ECF6120F727895E624FD75F00AA4248E
-:100D100014F582E434FCF583AC82AD8378A6868337
-:100D2000088682ECF9EDFA7B0A78011203B0C2035F
-:100D30007895E6FC1211151231BB228D2B8C2AED11
-:100D400060407527017529487528FFE52A24FDFCB8
-:100D5000E434FFFDEC7C0325E0CD33CDDCF9FCE58C
-:100D6000292CF529E5283DF528AD29AE28AF2774B3
-:100D7000809000061203207480900002120320125B
-:100D80000FC5E52B14603B7527017529087528FFF1
-:100D9000E52A24FDFCE434FFFDEC7C0325E0CD33A3
-:100DA000CDDCF9FCE5292CF529E5283DF528AD2910
-:100DB000AE28AF27E4900006120320E49000021250
-:100DC0000320221231387895ECF6EC249DF8E630B9
-:100DD000E2097895E6FC121514D2007895E6FC122B
-:100DE0000F727896760090FC39E030E704789676BA
-:100DF000017896E6FD7895E6FC120D38C2033000C6
-:100E0000077895E6FC1214137C001225DF1231BB23
-:100E10002278A9E62404F58218E63400F583E0443C
-:100E200001F078A9E62404F58218E63400F583E0A1
-:100E300030E00280ED78A9E6240BF58218E6340054
-:100E4000F583E054F8F078A9E62402F58218E63438
-:100E500000F583E04480F022C2038C58120F7278B0
-:100E6000A6868308868279AF7A357B0A78011203D9
-:100E7000FE120E0EAC587D02120D38C203AC581291
-:100E80001115228D538E528F518C50120F72754F47
-:100E90000078A9E62405F58218E63400F583E02001
-:100EA000E41FE54F24F64019054FC2037C181232A7
-:100EB000FB90FF93E04401F0B2B3AC50120F72808C
-:100EC000D078A9E62405F58218E63400F583E02001
-:100ED000E405C2037C022278A9E62405F58218E61F
-:100EE0003400F583E0540F601678A9E62405F582F6
-:100EF00018E63400F583E0540FF0C2037C01227839
-:100F0000A88683088682E0AD53AE52AF5112031813
-:100F1000C2037C00228D318C30121514E531600F34
-:100F2000E530B4030A7C0112250E7C8112250EAC3B
-:100F300030120F72E531601A78AA8683088682E043
-:100F400054E7F0A3A3A3A3E054E7F0AC307D021272
-:100F50000D3878A6868308868279B97A357B0A7837
-:100F6000011203FEC203E530249DF8E654FDF6AC01
-:100F700030121115228C2630030512329A80F87C2B
-:100F80000A1231ADD203E52624FD78A3F670077866
-:100F9000AA76FF0876E078A3E67D007C0425E0CD04
-:100FA00033CDDCF9FC24A078A9F6ED34FF18F678EF
-:100FB000A3E675F00AA42400FCE434FCFD78A6ED59
-:100FC000F608ECF61232462278A9E62402F58218D9
-:100FD000E63400F583E030E72278A9E62402F582C2
-:100FE00018E63400F583E0547FF078A9E62402F592
-:100FF0008218E63400F583E04480F02278AA8683E4
-:10100000088682E0547FF0AD83E5822404FCE43D51
-:101010008C82F583E0547FF078A9E6240BF58218E2
-:10102000E63400F583E054F8F078ABE62401F5826D
-:1010300018E63400F583E04403F078ABE62405F5C8
-:101040008218E63400F583E04403F078A9E624052D
-:10105000F58218E63400F583740FF02278AA8683AF
-:10106000088682E0543FF0AD83E5822404FCE43D31
-:101070008C82F583E0543FF078A3E624A4F8E6FCE4
-:1010800078ABE62401F58218E63400F583ECF078BD
-:10109000A3E624A4F8E6FC78ABE62405F58218E67E
-:1010A0003400F583ECF078A9E6240BF58218E634D9
-:1010B00000F583E054FB4402F52678A7E62402F508
-:1010C0008218E63400F583E030E50343260178A971
-:1010D000E62405F58218E63400F583E030E00312DB
-:1010E0000FC5E526FC78A9E6240BF58218E6340046
-:1010F000F583ECF078A9E62405F58218E63400F5CE
-:1011000083740FF078AA8683088682E04480F0A377
-:10111000A3A3A3E04480F0228C2A120F7278A7E6E2
-:101120002408F58218E63400F583E0FC78A9E6246B
-:101130000AF58218E63400F583ECF078A7E6240778
-:10114000F58218E63400F583E0FC78A9E62409F579
-:101150008218E63400F583ECF078A6868308868250
-:10116000E0FDA3E0FCEDFE78A9E62408F58218E690
-:101170003400F583EEF0ECFE78A9E62407F582183A
-:10118000E63400F583EEF08C298D28C3EC9405ED50
-:10119000940C400575277C8033D3E5299401E5281C
-:1011A0009403400575273C8023D3E5299481E528E5
-:1011B000940140057527188013D3E5299460E5282C
-:1011C0009400400575270C8003752708AF27E4EFCE
-:1011D000547C4483FF8F27E527FC78ABE62401F598
-:1011E0008218E63400F583ECF0E527FC78ABE624C2
-:1011F00005F58218E63400F583ECF0E527FC78A3CA
-:10120000E624A4F8ECF678A9E62402F58218E63480
-:1012100000F583E0F52778A7E62402F58218E63486
-:1012200000F583A3E030E3175327C778A7E624052A
-:10123000F58218E63400F583E09035AA93422778CA
-:10124000A7E62402F58218E63400F583E030E705CE
-:1012500043274080035327BF5327FB78A7E6240684
-:10126000F58218E63400F583E06003432704532732
-:10127000FC78A7E62404F58218E63400F583E04202
-:1012800027432780E527FC78A9E62402F58218E6A3
-:101290003400F583ECF078A9E62404F58218E634EE
-:1012A00000F583E0F52778A7E62402F58218E634F6
-:1012B00000F583A3E030E1055327DF8003432720B7
-:1012C00078A7E62402F58218E63400F583E030E4DE
-:1012D000055327EF800343271078A7E62409F582FA
-:1012E00018E63400F583E0B40203432702E527FC47
-:1012F00078A9E62404F58218E63400F583ECF0784A
-:10130000A9E62403F58218E63400F583E0F5277892
-:10131000A7E62409F58218E63400F583E07005534A
-:10132000277F800343278078A7E62402F58218E60A
-:101330003400F583A3E030E00543272080035327E2
-:10134000DF78A7E62402F58218E63400F583E03062
-:10135000E30543274080035327BF78A7E62402F51F
-:101360008218E63400F583E030E00543271080035F
-:101370005327EF78A7E62402F58218E63400F583B8
-:10138000A3E030E40543270880035327F778A7E656
-:101390002402F58218E63400F583A3E030E5054326
-:1013A000270480035327FB78A7E62402F58218E67A
-:1013B0003400F583A3E030E605432701800353277B
-:1013C000FE78A7E62402F58218E63400F583A3E050
-:1013D00030E70543270280035327FDE527FC78A962
-:1013E000E62403F58218E63400F583ECF0C2037CB2
-:1013F00000228D278C26ED54031460037C1022E517
-:1014000027547C24FC40037C0B22E526249DF8E62F
-:101410004402F67C00228C30120F72E530249DF8D5
-:10142000E620E24FAC307D02120D38E53024FE4458
-:1014300028FC78AA8683088682ECF0AF83E58224B4
-:1014400004FEE43FFFEC8E828F83F07C038C2CE55E
-:101450002CFC78ABE62401F58218E63400F583EC29
-:10146000F0E52CFC78ABE62405F58218E63400F5AF
-:1014700083ECF0752D01752F48752EFFE53024FDA6
-:10148000FCE434FFFDEC7C0325E0CD33CDDCF9FC3E
-:10149000E52F2CF52FE52E3DF52E78ABE62404F54F
-:1014A0008218E63400F583E054E7F52CAD2FAE2E1C
-:1014B000AF2DE4900002120320E4900006120320F6
-:1014C0001201EF30E503432C10E52CFC78ABE62449
-:1014D00004F58218E63400F583ECF012105978A96F
-:1014E000E62406F58218E63400F583E0C203FCE545
-:1014F00030249DF8E64404F68C2CE530540FC45497
-:10150000F07E00FFEEEF44047D00FFEC4EFCED4F5B
-:10151000FD121CC57C00228C2F120F72120FF9785D
-:10152000AA8683088682E05408F0A3A3A3A3E0540C
-:1015300008F0AC2F7D02120D38C203E52F249DF870
-:10154000E654FBF67C00221231387896ECF6EC2457
-:101550009DF8E630E10A7D007C131225461231BB6E
-:101560007896E6249DF8E64401F67896E6FC120F9C
-:10157000727896E624FD75F00AA42414F582E4340A
-:10158000FCF58378A6E6FA08E6F97B0A78011203EF
-:10159000B078A6868308868279B97A357B0A780185
-:1015A0001203FE120FC5C2037896E6FC12111578DD
-:1015B00095ECF6EC600A7D007C081225461231BBE2
-:1015C0007896E6FC120F7278A9E62404F58218E6F4
-:1015D0003400F583E0441054DFFC78A9E62404F5D8
-:1015E0008218E63400F583ECF07895ECF6C2037CC3
-:1015F000C81232FB7896E6FC120F7278A9E6240432
-:10160000F58218E63400F583E054EFF0C2037CC89D
-:101610001232FB7896E6FC120F7278A9E62404F5E4
-:101620008218E63400F583E04410F0C2037CC8124F
-:1016300032FB7896E6FC120F7278A9E62404F58254
-:1016400018E63400F583E04420F0C2037CF0123247
-:10165000FB7896E6FC120F7278A9E62405F582184D
-:10166000E63400F583E030E415C2037896E64410D2
-:101670007F00FE7C0712324D1231BB02173B78A966
-:10168000E62404F58218E63400F583E054CFF0C276
-:10169000037CC81232FB7896E6FC120F7278A9E63A
-:1016A0002404F58218E63400F583E04430F0C203E8
-:1016B0007CF01232FB7896E6FC120F7278A9E624D1
-:1016C00005F58218E63400F583E030E414C20378AF
-:1016D00096E644107F00FE7C0712324D1231BB802B
-:1016E0005D78A9E62404F58218E63400F583E05419
-:1016F000EFF078A9E62404F58218E63400F583E0DB
-:1017000054DFF07896E624FD75F00AA42414F582DF
-:10171000E434FCF583AC82AD8378A68683088682A8
-:10172000ECF9EDFA7B0A78011203B0C2037896E671
-:10173000FC1211157D007C0B1225461231BB2212C2
-:101740003138E490FC39F07D027C001225461231DC
-:10175000BB221231387C001225DF1231BB22743CCF
-:1017600090FBE0F0743E90FBE0F0E490FC28F02267
-:101770008D358C34ECB401028003D340028028B450
-:1017800002028003D34008A835E625E0F68018B4AD
-:1017900004028003D3400AA835E625E025E0F68060
-:1017A00006A83576008000228C3C8D3BEDFEECFDDA
-:1017B0007F0175660675670090FC29120477120197
-:1017C000EFB480028006D3500302186E90FC2912F9
-:1017D00004899000031201F554F0B430028003D361
-:1017E000405F90FC29120489900008120217FAFD4C
-:1017F000EBFE7F0190FC2C120477EECD9035C3FCFC
-:10180000E493FF740193FEF9EFFA7B01EAFFE9FE2E
-:10181000ECC39EED9F40259035C5E493FD74019384
-:10182000FCEDFEECFD7F01EECDFC90FC2EE0D39CA8
-:1018300090FC2DE09D5005756680803312198C80D8
-:101840002EB460028003D3400BAC3CAD3B1207804A
-:101850008C66801BB41003B34010C3B42003B340A4
-:1018600009C3B440028003D34000756681800080C4
-:1018700075B481028003D3406B90FC2912048990D7
-:1018800000031201F554F0B430028003D3401D90E0
-:10189000FC29120489900008120217FAFDEBFE7F62
-:1018A0000190FC2F1204771218F68036B460028083
-:1018B00003D34013753A67E4F539F538AC3CAD3BDA
-:1018C0001205DC8C66801BB41003B34010C3B42037
-:1018D00003B34009C3B440028003D340007566815E
-:1018E000800080028000E566FC90FC29120489ECEF
-:1018F000900002120320AC672290FC291204899008
-:1019000000041201F5600474018001E4A2E0920178
-:1019100090FC29120489ED2403FD50010E90FC2C4B
-:1019200012047790FC291204899000051201F5F544
-:10193000679000041201F5540FFC7D6712176DE5E6
-:10194000677004756608227566007884760078846E
-:10195000E6C39567503890FC2F1204891201EFFC02
-:1019600090FC2C120489EC12031830010E90FC310B
-:10197000E004F090FC307003E004F078840690FC02
-:101980002EE004F090FC2D7003E004F080C0229063
-:10199000FC2AE0FDA3E0FCEDFEECFD7F01ED240A56
-:1019A000FD50010E90FC3212047790FC291204893C
-:1019B0009000041201F5540FB401028003D34017C4
-:1019C00090FC321204890DED70010E90FC2F120470
-:1019D0007778887601804EB402028003D340199054
-:1019E000FC32120489ED2402FD50010E90FC2F12EE
-:1019F000047778887602802DB404028003D34019DE
-:101A000090FC32120489ED2404FD50010E90FC2F4D
-:101A100012047778887604800CB400028003D340E7
-:101A2000007566082290FC291204899000051201B5
-:101A3000F5F567788576007885E6C39567400302FB
-:101A40001AF4788676007886E6C378889650769081
-:101A5000FC2C1204891201EFFC90FC321204921249
-:101A600001E9F45CFC1201E9F890FC2F120489E80A
-:101A7000C0E01201EFC8D0E0C8584CFC90FC2C121A
-:101A80000489EC1203187887ECF690FC31E004F03E
-:101A900090FC307003E004F009E970010A90FC3218
-:101AA00012048090FC291204899000041201F53080
-:101AB000E40E90FC2EE004F090FC2D7003E004F0A6
-:101AC00078860680817888E6FDE4FEFFEECDFC9006
-:101AD000FC31E02CF090FC30E03DF07888E6FDE44D
-:101AE000FEFFEECDFC90FC34E02CF090FC33E03DAA
-:101AF000F0788506021A347566002222C0E0C0F034
-:101B0000C082C083C0D0E8C0E0E9C0E0EAC0E0EB3A
-:101B1000C0E0ECC0E0EDC0E0EEC0E0EFC0E090FF60
-:101B200092E01201C01B47301B47321B56381B681E
-:101B30003A1B7A3E1B92441B86461B9E501BE0526A
-:101B40001BBF541C015600001C2290FF92E07F0036
-:101B5000FE7C0112324D021C32E4FF04FE7C0312B3
-:101B6000324D742090FFFEF0021C32E4FF04FE7C34
-:101B70000212324D744090FFFEF0021C32E4FF046A
-:101B8000FE7C0412324D021C32E4FF04FE7C05127E
-:101B9000324D021C32E4FF04FE7C0612324D021C60
-:101BA0003290FFA5E07D0090FBF8CDF0A3CDF09042
-:101BB000FBF9E0FCF58390FBF8E04433FD121CC513
-:101BC000807390FFB5E07D0090FBFACDF0A3CDF0DF
-:101BD00090FBFBE0FCF58390FBFAE04443FD121C14
-:101BE000C5805290FFA6E07D0090FBFCCDF0A3CD18
-:101BF000F090FBFDE0FCF58390FBFCE04434FD122B
-:101C00001CC5803190FFB6E07D0090FBFECDF0A3B7
-:101C1000CDF090FBFFE0FCF58390FBFEE04444FD3B
-:101C2000121CC5801090FF92E07D00FCED44AAFDDF
-:101C3000121CC58000E490FF92F0D0E0FFD0E0FEDF
-:101C4000D0E0FDD0E0FCD0E0FBD0E0FAD0E0F9D06D
-:101C5000E0F8D0D0D083D082D0F0D0E0320581053A
-:101C60008105810581A881181818EDF608ECF69019
-:101C7000FF5AE020E70280F790FF59E07D00A8813D
-:101C800018CDF6CD08F67D03A881E618FCE6CC2534
-:101C9000E0CC33CCDDF9CCF6CC08F6A88118E644CC
-:101CA000F8F6A881181818E6FD08E6FCA881188641
-:101CB00083088682EDF0A3ECF0740290FF5AF015D1
-:101CC0008115811581158122E5812405F581E4A81E
-:101CD0008118F6A88118181818EDF608ECF690FB94
-:101CE000F5E024F85003021DE6E4A8811818F6A8D0
-:101CF0008118E6FEA88118181818E6FD08E6FC7F92
-:101D000000EF24F8404DE4EF25E0247DF582E43433
-:101D1000FCF583E0FBA3E06C7003FAEB6D700974D3
-:101D200001A8811818F6802BE4EF25E0247DF582C8
-:101D3000E434FCF5837A00E054F0CCF8CCCDF9CD56
-:101D4000FB7800E954F0F9EA687002EB6970010E63
-:101D50000F80AEA88118EEF6A88118181818EDF6B5
-:101D600008ECF6A881EFF6A8811818E67079A8812A
-:101D700018E624F74071A88118181818E6540FA81F
-:101D800081F664046017A881E664036010A88118D6
-:101D9000181818E6FD08E6FC121C5A804A7C0A1244
-:101DA00031ADA88118181818E6FD08E6FC90FBF480
-:101DB000E025E0247DF582E434FCF583EDF0A3EC2E
-:101DC000F090FBF4E0FFE4EF045407FF90FBF4F025
-:101DD00090FBF5E004F012324690FBF6E07008E468
-:101DE000FEFF7C0F12324D802790FBF7E004F05489
-:101DF0003F701D90FBF7E044FE7D00FC90FBF4E09B
-:101E000025E0247DF582E434FCF583EDF0A3ECF0CD
-:101E1000E58124FBF58122788B7600788C7600743E
-:101E20000190FBF6F012313890FBF5E060577C0A28
-:101E30001231AD90FBF3E025E0247DF582E434FC23
-:101E4000F583E0FDA3E0FC90FBF3E025E0247DF5C5
-:101E500082E434FCF583E4F0A3F090FBF3E0FFE4CC
-:101E6000EF045407FF90FBF3F090FBF5E014F078DB
-:101E700089EDF608ECF61232467889E6FD08E6FCB4
-:101E80001208E380A312329A90FF93E04401F0B26B
-:101E9000B3788B06B60011788B7600788CE6F40464
-:101EA00004A2E092B4788CF6021E25E490FBF6F0D2
-:101EB00090FBF5E07D00FCED44CFFD121C5A123181
-:101EC000BB22123138E5706449456F601590FF837D
-:101ED000E0540F7D00D39570ED956F5005122F8162
-:101EE00080031230511231BB22123138E57064493F
-:101EF000456F600512308B800E90FF80E04408F043
-:101F000090FF83E0547FF01231BB221231388C54A1
-:101F1000EC54F0B41015756A357569FC756801E507
-:101F20006A2403F56AE5693400F569E4F557F55666
-:101F3000E556C394015027E554540FFCAD6AAE69D1
-:101F4000AF68120E808C55EC60028012056AE56A5B
-:101F5000700205690557E5577002055680D2E554B1
-:101F6000540F249DF8E654FEF6E554540F7F00FE0E
-:101F70007C1212324DE5551470097D007C09122542
-:101F8000468007AD577C001225461231BB22123124
-:101F90003890FFFCE04402F090FF00E030E713903F
-:101FA000FF83E04480F0436D8090FFFCE04401F04B
-:101FB000801190FF82E04408F0536D7F90FFFCE0B9
-:101FC00054FEF090FF81E04480F01225F990FFFE6E
-:101FD000E04405F090FFFCE054FDF01231BB22120A
-:101FE00031387C011232FB78ADE64402F674FEFC17
-:101FF00004FD121CC590FF5AE030E70280F7E4F5BB
-:102000004E754D10AC4EAD4DE54E154E7002154D52
-:10201000EC4D600280EE4387011231BB2212313851
-:102020007C021231C778ADE654FDF61231BB2212A4
-:10203000313878ADE630E02C78ADE630E12678AD89
-:10204000E6FCF58318E644F0FD121C5A90FFFCE014
-:102050004420F07C021232FB78ADE654FDF6741A8F
-:1020600090FFFEF078ADE6FCF58318E644F1FD1232
-:102070001C5A1231BB22756D0090FFFFE0600343D4
-:102080006D01756E00E4F56CF56BE4F56F757049E4
-:10209000748490FF82F0748490FF80F0748090FFCD
-:1020A00058F0748090FF5AF0AD46AF457E00EE24A4
-:1020B000FE5003022142E4EE75F007A4247FF5826E
-:1020C000E434F8F583E0FFE4EF5480FDE4EF540FCF
-:1020D00014FFED6038E4EF75F008A42448F582E4BD
-:1020E00034FFF5837490F0E4EF75F008A4244AF50A
-:1020F00082E434FFF5837480F0E4EF75F008A424E3
-:102100004EF582E434FFF5837480F08034E4EF759B
-:10211000F008A42408F582E434FFF5837490F0E419
-:10212000EF75F008A4240AF582E434FFF583E4F0A7
-:10213000E4EF75F008A4240EF582E434FFF583E49F
-:10214000F00E0220AB8D468E448F45747F90FFFDCC
-:10215000F0749090FFFCF0228C58EC24F65006E5C9
-:10216000582437FC22E5582430FC22D2B0122543F3
-:10217000EC700302227E755C03AE5B7F00E55C15AC
-:102180005C6480247F5035EF2400F582E434FBF555
-:1021900083E0FE24FE501EEF7D00FCE4FB7474C35C
-:1021A0009CFAEB9DFBEE7D00FCEAC39CED6480CBCA
-:1021B00064809B50028005EF2EFF80C18E5B8F5A9A
-:1021C000E55C6480247F500302227EE55A248E5011
-:1021D0000302227E855A5D755B00AE5AAF5B903577
-:1021E000EEE493F55CE55C155C6480247F5018EEAA
-:1021F0002400F582E434FBF583E0FCEF9035EE93A8
-:102200006C70040E0F80DE8E5A8F5BE55C64802458
-:102210007F406E755E017560E8755FFFE55D2402C5
-:10222000F55A755C07E55C334057AD60AE5FAF5E55
-:10223000E55CF5823395E0F5831201F5C4540FFC9B
-:10224000122155E55A2400F582E434FBF583ECF0C5
-:10225000055A055AAD60AE5FAF5EE55CF582339519
-:10226000E0F5831201F5540FFC122155E55A2400C4
-:10227000F582E434FBF583ECF0055A055A155C80D1
-:10228000A4740290F851F090F86B79C77A357B27E7
-:1022900078011203FE756A357569FC756801E49072
-:1022A000FF83F0748090FF81F0755902E55975F055
-:1022B00007A4247FF582E434F8F583E0788FF6FCF8
-:1022C000540F14FC788FECF6E55975F007A42481BF
-:1022D000F582E434F8F583E0789276FD0876E8FC40
-:1022E000788FE675F008A42448F582E434FFF5837E
-:1022F000E4F0788FE675F008A4244FF582E434FF0B
-:10230000F583ECF07892E6FF08E67E03CFC313CFA7
-:1023100013DEF9FE788FE675F008A42449F582E40F
-:1023200034FFF583EEF0788FE675F008A4244AF5C3
-:1023300082E434FFF5837480F07890ECF67D0078C9
-:1023400093E62CF618E63DF67892E6FD08E67C0367
-:10235000CDC313CD13DCF9FC788FE675F008A42407
-:102360004DF582E434FFF583ECF0788FE675F008E4
-:10237000A4244EF582E434FFF583E4F07892E6FD80
-:1023800008E6FC788FE6FF7E00EE24FE5003022470
-:10239000FDE4EE75F007A4247FF582E434F8F583BC
-:1023A000E0FFE4EF5480FAE4EF540F14FFE4EE751D
-:1023B000F007A42481F582E434F8F583E07890F600
-:1023C000E4EE1313548024F0F8E434FDF9E8FCE95A
-:1023D000FD8A5AEA700302246AE4EF75F008A42427
-:1023E00048F582E434FFF583E4F07890E6FAE4EF10
-:1023F00075F008A4244FF582E434FFF583EAF0ED8C
-:10240000FBEC7A03CBC313CB13DAF9FAE4EF75F0E4
-:1024100008A42449F582E434FFF583EAF07890E6D5
-:102420007B00FAEC2AFCED3BFDFBEC7A03CBC313FB
-:10243000CB13DAF9FAE4EF75F008A4244DF582E441
-:1024400034FFF583EAF0E4EF75F008A4244AF5823E
-:10245000E434FFF5837480F0E4EF75F008A4244EB3
-:10246000F582E434FFF5837480F00224F9E4EF751B
-:10247000F008A42408F582E434FFF583E4F07890B2
-:10248000E6FAE4EF75F008A4240FF582E434FFF5D2
-:1024900083EAF0EDFBEC7A03CBC313CB13DAF9FA42
-:1024A000E4EF75F008A42409F582E434FFF583EA2B
-:1024B000F07890E67B00FAEC2AFCED3BFDFBEC7A31
-:1024C00003CBC313CB13DAF9FAE4EF75F008A424B5
-:1024D0000DF582E434FFF583EAF0E4EF75F008A42B
-:1024E000240AF582E434FFF583E4F0E4EF75F008A4
-:1024F000A4240EF582E434FFF583E4F00E02238673
-:102500008E597892EDF608ECF6788FEFF61220737C
-:10251000228C26EC30E718E526540F1475F008A439
-:102520002448F582E434FFF583E054DFF08016E5BB
-:1025300026540F1475F008A42408F582E434FFF53E
-:1025400083E054DFF0227C0022EC90FC37F08C24F6
-:10255000ED2403F5257D00D39572ED95714003853B
-:102560007225E52524B75009752503740290FC37C0
-:10257000F0AC2512307622E4F56CF56B12257D2245
-:1025800090FC35E06573600E740490FC37F0E4F560
-:102590006B756C0380467D73E4FEFF79357AFC7BB6
-:1025A0000174057800120348E56C2403F56CE56BB3
-:1025B0003400F56BE56CD39572E56B95714006853B
-:1025C000726C85716BD3E56C9448E56B9400400C9C
-:1025D000740290FC37F0E4F56B756C03AC6C123050
-:1025E0007622EC90FC37F0E4F56CF56B8C32EC6005
-:1025F0000512306780057C001230762290FF93E050
-:102600004401F0B2B390FF04E0F54A90FF06E0FD0C
-:10261000A3E0ED7D00FC7D00FC90FF06E0FFA3E061
-:102620007E00FFE4FEEC4EFCED4FFDC3EC9448ED64
-:102630009400502290FF06E0FDA3E0ED7D00FC7DBC
-:1026400000FC90FF06E0FFA3E07E00FFE4FEEC4EFE
-:10265000FCED4FFD8004E4FD7C488C728D7190FF91
-:1026600002E0FDA3E0ED7D00FC7D00FC90FF02E0B8
-:10267000FFA3E07E00FFE4FEEC4EF54CED4FF54B82
-:10268000756A357569FC7568017D357EFC7F017959
-:1026900073E4FAFB74057800120348754900E549B4
-:1026A00024FE4019AD6AAE69AF68E412031805490B
-:1026B0000DED70010E8D6A8E698F6880E1756A3547
-:1026C0007569FC75680190FF00E05460B4000280F9
-:1026D00006D35003022CBFE54A540FF549E54A548E
-:1026E00080A2E0920290FF01E012018A000B2CBA56
-:1026F000270528232CBA292F2CBA2A122A462BADBB
-:102700002BB02BF02C632C91E56D30E70EE54C459A
-:102710004B7008E572640245716003022CBC90FFA7
-:1027200000E0541FB400028003D34029E54A60034F
-:10273000022820AD6AAE69AF68740112031878AD43
-:10274000E630E00BAD6AAE69AF6874021203187C24
-:102750000212307622B401028003D3401BE56D20C3
-:10276000E107E54A6003022820E54A24FE500302FF
-:1027700028207C0212307622B402028006D3500355
-:1027800002281EE56D20E10DE54A6009E54A6480F6
-:102790006003022820AC4A1230FD4003022820E5E5
-:1027A00049702530021190FF80E05408AD6AAE698F
-:1027B000AF68120318800F90FF82E05408AD6AAE34
-:1027C00069AF68120318803D154930021DE549754F
-:1027D000F008A42448F582E434FFF583E05408AD02
-:1027E0006AAE69AF68120318801BE54975F008A44A
-:1027F0002408F582E434FFF583E05408AD6AAE693D
-:10280000AF68120318AD6AAE69AF681201EF600BD2
-:10281000AD6AAE69AF6874011203187C021230769B
-:10282000228000022CBCE56D20E706E57245716050
-:1028300003022CBC90FF00E0541FB400028003D3BD
-:10284000401AE54C14454B7004E54A600302292CFC
-:1028500078ADE654FEF67C0012307622B401028098
-:1028600003D3402AE56D20E108E56D20E00302294D
-:102870002CE56D30E004E54A700BE56D30E109E5CB
-:102880004A24FE500302292C7C0012307622B40226
-:10289000028006D3500302292AE54C454B6003020F
-:1028A000292CAC4A1230FD400302292CE56D20E1B1
-:1028B00007E56D20E0028077E56D30E006E54960D0
-:1028C00002806CE549700F90FF82E054F7F090FFB2
-:1028D00080E054F7F022E549B401028003D34009B7
-:1028E0007D017C03120F128011B402028003D340D9
-:1028F000097D017C04120F1280001549300215E594
-:102900004975F008A42448F582E434FFF583E054C7
-:10291000F7F08013E54975F008A42408F582E43443
-:10292000FFF583E054F7F07C00123076228000023D
-:102930002CBCE56D20E706E57245716003022CBCF6
-:1029400090FF00E0541FB400028003D3401AE54C0E
-:1029500014454B7004E54A6003022A0F78ADE64443
-:1029600001F67C0012307622B401028003D34029A4
-:10297000E56D20E108E56D20E003022A0FE56D30EA
-:10298000E004E549700BE56D30E108E54924FE50AF
-:1029900002807F7C0012307622B402028003D34092
-:1029A0006FE54C454B60028069AC4A1230FD400235
-:1029B0008060E56D20E107E56D20E0028054E54987
-:1029C000701430020990FF80E04408F0800790FF07
-:1029D00082E04408F022E56D30E1331549300215FC
-:1029E000E54975F008A42448F582E434FFF583E056
-:1029F0004408F08013E54975F008A42408F582E442
-:102A000034FFF583E04408F07C0012307622800227
-:102A10008000022CBCE56D20E712E5724571700C58
-:102A2000E54A700890FF00E0541F6003022CBCE5EB
-:102A30004C90FFFFF090FFFFE06005436D018003C5
-:102A4000536DFE7C0012307622E56D30E70EE572A4
-:102A50004571600890FF00E0541F6003022CBCAD7C
-:102A60004BE54CED7D00FC7D00FCBD0002800302C7
-:102A70002BA8B401028003D34032E54A7005E54C2F
-:102A8000FC6003022BAA756A407569F8756801D36A
-:102A9000E5729412E57194004006E4FD7C12800416
-:102AA000AC72AD718C708D6F12308B22B4020280CB
-:102AB00003D34059E54A6003022BAAE54CFC70277A
-:102AC000756A527569F8756801D3E5729419E571F4
-:102AD00094004006E4FD7C198004AC72AD718C70EA
-:102AE0008D6F12308B8025756A6B7569F87568017A
-:102AF000D3E5729427E57194004006E4FD7C2780BD
-:102B000004AC72AD718C708D6F12308B22B40302E5
-:102B10008006D35003022BA8E54CF549700F90FFB7
-:102B200004E0FDA3E04D6003022BAA801890FB0295
-:102B3000E0FDA3E0FC90FF05E06C700790FF04E06F
-:102B40006D60028068E4F570F56F7F00E54914C59B
-:102B500049600FEF2400F582E434FBF583E02FFF9A
-:102B600080EA8F4AE54A2400F582E434FBF583E0ED
-:102B70007D00D39572ED95714006AC72AD71800FFA
-:102B8000E54A2400F582E434FBF583E07D00FC8C0B
-:102B9000708D6FE54A2400FCE434FBFDFEECFD7F04
-:102BA000018D6A8E698F6812308B228000022CBCE6
-:102BB000022CBCE56D30E719E5721445717012E521
-:102BC0004A700EE54C454B700890FF00E0541F60C2
-:102BD00003022CBCE56D20E008E56D20E103022C2A
-:102BE000BC756A6EE4F569F568E4F56F04F570127A
-:102BF000308B22E56D20E727E57245717021E54AAB
-:102C0000701DE54C6402454B600DE54C14454B606E
-:102C100006E54C454B700890FF00E0541F6003022E
-:102C20002CBCE56D20E008E56D20E103022CBC859D
-:102C30004C6EE56E700A436D01536DFDD2B080207D
-:102C4000E56E64026007E56E1460028072536DFEEB
-:102C5000436D02E56E64026005E56E147002C2B059
-:102C60007C0012307622E56D30E71AE5721445716A
-:102C70007013E54A700FE54C454B700990FF00E07A
-:102C8000541F1460028038E56D20E10280317C0120
-:102C900012307622E56D20E715E5724571700FE57B
-:102CA0004C454B700990FF00E0541F146002800FE8
-:102CB000E56D20E10280087C00123076228000025F
-:102CC0002F7DB440028006D35003022F7390FF0182
-:102CD000E090FC35F0E54A90FC36F0E490FC37F0EB
-:102CE000E56A2403F56AE5693400F569AD4BE54C06
-:102CF000856A82856983CDF0A3CDF090FF01E01253
-:102D000001C02D2A012D50022D7A032DA4042DF28D
-:102D1000052E2F062E55072E7B082EA7092ECD0B2C
-:102D20002EF30C2F02802F028100002F60E56D2012
-:102D3000E7067C051225DF227D767E357F02793815
-:102D40007AFC7B01740878001203487D087C00122D
-:102D5000254622E56D20E7067C051225DF22E54A9F
-:102D6000B403004010B40500500BE54A7F00FE7C20
-:102D70001012324D227D007C0712254622E56D207F
-:102D8000E7067C051225DF22E54AB403004010B4B3
-:102D90000500500BE54A7F00FE7C1112324D227D6A
-:102DA000007C0712254622E56D20E7067C051225EA
-:102DB000DF22E54AB405028003D3400AE4FF04FEA3
-:102DC0007C0A12324D22B401028003D3400AE4FF90
-:102DD00004FE7C0812324D22B403004010B40500FA
-:102DE000500BE54A7F00FE7C1312324D227D007CA1
-:102DF0000712254622E56D20E734D3E5729448E5B5
-:102E00007194005006E572457170067C021225DF50
-:102E100022E54AB40103B3400BC3B403004009B434
-:102E200006005004123123227C071225DF221225CE
-:102E30007D22E56D20E71DE54AB403004010B4058E
-:102E400000500BE54A7F00FE7C1612324D227C07B3
-:102E50001225DF2212257D22E56D20E71DE54AB40B
-:102E600003004010B40500500BE54A7F00FE7C19BA
-:102E700012324D227C071225DF2212257D22E56DBC
-:102E800020E723748190FF93F0E54AB403004010DB
-:102E9000B40500500BE54A7F00FE7C1712324D222C
-:102EA0007C071225DF2212257D22E56D20E71DE536
-:102EB0004AB403004010B40500500BE54A7F00FE01
-:102EC0007C1812324D227C071225DF2212257D222A
-:102ED000E56D20E71DE54AB403004010B40500503D
-:102EE0000BE54A7F00FE7C1512324D227C0712252D
-:102EF000DF2212257D22E56D20E7067C071225DF03
-:102F00002212257D22E56D30E72090FF00E0541F5E
-:102F1000701090FF01E0B480051225748003122523
-:102F20007D227D007C051225462290FF00E0541F83
-:102F300060067C051225DF22D3E5729448E5719482
-:102F400000500BC3E5729407E571940050067C03B2
-:102F50001225DF22E54AB40504123123227C071230
-:102F600025DF22E56D30E7087D007C05122546222D
-:102F70007C051225DF22B420028003D340008000AC
-:102F80001230512275430090FF83E0540FD39543D4
-:102F90004024E54324F0F582E434FEF583E0AD6A95
-:102FA000AE69AF6812031805430DED70010E8D6A0E
-:102FB0008E698F6880D1E5437D00FCC3E5709CF588
-:102FC00070E56F9DF56FE570456F6006E490FF83D7
-:102FD000F02290FF82E04408F0E4F56F75704990AC
-:102FE000FC35E0B405028003D3404090FC36E0F5A8
-:102FF00043B405028003D3400AE4FF04FE7C0B12B5
-:10300000324D22B401028003D3400AE4FF04FE7C67
-:103010000912324D22B403004010B40500500BE5F4
-:10302000437F00FE7C1412324D2222B480004023E4
-:10303000B48200501E7C357DFC1217A57D008C6C7F
-:103040008D6B90FC37E0600512305180057C0012DA
-:103050003076222290FF83E0547FF090FF82E0449C
-:1030600008F090FF80E04408F02290FF82E04408DE
-:10307000F090FF80E04408F0228C237D008C708D5E
-:103080006F756A357569FC75680112308B2290FF87
-:1030900083E0547FF0E5706449456F700122C3E519
-:1030A000709408E56F94004015752108E5217D00B6
-:1030B000FCC3E5709CF570E56F9DF56F8009857028
-:1030C00021E4F56F757049752200E522C395215002
-:1030D00026AD6AAE69AF681201EFFCE52224F8F56F
-:1030E00082E434FEF583ECF005220DED70010E8DC7
-:1030F0006A8E698F6880D3E521547F90FF81F0222A
-:103100008C487F00EF24FD4019E4EF75F007A424FC
-:103110007FF582E434F8F583E065487002D3220F2E
-:1031200080E28F47C32285727085716F90FF82E0C5
-:1031300054F7F090FF83E0547FF022C000C001C03C
-:1031400002C006C007E5782408F8860653067F7C8F
-:10315000FF1231AD7C007D00E57B6046FF90FD9560
-:10316000E0547F6E700FC083C082A3E0FDA3E0FC3B
-:10317000A3157B8007A3A3A3DFE68026DF06D0820A
-:10318000D083801EE0F8A3E0F9A3E0FAD082D083D8
-:10319000E8F0A3E9F0A3EAF0A3C083C082A3A3A34D
-:1031A00080DA123246D007D006D002D001D00022F9
-:1031B00085A87A75A888EC70027C3F8C7922E57826
-:1031C0002408F8760012329A80FBC000C001C002C9
-:1031D000C006C007AE047CFF1231ADE57B6042FF44
-:1031E00090FD95E0547F6E700BC083C082A3A3A3B3
-:1031F000157B8007A3A3A3DFEA8026DF06D082D059
-:103200008380D8E0F8A3E0F9A3E0FAD082D083E885
-:10321000F0A3E9F0A3EAF0A3C083C082A3A3A38034
-:10322000DA7808087918097C01E6547F6E70067612
-:10323000007700800608090CBC08EE123246D00761
-:10324000D006D002D001D00022757900857AA8225C
-:10325000C0F0C082C083C3E57B24E8500512329AD7
-:1032600080F4EC6031903575E493C39C4028C00431
-:103270007CFF1231ADD004430480E57B75F003A4DC
-:103280002495F582E434FDF583ECF0EFA3F0EEA392
-:10329000F0057B123246D083D082D0F022C0047C6D
-:1032A00020D28CD28DD504FDD0042275A80075885B
-:1032B0000075B80075F00075D000E4F8900000F6D5
-:1032C00008B800FB020000C3ED940250047D037CAB
-:1032D000E8ECF4FCEDF4FD0CBC00010D8C7F8D7E60
-:1032E00022C3EC94BCED940250047D077CD0ECF436
-:1032F000FCEDF4FD0CBC00010D8C7D8D7C22EC708E
-:103300000122C000E5782418F8A604E5782408F81E
-:10331000C6547FF6E630E703D0002212329A80F4DA
-:10332000C28C857C8C857D8AD28CC0E0C0D0C0F0F8
-:10333000C082C083C000C001C002C003C004C00579
-:10334000C006C007121AF8E5782408F8E66024E5FC
-:10335000782410F8A681E57875F021A4248DF582F3
-:10336000E434FCF58378AEE58104C398F9E6F0080F
-:10337000A3D9FA74082578F8057808E65480700C0B
-:10338000E578B407F3780875780080EFE5782410C5
-:10339000F88681E57875F021A4248DF582E434FC6B
-:1033A000F58378AEE58104C398F9E0F608A3D9FA6D
-:1033B000D007D006D005D004D003D002D001D00071
-:1033C000D083D082D0F0D0D0D0E032C0E0C0D0C026
-:1033D00000C001C002C28E857E8D857F8BD28E7823
-:1033E0001979097A07E77004A600800BE6600816D1
-:1033F000E67004E74480F70809DAEAE57960131417
-:10340000F579700EE5782408F87600123246D28CF1
-:10341000D28DD002D001D000D0D0D0E0327581ADB5
-:10342000742A90FF93F0757F30757EF8757D607516
-:103430007CF012053F1234CE12175B90FF93E044EC
-:1034400001F0B2B31234F81232A880DA22C0007C44
-:1034500001EC2408F8E660090CBC08F512329A80E9
-:10346000EED00022C0F0C082C083C000C006C007FA
-:10347000ED2410F876BCED75F021A4248DF582E4DE
-:1034800034FCF583C082C083A3A3E4780DF0A3D8F5
-:10349000FCEC547F75F002A42441F582E5F034354C
-:1034A000F583E493FE740193F5828E83E493FE74B6
-:1034B0000193FFD083D082EFF0A3EEF0ED2408F863
-:1034C000EC4480F6D007D006D000D083D082D0F074
-:1034D00022757800757B007A08791878087600776D
-:1034E000000809DAF8E478087480447FF67401442F
-:1034F00010F58975B808D2ABD2A9227581ADD28EEC
-:10350000D28CD2AFE57B6032FF90FD95E0548060B5
-:103510002478087908E0547FFA7B00E6547FB502EE
-:10352000027BFF08D9F5EB700CEAF012344AAD04C7
-:10353000AC02123461A3A3A3DFD212329A80C57CFD
-:10354000017D002204FE04F204F604EA04E604E22B
-:1035500004EE04FA04A604AA04D604DA04A204A21F
-:1035600004A204DE04BE04B604BA04B204CA04C64B
-:1035700004C204CE04D204AE1901030022004802A2
-:1035800000480E301420C81AD0180A0C0506020391
-:1035900001020001CE0181010000C0008000600036
-:1035A0003000180010000800040002000100081894
-:1035B00028380C05100A0200000000000301100A60
-:1035C000020000000000FBE0FBF2090227000102FC
-:1035D00000A0FA0904000003FF00000007058102B3
-:1035E00040000007050102400000070583030200B8
-:1035F00001220354005500530042003300340031CF
-:1036000000300020002000200020002000200020AA
-:073610000020000000000093
-:00000001FF
--- zfcpdump-kernel-4.4.orig/firmware/myricom/lanai.bin.ihex
+++ /dev/null
@@ -1,4771 +0,0 @@
-:100000004FF8F20EFE00C290000007880008E001E1
-:10001000014C9793FFFCE000001400000001000079
-:1000200000009293FFFC02900008F7062A6C9713D9
-:10003000FFFCF7062C109713FFFC07880008E00070
-:1000400015489793FFFCF702053C9713FFFCF70256
-:1000500000039713FFFCF70629E09713FFFC0788BE
-:100060000008E000161C9793FFFCF7062B849713FB
-:10007000FFFCF7062C1C9713FFFC07880008E00024
-:1000800015489793FFFCF7020ABC9713FFFCF70291
-:1000900000029713FFFCF7062AF89713FFFC078866
-:1000A0000008E000161C9793FFFC8796FFFC8296E1
-:1000B000FFF802140000013C0000000000019293D0
-:1000C000FFFC02900008F7044A9C85160000203AC5
-:1000D0000001EE00010100000001F70475EC0000D2
-:1000E0000001203A0000E600010000000001F704D2
-:1000F00075F000000001203A0000E600012D00002C
-:100100000001F7042D38F6862C2806380001F60584
-:100110002D3877390002F482001220320044E600C4
-:1001200001E0B4BA6802E00001E0F0052D38F70400
-:100130003B64F5844F54F7057A10202E0000E6004A
-:100140000199972A002095AA001CF6064A9826AC29
-:10015000000177350001C738680077390002073899
-:10016000000CA4BA60020000000194AA0010C73875
-:100170006000873A000400000001972A0014F70489
-:100180004A9C0000000127380001C02E7200D700F1
-:100190000A01E00001D0F7057A1895AA001CF606BE
-:1001A0004A9806AC000177350001C73868007739F6
-:1001B00000020738000CA4BA60020000000194AAF3
-:1001C0000010C7386000873A0004F0057A18972AB3
-:1001D0000014F50579D807880008E00001F497932A
-:1001E000FFFC8796FFFC8296FFF802140004013C96
-:1001F0000000000000019293FFFC02900008221012
-:100200000038F7047A10F6843B6400000001C03A1D
-:100210006A00470C0001D7000A70203A0000E6008F
-:10022000024C00000001F70475EC00000001203AC8
-:100230000000E600024C00000001F70475F0000029
-:100240000001203A0000E6000285F4820000F70475
-:100250002D38F6862C2806380001F6052D3877391A
-:100260000002F302001220320044E6000274B33AA6
-:100270006802F0052D38F3062A6CF3052C10E00017
-:100280000528F0057A18F38479D8F6844AA0231457
-:1002900000209316FFC4841E00109696FFD4F70426
-:1002A0004A9C9416FFE0851E0014C0367200EC00D4
-:1002B000036C9516FFE477350001C738680077397D
-:1002C0000002F3064A98C6B8300006B4000CC58494
-:1002D00000008736000000000001C03A4200E6003E
-:1002E00002FCC62400008736000400000001C03A6A
-:1002F0005200E600030020320000F6020001203226
-:100300000000E600030D00000001F58200008636C3
-:1003100000008716FFE000000001C0327200E2001A
-:100320000348F5020000C0327200E6000350202AA4
-:10033000000086B600048716FFE400000001C03606
-:100340007200E2000351202A0000F5020001202A79
-:100350000000E6000361202E0000F5820001202E3F
-:100360000000E600037020260000F4820001202631
-:100370000000E60003A5F60200018716FFD4F3068D
-:100380004A9876B90001C6B4700076B50002C6B4CA
-:10039000300006B4001486B600009716FFD8E000BF
-:1003A00004189696FFDC2714002C9713FFFC831685
-:1003B000FFC4000000019313FFFCF3064A98931357
-:1003C000FFFC9396FFCC07880008E001256897930F
-:1003D000FFFC8396FFCC20220000E6000415F60205
-:1003E00000018716FFD4F3064A9876B90001C6B417
-:1003F000700076B50002C6B4300006B4001486B6AC
-:1004000000009716FFD89696FFDCF7054AA0E0009B
-:10041000041C20320000F602000020320000E6003A
-:10042000042CF4820001E0000484F482000086962B
-:10043000FFD80000000177350002C738680077391F
-:100440000002F68642C8A63A6802C73868007539C5
-:10045000001E7528FFE505B8000286AE00000738CB
-:1004600000049716FFECC63057C07630FFF09616A2
-:10047000FFF475AD001E75ACFFE5C6B45FC076B481
-:10048000FFF09696FFF020260000E6000525F30613
-:1004900029E08696FFF0F5820000C7346800C49C0E
-:1004A0007200C02E6A00EC0004F0C5240000C62CC7
-:1004B00000008716FFEC00000001A6B2700205AC38
-:1004C0000001C73070007739001E7738FFE5C6B4E9
-:1004D00077C076B4FFF0F6AB280005280002871637
-:1004E000FFF000000001C02E7200EC0004B10630E5
-:1004F0000002F3020003F30576F48716FFF0869EF0
-:100500000004C7387000C7384800C6B470008716AA
-:10051000FFF406B400209702FF6C9482FF5096828D
-:10052000FF58F30629E0F3052C108796FFFC82960E
-:10053000FFF802140000013C00000000000192934B
-:10054000FFFC02900008F7047A1800000001203A2E
-:100550000000E60005CD00000001F7047A10F684E3
-:100560003B6400000001C03A6A00470C0001203AD9
-:100570000000E60005CDF5864A98F60479D8F684A1
-:100580004F540000000196B2001C06B400017735FC
-:100590000001C7386800773900020738000CA53A17
-:1005A00058020000000195320010C7385800873A01
-:1005B0000004F0057A189732001407880008E0005C
-:1005C00001F49793FFFCE00005FC00000001F70434
-:1005D0002D38F6862C2806380001F6052D38773997
-:1005E0000002F502001220320044E60005F4B53A9C
-:1005F0006802F0052D38F5062A6CF5052C10879653
-:10060000FFFC8296FFF802140000013C000000008D
-:1006100000019293FFFC0290000885960000F70409
-:1006200075EC852E0020203A0000E60006CCF5058A
-:100630007A08F70475F000000001203A0000E60097
-:1006400006CC00000001F7047A08F6843B64000041
-:100650000001C03A6A00470C0001D7000A70203A36
-:100660000000E60006CC00000001872E001CF68486
-:100670004F54F7057A00C7347200203A0000EE00AC
-:10068000068DF5020001E0000690F50579F8F08589
-:1006900079F8F6847A00C7387000C6B47000F704A1
-:1006A00079F8F68579E8C7387000C6347000F70429
-:1006B0004A9C00000001C0367200EC0006CCF60532
-:1006C00079F020360000EC0006F800000001F70485
-:1006D0002D38F6862C2806380001F6052D38773996
-:1006E0000002F502001320320044E6000738B53A54
-:1006F0006802E0000738F0052D38F7044A9C000036
-:100700000001C0327200EE00071900000001F7047A
-:100710004A9CE0000728F70579F020320000EC0041
-:10072000072800000001F08579F0F58579E0078859
-:100730000008E000074C9793FFFC8796FFFC829629
-:10074000FFF802140004013C000000000001929335
-:10075000FFFC0290000822100038F70475EC00003E
-:100760000001203A0000E60007A400000001F704A1
-:1007700075F000000001203A0000E60007A4000028
-:100780000001F7047A08F6843B6400000001C03AD7
-:100790006A00470C0001D7000A70203A0000E6000A
-:1007A00007D5F4020000F7042D38F6862C28063809
-:1007B0000001F6052D3877390002F30200132032CC
-:1007C0000044E60007CCB33A6802F0052D38E0009B
-:1007D0000AA4F3062B84F68479E8F6064A9877355E
-:1007E0000001C738680077390002F68479E00738DD
-:1007F000000CA33A6002C3B4000093360010C7385F
-:100800006000873A0004231400209316FFC4973633
-:100810000014849E0010F6844AA09496FFE09696F9
-:10082000FFD4851E0014F7044A9C00000001C03666
-:100830007200EC0008EC9516FFE477350001C7382C
-:10084000680077390002C6B8600006B4000CC584A1
-:1008500000008736000000000001C03A4A00E600B0
-:10086000087CC62000008736000400000001C03A62
-:100870005200E600088020320000F602000120321B
-:100880000000E600088D00000001F58200008636B9
-:1008900000008716FFE000000001C0327200E20095
-:1008A00008C8F5020000C0327200E60008D0202A15
-:1008B000000086B600048716FFE400000001C03681
-:1008C0007200E20008D1202A0000F5020001202A6F
-:1008D0000000E60008E1202E0000F5820001202E35
-:1008E0000000E60008F020220000F40200012022AF
-:1008F0000000E6000925F60200018716FFD4F30682
-:100900004A9876B90001C6B4700076B50002C6B444
-:10091000300006B4001486B600009716FFD8E00039
-:1009200009989696FFDC2714002C9713FFFC83167A
-:10093000FFC4000000019313FFFCF3064A989313D1
-:10094000FFFC9396FFCC07880008E0012568979389
-:10095000FFFC8396FFCC20220000E6000995F602FA
-:1009600000018716FFD4F3064A9876B90001C6B491
-:10097000700076B50002C6B4300006B4001486B626
-:1009800000009716FFD89696FFDCF7054AA0E00016
-:10099000099C20320000F602000020320000E60030
-:1009A00009ACF4820001E0000A04F482000086969B
-:1009B000FFD80000000177350002C738680077399A
-:1009C0000002F68642C8A63A6802C7386800753940
-:1009D000001E7528FFE505B8000286AE0000073846
-:1009E00000049716FFECC63057C07630FFF096161D
-:1009F000FFF475AD001E75ACFFE5C6B45FC076B4FC
-:100A0000FFF09696FFF020260000E6000AA5F30608
-:100A10002AF88696FFF0F5820000C7346800C49C6F
-:100A20007200C02E6A00EC000A70C5240000C62CBB
-:100A300000008716FFEC00000001A6B2700205ACB2
-:100A40000001C73070007739001E7738FFE5C6B463
-:100A500077C076B4FFF0F6AB2800052800028716B1
-:100A6000FFF000000001C02E7200EC000A310630D9
-:100A70000002F3020002F30576F48716FFF0869E6B
-:100A80000004C7387000C7384800C6B47000871625
-:100A9000FFF406B400209702FF6C9482FF50968208
-:100AA000FF58F3062AF8F3052C1C8796FFFC829664
-:100AB000FFF802140000013C0000000000019293C6
-:100AC000FFFC02900008F68479E8F70479F800004A
-:100AD0000001C6B47000F7047A20F68579E807387B
-:100AE0000001F7057A20F70479F0F6047A20C03681
-:100AF0007200E6000B2CF6862C28F7042D38000037
-:100B0000000106380001F6052D3877390002F5821C
-:100B1000001320320044E6000B20B5BA6802F0054D
-:100B20002D38F5862B84E0000B38F5852C1C0788C2
-:100B30000008E000074C9793FFFC8796FFFC829625
-:100B4000FFF802140000013C000000000001929335
-:100B5000FFFC02900008F7062C109713FFFCF70625
-:100B600029E09713FFFC07880008E00014F497932E
-:100B7000FFFCF7062C109713FFFCF7062A6C97135F
-:100B8000FFFC07880008E00014F49793FFFCF706C9
-:100B90002C1C9713FFFCF7062AF89713FFFC078815
-:100BA0000008E00014F49793FFFCF7062C1C971341
-:100BB000FFFCF7062B849713FFFC07880008E00072
-:100BC00014F49793FFFC8796FFFC8296FFF80214BB
-:100BD0000000013C0000000000019293FFFC029025
-:100BE0000008F0052D38F0052D3C8796FFFC829615
-:100BF000FFF802140000013C000000000001929385
-:100C0000FFFC0290000822100018FF852EDCF7067A
-:100C10000C3EC77C7400203A0000E60014299716A9
-:100C2000FFF44738FFFBF6846F50CFB8000083967F
-:100C3000FFF4F702003FC39C6D80C71C7400203A8C
-:100C4000003FE20012609396FFF477390002F682CB
-:100C50000C5CA6B6700200000001C1340000000068
-:100C600012600000126000000D6800000D680000B6
-:100C70000D5C00000D5C00000D6800000D680000B8
-:100C80001250000012500000123C0000123C000004
-:100C90000DE000000DE00000123C0000123C0000DE
-:100CA0000DE800000DF400000E0000000E20000012
-:100CB0000E4000000E6000000E8000000EA000003C
-:100CC0000EC000000EC800000ED000001228000068
-:100CD0000ED800000EF400000F10000012280000D3
-:100CE0000F1800000F1800000F2400000F24000050
-:100CF0000F4400000F4400000F6400000F64000068
-:100D00000F8400000F8400000F8C00000F8C000087
-:100D10000F9400000F9400000FB000000FB000000F
-:100D20000FB800000FD800000FF80000102C0000D2
-:100D3000106000001094000010C8000010FC0000BB
-:100D400011300000114C0000116800001214000066
-:100D50001184000011B4000011E400001214F382A9
-:100D60000006E00012549393FFFCF60200052032C7
-:100D70000014E6000DB527000010203A0001E20043
-:100D80000DB5F7062DCCF6842ECC0000000175B50C
-:100D90000002B62E700206B40001F6852ECC860243
-:100DA000FF34F7062E4C2036001FE2000DB5B62E9C
-:100DB0007002F0052ECCF7042D5800000001873A90
-:100DC000000000000001873A0018000000010788B9
-:100DD0000008C13800009793FFFCE000126000009B
-:100DE0000001E0001240F3820006F382000BE000F5
-:100DF00012549393FFFCF3820007E0001254939384
-:100E0000FFFCF382000B9393FFFC07880008E000CF
-:100E100015849793FFFCF3820005E000125493932E
-:100E2000FFFCF38200079393FFFC07880008E000B3
-:100E300015849793FFFCF3820005E000125493930E
-:100E4000FFFCF382000B9393FFFC07880008E0008F
-:100E500015849793FFFCF3820006E00012549393ED
-:100E6000FFFCF38200079393FFFC07880008E00073
-:100E700015849793FFFCF3820006E00012549393CD
-:100E8000FFFCF382000B9393FFFC07880008E0004F
-:100E900015849793FFFCF3820005E00012549393AE
-:100EA000FFFCF38200079393FFFC07880008E00033
-:100EB00015849793FFFCF3820005E000125493938E
-:100EC000FFFCE0001240F382000BE0001240F382CE
-:100ED0000007E000122CF382000BF382000B9393C7
-:100EE000FFFC07880008E00015849793FFFCE000F2
-:100EF0001240F3820006F38200079393FFFC0788F9
-:100F00000008E00015849793FFFCE0001240F38294
-:100F10000006E000122CF382000BF3820014E000C4
-:100F200012549393FFFCF38200149393FFFC078801
-:100F30000008E00015849793FFFCF3820005E000B1
-:100F400012549393FFFCF38200149393FFFC0788E1
-:100F50000008E00015849793FFFCF3820006E00090
-:100F600012549393FFFCF38200149393FFFC0788C1
-:100F70000008E00015849793FFFCF3820005E00071
-:100F800012549393FFFCE0001240F3820014E0003F
-:100F9000122CF3820014F38200149393FFFC078851
-:100FA0000008E00015849793FFFCE0001240F382F4
-:100FB0000006E000122CF3820014F38200149393D5
-:100FC000FFFC07880008E00015849793FFFCF3827C
-:100FD000000BE00012549393FFFCF38200149393F0
-:100FE000FFFC07880008E00015849793FFFCF3825C
-:100FF0000007E00012549393FFFCF38200149393D4
-:10100000FFFC07880008E00015849793FFFCF3823B
-:10101000000B9393FFFC07880008E000158497936A
-:10102000FFFCF3820005E00012549393FFFCF3826F
-:1010300000149393FFFC07880008E0001584979341
-:10104000FFFCF38200079393FFFC07880008E00091
-:1010500015849793FFFCF3820005E00012549393EC
-:10106000FFFCF38200149393FFFC07880008E00064
-:1010700015849793FFFCF382000B9393FFFC078882
-:101080000008E00015849793FFFCF3820006E0005F
-:1010900012549393FFFCF38200149393FFFC078890
-:1010A0000008E00015849793FFFCF38200079393F8
-:1010B000FFFC07880008E00015849793FFFCF3828B
-:1010C0000006E00012549393FFFCF3820014939304
-:1010D000FFFC07880008E00015849793FFFCF3826B
-:1010E000000B9393FFFC07880008E000158497939A
-:1010F000FFFCF3820005E00012549393FFFCF3829F
-:1011000000149393FFFC07880008E0001584979370
-:10111000FFFCF38200079393FFFC07880008E000C0
-:1011200015849793FFFCF3820005E000125493931B
-:10113000FFFCF38200149393FFFC07880008E00093
-:1011400015849793FFFCE0001240F382000BF382BA
-:1011500000149393FFFC07880008E0001584979320
-:10116000FFFCE0001240F3820007F3820014939327
-:10117000FFFC07880008E00015849793FFFCE0005F
-:10118000122CF382000BF38200149393FFFC078868
-:101190000008E00015849793FFFCF382000B939303
-:1011A000FFFC07880008E00015849793FFFCE0002F
-:1011B0001240F3820006F38200149393FFFC078829
-:1011C0000008E00015849793FFFCF38200079393D7
-:1011D000FFFC07880008E00015849793FFFCE000FF
-:1011E0001240F3820006F38200149393FFFC0788F9
-:1011F0000008E00015849793FFFCE000122CF382B6
-:10120000000BF7043528F682000107380008E000DB
-:1012100013CCF7053544F38200149393FFFC078841
-:101220000008E00015849793FFFCF3820007939376
-:10123000FFFC07880008E00015849793FFFCF38209
-:1012400000059393FFFC07880008E000158497933E
-:10125000FFFC9013FFFC07880008E00015849793BB
-:10126000FFFC8396FFF400000001779C0014703EA1
-:10127000FFE1E600129DF7060400F7046F5C000032
-:10128000000107380001F7056F5CF7046F5CE000B0
-:101290000000000000018396FFF4F7060400C01E62
-:1012A0007400E600142900000001F7042ED0F68433
-:1012B00035240738000120360000E6001405F70544
-:1012C0002ED0F704E01400000001203A0000E600F0
-:1012D0001405F6820000F685E014F7042ED8C53414
-:1012E000000007380001F7052ED8202A0002EE0082
-:1012F00013CCF6820000F684352800000001873602
-:10130000000000000001203A0002E60013A005B42E
-:1013100000089593FFFC9516FFE89596FFE49696D6
-:10132000FFE007880008E00016649793FFFC85162D
-:10133000FFE88596FFE48696FFE020220000E600A5
-:101340001390F70200008636000C000000012032E6
-:10135000000FE20013750000000187360014000042
-:101360000001073800019736001487360014E000AA
-:101370001390F702000076B10002C6B46000773522
-:101380000005C7386A00C738600007380010C72C4E
-:101390007000203A0000E6001200F705352CF684B4
-:1013A0003528F7046F4C00000001C0367200E600DB
-:1013B00013C007341494F3846F44E00013C4F3851E
-:1013C0003528F7053528E00012E805280001203609
-:1013D0000000E6001429F6862C28F7042D38F005C5
-:1013E000352406380001F6052D3877390002F382DE
-:1013F000000D20320044E6001428B3BA6802E00071
-:101400001428F0052D38F704E01000000001203A00
-:101410000000E6001429F7020000F705E010078835
-:101420000008E00102989793FFFCF4842D38F7043C
-:101430002D3C00000001C03A4A00E6000C09F68687
-:101440002C2877390002A53A680200000001202A02
-:101450000014E600149127280015203A0001E2004C
-:101460001491F7062DCCF6842ECC8602FF3475B588
-:101470000002B52E700206B40001F6852ECCF706E8
-:101480002E4C2036001FE2001491B62E7002F0059B
-:101490002ECCF7062D4476A90002A7367002000074
-:1014A0000001873A000000000001C6B470008736D2
-:1014B00000049496FFEC07880008C1380000979359
-:1014C000FFFCF7042D3C8496FFEC07380001203A1E
-:1014D0000044E600142CF7052D3CE000142CF00528
-:1014E0002D3C8796FFFC8296FFF802140000013C19
-:1014F0000000000000019293FFFC02900008841697
-:101500000000F702000085960004203A0021EE005A
-:10151000153495A20000F606233807200084C6A0E3
-:101520000000963A000427380004C03A6A00EC0034
-:101530001520000000018796FFFC8296FFF8021438
-:101540000008013C0000000000019293FFFC0290A3
-:1015500000088696000087160004F6042D40973692
-:1015600000009736000407300001F7052D4096363D
-:1015700000088796FFFC8296FFF802140008013CE1
-:101580000000000000019293FFFC02900008851605
-:10159000000000000001202A0014E60015D92728C9
-:1015A0000015203A0001E20015D9F7062DCCF6848B
-:1015B0002ECC8602FF3475B50002B52E700206B43B
-:1015C0000001F6852ECCF7062E4C2036001FE200D7
-:1015D00015D9B62E7002F0052ECCF6862D4477294B
-:1015E0000002A6BA68020000000186B600000000F2
-:1015F0000001C7386800873A00040000000107882E
-:101600000008C13800009793FFFC8796FFFC829684
-:10161000FFF802140004013C000000000001929356
-:10162000FFFC029000088716000086960004F6066C
-:101630002D4476B5000285BA000000000001B5B661
-:101640006002C6B47000859600080000000195B6DF
-:1016500000048796FFFC8296FFF80214000C013C00
-:101660000000000000019293FFFC02900008861623
-:101670000000000000018732000400000001203A51
-:10168000000F86B20000C5380000EE0016B4C5B4E5
-:1016900000002036000FEE0016B400000001203AD2
-:1016A0000000EC0016B50000000120360000EC0040
-:1016B00016D0000000018732000C0000000107383E
-:1016C00000019732000C8732000CE00016D8F402BB
-:1016D0000000C02A5A00440C00018796FFFC829645
-:1016E000FFF802140004013C0000000000010000AB
-:1016F00000009293FFFC02900008F7062EE097137B
-:10170000FFFCF70632D49713FFFC07880008E000BF
-:1017100015489793FFFCF702182C9713FFFCF782EC
-:1017200000099793FFFCF7062EE09713FFFC07884C
-:101730000008E000161C9793FFFCF702345897133B
-:10174000FFFCF702000C9713FFFCF7062F6C9713B2
-:10175000FFFC07880008E000161C9793FFFCF702C7
-:101760003F949713FFFCF782000B9793FFFCF7065B
-:101770002FF89713FFFC07880008E000161C9793CA
-:10178000FFFCF7023B849713FFFCF782000B979353
-:10179000FFFCF70632289713FFFC07880008E000DB
-:1017A000161C9793FFFCF70226E49713FFFCF70241
-:1017B00000139713FFFCF70630849713FFFC07888C
-:1017C0000008E000161C9793FFFCF70226A0971371
-:1017D000FFFCF70200119713FFFCF7063110971377
-:1017E000FFFC07880008E000161C9793FFFCF70237
-:1017F000182C9713FFFCF78200099793FFFCF7065C
-:10180000319C9713FFFC07880008E000161C979393
-:10181000FFFCF0057A78F00532E88796FFFC8296A7
-:10182000FFF802140000013C000000000001929348
-:10183000FFFC0290000822100050F70471C800005D
-:101840000001203A0000E6001855F68671C4E00059
-:10185000186CF6020000F70471D40000000177391B
-:101860000002C7386800863A001800000001F6053B
-:1018700032C486B2000807018000C5B47400F58543
-:1018800032D087320018F6866F4477390002A73AC3
-:101890006802202E0000F70532C0073809D886B24A
-:1018A0000004F70532CCE6001941F68532C8F7048A
-:1018B0007198F6847A782738000120360000E60017
-:1018C0001910F7057198F70476FC00000001203A22
-:1018D0000000E60018E8F3020011F30632D4F30525
-:1018E00076FCE00018F8F7020001F30576F8F3063D
-:1018F00032D4F3057700F7020000203A0000E6003A
-:101900001914F3020001F3063110E000268CF305F0
-:1019100032D4F3020001F3057A78F3063084F3053C
-:1019200032D4F30432C4000000019313FFFC078893
-:101930000008E00006109793FFFCE000268C0000F2
-:101940000001F3020000202E0000E6001CB99316EF
-:10195000FFE4873200088696FFE4C3040000C03A23
-:101960003200E6001984203600008732000C0000A7
-:101970000001C03A3200E600198420360000F682E9
-:10198000000120360000E6001CB8F3020000F70456
-:1019900032C09316FFACF58432C4863A142803B8DB
-:1019A0001420042C000886BA142400000001C03260
-:1019B0006A00EC001A709616FFEC77310001C73808
-:1019C000600077390002C63838000630000C86B255
-:1019D0000000872E00088516FFACC0367200E600B6
-:1019E0001A00C484000086B20004872E000C000098
-:1019F0000001C0367200E6001A04202A0000F50239
-:101A00000001202A0000E6001A1100000001F48203
-:101A1000000086B200008722000000000001C036EE
-:101A20007200E2001A4CF5820000C0367200E60037
-:101A30001A54202E000086B2000487220004000001
-:101A40000001C0367200E2001A55202E0000F58217
-:101A50000001202E0000E6001A6520260000F48216
-:101A6000000120260000E6001A70F3020001931620
-:101A7000FFAC8316FFAC00000001201A0000E60056
-:101A80001AB1F60200018716FFEC0000000176B9DA
-:101A90000001C6B4700076B50002C6B4380006B4C2
-:101AA000001486B600009716FFF0E0001B1896960B
-:101AB000FFF4271400149713FFFC9413FFFC939377
-:101AC000FFFC9396FFBC07880008E0012568979308
-:101AD000FFFC8396FFBC20220000E6001B15F602E7
-:101AE00000018716FFEC0000000176B90001C6B4C2
-:101AF000700076B50002C6B4380006B4001486B68D
-:101B000000009716FFF09696FFF4971E0008E0007D
-:101B10001B1C20320000F602000020320000E6000C
-:101B20001CB8F3020000F60432C09316FFAC86B274
-:101B3000142803B014200430148C873214240000BD
-:101B40000001C0367200EC001C049696FFEC77355D
-:101B50000001C738680077390002C5B8380005AC05
-:101B6000000C86AE00008732148C8516FFACC036A0
-:101B70007200E6001B94C484000086AE0004873225
-:101B8000149000000001C0367200E6001B98202A65
-:101B90000000F5020001202A0000E6001BA500005D
-:101BA0000001F482000086AE0000872200000000E1
-:101BB0000001C0367200E2001BE0F6020000C036F1
-:101BC0007200E6001BE82032000086AE0004872287
-:101BD000000400000001C0367200E2001BE9203260
-:101BE0000000F602000120320000E6001BF920266A
-:101BF0000000F482000120260000E6001C04F3022D
-:101C000000019316FFAC8316FFAC00000001201A00
-:101C10000000E6001C45F60200018716FFEC0000FC
-:101C2000000176B90001C6B4700076B50002C6B4F2
-:101C3000380006B4001486B600009716FFF0E000E6
-:101C40001CAC9696FFF4271400149713FFFC941312
-:101C5000FFFC9393FFFC9396FFBC07880008E0010C
-:101C600025689793FFFC8396FFBC20220000E600C6
-:101C70001CA9F60200018716FFEC0000000176B9EE
-:101C80000001C6B4700076B50002C6B4380006B4D0
-:101C9000001486B600009716FFF09696FFF4971E84
-:101CA0000008E0001CB020320000F60200002032E4
-:101CB0000000E6001E15F3020001F68432C00000A9
-:101CC000000185B60EF486360EF8202E0010E200D4
-:101CD0001CDC20320010E2001CF9000000018736F5
-:101CE0000F00000000010738000197360F0087360B
-:101CF0000F00E0001D24F702000007300001C03A89
-:101D00005A00E6001D1DF682000020320010E60099
-:101D10001D20202E0000E6001D24C7340000F6829E
-:101D20000001C7340000203A0000E6001E14F30250
-:101D30000001F30432CC000000019316FFDC931382
-:101D4000FFFC07880008E00043689793FFFC20220F
-:101D50000000E6001DFCF30200008316FFDC00001B
-:101D60000001861A00000000000120320010E2008D
-:101D70001D9176B10002871A000C0000000107389F
-:101D80000001971A000C871A000CE0001DFCF302FA
-:101D90000000F302004C9313FFFCC6B460007735DB
-:101DA0000004C7386A008316FFDCC7386000C738F4
-:101DB0003000073800109713FFFCF3067A289313BE
-:101DC000FFFC9616FFB407880008E00126F89793F9
-:101DD000FFFC8616FFB4000000010630000120322F
-:101DE0000011E6001DEC00000001F6020000831661
-:101DF000FFDC00000001961A0000F30200019316B8
-:101E0000FFD48316FFD400000001201A0000E60072
-:101E10001E18F30200019316FFE48316FFE400008E
-:101E20000001201A0000E6001F35F6820CABF70413
-:101E300032B48316FFD407380001F70532B4F70433
-:101E400032B4201A0000E6001E7000000001F70402
-:101E500032C0F306E030C03A3200E6001E700000E7
-:101E60000001F70432E80000000107380001F7051F
-:101E700032E8F70471C400000001203A0000E600D7
-:101E80001EADF6862C28F7042D3800000001063818
-:101E90000001F6052D3877390002F302000A2032DE
-:101EA0000044E6001EACB33A6802F0052D38F70492
-:101EB00071D4F68471CC07380001C03A6A00E6009C
-:101EC0001EC8F70571D4F00571D4F68471D4F704F7
-:101ED00071D0F00571C4C0367200470C0001F68461
-:101EE00032D00000000120360000E60025D9F705B9
-:101EF00071C8F704719800000001203A0000E60064
-:101F0000257900000001F70475EC00000001203A7B
-:101F10000000E600257800000001F70475F00000DD
-:101F20000001203A0000E600257800000001E000F2
-:101F300025DCF306319CF00532E8F70432C0F604E4
-:101F40006F5496BA000420320000E6001F60F302CE
-:101F5000000CF3020001F3056F54E0001F68F70264
-:101F60000001F3056F58F7020000203A0000E60078
-:101F70001F7CF3062F6CE000268CF30532D4F58429
-:101F80007A7024940010202E0001E6002284F5854A
-:101F90007AA0F7020001F60432C8F7057A70F70458
-:101FA00032C4F68432C0F6057A2C9002FF8090028B
-:101FB000FF38F5847A28073800249582FF3C970281
-:101FC000FF409602FF448736141000000001C73816
-:101FD0006000973614108736141800000001073887
-:101FE00000019736141887361418F0056F50F7045F
-:101FF00032B89596FFECC7386000F70532B8F704A1
-:1020000032BCF3062FF807380001F70532BCF7049D
-:1020100032BCF30532D4F7060C3EC07E7400E600F5
-:10202000203400000001C07E7400E600202500007E
-:102030000001F7060C3EC77C7400203A0010E60051
-:10204000268C00000001F70432E4FF820010F584C2
-:102050006F5807380001202E0021E2002090F7057C
-:1020600032E4F7042D38F6862C2806380001F605F0
-:102070002D387739000220320044E6002084B5BABA
-:102080006802F0052D38F3020022E0002094F305E9
-:102090006F58F0056F54F58432C000000001902E97
-:1020A0000004872E000000000001203A0002E60034
-:1020B00021C0000000018702FF38032C0EF49316A4
-:1020C000FFCCF7057A689313FFFC9596FFB8078855
-:1020D0000008E00043A09793FFFC8596FFB82022FC
-:1020E0000000E600217C00000001862E0EF80000B2
-:1020F000000120320010E2002119F302004C872E6B
-:102100000F000000000107380001972E0F00872EF6
-:102110000F00E000217C000000019313FFFCF30698
-:102120007A289313FFFC76B10002C6B460007735BD
-:102130000004C7386A008316FFCCC7386000C73870
-:102140003000073800109713FFFC9596FFB89616DD
-:10215000FFB407880008E00126F89793FFFC861675
-:10216000FFB48596FFB80630000120320011E6006A
-:10217000217800000001F6020000962E0EF8F70408
-:1021800032C0F306E030C03A3200E60021C0000061
-:102190000001F704E0180000000177B8001E703E4F
-:1021A000FFE1E60021C1000000010F814000F704BB
-:1021B00079C80000000107380001F70579C8F70465
-:1021C00079C8F70471C400000001203A0000E6005D
-:1021D00021FDF6862C28F7042D3800000001063872
-:1021E0000001F6052D3877390002F302000A20328B
-:1021F0000044E60021FCB33A6802F0052D38F704EC
-:1022000071D4F68471CC07380001C03A6A00E60048
-:102210002218F70571D4F00571D4F68471D4F7044F
-:1022200071D0F00571C4C0367200470C0001F6840D
-:1022300032D00000000120360000E60025D9F70565
-:1022400071C8F704719800000001203A0000E60010
-:10225000257900000001F70475EC00000001203A28
-:102260000000E600257800000001F70475F000008A
-:102270000001203A0000E600257800000001E0009F
-:1022800025DCF306319CF0057A889002FF38F005D2
-:102290006F509002FF80F70432C4F3063228F30532
-:1022A00032D4F60432C8F6847A2CF50200000738DE
-:1022B0000024F7057A9820320000E60022D5F605C2
-:1022C0007A90C02A5A00E6002620C0326A00EE004A
-:1022D000262100000001F68432C00000000187368C
-:1022E000141000000001C7386000973614108736BC
-:1022F00014180000000107380001973614188736BB
-:102300001418F70432B800000001C7386000F70560
-:1023100032B8F70432BC0000000107380001F705AD
-:1023200032BCF70432BC20320000E6002345000036
-:102330000001F70432E0F5057A7007380001E0008B
-:102340002348F70532E0F5057A70F5846F580000F0
-:102350000001202E0021E200238CF6862C28F704B1
-:102360002D380000000106380001F6052D387739B8
-:10237000000220320044E6002380B5BA6802F0056E
-:102380002D38F3020022E0002390F3056F58F0058A
-:102390006F54F58432C000000001902E0004872E97
-:1023A000000000000001203A0002E60024BC00000A
-:1023B00000018702FF38032C0EF49316FFC4F705C3
-:1023C0007A689313FFFC9596FFB807880008E00031
-:1023D00043A09793FFFC8596FFB820220000E600FB
-:1023E000247800000001862E0EF800000001203243
-:1023F0000010E2002415F302004C872E0F000000AD
-:10240000000107380001972E0F00872E0F00E00013
-:102410002478000000019313FFFCF3067A2893133D
-:10242000FFFC76B10002C6B4600077350004C738FF
-:102430006A008316FFC4C7386000C7383000073809
-:1024400000109713FFFC9596FFB89616FFB4078807
-:102450000008E00126F89793FFFC8616FFB48596E6
-:10246000FFB80630000120320011E600247400009D
-:102470000001F6020000962E0EF8F70432C0F306B3
-:10248000E030C03A3200E60024BC00000001F7044E
-:10249000E0180000000177B8001E703EFFE1E60082
-:1024A00024BD000000010F814000F70479C800003E
-:1024B000000107380001F70579C8F70479C8F70467
-:1024C00071C400000001203A0000E60024F9F686FD
-:1024D0002C28F7042D380000000106380001F6050D
-:1024E0002D3877390002F302000A20320044E6005A
-:1024F00024F8B33A6802F0052D38F70471D4F68455
-:1025000071CC07380001C03A6A00E6002514F705CF
-:1025100071D4F00571D4F68471D4F70471D0F0054C
-:1025200071C4C0367200470C0001F68432D000003E
-:10253000000120360000E60025D9F70571C8F70430
-:10254000719800000001203A0000E60025790000A3
-:102550000001F70475EC00000001203A0000E600DD
-:10256000257800000001F70475F000000001203A12
-:102570000000E60025D100000001F58476F8000097
-:102580000001202E0021E20025C4F6862C28F70445
-:102590002D380000000106380001F6052D38773986
-:1025A000000220320044E60025B0B5BA6802F0050A
-:1025B0002D38F3020022F30576F8F3047700E000EB
-:1025C00025C8F30576FCF00576FCE00025D8F0057B
-:1025D0007A78E00025DCF306319CF3062EE0F30563
-:1025E00032D4F70471C800000001203A0000E60070
-:1025F000268CF6862C28F7042D38000000010638BA
-:102600000001F6052D3877390002F3020009203267
-:102610000044E600268CB33A6802E000268CF00500
-:102620002D38F7047A9000000001C03A6A00EE00ED
-:102630002641C5B40000C7385A00E0002648F70517
-:102640007A90C5B80000F0057A90F6847A88F7068B
-:102650007A2876350003A732700206B40001971677
-:10266000FFEC84A6FFFCF7067A2CF3047A98948298
-:10267000FF3C9302FF409582FF44B5B27002F7041D
-:102680007A98F6857A88C7385800F7057A98879639
-:10269000FFFC8296FFF802140000013C00000000DD
-:1026A00000019293FFFC02900008F7020001F70579
-:1026B0007A78F7063084F70532D4F70432C4000084
-:1026C00000019713FFFC07880008E00006109793AD
-:1026D000FFFC8796FFFC8296FFF802140000013C85
-:1026E0000000000000019293FFFC029000082210FD
-:1026F0000050F70432D0F3020000203A0000E60058
-:102700002A719316FFE4F68432C48616FFE48736F6
-:102710000008C3040000C03A3200E600273C203223
-:1027200000008736000C00000001C03A3200E600CD
-:10273000273C20320000F602000120320000E600B3
-:102740002A70F3020000F70432C09316FFACF58440
-:1027500032C4863A142803B81420042C000886BA20
-:10276000142400000001C0326A00EC0028289616EC
-:10277000FFEC77310001C738600077390002C638B6
-:1027800038000630000C86B20000872E000885163F
-:10279000FFACC0367200E60027B8C484000086B2E1
-:1027A0000004872E000C00000001C0367200E60015
-:1027B00027BC202A0000F5020001202A0000E600C4
-:1027C00027C900000001F482000086B200008722C1
-:1027D000000000000001C0367200E2002804F5820B
-:1027E0000000C0367200E600280C202E000086B2E1
-:1027F00000048722000400000001C0367200E200DD
-:10280000280D202E0000F5820001202E0000E60099
-:10281000281D20260000F482000120260000E6008A
-:102820002828F30200019316FFAC8316FFAC0000CA
-:102830000001201A0000E6002869F6020001871650
-:10284000FFEC0000000176B90001C6B4700076B557
-:102850000002C6B4380006B4001486B6000097160D
-:10286000FFF0E00028D09696FFF427140014971389
-:10287000FFFC9413FFFC9393FFFC9396FFBC078827
-:102880000008E00125689793FFFC8396FFBC202297
-:102890000000E60028CDF60200018716FFEC0000DC
-:1028A000000176B90001C6B4700076B50002C6B466
-:1028B000380006B4001486B600009716FFF096960E
-:1028C000FFF4971E0008E00028D420320000F60232
-:1028D000000020320000E6002A70F3020000F60437
-:1028E00032C09316FFAC86B2142803B01420043013
-:1028F000148C8732142400000001C0367200EC00F2
-:1029000029BC9696FFEC77350001C7386800773907
-:102910000002C5B8380005AC000C86AE0000873256
-:10292000148C8516FFACC0367200E600294CC484B6
-:10293000000086AE00048732149000000001C0360B
-:102940007200E6002950202A0000F5020001202A2A
-:102950000000E600295D00000001F482000086AE60
-:1029600000008722000000000001C0367200E20073
-:102970002998F6020000C0367200E60029A0203235
-:10298000000086AE00048722000400000001C0366B
-:102990007200E20029A120320000F602000120327C
-:1029A0000000E60029B120260000F4820001202664
-:1029B0000000E60029BCF30200019316FFAC831669
-:1029C000FFAC00000001201A0000E60029FDF6021D
-:1029D00000018716FFEC0000000176B90001C6B4C3
-:1029E000700076B50002C6B4380006B4001486B68E
-:1029F00000009716FFF0E0002A649696FFF4271473
-:102A000000149713FFFC9413FFFC9393FFFC939621
-:102A1000FFBC07880008E00125689793FFFC8396B8
-:102A2000FFBC20220000E6002A61F60200018716A2
-:102A3000FFEC0000000176B90001C6B4700076B565
-:102A40000002C6B4380006B4001486B6000097161B
-:102A5000FFF09696FFF4971E0008E0002A682032E7
-:102A60000000F602000020320000E6002BCDF30249
-:102A70000001F68432C00000000185B60EF48636EF
-:102A80000EF8202E0010E2002A9420320010E200FE
-:102A90002AB10000000187360F000000000107384E
-:102AA000000197360F0087360F00E0002ADCF7029E
-:102AB000000007300001C03A5A00E6002AD5F6822D
-:102AC000000020320010E6002AD8202E0000E60088
-:102AD0002ADCC7340000F6820001C7340000203A27
-:102AE0000000E6002BCCF3020001F30432CC00001E
-:102AF00000019316FFDC9313FFFC07880008E00039
-:102B000043689793FFFC20220000E6002BB4F302F9
-:102B100000008316FFDC00000001861A00000000A0
-:102B2000000120320010E2002B4976B10002871A22
-:102B3000000C0000000107380001971A000C871AEA
-:102B4000000CE0002BB4F3020000F302004C9313DE
-:102B5000FFFCC6B4600077350004C7386A008316EE
-:102B6000FFDCC7386000C738300007380010971303
-:102B7000FFFCF3067A289313FFFC9616FFB4078830
-:102B80000008E00126F89793FFFC8616FFB40000CA
-:102B900000010630000120320011E6002BA40000E5
-:102BA0000001F60200008316FFDC00000001961A07
-:102BB0000000F30200019316FFD48316FFD4000037
-:102BC0000001201A0000E6002BD0F302000193164A
-:102BD000FFE48316FFE400000001201A0000E60075
-:102BE0002CEDF6820CABF70432B48316FFD4073811
-:102BF0000001F70532B4F70432B4201A0000E600F1
-:102C00002C2800000001F70432C0F306E030C03A7F
-:102C10003200E6002C2800000001F70432E8000032
-:102C2000000107380001F70532E8F70471C400001D
-:102C30000001203A0000E6002C65F6862C28F704F7
-:102C40002D380000000106380001F6052D387739CF
-:102C50000002F302000A20320044E6002C64B33A7A
-:102C60006802F0052D38F70471D4F68471CC07386A
-:102C70000001C03A6A00E6002C80F70571D4F00527
-:102C800071D4F68471D4F70471D0F00571C4C036E4
-:102C90007200470C0001F68432D00000000120369B
-:102CA0000000E6003391F70571C8F7047198000041
-:102CB0000001203A0000E600333100000001F70473
-:102CC00075EC00000001203A0000E60033300000FF
-:102CD0000001F70475F000000001203A0000E60052
-:102CE000333000000001E0003394F306319CF0051E
-:102CF00032E8F70432C0F6046F5496BA000420326A
-:102D00000000E6002D18F302000CF3020001F305A9
-:102D10006F54E0002D20F7020001F3056F58F70211
-:102D20000000203A0000E6002D34F3062F6CE0008E
-:102D30003444F30532D4F5847A7024940010202EA4
-:102D40000001E600303CF5857AA0F7020001F604A8
-:102D500032C8F7057A70F70432C4F68432C0F6053B
-:102D60007A2C9002FF809002FF38F5847A28073889
-:102D700000249582FF3C9702FF409602FF4487366D
-:102D8000141000000001C738600097361410873611
-:102D90001418000000010738000197361418873610
-:102DA0001418F0056F50F70432B89596FFECC73849
-:102DB0006000F70532B8F70432BCF3062FF8073885
-:102DC0000001F70532BCF70432BCF30532D4F70634
-:102DD0000C3EC07E7400E6002DEC00000001C07EB9
-:102DE0007400E6002DDD00000001F7060C3EC77CF4
-:102DF0007400203A0010E600344400000001F7049B
-:102E000032E4FF820010F5846F5807380001202E4D
-:102E10000021E2002E48F70532E4F7042D38F6864B
-:102E20002C2806380001F6052D38773900022032AB
-:102E30000044E6002E3CB5BA6802F0052D38F302D6
-:102E40000022E0002E4CF3056F58F0056F54F58416
-:102E500032C000000001902E0004872E0000000008
-:102E60000001203A0002E6002F78000000018702EE
-:102E7000FF38032C0EF49316FFCCF7057A689313F2
-:102E8000FFFC9596FFB807880008E00043A09793E1
-:102E9000FFFC8596FFB820220000E6002F340000DA
-:102EA0000001862E0EF80000000120320010E20022
-:102EB0002ED1F302004C872E0F00000000010738CE
-:102EC0000001972E0F00872E0F00E0002F34000026
-:102ED00000019313FFFCF3067A289313FFFC76B1ED
-:102EE0000002C6B4600077350004C7386A00831654
-:102EF000FFCCC7386000C738300007380010971380
-:102F0000FFFC9596FFB89616FFB407880008E0010D
-:102F100026F89793FFFC8616FFB48596FFB8063017
-:102F2000000120320011E6002F3000000001F602FF
-:102F30000000962E0EF8F70432C0F306E030C03AD7
-:102F40003200E6002F7800000001F704E0180000CE
-:102F5000000177B8001E703EFFE1E6002F79000007
-:102F600000010F814000F70479C800000001073814
-:102F70000001F70579C8F70479C8F70471C40000A7
-:102F80000001203A0000E6002FB5F6862C28F70451
-:102F90002D380000000106380001F6052D3877397C
-:102FA0000002F302000A20320044E6002FB4B33AD4
-:102FB0006802F0052D38F70471D4F68471CC073817
-:102FC0000001C03A6A00E6002FD0F70571D4F00581
-:102FD00071D4F68471D4F70471D0F00571C4C03691
-:102FE0007200470C0001F68432D000000001203648
-:102FF0000000E6003391F70571C8F70471980000EE
-:103000000001203A0000E600333100000001F7041F
-:1030100075EC00000001203A0000E60033300000AB
-:103020000001F70475F000000001203A0000E600FE
-:10303000333000000001E0003394F306319CF005CA
-:103040007A889002FF38F0056F509002FF80F704F5
-:1030500032C4F3063228F30532D4F60432C8F684BB
-:103060007A2CF502000007380024F7057A98203200
-:103070000000E600308DF6057A90C02A5A00E6007E
-:1030800033D8C0326A00EE0033D900000001F68464
-:1030900032C0000000018736141000000001C7385C
-:1030A00060009736141087361418000000010738A6
-:1030B00000019736141887361418F70432B8000048
-:1030C0000001C7386000F70532B8F70432BC0000D1
-:1030D000000107380001F70532BCF70432BC20328A
-:1030E0000000E60030FD00000001F70432E0F505C5
-:1030F0007A7007380001E0003100F70532E0F5058D
-:103100007A70F5846F5800000001202E0021E20043
-:103110003144F6862C28F7042D38000000010638CB
-:103120000001F6052D387739000220320044E60010
-:103130003138B5BA6802F0052D38F3020022E000FC
-:103140003148F3056F58F0056F54F58432C0000024
-:103150000001902E0004872E000000000001203A9C
-:103160000002E6003274000000018702FF38032CE1
-:103170000EF49316FFC4F7057A689313FFFC959637
-:10318000FFB807880008E00043A09793FFFC8596EE
-:10319000FFB820220000E600323000000001862E39
-:1031A0000EF80000000120320010E20031CDF302E1
-:1031B000004C872E0F000000000107380001972EF9
-:1031C0000F00872E0F00E000323000000001931343
-:1031D000FFFCF3067A289313FFFC76B10002C6B415
-:1031E000600077350004C7386A008316FFC4C7380B
-:1031F0006000C7383000073800109713FFFC959621
-:10320000FFB89616FFB407880008E00126F89793E8
-:10321000FFFC8616FFB48596FFB806300001203209
-:103220000011E600322C00000001F6020000962E8C
-:103230000EF8F70432C0F306E030C03A3200E60080
-:10324000327400000001F704E0180000000177B8B4
-:10325000001E703EFFE1E6003275000000010F81A4
-:103260004000F70479C80000000107380001F705A5
-:1032700079C8F70479C8F70471C400000001203A46
-:103280000000E60032B1F6862C28F7042D38000045
-:10329000000106380001F6052D3877390002F302E7
-:1032A000000A20320044E60032B0B33A6802F0056A
-:1032B0002D38F70471D4F68471CC07380001C03A78
-:1032C0006A00E60032CCF70571D4F00571D4F684BB
-:1032D00071D4F70471D0F00571C4C0367200470C88
-:1032E0000001F68432D00000000120360000E60024
-:1032F0003391F70571C8F704719800000001203A76
-:103300000000E600333100000001F70475EC000016
-:103310000001203A0000E600333000000001F7040D
-:1033200075F000000001203A0000E600338900003B
-:103330000001F58476F800000001202E0021E20053
-:10334000337CF6862C28F7042D380000000106385F
-:103350000001F6052D387739000220320044E600DE
-:103360003368B5BA6802F0052D38F3020022F30580
-:1033700076F8F3047700E0003380F30576FCF0057F
-:1033800076FCE0003390F0057A78E0003394F306A1
-:10339000319CF3062EE0F30532D4F70471C8000027
-:1033A0000001203A0000E6003444F6862C28F70499
-:1033B0002D380000000106380001F6052D38773958
-:1033C0000002F302000920320044E6003444B33A1C
-:1033D0006802E0003444F0052D38F7047A900000CC
-:1033E0000001C03A6A00EE0033F9C5B40000C738E6
-:1033F0005A00E0003400F7057A90C5B80000F005E7
-:103400007A90F6847A88F7067A2876350003A73210
-:10341000700206B400019716FFEC84A6FFFCF706C5
-:103420007A2CF3047A989482FF3C9302FF409582B1
-:10343000FF44B5B27002F7047A98F6857A88C738E7
-:103440005800F7057A988796FFFC8296FFF80214D9
-:103450000000013C0000000000019293FFFC02907C
-:10346000000822100020F5847A7000000001202E50
-:103470000001E600376CF5857AA0F7020001F6043A
-:1034800032C8F7057A70F70432C4F68432C0F60504
-:103490007A2C9002FF809002FF38F5847A28073852
-:1034A00000249582FF3C9702FF409602FF44873636
-:1034B000141000000001C7386000973614108736DA
-:1034C00014180000000107380001973614188736D9
-:1034D0001418F0056F50F70432B89596FFF4C7380A
-:1034E0006000F70532B8F70432BCF4862FF80738CD
-:1034F0000001F70532BCF70432BCF48532D4F7067C
-:103500000C3EC07E7400E600351C00000001C07E49
-:103510007400E600350D00000001F7060C3EC77C84
-:103520007400203A0010E6003B7000000001F70430
-:1035300032E4FF820010F5846F5807380001202E16
-:103540000021E2003578F70532E4F7042D38F686DD
-:103550002C2806380001F6052D3877390002203274
-:103560000044E600356CB5BA6802F0052D38F482E7
-:103570000022E000357CF4856F58F0056F54F58427
-:1035800032C000000001902E0004872E00000000D1
-:103590000001203A0002E60036A800000001870280
-:1035A000FF3804AC0EF49496FFECF7057A68949318
-:1035B000FFFC9596FFDC07880008E00043A0979386
-:1035C000FFFC8596FFDC20220000E6003664000048
-:1035D0000001862E0EF80000000120320010E200EB
-:1035E0003601F482004C872E0F00000000010738DE
-:1035F0000001972E0F00872E0F00E00036640000B8
-:1036000000019493FFFCF4867A289493FFFC76B132
-:103610000002C6B4600077350004C7386A0084969B
-:10362000FFECC7386000C738480007380010971310
-:10363000FFFC9596FFDC9616FFD807880008E0018E
-:1036400026F89793FFFC8616FFD88596FFDC063098
-:10365000000120320011E600366000000001F60291
-:103660000000962E0EF8F70432C0F486E030C03A1F
-:103670004A00E60036A800000001F704E018000048
-:10368000000177B8001E703EFFE1E60036A9000099
-:1036900000010F814000F70479C8000000010738DD
-:1036A0000001F70579C8F70479C8F70471C4000070
-:1036B0000001203A0000E60036E5F6862C28F704E3
-:1036C0002D380000000106380001F6052D38773945
-:1036D0000002F482000A20320044E60036E4B4BA64
-:1036E0006802F0052D38F70471D4F68471CC0738E0
-:1036F0000001C03A6A00E6003700F70571D4F00512
-:1037000071D4F68471D4F70471D0F00571C4C03659
-:103710007200470C0001F68432D000000001203610
-:103720000000E6003AC1F70571C8F704719800007F
-:103730000001203A0000E6003A6100000001F704B1
-:1037400075EC00000001203A0000E6003A6000003D
-:103750000001F70475F000000001203A0000E600C7
-:103760003A6000000001E0003AC4F486319CF005A4
-:103770007A889002FF38F0056F509002FF80F704BE
-:1037800032C4F4863228F48532D4F60432C8F68482
-:103790007A2CF502000007380024F7057A982032C9
-:1037A0000000E60037BDF6057A90C02A5A00E60010
-:1037B0003B08C0326A00EE003B0900000001F684BD
-:1037C00032C0000000018736141000000001C73825
-:1037D000600097361410873614180000000107386F
-:1037E00000019736141887361418F70432B8000011
-:1037F0000001C7386000F70532B8F70432BC00009A
-:10380000000107380001F70532BCF70432BC203252
-:103810000000E600382D00000001F70432E0F50555
-:103820007A7007380001E0003830F70532E0F5051E
-:103830007A70F5846F5800000001202E0021E2000C
-:103840003874F6862C28F7042D380000000106385D
-:103850000001F6052D387739000220320044E600D9
-:103860003868B5BA6802F0052D38F4820022E0000D
-:103870003878F4856F58F0056F54F58432C0000035
-:103880000001902E0004872E000000000001203A65
-:103890000002E60039A4000000018702FF3804ACF2
-:1038A0000EF49496FFE4F7057A689493FFFC9596DE
-:1038B000FFDC07880008E00043A09793FFFC859693
-:1038C000FFDC20220000E600396000000001862EA7
-:1038D0000EF80000000120320010E20038FDF482F2
-:1038E000004C872E0F000000000107380001972EC2
-:1038F0000F00872E0F00E000396000000001949354
-:10390000FFFCF4867A289493FFFC76B10002C6B4DB
-:10391000600077350004C7386A008496FFE4C73832
-:103920006000C7384800073800109713FFFC9596D1
-:10393000FFDC9616FFD807880008E00126F8979369
-:10394000FFFC8616FFD88596FFDC0630000120328A
-:103950000011E600395C00000001F6020000962E1E
-:103960000EF8F70432C0F486E030C03A4A00E600B0
-:1039700039A400000001F704E0180000000177B846
-:10398000001E703EFFE1E60039A5000000010F8136
-:103990004000F70479C80000000107380001F7056E
-:1039A00079C8F70479C8F70471C400000001203A0F
-:1039B0000000E60039E1F6862C28F7042D380000D7
-:1039C000000106380001F6052D3877390002F4822F
-:1039D000000A20320044E60039E0B4BA6802F0057B
-:1039E0002D38F70471D4F68471CC07380001C03A41
-:1039F0006A00E60039FCF70571D4F00571D4F6844D
-:103A000071D4F70471D0F00571C4C0367200470C50
-:103A10000001F68432D00000000120360000E600EC
-:103A20003AC1F70571C8F704719800000001203A07
-:103A30000000E6003A6100000001F70475EC0000A8
-:103A40000001203A0000E6003A6000000001F7049F
-:103A500075F000000001203A0000E6003AB90000CD
-:103A60000001F58476F800000001202E0021E2001C
-:103A70003AACF6862C28F7042D38000000010638F1
-:103A80000001F6052D387739000220320044E600A7
-:103A90003A98B5BA6802F0052D38F4820022F48510
-:103AA00076F8F4847700E0003AB0F48576FCF0050F
-:103AB00076FCE0003AC0F0057A78E0003AC4F4867B
-:103AC000319CF4862EE0F48532D4F70471C80000EE
-:103AD0000001203A0000E6003B70F6862C28F7042F
-:103AE0002D380000000106380001F6052D38773921
-:103AF0000002F482000920320044E6003B70B4BAB0
-:103B00006802E0003B70F0052D38F7047A90000061
-:103B10000001C03A6A00EE003B29C5B40000C73876
-:103B20005A00E0003B30F7057A90C5B80000F00578
-:103B30007A90F7047A88F6867A2876390003A6B256
-:103B4000680207380001F7057A88F7047A98969694
-:103B5000FFF49682FF3CF4847A98F6867A2CC73874
-:103B600058009482FF409582FF44B5B26802F70581
-:103B70007A988796FFFC8296FFF802140000013CB9
-:103B80000000000000019293FFFC02900008221048
-:103B90000018F5047A88F7067A2CF5847A9076A9CD
-:103BA0000003A6B67002202E0000E6003BCD000008
-:103BB0000001F7047AA000000001C02A7200E600AC
-:103BC0003F18C02E6A00EE003F1900000001F68485
-:103BD00032C0F60432C88736141000000001C7381E
-:103BE000600097361410873614180000000107385B
-:103BF00000019736141887361418F70432B80000FD
-:103C00000001C7386000F70532B8F70432BC000085
-:103C1000000107380001F70532BCF70432BC202E42
-:103C20000000E6003C3DF6820000F70432E0F68535
-:103C30007A7007380001E0003C40F70532E0F505F6
-:103C40007A70F5846F5800000001202E0021E200F8
-:103C50003C84F6862C28F7042D3800000001063835
-:103C60000001F6052D387739000220320044E600C5
-:103C70003C78B5BA6802F0052D38F4820022E000E5
-:103C80003C88F4856F58F0056F54F58432C000000D
-:103C90000001902E0004872E000000000001203A51
-:103CA0000002E6003DB4000000018702FF3804ACCA
-:103CB0000EF49496FFECF7057A689493FFFC9596C2
-:103CC000FFE407880008E00043A09793FFFC859677
-:103CD000FFE420220000E6003D7000000001862E77
-:103CE0000EF80000000120320010E2003D0DF482C9
-:103CF000004C872E0F000000000107380001972EAE
-:103D00000F00872E0F00E0003D700000000194932B
-:103D1000FFFCF4867A289493FFFC76B10002C6B4C7
-:103D2000600077350004C7386A008496FFECC73816
-:103D30006000C7384800073800109713FFFC9596BD
-:103D4000FFE49616FFE007880008E00126F8979345
-:103D5000FFFC8616FFE08596FFE406300001203266
-:103D60000011E6003D6C00000001F6020000962EF6
-:103D70000EF8F70432C0F486E030C03A4A00E6009C
-:103D80003DB400000001F704E0180000000177B81E
-:103D9000001E703EFFE1E6003DB5000000010F810E
-:103DA0004000F70479C80000000107380001F7055A
-:103DB00079C8F70479C8F70471C400000001203AFB
-:103DC0000000E6003DF1F6862C28F7042D380000AF
-:103DD000000106380001F6052D3877390002F4821B
-:103DE000000A20320044E6003DF0B4BA6802F00553
-:103DF0002D38F70471D4F68471CC07380001C03A2D
-:103E00006A00E6003E0CF70571D4F00571D4F68423
-:103E100071D4F70471D0F00571C4C0367200470C3C
-:103E20000001F68432D00000000120360000E600D8
-:103E30003ED1F70571C8F704719800000001203ADF
-:103E40000000E6003E7100000001F70475EC000080
-:103E50000001203A0000E6003E7000000001F70477
-:103E600075F000000001203A0000E6003EC90000A5
-:103E70000001F58476F800000001202E0021E20008
-:103E80003EBCF6862C28F7042D38000000010638C9
-:103E90000001F6052D387739000220320044E60093
-:103EA0003EA8B5BA6802F0052D38F4820022F485E8
-:103EB00076F8F4847700E0003EC0F48576FCF005E7
-:103EC00076FCE0003ED0F0057A78E0003ED4F4863F
-:103ED000319CF4862EE0F48532D4F70471C80000DA
-:103EE0000001203A0000E6003F80F6862C28F70407
-:103EF0002D380000000106380001F6052D3877390D
-:103F00000002F482000920320044E6003F80B4BA87
-:103F10006802E0003F80F0052D38F7047A90000039
-:103F20000001C03A6A00EE003F39C5B40000C7384E
-:103F30005A00E0003F40F7057A90C5B80000F00550
-:103F40007A90F7047A88F6867A2876390003A6B242
-:103F5000680207380001F7057A88F7047A98969680
-:103F6000FFF49682FF3CF4847A98F6867A2CC73860
-:103F700058009482FF409582FF44B5B26802F7056D
-:103F80007A988796FFFC8296FFF802140000013CA5
-:103F90000000000000019293FFFC02900008221034
-:103FA0000010F5846F5800000001202E0021E2006F
-:103FB0003FE4F6862C28F7042D380000000106386F
-:103FC0000001F6052D387739000220320044E60062
-:103FD0003FD8B5BA6802F0052D38F5020022E0009E
-:103FE0003FE8F5056F58F0056F54F58432C00000C6
-:103FF0000001902E0004872E000000000001203AEE
-:104000000002E6004114000000018702FF38052C81
-:104010000EF49516FFF4F7057A689513FFFC959654
-:10402000FFEC07880008E00043A09793FFFC85960B
-:10403000FFEC20220000E60040D000000001862EA8
-:104040000EF80000000120320010E200406DF50281
-:10405000004C872E0F000000000107380001972E4A
-:104060000F00872E0F00E00040D0000000019513E4
-:10407000FFFCF5067A289513FFFC76B10002C6B462
-:10408000600077350004C7386A008516FFF4C7382A
-:104090006000C7385000073800109713FFFC959652
-:1040A000FFEC9616FFE807880008E00126F89793D2
-:1040B000FFFC8616FFE88596FFEC063000012032F3
-:1040C0000011E60040CC00000001F6020000962E30
-:1040D0000EF8F70432C0F506E030C03A5200E600B0
-:1040E000411400000001F704E0180000000177B857
-:1040F000001E703EFFE1E6004115000000010F8147
-:104100004000F70479C80000000107380001F705F6
-:1041100079C8F70479C8F70471C400000001203A97
-:104120000000E6004151F6862C28F7042D380000E7
-:10413000000106380001F6052D3877390002F50236
-:10414000000A20320044E6004150B53A6802F0050A
-:104150002D38F70471D4F68471CC07380001C03AC9
-:104160006A00E600416CF70571D4F00571D4F6845D
-:1041700071D4F70471D0F00571C4C0367200470CD9
-:104180000001F68432D00000000120360000E60075
-:104190004231F70571C8F704719800000001203A18
-:1041A0000000E60041D100000001F70475EC0000BA
-:1041B0000001203A0000E60041D000000001F704B1
-:1041C00075F000000001203A0000E60042290000DE
-:1041D0000001F58476F800000001202E0021E200A5
-:1041E000421CF6862C28F7042D3800000001063802
-:1041F0000001F6052D387739000220320044E60030
-:104200004208B5BA6802F0052D38F5020022F5051E
-:1042100076F8F5047700E0004220F50576FCF0051D
-:1042200076FCE0004230F0057A78E0004234F50692
-:10423000319CF5062EE0F50532D4F70471C8000074
-:104240000001203A0000E6004274F6862C28F704AC
-:104250002D380000000106380001F6052D387739A9
-:104260000002F502000920320044E6004274B53A2B
-:104270006802F0052D388796FFFC8296FFF802143D
-:104280000000013C0000000000019293FFFC02903E
-:104290000008F70632D49713FFFCF7062EE09713B9
-:1042A000FFFC07880008E00014F49793FFFCF70672
-:1042B00032D49713FFFCF7062F6C9713FFFC078887
-:1042C0000008E00014F49793FFFCF70632D497132C
-:1042D000FFFCF7062FF89713FFFC07880008E000A3
-:1042E00014F49793FFFCF70632D49713FFFCF706FC
-:1042F00030849713FFFC07880008E00014F49793BC
-:10430000FFFCF70632D49713FFFCF7063110971322
-:10431000FFFC07880008E00014F49793FFFCF70601
-:1043200032D49713FFFCF706319C9713FFFC0788E4
-:104330000008E00014F49793FFFCF70632D49713BB
-:10434000FFFCF70632289713FFFC07880008E000FF
-:1043500014F49793FFFC8796FFFC8296FFF80214F3
-:104360000000013C0000000000019293FFFC02905D
-:104370000008871600000000000186BA0000873A96
-:10438000000400000001C0367200440C0001879652
-:10439000FFFC8296FFF802140004013C00000000BC
-:1043A00000019293FFFC0290000885960000000037
-:1043B0000001862E000086AE000420320010E200CC
-:1043C00043D00000000120360010E20043ED073426
-:1043D0000001872E000C0000000107380001972E15
-:1043E000000C872E000CE0004414F4020000C03AD8
-:1043F0006200E6004411F402000020360010E600DE
-:1044000044140000000120320000E60044140000C3
-:104410000001F40200018796FFFC8296FFF8021467
-:104420000004013C0000000000019293FFFC029098
-:104430000008F7020001F7053524F7046F44000077
-:104440000001F7053528F70632F49713FFFCF7064D
-:1044500035309713FFFC07880008E0001548979354
-:10446000FFFCF70245049713FFFCF702000D9713BA
-:10447000FFFCF70632F49713FFFC07880008E00002
-:10448000161C9793FFFCF7024A049713FFFCF702F0
-:10449000000F9713FFFCF70633809713FFFC078884
-:1044A0000008E000161C9793FFFCF7024EEC9713F0
-:1044B000FFFCF70200089713FFFCF706340C971374
-:1044C000FFFC07880008E000161C9793FFFCF7022A
-:1044D00057649713FFFCF70200079713FFFCF706DA
-:1044E00034989713FFFC07880008E000161C979388
-:1044F000FFFC8796FFFC8296FFF802140000013C47
-:104500000000000000019293FFFC029000082210BE
-:104510000014F70475F800000001203A0000E600DE
-:10452000452DF68675F8E0004544F7020000F704D3
-:1045300076040000000177390002C7386800873A26
-:10454000001800000001203A0000E600455CF70575
-:104550003548F4863380E00049F0F4853530F704BF
-:104560006F5400000001203A0000E6004580F4820C
-:104570000008F4820001F4856F54E0004588F702DA
-:104580000001F4856F58F7020000203A0000E600B1
-:1045900045A0F4820004F486340CE00049F0F48570
-:1045A0003530F6843548F604352CF4B72800073446
-:1045B0000002F4820001F4BB28008732008CF482F0
-:1045C00000019736001887320090F4856F509736B7
-:1045D000000484B200840000000194B6001084B28C
-:1045E00000880000000194B6001484B6001000009A
-:1045F000000194B6000884B600140000000194B6CF
-:10460000000C84B2009800000001F4853554F48257
-:1046100000019482FF80F5043554F4863498F485C3
-:1046200035309502FF3885B2000006B4002495822B
-:10463000FF3C9682FF4087320004F6853550970292
-:10464000FF4486B20004F005354CF704354095165A
-:10465000FFF49596FFF4C7386800F7053540F584F8
-:10466000352886B20004872E141400000001C738D4
-:104670006800972E14148732008000000001203A51
-:104680000001EE0049F0F7060C3EC07E7400E60023
-:1046900046A400000001C07E7400E60046950000BC
-:1046A0000001F7060C3EC77C7400203A0010E600BB
-:1046B00049F000000001FF8200108682FF38F704F5
-:1046C0003558F5846F58F685355407380001202E8B
-:1046D0000021E2004708F7053558F7042D38F68623
-:1046E0002C2806380001F6052D38773900022032D3
-:1046F0000044E60046FCB5BA6802F0052D38F482A5
-:104700000022E000470CF4856F58F0056F54F684E2
-:10471000352C0000000187360094C4840000C03AA4
-:104720004A00E60047710000000186360094F684D6
-:1047300035540000000176B4FFF0F7043554969626
-:10474000FFF4473900009716FFF0C6B47000F70475
-:10475000354877B4000F703EFFE107380024E600CB
-:104760004769C638600006B40001C7046E00F7331D
-:104770002800F6843544000000018736000400005C
-:104780000001203A000FE20047BD073800018736DC
-:10479000000C00000001073800019736000C873636
-:1047A000000CE00047D000000001F7043528F68235
-:1047B000000107380008E0004968F7053544203A51
-:1047C0000010E60047CC00000001F7020000973619
-:1047D0000004F704353CF684352807380001F70556
-:1047E000353CF704353C8736141C000000010738BF
-:1047F00000019736141CF704760486B6141CF604E0
-:1048000075FC07380001F684760000000001C03A0C
-:104810006A00E600481CF7057604F0057604F68485
-:104820007604F7047608F00575FCC0367200470C74
-:10483000000120320000E6004881F70575F8F70412
-:104840007648F4867218C03A4A00470C0001203AB4
-:104850000000E6004881F6862C28F7042D38000079
-:10486000000106380001F6052D3877390002F48280
-:10487000000E20320044E6004880B4BA6802F00519
-:104880002D38F5020000202A0002EE004968F68269
-:104890000000F68435280000000187360000000083
-:1048A0000001203A0002E600493C05B40008959357
-:1048B000FFFC9516FFEC9596FFE89696FFE40788B7
-:1048C0000008E0005EDC9793FFFC8516FFEC859600
-:1048D000FFE88696FFE420220000E600492CF7025C
-:1048E00000008636000C000000012032000FE200BC
-:1048F000491100000001873600140000000107384C
-:1049000000019736001487360014E000492CF702A6
-:10491000000076B10002C6B4600077350005C738E4
-:104920006A00C738600007380010C72C7000203AB2
-:104930000000E60047A8F705352CF6843528F70473
-:104940006F4C00000001C0367200E600495C07347D
-:104950001494F4846F44E0004960F4853528F70529
-:104960003528E00048840528000120360000E600D4
-:1049700049A1F6862C28F7042D38000000010638DE
-:104980000001F6052D3877390002F482000D20323F
-:104990000044E60049A8B4BA6802E00049A8F0055E
-:1049A0002D38F4820001F4853524F6843528F70487
-:1049B0006F44F48632F4C0367200E60049F0F485A4
-:1049C0003530F704E0180000000177B8001F703E92
-:1049D000FFE1E60049F1000000010F814000F7040B
-:1049E00079C80000000107380001F70579C8F7040D
-:1049F00079C88796FFFC8296FFF802140000013CFC
-:104A00000000000000019293FFFC029000082210B9
-:104A10000014F70475F800000001203A0000E600D9
-:104A20004A2DF68675F8E0004A40F6820000F70449
-:104A300076040000000177390002C738680086BAA2
-:104A40000018F7046F5400000001203A0000E6004F
-:104A50004A64F6853548F4820001F4856F54E0001D
-:104A60004A70F7020001F4820008F4856F58F702DB
-:104A70000000203A0000E6004A88F4820004F48630
-:104A8000340CE0004ED8F4853530F6843548F60411
-:104A9000352CF4B7280007340002F4820001F4BB7F
-:104AA00028008732008CF482000197360018873284
-:104AB0000090F4856F509736000484B200840000A3
-:104AC000000194B6001084B200880000000194B682
-:104AD000001484B600100000000194B6000884B6EB
-:104AE00000140000000194B6000C84B2009800008D
-:104AF0000001F4853554F48200019482FF80F504AE
-:104B00003554F4863498F48535309502FF3885B2F3
-:104B1000000006B400249582FF3C9682FF40873255
-:104B20000004F68535509702FF4486B20004F00574
-:104B3000354CF70435409516FFF49596FFF4C738C9
-:104B40006800F7053540F584352886B20004872EC5
-:104B5000141400000001C7386800972E141487321F
-:104B6000008000000001203A0001EE004ED8F70658
-:104B70000C3EC07E7400E6004B8C00000001C07E3D
-:104B80007400E6004B7D00000001F7060C3EC77C78
-:104B90007400203A0010E6004ED800000001FF82A9
-:104BA00000108682FF38F7043558F5846F58F68573
-:104BB000355407380001202E0021E2004BF0F705A4
-:104BC0003558F7042D38F6862C2806380001F605EE
-:104BD0002D387739000220320044E6004BE4B5BAA4
-:104BE0006802F0052D38F4820022E0004BF4F485D1
-:104BF0006F58F0056F54F684352C0000000187369D
-:104C00000094C4840000C03A4A00E6004C590000F9
-:104C1000000186360094F68435540000000176B415
-:104C2000FFF0F70435549696FFF4473900009716C5
-:104C3000FFF0C6B47000F704354877B4000F703E3B
-:104C4000FFE107380024E6004C51C638600006B486
-:104C50000001C7046E00F7332800F68435440000D5
-:104C600000018736000400000001203A000FE20036
-:104C70004CA5073800018736000C000000010738FA
-:104C800000019736000C8736000CE0004CB800009D
-:104C90000001F7043528F682000107380008E0001B
-:104CA0004E50F7053544203A0010E6004CB40000A1
-:104CB0000001F702000097360004F704353CF68443
-:104CC000352807380001F705353CF704353C8736B1
-:104CD000141C00000001073800019736141CF7046B
-:104CE000760486B6141CF60475FC07380001F684B9
-:104CF000760000000001C03A6A00E6004D04F705A6
-:104D00007604F0057604F6847604F7047608F00558
-:104D100075FCC0367200470C000120320000E6002E
-:104D20004D69F70575F8F7047648F4867218C03AAD
-:104D30004A00470C0001203A0000E6004D69F68663
-:104D40002C28F7042D380000000106380001F60574
-:104D50002D3877390002F482000E20320044E6003C
-:104D60004D68B4BA6802F0052D38F5020000202A1B
-:104D70000002EE004E50F6820000F6843528000056
-:104D800000018736000000000001203A0002E60022
-:104D90004E2405B400089593FFFC9516FFEC9596FC
-:104DA000FFE89696FFE407880008E0005EDC979332
-:104DB000FFFC8516FFEC8596FFE88696FFE420222F
-:104DC0000000E6004E14F70200008636000C0000DA
-:104DD00000012032000FE2004DF90000000187368B
-:104DE00000140000000107380001973600148736D0
-:104DF0000014E0004E14F702000076B10002C6B4C1
-:104E0000600077350005C7386A00C738600007388A
-:104E10000010C72C7000203A0000E6004C90F70507
-:104E2000352CF6843528F7046F4C00000001C0369D
-:104E30007200E6004E4407341494F4846F44E0009A
-:104E40004E48F4853528F7053528E0004D6C0528D7
-:104E5000000120360000E6004E89F6862C28F70473
-:104E60002D380000000106380001F6052D3877398D
-:104E70000002F482000D20320044E6004E90B4BAE5
-:104E80006802E0004E90F0052D38F4820001F485B0
-:104E90003524F6843528F7046F44F48632F4C0369E
-:104EA0007200E6004ED8F4853530F704E0180000B3
-:104EB000000177B8001F703EFFE1E6004ED9000008
-:104EC00000010F814000F70479C800000001073895
-:104ED0000001F70579C8F70479C88796FFFC829628
-:104EE000FFF802140000013C000000000001929352
-:104EF000FFFC0290000822100014F6843548F604E6
-:104F0000352CF4820004F4B7280007340002F48240
-:104F10000001F4BB28008732008CF4820001973630
-:104F2000001887320090F4856F509736000484B2E1
-:104F300000840000000194B6001084B200880000D4
-:104F4000000194B6001484B600100000000194B66D
-:104F5000000884B600140000000194B6000C84B26E
-:104F6000009800000001F4853554F4820001948219
-:104F7000FF80F5043554F4863498F4853530950275
-:104F8000FF3885B2000006B400249582FF3C96826B
-:104F9000FF4087320004F68535509702FF4486B201
-:104FA0000004F005354CF70435409516FFF495964E
-:104FB000FFF4C7386800F7053540F584352886B218
-:104FC0000004872E141400000001C7386800972ED3
-:104FD00014148732008000000001203A0001EE0026
-:104FE000534CF7060C3EC07E7400E60050000000F3
-:104FF0000001C07E7400E6004FF100000001F706DA
-:105000000C3EC77C7400203A0010E600534C0000B0
-:105010000001FF8200108682FF38F7043558F584BE
-:105020006F58F685355407380001202E0021E20024
-:105030005064F7053558F7042D38F6862C280638C5
-:105040000001F6052D387739000220320044E600D1
-:105050005058B5BA6802F0052D38F4820022E000FD
-:105060005068F4856F58F0056F54F684352C0000B5
-:10507000000187360094C4840000C03A4A00E6006C
-:1050800050CD0000000186360094F68435540000AF
-:10509000000176B4FFF0F70435549696FFF44739D3
-:1050A00000009716FFF0C6B47000F704354877B4D7
-:1050B000000F703EFFE107380024E60050C5C638F7
-:1050C000600006B40001C7046E00F7332800F684C0
-:1050D0003544000000018736000400000001203A3A
-:1050E000000FE2005119073800018736000C00005C
-:1050F0000001073800019736000C8736000CE000ED
-:10510000512C00000001F7043528F6820001073811
-:105110000008E00052C4F7053544203A0010E600CC
-:10512000512800000001F702000097360004F70440
-:10513000353CF684352807380001F705353CF7047F
-:10514000353C8736141C00000001073800019736F3
-:10515000141CF704760486B6141CF60475FC073894
-:105160000001F684760000000001C03A6A00E60003
-:105170005178F7057604F0057604F6847604F70492
-:105180007608F00575FCC0367200470C000120322D
-:105190000000E60051DDF70575F8F7047648F4865F
-:1051A0007218C03A4A00470C0001203A0000E6009D
-:1051B00051DDF6862C28F7042D3800000001063852
-:1051C0000001F6052D3877390002F482000E2032F6
-:1051D0000044E60051DCB4BA6802F0052D38F5024F
-:1051E0000000202A0002EE0052C4F6820000F6847D
-:1051F0003528000000018736000000000001203A39
-:105200000002E600529805B400089593FFFC95163D
-:10521000FFEC9596FFE89696FFE407880008E0000B
-:105220005EDC9793FFFC8516FFEC8596FFE886967B
-:10523000FFE420220000E6005288F70200008636D4
-:10524000000C000000012032000FE200526D00004F
-:10525000000187360014000000010738000197366E
-:10526000001487360014E0005288F702000076B17F
-:105270000002C6B4600077350005C7386A00C73839
-:10528000600007380010C72C7000203A0000E600CC
-:105290005104F705352CF6843528F7046F4C0000CF
-:1052A0000001C0367200E60052B807341494F4844A
-:1052B0006F44E00052BCF4853528F7053528E0003E
-:1052C00051E00528000120360000E60052FDF68678
-:1052D0002C28F7042D380000000106380001F605DF
-:1052E0002D3877390002F482000D20320044E600A8
-:1052F0005304B4BA6802E0005304F0052D38F48278
-:105300000001F4853524F6843528F7046F44F486CB
-:1053100032F4C0367200E600534CF4853530F704A1
-:10532000E0180000000177B8001F703EFFE1E600C2
-:10533000534D000000010F814000F70479C80000C0
-:10534000000107380001F70579C8F70479C8879686
-:10535000FFFC8296FFF802140000013C00000000F0
-:1053600000019293FFFC0290000822100014F484C4
-:105370003554F684354CF584352C9482FF3876B557
-:105380000003A52E6802000000019502FF3CF38493
-:105390003550C6AC68009382FF4087360004000099
-:1053A00000019702FF4486360004F70435400000F0
-:1053B0000001C7386000F7053540F604352886B689
-:1053C0000004873214149496FFF4C73868009732AB
-:1053D0001414872E008000000001203A0001EE0026
-:1053E00057509516FFF4F7060C3EC07E7400E60099
-:1053F000540400000001C07E7400E60053F5000074
-:105400000001F7060C3EC77C7400203A0010E6004D
-:10541000575000000001FF8200108682FF38F70419
-:105420003558F5846F58F685355407380001202E1D
-:105430000021E2005468F7053558F7042D38F68648
-:105440002C2806380001F6052D3877390002203265
-:105450000044E600545CB5BA6802F0052D38F382CA
-:105460000022E000546CF3856F58F0056F54F68409
-:10547000352C0000000187360094C3840000C03A38
-:105480003A00E60054D10000000186360094F6840C
-:1054900035540000000176B4FFF0F70435549696B9
-:1054A000FFF4473900009716FFF0C6B47000F70408
-:1054B000354877B4000F703EFFE107380024E6005E
-:1054C00054C9C638600006B40001C7046E00F73343
-:1054D0002800F684354400000001873600040000EF
-:1054E0000001203A000FE200551D07380001873601
-:1054F000000C00000001073800019736000C8736C9
-:10550000000CE000553000000001F7043528F68259
-:10551000000107380008E00056C8F7053544203A76
-:105520000010E600552C00000001F702000097363D
-:105530000004F704353CF684352807380001F705E8
-:10554000353CF704353C8736141C00000001073851
-:1055500000019736141CF704760486B6141CF60472
-:1055600075FC07380001F684760000000001C03A9F
-:105570006A00E600557CF7057604F0057604F684AB
-:105580007604F7047608F00575FCC0367200470C07
-:10559000000120320000E60055E1F70575F8F70438
-:1055A0007648F3867218C03A3A00470C0001203A58
-:1055B0000000E60055E1F6862C28F7042D3800009F
-:1055C000000106380001F6052D3877390002F38214
-:1055D000000E20320044E60055E0B3BA6802F00540
-:1055E0002D38F5020000202A0002EE0056C8F6828F
-:1055F0000000F68435280000000187360000000016
-:105600000001203A0002E600569C05B4000895937C
-:10561000FFFC9516FFEC9596FFE89696FFE4078849
-:105620000008E0005EDC9793FFFC8516FFEC859692
-:10563000FFE88696FFE420220000E600568CF70281
-:1056400000008636000C000000012032000FE2004E
-:105650005671000000018736001400000001073871
-:1056600000019736001487360014E000568CF702CC
-:10567000000076B10002C6B4600077350005C73877
-:105680006A00C738600007380010C72C7000203A45
-:105690000000E6005508F705352CF6843528F70498
-:1056A0006F4C00000001C0367200E60056BC0734A3
-:1056B0001494F3846F44E00056C0F3853528F70551
-:1056C0003528E00055E40528000120360000E600FA
-:1056D0005701F6862C28F7042D3800000001063803
-:1056E0000001F6052D3877390002F382000D2032D3
-:1056F0000044E6005708B3BA6802E0005708F00516
-:105700002D38F3820001F3853524F6843528F7041B
-:105710006F44F38632F4C0367200E6005750F385CA
-:105720003530F704E0180000000177B8001F703E24
-:10573000FFE1E6005751000000010F814000F7042F
-:1057400079C80000000107380001F70579C8F7049F
-:1057500079C88796FFFC8296FFF802140000013C8E
-:105760000000000000019293FFFC0290000822104C
-:1057700000148702FF38F384352CF7053554871E53
-:105780000080F504354C27380001C02A7200E6007D
-:105790005A4C00000001F5846F5800000001202ED3
-:1057A0000021E20057D8F6862C28F7042D38000097
-:1057B000000106380001F6052D3877390002203245
-:1057C0000044E60057CCB5BA6802F0052D38F30264
-:1057D0000022E00057DCF3056F58F0056F54F684A3
-:1057E000352C0000000187360094C3040000C03A45
-:1057F0003200E60058410000000186360094F6842D
-:1058000035540000000176B4FFF0F7043554969645
-:10581000FFF4473900009716FFF0C6B47000F70494
-:10582000354877B4000F703EFFE107380024E600EA
-:105830005839C638600006B40001C7046E00F7335B
-:105840002800F6843544000000018736000400007B
-:105850000001203A000FE200588D0738000187361A
-:10586000000C00000001073800019736000C873655
-:10587000000CE00058A000000001F7043528F68273
-:10588000000107380008E0005A38F7053544203A8F
-:105890000010E600589C00000001F7020000973657
-:1058A0000004F704353CF684352807380001F70575
-:1058B000353CF704353C8736141C000000010738DE
-:1058C00000019736141CF704760486B6141CF604FF
-:1058D00075FC07380001F684760000000001C03A2C
-:1058E0006A00E60058ECF7057604F0057604F684C5
-:1058F0007604F7047608F00575FCC0367200470C94
-:10590000000120320000E6005951F70575F8F70450
-:105910007648F3067218C03A3200470C0001203A6C
-:105920000000E6005951F6862C28F7042D380000B7
-:10593000000106380001F6052D3877390002F30220
-:10594000000E20320044E6005950B33A6802F005D8
-:105950002D38F5020000202A0002EE005A38F682A7
-:105960000000F684352800000001873600000000A2
-:105970000001203A0002E6005A0C05B40008959395
-:10598000FFFC9516FFEC9596FFE89696FFE40788D6
-:105990000008E0005EDC9793FFFC8516FFEC85961F
-:1059A000FFE88696FFE420220000E60059FCF7029B
-:1059B00000008636000C000000012032000FE200DB
-:1059C00059E100000001873600140000000107388B
-:1059D00000019736001487360014E00059FCF702E6
-:1059E000000076B10002C6B4600077350005C73804
-:1059F0006A00C738600007380010C72C7000203AD2
-:105A00000000E6005878F705352CF6843528F704B1
-:105A10006F4C00000001C0367200E6005A2C0734BB
-:105A20001494F3046F44E0005A30F3053528F70569
-:105A30003528E00059540528000120360000E60012
-:105A40005DC4F3020001E0005DF000000001772971
-:105A50000003C71C7000873A00040528000176A9DE
-:105A60000003F4843554F60435509482FF38A41EA4
-:105A70006802C63070009402FF3C9602FF40C69C4C
-:105A8000680087360004000000019702FF4485B6D5
-:105A90000004F704354000000001C7385800F7053E
-:105AA000354085B60004F505354CF6843528F605F5
-:105AB0003550873614149496FFF4C738580097363B
-:105AC0001414871E008000000001203A0001EE003F
-:105AD0005E3C9416FFF4F7060C3EC07E7400E600B0
-:105AE0005AF400000001C07E7400E6005AE5000090
-:105AF0000001F7060C3EC77C7400203A0010E60057
-:105B00005E3C00000001FF8200108682FF38F7042F
-:105B10003558F5846F58F685355407380001202E26
-:105B20000021E2005B58F7053558F7042D38F6865A
-:105B30002C2806380001F6052D387739000220326E
-:105B40000044E6005B4CB5BA6802F0052D38F3025C
-:105B50000022E0005B5CF3056F58F0056F54F6849B
-:105B6000352C0000000187360094C3040000C03AC1
-:105B70003200E6005BC10000000186360094F68426
-:105B800035540000000176B4FFF0F70435549696C2
-:105B9000FFF4473900009716FFF0C6B47000F70411
-:105BA000354877B4000F703EFFE107380024E60067
-:105BB0005BB9C638600006B40001C7046E00F73355
-:105BC0002800F684354400000001873600040000F8
-:105BD0000001203A000FE2005C0D07380001873613
-:105BE000000C00000001073800019736000C8736D2
-:105BF000000CE0005C2000000001F7043528F6826C
-:105C0000000107380008E0005DB8F7053544203A88
-:105C10000010E6005C1C00000001F702000097364F
-:105C20000004F704353CF684352807380001F705F1
-:105C3000353CF704353C8736141C0000000107385A
-:105C400000019736141CF704760486B6141CF6047B
-:105C500075FC07380001F684760000000001C03AA8
-:105C60006A00E6005C6CF7057604F0057604F684BD
-:105C70007604F7047608F00575FCC0367200470C10
-:105C8000000120320000E6005CD1F70575F8F7044A
-:105C90007648F3067218C03A3200470C0001203AE9
-:105CA0000000E6005CD1F6862C28F7042D380000B1
-:105CB000000106380001F6052D3877390002F3029D
-:105CC000000E20320044E6005CD0B33A6802F005D2
-:105CD0002D38F5020000202A0002EE005DB8F682A1
-:105CE0000000F6843528000000018736000000001F
-:105CF0000001203A0002E6005D8C05B4000895938F
-:105D0000FFFC9516FFEC9596FFE89696FFE4078852
-:105D10000008E0005EDC9793FFFC8516FFEC85969B
-:105D2000FFE88696FFE420220000E6005D7CF70293
-:105D300000008636000C000000012032000FE20057
-:105D40005D61000000018736001400000001073883
-:105D500000019736001487360014E0005D7CF702DE
-:105D6000000076B10002C6B4600077350005C73880
-:105D70006A00C738600007380010C72C7000203A4E
-:105D80000000E6005BF8F705352CF6843528F704AB
-:105D90006F4C00000001C0367200E6005DAC0734B5
-:105DA0001494F3046F44E0005DB0F3053528F70563
-:105DB0003528E0005CD40528000120360000E6000C
-:105DC0005DF1F3020001F7042D38F6862C28063821
-:105DD0000001F6052D3877390002F302000D20325C
-:105DE0000044E6005DF4B33A6802E0005DF4F005BB
-:105DF0002D38F3053524F6843528F7046F44F3066F
-:105E000032F4C0367200E6005E3CF3053530F7042C
-:105E1000E0180000000177B8001F703EFFE1E600C7
-:105E20005E3D000000010F814000F70479C80000CA
-:105E3000000107380001F70579C8F70479C887968B
-:105E4000FFFC8296FFF802140000013C00000000F5
-:105E500000019293FFFC02900008F706353097137B
-:105E6000FFFCF70632F49713FFFC07880008E000F8
-:105E700014F49793FFFCF70635309713FFFCF706F1
-:105E800033809713FFFC07880008E00014F4979311
-:105E9000FFFCF70635309713FFFCF706340C971319
-:105EA000FFFC07880008E00014F49793FFFCF70656
-:105EB00035309713FFFCF70634989713FFFC0788DB
-:105EC0000008E00014F49793FFFC8796FFFC82968D
-:105ED000FFF802140000013C000000000001929352
-:105EE000FFFC0290000886160000000000018732C7
-:105EF000000400000001203A000F86B20000C538FF
-:105F00000000EE005F2CC5B400002036000FEE004C
-:105F10005F2C00000001203A0000EC005F2D000023
-:105F2000000120360000EC005F48000000018732CD
-:105F3000000C00000001073800019732000C873286
-:105F4000000CE0005F50F4020000C02A5A00440C2C
-:105F500000018796FFFC8296FFF802140004013CC2
-:105F6000000000000001000000009293FFFC02907E
-:105F70000008F68635609693FFFCF68642309693CD
-:105F8000FFFC07880008E00015489793FFFCF682A5
-:105F900066F89693FFFCF78200179793FFFCF6864E
-:105FA00035609693FFFC07880008E000161C979365
-:105FB000FFFCF68269809693FFFCF78200189793A6
-:105FC000FFFCF68635609693FFFC07880008E0002A
-:105FD000161C9793FFFCF6826B509693FFFCF7829A
-:105FE00000169793FFFCF68635609693FFFC0788B2
-:105FF0000008E000161C9793FFFCF68261789693E8
-:10600000FFFCF782001F9793FFFCF686356096939E
-:10601000FFFC07880008E000161C9793FFFCF6823F
-:10602000627C9693FFFCF78200209793FFFCF68634
-:1060300035609693FFFC07880008E000161C9793D4
-:10604000FFFCF68266F89693FFFCF78200179793A1
-:10605000FFFCF68635EC9693FFFC07880008E0000D
-:10606000161C9793FFFCF68269809693FFFCF782DB
-:1060700000189793FFFCF68635EC9693FFFC078893
-:106080000008E000161C9793FFFCF6826B50969375
-:10609000FFFCF78200169793FFFCF68635EC96938B
-:1060A000FFFC07880008E000161C9793FFFCF682AF
-:1060B00061789693FFFCF782001F9793FFFCF686AA
-:1060C00035EC9693FFFC07880008E000161C9793B8
-:1060D000FFFCF682627C9693FFFCF7820020979388
-:1060E000FFFCF68635EC9693FFFC07880008E0007D
-:1060F000161C9793FFFCF704E02800000001203AEB
-:106100000000E600611500000001F704E028E0004F
-:10611000611877390002F70200F0F7054228F70608
-:10612000408AF03B2800F706408CF03B2800F7023D
-:106130000000F7057AC0F7057AB8F7057AB0F705D9
-:106140007AC8F682C3509693FFFCF68200169693A7
-:10615000FFFCF68642309693FFFC07880008E001BA
-:106160001EC09793FFFC8796FFFC8296FFF80214EF
-:106170000000013C0000000000019293FFFC02902F
-:106180000008F6046F340000000120320000E60031
-:1061900061ED76B1001E8732000076B4FFE5C738A6
-:1061A0006FC07739FFF0203A0007E60061EC06B0D7
-:1061B00000028736000076B5001E76B4FFE5C738CA
-:1061C0006FC07739FFF0203A0001E60061ECF50678
-:1061D00035ECF704423000000001C03A5200470C91
-:1061E0000001203A0000E6006211F5820000F70489
-:1061F00042A0F60642A276B1001E76B4FFE5C7388B
-:106200006FC07739FFF007380001E0006268F733AC
-:1062100028008732000400000001F705E00086B284
-:106220000008203A0000E600623CF685E0042036D3
-:106230000000E6006240202E0000F5820001202EC2
-:106240000000E6006265F60642A2F70442A076B1BD
-:10625000001E76B4FFE5C7386FC07739FFF0073806
-:106260000001F7332800F00542288796FFFC82964C
-:10627000FFF802140000013C0000000000019293AE
-:10628000FFFC02900008F704423CF6846F340738A4
-:10629000000120360000E60062B1F705423C873677
-:1062A0000000F59E0002C03A5A00E60062BDF58685
-:1062B00035ECF70442A0E00062DCF60642A2F704E7
-:1062C000423000000001C03A5A00470C0001203A59
-:1062D0000000E60062F9F60642A4F70442A476B193
-:1062E000001E76B4FFE5C7386FC07739FFF0073876
-:1062F0000001E000630CF73328009693FFFC078849
-:106300000008E00063209793FFFCF0054228879681
-:10631000FFFC8296FFF802140000013C0000000020
-:1063200000019293FFFC02900008221000208316C7
-:10633000000000000001871A001800000001203A48
-:106340000000E600636CF7020000839A001C000066
-:106350000001F3857AC0849A0014F7057AC8F485A1
-:106360007AB0F7057AB88316000000000001869A1B
-:106370000014F7047AB000000001C0367200E60095
-:1063800063D0F6020000869A001CF7047AC0000071
-:106390000001C0367200E60063D000000001869A5A
-:1063A0000018F7047AB800000001C0367200E60059
-:1063B00063D000000001869A0020F7047AC800002C
-:1063C0000001C7386800203A0064EE0063D920322B
-:1063D0000000F602000120320000E60064580000D0
-:1063E00000018396000000000001871E00180000D5
-:1063F0000001203A0000E600643CF7020000F705C7
-:106400004080F7054084F6846E50F482FFFF831EBF
-:10641000000CF4854F5493360010839E0010849630
-:10642000000093B6001484A600080000000194B692
-:106430001DDCF6820064F6854A98F7054A9C8316AF
-:10644000000000000001871A002000000001203A2F
-:106450000000EE00647CF3820000F70442A4F6061C
-:1064600042A676B1001E76B4FFE5C7386FC0773913
-:10647000FFF007380001E00066E4F7332800939648
-:10648000FFF484160000F48642C89496FFECF302F1
-:10649000000C9316FFE4839600008496FFF4871E99
-:1064A000002000000001C0267200EC006648F38660
-:1064B0004A9884A200248316FFE4C5040000B49A1D
-:1064C0003802C7183800832200288396FFF4849688
-:1064D000FFE4933A000493BA0008F604E000F306E0
-:1064E0004A98A6A63002F5820000C0326A00E60093
-:1064F0006510C6380000F684E0048732000400000E
-:106500000001C0367200E6006514202E0000F582FE
-:106510000001202E0000E600652100000001F502C8
-:106520000000F684E0008732000000000001C03661
-:106530007200E200655CF5820000C0367200E60081
-:106540006564202E0000F684E00487320004000019
-:106550000001C0367200E2006565202E0000F58261
-:106560000001202E0000E6006575202A0000F502DB
-:106570000001202A0000E6006588000000018396E3
-:10658000FFF400000001F3854F548722002C76A110
-:10659000001E76B4FFE505A0002E762D001E763095
-:1065A000FFE5F48200009496FFDC8316FFEC2026C2
-:1065B0000007C7386FC07738FFF0F71B2800872E19
-:1065C000000006980002C73867C07738FFF0E20085
-:1065D000661CF73728008516FFEC8596FFDC000067
-:1065E0000001C72C400086BA0030062800040528A8
-:1065F000000205AC00028396FFDC7739001E773875
-:10660000FFE5039C00019396FFDC201E0007C6B443
-:1066100077C076B4FFF0E20065E1F6B3280004200D
-:10662000001C8496FFEC8316FFE48396FFF404A419
-:1066300000149496FFEC0318000C9316FFE4039CDF
-:106640000001E00064949396FFF48496000000003B
-:1066500000018726002000000001F7054A9C85A65E
-:106660000020F7047AB80000000107380001F705A0
-:106670007AB8F7047AB8F6847AC886260018C6B4C1
-:1066800058008726001C0000000127380001C03296
-:106690007200470C0001203A0000E60066E5F6852E
-:1066A0007AC883260008F7046E50F3053B6483A67E
-:1066B0000008F682000093BA1DDC84A6000C831645
-:1066C000000094BA0010831A0010F6857AC8933A35
-:1066D0000014F7020001F7054084F6857AC0F685BC
-:1066E0007AB8F6857AB08796FFFC8296FFF8021496
-:1066F0000004013C0000000000019293FFFC0290A6
-:10670000000822100008F3846F3400000001871E87
-:106710000018F684E01C00000001C0367200EC0096
-:106720006729F7020001F7020000203A0000E600A6
-:1067300067E8F5820001F704E01C869E001800005F
-:106740000001C03A6A00470C0001203A0000E60050
-:1067500067E9C5840000869E0010F704E000F60299
-:106760000000C0367200E6006788051C0010869E97
-:106770000014F704E00400000001C0367200E600D7
-:10678000678C20320000F602000120320000E60093
-:10679000679900000001F582000086AA0000F70456
-:1067A000E00000000001C0367200E20067D4F6028B
-:1067B0000000C0367200E60067DC2032000086AAC6
-:1067C0000004F704E00400000001C0367200E2009B
-:1067D00067DD20320000F602000120320000E600F2
-:1067E00067ED202E0000F5820001202E0000E6005B
-:1067F0006810F606429CF704429C76B1001E76B4FF
-:10680000FFE5C7386FC07739FFF007380001F7336D
-:106810002800F70475F475ACFFE1203A0000E600AB
-:1068200068459596FFF4F7044298F606429876B1CB
-:10683000001E76B4FFE5C7386FC07739FFF0073820
-:106840000001F7332800871E0020041C002076A1D9
-:10685000001E76B4FFE5C7386FC07739FFF0203AE5
-:106860000008EE0068C4F3061554F5020000059C0C
-:106870000022C4AC0000F60200018722000076A1CD
-:10688000001E76B4FFE5C7386FC07739FFF0C02A25
-:106890007200EC0068C0C6A46000A726600276B54E
-:1068A000001E76B4FFE505280001C7386FC07739B0
-:1068B000FFE8F72F680005AC0001E00068780630BB
-:1068C0000002F30615549313FFFCF704E0240000C4
-:1068D00000019713FFFCF704E01C00000001971370
-:1068E000FFFCF306E0009313FFFC9393FFFCF3021D
-:1068F00000019313FFFC07880008E000EE64979303
-:10690000FFFC20220000E6006928F606429EF704FC
-:10691000429C76B1001E76B4FFE5C7386FC0773968
-:10692000FFF007380001F73328008316FFF400005A
-:106930000001201A0000E600696CF30635ECF7044C
-:10694000423000000001C03A3200470C0001203AFA
-:106950000000E600696DF0054228F3063560F30596
-:10696000423007880008E000789C9793FFFC8796E8
-:10697000FFFC8296FFF802140000013C00000000BA
-:1069800000019293FFFC0290000822100004F5041D
-:106990006F34F7044240862A001807380001F68455
-:1069A000E01CF7054240C0366200EC0069B5F70212
-:1069B0000001F7020000203A0000E6006A80F702BA
-:1069C0000001F704E01C86AA001800000001C03A8C
-:1069D0006A00470C0001203A0000E6006A7DC58489
-:1069E000000086AA0010F704E000F6020000C0369E
-:1069F0007200E6006A1404A8001086AA0014F704C6
-:106A0000E00400000001C0367200E6006A1820327F
-:106A10000000F602000120320000E6006A250000B6
-:106A20000001F582000086A60000F704E0000000E7
-:106A30000001C0367200E2006A60F6020000C03653
-:106A40007200E6006A682032000086A60004F7049F
-:106A5000E00400000001C0367200E2006A692032E2
-:106A60000000F602000120320000E6006A81C72C17
-:106A70000000F5820001E0006A80C72C0000C70416
-:106A80000000203A0000EE006B3DF686408AF704D5
-:106A9000408876B5001E76B4FFE5C7386FC07738FA
-:106AA000FFF0203A0000E6006B3CF6820000F6851D
-:106AB0004080F68540849693FFFC9693FFFCF70494
-:106AC000E01C000000019713FFFCF386E0009393A5
-:106AD000FFFC9513FFFCF38200029393FFFC969654
-:106AE000FFF407880008E000EE649793FFFCF405CC
-:106AF00040848696FFF4F7046E50F38635ECF685F5
-:106B00004090F6854094873A1DDCF6854228F705CB
-:106B10003B64F7044230F4054080C03A3A00470C29
-:106B20000001203A0000E6006B3DF3863560F385F6
-:106B3000423007880008E000789C9793FFFC879616
-:106B4000FFFC8296FFF802140000013C00000000E8
-:106B500000019293FFFC02900008F4864230949367
-:106B6000FFFC07880008E00120E49793FFFC202247
-:106B70000000E6006DD9F5820000F704408CF606AF
-:106B8000408C7631001EF68442287630FFE506B44C
-:106B90000001C73867C07738FFF0203A0000E600F0
-:106BA0006BC8F6854228F7044088F686408A76B599
-:106BB000001E76B4FFE5C7386FC07738FFF0203A83
-:106BC0000000E6006D0D00000001F704408CF68621
-:106BD000408C76B5001E76B4FFE5C7386FC07738B5
-:106BE000FFF0203A0000E6006C35F606408AF70414
-:106BF000408876B1001E76B4FFE5C7386FC077389D
-:106C0000FFF0203A0000E6006C34F4863678F70492
-:106C1000424400000001C03A4A00470C0001203AFB
-:106C20000000E6006C35F4820001F4B32800E000B7
-:106C30006D10F005422CF704408CF506408C76A9C7
-:106C4000001E76B4FFE5C7386FC07738FFF0203AF2
-:106C50000000E6006CC1F606408AF704408876B171
-:106C6000001E76B4FFE5C7386FC07738FFF0203AD2
-:106C70000000E6006CC100000001F704422C000097
-:106C8000000107380001203A0009EE006D11F705F8
-:106C9000422CF02B2800F0332800F5820001F70485
-:106CA0004294F606429476B1001E76B4FFE5C738EA
-:106CB0006FC07739FFF007380001E0006D10F7333F
-:106CC0002800F704408CF686408C76B5001E76B41A
-:106CD000FFE5C7386FC07738FFF0203A0000E600C4
-:106CE0006D14202E0000F7044088F606408A76B125
-:106CF000001E76B4FFE5C7386FC07738FFF0203A42
-:106D00000000E6006D15202E0000F0332800F5820B
-:106D10000001202E0000E6006DB5F48635ECF70486
-:106D2000423000000001C03A4A00470C0001203AFE
-:106D30000000E6006D5900000001F704E0280000A3
-:106D40000001203A0000E6006D79F682003CF684EE
-:106D5000E028E0006D7800000001F704E028000062
-:106D60000001203A0000E6006D79F68200F0F70499
-:106D7000E0280000000176B90002F7044228000074
-:106D80000001C03A6A00EC006DB5F6862C28F704C5
-:106D90002D38F005422806380001F6052D387739E0
-:106DA0000002F482001920320044E6006DB4B4BA47
-:106DB0006802F0052D38F482C3509493FFFCF482EE
-:106DC00000169493FFFCF48642309493FFFC0788EE
-:106DD0000008E0011EC09793FFFC8796FFFC829697
-:106DE000FFF802140000013C000000000001929333
-:106DF000FFFC0290000822100004F5863678959377
-:106E0000FFFCF58642449593FFFC07880008E000EC
-:106E100015489793FFFCF58274189593FFFCF58253
-:106E200000199593FFFCF58636789593FFFC07884B
-:106E30000008E000161C9793FFFCF58274AC959354
-:106E4000FFFCF782001D9793FFFCF58637049593AE
-:106E5000FFFC07880008E000161C9793FFFCF582F2
-:106E600078009593FFFCF782001B9793FFFCF58653
-:106E700037049593FFFC07880008E000161C9793E1
-:106E8000FFFCF58278FC9593FFFCF782001A97933C
-:106E9000FFFCF58637909593FFFC07880008E0001B
-:106EA000161C9793FFFCF58280D89593FFFCF78220
-:106EB000001B9793FFFCF58637909593FFFC07889E
-:106EC0000008E000161C9793FFFCF58281749593EF
-:106ED000FFFCF782001D9793FFFCF586381C959305
-:106EE000FFFC07880008E000161C9793FFFCF58262
-:106EF00087749593FFFCF782001B9793FFFCF58640
-:106F0000381C9593FFFC07880008E000161C979337
-:106F1000FFFCF58294F89593FFFCF782001B979392
-:106F2000FFFCF58639349593FFFC07880008E000E4
-:106F3000161C9793FFFCF5828A009593FFFCF7825D
-:106F4000001C9793FFFCF58639349593FFFC078866
-:106F50000008E000161C9793FFFCF5828E089593BD
-:106F6000FFFCF782001A9793FFFCF586393495935E
-:106F7000FFFC07880008E000161C9793FFFCF582D1
-:106F8000969C9593FFFCF782001E9793FFFCF58675
-:106F900038A89593FFFC07880008E000161C97931B
-:106FA000FFFCF5829B2C9593FFFCF782001B9793C7
-:106FB000FFFCF58638A89593FFFC07880008E000E1
-:106FC000161C9793FFFCF582A2DC9593FFFCF782D9
-:106FD000001E9793FFFCF5863AD89593FFFC07882F
-:106FE0000008E000161C9793FFFCF5829E549593D1
-:106FF000FFFCF782001B9793FFFCF5863AD8959328
-:10700000FFFC07880008E000161C9793FFFCF58240
-:10701000A3C09593FFFCF782001C9793FFFCF586B5
-:1070200039C09593FFFC07880008E000161C979371
-:10703000FFFCF582A7649593FFFCF782001E9793EF
-:10704000FFFCF58639C09593FFFC07880008E00037
-:10705000161C9793FFFCF582AA049593FFFCF78218
-:10706000001B9793FFFCF58639C09593FFFC0788BA
-:107070000008E000161C9793FFFCF582AEF895938C
-:10708000FFFCF782001C9793FFFCF5863A4C959322
-:10709000FFFC07880008E000161C9793FFFCF7062A
-:1070A0004250F03B2800F7064088F03B2800F602EB
-:1070B0000000F6054080F6054084F7063B70F63B7D
-:1070C0002800F7063B72F0BB2800F582CA20F58540
-:1070D0003B74F7063B78F03B2800F7063B7AF0BBA1
-:1070E0002800F582B194F5853B7CF7063B80F03BA8
-:1070F0002800F7063B82F0BB2800F582C754F585CF
-:107100003B84F7063B88F03B2800F7063B8AF0BB40
-:107110002800F582BEF8F5853B8CF7063B90F03BE6
-:107120002800F7063B92F0BB2800F582C8F8F585E9
-:107130003B94F7063B98F03B2800F7063B9AF0BBE0
-:107140002800F582C5D8F5853B9CF7063BA0F03BAF
-:107150002800F7063BA2F0BB2800F582C770F58532
-:107160003BA4F7063BA8F03B2800F7063BAAF0BB80
-:107170002800F582C1B4F5853BAC9616FFF407886C
-:107180000008E000D5409793FFFCF6846E50861609
-:10719000FFF40000000196361DDCF6053B6487967F
-:1071A000FFFC8296FFF802140000013C0000000082
-:1071B00000019293FFFC02900008221000302594F9
-:1071C0000020F02F280026140038F03328009013F8
-:1071D000FFFCF7044250F686425076B5001E76B4A6
-:1071E000FFE5C7386FC07739FFF09713FFFC9613A0
-:1071F000FFFC9593FFFC07880008E000F5F49793E7
-:10720000FFFC20220000E600721DF5021770F70453
-:1072100042540000000127380001F705425495133D
-:10722000FFFCF502001B9513FFFCF5064244951385
-:10723000FFFC07880008E0011EC09793FFFC8796BB
-:10724000FFFC8296FFF802140000013C00000000E1
-:1072500000019293FFFC02900008F704E0048616F8
-:107260000000F68200FF7739FFF0C7386C00F73373
-:107270002800F706E006873A000006B00002F7375C
-:107280002800F6843B6407300004F6BB2800870220
-:10729000FF3406300006F73328008796FFFC8296FD
-:1072A000FFF802140004013C00000000000192936A
-:1072B000FFFC029000082210003026140020F0335A
-:1072C000280027140038F03B28009713FFFC909308
-:1072D000FFFCF7044250F686425076B5001E76B4A5
-:1072E000FFE5C7386FC07739FFF09713FFFC96139F
-:1072F000FFFC07880008E000F3389793FFFC20228A
-:107300000000E6007319F5821770F704425400007C
-:10731000000127380001F70542549593FFFCF582E0
-:10732000001B9593FFFCF58642449593FFFC07886C
-:107330000008E0011EC09793FFFC8796FFFC829631
-:10734000FFF802140000013C0000000000019293CD
-:10735000FFFC029000082210004026140020961620
-:10736000FFC4F03328009013FFFC9613FFFC261493
-:1073700000389616FFBC9613FFFC07880008E00053
-:10738000D0DC9793FFFC9013FFFCF7044250F68685
-:10739000425076B5001E76B4FFE5C7386FC0773926
-:1073A000FFF09713FFFC8616FFBC00000001961348
-:1073B000FFFC8616FFC4000000019613FFFC07883F
-:1073C0000008E000F5F49793FFFC20220000E6009F
-:1073D00073E5F6021770F7044254000000012738E5
-:1073E0000001F70542549613FFFCF602001B9613AA
-:1073F000FFFCF60642449613FFFC07880008E001F4
-:107400001EC09793FFFC8796FFFC8296FFF802143C
-:107410000000013C0000000000019293FFFC02907C
-:10742000000822100004F5820000F5854080959642
-:10743000FFF407880008E000CB509793FFFC859687
-:10744000FFF4F5020064F5053BB4F7044250F486FE
-:10745000425076A5001E76B4FFE5F6044F5CF402B8
-:107460000006F4054254F5853B6CF5853BB8953232
-:10747000000095B20004C7386FC07739FFF00738B5
-:107480000001F727280007880008E00071B09793F3
-:10749000FFFCF4063704F40542448796FFFC82960D
-:1074A000FFF802140000013C00000000000192936C
-:1074B000FFFC0290000822100050F7044250F686AC
-:1074C000425076B5001E76B4FFE5F6046F34C73837
-:1074D0006FC086B2000C7739FFF0C0367200E6004C
-:1074E00077ECC504000086B20010F704E000F30258
-:1074F0000000C0367200E600751804B0001086B2B5
-:107500000014F704E00400000001C0367200E60039
-:10751000751C201A0000F3020001201A0000E6008A
-:10752000752900000001F502000086A60000F7049E
-:10753000E00000000001C0367200E2007564F6024F
-:107540000000C0367200E600756C2032000086A68E
-:107550000004F704E00400000001C0367200E200FD
-:10756000756D20320000F602000120320000E600B6
-:10757000757D202A0000F5020001202A0000E600A7
-:1075800077EC0000000107880008E000CBCC97935F
-:10759000FFFC26140020F033280004A00002F0278E
-:1075A0002800F582000023940022F59F280003A004
-:1075B000001A9396FFD42594002285AE000077AD83
-:1075C000001E77BCFFE5C5AC7FC075ADFFF076311E
-:1075D000001E7630FFE506A400022314001E751578
-:1075E000001EF59F2800F384E0007528FFE593A2B4
-:1075F000001CF584E0047399001E739CFFE59396CC
-:10760000FFAC7395001E739CFFE59396FFCC23940B
-:10761000004295A200208716FFE07595001E75AC0C
-:10762000FFE59596FFB47595001E75ACFFE5959640
-:10763000FFC4C73867C07738FFF0F7272800F48405
-:107640004F58871A0000C4A04A0074A4FFFAC5A4CA
-:107650000000F59F28008396FFAC2314001A7619CA
-:10766000001E7630FFE58596FFB4C7383FC07738F7
-:10767000FFF0F737280006B400028716FFE4839670
-:10768000FFCCC73857C07738FFF0F7372800871A84
-:10769000000006B40002C73867C07738FFF0F7373C
-:1076A000280006B400028716FFE823140016761996
-:1076B000001E7630FFE5C7385FC07738FFF0F73738
-:1076C0002800871A000006B40002C73867C0773860
-:1076D000FFF0F737280006B400028716FFEC2314EA
-:1076E00000127619001E7630FFE5C7383FC07738A4
-:1076F000FFF0F7372800871A000006B400028596CD
-:10770000FFC4C73867C07738FFF0F73728008716FF
-:10771000FFF006B40002C7385FC07738FFF0F737D4
-:107720002800F3820002F3A3280004200018259407
-:10773000002285AE000077AD001E77BCFFE5C5AC2A
-:107740007FC075ADFFF08396FFD4F5A32800F49FAA
-:1077500028002594004285AE000077AD001E77BC5E
-:10776000FFE5C5AC7FC075ADFFF044AD000094935C
-:10777000FFFCF786E0009793FFFCF3844F5C00006A
-:1077800000019393FFFC07880008E00123409793D2
-:10779000FFFC07880008E00078D89793FFFCF0050D
-:1077A0004084F786E0009793FFFC07880008E0001C
-:1077B000D5A09793FFFCF7046E50F4054084873AF8
-:1077C0001DDC00000001F7053B64F5863678F58581
-:1077D0004244F3863560F3854230F5864244959302
-:1077E000FFFC07880008E0011F489793FFFC87967D
-:1077F000FFFC8296FFF802140000013C000000002C
-:1078000000019293FFFC02900008F5864244959394
-:10781000FFFC07880008E00120E49793FFFC20228A
-:107820000000E600788900000001F70442540000DF
-:107830000001203A0000EE007851F6064250078819
-:107840000008E00071B09793FFFCE000788800002A
-:107850000001F704425076B1001E76B4FFE5F582D0
-:107860000006F5854254C7386FC07739FFF00738F6
-:107870000001F733280007880008E00072AC9793F6
-:10788000FFFCF5863790F58542448796FFFC82968B
-:10789000FFF802140000013C000000000001929378
-:1078A000FFFC02900008F6063678F6054244F7021F
-:1078B0000000F7054080F7054094F6846E50F70508
-:1078C000409097361DDC8796FFFC8296FFF80214E5
-:1078D0000000013C0000000000019293FFFC0290B8
-:1078E0000008F7020001F70540808796FFFC8296AA
-:1078F000FFF802140000013C000000000001929318
-:10790000FFFC02900008221000A8F7044250F58600
-:10791000425076AD001EF4846F3476B4FFE5949641
-:10792000FFC4C7386FC086A6000C7739FFF0C03699
-:107930007200E6007955F606429AF704429876B14D
-:10794000001E76B4FFE5C7386FC07739FFF00738FF
-:107950000001F7332800F704425076AD001E76B4DC
-:10796000FFE58516FFC4C7386FC086AA000C7739BB
-:10797000FFF0C0367200E60080A8F606429A872A19
-:107980000010862A001C203A0000E60079A8F68242
-:107990000000872A001400000001203A0000E600E1
-:1079A00079AC20360000F682000120360000E600A7
-:1079B0007A05249400209496FFBC8516FFC4F02716
-:1079C0002800052800109516FFB49513FFFC0788C2
-:1079D0000008E00072509793FFFC8496FFB400000B
-:1079E00000019493FFFC8516FFBC00000001951375
-:1079F000FFFC07880008E000F9349793FFFCE000E3
-:107A000080C40000000120320000E600806C00000D
-:107A1000000107880008E000CBCC9793FFFC259479
-:107A20000020F02F280004A000029496FF5CF027AD
-:107A30002800F48200002514005AF4AB2800072027
-:107A4000001A2514005A852A000077A9001E77BC69
-:107A5000FFE5C5287FC07529FFF075AD001E75AC28
-:107A6000FFE52314001E7619001EF53B2800F48460
-:107A7000E0007630FFE594A2001CF504E004849653
-:107A8000FF5C952200208716FFE006A40002751512
-:107A9000001E7528FFE59516FF547495001E74A40A
-:107AA000FFE59496FF9C7515001E7528FFE5951659
-:107AB000FF947495001E8516FF5C74A4FFE59496F0
-:107AC000FF8C8496FF54C7385FC07738FFF0F72BE0
-:107AD0002800871A00008516FF9CC73867C07738D2
-:107AE000FFF0F737280006B400028716FFE42314DE
-:107AF000001A7619001E7630FFE5C7384FC0773878
-:107B0000FFF0F7372800871A000006B400028496B9
-:107B1000FF94C73867C07738FFF0F737280006B4FE
-:107B200000028716FFE8231400167619001E76302F
-:107B3000FFE5C73857C07738FFF0F7372800871AB6
-:107B4000000006B40002C73867C07738FFF0F73787
-:107B5000280006B400028716FFEC231400127619E1
-:107B6000001E7630FFE5C7384FC07738FFF0F73793
-:107B70002800871A000006B400028516FF8CC7385B
-:107B800067C07738FFF0F73728008716FFF006B494
-:107B90000002C73857C07738FFF0F7372800F48263
-:107BA0000002F4A328002514005A852A000077A9B2
-:107BB000001E77BCFFE5C5287FC07529FFF00720B0
-:107BC0000018F53B28009416FFAC07880008E00079
-:107BD000CBCC9793FFFC261400382494005A84A63B
-:107BE000000077A5001E77BCFFE5C4A47FC074A584
-:107BF000FFF005A0000206AC000223940036751DBC
-:107C0000001E7528FFE50720001AF4B3280076311E
-:107C1000001E7630FFE59516FF547495001E74A47F
-:107C2000FFE59496FF5C7515001E7528FFE5951617
-:107C3000FF7C7495001E8516FFC474A4FFE594961E
-:107C4000FF74852A00342494005A9516FF8484A674
-:107C5000000077A5001E77BCFFE5C4A47FC074A513
-:107C6000FFF02514005AF4AF2800852A000077A9F8
-:107C7000001E77BCFFE5C5287FC07529FFF08496FC
-:107C8000FFC4F53B280084A600108516FFC494A20B
-:107C9000001C852A00147495001E74A4FFE59496B8
-:107CA000FF6C952200208716FFC88516FF54C73841
-:107CB00067C07738FFF0F72F2800871E00008496F2
-:107CC000FF5CC73857C07738FFF0F737280006B495
-:107CD00000028716FFCC23940032761D001E7630FA
-:107CE000FFE58516FF7CC7384FC07738FFF0F737C0
-:107CF0002800871E000006B40002C73867C0773826
-:107D0000FFF0F737280006B400028716FFD023944F
-:107D1000002E761D001E7630FFE5C73857C0773835
-:107D2000FFF0F7372800871E000006B40002849693
-:107D3000FF748516FF6CC73867C07738FFF0F737D8
-:107D4000280006B400028716FFD42394002A761D6B
-:107D5000001E7630FFE5C7384FC07738FFF0F737A1
-:107D60002800871E000006B40002C73867C07738B5
-:107D7000FFF0F73728008716FFD806B40002C7388F
-:107D800057C07738FFF0F7372800F4820002F4A3D9
-:107D90002800072000182514007A852A000077A9FA
-:107DA000001E77BCFFE5C5287FC07529FFF08496CB
-:107DB000FFC4F53B28008726000400000001203A9C
-:107DC0000024F7044F58E6007EF99416FF54C720AC
-:107DD0007200F6846E508626002C7738FFFA251440
-:107DE000005A842A000077A9001E77BCFFE5C42052
-:107DF0007FC07421FFF04739000086B61DDC77395B
-:107E00000002C0326A00468C0001D6800A68203623
-:107E10000000F6864098E6007EC0C3B86800C584BE
-:107E2000000086A60024F704E000F6020000C03639
-:107E30007200E6007E540324002486A60028F7047E
-:107E4000E00400000001C0367200E6007E582032D7
-:107E50000000F602000120320000E6007E6500000E
-:107E60000001F5820000869A0000F704E00000009F
-:107E70000001C0367200E2007EA0F6020000C036AB
-:107E80007200E6007EA820320000869A0004F70403
-:107E9000E00400000001C0367200E2007EA920323A
-:107EA0000000F602000120320000E6007EB9202E1C
-:107EB0000000F5820001202E0000E6007EC50000D3
-:107EC0000001F4020001F7044F58F41F28008496C3
-:107ED000FF548516FFC4F686409AC724720077388F
-:107EE000FFFA862A00304739000077390002C73888
-:107EF0006800E0007F4CF63B28008496FF54F606AD
-:107F00004098C72472007738FFFAC6B8000046B51B
-:107F1000000076B50002C6B46000F5020001F53736
-:107F200028004739000077390002C73860002494E0
-:107F3000005A84A6000077A5001E77BCFFE5C4A404
-:107F40007FC074A5FFF007380002F4BB2800F704D7
-:107F50004F588516FF548496FFACC6A8720076B4BD
-:107F6000FFFA0624001AF6B32800C72472007738F7
-:107F7000FFFA06A8001AF7372800473900009713C0
-:107F8000FFFC0724001C9713FFFCF5044F5C000066
-:107F900000019513FFFC07880008E0012340979338
-:107FA000FFFCF7044F588496FF5400000001C724DB
-:107FB00072007738FFFA473900009713FFFC072457
-:107FC000001C9713FFFCF5044F5C000000019513A3
-:107FD000FFFC07880008E00123409793FFFC078817
-:107FE0000008E00078D89793FFFCF6846E500000FC
-:107FF000000187361DDC00000001073800019736BC
-:108000001DDC87361DDCF0054084F486E000949387
-:10801000FFFC07880008E000D5A09793FFFCF4055B
-:108020004084F7046E50F005425C873A1DDCF6860A
-:108030002C28F7053B64F7042D38F5063A4CF50576
-:10804000424406380001F6052D3877390002F482E3
-:10805000001C20320044E6008060B4BA6802F005DB
-:108060002D38F50635ECE000808CF50542302032E5
-:108070000001E60080C40000000107880008E0005D
-:10808000789C9793FFFCF4863560F4854230F506C2
-:1080900042449513FFFC07880008E0011F489793AE
-:1080A000FFFCE00080C400000001F704429876B1B4
-:1080B000001E76B4FFE5C7386FC07739FFF0073888
-:1080C0000001F73328008796FFFC8296FFF8021420
-:1080D0000000013C0000000000019293FFFC0290B0
-:1080E0000008F58642449593FFFC07880008E001EC
-:1080F00020E49793FFFC20220000E600816100004D
-:108100000001F704425400000001203A0000EE0094
-:108110008129F606425007880008E00072AC979368
-:10812000FFFCE000816000000001F704425076B1DE
-:10813000001E76B4FFE5F5820006F5854254C73887
-:108140006FC07739FFF007380001F7332800078840
-:108150000008E000734C9793FFFCF586381CF5850A
-:1081600042448796FFFC8296FFF802140000013C0F
-:108170000000000000019293FFFC02900008221012
-:108180000058F7044250F686425076B5001E76B489
-:10819000FFE5F6046F34C7386FC086B2000C77393C
-:1081A000FFF0C0367200E6008250F4820000C50481
-:1081B000000086B20010F704E000C5A40000C0363D
-:1081C0007200E60081E40430001086B20014F70467
-:1081D000E00400000001C0367200E60081E8202EB5
-:1081E0000000F5820001202E0000E60081F500006D
-:1081F0000001F502000086A20000F704E000000084
-:108200000001C0367200E2008230F6020000C03683
-:108210007200E60082382032000086A20004F704D3
-:10822000E00400000001C0367200E2008239203212
-:108230000000F602000120320000E6008249202AF8
-:108240000000F5020001202A0000E60082592026E5
-:108250000000F482000120260000E6008760000094
-:10826000000107880008E000CBCC9793FFFC0720B3
-:108270000002F03B2800F7044F58F4053BB006A07D
-:108280000014C72072007738FFFAF737280006A0DD
-:108290000016F7372800F3020001F32328000788AF
-:1082A0000008E000CBCC9793FFFC26140020F033AD
-:1082B000280004A00002F0272800F3020000239405
-:1082C000002AF31F28000720001A2394002A839E07
-:1082D0000000779D001E77BCFFE5C39C7FC0739DA7
-:1082E000FFF07631001E7630FFE506A4000275151A
-:1082F000001EF3BB2800F304E0007528FFE593227D
-:10830000001CF384E0042314001E9316FFA4759947
-:10831000001E75ACFFE57315001E7318FFE593167C
-:10832000FFCC8316FFA493A200208716FFE073956D
-:10833000001E739CFFE59396FFAC7395001E739C23
-:10834000FFE5C73867C07738FFF0F7272800871A9E
-:1083500000009396FFC4C7385FC07738FFF0F73747
-:10836000280006B400028716FFE42394001A9396AF
-:10837000FFA4761D001E7630FFE5C73857C077385A
-:10838000FFF0F7372800871E000006B40002C73848
-:1083900067C07738FFF0F737280006B40002871669
-:1083A000FFE8231400169316FFA47619001E839687
-:1083B000FFAC7630FFE5C7383FC07738FFF0F737BE
-:1083C0002800871A000006B40002C73867C0773853
-:1083D000FFF0F737280006B400028716FFEC2314DD
-:1083E00000129316FFA47619001E8396FFCC7630F8
-:1083F000FFE5C7383FC07738FFF0F7372800871A06
-:10840000000006B40002C73867C07738FFF0F737BE
-:1084100028008716FFF08316FFC406B40002C73891
-:1084200037C07738FFF0F7372800F3820002F3A354
-:1084300028002314002A831A00007799001E77BCB5
-:10844000FFE5C3187FC07319FFF007200018F33B46
-:1084500028009416FFDC07880008E000CBCC979337
-:10846000FFFC072000022394002A839E0000779DD2
-:10847000001E77BCFFE5C39C7FC0739DFFF0248086
-:1084800000070520000AF3BB280020260007EE00A5
-:1084900084E00628000E86B200007731001E77388F
-:1084A000FFE575B1001E75ACFFE50528000204A4C8
-:1084B0000001C6B477C076B5FFF0F702FF00C6B47E
-:1084C0007400F6B3280087320000F30200FFC738BB
-:1084D0005FC07739FFF0C7383400E0008488F73395
-:1084E000280005200026862A000076A9001EF584B3
-:1084F0004F5876B4FFE58396FFDCF30200FF941635
-:10850000FFBCC71C5A007738FFFAC6306FC07631FF
-:10851000FFF047390000C7383400F682FF00C6304C
-:108520006C00C7386000F6843B6CF72B2800C5A0B0
-:108530005A0075ACFFFA8316FFDC07340001F7051B
-:108540003B6C0720003AF6BB280007200036F03BC2
-:108550002800F3820003F3A328000718001AF5BBD4
-:10856000280007880008E000CBCC9793FFFC072089
-:108570000002F03B2800248000070520000A202686
-:108580000007EE0085D40628000E86B20000773181
-:10859000001E7738FFE575B1001E75ACFFE50528B4
-:1085A000000204A40001C6B477C076B5FFF0F7025C
-:1085B000FF00C6B47400F6B3280087320000F382CF
-:1085C00000FFC7385FC07739FFF0C7383C00E000D4
-:1085D000857CF733280005A00026862E000076ADA6
-:1085E000001E76B4FFE5C520000024000007F3025A
-:1085F00000019316FFA4F7044F588396FFBC248014
-:10860000000EC71C72007738FFFAC6306FC0763193
-:10861000FFF047390000F68200FFC7386C00F68291
-:10862000FF00C6306C00C7386000F6843B6CF72F43
-:10863000280007340001F7053B6C0728003AF6BB19
-:10864000280007280036F03B2800F3020003F32B34
-:10865000280020220007EE008694C6284800063035
-:1086600000268732000076B1001E76B4FFE504A430
-:108670000002042000018396FFA4C7386FC0773939
-:10868000FFF0F682FF00C7386C00C71C7000E000E6
-:108690008650F73328000628002686B2000077317E
-:1086A000001E7738FFE5C6B477C076B5FFF0F70255
-:1086B000FF00C6B47400F6B328009513FFFCF30462
-:1086C0003BB0000000019313FFFC9516FFB4078830
-:1086D0000008E000D42C9793FFFC8516FFB4F0054A
-:1086E000407C8396FFBC23000007F3054258F70443
-:1086F0004250F606425076B1001E76B4FFE5F3060E
-:108700003934F3054244F5054074F3854260F38241
-:108710000006F3854254C7386FC07739FFF0F684FE
-:108720002D3807380001F733280006340001F6051C
-:108730002D38F7062C2876B50002F382001C203273
-:108740000044E600874CB3B67002F0052D38F306FE
-:1087500042449313FFFC07880008E0011F489793E9
-:10876000FFFC8796FFFC8296FFF802140000013C94
-:108770000000000000019293FFFC0290000822100C
-:108780000048F38642449393FFFC07880008E00109
-:1087900020E49793FFFC20220000E60089ED000012
-:1087A0000001F704425400000001203A0000EE00EE
-:1087B00087C90000000107880008E000734C979308
-:1087C000FFFCE00089EC0000000107880008E000E1
-:1087D000CBCC9793FFFC26140020F033280005A093
-:1087E0000002F02F2800F382000024940022F3A757
-:1087F000280004A0001A9496FFD423940022839E9C
-:108800000000779D001E77BCFFE5C39C7FC0739D71
-:10881000FFF07631001E7630FFE506AC000223142F
-:10882000001E7519001EF3A72800F484E0007528C7
-:10883000FFE594A2001CF384E0047495001E74A468
-:10884000FFE59496FFB47495001E74A4FFE594961A
-:10885000FFCC8496FFB493A200208716FFE07395A7
-:10886000001E739CFFE59396FFBC7395001E739CDE
-:10887000FFE59396FFC48396FFBCC73867C077387F
-:10888000FFF0F72F2800F5844F58871A0000C5A085
-:108890005A0075ACFFFAC73857C07738FFF0F73782
-:1088A000280006B400028716FFE42314001A761984
-:1088B000001E7630FFE545AD0000C7384FC0773861
-:1088C000FFF0F7372800871A000006B400028496EC
-:1088D000FFCCC73867C07738FFF0F737280006B4F9
-:1088E00000028716FFE8231400167619001E763062
-:1088F000FFE5C7383FC07738FFF0F7372800871A01
-:10890000000006B40002C73867C07738FFF0F737B9
-:10891000280006B400028716FFEC23140012761913
-:10892000001E7630FFE5C7384FC07738FFF0F737C5
-:108930002800871A000006B400028396FFC4C738D7
-:1089400067C07738FFF0F73728008716FFF006B4C6
-:108950000002C7383FC07738FFF0F7372800F482AD
-:108960000002F4A328000420001823940022839E10
-:108970000000779D001E77BCFFE5C39C7FC0739D00
-:10898000FFF08496FFD4F3A32800F3820001F3A73D
-:1089900028009593FFFCF486E0009493FFFCF38499
-:1089A0004F5C000000019393FFFC07880008E00182
-:1089B00023409793FFFC07880008E00078D897933E
-:1089C000FFFCF4863678F4854244F0054084F68452
-:1089D0004F5CF70200649736000090360004F702FF
-:1089E0000001F7054084F38635ECF3854230879625
-:1089F000FFFC8296FFF802140000013C000000001A
-:108A000000019293FFFC0290000822100090F704EE
-:108A10004260F502000005B80018F6044258000054
-:108A2000000120320007EE008A70C7306000C738AE
-:108A300058000738000E86BA00007739001E7738D4
-:108A4000FFE5C6B477C076B5FFF0F70200FFC6B405
-:108A50007400C0365200470C0001D7000A70203A5B
-:108A60000000E6008A7107300001E0008A18F7056F
-:108A70004258F40442580000000120220007EE0092
-:108A80008D9424940036F604426025140038239413
-:108A90000020063000028732000076B1001E76B456
-:108AA000FFE50630000275B1001EC7386FC0773889
-:108AB000FFF0F72B28008732000075ACFFE5C738C0
-:108AC0005FC07738FFF0F727280024940034063081
-:108AD00000028732000076B1001E76B4FFE5C73889
-:108AE0006FC07738FFF0F727280024940032063053
-:108AF00000028732000076B1001E76B4FFE5C73869
-:108B00006FC07738FFF0F727280024940030063034
-:108B100000028732000076B1001E76B4FFE5C73848
-:108B20006FC07738FFF0F72728002494002E063016
-:108B300000028732000076B1001E76B4FFE5C73828
-:108B40006FC07738FFF0F72728002494002C0630F8
-:108B500000028732000076B1001E76B4FFE5C73808
-:108B60006FC07738FFF0F72728002494002A0630DA
-:108B700000028732000076B1001E76B4FFE5C738E8
-:108B80006FC07738FFF0F7272800063000028732E1
-:108B90000000249400287631001E7630FFE5C738A7
-:108BA00067C07738FFF0F72728009413FFFC951370
-:108BB000FFFC9396FF7C9393FFFC07880008E0007E
-:108BC000D0DC9793FFFCF60442602494007E2514C9
-:108BD000008023940068063000028732000076B1DE
-:108BE000001E76B4FFE50630000275B1001EC738DE
-:108BF0006FC07738FFF0F72B28008732000075AC84
-:108C0000FFE5C7385FC07738FFF0F72728002494C6
-:108C1000007C063000028732000076B1001E76B478
-:108C2000FFE5C7386FC07738FFF0F7272800249496
-:108C3000007A063000028732000076B1001E76B45A
-:108C4000FFE5C7386FC07738FFF0F7272800249476
-:108C50000078063000028732000076B1001E76B43C
-:108C6000FFE5C7386FC07738FFF0F7272800249456
-:108C70000076063000028732000076B1001E76B41E
-:108C8000FFE5C7386FC07738FFF0F7272800249436
-:108C90000074063000028732000076B1001E76B400
-:108CA000FFE5C7386FC07738FFF0F7272800249416
-:108CB0000072063000028732000076B1001E76B4E2
-:108CC000FFE5C7386FC07738FFF0F7272800063078
-:108CD000000287320000249400707631001E763046
-:108CE000FFE5C73867C07738FFF0F72728009513EE
-:108CF000FFFC9396FF749393FFFC07880008E00045
-:108D0000D2589793FFFC8396FF7400000001939361
-:108D1000FFFCF704425823940050C70072009713D9
-:108D2000FFFC9396FF6C9393FFFC07880008E0001C
-:108D3000CF249793FFFC8396FF6CF6864250939363
-:108D4000FFFCF384425876B5001E9393FFFCF704B2
-:108D5000425076B4FFE5C7386FC07739FFF09713FC
-:108D6000FFFC8396FF7C000000019393FFFC0788C3
-:108D70000008E000F3389793FFFC20220000E60093
-:108D80008D9500000001F7044258000000010738EB
-:108D90000001F7054258F704425800000001203A4C
-:108DA0000007EE008DD4F3821770F7042D38F68695
-:108DB0002C2806380001F6052D3877390002F38299
-:108DC000001C20320044E6008DF4B3BA6802E000D3
-:108DD0008DF4F0052D389393FFFCF382001B9393E1
-:108DE000FFFCF38642449393FFFC07880008E001F0
-:108DF0001EC09793FFFC8796FFFC8296FFF8021433
-:108E00000000013C0000000000019293FFFC029072
-:108E1000000822100088F7044250F686425076B5CA
-:108E2000001EF3846F3476B4FFE59396FFC4C73811
-:108E30006FC0869E000C7739FFF0C0367200E600E6
-:108E40008E65F60642A0F70442A076B1001E76B405
-:108E5000FFE5C7386FC07739FFF007380001E00041
-:108E600094E4F7332800F604426024940036851613
-:108E7000FFC423940038063000028732000076B128
-:108E8000001E76B4FFE5852A001C0630000275B18D
-:108E9000001EC7386FC07738FFF09516FFBCF71F6C
-:108EA00028008732000075ACFFE58516FFC4C7387F
-:108EB0005FC07738FFF0F72728002494003406308D
-:108EC00000028732000076B1001E76B4FFE5C73895
-:108ED0006FC07738FFF0F72728002494003206305F
-:108EE00000028732000076B1001E76B4FFE5C73875
-:108EF0006FC07738FFF0F727280024940030063041
-:108F000000028732000076B1001E76B4FFE5C73854
-:108F10006FC07738FFF0F72728002494002E063022
-:108F200000028732000076B1001E76B4FFE5C73834
-:108F30006FC07738FFF0F72728002494002C063004
-:108F400000028732000076B1001E76B4FFE5C73814
-:108F50006FC07738FFF0F72728002494002A0630E6
-:108F600000028732000076B1001E76B4FFE5C738F4
-:108F70006FC07738FFF0F7272800063000028732ED
-:108F80000000249400287631001E7630FFE5C738B3
-:108F900067C07738FFF0F7272800872A00200000F5
-:108FA00000019713FFFC9393FFFC271400209713F5
-:108FB000FFFC07880008E000D0DC9793FFFC839655
-:108FC000FFC400000001871E001000000001203ACD
-:108FD0000000E6008FF0F6820000871E00140000FB
-:108FE0000001203A0000E6008FF420360000F682EF
-:108FF000000120360000E6009041000000018516C7
-:10900000FFC400000001052800109516FFB4951359
-:10901000FFFC07880008E00072509793FFFC8396DE
-:10902000FFB4271400209393FFFC9713FFFC0788DD
-:109030000008E000F9349793FFFCE00094E400009E
-:1090400000018516FFBC00000001202A0000E60098
-:1090500094BC0000000107880008E000CBCC979387
-:10906000FFFCF502000023940062F51F28007595AF
-:10907000001E75ACFFE50620000206B000022314B6
-:10908000001E7399001E739CFFE59396FF7475157F
-:10909000001E7528FFE59516FF7C7395001E739CD6
-:1090A000FFE59396FF8C8516FFC47395001E93967B
-:1090B000FF84852A0034239400629516FFACF033B8
-:1090C00028000520001A9516FF94839E0000779DC6
-:1090D000001E77BCFFE5C39C7FC0739DFFF07495B5
-:1090E000001EF3AB28008516FFC474A4FFE5852A93
-:1090F00000108396FFC49522001C839E00148516E1
-:10910000FF8493A200208716FFE07528FFE59516DF
-:10911000FF84F3844F588516FF74C7385FC07738D3
-:10912000FFF0F7332800871A00009396FFA4C022AF
-:109130003A008396FF7CC73857C07738FFF0F7377F
-:10914000280006B400028716FFE42314001A7619DB
-:10915000001E7630FFE5C7384FC07738FFF0F7378D
-:109160002800871A000006B40002C73867C07738A5
-:10917000FFF0F737280006B400028716FFE8231433
-:1091800000167619001E7630FFE5C7383FC07738E5
-:10919000FFF0F7372800871A000006B40002851692
-:1091A000FF8C8396FF84C73867C07738FFF0F737A6
-:1091B000280006B400028716FFEC2314001276196B
-:1091C000001E7630FFE5C73857C07738FFF0F73715
-:1091D0002800871A000006B40002C73867C0773835
-:1091E000FFF0F73728008716FFF006B40002C738F3
-:1091F0003FC07738FFF0F7372800F5020002F5236B
-:10920000280023940052839E0000779D001E77BCA7
-:10921000FFE5C39C7FC0739DFFF003200018E600AC
-:109220009230F39B2800F7044270E000929CF6060F
-:1092300042728516FFC40000000186AA00200000CB
-:10924000000107340007203A000EE2009294C73470
-:109250006800F5844260F38200FFC72C7000073875
-:10926000002686BA00009716FF747739001E7738FB
-:10927000FFE5C6B477C076B5FFF0C6B43C00203633
-:109280000000470C0001D7000A70203A0000E600F9
-:1092900092C900000001F7044274F606427476B1E8
-:1092A000001E76B4FFE5C7386FC07739FFF0073886
-:1092B0000001F733280007880008E000789C9793A6
-:1092C000FFFCE00094E4000000018516FFA48396F3
-:1092D000FF74C720520074B8FFFAC6240000871E2E
-:1092E0000000769D001E76B4FFE5C5AC520075AC5B
-:1092F000FFFA46310000F50200FFC6305400C738BF
-:109300006FC07739FFF0F682FF00C7386C00C630B7
-:109310007000F61F28008396FF948516FFC4F59F02
-:109320002800872A000400000001203A0024E600FB
-:109330009469F6864098F7046E50862A002CC6A4DD
-:10934000000023940062849E0000779D001E77BC7D
-:10935000FFE5C4A47FC074A5FFF046B50000873ABE
-:109360001DDC76B50002C0327200470C0001D70048
-:109370000A70203A0000F7064098E6009434C3349F
-:109380007000C584000086AA0024F704E000F602FD
-:109390000000C036720005280024E60093C495162C
-:1093A000FF748396FFC400000001869E0028F70426
-:1093B000E00400000001C0367200E60093C82032CD
-:1093C0000000F602000120320000E60093D5000004
-:1093D0000001F58200008516FF74F704E00086AAFC
-:1093E000000000000001C0367200E2009414F60292
-:1093F0000000C0367200E600941C2032000086AAED
-:109400000004F704E00400000001C0367200E2002E
-:10941000941D20320000F602000120320000E60018
-:10942000942D202E0000F5820001202E0000E60081
-:10943000943900000001F4820001F7044F58F49BB6
-:1094400028008396FFC4F686409AC72072007738BA
-:10945000FFFA861E00304739000077390002C7380E
-:109460006800E00094E4F63B2800472500007739C7
-:109470000002C7386800F5020001F53B28000738F4
-:10948000000223940062839E0000779D001E77BC3B
-:10949000FFE5C39C7FC0739DFFF025140062F3BB02
-:1094A0002800852A000077A9001E77BCFFE5C528A3
-:1094B0007FC07529FFF0E00094E4F51B2800839637
-:1094C000FFBC00000001201E0001E60094E4000043
-:1094D000000107880008E000789C9793FFFCF506E0
-:1094E0003560F50542308796FFFC8296FFF802143E
-:1094F0000000013C0000000000019293FFFC02907C
-:109500000008F50642449513FFFC07880008E001B7
-:1095100020E49793FFFC20220000E60096890000DB
-:109520000001F68442540000000120360000EE00E5
-:10953000958DF5864250F7044250762D001E763008
-:10954000FFE526B40001F685425425000007F50525
-:109550004258F6842D38C73867C07739FFF007388E
-:109560000001F72F280006340001F6052D38F70614
-:109570002C2876B50002F502001C20320044E600DB
-:109580009688B5367002E0009688F0052D38F5040F
-:109590004260000000019513FFFC07880008E0000E
-:1095A000B2849793FFFCF6844F5800000001073403
-:1095B0000040C0227200E60095ECF6064276F70401
-:1095C000427476B1001E76B4FFE5C7386FC07739B4
-:1095D000FFF007380001F733280007880008E00093
-:1095E000789C9793FFFCE000968800000001F70448
-:1095F000426000000001C0227200E60096240000D4
-:1096000000019713FFFCF5043BB000000001951327
-:10961000FFFC07880008E000D42C9793FFFCE000D3
-:10962000964000000001C0226A00E600967100002A
-:1096300000019713FFFC07880008E000CC609793B7
-:10964000FFFCF704407C000000010738000197137D
-:10965000FFFCF5044074000000019513FFFC07882F
-:109660000008E000BEF89793FFFCE0009688000039
-:109670000001F5044074000000019513FFFC078809
-:109680000008E000C1B49793FFFC8796FFFC829628
-:10969000FFF802140000013C00000000000192935A
-:1096A000FFFC0290000822100070F6046F34F704EB
-:1096B000426486B2000400000001C0367200E60079
-:1096C0009B1806B0000287360000F404407C76B593
-:1096D000001E76B4FFE5C7386FC07739FFF0C03A97
-:1096E0004200E6009B1824940036F604407423944C
-:1096F0000038063000028732000076B1001E76B4D2
-:10970000FFE50630000275B1001EC7386FC077381C
-:10971000FFF0F71F28008732000075ACFFE5C7385F
-:109720005FC07738FFF0F727280024940034063014
-:1097300000028732000076B1001E76B4FFE5C7381C
-:109740006FC07738FFF0F7272800249400320630E6
-:1097500000028732000076B1001E76B4FFE5C738FC
-:109760006FC07738FFF0F7272800249400300630C8
-:1097700000028732000076B1001E76B4FFE5C738DC
-:109780006FC07738FFF0F72728002494002E0630AA
-:1097900000028732000076B1001E76B4FFE5C738BC
-:1097A0006FC07738FFF0F72728002494002C06308C
-:1097B00000028732000076B1001E76B4FFE5C7389C
-:1097C0006FC07738FFF0F72728002494002A06306E
-:1097D00000028732000076B1001E76B4FFE5C7387C
-:1097E0006FC07738FFF0F727280006300002873275
-:1097F0000000249400287631001E7630FFE5C7383B
-:1098000067C07738FFF0F72728009413FFFC939385
-:10981000FFFC271400209713FFFC07880008E000D6
-:10982000D0DC9793FFFC07880008E000CBCC97932F
-:10983000FFFCF50440749416FFC407200002F03BBF
-:10984000280024800007F40200FF8396FFC49516C9
-:10985000FFBC031C000A20260007EE0098A806188B
-:10986000000E86B200007731001E7738FFE575B133
-:10987000001E75ACFFE503180002C6B477C076B5CC
-:10988000FFF0F702FF00C6B47400F6B32800873279
-:10989000000004A40001C7385FC07739FFF0C73863
-:1098A0004400E0009854F73328008516FFC47495EF
-:1098B000001E74A4FFE58396FFC42314001E7419D0
-:1098C000001E7420FFE5052800269516FF8C85AA4A
-:1098D000000076A9001E76B4FFE5039C0002939673
-:1098E000FFB4061C00027395001E739CFFE593965F
-:1098F000FFAC7395001E739CFFE59396FF9C8396C7
-:10990000FFBC7515001E7528FFE59516FF947515AB
-:10991000001E7528FFE59516FFA48516FFC4C5AC8B
-:109920006FC075ADFFF0F5054260F5044F58F68243
-:1099300000FFC71C52007738FFFA47390000C738CC
-:109940006C00F682FF00C5AC6C00C73858008396E7
-:10995000FF8CF5843B6C8516FFB4F71F2800871633
-:10996000FFE006AC0001F6853B6C8396FFC4C73868
-:109970004FC07738FFF0F72B2800F5044F58871AAF
-:109980000000C01E5200C73847C07738FFF0F733D9
-:109990002800063000028716FFE42314001A769987
-:1099A000001E8396FF9476B4FFE5C7383FC0773832
-:1099B000FFF0F7332800871A000006300002C7388E
-:1099C0006FC07738FFF0F7332800063000028716A3
-:1099D000FFE8231400167699001E76B4FFE585167D
-:1099E000FFAC8396FFA4C73857C07738FFF0F73332
-:1099F0002800871A0000063000028516FF9CC73831
-:109A00006FC07738FFF0F733280006300002871662
-:109A1000FFEC231400127699001E76B4FFE5C738D8
-:109A20003FC07738FFF0F7332800871A0000063070
-:109A300000028396FFC4C7386FC07738FFF0F73352
-:109A400028008716FFF006300002C73857C0773865
-:109A5000FFF0F7332800071C003AF5BB2800071C6D
-:109A60000036F03B2800F5020003E6009AA4F51F3B
-:109A70002800F7044278F606427876B1001E76B4E4
-:109A8000FFE5C7386FC07739FFF007380001F733BB
-:109A9000280007880008E000789C9793FFFCE0000E
-:109AA0009B1800000001F38642449393FFFC078853
-:109AB0000008E0011F489793FFFC25000007F5050B
-:109AC0004258F7044250F606425076B1001E76B472
-:109AD000FFE5F3820006F3854254F5063934F505B7
-:109AE0004244C7386FC07739FFF0F6842D38073805
-:109AF0000001F733280006340001F6052D38F7067B
-:109B00002C2876B50002F382001C20320044E600C7
-:109B10009B18B3B67002F0052D388796FFFC82962D
-:109B2000FFF802140000013C0000000000019293C5
-:109B3000FFFC0290000822100078F38642449393C1
-:109B4000FFFC07880008E00120E49793FFFC202237
-:109B50000000E6009E4100000001F70442540000AE
-:109B60000001203A0000EE009D8524940036F604A2
-:109B7000407425140038063000028732000076B1A8
-:109B8000001E76B4FFE50630000275B1001EC7382E
-:109B90006FC07738FFF0F72B28008732000075ACD4
-:109BA000FFE5C7385FC07738FFF0F7272800249417
-:109BB0000034063000028732000076B1001E76B411
-:109BC000FFE5C7386FC07738FFF0F72728002494E7
-:109BD0000032063000028732000076B1001E76B4F3
-:109BE000FFE5C7386FC07738FFF0F72728002494C7
-:109BF0000030063000028732000076B1001E76B4D5
-:109C0000FFE5C7386FC07738FFF0F72728002494A6
-:109C1000002E063000028732000076B1001E76B4B6
-:109C2000FFE5C7386FC07738FFF0F7272800249486
-:109C3000002C063000028732000076B1001E76B498
-:109C4000FFE5C7386FC07738FFF0F7272800249466
-:109C5000002A063000028732000076B1001E76B47A
-:109C6000FFE5C7386FC07738FFF0F72728000630C8
-:109C7000000287320000249400287631001E7630DE
-:109C8000FFE5C73867C07738FFF0F7272800F3846F
-:109C9000407C000000019393FFFC9513FFFC23948C
-:109CA00000209396FF949393FFFC07880008E00040
-:109CB000D0DC9793FFFC8396FF9400000001939300
-:109CC000FFFC239400689396FF8C9393FFFC078816
-:109CD0000008E000D2589793FFFC8396FF8C0000A9
-:109CE00000019393FFFC9013FFFC23940050939684
-:109CF000FF849393FFFC07880008E000CF2497932C
-:109D0000FFFC8702FF3400000001F7054264F38482
-:109D1000407C000000019393FFFC9713FFFC8396A7
-:109D2000FF84000000019393FFFC8396FF940000E2
-:109D300000019393FFFC07880008E000F7C89793A1
-:109D4000FFFC20220000E6009D5DF3821770F704FF
-:109D500042540000000127380001F7054254939354
-:109D6000FFFCF382001B9393FFFCF3864244939322
-:109D7000FFFC07880008E0011EC09793FFFCE0008D
-:109D80009E4000000001F504407CF4844074C72824
-:109D90005000C724700005B8002686AE0000772D5D
-:109DA000001E7738FFE5C6B477C077B40008703E70
-:109DB000FFE8470C0001D7000A70203A0000F704C2
-:109DC0004F58E6009DFDF60200FFF7044278F606C4
-:109DD000427A76B1001E76B4FFE5C7386FC0773996
-:109DE000FFF007380001F733280007880008E0007B
-:109DF000789C9793FFFCE0009E400000000186AE37
-:109E00000000772D001E7738FFE5C6B477C076B521
-:109E1000FFF0F7020001C7386400F602FF00C6B485
-:109E20006400C7386800F72F28000728000197133F
-:109E3000FFFC9493FFFC07880008E000BEF89793AE
-:109E4000FFFC8796FFFC8296FFF802140000013C9D
-:109E50000000000000019293FFFC02900008221015
-:109E600000D8F38642449393FFFC07880008E00182
-:109E700020E49793FFFC20220000E600A2C9000026
-:109E80000001F704425400000001203A0000EE00F7
-:109E9000A03524940036F6044074251400380630AA
-:109EA00000028732000076B1001E76B4FFE506306E
-:109EB000000275B1001EC7386FC07738FFF0F72B6E
-:109EC00028008732000075ACFFE5C7385FC07738DF
-:109ED000FFF0F72728002494003406300002873270
-:109EE000000076B1001E76B4FFE5C7386FC0773842
-:109EF000FFF0F72728002494003206300002873252
-:109F0000000076B1001E76B4FFE5C7386FC0773821
-:109F1000FFF0F72728002494003006300002873233
-:109F2000000076B1001E76B4FFE5C7386FC0773801
-:109F3000FFF0F72728002494002E06300002873215
-:109F4000000076B1001E76B4FFE5C7386FC07738E1
-:109F5000FFF0F72728002494002C063000028732F7
-:109F6000000076B1001E76B4FFE5C7386FC07738C1
-:109F7000FFF0F72728002494002A063000028732D9
-:109F8000000076B1001E76B4FFE5C7386FC07738A1
-:109F9000FFF0F727280006300002873200002494E3
-:109FA00000287631001E7630FFE5C73867C0773865
-:109FB000FFF0F7272800F384407C00000001939312
-:109FC000FFFC9513FFFC239400209396FF4C939382
-:109FD000FFFC07880008E000D0DC9793FFFC839625
-:109FE000FF4C000000019393FFFC239400509396D4
-:109FF000FF449393FFFC07880008E000D258979332
-:10A00000FFFC8702FF3400000001F7054264F3847F
-:10A01000407C000000019393FFFC9713FFFC8396A4
-:10A02000FF44000000019393FFFC8396FF4CE00087
-:10A03000A2809393FFFCF404407CF6044074F38206
-:10A040000000C7204000C73070000738002686BADD
-:10A0500000007739001E7738FFE5C6B477C077B4C3
-:10A060000008703EFFE8470C0001D7000A70203A54
-:10A070000000E600A0AD9396FF3CF70442A0F60670
-:10A0800042A076B1001E76B4FFE5C7386FC07739BD
-:10A09000FFF007380001F733280007880008E000C8
-:10A0A000789C9793FFFCE000A2C8000000010630F6
-:10A0B00000028732000076B1001E76B4FFE52494DA
-:10A0C000007E25140080239400680630000275B1DC
-:10A0D000001EC7386FC07738FFF0F72B2800873293
-:10A0E000000075ACFFE5C7385FC07738FFF0F72791
-:10A0F00028002494007C063000028732000076B1EC
-:10A10000001E76B4FFE5C7386FC07738FFF0F72739
-:10A1100028002494007A063000028732000076B1CD
-:10A12000001E76B4FFE5C7386FC07738FFF0F72719
-:10A13000280024940078063000028732000076B1AF
-:10A14000001E76B4FFE5C7386FC07738FFF0F727F9
-:10A15000280024940076063000028732000076B191
-:10A16000001E76B4FFE5C7386FC07738FFF0F727D9
-:10A17000280024940074063000028732000076B173
-:10A18000001E76B4FFE5C7386FC07738FFF0F727B9
-:10A19000280024940072063000028732000076B155
-:10A1A000001E76B4FFE5C7386FC07738FFF0F72799
-:10A1B00028000630000287320000249400707631B7
-:10A1C000001E7630FFE5C73867C07738FFF0F72705
-:10A1D00028009413FFFC9513FFFC9396FF34939390
-:10A1E000FFFC07880008E000D0DC9793FFFC839613
-:10A1F000FF34000000019393FFFC239400B093967A
-:10A20000FF2C9393FFFC07880008E000D258979337
-:10A21000FFFC8396FF2C000000019393FFFC8396C4
-:10A22000FF3C000000019393FFFC23940098939659
-:10A23000FF249393FFFC07880008E000CF24979346
-:10A24000FFFCF3820006F38542548702FF34F38655
-:10A2500038A8F3854244F7054264F384407C00004B
-:10A2600000019393FFFC9713FFFC8396FF240000EB
-:10A2700000019393FFFC8396FF3400000001939349
-:10A28000FFFC07880008E000F7C89793FFFC202236
-:10A290000000E600A2A9F3821770F7044254000000
-:10A2A000000127380001F70542549393FFFCF38225
-:10A2B000001B9393FFFCF38642449393FFFC0788B3
-:10A2C0000008E0011EC09793FFFC8796FFFC829672
-:10A2D000FFF802140000013C00000000000192930E
-:10A2E000FFFC02900008F6046F34F704426486B263
-:10A2F000000400000001C0367200E600A3AC06B006
-:10A3000000028736000076B5001E76B4FFE5C73838
-:10A310006FC0F684407C7739FFF0C03A6A00E600EF
-:10A32000A3ACC7346800F5844074F6044F580000AD
-:10A330000001C62C62007630FFFAC5AC700005AC97
-:10A34000002686AE0000772D001E7738FFE54631E7
-:10A350000000C6B477C076B5FFF0F70200FFC63044
-:10A360007400F702FF00C6B47400C6306800F62F10
-:10A370002800F50642449513FFFC07880008E00119
-:10A380001F489793FFFCF704407C0000000107384A
-:10A3900000019713FFFCF5044074000000019513C1
-:10A3A000FFFC07880008E000BEF89793FFFC879643
-:10A3B000FFFC8296FFF802140000013C0000000040
-:10A3C00000019293FFFC0290000822100080F70425
-:10A3D000425800000001203A0000E600A3F4203AB1
-:10A3E0000007F5020001F5054258F7044258000045
-:10A3F0000001203A0007EE00A6F02394001EF604A8
-:10A40000426023140066F4844078063000028732EC
-:10A41000000076B1001E76B4FFE504A400027425A6
-:10A42000001E7420FFE5063000027531001E7528FD
-:10A43000FFE59516FF7CC7386FC07738FFF025140D
-:10A4400000209516FF94F72B280087320000851610
-:10A45000FF7C05A40002C73857C07738FFF0F71F0C
-:10A4600028002394001C063000028732000076B1D9
-:10A47000001E76B4FFE525140050C7386FC077384A
-:10A48000FFF0F71F28002394001A063000028732DD
-:10A49000000076B1001E76B4FFE5C7386FC077388C
-:10A4A000FFF0F71F280023940018063000028732BF
-:10A4B000000076B1001E76B4FFE5C7386FC077386C
-:10A4C000FFF0F71F280023940016063000028732A1
-:10A4D000000076B1001E76B4FFE5C7386FC077384C
-:10A4E000FFF0F71F28002394001406300002873283
-:10A4F000000076B1001E76B4FFE5C7386FC077382C
-:10A50000FFF0F71F28002394001206300002873264
-:10A51000000076B1001E76B4FFE5C7386FC077380B
-:10A52000FFF0F71F28002394001006300002873246
-:10A53000000076AD001E7631001E7630FFE5C7388C
-:10A5400067C07738FFF0F71F280087260000261421
-:10A550000068C73847C07738FFF0F7332800872EE8
-:10A56000000076B4FFE5C7386FC07738FFF0F71BFF
-:10A5700028002314006405AC0002872E000076AD8D
-:10A58000001E76B4FFE5C7386FC07738FFF0F71BC1
-:10A5900028002314006205AC0002872E000076AD6F
-:10A5A000001E76B4FFE5C7386FC07738FFF0F71BA1
-:10A5B00028002314006005AC0002872E000076AD51
-:10A5C000001E76B4FFE5C7386FC07738FFF0F71B81
-:10A5D00028002314005E05AC0002872E000076AD33
-:10A5E000001E76B4FFE5C7386FC07738FFF0F71B61
-:10A5F00028002314005C05AC0002872E000076AD15
-:10A60000001E76B4FFE5C7386FC07738FFF0F71B40
-:10A6100028002314005A05AC0002872E000076ADF6
-:10A62000001E76B4FFE5C7386FC07738FFF0F71B20
-:10A63000280005AC0002872E00002314005875ADD9
-:10A64000001E75ACFFE5C7385FC07738FFF0F71B19
-:10A6500028009613FFFC9516FF8C9513FFFC0788C6
-:10A660000008E000D2589793FFFC8516FF8C00008D
-:10A6700000019513FFFCF5044258000000019513FA
-:10A68000FFFC251400389516FF849513FFFC0788FE
-:10A690000008E000CF249793FFFCF5044258000027
-:10A6A00000019513FFFCF5044264000000019513BE
-:10A6B000FFFC8516FF84000000019513FFFC851642
-:10A6C000FF94000000019513FFFC07880008E000DC
-:10A6D000F7C89793FFFC20220000E600A6F10000D7
-:10A6E0000001F70442580000000107380001F70597
-:10A6F0004258F704425800000001203A0007EE00DB
-:10A70000A730F5021770F7042D38F6862C28063886
-:10A710000001F6052D3877390002F502001C2032C1
-:10A720000044E600A750B53A6802E000A750F005E3
-:10A730002D389513FFFCF502001B9513FFFCF50661
-:10A7400042449513FFFC07880008E0011EC0979360
-:10A75000FFFC8796FFFC8296FFF802140000013C84
-:10A760000000000000019293FFFC029000082210FC
-:10A770000030F6046F34F704426486B2000400002F
-:10A780000001C0367200E600A9F007300002863AE8
-:10A790000000F5820000F684407C7739001E77388F
-:10A7A000FFE5C63077C0F7044074C6B46800763160
-:10A7B000FFF0C60062009616FFF4C738680007383D
-:10A7C000002686BA00007739001E7738FFE5C6B448
-:10A7D00077C077B40008703EFFE8470C0001D7004F
-:10A7E0000A70203A0000E600A834F60200FF831643
-:10A7F000FFF48396FFF4F7044078C6983800C73812
-:10A8000068000738002686BA00007739001E7738BE
-:10A81000FFE5C6B477C076B5FFF0C6B46400C036B5
-:10A820005A00470C0001D7000A70203A0000E600E9
-:10A83000A83D202E0000F5820001202E0000E60039
-:10A84000A875F606427CF704427C76B1001E76B409
-:10A85000FFE5C7386FC07739FFF007380001F733DD
-:10A86000280007880008E000789C9793FFFCE00030
-:10A87000A9F000000001F3044260000000019313FE
-:10A88000FFFC07880008E000CC609793FFFCF4040D
-:10A890004078F7044F58F5044074F384407CF30487
-:10A8A000407CC62072007630FFFAC59C3000C5A8F7
-:10A8B000580005AC002686AE000074AD001E74A4DE
-:10A8C000FFE573AD001E739CFFE59396FFD4C5288A
-:10A8D00072007528FFFA8316FFF48396FFF4463161
-:10A8E000000045290000C7183800C420700004206B
-:10A8F00000267321001EC6B44FC076B5FFF0F48267
-:10A9000000FFC6304C00F382FF00C6B43C00C630E6
-:10A910006800F62F2800872E00007318FFE59316B5
-:10A92000FFCC8316FFD48396FFF4C5284C00C738AC
-:10A9300037C07739FFF0769D001076B5FFF8C7383D
-:10A940004C00C6B47000F6AF28008722000076A144
-:10A95000001E8316FFCCF382FF0076B4FFE5C738F4
-:10A9600037C07739FFF0C7383C00C5287000F523A1
-:10A97000280087220000F304407CC7386FC0773975
-:10A98000FFF0731900109316FFEC7399FFF8C738A6
-:10A990004C00C71C70009716FFDC23140022831A9A
-:10A9A00000007799001E77BCFFE5C3187FC07319BC
-:10A9B000FFF0F3232800F38642449393FFFC0788BB
-:10A9C0000008E0011F489793FFFCF704407C00005B
-:10A9D0000001073800019713FFFCF30440740000E6
-:10A9E00000019313FFFC07880008E000BEF897936E
-:10A9F000FFFC8796FFFC8296FFF802140000013CE2
-:10AA00000000000000019293FFFC02900008221059
-:10AA10000098F30642449313FFFC07880008E00106
-:10AA200020E49793FFFC20220000E600AEE5000042
-:10AA30000001F704425400000001203A0000EE003B
-:10AA4000AD8927380001F70542542394001EF6040F
-:10AA50004260249400669496FF64F3044078249442
-:10AA600000209496FF94063000028732000076B1F1
-:10AA7000001E76B4FFE5031800029316FF747419E4
-:10AA8000001E7420FFE505980002063000027531B3
-:10AA9000001EC7386FC07738FFF0F72728008732CD
-:10AAA00000007528FFE5C73857C07738FFF0F71F5B
-:10AAB00028002394001C063000028732000076B183
-:10AAC000001E76B4FFE58516FF64C7386FC077387F
-:10AAD000FFF0F71F28002394001A06300002873287
-:10AAE000000076B1001E76B4FFE5C7386FC0773836
-:10AAF000FFF0F71F28002394001806300002873269
-:10AB0000000076B1001E76B4FFE5C7386FC0773815
-:10AB1000FFF0F71F2800239400160630000287324A
-:10AB2000000076B1001E76B4FFE5C7386FC07738F5
-:10AB3000FFF0F71F2800239400140630000287322C
-:10AB4000000076B1001E76B4FFE5C7386FC07738D5
-:10AB5000FFF0F71F2800239400120630000287320E
-:10AB6000000076B1001E76B4FFE5C7386FC07738B5
-:10AB7000FFF0F71F280023940010063000028732F0
-:10AB8000000076AD001E7631001E7630FFE5C73836
-:10AB900067C07738FFF0F71F2800871A00002614D7
-:10ABA0000068C73847C07738FFF0F7332800872E92
-:10ABB000000076B4FFE5C7386FC07738FFF0F72B99
-:10ABC0002800231400649316FF6405AC0002872E4E
-:10ABD000000076AD001E76B4FFE5C7386FC0773849
-:10ABE000FFF0F71B2800249400629496FF6405ACE4
-:10ABF0000002872E000076AD001E76B4FFE5C73850
-:10AC00006FC07738FFF0F7272800251400609516ED
-:10AC1000FF6405AC0002872E000076AD001E76B4FE
-:10AC2000FFE5C7386FC07738FFF0F72B28002314F3
-:10AC3000005E9316FF6405AC0002872E000076AD1F
-:10AC4000001E76B4FFE5C7386FC07738FFF0F71BFA
-:10AC500028002494005C9496FF6405AC0002872EC3
-:10AC6000000076AD001E76B4FFE5C7386FC07738B8
-:10AC7000FFF0F72728002514005A9516FF6405AC4D
-:10AC80000002872E000076AD001E76B4FFE5249406
-:10AC90000050C7386FC07738FFF0F72B2800231417
-:10ACA000005805AC0002872E00009316FF6475ADB6
-:10ACB000001E75ACFFE5C7385FC07738FFF0F71BA3
-:10ACC00028009613FFFC9496FF8C9493FFFC078852
-:10ACD0000008E000D2589793FFFC8516FF8C2314E0
-:10ACE00000389513FFFC278000079793FFFC93160D
-:10ACF000FF849313FFFC07880008E000CF2497939C
-:10AD0000FFFC27800007F7854258278000079793AC
-:10AD1000FFFCF4844264000000019493FFFC85165C
-:10AD2000FF84000000019513FFFC8316FF940000D0
-:10AD300000019313FFFC07880008E000F7C8979311
-:10AD4000FFFC20220000E600AD5D00000001F704DA
-:10AD500042580000000107380001F7054258F70487
-:10AD60002D38F6862C2806380001F6052D3877395F
-:10AD70000002F482001C20320044E600AEE4B4BAC3
-:10AD80006802E000AEE4F0052D38F7044078F58461
-:10AD90004F580738001686BA0000F4063B90773902
-:10ADA000001E7738FFE5C6B477C076B4FFF076357D
-:10ADB0000006A72E6002C52C600076A9001E76B49E
-:10ADC000FFE5C7386FC07739FFF077390003C73820
-:10ADD00040000738000286BA00007739001E773835
-:10ADE000FFE5C6B477C073B7FFF0EE00AE55951619
-:10ADF000FF64A72E600276A9001E76B4FFE5C7386F
-:10AE00006FC07739FFF077390003C738400086BA42
-:10AE10000004231400887739001E7738FFE5C6B494
-:10AE200077C076B5FFF0A6AA6802771D0003C73881
-:10AE3000680027380008853A000484BA0000000042
-:10AE40000001951A0004949A00008596FF7CE000AA
-:10AE5000AE78000000018496FF64A72E600276A5FC
-:10AE6000001E76B4FFE5C7386FC07739FFF0773939
-:10AE70000003C738400085BA00048516FF64F60653
-:10AE80003B90872A000076A9001E76B4FFE5C738FC
-:10AE90006FC07739FFF077390003A6BA6002201E31
-:10AEA0000000C73860007739001E7738FFE5C6B468
-:10AEB00077C0EE00AEC976B5FFF08316FF780000CC
-:10AEC00000017719FFF0C6B868008496FF6400009F
-:10AED0000001C72468009713FFFC07880008C12CF5
-:10AEE00000009793FFFC8796FFFC8296FFF8021400
-:10AEF0000000013C0000000000019293FFFC029062
-:10AF0000000822100010F704408400000001203ADD
-:10AF10000000E600AF3CF60642B8F70442B876B14E
-:10AF2000001E76B4FFE5F3063678F3054244C738D1
-:10AF30006FC07739FFF007380001F7332800F704B6
-:10AF40004F5CF384425C833A0004C43800009316DB
-:10AF5000FFEC771D0001C73838007739000204B8CC
-:10AF6000000C8316FFEC00000001C01E3200EC0054
-:10AF7000B070C5040000A6A24802F704E000F58204
-:10AF80000000C0367200E600AFA8C620480086B2B6
-:10AF90000004F704E00400000001C0367200E6007F
-:10AFA000AFAC202E0000F5820001202E0000E6004C
-:10AFB000AFB900000001F502000086B20000F704FE
-:10AFC000E00000000001C0367200E200AFF4F5823C
-:10AFD0000000C0367200E600AFFC202E000086B2F2
-:10AFE0000004F704E00400000001C0367200E20033
-:10AFF000AFFD202E0000F5820001202E0000E600AB
-:10B00000B00D202A0000F5020001202A0000E60011
-:10B01000B05900000001F7047AD000000001203A86
-:10B020000000E600B064C7204800873A0008F60632
-:10B03000409877390002A6BA6002C73860007739B5
-:10B04000001E7738FFE5C6B477C076B5FFF020362E
-:10B050000000E600B0640000000104A4000CE00061
-:10B06000AF60039C00018316FFEC00000001C01ECE
-:10B070003200EC00B104F3063678F6844F5C771D9D
-:10B080000001C7383800773900020738000CC6B411
-:10B09000700087360008F6844F5877390006C6B42A
-:10B0A00070009693FFFC9396FFF407880008E00079
-:10B0B000FA989793FFFC20220000F684426C839656
-:10B0C000FFF4470C0001D7000A70C71C7000F70599
-:10B0D000425C06B40001F7042D38F685426CF68612
-:10B0E0002C2806380001F6052D3877390002F302C6
-:10B0F000001C20320044E600B108B33A6802E000C8
-:10B10000B108F0052D38F30542448796FFFC82967E
-:10B11000FFF802140000013C0000000000019293BF
-:10B12000FFFC02900008F4020000C5A00000F682B7
-:10B130000770F7046E5020360000E600B16D063847
-:10B14000001C8732000000000001C4207000C022F3
-:10B150007200E400B15D0000000105AC000126B4FE
-:10B16000000120360000E600B14006300004C42093
-:10B170005800C0225A00E400B18100000001042000
-:10B1800000018796FFFC8296FFF802140000013C44
-:10B190000000000000019293FFFC02900008078865
-:10B1A0000008E00078D89793FFFC07880008E000CB
-:10B1B000B11C9793FFFCF704409400000001C022EB
-:10B1C0007200E600B1EDF4054090F7046E50000007
-:10B1D000000186BA1DDCF582000106B4000196BAB2
-:10B1E0001DDC873A1DDCE000B1F0F5857AD0F00572
-:10B1F0007AD0F5844090F0054084F5854094F5863A
-:10B20000E0009593FFFC07880008E000D5A0979325
-:10B21000FFFCF7046E50F405408485BA1DDC000085
-:10B220000001F5853B64F584E000F005425C95BAC9
-:10B230000010F584E004F6862C2895BA0014F70473
-:10B240002D38F5863A4CF585424406380001F6055E
-:10B250002D3877390002F582001C20320044E600C8
-:10B26000B268B5BA6802F0052D38F58635ECF5857B
-:10B2700042308796FFFC8296FFF802140008013CDA
-:10B280000000000000019293FFFC029000082210D1
-:10B2900000C8F30200009316FF94248000089496DF
-:10B2A000FF84238000078316FF940000000193169B
-:10B2B000FF54201E0007EE00B564C71C38008496BA
-:10B2C000000000000001C72470000738002686BA7D
-:10B2D0000000F5844F587739001E7738FFE5C6B473
-:10B2E00077C076B5FFF0F70200FFC6B67400E6003F
-:10B2F000B32D20360001E600B32D77350006A6BA3F
-:10B300005802C73858007639001E7630FFE5C6B4BB
-:10B3100067C076B5FFF020360002E600B331C6B84C
-:10B320000000C72C0000E000B330C6B80000F6846F
-:10B330004F58F7044F58C5340000C02A7200E60089
-:10B34000B55D00000001F6843BBCF30200009316DB
-:10B35000FF3C0428001CF7043BB800000001C03685
-:10B360007200EC00B4409696FFAC77350001C73808
-:10B37000680077390002F4863BB4C63848000630CE
-:10B38000000CC30400009316FF3486B20000872A25
-:10B39000001C8596FF3CC0367200E600B3C0202E2C
-:10B3A000000086B20004872A002000000001C03699
-:10B3B0007200E600B3C0202E0000F5820001202EAE
-:10B3C0000000E600B3D100000001F4820000949672
-:10B3D000FF3486B200008722000000000001C03662
-:10B3E0007200E200B40CF5820000C0367200E60084
-:10B3F000B414202E000086B200048722000400004E
-:10B400000001C0367200E200B415202E0000F58263
-:10B410000001202E0000E600B42500000001F30228
-:10B4200000019316FF348496FF34000000012026AB
-:10B430000000E600B44000000001F3020001931692
-:10B44000FF3C8496FF3C0000000120260000E6003F
-:10B45000B481F60200018716FFACF3063BB476B95F
-:10B460000001C6B4700076B50002C6B4300006B460
-:10B47000001486B600009716FFB0E000B4F496966C
-:10B48000FFB4271400549713FFFC9413FFFCF486B9
-:10B490003BB49493FFFC9396FF4C9516FF440788AA
-:10B4A0000008E00125689793FFFC8396FF4C851602
-:10B4B000FF4420220000E600B4F1F60200018716E6
-:10B4C000FFACF3063BB476B90001C6B4700076B5A4
-:10B4D0000002C6B4300006B4001486B60000971609
-:10B4E000FFB09696FFB4F7053BBCE000B4F82032FD
-:10B4F0000000F602000020320000E600B52D2714FF
-:10B5000000088496FF5400000001C72470008316D1
-:10B51000FFB404A400049496FF548496FF94933AD5
-:10B52000FFC004A40001E000B5549496FF94831674
-:10B53000FF5400000001C7187000F4844F5803182E
-:10B5400000049316FF548316FF9494BAFFC00318A7
-:10B5500000019316FF949516FF3C9396FF8CE00034
-:10B56000B2B0039C00018496FF94000000012026E5
-:10B570000000E600B584F3820001F4044F58E000B7
-:10B58000BEE4000000018316FFB88496FF9400001B
-:10B590000001C01E4A00EC00B5CC9316FF7C269437
-:10B5A00000048736FFC08316FF7C00000001C03A0C
-:10B5B0003200E600BB98039C00018496FF940000D3
-:10B5C0000001C01E4A00EC00B5A106B40004F4045A
-:10B5D0004F588316FF7C00000001C01A4200E600AD
-:10B5E000BA2DF48200009496FF7423800007201E79
-:10B5F0000007EE00B748C71C38008316FF7C000028
-:10B600000001C71870000738002686BA0000F584CC
-:10B610004F587739001E7738FFE5C6B477C076B546
-:10B62000FFF0F70200FFC6B67400E600B6692036E8
-:10B630000001E600B66977350006A6BA5802C73899
-:10B6400058007639001E7630FFE5C6B467C076B57F
-:10B65000FFF020360002E600B66DC6B80000C72C29
-:10B660000000E000B66CC6B80000F6844F58F7043E
-:10B670004F58C5340000C02A7200E600B741C584A7
-:10B6800000008496FF7486AA001C8316FF3CF60215
-:10B69000000004A400019496FF74871A001C04A8FB
-:10B6A000001C9496FF34C0367200E600B6CC041835
-:10B6B000001C86AA0020871A002000000001C03666
-:10B6C0007200E600B6D020320000F60200012032FF
-:10B6D0000000E600B6DD00000001F58200008316E0
-:10B6E000FF3487220000869A000000000001C03667
-:10B6F0007200E200B71CF6020000C0367200E600DD
-:10B70000B72420320000869A00048722000400003B
-:10B710000001C0367200E200B72520320000F602B8
-:10B72000000120320000E600B735202E0000F5822F
-:10B730000001202E0000E600B740000000019396B3
-:10B74000FF84E000B5EC039C00018496FF7483162F
-:10B75000FF9400000001C0263200E600BB982300E1
-:10B7600000088496FF8400000001C0263200E60035
-:10B77000BB99F6020000F684407CF7044074C6B41E
-:10B780006800C73868000738002686BA0000773995
-:10B79000001E7738FFE5C6B477C077B40008703E66
-:10B7A000FFE8470C0001D7000A70203A0000E600CD
-:10B7B000B804F58200FF8496FF848316FF8C000096
-:10B7C0000001C72432008496FF7CC7387000C7246C
-:10B7D00070000738002686BA00007739001E7738D7
-:10B7E000FFE5C6B477C076B5FFF0C6B45C00C036DE
-:10B7F0006200470C0001D7000A70203A0000E60002
-:10B80000B80D20320000F602000120320000E600F0
-:10B81000BB9823800007201E0007EE00B8C8C71C95
-:10B8200038008316000000000001C71870000738B8
-:10B83000002686BA0000F5844F587739001E773805
-:10B84000FFE5C6B477C076B5FFF0F70200FFC6B6D5
-:10B850007400E600B89120360001E600B891773513
-:10B860000006A6BA5802C73858007639001E76304E
-:10B87000FFE5C6B467C076B5FFF020360002E600EB
-:10B88000B895C6B80000C72C0000E000B894C6B850
-:10B890000000F6844F58F7044F58C5340000C02A02
-:10B8A0007200E600B8C1000000019513FFFC9396FA
-:10B8B000FF4C07880008E000CC609793FFFC83965C
-:10B8C000FF4CE000B814039C00018496FF848316AB
-:10B8D000FF8CF384407CF5044074C4A43200949639
-:10B8E000FF348316FF34C59C3800C5A8580005AC4A
-:10B8F000002686AE0000772D001E7738FFE5742DF8
-:10B90000001E7420FFE5739D0010739DFFF8C4A412
-:10B9100030009496FF3C8316FF7CC6B477C0C49871
-:10B9200048009496FF3C04A400269496FF3C73259F
-:10B93000001E7318FFE59316FF6C74A5001E949605
-:10B94000FF6474A4FFE59496FF648316FF7CF4847F
-:10B950004F5876B5FFF0C6184A007630FFFA4631E8
-:10B960000000F30200FFC6303400F482FF00C6B4CA
-:10B970004C00C6306800F62F2800872E0000831682
-:10B98000FF34C73847C07739FFF07319001093169A
-:10B99000FF347499FFF8F30200FFC7383400C7245E
-:10B9A00070009716FF34249400CA84A6000077A57F
-:10B9B000001E77BCFFE5C4A47FC074A5FFF083160A
-:10B9C000FF3CF4AF2800F4844F58871A0000C528C4
-:10B9D0004A007528FFFA8316FF6C45290000F4829F
-:10B9E00000FFC5284C008496FF3CC73837C0773924
-:10B9F000FFF0F302FF00C7383400C5287000F527B8
-:10BA00002800872600008316FF648416FF7CC73851
-:10BA100037C07739FFF0F48200FFC7384C00831637
-:10BA2000FF3CC39C7000E000BEE4F39B2800F704D9
-:10BA3000407CF6044074C7387000C7307000073887
-:10BA4000002686BA00007739001E7738FFE5C6B4B5
-:10BA500077C077B40008703EFFE8470C0001D700BC
-:10BA60000A70203A0000E600BA7D25800007E00059
-:10BA7000BEE404200040E000BAD8C42C0000C73067
-:10BA80004200849600007538FFFA0624000A202E32
-:10BA90000007EE00BAD40730000E86BA00007739EE
-:10BAA000001E7738FFE5C6B477C076B5FFF0F70221
-:10BAB00000FFC6B4740047290000C0367200470C6E
-:10BAC0000001203A0000E600BA7406300002E000EF
-:10BAD000BA8C05AC0001F402000807200007203AE8
-:10BAE000000EE200BBA4C5A0400083160000F504D0
-:10BAF000407CF48200FFF6044F58C598580005AC0E
-:10BB0000002686AE0000772D001E7738FFE5C618A8
-:10BB100062007630FFFA46310000C6304C00C6B4F1
-:10BB200077C076B5FFF0772900107739FFF8C6B4F3
-:10BB30004C00C7386800F72F2800F5844074C528EA
-:10BB40005000C5AC500005AC002686AE0000772D35
-:10BB5000001E7738FFE5752D001E7528FFE5C6B479
-:10BB600077C076B5FFF0F702FF00C6B47400C630A8
-:10BB70006800F62F2800872E000076A1001076B509
-:10BB8000FFF8C73857C07739FFF0C7384C00C6B444
-:10BB90007000E000BBF8F6AF2800F4044F58E00056
-:10BBA000BEE404200040F6044F5883160000F7045A
-:10BBB000407CF5844074C61862007630FFFAC738BE
-:10BBC0007000C5AC700005AC002686AE0000772D75
-:10BBD000001E7738FFE546310000C6B477C076B561
-:10BBE000FFF0F70200FFC6307400F702FF00C6B492
-:10BBF0007400C6306800F62F280023800007201E3E
-:10BC00000007EE00BEE0C71C38008496000000006C
-:10BC10000001C72470000738002686BA0000F584AA
-:10BC20004F587739001E7738FFE5C6B477C076B530
-:10BC3000FFF0F70200FFC6B67400E600BC792036BC
-:10BC40000001E600BC7977350006A6BA5802C7386D
-:10BC500058007639001E7630FFE5C6B467C076B569
-:10BC6000FFF020360002E600BC7DC6B80000C72CFD
-:10BC70000000E000BC7CC6B80000F6844F58F70412
-:10BC80004F58C5340000C02A7200E600BED906A88D
-:10BC9000001C83160000000000019313FFFC969324
-:10BCA000FFFCF4863BB49493FFFC9396FF4C9516EF
-:10BCB000FF449696FF4007880008E00123409793D1
-:10BCC000FFFCF3044F5CF48200009496FF5C8696C0
-:10BCD000FF408396FF4C8516FF449316FF34861A67
-:10BCE00000089696FF3C871A000400000001C0324D
-:10BCF0007200EC00BDB89616FF9C77310001C73882
-:10BD0000600077390002C63830000630000C86B279
-:10BD10000000872A001C8596FF5CC0367200E60092
-:10BD2000BD40C404000086B20004872A0020000041
-:10BD30000001C0367200E600BD44202E0000F582EE
-:10BD40000001202E0000E600BD5100000001F402B9
-:10BD500000008316FF3C86B20000871A0000000036
-:10BD60000001C0367200E200BD90F5820000C036CE
-:10BD70007200E600BD98202E000086B20004871AEB
-:10BD8000000400000001C0367200E200BD99202EC0
-:10BD90000000F5820001202E0000E600BDA920224F
-:10BDA0000000F402000120220000E600BDB80000FF
-:10BDB0000001F48200019496FF5C8316FF5C000092
-:10BDC0000001201A0000E600BDF9F6020001871606
-:10BDD000FF9C8496FF3476B90001C6B4700076B536
-:10BDE0000002C6B4480006B4001486B600009716D8
-:10BDF000FFA0E000BE709696FFA42714006497137E
-:10BE0000FFFC8316FF3C000000019313FFFC8496A7
-:10BE1000FF34000000019493FFFC9396FF4C9516AD
-:10BE2000FF4407880008E00125689793FFFC83968C
-:10BE3000FF4C8516FF4420220000E600BE71F6028A
-:10BE400000008716FF9C8316FF3476B90001C6B444
-:10BE5000700076B50002C6B4300006B4001486B691
-:10BE600000009716FFA09696FFA4971A0008F60206
-:10BE7000000120320000E600BE99F606429CF7045D
-:10BE8000429C76B1001E76B4FFE5C7386FC07739A3
-:10BE9000FFF007380001F7332800F7044F5800007F
-:10BEA0000001C72872007738FFFA4739000097135E
-:10BEB000FFFC0728001C9713FFFCF4844F5C000074
-:10BEC00000019493FFFC9396FF4C07880008E00163
-:10BED00023409793FFFC8396FF4CE000BBFC039C40
-:10BEE0000001841600008796FFFC8296FFF802147A
-:10BEF0000004013C0000000000019293FFFC02904E
-:10BF0000000822100060851600008616000406A8AE
-:10BF10000018C7306000C5B8680020320007EE0086
-:10BF2000BF64072C000E86BA00007739001E7738F0
-:10BF3000FFE5C6B477C076B5FFF0F70200FFC6B4E0
-:10BF4000740020360000470C0001D7000A70203A28
-:10BF50000000E600BF6105AC0002E000BF1806303B
-:10BF6000000120320007EE00C04C06A80016F505BF
-:10BF70004074F605407CF3020006F3054254961324
-:10BF8000FFFC052800029516FFC49513FFFC2394BF
-:10BF900000209396FFBC9393FFFC9616FFAC078896
-:10BFA0000008E000D0DC9793FFFC8496FFC42314C4
-:10BFB00000389493FFFC9316FFB49313FFFC07889B
-:10BFC0000008E000D2589793FFFC8702FF348616E2
-:10BFD000FFACF70542649613FFFC9713FFFC8396B2
-:10BFE000FFB4000000019393FFFC8496FFBC0000A7
-:10BFF00000019493FFFC07880008E000F7C89793BE
-:10C00000FFFC20220000E600C01DF3063AD8F7042A
-:10C0100042540000000127380001F7054254F3059F
-:10C020004244F38217709393FFFCF482001B9493B5
-:10C03000FFFCF30642449313FFFC07880008E0016D
-:10C040001EC09793FFFCE000C1A0000000018736EE
-:10C050000000F5844F58F4063B7076B5001E76B4A8
-:10C06000FFE5C7386FC07738FFF076390006A72E96
-:10C070006002C52C600076A9001E76B4FFE5C738C3
-:10C080006FC07739FFF077390003C73840000738B1
-:10C09000000286BA00007739001E7738FFE5C6B483
-:10C0A00077C076B7FFF0EE00C1159696FF9CA72EDD
-:10C0B000600276A9001E76B4FFE58396FF9CC73820
-:10C0C0006FC07739FFF077390003C738400086BA70
-:10C0D0000004249400607739001E7738FFE5C6B469
-:10C0E00077C076B5FFF0A6AA6802771D0003C738AF
-:10C0F00068002738000883BA0004833A0000000073
-:10C10000000193A60004932600008596FFA4E0009A
-:10C11000C13823000007A72E600276A9001E76B45E
-:10C12000FFE5C7386FC07739FFF077390003C738AC
-:10C13000400085BA0004230000079313FFFC872A00
-:10C14000000076A9001E76B4FFE58396FF9CF606F4
-:10C150003B70C7386FC07739FFF077390003A6BA54
-:10C160006002201E0000C73860007739001E773853
-:10C17000FFE5C6B477C0EE00C18D76B5FFF08496BA
-:10C18000FFA0000000017725FFF0C6B86800C728AF
-:10C1900068009713FFFC07880008C12C00009793E4
-:10C1A000FFFC8796FFFC8296FFF802140008013C12
-:10C1B0000000000000019293FFFC02900008221092
-:10C1C000007025000007202A0007EE00C3B8C7282A
-:10C1D00050008316000000000001C71870000738E7
-:10C1E000002686BA0000F5844F587739001E77384C
-:10C1F000FFE5C6B477C076B5FFF0F70200FFC6B61C
-:10C200007400E600C23D20360001E600C23D7735ED
-:10C210000006A6BA5802C73858007639001E763094
-:10C22000FFE5C6B467C076B5FFF020360002E60031
-:10C23000C24DC03A5A00E000C248C72C0000F704C3
-:10C240004F58F5844F5800000001C03A5A00E600EC
-:10C25000C3B1F4863B908396000000000001069C69
-:10C2600000168736000076B5001E76B4FFE5C738A5
-:10C270006FC07738FFF076390006A72E6002C52C14
-:10C28000600076A9001E76B4FFE5C7386FC0773925
-:10C29000FFF077390003C73848000738000286BA34
-:10C2A00000007739001E7738FFE5C6B477C076B74F
-:10C2B000FFF0EE00C3219696FF8CA72E600276A9B0
-:10C2C000001E76B4FFE58316FF8CC7386FC0773940
-:10C2D000FFF077390003C738480086BA0004249479
-:10C2E00000707739001E7738FFE5C6B477C076B5A1
-:10C2F000FFF0A6AA680277190003C738680027383C
-:10C30000000883BA0004833A00000000000193A6ED
-:10C310000004932600008616FF94E000C34400004A
-:10C320000001A72E600276A9001E76B4FFE5F30691
-:10C330003B90C7386FC07739FFF077390003C738B3
-:10C340003000863A0004872A000076A9001E76B4E1
-:10C35000FFE58396FF8CF4863B90C7386FC0773932
-:10C36000FFF077390003A6BA4802201E0000C73844
-:10C3700048007739001E7738FFE5C6B477C0EE0075
-:10C38000C39576B5FFF08316FF9000000001771982
-:10C39000FFF0C6B86800C72868009713FFFC07883D
-:10C3A0000008C13000009793FFFCE000C5C4000006
-:10C3B0000001E000C1C40528000183960000F4825A
-:10C3C0000006F4854254F60442602514001E23142E
-:10C3D00000209316FFACF3854078063000028732C8
-:10C3E000000076B1001E76B4FFE50630000275B19C
-:10C3F000001EC7386FC07738FFF0F71B2800873260
-:10C40000000075ACFFE5C7385FC07738FFF0F72B49
-:10C4100028002514001C063000028732000076B187
-:10C42000001E76B4FFE5C7386FC07738FFF0F72BF2
-:10C4300028002514001A063000028732000076B169
-:10C44000001E76B4FFE5C7386FC07738FFF0F72BD2
-:10C45000280025140018063000028732000076B14B
-:10C46000001E76B4FFE5C7386FC07738FFF0F72BB2
-:10C47000280025140016063000028732000076B12D
-:10C48000001E76B4FFE5C7386FC07738FFF0F72B92
-:10C49000280025140014063000028732000076B10F
-:10C4A000001E76B4FFE5C7386FC07738FFF0F72B72
-:10C4B000280025140012063000028732000076B1F1
-:10C4C000001E76B4FFE5C7386FC07738FFF0F72B52
-:10C4D0002800063000028732000025140010763153
-:10C4E000001E7630FFE5C73867C07738FFF0F72BBE
-:10C4F0002800071C00029713FFFC2394005093961A
-:10C50000FFA49393FFFC07880008E000D25897939C
-:10C51000FFFC8496FFA4231400389493FFFC27802B
-:10C5200000079793FFFC9316FF9C9313FFFC07886B
-:10C530000008E000CF249793FFFC8702FF34278098
-:10C540000007F7854258F705426427800007979354
-:10C55000FFFC9713FFFC8396FF9C00000001939360
-:10C56000FFFC8496FFAC000000019493FFFC078859
-:10C570000008E000F5F49793FFFC20220000E6009D
-:10C58000C59500000001F70442580000000107387B
-:10C590000001F7054258F7042D38F30639C0F305BA
-:10C5A0004244F6862C2806380001F6052D387739E6
-:10C5B0000002F382001C20320044E600C5C4B3BA76
-:10C5C0006802F0052D388796FFFC8296FFF802146A
-:10C5D0000004013C0000000000019293FFFC029067
-:10C5E000000825000007F7044074F6844F58F6044D
-:10C5F0004260C7386A0075B8FFFA0630000A202A80
-:10C600000007EE00C6480730000E86BA00007739F2
-:10C61000001E7738FFE5C6B477C076B5FFF0F702A5
-:10C6200000FFC6B47400472D0000C0367200470CEE
-:10C630000001203A0000E600C64CC3280000063086
-:10C640000002E000C5FC05280001F3020008C5183F
-:10C650003000F3844260F6044F58F704407CF484C1
-:10C660004074C51C50000528002685AA00007429C6
-:10C67000001E7420FFE5C61C62007630FFFAC6B8C3
-:10C680007000C4A4680004A4002676A5001E76B439
-:10C69000FFE5773900107739FFF846310000C5AC67
-:10C6A00047C075ADFFF0F40200FFC5AC4400C738C9
-:10C6B0005800F72B28008726000075A5001EC630FD
-:10C6C000440075ACFFE5C7386FC07739FFF0F682DC
-:10C6D000FF00C7386C00C6307000F6272800872698
-:10C6E00000007699001076B5FFF8C7385FC077393B
-:10C6F000FFF0C7384400C6B47000F6A72800939333
-:10C70000FFFCF3843BB0000000019393FFFC07881B
-:10C710000008E000D42C9793FFFCF704407C000055
-:10C720000001073800019713FFFCF38440740000F8
-:10C7300000019393FFFC07880008E000BEF8979380
-:10C74000FFFC8796FFFC8296FFF802140004013C70
-:10C750000000000000019293FFFC02900008879601
-:10C76000FFFC8296FFF802140008013C0000000064
-:10C7700000019293FFFC029000088796FFFC8296CE
-:10C78000FFF802140004013C000000000001929335
-:10C79000FFFC029000088796FFFC8296FFF80214C7
-:10C7A0000000013C0000000000019293FFFC029099
-:10C7B0000008F70642309713FFFCF7063560971321
-:10C7C000FFFC07880008E00014F49793FFFCF706CD
-:10C7D00042309713FFFCF70635EC9713FFFC0788F0
-:10C7E0000008E00014F49793FFFCF7064244971307
-:10C7F000FFFCF70636789713FFFC07880008E00077
-:10C8000014F49793FFFCF70642449713FFFCF706D6
-:10C8100037049713FFFC07880008E00014F497938F
-:10C82000FFFCF70642449713FFFCF7063790971377
-:10C83000FFFC07880008E00014F49793FFFCF7065C
-:10C8400042449713FFFCF706381C9713FFFC078838
-:10C850000008E00014F49793FFFCF7064244971396
-:10C86000FFFCF70638A89713FFFC07880008E000D4
-:10C8700014F49793FFFCF70642449713FFFCF70666
-:10C8800039349713FFFC07880008E00014F49793ED
-:10C89000FFFCF70642449713FFFCF70639C09713D5
-:10C8A000FFFC07880008E00014F49793FFFCF706EC
-:10C8B00042449713FFFCF7063A4C9713FFFC078896
-:10C8C0000008E00014F49793FFFCF7064244971326
-:10C8D000FFFCF7063AD89713FFFC07880008E00032
-:10C8E00014F49793FFFC8796FFFC8296FFF80214DE
-:10C8F0000000013C0000000000019293FFFC029048
-:10C90000000885960000F5063B90872E000076AD66
-:10C91000001E76B4FFE5C7386FC07739FFF077396E
-:10C920000003C73850000738000286BA0000773984
-:10C93000001E7738FFE5C6B477C07637FFF0EE000B
-:10C94000C99500000001872E000076AD001E76B468
-:10C95000FFE5C7386FC07739FFF077390003C73874
-:10C96000500086BA00047739001E7738FFE5C6B458
-:10C9700077C076B5FFF0A6AE680277310003C738FE
-:10C9800068002738000884BA0004843A0000E000F8
-:10C99000C9B4C5240000872E000076AD001E76B411
-:10C9A000FFE5C7386FC07739FFF077390003C73824
-:10C9B0005000853A0004872E000076AD001E76B444
-:10C9C000FFE520320000F6063B90C7386FC077398C
-:10C9D000FFF077390003A6BA6002C73860007739E4
-:10C9E000001E7738FFE5C6B477C0EE00C9F976B50A
-:10C9F000FFF07721FFF0C6B86800C72C68009713D6
-:10CA0000FFFC07880008C12800009793FFFC879669
-:10CA1000FFFC8296FFF802140004013C00000000B5
-:10CA200000019293FFFC0290000885960000F50635
-:10CA30003B70872E000076AD001E76B4FFE5C73848
-:10CA40006FC07739FFF077390003C73850000738D7
-:10CA5000000286BA00007739001E7738FFE5C6B4B9
-:10CA600077C07637FFF0EE00CABD00000001872EC8
-:10CA7000000076AD001E76B4FFE5C7386FC0773989
-:10CA8000FFF077390003C738500086BA00047739C1
-:10CA9000001E7738FFE5C6B477C076B5FFF0A6AEC6
-:10CAA000680277310003C73868002738000884BA65
-:10CAB0000004843A0000E000CADCC5240000872E90
-:10CAC000000076AD001E76B4FFE5C7386FC0773939
-:10CAD000FFF077390003C7385000853A0004839689
-:10CAE000000476AD001E76B4FFE52032000093937B
-:10CAF000FFFC872E0000F6063B70C7386FC0773901
-:10CB0000FFF077390003A6BA6002C73860007739B2
-:10CB1000001E7738FFE5C6B477C0EE00CB2976B5A6
-:10CB2000FFF07721FFF0C6B86800C72C68009713A4
-:10CB3000FFFC07880008C12800009793FFFC879638
-:10CB4000FFFC8296FFF802140008013C0000000080
-:10CB500000019293FFFC02900008F5044F58F58203
-:10CB6000000206280080202E0062EE00CB900730E5
-:10CB70000040F0332800C6B8520076B4FFFA063001
-:10CB80000014F6B32800C6380000E000CB6405AC02
-:10CB90000001F7044F580000000106B818D4F482D1
-:10CBA0000001F4B72800073818C0F03B2800F7064A
-:10CBB00042C0F4820002F4BB28008796FFFC8296F4
-:10CBC000FFF802140000013C0000000000019293F5
-:10CBD000FFFC02900008F68442C0F60642C077319E
-:10CBE000001E7738FFE575B1001EC6B477C076B475
-:10CBF000FFF0F7044F5876B50006C4386800872266
-:10CC0000001476A1001E76B4FFE5C7386FC07738F0
-:10CC1000FFF0F7332800F70442C075ACFFE5C738D2
-:10CC20005FC07738FFF0203A0001E600CC4CF606F2
-:10CC30004290F704429076B1001E76B4FFE5C73803
-:10CC40006FC07739FFF007380001F7332800879667
-:10CC5000FFFC8296FFF802140000013C0000000077
-:10CC600000019293FFFC0290000822100004851638
-:10CC70000000000000019513FFFC9516FFF40788E3
-:10CC80000008E000CD009793FFFC8516FFF42022FA
-:10CC90000000E600CCBCF58642C0F7044290F606E0
-:10CCA000429276B1001E76B4FFE5C7386FC077397F
-:10CCB000FFF007380001E000CCECF7332800F02B40
-:10CCC0002800F68442C0772D001E7738FFE506283D
-:10CCD0000014C6B477C076B4FFF0F7044F58F6B32B
-:10CCE0002800C72872007738FFFAF72F28008796A8
-:10CCF000FFFC8296FFF802140004013C00000000D3
-:10CD000000019293FFFC0290000886960000F70451
-:10CD10004F58F4020000C6B472007734FFFA273887
-:10CD20000002203A0061F702003FE200CD40C6B4A5
-:10CD3000740020360000E600CD4000000001F4023F
-:10CD400000018796FFFC8296FFF802140004013C64
-:10CD50000000000000019293FFFC0290000886167C
-:10CD600000008716000885960004C5307000C032A8
-:10CD70005200E600CDA10000000186B2000077312C
-:10CD8000001E7738FFE5C6B477C076B5FFE8F6AF8A
-:10CD9000680006300001C0325200E600CD7805ACD4
-:10CDA00000018796FFFC8296FFF80214000C013CFC
-:10CDB000000000000001000000009293FFFC0290C0
-:10CDC000000884960000841600048596000886A654
-:10CDD00000007725001E7738FFE5C6B477C07535AB
-:10CDE000FFF0202A0010E200CE0DF606428EF5027A
-:10CDF0000010F704428C76B1001E76B4FFE5C73808
-:10CE00006FC07739FFF007380001F7332800202E74
-:10CE10000001E600CE70202A0000EE00CE7107244B
-:10CE2000000225280001A5BA50028622000076A142
-:10CE3000001E76B4FFE5C73850007739001E7738FA
-:10CE4000FFE5C5AC77C0C6306FC07631FFF075AD79
-:10CE5000FFE8F68200FFF702F15475AD0002A72E3D
-:10CE60007002C6306C00C6307580F623280024207E
-:10CE7000000225A80001F302F24603A40002C4AC9C
-:10CE80003800252C0001202E0000EC00CF110000FE
-:10CE90000001E600CEA0C71C5000E000CEB4F602B0
-:10CEA0000000A69E50027739001E7738FFE5C6B411
-:10CEB00077C07635FFE886A600007725001E773814
-:10CEC000FFE52528000225AC0002C6B477C076B580
-:10CED000FFE877310004C738620077390001C738AE
-:10CEE0003000C6B46800C6B4700006B4000E8736C1
-:10CEF000000024A4000276B5001E76B4FFE5C73812
-:10CF00006FC07738FFF0F7232800E000CE8424209C
-:10CF100000028796FFFC8296FFF80214000C013C89
-:10CF20000000000000019293FFFC029000088616AA
-:10CF3000000883160004839600008732000076B153
-:10CF4000001E76B4FFE5059C0002749D001E74A4CB
-:10CF5000FFE5741D001E063000027531001EC73843
-:10CF60006FC07738FFF0F71F280087320000752860
-:10CF7000FFE5C73857C07738FFF0F72F280005AC1A
-:10CF80000002063000028732000076B1001E76B43F
-:10CF9000FFE5C7386FC07738FFF0F72F280005ACE2
-:10CFA0000002063000028732000076B1001E76B41F
-:10CFB000FFE5C7386FC07738FFF0F72F280005ACC2
-:10CFC0000002063000028732000076B1001E76B4FF
-:10CFD000FFE5C7386FC07738FFF0F72F280005ACA2
-:10CFE0000002063000028732000076B1001E76B4DF
-:10CFF000FFE5C7386FC07738FFF0F72F280005AC82
-:10D000000002063000028732000076B1001E76B4BE
-:10D01000FFE5C7386FC07738FFF0F72F280005AC61
-:10D020000002063000028732000076B1001E76B49E
-:10D03000FFE5C7386FC07738FFF0F72F28000630BC
-:10D0400000028732000005AC00027631001E763007
-:10D05000FFE5C73867C07738FFF0F72F2800871E35
-:10D0600000007420FFE5C7384FC07739FFF007385C
-:10D070000001F71F2800871E0000049C0002C7382B
-:10D0800047C07739FFF025380001202A0000EE0064
-:10D09000D0BD26280001A7266002C6A4600076B590
-:10D0A000001E76B4FFE5C5A45000C5300000C738A7
-:10D0B0006FC07739FFE8E000D088F72F6800071CC1
-:10D0C0000002F33B6800C41C00008796FFFC8296B8
-:10D0D000FFF80214000C013C0000000000019293D4
-:10D0E000FFFC0290000886160004841600008732B8
-:10D0F000000076B1001E76B4FFE505A0000274A121
-:10D10000001E74A4FFE5063000027531001EC7380A
-:10D110006FC07738FFF0F7232800873200007528AA
-:10D12000FFE5C73857C07738FFF0F72F280005AC68
-:10D130000002063000028732000076B1001E76B48D
-:10D14000FFE5C7386FC07738FFF0F72F280005AC30
-:10D150000002063000028732000076B1001E76B46D
-:10D16000FFE5C7386FC07738FFF0F72F280005AC10
-:10D170000002063000028732000076B1001E76B44D
-:10D18000FFE5C7386FC07738FFF0F72F280005ACF0
-:10D190000002063000028732000076B1001E76B42D
-:10D1A000FFE5C7386FC07738FFF0F72F280005ACD0
-:10D1B0000002063000028732000076B1001E76B40D
-:10D1C000FFE5C7386FC07738FFF0F72F280005ACB0
-:10D1D0000002063000028732000076B1001E76B4ED
-:10D1E000FFE5C7386FC07738FFF0F72F280005AC90
-:10D1F0000002063000028732000006A000027631ED
-:10D20000001E7630FFE5C73867C07738FFF0F72F8C
-:10D210002800872200007621001E85960008C73866
-:10D220004FC07739FFF0C6B47000F5B768008722A9
-:10D2300000007630FFE5C73867C07739FFF0073860
-:10D240000001F72328008796FFFC8296FFF802145E
-:10D25000000C013C0000000000019293FFFC0290D2
-:10D2600000082210002027140020F03B280084969C
-:10D270000004F502000086A600007625001E763028
-:10D28000FFE504240002C6B467C076B4FFF0F6BB25
-:10D2900028008726000076A5001E76B4FFE5C73873
-:10D2A0006FC07739FFF0C02A7200EC00D2F876A583
-:10D2B000001E8726000076B4FFE5062800012594AD
-:10D2C000001EC5AC5000C5300000C7386FC07739AC
-:10D2D000FFF0C7385200A6A27002C720700077394D
-:10D2E000001E7738FFE5C6B477C076B5FFE8C68084
-:10D2F0006A00E000D290F6AF68008716FFE076156E
-:10D30000001E7630FFE5839600002314001E7599F9
-:10D31000001E75ACFFE57515001E7528FFE57495B8
-:10D32000001E74A4FFE57415001E7420FFE5069C22
-:10D3300000027395001E9396FFDCC73867C0839682
-:10D3400000007738FFF0F71F28008396FFDC871A6C
-:10D350000000739CFFE59396FFDCC7385FC0773809
-:10D36000FFF0F737280006B400028716FFE4231405
-:10D37000001A7619001E7630FFE5C73857C0773897
-:10D38000FFF0F7372800871A000006B40002C738FC
-:10D3900067C07738FFF0F737280006B40002871619
-:10D3A000FFE8231400167619001E7630FFE5C73813
-:10D3B0004FC07738FFF0F7372800871A000006B40F
-:10D3C0000002C73867C07738FFF0F737280006B487
-:10D3D00000028716FFEC231400127619001E763027
-:10D3E000FFE5C73847C07738FFF0F7372800871ABE
-:10D3F000000006B4000284160000C73867C0773802
-:10D40000FFF0F73728008716FFF006B40002C73890
-:10D410003FC07738FFF0F73728008796FFFC8296E9
-:10D42000FFF802140008013C000000000001929384
-:10D43000FFFC029000088616000084160004F684A3
-:10D440004F5887320014033000147519001E7528D8
-:10D45000FFE5C3A06A00739CFFFA04A0001475A541
-:10D46000001EC6306A007630FFFAC73857C07738DA
-:10D47000FFF0F7272800F39B280007200016F63B53
-:10D4800028008722001475ACFFE5C7385FC07738E5
-:10D49000FFF077390006C6B4700006B40016F3B783
-:10D4A00028008796FFFC8296FFF802140008013CD2
-:10D4B0000000000000019293FFFC02900008861615
-:10D4C0000000F5844F5805300016872A000076A921
-:10D4D000001E76B4FFE5C7386FC07738FFF07739A4
-:10D4E0000006C42C7000C0226200E600D52906A008
-:10D4F000001687360000C6305A007630FFFA76B53F
-:10D50000001E76B4FFE5C7386FC07738FFF0773973
-:10D51000000676B8FFFAF6AB2800C72C7000073873
-:10D520000014E000D52CF63B2800C42C00008796A0
-:10D53000FFFC8296FFF802140004013C000000008A
-:10D5400000019293FFFC02900008F7064F844738D1
-:10D55000FFFCF7056F30F686505C46B4FFFCF6859D
-:10D560006E50F7066E7C4738FFFCF7056E540734A3
-:10D57000191CF7054F5CF70200649736191CF70277
-:10D5800000009736192006B4001CF6854F58879680
-:10D59000FFFC8296FFF802140000013C000000002E
-:10D5A00000019293FFFC0290000822100090F30209
-:10D5B000FFFFF3054F54F38200009396FFAC231452
-:10D5C00000209316FF9C239400389396FF948316B3
-:10D5D000FFACF7044F5CF382000C9396FF74931634
-:10D5E000FF8C873A0004000000019716FFA4831601
-:10D5F000FFAC8396FFA400000001C01A3A00EC00C3
-:10D60000DB78F30204BCF7044F5C8316FF74000060
-:10D610000001C7383000873A0008F6844F58773940
-:10D620000006C4B470009493FFFC9496FF7C0788B6
-:10D630000008E000CD009793FFFC8496FF7C202239
-:10D640000000E600D654C5040000F7044288E0005C
-:10D65000D87CF6064288F6044F5C83960000831659
-:10D66000FF74869E0000A7323002F5820000C036AB
-:10D670007200E600D694C6303000869E00048732E1
-:10D68000000400000001C0367200E600D698202E8B
-:10D690000000F5820001202E0000E600D6A5000063
-:10D6A0000001F50200008396000087320000869E8C
-:10D6B000000000000001C0367200E200D6E4F582EE
-:10D6C0000000C0367200E600D6EC202E0000869ED8
-:10D6D00000048732000400000001C0367200E2003E
-:10D6E000D6ED202E0000F5820001202E0000E6007D
-:10D6F000D6FD202A0000F5020001202A0000E600E5
-:10D70000D72804A400028316FFACF70642C883960C
-:10D71000FF8CF3054F54C71C7000F03B28000738FE
-:10D720000002E000DB50F03B28009496FF6C872657
-:10D73000000076A5001E76B4FFE58316FF6C839685
-:10D74000FF9C2494001E0618000275B1001E75ACE3
-:10D75000FFE5C7386FC07738FFF0F71F2800873222
-:10D760000000751D001E7528FFE5C7385FC07738BB
-:10D77000FFF0F72728002494001C063000028732AF
-:10D78000000076B1001E76B4FFE5C7386FC0773869
-:10D79000FFF0F72728002494001A06300002873291
-:10D7A000000076B1001E76B4FFE5C7386FC0773849
-:10D7B000FFF0F72728002494001806300002873273
-:10D7C000000076B1001E76B4FFE5C7386FC0773829
-:10D7D000FFF0F72728002494001606300002873255
-:10D7E000000076B1001E76B4FFE5C7386FC0773809
-:10D7F000FFF0F72728002494001406300002873237
-:10D80000000076B1001E76B4FFE5C7386FC07738E8
-:10D81000FFF0F72728002494001206300002873218
-:10D82000000076B1001E76B4FFE5C7386FC07738C8
-:10D83000FFF0F7272800063000028732000024940A
-:10D8400000107631001E7630FFE5C73867C07738A4
-:10D85000FFF0F72728008716FFE0F682FFFCC738A5
-:10D8600057C07739FFF007380003C4B86C00202692
-:10D870000010E200D89DF606428AF704428876B18D
-:10D88000001E76B4FFE5F4020000C7386FC0773998
-:10D89000FFF007380001E000DBA0F7332800831613
-:10D8A000FF6C251400368396FF94871A0000769942
-:10D8B000001E76B4FFE50618000275B1001EC738D9
-:10D8C0006FC07738FFF0F71F28008732000075AC73
-:10D8D000FFE5C7385FC07738FFF0F72B2800251425
-:10D8E0000034063000028732000076B1001E76B4A4
-:10D8F000FFE5C7386FC07738FFF0F72B28002514F5
-:10D900000032063000028732000076B1001E76B485
-:10D91000FFE5C7386FC07738FFF0F72B28002514D4
-:10D920000030063000028732000076B1001E76B467
-:10D93000FFE5C7386FC07738FFF0F72B28002514B4
-:10D94000002E063000028732000076B1001E76B449
-:10D95000FFE5C7386FC07738FFF0F72B2800251494
-:10D96000002C063000028732000076B1001E76B42B
-:10D97000FFE5C7386FC07738FFF0F72B2800251474
-:10D98000002A063000028732000076B1001E76B40D
-:10D99000FFE5C7386FC07738FFF0F72B2800251454
-:10D9A0000028063000028732000026A4000274A47A
-:10D9B000FFFF7631001E7630FFE5C73867C0773845
-:10D9C000FFF0F72B28009013FFFC8316FF8CF7065F
-:10D9D00042CCC7187000C73868009713FFFC9393B8
-:10D9E000FFFC9496FF7C07880008E000CDB8979371
-:10D9F000FFFC8396FF6C2414004E25140050831600
-:10DA0000FF8C8496FF7C871E0000769D001E76B4F6
-:10DA1000FFE5061C000275B1001E75ACFFE5C738B6
-:10DA20006FC07738FFF0F72B280087320000752988
-:10DA3000001E7528FFE5C7385FC07738FFF0F72371
-:10DA400028002414004C063000028732000076B112
-:10DA5000001E76B4FFE5C7386FC07738FFF0F723B4
-:10DA600028002414004A063000028732000076B1F4
-:10DA7000001E76B4FFE5C7386FC07738FFF0F72394
-:10DA8000280024140048063000028732000076B1D6
-:10DA9000001E76B4FFE5C7386FC07738FFF0F72374
-:10DAA000280024140046063000028732000076B1B8
-:10DAB000001E76B4FFE5C7386FC07738FFF0F72354
-:10DAC000280024140044063000028732000076B19A
-:10DAD000001E76B4FFE5C7386FC07738FFF0F72334
-:10DAE000280024140042063000028732000076B17C
-:10DAF000001E76B4FFE5C7386FC07738FFF0F72314
-:10DB000028000630000287320000241400407631DD
-:10DB1000001E7630FFE5C73867C07738FFF0F7237F
-:10DB200028008696FFB0F60642C8C6186000F702C5
-:10DB30000003C6B457C076B5FFF0C6B47400F70250
-:10DB40000004C7386A00F733280006300002F4B337
-:10DB500028008396FF8C8316FF74039C0014939611
-:10DB6000FF8C0318000C8396FFAC9316FF74039C84
-:10DB70000001E000D5EC9396FFAC9313FFFCF38417
-:10DB80004F5C000000019393FFFCF3064A98931347
-:10DB9000FFFC07880008E00126F89793FFFCF402D9
-:10DBA00000018796FFFC8296FFF802140004013CF6
-:10DBB0000000000000019293FFFC02900008221078
-:10DBC00001A0F5020000F3846E50F602001C202A2A
-:10DBD0000063EE00DC08C59C6000A69E6002772D05
-:10DBE000001E7738FFE5C6B477C076B5FFF0203663
-:10DBF0000003E600DBFC072C0036F03B2800063073
-:10DC00000040E000DBCC05280001F5844F5C0000FB
-:10DC1000000186AE0008F4020000872E0004000018
-:10DC20000001C0367200EC00DCF09696FFEC773510
-:10DC30000001C738680077390002C638580006303E
-:10DC4000000CC38400008316000086B20000871A0F
-:10DC5000000000000001C0367200E600DC7CC52038
-:10DC6000000086B20004871A000400000001C036DC
-:10DC70007200E600DC80202A0000F5020001202A64
-:10DC80000000E600DC8D00000001F38200008496B5
-:10DC9000000086B200008726000000000001C036A8
-:10DCA0007200E200DCCCF5020000C0367200E60033
-:10DCB000DCD4202A000086B200048726000400007D
-:10DCC0000001C0367200E200DCD5202A0000F50217
-:10DCD0000001202A0000E600DCE5201E0000F3829F
-:10DCE0000001201E0000E600DCF420220000F40207
-:10DCF000000120220000E600DD29F602000187165F
-:10DD0000FFEC0000000176B90001C6B4700076B5E2
-:10DD10000002C6B4580006B4001486B60000971678
-:10DD2000FFF0E000DD989696FFF427140014971397
-:10DD3000FFFC83160000000000019313FFFC959385
-:10DD4000FFFC9596FE7007880008E0012568979310
-:10DD5000FFFC8596FE7020220000E600DD95F602AD
-:10DD600000018716FFEC0000000176B90001C6B47F
-:10DD7000700076B50002C6B4580006B4001486B62A
-:10DD800000009716FFF09696FFF4972E0008E0002B
-:10DD9000DD9C20320000F602000020320000E60088
-:10DDA000DDB0F4820000F704427CE000E09CF6065F
-:10DDB000427E9496FF448716FFF4F6044F58773955
-:10DDC0000006C73070009716FF5406B8001A873651
-:10DDD00000008316FF5476B5001E76B4FFE5C73801
-:10DDE0006FC09313FFFC7738FFF077390006C63019
-:10DDF00070009616FF4C07880008E000CD0097934E
-:10DE0000FFFC20220000E600DE35F30200018496CC
-:10DE1000FF4C000000019493FFFC07880008E0001D
-:10DE2000CD009793FFFC20220000E600DE380000C2
-:10DE30000001F30200019316FF448496FF440000A2
-:10DE4000000120260000E600DE59F60642A4F70491
-:10DE500042A4E000E0A076B1001E8316FF4C8616B7
-:10DE6000FF4C871A00007699001E76B4FFE5C7388C
-:10DE70006FC07739FFF0203A0002E600DE8500002F
-:10DE80000001F6044F58F5844F5800000001C032DD
-:10DE90005A00E600E025000000018496FF4C0000D7
-:10DEA000000106A4001A873600008316FF5476B5D9
-:10DEB000001E76B4FFE5C7386FC07738FFF07739BA
-:10DEC0000006C72C7000C03A3200E600DEDDF60620
-:10DED0004280F7044280E000E0A076B1001E2614E4
-:10DEE0000030F03328008716FFD07631001E7630E0
-:10DEF000FFE58496FF4C2314002E9316FE6475995B
-:10DF0000001E75ACFFE57515001E7528FFE573153D
-:10DF1000001E7318FFE59316FF348316FE64042475
-:10DF2000000206A000027495001E74A4FFE59496FA
-:10DF3000FF3C7495001EC73867C07738FFF0F723A1
-:10DF40002800871A000074A4FFE59496FF2CC738B8
-:10DF50005FC07738FFF0F737280006B40002871655
-:10DF6000FFD42494002A9496FE647625001E763011
-:10DF7000FFE5C73857C07738FFF0F7372800872606
-:10DF8000000006B40002C73867C07738FFF0F737E3
-:10DF9000280006B400028716FFD823140026931623
-:10DFA000FE647619001E8496FF3C7630FFE5C73884
-:10DFB0004FC07738FFF0F7372800871A000006B403
-:10DFC00000028496FF34C73867C07738FFF0F73710
-:10DFD000280006B400028716FFDC231400229316E3
-:10DFE000FE647619001E7630FFE5C7384FC07738DB
-:10DFF000FFF0F7372800871A000006B40002C73880
-:10E0000067C07738FFF0F73728008716FFE08316E0
-:10E01000FF2C06B40002C73837C07738FFF0E000A5
-:10E02000EAA0F737280007880008E000CBCC9793D8
-:10E03000FFFC06A00002F7044F58F037280006A0A6
-:10E0400000149416FF24C72072007738FFFAF737C0
-:10E05000280006A00016F7372800F4820001F4A378
-:10E0600028009413FFFC07880008E000CD00979378
-:10E07000FFFC20220000E600E0BC26940048F704E4
-:10E080004280E000E09CF60642828696FEF4E000C4
-:10E09000E29400000001F7044284F606428476B15F
-:10E0A000001E76B4FFE5F4020000C7386FC0773970
-:10E0B000FFF007380001E000EAA4F73328008316D8
-:10E0C000FF4C7515001E7528FFE59316FF1C0718F9
-:10E0D0000036F4820001F4BB2800F03728008716D0
-:10E0E000FFB876B5001E76B4FFE5041800020620DE
-:10E0F0000002231400469316FF147599001E75AC98
-:10E10000FFE57495001E74A4FFE59496FF0C73154B
-:10E11000001E7318FFE59316FF047495001E74A487
-:10E12000FFE59496FEFC230000079316FEF4849608
-:10E13000FF1C8316FF1404A4000A9496FE7CC738C3
-:10E140006FC07738FFF0F7232800F6844F58849685
-:10E15000FF54871A0000C6A46A007434FFFAC73857
-:10E160005FC07738FFF0F7332800063000028716CB
-:10E17000FFBC231400429316FF147699001E76B458
-:10E18000FFE5C73857C07738FFF0F7332800871A04
-:10E19000000006300002C7386FC07738FFF0F73351
-:10E1A0002800063000028716FFC02494003E949693
-:10E1B000FF1476A5001E8316FF0C76B4FFE5C73862
-:10E1C00037C07738FFF0F733280087260000063085
-:10E1D0000002C7386FC07738FFF0F73328000630E9
-:10E1E00000028716FFC42494003A9496FF1476A583
-:10E1F000001E8316FF0476B4FFE5C73837C07738B2
-:10E20000FFF0F73328008726000006300002C738E9
-:10E210006FC07738FFF0F73328008716FFC8849661
-:10E22000FEFC06300002C7384FC07738FFF0F733E6
-:10E2300028008316FEF400000001201A0007EE00FB
-:10E24000E294F68200088496FE7C00000001072418
-:10E25000000E86BA00007739001E7738FFE5C6B495
-:10E2600077C076B5FFF0F70200FFC6B4740047210F
-:10E270000000C0367200470C0001203A0000E600A2
-:10E28000E08804A400029496FE7C03180001E000DC
-:10E29000E2309316FEF48316FF1C000000010718FD
-:10E2A0000038F6BB28009313FFFC8496FF2400007F
-:10E2B00000019493FFFC07880008E000D42C97939A
-:10E2C000FFFC231400789316FEBC849600002314F0
-:10E2D00000A886A60004872600009316FE9CC6B4FC
-:10E2E00070009696FEECF7020001C7347400971692
-:10E2F000FEE48496FF24000000019493FFFC07884D
-:10E300000008E000D4B49793FFFCF7044F580000D6
-:10E310000001C0227200E600EAA19416FF1C86A24A
-:10E3200000387721001E7738FFE5F30200009316CE
-:10E33000FED4C6B477C076B5FFF09696FEDC849620
-:10E34000FED4000000012026000EEE00E2F0F302F1
-:10E35000000F9313FFFC8316FEEC00000001C718AA
-:10E3600048009713FFFC07880008E00127E897930F
-:10E37000FFFCC3A000008496FEE4000000012026FC
-:10E380000000E600E38D239C0007C3803A00C71C11
-:10E3900038008316FF1CF48200FFF6044F58C7189C
-:10E3A00070000738002686BA00009716FEC4773939
-:10E3B000001E7738FFE5C6B477C076B5FFF0C6B467
-:10E3C0004C0076B50006C330680007300040C01A24
-:10E3D0007200E600E40D9316FECC9313FFFC9396B7
-:10E3E000FE749616FE6C9696FE6807880008E0009C
-:10E3F000CD009793FFFC8396FE748616FE6C86967E
-:10E40000FE6820220000E600E09500000001F5848F
-:10E410004F588496FECC072C0040C0267200E600C0
-:10E42000EA8D00000001A732680276A5001E76B4CE
-:10E43000FFE58616FECCC7386FC07739FFF0203A6B
-:10E440000002E600E451C0325A00C62C0000C0327F
-:10E450005A00E600E6E5251400768316FF1C849634
-:10E46000FEBC061800028732000076B1001E76B4AA
-:10E47000FFE58316FEDC0630000275B1001EC738CA
-:10E480006FC07738FFF0F72728008732000075AC9F
-:10E49000FFE5C7385FC07738FFF0F72B2800251459
-:10E4A0000074063000028732000076B1001E76B498
-:10E4B000FFE5C7386FC07738FFF0F72B2800251429
-:10E4C0000072063000028732000076B1001E76B47A
-:10E4D000FFE5C7386FC07738FFF0F72B2800251409
-:10E4E0000070063000028732000076B1001E76B45C
-:10E4F000FFE5C7386FC07738FFF0F72B28002514E9
-:10E50000006E063000028732000076B1001E76B43D
-:10E51000FFE5C7386FC07738FFF0F72B28002514C8
-:10E52000006C063000028732000076B1001E76B41F
-:10E53000FFE5C7386FC07738FFF0F72B28002514A8
-:10E54000006A063000028732000076B1001E76B401
-:10E55000FFE5C7386FC07738FFF0F72B280006308B
-:10E56000000287320000251400687631001E7630E4
-:10E57000FFE5C73867C07738FFF0F72B2800C71CC6
-:10E5800032009713FFFC9493FFFC2614006096134F
-:10E59000FFFC9616FE6C07880008E000D0DC97931D
-:10E5A000FFFC8716FFA08616FE6C8496FECC231413
-:10E5B000005E9316FE5C7599001E75ACFFE5741540
-:10E5C000001E7420FFE57315001E7318FFE59316F7
-:10E5D000FEAC8316FE5C7631001E7630FFE5052426
-:10E5E000000206A800027495001E74A4FFE594962C
-:10E5F000FEB47495001EC73867C07738FFF0F72B5C
-:10E600002800871A000074A4FFE59496FEA4C7387A
-:10E610005FC07738FFF0F737280006B4000287168E
-:10E62000FFA42494005A9496FE5C7625001E83165F
-:10E63000FEB47630FFE5C73837C07738FFF0F737DC
-:10E6400028008726000006B40002C73867C0773864
-:10E65000FFF0F737280006B400028716FFA82494BD
-:10E6600000569496FE5C7625001E7630FFE5C7388E
-:10E6700047C07738FFF0F73728008726000006B438
-:10E680000002C73867C07738FFF0F737280006B4B4
-:10E6900000028716FFAC231400529316FE5C761915
-:10E6A000001E8496FEAC7630FFE5C7384FC0773841
-:10E6B000FFF0F7372800871A000006B40002C738B9
-:10E6C00067C07738FFF0F73728008716FFB083164A
-:10E6D000FEA406B40002C73837C07738FFF0E00068
-:10E6E000EA8CF73728008496FECC0000000104A4D1
-:10E6F00000369496FE5C8726000076A5001E76B450
-:10E70000FFE5C7386FC07739FFF0203A0000470CAB
-:10E710000001203A0000E600EA8D000000018316A7
-:10E72000FECC8496FF1C0618003A85B20000072430
-:10E73000003A86BA00007631001E7630FFE5773960
-:10E74000001E7738FFE5C5AC67C0C6B477C075ADAD
-:10E75000FFF076B5FFF0C02E6A00EC00E764F5022A
-:10E760000002F50200018316FF1C000000010718DB
-:10E77000003686BA00007739001E7738FFE5C6B448
-:10E7800077C076B5FFF020360002E600E79C000077
-:10E790000001202A0001E600EA8D000000018496B5
-:10E7A000FE5C8316FF1CF52728000618000287323E
-:10E7B000000076B1001E76B4FFE5251400A684960D
-:10E7C000FE9C8316FEDC0630000275B1001EC738C1
-:10E7D0006FC07738FFF0F72728008732000075AC4C
-:10E7E000FFE5C7385FC07738FFF0F72B2800251406
-:10E7F00000A4063000028732000076B1001E76B415
-:10E80000FFE5C7386FC07738FFF0F72B28002514D5
-:10E8100000A2063000028732000076B1001E76B4F6
-:10E82000FFE5C7386FC07738FFF0F72B28002514B5
-:10E8300000A0063000028732000076B1001E76B4D8
-:10E84000FFE5C7386FC07738FFF0F72B2800251495
-:10E85000009E063000028732000076B1001E76B4BA
-:10E86000FFE5C7386FC07738FFF0F72B2800251475
-:10E87000009C063000028732000076B1001E76B49C
-:10E88000FFE5C7386FC07738FFF0F72B2800251455
-:10E89000009A063000028732000076B1001E76B47E
-:10E8A000FFE5C7386FC07738FFF0F72B2800063038
-:10E8B000000287320000251400987631001E763061
-:10E8C000FFE5C73867C07738FFF0F72B2800C71C73
-:10E8D00032009713FFFC9493FFFC261400909613CC
-:10E8E000FFFC9616FE6C07880008E000D0DC9793CA
-:10E8F000FFFC8716FF708616FE6C8496FECC239470
-:10E90000008E759D001E75ACFFE57315001E731813
-:10E91000FFE59316FE947415001E7420FFE5731531
-:10E92000001E7318FFE59316FE848316FE9476315D
-:10E93000001E7630FFE50524000206A8000274954B
-:10E94000001E74A4FFE59496FE8CC73867C0773824
-:10E95000FFF0F72B28008496FEC4871E0000752563
-:10E96000001EC7385FC07738FFF0F737280006B4BD
-:10E9700000028716FF742394008A761D001E7630ED
-:10E98000FFE58496FE8C7528FFE5C73837C07738D9
-:10E99000FFF0F7372800871E000006B40002831638
-:10E9A000FE84C73867C07738FFF0F737280006B411
-:10E9B00000028716FF7823940086761D001E7630AD
-:10E9C000FFE5C73847C07738FFF0F7372800871EC4
-:10E9D000000006B40002C73867C07738FFF0F73789
-:10E9E000280006B400028716FF7C23940082761D5F
-:10E9F000001E7630FFE5C7384FC07738FFF0F73795
-:10EA00002800871E000006B400028496FEC4C738A2
-:10EA100067C07738FFF0F73728008716FF8006B405
-:10EA20000002C73837C07738FFF0F737280087264D
-:10EA30000000F30200FFC73857C07738FFE8C6B8B8
-:10EA40003400F7020080C73474007739001077393A
-:10EA5000FFF0203A0000E600EA6127000100C6B49A
-:10EA600075808496FECC0000000107240038F6BBB8
-:10EA700028009493FFFC8316FF24000000019313E9
-:10EA8000FFFC07880008E000D42C9793FFFC8496D5
-:10EA9000FED40000000104A40001E000E33C9496D1
-:10EAA000FED4F40200018796FFFC8296FFF8021460
-:10EAB0000004013C0000000000019293FFFC029062
-:10EAC0000008861600088696000CF502FFFC859665
-:10EAD000000484160010F484E0000730000294B2B1
-:10EAE0000010F484E00406B4000394B20014F4842B
-:10EAF000E01CC6B4540094B20018F4820005F4B3CC
-:10EB00002800F4820001F4BB280027340008973263
-:10EB1000000486160000072C0003C7385400C6B84E
-:10EB200068009693FFFCC63072009613FFFCF70254
-:10EB30000003C5AC7400F7020004C7385A009713ED
-:10EB4000FFFC07880008C12000009793FFFC879610
-:10EB5000FFFC8296FFF802140014013C0000000044
-:10EB600000019293FFFC0290000822100018871603
-:10EB700000040000000183BA000084960000939610
-:10EB8000FFF0F3846E54873A00049396FFEC9716D7
-:10EB9000FFF49013FFFC271C00029713FFFC0724CF
-:10EBA00000209713FFFC9496FFE407880008E0001C
-:10EBB000CDB89793FFFC8496FFE4839600088726E0
-:10EBC00000188516FFECC03A3A00EE00EC7CF582A6
-:10EBD0000001872600188396000800000001C01E6F
-:10EBE0007200E600EC7CC584000086A60010871643
-:10EBF000FFF0F6020000C0367200E600EC1C0424B0
-:10EC0000001086A600148716FFF400000001C0362D
-:10EC10007200E600EC2020320000F60200012032F3
-:10EC20000000E600EC2D00000001F582000086A245
-:10EC300000008716FFF000000001C0367200E200FD
-:10EC4000EC68F6020000C0367200E600EC7020327C
-:10EC5000000086A200048716FFF400000001C03601
-:10EC60007200E200EC7120320000F6020001203256
-:10EC70000000E600EC81202E0000F5820001202E2D
-:10EC80000000E600ECACF7020001F704429CF60637
-:10EC9000429C76B1001E76B4FFE5C7386FC0773965
-:10ECA000FFF007380001F7332800F7020001972A28
-:10ECB000000883A6000C772CFFE193AA000C972A8A
-:10ECC000001C83A6001CF7046E5093AA002083BA90
-:10ECD0001DDCF682000093AA002C8396000CC5B4BC
-:10ECE000000093AA003083BA0010C634000093AA33
-:10ECF0000024873A001400000001972A00282036DB
-:10ED0000001FEE00ED1CC73050000738003495BAE4
-:10ED1000000006300004E000ECFC06B4000183961D
-:10ED2000001076A5001E9393FFFCF38200B493932A
-:10ED3000FFFC9513FFFC8726002076B4FFE5C7385B
-:10ED40006FC07739FFF09713FFFC8396FFEC00004C
-:10ED500000019393FFFC07880008E000EAB897934E
-:10ED6000FFFC8796FFFC8296FFF802140014013C1A
-:10ED70000000000000019293FFFC029000082210A6
-:10ED800000188716000400000001863A0000000009
-:10ED900000019616FFF0873A000400000001971664
-:10EDA000FFF4F6021DE09613FFFC8616000000003B
-:10EDB00000019613FFFCF6046E500000000196134C
-:10EDC000FFFC261400109616FFEC07880008E001EF
-:10EDD00026F89793FFFCF6846E50F6020000873603
-:10EDE0001DD89616FFE476B5001E76B4FFE5C73849
-:10EDF0006FC07738FFF0F68642C0F73728008616D6
-:10EE0000FFEC000000019613FFFC07880008E000FB
-:10EE1000DBB49793FFFC20220000E600EE4D0000DB
-:10EE200000018616FFEC000000019613FFFC078826
-:10EE30000008E000D5A09793FFFC20220000E60028
-:10EE4000EE4D00000001F60200019616FFE4841664
-:10EE5000FFE48796FFFC8296FFF802140008013C4D
-:10EE60000000000000019293FFFC029000088696CB
-:10EE70000004861600008736000885960008203AB0
-:10EE80000000E600EE99203A0003E600EEE9F40205
-:10EE90000000E000EF0C0000000177B0001F703EA2
-:10EEA000FFE1E600EF0DF4020000851600140000FB
-:10EEB00000019513FFFC851600100000000195135A
-:10EEC000FFFC8516000C000000019513FFFC9593D4
-:10EED000FFFC9693FFFC07880008E000EB60979327
-:10EEE000FFFCE000EF0C0000000177B0001E703E58
-:10EEF000FFE1E600EF0D000000019593FFFC969303
-:10EF0000FFFC07880008E000ED749793FFFC8796EC
-:10EF1000FFFC8296FFF802140018013C000000007C
-:10EF200000019293FFFC0290000822100018F48266
-:10EF3000000086960000F6044AA023940010843650
-:10EF400000009616FFE4F7044A9C9416FFF08536FD
-:10EF50000004C0327200EC00F0149516FFF4773113
-:10EF60000001C738600077390002F3064A98C6B836
-:10EF7000300006B4000CC584000087360000000095
-:10EF80000001C03A4200E600EFA4C6240000873624
-:10EF9000000400000001C03A5200E600EFA8203251
-:10EFA0000000F602000120320000E600EFB500008C
-:10EFB0000001F5820000863600008716FFF0000091
-:10EFC0000001C0327200E200EFF0F5020000C03232
-:10EFD0007200E600EFF8202A000086B600048716CB
-:10EFE000FFF400000001C0367200E200EFF9202AB1
-:10EFF0000000F5020001202A0000E600F009202EA2
-:10F000000000F5820001202E0000E600F018202606
-:10F010000000F482000120260000E600F04DF60218
-:10F0200000018716FFE4F3064A9876B90001C6B4DA
-:10F03000700076B50002C6B4300006B4001486B67F
-:10F0400000009716FFE8E000F0B09696FFEC27145A
-:10F05000001C9713FFFC9393FFFCF3064A9893134D
-:10F06000FFFC07880008E00125689793FFFC202239
-:10F070000000E600F0ADF60200018716FFE4F3069B
-:10F080004A9876B90001C6B4700076B50002C6B4DD
-:10F09000300006B4001486B600009716FFE8969676
-:10F0A000FFECF7054AA0E000F0B420320000F602C1
-:10F0B000000020320000E600F121F4020001871672
-:10F0C000FFE8F60642C876B90002C6B4700076B50D
-:10F0D0000002A736600283160004C6B460007635CD
-:10F0E000001E7630FFE50534000275A9001EC73802
-:10F0F00067C07738FFF0971A0000872A000075ACC8
-:10F10000FFE583160008C7385FC07738FFF0971A0D
-:10F1100000008316000C06B40004E000F124969A67
-:10F120000000F40200008796FFFC8296FFF80214AC
-:10F130000010013C0000000000010000B9000000C8
-:10F14000BA000000BB000000BC000000BD000000D1
-:10F15000BE000000BF000000800000008100000031
-:10F160008200000083000000840000008500000091
-:10F17000860000008700B9B9B9BAB9BBB9BCB9BD3E
-:10F18000B9BEB9BFB980B981B982B983B984B9852B
-:10F19000B986B987BAB9BABABABBBABCBABDBABE2F
-:10F1A000BABFBA80BA81BA82BA83BA84BA85BA863B
-:10F1B000BA87BBB9BBBABBBBBBBCBBBDBBBEBBBFCD
-:10F1C000BB80BB81BB82BB83BB84BB85BB86BB874B
-:10F1D000BCB9BCBABCBBBCBCBCBDBCBEBCBFBC80AB
-:10F1E000BC81BC82BC83BC84BC85BC86BC87BDB9E9
-:10F1F000BDBABDBBBDBCBDBDBDBEBDBFBD80BD81BB
-:10F20000BD82BD83BD84BD85BD86BD87BEB9BEBA86
-:10F21000BEBBBEBCBEBDBEBEBEBFBE80BE81BE82CA
-:10F22000BE83BE84BE85BE86BE87BFB9BFBABFBB24
-:10F23000BFBCBFBDBFBEBFBFBF80BF81BF82BF83DA
-:10F24000BF84BF85BF86BF8780B980BA80BB80BCC2
-:10F2500080BD80BE80BF80808081808280838084EA
-:10F2600080858086808781B981BA81BB81BC81BD60
-:10F2700081BE81BF818081818182818381848185FA
-:10F280008186818782B982BA82BB82BC82BD82BEFE
-:10F2900082BF82808281828282838284828582860A
-:10F2A000828783B983BA83BB83BC83BD83BE83BF9C
-:10F2B000838083818382838383848385838683871A
-:10F2C00084B984BA84BB84BC84BD84BE84BF84807A
-:10F2D000848184828483848484858486848785B9B8
-:10F2E00085BA85BB85BC85BD85BE85BF858085818A
-:10F2F00085828583858485858586858786B986BA56
-:10F3000086BB86BC86BD86BE86BF86808681868299
-:10F310008683868486858686868787B987BA87BBF3
-:10F3200087BC87BD87BE87BF8780878187828783A9
-:10F33000878487858786878700009293FFFC0290E9
-:10F34000000822100018F70475EC00000001203AB4
-:10F350000000E600F37DF6064296F704429476B18B
-:10F36000001E76B4FFE5F4020000C7386FC077399D
-:10F37000FFF007380001E000F5E0F7332800F384E0
-:10F380006F309013FFFC271C00029713FFFC8316BD
-:10F390000000000000019313FFFC9396FFEC078828
-:10F3A0000008E000CDB89793FFFC8396FFECF702CE
-:10F3B0000000971E00088316000400000001931E41
-:10F3C000000C83160008049C0022931E001C831668
-:10F3D000000C9396FFF4871A00007699001E76B40D
-:10F3E000FFE50618000275B1001E75ACFFE5C738D1
-:10F3F0006FC07738FFF0069C0020F737280087326F
-:10F4000000009696FFE47535001EC7385FC0773858
-:10F41000FFF0F7272800049C002406300002873202
-:10F42000000076B1001E76B4FFE5C7386FC07738AC
-:10F43000FFF0F7272800049C0026063000028732E0
-:10F44000000076B1001E76B4FFE5C7386FC077388C
-:10F45000FFF0F7272800049C0028063000028732BE
-:10F46000000076B1001E76B4FFE5C7386FC077386C
-:10F47000FFF0F7272800049C002A0630000287329C
-:10F48000000076B1001E76B4FFE5C7386FC077384C
-:10F49000FFF0F7272800049C002C0630000287327A
-:10F4A000000076B1001E76B4FFE5C7386FC077382C
-:10F4B000FFF0F7272800049C002E06300002873258
-:10F4C000000076B1001E76B4FFE5C7386FC077380C
-:10F4D000FFF0F72728000630000287320000049C66
-:10F4E00000307631001E7630FFE5C73867C07738C8
-:10F4F000FFF0F7272800871E00207528FFE5C73892
-:10F5000057C07739FFF0203A0008EE00F598F3066F
-:10F5100014D88316FFE4871E00207699001E76B467
-:10F52000FFE5C7386FC07739FFF025B80001C4ACDC
-:10F53000580004240001202E0000EC00F595F5028F
-:10F5400000008316FFE40000000106180002A73245
-:10F550005802C6B0580076B5001E76B4FFE5C7382D
-:10F560006FC07739FFE8C6B0400077B80018703E2A
-:10F57000FFE1E600F57DF7376800F502FFFFC730D1
-:10F580004800F53B680024A4000224200002E000AB
-:10F59000F53425AC0001F30614D89313FFFCF302F5
-:10F5A00000349313FFFC8316FFF400000001931353
-:10F5B000FFFC8316000000000001871A0000769906
-:10F5C000001E76B4FFE5C7386FC07739FFF0971398
-:10F5D000FFFC9393FFFC07880008E000EAB89793CC
-:10F5E000FFFC8796FFFC8296FFF802140010013C96
-:10F5F0000000000000019293FFFC0290000822101E
-:10F600000010F70475EC00000001203A0000E6004D
-:10F61000F639F6064296F704429476B1001E76B4A7
-:10F62000FFE5F4020000C7386FC07739FFF00738F4
-:10F630000001E000F748F7332800F5046F300000C0
-:10F6400000019516FFF49013FFFC27280002971382
-:10F65000FFFC85960004000000019593FFFC0788DD
-:10F660000008E000CDB89793FFFC85160004F60271
-:10F67000000086AA00007729001E7738FFE5C6B48F
-:10F6800077C076B5FFF0F7020001C0367400E600DF
-:10F69000F6999696FFECC63800009613FFFC859607
-:10F6A000FFEC8516FFF4472CFFFE07380002C72841
-:10F6B00072009713FFFC85960000000000019593EF
-:10F6C000FFFC07880008E000CDB89793FFFC851683
-:10F6D000FFF4F7020002972A000885960008000050
-:10F6E000000195AA000C8596000C0000000195AA67
-:10F6F000001CF50614D89513FFFCF58200209593A5
-:10F70000FFFC8516FFF4000000019513FFFC8596B1
-:10F7100000008516FFEC872E000076AD001E76B443
-:10F72000FFE5C7386FC07739FFF0C738500097132F
-:10F73000FFFC8596FFF4000000019593FFFC07880D
-:10F740000008E000EAB89793FFFC8796FFFC8296DA
-:10F75000FFF802140010013C000000000001929329
-:10F76000FFFC0290000885960000851600048716AD
-:10F770000008F602FFFC06A80003C6B464000738C0
-:10F780000003C7386400C73470009713FFFCC5AC92
-:10F790006A009593FFFCF7020003C5287400F70286
-:10F7A0000004C73852009713FFFC07880008E001E7
-:10F7B00014D89793FFFC8796FFFC8296FFF80214FB
-:10F7C0000010013C0000000000019293FFFC029039
-:10F7D000000822100010F70475EC00000001203A28
-:10F7E0000000E600F80DF6064296F704429476B162
-:10F7F000001E76B4FFE5F4020000C7386FC0773909
-:10F80000FFF007380001E000F920F7332800F50485
-:10F810006F30000000019516FFF49013FFFC2728BD
-:10F8200000029713FFFC85960004000000019593E9
-:10F83000FFFC07880008E000CDB89793FFFC851611
-:10F840000004F602000086AA00007729001E77381F
-:10F85000FFE5C6B477C076B5FFF0F7020001C03609
-:10F860007400E600F86D9696FFECC638000096131B
-:10F87000FFFC8596FFEC8516FFF4472CFFFE07384A
-:10F880000002C72872009713FFFC85960000000055
-:10F8900000019593FFFC07880008E000CDB897931E
-:10F8A000FFFC8516FFF4F5820006F5AB280085966F
-:10F8B00000080728000295AA00040514000E852AF6
-:10F8C000000077A9001E77BCFFE5C5287FC0752919
-:10F8D000FFF0F53B2800F58614D89593FFFCF50260
-:10F8E00000089513FFFC859600008516FFEC872E17
-:10F8F000000076AD001E76B4FFE5C7386FC07739DB
-:10F90000FFF0C73850009713FFFC8596FFF4000006
-:10F9100000019593FFFC07880008E000F75C9793CF
-:10F92000FFFC8796FFFC8296FFF802140010013C52
-:10F930000000000000019293FFFC029000082210DA
-:10F940000008F70475EC83960004203A0000E600F6
-:10F95000FA64F6064296F5046F309013FFFC2728F0
-:10F9600000029713FFFC83160000000000019313B0
-:10F97000FFFC9396FFF49516FFF007880008E0005F
-:10F98000CDB89793FFFC8516FFF0F302000783962E
-:10F99000FFF4F32B280007280002F3020001F33BD9
-:10F9A0002800871E0000769D001E76B4FFE5059CAA
-:10F9B0000002762D001E7630FFE5749D001E74A4B3
-:10F9C000FFE5041C000683160000C7386FC07738B7
-:10F9D000FFF006A80004F7372800872E000006A8CD
-:10F9E000000675A1001EC73867C07738FFF0F737EB
-:10F9F0002800871E000475ACFFE506A800087619EC
-:10FA0000001EC7384FC07738FFF0F737280087222D
-:10FA1000000006A8000AC7385FC07738FFF0F73744
-:10FA20002800F30614D89313FFFCF302000C931381
-:10FA3000FFFC8316000000000001871A00007630EA
-:10FA4000FFE5C73867C07739FFF09713FFFC9513C0
-:10FA5000FFFC07880008E000F75C9793FFFCE000DC
-:10FA6000FA8400000001F704429476B1001E76B4D7
-:10FA7000FFE5F4020000C7386FC07739FFF00738A0
-:10FA80000001F73328008796FFFC8296FFF80214E6
-:10FA90000008013C0000000000019293FFFC02906E
-:10FAA000000822100048F70475EC85960000203A03
-:10FAB0000000E600FD98F606429605AC0002872E8F
-:10FAC000000076AD001E76B4FFE52414001E062C5F
-:10FAD00000027531001E249400207528FFE5F38490
-:10FAE0006E50C7386FC07738FFF0F727280087328D
-:10FAF00000009396FFC4C73857C07738FFF0F7234C
-:10FB000028002414001C063000028732000076B161
-:10FB1000001E76B4FFE5C7386FC07738FFF0F723D3
-:10FB200028002414001A063000028732000076B143
-:10FB3000001E76B4FFE5C7386FC07738FFF0F723B3
-:10FB4000280024140018063000028732000076B125
-:10FB5000001E76B4FFE5C7386FC07738FFF0F72393
-:10FB6000280024140016063000028732000076B107
-:10FB7000001E76B4FFE5C7386FC07738FFF0F72373
-:10FB8000280024140014063000028732000076B1E9
-:10FB9000001E76B4FFE5C7386FC07738FFF0F72353
-:10FBA000280024140012063000028732000076B1CB
-:10FBB000001E76B4FFE5C7386FC07738FFF0F72333
-:10FBC000280006300002873200002414001076312D
-:10FBD000001E7630FFE5C73867C07738FFF0F7239F
-:10FBE00028009013FFFC271C00029713FFFC94933E
-:10FBF000FFFC9596FFBC07880008E000CDB89793FE
-:10FC0000FFFC8596FFBC231400362494003873A5AE
-:10FC1000001E739CFFE5F40442C0F68642C076B530
-:10FC2000001E76B4FFE5872E0000762D001E76308C
-:10FC3000FFE5C4206FC07420FFF005AC0002752DF5
-:10FC4000001E7528FFE5C73867C07738FFF0F72733
-:10FC50002800872E0000F6046E50C73857C077384A
-:10FC6000FFF0F71B28002314003405AC0002872E98
-:10FC7000000076AD001E76B4FFE5C7386FC0773858
-:10FC8000FFF0F71B28002314003205AC0002872E7A
-:10FC9000000076AD001E76B4FFE5C7386FC0773838
-:10FCA000FFF0F71B28002314003005AC0002872E5C
-:10FCB000000076AD001E76B4FFE5C7386FC0773818
-:10FCC000FFF0F71B28002314002E05AC0002872E3E
-:10FCD000000076AD001E76B4FFE5C7386FC07738F8
-:10FCE000FFF0F71B28002314002C05AC0002872E20
-:10FCF000000076AD001E76B4FFE5C7386FC07738D8
-:10FD0000FFF0F71B28002314002A05AC0002872E01
-:10FD1000000076AD001E76B4FFE5C7386FC07738B7
-:10FD2000FFF0F71B280005AC0002872E000023140B
-:10FD3000002875AD001E75ACFFE5C7385FC0773889
-:10FD4000FFF0F71B28008716FFC8F6820003C738AC
-:10FD50003FC096B2000806B01DD8F4372800F386DD
-:10FD600014D89393FFFCF3821DE09393FFFC96134A
-:10FD7000FFFC7739FFF09713FFFC8396FFC4000068
-:10FD800000019393FFFC07880008E000EAB897930E
-:10FD9000FFFCE000FDB800000001F704429476B1DA
-:10FDA000001E76B4FFE5F4020000C7386FC0773953
-:10FDB000FFF007380001F73328008796FFFC829692
-:10FDC000FFF802140004013C0000000000019293BF
-:10FDD000FFFC029000088616000000000001873238
-:10FDE000000076B1001E76B4FFE5C7386FC07739E2
-:10FDF000FFF0203A0006E600FE21F582001EF7041F
-:10FE000042A8F60642A876B1001E76B4FFE5C738D0
-:10FE10006FC07739FFF007380001E000FE34F73398
-:10FE20002800F6056F349593FFFC07880008E00072
-:10FE300015849793FFFC8796FFFC8296FFF80214C7
-:10FE40000004013C0000000000019293FFFC0290BE
-:10FE5000000886160000859600048732000076B1FF
-:10FE6000001E76B4FFE5C7386FC07739FFF0203A3F
-:10FE70000007E600FE9DF4020000F70442A8F60623
-:10FE800042AA76B1001E76B4FFE5C7386FC0773955
-:10FE9000FFF007380001E000FF1CF73328000730AF
-:10FEA000000286BA00007739001E7738FFE5C6B435
-:10FEB00077C076B5FFF020360001E600FED5F605E6
-:10FEC0006F3420360002E600FEE5F5020020E00077
-:10FED000FEFCF60642AC202E000CE600FF1CF402ED
-:10FEE0000000F502001F9513FFFC07880008E000E2
-:10FEF00015849793FFFCE000FF1CF4020001F70457
-:10FF000042AC76B1001E76B4FFE5C7386FC07739D2
-:10FF1000FFF007380001F7332800F402000187964C
-:10FF2000FFFC8296FFF802140008013C000000006C
-:10FF300000019293FFFC02900008869600000000EA
-:10FF4000000187360004F6020000073800089736E3
-:10FF500000048736000800000001203A0000EC0091
-:10FF6000FF7DF6856F348736000800000001203AD7
-:10FF70000003EE00FF8020320000F6020001203274
-:10FF80000000E600FFBDF60642AEF7046F34000045
-:10FF90000001873A0008F682FFEC77390002A73AA1
-:10FFA0006802000000019713FFFC07880008E000CA
-:10FFB00015849793FFFCE000FFD800000001F704D0
-:10FFC00042AC76B1001E76B4FFE5C7386FC0773912
-:10FFD000FFF007380001F73328008796FFFC829670
-:10FFE000FFF802140004013C0000000000010000C2
-:10FFF00000170000001A0000001D0000001800009B
-:020000021000EC
-:10000000000056657273696F6E537472696E673A59
-:10001000206D63702D6C34763320332E303863209E
-:1000200044656320313120313939362031333A305B
-:10003000363A313600009293FFFC02900008F70434
-:10004000E00CFF0200009702FF84F7060C3ECFFC95
-:100050007580F60200029602FF8C9002FF88F7047A
-:10006000E02000000001203A0000E6010074F68262
-:100070000000F68200039682FF988796FFFC829626
-:10008000FFF802140000013C000000000001929300
-:10009000FFFC029000082210000CF5021494F505F4
-:1000A0007B00F50EF014F5057B08F706E000F686F8
-:1000B0007B68C7386A00F7057AF0F502004CF682D3
-:1000C000000020360002EE010124F5057AF8C5B4DF
-:1000D0000000C6340000F706E030C72C7000F506BB
-:1000E0006F44B73250029013FFFC9713FFFC9596B4
-:1000F000FFF49616FFF09696FFEC07880008E001E3
-:10010000031C9793FFFC8596FFF48616FFF08696F6
-:10011000FFEC05AC149406B4000120360002EE0199
-:1001200000D506300004F5020022F5056F58F005F1
-:100130006F54F0056F50F0052D408796FFFC8296B6
-:10014000FFF802140000013C00000000000192933F
-:10015000FFFC0290000807880008E00129589793E7
-:10016000FFFCF7020003F705E008F7047AD8F6026F
-:1001700000019602FF94203A0000E6010191F70683
-:100180007AE807880008E00103DC9793FFFCF70694
-:100190007AE8F6020005F63B2800F7067AE0868248
-:1001A000FF44F602000320360000E60101C9F63BD9
-:1001B0002800F7046F648682FF4407380001203668
-:1001C0000000E60101B0F7056F6407880008E00150
-:1001D00000349793FFFC07880008E001008C979398
-:1001E000FFFC07880008E00044289793FFFC07887D
-:1001F0000008E00016F09793FFFC07880008E00174
-:100200000C609793FFFC07880008E00104089793AF
-:10021000FFFC07880008E00000209793FFFC078898
-:100220000008E0000BD89793FFFC07880008E00166
-:100230001D689793FFFC07880008E0011E50979304
-:10024000FFFC07880008E0005F689793FFFC0788C1
-:100250000008E0006DEC9793FFFC07880008E001C0
-:1002600021D09793FFFC07880008E001222C979388
-:10027000FFFC9002FF9407880008E0000BFC9793B6
-:10028000FFFCF40200008796FFFC8296FFF8021440
-:100290000000013C0000000000019293FFFC02906E
-:1002A000000822100008F6020000C5B0000020324D
-:1002B0000002EE010308F5066F44A6AE50020000EE
-:1002C00000018736000000000001203A0001E6012D
-:1002D00002FCF50200029513FFFC9693FFFC959635
-:1002E000FFF49616FFF007880008E001031C9793BF
-:1002F000FFFC8616FFF08596FFF40000000105ACB8
-:100300000004E00102AC063000018796FFFC8296F3
-:10031000FFF802140000013C00000000000192936D
-:10032000FFFC0290000887160000F6020000F6822B
-:100330000008963A0008963A000C963A09D8963A80
-:1003400009DC963A0EF4963A0EF896BA1420963ACC
-:10035000142490BA148C8696000490BA149096BA1D
-:100360000000963A00048796FFFC8296FFF802147C
-:100370000008013C0000000000019293FFFC029085
-:100380000008859600008716000886160004773856
-:10039000FFFFC5307000C0325200E40103C9000005
-:1003A0000001872E000076AD001E76B4FFE5C73849
-:1003B0006FC07738FFF0F733280006300002C032F4
-:1003C0005200E40103A005AC00028796FFFC829670
-:1003D000FFF80214000C013C0000000000019293A1
-:1003E000FFFC02900008F7020001E00103E8F705B6
-:1003F0007AD88796FFFC8296FFF802140000013C31
-:10040000000000000001000000009293FFFC029039
-:100410000008F502000AF50571CCF00571D4F0056D
-:1004200071D0F00571C4F5020001F682000020369B
-:10043000000AEC010464F50571C8F58A1E00F60691
-:1004400071C4472CFFFC973200180630000406B434
-:100450000001F70471CC00000001C0367200EC010D
-:10046000044105AC214CF0057198F5066F689513B1
-:10047000FFFCF5067B189513FFFC07880008E000D9
-:1004800015489793FFFCF50605D49513FFFCF782FA
-:1004900000059793FFFCF5066F689513FFFC07882E
-:1004A0000008E000161C9793FFFCF5060B709513EF
-:1004B000FFFCF78200069793FFFCF5066F68951323
-:1004C000FFFC07880008E000161C9793FFFCF50668
-:1004D0000BA09513FFFCF78200059793FFFCF50630
-:1004E00070809513FFFC07880008E000161C9793A6
-:1004F000FFFCF5060B709513FFFCF782000697933F
-:10050000FFFCF50670809513FFFC07880008E000EB
-:10051000161C9793FFFCF50605589513FFFCF50292
-:10052000000A9513FFFCF506710C9513FFFC078874
-:100530000008E000161C9793FFFC07880008E00104
-:1005400005589793FFFC8796FFFC8296FFF80214EC
-:100550000000013C0000000000019293FFFC0290AB
-:100560000008F70471C400000001203A0000E60111
-:10057000057DF68671C4E0010594F7020000F704DA
-:1005800071D00000000177390002C7386800873A4F
-:10059000001800000001203A0000E60105ACF70554
-:1005A0007B10F606710CE00105C0F6057B18F60617
-:1005B0006F68F6057B189702FF48073821289702D5
-:1005C000FF4C8796FFFC8296FFF802140000013C66
-:1005D0000000000000019293FFFC0290000822102E
-:1005E00000108682FF48F4866F68F4857B18F50456
-:1005F0007B1026B4000285B60000872A0000762909
-:10060000001E7630FFE576B5001E76B4FFE5C5AC7A
-:100610006FC0C73867C07739FFF077B80010703EF9
-:10062000FFE1E601064575ACFFF0F70471AC000090
-:10063000000107380001F70571ACF70471ACE00167
-:1006400008C4F7020001772CFFF8203A0000E60109
-:10065000067176A9001EF70471A800000001073892
-:100660000001F70571A8F70471A8E00108C4F702BA
-:100670000001872A000076B4FFE5C7386FC07739DC
-:10068000FFF027380004203A0003E20108A400002C
-:10069000000177390002F68606A4A6B670020000B3
-:1006A0000001C1340000000106B40001077C000114
-:1006B00007EC00010844872A0004C4840000C03A03
-:1006C0004A00E60106D8000000018702FF4800004A
-:1006D0000001C7385200972A0004872A000400004E
-:1006E0000001203A2100EE01073CF602000086AA34
-:1006F00000048702FF4800000001C7385200273875
-:100700000028C0367200E601073C0000000177FCBB
-:10071000001D703EFFE1E601073C0000000177FC90
-:100720000017703EFFE1E601073D0000000177FC85
-:100730000016703EFFE1E601074420320000F60299
-:10074000000120320000E601088800000001872A2D
-:10075000001800000001203A0002EE0108C100006C
-:100760000001F70471A40000000107380001F7053B
-:1007700071A4F70471A4E00108C4F7020001872AFC
-:10078000000400000001203A2100EE0107E0F6021B
-:10079000000086AA00048702FF4800000001C73855
-:1007A00052002738000CC0367200E60107E0000056
-:1007B000000177FC001D703EFFE1E60107E000004C
-:1007C000000177FC0017703EFFE1E60107E1000041
-:1007D000000177FC0016703EFFE1E6010880203240
-:1007E0000000F6020001E0010880203200008702CC
-:1007F000FF4800000001C738520027380004203AA3
-:100800000008E6010838F682000077FC001D703E03
-:10081000FFE1E60108380000000177FC0017703E98
-:10082000FFE1E60108390000000177FC0016703E88
-:10083000FFE1E601088020360000F6820001E001B9
-:10084000088020360000F702000077FC001D703E93
-:10085000FFE1E60108780000000177FC0017703E18
-:10086000FFE1E60108790000000177FC0016703E08
-:10087000FFE1E6010880203A0000F7020001203A7B
-:100880000000E60108C100000001F70471A00000AB
-:10089000000107380001F70571A0F70471A0E0011D
-:1008A00008C4F7020001F704719C0000000107383A
-:1008B0000001F705719CF704719CE00108C4F70280
-:1008C0000001F7020000203A0000E601096800007C
-:1008D0000001F6847B10000000018736000076B529
-:1008E000001E76B4FFE5C7386FC07739FFF02738B0
-:1008F0000004203A0003E2010B5077390002F6862B
-:10090000090CA6B6700200000001C134000000010D
-:10091000091C00010AE000010AAC00010B14F704F5
-:1009200071D0F60471CC06B80001C0366200E60151
-:100930000938C7340000F7020000F58471D40000C4
-:100940000001C03A5A00470C0001203A0000E601BD
-:10095000098500000001F70471B0000000010738AC
-:100960000001F70571B0F70471B0F70471B400002D
-:10097000000107380001F70571B4F70471B4E00114
-:100980000B5000000001F48471C8F68571D0949674
-:10099000FFF4F4847B10C0366200E60109A494964B
-:1009A000FFECF00571D0F70471D0F00571C88496A2
-:1009B000FFECC03A5A00470C0001F70571C48726C6
-:1009C000000800000001703AFFE1E60109E10000C3
-:1009D0000001F70471980000000107380001F705D5
-:1009E00071988496FFF40000000120260000E601C3
-:1009F0000A710000000107880008E001055897937C
-:100A0000FFFCF602000920320014E6010A4D27001F
-:100A1000000C203A0001E2010A4DF7062DCCF684C5
-:100A20002ECC0000000175B50002B62E700206B48F
-:100A30000001F6852ECC8602FF34F7062E4C2036B8
-:100A4000001FE2010A4DB62E7002F0052ECCF7040D
-:100A50002D6800000001873A000000000001873A7D
-:100A600000280000000107880008C13800009793A3
-:100A7000FFFCF70471BC8496FFEC07380001F70512
-:100A800071BCF70471BC86A600048496FFF4F704D9
-:100A900071B820260000C7386800F70571B8E60174
-:100AA0000B5100000001E0010B5C00000001F704A5
-:100AB00071C00000000107380001F70571C0F7049C
-:100AC00071C0F4847B10000000019493FFFC078840
-:100AD0000008E000FDCC9793FFFCE0010B50000004
-:100AE0000001F70471C00000000107380001F7059C
-:100AF00071C0F70471C0F4847B100000000194936E
-:100B0000FFFC07880008E000FF309793FFFCE0013E
-:100B10000B5000000001F70471C00000000107380D
-:100B20000001F70571C0F70471C0F6847B108702DD
-:100B3000FF4800000001C7386A00273800049713F7
-:100B4000FFFC9693FFFC07880008E000FE4897939F
-:100B5000FFFC07880008E00105589793FFFC879683
-:100B6000FFFC8296FFF802140000013C0000000028
-:100B700000019293FFFC02900008F7067080F705D1
-:100B80007B1807880008E00105589793FFFC8796BB
-:100B9000FFFC8296FFF802140000013C00000000F8
-:100BA00000019293FFFC02900008F7066F68F705BA
-:100BB0007B1807880008E00105589793FFFC87968B
-:100BC000FFFC8296FFF802140000013C00000000C8
-:100BD00000019293FFFC02900008F7067B18971320
-:100BE000FFFCF7066F689713FFFC07880008E0001A
-:100BF00014F49793FFFCF7067B189713FFFCF70696
-:100C00006FF49713FFFC07880008E00014F4979333
-:100C1000FFFCF7067B189713FFFCF706708097130D
-:100C2000FFFC07880008E00014F49793FFFCF70628
-:100C30007B189713FFFCF706710C9713FFFC0788CE
-:100C40000008E00014F49793FFFC8796FFFC82965F
-:100C5000FFF802140000013C000000000001000049
-:100C600000009293FFFC02900008F5020004F505D5
-:100C70007600F0057608F0057604F00575F8F502C3
-:100C80000001F682000020360004EC010CBCF505E2
-:100C900075FCF58E6AF8F60675F8472CFFFC97325E
-:100CA00000180630000406B40001F70476000000C6
-:100CB0000001C0367200EC010C9905AC214CF50620
-:100CC00072189513FFFCF50676489513FFFC07880C
-:100CD0000008E00015489793FFFCF5060DF4951306
-:100CE000FFFCF782000E9793FFFCF5067218951330
-:100CF000FFFC07880008E000161C9793FFFCF50630
-:100D00000DF49513FFFCF782000E9793FFFCF50698
-:100D100072A49513FFFC07880008E000161C979347
-:100D2000FFFCF506132C9513FFFCF7820001979347
-:100D3000FFFCF50673309513FFFC07880008E00000
-:100D4000161C9793FFFCF50616C89513FFFCF78257
-:100D500000019793FFFCF50673BC9513FFFC078811
-:100D60000008E000161C9793FFFCF5061800951389
-:100D7000FFFCF78200109793FFFCF506744895136B
-:100D8000FFFC07880008E000161C9793FFFCF5069F
-:100D900016409513FFFCF78200109793FFFCF506B1
-:100DA00074D49513FFFC07880008E000161C979385
-:100DB000FFFCF506132C9513FFFCF50200129513AA
-:100DC000FFFCF50675609513FFFC07880008E0003E
-:100DD000161C9793FFFCF00575F0F00575ECF00517
-:100DE00075F48796FFFC8296FFF802140000013C20
-:100DF0000000000000019293FFFC02900008221006
-:100E00000038F70475EC00000001203A0000E6010C
-:100E10000E2800000001F70475F000000001203AE0
-:100E20000000E6010E3D0000000107880008E00117
-:100E300015D09793FFFCE001131800000001F704A0
-:100E400075FC00000001203A0000E6010E59F6860C
-:100E500075F8E0010E6CF6820000F70476080000D9
-:100E6000000177390002C738680086BA0018F70415
-:100E700076FC00000001203A0000E6010E90F685A5
-:100E80007660F3067648F30576FCE0010EA4F702DF
-:100E90000001F3020010F30576F8F3067648F30537
-:100EA0007700F7020000203A0000E6011315F30670
-:100EB0007448F70475EC00000001203A0000E601D8
-:100EC0000ED800000001F70475F000000001203A80
-:100ED0000000E6010EED0000000107880008E001B7
-:100EE00016409793FFFCE001131800000001F68400
-:100EF0007660000000018736000800000001703AAB
-:100F0000FFE1E6010F21F48200009693FFFC0788C1
-:100F10000008E00000BC9793FFFCE0011314F30607
-:100F20007560C3B40000841E0010F6844AA0231428
-:100F300000209316FFC49416FFE09696FFD4851EFA
-:100F40000014F7044A9C00000001C0367200EC0156
-:100F5000100C9516FFE477350001C7386800773923
-:100F60000002F3064A98C6B8300006B4000CC584E7
-:100F700000008736000000000001C03A4200E60190
-:100F80000F9CC62400008736000400000001C03A10
-:100F90005200E6010FA020320000F60200012032CC
-:100FA0000000E6010FAD00000001F582000086366A
-:100FB00000008716FFE000000001C0327200E2016D
-:100FC0000FE8F5020000C0327200E6010FF0202A9F
-:100FD000000086B600048716FFE400000001C0365A
-:100FE0007200E2010FF1202A0000F5020001202A20
-:100FF0000000E6011001202E0000F5820001202EE5
-:101000000000E601101020260000F48200012026D6
-:101010000000E6011045F60200018716FFD4F30632
-:101020004A9876B90001C6B4700076B50002C6B41D
-:10103000300006B4001486B600009716FFD8E00111
-:1010400010B89696FFDC2714002C9713FFFC83162C
-:10105000FFC4000000019313FFFCF3064A989313AA
-:10106000FFFC9396FFCC07880008E0012568979362
-:10107000FFFC8396FFCC20220000E60110B5F602AB
-:1010800000018716FFD4F3064A9876B90001C6B46A
-:10109000700076B50002C6B4300006B4001486B6FF
-:1010A00000009716FFD89696FFDCF7054AA0E001EE
-:1010B00010BC20320000F602000020320000E601E1
-:1010C00010CCF4820001E0011124F4820000869625
-:1010D000FFD80000000177350002C7386800773973
-:1010E0000002F68642C8A63A6802C7386800753919
-:1010F000001E7528FFE505B8000286AE000007381F
-:1011000000049716FFECC63057C07630FFF09616F5
-:10111000FFF475AD001E75ACFFE5C6B45FC076B4D4
-:10112000FFF09696FFF020260000E6011138F582C8
-:101130000000E00111CCF60200008696FFF00000EE
-:101140000001C7346800C49C7200C02E6A00EC0124
-:101150001198C5240000C62C00008716FFEC000083
-:101160000001A6B2700205AC0001C73070007739EB
-:10117000001E7738FFE5C6B477C076B4FFF0F6AB53
-:101180002800052800028716FFF000000001C02E8D
-:101190007200EC01115906300002F3020001F30560
-:1011A00076F4F60200018716FFF0869E0004C73829
-:1011B0007000C7384800C6B470008716FFF406B444
-:1011C00000209702FF6C9482FF509682FF582032D5
-:1011D0000000E601131000000001F704765CF584BE
-:1011E00076F807380001F705765CF704765C202E68
-:1011F0000021E2011230F6862C28F7042D38000079
-:10120000000106380001F6052D387739000220323A
-:101210000044E601121CB5BA6802F0052D38F3024D
-:101220000022F30576F8F3047700E0011234F305A9
-:1012300076FCF00576FCF70475F800000001203A12
-:101240000000E6011271F6862C28F7042D38000004
-:10125000000106380001F6052D3877390002F30247
-:10126000000F20320044E6011270B33A6802F00524
-:101270002D38F7047608F684760007380001C03A66
-:101280006A00E601128CF7057608F0057608F68408
-:101290007608F7047604F00575F8F60675F8C0369A
-:1012A0007200470C0001203A0000E60112B9F70570
-:1012B00075FCE00112C8F702000077350002C7385C
-:1012C0006000873A001800000001203A0000E601A3
-:1012D0001309F7057660F7042D38F30672A4F305B9
-:1012E0007648F6862C2806380001F6052D38773921
-:1012F0000002F302000E20320044E6011318B33A54
-:101300006802E0011318F0052D38E0011314F3060C
-:101310007218F3067330F30576488796FFFC8296C1
-:10132000FFF802140000013C00000000000192934D
-:10133000FFFC02900008F70476600000000186BA06
-:101340000004F704765400000001C7386800F70570
-:101350007654F70476580000000107380001F705BD
-:101360007658F70475F8F6847658203A0000E601BE
-:10137000139DF6862C28F7042D380000000106384E
-:101380000001F6052D3877390002F502000F2032F2
-:101390000044E601139CB53A6802F0052D38F704C5
-:1013A0007608F684760007380001C03A6A00E60144
-:1013B00013B8F7057608F0057608F7047608F68482
-:1013C0007604F00575F8F58476F8C03A6A00470CA3
-:1013D0000001202E0021E2011414F70575FCF7042A
-:1013E0002D38F6862C2806380001F6052D38773979
-:1013F000000220320044E6011400B5BA6802F0058C
-:101400002D38F5020022F50576F8F5047700E001A5
-:101410001418F50576FCF00576FCF70475ECF50676
-:101420007218203A0000E6011440F5057648F704EA
-:1014300075F000000001203A0000E601145500009C
-:10144000000107880008E00115D09793FFFCE00138
-:1014500014C400000001F70475FC00000001203AEC
-:101460000000E6011471F68675F8E0011488F702B1
-:101470000000F70476080000000177390002C73841
-:101480006800873A001800000001203A0000E601D9
-:1014900014C5F7057660F7042D38F6862C28063833
-:1014A0000001F6052D3877390002F502000E2032D2
-:1014B0000044E60114BCB53A6802F0052D38F50683
-:1014C00072A4F50576488796FFFC8296FFF8021411
-:1014D0000000013C0000000000019293FFFC02901C
-:1014E0000008F70475EC00000001203A0000E60156
-:1014F0001540F40200008696000400000001F68505
-:1015000075EC8696000800000001F6857B3886960B
-:101510000000F7047648F6857B30F6867218C03AEC
-:101520006A00470C0001203A0000E6011541F40270
-:10153000000107880008E00115D09793FFFCF40232
-:1015400000018796FFFC8296FFF80214000C013C14
-:101550000000000000019293FFFC02900008F704D5
-:1015600075F400000001203A0000E60115BCF40209
-:1015700000008696000400000001F68575F086964E
-:10158000000800000001F6857B4886960000F704FD
-:101590007648F6857B40F6867218C03A6A00470C9A
-:1015A0000001203A0000E60115BDF40200010788A1
-:1015B0000008E00115D09793FFFCF4020001879624
-:1015C000FFFC8296FFF80214000C013C00000000B2
-:1015D00000019293FFFC02900008F70476FC0000E3
-:1015E0000001203A0000E60115FCF6820010F686A4
-:1015F0007648F68576FCE001160CF7020001F685C8
-:1016000076F8F6867648F6857700F7020000203AED
-:101610000000E6011620F68674D4E001162CF6854B
-:10162000764807880008E00116409793FFFC8796EC
-:10163000FFFC8296FFF802140000013C000000004D
-:1016400000019293FFFC02900008F60475F0000080
-:10165000000120320000E6011685F7020001F705BF
-:1016600075F4F6847B48F70576F4F7047B40C6B042
-:10167000680026B400049702FF6C9602FF50E00158
-:1016800016A800000001F70475ECF6847B38F5829B
-:101690000001F58576F4F6047B30C6B8680026B400
-:1016A00000049602FF6C9702FF509682FF58F58661
-:1016B00073BCF58576488796FFFC8296FFF8021486
-:1016C0000000013C0000000000019293FFFC02902A
-:1016D0000008F7047B280000000107380001F70527
-:1016E0007B28F70475F4F6847B28203A0000E60195
-:1016F000172100000001F00575F4F70475EC0000F7
-:101700000001203A0000E6011725F00575F0078872
-:101710000008E00116409793FFFCE00117EC000081
-:101720000001F00575ECF70475FC00000001203A9B
-:101730000000E6011741F68675F8E0011758F70238
-:101740000000F70476080000000177390002C7386E
-:101750006800873A001800000001203A0000E60106
-:101760001795F7057660F7042D38F6862C2806388D
-:101770000001F6052D3877390002F502000E2032FF
-:101780000044E601178CB53A6802F0052D38E001F7
-:101790001798F50672A4F5067218F5057648F584D3
-:1017A00076F800000001202E0021E20117E8F686FD
-:1017B0002C28F7042D380000000106380001F6053A
-:1017C0002D387739000220320044E60117D4B5BA2B
-:1017D0006802F0052D38F5020022F50576F8F504CB
-:1017E0007700E00117ECF50576FCF00576FC8796AE
-:1017F000FFFC8296FFF802140000013C000000008C
-:1018000000019293FFFC0290000822100038F704B8
-:1018100075EC00000001203A0000E60118340000D9
-:101820000001F70475F000000001203A0000E60115
-:1018300018490000000107880008E001164097934E
-:10184000FFFCE0011C7400000001F68476600000DB
-:1018500000018736000800000001703AFFE1E60150
-:10186000187DF48200009693FFFC07880008E000D2
-:1018700000BC9793FFFCE0011C70F3067560C3B4D5
-:101880000000841E0010F6844AA023140020931642
-:10189000FFC49416FFE09696FFD4851E0014F7044B
-:1018A0004A9C00000001C0367200EC0119689516D0
-:1018B000FFE477350001C738680077390002F30686
-:1018C0004A98C6B8300006B4000CC58400008736BC
-:1018D000000000000001C03A4200E60118F8C624EA
-:1018E00000008736000400000001C03A5200E60103
-:1018F00018FC20320000F602000120320000E60150
-:10190000190900000001F5820000863600008716E4
-:10191000FFE000000001C0327200E2011944F5024C
-:101920000000C0327200E601194C202A000086B681
-:1019300000048716FFE400000001C0367200E201D7
-:10194000194D202A0000F5020001202A0000E601BE
-:10195000195D202E0000F5820001202E0000E60116
-:10196000196C20260000F482000120260000E60108
-:1019700019A1F60200018716FFD4F3064A9876B93A
-:101980000001C6B4700076B50002C6B4300006B4DB
-:10199000001486B600009716FFD8E0011A14969638
-:1019A000FFDC2714002C9713FFFC8316FFC40000F4
-:1019B00000019313FFFCF3064A989313FFFC9396E0
-:1019C000FFCC07880008E00125689793FFFC839609
-:1019D000FFCC20220000E6011A11F6020001871652
-:1019E000FFD4F3064A9876B90001C6B4700076B504
-:1019F0000002C6B4300006B4001486B60000971684
-:101A0000FFD89696FFDCF7054AA0E0011A182032AD
-:101A10000000F602000020320000E6011A28F482DD
-:101A20000001E0011A80F48200008696FFD80000D1
-:101A3000000177350002C738680077390002F68662
-:101A400042C8A63A6802C73868007539001E752872
-:101A5000FFE505B8000286AE0000073800049716BF
-:101A6000FFECC63057C07630FFF09616FFF475AD28
-:101A7000001E75ACFFE5C6B45FC076B4FFF0969665
-:101A8000FFF020260000E6011A94F5820000E00134
-:101A90001B28F60200008696FFF000000001C73404
-:101AA0006800C49C7200C02E6A00EC011AF4C524C0
-:101AB0000000C62C00008716FFEC00000001A6B253
-:101AC000700205AC0001C73070007739001E77380E
-:101AD000FFE5C6B477C076B4FFF0F6AB2800052862
-:101AE00000028716FFF000000001C02E7200EC011A
-:101AF0001AB506300002F3020001F30576F4F6028F
-:101B000000018716FFF0869E0004C7387000C738B2
-:101B10004800C6B470008716FFF406B40020970290
-:101B2000FF6C9482FF509682FF5820320000E6013D
-:101B30001C6C00000001F704765CF58476F8073829
-:101B40000001F705765CF704765C202E0021E201A7
-:101B50001B8CF6862C28F7042D380000000106386F
-:101B60000001F6052D387739000220320044E601E5
-:101B70001B78B5BA6802F0052D38F3020022F30590
-:101B800076F8F3047700E0011B90F30576FCF0058E
-:101B900076FCF70475F800000001203A0000E60129
-:101BA0001BCDF6862C28F7042D38000000010638DE
-:101BB0000001F6052D3877390002F302000F2032BC
-:101BC0000044E6011BCCB33A6802F0052D38F70457
-:101BD0007608F684760007380001C03A6A00E6010C
-:101BE0001BE8F7057608F0057608F6847608F70412
-:101BF0007604F00575F8F60675F8C0367200470CE5
-:101C00000001203A0000E6011C15F70575FCE00113
-:101C10001C24F702000077350002C7386000873ABD
-:101C2000001800000001203A0000E6011C65F705DD
-:101C30007660F7042D38F30672A4F3057648F6862D
-:101C40002C2806380001F6052D3877390002F302FA
-:101C5000000E20320044E6011C74B33A6802E00131
-:101C60001C74F0052D38E0011C70F3067218F306A1
-:101C70007330F30576488796FFFC8296FFF80214CE
-:101C80000000013C0000000000019293FFFC029064
-:101C90000008F70676489713FFFCF70672189713AB
-:101CA000FFFC07880008E00014F49793FFFCF70698
-:101CB00076489713FFFCF70672A49713FFFC07887A
-:101CC0000008E00014F49793FFFCF706764897139A
-:101CD000FFFCF70673309713FFFC07880008E0004D
-:101CE00014F49793FFFCF70676489713FFFCF7066A
-:101CF00073BC9713FFFC07880008E00014F4979367
-:101D0000FFFCF70676489713FFFCF7067448971315
-:101D1000FFFC07880008E00014F49793FFFCF70627
-:101D200076489713FFFCF70674D49713FFFC0788D7
-:101D30000008E00014F49793FFFCF7067648971329
-:101D4000FFFCF70675609713FFFC07880008E000AA
-:101D500014F49793FFFC8796FFFC8296FFF8021419
-:101D60000000013C0000000000019293FFFC029083
-:101D70000008F68676689693FFFCF68677049693BD
-:101D8000FFFC07880008E00015489793FFFCF686E3
-:101D90001DD49693FFFC9013FFFCF686766896930D
-:101DA000FFFC07880008E000161C9793FFFCF70271
-:101DB0000022F70576F4F70576F8F00576FCF005D5
-:101DC00077008796FFFC8296FFF802140000013C22
-:101DD0000000000000019293FFFC02900008F7044D
-:101DE00076F400000001203A0022E6011E01000006
-:101DF00000019713FFFC07880008E0001584979303
-:101E0000FFFC8796FFFC8296FFF802140000013C5D
-:101E10000000000000019293FFFC02900008F7060A
-:101E200077049713FFFCF70676689713FFFC078883
-:101E30000008E00014F49793FFFC8796FFFC82965D
-:101E4000FFF802140000013C000000000001000047
-:101E500000009293FFFC02900008F686781096939B
-:101E6000FFFCF68678A49693FFFC07880008E00044
-:101E700015489793FFFCF6861FBC9693FFFCF682ED
-:101E800000149693FFFCF68678109693FFFC078863
-:101E90000008E000161C9793FFFCF005789C900268
-:101EA000FF34F7027FFFF70578A09702FF3087968F
-:101EB000FFFC8296FFF802140000013C00000000C5
-:101EC00000019293FFFC02900008F604789C8716AC
-:101ED000000084960008F5867710873A0008F68699
-:101EE000218C7539000477390002A73A6802203244
-:101EF0000000C6A8580084160004C63075809436C9
-:101F00000004B4AA580287360008F605789C073802
-:101F10000001E6011F2D973600088702FF30000000
-:101F20000001C03A4A00EE011F3500000001F485AF
-:101F300078A09482FF308796FFFC8296FFF8021407
-:101F4000000C013C0000000000019293FFFC029095
-:101F500000088596000000000001872E0008F68624
-:101F6000218C77390002A73A6802F604789CC704EE
-:101F7000760086AE0008C6307400F7067710F605C6
-:101F8000789C76B50004C6B470008736000820320D
-:101F9000000007380001E6011FA897360008F70285
-:101FA0007FFFF70578A09702FF308796FFFC8296A7
-:101FB000FFF802140004013C0000000000019293AD
-:101FC000FFFC0290000822100008F704789C000033
-:101FD0000001203A0000E60120D1F6027FFF9616AC
-:101FE000FFF4F6842D40F606771026B4000177350D
-:101FF0000004C4B86000C338000074350002F6065F
-:102000007710C0266200EC0120C1F606218CF38413
-:10201000789CA722600200000001C01E7400E60147
-:1020200020B10000000186A60000F70478A000009F
-:102030000001C6B4720020360000EE01209896A67A
-:102040000000F7042D38F6067710C5186000F686F4
-:102050002C28862A000405B80001F5852D3877392B
-:102060000002202E0044E6012070B63A6802F00516
-:102070002D38862A000800000001962A000CF6067A
-:10208000218CA722600200000001C7047600C71C53
-:102090007400E00120B0F705789C8616FFF400007C
-:1020A0000001C0366200EC0120B0000000019696ED
-:1020B000FFF424A4001023180010E0011FFC2420CA
-:1020C00000048616FFF400000001F60578A09602D1
-:1020D000FF308796FFFC8296FFF802140000013C57
-:1020E0000000000000019293FFFC02900008871698
-:1020F000000000000001873A0008F6867710773963
-:102100000004C738680086BA000C873A000800004F
-:102110000001C0367200440C00018796FFFC8296D5
-:10212000FFF802140004013C00000000000192933B
-:10213000FFFC02900008F702000F203A0000EC01BB
-:10214000215DF68677189036000027380001C60416
-:102150000000C03A6200E601214406B40010F60611
-:1021600078A49613FFFCF60678109613FFFC0788F8
-:102170000008E00014F49793FFFC8796FFFC82961A
-:10218000FFF802140000013C000000000001000004
-:102190000001000000020000000400000008000030
-:1021A000001000000020000000400000008000003F
-:1021B0000100000002000000040000000800000010
-:1021C000100000002000000040000000800000001F
-:1021D00000009293FFFC02900008F70678B0971376
-:1021E000FFFCF70679CC9713FFFC07880008E00096
-:1021F00015489793FFFCF706222C9713FFFCF70274
-:1022000000159713FFFCF70678B09713FFFC0788BB
-:102210000008E000161C9793FFFC8796FFFC82964F
-:10222000FFF802140000013C00000000000192933E
-:10223000FFFC02900008F6846F440000000187361E
-:10224000000000000001203A0002E6012270F602C0
-:10225000000087360EF486B60EF800000001C03A82
-:102260006A00470C0001203A0000E6012278203283
-:102270000000F602000120320000E6012294000076
-:102280000001F70432E800000001203A0000E601F6
-:1022900022B1F58203E80F814000F70479C80000FD
-:1022A000000107380001F70579C8F70479C8F582FD
-:1022B00003E89593FFFCF58200159593FFFCF586E6
-:1022C00079CC9593FFFC07880008E0011EC0979326
-:1022D000FFFC8796FFFC8296FFF802140000013C89
-:1022E0000000000000019293FFFC02900008F70636
-:1022F00079CC9713FFFCF70678B09713FFFC07889B
-:102300000008E00014F49793FFFCF70679CC9713CC
-:10231000FFFCF706793C9713FFFC07880008E000F4
-:1023200014F49793FFFC8796FFFC8296FFF8021443
-:102330000000013C000000000001C13C0000021050
-:1023400000049293FFFC029000082210000C859676
-:1023500000000000000186AE0004000000012036ED
-:102360000000E60123842714000C872E00040000DF
-:10237000000107380001972E0004872E0004E001B9
-:1023800024349696FFF49713FFFC85160004000092
-:1023900000019513FFFC9593FFFC9596FFEC0788D1
-:1023A0000008E00125689793FFFC8596FFEC20224A
-:1023B0000000E60124340000000186AE0004861609
-:1023C000FFF400000001C0366200EE0124217735E1
-:1023D0000001C738680077390002C6B85800773165
-:1023E0000001C738600077390002C73858008536C9
-:1023F0000000000000019536000C85360004000046
-:102400000001953600108536000800000001953661
-:10241000001426B4000CC0367200EE0123EC00005C
-:102420000001872E00040000000107380001972EEC
-:102430000004872E00048696FFF485160004773585
-:102440000001C738680077390002C72C7000852A60
-:10245000000000000001953A000C85160004000001
-:102460000001852A000400000001953A001085163D
-:102470000008F4020001953A001496AE0008879611
-:10248000FFFC8296FFF80214000C013C00000000E3
-:1024900000019293FFFC029000082210000C859628
-:1024A000000000000001842E000400000001202232
-:1024B0000000E60125552714000C9713FFFC851634
-:1024C0000004000000019513FFFC9593FFFC959616
-:1024D000FFEC07880008E00125689793FFFC8596CC
-:1024E000FFEC20220000E6012555000000018616C1
-:1024F000FFF40000000120320000EE012545773195
-:102500000001C6AC0000C738600077390002C73848
-:10251000580085360018000000019536000C8536FD
-:10252000001C0000000195360010853600200000D8
-:1025300000019536001406B4000CC0367200EC01A0
-:10254000251100000001872E0004F4020001273845
-:102550000001972E00048796FFFC8296FFF8021474
-:102560000008013C0000000000019293FFFC029073
-:102570000008221000088396000483160000C5009E
-:102580000000841A0004C4A800009416FFF4C026BA
-:102590004200E60126D1000000018316FFF400008E
-:1025A0000001C02A3200E60126D1C7204A00951654
-:1025B000FFF476B8FFE1C73868007739FFFFC5241C
-:1025C000700077290001C738500077390002831660
-:1025D0000000869E0000C5B8300005AC000C872EB8
-:1025E0000000C6000000C0367200E601261020324E
-:1025F0000000869E0004872E000400000001C03603
-:102600007200E601261020320000F602000120329E
-:102610000000E601262500000001C7000000E001DF
-:102620002678203A0000869E0000872E00000000D9
-:102630000001C0367200E201265C00000001E601E4
-:10264000266420320000869E0004872E00040000CD
-:102650000001C0367200E201266520320000F60259
-:102660000001203200004704FFFFE6012679203AEE
-:102670000000F7020001203A0000E60126B1203AEE
-:102680000000EE0126A0203A00014304FFFFC03AFB
-:102690003200E60126C9C0264200E0012590000074
-:1026A0000001E60126C1C0264200E001259000009D
-:1026B000000183160008F4020001E00126E0951AEB
-:1026C0000000E001258CC4A80000E001258CC4288E
-:1026D00000008316000800000001941A0000C400E6
-:1026E00000008796FFFC8296FFF80214000C013C64
-:1026F000000000000001000000009293FFFC029027
-:102700000008859600048416000084960008F702ED
-:102710000003C6A04D80C6B67400E6012771C6202E
-:10272000000020360002E60127A0C5204800C7208F
-:10273000480027380002C0227200E201279CC538F9
-:102740000000872E000076AD001E76B4FFE5C73886
-:102750006FC07738FFF0F733280006300002C03230
-:102760005200E201274105AC0002E00127A0C5208C
-:102770004800C720480027380004C0227200E20148
-:1027800027A0C520480083AD00040000000193B1DC
-:102790000004C0327200E201278500000001C5205C
-:1027A0004800C0325200E40127D50000000186AE87
-:1027B0000000772D001E7738FFE5C6B477C076B5E8
-:1027C000FFE8F6B3680006300001C0325200E401B1
-:1027D00027AC05AC00018796FFFC8296FFF8021437
-:1027E000000C013C0000000000019293FFFC0290ED
-:1027F0000008841600008696000400000001C7222D
-:102800006D80E601281020360000E0012874C438ED
-:102810000000F7020001EE012841F602000076B543
-:10282000000120360000EE01281C77390001E0018C
-:10283000284420220000742100017738FFFF063071
-:10284000000120220000EE012834203A0000E601B9
-:10285000287100000001C0226A00E4012864000021
-:102860000001C4206A00773AFFFFE601285476B4DD
-:10287000FFFFD42007628796FFFC8296FFF80214C0
-:102880000008013C0000000000019293FFFC029050
-:10289000000822100004E00128CCF70629DC86BAE3
-:1028A00000000000000120360000E60128C90000F9
-:1028B00000019716FFF407880008C13400009793C1
-:1028C000FFFC8716FFF40000000127380004F6061D
-:1028D00029E0C03A6200E401289D000000018796CB
-:1028E000FFFC8296FFF802140000013C000000008B
-:1028F00000019293FFFC0290000822100004E00106
-:102900002934F706299886BA000000000001203615
-:102910000000E6012931000000019716FFF4078846
-:102920000008C13400009793FFFC8716FFF40000F5
-:10293000000107380004F60629E0C03A6200E4010D
-:102940002904000000018796FFFC8296FFF802141C
-:102950000000013C0000000000019293FFFC029087
-:102960000008F7047B5000000001203A0000E60157
-:102970002984F6820001F6857B5007880008E00173
-:1029800028F09793FFFC8796FFFC8296FFF80214CD
-:102990000000013C00000000000100000B4C0000A2
-:1029A0000000000042880000000000005E500000AF
-:1029B00000000000C7A80000000000010BD00000CC
-:1029C000000000011C880000000000011E1400002F
-:1029D00000000001212C00000000000122E40000A2
-:0229E0000000F5
-:00000001FF
-/* This is the Myrinet MCP code for LANai4.x */
-/* Generated by  cat $MYRI_HOME/lib/lanai/mcp4.dat > myri_code4.h */
--- zfcpdump-kernel-4.4.orig/firmware/ositech/Xilinx7OD.bin.ihex
+++ /dev/null
@@ -1,177 +0,0 @@
-:10000000FF04A036F3ECFFFFFFDFFBFFF3FFFFFF72
-:10001000EF3FFFF7FFFFFFFFEF7FFEFFCEFEFEFE8D
-:10002000FEDEBDDDFDFFFDCFF7BF7FFF7F3FFEBFE3
-:10003000FFFFFFBCFFFFBDB57F7FBFBF7FFFEFFFAF
-:10004000FFFFFBFFF7F7FFFFFFFFFEDEFEFEFADE1E
-:10005000BDFDEDFDFDCFEFEFEFEFC7DFDFDFDFDF52
-:10006000FF7EFEFD7D6DEEFE7CFBF4FBCFDBDFFF54
-:10007000FFBB7FFF7FFFF7FF9EBF3BBFBF7F7F7F41
-:100080007E6FDFEFF5F6FDF6F5EDEBFFEFEFEF7EC0
-:100090007F7F6F7FFFFEFEFEFEFEEFBFFFFFFFFFD5
-:1000A000FFFFFFFFFFFFBC1F1FEEFFBCB7FFDFFF1F
-:1000B000DFEF3BE3D3FFFBFFFFDFFFFFFFBABF2D07
-:1000C000DBBDFDDBDFFAFBFFEFFBDBF3FFDFFD7FDB
-:1000D000EFFBFFFFBEBF27BAFEFBDFFFF6FFFFEF20
-:1000E000FBDBF3D99A3FFFAFBFFFFFBE3F37BD96A3
-:1000F000FFFFFFFFFFFFAEFBF3F3EBFFFFFFFFFF91
-:10010000FFF7FABCAEFEBEFEBB7FFDFF7FEFF7FB45
-:10011000BBD7F77FFFF7FFFFF7BCEDFDBD9D7D7BF4
-:10012000FB7B7BFBAFFFFEFDFDFEFEFFFFFFFFF74E
-:10013000AAB9BF8FBFDFFF7FFFFF7FCFFBEBCBEB0A
-:10014000EEFFFFD7FFFFFF3E333F1C7CFCFFFFFFAE
-:10015000FFFFCFD3F3E3F3FBFFFFFFFFFFEBFE3522
-:100160003F3DFDFDFFFFFFBFFFEF6FE3E3E3EFFF69
-:10017000FFDFFFFFF7FE3E5EFEFFFFFFFFFDFFFF1D
-:10018000AFCFF2CBCF8EFFFFFFFFFFFDFC3E1F9EE8
-:10019000ADFDFFFFBFFFFFEFFFB3F7E7F7FAFFFF8C
-:1001A000FFFFFFEEEBABAF9FE37FFFDEFF7FEEFFD6
-:1001B000FFFB3AFAFFF277FFFFF7FEFFFEBDAEDE70
-:1001C0007D7DFDFFBFEEFFFDFFDBFBFFF7EFFBFFDC
-:1001D000FFFEFF2DAFB9FD79FBFAFFBFEFFFFF91E7
-:1001E000FAFBDFF7F7FFFFFFFCCF37BFBFFF7F7FD3
-:1001F000FFFFFFAFFFFFF3FBFBFFF5EFFFFFF7FA9A
-:10020000FFFFEEFAFEFB55DDFF7FAFFEFFFBFBF5C8
-:10021000FFF7EFFFFFFFBEBDBDBDBD7D7B7B7B7BE1
-:10022000FBAEFFFDFEFFFFFFFFFFFFFFF7DAB76149
-:10023000FFB959F373F3DF7F6FDFEFF7EBEBD7FF16
-:10024000D7FFFFF7FE7FFB3E3873F67FFCFFFFCF43
-:10025000FFB7FBB3B367FFE7FDFFEFF67FB7BCF572
-:100260007BF6F7F5FFFFEFFFF7FFF7CEE7FF9FFF06
-:10027000FFF5FE7DFF5FFFFFFFFFFFFFFFEFFFF6D4
-:10028000CBDBEEFEFFDFFFFFFFFE7FBE1E3EFEFF6D
-:100290007DFEFFFFEFBFE7FFE3E3FFDFE7FFFFFFC9
-:1002A000B8EFB72FEEFFDFFFBFFF7FEFEBBFA3D3AA
-:1002B000FF7FFFFFFFFFF7BEFD3FCFFDFBFFFFFF0F
-:1002C000FFFFAFFBBFBBBFDBFDFBFFFFFFFF3EFE42
-:1002D0003FBABAFEFFFFFFEFFFEFC37FB29BFFFF06
-:1002E000FFFFFEFFFF3CFF3F3CFFFEFFFFFFFFFF66
-:1002F000AFF3FEF3E3EBFFFFFFFBFFF79AFEAF9ECA
-:10030000BEFEFFDFFFFF7BEFF7BFFBFBFBFFFF7FC7
-:10031000FFFFFFBCBDFDBDDD7D7B7B7B7BFBAEFFBF
-:10032000FFFFFEFEFFFDFFFFFFF79AFF9FFFAFEF0E
-:10033000FFFFFFFF7FCFF3FFEBFFEBFFFFBFFFFFF1
-:10034000EFFEFF37FCBFFFFFFFFFFFFFCFEFFDF327
-:10035000FFEEFEFFFFFFFFFF6EFD2FFDFFFDFFFF26
-:10036000FFFFFFEFCFFFF3BF69FFFFFFFFFFFFFEC0
-:10037000FB9FFFBFFDFFFFFFFFFFEF87FEDAEFCF21
-:10038000FFFFFFFFFFFFFEEFBFEFEFFDFFFFFFFFF0
-:10039000FFEFFDFF7BFFEBFEFFFFFFFFEBF8FFEF43
-:1003A000AFFFFFBDFFFFFF7FEE7FEFFFBBFFBFFB98
-:1003B000FFFFFFF7F6FBBDFDDDF5FFFFFFFFFFAF22
-:1003C000FF5FF5DFFF7FFFFFFFFFFFF6F3FFDEFEBE
-:1003D000EFFDFFFFFFFFEFFFDEDF5FDFFDFFFFFF52
-:1003E000FFFFFEFFFFFEFEFFFDFFFFFFFFAFFFFF72
-:1003F000EFEDFFDFFFFFFBFFFFDABDBEAEFE7FFDCF
-:10040000DFFFFF7FEFFFFBFBFB7FF7FFFFFFFFF748
-:10041000BCFDBDBDBDFD7B7B7B7BFBAEFFFFFDFF60
-:10042000FFFFFDFFFFFFFFFA9FBFBFCF7FFFFFFF73
-:10043000FFFFAFFFEBEBEBFFD7FEFFFFBFE7FEBF1A
-:100440007FFCFFFFEDFFFFFFFF4FFFFBFBFFFFDD2B
-:10045000FFFFFFFFFFFEBDDF9DFDDFB9FFFFFFFFD9
-:10046000EFFFFBEFEBFFDEFFFFFFFFFFF69FFFFC61
-:10047000FEFBFDFFFFFFFFEFDFFACDCFBF9FFFFFCA
-:10048000FFFFF7FEBFFFDFEF5FFFFFFFFF7F6FFFA5
-:10049000BBFDFFFFFFFFFFFFFFFF7EFF5FFFBFBF53
-:1004A000F9FFFFFF7F6E7BFFEFFDEBDFFFFFFFFF3D
-:1004B000F7B63EFCFDBF7EFBFFFFFFF7EFF7F3F75C
-:1004C000FFFBFFFFFFFFFFFF6E3579FFBFFCFFFF64
-:1004D000FFFFFFEFFB53DFFFEBBFFFFFFFFFFFBCA3
-:1004E000FFFFFFBFFFFDFFFFFFFFAFF5FFF7FFFBC4
-:1004F000FFFFFFFFFFFFBAAAEEFE3F7DFDFFFFFFFC
-:100500007FAF77FBFBFFFBF7FFFFFFFFF7BEBDBD34
-:10051000BDBDFD7B7B7B7BFBAEFFEFFFFFFFFFFCE9
-:10052000FFFFFFFF9AD9B8FFFF79FFFFFFFFFFCF63
-:10053000FBFFEBFFEBD7FFFFFFFFE7DEF8FBFE3F24
-:10054000FBFDFFFFFFFFCFADBFFAFF73DFFFFFFF34
-:10055000FFFF3AF5B7FC3FF9FDFFFFFF7FEFF3FF29
-:10056000BFFEF39FFEFFFFFFF73EFFFFFFBFFFFF52
-:10057000FFFFFFFFAFD3FEDBFFDBDFFFFFFFFFFF70
-:100580003EFFBFFF7FFFFDFFFFFFFF8FF3FFEDFF8C
-:10059000F7FBFFFFFFFFEFF63CFEFFFFFFFFFFFF54
-:1005A000FF9FEFEFD1FFFFFFFFFFFFFFFFFF7EBFCA
-:1005B000FDFFFFFFFFFFFFFFBBEFDFF1FFFFFFFFCF
-:1005C000FFFFFFFFFFEE3EFEFFFFFFFFFFFFFFBF4E
-:1005D000EFFDC3FFFFFFFFFFFFFFBFFFFC3EFEFF7E
-:1005E000FFFFFFFFFFFFFF2EEFF3FFFFFFFFFFFF08
-:1005F000FFFFF7BABEFEFFFFFFFFFFFFFF7FAFFB6E
-:10060000FBFDFFFFFFFEFFFFFFF2D6EDBDBDBD7D91
-:100610007B7B7B7BFBAFDFFFFFFFFFFFFFFFFFFF6E
-:10062000FF92BFFFFFFFFFFFFFFFFF7FAFEBEBFF7F
-:10063000FFFFFFFFFFFFFFE7FE2EFEFFFFFFFFFFB5
-:10064000FFFFFF4FEFF3FFFFFFFFFFFFFFFFFFFE87
-:100650003CFEFFFFFFFFFFFFFFFFEFCEC3FDFFFFED
-:10066000FFFFFFFFFFFFFE5DFFFFFFFFFFFFFFFF3D
-:10067000FFEFCFEBFFFFFFFFFFFFFFFFF7EE3EFFB8
-:10068000FFFFFFFFFFFFFF7FEFDFE2FFFFFFFBFF4B
-:10069000FFFFFFFFF6BEFCFFFFFFFFFFFFFF7FEE48
-:1006A0005FE6FFFFFFFFFFFFFFFFFF3E7DFFFFFF56
-:1006B000FFFFFFFFFFFFEFF3FBFFFFFFFFFFFFFF6A
-:1006C000BFF736BEFEFFFFFFFFFFFFFFFFEFD3F6D2
-:1006D000FEFFFFFFFFFFFFFFFFFC7FEEFFFFFFFFBF
-:1006E000FFFFFFFFAFEFEBFFFFFFFFFFFFFFFFFF8E
-:1006F000BABEFEFFFFFFFFFFFFFFFFEEFBFAFFFFAB
-:10070000FFFFFFFFFFFFF7D6FDBDBDBD7D7B7B7B00
-:100710007BFBAEFF7EFFFFFFFFFFFFFFFFF7BABFD0
-:10072000FFFFFFFFFFFFFFFF7FEFEB6BFFFFFFFF11
-:10073000FFFFFFFFF7FEBEFEFFFFFFFFFFFFFFFF14
-:100740004FEFF7FFFFFFFFFFFFFFFFEF3E6EFCFFE6
-:10075000FFFFFFFFFFFFFFEFC3C9FFFFFFFFFFFF2B
-:10076000FFFFFF3EBFFFFFFFFFFFFFFFFFFFEFFBAE
-:10077000D5FFFFFFFFFFFFFFFFFFFEFEFEFFFFFFB6
-:10078000FFFFFFFFFF6FEFFBFFFFFFFBFFFFFFFF21
-:10079000FFF6DFFFFFFFFFFFFFFF7FFEEFFFFFFF23
-:1007A000FFFFFFFFFFFFE7FFFEFFF7FFFFFFFFFF7A
-:1007B000FF7FFAEFBFFFFFFFFFFFFFFFFFE7FFFE37
-:1007C000FFFFFFFFFFFFFFFF7FFEEFBFFFFFFFFF0A
-:1007D000FFFFFFFFA7FFFCF7FFFFFFFFFFFFFF7F0C
-:1007E000FEAEFFFFFDFFFFFFFFFFFFE7F7FAFFFD94
-:1007F000FFFFFFFFFFFFFF7FAFFFFFFFFFFFFFFFD9
-:10080000FFFFFFF7BEBDBDBDBD7D7B7B7B7BFBAF2F
-:100810007FFFFFFFFFFFFFFFFFFFFFCAFFFFFFFF9D
-:10082000FFFFFFFFFF7F6FFFFFFFFFFFFFFFFFFFE8
-:10083000FFE7FEFFFFFFFFFFFFFFFFFFFFCFFEFF12
-:10084000FFFFFFFFFFFFFFFFFFFEDFFFFFFFFFFFD9
-:10085000FFFFFFFFEFFFFEFFFFFFFFFFFFFFFFFFB9
-:10086000FEFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFA9
-:10087000FFFFFFFFFFFFF7FEFFFFFFFFFFFFFFFF91
-:10088000FFFFEFFFFEFFFFFFFBFFFFFFFFE7F2FCB5
-:10089000EFFFFFFFFFFFFFFF7FAEEFFFFFFFFFFF59
-:1008A000FFFFFFFFF77EFDFFFFFFFFFFFFFFFFFFE3
-:1008B000EFFFFEFFFFFFBFFFFFFFBFFFFEFEFFFFDB
-:1008C000FFFFFFFFFFFFDFEFDDFEFFFFFFFFFFFF8B
-:1008D000FFFFFFFEFEFFFFFFFFFFFFFFFFFFAFEF8A
-:1008E000FFFFFFFFFFFFFFFFFFFFBAFEFFFFFFFF5E
-:1008F000FFFFFFFFFFEFFAFEFFFFFFFFFFFFFFFF1E
-:10090000F69CBDBDBDBD7D7B7B7B7BFBAEFFFFFF52
-:10091000FFFFFFFFFFFFFFF77AFFFFFFFFDFFFFF94
-:10092000FFFF6FEFF7FFFFFFDFFFFFFFFFFFF7FEA8
-:10093000FEFFFFFFDFFFFFFFFFFFCFEBFFFFFFFF2C
-:10094000FFFFFFFFFFEF9EFCFFFFFFFFFFFFFFFF2B
-:10095000FFEFEFFFFFFFFFFFFFFFFFFFFFFEFFFFC8
-:10096000FFFFFFFFFFFFFF7FEFCBFFFFFFFFFFFD5D
-:10097000FFFFFFFFBEFDFFFFFFFFFFFFFFFFFFEFDA
-:10098000EFFFFFFFDFFFFFFFFFFFFFF8FFFFFFFFAE
-:10099000BFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFB7
-:1009A000FFFFFEFFFFFFFFFFFFFFFFFFFBAF7FFF2C
-:1009B000FFFFDFFFFFFFFFFFFFFEEFFFFFFFFFFF78
-:1009C000FFFFFFFFEFFFFFFFFFFFFFFFFFFFBFFF87
-:1009D000FEFFFFFFFFFFFFFFFFFFFFAEFFFFFFFF79
-:1009E000FFFFFFFFFFFFF7FAFFFFFFFFFFFFFFFF24
-:1009F000FF7FEFFFFFFFFFFFFFFFFFFFFFF7BCBD24
-:100A0000BDBDBD7D7B7B7B7BFBAFFFFFFFFFFFFFA2
-:100A1000FFFFFFFFF7FAFFFFFFFFFFFFFFFFFF7F73
-:100A2000AF7FFFFFFFFFFFFFFFFFFFEFFEFFFFFFB7
-:100A3000FFFFFFFFFFFFFFCFFFFFFFFFFFFFFFFFF6
-:100A4000FFFFFFFEFFFFFFFFFFFFFBFFFFFFEFFFCB
-:100A5000FFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFA7
-:100A6000FFFFFFFFFFEFFFFFFFFFFFFFBFFFFFFFE6
-:100A7000FFFCFFFFFFFFFFFFFFFFFFFFEFFFFFFF99
-:100A8000FFFFFBFFFFFFFFEFFEFF9F9F9F3F3F3FEB
-:100A90003F3FFFEFDFDFDFDFCFB7BFBFBFBFFFBC31
-:100AA000B99DBDBD7D7B7B7B7BFBEFD7F5F3F1D1A2
-:100AB00065E3E3E3A3FFFE7FFEDEDEFFBDBDBDBD5C
-:100AC000DFEFFBF7F3F3F3E7E7E7E7E7FBFEFFFF13
-:0A0AD000FFFFFFFFFFFFFFFFFFFF26
-:00000001FF
-This file contains the firmware of Seven of Diamonds from OSITECH.
-(Special thanks to Kevin MacPherson of OSITECH)
--- zfcpdump-kernel-4.4.orig/firmware/r128/r128_cce.bin.ihex
+++ /dev/null
@@ -1,129 +0,0 @@
-:1000000000000000108038000000000010003800E0
-:10001000000000020000008E0000000200000091BD
-:1000200000000000402E2423000000006062124FF8
-:10003000000000002E2B596D000000007677753E01
-:1000400000000000898984820000000023BC8B0D21
-:10005000000000002323232300000000238DABB405
-:1000600000000000232323230000000100B028002B
-:100070000000000100032800000000010004C0008F
-:100080000000000100030800000000023660300E8E
-:100090000000000B00040000000000000000000051
-:1000A000000000010200151D0000000100001D0EEF
-:1000B00000000001000039D900000001000019D73C
-:1000C0000000000C0000001C00000001000019D618
-:1000D0000000000C0000001C0000000200000017DF
-:1000E0000000000B01200000000000000100358A24
-:1000F0000000000100064000000000090000001E92
-:100100000000000108D015B4000000101910100004
-:100110000000000300002000000000000000280094
-:1001200000000001000308000000000100003D0E77
-:10013000000000010000C8000000000A0000882A3A
-:10014000000000090000002A000000010200150F55
-:1001500000000002000028240000000100003D65AE
-:100160000000000100003D66000000020000002BBE
-:100170000000000100F32DB4000000012200D8BFF0
-:100180000000000100E088BF0000000C1333383786
-:1001900000000001020615650000000C0000003799
-:1001A00000000001020015640000000100003D662F
-:1001B000000000020000002E000000040020083AA9
-:1001C0000000000100080800000000010006C0FF58
-:1001D000000000040040003D000000010007C800CE
-:1001E00000000001000700FF000000030000000005
-:1001F0000000000C0000005C000000020000002E67
-:100200000000000C000000B00000000100003D767E
-:100210000000000100032800000000010000480069
-:1002200000000001000208000000000106001D0E91
-:1002300000000001000248000000000100028800E8
-:100240000000000100F3C5F80000000100100000EC
-:10025000000000060030004E0000000100003D6379
-:100260000000001080303DF0000000021000384314
-:1002700000000002000028430000000C000000B055
-:100280000000000100003D760000000100003D7705
-:100290000000000100003D0E0000000100003D0FC5
-:1002A000000000010050280000000006003000524D
-:1002B0000000001080303DF00000000100003DF81B
-:1002C00000000002000000520000000100053D0E89
-:1002D0000000000100103D0F00000002003000553A
-:1002E0000000000100003D700000000100001E89B8
-:1002F0000000000100003D710000000300003D729D
-:100300000000000C0000005C000000020000006221
-:100310000000000100003F280000000100003F270E
-:100320000000000100003E820000000100003E8845
-:100330000000000100003E660000000100003E6772
-:100340000000000100003E760000000100003E6851
-:100350000000000100003E690000000100003E6C4A
-:100360000000000000003E6D0000000100002800B9
-:1003700000000001005028000000000100003D685E
-:100380000000000100030800000000060000006EED
-:10039000000000010002C0000000000106303D62C4
-:1003A0000000000200000070000000020030006F3A
-:1003B00000000000200038C0000000010001C0C0A3
-:1003C0000000000E0000007D0000000C0003287FEC
-:1003D00000000001020015BB0000000C00030880B3
-:1003E0000000000002003DBC0000000100003DBB19
-:1003F0000000000000003DBC00000003000480007D
-:100400000000000100048000000000030006C0029C
-:100410000000000100B0280000000000306038003B
-:100420000000000100C028000000000100B008002A
-:100430000000000100D600000000000712801086B6
-:10044000000000000000280000000001000039CC7E
-:1004500000000001000039CD00000001000039C992
-:1004600000000001000039CA00000000000039CB84
-:10047000000000011003B80000000001009000001F
-:100480000000000110003800000000010003080017
-:100490000000000100903D1B0000000140203D0ACB
-:1004A0000000000140203D0B00000001000880001A
-:1004B000000000010001C0C00000000E0000009F0D
-:1004C0000000000C000308800000000142203DBD38
-:1004D0000000000C0003087F0000000142003DBB4B
-:1004E0000000000C000308800000000142203DBC19
-:1004F00000000002000000A20000000140203DBDFD
-:100500000000000140003DBB0000000140203DBC58
-:1005100000000001000840000000000100A00000F1
-:1005200000000006003000A6000000101060380037
-:1005300000000009000000A80000000300400000C7
-:100540000000000300403D1D00000000000000000E
-:1005500000000000000001000000000E000000AEDE
-:10056000000000010001C0A900000001020015C741
-:100570000000000C000000B0000000000000280097
-:10058000000000010001C0AA00000001020015D215
-:10059000000000010001C0A900000003020015C70F
-:1005A0000000000100003E88000000010001C0BA08
-:1005B0000000000102001728000000010001C0BB7C
-:1005C000000000010200165A0000000000003E5B1F
-:1005D000000000000000010000000000000010000A
-:1005E000000000010006400B00000009000000BCF4
-:1005F00000000000000028000000000000000000D3
-:1006000000000000000000000000000000000000EA
-:1006100000000000000000000000000000000000DA
-:1006200000000000000000000000000000000000CA
-:1006300000000000000000000000000000000000BA
-:1006400000000000000000000000000000000000AA
-:10065000000000000000000000000000000000009A
-:10066000000000000000000000000000000000008A
-:10067000000000000000000000000000000000007A
-:10068000000000000000000000000000000000006A
-:10069000000000000000000000000000000000005A
-:1006A000000000000000000000000000000000004A
-:1006B000000000000000000000000000000000003A
-:1006C000000000000000000000000000000000002A
-:1006D000000000000000000000000000000000001A
-:1006E000000000000000000000000000000000000A
-:1006F00000000000000000000000000000000000FA
-:1007000000000000000000000000000000000000E9
-:1007100000000000000000000000000000000000D9
-:1007200000000000000000000000000000000000C9
-:1007300000000000000000000000000000000000B9
-:1007400000000000000000000000000000000000A9
-:100750000000000000000000000000000000000099
-:100760000000000000000000000000000000000089
-:100770000000000000000000000000000000000079
-:100780000000000000000000000000000000000069
-:100790000000000000000000000000000000000059
-:1007A0000000000000000000000000000000000049
-:1007B0000000000000000000000000000000000039
-:1007C0000000000000000000000000000000000029
-:1007D0000000000000000000000000000000000019
-:1007E0000000000000000000000000000000000009
-:1007F00000000000000000000000000000000000F9
-:00000001FF
--- zfcpdump-kernel-4.4.orig/firmware/radeon/R100_cp.bin.ihex
+++ /dev/null
@@ -1,130 +0,0 @@
-:1000000000000000210070000000000020007000CF
-:1000100000000004000000B400000004000000B86C
-:10002000000000006F5B4D4C000000004C4C427F14
-:10003000000000005B568A92000000004CA09C6DFE
-:1000400000000000AD4C4C4C000000004CE1AF3D06
-:1000500000000000D8AFAFAF00000000D64C4CDC71
-:10006000000000004CD10D1000000016000F000031
-:1000700000000000362F242D0000000400000012B4
-:1000800000000016000F000000000000362F282D91
-:1000900000000002000380E70000000204002C972B
-:1000A00000000016000F000100000000333A373056
-:1000B00000000002000077EF0000000200061000C0
-:1000C0000000001A000000210000001E0000400097
-:1000D00000000002000610000000001A00000021CD
-:1000E0000000001E0000400000000002000610009A
-:1000F0000000001A000000210000001E0000400067
-:100100000000000400000017000000020003802B24
-:1001100000000002040067E0000000040000001777
-:1001200000000002000077E000000002000650001E
-:1001300000000002000037E100000006040067E153
-:1001400000000002000077E000000002000077E1FC
-:1001500000000006000077E100000000FFFFFFFF45
-:100160000000000010000000000000020003802BCF
-:1001700000000006040067E0000000020000767541
-:100180000000000200007676000000020000767792
-:100190000000000600007678000000020003802CBA
-:1001A00000000002040026760000000200007677BE
-:1001B0000000000600007678000000180000002F04
-:1001C000000000180000002F0000000600000000E2
-:1001D000000000180000003000000018000000308F
-:1001E0000000000600000000000000020160500056
-:1001F000000000020006500000000002000980001C
-:1002000000000002000610000000000464C0603E10
-:1002100000000002000380E600000002040025C583
-:1002200000000016000800000000000000000000B0
-:10023000000000020400251D00000002000075807F
-:100240000000000200067581000000020400258005
-:100250000000000200067581000000040000004953
-:10026000000000000000500000000002000380E6D3
-:1002700000000002040025C5000000020006100076
-:10028000000000020000750E000000020001900056
-:10029000000000140001105500000012000000557D
-:1002A000000000020400250F000000040000504F71
-:1002B00000000002000380E600000002040025C5E3
-:1002C0000000000200007565000000020000756675
-:1002D000000000040000005800000002000380E657
-:1002E00000000002040025C50000000201E655B42C
-:1002F000000000024401B0E40000000201C110E46B
-:10030000000000182666706600000002040C2565D7
-:1003100000000018000000660000000204002564D0
-:100320000000000200007566000000040000005D8F
-:1003300000000008004010690000000200101000DA
-:1003400000000002000D80FF000000080080006C2B
-:1003500000000002000F900000000002000E00FFED
-:100360000000000600000000000000180000008FE0
-:10037000000000040000005B00000002000380E6B3
-:1003800000000002040025C5000000020000757690
-:100390000000000200065000000000020000900073
-:1003A0000000000200041000000000020C00350EE6
-:1003B0000000000200049000000000020005100090
-:1003C0000000000201E785F80000000200200000A4
-:1003D0000000000C0060007E000000020000756359
-:1003E00000000021006075F0000000042000707320
-:1003F000000000040000507300000002000380E6CB
-:1004000000000002040025C500000002000075760F
-:100410000000000200007577000000020000750E69
-:10042000000000020000750F0000000200A0500054
-:100430000000000C0060008300000021006075F0E7
-:1004400000000002000075F80000000400000083B6
-:1004500000000002000A750E00000002000380E6A2
-:1004600000000002040025C5000000020020750FF6
-:1004700000000004006000860000000200007570AB
-:100480000000000200007571000000060000757297
-:1004900000000002000380E600000002040025C501
-:1004A00000000002000050000000000200A0500008
-:1004B0000000000200007568000000020006100045
-:1004C0000000000C00000095000000020005800004
-:1004D000000000020C60756200000004000000973C
-:1004E00000000002000380E600000002040025C5B1
-:1004F000000000040060009600000000400070E56D
-:1005000000000002000380E600000002040025C590
-:1005100000000002000380E50000001C000000A8AD
-:1005200000000018000650AA00000002040025BBCD
-:1005300000000018000610AB00000000040075BCAD
-:1005400000000002000075BB00000000000075BC48
-:100550000000000600090000000000020009000081
-:1005600000000006000D800200000002000078324A
-:10057000000000020000500000000002000380E7BD
-:100580000000000204002C97000000020000782008
-:100590000000000200007821000000000000780048
-:1005A000000000020120000000000002200770008F
-:1005B0000000000201200000000000022000700086
-:1005C0000000000200061000000000020120751B60
-:1005D000000000028040750A000000028040750B98
-:1005E000000000020011000000000002000380E58E
-:1005F0000000001C000000C600000018000610AB40
-:1006000000000002844075BD00000018000610AA1A
-:1006100000000002840075BB00000018000610AB4B
-:1006200000000002844075BC00000004000000C906
-:1006300000000002804075BD00000002800075BB14
-:1006400000000002804075BC000000020010800025
-:1006500000000002014000000000000C006000CD1E
-:100660000000002020C0700000000012000000CF39
-:100670000000000600800000000000060080751DDC
-:100680000000000000000000000000020000775C95
-:100690000000000200A050000000000200661000F0
-:1006A000000000200460275D000000000000400002
-:1006B0000000000201E0083000000000210070008E
-:1006C000000000006464614D00000000696874204F
-:1006D00000000000000000730000000000000000A7
-:1006E000000000020000500000000002000380D063
-:1006F00000000002040025E000000000000075E199
-:10070000000000000000000100000002000380E083
-:1007100000000002040023940000000000005000CC
-:1007200000000000000000000000000000000000C9
-:1007300000000000000000080000000000000004AD
-:1007400000000000000000000000000000000000A9
-:100750000000000000000000000000000000000099
-:100760000000000000000000000000000000000089
-:100770000000000000000000000000000000000079
-:100780000000000000000000000000000000000069
-:100790000000000000000000000000000000000059
-:1007A0000000000000000000000000000000000049
-:1007B0000000000000000000000000000000000039
-:1007C0000000000000000000000000000000000029
-:1007D0000000000000000000000000000000000019
-:1007E0000000000000000000000000000000000009
-:1007F00000000000000000000000000000000000F9
-:00000001FF
-/* production radeon ucode r1xx-r6xx */
--- zfcpdump-kernel-4.4.orig/firmware/radeon/R200_cp.bin.ihex
+++ /dev/null
@@ -1,130 +0,0 @@
-:1000000000000000210070000000000020007000CF
-:1000100000000004000000BF00000004000000C356
-:10002000000000007A685E5D000000005D5D55889C
-:100030000000000068659197000000005DA19F78B6
-:10004000000000005D5D5D5D000000005DEE5D5044
-:1000500000000000F2ACACAC00000000E75DF9E984
-:1000600000000000B1DD0E1100000000E2AFAFAFF4
-:1000700000000016000F000000000000452F232D97
-:10008000000000040000001300000016000F000034
-:1000900000000000452F272D00000016000F000172
-:1000A000000000003E4D4A3700000002000077EFDC
-:1000B00000000002000610000000001A00000020EE
-:1000C0000000001E000040000000000200061000BA
-:1000D0000000001A000000200000001E0000400088
-:1000E00000000002000610000000001A00000020BE
-:1000F0000000001E00004000000000040000001688
-:10010000000000020003802A00000002040067E0F3
-:10011000000000040000001600000002000077E06C
-:10012000000000020006500000000002000037E15D
-:1001300000000006040067E100000002000077E014
-:1001400000000002000077E100000006000077E1F7
-:1001500000000000FFFFFFFF000000001000000093
-:100160000000000007F007F0000000020003802AF2
-:1001700000000006040067E0000000020003802C7D
-:100180000000000204002741000000020400274193
-:100190000000000204002743000000020000767502
-:1001A0000000000200007676000000020000767772
-:1001B0000000000600007678000000020003802C9A
-:1001C0000000000204002741000000020400274153
-:1001D00000000002040027430000000200007676C1
-:1001E000000000020000767700000006000076782C
-:1001F000000000020003802B0000000204002676AD
-:100200000000000200007677000000020003802C4E
-:100210000000000204002741000000020400274300
-:100220000000000600007678000000020003802C29
-:1002300000000002040027410000000204002741E2
-:10024000000000020400274300000006000076784A
-:10025000000000180000002F000000180000002F10
-:100260000000000600000000000000180000003739
-:100270000000001800000037000000060000000029
-:100280000000000201605000000000020006500063
-:1002900000000002000980000000000200061000BB
-:1002A0000000000464C06051000000160008000057
-:1002B0000000000000000000000000020400251DF6
-:1002C0000000000200007580000000020006758139
-:1002D0000000000204002580000000020006758175
-:1002E000000000040000005A000000000000500060
-:1002F0000000000200061000000000020000750E61
-:1003000000000002000190000000001400011064D1
-:100310000000001200000064000000020400250F2D
-:10032000000000040000505E00000002000075653F
-:100330000000000200007566000000040000006577
-:100340000000000201E655B4000000024401B0F0D4
-:100350000000000201C110F0000000182666707154
-:1003600000000002040C2565000000180000007168
-:100370000000000204002564000000020000756611
-:100380000000000400000068000000080040107435
-:10039000000000020010100000000002000D80FFAD
-:1003A000000000080080007700000002000F9000AD
-:1003B00000000002000E00FF000000060000000028
-:1003C0000000001800000094000000040000006815
-:1003D00000000002000075760000000200065000D8
-:1003E0000000000200009000000000020004100065
-:1003F000000000020C00350E000000020004900016
-:1004000000000002000510000000000201E785F86E
-:1004100000000002002000000000000C00600087C7
-:10042000000000020000756300000021006075F00C
-:10043000000000042000707C000000040000507CDC
-:1004400000000002000075760000000200007577D1
-:10045000000000020000750E000000020000750F91
-:100460000000000200A050000000000C0060008AA4
-:1004700000000021006075F000000002000075F827
-:10048000000000040000008A00000002000A750E4F
-:10049000000000020020750F000000040060008DC5
-:1004A000000000020000757000000002000075717D
-:1004B00000000006000075720000000200005000FD
-:1004C0000000000200A0500000000002000075685B
-:1004D00000000002000610000000000C0000009860
-:1004E0000000000200058000000000020C60756240
-:1004F000000000040000009A000000040060009961
-:1005000000000000400070F100000002000380F1D4
-:100510000000001C000000A700000018000650A901
-:1005200000000002040025BB00000018000610AA0D
-:1005300000000000040075BC00000002000075BB54
-:1005400000000000000075BC00000006000900006B
-:10055000000000020009000000000006000D8002FB
-:10056000000000020000500000000002000078219E
-:100570000000000000007800000000020000782168
-:10058000000000000000780000000002016650003A
-:1005900000000002000A000000000002000671CC0A
-:1005A000000000020286F1CD00000010000000B73C
-:1005B00000000000210070000000001C000000BED0
-:1005C000000000020006500000000002000A0000C7
-:1005D000000000020006100000000002000B0000F6
-:1005E000000000023806700000000004000A00BA93
-:1005F0000000000020007000000000020120000048
-:10060000000000022007700000000002012000002E
-:100610000000000020007000000000020006100032
-:10062000000000020120751B000000028040750AD6
-:10063000000000028040750B000000020011000065
-:1006400000000002000380F10000001C000000D147
-:1006500000000018000610AA00000002844075BDCA
-:1006600000000018000610A900000002840075BBFD
-:1006700000000018000610AA00000002844075BCAB
-:1006800000000004000000D400000002804075BD9E
-:1006900000000002800075BB00000002804075BCB5
-:1006A0000000000200108000000000020140000075
-:1006B0000000000C006000D80000002020C0700086
-:1006C00000000012000000DA0000000600800000B8
-:1006D000000000060080751D00000002000025BB20
-:1006E00000000004000040D4000000020000775C1D
-:1006F0000000000200A05000000000020066100090
-:10070000000000200460275D0000000000004000A1
-:1007100000000002000079990000000200A05000D3
-:100720000000000200661000000000200460299B09
-:1007300000000000000040000000000201E008305E
-:1007400000000000210070000000000200005000C6
-:10075000000000020003805600000002040025E0B3
-:1007600000000000000075E1000000000000000132
-:1007700000000002000380ED0000000004007394FC
-:100780000000000000000000000000000000000069
-:1007900000000002000078C400000002000078C5DC
-:1007A00000000002000078C600000002000079246A
-:1007B00000000002000079250000000200007926F8
-:1007C00000000004000000F2000000020000792494
-:1007D00000000002000079250000000200007926D8
-:1007E00000000004000000F900000000000000000C
-:1007F00000000000000000000000000000000000F9
-:00000001FF
-/* production radeon ucode r1xx-r6xx */
--- zfcpdump-kernel-4.4.orig/firmware/radeon/R300_cp.bin.ihex
+++ /dev/null
@@ -1,130 +0,0 @@
-:10000000000000004200E000000000004000E000AE
-:1000100000000008000000AE00000008000000B270
-:100020000000000067554B4A000000004A4A447532
-:100030000000000055527D83000000004A8C8B6553
-:10004000000000004AEF4AF6000000004AE14A4A78
-:1000500000000000E497979700000000DB4AEBDD0A
-:10006000000000009CCC4A4A00000000D1989898FB
-:10007000000000004A0F9AD600000004000CA00007
-:1000800000000038000D0012000000040000E8B479
-:1000900000000038000D0014000000040000E8B665
-:1000A00000000038000D0016000000040000E854B5
-:1000B00000000038000D0018000000040000E855A2
-:1000C00000000038000D001A000000040000E8568F
-:1000D00000000038000D001C000000040000E8577C
-:1000E00000000038000D001E000000040000E8249D
-:1000F00000000038000D0020000000040000E8258A
-:1001000000000038000D0022000000040000E8306C
-:1001100000000038000D0024000000040000F0C0C2
-:1001200000000038000D0026000000040000F0C1AF
-:1001300000000038000D0028000000040000F0411D
-:1001400000000038000D002A000000040000F184C7
-:1001500000000038000D002C000000040000F185B4
-:1001600000000038000D002E000000040000F186A1
-:1001700000000038000D0030000000040000F1878E
-:1001800000000038000D0032000000040000F18083
-:1001900000000038000D0034000000040000F3935C
-:1001A00000000038000D0036000000040000F38A53
-:1001B00000000038000D0038000000040000F38E3D
-:1001C000000000040000E821000000040140A0003D
-:1001D00000000018000000430000000400CCE8000C
-:1001E00000000004001B000100000004080048009B
-:1001F00000000004001B000100000004080048008B
-:1002000000000004001B000100000004080048007A
-:10021000000000080000003A000000000000A000FC
-:10022000000000042000451D000000040000E580DF
-:1002300000000004000CE581000000040800458077
-:1002400000000004000CE5810000000800000047E9
-:10025000000000000000A00000000004000C2000CE
-:10026000000000040000E50E000000040003200070
-:10027000000000280002205100000024000000516E
-:10028000000000040800450F000000080000A04B1B
-:10029000000000040000E565000000040000E566C1
-:1002A00000000008000000520000000403CCA5B4C8
-:1002B00000000004054320000000000400022000AC
-:1002C000000000304CCCE05E0000000408274565CB
-:1002D000000000300000005E0000000408004564DB
-:1002E000000000040000E566000000080000005562
-:1002F00000000010008020610000000400202000A9
-:1003000000000004001B00FF00000010010000645A
-:1003100000000004001F200000000004001C00FF7B
-:100320000000000C00000000000000300000008011
-:100330000000000800000055000000040000E57601
-:1003400000000004000CA0000000000400012000D8
-:100350000000000400082000000000041800650EE2
-:10036000000000040009200000000004000A200032
-:1003700000000004000F0000000000040040000026
-:100380000000001800000074000000040000E56395
-:10039000000000C200C0E5F900000008000000698C
-:1003A000000000080000A069000000040000E576DD
-:1003B000000000040000E577000000040000E50EE6
-:1003C000000000040000E50F000000040140A00050
-:1003D0000000001800000077000000C200C0E5F92E
-:1003E0000000000800000077000000040014E50E83
-:1003F000000000040040E50F0000000800C0007A83
-:10040000000000040000E570000000040000E57139
-:100410000000000C0000E572000000040000A000D5
-:10042000000000040140A000000000040000E56896
-:1004300000000004000C20000000001800000084F0
-:1004400000000004000B00000000000418C0E5627A
-:1004500000000008000000860000000800C00085C1
-:1004600000000004000700E30000003800000092D4
-:1004700000000030000CA09400000004080045BB00
-:1004800000000030000C2095000000000800E5BCD2
-:10049000000000040000E5BB000000000000E5BC17
-:1004A0000000000C00120000000000040012000018
-:1004B0000000000C001B0002000000040000A0006F
-:1004C000000000040000E821000000000000E80037
-:1004D000000000040000E821000000000000E82EF9
-:1004E0000000000402CCA000000000040014000082
-:1004F00000000004000CE1CC00000004050DE1CD7B
-:10050000000000040040000000000018000000A4EB
-:100510000000000400C0A00000000008000000A1CE
-:1005200000000020000000A6000000004200E000E3
-:1005300000000038000000AD00000004000CA00026
-:10054000000000040014000000000004000C200063
-:10055000000000040016000000000004700CE00021
-:1005600000000008001400A9000000004000E000A6
-:10057000000000040240000000000004400EE00003
-:100580000000000402400000000000004000E00005
-:1005900000000004000C2000000000040240E51BE5
-:1005A000000000050080E50A000000050080E50B62
-:1005B000000000040022000000000004000700E327
-:1005C00000000038000000C000000030000C209542
-:1005D000000000050880E5BD00000030000C2094FC
-:1005E000000000050800E5BB00000030000C20956D
-:1005F000000000050880E5BC00000008000000C302
-:10060000000000050080E5BD000000050000E5BB1E
-:10061000000000050080E5BC00000004002100008F
-:1006200000000004028000000000001800C000C7A5
-:10063000000000404180E00000000024000000C9EC
-:100640000000000C010000000000000C0100E51D8E
-:1006500000000004000045BB00000008000080C34B
-:10066000000000040000F3CE000000040140A000E0
-:100670000000000400CC20000000004008C053CF60
-:100680000000000000008000000000040000F3D221
-:10069000000000040140A0000000000400CC200085
-:1006A0000000004008C053D300000000000080009C
-:1006B000000000040000F39D000000040140A000C1
-:1006C0000000000400CC20000000004008C0539E41
-:1006D00000000000000080000000000403C008309B
-:1006E000000000004200E000000000040000A00044
-:1006F00000000004200045E0000000000000E5E1EB
-:10070000000000000000000100000004000700E0FD
-:10071000000000000800E39400000000000000005A
-:10072000000000040000E8C4000000040000E8C568
-:10073000000000040000E8C6000000040000E928F2
-:10074000000000040000E929000000040000E92A7C
-:1007500000000008000000E4000000040000E92898
-:10076000000000040000E929000000040000E92A5C
-:1007700000000008000000EB0000000402C02000A0
-:10078000000000040006000000000034000000F338
-:1007900000000008000000F00000000400008000DD
-:1007A00000000000C000E0000000000000000000A9
-:1007B00000000004000C200000000004001D0018D0
-:1007C00000000004001A000100000034000000FBDB
-:1007D000000000080000004A000000080500A04AD0
-:1007E0000000000000000000000000000000000009
-:1007F00000000000000000000000000000000000F9
-:00000001FF
-/* production radeon ucode r1xx-r6xx */
--- zfcpdump-kernel-4.4.orig/firmware/radeon/R420_cp.bin.ihex
+++ /dev/null
@@ -1,130 +0,0 @@
-:10000000000000004200E000000000004000E000AE
-:100010000000000800000099000000080000009D9A
-:10002000000000004A554B4A000000004A4A44675D
-:100030000000000055526F75000000004A7E7D658B
-:1000400000000000D9D3DFF6000000004AC54A4A8C
-:1000500000000000C882828200000000BF4ACFC1B9
-:100060000000000087B04A4A00000000B583838387
-:10007000000000004A0F85BA00000004000CA00038
-:1000800000000038000D0012000000040000E8B479
-:1000900000000038000D0014000000040000E8B665
-:1000A00000000038000D0016000000040000E854B5
-:1000B00000000038000D0018000000040000E855A2
-:1000C00000000038000D001A000000040000E8568F
-:1000D00000000038000D001C000000040000E8577C
-:1000E00000000038000D001E000000040000E8249D
-:1000F00000000038000D0020000000040000E8258A
-:1001000000000038000D0022000000040000E8306C
-:1001100000000038000D0024000000040000F0C0C2
-:1001200000000038000D0026000000040000F0C1AF
-:1001300000000038000D0028000000040000F0411D
-:1001400000000038000D002A000000040000F184C7
-:1001500000000038000D002C000000040000F185B4
-:1001600000000038000D002E000000040000F186A1
-:1001700000000038000D0030000000040000F1878E
-:1001800000000038000D0032000000040000F18083
-:1001900000000038000D0034000000040000F3935C
-:1001A00000000038000D0036000000040000F38A53
-:1001B00000000038000D0038000000040000F38E3D
-:1001C000000000040000E821000000040140A0003D
-:1001D00000000018000000430000000400CCE8000C
-:1001E00000000004001B000100000004080048009B
-:1001F00000000004001B000100000004080048008B
-:1002000000000004001B000100000004080048007A
-:10021000000000080000003A000000000000A000FC
-:10022000000000042000451D000000040000E580DF
-:1002300000000004000CE581000000040800458077
-:1002400000000004000CE5810000000800000047E9
-:10025000000000000000A00000000004000C2000CE
-:10026000000000040000E50E000000040003200070
-:10027000000000280002205100000024000000516E
-:10028000000000040800450F000000080000A04B1B
-:10029000000000040000E565000000040000E566C1
-:1002A00000000008000000520000000403CCA5B4C8
-:1002B00000000004054320000000000400022000AC
-:1002C000000000304CCCE05E0000000408274565CB
-:1002D000000000300000005E0000000408004564DB
-:1002E000000000040000E566000000080000005562
-:1002F00000000010008020610000000400202000A9
-:1003000000000004001B00FF00000010010000645A
-:1003100000000004001F200000000004001C00FF7B
-:100320000000000C0000000000000030000000721F
-:100330000000000800000055000000040000E57601
-:10034000000000040000E577000000040000E50E56
-:10035000000000040000E50F000000040140A000C0
-:100360000000001800000069000000C200C0E5F9AC
-:100370000000000800000069000000040014E50E01
-:10038000000000040040E50F0000000800C0006C01
-:10039000000000040000E570000000040000E571AA
-:1003A0000000000C0000E572000000040000A00046
-:1003B000000000040140A000000000040000E56807
-:1003C00000000004000C200000000018000000766F
-:1003D00000000004000B00000000000418C0E562EB
-:1003E00000000008000000780000000800C000774E
-:1003F00000000004000700C7000000380000008073
-:10040000000000040000E5BB000000000000E5BCA7
-:10041000000000040000A000000000040000E8212B
-:10042000000000000000E800000000040000E821D7
-:10043000000000000000E82E0000000402CCA00034
-:10044000000000040014000000000004000CE1CCD7
-:1004500000000004050DE1CD000000040040000094
-:10046000000000180000008F0000000400C0A00081
-:10047000000000080000008C000000200000009137
-:10048000000000004200E00000000038000000987A
-:1004900000000004000CA000000000040014000094
-:1004A00000000004000C2000000000040016000002
-:1004B00000000004700CE00000000008001400942C
-:1004C000000000004000E0000000000402400000C6
-:1004D00000000004400EE0000000000402400000A4
-:1004E000000000004000E00000000004000C2000BC
-:1004F000000000040240E51B000000050080E50A42
-:10050000000000050080E50B000000040022000050
-:1005100000000004000700C700000038000000A42D
-:10052000000000050080E5BD000000050000E5BBFF
-:10053000000000050080E5BC000000040021000070
-:1005400000000004028000000000001800C000ABA2
-:10055000000000404180E00000000024000000ADE9
-:100560000000000C010000000000000C0100E51D6F
-:1005700000000004000045BB00000008000080A748
-:10058000000000040000F3CE000000040140A000C1
-:100590000000000400CC20000000004008C053CF41
-:1005A0000000000000008000000000040000F3D202
-:1005B000000000040140A0000000000400CC200066
-:1005C0000000004008C053D300000000000080007D
-:1005D000000000040000F39D000000040140A000A2
-:1005E0000000000400CC20000000004008C0539E22
-:1005F00000000000000080000000000403C008307C
-:10060000000000004200E000000000040000A00024
-:1006100000000004200045E0000000000000E5E1CB
-:10062000000000000000000100000004000700C4FA
-:10063000000000000800E39400000000000000003B
-:10064000000000040000E8C4000000040000E8C549
-:10065000000000040000E8C6000000040000E928D3
-:10066000000000040000E929000000040000E92A5D
-:1006700000000008000000C8000000040000E92895
-:10068000000000040000E929000000040000E92A3D
-:1006900000000008000000CF0000000402C020009D
-:1006A000000000040006000000000034000000D735
-:1006B00000000008000000D40000000400008000DA
-:1006C00000000000C000E000000000040000E1CCD9
-:1006D000000000040500E1CD00000004000CA000B3
-:1006E00000000034000000DE00000008000000DA16
-:1006F000000000000000A000000000040019E1CC90
-:1007000000000004001B0001000000040500A00020
-:1007100000000004080041CD00000004000CA0000F
-:1007200000000034000000FB000000080000004A48
-:1007300000000000000000000000000000000000B9
-:1007400000000000000000000000000000000000A9
-:100750000000000000000000000000000000000099
-:100760000000000000000000000000000000000089
-:100770000000000000000000000000000000000079
-:100780000000000000000000000000000000000069
-:100790000000000000000000000000000000000059
-:1007A0000000000000000000000000000000000049
-:1007B00000000004000C200000000004001D0018D0
-:1007C00000000004001A000100000034000000FBDB
-:1007D000000000080000004A000000080500A04AD0
-:1007E0000000000000000000000000000000000009
-:1007F00000000000000000000000000000000000F9
-:00000001FF
-/* production radeon ucode r1xx-r6xx */
--- zfcpdump-kernel-4.4.orig/firmware/radeon/R520_cp.bin.ihex
+++ /dev/null
@@ -1,130 +0,0 @@
-:10000000000000004200E000000000004000E000AE
-:100010000000000800000099000000080000009D9A
-:10002000000000004A554B4A000000004A4A44675D
-:100030000000000055526F75000000004A7E7D658B
-:1000400000000000E0DAE6F6000000004AC54A4A77
-:1000500000000000C882828200000000BF4ACFC1B9
-:100060000000000087B04AD500000000B5838383FC
-:10007000000000004A0F85BA00000004000CA00038
-:1000800000000038000D0012000000040000E8B479
-:1000900000000038000D0014000000040000E8B665
-:1000A00000000038000D0016000000040000E854B5
-:1000B00000000038000D0018000000040000E855A2
-:1000C00000000038000D001A000000040000E8568F
-:1000D00000000038000D001C000000040000E8577C
-:1000E00000000038000D001E000000040000E8249D
-:1000F00000000038000D0020000000040000E8258A
-:1001000000000038000D0022000000040000E8306C
-:1001100000000038000D0024000000040000F0C0C2
-:1001200000000038000D0026000000040000F0C1AF
-:1001300000000038000D0028000000040000E0006E
-:1001400000000038000D002A000000040000E0005C
-:1001500000000038000D002C000000040000E0004A
-:1001600000000038000D002E000000040000E00038
-:1001700000000038000D0030000000040000E00026
-:1001800000000038000D0032000000040000F18083
-:1001900000000038000D0034000000040000F3935C
-:1001A00000000038000D0036000000040000F38A53
-:1001B00000000038000D0038000000040000F38E3D
-:1001C000000000040000E821000000040140A0003D
-:1001D00000000018000000430000000400CCE8000C
-:1001E00000000004001B000100000004080048009B
-:1001F00000000004001B000100000004080048008B
-:1002000000000004001B000100000004080048007A
-:10021000000000080000003A000000000000A000FC
-:10022000000000042000451D000000040000E580DF
-:1002300000000004000CE581000000040800458077
-:1002400000000004000CE5810000000800000047E9
-:10025000000000000000A00000000004000C2000CE
-:10026000000000040000E50E000000040003200070
-:10027000000000280002205100000024000000516E
-:10028000000000040800450F000000080000A04B1B
-:10029000000000040000E565000000040000E566C1
-:1002A00000000008000000520000000403CCA5B4C8
-:1002B00000000004054320000000000400022000AC
-:1002C000000000304CCCE05E0000000408274565CB
-:1002D000000000300000005E0000000408004564DB
-:1002E000000000040000E566000000080000005562
-:1002F00000000010008020610000000400202000A9
-:1003000000000004001B00FF00000010010000645A
-:1003100000000004001F200000000004001C00FF7B
-:100320000000000C0000000000000030000000721F
-:100330000000000800000055000000040000E57601
-:10034000000000040000E577000000040000E50E56
-:10035000000000040000E50F000000040140A000C0
-:100360000000001800000069000000C200C0E5F9AC
-:100370000000000800000069000000040014E50E01
-:10038000000000040040E50F0000000800C0006C01
-:10039000000000040000E570000000040000E571AA
-:1003A0000000000C0000E572000000040000A00046
-:1003B000000000040140A000000000040000E56807
-:1003C00000000004000C200000000018000000766F
-:1003D00000000004000B00000000000418C0E562EB
-:1003E00000000008000000780000000800C000774E
-:1003F00000000004000700C7000000380000008073
-:10040000000000040000E5BB000000000000E5BCA7
-:10041000000000040000A000000000040000E8212B
-:10042000000000000000E800000000040000E821D7
-:10043000000000000000E82E0000000402CCA00034
-:10044000000000040014000000000004000CE1CCD7
-:1004500000000004050DE1CD000000040040000094
-:10046000000000180000008F0000000400C0A00081
-:10047000000000080000008C000000200000009137
-:10048000000000004200E00000000038000000987A
-:1004900000000004000CA000000000040014000094
-:1004A00000000004000C2000000000040016000002
-:1004B00000000004700CE00000000008001400942C
-:1004C000000000004000E0000000000402400000C6
-:1004D00000000004400EE0000000000402400000A4
-:1004E000000000004000E00000000004000C2000BC
-:1004F000000000040240E51B000000050080E50A42
-:10050000000000050080E50B000000040022000050
-:1005100000000004000700C700000038000000A42D
-:10052000000000050080E5BD000000050000E5BBFF
-:10053000000000050080E5BC000000040021000070
-:1005400000000004028000000000001800C000ABA2
-:10055000000000404180E00000000024000000ADE9
-:100560000000000C010000000000000C0100E51D6F
-:1005700000000004000045BB00000008000080A748
-:10058000000000040000F3CE000000040140A000C1
-:100590000000000400CC20000000004008C053CF41
-:1005A0000000000000008000000000040000F3D202
-:1005B000000000040140A0000000000400CC200066
-:1005C0000000004008C053D300000000000080007D
-:1005D000000000040000F39D000000040140A000A2
-:1005E0000000000400CC20000000004008C0539E22
-:1005F00000000000000080000000000403C008307C
-:10060000000000004200E000000000040000A00024
-:1006100000000004200045E0000000000000E5E1CB
-:10062000000000000000000100000004000700C4FA
-:10063000000000000800E39400000000000000003B
-:10064000000000040000E8C4000000040000E8C549
-:10065000000000040000E8C6000000040000E928D3
-:10066000000000040000E929000000040000E92A5D
-:1006700000000008000000C8000000040000E92895
-:10068000000000040000E929000000040000E92A3D
-:1006900000000008000000CF00000000DEADBEEF4B
-:1006A000000000000000011600000004000700D355
-:1006B00000000004080050E700000004000700D418
-:1006C000000000040800401C000000000000E01DC5
-:1006D0000000000402C0200000000004000600002A
-:1006E00000000034000000DE00000008000000DB15
-:1006F000000000040000800000000000C000E000D6
-:10070000000000040000E1CC000000040500E1CD81
-:1007100000000004000CA00000000034000000E510
-:1007200000000008000000E1000000000000A00040
-:10073000000000040019E1CC00000004001B0001CF
-:10074000000000040500A00000000004080041CDE6
-:1007500000000004000CA00000000034000000FBBA
-:10076000000000080000004A000000000000000037
-:100770000000000000000000000000000000000079
-:100780000000000000000000000000000000000069
-:100790000000000000000000000000000000000059
-:1007A0000000000000000000000000000000000049
-:1007B00000000004000C200000000004001D0018D0
-:1007C00000000004001A000100000034000000FBDB
-:1007D000000000080000004A000000080500A04AD0
-:1007E0000000000000000000000000000000000009
-:1007F00000000000000000000000000000000000F9
-:00000001FF
-/* production radeon ucode r1xx-r6xx */
--- zfcpdump-kernel-4.4.orig/firmware/radeon/R600_me.bin.ihex
+++ /dev/null
@@ -1,1345 +0,0 @@
-:1000000000000000C020040000000000000000000C
-:1000100000A0000A000000000000FFFF00284621A9
-:100020000000000000000000D900480000000000AF
-:1000300000000000C02004000000000000000000DC
-:1000400000A0000A000000000000000000E0000026
-:100050000000000000010000C02946200000000050
-:1000600000000000D900480000000000000000006F
-:10007000C0200400000000000000000000A0000AF2
-:10008000000000008100000000204411000000007A
-:1000900000000001002048110000000000042004BE
-:1000A0000060441100000614000000000060000021
-:1000B000000005B20000000000600000000005C55F
-:1000C00000000000C02008000000000000000F0039
-:1000D000002816220000000000000008002116255C
-:1000E0000000000000000020002036250000000075
-:1000F0008D000000002044110000000000000004FA
-:10010000002F022500000000000000000CE00000AD
-:1001100000000018004120000040481100000019B4
-:100120000042200000204811000000008E00000066
-:1001300000204411000000000000003100204A2D82
-:1001400000000000900000000020441100000000AA
-:100150000000000000204805000000000000000C26
-:1001600000211622000000000000000300281625D0
-:10017000000000000000001900211A220000000009
-:100180000000000400281A26000000000000000003
-:10019000002914C5000000000000002100203625C1
-:1001A0000000000000000000003A140200000000FF
-:1001B00000000016002116250000000000000003CA
-:1001C00000281625000000000000001D00200E2D54
-:1001D00000000000FFFFFFFC00280E2300000000CD
-:1001E00000000000002914A3000000000000001D12
-:1001F00000203625000000000000800000280E22AC
-:10020000000000000000000700220E230000000094
-:10021000000000000029386E0000000020000000EF
-:1002200000280E22000000000000000600210E231E
-:1002300000000000000000000029386E00000000EF
-:100240000000000000220222000000000000000068
-:1002500014E0000000000038000000002EE0000064
-:1002600000000035000000002CE000000000003716
-:100270000000000000400E2D0000003900000008C2
-:1002800000200E2D00000000000000090040122D8B
-:10029000000000460000000100400E2D0000003963
-:1002A00000000000C0200C0000000000003FFFFC28
-:1002B0000028122300000000000000020022122487
-:1002C000000000000000001F00211E2300000000AD
-:1002D0000000000014E000000000003E00000008E4
-:1002E00000401C11000000410000000D00201E2DE8
-:1002F000000000000000000F00281E270000000082
-:100300000000000300221E27000000007FC0000044
-:1003100000281A23000000000000001400211A2603
-:10032000000000000000000100331A260000000059
-:100330000000000800221A26000000000000000053
-:1003400000290CC700000000000000300020362407
-:100350000000000000007F000028122100000000C3
-:1003600000001400002F0224000000000000000024
-:100370000CE000000000004B0000000100290E23EB
-:1003800000000000000000100020362300000000E4
-:100390000000E0000020441100000000FFF8000011
-:1003A00000294A230000000000000000003A2C024F
-:1003B000000000000000000200220E2B00000000E0
-:1003C000FC00000000280E230000000000000011C7
-:1003D000002036230000000000001FFF00294A23F0
-:1003E000000000000000003000204A2D0000000046
-:1003F0000000000000204811000000000000003252
-:1004000000200E2D00000000060A020000294A23E9
-:100410000000000000000000002048110000000063
-:100420000000000000204811000000000000000152
-:1004300000210222000000000000000014E0000083
-:1004400000000061000000002EE000000000005FDE
-:10045000000000002CE000000000005E0000000032
-:1004600000400E2D000000620000000100400E2D33
-:10047000000000620000000A00200E2D00000000B5
-:100480000000000B0040122D0000006A0000000078
-:10049000C0200C0000000000003FFFFC00281223D9
-:1004A00000000000000000020022122400000000F2
-:1004B0007FC0000000281623000000000000001488
-:1004C0000021162500000000000000010033162561
-:1004D000000000008000000000280E230000000043
-:1004E0000000000000290CA3000000003FFFFC00FA
-:1004F00000290E23000000000000001F00211E2321
-:10050000000000000000000014E000000000006D8A
-:100510000000010000401C11000000700000000DF0
-:1005200000201E2D00000000000000F000281E2703
-:10053000000000000000000400221E270000000050
-:100540008100000000204411000000000000000DA8
-:100550000020481100000000FFFFF0FF00281A30C3
-:10056000000000000000A02800204411000000004E
-:1005700000000000002948E6000000000000A0186C
-:1005800000204411000000003FFFFFFF00284A2325
-:10059000000000000000A010002044110000000036
-:1005A0000000000000204804000000000000002DB2
-:1005B0000020162D0000000000000000002F00A306
-:1005C00000000000000000000CC0000000000080DF
-:1005D0000000002E0020162D00000000000000008A
-:1005E000002F00A400000000000000000CC000006C
-:1005F00000000081000000000040000000000087B3
-:100600000000002D00203623000000000000002E16
-:1006100000203624000000000000001D00201E2DD8
-:10062000000000000000000200210227000000007E
-:100630000000000014E0000000000087000000003F
-:1006400000600000000005ED0000000000600000F8
-:10065000000005E10000000200210E220000000061
-:100660000000000014C000000000008A0000001814
-:10067000C040362000000090000000002EE0000086
-:100680000000008E000000002CE000000000008D43
-:100690000000000200400E2D0000008F000000034B
-:1006A00000400E2D0000008F0000000C00200E2DD9
-:1006B00000000000000000180020362300000000A9
-:1006C0000000000300210E220000000000000000D6
-:1006D00014C00000000000950000A00C0020441190
-:1006E0000000000000000000C020480000000000E2
-:1006F00000000000C04048000000009D0000A00C69
-:1007000000204411000000000000000000204811FB
-:1007100000000000000000002EE000000000009B30
-:10072000000000002CE000000000009A0000000221
-:1007300000400E2D0000009C0000000300400E2D24
-:100740000000009C0000000C00200E2D00000000A6
-:10075000000000000020480300000000000000002E
-:10076000003A0C0200000000003F000000280E23A9
-:10077000000000000000001000210E230000000017
-:100780000000001300203623000000000000001EBF
-:100790000021022B000000000000000014C0000037
-:1007A000000000A40000001CC02036200000000053
-:1007B0000000001F0021022B0000000000000000CC
-:1007C00014C00000000000A70000001BC02036205D
-:1007D000000000000000000800210E2B00000000B7
-:1007E0000000007F00280E23000000000000000031
-:1007F000002F022300000000000000000CE00000B9
-:10080000000000DB000000002700000000000000E6
-:1008100000000000006000000000028C8100000069
-:1008200000204411000000000000000600204811D4
-:10083000000000000000000C00221E30000000003C
-:100840009980000000204411000000000000000416
-:100850000020122D000000000000000800221224D9
-:10086000000000000000001000201811000000002F
-:100870000000000000291CE400000000000000004F
-:1008800000604807000001289B0000000020441180
-:1008900000000000000000000020480200000000EE
-:1008A0009C00000000204411000000000000000037
-:1008B0000033146F000000000000000100333E23ED
-:1008C0000000000000000000D90048000000000007
-:1008D0000000000000203C05000000008100000036
-:1008E00000204411000000000000000E002048110C
-:1008F00000000000000000000020101000000000B8
-:100900000000E00700204411000000000000000F7C
-:100910000021022B000000000000000014C00000B5
-:10092000000000C500F8FF0800204811000000008A
-:100930009800000000404811000000D6000000F0C0
-:1009400000280E2200000000000000A0002F02235B
-:1009500000000000000000000CC00000000000D4F7
-:100960000000001300200E2D000000000000000118
-:10097000002F022300000000000000000CE0000037
-:10098000000000CF00000002002F02230000000042
-:10099000000000000CE00000000000CE00003F005E
-:1009A00000400C11000000D000001F0000400C119E
-:1009B000000000D000000F0000200C11000000001B
-:1009C0000038000900294A23000000003F00000011
-:1009D00000280E2B000000000000000200220E2361
-:1009E000000000000000000700494A23000000D674
-:1009F00000380F09002048110000000068000007BF
-:100A000000204811000000000000000800214A27D3
-:100A1000000000000000000000204811000000005D
-:100A2000060A020000294A2400000000000000001D
-:100A300000204811000000000000000000204811C4
-:100A4000000000000000A20200204411000000008D
-:100A500000FF000000284A220000000000000030D3
-:100A600000200E2D000000000000002E0020122D9E
-:100A70000000000000000000002F008300000000C4
-:100A8000000000000CE00000000000E30000000097
-:100A900000600000000005E70000000000400000CA
-:100AA000000000E40000000000600000000005EA13
-:100AB000000000070020222D0000000000000005BB
-:100AC00000220E22000000000010000000280E236B
-:100AD0000000000000000000002920680000000065
-:100AE00000000000003A0C0200000000000000EFCF
-:100AF00000280E23000000000000000000292068EC
-:100B0000000000000000001D00200E2D000000006D
-:100B1000000000030021022300000000000000008C
-:100B200014E00000000000F10000000B002102288A
-:100B3000000000000000000014C00000000000F1F0
-:100B40000000040000292228000000000000001A14
-:100B500000203628000000000000001C00210E22AA
-:100B6000000000000000000014C00000000000F6BB
-:100B70000000A30C00204411000000000000000051
-:100B800000204811000000000000001E00210E227D
-:100B9000000000000000000014C00000000001047C
-:100BA0000000A30F0020441100000000000000130B
-:100BB00000200E2D0000000000000001002F022385
-:100BC00000000000000000000CC00000000000FD5C
-:100BD000FFFFFFFF00404811000001040000000279
-:100BE000002F022300000000000000000CC00000E5
-:100BF000000001000000FFFF004048110000010458
-:100C000000000004002F022300000000000000008C
-:100C10000CC0000000000103000000FF004048116C
-:100C20000000010400000001002048110000000045
-:100C30000002C40000204411000000000000001F5A
-:100C400000210E22000000000000000014C000007F
-:100C50000000010B0000001040210E2000000000E9
-:100C600000000019002036230000000000000018DA
-:100C700040224A200000000000000010C0424A202C
-:100C80000000010D0000000000200C110000000019
-:100C900000000019002036230000000000000000C2
-:100CA0000020481100000000000000000020481152
-:100CB000000000000000000A0020101100000000E9
-:100CC00000000000002F02240000000000000000CF
-:100CD0000CE000000000011400000000002048119A
-:100CE0000000000000000001005312240000011069
-:100CF000FFBFFFFF00283A2E000000000000001B8D
-:100D000000210222000000000000000014C00000CA
-:100D100000000127810000000020441100000000B5
-:100D20000000000D00204811000000000000001825
-:100D300000220E3000000000FC00000000280E23FE
-:100D400000000000810000000020441100000000AD
-:100D50000000000E0020481100000000000000000C
-:100D600000201010000000000000E00E00204411E0
-:100D70000000000007F8FF080020481100000000F4
-:100D80000000000000294A230000000000000024A9
-:100D900000201E2D000000000000000800214A274E
-:100DA00000000000000000000020481100000000CA
-:100DB000060A020000294A2400000000000000008A
-:100DC0000020481100000000000000000020481131
-:100DD0000000000000000000008000000000000093
-:100DE000810000000020441100000000000000010C
-:100DF00000204811000000000000217C0020441168
-:100E000000000000008000000020481100000000E9
-:100E1000000000000020480600000000000000085C
-:100E200000214A2700000000000000001700000019
-:100E3000000000000004217F00604411000006143F
-:100E40000000001F00210230000000000000000030
-:100E500014C00000000006130000000400404C1104
-:100E60000000012E00000000006000000000000BE8
-:100E70000000000000600411000002FE00000000FD
-:100E800000200411000000000000000000600811B4
-:100E90000000019F00000000006000000000015100
-:100EA0000000FFFF40280E2000000000000000109E
-:100EB000C0211220000000000000FFFF4028062093
-:100EC0000000000000000010C0210A200000000007
-:100ED0000000000000341461000000000000000069
-:100EE00000741882000002A40001A1FD00604411FA
-:100EF000000002C900003FFF002F022F0000000089
-:100F0000000000000CC000000000013800000000DC
-:100F1000C04004000000000100000000006000006C
-:100F20000000000B0000000000600411000002FE41
-:100F3000000000000020041100000000000000007C
-:100F4000006008110000019F00003FFF002F022FEA
-:100F500000000000000000000CE0000000000000A5
-:100F600000000000006000000000015100000010BF
-:100F700040210E20000000000000FFFFC0281220CA
-:100F800000000000000000104021162000000000BA
-:100F90000000FFFFC0681A20000002A40001A1FDAC
-:100FA00000604411000002C900003FFF002F022F23
-:100FB00000000000000000000CC00000000001491B
-:100FC00000000000C0400400000000010000225C9E
-:100FD00000204411000000000000000100300A2F32
-:100FE000000000000000000100210A2200000000B3
-:100FF0000000000300384A220000000000002256D2
-:1010000000204411000000000000001A00204811D8
-:10101000000000000000A1FC0020441100000000BE
-:1010200000000001008048110000000000000000E6
-:10103000006000000000000B0000000000600000E5
-:101040000000017C00000000006000000000018D35
-:1010500000003FFF002F022F0000000000000000F2
-:101060000CE00000000000000000000000202C0840
-:10107000000000000000000000202411000000001B
-:10108000000000000020281100000000000022568F
-:10109000002044110000000000000016002048114C
-:1010A000000000000000225C00204411000000004D
-:1010B00000000003002048110000000093800000A1
-:1010C00000204411000000000000000200221E2940
-:1010D0000000000000000000007048EB00000189E3
-:1010E0000000000000600000000002A400000001F9
-:1010F000403306200000000000000000C03024093A
-:101100000000000000003FFF002F022F0000000041
-:10111000000000000CE000000000000000000000E3
-:10112000006000000000028C9500000000204411C7
-:101130000000000000000000002F0221000000005D
-:10114000000000000CE0000000000173000000003F
-:10115000C0204800000000000000000100530621EC
-:101160000000016F92000000002044110000000008
-:1011700000000000C0604800000001840001A1FDE3
-:101180000020441100000000000000130020062D84
-:1011900000000000000000000078042A000002E4C3
-:1011A00000000000002028090000000000003FFFB0
-:1011B000002F022F00000000000000000CC0000003
-:1011C0000000016500000000C040040000000001B4
-:1011D0000000021000600411000002FE00003FFF4A
-:1011E000002F022F00000000000000000CE00000B3
-:1011F000000001810000001BC0203620000000001C
-:101200000000001CC0203620000000003F800000CD
-:1012100000200411000000004600000000600811DA
-:101220000000019F0000000000800000000000009E
-:101230000000A1FC002044110000000000003FFF5E
-:10124000002F022F00000000000000000CC0000072
-:10125000000001880000000100804811000000002B
-:101260000000002100804811000000000000FFFF86
-:1012700040280E200000000000000010C0211220B5
-:10128000000000000000FFFF4028162000000000C2
-:1012900000000010C0811A20000000008100000042
-:1012A000002044110000000000000006002048114A
-:1012B000000000000000000800221E3000000000B6
-:1012C0000000003200201A2D000000000000E000A5
-:1012D0000020441100000000FFFBFF09002048111E
-:1012E00000000000000000110020222D000000007E
-:1012F00000001FFF00294A2800000000000000062F
-:101300000020222D0000000000000000002920E83D
-:10131000000000000000000000204808000000005D
-:10132000000000000020481100000000060A020032
-:1013300000294A260000000000000000002048119B
-:101340000000000000000000002048110000000024
-:10135000000001000020181100000000000000083B
-:1013600000621E28000001280000000800822228D8
-:10137000000000000002C000002044110000000036
-:101380000000001B00600E2D000001AA0000001CE0
-:1013900000600E2D000001AA0000C00800204411CA
-:1013A000000000000000001D00200E2D00000000C5
-:1013B0000000000014C00000000001A600000000B2
-:1013C000002004110000000000000000002048017F
-:1013D000000000003900000000204811000000005B
-:1013E0000000000000204811000000000000000084
-:1013F00000804802000000000000002000202E2D88
-:101400000000000000000000003B0D630000000031
-:101410000000000800224A23000000000000001025
-:1014200000224A23000000000000001800224A2386
-:1014300000000000000000000080480300000000E1
-:1014400000000000006000000000000B0000100021
-:1014500000600411000002FE0000000000200411E2
-:101460000000000000000000006008110000019F63
-:10147000000000070021062F0000000000000019F6
-:1014800000200A2D000000000000000100202C11A7
-:10149000000000000000FFFF4028222000000000A4
-:1014A0000000000F002622280000000000000010AD
-:1014B00040212620000000000000000F0026262901
-:1014C00000000000000000000020280200000000D2
-:1014D0000000225600204411000000000000001B04
-:1014E000002048110000000000000000002F022131
-:1014F00000000000000000000CE00000000001CD32
-:101500000000225C00204411000000000000008167
-:1015100000204811000000000000A1FC0020441140
-:101520000000000000000001002048110000000041
-:101530000000008000201C110000000000000000DE
-:10154000002F022700000000000000000CE0000057
-:10155000000001C90000000000600000000001D68A
-:101560000000000100531E27000001C5000000011B
-:1015700000202C11000000000000001F00280A229B
-:10158000000000000000001F00282A2A00000000C0
-:101590000000000100530621000001BE0000225C93
-:1015A00000204411000000000000000200304A2F1B
-:1015B000000000000000A1FC002044110000000019
-:1015C00000000001002048110000000000000001A0
-:1015D00000301E2F0000000000000000002F022736
-:1015E00000000000000000000CE00000000000000F
-:1015F0000000000000600000000001D600000001B3
-:1016000000531E27000001D20000FFFF40280E20DB
-:10161000000000000000000F00260E230000000064
-:1016200000000010C0211220000000000000000F88
-:101630000026122400000000000000000020141109
-:10164000000000000000000000601811000002A46B
-:101650000001A1FD00204411000000000000000076
-:10166000002F022B00000000000000000CE0000032
-:10167000000001E500000010002216280000000014
-:10168000FFFF000000281625000000000000FFFFFB
-:1016900000281A290000000000000000002948C5A9
-:1016A00000000000000000000020480A00000000C8
-:1016B0000000000000202C110000000000000010BD
-:1016C0000022162300000000FFFF0000002816255E
-:1016D000000000000000FFFF00281A2400000000A6
-:1016E00000000000002948C50000000000000000C4
-:1016F00000731503000001F200000000002018052F
-:10170000000000000000000000731524000001F23A
-:1017100000000000002D14C50000000000000000C3
-:10172000003008A200000000000000000020480275
-:10173000000000000000000000202802000000005F
-:101740000000000000202003000000000000000056
-:1017500000802404000000000000000F002102258A
-:10176000000000000000000014C00000000006138C
-:1017700000000000002B1405000000000000000124
-:10178000009016250000000000000000006000002E
-:101790000000000B0000000000600411000002FEC9
-:1017A0000000000000200411000000000000000004
-:1017B000006008110000019F000022560020441123
-:1017C000000000000000001A00294A22000000006A
-:1017D00000000000C02000000000000000003FFFEB
-:1017E000002F022F00000000000000000CE00000AD
-:1017F0000000000000000000C02004000000000005
-:101800000000225C002044110000000000000003E2
-:1018100000384A21000000000000A1FC0020441113
-:10182000000000000000000100204811000000003E
-:101830000000FFFF40281220000000000000001000
-:10184000C0211A20000000000000FFFF40280E20E9
-:101850000000000000000010C02116200000000061
-:101860000000000000741465000002A40001A1FD46
-:1018700000604411000002C900000001003306218D
-:101880000000000000000000002F02210000000006
-:10189000000000000CC000000000020600003FFF36
-:1018A000002F022F00000000000000000CC000000C
-:1018B000000001FF00000000C04004000000000123
-:1018C0000000000000600000000005C500000000EE
-:1018D0000040040F00000200000000000060000053
-:1018E000000005B20000000000600000000005C517
-:1018F0000000021000600411000002FE0000000061
-:10190000006000000000018D000000000060000089
-:10191000000001890000000000600000000002A437
-:1019200000000000006000000000028C93800000B6
-:1019300000204411000000000000000000204808C2
-:10194000000000009500000000204411000000008D
-:1019500000000000002F022F000000000000000027
-:101960000CE000000000021F00000000C040480022
-:101970000000021C92000000002044110000000042
-:1019800000000000C02048000000000000002256B7
-:101990000020441100000000000000160020481143
-:1019A000000000000000225C002044110000000044
-:1019B0000000000300204811000000000000A1FC0E
-:1019C0000020441100000000000000010020481128
-:1019D000000000000001A1FD0020441100000000F3
-:1019E0000000000000600411000002E4000000009C
-:1019F000C040040000000001000000000060000082
-:101A0000000005B20000A00C0020441100000000FE
-:101A100000000000C020480000000000000000009E
-:101A2000C04048000000000000000000006000000E
-:101A30000000000B0000001840210A2000000000F8
-:101A400000000003002F0222000000000000000040
-:101A50000AE00000000002350000001A0020222DDC
-:101A600000000000000801010029222800000000F9
-:101A70000000001A00203628000000000000A30C1F
-:101A8000002044110000000000000000C0204800B9
-:101A90000000000000000000C0204800000000001E
-:101AA00000000000C04048000000023A00000000B2
-:101AB000006000000000000B000000100060041136
-:101AC000000002FE3F800000002004110000000022
-:101AD00000000000006008110000019F0000225C6F
-:101AE0000020441100000000000000030020481105
-:101AF000000000000000000000600000000002651F
-:101B00000000001D00201E2D00000000000000014C
-:101B100000211E27000000000000000014E000006B
-:101B2000000002530000001800201E2D00000000DD
-:101B30000000FFFF00281E2700000000000000003A
-:101B400000341C27000000000000000012C000004C
-:101B5000000002480000000000201C1100000000EE
-:101B600000000000002F00E5000000000000000061
-:101B700008C000000000024B000000000020140715
-:101B8000000000000000001800201E2D00000000D2
-:101B90000000001000211E270000000000000000CF
-:101BA00000341C47000000000000000012C00000CC
-:101BB000000002500000000000201C110000000086
-:101BC00000000000002F00E6000000000000000000
-:101BD00008C00000000002530000000000201807A9
-:101BE000000000000000000000600000000002AAE9
-:101BF00000002256002044110000000000000000F8
-:101C000000342023000000000000000012C000008B
-:101C10000000025B000000000034204400000000CF
-:101C20000000000012C000000000025A0000001670
-:101C3000004048110000025F0000001800404811F9
-:101C40000000025F0000000000342044000000009B
-:101C50000000000012C000000000025E000000173B
-:101C6000004048110000025F0000001900204811E8
-:101C7000000000000000A1FC002044110000000052
-:101C80000000000100204811000000000001A1FD3B
-:101C900000604411000002D200003FFF002F022F1D
-:101CA00000000000000000000CC000000000023F27
-:101CB00000000000C040040000000001000000100F
-:101CC00040210620000000000000FFFFC0280A207D
-:101CD000000000000000001040210E200000000065
-:101CE0000000FFFFC02812200000000000000010CC
-:101CF00040211620000000000000FFFFC0881A20CD
-:101D000000000000810000000020441100000000DD
-:101D10000000000100204811000000000004200421
-:101D20000060441100000614000000000060000084
-:101D3000000005B200000000C06000000000028C3E
-:101D40000000000500200A2D00000000000000082F
-:101D500000220A22000000000000003400201A2D9A
-:101D6000000000000000002400201E2D00000000E4
-:101D70000000700000281E27000000000000000086
-:101D800000311CE6000000000000003300201A2D86
-:101D9000000000000000000C00221A2600000000D5
-:101DA00000000000002F00E600000000000000001E
-:101DB00006E000000000027B0000000000201C1173
-:101DC000000000000000000000200C1100000000D6
-:101DD0000000003400203623000000000000001046
-:101DE00000201811000000000000000000691CE243
-:101DF0000000012893800000002044110000000032
-:101E000000000000002048070000000095000000CE
-:101E1000002044110000000000000000002F022FED
-:101E200000000000000000000CE00000000002863E
-:101E30000000000100333E2F000000000000000001
-:101E4000D90048000000000092000000002044116A
-:101E50000000000000000000C0204800000000005A
-:101E60000000002400403627000000000000000CA5
-:101E7000C0220A20000000000000003200203622AC
-:101E80000000000000000031C040362000000000CB
-:101E90000000A2A40020441100000000000000097E
-:101EA0000020481100000000A100000000204411A3
-:101EB0000000000000000001008048110000000048
-:101EC0000000002900201E2D00000000000000007E
-:101ED000002C1CE300000000000000290020362731
-:101EE000000000000000002A00201E2D000000005D
-:101EF00000000000002C1CE4000000000000002A8C
-:101F000000203627000000000000002B00201E2DBE
-:101F10000000000000000000003120A300000000CD
-:101F200000000000002D1D07000000000000002B35
-:101F300000203627000000000000002C00201E2D8D
-:101F40000000000000000000003120C4000000007C
-:101F500000000000002D1D07000000000000002C04
-:101F600000803627000000000000002900203623F2
-:101F7000000000000000002A0020362400000000BD
-:101F80000000000000311CA3000000000000002B36
-:101F900000203627000000000000000000311CC4B3
-:101FA000000000000000002C008036270000000028
-:101FB000000000220020362700000000000000235F
-:101FC00000203628000000000000001D00201E2D0B
-:101FD00000000000000000020021022700000000B5
-:101FE0000000000014C00000000002C50000000056
-:101FF00000400000000002C200000022002036273E
-:10200000000000000000002300203628000000002F
-:102010000000001D00201E2D000000000000000236
-:1020200000210227000000000000000014E0000072
-:10203000000002C20000000300210227000000008F
-:102040000000000014E00000000002C50000002BAA
-:1020500000201E2D0000000000000000002E00E106
-:10206000000000000000000002C00000000002C5E7
-:102070000000002900201E2D0000000000000000CC
-:10208000003120A10000000000000000002E00E848
-:10209000000000000000000006C00000000002C5B3
-:1020A0000000002C00201E2D000000000000000099
-:1020B000002E00E2000000000000000002C000004E
-:1020C000000002C50000002A00201E2D00000000B4
-:1020D00000000000003120C20000000000000000ED
-:1020E000002E00E8000000000000000006C0000014
-:1020F000000002C50000000000600000000005EDC7
-:1021000000000000006000000000029E00000000CF
-:1021100000400000000002C7000000000060000056
-:102120000000029E0000000000600000000005E4C6
-:102130000000000000400000000002C70000000096
-:10214000006000000000029000000000004000005D
-:10215000000002C70000002200201E2D0000000029
-:10216000000000230080222D00000000000000106D
-:1021700000221E2300000000000000000029488704
-:10218000000000000000000000311CA3000000005F
-:102190000000001000221E270000000000000000C8
-:1021A00000294887000000000000001000221E23C4
-:1021B0000000000000000000003120C4000000000A
-:1021C0000000FFFF0028222800000000000000009F
-:1021D00000894907000000000000001000221E23B3
-:1021E00000000000000000000029488700000000F7
-:1021F0000000001000221E2100000000000000006E
-:1022000000294847000000000000000000311CA326
-:10221000000000000000001000221E270000000047
-:1022200000000000002948870000000000000000B6
-:1022300000311CA1000000000000001000221E2739
-:1022400000000000000000000029484700000000D6
-:102250000000001000221E2300000000000000000B
-:10226000003120C4000000000000FFFF00282228E9
-:1022700000000000000000000029490700000000E5
-:102280000000001000221E210000000000000000DD
-:10229000003120C2000000000000FFFF00282228BB
-:1022A0000000000000000000008949070000000055
-:1022B0000000001000221E230000000000000000AB
-:1022C00000294887000000000000000100220A21C8
-:1022D0000000000000000000003308A20000000021
-:1022E0000000001000221E2200000000000000106C
-:1022F0000021222200000000000000000029490700
-:10230000000000000000000000311CA300000000DD
-:102310000000001000221E27000000000000000046
-:1023200000294887000000000000000100220A2167
-:102330000000000000000000003008A200000000C3
-:102340000000001000221E2200000000000000100B
-:10235000002122220000000000000000002949079F
-:10236000000000000000001000221E2300000000FA
-:1023700000000000003120C4000000000000FFFF4A
-:102380000028222800000000000000000029490762
-:102390000000000000000000003808C50000000038
-:1023A00000000000003008410000000000000001B3
-:1023B00000220A220000000000000000003308A2F2
-:1023C000000000000000001000221E22000000009B
-:1023D0000000001000212222000000000000000088
-:1023E00000894907000000000000001D0020222D88
-:1023F000000000000000000014C000000000030105
-:10240000FFFFFFEF00280621000000000000001A77
-:102410000020222D000000000000F8E00020441100
-:102420000000000000000000002949010000000039
-:1024300000000000008949010000000000000000C9
-:10244000002048110000000000000000002048119A
-:1024500000000000060A0200008048110000000091
-:1024600000000000C02000000000000097000000F5
-:10247000C02044110000000000000000C0204811EE
-:10248000000000008A00000000204411000000004D
-:102490000000000000204811000000000000225C45
-:1024A000002044110000000000000000C02048008F
-:1024B000000000000000A1FC00204411000000000A
-:1024C00000000000C02048000000000000000000E4
-:1024D000C0200400000000000000000000A0000A6E
-:1024E00000000000970000000020441100000000E0
-:1024F0000000000000204811000000008A000000D9
-:1025000000204411000000000000000000204811DD
-:10251000000000000000225C0020441100000000C8
-:1025200000000000C0204800000000000000A1FCE6
-:10253000002044110000000000000000C0204800FE
-:102540000000000000000000C020040000000000A7
-:102550000000000000A0000A00000000970000003A
-:10256000002044110000000000000000002048117D
-:10257000000000008A00000000204411000000005C
-:102580000000000000204811000000000000225C54
-:10259000002044110000000000000000C02048009E
-:1025A000000000000000A1FC002044110000000019
-:1025B00000000000C0204800000000000001A1FD54
-:1025C000002044110000000000000000D900480075
-:1025D0000000000000000000C02004000000000017
-:1025E0000000000000A0000A0000000000002257C8
-:1025F000002044110000000000000003C0484A20F1
-:10260000000000000000225D0020441100000000D6
-:1026100000000000C0404800000000000000000072
-:1026200000600000000005C500000000C020080098
-:10263000000000000000225C0020441100000000A7
-:102640000000000300384A22000000000000A1FC46
-:10265000002044110000000000000000C0204800DD
-:10266000000000000001A1FD002044110000000056
-:1026700000000000002F0222000000000000000007
-:102680000CE00000000000000000000040204800B6
-:10269000000000000000000140304A20000000005F
-:1026A00000000002C0304A200000000000000001CD
-:1026B00000530A22000003340000003FC0280A2013
-:1026C0000000000081000000002044110000000014
-:1026D000000000010020481100000000000021F867
-:1026E00000204411000000000000001700204811E5
-:1026F00000000000000421F90060441100000614ED
-:102700000000001100210230000000000000000065
-:1027100014E000000000033D00000014002F02221E
-:1027200000000000000000000CC000000000035189
-:102730000000201000204411000000000000800074
-:1027400000204811000000000001A2A40020441154
-:102750000000000000000000002048110000000000
-:1027600000000016006048110000035E0000210018
-:10277000002044110000000000000000C0204800BC
-:102780000000000000000000C02048000000000021
-:1027900000000000C0204800000000000000000011
-:1027A000C0204800000000000001A2A40020441145
-:1027B00000000000000000000020481100000000A0
-:1027C000000000000040480200000000000000047B
-:1027D000002F022200000000000000000CC00000DA
-:1027E00000000355000020100020441100000000EC
-:1027F000000080000040481100000349000000284C
-:10280000002F022200000000000000000CE0000089
-:1028100000000349000021040020441100000000D2
-:1028200000000000C0204800000000000000000080
-:10283000C02048000000000000000000C020480048
-:102840000000000000000000C02048000000000060
-:102850000000A2A4002044110000000000000000BD
-:10286000004048020000000000000035002036262D
-:1028700000000000000000490020181100000000C6
-:1028800000000000002048110000000000000001CE
-:1028900000331A260000000000000000002F02266E
-:1028A00000000000000000000CC0000000000360F9
-:1028B0000000003500801A2D000000000000003FDD
-:1028C000C0280A200000000000000015002F02228E
-:1028D00000000000000000000CE000000000037693
-:1028E0000000001E002F0222000000000000000077
-:1028F0000CE000000000038000000020002F0222F6
-:1029000000000000000000000CE000000000038C4C
-:102910000000000F002F0222000000000000000055
-:102920000CE000000000039800000010002F0222BD
-:1029300000000000000000000CE000000000039810
-:1029400000000006002F022200000000000000002E
-:102950000CE000000000039A00000016002F022285
-:1029600000000000000000000CE000000000039FD9
-:102970000000A2A40020441100000000000000009C
-:1029800000404802000000000800000000290A2260
-:10299000000000000000000340210E2000000000A5
-:1029A0000000000CC0211220000000000008000000
-:1029B000002812240000000000000014C02216208D
-:1029C0000000000000000000002914A40000000026
-:1029D0000000A2A40020441100000000000000003C
-:1029E000002948A2000000000000A1FE00204411C0
-:1029F000000000000000000000404803000000004C
-:102A000081000000002044110000000000000001CF
-:102A10000020481100000000000021F800204411AF
-:102A20000000000000000015002048110000000018
-:102A3000000421F900604411000006140000001594
-:102A400000210230000000000000000014E000003F
-:102A5000000003820000210E00204411000000004D
-:102A600000000000C020480000000000000000003E
-:102A7000C0204800000000000000A2A40020441173
-:102A800000000000000000000040480200000000BC
-:102A9000810000000020441100000000000000013F
-:102AA0000020481100000000000021F8002044111F
-:102AB0000000000000000016002048110000000087
-:102AC000000421F900604411000006140000000316
-:102AD00000210230000000000000000014E00000AF
-:102AE0000000038E000021080020441100000000B7
-:102AF00000000000C02048000000000000000000AE
-:102B0000C0204800000000000000A2A400204411E2
-:102B1000000000000000000000404802000000002B
-:102B20000000201000204411000000000000800080
-:102B30000040481100000000000020100020441157
-:102B4000000000000000800000204811000000008C
-:102B50000001A2A4002044110000000000000000B9
-:102B6000002048110000000000000006004048114D
-:102B700000000000000020100020441100000000B0
-:102B80000000800000204811000000000001A2A405
-:102B90000020441100000000000000000020481147
-:102BA0000000000000000016006048110000035EF5
-:102BB0000000001600404811000000000000000066
-:102BC000C02008000000000000000000C0200C0031
-:102BD000000000000000001D002102230000000092
-:102BE0000000000014E00000000003B981000000B4
-:102BF00000204411000000000000000100204811E6
-:102C000000000000000021F8002044110000000036
-:102C1000000000170020481100000000000421F906
-:102C20000060441100000614000000110021023071
-:102C3000000000000000000014E00000000003ABF2
-:102C400000002100002044110000000000000000EE
-:102C5000002048020000000000000000002048039F
-:102C600000000000BABECAFE0020481100000000AB
-:102C7000CAFEBABE0020481100000000000020106B
-:102C800000204411000000000000800000204811D6
-:102C9000000000000000A2A4002044110000000079
-:102CA00000000004004048110000000000002170F6
-:102CB0000020441100000000000000000020480235
-:102CC0000000000000000000002048030000000099
-:102CD0008100000000204411000000000000000AF4
-:102CE000002048110000000000000000002000103B
-:102CF000000000000000000014C00000000003BE3F
-:102D00008C0000000020441100000000CAFEBABE82
-:102D10000040481100000000810000000020441124
-:102D20000000000000000001002048110000000029
-:102D300000003FFF40280A20000000008000000043
-:102D400040280E200000000040000000C028122093
-:102D50000000000000040000006946220000061484
-:102D6000000000000020141000000000000000001F
-:102D7000002F022300000000000000000CC0000033
-:102D8000000003CC00000000C0401800000003CF8A
-:102D900000003FFFC0281A200000000000040000CF
-:102DA00000694626000006140000000000201810EC
-:102DB0000000000000000000002F022400000000BE
-:102DC000000000000CC00000000003D20000000062
-:102DD000C0401C00000003D500003FFFC0281E209B
-:102DE00000000000000400000069462700000614EF
-:102DF0000000000000201C10000000000000000087
-:102E0000002044020000000000000000002820C54F
-:102E10000000000000000000004948E80000000039
-:102E2000A580000000200811000000000000200024
-:102E300000200C110000000083000000006044111D
-:102E4000000003FD0000000000204402000000001C
-:102E500000000000C020480000000000000000004A
-:102E600040204800000000000000001FC021022098
-:102E7000000000000000000014C00000000003E299
-:102E8000000020100020441100000000000080001D
-:102E900000204811000000000000FFFFC048122081
-:102EA000000003EAA78000000020081100000000D5
-:102EB0000000A00000200C110000000083000000B2
-:102EC00000604411000003FD0000000000204402E7
-:102ED0000000000000000000C020480000000000CA
-:102EE00000000000C0204800000000000000FFFFBC
-:102EF000C0281220000000008300000000204411C0
-:102F000000000000000000000030488300000000C6
-:102F100084000000002044110000000000000000B8
-:102F2000C020480000000000000000001D0000005C
-:102F3000000000008300000000604411000003FD59
-:102F400000000000C040040000000001A980000053
-:102F500000200811000000000000C00000400C111B
-:102F6000000003E5AB800000002008110000000015
-:102F70000000F8E000400C11000003E5AD80000007
-:102F800000200811000000000000F88000400C1133
-:102F9000000003E5B38000000020081100000000DD
-:102FA0000000F3FC00400C11000003E5AF800000BE
-:102FB00000200811000000000000E00000400C119B
-:102FC000000003E5B18000000020081100000000AF
-:102FD0000000F00000400C11000003E58300000039
-:102FE000002044110000000000002148002048118A
-:102FF00000000000840000000020441100000000D8
-:1030000000000000C0204800000000000000000098
-:103010001D00000000000000000000000080000013
-:103020000000000000182000C03046200000000012
-:1030300000000000D900480000000000000000006F
-:10304000C0200400000000000000000000A0000AF2
-:10305000000000000018A000C03046200000000062
-:1030600000000000D900480000000000000000003F
-:10307000C0200400000000000000000000A0000AC2
-:10308000000000000018C000C03046200000000012
-:1030900000000000D900480000000000000000000F
-:1030A000C0200400000000000000000000A0000A92
-:1030B000000000000018F8E0C030462000000000CA
-:1030C00000000000D90048000000000000000000DF
-:1030D000C0200400000000000000000000A0000A62
-:1030E000000000000018F880C030462000000000FA
-:1030F00000000000D90048000000000000000000AF
-:10310000C0200400000000000000000000A0000A31
-:10311000000000000018E000C03046200000000061
-:1031200000000000D900480000000000000000007E
-:10313000C0200400000000000000000000A0000A01
-:10314000000000000018F000C03046200000000021
-:1031500000000000D900480000000000000000004E
-:10316000C0200400000000000000000000A0000AD1
-:10317000000000000018F3FCC030462000000000F2
-:1031800000000000D900480000000000000000001E
-:10319000C0200400000000000000000000A0000AA1
-:1031A0000000000086000000002044110000000024
-:1031B0000000000000404801000000008500000001
-:1031C0000020441100000000000000000040480101
-:1031D000000000000000217C0020441100000000DD
-:1031E00000000000C02048000000000000000000B7
-:1031F000C02048000000000000000000C02048007F
-:1032000000000000810000000020441100000000C8
-:103210000000000100204811000000000000000034
-:10322000C02008000000000000000000170000009F
-:10323000000000000004217F00604411000006141B
-:103240000000001F0021023000000000000000000C
-:1032500014C00000000000000000000000404C020C
-:103260000000042E00000000C0200C000000000040
-:1032700000000000C020100000000000000000005E
-:10328000C02014000000000000000000C020180052
-:103290000000000000000000C0201C000000000032
-:1032A00000007F0000280A21000000000000450007
-:1032B000002F022200000000000000000CE00000CF
-:1032C0000000043C00000000C020200000000000BE
-:1032D00000000000170000000000000000000010C7
-:1032E00000280A230000000000000010002F022226
-:1032F00000000000000000000CE00000000004449A
-:1033000081000000002044110000000000000001C6
-:10331000002048110000000000040000006946245D
-:103320000000061400000000004000000000044DF2
-:103330008100000000204411000000000000000097
-:1033400000204811000000000000216D0020441101
-:103350000000000000000000002048040000000001
-:1033600000000000002048050000000000000000F0
-:103370001AC00000000004499E0000000020441113
-:1033800000000000CAFEBABE002048110000000084
-:10339000000000001AE000000000044C00000000E3
-:1033A000002824F0000000000000000700280A2385
-:1033B0000000000000000001002F022200000000B9
-:1033C000000000000AE000000000045400000000BB
-:1033D000002F00C9000000000000000004E0000011
-:1033E0000000046D00000000004000000000047AAE
-:1033F00000000002002F0222000000000000000078
-:103400000AE000000000045900000000002F00C97D
-:10341000000000000000000002E000000000046D59
-:1034200000000000004000000000047A00000003DB
-:10343000002F022200000000000000000AE000004F
-:103440000000045E00000000002F00C90000000022
-:10345000000000000CE000000000046D000000000F
-:10346000004000000000047A00000004002F022247
-:1034700000000000000000000AE0000000000463FB
-:1034800000000000002F00C9000000000000000044
-:103490000AE000000000046D000000000040000091
-:1034A0000000047A00000005002F02220000000046
-:1034B000000000000AE000000000046800000000B6
-:1034C000002F00C9000000000000000006E000001E
-:1034D0000000046D00000000004000000000047ABD
-:1034E00000000006002F0222000000000000000083
-:1034F0000AE000000000046D00000000002F00C979
-:10350000000000000000000008E000000000046D62
-:1035100000000000004000000000047A00007F006E
-:1035200000280A210000000000004500002F0222B0
-:1035300000000000000000000AE0000000000000A1
-:103540000000000800210A23000000000000000025
-:1035500014C000000000047700002169002044111D
-:103560000000000000000000C02048000000000033
-:1035700000000000C0204800000000000000000023
-:10358000C020480000000000CAFEBABE004048113A
-:103590000000000000000000C02044000000000007
-:1035A00000000000C020000000000000000000003B
-:1035B000C04048000000000000007F0000280A21F1
-:1035C0000000000000004500002F02220000000063
-:1035D000000000000AE0000000000480000000007D
-:1035E000C02000000000000000000000C02000001B
-:1035F0000000000000000000C040000000000000CB
-:103600000000000000404C080000043C00000000E6
-:10361000C0200800000000000000001040210E2023
-:1036200000000000000000114021122000000000F6
-:103630000000001240211620000000000000216957
-:10364000002044110000000000000000002048029B
-:103650000000000000000000002102250000000022
-:103660000000000014E000000000048A00040000D4
-:10367000C0494A200000048BFFFBFFFFC0284A20FE
-:1036800000000000000000000021022300000000F4
-:103690000000000014E0000000000497000000009B
-:1036A000C02048000000000000000000C0204800CA
-:1036B00000000000000000000021022400000000C3
-:1036C0000000000014C000000000000081000000A5
-:1036D00000204411000000000000000C00204811F0
-:1036E00000000000000000000020001000000000AA
-:1036F0000000000014C0000000000493A0000000BF
-:103700000020441100000000CAFEBABE004048116B
-:1037100000000000810000000020441100000000B3
-:103720000000000400204811000000000000216B90
-:10373000002044110000000000000000C0204810DC
-:103740000000000081000000002044110000000083
-:103750000000000500204811000000000000216C5E
-:10376000002044110000000000000000C0204810AC
-:103770000000000000000000002F022400000000F4
-:10378000000000000CE0000000000000000000004D
-:10379000004000000000049100000000C0210A2049
-:1037A000000000000000000014C00000000004AE93
-:1037B0008100000000204411000000000000000013
-:1037C00000204811000000000000216D002044117D
-:1037D0000000000000000000C020480000000000C1
-:1037E00000000000C02048000000000000000000B1
-:1037F0001AC00000000004A99E000000002044112F
-:1038000000000000CAFEBABE0020481100000000FF
-:10381000000000001AE00000000004AC00000000FE
-:1038200000400000000004B28100000000204411AC
-:10383000000000000000000100204811000000000E
-:1038400000040000C0294620000000000000000025
-:10385000C0600000000006140000000100210222E8
-:10386000000000000000000014C00000000004B9C7
-:103870000000216900204411000000000000000049
-:10388000C02048000000000000000000C0204800E8
-:1038900000000000000000000020481000000000B0
-:1038A000CAFEBABE0040481100000000000000003F
-:1038B000C02044000000000000000000C04048108C
-:1038C0000000000081000000002044110000000002
-:1038D000000000010020481100000000000021F855
-:1038E00000204411000000000000000D00204811DD
-:1038F00000000000000421F90060441100000614DB
-:103900000000000000210230000000000000000064
-:1039100014C00000000004BB0000218000204411FE
-:103920000000000000000000C0204800000000006F
-:1039300000000000C02000000000000000000000A7
-:10394000C02048000000000000000000C02000006F
-:103950000000000000000000C0404800000000001F
-:103960000000000300333E2F0000000000000001B3
-:1039700000210221000000000000000014E000000F
-:10398000000004EB0000003500200A2D00000000BC
-:103990000004000018E00C11000004DA000000012F
-:1039A00000333E2F00000000000021690020441178
-:1039B000000000000000000000204802000000009D
-:1039C0000000000000204803000000000000000884
-:1039D00000300A220000000000000000C020480063
-:1039E0000000000000000000C020480000000000AF
-:1039F00000002169002044110000000000000000C8
-:103A000000204802000000000000000000204803E1
-:103A1000000000000000000800300A220000000042
-:103A200000000000C020480000000000000000006E
-:103A3000D8C04800000004CE0000216900204411D5
-:103A4000000000000000000000204802000000000C
-:103A500000000000002048030000000000000008F3
-:103A600000300A220000000000000000C0204800D2
-:103A70000000000000000000C0204800000000001E
-:103A8000000000360020122D0000000000000000A1
-:103A900000290C830000000000002169002044116F
-:103AA00000000000000000000020480200000000AC
-:103AB0000000000000204803000000000000000893
-:103AC00000300A220000000000000000C020480072
-:103AD0000000000000000000C020480000000000BE
-:103AE000000000110021022400000000000000007E
-:103AF00014C00000000000000000000000400000B2
-:103B00000000049100000035C020362000000000B5
-:103B100000000036C0403620000000000000304A9F
-:103B20000020441100000000E0000000C0484A20CE
-:103B3000000000000000000F002102210000000032
-:103B40000000000014C00000000004F200000000AB
-:103B5000006000000000000B00000000D900000021
-:103B60000000000000000000C04004000000000150
-:103B7000810000000020441100000000000000024D
-:103B80000020481100000000000000FF00280E3057
-:103B90000000000000000000002F022300000000D1
-:103BA000000000000CC00000000004F6000000004F
-:103BB000C0200800000000000000000014C0000049
-:103BC0000000050B0000000000200C1100000000A8
-:103BD0000000002400203623000000000000003414
-:103BE00000203623000000000000003200203623B1
-:103BF000000000000000003100203623000000001B
-:103C00000000001D00203623000000000000002DF1
-:103C100000203623000000000000002E0020362384
-:103C2000000000000000001B002036230000000000
-:103C30000000001C0020362300000000FFFFE00011
-:103C400000200C1100000000000000290020362395
-:103C5000000000000000002A0020362300000000C1
-:103C600000001FFF00200C11000000000000002BCE
-:103C700000203623000000000000002C0020362326
-:103C800000000000F1FFFFFF00283A2E00000000B6
-:103C90000000001AC0220E200000000000000000FA
-:103CA0000029386E0000000081000000002044114F
-:103CB0000000000000000006002048110000000085
-:103CC0000000003340203620000000008700000084
-:103CD000002044110000000000000000C020480047
-:103CE000000000000000A1F40020441100000000CA
-:103CF0000000000000204810000000009D000000AF
-:103D000000204411000000000000001F40214A2054
-:103D10000000000096000000002044110000000098
-:103D200000000000C020480000000000000000006B
-:103D3000C0200C000000000000000000C0201000A7
-:103D4000000000000000001F0021162400000000F9
-:103D50000000000014C0000000000000000000256A
-:103D600000203623000000000000000300281E236E
-:103D700000000000000000080022222300000000D4
-:103D8000FFFFF000002822280000000000000000D3
-:103D9000002920E80000000000000027002036284D
-:103DA000000000000000001800211E230000000099
-:103DB000000000280020362700000000000000025C
-:103DC000002216240000000000000000003014A8AB
-:103DD0000000000000000026002036250000000042
-:103DE0000000000300211A24000000001000000061
-:103DF00000281A2600000000EFFFFFFF00283A2EDF
-:103E00000000000000000000004938CE000006025B
-:103E10000000000140280A20000000000000000609
-:103E200040280E200000000000000300C0281220DF
-:103E30000000000000000008002112240000000023
-:103E400000000000C020162000000000000000005C
-:103E5000C0201A2000000000000000000021022203
-:103E6000000000000000000014C000000000054138
-:103E7000810000000020441100000000000000014B
-:103E800000204811000000000000225800300A24E1
-:103E90000000000000040000006946220000061433
-:103EA0000000216900204411000000000000000013
-:103EB00000204805000000000002000000294A26FA
-:103EC000000000000000000000204810000000007A
-:103ED000CAFEBABE00204811000000000000000227
-:103EE000002F022300000000000000000CC00000B2
-:103EF0000000054900000000C0201C100000000068
-:103F000000000000C04000000000055B000000024F
-:103F1000002F022300000000000000000CC0000081
-:103F2000000005498100000000204411000000004D
-:103F3000000000010020481100000000000022588D
-:103F400000300A240000000000040000006946223E
-:103F50000000061400000000C0201C10000000003B
-:103F600000000000C04000000000055B00000000F1
-:103F7000002F022300000000000000000CC0000021
-:103F80000000054D00000000C0201C0000000000E3
-:103F900000000000C04000000000055B00000004BD
-:103FA000002F022300000000000000000CC00000F1
-:103FB00000000559810000000020441100000000AD
-:103FC0000000000000204811000000000000216DEA
-:103FD000002044110000000000000000C020480044
-:103FE0000000000000000000C020480000000000A9
-:103FF000000000001AC00000000005549E000000F0
-:104000000020441100000000CAFEBABE0020481182
-:1040100000000000000000001AE00000000005574A
-:104020000000000000401C100000055B00000000C4
-:10403000C02000000000000000000000C0400000A0
-:1040400000000000000000000EE000000000055D20
-:104050000000000000600000000005A40000000057
-:10406000002F022400000000000000000CC000002F
-:104070000000056D0000A2B7002044110000000000
-:104080000000000000204807000000008100000040
-:104090000020441100000000000000010020481131
-:1040A000000000000004A2B60060441100000614E5
-:1040B0000000001A0021223000000000000000066D
-:1040C00000222630000000000000A2C4002044119D
-:1040D0000000000000000000003048E9000000007F
-:1040E0000000000000E000000000056B0000A2D10D
-:1040F00000204411000000000000000000404808BB
-:10410000000000000000A2D10020441100000000C7
-:104110000000000100504A280000000000000001DB
-:10412000002F022400000000000000000CC000006E
-:104130000000057D0000A2BB00204411000000002B
-:10414000000000000020480700000000810000007F
-:104150000020441100000000000000010020481170
-:10416000000000000004A2BA006044110000061420
-:104170000000001A002122300000000000000006AC
-:1041800000222630000000000000A2C500204411DB
-:104190000000000000000000003048E900000000BE
-:1041A0000000000000E000000000057B0000A2D23B
-:1041B00000204411000000000000000000404808FA
-:1041C000000000000000A2D2002044110000000006
-:1041D0000000000100504A2800000000000000021A
-:1041E000002F022400000000000000000CC00000AE
-:1041F0000000058D0000A2BF002044110000000057
-:1042000000000000002048070000000081000000BE
-:1042100000204411000000000000000100204811AF
-:10422000000000000004A2BE00604411000006145B
-:104230000000001A002122300000000000000006EB
-:1042400000222630000000000000A2C60020441119
-:104250000000000000000000003048E900000000FD
-:104260000000000000E000000000058B0000A2D369
-:104270000020441100000000000000000040480839
-:10428000000000000000A2D3002044110000000044
-:104290000000000100504A28000000000000A2C3F6
-:1042A000002044110000000000000000002048072A
-:1042B0000000000081000000002044110000000008
-:1042C0000000000100204811000000000004A2C20C
-:1042D00000604411000006140000001A0021223082
-:1042E0000000000000000006002226300000000050
-:1042F0000000A2C7002044110000000000000000E0
-:10430000003048E9000000000000000000E000006C
-:10431000000005990000A2D4002044110000000014
-:104320000000000000404808000000000000A2D487
-:1043300000204411000000000000000100504A2845
-:104340000000000085000000002044110000000073
-:104350000000000000204801000000000000304A7A
-:10436000002044110000000001000000002048115E
-:104370000000000000000000004000000000059F59
-:10438000A4000000C0204411000000000000000054
-:10439000C04048000000000000000000C0600000B5
-:1043A000000005A400000000C0400400000000015F
-:1043B0000001A2A400204411000000000000000041
-:1043C00000204811000000000000000000204811FB
-:1043D0000000000000000000002048110000000064
-:1043E000000000000020481100000000000000054F
-:1043F00000204811000000000000A1F4002044113A
-:104400000000000000000000002048110000000033
-:10441000880000000020441100000000000000019E
-:104420000020481100000000FF000000002044119F
-:104430000000000000000000002048110000000003
-:1044400000000001002048110000000000000002F0
-:104450000080481100000000000000000EE0000095
-:10446000000005B700001000002008110000000047
-:104470000000003400203622000000000000000090
-:1044800000600000000005BB0000000000600000AC
-:10449000000005A498000000002044110000000066
-:1044A0000000000000804811000000000000000033
-:1044B000C0600000000005BB00000000C040040018
-:1044C000000000010000A2A4002044110000000030
-:1044D00000000022002048110000000089000000B8
-:1044E00000204411000000000000000100204811DD
-:1044F00000000000FF000000002044110000000048
-:104500000000000000204811000000000000000131
-:104510000020481100000000000000020080481147
-:10452000000000000000217AC020441100000000BB
-:10453000000000000040481100000000970000004B
-:10454000002044110000000000000000002048117D
-:10455000000000008A00000000204411000000005C
-:10456000000000000020481100000000FF000000D3
-:10457000002044110000000000000000002048114D
-:1045800000000000000000010020481100000000B1
-:104590000000000200804811000000000000000040
-:1045A00000600000000005E1000020100020441120
-:1045B0000000000000008000002048110000000002
-:1045C0000001A2A4C020441100000000000000006F
-:1045D0000020481100000000000000160060481193
-:1045E0000000035E000000160020481100000000DB
-:1045F0000000201000204411000000000001000015
-:10460000002048110000000081000000002044113B
-:104610000000000000000001002048110000000020
-:104620000000217C002044110000000009800000EF
-:104630000020481100000000FFFFFFFF002048118C
-:1046400000000000000000000020481100000000F1
-:104650000000000017000000000000000004217F9F
-:1046600000604411000006140000001F0021023009
-:10467000000000000000000014C000000000000066
-:104680000000000400404C11000005DC0000001D8B
-:1046900000201E2D000000000000000400291E273D
-:1046A000000000000000001D008036270000000010
-:1046B0000000001D00201E2D00000000FFFFFFFB7A
-:1046C00000281E27000000000000001D0080362783
-:1046D000000000000000001D00201E2D0000000052
-:1046E0000000000800291E27000000000000001D37
-:1046F00000803627000000000000001D00201E2D55
-:1047000000000000FFFFFFF700281E270000000048
-:104710000000001D0080362700000000000020106F
-:10472000002044110000000000008000002048111B
-:10473000000000000001A2A40020441100000000BD
-:1047400000000000002048110000000000000016DA
-:10475000006048110000035E0000001600204811B0
-:1047600000000000000020100020441100000000A4
-:104770000001000000204811000000000000217C22
-:1047800000204411000000000180000000204811BA
-:104790000000000000FFFFFF0020481100000000A3
-:1047A0000000000000204811000000000000000090
-:1047B00017000000000000008100000000204411EC
-:1047C000000000000000000100204811000000006F
-:1047D0000004217F00604411000006140000000066
-:1047E00000200010000000000000000014C00000C5
-:1047F000000006130000001000404C11000005F9F5
-:1048000000000000C02004000000000000000000C4
-:1048100038C00000000000000000002500200A2D24
-:10482000000000000000002600200E2D0000000007
-:10483000000000270020122D0000000000000028CA
-:104840000020162D00000000000021690020441106
-:1048500000000000000000000020480400000000EC
-:1048600000000000002048050000000000000000DB
-:104870000020480100000000CAFEBABE0020481116
-:1048800000000000000000040030122400000000BE
-:1048900000000000002F0064000000000000000085
-:1048A0000CC00000000006120000000300281A22BD
-:1048B000000000000000000800221222000000009A
-:1048C000FFFFF0000028122400000000000000009C
-:1048D000002910C40000000000000027004036241A
-:1048E0000000000000000000008000000000000048
-:1048F000000000001AC00000000006149F00000025
-:104900000020441100000000CAFEBABE0020481179
-:1049100000000000000000001AE000000000061780
-:104920000000000000800000000000000000000007
-:10493000006000000000000B000010000060041187
-:10494000000002FE00000000002004110000000032
-:1049500000000000006008110000019F0000225CC0
-:104960000020441100000000000000030020481156
-:10497000000000000000225600204411000000004A
-:104980000000001B00204811000000000000A1FCF6
-:104990000020441100000000000000010020481128
-:1049A000000000000001A1FDC02044110000000033
-:1049B0000000002900201E2D000000000000001053
-:1049C00000221E27000000000000002C0020222DE5
-:1049D000000000000000FFFF002822280000000067
-:1049E000000000000029490700000000000000004E
-:1049F00000204811000000000000002A0020222DA5
-:104A0000000000000000FFFF002822280000000036
-:104A1000000000000029490700000000000000001D
-:104A200000204811000000000000002B00201E2D77
-:104A3000000000000000001000221E2700000000FF
-:104A400000000000002949070000000000000000ED
-:104A500000404811000000000000000000000000BD
-:104A60000000000000000000000000000000000046
-:104A70000000000000000000000000000000000036
-:104A80000000000000000000000000000000000026
-:104A90000000000000000000000000000000000016
-:104AA0000000000000000000000000000000000006
-:104AB00000000000000000000000000000000000F6
-:104AC00000000000000000000000000000000000E6
-:104AD00000000000000000000000000000000000D6
-:104AE00000000000000000000000000000000000C6
-:104AF00000000000000000000000000000000000B6
-:104B000000000000000000000000000000000000A5
-:104B10000000000000000000000000000000000095
-:104B20000000000000000000000000000000000085
-:104B30000000000000000000000000000000000075
-:104B40000000000000000000000000000000000065
-:104B50000000000000000000000000000000000055
-:104B60000000000000000000000000000000000045
-:104B70000000000000000000000000000000000035
-:104B80000000000000000000000000000000000025
-:104B90000000000000000000000000000000000015
-:104BA0000000000000000000000000000000000005
-:104BB00000000000000000000000000000000000F5
-:104BC00000000000000000000000000000000000E5
-:104BD00000000000000000000000000000000000D5
-:104BE00000000000000000000000000000000000C5
-:104BF00000000000000000000000000000000000B5
-:104C000000000000000000000000000000000000A4
-:104C10000000000000000000000000000000000094
-:104C20000000000000000000000000000000000084
-:104C30000000000000000000000000000000000074
-:104C40000000000000000000000000000000000064
-:104C50000000000000000000000000000000000054
-:104C60000000000000000000000000000000000044
-:104C70000000000000000000000000000000000034
-:104C80000000000000000000000000000000000024
-:104C90000000000000000000000000000000000014
-:104CA0000000000000000000000000000000000004
-:104CB00000000000000000000000000000000000F4
-:104CC00000000000000000000000000000000000E4
-:104CD00000000000000000000000000000000000D4
-:104CE00000000000000000000000000000000000C4
-:104CF00000000000000000000000000000000000B4
-:104D000000000000000000000000000000000000A3
-:104D10000000000000000000000000000000000093
-:104D20000000000000000000000000000000000083
-:104D30000000000000000000000000000000000073
-:104D40000000000000000000000000000000000063
-:104D50000000000000000000000000000000000053
-:104D60000000000000000000000000000000000043
-:104D70000000000000000000000000000000000033
-:104D80000000000000000000000000000000000023
-:104D90000000000000000000000000000000000013
-:104DA0000000000000000000000000000000000003
-:104DB00000000000000000000000000000000000F3
-:104DC00000000000000000000000000000000000E3
-:104DD00000000000000000000000000000000000D3
-:104DE00000000000000000000000000000000000C3
-:104DF00000000000000000000000000000000000B3
-:104E000000000000000000000000000000000000A2
-:104E10000000000000000000000000000000000092
-:104E20000000000000000000000000000000000082
-:104E30000000000000000000000000000000000072
-:104E40000000000000000000000000000000000062
-:104E50000000000000000000000000000000000052
-:104E60000000000000000000000000000000000042
-:104E70000000000000000000000000000000000032
-:104E80000000000000000000000000000000000022
-:104E90000000000000000000000000000000000012
-:104EA0000000000000000000000000000000000002
-:104EB00000000000000000000000000000000000F2
-:104EC00000000000000000000000000000000000E2
-:104ED00000000000000000000000000000000000D2
-:104EE00000000000000000000000000000000000C2
-:104EF00000000000000000000000000000000000B2
-:104F000000000000000000000000000000000000A1
-:104F10000000000000000000000000000000000091
-:104F20000000000000000000000000000000000081
-:104F30000000000000000000000000000000000071
-:104F40000000000000000000000000000000000061
-:104F50000000000000000000000000000000000051
-:104F60000000000000000000000000000000000041
-:104F70000000000000000000000000000000000031
-:104F80000000000000000000000000000000000021
-:104F90000000000000000000000000000000000011
-:104FA0000000000000000000000000000000000001
-:104FB00000000000000000000000000000000000F1
-:104FC00000000000000000000000000000000000E1
-:104FD00000000000000000000000000000000000D1
-:104FE00000000000000000000000000000000000C1
-:104FF00000000000000000000000000000000000B1
-:1050000000000000000000000000000000000000A0
-:105010000000000000000000000000000000000090
-:105020000000000000000000000000000000000080
-:105030000000000000000000000000000000000070
-:105040000000000000000000000000000000000060
-:105050000000000000000000000000000000000050
-:105060000000000000000000000000000000000040
-:105070000000000000000000000000000000000030
-:105080000000000000000000000000000000000020
-:105090000000000000000000000000000000000010
-:1050A0000000000000000000000000000000000000
-:1050B00000000000000000000000000000000000F0
-:1050C00000000000000000000000000000000000E0
-:1050D00000000000000000000000000000000000D0
-:1050E00000000000000000000000000000000000C0
-:1050F00000000000000000000000000000000000B0
-:10510000000000000000000000000000000000009F
-:10511000000000000000000000000000000000008F
-:10512000000000000000000000000000000000007F
-:10513000000000000000000000000000000000006F
-:10514000000000000000000000000000000000005F
-:10515000000000000000000000000000000000004F
-:10516000000000000000000000000000000000003F
-:10517000000000000000000000000000000000002F
-:10518000000000000000000000000000000000001F
-:10519000000000000000000000000000000000000F
-:1051A00000000000000000000000000000000000FF
-:1051B00000000000000000000000000000000000EF
-:1051C00000000000000000000000000000000000DF
-:1051D00000000000000000000000000000000000CF
-:1051E00000000000000000000000000000000000BF
-:1051F00000000000000000000000000000000000AF
-:10520000000000000000000000000000000000009E
-:10521000000000000000000000000000000000008E
-:10522000000000000000000000000000000000007E
-:10523000000000000000000000000000000000006E
-:10524000000000000000000000000000000000005E
-:10525000000000000000000000000000000000004E
-:10526000000000000000000000000000000000003E
-:10527000000000000000000000000000000000002E
-:10528000000000000000000000000000000000001E
-:10529000000000000000000000000000000000000E
-:1052A00000000000000000000000000000000000FE
-:1052B000013304EF059B02390000000001B00159E1
-:1052C0000425059B00000000021201F6023901428C
-:1052D000000000000210022E0289022A00000000D5
-:1052E00003C2059B059B059B0000000005CD05CE74
-:1052F0000308059B00000000059B05A00309032986
-:10530000000000000313026B032B031D00000000CC
-:10531000059B059B059B059B00000000059B052C3C
-:10532000059B059B0000000003A5059B04A2032D1F
-:1053300000000000048104330423059B00000000EA
-:1053400004BB04ED042704C800000000043304F487
-:10535000033A036500000000059B059B059B059B28
-:1053600000000000059B059B059B059B00000000BD
-:10537000059B059B05B905A200000000059B059B48
-:105380000007059B00000000059B059B059B059BF6
-:1053900000000000059B059B059B059B000000008D
-:1053A00003E303D803F303F10000000003F903F55E
-:1053B00003F703FB0000000004070403040F040BC1
-:1053C0000000000004170413041F041B0000000069
-:1053D000059B059B059B059B00000000059B059B0D
-:1053E000059B059B00000000059B059B059B059BFD
-:1053F0000000000000020600061900060000000080
-:00000001FF
--- zfcpdump-kernel-4.4.orig/firmware/radeon/R600_pfp.bin.ihex
+++ /dev/null
@@ -1,145 +0,0 @@
-:1000000000D4007100D4007200CA040000A00000F7
-:10001000007E828B0080000300CA040000D4401ED2
-:1000200000EE001E00CA040000A00000007E828BCB
-:1000300000C4183800CA240000CA2800009581A80E
-:1000400000C41C3A00C3C00000CA080000CA0C006B
-:10005000007C744B00C200050099C00000C41C3A2B
-:10006000007C744C00C0FFF000042C0400309002AF
-:10007000007D250000351402007D350B002554035A
-:10008000007CD58000259C030095C00400D5001B92
-:10009000007EDDC1007D9D8000D6801B00D5801BC9
-:1000A00000D4401E00D5401E00D6401E00D6801E43
-:1000B00000D4801E00D4C01E009783D400D5C01E7B
-:1000C00000CA08000080001B00CA0C0000E4011EEA
-:1000D00000D4001E0080000D00C4183800E4013E6A
-:1000E00000D4001E0080000D00C4183800D4401E4B
-:1000F00000EE001E00CA040000A00000007E828BFB
-:1001000000E4011E00D4001E00D4401E00EE001EBC
-:1001100000CA040000A00000007E828B00E4013EC3
-:1001200000D4001E00D4401E00EE001E00CA0400D1
-:1001300000A00000007E828B00CA180000D4401E80
-:1001400000D5801E0080005400D4007300D4401EEF
-:1001500000CA080000CA0C0000CA100000D48019B0
-:1001600000D4C01800D5001700D4801E00D4C01ED3
-:1001700000D5001E00E2001E00CA040000A000001E
-:10018000007E828B00CA080000D4806000D4401E2C
-:100190000080000200D4801E00CA080000D48061E4
-:1001A00000D4401E0080000200D4801E00CA080057
-:1001B00000CA0C0000D4401E00D4801600D4C01623
-:1001C00000D4801E008001B900D4C01E00C6083EC5
-:1001D00000CA0C0000CA10000094800400CA140079
-:1001E00000E420F300D4201300D5606500D4E01CA7
-:1001F00000D5201C00D5601C0080000200062001F4
-:1002000000C6083E00CA0C0000CA1000009483F724
-:1002100000CA140000E420F30080007A00D4201308
-:1002200000C6083E00CA0C0000CA1000009883EF08
-:1002300000CA140000D400640080008E000000009A
-:1002400000C4143200C6183E00C4082F00954005B3
-:1002500000C40C3000D4401E0080000200EE001EDE
-:10026000009583F500C4103100D4403300D52065DB
-:1002700000D4A01C00D4E01C00D5201C00D40073C6
-:1002800000E4015E00D4001E008001B900062001D8
-:10029000000A200100D6007400C4083600C61040D1
-:1002A0000098800700CC38350095010F00D4001F5E
-:1002B00000D460620080000200D4206200CC1433BD
-:1002C000008401BC00D4007000D5401E00800002F4
-:1002D00000EE001E00CA0C0000CA100000D4C01AB4
-:1002E000008401BC00D5001A00CC04430035101F67
-:1002F000002C9401007D098B00984005007D15CBF2
-:1003000000D4001A008001B900D4006D003444010B
-:1003100000CC0C440098403A00CC2C460095800458
-:1003200000CC0445008001B900D4001A00D4C01AE2
-:1003300000282801008400F300CC10030098801BE3
-:100340000004380C008400F300CC100300988017E0
-:1003500000043808008400F300CC100300988013D8
-:1003600000043804008400F300CC100300988014CB
-:1003700000CC1047009A800900CC1448009840DA5D
-:1003800000D4006D00CC184400D5001A00D5401AE6
-:10039000008000CC00D5801A0096C0D300D4006D38
-:1003A000008001B900D4006E009AC00300D4006D33
-:1003B00000D4006E0080000200EC007F009AC0CAEA
-:1003C00000D4006D008001B900D4006E00CC14038D
-:1003D00000CC180300CC1C03007D9103007DD58365
-:1003E000007D190C0035CC1F0035701F007CF0CB50
-:1003F000007CD08B00880000007E8E8B0095C004AE
-:1004000000D4006E008001B900D4001A00D4C01AD4
-:1004100000CC080300CC0C0300CC100300CC140368
-:1004200000CC180300CC1C0300CC240300CC280310
-:100430000035C41F0036B01F007C704B0034F01F25
-:10044000007C704B0035701F007C704B007D8881F4
-:10045000007DCCC1007E5101007E9541007C9082E0
-:10046000007CD4C2007C848B009AC003007C8C8BFF
-:10047000002C88010098809C00D4006D0098409A60
-:1004800000D4006E00CC084700CC0C4800CC1044CF
-:1004900000D4801A00D4C01A0080010400D5001ACC
-:1004A00000CC083200D40032009482D800CA0C007C
-:1004B00000D4401E0080000200D4001E00E4011E93
-:1004C00000D4001E00CA080000CA0C0000CA1000B8
-:1004D00000D4401E00CA140000D4801E00D4C01EE8
-:1004E00000D5001E00D5401E00D54034008000021B
-:1004F00000EE001E0028040400E2001A00E2001AC8
-:1005000000D4401A00CA380000CC080300CC0C0309
-:1005100000CC0C0300CC0C03009882BC000000004F
-:10052000008401BC00D7806F0080000200EE001F35
-:1005300000CA040000C2FF0000CC083400C13FFF25
-:10054000007C74CB007CC90B007D010F009902AFC9
-:10055000007C738B008401BC00D7806F0080000298
-:1005600000EE001F00CA080000281900007D898BDA
-:10057000009580140028140400CA0C0000CA100062
-:1005800000CA1C0000CA240000E2001F00D4C01AE8
-:1005900000D5001A00D5401A00CC180300CC2C035B
-:1005A00000CC2C0300CC2C03007DA58B007D9C4748
-:1005B00000984296000000000080016400D4C01A38
-:1005C00000D4401E00D4801E0080000200EE001EF9
-:1005D00000E4011E00D4001E00D4401E00EE001EE8
-:1005E00000CA040000A00000007E828B00E4013EEF
-:1005F00000D4001E00D4401E00EE001E00CA0400FD
-:1006000000A00000007E828B00CA080000248C0637
-:10061000000CCC060098C00600CC104900990004DC
-:1006200000D4007100E4011E00D4001E00D4401E5E
-:1006300000D4801E0080000200EE001E00CA0800E8
-:1006400000CA0C000034D018002510010095001FCE
-:1006500000C17FFF00CA100000CA140000CA1800C1
-:1006600000D4801D00D4C01D007DB18B00C14202AA
-:1006700000C2C00100D5801D0034DC0E007D5D4C41
-:10068000007F734C00D7401E00D5001E00D5401ED1
-:1006900000C1420000C2C00000099C010031DC1012
-:1006A000007F5F4C007F734C007D838000D5806F9E
-:1006B00000D5806600D7401E00EC005E00C8240212
-:1006C000008001B900D6007400D4401E00D4801E02
-:1006D00000D4C01E0080000200EE001E0080000258
-:1006E00000EE001F00D4001F0080000200D4001F95
-:1006F00000D4001F0088000000D4001F000000008C
-:1007000000000000000000000000000000000000E9
-:1007100000000000000000000000000000000000D9
-:1007200000000000000000000000000000000000C9
-:1007300000000000000000000000000000000000B9
-:1007400000000000000000000000000000000000A9
-:100750000000000000000000000000000000000099
-:100760000000000000000000000000000000000089
-:100770000000000000000000000000000000000079
-:100780000000000000000000000000000000000069
-:100790000000000000000000000000000000000059
-:1007A0000000000000000000000000000000000049
-:1007B0000000000000000000000000000000000039
-:1007C0000000000000000000000000000000000029
-:1007D0000000000000000000000000000000000019
-:1007E0000000000000000000000000000000000009
-:1007F00000000000000000000000000000000000F9
-:10080000000101740002017B0003009000040080DD
-:100810000005000500060040000700330008012F16
-:1008200000090047000A0037001001B7001700A4B4
-:100830000022013D0023014C002000B500240128C6
-:100840000027004E0028006B002A0061002B005397
-:10085000002F00660032008800340182003C0159FC
-:10086000003F00730041018F0044013100550176C3
-:100870000056017D0060000C006100350062003907
-:1008800000630039006400390065003900660039F2
-:10089000006700390068003B00690042006A0049B7
-:1008A000006B0049006C0049006D0049006E004972
-:1008B000006F0049007301B7000000070000000747
-:1008C000000000070000000700000007000000070C
-:1008D00000000007000000070000000700000007FC
-:1008E00000000007000000070000000700000007EC
-:1008F00000000007000000070000000700000007DC
-:00000001FF
--- zfcpdump-kernel-4.4.orig/firmware/radeon/RS600_cp.bin.ihex
+++ /dev/null
@@ -1,130 +0,0 @@
-:10000000000000004200E000000000004000E000AE
-:1000100000000008000000A000000008000000A48C
-:10002000000000004A554B4A000000004A4A44675D
-:100030000000000055526F75000000004A7E7D658B
-:10004000000000004AE74AF6000000004AD34A4A8E
-:1000500000000000D689898900000000CD4ADDCF6C
-:10006000000000008EBE4AE200000000C38A8A8AB7
-:10007000000000004A0F8CC800000004000CA00023
-:1000800000000038000D0012000000040000E8B479
-:1000900000000038000D0014000000040000E8B665
-:1000A00000000038000D0016000000040000E854B5
-:1000B00000000038000D0018000000040000E855A2
-:1000C00000000038000D001A000000040000E8568F
-:1000D00000000038000D001C000000040000E8577C
-:1000E00000000038000D001E000000040000E8249D
-:1000F00000000038000D0020000000040000E8258A
-:1001000000000038000D0022000000040000E8306C
-:1001100000000038000D0024000000040000F0C0C2
-:1001200000000038000D0026000000040000F0C1AF
-:1001300000000038000D0028000000040000F0411D
-:1001400000000038000D002A000000040000F184C7
-:1001500000000038000D002C000000040000F185B4
-:1001600000000038000D002E000000040000F186A1
-:1001700000000038000D0030000000040000F1878E
-:1001800000000038000D0032000000040000F18083
-:1001900000000038000D0034000000040000F3935C
-:1001A00000000038000D0036000000040000F38A53
-:1001B00000000038000D0038000000040000F38E3D
-:1001C000000000040000E821000000040140A0003D
-:1001D00000000018000000430000000400CCE8000C
-:1001E00000000004001B000100000004080048009B
-:1001F00000000004001B000100000004080048008B
-:1002000000000004001B000100000004080048007A
-:10021000000000080000003A000000000000A000FC
-:10022000000000042000451D000000040000E580DF
-:1002300000000004000CE581000000040800458077
-:1002400000000004000CE5810000000800000047E9
-:10025000000000000000A00000000004000C2000CE
-:10026000000000040000E50E000000040003200070
-:10027000000000280002205100000024000000516E
-:10028000000000040800450F000000080000A04B1B
-:10029000000000040000E565000000040000E566C1
-:1002A00000000008000000520000000403CCA5B4C8
-:1002B00000000004054320000000000400022000AC
-:1002C000000000304CCCE05E0000000408274565CB
-:1002D000000000300000005E0000000408004564DB
-:1002E000000000040000E566000000080000005562
-:1002F00000000010008020610000000400202000A9
-:1003000000000004001B00FF00000010010000645A
-:1003100000000004001F200000000004001C00FF7B
-:100320000000000C0000000000000030000000721F
-:100330000000000800000055000000040000E57601
-:10034000000000040000E577000000040000E50E56
-:10035000000000040000E50F000000040140A000C0
-:100360000000001800000069000000C200C0E5F9AC
-:100370000000000800000069000000040014E50E01
-:10038000000000040040E50F0000000800C0006C01
-:10039000000000040000E570000000040000E571AA
-:1003A0000000000C0000E572000000040000A00046
-:1003B000000000040140A000000000040000E56807
-:1003C00000000004000C200000000018000000766F
-:1003D00000000004000B00000000000418C0E562EB
-:1003E00000000008000000780000000800C000774E
-:1003F00000000004000700D5000000380000008461
-:1004000000000030000CA08600000004080045BB7E
-:1004100000000030000C2087000000000800E5BC50
-:10042000000000040000E5BB000000000000E5BC87
-:100430000000000C00120000000000040012000088
-:100440000000000C001B0002000000040000A000DF
-:10045000000000040000E821000000000000E800A7
-:10046000000000040000E821000000000000E82E69
-:100470000000000402CCA0000000000400140000F2
-:1004800000000004000CE1CC00000004050DE1CDEB
-:10049000000000040040000000000018000000966A
-:1004A0000000000400C0A00000000008000000934D
-:1004B0000000002000000098000000004200E00062
-:1004C000000000380000009F00000004000CA000A5
-:1004D000000000040014000000000004000C2000D4
-:1004E000000000040016000000000004700CE00092
-:1004F000000000080014009B000000004000E00025
-:10050000000000040240000000000004400EE00073
-:100510000000000402400000000000004000E00075
-:1005200000000004000C2000000000040240E51B55
-:10053000000000050080E50A000000050080E50BD2
-:10054000000000040022000000000004000700D5A5
-:1005500000000038000000B200000030000C2087CE
-:10056000000000050880E5BD00000030000C20867A
-:10057000000000050800E5BB00000030000C2087EB
-:10058000000000050880E5BC00000008000000B580
-:10059000000000050080E5BD000000050000E5BB8F
-:1005A000000000050080E5BC000000040021000000
-:1005B00000000004028000000000001800C000B924
-:1005C000000000404180E00000000024000000BB6B
-:1005D0000000000C010000000000000C0100E51DFF
-:1005E00000000004000045BB00000008000080B5CA
-:1005F000000000040000F3CE000000040140A00051
-:100600000000000400CC20000000004008C053CFD0
-:100610000000000000008000000000040000F3D291
-:10062000000000040140A0000000000400CC2000F5
-:100630000000004008C053D300000000000080000C
-:10064000000000040000F39D000000040140A00031
-:100650000000000400CC20000000004008C0539EB1
-:1006600000000000000080000000000403C008300B
-:10067000000000004200E000000000040000A000B4
-:1006800000000004200045E0000000000000E5E15B
-:10069000000000000000000100000004000700D27C
-:1006A000000000000800E3940000000000000000CB
-:1006B000000000040000E8C4000000040000E8C5D9
-:1006C000000000040000E8C6000000040000E92863
-:1006D000000000040000E929000000040000E92AED
-:1006E00000000008000000D6000000040000E92817
-:1006F000000000040000E929000000040000E92ACD
-:1007000000000008000000DD0000000000E001160D
-:1007100000000004000700E1000000040800401C85
-:1007200000000004200050E7000000040000E01D6D
-:1007300000000008000000E40000000402C02000E7
-:10074000000000040006000000000034000000EB80
-:1007500000000008000000E8000000040000800025
-:1007600000000000C000E0000000000000000000E9
-:100770000000000000000000000000000000000079
-:100780000000000000000000000000000000000069
-:100790000000000000000000000000000000000059
-:1007A0000000000000000000000000000000000049
-:1007B00000000004000C200000000004001D0018D0
-:1007C00000000004001A000100000034000000FBDB
-:1007D000000000080000004A000000080500A04AD0
-:1007E0000000000000000000000000000000000009
-:1007F00000000000000000000000000000000000F9
-:00000001FF
-/* production radeon ucode r1xx-r6xx */
--- zfcpdump-kernel-4.4.orig/firmware/radeon/RS690_cp.bin.ihex
+++ /dev/null
@@ -1,130 +0,0 @@
-:1000000000000008000000DD00000008000000DF24
-:1000100000000008000000A000000008000000A48C
-:10002000000000004A554B4A000000004A4A44675D
-:100030000000000055526F75000000004A7E7D658B
-:10004000000000004AD74AF6000000004AC94A4AA8
-:1000500000000000CC89898900000000C34AD3C594
-:10006000000000008E4A4A4A000000004A8A8A8A3C
-:10007000000000004A0F8C4A00000004000CA000A1
-:1000800000000038000D0012000000040000E8B479
-:1000900000000038000D0014000000040000E8B665
-:1000A00000000038000D0016000000040000E854B5
-:1000B00000000038000D0018000000040000E855A2
-:1000C00000000038000D001A000000040000E8568F
-:1000D00000000038000D001C000000040000E8577C
-:1000E00000000038000D001E000000040000E8249D
-:1000F00000000038000D0020000000040000E8258A
-:1001000000000038000D0022000000040000E8306C
-:1001100000000038000D0024000000040000F0C0C2
-:1001200000000038000D0026000000040000F0C1AF
-:1001300000000038000D0028000000040000F0411D
-:1001400000000038000D002A000000040000F184C7
-:1001500000000038000D002C000000040000F185B4
-:1001600000000038000D002E000000040000F186A1
-:1001700000000038000D0030000000040000F1878E
-:1001800000000038000D0032000000040000F18083
-:1001900000000038000D0034000000040000F3935C
-:1001A00000000038000D0036000000040000F38A53
-:1001B00000000038000D0038000000040000F38E3D
-:1001C000000000040000E821000000040140A0003D
-:1001D00000000018000000430000000400CCE8000C
-:1001E00000000004001B000100000004080048009B
-:1001F00000000004001B000100000004080048008B
-:1002000000000004001B000100000004080048007A
-:10021000000000080000003A000000000000A000FC
-:10022000000000042000451D000000040000E580DF
-:1002300000000004000CE581000000040800458077
-:1002400000000004000CE5810000000800000047E9
-:10025000000000000000A00000000004000C2000CE
-:10026000000000040000E50E000000040003200070
-:10027000000000280002205100000024000000516E
-:10028000000000040800450F000000080000A04B1B
-:10029000000000040000E565000000040000E566C1
-:1002A00000000008000000520000000403CCA5B4C8
-:1002B00000000004054320000000000400022000AC
-:1002C000000000304CCCE05E0000000408274565CB
-:1002D000000000300000005E0000000408004564DB
-:1002E000000000040000E566000000080000005562
-:1002F00000000010008020610000000400202000A9
-:1003000000000004001B00FF00000010010000645A
-:1003100000000004001F200000000004001C00FF7B
-:100320000000000C0000000000000030000000721F
-:100330000000000800000055000000040000E57601
-:10034000000000040000E577000000040000E50E56
-:10035000000000040000E50F000000040140A000C0
-:100360000000001800000069000000C200C0E5F9AC
-:100370000000000800000069000000040014E50E01
-:10038000000000040040E50F0000000800C0006C01
-:10039000000000040000E570000000040000E571AA
-:1003A0000000000C0000E572000000040000A00046
-:1003B000000000040140A000000000040000E56807
-:1003C00000000004000C200000000018000000766F
-:1003D00000000004000B00000000000418C0E562EB
-:1003E00000000008000000780000000800C000774E
-:1003F00000000004000700CB00000038000000846B
-:1004000000000030000CA08600000004080045BB7E
-:1004100000000030000C2087000000000800E5BC50
-:10042000000000040000E5BB000000000000E5BC87
-:100430000000000C00120000000000040012000088
-:100440000000000C001B0002000000040000A000DF
-:10045000000000040000E821000000000000E800A7
-:10046000000000040000E821000000000000E82E69
-:100470000000000402CCA0000000000400140000F2
-:1004800000000004000CE1CC00000004050DE1CDEB
-:10049000000000040040000000000018000000966A
-:1004A0000000000400C0A00000000008000000934D
-:1004B0000000002000000098000000004200E00062
-:1004C000000000380000009F00000004000CA000A5
-:1004D000000000040014000000000004000C2000D4
-:1004E000000000040016000000000004700CE00092
-:1004F000000000080014009B000000004000E00025
-:10050000000000040240000000000004400EE00073
-:100510000000000402400000000000004000E00075
-:100520000000002C0010000000000000000040004F
-:1005300000000004080045C8000000040024000575
-:100540000000000408004D0B00000004000C200017
-:10055000000000040240E51B000000050080E50AE1
-:10056000000000050080E50B0000000400220000F0
-:1005700000000004000700CB00000038000000B7B6
-:1005800000000030000C2087000000050880E5BD59
-:1005900000000030000C2086000000050800E5BBCC
-:1005A00000000030000C2087000000050880E5BC3A
-:1005B00000000008000000BA000000050080E5BD52
-:1005C000000000050000E5BB000000050080E5BC60
-:1005D0000000000400210000000000040280000070
-:1005E0000000001800C000BE000000404180E00094
-:1005F00000000024000000C00000000C010000000A
-:100600000000000C0100E51D00000004000045BBD7
-:1006100000000008000080BA0000000403C0083099
-:10062000000000004200E000000000040000A00004
-:1006300000000004200045E0000000000000E5E1AB
-:10064000000000000000000100000004000700C8D6
-:10065000000000000800E39400000000000000001B
-:10066000000000040000E8C4000000040000E8C529
-:10067000000000040000E8C6000000040000E928B3
-:10068000000000040000E929000000040000E92A3D
-:1006900000000008000000CC000000040000E92871
-:1006A000000000040000E929000000040000E92A1D
-:1006B00000000008000000D30000000402C0200079
-:1006C000000000040006000000000034000000DB11
-:1006D00000000008000000D80000000400008000B6
-:1006E00000000000C000E00000000030000000E159
-:1006F000000000004200E00000000030000000E1C7
-:10070000000000004000E000000000040025001B85
-:100710000000000400230000000000040025000584
-:1007200000000034000000E60000000C00000000A3
-:10073000000000040024400000000004080045C838
-:1007400000000004002400050000000C08004D0B10
-:100750000000000000000000000000000000000099
-:100760000000000000000000000000000000000089
-:100770000000000000000000000000000000000079
-:100780000000000000000000000000000000000069
-:100790000000000000000000000000000000000059
-:1007A0000000000000000000000000000000000049
-:1007B00000000004000C200000000004001D0018D0
-:1007C00000000004001A000100000034000000FBDB
-:1007D000000000080000004A000000080500A04AD0
-:1007E0000000000000000000000000000000000009
-:1007F00000000000000000000000000000000000F9
-:00000001FF
-/* production radeon ucode r1xx-r6xx */
--- zfcpdump-kernel-4.4.orig/firmware/radeon/RS780_me.bin.ihex
+++ /dev/null
@@ -1,1345 +0,0 @@
-:1000000000000000C020040000000000000000000C
-:1000100000A0000A000000000000FFFF00284621A9
-:100020000000000000000000D900480000000000AF
-:1000300000000000C02004000000000000000000DC
-:1000400000A0000A000000000000000000E0000026
-:100050000000000000010000C02946200000000050
-:1000600000000000D900480000000000000000006F
-:10007000C0200400000000000000000000A0000AF2
-:10008000000000008100000000204411000000007A
-:1000900000000001002048110000000000042004BE
-:1000A0000060441100000622000000000060000013
-:1000B000000005D10000000000600000000005DE27
-:1000C00000000000C02008000000000000000F0039
-:1000D000002816220000000000000008002116255C
-:1000E000000000000000001800203625000000007D
-:1000F0008D000000002044110000000000000004FA
-:10010000002F022500000000000000000CE00000AD
-:1001100000000018004120000040481100000019B4
-:100120000042200000204811000000008E00000066
-:1001300000204411000000000000002800204A2D8B
-:1001400000000000900000000020441100000000AA
-:100150000000000000204805000000000000000C26
-:1001600000211622000000000000000300281625D0
-:10017000000000000000001900211A220000000009
-:100180000000000400281A26000000000000000003
-:10019000002914C5000000000000001900203625C9
-:1001A0000000000000000000003A140200000000FF
-:1001B00000000016002116250000000000000003CA
-:1001C00000281625000000000000001700200E2D5A
-:1001D00000000000FFFFFFFC00280E2300000000CD
-:1001E00000000000002914A3000000000000001718
-:1001F00000203625000000000000800000280E22AC
-:10020000000000000000000700220E230000000094
-:10021000000000000029386E0000000020000000EF
-:1002200000280E22000000000000000600210E231E
-:1002300000000000000000000029386E00000000EF
-:100240000000000000220222000000000000000068
-:1002500014E0000000000038000000002EE0000064
-:1002600000000035000000002CE000000000003716
-:100270000000000000400E2D0000003900000008C2
-:1002800000200E2D00000000000000090040122D8B
-:10029000000000460000000100400E2D0000003963
-:1002A00000000000C0200C0000000000003FFFFC28
-:1002B0000028122300000000000000020022122487
-:1002C000000000000000001F00211E2300000000AD
-:1002D0000000000014E000000000003E00000008E4
-:1002E00000401C11000000410000000D00201E2DE8
-:1002F000000000000000000F00281E270000000082
-:100300000000000300221E27000000007FC0000044
-:1003100000281A23000000000000001400211A2603
-:10032000000000000000000100331A260000000059
-:100330000000000800221A26000000000000000053
-:1003400000290CC700000000000000270020362410
-:100350000000000000007F000028122100000000C3
-:1003600000001400002F0224000000000000000024
-:100370000CE000000000004B0000000100290E23EB
-:10038000000000000000000E0020362300000000E6
-:100390000000E0000020441100000000FFF8000011
-:1003A00000294A230000000000000000003A2C024F
-:1003B000000000000000000200220E2B00000000E0
-:1003C000FC00000000280E23000000000000000FC9
-:1003D000002036230000000000001FFF00294A23F0
-:1003E000000000000000002700204A2D000000004F
-:1003F000000000000020481100000000000000295B
-:1004000000200E2D00000000060A020000294A23E9
-:100410000000000000000000002048110000000063
-:100420000000000000204811000000000000000152
-:1004300000210222000000000000000014E0000083
-:1004400000000061000000002EE000000000005FDE
-:10045000000000002CE000000000005E0000000032
-:1004600000400E2D000000620000000100400E2D33
-:10047000000000620000000A00200E2D00000000B5
-:100480000000000B0040122D0000006A0000000078
-:10049000C0200C0000000000003FFFFC00281223D9
-:1004A00000000000000000020022122400000000F2
-:1004B0007FC0000000281623000000000000001488
-:1004C0000021162500000000000000010033162561
-:1004D000000000008000000000280E230000000043
-:1004E0000000000000290CA3000000003FFFFC00FA
-:1004F00000290E23000000000000001F00211E2321
-:10050000000000000000000014E000000000006D8A
-:100510000000010000401C11000000700000000DF0
-:1005200000201E2D00000000000000F000281E2703
-:10053000000000000000000400221E270000000050
-:100540008100000000204411000000000000000DA8
-:100550000020481100000000FFFFF0FF00281A30C3
-:10056000000000000000A02800204411000000004E
-:1005700000000000002948E6000000000000A0186C
-:1005800000204411000000003FFFFFFF00284A2325
-:10059000000000000000A010002044110000000036
-:1005A00000000000002048040000000000000030AF
-:1005B0000020162D00000000000000020029162572
-:1005C0000000000000000030002036250000000080
-:1005D000000000250020162D000000000000000093
-:1005E000002F00A300000000000000000CC000006D
-:1005F00000000083000000260020162D00000000EF
-:1006000000000000002F00A4000000000000000017
-:100610000CC000000000008400000000004000004A
-:100620000000008A000000250020362300000000A2
-:100630000000002600203624000000000000001703
-:1006400000201E2D000000000000000200210227F3
-:10065000000000000000000014E000000000008A1C
-:100660000000000000600000000005FF0000000026
-:1006700000600000000005F30000000200210E22CF
-:10068000000000000000000014C000000000008D09
-:1006900000000012C040362000000093000000005F
-:1006A0002EE0000000000091000000002CE000009F
-:1006B000000000900000000200400E2D000000929B
-:1006C0000000000300400E2D000000920000000C0E
-:1006D00000200E2D00000000000000120020362334
-:1006E000000000000000000300210E2200000000B6
-:1006F0000000000014C00000000000980000A00CE2
-:10070000002044110000000000000000C02048004C
-:100710000000000000000000C0404800000000A0F1
-:100720000000A00C002044110000000000000000A8
-:100730000020481100000000000000002EE0000032
-:100740000000009E000000002CE000000000009D62
-:100750000000000200400E2D0000009F000000037A
-:1007600000400E2D0000009F0000000C00200E2D08
-:10077000000000000000000000204803000000000E
-:1007800000000000003A0C0200000000003F0000E2
-:1007900000280E23000000000000001000210E239E
-:1007A00000000000000000110020362300000000BF
-:1007B0000000001E0021022B0000000000000000CD
-:1007C00014C00000000000A700000016C020362062
-:1007D000000000000000001F0021022B00000000AC
-:1007E0000000000014C00000000000AA0000001576
-:1007F000C0203620000000000000000800210E2B61
-:10080000000000000000007F00280E230000000010
-:1008100000000000002F0223000000000000000084
-:100820000CE00000000000E10000000027000000D4
-:10083000000000000000000000600000000002A3B3
-:1008400000000001002F0223000000000000000053
-:100850000AE00000000000B300000000006000009B
-:100860000000013A81000000002044110000000057
-:100870000000000600204811000000000000000CED
-:1008800000221E300000000099800000002044116A
-:1008900000000000000000040020122D00000000F5
-:1008A00000000008002212240000000000000010D8
-:1008B00000201811000000000000000000291CE4C6
-:1008C0000000000000000000006048070000012F49
-:1008D0009B00000000204411000000000000000008
-:1008E00000204802000000009C000000002044118D
-:1008F00000000000000000000033146F0000000042
-:100900000000000100333E23000000000000000052
-:10091000D9004800000000000000000000203C0555
-:1009200000000000810000000020441100000000D1
-:100930000000000E00204811000000000000000030
-:1009400000201010000000000000E007002044110B
-:10095000000000000000000F0021022B000000003A
-:100960000000000014C00000000000CB00F8FF08E9
-:1009700000204811000000009800000000404811CD
-:10098000000000DC000000F000280E220000000043
-:10099000000000A0002F0223000000000000000063
-:1009A0000CC00000000000DA0000001100200E2D35
-:1009B0000000000000000001002F022300000000E2
-:1009C000000000000CE00000000000D50000000264
-:1009D000002F022300000000000000000CE00000D7
-:1009E000000000D400003F0000400C11000000D6C1
-:1009F00000001F0000400C11000000D600000F0096
-:100A000000200C11000000000038000900294A23D2
-:100A1000000000003F00000000280E2B0000000036
-:100A20000000000200220E2300000000000000076A
-:100A300000494A23000000DC00380F09002048115B
-:100A400000000000680000070020481100000000BE
-:100A50000000000800214A270000000000000000FC
-:100A60000020481100000000060A020000294A2464
-:100A700000000000000000000020481100000000FD
-:100A80000000000000204811000000000000A20249
-:100A9000002044110000000000FF000000280E228A
-:100AA000000000000000008000294A230000000030
-:100AB0000000002700200E2D00000000000000268E
-:100AC0000020122D0000000000000000002F008315
-:100AD00000000000000000000CE00000000000EA40
-:100AE0000000000000600000000005F900000000A8
-:100AF00000400000000000EB00000000006000006B
-:100B0000000005FC000000070020222D000000006E
-:100B10000000000500220E2200000000001000006E
-:100B200000280E23000000000000000000292068BB
-:100B30000000000000000000003A0C02000000006D
-:100B4000000000EF00280E2300000000000000005D
-:100B500000292068000000000000001700200E2D72
-:100B6000000000000000000300210223000000003C
-:100B70000000000014E00000000000F80000000B7E
-:100B800000210228000000000000000014C0000046
-:100B9000000000F8000004000029222800000000E6
-:100BA0000000001400203628000000000000001C97
-:100BB00000210E22000000000000000014C0000010
-:100BC000000000FD0000A30C002044110000000004
-:100BD0000000000000204811000000000000001E7E
-:100BE00000210E22000000000000000014C00000E0
-:100BF0000000010B0000A30F0020441100000000C2
-:100C00000000001100200E2D000000000000000177
-:100C1000002F022300000000000000000CC00000B4
-:100C200000000104FFFFFFFF004048110000010B1E
-:100C300000000002002F022300000000000000005E
-:100C40000CC00000000001070000FFFF0040481139
-:100C50000000010B00000004002F02230000000030
-:100C6000000000000CC000000000010A000000FFAE
-:100C7000004048110000010B000000010020481155
-:100C8000000000000002C400002044110000000029
-:100C90000000001F00210E220000000000000000E4
-:100CA00014C00000000001120000001040210E20BE
-:100CB00000000000000000130020362300000000A8
-:100CC0000000001840224A20000000000000001030
-:100CD000C0424A20000001140000000000200C1156
-:100CE0000000000000000013002036230000000078
-:100CF000000000000020481100000000000000007B
-:100D000000204811000000000000000A002010111F
-:100D10000000000000000000002F0224000000007E
-:100D2000000000000CE000000000011B00000000BB
-:100D300000204811000000000000000100531224B0
-:100D400000000117FFBFFFFF00283A2E000000003F
-:100D50000000001B00210222000000000000000033
-:100D600014C000000000012E81000000002044118A
-:100D7000000000000000000D0020481100000000ED
-:100D80000000001800220E3000000000FC000000EF
-:100D900000280E2300000000810000000020441104
-:100DA000000000000000000E0020481100000000BC
-:100DB0000000000000201010000000000000E00E05
-:100DC000002044110000000007F8FF08002048112F
-:100DD000000000000000000000294A23000000007D
-:100DE0000000001C00201E2D000000000000000874
-:100DF00000214A27000000000000000000204811E8
-:100E000000000000060A020000294A240000000039
-:100E10000000000000204811000000000000000059
-:100E200000204811000000000000000000800000C9
-:100E300000000000810000000020441100000000BC
-:100E40000000000100204811000000000000217C8B
-:100E50000020441100000000008000000020481124
-:100E60000000000000000000002048060000000014
-:100E70000000000800214A270000000000000000D8
-:100E800017000000000000000004217F00604411F2
-:100E9000000006220000001F0021023000000000B8
-:100EA0000000000014C00000000006210000000443
-:100EB00000404C1100000135810000000020441169
-:100EC00000000000000000010020481100000000A8
-:100ED000000021F800204411000000000000001C68
-:100EE0000020481100000000000421F900604411B6
-:100EF0000000062200000011002102300000000066
-:100F00000000000014E000000000013C00000000B0
-:100F100000800000000000000000000000600000F1
-:100F20000000000B00000000006004110000031529
-:100F3000000000000020041100000000000000007C
-:100F400000600811000001B2000000000060000015
-:100F5000000001600000FFFF40280E20000000009C
-:100F600000000010C0211220000000000000FFFF60
-:100F7000402806200000000000000010C0210A20C8
-:100F800000000000000000000034146100000000B8
-:100F90000000000000741882000002BB0001A1FDE7
-:100FA00000604411000002E000003FFF002F022F0C
-:100FB00000000000000000000CC00000000001471D
-:100FC00000000000C040040000000001000000001C
-:100FD000006000000000000B000000000060041131
-:100FE00000000315000000000020041100000000B4
-:100FF0000000000000600811000001B200003FFF87
-:10100000002F022F00000000000000000CE0000094
-:10101000000000000000000000600000000001600F
-:101020000000001040210E20000000000000FFFF23
-:10103000C0281220000000000000001040211620EF
-:10104000000000000000FFFFC0681A20000002BB83
-:101050000001A1FD00604411000002E000003FFF1C
-:10106000002F022F00000000000000000CC0000054
-:101070000000015800000000C04004000000000112
-:101080000000225C0020441100000000000000016C
-:1010900000300A2F000000000000000100210A2299
-:1010A000000000000000000300384A220000000099
-:1010B0000000225600204411000000000000001A29
-:1010C00000204811000000000000A1FC0020441195
-:1010D0000000000000000001008048110000000036
-:1010E00000000000006000000000000B0000000095
-:1010F000006000000000018F0000000000600000A0
-:10110000000001A000003FFF002F022F00000000A0
-:10111000000000000CE000000000000000000000E3
-:1011200000202C0800000000000000000020241116
-:101130000000000000000000002028110000000056
-:10114000000022560020441100000000000000169C
-:1011500000204811000000000000225C0020441123
-:101160000000000000000003002048110000000003
-:1011700093800000002044110000000000000002E5
-:1011800000221E290000000000000000007048EB53
-:101190000000019C0000000000600000000002BB95
-:1011A00000000001403306200000000000000000A5
-:1011B000C03024090000000000003FFF002F022F74
-:1011C00000000000000000000CE000000000000033
-:1011D0000000000000600000000002A3000000000A
-:1011E000002F022100000000000000000AE00000C3
-:1011F0000000018100000000006000000000013AD2
-:101200000000000000400000000001869500000082
-:10121000002044110000000000000000002F022107
-:1012200000000000000000000CE00000000001864B
-:1012300000000000C0204800000000000000000185
-:10124000005306210000018292000000002044119A
-:101250000000000000000000C0604800000001978E
-:101260000001A1FD00204411000000000000001159
-:101270000020062D00000000000000000078042A75
-:10128000000002FB00000000002028090000000010
-:1012900000003FFF002F022F0000000000000000B0
-:1012A0000CC000000000017400000000C0400400F9
-:1012B000000000010000021000600411000003158E
-:1012C00000003FFF002F022F000000000000000080
-:1012D0000CE000000000019400000015C020362042
-:1012E0000000000000000016C020362000000000B2
-:1012F0003F800000002004110000000046000000B4
-:1013000000600811000001B2000000000080000031
-:10131000000000000000A1FC0020441100000000BB
-:1013200000003FFF002F022F00000000000000001F
-:101330000CC000000000019B00000001008048116B
-:1013400000000000000000210080481100000000A3
-:101350000000FFFF40280E200000000000000010E9
-:10136000C0211220000000000000FFFF40281620CE
-:101370000000000000000010C0811A2000000000E2
-:101380008100000000204411000000000000000661
-:1013900000204811000000000000000800221E305C
-:1013A000000000000000002900201A2D00000000AD
-:1013B0000000E0000020441100000000FFFBFF09D6
-:1013C00000204811000000000000000F0020222D26
-:1013D0000000000000001FFF00294A280000000054
-:1013E000000000060020222D000000000000000088
-:1013F000002920E80000000000000000002048084C
-:101400000000000000000000002048110000000063
-:10141000060A020000294A26000000000000000021
-:1014200000204811000000000000000000204811CA
-:101430000000000000000100002018110000000062
-:101440000000000800621E280000012F00000008B4
-:1014500000822228000000000002C0000020441189
-:10146000000000000000001500600E2D000001BD0E
-:101470000000001600600E2D000001BD0000C00835
-:1014800000204411000000000000001700200E2D75
-:10149000000000000000000014C00000000001B9BE
-:1014A0000000000000200411000000000000000007
-:1014B0000020480100000000390000000020481111
-:1014C00000000000000000000020481100000000A3
-:1014D000000000000080480200000000000000182A
-:1014E00000202E2D0000000000000000003B0D63D6
-:1014F000000000000000000800224A230000000055
-:101500000000001000224A23000000000000001824
-:1015100000224A2300000000000000000080480371
-:101520000000000000000000006000000000000B50
-:10153000000010000060041100000315000000000E
-:1015400000200411000000000000000000600811ED
-:10155000000001B2000000070021062F000000007B
-:101560000000001300200A2D000000000000000110
-:1015700000202C11000000000000FFFF4028222066
-:10158000000000000000000F0026222800000000DC
-:101590000000001040212620000000000000000F85
-:1015A000002626290000000000000000002028027C
-:1015B000000000000000225600204411000000003E
-:1015C0000000001B00204811000000000000000087
-:1015D000002F022100000000000000000CE00000CD
-:1015E000000001E00000225C002044110000000027
-:1015F0000000008100204811000000000000A1FC54
-:1016000000204411000000000000000100204811EB
-:10161000000000000000008000201C1100000000FD
-:1016200000000000002F0227000000000000000062
-:101630000CE00000000001DC000000000060000081
-:10164000000001E90000000100531E27000001D83E
-:101650000000000100202C11000000000000001F0D
-:1016600000280A22000000000000001F00282A2A8B
-:10167000000000000000000100530621000001D11D
-:101680000000225C00204411000000000000000265
-:1016900000304A2F000000000000A1FC002044118F
-:1016A00000000000000000010020481100000000C0
-:1016B0000000000100301E2F0000000000000000AC
-:1016C000002F022700000000000000000CE00000D6
-:1016D000000000000000000000600000000001E9C0
-:1016E0000000000100531E27000001E50000FFFF7D
-:1016F00040280E20000000000000000F00260E23EE
-:101700000000000000000010C021122000000000B6
-:101710000000000F0026122400000000000000005E
-:1017200000201411000000000000000000601811EB
-:10173000000002BB0001A1FD0020441100000000D8
-:1017400000000000002F022B00000000000000003D
-:101750000CE00000000001F8000000100022162834
-:1017600000000000FFFF0000002816250000000018
-:101770000000FFFF00281A29000000000000000000
-:10178000002948C500000000000000000020480AB1
-:10179000000000000000000000202C1100000000EC
-:1017A000000000100022162300000000FFFF0000D0
-:1017B00000281625000000000000FFFF00281A2462
-:1017C0000000000000000000002948C500000000E3
-:1017D0000000000000731503000002050000000077
-:1017E0000020180500000000000000000073152410
-:1017F0000000020500000000002D14C500000000DC
-:1018000000000000003008A20000000000000000FE
-:101810000020480200000000000000000020280214
-:101820000000000000000000002020030000000075
-:101830000000000000802404000000000000000FF1
-:1018400000210225000000000000000014C000007C
-:101850000000062100000000002B1405000000001D
-:1018600000000001009016250000000000000000AC
-:10187000006000000000000B000000000060041188
-:10188000000003150000000000200411000000000B
-:101890000000000000600811000001B200002256A4
-:1018A00000204411000000000000001A00294A2214
-:1018B0000000000000000000C02000000000000048
-:1018C00000003FFF002F022F00000000000000007A
-:1018D0000CE000000000000000000000C020040038
-:1018E000000000000000225C002044110000000005
-:1018F0000000000300384A21000000000000A1FCA5
-:1019000000204411000000000000000100204811E8
-:10191000000000000000FFFF40281220000000002F
-:1019200000000010C0211A20000000000000FFFF8E
-:1019300040280E200000000000000010C0211620EA
-:10194000000000000000000000741465000002BBED
-:101950000001A1FD00604411000002E00000000150
-:10196000003306210000000000000000002F0221CB
-:1019700000000000000000000CC000000000021980
-:1019800000003FFF002F022F0000000000000000B9
-:101990000CC000000000021200000000C040040063
-:1019A000000000010000000000600000000005DEF3
-:1019B000000000000040040F0000021300000000BF
-:1019C00000600000000005D1000000000060000081
-:1019D000000005DE00000210006004110000031585
-:1019E0000000000000600000000001A000000000F6
-:1019F000006000000000019C00000000006000008A
-:101A0000000002BB0000000000600000000002A314
-:101A1000938000000020441100000000000000003E
-:101A2000002048080000000000000000002F022FE6
-:101A300000000000000000000AE000000000023288
-:101A400000000000006000000000013A00000000FB
-:101A50000040000000000236950000000020441104
-:101A60000000000000000000002F022F0000000016
-:101A7000000000000CE00000000002360000000042
-:101A8000C0404800000002339200000000204411D2
-:101A90000000000000000000C0204800000000001E
-:101AA0000000225600204411000000000000001633
-:101AB00000204811000000000000225C00204411BA
-:101AC000000000000000000300204811000000009A
-:101AD0000000A1FC002044110000000000000001F3
-:101AE00000204811000000000001A1FD0020441169
-:101AF000000000000000000000600411000002FB74
-:101B000000000000C04004000000000100000000D0
-:101B100000600000000005D10000A00C002044116E
-:101B20000000000000000000C0204800000000008D
-:101B300000000000C040480000000000000000005D
-:101B4000006000000000000B0000001840210A2087
-:101B50000000000000000003002F0222000000002F
-:101B6000000000000AE000000000024C0000001429
-:101B70000020222D00000000000801010029222879
-:101B800000000000000000140020362800000000C3
-:101B90000000A30C00204411000000000000000021
-:101BA000C02048000000000000000000C0204800E5
-:101BB0000000000000000000C0404800000002518A
-:101BC00000000000006000000000000B000000109A
-:101BD00000600411000003153F8000000020041184
-:101BE000000000000000000000600811000001B2C9
-:101BF0000000225C002044110000000000000003EF
-:101C000000204811000000000000000000600000FB
-:101C10000000027C0000001700201E2D00000000C4
-:101C20000000000100211E2700000000000000004D
-:101C300014E000000000026A0000001200201E2DC7
-:101C4000000000000000FFFF00281E270000000029
-:101C50000000000000341C2700000000000000000D
-:101C600012C000000000025F0000000000201C11F4
-:101C70000000000000000000002F00E50000000050
-:101C80000000000008C00000000002620000000028
-:101C900000201407000000000000001200201E2D8C
-:101CA000000000000000001000211E2700000000BE
-:101CB0000000000000341C4700000000000000008D
-:101CC00012C00000000002670000000000201C118C
-:101CD0000000000000000000002F00E600000000EF
-:101CE0000000000008C000000000026A00000000C0
-:101CF0000020180700000000000000000060000045
-:101D0000000002C100002256002044110000000023
-:101D1000000000000034202300000000000000004C
-:101D200012C00000000002720000000000342044D5
-:101D3000000000000000000012C00000000002715E
-:101D40000000001600404811000002760000001854
-:101D500000404811000002760000000000342044DA
-:101D6000000000000000000012C00000000002752A
-:101D70000000001700404811000002760000001922
-:101D800000204811000000000000A1FC00204411C8
-:101D900000000000000000010020481100000000C9
-:101DA0000001A1FD00604411000002E900003FFFB6
-:101DB000002F022F00000000000000000CC00000F7
-:101DC0000000025600000000C040040000000001B6
-:101DD0000000001040210620000000000000FFFF6E
-:101DE000C0280A20000000000000001040210E2042
-:101DF000000000000000FFFFC028122000000000CB
-:101E00000000001040211620000000000000FFFF2D
-:101E1000C0881A200000000081000000002044114A
-:101E20000000000000000001002048110000000038
-:101E3000000420040060441100000622000000009D
-:101E400000600000000005D100000000C06000003C
-:101E5000000002A30000000500200A2D0000000081
-:101E60000000000800220A22000000000000002BF1
-:101E700000201A2D000000000000001C00201E2D74
-:101E8000000000000000700000281E270000000075
-:101E90000000000000311CE6000000000000002AE5
-:101EA00000201A2D000000000000000C00221A265D
-:101EB0000000000000000000002F00E6000000000D
-:101EC0000000000006E00000000002920000000098
-:101ED00000201C11000000000000000000200C1178
-:101EE000000000000000002B00203623000000004E
-:101EF0000000001000201811000000000000000089
-:101F000000691CE20000012F9380000000204411B2
-:101F10000000000000000000002048070000000052
-:101F200095000000002044110000000000000000A7
-:101F3000002F022F00000000000000000CE0000055
-:101F40000000029D0000000100333E2F0000000051
-:101F500000000000D90048000000000092000000CE
-:101F6000002044110000000000000000C0204800D4
-:101F7000000000000000001C0040362700000000A8
-:101F80000000000CC0220A20000000000000002910
-:101F9000002036220000000000000028C04036204B
-:101FA000000000000000A2A4002044110000000076
-:101FB000000000090020481100000000A1000000FE
-:101FC00000204411000000000000000100804811C2
-:101FD000000000000000002100201E2D0000000075
-:101FE00000000000002C1CE30000000000000021A5
-:101FF00000203627000000000000002200201E2DD7
-:102000000000000000000000002C1CE400000000A4
-:1020100000000022002036270000000000000023FE
-:1020200000201E2D0000000000000000003120A351
-:102030000000000000000000002D1D07000000004F
-:1020400000000023002036270000000000000024CC
-:1020500000201E2D0000000000000000003120C400
-:102060000000000000000000002D1D07000000001F
-:10207000000000240080362700000000000000213E
-:10208000002036230000000000000022002036243B
-:10209000000000000000000000311CA30000000050
-:1020A0000000002300203627000000000000000090
-:1020B00000311CC40000000000000024008036270E
-:1020C000000000000000001A002036270000000079
-:1020D0000000001B00203628000000000000001750
-:1020E00000201E2D00000000000000020021022739
-:1020F000000000000000000014C00000000002DC2E
-:102100000000000000400000000002D90000001A9A
-:1021100000203627000000000000001B00203628A9
-:10212000000000000000001700201E2D000000002D
-:102130000000000200210227000000000000000053
-:1021400014E00000000002D9000000030021022773
-:10215000000000000000000014E00000000002DCAD
-:102160000000002300201E2D0000000000000000E1
-:10217000002E00E1000000000000000002C000008E
-:10218000000002DC0000002100201E2D00000000E5
-:1021900000000000003120A100000000000000004D
-:1021A000002E00E8000000000000000006C0000053
-:1021B000000002DC0000002400201E2D00000000B2
-:1021C00000000000002E00E20000000000000000FF
-:1021D00002C00000000002DC0000002200201E2DD2
-:1021E0000000000000000000003120C200000000DC
-:1021F00000000000002E00E80000000000000000C9
-:1022000006C00000000002DC0000000000600000CA
-:10221000000005FF0000000000600000000002B5A3
-:102220000000000000400000000002DE000000008E
-:1022300000600000000002B5000000000060000027
-:10224000000005F60000000000400000000002DE73
-:102250000000000000600000000002A70000000075
-:1022600000400000000002DE0000001A00201E2DC9
-:10227000000000000000001B0080222D0000000074
-:102280000000001000221E230000000000000000DB
-:1022900000294887000000000000000000311CA356
-:1022A000000000000000001000221E2700000000B7
-:1022B0000000000000294887000000000000001016
-:1022C00000221E230000000000000000003120C496
-:1022D000000000000000FFFF00282228000000008E
-:1022E0000000000000894907000000000000001005
-:1022F00000221E2300000000000000000029488783
-:10230000000000000000001000221E21000000005C
-:102310000000000000294847000000000000000005
-:1023200000311CA3000000000000001000221E2746
-:1023300000000000000000000029488700000000A5
-:102340000000000000311CA100000000000000108F
-:1023500000221E270000000000000000002948475E
-:10236000000000000000001000221E2300000000FA
-:1023700000000000003120C4000000000000FFFF4A
-:102380000028222800000000000000000029490762
-:10239000000000000000001000221E2100000000CC
-:1023A00000000000003120C2000000000000FFFF1C
-:1023B00000282228000000000000000000894907D2
-:1023C000000000000000001000221E23000000009A
-:1023D0000000000000294887000000000000000104
-:1023E00000220A210000000000000000003308A2C3
-:1023F000000000000000001000221E22000000006B
-:102400000000001000212222000000000000000057
-:1024100000294907000000000000000000311CA353
-:10242000000000000000001000221E270000000035
-:1024300000000000002948870000000000000001A3
-:1024400000220A210000000000000000003008A265
-:10245000000000000000001000221E22000000000A
-:1024600000000010002122220000000000000000F7
-:1024700000294907000000000000001000221E2370
-:102480000000000000000000003120C40000000037
-:102490000000FFFF002822280000000000000000CC
-:1024A000002949070000000000000000003808C5AE
-:1024B00000000000000000000030084100000000A3
-:1024C0000000000100220A220000000000000000BD
-:1024D000003308A2000000000000001000221E22AD
-:1024E0000000000000000010002122220000000077
-:1024F00000000000008949070000000000000017EC
-:102500000020222D000000000000000014C0000088
-:1025100000000318FFFFFFEF002806210000000065
-:10252000000000140020222D000000000000F8E050
-:1025300000204411000000000000000000294901B3
-:1025400000000000000000000089490100000000B8
-:102550000000000000204811000000000000000002
-:102560000020481100000000060A02000080481107
-:102570000000000000000000C0200000000000007B
-:1025800097000000C020441100000000000000007F
-:10259000C0204811000000008A0000000020441103
-:1025A00000000000000000000020481100000000B2
-:1025B0000000225C00204411000000000000000028
-:1025C000C0204800000000000000A1FC00204411D1
-:1025D0000000000000000000C020480000000000D3
-:1025E00000000000C0200400000000000000000007
-:1025F00000A0000A0000000097000000C020441165
-:102600000000000000000000C02048110000000091
-:102610008A000000C02044110000000000000000FB
-:1026200000204811000000000000225C002044113E
-:102630000000000000000000C02048000000000072
-:102640000000A1FC00204411000000000000000078
-:10265000C02048000000000000000000C02004006E
-:10266000000000000000000000A0000A00000000C0
-:10267000970000000020441100000000000000004E
-:1026800000204811000000008A00000000204411D2
-:1026900000000000000000000020481100000000C1
-:1026A0000000225C00204411000000000000000037
-:1026B000C0204800000000000000A1FC00204411E0
-:1026C0000000000000000000C020480000000000E2
-:1026D00000000000C0200400000000000000000016
-:1026E00000A0000A00000000970000000020441134
-:1026F0000000000000000000002048110000000061
-:102700008A000000002044110000000000000000CA
-:1027100000204811000000000000225C002044114D
-:102720000000000000000000C02048000000000081
-:102730000000A1FC00204411000000000000000087
-:10274000C0204800000000000001A1FD002044114D
-:102750000000000000000000D90048000000000058
-:1027600000000000C0200400000000000000000085
-:1027700000A0000A000000000000225700204411C1
-:102780000000000000000003C0484A2000000000D4
-:102790000000225D00204411000000000000000045
-:1027A000C040480000000000000000000060000081
-:1027B000000005DE00000000C0200800000000004E
-:1027C0000000225C00204411000000000000000313
-:1027D00000384A22000000000000A1FC0020441143
-:1027E0000000000000000000C020480000000000C1
-:1027F0000001A1FD002044110000000000000000C5
-:10280000002F022200000000000000000CE0000089
-:102810000000000000000000402048000000000010
-:102820000000000140304A200000000000000002CB
-:10283000C0304A20000000000000000100530A22BE
-:10284000000003550000003FC0280A2000000000DF
-:102850008100000000204411000000000000000181
-:102860000020481100000000000021F80020441161
-:1028700000000000000000180020481100000000C7
-:10288000000421F90060441100000622000000113C
-:1028900000210230000000000000000014E00000F1
-:1028A0000000035E00000014002F02220000000060
-:1028B000000000000CC000000000036C0001A2A496
-:1028C00000204411000000000000000000604802E9
-:1028D00000000374000021000020441100000000EB
-:1028E00000000000C02048000000000000000000C0
-:1028F000C02048000000000000000000C020480088
-:102900000000000000000000C0404800000000007F
-:1029100000000004002F0222000000000000000060
-:102920000CC00000000003700001A2A400204411AC
-:1029300000000000000000000040480200000367A3
-:1029400000000028002F022200000000000000000C
-:102950000CC00000000005BA0001A2A40020441130
-:102960000000000000000000004048020000036773
-:102970000000002C00203626000000000000004966
-:1029800000201811000000000000003F0020481146
-:10299000000000000000000100331A2600000000C3
-:1029A00000000000002F02260000000000000000D0
-:1029B0000CC00000000003760000002C00801A2DDF
-:1029C000000000000000003FC0280A2000000000B6
-:1029D00000000015002F022200000000000000008F
-:1029E0000CE000000000038C00000006002F022213
-:1029F00000000000000000000CE00000000003B731
-:102A000000000016002F022200000000000000005D
-:102A10000CE00000000003B900000020002F02229B
-:102A200000000000000000000CE00000000003A215
-:102A30000000000F002F0222000000000000000034
-:102A40000CE00000000003AE00000010002F022286
-:102A500000000000000000000CE00000000003AED9
-:102A60000000001E002F02220000000000000000F5
-:102A70000CE00000000003960000A2A40020441116
-:102A800000000000000000000040480200000000BC
-:102A90000800000000290A220000000000000003D6
-:102AA00040210E20000000000000000CC021122078
-:102AB00000000000000800000028122400000000B0
-:102AC00000000014C02216200000000000000000DA
-:102AD000002914A4000000000000A2A4002044115A
-:102AE0000000000000000000002948A200000000D3
-:102AF0000000A1FE002044110000000000000000C2
-:102B00000040480300000000810000000020441144
-:102B1000000000000000000100204811000000003B
-:102B2000000021F800204411000000000000001601
-:102B30000020481100000000000421F90060441149
-:102B400000000622000000150021023000000000F5
-:102B50000000000014E00000000003980000210EB7
-:102B6000002044110000000000000000C0204800C8
-:102B70000000000000000000C0204800000000002D
-:102B80000000A2A40020441100000000000000008A
-:102B900000404802000000008100000000204411B5
-:102BA00000000000000000010020481100000000AB
-:102BB000000021F800204411000000000000001770
-:102BC0000020481100000000000421F900604411B9
-:102BD0000000062200000003002102300000000077
-:102BE0000000000014E00000000003A40000210821
-:102BF000002044110000000000000000C020480038
-:102C00000000000000000000C0204800000000009C
-:102C10000000A2A4002044110000000000000000F9
-:102C200000404802000000000000A2A4002044115F
-:102C3000000000000000000000204802000000002A
-:102C4000800000000020441100000000000000008F
-:102C50000020481100000000810000000020441105
-:102C600000000000000000100020481100000000DB
-:102C70000000000000200010000000000000000024
-:102C800014C00000000003B4000000000040000079
-:102C9000000000000001A2A4002044110000000078
-:102CA0000000000600404811000000000001A2A43E
-:102CB00000204411000000000000001600604811D0
-:102CC000000003740000000000400000000000004D
-:102CD00000000000C020080000000000000000000C
-:102CE000C0200C00000000000000001D0021022395
-:102CF000000000000000000014E00000000003CE0F
-:102D000081000000002044110000000000000001CC
-:102D10000020481100000000000021F800204411AC
-:102D20000000000000000018002048110000000012
-:102D3000000421F900604411000006220000001187
-:102D400000210230000000000000000014E000003C
-:102D5000000003C200002100002044110000000018
-:102D600000000000002048020000000000000000F9
-:102D70000020480300000000BABECAFE002048112F
-:102D800000000000CAFEBABE00204811000000008A
-:102D90000000A2A400204411000000000000000474
-:102DA0000040481100000000000021700020441184
-:102DB00000000000000000000020480200000000A9
-:102DC0000000000000204803000000008100000017
-:102DD00000204411000000000000000A00204811FB
-:102DE00000000000000000000020001000000000B3
-:102DF0000000000014C00000000003D38C0000009D
-:102E00000020441100000000CAFEBABE0040481174
-:102E100000000000810000000020441100000000BC
-:102E200000000001002048110000000000003FFFEA
-:102E300040280A20000000008000000040280E20EA
-:102E40000000000040000000C02812200000000028
-:102E50000004000000694622000006220000000075
-:102E6000002014100000000000000000002F0223CA
-:102E700000000000000000000CC00000000003E1A2
-:102E800000000000C0401800000003E400003FFF05
-:102E9000C0281A2000000000000400000069462637
-:102EA00000000622000000000020181000000000B2
-:102EB00000000000002F02240000000000000000BD
-:102EC0000CC00000000003E700000000C0401C0030
-:102ED000000003EA00003FFFC0281E2000000000A1
-:102EE00000040000006946270000062200000000E0
-:102EF00000201C1000000000000000000020440220
-:102F00000000000000000000002820C500000000B4
-:102F100000000000004948E800000000A580000013
-:102F200000200811000000000000200000200C110B
-:102F30000000000083000000006044110000041243
-:102F4000000000000020440200000000000000001B
-:102F5000C0204800000000000000000040204800A1
-:102F6000000000000000001FC0210220000000003F
-:102F70000000000014C00000000003F70000201053
-:102F800000204411000000000000800000204811D3
-:102F9000000000000000FFFFC0481220000003FFF7
-:102FA000A780000000200811000000000000A00021
-:102FB00000200C110000000083000000006044119C
-:102FC0000000041200000000002044020000000085
-:102FD00000000000C02048000000000000000000C9
-:102FE000C0204800000000000000FFFFC0281220A1
-:102FF00000000000830000000020441100000000D9
-:103000000000000000304883000000008400000041
-:10301000002044110000000000000000C020480013
-:1030200000000000000000001D0000000000000083
-:103030008300000000604411000004120000000042
-:10304000C040040000000001A98000000020081119
-:10305000000000000000C00000400C11000003FA56
-:10306000AB80000000200811000000000000F8E024
-:1030700000400C11000003FAAD8000000020081190
-:10308000000000000000F88000400C11000003FA6E
-:10309000B380000000200811000000000000F3FCD5
-:1030A00000400C11000003FAAF800000002008115E
-:1030B000000000000000E00000400C11000003FAD6
-:1030C000B180000000200811000000000000F000A6
-:1030D00000400C11000003FA83000000002044119E
-:1030E00000000000000021480020481100000000FE
-:1030F00084000000002044110000000000000000D7
-:10310000C020480000000000000000001D0000007A
-:10311000000000000000000000800000000000002F
-:1031200001182000C0304620000000000000000010
-:10313000D90048000000000000000000C02004008A
-:10314000000000000000000000A0000A00000000D5
-:103150000218A000C030462000000000000000005F
-:10316000D90048000000000000000000C02004005A
-:10317000000000000000000000A0000A00000000A5
-:103180000318C000C030462000000000000000000E
-:10319000D90048000000000000000000C02004002A
-:1031A000000000000000000000A0000A0000000075
-:1031B0000418F8E0C03046200000000000000000C5
-:1031C000D90048000000000000000000C0200400FA
-:1031D000000000000000000000A0000A0000000045
-:1031E0000518F880C03046200000000000000000F4
-:1031F000D90048000000000000000000C0200400CA
-:10320000000000000000000000A0000A0000000014
-:103210000618E000C030462000000000000000005A
-:10322000D90048000000000000000000C020040099
-:10323000000000000000000000A0000A00000000E4
-:103240000718F000C0304620000000000000000019
-:10325000D90048000000000000000000C020040069
-:10326000000000000000000000A0000A00000000B4
-:103270000818F3FCC03046200000000000000000E9
-:10328000D90048000000000000000000C020040039
-:10329000000000000000000000A0000A0000000084
-:1032A00000000033C0300A200000000000000000D1
-:1032B000C0403440000000000000003000200A2D13
-:1032C0000000000000000000C0290C4000000000C9
-:1032D0000000003000203623000000000000000045
-:1032E000C0200400000000000000000000A0000A50
-:1032F00000000000860000000020441100000000D3
-:1033000000000000004048010000000085000000AF
-:10331000C0204411000000000000000000404801EF
-:10332000000000000000217C00204411000000008B
-:1033300000000018402102200000000000000000F2
-:1033400014C000000000044700800000C0494A206B
-:103350000000044800000000C020480000000000F9
-:1033600000000000C0204800000000000000000035
-:10337000C02048000000000081000000002044112F
-:1033800000000000000000010020481100000000C3
-:1033900000000000C0200800000000000000000441
-:1033A000002F0222000000000000000006E00000E4
-:1033B000000004500000000400200811000000007C
-:1033C0000000000017000000000000000004217F42
-:1033D00000604411000006220000001F002102309E
-:1033E000000000000000000014C000000000000009
-:1033F0000000000000404C020000045000000000EB
-:10340000C0200C000000000000000000C0201000E0
-:103410000000000000000000C020140000000000B8
-:1034200000000000C02018000000000000000000A4
-:10343000C0201C000000000000007F0000280A21BE
-:103440000000000000004500002F022200000000E4
-:10345000000000000CE0000000000461000000001B
-:10346000C02020000000000000000004002F0228FF
-:10347000000000000000000006E000000000046101
-:1034800000000004002020110000000000000000E7
-:1034900017000000000000000000001000280A23B0
-:1034A0000000000000000010002F022200000000B9
-:1034B000000000000CE00000000004698100000032
-:1034C000002044110000000000000001002048110D
-:1034D00000000000000400000069462400000622ED
-:1034E00000000000004000000000046E81000000A9
-:1034F00000204411000000000000000000204811DE
-:10350000000000000000216D0020441100000000B8
-:10351000000000000020480400000000000000003F
-:10352000006048050000062700000000002824F085
-:10353000000000000000000700280A23000000002F
-:1035400000000001002F0222000000000000000027
-:103550000AE000000000047500000000002F00C910
-:10356000000000000000000004E000000000048EE5
-:1035700000000000004000000000049B000000026A
-:10358000002F022200000000000000000AE00000FE
-:103590000000047A00000000002F00C900000000B5
-:1035A0000000000002E000000000048E00000000A7
-:1035B000004000000000049B00000003002F0222D6
-:1035C00000000000000000000AE000000000047F8E
-:1035D00000000000002F00C90000000000000000F3
-:1035E0000CE000000000048E00000000004000001D
-:1035F0000000049B00000004002F022200000000D5
-:10360000000000000AE00000000004840000000048
-:10361000002F00C900000000000000000AE00000C8
-:103620000000048E00000000004000000000049B29
-:1036300000000005002F0222000000000000000032
-:103640000AE000000000048900000000002F00C90B
-:10365000000000000000000006E000000000048EF2
-:1036600000000000004000000000049B0000000675
-:10367000002F022200000000000000000AE000000D
-:103680000000048E00000000002F00C900000000B0
-:103690000000000008E000000000048E00000000B0
-:1036A000004000000000049B00007F0000280A2169
-:1036B0000000000000004500002F02220000000072
-:1036C000000000000AE00000000000000000000808
-:1036D00000210A23000000000000000014C00000C8
-:1036E000000004980000216900204411000000003F
-:1036F00000000000C02048000000000000000000A2
-:10370000C02048000000000000000000C020480069
-:1037100000000000CAFEBABE0040481100000000D0
-:1037200000000000C0204400000000000000000075
-:10373000C02000000000000000000000C040480061
-:103740000000000000007F0000280A2100000000A7
-:1037500000004500002F02220000000000000000D1
-:103760000AE00000000004A100000000C0200000EA
-:103770000000000000000000C02000000000000069
-:1037800000000000C0400000000000000000000039
-:1037900000404C080000046100000000C020080048
-:1037A000000000000000001040210E20000000007A
-:1037B0000000001140211220000000000000001253
-:1037C0004021162000000000000021690020441163
-:1037D000000000000000000000204802000000007F
-:1037E0000000000000210225000000000000000091
-:1037F00014E00000000004AB00040000C0494A20AF
-:10380000000004ACFFFBFFFFC0284A2000000000BE
-:103810000000000000210223000000000000000062
-:1038200014E00000000004B800000000C0204800C0
-:103830000000000000000000C02048000000000060
-:103840000000000000210224000000000000000031
-:1038500014C000000000000081000000002044119E
-:10386000000000000000000C0020481100000000D3
-:103870000000000000200010000000000000000018
-:1038800014C00000000004B4A00000000020441197
-:1038900000000000CAFEBABE00404811000000004F
-:1038A000810000000020441100000000000000041E
-:1038B00000204811000000000000216B002044118E
-:1038C0000000000000000000C020481000000000C0
-:1038D00081000000002044110000000000000005ED
-:1038E00000204811000000000000216C002044115D
-:1038F0000000000000000000C02048100000000090
-:1039000000000000002F0224000000000000000062
-:103910000CE000000000000000000000004000007B
-:10392000000004B200000000C0210A2000000000D6
-:103930000000000014C00000000004CB8100000063
-:103940000020441100000000000000000020481189
-:10395000000000000000216D002044110000000064
-:1039600000000000C020480000000000000000002F
-:10397000C060480000000627000000000040000072
-:10398000000004CF8100000000204411000000006E
-:1039900000000001002048110000000000040000A9
-:1039A000C02946200000000000000000C0600000A8
-:1039B0000000062200000001002102220000000099
-:1039C0000000000014C00000000004D600002169BF
-:1039D000002044110000000000000000C02048004A
-:1039E0000000000000000000C020480000000000AF
-:1039F000000000000020481000000000CAFEBABE0F
-:103A0000004048110000000000000000C0204400F9
-:103A10000000000000000000C0404810000000004E
-:103A2000810000000020441100000000000000019F
-:103A30000020481100000000000021F8002044117F
-:103A4000000000000000000E0020481100000000EF
-:103A5000000421F90060441100000622000000006B
-:103A600000210230000000000000000014C000002F
-:103A7000000004D800002180002044110000000054
-:103A800000000000C020480000000000000000000E
-:103A9000C02000000000000000000000C02048001E
-:103AA0000000000000000000C02000000000000036
-:103AB00000000000C04048000000000000000003BB
-:103AC00000333E2F00000000000000010021022111
-:103AD000000000000000000014E0000000000508E5
-:103AE0000000002C00200A2D00000000000400004F
-:103AF00018E00C11000004F70000000100333E2F15
-:103B000000000000000021690020441100000000B6
-:103B1000000000000020480200000000000000003B
-:103B200000204803000000000000000800300A22C6
-:103B30000000000000000000C0204800000000005D
-:103B400000000000C02048000000000000002169C3
-:103B50000020441100000000000000000020480286
-:103B600000000000000000000020480300000000EA
-:103B70000000000800300A220000000000000000E1
-:103B8000C02048000000000000000000D8C048002D
-:103B9000000004EB00002169002044110000000037
-:103BA00000000000002048020000000000000000AB
-:103BB00000204803000000000000000800300A2236
-:103BC0000000000000000000C020480000000000CD
-:103BD00000000000C0204800000000000000002D90
-:103BE0000020122D000000000000000000290C83BE
-:103BF00000000000000021690020441100000000C6
-:103C0000000000000020480200000000000000004A
-:103C100000204803000000000000000800300A22D5
-:103C20000000000000000000C0204800000000006C
-:103C300000000000C020480000000000000000114B
-:103C400000210224000000000000000014C0000059
-:103C5000000000000000000000400000000004B26E
-:103C60000000002CC0203620000000000000002DC5
-:103C7000C0403620000000000000000F002102219B
-:103C8000000000000000000014C000000000050D4E
-:103C900000000000006000000000000B00000000B9
-:103CA000D90000000000000000000000C040040037
-:103CB00000000001B50000000020441100000000D9
-:103CC000000020000020481100000000B6000000A5
-:103CD00000204411000000000000A0000020481156
-:103CE00000000000B70000000020441100000000A8
-:103CF0000000C0000020481100000000B8000000D3
-:103D000000204411000000000000F8E000204811ED
-:103D100000000000B9000000002044110000000075
-:103D20000000F8800020481100000000BA000000E8
-:103D300000204411000000000000E00000204811B5
-:103D400000000000BB000000002044110000000043
-:103D50000000F0000020481100000000BC0000003E
-:103D600000204411000000000000F3FC0020481176
-:103D7000000000008100000000204411000000004D
-:103D8000000000020020481100000000000000FFB9
-:103D900000280E300000000000000000002F022369
-:103DA00000000000000000000CC000000000052121
-:103DB00000000000C020080000000000000000001B
-:103DC00014C00000000005360000000000200C11A7
-:103DD000000000000000001C00203623000000004E
-:103DE0000000002B00203623000000000000002906
-:103DF00000203623000000000000002800203623A9
-:103E00000000000000000017002036230000000022
-:103E100000000025002036230000000000000026DE
-:103E2000002036230000000000000015002036238B
-:103E300000000000000000160020362300000000F3
-:103E4000FFFFE00000200C11000000000000002136
-:103E5000002036230000000000000022002036234E
-:103E60000000000000001FFF00200C1100000000F7
-:103E70000000002300203623000000000000002482
-:103E80000020362300000000F1FFFFFF00283A2E3B
-:103E9000000000000000001AC0220E2000000000F8
-:103EA000000000000029386E0000000081000000C2
-:103EB000002044110000000000000006002048110E
-:103EC000000000000000002A402036200000000012
-:103ED00087000000002044110000000000000000E6
-:103EE000C0204800000000000000A1F400204411A0
-:103EF000000000000000000000204810000000004A
-:103F00009D00000000204411000000000000001F80
-:103F100040214A20000000009600000000204411CB
-:103F20000000000000000000C02048000000000069
-:103F300000000000C0200C00000000000000000095
-:103F4000C0201000000000000000001F0021162407
-:103F5000000000000000000014C00000000000008D
-:103F60000000001D002036230000000000000003B8
-:103F700000281E2300000000000000080022222369
-:103F800000000000FFFFF0000028222800000000D1
-:103F900000000000002920E8000000000000001FD1
-:103FA00000203628000000000000001800211E2319
-:103FB0000000000000000020002036270000000064
-:103FC0000000000200221624000000000000000093
-:103FD000003014A8000000000000001E002036255C
-:103FE000000000000000000300211A24000000006F
-:103FF0001000000000281A2600000000EFFFFFFF5D
-:1040000000283A2E0000000000000000004938CED1
-:10401000000006100000000140280A2000000000F7
-:104020000000000640280E200000000000000300F1
-:10403000C028122000000000000000080021122407
-:104040000000000000000000C0201620000000005A
-:1040500000000000C0201A20000000000000000046
-:1040600000210222000000000000000014C0000037
-:104070000000056C810000000020441100000000D9
-:10408000000000010020481100000000000022583C
-:1040900000300A24000000000004000000694622ED
-:1040A00000000622000021690020441100000000E9
-:1040B0000000000000204805000000000002000091
-:1040C00000294A26000000000000000000204810DF
-:1040D00000000000CAFEBABE002048110000000027
-:1040E00000000002002F022300000000000000007A
-:1040F0000CC000000000057400000000C0201C106F
-:104100000000000000000000C04000000000058228
-:1041100000000002002F0223000000000000000049
-:104120000CC0000000000574810000000020441154
-:104130000000000000000001002048110000000005
-:104140000000225800300A24000000000004000093
-:10415000006946220000062200000000C0201C105A
-:104160000000000000000000C040000000000582C8
-:1041700000000000002F02230000000000000000EB
-:104180000CC000000000057800000000C0201C00EA
-:104190000000000000000000C04000000000058298
-:1041A00000000004002F02230000000000000000B7
-:1041B0000CC00000000005808100000000204411B8
-:1041C0000000000000000000002048110000000076
-:1041D0000000216D002044110000000000000000DC
-:1041E000C02048000000000000000000C06048003F
-:1041F000000006270000000000401C10000005829F
-:1042000000000000C02000000000000000000000CE
-:10421000C040000000000000000000000EE00000B0
-:10422000000005840000000000600000000005C3DD
-:1042300000000000002F0224000000000000000029
-:104240000CC00000000005920000A2B7002044113D
-:1042500000000000000000000020480700000000EF
-:10426000000000330020262D000000000000001A8E
-:10427000002122290000000000000006002226295B
-:10428000000000000000A2C4002044110000000053
-:1042900000000000003048E90000000000000000BD
-:1042A00000E00000000005900000A2D100204411B1
-:1042B000000000000000000000404808000000006E
-:1042C0000000A2D100204411000000000000000105
-:1042D00000504A280000000000000001002F0224C6
-:1042E00000000000000000000CC00000000005A05D
-:1042F0000000A2BB002044110000000000000000EC
-:104300000020480700000000000000340020262D97
-:10431000000000000000001A002122290000000017
-:104320000000000600222629000000000000A2C5AF
-:10433000002044110000000000000000003048E9A7
-:10434000000000000000000000E000000000059EEA
-:104350000000A2D200204411000000000000000074
-:1043600000404808000000000000A2D200204411D4
-:10437000000000000000000100504A28000000007A
-:1043800000000002002F02240000000000000000D6
-:104390000CC00000000005AE0000A2BF00204411C8
-:1043A000000000000000000000204807000000009E
-:1043B000000000350020262D000000000000001A3B
-:1043C000002122290000000000000006002226290A
-:1043D000000000000000A2C6002044110000000000
-:1043E00000000000003048E900000000000000006C
-:1043F00000E00000000005AC0000A2D30020441142
-:10440000000000000000000000404808000000001C
-:104410000000A2D3002044110000000000000001B1
-:1044200000504A28000000000000A2C300204411F0
-:10443000000000000000000000204807000000000D
-:10444000000000360020262D000000000000001AA9
-:104450000021222900000000000000060022262979
-:10446000000000000000A2C700204411000000006E
-:1044700000000000003048E90000000000000000DB
-:1044800000E00000000005B80000A2D400204411A4
-:10449000000000000000000000404808000000008C
-:1044A0000000A2D400204411000000000000000120
-:1044B00000504A2800000000850000000020441140
-:1044C0000000000000000000002048010000000083
-:1044D0000000304A002044110000000001000000EC
-:1044E0000020481100000000000000000040000013
-:1044F000000005BEA4000000C02044110000000020
-:1045000000000000C0404800000000000000000063
-:10451000C0600000000005C300000000C0400400AF
-:10452000000000010001A2A40020441100000000CE
-:104530000000003F00204811000000000000003F84
-:1045400000204811000000000000003F002048113A
-:10455000000000000000003F0020481100000000A3
-:104560000000000500204811000000000000A1F438
-:10457000002044110000000000000000002048114D
-:10458000000000008800000000204411000000002E
-:10459000000000010020481100000000FF000000A2
-:1045A000002044110000000000000000002048111D
-:1045B0000000000000000001002048110000000081
-:1045C0000000000200804811000000000000000010
-:1045D0000EE00000000005D60000100000200811C9
-:1045E000000000000000002B002036220000000028
-:1045F0000000000000600000000005DA000000007C
-:1046000000600000000005C3980000000020441175
-:1046100000000000000000000080481100000000C1
-:1046200000000000C0600000000005DA000000008B
-:10463000C0400400000000010000A2A400204411BA
-:1046400000000000000000220020481100000000CF
-:10465000890000000020441100000000000000015B
-:1046600000404811000005CD9700000000204411D3
-:1046700000000000000000000020481100000000C1
-:104680008A0000000020441100000000000000002B
-:1046900000404811000005CD00000000006000004F
-:1046A000000005F30001A2A4C02044110000000096
-:1046B0000000001600604811000003740000201084
-:1046C00000204411000000000001000000204811FB
-:1046D00000000000810000000020441100000000E4
-:1046E0000000000100204811000000000000217CB3
-:1046F0000020441100000000098000000020481143
-:1047000000000000FFFFFFFF002048110000000034
-:104710000000000000204811000000000000000020
-:1047200017000000000000000004217F0060441119
-:10473000000006220000001F0021023000000000DF
-:104740000000000014C00000000000000000000491
-:1047500000404C11000005ED00000000004000008A
-:10476000000000000000001700201E2D00000000C7
-:104770000000000400291E270000000000000017B0
-:1047800000803627000000000000001700201E2DCA
-:1047900000000000FFFFFFFB00281E2700000000B4
-:1047A00000000017008036270000000000000017FE
-:1047B00000201E2D000000000000000800291E2718
-:1047C00000000000000000170080362700000000F5
-:1047D0000000001700201E2D00000000FFFFFFF763
-:1047E00000281E2700000000000000170080362768
-:1047F000000000000001A2A40020441100000000FD
-:104800000000001600604811000003740000201032
-:1048100000204411000000000001000000204811A9
-:10482000000000000000217C002044110000000076
-:10483000018000000020481100000000FFFFFFFF82
-:104840000020481100000000000000000020481176
-:104850000000000000000000170000000000000041
-:104860008100000000204411000000000000000151
-:1048700000204811000000000004217F0060441166
-:10488000000006220000001F00210230000000008E
-:104890000000000014C0000000000621000000100D
-:1048A00000404C110000060700000000C02004007A
-:1048B000000000000000000038C000000000000000
-:1048C0000000001D00200A2D000000000000001E56
-:1048D00000200E2D000000000000001F0020122DFF
-:1048E00000000000000000200020162D0000000045
-:1048F00000002169002044110000000000000000B9
-:1049000000204804000000000000000000204805CE
-:10491000000000000000000000204801000000002E
-:10492000CAFEBABE002048110000000000000004CA
-:10493000003012240000000000000000002F00647E
-:1049400000000000000000000CC000000000062075
-:104950000000000300281A220000000000000008E8
-:104960000022122200000000FFFFF00000281224A5
-:104970000000000000000000002910C4000000003A
-:104980000000001F0040362400000000000000006E
-:104990000080000000000000000000001AC00000BD
-:1049A000000006229F0000000020441100000000CB
-:1049B000CAFEBABE0020481100000000000000003E
-:1049C0001AE0000000000625000000000080000042
-:1049D00000000000000000001AC0000000000627D0
-:1049E0009E0000000020441100000000CAFEBABE74
-:1049F0000020481100000000000000001AE0000044
-:104A00000000062A000000000080000000000000F6
-:104A100000000000006000000000000B000010001B
-:104A200000600411000003150000000000200411C4
-:104A3000000000000000000000600811000001B24A
-:104A40000000225C00204411000000000000000370
-:104A500000204811000000000000225600204411F0
-:104A6000000000000000001B0020481100000000B2
-:104A70000000A1FC00204411000000000000000123
-:104A800000204811000000000001A1FDC0204411D9
-:104A9000000000000000002100201E2D000000008A
-:104AA0000000001000221E2700000000000000246B
-:104AB0000020222D000000000000FFFF0028222817
-:104AC000000000000000000000294907000000006D
-:104AD000000000000020481100000000000000223B
-:104AE0000020222D000000000000FFFF00282228E7
-:104AF000000000000000000000294907000000003D
-:104B00000000000000204811000000000000002309
-:104B100000201E2D000000000000001000221E27B3
-:104B2000000000000000000000294907000000000C
-:104B300000000000004048110000000000000000DC
-:104B40000000000000000000000000000000000065
-:104B50000000000000000000000000000000000055
-:104B60000000000000000000000000000000000045
-:104B70000000000000000000000000000000000035
-:104B80000000000000000000000000000000000025
-:104B90000000000000000000000000000000000015
-:104BA0000000000000000000000000000000000005
-:104BB00000000000000000000000000000000000F5
-:104BC00000000000000000000000000000000000E5
-:104BD00000000000000000000000000000000000D5
-:104BE00000000000000000000000000000000000C5
-:104BF00000000000000000000000000000000000B5
-:104C000000000000000000000000000000000000A4
-:104C10000000000000000000000000000000000094
-:104C20000000000000000000000000000000000084
-:104C30000000000000000000000000000000000074
-:104C40000000000000000000000000000000000064
-:104C50000000000000000000000000000000000054
-:104C60000000000000000000000000000000000044
-:104C70000000000000000000000000000000000034
-:104C80000000000000000000000000000000000024
-:104C90000000000000000000000000000000000014
-:104CA0000000000000000000000000000000000004
-:104CB00000000000000000000000000000000000F4
-:104CC00000000000000000000000000000000000E4
-:104CD00000000000000000000000000000000000D4
-:104CE00000000000000000000000000000000000C4
-:104CF00000000000000000000000000000000000B4
-:104D000000000000000000000000000000000000A3
-:104D10000000000000000000000000000000000093
-:104D20000000000000000000000000000000000083
-:104D30000000000000000000000000000000000073
-:104D40000000000000000000000000000000000063
-:104D50000000000000000000000000000000000053
-:104D60000000000000000000000000000000000043
-:104D70000000000000000000000000000000000033
-:104D80000000000000000000000000000000000023
-:104D90000000000000000000000000000000000013
-:104DA0000000000000000000000000000000000003
-:104DB00000000000000000000000000000000000F3
-:104DC00000000000000000000000000000000000E3
-:104DD00000000000000000000000000000000000D3
-:104DE00000000000000000000000000000000000C3
-:104DF00000000000000000000000000000000000B3
-:104E000000000000000000000000000000000000A2
-:104E10000000000000000000000000000000000092
-:104E20000000000000000000000000000000000082
-:104E30000000000000000000000000000000000072
-:104E40000000000000000000000000000000000062
-:104E50000000000000000000000000000000000052
-:104E60000000000000000000000000000000000042
-:104E70000000000000000000000000000000000032
-:104E80000000000000000000000000000000000022
-:104E90000000000000000000000000000000000012
-:104EA0000000000000000000000000000000000002
-:104EB00000000000000000000000000000000000F2
-:104EC00000000000000000000000000000000000E2
-:104ED00000000000000000000000000000000000D2
-:104EE00000000000000000000000000000000000C2
-:104EF00000000000000000000000000000000000B2
-:104F000000000000000000000000000000000000A1
-:104F10000000000000000000000000000000000091
-:104F20000000000000000000000000000000000081
-:104F30000000000000000000000000000000000071
-:104F40000000000000000000000000000000000061
-:104F50000000000000000000000000000000000051
-:104F60000000000000000000000000000000000041
-:104F70000000000000000000000000000000000031
-:104F80000000000000000000000000000000000021
-:104F90000000000000000000000000000000000011
-:104FA0000000000000000000000000000000000001
-:104FB00000000000000000000000000000000000F1
-:104FC00000000000000000000000000000000000E1
-:104FD00000000000000000000000000000000000D1
-:104FE00000000000000000000000000000000000C1
-:104FF00000000000000000000000000000000000B1
-:1050000000000000000000000000000000000000A0
-:105010000000000000000000000000000000000090
-:105020000000000000000000000000000000000080
-:105030000000000000000000000000000000000070
-:105040000000000000000000000000000000000060
-:105050000000000000000000000000000000000050
-:105060000000000000000000000000000000000040
-:105070000000000000000000000000000000000030
-:105080000000000000000000000000000000000020
-:105090000000000000000000000000000000000010
-:1050A0000000000000000000000000000000000000
-:1050B00000000000000000000000000000000000F0
-:1050C00000000000000000000000000000000000E0
-:1050D00000000000000000000000000000000000D0
-:1050E00000000000000000000000000000000000C0
-:1050F00000000000000000000000000000000000B0
-:10510000000000000000000000000000000000009F
-:10511000000000000000000000000000000000008F
-:10512000000000000000000000000000000000007F
-:10513000000000000000000000000000000000006F
-:10514000000000000000000000000000000000005F
-:10515000000000000000000000000000000000004F
-:10516000000000000000000000000000000000003F
-:10517000000000000000000000000000000000002F
-:10518000000000000000000000000000000000001F
-:10519000000000000000000000000000000000000F
-:1051A00000000000000000000000000000000000FF
-:1051B00000000000000000000000000000000000EF
-:1051C00000000000000000000000000000000000DF
-:1051D00000000000000000000000000000000000CF
-:1051E00000000000000000000000000000000000BF
-:1051F00000000000000000000000000000000000AF
-:10520000000000000000000000000000000000009E
-:10521000000000000000000000000000000000008E
-:10522000000000000000000000000000000000007E
-:10523000000000000000000000000000000000006E
-:10524000000000000000000000000000000000005E
-:10525000000000000000000000000000000000004E
-:10526000000000000000000000000000000000003E
-:10527000000000000000000000000000000000002E
-:10528000000000000000000000000000000000001E
-:10529000000000000000000000000000000000000E
-:1052A00000000000000000000000000000000000FE
-:1052B0000142050A05BA02500000000001C301685E
-:1052C000044105BA00000000022502090250015104
-:1052D000000000000223024502A00241000000007D
-:1052E00003D705BA05BA05BA0000000005E205E3D8
-:1052F000031F05BA00000000032005BF0320034A76
-:105300000000000003340282034C033E0000000052
-:1053100005BA05BA05BA05BA0000000005BA055776
-:1053200005BA032A0000000003BC05BA04C3034EFB
-:105330000000000004A20455043F05BA000000006C
-:1053400004D805BA044304E5000000000455050F25
-:10535000035B037B0000000005BA05BA05BA05BA75
-:105360000000000005BA05BA05BA05BA0000000041
-:1053700005BA05BA05D805C10000000005BA05BA8E
-:10538000000705BA0000000005BA05BA05BA05BA5B
-:105390000000000005BA05BA05BA05BA0000000011
-:1053A00003F803ED0408040600000000040E040ADC
-:1053B000040C041000000000041C04180424042041
-:1053C00000000000042C0428043404300000000015
-:1053D00005BA05BA043A04380000000005BA05BA57
-:1053E00005BA05BA0000000005BA05BA05BA05BA43
-:1053F000000000000002060E062C0006000000005F
-:00000001FF
--- zfcpdump-kernel-4.4.orig/firmware/radeon/RS780_pfp.bin.ihex
+++ /dev/null
@@ -1,145 +0,0 @@
-:1000000000CA040000A00000007E828B007C038BED
-:10001000008001DB007C038B00D4401E00EE001E3C
-:1000200000CA040000A00000007E828B00C41838C3
-:1000300000CA240000CA2800009581CB00C41C3AE5
-:1000400000C3C00000CA080000CA0C00007C744B4A
-:1000500000C200050099C00000C41C3A007C744C2A
-:1000600000C0FFE000042C0800309002007D250055
-:1000700000351402007D350B00255407007CD58027
-:1000800000259C070095C00400D5001B007EDDC143
-:10009000007D9D8000D6801B00D5801B00D4401EB3
-:1000A00000D5401E00D6401E00D6801E00D4801E03
-:1000B00000D4C01E009783D300D5C01E00CA08001C
-:1000C0000080001A00CA0C0000E4011E00D4001ECB
-:1000D0000080000C00C4183800E4013E00D4001E6B
-:1000E0000080000C00C4183800D4401E00EE001E32
-:1000F00000CA040000A00000007E828B00E4011E04
-:1001000000D4001E00D4401E00EE001E00CA0400F1
-:1001100000A00000007E828B00E4013E00D4001E9F
-:1001200000D4401E00EE001E00CA040000A0000023
-:10013000007E828B00CA080000CA0C00008001DB30
-:1001400000D4802400CA0800007C00C000C8142528
-:1001500000C81824007C9488007C988000C20003AA
-:1001600000D40075007C744C0080006400D4401EF4
-:1001700000CA180000D4401E00D5801E0080006216
-:1001800000D4007500D4401E00CA080000CA0C004C
-:1001900000CA100000D4801900D4C01800D5001780
-:1001A00000D4801E00D4C01E00D5001E00E2001E38
-:1001B00000CA040000A00000007E828B00D40075FD
-:1001C00000D4401E00CA080000CA0C0000CA10007B
-:1001D00000D4801900D4C01800D5001700D4801EA8
-:1001E00000D4C01E00D5001E00EE001E00CA040090
-:1001F00000A00000007E828B00CA080000248C0151
-:1002000000D480600094C0030004100100041002B8
-:1002100000D5002500D4401E0080000000D4801EC0
-:1002200000CA080000D4806100D4401E0080000095
-:1002300000D4801E00CA080000CA0C0000D4401E72
-:1002400000D4801600D4C01600D4801E008001DBCC
-:1002500000D4C01E00C6084300CA0C0000CA10002B
-:100260000094800400CA140000E420F300D420139A
-:1002700000D5606500D4E01C00D5201C00D5601CB2
-:10028000008000000006200100C6084300CA0C00E0
-:1002900000CA1000009483F700CA140000E420F3A1
-:1002A0000080009C00D4201300C6084300CA0C0044
-:1002B00000CA1000009883EF00CA140000D4006444
-:1002C000008000B00000000000C4143200C61843D3
-:1002D00000C4082F0095400500C40C3000D4401E17
-:1002E0000080000000EE001E009583F500C4103170
-:1002F00000D4403300D5206500D4A01C00D4E01CFD
-:1003000000D5201C00E4015E00D4001E0080000027
-:100310000006200100CA1800000A200100D600765D
-:1003200000C408360098800700C6104500950110EB
-:1003300000D4001F00D460620080000000D420625E
-:1003400000CC383500CC1433008401DE00D40072B8
-:1003500000D5401E0080000000EE001E00E2001AE2
-:10036000008401DE00E2001A00CC104B00CC0447F0
-:10037000002C9401007D098B00984005007D15CB71
-:1003800000D4001A008001DB00D4006D0034440169
-:1003900000CC0C480098403A00CC2C4A00958004D0
-:1003A00000CC0449008001DB00D4001A00D4C01A3C
-:1003B000002828010084011300CC10030098801B42
-:1003C0000004380C0084011300CC1003009880173F
-:1003D000000438080084011300CC10030098801337
-:1003E000000438040084011300CC1003009880142A
-:1003F00000CC104C009A800900CC144D009840DCD1
-:1004000000D4006D00CC184800D5001A00D5401A61
-:10041000008000EC00D5801A0096C0D500D4006D95
-:10042000008001DB00D4006E009AC00300D4006D90
-:1004300000D4006E0080000000EC007F009AC0CC69
-:1004400000D4006D008001DB00D4006E00CC1403EA
-:1004500000CC180300CC1C03007D9103007DD583E4
-:10046000007D190C0035CC1F0035701F007CF0CBCF
-:10047000007CD08B00880000007E8E8B0095C0042D
-:1004800000D4006E008001DB00D4001A00D4C01A32
-:1004900000CC080300CC0C0300CC100300CC1403E8
-:1004A00000CC180300CC1C0300CC240300CC280390
-:1004B0000035C41F0036B01F007C704B0034F01FA5
-:1004C000007C704B0035701F007C704B007D888174
-:1004D000007DCCC1007E5101007E9541007C908260
-:1004E000007CD4C2007C848B009AC003007C8C8B7F
-:1004F000002C88010098809E00D4006D0098409CDC
-:1005000000D4006E00CC084C00CC0C4D00CC104840
-:1005100000D4801A00D4C01A0080012400D5001A2B
-:1005200000CC083200D40032009482B600CA0C001D
-:1005300000D4401E0080000000D4001E00E4011E14
-:1005400000D4001E00CA080000CA0C0000CA100037
-:1005500000D4401E00CA140000D4801E00D4C01E67
-:1005600000D5001E00D5401E00D54034008000009C
-:1005700000EE001E0028040400E2001A00E2001A47
-:1005800000D4401A00CA380000CC080300CC0C0389
-:1005900000CC0C0300CC0C030098829A00000000F1
-:1005A000008401DE00D7A06F0080000000EE001F75
-:1005B00000CA040000C2FF0000CC083400C13FFFA5
-:1005C000007C74CB007CC90B007D010F0099028D6B
-:1005D000007C738B008401DE00D7A06F00800000D8
-:1005E00000EE001F00CA080000281900007D898B5A
-:1005F000009580140028140400CA0C0000CA1000E2
-:1006000000CA1C0000CA240000E2001F00D4C01A67
-:1006100000D5001A00D5401A00CC180300CC2C03DA
-:1006200000CC2C0300CC2C03007DA58B007D9C47C7
-:1006300000984274000000000080018400D4C01AB9
-:1006400000D4401E00D4801E0080000000EE001E7A
-:1006500000E4011E00D4001E00D4401E00EE001E67
-:1006600000CA040000A00000007E828B00E4013E6E
-:1006700000D4001E00D4401E00EE001E00CA04007C
-:1006800000A00000007E828B00CA080000248C06B7
-:10069000000CCC060098C00600CC104E0099000457
-:1006A00000D4007300E4011E00D4001E00D4401EDC
-:1006B00000D4801E0080000000EE001E00CA08006A
-:1006C00000CA0C000034D01800251001009500214C
-:1006D00000C17FFF00CA100000CA140000CA180041
-:1006E00000D4801D00D4C01D007DB18B00C142022A
-:1006F00000C2C00100D5801D0034DC0E007D5D4CC1
-:10070000007F734C00D7401E00D5001E00D5401E50
-:1007100000C1420000C2C00000099C010031DC1091
-:10072000007F5F4C007F734C00042802007D8380B3
-:1007300000D5A86F00D5806600D7401E00EC005E93
-:1007400000C8240200C82402008001DB00D6007625
-:1007500000D4401E00D4801E00D4C01E00800000C3
-:1007600000EE001E0080000000EE001F00D4001FFD
-:100770000080000000D4001F00D4001F008800008B
-:1007800000D4001F00000000000000000000000076
-:100790000000000000000000000000000000000059
-:1007A0000000000000000000000000000000000049
-:1007B0000000000000000000000000000000000039
-:1007C0000000000000000000000000000000000029
-:1007D0000000000000000000000000000000000019
-:1007E0000000000000000000000000000000000009
-:1007F00000000000000000000000000000000000F9
-:10080000000101940002019B000300B2000400A259
-:10081000000500030006003F000700320008014FFA
-:1008200000090046000A0036001001D9001700C573
-:100830000022015D0023016C002000D70024014844
-:100840000026004D0027005C0028008D0029005183
-:10085000002A007E002B0061002F0088003200AAD1
-:10086000003401A20036006F003C0179003F009582
-:10087000004101AF00440151005501960056019D11
-:100880000060000B00610034006200380063003833
-:1008900000640038006500380066003800670038E2
-:1008A0000068003A00690041006A0048006B004897
-:1008B000006C0048006D0048006E0048006F004862
-:1008C000007301D9000000060000000600000006C9
-:1008D0000000000600000006000000060000000600
-:1008E00000000006000000060000000600000006F0
-:1008F00000000006000000060000000600000006E0
-:00000001FF
--- zfcpdump-kernel-4.4.orig/firmware/radeon/RV610_me.bin.ihex
+++ /dev/null
@@ -1,1345 +0,0 @@
-:1000000000000000C020040000000000000000000C
-:1000100000A0000A000000000000FFFF00284621A9
-:100020000000000000000000D900480000000000AF
-:1000300000000000C02004000000000000000000DC
-:1000400000A0000A000000000000000000E0000026
-:100050000000000000010000C02946200000000050
-:1000600000000000D900480000000000000000006F
-:10007000C0200400000000000000000000A0000AF2
-:10008000000000008100000000204411000000007A
-:1000900000000001002048110000000000042004BE
-:1000A000006044110000068D0000000000600000A8
-:1000B000000006310000000000600000000006455E
-:1000C00000000000C02008000000000000000F0039
-:1000D000002816220000000000000008002116255C
-:1000E000000000000000001800203625000000007D
-:1000F0008D000000002044110000000000000004FA
-:10010000002F022500000000000000000CE00000AD
-:1001100000000018004120000040481100000019B4
-:100120000042200000204811000000008E00000066
-:1001300000204411000000000000002800204A2D8B
-:1001400000000000900000000020441100000000AA
-:100150000000000000204805000000000000000C26
-:1001600000211622000000000000000300281625D0
-:10017000000000000000001900211A220000000009
-:100180000000000400281A26000000000000000003
-:10019000002914C5000000000000001900203625C9
-:1001A0000000000000000000003A140200000000FF
-:1001B00000000016002116250000000000000003CA
-:1001C00000281625000000000000001700200E2D5A
-:1001D00000000000FFFFFFFC00280E2300000000CD
-:1001E00000000000002914A3000000000000001718
-:1001F00000203625000000000000800000280E22AC
-:10020000000000000000000700220E230000000094
-:10021000000000000029386E0000000020000000EF
-:1002200000280E22000000000000000600210E231E
-:1002300000000000000000000029386E00000000EF
-:100240000000000000220222000000000000000068
-:1002500014E0000000000038000000002EE0000064
-:1002600000000035000000002CE000000000003716
-:100270000000000000400E2D0000003900000008C2
-:1002800000200E2D00000000000000090040122D8B
-:10029000000000460000000100400E2D0000003963
-:1002A00000000000C0200C0000000000003FFFFC28
-:1002B0000028122300000000000000020022122487
-:1002C000000000000000001F00211E2300000000AD
-:1002D0000000000014E000000000003E00000008E4
-:1002E00000401C11000000410000000D00201E2DE8
-:1002F000000000000000000F00281E270000000082
-:100300000000000300221E27000000007FC0000044
-:1003100000281A23000000000000001400211A2603
-:10032000000000000000000100331A260000000059
-:100330000000000800221A26000000000000000053
-:1003400000290CC700000000000000270020362410
-:100350000000000000007F000028122100000000C3
-:1003600000001400002F0224000000000000000024
-:100370000CE000000000004B0000000100290E23EB
-:10038000000000000000000E0020362300000000E6
-:100390000000E0000020441100000000FFF8000011
-:1003A00000294A230000000000000000003A2C024F
-:1003B000000000000000000200220E2B00000000E0
-:1003C000FC00000000280E23000000000000000FC9
-:1003D000002036230000000000001FFF00294A23F0
-:1003E000000000000000002700204A2D000000004F
-:1003F000000000000020481100000000000000295B
-:1004000000200E2D00000000060A020000294A23E9
-:100410000000000000000000002048110000000063
-:100420000000000000204811000000000000000152
-:1004300000210222000000000000000014E0000083
-:1004400000000061000000002EE000000000005FDE
-:10045000000000002CE000000000005E0000000032
-:1004600000400E2D000000620000000100400E2D33
-:10047000000000620000000A00200E2D00000000B5
-:100480000000000B0040122D0000006A0000000078
-:10049000C0200C0000000000003FFFFC00281223D9
-:1004A00000000000000000020022122400000000F2
-:1004B0007FC0000000281623000000000000001488
-:1004C0000021162500000000000000010033162561
-:1004D000000000008000000000280E230000000043
-:1004E0000000000000290CA3000000003FFFFC00FA
-:1004F00000290E23000000000000001F00211E2321
-:10050000000000000000000014E000000000006D8A
-:100510000000010000401C11000000700000000DF0
-:1005200000201E2D00000000000000F000281E2703
-:10053000000000000000000400221E270000000050
-:100540008100000000204411000000000000000DA8
-:100550000020481100000000FFFFF0FF00281A30C3
-:10056000000000000000A02800204411000000004E
-:1005700000000000002948E6000000000000A0186C
-:1005800000204411000000003FFFFFFF00284A2325
-:10059000000000000000A010002044110000000036
-:1005A00000000000002048040000000000000030AF
-:1005B0000020162D00000000000000020029162572
-:1005C0000000000000000030002036250000000080
-:1005D000000000250020162D000000000000000093
-:1005E000002F00A300000000000000000CC000006D
-:1005F00000000083000000260020162D00000000EF
-:1006000000000000002F00A4000000000000000017
-:100610000CC000000000008400000000004000004A
-:100620000000008A000000250020362300000000A2
-:100630000000002600203624000000000000001703
-:1006400000201E2D000000000000000200210227F3
-:10065000000000000000000014E000000000008A1C
-:1006600000000000006000000000066800000000BC
-:10067000006000000000065C0000000200210E2265
-:10068000000000000000000014C000000000008D09
-:1006900000000012C040362000000093000000005F
-:1006A0002EE0000000000091000000002CE000009F
-:1006B000000000900000000200400E2D000000929B
-:1006C0000000000300400E2D000000920000000C0E
-:1006D00000200E2D00000000000000120020362334
-:1006E000000000000000000300210E2200000000B6
-:1006F0000000000014C00000000000980000A00CE2
-:10070000002044110000000000000000C02048004C
-:100710000000000000000000C0404800000000A0F1
-:100720000000A00C002044110000000000000000A8
-:100730000020481100000000000000002EE0000032
-:100740000000009E000000002CE000000000009D62
-:100750000000000200400E2D0000009F000000037A
-:1007600000400E2D0000009F0000000C00200E2D08
-:10077000000000000000000000204803000000000E
-:1007800000000000003A0C0200000000003F0000E2
-:1007900000280E23000000000000001000210E239E
-:1007A00000000000000000110020362300000000BF
-:1007B0000000001E0021022B0000000000000000CD
-:1007C00014C00000000000A700000016C020362062
-:1007D000000000000000001F0021022B00000000AC
-:1007E0000000000014C00000000000AA0000001576
-:1007F000C0203620000000000000000800210E2B61
-:10080000000000000000007F00280E230000000010
-:1008100000000000002F0223000000000000000084
-:100820000CE00000000000E10000000027000000D4
-:10083000000000000000000000600000000002A3B3
-:1008400000000001002F0223000000000000000053
-:100850000AE00000000000B300000000006000009B
-:100860000000013A81000000002044110000000057
-:100870000000000600204811000000000000000CED
-:1008800000221E300000000099800000002044116A
-:1008900000000000000000040020122D00000000F5
-:1008A00000000008002212240000000000000010D8
-:1008B00000201811000000000000000000291CE4C6
-:1008C0000000000000000000006048070000012F49
-:1008D0009B00000000204411000000000000000008
-:1008E00000204802000000009C000000002044118D
-:1008F00000000000000000000033146F0000000042
-:100900000000000100333E23000000000000000052
-:10091000D9004800000000000000000000203C0555
-:1009200000000000810000000020441100000000D1
-:100930000000000E00204811000000000000000030
-:1009400000201010000000000000E007002044110B
-:10095000000000000000000F0021022B000000003A
-:100960000000000014C00000000000CB00F8FF08E9
-:1009700000204811000000009800000000404811CD
-:10098000000000DC000000F000280E220000000043
-:10099000000000A0002F0223000000000000000063
-:1009A0000CC00000000000DA0000001100200E2D35
-:1009B0000000000000000001002F022300000000E2
-:1009C000000000000CE00000000000D50000000264
-:1009D000002F022300000000000000000CE00000D7
-:1009E000000000D400003F0000400C11000000D6C1
-:1009F00000001F0000400C11000000D600000F0096
-:100A000000200C11000000000038000900294A23D2
-:100A1000000000003F00000000280E2B0000000036
-:100A20000000000200220E2300000000000000076A
-:100A300000494A23000000DC00380F09002048115B
-:100A400000000000680000070020481100000000BE
-:100A50000000000800214A270000000000000000FC
-:100A60000020481100000000060A020000294A2464
-:100A700000000000000000000020481100000000FD
-:100A80000000000000204811000000000000A20249
-:100A9000002044110000000000FF000000280E228A
-:100AA000000000000000008000294A230000000030
-:100AB0000000002700200E2D00000000000000268E
-:100AC0000020122D0000000000000000002F008315
-:100AD00000000000000000000CE00000000000EA40
-:100AE000000000000060000000000662000000003E
-:100AF00000400000000000EB00000000006000006B
-:100B000000000665000000070020222D0000000004
-:100B10000000000500220E2200000000001000006E
-:100B200000280E23000000000000000000292068BB
-:100B30000000000000000000003A0C02000000006D
-:100B4000000000EF00280E2300000000000000005D
-:100B500000292068000000000000001700200E2D72
-:100B6000000000000000000300210223000000003C
-:100B70000000000014E00000000000F80000000B7E
-:100B800000210228000000000000000014C0000046
-:100B9000000000F8000004000029222800000000E6
-:100BA0000000001400203628000000000000001C97
-:100BB00000210E22000000000000000014C0000010
-:100BC000000000FD0000A30C002044110000000004
-:100BD0000000000000204811000000000000001E7E
-:100BE00000210E22000000000000000014C00000E0
-:100BF0000000010B0000A30F0020441100000000C2
-:100C00000000001100200E2D000000000000000177
-:100C1000002F022300000000000000000CC00000B4
-:100C200000000104FFFFFFFF004048110000010B1E
-:100C300000000002002F022300000000000000005E
-:100C40000CC00000000001070000FFFF0040481139
-:100C50000000010B00000004002F02230000000030
-:100C6000000000000CC000000000010A000000FFAE
-:100C7000004048110000010B000000010020481155
-:100C8000000000000002C400002044110000000029
-:100C90000000001F00210E220000000000000000E4
-:100CA00014C00000000001120000001040210E20BE
-:100CB00000000000000000130020362300000000A8
-:100CC0000000001840224A20000000000000001030
-:100CD000C0424A20000001140000000000200C1156
-:100CE0000000000000000013002036230000000078
-:100CF000000000000020481100000000000000007B
-:100D000000204811000000000000000A002010111F
-:100D10000000000000000000002F0224000000007E
-:100D2000000000000CE000000000011B00000000BB
-:100D300000204811000000000000000100531224B0
-:100D400000000117FFBFFFFF00283A2E000000003F
-:100D50000000001B00210222000000000000000033
-:100D600014C000000000012E81000000002044118A
-:100D7000000000000000000D0020481100000000ED
-:100D80000000001800220E3000000000FC000000EF
-:100D900000280E2300000000810000000020441104
-:100DA000000000000000000E0020481100000000BC
-:100DB0000000000000201010000000000000E00E05
-:100DC000002044110000000007F8FF08002048112F
-:100DD000000000000000000000294A23000000007D
-:100DE0000000001C00201E2D000000000000000874
-:100DF00000214A27000000000000000000204811E8
-:100E000000000000060A020000294A240000000039
-:100E10000000000000204811000000000000000059
-:100E200000204811000000000000000000800000C9
-:100E300000000000810000000020441100000000BC
-:100E40000000000100204811000000000000217C8B
-:100E50000020441100000000008000000020481124
-:100E60000000000000000000002048060000000014
-:100E70000000000800214A270000000000000000D8
-:100E800017000000000000000004217F00604411F2
-:100E90000000068D0000001F00210230000000004D
-:100EA0000000000014C000000000068C00000004D8
-:100EB00000404C1100000135810000000020441169
-:100EC00000000000000000010020481100000000A8
-:100ED000000021F800204411000000000000001C68
-:100EE0000020481100000000000421F900604411B6
-:100EF0000000068D000000110021023000000000FB
-:100F00000000000014E000000000013C00000000B0
-:100F100000800000000000000000000000600000F1
-:100F20000000000B00000000006004110000031529
-:100F3000000000000020041100000000000000007C
-:100F400000600811000001B2000000000060000015
-:100F5000000001600000FFFF40280E20000000009C
-:100F600000000010C0211220000000000000FFFF60
-:100F7000402806200000000000000010C0210A20C8
-:100F800000000000000000000034146100000000B8
-:100F90000000000000741882000002BB0001A1FDE7
-:100FA00000604411000002E000003FFF002F022F0C
-:100FB00000000000000000000CC00000000001471D
-:100FC00000000000C040040000000001000000001C
-:100FD000006000000000000B000000000060041131
-:100FE00000000315000000000020041100000000B4
-:100FF0000000000000600811000001B200003FFF87
-:10100000002F022F00000000000000000CE0000094
-:10101000000000000000000000600000000001600F
-:101020000000001040210E20000000000000FFFF23
-:10103000C0281220000000000000001040211620EF
-:10104000000000000000FFFFC0681A20000002BB83
-:101050000001A1FD00604411000002E000003FFF1C
-:10106000002F022F00000000000000000CC0000054
-:101070000000015800000000C04004000000000112
-:101080000000225C0020441100000000000000016C
-:1010900000300A2F000000000000000100210A2299
-:1010A000000000000000000300384A220000000099
-:1010B0000000225600204411000000000000001A29
-:1010C00000204811000000000000A1FC0020441195
-:1010D0000000000000000001008048110000000036
-:1010E00000000000006000000000000B0000000095
-:1010F000006000000000018F0000000000600000A0
-:10110000000001A000003FFF002F022F00000000A0
-:10111000000000000CE000000000000000000000E3
-:1011200000202C0800000000000000000020241116
-:101130000000000000000000002028110000000056
-:10114000000022560020441100000000000000169C
-:1011500000204811000000000000225C0020441123
-:101160000000000000000003002048110000000003
-:1011700093800000002044110000000000000002E5
-:1011800000221E290000000000000000007048EB53
-:101190000000019C0000000000600000000002BB95
-:1011A00000000001403306200000000000000000A5
-:1011B000C03024090000000000003FFF002F022F74
-:1011C00000000000000000000CE000000000000033
-:1011D0000000000000600000000002A3000000000A
-:1011E000002F022100000000000000000AE00000C3
-:1011F0000000018100000000006000000000013AD2
-:101200000000000000400000000001869500000082
-:10121000002044110000000000000000002F022107
-:1012200000000000000000000CE00000000001864B
-:1012300000000000C0204800000000000000000185
-:10124000005306210000018292000000002044119A
-:101250000000000000000000C0604800000001978E
-:101260000001A1FD00204411000000000000001159
-:101270000020062D00000000000000000078042A75
-:10128000000002FB00000000002028090000000010
-:1012900000003FFF002F022F0000000000000000B0
-:1012A0000CC000000000017400000000C0400400F9
-:1012B000000000010000021000600411000003158E
-:1012C00000003FFF002F022F000000000000000080
-:1012D0000CE000000000019400000015C020362042
-:1012E0000000000000000016C020362000000000B2
-:1012F0003F800000002004110000000046000000B4
-:1013000000600811000001B2000000000080000031
-:10131000000000000000A1FC0020441100000000BB
-:1013200000003FFF002F022F00000000000000001F
-:101330000CC000000000019B00000001008048116B
-:1013400000000000000000210080481100000000A3
-:101350000000FFFF40280E200000000000000010E9
-:10136000C0211220000000000000FFFF40281620CE
-:101370000000000000000010C0811A2000000000E2
-:101380008100000000204411000000000000000661
-:1013900000204811000000000000000800221E305C
-:1013A000000000000000002900201A2D00000000AD
-:1013B0000000E0000020441100000000FFFBFF09D6
-:1013C00000204811000000000000000F0020222D26
-:1013D0000000000000001FFF00294A280000000054
-:1013E000000000060020222D000000000000000088
-:1013F000002920E80000000000000000002048084C
-:101400000000000000000000002048110000000063
-:10141000060A020000294A26000000000000000021
-:1014200000204811000000000000000000204811CA
-:101430000000000000000100002018110000000062
-:101440000000000800621E280000012F00000008B4
-:1014500000822228000000000002C0000020441189
-:10146000000000000000001500600E2D000001BD0E
-:101470000000001600600E2D000001BD0000C00835
-:1014800000204411000000000000001700200E2D75
-:10149000000000000000000014C00000000001B9BE
-:1014A0000000000000200411000000000000000007
-:1014B0000020480100000000390000000020481111
-:1014C00000000000000000000020481100000000A3
-:1014D000000000000080480200000000000000182A
-:1014E00000202E2D0000000000000000003B0D63D6
-:1014F000000000000000000800224A230000000055
-:101500000000001000224A23000000000000001824
-:1015100000224A2300000000000000000080480371
-:101520000000000000000000006000000000000B50
-:10153000000010000060041100000315000000000E
-:1015400000200411000000000000000000600811ED
-:10155000000001B2000000070021062F000000007B
-:101560000000001300200A2D000000000000000110
-:1015700000202C11000000000000FFFF4028222066
-:10158000000000000000000F0026222800000000DC
-:101590000000001040212620000000000000000F85
-:1015A000002626290000000000000000002028027C
-:1015B000000000000000225600204411000000003E
-:1015C0000000001B00204811000000000000000087
-:1015D000002F022100000000000000000CE00000CD
-:1015E000000001E00000225C002044110000000027
-:1015F0000000008100204811000000000000A1FC54
-:1016000000204411000000000000000100204811EB
-:10161000000000000000008000201C1100000000FD
-:1016200000000000002F0227000000000000000062
-:101630000CE00000000001DC000000000060000081
-:10164000000001E90000000100531E27000001D83E
-:101650000000000100202C11000000000000001F0D
-:1016600000280A22000000000000001F00282A2A8B
-:10167000000000000000000100530621000001D11D
-:101680000000225C00204411000000000000000265
-:1016900000304A2F000000000000A1FC002044118F
-:1016A00000000000000000010020481100000000C0
-:1016B0000000000100301E2F0000000000000000AC
-:1016C000002F022700000000000000000CE00000D6
-:1016D000000000000000000000600000000001E9C0
-:1016E0000000000100531E27000001E50000FFFF7D
-:1016F00040280E20000000000000000F00260E23EE
-:101700000000000000000010C021122000000000B6
-:101710000000000F0026122400000000000000005E
-:1017200000201411000000000000000000601811EB
-:10173000000002BB0001A1FD0020441100000000D8
-:1017400000000000002F022B00000000000000003D
-:101750000CE00000000001F8000000100022162834
-:1017600000000000FFFF0000002816250000000018
-:101770000000FFFF00281A29000000000000000000
-:10178000002948C500000000000000000020480AB1
-:10179000000000000000000000202C1100000000EC
-:1017A000000000100022162300000000FFFF0000D0
-:1017B00000281625000000000000FFFF00281A2462
-:1017C0000000000000000000002948C500000000E3
-:1017D0000000000000731503000002050000000077
-:1017E0000020180500000000000000000073152410
-:1017F0000000020500000000002D14C500000000DC
-:1018000000000000003008A20000000000000000FE
-:101810000020480200000000000000000020280214
-:101820000000000000000000002020030000000075
-:101830000000000000802404000000000000000FF1
-:1018400000210225000000000000000014C000007C
-:101850000000068C00000000002B140500000000B2
-:1018600000000001009016250000000000000000AC
-:10187000006000000000000B000000000060041188
-:10188000000003150000000000200411000000000B
-:101890000000000000600811000001B200002256A4
-:1018A00000204411000000000000001A00294A2214
-:1018B0000000000000000000C02000000000000048
-:1018C00000003FFF002F022F00000000000000007A
-:1018D0000CE000000000000000000000C020040038
-:1018E000000000000000225C002044110000000005
-:1018F0000000000300384A21000000000000A1FCA5
-:1019000000204411000000000000000100204811E8
-:10191000000000000000FFFF40281220000000002F
-:1019200000000010C0211A20000000000000FFFF8E
-:1019300040280E200000000000000010C0211620EA
-:10194000000000000000000000741465000002BBED
-:101950000001A1FD00604411000002E00000000150
-:10196000003306210000000000000000002F0221CB
-:1019700000000000000000000CC000000000021980
-:1019800000003FFF002F022F0000000000000000B9
-:101990000CC000000000021200000000C040040063
-:1019A000000000010000000000600000000006458B
-:1019B000000000000040040F0000021300000000BF
-:1019C0000060000000000631000000000060000020
-:1019D000000006450000021000600411000003151D
-:1019E0000000000000600000000001A000000000F6
-:1019F000006000000000019C00000000006000008A
-:101A0000000002BB0000000000600000000002A314
-:101A1000938000000020441100000000000000003E
-:101A2000002048080000000000000000002F022FE6
-:101A300000000000000000000AE000000000023288
-:101A400000000000006000000000013A00000000FB
-:101A50000040000000000236950000000020441104
-:101A60000000000000000000002F022F0000000016
-:101A7000000000000CE00000000002360000000042
-:101A8000C0404800000002339200000000204411D2
-:101A90000000000000000000C0204800000000001E
-:101AA0000000225600204411000000000000001633
-:101AB00000204811000000000000225C00204411BA
-:101AC000000000000000000300204811000000009A
-:101AD0000000A1FC002044110000000000000001F3
-:101AE00000204811000000000001A1FD0020441169
-:101AF000000000000000000000600411000002FB74
-:101B000000000000C04004000000000100000000D0
-:101B100000600000000006310000A00C002044110D
-:101B20000000000000000000C0204800000000008D
-:101B300000000000C040480000000000000000005D
-:101B4000006000000000000B0000001840210A2087
-:101B50000000000000000003002F0222000000002F
-:101B6000000000000AE000000000024C0000001429
-:101B70000020222D00000000000801010029222879
-:101B800000000000000000140020362800000000C3
-:101B90000000A30C00204411000000000000000021
-:101BA000C02048000000000000000000C0204800E5
-:101BB0000000000000000000C0404800000002518A
-:101BC00000000000006000000000000B000000109A
-:101BD00000600411000003153F8000000020041184
-:101BE000000000000000000000600811000001B2C9
-:101BF0000000225C002044110000000000000003EF
-:101C000000204811000000000000000000600000FB
-:101C10000000027C0000001700201E2D00000000C4
-:101C20000000000100211E2700000000000000004D
-:101C300014E000000000026A0000001200201E2DC7
-:101C4000000000000000FFFF00281E270000000029
-:101C50000000000000341C2700000000000000000D
-:101C600012C000000000025F0000000000201C11F4
-:101C70000000000000000000002F00E50000000050
-:101C80000000000008C00000000002620000000028
-:101C900000201407000000000000001200201E2D8C
-:101CA000000000000000001000211E2700000000BE
-:101CB0000000000000341C4700000000000000008D
-:101CC00012C00000000002670000000000201C118C
-:101CD0000000000000000000002F00E600000000EF
-:101CE0000000000008C000000000026A00000000C0
-:101CF0000020180700000000000000000060000045
-:101D0000000002C100002256002044110000000023
-:101D1000000000000034202300000000000000004C
-:101D200012C00000000002720000000000342044D5
-:101D3000000000000000000012C00000000002715E
-:101D40000000001600404811000002760000001854
-:101D500000404811000002760000000000342044DA
-:101D6000000000000000000012C00000000002752A
-:101D70000000001700404811000002760000001922
-:101D800000204811000000000000A1FC00204411C8
-:101D900000000000000000010020481100000000C9
-:101DA0000001A1FD00604411000002E900003FFFB6
-:101DB000002F022F00000000000000000CC00000F7
-:101DC0000000025600000000C040040000000001B6
-:101DD0000000001040210620000000000000FFFF6E
-:101DE000C0280A20000000000000001040210E2042
-:101DF000000000000000FFFFC028122000000000CB
-:101E00000000001040211620000000000000FFFF2D
-:101E1000C0881A200000000081000000002044114A
-:101E20000000000000000001002048110000000038
-:101E300000042004006044110000068D0000000032
-:101E4000006000000000063100000000C0600000DB
-:101E5000000002A30000000500200A2D0000000081
-:101E60000000000800220A22000000000000002BF1
-:101E700000201A2D000000000000001C00201E2D74
-:101E8000000000000000700000281E270000000075
-:101E90000000000000311CE6000000000000002AE5
-:101EA00000201A2D000000000000000C00221A265D
-:101EB0000000000000000000002F00E6000000000D
-:101EC0000000000006E00000000002920000000098
-:101ED00000201C11000000000000000000200C1178
-:101EE000000000000000002B00203623000000004E
-:101EF0000000001000201811000000000000000089
-:101F000000691CE20000012F9380000000204411B2
-:101F10000000000000000000002048070000000052
-:101F200095000000002044110000000000000000A7
-:101F3000002F022F00000000000000000CE0000055
-:101F40000000029D0000000100333E2F0000000051
-:101F500000000000D90048000000000092000000CE
-:101F6000002044110000000000000000C0204800D4
-:101F7000000000000000001C0040362700000000A8
-:101F80000000000CC0220A20000000000000002910
-:101F9000002036220000000000000028C04036204B
-:101FA000000000000000A2A4002044110000000076
-:101FB000000000090020481100000000A1000000FE
-:101FC00000204411000000000000000100804811C2
-:101FD000000000000000002100201E2D0000000075
-:101FE00000000000002C1CE30000000000000021A5
-:101FF00000203627000000000000002200201E2DD7
-:102000000000000000000000002C1CE400000000A4
-:1020100000000022002036270000000000000023FE
-:1020200000201E2D0000000000000000003120A351
-:102030000000000000000000002D1D07000000004F
-:1020400000000023002036270000000000000024CC
-:1020500000201E2D0000000000000000003120C400
-:102060000000000000000000002D1D07000000001F
-:10207000000000240080362700000000000000213E
-:10208000002036230000000000000022002036243B
-:10209000000000000000000000311CA30000000050
-:1020A0000000002300203627000000000000000090
-:1020B00000311CC40000000000000024008036270E
-:1020C000000000000000001A002036270000000079
-:1020D0000000001B00203628000000000000001750
-:1020E00000201E2D00000000000000020021022739
-:1020F000000000000000000014C00000000002DC2E
-:102100000000000000400000000002D90000001A9A
-:1021100000203627000000000000001B00203628A9
-:10212000000000000000001700201E2D000000002D
-:102130000000000200210227000000000000000053
-:1021400014E00000000002D9000000030021022773
-:10215000000000000000000014E00000000002DCAD
-:102160000000002300201E2D0000000000000000E1
-:10217000002E00E1000000000000000002C000008E
-:10218000000002DC0000002100201E2D00000000E5
-:1021900000000000003120A100000000000000004D
-:1021A000002E00E8000000000000000006C0000053
-:1021B000000002DC0000002400201E2D00000000B2
-:1021C00000000000002E00E20000000000000000FF
-:1021D00002C00000000002DC0000002200201E2DD2
-:1021E0000000000000000000003120C200000000DC
-:1021F00000000000002E00E80000000000000000C9
-:1022000006C00000000002DC0000000000600000CA
-:10221000000006680000000000600000000002B539
-:102220000000000000400000000002DE000000008E
-:1022300000600000000002B5000000000060000027
-:102240000000065F0000000000400000000002DE09
-:102250000000000000600000000002A70000000075
-:1022600000400000000002DE0000001A00201E2DC9
-:10227000000000000000001B0080222D0000000074
-:102280000000001000221E230000000000000000DB
-:1022900000294887000000000000000000311CA356
-:1022A000000000000000001000221E2700000000B7
-:1022B0000000000000294887000000000000001016
-:1022C00000221E230000000000000000003120C496
-:1022D000000000000000FFFF00282228000000008E
-:1022E0000000000000894907000000000000001005
-:1022F00000221E2300000000000000000029488783
-:10230000000000000000001000221E21000000005C
-:102310000000000000294847000000000000000005
-:1023200000311CA3000000000000001000221E2746
-:1023300000000000000000000029488700000000A5
-:102340000000000000311CA100000000000000108F
-:1023500000221E270000000000000000002948475E
-:10236000000000000000001000221E2300000000FA
-:1023700000000000003120C4000000000000FFFF4A
-:102380000028222800000000000000000029490762
-:10239000000000000000001000221E2100000000CC
-:1023A00000000000003120C2000000000000FFFF1C
-:1023B00000282228000000000000000000894907D2
-:1023C000000000000000001000221E23000000009A
-:1023D0000000000000294887000000000000000104
-:1023E00000220A210000000000000000003308A2C3
-:1023F000000000000000001000221E22000000006B
-:102400000000001000212222000000000000000057
-:1024100000294907000000000000000000311CA353
-:10242000000000000000001000221E270000000035
-:1024300000000000002948870000000000000001A3
-:1024400000220A210000000000000000003008A265
-:10245000000000000000001000221E22000000000A
-:1024600000000010002122220000000000000000F7
-:1024700000294907000000000000001000221E2370
-:102480000000000000000000003120C40000000037
-:102490000000FFFF002822280000000000000000CC
-:1024A000002949070000000000000000003808C5AE
-:1024B00000000000000000000030084100000000A3
-:1024C0000000000100220A220000000000000000BD
-:1024D000003308A2000000000000001000221E22AD
-:1024E0000000000000000010002122220000000077
-:1024F00000000000008949070000000000000017EC
-:102500000020222D000000000000000014C0000088
-:1025100000000318FFFFFFEF002806210000000065
-:10252000000000140020222D000000000000F8E050
-:1025300000204411000000000000000000294901B3
-:1025400000000000000000000089490100000000B8
-:102550000000000000204811000000000000000002
-:102560000020481100000000060A02000080481107
-:102570000000000000000000C0200000000000007B
-:1025800097000000C020441100000000000000007F
-:10259000C0204811000000008A0000000020441103
-:1025A00000000000000000000020481100000000B2
-:1025B0000000225C00204411000000000000000028
-:1025C000C0204800000000000000A1FC00204411D1
-:1025D0000000000000000000C020480000000000D3
-:1025E00000000000C0200400000000000000000007
-:1025F00000A0000A00000000970000000020441125
-:102600000000000000000000002048110000000051
-:102610008A000000002044110000000000000000BB
-:1026200000204811000000000000225C002044113E
-:102630000000000000000000C02048000000000072
-:102640000000A1FC00204411000000000000000078
-:10265000C02048000000000000000000C02004006E
-:10266000000000000000000000A0000A00000000C0
-:10267000970000000020441100000000000000004E
-:1026800000204811000000008A00000000204411D2
-:1026900000000000000000000020481100000000C1
-:1026A0000000225C00204411000000000000000037
-:1026B000C0204800000000000000A1FC00204411E0
-:1026C0000000000000000000C020480000000000E2
-:1026D0000001A1FD002044110000000000000000E6
-:1026E000D90048000000000000000000C0200400E5
-:1026F000000000000000000000A0000A0000000030
-:1027000000002257002044110000000000000003D8
-:10271000C0484A20000000000000225D0020441153
-:102720000000000000000000C04048000000000061
-:1027300000000000006000000000064500000000EE
-:10274000C0200800000000000000225C00204411AE
-:10275000000000000000000300384A2200000000D2
-:102760000000A1FC00204411000000000000000057
-:10277000C0204800000000000001A1FD002044111D
-:102780000000000000000000002F022200000000F6
-:10279000000000000CE0000000000000000000004D
-:1027A00040204800000000000000000140304A20A6
-:1027B0000000000000000002C0304A2000000000BD
-:1027C0000000000100530A220000034B0000003FFC
-:1027D000C0280A20000000008100000000204411F1
-:1027E000000000000000000100204811000000006F
-:1027F000000021F800204411000000000000001833
-:102800000020481100000000000421F9006044117C
-:102810000000068D000000110021023000000000C1
-:102820000000000014E00000000003540000001449
-:10283000002F022200000000000000000CC0000079
-:10284000000003640000201000204411000000007C
-:102850000000800000204811000000000001A2A438
-:102860000020441100000000000000000060480249
-:102870000000036E00002100002044110000000051
-:1028800000000000C0204800000000000000000020
-:10289000C02048000000000000000000C0204800E8
-:1028A0000000000000000000C040480000000000E0
-:1028B00000000004002F02220000000000000000C1
-:1028C0000CC000000000036A00002010002044112A
-:1028D00000000000000080000020481100000000FF
-:1028E0000001A2A40020441100000000000000002C
-:1028F000004048020000035F00000028002F022271
-:1029000000000000000000000CC00000000005C036
-:102910000001A2A4002044110000000000000000FB
-:10292000004048020000035F0000002C0020362613
-:102930000000000000000049002018110000000005
-:102940000000003F002048110000000000000001CE
-:1029500000331A260000000000000000002F0226AD
-:1029600000000000000000000CC000000000037028
-:102970000000002C00801A2D000000000000003F25
-:10298000C0280A200000000000000015002F0222CD
-:1029900000000000000000000CE0000000000386C2
-:1029A00000000006002F02220000000000000000CE
-:1029B0000CE00000000003B100000016002F02220E
-:1029C00000000000000000000CE00000000003B563
-:1029D00000000020002F0222000000000000000084
-:1029E0000CE000000000039C0000000F002F0222FA
-:1029F00000000000000000000CE00000000003A840
-:102A000000000010002F0222000000000000000063
-:102A10000CE00000000003A80000001E002F0222AE
-:102A200000000000000000000CE000000000039027
-:102A30000000A2A4002044110000000000000000DB
-:102A400000404802000000000800000000290A229F
-:102A5000000000000000000340210E2000000000E4
-:102A60000000000CC021122000000000000800003F
-:102A7000002812240000000000000014C0221620CC
-:102A80000000000000000000002914A40000000065
-:102A90000000A2A40020441100000000000000007B
-:102AA000002948A2000000000000A1FE00204411FF
-:102AB000000000000000000000404803000000008B
-:102AC000810000000020441100000000000000010F
-:102AD0000020481100000000000021F800204411EF
-:102AE0000000000000000016002048110000000057
-:102AF000000421F9006044110000068D000000155B
-:102B000000210230000000000000000014E000007E
-:102B1000000003920000210E00204411000000007C
-:102B200000000000C020480000000000000000007D
-:102B3000C0204800000000000000A2A400204411B2
-:102B400000000000000000000040480200000000FB
-:102B5000810000000020441100000000000000017E
-:102B60000020481100000000000021F8002044115E
-:102B700000000000000000170020481100000000C5
-:102B8000000421F9006044110000068D00000003DC
-:102B900000210230000000000000000014E00000EE
-:102BA0000000039E000021080020441100000000E6
-:102BB00000000000C02048000000000000000000ED
-:102BC000C0204800000000000000A2A40020441122
-:102BD000000000000000000000404802000000006B
-:102BE0000000A2A40020441100000000000000002A
-:102BF0000020480200000000800000000020441176
-:102C0000000000000000000000204811000000004B
-:102C100081000000002044110000000000000010AE
-:102C200000204811000000000000000000200010FB
-:102C3000000000000000000014C00000000003AE0F
-:102C40000000000000400000000000000000201014
-:102C50000020441100000000000080000020481106
-:102C6000000000000001A2A40020441100000000A8
-:102C70000000000600404811000000000000201085
-:102C800000204411000000000000800000204811D6
-:102C9000000000000001A2A4002044110000000078
-:102CA00000000016006048110000036E00000000E4
-:102CB000004000000000000000000000C0200800EC
-:102CC0000000000000000000C0200C000000000018
-:102CD0000000001D00210223000000000000000091
-:102CE00014E00000000003CE810000000020441129
-:102CF000000000000000000100204811000000005A
-:102D0000000021F80020441100000000000000181D
-:102D10000020481100000000000421F90060441167
-:102D20000000068D000000110021023000000000AC
-:102D30000000000014E00000000003C000002100BB
-:102D400000204411000000000000000000204802A4
-:102D50000000000000000000002048030000000008
-:102D6000BABECAFE0020481100000000CAFEBABE6A
-:102D70000020481100000000000020100020441135
-:102D8000000000000000800000204811000000004A
-:102D90000000A2A400204411000000000000000474
-:102DA0000040481100000000000021700020441184
-:102DB00000000000000000000020480200000000A9
-:102DC0000000000000204803000000008100000017
-:102DD00000204411000000000000000A00204811FB
-:102DE00000000000000000000020001000000000B3
-:102DF0000000000014C00000000003D38C0000009D
-:102E00000020441100000000CAFEBABE0040481174
-:102E100000000000810000000020441100000000BC
-:102E200000000001002048110000000000003FFFEA
-:102E300040280A20000000008000000040280E20EA
-:102E40000000000040000000C02812200000000028
-:102E500000040000006946220000068D000000000A
-:102E6000002014100000000000000000002F0223CA
-:102E700000000000000000000CC00000000003E1A2
-:102E800000000000C0401800000003E400003FFF05
-:102E9000C0281A2000000000000400000069462637
-:102EA0000000068D00000000002018100000000047
-:102EB00000000000002F02240000000000000000BD
-:102EC0000CC00000000003E700000000C0401C0030
-:102ED000000003EA00003FFFC0281E2000000000A1
-:102EE00000040000006946270000068D0000000075
-:102EF00000201C1000000000000000000020440220
-:102F00000000000000000000002820C500000000B4
-:102F100000000000004948E800000000A580000013
-:102F200000200811000000000000200000200C110B
-:102F30000000000083000000006044110000041243
-:102F4000000000000020440200000000000000001B
-:102F5000C0204800000000000000000040204800A1
-:102F6000000000000000001FC0210220000000003F
-:102F70000000000014C00000000003F70000201053
-:102F800000204411000000000000800000204811D3
-:102F9000000000000000FFFFC0481220000003FFF7
-:102FA000A780000000200811000000000000A00021
-:102FB00000200C110000000083000000006044119C
-:102FC0000000041200000000002044020000000085
-:102FD00000000000C02048000000000000000000C9
-:102FE000C0204800000000000000FFFFC0281220A1
-:102FF00000000000830000000020441100000000D9
-:103000000000000000304883000000008400000041
-:10301000002044110000000000000000C020480013
-:1030200000000000000000001D0000000000000083
-:103030008300000000604411000004120000000042
-:10304000C040040000000001A98000000020081119
-:10305000000000000000C00000400C11000003FA56
-:10306000AB80000000200811000000000000F8E024
-:1030700000400C11000003FAAD8000000020081190
-:10308000000000000000F88000400C11000003FA6E
-:10309000B380000000200811000000000000F3FCD5
-:1030A00000400C11000003FAAF800000002008115E
-:1030B000000000000000E00000400C11000003FAD6
-:1030C000B180000000200811000000000000F000A6
-:1030D00000400C11000003FA83000000002044119E
-:1030E00000000000000021480020481100000000FE
-:1030F00084000000002044110000000000000000D7
-:10310000C020480000000000000000001D0000007A
-:10311000000000000000000000800000000000002F
-:1031200001182000C0304620000000000000000010
-:10313000D90048000000000000000000C02004008A
-:10314000000000000000000000A0000A00000000D5
-:103150000218A000C030462000000000000000005F
-:10316000D90048000000000000000000C02004005A
-:10317000000000000000000000A0000A00000000A5
-:103180000318C000C030462000000000000000000E
-:10319000D90048000000000000000000C02004002A
-:1031A000000000000000000000A0000A0000000075
-:1031B0000418F8E0C03046200000000000000000C5
-:1031C000D90048000000000000000000C0200400FA
-:1031D000000000000000000000A0000A0000000045
-:1031E0000518F880C03046200000000000000000F4
-:1031F000D90048000000000000000000C0200400CA
-:10320000000000000000000000A0000A0000000014
-:103210000618E000C030462000000000000000005A
-:10322000D90048000000000000000000C020040099
-:10323000000000000000000000A0000A00000000E4
-:103240000718F000C0304620000000000000000019
-:10325000D90048000000000000000000C020040069
-:10326000000000000000000000A0000A00000000B4
-:103270000818F3FCC03046200000000000000000E9
-:10328000D90048000000000000000000C020040039
-:10329000000000000000000000A0000A0000000084
-:1032A0000000003000200A2D000000000000000097
-:1032B000C0290C4000000000000000300020362330
-:1032C0000000000000000000C0200400000000001A
-:1032D0000000000000A0000A0000000086000000BE
-:1032E00000204411000000000000000000404801E0
-:1032F0000000000085000000C02044110000000014
-:103300000000000000404801000000000000217C97
-:10331000002044110000000000000018402102209D
-:10332000000000000000000014C000000000044580
-:1033300000800000C0494A20000004460000000050
-:10334000C02048000000000000000000C02048002D
-:103350000000000000000000C02048000000000045
-:103360008100000000204411000000000000000166
-:10337000002048110000000000000000C0200800EC
-:103380000000000000000000170000000000000026
-:103390000004217F006044110000068D0000001F22
-:1033A00000210230000000000000000014C00000F6
-:1033B000000000000000000000404C020000044B30
-:1033C00000000000C0200C00000000000000000011
-:1033D000C02010000000000000000000C020140009
-:1033E0000000000000000000C020180000000000E5
-:1033F00000000000C0201C000000000000007F0052
-:1034000000280A210000000000004500002F0222D1
-:1034100000000000000000000CE000000000045963
-:1034200000000000C020200000000000000000009C
-:1034300017000000000000000000001000280A2310
-:103440000000000000000010002F02220000000019
-:10345000000000000CE0000000000461810000009A
-:10346000002044110000000000000001002048116D
-:103470000000000000040000006946240000068DE2
-:103480000000000000400000000004668100000011
-:10349000002044110000000000000000002048113E
-:1034A000000000000000216D002044110000000019
-:1034B00000000000002048040000000000000000A0
-:1034C000006048050000069200000000002824F07B
-:1034D000000000000000000700280A230000000090
-:1034E00000000001002F0222000000000000000088
-:1034F0000AE000000000046D00000000002F00C979
-:10350000000000000000000004E00000000004864D
-:1035100000000000004000000000049300000002D2
-:10352000002F022200000000000000000AE000005E
-:103530000000047200000000002F00C9000000001D
-:103540000000000002E0000000000486000000000F
-:10355000004000000000049300000003002F02223E
-:1035600000000000000000000AE0000000000477F6
-:1035700000000000002F00C9000000000000000053
-:103580000CE0000000000486000000000040000085
-:103590000000049300000004002F0222000000003D
-:1035A000000000000AE000000000047C00000000B1
-:1035B000002F00C900000000000000000AE0000029
-:1035C000000004860000000000400000000004939A
-:1035D00000000005002F0222000000000000000093
-:1035E0000AE000000000048100000000002F00C974
-:1035F000000000000000000006E00000000004865B
-:1036000000000000004000000000049300000006DD
-:10361000002F022200000000000000000AE000006D
-:103620000000048600000000002F00C90000000018
-:103630000000000008E00000000004860000000018
-:10364000004000000000049300007F0000280A21D1
-:103650000000000000004500002F022200000000D2
-:10366000000000000AE00000000000000000000868
-:1036700000210A23000000000000000014C0000028
-:1036800000000490000021690020441100000000A7
-:1036900000000000C0204800000000000000000002
-:1036A000C02048000000000000000000C0204800CA
-:1036B00000000000CAFEBABE004048110000000031
-:1036C00000000000C02044000000000000000000D6
-:1036D000C02000000000000000000000C0404800C2
-:1036E0000000000000007F0000280A210000000008
-:1036F00000004500002F0222000000000000000032
-:103700000AE000000000049900000000C020000052
-:103710000000000000000000C020000000000000C9
-:1037200000000000C0400000000000000000000099
-:1037300000404C080000045900000000C0200800B0
-:10374000000000000000001040210E2000000000DA
-:1037500000000011402112200000000000000012B3
-:1037600040211620000000000000216900204411C3
-:1037700000000000000000000020480200000000DF
-:1037800000000000002102250000000000000000F1
-:1037900014E00000000004A300040000C0494A2017
-:1037A000000004A4FFFBFFFFC0284A200000000027
-:1037B00000000000002102230000000000000000C3
-:1037C00014E00000000004B000000000C020480029
-:1037D0000000000000000000C020480000000000C1
-:1037E0000000000000210224000000000000000092
-:1037F00014C00000000000008100000000204411FF
-:10380000000000000000000C002048110000000033
-:103810000000000000200010000000000000000078
-:1038200014C00000000004ACA000000000204411FF
-:1038300000000000CAFEBABE0040481100000000AF
-:10384000810000000020441100000000000000047E
-:1038500000204811000000000000216B00204411EE
-:103860000000000000000000C02048100000000020
-:10387000810000000020441100000000000000054D
-:1038800000204811000000000000216C00204411BD
-:103890000000000000000000C020481000000000F0
-:1038A00000000000002F02240000000000000000C3
-:1038B0000CE00000000000000000000000400000DC
-:1038C000000004AA00000000C0210A20000000003F
-:1038D0000000000014C00000000004C381000000CC
-:1038E00000204411000000000000000000204811EA
-:1038F000000000000000216D0020441100000000C5
-:1039000000000000C020480000000000000000008F
-:10391000C060480000000692000000000040000067
-:10392000000004C7810000000020441100000000D6
-:103930000000000100204811000000000004000009
-:10394000C02946200000000000000000C060000008
-:103950000000068D0000000100210222000000008E
-:103960000000000014C00000000004CE0000216927
-:10397000002044110000000000000000C0204800AA
-:103980000000000000000000C0204800000000000F
-:10399000000000000020481000000000CAFEBABE6F
-:1039A000004048110000000000000000C02044005A
-:1039B0000000000000000000C040481000000000AF
-:1039C0008100000000204411000000000000000100
-:1039D0000020481100000000000021F800204411E0
-:1039E000000000000000000E002048110000000050
-:1039F000000421F9006044110000068D0000000061
-:103A000000210230000000000000000014C000008F
-:103A1000000004D0000021800020441100000000BC
-:103A200000000000C020480000000000000000006E
-:103A3000C02000000000000000000000C02048007E
-:103A40000000000000000000C02000000000000096
-:103A500000000000C040480000000000000000031B
-:103A600000333E2F00000000000000010021022171
-:103A7000000000000000000014E00000000005004D
-:103A80000000002C00200A2D0000000000040000AF
-:103A900018E00C11000004EF0000000100333E2F7D
-:103AA0000000000000002169002044110000000017
-:103AB000000000000020480200000000000000009C
-:103AC00000204803000000000000000800300A2227
-:103AD0000000000000000000C020480000000000BE
-:103AE00000000000C0204800000000000000216924
-:103AF00000204411000000000000000000204802E7
-:103B0000000000000000000000204803000000004A
-:103B10000000000800300A22000000000000000041
-:103B2000C02048000000000000000000D8C048008D
-:103B3000000004E30000216900204411000000009F
-:103B4000000000000020480200000000000000000B
-:103B500000204803000000000000000800300A2296
-:103B60000000000000000000C0204800000000002D
-:103B700000000000C0204800000000000000002DF0
-:103B80000020122D000000000000000000290C831E
-:103B90000000000000002169002044110000000026
-:103BA00000000000002048020000000000000000AB
-:103BB00000204803000000000000000800300A2236
-:103BC0000000000000000000C020480000000000CD
-:103BD00000000000C02048000000000000000011AC
-:103BE00000210224000000000000000014C00000BA
-:103BF000000000000000000000400000000004AAD7
-:103C00000000002CC0203620000000000000002D25
-:103C1000C0403620000000000000000F00210221FB
-:103C2000000000000000000014C0000000000505B6
-:103C300000000000006000000000000B0000000019
-:103C4000D90000000000000000000000C040040097
-:103C500000000001B5000000002044110000000039
-:103C6000000020000020481100000000B600000005
-:103C700000204411000000000000A00000204811B6
-:103C800000000000B7000000002044110000000008
-:103C90000000C0000020481100000000B800000033
-:103CA00000204411000000000000F8E0002048114E
-:103CB00000000000B90000000020441100000000D6
-:103CC0000000F8800020481100000000BA00000049
-:103CD00000204411000000000000E0000020481116
-:103CE00000000000BB0000000020441100000000A4
-:103CF0000000F0000020481100000000BC0000009F
-:103D000000204411000000000000F3FC00204811D6
-:103D100000000000810000000020441100000000AD
-:103D2000000000020020481100000000000000FF19
-:103D300000280E300000000000000000002F0223C9
-:103D400000000000000000000CC000000000051989
-:103D500000000000C020080000000000000000007B
-:103D600014C000000000052E0000000000200C110F
-:103D7000000000000000001C0020362300000000AE
-:103D80000000002B00203623000000000000002966
-:103D90000020362300000000000000280020362309
-:103DA0000000000000000017002036230000000083
-:103DB000000000250020362300000000000000263F
-:103DC00000203623000000000000001500203623EC
-:103DD0000000000000000016002036230000000054
-:103DE000FFFFE00000200C11000000000000002197
-:103DF00000203623000000000000002200203623AF
-:103E00000000000000001FFF00200C110000000057
-:103E100000000023002036230000000000000024E2
-:103E20000020362300000000F1FFFFFF00283A2E9B
-:103E3000000000000000001AC0220E200000000058
-:103E4000000000000029386E000000008100000022
-:103E5000002044110000000000000006002048116E
-:103E6000000000000000002A402036200000000072
-:103E70008700000000204411000000000000000046
-:103E8000C0204800000000000000A1F40020441100
-:103E900000000000000000000020481000000000AA
-:103EA0000000000000200C110000000000000030A5
-:103EB00000203623000000009D0000000020441177
-:103EC000000000000000001F40214A200000000008
-:103ED00096000000002044110000000000000000D7
-:103EE000C02048000000000000000000C0200C00BE
-:103EF0000000000000000000C020100000000000D2
-:103F00000000001F00211624000000000000000037
-:103F100014C00000000000000000001D0020362337
-:103F2000000000000000000300281E230000000025
-:103F3000000000080022222300000000FFFFF00024
-:103F4000002822280000000000000000002920E8CE
-:103F5000000000000000001F0020362800000000C4
-:103F60000000001800211E230000000000000020B7
-:103F70000020362700000000000000020022162466
-:103F80000000000000000000003014A80000000045
-:103F90000000001E00203625000000000000000385
-:103FA00000211A24000000001000000000281A263A
-:103FB00000000000EFFFFFFF00283A2E0000000085
-:103FC00000000000004938CE0000067B0000000120
-:103FD00040280A20000000000000000640280E20B3
-:103FE0000000000000000300C028122000000000B4
-:103FF0000000000800211224000000000000000062
-:10400000C02016200000000000000000C0201A2080
-:10401000000000000000000000210222000000005B
-:104020000000000014C000000000056681000000D0
-:104030000020441100000000000000010020481191
-:10404000000000000000225800300A240000000098
-:1040500000040000006946220000068D000021696E
-:10406000002044110000000000000000002048056E
-:10407000000000000002000000294A2600000000A5
-:10408000000000000020481000000000CAFEBABE78
-:10409000002048110000000000000002002F022351
-:1040A00000000000000000000CC000000000056ED1
-:1040B00000000000C0201C100000000000000000F4
-:1040C000C04000000000057C00000002002F022319
-:1040D00000000000000000000CC000000000056EA1
-:1040E00081000000002044110000000000000001D9
-:1040F00000204811000000000000225800300A246F
-:104100000000000000040000006946220000068D47
-:1041100000000000C0201C10000000000000000093
-:10412000C04000000000057C00000000002F0223BA
-:1041300000000000000000000CC00000000005723C
-:1041400000000000C0201C00000000000000000073
-:10415000C04000000000057C00000004002F022386
-:1041600000000000000000000CC000000000057A04
-:104170008100000000204411000000000000000049
-:1041800000204811000000000000216D00204411B3
-:104190000000000000000000C020480000000000F7
-:1041A00000000000C060480000000692000000000F
-:1041B00000401C100000057C00000000C020000032
-:1041C0000000000000000000C040000000000000EF
-:1041D000000000000EE000000000057E000000006E
-:1041E00000600000000005C900000000002F02244C
-:1041F00000000000000000000CC000000000058F5F
-:104200000000A2B7002044110000000000000000E0
-:104210000020480700000000810000000020441139
-:104220000000000000000001002048110000000014
-:104230000004A2B6006044110000068D0000001AC0
-:10424000002122300000000000000006002226307D
-:104250000000000000042004006044110000068DEE
-:104260000000A2C400204411000000000000000073
-:10427000003048E9000000000000000000E00000FD
-:104280000000058D0000A2D10020441100000000B4
-:104290000000000000404808000000000000A2D11B
-:1042A00000204411000000000000000100504A28D6
-:1042B0000000000000000001002F022400000000A8
-:1042C000000000000CC00000000005A00000A2BB20
-:1042D00000204411000000000000000000204807FA
-:1042E00000000000810000000020441100000000D8
-:1042F0000000000100204811000000000004A2BAE4
-:10430000006044110000068D0000001A00212230D8
-:10431000000000000000000600222630000000001F
-:1043200000042004006044110000068D0000A2C5B6
-:10433000002044110000000000000000003048E9A7
-:10434000000000000000000000E000000000059EEA
-:104350000000A2D200204411000000000000000074
-:1043600000404808000000000000A2D200204411D4
-:10437000000000000000000100504A28000000007A
-:1043800000000002002F02240000000000000000D6
-:104390000CC00000000005B10000A2BF00204411C5
-:1043A000000000000000000000204807000000009E
-:1043B0008100000000204411000000000000000106
-:1043C00000204811000000000004A2BE006044115B
-:1043D0000000068D0000001A0021223000000000BD
-:1043E0000000000600222630000000000004200427
-:1043F000006044110000068D0000A2C60020441198
-:104400000000000000000000003048E9000000004B
-:104410000000000000E00000000005AF0000A2D393
-:104420000020441100000000000000000040480887
-:10443000000000000000A2D3002044110000000092
-:104440000000000100504A28000000000000A2C344
-:104450000020441100000000000000000020480778
-:104460000000000081000000002044110000000056
-:104470000000000100204811000000000004A2C25A
-:10448000006044110000068D0000001A0021223057
-:10449000000000000000000600222630000000009E
-:1044A00000042004006044110000068D0000A2C733
-:1044B000002044110000000000000000003048E926
-:1044C000000000000000000000E00000000005BE49
-:1044D0000000A2D4002044110000000000000000F1
-:1044E00000404808000000000000A2D40020441151
-:1044F000000000000000000100504A2800000000F9
-:1045000085000000002044110000000000000000B1
-:1045100000204801000000000000304A0020441143
-:104520000000000001000000002048110000000011
-:104530000000000000400000000005C4A4000000CE
-:10454000C02044110000000000000000C0404800EE
-:104550000000000000000000C0600000000005C96D
-:1045600000000000C0400400000000010000002C1A
-:1045700000203621000000008100000000204411CE
-:1045800000000000000000060020481100000000AC
-:1045900000000000002F02300000000000000000BA
-:1045A0000CC00000000005D0000000000020041135
-:1045B000000000000000003000403621000005E34C
-:1045C000000000300020062D0000000000007E00EA
-:1045D000002806210000000000000000002F02213A
-:1045E00000000000000000000CE00000000005E3F7
-:1045F00081000000002044110000000000000001C4
-:1046000000204811000000000004A0920060441146
-:104610000000068D00000031002036300000000050
-:104620000004A093006044110000068D00000032D9
-:1046300000203630000000000004A2B600604411E3
-:104640000000068D0000003300203630000000001E
-:104650000004A2BA006044110000068D000000347E
-:1046600000203630000000000004A2BE00604411AB
-:104670000000068D000000350020363000000000EC
-:104680000004A2C2006044110000068D0000003644
-:1046900000203630000000000004200400604411B7
-:1046A0000000068D0001A2A40020441100000000BB
-:1046B0000000003F00204811000000000000003F03
-:1046C00000204811000000000000003F00204811B9
-:1046D000000000000000003F002048110000000022
-:1046E0000000000500204811000000000000A1F4B7
-:1046F00000204411000000000000000000204811CC
-:1047000000000000880000000020441100000000AC
-:10471000000000010020481100000000810000009E
-:104720000020441100000000000000060020481195
-:104730000000000000000001002F02300000000017
-:10474000000000000CE000000000062C000000301B
-:104750000020062D0000000000000000002F0221B4
-:1047600000000000000000000CE000000000062C2B
-:104770008100000000204411000000000000000142
-:10478000002048110000000000007E0000280621E3
-:104790000000000000000000002F022100000000C7
-:1047A000000000000CE00000000006050000A092E0
-:1047B00000204411000000000000003100204A2DBC
-:1047C000000000000000A093002044110000000041
-:1047D0000000003200204A2D000000000000A2B6B8
-:1047E00000204411000000000000003300204A2D8A
-:1047F000000000000000A2BA0020441100000000E8
-:104800000000003400204A2D000000000000A2BE7D
-:1048100000204411000000000000003500204A2D57
-:10482000000000000000A2C20020441100000000AF
-:104830000000003600204A2D00000000000000307B
-:104840000020062D00000000000001FF00280621C6
-:104850000000000000000000002F02210000000006
-:10486000000000000CE000000000062B000000002B
-:1048700000210221000000000000000014C0000020
-:104880000000060E0004A003006044110000068D25
-:104890000000A00300204411000000000000000000
-:1048A0000020481000000000000000010021062147
-:1048B000000000000000000014C00000000006130B
-:1048C0000004A010006044110000068D0000A0103C
-:1048D00000204411000000000000000000204810EB
-:1048E000000000000000000100210621000000007F
-:1048F00000000000002F0221000000000000000066
-:104900000CE000000000062B0004A0110060441120
-:104910000000068D0000A0110020441100000000DE
-:104920000000000000204810000000000004A01259
-:10493000006044110000068D0000A0120020441108
-:1049400000000000000000000020481000000000EF
-:104950000004A013006044110000068D0000A013A5
-:10496000002044110000000000000000002048105A
-:10497000000000000004A014006044110000068D37
-:104980000000A014002044110000000000000000FE
-:1049900000204810000000000004A0150060441131
-:1049A0000000068D0000A01500204411000000004A
-:1049B0000000000000204810000000000004A016C5
-:1049C000006044110000068D0000A0160020441174
-:1049D000000000000000000000204810000000005F
-:1049E0000004A017006044110000068D0000A0170D
-:1049F00000204411000000000000000000204810CA
-:104A00000000000000042004006044110000068D36
-:104A10000000002C0080062D00000000FF000000B8
-:104A20000020441100000000000000000020481198
-:104A300000000000000000010020481100000000FC
-:104A4000000000020080481100000000000000008B
-:104A50000EE000000000063D000000300020062DA2
-:104A600000000000000000020028062100000000F5
-:104A700000000000002F02210000000000000000E4
-:104A80000CE000000000063B810000000020441103
-:104A9000000000000000000100204811000000009C
-:104AA00000042004006044110000068D0000100086
-:104AB00000200811000000000000002B002036221A
-:104AC000000000000000000000600000000006413F
-:104AD0000000000000600000000005C99800000010
-:104AE0000020441100000000000000000080481178
-:104AF0000000000000000000C0600000000006414F
-:104B000000000000C0400400000000010000A2A45A
-:104B10000020441100000000000000220020481185
-:104B20000000000089000000002044110000000087
-:104B300000000001004048110000062D9700000011
-:104B40000020441100000000000000000020481177
-:104B5000000000008A000000002044110000000056
-:104B600000000000004048110000062D0000000079
-:104B7000006000000000065C0000201000204411CE
-:104B8000000000000000800000204811000000002C
-:104B90000001A2A4C0204411000000000000001683
-:104BA000006048110000036E000020100020441136
-:104BB000000000000001000000204811000000007B
-:104BC00081000000002044110000000000000001EE
-:104BD00000204811000000000000217C002044114A
-:104BE00000000000098000000020481100000000C3
-:104BF000FFFFFFFF00204811000000000000000040
-:104C00000020481100000000000000001700000014
-:104C1000000000000004217F006044110000068DA8
-:104C20000000001F00210230000000000000000012
-:104C300014C00000000000000000000400404C11FF
-:104C400000000656000000000040000000000000C8
-:104C50000000001700201E2D0000000000000004CE
-:104C600000291E27000000000000001700803627E2
-:104C7000000000000000001700201E2D00000000B2
-:104C8000FFFFFFFB00281E270000000000000017A8
-:104C900000803627000000000000001700201E2DB5
-:104CA000000000000000000800291E27000000008E
-:104CB00000000017008036270000000000000017E9
-:104CC00000201E2D00000000FFFFFFF700281E2718
-:104CD00000000000000000170080362700000000E0
-:104CE000000020100020441100000000000080009F
-:104CF00000204811000000000001A2A4002044117F
-:104D00000000000000000016006048110000036E63
-:104D100000002010002044110000000000010000ED
-:104D200000204811000000000000217C00204411F8
-:104D30000000000001800000002048110000000079
-:104D4000FFFFFFFF002048110000000000000000EE
-:104D500000204811000000000000000017000000C3
-:104D6000000000008100000000204411000000004D
-:104D70000000000100204811000000000004217F15
-:104D8000006044110000068D0000001F0021023069
-:104D9000000000000000000014C000000000068CAD
-:104DA0000000001000404C110000067200000000DE
-:104DB000C0200400000000000000000038C0000017
-:104DC000000000000000001D00200A2D000000006F
-:104DD0000000001E00200E2D000000000000001F3B
-:104DE0000020122D00000000000000200020162DE1
-:104DF00000000000000021690020441100000000B4
-:104E00000000000000204804000000000000000036
-:104E100000204805000000000000000000204801BC
-:104E200000000000CAFEBABE0020481100000000C9
-:104E30000000000400301224000000000000000008
-:104E4000002F006400000000000000000CC0000003
-:104E50000000068B0000000300281A22000000005A
-:104E6000000000080022122200000000FFFFF000F6
-:104E7000002812240000000000000000002910C4D7
-:104E8000000000000000001F004036240000000069
-:104E90000000000000800000000000000000000092
-:104EA0001AC000000000068D9F0000000020441181
-:104EB00000000000CAFEBABE002048110000000039
-:104EC000000000001AE00000000006900000000052
-:104ED0000080000000000000000000001AC0000078
-:104EE000000006929E000000002044110000000017
-:104EF000CAFEBABE002048110000000000000000F9
-:104F00001AE000000000069500000000008000008C
-:104F10000000000000000000006000000000000B26
-:104F200000001000006004110000031500000000E4
-:104F300000200411000000000000000000600811C3
-:104F4000000001B20000225C0020441100000000BB
-:104F5000000000030020481100000000000022565D
-:104F600000204411000000000000001B0020481138
-:104F7000000000000000A1FC00204411000000001F
-:104F80000000000100204811000000000001A1FD08
-:104F9000C0204411000000000000002100201E2D50
-:104FA000000000000000001000221E27000000008A
-:104FB000000000240020222D000000000000FFFF60
-:104FC00000282228000000000000000000294907F6
-:104FD0000000000000000000002048110000000058
-:104FE000000000220020222D000000000000FFFF32
-:104FF00000282228000000000000000000294907C6
-:105000000000000000000000002048110000000027
-:105010000000002300201E2D0000000000000010F2
-:1050200000221E27000000000000000000294907A0
-:1050300000000000000000000040481100000000D7
-:105040000000000000000000000000000000000060
-:105050000000000000000000000000000000000050
-:105060000000000000000000000000000000000040
-:105070000000000000000000000000000000000030
-:105080000000000000000000000000000000000020
-:105090000000000000000000000000000000000010
-:1050A0000000000000000000000000000000000000
-:1050B00000000000000000000000000000000000F0
-:1050C00000000000000000000000000000000000E0
-:1050D00000000000000000000000000000000000D0
-:1050E00000000000000000000000000000000000C0
-:1050F00000000000000000000000000000000000B0
-:10510000000000000000000000000000000000009F
-:10511000000000000000000000000000000000008F
-:10512000000000000000000000000000000000007F
-:10513000000000000000000000000000000000006F
-:10514000000000000000000000000000000000005F
-:10515000000000000000000000000000000000004F
-:10516000000000000000000000000000000000003F
-:10517000000000000000000000000000000000002F
-:10518000000000000000000000000000000000001F
-:10519000000000000000000000000000000000000F
-:1051A00000000000000000000000000000000000FF
-:1051B00000000000000000000000000000000000EF
-:1051C00000000000000000000000000000000000DF
-:1051D00000000000000000000000000000000000CF
-:1051E00000000000000000000000000000000000BF
-:1051F00000000000000000000000000000000000AF
-:10520000000000000000000000000000000000009E
-:10521000000000000000000000000000000000008E
-:10522000000000000000000000000000000000007E
-:10523000000000000000000000000000000000006E
-:10524000000000000000000000000000000000005E
-:10525000000000000000000000000000000000004E
-:10526000000000000000000000000000000000003E
-:10527000000000000000000000000000000000002E
-:10528000000000000000000000000000000000001E
-:10529000000000000000000000000000000000000E
-:1052A00000000000000000000000000000000000FE
-:1052B0000142050205C002500000000001C3016860
-:1052C000043F05C000000000022502090250015100
-:1052D000000000000223024502A00241000000007D
-:1052E00003D705C005C005C0000000000649064AF6
-:1052F000031F05C00000000005C005C503200340D2
-:1053000000000000032A0282034203340000000070
-:1053100005C005C005C005C00000000005C005515E
-:1053200005C005C00000000003BA05C004BB03446B
-:1053300000000000049A0450043D05C00000000075
-:1053400004D005C0044104DD00000000045005073E
-:10535000035103750000000005C005C005C005C06D
-:105360000000000005C005C005C005C00000000029
-:1053700005C005C0063F05C70000000005C005C008
-:10538000000705C00000000005C005C005C005C03D
-:105390000000000005C005C005C005C000000000F9
-:1053A00003F803ED0408040600000000040E040ADC
-:1053B000040C041000000000041C04180424042041
-:1053C00000000000042C0428043404300000000015
-:1053D00005C005C0043805C00000000005C005C0B8
-:1053E00005C005C00000000005C005C005C005C01F
-:1053F0000000000000020679069700060000000089
-:00000001FF
--- zfcpdump-kernel-4.4.orig/firmware/radeon/RV610_pfp.bin.ihex
+++ /dev/null
@@ -1,145 +0,0 @@
-:1000000000CA040000A00000007E828B007C038BED
-:10001000008001B8007C038B00D4401E00EE001E5F
-:1000200000CA040000A00000007E828B00C41838C3
-:1000300000CA240000CA2800009581A800C41C3A08
-:1000400000C3C00000CA080000CA0C00007C744B4A
-:1000500000C200050099C00000C41C3A007C744C2A
-:1000600000C0FFF000042C0400309002007D250049
-:1000700000351402007D350B00255403007CD5802B
-:1000800000259C030095C00400D5001B007EDDC147
-:10009000007D9D8000D6801B00D5801B00D4401EB3
-:1000A00000D5401E00D6401E00D6801E00D4801E03
-:1000B00000D4C01E009783D300D5C01E00CA08001C
-:1000C0000080001A00CA0C0000E4011E00D4001ECB
-:1000D0000080000C00C4183800E4013E00D4001E6B
-:1000E0000080000C00C4183800D4401E00EE001E32
-:1000F00000CA040000A00000007E828B00E4011E04
-:1001000000D4001E00D4401E00EE001E00CA0400F1
-:1001100000A00000007E828B00E4013E00D4001E9F
-:1001200000D4401E00EE001E00CA040000A0000023
-:10013000007E828B00CA180000D4401E00D5801EAD
-:100140000080005300D4007500D4401E00CA08008F
-:1001500000CA0C0000CA100000D4801900D4C018D6
-:1001600000D5001700D4801E00D4C01E00D5001E8C
-:1001700000E2001E00CA040000A00000007E828B86
-:1001800000CA080000D4806000D4401E0080000037
-:1001900000D4801E00CA080000D4806100D4401E34
-:1001A0000080000000D4801E00CA080000CA0C00B5
-:1001B00000D4401E00D4801600D4C01600D4801E87
-:1001C000008001B800D4C01E00C6084300CA0C005D
-:1001D00000CA10000094800400CA140000E420F358
-:1001E00000D4201300D5606500D4E01C00D5201C8D
-:1001F00000D5601C008000000006200100C60843F6
-:1002000000CA0C0000CA1000009483F700CA140052
-:1002100000E420F30080007900D4201300C60843D6
-:1002200000CA0C0000CA1000009883EF00CA140036
-:1002300000D400640080008D0000000000C414326F
-:1002400000C6184300C4082F0095400500C40C30B8
-:1002500000D4401E0080000000EE001E009583F5D3
-:1002600000C4103100D4403300D5206500D4A01C58
-:1002700000D4E01C00D5201C00E4015E00D4001E68
-:10028000008000000006200100CA1800000A2001BA
-:1002900000D6007600C408360098800700C61045D6
-:1002A0000095011000D4001F00D46062008000009F
-:1002B00000D4206200CC383500CC1433008401BB5C
-:1002C00000D4007200D5401E0080000000EE001E29
-:1002D00000E2001A008401BB00E2001A00CC104BBF
-:1002E00000CC0447002C9401007D098B0098400548
-:1002F000007D15CB00D4001A008001B800D4006D39
-:100300000034440100CC0C480098403A00CC2C4A00
-:100310000095800400CC0449008001B800D4001A84
-:1003200000D4C01A00282801008400F000CC10037B
-:100330000098801B0004380C008400F000CC1003EF
-:100340000098801700043808008400F000CC1003E7
-:100350000098801300043804008400F000CC1003DF
-:100360000098801400CC104C009A800900CC144DE9
-:10037000009840DC00D4006D00CC184800D5001A6D
-:1003800000D5401A008000C900D5801A0096C0D55B
-:1003900000D4006D008001B800D4006E009AC00344
-:1003A00000D4006D00D4006E0080000000EC007FDF
-:1003B000009AC0CC00D4006D008001B800D4006E5B
-:1003C00000CC140300CC180300CC1C03007D910367
-:1003D000007DD583007D190C0035CC1F0035701FC2
-:1003E000007CF0CB007CD08B00880000007E8E8BE0
-:1003F0000095C00400D4006E008001B800D4001A3B
-:1004000000D4C01A00CC080300CC0C0300CC1003AD
-:1004100000CC140300CC180300CC1C0300CC240334
-:1004200000CC28030035C41F0036B01F007C704B81
-:100430000034F01F007C704B0035701F007C704B47
-:10044000007D8881007DCCC1007E5101007E9541F8
-:10045000007C9082007CD4C2007C848B009AC00314
-:10046000007C8C8B002C88010098809E00D4006D4D
-:100470000098409C00D4006E00CC084C00CC0C4D81
-:1004800000CC104800D4801A00D4C01A00800101AA
-:1004900000D5001A00CC083200D40032009482D972
-:1004A00000CA0C0000D4401E0080000000D4001ED2
-:1004B00000E4011E00D4001E00CA080000CA0C009F
-:1004C00000CA100000D4401E00CA140000D4801ED0
-:1004D00000D4C01E00D5001E00D5401E00D54034FB
-:1004E0000080000000EE001E0028040400E2001A54
-:1004F00000E2001A00D4401A00CA380000CC0803F9
-:1005000000CC0C0300CC0C0300CC0C03009882BD83
-:1005100000000000008401BB00D7A06F0080000035
-:1005200000EE001F00CA040000C2FF0000CC083427
-:1005300000C13FFF007C74CB007CC90B007D010F24
-:10054000009902B0007C738B008401BB00D7A06FC0
-:100550000080000000EE001F00CA080000281900FB
-:10056000007D898B009580140028140400CA0C00BB
-:1005700000CA100000CA1C0000CA240000E2001FCC
-:1005800000D4C01A00D5001A00D5401A00CC1803B8
-:1005900000CC2C0300CC2C0300CC2C03007DA58BBD
-:1005A000007D9C4700984297000000000080016198
-:1005B00000D4C01A00D4401E00D4801E0080000069
-:1005C00000EE001E00E4011E00D4001E00D4401EF8
-:1005D00000EE001E00CA040000A00000007E828B16
-:1005E00000E4013E00D4001E00D4401E00EE001EB8
-:1005F00000CA040000A00000007E828B00CA080030
-:1006000000248C06000CCC060098C00600CC104ECE
-:100610000099000400D4007300E4011E00D4001E01
-:1006200000D4401E00D4801E0080000000EE001E9A
-:1006300000CA080000CA0C000034D01800251001C0
-:100640000095002100C17FFF00CA100000CA1400FD
-:1006500000CA180000D4801D00D4C01D007DB18BDD
-:1006600000C1420200C2C00100D5801D0034DC0E72
-:10067000007D5D4C007F734C00D7401E00D5001EEE
-:1006800000D5401E00C1420000C2C00000099C010C
-:100690000031DC10007F5F4C007F734C00042802A7
-:1006A000007D838000D5A86F00D5806600D7401EEE
-:1006B00000EC005E00C8240200C82402008001B8DB
-:1006C00000D6007600D4401E00D4801E00D4C01E88
-:1006D0000080000000EE001E0080000000EE001F01
-:1006E00000D4001F0080000000D4001F00D4001FB1
-:1006F0000088000000D4001F00000000000000007F
-:1007000000000000000000000000000000000000E9
-:1007100000000000000000000000000000000000D9
-:1007200000000000000000000000000000000000C9
-:1007300000000000000000000000000000000000B9
-:1007400000000000000000000000000000000000A9
-:100750000000000000000000000000000000000099
-:100760000000000000000000000000000000000089
-:100770000000000000000000000000000000000079
-:100780000000000000000000000000000000000069
-:100790000000000000000000000000000000000059
-:1007A0000000000000000000000000000000000049
-:1007B0000000000000000000000000000000000039
-:1007C0000000000000000000000000000000000029
-:1007D0000000000000000000000000000000000019
-:1007E0000000000000000000000000000000000009
-:1007F00000000000000000000000000000000000F9
-:1008000000010171000201780003008F0004007FE5
-:10081000000500030006003F000700320008012C1D
-:1008200000090046000A0036001001B6001700A2B9
-:100830000022013A00230149002000B400240125D0
-:100840000027004D0028006A002A0060002B00529B
-:10085000002F0065003200870034017F003C015604
-:10086000003F00720041018C0044012E00550173CD
-:100870000056017A0060000B00610034006200380D
-:1008800000630038006400380065003800660038F6
-:10089000006700380068003A00690041006A0048BB
-:1008A000006B0048006C0048006D0048006E004876
-:1008B000006F00480000000600000006000000066F
-:1008C0000000000600000006000000060000000610
-:1008D0000000000600000006000000060000000600
-:1008E00000000006000000060000000600000006F0
-:1008F00000000006000000060000000600000006E0
-:00000001FF
--- zfcpdump-kernel-4.4.orig/firmware/radeon/RV620_me.bin.ihex
+++ /dev/null
@@ -1,1345 +0,0 @@
-:1000000000000000C020040000000000000000000C
-:1000100000A0000A000000000000FFFF00284621A9
-:100020000000000000000000D900480000000000AF
-:1000300000000000C02004000000000000000000DC
-:1000400000A0000A000000000000000000E0000026
-:100050000000000000010000C02946200000000050
-:1000600000000000D900480000000000000000006F
-:10007000C0200400000000000000000000A0000AF2
-:10008000000000008100000000204411000000007A
-:1000900000000001002048110000000000042004BE
-:1000A000006044110000068D0000000000600000A8
-:1000B000000006310000000000600000000006455E
-:1000C00000000000C02008000000000000000F0039
-:1000D000002816220000000000000008002116255C
-:1000E000000000000000001800203625000000007D
-:1000F0008D000000002044110000000000000004FA
-:10010000002F022500000000000000000CE00000AD
-:1001100000000018004120000040481100000019B4
-:100120000042200000204811000000008E00000066
-:1001300000204411000000000000002800204A2D8B
-:1001400000000000900000000020441100000000AA
-:100150000000000000204805000000000000000C26
-:1001600000211622000000000000000300281625D0
-:10017000000000000000001900211A220000000009
-:100180000000000400281A26000000000000000003
-:10019000002914C5000000000000001900203625C9
-:1001A0000000000000000000003A140200000000FF
-:1001B00000000016002116250000000000000003CA
-:1001C00000281625000000000000001700200E2D5A
-:1001D00000000000FFFFFFFC00280E2300000000CD
-:1001E00000000000002914A3000000000000001718
-:1001F00000203625000000000000800000280E22AC
-:10020000000000000000000700220E230000000094
-:10021000000000000029386E0000000020000000EF
-:1002200000280E22000000000000000600210E231E
-:1002300000000000000000000029386E00000000EF
-:100240000000000000220222000000000000000068
-:1002500014E0000000000038000000002EE0000064
-:1002600000000035000000002CE000000000003716
-:100270000000000000400E2D0000003900000008C2
-:1002800000200E2D00000000000000090040122D8B
-:10029000000000460000000100400E2D0000003963
-:1002A00000000000C0200C0000000000003FFFFC28
-:1002B0000028122300000000000000020022122487
-:1002C000000000000000001F00211E2300000000AD
-:1002D0000000000014E000000000003E00000008E4
-:1002E00000401C11000000410000000D00201E2DE8
-:1002F000000000000000000F00281E270000000082
-:100300000000000300221E27000000007FC0000044
-:1003100000281A23000000000000001400211A2603
-:10032000000000000000000100331A260000000059
-:100330000000000800221A26000000000000000053
-:1003400000290CC700000000000000270020362410
-:100350000000000000007F000028122100000000C3
-:1003600000001400002F0224000000000000000024
-:100370000CE000000000004B0000000100290E23EB
-:10038000000000000000000E0020362300000000E6
-:100390000000E0000020441100000000FFF8000011
-:1003A00000294A230000000000000000003A2C024F
-:1003B000000000000000000200220E2B00000000E0
-:1003C000FC00000000280E23000000000000000FC9
-:1003D000002036230000000000001FFF00294A23F0
-:1003E000000000000000002700204A2D000000004F
-:1003F000000000000020481100000000000000295B
-:1004000000200E2D00000000060A020000294A23E9
-:100410000000000000000000002048110000000063
-:100420000000000000204811000000000000000152
-:1004300000210222000000000000000014E0000083
-:1004400000000061000000002EE000000000005FDE
-:10045000000000002CE000000000005E0000000032
-:1004600000400E2D000000620000000100400E2D33
-:10047000000000620000000A00200E2D00000000B5
-:100480000000000B0040122D0000006A0000000078
-:10049000C0200C0000000000003FFFFC00281223D9
-:1004A00000000000000000020022122400000000F2
-:1004B0007FC0000000281623000000000000001488
-:1004C0000021162500000000000000010033162561
-:1004D000000000008000000000280E230000000043
-:1004E0000000000000290CA3000000003FFFFC00FA
-:1004F00000290E23000000000000001F00211E2321
-:10050000000000000000000014E000000000006D8A
-:100510000000010000401C11000000700000000DF0
-:1005200000201E2D00000000000000F000281E2703
-:10053000000000000000000400221E270000000050
-:100540008100000000204411000000000000000DA8
-:100550000020481100000000FFFFF0FF00281A30C3
-:10056000000000000000A02800204411000000004E
-:1005700000000000002948E6000000000000A0186C
-:1005800000204411000000003FFFFFFF00284A2325
-:10059000000000000000A010002044110000000036
-:1005A00000000000002048040000000000000030AF
-:1005B0000020162D00000000000000020029162572
-:1005C0000000000000000030002036250000000080
-:1005D000000000250020162D000000000000000093
-:1005E000002F00A300000000000000000CC000006D
-:1005F00000000083000000260020162D00000000EF
-:1006000000000000002F00A4000000000000000017
-:100610000CC000000000008400000000004000004A
-:100620000000008A000000250020362300000000A2
-:100630000000002600203624000000000000001703
-:1006400000201E2D000000000000000200210227F3
-:10065000000000000000000014E000000000008A1C
-:1006600000000000006000000000066800000000BC
-:10067000006000000000065C0000000200210E2265
-:10068000000000000000000014C000000000008D09
-:1006900000000012C040362000000093000000005F
-:1006A0002EE0000000000091000000002CE000009F
-:1006B000000000900000000200400E2D000000929B
-:1006C0000000000300400E2D000000920000000C0E
-:1006D00000200E2D00000000000000120020362334
-:1006E000000000000000000300210E2200000000B6
-:1006F0000000000014C00000000000980000A00CE2
-:10070000002044110000000000000000C02048004C
-:100710000000000000000000C0404800000000A0F1
-:100720000000A00C002044110000000000000000A8
-:100730000020481100000000000000002EE0000032
-:100740000000009E000000002CE000000000009D62
-:100750000000000200400E2D0000009F000000037A
-:1007600000400E2D0000009F0000000C00200E2D08
-:10077000000000000000000000204803000000000E
-:1007800000000000003A0C0200000000003F0000E2
-:1007900000280E23000000000000001000210E239E
-:1007A00000000000000000110020362300000000BF
-:1007B0000000001E0021022B0000000000000000CD
-:1007C00014C00000000000A700000016C020362062
-:1007D000000000000000001F0021022B00000000AC
-:1007E0000000000014C00000000000AA0000001576
-:1007F000C0203620000000000000000800210E2B61
-:10080000000000000000007F00280E230000000010
-:1008100000000000002F0223000000000000000084
-:100820000CE00000000000E10000000027000000D4
-:10083000000000000000000000600000000002A3B3
-:1008400000000001002F0223000000000000000053
-:100850000AE00000000000B300000000006000009B
-:100860000000013A81000000002044110000000057
-:100870000000000600204811000000000000000CED
-:1008800000221E300000000099800000002044116A
-:1008900000000000000000040020122D00000000F5
-:1008A00000000008002212240000000000000010D8
-:1008B00000201811000000000000000000291CE4C6
-:1008C0000000000000000000006048070000012F49
-:1008D0009B00000000204411000000000000000008
-:1008E00000204802000000009C000000002044118D
-:1008F00000000000000000000033146F0000000042
-:100900000000000100333E23000000000000000052
-:10091000D9004800000000000000000000203C0555
-:1009200000000000810000000020441100000000D1
-:100930000000000E00204811000000000000000030
-:1009400000201010000000000000E007002044110B
-:10095000000000000000000F0021022B000000003A
-:100960000000000014C00000000000CB00F8FF08E9
-:1009700000204811000000009800000000404811CD
-:10098000000000DC000000F000280E220000000043
-:10099000000000A0002F0223000000000000000063
-:1009A0000CC00000000000DA0000001100200E2D35
-:1009B0000000000000000001002F022300000000E2
-:1009C000000000000CE00000000000D50000000264
-:1009D000002F022300000000000000000CE00000D7
-:1009E000000000D400003F0000400C11000000D6C1
-:1009F00000001F0000400C11000000D600000F0096
-:100A000000200C11000000000038000900294A23D2
-:100A1000000000003F00000000280E2B0000000036
-:100A20000000000200220E2300000000000000076A
-:100A300000494A23000000DC00380F09002048115B
-:100A400000000000680000070020481100000000BE
-:100A50000000000800214A270000000000000000FC
-:100A60000020481100000000060A020000294A2464
-:100A700000000000000000000020481100000000FD
-:100A80000000000000204811000000000000A20249
-:100A9000002044110000000000FF000000280E228A
-:100AA000000000000000008000294A230000000030
-:100AB0000000002700200E2D00000000000000268E
-:100AC0000020122D0000000000000000002F008315
-:100AD00000000000000000000CE00000000000EA40
-:100AE000000000000060000000000662000000003E
-:100AF00000400000000000EB00000000006000006B
-:100B000000000665000000070020222D0000000004
-:100B10000000000500220E2200000000001000006E
-:100B200000280E23000000000000000000292068BB
-:100B30000000000000000000003A0C02000000006D
-:100B4000000000EF00280E2300000000000000005D
-:100B500000292068000000000000001700200E2D72
-:100B6000000000000000000300210223000000003C
-:100B70000000000014E00000000000F80000000B7E
-:100B800000210228000000000000000014C0000046
-:100B9000000000F8000004000029222800000000E6
-:100BA0000000001400203628000000000000001C97
-:100BB00000210E22000000000000000014C0000010
-:100BC000000000FD0000A30C002044110000000004
-:100BD0000000000000204811000000000000001E7E
-:100BE00000210E22000000000000000014C00000E0
-:100BF0000000010B0000A30F0020441100000000C2
-:100C00000000001100200E2D000000000000000177
-:100C1000002F022300000000000000000CC00000B4
-:100C200000000104FFFFFFFF004048110000010B1E
-:100C300000000002002F022300000000000000005E
-:100C40000CC00000000001070000FFFF0040481139
-:100C50000000010B00000004002F02230000000030
-:100C6000000000000CC000000000010A000000FFAE
-:100C7000004048110000010B000000010020481155
-:100C8000000000000002C400002044110000000029
-:100C90000000001F00210E220000000000000000E4
-:100CA00014C00000000001120000001040210E20BE
-:100CB00000000000000000130020362300000000A8
-:100CC0000000001840224A20000000000000001030
-:100CD000C0424A20000001140000000000200C1156
-:100CE0000000000000000013002036230000000078
-:100CF000000000000020481100000000000000007B
-:100D000000204811000000000000000A002010111F
-:100D10000000000000000000002F0224000000007E
-:100D2000000000000CE000000000011B00000000BB
-:100D300000204811000000000000000100531224B0
-:100D400000000117FFBFFFFF00283A2E000000003F
-:100D50000000001B00210222000000000000000033
-:100D600014C000000000012E81000000002044118A
-:100D7000000000000000000D0020481100000000ED
-:100D80000000001800220E3000000000FC000000EF
-:100D900000280E2300000000810000000020441104
-:100DA000000000000000000E0020481100000000BC
-:100DB0000000000000201010000000000000E00E05
-:100DC000002044110000000007F8FF08002048112F
-:100DD000000000000000000000294A23000000007D
-:100DE0000000001C00201E2D000000000000000874
-:100DF00000214A27000000000000000000204811E8
-:100E000000000000060A020000294A240000000039
-:100E10000000000000204811000000000000000059
-:100E200000204811000000000000000000800000C9
-:100E300000000000810000000020441100000000BC
-:100E40000000000100204811000000000000217C8B
-:100E50000020441100000000008000000020481124
-:100E60000000000000000000002048060000000014
-:100E70000000000800214A270000000000000000D8
-:100E800017000000000000000004217F00604411F2
-:100E90000000068D0000001F00210230000000004D
-:100EA0000000000014C000000000068C00000004D8
-:100EB00000404C1100000135810000000020441169
-:100EC00000000000000000010020481100000000A8
-:100ED000000021F800204411000000000000001C68
-:100EE0000020481100000000000421F900604411B6
-:100EF0000000068D000000110021023000000000FB
-:100F00000000000014E000000000013C00000000B0
-:100F100000800000000000000000000000600000F1
-:100F20000000000B00000000006004110000031529
-:100F3000000000000020041100000000000000007C
-:100F400000600811000001B2000000000060000015
-:100F5000000001600000FFFF40280E20000000009C
-:100F600000000010C0211220000000000000FFFF60
-:100F7000402806200000000000000010C0210A20C8
-:100F800000000000000000000034146100000000B8
-:100F90000000000000741882000002BB0001A1FDE7
-:100FA00000604411000002E000003FFF002F022F0C
-:100FB00000000000000000000CC00000000001471D
-:100FC00000000000C040040000000001000000001C
-:100FD000006000000000000B000000000060041131
-:100FE00000000315000000000020041100000000B4
-:100FF0000000000000600811000001B200003FFF87
-:10100000002F022F00000000000000000CE0000094
-:10101000000000000000000000600000000001600F
-:101020000000001040210E20000000000000FFFF23
-:10103000C0281220000000000000001040211620EF
-:10104000000000000000FFFFC0681A20000002BB83
-:101050000001A1FD00604411000002E000003FFF1C
-:10106000002F022F00000000000000000CC0000054
-:101070000000015800000000C04004000000000112
-:101080000000225C0020441100000000000000016C
-:1010900000300A2F000000000000000100210A2299
-:1010A000000000000000000300384A220000000099
-:1010B0000000225600204411000000000000001A29
-:1010C00000204811000000000000A1FC0020441195
-:1010D0000000000000000001008048110000000036
-:1010E00000000000006000000000000B0000000095
-:1010F000006000000000018F0000000000600000A0
-:10110000000001A000003FFF002F022F00000000A0
-:10111000000000000CE000000000000000000000E3
-:1011200000202C0800000000000000000020241116
-:101130000000000000000000002028110000000056
-:10114000000022560020441100000000000000169C
-:1011500000204811000000000000225C0020441123
-:101160000000000000000003002048110000000003
-:1011700093800000002044110000000000000002E5
-:1011800000221E290000000000000000007048EB53
-:101190000000019C0000000000600000000002BB95
-:1011A00000000001403306200000000000000000A5
-:1011B000C03024090000000000003FFF002F022F74
-:1011C00000000000000000000CE000000000000033
-:1011D0000000000000600000000002A3000000000A
-:1011E000002F022100000000000000000AE00000C3
-:1011F0000000018100000000006000000000013AD2
-:101200000000000000400000000001869500000082
-:10121000002044110000000000000000002F022107
-:1012200000000000000000000CE00000000001864B
-:1012300000000000C0204800000000000000000185
-:10124000005306210000018292000000002044119A
-:101250000000000000000000C0604800000001978E
-:101260000001A1FD00204411000000000000001159
-:101270000020062D00000000000000000078042A75
-:10128000000002FB00000000002028090000000010
-:1012900000003FFF002F022F0000000000000000B0
-:1012A0000CC000000000017400000000C0400400F9
-:1012B000000000010000021000600411000003158E
-:1012C00000003FFF002F022F000000000000000080
-:1012D0000CE000000000019400000015C020362042
-:1012E0000000000000000016C020362000000000B2
-:1012F0003F800000002004110000000046000000B4
-:1013000000600811000001B2000000000080000031
-:10131000000000000000A1FC0020441100000000BB
-:1013200000003FFF002F022F00000000000000001F
-:101330000CC000000000019B00000001008048116B
-:1013400000000000000000210080481100000000A3
-:101350000000FFFF40280E200000000000000010E9
-:10136000C0211220000000000000FFFF40281620CE
-:101370000000000000000010C0811A2000000000E2
-:101380008100000000204411000000000000000661
-:1013900000204811000000000000000800221E305C
-:1013A000000000000000002900201A2D00000000AD
-:1013B0000000E0000020441100000000FFFBFF09D6
-:1013C00000204811000000000000000F0020222D26
-:1013D0000000000000001FFF00294A280000000054
-:1013E000000000060020222D000000000000000088
-:1013F000002920E80000000000000000002048084C
-:101400000000000000000000002048110000000063
-:10141000060A020000294A26000000000000000021
-:1014200000204811000000000000000000204811CA
-:101430000000000000000100002018110000000062
-:101440000000000800621E280000012F00000008B4
-:1014500000822228000000000002C0000020441189
-:10146000000000000000001500600E2D000001BD0E
-:101470000000001600600E2D000001BD0000C00835
-:1014800000204411000000000000001700200E2D75
-:10149000000000000000000014C00000000001B9BE
-:1014A0000000000000200411000000000000000007
-:1014B0000020480100000000390000000020481111
-:1014C00000000000000000000020481100000000A3
-:1014D000000000000080480200000000000000182A
-:1014E00000202E2D0000000000000000003B0D63D6
-:1014F000000000000000000800224A230000000055
-:101500000000001000224A23000000000000001824
-:1015100000224A2300000000000000000080480371
-:101520000000000000000000006000000000000B50
-:10153000000010000060041100000315000000000E
-:1015400000200411000000000000000000600811ED
-:10155000000001B2000000070021062F000000007B
-:101560000000001300200A2D000000000000000110
-:1015700000202C11000000000000FFFF4028222066
-:10158000000000000000000F0026222800000000DC
-:101590000000001040212620000000000000000F85
-:1015A000002626290000000000000000002028027C
-:1015B000000000000000225600204411000000003E
-:1015C0000000001B00204811000000000000000087
-:1015D000002F022100000000000000000CE00000CD
-:1015E000000001E00000225C002044110000000027
-:1015F0000000008100204811000000000000A1FC54
-:1016000000204411000000000000000100204811EB
-:10161000000000000000008000201C1100000000FD
-:1016200000000000002F0227000000000000000062
-:101630000CE00000000001DC000000000060000081
-:10164000000001E90000000100531E27000001D83E
-:101650000000000100202C11000000000000001F0D
-:1016600000280A22000000000000001F00282A2A8B
-:10167000000000000000000100530621000001D11D
-:101680000000225C00204411000000000000000265
-:1016900000304A2F000000000000A1FC002044118F
-:1016A00000000000000000010020481100000000C0
-:1016B0000000000100301E2F0000000000000000AC
-:1016C000002F022700000000000000000CE00000D6
-:1016D000000000000000000000600000000001E9C0
-:1016E0000000000100531E27000001E50000FFFF7D
-:1016F00040280E20000000000000000F00260E23EE
-:101700000000000000000010C021122000000000B6
-:101710000000000F0026122400000000000000005E
-:1017200000201411000000000000000000601811EB
-:10173000000002BB0001A1FD0020441100000000D8
-:1017400000000000002F022B00000000000000003D
-:101750000CE00000000001F8000000100022162834
-:1017600000000000FFFF0000002816250000000018
-:101770000000FFFF00281A29000000000000000000
-:10178000002948C500000000000000000020480AB1
-:10179000000000000000000000202C1100000000EC
-:1017A000000000100022162300000000FFFF0000D0
-:1017B00000281625000000000000FFFF00281A2462
-:1017C0000000000000000000002948C500000000E3
-:1017D0000000000000731503000002050000000077
-:1017E0000020180500000000000000000073152410
-:1017F0000000020500000000002D14C500000000DC
-:1018000000000000003008A20000000000000000FE
-:101810000020480200000000000000000020280214
-:101820000000000000000000002020030000000075
-:101830000000000000802404000000000000000FF1
-:1018400000210225000000000000000014C000007C
-:101850000000068C00000000002B140500000000B2
-:1018600000000001009016250000000000000000AC
-:10187000006000000000000B000000000060041188
-:10188000000003150000000000200411000000000B
-:101890000000000000600811000001B200002256A4
-:1018A00000204411000000000000001A00294A2214
-:1018B0000000000000000000C02000000000000048
-:1018C00000003FFF002F022F00000000000000007A
-:1018D0000CE000000000000000000000C020040038
-:1018E000000000000000225C002044110000000005
-:1018F0000000000300384A21000000000000A1FCA5
-:1019000000204411000000000000000100204811E8
-:10191000000000000000FFFF40281220000000002F
-:1019200000000010C0211A20000000000000FFFF8E
-:1019300040280E200000000000000010C0211620EA
-:10194000000000000000000000741465000002BBED
-:101950000001A1FD00604411000002E00000000150
-:10196000003306210000000000000000002F0221CB
-:1019700000000000000000000CC000000000021980
-:1019800000003FFF002F022F0000000000000000B9
-:101990000CC000000000021200000000C040040063
-:1019A000000000010000000000600000000006458B
-:1019B000000000000040040F0000021300000000BF
-:1019C0000060000000000631000000000060000020
-:1019D000000006450000021000600411000003151D
-:1019E0000000000000600000000001A000000000F6
-:1019F000006000000000019C00000000006000008A
-:101A0000000002BB0000000000600000000002A314
-:101A1000938000000020441100000000000000003E
-:101A2000002048080000000000000000002F022FE6
-:101A300000000000000000000AE000000000023288
-:101A400000000000006000000000013A00000000FB
-:101A50000040000000000236950000000020441104
-:101A60000000000000000000002F022F0000000016
-:101A7000000000000CE00000000002360000000042
-:101A8000C0404800000002339200000000204411D2
-:101A90000000000000000000C0204800000000001E
-:101AA0000000225600204411000000000000001633
-:101AB00000204811000000000000225C00204411BA
-:101AC000000000000000000300204811000000009A
-:101AD0000000A1FC002044110000000000000001F3
-:101AE00000204811000000000001A1FD0020441169
-:101AF000000000000000000000600411000002FB74
-:101B000000000000C04004000000000100000000D0
-:101B100000600000000006310000A00C002044110D
-:101B20000000000000000000C0204800000000008D
-:101B300000000000C040480000000000000000005D
-:101B4000006000000000000B0000001840210A2087
-:101B50000000000000000003002F0222000000002F
-:101B6000000000000AE000000000024C0000001429
-:101B70000020222D00000000000801010029222879
-:101B800000000000000000140020362800000000C3
-:101B90000000A30C00204411000000000000000021
-:101BA000C02048000000000000000000C0204800E5
-:101BB0000000000000000000C0404800000002518A
-:101BC00000000000006000000000000B000000109A
-:101BD00000600411000003153F8000000020041184
-:101BE000000000000000000000600811000001B2C9
-:101BF0000000225C002044110000000000000003EF
-:101C000000204811000000000000000000600000FB
-:101C10000000027C0000001700201E2D00000000C4
-:101C20000000000100211E2700000000000000004D
-:101C300014E000000000026A0000001200201E2DC7
-:101C4000000000000000FFFF00281E270000000029
-:101C50000000000000341C2700000000000000000D
-:101C600012C000000000025F0000000000201C11F4
-:101C70000000000000000000002F00E50000000050
-:101C80000000000008C00000000002620000000028
-:101C900000201407000000000000001200201E2D8C
-:101CA000000000000000001000211E2700000000BE
-:101CB0000000000000341C4700000000000000008D
-:101CC00012C00000000002670000000000201C118C
-:101CD0000000000000000000002F00E600000000EF
-:101CE0000000000008C000000000026A00000000C0
-:101CF0000020180700000000000000000060000045
-:101D0000000002C100002256002044110000000023
-:101D1000000000000034202300000000000000004C
-:101D200012C00000000002720000000000342044D5
-:101D3000000000000000000012C00000000002715E
-:101D40000000001600404811000002760000001854
-:101D500000404811000002760000000000342044DA
-:101D6000000000000000000012C00000000002752A
-:101D70000000001700404811000002760000001922
-:101D800000204811000000000000A1FC00204411C8
-:101D900000000000000000010020481100000000C9
-:101DA0000001A1FD00604411000002E900003FFFB6
-:101DB000002F022F00000000000000000CC00000F7
-:101DC0000000025600000000C040040000000001B6
-:101DD0000000001040210620000000000000FFFF6E
-:101DE000C0280A20000000000000001040210E2042
-:101DF000000000000000FFFFC028122000000000CB
-:101E00000000001040211620000000000000FFFF2D
-:101E1000C0881A200000000081000000002044114A
-:101E20000000000000000001002048110000000038
-:101E300000042004006044110000068D0000000032
-:101E4000006000000000063100000000C0600000DB
-:101E5000000002A30000000500200A2D0000000081
-:101E60000000000800220A22000000000000002BF1
-:101E700000201A2D000000000000001C00201E2D74
-:101E8000000000000000700000281E270000000075
-:101E90000000000000311CE6000000000000002AE5
-:101EA00000201A2D000000000000000C00221A265D
-:101EB0000000000000000000002F00E6000000000D
-:101EC0000000000006E00000000002920000000098
-:101ED00000201C11000000000000000000200C1178
-:101EE000000000000000002B00203623000000004E
-:101EF0000000001000201811000000000000000089
-:101F000000691CE20000012F9380000000204411B2
-:101F10000000000000000000002048070000000052
-:101F200095000000002044110000000000000000A7
-:101F3000002F022F00000000000000000CE0000055
-:101F40000000029D0000000100333E2F0000000051
-:101F500000000000D90048000000000092000000CE
-:101F6000002044110000000000000000C0204800D4
-:101F7000000000000000001C0040362700000000A8
-:101F80000000000CC0220A20000000000000002910
-:101F9000002036220000000000000028C04036204B
-:101FA000000000000000A2A4002044110000000076
-:101FB000000000090020481100000000A1000000FE
-:101FC00000204411000000000000000100804811C2
-:101FD000000000000000002100201E2D0000000075
-:101FE00000000000002C1CE30000000000000021A5
-:101FF00000203627000000000000002200201E2DD7
-:102000000000000000000000002C1CE400000000A4
-:1020100000000022002036270000000000000023FE
-:1020200000201E2D0000000000000000003120A351
-:102030000000000000000000002D1D07000000004F
-:1020400000000023002036270000000000000024CC
-:1020500000201E2D0000000000000000003120C400
-:102060000000000000000000002D1D07000000001F
-:10207000000000240080362700000000000000213E
-:10208000002036230000000000000022002036243B
-:10209000000000000000000000311CA30000000050
-:1020A0000000002300203627000000000000000090
-:1020B00000311CC40000000000000024008036270E
-:1020C000000000000000001A002036270000000079
-:1020D0000000001B00203628000000000000001750
-:1020E00000201E2D00000000000000020021022739
-:1020F000000000000000000014C00000000002DC2E
-:102100000000000000400000000002D90000001A9A
-:1021100000203627000000000000001B00203628A9
-:10212000000000000000001700201E2D000000002D
-:102130000000000200210227000000000000000053
-:1021400014E00000000002D9000000030021022773
-:10215000000000000000000014E00000000002DCAD
-:102160000000002300201E2D0000000000000000E1
-:10217000002E00E1000000000000000002C000008E
-:10218000000002DC0000002100201E2D00000000E5
-:1021900000000000003120A100000000000000004D
-:1021A000002E00E8000000000000000006C0000053
-:1021B000000002DC0000002400201E2D00000000B2
-:1021C00000000000002E00E20000000000000000FF
-:1021D00002C00000000002DC0000002200201E2DD2
-:1021E0000000000000000000003120C200000000DC
-:1021F00000000000002E00E80000000000000000C9
-:1022000006C00000000002DC0000000000600000CA
-:10221000000006680000000000600000000002B539
-:102220000000000000400000000002DE000000008E
-:1022300000600000000002B5000000000060000027
-:102240000000065F0000000000400000000002DE09
-:102250000000000000600000000002A70000000075
-:1022600000400000000002DE0000001A00201E2DC9
-:10227000000000000000001B0080222D0000000074
-:102280000000001000221E230000000000000000DB
-:1022900000294887000000000000000000311CA356
-:1022A000000000000000001000221E2700000000B7
-:1022B0000000000000294887000000000000001016
-:1022C00000221E230000000000000000003120C496
-:1022D000000000000000FFFF00282228000000008E
-:1022E0000000000000894907000000000000001005
-:1022F00000221E2300000000000000000029488783
-:10230000000000000000001000221E21000000005C
-:102310000000000000294847000000000000000005
-:1023200000311CA3000000000000001000221E2746
-:1023300000000000000000000029488700000000A5
-:102340000000000000311CA100000000000000108F
-:1023500000221E270000000000000000002948475E
-:10236000000000000000001000221E2300000000FA
-:1023700000000000003120C4000000000000FFFF4A
-:102380000028222800000000000000000029490762
-:10239000000000000000001000221E2100000000CC
-:1023A00000000000003120C2000000000000FFFF1C
-:1023B00000282228000000000000000000894907D2
-:1023C000000000000000001000221E23000000009A
-:1023D0000000000000294887000000000000000104
-:1023E00000220A210000000000000000003308A2C3
-:1023F000000000000000001000221E22000000006B
-:102400000000001000212222000000000000000057
-:1024100000294907000000000000000000311CA353
-:10242000000000000000001000221E270000000035
-:1024300000000000002948870000000000000001A3
-:1024400000220A210000000000000000003008A265
-:10245000000000000000001000221E22000000000A
-:1024600000000010002122220000000000000000F7
-:1024700000294907000000000000001000221E2370
-:102480000000000000000000003120C40000000037
-:102490000000FFFF002822280000000000000000CC
-:1024A000002949070000000000000000003808C5AE
-:1024B00000000000000000000030084100000000A3
-:1024C0000000000100220A220000000000000000BD
-:1024D000003308A2000000000000001000221E22AD
-:1024E0000000000000000010002122220000000077
-:1024F00000000000008949070000000000000017EC
-:102500000020222D000000000000000014C0000088
-:1025100000000318FFFFFFEF002806210000000065
-:10252000000000140020222D000000000000F8E050
-:1025300000204411000000000000000000294901B3
-:1025400000000000000000000089490100000000B8
-:102550000000000000204811000000000000000002
-:102560000020481100000000060A02000080481107
-:102570000000000000000000C0200000000000007B
-:1025800097000000C020441100000000000000007F
-:10259000C0204811000000008A0000000020441103
-:1025A00000000000000000000020481100000000B2
-:1025B0000000225C00204411000000000000000028
-:1025C000C0204800000000000000A1FC00204411D1
-:1025D0000000000000000000C020480000000000D3
-:1025E00000000000C0200400000000000000000007
-:1025F00000A0000A00000000970000000020441125
-:102600000000000000000000002048110000000051
-:102610008A000000002044110000000000000000BB
-:1026200000204811000000000000225C002044113E
-:102630000000000000000000C02048000000000072
-:102640000000A1FC00204411000000000000000078
-:10265000C02048000000000000000000C02004006E
-:10266000000000000000000000A0000A00000000C0
-:10267000970000000020441100000000000000004E
-:1026800000204811000000008A00000000204411D2
-:1026900000000000000000000020481100000000C1
-:1026A0000000225C00204411000000000000000037
-:1026B000C0204800000000000000A1FC00204411E0
-:1026C0000000000000000000C020480000000000E2
-:1026D0000001A1FD002044110000000000000000E6
-:1026E000D90048000000000000000000C0200400E5
-:1026F000000000000000000000A0000A0000000030
-:1027000000002257002044110000000000000003D8
-:10271000C0484A20000000000000225D0020441153
-:102720000000000000000000C04048000000000061
-:1027300000000000006000000000064500000000EE
-:10274000C0200800000000000000225C00204411AE
-:10275000000000000000000300384A2200000000D2
-:102760000000A1FC00204411000000000000000057
-:10277000C0204800000000000001A1FD002044111D
-:102780000000000000000000002F022200000000F6
-:10279000000000000CE0000000000000000000004D
-:1027A00040204800000000000000000140304A20A6
-:1027B0000000000000000002C0304A2000000000BD
-:1027C0000000000100530A220000034B0000003FFC
-:1027D000C0280A20000000008100000000204411F1
-:1027E000000000000000000100204811000000006F
-:1027F000000021F800204411000000000000001833
-:102800000020481100000000000421F9006044117C
-:102810000000068D000000110021023000000000C1
-:102820000000000014E00000000003540000001449
-:10283000002F022200000000000000000CC0000079
-:10284000000003640000201000204411000000007C
-:102850000000800000204811000000000001A2A438
-:102860000020441100000000000000000060480249
-:102870000000036E00002100002044110000000051
-:1028800000000000C0204800000000000000000020
-:10289000C02048000000000000000000C0204800E8
-:1028A0000000000000000000C040480000000000E0
-:1028B00000000004002F02220000000000000000C1
-:1028C0000CC000000000036A00002010002044112A
-:1028D00000000000000080000020481100000000FF
-:1028E0000001A2A40020441100000000000000002C
-:1028F000004048020000035F00000028002F022271
-:1029000000000000000000000CC00000000005C036
-:102910000001A2A4002044110000000000000000FB
-:10292000004048020000035F0000002C0020362613
-:102930000000000000000049002018110000000005
-:102940000000003F002048110000000000000001CE
-:1029500000331A260000000000000000002F0226AD
-:1029600000000000000000000CC000000000037028
-:102970000000002C00801A2D000000000000003F25
-:10298000C0280A200000000000000015002F0222CD
-:1029900000000000000000000CE0000000000386C2
-:1029A00000000006002F02220000000000000000CE
-:1029B0000CE00000000003B100000016002F02220E
-:1029C00000000000000000000CE00000000003B563
-:1029D00000000020002F0222000000000000000084
-:1029E0000CE000000000039C0000000F002F0222FA
-:1029F00000000000000000000CE00000000003A840
-:102A000000000010002F0222000000000000000063
-:102A10000CE00000000003A80000001E002F0222AE
-:102A200000000000000000000CE000000000039027
-:102A30000000A2A4002044110000000000000000DB
-:102A400000404802000000000800000000290A229F
-:102A5000000000000000000340210E2000000000E4
-:102A60000000000CC021122000000000000800003F
-:102A7000002812240000000000000014C0221620CC
-:102A80000000000000000000002914A40000000065
-:102A90000000A2A40020441100000000000000007B
-:102AA000002948A2000000000000A1FE00204411FF
-:102AB000000000000000000000404803000000008B
-:102AC000810000000020441100000000000000010F
-:102AD0000020481100000000000021F800204411EF
-:102AE0000000000000000016002048110000000057
-:102AF000000421F9006044110000068D000000155B
-:102B000000210230000000000000000014E000007E
-:102B1000000003920000210E00204411000000007C
-:102B200000000000C020480000000000000000007D
-:102B3000C0204800000000000000A2A400204411B2
-:102B400000000000000000000040480200000000FB
-:102B5000810000000020441100000000000000017E
-:102B60000020481100000000000021F8002044115E
-:102B700000000000000000170020481100000000C5
-:102B8000000421F9006044110000068D00000003DC
-:102B900000210230000000000000000014E00000EE
-:102BA0000000039E000021080020441100000000E6
-:102BB00000000000C02048000000000000000000ED
-:102BC000C0204800000000000000A2A40020441122
-:102BD000000000000000000000404802000000006B
-:102BE0000000A2A40020441100000000000000002A
-:102BF0000020480200000000800000000020441176
-:102C0000000000000000000000204811000000004B
-:102C100081000000002044110000000000000010AE
-:102C200000204811000000000000000000200010FB
-:102C3000000000000000000014C00000000003AE0F
-:102C40000000000000400000000000000000201014
-:102C50000020441100000000000080000020481106
-:102C6000000000000001A2A40020441100000000A8
-:102C70000000000600404811000000000000201085
-:102C800000204411000000000000800000204811D6
-:102C9000000000000001A2A4002044110000000078
-:102CA00000000016006048110000036E00000000E4
-:102CB000004000000000000000000000C0200800EC
-:102CC0000000000000000000C0200C000000000018
-:102CD0000000001D00210223000000000000000091
-:102CE00014E00000000003CE810000000020441129
-:102CF000000000000000000100204811000000005A
-:102D0000000021F80020441100000000000000181D
-:102D10000020481100000000000421F90060441167
-:102D20000000068D000000110021023000000000AC
-:102D30000000000014E00000000003C000002100BB
-:102D400000204411000000000000000000204802A4
-:102D50000000000000000000002048030000000008
-:102D6000BABECAFE0020481100000000CAFEBABE6A
-:102D70000020481100000000000020100020441135
-:102D8000000000000000800000204811000000004A
-:102D90000000A2A400204411000000000000000474
-:102DA0000040481100000000000021700020441184
-:102DB00000000000000000000020480200000000A9
-:102DC0000000000000204803000000008100000017
-:102DD00000204411000000000000000A00204811FB
-:102DE00000000000000000000020001000000000B3
-:102DF0000000000014C00000000003D38C0000009D
-:102E00000020441100000000CAFEBABE0040481174
-:102E100000000000810000000020441100000000BC
-:102E200000000001002048110000000000003FFFEA
-:102E300040280A20000000008000000040280E20EA
-:102E40000000000040000000C02812200000000028
-:102E500000040000006946220000068D000000000A
-:102E6000002014100000000000000000002F0223CA
-:102E700000000000000000000CC00000000003E1A2
-:102E800000000000C0401800000003E400003FFF05
-:102E9000C0281A2000000000000400000069462637
-:102EA0000000068D00000000002018100000000047
-:102EB00000000000002F02240000000000000000BD
-:102EC0000CC00000000003E700000000C0401C0030
-:102ED000000003EA00003FFFC0281E2000000000A1
-:102EE00000040000006946270000068D0000000075
-:102EF00000201C1000000000000000000020440220
-:102F00000000000000000000002820C500000000B4
-:102F100000000000004948E800000000A580000013
-:102F200000200811000000000000200000200C110B
-:102F30000000000083000000006044110000041243
-:102F4000000000000020440200000000000000001B
-:102F5000C0204800000000000000000040204800A1
-:102F6000000000000000001FC0210220000000003F
-:102F70000000000014C00000000003F70000201053
-:102F800000204411000000000000800000204811D3
-:102F9000000000000000FFFFC0481220000003FFF7
-:102FA000A780000000200811000000000000A00021
-:102FB00000200C110000000083000000006044119C
-:102FC0000000041200000000002044020000000085
-:102FD00000000000C02048000000000000000000C9
-:102FE000C0204800000000000000FFFFC0281220A1
-:102FF00000000000830000000020441100000000D9
-:103000000000000000304883000000008400000041
-:10301000002044110000000000000000C020480013
-:1030200000000000000000001D0000000000000083
-:103030008300000000604411000004120000000042
-:10304000C040040000000001A98000000020081119
-:10305000000000000000C00000400C11000003FA56
-:10306000AB80000000200811000000000000F8E024
-:1030700000400C11000003FAAD8000000020081190
-:10308000000000000000F88000400C11000003FA6E
-:10309000B380000000200811000000000000F3FCD5
-:1030A00000400C11000003FAAF800000002008115E
-:1030B000000000000000E00000400C11000003FAD6
-:1030C000B180000000200811000000000000F000A6
-:1030D00000400C11000003FA83000000002044119E
-:1030E00000000000000021480020481100000000FE
-:1030F00084000000002044110000000000000000D7
-:10310000C020480000000000000000001D0000007A
-:10311000000000000000000000800000000000002F
-:1031200001182000C0304620000000000000000010
-:10313000D90048000000000000000000C02004008A
-:10314000000000000000000000A0000A00000000D5
-:103150000218A000C030462000000000000000005F
-:10316000D90048000000000000000000C02004005A
-:10317000000000000000000000A0000A00000000A5
-:103180000318C000C030462000000000000000000E
-:10319000D90048000000000000000000C02004002A
-:1031A000000000000000000000A0000A0000000075
-:1031B0000418F8E0C03046200000000000000000C5
-:1031C000D90048000000000000000000C0200400FA
-:1031D000000000000000000000A0000A0000000045
-:1031E0000518F880C03046200000000000000000F4
-:1031F000D90048000000000000000000C0200400CA
-:10320000000000000000000000A0000A0000000014
-:103210000618E000C030462000000000000000005A
-:10322000D90048000000000000000000C020040099
-:10323000000000000000000000A0000A00000000E4
-:103240000718F000C0304620000000000000000019
-:10325000D90048000000000000000000C020040069
-:10326000000000000000000000A0000A00000000B4
-:103270000818F3FCC03046200000000000000000E9
-:10328000D90048000000000000000000C020040039
-:10329000000000000000000000A0000A0000000084
-:1032A0000000003000200A2D000000000000000097
-:1032B000C0290C4000000000000000300020362330
-:1032C0000000000000000000C0200400000000001A
-:1032D0000000000000A0000A0000000086000000BE
-:1032E00000204411000000000000000000404801E0
-:1032F0000000000085000000C02044110000000014
-:103300000000000000404801000000000000217C97
-:10331000002044110000000000000018402102209D
-:10332000000000000000000014C000000000044580
-:1033300000800000C0494A20000004460000000050
-:10334000C02048000000000000000000C02048002D
-:103350000000000000000000C02048000000000045
-:103360008100000000204411000000000000000166
-:10337000002048110000000000000000C0200800EC
-:103380000000000000000000170000000000000026
-:103390000004217F006044110000068D0000001F22
-:1033A00000210230000000000000000014C00000F6
-:1033B000000000000000000000404C020000044B30
-:1033C00000000000C0200C00000000000000000011
-:1033D000C02010000000000000000000C020140009
-:1033E0000000000000000000C020180000000000E5
-:1033F00000000000C0201C000000000000007F0052
-:1034000000280A210000000000004500002F0222D1
-:1034100000000000000000000CE000000000045963
-:1034200000000000C020200000000000000000009C
-:1034300017000000000000000000001000280A2310
-:103440000000000000000010002F02220000000019
-:10345000000000000CE0000000000461810000009A
-:10346000002044110000000000000001002048116D
-:103470000000000000040000006946240000068DE2
-:103480000000000000400000000004668100000011
-:10349000002044110000000000000000002048113E
-:1034A000000000000000216D002044110000000019
-:1034B00000000000002048040000000000000000A0
-:1034C000006048050000069200000000002824F07B
-:1034D000000000000000000700280A230000000090
-:1034E00000000001002F0222000000000000000088
-:1034F0000AE000000000046D00000000002F00C979
-:10350000000000000000000004E00000000004864D
-:1035100000000000004000000000049300000002D2
-:10352000002F022200000000000000000AE000005E
-:103530000000047200000000002F00C9000000001D
-:103540000000000002E0000000000486000000000F
-:10355000004000000000049300000003002F02223E
-:1035600000000000000000000AE0000000000477F6
-:1035700000000000002F00C9000000000000000053
-:103580000CE0000000000486000000000040000085
-:103590000000049300000004002F0222000000003D
-:1035A000000000000AE000000000047C00000000B1
-:1035B000002F00C900000000000000000AE0000029
-:1035C000000004860000000000400000000004939A
-:1035D00000000005002F0222000000000000000093
-:1035E0000AE000000000048100000000002F00C974
-:1035F000000000000000000006E00000000004865B
-:1036000000000000004000000000049300000006DD
-:10361000002F022200000000000000000AE000006D
-:103620000000048600000000002F00C90000000018
-:103630000000000008E00000000004860000000018
-:10364000004000000000049300007F0000280A21D1
-:103650000000000000004500002F022200000000D2
-:10366000000000000AE00000000000000000000868
-:1036700000210A23000000000000000014C0000028
-:1036800000000490000021690020441100000000A7
-:1036900000000000C0204800000000000000000002
-:1036A000C02048000000000000000000C0204800CA
-:1036B00000000000CAFEBABE004048110000000031
-:1036C00000000000C02044000000000000000000D6
-:1036D000C02000000000000000000000C0404800C2
-:1036E0000000000000007F0000280A210000000008
-:1036F00000004500002F0222000000000000000032
-:103700000AE000000000049900000000C020000052
-:103710000000000000000000C020000000000000C9
-:1037200000000000C0400000000000000000000099
-:1037300000404C080000045900000000C0200800B0
-:10374000000000000000001040210E2000000000DA
-:1037500000000011402112200000000000000012B3
-:1037600040211620000000000000216900204411C3
-:1037700000000000000000000020480200000000DF
-:1037800000000000002102250000000000000000F1
-:1037900014E00000000004A300040000C0494A2017
-:1037A000000004A4FFFBFFFFC0284A200000000027
-:1037B00000000000002102230000000000000000C3
-:1037C00014E00000000004B000000000C020480029
-:1037D0000000000000000000C020480000000000C1
-:1037E0000000000000210224000000000000000092
-:1037F00014C00000000000008100000000204411FF
-:10380000000000000000000C002048110000000033
-:103810000000000000200010000000000000000078
-:1038200014C00000000004ACA000000000204411FF
-:1038300000000000CAFEBABE0040481100000000AF
-:10384000810000000020441100000000000000047E
-:1038500000204811000000000000216B00204411EE
-:103860000000000000000000C02048100000000020
-:10387000810000000020441100000000000000054D
-:1038800000204811000000000000216C00204411BD
-:103890000000000000000000C020481000000000F0
-:1038A00000000000002F02240000000000000000C3
-:1038B0000CE00000000000000000000000400000DC
-:1038C000000004AA00000000C0210A20000000003F
-:1038D0000000000014C00000000004C381000000CC
-:1038E00000204411000000000000000000204811EA
-:1038F000000000000000216D0020441100000000C5
-:1039000000000000C020480000000000000000008F
-:10391000C060480000000692000000000040000067
-:10392000000004C7810000000020441100000000D6
-:103930000000000100204811000000000004000009
-:10394000C02946200000000000000000C060000008
-:103950000000068D0000000100210222000000008E
-:103960000000000014C00000000004CE0000216927
-:10397000002044110000000000000000C0204800AA
-:103980000000000000000000C0204800000000000F
-:10399000000000000020481000000000CAFEBABE6F
-:1039A000004048110000000000000000C02044005A
-:1039B0000000000000000000C040481000000000AF
-:1039C0008100000000204411000000000000000100
-:1039D0000020481100000000000021F800204411E0
-:1039E000000000000000000E002048110000000050
-:1039F000000421F9006044110000068D0000000061
-:103A000000210230000000000000000014C000008F
-:103A1000000004D0000021800020441100000000BC
-:103A200000000000C020480000000000000000006E
-:103A3000C02000000000000000000000C02048007E
-:103A40000000000000000000C02000000000000096
-:103A500000000000C040480000000000000000031B
-:103A600000333E2F00000000000000010021022171
-:103A7000000000000000000014E00000000005004D
-:103A80000000002C00200A2D0000000000040000AF
-:103A900018E00C11000004EF0000000100333E2F7D
-:103AA0000000000000002169002044110000000017
-:103AB000000000000020480200000000000000009C
-:103AC00000204803000000000000000800300A2227
-:103AD0000000000000000000C020480000000000BE
-:103AE00000000000C0204800000000000000216924
-:103AF00000204411000000000000000000204802E7
-:103B0000000000000000000000204803000000004A
-:103B10000000000800300A22000000000000000041
-:103B2000C02048000000000000000000D8C048008D
-:103B3000000004E30000216900204411000000009F
-:103B4000000000000020480200000000000000000B
-:103B500000204803000000000000000800300A2296
-:103B60000000000000000000C0204800000000002D
-:103B700000000000C0204800000000000000002DF0
-:103B80000020122D000000000000000000290C831E
-:103B90000000000000002169002044110000000026
-:103BA00000000000002048020000000000000000AB
-:103BB00000204803000000000000000800300A2236
-:103BC0000000000000000000C020480000000000CD
-:103BD00000000000C02048000000000000000011AC
-:103BE00000210224000000000000000014C00000BA
-:103BF000000000000000000000400000000004AAD7
-:103C00000000002CC0203620000000000000002D25
-:103C1000C0403620000000000000000F00210221FB
-:103C2000000000000000000014C0000000000505B6
-:103C300000000000006000000000000B0000000019
-:103C4000D90000000000000000000000C040040097
-:103C500000000001B5000000002044110000000039
-:103C6000000020000020481100000000B600000005
-:103C700000204411000000000000A00000204811B6
-:103C800000000000B7000000002044110000000008
-:103C90000000C0000020481100000000B800000033
-:103CA00000204411000000000000F8E0002048114E
-:103CB00000000000B90000000020441100000000D6
-:103CC0000000F8800020481100000000BA00000049
-:103CD00000204411000000000000E0000020481116
-:103CE00000000000BB0000000020441100000000A4
-:103CF0000000F0000020481100000000BC0000009F
-:103D000000204411000000000000F3FC00204811D6
-:103D100000000000810000000020441100000000AD
-:103D2000000000020020481100000000000000FF19
-:103D300000280E300000000000000000002F0223C9
-:103D400000000000000000000CC000000000051989
-:103D500000000000C020080000000000000000007B
-:103D600014C000000000052E0000000000200C110F
-:103D7000000000000000001C0020362300000000AE
-:103D80000000002B00203623000000000000002966
-:103D90000020362300000000000000280020362309
-:103DA0000000000000000017002036230000000083
-:103DB000000000250020362300000000000000263F
-:103DC00000203623000000000000001500203623EC
-:103DD0000000000000000016002036230000000054
-:103DE000FFFFE00000200C11000000000000002197
-:103DF00000203623000000000000002200203623AF
-:103E00000000000000001FFF00200C110000000057
-:103E100000000023002036230000000000000024E2
-:103E20000020362300000000F1FFFFFF00283A2E9B
-:103E3000000000000000001AC0220E200000000058
-:103E4000000000000029386E000000008100000022
-:103E5000002044110000000000000006002048116E
-:103E6000000000000000002A402036200000000072
-:103E70008700000000204411000000000000000046
-:103E8000C0204800000000000000A1F40020441100
-:103E900000000000000000000020481000000000AA
-:103EA0000000000000200C110000000000000030A5
-:103EB00000203623000000009D0000000020441177
-:103EC000000000000000001F40214A200000000008
-:103ED00096000000002044110000000000000000D7
-:103EE000C02048000000000000000000C0200C00BE
-:103EF0000000000000000000C020100000000000D2
-:103F00000000001F00211624000000000000000037
-:103F100014C00000000000000000001D0020362337
-:103F2000000000000000000300281E230000000025
-:103F3000000000080022222300000000FFFFF00024
-:103F4000002822280000000000000000002920E8CE
-:103F5000000000000000001F0020362800000000C4
-:103F60000000001800211E230000000000000020B7
-:103F70000020362700000000000000020022162466
-:103F80000000000000000000003014A80000000045
-:103F90000000001E00203625000000000000000385
-:103FA00000211A24000000001000000000281A263A
-:103FB00000000000EFFFFFFF00283A2E0000000085
-:103FC00000000000004938CE0000067B0000000120
-:103FD00040280A20000000000000000640280E20B3
-:103FE0000000000000000300C028122000000000B4
-:103FF0000000000800211224000000000000000062
-:10400000C02016200000000000000000C0201A2080
-:10401000000000000000000000210222000000005B
-:104020000000000014C000000000056681000000D0
-:104030000020441100000000000000010020481191
-:10404000000000000000225800300A240000000098
-:1040500000040000006946220000068D000021696E
-:10406000002044110000000000000000002048056E
-:10407000000000000002000000294A2600000000A5
-:10408000000000000020481000000000CAFEBABE78
-:10409000002048110000000000000002002F022351
-:1040A00000000000000000000CC000000000056ED1
-:1040B00000000000C0201C100000000000000000F4
-:1040C000C04000000000057C00000002002F022319
-:1040D00000000000000000000CC000000000056EA1
-:1040E00081000000002044110000000000000001D9
-:1040F00000204811000000000000225800300A246F
-:104100000000000000040000006946220000068D47
-:1041100000000000C0201C10000000000000000093
-:10412000C04000000000057C00000000002F0223BA
-:1041300000000000000000000CC00000000005723C
-:1041400000000000C0201C00000000000000000073
-:10415000C04000000000057C00000004002F022386
-:1041600000000000000000000CC000000000057A04
-:104170008100000000204411000000000000000049
-:1041800000204811000000000000216D00204411B3
-:104190000000000000000000C020480000000000F7
-:1041A00000000000C060480000000692000000000F
-:1041B00000401C100000057C00000000C020000032
-:1041C0000000000000000000C040000000000000EF
-:1041D000000000000EE000000000057E000000006E
-:1041E00000600000000005C900000000002F02244C
-:1041F00000000000000000000CC000000000058F5F
-:104200000000A2B7002044110000000000000000E0
-:104210000020480700000000810000000020441139
-:104220000000000000000001002048110000000014
-:104230000004A2B6006044110000068D0000001AC0
-:10424000002122300000000000000006002226307D
-:104250000000000000042004006044110000068DEE
-:104260000000A2C400204411000000000000000073
-:10427000003048E9000000000000000000E00000FD
-:104280000000058D0000A2D10020441100000000B4
-:104290000000000000404808000000000000A2D11B
-:1042A00000204411000000000000000100504A28D6
-:1042B0000000000000000001002F022400000000A8
-:1042C000000000000CC00000000005A00000A2BB20
-:1042D00000204411000000000000000000204807FA
-:1042E00000000000810000000020441100000000D8
-:1042F0000000000100204811000000000004A2BAE4
-:10430000006044110000068D0000001A00212230D8
-:10431000000000000000000600222630000000001F
-:1043200000042004006044110000068D0000A2C5B6
-:10433000002044110000000000000000003048E9A7
-:10434000000000000000000000E000000000059EEA
-:104350000000A2D200204411000000000000000074
-:1043600000404808000000000000A2D200204411D4
-:10437000000000000000000100504A28000000007A
-:1043800000000002002F02240000000000000000D6
-:104390000CC00000000005B10000A2BF00204411C5
-:1043A000000000000000000000204807000000009E
-:1043B0008100000000204411000000000000000106
-:1043C00000204811000000000004A2BE006044115B
-:1043D0000000068D0000001A0021223000000000BD
-:1043E0000000000600222630000000000004200427
-:1043F000006044110000068D0000A2C60020441198
-:104400000000000000000000003048E9000000004B
-:104410000000000000E00000000005AF0000A2D393
-:104420000020441100000000000000000040480887
-:10443000000000000000A2D3002044110000000092
-:104440000000000100504A28000000000000A2C344
-:104450000020441100000000000000000020480778
-:104460000000000081000000002044110000000056
-:104470000000000100204811000000000004A2C25A
-:10448000006044110000068D0000001A0021223057
-:10449000000000000000000600222630000000009E
-:1044A00000042004006044110000068D0000A2C733
-:1044B000002044110000000000000000003048E926
-:1044C000000000000000000000E00000000005BE49
-:1044D0000000A2D4002044110000000000000000F1
-:1044E00000404808000000000000A2D40020441151
-:1044F000000000000000000100504A2800000000F9
-:1045000085000000002044110000000000000000B1
-:1045100000204801000000000000304A0020441143
-:104520000000000001000000002048110000000011
-:104530000000000000400000000005C4A4000000CE
-:10454000C02044110000000000000000C0404800EE
-:104550000000000000000000C0600000000005C96D
-:1045600000000000C0400400000000010000002C1A
-:1045700000203621000000008100000000204411CE
-:1045800000000000000000060020481100000000AC
-:1045900000000000002F02300000000000000000BA
-:1045A0000CC00000000005D0000000000020041135
-:1045B000000000000000003000403621000005E34C
-:1045C000000000300020062D0000000000007E00EA
-:1045D000002806210000000000000000002F02213A
-:1045E00000000000000000000CE00000000005E3F7
-:1045F00081000000002044110000000000000001C4
-:1046000000204811000000000004A0920060441146
-:104610000000068D00000031002036300000000050
-:104620000004A093006044110000068D00000032D9
-:1046300000203630000000000004A2B600604411E3
-:104640000000068D0000003300203630000000001E
-:104650000004A2BA006044110000068D000000347E
-:1046600000203630000000000004A2BE00604411AB
-:104670000000068D000000350020363000000000EC
-:104680000004A2C2006044110000068D0000003644
-:1046900000203630000000000004200400604411B7
-:1046A0000000068D0001A2A40020441100000000BB
-:1046B0000000003F00204811000000000000003F03
-:1046C00000204811000000000000003F00204811B9
-:1046D000000000000000003F002048110000000022
-:1046E0000000000500204811000000000000A1F4B7
-:1046F00000204411000000000000000000204811CC
-:1047000000000000880000000020441100000000AC
-:10471000000000010020481100000000810000009E
-:104720000020441100000000000000060020481195
-:104730000000000000000001002F02300000000017
-:10474000000000000CE000000000062C000000301B
-:104750000020062D0000000000000000002F0221B4
-:1047600000000000000000000CE000000000062C2B
-:104770008100000000204411000000000000000142
-:10478000002048110000000000007E0000280621E3
-:104790000000000000000000002F022100000000C7
-:1047A000000000000CE00000000006050000A092E0
-:1047B00000204411000000000000003100204A2DBC
-:1047C000000000000000A093002044110000000041
-:1047D0000000003200204A2D000000000000A2B6B8
-:1047E00000204411000000000000003300204A2D8A
-:1047F000000000000000A2BA0020441100000000E8
-:104800000000003400204A2D000000000000A2BE7D
-:1048100000204411000000000000003500204A2D57
-:10482000000000000000A2C20020441100000000AF
-:104830000000003600204A2D00000000000000307B
-:104840000020062D00000000000001FF00280621C6
-:104850000000000000000000002F02210000000006
-:10486000000000000CE000000000062B000000002B
-:1048700000210221000000000000000014C0000020
-:104880000000060E0004A003006044110000068D25
-:104890000000A00300204411000000000000000000
-:1048A0000020481000000000000000010021062147
-:1048B000000000000000000014C00000000006130B
-:1048C0000004A010006044110000068D0000A0103C
-:1048D00000204411000000000000000000204810EB
-:1048E000000000000000000100210621000000007F
-:1048F00000000000002F0221000000000000000066
-:104900000CE000000000062B0004A0110060441120
-:104910000000068D0000A0110020441100000000DE
-:104920000000000000204810000000000004A01259
-:10493000006044110000068D0000A0120020441108
-:1049400000000000000000000020481000000000EF
-:104950000004A013006044110000068D0000A013A5
-:10496000002044110000000000000000002048105A
-:10497000000000000004A014006044110000068D37
-:104980000000A014002044110000000000000000FE
-:1049900000204810000000000004A0150060441131
-:1049A0000000068D0000A01500204411000000004A
-:1049B0000000000000204810000000000004A016C5
-:1049C000006044110000068D0000A0160020441174
-:1049D000000000000000000000204810000000005F
-:1049E0000004A017006044110000068D0000A0170D
-:1049F00000204411000000000000000000204810CA
-:104A00000000000000042004006044110000068D36
-:104A10000000002C0080062D00000000FF000000B8
-:104A20000020441100000000000000000020481198
-:104A300000000000000000010020481100000000FC
-:104A4000000000020080481100000000000000008B
-:104A50000EE000000000063D000000300020062DA2
-:104A600000000000000000020028062100000000F5
-:104A700000000000002F02210000000000000000E4
-:104A80000CE000000000063B810000000020441103
-:104A9000000000000000000100204811000000009C
-:104AA00000042004006044110000068D0000100086
-:104AB00000200811000000000000002B002036221A
-:104AC000000000000000000000600000000006413F
-:104AD0000000000000600000000005C99800000010
-:104AE0000020441100000000000000000080481178
-:104AF0000000000000000000C0600000000006414F
-:104B000000000000C0400400000000010000A2A45A
-:104B10000020441100000000000000220020481185
-:104B20000000000089000000002044110000000087
-:104B300000000001004048110000062D9700000011
-:104B40000020441100000000000000000020481177
-:104B5000000000008A000000002044110000000056
-:104B600000000000004048110000062D0000000079
-:104B7000006000000000065C0000201000204411CE
-:104B8000000000000000800000204811000000002C
-:104B90000001A2A4C0204411000000000000001683
-:104BA000006048110000036E000020100020441136
-:104BB000000000000001000000204811000000007B
-:104BC00081000000002044110000000000000001EE
-:104BD00000204811000000000000217C002044114A
-:104BE00000000000098000000020481100000000C3
-:104BF000FFFFFFFF00204811000000000000000040
-:104C00000020481100000000000000001700000014
-:104C1000000000000004217F006044110000068DA8
-:104C20000000001F00210230000000000000000012
-:104C300014C00000000000000000000400404C11FF
-:104C400000000656000000000040000000000000C8
-:104C50000000001700201E2D0000000000000004CE
-:104C600000291E27000000000000001700803627E2
-:104C7000000000000000001700201E2D00000000B2
-:104C8000FFFFFFFB00281E270000000000000017A8
-:104C900000803627000000000000001700201E2DB5
-:104CA000000000000000000800291E27000000008E
-:104CB00000000017008036270000000000000017E9
-:104CC00000201E2D00000000FFFFFFF700281E2718
-:104CD00000000000000000170080362700000000E0
-:104CE000000020100020441100000000000080009F
-:104CF00000204811000000000001A2A4002044117F
-:104D00000000000000000016006048110000036E63
-:104D100000002010002044110000000000010000ED
-:104D200000204811000000000000217C00204411F8
-:104D30000000000001800000002048110000000079
-:104D4000FFFFFFFF002048110000000000000000EE
-:104D500000204811000000000000000017000000C3
-:104D6000000000008100000000204411000000004D
-:104D70000000000100204811000000000004217F15
-:104D8000006044110000068D0000001F0021023069
-:104D9000000000000000000014C000000000068CAD
-:104DA0000000001000404C110000067200000000DE
-:104DB000C0200400000000000000000038C0000017
-:104DC000000000000000001D00200A2D000000006F
-:104DD0000000001E00200E2D000000000000001F3B
-:104DE0000020122D00000000000000200020162DE1
-:104DF00000000000000021690020441100000000B4
-:104E00000000000000204804000000000000000036
-:104E100000204805000000000000000000204801BC
-:104E200000000000CAFEBABE0020481100000000C9
-:104E30000000000400301224000000000000000008
-:104E4000002F006400000000000000000CC0000003
-:104E50000000068B0000000300281A22000000005A
-:104E6000000000080022122200000000FFFFF000F6
-:104E7000002812240000000000000000002910C4D7
-:104E8000000000000000001F004036240000000069
-:104E90000000000000800000000000000000000092
-:104EA0001AC000000000068D9F0000000020441181
-:104EB00000000000CAFEBABE002048110000000039
-:104EC000000000001AE00000000006900000000052
-:104ED0000080000000000000000000001AC0000078
-:104EE000000006929E000000002044110000000017
-:104EF000CAFEBABE002048110000000000000000F9
-:104F00001AE000000000069500000000008000008C
-:104F10000000000000000000006000000000000B26
-:104F200000001000006004110000031500000000E4
-:104F300000200411000000000000000000600811C3
-:104F4000000001B20000225C0020441100000000BB
-:104F5000000000030020481100000000000022565D
-:104F600000204411000000000000001B0020481138
-:104F7000000000000000A1FC00204411000000001F
-:104F80000000000100204811000000000001A1FD08
-:104F9000C0204411000000000000002100201E2D50
-:104FA000000000000000001000221E27000000008A
-:104FB000000000240020222D000000000000FFFF60
-:104FC00000282228000000000000000000294907F6
-:104FD0000000000000000000002048110000000058
-:104FE000000000220020222D000000000000FFFF32
-:104FF00000282228000000000000000000294907C6
-:105000000000000000000000002048110000000027
-:105010000000002300201E2D0000000000000010F2
-:1050200000221E27000000000000000000294907A0
-:1050300000000000000000000040481100000000D7
-:105040000000000000000000000000000000000060
-:105050000000000000000000000000000000000050
-:105060000000000000000000000000000000000040
-:105070000000000000000000000000000000000030
-:105080000000000000000000000000000000000020
-:105090000000000000000000000000000000000010
-:1050A0000000000000000000000000000000000000
-:1050B00000000000000000000000000000000000F0
-:1050C00000000000000000000000000000000000E0
-:1050D00000000000000000000000000000000000D0
-:1050E00000000000000000000000000000000000C0
-:1050F00000000000000000000000000000000000B0
-:10510000000000000000000000000000000000009F
-:10511000000000000000000000000000000000008F
-:10512000000000000000000000000000000000007F
-:10513000000000000000000000000000000000006F
-:10514000000000000000000000000000000000005F
-:10515000000000000000000000000000000000004F
-:10516000000000000000000000000000000000003F
-:10517000000000000000000000000000000000002F
-:10518000000000000000000000000000000000001F
-:10519000000000000000000000000000000000000F
-:1051A00000000000000000000000000000000000FF
-:1051B00000000000000000000000000000000000EF
-:1051C00000000000000000000000000000000000DF
-:1051D00000000000000000000000000000000000CF
-:1051E00000000000000000000000000000000000BF
-:1051F00000000000000000000000000000000000AF
-:10520000000000000000000000000000000000009E
-:10521000000000000000000000000000000000008E
-:10522000000000000000000000000000000000007E
-:10523000000000000000000000000000000000006E
-:10524000000000000000000000000000000000005E
-:10525000000000000000000000000000000000004E
-:10526000000000000000000000000000000000003E
-:10527000000000000000000000000000000000002E
-:10528000000000000000000000000000000000001E
-:10529000000000000000000000000000000000000E
-:1052A00000000000000000000000000000000000FE
-:1052B0000142050205C002500000000001C3016860
-:1052C000043F05C000000000022502090250015100
-:1052D000000000000223024502A00241000000007D
-:1052E00003D705C005C005C0000000000649064AF6
-:1052F000031F05C00000000005C005C503200340D2
-:1053000000000000032A0282034203340000000070
-:1053100005C005C005C005C00000000005C005515E
-:1053200005C005C00000000003BA05C004BB03446B
-:1053300000000000049A0450043D05C00000000075
-:1053400004D005C0044104DD00000000045005073E
-:10535000035103750000000005C005C005C005C06D
-:105360000000000005C005C005C005C00000000029
-:1053700005C005C0063F05C70000000005C005C008
-:10538000000705C00000000005C005C005C005C03D
-:105390000000000005C005C005C005C000000000F9
-:1053A00003F803ED0408040600000000040E040ADC
-:1053B000040C041000000000041C04180424042041
-:1053C00000000000042C0428043404300000000015
-:1053D00005C005C0043805C00000000005C005C0B8
-:1053E00005C005C00000000005C005C005C005C01F
-:1053F0000000000000020679069700060000000089
-:00000001FF
--- zfcpdump-kernel-4.4.orig/firmware/radeon/RV620_pfp.bin.ihex
+++ /dev/null
@@ -1,145 +0,0 @@
-:1000000000CA040000A00000007E828B007C038BED
-:10001000008001B8007C038B00D4401E00EE001E5F
-:1000200000CA040000A00000007E828B00C41838C3
-:1000300000CA240000CA2800009581A800C41C3A08
-:1000400000C3C00000CA080000CA0C00007C744B4A
-:1000500000C200050099C00000C41C3A007C744C2A
-:1000600000C0FFF000042C0400309002007D250049
-:1000700000351402007D350B00255403007CD5802B
-:1000800000259C030095C00400D5001B007EDDC147
-:10009000007D9D8000D6801B00D5801B00D4401EB3
-:1000A00000D5401E00D6401E00D6801E00D4801E03
-:1000B00000D4C01E009783D300D5C01E00CA08001C
-:1000C0000080001A00CA0C0000E4011E00D4001ECB
-:1000D0000080000C00C4183800E4013E00D4001E6B
-:1000E0000080000C00C4183800D4401E00EE001E32
-:1000F00000CA040000A00000007E828B00E4011E04
-:1001000000D4001E00D4401E00EE001E00CA0400F1
-:1001100000A00000007E828B00E4013E00D4001E9F
-:1001200000D4401E00EE001E00CA040000A0000023
-:10013000007E828B00CA180000D4401E00D5801EAD
-:100140000080005300D4007500D4401E00CA08008F
-:1001500000CA0C0000CA100000D4801900D4C018D6
-:1001600000D5001700D4801E00D4C01E00D5001E8C
-:1001700000E2001E00CA040000A00000007E828B86
-:1001800000CA080000D4806000D4401E0080000037
-:1001900000D4801E00CA080000D4806100D4401E34
-:1001A0000080000000D4801E00CA080000CA0C00B5
-:1001B00000D4401E00D4801600D4C01600D4801E87
-:1001C000008001B800D4C01E00C6084300CA0C005D
-:1001D00000CA10000094800400CA140000E420F358
-:1001E00000D4201300D5606500D4E01C00D5201C8D
-:1001F00000D5601C008000000006200100C60843F6
-:1002000000CA0C0000CA1000009483F700CA140052
-:1002100000E420F30080007900D4201300C60843D6
-:1002200000CA0C0000CA1000009883EF00CA140036
-:1002300000D400640080008D0000000000C414326F
-:1002400000C6184300C4082F0095400500C40C30B8
-:1002500000D4401E0080000000EE001E009583F5D3
-:1002600000C4103100D4403300D5206500D4A01C58
-:1002700000D4E01C00D5201C00E4015E00D4001E68
-:10028000008000000006200100CA1800000A2001BA
-:1002900000D6007600C408360098800700C61045D6
-:1002A0000095011000D4001F00D46062008000009F
-:1002B00000D4206200CC383500CC1433008401BB5C
-:1002C00000D4007200D5401E0080000000EE001E29
-:1002D00000E2001A008401BB00E2001A00CC104BBF
-:1002E00000CC0447002C9401007D098B0098400548
-:1002F000007D15CB00D4001A008001B800D4006D39
-:100300000034440100CC0C480098403A00CC2C4A00
-:100310000095800400CC0449008001B800D4001A84
-:1003200000D4C01A00282801008400F000CC10037B
-:100330000098801B0004380C008400F000CC1003EF
-:100340000098801700043808008400F000CC1003E7
-:100350000098801300043804008400F000CC1003DF
-:100360000098801400CC104C009A800900CC144DE9
-:10037000009840DC00D4006D00CC184800D5001A6D
-:1003800000D5401A008000C900D5801A0096C0D55B
-:1003900000D4006D008001B800D4006E009AC00344
-:1003A00000D4006D00D4006E0080000000EC007FDF
-:1003B000009AC0CC00D4006D008001B800D4006E5B
-:1003C00000CC140300CC180300CC1C03007D910367
-:1003D000007DD583007D190C0035CC1F0035701FC2
-:1003E000007CF0CB007CD08B00880000007E8E8BE0
-:1003F0000095C00400D4006E008001B800D4001A3B
-:1004000000D4C01A00CC080300CC0C0300CC1003AD
-:1004100000CC140300CC180300CC1C0300CC240334
-:1004200000CC28030035C41F0036B01F007C704B81
-:100430000034F01F007C704B0035701F007C704B47
-:10044000007D8881007DCCC1007E5101007E9541F8
-:10045000007C9082007CD4C2007C848B009AC00314
-:10046000007C8C8B002C88010098809E00D4006D4D
-:100470000098409C00D4006E00CC084C00CC0C4D81
-:1004800000CC104800D4801A00D4C01A00800101AA
-:1004900000D5001A00CC083200D40032009482D972
-:1004A00000CA0C0000D4401E0080000000D4001ED2
-:1004B00000E4011E00D4001E00CA080000CA0C009F
-:1004C00000CA100000D4401E00CA140000D4801ED0
-:1004D00000D4C01E00D5001E00D5401E00D54034FB
-:1004E0000080000000EE001E0028040400E2001A54
-:1004F00000E2001A00D4401A00CA380000CC0803F9
-:1005000000CC0C0300CC0C0300CC0C03009882BD83
-:1005100000000000008401BB00D7A06F0080000035
-:1005200000EE001F00CA040000C2FF0000CC083427
-:1005300000C13FFF007C74CB007CC90B007D010F24
-:10054000009902B0007C738B008401BB00D7A06FC0
-:100550000080000000EE001F00CA080000281900FB
-:10056000007D898B009580140028140400CA0C00BB
-:1005700000CA100000CA1C0000CA240000E2001FCC
-:1005800000D4C01A00D5001A00D5401A00CC1803B8
-:1005900000CC2C0300CC2C0300CC2C03007DA58BBD
-:1005A000007D9C4700984297000000000080016198
-:1005B00000D4C01A00D4401E00D4801E0080000069
-:1005C00000EE001E00E4011E00D4001E00D4401EF8
-:1005D00000EE001E00CA040000A00000007E828B16
-:1005E00000E4013E00D4001E00D4401E00EE001EB8
-:1005F00000CA040000A00000007E828B00CA080030
-:1006000000248C06000CCC060098C00600CC104ECE
-:100610000099000400D4007300E4011E00D4001E01
-:1006200000D4401E00D4801E0080000000EE001E9A
-:1006300000CA080000CA0C000034D01800251001C0
-:100640000095002100C17FFF00CA100000CA1400FD
-:1006500000CA180000D4801D00D4C01D007DB18BDD
-:1006600000C1420200C2C00100D5801D0034DC0E72
-:10067000007D5D4C007F734C00D7401E00D5001EEE
-:1006800000D5401E00C1420000C2C00000099C010C
-:100690000031DC10007F5F4C007F734C00042802A7
-:1006A000007D838000D5A86F00D5806600D7401EEE
-:1006B00000EC005E00C8240200C82402008001B8DB
-:1006C00000D6007600D4401E00D4801E00D4C01E88
-:1006D0000080000000EE001E0080000000EE001F01
-:1006E00000D4001F0080000000D4001F00D4001FB1
-:1006F0000088000000D4001F00000000000000007F
-:1007000000000000000000000000000000000000E9
-:1007100000000000000000000000000000000000D9
-:1007200000000000000000000000000000000000C9
-:1007300000000000000000000000000000000000B9
-:1007400000000000000000000000000000000000A9
-:100750000000000000000000000000000000000099
-:100760000000000000000000000000000000000089
-:100770000000000000000000000000000000000079
-:100780000000000000000000000000000000000069
-:100790000000000000000000000000000000000059
-:1007A0000000000000000000000000000000000049
-:1007B0000000000000000000000000000000000039
-:1007C0000000000000000000000000000000000029
-:1007D0000000000000000000000000000000000019
-:1007E0000000000000000000000000000000000009
-:1007F00000000000000000000000000000000000F9
-:1008000000010171000201780003008F0004007FE5
-:10081000000500030006003F000700320008012C1D
-:1008200000090046000A0036001001B6001700A2B9
-:100830000022013A00230149002000B400240125D0
-:100840000027004D0028006A002A0060002B00529B
-:10085000002F0065003200870034017F003C015604
-:10086000003F00720041018C0044012E00550173CD
-:100870000056017A0060000B00610034006200380D
-:1008800000630038006400380065003800660038F6
-:10089000006700380068003A00690041006A0048BB
-:1008A000006B0048006C0048006D0048006E004876
-:1008B000006F00480000000600000006000000066F
-:1008C0000000000600000006000000060000000610
-:1008D0000000000600000006000000060000000600
-:1008E00000000006000000060000000600000006F0
-:1008F00000000006000000060000000600000006E0
-:00000001FF
--- zfcpdump-kernel-4.4.orig/firmware/radeon/RV630_me.bin.ihex
+++ /dev/null
@@ -1,1345 +0,0 @@
-:1000000000000000C020040000000000000000000C
-:1000100000A0000A000000000000FFFF00284621A9
-:100020000000000000000000D900480000000000AF
-:1000300000000000C02004000000000000000000DC
-:1000400000A0000A000000000000000000E0000026
-:100050000000000000010000C02946200000000050
-:1000600000000000D900480000000000000000006F
-:10007000C0200400000000000000000000A0000AF2
-:10008000000000008100000000204411000000007A
-:1000900000000001002048110000000000042004BE
-:1000A000006044110000068A0000000000600000AB
-:1000B0000000062E00000000006000000000064264
-:1000C00000000000C02008000000000000000F0039
-:1000D000002816220000000000000008002116255C
-:1000E000000000000000001800203625000000007D
-:1000F0008D000000002044110000000000000004FA
-:10010000002F022500000000000000000CE00000AD
-:1001100000000018004120000040481100000019B4
-:100120000042200000204811000000008E00000066
-:1001300000204411000000000000002800204A2D8B
-:1001400000000000900000000020441100000000AA
-:100150000000000000204805000000000000000C26
-:1001600000211622000000000000000300281625D0
-:10017000000000000000001900211A220000000009
-:100180000000000400281A26000000000000000003
-:10019000002914C5000000000000001900203625C9
-:1001A0000000000000000000003A140200000000FF
-:1001B00000000016002116250000000000000003CA
-:1001C00000281625000000000000001700200E2D5A
-:1001D00000000000FFFFFFFC00280E2300000000CD
-:1001E00000000000002914A3000000000000001718
-:1001F00000203625000000000000800000280E22AC
-:10020000000000000000000700220E230000000094
-:10021000000000000029386E0000000020000000EF
-:1002200000280E22000000000000000600210E231E
-:1002300000000000000000000029386E00000000EF
-:100240000000000000220222000000000000000068
-:1002500014E0000000000038000000002EE0000064
-:1002600000000035000000002CE000000000003716
-:100270000000000000400E2D0000003900000008C2
-:1002800000200E2D00000000000000090040122D8B
-:10029000000000460000000100400E2D0000003963
-:1002A00000000000C0200C0000000000003FFFFC28
-:1002B0000028122300000000000000020022122487
-:1002C000000000000000001F00211E2300000000AD
-:1002D0000000000014E000000000003E00000008E4
-:1002E00000401C11000000410000000D00201E2DE8
-:1002F000000000000000000F00281E270000000082
-:100300000000000300221E27000000007FC0000044
-:1003100000281A23000000000000001400211A2603
-:10032000000000000000000100331A260000000059
-:100330000000000800221A26000000000000000053
-:1003400000290CC700000000000000270020362410
-:100350000000000000007F000028122100000000C3
-:1003600000001400002F0224000000000000000024
-:100370000CE000000000004B0000000100290E23EB
-:10038000000000000000000E0020362300000000E6
-:100390000000E0000020441100000000FFF8000011
-:1003A00000294A230000000000000000003A2C024F
-:1003B000000000000000000200220E2B00000000E0
-:1003C000FC00000000280E23000000000000000FC9
-:1003D000002036230000000000001FFF00294A23F0
-:1003E000000000000000002700204A2D000000004F
-:1003F000000000000020481100000000000000295B
-:1004000000200E2D00000000060A020000294A23E9
-:100410000000000000000000002048110000000063
-:100420000000000000204811000000000000000152
-:1004300000210222000000000000000014E0000083
-:1004400000000061000000002EE000000000005FDE
-:10045000000000002CE000000000005E0000000032
-:1004600000400E2D000000620000000100400E2D33
-:10047000000000620000000A00200E2D00000000B5
-:100480000000000B0040122D0000006A0000000078
-:10049000C0200C0000000000003FFFFC00281223D9
-:1004A00000000000000000020022122400000000F2
-:1004B0007FC0000000281623000000000000001488
-:1004C0000021162500000000000000010033162561
-:1004D000000000008000000000280E230000000043
-:1004E0000000000000290CA3000000003FFFFC00FA
-:1004F00000290E23000000000000001F00211E2321
-:10050000000000000000000014E000000000006D8A
-:100510000000010000401C11000000700000000DF0
-:1005200000201E2D00000000000000F000281E2703
-:10053000000000000000000400221E270000000050
-:100540008100000000204411000000000000000DA8
-:100550000020481100000000FFFFF0FF00281A30C3
-:10056000000000000000A02800204411000000004E
-:1005700000000000002948E6000000000000A0186C
-:1005800000204411000000003FFFFFFF00284A2325
-:10059000000000000000A010002044110000000036
-:1005A00000000000002048040000000000000030AF
-:1005B0000020162D00000000000000020029162572
-:1005C0000000000000000030002036250000000080
-:1005D000000000250020162D000000000000000093
-:1005E000002F00A300000000000000000CC000006D
-:1005F00000000083000000260020162D00000000EF
-:1006000000000000002F00A4000000000000000017
-:100610000CC000000000008400000000004000004A
-:100620000000008A000000250020362300000000A2
-:100630000000002600203624000000000000001703
-:1006400000201E2D000000000000000200210227F3
-:10065000000000000000000014E000000000008A1C
-:1006600000000000006000000000066500000000BF
-:1006700000600000000006590000000200210E2268
-:10068000000000000000000014C000000000008D09
-:1006900000000012C040362000000093000000005F
-:1006A0002EE0000000000091000000002CE000009F
-:1006B000000000900000000200400E2D000000929B
-:1006C0000000000300400E2D000000920000000C0E
-:1006D00000200E2D00000000000000120020362334
-:1006E000000000000000000300210E2200000000B6
-:1006F0000000000014C00000000000980000A00CE2
-:10070000002044110000000000000000C02048004C
-:100710000000000000000000C0404800000000A0F1
-:100720000000A00C002044110000000000000000A8
-:100730000020481100000000000000002EE0000032
-:100740000000009E000000002CE000000000009D62
-:100750000000000200400E2D0000009F000000037A
-:1007600000400E2D0000009F0000000C00200E2D08
-:10077000000000000000000000204803000000000E
-:1007800000000000003A0C0200000000003F0000E2
-:1007900000280E23000000000000001000210E239E
-:1007A00000000000000000110020362300000000BF
-:1007B0000000001E0021022B0000000000000000CD
-:1007C00014C00000000000A700000016C020362062
-:1007D000000000000000001F0021022B00000000AC
-:1007E0000000000014C00000000000AA0000001576
-:1007F000C0203620000000000000000800210E2B61
-:10080000000000000000007F00280E230000000010
-:1008100000000000002F0223000000000000000084
-:100820000CE00000000000E10000000027000000D4
-:10083000000000000000000000600000000002A3B3
-:1008400000000001002F0223000000000000000053
-:100850000AE00000000000B300000000006000009B
-:100860000000013A81000000002044110000000057
-:100870000000000600204811000000000000000CED
-:1008800000221E300000000099800000002044116A
-:1008900000000000000000040020122D00000000F5
-:1008A00000000008002212240000000000000010D8
-:1008B00000201811000000000000000000291CE4C6
-:1008C0000000000000000000006048070000012F49
-:1008D0009B00000000204411000000000000000008
-:1008E00000204802000000009C000000002044118D
-:1008F00000000000000000000033146F0000000042
-:100900000000000100333E23000000000000000052
-:10091000D9004800000000000000000000203C0555
-:1009200000000000810000000020441100000000D1
-:100930000000000E00204811000000000000000030
-:1009400000201010000000000000E007002044110B
-:10095000000000000000000F0021022B000000003A
-:100960000000000014C00000000000CB00F8FF08E9
-:1009700000204811000000009800000000404811CD
-:10098000000000DC000000F000280E220000000043
-:10099000000000A0002F0223000000000000000063
-:1009A0000CC00000000000DA0000001100200E2D35
-:1009B0000000000000000001002F022300000000E2
-:1009C000000000000CE00000000000D50000000264
-:1009D000002F022300000000000000000CE00000D7
-:1009E000000000D400003F0000400C11000000D6C1
-:1009F00000001F0000400C11000000D600000F0096
-:100A000000200C11000000000038000900294A23D2
-:100A1000000000003F00000000280E2B0000000036
-:100A20000000000200220E2300000000000000076A
-:100A300000494A23000000DC00380F09002048115B
-:100A400000000000680000070020481100000000BE
-:100A50000000000800214A270000000000000000FC
-:100A60000020481100000000060A020000294A2464
-:100A700000000000000000000020481100000000FD
-:100A80000000000000204811000000000000A20249
-:100A9000002044110000000000FF000000280E228A
-:100AA000000000000000008000294A230000000030
-:100AB0000000002700200E2D00000000000000268E
-:100AC0000020122D0000000000000000002F008315
-:100AD00000000000000000000CE00000000000EA40
-:100AE00000000000006000000000065F0000000041
-:100AF00000400000000000EB00000000006000006B
-:100B000000000662000000070020222D0000000007
-:100B10000000000500220E2200000000001000006E
-:100B200000280E23000000000000000000292068BB
-:100B30000000000000000000003A0C02000000006D
-:100B4000000000EF00280E2300000000000000005D
-:100B500000292068000000000000001700200E2D72
-:100B6000000000000000000300210223000000003C
-:100B70000000000014E00000000000F80000000B7E
-:100B800000210228000000000000000014C0000046
-:100B9000000000F8000004000029222800000000E6
-:100BA0000000001400203628000000000000001C97
-:100BB00000210E22000000000000000014C0000010
-:100BC000000000FD0000A30C002044110000000004
-:100BD0000000000000204811000000000000001E7E
-:100BE00000210E22000000000000000014C00000E0
-:100BF0000000010B0000A30F0020441100000000C2
-:100C00000000001100200E2D000000000000000177
-:100C1000002F022300000000000000000CC00000B4
-:100C200000000104FFFFFFFF004048110000010B1E
-:100C300000000002002F022300000000000000005E
-:100C40000CC00000000001070000FFFF0040481139
-:100C50000000010B00000004002F02230000000030
-:100C6000000000000CC000000000010A000000FFAE
-:100C7000004048110000010B000000010020481155
-:100C8000000000000002C400002044110000000029
-:100C90000000001F00210E220000000000000000E4
-:100CA00014C00000000001120000001040210E20BE
-:100CB00000000000000000130020362300000000A8
-:100CC0000000001840224A20000000000000001030
-:100CD000C0424A20000001140000000000200C1156
-:100CE0000000000000000013002036230000000078
-:100CF000000000000020481100000000000000007B
-:100D000000204811000000000000000A002010111F
-:100D10000000000000000000002F0224000000007E
-:100D2000000000000CE000000000011B00000000BB
-:100D300000204811000000000000000100531224B0
-:100D400000000117FFBFFFFF00283A2E000000003F
-:100D50000000001B00210222000000000000000033
-:100D600014C000000000012E81000000002044118A
-:100D7000000000000000000D0020481100000000ED
-:100D80000000001800220E3000000000FC000000EF
-:100D900000280E2300000000810000000020441104
-:100DA000000000000000000E0020481100000000BC
-:100DB0000000000000201010000000000000E00E05
-:100DC000002044110000000007F8FF08002048112F
-:100DD000000000000000000000294A23000000007D
-:100DE0000000001C00201E2D000000000000000874
-:100DF00000214A27000000000000000000204811E8
-:100E000000000000060A020000294A240000000039
-:100E10000000000000204811000000000000000059
-:100E200000204811000000000000000000800000C9
-:100E300000000000810000000020441100000000BC
-:100E40000000000100204811000000000000217C8B
-:100E50000020441100000000008000000020481124
-:100E60000000000000000000002048060000000014
-:100E70000000000800214A270000000000000000D8
-:100E800017000000000000000004217F00604411F2
-:100E90000000068A0000001F002102300000000050
-:100EA0000000000014C000000000068900000004DB
-:100EB00000404C1100000135810000000020441169
-:100EC00000000000000000010020481100000000A8
-:100ED000000021F800204411000000000000001C68
-:100EE0000020481100000000000421F900604411B6
-:100EF0000000068A000000110021023000000000FE
-:100F00000000000014E000000000013C00000000B0
-:100F100000800000000000000000000000600000F1
-:100F20000000000B00000000006004110000031529
-:100F3000000000000020041100000000000000007C
-:100F400000600811000001B2000000000060000015
-:100F5000000001600000FFFF40280E20000000009C
-:100F600000000010C0211220000000000000FFFF60
-:100F7000402806200000000000000010C0210A20C8
-:100F800000000000000000000034146100000000B8
-:100F90000000000000741882000002BB0001A1FDE7
-:100FA00000604411000002E000003FFF002F022F0C
-:100FB00000000000000000000CC00000000001471D
-:100FC00000000000C040040000000001000000001C
-:100FD000006000000000000B000000000060041131
-:100FE00000000315000000000020041100000000B4
-:100FF0000000000000600811000001B200003FFF87
-:10100000002F022F00000000000000000CE0000094
-:10101000000000000000000000600000000001600F
-:101020000000001040210E20000000000000FFFF23
-:10103000C0281220000000000000001040211620EF
-:10104000000000000000FFFFC0681A20000002BB83
-:101050000001A1FD00604411000002E000003FFF1C
-:10106000002F022F00000000000000000CC0000054
-:101070000000015800000000C04004000000000112
-:101080000000225C0020441100000000000000016C
-:1010900000300A2F000000000000000100210A2299
-:1010A000000000000000000300384A220000000099
-:1010B0000000225600204411000000000000001A29
-:1010C00000204811000000000000A1FC0020441195
-:1010D0000000000000000001008048110000000036
-:1010E00000000000006000000000000B0000000095
-:1010F000006000000000018F0000000000600000A0
-:10110000000001A000003FFF002F022F00000000A0
-:10111000000000000CE000000000000000000000E3
-:1011200000202C0800000000000000000020241116
-:101130000000000000000000002028110000000056
-:10114000000022560020441100000000000000169C
-:1011500000204811000000000000225C0020441123
-:101160000000000000000003002048110000000003
-:1011700093800000002044110000000000000002E5
-:1011800000221E290000000000000000007048EB53
-:101190000000019C0000000000600000000002BB95
-:1011A00000000001403306200000000000000000A5
-:1011B000C03024090000000000003FFF002F022F74
-:1011C00000000000000000000CE000000000000033
-:1011D0000000000000600000000002A3000000000A
-:1011E000002F022100000000000000000AE00000C3
-:1011F0000000018100000000006000000000013AD2
-:101200000000000000400000000001869500000082
-:10121000002044110000000000000000002F022107
-:1012200000000000000000000CE00000000001864B
-:1012300000000000C0204800000000000000000185
-:10124000005306210000018292000000002044119A
-:101250000000000000000000C0604800000001978E
-:101260000001A1FD00204411000000000000001159
-:101270000020062D00000000000000000078042A75
-:10128000000002FB00000000002028090000000010
-:1012900000003FFF002F022F0000000000000000B0
-:1012A0000CC000000000017400000000C0400400F9
-:1012B000000000010000021000600411000003158E
-:1012C00000003FFF002F022F000000000000000080
-:1012D0000CE000000000019400000015C020362042
-:1012E0000000000000000016C020362000000000B2
-:1012F0003F800000002004110000000046000000B4
-:1013000000600811000001B2000000000080000031
-:10131000000000000000A1FC0020441100000000BB
-:1013200000003FFF002F022F00000000000000001F
-:101330000CC000000000019B00000001008048116B
-:1013400000000000000000210080481100000000A3
-:101350000000FFFF40280E200000000000000010E9
-:10136000C0211220000000000000FFFF40281620CE
-:101370000000000000000010C0811A2000000000E2
-:101380008100000000204411000000000000000661
-:1013900000204811000000000000000800221E305C
-:1013A000000000000000002900201A2D00000000AD
-:1013B0000000E0000020441100000000FFFBFF09D6
-:1013C00000204811000000000000000F0020222D26
-:1013D0000000000000001FFF00294A280000000054
-:1013E000000000060020222D000000000000000088
-:1013F000002920E80000000000000000002048084C
-:101400000000000000000000002048110000000063
-:10141000060A020000294A26000000000000000021
-:1014200000204811000000000000000000204811CA
-:101430000000000000000100002018110000000062
-:101440000000000800621E280000012F00000008B4
-:1014500000822228000000000002C0000020441189
-:10146000000000000000001500600E2D000001BD0E
-:101470000000001600600E2D000001BD0000C00835
-:1014800000204411000000000000001700200E2D75
-:10149000000000000000000014C00000000001B9BE
-:1014A0000000000000200411000000000000000007
-:1014B0000020480100000000390000000020481111
-:1014C00000000000000000000020481100000000A3
-:1014D000000000000080480200000000000000182A
-:1014E00000202E2D0000000000000000003B0D63D6
-:1014F000000000000000000800224A230000000055
-:101500000000001000224A23000000000000001824
-:1015100000224A2300000000000000000080480371
-:101520000000000000000000006000000000000B50
-:10153000000010000060041100000315000000000E
-:1015400000200411000000000000000000600811ED
-:10155000000001B2000000070021062F000000007B
-:101560000000001300200A2D000000000000000110
-:1015700000202C11000000000000FFFF4028222066
-:10158000000000000000000F0026222800000000DC
-:101590000000001040212620000000000000000F85
-:1015A000002626290000000000000000002028027C
-:1015B000000000000000225600204411000000003E
-:1015C0000000001B00204811000000000000000087
-:1015D000002F022100000000000000000CE00000CD
-:1015E000000001E00000225C002044110000000027
-:1015F0000000008100204811000000000000A1FC54
-:1016000000204411000000000000000100204811EB
-:10161000000000000000008000201C1100000000FD
-:1016200000000000002F0227000000000000000062
-:101630000CE00000000001DC000000000060000081
-:10164000000001E90000000100531E27000001D83E
-:101650000000000100202C11000000000000001F0D
-:1016600000280A22000000000000001F00282A2A8B
-:10167000000000000000000100530621000001D11D
-:101680000000225C00204411000000000000000265
-:1016900000304A2F000000000000A1FC002044118F
-:1016A00000000000000000010020481100000000C0
-:1016B0000000000100301E2F0000000000000000AC
-:1016C000002F022700000000000000000CE00000D6
-:1016D000000000000000000000600000000001E9C0
-:1016E0000000000100531E27000001E50000FFFF7D
-:1016F00040280E20000000000000000F00260E23EE
-:101700000000000000000010C021122000000000B6
-:101710000000000F0026122400000000000000005E
-:1017200000201411000000000000000000601811EB
-:10173000000002BB0001A1FD0020441100000000D8
-:1017400000000000002F022B00000000000000003D
-:101750000CE00000000001F8000000100022162834
-:1017600000000000FFFF0000002816250000000018
-:101770000000FFFF00281A29000000000000000000
-:10178000002948C500000000000000000020480AB1
-:10179000000000000000000000202C1100000000EC
-:1017A000000000100022162300000000FFFF0000D0
-:1017B00000281625000000000000FFFF00281A2462
-:1017C0000000000000000000002948C500000000E3
-:1017D0000000000000731503000002050000000077
-:1017E0000020180500000000000000000073152410
-:1017F0000000020500000000002D14C500000000DC
-:1018000000000000003008A20000000000000000FE
-:101810000020480200000000000000000020280214
-:101820000000000000000000002020030000000075
-:101830000000000000802404000000000000000FF1
-:1018400000210225000000000000000014C000007C
-:101850000000068900000000002B140500000000B5
-:1018600000000001009016250000000000000000AC
-:10187000006000000000000B000000000060041188
-:10188000000003150000000000200411000000000B
-:101890000000000000600811000001B200002256A4
-:1018A00000204411000000000000001A00294A2214
-:1018B0000000000000000000C02000000000000048
-:1018C00000003FFF002F022F00000000000000007A
-:1018D0000CE000000000000000000000C020040038
-:1018E000000000000000225C002044110000000005
-:1018F0000000000300384A21000000000000A1FCA5
-:1019000000204411000000000000000100204811E8
-:10191000000000000000FFFF40281220000000002F
-:1019200000000010C0211A20000000000000FFFF8E
-:1019300040280E200000000000000010C0211620EA
-:10194000000000000000000000741465000002BBED
-:101950000001A1FD00604411000002E00000000150
-:10196000003306210000000000000000002F0221CB
-:1019700000000000000000000CC000000000021980
-:1019800000003FFF002F022F0000000000000000B9
-:101990000CC000000000021200000000C040040063
-:1019A000000000010000000000600000000006428E
-:1019B000000000000040040F0000021300000000BF
-:1019C000006000000000062E000000000060000023
-:1019D0000000064200000210006004110000031520
-:1019E0000000000000600000000001A000000000F6
-:1019F000006000000000019C00000000006000008A
-:101A0000000002BB0000000000600000000002A314
-:101A1000938000000020441100000000000000003E
-:101A2000002048080000000000000000002F022FE6
-:101A300000000000000000000AE000000000023288
-:101A400000000000006000000000013A00000000FB
-:101A50000040000000000236950000000020441104
-:101A60000000000000000000002F022F0000000016
-:101A7000000000000CE00000000002360000000042
-:101A8000C0404800000002339200000000204411D2
-:101A90000000000000000000C0204800000000001E
-:101AA0000000225600204411000000000000001633
-:101AB00000204811000000000000225C00204411BA
-:101AC000000000000000000300204811000000009A
-:101AD0000000A1FC002044110000000000000001F3
-:101AE00000204811000000000001A1FD0020441169
-:101AF000000000000000000000600411000002FB74
-:101B000000000000C04004000000000100000000D0
-:101B1000006000000000062E0000A00C0020441110
-:101B20000000000000000000C0204800000000008D
-:101B300000000000C040480000000000000000005D
-:101B4000006000000000000B0000001840210A2087
-:101B50000000000000000003002F0222000000002F
-:101B6000000000000AE000000000024C0000001429
-:101B70000020222D00000000000801010029222879
-:101B800000000000000000140020362800000000C3
-:101B90000000A30C00204411000000000000000021
-:101BA000C02048000000000000000000C0204800E5
-:101BB0000000000000000000C0404800000002518A
-:101BC00000000000006000000000000B000000109A
-:101BD00000600411000003153F8000000020041184
-:101BE000000000000000000000600811000001B2C9
-:101BF0000000225C002044110000000000000003EF
-:101C000000204811000000000000000000600000FB
-:101C10000000027C0000001700201E2D00000000C4
-:101C20000000000100211E2700000000000000004D
-:101C300014E000000000026A0000001200201E2DC7
-:101C4000000000000000FFFF00281E270000000029
-:101C50000000000000341C2700000000000000000D
-:101C600012C000000000025F0000000000201C11F4
-:101C70000000000000000000002F00E50000000050
-:101C80000000000008C00000000002620000000028
-:101C900000201407000000000000001200201E2D8C
-:101CA000000000000000001000211E2700000000BE
-:101CB0000000000000341C4700000000000000008D
-:101CC00012C00000000002670000000000201C118C
-:101CD0000000000000000000002F00E600000000EF
-:101CE0000000000008C000000000026A00000000C0
-:101CF0000020180700000000000000000060000045
-:101D0000000002C100002256002044110000000023
-:101D1000000000000034202300000000000000004C
-:101D200012C00000000002720000000000342044D5
-:101D3000000000000000000012C00000000002715E
-:101D40000000001600404811000002760000001854
-:101D500000404811000002760000000000342044DA
-:101D6000000000000000000012C00000000002752A
-:101D70000000001700404811000002760000001922
-:101D800000204811000000000000A1FC00204411C8
-:101D900000000000000000010020481100000000C9
-:101DA0000001A1FD00604411000002E900003FFFB6
-:101DB000002F022F00000000000000000CC00000F7
-:101DC0000000025600000000C040040000000001B6
-:101DD0000000001040210620000000000000FFFF6E
-:101DE000C0280A20000000000000001040210E2042
-:101DF000000000000000FFFFC028122000000000CB
-:101E00000000001040211620000000000000FFFF2D
-:101E1000C0881A200000000081000000002044114A
-:101E20000000000000000001002048110000000038
-:101E300000042004006044110000068A0000000035
-:101E4000006000000000062E00000000C0600000DE
-:101E5000000002A30000000500200A2D0000000081
-:101E60000000000800220A22000000000000002BF1
-:101E700000201A2D000000000000001C00201E2D74
-:101E8000000000000000700000281E270000000075
-:101E90000000000000311CE6000000000000002AE5
-:101EA00000201A2D000000000000000C00221A265D
-:101EB0000000000000000000002F00E6000000000D
-:101EC0000000000006E00000000002920000000098
-:101ED00000201C11000000000000000000200C1178
-:101EE000000000000000002B00203623000000004E
-:101EF0000000001000201811000000000000000089
-:101F000000691CE20000012F9380000000204411B2
-:101F10000000000000000000002048070000000052
-:101F200095000000002044110000000000000000A7
-:101F3000002F022F00000000000000000CE0000055
-:101F40000000029D0000000100333E2F0000000051
-:101F500000000000D90048000000000092000000CE
-:101F6000002044110000000000000000C0204800D4
-:101F7000000000000000001C0040362700000000A8
-:101F80000000000CC0220A20000000000000002910
-:101F9000002036220000000000000028C04036204B
-:101FA000000000000000A2A4002044110000000076
-:101FB000000000090020481100000000A1000000FE
-:101FC00000204411000000000000000100804811C2
-:101FD000000000000000002100201E2D0000000075
-:101FE00000000000002C1CE30000000000000021A5
-:101FF00000203627000000000000002200201E2DD7
-:102000000000000000000000002C1CE400000000A4
-:1020100000000022002036270000000000000023FE
-:1020200000201E2D0000000000000000003120A351
-:102030000000000000000000002D1D07000000004F
-:1020400000000023002036270000000000000024CC
-:1020500000201E2D0000000000000000003120C400
-:102060000000000000000000002D1D07000000001F
-:10207000000000240080362700000000000000213E
-:10208000002036230000000000000022002036243B
-:10209000000000000000000000311CA30000000050
-:1020A0000000002300203627000000000000000090
-:1020B00000311CC40000000000000024008036270E
-:1020C000000000000000001A002036270000000079
-:1020D0000000001B00203628000000000000001750
-:1020E00000201E2D00000000000000020021022739
-:1020F000000000000000000014C00000000002DC2E
-:102100000000000000400000000002D90000001A9A
-:1021100000203627000000000000001B00203628A9
-:10212000000000000000001700201E2D000000002D
-:102130000000000200210227000000000000000053
-:1021400014E00000000002D9000000030021022773
-:10215000000000000000000014E00000000002DCAD
-:102160000000002300201E2D0000000000000000E1
-:10217000002E00E1000000000000000002C000008E
-:10218000000002DC0000002100201E2D00000000E5
-:1021900000000000003120A100000000000000004D
-:1021A000002E00E8000000000000000006C0000053
-:1021B000000002DC0000002400201E2D00000000B2
-:1021C00000000000002E00E20000000000000000FF
-:1021D00002C00000000002DC0000002200201E2DD2
-:1021E0000000000000000000003120C200000000DC
-:1021F00000000000002E00E80000000000000000C9
-:1022000006C00000000002DC0000000000600000CA
-:10221000000006650000000000600000000002B53C
-:102220000000000000400000000002DE000000008E
-:1022300000600000000002B5000000000060000027
-:102240000000065C0000000000400000000002DE0C
-:102250000000000000600000000002A70000000075
-:1022600000400000000002DE0000001A00201E2DC9
-:10227000000000000000001B0080222D0000000074
-:102280000000001000221E230000000000000000DB
-:1022900000294887000000000000000000311CA356
-:1022A000000000000000001000221E2700000000B7
-:1022B0000000000000294887000000000000001016
-:1022C00000221E230000000000000000003120C496
-:1022D000000000000000FFFF00282228000000008E
-:1022E0000000000000894907000000000000001005
-:1022F00000221E2300000000000000000029488783
-:10230000000000000000001000221E21000000005C
-:102310000000000000294847000000000000000005
-:1023200000311CA3000000000000001000221E2746
-:1023300000000000000000000029488700000000A5
-:102340000000000000311CA100000000000000108F
-:1023500000221E270000000000000000002948475E
-:10236000000000000000001000221E2300000000FA
-:1023700000000000003120C4000000000000FFFF4A
-:102380000028222800000000000000000029490762
-:10239000000000000000001000221E2100000000CC
-:1023A00000000000003120C2000000000000FFFF1C
-:1023B00000282228000000000000000000894907D2
-:1023C000000000000000001000221E23000000009A
-:1023D0000000000000294887000000000000000104
-:1023E00000220A210000000000000000003308A2C3
-:1023F000000000000000001000221E22000000006B
-:102400000000001000212222000000000000000057
-:1024100000294907000000000000000000311CA353
-:10242000000000000000001000221E270000000035
-:1024300000000000002948870000000000000001A3
-:1024400000220A210000000000000000003008A265
-:10245000000000000000001000221E22000000000A
-:1024600000000010002122220000000000000000F7
-:1024700000294907000000000000001000221E2370
-:102480000000000000000000003120C40000000037
-:102490000000FFFF002822280000000000000000CC
-:1024A000002949070000000000000000003808C5AE
-:1024B00000000000000000000030084100000000A3
-:1024C0000000000100220A220000000000000000BD
-:1024D000003308A2000000000000001000221E22AD
-:1024E0000000000000000010002122220000000077
-:1024F00000000000008949070000000000000017EC
-:102500000020222D000000000000000014C0000088
-:1025100000000318FFFFFFEF002806210000000065
-:10252000000000140020222D000000000000F8E050
-:1025300000204411000000000000000000294901B3
-:1025400000000000000000000089490100000000B8
-:102550000000000000204811000000000000000002
-:102560000020481100000000060A02000080481107
-:102570000000000000000000C0200000000000007B
-:1025800097000000C020441100000000000000007F
-:10259000C0204811000000008A0000000020441103
-:1025A00000000000000000000020481100000000B2
-:1025B0000000225C00204411000000000000000028
-:1025C000C0204800000000000000A1FC00204411D1
-:1025D0000000000000000000C020480000000000D3
-:1025E00000000000C0200400000000000000000007
-:1025F00000A0000A00000000970000000020441125
-:102600000000000000000000002048110000000051
-:102610008A000000002044110000000000000000BB
-:1026200000204811000000000000225C002044113E
-:102630000000000000000000C02048000000000072
-:102640000000A1FC00204411000000000000000078
-:10265000C02048000000000000000000C02004006E
-:10266000000000000000000000A0000A00000000C0
-:10267000970000000020441100000000000000004E
-:1026800000204811000000008A00000000204411D2
-:1026900000000000000000000020481100000000C1
-:1026A0000000225C00204411000000000000000037
-:1026B000C0204800000000000000A1FC00204411E0
-:1026C0000000000000000000C020480000000000E2
-:1026D0000001A1FD002044110000000000000000E6
-:1026E000D90048000000000000000000C0200400E5
-:1026F000000000000000000000A0000A0000000030
-:1027000000002257002044110000000000000003D8
-:10271000C0484A20000000000000225D0020441153
-:102720000000000000000000C04048000000000061
-:1027300000000000006000000000064200000000F1
-:10274000C0200800000000000000225C00204411AE
-:10275000000000000000000300384A2200000000D2
-:102760000000A1FC00204411000000000000000057
-:10277000C0204800000000000001A1FD002044111D
-:102780000000000000000000002F022200000000F6
-:10279000000000000CE0000000000000000000004D
-:1027A00040204800000000000000000140304A20A6
-:1027B0000000000000000002C0304A2000000000BD
-:1027C0000000000100530A220000034B0000003FFC
-:1027D000C0280A20000000008100000000204411F1
-:1027E000000000000000000100204811000000006F
-:1027F000000021F800204411000000000000001833
-:102800000020481100000000000421F9006044117C
-:102810000000068A000000110021023000000000C4
-:102820000000000014E00000000003540000001449
-:10283000002F022200000000000000000CC0000079
-:10284000000003640000201000204411000000007C
-:102850000000800000204811000000000001A2A438
-:102860000020441100000000000000000060480249
-:102870000000036E00002100002044110000000051
-:1028800000000000C0204800000000000000000020
-:10289000C02048000000000000000000C0204800E8
-:1028A0000000000000000000C040480000000000E0
-:1028B00000000004002F02220000000000000000C1
-:1028C0000CC000000000036A00002010002044112A
-:1028D00000000000000080000020481100000000FF
-:1028E0000001A2A40020441100000000000000002C
-:1028F000004048020000035F00000028002F022271
-:1029000000000000000000000CC00000000005BD39
-:102910000001A2A4002044110000000000000000FB
-:10292000004048020000035F0000002C0020362613
-:102930000000000000000049002018110000000005
-:102940000000003F002048110000000000000001CE
-:1029500000331A260000000000000000002F0226AD
-:1029600000000000000000000CC000000000037028
-:102970000000002C00801A2D000000000000003F25
-:10298000C0280A200000000000000015002F0222CD
-:1029900000000000000000000CE0000000000386C2
-:1029A00000000006002F02220000000000000000CE
-:1029B0000CE00000000003B100000016002F02220E
-:1029C00000000000000000000CE00000000003B563
-:1029D00000000020002F0222000000000000000084
-:1029E0000CE000000000039C0000000F002F0222FA
-:1029F00000000000000000000CE00000000003A840
-:102A000000000010002F0222000000000000000063
-:102A10000CE00000000003A80000001E002F0222AE
-:102A200000000000000000000CE000000000039027
-:102A30000000A2A4002044110000000000000000DB
-:102A400000404802000000000800000000290A229F
-:102A5000000000000000000340210E2000000000E4
-:102A60000000000CC021122000000000000800003F
-:102A7000002812240000000000000014C0221620CC
-:102A80000000000000000000002914A40000000065
-:102A90000000A2A40020441100000000000000007B
-:102AA000002948A2000000000000A1FE00204411FF
-:102AB000000000000000000000404803000000008B
-:102AC000810000000020441100000000000000010F
-:102AD0000020481100000000000021F800204411EF
-:102AE0000000000000000016002048110000000057
-:102AF000000421F9006044110000068A000000155E
-:102B000000210230000000000000000014E000007E
-:102B1000000003920000210E00204411000000007C
-:102B200000000000C020480000000000000000007D
-:102B3000C0204800000000000000A2A400204411B2
-:102B400000000000000000000040480200000000FB
-:102B5000810000000020441100000000000000017E
-:102B60000020481100000000000021F8002044115E
-:102B700000000000000000170020481100000000C5
-:102B8000000421F9006044110000068A00000003DF
-:102B900000210230000000000000000014E00000EE
-:102BA0000000039E000021080020441100000000E6
-:102BB00000000000C02048000000000000000000ED
-:102BC000C0204800000000000000A2A40020441122
-:102BD000000000000000000000404802000000006B
-:102BE0000000A2A40020441100000000000000002A
-:102BF0000020480200000000800000000020441176
-:102C0000000000000000000000204811000000004B
-:102C100081000000002044110000000000000010AE
-:102C200000204811000000000000000000200010FB
-:102C3000000000000000000014C00000000003AE0F
-:102C40000000000000400000000000000000201014
-:102C50000020441100000000000080000020481106
-:102C6000000000000001A2A40020441100000000A8
-:102C70000000000600404811000000000000201085
-:102C800000204411000000000000800000204811D6
-:102C9000000000000001A2A4002044110000000078
-:102CA00000000016006048110000036E00000000E4
-:102CB000004000000000000000000000C0200800EC
-:102CC0000000000000000000C0200C000000000018
-:102CD0000000001D00210223000000000000000091
-:102CE00014E00000000003CE810000000020441129
-:102CF000000000000000000100204811000000005A
-:102D0000000021F80020441100000000000000181D
-:102D10000020481100000000000421F90060441167
-:102D20000000068A000000110021023000000000AF
-:102D30000000000014E00000000003C000002100BB
-:102D400000204411000000000000000000204802A4
-:102D50000000000000000000002048030000000008
-:102D6000BABECAFE0020481100000000CAFEBABE6A
-:102D70000020481100000000000020100020441135
-:102D8000000000000000800000204811000000004A
-:102D90000000A2A400204411000000000000000474
-:102DA0000040481100000000000021700020441184
-:102DB00000000000000000000020480200000000A9
-:102DC0000000000000204803000000008100000017
-:102DD00000204411000000000000000A00204811FB
-:102DE00000000000000000000020001000000000B3
-:102DF0000000000014C00000000003D38C0000009D
-:102E00000020441100000000CAFEBABE0040481174
-:102E100000000000810000000020441100000000BC
-:102E200000000001002048110000000000003FFFEA
-:102E300040280A20000000008000000040280E20EA
-:102E40000000000040000000C02812200000000028
-:102E500000040000006946220000068A000000000D
-:102E6000002014100000000000000000002F0223CA
-:102E700000000000000000000CC00000000003E1A2
-:102E800000000000C0401800000003E400003FFF05
-:102E9000C0281A2000000000000400000069462637
-:102EA0000000068A0000000000201810000000004A
-:102EB00000000000002F02240000000000000000BD
-:102EC0000CC00000000003E700000000C0401C0030
-:102ED000000003EA00003FFFC0281E2000000000A1
-:102EE00000040000006946270000068A0000000078
-:102EF00000201C1000000000000000000020440220
-:102F00000000000000000000002820C500000000B4
-:102F100000000000004948E800000000A580000013
-:102F200000200811000000000000200000200C110B
-:102F30000000000083000000006044110000041243
-:102F4000000000000020440200000000000000001B
-:102F5000C0204800000000000000000040204800A1
-:102F6000000000000000001FC0210220000000003F
-:102F70000000000014C00000000003F70000201053
-:102F800000204411000000000000800000204811D3
-:102F9000000000000000FFFFC0481220000003FFF7
-:102FA000A780000000200811000000000000A00021
-:102FB00000200C110000000083000000006044119C
-:102FC0000000041200000000002044020000000085
-:102FD00000000000C02048000000000000000000C9
-:102FE000C0204800000000000000FFFFC0281220A1
-:102FF00000000000830000000020441100000000D9
-:103000000000000000304883000000008400000041
-:10301000002044110000000000000000C020480013
-:1030200000000000000000001D0000000000000083
-:103030008300000000604411000004120000000042
-:10304000C040040000000001A98000000020081119
-:10305000000000000000C00000400C11000003FA56
-:10306000AB80000000200811000000000000F8E024
-:1030700000400C11000003FAAD8000000020081190
-:10308000000000000000F88000400C11000003FA6E
-:10309000B380000000200811000000000000F3FCD5
-:1030A00000400C11000003FAAF800000002008115E
-:1030B000000000000000E00000400C11000003FAD6
-:1030C000B180000000200811000000000000F000A6
-:1030D00000400C11000003FA83000000002044119E
-:1030E00000000000000021480020481100000000FE
-:1030F00084000000002044110000000000000000D7
-:10310000C020480000000000000000001D0000007A
-:10311000000000000000000000800000000000002F
-:1031200001182000C0304620000000000000000010
-:10313000D90048000000000000000000C02004008A
-:10314000000000000000000000A0000A00000000D5
-:103150000218A000C030462000000000000000005F
-:10316000D90048000000000000000000C02004005A
-:10317000000000000000000000A0000A00000000A5
-:103180000318C000C030462000000000000000000E
-:10319000D90048000000000000000000C02004002A
-:1031A000000000000000000000A0000A0000000075
-:1031B0000418F8E0C03046200000000000000000C5
-:1031C000D90048000000000000000000C0200400FA
-:1031D000000000000000000000A0000A0000000045
-:1031E0000518F880C03046200000000000000000F4
-:1031F000D90048000000000000000000C0200400CA
-:10320000000000000000000000A0000A0000000014
-:103210000618E000C030462000000000000000005A
-:10322000D90048000000000000000000C020040099
-:10323000000000000000000000A0000A00000000E4
-:103240000718F000C0304620000000000000000019
-:10325000D90048000000000000000000C020040069
-:10326000000000000000000000A0000A00000000B4
-:103270000818F3FCC03046200000000000000000E9
-:10328000D90048000000000000000000C020040039
-:10329000000000000000000000A0000A0000000084
-:1032A0000000003000200A2D000000000000000097
-:1032B000C0290C4000000000000000300020362330
-:1032C0000000000000000000C0200400000000001A
-:1032D0000000000000A0000A0000000086000000BE
-:1032E00000204411000000000000000000404801E0
-:1032F0000000000085000000C02044110000000014
-:103300000000000000404801000000000000217C97
-:10331000002044110000000000000000C020480010
-:103320000000000000000000C02048000000000075
-:1033300000000000C02048000000000081000000E4
-:10334000002044110000000000000001002048118E
-:103350000000000000000000C02008000000000085
-:103360000000000017000000000000000004217FA2
-:10337000006044110000068A0000001F0021023096
-:10338000000000000000000014C000000000000069
-:103390000000000000404C02000004480000000053
-:1033A000C0200C000000000000000000C020100041
-:1033B0000000000000000000C02014000000000019
-:1033C00000000000C0201800000000000000000005
-:1033D000C0201C000000000000007F0000280A211F
-:1033E0000000000000004500002F02220000000045
-:1033F000000000000CE00000000004560000000087
-:10340000C0202000000000000000000017000000A5
-:10341000000000000000001000280A230000000047
-:1034200000000010002F0222000000000000000039
-:103430000CE000000000045E810000000020441148
-:103440000000000000000001002048110000000002
-:1034500000040000006946240000068A0000000005
-:1034600000400000000004638100000000204411BF
-:1034700000000000000000000020481100000000D3
-:103480000000216D00204411000000000000000039
-:103490000020480400000000000000000060480513
-:1034A0000000068F00000000002824F0000000004B
-:1034B0000000000700280A230000000000000001AF
-:1034C000002F022200000000000000000AE00000BF
-:1034D0000000046A00000000002F00C90000000086
-:1034E0000000000004E00000000004830000000071
-:1034F000004000000000049000000002002F0222A3
-:1035000000000000000000000AE000000000046F5E
-:1035100000000000002F00C90000000000000000B3
-:1035200002E00000000004830000000000400000F2
-:103530000000049000000003002F022200000000A1
-:10354000000000000AE00000000004740000000019
-:10355000002F00C900000000000000000CE0000087
-:103560000000048300000000004000000000049000
-:1035700000000004002F02220000000000000000F4
-:103580000AE000000000047900000000002F00C9DC
-:1035900000000000000000000AE0000000000483BA
-:1035A0000000000000400000000004900000000542
-:1035B000002F022200000000000000000AE00000CE
-:1035C0000000047E00000000002F00C90000000081
-:1035D0000000000006E0000000000483000000007E
-:1035E000004000000000049000000006002F0222AE
-:1035F00000000000000000000AE00000000004835A
-:1036000000000000002F00C90000000000000000C2
-:1036100008E00000000004830000000000400000FB
-:103620000000049000007F0000280A210000000034
-:1036300000004500002F02220000000000000000F2
-:103640000AE00000000000000000000800210A233A
-:10365000000000000000000014C000000000048D05
-:10366000000021690020441100000000000000005B
-:10367000C02048000000000000000000C0204800FA
-:103680000000000000000000C02048000000000012
-:10369000CAFEBABE00404811000000000000000051
-:1036A000C02044000000000000000000C020000016
-:1036B0000000000000000000C040480000000000C2
-:1036C00000007F0000280A210000000000004500E3
-:1036D000002F022200000000000000000AE00000AD
-:1036E0000000049600000000C02000000000000060
-:1036F00000000000C02000000000000000000000EA
-:10370000C0400000000000000000000000404C0825
-:103710000000045600000000C02008000000000067
-:103720000000001040210E200000000000000011E9
-:10373000402112200000000000000012402116204D
-:10374000000000000000216900204411000000007A
-:1037500000000000002048020000000000000000FF
-:1037600000210225000000000000000014E000001D
-:10377000000004A000040000C0494A20000004A189
-:10378000FFFBFFFFC0284A200000000000000000EF
-:1037900000210223000000000000000014E00000EF
-:1037A000000004AD00000000C02048000000000040
-:1037B00000000000C02048000000000000000000E1
-:1037C00000210224000000000000000014C00000DE
-:1037D00000000000810000000020441100000000F3
-:1037E0000000000C00204811000000000000000054
-:1037F00000200010000000000000000014C00000C5
-:10380000000004A9A00000000020441100000000F6
-:10381000CAFEBABE0040481100000000810000004E
-:1038200000204411000000000000000400204811A6
-:10383000000000000000216B002044110000000087
-:1038400000000000C02048100000000081000000BF
-:103850000020441100000000000000050020481175
-:10386000000000000000216C002044110000000056
-:1038700000000000C0204810000000000000000010
-:10388000002F022400000000000000000CE00000F7
-:10389000000000000000000000400000000004A73D
-:1038A00000000000C0210A2000000000000000000D
-:1038B00014C00000000004C081000000002044117A
-:1038C000000000000000000000204811000000007F
-:1038D0000000216D002044110000000000000000E5
-:1038E000C02048000000000000000000C060480048
-:1038F0000000068F0000000000400000000004C42B
-:1039000081000000002044110000000000000001C0
-:10391000002048110000000000040000C0294620DB
-:103920000000000000000000C06000000000068AE7
-:103930000000000100210222000000000000000041
-:1039400014C00000000004CB0000216900204411D5
-:103950000000000000000000C0204800000000003F
-:1039600000000000C020480000000000000000002F
-:103970000020481000000000CAFEBABE00404811F6
-:103980000000000000000000C02044000000000013
-:1039900000000000C040481000000000810000004E
-:1039A0000020441100000000000000010020481128
-:1039B00000000000000021F8002044110000000079
-:1039C0000000000E0020481100000000000421F952
-:1039D000006044110000068A00000000002102304F
-:1039E000000000000000000014C00000000004CD32
-:1039F00000002180002044110000000000000000B1
-:103A0000C02048000000000000000000C0200000AE
-:103A10000000000000000000C0204800000000007E
-:103A200000000000C02000000000000000000000B6
-:103A3000C0404800000000000000000300333E2F9B
-:103A40000000000000000001002102210000000031
-:103A50000000000014E00000000004FD0000002C45
-:103A600000200A2D000000000004000018E00C11E6
-:103A7000000004EC0000000100333E2F00000000B5
-:103A80000000216900204411000000000000000037
-:103A90000020480200000000000000000020480351
-:103AA000000000000000000800300A2200000000B2
-:103AB00000000000C02048000000000000000000DE
-:103AC000C0204800000000000000216900204411CF
-:103AD000000000000000000000204802000000007C
-:103AE0000000000000204803000000000000000863
-:103AF00000300A220000000000000000C020480042
-:103B00000000000000000000D8C04800000004E0F1
-:103B100000002169002044110000000000000000A6
-:103B200000204802000000000000000000204803C0
-:103B3000000000000000000800300A220000000021
-:103B400000000000C020480000000000000000004D
-:103B5000C0204800000000000000002D0020122DB1
-:103B6000000000000000000000290C83000000009D
-:103B70000000216900204411000000000000000046
-:103B80000020480200000000000000000020480360
-:103B9000000000000000000800300A2200000000C1
-:103BA00000000000C02048000000000000000000ED
-:103BB000C020480000000000000000110021022485
-:103BC000000000000000000014C000000000000021
-:103BD0000000000000400000000004A70000002CCE
-:103BE000C0203620000000000000002DC04036201C
-:103BF000000000000000000F002102210000000072
-:103C00000000000014C000000000050200000000D9
-:103C1000006000000000000B00000000D900000060
-:103C20000000000000000000C0400400000000018F
-:103C3000B50000000020441100000000000020003A
-:103C40000020481100000000B600000000204411D0
-:103C5000000000000000A00000204811000000004B
-:103C6000B700000000204411000000000000C00068
-:103C70000020481100000000B8000000002044119E
-:103C8000000000000000F8E00020481100000000E3
-:103C9000B900000000204411000000000000F8807E
-:103CA0000020481100000000BA000000002044116C
-:103CB000000000000000E0000020481100000000AB
-:103CC000BB00000000204411000000000000F000D4
-:103CD0000020481100000000BC000000002044113A
-:103CE000000000000000F3FC00204811000000006C
-:103CF00081000000002044110000000000000002CC
-:103D00000020481100000000000000FF00280E30D5
-:103D10000000000000000000002F0223000000004F
-:103D2000000000000CC000000000051600000000AC
-:103D3000C0200800000000000000000014C00000C7
-:103D40000000052B0000000000200C110000000006
-:103D50000000001C00203623000000000000002BA3
-:103D60000020362300000000000000290020362338
-:103D700000000000000000280020362300000000A2
-:103D8000000000170020362300000000000000257E
-:103D9000002036230000000000000026002036230B
-:103DA0000000000000000015002036230000000085
-:103DB000000000160020362300000000FFFFE00096
-:103DC00000200C110000000000000021002036231C
-:103DD0000000000000000022002036230000000048
-:103DE00000001FFF00200C11000000000000002355
-:103DF00000203623000000000000002400203623AD
-:103E000000000000F1FFFFFF00283A2E0000000034
-:103E10000000001AC0220E20000000000000000078
-:103E20000029386E000000008100000000204411CD
-:103E30000000000000000006002048110000000003
-:103E40000000002A4020362000000000870000000B
-:103E5000002044110000000000000000C0204800C5
-:103E6000000000000000A1F4002044110000000048
-:103E700000000000002048100000000000000000CA
-:103E800000200C110000000000000030002036234C
-:103E9000000000009D000000002044110000000010
-:103EA0000000001F40214A20000000009600000092
-:103EB000002044110000000000000000C020480065
-:103EC0000000000000000000C0200C000000000006
-:103ED00000000000C0201000000000000000001FD3
-:103EE00000211624000000000000000014C00000A3
-:103EF000000000000000001D00203623000000002C
-:103F00000000000300281E2300000000000000083D
-:103F10000022222300000000FFFFF00000282228DA
-:103F20000000000000000000002920E80000000060
-:103F30000000001F002036280000000000000018CC
-:103F400000211E2300000000000000200020362772
-:103F50000000000000000002002216240000000003
-:103F600000000000003014A8000000000000001E47
-:103F700000203625000000000000000300211A2464
-:103F8000000000001000000000281A2600000000B9
-:103F9000EFFFFFFF00283A2E0000000000000000A5
-:103FA000004938CE000006780000000140280A20B1
-:103FB000000000000000000640280E200000000065
-:103FC00000000300C02812200000000000000008CC
-:103FD000002112240000000000000000C020162074
-:103FE0000000000000000000C0201A2000000000B7
-:103FF000000000000021022200000000000000007C
-:1040000014C000000000056381000000002044117E
-:104010000000000000000001002048110000000026
-:104020000000225800300A240000000000040000B4
-:10403000006946220000068A000021690020441120
-:104040000000000000000000002048050000000003
-:104050000002000000294A260000000000000000C5
-:104060000020481000000000CAFEBABE002048111F
-:104070000000000000000002002F022300000000EA
-:10408000000000000CC000000000056B00000000F4
-:10409000C0201C100000000000000000C040000014
-:1040A0000000057900000002002F0223000000003C
-:1040B000000000000CC000000000056B8100000043
-:1040C0000020441100000000000000010020481101
-:1040D000000000000000225800300A240000000008
-:1040E00000040000006946220000068A000000006B
-:1040F000C0201C100000000000000000C0400000B4
-:104100000000057900000000002F022300000000DD
-:10411000000000000CC000000000056F000000005F
-:10412000C0201C000000000000000000C040000093
-:104130000000057900000004002F022300000000A9
-:10414000000000000CC000000000057781000000A6
-:104150000020441100000000000000000020481171
-:10416000000000000000216D00204411000000004C
-:1041700000000000C0204800000000000000000017
-:10418000C06048000000068F0000000000401C10C6
-:104190000000057900000000C020000000000000C1
-:1041A00000000000C040000000000000000000000F
-:1041B0000EE000000000057B000000000060000031
-:1041C000000005C600000000002F022400000000CF
-:1041D000000000000CC000000000058C0000A2B729
-:1041E00000204411000000000000000000204807EB
-:1041F00000000000810000000020441100000000C9
-:104200000000000100204811000000000004A2B6D8
-:10421000006044110000068A0000001A00212230CC
-:104220000000000000000006002226300000000010
-:1042300000042004006044110000068A0000A2C4AB
-:10424000002044110000000000000000003048E998
-:10425000000000000000000000E000000000058AEF
-:104260000000A2D100204411000000000000000066
-:1042700000404808000000000000A2D100204411C6
-:10428000000000000000000100504A28000000006B
-:1042900000000001002F02240000000000000000C8
-:1042A0000CC000000000059D0000A2BB00204411CE
-:1042B000000000000000000000204807000000008F
-:1042C00081000000002044110000000000000001F7
-:1042D00000204811000000000004A2BA0060441150
-:1042E0000000068A0000001A0021223000000000B1
-:1042F0000000000600222630000000000004200418
-:10430000006044110000068A0000A2C5002044118C
-:104310000000000000000000003048E9000000003C
-:104320000000000000E000000000059B0000A2D299
-:104330000020441100000000000000000040480878
-:10434000000000000000A2D2002044110000000084
-:104350000000000100504A28000000000000000298
-:10436000002F022400000000000000000CC000002C
-:10437000000005AE0000A2BF0020441100000000B4
-:10438000000000000020480700000000810000003D
-:10439000002044110000000000000001002048112E
-:1043A000000000000004A2BE006044110000068A64
-:1043B0000000001A0021223000000000000000066A
-:1043C0000022263000000000000420040060441198
-:1043D0000000068A0000A2C6002044110000000070
-:1043E00000000000003048E900000000000000006C
-:1043F00000E00000000005AC0000A2D30020441142
-:10440000000000000000000000404808000000001C
-:104410000000A2D3002044110000000000000001B1
-:1044200000504A28000000000000A2C300204411F0
-:10443000000000000000000000204807000000000D
-:104440008100000000204411000000000000000175
-:1044500000204811000000000004A2C200604411C6
-:104460000000068A0000001A00212230000000002F
-:104470000000000600222630000000000004200496
-:10448000006044110000068A0000A2C70020441109
-:104490000000000000000000003048E900000000BB
-:1044A0000000000000E00000000005BB0000A2D4F6
-:1044B00000204411000000000000000000404808F7
-:1044C000000000000000A2D4002044110000000001
-:1044D0000000000100504A28000000008500000094
-:1044E00000204411000000000000000000204801EE
-:1044F000000000000000304A0020441100000000CD
-:104500000100000000204811000000000000000031
-:1045100000400000000005C1A4000000C0204411BC
-:104520000000000000000000C04048000000000043
-:1045300000000000C0600000000005C60000000090
-:10454000C0400400000000010000002C00203621C3
-:104550000000000081000000002044110000000065
-:1045600000000006002048110000000000000000CC
-:10457000002F023000000000000000000CC000000E
-:10458000000005CD00000000002004110000000024
-:104590000000003000403621000005E0000000303F
-:1045A0000020062D0000000000007E0000280621EB
-:1045B0000000000000000000002F022100000000A9
-:1045C000000000000CE00000000005E08100000099
-:1045D00000204411000000000000000100204811EC
-:1045E000000000000004A092006044110000068A50
-:1045F0000000003100203630000000000004A093CD
-:10460000006044110000068A0000003200203630AD
-:10461000000000000004A2B6006044110000068AF9
-:104620000000003300203630000000000004A2BA71
-:10463000006044110000068A00000034002036307B
-:10464000000000000004A2BE006044110000068AC1
-:104650000000003500203630000000000004A2C237
-:10466000006044110000068A000000360020363049
-:104670000000000000042004006044110000068ACD
-:104680000001A2A400204411000000000000003F2F
-:1046900000204811000000000000003F00204811E9
-:1046A000000000000000003F002048110000000052
-:1046B0000000003F0020481100000000000000053D
-:1046C00000204811000000000000A1F40020441167
-:1046D0000000000000000000002048110000000061
-:1046E00088000000002044110000000000000001CC
-:1046F000002048110000000081000000002044114B
-:10470000000000000000000600204811000000002A
-:1047100000000001002F0230000000000000000037
-:104720000CE0000000000629000000300020062DEB
-:104730000000000000000000002F02210000000027
-:10474000000000000CE000000000062981000000CD
-:10475000002044110000000000000001002048116A
-:104760000000000000007E0000280621000000007C
-:1047700000000000002F02210000000000000000E7
-:104780000CE00000000006020000A092002044118E
-:10479000000000000000003100204A2D0000000051
-:1047A0000000A0930020441100000000000000322F
-:1047B00000204A2D000000000000A2B60020441195
-:1047C000000000000000003300204A2D000000001F
-:1047D0000000A2BA002044110000000000000034D4
-:1047E00000204A2D000000000000A2BE002044115D
-:1047F000000000000000003500204A2D00000000ED
-:104800000000A2C200204411000000000000003699
-:1048100000204A2D00000000000000300020062D7E
-:1048200000000000000001FF002806210000000039
-:1048300000000000002F0221000000000000000026
-:104840000CE000000000062800000000002102210A
-:10485000000000000000000014C000000000060B73
-:104860000004A003006044110000068A0000A003B9
-:10487000002044110000000000000000002048104B
-:1048800000000000000000010021062100000000DF
-:104890000000000014C00000000006100004A0107A
-:1048A000006044110000068A0000A010002044119E
-:1048B0000000000000000000002048100000000080
-:1048C000000000010021062100000000000000009F
-:1048D000002F022100000000000000000CE000009A
-:1048E000000006280004A011006044110000068AA0
-:1048F0000000A01100204411000000000000000092
-:1049000000204810000000000004A01200604411C4
-:104910000000068A0000A0120020441100000000E0
-:104920000000000000204810000000000004A01358
-:10493000006044110000068A0000A013002044110A
-:1049400000000000000000000020481000000000EF
-:104950000004A014006044110000068A0000A014A6
-:10496000002044110000000000000000002048105A
-:10497000000000000004A015006044110000068A39
-:104980000000A015002044110000000000000000FD
-:1049900000204810000000000004A0160060441130
-:1049A0000000068A0000A01600204411000000004C
-:1049B0000000000000204810000000000004A017C4
-:1049C000006044110000068A0000A0170020441176
-:1049D000000000000000000000204810000000005F
-:1049E00000042004006044110000068A0000002C2E
-:1049F0000080062D00000000FF0000000020441190
-:104A0000000000000000000000204811000000002D
-:104A1000000000010020481100000000000000021A
-:104A20000080481100000000000000000EE00000BF
-:104A30000000063A000000300020062D00000000B3
-:104A40000000000200280621000000000000000015
-:104A5000002F022100000000000000000CE0000018
-:104A60000000063881000000002044110000000012
-:104A70000000000100204811000000000004200494
-:104A8000006044110000068A000010000020081198
-:104A9000000000000000002B002036220000000073
-:104AA00000000000006000000000063E0000000062
-:104AB00000600000000005C69800000000204411BE
-:104AC000000000000000000000804811000000000D
-:104AD00000000000C06000000000063E0000000072
-:104AE000C0400400000000010000A2A40020441106
-:104AF000000000000000002200204811000000001B
-:104B000089000000002044110000000000000001A6
-:104B1000004048110000062A9700000000204411C0
-:104B2000000000000000000000204811000000000C
-:104B30008A00000000204411000000000000000076
-:104B4000004048110000062A00000000006000003C
-:104B50000000065900002010002044110000000051
-:104B60000000800000204811000000000001A2A405
-:104B7000C020441100000000000000160060481131
-:104B80000000036E0000201000204411000000000F
-:104B9000000100000020481100000000810000001A
-:104BA0000020441100000000000000010020481116
-:104BB000000000000000217C0020441100000000E3
-:104BC000098000000020481100000000FFFFFFFFE7
-:104BD00000204811000000000000000000204811E3
-:104BE00000000000000000001700000000000000AE
-:104BF0000004217F006044110000068A0000001FAD
-:104C000000210230000000000000000014C000007D
-:104C1000000000000000000400404C11000006539A
-:104C2000000000000040000000000000000000172D
-:104C300000201E2D000000000000000400291E2797
-:104C40000000000000000017008036270000000070
-:104C50000000001700201E2D00000000FFFFFFFBDA
-:104C600000281E27000000000000001700803627E3
-:104C7000000000000000001700201E2D00000000B2
-:104C80000000000800291E27000000000000001797
-:104C900000803627000000000000001700201E2DB5
-:104CA00000000000FFFFFFF700281E2700000000A3
-:104CB00000000017008036270000000000002010D0
-:104CC0000020441100000000000080000020481176
-:104CD000000000000001A2A4002044110000000018
-:104CE00000000016006048110000036E0000201054
-:104CF00000204411000000000001000000204811C5
-:104D0000000000000000217C002044110000000091
-:104D1000018000000020481100000000FFFFFFFF9D
-:104D20000020481100000000000000000020481191
-:104D3000000000000000000017000000000000005C
-:104D4000810000000020441100000000000000016C
-:104D500000204811000000000004217F0060441181
-:104D60000000068A0000001F002102300000000041
-:104D70000000000014C000000000068900000010C0
-:104D800000404C110000066F00000000C02004002D
-:104D9000000000000000000038C00000000000001B
-:104DA0000000001D00200A2D000000000000001E71
-:104DB00000200E2D000000000000001F0020122D1A
-:104DC00000000000000000200020162D0000000060
-:104DD00000002169002044110000000000000000D4
-:104DE00000204804000000000000000000204805EA
-:104DF000000000000000000000204801000000004A
-:104E0000CAFEBABE002048110000000000000004E5
-:104E1000003012240000000000000000002F006499
-:104E200000000000000000000CC000000000068828
-:104E30000000000300281A22000000000000000803
-:104E40000022122200000000FFFFF00000281224C0
-:104E50000000000000000000002910C40000000055
-:104E60000000001F00403624000000000000000089
-:104E70000080000000000000000000001AC00000D8
-:104E80000000068A9F00000000204411000000007E
-:104E9000CAFEBABE00204811000000000000000059
-:104EA0001AE000000000068D0000000000800000F5
-:104EB00000000000000000001AC000000000068F83
-:104EC0009E0000000020441100000000CAFEBABE8F
-:104ED0000020481100000000000000001AE000005F
-:104EE00000000692000000000080000000000000AA
-:104EF00000000000006000000000000B0000100037
-:104F000000600411000003150000000000200411DF
-:104F1000000000000000000000600811000001B265
-:104F20000000225C0020441100000000000000038B
-:104F3000002048110000000000002256002044110B
-:104F4000000000000000001B0020481100000000CD
-:104F50000000A1FC0020441100000000000000013E
-:104F600000204811000000000001A1FDC0204411F4
-:104F7000000000000000002100201E2D00000000A5
-:104F80000000001000221E27000000000000002486
-:104F90000020222D000000000000FFFF0028222832
-:104FA0000000000000000000002949070000000088
-:104FB0000000000000204811000000000000002256
-:104FC0000020222D000000000000FFFF0028222802
-:104FD0000000000000000000002949070000000058
-:104FE0000000000000204811000000000000002325
-:104FF00000201E2D000000000000001000221E27CF
-:105000000000000000000000002949070000000027
-:1050100000000000004048110000000000000000F7
-:105020000000000000000000000000000000000080
-:105030000000000000000000000000000000000070
-:105040000000000000000000000000000000000060
-:105050000000000000000000000000000000000050
-:105060000000000000000000000000000000000040
-:105070000000000000000000000000000000000030
-:105080000000000000000000000000000000000020
-:105090000000000000000000000000000000000010
-:1050A0000000000000000000000000000000000000
-:1050B00000000000000000000000000000000000F0
-:1050C00000000000000000000000000000000000E0
-:1050D00000000000000000000000000000000000D0
-:1050E00000000000000000000000000000000000C0
-:1050F00000000000000000000000000000000000B0
-:10510000000000000000000000000000000000009F
-:10511000000000000000000000000000000000008F
-:10512000000000000000000000000000000000007F
-:10513000000000000000000000000000000000006F
-:10514000000000000000000000000000000000005F
-:10515000000000000000000000000000000000004F
-:10516000000000000000000000000000000000003F
-:10517000000000000000000000000000000000002F
-:10518000000000000000000000000000000000001F
-:10519000000000000000000000000000000000000F
-:1051A00000000000000000000000000000000000FF
-:1051B00000000000000000000000000000000000EF
-:1051C00000000000000000000000000000000000DF
-:1051D00000000000000000000000000000000000CF
-:1051E00000000000000000000000000000000000BF
-:1051F00000000000000000000000000000000000AF
-:10520000000000000000000000000000000000009E
-:10521000000000000000000000000000000000008E
-:10522000000000000000000000000000000000007E
-:10523000000000000000000000000000000000006E
-:10524000000000000000000000000000000000005E
-:10525000000000000000000000000000000000004E
-:10526000000000000000000000000000000000003E
-:10527000000000000000000000000000000000002E
-:10528000000000000000000000000000000000001E
-:10529000000000000000000000000000000000000E
-:1052A00000000000000000000000000000000000FE
-:1052B000014204FF05BD02500000000001C3016867
-:1052C000043F05BD00000000022502090250015103
-:1052D000000000000223024502A00241000000007D
-:1052E00003D705BD05BD05BD000000000646064705
-:1052F000031F05BD0000000005BD05C203200340DB
-:1053000000000000032A0282034203340000000070
-:1053100005BD05BD05BD05BD0000000005BD054E70
-:1053200005BD05BD0000000003BA05BD04B8034477
-:10533000000000000497044D043D05BD000000007E
-:1053400004CD05BD044104DA00000000044D05044D
-:10535000035103750000000005BD05BD05BD05BD79
-:105360000000000005BD05BD05BD05BD0000000035
-:1053700005BD05BD063C05C40000000005BD05BD1A
-:10538000000705BD0000000005BD05BD05BD05BD4C
-:105390000000000005BD05BD05BD05BD0000000005
-:1053A00003F803ED0408040600000000040E040ADC
-:1053B000040C041000000000041C04180424042041
-:1053C00000000000042C0428043404300000000015
-:1053D00005BD05BD043805BD0000000005BD05BDC7
-:1053E00005BD05BD0000000005BD05BD05BD05BD31
-:1053F000000000000002067606940006000000008F
-:00000001FF
--- zfcpdump-kernel-4.4.orig/firmware/radeon/RV630_pfp.bin.ihex
+++ /dev/null
@@ -1,145 +0,0 @@
-:1000000000CA040000A00000007E828B007C038BED
-:10001000008001B8007C038B00D4401E00EE001E5F
-:1000200000CA040000A00000007E828B00C41838C3
-:1000300000CA240000CA2800009581A800C41C3A08
-:1000400000C3C00000CA080000CA0C00007C744B4A
-:1000500000C200050099C00000C41C3A007C744C2A
-:1000600000C0FFF000042C0400309002007D250049
-:1000700000351402007D350B00255403007CD5802B
-:1000800000259C030095C00400D5001B007EDDC147
-:10009000007D9D8000D6801B00D5801B00D4401EB3
-:1000A00000D5401E00D6401E00D6801E00D4801E03
-:1000B00000D4C01E009783D300D5C01E00CA08001C
-:1000C0000080001A00CA0C0000E4011E00D4001ECB
-:1000D0000080000C00C4183800E4013E00D4001E6B
-:1000E0000080000C00C4183800D4401E00EE001E32
-:1000F00000CA040000A00000007E828B00E4011E04
-:1001000000D4001E00D4401E00EE001E00CA0400F1
-:1001100000A00000007E828B00E4013E00D4001E9F
-:1001200000D4401E00EE001E00CA040000A0000023
-:10013000007E828B00CA180000D4401E00D5801EAD
-:100140000080005300D4007500D4401E00CA08008F
-:1001500000CA0C0000CA100000D4801900D4C018D6
-:1001600000D5001700D4801E00D4C01E00D5001E8C
-:1001700000E2001E00CA040000A00000007E828B86
-:1001800000CA080000D4806000D4401E0080000037
-:1001900000D4801E00CA080000D4806100D4401E34
-:1001A0000080000000D4801E00CA080000CA0C00B5
-:1001B00000D4401E00D4801600D4C01600D4801E87
-:1001C000008001B800D4C01E00C6084300CA0C005D
-:1001D00000CA10000094800400CA140000E420F358
-:1001E00000D4201300D5606500D4E01C00D5201C8D
-:1001F00000D5601C008000000006200100C60843F6
-:1002000000CA0C0000CA1000009483F700CA140052
-:1002100000E420F30080007900D4201300C60843D6
-:1002200000CA0C0000CA1000009883EF00CA140036
-:1002300000D400640080008D0000000000C414326F
-:1002400000C6184300C4082F0095400500C40C30B8
-:1002500000D4401E0080000000EE001E009583F5D3
-:1002600000C4103100D4403300D5206500D4A01C58
-:1002700000D4E01C00D5201C00E4015E00D4001E68
-:10028000008000000006200100CA1800000A2001BA
-:1002900000D6007600C408360098800700C61045D6
-:1002A0000095011000D4001F00D46062008000009F
-:1002B00000D4206200CC383500CC1433008401BB5C
-:1002C00000D4007200D5401E0080000000EE001E29
-:1002D00000E2001A008401BB00E2001A00CC104BBF
-:1002E00000CC0447002C9401007D098B0098400548
-:1002F000007D15CB00D4001A008001B800D4006D39
-:100300000034440100CC0C480098403A00CC2C4A00
-:100310000095800400CC0449008001B800D4001A84
-:1003200000D4C01A00282801008400F000CC10037B
-:100330000098801B0004380C008400F000CC1003EF
-:100340000098801700043808008400F000CC1003E7
-:100350000098801300043804008400F000CC1003DF
-:100360000098801400CC104C009A800900CC144DE9
-:10037000009840DC00D4006D00CC184800D5001A6D
-:1003800000D5401A008000C900D5801A0096C0D55B
-:1003900000D4006D008001B800D4006E009AC00344
-:1003A00000D4006D00D4006E0080000000EC007FDF
-:1003B000009AC0CC00D4006D008001B800D4006E5B
-:1003C00000CC140300CC180300CC1C03007D910367
-:1003D000007DD583007D190C0035CC1F0035701FC2
-:1003E000007CF0CB007CD08B00880000007E8E8BE0
-:1003F0000095C00400D4006E008001B800D4001A3B
-:1004000000D4C01A00CC080300CC0C0300CC1003AD
-:1004100000CC140300CC180300CC1C0300CC240334
-:1004200000CC28030035C41F0036B01F007C704B81
-:100430000034F01F007C704B0035701F007C704B47
-:10044000007D8881007DCCC1007E5101007E9541F8
-:10045000007C9082007CD4C2007C848B009AC00314
-:10046000007C8C8B002C88010098809E00D4006D4D
-:100470000098409C00D4006E00CC084C00CC0C4D81
-:1004800000CC104800D4801A00D4C01A00800101AA
-:1004900000D5001A00CC083200D40032009482D972
-:1004A00000CA0C0000D4401E0080000000D4001ED2
-:1004B00000E4011E00D4001E00CA080000CA0C009F
-:1004C00000CA100000D4401E00CA140000D4801ED0
-:1004D00000D4C01E00D5001E00D5401E00D54034FB
-:1004E0000080000000EE001E0028040400E2001A54
-:1004F00000E2001A00D4401A00CA380000CC0803F9
-:1005000000CC0C0300CC0C0300CC0C03009882BD83
-:1005100000000000008401BB00D7A06F0080000035
-:1005200000EE001F00CA040000C2FF0000CC083427
-:1005300000C13FFF007C74CB007CC90B007D010F24
-:10054000009902B0007C738B008401BB00D7A06FC0
-:100550000080000000EE001F00CA080000281900FB
-:10056000007D898B009580140028140400CA0C00BB
-:1005700000CA100000CA1C0000CA240000E2001FCC
-:1005800000D4C01A00D5001A00D5401A00CC1803B8
-:1005900000CC2C0300CC2C0300CC2C03007DA58BBD
-:1005A000007D9C4700984297000000000080016198
-:1005B00000D4C01A00D4401E00D4801E0080000069
-:1005C00000EE001E00E4011E00D4001E00D4401EF8
-:1005D00000EE001E00CA040000A00000007E828B16
-:1005E00000E4013E00D4001E00D4401E00EE001EB8
-:1005F00000CA040000A00000007E828B00CA080030
-:1006000000248C06000CCC060098C00600CC104ECE
-:100610000099000400D4007300E4011E00D4001E01
-:1006200000D4401E00D4801E0080000000EE001E9A
-:1006300000CA080000CA0C000034D01800251001C0
-:100640000095002100C17FFF00CA100000CA1400FD
-:1006500000CA180000D4801D00D4C01D007DB18BDD
-:1006600000C1420200C2C00100D5801D0034DC0E72
-:10067000007D5D4C007F734C00D7401E00D5001EEE
-:1006800000D5401E00C1420000C2C00000099C010C
-:100690000031DC10007F5F4C007F734C00042802A7
-:1006A000007D838000D5A86F00D5806600D7401EEE
-:1006B00000EC005E00C8240200C82402008001B8DB
-:1006C00000D6007600D4401E00D4801E00D4C01E88
-:1006D0000080000000EE001E0080000000EE001F01
-:1006E00000D4001F0080000000D4001F00D4001FB1
-:1006F0000088000000D4001F00000000000000007F
-:1007000000000000000000000000000000000000E9
-:1007100000000000000000000000000000000000D9
-:1007200000000000000000000000000000000000C9
-:1007300000000000000000000000000000000000B9
-:1007400000000000000000000000000000000000A9
-:100750000000000000000000000000000000000099
-:100760000000000000000000000000000000000089
-:100770000000000000000000000000000000000079
-:100780000000000000000000000000000000000069
-:100790000000000000000000000000000000000059
-:1007A0000000000000000000000000000000000049
-:1007B0000000000000000000000000000000000039
-:1007C0000000000000000000000000000000000029
-:1007D0000000000000000000000000000000000019
-:1007E0000000000000000000000000000000000009
-:1007F00000000000000000000000000000000000F9
-:1008000000010171000201780003008F0004007FE5
-:10081000000500030006003F000700320008012C1D
-:1008200000090046000A0036001001B6001700A2B9
-:100830000022013A00230149002000B400240125D0
-:100840000027004D0028006A002A0060002B00529B
-:10085000002F0065003200870034017F003C015604
-:10086000003F00720041018C0044012E00550173CD
-:100870000056017A0060000B00610034006200380D
-:1008800000630038006400380065003800660038F6
-:10089000006700380068003A00690041006A0048BB
-:1008A000006B0048006C0048006D0048006E004876
-:1008B000006F00480000000600000006000000066F
-:1008C0000000000600000006000000060000000610
-:1008D0000000000600000006000000060000000600
-:1008E00000000006000000060000000600000006F0
-:1008F00000000006000000060000000600000006E0
-:00000001FF
--- zfcpdump-kernel-4.4.orig/firmware/radeon/RV635_me.bin.ihex
+++ /dev/null
@@ -1,1345 +0,0 @@
-:1000000000000000C020040000000000000000000C
-:1000100000A0000A000000000000FFFF00284621A9
-:100020000000000000000000D900480000000000AF
-:1000300000000000C02004000000000000000000DC
-:1000400000A0000A000000000000000000E0000026
-:100050000000000000010000C02946200000000050
-:1000600000000000D900480000000000000000006F
-:10007000C0200400000000000000000000A0000AF2
-:10008000000000008100000000204411000000007A
-:1000900000000001002048110000000000042004BE
-:1000A000006044110000068A0000000000600000AB
-:1000B0000000062E00000000006000000000064264
-:1000C00000000000C02008000000000000000F0039
-:1000D000002816220000000000000008002116255C
-:1000E000000000000000001800203625000000007D
-:1000F0008D000000002044110000000000000004FA
-:10010000002F022500000000000000000CE00000AD
-:1001100000000018004120000040481100000019B4
-:100120000042200000204811000000008E00000066
-:1001300000204411000000000000002800204A2D8B
-:1001400000000000900000000020441100000000AA
-:100150000000000000204805000000000000000C26
-:1001600000211622000000000000000300281625D0
-:10017000000000000000001900211A220000000009
-:100180000000000400281A26000000000000000003
-:10019000002914C5000000000000001900203625C9
-:1001A0000000000000000000003A140200000000FF
-:1001B00000000016002116250000000000000003CA
-:1001C00000281625000000000000001700200E2D5A
-:1001D00000000000FFFFFFFC00280E2300000000CD
-:1001E00000000000002914A3000000000000001718
-:1001F00000203625000000000000800000280E22AC
-:10020000000000000000000700220E230000000094
-:10021000000000000029386E0000000020000000EF
-:1002200000280E22000000000000000600210E231E
-:1002300000000000000000000029386E00000000EF
-:100240000000000000220222000000000000000068
-:1002500014E0000000000038000000002EE0000064
-:1002600000000035000000002CE000000000003716
-:100270000000000000400E2D0000003900000008C2
-:1002800000200E2D00000000000000090040122D8B
-:10029000000000460000000100400E2D0000003963
-:1002A00000000000C0200C0000000000003FFFFC28
-:1002B0000028122300000000000000020022122487
-:1002C000000000000000001F00211E2300000000AD
-:1002D0000000000014E000000000003E00000008E4
-:1002E00000401C11000000410000000D00201E2DE8
-:1002F000000000000000000F00281E270000000082
-:100300000000000300221E27000000007FC0000044
-:1003100000281A23000000000000001400211A2603
-:10032000000000000000000100331A260000000059
-:100330000000000800221A26000000000000000053
-:1003400000290CC700000000000000270020362410
-:100350000000000000007F000028122100000000C3
-:1003600000001400002F0224000000000000000024
-:100370000CE000000000004B0000000100290E23EB
-:10038000000000000000000E0020362300000000E6
-:100390000000E0000020441100000000FFF8000011
-:1003A00000294A230000000000000000003A2C024F
-:1003B000000000000000000200220E2B00000000E0
-:1003C000FC00000000280E23000000000000000FC9
-:1003D000002036230000000000001FFF00294A23F0
-:1003E000000000000000002700204A2D000000004F
-:1003F000000000000020481100000000000000295B
-:1004000000200E2D00000000060A020000294A23E9
-:100410000000000000000000002048110000000063
-:100420000000000000204811000000000000000152
-:1004300000210222000000000000000014E0000083
-:1004400000000061000000002EE000000000005FDE
-:10045000000000002CE000000000005E0000000032
-:1004600000400E2D000000620000000100400E2D33
-:10047000000000620000000A00200E2D00000000B5
-:100480000000000B0040122D0000006A0000000078
-:10049000C0200C0000000000003FFFFC00281223D9
-:1004A00000000000000000020022122400000000F2
-:1004B0007FC0000000281623000000000000001488
-:1004C0000021162500000000000000010033162561
-:1004D000000000008000000000280E230000000043
-:1004E0000000000000290CA3000000003FFFFC00FA
-:1004F00000290E23000000000000001F00211E2321
-:10050000000000000000000014E000000000006D8A
-:100510000000010000401C11000000700000000DF0
-:1005200000201E2D00000000000000F000281E2703
-:10053000000000000000000400221E270000000050
-:100540008100000000204411000000000000000DA8
-:100550000020481100000000FFFFF0FF00281A30C3
-:10056000000000000000A02800204411000000004E
-:1005700000000000002948E6000000000000A0186C
-:1005800000204411000000003FFFFFFF00284A2325
-:10059000000000000000A010002044110000000036
-:1005A00000000000002048040000000000000030AF
-:1005B0000020162D00000000000000020029162572
-:1005C0000000000000000030002036250000000080
-:1005D000000000250020162D000000000000000093
-:1005E000002F00A300000000000000000CC000006D
-:1005F00000000083000000260020162D00000000EF
-:1006000000000000002F00A4000000000000000017
-:100610000CC000000000008400000000004000004A
-:100620000000008A000000250020362300000000A2
-:100630000000002600203624000000000000001703
-:1006400000201E2D000000000000000200210227F3
-:10065000000000000000000014E000000000008A1C
-:1006600000000000006000000000066500000000BF
-:1006700000600000000006590000000200210E2268
-:10068000000000000000000014C000000000008D09
-:1006900000000012C040362000000093000000005F
-:1006A0002EE0000000000091000000002CE000009F
-:1006B000000000900000000200400E2D000000929B
-:1006C0000000000300400E2D000000920000000C0E
-:1006D00000200E2D00000000000000120020362334
-:1006E000000000000000000300210E2200000000B6
-:1006F0000000000014C00000000000980000A00CE2
-:10070000002044110000000000000000C02048004C
-:100710000000000000000000C0404800000000A0F1
-:100720000000A00C002044110000000000000000A8
-:100730000020481100000000000000002EE0000032
-:100740000000009E000000002CE000000000009D62
-:100750000000000200400E2D0000009F000000037A
-:1007600000400E2D0000009F0000000C00200E2D08
-:10077000000000000000000000204803000000000E
-:1007800000000000003A0C0200000000003F0000E2
-:1007900000280E23000000000000001000210E239E
-:1007A00000000000000000110020362300000000BF
-:1007B0000000001E0021022B0000000000000000CD
-:1007C00014C00000000000A700000016C020362062
-:1007D000000000000000001F0021022B00000000AC
-:1007E0000000000014C00000000000AA0000001576
-:1007F000C0203620000000000000000800210E2B61
-:10080000000000000000007F00280E230000000010
-:1008100000000000002F0223000000000000000084
-:100820000CE00000000000E10000000027000000D4
-:10083000000000000000000000600000000002A3B3
-:1008400000000001002F0223000000000000000053
-:100850000AE00000000000B300000000006000009B
-:100860000000013A81000000002044110000000057
-:100870000000000600204811000000000000000CED
-:1008800000221E300000000099800000002044116A
-:1008900000000000000000040020122D00000000F5
-:1008A00000000008002212240000000000000010D8
-:1008B00000201811000000000000000000291CE4C6
-:1008C0000000000000000000006048070000012F49
-:1008D0009B00000000204411000000000000000008
-:1008E00000204802000000009C000000002044118D
-:1008F00000000000000000000033146F0000000042
-:100900000000000100333E23000000000000000052
-:10091000D9004800000000000000000000203C0555
-:1009200000000000810000000020441100000000D1
-:100930000000000E00204811000000000000000030
-:1009400000201010000000000000E007002044110B
-:10095000000000000000000F0021022B000000003A
-:100960000000000014C00000000000CB00F8FF08E9
-:1009700000204811000000009800000000404811CD
-:10098000000000DC000000F000280E220000000043
-:10099000000000A0002F0223000000000000000063
-:1009A0000CC00000000000DA0000001100200E2D35
-:1009B0000000000000000001002F022300000000E2
-:1009C000000000000CE00000000000D50000000264
-:1009D000002F022300000000000000000CE00000D7
-:1009E000000000D400003F0000400C11000000D6C1
-:1009F00000001F0000400C11000000D600000F0096
-:100A000000200C11000000000038000900294A23D2
-:100A1000000000003F00000000280E2B0000000036
-:100A20000000000200220E2300000000000000076A
-:100A300000494A23000000DC00380F09002048115B
-:100A400000000000680000070020481100000000BE
-:100A50000000000800214A270000000000000000FC
-:100A60000020481100000000060A020000294A2464
-:100A700000000000000000000020481100000000FD
-:100A80000000000000204811000000000000A20249
-:100A9000002044110000000000FF000000280E228A
-:100AA000000000000000008000294A230000000030
-:100AB0000000002700200E2D00000000000000268E
-:100AC0000020122D0000000000000000002F008315
-:100AD00000000000000000000CE00000000000EA40
-:100AE00000000000006000000000065F0000000041
-:100AF00000400000000000EB00000000006000006B
-:100B000000000662000000070020222D0000000007
-:100B10000000000500220E2200000000001000006E
-:100B200000280E23000000000000000000292068BB
-:100B30000000000000000000003A0C02000000006D
-:100B4000000000EF00280E2300000000000000005D
-:100B500000292068000000000000001700200E2D72
-:100B6000000000000000000300210223000000003C
-:100B70000000000014E00000000000F80000000B7E
-:100B800000210228000000000000000014C0000046
-:100B9000000000F8000004000029222800000000E6
-:100BA0000000001400203628000000000000001C97
-:100BB00000210E22000000000000000014C0000010
-:100BC000000000FD0000A30C002044110000000004
-:100BD0000000000000204811000000000000001E7E
-:100BE00000210E22000000000000000014C00000E0
-:100BF0000000010B0000A30F0020441100000000C2
-:100C00000000001100200E2D000000000000000177
-:100C1000002F022300000000000000000CC00000B4
-:100C200000000104FFFFFFFF004048110000010B1E
-:100C300000000002002F022300000000000000005E
-:100C40000CC00000000001070000FFFF0040481139
-:100C50000000010B00000004002F02230000000030
-:100C6000000000000CC000000000010A000000FFAE
-:100C7000004048110000010B000000010020481155
-:100C8000000000000002C400002044110000000029
-:100C90000000001F00210E220000000000000000E4
-:100CA00014C00000000001120000001040210E20BE
-:100CB00000000000000000130020362300000000A8
-:100CC0000000001840224A20000000000000001030
-:100CD000C0424A20000001140000000000200C1156
-:100CE0000000000000000013002036230000000078
-:100CF000000000000020481100000000000000007B
-:100D000000204811000000000000000A002010111F
-:100D10000000000000000000002F0224000000007E
-:100D2000000000000CE000000000011B00000000BB
-:100D300000204811000000000000000100531224B0
-:100D400000000117FFBFFFFF00283A2E000000003F
-:100D50000000001B00210222000000000000000033
-:100D600014C000000000012E81000000002044118A
-:100D7000000000000000000D0020481100000000ED
-:100D80000000001800220E3000000000FC000000EF
-:100D900000280E2300000000810000000020441104
-:100DA000000000000000000E0020481100000000BC
-:100DB0000000000000201010000000000000E00E05
-:100DC000002044110000000007F8FF08002048112F
-:100DD000000000000000000000294A23000000007D
-:100DE0000000001C00201E2D000000000000000874
-:100DF00000214A27000000000000000000204811E8
-:100E000000000000060A020000294A240000000039
-:100E10000000000000204811000000000000000059
-:100E200000204811000000000000000000800000C9
-:100E300000000000810000000020441100000000BC
-:100E40000000000100204811000000000000217C8B
-:100E50000020441100000000008000000020481124
-:100E60000000000000000000002048060000000014
-:100E70000000000800214A270000000000000000D8
-:100E800017000000000000000004217F00604411F2
-:100E90000000068A0000001F002102300000000050
-:100EA0000000000014C000000000068900000004DB
-:100EB00000404C1100000135810000000020441169
-:100EC00000000000000000010020481100000000A8
-:100ED000000021F800204411000000000000001C68
-:100EE0000020481100000000000421F900604411B6
-:100EF0000000068A000000110021023000000000FE
-:100F00000000000014E000000000013C00000000B0
-:100F100000800000000000000000000000600000F1
-:100F20000000000B00000000006004110000031529
-:100F3000000000000020041100000000000000007C
-:100F400000600811000001B2000000000060000015
-:100F5000000001600000FFFF40280E20000000009C
-:100F600000000010C0211220000000000000FFFF60
-:100F7000402806200000000000000010C0210A20C8
-:100F800000000000000000000034146100000000B8
-:100F90000000000000741882000002BB0001A1FDE7
-:100FA00000604411000002E000003FFF002F022F0C
-:100FB00000000000000000000CC00000000001471D
-:100FC00000000000C040040000000001000000001C
-:100FD000006000000000000B000000000060041131
-:100FE00000000315000000000020041100000000B4
-:100FF0000000000000600811000001B200003FFF87
-:10100000002F022F00000000000000000CE0000094
-:10101000000000000000000000600000000001600F
-:101020000000001040210E20000000000000FFFF23
-:10103000C0281220000000000000001040211620EF
-:10104000000000000000FFFFC0681A20000002BB83
-:101050000001A1FD00604411000002E000003FFF1C
-:10106000002F022F00000000000000000CC0000054
-:101070000000015800000000C04004000000000112
-:101080000000225C0020441100000000000000016C
-:1010900000300A2F000000000000000100210A2299
-:1010A000000000000000000300384A220000000099
-:1010B0000000225600204411000000000000001A29
-:1010C00000204811000000000000A1FC0020441195
-:1010D0000000000000000001008048110000000036
-:1010E00000000000006000000000000B0000000095
-:1010F000006000000000018F0000000000600000A0
-:10110000000001A000003FFF002F022F00000000A0
-:10111000000000000CE000000000000000000000E3
-:1011200000202C0800000000000000000020241116
-:101130000000000000000000002028110000000056
-:10114000000022560020441100000000000000169C
-:1011500000204811000000000000225C0020441123
-:101160000000000000000003002048110000000003
-:1011700093800000002044110000000000000002E5
-:1011800000221E290000000000000000007048EB53
-:101190000000019C0000000000600000000002BB95
-:1011A00000000001403306200000000000000000A5
-:1011B000C03024090000000000003FFF002F022F74
-:1011C00000000000000000000CE000000000000033
-:1011D0000000000000600000000002A3000000000A
-:1011E000002F022100000000000000000AE00000C3
-:1011F0000000018100000000006000000000013AD2
-:101200000000000000400000000001869500000082
-:10121000002044110000000000000000002F022107
-:1012200000000000000000000CE00000000001864B
-:1012300000000000C0204800000000000000000185
-:10124000005306210000018292000000002044119A
-:101250000000000000000000C0604800000001978E
-:101260000001A1FD00204411000000000000001159
-:101270000020062D00000000000000000078042A75
-:10128000000002FB00000000002028090000000010
-:1012900000003FFF002F022F0000000000000000B0
-:1012A0000CC000000000017400000000C0400400F9
-:1012B000000000010000021000600411000003158E
-:1012C00000003FFF002F022F000000000000000080
-:1012D0000CE000000000019400000015C020362042
-:1012E0000000000000000016C020362000000000B2
-:1012F0003F800000002004110000000046000000B4
-:1013000000600811000001B2000000000080000031
-:10131000000000000000A1FC0020441100000000BB
-:1013200000003FFF002F022F00000000000000001F
-:101330000CC000000000019B00000001008048116B
-:1013400000000000000000210080481100000000A3
-:101350000000FFFF40280E200000000000000010E9
-:10136000C0211220000000000000FFFF40281620CE
-:101370000000000000000010C0811A2000000000E2
-:101380008100000000204411000000000000000661
-:1013900000204811000000000000000800221E305C
-:1013A000000000000000002900201A2D00000000AD
-:1013B0000000E0000020441100000000FFFBFF09D6
-:1013C00000204811000000000000000F0020222D26
-:1013D0000000000000001FFF00294A280000000054
-:1013E000000000060020222D000000000000000088
-:1013F000002920E80000000000000000002048084C
-:101400000000000000000000002048110000000063
-:10141000060A020000294A26000000000000000021
-:1014200000204811000000000000000000204811CA
-:101430000000000000000100002018110000000062
-:101440000000000800621E280000012F00000008B4
-:1014500000822228000000000002C0000020441189
-:10146000000000000000001500600E2D000001BD0E
-:101470000000001600600E2D000001BD0000C00835
-:1014800000204411000000000000001700200E2D75
-:10149000000000000000000014C00000000001B9BE
-:1014A0000000000000200411000000000000000007
-:1014B0000020480100000000390000000020481111
-:1014C00000000000000000000020481100000000A3
-:1014D000000000000080480200000000000000182A
-:1014E00000202E2D0000000000000000003B0D63D6
-:1014F000000000000000000800224A230000000055
-:101500000000001000224A23000000000000001824
-:1015100000224A2300000000000000000080480371
-:101520000000000000000000006000000000000B50
-:10153000000010000060041100000315000000000E
-:1015400000200411000000000000000000600811ED
-:10155000000001B2000000070021062F000000007B
-:101560000000001300200A2D000000000000000110
-:1015700000202C11000000000000FFFF4028222066
-:10158000000000000000000F0026222800000000DC
-:101590000000001040212620000000000000000F85
-:1015A000002626290000000000000000002028027C
-:1015B000000000000000225600204411000000003E
-:1015C0000000001B00204811000000000000000087
-:1015D000002F022100000000000000000CE00000CD
-:1015E000000001E00000225C002044110000000027
-:1015F0000000008100204811000000000000A1FC54
-:1016000000204411000000000000000100204811EB
-:10161000000000000000008000201C1100000000FD
-:1016200000000000002F0227000000000000000062
-:101630000CE00000000001DC000000000060000081
-:10164000000001E90000000100531E27000001D83E
-:101650000000000100202C11000000000000001F0D
-:1016600000280A22000000000000001F00282A2A8B
-:10167000000000000000000100530621000001D11D
-:101680000000225C00204411000000000000000265
-:1016900000304A2F000000000000A1FC002044118F
-:1016A00000000000000000010020481100000000C0
-:1016B0000000000100301E2F0000000000000000AC
-:1016C000002F022700000000000000000CE00000D6
-:1016D000000000000000000000600000000001E9C0
-:1016E0000000000100531E27000001E50000FFFF7D
-:1016F00040280E20000000000000000F00260E23EE
-:101700000000000000000010C021122000000000B6
-:101710000000000F0026122400000000000000005E
-:1017200000201411000000000000000000601811EB
-:10173000000002BB0001A1FD0020441100000000D8
-:1017400000000000002F022B00000000000000003D
-:101750000CE00000000001F8000000100022162834
-:1017600000000000FFFF0000002816250000000018
-:101770000000FFFF00281A29000000000000000000
-:10178000002948C500000000000000000020480AB1
-:10179000000000000000000000202C1100000000EC
-:1017A000000000100022162300000000FFFF0000D0
-:1017B00000281625000000000000FFFF00281A2462
-:1017C0000000000000000000002948C500000000E3
-:1017D0000000000000731503000002050000000077
-:1017E0000020180500000000000000000073152410
-:1017F0000000020500000000002D14C500000000DC
-:1018000000000000003008A20000000000000000FE
-:101810000020480200000000000000000020280214
-:101820000000000000000000002020030000000075
-:101830000000000000802404000000000000000FF1
-:1018400000210225000000000000000014C000007C
-:101850000000068900000000002B140500000000B5
-:1018600000000001009016250000000000000000AC
-:10187000006000000000000B000000000060041188
-:10188000000003150000000000200411000000000B
-:101890000000000000600811000001B200002256A4
-:1018A00000204411000000000000001A00294A2214
-:1018B0000000000000000000C02000000000000048
-:1018C00000003FFF002F022F00000000000000007A
-:1018D0000CE000000000000000000000C020040038
-:1018E000000000000000225C002044110000000005
-:1018F0000000000300384A21000000000000A1FCA5
-:1019000000204411000000000000000100204811E8
-:10191000000000000000FFFF40281220000000002F
-:1019200000000010C0211A20000000000000FFFF8E
-:1019300040280E200000000000000010C0211620EA
-:10194000000000000000000000741465000002BBED
-:101950000001A1FD00604411000002E00000000150
-:10196000003306210000000000000000002F0221CB
-:1019700000000000000000000CC000000000021980
-:1019800000003FFF002F022F0000000000000000B9
-:101990000CC000000000021200000000C040040063
-:1019A000000000010000000000600000000006428E
-:1019B000000000000040040F0000021300000000BF
-:1019C000006000000000062E000000000060000023
-:1019D0000000064200000210006004110000031520
-:1019E0000000000000600000000001A000000000F6
-:1019F000006000000000019C00000000006000008A
-:101A0000000002BB0000000000600000000002A314
-:101A1000938000000020441100000000000000003E
-:101A2000002048080000000000000000002F022FE6
-:101A300000000000000000000AE000000000023288
-:101A400000000000006000000000013A00000000FB
-:101A50000040000000000236950000000020441104
-:101A60000000000000000000002F022F0000000016
-:101A7000000000000CE00000000002360000000042
-:101A8000C0404800000002339200000000204411D2
-:101A90000000000000000000C0204800000000001E
-:101AA0000000225600204411000000000000001633
-:101AB00000204811000000000000225C00204411BA
-:101AC000000000000000000300204811000000009A
-:101AD0000000A1FC002044110000000000000001F3
-:101AE00000204811000000000001A1FD0020441169
-:101AF000000000000000000000600411000002FB74
-:101B000000000000C04004000000000100000000D0
-:101B1000006000000000062E0000A00C0020441110
-:101B20000000000000000000C0204800000000008D
-:101B300000000000C040480000000000000000005D
-:101B4000006000000000000B0000001840210A2087
-:101B50000000000000000003002F0222000000002F
-:101B6000000000000AE000000000024C0000001429
-:101B70000020222D00000000000801010029222879
-:101B800000000000000000140020362800000000C3
-:101B90000000A30C00204411000000000000000021
-:101BA000C02048000000000000000000C0204800E5
-:101BB0000000000000000000C0404800000002518A
-:101BC00000000000006000000000000B000000109A
-:101BD00000600411000003153F8000000020041184
-:101BE000000000000000000000600811000001B2C9
-:101BF0000000225C002044110000000000000003EF
-:101C000000204811000000000000000000600000FB
-:101C10000000027C0000001700201E2D00000000C4
-:101C20000000000100211E2700000000000000004D
-:101C300014E000000000026A0000001200201E2DC7
-:101C4000000000000000FFFF00281E270000000029
-:101C50000000000000341C2700000000000000000D
-:101C600012C000000000025F0000000000201C11F4
-:101C70000000000000000000002F00E50000000050
-:101C80000000000008C00000000002620000000028
-:101C900000201407000000000000001200201E2D8C
-:101CA000000000000000001000211E2700000000BE
-:101CB0000000000000341C4700000000000000008D
-:101CC00012C00000000002670000000000201C118C
-:101CD0000000000000000000002F00E600000000EF
-:101CE0000000000008C000000000026A00000000C0
-:101CF0000020180700000000000000000060000045
-:101D0000000002C100002256002044110000000023
-:101D1000000000000034202300000000000000004C
-:101D200012C00000000002720000000000342044D5
-:101D3000000000000000000012C00000000002715E
-:101D40000000001600404811000002760000001854
-:101D500000404811000002760000000000342044DA
-:101D6000000000000000000012C00000000002752A
-:101D70000000001700404811000002760000001922
-:101D800000204811000000000000A1FC00204411C8
-:101D900000000000000000010020481100000000C9
-:101DA0000001A1FD00604411000002E900003FFFB6
-:101DB000002F022F00000000000000000CC00000F7
-:101DC0000000025600000000C040040000000001B6
-:101DD0000000001040210620000000000000FFFF6E
-:101DE000C0280A20000000000000001040210E2042
-:101DF000000000000000FFFFC028122000000000CB
-:101E00000000001040211620000000000000FFFF2D
-:101E1000C0881A200000000081000000002044114A
-:101E20000000000000000001002048110000000038
-:101E300000042004006044110000068A0000000035
-:101E4000006000000000062E00000000C0600000DE
-:101E5000000002A30000000500200A2D0000000081
-:101E60000000000800220A22000000000000002BF1
-:101E700000201A2D000000000000001C00201E2D74
-:101E8000000000000000700000281E270000000075
-:101E90000000000000311CE6000000000000002AE5
-:101EA00000201A2D000000000000000C00221A265D
-:101EB0000000000000000000002F00E6000000000D
-:101EC0000000000006E00000000002920000000098
-:101ED00000201C11000000000000000000200C1178
-:101EE000000000000000002B00203623000000004E
-:101EF0000000001000201811000000000000000089
-:101F000000691CE20000012F9380000000204411B2
-:101F10000000000000000000002048070000000052
-:101F200095000000002044110000000000000000A7
-:101F3000002F022F00000000000000000CE0000055
-:101F40000000029D0000000100333E2F0000000051
-:101F500000000000D90048000000000092000000CE
-:101F6000002044110000000000000000C0204800D4
-:101F7000000000000000001C0040362700000000A8
-:101F80000000000CC0220A20000000000000002910
-:101F9000002036220000000000000028C04036204B
-:101FA000000000000000A2A4002044110000000076
-:101FB000000000090020481100000000A1000000FE
-:101FC00000204411000000000000000100804811C2
-:101FD000000000000000002100201E2D0000000075
-:101FE00000000000002C1CE30000000000000021A5
-:101FF00000203627000000000000002200201E2DD7
-:102000000000000000000000002C1CE400000000A4
-:1020100000000022002036270000000000000023FE
-:1020200000201E2D0000000000000000003120A351
-:102030000000000000000000002D1D07000000004F
-:1020400000000023002036270000000000000024CC
-:1020500000201E2D0000000000000000003120C400
-:102060000000000000000000002D1D07000000001F
-:10207000000000240080362700000000000000213E
-:10208000002036230000000000000022002036243B
-:10209000000000000000000000311CA30000000050
-:1020A0000000002300203627000000000000000090
-:1020B00000311CC40000000000000024008036270E
-:1020C000000000000000001A002036270000000079
-:1020D0000000001B00203628000000000000001750
-:1020E00000201E2D00000000000000020021022739
-:1020F000000000000000000014C00000000002DC2E
-:102100000000000000400000000002D90000001A9A
-:1021100000203627000000000000001B00203628A9
-:10212000000000000000001700201E2D000000002D
-:102130000000000200210227000000000000000053
-:1021400014E00000000002D9000000030021022773
-:10215000000000000000000014E00000000002DCAD
-:102160000000002300201E2D0000000000000000E1
-:10217000002E00E1000000000000000002C000008E
-:10218000000002DC0000002100201E2D00000000E5
-:1021900000000000003120A100000000000000004D
-:1021A000002E00E8000000000000000006C0000053
-:1021B000000002DC0000002400201E2D00000000B2
-:1021C00000000000002E00E20000000000000000FF
-:1021D00002C00000000002DC0000002200201E2DD2
-:1021E0000000000000000000003120C200000000DC
-:1021F00000000000002E00E80000000000000000C9
-:1022000006C00000000002DC0000000000600000CA
-:10221000000006650000000000600000000002B53C
-:102220000000000000400000000002DE000000008E
-:1022300000600000000002B5000000000060000027
-:102240000000065C0000000000400000000002DE0C
-:102250000000000000600000000002A70000000075
-:1022600000400000000002DE0000001A00201E2DC9
-:10227000000000000000001B0080222D0000000074
-:102280000000001000221E230000000000000000DB
-:1022900000294887000000000000000000311CA356
-:1022A000000000000000001000221E2700000000B7
-:1022B0000000000000294887000000000000001016
-:1022C00000221E230000000000000000003120C496
-:1022D000000000000000FFFF00282228000000008E
-:1022E0000000000000894907000000000000001005
-:1022F00000221E2300000000000000000029488783
-:10230000000000000000001000221E21000000005C
-:102310000000000000294847000000000000000005
-:1023200000311CA3000000000000001000221E2746
-:1023300000000000000000000029488700000000A5
-:102340000000000000311CA100000000000000108F
-:1023500000221E270000000000000000002948475E
-:10236000000000000000001000221E2300000000FA
-:1023700000000000003120C4000000000000FFFF4A
-:102380000028222800000000000000000029490762
-:10239000000000000000001000221E2100000000CC
-:1023A00000000000003120C2000000000000FFFF1C
-:1023B00000282228000000000000000000894907D2
-:1023C000000000000000001000221E23000000009A
-:1023D0000000000000294887000000000000000104
-:1023E00000220A210000000000000000003308A2C3
-:1023F000000000000000001000221E22000000006B
-:102400000000001000212222000000000000000057
-:1024100000294907000000000000000000311CA353
-:10242000000000000000001000221E270000000035
-:1024300000000000002948870000000000000001A3
-:1024400000220A210000000000000000003008A265
-:10245000000000000000001000221E22000000000A
-:1024600000000010002122220000000000000000F7
-:1024700000294907000000000000001000221E2370
-:102480000000000000000000003120C40000000037
-:102490000000FFFF002822280000000000000000CC
-:1024A000002949070000000000000000003808C5AE
-:1024B00000000000000000000030084100000000A3
-:1024C0000000000100220A220000000000000000BD
-:1024D000003308A2000000000000001000221E22AD
-:1024E0000000000000000010002122220000000077
-:1024F00000000000008949070000000000000017EC
-:102500000020222D000000000000000014C0000088
-:1025100000000318FFFFFFEF002806210000000065
-:10252000000000140020222D000000000000F8E050
-:1025300000204411000000000000000000294901B3
-:1025400000000000000000000089490100000000B8
-:102550000000000000204811000000000000000002
-:102560000020481100000000060A02000080481107
-:102570000000000000000000C0200000000000007B
-:1025800097000000C020441100000000000000007F
-:10259000C0204811000000008A0000000020441103
-:1025A00000000000000000000020481100000000B2
-:1025B0000000225C00204411000000000000000028
-:1025C000C0204800000000000000A1FC00204411D1
-:1025D0000000000000000000C020480000000000D3
-:1025E00000000000C0200400000000000000000007
-:1025F00000A0000A00000000970000000020441125
-:102600000000000000000000002048110000000051
-:102610008A000000002044110000000000000000BB
-:1026200000204811000000000000225C002044113E
-:102630000000000000000000C02048000000000072
-:102640000000A1FC00204411000000000000000078
-:10265000C02048000000000000000000C02004006E
-:10266000000000000000000000A0000A00000000C0
-:10267000970000000020441100000000000000004E
-:1026800000204811000000008A00000000204411D2
-:1026900000000000000000000020481100000000C1
-:1026A0000000225C00204411000000000000000037
-:1026B000C0204800000000000000A1FC00204411E0
-:1026C0000000000000000000C020480000000000E2
-:1026D0000001A1FD002044110000000000000000E6
-:1026E000D90048000000000000000000C0200400E5
-:1026F000000000000000000000A0000A0000000030
-:1027000000002257002044110000000000000003D8
-:10271000C0484A20000000000000225D0020441153
-:102720000000000000000000C04048000000000061
-:1027300000000000006000000000064200000000F1
-:10274000C0200800000000000000225C00204411AE
-:10275000000000000000000300384A2200000000D2
-:102760000000A1FC00204411000000000000000057
-:10277000C0204800000000000001A1FD002044111D
-:102780000000000000000000002F022200000000F6
-:10279000000000000CE0000000000000000000004D
-:1027A00040204800000000000000000140304A20A6
-:1027B0000000000000000002C0304A2000000000BD
-:1027C0000000000100530A220000034B0000003FFC
-:1027D000C0280A20000000008100000000204411F1
-:1027E000000000000000000100204811000000006F
-:1027F000000021F800204411000000000000001833
-:102800000020481100000000000421F9006044117C
-:102810000000068A000000110021023000000000C4
-:102820000000000014E00000000003540000001449
-:10283000002F022200000000000000000CC0000079
-:10284000000003640000201000204411000000007C
-:102850000000800000204811000000000001A2A438
-:102860000020441100000000000000000060480249
-:102870000000036E00002100002044110000000051
-:1028800000000000C0204800000000000000000020
-:10289000C02048000000000000000000C0204800E8
-:1028A0000000000000000000C040480000000000E0
-:1028B00000000004002F02220000000000000000C1
-:1028C0000CC000000000036A00002010002044112A
-:1028D00000000000000080000020481100000000FF
-:1028E0000001A2A40020441100000000000000002C
-:1028F000004048020000035F00000028002F022271
-:1029000000000000000000000CC00000000005BD39
-:102910000001A2A4002044110000000000000000FB
-:10292000004048020000035F0000002C0020362613
-:102930000000000000000049002018110000000005
-:102940000000003F002048110000000000000001CE
-:1029500000331A260000000000000000002F0226AD
-:1029600000000000000000000CC000000000037028
-:102970000000002C00801A2D000000000000003F25
-:10298000C0280A200000000000000015002F0222CD
-:1029900000000000000000000CE0000000000386C2
-:1029A00000000006002F02220000000000000000CE
-:1029B0000CE00000000003B100000016002F02220E
-:1029C00000000000000000000CE00000000003B563
-:1029D00000000020002F0222000000000000000084
-:1029E0000CE000000000039C0000000F002F0222FA
-:1029F00000000000000000000CE00000000003A840
-:102A000000000010002F0222000000000000000063
-:102A10000CE00000000003A80000001E002F0222AE
-:102A200000000000000000000CE000000000039027
-:102A30000000A2A4002044110000000000000000DB
-:102A400000404802000000000800000000290A229F
-:102A5000000000000000000340210E2000000000E4
-:102A60000000000CC021122000000000000800003F
-:102A7000002812240000000000000014C0221620CC
-:102A80000000000000000000002914A40000000065
-:102A90000000A2A40020441100000000000000007B
-:102AA000002948A2000000000000A1FE00204411FF
-:102AB000000000000000000000404803000000008B
-:102AC000810000000020441100000000000000010F
-:102AD0000020481100000000000021F800204411EF
-:102AE0000000000000000016002048110000000057
-:102AF000000421F9006044110000068A000000155E
-:102B000000210230000000000000000014E000007E
-:102B1000000003920000210E00204411000000007C
-:102B200000000000C020480000000000000000007D
-:102B3000C0204800000000000000A2A400204411B2
-:102B400000000000000000000040480200000000FB
-:102B5000810000000020441100000000000000017E
-:102B60000020481100000000000021F8002044115E
-:102B700000000000000000170020481100000000C5
-:102B8000000421F9006044110000068A00000003DF
-:102B900000210230000000000000000014E00000EE
-:102BA0000000039E000021080020441100000000E6
-:102BB00000000000C02048000000000000000000ED
-:102BC000C0204800000000000000A2A40020441122
-:102BD000000000000000000000404802000000006B
-:102BE0000000A2A40020441100000000000000002A
-:102BF0000020480200000000800000000020441176
-:102C0000000000000000000000204811000000004B
-:102C100081000000002044110000000000000010AE
-:102C200000204811000000000000000000200010FB
-:102C3000000000000000000014C00000000003AE0F
-:102C40000000000000400000000000000000201014
-:102C50000020441100000000000080000020481106
-:102C6000000000000001A2A40020441100000000A8
-:102C70000000000600404811000000000000201085
-:102C800000204411000000000000800000204811D6
-:102C9000000000000001A2A4002044110000000078
-:102CA00000000016006048110000036E00000000E4
-:102CB000004000000000000000000000C0200800EC
-:102CC0000000000000000000C0200C000000000018
-:102CD0000000001D00210223000000000000000091
-:102CE00014E00000000003CE810000000020441129
-:102CF000000000000000000100204811000000005A
-:102D0000000021F80020441100000000000000181D
-:102D10000020481100000000000421F90060441167
-:102D20000000068A000000110021023000000000AF
-:102D30000000000014E00000000003C000002100BB
-:102D400000204411000000000000000000204802A4
-:102D50000000000000000000002048030000000008
-:102D6000BABECAFE0020481100000000CAFEBABE6A
-:102D70000020481100000000000020100020441135
-:102D8000000000000000800000204811000000004A
-:102D90000000A2A400204411000000000000000474
-:102DA0000040481100000000000021700020441184
-:102DB00000000000000000000020480200000000A9
-:102DC0000000000000204803000000008100000017
-:102DD00000204411000000000000000A00204811FB
-:102DE00000000000000000000020001000000000B3
-:102DF0000000000014C00000000003D38C0000009D
-:102E00000020441100000000CAFEBABE0040481174
-:102E100000000000810000000020441100000000BC
-:102E200000000001002048110000000000003FFFEA
-:102E300040280A20000000008000000040280E20EA
-:102E40000000000040000000C02812200000000028
-:102E500000040000006946220000068A000000000D
-:102E6000002014100000000000000000002F0223CA
-:102E700000000000000000000CC00000000003E1A2
-:102E800000000000C0401800000003E400003FFF05
-:102E9000C0281A2000000000000400000069462637
-:102EA0000000068A0000000000201810000000004A
-:102EB00000000000002F02240000000000000000BD
-:102EC0000CC00000000003E700000000C0401C0030
-:102ED000000003EA00003FFFC0281E2000000000A1
-:102EE00000040000006946270000068A0000000078
-:102EF00000201C1000000000000000000020440220
-:102F00000000000000000000002820C500000000B4
-:102F100000000000004948E800000000A580000013
-:102F200000200811000000000000200000200C110B
-:102F30000000000083000000006044110000041243
-:102F4000000000000020440200000000000000001B
-:102F5000C0204800000000000000000040204800A1
-:102F6000000000000000001FC0210220000000003F
-:102F70000000000014C00000000003F70000201053
-:102F800000204411000000000000800000204811D3
-:102F9000000000000000FFFFC0481220000003FFF7
-:102FA000A780000000200811000000000000A00021
-:102FB00000200C110000000083000000006044119C
-:102FC0000000041200000000002044020000000085
-:102FD00000000000C02048000000000000000000C9
-:102FE000C0204800000000000000FFFFC0281220A1
-:102FF00000000000830000000020441100000000D9
-:103000000000000000304883000000008400000041
-:10301000002044110000000000000000C020480013
-:1030200000000000000000001D0000000000000083
-:103030008300000000604411000004120000000042
-:10304000C040040000000001A98000000020081119
-:10305000000000000000C00000400C11000003FA56
-:10306000AB80000000200811000000000000F8E024
-:1030700000400C11000003FAAD8000000020081190
-:10308000000000000000F88000400C11000003FA6E
-:10309000B380000000200811000000000000F3FCD5
-:1030A00000400C11000003FAAF800000002008115E
-:1030B000000000000000E00000400C11000003FAD6
-:1030C000B180000000200811000000000000F000A6
-:1030D00000400C11000003FA83000000002044119E
-:1030E00000000000000021480020481100000000FE
-:1030F00084000000002044110000000000000000D7
-:10310000C020480000000000000000001D0000007A
-:10311000000000000000000000800000000000002F
-:1031200001182000C0304620000000000000000010
-:10313000D90048000000000000000000C02004008A
-:10314000000000000000000000A0000A00000000D5
-:103150000218A000C030462000000000000000005F
-:10316000D90048000000000000000000C02004005A
-:10317000000000000000000000A0000A00000000A5
-:103180000318C000C030462000000000000000000E
-:10319000D90048000000000000000000C02004002A
-:1031A000000000000000000000A0000A0000000075
-:1031B0000418F8E0C03046200000000000000000C5
-:1031C000D90048000000000000000000C0200400FA
-:1031D000000000000000000000A0000A0000000045
-:1031E0000518F880C03046200000000000000000F4
-:1031F000D90048000000000000000000C0200400CA
-:10320000000000000000000000A0000A0000000014
-:103210000618E000C030462000000000000000005A
-:10322000D90048000000000000000000C020040099
-:10323000000000000000000000A0000A00000000E4
-:103240000718F000C0304620000000000000000019
-:10325000D90048000000000000000000C020040069
-:10326000000000000000000000A0000A00000000B4
-:103270000818F3FCC03046200000000000000000E9
-:10328000D90048000000000000000000C020040039
-:10329000000000000000000000A0000A0000000084
-:1032A0000000003000200A2D000000000000000097
-:1032B000C0290C4000000000000000300020362330
-:1032C0000000000000000000C0200400000000001A
-:1032D0000000000000A0000A0000000086000000BE
-:1032E00000204411000000000000000000404801E0
-:1032F0000000000085000000C02044110000000014
-:103300000000000000404801000000000000217C97
-:10331000002044110000000000000000C020480010
-:103320000000000000000000C02048000000000075
-:1033300000000000C02048000000000081000000E4
-:10334000002044110000000000000001002048118E
-:103350000000000000000000C02008000000000085
-:103360000000000017000000000000000004217FA2
-:10337000006044110000068A0000001F0021023096
-:10338000000000000000000014C000000000000069
-:103390000000000000404C02000004480000000053
-:1033A000C0200C000000000000000000C020100041
-:1033B0000000000000000000C02014000000000019
-:1033C00000000000C0201800000000000000000005
-:1033D000C0201C000000000000007F0000280A211F
-:1033E0000000000000004500002F02220000000045
-:1033F000000000000CE00000000004560000000087
-:10340000C0202000000000000000000017000000A5
-:10341000000000000000001000280A230000000047
-:1034200000000010002F0222000000000000000039
-:103430000CE000000000045E810000000020441148
-:103440000000000000000001002048110000000002
-:1034500000040000006946240000068A0000000005
-:1034600000400000000004638100000000204411BF
-:1034700000000000000000000020481100000000D3
-:103480000000216D00204411000000000000000039
-:103490000020480400000000000000000060480513
-:1034A0000000068F00000000002824F0000000004B
-:1034B0000000000700280A230000000000000001AF
-:1034C000002F022200000000000000000AE00000BF
-:1034D0000000046A00000000002F00C90000000086
-:1034E0000000000004E00000000004830000000071
-:1034F000004000000000049000000002002F0222A3
-:1035000000000000000000000AE000000000046F5E
-:1035100000000000002F00C90000000000000000B3
-:1035200002E00000000004830000000000400000F2
-:103530000000049000000003002F022200000000A1
-:10354000000000000AE00000000004740000000019
-:10355000002F00C900000000000000000CE0000087
-:103560000000048300000000004000000000049000
-:1035700000000004002F02220000000000000000F4
-:103580000AE000000000047900000000002F00C9DC
-:1035900000000000000000000AE0000000000483BA
-:1035A0000000000000400000000004900000000542
-:1035B000002F022200000000000000000AE00000CE
-:1035C0000000047E00000000002F00C90000000081
-:1035D0000000000006E0000000000483000000007E
-:1035E000004000000000049000000006002F0222AE
-:1035F00000000000000000000AE00000000004835A
-:1036000000000000002F00C90000000000000000C2
-:1036100008E00000000004830000000000400000FB
-:103620000000049000007F0000280A210000000034
-:1036300000004500002F02220000000000000000F2
-:103640000AE00000000000000000000800210A233A
-:10365000000000000000000014C000000000048D05
-:10366000000021690020441100000000000000005B
-:10367000C02048000000000000000000C0204800FA
-:103680000000000000000000C02048000000000012
-:10369000CAFEBABE00404811000000000000000051
-:1036A000C02044000000000000000000C020000016
-:1036B0000000000000000000C040480000000000C2
-:1036C00000007F0000280A210000000000004500E3
-:1036D000002F022200000000000000000AE00000AD
-:1036E0000000049600000000C02000000000000060
-:1036F00000000000C02000000000000000000000EA
-:10370000C0400000000000000000000000404C0825
-:103710000000045600000000C02008000000000067
-:103720000000001040210E200000000000000011E9
-:10373000402112200000000000000012402116204D
-:10374000000000000000216900204411000000007A
-:1037500000000000002048020000000000000000FF
-:1037600000210225000000000000000014E000001D
-:10377000000004A000040000C0494A20000004A189
-:10378000FFFBFFFFC0284A200000000000000000EF
-:1037900000210223000000000000000014E00000EF
-:1037A000000004AD00000000C02048000000000040
-:1037B00000000000C02048000000000000000000E1
-:1037C00000210224000000000000000014C00000DE
-:1037D00000000000810000000020441100000000F3
-:1037E0000000000C00204811000000000000000054
-:1037F00000200010000000000000000014C00000C5
-:10380000000004A9A00000000020441100000000F6
-:10381000CAFEBABE0040481100000000810000004E
-:1038200000204411000000000000000400204811A6
-:10383000000000000000216B002044110000000087
-:1038400000000000C02048100000000081000000BF
-:103850000020441100000000000000050020481175
-:10386000000000000000216C002044110000000056
-:1038700000000000C0204810000000000000000010
-:10388000002F022400000000000000000CE00000F7
-:10389000000000000000000000400000000004A73D
-:1038A00000000000C0210A2000000000000000000D
-:1038B00014C00000000004C081000000002044117A
-:1038C000000000000000000000204811000000007F
-:1038D0000000216D002044110000000000000000E5
-:1038E000C02048000000000000000000C060480048
-:1038F0000000068F0000000000400000000004C42B
-:1039000081000000002044110000000000000001C0
-:10391000002048110000000000040000C0294620DB
-:103920000000000000000000C06000000000068AE7
-:103930000000000100210222000000000000000041
-:1039400014C00000000004CB0000216900204411D5
-:103950000000000000000000C0204800000000003F
-:1039600000000000C020480000000000000000002F
-:103970000020481000000000CAFEBABE00404811F6
-:103980000000000000000000C02044000000000013
-:1039900000000000C040481000000000810000004E
-:1039A0000020441100000000000000010020481128
-:1039B00000000000000021F8002044110000000079
-:1039C0000000000E0020481100000000000421F952
-:1039D000006044110000068A00000000002102304F
-:1039E000000000000000000014C00000000004CD32
-:1039F00000002180002044110000000000000000B1
-:103A0000C02048000000000000000000C0200000AE
-:103A10000000000000000000C0204800000000007E
-:103A200000000000C02000000000000000000000B6
-:103A3000C0404800000000000000000300333E2F9B
-:103A40000000000000000001002102210000000031
-:103A50000000000014E00000000004FD0000002C45
-:103A600000200A2D000000000004000018E00C11E6
-:103A7000000004EC0000000100333E2F00000000B5
-:103A80000000216900204411000000000000000037
-:103A90000020480200000000000000000020480351
-:103AA000000000000000000800300A2200000000B2
-:103AB00000000000C02048000000000000000000DE
-:103AC000C0204800000000000000216900204411CF
-:103AD000000000000000000000204802000000007C
-:103AE0000000000000204803000000000000000863
-:103AF00000300A220000000000000000C020480042
-:103B00000000000000000000D8C04800000004E0F1
-:103B100000002169002044110000000000000000A6
-:103B200000204802000000000000000000204803C0
-:103B3000000000000000000800300A220000000021
-:103B400000000000C020480000000000000000004D
-:103B5000C0204800000000000000002D0020122DB1
-:103B6000000000000000000000290C83000000009D
-:103B70000000216900204411000000000000000046
-:103B80000020480200000000000000000020480360
-:103B9000000000000000000800300A2200000000C1
-:103BA00000000000C02048000000000000000000ED
-:103BB000C020480000000000000000110021022485
-:103BC000000000000000000014C000000000000021
-:103BD0000000000000400000000004A70000002CCE
-:103BE000C0203620000000000000002DC04036201C
-:103BF000000000000000000F002102210000000072
-:103C00000000000014C000000000050200000000D9
-:103C1000006000000000000B00000000D900000060
-:103C20000000000000000000C0400400000000018F
-:103C3000B50000000020441100000000000020003A
-:103C40000020481100000000B600000000204411D0
-:103C5000000000000000A00000204811000000004B
-:103C6000B700000000204411000000000000C00068
-:103C70000020481100000000B8000000002044119E
-:103C8000000000000000F8E00020481100000000E3
-:103C9000B900000000204411000000000000F8807E
-:103CA0000020481100000000BA000000002044116C
-:103CB000000000000000E0000020481100000000AB
-:103CC000BB00000000204411000000000000F000D4
-:103CD0000020481100000000BC000000002044113A
-:103CE000000000000000F3FC00204811000000006C
-:103CF00081000000002044110000000000000002CC
-:103D00000020481100000000000000FF00280E30D5
-:103D10000000000000000000002F0223000000004F
-:103D2000000000000CC000000000051600000000AC
-:103D3000C0200800000000000000000014C00000C7
-:103D40000000052B0000000000200C110000000006
-:103D50000000001C00203623000000000000002BA3
-:103D60000020362300000000000000290020362338
-:103D700000000000000000280020362300000000A2
-:103D8000000000170020362300000000000000257E
-:103D9000002036230000000000000026002036230B
-:103DA0000000000000000015002036230000000085
-:103DB000000000160020362300000000FFFFE00096
-:103DC00000200C110000000000000021002036231C
-:103DD0000000000000000022002036230000000048
-:103DE00000001FFF00200C11000000000000002355
-:103DF00000203623000000000000002400203623AD
-:103E000000000000F1FFFFFF00283A2E0000000034
-:103E10000000001AC0220E20000000000000000078
-:103E20000029386E000000008100000000204411CD
-:103E30000000000000000006002048110000000003
-:103E40000000002A4020362000000000870000000B
-:103E5000002044110000000000000000C0204800C5
-:103E6000000000000000A1F4002044110000000048
-:103E700000000000002048100000000000000000CA
-:103E800000200C110000000000000030002036234C
-:103E9000000000009D000000002044110000000010
-:103EA0000000001F40214A20000000009600000092
-:103EB000002044110000000000000000C020480065
-:103EC0000000000000000000C0200C000000000006
-:103ED00000000000C0201000000000000000001FD3
-:103EE00000211624000000000000000014C00000A3
-:103EF000000000000000001D00203623000000002C
-:103F00000000000300281E2300000000000000083D
-:103F10000022222300000000FFFFF00000282228DA
-:103F20000000000000000000002920E80000000060
-:103F30000000001F002036280000000000000018CC
-:103F400000211E2300000000000000200020362772
-:103F50000000000000000002002216240000000003
-:103F600000000000003014A8000000000000001E47
-:103F700000203625000000000000000300211A2464
-:103F8000000000001000000000281A2600000000B9
-:103F9000EFFFFFFF00283A2E0000000000000000A5
-:103FA000004938CE000006780000000140280A20B1
-:103FB000000000000000000640280E200000000065
-:103FC00000000300C02812200000000000000008CC
-:103FD000002112240000000000000000C020162074
-:103FE0000000000000000000C0201A2000000000B7
-:103FF000000000000021022200000000000000007C
-:1040000014C000000000056381000000002044117E
-:104010000000000000000001002048110000000026
-:104020000000225800300A240000000000040000B4
-:10403000006946220000068A000021690020441120
-:104040000000000000000000002048050000000003
-:104050000002000000294A260000000000000000C5
-:104060000020481000000000CAFEBABE002048111F
-:104070000000000000000002002F022300000000EA
-:10408000000000000CC000000000056B00000000F4
-:10409000C0201C100000000000000000C040000014
-:1040A0000000057900000002002F0223000000003C
-:1040B000000000000CC000000000056B8100000043
-:1040C0000020441100000000000000010020481101
-:1040D000000000000000225800300A240000000008
-:1040E00000040000006946220000068A000000006B
-:1040F000C0201C100000000000000000C0400000B4
-:104100000000057900000000002F022300000000DD
-:10411000000000000CC000000000056F000000005F
-:10412000C0201C000000000000000000C040000093
-:104130000000057900000004002F022300000000A9
-:10414000000000000CC000000000057781000000A6
-:104150000020441100000000000000000020481171
-:10416000000000000000216D00204411000000004C
-:1041700000000000C0204800000000000000000017
-:10418000C06048000000068F0000000000401C10C6
-:104190000000057900000000C020000000000000C1
-:1041A00000000000C040000000000000000000000F
-:1041B0000EE000000000057B000000000060000031
-:1041C000000005C600000000002F022400000000CF
-:1041D000000000000CC000000000058C0000A2B729
-:1041E00000204411000000000000000000204807EB
-:1041F00000000000810000000020441100000000C9
-:104200000000000100204811000000000004A2B6D8
-:10421000006044110000068A0000001A00212230CC
-:104220000000000000000006002226300000000010
-:1042300000042004006044110000068A0000A2C4AB
-:10424000002044110000000000000000003048E998
-:10425000000000000000000000E000000000058AEF
-:104260000000A2D100204411000000000000000066
-:1042700000404808000000000000A2D100204411C6
-:10428000000000000000000100504A28000000006B
-:1042900000000001002F02240000000000000000C8
-:1042A0000CC000000000059D0000A2BB00204411CE
-:1042B000000000000000000000204807000000008F
-:1042C00081000000002044110000000000000001F7
-:1042D00000204811000000000004A2BA0060441150
-:1042E0000000068A0000001A0021223000000000B1
-:1042F0000000000600222630000000000004200418
-:10430000006044110000068A0000A2C5002044118C
-:104310000000000000000000003048E9000000003C
-:104320000000000000E000000000059B0000A2D299
-:104330000020441100000000000000000040480878
-:10434000000000000000A2D2002044110000000084
-:104350000000000100504A28000000000000000298
-:10436000002F022400000000000000000CC000002C
-:10437000000005AE0000A2BF0020441100000000B4
-:10438000000000000020480700000000810000003D
-:10439000002044110000000000000001002048112E
-:1043A000000000000004A2BE006044110000068A64
-:1043B0000000001A0021223000000000000000066A
-:1043C0000022263000000000000420040060441198
-:1043D0000000068A0000A2C6002044110000000070
-:1043E00000000000003048E900000000000000006C
-:1043F00000E00000000005AC0000A2D30020441142
-:10440000000000000000000000404808000000001C
-:104410000000A2D3002044110000000000000001B1
-:1044200000504A28000000000000A2C300204411F0
-:10443000000000000000000000204807000000000D
-:104440008100000000204411000000000000000175
-:1044500000204811000000000004A2C200604411C6
-:104460000000068A0000001A00212230000000002F
-:104470000000000600222630000000000004200496
-:10448000006044110000068A0000A2C70020441109
-:104490000000000000000000003048E900000000BB
-:1044A0000000000000E00000000005BB0000A2D4F6
-:1044B00000204411000000000000000000404808F7
-:1044C000000000000000A2D4002044110000000001
-:1044D0000000000100504A28000000008500000094
-:1044E00000204411000000000000000000204801EE
-:1044F000000000000000304A0020441100000000CD
-:104500000100000000204811000000000000000031
-:1045100000400000000005C1A4000000C0204411BC
-:104520000000000000000000C04048000000000043
-:1045300000000000C0600000000005C60000000090
-:10454000C0400400000000010000002C00203621C3
-:104550000000000081000000002044110000000065
-:1045600000000006002048110000000000000000CC
-:10457000002F023000000000000000000CC000000E
-:10458000000005CD00000000002004110000000024
-:104590000000003000403621000005E0000000303F
-:1045A0000020062D0000000000007E0000280621EB
-:1045B0000000000000000000002F022100000000A9
-:1045C000000000000CE00000000005E08100000099
-:1045D00000204411000000000000000100204811EC
-:1045E000000000000004A092006044110000068A50
-:1045F0000000003100203630000000000004A093CD
-:10460000006044110000068A0000003200203630AD
-:10461000000000000004A2B6006044110000068AF9
-:104620000000003300203630000000000004A2BA71
-:10463000006044110000068A00000034002036307B
-:10464000000000000004A2BE006044110000068AC1
-:104650000000003500203630000000000004A2C237
-:10466000006044110000068A000000360020363049
-:104670000000000000042004006044110000068ACD
-:104680000001A2A400204411000000000000003F2F
-:1046900000204811000000000000003F00204811E9
-:1046A000000000000000003F002048110000000052
-:1046B0000000003F0020481100000000000000053D
-:1046C00000204811000000000000A1F40020441167
-:1046D0000000000000000000002048110000000061
-:1046E00088000000002044110000000000000001CC
-:1046F000002048110000000081000000002044114B
-:10470000000000000000000600204811000000002A
-:1047100000000001002F0230000000000000000037
-:104720000CE0000000000629000000300020062DEB
-:104730000000000000000000002F02210000000027
-:10474000000000000CE000000000062981000000CD
-:10475000002044110000000000000001002048116A
-:104760000000000000007E0000280621000000007C
-:1047700000000000002F02210000000000000000E7
-:104780000CE00000000006020000A092002044118E
-:10479000000000000000003100204A2D0000000051
-:1047A0000000A0930020441100000000000000322F
-:1047B00000204A2D000000000000A2B60020441195
-:1047C000000000000000003300204A2D000000001F
-:1047D0000000A2BA002044110000000000000034D4
-:1047E00000204A2D000000000000A2BE002044115D
-:1047F000000000000000003500204A2D00000000ED
-:104800000000A2C200204411000000000000003699
-:1048100000204A2D00000000000000300020062D7E
-:1048200000000000000001FF002806210000000039
-:1048300000000000002F0221000000000000000026
-:104840000CE000000000062800000000002102210A
-:10485000000000000000000014C000000000060B73
-:104860000004A003006044110000068A0000A003B9
-:10487000002044110000000000000000002048104B
-:1048800000000000000000010021062100000000DF
-:104890000000000014C00000000006100004A0107A
-:1048A000006044110000068A0000A010002044119E
-:1048B0000000000000000000002048100000000080
-:1048C000000000010021062100000000000000009F
-:1048D000002F022100000000000000000CE000009A
-:1048E000000006280004A011006044110000068AA0
-:1048F0000000A01100204411000000000000000092
-:1049000000204810000000000004A01200604411C4
-:104910000000068A0000A0120020441100000000E0
-:104920000000000000204810000000000004A01358
-:10493000006044110000068A0000A013002044110A
-:1049400000000000000000000020481000000000EF
-:104950000004A014006044110000068A0000A014A6
-:10496000002044110000000000000000002048105A
-:10497000000000000004A015006044110000068A39
-:104980000000A015002044110000000000000000FD
-:1049900000204810000000000004A0160060441130
-:1049A0000000068A0000A01600204411000000004C
-:1049B0000000000000204810000000000004A017C4
-:1049C000006044110000068A0000A0170020441176
-:1049D000000000000000000000204810000000005F
-:1049E00000042004006044110000068A0000002C2E
-:1049F0000080062D00000000FF0000000020441190
-:104A0000000000000000000000204811000000002D
-:104A1000000000010020481100000000000000021A
-:104A20000080481100000000000000000EE00000BF
-:104A30000000063A000000300020062D00000000B3
-:104A40000000000200280621000000000000000015
-:104A5000002F022100000000000000000CE0000018
-:104A60000000063881000000002044110000000012
-:104A70000000000100204811000000000004200494
-:104A8000006044110000068A000010000020081198
-:104A9000000000000000002B002036220000000073
-:104AA00000000000006000000000063E0000000062
-:104AB00000600000000005C69800000000204411BE
-:104AC000000000000000000000804811000000000D
-:104AD00000000000C06000000000063E0000000072
-:104AE000C0400400000000010000A2A40020441106
-:104AF000000000000000002200204811000000001B
-:104B000089000000002044110000000000000001A6
-:104B1000004048110000062A9700000000204411C0
-:104B2000000000000000000000204811000000000C
-:104B30008A00000000204411000000000000000076
-:104B4000004048110000062A00000000006000003C
-:104B50000000065900002010002044110000000051
-:104B60000000800000204811000000000001A2A405
-:104B7000C020441100000000000000160060481131
-:104B80000000036E0000201000204411000000000F
-:104B9000000100000020481100000000810000001A
-:104BA0000020441100000000000000010020481116
-:104BB000000000000000217C0020441100000000E3
-:104BC000098000000020481100000000FFFFFFFFE7
-:104BD00000204811000000000000000000204811E3
-:104BE00000000000000000001700000000000000AE
-:104BF0000004217F006044110000068A0000001FAD
-:104C000000210230000000000000000014C000007D
-:104C1000000000000000000400404C11000006539A
-:104C2000000000000040000000000000000000172D
-:104C300000201E2D000000000000000400291E2797
-:104C40000000000000000017008036270000000070
-:104C50000000001700201E2D00000000FFFFFFFBDA
-:104C600000281E27000000000000001700803627E3
-:104C7000000000000000001700201E2D00000000B2
-:104C80000000000800291E27000000000000001797
-:104C900000803627000000000000001700201E2DB5
-:104CA00000000000FFFFFFF700281E2700000000A3
-:104CB00000000017008036270000000000002010D0
-:104CC0000020441100000000000080000020481176
-:104CD000000000000001A2A4002044110000000018
-:104CE00000000016006048110000036E0000201054
-:104CF00000204411000000000001000000204811C5
-:104D0000000000000000217C002044110000000091
-:104D1000018000000020481100000000FFFFFFFF9D
-:104D20000020481100000000000000000020481191
-:104D3000000000000000000017000000000000005C
-:104D4000810000000020441100000000000000016C
-:104D500000204811000000000004217F0060441181
-:104D60000000068A0000001F002102300000000041
-:104D70000000000014C000000000068900000010C0
-:104D800000404C110000066F00000000C02004002D
-:104D9000000000000000000038C00000000000001B
-:104DA0000000001D00200A2D000000000000001E71
-:104DB00000200E2D000000000000001F0020122D1A
-:104DC00000000000000000200020162D0000000060
-:104DD00000002169002044110000000000000000D4
-:104DE00000204804000000000000000000204805EA
-:104DF000000000000000000000204801000000004A
-:104E0000CAFEBABE002048110000000000000004E5
-:104E1000003012240000000000000000002F006499
-:104E200000000000000000000CC000000000068828
-:104E30000000000300281A22000000000000000803
-:104E40000022122200000000FFFFF00000281224C0
-:104E50000000000000000000002910C40000000055
-:104E60000000001F00403624000000000000000089
-:104E70000080000000000000000000001AC00000D8
-:104E80000000068A9F00000000204411000000007E
-:104E9000CAFEBABE00204811000000000000000059
-:104EA0001AE000000000068D0000000000800000F5
-:104EB00000000000000000001AC000000000068F83
-:104EC0009E0000000020441100000000CAFEBABE8F
-:104ED0000020481100000000000000001AE000005F
-:104EE00000000692000000000080000000000000AA
-:104EF00000000000006000000000000B0000100037
-:104F000000600411000003150000000000200411DF
-:104F1000000000000000000000600811000001B265
-:104F20000000225C0020441100000000000000038B
-:104F3000002048110000000000002256002044110B
-:104F4000000000000000001B0020481100000000CD
-:104F50000000A1FC0020441100000000000000013E
-:104F600000204811000000000001A1FDC0204411F4
-:104F7000000000000000002100201E2D00000000A5
-:104F80000000001000221E27000000000000002486
-:104F90000020222D000000000000FFFF0028222832
-:104FA0000000000000000000002949070000000088
-:104FB0000000000000204811000000000000002256
-:104FC0000020222D000000000000FFFF0028222802
-:104FD0000000000000000000002949070000000058
-:104FE0000000000000204811000000000000002325
-:104FF00000201E2D000000000000001000221E27CF
-:105000000000000000000000002949070000000027
-:1050100000000000004048110000000000000000F7
-:105020000000000000000000000000000000000080
-:105030000000000000000000000000000000000070
-:105040000000000000000000000000000000000060
-:105050000000000000000000000000000000000050
-:105060000000000000000000000000000000000040
-:105070000000000000000000000000000000000030
-:105080000000000000000000000000000000000020
-:105090000000000000000000000000000000000010
-:1050A0000000000000000000000000000000000000
-:1050B00000000000000000000000000000000000F0
-:1050C00000000000000000000000000000000000E0
-:1050D00000000000000000000000000000000000D0
-:1050E00000000000000000000000000000000000C0
-:1050F00000000000000000000000000000000000B0
-:10510000000000000000000000000000000000009F
-:10511000000000000000000000000000000000008F
-:10512000000000000000000000000000000000007F
-:10513000000000000000000000000000000000006F
-:10514000000000000000000000000000000000005F
-:10515000000000000000000000000000000000004F
-:10516000000000000000000000000000000000003F
-:10517000000000000000000000000000000000002F
-:10518000000000000000000000000000000000001F
-:10519000000000000000000000000000000000000F
-:1051A00000000000000000000000000000000000FF
-:1051B00000000000000000000000000000000000EF
-:1051C00000000000000000000000000000000000DF
-:1051D00000000000000000000000000000000000CF
-:1051E00000000000000000000000000000000000BF
-:1051F00000000000000000000000000000000000AF
-:10520000000000000000000000000000000000009E
-:10521000000000000000000000000000000000008E
-:10522000000000000000000000000000000000007E
-:10523000000000000000000000000000000000006E
-:10524000000000000000000000000000000000005E
-:10525000000000000000000000000000000000004E
-:10526000000000000000000000000000000000003E
-:10527000000000000000000000000000000000002E
-:10528000000000000000000000000000000000001E
-:10529000000000000000000000000000000000000E
-:1052A00000000000000000000000000000000000FE
-:1052B000014204FF05BD02500000000001C3016867
-:1052C000043F05BD00000000022502090250015103
-:1052D000000000000223024502A00241000000007D
-:1052E00003D705BD05BD05BD000000000646064705
-:1052F000031F05BD0000000005BD05C203200340DB
-:1053000000000000032A0282034203340000000070
-:1053100005BD05BD05BD05BD0000000005BD054E70
-:1053200005BD05BD0000000003BA05BD04B8034477
-:10533000000000000497044D043D05BD000000007E
-:1053400004CD05BD044104DA00000000044D05044D
-:10535000035103750000000005BD05BD05BD05BD79
-:105360000000000005BD05BD05BD05BD0000000035
-:1053700005BD05BD063C05C40000000005BD05BD1A
-:10538000000705BD0000000005BD05BD05BD05BD4C
-:105390000000000005BD05BD05BD05BD0000000005
-:1053A00003F803ED0408040600000000040E040ADC
-:1053B000040C041000000000041C04180424042041
-:1053C00000000000042C0428043404300000000015
-:1053D00005BD05BD043805BD0000000005BD05BDC7
-:1053E00005BD05BD0000000005BD05BD05BD05BD31
-:1053F000000000000002067606940006000000008F
-:00000001FF
--- zfcpdump-kernel-4.4.orig/firmware/radeon/RV635_pfp.bin.ihex
+++ /dev/null
@@ -1,145 +0,0 @@
-:1000000000CA040000A00000007E828B007C038BED
-:10001000008001B8007C038B00D4401E00EE001E5F
-:1000200000CA040000A00000007E828B00C41838C3
-:1000300000CA240000CA2800009581A800C41C3A08
-:1000400000C3C00000CA080000CA0C00007C744B4A
-:1000500000C200050099C00000C41C3A007C744C2A
-:1000600000C0FFF000042C0400309002007D250049
-:1000700000351402007D350B00255403007CD5802B
-:1000800000259C030095C00400D5001B007EDDC147
-:10009000007D9D8000D6801B00D5801B00D4401EB3
-:1000A00000D5401E00D6401E00D6801E00D4801E03
-:1000B00000D4C01E009783D300D5C01E00CA08001C
-:1000C0000080001A00CA0C0000E4011E00D4001ECB
-:1000D0000080000C00C4183800E4013E00D4001E6B
-:1000E0000080000C00C4183800D4401E00EE001E32
-:1000F00000CA040000A00000007E828B00E4011E04
-:1001000000D4001E00D4401E00EE001E00CA0400F1
-:1001100000A00000007E828B00E4013E00D4001E9F
-:1001200000D4401E00EE001E00CA040000A0000023
-:10013000007E828B00CA180000D4401E00D5801EAD
-:100140000080005300D4007500D4401E00CA08008F
-:1001500000CA0C0000CA100000D4801900D4C018D6
-:1001600000D5001700D4801E00D4C01E00D5001E8C
-:1001700000E2001E00CA040000A00000007E828B86
-:1001800000CA080000D4806000D4401E0080000037
-:1001900000D4801E00CA080000D4806100D4401E34
-:1001A0000080000000D4801E00CA080000CA0C00B5
-:1001B00000D4401E00D4801600D4C01600D4801E87
-:1001C000008001B800D4C01E00C6084300CA0C005D
-:1001D00000CA10000094800400CA140000E420F358
-:1001E00000D4201300D5606500D4E01C00D5201C8D
-:1001F00000D5601C008000000006200100C60843F6
-:1002000000CA0C0000CA1000009483F700CA140052
-:1002100000E420F30080007900D4201300C60843D6
-:1002200000CA0C0000CA1000009883EF00CA140036
-:1002300000D400640080008D0000000000C414326F
-:1002400000C6184300C4082F0095400500C40C30B8
-:1002500000D4401E0080000000EE001E009583F5D3
-:1002600000C4103100D4403300D5206500D4A01C58
-:1002700000D4E01C00D5201C00E4015E00D4001E68
-:10028000008000000006200100CA1800000A2001BA
-:1002900000D6007600C408360098800700C61045D6
-:1002A0000095011000D4001F00D46062008000009F
-:1002B00000D4206200CC383500CC1433008401BB5C
-:1002C00000D4007200D5401E0080000000EE001E29
-:1002D00000E2001A008401BB00E2001A00CC104BBF
-:1002E00000CC0447002C9401007D098B0098400548
-:1002F000007D15CB00D4001A008001B800D4006D39
-:100300000034440100CC0C480098403A00CC2C4A00
-:100310000095800400CC0449008001B800D4001A84
-:1003200000D4C01A00282801008400F000CC10037B
-:100330000098801B0004380C008400F000CC1003EF
-:100340000098801700043808008400F000CC1003E7
-:100350000098801300043804008400F000CC1003DF
-:100360000098801400CC104C009A800900CC144DE9
-:10037000009840DC00D4006D00CC184800D5001A6D
-:1003800000D5401A008000C900D5801A0096C0D55B
-:1003900000D4006D008001B800D4006E009AC00344
-:1003A00000D4006D00D4006E0080000000EC007FDF
-:1003B000009AC0CC00D4006D008001B800D4006E5B
-:1003C00000CC140300CC180300CC1C03007D910367
-:1003D000007DD583007D190C0035CC1F0035701FC2
-:1003E000007CF0CB007CD08B00880000007E8E8BE0
-:1003F0000095C00400D4006E008001B800D4001A3B
-:1004000000D4C01A00CC080300CC0C0300CC1003AD
-:1004100000CC140300CC180300CC1C0300CC240334
-:1004200000CC28030035C41F0036B01F007C704B81
-:100430000034F01F007C704B0035701F007C704B47
-:10044000007D8881007DCCC1007E5101007E9541F8
-:10045000007C9082007CD4C2007C848B009AC00314
-:10046000007C8C8B002C88010098809E00D4006D4D
-:100470000098409C00D4006E00CC084C00CC0C4D81
-:1004800000CC104800D4801A00D4C01A00800101AA
-:1004900000D5001A00CC083200D40032009482D972
-:1004A00000CA0C0000D4401E0080000000D4001ED2
-:1004B00000E4011E00D4001E00CA080000CA0C009F
-:1004C00000CA100000D4401E00CA140000D4801ED0
-:1004D00000D4C01E00D5001E00D5401E00D54034FB
-:1004E0000080000000EE001E0028040400E2001A54
-:1004F00000E2001A00D4401A00CA380000CC0803F9
-:1005000000CC0C0300CC0C0300CC0C03009882BD83
-:1005100000000000008401BB00D7A06F0080000035
-:1005200000EE001F00CA040000C2FF0000CC083427
-:1005300000C13FFF007C74CB007CC90B007D010F24
-:10054000009902B0007C738B008401BB00D7A06FC0
-:100550000080000000EE001F00CA080000281900FB
-:10056000007D898B009580140028140400CA0C00BB
-:1005700000CA100000CA1C0000CA240000E2001FCC
-:1005800000D4C01A00D5001A00D5401A00CC1803B8
-:1005900000CC2C0300CC2C0300CC2C03007DA58BBD
-:1005A000007D9C4700984297000000000080016198
-:1005B00000D4C01A00D4401E00D4801E0080000069
-:1005C00000EE001E00E4011E00D4001E00D4401EF8
-:1005D00000EE001E00CA040000A00000007E828B16
-:1005E00000E4013E00D4001E00D4401E00EE001EB8
-:1005F00000CA040000A00000007E828B00CA080030
-:1006000000248C06000CCC060098C00600CC104ECE
-:100610000099000400D4007300E4011E00D4001E01
-:1006200000D4401E00D4801E0080000000EE001E9A
-:1006300000CA080000CA0C000034D01800251001C0
-:100640000095002100C17FFF00CA100000CA1400FD
-:1006500000CA180000D4801D00D4C01D007DB18BDD
-:1006600000C1420200C2C00100D5801D0034DC0E72
-:10067000007D5D4C007F734C00D7401E00D5001EEE
-:1006800000D5401E00C1420000C2C00000099C010C
-:100690000031DC10007F5F4C007F734C00042802A7
-:1006A000007D838000D5A86F00D5806600D7401EEE
-:1006B00000EC005E00C8240200C82402008001B8DB
-:1006C00000D6007600D4401E00D4801E00D4C01E88
-:1006D0000080000000EE001E0080000000EE001F01
-:1006E00000D4001F0080000000D4001F00D4001FB1
-:1006F0000088000000D4001F00000000000000007F
-:1007000000000000000000000000000000000000E9
-:1007100000000000000000000000000000000000D9
-:1007200000000000000000000000000000000000C9
-:1007300000000000000000000000000000000000B9
-:1007400000000000000000000000000000000000A9
-:100750000000000000000000000000000000000099
-:100760000000000000000000000000000000000089
-:100770000000000000000000000000000000000079
-:100780000000000000000000000000000000000069
-:100790000000000000000000000000000000000059
-:1007A0000000000000000000000000000000000049
-:1007B0000000000000000000000000000000000039
-:1007C0000000000000000000000000000000000029
-:1007D0000000000000000000000000000000000019
-:1007E0000000000000000000000000000000000009
-:1007F00000000000000000000000000000000000F9
-:1008000000010171000201780003008F0004007FE5
-:10081000000500030006003F000700320008012C1D
-:1008200000090046000A0036001001B6001700A2B9
-:100830000022013A00230149002000B400240125D0
-:100840000027004D0028006A002A0060002B00529B
-:10085000002F0065003200870034017F003C015604
-:10086000003F00720041018C0044012E00550173CD
-:100870000056017A0060000B00610034006200380D
-:1008800000630038006400380065003800660038F6
-:10089000006700380068003A00690041006A0048BB
-:1008A000006B0048006C0048006D0048006E004876
-:1008B000006F00480000000600000006000000066F
-:1008C0000000000600000006000000060000000610
-:1008D0000000000600000006000000060000000600
-:1008E00000000006000000060000000600000006F0
-:1008F00000000006000000060000000600000006E0
-:00000001FF
--- zfcpdump-kernel-4.4.orig/firmware/radeon/RV670_me.bin.ihex
+++ /dev/null
@@ -1,1345 +0,0 @@
-:1000000000000000C020040000000000000000000C
-:1000100000A0000A000000000000FFFF00284621A9
-:100020000000000000000000D900480000000000AF
-:1000300000000000C02004000000000000000000DC
-:1000400000A0000A000000000000000000E0000026
-:100050000000000000010000C02946200000000050
-:1000600000000000D900480000000000000000006F
-:10007000C0200400000000000000000000A0000AF2
-:10008000000000008100000000204411000000007A
-:1000900000000001002048110000000000042004BE
-:1000A000006044110000067C0000000000600000B9
-:1000B0000000062400000000006000000000063878
-:1000C00000000000C02008000000000000000F0039
-:1000D000002816220000000000000008002116255C
-:1000E000000000000000001800203625000000007D
-:1000F0008D000000002044110000000000000004FA
-:10010000002F022500000000000000000CE00000AD
-:1001100000000018004120000040481100000019B4
-:100120000042200000204811000000008E00000066
-:1001300000204411000000000000002800204A2D8B
-:1001400000000000900000000020441100000000AA
-:100150000000000000204805000000000000000C26
-:1001600000211622000000000000000300281625D0
-:10017000000000000000001900211A220000000009
-:100180000000000400281A26000000000000000003
-:10019000002914C5000000000000001900203625C9
-:1001A0000000000000000000003A140200000000FF
-:1001B00000000016002116250000000000000003CA
-:1001C00000281625000000000000001700200E2D5A
-:1001D00000000000FFFFFFFC00280E2300000000CD
-:1001E00000000000002914A3000000000000001718
-:1001F00000203625000000000000800000280E22AC
-:10020000000000000000000700220E230000000094
-:10021000000000000029386E0000000020000000EF
-:1002200000280E22000000000000000600210E231E
-:1002300000000000000000000029386E00000000EF
-:100240000000000000220222000000000000000068
-:1002500014E0000000000038000000002EE0000064
-:1002600000000035000000002CE000000000003716
-:100270000000000000400E2D0000003900000008C2
-:1002800000200E2D00000000000000090040122D8B
-:10029000000000460000000100400E2D0000003963
-:1002A00000000000C0200C0000000000003FFFFC28
-:1002B0000028122300000000000000020022122487
-:1002C000000000000000001F00211E2300000000AD
-:1002D0000000000014E000000000003E00000008E4
-:1002E00000401C11000000410000000D00201E2DE8
-:1002F000000000000000000F00281E270000000082
-:100300000000000300221E27000000007FC0000044
-:1003100000281A23000000000000001400211A2603
-:10032000000000000000000100331A260000000059
-:100330000000000800221A26000000000000000053
-:1003400000290CC700000000000000270020362410
-:100350000000000000007F000028122100000000C3
-:1003600000001400002F0224000000000000000024
-:100370000CE000000000004B0000000100290E23EB
-:10038000000000000000000E0020362300000000E6
-:100390000000E0000020441100000000FFF8000011
-:1003A00000294A230000000000000000003A2C024F
-:1003B000000000000000000200220E2B00000000E0
-:1003C000FC00000000280E23000000000000000FC9
-:1003D000002036230000000000001FFF00294A23F0
-:1003E000000000000000002700204A2D000000004F
-:1003F000000000000020481100000000000000295B
-:1004000000200E2D00000000060A020000294A23E9
-:100410000000000000000000002048110000000063
-:100420000000000000204811000000000000000152
-:1004300000210222000000000000000014E0000083
-:1004400000000061000000002EE000000000005FDE
-:10045000000000002CE000000000005E0000000032
-:1004600000400E2D000000620000000100400E2D33
-:10047000000000620000000A00200E2D00000000B5
-:100480000000000B0040122D0000006A0000000078
-:10049000C0200C0000000000003FFFFC00281223D9
-:1004A00000000000000000020022122400000000F2
-:1004B0007FC0000000281623000000000000001488
-:1004C0000021162500000000000000010033162561
-:1004D000000000008000000000280E230000000043
-:1004E0000000000000290CA3000000003FFFFC00FA
-:1004F00000290E23000000000000001F00211E2321
-:10050000000000000000000014E000000000006D8A
-:100510000000010000401C11000000700000000DF0
-:1005200000201E2D00000000000000F000281E2703
-:10053000000000000000000400221E270000000050
-:100540008100000000204411000000000000000DA8
-:100550000020481100000000FFFFF0FF00281A30C3
-:10056000000000000000A02800204411000000004E
-:1005700000000000002948E6000000000000A0186C
-:1005800000204411000000003FFFFFFF00284A2325
-:10059000000000000000A010002044110000000036
-:1005A00000000000002048040000000000000030AF
-:1005B0000020162D00000000000000020029162572
-:1005C0000000000000000030002036250000000080
-:1005D000000000250020162D000000000000000093
-:1005E000002F00A300000000000000000CC000006D
-:1005F00000000083000000260020162D00000000EF
-:1006000000000000002F00A4000000000000000017
-:100610000CC000000000008400000000004000004A
-:100620000000008A000000250020362300000000A2
-:100630000000002600203624000000000000001703
-:1006400000201E2D000000000000000200210227F3
-:10065000000000000000000014E000000000008A1C
-:1006600000000000006000000000065900000000CB
-:10067000006000000000064D0000000200210E2274
-:10068000000000000000000014C000000000008D09
-:1006900000000012C040362000000093000000005F
-:1006A0002EE0000000000091000000002CE000009F
-:1006B000000000900000000200400E2D000000929B
-:1006C0000000000300400E2D000000920000000C0E
-:1006D00000200E2D00000000000000120020362334
-:1006E000000000000000000300210E2200000000B6
-:1006F0000000000014C00000000000980000A00CE2
-:10070000002044110000000000000000C02048004C
-:100710000000000000000000C0404800000000A0F1
-:100720000000A00C002044110000000000000000A8
-:100730000020481100000000000000002EE0000032
-:100740000000009E000000002CE000000000009D62
-:100750000000000200400E2D0000009F000000037A
-:1007600000400E2D0000009F0000000C00200E2D08
-:10077000000000000000000000204803000000000E
-:1007800000000000003A0C0200000000003F0000E2
-:1007900000280E23000000000000001000210E239E
-:1007A00000000000000000110020362300000000BF
-:1007B0000000001E0021022B0000000000000000CD
-:1007C00014C00000000000A700000016C020362062
-:1007D000000000000000001F0021022B00000000AC
-:1007E0000000000014C00000000000AA0000001576
-:1007F000C0203620000000000000000800210E2B61
-:10080000000000000000007F00280E230000000010
-:1008100000000000002F0223000000000000000084
-:100820000CE00000000000E10000000027000000D4
-:10083000000000000000000000600000000002A3B3
-:1008400000000001002F0223000000000000000053
-:100850000AE00000000000B300000000006000009B
-:100860000000013A81000000002044110000000057
-:100870000000000600204811000000000000000CED
-:1008800000221E300000000099800000002044116A
-:1008900000000000000000040020122D00000000F5
-:1008A00000000008002212240000000000000010D8
-:1008B00000201811000000000000000000291CE4C6
-:1008C0000000000000000000006048070000012F49
-:1008D0009B00000000204411000000000000000008
-:1008E00000204802000000009C000000002044118D
-:1008F00000000000000000000033146F0000000042
-:100900000000000100333E23000000000000000052
-:10091000D9004800000000000000000000203C0555
-:1009200000000000810000000020441100000000D1
-:100930000000000E00204811000000000000000030
-:1009400000201010000000000000E007002044110B
-:10095000000000000000000F0021022B000000003A
-:100960000000000014C00000000000CB00F8FF08E9
-:1009700000204811000000009800000000404811CD
-:10098000000000DC000000F000280E220000000043
-:10099000000000A0002F0223000000000000000063
-:1009A0000CC00000000000DA0000001100200E2D35
-:1009B0000000000000000001002F022300000000E2
-:1009C000000000000CE00000000000D50000000264
-:1009D000002F022300000000000000000CE00000D7
-:1009E000000000D400003F0000400C11000000D6C1
-:1009F00000001F0000400C11000000D600000F0096
-:100A000000200C11000000000038000900294A23D2
-:100A1000000000003F00000000280E2B0000000036
-:100A20000000000200220E2300000000000000076A
-:100A300000494A23000000DC00380F09002048115B
-:100A400000000000680000070020481100000000BE
-:100A50000000000800214A270000000000000000FC
-:100A60000020481100000000060A020000294A2464
-:100A700000000000000000000020481100000000FD
-:100A80000000000000204811000000000000A20249
-:100A9000002044110000000000FF000000280E228A
-:100AA000000000000000008000294A230000000030
-:100AB0000000002700200E2D00000000000000268E
-:100AC0000020122D0000000000000000002F008315
-:100AD00000000000000000000CE00000000000EA40
-:100AE000000000000060000000000653000000004D
-:100AF00000400000000000EB00000000006000006B
-:100B000000000656000000070020222D0000000013
-:100B10000000000500220E2200000000001000006E
-:100B200000280E23000000000000000000292068BB
-:100B30000000000000000000003A0C02000000006D
-:100B4000000000EF00280E2300000000000000005D
-:100B500000292068000000000000001700200E2D72
-:100B6000000000000000000300210223000000003C
-:100B70000000000014E00000000000F80000000B7E
-:100B800000210228000000000000000014C0000046
-:100B9000000000F8000004000029222800000000E6
-:100BA0000000001400203628000000000000001C97
-:100BB00000210E22000000000000000014C0000010
-:100BC000000000FD0000A30C002044110000000004
-:100BD0000000000000204811000000000000001E7E
-:100BE00000210E22000000000000000014C00000E0
-:100BF0000000010B0000A30F0020441100000000C2
-:100C00000000001100200E2D000000000000000177
-:100C1000002F022300000000000000000CC00000B4
-:100C200000000104FFFFFFFF004048110000010B1E
-:100C300000000002002F022300000000000000005E
-:100C40000CC00000000001070000FFFF0040481139
-:100C50000000010B00000004002F02230000000030
-:100C6000000000000CC000000000010A000000FFAE
-:100C7000004048110000010B000000010020481155
-:100C8000000000000002C400002044110000000029
-:100C90000000001F00210E220000000000000000E4
-:100CA00014C00000000001120000001040210E20BE
-:100CB00000000000000000130020362300000000A8
-:100CC0000000001840224A20000000000000001030
-:100CD000C0424A20000001140000000000200C1156
-:100CE0000000000000000013002036230000000078
-:100CF000000000000020481100000000000000007B
-:100D000000204811000000000000000A002010111F
-:100D10000000000000000000002F0224000000007E
-:100D2000000000000CE000000000011B00000000BB
-:100D300000204811000000000000000100531224B0
-:100D400000000117FFBFFFFF00283A2E000000003F
-:100D50000000001B00210222000000000000000033
-:100D600014C000000000012E81000000002044118A
-:100D7000000000000000000D0020481100000000ED
-:100D80000000001800220E3000000000FC000000EF
-:100D900000280E2300000000810000000020441104
-:100DA000000000000000000E0020481100000000BC
-:100DB0000000000000201010000000000000E00E05
-:100DC000002044110000000007F8FF08002048112F
-:100DD000000000000000000000294A23000000007D
-:100DE0000000001C00201E2D000000000000000874
-:100DF00000214A27000000000000000000204811E8
-:100E000000000000060A020000294A240000000039
-:100E10000000000000204811000000000000000059
-:100E200000204811000000000000000000800000C9
-:100E300000000000810000000020441100000000BC
-:100E40000000000100204811000000000000217C8B
-:100E50000020441100000000008000000020481124
-:100E60000000000000000000002048060000000014
-:100E70000000000800214A270000000000000000D8
-:100E800017000000000000000004217F00604411F2
-:100E90000000067C0000001F00210230000000005E
-:100EA0000000000014C000000000067B00000004E9
-:100EB00000404C1100000135810000000020441169
-:100EC00000000000000000010020481100000000A8
-:100ED000000021F800204411000000000000001C68
-:100EE0000020481100000000000421F900604411B6
-:100EF0000000067C0000001100210230000000000C
-:100F00000000000014E000000000013C00000000B0
-:100F100000800000000000000000000000600000F1
-:100F20000000000B00000000006004110000031529
-:100F3000000000000020041100000000000000007C
-:100F400000600811000001B2000000000060000015
-:100F5000000001600000FFFF40280E20000000009C
-:100F600000000010C0211220000000000000FFFF60
-:100F7000402806200000000000000010C0210A20C8
-:100F800000000000000000000034146100000000B8
-:100F90000000000000741882000002BB0001A1FDE7
-:100FA00000604411000002E000003FFF002F022F0C
-:100FB00000000000000000000CC00000000001471D
-:100FC00000000000C040040000000001000000001C
-:100FD000006000000000000B000000000060041131
-:100FE00000000315000000000020041100000000B4
-:100FF0000000000000600811000001B200003FFF87
-:10100000002F022F00000000000000000CE0000094
-:10101000000000000000000000600000000001600F
-:101020000000001040210E20000000000000FFFF23
-:10103000C0281220000000000000001040211620EF
-:10104000000000000000FFFFC0681A20000002BB83
-:101050000001A1FD00604411000002E000003FFF1C
-:10106000002F022F00000000000000000CC0000054
-:101070000000015800000000C04004000000000112
-:101080000000225C0020441100000000000000016C
-:1010900000300A2F000000000000000100210A2299
-:1010A000000000000000000300384A220000000099
-:1010B0000000225600204411000000000000001A29
-:1010C00000204811000000000000A1FC0020441195
-:1010D0000000000000000001008048110000000036
-:1010E00000000000006000000000000B0000000095
-:1010F000006000000000018F0000000000600000A0
-:10110000000001A000003FFF002F022F00000000A0
-:10111000000000000CE000000000000000000000E3
-:1011200000202C0800000000000000000020241116
-:101130000000000000000000002028110000000056
-:10114000000022560020441100000000000000169C
-:1011500000204811000000000000225C0020441123
-:101160000000000000000003002048110000000003
-:1011700093800000002044110000000000000002E5
-:1011800000221E290000000000000000007048EB53
-:101190000000019C0000000000600000000002BB95
-:1011A00000000001403306200000000000000000A5
-:1011B000C03024090000000000003FFF002F022F74
-:1011C00000000000000000000CE000000000000033
-:1011D0000000000000600000000002A3000000000A
-:1011E000002F022100000000000000000AE00000C3
-:1011F0000000018100000000006000000000013AD2
-:101200000000000000400000000001869500000082
-:10121000002044110000000000000000002F022107
-:1012200000000000000000000CE00000000001864B
-:1012300000000000C0204800000000000000000185
-:10124000005306210000018292000000002044119A
-:101250000000000000000000C0604800000001978E
-:101260000001A1FD00204411000000000000001159
-:101270000020062D00000000000000000078042A75
-:10128000000002FB00000000002028090000000010
-:1012900000003FFF002F022F0000000000000000B0
-:1012A0000CC000000000017400000000C0400400F9
-:1012B000000000010000021000600411000003158E
-:1012C00000003FFF002F022F000000000000000080
-:1012D0000CE000000000019400000015C020362042
-:1012E0000000000000000016C020362000000000B2
-:1012F0003F800000002004110000000046000000B4
-:1013000000600811000001B2000000000080000031
-:10131000000000000000A1FC0020441100000000BB
-:1013200000003FFF002F022F00000000000000001F
-:101330000CC000000000019B00000001008048116B
-:1013400000000000000000210080481100000000A3
-:101350000000FFFF40280E200000000000000010E9
-:10136000C0211220000000000000FFFF40281620CE
-:101370000000000000000010C0811A2000000000E2
-:101380008100000000204411000000000000000661
-:1013900000204811000000000000000800221E305C
-:1013A000000000000000002900201A2D00000000AD
-:1013B0000000E0000020441100000000FFFBFF09D6
-:1013C00000204811000000000000000F0020222D26
-:1013D0000000000000001FFF00294A280000000054
-:1013E000000000060020222D000000000000000088
-:1013F000002920E80000000000000000002048084C
-:101400000000000000000000002048110000000063
-:10141000060A020000294A26000000000000000021
-:1014200000204811000000000000000000204811CA
-:101430000000000000000100002018110000000062
-:101440000000000800621E280000012F00000008B4
-:1014500000822228000000000002C0000020441189
-:10146000000000000000001500600E2D000001BD0E
-:101470000000001600600E2D000001BD0000C00835
-:1014800000204411000000000000001700200E2D75
-:10149000000000000000000014C00000000001B9BE
-:1014A0000000000000200411000000000000000007
-:1014B0000020480100000000390000000020481111
-:1014C00000000000000000000020481100000000A3
-:1014D000000000000080480200000000000000182A
-:1014E00000202E2D0000000000000000003B0D63D6
-:1014F000000000000000000800224A230000000055
-:101500000000001000224A23000000000000001824
-:1015100000224A2300000000000000000080480371
-:101520000000000000000000006000000000000B50
-:10153000000010000060041100000315000000000E
-:1015400000200411000000000000000000600811ED
-:10155000000001B2000000070021062F000000007B
-:101560000000001300200A2D000000000000000110
-:1015700000202C11000000000000FFFF4028222066
-:10158000000000000000000F0026222800000000DC
-:101590000000001040212620000000000000000F85
-:1015A000002626290000000000000000002028027C
-:1015B000000000000000225600204411000000003E
-:1015C0000000001B00204811000000000000000087
-:1015D000002F022100000000000000000CE00000CD
-:1015E000000001E00000225C002044110000000027
-:1015F0000000008100204811000000000000A1FC54
-:1016000000204411000000000000000100204811EB
-:10161000000000000000008000201C1100000000FD
-:1016200000000000002F0227000000000000000062
-:101630000CE00000000001DC000000000060000081
-:10164000000001E90000000100531E27000001D83E
-:101650000000000100202C11000000000000001F0D
-:1016600000280A22000000000000001F00282A2A8B
-:10167000000000000000000100530621000001D11D
-:101680000000225C00204411000000000000000265
-:1016900000304A2F000000000000A1FC002044118F
-:1016A00000000000000000010020481100000000C0
-:1016B0000000000100301E2F0000000000000000AC
-:1016C000002F022700000000000000000CE00000D6
-:1016D000000000000000000000600000000001E9C0
-:1016E0000000000100531E27000001E50000FFFF7D
-:1016F00040280E20000000000000000F00260E23EE
-:101700000000000000000010C021122000000000B6
-:101710000000000F0026122400000000000000005E
-:1017200000201411000000000000000000601811EB
-:10173000000002BB0001A1FD0020441100000000D8
-:1017400000000000002F022B00000000000000003D
-:101750000CE00000000001F8000000100022162834
-:1017600000000000FFFF0000002816250000000018
-:101770000000FFFF00281A29000000000000000000
-:10178000002948C500000000000000000020480AB1
-:10179000000000000000000000202C1100000000EC
-:1017A000000000100022162300000000FFFF0000D0
-:1017B00000281625000000000000FFFF00281A2462
-:1017C0000000000000000000002948C500000000E3
-:1017D0000000000000731503000002050000000077
-:1017E0000020180500000000000000000073152410
-:1017F0000000020500000000002D14C500000000DC
-:1018000000000000003008A20000000000000000FE
-:101810000020480200000000000000000020280214
-:101820000000000000000000002020030000000075
-:101830000000000000802404000000000000000FF1
-:1018400000210225000000000000000014C000007C
-:101850000000067B00000000002B140500000000C3
-:1018600000000001009016250000000000000000AC
-:10187000006000000000000B000000000060041188
-:10188000000003150000000000200411000000000B
-:101890000000000000600811000001B200002256A4
-:1018A00000204411000000000000001A00294A2214
-:1018B0000000000000000000C02000000000000048
-:1018C00000003FFF002F022F00000000000000007A
-:1018D0000CE000000000000000000000C020040038
-:1018E000000000000000225C002044110000000005
-:1018F0000000000300384A21000000000000A1FCA5
-:1019000000204411000000000000000100204811E8
-:10191000000000000000FFFF40281220000000002F
-:1019200000000010C0211A20000000000000FFFF8E
-:1019300040280E200000000000000010C0211620EA
-:10194000000000000000000000741465000002BBED
-:101950000001A1FD00604411000002E00000000150
-:10196000003306210000000000000000002F0221CB
-:1019700000000000000000000CC000000000021980
-:1019800000003FFF002F022F0000000000000000B9
-:101990000CC000000000021200000000C040040063
-:1019A0000000000100000000006000000000063898
-:1019B000000000000040040F0000021300000000BF
-:1019C000006000000000062400000000006000002D
-:1019D000000006380000021000600411000003152A
-:1019E0000000000000600000000001A000000000F6
-:1019F000006000000000019C00000000006000008A
-:101A0000000002BB0000000000600000000002A314
-:101A1000938000000020441100000000000000003E
-:101A2000002048080000000000000000002F022FE6
-:101A300000000000000000000AE000000000023288
-:101A400000000000006000000000013A00000000FB
-:101A50000040000000000236950000000020441104
-:101A60000000000000000000002F022F0000000016
-:101A7000000000000CE00000000002360000000042
-:101A8000C0404800000002339200000000204411D2
-:101A90000000000000000000C0204800000000001E
-:101AA0000000225600204411000000000000001633
-:101AB00000204811000000000000225C00204411BA
-:101AC000000000000000000300204811000000009A
-:101AD0000000A1FC002044110000000000000001F3
-:101AE00000204811000000000001A1FD0020441169
-:101AF000000000000000000000600411000002FB74
-:101B000000000000C04004000000000100000000D0
-:101B100000600000000006240000A00C002044111A
-:101B20000000000000000000C0204800000000008D
-:101B300000000000C040480000000000000000005D
-:101B4000006000000000000B0000001840210A2087
-:101B50000000000000000003002F0222000000002F
-:101B6000000000000AE000000000024C0000001429
-:101B70000020222D00000000000801010029222879
-:101B800000000000000000140020362800000000C3
-:101B90000000A30C00204411000000000000000021
-:101BA000C02048000000000000000000C0204800E5
-:101BB0000000000000000000C0404800000002518A
-:101BC00000000000006000000000000B000000109A
-:101BD00000600411000003153F8000000020041184
-:101BE000000000000000000000600811000001B2C9
-:101BF0000000225C002044110000000000000003EF
-:101C000000204811000000000000000000600000FB
-:101C10000000027C0000001700201E2D00000000C4
-:101C20000000000100211E2700000000000000004D
-:101C300014E000000000026A0000001200201E2DC7
-:101C4000000000000000FFFF00281E270000000029
-:101C50000000000000341C2700000000000000000D
-:101C600012C000000000025F0000000000201C11F4
-:101C70000000000000000000002F00E50000000050
-:101C80000000000008C00000000002620000000028
-:101C900000201407000000000000001200201E2D8C
-:101CA000000000000000001000211E2700000000BE
-:101CB0000000000000341C4700000000000000008D
-:101CC00012C00000000002670000000000201C118C
-:101CD0000000000000000000002F00E600000000EF
-:101CE0000000000008C000000000026A00000000C0
-:101CF0000020180700000000000000000060000045
-:101D0000000002C100002256002044110000000023
-:101D1000000000000034202300000000000000004C
-:101D200012C00000000002720000000000342044D5
-:101D3000000000000000000012C00000000002715E
-:101D40000000001600404811000002760000001854
-:101D500000404811000002760000000000342044DA
-:101D6000000000000000000012C00000000002752A
-:101D70000000001700404811000002760000001922
-:101D800000204811000000000000A1FC00204411C8
-:101D900000000000000000010020481100000000C9
-:101DA0000001A1FD00604411000002E900003FFFB6
-:101DB000002F022F00000000000000000CC00000F7
-:101DC0000000025600000000C040040000000001B6
-:101DD0000000001040210620000000000000FFFF6E
-:101DE000C0280A20000000000000001040210E2042
-:101DF000000000000000FFFFC028122000000000CB
-:101E00000000001040211620000000000000FFFF2D
-:101E1000C0881A200000000081000000002044114A
-:101E20000000000000000001002048110000000038
-:101E300000042004006044110000067C0000000043
-:101E4000006000000000062400000000C0600000E8
-:101E5000000002A30000000500200A2D0000000081
-:101E60000000000800220A22000000000000002BF1
-:101E700000201A2D000000000000001C00201E2D74
-:101E8000000000000000700000281E270000000075
-:101E90000000000000311CE6000000000000002AE5
-:101EA00000201A2D000000000000000C00221A265D
-:101EB0000000000000000000002F00E6000000000D
-:101EC0000000000006E00000000002920000000098
-:101ED00000201C11000000000000000000200C1178
-:101EE000000000000000002B00203623000000004E
-:101EF0000000001000201811000000000000000089
-:101F000000691CE20000012F9380000000204411B2
-:101F10000000000000000000002048070000000052
-:101F200095000000002044110000000000000000A7
-:101F3000002F022F00000000000000000CE0000055
-:101F40000000029D0000000100333E2F0000000051
-:101F500000000000D90048000000000092000000CE
-:101F6000002044110000000000000000C0204800D4
-:101F7000000000000000001C0040362700000000A8
-:101F80000000000CC0220A20000000000000002910
-:101F9000002036220000000000000028C04036204B
-:101FA000000000000000A2A4002044110000000076
-:101FB000000000090020481100000000A1000000FE
-:101FC00000204411000000000000000100804811C2
-:101FD000000000000000002100201E2D0000000075
-:101FE00000000000002C1CE30000000000000021A5
-:101FF00000203627000000000000002200201E2DD7
-:102000000000000000000000002C1CE400000000A4
-:1020100000000022002036270000000000000023FE
-:1020200000201E2D0000000000000000003120A351
-:102030000000000000000000002D1D07000000004F
-:1020400000000023002036270000000000000024CC
-:1020500000201E2D0000000000000000003120C400
-:102060000000000000000000002D1D07000000001F
-:10207000000000240080362700000000000000213E
-:10208000002036230000000000000022002036243B
-:10209000000000000000000000311CA30000000050
-:1020A0000000002300203627000000000000000090
-:1020B00000311CC40000000000000024008036270E
-:1020C000000000000000001A002036270000000079
-:1020D0000000001B00203628000000000000001750
-:1020E00000201E2D00000000000000020021022739
-:1020F000000000000000000014C00000000002DC2E
-:102100000000000000400000000002D90000001A9A
-:1021100000203627000000000000001B00203628A9
-:10212000000000000000001700201E2D000000002D
-:102130000000000200210227000000000000000053
-:1021400014E00000000002D9000000030021022773
-:10215000000000000000000014E00000000002DCAD
-:102160000000002300201E2D0000000000000000E1
-:10217000002E00E1000000000000000002C000008E
-:10218000000002DC0000002100201E2D00000000E5
-:1021900000000000003120A100000000000000004D
-:1021A000002E00E8000000000000000006C0000053
-:1021B000000002DC0000002400201E2D00000000B2
-:1021C00000000000002E00E20000000000000000FF
-:1021D00002C00000000002DC0000002200201E2DD2
-:1021E0000000000000000000003120C200000000DC
-:1021F00000000000002E00E80000000000000000C9
-:1022000006C00000000002DC0000000000600000CA
-:10221000000006590000000000600000000002B548
-:102220000000000000400000000002DE000000008E
-:1022300000600000000002B5000000000060000027
-:10224000000006500000000000400000000002DE18
-:102250000000000000600000000002A70000000075
-:1022600000400000000002DE0000001A00201E2DC9
-:10227000000000000000001B0080222D0000000074
-:102280000000001000221E230000000000000000DB
-:1022900000294887000000000000000000311CA356
-:1022A000000000000000001000221E2700000000B7
-:1022B0000000000000294887000000000000001016
-:1022C00000221E230000000000000000003120C496
-:1022D000000000000000FFFF00282228000000008E
-:1022E0000000000000894907000000000000001005
-:1022F00000221E2300000000000000000029488783
-:10230000000000000000001000221E21000000005C
-:102310000000000000294847000000000000000005
-:1023200000311CA3000000000000001000221E2746
-:1023300000000000000000000029488700000000A5
-:102340000000000000311CA100000000000000108F
-:1023500000221E270000000000000000002948475E
-:10236000000000000000001000221E2300000000FA
-:1023700000000000003120C4000000000000FFFF4A
-:102380000028222800000000000000000029490762
-:10239000000000000000001000221E2100000000CC
-:1023A00000000000003120C2000000000000FFFF1C
-:1023B00000282228000000000000000000894907D2
-:1023C000000000000000001000221E23000000009A
-:1023D0000000000000294887000000000000000104
-:1023E00000220A210000000000000000003308A2C3
-:1023F000000000000000001000221E22000000006B
-:102400000000001000212222000000000000000057
-:1024100000294907000000000000000000311CA353
-:10242000000000000000001000221E270000000035
-:1024300000000000002948870000000000000001A3
-:1024400000220A210000000000000000003008A265
-:10245000000000000000001000221E22000000000A
-:1024600000000010002122220000000000000000F7
-:1024700000294907000000000000001000221E2370
-:102480000000000000000000003120C40000000037
-:102490000000FFFF002822280000000000000000CC
-:1024A000002949070000000000000000003808C5AE
-:1024B00000000000000000000030084100000000A3
-:1024C0000000000100220A220000000000000000BD
-:1024D000003308A2000000000000001000221E22AD
-:1024E0000000000000000010002122220000000077
-:1024F00000000000008949070000000000000017EC
-:102500000020222D000000000000000014C0000088
-:1025100000000318FFFFFFEF002806210000000065
-:10252000000000140020222D000000000000F8E050
-:1025300000204411000000000000000000294901B3
-:1025400000000000000000000089490100000000B8
-:102550000000000000204811000000000000000002
-:102560000020481100000000060A02000080481107
-:102570000000000000000000C0200000000000007B
-:1025800097000000C020441100000000000000007F
-:10259000C0204811000000008A0000000020441103
-:1025A00000000000000000000020481100000000B2
-:1025B0000000225C00204411000000000000000028
-:1025C000C0204800000000000000A1FC00204411D1
-:1025D0000000000000000000C020480000000000D3
-:1025E00000000000C0200400000000000000000007
-:1025F00000A0000A00000000970000000020441125
-:102600000000000000000000002048110000000051
-:102610008A000000002044110000000000000000BB
-:1026200000204811000000000000225C002044113E
-:102630000000000000000000C02048000000000072
-:102640000000A1FC00204411000000000000000078
-:10265000C02048000000000000000000C02004006E
-:10266000000000000000000000A0000A00000000C0
-:10267000970000000020441100000000000000004E
-:1026800000204811000000008A00000000204411D2
-:1026900000000000000000000020481100000000C1
-:1026A0000000225C00204411000000000000000037
-:1026B000C0204800000000000000A1FC00204411E0
-:1026C0000000000000000000C020480000000000E2
-:1026D0000001A1FD002044110000000000000000E6
-:1026E000D90048000000000000000000C0200400E5
-:1026F000000000000000000000A0000A0000000030
-:1027000000002257002044110000000000000003D8
-:10271000C0484A20000000000000225D0020441153
-:102720000000000000000000C04048000000000061
-:1027300000000000006000000000063800000000FB
-:10274000C0200800000000000000225C00204411AE
-:10275000000000000000000300384A2200000000D2
-:102760000000A1FC00204411000000000000000057
-:10277000C0204800000000000001A1FD002044111D
-:102780000000000000000000002F022200000000F6
-:10279000000000000CE0000000000000000000004D
-:1027A00040204800000000000000000140304A20A6
-:1027B0000000000000000002C0304A2000000000BD
-:1027C0000000000100530A220000034B0000003FFC
-:1027D000C0280A20000000008100000000204411F1
-:1027E000000000000000000100204811000000006F
-:1027F000000021F800204411000000000000001833
-:102800000020481100000000000421F9006044117C
-:102810000000067C000000110021023000000000D2
-:102820000000000014E00000000003540000001449
-:10283000002F022200000000000000000CC0000079
-:10284000000003620001A2A4002044110000000067
-:1028500000000000006048020000036A0000210040
-:10286000002044110000000000000000C0204800CB
-:102870000000000000000000C02048000000000030
-:1028800000000000C0204800000000000000000020
-:10289000C04048000000000000000004002F022299
-:1028A00000000000000000000CC0000000000366F3
-:1028B0000001A2A40020441100000000000000005C
-:1028C000004048020000035D00000028002F0222A3
-:1028D00000000000000000000CC00000000005B374
-:1028E0000001A2A40020441100000000000000002C
-:1028F000004048020000035D0000002C0020362646
-:102900000000000000000049002018110000000035
-:102910000000003F002048110000000000000001FE
-:1029200000331A260000000000000000002F0226DD
-:1029300000000000000000000CC000000000036C5C
-:102940000000002C00801A2D000000000000003F55
-:10295000C0280A200000000000000015002F0222FD
-:1029600000000000000000000CE0000000000382F6
-:1029700000000006002F02220000000000000000FE
-:102980000CE00000000003AD00000016002F022242
-:1029900000000000000000000CE00000000003AF99
-:1029A00000000020002F02220000000000000000B4
-:1029B0000CE00000000003980000000F002F02222E
-:1029C00000000000000000000CE00000000003A474
-:1029D00000000010002F0222000000000000000094
-:1029E0000CE00000000003A40000001E002F0222E3
-:1029F00000000000000000000CE000000000038C5C
-:102A00000000A2A40020441100000000000000000B
-:102A100000404802000000000800000000290A22CF
-:102A2000000000000000000340210E200000000014
-:102A30000000000CC021122000000000000800006F
-:102A4000002812240000000000000014C0221620FC
-:102A50000000000000000000002914A40000000095
-:102A60000000A2A4002044110000000000000000AB
-:102A7000002948A2000000000000A1FE002044112F
-:102A800000000000000000000040480300000000BB
-:102A9000810000000020441100000000000000013F
-:102AA0000020481100000000000021F8002044111F
-:102AB0000000000000000016002048110000000087
-:102AC000000421F9006044110000067C000000159C
-:102AD00000210230000000000000000014E00000AF
-:102AE0000000038E0000210E0020441100000000B1
-:102AF00000000000C02048000000000000000000AE
-:102B0000C0204800000000000000A2A400204411E2
-:102B1000000000000000000000404802000000002B
-:102B200081000000002044110000000000000001AE
-:102B30000020481100000000000021F8002044118E
-:102B400000000000000000170020481100000000F5
-:102B5000000421F9006044110000067C000000031D
-:102B600000210230000000000000000014E000001E
-:102B70000000039A0000210800204411000000001A
-:102B800000000000C020480000000000000000001D
-:102B9000C0204800000000000000A2A40020441152
-:102BA000000000000000000000404802000000009B
-:102BB0000000A2A40020441100000000000000005A
-:102BC00000204802000000008000000000204411A6
-:102BD000000000000000000000204811000000007C
-:102BE00081000000002044110000000000000010DF
-:102BF000002048110000000000000000002000102C
-:102C0000000000000000000014C00000000003AA43
-:102C10000000000000400000000000000001A2A42D
-:102C20000020441100000000000000060040481190
-:102C3000000000000001A2A40020441100000000D8
-:102C400000000016006048110000036A0000000048
-:102C5000004000000000000000000000C02008004C
-:102C60000000000000000000C0200C000000000078
-:102C70000000001D002102230000000000000000F1
-:102C800014E00000000003C4810000000020441193
-:102C900000000000000000010020481100000000BA
-:102CA000000021F80020441100000000000000187E
-:102CB0000020481100000000000421F900604411C8
-:102CC0000000067C0000001100210230000000001E
-:102CD0000000000014E00000000003B80000210024
-:102CE0000020441100000000000000000020480205
-:102CF0000000000000000000002048030000000069
-:102D0000BABECAFE0020481100000000CAFEBABECA
-:102D100000204811000000000000A2A4002044117F
-:102D20000000000000000004004048110000000006
-:102D3000000021700020441100000000000000008D
-:102D400000204802000000000000000000204803AE
-:102D5000000000008100000000204411000000007D
-:102D60000000000A002048110000000000000000E0
-:102D700000200010000000000000000014C000004F
-:102D8000000003C98C000000002044110000000076
-:102D9000CAFEBABE004048110000000081000000D9
-:102DA0000020441100000000000000010020481134
-:102DB0000000000000003FFF40280A200000000043
-:102DC0008000000040280E200000000040000000AD
-:102DD000C028122000000000000400000069462204
-:102DE0000000067C0000000000201410000000001D
-:102DF00000000000002F022300000000000000007F
-:102E00000CC00000000003D700000000C040180004
-:102E1000000003DA00003FFFC0281A200000000075
-:102E200000040000006946260000067C0000000047
-:102E3000002018100000000000000000002F0224F5
-:102E400000000000000000000CC00000000003DDD6
-:102E500000000000C0401C00000003E000003FFF35
-:102E6000C0281E2000000000000400000069462762
-:102E70000000067C0000000000201C100000000084
-:102E800000000000002044020000000000000000DC
-:102E9000002820C50000000000000000004948E8AC
-:102EA00000000000A58000000020081100000000C4
-:102EB0000000200000200C11000000008300000032
-:102EC00000604411000004080000000000204402DB
-:102ED0000000000000000000C020480000000000CA
-:102EE0000000000040204800000000000000001F1B
-:102EF000C0210220000000000000000014C00000FB
-:102F0000000003ED0000201000204411000000002C
-:102F10000000800000204811000000000000FFFFBA
-:102F2000C0481220000003F5A7800000002008110F
-:102F3000000000000000A00000200C1100000000B4
-:102F4000830000000060441100000408000000003D
-:102F5000002044020000000000000000C0204800E3
-:102F60000000000000000000C02048000000000039
-:102F70000000FFFFC02812200000000083000000B6
-:102F800000204411000000000000000000304883D1
-:102F90000000000084000000002044110000000038
-:102FA00000000000C02048000000000000000000F9
-:102FB0001D000000000000008300000000604411BC
-:102FC0000000040800000000C040040000000001F0
-:102FD000A980000000200811000000000000C000CF
-:102FE00000400C11000003F0AB800000002008112D
-:102FF000000000000000F8E000400C11000003F0A9
-:10300000AD80000000200811000000000000F880E2
-:1030100000400C11000003F0B380000000200811F4
-:10302000000000000000F3FC00400C11000003F061
-:10303000AF80000000200811000000000000E00048
-:1030400000400C11000003F0B180000000200811C6
-:10305000000000000000F00000400C11000003F030
-:1030600083000000002044110000000000002148FF
-:1030700000204811000000008400000000204411DE
-:103080000000000000000000C02048000000000018
-:10309000000000001D000000000000000000000013
-:1030A000008000000000000001182000C030462011
-:1030B0000000000000000000D900480000000000EF
-:1030C00000000000C020040000000000000000001C
-:1030D00000A0000A000000000218A000C030462036
-:1030E0000000000000000000D900480000000000BF
-:1030F00000000000C02004000000000000000000EC
-:1031000000A0000A000000000318C000C0304620E4
-:103110000000000000000000D9004800000000008E
-:1031200000000000C02004000000000000000000BB
-:1031300000A0000A000000000418F8E0C03046209B
-:103140000000000000000000D9004800000000005E
-:1031500000000000C020040000000000000000008B
-:1031600000A0000A000000000518F880C0304620CA
-:103170000000000000000000D9004800000000002E
-:1031800000000000C020040000000000000000005B
-:1031900000A0000A000000000618E000C030462031
-:1031A0000000000000000000D900480000000000FE
-:1031B00000000000C020040000000000000000002B
-:1031C00000A0000A000000000718F000C0304620F0
-:1031D0000000000000000000D900480000000000CE
-:1031E00000000000C02004000000000000000000FB
-:1031F00000A0000A000000000818F3FCC0304620C0
-:103200000000000000000000D9004800000000009D
-:1032100000000000C02004000000000000000000CA
-:1032200000A0000A000000000000003000200A2D6D
-:103230000000000000000000C0290C400000000059
-:1032400000000030002036230000000000000000D5
-:10325000C0200400000000000000000000A0000AE0
-:103260000000000086000000002044110000000063
-:103270000000000000404801000000008500000040
-:10328000C020441100000000000000000040480180
-:10329000000000000000217C00204411000000001C
-:1032A00000000000C02048000000000000000000F6
-:1032B000C02048000000000000000000C0204800BE
-:1032C0000000000081000000002044110000000008
-:1032D0000000000100204811000000000000000074
-:1032E000C0200800000000000000000017000000DF
-:1032F000000000000004217F006044110000067CF3
-:103300000000001F0021023000000000000000004B
-:1033100014C00000000000000000000000404C024B
-:103320000000043E00000000C0200C00000000006F
-:1033300000000000C020100000000000000000009D
-:10334000C02014000000000000000000C020180091
-:103350000000000000000000C0201C000000000071
-:1033600000007F0000280A21000000000000450046
-:10337000002F022200000000000000000CE000000E
-:103380000000044C00000000C020200000000000ED
-:103390000000000017000000000000000000001006
-:1033A00000280A230000000000000010002F022265
-:1033B00000000000000000000CE0000000000454C9
-:1033C0008100000000204411000000000000000106
-:1033D000002048110000000000040000006946249D
-:1033E0000000067C000000000040000000000459BE
-:1033F00081000000002044110000000000000000D7
-:1034000000204811000000000000216D0020441140
-:103410000000000000000000002048040000000040
-:103420000000000000604805000006810000000068
-:10343000002824F0000000000000000700280A23F4
-:103440000000000000000001002F02220000000028
-:10345000000000000AE0000000000460000000001E
-:10346000002F00C9000000000000000004E0000080
-:103470000000047900000000004000000000048605
-:1034800000000002002F02220000000000000000E7
-:103490000AE000000000046500000000002F00C9E1
-:1034A000000000000000000002E0000000000479BD
-:1034B000000000000040000000000486000000033F
-:1034C000002F022200000000000000000AE00000BF
-:1034D0000000046A00000000002F00C90000000086
-:1034E000000000000CE00000000004790000000073
-:1034F000004000000000048600000004002F0222AB
-:1035000000000000000000000AE000000000046F5E
-:1035100000000000002F00C90000000000000000B3
-:103520000AE00000000004790000000000400000F4
-:103530000000048600000005002F022200000000A9
-:10354000000000000AE00000000004740000000019
-:10355000002F00C9000000000000000006E000008D
-:103560000000047900000000004000000000048614
-:1035700000000006002F02220000000000000000F2
-:103580000AE000000000047900000000002F00C9DC
-:10359000000000000000000008E0000000000479C6
-:1035A00000000000004000000000048600007F00D2
-:1035B00000280A210000000000004500002F022220
-:1035C00000000000000000000AE000000000000011
-:1035D0000000000800210A23000000000000000095
-:1035E00014C0000000000483000021690020441181
-:1035F0000000000000000000C020480000000000A3
-:1036000000000000C0204800000000000000000092
-:10361000C020480000000000CAFEBABE00404811A9
-:103620000000000000000000C02044000000000076
-:1036300000000000C02000000000000000000000AA
-:10364000C04048000000000000007F0000280A2160
-:103650000000000000004500002F022200000000D2
-:10366000000000000AE000000000048C00000000E0
-:10367000C02000000000000000000000C02000008A
-:103680000000000000000000C0400000000000003A
-:103690000000000000404C080000044C0000000046
-:1036A000C0200800000000000000001040210E2093
-:1036B0000000000000000011402112200000000066
-:1036C00000000012402116200000000000002169C7
-:1036D000002044110000000000000000002048020B
-:1036E0000000000000000000002102250000000092
-:1036F0000000000014E00000000004960004000038
-:10370000C0494A2000000497FFFBFFFFC0284A2061
-:103710000000000000000000002102230000000063
-:103720000000000014E00000000004A300000000FE
-:10373000C02048000000000000000000C020480039
-:103740000000000000000000002102240000000032
-:103750000000000014C00000000000008100000014
-:1037600000204411000000000000000C002048115F
-:103770000000000000000000002000100000000019
-:103780000000000014C000000000049FA000000022
-:103790000020441100000000CAFEBABE00404811DB
-:1037A0000000000081000000002044110000000023
-:1037B0000000000400204811000000000000216B00
-:1037C000002044110000000000000000C02048104C
-:1037D00000000000810000000020441100000000F3
-:1037E0000000000500204811000000000000216CCE
-:1037F000002044110000000000000000C02048101C
-:103800000000000000000000002F02240000000063
-:10381000000000000CE000000000000000000000BC
-:10382000004000000000049D00000000C0210A20AC
-:10383000000000000000000014C00000000004B6FA
-:103840008100000000204411000000000000000082
-:1038500000204811000000000000216D00204411EC
-:103860000000000000000000C02048000000000030
-:1038700000000000C0604800000006810000000059
-:1038800000400000000004BA810000000020441144
-:1038900000000000000000010020481100000000AE
-:1038A00000040000C02946200000000000000000C5
-:1038B000C06000000000067C000000010021022220
-:1038C000000000000000000014C00000000004C15F
-:1038D00000002169002044110000000000000000E9
-:1038E000C02048000000000000000000C020480088
-:1038F0000000000000000000002048100000000050
-:10390000CAFEBABE004048110000000000000000DE
-:10391000C02044000000000000000000C04048102B
-:1039200000000000810000000020441100000000A1
-:10393000000000010020481100000000000021F8F4
-:1039400000204411000000000000000E002048117B
-:1039500000000000000421F9006044110000067C12
-:103960000000000000210230000000000000000004
-:1039700014C00000000004C3000021800020441196
-:103980000000000000000000C0204800000000000F
-:1039900000000000C0200000000000000000000047
-:1039A000C02048000000000000000000C02000000F
-:1039B0000000000000000000C040480000000000BF
-:1039C0000000000300333E2F000000000000000153
-:1039D00000210221000000000000000014E00000AF
-:1039E000000004F30000002C00200A2D000000005D
-:1039F0000004000018E00C11000004E200000001C7
-:103A000000333E2F00000000000021690020441117
-:103A1000000000000000000000204802000000003C
-:103A20000000000000204803000000000000000823
-:103A300000300A220000000000000000C020480002
-:103A40000000000000000000C0204800000000004E
-:103A50000000216900204411000000000000000067
-:103A60000020480200000000000000000020480381
-:103A7000000000000000000800300A2200000000E2
-:103A800000000000C020480000000000000000000E
-:103A9000D8C04800000004D600002169002044116D
-:103AA00000000000000000000020480200000000AC
-:103AB0000000000000204803000000000000000893
-:103AC00000300A220000000000000000C020480072
-:103AD0000000000000000000C020480000000000BE
-:103AE0000000002D0020122D00000000000000004A
-:103AF00000290C830000000000002169002044110F
-:103B0000000000000000000000204802000000004B
-:103B10000000000000204803000000000000000832
-:103B200000300A220000000000000000C020480011
-:103B30000000000000000000C0204800000000005D
-:103B4000000000110021022400000000000000001D
-:103B500014C0000000000000000000000040000051
-:103B60000000049D0000002CC02036200000000052
-:103B70000000002DC0403620000000000000000FB3
-:103B800000210221000000000000000014C000001D
-:103B9000000004F800000000006000000000000BBE
-:103BA00000000000D900000000000000000000003C
-:103BB000C040040000000001B500000000204411D6
-:103BC000000000000000200000204811000000005C
-:103BD000B600000000204411000000000000A0001A
-:103BE0000020481100000000B70000000020441130
-:103BF000000000000000C00000204811000000008C
-:103C0000B800000000204411000000000000F8E0AF
-:103C10000020481100000000B900000000204411FD
-:103C2000000000000000F8800020481100000000A3
-:103C3000BA00000000204411000000000000E00075
-:103C40000020481100000000BB00000000204411CB
-:103C5000000000000000F0000020481100000000FB
-:103C6000BC00000000204411000000000000F3FC34
-:103C700000204811000000008100000000204411D5
-:103C800000000000000000020020481100000000B9
-:103C9000000000FF00280E300000000000000000BF
-:103CA000002F022300000000000000000CC00000F4
-:103CB0000000050C00000000C0200800000000000B
-:103CC0000000000014C000000000052100000000FA
-:103CD00000200C11000000000000001C0020362312
-:103CE000000000000000002B002036230000000030
-:103CF00000000029002036230000000000000028FA
-:103D000000203623000000000000001700203623AA
-:103D10000000000000000025002036230000000005
-:103D200000000026002036230000000000000015DF
-:103D3000002036230000000000000016002036237B
-:103D400000000000FFFFE00000200C110000000058
-:103D500000000021002036230000000000000022A7
-:103D6000002036230000000000001FFF00200C117F
-:103D700000000000000000230020362300000000A7
-:103D8000000000240020362300000000F1FFFFFFA8
-:103D900000283A2E000000000000001AC0220E2069
-:103DA00000000000000000000029386E0000000044
-:103DB0008100000000204411000000000000000607
-:103DC00000204811000000000000002A402036209A
-:103DD00000000000870000000020441100000000E7
-:103DE00000000000C0204800000000000000A1F416
-:103DF00000204411000000000000000000204810D6
-:103E0000000000000000000000200C110000000075
-:103E10000000003000203623000000009D0000005C
-:103E200000204411000000000000001F40214A2033
-:103E30000000000096000000002044110000000077
-:103E400000000000C020480000000000000000004A
-:103E5000C0200C000000000000000000C020100086
-:103E6000000000000000001F0021162400000000D8
-:103E70000000000014C00000000000000000001D51
-:103E800000203623000000000000000300281E234D
-:103E900000000000000000080022222300000000B3
-:103EA000FFFFF000002822280000000000000000B2
-:103EB000002920E8000000000000001F0020362834
-:103EC000000000000000001800211E230000000078
-:103ED0000000002000203627000000000000000243
-:103EE000002216240000000000000000003014A88A
-:103EF000000000000000001E002036250000000029
-:103F00000000000300211A2400000000100000003F
-:103F100000281A2600000000EFFFFFFF00283A2EBD
-:103F20000000000000000000004938CE0000066AD2
-:103F30000000000140280A200000000000000006E8
-:103F400040280E200000000000000300C0281220BE
-:103F50000000000000000008002112240000000002
-:103F600000000000C020162000000000000000003B
-:103F7000C0201A20000000000000000000210222E2
-:103F8000000000000000000014C0000000000559FF
-:103F9000810000000020441100000000000000012A
-:103FA00000204811000000000000225800300A24C0
-:103FB0000000000000040000006946220000067CAA
-:103FC00000002169002044110000000000000000F2
-:103FD00000204805000000000002000000294A26D9
-:103FE0000000000000000000002048100000000059
-:103FF000CAFEBABE00204811000000000000000206
-:10400000002F022300000000000000000CC0000090
-:104010000000056100000000C0201C10000000002E
-:1040200000000000C04000000000056F000000021A
-:10403000002F022300000000000000000CC0000060
-:104040000000056181000000002044110000000014
-:10405000000000010020481100000000000022586C
-:1040600000300A240000000000040000006946221D
-:104070000000067C00000000C0201C1000000000B2
-:1040800000000000C04000000000056F00000000BC
-:10409000002F022300000000000000000CC0000000
-:1040A0000000056500000000C0201C0000000000AA
-:1040B00000000000C04000000000056F0000000488
-:1040C000002F022300000000000000000CC00000D0
-:1040D0000000056D81000000002044110000000078
-:1040E0000000000000204811000000000000216DC9
-:1040F000002044110000000000000000C020480023
-:104100000000000000000000C060480000000681C0
-:104110000000000000401C100000056F00000000BF
-:10412000C02000000000000000000000C0400000AF
-:1041300000000000000000000EE00000000005711B
-:104140000000000000600000000005BC000000004E
-:10415000002F022400000000000000000CC000003E
-:10416000000005820000A2B70020441100000000FA
-:10417000000000000020480700000000810000004F
-:104180000020441100000000000000010020481140
-:10419000000000000004A2B6006044110000067C8C
-:1041A0000000001A0021223000000000000000067C
-:1041B00000222630000000000004200400604411AA
-:1041C0000000067C0000A2C4002044110000000092
-:1041D00000000000003048E900000000000000007E
-:1041E00000E00000000005800000A2D10020441182
-:1041F000000000000000000000404808000000002F
-:104200000000A2D1002044110000000000000001C5
-:1042100000504A280000000000000001002F022486
-:1042200000000000000000000CC00000000005932A
-:104230000000A2BB002044110000000000000000AC
-:104240000020480700000000810000000020441109
-:1042500000000000000000010020481100000000E4
-:104260000004A2BA006044110000067C0000001A9D
-:10427000002122300000000000000006002226304D
-:104280000000000000042004006044110000067CCF
-:104290000000A2C500204411000000000000000042
-:1042A000003048E9000000000000000000E00000CD
-:1042B000000005910000A2D200204411000000007F
-:1042C0000000000000404808000000000000A2D2EA
-:1042D00000204411000000000000000100504A28A6
-:1042E0000000000000000002002F02240000000077
-:1042F000000000000CC00000000005A40000A2BFE8
-:1043000000204411000000000000000000204807C9
-:1043100000000000810000000020441100000000A7
-:104320000000000100204811000000000004A2BEAF
-:10433000006044110000067C0000001A00212230B9
-:1043400000000000000000060022263000000000EF
-:1043500000042004006044110000067C0000A2C696
-:10436000002044110000000000000000003048E977
-:10437000000000000000000000E00000000005A2B6
-:104380000000A2D300204411000000000000000043
-:1043900000404808000000000000A2D300204411A3
-:1043A000000000000000000100504A28000000004A
-:1043B0000000A2C300204411000000000000000023
-:1043C0000020480700000000810000000020441188
-:1043D0000000000000000001002048110000000063
-:1043E0000004A2C2006044110000067C0000001A14
-:1043F00000212230000000000000000600222630CC
-:104400000000000000042004006044110000067C4D
-:104410000000A2C7002044110000000000000000BE
-:10442000003048E9000000000000000000E000004B
-:10443000000005B10000A2D40020441100000000DB
-:104440000000000000404808000000000000A2D466
-:1044500000204411000000000000000100504A2824
-:104460000000000085000000002044110000000052
-:104470000000000000204801000000000000304A59
-:10448000002044110000000001000000002048113D
-:10449000000000000000000000400000000005B720
-:1044A000A4000000C0204411000000000000000033
-:1044B000C04048000000000000000000C060000094
-:1044C000000005BC00000000C04004000000000126
-:1044D0000000002C002036210000000081000000B8
-:1044E00000204411000000000000000600204811D8
-:1044F0000000000000000000002F0230000000005B
-:10450000000000000CC00000000005C30000000017
-:10451000002004110000000000000030004036219F
-:10452000000005D6000000300020062D000000002D
-:1045300000007E00002806210000000000000000AE
-:10454000002F022100000000000000000CE000002D
-:10455000000005D68100000000204411000000008A
-:104560000000000100204811000000000004A0929B
-:10457000006044110000067C00000031002036304D
-:10458000000000000004A093006044110000067CBD
-:104590000000003200203630000000000004A2B607
-:1045A000006044110000067C00000033002036301B
-:1045B000000000000004A2BA006044110000067C64
-:1045C0000000003400203630000000000004A2BECD
-:1045D000006044110000067C0000003500203630E9
-:1045E000000000000004A2C2006044110000067C2C
-:1045F00000000036002036300000000000042004D7
-:10460000006044110000067C0001A2A400204411B7
-:10461000000000000000003F0020481100000000E2
-:104620000000003F00204811000000000000003F93
-:1046300000204811000000000000003F0020481149
-:1046400000000000000000050020481100000000EC
-:104650000000A1F400204411000000000000000050
-:1046600000204811000000008800000000204411D4
-:1046700000000000000000010020481100000000C0
-:10468000810000000020441100000000000000062E
-:10469000002048110000000000000001002F02303F
-:1046A00000000000000000000CE000000000061FF9
-:1046B000000000300020062D000000000000000077
-:1046C000002F022100000000000000000CE00000AC
-:1046D0000000061F810000000020441100000000BF
-:1046E00000000001002048110000000000007E00D2
-:1046F000002806210000000000000000002F022119
-:1047000000000000000000000CE00000000005F8C0
-:104710000000A092002044110000000000000031C1
-:1047200000204A2D000000000000A093002044114A
-:10473000000000000000003200204A2D00000000B0
-:104740000000A2B600204411000000000000003369
-:1047500000204A2D000000000000A2BA00204411F1
-:10476000000000000000003400204A2D000000007E
-:104770000000A2BE0020441100000000000000352F
-:1047800000204A2D000000000000A2C200204411B9
-:10479000000000000000003600204A2D000000004C
-:1047A000000000300020062D00000000000001FF86
-:1047B000002806210000000000000000002F022158
-:1047C00000000000000000000CE000000000061ED9
-:1047D0000000000000210221000000000000000095
-:1047E00014C00000000006010004A0030060441192
-:1047F0000000067C0000A00300204411000000001F
-:10480000000000000020481000000000000000012F
-:1048100000210621000000000000000014C000007C
-:10482000000006060004A010006044110000067C91
-:104830000000A01000204411000000000000000053
-:1048400000204810000000000000000100210621A7
-:104850000000000000000000002F02210000000006
-:10486000000000000CE000000000061E0004A01183
-:10487000006044110000067C0000A01100204411DB
-:1048800000000000000000000020481000000000B0
-:104890000004A012006044110000067C0000A01279
-:1048A000002044110000000000000000002048101B
-:1048B000000000000004A013006044110000067C0A
-:1048C0000000A013002044110000000000000000C0
-:1048D00000204810000000000004A01400604411F3
-:1048E0000000067C0000A01400204411000000001D
-:1048F0000000000000204810000000000004A01587
-:10490000006044110000067C0000A0150020441146
-:10491000000000000000000000204810000000001F
-:104920000004A016006044110000067C0000A016E0
-:10493000002044110000000000000000002048108A
-:10494000000000000004A017006044110000067C75
-:104950000000A0170020441100000000000000002B
-:1049600000204810000000000004200400604411F2
-:104970000000067C0000002C0080062D00000000D6
-:10498000FF000000002044110000000000000000B3
-:104990000020481100000000000000010020481124
-:1049A000000000000000000200804811000000002C
-:1049B000000000000EE000000000063000000030A3
-:1049C0000020062D00000000000000020028062143
-:1049D0000000000000000000002F02210000000085
-:1049E000000000000CE000000000062E8100000026
-:1049F00000204411000000000000000100204811C8
-:104A00000000000000042004006044110000067C47
-:104A10000000100000200811000000000000002B22
-:104A200000203622000000000000000000600000AE
-:104A3000000006340000000000600000000005BC1B
-:104A40009800000000204411000000000000000059
-:104A5000008048110000000000000000C06000005D
-:104A60000000063400000000C04004000000000107
-:104A70000000A2A400204411000000000000002259
-:104A800000204811000000008900000000204411AF
-:104A90000000000000000001004048110000062056
-:104AA00097000000002044110000000000000000FA
-:104AB00000204811000000008A000000002044117E
-:104AC0000000000000000000004048110000062027
-:104AD00000000000006000000000064D0001A2A4DC
-:104AE000C0204411000000000000001600604811C2
-:104AF0000000036A000020100020441100000000A4
-:104B000000010000002048110000000081000000AA
-:104B100000204411000000000000000100204811A6
-:104B2000000000000000217C002044110000000073
-:104B3000098000000020481100000000FFFFFFFF77
-:104B40000020481100000000000000000020481173
-:104B5000000000000000000017000000000000003E
-:104B60000004217F006044110000067C0000001F4B
-:104B700000210230000000000000000014C000000E
-:104B8000000000000000000400404C110000064737
-:104B900000000000004000000000000000000017BE
-:104BA00000201E2D000000000000000400291E2728
-:104BB0000000000000000017008036270000000001
-:104BC0000000001700201E2D00000000FFFFFFFB6B
-:104BD00000281E2700000000000000170080362774
-:104BE000000000000000001700201E2D0000000043
-:104BF0000000000800291E27000000000000001728
-:104C000000803627000000000000001700201E2D45
-:104C100000000000FFFFFFF700281E270000000033
-:104C20000000001700803627000000000001A2A449
-:104C30000020441100000000000000160060481130
-:104C40000000036A00002010002044110000000052
-:104C50000001000000204811000000000000217C3D
-:104C600000204411000000000180000000204811D5
-:104C700000000000FFFFFFFF0020481100000000BF
-:104C800000000000002048110000000000000000AB
-:104C90001700000000000000810000000020441107
-:104CA000000000000000000100204811000000008A
-:104CB0000004217F006044110000067C0000001FFA
-:104CC00000210230000000000000000014C00000BD
-:104CD0000000067B0000001000404C11000006613F
-:104CE00000000000C02004000000000000000000E0
-:104CF00038C00000000000000000001D00200A2D48
-:104D0000000000000000001E00200E2D000000002A
-:104D10000000001F0020122D0000000000000020F5
-:104D20000020162D00000000000021690020441121
-:104D30000000000000000000002048040000000007
-:104D400000000000002048050000000000000000F6
-:104D50000020480100000000CAFEBABE0020481131
-:104D600000000000000000040030122400000000D9
-:104D700000000000002F00640000000000000000A0
-:104D80000CC000000000067A0000000300281A2270
-:104D900000000000000000080022122200000000B5
-:104DA000FFFFF000002812240000000000000000B7
-:104DB000002910C4000000000000001F004036243D
-:104DC0000000000000000000008000000000000063
-:104DD000000000001AC000000000067C9F000000D8
-:104DE0000020441100000000CAFEBABE0020481195
-:104DF00000000000000000001AE000000000067F34
-:104E00000000000000800000000000000000000022
-:104E10001AC00000000006819E000000002044111E
-:104E200000000000CAFEBABE0020481100000000C9
-:104E3000000000001AE000000000068400000000EE
-:104E40000080000000000000000000000060000082
-:104E50000000000B000010000060041100000315AA
-:104E6000000000000020041100000000000000000D
-:104E700000600811000001B20000225C0020441113
-:104E800000000000000000030020481100000000A6
-:104E90000000225600204411000000000000001B0A
-:104EA00000204811000000000000A1FC0020441177
-:104EB0000000000000000001002048110000000078
-:104EC0000001A1FDC02044110000000000000021ED
-:104ED00000201E2D000000000000001000221E27F0
-:104EE00000000000000000240020222D000000002F
-:104EF0000000FFFF00282228000000000000000042
-:104F000000294907000000000000000000204811AF
-:104F100000000000000000220020222D0000000000
-:104F20000000FFFF00282228000000000000000011
-:104F3000002949070000000000000000002048117F
-:104F4000000000000000002300201E2D00000000D3
-:104F50000000001000221E270000000000000000DA
-:104F6000002949070000000000000000004048112F
-:104F70000000000000000000000000000000000031
-:104F80000000000000000000000000000000000021
-:104F90000000000000000000000000000000000011
-:104FA0000000000000000000000000000000000001
-:104FB00000000000000000000000000000000000F1
-:104FC00000000000000000000000000000000000E1
-:104FD00000000000000000000000000000000000D1
-:104FE00000000000000000000000000000000000C1
-:104FF00000000000000000000000000000000000B1
-:1050000000000000000000000000000000000000A0
-:105010000000000000000000000000000000000090
-:105020000000000000000000000000000000000080
-:105030000000000000000000000000000000000070
-:105040000000000000000000000000000000000060
-:105050000000000000000000000000000000000050
-:105060000000000000000000000000000000000040
-:105070000000000000000000000000000000000030
-:105080000000000000000000000000000000000020
-:105090000000000000000000000000000000000010
-:1050A0000000000000000000000000000000000000
-:1050B00000000000000000000000000000000000F0
-:1050C00000000000000000000000000000000000E0
-:1050D00000000000000000000000000000000000D0
-:1050E00000000000000000000000000000000000C0
-:1050F00000000000000000000000000000000000B0
-:10510000000000000000000000000000000000009F
-:10511000000000000000000000000000000000008F
-:10512000000000000000000000000000000000007F
-:10513000000000000000000000000000000000006F
-:10514000000000000000000000000000000000005F
-:10515000000000000000000000000000000000004F
-:10516000000000000000000000000000000000003F
-:10517000000000000000000000000000000000002F
-:10518000000000000000000000000000000000001F
-:10519000000000000000000000000000000000000F
-:1051A00000000000000000000000000000000000FF
-:1051B00000000000000000000000000000000000EF
-:1051C00000000000000000000000000000000000DF
-:1051D00000000000000000000000000000000000CF
-:1051E00000000000000000000000000000000000BF
-:1051F00000000000000000000000000000000000AF
-:10520000000000000000000000000000000000009E
-:10521000000000000000000000000000000000008E
-:10522000000000000000000000000000000000007E
-:10523000000000000000000000000000000000006E
-:10524000000000000000000000000000000000005E
-:10525000000000000000000000000000000000004E
-:10526000000000000000000000000000000000003E
-:10527000000000000000000000000000000000002E
-:10528000000000000000000000000000000000001E
-:10529000000000000000000000000000000000000E
-:1052A00000000000000000000000000000000000FE
-:1052B000014204F505B302500000000001C301687B
-:1052C000043505B300000000022502090250015117
-:1052D000000000000223024502A00241000000007D
-:1052E00003CD05B305B305B300000000063C063D41
-:1052F000031F05B30000000005B305B803200340F9
-:1053000000000000032A0282034203340000000070
-:1053100005B305B305B305B30000000005B30544AC
-:1053200005B305B30000000003B205B304AE0344A7
-:1053300000000000048D0443043305B300000000A6
-:1053400004C305B3043704D000000000044304FA8A
-:10535000035103710000000005B305B305B305B3A5
-:105360000000000005B305B305B305B3000000005D
-:1053700005B305B3063205BA0000000005B305B356
-:10538000000705B30000000005B305B305B305B37E
-:105390000000000005B305B305B305B3000000002D
-:1053A00003EE03E303FE03FC00000000040404001A
-:1053B00004020406000000000412040E041A04167D
-:1053C000000000000422041E042A0426000000003D
-:1053D00005B305B3042E05B30000000005B305B303
-:1053E00005B305B30000000005B305B305B305B36D
-:1053F00000000000000206680686000600000000AB
-:00000001FF
--- zfcpdump-kernel-4.4.orig/firmware/radeon/RV670_pfp.bin.ihex
+++ /dev/null
@@ -1,145 +0,0 @@
-:1000000000CA040000A00000007E828B007C038BED
-:10001000008001B8007C038B00D4401E00EE001E5F
-:1000200000CA040000A00000007E828B00C41838C3
-:1000300000CA240000CA2800009581A800C41C3A08
-:1000400000C3C00000CA080000CA0C00007C744B4A
-:1000500000C200050099C00000C41C3A007C744C2A
-:1000600000C0FFF000042C0400309002007D250049
-:1000700000351402007D350B00255403007CD5802B
-:1000800000259C030095C00400D5001B007EDDC147
-:10009000007D9D8000D6801B00D5801B00D4401EB3
-:1000A00000D5401E00D6401E00D6801E00D4801E03
-:1000B00000D4C01E009783D300D5C01E00CA08001C
-:1000C0000080001A00CA0C0000E4011E00D4001ECB
-:1000D0000080000C00C4183800E4013E00D4001E6B
-:1000E0000080000C00C4183800D4401E00EE001E32
-:1000F00000CA040000A00000007E828B00E4011E04
-:1001000000D4001E00D4401E00EE001E00CA0400F1
-:1001100000A00000007E828B00E4013E00D4001E9F
-:1001200000D4401E00EE001E00CA040000A0000023
-:10013000007E828B00CA180000D4401E00D5801EAD
-:100140000080005300D4007500D4401E00CA08008F
-:1001500000CA0C0000CA100000D4801900D4C018D6
-:1001600000D5001700D4801E00D4C01E00D5001E8C
-:1001700000E2001E00CA040000A00000007E828B86
-:1001800000CA080000D4806000D4401E0080000037
-:1001900000D4801E00CA080000D4806100D4401E34
-:1001A0000080000000D4801E00CA080000CA0C00B5
-:1001B00000D4401E00D4801600D4C01600D4801E87
-:1001C000008001B800D4C01E00C6084300CA0C005D
-:1001D00000CA10000094800400CA140000E420F358
-:1001E00000D4201300D5606500D4E01C00D5201C8D
-:1001F00000D5601C008000000006200100C60843F6
-:1002000000CA0C0000CA1000009483F700CA140052
-:1002100000E420F30080007900D4201300C60843D6
-:1002200000CA0C0000CA1000009883EF00CA140036
-:1002300000D400640080008D0000000000C414326F
-:1002400000C6184300C4082F0095400500C40C30B8
-:1002500000D4401E0080000000EE001E009583F5D3
-:1002600000C4103100D4403300D5206500D4A01C58
-:1002700000D4E01C00D5201C00E4015E00D4001E68
-:10028000008000000006200100CA1800000A2001BA
-:1002900000D6007600C408360098800700C61045D6
-:1002A0000095011000D4001F00D46062008000009F
-:1002B00000D4206200CC383500CC1433008401BB5C
-:1002C00000D4007200D5401E0080000000EE001E29
-:1002D00000E2001A008401BB00E2001A00CC104BBF
-:1002E00000CC0447002C9401007D098B0098400548
-:1002F000007D15CB00D4001A008001B800D4006D39
-:100300000034440100CC0C480098403A00CC2C4A00
-:100310000095800400CC0449008001B800D4001A84
-:1003200000D4C01A00282801008400F000CC10037B
-:100330000098801B0004380C008400F000CC1003EF
-:100340000098801700043808008400F000CC1003E7
-:100350000098801300043804008400F000CC1003DF
-:100360000098801400CC104C009A800900CC144DE9
-:10037000009840DC00D4006D00CC184800D5001A6D
-:1003800000D5401A008000C900D5801A0096C0D55B
-:1003900000D4006D008001B800D4006E009AC00344
-:1003A00000D4006D00D4006E0080000000EC007FDF
-:1003B000009AC0CC00D4006D008001B800D4006E5B
-:1003C00000CC140300CC180300CC1C03007D910367
-:1003D000007DD583007D190C0035CC1F0035701FC2
-:1003E000007CF0CB007CD08B00880000007E8E8BE0
-:1003F0000095C00400D4006E008001B800D4001A3B
-:1004000000D4C01A00CC080300CC0C0300CC1003AD
-:1004100000CC140300CC180300CC1C0300CC240334
-:1004200000CC28030035C41F0036B01F007C704B81
-:100430000034F01F007C704B0035701F007C704B47
-:10044000007D8881007DCCC1007E5101007E9541F8
-:10045000007C9082007CD4C2007C848B009AC00314
-:10046000007C8C8B002C88010098809E00D4006D4D
-:100470000098409C00D4006E00CC084C00CC0C4D81
-:1004800000CC104800D4801A00D4C01A00800101AA
-:1004900000D5001A00CC083200D40032009482D972
-:1004A00000CA0C0000D4401E0080000000D4001ED2
-:1004B00000E4011E00D4001E00CA080000CA0C009F
-:1004C00000CA100000D4401E00CA140000D4801ED0
-:1004D00000D4C01E00D5001E00D5401E00D54034FB
-:1004E0000080000000EE001E0028040400E2001A54
-:1004F00000E2001A00D4401A00CA380000CC0803F9
-:1005000000CC0C0300CC0C0300CC0C03009882BD83
-:1005100000000000008401BB00D7A06F0080000035
-:1005200000EE001F00CA040000C2FF0000CC083427
-:1005300000C13FFF007C74CB007CC90B007D010F24
-:10054000009902B0007C738B008401BB00D7A06FC0
-:100550000080000000EE001F00CA080000281900FB
-:10056000007D898B009580140028140400CA0C00BB
-:1005700000CA100000CA1C0000CA240000E2001FCC
-:1005800000D4C01A00D5001A00D5401A00CC1803B8
-:1005900000CC2C0300CC2C0300CC2C03007DA58BBD
-:1005A000007D9C4700984297000000000080016198
-:1005B00000D4C01A00D4401E00D4801E0080000069
-:1005C00000EE001E00E4011E00D4001E00D4401EF8
-:1005D00000EE001E00CA040000A00000007E828B16
-:1005E00000E4013E00D4001E00D4401E00EE001EB8
-:1005F00000CA040000A00000007E828B00CA080030
-:1006000000248C06000CCC060098C00600CC104ECE
-:100610000099000400D4007300E4011E00D4001E01
-:1006200000D4401E00D4801E0080000000EE001E9A
-:1006300000CA080000CA0C000034D01800251001C0
-:100640000095002100C17FFF00CA100000CA1400FD
-:1006500000CA180000D4801D00D4C01D007DB18BDD
-:1006600000C1420200C2C00100D5801D0034DC0E72
-:10067000007D5D4C007F734C00D7401E00D5001EEE
-:1006800000D5401E00C1420000C2C00000099C010C
-:100690000031DC10007F5F4C007F734C00042802A7
-:1006A000007D838000D5A86F00D5806600D7401EEE
-:1006B00000EC005E00C8240200C82402008001B8DB
-:1006C00000D6007600D4401E00D4801E00D4C01E88
-:1006D0000080000000EE001E0080000000EE001F01
-:1006E00000D4001F0080000000D4001F00D4001FB1
-:1006F0000088000000D4001F00000000000000007F
-:1007000000000000000000000000000000000000E9
-:1007100000000000000000000000000000000000D9
-:1007200000000000000000000000000000000000C9
-:1007300000000000000000000000000000000000B9
-:1007400000000000000000000000000000000000A9
-:100750000000000000000000000000000000000099
-:100760000000000000000000000000000000000089
-:100770000000000000000000000000000000000079
-:100780000000000000000000000000000000000069
-:100790000000000000000000000000000000000059
-:1007A0000000000000000000000000000000000049
-:1007B0000000000000000000000000000000000039
-:1007C0000000000000000000000000000000000029
-:1007D0000000000000000000000000000000000019
-:1007E0000000000000000000000000000000000009
-:1007F00000000000000000000000000000000000F9
-:1008000000010171000201780003008F0004007FE5
-:10081000000500030006003F000700320008012C1D
-:1008200000090046000A0036001001B6001700A2B9
-:100830000022013A00230149002000B400240125D0
-:100840000027004D0028006A002A0060002B00529B
-:10085000002F0065003200870034017F003C015604
-:10086000003F00720041018C0044012E00550173CD
-:100870000056017A0060000B00610034006200380D
-:1008800000630038006400380065003800660038F6
-:10089000006700380068003A00690041006A0048BB
-:1008A000006B0048006C0048006D0048006E004876
-:1008B000006F00480000000600000006000000066F
-:1008C0000000000600000006000000060000000610
-:1008D0000000000600000006000000060000000600
-:1008E00000000006000000060000000600000006F0
-:1008F00000000006000000060000000600000006E0
-:00000001FF
--- zfcpdump-kernel-4.4.orig/firmware/radeon/RV710_me.bin.ihex
+++ /dev/null
@@ -1,341 +0,0 @@
-:10000000CC0003EA04080003CC8000437C4080005D
-:10001000A0000000CC80006280000003D040007F80
-:1000200080000003CC4000417C40C000C0160004AA
-:1000300030D03FFF7D15000CCC11000028D8001EE9
-:100040003198000128DC001FC820000495C000067C
-:100050007C424000CC0000627E56800CCC2900001F
-:10006000C82400047E26000B958000067C42C00058
-:10007000CC0000627ED7000CCC310000C82C0004FC
-:100080007E2E000CCC00006231103FFF8000000388
-:10009000CE1100007C40C00080000003CC40004036
-:1000A00080000003CC4122577C418000CC400045B9
-:1000B000CC400048CC41225CCC41A1FC7C4080007B
-:1000C000A0000000CC800062CC400045CC4000483D
-:1000D0007C40C000CC41225CCC41A1FC7C40800033
-:1000E000A0000000CC800062CC000045CC0000489D
-:1000F000CC41225CCC41A1FC7C408000A0000000EF
-:10010000CC800062040CA1FDC0120001CC000045AF
-:10011000CC0000487CD0C00CCC41225CCC41A1FC7E
-:10012000D04D00007C408000A0000000CC80006228
-:1001300080000003CC41225D7C4080007C40C000F8
-:10014000C02A00027C4100007D29000C309400018F
-:1001500030980006309C030029DC00087C42000037
-:100160007C4240009540000FC02E000405F022584C
-:100170007F2F000CCC310000C8280004CCC12169BD
-:10018000CD01216ACE81216B0DB40002CC01216C1E
-:100190009740000E0DB400008000007DC834000AB6
-:1001A0000DB40002974000090DB40000C02E0004F9
-:1001B00005F022587F2F000CCC310000C828000425
-:1001C0008000007DC834000A974000047E02800051
-:1001D0008000007DC834000A0DB400049740FF8CF5
-:1001E00000000000CE01216DCE41216EC828000321
-:1001F000C834000A9B400004043C00058400026DE2
-:10020000CC0000620DF400009740000BC82C03E600
-:10021000CE81A2B7C03000067EF34028C030002057
-:100220007F6B80207FB3C029CF81A2C480000003F0
-:10023000CFC1A2D10DF400019740000BC82C03E7F9
-:10024000CE81A2BBC03000067EF34028C030002023
-:100250007F6B80207FB3C029CF81A2C580000003BF
-:10026000CFC1A2D20DF400029740000BC82C03E8C6
-:10027000CE81A2BFC03000067EF34028C0300020EF
-:100280007F6B80207FB3C029CF81A2C6800000038E
-:10029000CFC1A2D3C82C03E9CE81A2C3C0300006CF
-:1002A0007EF34028C03000207F6B80207FB3C029C0
-:1002B000CF81A2C780000003CFC1A2D48000000379
-:1002C000CC4000427C40C0007C4100002914001D4D
-:1002D000315400019940000C31181000C81C001165
-:1002E00095C00000C81C0011CCC12100CD01210126
-:1002F000CCC12102CD012103041800048000037E3B
-:10030000CD81A2A4C02A00049580000836A821A3AC
-:10031000CC290000C8280004C81C00110DE40040CE
-:100320009640FFFFC81C0011CCC12170CD01217186
-:10033000C820001296000000C82000128000037E32
-:10034000CC0000647C40C0007C410000CC00004533
-:10035000CC00004840D40003CD41225CCD01A1FC7B
-:10036000C01A0001041CA1FD7DD9C00C7C42000014
-:1003700008CC00010624000106280002CE1D000062
-:10038000CE5D000098C0FFFACE9D00007C4080004A
-:10039000A0000000CC8000627C40C00030D0000192
-:1003A00028CC00017C414000950000067C41800083
-:1003B000CD41216DCD81216E800000F4C81C000369
-:1003C000C02200047E16000CCC210000C81C0004D2
-:1003D0007C42400098C000047C4280008000000302
-:1003E000CDE50000CE412169CE81216ACDC1216BCE
-:1003F00080000003CC01216C7C40C0007C410000E7
-:100400007C4140007C4180007C41C00028A4000861
-:10041000326400FF0E68003C9680000A7C020000F7
-:100420007C4200001E300003CC00006A9B000003E9
-:100430004220000504200040800001117C024000A1
-:100440007E0240009A4000000A64000130EC001077
-:100450009AC0000ACC000062C02A0004C82C002107
-:100460007E92800CCC000041CC290000CEC000213F
-:1004700080000121C8300004CD01216DCD41216EE5
-:10048000C83000037F1F000B30F4000727780001FD
-:100490009740002A07B801269F8000000000000056
-:1004A000800001367F1B80048000013A7F1B80059D
-:1004B0008000013E7F1B8002800001427F1B800381
-:1004C000800001467F1B80078000014A7F1B800659
-:1004D0008000014F28A400089B80001928A4000870
-:1004E0008000015F326400FF9B80001528A4000893
-:1004F0008000015F326400FF9B80001128A4000887
-:100500008000015F326400FF9B80000D28A400087A
-:100510008000015F326400FF9B80000928A400086E
-:100520008000015F326400FF9B80000528A4000862
-:100530008000015F326400FF28A40008326400FFDD
-:100540000E68003C9A80FEB228EC00087C43400014
-:100550007C4380007C43C00096C00007CC00006252
-:10056000CF412169CF81216ACFC1216B8000000377
-:10057000CC01216C80000003CFF50000CC00006BA3
-:10058000840003810E68003C9A800004C82800158E
-:1005900080000003D040007F9680FFAB7E024000C9
-:1005A0008400023BC00E0002CC00004180000239F2
-:1005B000CCC1304A7C40C0007C410000C01E00011C
-:1005C00029240012C022000296400005C026000423
-:1005D000C027FFFB7D25000BC02600007DD2800BCD
-:1005E0007E12C00B7D25000C7C4140007C418000C8
-:1005F000CCC121699A80000ACD01216ACD41216BCD
-:1006000096C0FE83CD81216CC83000189700000091
-:10061000C830001880000003CC000018840003815B
-:10062000CC00007FC8140013C8180014CD41216B02
-:1006300096C0FE77CD81216C80000183C830001800
-:10064000C80C000898C00000C80C00087C410000DD
-:1006500095000002000000007C414000C820000915
-:10066000CC400043CE01A1F4CC400044C00E800039
-:100670007C4240007C4280002AAC001F96C0FE6491
-:10068000C035F000CE4003E232780003267C00083B
-:100690007FF7C00B7FFBC00C2A780018CFC003E3A4
-:1006A000CF8003E426B000027F3F0000CF0003E5C7
-:1006B0008000031F7C80C0007C40C00028D0000860
-:1006C0003110000F9500000F2528000106A801B485
-:1006D0009E80000000000000800001D5C0120800CC
-:1006E000800001E3C814000F800001EAC814001064
-:1006F000800001F1CCC1A2A4800001FAC81400114D
-:1007000030D0003F0D2800159A8000120D28001EE1
-:100710009A80001E0D2800209A8000230D24000FCF
-:100720000D2800107E6A800C9A8000260D2000049F
-:100730000D2400140D2800287E62400C7EA6800C3B
-:100740009A80002AC814001180000003CCC1A2A422
-:10075000C01208007C4140007D0CC00CC012000893
-:1007600029580003295C000C7C4200007DD1C00B9D
-:10077000262000147E1E400C7E4E800CCE81A2A44A
-:1007800080000003CD81A1FEC814000F0410210ECB
-:1007900095400000C814000FD051000080000003F5
-:1007A000CCC1A2A4C8140010041021089540000078
-:1007B000C8140010D051000080000003CCC1A2A4D6
-:1007C000CCC1A2A404100001CD0000198400038153
-:1007D000CC00007FC810001999000000C810001953
-:1007E000800000047C40800004102100954000003F
-:1007F000C8140011D05100008000037ECCC1A2A417
-:100800007C40C000CC40000D94C0FE01CC40000EE6
-:100810007C4100009500000508CC0001C8140005CB
-:10082000994000140000000098C0FFFB7C410000CC
-:10083000800000047D008000C81400057C40C000DA
-:100840009940000CC818000C7C4100009580FDF018
-:10085000C820000EC81C000D662000207E1E002C43
-:10086000252400027E62402080000003CCE60000C8
-:100870007C410000CC00006CCC00006DC818001F4B
-:10088000C81C001E659800207DD9C02C7CD4C00CEB
-:10089000CCDE000045DC0004C82800179680000F5D
-:1008A000C00E0001286800082AAC001632A800FF1C
-:1008B0000EB000497F2F000B9700000600000000DB
-:1008C000C81400057C40C000800002237C41000069
-:1008D00080000226D040007F8400023BCC00004113
-:1008E000CCC1304A94000000C83C001A043C00050A
-:1008F000CFC1A2A4C0361F90C0387FFF7C03C010B8
-:100900007F7B400CCF41217CCFC1217DCC01217E5A
-:10091000C03A00040434217F7F7B400CCC350000BA
-:10092000C83C00042BFC001F0438002097C00005C1
-:10093000CC0000629B8000000BB8000180000247E1
-:10094000CC000071CC01A1F404380016C0360002BE
-:10095000CF81A2A488000000CF4120107C40C000BD
-:1009600028D0001C9500000504D40001CD4000658E
-:1009700080000003CD40006809540002800000039D
-:10098000CD4000668400026CC81803EA7C40C000B9
-:100990009980FD9FC814001608D000019940002BD3
-:1009A000CD0000687C408000A0000000CC80006288
-:1009B000043C0005CFC1A2A4CC01A1F484000381B2
-:1009C000CC00004688000000CC00007F8400027E3E
-:1009D000C81803EA7C40C0009980FD8DC814001639
-:1009E00008D0000199400019CD0000687C408000CB
-:1009F000A0000000CC800062043C0022CFC1A2A471
-:100A000084000381CC00004788000000CC00007FF8
-:100A1000C81000169900000DCC400067800000044B
-:100A20007C408000C81803EA9980FD797C40C000B2
-:100A300094C00003C810001699000004CCC00068E0
-:100A4000800000047C4080008400023BC0148000D1
-:100A5000CC000041CD41304AC01480009900000014
-:100A6000C8100016800000047C408000C012000105
-:100A70007C51400C80000003D05500007C40C00039
-:100A80007C4100007C4140007C418000291C001F0B
-:100A9000CCC0004ACD00004B95C00003C01C8000B4
-:100AA000CDC12010DD830000055C2000CC00006279
-:100AB00080000003D81F41007C40C0007C41000042
-:100AC0007C4140007C418000CCC0004CCD00004DFA
-:100AD000DD830000055CA00080000003D81F4100FA
-:100AE0007C40C0007C4100007C4140007C41800093
-:100AF000CCC0004ECD00004FDD830000055CC0007F
-:100B000080000003D81F41007C40C0007C410000F1
-:100B10007C4140007C418000CCC00050CD000051A1
-:100B2000DD830000055CF8E080000003D81F410071
-:100B30007C40C0007C4100007C4140007C41800042
-:100B4000CCC00052CD000053DD830000055CF8806E
-:100B500080000003D81F41007C40C0007C410000A1
-:100B60007C4140007C418000CCC00054CD00005549
-:100B7000DD830000055CE00080000003D81F410019
-:100B80007C40C0007C4100007C4140007C418000F2
-:100B9000CCC00056CD000057DD830000055CF0009E
-:100BA00080000003D81F41007C40C0007C41000051
-:100BB0007C4140007C418000CCC00058CD000059F1
-:100BC000DD830000055CF3FC80000003D81F4100BA
-:100BD000D04320007C408000A0000000CC80006258
-:100BE000D043A0007C408000A0000000CC800062C8
-:100BF000D043C0007C408000A0000000CC80006298
-:100C0000D043F8E07C408000A0000000CC8000626F
-:100C1000D043F8807C408000A0000000CC800062BF
-:100C2000D043E0007C408000A0000000CC80006247
-:100C3000D043F0007C408000A0000000CC80006227
-:100C4000D043F3FC7C408000A0000000CC80006218
-:100C5000C81403E0CC430000CC430000CC430000A8
-:100C60007D45C000CDC30000D04300007C40800023
-:100C7000A0000000CC8000627C40C000C81003E2ED
-:100C8000C81403E5C81803E3C81C03E4CD81216937
-:100C9000CDC1216ACCC1216BCC01216C04200004A0
-:100CA0007DA180007D9640029640FCD9CD8003E373
-:100CB00031280003C02DF000251800087DAD800B01
-:100CC0007DA9800C80000003CD8003E3308CFFFF02
-:100CD000D04D00007C408000A0000000CC8000626D
-:100CE000C8140020155800029580FFFFC81400208A
-:100CF000CC00006ECC4121807C40C000CCC1218D55
-:100D0000CC41218128D0001F34588000CD81218C16
-:100D10009500FCBFCC412182C81400209940FFFF00
-:100D2000C8140020800000047C4080007C40C0008B
-:100D300028D0001831100001C01600809500000373
-:100D4000C02A00047CD4C00CCCC1217CCC41217DC4
-:100D5000CC41217E7C4180001DB0000336A0217F64
-:100D60009B000003419C0005041C004099C000004A
-:100D700009DC0001CC210000C82400042A6C001FFB
-:100D8000419C00059AC0FFFACC80006280000004FC
-:100D90007C4080007C40C00004D403E68000000357
-:100DA000CC5400008000037ECC4003EAC01C8000CD
-:100DB000044CA000CDC120107C410000C8140009E3
-:100DC00004180000041C0008CD80007109DC00013B
-:100DD00005980001CD0D000099C0FFFCCC80006299
-:100DE0008000037ECD400071C00E0100CC000041A8
-:100DF000CCC1304AC83C007FCC00007F800000039B
-:100E0000CC00007FCC00007F88000000CC00007F79
-:100E100000000000000000000000000000000000D2
-:100E200000000000000000000000000000000000C2
-:100E300000000000000000000000000000000000B2
-:100E400000000000000000000000000000000000A2
-:100E50000000000000000000000000000000000092
-:100E60000000000000000000000000000000000082
-:100E70000000000000000000000000000000000072
-:100E80000000000000000000000000000000000062
-:100E90000000000000000000000000000000000052
-:100EA0000000000000000000000000000000000042
-:100EB0000000000000000000000000000000000032
-:100EC0000000000000000000000000000000000022
-:100ED0000000000000000000000000000000000012
-:100EE0000000000000000000000000000000000002
-:100EF00000000000000000000000000000000000F2
-:100F000000000000000000000000000000000000E1
-:100F100000000000000000000000000000000000D1
-:100F200000000000000000000000000000000000C1
-:100F300000000000000000000000000000000000B1
-:100F400000000000000000000000000000000000A1
-:100F50000000000000000000000000000000000091
-:100F60000000000000000000000000000000000081
-:100F70000000000000000000000000000000000071
-:100F80000000000000000000000000000000000061
-:100F90000000000000000000000000000000000051
-:100FA0000000000000000000000000000000000041
-:100FB0000000000000000000000000000000000031
-:100FC0000000000000000000000000000000000021
-:100FD0000000000000000000000000000000000011
-:100FE0000000000000000000000000000000000001
-:100FF00000000000000000000000000000000000F1
-:1010000000000000000000000000000000000000E0
-:1010100000000000000000000000000000000000D0
-:1010200000000000000000000000000000000000C0
-:1010300000000000000000000000000000000000B0
-:1010400000000000000000000000000000000000A0
-:101050000000000000000000000000000000000090
-:101060000000000000000000000000000000000080
-:101070000000000000000000000000000000000070
-:101080000000000000000000000000000000000060
-:101090000000000000000000000000000000000050
-:1010A0000000000000000000000000000000000040
-:1010B0000000000000000000000000000000000030
-:1010C0000000000000000000000000000000000020
-:1010D0000000000000000000000000000000000010
-:1010E0000000000000000000000000000000000000
-:1010F00000000000000000000000000000000000F0
-:1011000000000000000000000000000000000000DF
-:1011100000000000000000000000000000000000CF
-:1011200000000000000000000000000000000000BF
-:1011300000000000000000000000000000000000AF
-:10114000000000000000000000000000000000009F
-:10115000000000000000000000000000000000008F
-:10116000000000000000000000000000000000007F
-:10117000000000000000000000000000000000006F
-:10118000000000000000000000000000000000005F
-:10119000000000000000000000000000000000004F
-:1011A000000000000000000000000000000000003F
-:1011B000000000000000000000000000000000002F
-:1011C000000000000000000000000000000000001F
-:1011D000000000000000000000000000000000000F
-:1011E00000000000000000000000000000000000FF
-:1011F00000000000000000000000000000000000EF
-:1012000000000000000000000000000000000000DE
-:1012100000000000000000000000000000000000CE
-:1012200000000000000000000000000000000000BE
-:1012300000000000000000000000000000000000AE
-:10124000000000000000000000000000000000009E
-:10125000000000000000000000000000000000008E
-:10126000000000000000000000000000000000007E
-:10127000000000000000000000000000000000006E
-:10128000000000000000000000000000000000005E
-:10129000000000000000000000000000000000004E
-:1012A000000000000000000000000000000000003E
-:1012B000000000000000000000000000000000002E
-:1012C000000000000000000000000000000000001E
-:1012D000000000000000000000000000000000000E
-:1012E00000000000000000000000000000000000FE
-:1012F00000000000000000000000000000000000EE
-:1013000000000000000000000000000000000000DD
-:1013100000000000000000000000000000000000CD
-:1013200000000000000000000000000000000000BD
-:1013300000000000000000000000000000000000AD
-:10134000000000000000000000000000000000009D
-:10135000000000000000000000000000000000008D
-:10136000000000000000000000000000000000007D
-:10137000000000000000000000000000000000006D
-:10138000000000000000000000000000000000005D
-:10139000000000000000000000000000000000004D
-:1013A000000000000000000000000000000000003D
-:1013B000000000000000000000000000000000002D
-:1013C000000000000000000000000000000000001D
-:1013D000000000000000000000000000000000000D
-:1013E00000000000000000000000000000000000FD
-:1013F00000000000000000000000000000000000ED
-:101400000001033300100006001700080021000A45
-:101410000027002A002800250029002B002A002888
-:10142000002B002B002D003A002E0041002F004C15
-:101430000034004E00360032003900B1003A00D1CD
-:10144000003B00E6003C00FE003D016D003F00AFA8
-:10145000004103380043034B00440190004500FE67
-:10146000004601AE004701AE004802000049020EEE
-:10147000004A0257004B028400520261005302737B
-:10148000005402890057029B0060029F006102AE77
-:10149000006202B8006302C2006402CC006502D69A
-:1014A000006602E0006702EA006802F4006902F8E0
-:1014B000006A02FC006B0300006C0304006D03086B
-:1014C000006E030C006F03100070031400720365BC
-:1014D0000074036B00790369007C031E000F037A1C
-:1014E000000F037A000F037A000F037A000F037ACC
-:1014F000000F037A000F037A000F037A000F037ABC
-:10150000000F037A000F037A000F037A000F037AAB
-:10151000000F037A000F037A000F037A000F037A9B
-:10152000000F037A000F037A000F037A000F037A8B
-:10153000000F037A000F037A000F037A000F037A7B
-:00000001FF
--- zfcpdump-kernel-4.4.orig/firmware/radeon/RV710_pfp.bin.ihex
+++ /dev/null
@@ -1,213 +0,0 @@
-:100000007C408000A00000007E82800B8000000009
-:10001000DC030000CC800040D04000407C408000E9
-:10002000A00000007E82800BC818000E31980001ED
-:100030007C4240009580023A7C428000C81C001C33
-:10004000C037C0007C40C0007C4100007CB4800B05
-:10005000C036000399C00000C81C001C7CB4800C92
-:1000600024D400027D654000CD400043CE80004393
-:10007000CD000043CC800040CE400040CE80004008
-:10008000CCC00040DC3A00009780FFDECD0000408D
-:100090007C40C000800000187C410000D400034078
-:1000A000D4000FC0D4000FA2C818000E8000000CAE
-:1000B00031980002D40003C0D4000FC0D4000FA2B6
-:1000C000C818000E288C000830CC000F3410000136
-:1000D0007D0D00088000000C7D91800BCC800040DD
-:1000E000D04000407C408000A00000007E82800B59
-:1000F000D4000340D4000FC0D4000FA2CC80004035
-:10010000D04000407C408000A00000007E82800B38
-:10011000D40003C0D4000FC0D4000FA2CC80004094
-:10012000D04000407C408000A00000007E82800B18
-:10013000CC4003F980000249CC4003F8C037FFFFF0
-:100140007C414000CF41A29EC82003F8C81C03F99F
-:1001500066200020C81803FB7DE1C02C7D58C00834
-:100160007CDCC02069100020C0360003CC000054A5
-:100170007CB4800C80000069CC8000407C41800011
-:10018000CD81A29ECC80004080000067CD800040E1
-:10019000C019FFFFCC800040CD81A29E7C40C000F2
-:1001A0007C4100007C414000CCC1A1FACD01A1F905
-:1001B000CD41A29DCCC00040CD000040CD400040CC
-:1001C000CC4000407C408000A00000007E82800B7C
-:1001D000CC000054CC8000407C40C0007C4100003A
-:1001E0007C414000CCC1A1FACD01A1F9CD41A29D35
-:1001F000CCC00040CD000040CD400040D040004089
-:100200007C408000A00000007E82800B7C40C0000B
-:1002100030D00001CCC1A29F95000003041400015E
-:1002200004140002CD4003FBCC800040800000009D
-:10023000CCC000407C40C000CC800040CCC1A2A219
-:1002400080000000CCC000407C40C00028D4001FCB
-:10025000CC800040954000037C410000CCC000579A
-:100260002918001FCCC0004095800003CD0000403D
-:10027000CD00005880000249CC00007FC820001744
-:10028000C83000229A0000060E280001C824001E73
-:100290000A640001D4001240CE400040C036C000C5
-:1002A0009680000737747900041C0001CF4000409D
-:1002B000CDC00040CF0003FA7C030000CA0C001040
-:1002C0007C41000094C000047C414000D42002C462
-:1002D000CDE000449B00000B7C418000CC00004B33
-:1002E000CDA00049CD200041CD600041CDA000410E
-:1002F00006200001CE00005680000249CC00007F9D
-:10030000C8280020C82C0021CC0000637EEA4001F0
-:10031000657400207F53402C269C00027DF5C02090
-:1003200069F80020CE80004BCE600049CDE000414E
-:10033000CFA00041CE600041271C00027DF5C02007
-:1003400069F800207DB24001CF00004BCE6000492B
-:10035000CDE00041CFA00041800000BCCE60004154
-:10036000C8200017C83000229A0000060E2800019D
-:10037000C824001E0A640001D4001240CE40004090
-:10038000CA0C00107C41000094C0000BC036C000B5
-:100390009680000737747900041C0001CF400040AC
-:1003A000CDC00040CF0003FA7C030000800000B500
-:1003B0007C414000CC000048800000EE00000000BE
-:1003C000C8200017C81C00230E24000299C0001585
-:1003D0007C4180000A200001CE000056D400044079
-:1003E000CC000040C036C000CA140013964000077D
-:1003F00037747900CF400040CC000040C83003FA89
-:1004000080000103CF000022CC000022954001466D
-:10041000CC00007FCCA0004680000000CC2000462D
-:1004200080000249CC000064C8200017C810001FDB
-:100430009600000509100001D4000440CD000040E2
-:10044000CD000022CC800040D0400040C80C0025E8
-:1004500094C0FEECC8100008CD000040D4000FC0CE
-:1004600080000000D4000FA27C40C0007C4100004E
-:10047000CCC003FDCD0003FCCCC00042CD00004247
-:100480002914001F29180010319800073B5C000157
-:100490007D76000B998000057D5E400BCC0000420C
-:1004A00080000249CC00004D29980001292C000849
-:1004B0009980003D32EC0001960000042930000CC8
-:1004C00080000249CC00004204140010CD400042DC
-:1004D00033300001342800018400015DC81400039A
-:1004E0009B40001B0438000C8400015DC81400030D
-:1004F0009B400017043800088400015DC814000305
-:100500009B400013043800048400015DC8140003FC
-:100510009B400015C80C03FD9A800009C81003FC1D
-:100520009B000101CC00004D04140010CCC000421F
-:10053000CD00004280000135CD40004296C000FA57
-:10054000CC00004D80000249CC00004E9AC0000350
-:10055000CC00004DCC00004EDF8300008000000086
-:10056000D80301FF9AC000F0CC00004D8000024982
-:10057000CC00004EC8180003C81C0003C8200003AC
-:100580007D5D40037DA1C0037D5D400C2A10001FEE
-:10059000299C001F7D1D000B7D17400B880000006B
-:1005A0007E92800B96400004CC00004E80000249F1
-:1005B000CC00004204380008CF800042C808000385
-:1005C000C80C0003C8100003C8140003C8180003B7
-:1005D000C81C0003C8240003C828000329FC001F0E
-:1005E0002AB0001F7FF3C00B28F0001F7FF3C00B61
-:1005F0002970001F7FF3C00B7D8880017DCCC00176
-:100600007E5100017E9540017C9080027CD4C00226
-:100610007CBC800B9AC000037C8F400B38B4000177
-:100620009B4000C1CC00004D9BC000BFCC00004EE1
-:10063000C80C03FDC81003FCCCC000428000016E52
-:10064000CD000042D4000340D4000FC0D4000FA25C
-:10065000CC800040CC400040CC400040CC4000402A
-:100660007C40C000CCC00040CCC0000D8000000029
-:10067000D04000407C40C0007C4100006514002058
-:100680007D4D402C245800027D5980207C41C000C3
-:10069000CD80004269980020CD800042CDC000424C
-:1006A000C023C00005E400027CA0800B266400107B
-:1006B0007CA4800CCC800040CDC00040CCC0004069
-:1006C00095C0000ECD00004009DC0001C8280003E1
-:1006D00096800008CE800040C834001D974000007E
-:1006E000C834001D26A800088400024CCC2B000052
-:1006F00099C0FFF709DC0001DC3A00009780000494
-:100700007C418000800001A225980002A00000002A
-:100710007D808000C818001D7C40C00064D00008A7
-:1007200095800000C818001DCC130000CC8000404C
-:10073000CCC0004080000000CC400040C810001F2A
-:100740007C40C000CC8000407CD1400CCD400040BB
-:100750000518000180000000CD8000227C40C00010
-:10076000645000208400024CCC0000617CD0C02C7E
-:10077000C8200017C8D60000994000087C438000BC
-:10078000DF830000CFA0004F8400024CCC00006249
-:1007900080000000D040007F80000249CC00006251
-:1007A0008400024CCC000061C82000177C40C000CF
-:1007B000C036FF00C810000DC0303FFF7CF5400B75
-:1007C0007D51800B7D81800F998000087CF3800B28
-:1007D000DF830000CFA0004F8400024CCC000062F9
-:1007E00080000000D040007F80000249CC00006201
-:1007F0008400024C7C40C00028DC000895C0001931
-:1008000030DC00107C41000099C0000464540020DA
-:1008100080000208C91D00007D15002CC91E0000C3
-:100820007C4200007C4240007C4180007DE5C00BA2
-:100830007DE280079A80000E41AC00059AC000005E
-:100840000AEC000130DC001099C000040000000038
-:100850008000020BC91D00008000020BC91E0000B1
-:10086000CC800040CCC00040D0400040C80C0025E7
-:1008700094C0FDE4C8100008CD000040D4000FC0B3
-:1008800080000000D4000FA2D4000340D4000FC0A9
-:10089000D4000FA2CC800040D04000407C408000BB
-:1008A000A00000007E82800BD40003C0D4000FC0E3
-:1008B000D4000FA2CC800040D04000407C4080009B
-:1008C000A00000007E82800B7C40C00030D000067B
-:1008D0000D10000699000007C81400159940000586
-:1008E000CC000052D4000340D4000FC0D4000FA2AB
-:1008F000CC800040CCC0004080000000D0400040D0
-:100900007C40C000CC4D0000DC3A00009780FDBD6B
-:1009100004CC000180000242CC4D000080000000A9
-:10092000D040007FCC00007F80000000CC00007F22
-:10093000CC00007F88000000CC00007F0000000099
-:1009400000000000000000000000000000000000A7
-:100950000000000000000000000000000000000097
-:100960000000000000000000000000000000000087
-:100970000000000000000000000000000000000077
-:100980000000000000000000000000000000000067
-:100990000000000000000000000000000000000057
-:1009A0000000000000000000000000000000000047
-:1009B0000000000000000000000000000000000037
-:1009C0000000000000000000000000000000000027
-:1009D0000000000000000000000000000000000017
-:1009E0000000000000000000000000000000000007
-:1009F00000000000000000000000000000000000F7
-:100A000000000000000000000000000000000000E6
-:100A100000000000000000000000000000000000D6
-:100A200000000000000000000000000000000000C6
-:100A300000000000000000000000000000000000B6
-:100A400000000000000000000000000000000000A6
-:100A50000000000000000000000000000000000096
-:100A60000000000000000000000000000000000086
-:100A70000000000000000000000000000000000076
-:100A80000000000000000000000000000000000066
-:100A90000000000000000000000000000000000056
-:100AA0000000000000000000000000000000000046
-:100AB0000000000000000000000000000000000036
-:100AC0000000000000000000000000000000000026
-:100AD0000000000000000000000000000000000016
-:100AE0000000000000000000000000000000000006
-:100AF00000000000000000000000000000000000F6
-:100B000000000000000000000000000000000000E5
-:100B100000000000000000000000000000000000D5
-:100B200000000000000000000000000000000000C5
-:100B300000000000000000000000000000000000B5
-:100B400000000000000000000000000000000000A5
-:100B50000000000000000000000000000000000095
-:100B60000000000000000000000000000000000085
-:100B70000000000000000000000000000000000075
-:100B80000000000000000000000000000000000065
-:100B90000000000000000000000000000000000055
-:100BA0000000000000000000000000000000000045
-:100BB0000000000000000000000000000000000035
-:100BC0000000000000000000000000000000000025
-:100BD0000000000000000000000000000000000015
-:100BE0000000000000000000000000000000000005
-:100BF00000000000000000000000000000000000F5
-:100C0000000302220004022A0005009F00020003E4
-:100C10000006003C0007002700080191000900447D
-:100C2000000A002D00100247001700F0002201D733
-:100C3000002301E80026004C0027005F0020011A75
-:100C4000002800920029004F002A0083002B006436
-:100C5000002F008D003200D80034023200360074BC
-:100C60000039010A003C01FC003F009F00410005E3
-:100C7000004401940048019D004901C5004A01CF8C
-:100C8000005502250056022D0060000A0061002A6E
-:100C90000062003000630030006400300065003006
-:100CA0000066003000670030006800370069003FD0
-:100CB000006A0047006B0047006C0047006D00476A
-:100CC000006E0047006F0047007000470073024746
-:100CD000007B024000000005000000050000000548
-:100CE00000000005000000050000000500000005F0
-:100CF00000000005000000050000000500000005E0
-:100D000000000005000000050000000500000005CF
-:100D100000000005000000050000000500000005BF
-:100D200000000005000000050000000500000005AF
-:100D3000000000050000000500000005000000059F
-:00000001FF
--- zfcpdump-kernel-4.4.orig/firmware/radeon/RV730_me.bin.ihex
+++ /dev/null
@@ -1,341 +0,0 @@
-:10000000CC0003EA7C408000A0000000CC800062AD
-:1000100080000001D040007F80000001CC40004102
-:100020007C40C000C016000430D03FFF7D15000C9E
-:10003000CC11000028D8001E3198000128DC001FD8
-:10004000C820000495C000067C424000CC0000623D
-:100050007E56800CCC290000C82400047E26000BAC
-:10006000958000067C42C000CC0000627ED7000C68
-:10007000CC310000C82C00047E2E000CCC000062A5
-:1000800031103FFF80000001CE1100007C40C00015
-:1000900080000001CC40004080000001CC4122578C
-:1000A0007C418000CC400045CC400048CC41225CE3
-:1000B000CC41A1FC7C408000A0000000CC8000620C
-:1000C000CC400045CC4000487C40C000CC41225C84
-:1000D000CC41A1FC7C408000A0000000CC800062EC
-:1000E000CC000045CC000048CC41225CCC41A1FCB6
-:1000F0007C408000A0000000CC800062040CA1FDC8
-:10010000C0120001CC000045CC0000487CD0C00CDF
-:10011000CC41225CCC41A1FCD04D00007C40800051
-:10012000A0000000CC80006280000001CC41225D74
-:100130007C4080007C40C000C02A00027C4100005E
-:100140007D29000C3094000130980006309C03009B
-:1001500029DC00087C4200007C4240009540000FF2
-:10016000C02E000405F022587F2F000CCC31000077
-:10017000C8280004CCC12169CD01216ACE81216B40
-:100180000DB40002CC01216C9740000E0DB40000AC
-:100190008000007BC834000A0DB4000297400009BB
-:1001A0000DB40000C02E000405F022587F2F000C73
-:1001B000CC310000C82800048000007BC834000A4D
-:1001C000974000047E0280008000007BC834000A53
-:1001D0000DB400049740FF8C00000000CE01216D9B
-:1001E000CE41216EC8280003C834000A9B40000499
-:1001F000043C00058400026BCC0000620DF400009A
-:100200009740000BC82C03E6CE81A2B7C030000691
-:100210007EF34028C03000207F6B80207FB3C02950
-:10022000CF81A2C480000001CFC1A2D10DF4000192
-:100230009740000BC82C03E7CE81A2BBC03000065C
-:100240007EF34028C03000207F6B80207FB3C02920
-:10025000CF81A2C580000001CFC1A2D20DF400025F
-:100260009740000BC82C03E8CE81A2BFC030000627
-:100270007EF34028C03000207F6B80207FB3C029F0
-:10028000CF81A2C680000001CFC1A2D3C82C03E950
-:10029000CE81A2C3C03000067EF34028C0300020CB
-:1002A0007F6B80207FB3C029CF81A2C7800000016F
-:1002B000CFC1A2D480000001CC4000427C40C000ED
-:1002C0007C4100002914001D315400019940000CAC
-:1002D00031181000C81C001195C00000C81C001186
-:1002E000CCC12100CD012101CCC12102CD012103CE
-:1002F000041800048000037CCD81A2A4C02A00045D
-:100300009580000836A821A3CC290000C828000445
-:10031000C81C00110DE400409640FFFFC81C0011EE
-:10032000CCC12170CD012171C820001296000000BF
-:10033000C82000128000037CCC0000647C40C00018
-:100340007C410000CC000045CC00004840D40003B4
-:10035000CD41225CCD01A1FCC01A0001041CA1FD0D
-:100360007DD9C00C7C42000008CC000106240001AD
-:1003700006280002CE1D0000CE5D000098C0FFFAE6
-:10038000CE9D00007C408000A0000000CC80006278
-:100390007C40C00030D0000128CC00017C414000EE
-:1003A000950000067C418000CD41216DCD81216EFC
-:1003B000800000F2C81C0003C02200047E16000C5E
-:1003C000CC210000C81C00047C42400098C00004FE
-:1003D0007C42800080000001CDE50000CE41216913
-:1003E000CE81216ACDC1216B80000001CC01216C3E
-:1003F0007C40C0007C4100007C4140007C4180008A
-:100400007C41C00028A40008326400FF0E68003C54
-:100410009680000A7C0200007C4200001E3000032F
-:10042000CC00006A9B00000342200005042000402D
-:100430008000010F7C0240007E0240009A400000D4
-:100440000A64000130EC00109AC0000ACC0000627F
-:10045000C02A0004C82C00217E92800CCC000041F0
-:10046000CC290000CEC000218000011FC83000044C
-:10047000CD01216DCD41216EC83000037F1F000BDF
-:1004800030F40007277800019740002A07B80124BC
-:100490009F80000000000000800001347F1B80046A
-:1004A000800001387F1B80058000013C7F1B80029B
-:1004B000800001407F1B8003800001447F1B800778
-:1004C000800001487F1B80068000014D28A40008A1
-:1004D0009B80001928A400088000015D326400FFA1
-:1004E0009B80001528A400088000015D326400FF95
-:1004F0009B80001128A400088000015D326400FF89
-:100500009B80000D28A400088000015D326400FF7C
-:100510009B80000928A400088000015D326400FF70
-:100520009B80000528A400088000015D326400FF64
-:1005300028A40008326400FF0E68003C9A80FEB2D6
-:1005400028EC00087C4340007C4380007C43C000D2
-:1005500096C00007CC000062CF412169CF81216A9B
-:10056000CFC1216B80000001CC01216C8000000113
-:10057000CFF50000CC00006B8400037F0E68003CC8
-:100580009A800004C828001580000001D040007F38
-:100590009680FFAB7E02400084000239C00E00024C
-:1005A000CC00004180000237CCC1304A7C40C00002
-:1005B0007C410000C01E000129240012C02200025C
-:1005C00096400005C0260004C027FFFB7D25000BD8
-:1005D000C02600007DD2800B7E12C00B7D25000C52
-:1005E0007C4140007C418000CCC121699A80000A96
-:1005F000CD01216ACD41216B96C0FE83CD81216C56
-:10060000C830001897000000C830001880000001B2
-:10061000CC0000188400037FCC00007FC8140013B6
-:10062000C8180014CD41216B96C0FE77CD81216C96
-:1006300080000181C8300018C80C000898C0000074
-:10064000C80C00087C41000095000002000000007A
-:100650007C414000C8200009CC400043CE01A1F4F9
-:10066000CC400044C00E80007C4240007C428000B0
-:100670002AAC001F96C0FE64C035F000CE4003E2F5
-:1006800032780003267C00087FF7C00B7FFBC00C8C
-:100690002A780018CFC003E3CF8003E426B000021D
-:1006A0007F3F0000CF0003E58000031D7C80C00079
-:1006B0007C40C00028D000083110000F9500000FCA
-:1006C0002528000106A801B29E800000000000005D
-:1006D000800001D3C0120800800001E1C814000F9F
-:1006E000800001E8C8140010800001EFCCC1A2A472
-:1006F000800001F8C814001130D0003F0D2800150B
-:100700009A8000120D28001E9A80001E0D280020DD
-:100710009A8000230D24000F0D2800107E6A800CA3
-:100720009A8000260D2000040D2400140D280028B6
-:100730007E62400C7EA6800C9A80002AC8140011AC
-:1007400080000001CCC1A2A4C01208007C4140007E
-:100750007D0CC00CC012000829580003295C000C55
-:100760007C4200007DD1C00B262000147E1E400C70
-:100770007E4E800CCE81A2A480000001CD81A1FE1E
-:10078000C814000F0410210E95400000C814000F7B
-:10079000D051000080000001CCC1A2A4C8140010F8
-:1007A0000410210895400000C8140010D05100002A
-:1007B00080000001CCC1A2A4CCC1A2A404100001FD
-:1007C000CD0000198400037FCC00007FC810001901
-:1007D00099000000C8100019800000027C408000D1
-:1007E0000410210095400000C8140011D0510000F1
-:1007F0008000037CCCC1A2A47C40C000CC40000D92
-:1008000094C0FE01CC40000E7C4100009500000524
-:1008100008CC0001C8140005994000140000000035
-:1008200098C0FFFB7C410000800000027D0080003A
-:10083000C81400057C40C0009940000CC818000C8A
-:100840007C4100009580FDF0C820000EC81C000D02
-:10085000662000207E1E002C252400027E6240209F
-:1008600080000001CCE600007C410000CC00006C60
-:10087000CC00006DC818001FC81C001E6598002021
-:100880007DD9C02C7CD4C00CCCDE000045DC00043B
-:10089000C82800179680000FC00E000128680008C5
-:1008A0002AAC001632A800FF0EB000497F2F000BC3
-:1008B0009700000600000000C81400057C40C0003E
-:1008C000800002217C41000080000224D040007F93
-:1008D00084000239CC000041CCC1304A94000000B1
-:1008E000C83C001A043C0005CFC1A2A4C0361F902A
-:1008F000C0387FFF7C03C0107F7B400CCF41217C40
-:10090000CFC1217DCC01217EC03A00040434217F77
-:100910007F7B400CCC350000C83C00042BFC001F42
-:100920000438002097C00005CC0000629B800000C6
-:100930000BB8000180000245CC000071CC01A1F48D
-:1009400004380016C0360002CF81A2A4880000003F
-:10095000CF4120107C40C00028D0001C950000052D
-:1009600004D40001CD40006580000001CD40006846
-:100970000954000280000001CD4000668400026A34
-:10098000C81803EA7C40C0009980FD9FC814001677
-:1009900008D000019940002BCD0000687C40800009
-:1009A000A0000000CC800062043C0005CFC1A2A4DE
-:1009B000CC01A1F48400037FCC0000468800000035
-:1009C000CC00007F8400027CC81803EA7C40C00091
-:1009D0009980FD8DC814001608D0000199400019B7
-:1009E000CD0000687C408000A0000000CC80006248
-:1009F000043C0022CFC1A2A48400037FCC000047A6
-:100A000088000000CC00007FC81000169900000D7F
-:100A1000CC400067800000027C408000C81803EAD8
-:100A20009980FD797C40C00094C00003C810001676
-:100A300099000004CCC00068800000027C40800067
-:100A400084000239C0148000CC000041CD41304AFE
-:100A5000C014800099000000C81000168000000239
-:100A60007C408000C01200017C51400C80000001DD
-:100A7000D05500007C40C0007C4100007C4140001B
-:100A80007C418000291C001FCCC0004ACD00004BD7
-:100A900095C00003C01C8000CDC12010DD83000084
-:100AA000055C2000CC00006280000001D81F4100DE
-:100AB0007C40C0007C4100007C4140007C418000C3
-:100AC000CCC0004CCD00004DDD830000055CA000D3
-:100AD00080000001D81F41007C40C0007C41000024
-:100AE0007C4140007C418000CCC0004ECD00004FD6
-:100AF000DD830000055CC00080000001D81F4100BC
-:100B00007C40C0007C4100007C4140007C41800072
-:100B1000CCC00050CD000051DD830000055CF8E042
-:100B200080000001D81F41007C40C0007C410000D3
-:100B30007C4140007C418000CCC00052CD0000537D
-:100B4000DD830000055CF88080000001D81F4100B3
-:100B50007C40C0007C4100007C4140007C41800022
-:100B6000CCC00054CD000055DD830000055CE000E2
-:100B700080000001D81F41007C40C0007C41000083
-:100B80007C4140007C418000CCC00056CD00005725
-:100B9000DD830000055CF00080000001D81F4100EB
-:100BA0007C40C0007C4100007C4140007C418000D2
-:100BB000CCC00058CD000059DD830000055CF3FC7B
-:100BC00080000001D81F4100D04320007C408000FD
-:100BD000A0000000CC800062D043A0007C408000D8
-:100BE000A0000000CC800062D043C0007C408000A8
-:100BF000A0000000CC800062D043F8E07C40800080
-:100C0000A0000000CC800062D043F8807C408000CF
-:100C1000A0000000CC800062D043E0007C40800057
-:100C2000A0000000CC800062D043F0007C40800037
-:100C3000A0000000CC800062D043F3FC7C40800028
-:100C4000A0000000CC800062C81403E0CC43000088
-:100C5000CC430000CC4300007D45C000CDC3000064
-:100C6000D04300007C408000A0000000CC800062E7
-:100C70007C40C000C81003E2C81403E5C81803E3B1
-:100C8000C81C03E4CD812169CDC1216ACCC1216B8F
-:100C9000CC01216C042000047DA180007D964002DF
-:100CA0009640FCD9CD8003E331280003C02DF0002D
-:100CB000251800087DAD800B7DA9800C8000000107
-:100CC000CD8003E3308CFFFFD04D00007C408000DE
-:100CD000A0000000CC800062C8140020155800025B
-:100CE0009580FFFFC8140020CC00006ECC4121800D
-:100CF0007C40C000CCC1218DCC41218128D0001F77
-:100D000034588000CD81218C9500FCBFCC412182DC
-:100D1000C81400209940FFFFC81400208000000282
-:100D20007C4080007C40C00028D0001831100001B9
-:100D3000C016008095000003C02A00047CD4C00CBB
-:100D4000CCC1217CCC41217DCC41217E7C418000E5
-:100D50001DB0000336A0217F9B000003419C0005CD
-:100D6000041C004099C0000009DC0001CC210000F7
-:100D7000C82400042A6C001F419C00059AC0FFFA99
-:100D8000CC800062800000027C4080007C40C0007B
-:100D900004D403E680000001CC5400008000037CF2
-:100DA000CC4003EAC01C8000044CA000CDC1201040
-:100DB0007C410000C814000904180000041C00084D
-:100DC000CD80007109DC000105980001CD0D000007
-:100DD00099C0FFFCCC8000628000037CCD40007194
-:100DE000C00E0100CC000041CCC1304AC83C007F9D
-:100DF000CC00007F80000001CC00007FCC00007F91
-:100E000088000000CC00007F00000000000000000F
-:100E100000000000000000000000000000000000D2
-:100E200000000000000000000000000000000000C2
-:100E300000000000000000000000000000000000B2
-:100E400000000000000000000000000000000000A2
-:100E50000000000000000000000000000000000092
-:100E60000000000000000000000000000000000082
-:100E70000000000000000000000000000000000072
-:100E80000000000000000000000000000000000062
-:100E90000000000000000000000000000000000052
-:100EA0000000000000000000000000000000000042
-:100EB0000000000000000000000000000000000032
-:100EC0000000000000000000000000000000000022
-:100ED0000000000000000000000000000000000012
-:100EE0000000000000000000000000000000000002
-:100EF00000000000000000000000000000000000F2
-:100F000000000000000000000000000000000000E1
-:100F100000000000000000000000000000000000D1
-:100F200000000000000000000000000000000000C1
-:100F300000000000000000000000000000000000B1
-:100F400000000000000000000000000000000000A1
-:100F50000000000000000000000000000000000091
-:100F60000000000000000000000000000000000081
-:100F70000000000000000000000000000000000071
-:100F80000000000000000000000000000000000061
-:100F90000000000000000000000000000000000051
-:100FA0000000000000000000000000000000000041
-:100FB0000000000000000000000000000000000031
-:100FC0000000000000000000000000000000000021
-:100FD0000000000000000000000000000000000011
-:100FE0000000000000000000000000000000000001
-:100FF00000000000000000000000000000000000F1
-:1010000000000000000000000000000000000000E0
-:1010100000000000000000000000000000000000D0
-:1010200000000000000000000000000000000000C0
-:1010300000000000000000000000000000000000B0
-:1010400000000000000000000000000000000000A0
-:101050000000000000000000000000000000000090
-:101060000000000000000000000000000000000080
-:101070000000000000000000000000000000000070
-:101080000000000000000000000000000000000060
-:101090000000000000000000000000000000000050
-:1010A0000000000000000000000000000000000040
-:1010B0000000000000000000000000000000000030
-:1010C0000000000000000000000000000000000020
-:1010D0000000000000000000000000000000000010
-:1010E0000000000000000000000000000000000000
-:1010F00000000000000000000000000000000000F0
-:1011000000000000000000000000000000000000DF
-:1011100000000000000000000000000000000000CF
-:1011200000000000000000000000000000000000BF
-:1011300000000000000000000000000000000000AF
-:10114000000000000000000000000000000000009F
-:10115000000000000000000000000000000000008F
-:10116000000000000000000000000000000000007F
-:10117000000000000000000000000000000000006F
-:10118000000000000000000000000000000000005F
-:10119000000000000000000000000000000000004F
-:1011A000000000000000000000000000000000003F
-:1011B000000000000000000000000000000000002F
-:1011C000000000000000000000000000000000001F
-:1011D000000000000000000000000000000000000F
-:1011E00000000000000000000000000000000000FF
-:1011F00000000000000000000000000000000000EF
-:1012000000000000000000000000000000000000DE
-:1012100000000000000000000000000000000000CE
-:1012200000000000000000000000000000000000BE
-:1012300000000000000000000000000000000000AE
-:10124000000000000000000000000000000000009E
-:10125000000000000000000000000000000000008E
-:10126000000000000000000000000000000000007E
-:10127000000000000000000000000000000000006E
-:10128000000000000000000000000000000000005E
-:10129000000000000000000000000000000000004E
-:1012A000000000000000000000000000000000003E
-:1012B000000000000000000000000000000000002E
-:1012C000000000000000000000000000000000001E
-:1012D000000000000000000000000000000000000E
-:1012E00000000000000000000000000000000000FE
-:1012F00000000000000000000000000000000000EE
-:1013000000000000000000000000000000000000DD
-:1013100000000000000000000000000000000000CD
-:1013200000000000000000000000000000000000BD
-:1013300000000000000000000000000000000000AD
-:10134000000000000000000000000000000000009D
-:10135000000000000000000000000000000000008D
-:10136000000000000000000000000000000000007D
-:10137000000000000000000000000000000000006D
-:10138000000000000000000000000000000000005D
-:10139000000000000000000000000000000000004D
-:1013A000000000000000000000000000000000003D
-:1013B000000000000000000000000000000000002D
-:1013C000000000000000000000000000000000001D
-:1013D000000000000000000000000000000000000D
-:1013E00000000000000000000000000000000000FD
-:1013F00000000000000000000000000000000000ED
-:10140000000103310010000400170006002100084D
-:10141000002700280028002300290029002A002690
-:10142000002B0029002D0038002E003F002F004A1D
-:101430000034004C00360030003900AF003A00CFD5
-:10144000003B00E4003C00FC003D016B003F00ADB0
-:1014500000410336004303490044018E004500FC6F
-:10146000004601AC004701AC004801FE0049020CF7
-:10147000004A0255004B02820052025F0053027183
-:1014800000540287005702990060029D006102AC7F
-:10149000006202B6006302C0006402CA006502D4A2
-:1014A000006602DE006702E8006802F2006902F6E8
-:1014B000006A02FA006B02FE006C0302006D030674
-:1014C000006E030A006F030E0070031200720363C4
-:1014D0000074036900790367007C031C000F037824
-:1014E000000F0378000F0378000F0378000F0378D4
-:1014F000000F0378000F0378000F0378000F0378C4
-:10150000000F0378000F0378000F0378000F0378B3
-:10151000000F0378000F0378000F0378000F0378A3
-:10152000000F0378000F0378000F0378000F037893
-:10153000000F0378000F0378000F0378000F037883
-:00000001FF
--- zfcpdump-kernel-4.4.orig/firmware/radeon/RV730_pfp.bin.ihex
+++ /dev/null
@@ -1,213 +0,0 @@
-:100000007C408000A00000007E82800B8000000009
-:10001000DC030000CC800040D04000407C408000E9
-:10002000A00000007E82800BC818000E31980001ED
-:100030007C4240009580023A7C428000C81C001C33
-:10004000C037C0007C40C0007C4100007CB4800B05
-:10005000C036000399C00000C81C001C7CB4800C92
-:1000600024D400027D654000CD400043CE80004393
-:10007000CD000043CC800040CE400040CE80004008
-:10008000CCC00040DC3A00009780FFDECD0000408D
-:100090007C40C000800000187C410000D400034078
-:1000A000D4000FC0D4000FA2C818000E8000000CAE
-:1000B00031980002D40003C0D4000FC0D4000FA2B6
-:1000C000C818000E288C000830CC000F3410000136
-:1000D0007D0D00088000000C7D91800BCC800040DD
-:1000E000D04000407C408000A00000007E82800B59
-:1000F000D4000340D4000FC0D4000FA2CC80004035
-:10010000D04000407C408000A00000007E82800B38
-:10011000D40003C0D4000FC0D4000FA2CC80004094
-:10012000D04000407C408000A00000007E82800B18
-:10013000CC4003F980000249CC4003F8C037FFFFF0
-:100140007C414000CF41A29EC82003F8C81C03F99F
-:1001500066200020C81803FB7DE1C02C7D58C00834
-:100160007CDCC02069100020C0360003CC000054A5
-:100170007CB4800C80000069CC8000407C41800011
-:10018000CD81A29ECC80004080000067CD800040E1
-:10019000C019FFFFCC800040CD81A29E7C40C000F2
-:1001A0007C4100007C414000CCC1A1FACD01A1F905
-:1001B000CD41A29DCCC00040CD000040CD400040CC
-:1001C000CC4000407C408000A00000007E82800B7C
-:1001D000CC000054CC8000407C40C0007C4100003A
-:1001E0007C414000CCC1A1FACD01A1F9CD41A29D35
-:1001F000CCC00040CD000040CD400040D040004089
-:100200007C408000A00000007E82800B7C40C0000B
-:1002100030D00001CCC1A29F95000003041400015E
-:1002200004140002CD4003FBCC800040800000009D
-:10023000CCC000407C40C000CC800040CCC1A2A219
-:1002400080000000CCC000407C40C00028D4001FCB
-:10025000CC800040954000037C410000CCC000579A
-:100260002918001FCCC0004095800003CD0000403D
-:10027000CD00005880000249CC00007FC820001744
-:10028000C83000229A0000060E280001C824001E73
-:100290000A640001D4001240CE400040C036C000C5
-:1002A0009680000737747900041C0001CF4000409D
-:1002B000CDC00040CF0003FA7C030000CA0C001040
-:1002C0007C41000094C000047C414000D42002C462
-:1002D000CDE000449B00000B7C418000CC00004B33
-:1002E000CDA00049CD200041CD600041CDA000410E
-:1002F00006200001CE00005680000249CC00007F9D
-:10030000C8280020C82C0021CC0000637EEA4001F0
-:10031000657400207F53402C269C00027DF5C02090
-:1003200069F80020CE80004BCE600049CDE000414E
-:10033000CFA00041CE600041271C00027DF5C02007
-:1003400069F800207DB24001CF00004BCE6000492B
-:10035000CDE00041CFA00041800000BCCE60004154
-:10036000C8200017C83000229A0000060E2800019D
-:10037000C824001E0A640001D4001240CE40004090
-:10038000CA0C00107C41000094C0000BC036C000B5
-:100390009680000737747900041C0001CF400040AC
-:1003A000CDC00040CF0003FA7C030000800000B500
-:1003B0007C414000CC000048800000EE00000000BE
-:1003C000C8200017C81C00230E24000299C0001585
-:1003D0007C4180000A200001CE000056D400044079
-:1003E000CC000040C036C000CA140013964000077D
-:1003F00037747900CF400040CC000040C83003FA89
-:1004000080000103CF000022CC000022954001466D
-:10041000CC00007FCCA0004680000000CC2000462D
-:1004200080000249CC000064C8200017C810001FDB
-:100430009600000509100001D4000440CD000040E2
-:10044000CD000022CC800040D0400040C80C0025E8
-:1004500094C0FEECC8100008CD000040D4000FC0CE
-:1004600080000000D4000FA27C40C0007C4100004E
-:10047000CCC003FDCD0003FCCCC00042CD00004247
-:100480002914001F29180010319800073B5C000157
-:100490007D76000B998000057D5E400BCC0000420C
-:1004A00080000249CC00004D29980001292C000849
-:1004B0009980003D32EC0001960000042930000CC8
-:1004C00080000249CC00004204140010CD400042DC
-:1004D00033300001342800018400015DC81400039A
-:1004E0009B40001B0438000C8400015DC81400030D
-:1004F0009B400017043800088400015DC814000305
-:100500009B400013043800048400015DC8140003FC
-:100510009B400015C80C03FD9A800009C81003FC1D
-:100520009B000101CC00004D04140010CCC000421F
-:10053000CD00004280000135CD40004296C000FA57
-:10054000CC00004D80000249CC00004E9AC0000350
-:10055000CC00004DCC00004EDF8300008000000086
-:10056000D80301FF9AC000F0CC00004D8000024982
-:10057000CC00004EC8180003C81C0003C8200003AC
-:100580007D5D40037DA1C0037D5D400C2A10001FEE
-:10059000299C001F7D1D000B7D17400B880000006B
-:1005A0007E92800B96400004CC00004E80000249F1
-:1005B000CC00004204380008CF800042C808000385
-:1005C000C80C0003C8100003C8140003C8180003B7
-:1005D000C81C0003C8240003C828000329FC001F0E
-:1005E0002AB0001F7FF3C00B28F0001F7FF3C00B61
-:1005F0002970001F7FF3C00B7D8880017DCCC00176
-:100600007E5100017E9540017C9080027CD4C00226
-:100610007CBC800B9AC000037C8F400B38B4000177
-:100620009B4000C1CC00004D9BC000BFCC00004EE1
-:10063000C80C03FDC81003FCCCC000428000016E52
-:10064000CD000042D4000340D4000FC0D4000FA25C
-:10065000CC800040CC400040CC400040CC4000402A
-:100660007C40C000CCC00040CCC0000D8000000029
-:10067000D04000407C40C0007C4100006514002058
-:100680007D4D402C245800027D5980207C41C000C3
-:10069000CD80004269980020CD800042CDC000424C
-:1006A000C023C00005E400027CA0800B266400107B
-:1006B0007CA4800CCC800040CDC00040CCC0004069
-:1006C00095C0000ECD00004009DC0001C8280003E1
-:1006D00096800008CE800040C834001D974000007E
-:1006E000C834001D26A800088400024CCC2B000052
-:1006F00099C0FFF709DC0001DC3A00009780000494
-:100700007C418000800001A225980002A00000002A
-:100710007D808000C818001D7C40C00064D00008A7
-:1007200095800000C818001DCC130000CC8000404C
-:10073000CCC0004080000000CC400040C810001F2A
-:100740007C40C000CC8000407CD1400CCD400040BB
-:100750000518000180000000CD8000227C40C00010
-:10076000645000208400024CCC0000617CD0C02C7E
-:10077000C8200017C8D60000994000087C438000BC
-:10078000DF830000CFA0004F8400024CCC00006249
-:1007900080000000D040007F80000249CC00006251
-:1007A0008400024CCC000061C82000177C40C000CF
-:1007B000C036FF00C810000DC0303FFF7CF5400B75
-:1007C0007D51800B7D81800F998000087CF3800B28
-:1007D000DF830000CFA0004F8400024CCC000062F9
-:1007E00080000000D040007F80000249CC00006201
-:1007F0008400024C7C40C00028DC000895C0001931
-:1008000030DC00107C41000099C0000464540020DA
-:1008100080000208C91D00007D15002CC91E0000C3
-:100820007C4200007C4240007C4180007DE5C00BA2
-:100830007DE280079A80000E41AC00059AC000005E
-:100840000AEC000130DC001099C000040000000038
-:100850008000020BC91D00008000020BC91E0000B1
-:10086000CC800040CCC00040D0400040C80C0025E7
-:1008700094C0FDE4C8100008CD000040D4000FC0B3
-:1008800080000000D4000FA2D4000340D4000FC0A9
-:10089000D4000FA2CC800040D04000407C408000BB
-:1008A000A00000007E82800BD40003C0D4000FC0E3
-:1008B000D4000FA2CC800040D04000407C4080009B
-:1008C000A00000007E82800B7C40C00030D000067B
-:1008D0000D10000699000007C81400159940000586
-:1008E000CC000052D4000340D4000FC0D4000FA2AB
-:1008F000CC800040CCC0004080000000D0400040D0
-:100900007C40C000CC4D0000DC3A00009780FDBD6B
-:1009100004CC000180000242CC4D000080000000A9
-:10092000D040007FCC00007F80000000CC00007F22
-:10093000CC00007F88000000CC00007F0000000099
-:1009400000000000000000000000000000000000A7
-:100950000000000000000000000000000000000097
-:100960000000000000000000000000000000000087
-:100970000000000000000000000000000000000077
-:100980000000000000000000000000000000000067
-:100990000000000000000000000000000000000057
-:1009A0000000000000000000000000000000000047
-:1009B0000000000000000000000000000000000037
-:1009C0000000000000000000000000000000000027
-:1009D0000000000000000000000000000000000017
-:1009E0000000000000000000000000000000000007
-:1009F00000000000000000000000000000000000F7
-:100A000000000000000000000000000000000000E6
-:100A100000000000000000000000000000000000D6
-:100A200000000000000000000000000000000000C6
-:100A300000000000000000000000000000000000B6
-:100A400000000000000000000000000000000000A6
-:100A50000000000000000000000000000000000096
-:100A60000000000000000000000000000000000086
-:100A70000000000000000000000000000000000076
-:100A80000000000000000000000000000000000066
-:100A90000000000000000000000000000000000056
-:100AA0000000000000000000000000000000000046
-:100AB0000000000000000000000000000000000036
-:100AC0000000000000000000000000000000000026
-:100AD0000000000000000000000000000000000016
-:100AE0000000000000000000000000000000000006
-:100AF00000000000000000000000000000000000F6
-:100B000000000000000000000000000000000000E5
-:100B100000000000000000000000000000000000D5
-:100B200000000000000000000000000000000000C5
-:100B300000000000000000000000000000000000B5
-:100B400000000000000000000000000000000000A5
-:100B50000000000000000000000000000000000095
-:100B60000000000000000000000000000000000085
-:100B70000000000000000000000000000000000075
-:100B80000000000000000000000000000000000065
-:100B90000000000000000000000000000000000055
-:100BA0000000000000000000000000000000000045
-:100BB0000000000000000000000000000000000035
-:100BC0000000000000000000000000000000000025
-:100BD0000000000000000000000000000000000015
-:100BE0000000000000000000000000000000000005
-:100BF00000000000000000000000000000000000F5
-:100C0000000302220004022A0005009F00020003E4
-:100C10000006003C0007002700080191000900447D
-:100C2000000A002D00100247001700F0002201D733
-:100C3000002301E80026004C0027005F0020011A75
-:100C4000002800920029004F002A0083002B006436
-:100C5000002F008D003200D80034023200360074BC
-:100C60000039010A003C01FC003F009F00410005E3
-:100C7000004401940048019D004901C5004A01CF8C
-:100C8000005502250056022D0060000A0061002A6E
-:100C90000062003000630030006400300065003006
-:100CA0000066003000670030006800370069003FD0
-:100CB000006A0047006B0047006C0047006D00476A
-:100CC000006E0047006F0047007000470073024746
-:100CD000007B024000000005000000050000000548
-:100CE00000000005000000050000000500000005F0
-:100CF00000000005000000050000000500000005E0
-:100D000000000005000000050000000500000005CF
-:100D100000000005000000050000000500000005BF
-:100D200000000005000000050000000500000005AF
-:100D3000000000050000000500000005000000059F
-:00000001FF
--- zfcpdump-kernel-4.4.orig/firmware/radeon/RV770_me.bin.ihex
+++ /dev/null
@@ -1,341 +0,0 @@
-:10000000CC0003EA7C408000A0000000CC800062AD
-:1000100080000001D040007F80000001CC40004102
-:100020007C40C000C016000430D03FFF7D15000C9E
-:10003000CC11000028D8001E3198000128DC001FD8
-:10004000C820000495C000067C424000CC0000623D
-:100050007E56800CCC290000C82400047E26000BAC
-:10006000958000067C42C000CC0000627ED7000C68
-:10007000CC310000C82C00047E2E000CCC000062A5
-:1000800031103FFF80000001CE1100007C40C00015
-:1000900080000001CC40004080000001CC4122578C
-:1000A0007C418000CC400045CC400048CC41225CE3
-:1000B000CC41A1FC7C408000A0000000CC8000620C
-:1000C000CC400045CC4000487C40C000CC41225C84
-:1000D000CC41A1FC7C408000A0000000CC800062EC
-:1000E000CC000045CC000048CC41225CCC41A1FCB6
-:1000F0007C408000A0000000CC800062040CA1FDC8
-:10010000C0120001CC000045CC0000487CD0C00CDF
-:10011000CC41225CCC41A1FCD04D00007C40800051
-:10012000A0000000CC80006280000001CC41225D74
-:100130007C4080007C40C000C02A00027C4100005E
-:100140007D29000C3094000130980006309C03009B
-:1001500029DC00087C4200007C4240009540000FF2
-:10016000C02E000405F022587F2F000CCC31000077
-:10017000C8280004CCC12169CD01216ACE81216B40
-:100180000DB40002CC01216C9740000E0DB40000AC
-:100190008000007BC834000A0DB4000297400009BB
-:1001A0000DB40000C02E000405F022587F2F000C73
-:1001B000CC310000C82800048000007BC834000A4D
-:1001C000974000047E0280008000007BC834000A53
-:1001D0000DB400049740FF8C00000000CE01216D9B
-:1001E000CE41216EC8280003C834000A9B40000499
-:1001F000043C00058400026DCC0000620DF4000098
-:100200009740000BC82C03E6CE81A2B7C030000691
-:100210007EF34028C03000207F6B80207FB3C02950
-:10022000CF81A2C480000001CFC1A2D10DF4000192
-:100230009740000BC82C03E7CE81A2BBC03000065C
-:100240007EF34028C03000207F6B80207FB3C02920
-:10025000CF81A2C580000001CFC1A2D20DF400025F
-:100260009740000BC82C03E8CE81A2BFC030000627
-:100270007EF34028C03000207F6B80207FB3C029F0
-:10028000CF81A2C680000001CFC1A2D3C82C03E950
-:10029000CE81A2C3C03000067EF34028C0300020CB
-:1002A0007F6B80207FB3C029CF81A2C7800000016F
-:1002B000CFC1A2D480000001CC4000427C40C000ED
-:1002C0007C4100002914001D315400019940000DAB
-:1002D00031181000C81C001109DC000195C0FFFF97
-:1002E000C81C0011CCC12100CD012101CCC12102CB
-:1002F000CD012103041800048000039FCD81A2A436
-:10030000C02A00049580000836A821A3CC2900004B
-:10031000C8280004C81C00110DE400409640FFFFEF
-:10032000C81C0011CCC12170CD012171C820001260
-:1003300096000000C82000128000039FCC000064DB
-:100340007C40C0007C410000CC000045CC0000484F
-:1003500040D40003CD41225CCD01A1FCC01A0001B4
-:10036000041CA1FD7DD9C00C7C42000008CC00011A
-:100370000624000106280002CE1D0000CE5D00000C
-:1003800098C0FFFACE9D00007C408000A0000000D5
-:10039000CC8000627C40C00030D0000128CC00013D
-:1003A0007C414000950000067C418000CD41216DDC
-:1003B000CD81216E800000F3C81C0003C022000420
-:1003C0007E16000CCC210000C81C00047C424000BA
-:1003D00098C000047C42800080000001CDE5000050
-:1003E000CE412169CE81216ACDC1216B80000001FF
-:1003F000CC01216C7C40C0007C4100007C4140006D
-:100400007C4180007C41C00028A40008326400FFC9
-:100410000E68003C9680000A7C0200007C420000CE
-:100420001E300003CC00006A9B0000034220000540
-:1004300004200040800001107C0240007E02400049
-:100440009A4000000A64000130EC00109AC0000AD3
-:10045000CC000062C02A0004C82C00217E92800CCF
-:10046000CC000041CC290000CEC00021800001203A
-:10047000C8300004CD01216DCD41216EC83000038C
-:100480007F1F000B30F40007277800019740002AF7
-:1004900007B801259F8000000000000080000135A2
-:1004A0007F1B8004800001397F1B80058000013D97
-:1004B0007F1B8002800001417F1B8003800001457B
-:1004C0007F1B8007800001497F1B80068000014E52
-:1004D00028A400089B80001928A400088000015E61
-:1004E000326400FF9B80001528A400088000015E94
-:1004F000326400FF9B80001128A400088000015E88
-:10050000326400FF9B80000D28A400088000015E7B
-:10051000326400FF9B80000928A400088000015E6F
-:10052000326400FF9B80000528A400088000015E63
-:10053000326400FF28A40008326400FF0E68003C0B
-:100540009A80FEB128EC00087C4340007C43800088
-:100550007C43C00096C00007CC000062CF412169F7
-:10056000CF81216ACFC1216B80000001CC01216CB9
-:1005700080000001CFF50000CC00006B840003A2D6
-:100580000E68003C9A800004C82800158000000115
-:10059000D040007F9680FFAB7E0240008400023B8B
-:1005A000C00E0002CC00004180000239CCC1304AAC
-:1005B0007C40C0007C410000C01E000129240012C4
-:1005C000C022000296400005C0260004C027FFFBA1
-:1005D0007D25000BC02600007DD2800B7E12C00B53
-:1005E0007D25000C7C4140007C418000CCC121690C
-:1005F0009A80000ACD01216ACD41216B96C0FE820E
-:10060000CD81216CC830001897000000C830001858
-:1006100080000001CC000018840003A2CC00007F01
-:10062000C8140013C8180014CD41216B96C0FE7683
-:10063000CD81216C80000182C8300018C80C0008F0
-:1006400098C00000C80C00087C4100009500000222
-:10065000000000007C414000C8200009CC4000435D
-:10066000CE01A1F4CC400044C00E80007C4240008A
-:100670007C4280002AAC001F96C0FE63C035F000AB
-:10068000CE4003E232780003267C00087FF7C00BDF
-:100690007FFBC00C2A780018CFC003E3CF8003E4AF
-:1006A00026B000027F3F0000CF0003E58000031F5B
-:1006B0007C80C0007C40C00028D000083110000FB2
-:1006C0009500000F2528000106A801B39E800000B8
-:1006D00000000000800001D4C0120800800001E288
-:1006E000C814000F800001E9C8140010800001F058
-:1006F000CCC1A2A4800001F9C814001130D0003F81
-:100700000D2800159A8000120D28001E9A80001EE8
-:100710000D2800209A8000230D24000F0D280010C2
-:100720007E6A800C9A8000260D2000040D2400149F
-:100730000D2800287E62400C7EA6800C9A80002A3C
-:10074000C814001180000001CCC1A2A4C01208008E
-:100750007C4140007D0CC00CC012000829580003E9
-:10076000295C000C7C4200007DD1C00B26200014C7
-:100770007E1E400C7E4E800CCE81A2A48000000123
-:10078000CD81A1FEC814000F0410210E9540000079
-:10079000C814000FD051000080000001CCC1A2A4F9
-:1007A000C81400100410210895400000C81400105F
-:1007B000D051000080000001CCC1A2A4CCC1A2A4F1
-:1007C00004100001CD000019840003A2CC00007FBA
-:1007D000C810001999000000C8100019800000021C
-:1007E0007C40800004102100095400019540FFFF67
-:1007F000C8140011D05100008000039FCCC1A2A4F6
-:100800007C40C000CC40000D94C0FDFFCC40000EE9
-:100810007C4100009500000508CC0001C8140005CB
-:10082000994000140000000098C0FFFB7C410000CC
-:10083000800000027D008000C81400057C40C000DC
-:100840009940000CC818000C7C4100009580FDEE1A
-:10085000C820000EC81C000D662000207E1E002C43
-:10086000252400027E62402080000001CCE60000CA
-:100870007C410000CC00006CCC00006DC818001F4B
-:10088000C81C001E659800207DD9C02C7CD4C00CEB
-:10089000CCDE000045DC0004C82800179680000F5D
-:1008A000C00E0001286800082AAC001632A800FF1C
-:1008B0000EB000497F2F000B9700000600000000DB
-:1008C000C81400057C40C000800002237C41000069
-:1008D00080000226D040007F8400023BCC00004113
-:1008E000CCC1304A94000000C83C001A043C00050A
-:1008F000CFC1A2A4C0361F90C0387FFF7C03C010B8
-:100900007F7B400CCF41217CCFC1217DCC01217E5A
-:10091000C03A00040434217F7F7B400CCC350000BA
-:10092000C83C00042BFC001F0438002097C00005C1
-:10093000CC0000629B8000000BB8000180000247E1
-:10094000CC000071CC01A1F404380016C0360002BE
-:10095000CF81A2A488000000CF4120107C40C000BD
-:1009600028D0001C9500000504D40001CD4000658E
-:1009700080000001CD4000680954000280000001A1
-:10098000CD4000668400026CC81803EA7C40C000B9
-:100990009980FD9DC814001608D000019940002BD5
-:1009A000CD0000687C408000A0000000CC80006288
-:1009B000043C0005CFC1A2A4CC01A1F4840003A291
-:1009C000CC00004688000000CC00007F8400027E3E
-:1009D000C81803EA7C40C0009980FD8BC81400163B
-:1009E00008D0000199400019CD0000687C408000CB
-:1009F000A0000000CC800062043C0022CFC1A2A471
-:100A0000840003A2CC00004788000000CC00007FD7
-:100A1000C81000169900000DCC400067800000024D
-:100A20007C408000C81803EA9980FD777C40C000B4
-:100A300094C00003C810001699000004CCC00068E0
-:100A4000800000027C4080008400023BC0148000D3
-:100A5000CC000041CD41304AC01480009900000014
-:100A6000C8100016800000027C408000C012000107
-:100A70007C51400C80000001D05500007C40C0003B
-:100A80007C4100007C4140007C418000291C001F0B
-:100A9000CCC0004ACD00004B95C00003C01C8000B4
-:100AA000CDC12010DD830000055C2000CC00006279
-:100AB00080000001D81F41007C40C0007C41000044
-:100AC0007C4140007C418000CCC0004CCD00004DFA
-:100AD000DD830000055CA00080000001D81F4100FC
-:100AE0007C40C0007C4100007C4140007C41800093
-:100AF000CCC0004ECD00004FDD830000055CC0007F
-:100B000080000001D81F41007C40C0007C410000F3
-:100B10007C4140007C418000CCC00050CD000051A1
-:100B2000DD830000055CF8E080000001D81F410073
-:100B30007C40C0007C4100007C4140007C41800042
-:100B4000CCC00052CD000053DD830000055CF8806E
-:100B500080000001D81F41007C40C0007C410000A3
-:100B60007C4140007C418000CCC00054CD00005549
-:100B7000DD830000055CE00080000001D81F41001B
-:100B80007C40C0007C4100007C4140007C418000F2
-:100B9000CCC00056CD000057DD830000055CF0009E
-:100BA00080000001D81F41007C40C0007C41000053
-:100BB0007C4140007C418000CCC00058CD000059F1
-:100BC000DD830000055CF3FC80000001D81F4100BC
-:100BD000D04320007C408000A0000000CC80006258
-:100BE000D043A0007C408000A0000000CC800062C8
-:100BF000D043C0007C408000A0000000CC80006298
-:100C0000D043F8E07C408000A0000000CC8000626F
-:100C1000D043F8807C408000A0000000CC800062BF
-:100C2000D043E0007C408000A0000000CC80006247
-:100C3000D043F0007C408000A0000000CC80006227
-:100C4000D043F3FC7C408000A0000000CC80006218
-:100C5000C81403E0CC430000CC430000CC430000A8
-:100C60007D45C000CDC30000D04300007C40800023
-:100C7000A0000000CC8000627C40C000C81003E2ED
-:100C8000C81403E5C81803E3C81C03E4CD81216937
-:100C9000CDC1216ACCC1216BCC01216C04200004A0
-:100CA0007DA180007D9640029640FCD7CD8003E375
-:100CB00031280003C02DF000251800087DAD800B01
-:100CC0007DA9800C80000001CD8003E3308CFFFF04
-:100CD000D04D00007C408000A0000000CC8000626D
-:100CE0007C40C0007C4100002924001832640001CF
-:100CF0009A400013C8140020155800029580FFFF89
-:100D0000C8140020CC00006ECCC12180CD01218D03
-:100D1000CC4121812914001F34588000CD81218CC1
-:100D20009540FCB9CC412182C81400209940FFFFB6
-:100D3000C8140020800000027C4080007C414000FC
-:100D40007C4180007C41C00065B400207F57402C6E
-:100D5000D437810047740004D437810047740004FD
-:100D6000D43781004774000409DC0004D4378100C3
-:100D700099C0FFF8477400042924001FC0380019E7
-:100D80009640FCA1C03E0004CF8121F837E021F954
-:100D9000CC210000C82000042A20001832200001C5
-:100DA0009A00FFFBCF8121F8800000027C40800088
-:100DB0007C40C00028D0001831100001C01600800F
-:100DC00095000003C02A00047CD4C00CCCC1217C57
-:100DD000CC41217DCC41217E7C4180001DB00003AF
-:100DE00036A0217F9B000003419C0005041C0040AD
-:100DF00099C0000009DC0001CC210000C8240004D7
-:100E00002A6C001F419C00059AC0FFFACC8000624A
-:100E1000800000027C4080007C40C00004D403E6D7
-:100E200080000001CC5400008000039FCC4003EA06
-:100E3000C01C8000044CA000CDC120107C410000EB
-:100E4000C814000904180000041C0008CD800071BB
-:100E500009DC000105980001CD0D000099C0FFFCE0
-:100E6000CC8000628000039FCD400071C00E010065
-:100E7000CC000041CCC1304AC83C007FCC00007F90
-:100E800080000001CC00007FCC00007F88000000C3
-:100E9000CC00007F00000000000000000000000007
-:100EA0000000000000000000000000000000000042
-:100EB0000000000000000000000000000000000032
-:100EC0000000000000000000000000000000000022
-:100ED0000000000000000000000000000000000012
-:100EE0000000000000000000000000000000000002
-:100EF00000000000000000000000000000000000F2
-:100F000000000000000000000000000000000000E1
-:100F100000000000000000000000000000000000D1
-:100F200000000000000000000000000000000000C1
-:100F300000000000000000000000000000000000B1
-:100F400000000000000000000000000000000000A1
-:100F50000000000000000000000000000000000091
-:100F60000000000000000000000000000000000081
-:100F70000000000000000000000000000000000071
-:100F80000000000000000000000000000000000061
-:100F90000000000000000000000000000000000051
-:100FA0000000000000000000000000000000000041
-:100FB0000000000000000000000000000000000031
-:100FC0000000000000000000000000000000000021
-:100FD0000000000000000000000000000000000011
-:100FE0000000000000000000000000000000000001
-:100FF00000000000000000000000000000000000F1
-:1010000000000000000000000000000000000000E0
-:1010100000000000000000000000000000000000D0
-:1010200000000000000000000000000000000000C0
-:1010300000000000000000000000000000000000B0
-:1010400000000000000000000000000000000000A0
-:101050000000000000000000000000000000000090
-:101060000000000000000000000000000000000080
-:101070000000000000000000000000000000000070
-:101080000000000000000000000000000000000060
-:101090000000000000000000000000000000000050
-:1010A0000000000000000000000000000000000040
-:1010B0000000000000000000000000000000000030
-:1010C0000000000000000000000000000000000020
-:1010D0000000000000000000000000000000000010
-:1010E0000000000000000000000000000000000000
-:1010F00000000000000000000000000000000000F0
-:1011000000000000000000000000000000000000DF
-:1011100000000000000000000000000000000000CF
-:1011200000000000000000000000000000000000BF
-:1011300000000000000000000000000000000000AF
-:10114000000000000000000000000000000000009F
-:10115000000000000000000000000000000000008F
-:10116000000000000000000000000000000000007F
-:10117000000000000000000000000000000000006F
-:10118000000000000000000000000000000000005F
-:10119000000000000000000000000000000000004F
-:1011A000000000000000000000000000000000003F
-:1011B000000000000000000000000000000000002F
-:1011C000000000000000000000000000000000001F
-:1011D000000000000000000000000000000000000F
-:1011E00000000000000000000000000000000000FF
-:1011F00000000000000000000000000000000000EF
-:1012000000000000000000000000000000000000DE
-:1012100000000000000000000000000000000000CE
-:1012200000000000000000000000000000000000BE
-:1012300000000000000000000000000000000000AE
-:10124000000000000000000000000000000000009E
-:10125000000000000000000000000000000000008E
-:10126000000000000000000000000000000000007E
-:10127000000000000000000000000000000000006E
-:10128000000000000000000000000000000000005E
-:10129000000000000000000000000000000000004E
-:1012A000000000000000000000000000000000003E
-:1012B000000000000000000000000000000000002E
-:1012C000000000000000000000000000000000001E
-:1012D000000000000000000000000000000000000E
-:1012E00000000000000000000000000000000000FE
-:1012F00000000000000000000000000000000000EE
-:1013000000000000000000000000000000000000DD
-:1013100000000000000000000000000000000000CD
-:1013200000000000000000000000000000000000BD
-:1013300000000000000000000000000000000000AD
-:10134000000000000000000000000000000000009D
-:10135000000000000000000000000000000000008D
-:10136000000000000000000000000000000000007D
-:10137000000000000000000000000000000000006D
-:10138000000000000000000000000000000000005D
-:10139000000000000000000000000000000000004D
-:1013A000000000000000000000000000000000003D
-:1013B000000000000000000000000000000000002D
-:1013C000000000000000000000000000000000001D
-:1013D000000000000000000000000000000000000D
-:1013E00000000000000000000000000000000000FD
-:1013F00000000000000000000000000000000000ED
-:10140000000103330010000400170006002100084B
-:10141000002700280028002300290029002A002690
-:10142000002B0029002D0038002E003F002F004A1D
-:101430000034004C00360030003900AF003A00D0D4
-:10144000003B00E5003C00FD003D016C003F00ADAD
-:10145000004103380043036C0044018F004500FD48
-:10146000004601AD004701AD004802000049020EF0
-:10147000004A0257004B028400520261005302737B
-:10148000005402890057029B0060029F006102AE77
-:10149000006202B8006302C2006402CC006502D69A
-:1014A000006602E0006702EA006802F4006902F8E0
-:1014B000006A02FC006B0300006C0304006D03086B
-:1014C000006E030C006F031000700314007203869B
-:1014D0000074038C0079038A007C031E000F039BB9
-:1014E000000F039B000F039B000F039B000F039B48
-:1014F000000F039B000F039B000F039B000F039B38
-:10150000000F039B000F039B000F039B000F039B27
-:10151000000F039B000F039B000F039B000F039B17
-:10152000000F039B000F039B000F039B000F039B07
-:10153000000F039B000F039B000F039B000F039BF7
-:00000001FF
--- zfcpdump-kernel-4.4.orig/firmware/radeon/RV770_pfp.bin.ihex
+++ /dev/null
@@ -1,213 +0,0 @@
-:100000007C408000A00000007E82800B8000000009
-:10001000DC030000CC800040D04000407C408000E9
-:10002000A00000007E82800BC818000E31980001ED
-:100030007C424000958002527C428000C81C001C1B
-:10004000C037C0007C40C0007C4100007CB4800B05
-:10005000C036000399C00000C81C001C7CB4800C92
-:1000600024D400027D654000CD400043CE80004393
-:10007000CD000043CC800040CE400040CE80004008
-:10008000CCC00040DC3A00009780FFDECD0000408D
-:100090007C40C000800000187C410000D400034078
-:1000A000D4000FC0D4000FA2C818000E8000000CAE
-:1000B00031980002D40003C0D4000FC0D4000FA2B6
-:1000C000C818000E288C000830CC000F3410000136
-:1000D0007D0D00088000000C7D91800BCC800040DD
-:1000E000D04000407C408000A00000007E82800B59
-:1000F000D4000340D4000FC0D4000FA2CC80004035
-:10010000D04000407C408000A00000007E82800B38
-:10011000D40003C0D4000FC0D4000FA2CC80004094
-:10012000D04000407C408000A00000007E82800B18
-:10013000CC4003F980000261CC4003F8C82003F8EA
-:10014000C81C03F9C81803FBC037FFFF7C414000FF
-:10015000CF41A29E662000207DE1C02C7D58C008C2
-:100160007CDCC02068D00020C0360003CC000054E6
-:100170007CB4800C8000006ACC8000407C41800010
-:10018000CD81A29ECC800040CD80004080000068E0
-:10019000CC000054C019FFFFCC800040CD81A29E4E
-:1001A0007C40C0007C4100007C414000CCC1A1FAF1
-:1001B000CD01A1F9CD41A29DCCC00040CD000040B1
-:1001C000CD400040CC4000407C408000A0000000BA
-:1001D0007E82800BCC000054CC8000407C40C0006C
-:1001E0007C4100007C414000CCC1A1FACD01A1F9C5
-:1001F000CD41A29DCCC00040CD000040CD4000408C
-:10020000D04000407C408000A00000007E82800B37
-:100210007C40C00030D00001CCC1A29F95000003FB
-:100220000414000104140002CD4003FBCC80004004
-:1002300080000000CCC000407C40C000CC8000406A
-:10024000CCC1A2A280000000CCC000407C40C00015
-:1002500028D4001FCC800040954000037C41000062
-:10026000CCC000572918001FCCC000409580000367
-:10027000CD000040CD00005880000261CC00007F1E
-:10028000C8200017C83000229A0000060E2800017E
-:10029000C824001E0A640001D4001240CE40004071
-:1002A000C036C0009680000737747900041C000136
-:1002B000CF400040CDC00040CF0003FA7C030000D7
-:1002C000CA0C00107C41000094C000047C41400036
-:1002D000D42002C4CDE000449B00000B7C41800090
-:1002E000CC00004BCDA00049CD200041CD600041A5
-:1002F000CDA0004106200001CE0000568000026122
-:10030000CC00007FC8280020C82C0021CC0000634E
-:100310007EEA4001657400207F53402C269C000239
-:100320007DF5C02069F80020CE80004BCE600049EA
-:10033000CDE00041CFA00041CE600041271C00026B
-:100340007DF5C02069F800207DB24001CF00004B50
-:10035000CE600049CDE00041CFA00041800000BD4B
-:10036000CE600041C8200017C83000229A00000665
-:100370000E280001C824001E0A640001D4001240A7
-:10038000CE400040CA0C00107C41000094C0000B1D
-:10039000C036C0009680000737747900041C000145
-:1003A000CF400040CDC00040CF0003FA7C030000E6
-:1003B000800000B67C414000CC000048800000EF87
-:1003C00000000000C8200017C81C00230E240002F3
-:1003D00099C000157C4180000A200001CE00005623
-:1003E000D4000440CC000040C036C000CA14001342
-:1003F0009640000737747900CF400040CC000040A1
-:10040000C83003FA80000104CF000022CC00002293
-:100410009540015DCC00007FCCA00046800000002C
-:10042000CC20004680000261CC000064C820001788
-:10043000C810001F9600000509100001D4000440F8
-:10044000CD000040CD000022CC800040D0400040D4
-:10045000C80C002594C0FEEBC8100008CD00004079
-:10046000D4000FC080000000D4000FA27C40C00068
-:100470007C410000CCC003FDCD0003FCCCC0004299
-:10048000CD0000422914001F2918001031980007E0
-:100490003B5C00017D76000B998000057D5E400B82
-:1004A000CC00004280000261CC00004D2998000180
-:1004B000292C00089980003D32EC000196000004D0
-:1004C0002930000C80000261CC00004204140010AE
-:1004D000CD40004233300001342800018400015E29
-:1004E000C81400039B40001B0438000C8400015E0C
-:1004F000C81400039B400017043800088400015E04
-:10050000C81400039B400013043800048400015EFB
-:10051000C81400039B400015C80C03FD9A80000915
-:10052000C81003FC9B000118CC00004D04140010FF
-:10053000CCC00042CD00004280000136CD400042D8
-:1005400096C00111CC00004D80000261CC00004E2D
-:100550009AC00003CC00004DCC00004EDF830000A9
-:1005600080000000D80301FF9AC00107CC00004DB5
-:1005700080000261CC00004EC8180003C81C0003B4
-:10058000C82000037D5D40037DA1C0037D5D400C5C
-:100590002A10001F299C001F7D1D000B7D17400B9A
-:1005A000880000007E92800B96400004CC00004E34
-:1005B00080000261CC00004204380008CF80004275
-:1005C000C8080003C80C0003C8100003C8140003C7
-:1005D000C8180003C81C0003C8240003C82800036F
-:1005E00029FC001F2AB0001F7FF3C00B28F0001F5A
-:1005F0007FF3C00B2970001F7FF3C00B7D88800143
-:100600007DCCC0017E5100017E9540017C9080022E
-:100610007CD4C0027CBC800B9AC000037C8F400B52
-:1006200038B400019B4000D8CC00004D9BC000D6E0
-:10063000CC00004EC80C03FDC81003FCCCC0004227
-:100640008000016FCD000042D4000340D4000FC0F1
-:10065000D4000FA2CC800040CC400040CC400040F1
-:10066000CC4000407C40C000CCC00040CCC0000D5D
-:1006700080000000D04000407C40C0007C41000071
-:10068000651400207D4D402C245800027D598020A7
-:100690007C41C000CD80004269980020CD8000429E
-:1006A000CDC00042C023C00005E400027CA0800B46
-:1006B000266400107CA4800CCC800040CDC000409B
-:1006C000CCC0004095C0000ECD00004009DC000108
-:1006D000C828000396800008CE800040C834001D62
-:1006E00097400000C834001D26A80008840002645A
-:1006F000CC2B000099C0FFF709DC0001DC3A0000B8
-:10070000978000047C418000800001A325980002AE
-:10071000A00000007D808000C818001D7C40C00043
-:1007200064D0000895800000C818001DCC1300009C
-:10073000CC800040CCC0004080000000CC40004095
-:10074000C810001F7C40C000CC8000407CD1400C11
-:10075000CD4000400518000180000000CD8000223F
-:100760007C40C0006450002084000264CC00006122
-:100770007CD0C02CC8200017C8D6000099400008C3
-:100780007C438000DF830000CFA0004F8400026420
-:10079000CC00006280000000D040007F8000026139
-:1007A000CC00006284000264CC000061C820001705
-:1007B0007C40C000C036FF00C810000DC0303FFFB5
-:1007C0007CF5400B7D51800B7D81800F9980000866
-:1007D0007CF3800BDF830000CFA0004F8400026415
-:1007E000CC00006280000000D040007F80000261E9
-:1007F000CC000062840002647C40C00028DC000859
-:1008000095C0001930DC00107C41000099C0000444
-:100810006454002080000209C91D00007D15002CD1
-:10082000C91E00007C4200007C4240007C418000E8
-:100830007DE5C00B7DE280079A80000E41AC00058B
-:100840009AC000000AEC000130DC001099C00004DE
-:10085000000000008000020CC91D00008000020C96
-:10086000C91E0000CC800040CCC00040D0400040F9
-:10087000C80C002594C0FDE3C8100008CD0000405E
-:10088000D4000FC080000000D4000FA2D4000340A9
-:10089000D4000FC0D4000FA2CC800040D040004054
-:1008A0007C408000A00000007E82800BD40003C04A
-:1008B000D4000FC0D4000FA2CC800040D040004034
-:1008C0007C408000A00000007E82800B7C40C00045
-:1008D00030D000060D10000699000007C81400155E
-:1008E00099400005CC000052D4000340D4000FC052
-:1008F000D4000FA2CC800040CCC00040800000009B
-:10090000D04000407C40C000CC4D0000DC3A0000EC
-:100910009780FDBC04CC000180000243CC4D000058
-:100920007C40C0007C410000292400183264000192
-:100930009640000FCC8000407C4140007C4180000C
-:100940007C41C000CCC00043CD00004331DC7FFFC0
-:10095000CDC00043CCC00040CD000040CD400040A1
-:10096000CD80004080000000CDC00040CCC00040E1
-:10097000CD00004080000000D0400040800000001A
-:10098000D040007FCC00007F80000000CC00007FC2
-:10099000CC00007F88000000CC00007F0000000039
-:1009A0000000000000000000000000000000000047
-:1009B0000000000000000000000000000000000037
-:1009C0000000000000000000000000000000000027
-:1009D0000000000000000000000000000000000017
-:1009E0000000000000000000000000000000000007
-:1009F00000000000000000000000000000000000F7
-:100A000000000000000000000000000000000000E6
-:100A100000000000000000000000000000000000D6
-:100A200000000000000000000000000000000000C6
-:100A300000000000000000000000000000000000B6
-:100A400000000000000000000000000000000000A6
-:100A50000000000000000000000000000000000096
-:100A60000000000000000000000000000000000086
-:100A70000000000000000000000000000000000076
-:100A80000000000000000000000000000000000066
-:100A90000000000000000000000000000000000056
-:100AA0000000000000000000000000000000000046
-:100AB0000000000000000000000000000000000036
-:100AC0000000000000000000000000000000000026
-:100AD0000000000000000000000000000000000016
-:100AE0000000000000000000000000000000000006
-:100AF00000000000000000000000000000000000F6
-:100B000000000000000000000000000000000000E5
-:100B100000000000000000000000000000000000D5
-:100B200000000000000000000000000000000000C5
-:100B300000000000000000000000000000000000B5
-:100B400000000000000000000000000000000000A5
-:100B50000000000000000000000000000000000095
-:100B60000000000000000000000000000000000085
-:100B70000000000000000000000000000000000075
-:100B80000000000000000000000000000000000065
-:100B90000000000000000000000000000000000055
-:100BA0000000000000000000000000000000000045
-:100BB0000000000000000000000000000000000035
-:100BC0000000000000000000000000000000000025
-:100BD0000000000000000000000000000000000015
-:100BE0000000000000000000000000000000000005
-:100BF00000000000000000000000000000000000F5
-:100C0000000302230004022B000500A000020003E1
-:100C10000006003C0007002700080192000900447C
-:100C2000000A002D0010025F001700F1002201D819
-:100C3000002301E90026004C0027005F0020011B73
-:100C4000002800930029004F002A0084002B006533
-:100C5000002F008E003200D90034023300360075B8
-:100C60000039010B003C01FD003F00A0004102489B
-:100C7000004401950048019E004901C6004A01D088
-:100C8000005502260056022E0060000A0061002A6C
-:100C90000062003000630030006400300065003006
-:100CA0000066003000670030006800370069003FD0
-:100CB000006A0047006B0047006C0047006D00476A
-:100CC000006E0047006F0047007000470073025F2E
-:100CD000007B024100000005000000050000000547
-:100CE00000000005000000050000000500000005F0
-:100CF00000000005000000050000000500000005E0
-:100D000000000005000000050000000500000005CF
-:100D100000000005000000050000000500000005BF
-:100D200000000005000000050000000500000005AF
-:100D3000000000050000000500000005000000059F
-:00000001FF
--- zfcpdump-kernel-4.4.orig/firmware/sun/cassini.bin.ihex
+++ /dev/null
@@ -1,143 +0,0 @@
-:1000000000827E82090000000000008E8EFFCE82FA
-:1000100025FF010FCE8426FF0111CE853DDFE58649
-:1000200039B78FF87EC3C2964784F38A009747CECC
-:100030008233FF010F9646840C8104270B96468479
-:100040000C810827577E8425964784F38A049747B6
-:10005000CE8254FF010F9646840C81042638B612D6
-:1000600020842026037E8425967BD67CFE8F56BD79
-:10007000F7B6FE8F4EBDEC8EBDFAF7BDF728CE82E7
-:1000800082FF010F9646840C8104260AB612208452
-:100090002027B57E8425BDF71F7E841F964784F3F5
-:1000A0008A089747DEE1AD00CE82AFFF010F7E8464
-:1000B00025964185102606962385402706BDED002E
-:1000C0007E83A2DE42BDEB8E9624840827037E83C6
-:1000D000DF967BD67CFE8F56BDF7B6FE8F50BDEC0B
-:1000E0008EBDFAF78611C649BDE412CE82EFFF013C
-:1000F0000F9646840C81002717C649BDE491240D54
-:10010000B612208520260CCE82C1FF010F7E8425E9
-:100110007E8416FE8F52BDEC8EBDFAF7866AC64904
-:10012000BDE412CE8327FF010F9646840C81002781
-:100130000AC649BDE49125067E84257E8416B6183C
-:1001400070BB19702A0481AF2E19967BF62007FA2E
-:100150002027C4388138270BF62007FA2027CB0840
-:100160007E82D3BDF7668674C649BDE412CE837124
-:10017000FF010F9646840C8108260AC649BDE4910A
-:1001800025067E84257E8416BDF73E260EBDE50934
-:100190002606CE82C1FF010F7E8425FE8F54BDEC62
-:1001A0008EBDFAF7BDF733860FC651BDE412CE837C
-:1001B000B2FF010F9646840C8108265CB61220849B
-:1001C0003F813A271C9623854027037E8425C6510C
-:1001D000BDE49125037E8425CE82C1FF010F7E847C
-:1001E00025BDF8377C007ACE83EEFF010F7E842593
-:1001F0009646840C81082620962484082629B61861
-:1002000082BB1982B1013B2209B6122084378132A8
-:100210002715BDF8447E82C1BDF71FBDF844BDFC63
-:1002200029CE8225FF010F39964784FC8A00974723
-:10023000CE8434FF011196468403810227037E8514
-:100240001E964784FC8A029747DEE1AD008601B71F
-:100250001251BDF714B6103184FDB71031BDF81E30
-:100260009681D682FE8F5ABDF7B6FE8F5CBDEC8EAE
-:10027000BDFAF78608D600C51026028B20C651BDF0
-:10028000E412CE8486FF011196468403810227037F
-:100290007E850FC651BDE49125037E851E9644855B
-:1002A00010260AB61250BA013C851027A8BDF76681
-:1002B000CE84B7FF01117E851E96468403810226F7
-:1002C00050B612308403810127037E851E96448533
-:1002D000102613B61250BA013C85102609CE84535D
-:1002E000FF01117E851EB610318A02B71031BD851F
-:1002F0001FBDF8377C0080CE84FEFF01117E851E75
-:100300009646840381022609B612308403810127B0
-:100310000FBDF844BDF70BBDFC29CE8426FF0111AB
-:1003200039D622C40FB61230BA12328404270D9681
-:100330002285042705CA107E853ACA20D72239862D
-:1003400000978318CE1C00BDEB4696578501270207
-:100350004F3985022701397F8F7D8604B7120486C5
-:1003600008B712078610B7120C8607B71206B68FA9
-:100370007DB712708601BA1204B71204010101019F
-:100380000101B6120484FE8A02B7120401010101C0
-:10039000010186FDB41204B71204B612008408816C
-:1003A000082716B68F7D810C27088B04B78F7D7EBA
-:1003B000856C860397407E896E8607B712065FF7C5
-:1003C0008F825FF78F7FF78F70F78F71F78F72F7DC
-:1003D0008F73F78F74F78F75F78F76F78F77F78FA7
-:1003E00078F78F79F78F7AF78F7BB612048A10B778
-:1003F000120486E4B71270B71207F71205F7120954
-:100400008608BA1204B7120486F7B41204B71204AD
-:10041000010101010101B61208277F8180260B86A8
-:1004200008CE8F79BD897B7E868E8140260B86041F
-:10043000CE8F76BD897B7E868E8120260B8602CE6E
-:100440008F73BD897B7E868E8110260B8601CE8FB1
-:1004500070BD897B7E868E8108260B8608CE8F79BB
-:10046000BD897F7E868E8104260B8604CE8F76BD65
-:10047000897F7E868E8102260B8A02CE8F73BD898C
-:100480007F7E868E810126088601CE8F70BD897F92
-:10049000B68F7F810F26037E8747B61209840381BA
-:1004A0000327067C12097E85FEB6120684078107A3
-:1004B00027088B01B712067E86D5B68F82260A7C66
-:1004C0008F824FB712067E85C0B61206843F813FE9
-:1004D00027108B08B71206B6120984FCB712097EE2
-:1004E00085FECE8F7018CE8F84C60CBD896FCE8FDF
-:1004F0008418CE8F70C60CBD896FD683C14F2D0373
-:100500007E8740B68F7F8107270F810B2715810DCE
-:10051000271B810E27217E8740F78F7B8602B78FAE
-:100520007A201CF78F788602B78F772012F78F75A5
-:100530008602B78F742008F78F728602B78F717E9C
-:100540008747860497407E896ECE8F72BD89F7CE2D
-:100550008F75BD89F7CE8F78BD89F7CE8F7BBD892A
-:10056000F74FB78F7DB78F81B68F7227477C8F7D0E
-:10057000B68F75273F7C8F7DB68F7827377C8F7D30
-:10058000B68F7B272F7F8F7D7C8F817A8F72271B81
-:100590007C8F7D7A8F7527167C8F7D7A8F782711D7
-:1005A0007C8F7D7A8F7B270C7E87837A8F757A8FFD
-:1005B000787A8F7BCEC1FCF68F7D3AA600B7127099
-:1005C000B68F7226037E87FAB68F75260A18CE8FED
-:1005D00073BD89D57E87FAB68F78260A18CE8F76B6
-:1005E000BD89D57E87FAB68F7B260A18CE8F79BD56
-:1005F00089D57E87FA860597407E8900B68F7581FA
-:10060000072EF2F61206C4F81BB71206B68F7881D1
-:10061000072EE2484848F61206C4C71BB71206B6B2
-:100620008F7B81072ECFF61205C4F81BB712058603
-:1006300000F68F71BD89948601F68F74BD8994860A
-:1006400002F68F77BD89948603F68F7ABD8994CEA2
-:100650008F70A60181012707810327037E8866A684
-:1006600000B88F818401260B8C8F792C0E08080826
-:100670007E8850B612048A40B71204B6120484FB76
-:1006800084EFB71204B6120736B68F7C4848B7120B
-:10069000078601BA1204B7120401010101010186A3
-:1006A000FEB41204B712048602BA1204B71204860A
-:1006B000FDB41204B7120432B71207B61200840850
-:1006C0008108270F7C82082607867697407E896EF0
-:1006D0007E86ECB68F7F810F273CBDE6C7B7120D33
-:1006E000BDE6CBB612048A20B71204CEFFFFB612C5
-:1006F00000810C26050926F6271CB6120484DFB7F4
-:100700001204968381072C057C0083200696838B38
-:100710000897837E85417F8F7E8680B7120C860185
-:10072000B78F7DB6120C847FB7120C8A80B7120C7B
-:10073000860ABD8A06B6120A2A09B6120CBA8F7D3D
-:10074000B7120CB68F7E8160271A8B20B78F7EB6CA
-:10075000120C849FBA8F7EB7120CB68F7D48B78F6C
-:100760007D7E8921B612048A20B71204BD8A0A4F01
-:1007700039A60018A7000818085A26F539366C0063
-:1007800032BA8F7FB78F7FB612098403A701B612E2
-:1007900006843FA70239368603B78F8032C1002610
-:1007A00006B78F7C7E89C9C1012718C102270CC1F9
-:1007B000032700F68F800505F78F80F68F800505EB
-:1007C000F78F80F68F800505F78F80F68F8053F4C2
-:1007D00012071BB7120739CE8F70A60018E6001853
-:1007E000A700E700A60118E60118A701E701A60285
-:1007F00018E60218A702E70239A6008407E600C43B
-:10080000385454541BA700394A26FD399622840FC8
-:1008100097228601B78F70B61207B78F71F6120C48
-:10082000C40FC80FF78F72F68F72B68F71840327CB
-:10083000148101271C81022724F48F70272A962215
-:100840008A807E8A64F48F70271E96228A107E8AA0
-:1008500064F48F70271296228A207E8A64F48F7047
-:10086000270696228A409722748F71748F71788F31
-:1008700070B68F70851027AFD622C41058B612708C
-:1008800081E4273681E1260C96228420441BD6225F
-:10089000C4CF20235881C6260D9622844044441B91
-:1008A000D622C4AF2011588127260F962284804477
-:1008B00044441BD622C46F1B972239270C7C820626
-:0D08C000BDD9EDB682077E8AB97F82063968
-:00000001FF
-/* firmware patch for NS_DP83065 */
--- zfcpdump-kernel-4.4.orig/firmware/tehuti/bdx.bin.ihex
+++ /dev/null
@@ -1,2678 +0,0 @@
-:1000000002000F00008071402D000000000000C0C1
-:1000100002000F00018071002D000000000080C070
-:1000200002000F00028071002D000000000000C1DE
-:1000300002000F00038071002D000000000080C14D
-:1000400002000F00048071002D000000000000C2BB
-:1000500002000F00058071002D000000000080C22A
-:1000600002000F00068071002D000000000000C398
-:1000700002000F00078071002D000000000080C307
-:1000800002000F00088071002D000000000000C475
-:1000900002000F00098071002D000000000080C4E4
-:1000A00002000F000A8071002D000000000000C552
-:1000B00002000F000B8071002D000000000080C5C1
-:1000C00002000F000C8071002D000000000000C62F
-:1000D00002000F000D8071002D000000000080C69E
-:1000E00002000F000E8071002D000000000000C70C
-:1000F00002000F000F8071002D000000000080C77B
-:1001000002000F00108071002D000000000000C8E8
-:1001100002000F00118071002D000000000080C857
-:1001200002000F00128071002D000000000000C9C5
-:1001300002000F00138071002D000000000080C934
-:1001400002000F00148071002D000000000000CAA2
-:1001500002000F00158071002D000000000080CA11
-:1001600002000F00168071002D000000000000CB7F
-:1001700002000F00178071002D000000000080CBEE
-:1001800002000F00188071002D000000000000CC5C
-:1001900002000F00198071002D000000000080CCCB
-:1001A00002000F001A8071002D000000000000CD39
-:1001B00002000F001B8071002D000000000080CDA8
-:1001C00002000F001C8071002D000000000000CE16
-:1001D00002000F001D8071002D000000000080CE85
-:1001E00002000F001E8071002D000000000000CFF3
-:1001F00002000F001F8071002D000000000080CF62
-:1002000002000F00208071002D000000000000D0CF
-:1002100002000F00218071002D000000000080D03E
-:1002200002000F00228071002D000000000000D1AC
-:1002300002000F00238071002D000000000080D11B
-:1002400002000F00248071002D000000000000D289
-:1002500002000F00258071002D000000000080D2F8
-:1002600002000F00268071002D000000000000D366
-:1002700002000F00278071002D000000000080D3D5
-:1002800002000F00288071002D000000000000D443
-:1002900002000F00298071002D000000000080D4B2
-:1002A00002000F002A8071002D000000000000D520
-:1002B00002000F002B8071002D000000000080D58F
-:1002C00002000F002C8071002D000000000000D6FD
-:1002D00002000F002D8071002D000000000080D66C
-:1002E00002000F002E8071002D000000000000D7DA
-:1002F00002000F002F8071002D000000000080D749
-:1003000002000F00308071002D000000000000D8B6
-:1003100002000F00318071002D000000000080D825
-:1003200002000F00328071002D000000000000D993
-:1003300002000F00338071002D000000000080D902
-:1003400002000F00348071002D000000000000DA70
-:1003500002000F00358071002D000000000080DADF
-:1003600002000F00368071002D000000000000DB4D
-:1003700002000F00378071002D000000000080DBBC
-:1003800002000F00388071007B000000008060DDFB
-:1003900002000F00398071002D000000000000DD18
-:1003A00002000F003A8071002D000000000080DB89
-:1003B00002000F003B8071002D000000000000DDF6
-:1003C00002000F003C8071002D000000000000DDE5
-:1003D00002000F003D8071000000000000000000DE
-:1003E00002000F003E8071000000000000000000CD
-:1003F00002000F003F8071000000000000000000BC
-:1004000002000F00408071000000000000000000AA
-:1004100002000F0041807100000000000000000099
-:1004200002000F0042807100000000000000000088
-:1004300002000F0043807100000000000000000077
-:1004400002000F0044807100000000000000000066
-:1004500002000F0045807100000000000000000055
-:1004600002000F0046807100000000000000000044
-:1004700002000F0047807100000000000000000033
-:1004800002000F0048807100000000000000000022
-:1004900002000F0049807100000000000000000011
-:1004A00002000F004A807100000000000000000000
-:1004B00002000F004B8071000000000000000000EF
-:1004C00002000F004C8071000000000000000000DE
-:1004D00002000F004D8071000000000000000000CD
-:1004E00002000F004E8071000000000000000000BC
-:1004F00002000F004F8071000000000000000000AB
-:1005000002000F0050807100000000000000000099
-:1005100002000F0051807100000000000000000088
-:1005200002000F0052807100000000000000000077
-:1005300002000F0053807100000000000000000066
-:1005400002000F0054807100000000000000000055
-:1005500002000F0055807100000000000000000044
-:1005600002000F0056807100000000000000000033
-:1005700002000F0057807100000000000000000022
-:1005800002000F0058807100000000000000000011
-:1005900002000F0059807100000000000000000000
-:1005A00002000F005A8071000000000000000000EF
-:1005B00002000F005B8071000000000000000000DE
-:1005C00002000F005C8071000000000000000000CD
-:1005D00002000F005D8071000000000000000000BC
-:1005E00002000F005E8071000000000000000000AB
-:1005F00002000F005F80710000000000000000009A
-:1006000002000F0060807100000000000000000088
-:1006100002000F0061807100000000000000000077
-:1006200002000F0062807100000000000000000066
-:1006300002000F0063807100000000000000000055
-:1006400002000F00648071002D000000000000DB3C
-:1006500002000F00658071003F000000040100DD12
-:1006600002000F00668071003F000000010018DDED
-:1006700002000F0067807100690000007A3D00DD14
-:1006800002000F00688071003F000000040800DDD8
-:1006900002000F0069807100690000007A3D00DDF2
-:1006A00002000F006A8071003F000000043000DD8E
-:1006B00002000F006B8071003F000000010018DD98
-:1006C00002000F006C807100690000007A3D00DDBF
-:1006D00002000F006D8071003F000000040000DD8B
-:1006E00002000F006E807100690000007A3D00DD9D
-:1006F00002000F006F8071003F000000043D00DD2C
-:1007000002000F00708071003F000000010018DD42
-:1007100002000F0071807100690000007A3D00DD69
-:1007200002000F00728071003F000000040700DD2E
-:1007300002000F0073807100690000007A3D00DD47
-:1007400002000F00748071003F000000842800DD6B
-:1007500002000F00758071003F000000010018DDED
-:1007600002000F0076807100690000007A3D00DD14
-:1007700002000F00778071003F000000043700DDA9
-:1007800002000F0078807100690000007A3D00DDF2
-:1007900002000F00798071003F000000042900DD95
-:1007A00002000F007A8071003F000000010018DD98
-:1007B00002000F007B807100690000007A3D00DDBF
-:1007C00002000F007C8071003F00000004AA04DDDD
-:1007D00002000F007D807100690000007A3D00DD9D
-:1007E00002000F007E8071003F000000042800DD41
-:1007F00002000F007F8071003F000000010018DD43
-:1008000002000F0080807100690000007A3D00DD69
-:1008100002000F00818071003F000000043100DD04
-:1008200002000F0082807100690000007A3D00DD47
-:1008300002000F00838071003F000000842B00DD68
-:1008400002000F00848071003F000000010018DDED
-:1008500002000F0085807100690000007A3D00DD14
-:1008600002000F00868071003F00000004E401DDFB
-:1008700002000F0087807100690000007A3D00DDF2
-:1008800002000F00888071003F000000840080D7C4
-:1008900002000F00898071003F000000010098D71E
-:1008A00002000F008A80710059000000EF3780D7E6
-:1008B00002000F008B8071003D0000006F0080F788
-:1008C00002000F008C8071003D0000006F0080F777
-:1008D00002000F008D8071003D0000006F0080F766
-:1008E00002000F008E8071002D0000007F02D6D71D
-:1008F00002000F008F807100180000008100FF17B8
-:1009000002000F00908071003D0000006F0080F732
-:1009100002000F00918071003D0000006F0080F721
-:1009200002000F00928071002D000000B800D8D79F
-:1009300002000F0093807100180000008100EB1787
-:1009400002000F00948071003F000000042900DDC8
-:1009500002000F00958071003F000000010018DDCB
-:1009600002000F0096807100690000007A3D00DDF2
-:1009700002000F00978071003F00000084AA04DD90
-:1009800002000F0098807100690000007A3D00DDD0
-:1009900002000F00998071003F000000042B00DD71
-:1009A00002000F009A8071003F000000010018DD76
-:1009B00002000F009B807100690000007A3D00DD9D
-:1009C00002000F009C8071003F000000040000DD69
-:1009D00002000F009D807100690000007A3D00DD7B
-:1009E00002000F009E8071003F000000842900DD9E
-:1009F00002000F009F8071003F000000010018DD21
-:100A000002000F00A0807100690000007A3D00DD47
-:100A100002000F00A18071003F000000040000DD13
-:100A200002000F00A2807100690000007A3D00DD25
-:100A300002000F00A38071003F000000042A00DDC7
-:100A400002000F00A48071003F000000010018DDCB
-:100A500002000F00A5807100690000007A3D00DDF2
-:100A600002000F00A68071003F000000849100DDAD
-:100A700002000F00A7807100690000007A3D00DDD0
-:100A800002000F00A88071003F000000841980D68A
-:100A900002000F00A98071003F000000010080D615
-:100AA00002000F00AA80710035000000ED0080D622
-:100AB00002000F00AB807100180000008100FF37BA
-:100AC00002000F00AC8071003F000000042B00DD2D
-:100AD00002000F00AD8071003F000000010018DD32
-:100AE00002000F00AE807100690000007A3D00DD59
-:100AF00002000F00AF8071003F000000040000DD25
-:100B000002000F00B0807100690000007A3D00DD36
-:100B100002000F00B18071003F000000842A00DD58
-:100B200002000F00B28071003F000000010018DDDC
-:100B300002000F00B3807100690000007A3D00DD03
-:100B400002000F00B48071003F000000040000DDCF
-:100B500002000F00B5807100690000007A3D00DDE1
-:100B600002000F00B68071003F000000840C80D6A8
-:100B700002000F00B78071003F000000010080D626
-:100B800002000F00B880710035000000ED0080D633
-:100B900002000F00B9807100180000008100FF37CB
-:100BA00002000F00BA8071003F000000842A00DDBF
-:100BB00002000F00BB8071003F000000010018DD43
-:100BC00002000F00BC807100690000007A3D00DD6A
-:100BD00002000F00BD8071003F000000040000DD36
-:100BE00002000F00BE807100690000007A3D00DD48
-:100BF00002000F00BF8071003F000000840F80D60C
-:100C000002000F00C08071003F000000010080D68C
-:100C100002000F00C180710035000000ED0080D699
-:100C200002000F00C2807100180000008100FF3731
-:100C300002000F00C38071003F000000042A00DDA5
-:100C400002000F00C48071003F000000010018DDA9
-:100C500002000F00C5807100690000007A3D00DDD0
-:100C600002000F00C68071003F000000841100DD0B
-:100C700002000F00C7807100690000007A3D00DDAE
-:100C800002000F00C88071003F000000842800DDD2
-:100C900002000F00C98071003F000000010018DD54
-:100CA00002000F00CA807100690000007A3D00DD7B
-:100CB00002000F00CB8071003F000000843700DD90
-:100CC00002000F00CC807100690000007A3D00DD59
-:100CD00002000F00CD8071002D000000000080D3C5
-:100CE00002000F00CE8071003F000000803700D26C
-:100CF00002000F00CF8071003F000000040480D18B
-:100D000002000F00D08071003F000000010084D17C
-:100D100002000F00D180710069000000763B00DD09
-:100D200002000F00D280710069000000763B00DDF8
-:100D300002000F00D380710069000000763B00DDE7
-:100D400002000F00D48071003F00000084FF7FD1BB
-:100D500002000F00D58071003F00000081FF7FD1AD
-:100D600002000F00D680710069000000763B00DDB4
-:100D700002000F00D780710069000000763B00DDA3
-:100D800002000F00D880710069000000763B00DD92
-:100D900002000F00D980710069000000763B00DD81
-:100DA00002000F00DA80710069000000763B00DD70
-:100DB00002000F00DB80710069000000763B00DD5F
-:100DC00002000F00DC8071003F000000840780D625
-:100DD00002000F00DD8071003F000000010080D69E
-:100DE00002000F00DE80710035000000ED0080D6AB
-:100DF00002000F00DF807100180000008100FF3743
-:100E000002000F00E080710049000000633B00DD3C
-:100E100002000F00E180710059000000763B00DD08
-:100E200002000F00E28071003D0000006F0080F7BB
-:100E300002000F00E38071003D0000006F0080F7AA
-:100E400002000F00E48071003D0000006F0080F799
-:100E500002000F00E58071002D0000007F0206DD1A
-:100E600002000F00E6807100180000007A3D7F1D2F
-:100E700002000F00E780710045000000393100DDFD
-:100E800002000F00E8807100940000003B310B006D
-:100E900002000F00E9807100940000003D3109005C
-:100EA00002000F00EA807100940000003F3107004B
-:100EB00002000F00EB80710094000000763B0500FB
-:100EC00002000F00EC807100090000007A3DEDC1C6
-:100ED00002000F00ED8071003F00000080B700D2DB
-:100EE00002000F00EE8071003F000000842800DD4A
-:100EF00002000F00EF8071003F000000010018DDCC
-:100F000002000F00F080710069000000643200DD13
-:100F100002000F00F1807100690000007A3D00DDE1
-:100F200002000F00F28071003F000000840780D6AD
-:100F300002000F00F38071003F000000010080D626
-:100F400002000F00F480710035000000ED0080D633
-:100F500002000F00F5807100180000008100FF37CB
-:100F600002000F00F680710049000000633B00DDC5
-:100F700002000F00F780710059000000763B00DD91
-:100F800002000F00F88071003D0000006F0080F744
-:100F900002000F00F98071003D0000006F0080F733
-:100FA00002000F00FA8071003D0000006F0080F722
-:100FB00002000F00FB8071002D0000007F0206DDA3
-:100FC00002000F00FC807100180000007A3D7F1DB8
-:100FD00002000F00FD807100450000003A3100DD85
-:100FE00002000F00FE80710018000000763B2D1DEE
-:100FF00002000F00FF807100450000003C3100DD61
-:1010000002000F000081710018000000763B131DE4
-:1010100002000F0001817100450000003E3100DD3B
-:1010200002000F000281710018000000763B1B1DBA
-:1010300002000F00038171003F000000043000DD5A
-:1010400002000F00048171003F000000010018DD64
-:1010500002000F0005817100690000007A3D00DD8B
-:1010600002000F00068171003F000000040100DD56
-:1010700002000F0007817100690000007A3D00DD69
-:1010800002000F0008817100090000007A3D2DC5A3
-:1010900002000F000981710029000000640001D2E4
-:1010A00002000F000A8171003F000000842800DD6B
-:1010B00002000F000B8171003F000000010018DDED
-:1010C00002000F000C81710069000000643200DD35
-:1010D00002000F000D817100690000007A3D00DD03
-:1010E00002000F000E817100090000007A3D29C244
-:1010F00002000F000F81710029000000640000D27F
-:1011000002000F00108171003F000000842800DD04
-:1011100002000F00118171003F000000010018DD86
-:1011200002000F001281710069000000643200DDCE
-:1011300002000F0013817100690000007A3D00DD9C
-:1011400002000F001481710049000000633B00DDC4
-:1011500002000F001581710059000000763B00DD90
-:1011600002000F00168171003D0000006F0080F743
-:1011700002000F00178171003D0000006F0080F732
-:1011800002000F00188171003D0000006F0080F721
-:1011900002000F00198171002D0000007F0206DDA2
-:1011A00002000F001A817100180000007A3D7F1DB7
-:1011B00002000F001B817100450000003A3100DD84
-:1011C00002000F001C81710018000000763B0F1D0B
-:1011D00002000F001D8171003F000000043000DD9F
-:1011E00002000F001E8171003F000000010018DDA9
-:1011F00002000F001F817100690000007A3D00DDD0
-:1012000002000F00208171003F000000040100DD9A
-:1012100002000F0021817100690000007A3D00DDAD
-:1012200002000F0022817100090000007A3D2DC5E7
-:1012300002000F00238171002D000000820008D100
-:1012400002000F0024817100080000007A3DC323D2
-:1012500002000F0025817100490000000A3B00D602
-:1012600002000F00268171003F000000040000D33F
-:1012700002000F00278171003F000000010004D32D
-:1012800002000F00288171002F000000854081D6E8
-:1012900002000F00298171003F00000084FFFFD48D
-:1012A00002000F002A8171003F000000810780D4F6
-:1012B00002000F002B8171003F00000084FFFFD16E
-:1012C00002000F002C8171003F000000010080D15E
-:1012D00002000F002D81710049000000663600DD1C
-:1012E00002000F002E81710069000000763B00DDD6
-:1012F00002000F002F81710069000000763B00DDC5
-:1013000002000F003081710069000000763B00DDB3
-:1013100002000F003181710069000000693B00DDAF
-:1013200002000F003281710069000000763B00DD91
-:1013300002000F003381710069000000763B00DD80
-:1013400002000F003481710069000000763B00DD6F
-:1013500002000F003581710069000000693B00DD6B
-:1013600002000F0036817100610000006C0400F67D
-:1013700002000F003781710035000000ED0080D6BB
-:1013800002000F00388171001800000081006B3DE1
-:1013900002000F0039817100490000008B0500D662
-:1013A00002000F003A8171002F000000060181D673
-:1013B00002000F003B8171002D000000000000D2F0
-:1013C00002000F003C81710021000000E40000D207
-:1013D00002000F003D8171003D0000006F0080F7AA
-:1013E00002000F003E8171002D0000007F0106DD2C
-:1013F00002000F003F817100180000007A3D7F1D40
-:1014000002000F0040817100490000006C3600D8D6
-:1014100002000F004181710069000000E73300D82D
-:1014200002000F004281710069000000E73300D81C
-:1014300002000F004381710069000000EF3700D8FF
-:1014400002000F0044817100310000006C0100D6E1
-:1014500002000F00458171002D000000000000D146
-:1014600002000F004681710049000000E4337AD188
-:1014700002000F00478171002F000000620171D14E
-:1014800002000F00488171002F000000620161D14D
-:1014900002000F004981710049000000E33340D190
-:1014A00002000F004A8171003D0000006F0080F7CC
-:1014B00002000F004B8171002D0000007F0106DD4E
-:1014C00002000F004C817100180000007A3D7F1D62
-:1014D00002000F004D817100490000006C3600D8F9
-:1014E00002000F004E81710069000000E73300D850
-:1014F00002000F004F81710069000000623100D8C6
-:1015000002000F005081710069000000EF3700D821
-:1015100002000F0051817100310000006C0100D603
-:1015200002000F00528171003D0000006F0080F743
-:1015300002000F00538171002D0000007F0106DDC5
-:1015400002000F0054817100180000007A3D7F1DD9
-:1015500002000F0055817100490000006C3600D870
-:1015600002000F005681710069000000E73300D8C7
-:1015700002000F005781710069000000E73300D8B6
-:1015800002000F005881710069000000EF3700D899
-:1015900002000F0059817100310000006C0100D67B
-:1015A00002000F005A8171002D000000000000D1E0
-:1015B00002000F005B8171002D000000E4076CD178
-:1015C00002000F005C81710049000000E33340D14C
-:1015D00002000F005D8171003D0000006F0080F788
-:1015E00002000F005E8171002D0000007F0106DD0A
-:1015F00002000F005F817100180000007A3D7F1D1E
-:1016000002000F0060817100490000006C3600D8B4
-:1016100002000F006181710069000000E73300D80B
-:1016200002000F006281710069000000623100D881
-:1016300002000F006381710069000000EF3700D8DD
-:1016400002000F0064817100310000006C0100D6BF
-:1016500002000F00658171003D0000006F0080F7FF
-:1016600002000F00668171002D0000007F0106DD81
-:1016700002000F0067817100180000007A3D7F1D95
-:1016800002000F0068817100490000006C3600D82C
-:1016900002000F006981710069000000E73300D883
-:1016A00002000F006A81710069000000E73300D872
-:1016B00002000F006B81710069000000EF3700D855
-:1016C00002000F006C817100310000006C0100D637
-:1016D00002000F006D8171002D000000000000D19C
-:1016E00002000F006E81710049000000E43378D1E0
-:1016F00002000F006F8171002F000000620171D1A4
-:1017000002000F00708171002F000000620161D1A2
-:1017100002000F007181710049000000E33340D1E5
-:1017200002000F00728171003D0000006F0080F721
-:1017300002000F00738171002D0000007F0106DDA3
-:1017400002000F0074817100180000007A3D7F1DB7
-:1017500002000F0075817100490000006C3600D84E
-:1017600002000F007681710069000000E73300D8A5
-:1017700002000F007781710069000000623100D81B
-:1017800002000F007881710069000000EF3700D877
-:1017900002000F0079817100310000006C0100D659
-:1017A00002000F007A8171003D0000006F0080F799
-:1017B00002000F007B8171002D0000007F0106DD1B
-:1017C00002000F007C817100180000007A3D7F1D2F
-:1017D00002000F007D817100490000006C3600D8C6
-:1017E00002000F007E81710069000000E73300D81D
-:1017F00002000F007F81710069000000E73300D80C
-:1018000002000F008081710069000000EF3700D8EE
-:1018100002000F0081817100310000006C0100D6D0
-:1018200002000F00828171002D000000000000D135
-:1018300002000F00838171002D000000E40768D1D1
-:1018400002000F008481710049000000E33340D1A1
-:1018500002000F00858171003D0000006F0080F7DD
-:1018600002000F00868171002D0000007F0106DD5F
-:1018700002000F0087817100180000007A3D7F1D73
-:1018800002000F0088817100490000006C3600D80A
-:1018900002000F008981710069000000E73300D861
-:1018A00002000F008A81710069000000623100D8D7
-:1018B00002000F008B81710069000000EF3700D833
-:1018C00002000F008C817100310000006C0100D615
-:1018D00002000F008D81710035000000ED0080D600
-:1018E00002000F008E817100080000008100792243
-:1018F00002000F008F817100490000000C0600D625
-:1019000002000F00908171002F000000060181D6B7
-:1019100002000F00918171003F000000020080D49E
-:1019200002000F00928171003F000000840080D40B
-:1019300002000F00938171003F000000020100D5FA
-:1019400002000F00948171003F000000840100D567
-:1019500002000F00958171003F000000020280D557
-:1019600002000F00968171003F000000040280D544
-:1019700002000F00978171003D0000006F0080F7AA
-:1019800002000F00988171002D0000007F0106DD2C
-:1019900002000F0099817100180000007A3D7F1D40
-:1019A00002000F009A817100490000006C3600D8D7
-:1019B00002000F009B81710069000000E93400D82B
-:1019C00002000F009C817100690000006A3500D898
-:1019D00002000F009D81710069000000EF3700D800
-:1019E00002000F009E817100310000006C0100D6E2
-:1019F00002000F009F81710041000000EB3480D491
-:101A000002000F00A0817100410000006B3500D57D
-:101A100002000F00A181710035000000ED0080D6AA
-:101A200002000F00A2817100180000008100EB3756
-:101A300002000F00A3817100490000000D3B00D699
-:101A400002000F00A481710049000000073B80D60E
-:101A500002000F00A58171002D000000000000D1E0
-:101A600002000F00A681710049000000663600DD0B
-:101A700002000F00A781710069000000763B00DDC5
-:101A800002000F00A881710069000000763B00DDB4
-:101A900002000F00A981710069000000763B00DDA3
-:101AA00002000F00AA81710069000000763B00DD92
-:101AB00002000F00AB81710069000000763B00DD81
-:101AC00002000F00AC81710069000000763B00DD70
-:101AD00002000F00AD81710069000000763B00DD5F
-:101AE00002000F00AE81710069000000763B00DD4E
-:101AF00002000F00AF817100610000006C0400F66D
-:101B000002000F00B081710035000000ED0080D6AA
-:101B100002000F00B1817100180000008100EB3756
-:101B200002000F00B2817100490000000E3B00D698
-:101B300002000F00B381710049000000083B80D60D
-:101B400002000F00B481710049000000093B80D5FC
-:101B500002000F00B58171003D0000006F0080F7AA
-:101B600002000F00B68171002D0000007F0106DD2C
-:101B700002000F00B7817100180000007A3D7F1D40
-:101B800002000F00B8817100490000006C3600D8D7
-:101B900002000F00B981710069000000EB3500D828
-:101BA00002000F00BA81710069000000E73300D81D
-:101BB00002000F00BB81710069000000EF3700D800
-:101BC00002000F00BC81710041000000EC0700D64C
-:101BD00002000F00BD817100410000006B0880D53C
-:101BE00002000F00BE81710035000000ED0080D6BC
-:101BF00002000F00BF817100180000008100ED3766
-:101C000002000F00C08171003F00000080FFFFD480
-:101C100002000F00C18171003F000000040002D5E6
-:101C200002000F00C28171003F000000010018D5C2
-:101C300002000F00C3817100490000006A3B00DD13
-:101C400002000F00C481710069000000693B00DDE3
-:101C500002000F00C581710069000000693B00DDD2
-:101C600002000F00C681710021000000EA0000D5CB
-:101C700002000F00C7817100490000006A3B0EDDC1
-:101C800002000F00C8817100350000007A0004D105
-:101C900002000F00C9817100180000008100F537B3
-:101CA00002000F00CA8171003F00000080FFFFD4D6
-:101CB00002000F00CB8171003F000000040004D53A
-:101CC00002000F00CC8171003F000000010018D518
-:101CD00002000F00CD81710069000000693B00DD4A
-:101CE00002000F00CE81710069000000693B00DD39
-:101CF00002000F00CF817100490000006A3B00DD47
-:101D000002000F00D081710051000000EA0000F5D0
-:101D100002000F00D18171003D0000006F0080F7CC
-:101D200002000F00D28171003D0000006F0080F7BB
-:101D300002000F00D3817100490000006A3B0EDDF4
-:101D400002000F00D4817100350000007A8004D1B8
-:101D500002000F00D5817100180000008100F537E6
-:101D600002000F00D68171003F000000047F7FC792
-:101D700002000F00D78171003F000000017F7FC784
-:101D800002000F00D88171003F000000004080D6A3
-:101D900002000F00D98171003F00000000C003D194
-:101DA00002000F00DA81710025000000E20020DE51
-:101DB00002000F00DB817100490000004E2780DE29
-:101DC00002000F00DC8171003D0000006F0080F711
-:101DD00002000F00DD8171003D0000006F0080F700
-:101DE00002000F00DE81710035000000E20000D12A
-:101DF00002000F00DF81710035000000ED0080D689
-:101E000002000F00E0817100180000008100F5372A
-:101E100002000F00E18171003F000000043000DD8E
-:101E200002000F00E28171003F000000010018DD98
-:101E300002000F00E3817100690000003A1D00DD1F
-:101E400002000F00E4817100690000007A3D00DDAE
-:101E500002000F00E58171007D00000013A760C73C
-:101E600002000F00E681710031000000410080C0D7
-:101E700002000F00E781710031000000480000C43B
-:101E800002000F00E881710031000000450080C2AF
-:101E900002000F00E9817100000000000000000056
-:101EA00002000F00EA817100000000000000000045
-:101EB00002000F00EB817100000000000000000034
-:101EC00002000F00EC817100000000000000000023
-:101ED00002000F00ED817100000000000000000012
-:101EE00002000F00EE817100000000000000000001
-:101EF00002000F00EF8171000000000000000000F0
-:101F000002000F00F08171000000000000000000DE
-:101F100002000F00F18171000000000000000000CD
-:101F200002000F00F28171000000000000000000BC
-:101F300002000F00F38171000000000000000000AB
-:101F400002000F00F48171002D000000000000DB92
-:101F500002000F00F58171003F000000043000DD39
-:101F600002000F00F68171003F000000010018DD43
-:101F700002000F00F7817100690000007A3D00DD6A
-:101F800002000F00F88171003F000000040000DD36
-:101F900002000F00F9817100690000007A3D00DD48
-:101FA00002000F00FA8171002D000000000080D3B4
-:101FB00002000F00FB8171003F000000040400DDFF
-:101FC00002000F00FC8171003F000000010018DDDD
-:101FD00002000F00FD81710069000000140A00DD9D
-:101FE00002000F00FE817100690000007A3D00DDF3
-:101FF00002000F00FF81710049000000943304D1FA
-:1020000002000F00008271003F000000840400DD28
-:1020100002000F00018271003F000000010018DD86
-:1020200002000F000282710069000000623100DDD1
-:1020300002000F0003827100690000007A3D00DD9C
-:1020400002000F00048271003F000000040500DD63
-:1020500002000F00058271003F000000010018DD42
-:1020600002000F000682710069000000950A00DD81
-:1020700002000F0007827100690000007A3D00DD58
-:1020800002000F000882710049000000953304D15E
-:1020900002000F00098271003F000000840500DD8E
-:1020A00002000F000A8271003F000000010018DDED
-:1020B00002000F000B82710069000000623100DD38
-:1020C00002000F000C827100690000007A3D00DD03
-:1020D00002000F000D8271003F000000040600DDC9
-:1020E00002000F000E8271003F000000010018DDA9
-:1020F00002000F000F827100690000007A3D00DDD0
-:1021000002000F00108271003F000000840000DD1B
-:1021100002000F0011827100690000007A3D00DDAD
-:1021200002000F00128271003F000000040000DD79
-:1021300002000F00138271003F000000010018DD53
-:1021400002000F001482710069000000160B00DD10
-:1021500002000F0015827100690000007A3D00DD69
-:1021600002000F00168271003F000000041000DD25
-:1021700002000F00178271003F000000010018DD0F
-:1021800002000F0018827100690000007A3D00DD36
-:1021900002000F00198271003F000000040000DD02
-:1021A00002000F001A827100690000007A3D00DD14
-:1021B00002000F001B8271003F000000841000DD50
-:1021C00002000F001C8271003F000000010018DDBA
-:1021D00002000F001D827100690000007A3D00DDE1
-:1021E00002000F001E8271003F000000048001DD2C
-:1021F00002000F001F827100690000007A3D00DDBF
-:1022000002000F00208271003F000000041100DD79
-:1022100002000F00218271003F000000010018DD64
-:1022200002000F0022827100690000007A3D00DD8B
-:1022300002000F00238271003F000000040000DD57
-:1022400002000F0024827100690000007A3D00DD69
-:1022500002000F00258271003F000000841100DDA4
-:1022600002000F00268271003F000000010018DD0F
-:1022700002000F0027827100690000007A3D00DD36
-:1022800002000F00288271003F000000040016DDEC
-:1022900002000F0029827100690000007A3D00DD14
-:1022A00002000F002A8271003F000000041200DDCE
-:1022B00002000F002B8271003F000000010018DDBA
-:1022C00002000F002C827100690000007A3D00DDE1
-:1022D00002000F002D8271003F000000040000DDAD
-:1022E00002000F002E827100690000007A3D00DDBF
-:1022F00002000F002F8271003F000000841200DDF9
-:1023000002000F00308271003F000000010018DD64
-:1023100002000F0031827100690000007A3D00DD8B
-:1023200002000F00328271003F000000040000DD57
-:1023300002000F0033827100690000007A3D00DD69
-:1023400002000F00348271003F000000041300DD22
-:1023500002000F00358271003F000000010018DD0F
-:1023600002000F0036827100690000007A3D00DD36
-:1023700002000F00378271003F000000040000DD02
-:1023800002000F0038827100690000007A3D00DD14
-:1023900002000F00398271003F000000841300DD4D
-:1023A00002000F003A8271003F000000010018DDBA
-:1023B00002000F003B827100690000007A3D00DDE1
-:1023C00002000F003C8271003F000000040005DDA8
-:1023D00002000F003D827100690000007A3D00DDBF
-:1023E00002000F003E8271003F000000042000DD6B
-:1023F00002000F003F8271003F000000010018DD65
-:1024000002000F0040827100690000007A3D00DD8B
-:1024100002000F00418271003F000000040000DD57
-:1024200002000F0042827100690000007A3D00DD69
-:1024300002000F00438271003F000000842000DD95
-:1024400002000F00448271003F000000010018DD0F
-:1024500002000F0045827100690000007A3D00DD36
-:1024600002000F00468271003F000000049001DD71
-:1024700002000F0047827100690000007A3D00DD14
-:1024800002000F00488271003F000000042100DDBF
-:1024900002000F00498271003F000000010018DDBA
-:1024A00002000F004A827100690000007A3D00DDE1
-:1024B00002000F004B8271003F000000840000DD2D
-:1024C00002000F004C827100690000007A3D00DDBF
-:1024D00002000F004D8271003F000000842100DDEA
-:1024E00002000F004E8271003F000000010018DD65
-:1024F00002000F004F827100690000007A3D00DD8C
-:1025000002000F00508271003F000000040000DD57
-:1025100002000F0051827100690000007A3D00DD69
-:1025200002000F00528271003F000000042200DD13
-:1025300002000F00538271003F000000010018DD0F
-:1025400002000F0054827100690000007A3D00DD36
-:1025500002000F00558271003F000000840200DD80
-:1025600002000F0056827100690000007A3D00DD14
-:1025700002000F00578271003F000000842200DD3E
-:1025800002000F00588271003F000000010018DDBA
-:1025900002000F0059827100690000007A3D00DDE1
-:1025A00002000F005A8271003F000000040000DDAD
-:1025B00002000F005B827100690000007A3D00DDBF
-:1025C00002000F005C8271003F000000042300DD68
-:1025D00002000F005D8271003F000000010018DD65
-:1025E00002000F005E827100690000007A3D00DD8C
-:1025F00002000F005F8271003F000000040000DD58
-:1026000002000F0060827100690000007A3D00DD69
-:1026100002000F00618271003F000000041800DD1D
-:1026200002000F00628271003F000000010018DD0F
-:1026300002000F006382710069000000970B00DD4B
-:1026400002000F0064827100690000007A3D00DD25
-:1026500002000F006582710049000000973304D129
-:1026600002000F00668271003F000000841800DD48
-:1026700002000F00678271003F000000010018DDBA
-:1026800002000F006882710069000000623100DD05
-:1026900002000F0069827100690000007A3D00DDD0
-:1026A00002000F006A8271003F000000041900DD83
-:1026B00002000F006B8271003F000000010018DD76
-:1026C00002000F006C82710069000000180C00DD30
-:1026D00002000F006D827100690000007A3D00DD8C
-:1026E00002000F006E82710049000000983304D18F
-:1026F00002000F006F8271003F000000841900DDAE
-:1027000002000F00708271003F000000010018DD20
-:1027100002000F007182710069000000623100DD6B
-:1027200002000F0072827100690000007A3D00DD36
-:1027300002000F00738271003F000000041A00DDE8
-:1027400002000F00748271003F000000010018DDDC
-:1027500002000F0075827100690000007A3D00DD03
-:1027600002000F00768271003F000000040000DDCF
-:1027700002000F0077827100690000007A3D00DDE1
-:1027800002000F00788271003F000000841A00DD13
-:1027900002000F00798271003F000000010018DD87
-:1027A00002000F007A82710069000000160B00DD44
-:1027B00002000F007B827100690000007A3D00DD9D
-:1027C00002000F007C8271003F000000041C00DD4D
-:1027D00002000F007D8271003F000000010018DD43
-:1027E00002000F007E82710069000000990C00DD7C
-:1027F00002000F007F827100690000007A3D00DD59
-:1028000002000F00808271003F000000841C00DD88
-:1028100002000F00818271003F000000010018DDFE
-:1028200002000F0082827100690000001A0D00DDB5
-:1028300002000F0083827100690000007A3D00DD14
-:1028400002000F00848271003F000000041D00DDC3
-:1028500002000F00858271003F000000010018DDBA
-:1028600002000F0086827100690000009B0D00DDF0
-:1028700002000F0087827100690000007A3D00DDD0
-:1028800002000F0088827100490000009B3304D1D0
-:1028900002000F00898271003F000000841D00DDEE
-:1028A00002000F008A8271003F000000010018DD65
-:1028B00002000F008B82710069000000623100DDB0
-:1028C00002000F008C827100690000007A3D00DD7B
-:1028D00002000F008D8271003F000000041E00DD29
-:1028E00002000F008E8271003F000000010018DD21
-:1028F00002000F008F827100690000001C0E00DDD5
-:1029000002000F0090827100690000007A3D00DD36
-:1029100002000F00918271003F000000040100DD01
-:1029200002000F00928271003F000000010018DDDC
-:1029300002000F0093827100690000007A3D00DD03
-:1029400002000F00948271003F000000040F00DDC0
-:1029500002000F0095827100690000007A3D00DDE1
-:1029600002000F00968271007D00000013A760C76F
-:1029700002000F009782710031000000410080C00A
-:1029800002000F009882710031000000480000C46E
-:1029900002000F009982710031000000450080C2E2
-:1029A00002000F009A827100310000006D0080D695
-:1029B0000F000F0064007000000000000000000025
-:1029C00000000000400000000001000000040000C2
-:1029D000640000005400000000000000002400001B
-:1029E0000028000000040000802800008001000092
-:1029F00003000000000000000000000000000000D4
-:102A0000510000007D01000008000000510000009E
-:102A10005D00000000000000090000000050000000
-:102A200000000000000000000F000F00F401700023
-:102A30000000000000000000000000004000000056
-:102A400000010000000400006400000054000000C9
-:102A50000000000000240000002800000004000026
-:102A6000802800008001000003000000000000003A
-:102A70000000000000000000510000007D01000087
-:102A800008000000510000005D0000000000000090
-:102A900009000000005000000000000000000000DD
-:102AA00002000F00000070000100000000000000A4
-:102AB00002000F0000007000010000000000000094
-:102AC00002000F00008071002500000002000EDDF2
-:102AD00002000F000180710004000000763BD1016C
-:102AE00002000F00028071002500000082000EDD50
-:102AF00002000F000380710004000000763B890291
-:102B000002000F00048071002500000002010EDDAC
-:102B100002000F000580710004000000763B850272
-:102B200002000F00068071002500000082010EDD0A
-:102B300002000F000780710004000000763BFD03D7
-:102B400002000F000880710009000000763B81CF71
-:102B500002000F000980710000000000000000006A
-:102B600002000F000A807100000000000000000059
-:102B700002000F000B807100000000000000000048
-:102B800002000F000C807100000000000000000037
-:102B900002000F000D807100000000000000000026
-:102BA00002000F000E807100000000000000000015
-:102BB00002000F000F807100000000000000000004
-:102BC00002000F00108071000000000000000000F3
-:102BD00002000F00118071000000000000000000E2
-:102BE00002000F00128071000000000000000000D1
-:102BF00002000F00138071000000000000000000C0
-:102C000002000F00148071000000000000000000AE
-:102C100002000F001580710000000000000000009D
-:102C200002000F001680710000000000000000008C
-:102C300002000F001780710000000000000000007B
-:102C400002000F001880710000000000000000006A
-:102C500002000F0019807100000000000000000059
-:102C600002000F001A807100000000000000000048
-:102C700002000F001B807100000000000000000037
-:102C800002000F001C807100000000000000000026
-:102C900002000F001D807100000000000000000015
-:102CA00002000F001E807100000000000000000004
-:102CB00002000F001F8071000000000000000000F3
-:102CC00002000F00208071000000000000000000E2
-:102CD00002000F00218071000000000000000000D1
-:102CE00002000F00228071000000000000000000C0
-:102CF00002000F00238071000000000000000000AF
-:102D000002000F002480710000000000000000009D
-:102D100002000F002580710000000000000000008C
-:102D200002000F002680710000000000000000007B
-:102D300002000F002780710000000000000000006A
-:102D400002000F002880710049000000003B00C015
-:102D500002000F002980710049000000023B80C082
-:102D600002000F002A80710049000000033B00C1EF
-:102D700002000F002B80710049000000043B80C15D
-:102D800002000F002C80710029000000760060DF37
-:102D900002000F002D807100490000007D3B44DFE0
-:102DA00002000F002E80710079000000769060FD17
-:102DB00002000F002F8071003D0000006F0080F7BF
-:102DC00002000F00308071003D0000006F0080F7AE
-:102DD00002000F00318071003D0000006F0080F79D
-:102DE00002000F00328071003D0000006F0080F78C
-:102DF00002000F003380710000000000000000009E
-:102E000002000F003480710000000000000000008C
-:102E100002000F003580710000000000000000007B
-:102E200002000F003680710000000000000000006A
-:102E300002000F0037807100000000000000000059
-:102E400002000F0038807100000000000000000048
-:102E500002000F0039807100000000000000000037
-:102E600002000F003A807100000000000000000026
-:102E700002000F003B807100000000000000000015
-:102E800002000F003C807100000000000000000004
-:102E900002000F003D8071000000000000000000F3
-:102EA00002000F003E8071000000000000000000E2
-:102EB00002000F003F8071000000000000000000D1
-:102EC00002000F00408071000000000000000000C0
-:102ED00002000F00418071000000000000000000AF
-:102EE00002000F004280710000000000000000009E
-:102EF00002000F004380710000000000000000008D
-:102F000002000F004480710000000000000000007B
-:102F100002000F004580710000000000000000006A
-:102F200002000F0046807100000000000000000059
-:102F300002000F0047807100000000000000000048
-:102F400002000F0048807100000000000000000037
-:102F500002000F0049807100000000000000000026
-:102F600002000F004A807100000000000000000015
-:102F700002000F004B807100000000000000000004
-:102F800002000F004C8071000000000000000000F3
-:102F900002000F004D8071000000000000000000E2
-:102FA00002000F004E8071000000000000000000D1
-:102FB00002000F004F8071000000000000000000C0
-:102FC00002000F00508071000000000000000000AF
-:102FD00002000F005180710000000000000000009E
-:102FE00002000F005280710000000000000000008D
-:102FF00002000F005380710000000000000000007C
-:1030000002000F005480710000000000000000006A
-:1030100002000F0055807100000000000000000059
-:1030200002000F0056807100000000000000000048
-:1030300002000F0057807100000000000000000037
-:1030400002000F0058807100000000000000000026
-:1030500002000F0059807100000000000000000015
-:1030600002000F005A807100000000000000000004
-:1030700002000F005B8071000000000000000000F3
-:1030800002000F005C8071000000000000000000E2
-:1030900002000F005D8071000000000000000000D1
-:1030A00002000F005E8071000000000000000000C0
-:1030B00002000F005F8071000000000000000000AF
-:1030C00002000F00608071003F000000030000DF7D
-:1030D00002000F00618071002D000000810FE0DD13
-:1030E00002000F00628071003F000000830280DD5B
-:1030F00002000F00638071002D000000800104DDDC
-:1031000002000F00648071007D000000800015FD4A
-:1031100002000F00658071007A000000763B2010ED
-:1031200002000F00668071007A000000767B20307C
-:1031300002000F006780710021000000600024D0B1
-:1031400002000F00688071003F000000040100DDF4
-:1031500002000F00698071003F000000810240DD25
-:1031600002000F006A8071007900000003BB31DDAE
-:1031700002000F006B8071007900000004FB31DD5C
-:1031800002000F006C8071007900000076BB31DD19
-:1031900002000F006D8071007900000076FB31DDC8
-:1031A00002000F006E80710079000000010121FD16
-:1031B00002000F006F8071007D00000081402BFD38
-:1031C00002000F0070807100400000000230003DDE
-:1031D00002000F007180710048000000023B001DDA
-:1031E00002000F007280710079000000767B21DD03
-:1031F00002000F00738071002D0000007F0504DDC8
-:1032000002000F007480710018000000763B7F3DC3
-:1032100002000F00758071003D0000006F0080F714
-:1032200002000F00768071003D0000006F0080F703
-:1032300002000F00778071003D0000006F0080F7F2
-:1032400002000F007880710021000000761F37E334
-:1032500002000F007980710049000000793B00DD19
-:1032600002000F007A8071007900000076BB21DD3A
-:1032700002000F007B80710049000000793B00DDF7
-:1032800002000F007C8071007900000076BB21DD18
-:1032900002000F007D80710049000000793B00DDD5
-:1032A00002000F007E8071007900000076BB21DDF6
-:1032B00002000F007F80710079000000769060FDB1
-:1032C00002000F00808071007900000076FB21DD94
-:1032D00002000F00818071003F000000830000DFCA
-:1032E00002000F00828071003D0000006F0080F737
-:1032F00002000F0083807100000000000000000049
-:1033000002000F0084807100000000000000000037
-:1033100002000F0085807100000000000000000026
-:1033200002000F0086807100000000000000000015
-:1033300002000F0087807100000000000000000004
-:1033400002000F00888071000000000000000000F3
-:1033500002000F00898071000000000000000000E2
-:1033600002000F008A8071000000000000000000D1
-:1033700002000F008B8071000000000000000000C0
-:1033800002000F008C8071000000000000000000AF
-:1033900002000F008D80710000000000000000009E
-:1033A00002000F008E80710000000000000000008D
-:1033B00002000F008F80710000000000000000007C
-:1033C00002000F009080710000000000000000006B
-:1033D00002000F009180710000000000000000005A
-:1033E00002000F0092807100000000000000000049
-:1033F00002000F0093807100000000000000000038
-:1034000002000F0094807100000000000000000026
-:1034100002000F0095807100000000000000000015
-:1034200002000F0096807100000000000000000004
-:1034300002000F00978071000000000000000000F3
-:1034400002000F00988071000000000000000000E2
-:1034500002000F00998071000000000000000000D1
-:1034600002000F009A8071000000000000000000C0
-:1034700002000F009B8071000000000000000000AF
-:1034800002000F009C80710000000000000000009E
-:1034900002000F009D80710000000000000000008D
-:1034A00002000F009E80710000000000000000007C
-:1034B00002000F009F80710000000000000000006B
-:1034C00002000F00A08071002D000000030808D04A
-:1034D00002000F00A18071000800000076FBB521FA
-:1034E00002000F00A280710079000000810001DD60
-:1034F00002000F00A380710079000000028101DD4D
-:1035000002000F00A48071007D000000838001FD97
-:1035100002000F00A580710079000000763B90D07A
-:1035200002000F00A6807100490000007A3B58D0CD
-:1035300002000F00A780710049000000003B04D288
-:1035400002000F00A88071003D000000030040DD74
-:1035500002000F00A9807100240000006402003204
-:1035600002000F00AA8071003D00000003F87FDD1B
-:1035700002000F00AB807100290000007A0120D00A
-:1035800002000F00AC807100490000000E3BA4D087
-:1035900002000F00AD8071002D000000FF4204DD2D
-:1035A00002000F00AE80710018000000763B7F3DE6
-:1035B00002000F00AF8071002D000000820006DDC8
-:1035C00002000F00B080710038000000E001003000
-:1035D00002000F00B180710039000000600100D0CE
-:1035E00002000F00B2807100790000007C3BB1D175
-:1035F00002000F00B38071002D000000E30FE0DD3A
-:1036000002000F00B480710049000000E43080D057
-:1036100002000F00B5807100790000007C7B31DD75
-:1036200002000F00B6807100790000007C3B31DDA4
-:1036300002000F00B78071007D000000824037FD5E
-:1036400002000F00B880710008000000763B7D0189
-:1036500002000F00B98071003D0000006F0080F78C
-:1036600002000F00BA8071003D0000006F0080F77B
-:1036700002000F00BB80710049000000870300DDDD
-:1036800002000F00BC80710079000000080431DDE9
-:1036900002000F00BD807100790000007A7D31DDED
-:1036A00002000F00BE807100490000007C3B00D387
-:1036B00002000F00BF807100790000007CBB81D345
-:1036C00002000F00C08071007F0000007CB201D1B9
-:1036D00002000F00C18071004800000064320051F8
-:1036E00002000F00C28071003D000000030040DDB9
-:1036F00002000F00C38071000800000062319501D4
-:1037000002000F00C480710021000000660600D393
-:1037100002000F00C580710020000000E700805308
-:1037200002000F00C68071003F000000000800DDAD
-:1037300002000F00C78071007900000066B301DD50
-:1037400002000F00C880710079000000E7B301DDBE
-:1037500002000F00C980710075000000628601F14F
-:1037600002000F00CA8071007500000064B101D230
-:1037700002000F00CB80710078000000767B001DF6
-:1037800002000F00CC80710025000000E30100DD85
-:1037900002000F00CD807100080000006231B1010D
-:1037A00002000F00CE8071003D0000006F0080F726
-:1037B00002000F00CF8071003D0000006F0080F715
-:1037C00002000F00D08071003D0000006F0080F704
-:1037D00002000F00D180710021000000639F37E3D9
-:1037E00002000F00D2807100490000007C3B00D332
-:1037F00002000F00D3807100790000007CBB81D3F0
-:1038000002000F00D48071007F0000007CB201D163
-:1038100002000F00D58071004800000064320051A2
-:1038200002000F00D68071007500000064B101D263
-:1038300002000F00D780710078000000767B001D29
-:1038400002000F00D88071003F000000040000DD7E
-:1038500002000F00D98071007900000081C001DDF5
-:1038600002000F00DA80710079000000769060FDA0
-:1038700002000F00DB8071002D000000030808DD4E
-:1038800002000F00DC8071007800000081C0013D63
-:1038900002000F00DD8071003D0000006F0080F726
-:1038A00002000F00DE807100000000000000000038
-:1038B00002000F00DF807100000000000000000027
-:1038C00002000F00E0807100000000000000000016
-:1038D00002000F00E1807100000000000000000005
-:1038E00002000F00E28071000000000000000000F4
-:1038F00002000F00E38071000000000000000000E3
-:1039000002000F00E48071000000000000000000D1
-:1039100002000F00E58071000000000000000000C0
-:1039200002000F00E68071000000000000000000AF
-:1039300002000F00E780710000000000000000009E
-:1039400002000F00E880710049000000033B8ED1A7
-:1039500002000F00E98071002F000000E30081D118
-:1039600002000F00EA8071003F000000031880D1C0
-:1039700002000F00EB80710049000000033B04D1FE
-:1039800002000F00EC8071003F000000030280DDA8
-:1039900002000F00ED80710049000000023B04D2DC
-:1039A00002000F00EE80710049000000003B84D24D
-:1039B00002000F00EF80710025000000E20000DD32
-:1039C00002000F00F08071009400000062411300BB
-:1039D00002000F00F18071009400000062430B00B0
-:1039E00002000F00F280710094000000E248150010
-:1039F00002000F00F38071009400000062491B0078
-:103A000002000F00F48071009400000076402F0047
-:103A100002000F00F5807100090000007A3D81CF9F
-:103A200002000F00F68071001D000000E5802BFDF4
-:103A300002000F00F78071003000000063808331C6
-:103A400002000F00F88071003000000063808211D6
-:103A500002000F00F98071001D000000E58025FDC7
-:103A600002000F00FA807100300000006300833113
-:103A700002000F00FB807100300000006300821123
-:103A800002000F00FC8071002F000000E30081D1D4
-:103A900002000F00FD8071001D000000E58009FD9F
-:103AA00002000F00FE8071003000000063D38331FC
-:103AB00002000F00FF8071003000000063D283110C
-:103AC00002000F00008171002F000000E30081D18F
-:103AD00002000F00018171003F000000840180D6C8
-:103AE00002000F00028171003F000000010080D63B
-:103AF00002000F000381710035000000ED0080D648
-:103B000002000F0004817100180000008100FF37DF
-:103B100002000F000581710025000000640200D240
-:103B200002000F0006817100180000007AFD777D09
-:103B300002000F000781710049000000633B20DE96
-:103B400002000F000881710049000000793B80DE0F
-:103B500002000F000981710021000000E30080D104
-:103B600002000F000A817100090000007A3D81CF38
-:103B700002000F000B81710049000000E33100DDFD
-:103B800002000F000C81710069000000783B0EDD1F
-:103B900002000F000D81710061000000763B00DD26
-:103BA00002000F000E8171003F000000840100DD63
-:103BB00002000F000F8171003F000000010000DDD6
-:103BC00002000F001081710035000000FA0000DDD6
-:103BD00002000F001181710018000000763B7F3B4E
-:103BE00002000F00128171003D0000006F0080F79D
-:103BF00002000F00138171003D0000006F0080F78C
-:103C000002000F00148171003D0000006F0080F77A
-:103C100002000F001581710021000000E30080D137
-:103C200002000F001681710069000000793B04DD7D
-:103C300002000F001781710061000000E30080F1B5
-:103C400002000F00188171003F000000840180D63F
-:103C500002000F00198171003F000000010080D6B2
-:103C600002000F001A81710035000000ED0080D6BF
-:103C700002000F001B817100180000008100FF3757
-:103C800002000F001C81710025000000640200D2B8
-:103C900002000F001D8171009800000076BB5D607E
-:103CA00002000F001E817100090000007A3D81CFE3
-:103CB00002000F001F8171000000000000000000E2
-:103CC00002000F00208171000000000000000000D1
-:103CD00002000F00218171000000000000000000C0
-:103CE00002000F00228171000000000000000000AF
-:103CF00002000F002381710000000000000000009E
-:103D000002000F002481710000000000000000008C
-:103D100002000F002581710000000000000000007B
-:103D200002000F002681710000000000000000006A
-:103D300002000F0027817100000000000000000059
-:103D400002000F0028817100000000000000000048
-:103D500002000F0029817100000000000000000037
-:103D600002000F002A817100000000000000000026
-:103D700002000F002B817100000000000000000015
-:103D800002000F002C817100000000000000000004
-:103D900002000F002D8171000000000000000000F3
-:103DA00002000F002E8171000000000000000000E2
-:103DB00002000F002F8171000000000000000000D1
-:103DC00002000F00308171000000000000000000C0
-:103DD00002000F00318171000000000000000000AF
-:103DE00002000F003281710000000000000000009E
-:103DF00002000F003381710000000000000000008D
-:103E000002000F003481710000000000000000007B
-:103E100002000F003581710000000000000000006A
-:103E200002000F0036817100000000000000000059
-:103E300002000F0037817100000000000000000048
-:103E400002000F0038817100000000000000000037
-:103E500002000F0039817100000000000000000026
-:103E600002000F003A817100000000000000000015
-:103E700002000F003B817100000000000000000004
-:103E800002000F003C8171000000000000000000F3
-:103E900002000F003D8171000000000000000000E2
-:103EA00002000F003E8171000000000000000000D1
-:103EB00002000F003F8171000000000000000000C0
-:103EC00002000F004081710049000000013B08D44E
-:103ED00002000F0041817100090000007A3D8BC291
-:103EE00002000F00428171003F000000800300D4F7
-:103EF00002000F0043817100090000007A3D8BC26F
-:103F000002000F004481710049000000033B0ED401
-:103F100002000F00458171003F000000000042D602
-:103F200002000F00468171002F000000804081D206
-:103F300002000F00478171002D000000650384D24C
-:103F400002000F00488171003F000000800080D611
-:103F500002000F00498171003F000000040004DDF1
-:103F600002000F004A8171003F000000010018DDCF
-:103F700002000F004B817100690000006D3B00DD05
-:103F800002000F004C817100690000006D3B00DDF4
-:103F900002000F004D8171003100000065D203D393
-:103FA00002000F004E81710049000000663B40DEB8
-:103FB00002000F004F8171003F000000840180D695
-:103FC00002000F00508171003F000000010080D608
-:103FD00002000F005181710035000000ED0080D615
-:103FE00002000F0052817100180000008100FF37AD
-:103FF00002000F0053817100490000007E3B80D514
-:1040000002000F005481710021000000E60040DE34
-:1040100002000F00558171003F000000840180D62E
-:1040200002000F00568171003F000000010080D6A1
-:1040300002000F005781710035000000ED0080D6AE
-:1040400002000F0058817100180000008100FF3746
-:1040500002000F0059817100490000007E3B00D52D
-:1040600002000F005A81710079000000763B01DDEB
-:1040700002000F005B8171002D0000007F4004DD15
-:1040800002000F005C81710018000000763B7F3D4C
-:1040900002000F005D8171007900000076BB01DD38
-:1040A00002000F005E81710075000000E88001FDD4
-:1040B00002000F005F81710094000000684115004C
-:1040C00002000F006081710094000000E8442500A8
-:1040D00002000F006181710094000000E84123009C
-:1040E00002000F0062817100940000006845170013
-:1040F00002000F0063817100940000006842150007
-:1041000002000F006481710094000000E842270063
-:1041100002000F00658171009400000068432D00CB
-:1041200002000F00668171009400000068442D00B9
-:1041300002000F006781710094000000E843330023
-:1041400002000F006881710004000000763B9703B5
-:1041500002000F00698171000D00000065C10DE3D0
-:1041600002000F006A817100300000007600033207
-:1041700002000F006B817100300000007600021217
-:1041800002000F006C8171003F000000000080D42D
-:1041900002000F006D8171003F000000008080D19F
-:1041A00002000F006E8171000D00000065C13FE349
-:1041B00002000F006F817100300000007660043251
-:1041C00002000F0070817100300000007640041280
-:1041D00002000F00718171003F000000008082D456
-:1041E00002000F00728171003F000000008080D14A
-:1041F00002000F00738171000D00000065C13FE3F4
-:1042000002000F007481710030000000762004323B
-:1042100002000F007581710030000000760004126A
-:1042200002000F00768171003F000000000082D480
-:1042300002000F00778171000D00000065C163E38B
-:1042400002000F00788171003000000076200332F8
-:1042500002000F0079817100300000007600031227
-:1042600002000F007A8171003F000000000083D43B
-:1042700002000F007B81710049000000763B80D274
-:1042800002000F007C8171000D00000065C10DE38C
-:1042900002000F007D817100300000007680033243
-:1042A00002000F007E817100300000007680021253
-:1042B00002000F007F8171003F000000000081D4E8
-:1042C00002000F00808171003F000000000002D654
-:1042D00002000F00818171003F000000000081D1C9
-:1042E00002000F00828171000D00000065C13FE3F4
-:1042F00002000F008381710030000000762004323C
-:1043000002000F008481710030000000760004126A
-:1043100002000F00858171003F000000000082D480
-:1043200002000F008681710041000000EB3480D450
-:1043300002000F0087817100790000006ABB01DD77
-:1043400002000F00888171007900000076BB01DD5A
-:1043500002000F00898171003F000000031800D2A5
-:1043600002000F008A8171003F000000000081D12F
-:1043700002000F008B81710075000000638001FD59
-:1043800002000F008C81710098000000643B69807E
-:1043900002000F008D81710051000000E40000F266
-:1043A00002000F008E8171003F000000840180D662
-:1043B00002000F008F8171003F000000010080D6D5
-:1043C00002000F009081710035000000ED0080D6E2
-:1043D00002000F0091817100180000008100FF377A
-:1043E00002000F00928171002D0000007F4004DD6B
-:1043F00002000F009381710018000000763B7F3DA2
-:1044000002000F009481710049000000383BC0D3C6
-:1044100002000F009581710049000000643B00DD3F
-:1044200002000F009681710051000000E40000F2CC
-:1044300002000F00978171003F000000840180D6C8
-:1044400002000F00988171003F000000010080D63B
-:1044500002000F009981710035000000ED0080D648
-:1044600002000F009A817100180000008100FF37E0
-:1044700002000F009B81710049000000383BA0D36F
-:1044800002000F009C8171001900000076BB61DD05
-:1044900002000F009D81710049000000673B00DDB4
-:1044A00002000F009E81710075000000638281F19F
-:1044B00002000F009F81710041000000EB3480D4A6
-:1044C00002000F00A0817100790000006ABB01DDCD
-:1044D00002000F00A18171007900000076BB01DDB0
-:1044E00002000F00A28171003F000000031800D2FB
-:1044F00002000F00A38171003F000000008080D106
-:1045000002000F00A481710075000000638001FDAE
-:1045100002000F00A581710098000000643B378005
-:1045200002000F00A681710051000000E40000F2BB
-:1045300002000F00A78171003F000000840180D6B7
-:1045400002000F00A88171003F000000010080D62A
-:1045500002000F00A981710035000000ED0080D637
-:1045600002000F00AA817100180000008100FF37CF
-:1045700002000F00AB8171002D0000007F4004DDC0
-:1045800002000F00AC81710018000000763B7F3DF7
-:1045900002000F00AD81710049000000383B80D35C
-:1045A00002000F00AE8171001900000076BB6FDDC4
-:1045B00002000F00AF81710049000000673B00DD81
-:1045C00002000F00B081710075000000638281F16C
-:1045D00002000F00B181710041000000EB3480D473
-:1045E00002000F00B2817100790000006ABB01DD9A
-:1045F00002000F00B38171007900000063BB01DD90
-:1046000002000F00B481710075000000638001FD9D
-:1046100002000F00B581710098000000643B178014
-:1046200002000F00B681710049000000643B40DECB
-:1046300002000F00B78171003F000000840180D6A6
-:1046400002000F00B88171003F000000010080D619
-:1046500002000F00B981710035000000ED0080D626
-:1046600002000F00BA817100180000008100FF37BE
-:1046700002000F00BB8171002D0000007F4004DDAF
-:1046800002000F00BC81710018000000763B7F3DE6
-:1046900002000F00BD81710021000000E40000D283
-:1046A00002000F00BE817100190000007E7BEFD375
-:1046B00002000F00BF81710075000000638281F16C
-:1046C00002000F00C08171003F000000000080D692
-:1046D00002000F00C18171003F000000040004DDF2
-:1046E00002000F00C28171003F000000010018DDD0
-:1046F00002000F00C3817100690000006D3B00DD06
-:1047000002000F00C4817100690000006D3B00DDF4
-:1047100002000F00C58171003F000000000000DDB5
-:1047200002000F00C68171002D000000800154DDE1
-:1047300002000F00C7817100790000007680E0F36D
-:1047400002000F00C8817100490000007A3600D6CF
-:1047500002000F00C98171007900000076FB01DDC5
-:1047600002000F00CA8171003D0000006F0080F759
-:1047700002000F00CB81710049000000033B00DD07
-:1047800002000F00CC81710059000000763B00FD53
-:1047900002000F00CD8171003F000000031C80DD8E
-:1047A00002000F00CE8171003D0000006F0080F715
-:1047B00002000F00CF8171003D0000006F0080F704
-:1047C00002000F00D08171003D0000006F0080F7F3
-:1047D00002000F00D18171002D0000007F0206DD74
-:1047E00002000F00D2817100180000007A3D7F1D89
-:1047F00002000F00D3817100310000006B8883D468
-:1048000002000F00D4817100790000006ABB01DD55
-:1048100002000F00D581710079000000769081F1CF
-:1048200002000F00D681710075000000638001FD59
-:1048300002000F00D78171009800000076BB538002
-:1048400002000F00D881710019000000797B7FDD24
-:1048500002000F00D981710075000000638281F1B0
-:1048600002000F00DA81710000000000000000006B
-:1048700002000F00DB81710000000000000000005A
-:1048800002000F00DC817100000000000000000049
-:1048900002000F00DD817100000000000000000038
-:1048A00002000F00DE817100000000000000000027
-:1048B00002000F00DF817100000000000000000016
-:1048C00002000F00E0817100000000000000000005
-:1048D00002000F00E18171000000000000000000F4
-:1048E00002000F00E28171000000000000000000E3
-:1048F00002000F00E38171000000000000000000D2
-:1049000002000F00E48171000000000000000000C0
-:1049100002000F00E58171000000000000000000AF
-:1049200002000F00E681710000000000000000009E
-:1049300002000F00E781710000000000000000008D
-:1049400002000F00E881710000000000000000007C
-:1049500002000F00E981710000000000000000006B
-:1049600002000F00EA81710000000000000000005A
-:1049700002000F00EB817100000000000000000049
-:1049800002000F00EC817100000000000000000038
-:1049900002000F00ED817100000000000000000027
-:1049A00002000F00EE817100000000000000000016
-:1049B00002000F00EF817100000000000000000005
-:1049C00002000F00F08171000000000000000000F4
-:1049D00002000F00F18171000000000000000000E3
-:1049E00002000F00F28171000000000000000000D2
-:1049F00002000F00F38171000000000000000000C1
-:104A000002000F00F48171000000000000000000AF
-:104A100002000F00F581710000000000000000009E
-:104A200002000F00F681710000000000000000008D
-:104A300002000F00F781710000000000000000007C
-:104A400002000F00F881710000000000000000006B
-:104A500002000F00F981710000000000000000005A
-:104A600002000F00FA817100000000000000000049
-:104A700002000F00FB817100000000000000000038
-:104A800002000F00FC817100000000000000000027
-:104A900002000F00FD817100000000000000000016
-:104AA00002000F00FE8171003F000000030280DD64
-:104AB00002000F00FF81710049000000023B84D119
-:104AC00002000F000082710049000000033B00DD7E
-:104AD00002000F0001827100690000007A3B00DDD6
-:104AE00002000F000282710049000000793B00DDE6
-:104AF00002000F000382710065000000630280F174
-:104B000002000F000482710018000000763B7D7DDA
-:104B100002000F0005827100090000007A3D81CF7C
-:104B200002000F000682710000000000000000007B
-:104B300002000F000782710000000000000000006A
-:104B400002000F0008827100000000000000000059
-:104B500002000F0009827100000000000000000048
-:104B600002000F000A827100000000000000000037
-:104B700002000F000B827100000000000000000026
-:104B800002000F000C827100000000000000000015
-:104B900002000F000D827100000000000000000004
-:104BA00002000F000E8271000000000000000000F3
-:104BB00002000F000F8271000000000000000000E2
-:104BC00002000F00108271000000000000000000D1
-:104BD00002000F00118271000000000000000000C0
-:104BE00002000F00128271000000000000000000AF
-:104BF00002000F001382710000000000000000009E
-:104C000002000F001482710000000000000000008C
-:104C100002000F001582710000000000000000007B
-:104C200002000F001682710000000000000000006A
-:104C300002000F0017827100000000000000000059
-:104C400002000F0018827100000000000000000048
-:104C500002000F0019827100000000000000000037
-:104C600002000F001A827100000000000000000026
-:104C700002000F001B827100000000000000000015
-:104C800002000F001C827100000000000000000004
-:104C900002000F001D8271000000000000000000F3
-:104CA00002000F001E8271000000000000000000E2
-:104CB00002000F001F8271000000000000000000D1
-:104CC00002000F00208271000000000000000000C0
-:104CD00002000F00218271000000000000000000AF
-:104CE00002000F002282710000000000000000009E
-:104CF00002000F002382710000000000000000008D
-:104D000002000F002482710000000000000000007B
-:104D100002000F002582710000000000000000006A
-:104D200002000F0026827100000000000000000059
-:104D300002000F0027827100000000000000000048
-:104D400002000F0028827100000000000000000037
-:104D500002000F0029827100000000000000000026
-:104D600002000F002A827100000000000000000015
-:104D700002000F002B827100000000000000000004
-:104D800002000F002C8271000000000000000000F3
-:104D900002000F002D8271000000000000000000E2
-:104DA00002000F002E8271000000000000000000D1
-:104DB00002000F002F8271000000000000000000C0
-:104DC00002000F00308271000000000000000000AF
-:104DD00002000F003182710000000000000000009E
-:104DE00002000F003282710000000000000000008D
-:104DF00002000F003382710000000000000000007C
-:104E000002000F003482710000000000000000006A
-:104E100002000F0035827100000000000000000059
-:104E200002000F0036827100000000000000000048
-:104E300002000F0037827100000000000000000037
-:104E400002000F0038827100000000000000000026
-:104E500002000F0039827100000000000000000015
-:104E600002000F003A827100000000000000000004
-:104E700002000F003B8271000000000000000000F3
-:104E800002000F003C8271000000000000000000E2
-:104E900002000F003D8271000000000000000000D1
-:104EA00002000F003E8271000000000000000000C0
-:104EB00002000F003F8271000000000000000000AF
-:104EC00002000F004082710000000000000000009E
-:104ED00002000F004182710000000000000000008D
-:104EE00002000F004282710000000000000000007C
-:104EF00002000F004382710000000000000000006B
-:104F000002000F0044827100000000000000000059
-:104F100002000F0045827100000000000000000048
-:104F200002000F0046827100000000000000000037
-:104F300002000F0047827100000000000000000026
-:104F400002000F0048827100000000000000000015
-:104F500002000F0049827100000000000000000004
-:104F600002000F004A8271000000000000000000F3
-:104F700002000F004B8271000000000000000000E2
-:104F800002000F004C8271000000000000000000D1
-:104F900002000F004D8271000000000000000000C0
-:104FA00002000F004E8271000000000000000000AF
-:104FB00002000F004F82710000000000000000009E
-:104FC00002000F005082710000000000000000008D
-:104FD00002000F005182710000000000000000007C
-:104FE00002000F005282710000000000000000006B
-:104FF00002000F005382710000000000000000005A
-:1050000002000F0054827100000000000000000048
-:1050100002000F0055827100000000000000000037
-:1050200002000F0056827100000000000000000026
-:1050300002000F0057827100000000000000000015
-:1050400002000F0058827100000000000000000004
-:1050500002000F00598271000000000000000000F3
-:1050600002000F005A8271000000000000000000E2
-:1050700002000F005B8271000000000000000000D1
-:1050800002000F005C8271000000000000000000C0
-:1050900002000F005D8271000000000000000000AF
-:1050A00002000F005E82710000000000000000009E
-:1050B00002000F005F82710000000000000000008D
-:1050C00002000F006082710000000000000000007C
-:1050D00002000F006182710000000000000000006B
-:1050E00002000F006282710000000000000000005A
-:1050F00002000F0063827100000000000000000049
-:1051000002000F0064827100000000000000000037
-:1051100002000F0065827100000000000000000026
-:1051200002000F0066827100000000000000000015
-:1051300002000F0067827100000000000000000004
-:1051400002000F00688271000000000000000000F3
-:1051500002000F00698271000000000000000000E2
-:1051600002000F006A8271000000000000000000D1
-:1051700002000F006B8271000000000000000000C0
-:1051800002000F006C8271000000000000000000AF
-:1051900002000F006D82710000000000000000009E
-:1051A00002000F006E82710000000000000000008D
-:1051B00002000F006F82710000000000000000007C
-:1051C00002000F007082710000000000000000006B
-:1051D00002000F007182710000000000000000005A
-:1051E00002000F0072827100000000000000000049
-:1051F00002000F0073827100000000000000000038
-:1052000002000F0074827100000000000000000026
-:1052100002000F0075827100000000000000000015
-:1052200002000F0076827100000000000000000004
-:1052300002000F00778271000000000000000000F3
-:1052400002000F00788271000000000000000000E2
-:1052500002000F00798271000000000000000000D1
-:1052600002000F007A8271000000000000000000C0
-:1052700002000F007B8271000000000000000000AF
-:1052800002000F007C82710000000000000000009E
-:1052900002000F007D82710000000000000000008D
-:1052A00002000F007E82710000000000000000007C
-:1052B00002000F007F82710000000000000000006B
-:1052C00002000F008082710000000000000000005A
-:1052D00002000F0081827100000000000000000049
-:1052E00002000F0082827100000000000000000038
-:1052F00002000F0083827100000000000000000027
-:1053000002000F0084827100000000000000000015
-:1053100002000F0085827100000000000000000004
-:1053200002000F00868271000000000000000000F3
-:1053300002000F00878271000000000000000000E2
-:1053400002000F00888271000000000000000000D1
-:1053500002000F00898271000000000000000000C0
-:1053600002000F008A8271000000000000000000AF
-:1053700002000F008B82710000000000000000009E
-:1053800002000F008C82710000000000000000008D
-:1053900002000F008D82710000000000000000007C
-:1053A00002000F008E82710000000000000000006B
-:1053B00002000F008F82710000000000000000005A
-:1053C00002000F0090827100000000000000000049
-:1053D00002000F0091827100000000000000000038
-:1053E00002000F0092827100000000000000000027
-:1053F00002000F0093827100000000000000000016
-:1054000002000F0094827100000000000000000004
-:1054100002000F00958271000000000000000000F3
-:1054200002000F00968271000000000000000000E2
-:1054300002000F00978271000000000000000000D1
-:1054400002000F00988271000000000000000000C0
-:1054500002000F00998271000000000000000000AF
-:1054600002000F009A82710000000000000000009E
-:1054700002000F009B82710000000000000000008D
-:1054800002000F009C82710000000000000000007C
-:1054900002000F009D82710000000000000000006B
-:1054A00002000F009E82710000000000000000005A
-:1054B00002000F009F827100000000000000000049
-:1054C00002000F00A0827100000000000000000038
-:1054D00002000F00A1827100000000000000000027
-:1054E00002000F00A2827100000000000000000016
-:1054F00002000F00A3827100000000000000000005
-:1055000002000F00A48271000000000000000000F3
-:1055100002000F00A58271000000000000000000E2
-:1055200002000F00A68271000000000000000000D1
-:1055300002000F00A78271000000000000000000C0
-:1055400002000F00A88271000000000000000000AF
-:1055500002000F00A982710000000000000000009E
-:1055600002000F00AA82710000000000000000008D
-:1055700002000F00AB82710000000000000000007C
-:1055800002000F00AC82710000000000000000006B
-:1055900002000F00AD82710000000000000000005A
-:1055A00002000F00AE827100000000000000000049
-:1055B00002000F00AF827100000000000000000038
-:1055C00002000F00B0827100000000000000000027
-:1055D00002000F00B1827100000000000000000016
-:1055E00002000F00B2827100000000000000000005
-:1055F00002000F00B38271000000000000000000F4
-:1056000002000F00B48271000000000000000000E2
-:1056100002000F00B58271000000000000000000D1
-:1056200002000F00B68271000000000000000000C0
-:1056300002000F00B78271000000000000000000AF
-:1056400002000F00B882710000000000000000009E
-:1056500002000F00B982710000000000000000008D
-:1056600002000F00BA82710000000000000000007C
-:1056700002000F00BB82710000000000000000006B
-:1056800002000F00BC82710000000000000000005A
-:1056900002000F00BD827100000000000000000049
-:1056A00002000F00BE827100000000000000000038
-:1056B00002000F00BF827100000000000000000027
-:1056C00002000F00C0827100000000000000000016
-:1056D00002000F00C1827100000000000000000005
-:1056E00002000F00C28271000000000000000000F4
-:1056F00002000F00C38271000000000000000000E3
-:1057000002000F00C48271000000000000000000D1
-:1057100002000F00C58271000000000000000000C0
-:1057200002000F00C68271000000000000000000AF
-:1057300002000F00C782710000000000000000009E
-:1057400002000F00C882710000000000000000008D
-:1057500002000F00C982710000000000000000007C
-:1057600002000F00CA82710000000000000000006B
-:1057700002000F00CB82710000000000000000005A
-:1057800002000F00CC827100000000000000000049
-:1057900002000F00CD827100000000000000000038
-:1057A00002000F00CE827100000000000000000027
-:1057B00002000F00CF827100000000000000000016
-:1057C00002000F00D0827100000000000000000005
-:1057D00002000F00D18271000000000000000000F4
-:1057E00002000F00D28271000000000000000000E3
-:1057F00002000F00D38271000000000000000000D2
-:1058000002000F00D48271000000000000000000C0
-:1058100002000F00D58271000000000000000000AF
-:1058200002000F00D682710000000000000000009E
-:1058300002000F00D782710000000000000000008D
-:1058400002000F00D882710000000000000000007C
-:1058500002000F00D982710000000000000000006B
-:1058600002000F00DA82710000000000000000005A
-:1058700002000F00DB827100000000000000000049
-:1058800002000F00DC827100000000000000000038
-:1058900002000F00DD827100000000000000000027
-:1058A00002000F00DE827100000000000000000016
-:1058B00002000F00DF827100000000000000000005
-:1058C00002000F00E08271000000000000000000F4
-:1058D00002000F00E18271000000000000000000E3
-:1058E00002000F00E28271000000000000000000D2
-:1058F00002000F00E38271000000000000000000C1
-:1059000002000F00E48271000000000000000000AF
-:1059100002000F00E582710000000000000000009E
-:1059200002000F00E682710000000000000000008D
-:1059300002000F00E782710000000000000000007C
-:1059400002000F00E882710000000000000000006B
-:1059500002000F00E982710000000000000000005A
-:1059600002000F00EA827100000000000000000049
-:1059700002000F00EB827100000000000000000038
-:1059800002000F00EC827100000000000000000027
-:1059900002000F00ED827100000000000000000016
-:1059A00002000F00EE827100000000000000000005
-:1059B00002000F00EF8271000000000000000000F4
-:1059C00002000F00F08271000000000000000000E3
-:1059D00002000F00F18271000000000000000000D2
-:1059E00002000F00F28271000000000000000000C1
-:1059F00002000F00F38271000000000000000000B0
-:105A000002000F00F482710000000000000000009E
-:105A100002000F00F582710000000000000000008D
-:105A200002000F00F682710000000000000000007C
-:105A300002000F00F782710000000000000000006B
-:105A400002000F00F882710000000000000000005A
-:105A500002000F00F9827100000000000000000049
-:105A600002000F00FA827100000000000000000038
-:105A700002000F00FB827100000000000000000027
-:105A800002000F00FC827100000000000000000016
-:105A900002000F00FD827100000000000000000005
-:105AA00002000F00FE8271000000000000000000F4
-:105AB00002000F00FF8271000000000000000000E3
-:105AC00002000F00008371000000000000000000D1
-:105AD00002000F00018371000000000000000000C0
-:105AE00002000F00028371000000000000000000AF
-:105AF00002000F000383710000000000000000009E
-:105B000002000F000483710000000000000000008C
-:105B100002000F000583710000000000000000007B
-:105B200002000F000683710000000000000000006A
-:105B300002000F0007837100000000000000000059
-:105B400002000F0008837100000000000000000048
-:105B500002000F0009837100000000000000000037
-:105B600002000F000A837100000000000000000026
-:105B700002000F000B837100000000000000000015
-:105B800002000F000C837100000000000000000004
-:105B900002000F000D8371000000000000000000F3
-:105BA00002000F000E8371000000000000000000E2
-:105BB00002000F000F8371000000000000000000D1
-:105BC00002000F00108371000000000000000000C0
-:105BD00002000F00118371000000000000000000AF
-:105BE00002000F001283710000000000000000009E
-:105BF00002000F001383710000000000000000008D
-:105C000002000F001483710000000000000000007B
-:105C100002000F001583710000000000000000006A
-:105C200002000F0016837100000000000000000059
-:105C300002000F0017837100000000000000000048
-:105C400002000F0018837100000000000000000037
-:105C500002000F0019837100000000000000000026
-:105C600002000F001A837100000000000000000015
-:105C700002000F001B837100000000000000000004
-:105C800002000F001C8371000000000000000000F3
-:105C900002000F001D8371000000000000000000E2
-:105CA00002000F001E8371000000000000000000D1
-:105CB00002000F001F8371000000000000000000C0
-:105CC00002000F00208371000000000000000000AF
-:105CD00002000F002183710000000000000000009E
-:105CE00002000F002283710000000000000000008D
-:105CF00002000F002383710000000000000000007C
-:105D000002000F002483710000000000000000006A
-:105D100002000F0025837100000000000000000059
-:105D200002000F0026837100000000000000000048
-:105D300002000F0027837100000000000000000037
-:105D400002000F0028837100000000000000000026
-:105D500002000F0029837100000000000000000015
-:105D600002000F002A837100000000000000000004
-:105D700002000F002B8371000000000000000000F3
-:105D800002000F002C8371000000000000000000E2
-:105D900002000F002D8371000000000000000000D1
-:105DA00002000F002E8371000000000000000000C0
-:105DB00002000F002F8371000000000000000000AF
-:105DC00002000F003083710000000000000000009E
-:105DD00002000F003183710000000000000000008D
-:105DE00002000F003283710000000000000000007C
-:105DF00002000F003383710000000000000000006B
-:105E000002000F0034837100000000000000000059
-:105E100002000F0035837100000000000000000048
-:105E200002000F0036837100000000000000000037
-:105E300002000F0037837100000000000000000026
-:105E400002000F0038837100000000000000000015
-:105E500002000F0039837100000000000000000004
-:105E600002000F003A8371000000000000000000F3
-:105E700002000F003B8371000000000000000000E2
-:105E800002000F003C8371000000000000000000D1
-:105E900002000F003D8371000000000000000000C0
-:105EA00002000F003E8371000000000000000000AF
-:105EB00002000F003F83710000000000000000009E
-:105EC00002000F004083710000000000000000008D
-:105ED00002000F004183710000000000000000007C
-:105EE00002000F004283710000000000000000006B
-:105EF00002000F004383710000000000000000005A
-:105F000002000F0044837100000000000000000048
-:105F100002000F0045837100000000000000000037
-:105F200002000F0046837100000000000000000026
-:105F300002000F0047837100000000000000000015
-:105F400002000F0048837100000000000000000004
-:105F500002000F00498371000000000000000000F3
-:105F600002000F004A8371000000000000000000E2
-:105F700002000F004B8371000000000000000000D1
-:105F800002000F004C8371000000000000000000C0
-:105F900002000F004D8371000000000000000000AF
-:105FA00002000F004E83710000000000000000009E
-:105FB00002000F004F83710000000000000000008D
-:105FC00002000F005083710000000000000000007C
-:105FD00002000F005183710000000000000000006B
-:105FE00002000F005283710000000000000000005A
-:105FF00002000F0053837100000000000000000049
-:1060000002000F0054837100000000000000000037
-:1060100002000F0055837100000000000000000026
-:1060200002000F0056837100000000000000000015
-:1060300002000F0057837100000000000000000004
-:1060400002000F00588371000000000000000000F3
-:1060500002000F00598371000000000000000000E2
-:1060600002000F005A8371000000000000000000D1
-:1060700002000F005B8371000000000000000000C0
-:1060800002000F005C8371000000000000000000AF
-:1060900002000F005D83710000000000000000009E
-:1060A00002000F005E83710000000000000000008D
-:1060B00002000F005F83710000000000000000007C
-:1060C00002000F006083710000000000000000006B
-:1060D00002000F006183710000000000000000005A
-:1060E00002000F0062837100000000000000000049
-:1060F00002000F0063837100000000000000000038
-:1061000002000F0064837100000000000000000026
-:1061100002000F0065837100000000000000000015
-:1061200002000F0066837100000000000000000004
-:1061300002000F00678371000000000000000000F3
-:1061400002000F00688371000000000000000000E2
-:1061500002000F00698371000000000000000000D1
-:1061600002000F006A8371000000000000000000C0
-:1061700002000F006B8371000000000000000000AF
-:1061800002000F006C83710000000000000000009E
-:1061900002000F006D83710000000000000000008D
-:1061A00002000F006E83710000000000000000007C
-:1061B00002000F006F83710000000000000000006B
-:1061C00002000F007083710000000000000000005A
-:1061D00002000F0071837100000000000000000049
-:1061E00002000F0072837100000000000000000038
-:1061F00002000F0073837100000000000000000027
-:1062000002000F0074837100000000000000000015
-:1062100002000F0075837100000000000000000004
-:1062200002000F00768371000000000000000000F3
-:1062300002000F00778371000000000000000000E2
-:1062400002000F00788371000000000000000000D1
-:1062500002000F00798371000000000000000000C0
-:1062600002000F007A8371000000000000000000AF
-:1062700002000F007B83710000000000000000009E
-:1062800002000F007C83710000000000000000008D
-:1062900002000F007D83710000000000000000007C
-:1062A00002000F007E83710000000000000000006B
-:1062B00002000F007F83710000000000000000005A
-:1062C00002000F0080837100000000000000000049
-:1062D00002000F0081837100000000000000000038
-:1062E00002000F0082837100000000000000000027
-:1062F00002000F0083837100000000000000000016
-:1063000002000F0084837100000000000000000004
-:1063100002000F00858371000000000000000000F3
-:1063200002000F00868371000000000000000000E2
-:1063300002000F00878371000000000000000000D1
-:1063400002000F00888371000000000000000000C0
-:1063500002000F00898371000000000000000000AF
-:1063600002000F008A83710000000000000000009E
-:1063700002000F008B83710000000000000000008D
-:1063800002000F008C83710000000000000000007C
-:1063900002000F008D83710000000000000000006B
-:1063A00002000F008E83710000000000000000005A
-:1063B00002000F008F837100000000000000000049
-:1063C00002000F0090837100000000000000000038
-:1063D00002000F0091837100000000000000000027
-:1063E00002000F0092837100000000000000000016
-:1063F00002000F0093837100000000000000000005
-:1064000002000F00948371000000000000000000F3
-:1064100002000F00958371000000000000000000E2
-:1064200002000F00968371000000000000000000D1
-:1064300002000F00978371000000000000000000C0
-:1064400002000F00988371000000000000000000AF
-:1064500002000F009983710000000000000000009E
-:1064600002000F009A83710000000000000000008D
-:1064700002000F009B83710000000000000000007C
-:1064800002000F009C83710000000000000000006B
-:1064900002000F009D83710000000000000000005A
-:1064A00002000F009E837100000000000000000049
-:1064B00002000F009F837100000000000000000038
-:1064C00002000F00A0837100000000000000000027
-:1064D00002000F00A1837100000000000000000016
-:1064E00002000F00A2837100000000000000000005
-:1064F00002000F00A38371000000000000000000F4
-:1065000002000F00A48371000000000000000000E2
-:1065100002000F00A58371000000000000000000D1
-:1065200002000F00A68371000000000000000000C0
-:1065300002000F00A78371000000000000000000AF
-:1065400002000F00A883710000000000000000009E
-:1065500002000F00A983710000000000000000008D
-:1065600002000F00AA83710000000000000000007C
-:1065700002000F00AB83710000000000000000006B
-:1065800002000F00AC83710000000000000000005A
-:1065900002000F00AD837100000000000000000049
-:1065A00002000F00AE837100000000000000000038
-:1065B00002000F00AF837100000000000000000027
-:1065C00002000F00B0837100000000000000000016
-:1065D00002000F00B1837100000000000000000005
-:1065E00002000F00B28371000000000000000000F4
-:1065F00002000F00B38371000000000000000000E3
-:1066000002000F00B48371000000000000000000D1
-:1066100002000F00B58371000000000000000000C0
-:1066200002000F00B68371000000000000000000AF
-:1066300002000F00B783710000000000000000009E
-:1066400002000F00B883710000000000000000008D
-:1066500002000F00B983710000000000000000007C
-:1066600002000F00BA83710000000000000000006B
-:1066700002000F00BB83710000000000000000005A
-:1066800002000F00BC837100000000000000000049
-:1066900002000F00BD837100000000000000000038
-:1066A00002000F00BE837100000000000000000027
-:1066B00002000F00BF837100000000000000000016
-:1066C00002000F00C0837100000000000000000005
-:1066D00002000F00C18371000000000000000000F4
-:1066E00002000F00C28371000000000000000000E3
-:1066F00002000F00C38371000000000000000000D2
-:1067000002000F00C48371000000000000000000C0
-:1067100002000F00C58371000000000000000000AF
-:1067200002000F00C683710000000000000000009E
-:1067300002000F00C783710000000000000000008D
-:1067400002000F00C883710000000000000000007C
-:1067500002000F00C983710000000000000000006B
-:1067600002000F00CA83710000000000000000005A
-:1067700002000F00CB837100000000000000000049
-:1067800002000F00CC837100000000000000000038
-:1067900002000F00CD837100000000000000000027
-:1067A00002000F00CE837100000000000000000016
-:1067B00002000F00CF837100000000000000000005
-:1067C00002000F00D08371000000000000000000F4
-:1067D00002000F00D18371000000000000000000E3
-:1067E00002000F00D28371000000000000000000D2
-:1067F00002000F00D38371000000000000000000C1
-:1068000002000F00D48371000000000000000000AF
-:1068100002000F00D583710000000000000000009E
-:1068200002000F00D683710000000000000000008D
-:1068300002000F00D783710000000000000000007C
-:1068400002000F00D883710000000000000000006B
-:1068500002000F00D983710000000000000000005A
-:1068600002000F00DA837100000000000000000049
-:1068700002000F00DB837100000000000000000038
-:1068800002000F00DC837100000000000000000027
-:1068900002000F00DD837100000000000000000016
-:1068A00002000F00DE837100000000000000000005
-:1068B00002000F00DF8371000000000000000000F4
-:1068C00002000F00E08371000000000000000000E3
-:1068D00002000F00E18371000000000000000000D2
-:1068E00002000F00E28371000000000000000000C1
-:1068F00002000F00E38371000000000000000000B0
-:1069000002000F00E483710000000000000000009E
-:1069100002000F00E583710000000000000000008D
-:1069200002000F00E683710000000000000000007C
-:1069300002000F00E783710000000000000000006B
-:1069400002000F00E883710000000000000000005A
-:1069500002000F00E9837100000000000000000049
-:1069600002000F00EA837100000000000000000038
-:1069700002000F00EB837100000000000000000027
-:1069800002000F00EC837100000000000000000016
-:1069900002000F00ED837100000000000000000005
-:1069A00002000F00EE8371000000000000000000F4
-:1069B00002000F00EF8371000000000000000000E3
-:1069C00002000F00F08371000000000000000000D2
-:1069D00002000F00F18371000000000000000000C1
-:1069E00002000F00F28371000000000000000000B0
-:1069F00002000F00F383710000000000000000009F
-:106A000002000F00F483710000000000000000008D
-:106A100002000F00F583710000000000000000007C
-:106A200002000F00F683710000000000000000006B
-:106A300002000F00F783710000000000000000005A
-:106A400002000F00F8837100000000000000000049
-:106A500002000F00F9837100000000000000000038
-:106A600002000F00FA837100000000000000000027
-:106A700002000F00FB837100000000000000000016
-:106A800002000F00FC837100000000000000000005
-:106A900002000F00FD8371000000000000000000F4
-:106AA00002000F00FE8371000000000000000000E3
-:106AB00002000F00FF8371000000000000000000D2
-:106AC00002000F00008471000000000000000000C0
-:106AD00002000F00018471000000000000000000AF
-:106AE00002000F000284710000000000000000009E
-:106AF00002000F000384710000000000000000008D
-:106B000002000F000484710000000000000000007B
-:106B100002000F000584710000000000000000006A
-:106B200002000F0006847100000000000000000059
-:106B300002000F0007847100000000000000000048
-:106B400002000F0008847100000000000000000037
-:106B500002000F0009847100000000000000000026
-:106B600002000F000A847100000000000000000015
-:106B700002000F000B847100000000000000000004
-:106B800002000F000C8471000000000000000000F3
-:106B900002000F000D8471000000000000000000E2
-:106BA00002000F000E8471000000000000000000D1
-:106BB00002000F000F8471000000000000000000C0
-:106BC00002000F00108471000000000000000000AF
-:106BD00002000F001184710000000000000000009E
-:106BE00002000F001284710000000000000000008D
-:106BF00002000F001384710000000000000000007C
-:106C000002000F001484710000000000000000006A
-:106C100002000F0015847100000000000000000059
-:106C200002000F0016847100000000000000000048
-:106C300002000F0017847100000000000000000037
-:106C400002000F0018847100000000000000000026
-:106C500002000F0019847100000000000000000015
-:106C600002000F001A847100000000000000000004
-:106C700002000F001B8471000000000000000000F3
-:106C800002000F001C8471000000000000000000E2
-:106C900002000F001D8471000000000000000000D1
-:106CA00002000F001E8471000000000000000000C0
-:106CB00002000F001F8471000000000000000000AF
-:106CC00002000F002084710000000000000000009E
-:106CD00002000F002184710000000000000000008D
-:106CE00002000F002284710000000000000000007C
-:106CF00002000F002384710000000000000000006B
-:106D000002000F0024847100000000000000000059
-:106D100002000F0025847100000000000000000048
-:106D200002000F0026847100000000000000000037
-:106D300002000F0027847100000000000000000026
-:106D400002000F0028847100000000000000000015
-:106D500002000F0029847100000000000000000004
-:106D600002000F002A8471000000000000000000F3
-:106D700002000F002B8471000000000000000000E2
-:106D800002000F002C8471000000000000000000D1
-:106D900002000F002D8471000000000000000000C0
-:106DA00002000F002E8471000000000000000000AF
-:106DB00002000F002F84710000000000000000009E
-:106DC00002000F003084710000000000000000008D
-:106DD00002000F003184710000000000000000007C
-:106DE00002000F003284710000000000000000006B
-:106DF00002000F003384710000000000000000005A
-:106E000002000F0034847100000000000000000048
-:106E100002000F0035847100000000000000000037
-:106E200002000F0036847100000000000000000026
-:106E300002000F0037847100000000000000000015
-:106E400002000F0038847100000000000000000004
-:106E500002000F00398471000000000000000000F3
-:106E600002000F003A8471000000000000000000E2
-:106E700002000F003B8471000000000000000000D1
-:106E800002000F003C8471000000000000000000C0
-:106E900002000F003D8471000000000000000000AF
-:106EA00002000F003E84710000000000000000009E
-:106EB00002000F003F84710000000000000000008D
-:106EC00002000F004084710000000000000000007C
-:106ED00002000F004184710000000000000000006B
-:106EE00002000F004284710000000000000000005A
-:106EF00002000F0043847100000000000000000049
-:106F000002000F0044847100000000000000000037
-:106F100002000F0045847100000000000000000026
-:106F200002000F0046847100000000000000000015
-:106F300002000F0047847100000000000000000004
-:106F400002000F00488471000000000000000000F3
-:106F500002000F00498471000000000000000000E2
-:106F600002000F004A8471000000000000000000D1
-:106F700002000F004B8471000000000000000000C0
-:106F800002000F004C8471000000000000000000AF
-:106F900002000F004D84710000000000000000009E
-:106FA00002000F004E84710000000000000000008D
-:106FB00002000F004F84710000000000000000007C
-:106FC00002000F005084710000000000000000006B
-:106FD00002000F005184710000000000000000005A
-:106FE00002000F0052847100000000000000000049
-:106FF00002000F0053847100000000000000000038
-:1070000002000F0054847100000000000000000026
-:1070100002000F0055847100000000000000000015
-:1070200002000F0056847100000000000000000004
-:1070300002000F00578471000000000000000000F3
-:1070400002000F00588471000000000000000000E2
-:1070500002000F00598471000000000000000000D1
-:1070600002000F005A8471000000000000000000C0
-:1070700002000F005B8471000000000000000000AF
-:1070800002000F005C84710000000000000000009E
-:1070900002000F005D84710000000000000000008D
-:1070A00002000F005E84710000000000000000007C
-:1070B00002000F005F84710000000000000000006B
-:1070C00002000F006084710000000000000000005A
-:1070D00002000F0061847100000000000000000049
-:1070E00002000F0062847100000000000000000038
-:1070F00002000F0063847100000000000000000027
-:1071000002000F0064847100000000000000000015
-:1071100002000F0065847100000000000000000004
-:1071200002000F00668471000000000000000000F3
-:1071300002000F00678471000000000000000000E2
-:1071400002000F00688471000000000000000000D1
-:1071500002000F00698471000000000000000000C0
-:1071600002000F006A8471000000000000000000AF
-:1071700002000F006B84710000000000000000009E
-:1071800002000F006C84710000000000000000008D
-:1071900002000F006D84710000000000000000007C
-:1071A00002000F006E84710000000000000000006B
-:1071B00002000F006F84710000000000000000005A
-:1071C00002000F0070847100000000000000000049
-:1071D00002000F0071847100000000000000000038
-:1071E00002000F0072847100000000000000000027
-:1071F00002000F0073847100000000000000000016
-:1072000002000F0074847100000000000000000004
-:1072100002000F00758471000000000000000000F3
-:1072200002000F00768471000000000000000000E2
-:1072300002000F00778471000000000000000000D1
-:1072400002000F00788471000000000000000000C0
-:1072500002000F00798471000000000000000000AF
-:1072600002000F007A84710000000000000000009E
-:1072700002000F007B84710000000000000000008D
-:1072800002000F007C84710000000000000000007C
-:1072900002000F007D84710000000000000000006B
-:1072A00002000F007E84710000000000000000005A
-:1072B00002000F007F847100000000000000000049
-:1072C00002000F0080847100000000000000000038
-:1072D00002000F0081847100000000000000000027
-:1072E00002000F0082847100000000000000000016
-:1072F00002000F0083847100000000000000000005
-:1073000002000F00848471000000000000000000F3
-:1073100002000F00858471000000000000000000E2
-:1073200002000F00868471000000000000000000D1
-:1073300002000F00878471000000000000000000C0
-:1073400002000F00888471000000000000000000AF
-:1073500002000F008984710000000000000000009E
-:1073600002000F008A84710000000000000000008D
-:1073700002000F008B84710000000000000000007C
-:1073800002000F008C84710000000000000000006B
-:1073900002000F008D84710000000000000000005A
-:1073A00002000F008E847100000000000000000049
-:1073B00002000F008F847100000000000000000038
-:1073C00002000F0090847100000000000000000027
-:1073D00002000F0091847100000000000000000016
-:1073E00002000F0092847100000000000000000005
-:1073F00002000F00938471000000000000000000F4
-:1074000002000F00948471000000000000000000E2
-:1074100002000F00958471000000000000000000D1
-:1074200002000F00968471000000000000000000C0
-:1074300002000F00978471000000000000000000AF
-:1074400002000F009884710000000000000000009E
-:1074500002000F009984710000000000000000008D
-:1074600002000F009A84710000000000000000007C
-:1074700002000F009B84710000000000000000006B
-:1074800002000F009C84710000000000000000005A
-:1074900002000F009D847100000000000000000049
-:1074A00002000F009E847100000000000000000038
-:1074B00002000F009F847100000000000000000027
-:1074C00002000F00A0847100000000000000000016
-:1074D00002000F00A1847100000000000000000005
-:1074E00002000F00A28471000000000000000000F4
-:1074F00002000F00A38471000000000000000000E3
-:1075000002000F00A48471000000000000000000D1
-:1075100002000F00A58471000000000000000000C0
-:1075200002000F00A68471000000000000000000AF
-:1075300002000F00A784710000000000000000009E
-:1075400002000F00A884710000000000000000008D
-:1075500002000F00A984710000000000000000007C
-:1075600002000F00AA84710000000000000000006B
-:1075700002000F00AB84710000000000000000005A
-:1075800002000F00AC847100000000000000000049
-:1075900002000F00AD847100000000000000000038
-:1075A00002000F00AE847100000000000000000027
-:1075B00002000F00AF847100000000000000000016
-:1075C00002000F00B0847100000000000000000005
-:1075D00002000F00B18471000000000000000000F4
-:1075E00002000F00B28471000000000000000000E3
-:1075F00002000F00B38471000000000000000000D2
-:1076000002000F00B48471000000000000000000C0
-:1076100002000F00B58471000000000000000000AF
-:1076200002000F00B684710000000000000000009E
-:1076300002000F00B784710000000000000000008D
-:1076400002000F00B884710000000000000000007C
-:1076500002000F00B984710000000000000000006B
-:1076600002000F00BA84710000000000000000005A
-:1076700002000F00BB847100000000000000000049
-:1076800002000F00BC847100000000000000000038
-:1076900002000F00BD847100000000000000000027
-:1076A00002000F00BE847100000000000000000016
-:1076B00002000F00BF847100000000000000000005
-:1076C00002000F00C08471000000000000000000F4
-:1076D00002000F00C18471000000000000000000E3
-:1076E00002000F00C28471000000000000000000D2
-:1076F00002000F00C38471000000000000000000C1
-:1077000002000F00C48471000000000000000000AF
-:1077100002000F00C584710000000000000000009E
-:1077200002000F00C684710000000000000000008D
-:1077300002000F00C784710000000000000000007C
-:1077400002000F00C884710000000000000000006B
-:1077500002000F00C984710000000000000000005A
-:1077600002000F00CA847100000000000000000049
-:1077700002000F00CB847100000000000000000038
-:1077800002000F00CC847100000000000000000027
-:1077900002000F00CD847100000000000000000016
-:1077A00002000F00CE847100000000000000000005
-:1077B00002000F00CF8471000000000000000000F4
-:1077C00002000F00D08471000000000000000000E3
-:1077D00002000F00D18471000000000000000000D2
-:1077E00002000F00D28471000000000000000000C1
-:1077F00002000F00D38471000000000000000000B0
-:1078000002000F00D484710000000000000000009E
-:1078100002000F00D584710000000000000000008D
-:1078200002000F00D684710000000000000000007C
-:1078300002000F00D784710000000000000000006B
-:1078400002000F00D884710000000000000000005A
-:1078500002000F00D9847100000000000000000049
-:1078600002000F00DA847100000000000000000038
-:1078700002000F00DB847100000000000000000027
-:1078800002000F00DC847100000000000000000016
-:1078900002000F00DD847100000000000000000005
-:1078A00002000F00DE8471000000000000000000F4
-:1078B00002000F00DF8471000000000000000000E3
-:1078C00002000F00E08471000000000000000000D2
-:1078D00002000F00E18471000000000000000000C1
-:1078E00002000F00E28471000000000000000000B0
-:1078F00002000F00E384710000000000000000009F
-:1079000002000F00E484710000000000000000008D
-:1079100002000F00E584710000000000000000007C
-:1079200002000F00E684710000000000000000006B
-:1079300002000F00E784710000000000000000005A
-:1079400002000F00E8847100000000000000000049
-:1079500002000F00E9847100000000000000000038
-:1079600002000F00EA847100000000000000000027
-:1079700002000F00EB847100000000000000000016
-:1079800002000F00EC847100000000000000000005
-:1079900002000F00ED8471000000000000000000F4
-:1079A00002000F00EE8471000000000000000000E3
-:1079B00002000F00EF8471000000000000000000D2
-:1079C00002000F00F08471000000000000000000C1
-:1079D00002000F00F18471000000000000000000B0
-:1079E00002000F00F284710000000000000000009F
-:1079F00002000F00F384710000000000000000008E
-:107A000002000F00F484710000000000000000007C
-:107A100002000F00F584710000000000000000006B
-:107A200002000F00F684710000000000000000005A
-:107A300002000F00F7847100000000000000000049
-:107A400002000F00F8847100000000000000000038
-:107A500002000F00F9847100000000000000000027
-:107A600002000F00FA847100000000000000000016
-:107A700002000F00FB847100000000000000000005
-:107A800002000F00FC8471000000000000000000F4
-:107A900002000F00FD8471000000000000000000E3
-:107AA00002000F00FE8471000000000000000000D2
-:107AB00002000F00FF8471000000000000000000C1
-:107AC00002000F00008571000000000000000000AF
-:107AD00002000F000185710000000000000000009E
-:107AE00002000F000285710000000000000000008D
-:107AF00002000F000385710000000000000000007C
-:107B000002000F000485710000000000000000006A
-:107B100002000F0005857100000000000000000059
-:107B200002000F0006857100000000000000000048
-:107B300002000F0007857100000000000000000037
-:107B400002000F0008857100000000000000000026
-:107B500002000F0009857100000000000000000015
-:107B600002000F000A857100000000000000000004
-:107B700002000F000B8571000000000000000000F3
-:107B800002000F000C8571000000000000000000E2
-:107B900002000F000D8571000000000000000000D1
-:107BA00002000F000E8571000000000000000000C0
-:107BB00002000F000F8571000000000000000000AF
-:107BC00002000F001085710000000000000000009E
-:107BD00002000F001185710000000000000000008D
-:107BE00002000F001285710000000000000000007C
-:107BF00002000F001385710000000000000000006B
-:107C000002000F0014857100000000000000000059
-:107C100002000F0015857100000000000000000048
-:107C200002000F0016857100000000000000000037
-:107C300002000F0017857100000000000000000026
-:107C400002000F0018857100000000000000000015
-:107C500002000F0019857100000000000000000004
-:107C600002000F001A8571000000000000000000F3
-:107C700002000F001B8571000000000000000000E2
-:107C800002000F001C8571000000000000000000D1
-:107C900002000F001D8571000000000000000000C0
-:107CA00002000F001E8571000000000000000000AF
-:107CB00002000F001F85710000000000000000009E
-:107CC00002000F002085710000000000000000008D
-:107CD00002000F002185710000000000000000007C
-:107CE00002000F002285710000000000000000006B
-:107CF00002000F002385710000000000000000005A
-:107D000002000F0024857100000000000000000048
-:107D100002000F0025857100000000000000000037
-:107D200002000F0026857100000000000000000026
-:107D300002000F0027857100000000000000000015
-:107D400002000F0028857100000000000000000004
-:107D500002000F00298571000000000000000000F3
-:107D600002000F002A8571000000000000000000E2
-:107D700002000F002B8571000000000000000000D1
-:107D800002000F002C8571000000000000000000C0
-:107D900002000F002D8571000000000000000000AF
-:107DA00002000F002E85710000000000000000009E
-:107DB00002000F002F85710000000000000000008D
-:107DC00002000F003085710000000000000000007C
-:107DD00002000F003185710000000000000000006B
-:107DE00002000F003285710000000000000000005A
-:107DF00002000F0033857100000000000000000049
-:107E000002000F0034857100000000000000000037
-:107E100002000F0035857100000000000000000026
-:107E200002000F0036857100000000000000000015
-:107E300002000F0037857100000000000000000004
-:107E400002000F00388571000000000000000000F3
-:107E500002000F00398571000000000000000000E2
-:107E600002000F003A8571000000000000000000D1
-:107E700002000F003B8571000000000000000000C0
-:107E800002000F003C8571000000000000000000AF
-:107E900002000F003D85710000000000000000009E
-:107EA00002000F003E85710000000000000000008D
-:107EB00002000F003F85710000000000000000007C
-:107EC00002000F004085710000000000000000006B
-:107ED00002000F004185710000000000000000005A
-:107EE00002000F0042857100000000000000000049
-:107EF00002000F0043857100000000000000000038
-:107F000002000F0044857100000000000000000026
-:107F100002000F0045857100000000000000000015
-:107F200002000F0046857100000000000000000004
-:107F300002000F00478571000000000000000000F3
-:107F400002000F00488571000000000000000000E2
-:107F500002000F00498571000000000000000000D1
-:107F600002000F004A8571000000000000000000C0
-:107F700002000F004B8571000000000000000000AF
-:107F800002000F004C85710000000000000000009E
-:107F900002000F004D85710000000000000000008D
-:107FA00002000F004E85710000000000000000007C
-:107FB00002000F004F85710000000000000000006B
-:107FC00002000F005085710000000000000000005A
-:107FD00002000F0051857100000000000000000049
-:107FE00002000F0052857100000000000000000038
-:107FF00002000F0053857100000000000000000027
-:1080000002000F0054857100000000000000000015
-:1080100002000F0055857100000000000000000004
-:1080200002000F00568571000000000000000000F3
-:1080300002000F00578571000000000000000000E2
-:1080400002000F00588571000000000000000000D1
-:1080500002000F00598571000000000000000000C0
-:1080600002000F005A8571000000000000000000AF
-:1080700002000F005B85710000000000000000009E
-:1080800002000F005C85710000000000000000008D
-:1080900002000F005D85710000000000000000007C
-:1080A00002000F005E85710000000000000000006B
-:1080B00002000F005F85710000000000000000005A
-:1080C00002000F0060857100000000000000000049
-:1080D00002000F0061857100000000000000000038
-:1080E00002000F0062857100000000000000000027
-:1080F00002000F0063857100000000000000000016
-:1081000002000F0064857100000000000000000004
-:1081100002000F00658571000000000000000000F3
-:1081200002000F00668571000000000000000000E2
-:1081300002000F00678571000000000000000000D1
-:1081400002000F00688571000000000000000000C0
-:1081500002000F00698571000000000000000000AF
-:1081600002000F006A85710000000000000000009E
-:1081700002000F006B85710000000000000000008D
-:1081800002000F006C85710000000000000000007C
-:1081900002000F006D85710000000000000000006B
-:1081A00002000F006E85710000000000000000005A
-:1081B00002000F006F857100000000000000000049
-:1081C00002000F0070857100000000000000000038
-:1081D00002000F0071857100000000000000000027
-:1081E00002000F0072857100000000000000000016
-:1081F00002000F0073857100000000000000000005
-:1082000002000F00748571000000000000000000F3
-:1082100002000F00758571000000000000000000E2
-:1082200002000F00768571000000000000000000D1
-:1082300002000F00778571000000000000000000C0
-:1082400002000F00788571000000000000000000AF
-:1082500002000F007985710000000000000000009E
-:1082600002000F007A85710000000000000000008D
-:1082700002000F007B85710000000000000000007C
-:1082800002000F007C85710000000000000000006B
-:1082900002000F007D85710000000000000000005A
-:1082A00002000F007E857100000000000000000049
-:1082B00002000F007F857100000000000000000038
-:1082C00002000F0080857100000000000000000027
-:1082D00002000F0081857100000000000000000016
-:1082E00002000F0082857100000000000000000005
-:1082F00002000F00838571000000000000000000F4
-:1083000002000F00848571000000000000000000E2
-:1083100002000F00858571000000000000000000D1
-:1083200002000F00868571000000000000000000C0
-:1083300002000F00878571000000000000000000AF
-:1083400002000F008885710000000000000000009E
-:1083500002000F008985710000000000000000008D
-:1083600002000F008A85710000000000000000007C
-:1083700002000F008B85710000000000000000006B
-:1083800002000F008C85710000000000000000005A
-:1083900002000F008D857100000000000000000049
-:1083A00002000F008E857100000000000000000038
-:1083B00002000F008F857100000000000000000027
-:1083C00002000F0090857100000000000000000016
-:1083D00002000F0091857100000000000000000005
-:1083E00002000F00928571000000000000000000F4
-:1083F00002000F00938571000000000000000000E3
-:1084000002000F00948571000000000000000000D1
-:1084100002000F00958571000000000000000000C0
-:1084200002000F00968571000000000000000000AF
-:1084300002000F009785710000000000000000009E
-:1084400002000F009885710000000000000000008D
-:1084500002000F009985710000000000000000007C
-:1084600002000F009A85710000000000000000006B
-:1084700002000F009B85710000000000000000005A
-:1084800002000F009C857100000000000000000049
-:1084900002000F009D857100000000000000000038
-:1084A00002000F009E857100000000000000000027
-:1084B00002000F009F857100000000000000000016
-:1084C00002000F00A0857100000000000000000005
-:1084D00002000F00A18571000000000000000000F4
-:1084E00002000F00A28571000000000000000000E3
-:1084F00002000F00A38571000000000000000000D2
-:1085000002000F00A48571000000000000000000C0
-:1085100002000F00A58571000000000000000000AF
-:1085200002000F00A685710000000000000000009E
-:1085300002000F00A785710000000000000000008D
-:1085400002000F00A885710000000000000000007C
-:1085500002000F00A985710000000000000000006B
-:1085600002000F00AA85710000000000000000005A
-:1085700002000F00AB857100000000000000000049
-:1085800002000F00AC857100000000000000000038
-:1085900002000F00AD857100000000000000000027
-:1085A00002000F00AE857100000000000000000016
-:1085B00002000F00AF857100000000000000000005
-:1085C00002000F00B08571000000000000000000F4
-:1085D00002000F00B18571000000000000000000E3
-:1085E00002000F00B28571000000000000000000D2
-:1085F00002000F00B38571000000000000000000C1
-:1086000002000F00B48571000000000000000000AF
-:1086100002000F00B585710000000000000000009E
-:1086200002000F00B685710000000000000000008D
-:1086300002000F00B785710000000000000000007C
-:1086400002000F00B885710000000000000000006B
-:1086500002000F00B985710000000000000000005A
-:1086600002000F00BA857100000000000000000049
-:1086700002000F00BB857100000000000000000038
-:1086800002000F00BC857100000000000000000027
-:1086900002000F00BD857100000000000000000016
-:1086A00002000F00BE857100000000000000000005
-:1086B00002000F00BF8571000000000000000000F4
-:1086C00002000F00C08571000000000000000000E3
-:1086D00002000F00C18571000000000000000000D2
-:1086E00002000F00C28571000000000000000000C1
-:1086F00002000F00C38571000000000000000000B0
-:1087000002000F00C485710000000000000000009E
-:1087100002000F00C585710000000000000000008D
-:1087200002000F00C685710000000000000000007C
-:1087300002000F00C785710000000000000000006B
-:1087400002000F00C885710000000000000000005A
-:1087500002000F00C9857100000000000000000049
-:1087600002000F00CA857100000000000000000038
-:1087700002000F00CB857100000000000000000027
-:1087800002000F00CC857100000000000000000016
-:1087900002000F00CD857100000000000000000005
-:1087A00002000F00CE8571000000000000000000F4
-:1087B00002000F00CF8571000000000000000000E3
-:1087C00002000F00D08571000000000000000000D2
-:1087D00002000F00D18571000000000000000000C1
-:1087E00002000F00D28571000000000000000000B0
-:1087F00002000F00D385710000000000000000009F
-:1088000002000F00D485710000000000000000008D
-:1088100002000F00D585710000000000000000007C
-:1088200002000F00D685710000000000000000006B
-:1088300002000F00D785710000000000000000005A
-:1088400002000F00D8857100000000000000000049
-:1088500002000F00D9857100000000000000000038
-:1088600002000F00DA857100000000000000000027
-:1088700002000F00DB857100000000000000000016
-:1088800002000F00DC857100000000000000000005
-:1088900002000F00DD8571000000000000000000F4
-:1088A00002000F00DE8571000000000000000000E3
-:1088B00002000F00DF8571000000000000000000D2
-:1088C00002000F00E08571000000000000000000C1
-:1088D00002000F00E18571000000000000000000B0
-:1088E00002000F00E285710000000000000000009F
-:1088F00002000F00E385710000000000000000008E
-:1089000002000F00E485710000000000000000007C
-:1089100002000F00E585710000000000000000006B
-:1089200002000F00E685710000000000000000005A
-:1089300002000F00E7857100000000000000000049
-:1089400002000F00E8857100000000000000000038
-:1089500002000F00E9857100000000000000000027
-:1089600002000F00EA857100000000000000000016
-:1089700002000F00EB857100000000000000000005
-:1089800002000F00EC8571000000000000000000F4
-:1089900002000F00ED8571000000000000000000E3
-:1089A00002000F00EE8571000000000000000000D2
-:1089B00002000F00EF8571000000000000000000C1
-:1089C00002000F00F08571000000000000000000B0
-:1089D00002000F00F185710000000000000000009F
-:1089E00002000F00F285710000000000000000008E
-:1089F00002000F00F385710000000000000000007D
-:108A000002000F00F485710000000000000000006B
-:108A100002000F00F585710000000000000000005A
-:108A200002000F00F6857100000000000000000049
-:108A300002000F00F7857100000000000000000038
-:108A400002000F00F8857100000000000000000027
-:108A500002000F00F9857100000000000000000016
-:108A600002000F00FA857100000000000000000005
-:108A700002000F00FB8571000000000000000000F4
-:108A800002000F00FC8571000000000000000000E3
-:108A900002000F00FD8571000000000000000000D2
-:108AA00002000F00FE8571000000000000000000C1
-:108AB00002000F00FF8571000000000000000000B0
-:108AC00002000F000086710000000000000000009E
-:108AD00002000F000186710000000000000000008D
-:108AE00002000F000286710000000000000000007C
-:108AF00002000F000386710000000000000000006B
-:108B000002000F0004867100000000000000000059
-:108B100002000F0005867100000000000000000048
-:108B200002000F0006867100000000000000000037
-:108B300002000F0007867100000000000000000026
-:108B400002000F0008867100000000000000000015
-:108B500002000F0009867100000000000000000004
-:108B600002000F000A8671000000000000000000F3
-:108B700002000F000B8671000000000000000000E2
-:108B800002000F000C8671000000000000000000D1
-:108B900002000F000D8671000000000000000000C0
-:108BA00002000F000E8671000000000000000000AF
-:108BB00002000F000F86710000000000000000009E
-:108BC00002000F001086710000000000000000008D
-:108BD00002000F001186710000000000000000007C
-:108BE00002000F001286710000000000000000006B
-:108BF00002000F001386710000000000000000005A
-:108C000002000F0014867100000000000000000048
-:108C100002000F0015867100000000000000000037
-:108C200002000F0016867100000000000000000026
-:108C300002000F0017867100000000000000000015
-:108C400002000F0018867100000000000000000004
-:108C500002000F00198671000000000000000000F3
-:108C600002000F001A8671000000000000000000E2
-:108C700002000F001B8671000000000000000000D1
-:108C800002000F001C8671000000000000000000C0
-:108C900002000F001D8671000000000000000000AF
-:108CA00002000F001E86710000000000000000009E
-:108CB00002000F001F86710000000000000000008D
-:108CC00002000F002086710000000000000000007C
-:108CD00002000F002186710000000000000000006B
-:108CE00002000F002286710000000000000000005A
-:108CF00002000F0023867100000000000000000049
-:108D000002000F0024867100000000000000000037
-:108D100002000F0025867100000000000000000026
-:108D200002000F0026867100000000000000000015
-:108D300002000F0027867100000000000000000004
-:108D400002000F00288671000000000000000000F3
-:108D500002000F00298671000000000000000000E2
-:108D600002000F002A8671000000000000000000D1
-:108D700002000F002B8671000000000000000000C0
-:108D800002000F002C8671000000000000000000AF
-:108D900002000F002D86710000000000000000009E
-:108DA00002000F002E86710000000000000000008D
-:108DB00002000F002F86710000000000000000007C
-:108DC00002000F003086710000000000000000006B
-:108DD00002000F003186710000000000000000005A
-:108DE00002000F0032867100000000000000000049
-:108DF00002000F0033867100000000000000000038
-:108E000002000F0034867100000000000000000026
-:108E100002000F0035867100000000000000000015
-:108E200002000F0036867100000000000000000004
-:108E300002000F00378671000000000000000000F3
-:108E400002000F00388671000000000000000000E2
-:108E500002000F00398671000000000000000000D1
-:108E600002000F003A8671000000000000000000C0
-:108E700002000F003B8671000000000000000000AF
-:108E800002000F003C86710000000000000000009E
-:108E900002000F003D86710000000000000000008D
-:108EA00002000F003E86710000000000000000007C
-:108EB00002000F003F86710000000000000000006B
-:108EC00002000F004086710000000000000000005A
-:108ED00002000F0041867100000000000000000049
-:108EE00002000F0042867100000000000000000038
-:108EF00002000F0043867100000000000000000027
-:108F000002000F0044867100000000000000000015
-:108F100002000F0045867100000000000000000004
-:108F200002000F00468671000000000000000000F3
-:108F300002000F00478671000000000000000000E2
-:108F400002000F00488671000000000000000000D1
-:108F500002000F00498671000000000000000000C0
-:108F600002000F004A8671000000000000000000AF
-:108F700002000F004B86710000000000000000009E
-:108F800002000F004C86710000000000000000008D
-:108F900002000F004D86710000000000000000007C
-:108FA00002000F004E86710000000000000000006B
-:108FB00002000F004F86710000000000000000005A
-:108FC00002000F0050867100000000000000000049
-:108FD00002000F0051867100000000000000000038
-:108FE00002000F0052867100000000000000000027
-:108FF00002000F0053867100000000000000000016
-:1090000002000F0054867100000000000000000004
-:1090100002000F00558671000000000000000000F3
-:1090200002000F00568671000000000000000000E2
-:1090300002000F00578671000000000000000000D1
-:1090400002000F00588671000000000000000000C0
-:1090500002000F00598671000000000000000000AF
-:1090600002000F005A86710000000000000000009E
-:1090700002000F005B86710000000000000000008D
-:1090800002000F005C86710000000000000000007C
-:1090900002000F005D86710000000000000000006B
-:1090A00002000F005E86710000000000000000005A
-:1090B00002000F005F867100000000000000000049
-:1090C00002000F0060867100000000000000000038
-:1090D00002000F0061867100000000000000000027
-:1090E00002000F0062867100000000000000000016
-:1090F00002000F0063867100000000000000000005
-:1091000002000F00648671000000000000000000F3
-:1091100002000F00658671000000000000000000E2
-:1091200002000F00668671000000000000000000D1
-:1091300002000F00678671000000000000000000C0
-:1091400002000F00688671000000000000000000AF
-:1091500002000F006986710000000000000000009E
-:1091600002000F006A86710000000000000000008D
-:1091700002000F006B86710000000000000000007C
-:1091800002000F006C86710000000000000000006B
-:1091900002000F006D86710000000000000000005A
-:1091A00002000F006E867100000000000000000049
-:1091B00002000F006F867100000000000000000038
-:1091C00002000F0070867100000000000000000027
-:1091D00002000F0071867100000000000000000016
-:1091E00002000F0072867100000000000000000005
-:1091F00002000F00738671000000000000000000F4
-:1092000002000F00748671000000000000000000E2
-:1092100002000F00758671000000000000000000D1
-:1092200002000F00768671000000000000000000C0
-:1092300002000F00778671000000000000000000AF
-:1092400002000F007886710000000000000000009E
-:1092500002000F007986710000000000000000008D
-:1092600002000F007A86710000000000000000007C
-:1092700002000F007B86710000000000000000006B
-:1092800002000F007C86710000000000000000005A
-:1092900002000F007D867100000000000000000049
-:1092A00002000F007E867100000000000000000038
-:1092B00002000F007F867100000000000000000027
-:1092C00002000F0080867100000000000000000016
-:1092D00002000F0081867100000000000000000005
-:1092E00002000F00828671000000000000000000F4
-:1092F00002000F00838671000000000000000000E3
-:1093000002000F00848671000000000000000000D1
-:1093100002000F00858671000000000000000000C0
-:1093200002000F00868671000000000000000000AF
-:1093300002000F008786710000000000000000009E
-:1093400002000F008886710000000000000000008D
-:1093500002000F008986710000000000000000007C
-:1093600002000F008A86710000000000000000006B
-:1093700002000F008B86710000000000000000005A
-:1093800002000F008C867100000000000000000049
-:1093900002000F008D867100000000000000000038
-:1093A00002000F008E867100000000000000000027
-:1093B00002000F008F867100000000000000000016
-:1093C00002000F0090867100000000000000000005
-:1093D00002000F00918671000000000000000000F4
-:1093E00002000F00928671000000000000000000E3
-:1093F00002000F00938671000000000000000000D2
-:1094000002000F00948671000000000000000000C0
-:1094100002000F00958671000000000000000000AF
-:1094200002000F009686710000000000000000009E
-:1094300002000F009786710000000000000000008D
-:1094400002000F009886710000000000000000007C
-:1094500002000F009986710000000000000000006B
-:1094600002000F009A86710000000000000000005A
-:1094700002000F009B867100000000000000000049
-:1094800002000F009C867100000000000000000038
-:1094900002000F009D867100000000000000000027
-:1094A00002000F009E867100000000000000000016
-:1094B00002000F009F867100000000000000000005
-:1094C00002000F00A08671000000000000000000F4
-:1094D00002000F00A18671000000000000000000E3
-:1094E00002000F00A28671000000000000000000D2
-:1094F00002000F00A38671000000000000000000C1
-:1095000002000F00A48671000000000000000000AF
-:1095100002000F00A586710000000000000000009E
-:1095200002000F00A686710000000000000000008D
-:1095300002000F00A786710000000000000000007C
-:1095400002000F00A886710000000000000000006B
-:1095500002000F00A986710000000000000000005A
-:1095600002000F00AA867100000000000000000049
-:1095700002000F00AB867100000000000000000038
-:1095800002000F00AC867100000000000000000027
-:1095900002000F00AD867100000000000000000016
-:1095A00002000F00AE867100000000000000000005
-:1095B00002000F00AF8671000000000000000000F4
-:1095C00002000F00B08671000000000000000000E3
-:1095D00002000F00B18671000000000000000000D2
-:1095E00002000F00B28671000000000000000000C1
-:1095F00002000F00B38671000000000000000000B0
-:1096000002000F00B486710000000000000000009E
-:1096100002000F00B586710000000000000000008D
-:1096200002000F00B686710000000000000000007C
-:1096300002000F00B786710000000000000000006B
-:1096400002000F00B886710000000000000000005A
-:1096500002000F00B9867100000000000000000049
-:1096600002000F00BA867100000000000000000038
-:1096700002000F00BB867100000000000000000027
-:1096800002000F00BC867100000000000000000016
-:1096900002000F00BD867100000000000000000005
-:1096A00002000F00BE8671000000000000000000F4
-:1096B00002000F00BF8671000000000000000000E3
-:1096C00002000F00C08671000000000000000000D2
-:1096D00002000F00C18671000000000000000000C1
-:1096E00002000F00C28671000000000000000000B0
-:1096F00002000F00C386710000000000000000009F
-:1097000002000F00C486710000000000000000008D
-:1097100002000F00C586710000000000000000007C
-:1097200002000F00C686710000000000000000006B
-:1097300002000F00C786710000000000000000005A
-:1097400002000F00C8867100000000000000000049
-:1097500002000F00C9867100000000000000000038
-:1097600002000F00CA867100000000000000000027
-:1097700002000F00CB867100000000000000000016
-:1097800002000F00CC867100000000000000000005
-:1097900002000F00CD8671000000000000000000F4
-:1097A00002000F00CE8671000000000000000000E3
-:1097B00002000F00CF8671000000000000000000D2
-:1097C00002000F00D08671000000000000000000C1
-:1097D00002000F00D18671000000000000000000B0
-:1097E00002000F00D286710000000000000000009F
-:1097F00002000F00D386710000000000000000008E
-:1098000002000F00D486710000000000000000007C
-:1098100002000F00D586710000000000000000006B
-:1098200002000F00D686710000000000000000005A
-:1098300002000F00D7867100000000000000000049
-:1098400002000F00D8867100000000000000000038
-:1098500002000F00D9867100000000000000000027
-:1098600002000F00DA867100000000000000000016
-:1098700002000F00DB867100000000000000000005
-:1098800002000F00DC8671000000000000000000F4
-:1098900002000F00DD8671000000000000000000E3
-:1098A00002000F00DE8671000000000000000000D2
-:1098B00002000F00DF8671000000000000000000C1
-:1098C00002000F00E08671000000000000000000B0
-:1098D00002000F00E186710000000000000000009F
-:1098E00002000F00E286710000000000000000008E
-:1098F00002000F00E386710000000000000000007D
-:1099000002000F00E486710000000000000000006B
-:1099100002000F00E586710000000000000000005A
-:1099200002000F00E6867100000000000000000049
-:1099300002000F00E7867100000000000000000038
-:1099400002000F00E8867100000000000000000027
-:1099500002000F00E9867100000000000000000016
-:1099600002000F00EA867100000000000000000005
-:1099700002000F00EB8671000000000000000000F4
-:1099800002000F00EC8671000000000000000000E3
-:1099900002000F00ED8671000000000000000000D2
-:1099A00002000F00EE8671000000000000000000C1
-:1099B00002000F00EF8671000000000000000000B0
-:1099C00002000F00F086710000000000000000009F
-:1099D00002000F00F186710000000000000000008E
-:1099E00002000F00F286710000000000000000007D
-:1099F00002000F00F386710000000000000000006C
-:109A000002000F00F486710000000000000000005A
-:109A100002000F00F5867100000000000000000049
-:109A200002000F00F6867100000000000000000038
-:109A300002000F00F7867100000000000000000027
-:109A400002000F00F8867100000000000000000016
-:109A500002000F00F9867100000000000000000005
-:109A600002000F00FA8671000000000000000000F4
-:109A700002000F00FB8671000000000000000000E3
-:109A800002000F00FC8671000000000000000000D2
-:109A900002000F00FD8671000000000000000000C1
-:109AA00002000F00FE8671000000000000000000B0
-:109AB00002000F00FF86710000000000000000009F
-:109AC00002000F000087710000000000000000008D
-:109AD00002000F000187710000000000000000007C
-:109AE00002000F000287710000000000000000006B
-:109AF00002000F000387710000000000000000005A
-:109B000002000F0004877100000000000000000048
-:109B100002000F0005877100000000000000000037
-:109B200002000F0006877100000000000000000026
-:109B300002000F0007877100000000000000000015
-:109B400002000F0008877100000000000000000004
-:109B500002000F00098771000000000000000000F3
-:109B600002000F000A8771000000000000000000E2
-:109B700002000F000B8771000000000000000000D1
-:109B800002000F000C8771000000000000000000C0
-:109B900002000F000D8771000000000000000000AF
-:109BA00002000F000E87710000000000000000009E
-:109BB00002000F000F87710000000000000000008D
-:109BC00002000F001087710000000000000000007C
-:109BD00002000F001187710000000000000000006B
-:109BE00002000F001287710000000000000000005A
-:109BF00002000F0013877100000000000000000049
-:109C000002000F0014877100000000000000000037
-:109C100002000F0015877100000000000000000026
-:109C200002000F0016877100000000000000000015
-:109C300002000F0017877100000000000000000004
-:109C400002000F00188771000000000000000000F3
-:109C500002000F00198771000000000000000000E2
-:109C600002000F001A8771000000000000000000D1
-:109C700002000F001B8771000000000000000000C0
-:109C800002000F001C8771000000000000000000AF
-:109C900002000F001D87710000000000000000009E
-:109CA00002000F001E87710000000000000000008D
-:109CB00002000F001F87710000000000000000007C
-:109CC00002000F002087710000000000000000006B
-:109CD00002000F002187710000000000000000005A
-:109CE00002000F0022877100000000000000000049
-:109CF00002000F0023877100000000000000000038
-:109D000002000F0024877100000000000000000026
-:109D100002000F0025877100000000000000000015
-:109D200002000F0026877100000000000000000004
-:109D300002000F00278771000000000000000000F3
-:109D400002000F00288771000000000000000000E2
-:109D500002000F00298771000000000000000000D1
-:109D600002000F002A8771000000000000000000C0
-:109D700002000F002B8771000000000000000000AF
-:109D800002000F002C87710000000000000000009E
-:109D900002000F002D87710000000000000000008D
-:109DA00002000F002E87710000000000000000007C
-:109DB00002000F002F87710000000000000000006B
-:109DC00002000F003087710000000000000000005A
-:109DD00002000F0031877100000000000000000049
-:109DE00002000F0032877100000000000000000038
-:109DF00002000F0033877100000000000000000027
-:109E000002000F0034877100000000000000000015
-:109E100002000F0035877100000000000000000004
-:109E200002000F00368771000000000000000000F3
-:109E300002000F00378771000000000000000000E2
-:109E400002000F00388771000000000000000000D1
-:109E500002000F00398771000000000000000000C0
-:109E600002000F003A8771000000000000000000AF
-:109E700002000F003B87710000000000000000009E
-:109E800002000F003C87710000000000000000008D
-:109E900002000F003D87710000000000000000007C
-:109EA00002000F003E87710000000000000000006B
-:109EB00002000F003F87710000000000000000005A
-:109EC00002000F0040877100000000000000000049
-:109ED00002000F0041877100000000000000000038
-:109EE00002000F0042877100000000000000000027
-:109EF00002000F0043877100000000000000000016
-:109F000002000F0044877100000000000000000004
-:109F100002000F00458771000000000000000000F3
-:109F200002000F00468771000000000000000000E2
-:109F300002000F00478771000000000000000000D1
-:109F400002000F00488771000000000000000000C0
-:109F500002000F00498771000000000000000000AF
-:109F600002000F004A87710000000000000000009E
-:109F700002000F004B87710000000000000000008D
-:109F800002000F004C87710000000000000000007C
-:109F900002000F004D87710000000000000000006B
-:109FA00002000F004E87710000000000000000005A
-:109FB00002000F004F877100000000000000000049
-:109FC00002000F0050877100000000000000000038
-:109FD00002000F0051877100000000000000000027
-:109FE00002000F0052877100000000000000000016
-:109FF00002000F0053877100000000000000000005
-:10A0000002000F00548771000000000000000000F3
-:10A0100002000F00558771000000000000000000E2
-:10A0200002000F00568771000000000000000000D1
-:10A0300002000F00578771000000000000000000C0
-:10A0400002000F00588771000000000000000000AF
-:10A0500002000F005987710000000000000000009E
-:10A0600002000F005A87710000000000000000008D
-:10A0700002000F005B87710000000000000000007C
-:10A0800002000F005C87710000000000000000006B
-:10A0900002000F005D87710000000000000000005A
-:10A0A00002000F005E877100000000000000000049
-:10A0B00002000F005F877100000000000000000038
-:10A0C00002000F0060877100000000000000000027
-:10A0D00002000F0061877100000000000000000016
-:10A0E00002000F0062877100000000000000000005
-:10A0F00002000F00638771000000000000000000F4
-:10A1000002000F00648771000000000000000000E2
-:10A1100002000F00658771000000000000000000D1
-:10A1200002000F00668771000000000000000000C0
-:10A1300002000F00678771000000000000000000AF
-:10A1400002000F006887710000000000000000009E
-:10A1500002000F006987710000000000000000008D
-:10A1600002000F006A87710000000000000000007C
-:10A1700002000F006B87710000000000000000006B
-:10A1800002000F006C87710000000000000000005A
-:10A1900002000F006D877100000000000000000049
-:10A1A00002000F006E877100000000000000000038
-:10A1B00002000F006F877100000000000000000027
-:10A1C00002000F0070877100000000000000000016
-:10A1D00002000F0071877100000000000000000005
-:10A1E00002000F00728771000000000000000000F4
-:10A1F00002000F00738771000000000000000000E3
-:10A2000002000F00748771000000000000000000D1
-:10A2100002000F00758771000000000000000000C0
-:10A2200002000F00768771000000000000000000AF
-:10A2300002000F007787710000000000000000009E
-:10A2400002000F007887710000000000000000008D
-:10A2500002000F007987710000000000000000007C
-:10A2600002000F007A87710000000000000000006B
-:10A2700002000F007B87710000000000000000005A
-:10A2800002000F007C877100000000000000000049
-:10A2900002000F007D877100000000000000000038
-:10A2A00002000F007E877100000000000000000027
-:10A2B00002000F007F877100000000000000000016
-:10A2C00002000F0080877100000000000000000005
-:10A2D00002000F00818771000000000000000000F4
-:10A2E00002000F00828771000000000000000000E3
-:10A2F00002000F00838771000000000000000000D2
-:10A3000002000F00848771000000000000000000C0
-:10A3100002000F00858771000000000000000000AF
-:10A3200002000F008687710000000000000000009E
-:10A3300002000F008787710000000000000000008D
-:10A3400002000F008887710000000000000000007C
-:10A3500002000F008987710000000000000000006B
-:10A3600002000F008A87710000000000000000005A
-:10A3700002000F008B877100000000000000000049
-:10A3800002000F008C877100000000000000000038
-:10A3900002000F008D877100000000000000000027
-:10A3A00002000F008E877100000000000000000016
-:10A3B00002000F008F877100000000000000000005
-:10A3C00002000F00908771000000000000000000F4
-:10A3D00002000F00918771000000000000000000E3
-:10A3E00002000F00928771000000000000000000D2
-:10A3F00002000F00938771000000000000000000C1
-:10A4000002000F00948771000000000000000000AF
-:10A4100002000F009587710000000000000000009E
-:10A4200002000F009687710000000000000000008D
-:10A4300002000F009787710000000000000000007C
-:10A4400002000F009887710000000000000000006B
-:10A4500002000F009987710000000000000000005A
-:10A4600002000F009A877100000000000000000049
-:10A4700002000F009B877100000000000000000038
-:10A4800002000F009C877100000000000000000027
-:10A4900002000F009D877100000000000000000016
-:10A4A00002000F009E877100000000000000000005
-:10A4B00002000F009F8771000000000000000000F4
-:10A4C00002000F00A08771000000000000000000E3
-:10A4D00002000F00A18771000000000000000000D2
-:10A4E00002000F00A28771000000000000000000C1
-:10A4F00002000F00A38771000000000000000000B0
-:10A5000002000F00A487710000000000000000009E
-:10A5100002000F00A587710000000000000000008D
-:10A5200002000F00A687710000000000000000007C
-:10A5300002000F00A787710000000000000000006B
-:10A5400002000F00A887710000000000000000005A
-:10A5500002000F00A9877100000000000000000049
-:10A5600002000F00AA877100000000000000000038
-:10A5700002000F00AB877100000000000000000027
-:10A5800002000F00AC877100000000000000000016
-:10A5900002000F00AD877100000000000000000005
-:10A5A00002000F00AE8771000000000000000000F4
-:10A5B00002000F00AF8771000000000000000000E3
-:10A5C00002000F00B08771000000000000000000D2
-:10A5D00002000F00B18771000000000000000000C1
-:10A5E00002000F00B28771000000000000000000B0
-:10A5F00002000F00B387710000000000000000009F
-:10A6000002000F00B487710000000000000000008D
-:10A6100002000F00B587710000000000000000007C
-:10A6200002000F00B687710000000000000000006B
-:10A6300002000F00B787710000000000000000005A
-:10A6400002000F00B8877100000000000000000049
-:10A6500002000F00B9877100000000000000000038
-:10A6600002000F00BA877100000000000000000027
-:10A6700002000F00BB877100000000000000000016
-:10A6800002000F00BC877100000000000000000005
-:10A6900002000F00BD8771000000000000000000F4
-:10A6A00002000F00BE8771000000000000000000E3
-:10A6B00002000F00BF8771000000000000000000D2
-:10A6C00002000F00C087710079000000769060FDE5
-:10A6D00002000F00C18771003D0000006F0080F78D
-:10A6E00002000F00C28771003D0000006F0080F77C
-:10A6F00002000F00C38771003D0000006F0080F76B
-:10A7000002000F00C48771803D0000006F0080F7D9
-:00000001FF
-/* Loading Firmware */
-/* INT_MEM Ver */
- * Tehuti Networks(R) Network Driver
- * Copyright (C) 2007 Tehuti Networks Ltd. All rights reserved
--- zfcpdump-kernel-4.4.orig/firmware/ti_3410.fw.ihex
+++ /dev/null
@@ -1,862 +0,0 @@
-:10000000C2350002001E021ADBFFFFFFFFFF0232B3
-:10001000CBFFFFFFFFFFFFFFFFFFFFFFFFFF0233ED
-:10002000767581CE90FDE88583A01234EAEC4D60B0
-:100030006A78AB8003760018B89CFA787F800376E4
-:100040000018B865FA78208003760018B820FA9076
-:10005000FDDDAE83AF8290FBF81200A16005E4F0F5
-:10006000A380F690FDE8A88290FDE8A982E8C399F4
-:10007000500576000880F69000FF1200AA90010358
-:100080001200AA9001071200AA90010B1200C8905A
-:1000900001111200C89001171200C875D000123368
-:1000A000C802011DEF65827003EE658322E493F8B8
-:1000B000740193F9740293FE740393F5828E83E8BE
-:1000C00069700122E493F6A30880F4E493FC7401C0
-:1000D00093FD740293FE740393FF740493F8740504
-:1000E00093F58288831200A1700122E493A3A88370
-:1000F000A9828C838D82F0A3AC83AD8288838982B0
-:1001000080E32121049280800492ACAE0492FDE849
-:1001100004940494FBF304990494FBF304F904F9A4
-:1001200080FED0F030F00920F303F68010F7800D48
-:1001300030F10920F303F28004F38001F020F4048D
-:10014000FCD0E0CC22CCC0E012015A02014BBC0032
-:1001500005D0F0ACF022C313DCFC020121BF000982
-:10016000ED258275F001F8E622BF010FED2582F53D
-:1001700082EE3583F58375F004E022ED258275F07B
-:1001800002F8E222D083D082F5F0C3E493A3C5F055
-:1001900095F0C0E0C3D0F0E493A395F04012A3A380
-:1001A000C3E5F033500205832582F58250020583B2
-:1001B000740193C0E0E493C0E022D083D082F5F0D4
-:1001C000E49370097401937004A3A3800C740293E8
-:1001D00065F06005A3A3A380E7740193C0E0E493F6
-:1001E000C0E02212025B0201F21202AF0201F2121F
-:1001F00002D30201F230E00720E302E622E72230D8
-:10020000E10720E302E222E32230E202E022E4936B
-:10021000221202D302021A1202AF02021AABF01229
-:100220000224CBC5F0CB2230E01020E306E6F5F047
-:1002300008E622E7F5F009E7192230E11020E3068D
-:10024000E2F5F008E222E3F5F009E3192230E206D4
-:10025000E0F5F0A3E022E493F5F074019322BB00F3
-:1002600003740922BB010789828A83740422BB02BA
-:100270000789828A83741022740A2202027BBB00DF
-:1002800007E92582F8740122BB010DE92582F58278
-:10029000EA3583F583740422BB020DE92582F582D9
-:1002A000EA3583F583741022E92582F8740222026C
-:1002B00002AFBF0005EDF8740122BF01078D828EE9
-:1002C00083740422BF02078D828E83741022EDF89E
-:1002D0007402220202D3BF0007ED2582F8740122C6
-:1002E000BF010DED2582F582EE3583F5837404227E
-:1002F000BF020DED2582F582EE3583F58374102261
-:10030000ED2582F8740222020307C0E012025B02AC
-:10031000031FC0E01202AF02031FC0E01202D302AB
-:10032000031F30E00B20E304D0E0F622D0E0F722F8
-:1003300030E10B20E304D0E0F222D0E0F322D0E061
-:10034000F022C9CDC9CACECACBCFCB120352EDF928
-:10035000EEFAEFFB22BB002FBF000AFAEDF8E7F63A
-:100360000809DAFA22BF01128D828E83F802036F28
-:1003700009A3E7F0D8FA2202037AFAEDF8E7F208C7
-:1003800009DAFA22020384BB014DBF001489828A74
-:1003900083F9EDF802039608A3E0F6D9FA220203E6
-:1003A000A7BF01228D828E83FB08C9C582C9CAC539
-:1003B00083CAE0A3C9C582C9CAC583CAF0A3DBEA60
-:1003C000D8E8220203CA8D828E83F9EDF8E0F208A4
-:1003D000A3D9FA220203D4BB024DBF001289828A3C
-:1003E00083F9EDF80203E608A3E493F6D9F922BFF6
-:1003F00001238D828E83FB08C9C582C9CAC583CA01
-:10040000E493A3C9C582C9CAC583CAF0A3DBE9D8EE
-:10041000E72202041989828A83F9EDF8E493F2084D
-:10042000A3D9F92202042ABF000DFAEDF8E3F60879
-:1004300009DAFA22020434BF01128D828E83F80297
-:10044000044109A3E3F0D8FA2202044CFAEDF8E3E0
-:10045000F20809DAFA22020456E6FB08E6FA08E690
-:10046000F904F61870010622E6FF08E6FE08E6FD2C
-:1004700022EFF0A3EEF0A3EDF022EBF0A3EAF0A35D
-:10048000E9F022E0FFA3E0FEA3E0FD22E0FBA3E011
-:10049000FAA3E0F9220000000000000004F9006166
-:1004A00005680026058F00330A0000610A6C0066AB
-:1004B000151D00610CF0006109A0006109D7006101
-:1004C0000DB700610BE800610A1300610A48006182
-:1004D00017150033172800341DF600431EA10044F1
-:1004E000200E00441FFC00471EC800471F6D004D32
-:1004F0001FBE004F1EEA0058325600617CCC7DFFC3
-:10050000121CA72290FFFCE020E72DC2AFAE59AF2E
-:1005100058755A20E55A14C55A6019E4FE7F05EE55
-:100520004FCE24FFCECF34FFCF6007E490FF92F090
-:1005300080ED80E08E598F58221205017D077CB72F
-:100540001232727D0F7C6E12328C789D7A06E4F640
-:1005500008DAFC7A061205C47C03120E4C12214AFA
-:10056000E4FEFF7C0F1231FBD2A8221230E6E490A9
-:10057000FC38F090FFF0E030E408740190FC39F0B2
-:100580008005E490FC39F07D0A7C001225261231AA
-:1005900069221230E690FC39E014700E90FFF0E012
-:1005A0004410F07C001225BF801990FC39E0700ED9
-:1005B00090FFF0E054EFF07C001225BF80057C171F
-:1005C0001225BF1231692290FFF0E054ABF090FF8A
-:1005D000F0E04420F0228C378D367882EDF608EC7E
-:1005E000F6EDFEECFD7F019000051201EC7880F63F
-:1005F0007882E6FD08E6FCEDFEECFD7F019000044C
-:100600001201EC540FFC7D801217467880E6700DC5
-:10061000AD3AAE39AF38E412030F7C082290FFF0F8
-:10062000E054FEF090FFF0E054FDF0801E7882E68A
-:10063000FD08E6FCEDFEECFD7F0190000812020EC5
-:1006400025E0440190FFF3F00206D07882E6FD0831
-:10065000E6FCEDFEECFD7F0190000612020E54FE5A
-:1006600090FFF3F0802B7882E6FD08E6FCEDFEECCF
-:10067000FD7F0190000812020EFAEB90FFF1F012DC
-:1006800008BF400DAD3AAE39AF38E412030F7C1805
-:10069000227882E6FD08E6FCEDFEECFD7F0190008D
-:1006A0000812020E90FFF1F01208BF400DAD3AAEF5
-:1006B00039AF38E412030F7C18227882E6FD08E691
-:1006C000FCEDFEECFD7F0190000612020E4401904D
-:1006D000FFF3F07883E62403F618E63400F678801A
-:1006E000E624FE500990FFF0E054FDF0800790FFF3
-:1006F000F0E04402F0E490FFF1F078817600788039
-:10070000E624FFFCE434FFFD7881E67F00FEECD3B5
-:100710009EEF6480CD64809D402F1208A4400F7826
-:1007200081E6AD3AAE39AF3812030F7C182290FF44
-:10073000F2E0FC78828683088682ECF0788106A35A
-:100740007882A68308A68280B51208A4400F78811B
-:10075000E6AD3AAE39AF3812030F7C182290FFF2A3
-:10076000E0FC78828683088682ECF07880E6AD3AF9
-:10077000AE39AF3812030F7C00228C378D36788269
-:10078000EDF608ECF6EDFEECFD7F019000051201A0
-:10079000EC7881F67882E6FD08E6FCEDFEECFD7F64
-:1007A000019000041201EC540FFC7D811217467871
-:1007B00081E670037C082290FFF0E054FEF090FF89
-:1007C000F0E054FDF0801B7882E6FD08E6FCEDFECB
-:1007D000ECFD7F0190000812020E25E090FFF3F07F
-:1007E000805B7882E6FD08E6FCEDFEECFD7F019083
-:1007F000000612020E54FE90FFF3F080217882E68C
-:10080000FD08E6FCEDFEECFD7F0190000812020EF3
-:10081000FAEB90FFF1F01208BF40037C18227882B7
-:10082000E6FD08E6FCEDFEECFD7F019000081202FB
-:100830000E90FFF1F01208BF40037C18227883E687
-:10084000240AF618E63400F6788076007881E624EB
-:10085000FFFCE434FFFD7880E67F00FEECD39EEFE2
-:100860006480CD64809D402178828683088682E002
-:1008700090FFF1F01208BF40037C182278800678C0
-:100880008306E61870010680C390FFF0E04401F093
-:1008900078828683088682E090FFF1F01208BF40DC
-:1008A000037C18227C002290FFF0E020E71290FFEA
-:1008B000F0E030E50990FFF0E04420F0C32280E74B
-:1008C000D32290FFF0E020E31290FFF0E030E50942
-:1008D00090FFF0E04420F0C32280E7D3228C428DC9
-:1008E000417C00ED54F0FDEC7003ED643070057553
-:1008F0003E038003753E04AC3E120F69758300858C
-:100900008340E541540FF53FE5407004E53F640343
-:100910007035E53E24FD75F00AA42402F582E43426
-:10092000FCF583E030E60512104B8019E53E249D6E
-:10093000F8C654FBF678A9E62405F58218E63400DB
-:10094000F583740FF08059E5407004E53F6404704E
-:1009500048E53E24FD75F00AA42402F582E434FC47
-:10096000F583E030E507AC42AD41121C3CE5423076
-:10097000E21578ADE630E00F78ADE630E109E4FF4E
-:1009800004FE7C041231FB78A9E62406F58218E601
-:100990003400F583740FF08007E4FC7DEE121C3CFC
-:1009A000C203221230E6120F6978A9E62406F58206
-:1009B00018E63400F583E090FC38F078A9E62405C9
-:1009C000F58218E63400F583E090FC39F0C2037D2F
-:1009D000027C00122526123169221230E67895EC4D
-:1009E000F6EC249DF8E630E1077C131225BF800F5A
-:1009F00090FC39E0FD7895E6FC1213C81225BF1271
-:100A00003169221230E67895ECF67D00120F09125A
-:100A100025BF123169221230E67895ECF6EC249D60
-:100A2000F8E630E2077C131225BF801B7895E62498
-:100A30009DF8E620E1077C121225BF800A7895E632
-:100A4000FC1213EC1225BF123169221230E67895A0
-:100A5000ECF6EC249DF8E620E2077C111225BF801D
-:100A60000A7895E6FC1214ED1225BF1231692212A4
-:100A700030E67895ECF6120F6978A9E62409F5823C
-:100A800018E63400F583E090FC3FF078A9E6240AEC
-:100A9000F58218E63400F583E090FC40F078A9E692
-:100AA0002403F58218E63400F583E0FC78A9E624F7
-:100AB00004F58218E63400F583E0F56278A9E624AF
-:100AC00002F58218E63400F583E0F5638C61E4EC0E
-:100AD000333354017895F66008E56230E103789588
-:100AE000067895E690FC41F078A7E62402F5821896
-:100AF000E63400F583E0FDA3E0540CFCED54E68CF5
-:100B000065F564E56130E503436501E56220E50EC6
-:100B1000E561547F7008E56120E703436502E56104
-:100B200030E303436510E56130E203436520E5618E
-:100B300054036003436540E56130E103436580E5AC
-:100B40006130E403436401E56130E603436408E592
-:100B50006220E40EE561547F7008E56120E70343FD
-:100B600064105365FB536479AD64E56590FC3ACD40
-:100B7000F0A3CDF0E56330E30DE5635430C4540FCA
-:100B800090FC3DF08005E490FC3DF0E5635403905B
-:100B9000FC3CF0E5635404C31390FC3EF090FC3C35
-:100BA000E0700E7D357EFC7F01740190000912011A
-:100BB0004278A9E62408F58218E63400F583E07C43
-:100BC00000FD78A9E62407F58218E63400F583E0F5
-:100BD0007F004CFEEF4D90FC38F0A3CEF0CEC20368
-:100BE0007D0A7C00122526123169221230E67895A2
-:100BF000ECF6789A76010876FC0876387897760CC9
-:100C0000789A1204651202147898CBF6CB08F67F16
-:100C100000EF24EA401FE4EF25E090352CFD93CD52
-:100C200004937899667003ED1866700678977600DD
-:100C300080030F80DC7896EFF6789A1204659000B6
-:100C40000212020E7898CBF6CB08F65404CB5486E9
-:100C50004B60047897760B7899E630E313789A1214
-:100C600004659000051201EC24FB50047897760D82
-:100C70007899E654C07D0064C04D70047897760B77
-:100C8000789A1204659000041201EC24FC50047858
-:100C900097760F789A1204659000061201EC24FDF5
-:100CA00050047897760E789A120465900009120124
-:100CB000EC24FD50047897760A7897E6702A7895A8
-:100CC000E6FC120F69789A12046578A7E6F978A60F
-:100CD000E6FA7B01740A780012033FC2037895E6B6
-:100CE000FC1211077897ECF67897E6FC1225BF12F4
-:100CF0003169221230E67895ECF6120F697895E6A4
-:100D000024FD75F00AA42414F582E434FCF583ACC8
-:100D100082AD8378A68683088682ECF9EDFA7B0A99
-:100D200078011203A7C2037895E6FC12110712316D
-:100D300069228D2B8C2AED60407527017529487535
-:100D400028FFE52A24FDFCE434FFFDEC7C0325E0CC
-:100D5000CD33CDDCF9FCE5292CF529E5283DF52836
-:100D6000AD29AE28AF277480900006120317748057
-:100D7000900002120317120FB7E52B14603B752782
-:100D8000017529087528FFE52A24FDFCE434FFFDE0
-:100D9000EC7C0325E0CD33CDDCF9FCE5292CF529ED
-:100DA000E5283DF528AD29AE28AF27E490000612CE
-:100DB0000317E4900002120317221230E67895EC34
-:100DC000F6EC249DF8E630E2097895E6FC1214ED85
-:100DD000D2007895E6FC120F697896760090FC397F
-:100DE000E030E704789676017896E6FD7895E6FCA3
-:100DF000120D2FC2033000077895E6FC1213EC7C2D
-:100E0000001225BF1231692278A9E62404F5821860
-:100E1000E63400F583E04401F078A9E62404F58285
-:100E200018E63400F583E030E00280ED78A9E6248E
-:100E30000BF58218E63400F583E054F8F078A9E663
-:100E40002402F58218E63400F583E04480F022C2E3
-:100E5000038C58120F6978A68683088682795D7A9A
-:100E6000357B0A78011203F5120E05AC587D02128B
-:100E70000D2FC203AC58121107228D538E528F5181
-:100E80008C50120F69754F0078A9E62405F5821879
-:100E9000E63400F583E020E41FE54F24F640190511
-:100EA0004FC2037C181232A990FF93E04401F0B2C4
-:100EB000B3AC50120F6980D078A9E62405F58218EA
-:100EC000E63400F583E020E405C2037C022278A921
-:100ED000E62405F58218E63400F583E0540F601629
-:100EE00078A9E62405F58218E63400F583E0540F6E
-:100EF000F0C2037C012278A88683088682E0AD5385
-:100F0000AE52AF5112030FC2037C00228D318C30E0
-:100F10001214EDE531600FE530B4030A7C011224B0
-:100F2000EE7C811224EEAC30120F69E531601A7844
-:100F3000AA8683088682E054E7F0A3A3A3A3E05423
-:100F4000E7F0AC307D02120D2F78A68683088682EA
-:100F500079677A357B0A78011203F5C203E53024FC
-:100F60009DF8C654FDF6AC30121107228C263003D2
-:100F70000512324880F87C0A12315BD203E5262440
-:100F8000FD78A3F6700778AA76FF0876E078A3E6E6
-:100F900075F010A4ADF0FC24A078A9F6ED34FF188C
-:100FA000F678A3E675F00AA42400FCE434FCFD788E
-:100FB000A6EDF608ECF61231F42278A9E62402F543
-:100FC0008218E63400F583E030E72278A9E62402AF
-:100FD000F58218E63400F583E0547FF078A9E62422
-:100FE00002F58218E63400F583E04480F02278AA06
-:100FF0008683088682E0547FF0AD83E5822404FC7A
-:10100000E43D8C82F583E0547FF078A9E6240BF56B
-:101010008218E63400F583E054F8F078ABE624015A
-:10102000F58218E63400F583E04403F078ABE6245B
-:1010300005F58218E63400F583E04403F078A9E66C
-:101040002405F58218E63400F583740FF02278AA9F
-:101050008683088682E0543FF0AD83E5822404FC59
-:10106000E43D8C82F583E0543FF078A3E624A4F8B5
-:10107000E6FC78ABE62401F58218E63400F583EC53
-:10108000F078A3E624A4F8E6FC78ABE62405F58224
-:1010900018E63400F583ECF078A9E6240BF5821805
-:1010A000E63400F583E054FB4402F52678A7E624F5
-:1010B00002F58218E63400F583E030E503432601AB
-:1010C00078A9E62405F58218E63400F583E030E0DF
-:1010D00003120FB7E526FC78A9E6240BF58218E683
-:1010E0003400F583ECF078A9E62405F58218E6349F
-:1010F00000F583740FF078AA8683088682E0448026
-:10110000F0A3A3A3A3E04480F0228C2A120F6978F5
-:10111000A7E62408F58218E63400F583E0FC78A9F8
-:10112000E6240AF58218E63400F583ECF078A7E6A9
-:101130002407F58218E63400F583E0FC78A9E6245C
-:1011400009F58218E63400F583ECF078A68683086A
-:101150008682E0FDA3E0FCEDFE78A9E62408F58296
-:1011600018E63400F583EEF0ECFE78A9E62407F5E6
-:101170008218E63400F583EEF08C298D28C3EC94B8
-:1011800005ED940C400575277C8033D3E529940147
-:10119000E5289403400575273C8023D3E5299481F5
-:1011A000E528940140057527188013D3E52994603C
-:1011B000E5289400400575270C8003752708AF27A4
-:1011C000E4EF547C4483FF8F27E527FC78ABE624CB
-:1011D00001F58218E63400F583ECF0E527FC78ABE6
-:1011E000E62405F58218E63400F583ECF0E527FCEB
-:1011F00078A3E624A4F8ECF678A9E62402F5821890
-:10120000E63400F583E0F52778A7E62402F5821896
-:10121000E63400F583A3E030E3175327C778A7E649
-:101220002405F58218E63400F583E09035589342A2
-:10123000275327FB78A7E62406F58218E63400F545
-:1012400083E060034327045327FC78A7E62404F5D2
-:101250008218E63400F583E04227432780E527FC27
-:1012600078A9E62402F58218E63400F583ECF078DC
-:10127000A9E62404F58218E63400F583E0F5277822
-:10128000A7E62402F58218E63400F583A3E030E1F6
-:10129000055327DF800343272078A7E62402F58241
-:1012A00018E63400F583E030E4055327EF8003436C
-:1012B000271078A7E62409F58218E63400F583E0C4
-:1012C000B40203432702E527FC78A9E62404F5824B
-:1012D00018E63400F583ECF078A9E62403F58218CB
-:1012E000E63400F583E0F52778A7E62409F58218AF
-:1012F000E63400F583E0700553277F8003432780A1
-:1013000078A7E62402F58218E63400F583A3E030DE
-:10131000E00543272080035327DF78A7E62402F562
-:101320008218E63400F583E030E30543274080036C
-:101330005327BF78A7E62402F58218E63400F58328
-:10134000E030E00543271080035327EF78A7E62419
-:1013500002F58218E63400F583A3E030E405432764
-:101360000880035327F778A7E62402F58218E634AD
-:1013700000F583A3E030E50543270480035327FBF2
-:1013800078A7E62402F58218E63400F583A3E0305E
-:10139000E60543270180035327FE78A7E62402F5DC
-:1013A0008218E63400F583A3E030E7054327028086
-:1013B000035327FDE527FC78A9E62403F58218E608
-:1013C0003400F583ECF0C2037C00228D278C26EDDF
-:1013D00054031460037C1022E527547C24FC400352
-:1013E0007C0B22E526249DF8C64402F67C00228C64
-:1013F00030120F69E530249DF8E620E24FAC307DD5
-:1014000002120D2FE53024FE4428FC78AA868308BA
-:101410008682ECF0AF83E5822404FEE43FFFEC8E8D
-:10142000828F83F07C038C2CE52CFC78ABE62401C6
-:10143000F58218E63400F583ECF0E52CFC78ABE699
-:101440002405F58218E63400F583ECF0752D01755E
-:101450002F48752EFFE53024FDFCE434FFFDEC7CC5
-:101460000325E0CD33CDDCF9FCE52F2CF52FE52E5F
-:101470003DF52E78ABE62404F58218E63400F583BA
-:10148000E054E7F52CAD2FAE2EAF2DE49000021204
-:101490000317E49000061203171201E630E5034338
-:1014A0002C10E52CFC78ABE62404F58218E6340019
-:1014B000F583ECF012104B78A9E62406F58218E6C5
-:1014C0003400F583E0C203FCE530249DF8C64404F3
-:1014D000F68C2CE530540FC454F07E00FFEEEF4440
-:1014E000047D00FFEC4EFCED4FFD121CA77C00229A
-:1014F0008C2F120F69120FEB78AA8683088682E080
-:101500005408F0A3A3A3A3E05408F0AC2F7D02126B
-:101510000D2FC203E52F249DF8C654FBF67C002254
-:101520001230E67896ECF6EC249DF8E630E10A7D80
-:10153000007C131225261231697896E6249DF8C6A0
-:101540004401F67896E6FC120F697896E624FD755C
-:10155000F00AA42414F582E434FCF58378A6E6FAB4
-:1015600008E6F97B0A78011203A778A68683088625
-:101570008279677A357B0A78011203F5120FB7C2B8
-:10158000037896E6FC1211077895ECF6EC600A7D7C
-:10159000007C081225261231697896E6FC120F6944
-:1015A00078A9E62404F58218E63400F583E04410B7
-:1015B00054DFFC78A9E62404F58218E63400F583AC
-:1015C000ECF07895ECF6C2037CC81232A97896E666
-:1015D000FC120F6978A9E62404F58218E63400F5B8
-:1015E00083E054EFF0C2037CC81232A97896E6FC7F
-:1015F000120F6978A9E62404F58218E63400F58311
-:10160000E04410F0C2037CC81232A97896E6FC12BE
-:101610000F6978A9E62404F58218E63400F583E022
-:101620004420F0C2037CF01232A97896E6FC120F37
-:101630006978A9E62405F58218E63400F583E030E0
-:10164000E415C2037896E644107F00FE7C07123151
-:10165000FB12316902171478A9E62404F58218E612
-:101660003400F583E054CFF0C2037CC81232A9786D
-:1016700096E6FC120F6978A9E62404F58218E63490
-:1016800000F583E04430F0C2037CF01232A9789672
-:10169000E6FC120F6978A9E62405F58218E6340005
-:1016A000F583E030E414C2037896E644107F00FE30
-:1016B0007C071231FB123169805D78A9E62404F5BC
-:1016C0008218E63400F583E054EFF078A9E62404AC
-:1016D000F58218E63400F583E054DFF07896E624CE
-:1016E000FD75F00AA42414F582E434FCF583AC8281
-:1016F000AD8378A68683088682ECF9EDFA7B0A78BA
-:10170000011203A7C2037896E6FC1211077D007C44
-:101710000B122526123169221230E6E490FC39F0D2
-:101720007D027C00122526123169221230E67C00EF
-:101730001225BF12316922743C90FBE0F0743E9098
-:10174000FBE0F0E490FC28F0228D358C34ECB40101
-:10175000028003D340028028B402028003D34008F1
-:10176000A835C625E0F68018B404028003D3400AE9
-:10177000A835C625E025E0F68006A835760080006D
-:10178000228C3C8D3BEDFEECFD7F01756606756796
-:101790000090FC2912046E1201E6B480028006D388
-:1017A000500302184790FC29120480900003120194
-:1017B000EC54F0B430028003D3405F90FC29120453
-:1017C0008090000812020EFAFDEBFE7F0190FC2CC7
-:1017D00012046EEECD903571FCE493FF740193FE1C
-:1017E000F9EFFA7B01EAFFE9FEECC39EED9F40258D
-:1017F000903573E493FD740193FCEDFEECFD7F01E5
-:10180000EECDFC90FC2EE0D39C90FC2DE09D50058D
-:101810007566808033121965802EB460028003D310
-:10182000400BAC3CAD3B1207778C66801BB41003B9
-:10183000B34010C3B42003B34009C3B440028003D3
-:10184000D3400075668180008075B481028003D327
-:10185000406B90FC291204809000031201EC54F0BC
-:10186000B430028003D3401D90FC29120480900004
-:101870000812020EFAFDEBFE7F0190FC2F12046E9F
-:101880001218CF8036B460028003D34013753A67D4
-:10189000E4F539F538AC3CAD3B1205D38C66801BC2
-:1018A000B41003B34010C3B42003B34009C3B44021
-:1018B000028003D34000756681800080028000E5CD
-:1018C00066FC90FC29120480EC900002120317AC15
-:1018D000672290FC291204809000041201EC60043D
-:1018E00074018001E4A2E0920190FC29120480EDD1
-:1018F0002403FD50010E90FC2C12046E90FC291262
-:1019000004809000051201ECF5679000041201ECD0
-:10191000540FFC7D67121746E56770047566082250
-:10192000756600788476007884E6C39567503890B1
-:10193000FC2F1204801201E6FC90FC2C120480ECB7
-:1019400012030F30010E90FC31E004F090FC307077
-:1019500003E004F078840690FC2EE004F090FC2D67
-:101960007003E004F080C02290FC2AE0FDA3E0FCBC
-:10197000EDFEECFD7F01ED240AFD50010E90FC32DE
-:1019800012046E90FC291204809000041201EC54A1
-:101990000FB401028003D3401790FC321204800D73
-:1019A000ED70010E90FC2F12046E78887601804E47
-:1019B000B402028003D3401990FC32120480ED245B
-:1019C00002FD50010E90FC2F12046E788876028082
-:1019D0002DB404028003D3401990FC32120480ED30
-:1019E0002404FD50010E90FC2F12046E78887604BA
-:1019F000800CB400028003D340007566082290FC7E
-:101A0000291204809000051201ECF56778857600B4
-:101A10007885E6C395674003021ACD78867600780C
-:101A200086E6C3788896507690FC2C1204801201CA
-:101A3000E6FC90FC321204891201E0F45CFC120115
-:101A4000E0F890FC2F120480E8C0E01201E6C8D054
-:101A5000E0C8584CFC90FC2C120480EC12030F7868
-:101A600087ECF690FC31E004F090FC307003E00469
-:101A7000F009E970010A90FC3212047790FC2912F7
-:101A800004809000041201EC30E40E90FC2EE0047F
-:101A9000F090FC2D7003E004F07886068081788851
-:101AA000E6FDE4FEFFEECDFC90FC31E02CF090FC76
-:101AB00030E03DF07888E6FDE4FEFFEECDFC90FCE2
-:101AC00034E02CF090FC33E03DF0788506021A0DEE
-:101AD00075660022E53D053D047002B2B022C0E00B
-:101AE000C0F0C082C083C0D0E8C0E0E9C0E0EAC076
-:101AF000E0EBC0E0ECC0E0EDC0E0EEC0E0EFC0E045
-:101B000090FF92E01201B71B29301B29321B383895
-:101B10001B4A3A1B5C3E1B74441B68461B80501BCF
-:101B2000C2521BA1541BE35600001C0490FF92E01C
-:101B30007F00FE7C011231FB021C14E4FF04FE7CDA
-:101B4000031231FB742090FFFEF0021C14E4FF042A
-:101B5000FE7C021231FB744090FFFEF0021C14E484
-:101B6000FF04FE7C041231FB021C14E4FF04FE7C23
-:101B7000051231FB021C14E4FF04FE7C061231FB4B
-:101B8000021C1490FFA5E07D0090FBF8CDF0A3CDE2
-:101B9000F090FBF9E0FCF58390FBF8E04433FD1294
-:101BA0001CA7807390FFB5E07D0090FBFACDF0A3F9
-:101BB000CDF090FBFBE0FCF58390FBFAE04443FDA5
-:101BC000121CA7805290FFA6E07D0090FBFCCDF098
-:101BD000A3CDF090FBFDE0FCF58390FBFCE04434EA
-:101BE000FD121CA7803190FFB6E07D0090FBFECD7A
-:101BF000F0A3CDF090FBFFE0FCF58390FBFEE0440A
-:101C000044FD121CA7801090FF92E07D00FCED4483
-:101C1000AAFD121CA78000E490FF92F0D0E0FFD054
-:101C2000E0FED0E0FDD0E0FCD0E0FBD0E0FAD0E078
-:101C3000F9D0E0F8D0D0D083D082D0F0D0E0320517
-:101C400081058105810581A881181818EDF608EC39
-:101C5000F690FF5AE020E70280F790FF59E07D0000
-:101C6000A88118CDF6CD08F67D03A881E618FCE61C
-:101C7000CC25E0CC33CCDDF9CCF6CC08F6A8811825
-:101C8000E644F8F6A881181818E6FD08E6FCA881D5
-:101C9000188683088682EDF0A3ECF0740290FF5A58
-:101CA000F0158115811581158122E5812405F581C5
-:101CB000E4A88118F6A88118181818EDF608ECF6B3
-:101CC00090FBF5E024F85003021DC8E4A881181821
-:101CD000F6A88118E6FEA88118181818E6FD08E68F
-:101CE000FC7F00EF24F8404DE4EF25E0247DF582F1
-:101CF000E434FCF583E0FBA3E06C7003FAEB6D7059
-:101D0000097401A8811818F6802BE4EF25E0247DE2
-:101D1000F582E434FCF5837A00E054F0CCF8CCCDC5
-:101D2000F9CDFB7800E954F0F9EA687002EB6970CC
-:101D3000010E0F80AEA88118EEF6A88118181818A9
-:101D4000EDF608ECF6A881EFF6A8811818E6707990
-:101D5000A88118E624F74071A88118181818E654CD
-:101D60000FA881F664046017A881E664036010A8D8
-:101D70008118181818E6FD08E6FC121C3C804A7C05
-:101D80000A12315BA88118181818E6FD08E6FC90C5
-:101D9000FBF4E025E0247DF582E434FCF583EDF0EE
-:101DA000A3ECF090FBF4E0FFE4EF045407FF90FB9A
-:101DB000F4F090FBF5E004F01231F490FBF6E070E3
-:101DC00008E4FEFF7C0F1231FB802790FBF7E00454
-:101DD000F0543F701D90FBF7E044FE7D00FC90FB4B
-:101DE000F4E025E0247DF582E434FCF583EDF0A3F6
-:101DF000ECF0E58124FBF58122788B7600788C76F7
-:101E000000740190FBF6F01230E690FBF5E06057AD
-:101E10007C0A12315B90FBF3E025E0247DF582E43F
-:101E200034FCF583E0FDA3E0FC90FBF3E025E02427
-:101E30007DF582E434FCF583E4F0A3F090FBF3E05D
-:101E4000FFE4EF045407FF90FBF3F090FBF5E01480
-:101E5000F07889EDF608ECF61231F47889E6FD08A1
-:101E6000E6FC1208DA80A312324890FF93E04401A6
-:101E7000F0B2B3788B06B60011788B7600788CE6DA
-:101E8000F40404A2E092B4788CF6021E07E490FBFE
-:101E9000F6F090FBF5E07D00FCED44CFFD121C3C1C
-:101EA000123169221230E6E5706449456F60159081
-:101EB000FF83E0540F7D00D39570ED956F500512B0
-:101EC0002F2F8003122FFF123169221230E6E570A6
-:101ED0006449456F6005123039800E90FF80E04400
-:101EE00008F090FF83E0547FF0123169221230E64F
-:101EF0008C54EC54F0B41015756A357569FC75682E
-:101F000001E56A2403F56AE5693400F569E4F557EB
-:101F1000F556E556C394015027E554540FFCAD6ABD
-:101F2000AE69AF68120E778C55EC60028012056ABC
-:101F3000E56A700205690557E5577002055680D2BB
-:101F4000E554540F249DF8C654FEF6E554540F7F13
-:101F500000FE7C121231FBE5551470097D007C09EE
-:101F60001225268007AD577C0012252612316922E2
-:101F70001230E690FFFCE04402F090FF00E030E712
-:101F80001390FF83E04480F0436D8090FFFCE044B9
-:101F900001F0801190FF82E04408F0536D7F90FFC4
-:101FA000FCE054FEF090FF81E04480F01225D990CF
-:101FB000FFFEE04405F090FFFCE054FDF0123169B3
-:101FC000221230E67C011232A978ADE64402F674A2
-:101FD000FEFC04FD121CA790FF5AE030E70280F7D8
-:101FE000E4F54E754D10AC4EAD4DE54E154E7002FC
-:101FF000154DEC4D600280EE4387011231692212CB
-:1020000030E67C0212317578ADE654FDF612316986
-:10201000221230E678ADE630E02C78ADE630E126ED
-:1020200078ADE6FCF58318E644F0FD121C3C90FF09
-:10203000FCE04420F07C021232A978ADE654FDF6B3
-:10204000741A90FFFEF078ADE6FCF58318E644F1D3
-:10205000FD121C3C12316922756D0090FFFFE0609B
-:1020600003436D01756E00E4F56CF56BE4F56F7577
-:102070007049748490FF82F0748490FF80F07480C3
-:1020800090FF58F0748090FF5AF0AD46AF457E0047
-:10209000EE24FE5003022124E4EE75F007A4247F11
-:1020A000F582E434F8F583E0FFE4EF5480FDE4EFDB
-:1020B000540F14FFED6038E4EF75F008A42448F5E0
-:1020C00082E434FFF5837490F0E4EF75F008A42403
-:1020D0004AF582E434FFF5837480F0E4EF75F0088C
-:1020E000A4244EF582E434FFF5837480F08034E458
-:1020F000EF75F008A42408F582E434FFF5837490AA
-:10210000F0E4EF75F008A4240AF582E434FFF583C7
-:10211000E4F0E4EF75F008A4240EF582E434FFF552
-:1021200083E4F00E02208D8D468E448F45747F909F
-:10213000FFFDF0749090FFFCF0228C58EC24F650D8
-:1021400006E5582437FC22E5582430FC22122523CA
-:10215000EC700302225E755C03AE5B7F00E55C15EC
-:102160005C6480247F5035EF2400F582E434FBF575
-:1021700083E0FE24FE501EEF7D00FCE4FB7474C37C
-:102180009CFAEB9DFBEE7D00FCEAC39CED6480CBEA
-:1021900064809B50028005EF2EFF80C18E5B8F5ABA
-:1021A000E55C6480247F500302225EE55A248E5051
-:1021B0000302225E855A5D755B00AE5AAF5B9035B7
-:1021C0009CE493F55CE55C155C6480247F5018EE1C
-:1021D0002400F582E434FBF583E0FCEF90359C931A
-:1021E0006C70040E0F80DE8E5A8F5BE55C64802479
-:1021F0007F406E755E017560E8755FFFE55D2402E6
-:10220000F55A755C07E55C334057AD60AE5FAF5E75
-:10221000E55CF5823395E0F5831201ECC4540FFCC4
-:10222000122137E55A2400F582E434FBF583ECF003
-:10223000055A055AAD60AE5FAF5EE55CF582339539
-:10224000E0F5831201EC540FFC122137E55A24000B
-:10225000F582E434FBF583ECF0055A055A155C80F1
-:10226000A4740290F851F090F86B79757A357B2759
-:1022700078011203F5756A357569FC756801E4909B
-:10228000FF83F0748090FF81F0755902E55975F075
-:1022900007A4247FF582E434F8F583E0788FF6FC18
-:1022A000540F14FC788FECF6E55975F007A42481DF
-:1022B000F582E434F8F583E0789276FD0876E8FC60
-:1022C000788FE675F008A42448F582E434FFF5839E
-:1022D000E4F0788FE675F008A4244FF582E434FF2B
-:1022E000F583ECF07892E6FF08E67E03CFC313CFC8
-:1022F00013DEF9FE788FE675F008A42449F582E430
-:1023000034FFF583EEF0788FE675F008A4244AF5E3
-:1023100082E434FFF5837480F07890ECF67D0078E9
-:1023200093E62CF618E63DF67892E6FD08E67C0387
-:10233000CDC313CD13DCF9FC788FE675F008A42427
-:102340004DF582E434FFF583ECF0788FE675F00804
-:10235000A4244EF582E434FFF583E4F07892E6FDA0
-:1023600008E6FC788FE6FF7E00EE24FE5003022490
-:10237000DDE4EE75F007A4247FF582E434F8F583FC
-:10238000E0FFE4EF5480FAE4EF540F14FFE4EE753D
-:10239000F007A42481F582E434F8F583E07890F620
-:1023A000E4EE1313548024F0F8E434FDF9E8FCE97A
-:1023B000FD8A5AEA700302244AE4EF75F008A42467
-:1023C00048F582E434FFF583E4F07890E6FAE4EF30
-:1023D00075F008A4244FF582E434FFF583EAF0EDAC
-:1023E000FBEC7A03CBC313CB13DAF9FAE4EF75F005
-:1023F00008A42449F582E434FFF583EAF07890E6F6
-:102400007B00FAEC2AFCED3BFDFBEC7A03CBC3131B
-:10241000CB13DAF9FAE4EF75F008A4244DF582E461
-:1024200034FFF583EAF0E4EF75F008A4244AF5825E
-:10243000E434FFF5837480F0E4EF75F008A4244ED3
-:10244000F582E434FFF5837480F00224D9E4EF755B
-:10245000F008A42408F582E434FFF583E4F07890D2
-:10246000E6FAE4EF75F008A4240FF582E434FFF5F2
-:1024700083EAF0EDFBEC7A03CBC313CB13DAF9FA62
-:10248000E4EF75F008A42409F582E434FFF583EA4B
-:10249000F07890E67B00FAEC2AFCED3BFDFBEC7A51
-:1024A00003CBC313CB13DAF9FAE4EF75F008A424D5
-:1024B0000DF582E434FFF583EAF0E4EF75F008A44B
-:1024C000240AF582E434FFF583E4F0E4EF75F008C4
-:1024D000A4240EF582E434FFF583E4F00E022366B3
-:1024E0008E597892EDF608ECF6788FEFF6122055BB
-:1024F000228C26EC30E718E526540F1475F008A45A
-:102500002448F582E434FFF583E054DFF08016E5DB
-:1025100026540F1475F008A42408F582E434FFF55E
-:1025200083E054DFF0227C0022EC90FC37F08C2416
-:10253000ED2403F5257D00D39572ED95714003855B
-:102540007225E52524B75009752503740290FC37E0
-:10255000F0AC2512302422E4F56CF56B12255D22D7
-:1025600090FC35E06573600E740490FC37F0E4F580
-:102570006B756C0380467D73E4FEFF79357AFC7BD6
-:10258000017405780012033FE56C2403F56CE56BDC
-:102590003400F56BE56CD39572E56B95714006855B
-:1025A000726C85716BD3E56C9448E56B9400400CBC
-:1025B000740290FC37F0E4F56B756C03AC6C123070
-:1025C0002422EC90FC37F0E4F56CF56B8C32EC6077
-:1025D0000512301580057C001230242290FF93E014
-:1025E0004401F0B2B390FF04E0F54A90FF06E0FD2D
-:1025F000A3E0ED7D00FC7D00FC90FF06E0FFA3E082
-:102600007E00FFE4FEEC4EFCED4FFDC3EC9448ED84
-:102610009400502290FF06E0FDA3E0ED7D00FC7DDC
-:1026200000FC90FF06E0FFA3E07E00FFE4FEEC4E1E
-:10263000FCED4FFD8004E4FD7C488C728D7190FFB1
-:1026400002E0FDA3E0ED7D00FC7D00FC90FF02E0D8
-:10265000FFA3E07E00FFE4FEEC4EF54CED4FF54BA2
-:10266000756A357569FC7568017D357EFC7F017979
-:1026700073E4FAFB7405780012033F754900E549DD
-:1026800024FE4019AD6AAE69AF68E412030F054934
-:102690000DED70010E8D6A8E698F6880E1756A3567
-:1026A0007569FC75680190FF00E05460B400028019
-:1026B00006D35003022C6DE54A540FF549E54A5400
-:1026C00080A2E0920290FF01E0120181000B2C68D1
-:1026D00026E528032C68290F2C6829F22A262B8D41
-:1026E0002B902BD02C112C3FE56D30E70EE54C459F
-:1026F0004B7008E572640245716003022C6A90FF1A
-:1027000000E0541FB400028003D34029E54A60036F
-:10271000022800AD6AAE69AF68740112030F78AD8C
-:10272000E630E00BAD6AAE69AF68740212030F7C4D
-:102730000212302422B401028003D3401BE56D2035
-:10274000E107E54A6003022800E54A24FE5003023F
-:1027500028007C0212302422B402028006D35003E7
-:102760000227FEE56D20E10DE54A6009E54A648037
-:102770006003022800AC4A1230AB4003022800E597
-:1027800049702530021190FF80E05408AD6AAE69AF
-:10279000AF6812030F800F90FF82E05408AD6AAE5D
-:1027A00069AF6812030F803D154930021DE5497578
-:1027B000F008A42448F582E434FFF583E05408AD22
-:1027C0006AAE69AF6812030F801BE54975F008A473
-:1027D0002408F582E434FFF583E05408AD6AAE695D
-:1027E000AF6812030FAD6AAE69AF681201E6600B05
-:1027F000AD6AAE69AF68740112030F7C0212302417
-:10280000228000022C6AE56D20E706E572457160C2
-:1028100003022C6A90FF00E0541FB400028003D32F
-:10282000401AE54C14454B7004E54A600302290C3C
-:1028300078ADE654FEF67C0012302422B40102800A
-:1028400003D3402AE56D20E108E56D20E00302296D
-:102850000CE56D30E004E54A700BE56D30E109E50B
-:102860004A24FE500302290C7C0012302422B402B8
-:10287000028006D3500302290AE54C454B6003024F
-:10288000290CAC4A1230AB400302290CE56D20E163
-:1028900007E56D20E0028077E56D30E006E54960F0
-:1028A00002806CE549700F90FF82E054F7F090FFD2
-:1028B00080E054F7F022E549B401028003D34009D7
-:1028C0007D017C03120F098011B402028003D34002
-:1028D000097D017C04120F0980001549300215E5BD
-:1028E0004975F008A42448F582E434FFF583E054E8
-:1028F000F7F08013E54975F008A42408F582E43464
-:10290000FFF583E054F7F07C0012302422800002AF
-:102910002C6AE56D20E706E57245716003022C6ABA
-:1029200090FF00E0541FB400028003D3401AE54C2E
-:1029300014454B7004E54A60030229EF78ADE64484
-:1029400001F67C0012302422B401028003D3402916
-:10295000E56D20E108E56D20E0030229EFE56D302B
-:10296000E004E549700BE56D30E108E54924FE50CF
-:1029700002807F7C0012302422B402028003D34004
-:102980006FE54C454B60028069AC4A1230AB4002A7
-:102990008060E56D20E107E56D20E0028054E549A7
-:1029A000701430020990FF80E04408F0800790FF27
-:1029B00082E04408F022E56D30E13315493002151C
-:1029C000E54975F008A42448F582E434FFF583E076
-:1029D0004408F08013E54975F008A42408F582E462
-:1029E00034FFF583E04408F07C001230242280029A
-:1029F0008000022C6AE56D20E712E5724571700CCB
-:102A0000E54A700890FF00E0541F6003022C6AE55D
-:102A10004C90FFFFF090FFFFE06005436D018003E5
-:102A2000536DFE7C0012302422E56D30E70EE57216
-:102A30004571600890FF00E0541F6003022C6AADEE
-:102A40004BE54CED7D00FC7D00FCBD0002800302E7
-:102A50002B88B401028003D34032E54A7005E54C6F
-:102A6000FC6003022B8A756A407569F8756801D3AA
-:102A7000E5729412E57194004006E4FD7C12800436
-:102A8000AC72AD718C708D6F12303922B40202803D
-:102A900003D34059E54A6003022B8AE54CFC7027BA
-:102AA000756A527569F8756801D3E5729419E57114
-:102AB00094004006E4FD7C198004AC72AD718C700A
-:102AC0008D6F1230398025756A6B7569F8756801EC
-:102AD000D3E5729427E57194004006E4FD7C2780DD
-:102AE00004AC72AD718C708D6F12303922B4030258
-:102AF0008006D35003022B88E54CF549700F90FFF8
-:102B000004E0FDA3E04D6003022B8A801890FB02D5
-:102B1000E0FDA3E0FC90FF05E06C700790FF04E08F
-:102B20006D60028068E4F570F56F7F00E54914C5BB
-:102B300049600FEF2400F582E434FBF583E02FFFBA
-:102B400080EA8F4AE54A2400F582E434FBF583E00D
-:102B50007D00D39572ED95714006AC72AD71800F1A
-:102B6000E54A2400F582E434FBF583E07D00FC8C2B
-:102B7000708D6FE54A2400FCE434FBFDFEECFD7F24
-:102B8000018D6A8E698F68123039228000022C6AAA
-:102B9000022C6AE56D30E719E5721445717012E593
-:102BA0004A700EE54C454B700890FF00E0541F60E2
-:102BB00003022C6AE56D20E008E56D20E103022C9C
-:102BC0006A756A6EE4F569F568E4F56F04F57012EC
-:102BD000303922E56D20E712E5724571700CE54A47
-:102BE000700890FF00E0541F6003022C6AE56D201E
-:102BF000E007E56D20E1028074854C6EE56E70089B
-:102C0000436D01536DFD8006536DFE436D027C00E4
-:102C100012302422E56D30E71AE572144571701305
-:102C2000E54A700FE54C454B700990FF00E0541FDA
-:102C30001460028038E56D20E10280317C011230A1
-:102C40002422E56D20E715E5724571700FE54C45CE
-:102C50004B700990FF00E0541F146002800FE56D77
-:102C600020E10280087C00123024228000022F2BF9
-:102C7000B440028006D35003022F2190FF01E09060
-:102C8000FC35F0E54A90FC36F0E490FC37F0E56A5C
-:102C90002403F56AE5693400F569AD4BE54C856AB6
-:102CA00082856983CDF0A3CDF090FF01E01201B7DA
-:102CB0002CD8012CFE022D28032D52042DA0052D09
-:102CC000DD062E03072E29082E55092E7B0B2EA17B
-:102CD0000C2EB0802EB08100002F0EE56D20E7068F
-:102CE0007C051225BF227D247E357F0279387AFC4F
-:102CF0007B017408780012033F7D087C00122526B2
-:102D000022E56D20E7067C051225BF22E54AB403C3
-:102D1000004010B40500500BE54A7F00FE7C101205
-:102D200031FB227D007C0712252622E56D20E70677
-:102D30007C051225BF22E54AB403004010B405000B
-:102D4000500BE54A7F00FE7C111231FB227D007C96
-:102D50000712252622E56D20E7067C051225BF22F5
-:102D6000E54AB405028003D3400AE4FF04FE7C0A6E
-:102D70001231FB22B401028003D3400AE4FF04FEB7
-:102D80007C081231FB22B403004010B40500500B44
-:102D9000E54A7F00FE7C131231FB227D007C071286
-:102DA000252622E56D20E734D3E5729448E5719439
-:102DB000005006E572457170067C021225BF22E5BF
-:102DC0004AB40103B3400BC3B403004009B4060086
-:102DD00050041230D1227C071225BF2212255D2219
-:102DE000E56D20E71DE54AB403004010B40500502E
-:102DF0000BE54A7F00FE7C161231FB227C07122570
-:102E0000BF2212255D22E56D20E71DE54AB40300CF
-:102E10004010B40500500BE54A7F00FE7C191231CA
-:102E2000FB227C071225BF2212255D22E56D20E7DB
-:102E300023748190FF93F0E54AB403004010B40579
-:102E400000500BE54A7F00FE7C171231FB227C0705
-:102E50001225BF2212255D22E56D20E71DE54AB44B
-:102E600003004010B40500500BE54A7F00FE7C18BB
-:102E70001231FB227C071225BF2212255D22E56D4F
-:102E800020E71DE54AB403004010B40500500BE5EF
-:102E90004A7F00FE7C151231FB227C071225BF22DF
-:102EA00012255D22E56D20E7067C071225BF221260
-:102EB000255D22E56D30E72090FF00E0541F701083
-:102EC00090FF01E0B48005122554800312255D2295
-:102ED0007D007C051225262290FF00E0541F60062D
-:102EE0007C051225BF22D3E5729448E57194005009
-:102EF0000BC3E5729407E571940050067C0312251C
-:102F0000BF22E54AB405041230D1227C071225BF46
-:102F100022E56D30E7087D007C05122526227C0520
-:102F20001225BF22B420028003D340008000122F5C
-:102F3000FF2275430090FF83E0540FD39543402454
-:102F4000E54324F0F582E434FEF583E0AD6AAE6932
-:102F5000AF6812030F05430DED70010E8D6A8E6987
-:102F60008F6880D1E5437D00FCC3E5709CF570E57A
-:102F70006F9DF56FE570456F6006E490FF83F0226A
-:102F800090FF82E04408F0E4F56F75704990FC35DD
-:102F9000E0B405028003D3404090FC36E0F543B432
-:102FA00005028003D3400AE4FF04FE7C0B1231FBD0
-:102FB00022B401028003D3400AE4FF04FE7C09121C
-:102FC00031FB22B403004010B40500500BE5437FF1
-:102FD00000FE7C141231FB2222B480004023B48214
-:102FE00000501E7C357DFC12177E7D008C6C8D6B35
-:102FF00090FC37E06005122FFF80057C0012302422
-:10300000222290FF83E0547FF090FF82E04408F09A
-:1030100090FF80E04408F02290FF82E04408F090A6
-:10302000FF80E04408F0228C237D008C708D6F754A
-:103030006A357569FC7568011230392290FF83E0AA
-:10304000547FF0E5706449456F700122C3E57094C8
-:1030500008E56F94004015752108E5217D00FCC34B
-:10306000E5709CF570E56F9DF56F8009857021E432
-:10307000F56F757049752200E522C395215026AD84
-:103080006AAE69AF681201E6FCE52224F8F582E435
-:1030900034FEF583ECF005220DED70010E8D6A8E85
-:1030A000698F6880D3E521547F90FF81F0228C489E
-:1030B0007F00EF24FD4019E4EF75F007A4247FF5AD
-:1030C00082E434F8F583E065487002D3220F80E291
-:1030D0008F47C32285727085716F90FF82E054F72D
-:1030E000F090FF83E0547FF022C000C001C002C016
-:1030F00006C007E5782408F8860653067F7CFF1291
-:10310000315B7C007D00E57B6046FF90FD95E054DF
-:103110007F6E700FC083C082A3E0FDA3E0FCA31507
-:103120007B8007A3A3A3DFE68026DF06D082D083BF
-:10313000801EE0F8A3E0F9A3E0FAD082D083E8F0A3
-:10314000A3E9F0A3EAF0A3C083C082A3A3A380DA1B
-:103150001231F4D007D006D002D001D0002285A8C9
-:103160007A75A888EC70027C3F8C7922E578240877
-:10317000F8760012324880FBC000C001C002C006D1
-:10318000C007AE047CFF12315BE57B6042FF90FD1F
-:1031900095E0547F6E700BC083C082A3A3A3157B00
-:1031A0008007A3A3A3DFEA8026DF06D082D0838036
-:1031B000D8E0F8A3E0F9A3E0FAD082D083E8F0A346
-:1031C000E9F0A3EAF0A3C083C082A3A3A380DA78C6
-:1031D00008087918097C01E6547F6E70067600773E
-:1031E00000800608090CBC08EE1231F4D007D006A6
-:1031F000D002D001D00022757900857AA822C0F0D3
-:10320000C082C083C3E57B24E8500512324880F4B5
-:10321000EC6031903523E493C39C4028C0047CFFCC
-:1032200012315BD004430480E57B75F003A4249540
-:10323000F582E434FDF583ECF0EFA3F0EEA3F005A6
-:103240007B1231F4D083D082D0F022C0047C20D213
-:103250008CD28DD504FDD0042275A8007588007528
-:10326000B80075F00075D000E4F8900000F608B8DA
-:1032700000FB020000C3ED940250047D037CE8ECE7
-:10328000F4FCEDF4FD0CBC00010D8C7F8D7E22C39F
-:10329000EC94BCED940250047D077CD0ECF4FCED82
-:1032A000F4FD0CBC00010D8C7D8D7C22EC700122A4
-:1032B000C000E5782418F8A604E5782408F8C65478
-:1032C0007FF6E630E703D0002212324880F4C28C49
-:1032D000857C8C857D8AD28CC0E0C0D0C0F0C08255
-:1032E000C083C000C001C002C003C004C005C00646
-:1032F000C007121AD1E5782408F8E66024E578249E
-:1033000010F8A681E57875F021A4248DF582E434C7
-:10331000FCF58378AEE58104C398F9E6F008A3D9FB
-:10332000FA74082578F8057808E65480700CE5787A
-:10333000B407F3780875780080EFE5782410F886F4
-:1033400081E57875F021A4248DF582E434FCF583C1
-:1033500078AEE58104C398F9E0F608A3D9FAD0075E
-:10336000D006D005D004D003D002D001D000D08345
-:10337000D082D0F0D0D0D0E032C0E0C0D0C000C009
-:1033800001C002C28E857E8D857F8BD28E781979A1
-:10339000097A07E77004A600800BE6600816E6705D
-:1033A00004E74480F70809DAEAE579601314F5794F
-:1033B000700EE5782408F876001231F4D28CD28DA4
-:1033C000D002D001D000D0D0D0E0327581AD742AC7
-:1033D00090FF93F0757F30757EF8757D60757CF099
-:1033E00012053612347C12173490FF93E04401F03A
-:1033F000B2B31234A612325680DA22C0007C01EC3D
-:103400002408F8E660090CBC08F512324880EED0BA
-:103410000022C0F0C082C083C000C006C007ED24F7
-:1034200010F876BCED75F021A4248DF582E434FC0F
-:10343000F583C082C083A3A3E4780DF0A3D8FCEC8D
-:10344000547F75F002A424EFF582E5F03434F5835F
-:10345000E493FE740193F5828E83E493FE740193EA
-:10346000FFD083D082EFF0A3EEF0ED2408F8EC4417
-:1034700080F6D007D006D000D083D082D0F022755D
-:103480007800757B007A087918780876007700084C
-:1034900009DAF8E478087480447FF674014410F582
-:1034A0008975B808D2ABD2A9227581ADD28ED28CE3
-:1034B000D2AFE57B6032FF90FD95E05480602478C8
-:1034C000087908E0547FFA7B00E6547FB502027B5E
-:1034D000FF08D9F5EB700CEAF01233F8AD04AC023A
-:1034E00012340FA3A3A3DFD212324880C57C017D22
-:1034F000002204F504E904ED04E104DD04D904E547
-:1035000004F1049D04A104CD04D104990499049903
-:1035100004D504B504AD04B104A904C104BD04B9C3
-:1035200004C504C904A5190103002200480200488B
-:103530000E301420C81AD0180A0C05060203010226
-:103540000001CE0181010000C00080006000300059
-:1035500018001000080004000200010008183828B4
-:103560000C05100A0200000000000301100A02000E
-:1035700000000000FBE0FBF209022700010200A0AE
-:10358000320904000003FF0000000705810240002B
-:103590000007050102400000070583030200012225
-:1035A0000354005500530042003300340031003012
-:1035B000002000200020002000200020002000200B
-:0535C000000000000006
-:00000001FF
--- zfcpdump-kernel-4.4.orig/firmware/ti_5052.fw.ihex
+++ /dev/null
@@ -1,862 +0,0 @@
-:10000000C1350002001E021B32FFFFFFFFFF02325C
-:100010006AFFFFFFFFFFFFFFFFFFFFFFFFFF02334E
-:10002000157581C890FEF08583A012347DEC4D607B
-:100030006A78A58003760018B896FA7879800376F6
-:100040000018B85FFA78208003760018B820FA907C
-:10005000FEE5AE83AF8290FD001200A16005E4F0E2
-:10006000A380F690FEF0A88290FEF0A982E8C399E2
-:10007000500576000880F69000FF1200AA90010358
-:100080001200AA9001071200AA90010B1200C8905A
-:1000900001111200C89001171200C875D000123368
-:1000A0006702011DEF65827003EE658322E493F819
-:1000B000740193F9740293FE740393F5828E83E8BE
-:1000C00069700122E493F6A30880F4E493FC7401C0
-:1000D00093FD740293FE740393FF740493F8740504
-:1000E00093F58288831200A1700122E493A3A88370
-:1000F000A9828C838D82F0A3AC83AD8288838982B0
-:1001000080E3212104927A7A0492A6A80492FEF058
-:1001100004940494FBFB04990494FBFB04F904F994
-:1001200080FED0F030F00920F303F68010F7800D48
-:1001300030F10920F303F28004F38001F020F4048D
-:10014000FCD0E0CC22CCC0E012015A02014BBC0032
-:1001500005D0F0ACF022C313DCFC020121BF000982
-:10016000ED258275F001F8E622BF010FED2582F53D
-:1001700082EE3583F58375F004E022ED258275F07B
-:1001800002F8E222D083D082F5F0C3E493A3C5F055
-:1001900095F0C0E0C3D0F0E493A395F04012A3A380
-:1001A000C3E5F033500205832582F58250020583B2
-:1001B000740193C0E0E493C0E022D083D082F5F0D4
-:1001C000E49370097401937004A3A3800C740293E8
-:1001D00065F06005A3A3A380E7740193C0E0E493F6
-:1001E000C0E02212025B0201F21202AF0201F2121F
-:1001F00002D30201F230E00720E302E622E72230D8
-:10020000E10720E302E222E32230E202E022E4936B
-:10021000221202D302021A1202AF02021AABF01229
-:100220000224CBC5F0CB2230E01020E306E6F5F047
-:1002300008E622E7F5F009E7192230E11020E3068D
-:10024000E2F5F008E222E3F5F009E3192230E206D4
-:10025000E0F5F0A3E022E493F5F074019322BB00F3
-:1002600003740922BB010789828A83740422BB02BA
-:100270000789828A83741022740A2202027BBB00DF
-:1002800007E92582F8740122BB010DE92582F58278
-:10029000EA3583F583740422BB020DE92582F582D9
-:1002A000EA3583F583741022E92582F8740222026C
-:1002B00002AFBF0005EDF8740122BF01078D828EE9
-:1002C00083740422BF02078D828E83741022EDF89E
-:1002D0007402220202D3BF0007ED2582F8740122C6
-:1002E000BF010DED2582F582EE3583F5837404227E
-:1002F000BF020DED2582F582EE3583F58374102261
-:10030000ED2582F8740222020307C0E012025B02AC
-:10031000031FC0E01202AF02031FC0E01202D302AB
-:10032000031F30E00B20E304D0E0F622D0E0F722F8
-:1003300030E10B20E304D0E0F222D0E0F322D0E061
-:10034000F022C9CDC9CACECACBCFCB120352EDF928
-:10035000EEFAEFFB22BB002FBF000AFAEDF8E7F63A
-:100360000809DAFA22BF01128D828E83F802036F28
-:1003700009A3E7F0D8FA2202037AFAEDF8E7F208C7
-:1003800009DAFA22020384BB014DBF001489828A74
-:1003900083F9EDF802039608A3E0F6D9FA220203E6
-:1003A000A7BF01228D828E83FB08C9C582C9CAC539
-:1003B00083CAE0A3C9C582C9CAC583CAF0A3DBEA60
-:1003C000D8E8220203CA8D828E83F9EDF8E0F208A4
-:1003D000A3D9FA220203D4BB024DBF001289828A3C
-:1003E00083F9EDF80203E608A3E493F6D9F922BFF6
-:1003F00001238D828E83FB08C9C582C9CAC583CA01
-:10040000E493A3C9C582C9CAC583CAF0A3DBE9D8EE
-:10041000E72202041989828A83F9EDF8E493F2084D
-:10042000A3D9F92202042ABF000DFAEDF8E3F60879
-:1004300009DAFA22020434BF01128D828E83F80297
-:10044000044109A3E3F0D8FA2202044CFAEDF8E3E0
-:10045000F20809DAFA22020456E6FB08E6FA08E690
-:10046000F904F61870010622E6FF08E6FE08E6FD2C
-:1004700022EFF0A3EEF0A3EDF022EBF0A3EAF0A35D
-:10048000E9F022E0FFA3E0FEA3E0FD22E0FBA3E011
-:10049000FAA3E0F9220000000000000004F9005B6C
-:1004A00005730026059A00330A0B005B0A7700608B
-:1004B0001552005B0CFB005B09AB005B09E2005BC3
-:1004C0000DC2005B0BF3005B0A1E005B0A53005B6E
-:1004D000174A0033176000341E4D00431EF00044DD
-:1004E000205D0044204B00471F1700471FBC004DF4
-:1004F000200D004F1F39005831F5005B7CCC7DFF8B
-:10050000121CFE22749090FF91F090FFFCE020E717
-:100510002DC2AFAE59AF58755A20E55A14C55A606E
-:1005200019E4FE7F05EE4FCE24FFCECF34FFCF601F
-:1005300007E490FF92F080ED80E08E598F582212F0
-:1005400005017D077CB71232117D0F7C6E12322BB4
-:1005500078977A06E4F608DAFC7A061205CF7C036F
-:10056000120E577C04120E5712218BE4FEFF7C0FF3
-:1005700012319AD2A822123085E490FD40F090FF0B
-:10058000F0E030E408740190FD41F08005E490FD56
-:1005900041F07D0A7C001224B1123108221230850C
-:1005A00090FD41E014700E90FFF0E04410F07C00EC
-:1005B00012254A801990FD41E0700E90FFF0E05442
-:1005C000EFF07C0012254A80057C1712254A123173
-:1005D000082290FFF0E054ABF090FFF0E04420F0F0
-:1005E000228C378D36787CEDF608ECF6EDFEECFDCE
-:1005F0007F019000051201EC787AF6787CE6FD0820
-:10060000E6FCEDFEECFD7F019000041201EC540FBE
-:10061000FC7D7A12179D787AE6700DAD3AAE39AF4F
-:1006200038E412030F7C082290FFF0E054FEF090B3
-:10063000FFF0E054FDF0801E787CE6FD08E6FCED5E
-:10064000FEECFD7F0190000812020E25E0440190AF
-:10065000FFF3F00206DB787CE6FD08E6FCEDFEEC3D
-:10066000FD7F0190000612020E54FE90FFF3F08011
-:100670002B787CE6FD08E6FCEDFEECFD7F019000AA
-:100680000812020EFAEB90FFF1F01208CA400DAD0D
-:100690003AAE39AF38E412030F7C1822787CE6FDBD
-:1006A00008E6FCEDFEECFD7F0190000812020E90C2
-:1006B000FFF1F01208CA400DAD3AAE39AF38E4127E
-:1006C000030F7C1822787CE6FD08E6FCEDFEECFDCD
-:1006D0007F0190000612020E440190FFF3F0787D36
-:1006E000E62403F618E63400F6787AE624FE50098C
-:1006F00090FFF0E054FDF0800790FFF0E04402F03E
-:10070000E490FFF1F0787B7600787AE624FFFCE451
-:1007100034FFFD787BE67F00FEECD39EEF6480CD56
-:1007200064809D402F1208AF400F787BE6AD3AAE53
-:1007300039AF3812030F7C182290FFF2E0FC787C6E
-:100740008683088682ECF0787B06A3787CA68308F3
-:10075000A68280B51208AF400F787BE6AD3AAE397D
-:10076000AF3812030F7C182290FFF2E0FC787C86F1
-:1007700083088682ECF0787AE6AD3AAE39AF38126B
-:10078000030F7C00228C378D36787CEDF608ECF672
-:10079000EDFEECFD7F019000051201EC787BF67810
-:1007A0007CE6FD08E6FCEDFEECFD7F019000041206
-:1007B00001EC540FFC7D7B12179D787BE670037C67
-:1007C000082290FFF0E054FEF090FFF0E054FDF0BE
-:1007D000801B787CE6FD08E6FCEDFEECFD7F0190D9
-:1007E000000812020E25E090FFF3F0805B787CE6B3
-:1007F000FD08E6FCEDFEECFD7F0190000612020E06
-:1008000054FE90FFF3F08021787CE6FD08E6FCEDD5
-:10081000FEECFD7F0190000812020EFAEB90FFF152
-:10082000F01208CA40037C1822787CE6FD08E6FC3A
-:10083000EDFEECFD7F0190000812020E90FFF1F03A
-:100840001208CA40037C1822787DE6240AF618E6CE
-:100850003400F6787A7600787BE624FFFCE434FFF7
-:10086000FD787AE67F00FEECD39EEF6480CD648055
-:100870009D4021787C8683088682E090FFF1F0120B
-:1008800008CA40037C1822787A06787D06E618703C
-:10089000010680C390FFF0E04401F0787C86830875
-:1008A0008682E090FFF1F01208CA40037C18227C97
-:1008B000002290FFF0E020E71290FFF0E030E50921
-:1008C00090FFF0E04420F0C32280E7D32290FFF0B5
-:1008D000E020E31290FFF0E030E50990FFF0E04403
-:1008E00020F0C32280E7D3228C428D417C00ED545E
-:1008F000F0FDEC7003ED64307005753E0380037508
-:100900003E04AC3E120F7C758300858340E5415464
-:100910000FF53FE5407004E53F64037035E53E2484
-:10092000FD75F00AA4240AF582E434FDF583E03075
-:10093000E6051210678019E53E2497F8C654FBF6C9
-:1009400078A3E62405F58218E63400F583740FF0E9
-:100950008059E5407004E53F64047048E53E24FD9D
-:1009600075F00AA4240AF582E434FDF583E030E54D
-:1009700007AC42AD41121C93E54230E21578A7E680
-:1009800030E00F78A7E630E109E4FF04FE7C0412B2
-:10099000319A78A3E62406F58218E63400F58374CC
-:1009A0000FF08007E4FC7DEE121C93C2032212308C
-:1009B00085120F7C78A3E62406F58218E63400F54C
-:1009C00083E090FD40F078A3E62405F58218E63434
-:1009D00000F583E090FD41F0C2037D027C0012240B
-:1009E000B112310822123085788FECF6EC2497F89A
-:1009F000E630E1077C1312254A800F90FD41E0FDAF
-:100A0000788FE6FC1213FD12254A123108221230AB
-:100A100085788FECF67D00120F0B12254A123108F3
-:100A200022123085788FECF6EC2497F8E630E20756
-:100A30007C1312254A801B788FE62497F8E620E184
-:100A4000077C1212254A800A788FE6FC12142112C4
-:100A5000254A12310822123085788FECF6EC249763
-:100A6000F8E620E2077C1112254A800A788FE6FC1E
-:100A700012152212254A12310822123085788FEC85
-:100A8000F6120F7C78A3E62409F58218E63400F507
-:100A900083E090FD47F078A3E6240AF58218E63457
-:100AA00000F583E090FD48F078A3E62403F5821872
-:100AB000E63400F583E0FC78A3E62404F58218E62A
-:100AC0003400F583E0F55C78A3E62402F58218E6AD
-:100AD0003400F583E0F55D8C5BE4EC33335401784E
-:100AE0008FF66008E55C30E103788F06788FE6903A
-:100AF000FD49F078A1E62402F58218E63400F5837A
-:100B0000E0FDA3E0540CFCED54E68C5FF55EE55B84
-:100B100030E503435F01E55C20E50EE55B547F7043
-:100B200008E55B20E703435F02E55B30E303435FD7
-:100B300010E55B30E203435F20E55B540360034351
-:100B40005F40E55B30E103435F80E55B30E40343F6
-:100B50005E01E55B30E603435E08E55C20E40EE5FC
-:100B60005B547F7008E55B20E703435E10535FFB37
-:100B7000535EF9AD5EE55F90FD42CDF0A3CDF0E5AB
-:100B80005D30E30DE55D5430C4540F90FD45F080B9
-:100B900005E490FD45F0E55D540390FD44F0E55D0E
-:100BA0005404C31390FD46F090FD44E0700E7D3D6B
-:100BB0007EFD7F01740190000912014278A3E624B2
-:100BC00008F58218E63400F583E07C00FD78A3E6A2
-:100BD0002407F58218E63400F583E07F004CFEEF31
-:100BE0004D90FD40F0A3CEF0CEC2037D0A7C0012F2
-:100BF00024B112310822123085788FECF678947681
-:100C0000010876FD0876407891760C789412046598
-:100C10001202147892CBF6CB08F67F00EF24EB405B
-:100C20001FE4EF25E09034BFFD93CD0493789366E5
-:100C30007003ED186670067891760080030F80DCF3
-:100C40007890EFF6789412046590000212020E7804
-:100C500092CBF6CB08F65404CB54064B6004789143
-:100C6000760B7893E630E3137894120465900005D0
-:100C70001201EC24FB50047891760D7893E654C071
-:100C80007D0064C04D70047891760B7894120465F1
-:100C90009000041201EC24FC50047891760F7894B3
-:100CA0001204659000061201EC24FD500478917640
-:100CB0000E78941204659000091201EC24FD500492
-:100CC0007891760A7891E6702A788FE6FC120F7C8C
-:100CD000789412046578A1E6F978A0E6FA7B0174AD
-:100CE0000A780012033FC203788FE6FC12112378C2
-:100CF00091ECF67891E6FC12254A12310822123066
-:100D000085788FECF6120F7C788FE624FD75F00A5B
-:100D1000A4241CF582E434FDF583AC82AD8378A075
-:100D20008683088682ECF9EDFA7B0A78011203A724
-:100D3000C203788FE6FC121123123108228D2B8C0E
-:100D40002AED60407527017529487528FFE52A249A
-:100D5000FDFCE434FFFDEC7C0325E0CD33CDDCF974
-:100D6000FCE5292CF529E5283DF528AD29AE28AF6D
-:100D700027748090000612031774809000021203FB
-:100D800017120FD3E52B14603B75270175290875E1
-:100D900028FFE52A24FDFCE434FFFDEC7C0325E07C
-:100DA000CD33CDDCF9FCE5292CF529E5283DF528E6
-:100DB000AD29AE28AF27E4900006120317E4900097
-:100DC0000212031722123085788FECF6EC2497F884
-:100DD000E630E209788FE6FC121522D200788FE621
-:100DE000FC120F7C7890760090FD41E030E70478AB
-:100DF0009076017890E6FD788FE6FC120D3AC203FA
-:100E0000300007788FE6FC1214217C0012254A126C
-:100E100031082278A3E62404F58218E63400F5832D
-:100E2000E04401F078A3E62404F58218E63400F5E6
-:100E300083E030E00280ED78A3E6240BF58218E62B
-:100E40003400F583E054F8F078A3E62402F5821824
-:100E5000E63400F583E04480F022C2038C58120F80
-:100E60007C78A0868308868279EE7A347B0A7801C2
-:100E70001203F5120E10AC587D02120D3AC203ACEB
-:100E800058121123228D538E528F518C50120F7C89
-:100E9000754F0078A3E62405F58218E63400F58343
-:100EA000E020E416E54F24F64010054FC2037C18FD
-:100EB000123248AC50120F7C80D978A3E62405F595
-:100EC0008218E63400F583E020E405C2037C0222A8
-:100ED00078A3E62405F58218E63400F583E0540F84
-:100EE000601678A3E62405F58218E63400F583E061
-:100EF000540FF0C2037C012278A28683088682E028
-:100F0000AD53AE52AF5112030FC2037C00228D319C
-:100F10008C30121522E5316020E530B4030C7C01E1
-:100F200012247C7C8112247C800FE530B4040A7C7E
-:100F30000212247C7C8212247CAC30120F7CE531BE
-:100F4000601A78A48683088682E054E7F0A3A3A3FE
-:100F5000A3E054E7F0AC307D02120D3A78A086830E
-:100F600008868279F87A347B0A78011203F5C20385
-:100F7000E5302497F8C654FDF6AC30121123228CCC
-:100F8000263003051231E780F87C0A1230FAD203CA
-:100F9000E52624FD789DF6700978A476FF0876E0B2
-:100FA000800778A476FF0876E2789DE675F010A4B5
-:100FB000ADF0FC24A078A3F6ED34FF18F6789DE69A
-:100FC00075F00AA42408FCE434FDFD78A0EDF608D1
-:100FD000ECF61231932278A3E62402F58218E63467
-:100FE00000F583E030E72278A3E62402F58218E6D4
-:100FF0003400F583E0547FF078A3E62402F58218EC
-:10100000E63400F583E04480F02278A486830886E5
-:1010100082E0547FF0AD83E5822404FCE43D8C82C1
-:10102000F583E0547FF078A3E6240BF58218E634CC
-:1010300000F583E054F8F078A5E62401F58218E67F
-:101040003400F583E04403F078A5E62405F5821822
-:10105000E63400F583E04403F078A3E62405F58246
-:1010600018E63400F583740FF02278A4868308868E
-:1010700082E0543FF0AD83E5822404FCE43D8C82A1
-:10108000F583E0543FF0789DE6249EF8E6FC78A5D1
-:10109000E62401F58218E63400F583ECF0789DE64D
-:1010A000249EF8E6FC78A5E62405F58218E63400CF
-:1010B000F583ECF078A3E6240BF58218E63400F50E
-:1010C00083E054FB4402F52678A1E62402F5821859
-:1010D000E63400F583E030E50343260178A3E624F7
-:1010E00005F58218E63400F583E030E003120FD3F3
-:1010F000E526FC78A3E6240BF58218E63400F58398
-:10110000ECF078A3E62405F58218E63400F5837444
-:101110000FF078A48683088682E04480F0A3A3A31E
-:10112000A3E04480F0228C2A120F7C78A1E62408E8
-:10113000F58218E63400F583E0FC78A3E6240AF58E
-:101140008218E63400F583ECF078A1E62407F582F6
-:1011500018E63400F583E0FC78A3E62409F582184C
-:10116000E63400F583ECF078A08683088682E0FD03
-:10117000A3E0FCEDFE78A3E62408F58218E634002F
-:10118000F583EEF0ECFE78A3E62407F58218E6344A
-:1011900000F583EEF08C298D28C3EC9402ED9406C3
-:1011A000400575277C8033D3E5299481E528940197
-:1011B000400575273C8023D3E52994C0E528940099
-:1011C00040057527188013D3E5299430E52894004D
-:1011D000400575270C8003752708AF27E4EF547C82
-:1011E0004483FF8F27E527FC78A5E62401F58218C4
-:1011F000E63400F583ECF0E527FC78A5E62405F558
-:101200008218E63400F583ECF0E527FC789DE624AF
-:101210009EF8ECF678A3E62402F58218E63400F591
-:1012200083E0F52778A1E62402F58218E63400F57C
-:1012300083A3E030E3175327C778A1E62405F5829E
-:1012400018E63400F583E09034E993422778A1E66C
-:101250002402F58218E63400F583E030E7054327E1
-:101260004080035327BF5327FB78A1E62406F5826D
-:1012700018E63400F583E060034327045327FC7825
-:10128000A1E62404F58218E63400F583E042274302
-:101290002780E527FC78A3E62402F58218E63400CF
-:1012A000F583ECF078A3E62404F58218E63400F523
-:1012B00083E0F52778A1E62402F58218E63400F5EC
-:1012C00083A3E030E1055327DF800343272078A183
-:1012D000E62402F58218E63400F583E030E4055395
-:1012E00027EF800343271078A1E62409F58218E64A
-:1012F0003400F583E0B40203432702E527FC78A31A
-:10130000E62404F58218E63400F583ECF078A3E6D1
-:101310002403F58218E63400F583E0F52778A1E68A
-:101320002409F58218E63400F583E0700553277F21
-:10133000800343278078A1E62402F58218E6340072
-:10134000F583A3E030E00543272080035327DF78AF
-:10135000A1E62402F58218E63400F583E030E305C7
-:1013600043274080035327BF78A1E62402F5821863
-:10137000E63400F583E030E005432710800353276F
-:10138000EF78A1E62402F58218E63400F583A3E0A5
-:1013900030E40543270880035327F778A1E62402A9
-:1013A000F58218E63400F583A3E030E50543270411
-:1013B00080035327FB78A1E62402F58218E6340067
-:1013C000F583A3E030E60543270180035327FE7829
-:1013D000A1E62402F58218E63400F583A3E030E7A5
-:1013E0000543270280035327FDE527FC78A3E62465
-:1013F00003F58218E63400F583ECF0C2037C00228A
-:101400008D278C26ED54031460037C1022E52754AD
-:101410007C24FC40037C0B22E5262497F8C644027A
-:10142000F67C00228C30120F7CE5302497F8E62001
-:10143000E24FAC307D02120D3AE53024FE4428FC28
-:1014400078A48683088682ECF0AF83E5822404FECC
-:10145000E43FFFEC8E828F83F07C038C2CE52CFC28
-:1014600078A5E62401F58218E63400F583ECF0E572
-:101470002CFC78A5E62405F58218E63400F583EC0B
-:10148000F0752D01752F48752EFFE53024FDFCE425
-:1014900034FFFDEC7C0325E0CD33CDDCF9FCE52FFA
-:1014A0002CF52FE52E3DF52E78A5E62404F58218BF
-:1014B000E63400F583E054E7F52CAD2FAE2EAF2DCA
-:1014C000E4900002120317E49000061203171201C1
-:1014D000E630E503432C10E52CFC78A5E62404F562
-:1014E0008218E63400F583ECF012106778A3E62446
-:1014F00006F58218E63400F583E0C203FCE53024EB
-:1015000097F8C64404F68C2CE530540FC454F07E92
-:1015100000FFEEEF44047D00FFEC4EFCED4FFD12AA
-:101520001CFE7C00228C2F120F7C12100778A486E0
-:1015300083088682E05408F0A3A3A3A3E05408F034
-:10154000AC2F7D02120D3AC203E52F2497F8C65442
-:10155000FBF67C00221230857890ECF6EC2497F8AC
-:10156000E630E10A7D007C131224B1123108789034
-:10157000E62497F8C64401F67890E6FC120F7C78D2
-:1015800090E624FD75F00AA4241CF582E434FDF5F0
-:101590008378A0E6FA08E6F97B0A78011203A778B7
-:1015A000A0868308868279F87A347B0A7801120350
-:1015B000F5120FD3C2037890E6FC121123788FEC5A
-:1015C000F6EC600A7D007C081224B1123108789094
-:1015D000E6FC120F7C78A3E62404F58218E63400BA
-:1015E000F583E0441054DFFC78A3E62404F5821868
-:1015F000E63400F583ECF0788FECF6C2037CC81279
-:1016000032487890E6FC120F7C78A3E62404F58239
-:1016100018E63400F583E054EFF0C2037CC81232C0
-:10162000487890E6FC120F7C78A3E62404F5821833
-:10163000E63400F583E04410F0C2037CC81232485F
-:101640007890E6FC120F7C78A3E62404F58218E675
-:101650003400F583E04420F0C2037CF01232487875
-:1016600090E6FC120F7C78A3E62405F58218E63498
-:1016700000F583E030E415C2037890E644107F0063
-:10168000FE7C0712319A12310802174978A3E6242A
-:1016900004F58218E63400F583E054CFF0C2037CF1
-:1016A000C81232487890E6FC120F7C78A3E6240436
-:1016B000F58218E63400F583E04430F0C2037CF094
-:1016C0001232487890E6FC120F7C78A3E62405F5E8
-:1016D0008218E63400F583E030E414C2037890E623
-:1016E00044107F00FE7C0712319A123108805D7829
-:1016F000A3E62404F58218E63400F583E054EFF005
-:1017000078A3E62404F58218E63400F583E054DF7C
-:10171000F07890E624FD75F00AA4241CF582E434E8
-:10172000FDF583AC82AD8378A08683088682ECF9D0
-:10173000EDFA7B0A78011203A7C2037890E6FC1247
-:1017400011237D007C0B1224B11231082212308546
-:1017500090FF91E090FD41F07D027C001224B112D7
-:1017600031082212308590FD40E0F4FC90FF91E0BA
-:101770005CF53390FD41E0FC90FD40E05C4233E5D8
-:101780003390FF91F07C0012254A12310822743CFC
-:1017900090FBE8F0743E90FBE8F0E490FD30F0221E
-:1017A0008D358C34ECB401028003D340028028B420
-:1017B00002028003D34008A835C625E0F68018B49D
-:1017C00004028003D3400AA835C625E025E0F68050
-:1017D00006A83576008000228C3C8D3BEDFEECFDAA
-:1017E0007F0175600675610090FD3112046E120173
-:1017F000E6B480028006D3500302189E90FD311299
-:1018000004809000031201EC54F0B430028003D342
-:10181000405F90FD3112048090000812020EFAFD24
-:10182000EBFE7F0190FD3412046EEECD903502FC8C
-:10183000E493FF740193FEF9EFFA7B01EAFFE9FEFE
-:10184000ECC39EED9F4025903504E493FD74019315
-:10185000FCEDFEECFD7F01EECDFC90FD36E0D39C6F
-:1018600090FD35E09D500575608080331219BC8075
-:101870002EB460028003D3400BAC3CAD3B12078218
-:101880008C60801BB41003B34010C3B42003B3407A
-:1018900009C3B440028003D340007560818000809A
-:1018A00075B481028003D3406B90FD3112048090A7
-:1018B00000031201EC54F0B430028003D3401D90B9
-:1018C000FD3112048090000812020EFAFDEBFE7F3B
-:1018D0000190FD3712046E1219268036B460028022
-:1018E00003D34013753A61E4F539F538AC3CAD3BB0
-:1018F0001205DE8C60801BB41003B34010C3B4200B
-:1019000003B34009C3B440028003D3400075608133
-:10191000800080028000E560FC90FD31120480ECC4
-:10192000900002120317AC612290FD3112048090E6
-:1019300000041201EC600474018001E4A2E0920151
-:1019400090FD31120480ED2403FD50010E90FD3412
-:1019500012046E90FD311204809000051201ECF526
-:10196000619000041201EC540FFC7D6112179DE59B
-:1019700061700475600822756000787E7600787E5C
-:10198000E6C39561503890FD371204801201E6FCE1
-:1019900090FD34120480EC12030F30010E90FD39DB
-:1019A000E004F090FD387003E004F0787E0690FDCE
-:1019B00036E004F090FD357003E004F080C0229022
-:1019C000FD32E0FDA3E0FCEDFEECFD7F01ED240A1D
-:1019D000FD50010E90FD3A12046E90FD311204800C
-:1019E0009000041201EC540FB401028003D340179D
-:1019F00090FD3A1204800DED70010E90FD37120437
-:101A00006E78827601804EB402028003D340199032
-:101A1000FD3A120480ED2402FD50010E90FD3712B4
-:101A2000046E78827602802DB404028003D34019BC
-:101A300090FD3A120480ED2404FD50010E90FD3714
-:101A400012046E78827604800CB400028003D340C6
-:101A5000007560082290FD3112048090000512018B
-:101A6000ECF561787F7600787FE6C39561400302EC
-:101A70001B24788076007880E6C378829650769032
-:101A8000FD341204801201E6FC90FD3A1204891222
-:101A900001E0F45CFC1201E0F890FD37120480E8EC
-:101AA000C0E01201E6C8D0E0C8584CFC90FD3412EA
-:101AB0000480EC12030F7881ECF690FD39E004F01D
-:101AC00090FD387003E004F009E970010A90FD3AD6
-:101AD00012047790FD311204809000041201EC3062
-:101AE000E40E90FD36E004F090FD357003E004F064
-:101AF00078800680817882E6FDE4FEFFEECDFC90E2
-:101B0000FD39E02CF090FD38E03DF07882E6FDE410
-:101B1000FEFFEECDFC90FD3CE02CF090FD3BE03D67
-:101B2000F0787F06021A6475600022E53D053D04E9
-:101B30007002B2B022C0E0C0F0C082C083C0D0E862
-:101B4000C0E0E9C0E0EAC0E0EBC0E0ECC0E0EDC01E
-:101B5000E0EEC0E0EFC0E090FF92E01201B71B8022
-:101B6000301B80321B8F381BA13A1BB33E1BCB446A
-:101B70001BBF461BD7501C19521BF8541C3A560069
-:101B8000001C5B90FF92E07F00FE7C0112319A0204
-:101B90001C6BE4FF04FE7C0312319A742090FFFE5C
-:101BA000F0021C6BE4FF04FE7C0212319A74409038
-:101BB000FFFEF0021C6BE4FF04FE7C0412319A026B
-:101BC0001C6BE4FF04FE7C0512319A021C6BE4FFDF
-:101BD00004FE7C0612319A021C6B90FFA5E07D008A
-:101BE00090FD00CDF0A3CDF090FD01E0FCF58390D9
-:101BF000FD00E04433FD121CFE807390FFB5E07DD4
-:101C00000090FD02CDF0A3CDF090FD03E0FCF58344
-:101C100090FD02E04443FD121CFE805290FFA6E0BE
-:101C20007D0090FD04CDF0A3CDF090FD05E0FCF526
-:101C30008390FD04E04434FD121CFE803190FFB619
-:101C4000E07D0090FD06CDF0A3CDF090FD07E0FC17
-:101C5000F58390FD06E04444FD121CFE801090FFC9
-:101C600092E07D00FCED44AAFD121CFE8000E49091
-:101C7000FF92F0D0E0FFD0E0FED0E0FDD0E0FCD05D
-:101C8000E0FBD0E0FAD0E0F9D0E0F8D0D0D083D0BB
-:101C900082D0F0D0E0320581058105810581A881DF
-:101CA000181818EDF608ECF690FF6AE020E70280BD
-:101CB000F790FF69E07D00A88118CDF6CD08F67D8C
-:101CC00003A881E618FCE6CC25E0CC33CCDDF9CCCA
-:101CD000F6CC08F6A88118E644F8F6A8811818187A
-:101CE000E6FD08E6FCA881188683088682EDF0A34D
-:101CF000ECF0740290FF6AF0158115811581158151
-:101D000022E5812405F581E4A88118F6A881181838
-:101D10001818EDF608ECF690FBFDE024F8500302ED
-:101D20001E1FE4A8811818F6A88118E6FEA88118DD
-:101D3000181818E6FD08E6FC7F00EF24F8404DE493
-:101D4000EF25E02485F582E434FDF583E0FBA3E094
-:101D50006C7003FAEB6D70097401A8811818F68095
-:101D60002BE4EF25E02485F582E434FDF5837A0049
-:101D7000E054F0CCF8CCCDF9CDFB7800E954F0F983
-:101D8000EA687002EB6970010E0F80AEA88118EE50
-:101D9000F6A88118181818EDF608ECF6A881EFF6E9
-:101DA000A8811818E67079A88118E624F74071A870
-:101DB0008118181818E6540FA881F664046017A853
-:101DC00081E664036010A88118181818E6FD08E67B
-:101DD000FC121C93804A7C0A1230FAA88118181849
-:101DE00018E6FD08E6FC90FBFCE025E02485F58282
-:101DF000E434FDF583EDF0A3ECF090FBFCE0FFE4B0
-:101E0000EF045407FF90FBFCF090FBFDE004F012A0
-:101E1000319390FBFEE07008E4FEFF7C0F12319AD4
-:101E2000802790FBFFE004F0543F701D90FBFFE023
-:101E300044FE7D00FC90FBFCE025E02485F582E477
-:101E400034FDF583EDF0A3ECF0E58124FBF5812270
-:101E50007885760078867600740190FBFEF012306B
-:101E60008590FBFDE060597C0A1230FA90FBFBE0A4
-:101E700025E02485F582E434FDF583E0FDA3E0FC54
-:101E800090FBFBE025E02485F582E434FDF583E456
-:101E9000F0A3F090FBFBE0FFE4EF045407FF90FB9E
-:101EA000FBF090FBFDE014F07883EDF608ECF61201
-:101EB0003193B2B37883E6FD08E6FC1208E580A111
-:101EC0001231E7788506B60011788576007886E6C7
-:101ED000F40404A2E092B47886F68085E490FBFED8
-:101EE000F090FBFDE07D00FCED44CFFD121C931251
-:101EF000310822123085E56A64494569601590FF12
-:101F000083E0540F7D00D3956AED95695005122E3C
-:101F1000CE8003122F9E12310822123085E56A64AA
-:101F20004945696005122FD8800E90FF80E0440873
-:101F3000F090FF83E0547FF0123108221230858C3C
-:101F400054EC54F0B4101575643D7563FD75620171
-:101F5000E5642403F564E5633400F563E4F557F5BF
-:101F600056E556C394015027E554540FFCAD64AEBA
-:101F700063AF62120E828C55EC600280120564E53C
-:101F800064700205630557E5577002055680D2E577
-:101F900054540F2497F8C654FEF6E554540F7F00AE
-:101FA000FE7C1212319AE5551470097D007C0912ED
-:101FB00024B18007AD577C001224B11231082212DF
-:101FC000308590FFFCE04402F090FF00E030E71322
-:101FD00090FF83E04480F043678090FFFCE0440181
-:101FE000F0801190FF82E04408F053677F90FFFC7F
-:101FF000E054FEF090FF81E04480F012256490FFF1
-:10200000FEE04405F090FFFCE054FDF012310822A0
-:102010001230857C0112324878A7E64402F674FE3D
-:10202000FC04FD121CFE90FF6AE030E70280F7E43A
-:10203000F54E754D10AC4EAD4DE54E154E7002157A
-:102040004DEC4D600280EE438701123108221230C0
-:10205000857C0212311478A7E654FDF6123108226D
-:1020600012308578A7E630E02C78A7E630E12678B4
-:10207000A7E6FCF58318E644F0FD121C9390FFFCE4
-:10208000E04420F07C0212324878A7E654FDF67452
-:102090001A90FFFEF078A7E6FCF58318E644F1FD00
-:1020A000121C9312310822756700756800E4F5660A
-:1020B000F565E4F569756A49748490FF82F074846B
-:1020C00090FF80F0748090FF68F0748090FF6AF059
-:1020D000AD46AF457E00EE24FC500302216AE4EEDB
-:1020E00075F007A4243FF582E434FCF583E0FFE4B7
-:1020F000EF5480FDE4EF540F14FFED6038E4EF750A
-:10210000F008A42448F582E434FFF5837490F0E4E9
-:10211000EF75F008A4244AF582E434FFF583748057
-:10212000F0E4EF75F008A4244EF582E434FFF58363
-:102130007480F08034E4EF75F008A42408F582E49C
-:1021400034FFF5837490F0E4EF75F008A4240AF5E9
-:1021500082E434FFF583E4F0E4EF75F008A4240E84
-:10216000F582E434FFF583E4F00E0220D38D468E31
-:10217000448F45747F90FFFDF0749090FFFCF090C9
-:10218000FC19E030E60790FFFCE04404F02290FCEC
-:102190000DE014700490FC0CE0703990FC0079069E
-:1021A0007A357B1278011203F57F00EF334015EF8B
-:1021B00090354D93FCEF2480F582E434FCF583ECFC
-:1021C000F00F80E78F5990FC2B79187A357B3578A2
-:1021D000011203F5E490FFFFF0745190FFFAF074E0
-:1021E0000490FFFBF0745390FFF8F0745190FFF9E6
-:1021F000F0745590FFF7F0749390FFF6F0743290FE
-:10220000FFF5F075643D7563FD756201E490FF8331
-:10221000F0748090FF81F0755804E55875F007A4BC
-:10222000243FF582E434FCF583E07889F6FC540F12
-:1022300014FC7889ECF6E55875F007A42441F58282
-:10224000E434FCF583E0788C76F8087600FC788935
-:10225000E675F008A42448F582E434FFF583E4F041
-:102260007889E675F008A4244FF582E434FFF583FD
-:10227000ECF0788CE6FF08E67E03CFC313CF13DEC5
-:10228000F9FE7889E675F008A42449F582E434FF64
-:10229000F583EEF07889E675F008A4244AF582E427
-:1022A00034FFF5837480F0788AECF67D00788DE653
-:1022B0002CF618E63DF6788CE6FD08E67C03CDC3E7
-:1022C00013CD13DCF9FC7889E675F008A4244DF5EC
-:1022D00082E434FFF583ECF07889E675F008A424F5
-:1022E0004EF582E434FFF583E4F0788CE6FD08E6F1
-:1022F000FC7889E6FF7E00EE24FC500302246BE4A8
-:10230000EE75F007A4243FF582E434FCF583E0FF8A
-:10231000E4EF5480FAE4EF540F14FFE4EE75F00795
-:10232000A42441F582E434FCF583E0788AF6EE7566
-:10233000F080A42408F8E5F034F8F9E8FCE9FD8A17
-:1023400059EA70030223D8E4EF75F008A42448F595
-:1023500082E434FFF583E4F0788AE6FAE4EF75F07E
-:1023600008A4244FF582E434FFF583EAF0EDFBEC9A
-:102370007A03CBC313CB13DAF9FAE4EF75F008A4B0
-:102380002449F582E434FFF583EAF0788AE67B009D
-:10239000FAEC2AFCED3BFDFBEC7A03CBC313CB1329
-:1023A000DAF9FAE4EF75F008A4244DF582E434FF7D
-:1023B000F583EAF0E4EF75F008A4244AF582E434EA
-:1023C000FFF5837480F0E4EF75F008A4244EF582E5
-:1023D000E434FFF5837480F0022467E4EF75F008BD
-:1023E000A42408F582E434FFF583E4F0788AE6FA61
-:1023F000E4EF75F008A4240FF582E434FFF583EAD6
-:10240000F0EDFBEC7A03CBC313CB13DAF9FAE4EF6C
-:1024100075F008A42409F582E434FFF583EAF07826
-:102420008AE67B00FAEC2AFCED3BFDFBEC7A03CB61
-:10243000C313CB13DAF9FAE4EF75F008A4240DF511
-:1024400082E434FFF583EAF0E4EF75F008A4240A8F
-:10245000F582E434FFF583E4F0E4EF75F008A4249A
-:102460000EF582E434FFF583E4F00E0222F48E5878
-:10247000788CEDF608ECF67889EFF61220A4228C21
-:1024800026EC30E718E526540F1475F008A424480C
-:10249000F582E434FFF583E054DFF08016E526543E
-:1024A0000F1475F008A42408F582E434FFF583E0E6
-:1024B00054DFF022EC90FD3FF08C24ED2403F52551
-:1024C0007D00D3956CED956B4003856C25E5252447
-:1024D000B75009752503740290FD3FF0AC25122F0B
-:1024E000C322E4F566F5651224E82290FD3DE0651F
-:1024F0006D600E740490FD3FF0E4F5657566038031
-:10250000467D6DE4FEFF793D7AFD7B017405780020
-:1025100012033FE5662403F566E5653400F565E5DD
-:1025200066D3956CE565956B4006856C66856B6535
-:10253000D3E5669448E5659400400C740290FD3F35
-:10254000F0E4F565756603AC66122FC322EC90FDCE
-:102550003FF0E4F566F5658C32EC6005122FB4802F
-:10256000057C00122FC32290FF04E0F54A90FF067D
-:10257000E0FDA3E0ED7D00FC7D00FC90FF06E0FFA8
-:10258000A3E07E00FFE4FEEC4EFCED4FFDC3EC94B7
-:1025900048ED9400502290FF06E0FDA3E0ED7D00A1
-:1025A000FC7D00FC90FF06E0FFA3E07E00FFE4FE60
-:1025B000EC4EFCED4FFD8004E4FD7C488C6C8D6B93
-:1025C00090FF02E0FDA3E0ED7D00FC7D00FC90FFAC
-:1025D00002E0FFA3E07E00FFE4FEEC4EF54CED4F81
-:1025E000F54B75643D7563FD7562017D3D7EFD7F34
-:1025F00001796DE4FAFB7405780012033F75490018
-:10260000E54924FE4019AD64AE63AF62E412030FE6
-:1026100005490DED70010E8D648E638F6280E1754A
-:10262000643D7563FD75620190FF00E05460B40085
-:10263000028006D35003022C12E54A540FF549E5F7
-:102640004A5480A2E0920290FF01E0120181000B47
-:102650002C0D266727852C0D28912C0D297429A86F
-:102660002B0F2B122B522BB62BE4E56730E70EE530
-:102670004C454B7008E56C6402456B6003022C0FFF
-:1026800090FF00E0541FB400028003D34029E54AC4
-:102690006003022782AD64AE63AF62740112030F60
-:1026A00078A7E630E00BAD64AE63AF62740212034C
-:1026B0000F7C02122FC322B401028003D3401BE51A
-:1026C0006720E107E54A6003022782E54A24FE50BD
-:1026D000030227827C02122FC322B402028006D397
-:1026E0005003022780E56720E10DE54A6009E54ACD
-:1026F00064806003022782AC4A12304A40030227FA
-:1027000082E549702530021190FF80E05408AD64E5
-:10271000AE63AF6212030F800F90FF82E05408ADEA
-:1027200064AE63AF6212030F803D154930021DE5B0
-:102730004975F008A42448F582E434FFF583E05499
-:1027400008AD64AE63AF6212030F801BE54975F0FC
-:1027500008A42408F582E434FFF583E05408AD644E
-:10276000AE63AF6212030FAD64AE63AF621201E6F7
-:10277000600BAD64AE63AF62740112030F7C021292
-:102780002FC3228000022C0FE56720E706E56C4589
-:102790006B6003022C0F90FF00E0541FB400028016
-:1027A00003D3401AE54C14454B7004E54A6003021C
-:1027B000288E78A7E654FEF67C00122FC322B401BF
-:1027C000028003D3402AE56720E108E56720E003A3
-:1027D00002288EE56730E004E54A700BE56730E1DA
-:1027E00009E54A24FE500302288E7C00122FC322E2
-:1027F000B402028006D3500302288CE54C454B609E
-:102800000302288EAC4A12304A400302288EE56744
-:1028100020E107E56720E0028077E56730E006E524
-:10282000496002806CE549700F90FF82E054F7F038
-:1028300090FF80E054F7F022E549B401028003D311
-:1028400040097D017C03120F0B8011B4020280034A
-:10285000D340097D017C04120F0B80001549300222
-:1028600015E54975F008A42448F582E434FFF583A2
-:10287000E054F7F08013E54975F008A42408F582C8
-:10288000E434FFF583E054F7F07C00122FC322807C
-:1028900000022C0FE56720E706E56C456B6003023C
-:1028A0002C0F90FF00E0541FB400028003D3401AA5
-:1028B000E54C14454B7004E54A600302297178A782
-:1028C000E64401F67C00122FC322B401028003D338
-:1028D0004029E56720E108E56720E003022971E56A
-:1028E0006730E004E549700BE56730E108E549240D
-:1028F000FE5002807F7C00122FC322B402028003AC
-:10290000D3406FE54C454B60028069AC4A12304AB7
-:1029100040028060E56720E107E56720E00280541F
-:10292000E549701430020990FF80E04408F0800708
-:1029300090FF82E04408F022E56730E1331549302A
-:102940000215E54975F008A42448F582E434FFF542
-:1029500083E04408F08013E54975F008A42408F5E5
-:1029600082E434FFF583E04408F07C00122FC32298
-:1029700080028000022C0FE56720E712E56C456BB2
-:10298000700CE54A700890FF00E0541F6003022CB1
-:102990000FE54C90FFFFF090FFFFE06005436701FB
-:1029A00080035367FE7C00122FC322E56730E70ED9
-:1029B000E56C456B600890FF00E0541F6003022C3B
-:1029C0000FAD4BE54CED7D00FC7D00FCBD000280B1
-:1029D00003022B0AB401028003D34032E54A70059A
-:1029E000E54CFC6003022B0C7564007563FC75629A
-:1029F00001D3E56C9412E56B94004006E4FD7C1273
-:102A00008004AC6CAD6B8C6A8D69122FD822B40235
-:102A1000028003D34059E54A6003022B0CE54CFCCD
-:102A200070277564127563FC756201D3E56C9419A7
-:102A3000E56B94004006E4FD7C198004AC6CAD6B42
-:102A40008C6A8D69122FD8802575642B7563FC758F
-:102A50006201D3E56C9435E56B94004006E4FD7C9F
-:102A6000358004AC6CAD6B8C6A8D69122FD822B4A2
-:102A700003028006D35003022B0AE54CF549700F80
-:102A800090FF04E0FDA3E04D6003022B0C80189042
-:102A9000FC82E0FDA3E0FC90FF05E06C700790FF76
-:102AA00004E06D60028068E4F56AF5697F00E5493D
-:102AB00014C549600FEF2480F582E434FCF583E00F
-:102AC0002FFF80EA8F4AE54A2480F582E434FCF542
-:102AD00083E07D00D3956CED956B4006AC6CAD6BDF
-:102AE000800FE54A2480F582E434FCF583E07D0024
-:102AF000FC8C6A8D69E54A2480FCE434FCFDFEEC24
-:102B0000FD7F018D648E638F62122FD822800002B8
-:102B10002C0F022C0FE56730E719E56C14456B703C
-:102B200012E54A700EE54C454B700890FF00E054EA
-:102B30001F6003022C0FE56720E008E56720E10332
-:102B4000022C0F756468E4F563F562E4F56904F539
-:102B50006A122FD822E56720E727E56C456B7021C4
-:102B6000E54A701DE54C6402454B600DE54C14458B
-:102B70004B6006E54C454B700890FF00E0541F6029
-:102B800003022C0FE56720E008E56720E103022C33
-:102B90000F854C68E56870084367015367FD801333
-:102BA000E56864026007E56814600280655367FEAB
-:102BB0004367027C00122FC322E56730E71AE56CF9
-:102BC00014456B7013E54A700FE54C454B70099046
-:102BD000FF00E0541F1460028038E56720E10280A6
-:102BE000317C01122FC322E56720E715E56C456BA8
-:102BF000700FE54C454B700990FF00E0541F1460C6
-:102C000002800FE56720E10280087C00122FC322BA
-:102C10008000022ECAB440028006D35003022EC0A8
-:102C200090FF01E090FD3DF0E54A90FD3EF0E4901C
-:102C3000FD3FF0E5642403F564E5633400F563AD1E
-:102C40004BE54C856482856383CDF0A3CDF090FF86
-:102C500001E01201B72C7D012CA3022CCD032CF72F
-:102C6000042D45052D82062DA8072DCE082DF4092B
-:102C70002E1A0B2E400C2E4F802E4F8100002EADB1
-:102C8000E56720E7067C0512254A227DB77E347F62
-:102C90000279407AFD7B017408780012033F7D08B9
-:102CA0007C001224B122E56720E7067C0512254A44
-:102CB00022E54AB403004010B40500500BE54A7FFA
-:102CC00000FE7C1012319A227D007C071224B12272
-:102CD000E56720E7067C0512254A22E54AB4030091
-:102CE0004010B40500500BE54A7F00FE7C11123104
-:102CF0009A227D007C071224B122E56720E7067C3A
-:102D00000512254A22E54AB405028003D3400AE4AD
-:102D1000FF04FE7C0A12319A22B401028003D340E0
-:102D20000AE4FF04FE7C0812319A22B4030040102A
-:102D3000B40500500BE54A7F00FE7C1312319A2245
-:102D40007D007C071224B122E56720E734D3E56CCF
-:102D50009448E56B94005006E56C456B70067C0268
-:102D600012254A22E54AB40103B3400BC3B4030061
-:102D70004009B406005004123070227C0712254A24
-:102D8000221224E822E56720E71DE54AB40300404B
-:102D900010B40500500BE54A7F00FE7C1612319AF4
-:102DA000227C0712254A221224E822E56720E71D2B
-:102DB000E54AB403004010B40500500BE54A7F001B
-:102DC000FE7C1912319A227C0712254A221224E82D
-:102DD00022E56720E71DE54AB403004010B4050072
-:102DE000500BE54A7F00FE7C1712319A227C0712B5
-:102DF000254A221224E822E56720E71DE54AB403AC
-:102E0000004010B40500500BE54A7F00FE7C18120C
-:102E1000319A227C0712254A221224E822E56720F3
-:102E2000E71DE54AB403004010B40500500BE54A25
-:102E30007F00FE7C1512319A227C0712254A22124D
-:102E400024E822E56720E7067C0712254A2212249F
-:102E5000E822E56730E72090FF00E0541F701090F3
-:102E6000FF01E0B480051224DF80031224E8227DF4
-:102E7000007C051224B12290FF00E0541F60067C04
-:102E80000512254A22D3E56C9448E56B9400500B5B
-:102E9000C3E56C9407E56B940050067C0312254A49
-:102EA00022E54AB40504123070227C0712254A221A
-:102EB000E56730E7087D007C051224B1227C05120D
-:102EC000254A22B420028003D340008000122F9EA6
-:102ED0002275430090FF83E0540FD395434024E5CF
-:102EE0004324F0F582E434FEF583E0AD64AE63AFD5
-:102EF0006212030F05430DED70010E8D648E638F1A
-:102F00006280D1E5437D00FCC3E56A9CF56AE56912
-:102F10009DF569E56A45696006E490FF83F02290BB
-:102F2000FF82E04408F0E4F569756A4990FD3DE0F0
-:102F3000B405028003D3404090FD3EE0F543B40564
-:102F4000028003D3400AE4FF04FE7C0B12319A2274
-:102F5000B401028003D3400AE4FF04FE7C0912316D
-:102F60009A22B403004010B40500500BE5437F00E3
-:102F7000FE7C1412319A2222B480004023B48200D5
-:102F8000501E7C3D7DFD1217D57D008C668D6590B1
-:102F9000FD3FE06005122F9E80057C00122FC322AA
-:102FA0002290FF83E0547FF090FF82E04408F0908D
-:102FB000FF80E04408F02290FF82E04408F090FF98
-:102FC00080E04408F0228C237D008C6A8D69756452
-:102FD0003D7563FD756201122FD82290FF83E05486
-:102FE0007FF0E56A64494569700122C3E56A940887
-:102FF000E56994004015752108E5217D00FCC3E5D5
-:103000006A9CF56AE5699DF5698009856A21E4F5A0
-:1030100069756A49752200E522C395215026AD6481
-:10302000AE63AF621201E6FCE52224F8F582E434D7
-:10303000FEF583ECF005220DED70010E8D648E63BC
-:103040008F6280D3E521547F90FF81F0228C487FEE
-:1030500000EF24FB4019E4EF75F007A4243FF5824C
-:10306000E434FCF583E065487002D3220F80E28FE0
-:1030700047C322856C6A856B6990FF82E054F7F044
-:1030800090FF83E0547FF022C000C001C002C00660
-:10309000C007E5722408F8860653067F7CFF1230CD
-:1030A000FA7C007D00E5756046FF90FE9DE0547F50
-:1030B0006E700FC083C082A3E0FDA3E0FCA3157572
-:1030C0008007A3A3A3DFE68026DF06D082D083801B
-:1030D0001EE0F8A3E0F9A3E0FAD082D083E8F0A3E1
-:1030E000E9F0A3EAF0A3C083C082A3A3A380DA120D
-:1030F0003193D007D006D002D001D0002285A87429
-:1031000075A888EC70027C3F8C7322E5722408F865
-:1031100076001231E780FBC000C001C002C006C0CB
-:1031200007AE047CFF1230FAE5756042FF90FE9D09
-:10313000E0547F6E700BC083C082A3A3A31575807B
-:1031400007A3A3A3DFEA8026DF06D082D08380D83E
-:10315000E0F8A3E0F9A3E0FAD082D083E8F0A3E995
-:10316000F0A3EAF0A3C083C082A3A3A380DA780807
-:10317000087918097C01E6547F6E700676007700A6
-:10318000800608090CBC08EE123193D007D006D097
-:1031900002D001D000227573008574A822C0F0C04F
-:1031A00082C083C3E57524E850051231E780F4EC52
-:1031B00060319034B6E493C39C4028C0047CFF1275
-:1031C00030FAD004430480E57575F003A4249DF51E
-:1031D00082E434FEF583ECF0EFA3F0EEA3F0057586
-:1031E000123193D083D082D0F022C0047C20D28CC4
-:1031F000D28DD504FDD0042275A80075880075B85D
-:103200000075F00075D000E4F8900000F608B800F2
-:10321000FB020000C3ED940250047D037CE8ECF453
-:10322000FCEDF4FD0CBC00010D8C798D7822C3EC13
-:1032300094BCED940250047D077CD0ECF4FCEDF4DA
-:10324000FD0CBC00010D8C778D7622EC700122C044
-:1032500000E5722418F8A604E5722408F8C6547F25
-:10326000F6E630E703D000221231E780F4C28C8505
-:10327000768C85778AD28CC0E0C0D0C0F0C082C086
-:1032800083C000C001C002C003C004C005C006C0A6
-:1032900007121B28E5722408F8E66024E572241062
-:1032A000F8A681E57275F021A42495F582E434FD39
-:1032B000F58378A8E58104C398F9E6F008A3D9FA64
-:1032C00074082572F8057208E65480700CE572B433
-:1032D00007F3780875720080EFE5722410F8868194
-:1032E000E57275F021A42495F582E434FDF5837828
-:1032F000A8E58104C398F9E0F608A3D9FAD007D06D
-:1033000006D005D004D003D002D001D000D083D0A5
-:1033100082D0F0D0D0D0E032C0E0C0D0C000C00138
-:10332000C002C28E85788D85798BD28E7819790905
-:103330007A07E77004A600800BE6600816E67004C2
-:10334000E74480F70809DAEAE573601314F573704F
-:103350000EE5722408F87600123193D28CD28DD00B
-:1033600002D001D000D0D0D0E0327581A775900096
-:103370007579307578F87577607576F012053C12BE
-:10338000340F12178B1234391231F580E322C0004A
-:103390007C01EC2408F8E660090CBC08F51231E762
-:1033A00080EED00022C0F0C082C083C000C006C042
-:1033B00007ED2410F876B6ED75F021A42495F5827A
-:1033C000E434FDF583C082C083A3A3E4780DF0A3A9
-:1033D000D8FCEC547F75F002A42482F582E5F03429
-:1033E00034F583E493FE740193F5828E83E493FEB7
-:1033F000740193FFD083D082EFF0A3EEF0ED2408A8
-:10340000F8EC4480F6D007D006D000D083D082D02C
-:10341000F0227572007575007A08791878087600C0
-:1034200077000809DAF8E478087480447FF67401BC
-:103430004410F58975B808D2ABD2A9227581A7D2FC
-:103440008ED28CD2AFE5756032FF90FE9DE0548045
-:10345000602478087908E0547FFA7B00E6547FB551
-:1034600002027BFF08D9F5EB700CEAF012338BAD4A
-:1034700004AC021233A2A3A3A3DFD21231E780C5AA
-:103480007C017D002204F504E904ED04E104DD047F
-:10349000D904E504F1049D04A104CD04D1049904E8
-:1034A00099049904D504B504AD04B104A904C10478
-:1034B000BD04B904C504C904A519010300220048CC
-:1034C0000200240F180A10640D680C05060203019F
-:1034D0000181010000E700C0008000600040003072
-:1034E0000018000C00080004000200010008183851
-:1034F000280602100A0200000000000181100A02E2
-:103500000000000000FBE8FBFA12011001FF0000C0
-:103510000851045F50160101020002090235000142
-:103520000200E0000904000005FF0000000705811B
-:10353000024000000705010240000007058202402A
-:103540000000070502024000000705850302000194
-:10355000040309042403540065007800610073002B
-:10356000200049006E0073007400720075006D0049
-:1035700065006E00740073002A0354005500530068
-:103580004200350030003500320020005300650055
-:103590007200690061006C00200050006F00720032
-:1035A00074002203540055005300420035003000DF
-:1035B00035003200200020002000200020002000E4
-:0435C00020002000C7
-:00000001FF
--- zfcpdump-kernel-4.4.orig/firmware/ttusb-budget/dspbootcode.bin.ihex
+++ /dev/null
@@ -1,820 +0,0 @@
-:1000000008AA001800030800001000000180185F13
-:100010000000018077182AEB6BF8001803FF68F8DE
-:100020000018FFFEF7B8F7BEF6B9F4A0F6B7F6B5BC
-:10003000F6B6F02019DFF1000001F84D01ABF6B87B
-:10004000F02019DFF07301A57EF80012F000000126
-:1000500047F800117E9200F80011F00000017EF8D0
-:100060000011F00000016C89019AF7B8EEFCF02055
-:10007000FFFFF1000001F84D01BFF27301B94E021C
-:10008000F495F5E356027E001100FA4C01B76B03BC
-:100090000001F6B8EE04F0740DA7F07401C54A1122
-:1000A0004A1672112AE610F80011FA4501DBF495A0
-:1000B000EEFF4811F0002AC68816F495F49510EE6C
-:1000C000FFFFF4E36CE9FFFF01D510F82AE7F845DC
-:1000D00001E210F82AE7F4E3F07401FFEE018A165A
-:1000E0008A11FC00F7B8E9204A1109F82AE6F84E0F
-:1000F00001F3F27301FDF495E80172112AE649114A
-:1001000080E12AC6F3000001E80081F82AE68A119E
-:10011000FC00F495F073020010F82A0FFC004A115D
-:10012000F074020280F82A107308000940F82A15BA
-:1001300082F80011F495771003E8F5A9F830022150
-:1001400071F82A102A1556F82A0CF0E34EF82A16F0
-:10015000E8004EF82A0C8A11FC004A064A074A1D9C
-:1001600068F800077D3F69F80007400068F8001D47
-:10017000FFFC6BF82A0F00018A1D8A078A06F4EB40
-:10018000EEFD76F82A0F000076000000FB80194C87
-:10019000F495E80080F82A11F980190780F82A0EF2
-:1001A000F980166676002A1210F82A11F98018E3F1
-:1001B00010F82A0EF980166610F82A0EF9801687B4
-:1001C000EE03FC004A11F6B8F495F020800011F817
-:1001D0002A5AF84D029311F82A9FF84C027C7712A4
-:1001E0002A39491201F82A9F8911F495F4957181F1
-:1001F00000116CE1FFAB02936BF82A9F0001E90547
-:1002000001E2000381F82AA0F073029572112A9F7F
-:10021000F49510E12A396BF82A9F000111F82A9F02
-:1002200009F82AA0F84C029376F82A5A000076F8CA
-:100230002A9F000076F82AA000008811F495481142
-:100240008A11FC004A11EEFE10F82A5AF84402B254
-:1002500076F82A5A0001F07402588811F495771044
-:100260008000F4A9F83002B24811F03000FF80009D
-:1002700010F82A5BF98018D6EE028A11FC00F4957A
-:100280004A084A094A0A4A0B4A0C4A0D4A104A11BE
-:100290004A124A134A144A154A164A174A174A1963
-:1002A0004A0E4A064A074A1A4A1D4A1B4A1C68F85F
-:1002B00000077D3F69F80007400068F8001DFFFC5B
-:1002C000481868F80018FFFEF495F4954A08EEFD0A
-:1002D000F07402588811F49577108000F4A9F83072
-:1002E00002EF4811F03000FF800010F82A5BF9801F
-:1002F00018D6EE038A18F4958A1C8A1B8A1D8A1A5E
-:100300008A078A068A0E8A198A178A178A168A1510
-:100310008A148A138A128A118A108A0D8A0C8A0B0F
-:100320008A0A8A098A08F4EB4A1177112A397681F8
-:10033000005577122A1810E2000180E1000110E256
-:10034000000280E1000276E10003000076E1000493
-:1003500000AAF07402988A11FC004A118811F495E1
-:10036000F49510816FF82A9E0C88E8FF18E10001CF
-:100370001AF82A9EF0301FFF80F82A9E8A11FC008E
-:100380004A1177112A397681005577122A1811E21D
-:10039000000181E1000111E2000281E1000276E149
-:1003A0000003000248086FE100040C98F03000FFE1
-:1003B00080E1000576E1000600AAF07402988A1137
-:1003C000FC004A1177112A397681005577122A18D4
-:1003D00010E2000180E1000110E2000280E1000271
-:1003E00076E1000300044811F00000048812F4953F
-:1003F00077132A76E900E598F3000001F6B8480B78
-:1004000008F82A3CF8430371768200AAF074029837
-:100410008A11FC004A11EEF08811F495F49571816F
-:10042000001471E1000100154911F3000002891167
-:10043000E7826DEA0004E7836DEB000A771A000596
-:10044000F07203AA1181F2E88082E9FF19E100014C
-:10045000F1A0819211E1000CF2E88083E9FF19E13B
-:10046000000DF1A081936DE9000248184918700051
-:100470000015F0000004F300000A80018102F2740C
-:100480000E54F4954814EE108A11FC004A11F074D1
-:100490000C5E80F82A5C77122A3976820055771133
-:1004A0002A1810E1000180E2000110E1000280E260
-:1004B000000276E20003001CF6B856F82A16F0F0A7
-:1004C000F0F880E2000756F82A16F1F0E8FFF28013
-:1004D00080E2000656F82A16F1F8E8FFF28080E282
-:1004E000000557F82A16E8FFF28080E2000456F86B
-:1004F000276CF0F0F0F880E2000B56F8276CF1F072
-:10050000E8FFF28080E2000A56F8276CF1F8E8FF75
-:10051000F28080E20009E8FF57F8276CF28080E261
-:10052000000856F8276AF0F0F0F880E2000F56F85D
-:10053000276AF1F0E8FFF28080E2000E56F8276AA1
-:10054000F1F8E8FFF28080E2000D57F8276AE8FF33
-:10055000F28080E2000C76E20013000076E20012E6
-:1005600000006FF82A5C0C5880E20011E8FF18F8D0
-:100570002A5C80E2001076E20017000076E20016A6
-:1005800000006FF82A9E0C5880E20015E8FF18F86A
-:100590002A9E80E2001476E2001B000076E2001A38
-:1005A000000076E20019000070E20018276E76E283
-:1005B000001F000076E2001E000076E2001D000031
-:1005C00076E2001C000076E2002000AAF074029897
-:1005D0008A11FC004A11EEFE10F82A38F84504EDA5
-:1005E00077122A1810E200028811F495771000089B
-:1005F0006DE9FFDFF6A9F8200475F073047DF010B3
-:100600000021F0001A8348087EF80008F4E2F07434
-:10061000030AF07304EA4812F2740323F0000004A2
-:10062000F2740336F495E800F07304EA77112A189F
-:10063000E8FF6FE100040D4818E10005F274096954
-:10064000F495F2A0F0740336F07304EA77112A18D7
-:10065000E8FF6FE100040D4818E10005F27409415C
-:10066000F495F2A0F0740336F07304EAF0740357C3
-:10067000F07304EA10F82A1CF07412A4F274033622
-:10068000F495E800F07304EA4812F2740380F00075
-:100690000004F2740336F495E800F07304EA10F8ED
-:1006A0002A1CF07412C5F2740336F495E800F07356
-:1006B00004EA77112A18E8FF6FE100060D4818E1F7
-:1006C000000771E100050012F2A070000012800125
-:1006D00010E10004F0740E7AF2740336F495E80029
-:1006E000F07304EAF07403BC76F82A380000EE02D6
-:1006F0008A11FC004A1177112A3976810055771248
-:100700002A1810E2000180E1000110E2000280E1FD
-:10071000000276E1000300094811F000000488128D
-:10072000F49577132A86E900E598F3000001F6B8FE
-:10073000480B08F82A3CF843050A768200AAF074B0
-:1007400002988A11FC004A1177112A3976810055E6
-:1007500077132A1810E3000180E1000110E3000282
-:1007600080E1000213E3000381E1000348117711E7
-:100770000000F84D0544F000000488124813F00012
-:1007800000048813F495F495E5986D91F6B8481136
-:1007900008F82A3CF843053AF0202A394911F500B7
-:1007A0008911F495F49576E1000400AAF07402989A
-:1007B0008A11FC004A1177112A3976810055771287
-:1007C0002A1810E2000180E1000110E2000280E13D
-:1007D000000276E10003000C4811F00000048812CA
-:1007E000F49577132A7AE900E598F3000001F6B84A
-:1007F000480B08F82A3CF843056A768200AAF07490
-:1008000002988A11FC004A1177112A397681005525
-:1008100077122A1810E2000180E1000110E20002C4
-:1008200080E1000276E1000300194811F0000004A5
-:100830008812F49577132A5DE900E598F30000012A
-:10084000F6B8480B08F82A3CF8430593768200AACC
-:10085000F07402988A11FC004A11881110F82A38A5
-:10086000F84405E310F82AA1F84405BA6CE1FF56F4
-:1008700005E372122AA1F49570E22A1800116BF8B0
-:100880002AA10001F07305E372122AA1F49570E227
-:100890002A18001110F82AA1F00000018812F4951E
-:1008A000F4956EE2FFFC05D173122AA14811F00005
-:1008B000000580F82AA210F82AA108F82AA2F84414
-:1008C00005E36CE1FFAB05DD76F82A38000176F828
-:1008D0002AA1000076F82AA200008A11FC00F495F3
-:1008E0004A084A094A0A4A0B4A0C4A0D4A104A1158
-:1008F0004A124A134A144A154A164A174A174A19FD
-:100900004A0E4A064A074A1A4A1D4A1B4A1C68F8F8
-:1009100000077D3F69F80007400068F8001DFFFCF4
-:10092000481868F80018FFFEF495F4954A08EEFFA1
-:1009300010F82A5BF9801804F07405A2EE018A18F9
-:10094000F4958A1C8A1B8A1D8A1A8A078A068A0ECF
-:100950008A198A178A178A168A158A148A138A129C
-:100960008A118A108A0D8A0C8A0B8A0A8A098A08D7
-:10097000F4EBEEFD76F82A38000076F82A5A0000EB
-:10098000E8014E00FB8017D6F495E80180F82A5B59
-:1009900076002A8FF98016AA10F82A5BF980175C76
-:1009A00010F82A5BF980176FFB801666F495E81A39
-:1009B000FB801687F495E81AFB801666F495E81B11
-:1009C000FB801687F495E81BEE03FC004A11F495B2
-:1009D00013028811E800F84D066AF3100001891A25
-:1009E000F495F07206691C918A11FC004A11881175
-:1009F00012031102F8450679F0100001881AF495E7
-:100A0000F072067881918A11FC004A11F495710206
-:100A10000011110361F800110001F8300691F6B8D9
-:100A20006FF800110C1F8811F3E8E8FF1881F1A09E
-:100A30008181F073069DF6B86FF800110C1F8811C4
-:100A4000F33000FFF020FF001881F1A081818A11AE
-:100A5000FC004A11F495110261F8000B0001F82026
-:100A600006B1490BF61F8811F495F4951081F273C5
-:100A700006B8F03000FF490BF61F8811F495F49585
-:100A80001281F4788A11FC004A11F4957102001267
-:100A900013038811E800F84D06CCF3100001891A01
-:100AA000F495F07206CB1192F2C081918A11FC008C
-:100AB0008812120271010013F84506DBF0100001E4
-:100AC000881AF495F07206DAE598FC004A11EEFEF9
-:100AD0008811110410067105001261F8001200015E
-:100AE000F82006EAF0000001F6B8F00000016FF807
-:100AF00000120F1F48088100F47F8001F27406BACB
-:100B0000F4954811EE028A11FC004A11EEFE88129B
-:100B1000110410067105001361F800130001F8209C
-:100B20000709F0000001F00000018811F6B86FF825
-:100B300000130F1F81004811F47F8001F27406CE6C
-:100B4000F49548124811F030FFFEEE028A11FC00C5
-:100B50004A114A164A17EEFCF495800271080016F5
-:100B60001009710B00178003710A00114817F8452E
-:100B7000073F700000111003F074069F80017000A1
-:100B800000161002F074067B6D916D966CEFFFFFFE
-:100B9000072FEE048A178A168A11FC004A11EEFE0E
-:100BA00010F82AE808F82AE9F845076476000001F9
-:100BB00062F82AE9005EF274120BF0003040721104
-:100BC0002AE97710000FF5A9F82007616BF82AE9E8
-:100BD0000001F073076476F82AE90000EE028A113A
-:100BE000FC004A118811E80075F800080008E800C8
-:100BF00075F800080009F6B8F495F020FC3F75F888
-:100C00000008000DF0200C3075F80008000C76F894
-:100C10002AE8000076F82AE900006C81079276F84D
-:100C20002AEA0000FB801676F495E810E80075F8D3
-:100C300000080000F07307A876F82AEA0001FB809C
-:100C40001666F495E810FB801687F495E810E80026
-:100C500075F800080000F6B8F495F020FFFF75F86D
-:100C6000000800008A11FC00F4954A084A094A0A63
-:100C70004A064A074A1D68F800077D3F69F80007E1
-:100C8000400068F8001DFFFC10F82AEAF84507E16B
-:100C900010F82AE8F0000001F030000F80F82AE890
-:100CA00010F82AE8F84407D6F6B8F495F020FC3F8F
-:100CB00075F80008000DF0200C3075F80008000CE5
-:100CC000E80075F800080000F6B8F495F020FFFF82
-:100CD00075F8000800008A1D8A078A068A0A8A09B0
-:100CE0008A08F4EBEEFFF2740767F495E801EE0171
-:100CF000FC004A074A1D68F800077D3F69F80007B5
-:100D0000400068F8001DFFFC8A1D8A07F4EB4A11B9
-:100D10007711002876812400E80075F800080001AA
-:100D2000F2740767F495E8007711001D6881007F71
-:100D3000F6B8F495F020FF807711001DF030010027
-:100D40001A818081F0740A33F07411ACF980132594
-:100D5000F9801653F9801782F074062FF98014B2C7
-:100D6000F9801910F0740DE3F07407E8F07402369E
-:100D70008A11FC004A1160F8277BFFFFF830083920
-:100D800071F8277B277960F82779FFFFF83008B2E0
-:100D900010F8298608F82779F0307FFF8811F4953C
-:100DA00077104000F6A9F830085810F8277908F8AD
-:100DB000277AF0307FFF8811F49577104000F6A96C
-:100DC000F820086376F82779FFFF76F8277BFFFF86
-:100DD000F7B8F27308D9F020FFFFF6B856F8277479
-:100DE000F0F9881156F82772F0F98812F495F49505
-:100DF000E720F4A9F830088FF120277C4811F6008D
-:100E00008813F495F495108308F82779F0307FFF64
-:100E10008813F49577104000F5ABF830088F6D918A
-:100E20004811F03001FF8811F495E720F7A9F83058
-:100E300008746D894811F03001FFF0E7F495480817
-:100E40004EF827744808F1F98911F495F49571E189
-:100E5000277C277A60F8277BFFFFF83008AB48082B
-:100E60004EF8277276F8277BFFFF76F82779FFFF89
-:100E7000F27308D9F495E80044F8277340F8277511
-:100E800082F80011F49577108000F6A9F82008D8B0
-:100E9000F6B810F82773F000800048084EF8277461
-:100EA0004808F0F98811F495F49571E1277C277AC8
-:100EB000F7B857F82774F062FFFFF040FF80F28028
-:100EC0004EF82774E8008A11FC004A114A16EEFB1E
-:100ED00011F8277109F8277389118810F495F49592
-:100EE000F6A9F82008EDF273090EF495E800F62053
-:100EF00076000041F07412EE8816F495F7B86D96FE
-:100F000010F80016F847090AE7617600000076013C
-:100F10000080760200FF76030000F2740CB9F495AD
-:100F2000E8006CE9FFFF08FB7316000EF066004155
-:100F3000EE058A168A11FC004A11F495710200131D
-:100F4000F6B877117FFF57F827724811F280F0004A
-:100F500080008811F640F0E0F1F1E801F28080F8BD
-:100F600027787712800057F827724812F28088128B
-:100F7000F495F4956C820938E80075F800080001D2
-:100F8000F073093DF020800175F8000800017081C0
-:100F900000138A11FC004A11F0307FFF11F82986F6
-:100FA000F520F3307FFF8911F49577104000F6A902
-:100FB000F8200954F2730967F495E8026FF8277A6C
-:100FC0000D20F3307FFF8911F49577104000F6A9CA
-:100FD000F8200964F2730967F495E80180F8277B2B
-:100FE000E8008A11FC004A1111F82986F520F33037
-:100FF0007FFF8911F49577104000F6A9F820097A4F
-:10100000F273098DF495E8026FF8277A0D20F3301A
-:101010007FFF8911F49577104000F6A9F820098A1E
-:10102000F273098DF495E80180F82779E8008A11B8
-:10103000FC004A11F495710200128811F6B857F8B5
-:101040002772F0207FFFF280F0008000808157F847
-:101050002772E801F3F1F28080F827787711800099
-:10106000481157F82772F2808811F495F4956C8135
-:1010700009B5E80075F800080001F07309BAF0201E
-:10108000800175F80008000145F8277143F82773BF
-:1010900083F80011F495E720F6A9F83009C9F27336
-:1010A00009E47712000057F82772F0207FFFF280E2
-:1010B0004912F500F300800061F8000B8000F83061
-:1010C00009DCF1208000F5208912F49548126FF8B0
-:1010D00027730D00F495490B4FF827728A11FE0013
-:1010E0004812F4954A114A164A17EEFCF495710815
-:1010F00000168817F0740830481870000016F27453
-:10110000098FF00000028811F495F4956C810A0AA9
-:10111000F27408DBF4954816481870000016F27453
-:10112000098FF00000028811100270010011800088
-:10113000F27406CEF495481749114817F60088173F
-:10114000E760F5A9F8200A2D4816F62088114818FE
-:1011500070000011F274098FF00000028811700114
-:10116000001110028000F27406CEF4954817EE04C8
-:1011700048168A178A168A11FC00EEFDE8004EF820
-:101180002770E8004EF82772E8004EF82774E80050
-:101190004EF8277676F82779FFFF76F8277A000051
-:1011A00076F8277BFFFF76F827780000E80075F8CF
-:1011B000000800017600000076010200F27412DCE3
-:1011C000F020277CEE03FC004A11EEFCF4954E0063
-:1011D00077127FFFF6B84912F180F3008000891280
-:1011E000F0E0F1F14F02E901F495480BF5405602A9
-:1011F000F18081F827787711800056004911F1803D
-:101200008911F495F4956C810A81E80075F800085D
-:101210000001F0730A86F020800175F800080001D3
-:101220001082EE048A11FC004A11EEFEF4954E0085
-:1012300077117FFFF6B84911F180F3008000891122
-:10124000F0E0F1F1E801F28080F827785600F12013
-:101250008000F180F495490BF84D0AABF020800135
-:1012600075F800080001F0730AAFE80075F800088F
-:101270000001EE0248118A11FC004A118812130283
-:1012800077110000F84D0ACBF3100001891AF4958C
-:10129000F0720ACA48111CF8297E881111F8297EBB
-:1012A000F200000180F8297E819248118A11FC0029
-:1012B0004A11F495710200118812F6B8F0207FFFF0
-:1012C00057F82770F280F0008000808257F827706E
-:1012D000E801F3F1F28080F8277877128000481255
-:1012E00057F82770F2808812F495F4956C820AF40E
-:1012F000E80075F800080001F0730AF9F020800199
-:1013000075F80008000145F82775E71043F82771C4
-:1013100083F800126DE800046D8AF6AAF8300B0A13
-:10132000F2730B257711000057F82770F0207FFF2C
-:10133000F2804911F500F300800061F8000B800095
-:10134000F8300B1DF1208000F5208911F49548112B
-:101350006FF827710D00F495490B4FF8277048116D
-:101360008A11FC004A114A164A17EEF08817101726
-:1013700080051016800610158007711400111005E5
-:10138000F030000188101006F0300001800849118B
-:101390001005F6018009100661F800080001F82028
-:1013A0000B4B1009F0000001800971080012F4AA2B
-:1013B000F8300B541009F00000018009120949119E
-:1013C000F47F8009F620800A56F827704E0C100929
-:1013D00080004818F2740ACEF00000048816F495D4
-:1013E000F4956C860B6DF2730C59F495E800F6B821
-:1013F000F495560CF0F98812F495F49570E2277C78
-:101400002986E800800E4811F8450BCC77100001C2
-:10141000F4A9F8300B896CE1FFFD0B8B10E700029B
-:10142000800EF0730B8B1087800EE710F5AEF8205E
-:101430000BB270000017700100161004F07406CE95
-:1014400048174916F60088174811F6208811100928
-:10145000F62080004818F2740ACEF00000048816C6
-:1014600010047000001770010011F07406CE4811CE
-:1014700000048004F0730BBC7000001770010011B1
-:101480001004F07406CE4811000480044911481677
-:10149000F6208816F495F4956C860BCC100A800023
-:1014A0004818F2740ACEF00000048816120AF845B3
-:1014B0000C33710A0010F4AEF8300C1C4816F0E141
-:1014C00088111208F8450BDB6D891207F8450BE906
-:1014D0001007800070020011100680011004F074E3
-:1014E00006DCF0730BEF48116F000C9F1004F074D2
-:1014F0000AB3110EF1C0810E10064911F6008006E4
-:101500001005F6208811F000000148086F000C9FBC
-:101510004818F2740ACEF00000041207F8450C11C6
-:101520001007800070020011100680011004F07492
-:1015300006DCF0730C1748116F000C9F1004F07458
-:101540000AB3110EF1C0810EF0730C331207F84587
-:101550000C2A10078000100680011005800210047C
-:10156000F07406DCF0730C3012056F000C9F100451
-:10157000F0740AB3110EF1C0810E76000001481814
-:10158000F2740ACEF0000004710400117081298603
-:10159000100E1CF82986800E760000014818F2749F
-:1015A0000ACEF0000004100E71040011808110F8C2
-:1015B0002986F0000001F0307FFF80F829861009AD
-:1015C000F00000028009EE108A178A168A11FC00CA
-:1015D00010F8277508F82771F01000014808FC0082
-:1015E0004A114A16EEFFF49571040016F00000014E
-:1015F00048084EF8297C6DEEFFFD4816F8450C9919
-:1016000056F8297CF0740A5A881110F8297DF000E8
-:10161000000148084EF8297C10F82982F0000001EA
-:101620008810F495F495F4A9FA300C9680F8298284
-:1016300056F82980F00000014EF8298073112982A4
-:101640006CEEFFFF0C76EE018A168A11FC004A113F
-:1016500076F82984000076F829850001E8004EF824
-:101660002A0C76F82986000076F829870000771181
-:1016700029887681AAAA76E10001AAAA76E1000269
-:1016800000008A11FC004A11EEFCF495710600146A
-:10169000710700137108001271090015771000FF1F
-:1016A000F4AAF8300D44491353F82A0C4FF82A0CC9
-:1016B0007312000EF166000D8911F4957710000188
-:1016C00071E124000011F4A9F8300D177710000221
-:1016D000F4A9F8300CEC7711298A76810000E80033
-:1016E0007714000077130000F0730D486C830CFA38
-:1016F0007711298A4812F0E8F04080008081E800E4
-:1017000077140000F0730D484913F340800081F80E
-:10171000298A61F800150001F8200D0769F8298A67
-:10172000400061F800140001F8200D0F69F8298AC3
-:1017300020007711298A4912F3E81B818181F07317
-:101740000D4811F82984F84C0D37771129887681D6
-:10175000AAAA11F82985F3100001F340AA0081E13B
-:101760000001760000028001700200147003001373
-:10177000F2740B28F495481171F829852984F073C7
-:101780000D737600000080017602000070030013E4
-:10179000F2740B28F495E800F0730D737711298A21
-:1017A0007081001311F82984F84C0D68771129888D
-:1017B0007681AAAA11F82985F3100001F340AA0046
-:1017C00081E10001760000038001700200147003C3
-:1017D0000013F2740B28F495481171F829852984B7
-:1017E000F0730D7376000001800170020014700325
-:1017F0000013F2740B28F49548116BF82984FFFF4D
-:10180000EE048A11FC004A11F540F495480BF47877
-:101810008811F495F4956CE1FFB90D88F2730DA56C
-:10182000F495E860F200000661F800110020F8303D
-:101830000D9861F8000B0001F8200DA3F2000007DD
-:10184000F0730DA361F8000B0001F8200DA1F273F5
-:101850000DA3F0000001F00000024808F47F8A1197
-:10186000FC00EEFFF07407FDF0740744F0740DB453
-:10187000F0740205F0740460F0730DAAEEFD10F828
-:101880002AA3F8440DCB10F82AA4F8450DD776000A
-:101890000200F27409E8F020220076F82AA4000081
-:1018A00076F82AA70000F0730DD776000200F274D4
-:1018B00009E8F020200076F82AA3000076F82AA78D
-:1018C0000001F0740C5EF0E0F0103A98F8470DE17A
-:1018D00076F8276E0000EE03FC004A11EEFE771149
-:1018E00020007600AAAA76010200F274066CF49534
-:1018F000481176005555760102004811F274066CC5
-:10190000F000020076F82AA3000076F82AA400006E
-:10191000E8004E00FB80153EF495E80480F82AA507
-:1019200076002AA8F980148776002AADFB8013621E
-:10193000F495E80210F82AA5F9801463FB80166676
-:10194000F495E81CFB801687F495E81CE8014E002E
-:10195000FB8017D6F495E80080F82AA676002AB70F
-:10196000F98016AA10F82AA6F980175C10F82AA6A2
-:10197000F980176FEE028A11FC00F4954A084A09B3
-:101980004A0A4A074A1D68F800077D3F69F80007C0
-:10199000400068F8001DFFFC10F82AA7F8440E4B21
-:1019A00076F82AA30001F0730E4E76F82AA40001FF
-:1019B0008A1D8A078A0A8A098A08F4EB4A114A169C
-:1019C0004A17EEFE880E71080016710600171107FF
-:1019D000F066000DF00025A0881176010006810058
-:1019E000F27406CEF00000017601000670000016C9
-:1019F0004811F27406CEF000000770810017EE0265
-:101A00008A178A168A11FC004A11880E7102001288
-:101A10001103F066000DF00024008811F495708128
-:101A200000126EE2FFFE0E8DF495E800E80180E101
-:101A3000000276E1000300FF76E10004000076E199
-:101A4000000B000076E1000C000081E100018A112A
-:101A5000FC004A11EEFC880EF495F166000DF300CF
-:101A600024008911F495F49576E1000C000076E1EC
-:101A7000000B000076E10002000176000000760114
-:101A80000000800276030000F2740CB9F495E800BF
-:101A9000EE048A11FC004A118819F4957319000E9E
-:101AA000F166000DF2002400771525A077140000E0
-:101AB000771A001FF0720F14F6B849190985F84C0F
-:101AC0000F13F100000589114915F3000001891376
-:101AD0004915F3000007891211931D91199289107D
-:101AE000F495F4956C800F1311931D911992891040
-:101AF000F495F4956C800F1311931D911992891030
-:101B0000F495F4956C800F1311931D91199289101F
-:101B1000F495F4956C800F1311931D91199289100F
-:101B2000F495F4956C800F1311931D9119928911FE
-:101B3000F495F4956C810F136D946DED000D4814C0
-:101B40008A11FC004A114A164A17EEF88817100D40
-:101B50008004100C8005710E00167317000EF066DD
-:101B6000000DF0002400881110F82763F8450F32AB
-:101B7000F2740E9FF495481710F82760F8440F3D53
-:101B800060E100020001F8200F6DF07311331004C2
-:101B900080001005F074069F1104F3000001810419
-:101BA0006D8E7710000171E100020012F4AAF83086
-:101BB0000F6277100002F4AAF8300F6D45E1000BB8
-:101BC000881043E1000C83F80012F495F495F4AA10
-:101BD000F8300F6DF0730F96F50081044916F5206B
-:101BE000891676E1000C000076E10004000048163A
-:101BF000F8451133F7B871E10002001210F8001235
-:101C0000F0100003F8460F8C10F80012F0100003DB
-:101C1000F845101677100001F4AAF8300F9C7710E1
-:101C20000002F4AAF8300FA8F0730F9677100004A2
-:101C3000F4AAF83010B777100005F4AAF83010BCF9
-:101C4000F2740E9FF4954817F073113176E1000C91
-:101C5000000076E1000B000076E10004000076E170
-:101C60000002000211E1000CE803F6208912F4954D
-:101C700077100003F5AAF8300FB66BF8276F000154
-:101C80008810F495F495F5AEF8200FBD481680063F
-:101C90008813F49577100003F6ABF8200FC86BF8A3
-:101CA000276F00011206F845100010E100048000C3
-:101CB0001005800110048002100680034811F274A0
-:101CC000071EF0000005100600E1000480E100049A
-:101CD000100600E1000C80E1000C881211061004CF
-:101CE000F60080044816F62088168913F4957710BC
-:101CF0000003F6ABF8200FF56BF8276F00017710A3
-:101D0000000C71E100040013F6ABF82010006BF832
-:101D1000276F00016CE2FFFD1131F6B86FE100059D
-:101D20000C486FE100060C18F0300FFFF0000003C4
-:101D300080E1000B76E1000200034816F8451133FC
-:101D400071E1000C001210E1000B4912F62088131B
-:101D5000E80CF6208810F495F495F5ABF8201027E0
-:101D6000481380068810F495F495F5AEF8201030ED
-:101D7000700600161206F845105F10E1000480009E
-:101D80001005800110048002100680034811F274CF
-:101D9000071EF0000005100600E1000480E10004C9
-:101DA000100600E1000C80E1000C881211061004FE
-:101DB000F60080044816F6208816F4957710000C7B
-:101DC00071E100040013F6ABF820105F6BF8276F89
-:101DD00000017710000CF6AAF820106BF2740E9F29
-:101DE000F495481771E1000C00127710000CF4AA6A
-:101DF000F830107C7710000C71E1000B0013F6AB8B
-:101E0000F83010B4E730F7AAF83010B4F2740EC10D
-:101E1000F49548178812F495F4956C82108D76E14C
-:101E20000004000076E100020005F07310B476E1D2
-:101E3000000200047710000C71E1000B0012F5AAFB
-:101E4000F820109AF073109C7712000C76000000B6
-:101E50007001001270020017760300014811F2743D
-:101E60000CB9F000000576E1000400007710000CCA
-:101E700071E1000B0012F6AAF820111C4816F84573
-:101E8000113360E100020005F82010DF10E1000BC3
-:101E900008E1000C11E10004F84D10C76BF8276F42
-:101EA00000018810F495F495F5AEF82010CF48168F
-:101EB000F4954808F84511166FE1000C0D0081E11A
-:101EC000000C1104F50081044916F5208916F07301
-:101ED000110E10E1000B71E1000C00128810F49556
-:101EE000F495F6AAF83011164912F6208810F495E8
-:101EF000F495F5AEF82010F3481680064808F8452A
-:101F000011161004700200178000760300001006FE
-:101F100080011005F0740CB9100600E1000C80E19E
-:101F2000000C11061004F60080044816F6208816EE
-:101F300010E1000C08E1000BF845111CF0731131A1
-:101F4000F2740E9FF4954817F073113376E1000C8C
-:101F5000000076E1000B000076E1000200011004B1
-:101F600080001005F074069F8812F495771000FF2A
-:101F7000F4AAF83011336C860F70EE088A178A16AF
-:101F80008A11FC004A11EEFCF495710600128811CA
-:101F90007312000EF166000DF30024008914138102
-:101FA000F77AF330000181F8276013E10001F77C34
-:101FB000F330000381F82761E90F19E1000181F88E
-:101FC000276271E400030013F6B84913F30000011F
-:101FD000F330000F490B09F82762F84D117577109F
-:101FE00000FFF4ABF830117557F8276CF3000001CF
-:101FF0004FF8276C76F827630001F073117876F8B4
-:102000002763000070E40003276276F8276400006D
-:1020100011F8276161F8000B0002F820118DE90129
-:102020006FE100020F1881F8276411F8276161F849
-:10203000000B0001F82011A910F82764F10000043A
-:102040008913E9B8F52081F8276560840002F8203B
-:1020500011A9700000117001001370022765F2745D
-:102060000F18F4954812EE048A11FC004A114A1622
-:102070004A17EEFCE8004EF82766E8004EF827689D
-:10208000E8004EF8276CE8004EF8276A77122740E0
-:1020900077112400771A001FF07211DB7092001183
-:1020A00076E10001FFFF7681000076E1000200008A
-:1020B00076E1000300FF76E1000C000076E1000B02
-:1020C000000076E1000400006DE9000DF02025A07D
-:1020D000F10000078911F100000181028816F495D2
-:1020E00077170020768600FF760000007601000654
-:1020F0001002F074066C7600000076010006F2749F
-:10210000066CF49548111002F000000D80026DE994
-:10211000000D6DEE000D6CEFFFFF11E8F0740C9DEB
-:10212000EE048A178A168A11FC004A114A164A17C9
-:10213000EEFA8811100A4911F84D129F4808F84527
-:10214000129F80041281F5788912F495F4956CE25F
-:10215000FFB9128A61F800080080F830128A13E192
-:102160000001F0E8F778F1A0F2301FFF8817F4952E
-:10217000771224007716000077130020F6B848176E
-:1021800008E20001F84512426DEA000D6D966CEB15
-:10219000FFFF1234F073129056F8276AF000000126
-:1021A0004EF8276A60820001F83012547000001661
-:1021B000F2741138F4954811F07312907000001603
-:1021C000F2741138F495481172102A9EF495F4AF08
-:1021D000F830126E76000000760100BC7002001626
-:1021E00076030000F2740CB9F4954811F073129064
-:1021F00010F8276EF844129076000000760100BCBB
-:102200007002001676030000F2740CB9F4954811C0
-:10221000F0740C5EF0E0F0101388F842129076F83B
-:10222000276E0001F073129056F82766F000000147
-:102230004EF827666DE9005E56F82768F000000149
-:102240004EF82768710400126EEAFFFF121870043E
-:102250000012EE068A178A168A11FC004A11EEFE59
-:10226000880EF495F066000DF00025A08811F49515
-:10227000F495768100FF7600000076010006F27486
-:10228000066CF0000001760000007601000648119F
-:10229000F274066CF0000007EE028A11FC004A118D
-:1022A000880EF495F066000DF00024008811F49576
-:1022B000F49576E10001FFFF7681000076E10002EF
-:1022C000000076E1000300FF8A11FC004A11F4953A
-:1022D00013038811FA4D12EC71020012F310000181
-:1022E000891AF495F07212EB709100128A11FC00B9
-:1022F000F4954A0B4A0C4A0DF7B8EEFE10F80008A8
-:102300001106F1C08300F4851106F7858106F6B841
-:10231000EC0F1E0661008000F8201305F484EE0225
-:102320008A0D8A0C8A0BFC00F4954A0B4A0C4A0D64
-:10233000EEFEF7B8800010F80008F4851106F78566
-:102340008106F6B8EC0F1E06F0F061008000F82060
-:102350001320F484EE028A0D8A0C8A0BFC004A11C9
-:102360007711007B76812EEC7711007BEEFF718177
-:102370000011EE0176E10001000076E100040000AA
-:1023800076E10006000076E10062000076E100766A
-:10239000000076E10092000076E10094000076E112
-:1023A00000B0000076E100B3000076E100BE00005E
-:1023B00076E100BF000076E100C1000076E100C3D5
-:1023C000000076E100C5000076E100C700007681DC
-:1023D00000008A11F495F4E44A114A164A17EEFFF8
-:1023E000F49571060016FB8016A28817F495F7B8CD
-:1023F00010F80017F0100002FA4613887711000059
-:1024000010F80017F0100002F84513F910F8001743
-:10241000F845143910F80017F0100001F845141FA2
-:10242000F073145210F80017F0100003F84513D39E
-:1024300010F80017F0100006F84414527712007BD1
-:102440007182001461E400070040F830145249140E
-:102450004817F6008812F495771300557711005746
-:102460006DEA003BE50110E600068081481400F8A3
-:1024700000178812F4957711005510E20040808112
-:102480007711005710E6000780817711005510E2A0
-:102490000045808110E60008771100578081771190
-:1024A000005510E2004A80817711005710E60009BC
-:1024B0008081F2731452771103C07712007B10826F
-:1024C000F00000078813F495F495961BF830145229
-:1024D00010E300357712005580827712005710E61E
-:1024E000000480827712005510E300378082771253
-:1024F000005710E6000580824811F0400010F2738A
-:102500001450F04000207712007B1082F00000078A
-:102510008812F495F495960DF830145210E20034B8
-:102520007713005580837713005710E600028083ED
-:1025300010E200367712005580827712005710E6BD
-:10254000000380824811F0400004F2731450F04000
-:1025500000087712007B1082F00000078812F495C3
-:10256000F495960EF830145210E2003377120055AD
-:1025700080827712005710E6000180824811F273C2
-:102580001450F04000027712007B1082F000000728
-:102590008812F495F495960FF830145210E2003238
-:1025A000771200557713005780824811E762F04098
-:1025B0000001E5018811F4957712007B48117182C2
-:1025C00000121AE2000780E20007F980169AEE0175
-:1025D0008A1748118A168A11F4E44A118811770E75
-:1025E000000577120055E804F6B828E10002EEFF76
-:1025F000808277120057F0208000EE011A82771255
-:1026000000578082E80132E10002F5827711005420
-:10261000F693188177110054F2A080818A11F49505
-:10262000F4E44A114A16F49571040011FB8016A2D5
-:102630008816F4957712005510E600038082771211
-:10264000005610E100027713005680827712005680
-:1026500010E10003808210E10004771200568082AE
-:102660007712005610E100018082E712E501F9803F
-:10267000169A8A168A11F4E44A114A164A17EEF994
-:102680007711007B76000016760100177602001A9B
-:102690007603001B7604001C7605001D718100176F
-:1026A00071E7000600111081F84414DFF980165319
-:1026B000F6B8FB801585F020FFFFF6B8FB80160802
-:1026C000F020FFFF7711007B7181001776E700068D
-:1026D00000014817771600007710000477150003F3
-:1026E0007714000277130001F000003976E7000844
-:1026F000001F76E700070000880E771A00054817CC
-:10270000F0000009881248188819E800F072152CAA
-:10271000731900117682000011917311001970E293
-:102720000003001670E20004001370E200050014BC
-:1027300081E2000170E20006001570E2000700105F
-:1027400080E20002730E0011F100001E6DEE000524
-:102750006DEB00056DEC00056DED00056DE8000505
-:10276000F000000181916DEA00087311000EEE0780
-:1027700076E70041002476E70046002576E7004B27
-:10278000002676E7005000278A178A168A11F4E49B
-:102790004A114A16EEFE881156064E00F98016A21E
-:1027A000F7B810F80011F010FFFFFA451560771622
-:1027B000FFFF7712007B49111082F603F000000939
-:1027C0008811F495F4951081F8441571F273157120
-:1027D000F495E7167711007B1081F000000988114D
-:1027E000F495771200061081F845155C6EEAFFFF3C
-:1027F00015696DE9000876860001E9015600F1804F
-:1028000010F8000BF845157EFB801585F4954816E9
-:10281000F980169AEE0248168A168A11F4E44A11D3
-:10282000EEFFFB8016A28811F4957710FFFFF4A944
-:10283000F83015C410E1000377120055808277123A
-:1028400000567682000077120056768200007712DA
-:1028500000567682000077120056768200007712CA
-:1028600000567682000010E10002F000000832F805
-:10287000000877120054E801F482F493188277126A
-:102880000054F0400000808210E10001F9801676CB
-:1028900010E10001F9801666F07316037711007BD2
-:1028A0007181001171E1000700127682000010E1D1
-:1028B0000009F98015857711007B7181001110E105
-:1028C0000009FB801585F00000087711007B7181FD
-:1028D000001110E10009FB801585F0000010771150
-:1028E000007B7181001110E10009FB801585F0006B
-:1028F00000187711007B7181001110E10009FB8045
-:102900001585F00000207711007B7181001110E126
-:102910000009FB801585F0000028F980169AEE0169
-:102920008A11F4E44A11EEFFFB8016A28811F49597
-:102930007710FFFFF4A9F830164177110055768122
-:10294000001E7711005676810000771100567681BF
-:1029500000007711005676810000771100567681CD
-:1029600000007711005676810000771100567681BD
-:1029700000007711005676810000771100567681AD
-:102980000000771100567681000077110056F2732F
-:10299000164E768100007711007B7181001171E184
-:1029A000000700127682000010E10039F980160855
-:1029B000F980169AEE018A11F4E44A117711007B2E
-:1029C0001081F00000048811F495F4951081FA4408
-:1029D0001663F495EEFF76810001EE018A11F4E4AE
-:1029E000F01000104A1132F80008EEFF77110001D4
-:1029F000E801EE01F4821A8180818A11F495F4E4F1
-:102A0000F01000104A1132F80008EEFFE8017711CB
-:102A10000000F482EE01F493188180818A11F4950C
-:102A2000F4E44A11F01000107711000032F80008A9
-:102A3000EEFF1181E801EE0177110000F482F2A0AF
-:102A400080818A11F495F4E4F273169EF6BBF49536
-:102A5000F495F495F495F4E4F27316A6F7BBF495A7
-:102A6000F495F495F495F4E44A114A16F49571043A
-:102A70000016FB8016A28811F49571E10005001282
-:102A80007682000E10E6000E71E1000600128082D0
-:102A900071E1000500127682000D71E1000600125E
-:102AA00010E6000D808271E1000500127682000CB4
-:102AB00010E6000C71E100060012808271E1000551
-:102AC00000127682000B10E6000B71E10006001286
-:102AD000808271E1000500127682000A71E1000631
-:102AE000001210E6000A808271E100050012768271
-:102AF000000910E6000971E100060012808271E110
-:102B0000000500127682000871E10006001210E64E
-:102B10000008808271E1000500127682000710E64D
-:102B2000000771E100060012808271E100050012C9
-:102B30007682000671E10006001210E6000680822F
-:102B400071E1000500127682000571E100060012B5
-:102B500010E60005808271E1000500127682000413
-:102B600071E10006001210E60004808271E10005A8
-:102B700000127682000371E10006001210E60003E5
-:102B8000808271E1000500127682000210E60002E8
-:102B900071E100060012808271E100050012768268
-:102BA000000110E6000171E100060012808271E16F
-:102BB000000500127682000071E100060013E76252
-:102BC000E501F980169A8A168A11F4E44A118811EF
-:102BD000F495F49571E100050012EEFF7682000095
-:102BE000EE0171E100060011698100018A11F4957E
-:102BF000F4E44A118811F495F49571E1000500128E
-:102C0000EEFF76820001EE0171E10006001169819C
-:102C100000018A11F495F4E44A117711007B1081C8
-:102C2000F00000948811F495F4951081FA44179CF3
-:102C3000F495EEFFF98016537711007B1081F000B8
-:102C400000948811F495F49576810001EE0176E107
-:102C50000001000076E10002002176E1000300207F
-:102C600076E10004002376E10005002276E100060B
-:102C7000003876E10007003976E10008001576E1BA
-:102C80000009001476E1000A000076E1000B004123
-:102C900076E1000C004076E1000D004376E1000E85
-:102CA000004276E1000F004876E10010004976E12D
-:102CB0000011001B76E10012001A8A11F495F4E469
-:102CC0004A11EEFD881156064E00F98016A27712C1
-:102CD000007B770E0009108228F80011F0000095A3
-:102CE0008811F495F4951081F84517F0F27317FDEB
-:102CF0007711FFFF76810001E9015600F18010F89D
-:102D0000000BF84517FDFB801810F4954811F98069
-:102D1000169AEE0348118A11F495F4E44A118811C9
-:102D2000F495EEFF71E100010011EE0110818A11AE
-:102D3000F495F4E44A11EEFFFB8016A28811F49595
-:102D40007710FFFFF4A9F83018C371E100050012F5
-:102D50007682000071E1000600127682000071E1C7
-:102D6000000500127682000171E1000600127682F1
-:102D7000000071E1000500127682000271E1000698
-:102D800000127682000071E10005001276820003D5
-:102D900071E1000600127682000071E10005001268
-:102DA0007682000471E1000600127682000071E173
-:102DB000000500127682000571E10006001276829D
-:102DC000000071E1000500127682000671E1000644
-:102DD00000127682000171E1000500127682000780
-:102DE00071E1000600127682200071E100050012F8
-:102DF0007682000871E1000600127682000071E11F
-:102E0000000500127682000971E100060012768248
-:102E1000000071E1000500127682000A71E10006EF
-:102E200000127682000071E1000500127682000B2C
-:102E300071E1000600127682000071E100050012C7
-:102E40007682000C71E1000600127682000071E1CA
-:102E5000000500127682000D71E1000600127682F4
-:102E6000000071E1000500127682000E71E100069B
-:102E700000127682000010E10007F980167610E15A
-:102E80000008F980167610E10007F980166610E157
-:102E90000008F9801666F07318D17711007B108155
-:102EA000FB801810F00000957711007B1081FB80EB
-:102EB0001810F000009EF980169AEE018A11F4E4D1
-:102EC0004A118811EEFFF495100471E1000300111E
-:102ED000EE0180818A11F495F4E44A114A16F495C2
-:102EE00071040016FB8016A28811F49571E10002AE
-:102EF00000127682001010E6000171E1000300125A
-:102F0000808271E10004001210E600028082E76214
-:102F100071E100020013E501F980169A8A168A1100
-:102F2000F4E44A118811EEFFEE0110E100018A116C
-:102F3000F495F4E44A117711007B1081F00000B39E
-:102F40008811F495F4951081FA44192AF495EEFF4E
-:102F5000F98016537711007B1081F00000B38811BF
-:102F6000F495F49576810001EE0176E10001000010
-:102F700076E10002001376E10003002676E100040A
-:102F8000002576E10005002476E10006000076E1E8
-:102F90000007001776E10008003276E100090031F1
-:102FA00076E1000A00308A11F495F4E44A114A16D9
-:102FB0004A17EEFFF49571060017FB8016A28811E0
-:102FC000F495F7B810F80011F010FFFFFA451973E7
-:102FD0007716FFFF7712007B770E0005108228F826
-:102FE0000011F00000B48811F495F4951081F844B4
-:102FF0001984F2731984F495E7167711007B108118
-:10300000F00000B48811F495771200021081F845A1
-:10301000196F6EEAFFFF197C6DE9000561F8001772
-:103020000001FA20198F76860001FB801997F4952C
-:103030004816F980169AEE018A1748168A168A11E0
-:10304000F4E44A11EEFFFB8016A28811F495771084
-:10305000FFFFF4A9F83019CC71E100020012698277
-:10306000001071E1000200126882F7FF71E10002B6
-:1030700000126882FBFF71E1000200126882FFF01B
-:1030800071E1000300127682FFFF71E1000400127B
-:103090007682FFFF71E1000200126982002071E177
-:1030A00000020011F27319DA6881FFEF7711007BDB
-:1030B0001081FB801997F00000B47711007B10811C
-:1030C000FB801997F00000B9F980169AEE018A1179
-:1030D000F4E400A4000019DF00012AE6000000016A
-:1030E0002AE7000000032A120C01C34F0000000170
-:1030F0002A15000000022A160000000000192A5DAF
-:103100000043006F0070007900720069006700687A
-:10311000007400200054006500630068006E006FBA
-:10312000005400720065006E0064002000410047FA
-:10313000000000042A760030002E00300000000C51
-:103140002A7A004600650062002000320037002025
-:103150000032003000300031000000092A860031C2
-:103160000034003A00330035003A003300330000E9
-:10317000000F2A8F00000000000000010000000185
-:10318000000000000000000000000000000000003F
-:10319000000000012A9E000000012A9F000000019B
-:1031A0002AA0000000012AA1000000012AA20000BC
-:1031B0000001297E000000022980000000000001BB
-:1031C0002982FFFF00012AA7000000052AA87141FB
-:1031D0002000200000230400000A2AAD00000000A7
-:1031E00000000000000000000000000000000000DF
-:1031F000000F2AB7000000000000004000A082403D
-:103200000008307F00800180000000000000000006
-:1032100000000001276E00000001276F0000000081
-:10322000000900001A8304E804CF04C504BA04B0FE
-:1032300004AC049C048C0481007800000100F2734B
-:1032400007EFF495F495F27307EFF495F495F273A4
-:1032500007EFF495F495F27307EFF495F495F27394
-:1032600007EFF495F495F27307EFF495F495F27384
-:1032700007EFF495F495F27307EFF495F495F27374
-:1032800007EFF495F495F27307EFF495F495F27364
-:1032900007EFF495F495F27307EFF495F495F27354
-:1032A00007EFF495F495F27307EFF495F495F27344
-:1032B00007EFF495F495F27307EFF495F495F27334
-:1032C00007AAF495F495F27307EFF495F495F27369
-:1032D00007EFF495F495F2730223F495F495F273E5
-:1032E00007EFF495F495F27307EFF495F495F27304
-:1032F00007EFF495F495F27307EFF495F495F273F4
-:1033000007EFF495F495F27307EFF495F495F273E3
-:1033100005E5F495F495F27302B5F495F495F2731E
-:103320000E33F495F495F27307EFF495F4950000DD
-:00000001FF
--- zfcpdump-kernel-4.4.orig/firmware/vicam/firmware.H16
+++ /dev/null
@@ -1,7 +0,0 @@
-:0026000000B6C31F000264E767FDFF0EC0E709DE008E00C0094003C01744034BAFC00700004BAF97CF00001D
-:000A000000B6C30300036418000000FB
-:0008000000B6C301000664000014
-:0696000000B6C38F060264E707000008C0E70700003EC0E7075401AA00E707C805B600E7074201D200E7077C001600E70756001800E707060092C0E70700001EC0E707FFFF22C0E707040024C0E707EC2728C0E70716018E00E78701000EC097CFD70900C0E777010092C009C1E709FE052401E70904062601E707070092C0E70500C0C0DF97CF170057001702D70900C0E777010092C00AC1E757FFFFFA050DC0E7570000FA050FC09FAFC600E70500C0C805C105C005C0DF97CF27DAFA05EF0701000B0673CF9FAF78019FAF1A036ECFE709FC052401E70902062601E707070092C0E709FC05FE05E70902060406E7090006FC05E709FE05000627DAFA05E7570100FA0502CA04C097CF9FAF660597CFE70740000206C809FC059FAFDA0297CFCF170200EF57810009069FA0B601EF57800009069FA04002EF5701000B069FA04603E70701000AC046AF47AF9FAF4002E7072E000AC0EF878000090697CF000E0100C05751009FC09E02C057500020C0C057550012C0C05756009FC072029FCFD602C10B080601D06F900806C0070800C10B08069FAF280597CF2F0E02000806C0070800C10B08069FAF28059FCFD6022F0E02000906EF87800009069FCFD602EF677FFF0906E767FFFD22C0E767EFFF24C0E787100028C09FAFB805E787E02124C09FAFA805E787080024C0E767DFFF24C0C8070A00C0070000C10701009FAF28059FAFB805C0079E009FAF4405E767FFFE24C0C00920C0E787000124C0C07700020FC1E767F7FF24C0E767F7FF24C0E787080024C008DA5EC1EF078000090697CFEF0701000A0697CFEF0700000B06EF0700000A06EF677FFF0906EF0700000D06E767EFFF28C0E76717D824C0E70700001EC0E707FFFF22C097CFC8070E069FAFDA02E7070000F205E7071000F605E7070E06F405E707D602F805C807F205C107008050AF97CF2F0C020007062F0C04000606E7070000F205E7071000F605E707E205F405E707CE02F805C807F205C107008051AF97CF9FAF66049FAF1A0359AF97CFC0070E00C10B0C0641D19FAF2805C0073C009FAF44056800C0073B009FAF44056F000C066800E0070401E80B0A06E8070000E0070002E007EC01E007FCFF97CFE707FFFFFA05EF0700000B06E7070E062401E7070E06FE05E70740002601E70740000406E707070092C097CFEF0702000B069FAF7801EF77800007069FC01404EF770100070637C0EF7701000D060FC1EF0701000D06C0070200C10730009FAF2805C0070100C10702009FAF2805C807FF4F9FAFA805C00738009FAF4405C177030002C108DA75C1C17701000AC1C0070100C10702009FAF2805EF07010006062CCFC0070100C10704009FAF2805EF070000060622CFEF0700000D06EF57010006061BC0C0070100C10701009FAF2805C0070200C10730009FAF2805C807FF4F9FAFA805C00738009FAF4405C1670300C157030002C008DA73C1C0070200C1071200EF570000060602C0C10723009FAF2805C0071400C10BEA059FAF2805C0073E009FAF0A05E709E405FA0527D8FA05E7070E06FC05E7074E060006E707400002069FAF66059FAFC60097CFC10BE20541D001D2C11723009FAFDC04C0070400C10BE3059FAF2805C0070600C109E6059FAF2805C0070700C109E605C1D19FAF2805C0070B00C109E8059FAF2805C0070C00C109E805C1D19FAF2805C0070D00C10709009FAF2805C0070300C10732009FAF2805C0070F00C10700009FAF280597CFE767FFD924C0C8070A004000C0670002278024C0E787000424C0E767FFF924C001D208DA72C1E787002024C097CF27001EC0E787FF0022C0E7677FFF24C0E787800024C0E787800024C097CF9FAF0A0567001EC0E767BFFF24C0E787400024C0E787400024C097CF9FAF0A05E76700FF22C0E767FFFE24C0E767FFFE24C0C10920C0E787000124C097CFC0074000C809FC05E76700FF22C0E767FFFE24C0E767BFFF24C0E767BFFF24C000DAE80920C0E787400024C0E787400024C000DAE80920C06DC1E787000124C097CFE707320012C0E777008012C07CC097CFE707204E12C0E777008012C07CC097CF0902190001010080960904000001000000000705810240000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A1
-:0136000000B6C32F0103640E0014001A00200026004A0064006A0092009A00A000B200B800BE00C200C800CE00DC00DA00E200E000E800E600EE00EC00F200F80002010A010E0112011E01220128012C0132013601440150015E01720176017A01800188018C0194019C01A001A401AA01B001B401BA01D001DA01F601FA01020234023C0244024A0250025602740278027E0284028A02880290028E029402A202A802AE02B402BA02B802C002BE02C402D002D402E002E602EE02F802FC0206031E032403280330032E033C034A034E03540358035E0366036E037A0386038E039603B203B803C603CC03D403DA03E803F403FC03040420042A04320436043E044404420448044E044C04540452045A045E046204680474047C04800488048C0494049A04A204A604AE04B404C004CC04D8042A0546056C0500005E
-:0008000000B6C301000664000014
-:0000000001FF
--- zfcpdump-kernel-4.4.orig/firmware/yam/1200.bin.ihex
+++ /dev/null
@@ -1,342 +0,0 @@
-:10000000FFF200A5ADFFFE9FFFEFF3CBFFDBFCF29D
-:10001000FFF6FF3CBFFDBFDF6E3F6FF17DB4FDBF5C
-:10002000DF6F3F6FF70BFFDBFDF2FFF6FFFFFFFF18
-:10003000F0CFFFFFFFFEFFFFDFFFFFFFEFFFFFFF40
-:10004000FDFFFFFFFEFFFFFFFFFFF1FFFFFFFFBF11
-:10005000FFFFF7FFFFFBFFFFFFFCFFFEFFFFFFF0CF
-:100060005FFFFFFFFEFFFFFFFFFFFFFFFFFFFFFF41
-:10007000FFFFFFFFFFF7FFFFFFF1FFFFFE7FBFFF67
-:10008000FFFFFFFFFFFFFFFFF7FFFBFFFFFFF09FFB
-:10009000FFFFFFFEFFFDFFFFFFFFDFFFFFFFF7FF9B
-:1000A000FFFFFBFFFBFFFFFFF0FFFFFFFFFFFFFF77
-:1000B000F7FFFFFBFFFFFFFEFFFFFFEFFFF05FFF1C
-:1000C000FFFFFEFFFFEFFFFFFBFFFFFFFFFFFFFF55
-:1000D000FFBFFFFFDFF7FFF1FFFFFFFFFFFFFFFFA6
-:1000E000FFFFFFFFFFFBFEFFFFFFFFFFF0FFFFFF34
-:1000F000FFFEFFFFFFFFFFFFFFFFFFFFFFFFFFEB25
-:10010000FFFFFFFDFFBFF1FFFFFFFFDFFFFFFFFB73
-:10011000FFFFFFFFFFFFFFFFFFFFFFF06FFFFFFF8E
-:10012000FEFFFFFFFFFFFFFFFFFFDFFFFFFFFFFF00
-:10013000FFFFF7FFFFF1FFFFF7BFE7FFFFFFFFFB49
-:10014000FFFFFFFFFFFF77FFFFFFF0FFFFFFFFFE57
-:10015000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF
-:10016000FFFFFFFFF1FFFFFFFFFFFFFFFFFFFFFFAD
-:10017000FFFFFFFFFFFFFFFFFFF01FFFFFFFFEDBA3
-:10018000FFFFF5A5FD4B6EEF3332DDD34AD692FE6D
-:10019000B33FBDF1FADBFEF7F696BDBDFFBDFFED47
-:1001A0007F6B7FFBDFFEFBFE90CFFFFFFFFEBEEF0E
-:1001B000FFFFDB5FF6FFF68FFDA5DDFFFFFFFF6FA3
-:1001C0007FDBF1FCBFFF6FFFEFFC5B5DDADFF4FF6D
-:1001D000F2FFFDBFFFFFFFD01FFFFFFFFEFFFFFF8E
-:1001E000FFFBEFB7FC33FFFBFF046AF33C36FFF085
-:1001F0000FF10FFFFFFFF315720FF16FFFFE943F3A
-:10020000FFFFFF7BFFFFF0FFFFFFFFFEFFFFFFF0A1
-:10021000F7EFB7FC33FFFFFF046AF33C36FFF00F44
-:10022000F10FFFFFFFF315738FF26FFFFE943FFF97
-:10023000FFFF7D9FFFF00FFFFFFFFEFFFFFFFF9E11
-:10024000FFFCEFD3FBFF7FF55FFE59FFFFFFFCF1E3
-:10025000FE7FFFFFFA17FFE7EFEFFFFF3FF1FFFF22
-:10026000FFFFFFFFF0FFFFFFFFFEF5FFBFFFFCEA10
-:10027000FFF0FFFFBFF93FB1EFFFD7FFFBFFF0FF3C
-:10028000FFF3FFDFFF7BFFFDFFF6FFBFFFFFBFFFB9
-:10029000FFFFDAF0FFFFFFFFFEF2C00100000202E5
-:1002A0000202004040401000000020000001000059
-:1002B000000000001900040400000000000000100D
-:1002C000003CF0AFFFFFFFFEFDBFFFFFFBFFFDFFA8
-:1002D000FF7FFFFFBFFFEFFFFFFDFFFFF1FFDFFF2E
-:1002E000FFFFFFFFFFBFFEFFFFFEFFFFFFFFFFDF80
-:1002F000DBF06FFFFFFFFEF0BFDFFF7FFFFFFFFFC1
-:10030000DFDFFFEFFF9EEFFFFF7FFFF1EFFFFFFF5C
-:10031000F7FABFFFFFFE47EFFFBDF6FFFFDFF5F087
-:10032000F0EFFFFFFFFEF8300000000400010208BC
-:1003300016000000800001020080010C0200000194
-:100340000000200000060020001000140004C1F08E
-:100350002FFFFFFFFEFFFFFFFFFFFFFFFBFFFF7F02
-:10036000ECFFFFFAFFBFFF6FFFE1FFFFFFFFBDFEE6
-:1003700046FFEF7FCDDFFFFFFDFFBDFF7F7FF04F2B
-:10038000FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFF7E
-:10039000FFFFFFFFFFFFFFFFF1FFFFFFFFFFFFFF7B
-:1003A000FFFFFFFFFFFFFFFFFFFFFFFFFFF00FFF5C
-:1003B000FFFFFEFFFFFFFDA4BCCD6D6B6F5BDC3369
-:1003C0005AF6F7F6B33FBDC1FA5AF6F6B6F7FFBDD7
-:1003D000BB3CCECF34EF33BBCCFFFFFFF04FFFFF72
-:1003E000FFFEBFFFFFFFDBFFF6D6FFFDFDBFFFAD4A
-:1003F000BFF97F6FFCDBF1FDBFFF6FFFFFDADBFCB6
-:10040000DBFF768FF6FFCDABFEFBFFD0FFFFFFFFDC
-:10041000FEFF9FFFF420AF6D0BC17BFFFFFFCBFF03
-:100420003FF0EF7F0FF1C33CFFFFFFFFFFFFF80B33
-:100430001D6A64056B9901FFFDEFF02FFFFFFFFEC2
-:10044000FFFFFFF4002FCC0BC37FFFFFFF0ADFBFCE
-:10045000FD7FFFFFF1C3BFFFFFFFFFFFFFF04A0E6D
-:10046000966402979910FFFFFFF0DFFFFFFFFEFF8A
-:10047000FFFFFE84F9D527F17FFFF8EBDFF3CF3FD5
-:100480001FFFF711FFCFFFFE67FFFFFFFFC4FFFF56
-:10049000B3A1FFF9E0FFFFFFF0EFFFFFFFFEF5FF65
-:1004A000FFFB7FE0FFC7FE7F3FFFFD778D7F0FFFE4
-:1004B000C3FFF1BF8FCFFFFFDD7BFFF6FAF7FF40F1
-:1004C0009FF97FD8FFFFFAF01FFFFFFFFEF1C0008A
-:1004D00000030000000000000000400010000010B9
-:1004E00000010010202000001000040105000000A1
-:1004F00000404000003CF01FFFFFFFFEFDBFFFFF7C
-:10050000FFFFFE7F7FFFEFFFFFDFFFFFDFFFEFF764
-:10051000F1FFFFFFFFDFFFFFF7FFFFFFFCFDFF7FA6
-:100520007EFFFFFFDBF06FFFFFFFFEF0BBFFFFFF73
-:10053000FFFFFEEBFD6FFFF7FEF57FFFFF7FBFB113
-:10054000FFFF9FBFFBFFFEFFFEFFF7EBDFBF5FDD9F
-:10055000FFDBFDD0F06FFFFFFFFEF8302000420010
-:100560000000301804080921828002000800010000
-:1005700000000C2010001100448400202084800022
-:100580000000C1F0DFFFFFFFFEFFF7FFFBDDF9FF1B
-:10059000DAFFDCDDFCFBFFBFFB3ED796FE61F7FF19
-:1005A0007FFF3FFDFFDFCFF7DFF7BFFDFFFEEFEF80
-:1005B000FEFFF07FFFFFFFFEFFFFFFFFFFFFFFFFDC
-:1005C000FFFFFFFFFFFFFFFFFFFFFFFFF1FFFFFF49
-:1005D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2B
-:1005E000FFF02FFFFFFFFEFFFFFFF3BDFD4B74CFBA
-:1005F000735BCB3BDFFEF7FED375ACA1FBDFFEF7F1
-:100600007696B524BDA5AD492F692B525BBDFFFF82
-:10061000F0CFFFFFFFFEBFFFFFFFDBFFF6FEFFCCCB
-:10062000A7FBADFF7F6FFF6D7FDBF1FDBFFF6FFFAE
-:100630006FFFDBFFDBFFF697F6FFB5B5FFFFFFD0DF
-:10064000EFFFFFFFFEFFFFFFFDA5BC43FC7C03E7C0
-:10065000FFFF20FFFFFFCCFD7DF1FFFFFFFFD5591E
-:10066000BA56666AAD9AA99A97A5AABBFFFFF00F82
-:10067000FFFFFFFEFEFBFFFDF7FD43FFFD6BE7FF06
-:10068000FFDFFFFFFFFFFF3FF1FFFFFFFFD559B582
-:10069000A6666AAD9AA9996B5AAAFFFFB7F03FFF09
-:1006A000FFFFFEFFFFFFFE9CF7FDD241FFFFF27F41
-:1006B0008FFFFF3DF3FF17F1FFFFFFFFFF7FDFFC21
-:1006C0008F38FFEF23FFFBF7C8FFFFFFF09FFFFF0F
-:1006D000FFFEF57FFFFDFFE4FFEBFFCFBFFAFFABAF
-:1006E000EFFFFBFFF3FD61FFFFFFFFFAFFFBFD0DD7
-:1006F000FFFEFF437FFEBFD0FDFFFAF03FFFFFFF8D
-:10070000FEF3C0000000020002010060C0400000D3
-:100710000000340400010000000000000008880010
-:100720000003000040004000003CF03FFFFFFFFEE0
-:10073000FD3FFFFFFFFFFFFF7F7FBFFFFFFFFFFFCB
-:10074000FFFFFFF7F1FFFFFFFFFFF7FFFFFFFDFFD9
-:10075000FFFFFFFEFE5FFFFFCBF0DFFFFFFFFEF0BE
-:10076000FFFFFDFFEFE3DEEED9C593FFFFFEFEFFC7
-:10077000FBEEFEF1FFFFFFFFFFFDFFBFF7FFFF7F77
-:10078000AFBDDFDFFBF3F3F0F0AFFFFFFFFEF834A8
-:10079000000661001801A0051700200528200000B0
-:1007A0000500410000400009000120868208400346
-:1007B000803070081402C1F0CFFFFFFFFEFFFFFF83
-:1007C000FFFFBDEFFBFFFFFB9C7FEFDFFFBFEBDE1B
-:1007D000FFC17FFFFB7FFFFFFF5FFFFFFFDFBFEF7B
-:1007E0003FF78FEF7FFFF07FFFFFFFFEFFFFFFFF71
-:1007F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF09
-:10080000F1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF06
-:10081000FFFFFFFFFFF03FFFFFFFFEFFFFFFFFBDFA
-:10082000DFEF7D6D2B5A5DD2DFF692B6B2B3ACA18D
-:10083000FBDFFEF1EEF5F6BC6BBD7DAF1AEF5F6B33
-:10084000C6FFFFFFF05FFFFFFFFEBFFFFFFFDBFF05
-:10085000F6FFF6B7FDADFDBFF36FFF6FFFDBD1FD18
-:10086000BFFF6FF56BBC5B3CDAEF16AF16FFCDAB8D
-:10087000FF6FFFD0FFFFFFFFFEFFFFFFFCBFFFFF8B
-:10088000FF6C0310C1F3FFF33AF3CAFFAFF1FFFFB0
-:10089000FFFFD996A665A6666A9569696A5A5AFFE6
-:1008A000FF5FF01FFFFFFFFEFFFFFFFFBFFFFFFF28
-:1008B000EA0F50C3F37FFFF3F3C3FFAFF1FFFFFF76
-:1008C000FFD996A665A6666A9569696A5A5AFFFFB6
-:1008D000FFF03FFFFFFFFEFFFFFFFFD7FFFF5FC1FE
-:1008E0003FF75EF5CE9E5F3F17FFF3E1FFFFFFFF8F
-:1008F000D8FFFAFE67FFFEBF5AFFFFAFF5FFFFFF0D
-:10090000F02FFFFFFFFEF5FFFFFDFFF7FFFD4E3D60
-:100910003FE70BBF8FF9FFEBE3FFE1FFFFFCFFC7F2
-:100920009FFF3E39E5FFCF9BF9FFFFC5FFFFFAF0C0
-:100930005FFFFFFFFEF3C00000000000000040006A
-:100940000000006000000000000100000020002006
-:10095000000110080000000000000000003CF04F03
-:10096000FFFFFFFEFDBFFFFFFFFFFFFFFEFFFFBF1B
-:100970003FFFFFBFFFFFFFFBF1FFFFFFFFF7FFF7A9
-:10098000FFEDFFFBFEFF7FFF7FDFFFFFDDF03FFF9F
-:10099000FFFFFEF0FFFFF3FFF7FFFE5FFFF7FFFF34
-:1009A000DFFFFFFFF7FE7BF1FFFDFDFFDFDFFF7DD8
-:1009B00073F9FFC37EFEFFEFD7FFCFD0F06FFFFFCD
-:1009C000FFFEF83000004004000141200004000256
-:1009D000D50900028002010000000A04000700019E
-:1009E000500180026140410C1408C1F09FFFFFFFDD
-:1009F000FEFFFFFFFEFFFFFFFEDFCB5FFEEFFFFE10
-:100A0000FF3FFF7FFDC1FFFF7FFFDFFDFCFDF7EE36
-:100A1000FFFF4EFFDFCFDBEBFFFFF01FFFFFFFFE0F
-:100A2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6
-:100A3000FFFFFFFFF1FFFFFFFFFFFFFFFFFFFFFFD4
-:100A4000FFFFFFFFFFFFFFFFFFF02FFFFFFFFE7F16
-:100A5000FFFFFFFDFFFFFFFFFFFFFFFFDFFFFFFFC8
-:100A6000F7FBFFF1FFFFFFFFFFFFFFFFFFFFFFFFB0
-:100A7000FFFF7FFFFFFF7FFFF01FFFFFFFFEDDFF98
-:100A8000FFFFA5FF6F6BE96FDACAFBDDEEF7F6B289
-:100A9000B3A4A15B5BF6D7F4F77BBDBDADCFEF7F11
-:100AA0006B7F3BDFDBFFFF30CFFFFFFFFEBFFFFFB2
-:100AB000FFFFFFF6FE96FFFDB5FDBFAD7FFF6FFFA9
-:100AC000DED1ADADE9FFF1ECEFDE3FCBFFF6FF325B
-:100AD000FFC5BDFFFFFFD0BFFFFFFFFEFEFBFFF422
-:100AE00028BFFFFDFBD3FFFF42FFFFFFEAB3FCC3BC
-:100AF000C1FF33FFC0156B70FFF0F24FFFFC3E9754
-:100B00003CFFFFFDEFF0BFFFFFFFFEFFFFFFFE78A2
-:100B1000BFFFFDF3EF55FF7EFFFFFFEAB3FCC3C14C
-:100B2000FF33FFC0156FFF0FF0F00FFFFC3D6BC3ED
-:100B3000FFFFFEF7F0CFFFFFFFFEFFFFFFFFFCFF11
-:100B4000FF23F87FFF4EFFFFFFFBF917FFF6F1FFD2
-:100B5000CFEFFFFF13DFE62FC7FFFFE7C1FDFFFE6B
-:100B6000FFFFFFF04FFFFFFFFEF5FFFFFFFEAEFFB1
-:100B7000FF7F3B3FFC7FFCEFFFFCE27BFFF1FDEDE5
-:100B8000EFFFFF3573FFFFFEFAFFFFFFFEBFFFFF22
-:100B9000FFFAF08FFFFFFFFEF1C000000000000031
-:100BA000000000800000400000000C0401404000F4
-:100BB00000302804000800000001000100000000CF
-:100BC00038F00FFFFFFFFEFDBFFFFFFFFFFBFF7FC2
-:100BD000FFFF9FFFFFFFFFFFFFFFFFF1FFDFDFFFD3
-:100BE000FFFFFFEDFFFDFFFFFFFFFFBFBFFFFFC3E5
-:100BF000F03FFFFFFFFEF0BFFDFFBFFFFFFDFFFF68
-:100C0000FFFFFFFD7BFF7FFFBDFFF1EFFFFFFDDF7C
-:100C1000FDFBFFFFBFBEFFCD7FFCF7F76FBFD8F036
-:100C2000EFFFFFFFFEF830000000040000A000000E
-:100C3000C0000020340000000C810020A42000101F
-:100C400008044808004093001000381820C1F03F05
-:100C5000FFFFFFFEFFFBFFFFB9DFFEB3FFFFE7FD76
-:100C6000FFFF3BFF7FFFBFFFC1FFFCFFFF3F77FEA2
-:100C7000FECFFFBFFDBFFFFEEDF2FDF7FFF02FFF40
-:100C8000FFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFF75
-:100C9000FFFFFFFFFFFFFFF1FFFFFFFFFFFFFFFF72
-:100CA000FFFFFFFFFFFFFFFFFFFFFFFFF0BFFFFFA3
-:100CB000FFFEFFFFFFF3ADCFEF70C9733BDF5B4A71
-:100CC000F6B7FED7F5BCC133CAD6B76EF7FBBDC5C4
-:100CD00024CF6F2F4D2BBA5AFFFFFFF0AFFFFFFF5E
-:100CE000FEBFFFFFFFFFF6F6D7FFFFADBDFFFFFF23
-:100CF000EFF77FFC5BB1FDBD756FEF6AFD5BFBDB62
-:100D00003ABF8E9FFFBFFDFF6FFFD06FFFFFFFFE5B
-:100D1000FFBBFFF03FFFFFFDFB7FDEFFFF5AD6BFAB
-:100D2000D82ABFBFF1E5FFCCC0A970FFF33C3CFD62
-:100D300057FD980300C3FFFFFFF0AFFFFFFFFEFF6B
-:100D4000FFFFFF3DBFFFFDFBFFDBFFFF0FFC3FD8B9
-:100D50002ABFBFF1EFFFCCC096BEFFF33FFFFD57A8
-:100D6000FD990FFFC3FFFFFFF04FFFFFFFFEFFFFE7
-:100D7000FFF1E7FFFFF38E7BFFA8FFDF7F8E787325
-:100D8000FFF15162FFFC4BFFF3FF7ECFF9FFFDFF48
-:100D9000FF7FFFE0FFFFFFF04FFFFFFFFEF5FFFFCC
-:100DA000FBFDAEFFFCFE6F3FF8FD77AFFE37FE7B2D
-:100DB000FFB18CFFEFFDF8E7BFFFF1FE3EF7FE95B8
-:100DC0003EBFFFFFFFFAF0BFFFFFFFFEF1C00000D4
-:100DD0000104000000008002000010001000100854
-:100DE0004180100000081084000C040261000081A2
-:100DF000000000003DF07FFFFFFFFEFDBFFFFFFF93
-:100E0000FFFF7FFFFEFDBFFFFFFFFFFFFFFFFFF1C3
-:100E10007FBFF77FEFFFEFFFF7FDFFFFFD7FFFBE17
-:100E2000DFFFFFD9F0BFFFFFFFFEF0BBFF7FFBFF3F
-:100E3000FBFFBFFFF37FFBFDEB7FDFFAFFDEF0ED93
-:100E4000FFB1F7F91FB55BFE7EF7BEFD7F5FB5F71B
-:100E5000FFFFD0F04FFFFFFFFEF830010007420117
-:100E6000006A185080000002400101200101241492
-:100E700021100208070800401080580084801810D4
-:100E800040C1F0BFFFFFFFFEFFFFFFF7FFDBB7F33F
-:100E9000DF7CF874FFFF6F7D3F7EEC7FC1F5FFCFF5
-:100EA0006F9FF9DFBEE5E7FFD7F3DDFBFFFCFFBF78
-:100EB000FFF0FFFFFFFFFEFFFFFFFFFFFFFFFFFF52
-:100EC000FFFFFFFFFFFFFFFFFFFFFFF1FFFFFFFF40
-:100ED000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22
-:100EE000F02FFFFFFFFED7FFFFFFB4CFEF776F7349
-:100EF0003A4A3ACBD4F72ED6BDBDA13BDFD6F7EEAA
-:100F0000D335BDFBBDCEEB2B4D2FBBDAFFFFFEB0C3
-:100F10005FFFFFFFFEBFFFFFFFDF5F36AF3FEDB7B5
-:100F2000F5FDF32BEF77FFFBDAB1BDA377697F4FB8
-:100F3000FFDBFA5BFFF2FEFF96FFFFFEDFFFD0AFA5
-:100F4000FFFFFFFEFFFFFFFD8FFD406F9E835A0FE7
-:100F5000FAC3FFFFFCE97FF301D000FEBFCD3FF0F5
-:100F6000EFFCC50C3FFD680BFFFFFFFEDFF0FFFF4E
-:100F7000FFFFFEFFBBFFFD85FFD46F9FC35A0FFF2E
-:100F8000FFFFFFFCE97FF301F0FBC2BFFC0037EF7E
-:100F9000FCCDBC3FFF0CBFFFFFFFFFFFF05FFFFF7B
-:100FA000FFFEFFFFFFFFD9F7D1B77E7FF1E4FDFF22
-:100FB000FBFBFF5FFF7FB1BC0F67EBB83FFFE2FFBA
-:100FC000E9FFFDE3FF3F9FC2FFFFFFF09FFFFFFF31
-:100FD000FEF57FFFF03FBCFFD5F5CE3FFEFFFE6D77
-:100FE000FFF1BF7BFFF1FDFF4FFF87FFAEFFB1F8C1
-:100FF000FEFFFF7801B9FFFFFFFAF02FFFFFFFFEB2
-:10100000F3C00000000402130200804000901000B2
-:1010100010000200012080121000400800040000AF
-:1010200002000140008000003CF0EFFFFFFFFEFDEA
-:101030001FFFFFFF7FFFFFFFFF7FFF7FF7DFF7FF50
-:10104000F7FBEBD1FFFFFFFFEFF7FFFFFBFFFEFF1B
-:10105000FF7EFFFBFFFFFFDBF0FFFFFFFFFEF0FF68
-:10106000FFB7EBF7DFFFFEF56BE7EDF73EECFF5464
-:10107000EF6FF1F5AF6FF6FDFFDD7BFFEFBF7FFF99
-:10108000FFF7FFF35FF7D0F0CFFFFFFFFEF8300070
-:1010900080400400812C0424000201C802000224C4
-:1010A0000001B442DC4402159002034839100224C6
-:1010B000A0BA000040C1F0BFFFFFFFFEFFFFFFFF2F
-:1010C000FEFCF7F0EEB65DFDF5FFDBF77F7FBEFFC0
-:1010D000C1FEBFFAFA5FFFADFFEFFF7FDF7FFEBF0C
-:1010E000B794BFFFFFF09FFFFFFFFEFFFFFFFFFF73
-:1010F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10E
-:10110000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF
-:10111000FFFFFFFFF08FFFFFFFFED7FFFFFBB5FFD5
-:10112000EF7CEB2B525B3BDAD4F33696B5BDF1FB8B
-:10113000DAEEF6FED335BDDFADCFEF7ECD6BBBDF94
-:10114000FFFFFDB0EFFFFFFFFEBFFFFFFFD35FF626
-:10115000FFF6FFFDADFDFF7FEFFF6F7FDBF1A5A386
-:101160007F6F6B4FFFDBFBCBFFF6FFF4D7FDBFFEBE
-:10117000DFFFD0CFFFFFFFFEFFFFFFF7DFFFFFFF27
-:101180003F7FFCE5FF20FEFFFFDF7FFFF17FFFFEDB
-:10119000FFF07C3D4FF3C33FFFFF6FC3FF0FFFFF27
-:1011A000AFF02FFFFFFFFEFFFFFBB7E00FFFFF2BAE
-:1011B000FF7DBFFFDFFFFFF89F7FFFF155FFFFFFC0
-:1011C000FD7C3CFFF3C33FFFFFEFC3FFDFFFFFFFEB
-:1011D000F09FFFFFFFFEFFFFFFFFEFFFFF9FBF7FBF
-:1011E000F919478EE79F3F17FFFC81C17EF3D9F9BC
-:1011F00073DFF47FFAFFFFFFFB7F77C7FFFFFFF08E
-:101200002FFFFFFFFEF5F7FFFBFFF73FFCBF3E3F61
-:10121000ECFF81AFFE4FF3BBFFF07EFF6FFF87FF58
-:10122000BBFFD5FCFF7FFC6FFFEFE7FFFFFAF03F4E
-:10123000FFFFFFFEF3C00000000000000000008080
-:101240000030106020000800012080001000040021
-:101250000000000000020080400008203CF06FFF0A
-:10126000FFFFFEF5BFFFFFFEFFFFFFFF7FFE3FFF1B
-:10127000FFFFFFFFEFFFFFF1DFDFFFFFFF7FDFFF7C
-:10128000FDBDFFFFFFFBDFFFFFFFFF5BF0FFFFFF89
-:10129000FFFEF0BFBFBFFFF7FBFFFEEEFAFFFFFF51
-:1012A0003D3BFFFFFEFBF1FFBF7BFFFFEFFFBFFFFB
-:1012B000FFFFFFFFFEFFF7EFFFFBD0F0DFFFFFFFB9
-:1012C000FEF83000000000000B10050100080002CD
-:1012D000010100001001C8080000000042020000E7
-:1012E000008002000040248000C1F03FFFFFFFFEAD
-:1012F000FFFFFFFFF7FDF7FAEFEEF9FDFFF7FEBF87
-:101300001FFD9EFDD1EFFFF77F9FFFEFFFF6FFFE72
-:10131000FE7BFFBDFF7EFFFFFFF03FFFFFFFFEFFF5
-:10132000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD
-:10133000FFFFFFF1FFFFFFFFFFFFFFFFFFFFFFFFCB
-:10134000FFFFFFFFFFFFFFFFF0AFFFFFFFFEFFFF0D
-:10135000FFF7FFFFFFFF7FFFFFFFDFFDFFFFDFFF67
-:10136000FF5FF1BFFFFFFFFFFFFFFFFFFFFFFFFF7B
-:10137000FFFFFFFFFFFFFFF0DFFFFFFFFEFFEFFFBD
-:10138000F7FFFFFFFFFFFFFFFF3FFBFFFFEFFBFD4F
-:10139000FFF1FFFFFBFFFFFFFFFFFFFFFFFFFFFF6F
-:1013A000FFFFFFFFFFFFF02FFFFFFFFEF7FFFFFF35
-:1013B000FFFFFFFFFDFFFFFFFFFFFF7FFFFFE7FFD7
-:1013C000F1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3B
-:1013D000FFFFFFFFFFF0FFFFFFFFFEFFFFFFFFFF2D
-:1013E000FFFFFFFFFFFFFFFFFFFFCFFFFBFFFBF153
-:1013F000FFFFFBFFFFFFFFFFFFFFFFFFFFFFFFFF01
-:10140000FFFFFFFFF02FFFFFFFFEFFFFFFFFFFFFCC
-:10141000FFFFFFFFFFFFFFFF7BFFFFFF7FFFF1FFEE
-:10142000FFFFDFFFFFFFFFFFFFFFFFFFFFFFFFFFEC
-:10143000FFFFFFF07FFFFFFFFEFFFFFFEFFFFFFF5C
-:10144000FFFFFFFFFFFFFFDF57FFFEBFFBF1FFFFC7
-:10145000FDF7FFFFFFFFFFFFFFFFFFFFFFFFFFFFA6
-:10146000D7FFF07FFFFFFFFEFFFFFFF7DBFFDBFD96
-:10147000F6FFF6FF3CBCBCBFDF6FEF2FF13CBFBCFB
-:10148000BFDF6FFF6FF7DBFFDBFDF6FFF6FFFFFF50
-:1014900001E2EFFFFFFFFEFFFFFFFFFFFFFFFFFF88
-:1014A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4C
-:0614B000FFFFFFFFFFFF3C
-:00000001FF
-/*
- *
- * File yam1k2b5.mcs converted to h format by mcs2h
- *
- * (C) F6FBB 1998
- *
- * Tue Aug 25 20:24:08 1998
- *
- */
--- zfcpdump-kernel-4.4.orig/firmware/yam/9600.bin.ihex
+++ /dev/null
@@ -1,342 +0,0 @@
-:10000000FFF200A5ADFFFE9FFFEFFBCBFFDBFEF293
-:10001000FFF6FF9CBFFDBFEF2E3F6FF1FDB4FDBFAC
-:10002000FF6FFF6FFF0BFFDBFFF2FFF6FFFFFFFF2E
-:10003000F06FFFFFFFFEFFFDDFFFFFFFF7FFFFFF9A
-:10004000FBFFFFF7FFFFFFFEFF7FF1FFFEFFBFBFDC
-:10005000FFFFFFFFFFF7FFFFFFFEFFFEFFFFFFF0C9
-:10006000EFFFFFFFFEFFFFFFFFFFFFBFFFFFFFF7F9
-:10007000FFFFF7EFFFFFFFFFFFF1FFFFFF7EFFFF37
-:10008000FFFFFFFFDFFFFFFFFFFFFDFFFFFFF0DFD1
-:10009000FFFFFFFEFFFFDFFFFFFFFFFFFFFFFFFF91
-:1000A000FFFFEFFFF3FBFEFFF1FFFDFFFFFFFFFF91
-:1000B000FFFFFFFFFFFFFFFEFFFFFFDFFFF07FFF00
-:1000C000FFFFFEFFFFEFFFFFFFFFFFFFFFFFFFFF51
-:1000D000FFFFDFFFFFFFF7F1FFFFFFDFFFFFFFFF86
-:1000E000FFFFFFFFFFFFFFFEFFFFFFFFF00FFFFF20
-:1000F000FFFEFFFFFFFFFFFFFFFFFFFFFFFF7FFF91
-:10010000FFFFFFFFFFFFF1FFFFFFFFFFFFFFFFF517
-:10011000FFFFFFFFFFFFFFFFFFFFFFF02FFFFFFFCE
-:10012000FEFFFFFFFFFFFFFBFFFFFFEFFF7FFFEF84
-:10013000FFEFFF7FEFF1FFEFFF7FFFFFFFFFFFFF0D
-:10014000FFFFFFFFFFFEFFFFFFFFF09FFFFFFFFE30
-:10015000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF
-:10016000FFFFFFFFF1FFFFFFFFFFFFFFFFFFFFFFAD
-:10017000FFFFFFFFFFFFFFFFFFF0BFFFFFFFFEFFDF
-:10018000FFFFFFBDFFEF7FEF7FFBDFD35AFED7D628
-:10019000F77FBDF1BB5DD6F7FE96FFBDAFADBFEFFC
-:1001A0007F6B7FFBD6FEF7FF10EFFFFFFFFEBEEF7A
-:1001B000FFFFDBFFF6FFF6FFFDBFFDBFFF7FFF7F09
-:1001C000DFDBF1FD35FF6FFF6FFFDBFFCBFFF6FFDE
-:1001D000F2FDFDBFFFFFFFD0EFFFFFFFFEFFFFFFC0
-:1001E000FFFFFFFFFFFFFFFFFFFF55FFCCC03FFFFB
-:1001F000FFF124F0FFFFCFEF3FFFF0FFFFFFFC3FD9
-:10020000FFFFFFFFFFFFF0CFFFFFFFFEFFFFFFFF3E
-:10021000FFFFFFFFFFFFFFFFFF55FFCCC03FFFFFCA
-:10022000F100F0FFFFCFDFFFFFF0FFFFFFFC3FFF1C
-:10023000FFFF7DFFFFF0FFFFFFFFFEFFFFFFFFFF60
-:10024000FFFFFFFFFFFFFFFFDFFE7FDFFFFFFFF18D
-:10025000FFCFFFF3FF97FFFF8FE7FFFFFC71FFFF6B
-:10026000FFFFFFFFF0EFFFFFFFFEF5FFBFFFFFFF08
-:10027000FFFFFFFFFFFFE3F7EFFFFFFC7BFFF13F17
-:10028000FFEFFFCFE3E3FFFFFFFF3FFFFFFFBFFFF6
-:10029000BFFFDAF07FFFFFFFFEF2C00000000000AA
-:1002A000000000000000000000000000000100004D
-:1002B000000000000000000100000200000000003B
-:1002C000013CF0AFFFFFFFFEFDBFFFFFFFFFFFFFA1
-:1002D000FFFFFFFFFFDBFFFFFFFFFFFFF1FF9FFFC0
-:1002E000FFFFF7FFEFFFFFFFFFFFFFFFFFFFFFFF36
-:1002F000DBF07FFFFFFFFEF0BBDFFFFFFFFFFFFF35
-:10030000FFFFFFFFFFFFFFEFFBDFBFF1FEFDF7FF8A
-:10031000FFFFFFFFFEFFFFFFFFFFFFFFFF77FDF285
-:10032000F01FFFFFFFFEF838000000000000000390
-:100330000000000200900000000C010000042400F6
-:100340004001000000400000000002000001C0F079
-:100350004FFFFFFFFEFFFFFFFFFFFFFFFFFFFFFF5E
-:10036000FFFFBFFFFF6FFFDFFFD1FFFEFFFFFFFFBC
-:10037000FFFFDFFFFBFFFBEFFFFFEEFFFF7FF0DF85
-:10038000FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFF7E
-:10039000FFFFFFFFFFFFFFFFF1FFFFFFFFFFFFFF7B
-:1003A000FFFFFFFFFFFFFFFFFFFFFFFFFFF08FFFDC
-:1003B000FFFFFEFFFFFFF5ADFF692AED6BFBDF3AA4
-:1003C000DCF496EEB33D35C1BBDDFEF6FED6B5AD31
-:1003D000BFA5AD492F4F2BDA5FFFFFFFF02FFFFFC7
-:1003E000FFFEBFFFFFFB5BF7F6FFF6FFFDBFFDA5BE
-:1003F000F36FF36EFA7BD1FDB5776FE96FFFDBFB2F
-:10040000DBDFF6FFF6FFFD3FFEF7FFD04FFFFFFFFC
-:10041000FEFF9FFFFF0FFFC03F9C03FFFF8BA5FE6A
-:10042000803EC2BFACB124FFFFFFFFFFFF0FFFA361
-:10043000FFFD6BFFFFF0A5FFFFFFF0AFFFFFFFFE2B
-:10044000FFFFFFFF0FFFC03FD46BFFFFDBFFFE8608
-:10045000BFC2BF30A124FFFFFFFFCCFF0FFFA3FFF0
-:10046000056BFFFFF0A5FFFFFFF07FFFFFFFFEFF23
-:10047000FFFFFBC7FFC4FFFF7FFFECFE7FDFD8B9A4
-:1004800047FC36C1DFFFFFF9FFF3FFF7FFFCFFFD7D
-:100490003FFFFFFF3FFFFFFFF07FFFFFFFFEF5FF86
-:1004A000FFFFFFFEFFFF7EBD3FFF2BFE2FF5A3FCEE
-:1004B0005BFE619F7FEFFFFFA7FBFFFFFAFEFF33AD
-:1004C000F1FFBFFFFFFFFAF07FFFFFFFFEF1C0006B
-:1004D0000000000000000000000000400030240484
-:1004E000000100804000080000000201010002003D
-:1004F00000000000013DF02FFFFFFFFEFDBDFFFDEE
-:10050000FFFFFFFFFFFBFFFF7FF6EFBFF7FF73EB80
-:10051000F1FFFFFFDFFFFFFFFFFFF9FFFDFEFFFF22
-:10052000FFFFFFFFD9F0DFFFFFFFFEF0BF7FFFFF00
-:10053000FF7FFFFFDEFFFFEFDDDE77F2FBEDE7F190
-:1005400073FDFDDFFF7DBEDFFFFBFFEFFFEFFFFF72
-:10055000FFFFFFD0F0BFFFFFFFFEF83020020022B8
-:1005600040C0000000080002410212002187810003
-:100570000080040B2801B000820040000000000051
-:100580000000C1F0DFFFFFFFFEFFFFFFFFFFFDFFE9
-:10059000F7FFFE7FED79FFDEEB7F74F7F7E1F9FF00
-:1005A000F65F7FFFFFFFD7DBEFFFBBFFFFFFCCFF57
-:1005B000FFFFF0CFFFFFFFFEFFFFFFFFFFFFFFFF8B
-:1005C000FFFFFFFFFFFFFFFFFFFFFFFFF1FFFFFF49
-:1005D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2B
-:1005E000FFF00FFFFFFFFEFFFFFFFD3DCD497F6FD7
-:1005F0002BBA5CD2DAF6F33EF7FFBDF1FADFFEF775
-:10060000CCF6BBA5B3ADBF6F7D6F6BDBDFBDFFFE6F
-:10061000B05FFFFFFFFEBFFFFFFBDB57F6FE9FD57E
-:10062000B7FFAFE53FFFFF6FFFDBF1FDBFFF6F6976
-:100630006CDFDADFCBFFF6FF76FDFDBFFFFFFFD0FB
-:100640003FFFFFFFFEFFFFFFFFFDBD0803894F5A7D
-:100650000FF0FFF8BFFFFFFFFFF15AFFFFFFFFF3AF
-:10066000FAA0F0F2BFFFFFFFFFFFFFFFFFFFF0FF69
-:10067000FFFFFFFEFFFFFFFFFCFD006BFFFF5A0FB8
-:10068000F0FFFFFFFFFFFFFFF15AFFFFFFFFB3F592
-:1006900050F0F0FFFFFFD7FFFFFFFFFFFFF07FFFEE
-:1006A000FFFFFEFFFFFFFDBCFFE4E771FFF9C4F4AD
-:1006B0007F7FCFFFFFFFFFF1FFFFFFFBF773BF144B
-:1006C000FFE6FFFFE17DFFFFE7FFFFFFF03FFFFFDA
-:1006D000FFFEF5FFFFFED2FAFFC4F45CBFFAFFFF96
-:1006E000EC7EBFFFFFFFF1FFFFEFFFFF6BDBFFDFE4
-:1006F000F9FBBFFFF1FFBFFFFFFFFBF0BFFFFFFFF5
-:10070000FEF3C00002000000008200000000800034
-:10071000000000400001000000010820000000006F
-:100720000100010000800200013CF05FFFFFFFFEBE
-:10073000FDBFFFFFFFDFFFFFFFFF7FFFDFFFEFFFDB
-:10074000FFFFFFFFF1FFFFFFFFFFF7FFFBFFFDFFD5
-:10075000FFFFFFFFFFFDFFFFC3F0AFFFFFFFFEF056
-:10076000FFDFFFFFF723FFFFFDFFEFFFFE7F7DF7BA
-:10077000FEFF7F71FFFB7FFFFFFF6EFDF7FDFFBFF9
-:10078000FFBFF9FDFFDFEFF0F0AFFFFFFFFEF83036
-:10079000400100830000000C060804262600000625
-:1007A0000300010000000004007008800020012008
-:1007B000000200300000C1F05FFFFFFFFEFFFFFFFF
-:1007C000FFFF7B3FF7FFD7FEFEFBFE3BFEBDFF2F8B
-:1007D000FF71FFFB7FE7FFF9EFFFD7FAFFB7BBFE23
-:1007E000FFFF74FFF7FFF0CFFFFFFFFEFFFFFFFFEC
-:1007F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF09
-:10080000F1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF06
-:10081000FFFFFFFFFFF08FFFFFFFFEFFFFFFFFB5B2
-:10082000BD6F7CEB7FFBDBD34BEED6F6B7FDACA107
-:10083000FBDFFEF7F496BDB4C5A5AF6F694F7FBA75
-:10084000DBFFFFFFF03FFFFFFFFEBFFFFFFFDBFF10
-:10085000F6FFF6FFBDBFA5BFFF7D7FEFFFFBF1FDFC
-:10086000BFFF6FFF6B7ADBFFDBDFF6FEB6FDFDBF80
-:10087000FEF7FFD0EFFFFFFFFEFFFFFFFFF42FFFAC
-:10088000FC436BFFFFFF0DFFFC333FF05FF1FFFF09
-:10089000FFFFF9DEF04CFE77AFFFFFEFFFF0FFDB6D
-:1008A000FF5FF0EFFFFFFFFEFFFEF7FFF02FFFFD02
-:1008B000437FFFFFF10FFFFC333FFFAFF1FFFFFF6F
-:1008C000FFF6D7FFBCFDBDFFFFFFFFFFF0FFFFFFFF
-:1008D000FFF0EFFFFFFFFEFFFFFFFFFCFFFFFBF15D
-:1008E000BFFFF9FDCFF270FF1F9FF3F1FFFFFFFF86
-:1008F000FCF7FF139FFCFFFF84F7FFFF47FFFFFF9D
-:10090000F0BFFFFFFFFEF5FFFFFFF1FCFFFEFE79EA
-:100910003FFF1D46CFFFCFFC7BFFF1FFFFFFFFED49
-:10092000F3ABFFCBFFF8FFFCF5FFBFFFFFFFFAF0D3
-:100930008FFFFFFFFEF3C200000000000000010077
-:10094000000020002000000408010000000000203A
-:100950000C0000040100010000800000013CF07F59
-:10096000FFFFFFFEFDBFFFFFFDFEFFFFFFFFFEFFDE
-:10097000DFFFFFF7FFFFFFEFF1FFFFFFFFFFFFEBE1
-:10098000FFDFFFFFFBF77FFFFEFFFFBFDBF0FFFF97
-:10099000FFFFFEF0FFFFFFFFFFDFFFFFFF7FF7FF1F
-:1009A000BFBFCFFFFFFF3EF17FFFFFEFFFFFFFFE67
-:1009B000FFFDFFBFBDFEFFFBF7DFFBD0F09FFFFF9A
-:1009C000FFFEF8302000400180C030000020001001
-:1009D00050882000001301000000000000100000FB
-:1009E00000000180080000A00010C1F0EFFFFFFF31
-:1009F000FEFDEF7FFFFFBFFFF7FFEFFBFD77EFBFD0
-:100A0000F77FFFFFBFD17FFFFFF7FFFFFFFFAFFFC4
-:100A1000DFF7FBFFFDFFFCFFFDFFF0FFFFFFFFFE29
-:100A2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6
-:100A3000FFFFFFFFF1FFFFFFFFFFFFFFFFFFFFFFD4
-:100A4000FFFFFFFFFFFFFFFFFFF05FFFFFFFFEFF66
-:100A5000FFFFFFFFFFFFFFFFFFFFFFFFDFFFFFFFC6
-:100A6000FFFFFFF1FFFFFFFFFFFFFFFFFFFFFFFFA4
-:100A7000FFFFFFFFFFFFFFFFE03FFFFFFFFEDDFF88
-:100A8000FFFFA5FD6F7D6D7F52DF5A4BEEB6EEF294
-:100A9000BBACA15B4DD6F7FEB2BD35B5B5DD6F7F02
-:100AA000E95F52DFBDFFFFF0DFFFFFFFFEBFFFFF8B
-:100AB000FFDBFEF6FFF6FFFDBFFDB5BFF97F6FFF61
-:100AC000DBF1FDBFFF6FFF697FDBFFD3FFF6FEF2B7
-:100AD000FFADBFFFFFFFD0DFFFFFFFFEFFFFFFF512
-:100AE000300FFFFFFD6BCAFFF00FD6BFCF3FFFFFF8
-:100AF000F1FFFFFFCAFEBFFFF005AF0FFFFCF0CF15
-:100B0000F0FFFFFFFFF0EFFFFFFFFEFFFFFFF530FD
-:100B10000FFFFFFC3FCAFF0F0FD6BFFFFFF55FF1CE
-:100B2000FF8BFFC3FFFFFFFFFFFF0FFFFCF0CFF0C6
-:100B3000FFFFFFFFF03FFFFFFFFEFFFFFFFFCFFFC5
-:100B4000FFBF9F3FFEFCFF4FFFFFFFFFFFF7F1FFDF
-:100B5000DFFE7E3F9FF4FC7FFCFFFF3FFF3FFE3F39
-:100B6000FFFFFFF04FFFFFFFFEF5FFFFFBFFFEFF64
-:100B7000FFFFFFBFFBFFF8EDFF8FFFBBFFB1F3EF00
-:100B80008FF7FFFFDBFFFFFFEFBFFD79BFBFFFFF69
-:100B9000FFFBF0DFFFFFFFFEF3C0000000040000DA
-:100BA000000000000000008000040808010100901F
-:100BB000000000040008000000000800040000011C
-:100BC0003CF0DFFFFFFFFEFDBFFFFFFFFFFFFFFF6A
-:100BD000FFFFFFFF9FFFAFDFFFFFFFF1FFFFFFFF03
-:100BE000BFEFFFFFFFEDFFFFFFEFFFBFFFFFFFC303
-:100BF000F03FFFFFFFFEF0FFFDFFFFFFFBFFBBFF2E
-:100C0000FFFF7FF6FF7FFBFDEDFFF1FFFE7FFFFFA4
-:100C1000FF5FFFF7FF7EFFFDFFEFFFFFFFEFF0F04D
-:100C20008FFFFFFFFEF83080000400004002000349
-:100C300000050420000001D0008100200404000011
-:100C4000810408801000C0000000200008C1F06F7F
-:100C5000FFFFFFFEFFFF7FFFFFFFFFF3FDFFEDFC48
-:100C6000FFFF9FFBFDFFFFFFF1FFFF7FFB3EFF9FAD
-:100C7000FFFFFFFFFDF9FFFFFFFDFFFFFFF06FFF2D
-:100C8000FFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFF75
-:100C9000FFFFFFFFFFFFFFF1FFFFFFFFFFFFFFFF72
-:100CA000FFFFFFFFFFFFFFFFFFFFFFFFF0CFFFFF93
-:100CB000FFFEFFFFFFFDBDFFEF7CEB7FFBDBFADC00
-:100CC000EEF7F6D7F52DA1BBDDEEF754F7FB2CB50B
-:100CD000B4BD6B6FEF6FBBDFFFFFFFF01FFFFFFFC8
-:100CE000FEBFFFFFFFFBFFF6FFF6FFFDBFFFBFEFFD
-:100CF0006FFF6FFADBF1C5BDF56FFF6FCADBFFDB7E
-:100D0000FBF697F6FFFDBFFEF7FFD09FFFFFFFFE4C
-:100D1000FFFFFFFFFFFFFFFF8B7FFFFFE763FFFF8B
-:100D2000FFFC77DFF1DBFFD6A83FFFFF082FF0FFC6
-:100D3000C3FFEBFFFFFFFFFF5FF0EFFFFFFFFEFFD3
-:100D4000FFFFFFFFFFFFFF8BFFFFFFFFFFFFFFFF27
-:100D5000FCFFCFF1DBFFD6A83FFFFF082FF0FFC35A
-:100D6000FFEBFFFFFFFFFFFFF05FFFFFFFFEFFFF57
-:100D7000FFFFFFFFFFFFF5BFFFCAFF9FFFFAB9E7C5
-:100D80009FF381FFFFFC73D7FFFF77FFFDFFFCFFA1
-:100D9000FFFFFFCFFFFFFFF01FFFFFFFFEF5FFFF8D
-:100DA000FFF7DEFFFE7EFFBFFFBFF1B3FFFFE3FBF8
-:100DB000FFE11F7FFFF878FFFB1EFFF7FEE7FFFF55
-:100DC000FFBFFFFFFFFAF04FFFFFFFFEF3C0000081
-:100DD00000000000000000000000500000000400BF
-:100DE00001804040200000080000000003000000D7
-:100DF000800000013CF0AFFFFFFFFEFDBFFFFBFFE7
-:100E0000FFFFFFFFFFFEFFFFFFFFFFFFFFEFF7F119
-:100E1000FDFFFFFFDFFFEFFFFFFFFFFFFFFF7FFF94
-:100E2000FFFFFFDBF08FFFFFFFFEF0FFDFFFFF7F25
-:100E3000FFFFFFBED7FFEDBD7EBFFEF67FBF71FF98
-:100E4000FFDAFFF9FFBF7FFEFF6F7FFFFFFFFFFFAE
-:100E50007FFFD0F0CFFFFFFFFEF830420000000020
-:100E600080C100009000C400001220432281840051
-:100E700000140001000880000200020004020000CB
-:100E800010C1F01FFFFFFFFEFFFFFDFFFFDDFEFFB4
-:100E9000B676E5BCF9F7AF5FBFFCDFCFF1FFEF79C6
-:100EA000FFBDFFEFFFFFF76F5FFFFFFDEFEFBFFF3E
-:100EB000FFF09FFFFFFFFEFFFFFFFFFFFFFFFFFFB2
-:100EC000FFFFFFFFFFFFFFFFFFFFFFF1FFFFFFFF40
-:100ED000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22
-:100EE000F0FFFFFFFFFEDBFFFFFD2DFF692AEF771D
-:100EF000BBDD5ADFF6F6D6F77DBDD1B24AD6B2BE1B
-:100F000097F5BDB3ADFFEF7F696BFBDFFFFFFFF030
-:100F10002FFFFFFFFEBFFFFFFFDBFFF6FE9FD4BFEB
-:100F2000EDAFFF6B6FF7FFDDDB31FDBFFF6F7FFFC5
-:100F3000FFDBFFCBDFF6FFF6FFFDBFFEF7FFD08F35
-:100F4000FFFFFFFEFFFFFFFD1FFF462F9FFFFFFF7D
-:100F5000A5FFFFFFDFB7FFFFF1FFFFFFF7E96ABF64
-:100F6000FFFFFDFFFFFD5557FFFFFFFFAFF04FFFF6
-:100F7000FFFFFEFEDFFFFD1FFF462F9FFFFFFFA5C8
-:100F8000FFFFFFC037FFFFF1998EDC7FE96ABFFFEB
-:100F9000F00FFFFFFD5557FFFFFFFFFFF00FFFFFB3
-:100FA000FFFEFFFFFFFF07FFC0BEFFFFCFEF9FFF6A
-:100FB000FFFBFFE7FFFFA1E3CE3C583FF3FFFDEF50
-:100FC000F9FFFFF7F17FFFCBFFFFFFF02FFFFFFFE0
-:100FD000FEF57FFFF0FFFEFFC475E7B9FFFFFFEFEF
-:100FE000FFC7373BFFF0139E0FF4FFFEFBFFFFF937
-:100FF000FCFFFFFFFFBFFFFFFFFAF0EFFFFFFFFE69
-:10100000F3C0010000020002220000C040004000C6
-:101010000408040A0101102020000004080804004C
-:1010200000000000010000013CF0CFFFFFFFFEFDCB
-:101030003FFFFFFFFFFFFF7FFF7FFF7FFFCF9DFF92
-:10104000FFF7FDF1FFFFFFEEBFFFFFFFFFFEFFFF1A
-:10105000FFFFFFFFFFFFFFDBF06FFFFFFFFEF0FF73
-:10106000FFFFF7F7FFFFFEBFF7FFFF5BFFBFF7FFD5
-:10107000FD7F71FDFFEDF7FEEFFFFF7FFFFFFFFF3D
-:10108000FFFFEFFF7FFFD0F0FFFFFFFFFEF8301103
-:10109000004860408260246000CC008004010000B1
-:1010A00014010C0400300000000808000100C20018
-:1010B0000002008000C1F05FFFFFFFFEFFFFFFFFA7
-:1010C000F77BFFF3EBBFFFF7FFFFFFE75D3FFFF6A7
-:1010D000D1FDFFEBF73DFFFFFF5FFF7F7FF3FFFFDA
-:1010E000EFFDBFFFFFF05FFFFFFFFEFFFFFFFFFF12
-:1010F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10E
-:10110000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF
-:10111000FFFFFFFFF0DFFFFFFFFEFFFFFFF5B5DF83
-:101120006F7D697FFBDF525FF6F7FEF6F3BDB1DA44
-:10113000CDFEF6EED2BDA5AFBDFF6F7CEB2BFADA8C
-:10114000FFFEDFF04FFFFFFFFEBFFFFFFFDBFFF6FD
-:10115000FFF6FFBDBFCDBFEB6FF76FDFDB51FDBD0E
-:10116000FF6FFF6FFB5BFFDBFFF6FEF6FDFDBFFED3
-:10117000F7FFD0FFFFFFFFFEFFFFFFFA50FFFFFF6B
-:10118000F06FFFFFF096FFFFC62BFFFFF1FCFFFFA4
-:10119000F7DBC3FF00FFFFFFFFFFC14FC3FFFFFFF0
-:1011A000AFF09FFFFFFFFEFFFFFFF5A0FFFFFFF087
-:1011B0006FFFFFF096FFFFC62BFFFFF15AFFFFFF07
-:1011C000F3C3FF00FFFFFFFFFFC14FC3FFFFFFFFA0
-:1011D000F0CFFFFFFFFEFFFFFFFFFCFFFF9FF07F51
-:1011E000FFF9FC4FF3FF27EBFFFC81FC7FFE7BFF49
-:1011F000F7FF127FFFFFFFFF18FFFFFFFFFFFFF06A
-:101200007FFFFFFFFEF5FFFFFFDFFEFFFC7E7FBFDE
-:10121000FFFFAFEFFFDFDFFBFFF1C3FE6FF1CF3F5B
-:10122000FBFFFFCFFEFFFFFE7FBFFFFFBFFAF0DF38
-:10123000FFFFFFFEF3C000000100000000010000FE
-:10124000200001001000000001000200000000006A
-:101250000000000200008000028000023CF02FFF2E
-:10126000FFFFFEFDBFFFFBFDFFFFFFFFFFFFFFFFD7
-:10127000FFFFFFFFFFFFF5F1FF7FFFFFFFFFEFFF26
-:10128000FFFFFFFFFEFFFFFFFFFFFFDBF02FFFFF72
-:10129000FFFEF0FFFFFFFBFFBFFFFFFFFFF7BFFBFE
-:1012A000FFFFFFDFF7FFF1F7BFFBFFFFFF7FDEFF71
-:1012B000FFFFFFFFFFEDF7FFFF7FD0F03FFFFFFFD6
-:1012C000FEF830000000004000000000E000008058
-:1012D0002001019200010100E01C6020300808009C
-:1012E000000000000000008000C1F06FFFFFFFFE63
-:1012F000FFFFFFFFFFDBFEFFFFDFFFFC7FFBBFFF0A
-:10130000FFFFFFFFF1F6FFF77E3FFF7FFFFFFFF7D5
-:10131000FFFFFFEDFFDFFFB7FFF03FFFFFFFFEFF27
-:10132000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD
-:10133000FFFFFFF1FFFFFFFFFFFFFFFFFFFFFFFFCB
-:10134000FFFFFFFFFFFFFFFFF0FFFFFFFFFEFFFFBD
-:10135000FFFFFFFFDFFFFFFFDFFFFFFFFFBFFFDF3D
-:1013600057EFF1FDFE7FFFFFFFFFFFFFFFDFFBFFFA
-:10137000FFFFFFFFFFFFFFF07FFFFFFFFEFFFFFF0D
-:10138000FFFFFF7FFFFFFFFFFFFFFFFFFBFFDFFF11
-:10139000FFF1FDFF7FBFFFFFFFFFFFFFFFFFFFFF2D
-:1013A000FFFEFFFFFFFFF09FFFFFFFFEF7FDFFFFC8
-:1013B000FFFFFFFFFFFFFFFFFFFFBFFFFFFFFFFF7D
-:1013C000F1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3B
-:1013D000FFFFFFFFFFF06FFFFFFFFEFFFFFFFFFFBD
-:1013E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF11B
-:1013F000FFFFFDFFFFFFFFFFFFFFFFFFFFFFFFFFFF
-:10140000FFFFFFFFF0CFFFFFFFFEFFFFFFFFFFFF2C
-:10141000FFFBFFFFFFFEFFFFFB6FFFFEBFFFF1FFC4
-:10142000F7FFFF7FFFFFFFFFFFFFFFFFFFFFFFFD56
-:10143000FFFFFFF0EFFFFFFFFEFFFFFFFFFFFFFFDC
-:10144000FBFFFFFFFEFFFFFF57FFFDBFFFF1FFEFB9
-:10145000FEFFBFFFFFFFFFFFFFFFFFFFFFFFFEFFDE
-:10146000DEFFF0CFFFFFFFFEFFFFFFF7DBFFDBFD3F
-:10147000F6FFF6FF3CBCBCBFDF6FE72FF13CBFFDC2
-:10148000BFDF6FFF6FF7DBFFDBFDF6FFF6FFFFFF50
-:101490000201DFFFFFFFFEFFFFFFFFFFFFFFFFFF78
-:1014A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4C
-:0614B000FFFFFFFFFFFF3C
-:00000001FF
-/*
- *
- * File yam111.mcs converted to h format by mcs2h
- *
- * (C) F6FBB 1998
- *
- * Tue Aug 25 20:23:03 1998
- *
- */
--- zfcpdump-kernel-4.4.orig/firmware/yamaha/ds1_ctrl.fw.ihex
+++ /dev/null
@@ -1,769 +0,0 @@
-:10000000070000000700240007000C0007001C0088
-:1000100007000600020070002000000040000300FE
-:100020000471000086420000400003000D0F000034
-:10003000100800003A042000820200000D020000B7
-:10004000100800003A04200082120000820E2000F6
-:10005000821A00000D2D0300100800003A04100061
-:100060008DD30200100800003A0418000D010000B2
-:1000700015000200FD000000200000006088030061
-:100080006090030060800300408003004080030014
-:1000900040800300408001007D0A00004080030092
-:1000A000408003004080010002042000820800001C
-:1000B0001A0008000409000086590100070000002A
-:1000C000070026000700000007000000068A010064
-:1000D000070000008D0C0300100800003A0418000F
-:1000E000070026007D080000428001000A1600007B
-:1000F00006A20400070000008D2100001008000087
-:100100003A04080006C2210007000000FD070000B5
-:10011000428001000A0008000409000086930200E2
-:1001200095010000040D09000700000020080000F0
-:10013000F50000007D0B000060F00100FD000000F4
-:1001400006220300408001007D0A00004280030077
-:100150004A8013000A001800201800006090050073
-:100160006088050040800100FD0000004280010021
-:100170000A007000150100004411070086230300E7
-:100180000000030020700000064A030040800100C8
-:100190008D340000100800003A04080006EA21002F
-:1001A000070000008DD30200100800003A04180078
-:1001B0000682010007000000070024008D0F0000E8
-:1001C000100800003A16000002240000025C000043
-:1001D000FD28000020000000408001000D00080004
-:1001E0001508000084095100070000004D000000C0
-:1001F0005D0E0000020E00008D410000100800009E
-:100200003A040800068A2C00070000008D00000058
-:1002100024090000020F00008D45000010080000B6
-:100220003A040800068A2C00070000007D38000010
-:10023000428001000A000800151000008409010036
-:10024000868301000700000006AA010007000000E5
-:10025000FD080000428001000A0018000419000097
-:100260008680210007002800101800003A042800AA
-:10027000020C28000D000000100800003A142800AD
-:100280008D80080020080000FD0200004080010071
-:10029000070020000D02000004991800070000006C
-:1002A0002D400000BD000000FD0200004280010062
-:1002B0000A00080004090000865A05000700000033
-:1002C00000010000200A00007D04000040800100C1
-:1002D000428001000A002000153000004421010086
-:1002E000864903000700000004210000864903003E
-:1002F000070000008D0F0000100800003A0C2800D5
-:100300004439020086C906000700000010180000EA
-:100310003A0428000D81080020080000FD020000BA
-:100320004080010007002000102800003A007800FB
-:100330008D680000100800003A040800068A2800B2
-:10034000070000000D40000015100000049918007F
-:1003500004292900043939000700000006020600BC
-:1003600007000000F50400007D00000020000000F0
-:100370008D00000060080100408001007D04000045
-:10038000428003004A8021000A001800441902003C
-:1003900086582100070000007540000004F171003C
-:1003A00007000000420001000A00280004290000A4
-:1003B00086202100070000000D3C000004A9300049
-:1003C000070000007D070000428001000A000800CD
-:1003D0000409000086DA07007D05000020280000DF
-:1003E00060B0030006F207004080010020300000EA
-:1003F00060A8030040800100FD020000428001006F
-:100400000A0008000409000086FA0700070000003F
-:100410007D050000428001000A0428008D0E0000C6
-:10042000100800003A0C28000D0000001008000021
-:100430003A1428000D00090020080000FD02000009
-:100440004080010007002000FD3D0000200000006A
-:10045000408001007D1000008D8D0000100800001C
-:100460003A040800068A280007000000150800006A
-:100470001A00080084090100865109007D1300005C
-:1004800000052000200F2800608F3300608F3B00A4
-:10049000608F4300608F4B00608F5300608F5B0064
-:1004A000608A030040800100BD7F0000C43D380029
-:1004B000070000007D1A0000751300004280010053
-:1004C0004A0009000A001000048D0B000495130077
-:1004D00007000000200800006090010004110000E7
-:1004E0008620210040000100FD170000428001002D
-:1004F0000A0008000409000086222100070000000D
-:100500007D190000428003004A8009000A001000A3
-:100510002409000064160000FD1100004280030061
-:100520004A802B004A8019008D0000004489210078
-:10053000070000004422000086E10A0007000000D6
-:10054000641A0000242A00007D190000020108003E
-:10055000220110002008000060900300408001008C
-:10056000FD3D00008D0000002008000040800100DB
-:10057000751300007D1A0000420001004A80090046
-:100580000A0010001D020000E4890100E492290025
-:1005900044913000070000000D060000150A00001D
-:1005A0001D0C000025100000E4A90000E42B010050
-:1005B00064040000E4B30100E432020064040000BB
-:1005C0006404000064040000640400000D040000E2
-:1005D000C4B108000700000020080000F50B00006F
-:1005E000400003007D190000428003004A8009009A
-:1005F000240A00000A000800640E0800070000003A
-:1006000022011000200800006010030040000100DB
-:10061000AC6400007D02000020000000408001006A
-:100620007D10000042800100FD1100004A803B0067
-:100630004A8009000A0020009500000044111A00B9
-:1006400044A1000086200D000D04000084B90000C4
-:1006500086210D00FD18000042800100FD10000001
-:100660004A8009000A0028009500000024090100C2
-:10067000642A000086110D00070000000429000014
-:1006800086220D0007000000062A0D000200080067
-:100690008D0000007D38000020080000408001002F
-:1006A0007D120000428001000A00100004390000A1
-:1006B00086D10D000D080000B5FF7F0084B9000051
-:1006C00086A10D0025000000067A0E002D00000016
-:1006D000150000002D0800008DC702002008000052
-:1006E00006C20E000D00000035807F0084B90000B6
-:1006F00086710E00250040008D00000044091100A5
-:10070000070000008D0100000495100007000000A4
-:10071000649100002404000024040000240400006C
-:1007200002011000020028008DC60200200800000F
-:1007300006C20E008D0100002D0400008D00000097
-:1007400004951000070000000D02000084911000C5
-:10075000070000000DC70200200800008D00000007
-:10076000FD38000040800100FD3B0000201000002B
-:1007700060A80300150800008431310084212100A5
-:100780000700000060B0030060A00300408001008B
-:10079000FD2200009500000024090100240400004F
-:1007A0002404000064120000020110002008000070
-:1007B0006090030040800100241900008DFB0000C0
-:1007C0007D390000200800004080050042800300C1
-:1007D0004A840900060600000A04080024040000F8
-:1007E000240400007D110000428001000A0008007E
-:1007F000240A000002052800020C28000D800900D0
-:1008000020080000FD0200004080010007002000D9
-:10081000FD220000428001000A000800950000004F
-:10082000C40D2800241901007D1900004280010038
-:10083000FD1100004A8009000A001000B500000008
-:1008400044311100048D0A0007000000440A08002A
-:100850000495120007000000FD2300002010000096
-:100860004080030044121000070000002008000030
-:100870006090030040800100FD0200004280010002
-:100880000A0008000409000086FA100007000000B2
-:10089000FD3B000000010000100A00007A800B0000
-:1008A0004A80130084090900070000009500000039
-:1008B000043D0100868011000A00100002001000B3
-:1008C0008409090007000000428003004A801100EB
-:1008D000040D0900070000000A001000840D090043
-:1008E000070000007D250000200800004080010076
-:1008F0000D010000100800003A1428007D120000CD
-:10090000428001000A0020007D19000042800100A1
-:100910007D1100004A8031000A00100024310000DF
-:100920000D2801007D3900002008000040800500EE
-:10093000428003004A840900060600000A040800F9
-:1009400002013000243100002404000024040000CF
-:1009500024120000020528004C1A00008601130032
-:10096000020070002D000000000003007D38000030
-:10097000428001000A001000062A13002421000012
-:10098000AD000000020010000D010000240900006D
-:10099000246B00008D3601007D3900002008000026
-:1009A00040800500428003004A84090006060000DA
-:1009B0000A040800643200008D000000240A0000D0
-:1009C000201000007D220000408001000D3C01004D
-:1009D000100800003A04080006D2290007000000B1
-:1009E000202800007D200000408001007D110000D3
-:1009F000428003004A8013000A8033007D380000E3
-:100A0000428001000A00080004090000863A16002E
-:100A1000070000008D000000640903008D470100FD
-:100A20007D3900002008000040800500428003005E
-:100A30004A840900060600000A0408000201380082
-:100A4000240400002404000024120000FD02000021
-:100A5000428001000A0008000409000086A2140078
-:100A600007000000020528004C1A00008639160015
-:100A700007000000642103002C630000FD3D00001E
-:100A8000428001000A0008009500000004090900E6
-:100A900007000000200800004C1A000086611500C5
-:100AA0004080010000000300067A150024210000A8
-:100AB0000D01000024090000246B00008D5B010083
-:100AC0007D390000200800004080050042800300BE
-:100AD0004A840900060600000A040800643A00007F
-:100AE0009500000024120000FD0200004280010079
-:100AF0000A0008000409000086DA1500070000005B
-:100B00008D620100100800003A04080006D2290096
-:100B10000700000006D2140007000000207000004B
-:100B20000A0108002A011000FD200000608803006F
-:100B300060900300408001007D220000428001009F
-:100B4000FD3D00000A0008004A843100040900004D
-:100B500086D816008B0018008D000000049918003C
-:100B60002C31000006AA1700070000004C320000DC
-:100B700086331700070000000419000086301700B4
-:100B80000700000095000000449119002C2200008D
-:100B9000243100006C6300003D0E0000751300005E
-:100BA000FD0B0000420001004A8009000A0010000D
-:100BB000EC8A0300EC9303004C22000086A9170086
-:100BC000070000008D000000049918006C2200004E
-:100BD0002C3200000A053000AB1D300083200000DD
-:100BE000FD180000428001000A000800248901006D
-:100BF000020530008310000075180000420001005B
-:100C00000A0010008D000000240901007513000087
-:100C100042053300CB0C3300CB2C3300CB343300F4
-:100C2000CB3C3300CB443300CB4C3300CB543300AC
-:100C30008B5C300083600000F50200004200010080
-:100C40000A00080004090000867A18000700000066
-:100C50002D1E0000FD050000428001000A00080072
-:100C600024890200020528000D060000100800007B
-:100C70003A0C28008D000000100800003A142800EB
-:100C80008D800A0020080000F502000040000100ED
-:100C90000700220075120000420003004A002100F4
-:100CA0008D00000044091A00070000000D980100A3
-:100CB000100800003A04080006222B00070000007C
-:100CC000F5010000420003004A000D000A00100078
-:100CD00044910800070000002008000040000100C7
-:100CE000F525000044310A0007000000200800003C
-:100CF00060280300400003007D21000042800300C3
-:100D00004A800B000A001000200800006010030059
-:100D1000400003008D000000240100002C010000B1
-:100D2000640E0000641A00006C6300000A010800F1
-:100D30002A0110002008000060100300400003009A
-:100D4000FD200000428001000A0008007D22000012
-:100D5000428001000A00100020080000601003001B
-:100D6000400003007D190000428001000A000800D5
-:100D7000FD220000428003000A001000200800004D
-:100D80006010030040000300040D0900070000008C
-:100D90002008000040000300428003004A800B004E
-:100DA0000A0010002008000060100300400003004B
-:100DB000428003004A8013004A801900040D11008C
-:100DC000048D1900070000000A0008002010000030
-:100DD0006018030060080300400003008D0000005D
-:100DE00044090B000700000020080000400001003B
-:100DF000F5050000420003000A000800200800007A
-:100E000040000100F5000000420001000A00080057
-:100E10000409000086601C00751E000042000300EB
-:100E20004A0401000A0C000006721C0007000000C2
-:100E300002040000020C00007D170000F51A0000FB
-:100E4000428001004A1403004A1C03004A240300A4
-:100E50004A2C03004A3403004A3C03004A4403007E
-:100E60000A4C00003D040000F5130000FD1A0000CC
-:100E7000420003004A000B004A801B004A80130016
-:100E80000A0020004491080044A11900E4890300ED
-:100E9000EC990300025500000A5D000042000300C7
-:100EA0004A000B004A801B004A8013000A00200001
-:100EB0004491080044A11900E4890300EC9903005F
-:100EC000026500000A6D0000420003004A000B00AA
-:100ED0004A0019004A802B004A8013004A802100F2
-:100EE0000A0030004491080044A1190044B12A00CE
-:100EF000E4890300EC990300027500000A7D0000FC
-:100F0000E4A90300020700007D10000015040000A2
-:100F1000428001000A000800E4090100020F0000FD
-:100F2000F52A0000FD190000420001004A80090076
-:100F30000A0010003409000074160000F5290000B2
-:100F4000420001000A0010007C91000075200000A2
-:100F5000420001000A0008000409000086D21E00B9
-:100F6000F5260000F5270000420003004A000900B2
-:100F70000A0010003C0A00007C160000751A0000F0
-:100F8000FD0B0000420001004A8051000A004800A9
-:100F90000700160075100000420001000A2C28000E
-:100FA000121D280012252800321F000007001E0015
-:100FB00007000E007519000042000100F52D000029
-:100FC0004A000D000A0010004491000086B21F0084
-:100FD000420001000A3428005D0E00008D00000070
-:100FE000750300002008000040000100F4D2050055
-:100FF00004D154005C7300008653200007000000F9
-:1010000007000C000700080007000A000D0402009A
-:10101000100800003A040800062233000700000010
-:10102000065A200007000000070008007522000093
-:10103000420001000A002000042100008620210057
-:101040002D1E0000F5020000420001000A00080009
-:101050000409000086922000070000001020000014
-:101060003A0430007D050000C38001000A0008003A
-:101070002489020002052800020C28000D810A00C4
-:1010800020080000F50200004000010007002200D7
-:10109000FD040000428001000A007000000003000F
-:1010A0002070000006FA0600408001000D180200C2
-:1010B000100800003A04080006222B000700000078
-:1010C000FD020000428001000A000800040900003F
-:1010D000868A21000700000006F2010007000000D8
-:1010E00075080000FD0900000D010000060A22003D
-:1010F00095020000750B00007D0900000D00000046
-:1011000015050000420001000A0018000419000043
-:1011100086782800F506000020100000400001003D
-:10112000F5040000200800004000010075070000E1
-:10113000420001004A8009000A001000241100004A
-:101140000409000086BA2200150800000201080008
-:101150000412100006DA22007505000004120800CF
-:1011600007000000020110007505000025040000C2
-:10117000241102000201100020080000601003008A
-:101180004000010024190000867828008D0000002E
-:1011900064040000049D00008688270002011800F6
-:1011A00075050000420001000A0428008D010000BE
-:1011B00024090000020D28000D0000002409000091
-:1011C000021528000D00100020080000F5020000A4
-:1011D000400001000700200075110000FD02000022
-:1011E000428001000A0008000409000086C22300B2
-:1011F0000700000000010000200B0800600B130036
-:10120000600B1B00600A0300400001004200050063
-:101210004A003D004A0035004A002D000A00200027
-:10122000F5060000420001000A142800F504000041
-:10123000420001000A00080015030000040D01002F
-:1012400086CA24001540000095000000040D01002E
-:1012500086B82400220010002A00100006E22400B4
-:10126000070000000431330004A92A000700000031
-:10127000242103000205280024110000240400009A
-:1012800024040000243200002C2900006C630000BC
-:1012900086F325000700000064B10200640400002A
-:1012A000640400008D000000640A0000020D2800A4
-:1012B0008D00100020080000F50200004000010031
-:1012C000070022008D00000004B93800070000006C
-:1012D0006C2903000A013000F50200004200010001
-:1012E0000A0008000409000086BA25000700000073
-:1012F0002C3102000A0528008D0000006C09010055
-:101300000A0D28000D01100020080000F502000061
-:101310004000010007002200241100002404000006
-:10132000240400002432000002013000442903009C
-:10133000867A26000700000002003000F504000055
-:10134000420001000A00080015030000040D01001E
-:1013500086C0260024310000640400000201300031
-:10136000F5020000420001000A0008000409000024
-:1013700086CA260007000000243100000205300064
-:10138000243900008305300083080000F5050000C3
-:10139000420001000A0428008D00000024810000A2
-:1013A000020D28008D000000248100000215280095
-:1013B0008D01100020080000F5020000400001002F
-:1013C0000700220025100000750500004200030000
-:1013D0004A0009000A00100004090A000411120062
-:1013E0000700000020100000600805004000050014
-:1013F000FD060000428001004A0009000A001000BA
-:10140000A500000004090A000411120007000000F2
-:10141000200800006090010040000100F50200007B
-:10142000420001000A00080004090000864228006A
-:1014300007000000060A230007000000060600005F
-:1014400007000000F5020000420001000A00080049
-:101450000409000086922800070000000001000037
-:10146000200B0800608B1300608B1B00608B230037
-:10147000608B2B00608B3300608B3B00608B4300E4
-:10148000608B4B00608B5300608B5B00608B630054
-:10149000608B6B00608B7300608B7B00608F030040
-:1014A000608F0B00608F1300608F1B00608F230024
-:1014B000608F2B00608F3300608F3B00608F430094
-:1014C000608F4B00608F5300608F5B00608F630004
-:1014D000608F6B00608F7300608F7B00608A0300F9
-:1014E00006060000408001008D000000640A000034
-:1014F000020D2800240A00007D0200004280010045
-:101500000A00100024120000FD03000042800100C8
-:101510000A0008000409000086822A000700000073
-:101520008D010000240A000064040000640400002F
-:101530000201080024090000240400002404000023
-:10154000020110000D0002004491000086D92A001B
-:1015500007000000FD010000428001000A000800B1
-:10156000440A000086BB2A00428001000D000A00E8
-:1015700020080000FD02000040800100070020005C
-:101580007D020000201000000606000040800100DF
-:10159000F5020000420001000A00080004090000F2
-:1015A000862A2B00070000007D0300004280010016
-:1015B0000A00080004090000865A2B0007000000FA
-:1015C000750000007D2E0000420001004A800B00E3
-:1015D0002000000004090000860600004000010011
-:1015E0004A8431008B043000830800008D00000025
-:1015F000100800003A1428008D00000010080000B8
-:101600003A0C280075060000420001000A0008009C
-:101610001538000024090100020528000D000B0008
-:1016200020080000F502000040000100060600004E
-:1016300007002200640400006404000006060000A5
-:1016400007000000340100008D7F00003C0900000D
-:10165000121D280012252800321F000007000E006E
-:101660000D0100007D030000200800004080010003
-:10167000F4D2050007000000070008007D03000009
-:10168000428001000A0008000409000086022D00C3
-:101690000700000006060000070000000700000029
-:1016A0001200000007001000070032000700600071
-:1016B000800010001A0048000449000086612D00D7
-:1016C00007000000101200003A0058004501000019
-:1016D000045D5C0007000000800000001A00480064
-:1016E0000449000086B12D00070000001012000020
-:1016F0003A0050000459000086082E004500000002
-:10170000C5000000F5FF7F007DFF7F0024D50700A6
-:101710002442000002015000020520008200000067
-:101720001A0040000441000086392E000700000026
-:10173000653800001A004000204000004D100000F5
-:1017400084C10400861B3000400000000700040034
-:10175000650100004501000020400000400000003D
-:1017600065070000800008001A00400004410000E6
-:1017700086C92E0007000000101200003A00400049
-:101780000441000086222F004D000000CD00000023
-:10179000104800003A042000820800001A004000AF
-:1017A0000441000086312F0007000000204800009F
-:1017B000045900008608300040000000E5070000E2
-:1017C00080042000A0162800E0163200E0163A003F
-:1017D000E0164200601202004000000032000000EB
-:1017E000750040007D00000074D507001205200040
-:1017F000820000001A0040000441000086E12F0032
-:1018000007000000067203000700640007000600DE
-:10181000E50000002000000040000000650A000014
-:1018200020000000400002004000020040000000D4
-:1018300065010000420000000A0070000471000011
-:1018400086A2300007000000068201000700640045
-:101850000000050020700000400000000672030038
-:1018600007006400070000006D300000608802007F
-:10187000609002000A0008006088020040800000BA
-:10188000120010000D10000084910000864131000C
-:101890000D0E000084910000865132000700000008
-:1018A00007003000201000006D3B00004080000069
-:1018B000800000001A000800040900008661310061
-:1018C0000700000020120000ED0D00004080000025
-:1018D000428000000A0010000D00400044951000F6
-:1018E0000700000020100000ED0D00004080000007
-:1018F000428000000A042000820000001A00080054
-:101900000409000086F13100070000006D3B000073
-:10191000428000000A000800150E00008409010042
-:10192000869B3200070060001A000800150C0000BA
-:1019300084090100868332002000000007001A009D
-:10194000ED02000040800000070062006D300000E2
-:10195000428002004A800A00200800004A800A00F3
-:10196000060600004A80100007000000122528002B
-:10197000321F0000F4D2050004D154005C73000053
-:10198000860700000700000007000C0007000A009F
-:1019900007001C00653400004000020020480000E1
-:1019A000605002000A004000604002004000000059
-:1019B000444945000700000020400000E53A0000CF
-:1019C00040000000E5280000420000000A00480036
-:1019D0000449000086683800652C000042000000C1
-:1019E0000A004000D5000000044145000700000047
-:1019F000550600000445050086F23400D5010000BC
-:101A00000445050086F03400652B0000420000000C
-:101A1000E53A00004A0050000A004000D4C34500E7
-:101A2000070000000445450007000000CD0000004D
-:101A30004449440007000000044545000700000039
-:101A40004D010000444955000700000044510400C6
-:101A500086E93400652C0000420000000A004800BE
-:101A600004D14C000700000044C1040086F3340098
-:101A70000700000007001600E52C000042000400EB
-:101A80000A004000204000004000000065290000DE
-:101A9000420000000A00400004410000866035005A
-:101AA000070000000224000006A23600025C0000CD
-:101AB000E5250000420000000A00400074420000DA
-:101AC000E52A0000420000000A00400074420000C5
-:101AD00012015000E5290000420000000A00400009
-:101AE000344200000441450007000000204000008F
-:101AF00040000000E53E0000200000004000000023
-:101B0000E52D0000520140000A005000445104003D
-:101B1000864A3600C5000000E53E00002040000077
-:101B200040000000E52B0000420000000A004000D9
-:101B30005442400007000000E52A00002040000059
-:101B400040000000320150003401040074560000CF
-:101B5000E5290000420002000A00420042000000A5
-:101B60000A0050007C410500E5280000420000000A
-:101B70000A004800C500000044C14C008610370030
-:101B8000E5260000E5270000420002004A00400070
-:101B90000A0050003C4200007C560000E52800008E
-:101BA0002048000040000000121D280012252800D7
-:101BB000721F000065290000420000000A0040007A
-:101BC0000441000086AA370007000E000700160037
-:101BD00007001E00E53E0000420000000A00400031
-:101BE0000441000086E83700652D00004200000037
-:101BF0000A34280065340000420002004A00420016
-:101C0000204000004A004A004A005000F4D205007B
-:101C100004D154005C7300008651380007000000B6
-:101C2000060600000700080007000C000700080077
-:101C300007000A00E5010000450002002040000006
-:101C4000600000006503000040000000652E0000F9
-:101C5000201A0000601A0A004000000065340000ED
-:101C6000420002004A004200204000004A004A00B0
-:101C7000060600004A0050000000000000000000BE
-:101C80000000000000000000000000000000000054
-:101C90000000000000000000000000000000000044
-:101CA0000000000000000000000000000000000034
-:101CB0000000000000000000000000000000000024
-:101CC0000000000000000000000000000000000014
-:101CD0000000000000000000000000000000000004
-:101CE00000000000000000000000000000000000F4
-:101CF00000000000000000000000000000000000E4
-:101D000000000000000000000000000000000000D3
-:101D100000000000000000000000000000000000C3
-:101D200000000000000000000000000000000000B3
-:101D300000000000000000000000000000000000A3
-:101D40000000000000000000000000000000000093
-:101D50000000000000000000000000000000000083
-:101D60000000000000000000000000000000000073
-:101D70000000000000000000000000000000000063
-:101D80000000000000000000000000000000000053
-:101D90000000000000000000000000000000000043
-:101DA0000000000000000000000000000000000033
-:101DB0000000000000000000000000000000000023
-:101DC0000000000000000000000000000000000013
-:101DD0000000000000000000000000000000000003
-:101DE00000000000000000000000000000000000F3
-:101DF00000000000000000000000000000000000E3
-:101E000000000000000000000000000000000000D2
-:101E100000000000000000000000000000000000C2
-:101E200000000000000000000000000000000000B2
-:101E300000000000000000000000000000000000A2
-:101E40000000000000000000000000000000000092
-:101E50000000000000000000000000000000000082
-:101E60000000000000000000000000000000000072
-:101E70000000000000000000000000000000000062
-:101E80000000000000000000000000000000000052
-:101E90000000000000000000000000000000000042
-:101EA0000000000000000000000000000000000032
-:101EB0000000000000000000000000000000000022
-:101EC0000000000000000000000000000000000012
-:101ED0000000000000000000000000000000000002
-:101EE00000000000000000000000000000000000F2
-:101EF00000000000000000000000000000000000E2
-:101F000000000000000000000000000000000000D1
-:101F100000000000000000000000000000000000C1
-:101F200000000000000000000000000000000000B1
-:101F300000000000000000000000000000000000A1
-:101F40000000000000000000000000000000000091
-:101F50000000000000000000000000000000000081
-:101F60000000000000000000000000000000000071
-:101F70000000000000000000000000000000000061
-:101F80000000000000000000000000000000000051
-:101F90000000000000000000000000000000000041
-:101FA0000000000000000000000000000000000031
-:101FB0000000000000000000000000000000000021
-:101FC0000000000000000000000000000000000011
-:101FD0000000000000000000000000000000000001
-:101FE00000000000000000000000000000000000F1
-:101FF00000000000000000000000000000000000E1
-:1020000000000000000000000000000000000000D0
-:1020100000000000000000000000000000000000C0
-:1020200000000000000000000000000000000000B0
-:1020300000000000000000000000000000000000A0
-:102040000000000000000000000000000000000090
-:102050000000000000000000000000000000000080
-:102060000000000000000000000000000000000070
-:102070000000000000000000000000000000000060
-:102080000000000000000000000000000000000050
-:102090000000000000000000000000000000000040
-:1020A0000000000000000000000000000000000030
-:1020B0000000000000000000000000000000000020
-:1020C0000000000000000000000000000000000010
-:1020D0000000000000000000000000000000000000
-:1020E00000000000000000000000000000000000F0
-:1020F00000000000000000000000000000000000E0
-:1021000000000000000000000000000000000000CF
-:1021100000000000000000000000000000000000BF
-:1021200000000000000000000000000000000000AF
-:10213000000000000000000000000000000000009F
-:10214000000000000000000000000000000000008F
-:10215000000000000000000000000000000000007F
-:10216000000000000000000000000000000000006F
-:10217000000000000000000000000000000000005F
-:10218000000000000000000000000000000000004F
-:10219000000000000000000000000000000000003F
-:1021A000000000000000000000000000000000002F
-:1021B000000000000000000000000000000000001F
-:1021C000000000000000000000000000000000000F
-:1021D00000000000000000000000000000000000FF
-:1021E00000000000000000000000000000000000EF
-:1021F00000000000000000000000000000000000DF
-:1022000000000000000000000000000000000000CE
-:1022100000000000000000000000000000000000BE
-:1022200000000000000000000000000000000000AE
-:10223000000000000000000000000000000000009E
-:10224000000000000000000000000000000000008E
-:10225000000000000000000000000000000000007E
-:10226000000000000000000000000000000000006E
-:10227000000000000000000000000000000000005E
-:10228000000000000000000000000000000000004E
-:10229000000000000000000000000000000000003E
-:1022A000000000000000000000000000000000002E
-:1022B000000000000000000000000000000000001E
-:1022C000000000000000000000000000000000000E
-:1022D00000000000000000000000000000000000FE
-:1022E00000000000000000000000000000000000EE
-:1022F00000000000000000000000000000000000DE
-:1023000000000000000000000000000000000000CD
-:1023100000000000000000000000000000000000BD
-:1023200000000000000000000000000000000000AD
-:10233000000000000000000000000000000000009D
-:10234000000000000000000000000000000000008D
-:10235000000000000000000000000000000000007D
-:10236000000000000000000000000000000000006D
-:10237000000000000000000000000000000000005D
-:10238000000000000000000000000000000000004D
-:10239000000000000000000000000000000000003D
-:1023A000000000000000000000000000000000002D
-:1023B000000000000000000000000000000000001D
-:1023C000000000000000000000000000000000000D
-:1023D00000000000000000000000000000000000FD
-:1023E00000000000000000000000000000000000ED
-:1023F00000000000000000000000000000000000DD
-:1024000000000000000000000000000000000000CC
-:1024100000000000000000000000000000000000BC
-:1024200000000000000000000000000000000000AC
-:10243000000000000000000000000000000000009C
-:10244000000000000000000000000000000000008C
-:10245000000000000000000000000000000000007C
-:10246000000000000000000000000000000000006C
-:10247000000000000000000000000000000000005C
-:10248000000000000000000000000000000000004C
-:10249000000000000000000000000000000000003C
-:1024A000000000000000000000000000000000002C
-:1024B000000000000000000000000000000000001C
-:1024C000000000000000000000000000000000000C
-:1024D00000000000000000000000000000000000FC
-:1024E00000000000000000000000000000000000EC
-:1024F00000000000000000000000000000000000DC
-:1025000000000000000000000000000000000000CB
-:1025100000000000000000000000000000000000BB
-:1025200000000000000000000000000000000000AB
-:10253000000000000000000000000000000000009B
-:10254000000000000000000000000000000000008B
-:10255000000000000000000000000000000000007B
-:10256000000000000000000000000000000000006B
-:10257000000000000000000000000000000000005B
-:10258000000000000000000000000000000000004B
-:10259000000000000000000000000000000000003B
-:1025A000000000000000000000000000000000002B
-:1025B000000000000000000000000000000000001B
-:1025C000000000000000000000000000000000000B
-:1025D00000000000000000000000000000000000FB
-:1025E00000000000000000000000000000000000EB
-:1025F00000000000000000000000000000000000DB
-:1026000000000000000000000000000000000000CA
-:1026100000000000000000000000000000000000BA
-:1026200000000000000000000000000000000000AA
-:10263000000000000000000000000000000000009A
-:10264000000000000000000000000000000000008A
-:10265000000000000000000000000000000000007A
-:10266000000000000000000000000000000000006A
-:10267000000000000000000000000000000000005A
-:10268000000000000000000000000000000000004A
-:10269000000000000000000000000000000000003A
-:1026A000000000000000000000000000000000002A
-:1026B000000000000000000000000000000000001A
-:1026C000000000000000000000000000000000000A
-:1026D00000000000000000000000000000000000FA
-:1026E00000000000000000000000000000000000EA
-:1026F00000000000000000000000000000000000DA
-:1027000000000000000000000000000000000000C9
-:1027100000000000000000000000000000000000B9
-:1027200000000000000000000000000000000000A9
-:102730000000000000000000000000000000000099
-:102740000000000000000000000000000000000089
-:102750000000000000000000000000000000000079
-:102760000000000000000000000000000000000069
-:102770000000000000000000000000000000000059
-:102780000000000000000000000000000000000049
-:102790000000000000000000000000000000000039
-:1027A0000000000000000000000000000000000029
-:1027B0000000000000000000000000000000000019
-:1027C0000000000000000000000000000000000009
-:1027D00000000000000000000000000000000000F9
-:1027E00000000000000000000000000000000000E9
-:1027F00000000000000000000000000000000000D9
-:1028000000000000000000000000000000000000C8
-:1028100000000000000000000000000000000000B8
-:1028200000000000000000000000000000000000A8
-:102830000000000000000000000000000000000098
-:102840000000000000000000000000000000000088
-:102850000000000000000000000000000000000078
-:102860000000000000000000000000000000000068
-:102870000000000000000000000000000000000058
-:102880000000000000000000000000000000000048
-:102890000000000000000000000000000000000038
-:1028A0000000000000000000000000000000000028
-:1028B0000000000000000000000000000000000018
-:1028C0000000000000000000000000000000000008
-:1028D00000000000000000000000000000000000F8
-:1028E00000000000000000000000000000000000E8
-:1028F00000000000000000000000000000000000D8
-:1029000000000000000000000000000000000000C7
-:1029100000000000000000000000000000000000B7
-:1029200000000000000000000000000000000000A7
-:102930000000000000000000000000000000000097
-:102940000000000000000000000000000000000087
-:102950000000000000000000000000000000000077
-:102960000000000000000000000000000000000067
-:102970000000000000000000000000000000000057
-:102980000000000000000000000000000000000047
-:102990000000000000000000000000000000000037
-:1029A0000000000000000000000000000000000027
-:1029B0000000000000000000000000000000000017
-:1029C0000000000000000000000000000000000007
-:1029D00000000000000000000000000000000000F7
-:1029E00000000000000000000000000000000000E7
-:1029F00000000000000000000000000000000000D7
-:102A000000000000000000000000000000000000C6
-:102A100000000000000000000000000000000000B6
-:102A200000000000000000000000000000000000A6
-:102A30000000000000000000000000000000000096
-:102A40000000000000000000000000000000000086
-:102A50000000000000000000000000000000000076
-:102A60000000000000000000000000000000000066
-:102A70000000000000000000000000000000000056
-:102A80000000000000000000000000000000000046
-:102A90000000000000000000000000000000000036
-:102AA0000000000000000000000000000000000026
-:102AB0000000000000000000000000000000000016
-:102AC0000000000000000000000000000000000006
-:102AD00000000000000000000000000000000000F6
-:102AE00000000000000000000000000000000000E6
-:102AF00000000000000000000000000000000000D6
-:102B000000000000000000000000000000000000C5
-:102B100000000000000000000000000000000000B5
-:102B200000000000000000000000000000000000A5
-:102B30000000000000000000000000000000000095
-:102B40000000000000000000000000000000000085
-:102B50000000000000000000000000000000000075
-:102B60000000000000000000000000000000000065
-:102B70000000000000000000000000000000000055
-:102B80000000000000000000000000000000000045
-:102B90000000000000000000000000000000000035
-:102BA0000000000000000000000000000000000025
-:102BB0000000000000000000000000000000000015
-:102BC0000000000000000000000000000000000005
-:102BD00000000000000000000000000000000000F5
-:102BE00000000000000000000000000000000000E5
-:102BF00000000000000000000000000000000000D5
-:102C000000000000000000000000000000000000C4
-:102C100000000000000000000000000000000000B4
-:102C200000000000000000000000000000000000A4
-:102C30000000000000000000000000000000000094
-:102C40000000000000000000000000000000000084
-:102C50000000000000000000000000000000000074
-:102C60000000000000000000000000000000000064
-:102C70000000000000000000000000000000000054
-:102C80000000000000000000000000000000000044
-:102C90000000000000000000000000000000000034
-:102CA0000000000000000000000000000000000024
-:102CB0000000000000000000000000000000000014
-:102CC0000000000000000000000000000000000004
-:102CD00000000000000000000000000000000000F4
-:102CE00000000000000000000000000000000000E4
-:102CF00000000000000000000000000000000000D4
-:102D000000000000000000000000000000000000C3
-:102D100000000000000000000000000000000000B3
-:102D200000000000000000000000000000000000A3
-:102D30000000000000000000000000000000000093
-:102D40000000000000000000000000000000000083
-:102D50000000000000000000000000000000000073
-:102D60000000000000000000000000000000000063
-:102D70000000000000000000000000000000000053
-:102D80000000000000000000000000000000000043
-:102D90000000000000000000000000000000000033
-:102DA0000000000000000000000000000000000023
-:102DB0000000000000000000000000000000000013
-:102DC0000000000000000000000000000000000003
-:102DD00000000000000000000000000000000000F3
-:102DE00000000000000000000000000000000000E3
-:102DF00000000000000000000000000000000000D3
-:102E000000000000000000000000000000000000C2
-:102E100000000000000000000000000000000000B2
-:102E200000000000000000000000000000000000A2
-:102E30000000000000000000000000000000000092
-:102E40000000000000000000000000000000000082
-:102E50000000000000000000000000000000000072
-:102E60000000000000000000000000000000000062
-:102E70000000000000000000000000000000000052
-:102E80000000000000000000000000000000000042
-:102E90000000000000000000000000000000000032
-:102EA0000000000000000000000000000000000022
-:102EB0000000000000000000000000000000000012
-:102EC0000000000000000000000000000000000002
-:102ED00000000000000000000000000000000000F2
-:102EE00000000000000000000000000000000000E2
-:102EF00000000000000000000000000000000000D2
-:102F000000000000000000000000000000000000C1
-:102F100000000000000000000000000000000000B1
-:102F200000000000000000000000000000000000A1
-:102F30000000000000000000000000000000000091
-:102F40000000000000000000000000000000000081
-:102F50000000000000000000000000000000000071
-:102F60000000000000000000000000000000000061
-:102F70000000000000000000000000000000000051
-:102F80000000000000000000000000000000000041
-:102F90000000000000000000000000000000000031
-:102FA0000000000000000000000000000000000021
-:102FB0000000000000000000000000000000000011
-:102FC0000000000000000000000000000000000001
-:102FD00000000000000000000000000000000000F1
-:102FE00000000000000000000000000000000000E1
-:102FF00000000000000000000000000000000000D1
-:00000001FF
--- zfcpdump-kernel-4.4.orig/firmware/yamaha/ds1_dsp.fw.ihex
+++ /dev/null
@@ -1,9 +0,0 @@
-:1000000081000000A40100000A0000002F00000091
-:1000100053020800170380017B4000003F8400006A
-:100020003C4801003C9401003CD805003C1C000009
-:100030007BC000003F0C05003C5021010000000087
-:1000400000000000000000000000000000000000B0
-:1000500000000000000000000000000000000000A0
-:100060000000000000000000000000000000000090
-:100070000000000000000000000000000000000080
-:00000001FF
--- zfcpdump-kernel-4.4.orig/firmware/yamaha/ds1e_ctrl.fw.ihex
+++ /dev/null
@@ -1,769 +0,0 @@
-:10000000070000000700240007000C0007001C0088
-:1000100007000600020070002000000040000300FE
-:100020000471000086420000400003000D0F000034
-:10003000100800003A042000820200000D020000B7
-:10004000100800003A04200082120000820E2000F6
-:100050000D800000100800003A042000821A000001
-:100060000D460300100800003A0410000DEC0200D9
-:10007000100800003A0418000D01000015000200ED
-:10008000FD00000020000000608803006090030075
-:100090006080030040800300408003004080030034
-:1000A000408001007D0A0000408003004080030082
-:1000B0004080010002042000820800001A000800AD
-:1000C00004090000867101000700000007002600F7
-:1000D00007004000070000008D2503001008000005
-:1000E0003A04180007002600024428007D0800009A
-:1000F000428001000A16000006A205000700000069
-:10010000070044000D230000100800003A04080016
-:1001100006FA220007000000FD07000042800100EF
-:100120000A0008000409000086AB020095010000E7
-:10013000040D09000700000020080000F500000081
-:100140007D0B000060F00100FD000000063A030096
-:10015000408001007D0A0000428003004A801300B5
-:100160000A00180020180000609005006088050053
-:1001700040800100FD000000428001000A00700084
-:100180001501000044110700863B03000000030036
-:100190002070000006620300408001000D36000060
-:1001A000100800003A04080006222300070000009F
-:1001B0000DEC0200100800003A041800069A010035
-:1001C00007000000070024008D0F00001008000049
-:1001D0003A16000002240000025C0000FD28000026
-:1001E00020000000408001000D00080015080000FC
-:1001F00084095100070000004D0000005D0E000062
-:10020000020E00000D430000100800003A04080030
-:1002100006122E00070000008D00000024090000D7
-:10022000020F00000D470000100800003A0408000B
-:1002300006122E0007000000800448001012000083
-:100240003A0428008D770000100800003A0C2800BE
-:100250008D060000100800003A142800024428000F
-:100260008D250300100800003A0418008DFF0700D8
-:1002700020080000FD020000408001000700260069
-:1002800007002000FD020000428001000A00080073
-:100290000409000086120500070000000700240082
-:1002A0000DEC0200100800003A0418007D38000030
-:1002B000428001000A0008001510000084090100B6
-:1002C000869B01000700000006B201000700000045
-:1002D000FD080000428001000A0018000419000017
-:1002E00086B8220007002800101800003A042800F1
-:1002F000020C28000D000000100800003A1428002D
-:100300008D80080020080000FD02000040800100F0
-:10031000070020000D0200000499180007000000EB
-:100320002D400000BD000000FD02000042800100E1
-:100330000A00080004090000865A060007000000B1
-:1003400000010000200A00007D0400004080010040
-:10035000428001000A002000153000004421010005
-:10036000866103000700000004210000866103008D
-:10037000070000008D0F0000100800003A0C280054
-:100380004439020086C90700070000001018000069
-:100390003A0428000D81080020080000FD0200003A
-:1003A0004080010007002000102800003A0078007B
-:1003B0008D780000100800003A04080006122A0098
-:1003C000070000000D4000001510000004991800FF
-:1003D000042929000439390007000000060207003B
-:1003E00007000000F50400007D0000002000000070
-:1003F0008D00000060080100408001007D040000C5
-:10040000428003004A8021000A00180044190200BB
-:1004100086902200070000007540000004F1710082
-:1004200007000000420001000A0028000429000023
-:1004300086582200070000000D3C000004A930008F
-:10044000070000007D070000428001000A0008004C
-:100450000409000086DA08007D050000202800005D
-:1004600060B0030006F20800408001002030000068
-:1004700060A8030040800100FD02000042800100EE
-:100480000A0008000409000086FA080007000000BE
-:100490007D050000428001000A0428008D0E000046
-:1004A000100800003A0C28000D00000010080000A1
-:1004B0003A1428000D00090020080000FD02000089
-:1004C0004080010007002000FD3D000020000000EA
-:1004D000408001007D1000008D9D0000100800008C
-:1004E0003A04080006122A00070000001508000060
-:1004F0001A0008008409010086510A007D130000DB
-:1005000000052000200F2800608F3300608F3B0023
-:10051000608F4300608F4B00608F5300608F5B00E3
-:10052000608A0300408001007D10000042800100CD
-:100530000A000800150200008409010086813A00C3
-:1005400007000000BD7F0000C43D38000700000028
-:100550007D1A000075130000428001004A00090066
-:100560000A001000048D0B00049513000700000022
-:10057000200800006090010004110000865822004D
-:1005800040000100FD170000428001000A00080041
-:1005900004090000865A2200070000007D190000AF
-:1005A000428003004A8009000A001000240900006C
-:1005B00064160000FD110000428003004A802B00F9
-:1005C0004A8019008D0000004489210007000000C6
-:1005D0004422000086190C0007000000641A000085
-:1005E000242A00007D1900000201080022011000E9
-:1005F000200800006090030040800100FD3D0000E5
-:100600008D000000200800004080010075130000EC
-:100610007D1A0000420001004A8009000A00100013
-:100620001D020000E4890100E49229004491300099
-:10063000070000000D060000150A00001D0C000058
-:1006400025100000E4A90000E42B01006404000070
-:10065000E4B30100E432020064040000640400001A
-:1006600064040000640400000D040000C4B108002C
-:100670000700000020080000F50B00004000030008
-:100680007D190000428003004A800900240A00000E
-:100690000A000800640E0800070000002201100094
-:1006A000200800006010030040000100AC6400005E
-:1006B0007D02000020000000408001007D1000004D
-:1006C00042800100FD1100004A803B004A80090081
-:1006D0000A0020009500000044111A0044A1000007
-:1006E00086580E000D04000084B9000086590E00E3
-:1006F000FD18000042800100FD1000004A80090042
-:100700000A0028009500000024090100642A000066
-:1007100086490E000700000004290000865A0E00DA
-:100720000700000006620E00020008008D000000B5
-:100730007D38000020080000408001007D1200008C
-:10074000428001000A0010000439000086090F00F1
-:100750000D080000B5FF7F0084B9000086D90E00A7
-:100760002500000006B20F002D000000150000005B
-:100770002D0800000DE002002008000006FA0F001E
-:100780000D00000035807F0084B9000086A90F00AD
-:10079000250040008D000000440911000700000002
-:1007A0008D01000004951000070000006491000016
-:1007B00024040000240400002404000002011000AE
-:1007C000020028000DDF02002008000006FA0F00DA
-:1007D0008D0100002D0400008D0000000495100024
-:1007E000070000000D0200008491100007000000C7
-:1007F0008DDF0200200800008D000000FD380000A1
-:1008000040800100FD3B00002010000060A80300B4
-:100810001508000084313100842121000700000008
-:1008200060B0030060A0030040800100FD220000D2
-:1008300095000000240901002404000024040000A5
-:100840006412000002011000200800006090030004
-:1008500040800100241900000D0F01007D390000C7
-:100860002008000040800500428003004A840900FF
-:10087000060600000A040800240400002404000006
-:100880007D110000428001000A000800240A0000D7
-:1008900002052800020C28000D8009002008000035
-:1008A000FD0200004080010007002000FD22000042
-:1008B000428001000A00080095000000C40D2800D5
-:1008C000241901007D19000042800100FD11000083
-:1008D0004A8009000A001000B500000044311100F0
-:1008E000048D0A0007000000440A08000495120065
-:1008F00007000000FD2300002010000040800300DE
-:10090000441210000700000020080000609003005F
-:1009100040800100FD020000428001000A00080042
-:10092000040900008632120007000000FD3B0000B1
-:1009300000010000100A00007A800B004A801300BA
-:10094000840909000700000095000000043D010033
-:1009500086B812000A001000020010008409090085
-:1009600007000000428003004A801100040D0900C6
-:10097000070000000A001000840D090007000000B5
-:100980007D25000020080000408001000D010000CE
-:10099000100800003A1428007D1200004280010077
-:1009A0000A0020007D190000428001007D11000036
-:1009B0004A8031000A001000243100008D3B010004
-:1009C0007D390000200800004080050042800300BF
-:1009D0004A840900060600000A04080002013000EB
-:1009E000243100002404000024040000241200002C
-:1009F000020528004C1A000086391400020070001D
-:100A00002D000000000003007D380000428001003E
-:100A10000A0010000662140024210000AD0000004E
-:100A2000020010000D01000024090000246B0000EA
-:100A30000D4A01007D3900002008000040800500BB
-:100A4000428003004A840900060600000A040800E8
-:100A5000643200008D000000240A00002010000015
-:100A60007D220000408001008D4F01001008000031
-:100A70003A040800065A2B00070000002028000056
-:100A80007D200000408001007D11000042800300B5
-:100A90004A8013000A8033007D3800004280010044
-:100AA0000A00080004090000867217000700000011
-:100AB0008D000000640903000D5B01007D3900001A
-:100AC0002008000040800500428003004A8409009D
-:100AD000060600000A040800020138002404000091
-:100AE0002404000024120000FD02000042800100E6
-:100AF0000A0008000409000086DA1500070000005B
-:100B0000020528004C1A000086711700070000003B
-:100B1000642103002C630000FD3D000042800100C1
-:100B20000A00080095000000040909000700000001
-:100B3000200800004C1A0000869916004080010031
-:100B40000000030006B21600242100000D01000081
-:100B500024090000246B00000D6F01007D390000A6
-:100B60002008000040800500428003004A840900FC
-:100B7000060600000A040800643A00009500000020
-:100B800024120000FD020000428001000A0008005B
-:100B90000409000086121700070000000D7601000E
-:100BA000100800003A040800065A2B000700000055
-:100BB000060A160007000000207000000A01080065
-:100BC0002A011000FD2000006088030060900300EF
-:100BD000408001007D22000042800100FD3D0000B8
-:100BE0000A0008004A843100040900008610180039
-:100BF0008B0018008D000000049918002C310000B3
-:100C000006E21800070000004C320000866B180056
-:100C100007000000041900008668180007000000A3
-:100C200095000000449119002C220000243100009E
-:100C30006C6300003D0E000075130000FD0B00000A
-:100C4000420001004A8009000A001000EC8A0300FB
-:100C5000EC9303004C22000086E11800070000001E
-:100C60008D000000049918006C2200002C32000056
-:100C70000A053000AB1D300083200000FD18000085
-:100C8000428001000A0008002489010002053000AA
-:100C90008310000075180000420001000A001000D7
-:100CA0008D00000024090100751300004205330087
-:100CB000CB0C3300CB2C3300CB343300CB3C330094
-:100CC000CB443300CB4C3300CB5433008B5C30002F
-:100CD00083600000F5020000420001000A000800E5
-:100CE0000409000086B21900070000002D1E000054
-:100CF000FD050000428001000A000800248902006E
-:100D0000020528000D060000100800003A0C28001B
-:100D10008D000000100800003A1428008D800A00A1
-:100D200020080000F502000040000100070022003A
-:100D300075120000420003004A0021008D000000EF
-:100D400044091A00070000008DAB010010080000E4
-:100D50003A04080006AA2C0007000000F501000074
-:100D6000420003004A000D000A00100044910800F0
-:100D7000070000002008000040000100F5250000E9
-:100D800044310A000700000020080000602803002A
-:100D9000400003007D210000428003004A800B00D8
-:100DA0000A0010002008000060100300400003004B
-:100DB0008D000000240100002C010000640E0000E2
-:100DC000641A00006C6300000A0108002A01100088
-:100DD000200800006010030040000300FD20000018
-:100DE000428001000A0008007D22000042800100CC
-:100DF0000A001000200800006010030040000300FB
-:100E00007D190000428001000A000800FD22000058
-:100E1000428003000A001000200800006010030058
-:100E200040000300040D0900070000002008000036
-:100E300040000300428003004A800B000A001000BB
-:100E400020080000601003004000030042800300FF
-:100E50004A8013004A801900040D1100048D190006
-:100E6000070000000A0008002010000060180300BE
-:100E700060080300400003008D00000044090B00DF
-:100E8000070000002008000040000100F5050000F8
-:100E9000420003000A000800200800004000010092
-:100EA000F5000000420001000A00080004090000EB
-:100EB00086981D00751E0000420003004A040100D0
-:100EC0000A0C000006AA1D00070000000204000032
-:100ED000020C00007D170000F51A0000428001009E
-:100EE0004A1403004A1C03004A2403004A2C03004E
-:100EF0004A3403004A3C03004A4403000A4C000001
-:100F00003D040000F5130000FD1A0000420003003C
-:100F10004A000B004A801B004A8013000A00200090
-:100F20004491080044A11900E4890300EC990300EE
-:100F3000025500000A5D0000420003004A000B0059
-:100F40004A801B004A8013000A00200044910800D8
-:100F500044A11900E4890300EC9903000265000034
-:100F60000A6D0000420003004A000B004A0019000D
-:100F70004A802B004A8013004A8021000A0030007A
-:100F80004491080044A1190044B12A00E4890300F7
-:100F9000EC990300027500000A7D0000E4A903003B
-:100FA000020700007D1000001504000042800100CF
-:100FB0000A000800E4090100020F0000F52A000001
-:100FC000FD190000420001004A8009000A001000DB
-:100FD0003409000074160000F529000042000100E9
-:100FE0000A0010007C910000752000004200010002
-:100FF0000A00080004090000860A2000F526000007
-:10100000F5270000420003004A0009000A00100012
-:101010003C0A00007C160000751A0000FD0B000061
-:10102000420001004A8051000A00480007001600F3
-:1010300075100000420001000A2C2800121D280033
-:1010400012252800321F000007001E0007000E00B6
-:101050007519000042000100F52D00004A000D0046
-:101060000A0010004491000086EA200042000100BE
-:101070000A3428005D0E00008D000000750300009A
-:101080002008000040000100F4D2050004D1540003
-:101090005C730000868B21000700000007000C0035
-:1010A0000700080007000A008D1702001008000062
-:1010B0003A04080006B2340007000000069221003E
-:1010C0000700000007000800752200004200010030
-:1010D0000A00200004210000865822002D1E000076
-:1010E000F5020000420001000A00080004090000A7
-:1010F00086CA210007000000102000003A043000DA
-:101100007D050000C38001000A0008002489020058
-:1011100002052800020C28000D810A0020080000AA
-:10112000F50200004000010007002200FD0400005D
-:10113000428001000A0070000000030020700000DF
-:1011400006FA0700408001008D2B02001008000005
-:101150003A04080006AA2C0007000000FD02000067
-:10116000428001000A0008000409000086C2220033
-:1011700007000000060202000700000075080000DA
-:10118000FD0900000D010000064223009502000049
-:10119000750B00007D0900000D0000001505000022
-:1011A000420001000A0018000419000086002A000D
-:1011B000F50600002010000040000100F5040000CA
-:1011C00020080000400001007507000042000100F7
-:1011D0004A8009000A0010002411000004090000E0
-:1011E00086F2230015080000020108000412100016
-:1011F0000612240075050000041208000700000014
-:1012000002011000750500002504000024110200F1
-:1012100002011000200800006010030040000100DF
-:101220002419000086002A008D00000064040000DC
-:10123000049D0000861029000201180075050000B9
-:10124000420001000A0428008D010000240900006A
-:10125000020D28000D0000002409000002152800DE
-:101260000D00100020080000F50200004000010001
-:101270000700200075110000FD02000042800100FF
-:101280000A0008000409000086FA24000700000094
-:1012900000010000200B0800600B1300600B1B0016
-:1012A000600A030040000100420005004A003D00C2
-:1012B0004A0035004A002D000A002000F506000013
-:1012C000420001000A142800F50400004200010059
-:1012D0000A00080015030000040D01008602260024
-:1012E0001540000095000000040D010086F0250067
-:1012F000220010002A001000061A26000700000035
-:101300000431330004A92A0007000000242103004F
-:1013100002052800024428002411000002014000B8
-:101320002404000024040000243200002C290000C2
-:101330006C630000867327000700000064B10200A0
-:1013400064040000640400008D000000640A0000D2
-:10135000020D28008D00100020080000F50200009A
-:1013600040000100070022008D00000004B9380091
-:10137000070000006C2903000A013000F50200009C
-:10138000420001000A00080004090000860227004C
-:10139000070000002C2100000A0528006C31000025
-:1013A0006C0400006C0400000A45280024110000B1
-:1013B000646B0000020110008D0000006C09010048
-:1013C0000A0D28000D01100020080000F5020000A1
-:1013D0004000010007002200244100002404000016
-:1013E00024040000243200000201300044290300DC
-:1013F00086FA27000700000002003000F504000014
-:10140000420001000A00080015030000040D01005D
-:1014100086402800243100006404000002013000EE
-:10142000F5020000420001000A0008000409000063
-:10143000864A2800070000000244280024310000EA
-:1014400002053000243900008305300083080000C5
-:10145000F5050000420001000A0428008D0000008C
-:1014600024810000020D28008D000000248100006E
-:10147000021528008D01100020080000F502000070
-:101480004000010007002200251000007505000043
-:10149000420003004A0009000A00100004090A0083
-:1014A0000411120007000000201000006008050071
-:1014B00040000500FD060000428001004A000900CE
-:1014C0000A001000A500000004090A00041112001F
-:1014D00007000000200800006090010040000100AB
-:1014E000F5020000420001000A00080004090000A3
-:1014F00086CA2900070000000642240007000000F9
-:101500000606000007000000F5020000420001008E
-:101510000A00080004090000861A2A0007000000DB
-:1015200000010000200B0800608B1300608B1B0083
-:10153000608B2300608B2B00608B3300608B3B0043
-:10154000608B4300608B4B00608B5300608B5B00B3
-:10155000608B6300608B6B00608B7300608B7B0023
-:10156000608F0300608F0B00608F1300608F1B0083
-:10157000608F2300608F2B00608F3300608F3B00F3
-:10158000608F4300608F4B00608F5300608F5B0063
-:10159000608F6300608F6B00608F7300608F7B00D3
-:1015A000608A030006060000408001008D000000F4
-:1015B000640A0000020D2800240A00007D020000D9
-:1015C000428001000A00100024120000FD03000008
-:1015D000428001000A00080004090000860A2C006D
-:1015E000070000008D010000240A000064040000D0
-:1015F0006404000002010800240900002404000023
-:1016000024040000020110000D00020044910000BB
-:1016100086612C0007000000FD01000042800100EF
-:101620000A000800440A000086432C0042800100A2
-:101630000D000A0020080000FD02000040800100AB
-:10164000070020007D0200002010000006060000B8
-:1016500040800100F5020000420001000A0008007D
-:101660000409000086B22C00070000007D03000082
-:10167000428001000A0008000409000086E22C00F4
-:1016800007000000750000007D2E000042000100F0
-:101690004A800B00200000000409000086060000BC
-:1016A000400001004A8431008B04300083080000B0
-:1016B0008D000000100800003A1428008D00000082
-:1016C000100800003A0C28007506000042000100D6
-:1016D0000A0008001538000024090100020528004E
-:1016E0000D000B0020080000F50200004000010082
-:1016F00006060000070022006404000064040000E5
-:101700000606000007000000340100008D7F000085
-:101710003C090000121D280012252800321F00007D
-:1017200007000E000D0100007D03000020080000EE
-:1017300040800100F4D20500070000000700080007
-:101740007D030000428001000A0008000409000037
-:10175000868A2E0007000000060600000700000031
-:101760000700000012000000070010000700320010
-:101770000700600007004600800010001A004800C3
-:101780000449000086F12E0007000000101200003E
-:101790003A00580045010000045D5C0007000000AD
-:1017A000800000001A0048000449000086412F0014
-:1017B00007000000101200003A0050000459000019
-:1017C00086982F0045000000C5000000F5FF7F004F
-:1017D0007DFF7F0024D50700244200000201500055
-:1017E00002052000820000001A00400004410000B1
-:1017F00086C92F0007000000653800001A0040006D
-:10180000204000004D10000084C1040086AB310070
-:1018100040000000070004006501000045010000D1
-:101820002040000040000000650700008000080024
-:101830001A004000044100008659300007000000F3
-:10184000101200003A0040000441000086B230004F
-:101850004D000000CD000000104800003A042000B8
-:10186000820800001A0040000441000086C13000D8
-:10187000070000002048000004590000869831004D
-:1018800040000000E507000080042000A0162800AA
-:10189000E0163200E0163A00E01642006012020044
-:1018A0004000000032000000750040007D00000094
-:1018B00074D5070012052000820000001A004000C5
-:1018C000044100008671310007000000068A030011
-:1018D00007006400E5000000200000004000000058
-:1018E000650A0000200000004000020040000200E5
-:1018F0004000000065010000420000000A00700086
-:101900000471000086323200070000000700060064
-:10191000069A010007006400000005002070000026
-:1019200040000000068A0300070064000700000072
-:101930006D30000060880200609002000A0008001C
-:101940006088020040800000120010000D100000AE
-:101950008491000086D132000D0E000084910000B9
-:1019600086E133000700000007003000201000006F
-:101970006D3B000040800000800000001A0008005D
-:101980000409000086F13200070000002012000068
-:10199000ED0D000040800000428000000A001000B1
-:1019A0000D004000449510000700000020100000CA
-:1019B000ED0D000040800000428000000A0420007D
-:1019C000820000001A00080004090000868133002C
-:1019D000070000006D3B0000428000000A00080084
-:1019E000150E000084090100862B340007006000FA
-:1019F0001A000800150C0000840901008613340049
-:101A00002000000007001A00ED02000040800000E6
-:101A1000070062006D300000428002004A800A0028
-:101A2000200800004A800A00060600004A801000D4
-:101A30000700000012252800321F0000F4D2050024
-:101A400004D154005C73000086070000070000000A
-:101A500007000C0007000A0007001C0065340000A6
-:101A60004000020020480000605002000A004000D0
-:101A700060400200400000004449450007000000AB
-:101A800020400000E53A000040000000E52800008A
-:101A9000420000000A0048000449000086F83900AE
-:101AA000652C0000420000000A004000D500000044
-:101AB00004414500070000005506000004450500EC
-:101AC00086823600D5010000044505008680360078
-:101AD000652B000042000000E53A00004A0050007B
-:101AE0000A004000D4C3450007000000044545003B
-:101AF00007000000CD00000044494400070000003A
-:101B000004454500070000004D0100004449550010
-:101B1000070000004451040086793600652C00005F
-:101B2000420000000A00480004D14C0007000000F9
-:101B300044C1040086833600070000000700160039
-:101B4000E52C0000420004000A0040002040000094
-:101B50004000000065290000420000000A0040002B
-:101B60000441000086F03600070000000224000057
-:101B700006323800025C0000E5250000420000004B
-:101B80000A00400074420000E52A00004200000004
-:101B90000A0040007442000012015000E5290000D4
-:101BA000420000000A0040003442000004414500A9
-:101BB000070000002040000040000000E53E00005B
-:101BC0002000000040000000E52D00005201400010
-:101BD0000A0050004451040086DA3700C5000000B6
-:101BE000E53E00002040000040000000E52B000022
-:101BF000420000000A00400054424000070000007C
-:101C0000E52A0000204000004000000032015000A2
-:101C10003401040074560000E5290000420002006F
-:101C20000A004200420000000A0050007C4105000A
-:101C3000E5280000420000000A004800C50000003E
-:101C400044C14C0086A03800E5260000E5270000CE
-:101C5000420002004A0040000A0050003C420000DE
-:101C60007C560000E52800002048000040000000ED
-:101C7000121D280012252800721F0000652900008F
-:101C8000420000000A00400004410000863A39008A
-:101C900007000E000700160007001E00E53E0000CA
-:101CA000420000000A00400004410000867839002C
-:101CB000652D0000420000000A3428006534000051
-:101CC000420002004A004200204000004A004A0050
-:101CD0004A005000F4D2050004D154005C730000A7
-:101CE00086E1390007000000060600000700080032
-:101CF00007000C000700080007000A00E5010000CB
-:101D00004500020020400000600000006503000064
-:101D100040000000652E0000201A0000601A0A0032
-:101D20004000000065340000420002004A0042000A
-:101D3000204000004A004A00060600004A00500009
-:101D4000FD170000428001000A000800040900009D
-:101D5000865A2200070000007D100000428001002A
-:101D6000FD1100004A8033004A8019000A0020005B
-:101D70009500000044112A0044A1010086903B0018
-:101D80000D04000084B1000086913B00FD180000A6
-:101D900042800100FD1000004A8009000A0038005E
-:101DA0009500000024090100643A000086813B0090
-:101DB000070000000439000086923B000700000085
-:101DC000069A3B000D0000008D0000002008000076
-:101DD0007D38000040800100020070007D1100008D
-:101DE000428001007D1900004A8029000A0030006D
-:101DF0000200380024310000240400002404000004
-:101E0000242A0000020528008D06000010080000AA
-:101E10003A1428000D75000024B10000642200006F
-:101E200086033D0002442800100800003A0C2800F8
-:101E30000D800B0020080000FD0200004080010022
-:101E4000070020008D75000024B100000201100081
-:101E50004421010086493E00101800003A0010009D
-:101E60007D380000428001000A00080004090000DB
-:101E700086483E0000000300064A3E00BD00000008
-:101E80008D00000064310200640A0000020D280089
-:101E90008D800B0020080000FD0200004080010042
-:101EA000070020007D380000428001000A00080081
-:101EB0000409000086323E0000000300FD0200001D
-:101EC000428001000A0008000409000086823D00EB
-:101ED00007000000102800003A0428000D750000DB
-:101EE0002409030064220000020D28006C31020066
-:101EF0000A4528000D810B0020080000FD020000AB
-:101F000040800100070020008D000000240A00002E
-:101F1000064A3E0002011000101800003A001000AE
-:101F2000BD000000103800003A0430007D180000A9
-:101F300042800100FD1800004A8009000A002000CC
-:101F4000AD000000248902002C21070010100000C1
-:101F5000830530008B0D3000BB143000831C300033
-:101F6000832000007D130000428003004A84330078
-:101F7000CBAC3300CBB43300CBBC3300CBC4330089
-:101F8000CBCC3300CBD433008B5C300083600000BB
-:101F90000D1E0000FD050000428001000A00200027
-:101FA000240902008D0600006CA900009D000000BD
-:101FB000FD020000428001000A0008000409000040
-:101FC000866A3F0007000000020528000A0D28006D
-:101FD00002442800101800003A1428008D000C005C
-:101FE00020080000FD0200004080010007002200E0
-:101FF00004390000865822000D1E00007D050000F7
-:10200000428001000A00200024090200A50000000F
-:10201000FD020000428001000A00080004090000DF
-:10202000862A40000700000002052800020C280054
-:10203000102000003A1428000D010C0020080000B8
-:10204000FD02000040800100065A22000700220025
-:102050000000000000000000000000000000000080
-:102060000000000000000000000000000000000070
-:102070000000000000000000000000000000000060
-:102080000000000000000000000000000000000050
-:102090000000000000000000000000000000000040
-:1020A0000000000000000000000000000000000030
-:1020B0000000000000000000000000000000000020
-:1020C0000000000000000000000000000000000010
-:1020D0000000000000000000000000000000000000
-:1020E00000000000000000000000000000000000F0
-:1020F00000000000000000000000000000000000E0
-:1021000000000000000000000000000000000000CF
-:1021100000000000000000000000000000000000BF
-:1021200000000000000000000000000000000000AF
-:10213000000000000000000000000000000000009F
-:10214000000000000000000000000000000000008F
-:10215000000000000000000000000000000000007F
-:10216000000000000000000000000000000000006F
-:10217000000000000000000000000000000000005F
-:10218000000000000000000000000000000000004F
-:10219000000000000000000000000000000000003F
-:1021A000000000000000000000000000000000002F
-:1021B000000000000000000000000000000000001F
-:1021C000000000000000000000000000000000000F
-:1021D00000000000000000000000000000000000FF
-:1021E00000000000000000000000000000000000EF
-:1021F00000000000000000000000000000000000DF
-:1022000000000000000000000000000000000000CE
-:1022100000000000000000000000000000000000BE
-:1022200000000000000000000000000000000000AE
-:10223000000000000000000000000000000000009E
-:10224000000000000000000000000000000000008E
-:10225000000000000000000000000000000000007E
-:10226000000000000000000000000000000000006E
-:10227000000000000000000000000000000000005E
-:10228000000000000000000000000000000000004E
-:10229000000000000000000000000000000000003E
-:1022A000000000000000000000000000000000002E
-:1022B000000000000000000000000000000000001E
-:1022C000000000000000000000000000000000000E
-:1022D00000000000000000000000000000000000FE
-:1022E00000000000000000000000000000000000EE
-:1022F00000000000000000000000000000000000DE
-:1023000000000000000000000000000000000000CD
-:1023100000000000000000000000000000000000BD
-:1023200000000000000000000000000000000000AD
-:10233000000000000000000000000000000000009D
-:10234000000000000000000000000000000000008D
-:10235000000000000000000000000000000000007D
-:10236000000000000000000000000000000000006D
-:10237000000000000000000000000000000000005D
-:10238000000000000000000000000000000000004D
-:10239000000000000000000000000000000000003D
-:1023A000000000000000000000000000000000002D
-:1023B000000000000000000000000000000000001D
-:1023C000000000000000000000000000000000000D
-:1023D00000000000000000000000000000000000FD
-:1023E00000000000000000000000000000000000ED
-:1023F00000000000000000000000000000000000DD
-:1024000000000000000000000000000000000000CC
-:1024100000000000000000000000000000000000BC
-:1024200000000000000000000000000000000000AC
-:10243000000000000000000000000000000000009C
-:10244000000000000000000000000000000000008C
-:10245000000000000000000000000000000000007C
-:10246000000000000000000000000000000000006C
-:10247000000000000000000000000000000000005C
-:10248000000000000000000000000000000000004C
-:10249000000000000000000000000000000000003C
-:1024A000000000000000000000000000000000002C
-:1024B000000000000000000000000000000000001C
-:1024C000000000000000000000000000000000000C
-:1024D00000000000000000000000000000000000FC
-:1024E00000000000000000000000000000000000EC
-:1024F00000000000000000000000000000000000DC
-:1025000000000000000000000000000000000000CB
-:1025100000000000000000000000000000000000BB
-:1025200000000000000000000000000000000000AB
-:10253000000000000000000000000000000000009B
-:10254000000000000000000000000000000000008B
-:10255000000000000000000000000000000000007B
-:10256000000000000000000000000000000000006B
-:10257000000000000000000000000000000000005B
-:10258000000000000000000000000000000000004B
-:10259000000000000000000000000000000000003B
-:1025A000000000000000000000000000000000002B
-:1025B000000000000000000000000000000000001B
-:1025C000000000000000000000000000000000000B
-:1025D00000000000000000000000000000000000FB
-:1025E00000000000000000000000000000000000EB
-:1025F00000000000000000000000000000000000DB
-:1026000000000000000000000000000000000000CA
-:1026100000000000000000000000000000000000BA
-:1026200000000000000000000000000000000000AA
-:10263000000000000000000000000000000000009A
-:10264000000000000000000000000000000000008A
-:10265000000000000000000000000000000000007A
-:10266000000000000000000000000000000000006A
-:10267000000000000000000000000000000000005A
-:10268000000000000000000000000000000000004A
-:10269000000000000000000000000000000000003A
-:1026A000000000000000000000000000000000002A
-:1026B000000000000000000000000000000000001A
-:1026C000000000000000000000000000000000000A
-:1026D00000000000000000000000000000000000FA
-:1026E00000000000000000000000000000000000EA
-:1026F00000000000000000000000000000000000DA
-:1027000000000000000000000000000000000000C9
-:1027100000000000000000000000000000000000B9
-:1027200000000000000000000000000000000000A9
-:102730000000000000000000000000000000000099
-:102740000000000000000000000000000000000089
-:102750000000000000000000000000000000000079
-:102760000000000000000000000000000000000069
-:102770000000000000000000000000000000000059
-:102780000000000000000000000000000000000049
-:102790000000000000000000000000000000000039
-:1027A0000000000000000000000000000000000029
-:1027B0000000000000000000000000000000000019
-:1027C0000000000000000000000000000000000009
-:1027D00000000000000000000000000000000000F9
-:1027E00000000000000000000000000000000000E9
-:1027F00000000000000000000000000000000000D9
-:1028000000000000000000000000000000000000C8
-:1028100000000000000000000000000000000000B8
-:1028200000000000000000000000000000000000A8
-:102830000000000000000000000000000000000098
-:102840000000000000000000000000000000000088
-:102850000000000000000000000000000000000078
-:102860000000000000000000000000000000000068
-:102870000000000000000000000000000000000058
-:102880000000000000000000000000000000000048
-:102890000000000000000000000000000000000038
-:1028A0000000000000000000000000000000000028
-:1028B0000000000000000000000000000000000018
-:1028C0000000000000000000000000000000000008
-:1028D00000000000000000000000000000000000F8
-:1028E00000000000000000000000000000000000E8
-:1028F00000000000000000000000000000000000D8
-:1029000000000000000000000000000000000000C7
-:1029100000000000000000000000000000000000B7
-:1029200000000000000000000000000000000000A7
-:102930000000000000000000000000000000000097
-:102940000000000000000000000000000000000087
-:102950000000000000000000000000000000000077
-:102960000000000000000000000000000000000067
-:102970000000000000000000000000000000000057
-:102980000000000000000000000000000000000047
-:102990000000000000000000000000000000000037
-:1029A0000000000000000000000000000000000027
-:1029B0000000000000000000000000000000000017
-:1029C0000000000000000000000000000000000007
-:1029D00000000000000000000000000000000000F7
-:1029E00000000000000000000000000000000000E7
-:1029F00000000000000000000000000000000000D7
-:102A000000000000000000000000000000000000C6
-:102A100000000000000000000000000000000000B6
-:102A200000000000000000000000000000000000A6
-:102A30000000000000000000000000000000000096
-:102A40000000000000000000000000000000000086
-:102A50000000000000000000000000000000000076
-:102A60000000000000000000000000000000000066
-:102A70000000000000000000000000000000000056
-:102A80000000000000000000000000000000000046
-:102A90000000000000000000000000000000000036
-:102AA0000000000000000000000000000000000026
-:102AB0000000000000000000000000000000000016
-:102AC0000000000000000000000000000000000006
-:102AD00000000000000000000000000000000000F6
-:102AE00000000000000000000000000000000000E6
-:102AF00000000000000000000000000000000000D6
-:102B000000000000000000000000000000000000C5
-:102B100000000000000000000000000000000000B5
-:102B200000000000000000000000000000000000A5
-:102B30000000000000000000000000000000000095
-:102B40000000000000000000000000000000000085
-:102B50000000000000000000000000000000000075
-:102B60000000000000000000000000000000000065
-:102B70000000000000000000000000000000000055
-:102B80000000000000000000000000000000000045
-:102B90000000000000000000000000000000000035
-:102BA0000000000000000000000000000000000025
-:102BB0000000000000000000000000000000000015
-:102BC0000000000000000000000000000000000005
-:102BD00000000000000000000000000000000000F5
-:102BE00000000000000000000000000000000000E5
-:102BF00000000000000000000000000000000000D5
-:102C000000000000000000000000000000000000C4
-:102C100000000000000000000000000000000000B4
-:102C200000000000000000000000000000000000A4
-:102C30000000000000000000000000000000000094
-:102C40000000000000000000000000000000000084
-:102C50000000000000000000000000000000000074
-:102C60000000000000000000000000000000000064
-:102C70000000000000000000000000000000000054
-:102C80000000000000000000000000000000000044
-:102C90000000000000000000000000000000000034
-:102CA0000000000000000000000000000000000024
-:102CB0000000000000000000000000000000000014
-:102CC0000000000000000000000000000000000004
-:102CD00000000000000000000000000000000000F4
-:102CE00000000000000000000000000000000000E4
-:102CF00000000000000000000000000000000000D4
-:102D000000000000000000000000000000000000C3
-:102D100000000000000000000000000000000000B3
-:102D200000000000000000000000000000000000A3
-:102D30000000000000000000000000000000000093
-:102D40000000000000000000000000000000000083
-:102D50000000000000000000000000000000000073
-:102D60000000000000000000000000000000000063
-:102D70000000000000000000000000000000000053
-:102D80000000000000000000000000000000000043
-:102D90000000000000000000000000000000000033
-:102DA0000000000000000000000000000000000023
-:102DB0000000000000000000000000000000000013
-:102DC0000000000000000000000000000000000003
-:102DD00000000000000000000000000000000000F3
-:102DE00000000000000000000000000000000000E3
-:102DF00000000000000000000000000000000000D3
-:102E000000000000000000000000000000000000C2
-:102E100000000000000000000000000000000000B2
-:102E200000000000000000000000000000000000A2
-:102E30000000000000000000000000000000000092
-:102E40000000000000000000000000000000000082
-:102E50000000000000000000000000000000000072
-:102E60000000000000000000000000000000000062
-:102E70000000000000000000000000000000000052
-:102E80000000000000000000000000000000000042
-:102E90000000000000000000000000000000000032
-:102EA0000000000000000000000000000000000022
-:102EB0000000000000000000000000000000000012
-:102EC0000000000000000000000000000000000002
-:102ED00000000000000000000000000000000000F2
-:102EE00000000000000000000000000000000000E2
-:102EF00000000000000000000000000000000000D2
-:102F000000000000000000000000000000000000C1
-:102F100000000000000000000000000000000000B1
-:102F200000000000000000000000000000000000A1
-:102F30000000000000000000000000000000000091
-:102F40000000000000000000000000000000000081
-:102F50000000000000000000000000000000000071
-:102F60000000000000000000000000000000000061
-:102F70000000000000000000000000000000000051
-:102F80000000000000000000000000000000000041
-:102F90000000000000000000000000000000000031
-:102FA0000000000000000000000000000000000021
-:102FB0000000000000000000000000000000000011
-:102FC0000000000000000000000000000000000001
-:102FD00000000000000000000000000000000000F1
-:102FE00000000000000000000000000000000000E1
-:102FF00000000000000000000000000000000000D1
-:00000001FF
--- zfcpdump-kernel-4.4.orig/fs/9p/vfs_file.c
+++ zfcpdump-kernel-4.4/fs/9p/vfs_file.c
@@ -74,7 +74,7 @@ int v9fs_file_open(struct inode *inode,
 					v9fs_proto_dotu(v9ses));
 	fid = file->private_data;
 	if (!fid) {
-		fid = v9fs_fid_clone(file->f_path.dentry);
+		fid = v9fs_fid_clone(file_dentry(file));
 		if (IS_ERR(fid))
 			return PTR_ERR(fid);
 
@@ -100,7 +100,7 @@ int v9fs_file_open(struct inode *inode,
 		 * because we want write after unlink usecase
 		 * to work.
 		 */
-		fid = v9fs_writeback_fid(file->f_path.dentry);
+		fid = v9fs_writeback_fid(file_dentry(file));
 		if (IS_ERR(fid)) {
 			err = PTR_ERR(fid);
 			mutex_unlock(&v9inode->v_mutex);
@@ -516,7 +516,7 @@ v9fs_mmap_file_mmap(struct file *filp, s
 		 * because we want write after unlink usecase
 		 * to work.
 		 */
-		fid = v9fs_writeback_fid(filp->f_path.dentry);
+		fid = v9fs_writeback_fid(file_dentry(filp));
 		if (IS_ERR(fid)) {
 			retval = PTR_ERR(fid);
 			mutex_unlock(&v9inode->v_mutex);
--- zfcpdump-kernel-4.4.orig/fs/Kconfig
+++ zfcpdump-kernel-4.4/fs/Kconfig
@@ -221,6 +221,7 @@ source "fs/pstore/Kconfig"
 source "fs/sysv/Kconfig"
 source "fs/ufs/Kconfig"
 source "fs/exofs/Kconfig"
+source "fs/aufs/Kconfig"
 
 endif # MISC_FILESYSTEMS
 
--- zfcpdump-kernel-4.4.orig/fs/Makefile
+++ zfcpdump-kernel-4.4/fs/Makefile
@@ -126,3 +126,4 @@ obj-y				+= exofs/ # Multiple modules
 obj-$(CONFIG_CEPH_FS)		+= ceph/
 obj-$(CONFIG_PSTORE)		+= pstore/
 obj-$(CONFIG_EFIVAR_FS)		+= efivarfs/
+obj-$(CONFIG_AUFS_FS)           += aufs/
--- zfcpdump-kernel-4.4.orig/fs/affs/super.c
+++ zfcpdump-kernel-4.4/fs/affs/super.c
@@ -528,7 +528,7 @@ affs_remount(struct super_block *sb, int
 	char			*prefix = NULL;
 
 	new_opts = kstrdup(data, GFP_KERNEL);
-	if (!new_opts)
+	if (data && !new_opts)
 		return -ENOMEM;
 
 	pr_debug("%s(flags=0x%x,opts=\"%s\")\n", __func__, *flags, data);
@@ -546,7 +546,8 @@ affs_remount(struct super_block *sb, int
 	}
 
 	flush_delayed_work(&sbi->sb_work);
-	replace_mount_options(sb, new_opts);
+	if (new_opts)
+		replace_mount_options(sb, new_opts);
 
 	sbi->s_flags = mount_flags;
 	sbi->s_mode  = mode;
--- zfcpdump-kernel-4.4.orig/fs/aio.c
+++ zfcpdump-kernel-4.4/fs/aio.c
@@ -239,7 +239,12 @@ static struct dentry *aio_mount(struct f
 	static const struct dentry_operations ops = {
 		.d_dname	= simple_dname,
 	};
-	return mount_pseudo(fs_type, "aio:", NULL, &ops, AIO_RING_MAGIC);
+	struct dentry *root = mount_pseudo(fs_type, "aio:", NULL, &ops,
+					   AIO_RING_MAGIC);
+
+	if (!IS_ERR(root))
+		root->d_sb->s_iflags |= SB_I_NOEXEC;
+	return root;
 }
 
 /* aio_setup
--- zfcpdump-kernel-4.4.orig/fs/attr.c
+++ zfcpdump-kernel-4.4/fs/attr.c
@@ -16,6 +16,43 @@
 #include <linux/evm.h>
 #include <linux/ima.h>
 
+static bool chown_ok(const struct inode *inode, kuid_t uid)
+{
+	struct user_namespace *user_ns;
+
+	if (uid_eq(current_fsuid(), inode->i_uid) && uid_eq(uid, inode->i_uid))
+		return true;
+	if (capable_wrt_inode_uidgid(inode, CAP_CHOWN))
+		return true;
+
+	user_ns = inode->i_sb->s_user_ns;
+	if (!uid_valid(inode->i_uid) &&
+	    (!gid_valid(inode->i_gid) || kgid_has_mapping(user_ns, inode->i_gid)) &&
+	    ns_capable(user_ns, CAP_CHOWN))
+		return true;
+
+	return false;
+}
+
+static bool chgrp_ok(const struct inode *inode, kgid_t gid)
+{
+	struct user_namespace *user_ns;
+
+	if (uid_eq(current_fsuid(), inode->i_uid) &&
+	    (in_group_p(gid) || gid_eq(gid, inode->i_gid)))
+		return true;
+	if (capable_wrt_inode_uidgid(inode, CAP_CHOWN))
+		return true;
+
+	user_ns = inode->i_sb->s_user_ns;
+	if (!gid_valid(inode->i_gid) &&
+	    (!uid_valid(inode->i_uid) || kuid_has_mapping(user_ns, inode->i_uid)) &&
+	    ns_capable(user_ns, CAP_CHOWN))
+		return true;
+
+	return false;
+}
+
 /**
  * inode_change_ok - check if attribute changes to an inode are allowed
  * @inode:	inode to check
@@ -42,22 +79,27 @@ int inode_change_ok(const struct inode *
 			return error;
 	}
 
+	/*
+	 * Verify that uid/gid changes are valid in the target namespace
+	 * of the superblock. This cannot be overriden using ATTR_FORCE.
+	 */
+	if (ia_valid & ATTR_UID &&
+	    from_kuid(inode->i_sb->s_user_ns, attr->ia_uid) == (uid_t)-1)
+		return -EOVERFLOW;
+	if (ia_valid & ATTR_GID &&
+	    from_kgid(inode->i_sb->s_user_ns, attr->ia_gid) == (gid_t)-1)
+		return -EOVERFLOW;
+
 	/* If force is set do it anyway. */
 	if (ia_valid & ATTR_FORCE)
 		return 0;
 
 	/* Make sure a caller can chown. */
-	if ((ia_valid & ATTR_UID) &&
-	    (!uid_eq(current_fsuid(), inode->i_uid) ||
-	     !uid_eq(attr->ia_uid, inode->i_uid)) &&
-	    !capable_wrt_inode_uidgid(inode, CAP_CHOWN))
+	if ((ia_valid & ATTR_UID) && !chown_ok(inode, attr->ia_uid))
 		return -EPERM;
 
 	/* Make sure caller can chgrp. */
-	if ((ia_valid & ATTR_GID) &&
-	    (!uid_eq(current_fsuid(), inode->i_uid) ||
-	    (!in_group_p(attr->ia_gid) && !gid_eq(attr->ia_gid, inode->i_gid))) &&
-	    !capable_wrt_inode_uidgid(inode, CAP_CHOWN))
+	if ((ia_valid & ATTR_GID) && !chgrp_ok(inode, attr->ia_gid))
 		return -EPERM;
 
 	/* Make sure a caller can chmod. */
--- /dev/null
+++ zfcpdump-kernel-4.4/fs/aufs/Kconfig
@@ -0,0 +1,185 @@
+config AUFS_FS
+	tristate "Aufs (Advanced multi layered unification filesystem) support"
+	help
+	Aufs is a stackable unification filesystem such as Unionfs,
+	which unifies several directories and provides a merged single
+	directory.
+	In the early days, aufs was entirely re-designed and
+	re-implemented Unionfs Version 1.x series. Introducing many
+	original ideas, approaches and improvements, it becomes totally
+	different from Unionfs while keeping the basic features.
+
+if AUFS_FS
+choice
+	prompt "Maximum number of branches"
+	default AUFS_BRANCH_MAX_127
+	help
+	Specifies the maximum number of branches (or member directories)
+	in a single aufs. The larger value consumes more system
+	resources and has a minor impact to performance.
+config AUFS_BRANCH_MAX_127
+	bool "127"
+	help
+	Specifies the maximum number of branches (or member directories)
+	in a single aufs. The larger value consumes more system
+	resources and has a minor impact to performance.
+config AUFS_BRANCH_MAX_511
+	bool "511"
+	help
+	Specifies the maximum number of branches (or member directories)
+	in a single aufs. The larger value consumes more system
+	resources and has a minor impact to performance.
+config AUFS_BRANCH_MAX_1023
+	bool "1023"
+	help
+	Specifies the maximum number of branches (or member directories)
+	in a single aufs. The larger value consumes more system
+	resources and has a minor impact to performance.
+config AUFS_BRANCH_MAX_32767
+	bool "32767"
+	help
+	Specifies the maximum number of branches (or member directories)
+	in a single aufs. The larger value consumes more system
+	resources and has a minor impact to performance.
+endchoice
+
+config AUFS_SBILIST
+	bool
+	depends on AUFS_MAGIC_SYSRQ || PROC_FS
+	default y
+	help
+	Automatic configuration for internal use.
+	When aufs supports Magic SysRq or /proc, enabled automatically.
+
+config AUFS_HNOTIFY
+	bool "Detect direct branch access (bypassing aufs)"
+	help
+	If you want to modify files on branches directly, eg. bypassing aufs,
+	and want aufs to detect the changes of them fully, then enable this
+	option and use 'udba=notify' mount option.
+	Currently there is only one available configuration, "fsnotify".
+	It will have a negative impact to the performance.
+	See detail in aufs.5.
+
+choice
+	prompt "method" if AUFS_HNOTIFY
+	default AUFS_HFSNOTIFY
+config AUFS_HFSNOTIFY
+	bool "fsnotify"
+	select FSNOTIFY
+endchoice
+
+config AUFS_EXPORT
+	bool "NFS-exportable aufs"
+	depends on EXPORTFS
+	help
+	If you want to export your mounted aufs via NFS, then enable this
+	option. There are several requirements for this configuration.
+	See detail in aufs.5.
+
+config AUFS_INO_T_64
+	bool
+	depends on AUFS_EXPORT
+	depends on 64BIT && !(ALPHA || S390)
+	default y
+	help
+	Automatic configuration for internal use.
+	/* typedef unsigned long/int __kernel_ino_t */
+	/* alpha and s390x are int */
+
+config AUFS_XATTR
+	bool "support for XATTR/EA (including Security Labels)"
+	help
+	If your branch fs supports XATTR/EA and you want to make them
+	available in aufs too, then enable this opsion and specify the
+	branch attributes for EA.
+	See detail in aufs.5.
+
+config AUFS_FHSM
+	bool "File-based Hierarchical Storage Management"
+	help
+	Hierarchical Storage Management (or HSM) is a well-known feature
+	in the storage world. Aufs provides this feature as file-based.
+	with multiple branches.
+	These multiple branches are prioritized, ie. the topmost one
+	should be the fastest drive and be used heavily.
+
+config AUFS_RDU
+	bool "Readdir in userspace"
+	help
+	Aufs has two methods to provide a merged view for a directory,
+	by a user-space library and by kernel-space natively. The latter
+	is always enabled but sometimes large and slow.
+	If you enable this option, install the library in aufs2-util
+	package, and set some environment variables for your readdir(3),
+	then the work will be handled in user-space which generally
+	shows better performance in most cases.
+	See detail in aufs.5.
+
+config AUFS_SHWH
+	bool "Show whiteouts"
+	help
+	If you want to make the whiteouts in aufs visible, then enable
+	this option and specify 'shwh' mount option. Although it may
+	sounds like philosophy or something, but in technically it
+	simply shows the name of whiteout with keeping its behaviour.
+
+config AUFS_BR_RAMFS
+	bool "Ramfs (initramfs/rootfs) as an aufs branch"
+	help
+	If you want to use ramfs as an aufs branch fs, then enable this
+	option. Generally tmpfs is recommended.
+	Aufs prohibited them to be a branch fs by default, because
+	initramfs becomes unusable after switch_root or something
+	generally. If you sets initramfs as an aufs branch and boot your
+	system by switch_root, you will meet a problem easily since the
+	files in initramfs may be inaccessible.
+	Unless you are going to use ramfs as an aufs branch fs without
+	switch_root or something, leave it N.
+
+config AUFS_BR_FUSE
+	bool "Fuse fs as an aufs branch"
+	depends on FUSE_FS
+	select AUFS_POLL
+	help
+	If you want to use fuse-based userspace filesystem as an aufs
+	branch fs, then enable this option.
+	It implements the internal poll(2) operation which is
+	implemented by fuse only (curretnly).
+
+config AUFS_POLL
+	bool
+	help
+	Automatic configuration for internal use.
+
+config AUFS_BR_HFSPLUS
+	bool "Hfsplus as an aufs branch"
+	depends on HFSPLUS_FS
+	default y
+	help
+	If you want to use hfsplus fs as an aufs branch fs, then enable
+	this option. This option introduces a small overhead at
+	copying-up a file on hfsplus.
+
+config AUFS_BDEV_LOOP
+	bool
+	depends on BLK_DEV_LOOP
+	default y
+	help
+	Automatic configuration for internal use.
+	Convert =[ym] into =y.
+
+config AUFS_DEBUG
+	bool "Debug aufs"
+	help
+	Enable this to compile aufs internal debug code.
+	It will have a negative impact to the performance.
+
+config AUFS_MAGIC_SYSRQ
+	bool
+	depends on AUFS_DEBUG && MAGIC_SYSRQ
+	default y
+	help
+	Automatic configuration for internal use.
+	When aufs supports Magic SysRq, enabled automatically.
+endif
--- /dev/null
+++ zfcpdump-kernel-4.4/fs/aufs/Makefile
@@ -0,0 +1,44 @@
+
+include ${src}/magic.mk
+ifeq (${CONFIG_AUFS_FS},m)
+include ${src}/conf.mk
+endif
+-include ${src}/priv_def.mk
+
+# cf. include/linux/kernel.h
+# enable pr_debug
+ccflags-y += -DDEBUG
+# sparse requires the full pathname
+ifdef M
+ccflags-y += -include ${M}/../../include/uapi/linux/aufs_type.h
+else
+ccflags-y += -include ${srctree}/include/uapi/linux/aufs_type.h
+endif
+
+obj-$(CONFIG_AUFS_FS) += aufs.o
+aufs-y := module.o sbinfo.o super.o branch.o xino.o sysaufs.o opts.o \
+	wkq.o vfsub.o dcsub.o \
+	cpup.o whout.o wbr_policy.o \
+	dinfo.o dentry.o \
+	dynop.o \
+	finfo.o file.o f_op.o \
+	dir.o vdir.o \
+	iinfo.o inode.o i_op.o i_op_add.o i_op_del.o i_op_ren.o \
+	mvdown.o ioctl.o
+
+# all are boolean
+aufs-$(CONFIG_PROC_FS) += procfs.o plink.o
+aufs-$(CONFIG_SYSFS) += sysfs.o
+aufs-$(CONFIG_DEBUG_FS) += dbgaufs.o
+aufs-$(CONFIG_AUFS_BDEV_LOOP) += loop.o
+aufs-$(CONFIG_AUFS_HNOTIFY) += hnotify.o
+aufs-$(CONFIG_AUFS_HFSNOTIFY) += hfsnotify.o
+aufs-$(CONFIG_AUFS_EXPORT) += export.o
+aufs-$(CONFIG_AUFS_XATTR) += xattr.o
+aufs-$(CONFIG_FS_POSIX_ACL) += posix_acl.o
+aufs-$(CONFIG_AUFS_FHSM) += fhsm.o
+aufs-$(CONFIG_AUFS_POLL) += poll.o
+aufs-$(CONFIG_AUFS_RDU) += rdu.o
+aufs-$(CONFIG_AUFS_BR_HFSPLUS) += hfsplus.o
+aufs-$(CONFIG_AUFS_DEBUG) += debug.o
+aufs-$(CONFIG_AUFS_MAGIC_SYSRQ) += sysrq.o
--- /dev/null
+++ zfcpdump-kernel-4.4/fs/aufs/aufs.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+ *
+ * This program, aufs is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * all header files
+ */
+
+#ifndef __AUFS_H__
+#define __AUFS_H__
+
+#ifdef __KERNEL__
+
+#define AuStub(type, name, body, ...) \
+	static inline type name(__VA_ARGS__) { body; }
+
+#define AuStubVoid(name, ...) \
+	AuStub(void, name, , __VA_ARGS__)
+#define AuStubInt0(name, ...) \
+	AuStub(int, name, return 0, __VA_ARGS__)
+
+#include "debug.h"
+
+#include "branch.h"
+#include "cpup.h"
+#include "dcsub.h"
+#include "dbgaufs.h"
+#include "dentry.h"
+#include "dir.h"
+#include "dynop.h"
+#include "file.h"
+#include "fstype.h"
+#include "inode.h"
+#include "loop.h"
+#include "module.h"
+#include "opts.h"
+#include "rwsem.h"
+#include "spl.h"
+#include "super.h"
+#include "sysaufs.h"
+#include "vfsub.h"
+#include "whout.h"
+#include "wkq.h"
+
+#endif /* __KERNEL__ */
+#endif /* __AUFS_H__ */
--- /dev/null
+++ zfcpdump-kernel-4.4/fs/aufs/branch.c
@@ -0,0 +1,1407 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+ *
+ * This program, aufs is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * branch management
+ */
+
+#include <linux/compat.h>
+#include <linux/statfs.h>
+#include "aufs.h"
+
+/*
+ * free a single branch
+ */
+static void au_br_do_free(struct au_branch *br)
+{
+	int i;
+	struct au_wbr *wbr;
+	struct au_dykey **key;
+
+	au_hnotify_fin_br(br);
+
+	if (br->br_xino.xi_file)
+		fput(br->br_xino.xi_file);
+	mutex_destroy(&br->br_xino.xi_nondir_mtx);
+
+	AuDebugOn(atomic_read(&br->br_count));
+
+	wbr = br->br_wbr;
+	if (wbr) {
+		for (i = 0; i < AuBrWh_Last; i++)
+			dput(wbr->wbr_wh[i]);
+		AuDebugOn(atomic_read(&wbr->wbr_wh_running));
+		AuRwDestroy(&wbr->wbr_wh_rwsem);
+	}
+
+	if (br->br_fhsm) {
+		au_br_fhsm_fin(br->br_fhsm);
+		kfree(br->br_fhsm);
+	}
+
+	key = br->br_dykey;
+	for (i = 0; i < AuBrDynOp; i++, key++)
+		if (*key)
+			au_dy_put(*key);
+		else
+			break;
+
+	/* recursive lock, s_umount of branch's */
+	lockdep_off();
+	path_put(&br->br_path);
+	lockdep_on();
+	kfree(wbr);
+	kfree(br);
+}
+
+/*
+ * frees all branches
+ */
+void au_br_free(struct au_sbinfo *sbinfo)
+{
+	aufs_bindex_t bmax;
+	struct au_branch **br;
+
+	AuRwMustWriteLock(&sbinfo->si_rwsem);
+
+	bmax = sbinfo->si_bend + 1;
+	br = sbinfo->si_branch;
+	while (bmax--)
+		au_br_do_free(*br++);
+}
+
+/*
+ * find the index of a branch which is specified by @br_id.
+ */
+int au_br_index(struct super_block *sb, aufs_bindex_t br_id)
+{
+	aufs_bindex_t bindex, bend;
+
+	bend = au_sbend(sb);
+	for (bindex = 0; bindex <= bend; bindex++)
+		if (au_sbr_id(sb, bindex) == br_id)
+			return bindex;
+	return -1;
+}
+
+/* ---------------------------------------------------------------------- */
+
+/*
+ * add a branch
+ */
+
+static int test_overlap(struct super_block *sb, struct dentry *h_adding,
+			struct dentry *h_root)
+{
+	if (unlikely(h_adding == h_root
+		     || au_test_loopback_overlap(sb, h_adding)))
+		return 1;
+	if (h_adding->d_sb != h_root->d_sb)
+		return 0;
+	return au_test_subdir(h_adding, h_root)
+		|| au_test_subdir(h_root, h_adding);
+}
+
+/*
+ * returns a newly allocated branch. @new_nbranch is a number of branches
+ * after adding a branch.
+ */
+static struct au_branch *au_br_alloc(struct super_block *sb, int new_nbranch,
+				     int perm)
+{
+	struct au_branch *add_branch;
+	struct dentry *root;
+	struct inode *inode;
+	int err;
+
+	err = -ENOMEM;
+	root = sb->s_root;
+	add_branch = kzalloc(sizeof(*add_branch), GFP_NOFS);
+	if (unlikely(!add_branch))
+		goto out;
+
+	err = au_hnotify_init_br(add_branch, perm);
+	if (unlikely(err))
+		goto out_br;
+
+	if (au_br_writable(perm)) {
+		/* may be freed separately at changing the branch permission */
+		add_branch->br_wbr = kzalloc(sizeof(*add_branch->br_wbr),
+					     GFP_NOFS);
+		if (unlikely(!add_branch->br_wbr))
+			goto out_hnotify;
+	}
+
+	if (au_br_fhsm(perm)) {
+		err = au_fhsm_br_alloc(add_branch);
+		if (unlikely(err))
+			goto out_wbr;
+	}
+
+	err = au_sbr_realloc(au_sbi(sb), new_nbranch);
+	if (!err)
+		err = au_di_realloc(au_di(root), new_nbranch);
+	if (!err) {
+		inode = d_inode(root);
+		err = au_ii_realloc(au_ii(inode), new_nbranch);
+	}
+	if (!err)
+		return add_branch; /* success */
+
+out_wbr:
+	kfree(add_branch->br_wbr);
+out_hnotify:
+	au_hnotify_fin_br(add_branch);
+out_br:
+	kfree(add_branch);
+out:
+	return ERR_PTR(err);
+}
+
+/*
+ * test if the branch permission is legal or not.
+ */
+static int test_br(struct inode *inode, int brperm, char *path)
+{
+	int err;
+
+	err = (au_br_writable(brperm) && IS_RDONLY(inode));
+	if (!err)
+		goto out;
+
+	err = -EINVAL;
+	pr_err("write permission for readonly mount or inode, %s\n", path);
+
+out:
+	return err;
+}
+
+/*
+ * returns:
+ * 0: success, the caller will add it
+ * plus: success, it is already unified, the caller should ignore it
+ * minus: error
+ */
+static int test_add(struct super_block *sb, struct au_opt_add *add, int remount)
+{
+	int err;
+	aufs_bindex_t bend, bindex;
+	struct dentry *root, *h_dentry;
+	struct inode *inode, *h_inode;
+
+	root = sb->s_root;
+	bend = au_sbend(sb);
+	if (unlikely(bend >= 0
+		     && au_find_dbindex(root, add->path.dentry) >= 0)) {
+		err = 1;
+		if (!remount) {
+			err = -EINVAL;
+			pr_err("%s duplicated\n", add->pathname);
+		}
+		goto out;
+	}
+
+	err = -ENOSPC; /* -E2BIG; */
+	if (unlikely(AUFS_BRANCH_MAX <= add->bindex
+		     || AUFS_BRANCH_MAX - 1 <= bend)) {
+		pr_err("number of branches exceeded %s\n", add->pathname);
+		goto out;
+	}
+
+	err = -EDOM;
+	if (unlikely(add->bindex < 0 || bend + 1 < add->bindex)) {
+		pr_err("bad index %d\n", add->bindex);
+		goto out;
+	}
+
+	inode = d_inode(add->path.dentry);
+	err = -ENOENT;
+	if (unlikely(!inode->i_nlink)) {
+		pr_err("no existence %s\n", add->pathname);
+		goto out;
+	}
+
+	err = -EINVAL;
+	if (unlikely(inode->i_sb == sb)) {
+		pr_err("%s must be outside\n", add->pathname);
+		goto out;
+	}
+
+	if (unlikely(au_test_fs_unsuppoted(inode->i_sb))) {
+		pr_err("unsupported filesystem, %s (%s)\n",
+		       add->pathname, au_sbtype(inode->i_sb));
+		goto out;
+	}
+
+	if (unlikely(inode->i_sb->s_stack_depth)) {
+		pr_err("already stacked, %s (%s)\n",
+		       add->pathname, au_sbtype(inode->i_sb));
+		goto out;
+	}
+
+	err = test_br(d_inode(add->path.dentry), add->perm, add->pathname);
+	if (unlikely(err))
+		goto out;
+
+	if (bend < 0)
+		return 0; /* success */
+
+	err = -EINVAL;
+	for (bindex = 0; bindex <= bend; bindex++)
+		if (unlikely(test_overlap(sb, add->path.dentry,
+					  au_h_dptr(root, bindex)))) {
+			pr_err("%s is overlapped\n", add->pathname);
+			goto out;
+		}
+
+	err = 0;
+	if (au_opt_test(au_mntflags(sb), WARN_PERM)) {
+		h_dentry = au_h_dptr(root, 0);
+		h_inode = d_inode(h_dentry);
+		if ((h_inode->i_mode & S_IALLUGO) != (inode->i_mode & S_IALLUGO)
+		    || !uid_eq(h_inode->i_uid, inode->i_uid)
+		    || !gid_eq(h_inode->i_gid, inode->i_gid))
+			pr_warn("uid/gid/perm %s %u/%u/0%o, %u/%u/0%o\n",
+				add->pathname,
+				i_uid_read(inode), i_gid_read(inode),
+				(inode->i_mode & S_IALLUGO),
+				i_uid_read(h_inode), i_gid_read(h_inode),
+				(h_inode->i_mode & S_IALLUGO));
+	}
+
+out:
+	return err;
+}
+
+/*
+ * initialize or clean the whiteouts for an adding branch
+ */
+static int au_br_init_wh(struct super_block *sb, struct au_branch *br,
+			 int new_perm)
+{
+	int err, old_perm;
+	aufs_bindex_t bindex;
+	struct mutex *h_mtx;
+	struct au_wbr *wbr;
+	struct au_hinode *hdir;
+	struct dentry *h_dentry;
+
+	err = vfsub_mnt_want_write(au_br_mnt(br));
+	if (unlikely(err))
+		goto out;
+
+	wbr = br->br_wbr;
+	old_perm = br->br_perm;
+	br->br_perm = new_perm;
+	hdir = NULL;
+	h_mtx = NULL;
+	bindex = au_br_index(sb, br->br_id);
+	if (0 <= bindex) {
+		hdir = au_hi(d_inode(sb->s_root), bindex);
+		au_hn_imtx_lock_nested(hdir, AuLsc_I_PARENT);
+	} else {
+		h_dentry = au_br_dentry(br);
+		h_mtx = &d_inode(h_dentry)->i_mutex;
+		mutex_lock_nested(h_mtx, AuLsc_I_PARENT);
+	}
+	if (!wbr)
+		err = au_wh_init(br, sb);
+	else {
+		wbr_wh_write_lock(wbr);
+		err = au_wh_init(br, sb);
+		wbr_wh_write_unlock(wbr);
+	}
+	if (hdir)
+		au_hn_imtx_unlock(hdir);
+	else
+		mutex_unlock(h_mtx);
+	vfsub_mnt_drop_write(au_br_mnt(br));
+	br->br_perm = old_perm;
+
+	if (!err && wbr && !au_br_writable(new_perm)) {
+		kfree(wbr);
+		br->br_wbr = NULL;
+	}
+
+out:
+	return err;
+}
+
+static int au_wbr_init(struct au_branch *br, struct super_block *sb,
+		       int perm)
+{
+	int err;
+	struct kstatfs kst;
+	struct au_wbr *wbr;
+
+	wbr = br->br_wbr;
+	au_rw_init(&wbr->wbr_wh_rwsem);
+	atomic_set(&wbr->wbr_wh_running, 0);
+
+	/*
+	 * a limit for rmdir/rename a dir
+	 * cf. AUFS_MAX_NAMELEN in include/uapi/linux/aufs_type.h
+	 */
+	err = vfs_statfs(&br->br_path, &kst);
+	if (unlikely(err))
+		goto out;
+	err = -EINVAL;
+	if (kst.f_namelen >= NAME_MAX)
+		err = au_br_init_wh(sb, br, perm);
+	else
+		pr_err("%pd(%s), unsupported namelen %ld\n",
+		       au_br_dentry(br),
+		       au_sbtype(au_br_dentry(br)->d_sb), kst.f_namelen);
+
+out:
+	return err;
+}
+
+/* initialize a new branch */
+static int au_br_init(struct au_branch *br, struct super_block *sb,
+		      struct au_opt_add *add)
+{
+	int err;
+	struct inode *h_inode;
+
+	err = 0;
+	mutex_init(&br->br_xino.xi_nondir_mtx);
+	br->br_perm = add->perm;
+	br->br_path = add->path; /* set first, path_get() later */
+	spin_lock_init(&br->br_dykey_lock);
+	atomic_set(&br->br_count, 0);
+	atomic_set(&br->br_xino_running, 0);
+	br->br_id = au_new_br_id(sb);
+	AuDebugOn(br->br_id < 0);
+
+	if (au_br_writable(add->perm)) {
+		err = au_wbr_init(br, sb, add->perm);
+		if (unlikely(err))
+			goto out_err;
+	}
+
+	if (au_opt_test(au_mntflags(sb), XINO)) {
+		h_inode = d_inode(add->path.dentry);
+		err = au_xino_br(sb, br, h_inode->i_ino,
+				 au_sbr(sb, 0)->br_xino.xi_file, /*do_test*/1);
+		if (unlikely(err)) {
+			AuDebugOn(br->br_xino.xi_file);
+			goto out_err;
+		}
+	}
+
+	sysaufs_br_init(br);
+	path_get(&br->br_path);
+	goto out; /* success */
+
+out_err:
+	memset(&br->br_path, 0, sizeof(br->br_path));
+out:
+	return err;
+}
+
+static void au_br_do_add_brp(struct au_sbinfo *sbinfo, aufs_bindex_t bindex,
+			     struct au_branch *br, aufs_bindex_t bend,
+			     aufs_bindex_t amount)
+{
+	struct au_branch **brp;
+
+	AuRwMustWriteLock(&sbinfo->si_rwsem);
+
+	brp = sbinfo->si_branch + bindex;
+	memmove(brp + 1, brp, sizeof(*brp) * amount);
+	*brp = br;
+	sbinfo->si_bend++;
+	if (unlikely(bend < 0))
+		sbinfo->si_bend = 0;
+}
+
+static void au_br_do_add_hdp(struct au_dinfo *dinfo, aufs_bindex_t bindex,
+			     aufs_bindex_t bend, aufs_bindex_t amount)
+{
+	struct au_hdentry *hdp;
+
+	AuRwMustWriteLock(&dinfo->di_rwsem);
+
+	hdp = dinfo->di_hdentry + bindex;
+	memmove(hdp + 1, hdp, sizeof(*hdp) * amount);
+	au_h_dentry_init(hdp);
+	dinfo->di_bend++;
+	if (unlikely(bend < 0))
+		dinfo->di_bstart = 0;
+}
+
+static void au_br_do_add_hip(struct au_iinfo *iinfo, aufs_bindex_t bindex,
+			     aufs_bindex_t bend, aufs_bindex_t amount)
+{
+	struct au_hinode *hip;
+
+	AuRwMustWriteLock(&iinfo->ii_rwsem);
+
+	hip = iinfo->ii_hinode + bindex;
+	memmove(hip + 1, hip, sizeof(*hip) * amount);
+	hip->hi_inode = NULL;
+	au_hn_init(hip);
+	iinfo->ii_bend++;
+	if (unlikely(bend < 0))
+		iinfo->ii_bstart = 0;
+}
+
+static void au_br_do_add(struct super_block *sb, struct au_branch *br,
+			 aufs_bindex_t bindex)
+{
+	struct dentry *root, *h_dentry;
+	struct inode *root_inode, *h_inode;
+	aufs_bindex_t bend, amount;
+
+	root = sb->s_root;
+	root_inode = d_inode(root);
+	bend = au_sbend(sb);
+	amount = bend + 1 - bindex;
+	h_dentry = au_br_dentry(br);
+	au_sbilist_lock();
+	au_br_do_add_brp(au_sbi(sb), bindex, br, bend, amount);
+	au_br_do_add_hdp(au_di(root), bindex, bend, amount);
+	au_br_do_add_hip(au_ii(root_inode), bindex, bend, amount);
+	au_set_h_dptr(root, bindex, dget(h_dentry));
+	h_inode = d_inode(h_dentry);
+	au_set_h_iptr(root_inode, bindex, au_igrab(h_inode), /*flags*/0);
+	au_sbilist_unlock();
+}
+
+int au_br_add(struct super_block *sb, struct au_opt_add *add, int remount)
+{
+	int err;
+	aufs_bindex_t bend, add_bindex;
+	struct dentry *root, *h_dentry;
+	struct inode *root_inode;
+	struct au_branch *add_branch;
+
+	root = sb->s_root;
+	root_inode = d_inode(root);
+	IMustLock(root_inode);
+	err = test_add(sb, add, remount);
+	if (unlikely(err < 0))
+		goto out;
+	if (err) {
+		err = 0;
+		goto out; /* success */
+	}
+
+	bend = au_sbend(sb);
+	add_branch = au_br_alloc(sb, bend + 2, add->perm);
+	err = PTR_ERR(add_branch);
+	if (IS_ERR(add_branch))
+		goto out;
+
+	err = au_br_init(add_branch, sb, add);
+	if (unlikely(err)) {
+		au_br_do_free(add_branch);
+		goto out;
+	}
+
+	add_bindex = add->bindex;
+	if (!remount)
+		au_br_do_add(sb, add_branch, add_bindex);
+	else {
+		sysaufs_brs_del(sb, add_bindex);
+		au_br_do_add(sb, add_branch, add_bindex);
+		sysaufs_brs_add(sb, add_bindex);
+	}
+
+	h_dentry = add->path.dentry;
+	if (!add_bindex) {
+		au_cpup_attr_all(root_inode, /*force*/1);
+		sb->s_maxbytes = h_dentry->d_sb->s_maxbytes;
+	} else
+		au_add_nlink(root_inode, d_inode(h_dentry));
+
+	/*
+	 * this test/set prevents aufs from handling unnecesary notify events
+	 * of xino files, in case of re-adding a writable branch which was
+	 * once detached from aufs.
+	 */
+	if (au_xino_brid(sb) < 0
+	    && au_br_writable(add_branch->br_perm)
+	    && !au_test_fs_bad_xino(h_dentry->d_sb)
+	    && add_branch->br_xino.xi_file
+	    && add_branch->br_xino.xi_file->f_path.dentry->d_parent == h_dentry)
+		au_xino_brid_set(sb, add_branch->br_id);
+
+out:
+	return err;
+}
+
+/* ---------------------------------------------------------------------- */
+
+static unsigned long long au_farray_cb(struct super_block *sb, void *a,
+				       unsigned long long max __maybe_unused,
+				       void *arg)
+{
+	unsigned long long n;
+	struct file **p, *f;
+	struct au_sphlhead *files;
+	struct au_finfo *finfo;
+
+	n = 0;
+	p = a;
+	files = &au_sbi(sb)->si_files;
+	spin_lock(&files->spin);
+	hlist_for_each_entry(finfo, &files->head, fi_hlist) {
+		f = finfo->fi_file;
+		if (file_count(f)
+		    && !special_file(file_inode(f)->i_mode)) {
+			get_file(f);
+			*p++ = f;
+			n++;
+			AuDebugOn(n > max);
+		}
+	}
+	spin_unlock(&files->spin);
+
+	return n;
+}
+
+static struct file **au_farray_alloc(struct super_block *sb,
+				     unsigned long long *max)
+{
+	*max = atomic_long_read(&au_sbi(sb)->si_nfiles);
+	return au_array_alloc(max, au_farray_cb, sb, /*arg*/NULL);
+}
+
+static void au_farray_free(struct file **a, unsigned long long max)
+{
+	unsigned long long ull;
+
+	for (ull = 0; ull < max; ull++)
+		if (a[ull])
+			fput(a[ull]);
+	kvfree(a);
+}
+
+/* ---------------------------------------------------------------------- */
+
+/*
+ * delete a branch
+ */
+
+/* to show the line number, do not make it inlined function */
+#define AuVerbose(do_info, fmt, ...) do { \
+	if (do_info) \
+		pr_info(fmt, ##__VA_ARGS__); \
+} while (0)
+
+static int au_test_ibusy(struct inode *inode, aufs_bindex_t bstart,
+			 aufs_bindex_t bend)
+{
+	return (inode && !S_ISDIR(inode->i_mode)) || bstart == bend;
+}
+
+static int au_test_dbusy(struct dentry *dentry, aufs_bindex_t bstart,
+			 aufs_bindex_t bend)
+{
+	return au_test_ibusy(d_inode(dentry), bstart, bend);
+}
+
+/*
+ * test if the branch is deletable or not.
+ */
+static int test_dentry_busy(struct dentry *root, aufs_bindex_t bindex,
+			    unsigned int sigen, const unsigned int verbose)
+{
+	int err, i, j, ndentry;
+	aufs_bindex_t bstart, bend;
+	struct au_dcsub_pages dpages;
+	struct au_dpage *dpage;
+	struct dentry *d;
+
+	err = au_dpages_init(&dpages, GFP_NOFS);
+	if (unlikely(err))
+		goto out;
+	err = au_dcsub_pages(&dpages, root, NULL, NULL);
+	if (unlikely(err))
+		goto out_dpages;
+
+	for (i = 0; !err && i < dpages.ndpage; i++) {
+		dpage = dpages.dpages + i;
+		ndentry = dpage->ndentry;
+		for (j = 0; !err && j < ndentry; j++) {
+			d = dpage->dentries[j];
+			AuDebugOn(au_dcount(d) <= 0);
+			if (!au_digen_test(d, sigen)) {
+				di_read_lock_child(d, AuLock_IR);
+				if (unlikely(au_dbrange_test(d))) {
+					di_read_unlock(d, AuLock_IR);
+					continue;
+				}
+			} else {
+				di_write_lock_child(d);
+				if (unlikely(au_dbrange_test(d))) {
+					di_write_unlock(d);
+					continue;
+				}
+				err = au_reval_dpath(d, sigen);
+				if (!err)
+					di_downgrade_lock(d, AuLock_IR);
+				else {
+					di_write_unlock(d);
+					break;
+				}
+			}
+
+			/* AuDbgDentry(d); */
+			bstart = au_dbstart(d);
+			bend = au_dbend(d);
+			if (bstart <= bindex
+			    && bindex <= bend
+			    && au_h_dptr(d, bindex)
+			    && au_test_dbusy(d, bstart, bend)) {
+				err = -EBUSY;
+				AuVerbose(verbose, "busy %pd\n", d);
+				AuDbgDentry(d);
+			}
+			di_read_unlock(d, AuLock_IR);
+		}
+	}
+
+out_dpages:
+	au_dpages_free(&dpages);
+out:
+	return err;
+}
+
+static int test_inode_busy(struct super_block *sb, aufs_bindex_t bindex,
+			   unsigned int sigen, const unsigned int verbose)
+{
+	int err;
+	unsigned long long max, ull;
+	struct inode *i, **array;
+	aufs_bindex_t bstart, bend;
+
+	array = au_iarray_alloc(sb, &max);
+	err = PTR_ERR(array);
+	if (IS_ERR(array))
+		goto out;
+
+	err = 0;
+	AuDbg("b%d\n", bindex);
+	for (ull = 0; !err && ull < max; ull++) {
+		i = array[ull];
+		if (unlikely(!i))
+			break;
+		if (i->i_ino == AUFS_ROOT_INO)
+			continue;
+
+		/* AuDbgInode(i); */
+		if (au_iigen(i, NULL) == sigen)
+			ii_read_lock_child(i);
+		else {
+			ii_write_lock_child(i);
+			err = au_refresh_hinode_self(i);
+			au_iigen_dec(i);
+			if (!err)
+				ii_downgrade_lock(i);
+			else {
+				ii_write_unlock(i);
+				break;
+			}
+		}
+
+		bstart = au_ibstart(i);
+		bend = au_ibend(i);
+		if (bstart <= bindex
+		    && bindex <= bend
+		    && au_h_iptr(i, bindex)
+		    && au_test_ibusy(i, bstart, bend)) {
+			err = -EBUSY;
+			AuVerbose(verbose, "busy i%lu\n", i->i_ino);
+			AuDbgInode(i);
+		}
+		ii_read_unlock(i);
+	}
+	au_iarray_free(array, max);
+
+out:
+	return err;
+}
+
+static int test_children_busy(struct dentry *root, aufs_bindex_t bindex,
+			      const unsigned int verbose)
+{
+	int err;
+	unsigned int sigen;
+
+	sigen = au_sigen(root->d_sb);
+	DiMustNoWaiters(root);
+	IiMustNoWaiters(d_inode(root));
+	di_write_unlock(root);
+	err = test_dentry_busy(root, bindex, sigen, verbose);
+	if (!err)
+		err = test_inode_busy(root->d_sb, bindex, sigen, verbose);
+	di_write_lock_child(root); /* aufs_write_lock() calls ..._child() */
+
+	return err;
+}
+
+static int test_dir_busy(struct file *file, aufs_bindex_t br_id,
+			 struct file **to_free, int *idx)
+{
+	int err;
+	unsigned char matched, root;
+	aufs_bindex_t bindex, bend;
+	struct au_fidir *fidir;
+	struct au_hfile *hfile;
+
+	err = 0;
+	root = IS_ROOT(file->f_path.dentry);
+	if (root) {
+		get_file(file);
+		to_free[*idx] = file;
+		(*idx)++;
+		goto out;
+	}
+
+	matched = 0;
+	fidir = au_fi(file)->fi_hdir;
+	AuDebugOn(!fidir);
+	bend = au_fbend_dir(file);
+	for (bindex = au_fbstart(file); bindex <= bend; bindex++) {
+		hfile = fidir->fd_hfile + bindex;
+		if (!hfile->hf_file)
+			continue;
+
+		if (hfile->hf_br->br_id == br_id) {
+			matched = 1;
+			break;
+		}
+	}
+	if (matched)
+		err = -EBUSY;
+
+out:
+	return err;
+}
+
+static int test_file_busy(struct super_block *sb, aufs_bindex_t br_id,
+			  struct file **to_free, int opened)
+{
+	int err, idx;
+	unsigned long long ull, max;
+	aufs_bindex_t bstart;
+	struct file *file, **array;
+	struct dentry *root;
+	struct au_hfile *hfile;
+
+	array = au_farray_alloc(sb, &max);
+	err = PTR_ERR(array);
+	if (IS_ERR(array))
+		goto out;
+
+	err = 0;
+	idx = 0;
+	root = sb->s_root;
+	di_write_unlock(root);
+	for (ull = 0; ull < max; ull++) {
+		file = array[ull];
+		if (unlikely(!file))
+			break;
+
+		/* AuDbg("%pD\n", file); */
+		fi_read_lock(file);
+		bstart = au_fbstart(file);
+		if (!d_is_dir(file->f_path.dentry)) {
+			hfile = &au_fi(file)->fi_htop;
+			if (hfile->hf_br->br_id == br_id)
+				err = -EBUSY;
+		} else
+			err = test_dir_busy(file, br_id, to_free, &idx);
+		fi_read_unlock(file);
+		if (unlikely(err))
+			break;
+	}
+	di_write_lock_child(root);
+	au_farray_free(array, max);
+	AuDebugOn(idx > opened);
+
+out:
+	return err;
+}
+
+static void br_del_file(struct file **to_free, unsigned long long opened,
+			  aufs_bindex_t br_id)
+{
+	unsigned long long ull;
+	aufs_bindex_t bindex, bstart, bend, bfound;
+	struct file *file;
+	struct au_fidir *fidir;
+	struct au_hfile *hfile;
+
+	for (ull = 0; ull < opened; ull++) {
+		file = to_free[ull];
+		if (unlikely(!file))
+			break;
+
+		/* AuDbg("%pD\n", file); */
+		AuDebugOn(!d_is_dir(file->f_path.dentry));
+		bfound = -1;
+		fidir = au_fi(file)->fi_hdir;
+		AuDebugOn(!fidir);
+		fi_write_lock(file);
+		bstart = au_fbstart(file);
+		bend = au_fbend_dir(file);
+		for (bindex = bstart; bindex <= bend; bindex++) {
+			hfile = fidir->fd_hfile + bindex;
+			if (!hfile->hf_file)
+				continue;
+
+			if (hfile->hf_br->br_id == br_id) {
+				bfound = bindex;
+				break;
+			}
+		}
+		AuDebugOn(bfound < 0);
+		au_set_h_fptr(file, bfound, NULL);
+		if (bfound == bstart) {
+			for (bstart++; bstart <= bend; bstart++)
+				if (au_hf_dir(file, bstart)) {
+					au_set_fbstart(file, bstart);
+					break;
+				}
+		}
+		fi_write_unlock(file);
+	}
+}
+
+static void au_br_do_del_brp(struct au_sbinfo *sbinfo,
+			     const aufs_bindex_t bindex,
+			     const aufs_bindex_t bend)
+{
+	struct au_branch **brp, **p;
+
+	AuRwMustWriteLock(&sbinfo->si_rwsem);
+
+	brp = sbinfo->si_branch + bindex;
+	if (bindex < bend)
+		memmove(brp, brp + 1, sizeof(*brp) * (bend - bindex));
+	sbinfo->si_branch[0 + bend] = NULL;
+	sbinfo->si_bend--;
+
+	p = krealloc(sbinfo->si_branch, sizeof(*p) * bend, AuGFP_SBILIST);
+	if (p)
+		sbinfo->si_branch = p;
+	/* harmless error */
+}
+
+static void au_br_do_del_hdp(struct au_dinfo *dinfo, const aufs_bindex_t bindex,
+			     const aufs_bindex_t bend)
+{
+	struct au_hdentry *hdp, *p;
+
+	AuRwMustWriteLock(&dinfo->di_rwsem);
+
+	hdp = dinfo->di_hdentry;
+	if (bindex < bend)
+		memmove(hdp + bindex, hdp + bindex + 1,
+			sizeof(*hdp) * (bend - bindex));
+	hdp[0 + bend].hd_dentry = NULL;
+	dinfo->di_bend--;
+
+	p = krealloc(hdp, sizeof(*p) * bend, AuGFP_SBILIST);
+	if (p)
+		dinfo->di_hdentry = p;
+	/* harmless error */
+}
+
+static void au_br_do_del_hip(struct au_iinfo *iinfo, const aufs_bindex_t bindex,
+			     const aufs_bindex_t bend)
+{
+	struct au_hinode *hip, *p;
+
+	AuRwMustWriteLock(&iinfo->ii_rwsem);
+
+	hip = iinfo->ii_hinode + bindex;
+	if (bindex < bend)
+		memmove(hip, hip + 1, sizeof(*hip) * (bend - bindex));
+	iinfo->ii_hinode[0 + bend].hi_inode = NULL;
+	au_hn_init(iinfo->ii_hinode + bend);
+	iinfo->ii_bend--;
+
+	p = krealloc(iinfo->ii_hinode, sizeof(*p) * bend, AuGFP_SBILIST);
+	if (p)
+		iinfo->ii_hinode = p;
+	/* harmless error */
+}
+
+static void au_br_do_del(struct super_block *sb, aufs_bindex_t bindex,
+			 struct au_branch *br)
+{
+	aufs_bindex_t bend;
+	struct au_sbinfo *sbinfo;
+	struct dentry *root, *h_root;
+	struct inode *inode, *h_inode;
+	struct au_hinode *hinode;
+
+	SiMustWriteLock(sb);
+
+	root = sb->s_root;
+	inode = d_inode(root);
+	sbinfo = au_sbi(sb);
+	bend = sbinfo->si_bend;
+
+	h_root = au_h_dptr(root, bindex);
+	hinode = au_hi(inode, bindex);
+	h_inode = au_igrab(hinode->hi_inode);
+	au_hiput(hinode);
+
+	au_sbilist_lock();
+	au_br_do_del_brp(sbinfo, bindex, bend);
+	au_br_do_del_hdp(au_di(root), bindex, bend);
+	au_br_do_del_hip(au_ii(inode), bindex, bend);
+	au_sbilist_unlock();
+
+	dput(h_root);
+	iput(h_inode);
+	au_br_do_free(br);
+}
+
+static unsigned long long empty_cb(struct super_block *sb, void *array,
+				   unsigned long long max, void *arg)
+{
+	return max;
+}
+
+int au_br_del(struct super_block *sb, struct au_opt_del *del, int remount)
+{
+	int err, rerr, i;
+	unsigned long long opened;
+	unsigned int mnt_flags;
+	aufs_bindex_t bindex, bend, br_id;
+	unsigned char do_wh, verbose;
+	struct au_branch *br;
+	struct au_wbr *wbr;
+	struct dentry *root;
+	struct file **to_free;
+
+	err = 0;
+	opened = 0;
+	to_free = NULL;
+	root = sb->s_root;
+	bindex = au_find_dbindex(root, del->h_path.dentry);
+	if (bindex < 0) {
+		if (remount)
+			goto out; /* success */
+		err = -ENOENT;
+		pr_err("%s no such branch\n", del->pathname);
+		goto out;
+	}
+	AuDbg("bindex b%d\n", bindex);
+
+	err = -EBUSY;
+	mnt_flags = au_mntflags(sb);
+	verbose = !!au_opt_test(mnt_flags, VERBOSE);
+	bend = au_sbend(sb);
+	if (unlikely(!bend)) {
+		AuVerbose(verbose, "no more branches left\n");
+		goto out;
+	}
+	br = au_sbr(sb, bindex);
+	AuDebugOn(!path_equal(&br->br_path, &del->h_path));
+
+	br_id = br->br_id;
+	opened = atomic_read(&br->br_count);
+	if (unlikely(opened)) {
+		to_free = au_array_alloc(&opened, empty_cb, sb, NULL);
+		err = PTR_ERR(to_free);
+		if (IS_ERR(to_free))
+			goto out;
+
+		err = test_file_busy(sb, br_id, to_free, opened);
+		if (unlikely(err)) {
+			AuVerbose(verbose, "%llu file(s) opened\n", opened);
+			goto out;
+		}
+	}
+
+	wbr = br->br_wbr;
+	do_wh = wbr && (wbr->wbr_whbase || wbr->wbr_plink || wbr->wbr_orph);
+	if (do_wh) {
+		/* instead of WbrWhMustWriteLock(wbr) */
+		SiMustWriteLock(sb);
+		for (i = 0; i < AuBrWh_Last; i++) {
+			dput(wbr->wbr_wh[i]);
+			wbr->wbr_wh[i] = NULL;
+		}
+	}
+
+	err = test_children_busy(root, bindex, verbose);
+	if (unlikely(err)) {
+		if (do_wh)
+			goto out_wh;
+		goto out;
+	}
+
+	err = 0;
+	if (to_free) {
+		/*
+		 * now we confirmed the branch is deletable.
+		 * let's free the remaining opened dirs on the branch.
+		 */
+		di_write_unlock(root);
+		br_del_file(to_free, opened, br_id);
+		di_write_lock_child(root);
+	}
+
+	if (!remount)
+		au_br_do_del(sb, bindex, br);
+	else {
+		sysaufs_brs_del(sb, bindex);
+		au_br_do_del(sb, bindex, br);
+		sysaufs_brs_add(sb, bindex);
+	}
+
+	if (!bindex) {
+		au_cpup_attr_all(d_inode(root), /*force*/1);
+		sb->s_maxbytes = au_sbr_sb(sb, 0)->s_maxbytes;
+	} else
+		au_sub_nlink(d_inode(root), d_inode(del->h_path.dentry));
+	if (au_opt_test(mnt_flags, PLINK))
+		au_plink_half_refresh(sb, br_id);
+
+	if (au_xino_brid(sb) == br_id)
+		au_xino_brid_set(sb, -1);
+	goto out; /* success */
+
+out_wh:
+	/* revert */
+	rerr = au_br_init_wh(sb, br, br->br_perm);
+	if (rerr)
+		pr_warn("failed re-creating base whiteout, %s. (%d)\n",
+			del->pathname, rerr);
+out:
+	if (to_free)
+		au_farray_free(to_free, opened);
+	return err;
+}
+
+/* ---------------------------------------------------------------------- */
+
+static int au_ibusy(struct super_block *sb, struct aufs_ibusy __user *arg)
+{
+	int err;
+	aufs_bindex_t bstart, bend;
+	struct aufs_ibusy ibusy;
+	struct inode *inode, *h_inode;
+
+	err = -EPERM;
+	if (unlikely(!capable(CAP_SYS_ADMIN)))
+		goto out;
+
+	err = copy_from_user(&ibusy, arg, sizeof(ibusy));
+	if (!err)
+		err = !access_ok(VERIFY_WRITE, &arg->h_ino, sizeof(arg->h_ino));
+	if (unlikely(err)) {
+		err = -EFAULT;
+		AuTraceErr(err);
+		goto out;
+	}
+
+	err = -EINVAL;
+	si_read_lock(sb, AuLock_FLUSH);
+	if (unlikely(ibusy.bindex < 0 || ibusy.bindex > au_sbend(sb)))
+		goto out_unlock;
+
+	err = 0;
+	ibusy.h_ino = 0; /* invalid */
+	inode = ilookup(sb, ibusy.ino);
+	if (!inode
+	    || inode->i_ino == AUFS_ROOT_INO
+	    || is_bad_inode(inode))
+		goto out_unlock;
+
+	ii_read_lock_child(inode);
+	bstart = au_ibstart(inode);
+	bend = au_ibend(inode);
+	if (bstart <= ibusy.bindex && ibusy.bindex <= bend) {
+		h_inode = au_h_iptr(inode, ibusy.bindex);
+		if (h_inode && au_test_ibusy(inode, bstart, bend))
+			ibusy.h_ino = h_inode->i_ino;
+	}
+	ii_read_unlock(inode);
+	iput(inode);
+
+out_unlock:
+	si_read_unlock(sb);
+	if (!err) {
+		err = __put_user(ibusy.h_ino, &arg->h_ino);
+		if (unlikely(err)) {
+			err = -EFAULT;
+			AuTraceErr(err);
+		}
+	}
+out:
+	return err;
+}
+
+long au_ibusy_ioctl(struct file *file, unsigned long arg)
+{
+	return au_ibusy(file->f_path.dentry->d_sb, (void __user *)arg);
+}
+
+#ifdef CONFIG_COMPAT
+long au_ibusy_compat_ioctl(struct file *file, unsigned long arg)
+{
+	return au_ibusy(file->f_path.dentry->d_sb, compat_ptr(arg));
+}
+#endif
+
+/* ---------------------------------------------------------------------- */
+
+/*
+ * change a branch permission
+ */
+
+static void au_warn_ima(void)
+{
+#ifdef CONFIG_IMA
+	/* since it doesn't support mark_files_ro() */
+	AuWarn1("RW -> RO makes IMA to produce wrong message\n");
+#endif
+}
+
+static int do_need_sigen_inc(int a, int b)
+{
+	return au_br_whable(a) && !au_br_whable(b);
+}
+
+static int need_sigen_inc(int old, int new)
+{
+	return do_need_sigen_inc(old, new)
+		|| do_need_sigen_inc(new, old);
+}
+
+static int au_br_mod_files_ro(struct super_block *sb, aufs_bindex_t bindex)
+{
+	int err, do_warn;
+	unsigned int mnt_flags;
+	unsigned long long ull, max;
+	aufs_bindex_t br_id;
+	unsigned char verbose, writer;
+	struct file *file, *hf, **array;
+	struct au_hfile *hfile;
+
+	mnt_flags = au_mntflags(sb);
+	verbose = !!au_opt_test(mnt_flags, VERBOSE);
+
+	array = au_farray_alloc(sb, &max);
+	err = PTR_ERR(array);
+	if (IS_ERR(array))
+		goto out;
+
+	do_warn = 0;
+	br_id = au_sbr_id(sb, bindex);
+	for (ull = 0; ull < max; ull++) {
+		file = array[ull];
+		if (unlikely(!file))
+			break;
+
+		/* AuDbg("%pD\n", file); */
+		fi_read_lock(file);
+		if (unlikely(au_test_mmapped(file))) {
+			err = -EBUSY;
+			AuVerbose(verbose, "mmapped %pD\n", file);
+			AuDbgFile(file);
+			FiMustNoWaiters(file);
+			fi_read_unlock(file);
+			goto out_array;
+		}
+
+		hfile = &au_fi(file)->fi_htop;
+		hf = hfile->hf_file;
+		if (!d_is_reg(file->f_path.dentry)
+		    || !(file->f_mode & FMODE_WRITE)
+		    || hfile->hf_br->br_id != br_id
+		    || !(hf->f_mode & FMODE_WRITE))
+			array[ull] = NULL;
+		else {
+			do_warn = 1;
+			get_file(file);
+		}
+
+		FiMustNoWaiters(file);
+		fi_read_unlock(file);
+		fput(file);
+	}
+
+	err = 0;
+	if (do_warn)
+		au_warn_ima();
+
+	for (ull = 0; ull < max; ull++) {
+		file = array[ull];
+		if (!file)
+			continue;
+
+		/* todo: already flushed? */
+		/*
+		 * fs/super.c:mark_files_ro() is gone, but aufs keeps its
+		 * approach which resets f_mode and calls mnt_drop_write() and
+		 * file_release_write() for each file, because the branch
+		 * attribute in aufs world is totally different from the native
+		 * fs rw/ro mode.
+		*/
+		/* fi_read_lock(file); */
+		hfile = &au_fi(file)->fi_htop;
+		hf = hfile->hf_file;
+		/* fi_read_unlock(file); */
+		spin_lock(&hf->f_lock);
+		writer = !!(hf->f_mode & FMODE_WRITER);
+		hf->f_mode &= ~(FMODE_WRITE | FMODE_WRITER);
+		spin_unlock(&hf->f_lock);
+		if (writer) {
+			put_write_access(file_inode(hf));
+			__mnt_drop_write(hf->f_path.mnt);
+		}
+	}
+
+out_array:
+	au_farray_free(array, max);
+out:
+	AuTraceErr(err);
+	return err;
+}
+
+int au_br_mod(struct super_block *sb, struct au_opt_mod *mod, int remount,
+	      int *do_refresh)
+{
+	int err, rerr;
+	aufs_bindex_t bindex;
+	struct dentry *root;
+	struct au_branch *br;
+	struct au_br_fhsm *bf;
+
+	root = sb->s_root;
+	bindex = au_find_dbindex(root, mod->h_root);
+	if (bindex < 0) {
+		if (remount)
+			return 0; /* success */
+		err = -ENOENT;
+		pr_err("%s no such branch\n", mod->path);
+		goto out;
+	}
+	AuDbg("bindex b%d\n", bindex);
+
+	err = test_br(d_inode(mod->h_root), mod->perm, mod->path);
+	if (unlikely(err))
+		goto out;
+
+	br = au_sbr(sb, bindex);
+	AuDebugOn(mod->h_root != au_br_dentry(br));
+	if (br->br_perm == mod->perm)
+		return 0; /* success */
+
+	/* pre-allocate for non-fhsm --> fhsm */
+	bf = NULL;
+	if (!au_br_fhsm(br->br_perm) && au_br_fhsm(mod->perm)) {
+		err = au_fhsm_br_alloc(br);
+		if (unlikely(err))
+			goto out;
+		bf = br->br_fhsm;
+		br->br_fhsm = NULL;
+	}
+
+	if (au_br_writable(br->br_perm)) {
+		/* remove whiteout base */
+		err = au_br_init_wh(sb, br, mod->perm);
+		if (unlikely(err))
+			goto out_bf;
+
+		if (!au_br_writable(mod->perm)) {
+			/* rw --> ro, file might be mmapped */
+			DiMustNoWaiters(root);
+			IiMustNoWaiters(d_inode(root));
+			di_write_unlock(root);
+			err = au_br_mod_files_ro(sb, bindex);
+			/* aufs_write_lock() calls ..._child() */
+			di_write_lock_child(root);
+
+			if (unlikely(err)) {
+				rerr = -ENOMEM;
+				br->br_wbr = kzalloc(sizeof(*br->br_wbr),
+						     GFP_NOFS);
+				if (br->br_wbr)
+					rerr = au_wbr_init(br, sb, br->br_perm);
+				if (unlikely(rerr)) {
+					AuIOErr("nested error %d (%d)\n",
+						rerr, err);
+					br->br_perm = mod->perm;
+				}
+			}
+		}
+	} else if (au_br_writable(mod->perm)) {
+		/* ro --> rw */
+		err = -ENOMEM;
+		br->br_wbr = kzalloc(sizeof(*br->br_wbr), GFP_NOFS);
+		if (br->br_wbr) {
+			err = au_wbr_init(br, sb, mod->perm);
+			if (unlikely(err)) {
+				kfree(br->br_wbr);
+				br->br_wbr = NULL;
+			}
+		}
+	}
+	if (unlikely(err))
+		goto out_bf;
+
+	if (au_br_fhsm(br->br_perm)) {
+		if (!au_br_fhsm(mod->perm)) {
+			/* fhsm --> non-fhsm */
+			au_br_fhsm_fin(br->br_fhsm);
+			kfree(br->br_fhsm);
+			br->br_fhsm = NULL;
+		}
+	} else if (au_br_fhsm(mod->perm))
+		/* non-fhsm --> fhsm */
+		br->br_fhsm = bf;
+
+	*do_refresh |= need_sigen_inc(br->br_perm, mod->perm);
+	br->br_perm = mod->perm;
+	goto out; /* success */
+
+out_bf:
+	kfree(bf);
+out:
+	AuTraceErr(err);
+	return err;
+}
+
+/* ---------------------------------------------------------------------- */
+
+int au_br_stfs(struct au_branch *br, struct aufs_stfs *stfs)
+{
+	int err;
+	struct kstatfs kstfs;
+
+	err = vfs_statfs(&br->br_path, &kstfs);
+	if (!err) {
+		stfs->f_blocks = kstfs.f_blocks;
+		stfs->f_bavail = kstfs.f_bavail;
+		stfs->f_files = kstfs.f_files;
+		stfs->f_ffree = kstfs.f_ffree;
+	}
+
+	return err;
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/fs/aufs/branch.h
@@ -0,0 +1,279 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+ *
+ * This program, aufs is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * branch filesystems and xino for them
+ */
+
+#ifndef __AUFS_BRANCH_H__
+#define __AUFS_BRANCH_H__
+
+#ifdef __KERNEL__
+
+#include <linux/mount.h>
+#include "dynop.h"
+#include "rwsem.h"
+#include "super.h"
+
+/* ---------------------------------------------------------------------- */
+
+/* a xino file */
+struct au_xino_file {
+	struct file		*xi_file;
+	struct mutex		xi_nondir_mtx;
+
+	/* todo: make xino files an array to support huge inode number */
+
+#ifdef CONFIG_DEBUG_FS
+	struct dentry		 *xi_dbgaufs;
+#endif
+};
+
+/* File-based Hierarchical Storage Management */
+struct au_br_fhsm {
+#ifdef CONFIG_AUFS_FHSM
+	struct mutex		bf_lock;
+	unsigned long		bf_jiffy;
+	struct aufs_stfs	bf_stfs;
+	int			bf_readable;
+#endif
+};
+
+/* members for writable branch only */
+enum {AuBrWh_BASE, AuBrWh_PLINK, AuBrWh_ORPH, AuBrWh_Last};
+struct au_wbr {
+	struct au_rwsem		wbr_wh_rwsem;
+	struct dentry		*wbr_wh[AuBrWh_Last];
+	atomic_t		wbr_wh_running;
+#define wbr_whbase		wbr_wh[AuBrWh_BASE]	/* whiteout base */
+#define wbr_plink		wbr_wh[AuBrWh_PLINK]	/* pseudo-link dir */
+#define wbr_orph		wbr_wh[AuBrWh_ORPH]	/* dir for orphans */
+
+	/* mfs mode */
+	unsigned long long	wbr_bytes;
+};
+
+/* ext2 has 3 types of operations at least, ext3 has 4 */
+#define AuBrDynOp (AuDyLast * 4)
+
+#ifdef CONFIG_AUFS_HFSNOTIFY
+/* support for asynchronous destruction */
+struct au_br_hfsnotify {
+	struct fsnotify_group	*hfsn_group;
+};
+#endif
+
+/* sysfs entries */
+struct au_brsysfs {
+	char			name[16];
+	struct attribute	attr;
+};
+
+enum {
+	AuBrSysfs_BR,
+	AuBrSysfs_BRID,
+	AuBrSysfs_Last
+};
+
+/* protected by superblock rwsem */
+struct au_branch {
+	struct au_xino_file	br_xino;
+
+	aufs_bindex_t		br_id;
+
+	int			br_perm;
+	struct path		br_path;
+	spinlock_t		br_dykey_lock;
+	struct au_dykey		*br_dykey[AuBrDynOp];
+	atomic_t		br_count;
+
+	struct au_wbr		*br_wbr;
+	struct au_br_fhsm	*br_fhsm;
+
+	/* xino truncation */
+	atomic_t		br_xino_running;
+
+#ifdef CONFIG_AUFS_HFSNOTIFY
+	struct au_br_hfsnotify	*br_hfsn;
+#endif
+
+#ifdef CONFIG_SYSFS
+	/* entries under sysfs per mount-point */
+	struct au_brsysfs	br_sysfs[AuBrSysfs_Last];
+#endif
+};
+
+/* ---------------------------------------------------------------------- */
+
+static inline struct vfsmount *au_br_mnt(struct au_branch *br)
+{
+	return br->br_path.mnt;
+}
+
+static inline struct dentry *au_br_dentry(struct au_branch *br)
+{
+	return br->br_path.dentry;
+}
+
+static inline struct super_block *au_br_sb(struct au_branch *br)
+{
+	return au_br_mnt(br)->mnt_sb;
+}
+
+static inline int au_br_rdonly(struct au_branch *br)
+{
+	return ((au_br_sb(br)->s_flags & MS_RDONLY)
+		|| !au_br_writable(br->br_perm))
+		? -EROFS : 0;
+}
+
+static inline int au_br_hnotifyable(int brperm __maybe_unused)
+{
+#ifdef CONFIG_AUFS_HNOTIFY
+	return !(brperm & AuBrPerm_RR);
+#else
+	return 0;
+#endif
+}
+
+static inline int au_br_test_oflag(int oflag, struct au_branch *br)
+{
+	int err, exec_flag;
+
+	err = 0;
+	exec_flag = oflag & __FMODE_EXEC;
+	if (unlikely(exec_flag && path_noexec(&br->br_path)))
+		err = -EACCES;
+
+	return err;
+}
+
+/* ---------------------------------------------------------------------- */
+
+/* branch.c */
+struct au_sbinfo;
+void au_br_free(struct au_sbinfo *sinfo);
+int au_br_index(struct super_block *sb, aufs_bindex_t br_id);
+struct au_opt_add;
+int au_br_add(struct super_block *sb, struct au_opt_add *add, int remount);
+struct au_opt_del;
+int au_br_del(struct super_block *sb, struct au_opt_del *del, int remount);
+long au_ibusy_ioctl(struct file *file, unsigned long arg);
+#ifdef CONFIG_COMPAT
+long au_ibusy_compat_ioctl(struct file *file, unsigned long arg);
+#endif
+struct au_opt_mod;
+int au_br_mod(struct super_block *sb, struct au_opt_mod *mod, int remount,
+	      int *do_refresh);
+struct aufs_stfs;
+int au_br_stfs(struct au_branch *br, struct aufs_stfs *stfs);
+
+/* xino.c */
+static const loff_t au_loff_max = LLONG_MAX;
+
+int au_xib_trunc(struct super_block *sb);
+ssize_t xino_fread(vfs_readf_t func, struct file *file, void *buf, size_t size,
+		   loff_t *pos);
+ssize_t xino_fwrite(vfs_writef_t func, struct file *file, void *buf,
+		    size_t size, loff_t *pos);
+struct file *au_xino_create2(struct file *base_file, struct file *copy_src);
+struct file *au_xino_create(struct super_block *sb, char *fname, int silent);
+ino_t au_xino_new_ino(struct super_block *sb);
+void au_xino_delete_inode(struct inode *inode, const int unlinked);
+int au_xino_write(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
+		  ino_t ino);
+int au_xino_read(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
+		 ino_t *ino);
+int au_xino_br(struct super_block *sb, struct au_branch *br, ino_t hino,
+	       struct file *base_file, int do_test);
+int au_xino_trunc(struct super_block *sb, aufs_bindex_t bindex);
+
+struct au_opt_xino;
+int au_xino_set(struct super_block *sb, struct au_opt_xino *xino, int remount);
+void au_xino_clr(struct super_block *sb);
+struct file *au_xino_def(struct super_block *sb);
+int au_xino_path(struct seq_file *seq, struct file *file);
+
+/* ---------------------------------------------------------------------- */
+
+/* Superblock to branch */
+static inline
+aufs_bindex_t au_sbr_id(struct super_block *sb, aufs_bindex_t bindex)
+{
+	return au_sbr(sb, bindex)->br_id;
+}
+
+static inline
+struct vfsmount *au_sbr_mnt(struct super_block *sb, aufs_bindex_t bindex)
+{
+	return au_br_mnt(au_sbr(sb, bindex));
+}
+
+static inline
+struct super_block *au_sbr_sb(struct super_block *sb, aufs_bindex_t bindex)
+{
+	return au_br_sb(au_sbr(sb, bindex));
+}
+
+static inline void au_sbr_put(struct super_block *sb, aufs_bindex_t bindex)
+{
+	atomic_dec(&au_sbr(sb, bindex)->br_count);
+}
+
+static inline int au_sbr_perm(struct super_block *sb, aufs_bindex_t bindex)
+{
+	return au_sbr(sb, bindex)->br_perm;
+}
+
+static inline int au_sbr_whable(struct super_block *sb, aufs_bindex_t bindex)
+{
+	return au_br_whable(au_sbr_perm(sb, bindex));
+}
+
+/* ---------------------------------------------------------------------- */
+
+/*
+ * wbr_wh_read_lock, wbr_wh_write_lock
+ * wbr_wh_read_unlock, wbr_wh_write_unlock, wbr_wh_downgrade_lock
+ */
+AuSimpleRwsemFuncs(wbr_wh, struct au_wbr *wbr, &wbr->wbr_wh_rwsem);
+
+#define WbrWhMustNoWaiters(wbr)	AuRwMustNoWaiters(&wbr->wbr_wh_rwsem)
+#define WbrWhMustAnyLock(wbr)	AuRwMustAnyLock(&wbr->wbr_wh_rwsem)
+#define WbrWhMustWriteLock(wbr)	AuRwMustWriteLock(&wbr->wbr_wh_rwsem)
+
+/* ---------------------------------------------------------------------- */
+
+#ifdef CONFIG_AUFS_FHSM
+static inline void au_br_fhsm_init(struct au_br_fhsm *brfhsm)
+{
+	mutex_init(&brfhsm->bf_lock);
+	brfhsm->bf_jiffy = 0;
+	brfhsm->bf_readable = 0;
+}
+
+static inline void au_br_fhsm_fin(struct au_br_fhsm *brfhsm)
+{
+	mutex_destroy(&brfhsm->bf_lock);
+}
+#else
+AuStubVoid(au_br_fhsm_init, struct au_br_fhsm *brfhsm)
+AuStubVoid(au_br_fhsm_fin, struct au_br_fhsm *brfhsm)
+#endif
+
+#endif /* __KERNEL__ */
+#endif /* __AUFS_BRANCH_H__ */
--- /dev/null
+++ zfcpdump-kernel-4.4/fs/aufs/conf.mk
@@ -0,0 +1,38 @@
+
+AuConfStr = CONFIG_AUFS_FS=${CONFIG_AUFS_FS}
+
+define AuConf
+ifdef ${1}
+AuConfStr += ${1}=${${1}}
+endif
+endef
+
+AuConfAll = BRANCH_MAX_127 BRANCH_MAX_511 BRANCH_MAX_1023 BRANCH_MAX_32767 \
+	SBILIST \
+	HNOTIFY HFSNOTIFY \
+	EXPORT INO_T_64 \
+	XATTR \
+	FHSM \
+	RDU \
+	SHWH \
+	BR_RAMFS \
+	BR_FUSE POLL \
+	BR_HFSPLUS \
+	BDEV_LOOP \
+	DEBUG MAGIC_SYSRQ
+$(foreach i, ${AuConfAll}, \
+	$(eval $(call AuConf,CONFIG_AUFS_${i})))
+
+AuConfName = ${obj}/conf.str
+${AuConfName}.tmp: FORCE
+	@echo ${AuConfStr} | tr ' ' '\n' | sed -e 's/^/"/' -e 's/$$/\\n"/' > $@
+${AuConfName}: ${AuConfName}.tmp
+	@diff -q $< $@ > /dev/null 2>&1 || { \
+	echo '  GEN    ' $@; \
+	cp -p $< $@; \
+	}
+FORCE:
+clean-files += ${AuConfName} ${AuConfName}.tmp
+${obj}/sysfs.o: ${AuConfName}
+
+-include ${srctree}/${src}/conf_priv.mk
--- /dev/null
+++ zfcpdump-kernel-4.4/fs/aufs/cpup.c
@@ -0,0 +1,1319 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+ *
+ * This program, aufs is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * copy-up functions, see wbr_policy.c for copy-down
+ */
+
+#include <linux/fs_stack.h>
+#include <linux/mm.h>
+#include "aufs.h"
+
+void au_cpup_attr_flags(struct inode *dst, unsigned int iflags)
+{
+	const unsigned int mask = S_DEAD | S_SWAPFILE | S_PRIVATE
+		| S_NOATIME | S_NOCMTIME | S_AUTOMOUNT;
+
+	BUILD_BUG_ON(sizeof(iflags) != sizeof(dst->i_flags));
+
+	dst->i_flags |= iflags & ~mask;
+	if (au_test_fs_notime(dst->i_sb))
+		dst->i_flags |= S_NOATIME | S_NOCMTIME;
+}
+
+void au_cpup_attr_timesizes(struct inode *inode)
+{
+	struct inode *h_inode;
+
+	h_inode = au_h_iptr(inode, au_ibstart(inode));
+	fsstack_copy_attr_times(inode, h_inode);
+	fsstack_copy_inode_size(inode, h_inode);
+}
+
+void au_cpup_attr_nlink(struct inode *inode, int force)
+{
+	struct inode *h_inode;
+	struct super_block *sb;
+	aufs_bindex_t bindex, bend;
+
+	sb = inode->i_sb;
+	bindex = au_ibstart(inode);
+	h_inode = au_h_iptr(inode, bindex);
+	if (!force
+	    && !S_ISDIR(h_inode->i_mode)
+	    && au_opt_test(au_mntflags(sb), PLINK)
+	    && au_plink_test(inode))
+		return;
+
+	/*
+	 * 0 can happen in revalidating.
+	 * h_inode->i_mutex may not be held here, but it is harmless since once
+	 * i_nlink reaches 0, it will never become positive except O_TMPFILE
+	 * case.
+	 * todo: O_TMPFILE+linkat(AT_SYMLINK_FOLLOW) bypassing aufs may cause
+	 *	 the incorrect link count.
+	 */
+	set_nlink(inode, h_inode->i_nlink);
+
+	/*
+	 * fewer nlink makes find(1) noisy, but larger nlink doesn't.
+	 * it may includes whplink directory.
+	 */
+	if (S_ISDIR(h_inode->i_mode)) {
+		bend = au_ibend(inode);
+		for (bindex++; bindex <= bend; bindex++) {
+			h_inode = au_h_iptr(inode, bindex);
+			if (h_inode)
+				au_add_nlink(inode, h_inode);
+		}
+	}
+}
+
+void au_cpup_attr_changeable(struct inode *inode)
+{
+	struct inode *h_inode;
+
+	h_inode = au_h_iptr(inode, au_ibstart(inode));
+	inode->i_mode = h_inode->i_mode;
+	inode->i_uid = h_inode->i_uid;
+	inode->i_gid = h_inode->i_gid;
+	au_cpup_attr_timesizes(inode);
+	au_cpup_attr_flags(inode, h_inode->i_flags);
+}
+
+void au_cpup_igen(struct inode *inode, struct inode *h_inode)
+{
+	struct au_iinfo *iinfo = au_ii(inode);
+
+	IiMustWriteLock(inode);
+
+	iinfo->ii_higen = h_inode->i_generation;
+	iinfo->ii_hsb1 = h_inode->i_sb;
+}
+
+void au_cpup_attr_all(struct inode *inode, int force)
+{
+	struct inode *h_inode;
+
+	h_inode = au_h_iptr(inode, au_ibstart(inode));
+	au_cpup_attr_changeable(inode);
+	if (inode->i_nlink > 0)
+		au_cpup_attr_nlink(inode, force);
+	inode->i_rdev = h_inode->i_rdev;
+	inode->i_blkbits = h_inode->i_blkbits;
+	au_cpup_igen(inode, h_inode);
+}
+
+/* ---------------------------------------------------------------------- */
+
+/* Note: dt_dentry and dt_h_dentry are not dget/dput-ed */
+
+/* keep the timestamps of the parent dir when cpup */
+void au_dtime_store(struct au_dtime *dt, struct dentry *dentry,
+		    struct path *h_path)
+{
+	struct inode *h_inode;
+
+	dt->dt_dentry = dentry;
+	dt->dt_h_path = *h_path;
+	h_inode = d_inode(h_path->dentry);
+	dt->dt_atime = h_inode->i_atime;
+	dt->dt_mtime = h_inode->i_mtime;
+	/* smp_mb(); */
+}
+
+void au_dtime_revert(struct au_dtime *dt)
+{
+	struct iattr attr;
+	int err;
+
+	attr.ia_atime = dt->dt_atime;
+	attr.ia_mtime = dt->dt_mtime;
+	attr.ia_valid = ATTR_FORCE | ATTR_MTIME | ATTR_MTIME_SET
+		| ATTR_ATIME | ATTR_ATIME_SET;
+
+	/* no delegation since this is a directory */
+	err = vfsub_notify_change(&dt->dt_h_path, &attr, /*delegated*/NULL);
+	if (unlikely(err))
+		pr_warn("restoring timestamps failed(%d). ignored\n", err);
+}
+
+/* ---------------------------------------------------------------------- */
+
+/* internal use only */
+struct au_cpup_reg_attr {
+	int		valid;
+	struct kstat	st;
+	unsigned int	iflags; /* inode->i_flags */
+};
+
+static noinline_for_stack
+int cpup_iattr(struct dentry *dst, aufs_bindex_t bindex, struct dentry *h_src,
+	       struct au_cpup_reg_attr *h_src_attr)
+{
+	int err, sbits, icex;
+	unsigned int mnt_flags;
+	unsigned char verbose;
+	struct iattr ia;
+	struct path h_path;
+	struct inode *h_isrc, *h_idst;
+	struct kstat *h_st;
+	struct au_branch *br;
+
+	h_path.dentry = au_h_dptr(dst, bindex);
+	h_idst = d_inode(h_path.dentry);
+	br = au_sbr(dst->d_sb, bindex);
+	h_path.mnt = au_br_mnt(br);
+	h_isrc = d_inode(h_src);
+	ia.ia_valid = ATTR_FORCE | ATTR_UID | ATTR_GID
+		| ATTR_ATIME | ATTR_MTIME
+		| ATTR_ATIME_SET | ATTR_MTIME_SET;
+	if (h_src_attr && h_src_attr->valid) {
+		h_st = &h_src_attr->st;
+		ia.ia_uid = h_st->uid;
+		ia.ia_gid = h_st->gid;
+		ia.ia_atime = h_st->atime;
+		ia.ia_mtime = h_st->mtime;
+		if (h_idst->i_mode != h_st->mode
+		    && !S_ISLNK(h_idst->i_mode)) {
+			ia.ia_valid |= ATTR_MODE;
+			ia.ia_mode = h_st->mode;
+		}
+		sbits = !!(h_st->mode & (S_ISUID | S_ISGID));
+		au_cpup_attr_flags(h_idst, h_src_attr->iflags);
+	} else {
+		ia.ia_uid = h_isrc->i_uid;
+		ia.ia_gid = h_isrc->i_gid;
+		ia.ia_atime = h_isrc->i_atime;
+		ia.ia_mtime = h_isrc->i_mtime;
+		if (h_idst->i_mode != h_isrc->i_mode
+		    && !S_ISLNK(h_idst->i_mode)) {
+			ia.ia_valid |= ATTR_MODE;
+			ia.ia_mode = h_isrc->i_mode;
+		}
+		sbits = !!(h_isrc->i_mode & (S_ISUID | S_ISGID));
+		au_cpup_attr_flags(h_idst, h_isrc->i_flags);
+	}
+	/* no delegation since it is just created */
+	err = vfsub_notify_change(&h_path, &ia, /*delegated*/NULL);
+
+	/* is this nfs only? */
+	if (!err && sbits && au_test_nfs(h_path.dentry->d_sb)) {
+		ia.ia_valid = ATTR_FORCE | ATTR_MODE;
+		ia.ia_mode = h_isrc->i_mode;
+		err = vfsub_notify_change(&h_path, &ia, /*delegated*/NULL);
+	}
+
+	icex = br->br_perm & AuBrAttr_ICEX;
+	if (!err) {
+		mnt_flags = au_mntflags(dst->d_sb);
+		verbose = !!au_opt_test(mnt_flags, VERBOSE);
+		err = au_cpup_xattr(h_path.dentry, h_src, icex, verbose);
+	}
+
+	return err;
+}
+
+/* ---------------------------------------------------------------------- */
+
+static int au_do_copy_file(struct file *dst, struct file *src, loff_t len,
+			   char *buf, unsigned long blksize)
+{
+	int err;
+	size_t sz, rbytes, wbytes;
+	unsigned char all_zero;
+	char *p, *zp;
+	struct mutex *h_mtx;
+	/* reduce stack usage */
+	struct iattr *ia;
+
+	zp = page_address(ZERO_PAGE(0));
+	if (unlikely(!zp))
+		return -ENOMEM; /* possible? */
+
+	err = 0;
+	all_zero = 0;
+	while (len) {
+		AuDbg("len %lld\n", len);
+		sz = blksize;
+		if (len < blksize)
+			sz = len;
+
+		rbytes = 0;
+		/* todo: signal_pending? */
+		while (!rbytes || err == -EAGAIN || err == -EINTR) {
+			rbytes = vfsub_read_k(src, buf, sz, &src->f_pos);
+			err = rbytes;
+		}
+		if (unlikely(err < 0))
+			break;
+
+		all_zero = 0;
+		if (len >= rbytes && rbytes == blksize)
+			all_zero = !memcmp(buf, zp, rbytes);
+		if (!all_zero) {
+			wbytes = rbytes;
+			p = buf;
+			while (wbytes) {
+				size_t b;
+
+				b = vfsub_write_k(dst, p, wbytes, &dst->f_pos);
+				err = b;
+				/* todo: signal_pending? */
+				if (unlikely(err == -EAGAIN || err == -EINTR))
+					continue;
+				if (unlikely(err < 0))
+					break;
+				wbytes -= b;
+				p += b;
+			}
+			if (unlikely(err < 0))
+				break;
+		} else {
+			loff_t res;
+
+			AuLabel(hole);
+			res = vfsub_llseek(dst, rbytes, SEEK_CUR);
+			err = res;
+			if (unlikely(res < 0))
+				break;
+		}
+		len -= rbytes;
+		err = 0;
+	}
+
+	/* the last block may be a hole */
+	if (!err && all_zero) {
+		AuLabel(last hole);
+
+		err = 1;
+		if (au_test_nfs(dst->f_path.dentry->d_sb)) {
+			/* nfs requires this step to make last hole */
+			/* is this only nfs? */
+			do {
+				/* todo: signal_pending? */
+				err = vfsub_write_k(dst, "\0", 1, &dst->f_pos);
+			} while (err == -EAGAIN || err == -EINTR);
+			if (err == 1)
+				dst->f_pos--;
+		}
+
+		if (err == 1) {
+			ia = (void *)buf;
+			ia->ia_size = dst->f_pos;
+			ia->ia_valid = ATTR_SIZE | ATTR_FILE;
+			ia->ia_file = dst;
+			h_mtx = &file_inode(dst)->i_mutex;
+			mutex_lock_nested(h_mtx, AuLsc_I_CHILD2);
+			/* no delegation since it is just created */
+			err = vfsub_notify_change(&dst->f_path, ia,
+						  /*delegated*/NULL);
+			mutex_unlock(h_mtx);
+		}
+	}
+
+	return err;
+}
+
+int au_copy_file(struct file *dst, struct file *src, loff_t len)
+{
+	int err;
+	unsigned long blksize;
+	unsigned char do_kfree;
+	char *buf;
+
+	err = -ENOMEM;
+	blksize = dst->f_path.dentry->d_sb->s_blocksize;
+	if (!blksize || PAGE_SIZE < blksize)
+		blksize = PAGE_SIZE;
+	AuDbg("blksize %lu\n", blksize);
+	do_kfree = (blksize != PAGE_SIZE && blksize >= sizeof(struct iattr *));
+	if (do_kfree)
+		buf = kmalloc(blksize, GFP_NOFS);
+	else
+		buf = (void *)__get_free_page(GFP_NOFS);
+	if (unlikely(!buf))
+		goto out;
+
+	if (len > (1 << 22))
+		AuDbg("copying a large file %lld\n", (long long)len);
+
+	src->f_pos = 0;
+	dst->f_pos = 0;
+	err = au_do_copy_file(dst, src, len, buf, blksize);
+	if (do_kfree)
+		kfree(buf);
+	else
+		free_page((unsigned long)buf);
+
+out:
+	return err;
+}
+
+/*
+ * to support a sparse file which is opened with O_APPEND,
+ * we need to close the file.
+ */
+static int au_cp_regular(struct au_cp_generic *cpg)
+{
+	int err, i;
+	enum { SRC, DST };
+	struct {
+		aufs_bindex_t bindex;
+		unsigned int flags;
+		struct dentry *dentry;
+		int force_wr;
+		struct file *file;
+		void *label;
+	} *f, file[] = {
+		{
+			.bindex = cpg->bsrc,
+			.flags = O_RDONLY | O_NOATIME | O_LARGEFILE,
+			.label = &&out
+		},
+		{
+			.bindex = cpg->bdst,
+			.flags = O_WRONLY | O_NOATIME | O_LARGEFILE,
+			.force_wr = !!au_ftest_cpup(cpg->flags, RWDST),
+			.label = &&out_src
+		}
+	};
+	struct super_block *sb;
+
+	/* bsrc branch can be ro/rw. */
+	sb = cpg->dentry->d_sb;
+	f = file;
+	for (i = 0; i < 2; i++, f++) {
+		f->dentry = au_h_dptr(cpg->dentry, f->bindex);
+		f->file = au_h_open(cpg->dentry, f->bindex, f->flags,
+				    /*file*/NULL, f->force_wr);
+		err = PTR_ERR(f->file);
+		if (IS_ERR(f->file))
+			goto *f->label;
+	}
+
+	/* try stopping to update while we copyup */
+	IMustLock(d_inode(file[SRC].dentry));
+	err = au_copy_file(file[DST].file, file[SRC].file, cpg->len);
+
+	fput(file[DST].file);
+	au_sbr_put(sb, file[DST].bindex);
+
+out_src:
+	fput(file[SRC].file);
+	au_sbr_put(sb, file[SRC].bindex);
+out:
+	return err;
+}
+
+static int au_do_cpup_regular(struct au_cp_generic *cpg,
+			      struct au_cpup_reg_attr *h_src_attr)
+{
+	int err, rerr;
+	loff_t l;
+	struct path h_path;
+	struct inode *h_src_inode, *h_dst_inode;
+
+	err = 0;
+	h_src_inode = au_h_iptr(d_inode(cpg->dentry), cpg->bsrc);
+	l = i_size_read(h_src_inode);
+	if (cpg->len == -1 || l < cpg->len)
+		cpg->len = l;
+	if (cpg->len) {
+		/* try stopping to update while we are referencing */
+		mutex_lock_nested(&h_src_inode->i_mutex, AuLsc_I_CHILD);
+		au_pin_hdir_unlock(cpg->pin);
+
+		h_path.dentry = au_h_dptr(cpg->dentry, cpg->bsrc);
+		h_path.mnt = au_sbr_mnt(cpg->dentry->d_sb, cpg->bsrc);
+		h_src_attr->iflags = h_src_inode->i_flags;
+		if (!au_test_nfs(h_src_inode->i_sb))
+			err = vfs_getattr(&h_path, &h_src_attr->st);
+		else {
+			mutex_unlock(&h_src_inode->i_mutex);
+			err = vfs_getattr(&h_path, &h_src_attr->st);
+			mutex_lock_nested(&h_src_inode->i_mutex, AuLsc_I_CHILD);
+		}
+		if (unlikely(err)) {
+			mutex_unlock(&h_src_inode->i_mutex);
+			goto out;
+		}
+		h_src_attr->valid = 1;
+		err = au_cp_regular(cpg);
+		mutex_unlock(&h_src_inode->i_mutex);
+		rerr = au_pin_hdir_relock(cpg->pin);
+		if (!err && rerr)
+			err = rerr;
+	}
+	if (!err && (h_src_inode->i_state & I_LINKABLE)) {
+		h_path.dentry = au_h_dptr(cpg->dentry, cpg->bdst);
+		h_dst_inode = d_inode(h_path.dentry);
+		spin_lock(&h_dst_inode->i_lock);
+		h_dst_inode->i_state |= I_LINKABLE;
+		spin_unlock(&h_dst_inode->i_lock);
+	}
+
+out:
+	return err;
+}
+
+static int au_do_cpup_symlink(struct path *h_path, struct dentry *h_src,
+			      struct inode *h_dir)
+{
+	int err, symlen;
+	mm_segment_t old_fs;
+	union {
+		char *k;
+		char __user *u;
+	} sym;
+	struct inode *h_inode = d_inode(h_src);
+	const struct inode_operations *h_iop = h_inode->i_op;
+
+	err = -ENOSYS;
+	if (unlikely(!h_iop->readlink))
+		goto out;
+
+	err = -ENOMEM;
+	sym.k = (void *)__get_free_page(GFP_NOFS);
+	if (unlikely(!sym.k))
+		goto out;
+
+	/* unnecessary to support mmap_sem since symlink is not mmap-able */
+	old_fs = get_fs();
+	set_fs(KERNEL_DS);
+	symlen = h_iop->readlink(h_src, sym.u, PATH_MAX);
+	err = symlen;
+	set_fs(old_fs);
+
+	if (symlen > 0) {
+		sym.k[symlen] = 0;
+		err = vfsub_symlink(h_dir, h_path, sym.k);
+	}
+	free_page((unsigned long)sym.k);
+
+out:
+	return err;
+}
+
+static noinline_for_stack
+int cpup_entry(struct au_cp_generic *cpg, struct dentry *dst_parent,
+	       struct au_cpup_reg_attr *h_src_attr)
+{
+	int err;
+	umode_t mode;
+	unsigned int mnt_flags;
+	unsigned char isdir, isreg, force;
+	const unsigned char do_dt = !!au_ftest_cpup(cpg->flags, DTIME);
+	struct au_dtime dt;
+	struct path h_path;
+	struct dentry *h_src, *h_dst, *h_parent;
+	struct inode *h_inode, *h_dir, *dir, *inode;
+	struct super_block *sb;
+
+	/* bsrc branch can be ro/rw. */
+	h_src = au_h_dptr(cpg->dentry, cpg->bsrc);
+	h_inode = d_inode(h_src);
+	AuDebugOn(h_inode != au_h_iptr(d_inode(cpg->dentry), cpg->bsrc));
+
+	/* try stopping to be referenced while we are creating */
+	h_dst = au_h_dptr(cpg->dentry, cpg->bdst);
+	if (au_ftest_cpup(cpg->flags, RENAME))
+		AuDebugOn(strncmp(h_dst->d_name.name, AUFS_WH_PFX,
+				  AUFS_WH_PFX_LEN));
+	h_parent = h_dst->d_parent; /* dir inode is locked */
+	h_dir = d_inode(h_parent);
+	IMustLock(h_dir);
+	AuDebugOn(h_parent != h_dst->d_parent);
+
+	sb = cpg->dentry->d_sb;
+	h_path.mnt = au_sbr_mnt(sb, cpg->bdst);
+	if (do_dt) {
+		h_path.dentry = h_parent;
+		au_dtime_store(&dt, dst_parent, &h_path);
+	}
+	h_path.dentry = h_dst;
+
+	isreg = 0;
+	isdir = 0;
+	mode = h_inode->i_mode;
+	switch (mode & S_IFMT) {
+	case S_IFREG:
+		isreg = 1;
+		err = vfsub_create(h_dir, &h_path, mode | S_IWUSR,
+				   /*want_excl*/true);
+		if (!err)
+			err = au_do_cpup_regular(cpg, h_src_attr);
+		break;
+	case S_IFDIR:
+		isdir = 1;
+		err = vfsub_mkdir(h_dir, &h_path, mode);
+		if (!err) {
+			/*
+			 * strange behaviour from the users view,
+			 * particularry setattr case
+			 */
+			dir = d_inode(dst_parent);
+			if (au_ibstart(dir) == cpg->bdst)
+				au_cpup_attr_nlink(dir, /*force*/1);
+			inode = d_inode(cpg->dentry);
+			au_cpup_attr_nlink(inode, /*force*/1);
+		}
+		break;
+	case S_IFLNK:
+		err = au_do_cpup_symlink(&h_path, h_src, h_dir);
+		break;
+	case S_IFCHR:
+	case S_IFBLK:
+		AuDebugOn(!capable(CAP_MKNOD));
+		/*FALLTHROUGH*/
+	case S_IFIFO:
+	case S_IFSOCK:
+		err = vfsub_mknod(h_dir, &h_path, mode, h_inode->i_rdev);
+		break;
+	default:
+		AuIOErr("Unknown inode type 0%o\n", mode);
+		err = -EIO;
+	}
+
+	mnt_flags = au_mntflags(sb);
+	if (!au_opt_test(mnt_flags, UDBA_NONE)
+	    && !isdir
+	    && au_opt_test(mnt_flags, XINO)
+	    && (h_inode->i_nlink == 1
+		|| (h_inode->i_state & I_LINKABLE))
+	    /* todo: unnecessary? */
+	    /* && d_inode(cpg->dentry)->i_nlink == 1 */
+	    && cpg->bdst < cpg->bsrc
+	    && !au_ftest_cpup(cpg->flags, KEEPLINO))
+		au_xino_write(sb, cpg->bsrc, h_inode->i_ino, /*ino*/0);
+		/* ignore this error */
+
+	if (!err) {
+		force = 0;
+		if (isreg) {
+			force = !!cpg->len;
+			if (cpg->len == -1)
+				force = !!i_size_read(h_inode);
+		}
+		au_fhsm_wrote(sb, cpg->bdst, force);
+	}
+
+	if (do_dt)
+		au_dtime_revert(&dt);
+	return err;
+}
+
+static int au_do_ren_after_cpup(struct au_cp_generic *cpg, struct path *h_path)
+{
+	int err;
+	struct dentry *dentry, *h_dentry, *h_parent, *parent;
+	struct inode *h_dir;
+	aufs_bindex_t bdst;
+
+	dentry = cpg->dentry;
+	bdst = cpg->bdst;
+	h_dentry = au_h_dptr(dentry, bdst);
+	if (!au_ftest_cpup(cpg->flags, OVERWRITE)) {
+		dget(h_dentry);
+		au_set_h_dptr(dentry, bdst, NULL);
+		err = au_lkup_neg(dentry, bdst, /*wh*/0);
+		if (!err)
+			h_path->dentry = dget(au_h_dptr(dentry, bdst));
+		au_set_h_dptr(dentry, bdst, h_dentry);
+	} else {
+		err = 0;
+		parent = dget_parent(dentry);
+		h_parent = au_h_dptr(parent, bdst);
+		dput(parent);
+		h_path->dentry = vfsub_lkup_one(&dentry->d_name, h_parent);
+		if (IS_ERR(h_path->dentry))
+			err = PTR_ERR(h_path->dentry);
+	}
+	if (unlikely(err))
+		goto out;
+
+	h_parent = h_dentry->d_parent; /* dir inode is locked */
+	h_dir = d_inode(h_parent);
+	IMustLock(h_dir);
+	AuDbg("%pd %pd\n", h_dentry, h_path->dentry);
+	/* no delegation since it is just created */
+	err = vfsub_rename(h_dir, h_dentry, h_dir, h_path, /*delegated*/NULL);
+	dput(h_path->dentry);
+
+out:
+	return err;
+}
+
+/*
+ * copyup the @dentry from @bsrc to @bdst.
+ * the caller must set the both of lower dentries.
+ * @len is for truncating when it is -1 copyup the entire file.
+ * in link/rename cases, @dst_parent may be different from the real one.
+ * basic->bsrc can be larger than basic->bdst.
+ */
+static int au_cpup_single(struct au_cp_generic *cpg, struct dentry *dst_parent)
+{
+	int err, rerr;
+	aufs_bindex_t old_ibstart;
+	unsigned char isdir, plink;
+	struct dentry *h_src, *h_dst, *h_parent;
+	struct inode *dst_inode, *h_dir, *inode, *delegated, *src_inode;
+	struct super_block *sb;
+	struct au_branch *br;
+	/* to reuduce stack size */
+	struct {
+		struct au_dtime dt;
+		struct path h_path;
+		struct au_cpup_reg_attr h_src_attr;
+	} *a;
+
+	err = -ENOMEM;
+	a = kmalloc(sizeof(*a), GFP_NOFS);
+	if (unlikely(!a))
+		goto out;
+	a->h_src_attr.valid = 0;
+
+	sb = cpg->dentry->d_sb;
+	br = au_sbr(sb, cpg->bdst);
+	a->h_path.mnt = au_br_mnt(br);
+	h_dst = au_h_dptr(cpg->dentry, cpg->bdst);
+	h_parent = h_dst->d_parent; /* dir inode is locked */
+	h_dir = d_inode(h_parent);
+	IMustLock(h_dir);
+
+	h_src = au_h_dptr(cpg->dentry, cpg->bsrc);
+	inode = d_inode(cpg->dentry);
+
+	if (!dst_parent)
+		dst_parent = dget_parent(cpg->dentry);
+	else
+		dget(dst_parent);
+
+	plink = !!au_opt_test(au_mntflags(sb), PLINK);
+	dst_inode = au_h_iptr(inode, cpg->bdst);
+	if (dst_inode) {
+		if (unlikely(!plink)) {
+			err = -EIO;
+			AuIOErr("hi%lu(i%lu) exists on b%d "
+				"but plink is disabled\n",
+				dst_inode->i_ino, inode->i_ino, cpg->bdst);
+			goto out_parent;
+		}
+
+		if (dst_inode->i_nlink) {
+			const int do_dt = au_ftest_cpup(cpg->flags, DTIME);
+
+			h_src = au_plink_lkup(inode, cpg->bdst);
+			err = PTR_ERR(h_src);
+			if (IS_ERR(h_src))
+				goto out_parent;
+			if (unlikely(d_is_negative(h_src))) {
+				err = -EIO;
+				AuIOErr("i%lu exists on b%d "
+					"but not pseudo-linked\n",
+					inode->i_ino, cpg->bdst);
+				dput(h_src);
+				goto out_parent;
+			}
+
+			if (do_dt) {
+				a->h_path.dentry = h_parent;
+				au_dtime_store(&a->dt, dst_parent, &a->h_path);
+			}
+
+			a->h_path.dentry = h_dst;
+			delegated = NULL;
+			err = vfsub_link(h_src, h_dir, &a->h_path, &delegated);
+			if (!err && au_ftest_cpup(cpg->flags, RENAME))
+				err = au_do_ren_after_cpup(cpg, &a->h_path);
+			if (do_dt)
+				au_dtime_revert(&a->dt);
+			if (unlikely(err == -EWOULDBLOCK)) {
+				pr_warn("cannot retry for NFSv4 delegation"
+					" for an internal link\n");
+				iput(delegated);
+			}
+			dput(h_src);
+			goto out_parent;
+		} else
+			/* todo: cpup_wh_file? */
+			/* udba work */
+			au_update_ibrange(inode, /*do_put_zero*/1);
+	}
+
+	isdir = S_ISDIR(inode->i_mode);
+	old_ibstart = au_ibstart(inode);
+	err = cpup_entry(cpg, dst_parent, &a->h_src_attr);
+	if (unlikely(err))
+		goto out_rev;
+	dst_inode = d_inode(h_dst);
+	mutex_lock_nested(&dst_inode->i_mutex, AuLsc_I_CHILD2);
+	/* todo: necessary? */
+	/* au_pin_hdir_unlock(cpg->pin); */
+
+	err = cpup_iattr(cpg->dentry, cpg->bdst, h_src, &a->h_src_attr);
+	if (unlikely(err)) {
+		/* todo: necessary? */
+		/* au_pin_hdir_relock(cpg->pin); */ /* ignore an error */
+		mutex_unlock(&dst_inode->i_mutex);
+		goto out_rev;
+	}
+
+	if (cpg->bdst < old_ibstart) {
+		if (S_ISREG(inode->i_mode)) {
+			err = au_dy_iaop(inode, cpg->bdst, dst_inode);
+			if (unlikely(err)) {
+				/* ignore an error */
+				/* au_pin_hdir_relock(cpg->pin); */
+				mutex_unlock(&dst_inode->i_mutex);
+				goto out_rev;
+			}
+		}
+		au_set_ibstart(inode, cpg->bdst);
+	} else
+		au_set_ibend(inode, cpg->bdst);
+	au_set_h_iptr(inode, cpg->bdst, au_igrab(dst_inode),
+		      au_hi_flags(inode, isdir));
+
+	/* todo: necessary? */
+	/* err = au_pin_hdir_relock(cpg->pin); */
+	mutex_unlock(&dst_inode->i_mutex);
+	if (unlikely(err))
+		goto out_rev;
+
+	src_inode = d_inode(h_src);
+	if (!isdir
+	    && (src_inode->i_nlink > 1
+		|| src_inode->i_state & I_LINKABLE)
+	    && plink)
+		au_plink_append(inode, cpg->bdst, h_dst);
+
+	if (au_ftest_cpup(cpg->flags, RENAME)) {
+		a->h_path.dentry = h_dst;
+		err = au_do_ren_after_cpup(cpg, &a->h_path);
+	}
+	if (!err)
+		goto out_parent; /* success */
+
+	/* revert */
+out_rev:
+	a->h_path.dentry = h_parent;
+	au_dtime_store(&a->dt, dst_parent, &a->h_path);
+	a->h_path.dentry = h_dst;
+	rerr = 0;
+	if (d_is_positive(h_dst)) {
+		if (!isdir) {
+			/* no delegation since it is just created */
+			rerr = vfsub_unlink(h_dir, &a->h_path,
+					    /*delegated*/NULL, /*force*/0);
+		} else
+			rerr = vfsub_rmdir(h_dir, &a->h_path);
+	}
+	au_dtime_revert(&a->dt);
+	if (rerr) {
+		AuIOErr("failed removing broken entry(%d, %d)\n", err, rerr);
+		err = -EIO;
+	}
+out_parent:
+	dput(dst_parent);
+	kfree(a);
+out:
+	return err;
+}
+
+#if 0 /* reserved */
+struct au_cpup_single_args {
+	int *errp;
+	struct au_cp_generic *cpg;
+	struct dentry *dst_parent;
+};
+
+static void au_call_cpup_single(void *args)
+{
+	struct au_cpup_single_args *a = args;
+
+	au_pin_hdir_acquire_nest(a->cpg->pin);
+	*a->errp = au_cpup_single(a->cpg, a->dst_parent);
+	au_pin_hdir_release(a->cpg->pin);
+}
+#endif
+
+/*
+ * prevent SIGXFSZ in copy-up.
+ * testing CAP_MKNOD is for generic fs,
+ * but CAP_FSETID is for xfs only, currently.
+ */
+static int au_cpup_sio_test(struct au_pin *pin, umode_t mode)
+{
+	int do_sio;
+	struct super_block *sb;
+	struct inode *h_dir;
+
+	do_sio = 0;
+	sb = au_pinned_parent(pin)->d_sb;
+	if (!au_wkq_test()
+	    && (!au_sbi(sb)->si_plink_maint_pid
+		|| au_plink_maint(sb, AuLock_NOPLM))) {
+		switch (mode & S_IFMT) {
+		case S_IFREG:
+			/* no condition about RLIMIT_FSIZE and the file size */
+			do_sio = 1;
+			break;
+		case S_IFCHR:
+		case S_IFBLK:
+			do_sio = !capable(CAP_MKNOD);
+			break;
+		}
+		if (!do_sio)
+			do_sio = ((mode & (S_ISUID | S_ISGID))
+				  && !capable(CAP_FSETID));
+		/* this workaround may be removed in the future */
+		if (!do_sio) {
+			h_dir = au_pinned_h_dir(pin);
+			do_sio = h_dir->i_mode & S_ISVTX;
+		}
+	}
+
+	return do_sio;
+}
+
+#if 0 /* reserved */
+int au_sio_cpup_single(struct au_cp_generic *cpg, struct dentry *dst_parent)
+{
+	int err, wkq_err;
+	struct dentry *h_dentry;
+
+	h_dentry = au_h_dptr(cpg->dentry, cpg->bsrc);
+	if (!au_cpup_sio_test(pin, d_inode(h_dentry)->i_mode))
+		err = au_cpup_single(cpg, dst_parent);
+	else {
+		struct au_cpup_single_args args = {
+			.errp		= &err,
+			.cpg		= cpg,
+			.dst_parent	= dst_parent
+		};
+		wkq_err = au_wkq_wait(au_call_cpup_single, &args);
+		if (unlikely(wkq_err))
+			err = wkq_err;
+	}
+
+	return err;
+}
+#endif
+
+/*
+ * copyup the @dentry from the first active lower branch to @bdst,
+ * using au_cpup_single().
+ */
+static int au_cpup_simple(struct au_cp_generic *cpg)
+{
+	int err;
+	unsigned int flags_orig;
+	struct dentry *dentry;
+
+	AuDebugOn(cpg->bsrc < 0);
+
+	dentry = cpg->dentry;
+	DiMustWriteLock(dentry);
+
+	err = au_lkup_neg(dentry, cpg->bdst, /*wh*/1);
+	if (!err) {
+		flags_orig = cpg->flags;
+		au_fset_cpup(cpg->flags, RENAME);
+		err = au_cpup_single(cpg, NULL);
+		cpg->flags = flags_orig;
+		if (!err)
+			return 0; /* success */
+
+		/* revert */
+		au_set_h_dptr(dentry, cpg->bdst, NULL);
+		au_set_dbstart(dentry, cpg->bsrc);
+	}
+
+	return err;
+}
+
+struct au_cpup_simple_args {
+	int *errp;
+	struct au_cp_generic *cpg;
+};
+
+static void au_call_cpup_simple(void *args)
+{
+	struct au_cpup_simple_args *a = args;
+
+	au_pin_hdir_acquire_nest(a->cpg->pin);
+	*a->errp = au_cpup_simple(a->cpg);
+	au_pin_hdir_release(a->cpg->pin);
+}
+
+static int au_do_sio_cpup_simple(struct au_cp_generic *cpg)
+{
+	int err, wkq_err;
+	struct dentry *dentry, *parent;
+	struct file *h_file;
+	struct inode *h_dir;
+
+	dentry = cpg->dentry;
+	h_file = NULL;
+	if (au_ftest_cpup(cpg->flags, HOPEN)) {
+		AuDebugOn(cpg->bsrc < 0);
+		h_file = au_h_open_pre(dentry, cpg->bsrc, /*force_wr*/0);
+		err = PTR_ERR(h_file);
+		if (IS_ERR(h_file))
+			goto out;
+	}
+
+	parent = dget_parent(dentry);
+	h_dir = au_h_iptr(d_inode(parent), cpg->bdst);
+	if (!au_test_h_perm_sio(h_dir, MAY_EXEC | MAY_WRITE)
+	    && !au_cpup_sio_test(cpg->pin, d_inode(dentry)->i_mode))
+		err = au_cpup_simple(cpg);
+	else {
+		struct au_cpup_simple_args args = {
+			.errp		= &err,
+			.cpg		= cpg
+		};
+		wkq_err = au_wkq_wait(au_call_cpup_simple, &args);
+		if (unlikely(wkq_err))
+			err = wkq_err;
+	}
+
+	dput(parent);
+	if (h_file)
+		au_h_open_post(dentry, cpg->bsrc, h_file);
+
+out:
+	return err;
+}
+
+int au_sio_cpup_simple(struct au_cp_generic *cpg)
+{
+	aufs_bindex_t bsrc, bend;
+	struct dentry *dentry, *h_dentry;
+
+	if (cpg->bsrc < 0) {
+		dentry = cpg->dentry;
+		bend = au_dbend(dentry);
+		for (bsrc = cpg->bdst + 1; bsrc <= bend; bsrc++) {
+			h_dentry = au_h_dptr(dentry, bsrc);
+			if (h_dentry) {
+				AuDebugOn(d_is_negative(h_dentry));
+				break;
+			}
+		}
+		AuDebugOn(bsrc > bend);
+		cpg->bsrc = bsrc;
+	}
+	AuDebugOn(cpg->bsrc <= cpg->bdst);
+	return au_do_sio_cpup_simple(cpg);
+}
+
+int au_sio_cpdown_simple(struct au_cp_generic *cpg)
+{
+	AuDebugOn(cpg->bdst <= cpg->bsrc);
+	return au_do_sio_cpup_simple(cpg);
+}
+
+/* ---------------------------------------------------------------------- */
+
+/*
+ * copyup the deleted file for writing.
+ */
+static int au_do_cpup_wh(struct au_cp_generic *cpg, struct dentry *wh_dentry,
+			 struct file *file)
+{
+	int err;
+	unsigned int flags_orig;
+	aufs_bindex_t bsrc_orig;
+	struct dentry *h_d_dst, *h_d_start;
+	struct au_dinfo *dinfo;
+	struct au_hdentry *hdp;
+
+	dinfo = au_di(cpg->dentry);
+	AuRwMustWriteLock(&dinfo->di_rwsem);
+
+	bsrc_orig = cpg->bsrc;
+	cpg->bsrc = dinfo->di_bstart;
+	hdp = dinfo->di_hdentry;
+	h_d_dst = hdp[0 + cpg->bdst].hd_dentry;
+	dinfo->di_bstart = cpg->bdst;
+	hdp[0 + cpg->bdst].hd_dentry = wh_dentry;
+	h_d_start = NULL;
+	if (file) {
+		h_d_start = hdp[0 + cpg->bsrc].hd_dentry;
+		hdp[0 + cpg->bsrc].hd_dentry = au_hf_top(file)->f_path.dentry;
+	}
+	flags_orig = cpg->flags;
+	cpg->flags = !AuCpup_DTIME;
+	err = au_cpup_single(cpg, /*h_parent*/NULL);
+	cpg->flags = flags_orig;
+	if (file) {
+		if (!err)
+			err = au_reopen_nondir(file);
+		hdp[0 + cpg->bsrc].hd_dentry = h_d_start;
+	}
+	hdp[0 + cpg->bdst].hd_dentry = h_d_dst;
+	dinfo->di_bstart = cpg->bsrc;
+	cpg->bsrc = bsrc_orig;
+
+	return err;
+}
+
+static int au_cpup_wh(struct au_cp_generic *cpg, struct file *file)
+{
+	int err;
+	aufs_bindex_t bdst;
+	struct au_dtime dt;
+	struct dentry *dentry, *parent, *h_parent, *wh_dentry;
+	struct au_branch *br;
+	struct path h_path;
+
+	dentry = cpg->dentry;
+	bdst = cpg->bdst;
+	br = au_sbr(dentry->d_sb, bdst);
+	parent = dget_parent(dentry);
+	h_parent = au_h_dptr(parent, bdst);
+	wh_dentry = au_whtmp_lkup(h_parent, br, &dentry->d_name);
+	err = PTR_ERR(wh_dentry);
+	if (IS_ERR(wh_dentry))
+		goto out;
+
+	h_path.dentry = h_parent;
+	h_path.mnt = au_br_mnt(br);
+	au_dtime_store(&dt, parent, &h_path);
+	err = au_do_cpup_wh(cpg, wh_dentry, file);
+	if (unlikely(err))
+		goto out_wh;
+
+	dget(wh_dentry);
+	h_path.dentry = wh_dentry;
+	if (!d_is_dir(wh_dentry)) {
+		/* no delegation since it is just created */
+		err = vfsub_unlink(d_inode(h_parent), &h_path,
+				   /*delegated*/NULL, /*force*/0);
+	} else
+		err = vfsub_rmdir(d_inode(h_parent), &h_path);
+	if (unlikely(err)) {
+		AuIOErr("failed remove copied-up tmp file %pd(%d)\n",
+			wh_dentry, err);
+		err = -EIO;
+	}
+	au_dtime_revert(&dt);
+	au_set_hi_wh(d_inode(dentry), bdst, wh_dentry);
+
+out_wh:
+	dput(wh_dentry);
+out:
+	dput(parent);
+	return err;
+}
+
+struct au_cpup_wh_args {
+	int *errp;
+	struct au_cp_generic *cpg;
+	struct file *file;
+};
+
+static void au_call_cpup_wh(void *args)
+{
+	struct au_cpup_wh_args *a = args;
+
+	au_pin_hdir_acquire_nest(a->cpg->pin);
+	*a->errp = au_cpup_wh(a->cpg, a->file);
+	au_pin_hdir_release(a->cpg->pin);
+}
+
+int au_sio_cpup_wh(struct au_cp_generic *cpg, struct file *file)
+{
+	int err, wkq_err;
+	aufs_bindex_t bdst;
+	struct dentry *dentry, *parent, *h_orph, *h_parent;
+	struct inode *dir, *h_dir, *h_tmpdir;
+	struct au_wbr *wbr;
+	struct au_pin wh_pin, *pin_orig;
+
+	dentry = cpg->dentry;
+	bdst = cpg->bdst;
+	parent = dget_parent(dentry);
+	dir = d_inode(parent);
+	h_orph = NULL;
+	h_parent = NULL;
+	h_dir = au_igrab(au_h_iptr(dir, bdst));
+	h_tmpdir = h_dir;
+	pin_orig = NULL;
+	if (!h_dir->i_nlink) {
+		wbr = au_sbr(dentry->d_sb, bdst)->br_wbr;
+		h_orph = wbr->wbr_orph;
+
+		h_parent = dget(au_h_dptr(parent, bdst));
+		au_set_h_dptr(parent, bdst, dget(h_orph));
+		h_tmpdir = d_inode(h_orph);
+		au_set_h_iptr(dir, bdst, au_igrab(h_tmpdir), /*flags*/0);
+
+		mutex_lock_nested(&h_tmpdir->i_mutex, AuLsc_I_PARENT3);
+		/* todo: au_h_open_pre()? */
+
+		pin_orig = cpg->pin;
+		au_pin_init(&wh_pin, dentry, bdst, AuLsc_DI_PARENT,
+			    AuLsc_I_PARENT3, cpg->pin->udba, AuPin_DI_LOCKED);
+		cpg->pin = &wh_pin;
+	}
+
+	if (!au_test_h_perm_sio(h_tmpdir, MAY_EXEC | MAY_WRITE)
+	    && !au_cpup_sio_test(cpg->pin, d_inode(dentry)->i_mode))
+		err = au_cpup_wh(cpg, file);
+	else {
+		struct au_cpup_wh_args args = {
+			.errp	= &err,
+			.cpg	= cpg,
+			.file	= file
+		};
+		wkq_err = au_wkq_wait(au_call_cpup_wh, &args);
+		if (unlikely(wkq_err))
+			err = wkq_err;
+	}
+
+	if (h_orph) {
+		mutex_unlock(&h_tmpdir->i_mutex);
+		/* todo: au_h_open_post()? */
+		au_set_h_iptr(dir, bdst, au_igrab(h_dir), /*flags*/0);
+		au_set_h_dptr(parent, bdst, h_parent);
+		AuDebugOn(!pin_orig);
+		cpg->pin = pin_orig;
+	}
+	iput(h_dir);
+	dput(parent);
+
+	return err;
+}
+
+/* ---------------------------------------------------------------------- */
+
+/*
+ * generic routine for both of copy-up and copy-down.
+ */
+/* cf. revalidate function in file.c */
+int au_cp_dirs(struct dentry *dentry, aufs_bindex_t bdst,
+	       int (*cp)(struct dentry *dentry, aufs_bindex_t bdst,
+			 struct au_pin *pin,
+			 struct dentry *h_parent, void *arg),
+	       void *arg)
+{
+	int err;
+	struct au_pin pin;
+	struct dentry *d, *parent, *h_parent, *real_parent, *h_dentry;
+
+	err = 0;
+	parent = dget_parent(dentry);
+	if (IS_ROOT(parent))
+		goto out;
+
+	au_pin_init(&pin, dentry, bdst, AuLsc_DI_PARENT2, AuLsc_I_PARENT2,
+		    au_opt_udba(dentry->d_sb), AuPin_MNT_WRITE);
+
+	/* do not use au_dpage */
+	real_parent = parent;
+	while (1) {
+		dput(parent);
+		parent = dget_parent(dentry);
+		h_parent = au_h_dptr(parent, bdst);
+		if (h_parent)
+			goto out; /* success */
+
+		/* find top dir which is necessary to cpup */
+		do {
+			d = parent;
+			dput(parent);
+			parent = dget_parent(d);
+			di_read_lock_parent3(parent, !AuLock_IR);
+			h_parent = au_h_dptr(parent, bdst);
+			di_read_unlock(parent, !AuLock_IR);
+		} while (!h_parent);
+
+		if (d != real_parent)
+			di_write_lock_child3(d);
+
+		/* somebody else might create while we were sleeping */
+		h_dentry = au_h_dptr(d, bdst);
+		if (!h_dentry || d_is_negative(h_dentry)) {
+			if (h_dentry)
+				au_update_dbstart(d);
+
+			au_pin_set_dentry(&pin, d);
+			err = au_do_pin(&pin);
+			if (!err) {
+				err = cp(d, bdst, &pin, h_parent, arg);
+				au_unpin(&pin);
+			}
+		}
+
+		if (d != real_parent)
+			di_write_unlock(d);
+		if (unlikely(err))
+			break;
+	}
+
+out:
+	dput(parent);
+	return err;
+}
+
+static int au_cpup_dir(struct dentry *dentry, aufs_bindex_t bdst,
+		       struct au_pin *pin,
+		       struct dentry *h_parent __maybe_unused,
+		       void *arg __maybe_unused)
+{
+	struct au_cp_generic cpg = {
+		.dentry	= dentry,
+		.bdst	= bdst,
+		.bsrc	= -1,
+		.len	= 0,
+		.pin	= pin,
+		.flags	= AuCpup_DTIME
+	};
+	return au_sio_cpup_simple(&cpg);
+}
+
+int au_cpup_dirs(struct dentry *dentry, aufs_bindex_t bdst)
+{
+	return au_cp_dirs(dentry, bdst, au_cpup_dir, NULL);
+}
+
+int au_test_and_cpup_dirs(struct dentry *dentry, aufs_bindex_t bdst)
+{
+	int err;
+	struct dentry *parent;
+	struct inode *dir;
+
+	parent = dget_parent(dentry);
+	dir = d_inode(parent);
+	err = 0;
+	if (au_h_iptr(dir, bdst))
+		goto out;
+
+	di_read_unlock(parent, AuLock_IR);
+	di_write_lock_parent(parent);
+	/* someone else might change our inode while we were sleeping */
+	if (!au_h_iptr(dir, bdst))
+		err = au_cpup_dirs(dentry, bdst);
+	di_downgrade_lock(parent, AuLock_IR);
+
+out:
+	dput(parent);
+	return err;
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/fs/aufs/cpup.h
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+ *
+ * This program, aufs is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * copy-up/down functions
+ */
+
+#ifndef __AUFS_CPUP_H__
+#define __AUFS_CPUP_H__
+
+#ifdef __KERNEL__
+
+#include <linux/path.h>
+
+struct inode;
+struct file;
+struct au_pin;
+
+void au_cpup_attr_flags(struct inode *dst, unsigned int iflags);
+void au_cpup_attr_timesizes(struct inode *inode);
+void au_cpup_attr_nlink(struct inode *inode, int force);
+void au_cpup_attr_changeable(struct inode *inode);
+void au_cpup_igen(struct inode *inode, struct inode *h_inode);
+void au_cpup_attr_all(struct inode *inode, int force);
+
+/* ---------------------------------------------------------------------- */
+
+struct au_cp_generic {
+	struct dentry	*dentry;
+	aufs_bindex_t	bdst, bsrc;
+	loff_t		len;
+	struct au_pin	*pin;
+	unsigned int	flags;
+};
+
+/* cpup flags */
+#define AuCpup_DTIME		1		/* do dtime_store/revert */
+#define AuCpup_KEEPLINO		(1 << 1)	/* do not clear the lower xino,
+						   for link(2) */
+#define AuCpup_RENAME		(1 << 2)	/* rename after cpup */
+#define AuCpup_HOPEN		(1 << 3)	/* call h_open_pre/post() in
+						   cpup */
+#define AuCpup_OVERWRITE	(1 << 4)	/* allow overwriting the
+						   existing entry */
+#define AuCpup_RWDST		(1 << 5)	/* force write target even if
+						   the branch is marked as RO */
+
+#define au_ftest_cpup(flags, name)	((flags) & AuCpup_##name)
+#define au_fset_cpup(flags, name) \
+	do { (flags) |= AuCpup_##name; } while (0)
+#define au_fclr_cpup(flags, name) \
+	do { (flags) &= ~AuCpup_##name; } while (0)
+
+int au_copy_file(struct file *dst, struct file *src, loff_t len);
+int au_sio_cpup_simple(struct au_cp_generic *cpg);
+int au_sio_cpdown_simple(struct au_cp_generic *cpg);
+int au_sio_cpup_wh(struct au_cp_generic *cpg, struct file *file);
+
+int au_cp_dirs(struct dentry *dentry, aufs_bindex_t bdst,
+	       int (*cp)(struct dentry *dentry, aufs_bindex_t bdst,
+			 struct au_pin *pin,
+			 struct dentry *h_parent, void *arg),
+	       void *arg);
+int au_cpup_dirs(struct dentry *dentry, aufs_bindex_t bdst);
+int au_test_and_cpup_dirs(struct dentry *dentry, aufs_bindex_t bdst);
+
+/* ---------------------------------------------------------------------- */
+
+/* keep timestamps when copyup */
+struct au_dtime {
+	struct dentry *dt_dentry;
+	struct path dt_h_path;
+	struct timespec dt_atime, dt_mtime;
+};
+void au_dtime_store(struct au_dtime *dt, struct dentry *dentry,
+		    struct path *h_path);
+void au_dtime_revert(struct au_dtime *dt);
+
+#endif /* __KERNEL__ */
+#endif /* __AUFS_CPUP_H__ */
--- /dev/null
+++ zfcpdump-kernel-4.4/fs/aufs/dbgaufs.c
@@ -0,0 +1,432 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+ *
+ * This program, aufs is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * debugfs interface
+ */
+
+#include <linux/debugfs.h>
+#include "aufs.h"
+
+#ifndef CONFIG_SYSFS
+#error DEBUG_FS depends upon SYSFS
+#endif
+
+static struct dentry *dbgaufs;
+static const mode_t dbgaufs_mode = S_IRUSR | S_IRGRP | S_IROTH;
+
+/* 20 is max digits length of ulong 64 */
+struct dbgaufs_arg {
+	int n;
+	char a[20 * 4];
+};
+
+/*
+ * common function for all XINO files
+ */
+static int dbgaufs_xi_release(struct inode *inode __maybe_unused,
+			      struct file *file)
+{
+	kfree(file->private_data);
+	return 0;
+}
+
+static int dbgaufs_xi_open(struct file *xf, struct file *file, int do_fcnt)
+{
+	int err;
+	struct kstat st;
+	struct dbgaufs_arg *p;
+
+	err = -ENOMEM;
+	p = kmalloc(sizeof(*p), GFP_NOFS);
+	if (unlikely(!p))
+		goto out;
+
+	err = 0;
+	p->n = 0;
+	file->private_data = p;
+	if (!xf)
+		goto out;
+
+	err = vfs_getattr(&xf->f_path, &st);
+	if (!err) {
+		if (do_fcnt)
+			p->n = snprintf
+				(p->a, sizeof(p->a), "%ld, %llux%lu %lld\n",
+				 (long)file_count(xf), st.blocks, st.blksize,
+				 (long long)st.size);
+		else
+			p->n = snprintf(p->a, sizeof(p->a), "%llux%lu %lld\n",
+					st.blocks, st.blksize,
+					(long long)st.size);
+		AuDebugOn(p->n >= sizeof(p->a));
+	} else {
+		p->n = snprintf(p->a, sizeof(p->a), "err %d\n", err);
+		err = 0;
+	}
+
+out:
+	return err;
+
+}
+
+static ssize_t dbgaufs_xi_read(struct file *file, char __user *buf,
+			       size_t count, loff_t *ppos)
+{
+	struct dbgaufs_arg *p;
+
+	p = file->private_data;
+	return simple_read_from_buffer(buf, count, ppos, p->a, p->n);
+}
+
+/* ---------------------------------------------------------------------- */
+
+struct dbgaufs_plink_arg {
+	int n;
+	char a[];
+};
+
+static int dbgaufs_plink_release(struct inode *inode __maybe_unused,
+				 struct file *file)
+{
+	free_page((unsigned long)file->private_data);
+	return 0;
+}
+
+static int dbgaufs_plink_open(struct inode *inode, struct file *file)
+{
+	int err, i, limit;
+	unsigned long n, sum;
+	struct dbgaufs_plink_arg *p;
+	struct au_sbinfo *sbinfo;
+	struct super_block *sb;
+	struct au_sphlhead *sphl;
+
+	err = -ENOMEM;
+	p = (void *)get_zeroed_page(GFP_NOFS);
+	if (unlikely(!p))
+		goto out;
+
+	err = -EFBIG;
+	sbinfo = inode->i_private;
+	sb = sbinfo->si_sb;
+	si_noflush_read_lock(sb);
+	if (au_opt_test(au_mntflags(sb), PLINK)) {
+		limit = PAGE_SIZE - sizeof(p->n);
+
+		/* the number of buckets */
+		n = snprintf(p->a + p->n, limit, "%d\n", AuPlink_NHASH);
+		p->n += n;
+		limit -= n;
+
+		sum = 0;
+		for (i = 0, sphl = sbinfo->si_plink;
+		     i < AuPlink_NHASH;
+		     i++, sphl++) {
+			n = au_sphl_count(sphl);
+			sum += n;
+
+			n = snprintf(p->a + p->n, limit, "%lu ", n);
+			p->n += n;
+			limit -= n;
+			if (unlikely(limit <= 0))
+				goto out_free;
+		}
+		p->a[p->n - 1] = '\n';
+
+		/* the sum of plinks */
+		n = snprintf(p->a + p->n, limit, "%lu\n", sum);
+		p->n += n;
+		limit -= n;
+		if (unlikely(limit <= 0))
+			goto out_free;
+	} else {
+#define str "1\n0\n0\n"
+		p->n = sizeof(str) - 1;
+		strcpy(p->a, str);
+#undef str
+	}
+	si_read_unlock(sb);
+
+	err = 0;
+	file->private_data = p;
+	goto out; /* success */
+
+out_free:
+	free_page((unsigned long)p);
+out:
+	return err;
+}
+
+static ssize_t dbgaufs_plink_read(struct file *file, char __user *buf,
+				  size_t count, loff_t *ppos)
+{
+	struct dbgaufs_plink_arg *p;
+
+	p = file->private_data;
+	return simple_read_from_buffer(buf, count, ppos, p->a, p->n);
+}
+
+static const struct file_operations dbgaufs_plink_fop = {
+	.owner		= THIS_MODULE,
+	.open		= dbgaufs_plink_open,
+	.release	= dbgaufs_plink_release,
+	.read		= dbgaufs_plink_read
+};
+
+/* ---------------------------------------------------------------------- */
+
+static int dbgaufs_xib_open(struct inode *inode, struct file *file)
+{
+	int err;
+	struct au_sbinfo *sbinfo;
+	struct super_block *sb;
+
+	sbinfo = inode->i_private;
+	sb = sbinfo->si_sb;
+	si_noflush_read_lock(sb);
+	err = dbgaufs_xi_open(sbinfo->si_xib, file, /*do_fcnt*/0);
+	si_read_unlock(sb);
+	return err;
+}
+
+static const struct file_operations dbgaufs_xib_fop = {
+	.owner		= THIS_MODULE,
+	.open		= dbgaufs_xib_open,
+	.release	= dbgaufs_xi_release,
+	.read		= dbgaufs_xi_read
+};
+
+/* ---------------------------------------------------------------------- */
+
+#define DbgaufsXi_PREFIX "xi"
+
+static int dbgaufs_xino_open(struct inode *inode, struct file *file)
+{
+	int err;
+	long l;
+	struct au_sbinfo *sbinfo;
+	struct super_block *sb;
+	struct file *xf;
+	struct qstr *name;
+
+	err = -ENOENT;
+	xf = NULL;
+	name = &file->f_path.dentry->d_name;
+	if (unlikely(name->len < sizeof(DbgaufsXi_PREFIX)
+		     || memcmp(name->name, DbgaufsXi_PREFIX,
+			       sizeof(DbgaufsXi_PREFIX) - 1)))
+		goto out;
+	err = kstrtol(name->name + sizeof(DbgaufsXi_PREFIX) - 1, 10, &l);
+	if (unlikely(err))
+		goto out;
+
+	sbinfo = inode->i_private;
+	sb = sbinfo->si_sb;
+	si_noflush_read_lock(sb);
+	if (l <= au_sbend(sb)) {
+		xf = au_sbr(sb, (aufs_bindex_t)l)->br_xino.xi_file;
+		err = dbgaufs_xi_open(xf, file, /*do_fcnt*/1);
+	} else
+		err = -ENOENT;
+	si_read_unlock(sb);
+
+out:
+	return err;
+}
+
+static const struct file_operations dbgaufs_xino_fop = {
+	.owner		= THIS_MODULE,
+	.open		= dbgaufs_xino_open,
+	.release	= dbgaufs_xi_release,
+	.read		= dbgaufs_xi_read
+};
+
+void dbgaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex)
+{
+	aufs_bindex_t bend;
+	struct au_branch *br;
+	struct au_xino_file *xi;
+
+	if (!au_sbi(sb)->si_dbgaufs)
+		return;
+
+	bend = au_sbend(sb);
+	for (; bindex <= bend; bindex++) {
+		br = au_sbr(sb, bindex);
+		xi = &br->br_xino;
+		debugfs_remove(xi->xi_dbgaufs);
+		xi->xi_dbgaufs = NULL;
+	}
+}
+
+void dbgaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex)
+{
+	struct au_sbinfo *sbinfo;
+	struct dentry *parent;
+	struct au_branch *br;
+	struct au_xino_file *xi;
+	aufs_bindex_t bend;
+	char name[sizeof(DbgaufsXi_PREFIX) + 5]; /* "xi" bindex NULL */
+
+	sbinfo = au_sbi(sb);
+	parent = sbinfo->si_dbgaufs;
+	if (!parent)
+		return;
+
+	bend = au_sbend(sb);
+	for (; bindex <= bend; bindex++) {
+		snprintf(name, sizeof(name), DbgaufsXi_PREFIX "%d", bindex);
+		br = au_sbr(sb, bindex);
+		xi = &br->br_xino;
+		AuDebugOn(xi->xi_dbgaufs);
+		xi->xi_dbgaufs = debugfs_create_file(name, dbgaufs_mode, parent,
+						     sbinfo, &dbgaufs_xino_fop);
+		/* ignore an error */
+		if (unlikely(!xi->xi_dbgaufs))
+			AuWarn1("failed %s under debugfs\n", name);
+	}
+}
+
+/* ---------------------------------------------------------------------- */
+
+#ifdef CONFIG_AUFS_EXPORT
+static int dbgaufs_xigen_open(struct inode *inode, struct file *file)
+{
+	int err;
+	struct au_sbinfo *sbinfo;
+	struct super_block *sb;
+
+	sbinfo = inode->i_private;
+	sb = sbinfo->si_sb;
+	si_noflush_read_lock(sb);
+	err = dbgaufs_xi_open(sbinfo->si_xigen, file, /*do_fcnt*/0);
+	si_read_unlock(sb);
+	return err;
+}
+
+static const struct file_operations dbgaufs_xigen_fop = {
+	.owner		= THIS_MODULE,
+	.open		= dbgaufs_xigen_open,
+	.release	= dbgaufs_xi_release,
+	.read		= dbgaufs_xi_read
+};
+
+static int dbgaufs_xigen_init(struct au_sbinfo *sbinfo)
+{
+	int err;
+
+	/*
+	 * This function is a dynamic '__init' function actually,
+	 * so the tiny check for si_rwsem is unnecessary.
+	 */
+	/* AuRwMustWriteLock(&sbinfo->si_rwsem); */
+
+	err = -EIO;
+	sbinfo->si_dbgaufs_xigen = debugfs_create_file
+		("xigen", dbgaufs_mode, sbinfo->si_dbgaufs, sbinfo,
+		 &dbgaufs_xigen_fop);
+	if (sbinfo->si_dbgaufs_xigen)
+		err = 0;
+
+	return err;
+}
+#else
+static int dbgaufs_xigen_init(struct au_sbinfo *sbinfo)
+{
+	return 0;
+}
+#endif /* CONFIG_AUFS_EXPORT */
+
+/* ---------------------------------------------------------------------- */
+
+void dbgaufs_si_fin(struct au_sbinfo *sbinfo)
+{
+	/*
+	 * This function is a dynamic '__fin' function actually,
+	 * so the tiny check for si_rwsem is unnecessary.
+	 */
+	/* AuRwMustWriteLock(&sbinfo->si_rwsem); */
+
+	debugfs_remove_recursive(sbinfo->si_dbgaufs);
+	sbinfo->si_dbgaufs = NULL;
+	kobject_put(&sbinfo->si_kobj);
+}
+
+int dbgaufs_si_init(struct au_sbinfo *sbinfo)
+{
+	int err;
+	char name[SysaufsSiNameLen];
+
+	/*
+	 * This function is a dynamic '__init' function actually,
+	 * so the tiny check for si_rwsem is unnecessary.
+	 */
+	/* AuRwMustWriteLock(&sbinfo->si_rwsem); */
+
+	err = -ENOENT;
+	if (!dbgaufs) {
+		AuErr1("/debug/aufs is uninitialized\n");
+		goto out;
+	}
+
+	err = -EIO;
+	sysaufs_name(sbinfo, name);
+	sbinfo->si_dbgaufs = debugfs_create_dir(name, dbgaufs);
+	if (unlikely(!sbinfo->si_dbgaufs))
+		goto out;
+	kobject_get(&sbinfo->si_kobj);
+
+	sbinfo->si_dbgaufs_xib = debugfs_create_file
+		("xib", dbgaufs_mode, sbinfo->si_dbgaufs, sbinfo,
+		 &dbgaufs_xib_fop);
+	if (unlikely(!sbinfo->si_dbgaufs_xib))
+		goto out_dir;
+
+	sbinfo->si_dbgaufs_plink = debugfs_create_file
+		("plink", dbgaufs_mode, sbinfo->si_dbgaufs, sbinfo,
+		 &dbgaufs_plink_fop);
+	if (unlikely(!sbinfo->si_dbgaufs_plink))
+		goto out_dir;
+
+	err = dbgaufs_xigen_init(sbinfo);
+	if (!err)
+		goto out; /* success */
+
+out_dir:
+	dbgaufs_si_fin(sbinfo);
+out:
+	return err;
+}
+
+/* ---------------------------------------------------------------------- */
+
+void dbgaufs_fin(void)
+{
+	debugfs_remove(dbgaufs);
+}
+
+int __init dbgaufs_init(void)
+{
+	int err;
+
+	err = -EIO;
+	dbgaufs = debugfs_create_dir(AUFS_NAME, NULL);
+	if (dbgaufs)
+		err = 0;
+	return err;
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/fs/aufs/dbgaufs.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+ *
+ * This program, aufs is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * debugfs interface
+ */
+
+#ifndef __DBGAUFS_H__
+#define __DBGAUFS_H__
+
+#ifdef __KERNEL__
+
+struct super_block;
+struct au_sbinfo;
+
+#ifdef CONFIG_DEBUG_FS
+/* dbgaufs.c */
+void dbgaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex);
+void dbgaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex);
+void dbgaufs_si_fin(struct au_sbinfo *sbinfo);
+int dbgaufs_si_init(struct au_sbinfo *sbinfo);
+void dbgaufs_fin(void);
+int __init dbgaufs_init(void);
+#else
+AuStubVoid(dbgaufs_brs_del, struct super_block *sb, aufs_bindex_t bindex)
+AuStubVoid(dbgaufs_brs_add, struct super_block *sb, aufs_bindex_t bindex)
+AuStubVoid(dbgaufs_si_fin, struct au_sbinfo *sbinfo)
+AuStubInt0(dbgaufs_si_init, struct au_sbinfo *sbinfo)
+AuStubVoid(dbgaufs_fin, void)
+AuStubInt0(__init dbgaufs_init, void)
+#endif /* CONFIG_DEBUG_FS */
+
+#endif /* __KERNEL__ */
+#endif /* __DBGAUFS_H__ */
--- /dev/null
+++ zfcpdump-kernel-4.4/fs/aufs/dcsub.c
@@ -0,0 +1,224 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+ *
+ * This program, aufs is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * sub-routines for dentry cache
+ */
+
+#include "aufs.h"
+
+static void au_dpage_free(struct au_dpage *dpage)
+{
+	int i;
+	struct dentry **p;
+
+	p = dpage->dentries;
+	for (i = 0; i < dpage->ndentry; i++)
+		dput(*p++);
+	free_page((unsigned long)dpage->dentries);
+}
+
+int au_dpages_init(struct au_dcsub_pages *dpages, gfp_t gfp)
+{
+	int err;
+	void *p;
+
+	err = -ENOMEM;
+	dpages->dpages = kmalloc(sizeof(*dpages->dpages), gfp);
+	if (unlikely(!dpages->dpages))
+		goto out;
+
+	p = (void *)__get_free_page(gfp);
+	if (unlikely(!p))
+		goto out_dpages;
+
+	dpages->dpages[0].ndentry = 0;
+	dpages->dpages[0].dentries = p;
+	dpages->ndpage = 1;
+	return 0; /* success */
+
+out_dpages:
+	kfree(dpages->dpages);
+out:
+	return err;
+}
+
+void au_dpages_free(struct au_dcsub_pages *dpages)
+{
+	int i;
+	struct au_dpage *p;
+
+	p = dpages->dpages;
+	for (i = 0; i < dpages->ndpage; i++)
+		au_dpage_free(p++);
+	kfree(dpages->dpages);
+}
+
+static int au_dpages_append(struct au_dcsub_pages *dpages,
+			    struct dentry *dentry, gfp_t gfp)
+{
+	int err, sz;
+	struct au_dpage *dpage;
+	void *p;
+
+	dpage = dpages->dpages + dpages->ndpage - 1;
+	sz = PAGE_SIZE / sizeof(dentry);
+	if (unlikely(dpage->ndentry >= sz)) {
+		AuLabel(new dpage);
+		err = -ENOMEM;
+		sz = dpages->ndpage * sizeof(*dpages->dpages);
+		p = au_kzrealloc(dpages->dpages, sz,
+				 sz + sizeof(*dpages->dpages), gfp);
+		if (unlikely(!p))
+			goto out;
+
+		dpages->dpages = p;
+		dpage = dpages->dpages + dpages->ndpage;
+		p = (void *)__get_free_page(gfp);
+		if (unlikely(!p))
+			goto out;
+
+		dpage->ndentry = 0;
+		dpage->dentries = p;
+		dpages->ndpage++;
+	}
+
+	AuDebugOn(au_dcount(dentry) <= 0);
+	dpage->dentries[dpage->ndentry++] = dget_dlock(dentry);
+	return 0; /* success */
+
+out:
+	return err;
+}
+
+/* todo: BAD approach */
+/* copied from linux/fs/dcache.c */
+enum d_walk_ret {
+	D_WALK_CONTINUE,
+	D_WALK_QUIT,
+	D_WALK_NORETRY,
+	D_WALK_SKIP,
+};
+
+extern void d_walk(struct dentry *parent, void *data,
+		   enum d_walk_ret (*enter)(void *, struct dentry *),
+		   void (*finish)(void *));
+
+struct ac_dpages_arg {
+	int err;
+	struct au_dcsub_pages *dpages;
+	struct super_block *sb;
+	au_dpages_test test;
+	void *arg;
+};
+
+static enum d_walk_ret au_call_dpages_append(void *_arg, struct dentry *dentry)
+{
+	enum d_walk_ret ret;
+	struct ac_dpages_arg *arg = _arg;
+
+	ret = D_WALK_CONTINUE;
+	if (dentry->d_sb == arg->sb
+	    && !IS_ROOT(dentry)
+	    && au_dcount(dentry) > 0
+	    && au_di(dentry)
+	    && (!arg->test || arg->test(dentry, arg->arg))) {
+		arg->err = au_dpages_append(arg->dpages, dentry, GFP_ATOMIC);
+		if (unlikely(arg->err))
+			ret = D_WALK_QUIT;
+	}
+
+	return ret;
+}
+
+int au_dcsub_pages(struct au_dcsub_pages *dpages, struct dentry *root,
+		   au_dpages_test test, void *arg)
+{
+	struct ac_dpages_arg args = {
+		.err	= 0,
+		.dpages	= dpages,
+		.sb	= root->d_sb,
+		.test	= test,
+		.arg	= arg
+	};
+
+	d_walk(root, &args, au_call_dpages_append, NULL);
+
+	return args.err;
+}
+
+int au_dcsub_pages_rev(struct au_dcsub_pages *dpages, struct dentry *dentry,
+		       int do_include, au_dpages_test test, void *arg)
+{
+	int err;
+
+	err = 0;
+	write_seqlock(&rename_lock);
+	spin_lock(&dentry->d_lock);
+	if (do_include
+	    && au_dcount(dentry) > 0
+	    && (!test || test(dentry, arg)))
+		err = au_dpages_append(dpages, dentry, GFP_ATOMIC);
+	spin_unlock(&dentry->d_lock);
+	if (unlikely(err))
+		goto out;
+
+	/*
+	 * RCU for vfsmount is unnecessary since this is a traverse in a single
+	 * mount
+	 */
+	while (!IS_ROOT(dentry)) {
+		dentry = dentry->d_parent; /* rename_lock is locked */
+		spin_lock(&dentry->d_lock);
+		if (au_dcount(dentry) > 0
+		    && (!test || test(dentry, arg)))
+			err = au_dpages_append(dpages, dentry, GFP_ATOMIC);
+		spin_unlock(&dentry->d_lock);
+		if (unlikely(err))
+			break;
+	}
+
+out:
+	write_sequnlock(&rename_lock);
+	return err;
+}
+
+static inline int au_dcsub_dpages_aufs(struct dentry *dentry, void *arg)
+{
+	return au_di(dentry) && dentry->d_sb == arg;
+}
+
+int au_dcsub_pages_rev_aufs(struct au_dcsub_pages *dpages,
+			    struct dentry *dentry, int do_include)
+{
+	return au_dcsub_pages_rev(dpages, dentry, do_include,
+				  au_dcsub_dpages_aufs, dentry->d_sb);
+}
+
+int au_test_subdir(struct dentry *d1, struct dentry *d2)
+{
+	struct path path[2] = {
+		{
+			.dentry = d1
+		},
+		{
+			.dentry = d2
+		}
+	};
+
+	return path_is_under(path + 0, path + 1);
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/fs/aufs/dcsub.h
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+ *
+ * This program, aufs is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * sub-routines for dentry cache
+ */
+
+#ifndef __AUFS_DCSUB_H__
+#define __AUFS_DCSUB_H__
+
+#ifdef __KERNEL__
+
+#include <linux/dcache.h>
+#include <linux/fs.h>
+
+struct au_dpage {
+	int ndentry;
+	struct dentry **dentries;
+};
+
+struct au_dcsub_pages {
+	int ndpage;
+	struct au_dpage *dpages;
+};
+
+/* ---------------------------------------------------------------------- */
+
+/* dcsub.c */
+int au_dpages_init(struct au_dcsub_pages *dpages, gfp_t gfp);
+void au_dpages_free(struct au_dcsub_pages *dpages);
+typedef int (*au_dpages_test)(struct dentry *dentry, void *arg);
+int au_dcsub_pages(struct au_dcsub_pages *dpages, struct dentry *root,
+		   au_dpages_test test, void *arg);
+int au_dcsub_pages_rev(struct au_dcsub_pages *dpages, struct dentry *dentry,
+		       int do_include, au_dpages_test test, void *arg);
+int au_dcsub_pages_rev_aufs(struct au_dcsub_pages *dpages,
+			    struct dentry *dentry, int do_include);
+int au_test_subdir(struct dentry *d1, struct dentry *d2);
+
+/* ---------------------------------------------------------------------- */
+
+/*
+ * todo: in linux-3.13, several similar (but faster) helpers are added to
+ * include/linux/dcache.h. Try them (in the future).
+ */
+
+static inline int au_d_hashed_positive(struct dentry *d)
+{
+	int err;
+	struct inode *inode = d_inode(d);
+
+	err = 0;
+	if (unlikely(d_unhashed(d)
+		     || d_is_negative(d)
+		     || !inode->i_nlink))
+		err = -ENOENT;
+	return err;
+}
+
+static inline int au_d_linkable(struct dentry *d)
+{
+	int err;
+	struct inode *inode = d_inode(d);
+
+	err = au_d_hashed_positive(d);
+	if (err
+	    && d_is_positive(d)
+	    && (inode->i_state & I_LINKABLE))
+		err = 0;
+	return err;
+}
+
+static inline int au_d_alive(struct dentry *d)
+{
+	int err;
+	struct inode *inode;
+
+	err = 0;
+	if (!IS_ROOT(d))
+		err = au_d_hashed_positive(d);
+	else {
+		inode = d_inode(d);
+		if (unlikely(d_unlinked(d)
+			     || d_is_negative(d)
+			     || !inode->i_nlink))
+			err = -ENOENT;
+	}
+	return err;
+}
+
+static inline int au_alive_dir(struct dentry *d)
+{
+	int err;
+
+	err = au_d_alive(d);
+	if (unlikely(err || IS_DEADDIR(d_inode(d))))
+		err = -ENOENT;
+	return err;
+}
+
+static inline int au_qstreq(struct qstr *a, struct qstr *b)
+{
+	return a->len == b->len
+		&& !memcmp(a->name, b->name, a->len);
+}
+
+/*
+ * by the commit
+ * 360f547 2015-01-25 dcache: let the dentry count go down to zero without
+ *			taking d_lock
+ * the type of d_lockref.count became int, but the inlined function d_count()
+ * still returns unsigned int.
+ * I don't know why. Maybe it is for every d_count() users?
+ * Anyway au_dcount() lives on.
+ */
+static inline int au_dcount(struct dentry *d)
+{
+	return (int)d_count(d);
+}
+
+#endif /* __KERNEL__ */
+#endif /* __AUFS_DCSUB_H__ */
--- /dev/null
+++ zfcpdump-kernel-4.4/fs/aufs/debug.c
@@ -0,0 +1,438 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+ *
+ * This program, aufs is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * debug print functions
+ */
+
+#include "aufs.h"
+
+/* Returns 0, or -errno.  arg is in kp->arg. */
+static int param_atomic_t_set(const char *val, const struct kernel_param *kp)
+{
+	int err, n;
+
+	err = kstrtoint(val, 0, &n);
+	if (!err) {
+		if (n > 0)
+			au_debug_on();
+		else
+			au_debug_off();
+	}
+	return err;
+}
+
+/* Returns length written or -errno.  Buffer is 4k (ie. be short!) */
+static int param_atomic_t_get(char *buffer, const struct kernel_param *kp)
+{
+	atomic_t *a;
+
+	a = kp->arg;
+	return sprintf(buffer, "%d", atomic_read(a));
+}
+
+static struct kernel_param_ops param_ops_atomic_t = {
+	.set = param_atomic_t_set,
+	.get = param_atomic_t_get
+	/* void (*free)(void *arg) */
+};
+
+atomic_t aufs_debug = ATOMIC_INIT(0);
+MODULE_PARM_DESC(debug, "debug print");
+module_param_named(debug, aufs_debug, atomic_t, S_IRUGO | S_IWUSR | S_IWGRP);
+
+DEFINE_MUTEX(au_dbg_mtx);	/* just to serialize the dbg msgs */
+char *au_plevel = KERN_DEBUG;
+#define dpri(fmt, ...) do {					\
+	if ((au_plevel						\
+	     && strcmp(au_plevel, KERN_DEBUG))			\
+	    || au_debug_test())					\
+		printk("%s" fmt, au_plevel, ##__VA_ARGS__);	\
+} while (0)
+
+/* ---------------------------------------------------------------------- */
+
+void au_dpri_whlist(struct au_nhash *whlist)
+{
+	unsigned long ul, n;
+	struct hlist_head *head;
+	struct au_vdir_wh *pos;
+
+	n = whlist->nh_num;
+	head = whlist->nh_head;
+	for (ul = 0; ul < n; ul++) {
+		hlist_for_each_entry(pos, head, wh_hash)
+			dpri("b%d, %.*s, %d\n",
+			     pos->wh_bindex,
+			     pos->wh_str.len, pos->wh_str.name,
+			     pos->wh_str.len);
+		head++;
+	}
+}
+
+void au_dpri_vdir(struct au_vdir *vdir)
+{
+	unsigned long ul;
+	union au_vdir_deblk_p p;
+	unsigned char *o;
+
+	if (!vdir || IS_ERR(vdir)) {
+		dpri("err %ld\n", PTR_ERR(vdir));
+		return;
+	}
+
+	dpri("deblk %u, nblk %lu, deblk %p, last{%lu, %p}, ver %lu\n",
+	     vdir->vd_deblk_sz, vdir->vd_nblk, vdir->vd_deblk,
+	     vdir->vd_last.ul, vdir->vd_last.p.deblk, vdir->vd_version);
+	for (ul = 0; ul < vdir->vd_nblk; ul++) {
+		p.deblk = vdir->vd_deblk[ul];
+		o = p.deblk;
+		dpri("[%lu]: %p\n", ul, o);
+	}
+}
+
+static int do_pri_inode(aufs_bindex_t bindex, struct inode *inode, int hn,
+			struct dentry *wh)
+{
+	char *n = NULL;
+	int l = 0;
+
+	if (!inode || IS_ERR(inode)) {
+		dpri("i%d: err %ld\n", bindex, PTR_ERR(inode));
+		return -1;
+	}
+
+	/* the type of i_blocks depends upon CONFIG_LBDAF */
+	BUILD_BUG_ON(sizeof(inode->i_blocks) != sizeof(unsigned long)
+		     && sizeof(inode->i_blocks) != sizeof(u64));
+	if (wh) {
+		n = (void *)wh->d_name.name;
+		l = wh->d_name.len;
+	}
+
+	dpri("i%d: %p, i%lu, %s, cnt %d, nl %u, 0%o, sz %llu, blk %llu,"
+	     " hn %d, ct %lld, np %lu, st 0x%lx, f 0x%x, v %llu, g %x%s%.*s\n",
+	     bindex, inode,
+	     inode->i_ino, inode->i_sb ? au_sbtype(inode->i_sb) : "??",
+	     atomic_read(&inode->i_count), inode->i_nlink, inode->i_mode,
+	     i_size_read(inode), (unsigned long long)inode->i_blocks,
+	     hn, (long long)timespec_to_ns(&inode->i_ctime) & 0x0ffff,
+	     inode->i_mapping ? inode->i_mapping->nrpages : 0,
+	     inode->i_state, inode->i_flags, inode->i_version,
+	     inode->i_generation,
+	     l ? ", wh " : "", l, n);
+	return 0;
+}
+
+void au_dpri_inode(struct inode *inode)
+{
+	struct au_iinfo *iinfo;
+	aufs_bindex_t bindex;
+	int err, hn;
+
+	err = do_pri_inode(-1, inode, -1, NULL);
+	if (err || !au_test_aufs(inode->i_sb))
+		return;
+
+	iinfo = au_ii(inode);
+	if (!iinfo)
+		return;
+	dpri("i-1: bstart %d, bend %d, gen %d\n",
+	     iinfo->ii_bstart, iinfo->ii_bend, au_iigen(inode, NULL));
+	if (iinfo->ii_bstart < 0)
+		return;
+	hn = 0;
+	for (bindex = iinfo->ii_bstart; bindex <= iinfo->ii_bend; bindex++) {
+		hn = !!au_hn(iinfo->ii_hinode + bindex);
+		do_pri_inode(bindex, iinfo->ii_hinode[0 + bindex].hi_inode, hn,
+			     iinfo->ii_hinode[0 + bindex].hi_whdentry);
+	}
+}
+
+void au_dpri_dalias(struct inode *inode)
+{
+	struct dentry *d;
+
+	spin_lock(&inode->i_lock);
+	hlist_for_each_entry(d, &inode->i_dentry, d_u.d_alias)
+		au_dpri_dentry(d);
+	spin_unlock(&inode->i_lock);
+}
+
+static int do_pri_dentry(aufs_bindex_t bindex, struct dentry *dentry)
+{
+	struct dentry *wh = NULL;
+	int hn;
+	struct au_iinfo *iinfo;
+
+	if (!dentry || IS_ERR(dentry)) {
+		dpri("d%d: err %ld\n", bindex, PTR_ERR(dentry));
+		return -1;
+	}
+	/* do not call dget_parent() here */
+	/* note: access d_xxx without d_lock */
+	dpri("d%d: %p, %pd2?, %s, cnt %d, flags 0x%x, %shashed\n",
+	     bindex, dentry, dentry,
+	     dentry->d_sb ? au_sbtype(dentry->d_sb) : "??",
+	     au_dcount(dentry), dentry->d_flags,
+	     d_unhashed(dentry) ? "un" : "");
+	hn = -1;
+	if (bindex >= 0
+	    && d_is_positive(dentry)
+	    && au_test_aufs(dentry->d_sb)) {
+		iinfo = au_ii(d_inode(dentry));
+		if (iinfo) {
+			hn = !!au_hn(iinfo->ii_hinode + bindex);
+			wh = iinfo->ii_hinode[0 + bindex].hi_whdentry;
+		}
+	}
+	do_pri_inode(bindex, d_inode(dentry), hn, wh);
+	return 0;
+}
+
+void au_dpri_dentry(struct dentry *dentry)
+{
+	struct au_dinfo *dinfo;
+	aufs_bindex_t bindex;
+	int err;
+	struct au_hdentry *hdp;
+
+	err = do_pri_dentry(-1, dentry);
+	if (err || !au_test_aufs(dentry->d_sb))
+		return;
+
+	dinfo = au_di(dentry);
+	if (!dinfo)
+		return;
+	dpri("d-1: bstart %d, bend %d, bwh %d, bdiropq %d, gen %d, tmp %d\n",
+	     dinfo->di_bstart, dinfo->di_bend,
+	     dinfo->di_bwh, dinfo->di_bdiropq, au_digen(dentry),
+	     dinfo->di_tmpfile);
+	if (dinfo->di_bstart < 0)
+		return;
+	hdp = dinfo->di_hdentry;
+	for (bindex = dinfo->di_bstart; bindex <= dinfo->di_bend; bindex++)
+		do_pri_dentry(bindex, hdp[0 + bindex].hd_dentry);
+}
+
+static int do_pri_file(aufs_bindex_t bindex, struct file *file)
+{
+	char a[32];
+
+	if (!file || IS_ERR(file)) {
+		dpri("f%d: err %ld\n", bindex, PTR_ERR(file));
+		return -1;
+	}
+	a[0] = 0;
+	if (bindex < 0
+	    && !IS_ERR_OR_NULL(file->f_path.dentry)
+	    && au_test_aufs(file->f_path.dentry->d_sb)
+	    && au_fi(file))
+		snprintf(a, sizeof(a), ", gen %d, mmapped %d",
+			 au_figen(file), atomic_read(&au_fi(file)->fi_mmapped));
+	dpri("f%d: mode 0x%x, flags 0%o, cnt %ld, v %llu, pos %llu%s\n",
+	     bindex, file->f_mode, file->f_flags, (long)file_count(file),
+	     file->f_version, file->f_pos, a);
+	if (!IS_ERR_OR_NULL(file->f_path.dentry))
+		do_pri_dentry(bindex, file->f_path.dentry);
+	return 0;
+}
+
+void au_dpri_file(struct file *file)
+{
+	struct au_finfo *finfo;
+	struct au_fidir *fidir;
+	struct au_hfile *hfile;
+	aufs_bindex_t bindex;
+	int err;
+
+	err = do_pri_file(-1, file);
+	if (err
+	    || IS_ERR_OR_NULL(file->f_path.dentry)
+	    || !au_test_aufs(file->f_path.dentry->d_sb))
+		return;
+
+	finfo = au_fi(file);
+	if (!finfo)
+		return;
+	if (finfo->fi_btop < 0)
+		return;
+	fidir = finfo->fi_hdir;
+	if (!fidir)
+		do_pri_file(finfo->fi_btop, finfo->fi_htop.hf_file);
+	else
+		for (bindex = finfo->fi_btop;
+		     bindex >= 0 && bindex <= fidir->fd_bbot;
+		     bindex++) {
+			hfile = fidir->fd_hfile + bindex;
+			do_pri_file(bindex, hfile ? hfile->hf_file : NULL);
+		}
+}
+
+static int do_pri_br(aufs_bindex_t bindex, struct au_branch *br)
+{
+	struct vfsmount *mnt;
+	struct super_block *sb;
+
+	if (!br || IS_ERR(br))
+		goto out;
+	mnt = au_br_mnt(br);
+	if (!mnt || IS_ERR(mnt))
+		goto out;
+	sb = mnt->mnt_sb;
+	if (!sb || IS_ERR(sb))
+		goto out;
+
+	dpri("s%d: {perm 0x%x, id %d, cnt %d, wbr %p}, "
+	     "%s, dev 0x%02x%02x, flags 0x%lx, cnt %d, active %d, "
+	     "xino %d\n",
+	     bindex, br->br_perm, br->br_id, atomic_read(&br->br_count),
+	     br->br_wbr, au_sbtype(sb), MAJOR(sb->s_dev), MINOR(sb->s_dev),
+	     sb->s_flags, sb->s_count,
+	     atomic_read(&sb->s_active), !!br->br_xino.xi_file);
+	return 0;
+
+out:
+	dpri("s%d: err %ld\n", bindex, PTR_ERR(br));
+	return -1;
+}
+
+void au_dpri_sb(struct super_block *sb)
+{
+	struct au_sbinfo *sbinfo;
+	aufs_bindex_t bindex;
+	int err;
+	/* to reuduce stack size */
+	struct {
+		struct vfsmount mnt;
+		struct au_branch fake;
+	} *a;
+
+	/* this function can be called from magic sysrq */
+	a = kzalloc(sizeof(*a), GFP_ATOMIC);
+	if (unlikely(!a)) {
+		dpri("no memory\n");
+		return;
+	}
+
+	a->mnt.mnt_sb = sb;
+	a->fake.br_path.mnt = &a->mnt;
+	atomic_set(&a->fake.br_count, 0);
+	smp_mb(); /* atomic_set */
+	err = do_pri_br(-1, &a->fake);
+	kfree(a);
+	dpri("dev 0x%x\n", sb->s_dev);
+	if (err || !au_test_aufs(sb))
+		return;
+
+	sbinfo = au_sbi(sb);
+	if (!sbinfo)
+		return;
+	dpri("nw %d, gen %u, kobj %d\n",
+	     atomic_read(&sbinfo->si_nowait.nw_len), sbinfo->si_generation,
+	     atomic_read(&sbinfo->si_kobj.kref.refcount));
+	for (bindex = 0; bindex <= sbinfo->si_bend; bindex++)
+		do_pri_br(bindex, sbinfo->si_branch[0 + bindex]);
+}
+
+/* ---------------------------------------------------------------------- */
+
+void __au_dbg_verify_dinode(struct dentry *dentry, const char *func, int line)
+{
+	struct inode *h_inode, *inode = d_inode(dentry);
+	struct dentry *h_dentry;
+	aufs_bindex_t bindex, bend, bi;
+
+	if (!inode /* || au_di(dentry)->di_lsc == AuLsc_DI_TMP */)
+		return;
+
+	bend = au_dbend(dentry);
+	bi = au_ibend(inode);
+	if (bi < bend)
+		bend = bi;
+	bindex = au_dbstart(dentry);
+	bi = au_ibstart(inode);
+	if (bi > bindex)
+		bindex = bi;
+
+	for (; bindex <= bend; bindex++) {
+		h_dentry = au_h_dptr(dentry, bindex);
+		if (!h_dentry)
+			continue;
+		h_inode = au_h_iptr(inode, bindex);
+		if (unlikely(h_inode != d_inode(h_dentry))) {
+			au_debug_on();
+			AuDbg("b%d, %s:%d\n", bindex, func, line);
+			AuDbgDentry(dentry);
+			AuDbgInode(inode);
+			au_debug_off();
+			BUG();
+		}
+	}
+}
+
+void au_dbg_verify_gen(struct dentry *parent, unsigned int sigen)
+{
+	int err, i, j;
+	struct au_dcsub_pages dpages;
+	struct au_dpage *dpage;
+	struct dentry **dentries;
+
+	err = au_dpages_init(&dpages, GFP_NOFS);
+	AuDebugOn(err);
+	err = au_dcsub_pages_rev_aufs(&dpages, parent, /*do_include*/1);
+	AuDebugOn(err);
+	for (i = dpages.ndpage - 1; !err && i >= 0; i--) {
+		dpage = dpages.dpages + i;
+		dentries = dpage->dentries;
+		for (j = dpage->ndentry - 1; !err && j >= 0; j--)
+			AuDebugOn(au_digen_test(dentries[j], sigen));
+	}
+	au_dpages_free(&dpages);
+}
+
+void au_dbg_verify_kthread(void)
+{
+	if (au_wkq_test()) {
+		au_dbg_blocked();
+		/*
+		 * It may be recursive, but udba=notify between two aufs mounts,
+		 * where a single ro branch is shared, is not a problem.
+		 */
+		/* WARN_ON(1); */
+	}
+}
+
+/* ---------------------------------------------------------------------- */
+
+int __init au_debug_init(void)
+{
+	aufs_bindex_t bindex;
+	struct au_vdir_destr destr;
+
+	bindex = -1;
+	AuDebugOn(bindex >= 0);
+
+	destr.len = -1;
+	AuDebugOn(destr.len < NAME_MAX);
+
+#ifdef CONFIG_4KSTACKS
+	pr_warn("CONFIG_4KSTACKS is defined.\n");
+#endif
+
+	return 0;
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/fs/aufs/debug.h
@@ -0,0 +1,225 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+ *
+ * This program, aufs is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * debug print functions
+ */
+
+#ifndef __AUFS_DEBUG_H__
+#define __AUFS_DEBUG_H__
+
+#ifdef __KERNEL__
+
+#include <linux/atomic.h>
+#include <linux/module.h>
+#include <linux/kallsyms.h>
+#include <linux/sysrq.h>
+
+#ifdef CONFIG_AUFS_DEBUG
+#define AuDebugOn(a)		BUG_ON(a)
+
+/* module parameter */
+extern atomic_t aufs_debug;
+static inline void au_debug_on(void)
+{
+	atomic_inc(&aufs_debug);
+}
+static inline void au_debug_off(void)
+{
+	atomic_dec_if_positive(&aufs_debug);
+}
+
+static inline int au_debug_test(void)
+{
+	return atomic_read(&aufs_debug) > 0;
+}
+#else
+#define AuDebugOn(a)		do {} while (0)
+AuStubVoid(au_debug_on, void)
+AuStubVoid(au_debug_off, void)
+AuStubInt0(au_debug_test, void)
+#endif /* CONFIG_AUFS_DEBUG */
+
+#define param_check_atomic_t(name, p) __param_check(name, p, atomic_t)
+
+/* ---------------------------------------------------------------------- */
+
+/* debug print */
+
+#define AuDbg(fmt, ...) do { \
+	if (au_debug_test()) \
+		pr_debug("DEBUG: " fmt, ##__VA_ARGS__); \
+} while (0)
+#define AuLabel(l)		AuDbg(#l "\n")
+#define AuIOErr(fmt, ...)	pr_err("I/O Error, " fmt, ##__VA_ARGS__)
+#define AuWarn1(fmt, ...) do { \
+	static unsigned char _c; \
+	if (!_c++) \
+		pr_warn(fmt, ##__VA_ARGS__); \
+} while (0)
+
+#define AuErr1(fmt, ...) do { \
+	static unsigned char _c; \
+	if (!_c++) \
+		pr_err(fmt, ##__VA_ARGS__); \
+} while (0)
+
+#define AuIOErr1(fmt, ...) do { \
+	static unsigned char _c; \
+	if (!_c++) \
+		AuIOErr(fmt, ##__VA_ARGS__); \
+} while (0)
+
+#define AuUnsupportMsg	"This operation is not supported." \
+			" Please report this application to aufs-users ML."
+#define AuUnsupport(fmt, ...) do { \
+	pr_err(AuUnsupportMsg "\n" fmt, ##__VA_ARGS__); \
+	dump_stack(); \
+} while (0)
+
+#define AuTraceErr(e) do { \
+	if (unlikely((e) < 0)) \
+		AuDbg("err %d\n", (int)(e)); \
+} while (0)
+
+#define AuTraceErrPtr(p) do { \
+	if (IS_ERR(p)) \
+		AuDbg("err %ld\n", PTR_ERR(p)); \
+} while (0)
+
+/* dirty macros for debug print, use with "%.*s" and caution */
+#define AuLNPair(qstr)		(qstr)->len, (qstr)->name
+
+/* ---------------------------------------------------------------------- */
+
+struct dentry;
+#ifdef CONFIG_AUFS_DEBUG
+extern struct mutex au_dbg_mtx;
+extern char *au_plevel;
+struct au_nhash;
+void au_dpri_whlist(struct au_nhash *whlist);
+struct au_vdir;
+void au_dpri_vdir(struct au_vdir *vdir);
+struct inode;
+void au_dpri_inode(struct inode *inode);
+void au_dpri_dalias(struct inode *inode);
+void au_dpri_dentry(struct dentry *dentry);
+struct file;
+void au_dpri_file(struct file *filp);
+struct super_block;
+void au_dpri_sb(struct super_block *sb);
+
+#define au_dbg_verify_dinode(d) __au_dbg_verify_dinode(d, __func__, __LINE__)
+void __au_dbg_verify_dinode(struct dentry *dentry, const char *func, int line);
+void au_dbg_verify_gen(struct dentry *parent, unsigned int sigen);
+void au_dbg_verify_kthread(void);
+
+int __init au_debug_init(void);
+
+#define AuDbgWhlist(w) do { \
+	mutex_lock(&au_dbg_mtx); \
+	AuDbg(#w "\n"); \
+	au_dpri_whlist(w); \
+	mutex_unlock(&au_dbg_mtx); \
+} while (0)
+
+#define AuDbgVdir(v) do { \
+	mutex_lock(&au_dbg_mtx); \
+	AuDbg(#v "\n"); \
+	au_dpri_vdir(v); \
+	mutex_unlock(&au_dbg_mtx); \
+} while (0)
+
+#define AuDbgInode(i) do { \
+	mutex_lock(&au_dbg_mtx); \
+	AuDbg(#i "\n"); \
+	au_dpri_inode(i); \
+	mutex_unlock(&au_dbg_mtx); \
+} while (0)
+
+#define AuDbgDAlias(i) do { \
+	mutex_lock(&au_dbg_mtx); \
+	AuDbg(#i "\n"); \
+	au_dpri_dalias(i); \
+	mutex_unlock(&au_dbg_mtx); \
+} while (0)
+
+#define AuDbgDentry(d) do { \
+	mutex_lock(&au_dbg_mtx); \
+	AuDbg(#d "\n"); \
+	au_dpri_dentry(d); \
+	mutex_unlock(&au_dbg_mtx); \
+} while (0)
+
+#define AuDbgFile(f) do { \
+	mutex_lock(&au_dbg_mtx); \
+	AuDbg(#f "\n"); \
+	au_dpri_file(f); \
+	mutex_unlock(&au_dbg_mtx); \
+} while (0)
+
+#define AuDbgSb(sb) do { \
+	mutex_lock(&au_dbg_mtx); \
+	AuDbg(#sb "\n"); \
+	au_dpri_sb(sb); \
+	mutex_unlock(&au_dbg_mtx); \
+} while (0)
+
+#define AuDbgSym(addr) do {				\
+	char sym[KSYM_SYMBOL_LEN];			\
+	sprint_symbol(sym, (unsigned long)addr);	\
+	AuDbg("%s\n", sym);				\
+} while (0)
+#else
+AuStubVoid(au_dbg_verify_dinode, struct dentry *dentry)
+AuStubVoid(au_dbg_verify_gen, struct dentry *parent, unsigned int sigen)
+AuStubVoid(au_dbg_verify_kthread, void)
+AuStubInt0(__init au_debug_init, void)
+
+#define AuDbgWhlist(w)		do {} while (0)
+#define AuDbgVdir(v)		do {} while (0)
+#define AuDbgInode(i)		do {} while (0)
+#define AuDbgDAlias(i)		do {} while (0)
+#define AuDbgDentry(d)		do {} while (0)
+#define AuDbgFile(f)		do {} while (0)
+#define AuDbgSb(sb)		do {} while (0)
+#define AuDbgSym(addr)		do {} while (0)
+#endif /* CONFIG_AUFS_DEBUG */
+
+/* ---------------------------------------------------------------------- */
+
+#ifdef CONFIG_AUFS_MAGIC_SYSRQ
+int __init au_sysrq_init(void);
+void au_sysrq_fin(void);
+
+#ifdef CONFIG_HW_CONSOLE
+#define au_dbg_blocked() do { \
+	WARN_ON(1); \
+	handle_sysrq('w'); \
+} while (0)
+#else
+AuStubVoid(au_dbg_blocked, void)
+#endif
+
+#else
+AuStubInt0(__init au_sysrq_init, void)
+AuStubVoid(au_sysrq_fin, void)
+AuStubVoid(au_dbg_blocked, void)
+#endif /* CONFIG_AUFS_MAGIC_SYSRQ */
+
+#endif /* __KERNEL__ */
+#endif /* __AUFS_DEBUG_H__ */
--- /dev/null
+++ zfcpdump-kernel-4.4/fs/aufs/dentry.c
@@ -0,0 +1,1136 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+ *
+ * This program, aufs is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * lookup and dentry operations
+ */
+
+#include <linux/namei.h>
+#include "aufs.h"
+
+#define AuLkup_ALLOW_NEG	1
+#define AuLkup_IGNORE_PERM	(1 << 1)
+#define au_ftest_lkup(flags, name)	((flags) & AuLkup_##name)
+#define au_fset_lkup(flags, name) \
+	do { (flags) |= AuLkup_##name; } while (0)
+#define au_fclr_lkup(flags, name) \
+	do { (flags) &= ~AuLkup_##name; } while (0)
+
+struct au_do_lookup_args {
+	unsigned int		flags;
+	mode_t			type;
+};
+
+/*
+ * returns positive/negative dentry, NULL or an error.
+ * NULL means whiteout-ed or not-found.
+ */
+static struct dentry*
+au_do_lookup(struct dentry *h_parent, struct dentry *dentry,
+	     aufs_bindex_t bindex, struct qstr *wh_name,
+	     struct au_do_lookup_args *args)
+{
+	struct dentry *h_dentry;
+	struct inode *h_inode;
+	struct au_branch *br;
+	int wh_found, opq;
+	unsigned char wh_able;
+	const unsigned char allow_neg = !!au_ftest_lkup(args->flags, ALLOW_NEG);
+	const unsigned char ignore_perm = !!au_ftest_lkup(args->flags,
+							  IGNORE_PERM);
+
+	wh_found = 0;
+	br = au_sbr(dentry->d_sb, bindex);
+	wh_able = !!au_br_whable(br->br_perm);
+	if (wh_able)
+		wh_found = au_wh_test(h_parent, wh_name, /*try_sio*/0);
+	h_dentry = ERR_PTR(wh_found);
+	if (!wh_found)
+		goto real_lookup;
+	if (unlikely(wh_found < 0))
+		goto out;
+
+	/* We found a whiteout */
+	/* au_set_dbend(dentry, bindex); */
+	au_set_dbwh(dentry, bindex);
+	if (!allow_neg)
+		return NULL; /* success */
+
+real_lookup:
+	if (!ignore_perm)
+		h_dentry = vfsub_lkup_one(&dentry->d_name, h_parent);
+	else
+		h_dentry = au_sio_lkup_one(&dentry->d_name, h_parent);
+	if (IS_ERR(h_dentry)) {
+		if (PTR_ERR(h_dentry) == -ENAMETOOLONG
+		    && !allow_neg)
+			h_dentry = NULL;
+		goto out;
+	}
+
+	h_inode = d_inode(h_dentry);
+	if (d_is_negative(h_dentry)) {
+		if (!allow_neg)
+			goto out_neg;
+	} else if (wh_found
+		   || (args->type && args->type != (h_inode->i_mode & S_IFMT)))
+		goto out_neg;
+
+	if (au_dbend(dentry) <= bindex)
+		au_set_dbend(dentry, bindex);
+	if (au_dbstart(dentry) < 0 || bindex < au_dbstart(dentry))
+		au_set_dbstart(dentry, bindex);
+	au_set_h_dptr(dentry, bindex, h_dentry);
+
+	if (!d_is_dir(h_dentry)
+	    || !wh_able
+	    || (d_really_is_positive(dentry) && !d_is_dir(dentry)))
+		goto out; /* success */
+
+	mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD);
+	opq = au_diropq_test(h_dentry);
+	mutex_unlock(&h_inode->i_mutex);
+	if (opq > 0)
+		au_set_dbdiropq(dentry, bindex);
+	else if (unlikely(opq < 0)) {
+		au_set_h_dptr(dentry, bindex, NULL);
+		h_dentry = ERR_PTR(opq);
+	}
+	goto out;
+
+out_neg:
+	dput(h_dentry);
+	h_dentry = NULL;
+out:
+	return h_dentry;
+}
+
+static int au_test_shwh(struct super_block *sb, const struct qstr *name)
+{
+	if (unlikely(!au_opt_test(au_mntflags(sb), SHWH)
+		     && !strncmp(name->name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)))
+		return -EPERM;
+	return 0;
+}
+
+/*
+ * returns the number of lower positive dentries,
+ * otherwise an error.
+ * can be called at unlinking with @type is zero.
+ */
+int au_lkup_dentry(struct dentry *dentry, aufs_bindex_t bstart, mode_t type)
+{
+	int npositive, err;
+	aufs_bindex_t bindex, btail, bdiropq;
+	unsigned char isdir, dirperm1;
+	struct qstr whname;
+	struct au_do_lookup_args args = {
+		.flags		= 0,
+		.type		= type
+	};
+	const struct qstr *name = &dentry->d_name;
+	struct dentry *parent;
+	struct super_block *sb;
+
+	sb = dentry->d_sb;
+	err = au_test_shwh(sb, name);
+	if (unlikely(err))
+		goto out;
+
+	err = au_wh_name_alloc(&whname, name);
+	if (unlikely(err))
+		goto out;
+
+	isdir = !!d_is_dir(dentry);
+	if (!type)
+		au_fset_lkup(args.flags, ALLOW_NEG);
+	dirperm1 = !!au_opt_test(au_mntflags(sb), DIRPERM1);
+
+	npositive = 0;
+	parent = dget_parent(dentry);
+	btail = au_dbtaildir(parent);
+	for (bindex = bstart; bindex <= btail; bindex++) {
+		struct dentry *h_parent, *h_dentry;
+		struct inode *h_inode, *h_dir;
+
+		h_dentry = au_h_dptr(dentry, bindex);
+		if (h_dentry) {
+			if (d_is_positive(h_dentry))
+				npositive++;
+			if (type != S_IFDIR)
+				break;
+			continue;
+		}
+		h_parent = au_h_dptr(parent, bindex);
+		if (!h_parent || !d_is_dir(h_parent))
+			continue;
+
+		h_dir = d_inode(h_parent);
+		mutex_lock_nested(&h_dir->i_mutex, AuLsc_I_PARENT);
+		h_dentry = au_do_lookup(h_parent, dentry, bindex, &whname,
+					&args);
+		mutex_unlock(&h_dir->i_mutex);
+		err = PTR_ERR(h_dentry);
+		if (IS_ERR(h_dentry))
+			goto out_parent;
+		if (h_dentry)
+			au_fclr_lkup(args.flags, ALLOW_NEG);
+		if (dirperm1)
+			au_fset_lkup(args.flags, IGNORE_PERM);
+
+		if (au_dbwh(dentry) == bindex)
+			break;
+		if (!h_dentry)
+			continue;
+		if (d_is_negative(h_dentry))
+			continue;
+		h_inode = d_inode(h_dentry);
+		npositive++;
+		if (!args.type)
+			args.type = h_inode->i_mode & S_IFMT;
+		if (args.type != S_IFDIR)
+			break;
+		else if (isdir) {
+			/* the type of lower may be different */
+			bdiropq = au_dbdiropq(dentry);
+			if (bdiropq >= 0 && bdiropq <= bindex)
+				break;
+		}
+	}
+
+	if (npositive) {
+		AuLabel(positive);
+		au_update_dbstart(dentry);
+	}
+	err = npositive;
+	if (unlikely(!au_opt_test(au_mntflags(sb), UDBA_NONE)
+		     && au_dbstart(dentry) < 0)) {
+		err = -EIO;
+		AuIOErr("both of real entry and whiteout found, %pd, err %d\n",
+			dentry, err);
+	}
+
+out_parent:
+	dput(parent);
+	kfree(whname.name);
+out:
+	return err;
+}
+
+struct dentry *au_sio_lkup_one(struct qstr *name, struct dentry *parent)
+{
+	struct dentry *dentry;
+	int wkq_err;
+
+	if (!au_test_h_perm_sio(d_inode(parent), MAY_EXEC))
+		dentry = vfsub_lkup_one(name, parent);
+	else {
+		struct vfsub_lkup_one_args args = {
+			.errp	= &dentry,
+			.name	= name,
+			.parent	= parent
+		};
+
+		wkq_err = au_wkq_wait(vfsub_call_lkup_one, &args);
+		if (unlikely(wkq_err))
+			dentry = ERR_PTR(wkq_err);
+	}
+
+	return dentry;
+}
+
+/*
+ * lookup @dentry on @bindex which should be negative.
+ */
+int au_lkup_neg(struct dentry *dentry, aufs_bindex_t bindex, int wh)
+{
+	int err;
+	struct dentry *parent, *h_parent, *h_dentry;
+	struct au_branch *br;
+
+	parent = dget_parent(dentry);
+	h_parent = au_h_dptr(parent, bindex);
+	br = au_sbr(dentry->d_sb, bindex);
+	if (wh)
+		h_dentry = au_whtmp_lkup(h_parent, br, &dentry->d_name);
+	else
+		h_dentry = au_sio_lkup_one(&dentry->d_name, h_parent);
+	err = PTR_ERR(h_dentry);
+	if (IS_ERR(h_dentry))
+		goto out;
+	if (unlikely(d_is_positive(h_dentry))) {
+		err = -EIO;
+		AuIOErr("%pd should be negative on b%d.\n", h_dentry, bindex);
+		dput(h_dentry);
+		goto out;
+	}
+
+	err = 0;
+	if (bindex < au_dbstart(dentry))
+		au_set_dbstart(dentry, bindex);
+	if (au_dbend(dentry) < bindex)
+		au_set_dbend(dentry, bindex);
+	au_set_h_dptr(dentry, bindex, h_dentry);
+
+out:
+	dput(parent);
+	return err;
+}
+
+/* ---------------------------------------------------------------------- */
+
+/* subset of struct inode */
+struct au_iattr {
+	unsigned long		i_ino;
+	/* unsigned int		i_nlink; */
+	kuid_t			i_uid;
+	kgid_t			i_gid;
+	u64			i_version;
+/*
+	loff_t			i_size;
+	blkcnt_t		i_blocks;
+*/
+	umode_t			i_mode;
+};
+
+static void au_iattr_save(struct au_iattr *ia, struct inode *h_inode)
+{
+	ia->i_ino = h_inode->i_ino;
+	/* ia->i_nlink = h_inode->i_nlink; */
+	ia->i_uid = h_inode->i_uid;
+	ia->i_gid = h_inode->i_gid;
+	ia->i_version = h_inode->i_version;
+/*
+	ia->i_size = h_inode->i_size;
+	ia->i_blocks = h_inode->i_blocks;
+*/
+	ia->i_mode = (h_inode->i_mode & S_IFMT);
+}
+
+static int au_iattr_test(struct au_iattr *ia, struct inode *h_inode)
+{
+	return ia->i_ino != h_inode->i_ino
+		/* || ia->i_nlink != h_inode->i_nlink */
+		|| !uid_eq(ia->i_uid, h_inode->i_uid)
+		|| !gid_eq(ia->i_gid, h_inode->i_gid)
+		|| ia->i_version != h_inode->i_version
+/*
+		|| ia->i_size != h_inode->i_size
+		|| ia->i_blocks != h_inode->i_blocks
+*/
+		|| ia->i_mode != (h_inode->i_mode & S_IFMT);
+}
+
+static int au_h_verify_dentry(struct dentry *h_dentry, struct dentry *h_parent,
+			      struct au_branch *br)
+{
+	int err;
+	struct au_iattr ia;
+	struct inode *h_inode;
+	struct dentry *h_d;
+	struct super_block *h_sb;
+
+	err = 0;
+	memset(&ia, -1, sizeof(ia));
+	h_sb = h_dentry->d_sb;
+	h_inode = NULL;
+	if (d_is_positive(h_dentry)) {
+		h_inode = d_inode(h_dentry);
+		au_iattr_save(&ia, h_inode);
+	} else if (au_test_nfs(h_sb) || au_test_fuse(h_sb))
+		/* nfs d_revalidate may return 0 for negative dentry */
+		/* fuse d_revalidate always return 0 for negative dentry */
+		goto out;
+
+	/* main purpose is namei.c:cached_lookup() and d_revalidate */
+	h_d = vfsub_lkup_one(&h_dentry->d_name, h_parent);
+	err = PTR_ERR(h_d);
+	if (IS_ERR(h_d))
+		goto out;
+
+	err = 0;
+	if (unlikely(h_d != h_dentry
+		     || d_inode(h_d) != h_inode
+		     || (h_inode && au_iattr_test(&ia, h_inode))))
+		err = au_busy_or_stale();
+	dput(h_d);
+
+out:
+	AuTraceErr(err);
+	return err;
+}
+
+int au_h_verify(struct dentry *h_dentry, unsigned int udba, struct inode *h_dir,
+		struct dentry *h_parent, struct au_branch *br)
+{
+	int err;
+
+	err = 0;
+	if (udba == AuOpt_UDBA_REVAL
+	    && !au_test_fs_remote(h_dentry->d_sb)) {
+		IMustLock(h_dir);
+		err = (d_inode(h_dentry->d_parent) != h_dir);
+	} else if (udba != AuOpt_UDBA_NONE)
+		err = au_h_verify_dentry(h_dentry, h_parent, br);
+
+	return err;
+}
+
+/* ---------------------------------------------------------------------- */
+
+static int au_do_refresh_hdentry(struct dentry *dentry, struct dentry *parent)
+{
+	int err;
+	aufs_bindex_t new_bindex, bindex, bend, bwh, bdiropq;
+	struct au_hdentry tmp, *p, *q;
+	struct au_dinfo *dinfo;
+	struct super_block *sb;
+
+	DiMustWriteLock(dentry);
+
+	sb = dentry->d_sb;
+	dinfo = au_di(dentry);
+	bend = dinfo->di_bend;
+	bwh = dinfo->di_bwh;
+	bdiropq = dinfo->di_bdiropq;
+	p = dinfo->di_hdentry + dinfo->di_bstart;
+	for (bindex = dinfo->di_bstart; bindex <= bend; bindex++, p++) {
+		if (!p->hd_dentry)
+			continue;
+
+		new_bindex = au_br_index(sb, p->hd_id);
+		if (new_bindex == bindex)
+			continue;
+
+		if (dinfo->di_bwh == bindex)
+			bwh = new_bindex;
+		if (dinfo->di_bdiropq == bindex)
+			bdiropq = new_bindex;
+		if (new_bindex < 0) {
+			au_hdput(p);
+			p->hd_dentry = NULL;
+			continue;
+		}
+
+		/* swap two lower dentries, and loop again */
+		q = dinfo->di_hdentry + new_bindex;
+		tmp = *q;
+		*q = *p;
+		*p = tmp;
+		if (tmp.hd_dentry) {
+			bindex--;
+			p--;
+		}
+	}
+
+	dinfo->di_bwh = -1;
+	if (bwh >= 0 && bwh <= au_sbend(sb) && au_sbr_whable(sb, bwh))
+		dinfo->di_bwh = bwh;
+
+	dinfo->di_bdiropq = -1;
+	if (bdiropq >= 0
+	    && bdiropq <= au_sbend(sb)
+	    && au_sbr_whable(sb, bdiropq))
+		dinfo->di_bdiropq = bdiropq;
+
+	err = -EIO;
+	dinfo->di_bstart = -1;
+	dinfo->di_bend = -1;
+	bend = au_dbend(parent);
+	p = dinfo->di_hdentry;
+	for (bindex = 0; bindex <= bend; bindex++, p++)
+		if (p->hd_dentry) {
+			dinfo->di_bstart = bindex;
+			break;
+		}
+
+	if (dinfo->di_bstart >= 0) {
+		p = dinfo->di_hdentry + bend;
+		for (bindex = bend; bindex >= 0; bindex--, p--)
+			if (p->hd_dentry) {
+				dinfo->di_bend = bindex;
+				err = 0;
+				break;
+			}
+	}
+
+	return err;
+}
+
+static void au_do_hide(struct dentry *dentry)
+{
+	struct inode *inode;
+
+	if (d_really_is_positive(dentry)) {
+		inode = d_inode(dentry);
+		if (!d_is_dir(dentry)) {
+			if (inode->i_nlink && !d_unhashed(dentry))
+				drop_nlink(inode);
+		} else {
+			clear_nlink(inode);
+			/* stop next lookup */
+			inode->i_flags |= S_DEAD;
+		}
+		smp_mb(); /* necessary? */
+	}
+	d_drop(dentry);
+}
+
+static int au_hide_children(struct dentry *parent)
+{
+	int err, i, j, ndentry;
+	struct au_dcsub_pages dpages;
+	struct au_dpage *dpage;
+	struct dentry *dentry;
+
+	err = au_dpages_init(&dpages, GFP_NOFS);
+	if (unlikely(err))
+		goto out;
+	err = au_dcsub_pages(&dpages, parent, NULL, NULL);
+	if (unlikely(err))
+		goto out_dpages;
+
+	/* in reverse order */
+	for (i = dpages.ndpage - 1; i >= 0; i--) {
+		dpage = dpages.dpages + i;
+		ndentry = dpage->ndentry;
+		for (j = ndentry - 1; j >= 0; j--) {
+			dentry = dpage->dentries[j];
+			if (dentry != parent)
+				au_do_hide(dentry);
+		}
+	}
+
+out_dpages:
+	au_dpages_free(&dpages);
+out:
+	return err;
+}
+
+static void au_hide(struct dentry *dentry)
+{
+	int err;
+
+	AuDbgDentry(dentry);
+	if (d_is_dir(dentry)) {
+		/* shrink_dcache_parent(dentry); */
+		err = au_hide_children(dentry);
+		if (unlikely(err))
+			AuIOErr("%pd, failed hiding children, ignored %d\n",
+				dentry, err);
+	}
+	au_do_hide(dentry);
+}
+
+/*
+ * By adding a dirty branch, a cached dentry may be affected in various ways.
+ *
+ * a dirty branch is added
+ * - on the top of layers
+ * - in the middle of layers
+ * - to the bottom of layers
+ *
+ * on the added branch there exists
+ * - a whiteout
+ * - a diropq
+ * - a same named entry
+ *   + exist
+ *     * negative --> positive
+ *     * positive --> positive
+ *	 - type is unchanged
+ *	 - type is changed
+ *   + doesn't exist
+ *     * negative --> negative
+ *     * positive --> negative (rejected by au_br_del() for non-dir case)
+ * - none
+ */
+static int au_refresh_by_dinfo(struct dentry *dentry, struct au_dinfo *dinfo,
+			       struct au_dinfo *tmp)
+{
+	int err;
+	aufs_bindex_t bindex, bend;
+	struct {
+		struct dentry *dentry;
+		struct inode *inode;
+		mode_t mode;
+	} orig_h, tmp_h = {
+		.dentry = NULL
+	};
+	struct au_hdentry *hd;
+	struct inode *inode, *h_inode;
+	struct dentry *h_dentry;
+
+	err = 0;
+	AuDebugOn(dinfo->di_bstart < 0);
+	orig_h.mode = 0;
+	orig_h.dentry = dinfo->di_hdentry[dinfo->di_bstart].hd_dentry;
+	orig_h.inode = NULL;
+	if (d_is_positive(orig_h.dentry)) {
+		orig_h.inode = d_inode(orig_h.dentry);
+		orig_h.mode = orig_h.inode->i_mode & S_IFMT;
+	}
+	if (tmp->di_bstart >= 0) {
+		tmp_h.dentry = tmp->di_hdentry[tmp->di_bstart].hd_dentry;
+		if (d_is_positive(tmp_h.dentry)) {
+			tmp_h.inode = d_inode(tmp_h.dentry);
+			tmp_h.mode = tmp_h.inode->i_mode & S_IFMT;
+		}
+	}
+
+	inode = NULL;
+	if (d_really_is_positive(dentry))
+		inode = d_inode(dentry);
+	if (!orig_h.inode) {
+		AuDbg("nagative originally\n");
+		if (inode) {
+			au_hide(dentry);
+			goto out;
+		}
+		AuDebugOn(inode);
+		AuDebugOn(dinfo->di_bstart != dinfo->di_bend);
+		AuDebugOn(dinfo->di_bdiropq != -1);
+
+		if (!tmp_h.inode) {
+			AuDbg("negative --> negative\n");
+			/* should have only one negative lower */
+			if (tmp->di_bstart >= 0
+			    && tmp->di_bstart < dinfo->di_bstart) {
+				AuDebugOn(tmp->di_bstart != tmp->di_bend);
+				AuDebugOn(dinfo->di_bstart != dinfo->di_bend);
+				au_set_h_dptr(dentry, dinfo->di_bstart, NULL);
+				au_di_cp(dinfo, tmp);
+				hd = tmp->di_hdentry + tmp->di_bstart;
+				au_set_h_dptr(dentry, tmp->di_bstart,
+					      dget(hd->hd_dentry));
+			}
+			au_dbg_verify_dinode(dentry);
+		} else {
+			AuDbg("negative --> positive\n");
+			/*
+			 * similar to the behaviour of creating with bypassing
+			 * aufs.
+			 * unhash it in order to force an error in the
+			 * succeeding create operation.
+			 * we should not set S_DEAD here.
+			 */
+			d_drop(dentry);
+			/* au_di_swap(tmp, dinfo); */
+			au_dbg_verify_dinode(dentry);
+		}
+	} else {
+		AuDbg("positive originally\n");
+		/* inode may be NULL */
+		AuDebugOn(inode && (inode->i_mode & S_IFMT) != orig_h.mode);
+		if (!tmp_h.inode) {
+			AuDbg("positive --> negative\n");
+			/* or bypassing aufs */
+			au_hide(dentry);
+			if (tmp->di_bwh >= 0 && tmp->di_bwh <= dinfo->di_bstart)
+				dinfo->di_bwh = tmp->di_bwh;
+			if (inode)
+				err = au_refresh_hinode_self(inode);
+			au_dbg_verify_dinode(dentry);
+		} else if (orig_h.mode == tmp_h.mode) {
+			AuDbg("positive --> positive, same type\n");
+			if (!S_ISDIR(orig_h.mode)
+			    && dinfo->di_bstart > tmp->di_bstart) {
+				/*
+				 * similar to the behaviour of removing and
+				 * creating.
+				 */
+				au_hide(dentry);
+				if (inode)
+					err = au_refresh_hinode_self(inode);
+				au_dbg_verify_dinode(dentry);
+			} else {
+				/* fill empty slots */
+				if (dinfo->di_bstart > tmp->di_bstart)
+					dinfo->di_bstart = tmp->di_bstart;
+				if (dinfo->di_bend < tmp->di_bend)
+					dinfo->di_bend = tmp->di_bend;
+				dinfo->di_bwh = tmp->di_bwh;
+				dinfo->di_bdiropq = tmp->di_bdiropq;
+				hd = tmp->di_hdentry;
+				bend = dinfo->di_bend;
+				for (bindex = tmp->di_bstart; bindex <= bend;
+				     bindex++) {
+					if (au_h_dptr(dentry, bindex))
+						continue;
+					h_dentry = hd[bindex].hd_dentry;
+					if (!h_dentry)
+						continue;
+					AuDebugOn(d_is_negative(h_dentry));
+					h_inode = d_inode(h_dentry);
+					AuDebugOn(orig_h.mode
+						  != (h_inode->i_mode
+						      & S_IFMT));
+					au_set_h_dptr(dentry, bindex,
+						      dget(h_dentry));
+				}
+				err = au_refresh_hinode(inode, dentry);
+				au_dbg_verify_dinode(dentry);
+			}
+		} else {
+			AuDbg("positive --> positive, different type\n");
+			/* similar to the behaviour of removing and creating */
+			au_hide(dentry);
+			if (inode)
+				err = au_refresh_hinode_self(inode);
+			au_dbg_verify_dinode(dentry);
+		}
+	}
+
+out:
+	return err;
+}
+
+void au_refresh_dop(struct dentry *dentry, int force_reval)
+{
+	const struct dentry_operations *dop
+		= force_reval ? &aufs_dop : dentry->d_sb->s_d_op;
+	static const unsigned int mask
+		= DCACHE_OP_REVALIDATE | DCACHE_OP_WEAK_REVALIDATE;
+
+	BUILD_BUG_ON(sizeof(mask) != sizeof(dentry->d_flags));
+
+	if (dentry->d_op == dop)
+		return;
+
+	AuDbg("%pd\n", dentry);
+	spin_lock(&dentry->d_lock);
+	if (dop == &aufs_dop)
+		dentry->d_flags |= mask;
+	else
+		dentry->d_flags &= ~mask;
+	dentry->d_op = dop;
+	spin_unlock(&dentry->d_lock);
+}
+
+int au_refresh_dentry(struct dentry *dentry, struct dentry *parent)
+{
+	int err, ebrange;
+	unsigned int sigen;
+	struct au_dinfo *dinfo, *tmp;
+	struct super_block *sb;
+	struct inode *inode;
+
+	DiMustWriteLock(dentry);
+	AuDebugOn(IS_ROOT(dentry));
+	AuDebugOn(d_really_is_negative(parent));
+
+	sb = dentry->d_sb;
+	sigen = au_sigen(sb);
+	err = au_digen_test(parent, sigen);
+	if (unlikely(err))
+		goto out;
+
+	dinfo = au_di(dentry);
+	err = au_di_realloc(dinfo, au_sbend(sb) + 1);
+	if (unlikely(err))
+		goto out;
+	ebrange = au_dbrange_test(dentry);
+	if (!ebrange)
+		ebrange = au_do_refresh_hdentry(dentry, parent);
+
+	if (d_unhashed(dentry) || ebrange /* || dinfo->di_tmpfile */) {
+		AuDebugOn(au_dbstart(dentry) < 0 && au_dbend(dentry) >= 0);
+		if (d_really_is_positive(dentry)) {
+			inode = d_inode(dentry);
+			err = au_refresh_hinode_self(inode);
+		}
+		au_dbg_verify_dinode(dentry);
+		if (!err)
+			goto out_dgen; /* success */
+		goto out;
+	}
+
+	/* temporary dinfo */
+	AuDbgDentry(dentry);
+	err = -ENOMEM;
+	tmp = au_di_alloc(sb, AuLsc_DI_TMP);
+	if (unlikely(!tmp))
+		goto out;
+	au_di_swap(tmp, dinfo);
+	/* returns the number of positive dentries */
+	/*
+	 * if current working dir is removed, it returns an error.
+	 * but the dentry is legal.
+	 */
+	err = au_lkup_dentry(dentry, /*bstart*/0, /*type*/0);
+	AuDbgDentry(dentry);
+	au_di_swap(tmp, dinfo);
+	if (err == -ENOENT)
+		err = 0;
+	if (err >= 0) {
+		/* compare/refresh by dinfo */
+		AuDbgDentry(dentry);
+		err = au_refresh_by_dinfo(dentry, dinfo, tmp);
+		au_dbg_verify_dinode(dentry);
+		AuTraceErr(err);
+	}
+	au_rw_write_unlock(&tmp->di_rwsem);
+	au_di_free(tmp);
+	if (unlikely(err))
+		goto out;
+
+out_dgen:
+	au_update_digen(dentry);
+out:
+	if (unlikely(err && !(dentry->d_flags & DCACHE_NFSFS_RENAMED))) {
+		AuIOErr("failed refreshing %pd, %d\n", dentry, err);
+		AuDbgDentry(dentry);
+	}
+	AuTraceErr(err);
+	return err;
+}
+
+static int au_do_h_d_reval(struct dentry *h_dentry, unsigned int flags,
+			   struct dentry *dentry, aufs_bindex_t bindex)
+{
+	int err, valid;
+
+	err = 0;
+	if (!(h_dentry->d_flags & DCACHE_OP_REVALIDATE))
+		goto out;
+
+	AuDbg("b%d\n", bindex);
+	/*
+	 * gave up supporting LOOKUP_CREATE/OPEN for lower fs,
+	 * due to whiteout and branch permission.
+	 */
+	flags &= ~(/*LOOKUP_PARENT |*/ LOOKUP_OPEN | LOOKUP_CREATE
+		   | LOOKUP_FOLLOW | LOOKUP_EXCL);
+	/* it may return tri-state */
+	valid = h_dentry->d_op->d_revalidate(h_dentry, flags);
+
+	if (unlikely(valid < 0))
+		err = valid;
+	else if (!valid)
+		err = -EINVAL;
+
+out:
+	AuTraceErr(err);
+	return err;
+}
+
+/* todo: remove this */
+static int h_d_revalidate(struct dentry *dentry, struct inode *inode,
+			  unsigned int flags, int do_udba)
+{
+	int err;
+	umode_t mode, h_mode;
+	aufs_bindex_t bindex, btail, bstart, ibs, ibe;
+	unsigned char plus, unhashed, is_root, h_plus, h_nfs, tmpfile;
+	struct inode *h_inode, *h_cached_inode;
+	struct dentry *h_dentry;
+	struct qstr *name, *h_name;
+
+	err = 0;
+	plus = 0;
+	mode = 0;
+	ibs = -1;
+	ibe = -1;
+	unhashed = !!d_unhashed(dentry);
+	is_root = !!IS_ROOT(dentry);
+	name = &dentry->d_name;
+	tmpfile = au_di(dentry)->di_tmpfile;
+
+	/*
+	 * Theoretically, REVAL test should be unnecessary in case of
+	 * {FS,I}NOTIFY.
+	 * But {fs,i}notify doesn't fire some necessary events,
+	 *	IN_ATTRIB for atime/nlink/pageio
+	 * Let's do REVAL test too.
+	 */
+	if (do_udba && inode) {
+		mode = (inode->i_mode & S_IFMT);
+		plus = (inode->i_nlink > 0);
+		ibs = au_ibstart(inode);
+		ibe = au_ibend(inode);
+	}
+
+	bstart = au_dbstart(dentry);
+	btail = bstart;
+	if (inode && S_ISDIR(inode->i_mode))
+		btail = au_dbtaildir(dentry);
+	for (bindex = bstart; bindex <= btail; bindex++) {
+		h_dentry = au_h_dptr(dentry, bindex);
+		if (!h_dentry)
+			continue;
+
+		AuDbg("b%d, %pd\n", bindex, h_dentry);
+		h_nfs = !!au_test_nfs(h_dentry->d_sb);
+		spin_lock(&h_dentry->d_lock);
+		h_name = &h_dentry->d_name;
+		if (unlikely(do_udba
+			     && !is_root
+			     && ((!h_nfs
+				  && (unhashed != !!d_unhashed(h_dentry)
+				      || (!tmpfile
+					  && !au_qstreq(name, h_name))
+					  ))
+				 || (h_nfs
+				     && !(flags & LOOKUP_OPEN)
+				     && (h_dentry->d_flags
+					 & DCACHE_NFSFS_RENAMED)))
+			    )) {
+			int h_unhashed;
+
+			h_unhashed = d_unhashed(h_dentry);
+			spin_unlock(&h_dentry->d_lock);
+			AuDbg("unhash 0x%x 0x%x, %pd %pd\n",
+			      unhashed, h_unhashed, dentry, h_dentry);
+			goto err;
+		}
+		spin_unlock(&h_dentry->d_lock);
+
+		err = au_do_h_d_reval(h_dentry, flags, dentry, bindex);
+		if (unlikely(err))
+			/* do not goto err, to keep the errno */
+			break;
+
+		/* todo: plink too? */
+		if (!do_udba)
+			continue;
+
+		/* UDBA tests */
+		if (unlikely(!!inode != d_is_positive(h_dentry)))
+			goto err;
+
+		h_inode = NULL;
+		if (d_is_positive(h_dentry))
+			h_inode = d_inode(h_dentry);
+		h_plus = plus;
+		h_mode = mode;
+		h_cached_inode = h_inode;
+		if (h_inode) {
+			h_mode = (h_inode->i_mode & S_IFMT);
+			h_plus = (h_inode->i_nlink > 0);
+		}
+		if (inode && ibs <= bindex && bindex <= ibe)
+			h_cached_inode = au_h_iptr(inode, bindex);
+
+		if (!h_nfs) {
+			if (unlikely(plus != h_plus && !tmpfile))
+				goto err;
+		} else {
+			if (unlikely(!(h_dentry->d_flags & DCACHE_NFSFS_RENAMED)
+				     && !is_root
+				     && !IS_ROOT(h_dentry)
+				     && unhashed != d_unhashed(h_dentry)))
+				goto err;
+		}
+		if (unlikely(mode != h_mode
+			     || h_cached_inode != h_inode))
+			goto err;
+		continue;
+
+err:
+		err = -EINVAL;
+		break;
+	}
+
+	AuTraceErr(err);
+	return err;
+}
+
+/* todo: consolidate with do_refresh() and au_reval_for_attr() */
+static int simple_reval_dpath(struct dentry *dentry, unsigned int sigen)
+{
+	int err;
+	struct dentry *parent;
+
+	if (!au_digen_test(dentry, sigen))
+		return 0;
+
+	parent = dget_parent(dentry);
+	di_read_lock_parent(parent, AuLock_IR);
+	AuDebugOn(au_digen_test(parent, sigen));
+	au_dbg_verify_gen(parent, sigen);
+	err = au_refresh_dentry(dentry, parent);
+	di_read_unlock(parent, AuLock_IR);
+	dput(parent);
+	AuTraceErr(err);
+	return err;
+}
+
+int au_reval_dpath(struct dentry *dentry, unsigned int sigen)
+{
+	int err;
+	struct dentry *d, *parent;
+
+	if (!au_ftest_si(au_sbi(dentry->d_sb), FAILED_REFRESH_DIR))
+		return simple_reval_dpath(dentry, sigen);
+
+	/* slow loop, keep it simple and stupid */
+	/* cf: au_cpup_dirs() */
+	err = 0;
+	parent = NULL;
+	while (au_digen_test(dentry, sigen)) {
+		d = dentry;
+		while (1) {
+			dput(parent);
+			parent = dget_parent(d);
+			if (!au_digen_test(parent, sigen))
+				break;
+			d = parent;
+		}
+
+		if (d != dentry)
+			di_write_lock_child2(d);
+
+		/* someone might update our dentry while we were sleeping */
+		if (au_digen_test(d, sigen)) {
+			/*
+			 * todo: consolidate with simple_reval_dpath(),
+			 * do_refresh() and au_reval_for_attr().
+			 */
+			di_read_lock_parent(parent, AuLock_IR);
+			err = au_refresh_dentry(d, parent);
+			di_read_unlock(parent, AuLock_IR);
+		}
+
+		if (d != dentry)
+			di_write_unlock(d);
+		dput(parent);
+		if (unlikely(err))
+			break;
+	}
+
+	return err;
+}
+
+/*
+ * if valid returns 1, otherwise 0.
+ */
+static int aufs_d_revalidate(struct dentry *dentry, unsigned int flags)
+{
+	int valid, err;
+	unsigned int sigen;
+	unsigned char do_udba;
+	struct super_block *sb;
+	struct inode *inode;
+
+	/* todo: support rcu-walk? */
+	if (flags & LOOKUP_RCU)
+		return -ECHILD;
+
+	valid = 0;
+	if (unlikely(!au_di(dentry)))
+		goto out;
+
+	valid = 1;
+	sb = dentry->d_sb;
+	/*
+	 * todo: very ugly
+	 * i_mutex of parent dir may be held,
+	 * but we should not return 'invalid' due to busy.
+	 */
+	err = aufs_read_lock(dentry, AuLock_FLUSH | AuLock_DW | AuLock_NOPLM);
+	if (unlikely(err)) {
+		valid = err;
+		AuTraceErr(err);
+		goto out;
+	}
+	inode = NULL;
+	if (d_really_is_positive(dentry))
+		inode = d_inode(dentry);
+	if (unlikely(inode && is_bad_inode(inode))) {
+		err = -EINVAL;
+		AuTraceErr(err);
+		goto out_dgrade;
+	}
+	if (unlikely(au_dbrange_test(dentry))) {
+		err = -EINVAL;
+		AuTraceErr(err);
+		goto out_dgrade;
+	}
+
+	sigen = au_sigen(sb);
+	if (au_digen_test(dentry, sigen)) {
+		AuDebugOn(IS_ROOT(dentry));
+		err = au_reval_dpath(dentry, sigen);
+		if (unlikely(err)) {
+			AuTraceErr(err);
+			goto out_dgrade;
+		}
+	}
+	di_downgrade_lock(dentry, AuLock_IR);
+
+	err = -EINVAL;
+	if (!(flags & (LOOKUP_OPEN | LOOKUP_EMPTY))
+	    && inode
+	    && !(inode->i_state && I_LINKABLE)
+	    && (IS_DEADDIR(inode) || !inode->i_nlink)) {
+		AuTraceErr(err);
+		goto out_inval;
+	}
+
+	do_udba = !au_opt_test(au_mntflags(sb), UDBA_NONE);
+	if (do_udba && inode) {
+		aufs_bindex_t bstart = au_ibstart(inode);
+		struct inode *h_inode;
+
+		if (bstart >= 0) {
+			h_inode = au_h_iptr(inode, bstart);
+			if (h_inode && au_test_higen(inode, h_inode)) {
+				AuTraceErr(err);
+				goto out_inval;
+			}
+		}
+	}
+
+	err = h_d_revalidate(dentry, inode, flags, do_udba);
+	if (unlikely(!err && do_udba && au_dbstart(dentry) < 0)) {
+		err = -EIO;
+		AuDbg("both of real entry and whiteout found, %p, err %d\n",
+		      dentry, err);
+	}
+	goto out_inval;
+
+out_dgrade:
+	di_downgrade_lock(dentry, AuLock_IR);
+out_inval:
+	aufs_read_unlock(dentry, AuLock_IR);
+	AuTraceErr(err);
+	valid = !err;
+out:
+	if (!valid) {
+		AuDbg("%pd invalid, %d\n", dentry, valid);
+		d_drop(dentry);
+	}
+	return valid;
+}
+
+static void aufs_d_release(struct dentry *dentry)
+{
+	if (au_di(dentry)) {
+		au_di_fin(dentry);
+		au_hn_di_reinit(dentry);
+	}
+}
+
+const struct dentry_operations aufs_dop = {
+	.d_revalidate		= aufs_d_revalidate,
+	.d_weak_revalidate	= aufs_d_revalidate,
+	.d_release		= aufs_d_release
+};
+
+/* aufs_dop without d_revalidate */
+const struct dentry_operations aufs_dop_noreval = {
+	.d_release		= aufs_d_release
+};
--- /dev/null
+++ zfcpdump-kernel-4.4/fs/aufs/dentry.h
@@ -0,0 +1,234 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+ *
+ * This program, aufs is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * lookup and dentry operations
+ */
+
+#ifndef __AUFS_DENTRY_H__
+#define __AUFS_DENTRY_H__
+
+#ifdef __KERNEL__
+
+#include <linux/dcache.h>
+#include "rwsem.h"
+
+struct au_hdentry {
+	struct dentry		*hd_dentry;
+	aufs_bindex_t		hd_id;
+};
+
+struct au_dinfo {
+	atomic_t		di_generation;
+
+	struct au_rwsem		di_rwsem;
+	aufs_bindex_t		di_bstart, di_bend, di_bwh, di_bdiropq;
+	unsigned char		di_tmpfile; /* to allow the different name */
+	struct au_hdentry	*di_hdentry;
+} ____cacheline_aligned_in_smp;
+
+/* ---------------------------------------------------------------------- */
+
+/* dentry.c */
+extern const struct dentry_operations aufs_dop, aufs_dop_noreval;
+struct au_branch;
+struct dentry *au_sio_lkup_one(struct qstr *name, struct dentry *parent);
+int au_h_verify(struct dentry *h_dentry, unsigned int udba, struct inode *h_dir,
+		struct dentry *h_parent, struct au_branch *br);
+
+int au_lkup_dentry(struct dentry *dentry, aufs_bindex_t bstart, mode_t type);
+int au_lkup_neg(struct dentry *dentry, aufs_bindex_t bindex, int wh);
+int au_refresh_dentry(struct dentry *dentry, struct dentry *parent);
+int au_reval_dpath(struct dentry *dentry, unsigned int sigen);
+void au_refresh_dop(struct dentry *dentry, int force_reval);
+
+/* dinfo.c */
+void au_di_init_once(void *_di);
+struct au_dinfo *au_di_alloc(struct super_block *sb, unsigned int lsc);
+void au_di_free(struct au_dinfo *dinfo);
+void au_di_swap(struct au_dinfo *a, struct au_dinfo *b);
+void au_di_cp(struct au_dinfo *dst, struct au_dinfo *src);
+int au_di_init(struct dentry *dentry);
+void au_di_fin(struct dentry *dentry);
+int au_di_realloc(struct au_dinfo *dinfo, int nbr);
+
+void di_read_lock(struct dentry *d, int flags, unsigned int lsc);
+void di_read_unlock(struct dentry *d, int flags);
+void di_downgrade_lock(struct dentry *d, int flags);
+void di_write_lock(struct dentry *d, unsigned int lsc);
+void di_write_unlock(struct dentry *d);
+void di_write_lock2_child(struct dentry *d1, struct dentry *d2, int isdir);
+void di_write_lock2_parent(struct dentry *d1, struct dentry *d2, int isdir);
+void di_write_unlock2(struct dentry *d1, struct dentry *d2);
+
+struct dentry *au_h_dptr(struct dentry *dentry, aufs_bindex_t bindex);
+struct dentry *au_h_d_alias(struct dentry *dentry, aufs_bindex_t bindex);
+aufs_bindex_t au_dbtail(struct dentry *dentry);
+aufs_bindex_t au_dbtaildir(struct dentry *dentry);
+
+void au_set_h_dptr(struct dentry *dentry, aufs_bindex_t bindex,
+		   struct dentry *h_dentry);
+int au_digen_test(struct dentry *dentry, unsigned int sigen);
+int au_dbrange_test(struct dentry *dentry);
+void au_update_digen(struct dentry *dentry);
+void au_update_dbrange(struct dentry *dentry, int do_put_zero);
+void au_update_dbstart(struct dentry *dentry);
+void au_update_dbend(struct dentry *dentry);
+int au_find_dbindex(struct dentry *dentry, struct dentry *h_dentry);
+
+/* ---------------------------------------------------------------------- */
+
+static inline struct au_dinfo *au_di(struct dentry *dentry)
+{
+	return dentry->d_fsdata;
+}
+
+/* ---------------------------------------------------------------------- */
+
+/* lock subclass for dinfo */
+enum {
+	AuLsc_DI_CHILD,		/* child first */
+	AuLsc_DI_CHILD2,	/* rename(2), link(2), and cpup at hnotify */
+	AuLsc_DI_CHILD3,	/* copyup dirs */
+	AuLsc_DI_PARENT,
+	AuLsc_DI_PARENT2,
+	AuLsc_DI_PARENT3,
+	AuLsc_DI_TMP		/* temp for replacing dinfo */
+};
+
+/*
+ * di_read_lock_child, di_write_lock_child,
+ * di_read_lock_child2, di_write_lock_child2,
+ * di_read_lock_child3, di_write_lock_child3,
+ * di_read_lock_parent, di_write_lock_parent,
+ * di_read_lock_parent2, di_write_lock_parent2,
+ * di_read_lock_parent3, di_write_lock_parent3,
+ */
+#define AuReadLockFunc(name, lsc) \
+static inline void di_read_lock_##name(struct dentry *d, int flags) \
+{ di_read_lock(d, flags, AuLsc_DI_##lsc); }
+
+#define AuWriteLockFunc(name, lsc) \
+static inline void di_write_lock_##name(struct dentry *d) \
+{ di_write_lock(d, AuLsc_DI_##lsc); }
+
+#define AuRWLockFuncs(name, lsc) \
+	AuReadLockFunc(name, lsc) \
+	AuWriteLockFunc(name, lsc)
+
+AuRWLockFuncs(child, CHILD);
+AuRWLockFuncs(child2, CHILD2);
+AuRWLockFuncs(child3, CHILD3);
+AuRWLockFuncs(parent, PARENT);
+AuRWLockFuncs(parent2, PARENT2);
+AuRWLockFuncs(parent3, PARENT3);
+
+#undef AuReadLockFunc
+#undef AuWriteLockFunc
+#undef AuRWLockFuncs
+
+#define DiMustNoWaiters(d)	AuRwMustNoWaiters(&au_di(d)->di_rwsem)
+#define DiMustAnyLock(d)	AuRwMustAnyLock(&au_di(d)->di_rwsem)
+#define DiMustWriteLock(d)	AuRwMustWriteLock(&au_di(d)->di_rwsem)
+
+/* ---------------------------------------------------------------------- */
+
+/* todo: memory barrier? */
+static inline unsigned int au_digen(struct dentry *d)
+{
+	return atomic_read(&au_di(d)->di_generation);
+}
+
+static inline void au_h_dentry_init(struct au_hdentry *hdentry)
+{
+	hdentry->hd_dentry = NULL;
+}
+
+static inline void au_hdput(struct au_hdentry *hd)
+{
+	if (hd)
+		dput(hd->hd_dentry);
+}
+
+static inline aufs_bindex_t au_dbstart(struct dentry *dentry)
+{
+	DiMustAnyLock(dentry);
+	return au_di(dentry)->di_bstart;
+}
+
+static inline aufs_bindex_t au_dbend(struct dentry *dentry)
+{
+	DiMustAnyLock(dentry);
+	return au_di(dentry)->di_bend;
+}
+
+static inline aufs_bindex_t au_dbwh(struct dentry *dentry)
+{
+	DiMustAnyLock(dentry);
+	return au_di(dentry)->di_bwh;
+}
+
+static inline aufs_bindex_t au_dbdiropq(struct dentry *dentry)
+{
+	DiMustAnyLock(dentry);
+	return au_di(dentry)->di_bdiropq;
+}
+
+/* todo: hard/soft set? */
+static inline void au_set_dbstart(struct dentry *dentry, aufs_bindex_t bindex)
+{
+	DiMustWriteLock(dentry);
+	au_di(dentry)->di_bstart = bindex;
+}
+
+static inline void au_set_dbend(struct dentry *dentry, aufs_bindex_t bindex)
+{
+	DiMustWriteLock(dentry);
+	au_di(dentry)->di_bend = bindex;
+}
+
+static inline void au_set_dbwh(struct dentry *dentry, aufs_bindex_t bindex)
+{
+	DiMustWriteLock(dentry);
+	/* dbwh can be outside of bstart - bend range */
+	au_di(dentry)->di_bwh = bindex;
+}
+
+static inline void au_set_dbdiropq(struct dentry *dentry, aufs_bindex_t bindex)
+{
+	DiMustWriteLock(dentry);
+	au_di(dentry)->di_bdiropq = bindex;
+}
+
+/* ---------------------------------------------------------------------- */
+
+#ifdef CONFIG_AUFS_HNOTIFY
+static inline void au_digen_dec(struct dentry *d)
+{
+	atomic_dec(&au_di(d)->di_generation);
+}
+
+static inline void au_hn_di_reinit(struct dentry *dentry)
+{
+	dentry->d_fsdata = NULL;
+}
+#else
+AuStubVoid(au_hn_di_reinit, struct dentry *dentry __maybe_unused)
+#endif /* CONFIG_AUFS_HNOTIFY */
+
+#endif /* __KERNEL__ */
+#endif /* __AUFS_DENTRY_H__ */
--- /dev/null
+++ zfcpdump-kernel-4.4/fs/aufs/dinfo.c
@@ -0,0 +1,550 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+ *
+ * This program, aufs is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * dentry private data
+ */
+
+#include "aufs.h"
+
+void au_di_init_once(void *_dinfo)
+{
+	struct au_dinfo *dinfo = _dinfo;
+	static struct lock_class_key aufs_di;
+
+	au_rw_init(&dinfo->di_rwsem);
+	au_rw_class(&dinfo->di_rwsem, &aufs_di);
+}
+
+struct au_dinfo *au_di_alloc(struct super_block *sb, unsigned int lsc)
+{
+	struct au_dinfo *dinfo;
+	int nbr, i;
+
+	dinfo = au_cache_alloc_dinfo();
+	if (unlikely(!dinfo))
+		goto out;
+
+	nbr = au_sbend(sb) + 1;
+	if (nbr <= 0)
+		nbr = 1;
+	dinfo->di_hdentry = kcalloc(nbr, sizeof(*dinfo->di_hdentry), GFP_NOFS);
+	if (dinfo->di_hdentry) {
+		au_rw_write_lock_nested(&dinfo->di_rwsem, lsc);
+		dinfo->di_bstart = -1;
+		dinfo->di_bend = -1;
+		dinfo->di_bwh = -1;
+		dinfo->di_bdiropq = -1;
+		dinfo->di_tmpfile = 0;
+		for (i = 0; i < nbr; i++)
+			dinfo->di_hdentry[i].hd_id = -1;
+		goto out;
+	}
+
+	au_cache_free_dinfo(dinfo);
+	dinfo = NULL;
+
+out:
+	return dinfo;
+}
+
+void au_di_free(struct au_dinfo *dinfo)
+{
+	struct au_hdentry *p;
+	aufs_bindex_t bend, bindex;
+
+	/* dentry may not be revalidated */
+	bindex = dinfo->di_bstart;
+	if (bindex >= 0) {
+		bend = dinfo->di_bend;
+		p = dinfo->di_hdentry + bindex;
+		while (bindex++ <= bend)
+			au_hdput(p++);
+	}
+	kfree(dinfo->di_hdentry);
+	au_cache_free_dinfo(dinfo);
+}
+
+void au_di_swap(struct au_dinfo *a, struct au_dinfo *b)
+{
+	struct au_hdentry *p;
+	aufs_bindex_t bi;
+
+	AuRwMustWriteLock(&a->di_rwsem);
+	AuRwMustWriteLock(&b->di_rwsem);
+
+#define DiSwap(v, name)				\
+	do {					\
+		v = a->di_##name;		\
+		a->di_##name = b->di_##name;	\
+		b->di_##name = v;		\
+	} while (0)
+
+	DiSwap(p, hdentry);
+	DiSwap(bi, bstart);
+	DiSwap(bi, bend);
+	DiSwap(bi, bwh);
+	DiSwap(bi, bdiropq);
+	/* smp_mb(); */
+
+#undef DiSwap
+}
+
+void au_di_cp(struct au_dinfo *dst, struct au_dinfo *src)
+{
+	AuRwMustWriteLock(&dst->di_rwsem);
+	AuRwMustWriteLock(&src->di_rwsem);
+
+	dst->di_bstart = src->di_bstart;
+	dst->di_bend = src->di_bend;
+	dst->di_bwh = src->di_bwh;
+	dst->di_bdiropq = src->di_bdiropq;
+	/* smp_mb(); */
+}
+
+int au_di_init(struct dentry *dentry)
+{
+	int err;
+	struct super_block *sb;
+	struct au_dinfo *dinfo;
+
+	err = 0;
+	sb = dentry->d_sb;
+	dinfo = au_di_alloc(sb, AuLsc_DI_CHILD);
+	if (dinfo) {
+		atomic_set(&dinfo->di_generation, au_sigen(sb));
+		/* smp_mb(); */ /* atomic_set */
+		dentry->d_fsdata = dinfo;
+	} else
+		err = -ENOMEM;
+
+	return err;
+}
+
+void au_di_fin(struct dentry *dentry)
+{
+	struct au_dinfo *dinfo;
+
+	dinfo = au_di(dentry);
+	AuRwDestroy(&dinfo->di_rwsem);
+	au_di_free(dinfo);
+}
+
+int au_di_realloc(struct au_dinfo *dinfo, int nbr)
+{
+	int err, sz;
+	struct au_hdentry *hdp;
+
+	AuRwMustWriteLock(&dinfo->di_rwsem);
+
+	err = -ENOMEM;
+	sz = sizeof(*hdp) * (dinfo->di_bend + 1);
+	if (!sz)
+		sz = sizeof(*hdp);
+	hdp = au_kzrealloc(dinfo->di_hdentry, sz, sizeof(*hdp) * nbr, GFP_NOFS);
+	if (hdp) {
+		dinfo->di_hdentry = hdp;
+		err = 0;
+	}
+
+	return err;
+}
+
+/* ---------------------------------------------------------------------- */
+
+static void do_ii_write_lock(struct inode *inode, unsigned int lsc)
+{
+	switch (lsc) {
+	case AuLsc_DI_CHILD:
+		ii_write_lock_child(inode);
+		break;
+	case AuLsc_DI_CHILD2:
+		ii_write_lock_child2(inode);
+		break;
+	case AuLsc_DI_CHILD3:
+		ii_write_lock_child3(inode);
+		break;
+	case AuLsc_DI_PARENT:
+		ii_write_lock_parent(inode);
+		break;
+	case AuLsc_DI_PARENT2:
+		ii_write_lock_parent2(inode);
+		break;
+	case AuLsc_DI_PARENT3:
+		ii_write_lock_parent3(inode);
+		break;
+	default:
+		BUG();
+	}
+}
+
+static void do_ii_read_lock(struct inode *inode, unsigned int lsc)
+{
+	switch (lsc) {
+	case AuLsc_DI_CHILD:
+		ii_read_lock_child(inode);
+		break;
+	case AuLsc_DI_CHILD2:
+		ii_read_lock_child2(inode);
+		break;
+	case AuLsc_DI_CHILD3:
+		ii_read_lock_child3(inode);
+		break;
+	case AuLsc_DI_PARENT:
+		ii_read_lock_parent(inode);
+		break;
+	case AuLsc_DI_PARENT2:
+		ii_read_lock_parent2(inode);
+		break;
+	case AuLsc_DI_PARENT3:
+		ii_read_lock_parent3(inode);
+		break;
+	default:
+		BUG();
+	}
+}
+
+void di_read_lock(struct dentry *d, int flags, unsigned int lsc)
+{
+	struct inode *inode;
+
+	au_rw_read_lock_nested(&au_di(d)->di_rwsem, lsc);
+	if (d_really_is_positive(d)) {
+		inode = d_inode(d);
+		if (au_ftest_lock(flags, IW))
+			do_ii_write_lock(inode, lsc);
+		else if (au_ftest_lock(flags, IR))
+			do_ii_read_lock(inode, lsc);
+	}
+}
+
+void di_read_unlock(struct dentry *d, int flags)
+{
+	struct inode *inode;
+
+	if (d_really_is_positive(d)) {
+		inode = d_inode(d);
+		if (au_ftest_lock(flags, IW)) {
+			au_dbg_verify_dinode(d);
+			ii_write_unlock(inode);
+		} else if (au_ftest_lock(flags, IR)) {
+			au_dbg_verify_dinode(d);
+			ii_read_unlock(inode);
+		}
+	}
+	au_rw_read_unlock(&au_di(d)->di_rwsem);
+}
+
+void di_downgrade_lock(struct dentry *d, int flags)
+{
+	if (d_really_is_positive(d) && au_ftest_lock(flags, IR))
+		ii_downgrade_lock(d_inode(d));
+	au_rw_dgrade_lock(&au_di(d)->di_rwsem);
+}
+
+void di_write_lock(struct dentry *d, unsigned int lsc)
+{
+	au_rw_write_lock_nested(&au_di(d)->di_rwsem, lsc);
+	if (d_really_is_positive(d))
+		do_ii_write_lock(d_inode(d), lsc);
+}
+
+void di_write_unlock(struct dentry *d)
+{
+	au_dbg_verify_dinode(d);
+	if (d_really_is_positive(d))
+		ii_write_unlock(d_inode(d));
+	au_rw_write_unlock(&au_di(d)->di_rwsem);
+}
+
+void di_write_lock2_child(struct dentry *d1, struct dentry *d2, int isdir)
+{
+	AuDebugOn(d1 == d2
+		  || d_inode(d1) == d_inode(d2)
+		  || d1->d_sb != d2->d_sb);
+
+	if (isdir && au_test_subdir(d1, d2)) {
+		di_write_lock_child(d1);
+		di_write_lock_child2(d2);
+	} else {
+		/* there should be no races */
+		di_write_lock_child(d2);
+		di_write_lock_child2(d1);
+	}
+}
+
+void di_write_lock2_parent(struct dentry *d1, struct dentry *d2, int isdir)
+{
+	AuDebugOn(d1 == d2
+		  || d_inode(d1) == d_inode(d2)
+		  || d1->d_sb != d2->d_sb);
+
+	if (isdir && au_test_subdir(d1, d2)) {
+		di_write_lock_parent(d1);
+		di_write_lock_parent2(d2);
+	} else {
+		/* there should be no races */
+		di_write_lock_parent(d2);
+		di_write_lock_parent2(d1);
+	}
+}
+
+void di_write_unlock2(struct dentry *d1, struct dentry *d2)
+{
+	di_write_unlock(d1);
+	if (d_inode(d1) == d_inode(d2))
+		au_rw_write_unlock(&au_di(d2)->di_rwsem);
+	else
+		di_write_unlock(d2);
+}
+
+/* ---------------------------------------------------------------------- */
+
+struct dentry *au_h_dptr(struct dentry *dentry, aufs_bindex_t bindex)
+{
+	struct dentry *d;
+
+	DiMustAnyLock(dentry);
+
+	if (au_dbstart(dentry) < 0 || bindex < au_dbstart(dentry))
+		return NULL;
+	AuDebugOn(bindex < 0);
+	d = au_di(dentry)->di_hdentry[0 + bindex].hd_dentry;
+	AuDebugOn(d && au_dcount(d) <= 0);
+	return d;
+}
+
+/*
+ * extended version of au_h_dptr().
+ * returns a hashed and positive (or linkable) h_dentry in bindex, NULL, or
+ * error.
+ */
+struct dentry *au_h_d_alias(struct dentry *dentry, aufs_bindex_t bindex)
+{
+	struct dentry *h_dentry;
+	struct inode *inode, *h_inode;
+
+	AuDebugOn(d_really_is_negative(dentry));
+
+	h_dentry = NULL;
+	if (au_dbstart(dentry) <= bindex
+	    && bindex <= au_dbend(dentry))
+		h_dentry = au_h_dptr(dentry, bindex);
+	if (h_dentry && !au_d_linkable(h_dentry)) {
+		dget(h_dentry);
+		goto out; /* success */
+	}
+
+	inode = d_inode(dentry);
+	AuDebugOn(bindex < au_ibstart(inode));
+	AuDebugOn(au_ibend(inode) < bindex);
+	h_inode = au_h_iptr(inode, bindex);
+	h_dentry = d_find_alias(h_inode);
+	if (h_dentry) {
+		if (!IS_ERR(h_dentry)) {
+			if (!au_d_linkable(h_dentry))
+				goto out; /* success */
+			dput(h_dentry);
+		} else
+			goto out;
+	}
+
+	if (au_opt_test(au_mntflags(dentry->d_sb), PLINK)) {
+		h_dentry = au_plink_lkup(inode, bindex);
+		AuDebugOn(!h_dentry);
+		if (!IS_ERR(h_dentry)) {
+			if (!au_d_hashed_positive(h_dentry))
+				goto out; /* success */
+			dput(h_dentry);
+			h_dentry = NULL;
+		}
+	}
+
+out:
+	AuDbgDentry(h_dentry);
+	return h_dentry;
+}
+
+aufs_bindex_t au_dbtail(struct dentry *dentry)
+{
+	aufs_bindex_t bend, bwh;
+
+	bend = au_dbend(dentry);
+	if (0 <= bend) {
+		bwh = au_dbwh(dentry);
+		if (!bwh)
+			return bwh;
+		if (0 < bwh && bwh < bend)
+			return bwh - 1;
+	}
+	return bend;
+}
+
+aufs_bindex_t au_dbtaildir(struct dentry *dentry)
+{
+	aufs_bindex_t bend, bopq;
+
+	bend = au_dbtail(dentry);
+	if (0 <= bend) {
+		bopq = au_dbdiropq(dentry);
+		if (0 <= bopq && bopq < bend)
+			bend = bopq;
+	}
+	return bend;
+}
+
+/* ---------------------------------------------------------------------- */
+
+void au_set_h_dptr(struct dentry *dentry, aufs_bindex_t bindex,
+		   struct dentry *h_dentry)
+{
+	struct au_hdentry *hd = au_di(dentry)->di_hdentry + bindex;
+	struct au_branch *br;
+
+	DiMustWriteLock(dentry);
+
+	au_hdput(hd);
+	hd->hd_dentry = h_dentry;
+	if (h_dentry) {
+		br = au_sbr(dentry->d_sb, bindex);
+		hd->hd_id = br->br_id;
+	}
+}
+
+int au_dbrange_test(struct dentry *dentry)
+{
+	int err;
+	aufs_bindex_t bstart, bend;
+
+	err = 0;
+	bstart = au_dbstart(dentry);
+	bend = au_dbend(dentry);
+	if (bstart >= 0)
+		AuDebugOn(bend < 0 && bstart > bend);
+	else {
+		err = -EIO;
+		AuDebugOn(bend >= 0);
+	}
+
+	return err;
+}
+
+int au_digen_test(struct dentry *dentry, unsigned int sigen)
+{
+	int err;
+
+	err = 0;
+	if (unlikely(au_digen(dentry) != sigen
+		     || au_iigen_test(d_inode(dentry), sigen)))
+		err = -EIO;
+
+	return err;
+}
+
+void au_update_digen(struct dentry *dentry)
+{
+	atomic_set(&au_di(dentry)->di_generation, au_sigen(dentry->d_sb));
+	/* smp_mb(); */ /* atomic_set */
+}
+
+void au_update_dbrange(struct dentry *dentry, int do_put_zero)
+{
+	struct au_dinfo *dinfo;
+	struct dentry *h_d;
+	struct au_hdentry *hdp;
+
+	DiMustWriteLock(dentry);
+
+	dinfo = au_di(dentry);
+	if (!dinfo || dinfo->di_bstart < 0)
+		return;
+
+	hdp = dinfo->di_hdentry;
+	if (do_put_zero) {
+		aufs_bindex_t bindex, bend;
+
+		bend = dinfo->di_bend;
+		for (bindex = dinfo->di_bstart; bindex <= bend; bindex++) {
+			h_d = hdp[0 + bindex].hd_dentry;
+			if (h_d && d_is_negative(h_d))
+				au_set_h_dptr(dentry, bindex, NULL);
+		}
+	}
+
+	dinfo->di_bstart = -1;
+	while (++dinfo->di_bstart <= dinfo->di_bend)
+		if (hdp[0 + dinfo->di_bstart].hd_dentry)
+			break;
+	if (dinfo->di_bstart > dinfo->di_bend) {
+		dinfo->di_bstart = -1;
+		dinfo->di_bend = -1;
+		return;
+	}
+
+	dinfo->di_bend++;
+	while (0 <= --dinfo->di_bend)
+		if (hdp[0 + dinfo->di_bend].hd_dentry)
+			break;
+	AuDebugOn(dinfo->di_bstart > dinfo->di_bend || dinfo->di_bend < 0);
+}
+
+void au_update_dbstart(struct dentry *dentry)
+{
+	aufs_bindex_t bindex, bend;
+	struct dentry *h_dentry;
+
+	bend = au_dbend(dentry);
+	for (bindex = au_dbstart(dentry); bindex <= bend; bindex++) {
+		h_dentry = au_h_dptr(dentry, bindex);
+		if (!h_dentry)
+			continue;
+		if (d_is_positive(h_dentry)) {
+			au_set_dbstart(dentry, bindex);
+			return;
+		}
+		au_set_h_dptr(dentry, bindex, NULL);
+	}
+}
+
+void au_update_dbend(struct dentry *dentry)
+{
+	aufs_bindex_t bindex, bstart;
+	struct dentry *h_dentry;
+
+	bstart = au_dbstart(dentry);
+	for (bindex = au_dbend(dentry); bindex >= bstart; bindex--) {
+		h_dentry = au_h_dptr(dentry, bindex);
+		if (!h_dentry)
+			continue;
+		if (d_is_positive(h_dentry)) {
+			au_set_dbend(dentry, bindex);
+			return;
+		}
+		au_set_h_dptr(dentry, bindex, NULL);
+	}
+}
+
+int au_find_dbindex(struct dentry *dentry, struct dentry *h_dentry)
+{
+	aufs_bindex_t bindex, bend;
+
+	bend = au_dbend(dentry);
+	for (bindex = au_dbstart(dentry); bindex <= bend; bindex++)
+		if (au_h_dptr(dentry, bindex) == h_dentry)
+			return bindex;
+	return -1;
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/fs/aufs/dir.c
@@ -0,0 +1,753 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+ *
+ * This program, aufs is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * directory operations
+ */
+
+#include <linux/fs_stack.h>
+#include "aufs.h"
+
+void au_add_nlink(struct inode *dir, struct inode *h_dir)
+{
+	unsigned int nlink;
+
+	AuDebugOn(!S_ISDIR(dir->i_mode) || !S_ISDIR(h_dir->i_mode));
+
+	nlink = dir->i_nlink;
+	nlink += h_dir->i_nlink - 2;
+	if (h_dir->i_nlink < 2)
+		nlink += 2;
+	smp_mb(); /* for i_nlink */
+	/* 0 can happen in revaliding */
+	set_nlink(dir, nlink);
+}
+
+void au_sub_nlink(struct inode *dir, struct inode *h_dir)
+{
+	unsigned int nlink;
+
+	AuDebugOn(!S_ISDIR(dir->i_mode) || !S_ISDIR(h_dir->i_mode));
+
+	nlink = dir->i_nlink;
+	nlink -= h_dir->i_nlink - 2;
+	if (h_dir->i_nlink < 2)
+		nlink -= 2;
+	smp_mb(); /* for i_nlink */
+	/* nlink == 0 means the branch-fs is broken */
+	set_nlink(dir, nlink);
+}
+
+loff_t au_dir_size(struct file *file, struct dentry *dentry)
+{
+	loff_t sz;
+	aufs_bindex_t bindex, bend;
+	struct file *h_file;
+	struct dentry *h_dentry;
+
+	sz = 0;
+	if (file) {
+		AuDebugOn(!d_is_dir(file->f_path.dentry));
+
+		bend = au_fbend_dir(file);
+		for (bindex = au_fbstart(file);
+		     bindex <= bend && sz < KMALLOC_MAX_SIZE;
+		     bindex++) {
+			h_file = au_hf_dir(file, bindex);
+			if (h_file && file_inode(h_file))
+				sz += vfsub_f_size_read(h_file);
+		}
+	} else {
+		AuDebugOn(!dentry);
+		AuDebugOn(!d_is_dir(dentry));
+
+		bend = au_dbtaildir(dentry);
+		for (bindex = au_dbstart(dentry);
+		     bindex <= bend && sz < KMALLOC_MAX_SIZE;
+		     bindex++) {
+			h_dentry = au_h_dptr(dentry, bindex);
+			if (h_dentry && d_is_positive(h_dentry))
+				sz += i_size_read(d_inode(h_dentry));
+		}
+	}
+	if (sz < KMALLOC_MAX_SIZE)
+		sz = roundup_pow_of_two(sz);
+	if (sz > KMALLOC_MAX_SIZE)
+		sz = KMALLOC_MAX_SIZE;
+	else if (sz < NAME_MAX) {
+		BUILD_BUG_ON(AUFS_RDBLK_DEF < NAME_MAX);
+		sz = AUFS_RDBLK_DEF;
+	}
+	return sz;
+}
+
+struct au_dir_ts_arg {
+	struct dentry *dentry;
+	aufs_bindex_t brid;
+};
+
+static void au_do_dir_ts(void *arg)
+{
+	struct au_dir_ts_arg *a = arg;
+	struct au_dtime dt;
+	struct path h_path;
+	struct inode *dir, *h_dir;
+	struct super_block *sb;
+	struct au_branch *br;
+	struct au_hinode *hdir;
+	int err;
+	aufs_bindex_t bstart, bindex;
+
+	sb = a->dentry->d_sb;
+	if (d_really_is_negative(a->dentry))
+		goto out;
+	/* no dir->i_mutex lock */
+	aufs_read_lock(a->dentry, AuLock_DW); /* noflush */
+
+	dir = d_inode(a->dentry);
+	bstart = au_ibstart(dir);
+	bindex = au_br_index(sb, a->brid);
+	if (bindex < bstart)
+		goto out_unlock;
+
+	br = au_sbr(sb, bindex);
+	h_path.dentry = au_h_dptr(a->dentry, bindex);
+	if (!h_path.dentry)
+		goto out_unlock;
+	h_path.mnt = au_br_mnt(br);
+	au_dtime_store(&dt, a->dentry, &h_path);
+
+	br = au_sbr(sb, bstart);
+	if (!au_br_writable(br->br_perm))
+		goto out_unlock;
+	h_path.dentry = au_h_dptr(a->dentry, bstart);
+	h_path.mnt = au_br_mnt(br);
+	err = vfsub_mnt_want_write(h_path.mnt);
+	if (err)
+		goto out_unlock;
+	hdir = au_hi(dir, bstart);
+	au_hn_imtx_lock_nested(hdir, AuLsc_I_PARENT);
+	h_dir = au_h_iptr(dir, bstart);
+	if (h_dir->i_nlink
+	    && timespec_compare(&h_dir->i_mtime, &dt.dt_mtime) < 0) {
+		dt.dt_h_path = h_path;
+		au_dtime_revert(&dt);
+	}
+	au_hn_imtx_unlock(hdir);
+	vfsub_mnt_drop_write(h_path.mnt);
+	au_cpup_attr_timesizes(dir);
+
+out_unlock:
+	aufs_read_unlock(a->dentry, AuLock_DW);
+out:
+	dput(a->dentry);
+	au_nwt_done(&au_sbi(sb)->si_nowait);
+	kfree(arg);
+}
+
+void au_dir_ts(struct inode *dir, aufs_bindex_t bindex)
+{
+	int perm, wkq_err;
+	aufs_bindex_t bstart;
+	struct au_dir_ts_arg *arg;
+	struct dentry *dentry;
+	struct super_block *sb;
+
+	IMustLock(dir);
+
+	dentry = d_find_any_alias(dir);
+	AuDebugOn(!dentry);
+	sb = dentry->d_sb;
+	bstart = au_ibstart(dir);
+	if (bstart == bindex) {
+		au_cpup_attr_timesizes(dir);
+		goto out;
+	}
+
+	perm = au_sbr_perm(sb, bstart);
+	if (!au_br_writable(perm))
+		goto out;
+
+	arg = kmalloc(sizeof(*arg), GFP_NOFS);
+	if (!arg)
+		goto out;
+
+	arg->dentry = dget(dentry); /* will be dput-ted by au_do_dir_ts() */
+	arg->brid = au_sbr_id(sb, bindex);
+	wkq_err = au_wkq_nowait(au_do_dir_ts, arg, sb, /*flags*/0);
+	if (unlikely(wkq_err)) {
+		pr_err("wkq %d\n", wkq_err);
+		dput(dentry);
+		kfree(arg);
+	}
+
+out:
+	dput(dentry);
+}
+
+/* ---------------------------------------------------------------------- */
+
+static int reopen_dir(struct file *file)
+{
+	int err;
+	unsigned int flags;
+	aufs_bindex_t bindex, btail, bstart;
+	struct dentry *dentry, *h_dentry;
+	struct file *h_file;
+
+	/* open all lower dirs */
+	dentry = file->f_path.dentry;
+	bstart = au_dbstart(dentry);
+	for (bindex = au_fbstart(file); bindex < bstart; bindex++)
+		au_set_h_fptr(file, bindex, NULL);
+	au_set_fbstart(file, bstart);
+
+	btail = au_dbtaildir(dentry);
+	for (bindex = au_fbend_dir(file); btail < bindex; bindex--)
+		au_set_h_fptr(file, bindex, NULL);
+	au_set_fbend_dir(file, btail);
+
+	flags = vfsub_file_flags(file);
+	for (bindex = bstart; bindex <= btail; bindex++) {
+		h_dentry = au_h_dptr(dentry, bindex);
+		if (!h_dentry)
+			continue;
+		h_file = au_hf_dir(file, bindex);
+		if (h_file)
+			continue;
+
+		h_file = au_h_open(dentry, bindex, flags, file, /*force_wr*/0);
+		err = PTR_ERR(h_file);
+		if (IS_ERR(h_file))
+			goto out; /* close all? */
+		au_set_h_fptr(file, bindex, h_file);
+	}
+	au_update_figen(file);
+	/* todo: necessary? */
+	/* file->f_ra = h_file->f_ra; */
+	err = 0;
+
+out:
+	return err;
+}
+
+static int do_open_dir(struct file *file, int flags, struct file *h_file)
+{
+	int err;
+	aufs_bindex_t bindex, btail;
+	struct dentry *dentry, *h_dentry;
+
+	FiMustWriteLock(file);
+	AuDebugOn(h_file);
+
+	err = 0;
+	dentry = file->f_path.dentry;
+	file->f_version = d_inode(dentry)->i_version;
+	bindex = au_dbstart(dentry);
+	au_set_fbstart(file, bindex);
+	btail = au_dbtaildir(dentry);
+	au_set_fbend_dir(file, btail);
+	for (; !err && bindex <= btail; bindex++) {
+		h_dentry = au_h_dptr(dentry, bindex);
+		if (!h_dentry)
+			continue;
+
+		h_file = au_h_open(dentry, bindex, flags, file, /*force_wr*/0);
+		if (IS_ERR(h_file)) {
+			err = PTR_ERR(h_file);
+			break;
+		}
+		au_set_h_fptr(file, bindex, h_file);
+	}
+	au_update_figen(file);
+	/* todo: necessary? */
+	/* file->f_ra = h_file->f_ra; */
+	if (!err)
+		return 0; /* success */
+
+	/* close all */
+	for (bindex = au_fbstart(file); bindex <= btail; bindex++)
+		au_set_h_fptr(file, bindex, NULL);
+	au_set_fbstart(file, -1);
+	au_set_fbend_dir(file, -1);
+
+	return err;
+}
+
+static int aufs_open_dir(struct inode *inode __maybe_unused,
+			 struct file *file)
+{
+	int err;
+	struct super_block *sb;
+	struct au_fidir *fidir;
+
+	err = -ENOMEM;
+	sb = file->f_path.dentry->d_sb;
+	si_read_lock(sb, AuLock_FLUSH);
+	fidir = au_fidir_alloc(sb);
+	if (fidir) {
+		struct au_do_open_args args = {
+			.open	= do_open_dir,
+			.fidir	= fidir
+		};
+		err = au_do_open(file, &args);
+		if (unlikely(err))
+			kfree(fidir);
+	}
+	si_read_unlock(sb);
+	return err;
+}
+
+static int aufs_release_dir(struct inode *inode __maybe_unused,
+			    struct file *file)
+{
+	struct au_vdir *vdir_cache;
+	struct au_finfo *finfo;
+	struct au_fidir *fidir;
+	aufs_bindex_t bindex, bend;
+
+	finfo = au_fi(file);
+	fidir = finfo->fi_hdir;
+	if (fidir) {
+		au_sphl_del(&finfo->fi_hlist,
+			    &au_sbi(file->f_path.dentry->d_sb)->si_files);
+		vdir_cache = fidir->fd_vdir_cache; /* lock-free */
+		if (vdir_cache)
+			au_vdir_free(vdir_cache);
+
+		bindex = finfo->fi_btop;
+		if (bindex >= 0) {
+			/*
+			 * calls fput() instead of filp_close(),
+			 * since no dnotify or lock for the lower file.
+			 */
+			bend = fidir->fd_bbot;
+			for (; bindex <= bend; bindex++)
+				au_set_h_fptr(file, bindex, NULL);
+		}
+		kfree(fidir);
+		finfo->fi_hdir = NULL;
+	}
+	au_finfo_fin(file);
+	return 0;
+}
+
+/* ---------------------------------------------------------------------- */
+
+static int au_do_flush_dir(struct file *file, fl_owner_t id)
+{
+	int err;
+	aufs_bindex_t bindex, bend;
+	struct file *h_file;
+
+	err = 0;
+	bend = au_fbend_dir(file);
+	for (bindex = au_fbstart(file); !err && bindex <= bend; bindex++) {
+		h_file = au_hf_dir(file, bindex);
+		if (h_file)
+			err = vfsub_flush(h_file, id);
+	}
+	return err;
+}
+
+static int aufs_flush_dir(struct file *file, fl_owner_t id)
+{
+	return au_do_flush(file, id, au_do_flush_dir);
+}
+
+/* ---------------------------------------------------------------------- */
+
+static int au_do_fsync_dir_no_file(struct dentry *dentry, int datasync)
+{
+	int err;
+	aufs_bindex_t bend, bindex;
+	struct inode *inode;
+	struct super_block *sb;
+
+	err = 0;
+	sb = dentry->d_sb;
+	inode = d_inode(dentry);
+	IMustLock(inode);
+	bend = au_dbend(dentry);
+	for (bindex = au_dbstart(dentry); !err && bindex <= bend; bindex++) {
+		struct path h_path;
+
+		if (au_test_ro(sb, bindex, inode))
+			continue;
+		h_path.dentry = au_h_dptr(dentry, bindex);
+		if (!h_path.dentry)
+			continue;
+
+		h_path.mnt = au_sbr_mnt(sb, bindex);
+		err = vfsub_fsync(NULL, &h_path, datasync);
+	}
+
+	return err;
+}
+
+static int au_do_fsync_dir(struct file *file, int datasync)
+{
+	int err;
+	aufs_bindex_t bend, bindex;
+	struct file *h_file;
+	struct super_block *sb;
+	struct inode *inode;
+
+	err = au_reval_and_lock_fdi(file, reopen_dir, /*wlock*/1);
+	if (unlikely(err))
+		goto out;
+
+	inode = file_inode(file);
+	sb = inode->i_sb;
+	bend = au_fbend_dir(file);
+	for (bindex = au_fbstart(file); !err && bindex <= bend; bindex++) {
+		h_file = au_hf_dir(file, bindex);
+		if (!h_file || au_test_ro(sb, bindex, inode))
+			continue;
+
+		err = vfsub_fsync(h_file, &h_file->f_path, datasync);
+	}
+
+out:
+	return err;
+}
+
+/*
+ * @file may be NULL
+ */
+static int aufs_fsync_dir(struct file *file, loff_t start, loff_t end,
+			  int datasync)
+{
+	int err;
+	struct dentry *dentry;
+	struct inode *inode;
+	struct super_block *sb;
+	struct mutex *mtx;
+
+	err = 0;
+	dentry = file->f_path.dentry;
+	inode = d_inode(dentry);
+	mtx = &inode->i_mutex;
+	mutex_lock(mtx);
+	sb = dentry->d_sb;
+	si_noflush_read_lock(sb);
+	if (file)
+		err = au_do_fsync_dir(file, datasync);
+	else {
+		di_write_lock_child(dentry);
+		err = au_do_fsync_dir_no_file(dentry, datasync);
+	}
+	au_cpup_attr_timesizes(inode);
+	di_write_unlock(dentry);
+	if (file)
+		fi_write_unlock(file);
+
+	si_read_unlock(sb);
+	mutex_unlock(mtx);
+	return err;
+}
+
+/* ---------------------------------------------------------------------- */
+
+static int aufs_iterate(struct file *file, struct dir_context *ctx)
+{
+	int err;
+	struct dentry *dentry;
+	struct inode *inode, *h_inode;
+	struct super_block *sb;
+
+	AuDbg("%pD, ctx{%pf, %llu}\n", file, ctx->actor, ctx->pos);
+
+	dentry = file->f_path.dentry;
+	inode = d_inode(dentry);
+	IMustLock(inode);
+
+	sb = dentry->d_sb;
+	si_read_lock(sb, AuLock_FLUSH);
+	err = au_reval_and_lock_fdi(file, reopen_dir, /*wlock*/1);
+	if (unlikely(err))
+		goto out;
+	err = au_alive_dir(dentry);
+	if (!err)
+		err = au_vdir_init(file);
+	di_downgrade_lock(dentry, AuLock_IR);
+	if (unlikely(err))
+		goto out_unlock;
+
+	h_inode = au_h_iptr(inode, au_ibstart(inode));
+	if (!au_test_nfsd()) {
+		err = au_vdir_fill_de(file, ctx);
+		fsstack_copy_attr_atime(inode, h_inode);
+	} else {
+		/*
+		 * nfsd filldir may call lookup_one_len(), vfs_getattr(),
+		 * encode_fh() and others.
+		 */
+		atomic_inc(&h_inode->i_count);
+		di_read_unlock(dentry, AuLock_IR);
+		si_read_unlock(sb);
+		err = au_vdir_fill_de(file, ctx);
+		fsstack_copy_attr_atime(inode, h_inode);
+		fi_write_unlock(file);
+		iput(h_inode);
+
+		AuTraceErr(err);
+		return err;
+	}
+
+out_unlock:
+	di_read_unlock(dentry, AuLock_IR);
+	fi_write_unlock(file);
+out:
+	si_read_unlock(sb);
+	return err;
+}
+
+/* ---------------------------------------------------------------------- */
+
+#define AuTestEmpty_WHONLY	1
+#define AuTestEmpty_CALLED	(1 << 1)
+#define AuTestEmpty_SHWH	(1 << 2)
+#define au_ftest_testempty(flags, name)	((flags) & AuTestEmpty_##name)
+#define au_fset_testempty(flags, name) \
+	do { (flags) |= AuTestEmpty_##name; } while (0)
+#define au_fclr_testempty(flags, name) \
+	do { (flags) &= ~AuTestEmpty_##name; } while (0)
+
+#ifndef CONFIG_AUFS_SHWH
+#undef AuTestEmpty_SHWH
+#define AuTestEmpty_SHWH	0
+#endif
+
+struct test_empty_arg {
+	struct dir_context ctx;
+	struct au_nhash *whlist;
+	unsigned int flags;
+	int err;
+	aufs_bindex_t bindex;
+};
+
+static int test_empty_cb(struct dir_context *ctx, const char *__name,
+			 int namelen, loff_t offset __maybe_unused, u64 ino,
+			 unsigned int d_type)
+{
+	struct test_empty_arg *arg = container_of(ctx, struct test_empty_arg,
+						  ctx);
+	char *name = (void *)__name;
+
+	arg->err = 0;
+	au_fset_testempty(arg->flags, CALLED);
+	/* smp_mb(); */
+	if (name[0] == '.'
+	    && (namelen == 1 || (name[1] == '.' && namelen == 2)))
+		goto out; /* success */
+
+	if (namelen <= AUFS_WH_PFX_LEN
+	    || memcmp(name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)) {
+		if (au_ftest_testempty(arg->flags, WHONLY)
+		    && !au_nhash_test_known_wh(arg->whlist, name, namelen))
+			arg->err = -ENOTEMPTY;
+		goto out;
+	}
+
+	name += AUFS_WH_PFX_LEN;
+	namelen -= AUFS_WH_PFX_LEN;
+	if (!au_nhash_test_known_wh(arg->whlist, name, namelen))
+		arg->err = au_nhash_append_wh
+			(arg->whlist, name, namelen, ino, d_type, arg->bindex,
+			 au_ftest_testempty(arg->flags, SHWH));
+
+out:
+	/* smp_mb(); */
+	AuTraceErr(arg->err);
+	return arg->err;
+}
+
+static int do_test_empty(struct dentry *dentry, struct test_empty_arg *arg)
+{
+	int err;
+	struct file *h_file;
+
+	h_file = au_h_open(dentry, arg->bindex,
+			   O_RDONLY | O_NONBLOCK | O_DIRECTORY | O_LARGEFILE,
+			   /*file*/NULL, /*force_wr*/0);
+	err = PTR_ERR(h_file);
+	if (IS_ERR(h_file))
+		goto out;
+
+	err = 0;
+	if (!au_opt_test(au_mntflags(dentry->d_sb), UDBA_NONE)
+	    && !file_inode(h_file)->i_nlink)
+		goto out_put;
+
+	do {
+		arg->err = 0;
+		au_fclr_testempty(arg->flags, CALLED);
+		/* smp_mb(); */
+		err = vfsub_iterate_dir(h_file, &arg->ctx);
+		if (err >= 0)
+			err = arg->err;
+	} while (!err && au_ftest_testempty(arg->flags, CALLED));
+
+out_put:
+	fput(h_file);
+	au_sbr_put(dentry->d_sb, arg->bindex);
+out:
+	return err;
+}
+
+struct do_test_empty_args {
+	int *errp;
+	struct dentry *dentry;
+	struct test_empty_arg *arg;
+};
+
+static void call_do_test_empty(void *args)
+{
+	struct do_test_empty_args *a = args;
+	*a->errp = do_test_empty(a->dentry, a->arg);
+}
+
+static int sio_test_empty(struct dentry *dentry, struct test_empty_arg *arg)
+{
+	int err, wkq_err;
+	struct dentry *h_dentry;
+	struct inode *h_inode;
+
+	h_dentry = au_h_dptr(dentry, arg->bindex);
+	h_inode = d_inode(h_dentry);
+	/* todo: i_mode changes anytime? */
+	mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD);
+	err = au_test_h_perm_sio(h_inode, MAY_EXEC | MAY_READ);
+	mutex_unlock(&h_inode->i_mutex);
+	if (!err)
+		err = do_test_empty(dentry, arg);
+	else {
+		struct do_test_empty_args args = {
+			.errp	= &err,
+			.dentry	= dentry,
+			.arg	= arg
+		};
+		unsigned int flags = arg->flags;
+
+		wkq_err = au_wkq_wait(call_do_test_empty, &args);
+		if (unlikely(wkq_err))
+			err = wkq_err;
+		arg->flags = flags;
+	}
+
+	return err;
+}
+
+int au_test_empty_lower(struct dentry *dentry)
+{
+	int err;
+	unsigned int rdhash;
+	aufs_bindex_t bindex, bstart, btail;
+	struct au_nhash whlist;
+	struct test_empty_arg arg = {
+		.ctx = {
+			.actor = test_empty_cb
+		}
+	};
+	int (*test_empty)(struct dentry *dentry, struct test_empty_arg *arg);
+
+	SiMustAnyLock(dentry->d_sb);
+
+	rdhash = au_sbi(dentry->d_sb)->si_rdhash;
+	if (!rdhash)
+		rdhash = au_rdhash_est(au_dir_size(/*file*/NULL, dentry));
+	err = au_nhash_alloc(&whlist, rdhash, GFP_NOFS);
+	if (unlikely(err))
+		goto out;
+
+	arg.flags = 0;
+	arg.whlist = &whlist;
+	bstart = au_dbstart(dentry);
+	if (au_opt_test(au_mntflags(dentry->d_sb), SHWH))
+		au_fset_testempty(arg.flags, SHWH);
+	test_empty = do_test_empty;
+	if (au_opt_test(au_mntflags(dentry->d_sb), DIRPERM1))
+		test_empty = sio_test_empty;
+	arg.bindex = bstart;
+	err = test_empty(dentry, &arg);
+	if (unlikely(err))
+		goto out_whlist;
+
+	au_fset_testempty(arg.flags, WHONLY);
+	btail = au_dbtaildir(dentry);
+	for (bindex = bstart + 1; !err && bindex <= btail; bindex++) {
+		struct dentry *h_dentry;
+
+		h_dentry = au_h_dptr(dentry, bindex);
+		if (h_dentry && d_is_positive(h_dentry)) {
+			arg.bindex = bindex;
+			err = test_empty(dentry, &arg);
+		}
+	}
+
+out_whlist:
+	au_nhash_wh_free(&whlist);
+out:
+	return err;
+}
+
+int au_test_empty(struct dentry *dentry, struct au_nhash *whlist)
+{
+	int err;
+	struct test_empty_arg arg = {
+		.ctx = {
+			.actor = test_empty_cb
+		}
+	};
+	aufs_bindex_t bindex, btail;
+
+	err = 0;
+	arg.whlist = whlist;
+	arg.flags = AuTestEmpty_WHONLY;
+	if (au_opt_test(au_mntflags(dentry->d_sb), SHWH))
+		au_fset_testempty(arg.flags, SHWH);
+	btail = au_dbtaildir(dentry);
+	for (bindex = au_dbstart(dentry); !err && bindex <= btail; bindex++) {
+		struct dentry *h_dentry;
+
+		h_dentry = au_h_dptr(dentry, bindex);
+		if (h_dentry && d_is_positive(h_dentry)) {
+			arg.bindex = bindex;
+			err = sio_test_empty(dentry, &arg);
+		}
+	}
+
+	return err;
+}
+
+/* ---------------------------------------------------------------------- */
+
+const struct file_operations aufs_dir_fop = {
+	.owner		= THIS_MODULE,
+	.llseek		= default_llseek,
+	.read		= generic_read_dir,
+	.iterate	= aufs_iterate,
+	.unlocked_ioctl	= aufs_ioctl_dir,
+#ifdef CONFIG_COMPAT
+	.compat_ioctl	= aufs_compat_ioctl_dir,
+#endif
+	.open		= aufs_open_dir,
+	.release	= aufs_release_dir,
+	.flush		= aufs_flush_dir,
+	.fsync		= aufs_fsync_dir
+};
--- /dev/null
+++ zfcpdump-kernel-4.4/fs/aufs/dir.h
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+ *
+ * This program, aufs is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * directory operations
+ */
+
+#ifndef __AUFS_DIR_H__
+#define __AUFS_DIR_H__
+
+#ifdef __KERNEL__
+
+#include <linux/fs.h>
+
+/* ---------------------------------------------------------------------- */
+
+/* need to be faster and smaller */
+
+struct au_nhash {
+	unsigned int		nh_num;
+	struct hlist_head	*nh_head;
+};
+
+struct au_vdir_destr {
+	unsigned char	len;
+	unsigned char	name[0];
+} __packed;
+
+struct au_vdir_dehstr {
+	struct hlist_node	hash;
+	struct au_vdir_destr	*str;
+} ____cacheline_aligned_in_smp;
+
+struct au_vdir_de {
+	ino_t			de_ino;
+	unsigned char		de_type;
+	/* caution: packed */
+	struct au_vdir_destr	de_str;
+} __packed;
+
+struct au_vdir_wh {
+	struct hlist_node	wh_hash;
+#ifdef CONFIG_AUFS_SHWH
+	ino_t			wh_ino;
+	aufs_bindex_t		wh_bindex;
+	unsigned char		wh_type;
+#else
+	aufs_bindex_t		wh_bindex;
+#endif
+	/* caution: packed */
+	struct au_vdir_destr	wh_str;
+} __packed;
+
+union au_vdir_deblk_p {
+	unsigned char		*deblk;
+	struct au_vdir_de	*de;
+};
+
+struct au_vdir {
+	unsigned char	**vd_deblk;
+	unsigned long	vd_nblk;
+	struct {
+		unsigned long		ul;
+		union au_vdir_deblk_p	p;
+	} vd_last;
+
+	unsigned long	vd_version;
+	unsigned int	vd_deblk_sz;
+	unsigned long	vd_jiffy;
+} ____cacheline_aligned_in_smp;
+
+/* ---------------------------------------------------------------------- */
+
+/* dir.c */
+extern const struct file_operations aufs_dir_fop;
+void au_add_nlink(struct inode *dir, struct inode *h_dir);
+void au_sub_nlink(struct inode *dir, struct inode *h_dir);
+loff_t au_dir_size(struct file *file, struct dentry *dentry);
+void au_dir_ts(struct inode *dir, aufs_bindex_t bsrc);
+int au_test_empty_lower(struct dentry *dentry);
+int au_test_empty(struct dentry *dentry, struct au_nhash *whlist);
+
+/* vdir.c */
+unsigned int au_rdhash_est(loff_t sz);
+int au_nhash_alloc(struct au_nhash *nhash, unsigned int num_hash, gfp_t gfp);
+void au_nhash_wh_free(struct au_nhash *whlist);
+int au_nhash_test_longer_wh(struct au_nhash *whlist, aufs_bindex_t btgt,
+			    int limit);
+int au_nhash_test_known_wh(struct au_nhash *whlist, char *name, int nlen);
+int au_nhash_append_wh(struct au_nhash *whlist, char *name, int nlen, ino_t ino,
+		       unsigned int d_type, aufs_bindex_t bindex,
+		       unsigned char shwh);
+void au_vdir_free(struct au_vdir *vdir);
+int au_vdir_init(struct file *file);
+int au_vdir_fill_de(struct file *file, struct dir_context *ctx);
+
+/* ioctl.c */
+long aufs_ioctl_dir(struct file *file, unsigned int cmd, unsigned long arg);
+
+#ifdef CONFIG_AUFS_RDU
+/* rdu.c */
+long au_rdu_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
+#ifdef CONFIG_COMPAT
+long au_rdu_compat_ioctl(struct file *file, unsigned int cmd,
+			 unsigned long arg);
+#endif
+#else
+AuStub(long, au_rdu_ioctl, return -EINVAL, struct file *file,
+       unsigned int cmd, unsigned long arg)
+#ifdef CONFIG_COMPAT
+AuStub(long, au_rdu_compat_ioctl, return -EINVAL, struct file *file,
+       unsigned int cmd, unsigned long arg)
+#endif
+#endif
+
+#endif /* __KERNEL__ */
+#endif /* __AUFS_DIR_H__ */
--- /dev/null
+++ zfcpdump-kernel-4.4/fs/aufs/dynop.c
@@ -0,0 +1,369 @@
+/*
+ * Copyright (C) 2010-2015 Junjiro R. Okajima
+ *
+ * This program, aufs is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * dynamically customizable operations for regular files
+ */
+
+#include "aufs.h"
+
+#define DyPrSym(key)	AuDbgSym(key->dk_op.dy_hop)
+
+/*
+ * How large will these lists be?
+ * Usually just a few elements, 20-30 at most for each, I guess.
+ */
+static struct au_splhead dynop[AuDyLast];
+
+static struct au_dykey *dy_gfind_get(struct au_splhead *spl, const void *h_op)
+{
+	struct au_dykey *key, *tmp;
+	struct list_head *head;
+
+	key = NULL;
+	head = &spl->head;
+	rcu_read_lock();
+	list_for_each_entry_rcu(tmp, head, dk_list)
+		if (tmp->dk_op.dy_hop == h_op) {
+			key = tmp;
+			kref_get(&key->dk_kref);
+			break;
+		}
+	rcu_read_unlock();
+
+	return key;
+}
+
+static struct au_dykey *dy_bradd(struct au_branch *br, struct au_dykey *key)
+{
+	struct au_dykey **k, *found;
+	const void *h_op = key->dk_op.dy_hop;
+	int i;
+
+	found = NULL;
+	k = br->br_dykey;
+	for (i = 0; i < AuBrDynOp; i++)
+		if (k[i]) {
+			if (k[i]->dk_op.dy_hop == h_op) {
+				found = k[i];
+				break;
+			}
+		} else
+			break;
+	if (!found) {
+		spin_lock(&br->br_dykey_lock);
+		for (; i < AuBrDynOp; i++)
+			if (k[i]) {
+				if (k[i]->dk_op.dy_hop == h_op) {
+					found = k[i];
+					break;
+				}
+			} else {
+				k[i] = key;
+				break;
+			}
+		spin_unlock(&br->br_dykey_lock);
+		BUG_ON(i == AuBrDynOp); /* expand the array */
+	}
+
+	return found;
+}
+
+/* kref_get() if @key is already added */
+static struct au_dykey *dy_gadd(struct au_splhead *spl, struct au_dykey *key)
+{
+	struct au_dykey *tmp, *found;
+	struct list_head *head;
+	const void *h_op = key->dk_op.dy_hop;
+
+	found = NULL;
+	head = &spl->head;
+	spin_lock(&spl->spin);
+	list_for_each_entry(tmp, head, dk_list)
+		if (tmp->dk_op.dy_hop == h_op) {
+			kref_get(&tmp->dk_kref);
+			found = tmp;
+			break;
+		}
+	if (!found)
+		list_add_rcu(&key->dk_list, head);
+	spin_unlock(&spl->spin);
+
+	if (!found)
+		DyPrSym(key);
+	return found;
+}
+
+static void dy_free_rcu(struct rcu_head *rcu)
+{
+	struct au_dykey *key;
+
+	key = container_of(rcu, struct au_dykey, dk_rcu);
+	DyPrSym(key);
+	kfree(key);
+}
+
+static void dy_free(struct kref *kref)
+{
+	struct au_dykey *key;
+	struct au_splhead *spl;
+
+	key = container_of(kref, struct au_dykey, dk_kref);
+	spl = dynop + key->dk_op.dy_type;
+	au_spl_del_rcu(&key->dk_list, spl);
+	call_rcu(&key->dk_rcu, dy_free_rcu);
+}
+
+void au_dy_put(struct au_dykey *key)
+{
+	kref_put(&key->dk_kref, dy_free);
+}
+
+/* ---------------------------------------------------------------------- */
+
+#define DyDbgSize(cnt, op)	AuDebugOn(cnt != sizeof(op)/sizeof(void *))
+
+#ifdef CONFIG_AUFS_DEBUG
+#define DyDbgDeclare(cnt)	unsigned int cnt = 0
+#define DyDbgInc(cnt)		do { cnt++; } while (0)
+#else
+#define DyDbgDeclare(cnt)	do {} while (0)
+#define DyDbgInc(cnt)		do {} while (0)
+#endif
+
+#define DySet(func, dst, src, h_op, h_sb) do {				\
+	DyDbgInc(cnt);							\
+	if (h_op->func) {						\
+		if (src.func)						\
+			dst.func = src.func;				\
+		else							\
+			AuDbg("%s %s\n", au_sbtype(h_sb), #func);	\
+	}								\
+} while (0)
+
+#define DySetForce(func, dst, src) do {		\
+	AuDebugOn(!src.func);			\
+	DyDbgInc(cnt);				\
+	dst.func = src.func;			\
+} while (0)
+
+#define DySetAop(func) \
+	DySet(func, dyaop->da_op, aufs_aop, h_aop, h_sb)
+#define DySetAopForce(func) \
+	DySetForce(func, dyaop->da_op, aufs_aop)
+
+static void dy_aop(struct au_dykey *key, const void *h_op,
+		   struct super_block *h_sb __maybe_unused)
+{
+	struct au_dyaop *dyaop = (void *)key;
+	const struct address_space_operations *h_aop = h_op;
+	DyDbgDeclare(cnt);
+
+	AuDbg("%s\n", au_sbtype(h_sb));
+
+	DySetAop(writepage);
+	DySetAopForce(readpage);	/* force */
+	DySetAop(writepages);
+	DySetAop(set_page_dirty);
+	DySetAop(readpages);
+	DySetAop(write_begin);
+	DySetAop(write_end);
+	DySetAop(bmap);
+	DySetAop(invalidatepage);
+	DySetAop(releasepage);
+	DySetAop(freepage);
+	/* this one will be changed according to an aufs mount option */
+	DySetAop(direct_IO);
+	DySetAop(migratepage);
+	DySetAop(launder_page);
+	DySetAop(is_partially_uptodate);
+	DySetAop(is_dirty_writeback);
+	DySetAop(error_remove_page);
+	DySetAop(swap_activate);
+	DySetAop(swap_deactivate);
+
+	DyDbgSize(cnt, *h_aop);
+}
+
+/* ---------------------------------------------------------------------- */
+
+static void dy_bug(struct kref *kref)
+{
+	BUG();
+}
+
+static struct au_dykey *dy_get(struct au_dynop *op, struct au_branch *br)
+{
+	struct au_dykey *key, *old;
+	struct au_splhead *spl;
+	struct op {
+		unsigned int sz;
+		void (*set)(struct au_dykey *key, const void *h_op,
+			    struct super_block *h_sb __maybe_unused);
+	};
+	static const struct op a[] = {
+		[AuDy_AOP] = {
+			.sz	= sizeof(struct au_dyaop),
+			.set	= dy_aop
+		}
+	};
+	const struct op *p;
+
+	spl = dynop + op->dy_type;
+	key = dy_gfind_get(spl, op->dy_hop);
+	if (key)
+		goto out_add; /* success */
+
+	p = a + op->dy_type;
+	key = kzalloc(p->sz, GFP_NOFS);
+	if (unlikely(!key)) {
+		key = ERR_PTR(-ENOMEM);
+		goto out;
+	}
+
+	key->dk_op.dy_hop = op->dy_hop;
+	kref_init(&key->dk_kref);
+	p->set(key, op->dy_hop, au_br_sb(br));
+	old = dy_gadd(spl, key);
+	if (old) {
+		kfree(key);
+		key = old;
+	}
+
+out_add:
+	old = dy_bradd(br, key);
+	if (old)
+		/* its ref-count should never be zero here */
+		kref_put(&key->dk_kref, dy_bug);
+out:
+	return key;
+}
+
+/* ---------------------------------------------------------------------- */
+/*
+ * Aufs prohibits O_DIRECT by defaut even if the branch supports it.
+ * This behaviour is necessary to return an error from open(O_DIRECT) instead
+ * of the succeeding I/O. The dio mount option enables O_DIRECT and makes
+ * open(O_DIRECT) always succeed, but the succeeding I/O may return an error.
+ * See the aufs manual in detail.
+ */
+static void dy_adx(struct au_dyaop *dyaop, int do_dx)
+{
+	if (!do_dx)
+		dyaop->da_op.direct_IO = NULL;
+	else
+		dyaop->da_op.direct_IO = aufs_aop.direct_IO;
+}
+
+static struct au_dyaop *dy_aget(struct au_branch *br,
+				const struct address_space_operations *h_aop,
+				int do_dx)
+{
+	struct au_dyaop *dyaop;
+	struct au_dynop op;
+
+	op.dy_type = AuDy_AOP;
+	op.dy_haop = h_aop;
+	dyaop = (void *)dy_get(&op, br);
+	if (IS_ERR(dyaop))
+		goto out;
+	dy_adx(dyaop, do_dx);
+
+out:
+	return dyaop;
+}
+
+int au_dy_iaop(struct inode *inode, aufs_bindex_t bindex,
+		struct inode *h_inode)
+{
+	int err, do_dx;
+	struct super_block *sb;
+	struct au_branch *br;
+	struct au_dyaop *dyaop;
+
+	AuDebugOn(!S_ISREG(h_inode->i_mode));
+	IiMustWriteLock(inode);
+
+	sb = inode->i_sb;
+	br = au_sbr(sb, bindex);
+	do_dx = !!au_opt_test(au_mntflags(sb), DIO);
+	dyaop = dy_aget(br, h_inode->i_mapping->a_ops, do_dx);
+	err = PTR_ERR(dyaop);
+	if (IS_ERR(dyaop))
+		/* unnecessary to call dy_fput() */
+		goto out;
+
+	err = 0;
+	inode->i_mapping->a_ops = &dyaop->da_op;
+
+out:
+	return err;
+}
+
+/*
+ * Is it safe to replace a_ops during the inode/file is in operation?
+ * Yes, I hope so.
+ */
+int au_dy_irefresh(struct inode *inode)
+{
+	int err;
+	aufs_bindex_t bstart;
+	struct inode *h_inode;
+
+	err = 0;
+	if (S_ISREG(inode->i_mode)) {
+		bstart = au_ibstart(inode);
+		h_inode = au_h_iptr(inode, bstart);
+		err = au_dy_iaop(inode, bstart, h_inode);
+	}
+	return err;
+}
+
+void au_dy_arefresh(int do_dx)
+{
+	struct au_splhead *spl;
+	struct list_head *head;
+	struct au_dykey *key;
+
+	spl = dynop + AuDy_AOP;
+	head = &spl->head;
+	spin_lock(&spl->spin);
+	list_for_each_entry(key, head, dk_list)
+		dy_adx((void *)key, do_dx);
+	spin_unlock(&spl->spin);
+}
+
+/* ---------------------------------------------------------------------- */
+
+void __init au_dy_init(void)
+{
+	int i;
+
+	/* make sure that 'struct au_dykey *' can be any type */
+	BUILD_BUG_ON(offsetof(struct au_dyaop, da_key));
+
+	for (i = 0; i < AuDyLast; i++)
+		au_spl_init(dynop + i);
+}
+
+void au_dy_fin(void)
+{
+	int i;
+
+	for (i = 0; i < AuDyLast; i++)
+		WARN_ON(!list_empty(&dynop[i].head));
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/fs/aufs/dynop.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2010-2015 Junjiro R. Okajima
+ *
+ * This program, aufs is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * dynamically customizable operations (for regular files only)
+ */
+
+#ifndef __AUFS_DYNOP_H__
+#define __AUFS_DYNOP_H__
+
+#ifdef __KERNEL__
+
+#include <linux/fs.h>
+#include <linux/kref.h>
+
+enum {AuDy_AOP, AuDyLast};
+
+struct au_dynop {
+	int						dy_type;
+	union {
+		const void				*dy_hop;
+		const struct address_space_operations	*dy_haop;
+	};
+};
+
+struct au_dykey {
+	union {
+		struct list_head	dk_list;
+		struct rcu_head		dk_rcu;
+	};
+	struct au_dynop		dk_op;
+
+	/*
+	 * during I am in the branch local array, kref is gotten. when the
+	 * branch is removed, kref is put.
+	 */
+	struct kref		dk_kref;
+};
+
+/* stop unioning since their sizes are very different from each other */
+struct au_dyaop {
+	struct au_dykey			da_key;
+	struct address_space_operations	da_op; /* not const */
+};
+
+/* ---------------------------------------------------------------------- */
+
+/* dynop.c */
+struct au_branch;
+void au_dy_put(struct au_dykey *key);
+int au_dy_iaop(struct inode *inode, aufs_bindex_t bindex,
+		struct inode *h_inode);
+int au_dy_irefresh(struct inode *inode);
+void au_dy_arefresh(int do_dio);
+
+void __init au_dy_init(void);
+void au_dy_fin(void);
+
+#endif /* __KERNEL__ */
+#endif /* __AUFS_DYNOP_H__ */
--- /dev/null
+++ zfcpdump-kernel-4.4/fs/aufs/export.c
@@ -0,0 +1,832 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+ *
+ * This program, aufs is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * export via nfs
+ */
+
+#include <linux/exportfs.h>
+#include <linux/fs_struct.h>
+#include <linux/namei.h>
+#include <linux/nsproxy.h>
+#include <linux/random.h>
+#include <linux/writeback.h>
+#include "../fs/mount.h"
+#include "aufs.h"
+
+union conv {
+#ifdef CONFIG_AUFS_INO_T_64
+	__u32 a[2];
+#else
+	__u32 a[1];
+#endif
+	ino_t ino;
+};
+
+static ino_t decode_ino(__u32 *a)
+{
+	union conv u;
+
+	BUILD_BUG_ON(sizeof(u.ino) != sizeof(u.a));
+	u.a[0] = a[0];
+#ifdef CONFIG_AUFS_INO_T_64
+	u.a[1] = a[1];
+#endif
+	return u.ino;
+}
+
+static void encode_ino(__u32 *a, ino_t ino)
+{
+	union conv u;
+
+	u.ino = ino;
+	a[0] = u.a[0];
+#ifdef CONFIG_AUFS_INO_T_64
+	a[1] = u.a[1];
+#endif
+}
+
+/* NFS file handle */
+enum {
+	Fh_br_id,
+	Fh_sigen,
+#ifdef CONFIG_AUFS_INO_T_64
+	/* support 64bit inode number */
+	Fh_ino1,
+	Fh_ino2,
+	Fh_dir_ino1,
+	Fh_dir_ino2,
+#else
+	Fh_ino1,
+	Fh_dir_ino1,
+#endif
+	Fh_igen,
+	Fh_h_type,
+	Fh_tail,
+
+	Fh_ino = Fh_ino1,
+	Fh_dir_ino = Fh_dir_ino1
+};
+
+static int au_test_anon(struct dentry *dentry)
+{
+	/* note: read d_flags without d_lock */
+	return !!(dentry->d_flags & DCACHE_DISCONNECTED);
+}
+
+int au_test_nfsd(void)
+{
+	int ret;
+	struct task_struct *tsk = current;
+	char comm[sizeof(tsk->comm)];
+
+	ret = 0;
+	if (tsk->flags & PF_KTHREAD) {
+		get_task_comm(comm, tsk);
+		ret = !strcmp(comm, "nfsd");
+	}
+
+	return ret;
+}
+
+/* ---------------------------------------------------------------------- */
+/* inode generation external table */
+
+void au_xigen_inc(struct inode *inode)
+{
+	loff_t pos;
+	ssize_t sz;
+	__u32 igen;
+	struct super_block *sb;
+	struct au_sbinfo *sbinfo;
+
+	sb = inode->i_sb;
+	AuDebugOn(!au_opt_test(au_mntflags(sb), XINO));
+
+	sbinfo = au_sbi(sb);
+	pos = inode->i_ino;
+	pos *= sizeof(igen);
+	igen = inode->i_generation + 1;
+	sz = xino_fwrite(sbinfo->si_xwrite, sbinfo->si_xigen, &igen,
+			 sizeof(igen), &pos);
+	if (sz == sizeof(igen))
+		return; /* success */
+
+	if (unlikely(sz >= 0))
+		AuIOErr("xigen error (%zd)\n", sz);
+}
+
+int au_xigen_new(struct inode *inode)
+{
+	int err;
+	loff_t pos;
+	ssize_t sz;
+	struct super_block *sb;
+	struct au_sbinfo *sbinfo;
+	struct file *file;
+
+	err = 0;
+	/* todo: dirty, at mount time */
+	if (inode->i_ino == AUFS_ROOT_INO)
+		goto out;
+	sb = inode->i_sb;
+	SiMustAnyLock(sb);
+	if (unlikely(!au_opt_test(au_mntflags(sb), XINO)))
+		goto out;
+
+	err = -EFBIG;
+	pos = inode->i_ino;
+	if (unlikely(au_loff_max / sizeof(inode->i_generation) - 1 < pos)) {
+		AuIOErr1("too large i%lld\n", pos);
+		goto out;
+	}
+	pos *= sizeof(inode->i_generation);
+
+	err = 0;
+	sbinfo = au_sbi(sb);
+	file = sbinfo->si_xigen;
+	BUG_ON(!file);
+
+	if (vfsub_f_size_read(file)
+	    < pos + sizeof(inode->i_generation)) {
+		inode->i_generation = atomic_inc_return(&sbinfo->si_xigen_next);
+		sz = xino_fwrite(sbinfo->si_xwrite, file, &inode->i_generation,
+				 sizeof(inode->i_generation), &pos);
+	} else
+		sz = xino_fread(sbinfo->si_xread, file, &inode->i_generation,
+				sizeof(inode->i_generation), &pos);
+	if (sz == sizeof(inode->i_generation))
+		goto out; /* success */
+
+	err = sz;
+	if (unlikely(sz >= 0)) {
+		err = -EIO;
+		AuIOErr("xigen error (%zd)\n", sz);
+	}
+
+out:
+	return err;
+}
+
+int au_xigen_set(struct super_block *sb, struct file *base)
+{
+	int err;
+	struct au_sbinfo *sbinfo;
+	struct file *file;
+
+	SiMustWriteLock(sb);
+
+	sbinfo = au_sbi(sb);
+	file = au_xino_create2(base, sbinfo->si_xigen);
+	err = PTR_ERR(file);
+	if (IS_ERR(file))
+		goto out;
+	err = 0;
+	if (sbinfo->si_xigen)
+		fput(sbinfo->si_xigen);
+	sbinfo->si_xigen = file;
+
+out:
+	return err;
+}
+
+void au_xigen_clr(struct super_block *sb)
+{
+	struct au_sbinfo *sbinfo;
+
+	SiMustWriteLock(sb);
+
+	sbinfo = au_sbi(sb);
+	if (sbinfo->si_xigen) {
+		fput(sbinfo->si_xigen);
+		sbinfo->si_xigen = NULL;
+	}
+}
+
+/* ---------------------------------------------------------------------- */
+
+static struct dentry *decode_by_ino(struct super_block *sb, ino_t ino,
+				    ino_t dir_ino)
+{
+	struct dentry *dentry, *d;
+	struct inode *inode;
+	unsigned int sigen;
+
+	dentry = NULL;
+	inode = ilookup(sb, ino);
+	if (!inode)
+		goto out;
+
+	dentry = ERR_PTR(-ESTALE);
+	sigen = au_sigen(sb);
+	if (unlikely(is_bad_inode(inode)
+		     || IS_DEADDIR(inode)
+		     || sigen != au_iigen(inode, NULL)))
+		goto out_iput;
+
+	dentry = NULL;
+	if (!dir_ino || S_ISDIR(inode->i_mode))
+		dentry = d_find_alias(inode);
+	else {
+		spin_lock(&inode->i_lock);
+		hlist_for_each_entry(d, &inode->i_dentry, d_u.d_alias) {
+			spin_lock(&d->d_lock);
+			if (!au_test_anon(d)
+			    && d_inode(d->d_parent)->i_ino == dir_ino) {
+				dentry = dget_dlock(d);
+				spin_unlock(&d->d_lock);
+				break;
+			}
+			spin_unlock(&d->d_lock);
+		}
+		spin_unlock(&inode->i_lock);
+	}
+	if (unlikely(dentry && au_digen_test(dentry, sigen))) {
+		/* need to refresh */
+		dput(dentry);
+		dentry = NULL;
+	}
+
+out_iput:
+	iput(inode);
+out:
+	AuTraceErrPtr(dentry);
+	return dentry;
+}
+
+/* ---------------------------------------------------------------------- */
+
+/* todo: dirty? */
+/* if exportfs_decode_fh() passed vfsmount*, we could be happy */
+
+struct au_compare_mnt_args {
+	/* input */
+	struct super_block *sb;
+
+	/* output */
+	struct vfsmount *mnt;
+};
+
+static int au_compare_mnt(struct vfsmount *mnt, void *arg)
+{
+	struct au_compare_mnt_args *a = arg;
+
+	if (mnt->mnt_sb != a->sb)
+		return 0;
+	a->mnt = mntget(mnt);
+	return 1;
+}
+
+static struct vfsmount *au_mnt_get(struct super_block *sb)
+{
+	int err;
+	struct path root;
+	struct au_compare_mnt_args args = {
+		.sb = sb
+	};
+
+	get_fs_root(current->fs, &root);
+	rcu_read_lock();
+	err = iterate_mounts(au_compare_mnt, &args, root.mnt);
+	rcu_read_unlock();
+	path_put(&root);
+	AuDebugOn(!err);
+	AuDebugOn(!args.mnt);
+	return args.mnt;
+}
+
+struct au_nfsd_si_lock {
+	unsigned int sigen;
+	aufs_bindex_t bindex, br_id;
+	unsigned char force_lock;
+};
+
+static int si_nfsd_read_lock(struct super_block *sb,
+			     struct au_nfsd_si_lock *nsi_lock)
+{
+	int err;
+	aufs_bindex_t bindex;
+
+	si_read_lock(sb, AuLock_FLUSH);
+
+	/* branch id may be wrapped around */
+	err = 0;
+	bindex = au_br_index(sb, nsi_lock->br_id);
+	if (bindex >= 0 && nsi_lock->sigen + AUFS_BRANCH_MAX > au_sigen(sb))
+		goto out; /* success */
+
+	err = -ESTALE;
+	bindex = -1;
+	if (!nsi_lock->force_lock)
+		si_read_unlock(sb);
+
+out:
+	nsi_lock->bindex = bindex;
+	return err;
+}
+
+struct find_name_by_ino {
+	struct dir_context ctx;
+	int called, found;
+	ino_t ino;
+	char *name;
+	int namelen;
+};
+
+static int
+find_name_by_ino(struct dir_context *ctx, const char *name, int namelen,
+		 loff_t offset, u64 ino, unsigned int d_type)
+{
+	struct find_name_by_ino *a = container_of(ctx, struct find_name_by_ino,
+						  ctx);
+
+	a->called++;
+	if (a->ino != ino)
+		return 0;
+
+	memcpy(a->name, name, namelen);
+	a->namelen = namelen;
+	a->found = 1;
+	return 1;
+}
+
+static struct dentry *au_lkup_by_ino(struct path *path, ino_t ino,
+				     struct au_nfsd_si_lock *nsi_lock)
+{
+	struct dentry *dentry, *parent;
+	struct file *file;
+	struct inode *dir;
+	struct find_name_by_ino arg = {
+		.ctx = {
+			.actor = find_name_by_ino
+		}
+	};
+	int err;
+
+	parent = path->dentry;
+	if (nsi_lock)
+		si_read_unlock(parent->d_sb);
+	file = vfsub_dentry_open(path, au_dir_roflags);
+	dentry = (void *)file;
+	if (IS_ERR(file))
+		goto out;
+
+	dentry = ERR_PTR(-ENOMEM);
+	arg.name = (void *)__get_free_page(GFP_NOFS);
+	if (unlikely(!arg.name))
+		goto out_file;
+	arg.ino = ino;
+	arg.found = 0;
+	do {
+		arg.called = 0;
+		/* smp_mb(); */
+		err = vfsub_iterate_dir(file, &arg.ctx);
+	} while (!err && !arg.found && arg.called);
+	dentry = ERR_PTR(err);
+	if (unlikely(err))
+		goto out_name;
+	/* instead of ENOENT */
+	dentry = ERR_PTR(-ESTALE);
+	if (!arg.found)
+		goto out_name;
+
+	/* do not call vfsub_lkup_one() */
+	dir = d_inode(parent);
+	mutex_lock(&dir->i_mutex);
+	dentry = vfsub_lookup_one_len(arg.name, parent, arg.namelen);
+	mutex_unlock(&dir->i_mutex);
+	AuTraceErrPtr(dentry);
+	if (IS_ERR(dentry))
+		goto out_name;
+	AuDebugOn(au_test_anon(dentry));
+	if (unlikely(d_really_is_negative(dentry))) {
+		dput(dentry);
+		dentry = ERR_PTR(-ENOENT);
+	}
+
+out_name:
+	free_page((unsigned long)arg.name);
+out_file:
+	fput(file);
+out:
+	if (unlikely(nsi_lock
+		     && si_nfsd_read_lock(parent->d_sb, nsi_lock) < 0))
+		if (!IS_ERR(dentry)) {
+			dput(dentry);
+			dentry = ERR_PTR(-ESTALE);
+		}
+	AuTraceErrPtr(dentry);
+	return dentry;
+}
+
+static struct dentry *decode_by_dir_ino(struct super_block *sb, ino_t ino,
+					ino_t dir_ino,
+					struct au_nfsd_si_lock *nsi_lock)
+{
+	struct dentry *dentry;
+	struct path path;
+
+	if (dir_ino != AUFS_ROOT_INO) {
+		path.dentry = decode_by_ino(sb, dir_ino, 0);
+		dentry = path.dentry;
+		if (!path.dentry || IS_ERR(path.dentry))
+			goto out;
+		AuDebugOn(au_test_anon(path.dentry));
+	} else
+		path.dentry = dget(sb->s_root);
+
+	path.mnt = au_mnt_get(sb);
+	dentry = au_lkup_by_ino(&path, ino, nsi_lock);
+	path_put(&path);
+
+out:
+	AuTraceErrPtr(dentry);
+	return dentry;
+}
+
+/* ---------------------------------------------------------------------- */
+
+static int h_acceptable(void *expv, struct dentry *dentry)
+{
+	return 1;
+}
+
+static char *au_build_path(struct dentry *h_parent, struct path *h_rootpath,
+			   char *buf, int len, struct super_block *sb)
+{
+	char *p;
+	int n;
+	struct path path;
+
+	p = d_path(h_rootpath, buf, len);
+	if (IS_ERR(p))
+		goto out;
+	n = strlen(p);
+
+	path.mnt = h_rootpath->mnt;
+	path.dentry = h_parent;
+	p = d_path(&path, buf, len);
+	if (IS_ERR(p))
+		goto out;
+	if (n != 1)
+		p += n;
+
+	path.mnt = au_mnt_get(sb);
+	path.dentry = sb->s_root;
+	p = d_path(&path, buf, len - strlen(p));
+	mntput(path.mnt);
+	if (IS_ERR(p))
+		goto out;
+	if (n != 1)
+		p[strlen(p)] = '/';
+
+out:
+	AuTraceErrPtr(p);
+	return p;
+}
+
+static
+struct dentry *decode_by_path(struct super_block *sb, ino_t ino, __u32 *fh,
+			      int fh_len, struct au_nfsd_si_lock *nsi_lock)
+{
+	struct dentry *dentry, *h_parent, *root;
+	struct super_block *h_sb;
+	char *pathname, *p;
+	struct vfsmount *h_mnt;
+	struct au_branch *br;
+	int err;
+	struct path path;
+
+	br = au_sbr(sb, nsi_lock->bindex);
+	h_mnt = au_br_mnt(br);
+	h_sb = h_mnt->mnt_sb;
+	/* todo: call lower fh_to_dentry()? fh_to_parent()? */
+	h_parent = exportfs_decode_fh(h_mnt, (void *)(fh + Fh_tail),
+				      fh_len - Fh_tail, fh[Fh_h_type],
+				      h_acceptable, /*context*/NULL);
+	dentry = h_parent;
+	if (unlikely(!h_parent || IS_ERR(h_parent))) {
+		AuWarn1("%s decode_fh failed, %ld\n",
+			au_sbtype(h_sb), PTR_ERR(h_parent));
+		goto out;
+	}
+	dentry = NULL;
+	if (unlikely(au_test_anon(h_parent))) {
+		AuWarn1("%s decode_fh returned a disconnected dentry\n",
+			au_sbtype(h_sb));
+		goto out_h_parent;
+	}
+
+	dentry = ERR_PTR(-ENOMEM);
+	pathname = (void *)__get_free_page(GFP_NOFS);
+	if (unlikely(!pathname))
+		goto out_h_parent;
+
+	root = sb->s_root;
+	path.mnt = h_mnt;
+	di_read_lock_parent(root, !AuLock_IR);
+	path.dentry = au_h_dptr(root, nsi_lock->bindex);
+	di_read_unlock(root, !AuLock_IR);
+	p = au_build_path(h_parent, &path, pathname, PAGE_SIZE, sb);
+	dentry = (void *)p;
+	if (IS_ERR(p))
+		goto out_pathname;
+
+	si_read_unlock(sb);
+	err = vfsub_kern_path(p, LOOKUP_FOLLOW | LOOKUP_DIRECTORY, &path);
+	dentry = ERR_PTR(err);
+	if (unlikely(err))
+		goto out_relock;
+
+	dentry = ERR_PTR(-ENOENT);
+	AuDebugOn(au_test_anon(path.dentry));
+	if (unlikely(d_really_is_negative(path.dentry)))
+		goto out_path;
+
+	if (ino != d_inode(path.dentry)->i_ino)
+		dentry = au_lkup_by_ino(&path, ino, /*nsi_lock*/NULL);
+	else
+		dentry = dget(path.dentry);
+
+out_path:
+	path_put(&path);
+out_relock:
+	if (unlikely(si_nfsd_read_lock(sb, nsi_lock) < 0))
+		if (!IS_ERR(dentry)) {
+			dput(dentry);
+			dentry = ERR_PTR(-ESTALE);
+		}
+out_pathname:
+	free_page((unsigned long)pathname);
+out_h_parent:
+	dput(h_parent);
+out:
+	AuTraceErrPtr(dentry);
+	return dentry;
+}
+
+/* ---------------------------------------------------------------------- */
+
+static struct dentry *
+aufs_fh_to_dentry(struct super_block *sb, struct fid *fid, int fh_len,
+		  int fh_type)
+{
+	struct dentry *dentry;
+	__u32 *fh = fid->raw;
+	struct au_branch *br;
+	ino_t ino, dir_ino;
+	struct au_nfsd_si_lock nsi_lock = {
+		.force_lock	= 0
+	};
+
+	dentry = ERR_PTR(-ESTALE);
+	/* it should never happen, but the file handle is unreliable */
+	if (unlikely(fh_len < Fh_tail))
+		goto out;
+	nsi_lock.sigen = fh[Fh_sigen];
+	nsi_lock.br_id = fh[Fh_br_id];
+
+	/* branch id may be wrapped around */
+	br = NULL;
+	if (unlikely(si_nfsd_read_lock(sb, &nsi_lock)))
+		goto out;
+	nsi_lock.force_lock = 1;
+
+	/* is this inode still cached? */
+	ino = decode_ino(fh + Fh_ino);
+	/* it should never happen */
+	if (unlikely(ino == AUFS_ROOT_INO))
+		goto out;
+
+	dir_ino = decode_ino(fh + Fh_dir_ino);
+	dentry = decode_by_ino(sb, ino, dir_ino);
+	if (IS_ERR(dentry))
+		goto out_unlock;
+	if (dentry)
+		goto accept;
+
+	/* is the parent dir cached? */
+	br = au_sbr(sb, nsi_lock.bindex);
+	atomic_inc(&br->br_count);
+	dentry = decode_by_dir_ino(sb, ino, dir_ino, &nsi_lock);
+	if (IS_ERR(dentry))
+		goto out_unlock;
+	if (dentry)
+		goto accept;
+
+	/* lookup path */
+	dentry = decode_by_path(sb, ino, fh, fh_len, &nsi_lock);
+	if (IS_ERR(dentry))
+		goto out_unlock;
+	if (unlikely(!dentry))
+		/* todo?: make it ESTALE */
+		goto out_unlock;
+
+accept:
+	if (!au_digen_test(dentry, au_sigen(sb))
+	    && d_inode(dentry)->i_generation == fh[Fh_igen])
+		goto out_unlock; /* success */
+
+	dput(dentry);
+	dentry = ERR_PTR(-ESTALE);
+out_unlock:
+	if (br)
+		atomic_dec(&br->br_count);
+	si_read_unlock(sb);
+out:
+	AuTraceErrPtr(dentry);
+	return dentry;
+}
+
+#if 0 /* reserved for future use */
+/* support subtreecheck option */
+static struct dentry *aufs_fh_to_parent(struct super_block *sb, struct fid *fid,
+					int fh_len, int fh_type)
+{
+	struct dentry *parent;
+	__u32 *fh = fid->raw;
+	ino_t dir_ino;
+
+	dir_ino = decode_ino(fh + Fh_dir_ino);
+	parent = decode_by_ino(sb, dir_ino, 0);
+	if (IS_ERR(parent))
+		goto out;
+	if (!parent)
+		parent = decode_by_path(sb, au_br_index(sb, fh[Fh_br_id]),
+					dir_ino, fh, fh_len);
+
+out:
+	AuTraceErrPtr(parent);
+	return parent;
+}
+#endif
+
+/* ---------------------------------------------------------------------- */
+
+static int aufs_encode_fh(struct inode *inode, __u32 *fh, int *max_len,
+			  struct inode *dir)
+{
+	int err;
+	aufs_bindex_t bindex;
+	struct super_block *sb, *h_sb;
+	struct dentry *dentry, *parent, *h_parent;
+	struct inode *h_dir;
+	struct au_branch *br;
+
+	err = -ENOSPC;
+	if (unlikely(*max_len <= Fh_tail)) {
+		AuWarn1("NFSv2 client (max_len %d)?\n", *max_len);
+		goto out;
+	}
+
+	err = FILEID_ROOT;
+	if (inode->i_ino == AUFS_ROOT_INO) {
+		AuDebugOn(inode->i_ino != AUFS_ROOT_INO);
+		goto out;
+	}
+
+	h_parent = NULL;
+	sb = inode->i_sb;
+	err = si_read_lock(sb, AuLock_FLUSH);
+	if (unlikely(err))
+		goto out;
+
+#ifdef CONFIG_AUFS_DEBUG
+	if (unlikely(!au_opt_test(au_mntflags(sb), XINO)))
+		AuWarn1("NFS-exporting requires xino\n");
+#endif
+	err = -EIO;
+	parent = NULL;
+	ii_read_lock_child(inode);
+	bindex = au_ibstart(inode);
+	if (!dir) {
+		dentry = d_find_any_alias(inode);
+		if (unlikely(!dentry))
+			goto out_unlock;
+		AuDebugOn(au_test_anon(dentry));
+		parent = dget_parent(dentry);
+		dput(dentry);
+		if (unlikely(!parent))
+			goto out_unlock;
+		if (d_really_is_positive(parent))
+			dir = d_inode(parent);
+	}
+
+	ii_read_lock_parent(dir);
+	h_dir = au_h_iptr(dir, bindex);
+	ii_read_unlock(dir);
+	if (unlikely(!h_dir))
+		goto out_parent;
+	h_parent = d_find_any_alias(h_dir);
+	if (unlikely(!h_parent))
+		goto out_hparent;
+
+	err = -EPERM;
+	br = au_sbr(sb, bindex);
+	h_sb = au_br_sb(br);
+	if (unlikely(!h_sb->s_export_op)) {
+		AuErr1("%s branch is not exportable\n", au_sbtype(h_sb));
+		goto out_hparent;
+	}
+
+	fh[Fh_br_id] = br->br_id;
+	fh[Fh_sigen] = au_sigen(sb);
+	encode_ino(fh + Fh_ino, inode->i_ino);
+	encode_ino(fh + Fh_dir_ino, dir->i_ino);
+	fh[Fh_igen] = inode->i_generation;
+
+	*max_len -= Fh_tail;
+	fh[Fh_h_type] = exportfs_encode_fh(h_parent, (void *)(fh + Fh_tail),
+					   max_len,
+					   /*connectable or subtreecheck*/0);
+	err = fh[Fh_h_type];
+	*max_len += Fh_tail;
+	/* todo: macros? */
+	if (err != FILEID_INVALID)
+		err = 99;
+	else
+		AuWarn1("%s encode_fh failed\n", au_sbtype(h_sb));
+
+out_hparent:
+	dput(h_parent);
+out_parent:
+	dput(parent);
+out_unlock:
+	ii_read_unlock(inode);
+	si_read_unlock(sb);
+out:
+	if (unlikely(err < 0))
+		err = FILEID_INVALID;
+	return err;
+}
+
+/* ---------------------------------------------------------------------- */
+
+static int aufs_commit_metadata(struct inode *inode)
+{
+	int err;
+	aufs_bindex_t bindex;
+	struct super_block *sb;
+	struct inode *h_inode;
+	int (*f)(struct inode *inode);
+
+	sb = inode->i_sb;
+	si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW);
+	ii_write_lock_child(inode);
+	bindex = au_ibstart(inode);
+	AuDebugOn(bindex < 0);
+	h_inode = au_h_iptr(inode, bindex);
+
+	f = h_inode->i_sb->s_export_op->commit_metadata;
+	if (f)
+		err = f(h_inode);
+	else {
+		struct writeback_control wbc = {
+			.sync_mode	= WB_SYNC_ALL,
+			.nr_to_write	= 0 /* metadata only */
+		};
+
+		err = sync_inode(h_inode, &wbc);
+	}
+
+	au_cpup_attr_timesizes(inode);
+	ii_write_unlock(inode);
+	si_read_unlock(sb);
+	return err;
+}
+
+/* ---------------------------------------------------------------------- */
+
+static struct export_operations aufs_export_op = {
+	.fh_to_dentry		= aufs_fh_to_dentry,
+	/* .fh_to_parent	= aufs_fh_to_parent, */
+	.encode_fh		= aufs_encode_fh,
+	.commit_metadata	= aufs_commit_metadata
+};
+
+void au_export_init(struct super_block *sb)
+{
+	struct au_sbinfo *sbinfo;
+	__u32 u;
+
+	sb->s_export_op = &aufs_export_op;
+	sbinfo = au_sbi(sb);
+	sbinfo->si_xigen = NULL;
+	get_random_bytes(&u, sizeof(u));
+	BUILD_BUG_ON(sizeof(u) != sizeof(int));
+	atomic_set(&sbinfo->si_xigen_next, u);
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/fs/aufs/f_op.c
@@ -0,0 +1,738 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+ *
+ * This program, aufs is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * file and vm operations
+ */
+
+#include <linux/aio.h>
+#include <linux/fs_stack.h>
+#include <linux/mman.h>
+#include <linux/security.h>
+#include "aufs.h"
+
+int au_do_open_nondir(struct file *file, int flags, struct file *h_file)
+{
+	int err;
+	aufs_bindex_t bindex;
+	struct dentry *dentry;
+	struct au_finfo *finfo;
+	struct inode *h_inode;
+
+	FiMustWriteLock(file);
+
+	err = 0;
+	dentry = file->f_path.dentry;
+	AuDebugOn(IS_ERR_OR_NULL(dentry));
+	finfo = au_fi(file);
+	memset(&finfo->fi_htop, 0, sizeof(finfo->fi_htop));
+	atomic_set(&finfo->fi_mmapped, 0);
+	bindex = au_dbstart(dentry);
+	if (!h_file)
+		h_file = au_h_open(dentry, bindex, flags, file, /*force_wr*/0);
+	else
+		get_file(h_file);
+	if (IS_ERR(h_file))
+		err = PTR_ERR(h_file);
+	else {
+		if ((flags & __O_TMPFILE)
+		    && !(flags & O_EXCL)) {
+			h_inode = file_inode(h_file);
+			spin_lock(&h_inode->i_lock);
+			h_inode->i_state |= I_LINKABLE;
+			spin_unlock(&h_inode->i_lock);
+		}
+		au_set_fbstart(file, bindex);
+		au_set_h_fptr(file, bindex, h_file);
+		au_update_figen(file);
+		/* todo: necessary? */
+		/* file->f_ra = h_file->f_ra; */
+	}
+
+	return err;
+}
+
+static int aufs_open_nondir(struct inode *inode __maybe_unused,
+			    struct file *file)
+{
+	int err;
+	struct super_block *sb;
+	struct au_do_open_args args = {
+		.open	= au_do_open_nondir
+	};
+
+	AuDbg("%pD, f_flags 0x%x, f_mode 0x%x\n",
+	      file, vfsub_file_flags(file), file->f_mode);
+
+	sb = file->f_path.dentry->d_sb;
+	si_read_lock(sb, AuLock_FLUSH);
+	err = au_do_open(file, &args);
+	si_read_unlock(sb);
+	return err;
+}
+
+int aufs_release_nondir(struct inode *inode __maybe_unused, struct file *file)
+{
+	struct au_finfo *finfo;
+	aufs_bindex_t bindex;
+
+	finfo = au_fi(file);
+	au_sphl_del(&finfo->fi_hlist,
+		    &au_sbi(file->f_path.dentry->d_sb)->si_files);
+	bindex = finfo->fi_btop;
+	if (bindex >= 0)
+		au_set_h_fptr(file, bindex, NULL);
+
+	au_finfo_fin(file);
+	return 0;
+}
+
+/* ---------------------------------------------------------------------- */
+
+static int au_do_flush_nondir(struct file *file, fl_owner_t id)
+{
+	int err;
+	struct file *h_file;
+
+	err = 0;
+	h_file = au_hf_top(file);
+	if (h_file)
+		err = vfsub_flush(h_file, id);
+	return err;
+}
+
+static int aufs_flush_nondir(struct file *file, fl_owner_t id)
+{
+	return au_do_flush(file, id, au_do_flush_nondir);
+}
+
+/* ---------------------------------------------------------------------- */
+/*
+ * read and write functions acquire [fdi]_rwsem once, but release before
+ * mmap_sem. This is because to stop a race condition between mmap(2).
+ * Releasing these aufs-rwsem should be safe, no branch-mamagement (by keeping
+ * si_rwsem), no harmful copy-up should happen. Actually copy-up may happen in
+ * read functions after [fdi]_rwsem are released, but it should be harmless.
+ */
+
+/* Callers should call au_read_post() or fput() in the end */
+struct file *au_read_pre(struct file *file, int keep_fi)
+{
+	struct file *h_file;
+	int err;
+
+	err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/0);
+	if (!err) {
+		di_read_unlock(file->f_path.dentry, AuLock_IR);
+		h_file = au_hf_top(file);
+		get_file(h_file);
+		if (!keep_fi)
+			fi_read_unlock(file);
+	} else
+		h_file = ERR_PTR(err);
+
+	return h_file;
+}
+
+static void au_read_post(struct inode *inode, struct file *h_file)
+{
+	/* update without lock, I don't think it a problem */
+	fsstack_copy_attr_atime(inode, file_inode(h_file));
+	fput(h_file);
+}
+
+struct au_write_pre {
+	blkcnt_t blks;
+	aufs_bindex_t bstart;
+};
+
+/*
+ * return with iinfo is write-locked
+ * callers should call au_write_post() or iinfo_write_unlock() + fput() in the
+ * end
+ */
+static struct file *au_write_pre(struct file *file, int do_ready,
+				 struct au_write_pre *wpre)
+{
+	struct file *h_file;
+	struct dentry *dentry;
+	int err;
+	struct au_pin pin;
+
+	err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1);
+	h_file = ERR_PTR(err);
+	if (unlikely(err))
+		goto out;
+
+	dentry = file->f_path.dentry;
+	if (do_ready) {
+		err = au_ready_to_write(file, -1, &pin);
+		if (unlikely(err)) {
+			h_file = ERR_PTR(err);
+			di_write_unlock(dentry);
+			goto out_fi;
+		}
+	}
+
+	di_downgrade_lock(dentry, /*flags*/0);
+	if (wpre)
+		wpre->bstart = au_fbstart(file);
+	h_file = au_hf_top(file);
+	get_file(h_file);
+	if (wpre)
+		wpre->blks = file_inode(h_file)->i_blocks;
+	if (do_ready)
+		au_unpin(&pin);
+	di_read_unlock(dentry, /*flags*/0);
+
+out_fi:
+	fi_write_unlock(file);
+out:
+	return h_file;
+}
+
+static void au_write_post(struct inode *inode, struct file *h_file,
+			  struct au_write_pre *wpre, ssize_t written)
+{
+	struct inode *h_inode;
+
+	au_cpup_attr_timesizes(inode);
+	AuDebugOn(au_ibstart(inode) != wpre->bstart);
+	h_inode = file_inode(h_file);
+	inode->i_mode = h_inode->i_mode;
+	ii_write_unlock(inode);
+	fput(h_file);
+
+	/* AuDbg("blks %llu, %llu\n", (u64)blks, (u64)h_inode->i_blocks); */
+	if (written > 0)
+		au_fhsm_wrote(inode->i_sb, wpre->bstart,
+			      /*force*/h_inode->i_blocks > wpre->blks);
+}
+
+static ssize_t aufs_read(struct file *file, char __user *buf, size_t count,
+			 loff_t *ppos)
+{
+	ssize_t err;
+	struct inode *inode;
+	struct file *h_file;
+	struct super_block *sb;
+
+	inode = file_inode(file);
+	sb = inode->i_sb;
+	si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW);
+
+	h_file = au_read_pre(file, /*keep_fi*/0);
+	err = PTR_ERR(h_file);
+	if (IS_ERR(h_file))
+		goto out;
+
+	/* filedata may be obsoleted by concurrent copyup, but no problem */
+	err = vfsub_read_u(h_file, buf, count, ppos);
+	/* todo: necessary? */
+	/* file->f_ra = h_file->f_ra; */
+	au_read_post(inode, h_file);
+
+out:
+	si_read_unlock(sb);
+	return err;
+}
+
+/*
+ * todo: very ugly
+ * it locks both of i_mutex and si_rwsem for read in safe.
+ * if the plink maintenance mode continues forever (that is the problem),
+ * may loop forever.
+ */
+static void au_mtx_and_read_lock(struct inode *inode)
+{
+	int err;
+	struct super_block *sb = inode->i_sb;
+
+	while (1) {
+		mutex_lock(&inode->i_mutex);
+		err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
+		if (!err)
+			break;
+		mutex_unlock(&inode->i_mutex);
+		si_read_lock(sb, AuLock_NOPLMW);
+		si_read_unlock(sb);
+	}
+}
+
+static ssize_t aufs_write(struct file *file, const char __user *ubuf,
+			  size_t count, loff_t *ppos)
+{
+	ssize_t err;
+	struct au_write_pre wpre;
+	struct inode *inode;
+	struct file *h_file;
+	char __user *buf = (char __user *)ubuf;
+
+	inode = file_inode(file);
+	au_mtx_and_read_lock(inode);
+
+	h_file = au_write_pre(file, /*do_ready*/1, &wpre);
+	err = PTR_ERR(h_file);
+	if (IS_ERR(h_file))
+		goto out;
+
+	err = vfsub_write_u(h_file, buf, count, ppos);
+	au_write_post(inode, h_file, &wpre, err);
+
+out:
+	si_read_unlock(inode->i_sb);
+	mutex_unlock(&inode->i_mutex);
+	return err;
+}
+
+static ssize_t au_do_iter(struct file *h_file, int rw, struct kiocb *kio,
+			  struct iov_iter *iov_iter)
+{
+	ssize_t err;
+	struct file *file;
+	ssize_t (*iter)(struct kiocb *, struct iov_iter *);
+
+	err = security_file_permission(h_file, rw);
+	if (unlikely(err))
+		goto out;
+
+	err = -ENOSYS;
+	iter = NULL;
+	if (rw == MAY_READ)
+		iter = h_file->f_op->read_iter;
+	else if (rw == MAY_WRITE)
+		iter = h_file->f_op->write_iter;
+
+	file = kio->ki_filp;
+	kio->ki_filp = h_file;
+	if (iter) {
+		lockdep_off();
+		err = iter(kio, iov_iter);
+		lockdep_on();
+	} else
+		/* currently there is no such fs */
+		WARN_ON_ONCE(1);
+	kio->ki_filp = file;
+
+out:
+	return err;
+}
+
+static ssize_t aufs_read_iter(struct kiocb *kio, struct iov_iter *iov_iter)
+{
+	ssize_t err;
+	struct file *file, *h_file;
+	struct inode *inode;
+	struct super_block *sb;
+
+	file = kio->ki_filp;
+	inode = file_inode(file);
+	sb = inode->i_sb;
+	si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW);
+
+	h_file = au_read_pre(file, /*keep_fi*/0);
+	err = PTR_ERR(h_file);
+	if (IS_ERR(h_file))
+		goto out;
+
+	err = au_do_iter(h_file, MAY_READ, kio, iov_iter);
+	/* todo: necessary? */
+	/* file->f_ra = h_file->f_ra; */
+	au_read_post(inode, h_file);
+
+out:
+	si_read_unlock(sb);
+	return err;
+}
+
+static ssize_t aufs_write_iter(struct kiocb *kio, struct iov_iter *iov_iter)
+{
+	ssize_t err;
+	struct au_write_pre wpre;
+	struct inode *inode;
+	struct file *file, *h_file;
+
+	file = kio->ki_filp;
+	inode = file_inode(file);
+	au_mtx_and_read_lock(inode);
+
+	h_file = au_write_pre(file, /*do_ready*/1, &wpre);
+	err = PTR_ERR(h_file);
+	if (IS_ERR(h_file))
+		goto out;
+
+	err = au_do_iter(h_file, MAY_WRITE, kio, iov_iter);
+	au_write_post(inode, h_file, &wpre, err);
+
+out:
+	si_read_unlock(inode->i_sb);
+	mutex_unlock(&inode->i_mutex);
+	return err;
+}
+
+static ssize_t aufs_splice_read(struct file *file, loff_t *ppos,
+				struct pipe_inode_info *pipe, size_t len,
+				unsigned int flags)
+{
+	ssize_t err;
+	struct file *h_file;
+	struct inode *inode;
+	struct super_block *sb;
+
+	inode = file_inode(file);
+	sb = inode->i_sb;
+	si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW);
+
+	h_file = au_read_pre(file, /*keep_fi*/1);
+	err = PTR_ERR(h_file);
+	if (IS_ERR(h_file))
+		goto out;
+
+	if (0 && au_test_loopback_kthread()) {
+		au_warn_loopback(h_file->f_path.dentry->d_sb);
+		if (file->f_mapping != h_file->f_mapping) {
+			file->f_mapping = h_file->f_mapping;
+			smp_mb(); /* unnecessary? */
+		}
+	}
+	fi_read_unlock(file);
+
+	err = vfsub_splice_to(h_file, ppos, pipe, len, flags);
+	/* todo: necessasry? */
+	/* file->f_ra = h_file->f_ra; */
+	au_read_post(inode, h_file);
+
+out:
+	si_read_unlock(sb);
+	return err;
+}
+
+static ssize_t
+aufs_splice_write(struct pipe_inode_info *pipe, struct file *file, loff_t *ppos,
+		  size_t len, unsigned int flags)
+{
+	ssize_t err;
+	struct au_write_pre wpre;
+	struct inode *inode;
+	struct file *h_file;
+
+	inode = file_inode(file);
+	au_mtx_and_read_lock(inode);
+
+	h_file = au_write_pre(file, /*do_ready*/1, &wpre);
+	err = PTR_ERR(h_file);
+	if (IS_ERR(h_file))
+		goto out;
+
+	err = vfsub_splice_from(pipe, h_file, ppos, len, flags);
+	au_write_post(inode, h_file, &wpre, err);
+
+out:
+	si_read_unlock(inode->i_sb);
+	mutex_unlock(&inode->i_mutex);
+	return err;
+}
+
+static long aufs_fallocate(struct file *file, int mode, loff_t offset,
+			   loff_t len)
+{
+	long err;
+	struct au_write_pre wpre;
+	struct inode *inode;
+	struct file *h_file;
+
+	inode = file_inode(file);
+	au_mtx_and_read_lock(inode);
+
+	h_file = au_write_pre(file, /*do_ready*/1, &wpre);
+	err = PTR_ERR(h_file);
+	if (IS_ERR(h_file))
+		goto out;
+
+	lockdep_off();
+	err = vfs_fallocate(h_file, mode, offset, len);
+	lockdep_on();
+	au_write_post(inode, h_file, &wpre, /*written*/1);
+
+out:
+	si_read_unlock(inode->i_sb);
+	mutex_unlock(&inode->i_mutex);
+	return err;
+}
+
+/* ---------------------------------------------------------------------- */
+
+/*
+ * The locking order around current->mmap_sem.
+ * - in most and regular cases
+ *   file I/O syscall -- aufs_read() or something
+ *	-- si_rwsem for read -- mmap_sem
+ *	(Note that [fdi]i_rwsem are released before mmap_sem).
+ * - in mmap case
+ *   mmap(2) -- mmap_sem -- aufs_mmap() -- si_rwsem for read -- [fdi]i_rwsem
+ * This AB-BA order is definitly bad, but is not a problem since "si_rwsem for
+ * read" allows muliple processes to acquire it and [fdi]i_rwsem are not held in
+ * file I/O. Aufs needs to stop lockdep in aufs_mmap() though.
+ * It means that when aufs acquires si_rwsem for write, the process should never
+ * acquire mmap_sem.
+ *
+ * Actually aufs_iterate() holds [fdi]i_rwsem before mmap_sem, but this is not a
+ * problem either since any directory is not able to be mmap-ed.
+ * The similar scenario is applied to aufs_readlink() too.
+ */
+
+#if 0 /* stop calling security_file_mmap() */
+/* cf. linux/include/linux/mman.h: calc_vm_prot_bits() */
+#define AuConv_VM_PROT(f, b)	_calc_vm_trans(f, VM_##b, PROT_##b)
+
+static unsigned long au_arch_prot_conv(unsigned long flags)
+{
+	/* currently ppc64 only */
+#ifdef CONFIG_PPC64
+	/* cf. linux/arch/powerpc/include/asm/mman.h */
+	AuDebugOn(arch_calc_vm_prot_bits(-1) != VM_SAO);
+	return AuConv_VM_PROT(flags, SAO);
+#else
+	AuDebugOn(arch_calc_vm_prot_bits(-1));
+	return 0;
+#endif
+}
+
+static unsigned long au_prot_conv(unsigned long flags)
+{
+	return AuConv_VM_PROT(flags, READ)
+		| AuConv_VM_PROT(flags, WRITE)
+		| AuConv_VM_PROT(flags, EXEC)
+		| au_arch_prot_conv(flags);
+}
+
+/* cf. linux/include/linux/mman.h: calc_vm_flag_bits() */
+#define AuConv_VM_MAP(f, b)	_calc_vm_trans(f, VM_##b, MAP_##b)
+
+static unsigned long au_flag_conv(unsigned long flags)
+{
+	return AuConv_VM_MAP(flags, GROWSDOWN)
+		| AuConv_VM_MAP(flags, DENYWRITE)
+		| AuConv_VM_MAP(flags, LOCKED);
+}
+#endif
+
+static int aufs_mmap(struct file *file, struct vm_area_struct *vma)
+{
+	int err;
+	const unsigned char wlock
+		= (file->f_mode & FMODE_WRITE) && (vma->vm_flags & VM_SHARED);
+	struct super_block *sb;
+	struct file *h_file;
+	struct inode *inode;
+
+	AuDbgVmRegion(file, vma);
+
+	inode = file_inode(file);
+	sb = inode->i_sb;
+	lockdep_off();
+	si_read_lock(sb, AuLock_NOPLMW);
+
+	h_file = au_write_pre(file, wlock, /*wpre*/NULL);
+	lockdep_on();
+	err = PTR_ERR(h_file);
+	if (IS_ERR(h_file))
+		goto out;
+
+	err = 0;
+	au_set_mmapped(file);
+	au_vm_file_reset(vma, h_file);
+	/*
+	 * we cannot call security_mmap_file() here since it may acquire
+	 * mmap_sem or i_mutex.
+	 *
+	 * err = security_mmap_file(h_file, au_prot_conv(vma->vm_flags),
+	 *			 au_flag_conv(vma->vm_flags));
+	 */
+	if (!err)
+		err = h_file->f_op->mmap(h_file, vma);
+	if (!err) {
+		au_vm_prfile_set(vma, file);
+		fsstack_copy_attr_atime(inode, file_inode(h_file));
+		goto out_fput; /* success */
+	}
+	au_unset_mmapped(file);
+	au_vm_file_reset(vma, file);
+
+out_fput:
+	lockdep_off();
+	ii_write_unlock(inode);
+	lockdep_on();
+	fput(h_file);
+out:
+	lockdep_off();
+	si_read_unlock(sb);
+	lockdep_on();
+	AuTraceErr(err);
+	return err;
+}
+
+/* ---------------------------------------------------------------------- */
+
+static int aufs_fsync_nondir(struct file *file, loff_t start, loff_t end,
+			     int datasync)
+{
+	int err;
+	struct au_write_pre wpre;
+	struct inode *inode;
+	struct file *h_file;
+
+	err = 0; /* -EBADF; */ /* posix? */
+	if (unlikely(!(file->f_mode & FMODE_WRITE)))
+		goto out;
+
+	inode = file_inode(file);
+	au_mtx_and_read_lock(inode);
+
+	h_file = au_write_pre(file, /*do_ready*/1, &wpre);
+	err = PTR_ERR(h_file);
+	if (IS_ERR(h_file))
+		goto out_unlock;
+
+	err = vfsub_fsync(h_file, &h_file->f_path, datasync);
+	au_write_post(inode, h_file, &wpre, /*written*/0);
+
+out_unlock:
+	si_read_unlock(inode->i_sb);
+	mutex_unlock(&inode->i_mutex);
+out:
+	return err;
+}
+
+/* no one supports this operation, currently */
+#if 0
+static int aufs_aio_fsync_nondir(struct kiocb *kio, int datasync)
+{
+	int err;
+	struct au_write_pre wpre;
+	struct inode *inode;
+	struct file *file, *h_file;
+
+	err = 0; /* -EBADF; */ /* posix? */
+	if (unlikely(!(file->f_mode & FMODE_WRITE)))
+		goto out;
+
+	file = kio->ki_filp;
+	inode = file_inode(file);
+	au_mtx_and_read_lock(inode);
+
+	h_file = au_write_pre(file, /*do_ready*/1, &wpre);
+	err = PTR_ERR(h_file);
+	if (IS_ERR(h_file))
+		goto out_unlock;
+
+	err = -ENOSYS;
+	h_file = au_hf_top(file);
+	if (h_file->f_op->aio_fsync) {
+		struct mutex *h_mtx;
+
+		h_mtx = &file_inode(h_file)->i_mutex;
+		if (!is_sync_kiocb(kio)) {
+			get_file(h_file);
+			fput(file);
+		}
+		kio->ki_filp = h_file;
+		err = h_file->f_op->aio_fsync(kio, datasync);
+		mutex_lock_nested(h_mtx, AuLsc_I_CHILD);
+		if (!err)
+			vfsub_update_h_iattr(&h_file->f_path, /*did*/NULL);
+		/*ignore*/
+		mutex_unlock(h_mtx);
+	}
+	au_write_post(inode, h_file, &wpre, /*written*/0);
+
+out_unlock:
+	si_read_unlock(inode->sb);
+	mutex_unlock(&inode->i_mutex);
+out:
+	return err;
+}
+#endif
+
+static int aufs_fasync(int fd, struct file *file, int flag)
+{
+	int err;
+	struct file *h_file;
+	struct super_block *sb;
+
+	sb = file->f_path.dentry->d_sb;
+	si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW);
+
+	h_file = au_read_pre(file, /*keep_fi*/0);
+	err = PTR_ERR(h_file);
+	if (IS_ERR(h_file))
+		goto out;
+
+	if (h_file->f_op->fasync)
+		err = h_file->f_op->fasync(fd, h_file, flag);
+	fput(h_file); /* instead of au_read_post() */
+
+out:
+	si_read_unlock(sb);
+	return err;
+}
+
+/* ---------------------------------------------------------------------- */
+
+/* no one supports this operation, currently */
+#if 0
+static ssize_t aufs_sendpage(struct file *file, struct page *page, int offset,
+			     size_t len, loff_t *pos, int more)
+{
+}
+#endif
+
+/* ---------------------------------------------------------------------- */
+
+const struct file_operations aufs_file_fop = {
+	.owner		= THIS_MODULE,
+
+	.llseek		= default_llseek,
+
+	.read		= aufs_read,
+	.write		= aufs_write,
+	.read_iter	= aufs_read_iter,
+	.write_iter	= aufs_write_iter,
+
+#ifdef CONFIG_AUFS_POLL
+	.poll		= aufs_poll,
+#endif
+	.unlocked_ioctl	= aufs_ioctl_nondir,
+#ifdef CONFIG_COMPAT
+	.compat_ioctl	= aufs_compat_ioctl_nondir,
+#endif
+	.mmap		= aufs_mmap,
+	.open		= aufs_open_nondir,
+	.flush		= aufs_flush_nondir,
+	.release	= aufs_release_nondir,
+	.fsync		= aufs_fsync_nondir,
+	/* .aio_fsync	= aufs_aio_fsync_nondir, */
+	.fasync		= aufs_fasync,
+	/* .sendpage	= aufs_sendpage, */
+	.splice_write	= aufs_splice_write,
+	.splice_read	= aufs_splice_read,
+#if 0
+	.aio_splice_write = aufs_aio_splice_write,
+	.aio_splice_read  = aufs_aio_splice_read,
+#endif
+	.fallocate	= aufs_fallocate
+};
--- /dev/null
+++ zfcpdump-kernel-4.4/fs/aufs/fhsm.c
@@ -0,0 +1,426 @@
+/*
+ * Copyright (C) 2011-2015 Junjiro R. Okajima
+ *
+ * This program, aufs is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+/*
+ * File-based Hierarchy Storage Management
+ */
+
+#include <linux/anon_inodes.h>
+#include <linux/poll.h>
+#include <linux/seq_file.h>
+#include <linux/statfs.h>
+#include "aufs.h"
+
+static aufs_bindex_t au_fhsm_bottom(struct super_block *sb)
+{
+	struct au_sbinfo *sbinfo;
+	struct au_fhsm *fhsm;
+
+	SiMustAnyLock(sb);
+
+	sbinfo = au_sbi(sb);
+	fhsm = &sbinfo->si_fhsm;
+	AuDebugOn(!fhsm);
+	return fhsm->fhsm_bottom;
+}
+
+void au_fhsm_set_bottom(struct super_block *sb, aufs_bindex_t bindex)
+{
+	struct au_sbinfo *sbinfo;
+	struct au_fhsm *fhsm;
+
+	SiMustWriteLock(sb);
+
+	sbinfo = au_sbi(sb);
+	fhsm = &sbinfo->si_fhsm;
+	AuDebugOn(!fhsm);
+	fhsm->fhsm_bottom = bindex;
+}
+
+/* ---------------------------------------------------------------------- */
+
+static int au_fhsm_test_jiffy(struct au_sbinfo *sbinfo, struct au_branch *br)
+{
+	struct au_br_fhsm *bf;
+
+	bf = br->br_fhsm;
+	MtxMustLock(&bf->bf_lock);
+
+	return !bf->bf_readable
+		|| time_after(jiffies,
+			      bf->bf_jiffy + sbinfo->si_fhsm.fhsm_expire);
+}
+
+/* ---------------------------------------------------------------------- */
+
+static void au_fhsm_notify(struct super_block *sb, int val)
+{
+	struct au_sbinfo *sbinfo;
+	struct au_fhsm *fhsm;
+
+	SiMustAnyLock(sb);
+
+	sbinfo = au_sbi(sb);
+	fhsm = &sbinfo->si_fhsm;
+	if (au_fhsm_pid(fhsm)
+	    && atomic_read(&fhsm->fhsm_readable) != -1) {
+		atomic_set(&fhsm->fhsm_readable, val);
+		if (val)
+			wake_up(&fhsm->fhsm_wqh);
+	}
+}
+
+static int au_fhsm_stfs(struct super_block *sb, aufs_bindex_t bindex,
+			struct aufs_stfs *rstfs, int do_lock, int do_notify)
+{
+	int err;
+	struct au_branch *br;
+	struct au_br_fhsm *bf;
+
+	br = au_sbr(sb, bindex);
+	AuDebugOn(au_br_rdonly(br));
+	bf = br->br_fhsm;
+	AuDebugOn(!bf);
+
+	if (do_lock)
+		mutex_lock(&bf->bf_lock);
+	else
+		MtxMustLock(&bf->bf_lock);
+
+	/* sb->s_root for NFS is unreliable */
+	err = au_br_stfs(br, &bf->bf_stfs);
+	if (unlikely(err)) {
+		AuErr1("FHSM failed (%d), b%d, ignored.\n", bindex, err);
+		goto out;
+	}
+
+	bf->bf_jiffy = jiffies;
+	bf->bf_readable = 1;
+	if (do_notify)
+		au_fhsm_notify(sb, /*val*/1);
+	if (rstfs)
+		*rstfs = bf->bf_stfs;
+
+out:
+	if (do_lock)
+		mutex_unlock(&bf->bf_lock);
+	au_fhsm_notify(sb, /*val*/1);
+
+	return err;
+}
+
+void au_fhsm_wrote(struct super_block *sb, aufs_bindex_t bindex, int force)
+{
+	int err;
+	struct au_sbinfo *sbinfo;
+	struct au_fhsm *fhsm;
+	struct au_branch *br;
+	struct au_br_fhsm *bf;
+
+	AuDbg("b%d, force %d\n", bindex, force);
+	SiMustAnyLock(sb);
+
+	sbinfo = au_sbi(sb);
+	fhsm = &sbinfo->si_fhsm;
+	if (!au_ftest_si(sbinfo, FHSM)
+	    || fhsm->fhsm_bottom == bindex)
+		return;
+
+	br = au_sbr(sb, bindex);
+	bf = br->br_fhsm;
+	AuDebugOn(!bf);
+	mutex_lock(&bf->bf_lock);
+	if (force
+	    || au_fhsm_pid(fhsm)
+	    || au_fhsm_test_jiffy(sbinfo, br))
+		err = au_fhsm_stfs(sb, bindex, /*rstfs*/NULL, /*do_lock*/0,
+				  /*do_notify*/1);
+	mutex_unlock(&bf->bf_lock);
+}
+
+void au_fhsm_wrote_all(struct super_block *sb, int force)
+{
+	aufs_bindex_t bindex, bend;
+	struct au_branch *br;
+
+	/* exclude the bottom */
+	bend = au_fhsm_bottom(sb);
+	for (bindex = 0; bindex < bend; bindex++) {
+		br = au_sbr(sb, bindex);
+		if (au_br_fhsm(br->br_perm))
+			au_fhsm_wrote(sb, bindex, force);
+	}
+}
+
+/* ---------------------------------------------------------------------- */
+
+static unsigned int au_fhsm_poll(struct file *file,
+				 struct poll_table_struct *wait)
+{
+	unsigned int mask;
+	struct au_sbinfo *sbinfo;
+	struct au_fhsm *fhsm;
+
+	mask = 0;
+	sbinfo = file->private_data;
+	fhsm = &sbinfo->si_fhsm;
+	poll_wait(file, &fhsm->fhsm_wqh, wait);
+	if (atomic_read(&fhsm->fhsm_readable))
+		mask = POLLIN /* | POLLRDNORM */;
+
+	AuTraceErr((int)mask);
+	return mask;
+}
+
+static int au_fhsm_do_read_one(struct aufs_stbr __user *stbr,
+			      struct aufs_stfs *stfs, __s16 brid)
+{
+	int err;
+
+	err = copy_to_user(&stbr->stfs, stfs, sizeof(*stfs));
+	if (!err)
+		err = __put_user(brid, &stbr->brid);
+	if (unlikely(err))
+		err = -EFAULT;
+
+	return err;
+}
+
+static ssize_t au_fhsm_do_read(struct super_block *sb,
+			       struct aufs_stbr __user *stbr, size_t count)
+{
+	ssize_t err;
+	int nstbr;
+	aufs_bindex_t bindex, bend;
+	struct au_branch *br;
+	struct au_br_fhsm *bf;
+
+	/* except the bottom branch */
+	err = 0;
+	nstbr = 0;
+	bend = au_fhsm_bottom(sb);
+	for (bindex = 0; !err && bindex < bend; bindex++) {
+		br = au_sbr(sb, bindex);
+		if (!au_br_fhsm(br->br_perm))
+			continue;
+
+		bf = br->br_fhsm;
+		mutex_lock(&bf->bf_lock);
+		if (bf->bf_readable) {
+			err = -EFAULT;
+			if (count >= sizeof(*stbr))
+				err = au_fhsm_do_read_one(stbr++, &bf->bf_stfs,
+							  br->br_id);
+			if (!err) {
+				bf->bf_readable = 0;
+				count -= sizeof(*stbr);
+				nstbr++;
+			}
+		}
+		mutex_unlock(&bf->bf_lock);
+	}
+	if (!err)
+		err = sizeof(*stbr) * nstbr;
+
+	return err;
+}
+
+static ssize_t au_fhsm_read(struct file *file, char __user *buf, size_t count,
+			   loff_t *pos)
+{
+	ssize_t err;
+	int readable;
+	aufs_bindex_t nfhsm, bindex, bend;
+	struct au_sbinfo *sbinfo;
+	struct au_fhsm *fhsm;
+	struct au_branch *br;
+	struct super_block *sb;
+
+	err = 0;
+	sbinfo = file->private_data;
+	fhsm = &sbinfo->si_fhsm;
+need_data:
+	spin_lock_irq(&fhsm->fhsm_wqh.lock);
+	if (!atomic_read(&fhsm->fhsm_readable)) {
+		if (vfsub_file_flags(file) & O_NONBLOCK)
+			err = -EAGAIN;
+		else
+			err = wait_event_interruptible_locked_irq
+				(fhsm->fhsm_wqh,
+				 atomic_read(&fhsm->fhsm_readable));
+	}
+	spin_unlock_irq(&fhsm->fhsm_wqh.lock);
+	if (unlikely(err))
+		goto out;
+
+	/* sb may already be dead */
+	au_rw_read_lock(&sbinfo->si_rwsem);
+	readable = atomic_read(&fhsm->fhsm_readable);
+	if (readable > 0) {
+		sb = sbinfo->si_sb;
+		AuDebugOn(!sb);
+		/* exclude the bottom branch */
+		nfhsm = 0;
+		bend = au_fhsm_bottom(sb);
+		for (bindex = 0; bindex < bend; bindex++) {
+			br = au_sbr(sb, bindex);
+			if (au_br_fhsm(br->br_perm))
+				nfhsm++;
+		}
+		err = -EMSGSIZE;
+		if (nfhsm * sizeof(struct aufs_stbr) <= count) {
+			atomic_set(&fhsm->fhsm_readable, 0);
+			err = au_fhsm_do_read(sbinfo->si_sb, (void __user *)buf,
+					     count);
+		}
+	}
+	au_rw_read_unlock(&sbinfo->si_rwsem);
+	if (!readable)
+		goto need_data;
+
+out:
+	return err;
+}
+
+static int au_fhsm_release(struct inode *inode, struct file *file)
+{
+	struct au_sbinfo *sbinfo;
+	struct au_fhsm *fhsm;
+
+	/* sb may already be dead */
+	sbinfo = file->private_data;
+	fhsm = &sbinfo->si_fhsm;
+	spin_lock(&fhsm->fhsm_spin);
+	fhsm->fhsm_pid = 0;
+	spin_unlock(&fhsm->fhsm_spin);
+	kobject_put(&sbinfo->si_kobj);
+
+	return 0;
+}
+
+static const struct file_operations au_fhsm_fops = {
+	.owner		= THIS_MODULE,
+	.llseek		= noop_llseek,
+	.read		= au_fhsm_read,
+	.poll		= au_fhsm_poll,
+	.release	= au_fhsm_release
+};
+
+int au_fhsm_fd(struct super_block *sb, int oflags)
+{
+	int err, fd;
+	struct au_sbinfo *sbinfo;
+	struct au_fhsm *fhsm;
+
+	err = -EPERM;
+	if (unlikely(!capable(CAP_SYS_ADMIN)))
+		goto out;
+
+	err = -EINVAL;
+	if (unlikely(oflags & ~(O_CLOEXEC | O_NONBLOCK)))
+		goto out;
+
+	err = 0;
+	sbinfo = au_sbi(sb);
+	fhsm = &sbinfo->si_fhsm;
+	spin_lock(&fhsm->fhsm_spin);
+	if (!fhsm->fhsm_pid)
+		fhsm->fhsm_pid = current->pid;
+	else
+		err = -EBUSY;
+	spin_unlock(&fhsm->fhsm_spin);
+	if (unlikely(err))
+		goto out;
+
+	oflags |= O_RDONLY;
+	/* oflags |= FMODE_NONOTIFY; */
+	fd = anon_inode_getfd("[aufs_fhsm]", &au_fhsm_fops, sbinfo, oflags);
+	err = fd;
+	if (unlikely(fd < 0))
+		goto out_pid;
+
+	/* succeed reglardless 'fhsm' status */
+	kobject_get(&sbinfo->si_kobj);
+	si_noflush_read_lock(sb);
+	if (au_ftest_si(sbinfo, FHSM))
+		au_fhsm_wrote_all(sb, /*force*/0);
+	si_read_unlock(sb);
+	goto out; /* success */
+
+out_pid:
+	spin_lock(&fhsm->fhsm_spin);
+	fhsm->fhsm_pid = 0;
+	spin_unlock(&fhsm->fhsm_spin);
+out:
+	AuTraceErr(err);
+	return err;
+}
+
+/* ---------------------------------------------------------------------- */
+
+int au_fhsm_br_alloc(struct au_branch *br)
+{
+	int err;
+
+	err = 0;
+	br->br_fhsm = kmalloc(sizeof(*br->br_fhsm), GFP_NOFS);
+	if (br->br_fhsm)
+		au_br_fhsm_init(br->br_fhsm);
+	else
+		err = -ENOMEM;
+
+	return err;
+}
+
+/* ---------------------------------------------------------------------- */
+
+void au_fhsm_fin(struct super_block *sb)
+{
+	au_fhsm_notify(sb, /*val*/-1);
+}
+
+void au_fhsm_init(struct au_sbinfo *sbinfo)
+{
+	struct au_fhsm *fhsm;
+
+	fhsm = &sbinfo->si_fhsm;
+	spin_lock_init(&fhsm->fhsm_spin);
+	init_waitqueue_head(&fhsm->fhsm_wqh);
+	atomic_set(&fhsm->fhsm_readable, 0);
+	fhsm->fhsm_expire
+		= msecs_to_jiffies(AUFS_FHSM_CACHE_DEF_SEC * MSEC_PER_SEC);
+	fhsm->fhsm_bottom = -1;
+}
+
+void au_fhsm_set(struct au_sbinfo *sbinfo, unsigned int sec)
+{
+	sbinfo->si_fhsm.fhsm_expire
+		= msecs_to_jiffies(sec * MSEC_PER_SEC);
+}
+
+void au_fhsm_show(struct seq_file *seq, struct au_sbinfo *sbinfo)
+{
+	unsigned int u;
+
+	if (!au_ftest_si(sbinfo, FHSM))
+		return;
+
+	u = jiffies_to_msecs(sbinfo->si_fhsm.fhsm_expire) / MSEC_PER_SEC;
+	if (u != AUFS_FHSM_CACHE_DEF_SEC)
+		seq_printf(seq, ",fhsm_sec=%u", u);
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/fs/aufs/file.c
@@ -0,0 +1,844 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+ *
+ * This program, aufs is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * handling file/dir, and address_space operation
+ */
+
+#ifdef CONFIG_AUFS_DEBUG
+#include <linux/migrate.h>
+#endif
+#include <linux/pagemap.h>
+#include "aufs.h"
+
+/* drop flags for writing */
+unsigned int au_file_roflags(unsigned int flags)
+{
+	flags &= ~(O_WRONLY | O_RDWR | O_APPEND | O_CREAT | O_TRUNC);
+	flags |= O_RDONLY | O_NOATIME;
+	return flags;
+}
+
+/* common functions to regular file and dir */
+struct file *au_h_open(struct dentry *dentry, aufs_bindex_t bindex, int flags,
+		       struct file *file, int force_wr)
+{
+	struct file *h_file;
+	struct dentry *h_dentry;
+	struct inode *h_inode;
+	struct super_block *sb;
+	struct au_branch *br;
+	struct path h_path;
+	int err;
+
+	/* a race condition can happen between open and unlink/rmdir */
+	h_file = ERR_PTR(-ENOENT);
+	h_dentry = au_h_dptr(dentry, bindex);
+	if (au_test_nfsd() && (!h_dentry || d_is_negative(h_dentry)))
+		goto out;
+	h_inode = d_inode(h_dentry);
+	spin_lock(&h_dentry->d_lock);
+	err = (!d_unhashed(dentry) && d_unlinked(h_dentry))
+		/* || !d_inode(dentry)->i_nlink */
+		;
+	spin_unlock(&h_dentry->d_lock);
+	if (unlikely(err))
+		goto out;
+
+	sb = dentry->d_sb;
+	br = au_sbr(sb, bindex);
+	err = au_br_test_oflag(flags, br);
+	h_file = ERR_PTR(err);
+	if (unlikely(err))
+		goto out;
+
+	/* drop flags for writing */
+	if (au_test_ro(sb, bindex, d_inode(dentry))) {
+		if (force_wr && !(flags & O_WRONLY))
+			force_wr = 0;
+		flags = au_file_roflags(flags);
+		if (force_wr) {
+			h_file = ERR_PTR(-EROFS);
+			flags = au_file_roflags(flags);
+			if (unlikely(vfsub_native_ro(h_inode)
+				     || IS_APPEND(h_inode)))
+				goto out;
+			flags &= ~O_ACCMODE;
+			flags |= O_WRONLY;
+		}
+	}
+	flags &= ~O_CREAT;
+	atomic_inc(&br->br_count);
+	h_path.dentry = h_dentry;
+	h_path.mnt = au_br_mnt(br);
+	h_file = vfsub_dentry_open(&h_path, flags);
+	if (IS_ERR(h_file))
+		goto out_br;
+
+	if (flags & __FMODE_EXEC) {
+		err = deny_write_access(h_file);
+		if (unlikely(err)) {
+			fput(h_file);
+			h_file = ERR_PTR(err);
+			goto out_br;
+		}
+	}
+	fsnotify_open(h_file);
+	goto out; /* success */
+
+out_br:
+	atomic_dec(&br->br_count);
+out:
+	return h_file;
+}
+
+static int au_cmoo(struct dentry *dentry)
+{
+	int err, cmoo;
+	unsigned int udba;
+	struct path h_path;
+	struct au_pin pin;
+	struct au_cp_generic cpg = {
+		.dentry	= dentry,
+		.bdst	= -1,
+		.bsrc	= -1,
+		.len	= -1,
+		.pin	= &pin,
+		.flags	= AuCpup_DTIME | AuCpup_HOPEN
+	};
+	struct inode *delegated;
+	struct super_block *sb;
+	struct au_sbinfo *sbinfo;
+	struct au_fhsm *fhsm;
+	pid_t pid;
+	struct au_branch *br;
+	struct dentry *parent;
+	struct au_hinode *hdir;
+
+	DiMustWriteLock(dentry);
+	IiMustWriteLock(d_inode(dentry));
+
+	err = 0;
+	if (IS_ROOT(dentry))
+		goto out;
+	cpg.bsrc = au_dbstart(dentry);
+	if (!cpg.bsrc)
+		goto out;
+
+	sb = dentry->d_sb;
+	sbinfo = au_sbi(sb);
+	fhsm = &sbinfo->si_fhsm;
+	pid = au_fhsm_pid(fhsm);
+	if (pid
+	    && (current->pid == pid
+		|| current->real_parent->pid == pid))
+		goto out;
+
+	br = au_sbr(sb, cpg.bsrc);
+	cmoo = au_br_cmoo(br->br_perm);
+	if (!cmoo)
+		goto out;
+	if (!d_is_reg(dentry))
+		cmoo &= AuBrAttr_COO_ALL;
+	if (!cmoo)
+		goto out;
+
+	parent = dget_parent(dentry);
+	di_write_lock_parent(parent);
+	err = au_wbr_do_copyup_bu(dentry, cpg.bsrc - 1);
+	cpg.bdst = err;
+	if (unlikely(err < 0)) {
+		err = 0;	/* there is no upper writable branch */
+		goto out_dgrade;
+	}
+	AuDbg("bsrc %d, bdst %d\n", cpg.bsrc, cpg.bdst);
+
+	/* do not respect the coo attrib for the target branch */
+	err = au_cpup_dirs(dentry, cpg.bdst);
+	if (unlikely(err))
+		goto out_dgrade;
+
+	di_downgrade_lock(parent, AuLock_IR);
+	udba = au_opt_udba(sb);
+	err = au_pin(&pin, dentry, cpg.bdst, udba,
+		     AuPin_DI_LOCKED | AuPin_MNT_WRITE);
+	if (unlikely(err))
+		goto out_parent;
+
+	err = au_sio_cpup_simple(&cpg);
+	au_unpin(&pin);
+	if (unlikely(err))
+		goto out_parent;
+	if (!(cmoo & AuBrWAttr_MOO))
+		goto out_parent; /* success */
+
+	err = au_pin(&pin, dentry, cpg.bsrc, udba,
+		     AuPin_DI_LOCKED | AuPin_MNT_WRITE);
+	if (unlikely(err))
+		goto out_parent;
+
+	h_path.mnt = au_br_mnt(br);
+	h_path.dentry = au_h_dptr(dentry, cpg.bsrc);
+	hdir = au_hi(d_inode(parent), cpg.bsrc);
+	delegated = NULL;
+	err = vfsub_unlink(hdir->hi_inode, &h_path, &delegated, /*force*/1);
+	au_unpin(&pin);
+	/* todo: keep h_dentry or not? */
+	if (unlikely(err == -EWOULDBLOCK)) {
+		pr_warn("cannot retry for NFSv4 delegation"
+			" for an internal unlink\n");
+		iput(delegated);
+	}
+	if (unlikely(err)) {
+		pr_err("unlink %pd after coo failed (%d), ignored\n",
+		       dentry, err);
+		err = 0;
+	}
+	goto out_parent; /* success */
+
+out_dgrade:
+	di_downgrade_lock(parent, AuLock_IR);
+out_parent:
+	di_read_unlock(parent, AuLock_IR);
+	dput(parent);
+out:
+	AuTraceErr(err);
+	return err;
+}
+
+int au_do_open(struct file *file, struct au_do_open_args *args)
+{
+	int err, no_lock = args->no_lock;
+	struct dentry *dentry;
+	struct au_finfo *finfo;
+
+	if (!no_lock)
+		err = au_finfo_init(file, args->fidir);
+	else {
+		lockdep_off();
+		err = au_finfo_init(file, args->fidir);
+		lockdep_on();
+	}
+	if (unlikely(err))
+		goto out;
+
+	dentry = file->f_path.dentry;
+	AuDebugOn(IS_ERR_OR_NULL(dentry));
+	if (!no_lock) {
+		di_write_lock_child(dentry);
+		err = au_cmoo(dentry);
+		di_downgrade_lock(dentry, AuLock_IR);
+		if (!err)
+			err = args->open(file, vfsub_file_flags(file), NULL);
+		di_read_unlock(dentry, AuLock_IR);
+	} else {
+		err = au_cmoo(dentry);
+		if (!err)
+			err = args->open(file, vfsub_file_flags(file),
+					 args->h_file);
+		if (!err && au_fbstart(file) != au_dbstart(dentry))
+			/*
+			 * cmoo happens after h_file was opened.
+			 * need to refresh file later.
+			 */
+			atomic_dec(&au_fi(file)->fi_generation);
+	}
+
+	finfo = au_fi(file);
+	if (!err) {
+		finfo->fi_file = file;
+		au_sphl_add(&finfo->fi_hlist,
+			    &au_sbi(file->f_path.dentry->d_sb)->si_files);
+	}
+	if (!no_lock)
+		fi_write_unlock(file);
+	else {
+		lockdep_off();
+		fi_write_unlock(file);
+		lockdep_on();
+	}
+	if (unlikely(err)) {
+		finfo->fi_hdir = NULL;
+		au_finfo_fin(file);
+	}
+
+out:
+	return err;
+}
+
+int au_reopen_nondir(struct file *file)
+{
+	int err;
+	aufs_bindex_t bstart;
+	struct dentry *dentry;
+	struct file *h_file, *h_file_tmp;
+
+	dentry = file->f_path.dentry;
+	bstart = au_dbstart(dentry);
+	h_file_tmp = NULL;
+	if (au_fbstart(file) == bstart) {
+		h_file = au_hf_top(file);
+		if (file->f_mode == h_file->f_mode)
+			return 0; /* success */
+		h_file_tmp = h_file;
+		get_file(h_file_tmp);
+		au_set_h_fptr(file, bstart, NULL);
+	}
+	AuDebugOn(au_fi(file)->fi_hdir);
+	/*
+	 * it can happen
+	 * file exists on both of rw and ro
+	 * open --> dbstart and fbstart are both 0
+	 * prepend a branch as rw, "rw" become ro
+	 * remove rw/file
+	 * delete the top branch, "rw" becomes rw again
+	 *	--> dbstart is 1, fbstart is still 0
+	 * write --> fbstart is 0 but dbstart is 1
+	 */
+	/* AuDebugOn(au_fbstart(file) < bstart); */
+
+	h_file = au_h_open(dentry, bstart, vfsub_file_flags(file) & ~O_TRUNC,
+			   file, /*force_wr*/0);
+	err = PTR_ERR(h_file);
+	if (IS_ERR(h_file)) {
+		if (h_file_tmp) {
+			atomic_inc(&au_sbr(dentry->d_sb, bstart)->br_count);
+			au_set_h_fptr(file, bstart, h_file_tmp);
+			h_file_tmp = NULL;
+		}
+		goto out; /* todo: close all? */
+	}
+
+	err = 0;
+	au_set_fbstart(file, bstart);
+	au_set_h_fptr(file, bstart, h_file);
+	au_update_figen(file);
+	/* todo: necessary? */
+	/* file->f_ra = h_file->f_ra; */
+
+out:
+	if (h_file_tmp)
+		fput(h_file_tmp);
+	return err;
+}
+
+/* ---------------------------------------------------------------------- */
+
+static int au_reopen_wh(struct file *file, aufs_bindex_t btgt,
+			struct dentry *hi_wh)
+{
+	int err;
+	aufs_bindex_t bstart;
+	struct au_dinfo *dinfo;
+	struct dentry *h_dentry;
+	struct au_hdentry *hdp;
+
+	dinfo = au_di(file->f_path.dentry);
+	AuRwMustWriteLock(&dinfo->di_rwsem);
+
+	bstart = dinfo->di_bstart;
+	dinfo->di_bstart = btgt;
+	hdp = dinfo->di_hdentry;
+	h_dentry = hdp[0 + btgt].hd_dentry;
+	hdp[0 + btgt].hd_dentry = hi_wh;
+	err = au_reopen_nondir(file);
+	hdp[0 + btgt].hd_dentry = h_dentry;
+	dinfo->di_bstart = bstart;
+
+	return err;
+}
+
+static int au_ready_to_write_wh(struct file *file, loff_t len,
+				aufs_bindex_t bcpup, struct au_pin *pin)
+{
+	int err;
+	struct inode *inode, *h_inode;
+	struct dentry *h_dentry, *hi_wh;
+	struct au_cp_generic cpg = {
+		.dentry	= file->f_path.dentry,
+		.bdst	= bcpup,
+		.bsrc	= -1,
+		.len	= len,
+		.pin	= pin
+	};
+
+	au_update_dbstart(cpg.dentry);
+	inode = d_inode(cpg.dentry);
+	h_inode = NULL;
+	if (au_dbstart(cpg.dentry) <= bcpup
+	    && au_dbend(cpg.dentry) >= bcpup) {
+		h_dentry = au_h_dptr(cpg.dentry, bcpup);
+		if (h_dentry && d_is_positive(h_dentry))
+			h_inode = d_inode(h_dentry);
+	}
+	hi_wh = au_hi_wh(inode, bcpup);
+	if (!hi_wh && !h_inode)
+		err = au_sio_cpup_wh(&cpg, file);
+	else
+		/* already copied-up after unlink */
+		err = au_reopen_wh(file, bcpup, hi_wh);
+
+	if (!err
+	    && (inode->i_nlink > 1
+		|| (inode->i_state & I_LINKABLE))
+	    && au_opt_test(au_mntflags(cpg.dentry->d_sb), PLINK))
+		au_plink_append(inode, bcpup, au_h_dptr(cpg.dentry, bcpup));
+
+	return err;
+}
+
+/*
+ * prepare the @file for writing.
+ */
+int au_ready_to_write(struct file *file, loff_t len, struct au_pin *pin)
+{
+	int err;
+	aufs_bindex_t dbstart;
+	struct dentry *parent;
+	struct inode *inode;
+	struct super_block *sb;
+	struct file *h_file;
+	struct au_cp_generic cpg = {
+		.dentry	= file->f_path.dentry,
+		.bdst	= -1,
+		.bsrc	= -1,
+		.len	= len,
+		.pin	= pin,
+		.flags	= AuCpup_DTIME
+	};
+
+	sb = cpg.dentry->d_sb;
+	inode = d_inode(cpg.dentry);
+	cpg.bsrc = au_fbstart(file);
+	err = au_test_ro(sb, cpg.bsrc, inode);
+	if (!err && (au_hf_top(file)->f_mode & FMODE_WRITE)) {
+		err = au_pin(pin, cpg.dentry, cpg.bsrc, AuOpt_UDBA_NONE,
+			     /*flags*/0);
+		goto out;
+	}
+
+	/* need to cpup or reopen */
+	parent = dget_parent(cpg.dentry);
+	di_write_lock_parent(parent);
+	err = AuWbrCopyup(au_sbi(sb), cpg.dentry);
+	cpg.bdst = err;
+	if (unlikely(err < 0))
+		goto out_dgrade;
+	err = 0;
+
+	if (!d_unhashed(cpg.dentry) && !au_h_dptr(parent, cpg.bdst)) {
+		err = au_cpup_dirs(cpg.dentry, cpg.bdst);
+		if (unlikely(err))
+			goto out_dgrade;
+	}
+
+	err = au_pin(pin, cpg.dentry, cpg.bdst, AuOpt_UDBA_NONE,
+		     AuPin_DI_LOCKED | AuPin_MNT_WRITE);
+	if (unlikely(err))
+		goto out_dgrade;
+
+	dbstart = au_dbstart(cpg.dentry);
+	if (dbstart <= cpg.bdst)
+		cpg.bsrc = cpg.bdst;
+
+	if (dbstart <= cpg.bdst		/* just reopen */
+	    || !d_unhashed(cpg.dentry)	/* copyup and reopen */
+		) {
+		h_file = au_h_open_pre(cpg.dentry, cpg.bsrc, /*force_wr*/0);
+		if (IS_ERR(h_file))
+			err = PTR_ERR(h_file);
+		else {
+			di_downgrade_lock(parent, AuLock_IR);
+			if (dbstart > cpg.bdst)
+				err = au_sio_cpup_simple(&cpg);
+			if (!err)
+				err = au_reopen_nondir(file);
+			au_h_open_post(cpg.dentry, cpg.bsrc, h_file);
+		}
+	} else {			/* copyup as wh and reopen */
+		/*
+		 * since writable hfsplus branch is not supported,
+		 * h_open_pre/post() are unnecessary.
+		 */
+		err = au_ready_to_write_wh(file, len, cpg.bdst, pin);
+		di_downgrade_lock(parent, AuLock_IR);
+	}
+
+	if (!err) {
+		au_pin_set_parent_lflag(pin, /*lflag*/0);
+		goto out_dput; /* success */
+	}
+	au_unpin(pin);
+	goto out_unlock;
+
+out_dgrade:
+	di_downgrade_lock(parent, AuLock_IR);
+out_unlock:
+	di_read_unlock(parent, AuLock_IR);
+out_dput:
+	dput(parent);
+out:
+	return err;
+}
+
+/* ---------------------------------------------------------------------- */
+
+int au_do_flush(struct file *file, fl_owner_t id,
+		int (*flush)(struct file *file, fl_owner_t id))
+{
+	int err;
+	struct super_block *sb;
+	struct inode *inode;
+
+	inode = file_inode(file);
+	sb = inode->i_sb;
+	si_noflush_read_lock(sb);
+	fi_read_lock(file);
+	ii_read_lock_child(inode);
+
+	err = flush(file, id);
+	au_cpup_attr_timesizes(inode);
+
+	ii_read_unlock(inode);
+	fi_read_unlock(file);
+	si_read_unlock(sb);
+	return err;
+}
+
+/* ---------------------------------------------------------------------- */
+
+static int au_file_refresh_by_inode(struct file *file, int *need_reopen)
+{
+	int err;
+	struct au_pin pin;
+	struct au_finfo *finfo;
+	struct dentry *parent, *hi_wh;
+	struct inode *inode;
+	struct super_block *sb;
+	struct au_cp_generic cpg = {
+		.dentry	= file->f_path.dentry,
+		.bdst	= -1,
+		.bsrc	= -1,
+		.len	= -1,
+		.pin	= &pin,
+		.flags	= AuCpup_DTIME
+	};
+
+	FiMustWriteLock(file);
+
+	err = 0;
+	finfo = au_fi(file);
+	sb = cpg.dentry->d_sb;
+	inode = d_inode(cpg.dentry);
+	cpg.bdst = au_ibstart(inode);
+	if (cpg.bdst == finfo->fi_btop || IS_ROOT(cpg.dentry))
+		goto out;
+
+	parent = dget_parent(cpg.dentry);
+	if (au_test_ro(sb, cpg.bdst, inode)) {
+		di_read_lock_parent(parent, !AuLock_IR);
+		err = AuWbrCopyup(au_sbi(sb), cpg.dentry);
+		cpg.bdst = err;
+		di_read_unlock(parent, !AuLock_IR);
+		if (unlikely(err < 0))
+			goto out_parent;
+		err = 0;
+	}
+
+	di_read_lock_parent(parent, AuLock_IR);
+	hi_wh = au_hi_wh(inode, cpg.bdst);
+	if (!S_ISDIR(inode->i_mode)
+	    && au_opt_test(au_mntflags(sb), PLINK)
+	    && au_plink_test(inode)
+	    && !d_unhashed(cpg.dentry)
+	    && cpg.bdst < au_dbstart(cpg.dentry)) {
+		err = au_test_and_cpup_dirs(cpg.dentry, cpg.bdst);
+		if (unlikely(err))
+			goto out_unlock;
+
+		/* always superio. */
+		err = au_pin(&pin, cpg.dentry, cpg.bdst, AuOpt_UDBA_NONE,
+			     AuPin_DI_LOCKED | AuPin_MNT_WRITE);
+		if (!err) {
+			err = au_sio_cpup_simple(&cpg);
+			au_unpin(&pin);
+		}
+	} else if (hi_wh) {
+		/* already copied-up after unlink */
+		err = au_reopen_wh(file, cpg.bdst, hi_wh);
+		*need_reopen = 0;
+	}
+
+out_unlock:
+	di_read_unlock(parent, AuLock_IR);
+out_parent:
+	dput(parent);
+out:
+	return err;
+}
+
+static void au_do_refresh_dir(struct file *file)
+{
+	aufs_bindex_t bindex, bend, new_bindex, brid;
+	struct au_hfile *p, tmp, *q;
+	struct au_finfo *finfo;
+	struct super_block *sb;
+	struct au_fidir *fidir;
+
+	FiMustWriteLock(file);
+
+	sb = file->f_path.dentry->d_sb;
+	finfo = au_fi(file);
+	fidir = finfo->fi_hdir;
+	AuDebugOn(!fidir);
+	p = fidir->fd_hfile + finfo->fi_btop;
+	brid = p->hf_br->br_id;
+	bend = fidir->fd_bbot;
+	for (bindex = finfo->fi_btop; bindex <= bend; bindex++, p++) {
+		if (!p->hf_file)
+			continue;
+
+		new_bindex = au_br_index(sb, p->hf_br->br_id);
+		if (new_bindex == bindex)
+			continue;
+		if (new_bindex < 0) {
+			au_set_h_fptr(file, bindex, NULL);
+			continue;
+		}
+
+		/* swap two lower inode, and loop again */
+		q = fidir->fd_hfile + new_bindex;
+		tmp = *q;
+		*q = *p;
+		*p = tmp;
+		if (tmp.hf_file) {
+			bindex--;
+			p--;
+		}
+	}
+
+	p = fidir->fd_hfile;
+	if (!au_test_mmapped(file) && !d_unlinked(file->f_path.dentry)) {
+		bend = au_sbend(sb);
+		for (finfo->fi_btop = 0; finfo->fi_btop <= bend;
+		     finfo->fi_btop++, p++)
+			if (p->hf_file) {
+				if (file_inode(p->hf_file))
+					break;
+				au_hfput(p, file);
+			}
+	} else {
+		bend = au_br_index(sb, brid);
+		for (finfo->fi_btop = 0; finfo->fi_btop < bend;
+		     finfo->fi_btop++, p++)
+			if (p->hf_file)
+				au_hfput(p, file);
+		bend = au_sbend(sb);
+	}
+
+	p = fidir->fd_hfile + bend;
+	for (fidir->fd_bbot = bend; fidir->fd_bbot >= finfo->fi_btop;
+	     fidir->fd_bbot--, p--)
+		if (p->hf_file) {
+			if (file_inode(p->hf_file))
+				break;
+			au_hfput(p, file);
+		}
+	AuDebugOn(fidir->fd_bbot < finfo->fi_btop);
+}
+
+/*
+ * after branch manipulating, refresh the file.
+ */
+static int refresh_file(struct file *file, int (*reopen)(struct file *file))
+{
+	int err, need_reopen;
+	aufs_bindex_t bend, bindex;
+	struct dentry *dentry;
+	struct au_finfo *finfo;
+	struct au_hfile *hfile;
+
+	dentry = file->f_path.dentry;
+	finfo = au_fi(file);
+	if (!finfo->fi_hdir) {
+		hfile = &finfo->fi_htop;
+		AuDebugOn(!hfile->hf_file);
+		bindex = au_br_index(dentry->d_sb, hfile->hf_br->br_id);
+		AuDebugOn(bindex < 0);
+		if (bindex != finfo->fi_btop)
+			au_set_fbstart(file, bindex);
+	} else {
+		err = au_fidir_realloc(finfo, au_sbend(dentry->d_sb) + 1);
+		if (unlikely(err))
+			goto out;
+		au_do_refresh_dir(file);
+	}
+
+	err = 0;
+	need_reopen = 1;
+	if (!au_test_mmapped(file))
+		err = au_file_refresh_by_inode(file, &need_reopen);
+	if (!err && need_reopen && !d_unlinked(dentry))
+		err = reopen(file);
+	if (!err) {
+		au_update_figen(file);
+		goto out; /* success */
+	}
+
+	/* error, close all lower files */
+	if (finfo->fi_hdir) {
+		bend = au_fbend_dir(file);
+		for (bindex = au_fbstart(file); bindex <= bend; bindex++)
+			au_set_h_fptr(file, bindex, NULL);
+	}
+
+out:
+	return err;
+}
+
+/* common function to regular file and dir */
+int au_reval_and_lock_fdi(struct file *file, int (*reopen)(struct file *file),
+			  int wlock)
+{
+	int err;
+	unsigned int sigen, figen;
+	aufs_bindex_t bstart;
+	unsigned char pseudo_link;
+	struct dentry *dentry;
+	struct inode *inode;
+
+	err = 0;
+	dentry = file->f_path.dentry;
+	inode = d_inode(dentry);
+	sigen = au_sigen(dentry->d_sb);
+	fi_write_lock(file);
+	figen = au_figen(file);
+	di_write_lock_child(dentry);
+	bstart = au_dbstart(dentry);
+	pseudo_link = (bstart != au_ibstart(inode));
+	if (sigen == figen && !pseudo_link && au_fbstart(file) == bstart) {
+		if (!wlock) {
+			di_downgrade_lock(dentry, AuLock_IR);
+			fi_downgrade_lock(file);
+		}
+		goto out; /* success */
+	}
+
+	AuDbg("sigen %d, figen %d\n", sigen, figen);
+	if (au_digen_test(dentry, sigen)) {
+		err = au_reval_dpath(dentry, sigen);
+		AuDebugOn(!err && au_digen_test(dentry, sigen));
+	}
+
+	if (!err)
+		err = refresh_file(file, reopen);
+	if (!err) {
+		if (!wlock) {
+			di_downgrade_lock(dentry, AuLock_IR);
+			fi_downgrade_lock(file);
+		}
+	} else {
+		di_write_unlock(dentry);
+		fi_write_unlock(file);
+	}
+
+out:
+	return err;
+}
+
+/* ---------------------------------------------------------------------- */
+
+/* cf. aufs_nopage() */
+/* for madvise(2) */
+static int aufs_readpage(struct file *file __maybe_unused, struct page *page)
+{
+	unlock_page(page);
+	return 0;
+}
+
+/* it will never be called, but necessary to support O_DIRECT */
+static ssize_t aufs_direct_IO(struct kiocb *iocb, struct iov_iter *iter,
+			      loff_t offset)
+{ BUG(); return 0; }
+
+/* they will never be called. */
+#ifdef CONFIG_AUFS_DEBUG
+static int aufs_write_begin(struct file *file, struct address_space *mapping,
+			    loff_t pos, unsigned len, unsigned flags,
+			    struct page **pagep, void **fsdata)
+{ AuUnsupport(); return 0; }
+static int aufs_write_end(struct file *file, struct address_space *mapping,
+			  loff_t pos, unsigned len, unsigned copied,
+			  struct page *page, void *fsdata)
+{ AuUnsupport(); return 0; }
+static int aufs_writepage(struct page *page, struct writeback_control *wbc)
+{ AuUnsupport(); return 0; }
+
+static int aufs_set_page_dirty(struct page *page)
+{ AuUnsupport(); return 0; }
+static void aufs_invalidatepage(struct page *page, unsigned int offset,
+				unsigned int length)
+{ AuUnsupport(); }
+static int aufs_releasepage(struct page *page, gfp_t gfp)
+{ AuUnsupport(); return 0; }
+#if 0 /* called by memory compaction regardless file */
+static int aufs_migratepage(struct address_space *mapping, struct page *newpage,
+			    struct page *page, enum migrate_mode mode)
+{ AuUnsupport(); return 0; }
+#endif
+static int aufs_launder_page(struct page *page)
+{ AuUnsupport(); return 0; }
+static int aufs_is_partially_uptodate(struct page *page,
+				      unsigned long from,
+				      unsigned long count)
+{ AuUnsupport(); return 0; }
+static void aufs_is_dirty_writeback(struct page *page, bool *dirty,
+				    bool *writeback)
+{ AuUnsupport(); }
+static int aufs_error_remove_page(struct address_space *mapping,
+				  struct page *page)
+{ AuUnsupport(); return 0; }
+static int aufs_swap_activate(struct swap_info_struct *sis, struct file *file,
+			      sector_t *span)
+{ AuUnsupport(); return 0; }
+static void aufs_swap_deactivate(struct file *file)
+{ AuUnsupport(); }
+#endif /* CONFIG_AUFS_DEBUG */
+
+const struct address_space_operations aufs_aop = {
+	.readpage		= aufs_readpage,
+	.direct_IO		= aufs_direct_IO,
+#ifdef CONFIG_AUFS_DEBUG
+	.writepage		= aufs_writepage,
+	/* no writepages, because of writepage */
+	.set_page_dirty		= aufs_set_page_dirty,
+	/* no readpages, because of readpage */
+	.write_begin		= aufs_write_begin,
+	.write_end		= aufs_write_end,
+	/* no bmap, no block device */
+	.invalidatepage		= aufs_invalidatepage,
+	.releasepage		= aufs_releasepage,
+	/* is fallback_migrate_page ok? */
+	/* .migratepage		= aufs_migratepage, */
+	.launder_page		= aufs_launder_page,
+	.is_partially_uptodate	= aufs_is_partially_uptodate,
+	.is_dirty_writeback	= aufs_is_dirty_writeback,
+	.error_remove_page	= aufs_error_remove_page,
+	.swap_activate		= aufs_swap_activate,
+	.swap_deactivate	= aufs_swap_deactivate
+#endif /* CONFIG_AUFS_DEBUG */
+};
--- /dev/null
+++ zfcpdump-kernel-4.4/fs/aufs/file.h
@@ -0,0 +1,291 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+ *
+ * This program, aufs is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * file operations
+ */
+
+#ifndef __AUFS_FILE_H__
+#define __AUFS_FILE_H__
+
+#ifdef __KERNEL__
+
+#include <linux/file.h>
+#include <linux/fs.h>
+#include <linux/poll.h>
+#include "rwsem.h"
+
+struct au_branch;
+struct au_hfile {
+	struct file		*hf_file;
+	struct au_branch	*hf_br;
+};
+
+struct au_vdir;
+struct au_fidir {
+	aufs_bindex_t		fd_bbot;
+	aufs_bindex_t		fd_nent;
+	struct au_vdir		*fd_vdir_cache;
+	struct au_hfile		fd_hfile[];
+};
+
+static inline int au_fidir_sz(int nent)
+{
+	AuDebugOn(nent < 0);
+	return sizeof(struct au_fidir) + sizeof(struct au_hfile) * nent;
+}
+
+struct au_finfo {
+	atomic_t		fi_generation;
+
+	struct au_rwsem		fi_rwsem;
+	aufs_bindex_t		fi_btop;
+
+	/* do not union them */
+	struct {				/* for non-dir */
+		struct au_hfile			fi_htop;
+		atomic_t			fi_mmapped;
+	};
+	struct au_fidir		*fi_hdir;	/* for dir only */
+
+	struct hlist_node	fi_hlist;
+	struct file		*fi_file;	/* very ugly */
+} ____cacheline_aligned_in_smp;
+
+/* ---------------------------------------------------------------------- */
+
+/* file.c */
+extern const struct address_space_operations aufs_aop;
+unsigned int au_file_roflags(unsigned int flags);
+struct file *au_h_open(struct dentry *dentry, aufs_bindex_t bindex, int flags,
+		       struct file *file, int force_wr);
+struct au_do_open_args {
+	int		no_lock;
+	int		(*open)(struct file *file, int flags,
+				struct file *h_file);
+	struct au_fidir	*fidir;
+	struct file	*h_file;
+};
+int au_do_open(struct file *file, struct au_do_open_args *args);
+int au_reopen_nondir(struct file *file);
+struct au_pin;
+int au_ready_to_write(struct file *file, loff_t len, struct au_pin *pin);
+int au_reval_and_lock_fdi(struct file *file, int (*reopen)(struct file *file),
+			  int wlock);
+int au_do_flush(struct file *file, fl_owner_t id,
+		int (*flush)(struct file *file, fl_owner_t id));
+
+/* poll.c */
+#ifdef CONFIG_AUFS_POLL
+unsigned int aufs_poll(struct file *file, poll_table *wait);
+#endif
+
+#ifdef CONFIG_AUFS_BR_HFSPLUS
+/* hfsplus.c */
+struct file *au_h_open_pre(struct dentry *dentry, aufs_bindex_t bindex,
+			   int force_wr);
+void au_h_open_post(struct dentry *dentry, aufs_bindex_t bindex,
+		    struct file *h_file);
+#else
+AuStub(struct file *, au_h_open_pre, return NULL, struct dentry *dentry,
+       aufs_bindex_t bindex, int force_wr)
+AuStubVoid(au_h_open_post, struct dentry *dentry, aufs_bindex_t bindex,
+	   struct file *h_file);
+#endif
+
+/* f_op.c */
+extern const struct file_operations aufs_file_fop;
+int au_do_open_nondir(struct file *file, int flags, struct file *h_file);
+int aufs_release_nondir(struct inode *inode __maybe_unused, struct file *file);
+struct file *au_read_pre(struct file *file, int keep_fi);
+
+/* finfo.c */
+void au_hfput(struct au_hfile *hf, struct file *file);
+void au_set_h_fptr(struct file *file, aufs_bindex_t bindex,
+		   struct file *h_file);
+
+void au_update_figen(struct file *file);
+struct au_fidir *au_fidir_alloc(struct super_block *sb);
+int au_fidir_realloc(struct au_finfo *finfo, int nbr);
+
+void au_fi_init_once(void *_fi);
+void au_finfo_fin(struct file *file);
+int au_finfo_init(struct file *file, struct au_fidir *fidir);
+
+/* ioctl.c */
+long aufs_ioctl_nondir(struct file *file, unsigned int cmd, unsigned long arg);
+#ifdef CONFIG_COMPAT
+long aufs_compat_ioctl_dir(struct file *file, unsigned int cmd,
+			   unsigned long arg);
+long aufs_compat_ioctl_nondir(struct file *file, unsigned int cmd,
+			      unsigned long arg);
+#endif
+
+/* ---------------------------------------------------------------------- */
+
+static inline struct au_finfo *au_fi(struct file *file)
+{
+	return file->private_data;
+}
+
+/* ---------------------------------------------------------------------- */
+
+/*
+ * fi_read_lock, fi_write_lock,
+ * fi_read_unlock, fi_write_unlock, fi_downgrade_lock
+ */
+AuSimpleRwsemFuncs(fi, struct file *f, &au_fi(f)->fi_rwsem);
+
+#define FiMustNoWaiters(f)	AuRwMustNoWaiters(&au_fi(f)->fi_rwsem)
+#define FiMustAnyLock(f)	AuRwMustAnyLock(&au_fi(f)->fi_rwsem)
+#define FiMustWriteLock(f)	AuRwMustWriteLock(&au_fi(f)->fi_rwsem)
+
+/* ---------------------------------------------------------------------- */
+
+/* todo: hard/soft set? */
+static inline aufs_bindex_t au_fbstart(struct file *file)
+{
+	FiMustAnyLock(file);
+	return au_fi(file)->fi_btop;
+}
+
+static inline aufs_bindex_t au_fbend_dir(struct file *file)
+{
+	FiMustAnyLock(file);
+	AuDebugOn(!au_fi(file)->fi_hdir);
+	return au_fi(file)->fi_hdir->fd_bbot;
+}
+
+static inline struct au_vdir *au_fvdir_cache(struct file *file)
+{
+	FiMustAnyLock(file);
+	AuDebugOn(!au_fi(file)->fi_hdir);
+	return au_fi(file)->fi_hdir->fd_vdir_cache;
+}
+
+static inline void au_set_fbstart(struct file *file, aufs_bindex_t bindex)
+{
+	FiMustWriteLock(file);
+	au_fi(file)->fi_btop = bindex;
+}
+
+static inline void au_set_fbend_dir(struct file *file, aufs_bindex_t bindex)
+{
+	FiMustWriteLock(file);
+	AuDebugOn(!au_fi(file)->fi_hdir);
+	au_fi(file)->fi_hdir->fd_bbot = bindex;
+}
+
+static inline void au_set_fvdir_cache(struct file *file,
+				      struct au_vdir *vdir_cache)
+{
+	FiMustWriteLock(file);
+	AuDebugOn(!au_fi(file)->fi_hdir);
+	au_fi(file)->fi_hdir->fd_vdir_cache = vdir_cache;
+}
+
+static inline struct file *au_hf_top(struct file *file)
+{
+	FiMustAnyLock(file);
+	AuDebugOn(au_fi(file)->fi_hdir);
+	return au_fi(file)->fi_htop.hf_file;
+}
+
+static inline struct file *au_hf_dir(struct file *file, aufs_bindex_t bindex)
+{
+	FiMustAnyLock(file);
+	AuDebugOn(!au_fi(file)->fi_hdir);
+	return au_fi(file)->fi_hdir->fd_hfile[0 + bindex].hf_file;
+}
+
+/* todo: memory barrier? */
+static inline unsigned int au_figen(struct file *f)
+{
+	return atomic_read(&au_fi(f)->fi_generation);
+}
+
+static inline void au_set_mmapped(struct file *f)
+{
+	if (atomic_inc_return(&au_fi(f)->fi_mmapped))
+		return;
+	pr_warn("fi_mmapped wrapped around\n");
+	while (!atomic_inc_return(&au_fi(f)->fi_mmapped))
+		;
+}
+
+static inline void au_unset_mmapped(struct file *f)
+{
+	atomic_dec(&au_fi(f)->fi_mmapped);
+}
+
+static inline int au_test_mmapped(struct file *f)
+{
+	return atomic_read(&au_fi(f)->fi_mmapped);
+}
+
+/* customize vma->vm_file */
+
+static inline void au_do_vm_file_reset(struct vm_area_struct *vma,
+				       struct file *file)
+{
+	struct file *f;
+
+	f = vma->vm_file;
+	get_file(file);
+	vma->vm_file = file;
+	fput(f);
+}
+
+#ifdef CONFIG_MMU
+#define AuDbgVmRegion(file, vma) do {} while (0)
+
+static inline void au_vm_file_reset(struct vm_area_struct *vma,
+				    struct file *file)
+{
+	au_do_vm_file_reset(vma, file);
+}
+#else
+#define AuDbgVmRegion(file, vma) \
+	AuDebugOn((vma)->vm_region && (vma)->vm_region->vm_file != (file))
+
+static inline void au_vm_file_reset(struct vm_area_struct *vma,
+				    struct file *file)
+{
+	struct file *f;
+
+	au_do_vm_file_reset(vma, file);
+	f = vma->vm_region->vm_file;
+	get_file(file);
+	vma->vm_region->vm_file = file;
+	fput(f);
+}
+#endif /* CONFIG_MMU */
+
+/* handle vma->vm_prfile */
+static inline void au_vm_prfile_set(struct vm_area_struct *vma,
+				    struct file *file)
+{
+	get_file(file);
+	vma->vm_prfile = file;
+#ifndef CONFIG_MMU
+	get_file(file);
+	vma->vm_region->vm_prfile = file;
+#endif
+}
+
+#endif /* __KERNEL__ */
+#endif /* __AUFS_FILE_H__ */
--- /dev/null
+++ zfcpdump-kernel-4.4/fs/aufs/finfo.c
@@ -0,0 +1,156 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+ *
+ * This program, aufs is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * file private data
+ */
+
+#include "aufs.h"
+
+void au_hfput(struct au_hfile *hf, struct file *file)
+{
+	/* todo: direct access f_flags */
+	if (vfsub_file_flags(file) & __FMODE_EXEC)
+		allow_write_access(hf->hf_file);
+	fput(hf->hf_file);
+	hf->hf_file = NULL;
+	atomic_dec(&hf->hf_br->br_count);
+	hf->hf_br = NULL;
+}
+
+void au_set_h_fptr(struct file *file, aufs_bindex_t bindex, struct file *val)
+{
+	struct au_finfo *finfo = au_fi(file);
+	struct au_hfile *hf;
+	struct au_fidir *fidir;
+
+	fidir = finfo->fi_hdir;
+	if (!fidir) {
+		AuDebugOn(finfo->fi_btop != bindex);
+		hf = &finfo->fi_htop;
+	} else
+		hf = fidir->fd_hfile + bindex;
+
+	if (hf && hf->hf_file)
+		au_hfput(hf, file);
+	if (val) {
+		FiMustWriteLock(file);
+		AuDebugOn(IS_ERR_OR_NULL(file->f_path.dentry));
+		hf->hf_file = val;
+		hf->hf_br = au_sbr(file->f_path.dentry->d_sb, bindex);
+	}
+}
+
+void au_update_figen(struct file *file)
+{
+	atomic_set(&au_fi(file)->fi_generation, au_digen(file->f_path.dentry));
+	/* smp_mb(); */ /* atomic_set */
+}
+
+/* ---------------------------------------------------------------------- */
+
+struct au_fidir *au_fidir_alloc(struct super_block *sb)
+{
+	struct au_fidir *fidir;
+	int nbr;
+
+	nbr = au_sbend(sb) + 1;
+	if (nbr < 2)
+		nbr = 2; /* initial allocate for 2 branches */
+	fidir = kzalloc(au_fidir_sz(nbr), GFP_NOFS);
+	if (fidir) {
+		fidir->fd_bbot = -1;
+		fidir->fd_nent = nbr;
+	}
+
+	return fidir;
+}
+
+int au_fidir_realloc(struct au_finfo *finfo, int nbr)
+{
+	int err;
+	struct au_fidir *fidir, *p;
+
+	AuRwMustWriteLock(&finfo->fi_rwsem);
+	fidir = finfo->fi_hdir;
+	AuDebugOn(!fidir);
+
+	err = -ENOMEM;
+	p = au_kzrealloc(fidir, au_fidir_sz(fidir->fd_nent), au_fidir_sz(nbr),
+			 GFP_NOFS);
+	if (p) {
+		p->fd_nent = nbr;
+		finfo->fi_hdir = p;
+		err = 0;
+	}
+
+	return err;
+}
+
+/* ---------------------------------------------------------------------- */
+
+void au_finfo_fin(struct file *file)
+{
+	struct au_finfo *finfo;
+
+	au_nfiles_dec(file->f_path.dentry->d_sb);
+
+	finfo = au_fi(file);
+	AuDebugOn(finfo->fi_hdir);
+	AuRwDestroy(&finfo->fi_rwsem);
+	au_cache_free_finfo(finfo);
+}
+
+void au_fi_init_once(void *_finfo)
+{
+	struct au_finfo *finfo = _finfo;
+	static struct lock_class_key aufs_fi;
+
+	au_rw_init(&finfo->fi_rwsem);
+	au_rw_class(&finfo->fi_rwsem, &aufs_fi);
+}
+
+int au_finfo_init(struct file *file, struct au_fidir *fidir)
+{
+	int err;
+	struct au_finfo *finfo;
+	struct dentry *dentry;
+
+	err = -ENOMEM;
+	dentry = file->f_path.dentry;
+	finfo = au_cache_alloc_finfo();
+	if (unlikely(!finfo))
+		goto out;
+
+	err = 0;
+	au_nfiles_inc(dentry->d_sb);
+	/* verbose coding for lock class name */
+	if (!fidir)
+		au_rw_class(&finfo->fi_rwsem, au_lc_key + AuLcNonDir_FIINFO);
+	else
+		au_rw_class(&finfo->fi_rwsem, au_lc_key + AuLcDir_FIINFO);
+	au_rw_write_lock(&finfo->fi_rwsem);
+	finfo->fi_btop = -1;
+	finfo->fi_hdir = fidir;
+	atomic_set(&finfo->fi_generation, au_digen(dentry));
+	/* smp_mb(); */ /* atomic_set */
+
+	file->private_data = finfo;
+
+out:
+	return err;
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/fs/aufs/fstype.h
@@ -0,0 +1,400 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+ *
+ * This program, aufs is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * judging filesystem type
+ */
+
+#ifndef __AUFS_FSTYPE_H__
+#define __AUFS_FSTYPE_H__
+
+#ifdef __KERNEL__
+
+#include <linux/fs.h>
+#include <linux/magic.h>
+#include <linux/nfs_fs.h>
+#include <linux/romfs_fs.h>
+
+static inline int au_test_aufs(struct super_block *sb)
+{
+	return sb->s_magic == AUFS_SUPER_MAGIC;
+}
+
+static inline const char *au_sbtype(struct super_block *sb)
+{
+	return sb->s_type->name;
+}
+
+static inline int au_test_iso9660(struct super_block *sb __maybe_unused)
+{
+#if defined(CONFIG_ISO9660_FS) || defined(CONFIG_ISO9660_FS_MODULE)
+	return sb->s_magic == ISOFS_SUPER_MAGIC;
+#else
+	return 0;
+#endif
+}
+
+static inline int au_test_romfs(struct super_block *sb __maybe_unused)
+{
+#if defined(CONFIG_ROMFS_FS) || defined(CONFIG_ROMFS_FS_MODULE)
+	return sb->s_magic == ROMFS_MAGIC;
+#else
+	return 0;
+#endif
+}
+
+static inline int au_test_cramfs(struct super_block *sb __maybe_unused)
+{
+#if defined(CONFIG_CRAMFS) || defined(CONFIG_CRAMFS_MODULE)
+	return sb->s_magic == CRAMFS_MAGIC;
+#endif
+	return 0;
+}
+
+static inline int au_test_nfs(struct super_block *sb __maybe_unused)
+{
+#if defined(CONFIG_NFS_FS) || defined(CONFIG_NFS_FS_MODULE)
+	return sb->s_magic == NFS_SUPER_MAGIC;
+#else
+	return 0;
+#endif
+}
+
+static inline int au_test_fuse(struct super_block *sb __maybe_unused)
+{
+#if defined(CONFIG_FUSE_FS) || defined(CONFIG_FUSE_FS_MODULE)
+	return sb->s_magic == FUSE_SUPER_MAGIC;
+#else
+	return 0;
+#endif
+}
+
+static inline int au_test_xfs(struct super_block *sb __maybe_unused)
+{
+#if defined(CONFIG_XFS_FS) || defined(CONFIG_XFS_FS_MODULE)
+	return sb->s_magic == XFS_SB_MAGIC;
+#else
+	return 0;
+#endif
+}
+
+static inline int au_test_tmpfs(struct super_block *sb __maybe_unused)
+{
+#ifdef CONFIG_TMPFS
+	return sb->s_magic == TMPFS_MAGIC;
+#else
+	return 0;
+#endif
+}
+
+static inline int au_test_ecryptfs(struct super_block *sb __maybe_unused)
+{
+#if defined(CONFIG_ECRYPT_FS) || defined(CONFIG_ECRYPT_FS_MODULE)
+	return !strcmp(au_sbtype(sb), "ecryptfs");
+#else
+	return 0;
+#endif
+}
+
+static inline int au_test_ramfs(struct super_block *sb)
+{
+	return sb->s_magic == RAMFS_MAGIC;
+}
+
+static inline int au_test_ubifs(struct super_block *sb __maybe_unused)
+{
+#if defined(CONFIG_UBIFS_FS) || defined(CONFIG_UBIFS_FS_MODULE)
+	return sb->s_magic == UBIFS_SUPER_MAGIC;
+#else
+	return 0;
+#endif
+}
+
+static inline int au_test_procfs(struct super_block *sb __maybe_unused)
+{
+#ifdef CONFIG_PROC_FS
+	return sb->s_magic == PROC_SUPER_MAGIC;
+#else
+	return 0;
+#endif
+}
+
+static inline int au_test_sysfs(struct super_block *sb __maybe_unused)
+{
+#ifdef CONFIG_SYSFS
+	return sb->s_magic == SYSFS_MAGIC;
+#else
+	return 0;
+#endif
+}
+
+static inline int au_test_configfs(struct super_block *sb __maybe_unused)
+{
+#if defined(CONFIG_CONFIGFS_FS) || defined(CONFIG_CONFIGFS_FS_MODULE)
+	return sb->s_magic == CONFIGFS_MAGIC;
+#else
+	return 0;
+#endif
+}
+
+static inline int au_test_minix(struct super_block *sb __maybe_unused)
+{
+#if defined(CONFIG_MINIX_FS) || defined(CONFIG_MINIX_FS_MODULE)
+	return sb->s_magic == MINIX3_SUPER_MAGIC
+		|| sb->s_magic == MINIX2_SUPER_MAGIC
+		|| sb->s_magic == MINIX2_SUPER_MAGIC2
+		|| sb->s_magic == MINIX_SUPER_MAGIC
+		|| sb->s_magic == MINIX_SUPER_MAGIC2;
+#else
+	return 0;
+#endif
+}
+
+static inline int au_test_fat(struct super_block *sb __maybe_unused)
+{
+#if defined(CONFIG_FAT_FS) || defined(CONFIG_FAT_FS_MODULE)
+	return sb->s_magic == MSDOS_SUPER_MAGIC;
+#else
+	return 0;
+#endif
+}
+
+static inline int au_test_msdos(struct super_block *sb)
+{
+	return au_test_fat(sb);
+}
+
+static inline int au_test_vfat(struct super_block *sb)
+{
+	return au_test_fat(sb);
+}
+
+static inline int au_test_securityfs(struct super_block *sb __maybe_unused)
+{
+#ifdef CONFIG_SECURITYFS
+	return sb->s_magic == SECURITYFS_MAGIC;
+#else
+	return 0;
+#endif
+}
+
+static inline int au_test_squashfs(struct super_block *sb __maybe_unused)
+{
+#if defined(CONFIG_SQUASHFS) || defined(CONFIG_SQUASHFS_MODULE)
+	return sb->s_magic == SQUASHFS_MAGIC;
+#else
+	return 0;
+#endif
+}
+
+static inline int au_test_btrfs(struct super_block *sb __maybe_unused)
+{
+#if defined(CONFIG_BTRFS_FS) || defined(CONFIG_BTRFS_FS_MODULE)
+	return sb->s_magic == BTRFS_SUPER_MAGIC;
+#else
+	return 0;
+#endif
+}
+
+static inline int au_test_xenfs(struct super_block *sb __maybe_unused)
+{
+#if defined(CONFIG_XENFS) || defined(CONFIG_XENFS_MODULE)
+	return sb->s_magic == XENFS_SUPER_MAGIC;
+#else
+	return 0;
+#endif
+}
+
+static inline int au_test_debugfs(struct super_block *sb __maybe_unused)
+{
+#ifdef CONFIG_DEBUG_FS
+	return sb->s_magic == DEBUGFS_MAGIC;
+#else
+	return 0;
+#endif
+}
+
+static inline int au_test_nilfs(struct super_block *sb __maybe_unused)
+{
+#if defined(CONFIG_NILFS) || defined(CONFIG_NILFS_MODULE)
+	return sb->s_magic == NILFS_SUPER_MAGIC;
+#else
+	return 0;
+#endif
+}
+
+static inline int au_test_hfsplus(struct super_block *sb __maybe_unused)
+{
+#if defined(CONFIG_HFSPLUS_FS) || defined(CONFIG_HFSPLUS_FS_MODULE)
+	return sb->s_magic == HFSPLUS_SUPER_MAGIC;
+#else
+	return 0;
+#endif
+}
+
+/* ---------------------------------------------------------------------- */
+/*
+ * they can't be an aufs branch.
+ */
+static inline int au_test_fs_unsuppoted(struct super_block *sb)
+{
+	return
+#ifndef CONFIG_AUFS_BR_RAMFS
+		au_test_ramfs(sb) ||
+#endif
+		au_test_procfs(sb)
+		|| au_test_sysfs(sb)
+		|| au_test_configfs(sb)
+		|| au_test_debugfs(sb)
+		|| au_test_securityfs(sb)
+		|| au_test_xenfs(sb)
+		|| au_test_ecryptfs(sb)
+		/* || !strcmp(au_sbtype(sb), "unionfs") */
+		|| au_test_aufs(sb); /* will be supported in next version */
+}
+
+static inline int au_test_fs_remote(struct super_block *sb)
+{
+	return !au_test_tmpfs(sb)
+#ifdef CONFIG_AUFS_BR_RAMFS
+		&& !au_test_ramfs(sb)
+#endif
+		&& !(sb->s_type->fs_flags & FS_REQUIRES_DEV);
+}
+
+/* ---------------------------------------------------------------------- */
+
+/*
+ * Note: these functions (below) are created after reading ->getattr() in all
+ * filesystems under linux/fs. it means we have to do so in every update...
+ */
+
+/*
+ * some filesystems require getattr to refresh the inode attributes before
+ * referencing.
+ * in most cases, we can rely on the inode attribute in NFS (or every remote fs)
+ * and leave the work for d_revalidate()
+ */
+static inline int au_test_fs_refresh_iattr(struct super_block *sb)
+{
+	return au_test_nfs(sb)
+		|| au_test_fuse(sb)
+		/* || au_test_btrfs(sb) */	/* untested */
+		;
+}
+
+/*
+ * filesystems which don't maintain i_size or i_blocks.
+ */
+static inline int au_test_fs_bad_iattr_size(struct super_block *sb)
+{
+	return au_test_xfs(sb)
+		|| au_test_btrfs(sb)
+		|| au_test_ubifs(sb)
+		|| au_test_hfsplus(sb)	/* maintained, but incorrect */
+		/* || au_test_minix(sb) */	/* untested */
+		;
+}
+
+/*
+ * filesystems which don't store the correct value in some of their inode
+ * attributes.
+ */
+static inline int au_test_fs_bad_iattr(struct super_block *sb)
+{
+	return au_test_fs_bad_iattr_size(sb)
+		|| au_test_fat(sb)
+		|| au_test_msdos(sb)
+		|| au_test_vfat(sb);
+}
+
+/* they don't check i_nlink in link(2) */
+static inline int au_test_fs_no_limit_nlink(struct super_block *sb)
+{
+	return au_test_tmpfs(sb)
+#ifdef CONFIG_AUFS_BR_RAMFS
+		|| au_test_ramfs(sb)
+#endif
+		|| au_test_ubifs(sb)
+		|| au_test_hfsplus(sb);
+}
+
+/*
+ * filesystems which sets S_NOATIME and S_NOCMTIME.
+ */
+static inline int au_test_fs_notime(struct super_block *sb)
+{
+	return au_test_nfs(sb)
+		|| au_test_fuse(sb)
+		|| au_test_ubifs(sb)
+		;
+}
+
+/* temporary support for i#1 in cramfs */
+static inline int au_test_fs_unique_ino(struct inode *inode)
+{
+	if (au_test_cramfs(inode->i_sb))
+		return inode->i_ino != 1;
+	return 1;
+}
+
+/* ---------------------------------------------------------------------- */
+
+/*
+ * the filesystem where the xino files placed must support i/o after unlink and
+ * maintain i_size and i_blocks.
+ */
+static inline int au_test_fs_bad_xino(struct super_block *sb)
+{
+	return au_test_fs_remote(sb)
+		|| au_test_fs_bad_iattr_size(sb)
+		/* don't want unnecessary work for xino */
+		|| au_test_aufs(sb)
+		|| au_test_ecryptfs(sb)
+		|| au_test_nilfs(sb);
+}
+
+static inline int au_test_fs_trunc_xino(struct super_block *sb)
+{
+	return au_test_tmpfs(sb)
+		|| au_test_ramfs(sb);
+}
+
+/*
+ * test if the @sb is real-readonly.
+ */
+static inline int au_test_fs_rr(struct super_block *sb)
+{
+	return au_test_squashfs(sb)
+		|| au_test_iso9660(sb)
+		|| au_test_cramfs(sb)
+		|| au_test_romfs(sb);
+}
+
+/*
+ * test if the @inode is nfs with 'noacl' option
+ * NFS always sets MS_POSIXACL regardless its mount option 'noacl.'
+ */
+static inline int au_test_nfs_noacl(struct inode *inode)
+{
+	return au_test_nfs(inode->i_sb)
+		/* && IS_POSIXACL(inode) */
+		&& !nfs_server_capable(inode, NFS_CAP_ACLS);
+}
+
+#endif /* __KERNEL__ */
+#endif /* __AUFS_FSTYPE_H__ */
--- /dev/null
+++ zfcpdump-kernel-4.4/fs/aufs/hfsnotify.c
@@ -0,0 +1,288 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+ *
+ * This program, aufs is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * fsnotify for the lower directories
+ */
+
+#include "aufs.h"
+
+/* FS_IN_IGNORED is unnecessary */
+static const __u32 AuHfsnMask = (FS_MOVED_TO | FS_MOVED_FROM | FS_DELETE
+				 | FS_CREATE | FS_EVENT_ON_CHILD);
+static DECLARE_WAIT_QUEUE_HEAD(au_hfsn_wq);
+static __cacheline_aligned_in_smp atomic64_t au_hfsn_ifree = ATOMIC64_INIT(0);
+
+static void au_hfsn_free_mark(struct fsnotify_mark *mark)
+{
+	struct au_hnotify *hn = container_of(mark, struct au_hnotify,
+					     hn_mark);
+	AuDbg("here\n");
+	au_cache_free_hnotify(hn);
+	smp_mb__before_atomic();
+	if (atomic64_dec_and_test(&au_hfsn_ifree))
+		wake_up(&au_hfsn_wq);
+}
+
+static int au_hfsn_alloc(struct au_hinode *hinode)
+{
+	int err;
+	struct au_hnotify *hn;
+	struct super_block *sb;
+	struct au_branch *br;
+	struct fsnotify_mark *mark;
+	aufs_bindex_t bindex;
+
+	hn = hinode->hi_notify;
+	sb = hn->hn_aufs_inode->i_sb;
+	bindex = au_br_index(sb, hinode->hi_id);
+	br = au_sbr(sb, bindex);
+	AuDebugOn(!br->br_hfsn);
+
+	mark = &hn->hn_mark;
+	fsnotify_init_mark(mark, au_hfsn_free_mark);
+	mark->mask = AuHfsnMask;
+	/*
+	 * by udba rename or rmdir, aufs assign a new inode to the known
+	 * h_inode, so specify 1 to allow dups.
+	 */
+	lockdep_off();
+	err = fsnotify_add_mark(mark, br->br_hfsn->hfsn_group, hinode->hi_inode,
+				 /*mnt*/NULL, /*allow_dups*/1);
+	/* even if err */
+	fsnotify_put_mark(mark);
+	lockdep_on();
+
+	return err;
+}
+
+static int au_hfsn_free(struct au_hinode *hinode, struct au_hnotify *hn)
+{
+	struct fsnotify_mark *mark;
+	unsigned long long ull;
+	struct fsnotify_group *group;
+
+	ull = atomic64_inc_return(&au_hfsn_ifree);
+	BUG_ON(!ull);
+
+	mark = &hn->hn_mark;
+	spin_lock(&mark->lock);
+	group = mark->group;
+	fsnotify_get_group(group);
+	spin_unlock(&mark->lock);
+	lockdep_off();
+	fsnotify_destroy_mark(mark, group);
+	fsnotify_put_group(group);
+	lockdep_on();
+
+	/* free hn by myself */
+	return 0;
+}
+
+/* ---------------------------------------------------------------------- */
+
+static void au_hfsn_ctl(struct au_hinode *hinode, int do_set)
+{
+	struct fsnotify_mark *mark;
+
+	mark = &hinode->hi_notify->hn_mark;
+	spin_lock(&mark->lock);
+	if (do_set) {
+		AuDebugOn(mark->mask & AuHfsnMask);
+		mark->mask |= AuHfsnMask;
+	} else {
+		AuDebugOn(!(mark->mask & AuHfsnMask));
+		mark->mask &= ~AuHfsnMask;
+	}
+	spin_unlock(&mark->lock);
+	/* fsnotify_recalc_inode_mask(hinode->hi_inode); */
+}
+
+/* ---------------------------------------------------------------------- */
+
+/* #define AuDbgHnotify */
+#ifdef AuDbgHnotify
+static char *au_hfsn_name(u32 mask)
+{
+#ifdef CONFIG_AUFS_DEBUG
+#define test_ret(flag)				\
+	do {					\
+		if (mask & flag)		\
+			return #flag;		\
+	} while (0)
+	test_ret(FS_ACCESS);
+	test_ret(FS_MODIFY);
+	test_ret(FS_ATTRIB);
+	test_ret(FS_CLOSE_WRITE);
+	test_ret(FS_CLOSE_NOWRITE);
+	test_ret(FS_OPEN);
+	test_ret(FS_MOVED_FROM);
+	test_ret(FS_MOVED_TO);
+	test_ret(FS_CREATE);
+	test_ret(FS_DELETE);
+	test_ret(FS_DELETE_SELF);
+	test_ret(FS_MOVE_SELF);
+	test_ret(FS_UNMOUNT);
+	test_ret(FS_Q_OVERFLOW);
+	test_ret(FS_IN_IGNORED);
+	test_ret(FS_ISDIR);
+	test_ret(FS_IN_ONESHOT);
+	test_ret(FS_EVENT_ON_CHILD);
+	return "";
+#undef test_ret
+#else
+	return "??";
+#endif
+}
+#endif
+
+/* ---------------------------------------------------------------------- */
+
+static void au_hfsn_free_group(struct fsnotify_group *group)
+{
+	struct au_br_hfsnotify *hfsn = group->private;
+
+	AuDbg("here\n");
+	kfree(hfsn);
+}
+
+static int au_hfsn_handle_event(struct fsnotify_group *group,
+				struct inode *inode,
+				struct fsnotify_mark *inode_mark,
+				struct fsnotify_mark *vfsmount_mark,
+				u32 mask, void *data, int data_type,
+				const unsigned char *file_name, u32 cookie)
+{
+	int err;
+	struct au_hnotify *hnotify;
+	struct inode *h_dir, *h_inode;
+	struct qstr h_child_qstr = QSTR_INIT(file_name, strlen(file_name));
+
+	AuDebugOn(data_type != FSNOTIFY_EVENT_INODE);
+
+	err = 0;
+	/* if FS_UNMOUNT happens, there must be another bug */
+	AuDebugOn(mask & FS_UNMOUNT);
+	if (mask & (FS_IN_IGNORED | FS_UNMOUNT))
+		goto out;
+
+	h_dir = inode;
+	h_inode = NULL;
+#ifdef AuDbgHnotify
+	au_debug_on();
+	if (1 || h_child_qstr.len != sizeof(AUFS_XINO_FNAME) - 1
+	    || strncmp(h_child_qstr.name, AUFS_XINO_FNAME, h_child_qstr.len)) {
+		AuDbg("i%lu, mask 0x%x %s, hcname %.*s, hi%lu\n",
+		      h_dir->i_ino, mask, au_hfsn_name(mask),
+		      AuLNPair(&h_child_qstr), h_inode ? h_inode->i_ino : 0);
+		/* WARN_ON(1); */
+	}
+	au_debug_off();
+#endif
+
+	AuDebugOn(!inode_mark);
+	hnotify = container_of(inode_mark, struct au_hnotify, hn_mark);
+	err = au_hnotify(h_dir, hnotify, mask, &h_child_qstr, h_inode);
+
+out:
+	return err;
+}
+
+static struct fsnotify_ops au_hfsn_ops = {
+	.handle_event		= au_hfsn_handle_event,
+	.free_group_priv	= au_hfsn_free_group
+};
+
+/* ---------------------------------------------------------------------- */
+
+static void au_hfsn_fin_br(struct au_branch *br)
+{
+	struct au_br_hfsnotify *hfsn;
+
+	hfsn = br->br_hfsn;
+	if (hfsn) {
+		lockdep_off();
+		fsnotify_put_group(hfsn->hfsn_group);
+		lockdep_on();
+	}
+}
+
+static int au_hfsn_init_br(struct au_branch *br, int perm)
+{
+	int err;
+	struct fsnotify_group *group;
+	struct au_br_hfsnotify *hfsn;
+
+	err = 0;
+	br->br_hfsn = NULL;
+	if (!au_br_hnotifyable(perm))
+		goto out;
+
+	err = -ENOMEM;
+	hfsn = kmalloc(sizeof(*hfsn), GFP_NOFS);
+	if (unlikely(!hfsn))
+		goto out;
+
+	err = 0;
+	group = fsnotify_alloc_group(&au_hfsn_ops);
+	if (IS_ERR(group)) {
+		err = PTR_ERR(group);
+		pr_err("fsnotify_alloc_group() failed, %d\n", err);
+		goto out_hfsn;
+	}
+
+	group->private = hfsn;
+	hfsn->hfsn_group = group;
+	br->br_hfsn = hfsn;
+	goto out; /* success */
+
+out_hfsn:
+	kfree(hfsn);
+out:
+	return err;
+}
+
+static int au_hfsn_reset_br(unsigned int udba, struct au_branch *br, int perm)
+{
+	int err;
+
+	err = 0;
+	if (!br->br_hfsn)
+		err = au_hfsn_init_br(br, perm);
+
+	return err;
+}
+
+/* ---------------------------------------------------------------------- */
+
+static void au_hfsn_fin(void)
+{
+	AuDbg("au_hfsn_ifree %lld\n", (long long)atomic64_read(&au_hfsn_ifree));
+	wait_event(au_hfsn_wq, !atomic64_read(&au_hfsn_ifree));
+}
+
+const struct au_hnotify_op au_hnotify_op = {
+	.ctl		= au_hfsn_ctl,
+	.alloc		= au_hfsn_alloc,
+	.free		= au_hfsn_free,
+
+	.fin		= au_hfsn_fin,
+
+	.reset_br	= au_hfsn_reset_br,
+	.fin_br		= au_hfsn_fin_br,
+	.init_br	= au_hfsn_init_br
+};
--- /dev/null
+++ zfcpdump-kernel-4.4/fs/aufs/hfsplus.c
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2010-2015 Junjiro R. Okajima
+ *
+ * This program, aufs is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * special support for filesystems which aqucires an inode mutex
+ * at final closing a file, eg, hfsplus.
+ *
+ * This trick is very simple and stupid, just to open the file before really
+ * neceeary open to tell hfsplus that this is not the final closing.
+ * The caller should call au_h_open_pre() after acquiring the inode mutex,
+ * and au_h_open_post() after releasing it.
+ */
+
+#include "aufs.h"
+
+struct file *au_h_open_pre(struct dentry *dentry, aufs_bindex_t bindex,
+			   int force_wr)
+{
+	struct file *h_file;
+	struct dentry *h_dentry;
+
+	h_dentry = au_h_dptr(dentry, bindex);
+	AuDebugOn(!h_dentry);
+	AuDebugOn(d_is_negative(h_dentry));
+
+	h_file = NULL;
+	if (au_test_hfsplus(h_dentry->d_sb)
+	    && d_is_reg(h_dentry))
+		h_file = au_h_open(dentry, bindex,
+				   O_RDONLY | O_NOATIME | O_LARGEFILE,
+				   /*file*/NULL, force_wr);
+	return h_file;
+}
+
+void au_h_open_post(struct dentry *dentry, aufs_bindex_t bindex,
+		    struct file *h_file)
+{
+	if (h_file) {
+		fput(h_file);
+		au_sbr_put(dentry->d_sb, bindex);
+	}
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/fs/aufs/hnotify.c
@@ -0,0 +1,710 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+ *
+ * This program, aufs is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * abstraction to notify the direct changes on lower directories
+ */
+
+#include "aufs.h"
+
+int au_hn_alloc(struct au_hinode *hinode, struct inode *inode)
+{
+	int err;
+	struct au_hnotify *hn;
+
+	err = -ENOMEM;
+	hn = au_cache_alloc_hnotify();
+	if (hn) {
+		hn->hn_aufs_inode = inode;
+		hinode->hi_notify = hn;
+		err = au_hnotify_op.alloc(hinode);
+		AuTraceErr(err);
+		if (unlikely(err)) {
+			hinode->hi_notify = NULL;
+			au_cache_free_hnotify(hn);
+			/*
+			 * The upper dir was removed by udba, but the same named
+			 * dir left. In this case, aufs assignes a new inode
+			 * number and set the monitor again.
+			 * For the lower dir, the old monitnor is still left.
+			 */
+			if (err == -EEXIST)
+				err = 0;
+		}
+	}
+
+	AuTraceErr(err);
+	return err;
+}
+
+void au_hn_free(struct au_hinode *hinode)
+{
+	struct au_hnotify *hn;
+
+	hn = hinode->hi_notify;
+	if (hn) {
+		hinode->hi_notify = NULL;
+		if (au_hnotify_op.free(hinode, hn))
+			au_cache_free_hnotify(hn);
+	}
+}
+
+/* ---------------------------------------------------------------------- */
+
+void au_hn_ctl(struct au_hinode *hinode, int do_set)
+{
+	if (hinode->hi_notify)
+		au_hnotify_op.ctl(hinode, do_set);
+}
+
+void au_hn_reset(struct inode *inode, unsigned int flags)
+{
+	aufs_bindex_t bindex, bend;
+	struct inode *hi;
+	struct dentry *iwhdentry;
+
+	bend = au_ibend(inode);
+	for (bindex = au_ibstart(inode); bindex <= bend; bindex++) {
+		hi = au_h_iptr(inode, bindex);
+		if (!hi)
+			continue;
+
+		/* mutex_lock_nested(&hi->i_mutex, AuLsc_I_CHILD); */
+		iwhdentry = au_hi_wh(inode, bindex);
+		if (iwhdentry)
+			dget(iwhdentry);
+		au_igrab(hi);
+		au_set_h_iptr(inode, bindex, NULL, 0);
+		au_set_h_iptr(inode, bindex, au_igrab(hi),
+			      flags & ~AuHi_XINO);
+		iput(hi);
+		dput(iwhdentry);
+		/* mutex_unlock(&hi->i_mutex); */
+	}
+}
+
+/* ---------------------------------------------------------------------- */
+
+static int hn_xino(struct inode *inode, struct inode *h_inode)
+{
+	int err;
+	aufs_bindex_t bindex, bend, bfound, bstart;
+	struct inode *h_i;
+
+	err = 0;
+	if (unlikely(inode->i_ino == AUFS_ROOT_INO)) {
+		pr_warn("branch root dir was changed\n");
+		goto out;
+	}
+
+	bfound = -1;
+	bend = au_ibend(inode);
+	bstart = au_ibstart(inode);
+#if 0 /* reserved for future use */
+	if (bindex == bend) {
+		/* keep this ino in rename case */
+		goto out;
+	}
+#endif
+	for (bindex = bstart; bindex <= bend; bindex++)
+		if (au_h_iptr(inode, bindex) == h_inode) {
+			bfound = bindex;
+			break;
+		}
+	if (bfound < 0)
+		goto out;
+
+	for (bindex = bstart; bindex <= bend; bindex++) {
+		h_i = au_h_iptr(inode, bindex);
+		if (!h_i)
+			continue;
+
+		err = au_xino_write(inode->i_sb, bindex, h_i->i_ino, /*ino*/0);
+		/* ignore this error */
+		/* bad action? */
+	}
+
+	/* children inode number will be broken */
+
+out:
+	AuTraceErr(err);
+	return err;
+}
+
+static int hn_gen_tree(struct dentry *dentry)
+{
+	int err, i, j, ndentry;
+	struct au_dcsub_pages dpages;
+	struct au_dpage *dpage;
+	struct dentry **dentries;
+
+	err = au_dpages_init(&dpages, GFP_NOFS);
+	if (unlikely(err))
+		goto out;
+	err = au_dcsub_pages(&dpages, dentry, NULL, NULL);
+	if (unlikely(err))
+		goto out_dpages;
+
+	for (i = 0; i < dpages.ndpage; i++) {
+		dpage = dpages.dpages + i;
+		dentries = dpage->dentries;
+		ndentry = dpage->ndentry;
+		for (j = 0; j < ndentry; j++) {
+			struct dentry *d;
+
+			d = dentries[j];
+			if (IS_ROOT(d))
+				continue;
+
+			au_digen_dec(d);
+			if (d_really_is_positive(d))
+				/* todo: reset children xino?
+				   cached children only? */
+				au_iigen_dec(d_inode(d));
+		}
+	}
+
+out_dpages:
+	au_dpages_free(&dpages);
+
+#if 0
+	/* discard children */
+	dentry_unhash(dentry);
+	dput(dentry);
+#endif
+out:
+	return err;
+}
+
+/*
+ * return 0 if processed.
+ */
+static int hn_gen_by_inode(char *name, unsigned int nlen, struct inode *inode,
+			   const unsigned int isdir)
+{
+	int err;
+	struct dentry *d;
+	struct qstr *dname;
+
+	err = 1;
+	if (unlikely(inode->i_ino == AUFS_ROOT_INO)) {
+		pr_warn("branch root dir was changed\n");
+		err = 0;
+		goto out;
+	}
+
+	if (!isdir) {
+		AuDebugOn(!name);
+		au_iigen_dec(inode);
+		spin_lock(&inode->i_lock);
+		hlist_for_each_entry(d, &inode->i_dentry, d_u.d_alias) {
+			spin_lock(&d->d_lock);
+			dname = &d->d_name;
+			if (dname->len != nlen
+			    && memcmp(dname->name, name, nlen)) {
+				spin_unlock(&d->d_lock);
+				continue;
+			}
+			err = 0;
+			au_digen_dec(d);
+			spin_unlock(&d->d_lock);
+			break;
+		}
+		spin_unlock(&inode->i_lock);
+	} else {
+		au_fset_si(au_sbi(inode->i_sb), FAILED_REFRESH_DIR);
+		d = d_find_any_alias(inode);
+		if (!d) {
+			au_iigen_dec(inode);
+			goto out;
+		}
+
+		spin_lock(&d->d_lock);
+		dname = &d->d_name;
+		if (dname->len == nlen && !memcmp(dname->name, name, nlen)) {
+			spin_unlock(&d->d_lock);
+			err = hn_gen_tree(d);
+			spin_lock(&d->d_lock);
+		}
+		spin_unlock(&d->d_lock);
+		dput(d);
+	}
+
+out:
+	AuTraceErr(err);
+	return err;
+}
+
+static int hn_gen_by_name(struct dentry *dentry, const unsigned int isdir)
+{
+	int err;
+
+	if (IS_ROOT(dentry)) {
+		pr_warn("branch root dir was changed\n");
+		return 0;
+	}
+
+	err = 0;
+	if (!isdir) {
+		au_digen_dec(dentry);
+		if (d_really_is_positive(dentry))
+			au_iigen_dec(d_inode(dentry));
+	} else {
+		au_fset_si(au_sbi(dentry->d_sb), FAILED_REFRESH_DIR);
+		if (d_really_is_positive(dentry))
+			err = hn_gen_tree(dentry);
+	}
+
+	AuTraceErr(err);
+	return err;
+}
+
+/* ---------------------------------------------------------------------- */
+
+/* hnotify job flags */
+#define AuHnJob_XINO0		1
+#define AuHnJob_GEN		(1 << 1)
+#define AuHnJob_DIRENT		(1 << 2)
+#define AuHnJob_ISDIR		(1 << 3)
+#define AuHnJob_TRYXINO0	(1 << 4)
+#define AuHnJob_MNTPNT		(1 << 5)
+#define au_ftest_hnjob(flags, name)	((flags) & AuHnJob_##name)
+#define au_fset_hnjob(flags, name) \
+	do { (flags) |= AuHnJob_##name; } while (0)
+#define au_fclr_hnjob(flags, name) \
+	do { (flags) &= ~AuHnJob_##name; } while (0)
+
+enum {
+	AuHn_CHILD,
+	AuHn_PARENT,
+	AuHnLast
+};
+
+struct au_hnotify_args {
+	struct inode *h_dir, *dir, *h_child_inode;
+	u32 mask;
+	unsigned int flags[AuHnLast];
+	unsigned int h_child_nlen;
+	char h_child_name[];
+};
+
+struct hn_job_args {
+	unsigned int flags;
+	struct inode *inode, *h_inode, *dir, *h_dir;
+	struct dentry *dentry;
+	char *h_name;
+	int h_nlen;
+};
+
+static int hn_job(struct hn_job_args *a)
+{
+	const unsigned int isdir = au_ftest_hnjob(a->flags, ISDIR);
+	int e;
+
+	/* reset xino */
+	if (au_ftest_hnjob(a->flags, XINO0) && a->inode)
+		hn_xino(a->inode, a->h_inode); /* ignore this error */
+
+	if (au_ftest_hnjob(a->flags, TRYXINO0)
+	    && a->inode
+	    && a->h_inode) {
+		mutex_lock_nested(&a->h_inode->i_mutex, AuLsc_I_CHILD);
+		if (!a->h_inode->i_nlink
+		    && !(a->h_inode->i_state & I_LINKABLE))
+			hn_xino(a->inode, a->h_inode); /* ignore this error */
+		mutex_unlock(&a->h_inode->i_mutex);
+	}
+
+	/* make the generation obsolete */
+	if (au_ftest_hnjob(a->flags, GEN)) {
+		e = -1;
+		if (a->inode)
+			e = hn_gen_by_inode(a->h_name, a->h_nlen, a->inode,
+					      isdir);
+		if (e && a->dentry)
+			hn_gen_by_name(a->dentry, isdir);
+		/* ignore this error */
+	}
+
+	/* make dir entries obsolete */
+	if (au_ftest_hnjob(a->flags, DIRENT) && a->inode) {
+		struct au_vdir *vdir;
+
+		vdir = au_ivdir(a->inode);
+		if (vdir)
+			vdir->vd_jiffy = 0;
+		/* IMustLock(a->inode); */
+		/* a->inode->i_version++; */
+	}
+
+	/* can do nothing but warn */
+	if (au_ftest_hnjob(a->flags, MNTPNT)
+	    && a->dentry
+	    && d_mountpoint(a->dentry))
+		pr_warn("mount-point %pd is removed or renamed\n", a->dentry);
+
+	return 0;
+}
+
+/* ---------------------------------------------------------------------- */
+
+static struct dentry *lookup_wlock_by_name(char *name, unsigned int nlen,
+					   struct inode *dir)
+{
+	struct dentry *dentry, *d, *parent;
+	struct qstr *dname;
+
+	parent = d_find_any_alias(dir);
+	if (!parent)
+		return NULL;
+
+	dentry = NULL;
+	spin_lock(&parent->d_lock);
+	list_for_each_entry(d, &parent->d_subdirs, d_child) {
+		/* AuDbg("%pd\n", d); */
+		spin_lock_nested(&d->d_lock, DENTRY_D_LOCK_NESTED);
+		dname = &d->d_name;
+		if (dname->len != nlen || memcmp(dname->name, name, nlen))
+			goto cont_unlock;
+		if (au_di(d))
+			au_digen_dec(d);
+		else
+			goto cont_unlock;
+		if (au_dcount(d) > 0) {
+			dentry = dget_dlock(d);
+			spin_unlock(&d->d_lock);
+			break;
+		}
+
+cont_unlock:
+		spin_unlock(&d->d_lock);
+	}
+	spin_unlock(&parent->d_lock);
+	dput(parent);
+
+	if (dentry)
+		di_write_lock_child(dentry);
+
+	return dentry;
+}
+
+static struct inode *lookup_wlock_by_ino(struct super_block *sb,
+					 aufs_bindex_t bindex, ino_t h_ino)
+{
+	struct inode *inode;
+	ino_t ino;
+	int err;
+
+	inode = NULL;
+	err = au_xino_read(sb, bindex, h_ino, &ino);
+	if (!err && ino)
+		inode = ilookup(sb, ino);
+	if (!inode)
+		goto out;
+
+	if (unlikely(inode->i_ino == AUFS_ROOT_INO)) {
+		pr_warn("wrong root branch\n");
+		iput(inode);
+		inode = NULL;
+		goto out;
+	}
+
+	ii_write_lock_child(inode);
+
+out:
+	return inode;
+}
+
+static void au_hn_bh(void *_args)
+{
+	struct au_hnotify_args *a = _args;
+	struct super_block *sb;
+	aufs_bindex_t bindex, bend, bfound;
+	unsigned char xino, try_iput;
+	int err;
+	struct inode *inode;
+	ino_t h_ino;
+	struct hn_job_args args;
+	struct dentry *dentry;
+	struct au_sbinfo *sbinfo;
+
+	AuDebugOn(!_args);
+	AuDebugOn(!a->h_dir);
+	AuDebugOn(!a->dir);
+	AuDebugOn(!a->mask);
+	AuDbg("mask 0x%x, i%lu, hi%lu, hci%lu\n",
+	      a->mask, a->dir->i_ino, a->h_dir->i_ino,
+	      a->h_child_inode ? a->h_child_inode->i_ino : 0);
+
+	inode = NULL;
+	dentry = NULL;
+	/*
+	 * do not lock a->dir->i_mutex here
+	 * because of d_revalidate() may cause a deadlock.
+	 */
+	sb = a->dir->i_sb;
+	AuDebugOn(!sb);
+	sbinfo = au_sbi(sb);
+	AuDebugOn(!sbinfo);
+	si_write_lock(sb, AuLock_NOPLMW);
+
+	ii_read_lock_parent(a->dir);
+	bfound = -1;
+	bend = au_ibend(a->dir);
+	for (bindex = au_ibstart(a->dir); bindex <= bend; bindex++)
+		if (au_h_iptr(a->dir, bindex) == a->h_dir) {
+			bfound = bindex;
+			break;
+		}
+	ii_read_unlock(a->dir);
+	if (unlikely(bfound < 0))
+		goto out;
+
+	xino = !!au_opt_test(au_mntflags(sb), XINO);
+	h_ino = 0;
+	if (a->h_child_inode)
+		h_ino = a->h_child_inode->i_ino;
+
+	if (a->h_child_nlen
+	    && (au_ftest_hnjob(a->flags[AuHn_CHILD], GEN)
+		|| au_ftest_hnjob(a->flags[AuHn_CHILD], MNTPNT)))
+		dentry = lookup_wlock_by_name(a->h_child_name, a->h_child_nlen,
+					      a->dir);
+	try_iput = 0;
+	if (dentry && d_really_is_positive(dentry))
+		inode = d_inode(dentry);
+	if (xino && !inode && h_ino
+	    && (au_ftest_hnjob(a->flags[AuHn_CHILD], XINO0)
+		|| au_ftest_hnjob(a->flags[AuHn_CHILD], TRYXINO0)
+		|| au_ftest_hnjob(a->flags[AuHn_CHILD], GEN))) {
+		inode = lookup_wlock_by_ino(sb, bfound, h_ino);
+		try_iput = 1;
+	    }
+
+	args.flags = a->flags[AuHn_CHILD];
+	args.dentry = dentry;
+	args.inode = inode;
+	args.h_inode = a->h_child_inode;
+	args.dir = a->dir;
+	args.h_dir = a->h_dir;
+	args.h_name = a->h_child_name;
+	args.h_nlen = a->h_child_nlen;
+	err = hn_job(&args);
+	if (dentry) {
+		if (au_di(dentry))
+			di_write_unlock(dentry);
+		dput(dentry);
+	}
+	if (inode && try_iput) {
+		ii_write_unlock(inode);
+		iput(inode);
+	}
+
+	ii_write_lock_parent(a->dir);
+	args.flags = a->flags[AuHn_PARENT];
+	args.dentry = NULL;
+	args.inode = a->dir;
+	args.h_inode = a->h_dir;
+	args.dir = NULL;
+	args.h_dir = NULL;
+	args.h_name = NULL;
+	args.h_nlen = 0;
+	err = hn_job(&args);
+	ii_write_unlock(a->dir);
+
+out:
+	iput(a->h_child_inode);
+	iput(a->h_dir);
+	iput(a->dir);
+	si_write_unlock(sb);
+	au_nwt_done(&sbinfo->si_nowait);
+	kfree(a);
+}
+
+/* ---------------------------------------------------------------------- */
+
+int au_hnotify(struct inode *h_dir, struct au_hnotify *hnotify, u32 mask,
+	       struct qstr *h_child_qstr, struct inode *h_child_inode)
+{
+	int err, len;
+	unsigned int flags[AuHnLast], f;
+	unsigned char isdir, isroot, wh;
+	struct inode *dir;
+	struct au_hnotify_args *args;
+	char *p, *h_child_name;
+
+	err = 0;
+	AuDebugOn(!hnotify || !hnotify->hn_aufs_inode);
+	dir = igrab(hnotify->hn_aufs_inode);
+	if (!dir)
+		goto out;
+
+	isroot = (dir->i_ino == AUFS_ROOT_INO);
+	wh = 0;
+	h_child_name = (void *)h_child_qstr->name;
+	len = h_child_qstr->len;
+	if (h_child_name) {
+		if (len > AUFS_WH_PFX_LEN
+		    && !memcmp(h_child_name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)) {
+			h_child_name += AUFS_WH_PFX_LEN;
+			len -= AUFS_WH_PFX_LEN;
+			wh = 1;
+		}
+	}
+
+	isdir = 0;
+	if (h_child_inode)
+		isdir = !!S_ISDIR(h_child_inode->i_mode);
+	flags[AuHn_PARENT] = AuHnJob_ISDIR;
+	flags[AuHn_CHILD] = 0;
+	if (isdir)
+		flags[AuHn_CHILD] = AuHnJob_ISDIR;
+	au_fset_hnjob(flags[AuHn_PARENT], DIRENT);
+	au_fset_hnjob(flags[AuHn_CHILD], GEN);
+	switch (mask & FS_EVENTS_POSS_ON_CHILD) {
+	case FS_MOVED_FROM:
+	case FS_MOVED_TO:
+		au_fset_hnjob(flags[AuHn_CHILD], XINO0);
+		au_fset_hnjob(flags[AuHn_CHILD], MNTPNT);
+		/*FALLTHROUGH*/
+	case FS_CREATE:
+		AuDebugOn(!h_child_name);
+		break;
+
+	case FS_DELETE:
+		/*
+		 * aufs never be able to get this child inode.
+		 * revalidation should be in d_revalidate()
+		 * by checking i_nlink, i_generation or d_unhashed().
+		 */
+		AuDebugOn(!h_child_name);
+		au_fset_hnjob(flags[AuHn_CHILD], TRYXINO0);
+		au_fset_hnjob(flags[AuHn_CHILD], MNTPNT);
+		break;
+
+	default:
+		AuDebugOn(1);
+	}
+
+	if (wh)
+		h_child_inode = NULL;
+
+	err = -ENOMEM;
+	/* iput() and kfree() will be called in au_hnotify() */
+	args = kmalloc(sizeof(*args) + len + 1, GFP_NOFS);
+	if (unlikely(!args)) {
+		AuErr1("no memory\n");
+		iput(dir);
+		goto out;
+	}
+	args->flags[AuHn_PARENT] = flags[AuHn_PARENT];
+	args->flags[AuHn_CHILD] = flags[AuHn_CHILD];
+	args->mask = mask;
+	args->dir = dir;
+	args->h_dir = igrab(h_dir);
+	if (h_child_inode)
+		h_child_inode = igrab(h_child_inode); /* can be NULL */
+	args->h_child_inode = h_child_inode;
+	args->h_child_nlen = len;
+	if (len) {
+		p = (void *)args;
+		p += sizeof(*args);
+		memcpy(p, h_child_name, len);
+		p[len] = 0;
+	}
+
+	/* NFS fires the event for silly-renamed one from kworker */
+	f = 0;
+	if (!dir->i_nlink
+	    || (au_test_nfs(h_dir->i_sb) && (mask & FS_DELETE)))
+		f = AuWkq_NEST;
+	err = au_wkq_nowait(au_hn_bh, args, dir->i_sb, f);
+	if (unlikely(err)) {
+		pr_err("wkq %d\n", err);
+		iput(args->h_child_inode);
+		iput(args->h_dir);
+		iput(args->dir);
+		kfree(args);
+	}
+
+out:
+	return err;
+}
+
+/* ---------------------------------------------------------------------- */
+
+int au_hnotify_reset_br(unsigned int udba, struct au_branch *br, int perm)
+{
+	int err;
+
+	AuDebugOn(!(udba & AuOptMask_UDBA));
+
+	err = 0;
+	if (au_hnotify_op.reset_br)
+		err = au_hnotify_op.reset_br(udba, br, perm);
+
+	return err;
+}
+
+int au_hnotify_init_br(struct au_branch *br, int perm)
+{
+	int err;
+
+	err = 0;
+	if (au_hnotify_op.init_br)
+		err = au_hnotify_op.init_br(br, perm);
+
+	return err;
+}
+
+void au_hnotify_fin_br(struct au_branch *br)
+{
+	if (au_hnotify_op.fin_br)
+		au_hnotify_op.fin_br(br);
+}
+
+static void au_hn_destroy_cache(void)
+{
+	kmem_cache_destroy(au_cachep[AuCache_HNOTIFY]);
+	au_cachep[AuCache_HNOTIFY] = NULL;
+}
+
+int __init au_hnotify_init(void)
+{
+	int err;
+
+	err = -ENOMEM;
+	au_cachep[AuCache_HNOTIFY] = AuCache(au_hnotify);
+	if (au_cachep[AuCache_HNOTIFY]) {
+		err = 0;
+		if (au_hnotify_op.init)
+			err = au_hnotify_op.init();
+		if (unlikely(err))
+			au_hn_destroy_cache();
+	}
+	AuTraceErr(err);
+	return err;
+}
+
+void au_hnotify_fin(void)
+{
+	if (au_hnotify_op.fin)
+		au_hnotify_op.fin();
+	/* cf. au_cache_fin() */
+	if (au_cachep[AuCache_HNOTIFY])
+		au_hn_destroy_cache();
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/fs/aufs/i_op.c
@@ -0,0 +1,1484 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+ *
+ * This program, aufs is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * inode operations (except add/del/rename)
+ */
+
+#include <linux/device_cgroup.h>
+#include <linux/fs_stack.h>
+#include <linux/namei.h>
+#include <linux/security.h>
+#include "aufs.h"
+
+static int h_permission(struct inode *h_inode, int mask,
+			struct path *h_path, int brperm)
+{
+	int err;
+	const unsigned char write_mask = !!(mask & (MAY_WRITE | MAY_APPEND));
+
+	err = -EACCES;
+	if ((write_mask && IS_IMMUTABLE(h_inode))
+	    || ((mask & MAY_EXEC)
+		&& S_ISREG(h_inode->i_mode)
+		&& (path_noexec(h_path)
+		    || !(h_inode->i_mode & S_IXUGO))))
+		goto out;
+
+	/*
+	 * - skip the lower fs test in the case of write to ro branch.
+	 * - nfs dir permission write check is optimized, but a policy for
+	 *   link/rename requires a real check.
+	 * - nfs always sets MS_POSIXACL regardless its mount option 'noacl.'
+	 *   in this case, generic_permission() returns -EOPNOTSUPP.
+	 */
+	if ((write_mask && !au_br_writable(brperm))
+	    || (au_test_nfs(h_inode->i_sb) && S_ISDIR(h_inode->i_mode)
+		&& write_mask && !(mask & MAY_READ))
+	    || !h_inode->i_op->permission) {
+		/* AuLabel(generic_permission); */
+		/* AuDbg("get_acl %pf\n", h_inode->i_op->get_acl); */
+		err = generic_permission(h_inode, mask);
+		if (err == -EOPNOTSUPP && au_test_nfs_noacl(h_inode))
+			err = h_inode->i_op->permission(h_inode, mask);
+		AuTraceErr(err);
+	} else {
+		/* AuLabel(h_inode->permission); */
+		err = h_inode->i_op->permission(h_inode, mask);
+		AuTraceErr(err);
+	}
+
+	if (!err)
+		err = devcgroup_inode_permission(h_inode, mask);
+	if (!err)
+		err = security_inode_permission(h_inode, mask);
+
+#if 0
+	if (!err) {
+		/* todo: do we need to call ima_path_check()? */
+		struct path h_path = {
+			.dentry	=
+			.mnt	= h_mnt
+		};
+		err = ima_path_check(&h_path,
+				     mask & (MAY_READ | MAY_WRITE | MAY_EXEC),
+				     IMA_COUNT_LEAVE);
+	}
+#endif
+
+out:
+	return err;
+}
+
+static int aufs_permission(struct inode *inode, int mask)
+{
+	int err;
+	aufs_bindex_t bindex, bend;
+	const unsigned char isdir = !!S_ISDIR(inode->i_mode),
+		write_mask = !!(mask & (MAY_WRITE | MAY_APPEND));
+	struct inode *h_inode;
+	struct super_block *sb;
+	struct au_branch *br;
+
+	/* todo: support rcu-walk? */
+	if (mask & MAY_NOT_BLOCK)
+		return -ECHILD;
+
+	sb = inode->i_sb;
+	si_read_lock(sb, AuLock_FLUSH);
+	ii_read_lock_child(inode);
+#if 0
+	err = au_iigen_test(inode, au_sigen(sb));
+	if (unlikely(err))
+		goto out;
+#endif
+
+	if (!isdir
+	    || write_mask
+	    || au_opt_test(au_mntflags(sb), DIRPERM1)) {
+		err = au_busy_or_stale();
+		h_inode = au_h_iptr(inode, au_ibstart(inode));
+		if (unlikely(!h_inode
+			     || (h_inode->i_mode & S_IFMT)
+			     != (inode->i_mode & S_IFMT)))
+			goto out;
+
+		err = 0;
+		bindex = au_ibstart(inode);
+		br = au_sbr(sb, bindex);
+		err = h_permission(h_inode, mask, &br->br_path, br->br_perm);
+		if (write_mask
+		    && !err
+		    && !special_file(h_inode->i_mode)) {
+			/* test whether the upper writable branch exists */
+			err = -EROFS;
+			for (; bindex >= 0; bindex--)
+				if (!au_br_rdonly(au_sbr(sb, bindex))) {
+					err = 0;
+					break;
+				}
+		}
+		goto out;
+	}
+
+	/* non-write to dir */
+	err = 0;
+	bend = au_ibend(inode);
+	for (bindex = au_ibstart(inode); !err && bindex <= bend; bindex++) {
+		h_inode = au_h_iptr(inode, bindex);
+		if (h_inode) {
+			err = au_busy_or_stale();
+			if (unlikely(!S_ISDIR(h_inode->i_mode)))
+				break;
+
+			br = au_sbr(sb, bindex);
+			err = h_permission(h_inode, mask, &br->br_path,
+					   br->br_perm);
+		}
+	}
+
+out:
+	ii_read_unlock(inode);
+	si_read_unlock(sb);
+	return err;
+}
+
+/* ---------------------------------------------------------------------- */
+
+static struct dentry *aufs_lookup(struct inode *dir, struct dentry *dentry,
+				  unsigned int flags)
+{
+	struct dentry *ret, *parent;
+	struct inode *inode;
+	struct super_block *sb;
+	int err, npositive;
+
+	IMustLock(dir);
+
+	/* todo: support rcu-walk? */
+	ret = ERR_PTR(-ECHILD);
+	if (flags & LOOKUP_RCU)
+		goto out;
+
+	ret = ERR_PTR(-ENAMETOOLONG);
+	if (unlikely(dentry->d_name.len > AUFS_MAX_NAMELEN))
+		goto out;
+
+	sb = dir->i_sb;
+	err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
+	ret = ERR_PTR(err);
+	if (unlikely(err))
+		goto out;
+
+	err = au_di_init(dentry);
+	ret = ERR_PTR(err);
+	if (unlikely(err))
+		goto out_si;
+
+	inode = NULL;
+	npositive = 0; /* suppress a warning */
+	parent = dentry->d_parent; /* dir inode is locked */
+	di_read_lock_parent(parent, AuLock_IR);
+	err = au_alive_dir(parent);
+	if (!err)
+		err = au_digen_test(parent, au_sigen(sb));
+	if (!err) {
+		npositive = au_lkup_dentry(dentry, au_dbstart(parent),
+					   /*type*/0);
+		err = npositive;
+	}
+	di_read_unlock(parent, AuLock_IR);
+	ret = ERR_PTR(err);
+	if (unlikely(err < 0))
+		goto out_unlock;
+
+	if (npositive) {
+		inode = au_new_inode(dentry, /*must_new*/0);
+		if (IS_ERR(inode)) {
+			ret = (void *)inode;
+			inode = NULL;
+			goto out_unlock;
+		}
+	}
+
+	if (inode)
+		atomic_inc(&inode->i_count);
+	ret = d_splice_alias(inode, dentry);
+#if 0
+	if (unlikely(d_need_lookup(dentry))) {
+		spin_lock(&dentry->d_lock);
+		dentry->d_flags &= ~DCACHE_NEED_LOOKUP;
+		spin_unlock(&dentry->d_lock);
+	} else
+#endif
+	if (inode) {
+		if (!IS_ERR(ret)) {
+			iput(inode);
+			if (ret && ret != dentry)
+				ii_write_unlock(inode);
+		} else {
+			ii_write_unlock(inode);
+			iput(inode);
+			inode = NULL;
+		}
+	}
+
+out_unlock:
+	di_write_unlock(dentry);
+	if (inode) {
+		/* verbose coding for lock class name */
+		if (unlikely(S_ISLNK(inode->i_mode)))
+			au_rw_class(&au_di(dentry)->di_rwsem,
+				    au_lc_key + AuLcSymlink_DIINFO);
+		else if (unlikely(S_ISDIR(inode->i_mode)))
+			au_rw_class(&au_di(dentry)->di_rwsem,
+				    au_lc_key + AuLcDir_DIINFO);
+		else /* likely */
+			au_rw_class(&au_di(dentry)->di_rwsem,
+				    au_lc_key + AuLcNonDir_DIINFO);
+	}
+out_si:
+	si_read_unlock(sb);
+out:
+	return ret;
+}
+
+/* ---------------------------------------------------------------------- */
+
+struct aopen_node {
+	struct hlist_node hlist;
+	struct file *file, *h_file;
+};
+
+static int au_do_aopen(struct inode *inode, struct file *file)
+{
+	struct au_sphlhead *aopen;
+	struct aopen_node *node;
+	struct au_do_open_args args = {
+		.no_lock	= 1,
+		.open		= au_do_open_nondir
+	};
+
+	aopen = &au_sbi(inode->i_sb)->si_aopen;
+	spin_lock(&aopen->spin);
+	hlist_for_each_entry(node, &aopen->head, hlist)
+		if (node->file == file) {
+			args.h_file = node->h_file;
+			break;
+		}
+	spin_unlock(&aopen->spin);
+	/* AuDebugOn(!args.h_file); */
+
+	return au_do_open(file, &args);
+}
+
+static int aufs_atomic_open(struct inode *dir, struct dentry *dentry,
+			    struct file *file, unsigned int open_flag,
+			    umode_t create_mode, int *opened)
+{
+	int err, h_opened = *opened;
+	struct dentry *parent;
+	struct dentry *d;
+	struct au_sphlhead *aopen;
+	struct vfsub_aopen_args args = {
+		.open_flag	= open_flag,
+		.create_mode	= create_mode,
+		.opened		= &h_opened
+	};
+	struct aopen_node aopen_node = {
+		.file	= file
+	};
+
+	IMustLock(dir);
+	AuDbg("open_flag 0x%x\n", open_flag);
+	AuDbgDentry(dentry);
+
+	err = 0;
+	if (!au_di(dentry)) {
+		d = aufs_lookup(dir, dentry, /*flags*/0);
+		if (IS_ERR(d)) {
+			err = PTR_ERR(d);
+			goto out;
+		} else if (d) {
+			/*
+			 * obsoleted dentry found.
+			 * another error will be returned later.
+			 */
+			d_drop(d);
+			dput(d);
+			AuDbgDentry(d);
+		}
+		AuDbgDentry(dentry);
+	}
+
+	if (d_is_positive(dentry)
+	    || d_unhashed(dentry)
+	    || d_unlinked(dentry)
+	    || !(open_flag & O_CREAT))
+		goto out_no_open;
+
+	err = aufs_read_lock(dentry, AuLock_DW | AuLock_FLUSH | AuLock_GEN);
+	if (unlikely(err))
+		goto out;
+
+	parent = dentry->d_parent;	/* dir is locked */
+	di_write_lock_parent(parent);
+	err = au_lkup_dentry(dentry, /*bstart*/0, /*type*/0);
+	if (unlikely(err))
+		goto out_unlock;
+
+	AuDbgDentry(dentry);
+	if (d_is_positive(dentry))
+		goto out_unlock;
+
+	args.file = get_empty_filp();
+	err = PTR_ERR(args.file);
+	if (IS_ERR(args.file))
+		goto out_unlock;
+
+	args.file->f_flags = file->f_flags;
+	err = au_aopen_or_create(dir, dentry, &args);
+	AuTraceErr(err);
+	AuDbgFile(args.file);
+	if (unlikely(err < 0)) {
+		if (h_opened & FILE_OPENED)
+			fput(args.file);
+		else
+			put_filp(args.file);
+		goto out_unlock;
+	}
+
+	/* some filesystems don't set FILE_CREATED while succeeded? */
+	*opened |= FILE_CREATED;
+	if (h_opened & FILE_OPENED)
+		aopen_node.h_file = args.file;
+	else {
+		put_filp(args.file);
+		args.file = NULL;
+	}
+	aopen = &au_sbi(dir->i_sb)->si_aopen;
+	au_sphl_add(&aopen_node.hlist, aopen);
+	err = finish_open(file, dentry, au_do_aopen, opened);
+	au_sphl_del(&aopen_node.hlist, aopen);
+	AuTraceErr(err);
+	AuDbgFile(file);
+	if (aopen_node.h_file)
+		fput(aopen_node.h_file);
+
+out_unlock:
+	di_write_unlock(parent);
+	aufs_read_unlock(dentry, AuLock_DW);
+	AuDbgDentry(dentry);
+	if (unlikely(err))
+		goto out;
+out_no_open:
+	if (!err && !(*opened & FILE_CREATED)) {
+		AuLabel(out_no_open);
+		dget(dentry);
+		err = finish_no_open(file, dentry);
+	}
+out:
+	AuDbg("%pd%s%s\n", dentry,
+	      (*opened & FILE_CREATED) ? " created" : "",
+	      (*opened & FILE_OPENED) ? " opened" : "");
+	AuTraceErr(err);
+	return err;
+}
+
+
+/* ---------------------------------------------------------------------- */
+
+static int au_wr_dir_cpup(struct dentry *dentry, struct dentry *parent,
+			  const unsigned char add_entry, aufs_bindex_t bcpup,
+			  aufs_bindex_t bstart)
+{
+	int err;
+	struct dentry *h_parent;
+	struct inode *h_dir;
+
+	if (add_entry)
+		IMustLock(d_inode(parent));
+	else
+		di_write_lock_parent(parent);
+
+	err = 0;
+	if (!au_h_dptr(parent, bcpup)) {
+		if (bstart > bcpup)
+			err = au_cpup_dirs(dentry, bcpup);
+		else if (bstart < bcpup)
+			err = au_cpdown_dirs(dentry, bcpup);
+		else
+			BUG();
+	}
+	if (!err && add_entry && !au_ftest_wrdir(add_entry, TMPFILE)) {
+		h_parent = au_h_dptr(parent, bcpup);
+		h_dir = d_inode(h_parent);
+		mutex_lock_nested(&h_dir->i_mutex, AuLsc_I_PARENT);
+		err = au_lkup_neg(dentry, bcpup, /*wh*/0);
+		/* todo: no unlock here */
+		mutex_unlock(&h_dir->i_mutex);
+
+		AuDbg("bcpup %d\n", bcpup);
+		if (!err) {
+			if (d_really_is_negative(dentry))
+				au_set_h_dptr(dentry, bstart, NULL);
+			au_update_dbrange(dentry, /*do_put_zero*/0);
+		}
+	}
+
+	if (!add_entry)
+		di_write_unlock(parent);
+	if (!err)
+		err = bcpup; /* success */
+
+	AuTraceErr(err);
+	return err;
+}
+
+/*
+ * decide the branch and the parent dir where we will create a new entry.
+ * returns new bindex or an error.
+ * copyup the parent dir if needed.
+ */
+int au_wr_dir(struct dentry *dentry, struct dentry *src_dentry,
+	      struct au_wr_dir_args *args)
+{
+	int err;
+	unsigned int flags;
+	aufs_bindex_t bcpup, bstart, src_bstart;
+	const unsigned char add_entry
+		= au_ftest_wrdir(args->flags, ADD_ENTRY)
+		| au_ftest_wrdir(args->flags, TMPFILE);
+	struct super_block *sb;
+	struct dentry *parent;
+	struct au_sbinfo *sbinfo;
+
+	sb = dentry->d_sb;
+	sbinfo = au_sbi(sb);
+	parent = dget_parent(dentry);
+	bstart = au_dbstart(dentry);
+	bcpup = bstart;
+	if (args->force_btgt < 0) {
+		if (src_dentry) {
+			src_bstart = au_dbstart(src_dentry);
+			if (src_bstart < bstart)
+				bcpup = src_bstart;
+		} else if (add_entry) {
+			flags = 0;
+			if (au_ftest_wrdir(args->flags, ISDIR))
+				au_fset_wbr(flags, DIR);
+			err = AuWbrCreate(sbinfo, dentry, flags);
+			bcpup = err;
+		}
+
+		if (bcpup < 0 || au_test_ro(sb, bcpup, d_inode(dentry))) {
+			if (add_entry)
+				err = AuWbrCopyup(sbinfo, dentry);
+			else {
+				if (!IS_ROOT(dentry)) {
+					di_read_lock_parent(parent, !AuLock_IR);
+					err = AuWbrCopyup(sbinfo, dentry);
+					di_read_unlock(parent, !AuLock_IR);
+				} else
+					err = AuWbrCopyup(sbinfo, dentry);
+			}
+			bcpup = err;
+			if (unlikely(err < 0))
+				goto out;
+		}
+	} else {
+		bcpup = args->force_btgt;
+		AuDebugOn(au_test_ro(sb, bcpup, d_inode(dentry)));
+	}
+
+	AuDbg("bstart %d, bcpup %d\n", bstart, bcpup);
+	err = bcpup;
+	if (bcpup == bstart)
+		goto out; /* success */
+
+	/* copyup the new parent into the branch we process */
+	err = au_wr_dir_cpup(dentry, parent, add_entry, bcpup, bstart);
+	if (err >= 0) {
+		if (d_really_is_negative(dentry)) {
+			au_set_h_dptr(dentry, bstart, NULL);
+			au_set_dbstart(dentry, bcpup);
+			au_set_dbend(dentry, bcpup);
+		}
+		AuDebugOn(add_entry
+			  && !au_ftest_wrdir(args->flags, TMPFILE)
+			  && !au_h_dptr(dentry, bcpup));
+	}
+
+out:
+	dput(parent);
+	return err;
+}
+
+/* ---------------------------------------------------------------------- */
+
+void au_pin_hdir_unlock(struct au_pin *p)
+{
+	if (p->hdir)
+		au_hn_imtx_unlock(p->hdir);
+}
+
+int au_pin_hdir_lock(struct au_pin *p)
+{
+	int err;
+
+	err = 0;
+	if (!p->hdir)
+		goto out;
+
+	/* even if an error happens later, keep this lock */
+	au_hn_imtx_lock_nested(p->hdir, p->lsc_hi);
+
+	err = -EBUSY;
+	if (unlikely(p->hdir->hi_inode != d_inode(p->h_parent)))
+		goto out;
+
+	err = 0;
+	if (p->h_dentry)
+		err = au_h_verify(p->h_dentry, p->udba, p->hdir->hi_inode,
+				  p->h_parent, p->br);
+
+out:
+	return err;
+}
+
+int au_pin_hdir_relock(struct au_pin *p)
+{
+	int err, i;
+	struct inode *h_i;
+	struct dentry *h_d[] = {
+		p->h_dentry,
+		p->h_parent
+	};
+
+	err = au_pin_hdir_lock(p);
+	if (unlikely(err))
+		goto out;
+
+	for (i = 0; !err && i < sizeof(h_d)/sizeof(*h_d); i++) {
+		if (!h_d[i])
+			continue;
+		if (d_is_positive(h_d[i])) {
+			h_i = d_inode(h_d[i]);
+			err = !h_i->i_nlink;
+		}
+	}
+
+out:
+	return err;
+}
+
+void au_pin_hdir_set_owner(struct au_pin *p, struct task_struct *task)
+{
+#if defined(CONFIG_DEBUG_MUTEXES) || defined(CONFIG_SMP)
+	p->hdir->hi_inode->i_mutex.owner = task;
+#endif
+}
+
+void au_pin_hdir_acquire_nest(struct au_pin *p)
+{
+	if (p->hdir) {
+		mutex_acquire_nest(&p->hdir->hi_inode->i_mutex.dep_map,
+				   p->lsc_hi, 0, NULL, _RET_IP_);
+		au_pin_hdir_set_owner(p, current);
+	}
+}
+
+void au_pin_hdir_release(struct au_pin *p)
+{
+	if (p->hdir) {
+		au_pin_hdir_set_owner(p, p->task);
+		mutex_release(&p->hdir->hi_inode->i_mutex.dep_map, 1, _RET_IP_);
+	}
+}
+
+struct dentry *au_pinned_h_parent(struct au_pin *pin)
+{
+	if (pin && pin->parent)
+		return au_h_dptr(pin->parent, pin->bindex);
+	return NULL;
+}
+
+void au_unpin(struct au_pin *p)
+{
+	if (p->hdir)
+		au_pin_hdir_unlock(p);
+	if (p->h_mnt && au_ftest_pin(p->flags, MNT_WRITE))
+		vfsub_mnt_drop_write(p->h_mnt);
+	if (!p->hdir)
+		return;
+
+	if (!au_ftest_pin(p->flags, DI_LOCKED))
+		di_read_unlock(p->parent, AuLock_IR);
+	iput(p->hdir->hi_inode);
+	dput(p->parent);
+	p->parent = NULL;
+	p->hdir = NULL;
+	p->h_mnt = NULL;
+	/* do not clear p->task */
+}
+
+int au_do_pin(struct au_pin *p)
+{
+	int err;
+	struct super_block *sb;
+	struct inode *h_dir;
+
+	err = 0;
+	sb = p->dentry->d_sb;
+	p->br = au_sbr(sb, p->bindex);
+	if (IS_ROOT(p->dentry)) {
+		if (au_ftest_pin(p->flags, MNT_WRITE)) {
+			p->h_mnt = au_br_mnt(p->br);
+			err = vfsub_mnt_want_write(p->h_mnt);
+			if (unlikely(err)) {
+				au_fclr_pin(p->flags, MNT_WRITE);
+				goto out_err;
+			}
+		}
+		goto out;
+	}
+
+	p->h_dentry = NULL;
+	if (p->bindex <= au_dbend(p->dentry))
+		p->h_dentry = au_h_dptr(p->dentry, p->bindex);
+
+	p->parent = dget_parent(p->dentry);
+	if (!au_ftest_pin(p->flags, DI_LOCKED))
+		di_read_lock(p->parent, AuLock_IR, p->lsc_di);
+
+	h_dir = NULL;
+	p->h_parent = au_h_dptr(p->parent, p->bindex);
+	p->hdir = au_hi(d_inode(p->parent), p->bindex);
+	if (p->hdir)
+		h_dir = p->hdir->hi_inode;
+
+	/*
+	 * udba case, or
+	 * if DI_LOCKED is not set, then p->parent may be different
+	 * and h_parent can be NULL.
+	 */
+	if (unlikely(!p->hdir || !h_dir || !p->h_parent)) {
+		err = -EBUSY;
+		if (!au_ftest_pin(p->flags, DI_LOCKED))
+			di_read_unlock(p->parent, AuLock_IR);
+		dput(p->parent);
+		p->parent = NULL;
+		goto out_err;
+	}
+
+	if (au_ftest_pin(p->flags, MNT_WRITE)) {
+		p->h_mnt = au_br_mnt(p->br);
+		err = vfsub_mnt_want_write(p->h_mnt);
+		if (unlikely(err)) {
+			au_fclr_pin(p->flags, MNT_WRITE);
+			if (!au_ftest_pin(p->flags, DI_LOCKED))
+				di_read_unlock(p->parent, AuLock_IR);
+			dput(p->parent);
+			p->parent = NULL;
+			goto out_err;
+		}
+	}
+
+	au_igrab(h_dir);
+	err = au_pin_hdir_lock(p);
+	if (!err)
+		goto out; /* success */
+
+	au_unpin(p);
+
+out_err:
+	pr_err("err %d\n", err);
+	err = au_busy_or_stale();
+out:
+	return err;
+}
+
+void au_pin_init(struct au_pin *p, struct dentry *dentry,
+		 aufs_bindex_t bindex, int lsc_di, int lsc_hi,
+		 unsigned int udba, unsigned char flags)
+{
+	p->dentry = dentry;
+	p->udba = udba;
+	p->lsc_di = lsc_di;
+	p->lsc_hi = lsc_hi;
+	p->flags = flags;
+	p->bindex = bindex;
+
+	p->parent = NULL;
+	p->hdir = NULL;
+	p->h_mnt = NULL;
+
+	p->h_dentry = NULL;
+	p->h_parent = NULL;
+	p->br = NULL;
+	p->task = current;
+}
+
+int au_pin(struct au_pin *pin, struct dentry *dentry, aufs_bindex_t bindex,
+	   unsigned int udba, unsigned char flags)
+{
+	au_pin_init(pin, dentry, bindex, AuLsc_DI_PARENT, AuLsc_I_PARENT2,
+		    udba, flags);
+	return au_do_pin(pin);
+}
+
+/* ---------------------------------------------------------------------- */
+
+/*
+ * ->setattr() and ->getattr() are called in various cases.
+ * chmod, stat: dentry is revalidated.
+ * fchmod, fstat: file and dentry are not revalidated, additionally they may be
+ *		  unhashed.
+ * for ->setattr(), ia->ia_file is passed from ftruncate only.
+ */
+/* todo: consolidate with do_refresh() and simple_reval_dpath() */
+int au_reval_for_attr(struct dentry *dentry, unsigned int sigen)
+{
+	int err;
+	struct dentry *parent;
+
+	err = 0;
+	if (au_digen_test(dentry, sigen)) {
+		parent = dget_parent(dentry);
+		di_read_lock_parent(parent, AuLock_IR);
+		err = au_refresh_dentry(dentry, parent);
+		di_read_unlock(parent, AuLock_IR);
+		dput(parent);
+	}
+
+	AuTraceErr(err);
+	return err;
+}
+
+int au_pin_and_icpup(struct dentry *dentry, struct iattr *ia,
+		     struct au_icpup_args *a)
+{
+	int err;
+	loff_t sz;
+	aufs_bindex_t bstart, ibstart;
+	struct dentry *hi_wh, *parent;
+	struct inode *inode;
+	struct au_wr_dir_args wr_dir_args = {
+		.force_btgt	= -1,
+		.flags		= 0
+	};
+
+	if (d_is_dir(dentry))
+		au_fset_wrdir(wr_dir_args.flags, ISDIR);
+	/* plink or hi_wh() case */
+	bstart = au_dbstart(dentry);
+	inode = d_inode(dentry);
+	ibstart = au_ibstart(inode);
+	if (bstart != ibstart && !au_test_ro(inode->i_sb, ibstart, inode))
+		wr_dir_args.force_btgt = ibstart;
+	err = au_wr_dir(dentry, /*src_dentry*/NULL, &wr_dir_args);
+	if (unlikely(err < 0))
+		goto out;
+	a->btgt = err;
+	if (err != bstart)
+		au_fset_icpup(a->flags, DID_CPUP);
+
+	err = 0;
+	a->pin_flags = AuPin_MNT_WRITE;
+	parent = NULL;
+	if (!IS_ROOT(dentry)) {
+		au_fset_pin(a->pin_flags, DI_LOCKED);
+		parent = dget_parent(dentry);
+		di_write_lock_parent(parent);
+	}
+
+	err = au_pin(&a->pin, dentry, a->btgt, a->udba, a->pin_flags);
+	if (unlikely(err))
+		goto out_parent;
+
+	a->h_path.dentry = au_h_dptr(dentry, bstart);
+	sz = -1;
+	a->h_inode = d_inode(a->h_path.dentry);
+	if (ia && (ia->ia_valid & ATTR_SIZE)) {
+		mutex_lock_nested(&a->h_inode->i_mutex, AuLsc_I_CHILD);
+		if (ia->ia_size < i_size_read(a->h_inode))
+			sz = ia->ia_size;
+		mutex_unlock(&a->h_inode->i_mutex);
+	}
+
+	hi_wh = NULL;
+	if (au_ftest_icpup(a->flags, DID_CPUP) && d_unlinked(dentry)) {
+		hi_wh = au_hi_wh(inode, a->btgt);
+		if (!hi_wh) {
+			struct au_cp_generic cpg = {
+				.dentry	= dentry,
+				.bdst	= a->btgt,
+				.bsrc	= -1,
+				.len	= sz,
+				.pin	= &a->pin
+			};
+			err = au_sio_cpup_wh(&cpg, /*file*/NULL);
+			if (unlikely(err))
+				goto out_unlock;
+			hi_wh = au_hi_wh(inode, a->btgt);
+			/* todo: revalidate hi_wh? */
+		}
+	}
+
+	if (parent) {
+		au_pin_set_parent_lflag(&a->pin, /*lflag*/0);
+		di_downgrade_lock(parent, AuLock_IR);
+		dput(parent);
+		parent = NULL;
+	}
+	if (!au_ftest_icpup(a->flags, DID_CPUP))
+		goto out; /* success */
+
+	if (!d_unhashed(dentry)) {
+		struct au_cp_generic cpg = {
+			.dentry	= dentry,
+			.bdst	= a->btgt,
+			.bsrc	= bstart,
+			.len	= sz,
+			.pin	= &a->pin,
+			.flags	= AuCpup_DTIME | AuCpup_HOPEN
+		};
+		err = au_sio_cpup_simple(&cpg);
+		if (!err)
+			a->h_path.dentry = au_h_dptr(dentry, a->btgt);
+	} else if (!hi_wh)
+		a->h_path.dentry = au_h_dptr(dentry, a->btgt);
+	else
+		a->h_path.dentry = hi_wh; /* do not dget here */
+
+out_unlock:
+	a->h_inode = d_inode(a->h_path.dentry);
+	if (!err)
+		goto out; /* success */
+	au_unpin(&a->pin);
+out_parent:
+	if (parent) {
+		di_write_unlock(parent);
+		dput(parent);
+	}
+out:
+	if (!err)
+		mutex_lock_nested(&a->h_inode->i_mutex, AuLsc_I_CHILD);
+	return err;
+}
+
+static int aufs_setattr(struct dentry *dentry, struct iattr *ia)
+{
+	int err;
+	struct inode *inode, *delegated;
+	struct super_block *sb;
+	struct file *file;
+	struct au_icpup_args *a;
+
+	inode = d_inode(dentry);
+	IMustLock(inode);
+
+	err = -ENOMEM;
+	a = kzalloc(sizeof(*a), GFP_NOFS);
+	if (unlikely(!a))
+		goto out;
+
+	if (ia->ia_valid & (ATTR_KILL_SUID | ATTR_KILL_SGID))
+		ia->ia_valid &= ~ATTR_MODE;
+
+	file = NULL;
+	sb = dentry->d_sb;
+	err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
+	if (unlikely(err))
+		goto out_kfree;
+
+	if (ia->ia_valid & ATTR_FILE) {
+		/* currently ftruncate(2) only */
+		AuDebugOn(!d_is_reg(dentry));
+		file = ia->ia_file;
+		err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1);
+		if (unlikely(err))
+			goto out_si;
+		ia->ia_file = au_hf_top(file);
+		a->udba = AuOpt_UDBA_NONE;
+	} else {
+		/* fchmod() doesn't pass ia_file */
+		a->udba = au_opt_udba(sb);
+		di_write_lock_child(dentry);
+		/* no d_unlinked(), to set UDBA_NONE for root */
+		if (d_unhashed(dentry))
+			a->udba = AuOpt_UDBA_NONE;
+		if (a->udba != AuOpt_UDBA_NONE) {
+			AuDebugOn(IS_ROOT(dentry));
+			err = au_reval_for_attr(dentry, au_sigen(sb));
+			if (unlikely(err))
+				goto out_dentry;
+		}
+	}
+
+	err = au_pin_and_icpup(dentry, ia, a);
+	if (unlikely(err < 0))
+		goto out_dentry;
+	if (au_ftest_icpup(a->flags, DID_CPUP)) {
+		ia->ia_file = NULL;
+		ia->ia_valid &= ~ATTR_FILE;
+	}
+
+	a->h_path.mnt = au_sbr_mnt(sb, a->btgt);
+	if ((ia->ia_valid & (ATTR_MODE | ATTR_CTIME))
+	    == (ATTR_MODE | ATTR_CTIME)) {
+		err = security_path_chmod(&a->h_path, ia->ia_mode);
+		if (unlikely(err))
+			goto out_unlock;
+	} else if ((ia->ia_valid & (ATTR_UID | ATTR_GID))
+		   && (ia->ia_valid & ATTR_CTIME)) {
+		err = security_path_chown(&a->h_path, ia->ia_uid, ia->ia_gid);
+		if (unlikely(err))
+			goto out_unlock;
+	}
+
+	if (ia->ia_valid & ATTR_SIZE) {
+		struct file *f;
+
+		if (ia->ia_size < i_size_read(inode))
+			/* unmap only */
+			truncate_setsize(inode, ia->ia_size);
+
+		f = NULL;
+		if (ia->ia_valid & ATTR_FILE)
+			f = ia->ia_file;
+		mutex_unlock(&a->h_inode->i_mutex);
+		err = vfsub_trunc(&a->h_path, ia->ia_size, ia->ia_valid, f);
+		mutex_lock_nested(&a->h_inode->i_mutex, AuLsc_I_CHILD);
+	} else {
+		delegated = NULL;
+		while (1) {
+			err = vfsub_notify_change(&a->h_path, ia, &delegated);
+			if (delegated) {
+				err = break_deleg_wait(&delegated);
+				if (!err)
+					continue;
+			}
+			break;
+		}
+	}
+	if (!err)
+		au_cpup_attr_changeable(inode);
+
+out_unlock:
+	mutex_unlock(&a->h_inode->i_mutex);
+	au_unpin(&a->pin);
+	if (unlikely(err))
+		au_update_dbstart(dentry);
+out_dentry:
+	di_write_unlock(dentry);
+	if (file) {
+		fi_write_unlock(file);
+		ia->ia_file = file;
+		ia->ia_valid |= ATTR_FILE;
+	}
+out_si:
+	si_read_unlock(sb);
+out_kfree:
+	kfree(a);
+out:
+	AuTraceErr(err);
+	return err;
+}
+
+#if IS_ENABLED(CONFIG_AUFS_XATTR) || IS_ENABLED(CONFIG_FS_POSIX_ACL)
+static int au_h_path_to_set_attr(struct dentry *dentry,
+				 struct au_icpup_args *a, struct path *h_path)
+{
+	int err;
+	struct super_block *sb;
+
+	sb = dentry->d_sb;
+	a->udba = au_opt_udba(sb);
+	/* no d_unlinked(), to set UDBA_NONE for root */
+	if (d_unhashed(dentry))
+		a->udba = AuOpt_UDBA_NONE;
+	if (a->udba != AuOpt_UDBA_NONE) {
+		AuDebugOn(IS_ROOT(dentry));
+		err = au_reval_for_attr(dentry, au_sigen(sb));
+		if (unlikely(err))
+			goto out;
+	}
+	err = au_pin_and_icpup(dentry, /*ia*/NULL, a);
+	if (unlikely(err < 0))
+		goto out;
+
+	h_path->dentry = a->h_path.dentry;
+	h_path->mnt = au_sbr_mnt(sb, a->btgt);
+
+out:
+	return err;
+}
+
+ssize_t au_srxattr(struct dentry *dentry, struct au_srxattr *arg)
+{
+	int err;
+	struct path h_path;
+	struct super_block *sb;
+	struct au_icpup_args *a;
+	struct inode *inode, *h_inode;
+
+	inode = d_inode(dentry);
+	IMustLock(inode);
+
+	err = -ENOMEM;
+	a = kzalloc(sizeof(*a), GFP_NOFS);
+	if (unlikely(!a))
+		goto out;
+
+	sb = dentry->d_sb;
+	err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
+	if (unlikely(err))
+		goto out_kfree;
+
+	h_path.dentry = NULL;	/* silence gcc */
+	di_write_lock_child(dentry);
+	err = au_h_path_to_set_attr(dentry, a, &h_path);
+	if (unlikely(err))
+		goto out_di;
+
+	mutex_unlock(&a->h_inode->i_mutex);
+	switch (arg->type) {
+	case AU_XATTR_SET:
+		err = vfsub_setxattr(h_path.dentry,
+				     arg->u.set.name, arg->u.set.value,
+				     arg->u.set.size, arg->u.set.flags);
+		break;
+	case AU_XATTR_REMOVE:
+		err = vfsub_removexattr(h_path.dentry, arg->u.remove.name);
+		break;
+	case AU_ACL_SET:
+		err = -EOPNOTSUPP;
+		h_inode = d_inode(h_path.dentry);
+		if (h_inode->i_op->set_acl)
+			err = h_inode->i_op->set_acl(h_inode,
+						     arg->u.acl_set.acl,
+						     arg->u.acl_set.type);
+		break;
+	}
+	if (!err)
+		au_cpup_attr_timesizes(inode);
+
+	au_unpin(&a->pin);
+	if (unlikely(err))
+		au_update_dbstart(dentry);
+
+out_di:
+	di_write_unlock(dentry);
+	si_read_unlock(sb);
+out_kfree:
+	kfree(a);
+out:
+	AuTraceErr(err);
+	return err;
+}
+#endif
+
+static void au_refresh_iattr(struct inode *inode, struct kstat *st,
+			     unsigned int nlink)
+{
+	unsigned int n;
+
+	inode->i_mode = st->mode;
+	/* don't i_[ug]id_write() here */
+	inode->i_uid = st->uid;
+	inode->i_gid = st->gid;
+	inode->i_atime = st->atime;
+	inode->i_mtime = st->mtime;
+	inode->i_ctime = st->ctime;
+
+	au_cpup_attr_nlink(inode, /*force*/0);
+	if (S_ISDIR(inode->i_mode)) {
+		n = inode->i_nlink;
+		n -= nlink;
+		n += st->nlink;
+		smp_mb(); /* for i_nlink */
+		/* 0 can happen */
+		set_nlink(inode, n);
+	}
+
+	spin_lock(&inode->i_lock);
+	inode->i_blocks = st->blocks;
+	i_size_write(inode, st->size);
+	spin_unlock(&inode->i_lock);
+}
+
+/*
+ * common routine for aufs_getattr() and aufs_getxattr().
+ * returns zero or negative (an error).
+ * @dentry will be read-locked in success.
+ */
+int au_h_path_getattr(struct dentry *dentry, int force, struct path *h_path)
+{
+	int err;
+	unsigned int mnt_flags, sigen;
+	unsigned char udba_none;
+	aufs_bindex_t bindex;
+	struct super_block *sb, *h_sb;
+	struct inode *inode;
+
+	h_path->mnt = NULL;
+	h_path->dentry = NULL;
+
+	err = 0;
+	sb = dentry->d_sb;
+	mnt_flags = au_mntflags(sb);
+	udba_none = !!au_opt_test(mnt_flags, UDBA_NONE);
+
+	/* support fstat(2) */
+	if (!d_unlinked(dentry) && !udba_none) {
+		sigen = au_sigen(sb);
+		err = au_digen_test(dentry, sigen);
+		if (!err) {
+			di_read_lock_child(dentry, AuLock_IR);
+			err = au_dbrange_test(dentry);
+			if (unlikely(err)) {
+				di_read_unlock(dentry, AuLock_IR);
+				goto out;
+			}
+		} else {
+			AuDebugOn(IS_ROOT(dentry));
+			di_write_lock_child(dentry);
+			err = au_dbrange_test(dentry);
+			if (!err)
+				err = au_reval_for_attr(dentry, sigen);
+			if (!err)
+				di_downgrade_lock(dentry, AuLock_IR);
+			else {
+				di_write_unlock(dentry);
+				goto out;
+			}
+		}
+	} else
+		di_read_lock_child(dentry, AuLock_IR);
+
+	inode = d_inode(dentry);
+	bindex = au_ibstart(inode);
+	h_path->mnt = au_sbr_mnt(sb, bindex);
+	h_sb = h_path->mnt->mnt_sb;
+	if (!force
+	    && !au_test_fs_bad_iattr(h_sb)
+	    && udba_none)
+		goto out; /* success */
+
+	if (au_dbstart(dentry) == bindex)
+		h_path->dentry = au_h_dptr(dentry, bindex);
+	else if (au_opt_test(mnt_flags, PLINK) && au_plink_test(inode)) {
+		h_path->dentry = au_plink_lkup(inode, bindex);
+		if (IS_ERR(h_path->dentry))
+			/* pretending success */
+			h_path->dentry = NULL;
+		else
+			dput(h_path->dentry);
+	}
+
+out:
+	return err;
+}
+
+static int aufs_getattr(struct vfsmount *mnt __maybe_unused,
+			struct dentry *dentry, struct kstat *st)
+{
+	int err;
+	unsigned char positive;
+	struct path h_path;
+	struct inode *inode;
+	struct super_block *sb;
+
+	inode = d_inode(dentry);
+	sb = dentry->d_sb;
+	err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
+	if (unlikely(err))
+		goto out;
+	err = au_h_path_getattr(dentry, /*force*/0, &h_path);
+	if (unlikely(err))
+		goto out_si;
+	if (unlikely(!h_path.dentry))
+		/* illegally overlapped or something */
+		goto out_fill; /* pretending success */
+
+	positive = d_is_positive(h_path.dentry);
+	if (positive)
+		err = vfs_getattr(&h_path, st);
+	if (!err) {
+		if (positive)
+			au_refresh_iattr(inode, st,
+					 d_inode(h_path.dentry)->i_nlink);
+		goto out_fill; /* success */
+	}
+	AuTraceErr(err);
+	goto out_di;
+
+out_fill:
+	generic_fillattr(inode, st);
+out_di:
+	di_read_unlock(dentry, AuLock_IR);
+out_si:
+	si_read_unlock(sb);
+out:
+	AuTraceErr(err);
+	return err;
+}
+
+/* ---------------------------------------------------------------------- */
+
+/*
+ * Assumption:
+ * - the number of symlinks is not so many.
+ *
+ * Structure:
+ * - sbinfo (instead of iinfo) contains an hlist of struct au_symlink.
+ *   If iinfo contained the hlist, then it would be rather large waste of memory
+ *   I am afraid.
+ * - struct au_symlink contains the necessary info for h_inode follow_link() and
+ *   put_link().
+ */
+
+struct au_symlink {
+	union {
+		struct hlist_node hlist;
+		struct rcu_head rcu;
+	};
+
+	struct inode *h_inode;
+	void *h_cookie;
+};
+
+static void au_symlink_add(struct super_block *sb, struct au_symlink *slink,
+			   struct inode *h_inode, void *cookie)
+{
+	struct au_sbinfo *sbinfo;
+
+	ihold(h_inode);
+	slink->h_inode = h_inode;
+	slink->h_cookie = cookie;
+	sbinfo = au_sbi(sb);
+	au_sphl_add(&slink->hlist, &sbinfo->si_symlink);
+}
+
+static void au_symlink_del(struct super_block *sb, struct au_symlink *slink)
+{
+	struct au_sbinfo *sbinfo;
+
+	/* do not iput() within rcu */
+	iput(slink->h_inode);
+	slink->h_inode = NULL;
+	sbinfo = au_sbi(sb);
+	au_sphl_del_rcu(&slink->hlist, &sbinfo->si_symlink);
+	kfree_rcu(slink, rcu);
+}
+
+static const char *aufs_follow_link(struct dentry *dentry, void **cookie)
+{
+	const char *ret;
+	struct inode *inode, *h_inode;
+	struct dentry *h_dentry;
+	struct au_symlink *slink;
+	int err;
+	aufs_bindex_t bindex;
+
+	ret = NULL; /* suppress a warning */
+	err = aufs_read_lock(dentry, AuLock_IR | AuLock_GEN);
+	if (unlikely(err))
+		goto out;
+
+	err = au_d_hashed_positive(dentry);
+	if (unlikely(err))
+		goto out_unlock;
+
+	err = -EINVAL;
+	inode = d_inode(dentry);
+	bindex = au_ibstart(inode);
+	h_inode = au_h_iptr(inode, bindex);
+	if (unlikely(!h_inode->i_op->follow_link))
+		goto out_unlock;
+
+	err = -ENOMEM;
+	slink = kmalloc(sizeof(*slink), GFP_NOFS);
+	if (unlikely(!slink))
+		goto out_unlock;
+
+	err = -EBUSY;
+	h_dentry = NULL;
+	if (au_dbstart(dentry) <= bindex) {
+		h_dentry = au_h_dptr(dentry, bindex);
+		if (h_dentry)
+			dget(h_dentry);
+	}
+	if (!h_dentry) {
+		h_dentry = d_find_any_alias(h_inode);
+		if (IS_ERR(h_dentry)) {
+			err = PTR_ERR(h_dentry);
+			goto out_free;
+		}
+	}
+	if (unlikely(!h_dentry))
+		goto out_free;
+
+	err = 0;
+	AuDbg("%pf\n", h_inode->i_op->follow_link);
+	AuDbgDentry(h_dentry);
+	ret = h_inode->i_op->follow_link(h_dentry, cookie);
+	dput(h_dentry);
+
+	if (!IS_ERR_OR_NULL(ret)) {
+		au_symlink_add(inode->i_sb, slink, h_inode, *cookie);
+		*cookie = slink;
+		AuDbg("slink %p\n", slink);
+		goto out_unlock; /* success */
+	}
+
+out_free:
+	slink->h_inode = NULL;
+	kfree_rcu(slink, rcu);
+out_unlock:
+	aufs_read_unlock(dentry, AuLock_IR);
+out:
+	if (unlikely(err))
+		ret = ERR_PTR(err);
+	AuTraceErrPtr(ret);
+	return ret;
+}
+
+static void aufs_put_link(struct inode *inode, void *cookie)
+{
+	struct au_symlink *slink;
+	struct inode *h_inode;
+
+	slink = cookie;
+	AuDbg("slink %p\n", slink);
+	h_inode = slink->h_inode;
+	AuDbg("%pf\n", h_inode->i_op->put_link);
+	AuDbgInode(h_inode);
+	if (h_inode->i_op->put_link)
+		h_inode->i_op->put_link(h_inode, slink->h_cookie);
+	au_symlink_del(inode->i_sb, slink);
+}
+
+/* ---------------------------------------------------------------------- */
+
+static int aufs_update_time(struct inode *inode, struct timespec *ts, int flags)
+{
+	int err;
+	struct super_block *sb;
+	struct inode *h_inode;
+
+	sb = inode->i_sb;
+	/* mmap_sem might be acquired already, cf. aufs_mmap() */
+	lockdep_off();
+	si_read_lock(sb, AuLock_FLUSH);
+	ii_write_lock_child(inode);
+	lockdep_on();
+	h_inode = au_h_iptr(inode, au_ibstart(inode));
+	err = vfsub_update_time(h_inode, ts, flags);
+	lockdep_off();
+	if (!err)
+		au_cpup_attr_timesizes(inode);
+	ii_write_unlock(inode);
+	si_read_unlock(sb);
+	lockdep_on();
+
+	if (!err && (flags & S_VERSION))
+		inode_inc_iversion(inode);
+
+	return err;
+}
+
+/* ---------------------------------------------------------------------- */
+
+/* no getattr version will be set by module.c:aufs_init() */
+struct inode_operations aufs_iop_nogetattr[AuIop_Last],
+	aufs_iop[] = {
+	[AuIop_SYMLINK] = {
+		.permission	= aufs_permission,
+#ifdef CONFIG_FS_POSIX_ACL
+		.get_acl	= aufs_get_acl,
+		.set_acl	= aufs_set_acl, /* unsupport for symlink? */
+#endif
+
+		.setattr	= aufs_setattr,
+		.getattr	= aufs_getattr,
+
+#ifdef CONFIG_AUFS_XATTR
+		.setxattr	= aufs_setxattr,
+		.getxattr	= aufs_getxattr,
+		.listxattr	= aufs_listxattr,
+		.removexattr	= aufs_removexattr,
+#endif
+
+		.readlink	= generic_readlink,
+		.follow_link	= aufs_follow_link,
+		.put_link	= aufs_put_link,
+
+		/* .update_time	= aufs_update_time */
+	},
+	[AuIop_DIR] = {
+		.create		= aufs_create,
+		.lookup		= aufs_lookup,
+		.link		= aufs_link,
+		.unlink		= aufs_unlink,
+		.symlink	= aufs_symlink,
+		.mkdir		= aufs_mkdir,
+		.rmdir		= aufs_rmdir,
+		.mknod		= aufs_mknod,
+		.rename		= aufs_rename,
+
+		.permission	= aufs_permission,
+#ifdef CONFIG_FS_POSIX_ACL
+		.get_acl	= aufs_get_acl,
+		.set_acl	= aufs_set_acl,
+#endif
+
+		.setattr	= aufs_setattr,
+		.getattr	= aufs_getattr,
+
+#ifdef CONFIG_AUFS_XATTR
+		.setxattr	= aufs_setxattr,
+		.getxattr	= aufs_getxattr,
+		.listxattr	= aufs_listxattr,
+		.removexattr	= aufs_removexattr,
+#endif
+
+		.update_time	= aufs_update_time,
+		.atomic_open	= aufs_atomic_open,
+		.tmpfile	= aufs_tmpfile
+	},
+	[AuIop_OTHER] = {
+		.permission	= aufs_permission,
+#ifdef CONFIG_FS_POSIX_ACL
+		.get_acl	= aufs_get_acl,
+		.set_acl	= aufs_set_acl,
+#endif
+
+		.setattr	= aufs_setattr,
+		.getattr	= aufs_getattr,
+
+#ifdef CONFIG_AUFS_XATTR
+		.setxattr	= aufs_setxattr,
+		.getxattr	= aufs_getxattr,
+		.listxattr	= aufs_listxattr,
+		.removexattr	= aufs_removexattr,
+#endif
+
+		.update_time	= aufs_update_time
+	}
+};
--- /dev/null
+++ zfcpdump-kernel-4.4/fs/aufs/i_op_add.c
@@ -0,0 +1,932 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+ *
+ * This program, aufs is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * inode operations (add entry)
+ */
+
+#include "aufs.h"
+
+/*
+ * final procedure of adding a new entry, except link(2).
+ * remove whiteout, instantiate, copyup the parent dir's times and size
+ * and update version.
+ * if it failed, re-create the removed whiteout.
+ */
+static int epilog(struct inode *dir, aufs_bindex_t bindex,
+		  struct dentry *wh_dentry, struct dentry *dentry)
+{
+	int err, rerr;
+	aufs_bindex_t bwh;
+	struct path h_path;
+	struct super_block *sb;
+	struct inode *inode, *h_dir;
+	struct dentry *wh;
+
+	bwh = -1;
+	sb = dir->i_sb;
+	if (wh_dentry) {
+		h_dir = d_inode(wh_dentry->d_parent); /* dir inode is locked */
+		IMustLock(h_dir);
+		AuDebugOn(au_h_iptr(dir, bindex) != h_dir);
+		bwh = au_dbwh(dentry);
+		h_path.dentry = wh_dentry;
+		h_path.mnt = au_sbr_mnt(sb, bindex);
+		err = au_wh_unlink_dentry(au_h_iptr(dir, bindex), &h_path,
+					  dentry);
+		if (unlikely(err))
+			goto out;
+	}
+
+	inode = au_new_inode(dentry, /*must_new*/1);
+	if (!IS_ERR(inode)) {
+		d_instantiate(dentry, inode);
+		dir = d_inode(dentry->d_parent); /* dir inode is locked */
+		IMustLock(dir);
+		au_dir_ts(dir, bindex);
+		dir->i_version++;
+		au_fhsm_wrote(sb, bindex, /*force*/0);
+		return 0; /* success */
+	}
+
+	err = PTR_ERR(inode);
+	if (!wh_dentry)
+		goto out;
+
+	/* revert */
+	/* dir inode is locked */
+	wh = au_wh_create(dentry, bwh, wh_dentry->d_parent);
+	rerr = PTR_ERR(wh);
+	if (IS_ERR(wh)) {
+		AuIOErr("%pd reverting whiteout failed(%d, %d)\n",
+			dentry, err, rerr);
+		err = -EIO;
+	} else
+		dput(wh);
+
+out:
+	return err;
+}
+
+static int au_d_may_add(struct dentry *dentry)
+{
+	int err;
+
+	err = 0;
+	if (unlikely(d_unhashed(dentry)))
+		err = -ENOENT;
+	if (unlikely(d_really_is_positive(dentry)))
+		err = -EEXIST;
+	return err;
+}
+
+/*
+ * simple tests for the adding inode operations.
+ * following the checks in vfs, plus the parent-child relationship.
+ */
+int au_may_add(struct dentry *dentry, aufs_bindex_t bindex,
+	       struct dentry *h_parent, int isdir)
+{
+	int err;
+	umode_t h_mode;
+	struct dentry *h_dentry;
+	struct inode *h_inode;
+
+	err = -ENAMETOOLONG;
+	if (unlikely(dentry->d_name.len > AUFS_MAX_NAMELEN))
+		goto out;
+
+	h_dentry = au_h_dptr(dentry, bindex);
+	if (d_really_is_negative(dentry)) {
+		err = -EEXIST;
+		if (unlikely(d_is_positive(h_dentry)))
+			goto out;
+	} else {
+		/* rename(2) case */
+		err = -EIO;
+		if (unlikely(d_is_negative(h_dentry)))
+			goto out;
+		h_inode = d_inode(h_dentry);
+		if (unlikely(!h_inode->i_nlink))
+			goto out;
+
+		h_mode = h_inode->i_mode;
+		if (!isdir) {
+			err = -EISDIR;
+			if (unlikely(S_ISDIR(h_mode)))
+				goto out;
+		} else if (unlikely(!S_ISDIR(h_mode))) {
+			err = -ENOTDIR;
+			goto out;
+		}
+	}
+
+	err = 0;
+	/* expected parent dir is locked */
+	if (unlikely(h_parent != h_dentry->d_parent))
+		err = -EIO;
+
+out:
+	AuTraceErr(err);
+	return err;
+}
+
+/*
+ * initial procedure of adding a new entry.
+ * prepare writable branch and the parent dir, lock it,
+ * and lookup whiteout for the new entry.
+ */
+static struct dentry*
+lock_hdir_lkup_wh(struct dentry *dentry, struct au_dtime *dt,
+		  struct dentry *src_dentry, struct au_pin *pin,
+		  struct au_wr_dir_args *wr_dir_args)
+{
+	struct dentry *wh_dentry, *h_parent;
+	struct super_block *sb;
+	struct au_branch *br;
+	int err;
+	unsigned int udba;
+	aufs_bindex_t bcpup;
+
+	AuDbg("%pd\n", dentry);
+
+	err = au_wr_dir(dentry, src_dentry, wr_dir_args);
+	bcpup = err;
+	wh_dentry = ERR_PTR(err);
+	if (unlikely(err < 0))
+		goto out;
+
+	sb = dentry->d_sb;
+	udba = au_opt_udba(sb);
+	err = au_pin(pin, dentry, bcpup, udba,
+		     AuPin_DI_LOCKED | AuPin_MNT_WRITE);
+	wh_dentry = ERR_PTR(err);
+	if (unlikely(err))
+		goto out;
+
+	h_parent = au_pinned_h_parent(pin);
+	if (udba != AuOpt_UDBA_NONE
+	    && au_dbstart(dentry) == bcpup)
+		err = au_may_add(dentry, bcpup, h_parent,
+				 au_ftest_wrdir(wr_dir_args->flags, ISDIR));
+	else if (unlikely(dentry->d_name.len > AUFS_MAX_NAMELEN))
+		err = -ENAMETOOLONG;
+	wh_dentry = ERR_PTR(err);
+	if (unlikely(err))
+		goto out_unpin;
+
+	br = au_sbr(sb, bcpup);
+	if (dt) {
+		struct path tmp = {
+			.dentry	= h_parent,
+			.mnt	= au_br_mnt(br)
+		};
+		au_dtime_store(dt, au_pinned_parent(pin), &tmp);
+	}
+
+	wh_dentry = NULL;
+	if (bcpup != au_dbwh(dentry))
+		goto out; /* success */
+
+	/*
+	 * ENAMETOOLONG here means that if we allowed create such name, then it
+	 * would not be able to removed in the future. So we don't allow such
+	 * name here and we don't handle ENAMETOOLONG differently here.
+	 */
+	wh_dentry = au_wh_lkup(h_parent, &dentry->d_name, br);
+
+out_unpin:
+	if (IS_ERR(wh_dentry))
+		au_unpin(pin);
+out:
+	return wh_dentry;
+}
+
+/* ---------------------------------------------------------------------- */
+
+enum { Mknod, Symlink, Creat };
+struct simple_arg {
+	int type;
+	union {
+		struct {
+			umode_t			mode;
+			bool			want_excl;
+			bool			try_aopen;
+			struct vfsub_aopen_args	*aopen;
+		} c;
+		struct {
+			const char *symname;
+		} s;
+		struct {
+			umode_t mode;
+			dev_t dev;
+		} m;
+	} u;
+};
+
+static int add_simple(struct inode *dir, struct dentry *dentry,
+		      struct simple_arg *arg)
+{
+	int err, rerr;
+	aufs_bindex_t bstart;
+	unsigned char created;
+	const unsigned char try_aopen
+		= (arg->type == Creat && arg->u.c.try_aopen);
+	struct dentry *wh_dentry, *parent;
+	struct inode *h_dir;
+	struct super_block *sb;
+	struct au_branch *br;
+	/* to reuduce stack size */
+	struct {
+		struct au_dtime dt;
+		struct au_pin pin;
+		struct path h_path;
+		struct au_wr_dir_args wr_dir_args;
+	} *a;
+
+	AuDbg("%pd\n", dentry);
+	IMustLock(dir);
+
+	err = -ENOMEM;
+	a = kmalloc(sizeof(*a), GFP_NOFS);
+	if (unlikely(!a))
+		goto out;
+	a->wr_dir_args.force_btgt = -1;
+	a->wr_dir_args.flags = AuWrDir_ADD_ENTRY;
+
+	parent = dentry->d_parent; /* dir inode is locked */
+	if (!try_aopen) {
+		err = aufs_read_lock(dentry, AuLock_DW | AuLock_GEN);
+		if (unlikely(err))
+			goto out_free;
+	}
+	err = au_d_may_add(dentry);
+	if (unlikely(err))
+		goto out_unlock;
+	if (!try_aopen)
+		di_write_lock_parent(parent);
+	wh_dentry = lock_hdir_lkup_wh(dentry, &a->dt, /*src_dentry*/NULL,
+				      &a->pin, &a->wr_dir_args);
+	err = PTR_ERR(wh_dentry);
+	if (IS_ERR(wh_dentry))
+		goto out_parent;
+
+	bstart = au_dbstart(dentry);
+	sb = dentry->d_sb;
+	br = au_sbr(sb, bstart);
+	a->h_path.dentry = au_h_dptr(dentry, bstart);
+	a->h_path.mnt = au_br_mnt(br);
+	h_dir = au_pinned_h_dir(&a->pin);
+	switch (arg->type) {
+	case Creat:
+		err = 0;
+		if (!try_aopen || !h_dir->i_op->atomic_open)
+			err = vfsub_create(h_dir, &a->h_path, arg->u.c.mode,
+					   arg->u.c.want_excl);
+		else
+			err = vfsub_atomic_open(h_dir, a->h_path.dentry,
+						arg->u.c.aopen, br);
+		break;
+	case Symlink:
+		err = vfsub_symlink(h_dir, &a->h_path, arg->u.s.symname);
+		break;
+	case Mknod:
+		err = vfsub_mknod(h_dir, &a->h_path, arg->u.m.mode,
+				  arg->u.m.dev);
+		break;
+	default:
+		BUG();
+	}
+	created = !err;
+	if (!err)
+		err = epilog(dir, bstart, wh_dentry, dentry);
+
+	/* revert */
+	if (unlikely(created && err && d_is_positive(a->h_path.dentry))) {
+		/* no delegation since it is just created */
+		rerr = vfsub_unlink(h_dir, &a->h_path, /*delegated*/NULL,
+				    /*force*/0);
+		if (rerr) {
+			AuIOErr("%pd revert failure(%d, %d)\n",
+				dentry, err, rerr);
+			err = -EIO;
+		}
+		au_dtime_revert(&a->dt);
+	}
+
+	if (!err && try_aopen && !h_dir->i_op->atomic_open)
+		*arg->u.c.aopen->opened |= FILE_CREATED;
+
+	au_unpin(&a->pin);
+	dput(wh_dentry);
+
+out_parent:
+	if (!try_aopen)
+		di_write_unlock(parent);
+out_unlock:
+	if (unlikely(err)) {
+		au_update_dbstart(dentry);
+		d_drop(dentry);
+	}
+	if (!try_aopen)
+		aufs_read_unlock(dentry, AuLock_DW);
+out_free:
+	kfree(a);
+out:
+	return err;
+}
+
+int aufs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode,
+	       dev_t dev)
+{
+	struct simple_arg arg = {
+		.type = Mknod,
+		.u.m = {
+			.mode	= mode,
+			.dev	= dev
+		}
+	};
+	return add_simple(dir, dentry, &arg);
+}
+
+int aufs_symlink(struct inode *dir, struct dentry *dentry, const char *symname)
+{
+	struct simple_arg arg = {
+		.type = Symlink,
+		.u.s.symname = symname
+	};
+	return add_simple(dir, dentry, &arg);
+}
+
+int aufs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
+		bool want_excl)
+{
+	struct simple_arg arg = {
+		.type = Creat,
+		.u.c = {
+			.mode		= mode,
+			.want_excl	= want_excl
+		}
+	};
+	return add_simple(dir, dentry, &arg);
+}
+
+int au_aopen_or_create(struct inode *dir, struct dentry *dentry,
+		       struct vfsub_aopen_args *aopen_args)
+{
+	struct simple_arg arg = {
+		.type = Creat,
+		.u.c = {
+			.mode		= aopen_args->create_mode,
+			.want_excl	= aopen_args->open_flag & O_EXCL,
+			.try_aopen	= true,
+			.aopen		= aopen_args
+		}
+	};
+	return add_simple(dir, dentry, &arg);
+}
+
+int aufs_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode)
+{
+	int err;
+	aufs_bindex_t bindex;
+	struct super_block *sb;
+	struct dentry *parent, *h_parent, *h_dentry;
+	struct inode *h_dir, *inode;
+	struct vfsmount *h_mnt;
+	struct au_wr_dir_args wr_dir_args = {
+		.force_btgt	= -1,
+		.flags		= AuWrDir_TMPFILE
+	};
+
+	/* copy-up may happen */
+	mutex_lock(&dir->i_mutex);
+
+	sb = dir->i_sb;
+	err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
+	if (unlikely(err))
+		goto out;
+
+	err = au_di_init(dentry);
+	if (unlikely(err))
+		goto out_si;
+
+	err = -EBUSY;
+	parent = d_find_any_alias(dir);
+	AuDebugOn(!parent);
+	di_write_lock_parent(parent);
+	if (unlikely(d_inode(parent) != dir))
+		goto out_parent;
+
+	err = au_digen_test(parent, au_sigen(sb));
+	if (unlikely(err))
+		goto out_parent;
+
+	bindex = au_dbstart(parent);
+	au_set_dbstart(dentry, bindex);
+	au_set_dbend(dentry, bindex);
+	err = au_wr_dir(dentry, /*src_dentry*/NULL, &wr_dir_args);
+	bindex = err;
+	if (unlikely(err < 0))
+		goto out_parent;
+
+	err = -EOPNOTSUPP;
+	h_dir = au_h_iptr(dir, bindex);
+	if (unlikely(!h_dir->i_op->tmpfile))
+		goto out_parent;
+
+	h_mnt = au_sbr_mnt(sb, bindex);
+	err = vfsub_mnt_want_write(h_mnt);
+	if (unlikely(err))
+		goto out_parent;
+
+	h_parent = au_h_dptr(parent, bindex);
+	err = inode_permission(d_inode(h_parent), MAY_WRITE | MAY_EXEC);
+	if (unlikely(err))
+		goto out_mnt;
+
+	err = -ENOMEM;
+	h_dentry = d_alloc(h_parent, &dentry->d_name);
+	if (unlikely(!h_dentry))
+		goto out_mnt;
+
+	err = h_dir->i_op->tmpfile(h_dir, h_dentry, mode);
+	if (unlikely(err))
+		goto out_dentry;
+
+	au_set_dbstart(dentry, bindex);
+	au_set_dbend(dentry, bindex);
+	au_set_h_dptr(dentry, bindex, dget(h_dentry));
+	inode = au_new_inode(dentry, /*must_new*/1);
+	if (IS_ERR(inode)) {
+		err = PTR_ERR(inode);
+		au_set_h_dptr(dentry, bindex, NULL);
+		au_set_dbstart(dentry, -1);
+		au_set_dbend(dentry, -1);
+	} else {
+		if (!inode->i_nlink)
+			set_nlink(inode, 1);
+		d_tmpfile(dentry, inode);
+		au_di(dentry)->di_tmpfile = 1;
+
+		/* update without i_mutex */
+		if (au_ibstart(dir) == au_dbstart(dentry))
+			au_cpup_attr_timesizes(dir);
+	}
+
+out_dentry:
+	dput(h_dentry);
+out_mnt:
+	vfsub_mnt_drop_write(h_mnt);
+out_parent:
+	di_write_unlock(parent);
+	dput(parent);
+	di_write_unlock(dentry);
+	if (!err)
+#if 0
+		/* verbose coding for lock class name */
+		au_rw_class(&au_di(dentry)->di_rwsem,
+			    au_lc_key + AuLcNonDir_DIINFO);
+#else
+		;
+#endif
+	else {
+		au_di_fin(dentry);
+		dentry->d_fsdata = NULL;
+	}
+out_si:
+	si_read_unlock(sb);
+out:
+	mutex_unlock(&dir->i_mutex);
+	return err;
+}
+
+/* ---------------------------------------------------------------------- */
+
+struct au_link_args {
+	aufs_bindex_t bdst, bsrc;
+	struct au_pin pin;
+	struct path h_path;
+	struct dentry *src_parent, *parent;
+};
+
+static int au_cpup_before_link(struct dentry *src_dentry,
+			       struct au_link_args *a)
+{
+	int err;
+	struct dentry *h_src_dentry;
+	struct au_cp_generic cpg = {
+		.dentry	= src_dentry,
+		.bdst	= a->bdst,
+		.bsrc	= a->bsrc,
+		.len	= -1,
+		.pin	= &a->pin,
+		.flags	= AuCpup_DTIME | AuCpup_HOPEN /* | AuCpup_KEEPLINO */
+	};
+
+	di_read_lock_parent(a->src_parent, AuLock_IR);
+	err = au_test_and_cpup_dirs(src_dentry, a->bdst);
+	if (unlikely(err))
+		goto out;
+
+	h_src_dentry = au_h_dptr(src_dentry, a->bsrc);
+	err = au_pin(&a->pin, src_dentry, a->bdst,
+		     au_opt_udba(src_dentry->d_sb),
+		     AuPin_DI_LOCKED | AuPin_MNT_WRITE);
+	if (unlikely(err))
+		goto out;
+
+	err = au_sio_cpup_simple(&cpg);
+	au_unpin(&a->pin);
+
+out:
+	di_read_unlock(a->src_parent, AuLock_IR);
+	return err;
+}
+
+static int au_cpup_or_link(struct dentry *src_dentry, struct dentry *dentry,
+			   struct au_link_args *a)
+{
+	int err;
+	unsigned char plink;
+	aufs_bindex_t bend;
+	struct dentry *h_src_dentry;
+	struct inode *h_inode, *inode, *delegated;
+	struct super_block *sb;
+	struct file *h_file;
+
+	plink = 0;
+	h_inode = NULL;
+	sb = src_dentry->d_sb;
+	inode = d_inode(src_dentry);
+	if (au_ibstart(inode) <= a->bdst)
+		h_inode = au_h_iptr(inode, a->bdst);
+	if (!h_inode || !h_inode->i_nlink) {
+		/* copyup src_dentry as the name of dentry. */
+		bend = au_dbend(dentry);
+		if (bend < a->bsrc)
+			au_set_dbend(dentry, a->bsrc);
+		au_set_h_dptr(dentry, a->bsrc,
+			      dget(au_h_dptr(src_dentry, a->bsrc)));
+		dget(a->h_path.dentry);
+		au_set_h_dptr(dentry, a->bdst, NULL);
+		AuDbg("temporary d_inode...\n");
+		spin_lock(&dentry->d_lock);
+		dentry->d_inode = d_inode(src_dentry); /* tmp */
+		spin_unlock(&dentry->d_lock);
+		h_file = au_h_open_pre(dentry, a->bsrc, /*force_wr*/0);
+		if (IS_ERR(h_file))
+			err = PTR_ERR(h_file);
+		else {
+			struct au_cp_generic cpg = {
+				.dentry	= dentry,
+				.bdst	= a->bdst,
+				.bsrc	= -1,
+				.len	= -1,
+				.pin	= &a->pin,
+				.flags	= AuCpup_KEEPLINO
+			};
+			err = au_sio_cpup_simple(&cpg);
+			au_h_open_post(dentry, a->bsrc, h_file);
+			if (!err) {
+				dput(a->h_path.dentry);
+				a->h_path.dentry = au_h_dptr(dentry, a->bdst);
+			} else
+				au_set_h_dptr(dentry, a->bdst,
+					      a->h_path.dentry);
+		}
+		spin_lock(&dentry->d_lock);
+		dentry->d_inode = NULL; /* restore */
+		spin_unlock(&dentry->d_lock);
+		AuDbg("temporary d_inode...done\n");
+		au_set_h_dptr(dentry, a->bsrc, NULL);
+		au_set_dbend(dentry, bend);
+	} else {
+		/* the inode of src_dentry already exists on a.bdst branch */
+		h_src_dentry = d_find_alias(h_inode);
+		if (!h_src_dentry && au_plink_test(inode)) {
+			plink = 1;
+			h_src_dentry = au_plink_lkup(inode, a->bdst);
+			err = PTR_ERR(h_src_dentry);
+			if (IS_ERR(h_src_dentry))
+				goto out;
+
+			if (unlikely(d_is_negative(h_src_dentry))) {
+				dput(h_src_dentry);
+				h_src_dentry = NULL;
+			}
+
+		}
+		if (h_src_dentry) {
+			delegated = NULL;
+			err = vfsub_link(h_src_dentry, au_pinned_h_dir(&a->pin),
+					 &a->h_path, &delegated);
+			if (unlikely(err == -EWOULDBLOCK)) {
+				pr_warn("cannot retry for NFSv4 delegation"
+					" for an internal link\n");
+				iput(delegated);
+			}
+			dput(h_src_dentry);
+		} else {
+			AuIOErr("no dentry found for hi%lu on b%d\n",
+				h_inode->i_ino, a->bdst);
+			err = -EIO;
+		}
+	}
+
+	if (!err && !plink)
+		au_plink_append(inode, a->bdst, a->h_path.dentry);
+
+out:
+	AuTraceErr(err);
+	return err;
+}
+
+int aufs_link(struct dentry *src_dentry, struct inode *dir,
+	      struct dentry *dentry)
+{
+	int err, rerr;
+	struct au_dtime dt;
+	struct au_link_args *a;
+	struct dentry *wh_dentry, *h_src_dentry;
+	struct inode *inode, *delegated;
+	struct super_block *sb;
+	struct au_wr_dir_args wr_dir_args = {
+		/* .force_btgt	= -1, */
+		.flags		= AuWrDir_ADD_ENTRY
+	};
+
+	IMustLock(dir);
+	inode = d_inode(src_dentry);
+	IMustLock(inode);
+
+	err = -ENOMEM;
+	a = kzalloc(sizeof(*a), GFP_NOFS);
+	if (unlikely(!a))
+		goto out;
+
+	a->parent = dentry->d_parent; /* dir inode is locked */
+	err = aufs_read_and_write_lock2(dentry, src_dentry,
+					AuLock_NOPLM | AuLock_GEN);
+	if (unlikely(err))
+		goto out_kfree;
+	err = au_d_linkable(src_dentry);
+	if (unlikely(err))
+		goto out_unlock;
+	err = au_d_may_add(dentry);
+	if (unlikely(err))
+		goto out_unlock;
+
+	a->src_parent = dget_parent(src_dentry);
+	wr_dir_args.force_btgt = au_ibstart(inode);
+
+	di_write_lock_parent(a->parent);
+	wr_dir_args.force_btgt = au_wbr(dentry, wr_dir_args.force_btgt);
+	wh_dentry = lock_hdir_lkup_wh(dentry, &dt, src_dentry, &a->pin,
+				      &wr_dir_args);
+	err = PTR_ERR(wh_dentry);
+	if (IS_ERR(wh_dentry))
+		goto out_parent;
+
+	err = 0;
+	sb = dentry->d_sb;
+	a->bdst = au_dbstart(dentry);
+	a->h_path.dentry = au_h_dptr(dentry, a->bdst);
+	a->h_path.mnt = au_sbr_mnt(sb, a->bdst);
+	a->bsrc = au_ibstart(inode);
+	h_src_dentry = au_h_d_alias(src_dentry, a->bsrc);
+	if (!h_src_dentry && au_di(src_dentry)->di_tmpfile)
+		h_src_dentry = dget(au_hi_wh(inode, a->bsrc));
+	if (!h_src_dentry) {
+		a->bsrc = au_dbstart(src_dentry);
+		h_src_dentry = au_h_d_alias(src_dentry, a->bsrc);
+		AuDebugOn(!h_src_dentry);
+	} else if (IS_ERR(h_src_dentry)) {
+		err = PTR_ERR(h_src_dentry);
+		goto out_parent;
+	}
+
+	if (au_opt_test(au_mntflags(sb), PLINK)) {
+		if (a->bdst < a->bsrc
+		    /* && h_src_dentry->d_sb != a->h_path.dentry->d_sb */)
+			err = au_cpup_or_link(src_dentry, dentry, a);
+		else {
+			delegated = NULL;
+			err = vfsub_link(h_src_dentry, au_pinned_h_dir(&a->pin),
+					 &a->h_path, &delegated);
+			if (unlikely(err == -EWOULDBLOCK)) {
+				pr_warn("cannot retry for NFSv4 delegation"
+					" for an internal link\n");
+				iput(delegated);
+			}
+		}
+		dput(h_src_dentry);
+	} else {
+		/*
+		 * copyup src_dentry to the branch we process,
+		 * and then link(2) to it.
+		 */
+		dput(h_src_dentry);
+		if (a->bdst < a->bsrc
+		    /* && h_src_dentry->d_sb != a->h_path.dentry->d_sb */) {
+			au_unpin(&a->pin);
+			di_write_unlock(a->parent);
+			err = au_cpup_before_link(src_dentry, a);
+			di_write_lock_parent(a->parent);
+			if (!err)
+				err = au_pin(&a->pin, dentry, a->bdst,
+					     au_opt_udba(sb),
+					     AuPin_DI_LOCKED | AuPin_MNT_WRITE);
+			if (unlikely(err))
+				goto out_wh;
+		}
+		if (!err) {
+			h_src_dentry = au_h_dptr(src_dentry, a->bdst);
+			err = -ENOENT;
+			if (h_src_dentry && d_is_positive(h_src_dentry)) {
+				delegated = NULL;
+				err = vfsub_link(h_src_dentry,
+						 au_pinned_h_dir(&a->pin),
+						 &a->h_path, &delegated);
+				if (unlikely(err == -EWOULDBLOCK)) {
+					pr_warn("cannot retry"
+						" for NFSv4 delegation"
+						" for an internal link\n");
+					iput(delegated);
+				}
+			}
+		}
+	}
+	if (unlikely(err))
+		goto out_unpin;
+
+	if (wh_dentry) {
+		a->h_path.dentry = wh_dentry;
+		err = au_wh_unlink_dentry(au_pinned_h_dir(&a->pin), &a->h_path,
+					  dentry);
+		if (unlikely(err))
+			goto out_revert;
+	}
+
+	au_dir_ts(dir, a->bdst);
+	dir->i_version++;
+	inc_nlink(inode);
+	inode->i_ctime = dir->i_ctime;
+	d_instantiate(dentry, au_igrab(inode));
+	if (d_unhashed(a->h_path.dentry))
+		/* some filesystem calls d_drop() */
+		d_drop(dentry);
+	/* some filesystems consume an inode even hardlink */
+	au_fhsm_wrote(sb, a->bdst, /*force*/0);
+	goto out_unpin; /* success */
+
+out_revert:
+	/* no delegation since it is just created */
+	rerr = vfsub_unlink(au_pinned_h_dir(&a->pin), &a->h_path,
+			    /*delegated*/NULL, /*force*/0);
+	if (unlikely(rerr)) {
+		AuIOErr("%pd reverting failed(%d, %d)\n", dentry, err, rerr);
+		err = -EIO;
+	}
+	au_dtime_revert(&dt);
+out_unpin:
+	au_unpin(&a->pin);
+out_wh:
+	dput(wh_dentry);
+out_parent:
+	di_write_unlock(a->parent);
+	dput(a->src_parent);
+out_unlock:
+	if (unlikely(err)) {
+		au_update_dbstart(dentry);
+		d_drop(dentry);
+	}
+	aufs_read_and_write_unlock2(dentry, src_dentry);
+out_kfree:
+	kfree(a);
+out:
+	AuTraceErr(err);
+	return err;
+}
+
+int aufs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
+{
+	int err, rerr;
+	aufs_bindex_t bindex;
+	unsigned char diropq;
+	struct path h_path;
+	struct dentry *wh_dentry, *parent, *opq_dentry;
+	struct mutex *h_mtx;
+	struct super_block *sb;
+	struct {
+		struct au_pin pin;
+		struct au_dtime dt;
+	} *a; /* reduce the stack usage */
+	struct au_wr_dir_args wr_dir_args = {
+		.force_btgt	= -1,
+		.flags		= AuWrDir_ADD_ENTRY | AuWrDir_ISDIR
+	};
+
+	IMustLock(dir);
+
+	err = -ENOMEM;
+	a = kmalloc(sizeof(*a), GFP_NOFS);
+	if (unlikely(!a))
+		goto out;
+
+	err = aufs_read_lock(dentry, AuLock_DW | AuLock_GEN);
+	if (unlikely(err))
+		goto out_free;
+	err = au_d_may_add(dentry);
+	if (unlikely(err))
+		goto out_unlock;
+
+	parent = dentry->d_parent; /* dir inode is locked */
+	di_write_lock_parent(parent);
+	wh_dentry = lock_hdir_lkup_wh(dentry, &a->dt, /*src_dentry*/NULL,
+				      &a->pin, &wr_dir_args);
+	err = PTR_ERR(wh_dentry);
+	if (IS_ERR(wh_dentry))
+		goto out_parent;
+
+	sb = dentry->d_sb;
+	bindex = au_dbstart(dentry);
+	h_path.dentry = au_h_dptr(dentry, bindex);
+	h_path.mnt = au_sbr_mnt(sb, bindex);
+	err = vfsub_mkdir(au_pinned_h_dir(&a->pin), &h_path, mode);
+	if (unlikely(err))
+		goto out_unpin;
+
+	/* make the dir opaque */
+	diropq = 0;
+	h_mtx = &d_inode(h_path.dentry)->i_mutex;
+	if (wh_dentry
+	    || au_opt_test(au_mntflags(sb), ALWAYS_DIROPQ)) {
+		mutex_lock_nested(h_mtx, AuLsc_I_CHILD);
+		opq_dentry = au_diropq_create(dentry, bindex);
+		mutex_unlock(h_mtx);
+		err = PTR_ERR(opq_dentry);
+		if (IS_ERR(opq_dentry))
+			goto out_dir;
+		dput(opq_dentry);
+		diropq = 1;
+	}
+
+	err = epilog(dir, bindex, wh_dentry, dentry);
+	if (!err) {
+		inc_nlink(dir);
+		goto out_unpin; /* success */
+	}
+
+	/* revert */
+	if (diropq) {
+		AuLabel(revert opq);
+		mutex_lock_nested(h_mtx, AuLsc_I_CHILD);
+		rerr = au_diropq_remove(dentry, bindex);
+		mutex_unlock(h_mtx);
+		if (rerr) {
+			AuIOErr("%pd reverting diropq failed(%d, %d)\n",
+				dentry, err, rerr);
+			err = -EIO;
+		}
+	}
+
+out_dir:
+	AuLabel(revert dir);
+	rerr = vfsub_rmdir(au_pinned_h_dir(&a->pin), &h_path);
+	if (rerr) {
+		AuIOErr("%pd reverting dir failed(%d, %d)\n",
+			dentry, err, rerr);
+		err = -EIO;
+	}
+	au_dtime_revert(&a->dt);
+out_unpin:
+	au_unpin(&a->pin);
+	dput(wh_dentry);
+out_parent:
+	di_write_unlock(parent);
+out_unlock:
+	if (unlikely(err)) {
+		au_update_dbstart(dentry);
+		d_drop(dentry);
+	}
+	aufs_read_unlock(dentry, AuLock_DW);
+out_free:
+	kfree(a);
+out:
+	return err;
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/fs/aufs/i_op_del.c
@@ -0,0 +1,510 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+ *
+ * This program, aufs is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * inode operations (del entry)
+ */
+
+#include "aufs.h"
+
+/*
+ * decide if a new whiteout for @dentry is necessary or not.
+ * when it is necessary, prepare the parent dir for the upper branch whose
+ * branch index is @bcpup for creation. the actual creation of the whiteout will
+ * be done by caller.
+ * return value:
+ * 0: wh is unnecessary
+ * plus: wh is necessary
+ * minus: error
+ */
+int au_wr_dir_need_wh(struct dentry *dentry, int isdir, aufs_bindex_t *bcpup)
+{
+	int need_wh, err;
+	aufs_bindex_t bstart;
+	struct super_block *sb;
+
+	sb = dentry->d_sb;
+	bstart = au_dbstart(dentry);
+	if (*bcpup < 0) {
+		*bcpup = bstart;
+		if (au_test_ro(sb, bstart, d_inode(dentry))) {
+			err = AuWbrCopyup(au_sbi(sb), dentry);
+			*bcpup = err;
+			if (unlikely(err < 0))
+				goto out;
+		}
+	} else
+		AuDebugOn(bstart < *bcpup
+			  || au_test_ro(sb, *bcpup, d_inode(dentry)));
+	AuDbg("bcpup %d, bstart %d\n", *bcpup, bstart);
+
+	if (*bcpup != bstart) {
+		err = au_cpup_dirs(dentry, *bcpup);
+		if (unlikely(err))
+			goto out;
+		need_wh = 1;
+	} else {
+		struct au_dinfo *dinfo, *tmp;
+
+		need_wh = -ENOMEM;
+		dinfo = au_di(dentry);
+		tmp = au_di_alloc(sb, AuLsc_DI_TMP);
+		if (tmp) {
+			au_di_cp(tmp, dinfo);
+			au_di_swap(tmp, dinfo);
+			/* returns the number of positive dentries */
+			need_wh = au_lkup_dentry(dentry, bstart + 1, /*type*/0);
+			au_di_swap(tmp, dinfo);
+			au_rw_write_unlock(&tmp->di_rwsem);
+			au_di_free(tmp);
+		}
+	}
+	AuDbg("need_wh %d\n", need_wh);
+	err = need_wh;
+
+out:
+	return err;
+}
+
+/*
+ * simple tests for the del-entry operations.
+ * following the checks in vfs, plus the parent-child relationship.
+ */
+int au_may_del(struct dentry *dentry, aufs_bindex_t bindex,
+	       struct dentry *h_parent, int isdir)
+{
+	int err;
+	umode_t h_mode;
+	struct dentry *h_dentry, *h_latest;
+	struct inode *h_inode;
+
+	h_dentry = au_h_dptr(dentry, bindex);
+	if (d_really_is_positive(dentry)) {
+		err = -ENOENT;
+		if (unlikely(d_is_negative(h_dentry)))
+			goto out;
+		h_inode = d_inode(h_dentry);
+		if (unlikely(!h_inode->i_nlink))
+			goto out;
+
+		h_mode = h_inode->i_mode;
+		if (!isdir) {
+			err = -EISDIR;
+			if (unlikely(S_ISDIR(h_mode)))
+				goto out;
+		} else if (unlikely(!S_ISDIR(h_mode))) {
+			err = -ENOTDIR;
+			goto out;
+		}
+	} else {
+		/* rename(2) case */
+		err = -EIO;
+		if (unlikely(d_is_positive(h_dentry)))
+			goto out;
+	}
+
+	err = -ENOENT;
+	/* expected parent dir is locked */
+	if (unlikely(h_parent != h_dentry->d_parent))
+		goto out;
+	err = 0;
+
+	/*
+	 * rmdir a dir may break the consistency on some filesystem.
+	 * let's try heavy test.
+	 */
+	err = -EACCES;
+	if (unlikely(!au_opt_test(au_mntflags(dentry->d_sb), DIRPERM1)
+		     && au_test_h_perm(d_inode(h_parent),
+				       MAY_EXEC | MAY_WRITE)))
+		goto out;
+
+	h_latest = au_sio_lkup_one(&dentry->d_name, h_parent);
+	err = -EIO;
+	if (IS_ERR(h_latest))
+		goto out;
+	if (h_latest == h_dentry)
+		err = 0;
+	dput(h_latest);
+
+out:
+	return err;
+}
+
+/*
+ * decide the branch where we operate for @dentry. the branch index will be set
+ * @rbcpup. after diciding it, 'pin' it and store the timestamps of the parent
+ * dir for reverting.
+ * when a new whiteout is necessary, create it.
+ */
+static struct dentry*
+lock_hdir_create_wh(struct dentry *dentry, int isdir, aufs_bindex_t *rbcpup,
+		    struct au_dtime *dt, struct au_pin *pin)
+{
+	struct dentry *wh_dentry;
+	struct super_block *sb;
+	struct path h_path;
+	int err, need_wh;
+	unsigned int udba;
+	aufs_bindex_t bcpup;
+
+	need_wh = au_wr_dir_need_wh(dentry, isdir, rbcpup);
+	wh_dentry = ERR_PTR(need_wh);
+	if (unlikely(need_wh < 0))
+		goto out;
+
+	sb = dentry->d_sb;
+	udba = au_opt_udba(sb);
+	bcpup = *rbcpup;
+	err = au_pin(pin, dentry, bcpup, udba,
+		     AuPin_DI_LOCKED | AuPin_MNT_WRITE);
+	wh_dentry = ERR_PTR(err);
+	if (unlikely(err))
+		goto out;
+
+	h_path.dentry = au_pinned_h_parent(pin);
+	if (udba != AuOpt_UDBA_NONE
+	    && au_dbstart(dentry) == bcpup) {
+		err = au_may_del(dentry, bcpup, h_path.dentry, isdir);
+		wh_dentry = ERR_PTR(err);
+		if (unlikely(err))
+			goto out_unpin;
+	}
+
+	h_path.mnt = au_sbr_mnt(sb, bcpup);
+	au_dtime_store(dt, au_pinned_parent(pin), &h_path);
+	wh_dentry = NULL;
+	if (!need_wh)
+		goto out; /* success, no need to create whiteout */
+
+	wh_dentry = au_wh_create(dentry, bcpup, h_path.dentry);
+	if (IS_ERR(wh_dentry))
+		goto out_unpin;
+
+	/* returns with the parent is locked and wh_dentry is dget-ed */
+	goto out; /* success */
+
+out_unpin:
+	au_unpin(pin);
+out:
+	return wh_dentry;
+}
+
+/*
+ * when removing a dir, rename it to a unique temporary whiteout-ed name first
+ * in order to be revertible and save time for removing many child whiteouts
+ * under the dir.
+ * returns 1 when there are too many child whiteout and caller should remove
+ * them asynchronously. returns 0 when the number of children is enough small to
+ * remove now or the branch fs is a remote fs.
+ * otherwise return an error.
+ */
+static int renwh_and_rmdir(struct dentry *dentry, aufs_bindex_t bindex,
+			   struct au_nhash *whlist, struct inode *dir)
+{
+	int rmdir_later, err, dirwh;
+	struct dentry *h_dentry;
+	struct super_block *sb;
+	struct inode *inode;
+
+	sb = dentry->d_sb;
+	SiMustAnyLock(sb);
+	h_dentry = au_h_dptr(dentry, bindex);
+	err = au_whtmp_ren(h_dentry, au_sbr(sb, bindex));
+	if (unlikely(err))
+		goto out;
+
+	/* stop monitoring */
+	inode = d_inode(dentry);
+	au_hn_free(au_hi(inode, bindex));
+
+	if (!au_test_fs_remote(h_dentry->d_sb)) {
+		dirwh = au_sbi(sb)->si_dirwh;
+		rmdir_later = (dirwh <= 1);
+		if (!rmdir_later)
+			rmdir_later = au_nhash_test_longer_wh(whlist, bindex,
+							      dirwh);
+		if (rmdir_later)
+			return rmdir_later;
+	}
+
+	err = au_whtmp_rmdir(dir, bindex, h_dentry, whlist);
+	if (unlikely(err)) {
+		AuIOErr("rmdir %pd, b%d failed, %d. ignored\n",
+			h_dentry, bindex, err);
+		err = 0;
+	}
+
+out:
+	AuTraceErr(err);
+	return err;
+}
+
+/*
+ * final procedure for deleting a entry.
+ * maintain dentry and iattr.
+ */
+static void epilog(struct inode *dir, struct dentry *dentry,
+		   aufs_bindex_t bindex)
+{
+	struct inode *inode;
+
+	inode = d_inode(dentry);
+	d_drop(dentry);
+	inode->i_ctime = dir->i_ctime;
+
+	au_dir_ts(dir, bindex);
+	dir->i_version++;
+}
+
+/*
+ * when an error happened, remove the created whiteout and revert everything.
+ */
+static int do_revert(int err, struct inode *dir, aufs_bindex_t bindex,
+		     aufs_bindex_t bwh, struct dentry *wh_dentry,
+		     struct dentry *dentry, struct au_dtime *dt)
+{
+	int rerr;
+	struct path h_path = {
+		.dentry	= wh_dentry,
+		.mnt	= au_sbr_mnt(dir->i_sb, bindex)
+	};
+
+	rerr = au_wh_unlink_dentry(au_h_iptr(dir, bindex), &h_path, dentry);
+	if (!rerr) {
+		au_set_dbwh(dentry, bwh);
+		au_dtime_revert(dt);
+		return 0;
+	}
+
+	AuIOErr("%pd reverting whiteout failed(%d, %d)\n", dentry, err, rerr);
+	return -EIO;
+}
+
+/* ---------------------------------------------------------------------- */
+
+int aufs_unlink(struct inode *dir, struct dentry *dentry)
+{
+	int err;
+	aufs_bindex_t bwh, bindex, bstart;
+	struct inode *inode, *h_dir, *delegated;
+	struct dentry *parent, *wh_dentry;
+	/* to reuduce stack size */
+	struct {
+		struct au_dtime dt;
+		struct au_pin pin;
+		struct path h_path;
+	} *a;
+
+	IMustLock(dir);
+
+	err = -ENOMEM;
+	a = kmalloc(sizeof(*a), GFP_NOFS);
+	if (unlikely(!a))
+		goto out;
+
+	err = aufs_read_lock(dentry, AuLock_DW | AuLock_GEN);
+	if (unlikely(err))
+		goto out_free;
+	err = au_d_hashed_positive(dentry);
+	if (unlikely(err))
+		goto out_unlock;
+	inode = d_inode(dentry);
+	IMustLock(inode);
+	err = -EISDIR;
+	if (unlikely(d_is_dir(dentry)))
+		goto out_unlock; /* possible? */
+
+	bstart = au_dbstart(dentry);
+	bwh = au_dbwh(dentry);
+	bindex = -1;
+	parent = dentry->d_parent; /* dir inode is locked */
+	di_write_lock_parent(parent);
+	wh_dentry = lock_hdir_create_wh(dentry, /*isdir*/0, &bindex, &a->dt,
+					&a->pin);
+	err = PTR_ERR(wh_dentry);
+	if (IS_ERR(wh_dentry))
+		goto out_parent;
+
+	a->h_path.mnt = au_sbr_mnt(dentry->d_sb, bstart);
+	a->h_path.dentry = au_h_dptr(dentry, bstart);
+	dget(a->h_path.dentry);
+	if (bindex == bstart) {
+		h_dir = au_pinned_h_dir(&a->pin);
+		delegated = NULL;
+		err = vfsub_unlink(h_dir, &a->h_path, &delegated, /*force*/0);
+		if (unlikely(err == -EWOULDBLOCK)) {
+			pr_warn("cannot retry for NFSv4 delegation"
+				" for an internal unlink\n");
+			iput(delegated);
+		}
+	} else {
+		/* dir inode is locked */
+		h_dir = d_inode(wh_dentry->d_parent);
+		IMustLock(h_dir);
+		err = 0;
+	}
+
+	if (!err) {
+		vfsub_drop_nlink(inode);
+		epilog(dir, dentry, bindex);
+
+		/* update target timestamps */
+		if (bindex == bstart) {
+			vfsub_update_h_iattr(&a->h_path, /*did*/NULL);
+			/*ignore*/
+			inode->i_ctime = d_inode(a->h_path.dentry)->i_ctime;
+		} else
+			/* todo: this timestamp may be reverted later */
+			inode->i_ctime = h_dir->i_ctime;
+		goto out_unpin; /* success */
+	}
+
+	/* revert */
+	if (wh_dentry) {
+		int rerr;
+
+		rerr = do_revert(err, dir, bindex, bwh, wh_dentry, dentry,
+				 &a->dt);
+		if (rerr)
+			err = rerr;
+	}
+
+out_unpin:
+	au_unpin(&a->pin);
+	dput(wh_dentry);
+	dput(a->h_path.dentry);
+out_parent:
+	di_write_unlock(parent);
+out_unlock:
+	aufs_read_unlock(dentry, AuLock_DW);
+out_free:
+	kfree(a);
+out:
+	return err;
+}
+
+int aufs_rmdir(struct inode *dir, struct dentry *dentry)
+{
+	int err, rmdir_later;
+	aufs_bindex_t bwh, bindex, bstart;
+	struct inode *inode;
+	struct dentry *parent, *wh_dentry, *h_dentry;
+	struct au_whtmp_rmdir *args;
+	/* to reuduce stack size */
+	struct {
+		struct au_dtime dt;
+		struct au_pin pin;
+	} *a;
+
+	IMustLock(dir);
+
+	err = -ENOMEM;
+	a = kmalloc(sizeof(*a), GFP_NOFS);
+	if (unlikely(!a))
+		goto out;
+
+	err = aufs_read_lock(dentry, AuLock_DW | AuLock_FLUSH | AuLock_GEN);
+	if (unlikely(err))
+		goto out_free;
+	err = au_alive_dir(dentry);
+	if (unlikely(err))
+		goto out_unlock;
+	inode = d_inode(dentry);
+	IMustLock(inode);
+	err = -ENOTDIR;
+	if (unlikely(!d_is_dir(dentry)))
+		goto out_unlock; /* possible? */
+
+	err = -ENOMEM;
+	args = au_whtmp_rmdir_alloc(dir->i_sb, GFP_NOFS);
+	if (unlikely(!args))
+		goto out_unlock;
+
+	parent = dentry->d_parent; /* dir inode is locked */
+	di_write_lock_parent(parent);
+	err = au_test_empty(dentry, &args->whlist);
+	if (unlikely(err))
+		goto out_parent;
+
+	bstart = au_dbstart(dentry);
+	bwh = au_dbwh(dentry);
+	bindex = -1;
+	wh_dentry = lock_hdir_create_wh(dentry, /*isdir*/1, &bindex, &a->dt,
+					&a->pin);
+	err = PTR_ERR(wh_dentry);
+	if (IS_ERR(wh_dentry))
+		goto out_parent;
+
+	h_dentry = au_h_dptr(dentry, bstart);
+	dget(h_dentry);
+	rmdir_later = 0;
+	if (bindex == bstart) {
+		err = renwh_and_rmdir(dentry, bstart, &args->whlist, dir);
+		if (err > 0) {
+			rmdir_later = err;
+			err = 0;
+		}
+	} else {
+		/* stop monitoring */
+		au_hn_free(au_hi(inode, bstart));
+
+		/* dir inode is locked */
+		IMustLock(d_inode(wh_dentry->d_parent));
+		err = 0;
+	}
+
+	if (!err) {
+		vfsub_dead_dir(inode);
+		au_set_dbdiropq(dentry, -1);
+		epilog(dir, dentry, bindex);
+
+		if (rmdir_later) {
+			au_whtmp_kick_rmdir(dir, bstart, h_dentry, args);
+			args = NULL;
+		}
+
+		goto out_unpin; /* success */
+	}
+
+	/* revert */
+	AuLabel(revert);
+	if (wh_dentry) {
+		int rerr;
+
+		rerr = do_revert(err, dir, bindex, bwh, wh_dentry, dentry,
+				 &a->dt);
+		if (rerr)
+			err = rerr;
+	}
+
+out_unpin:
+	au_unpin(&a->pin);
+	dput(wh_dentry);
+	dput(h_dentry);
+out_parent:
+	di_write_unlock(parent);
+	if (args)
+		au_whtmp_rmdir_free(args);
+out_unlock:
+	aufs_read_unlock(dentry, AuLock_DW);
+out_free:
+	kfree(a);
+out:
+	AuTraceErr(err);
+	return err;
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/fs/aufs/i_op_ren.c
@@ -0,0 +1,1015 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+ *
+ * This program, aufs is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * inode operation (rename entry)
+ * todo: this is crazy monster
+ */
+
+#include "aufs.h"
+
+enum { AuSRC, AuDST, AuSrcDst };
+enum { AuPARENT, AuCHILD, AuParentChild };
+
+#define AuRen_ISDIR	1
+#define AuRen_ISSAMEDIR	(1 << 1)
+#define AuRen_WHSRC	(1 << 2)
+#define AuRen_WHDST	(1 << 3)
+#define AuRen_MNT_WRITE	(1 << 4)
+#define AuRen_DT_DSTDIR	(1 << 5)
+#define AuRen_DIROPQ	(1 << 6)
+#define au_ftest_ren(flags, name)	((flags) & AuRen_##name)
+#define au_fset_ren(flags, name) \
+	do { (flags) |= AuRen_##name; } while (0)
+#define au_fclr_ren(flags, name) \
+	do { (flags) &= ~AuRen_##name; } while (0)
+
+struct au_ren_args {
+	struct {
+		struct dentry *dentry, *h_dentry, *parent, *h_parent,
+			*wh_dentry;
+		struct inode *dir, *inode;
+		struct au_hinode *hdir;
+		struct au_dtime dt[AuParentChild];
+		aufs_bindex_t bstart;
+	} sd[AuSrcDst];
+
+#define src_dentry	sd[AuSRC].dentry
+#define src_dir		sd[AuSRC].dir
+#define src_inode	sd[AuSRC].inode
+#define src_h_dentry	sd[AuSRC].h_dentry
+#define src_parent	sd[AuSRC].parent
+#define src_h_parent	sd[AuSRC].h_parent
+#define src_wh_dentry	sd[AuSRC].wh_dentry
+#define src_hdir	sd[AuSRC].hdir
+#define src_h_dir	sd[AuSRC].hdir->hi_inode
+#define src_dt		sd[AuSRC].dt
+#define src_bstart	sd[AuSRC].bstart
+
+#define dst_dentry	sd[AuDST].dentry
+#define dst_dir		sd[AuDST].dir
+#define dst_inode	sd[AuDST].inode
+#define dst_h_dentry	sd[AuDST].h_dentry
+#define dst_parent	sd[AuDST].parent
+#define dst_h_parent	sd[AuDST].h_parent
+#define dst_wh_dentry	sd[AuDST].wh_dentry
+#define dst_hdir	sd[AuDST].hdir
+#define dst_h_dir	sd[AuDST].hdir->hi_inode
+#define dst_dt		sd[AuDST].dt
+#define dst_bstart	sd[AuDST].bstart
+
+	struct dentry *h_trap;
+	struct au_branch *br;
+	struct au_hinode *src_hinode;
+	struct path h_path;
+	struct au_nhash whlist;
+	aufs_bindex_t btgt, src_bwh, src_bdiropq;
+
+	unsigned int flags;
+
+	struct au_whtmp_rmdir *thargs;
+	struct dentry *h_dst;
+};
+
+/* ---------------------------------------------------------------------- */
+
+/*
+ * functions for reverting.
+ * when an error happened in a single rename systemcall, we should revert
+ * everything as if nothing happened.
+ * we don't need to revert the copied-up/down the parent dir since they are
+ * harmless.
+ */
+
+#define RevertFailure(fmt, ...) do { \
+	AuIOErr("revert failure: " fmt " (%d, %d)\n", \
+		##__VA_ARGS__, err, rerr); \
+	err = -EIO; \
+} while (0)
+
+static void au_ren_rev_diropq(int err, struct au_ren_args *a)
+{
+	int rerr;
+
+	au_hn_imtx_lock_nested(a->src_hinode, AuLsc_I_CHILD);
+	rerr = au_diropq_remove(a->src_dentry, a->btgt);
+	au_hn_imtx_unlock(a->src_hinode);
+	au_set_dbdiropq(a->src_dentry, a->src_bdiropq);
+	if (rerr)
+		RevertFailure("remove diropq %pd", a->src_dentry);
+}
+
+static void au_ren_rev_rename(int err, struct au_ren_args *a)
+{
+	int rerr;
+	struct inode *delegated;
+
+	a->h_path.dentry = vfsub_lkup_one(&a->src_dentry->d_name,
+					  a->src_h_parent);
+	rerr = PTR_ERR(a->h_path.dentry);
+	if (IS_ERR(a->h_path.dentry)) {
+		RevertFailure("lkup one %pd", a->src_dentry);
+		return;
+	}
+
+	delegated = NULL;
+	rerr = vfsub_rename(a->dst_h_dir,
+			    au_h_dptr(a->src_dentry, a->btgt),
+			    a->src_h_dir, &a->h_path, &delegated);
+	if (unlikely(rerr == -EWOULDBLOCK)) {
+		pr_warn("cannot retry for NFSv4 delegation"
+			" for an internal rename\n");
+		iput(delegated);
+	}
+	d_drop(a->h_path.dentry);
+	dput(a->h_path.dentry);
+	/* au_set_h_dptr(a->src_dentry, a->btgt, NULL); */
+	if (rerr)
+		RevertFailure("rename %pd", a->src_dentry);
+}
+
+static void au_ren_rev_whtmp(int err, struct au_ren_args *a)
+{
+	int rerr;
+	struct inode *delegated;
+
+	a->h_path.dentry = vfsub_lkup_one(&a->dst_dentry->d_name,
+					  a->dst_h_parent);
+	rerr = PTR_ERR(a->h_path.dentry);
+	if (IS_ERR(a->h_path.dentry)) {
+		RevertFailure("lkup one %pd", a->dst_dentry);
+		return;
+	}
+	if (d_is_positive(a->h_path.dentry)) {
+		d_drop(a->h_path.dentry);
+		dput(a->h_path.dentry);
+		return;
+	}
+
+	delegated = NULL;
+	rerr = vfsub_rename(a->dst_h_dir, a->h_dst, a->dst_h_dir, &a->h_path,
+			    &delegated);
+	if (unlikely(rerr == -EWOULDBLOCK)) {
+		pr_warn("cannot retry for NFSv4 delegation"
+			" for an internal rename\n");
+		iput(delegated);
+	}
+	d_drop(a->h_path.dentry);
+	dput(a->h_path.dentry);
+	if (!rerr)
+		au_set_h_dptr(a->dst_dentry, a->btgt, dget(a->h_dst));
+	else
+		RevertFailure("rename %pd", a->h_dst);
+}
+
+static void au_ren_rev_whsrc(int err, struct au_ren_args *a)
+{
+	int rerr;
+
+	a->h_path.dentry = a->src_wh_dentry;
+	rerr = au_wh_unlink_dentry(a->src_h_dir, &a->h_path, a->src_dentry);
+	au_set_dbwh(a->src_dentry, a->src_bwh);
+	if (rerr)
+		RevertFailure("unlink %pd", a->src_wh_dentry);
+}
+#undef RevertFailure
+
+/* ---------------------------------------------------------------------- */
+
+/*
+ * when we have to copyup the renaming entry, do it with the rename-target name
+ * in order to minimize the cost (the later actual rename is unnecessary).
+ * otherwise rename it on the target branch.
+ */
+static int au_ren_or_cpup(struct au_ren_args *a)
+{
+	int err;
+	struct dentry *d;
+	struct inode *delegated;
+
+	d = a->src_dentry;
+	if (au_dbstart(d) == a->btgt) {
+		a->h_path.dentry = a->dst_h_dentry;
+		if (au_ftest_ren(a->flags, DIROPQ)
+		    && au_dbdiropq(d) == a->btgt)
+			au_fclr_ren(a->flags, DIROPQ);
+		AuDebugOn(au_dbstart(d) != a->btgt);
+		delegated = NULL;
+		err = vfsub_rename(a->src_h_dir, au_h_dptr(d, a->btgt),
+				   a->dst_h_dir, &a->h_path, &delegated);
+		if (unlikely(err == -EWOULDBLOCK)) {
+			pr_warn("cannot retry for NFSv4 delegation"
+				" for an internal rename\n");
+			iput(delegated);
+		}
+	} else
+		BUG();
+
+	if (!err && a->h_dst)
+		/* it will be set to dinfo later */
+		dget(a->h_dst);
+
+	return err;
+}
+
+/* cf. aufs_rmdir() */
+static int au_ren_del_whtmp(struct au_ren_args *a)
+{
+	int err;
+	struct inode *dir;
+
+	dir = a->dst_dir;
+	SiMustAnyLock(dir->i_sb);
+	if (!au_nhash_test_longer_wh(&a->whlist, a->btgt,
+				     au_sbi(dir->i_sb)->si_dirwh)
+	    || au_test_fs_remote(a->h_dst->d_sb)) {
+		err = au_whtmp_rmdir(dir, a->btgt, a->h_dst, &a->whlist);
+		if (unlikely(err))
+			pr_warn("failed removing whtmp dir %pd (%d), "
+				"ignored.\n", a->h_dst, err);
+	} else {
+		au_nhash_wh_free(&a->thargs->whlist);
+		a->thargs->whlist = a->whlist;
+		a->whlist.nh_num = 0;
+		au_whtmp_kick_rmdir(dir, a->btgt, a->h_dst, a->thargs);
+		dput(a->h_dst);
+		a->thargs = NULL;
+	}
+
+	return 0;
+}
+
+/* make it 'opaque' dir. */
+static int au_ren_diropq(struct au_ren_args *a)
+{
+	int err;
+	struct dentry *diropq;
+
+	err = 0;
+	a->src_bdiropq = au_dbdiropq(a->src_dentry);
+	a->src_hinode = au_hi(a->src_inode, a->btgt);
+	au_hn_imtx_lock_nested(a->src_hinode, AuLsc_I_CHILD);
+	diropq = au_diropq_create(a->src_dentry, a->btgt);
+	au_hn_imtx_unlock(a->src_hinode);
+	if (IS_ERR(diropq))
+		err = PTR_ERR(diropq);
+	else
+		dput(diropq);
+
+	return err;
+}
+
+static int do_rename(struct au_ren_args *a)
+{
+	int err;
+	struct dentry *d, *h_d;
+
+	/* prepare workqueue args for asynchronous rmdir */
+	h_d = a->dst_h_dentry;
+	if (au_ftest_ren(a->flags, ISDIR) && d_is_positive(h_d)) {
+		err = -ENOMEM;
+		a->thargs = au_whtmp_rmdir_alloc(a->src_dentry->d_sb, GFP_NOFS);
+		if (unlikely(!a->thargs))
+			goto out;
+		a->h_dst = dget(h_d);
+	}
+
+	/* create whiteout for src_dentry */
+	if (au_ftest_ren(a->flags, WHSRC)) {
+		a->src_bwh = au_dbwh(a->src_dentry);
+		AuDebugOn(a->src_bwh >= 0);
+		a->src_wh_dentry
+			= au_wh_create(a->src_dentry, a->btgt, a->src_h_parent);
+		err = PTR_ERR(a->src_wh_dentry);
+		if (IS_ERR(a->src_wh_dentry))
+			goto out_thargs;
+	}
+
+	/* lookup whiteout for dentry */
+	if (au_ftest_ren(a->flags, WHDST)) {
+		h_d = au_wh_lkup(a->dst_h_parent, &a->dst_dentry->d_name,
+				 a->br);
+		err = PTR_ERR(h_d);
+		if (IS_ERR(h_d))
+			goto out_whsrc;
+		if (d_is_negative(h_d))
+			dput(h_d);
+		else
+			a->dst_wh_dentry = h_d;
+	}
+
+	/* rename dentry to tmpwh */
+	if (a->thargs) {
+		err = au_whtmp_ren(a->dst_h_dentry, a->br);
+		if (unlikely(err))
+			goto out_whdst;
+
+		d = a->dst_dentry;
+		au_set_h_dptr(d, a->btgt, NULL);
+		err = au_lkup_neg(d, a->btgt, /*wh*/0);
+		if (unlikely(err))
+			goto out_whtmp;
+		a->dst_h_dentry = au_h_dptr(d, a->btgt);
+	}
+
+	BUG_ON(d_is_positive(a->dst_h_dentry) && a->src_bstart != a->btgt);
+
+	/* rename by vfs_rename or cpup */
+	d = a->dst_dentry;
+	if (au_ftest_ren(a->flags, ISDIR)
+	    && (a->dst_wh_dentry
+		|| au_dbdiropq(d) == a->btgt
+		/* hide the lower to keep xino */
+		|| a->btgt < au_dbend(d)
+		|| au_opt_test(au_mntflags(d->d_sb), ALWAYS_DIROPQ)))
+		au_fset_ren(a->flags, DIROPQ);
+	err = au_ren_or_cpup(a);
+	if (unlikely(err))
+		/* leave the copied-up one */
+		goto out_whtmp;
+
+	/* make dir opaque */
+	if (au_ftest_ren(a->flags, DIROPQ)) {
+		err = au_ren_diropq(a);
+		if (unlikely(err))
+			goto out_rename;
+	}
+
+	/* update target timestamps */
+	AuDebugOn(au_dbstart(a->src_dentry) != a->btgt);
+	a->h_path.dentry = au_h_dptr(a->src_dentry, a->btgt);
+	vfsub_update_h_iattr(&a->h_path, /*did*/NULL); /*ignore*/
+	a->src_inode->i_ctime = d_inode(a->h_path.dentry)->i_ctime;
+
+	/* remove whiteout for dentry */
+	if (a->dst_wh_dentry) {
+		a->h_path.dentry = a->dst_wh_dentry;
+		err = au_wh_unlink_dentry(a->dst_h_dir, &a->h_path,
+					  a->dst_dentry);
+		if (unlikely(err))
+			goto out_diropq;
+	}
+
+	/* remove whtmp */
+	if (a->thargs)
+		au_ren_del_whtmp(a); /* ignore this error */
+
+	au_fhsm_wrote(a->src_dentry->d_sb, a->btgt, /*force*/0);
+	err = 0;
+	goto out_success;
+
+out_diropq:
+	if (au_ftest_ren(a->flags, DIROPQ))
+		au_ren_rev_diropq(err, a);
+out_rename:
+	au_ren_rev_rename(err, a);
+	dput(a->h_dst);
+out_whtmp:
+	if (a->thargs)
+		au_ren_rev_whtmp(err, a);
+out_whdst:
+	dput(a->dst_wh_dentry);
+	a->dst_wh_dentry = NULL;
+out_whsrc:
+	if (a->src_wh_dentry)
+		au_ren_rev_whsrc(err, a);
+out_success:
+	dput(a->src_wh_dentry);
+	dput(a->dst_wh_dentry);
+out_thargs:
+	if (a->thargs) {
+		dput(a->h_dst);
+		au_whtmp_rmdir_free(a->thargs);
+		a->thargs = NULL;
+	}
+out:
+	return err;
+}
+
+/* ---------------------------------------------------------------------- */
+
+/*
+ * test if @dentry dir can be rename destination or not.
+ * success means, it is a logically empty dir.
+ */
+static int may_rename_dstdir(struct dentry *dentry, struct au_nhash *whlist)
+{
+	return au_test_empty(dentry, whlist);
+}
+
+/*
+ * test if @dentry dir can be rename source or not.
+ * if it can, return 0 and @children is filled.
+ * success means,
+ * - it is a logically empty dir.
+ * - or, it exists on writable branch and has no children including whiteouts
+ *       on the lower branch.
+ */
+static int may_rename_srcdir(struct dentry *dentry, aufs_bindex_t btgt)
+{
+	int err;
+	unsigned int rdhash;
+	aufs_bindex_t bstart;
+
+	bstart = au_dbstart(dentry);
+	if (bstart != btgt) {
+		struct au_nhash whlist;
+
+		SiMustAnyLock(dentry->d_sb);
+		rdhash = au_sbi(dentry->d_sb)->si_rdhash;
+		if (!rdhash)
+			rdhash = au_rdhash_est(au_dir_size(/*file*/NULL,
+							   dentry));
+		err = au_nhash_alloc(&whlist, rdhash, GFP_NOFS);
+		if (unlikely(err))
+			goto out;
+		err = au_test_empty(dentry, &whlist);
+		au_nhash_wh_free(&whlist);
+		goto out;
+	}
+
+	if (bstart == au_dbtaildir(dentry))
+		return 0; /* success */
+
+	err = au_test_empty_lower(dentry);
+
+out:
+	if (err == -ENOTEMPTY) {
+		AuWarn1("renaming dir who has child(ren) on multiple branches,"
+			" is not supported\n");
+		err = -EXDEV;
+	}
+	return err;
+}
+
+/* side effect: sets whlist and h_dentry */
+static int au_ren_may_dir(struct au_ren_args *a)
+{
+	int err;
+	unsigned int rdhash;
+	struct dentry *d;
+
+	d = a->dst_dentry;
+	SiMustAnyLock(d->d_sb);
+
+	err = 0;
+	if (au_ftest_ren(a->flags, ISDIR) && a->dst_inode) {
+		rdhash = au_sbi(d->d_sb)->si_rdhash;
+		if (!rdhash)
+			rdhash = au_rdhash_est(au_dir_size(/*file*/NULL, d));
+		err = au_nhash_alloc(&a->whlist, rdhash, GFP_NOFS);
+		if (unlikely(err))
+			goto out;
+
+		au_set_dbstart(d, a->dst_bstart);
+		err = may_rename_dstdir(d, &a->whlist);
+		au_set_dbstart(d, a->btgt);
+	}
+	a->dst_h_dentry = au_h_dptr(d, au_dbstart(d));
+	if (unlikely(err))
+		goto out;
+
+	d = a->src_dentry;
+	a->src_h_dentry = au_h_dptr(d, au_dbstart(d));
+	if (au_ftest_ren(a->flags, ISDIR)) {
+		err = may_rename_srcdir(d, a->btgt);
+		if (unlikely(err)) {
+			au_nhash_wh_free(&a->whlist);
+			a->whlist.nh_num = 0;
+		}
+	}
+out:
+	return err;
+}
+
+/* ---------------------------------------------------------------------- */
+
+/*
+ * simple tests for rename.
+ * following the checks in vfs, plus the parent-child relationship.
+ */
+static int au_may_ren(struct au_ren_args *a)
+{
+	int err, isdir;
+	struct inode *h_inode;
+
+	if (a->src_bstart == a->btgt) {
+		err = au_may_del(a->src_dentry, a->btgt, a->src_h_parent,
+				 au_ftest_ren(a->flags, ISDIR));
+		if (unlikely(err))
+			goto out;
+		err = -EINVAL;
+		if (unlikely(a->src_h_dentry == a->h_trap))
+			goto out;
+	}
+
+	err = 0;
+	if (a->dst_bstart != a->btgt)
+		goto out;
+
+	err = -ENOTEMPTY;
+	if (unlikely(a->dst_h_dentry == a->h_trap))
+		goto out;
+
+	err = -EIO;
+	isdir = !!au_ftest_ren(a->flags, ISDIR);
+	if (d_really_is_negative(a->dst_dentry)) {
+		if (d_is_negative(a->dst_h_dentry))
+			err = au_may_add(a->dst_dentry, a->btgt,
+					 a->dst_h_parent, isdir);
+	} else {
+		if (unlikely(d_is_negative(a->dst_h_dentry)))
+			goto out;
+		h_inode = d_inode(a->dst_h_dentry);
+		if (h_inode->i_nlink)
+			err = au_may_del(a->dst_dentry, a->btgt,
+					 a->dst_h_parent, isdir);
+	}
+
+out:
+	if (unlikely(err == -ENOENT || err == -EEXIST))
+		err = -EIO;
+	AuTraceErr(err);
+	return err;
+}
+
+/* ---------------------------------------------------------------------- */
+
+/*
+ * locking order
+ * (VFS)
+ * - src_dir and dir by lock_rename()
+ * - inode if exitsts
+ * (aufs)
+ * - lock all
+ *   + src_dentry and dentry by aufs_read_and_write_lock2() which calls,
+ *     + si_read_lock
+ *     + di_write_lock2_child()
+ *       + di_write_lock_child()
+ *	   + ii_write_lock_child()
+ *       + di_write_lock_child2()
+ *	   + ii_write_lock_child2()
+ *     + src_parent and parent
+ *       + di_write_lock_parent()
+ *	   + ii_write_lock_parent()
+ *       + di_write_lock_parent2()
+ *	   + ii_write_lock_parent2()
+ *   + lower src_dir and dir by vfsub_lock_rename()
+ *   + verify the every relationships between child and parent. if any
+ *     of them failed, unlock all and return -EBUSY.
+ */
+static void au_ren_unlock(struct au_ren_args *a)
+{
+	vfsub_unlock_rename(a->src_h_parent, a->src_hdir,
+			    a->dst_h_parent, a->dst_hdir);
+	if (au_ftest_ren(a->flags, MNT_WRITE))
+		vfsub_mnt_drop_write(au_br_mnt(a->br));
+}
+
+static int au_ren_lock(struct au_ren_args *a)
+{
+	int err;
+	unsigned int udba;
+
+	err = 0;
+	a->src_h_parent = au_h_dptr(a->src_parent, a->btgt);
+	a->src_hdir = au_hi(a->src_dir, a->btgt);
+	a->dst_h_parent = au_h_dptr(a->dst_parent, a->btgt);
+	a->dst_hdir = au_hi(a->dst_dir, a->btgt);
+
+	err = vfsub_mnt_want_write(au_br_mnt(a->br));
+	if (unlikely(err))
+		goto out;
+	au_fset_ren(a->flags, MNT_WRITE);
+	a->h_trap = vfsub_lock_rename(a->src_h_parent, a->src_hdir,
+				      a->dst_h_parent, a->dst_hdir);
+	udba = au_opt_udba(a->src_dentry->d_sb);
+	if (unlikely(a->src_hdir->hi_inode != d_inode(a->src_h_parent)
+		     || a->dst_hdir->hi_inode != d_inode(a->dst_h_parent)))
+		err = au_busy_or_stale();
+	if (!err && au_dbstart(a->src_dentry) == a->btgt)
+		err = au_h_verify(a->src_h_dentry, udba,
+				  d_inode(a->src_h_parent), a->src_h_parent,
+				  a->br);
+	if (!err && au_dbstart(a->dst_dentry) == a->btgt)
+		err = au_h_verify(a->dst_h_dentry, udba,
+				  d_inode(a->dst_h_parent), a->dst_h_parent,
+				  a->br);
+	if (!err)
+		goto out; /* success */
+
+	err = au_busy_or_stale();
+	au_ren_unlock(a);
+
+out:
+	return err;
+}
+
+/* ---------------------------------------------------------------------- */
+
+static void au_ren_refresh_dir(struct au_ren_args *a)
+{
+	struct inode *dir;
+
+	dir = a->dst_dir;
+	dir->i_version++;
+	if (au_ftest_ren(a->flags, ISDIR)) {
+		/* is this updating defined in POSIX? */
+		au_cpup_attr_timesizes(a->src_inode);
+		au_cpup_attr_nlink(dir, /*force*/1);
+	}
+
+	au_dir_ts(dir, a->btgt);
+
+	if (au_ftest_ren(a->flags, ISSAMEDIR))
+		return;
+
+	dir = a->src_dir;
+	dir->i_version++;
+	if (au_ftest_ren(a->flags, ISDIR))
+		au_cpup_attr_nlink(dir, /*force*/1);
+	au_dir_ts(dir, a->btgt);
+}
+
+static void au_ren_refresh(struct au_ren_args *a)
+{
+	aufs_bindex_t bend, bindex;
+	struct dentry *d, *h_d;
+	struct inode *i, *h_i;
+	struct super_block *sb;
+
+	d = a->dst_dentry;
+	d_drop(d);
+	if (a->h_dst)
+		/* already dget-ed by au_ren_or_cpup() */
+		au_set_h_dptr(d, a->btgt, a->h_dst);
+
+	i = a->dst_inode;
+	if (i) {
+		if (!au_ftest_ren(a->flags, ISDIR))
+			vfsub_drop_nlink(i);
+		else {
+			vfsub_dead_dir(i);
+			au_cpup_attr_timesizes(i);
+		}
+		au_update_dbrange(d, /*do_put_zero*/1);
+	} else {
+		bend = a->btgt;
+		for (bindex = au_dbstart(d); bindex < bend; bindex++)
+			au_set_h_dptr(d, bindex, NULL);
+		bend = au_dbend(d);
+		for (bindex = a->btgt + 1; bindex <= bend; bindex++)
+			au_set_h_dptr(d, bindex, NULL);
+		au_update_dbrange(d, /*do_put_zero*/0);
+	}
+
+	d = a->src_dentry;
+	au_set_dbwh(d, -1);
+	bend = au_dbend(d);
+	for (bindex = a->btgt + 1; bindex <= bend; bindex++) {
+		h_d = au_h_dptr(d, bindex);
+		if (h_d)
+			au_set_h_dptr(d, bindex, NULL);
+	}
+	au_set_dbend(d, a->btgt);
+
+	sb = d->d_sb;
+	i = a->src_inode;
+	if (au_opt_test(au_mntflags(sb), PLINK) && au_plink_test(i))
+		return; /* success */
+
+	bend = au_ibend(i);
+	for (bindex = a->btgt + 1; bindex <= bend; bindex++) {
+		h_i = au_h_iptr(i, bindex);
+		if (h_i) {
+			au_xino_write(sb, bindex, h_i->i_ino, /*ino*/0);
+			/* ignore this error */
+			au_set_h_iptr(i, bindex, NULL, 0);
+		}
+	}
+	au_set_ibend(i, a->btgt);
+}
+
+/* ---------------------------------------------------------------------- */
+
+/* mainly for link(2) and rename(2) */
+int au_wbr(struct dentry *dentry, aufs_bindex_t btgt)
+{
+	aufs_bindex_t bdiropq, bwh;
+	struct dentry *parent;
+	struct au_branch *br;
+
+	parent = dentry->d_parent;
+	IMustLock(d_inode(parent)); /* dir is locked */
+
+	bdiropq = au_dbdiropq(parent);
+	bwh = au_dbwh(dentry);
+	br = au_sbr(dentry->d_sb, btgt);
+	if (au_br_rdonly(br)
+	    || (0 <= bdiropq && bdiropq < btgt)
+	    || (0 <= bwh && bwh < btgt))
+		btgt = -1;
+
+	AuDbg("btgt %d\n", btgt);
+	return btgt;
+}
+
+/* sets src_bstart, dst_bstart and btgt */
+static int au_ren_wbr(struct au_ren_args *a)
+{
+	int err;
+	struct au_wr_dir_args wr_dir_args = {
+		/* .force_btgt	= -1, */
+		.flags		= AuWrDir_ADD_ENTRY
+	};
+
+	a->src_bstart = au_dbstart(a->src_dentry);
+	a->dst_bstart = au_dbstart(a->dst_dentry);
+	if (au_ftest_ren(a->flags, ISDIR))
+		au_fset_wrdir(wr_dir_args.flags, ISDIR);
+	wr_dir_args.force_btgt = a->src_bstart;
+	if (a->dst_inode && a->dst_bstart < a->src_bstart)
+		wr_dir_args.force_btgt = a->dst_bstart;
+	wr_dir_args.force_btgt = au_wbr(a->dst_dentry, wr_dir_args.force_btgt);
+	err = au_wr_dir(a->dst_dentry, a->src_dentry, &wr_dir_args);
+	a->btgt = err;
+
+	return err;
+}
+
+static void au_ren_dt(struct au_ren_args *a)
+{
+	a->h_path.dentry = a->src_h_parent;
+	au_dtime_store(a->src_dt + AuPARENT, a->src_parent, &a->h_path);
+	if (!au_ftest_ren(a->flags, ISSAMEDIR)) {
+		a->h_path.dentry = a->dst_h_parent;
+		au_dtime_store(a->dst_dt + AuPARENT, a->dst_parent, &a->h_path);
+	}
+
+	au_fclr_ren(a->flags, DT_DSTDIR);
+	if (!au_ftest_ren(a->flags, ISDIR))
+		return;
+
+	a->h_path.dentry = a->src_h_dentry;
+	au_dtime_store(a->src_dt + AuCHILD, a->src_dentry, &a->h_path);
+	if (d_is_positive(a->dst_h_dentry)) {
+		au_fset_ren(a->flags, DT_DSTDIR);
+		a->h_path.dentry = a->dst_h_dentry;
+		au_dtime_store(a->dst_dt + AuCHILD, a->dst_dentry, &a->h_path);
+	}
+}
+
+static void au_ren_rev_dt(int err, struct au_ren_args *a)
+{
+	struct dentry *h_d;
+	struct mutex *h_mtx;
+
+	au_dtime_revert(a->src_dt + AuPARENT);
+	if (!au_ftest_ren(a->flags, ISSAMEDIR))
+		au_dtime_revert(a->dst_dt + AuPARENT);
+
+	if (au_ftest_ren(a->flags, ISDIR) && err != -EIO) {
+		h_d = a->src_dt[AuCHILD].dt_h_path.dentry;
+		h_mtx = &d_inode(h_d)->i_mutex;
+		mutex_lock_nested(h_mtx, AuLsc_I_CHILD);
+		au_dtime_revert(a->src_dt + AuCHILD);
+		mutex_unlock(h_mtx);
+
+		if (au_ftest_ren(a->flags, DT_DSTDIR)) {
+			h_d = a->dst_dt[AuCHILD].dt_h_path.dentry;
+			h_mtx = &d_inode(h_d)->i_mutex;
+			mutex_lock_nested(h_mtx, AuLsc_I_CHILD);
+			au_dtime_revert(a->dst_dt + AuCHILD);
+			mutex_unlock(h_mtx);
+		}
+	}
+}
+
+/* ---------------------------------------------------------------------- */
+
+int aufs_rename(struct inode *_src_dir, struct dentry *_src_dentry,
+		struct inode *_dst_dir, struct dentry *_dst_dentry)
+{
+	int err, flags;
+	/* reduce stack space */
+	struct au_ren_args *a;
+
+	AuDbg("%pd, %pd\n", _src_dentry, _dst_dentry);
+	IMustLock(_src_dir);
+	IMustLock(_dst_dir);
+
+	err = -ENOMEM;
+	BUILD_BUG_ON(sizeof(*a) > PAGE_SIZE);
+	a = kzalloc(sizeof(*a), GFP_NOFS);
+	if (unlikely(!a))
+		goto out;
+
+	a->src_dir = _src_dir;
+	a->src_dentry = _src_dentry;
+	a->src_inode = NULL;
+	if (d_really_is_positive(a->src_dentry))
+		a->src_inode = d_inode(a->src_dentry);
+	a->src_parent = a->src_dentry->d_parent; /* dir inode is locked */
+	a->dst_dir = _dst_dir;
+	a->dst_dentry = _dst_dentry;
+	a->dst_inode = NULL;
+	if (d_really_is_positive(a->dst_dentry))
+		a->dst_inode = d_inode(a->dst_dentry);
+	a->dst_parent = a->dst_dentry->d_parent; /* dir inode is locked */
+	if (a->dst_inode) {
+		IMustLock(a->dst_inode);
+		au_igrab(a->dst_inode);
+	}
+
+	err = -ENOTDIR;
+	flags = AuLock_FLUSH | AuLock_NOPLM | AuLock_GEN;
+	if (d_is_dir(a->src_dentry)) {
+		au_fset_ren(a->flags, ISDIR);
+		if (unlikely(d_really_is_positive(a->dst_dentry)
+			     && !d_is_dir(a->dst_dentry)))
+			goto out_free;
+		flags |= AuLock_DIRS;
+	}
+	err = aufs_read_and_write_lock2(a->dst_dentry, a->src_dentry, flags);
+	if (unlikely(err))
+		goto out_free;
+
+	err = au_d_hashed_positive(a->src_dentry);
+	if (unlikely(err))
+		goto out_unlock;
+	err = -ENOENT;
+	if (a->dst_inode) {
+		/*
+		 * If it is a dir, VFS unhash dst_dentry before this
+		 * function. It means we cannot rely upon d_unhashed().
+		 */
+		if (unlikely(!a->dst_inode->i_nlink))
+			goto out_unlock;
+		if (!S_ISDIR(a->dst_inode->i_mode)) {
+			err = au_d_hashed_positive(a->dst_dentry);
+			if (unlikely(err))
+				goto out_unlock;
+		} else if (unlikely(IS_DEADDIR(a->dst_inode)))
+			goto out_unlock;
+	} else if (unlikely(d_unhashed(a->dst_dentry)))
+		goto out_unlock;
+
+	/*
+	 * is it possible?
+	 * yes, it happened (in linux-3.3-rcN) but I don't know why.
+	 * there may exist a problem somewhere else.
+	 */
+	err = -EINVAL;
+	if (unlikely(d_inode(a->dst_parent) == d_inode(a->src_dentry)))
+		goto out_unlock;
+
+	au_fset_ren(a->flags, ISSAMEDIR); /* temporary */
+	di_write_lock_parent(a->dst_parent);
+
+	/* which branch we process */
+	err = au_ren_wbr(a);
+	if (unlikely(err < 0))
+		goto out_parent;
+	a->br = au_sbr(a->dst_dentry->d_sb, a->btgt);
+	a->h_path.mnt = au_br_mnt(a->br);
+
+	/* are they available to be renamed */
+	err = au_ren_may_dir(a);
+	if (unlikely(err))
+		goto out_children;
+
+	/* prepare the writable parent dir on the same branch */
+	if (a->dst_bstart == a->btgt) {
+		au_fset_ren(a->flags, WHDST);
+	} else {
+		err = au_cpup_dirs(a->dst_dentry, a->btgt);
+		if (unlikely(err))
+			goto out_children;
+	}
+
+	if (a->src_dir != a->dst_dir) {
+		/*
+		 * this temporary unlock is safe,
+		 * because both dir->i_mutex are locked.
+		 */
+		di_write_unlock(a->dst_parent);
+		di_write_lock_parent(a->src_parent);
+		err = au_wr_dir_need_wh(a->src_dentry,
+					au_ftest_ren(a->flags, ISDIR),
+					&a->btgt);
+		di_write_unlock(a->src_parent);
+		di_write_lock2_parent(a->src_parent, a->dst_parent, /*isdir*/1);
+		au_fclr_ren(a->flags, ISSAMEDIR);
+	} else
+		err = au_wr_dir_need_wh(a->src_dentry,
+					au_ftest_ren(a->flags, ISDIR),
+					&a->btgt);
+	if (unlikely(err < 0))
+		goto out_children;
+	if (err)
+		au_fset_ren(a->flags, WHSRC);
+
+	/* cpup src */
+	if (a->src_bstart != a->btgt) {
+		struct au_pin pin;
+
+		err = au_pin(&pin, a->src_dentry, a->btgt,
+			     au_opt_udba(a->src_dentry->d_sb),
+			     AuPin_DI_LOCKED | AuPin_MNT_WRITE);
+		if (!err) {
+			struct au_cp_generic cpg = {
+				.dentry	= a->src_dentry,
+				.bdst	= a->btgt,
+				.bsrc	= a->src_bstart,
+				.len	= -1,
+				.pin	= &pin,
+				.flags	= AuCpup_DTIME | AuCpup_HOPEN
+			};
+			AuDebugOn(au_dbstart(a->src_dentry) != a->src_bstart);
+			err = au_sio_cpup_simple(&cpg);
+			au_unpin(&pin);
+		}
+		if (unlikely(err))
+			goto out_children;
+		a->src_bstart = a->btgt;
+		a->src_h_dentry = au_h_dptr(a->src_dentry, a->btgt);
+		au_fset_ren(a->flags, WHSRC);
+	}
+
+	/* lock them all */
+	err = au_ren_lock(a);
+	if (unlikely(err))
+		/* leave the copied-up one */
+		goto out_children;
+
+	if (!au_opt_test(au_mntflags(a->dst_dir->i_sb), UDBA_NONE))
+		err = au_may_ren(a);
+	else if (unlikely(a->dst_dentry->d_name.len > AUFS_MAX_NAMELEN))
+		err = -ENAMETOOLONG;
+	if (unlikely(err))
+		goto out_hdir;
+
+	/* store timestamps to be revertible */
+	au_ren_dt(a);
+
+	/* here we go */
+	err = do_rename(a);
+	if (unlikely(err))
+		goto out_dt;
+
+	/* update dir attributes */
+	au_ren_refresh_dir(a);
+
+	/* dput/iput all lower dentries */
+	au_ren_refresh(a);
+
+	goto out_hdir; /* success */
+
+out_dt:
+	au_ren_rev_dt(err, a);
+out_hdir:
+	au_ren_unlock(a);
+out_children:
+	au_nhash_wh_free(&a->whlist);
+	if (err && a->dst_inode && a->dst_bstart != a->btgt) {
+		AuDbg("bstart %d, btgt %d\n", a->dst_bstart, a->btgt);
+		au_set_h_dptr(a->dst_dentry, a->btgt, NULL);
+		au_set_dbstart(a->dst_dentry, a->dst_bstart);
+	}
+out_parent:
+	if (!err)
+		d_move(a->src_dentry, a->dst_dentry);
+	else {
+		au_update_dbstart(a->dst_dentry);
+		if (!a->dst_inode)
+			d_drop(a->dst_dentry);
+	}
+	if (au_ftest_ren(a->flags, ISSAMEDIR))
+		di_write_unlock(a->dst_parent);
+	else
+		di_write_unlock2(a->src_parent, a->dst_parent);
+out_unlock:
+	aufs_read_and_write_unlock2(a->dst_dentry, a->src_dentry);
+out_free:
+	iput(a->dst_inode);
+	if (a->thargs)
+		au_whtmp_rmdir_free(a->thargs);
+	kfree(a);
+out:
+	AuTraceErr(err);
+	return err;
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/fs/aufs/iinfo.c
@@ -0,0 +1,277 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+ *
+ * This program, aufs is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * inode private data
+ */
+
+#include "aufs.h"
+
+struct inode *au_h_iptr(struct inode *inode, aufs_bindex_t bindex)
+{
+	struct inode *h_inode;
+
+	IiMustAnyLock(inode);
+
+	h_inode = au_ii(inode)->ii_hinode[0 + bindex].hi_inode;
+	AuDebugOn(h_inode && atomic_read(&h_inode->i_count) <= 0);
+	return h_inode;
+}
+
+/* todo: hard/soft set? */
+void au_hiput(struct au_hinode *hinode)
+{
+	au_hn_free(hinode);
+	dput(hinode->hi_whdentry);
+	iput(hinode->hi_inode);
+}
+
+unsigned int au_hi_flags(struct inode *inode, int isdir)
+{
+	unsigned int flags;
+	const unsigned int mnt_flags = au_mntflags(inode->i_sb);
+
+	flags = 0;
+	if (au_opt_test(mnt_flags, XINO))
+		au_fset_hi(flags, XINO);
+	if (isdir && au_opt_test(mnt_flags, UDBA_HNOTIFY))
+		au_fset_hi(flags, HNOTIFY);
+	return flags;
+}
+
+void au_set_h_iptr(struct inode *inode, aufs_bindex_t bindex,
+		   struct inode *h_inode, unsigned int flags)
+{
+	struct au_hinode *hinode;
+	struct inode *hi;
+	struct au_iinfo *iinfo = au_ii(inode);
+
+	IiMustWriteLock(inode);
+
+	hinode = iinfo->ii_hinode + bindex;
+	hi = hinode->hi_inode;
+	AuDebugOn(h_inode && atomic_read(&h_inode->i_count) <= 0);
+
+	if (hi)
+		au_hiput(hinode);
+	hinode->hi_inode = h_inode;
+	if (h_inode) {
+		int err;
+		struct super_block *sb = inode->i_sb;
+		struct au_branch *br;
+
+		AuDebugOn(inode->i_mode
+			  && (h_inode->i_mode & S_IFMT)
+			  != (inode->i_mode & S_IFMT));
+		if (bindex == iinfo->ii_bstart)
+			au_cpup_igen(inode, h_inode);
+		br = au_sbr(sb, bindex);
+		hinode->hi_id = br->br_id;
+		if (au_ftest_hi(flags, XINO)) {
+			err = au_xino_write(sb, bindex, h_inode->i_ino,
+					    inode->i_ino);
+			if (unlikely(err))
+				AuIOErr1("failed au_xino_write() %d\n", err);
+		}
+
+		if (au_ftest_hi(flags, HNOTIFY)
+		    && au_br_hnotifyable(br->br_perm)) {
+			err = au_hn_alloc(hinode, inode);
+			if (unlikely(err))
+				AuIOErr1("au_hn_alloc() %d\n", err);
+		}
+	}
+}
+
+void au_set_hi_wh(struct inode *inode, aufs_bindex_t bindex,
+		  struct dentry *h_wh)
+{
+	struct au_hinode *hinode;
+
+	IiMustWriteLock(inode);
+
+	hinode = au_ii(inode)->ii_hinode + bindex;
+	AuDebugOn(hinode->hi_whdentry);
+	hinode->hi_whdentry = h_wh;
+}
+
+void au_update_iigen(struct inode *inode, int half)
+{
+	struct au_iinfo *iinfo;
+	struct au_iigen *iigen;
+	unsigned int sigen;
+
+	sigen = au_sigen(inode->i_sb);
+	iinfo = au_ii(inode);
+	iigen = &iinfo->ii_generation;
+	spin_lock(&iigen->ig_spin);
+	iigen->ig_generation = sigen;
+	if (half)
+		au_ig_fset(iigen->ig_flags, HALF_REFRESHED);
+	else
+		au_ig_fclr(iigen->ig_flags, HALF_REFRESHED);
+	spin_unlock(&iigen->ig_spin);
+}
+
+/* it may be called at remount time, too */
+void au_update_ibrange(struct inode *inode, int do_put_zero)
+{
+	struct au_iinfo *iinfo;
+	aufs_bindex_t bindex, bend;
+
+	iinfo = au_ii(inode);
+	if (!iinfo)
+		return;
+
+	IiMustWriteLock(inode);
+
+	if (do_put_zero && iinfo->ii_bstart >= 0) {
+		for (bindex = iinfo->ii_bstart; bindex <= iinfo->ii_bend;
+		     bindex++) {
+			struct inode *h_i;
+
+			h_i = iinfo->ii_hinode[0 + bindex].hi_inode;
+			if (h_i
+			    && !h_i->i_nlink
+			    && !(h_i->i_state & I_LINKABLE))
+				au_set_h_iptr(inode, bindex, NULL, 0);
+		}
+	}
+
+	iinfo->ii_bstart = -1;
+	iinfo->ii_bend = -1;
+	bend = au_sbend(inode->i_sb);
+	for (bindex = 0; bindex <= bend; bindex++)
+		if (iinfo->ii_hinode[0 + bindex].hi_inode) {
+			iinfo->ii_bstart = bindex;
+			break;
+		}
+	if (iinfo->ii_bstart >= 0)
+		for (bindex = bend; bindex >= iinfo->ii_bstart; bindex--)
+			if (iinfo->ii_hinode[0 + bindex].hi_inode) {
+				iinfo->ii_bend = bindex;
+				break;
+			}
+	AuDebugOn(iinfo->ii_bstart > iinfo->ii_bend);
+}
+
+/* ---------------------------------------------------------------------- */
+
+void au_icntnr_init_once(void *_c)
+{
+	struct au_icntnr *c = _c;
+	struct au_iinfo *iinfo = &c->iinfo;
+	static struct lock_class_key aufs_ii;
+
+	spin_lock_init(&iinfo->ii_generation.ig_spin);
+	au_rw_init(&iinfo->ii_rwsem);
+	au_rw_class(&iinfo->ii_rwsem, &aufs_ii);
+	inode_init_once(&c->vfs_inode);
+}
+
+int au_iinfo_init(struct inode *inode)
+{
+	struct au_iinfo *iinfo;
+	struct super_block *sb;
+	int nbr, i;
+
+	sb = inode->i_sb;
+	iinfo = &(container_of(inode, struct au_icntnr, vfs_inode)->iinfo);
+	nbr = au_sbend(sb) + 1;
+	if (unlikely(nbr <= 0))
+		nbr = 1;
+	iinfo->ii_hinode = kcalloc(nbr, sizeof(*iinfo->ii_hinode), GFP_NOFS);
+	if (iinfo->ii_hinode) {
+		au_ninodes_inc(sb);
+		for (i = 0; i < nbr; i++)
+			iinfo->ii_hinode[i].hi_id = -1;
+
+		iinfo->ii_generation.ig_generation = au_sigen(sb);
+		iinfo->ii_bstart = -1;
+		iinfo->ii_bend = -1;
+		iinfo->ii_vdir = NULL;
+		return 0;
+	}
+	return -ENOMEM;
+}
+
+int au_ii_realloc(struct au_iinfo *iinfo, int nbr)
+{
+	int err, sz;
+	struct au_hinode *hip;
+
+	AuRwMustWriteLock(&iinfo->ii_rwsem);
+
+	err = -ENOMEM;
+	sz = sizeof(*hip) * (iinfo->ii_bend + 1);
+	if (!sz)
+		sz = sizeof(*hip);
+	hip = au_kzrealloc(iinfo->ii_hinode, sz, sizeof(*hip) * nbr, GFP_NOFS);
+	if (hip) {
+		iinfo->ii_hinode = hip;
+		err = 0;
+	}
+
+	return err;
+}
+
+void au_iinfo_fin(struct inode *inode)
+{
+	struct au_iinfo *iinfo;
+	struct au_hinode *hi;
+	struct super_block *sb;
+	aufs_bindex_t bindex, bend;
+	const unsigned char unlinked = !inode->i_nlink;
+
+	iinfo = au_ii(inode);
+	/* bad_inode case */
+	if (!iinfo)
+		return;
+
+	sb = inode->i_sb;
+	au_ninodes_dec(sb);
+	if (si_pid_test(sb))
+		au_xino_delete_inode(inode, unlinked);
+	else {
+		/*
+		 * it is safe to hide the dependency between sbinfo and
+		 * sb->s_umount.
+		 */
+		lockdep_off();
+		si_noflush_read_lock(sb);
+		au_xino_delete_inode(inode, unlinked);
+		si_read_unlock(sb);
+		lockdep_on();
+	}
+
+	if (iinfo->ii_vdir)
+		au_vdir_free(iinfo->ii_vdir);
+
+	bindex = iinfo->ii_bstart;
+	if (bindex >= 0) {
+		hi = iinfo->ii_hinode + bindex;
+		bend = iinfo->ii_bend;
+		while (bindex++ <= bend) {
+			if (hi->hi_inode)
+				au_hiput(hi);
+			hi++;
+		}
+	}
+	kfree(iinfo->ii_hinode);
+	iinfo->ii_hinode = NULL;
+	AuRwDestroy(&iinfo->ii_rwsem);
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/fs/aufs/inode.c
@@ -0,0 +1,528 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+ *
+ * This program, aufs is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * inode functions
+ */
+
+#include "aufs.h"
+
+struct inode *au_igrab(struct inode *inode)
+{
+	if (inode) {
+		AuDebugOn(!atomic_read(&inode->i_count));
+		ihold(inode);
+	}
+	return inode;
+}
+
+static void au_refresh_hinode_attr(struct inode *inode, int do_version)
+{
+	au_cpup_attr_all(inode, /*force*/0);
+	au_update_iigen(inode, /*half*/1);
+	if (do_version)
+		inode->i_version++;
+}
+
+static int au_ii_refresh(struct inode *inode, int *update)
+{
+	int err, e;
+	umode_t type;
+	aufs_bindex_t bindex, new_bindex;
+	struct super_block *sb;
+	struct au_iinfo *iinfo;
+	struct au_hinode *p, *q, tmp;
+
+	IiMustWriteLock(inode);
+
+	*update = 0;
+	sb = inode->i_sb;
+	type = inode->i_mode & S_IFMT;
+	iinfo = au_ii(inode);
+	err = au_ii_realloc(iinfo, au_sbend(sb) + 1);
+	if (unlikely(err))
+		goto out;
+
+	AuDebugOn(iinfo->ii_bstart < 0);
+	p = iinfo->ii_hinode + iinfo->ii_bstart;
+	for (bindex = iinfo->ii_bstart; bindex <= iinfo->ii_bend;
+	     bindex++, p++) {
+		if (!p->hi_inode)
+			continue;
+
+		AuDebugOn(type != (p->hi_inode->i_mode & S_IFMT));
+		new_bindex = au_br_index(sb, p->hi_id);
+		if (new_bindex == bindex)
+			continue;
+
+		if (new_bindex < 0) {
+			*update = 1;
+			au_hiput(p);
+			p->hi_inode = NULL;
+			continue;
+		}
+
+		if (new_bindex < iinfo->ii_bstart)
+			iinfo->ii_bstart = new_bindex;
+		if (iinfo->ii_bend < new_bindex)
+			iinfo->ii_bend = new_bindex;
+		/* swap two lower inode, and loop again */
+		q = iinfo->ii_hinode + new_bindex;
+		tmp = *q;
+		*q = *p;
+		*p = tmp;
+		if (tmp.hi_inode) {
+			bindex--;
+			p--;
+		}
+	}
+	au_update_ibrange(inode, /*do_put_zero*/0);
+	e = au_dy_irefresh(inode);
+	if (unlikely(e && !err))
+		err = e;
+
+out:
+	AuTraceErr(err);
+	return err;
+}
+
+void au_refresh_iop(struct inode *inode, int force_getattr)
+{
+	int type;
+	struct au_sbinfo *sbi = au_sbi(inode->i_sb);
+	const struct inode_operations *iop
+		= force_getattr ? aufs_iop : sbi->si_iop_array;
+
+	if (inode->i_op == iop)
+		return;
+
+	switch (inode->i_mode & S_IFMT) {
+	case S_IFDIR:
+		type = AuIop_DIR;
+		break;
+	case S_IFLNK:
+		type = AuIop_SYMLINK;
+		break;
+	default:
+		type = AuIop_OTHER;
+		break;
+	}
+
+	inode->i_op = iop + type;
+	/* unnecessary smp_wmb() */
+}
+
+int au_refresh_hinode_self(struct inode *inode)
+{
+	int err, update;
+
+	err = au_ii_refresh(inode, &update);
+	if (!err)
+		au_refresh_hinode_attr(inode, update && S_ISDIR(inode->i_mode));
+
+	AuTraceErr(err);
+	return err;
+}
+
+int au_refresh_hinode(struct inode *inode, struct dentry *dentry)
+{
+	int err, e, update;
+	unsigned int flags;
+	umode_t mode;
+	aufs_bindex_t bindex, bend;
+	unsigned char isdir;
+	struct au_hinode *p;
+	struct au_iinfo *iinfo;
+
+	err = au_ii_refresh(inode, &update);
+	if (unlikely(err))
+		goto out;
+
+	update = 0;
+	iinfo = au_ii(inode);
+	p = iinfo->ii_hinode + iinfo->ii_bstart;
+	mode = (inode->i_mode & S_IFMT);
+	isdir = S_ISDIR(mode);
+	flags = au_hi_flags(inode, isdir);
+	bend = au_dbend(dentry);
+	for (bindex = au_dbstart(dentry); bindex <= bend; bindex++) {
+		struct inode *h_i, *h_inode;
+		struct dentry *h_d;
+
+		h_d = au_h_dptr(dentry, bindex);
+		if (!h_d || d_is_negative(h_d))
+			continue;
+
+		h_inode = d_inode(h_d);
+		AuDebugOn(mode != (h_inode->i_mode & S_IFMT));
+		if (iinfo->ii_bstart <= bindex && bindex <= iinfo->ii_bend) {
+			h_i = au_h_iptr(inode, bindex);
+			if (h_i) {
+				if (h_i == h_inode)
+					continue;
+				err = -EIO;
+				break;
+			}
+		}
+		if (bindex < iinfo->ii_bstart)
+			iinfo->ii_bstart = bindex;
+		if (iinfo->ii_bend < bindex)
+			iinfo->ii_bend = bindex;
+		au_set_h_iptr(inode, bindex, au_igrab(h_inode), flags);
+		update = 1;
+	}
+	au_update_ibrange(inode, /*do_put_zero*/0);
+	e = au_dy_irefresh(inode);
+	if (unlikely(e && !err))
+		err = e;
+	if (!err)
+		au_refresh_hinode_attr(inode, update && isdir);
+
+out:
+	AuTraceErr(err);
+	return err;
+}
+
+static int set_inode(struct inode *inode, struct dentry *dentry)
+{
+	int err;
+	unsigned int flags;
+	umode_t mode;
+	aufs_bindex_t bindex, bstart, btail;
+	unsigned char isdir;
+	struct dentry *h_dentry;
+	struct inode *h_inode;
+	struct au_iinfo *iinfo;
+	struct inode_operations *iop;
+
+	IiMustWriteLock(inode);
+
+	err = 0;
+	isdir = 0;
+	iop = au_sbi(inode->i_sb)->si_iop_array;
+	bstart = au_dbstart(dentry);
+	h_dentry = au_h_dptr(dentry, bstart);
+	h_inode = d_inode(h_dentry);
+	mode = h_inode->i_mode;
+	switch (mode & S_IFMT) {
+	case S_IFREG:
+		btail = au_dbtail(dentry);
+		inode->i_op = iop + AuIop_OTHER;
+		inode->i_fop = &aufs_file_fop;
+		err = au_dy_iaop(inode, bstart, h_inode);
+		if (unlikely(err))
+			goto out;
+		break;
+	case S_IFDIR:
+		isdir = 1;
+		btail = au_dbtaildir(dentry);
+		inode->i_op = iop + AuIop_DIR;
+		inode->i_fop = &aufs_dir_fop;
+		break;
+	case S_IFLNK:
+		btail = au_dbtail(dentry);
+		inode->i_op = iop + AuIop_SYMLINK;
+		break;
+	case S_IFBLK:
+	case S_IFCHR:
+	case S_IFIFO:
+	case S_IFSOCK:
+		btail = au_dbtail(dentry);
+		inode->i_op = iop + AuIop_OTHER;
+		init_special_inode(inode, mode, h_inode->i_rdev);
+		break;
+	default:
+		AuIOErr("Unknown file type 0%o\n", mode);
+		err = -EIO;
+		goto out;
+	}
+
+	/* do not set hnotify for whiteouted dirs (SHWH mode) */
+	flags = au_hi_flags(inode, isdir);
+	if (au_opt_test(au_mntflags(dentry->d_sb), SHWH)
+	    && au_ftest_hi(flags, HNOTIFY)
+	    && dentry->d_name.len > AUFS_WH_PFX_LEN
+	    && !memcmp(dentry->d_name.name, AUFS_WH_PFX, AUFS_WH_PFX_LEN))
+		au_fclr_hi(flags, HNOTIFY);
+	iinfo = au_ii(inode);
+	iinfo->ii_bstart = bstart;
+	iinfo->ii_bend = btail;
+	for (bindex = bstart; bindex <= btail; bindex++) {
+		h_dentry = au_h_dptr(dentry, bindex);
+		if (h_dentry)
+			au_set_h_iptr(inode, bindex,
+				      au_igrab(d_inode(h_dentry)), flags);
+	}
+	au_cpup_attr_all(inode, /*force*/1);
+	/*
+	 * to force calling aufs_get_acl() every time,
+	 * do not call cache_no_acl() for aufs inode.
+	 */
+
+out:
+	return err;
+}
+
+/*
+ * successful returns with iinfo write_locked
+ * minus: errno
+ * zero: success, matched
+ * plus: no error, but unmatched
+ */
+static int reval_inode(struct inode *inode, struct dentry *dentry)
+{
+	int err;
+	unsigned int gen;
+	struct au_iigen iigen;
+	aufs_bindex_t bindex, bend;
+	struct inode *h_inode, *h_dinode;
+	struct dentry *h_dentry;
+
+	/*
+	 * before this function, if aufs got any iinfo lock, it must be only
+	 * one, the parent dir.
+	 * it can happen by UDBA and the obsoleted inode number.
+	 */
+	err = -EIO;
+	if (unlikely(inode->i_ino == parent_ino(dentry)))
+		goto out;
+
+	err = 1;
+	ii_write_lock_new_child(inode);
+	h_dentry = au_h_dptr(dentry, au_dbstart(dentry));
+	h_dinode = d_inode(h_dentry);
+	bend = au_ibend(inode);
+	for (bindex = au_ibstart(inode); bindex <= bend; bindex++) {
+		h_inode = au_h_iptr(inode, bindex);
+		if (!h_inode || h_inode != h_dinode)
+			continue;
+
+		err = 0;
+		gen = au_iigen(inode, &iigen);
+		if (gen == au_digen(dentry)
+		    && !au_ig_ftest(iigen.ig_flags, HALF_REFRESHED))
+			break;
+
+		/* fully refresh inode using dentry */
+		err = au_refresh_hinode(inode, dentry);
+		if (!err)
+			au_update_iigen(inode, /*half*/0);
+		break;
+	}
+
+	if (unlikely(err))
+		ii_write_unlock(inode);
+out:
+	return err;
+}
+
+int au_ino(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
+	   unsigned int d_type, ino_t *ino)
+{
+	int err;
+	struct mutex *mtx;
+
+	/* prevent hardlinked inode number from race condition */
+	mtx = NULL;
+	if (d_type != DT_DIR) {
+		mtx = &au_sbr(sb, bindex)->br_xino.xi_nondir_mtx;
+		mutex_lock(mtx);
+	}
+	err = au_xino_read(sb, bindex, h_ino, ino);
+	if (unlikely(err))
+		goto out;
+
+	if (!*ino) {
+		err = -EIO;
+		*ino = au_xino_new_ino(sb);
+		if (unlikely(!*ino))
+			goto out;
+		err = au_xino_write(sb, bindex, h_ino, *ino);
+		if (unlikely(err))
+			goto out;
+	}
+
+out:
+	if (mtx)
+		mutex_unlock(mtx);
+	return err;
+}
+
+/* successful returns with iinfo write_locked */
+/* todo: return with unlocked? */
+struct inode *au_new_inode(struct dentry *dentry, int must_new)
+{
+	struct inode *inode, *h_inode;
+	struct dentry *h_dentry;
+	struct super_block *sb;
+	struct mutex *mtx;
+	ino_t h_ino, ino;
+	int err;
+	aufs_bindex_t bstart;
+
+	sb = dentry->d_sb;
+	bstart = au_dbstart(dentry);
+	h_dentry = au_h_dptr(dentry, bstart);
+	h_inode = d_inode(h_dentry);
+	h_ino = h_inode->i_ino;
+
+	/*
+	 * stop 'race'-ing between hardlinks under different
+	 * parents.
+	 */
+	mtx = NULL;
+	if (!d_is_dir(h_dentry))
+		mtx = &au_sbr(sb, bstart)->br_xino.xi_nondir_mtx;
+
+new_ino:
+	if (mtx)
+		mutex_lock(mtx);
+	err = au_xino_read(sb, bstart, h_ino, &ino);
+	inode = ERR_PTR(err);
+	if (unlikely(err))
+		goto out;
+
+	if (!ino) {
+		ino = au_xino_new_ino(sb);
+		if (unlikely(!ino)) {
+			inode = ERR_PTR(-EIO);
+			goto out;
+		}
+	}
+
+	AuDbg("i%lu\n", (unsigned long)ino);
+	inode = au_iget_locked(sb, ino);
+	err = PTR_ERR(inode);
+	if (IS_ERR(inode))
+		goto out;
+
+	AuDbg("%lx, new %d\n", inode->i_state, !!(inode->i_state & I_NEW));
+	if (inode->i_state & I_NEW) {
+		/* verbose coding for lock class name */
+		if (unlikely(d_is_symlink(h_dentry)))
+			au_rw_class(&au_ii(inode)->ii_rwsem,
+				    au_lc_key + AuLcSymlink_IIINFO);
+		else if (unlikely(d_is_dir(h_dentry)))
+			au_rw_class(&au_ii(inode)->ii_rwsem,
+				    au_lc_key + AuLcDir_IIINFO);
+		else /* likely */
+			au_rw_class(&au_ii(inode)->ii_rwsem,
+				    au_lc_key + AuLcNonDir_IIINFO);
+
+		ii_write_lock_new_child(inode);
+		err = set_inode(inode, dentry);
+		if (!err) {
+			unlock_new_inode(inode);
+			goto out; /* success */
+		}
+
+		/*
+		 * iget_failed() calls iput(), but we need to call
+		 * ii_write_unlock() after iget_failed(). so dirty hack for
+		 * i_count.
+		 */
+		atomic_inc(&inode->i_count);
+		iget_failed(inode);
+		ii_write_unlock(inode);
+		au_xino_write(sb, bstart, h_ino, /*ino*/0);
+		/* ignore this error */
+		goto out_iput;
+	} else if (!must_new && !IS_DEADDIR(inode) && inode->i_nlink) {
+		/*
+		 * horrible race condition between lookup, readdir and copyup
+		 * (or something).
+		 */
+		if (mtx)
+			mutex_unlock(mtx);
+		err = reval_inode(inode, dentry);
+		if (unlikely(err < 0)) {
+			mtx = NULL;
+			goto out_iput;
+		}
+
+		if (!err) {
+			mtx = NULL;
+			goto out; /* success */
+		} else if (mtx)
+			mutex_lock(mtx);
+	}
+
+	if (unlikely(au_test_fs_unique_ino(h_inode)))
+		AuWarn1("Warning: Un-notified UDBA or repeatedly renamed dir,"
+			" b%d, %s, %pd, hi%lu, i%lu.\n",
+			bstart, au_sbtype(h_dentry->d_sb), dentry,
+			(unsigned long)h_ino, (unsigned long)ino);
+	ino = 0;
+	err = au_xino_write(sb, bstart, h_ino, /*ino*/0);
+	if (!err) {
+		iput(inode);
+		if (mtx)
+			mutex_unlock(mtx);
+		goto new_ino;
+	}
+
+out_iput:
+	iput(inode);
+	inode = ERR_PTR(err);
+out:
+	if (mtx)
+		mutex_unlock(mtx);
+	return inode;
+}
+
+/* ---------------------------------------------------------------------- */
+
+int au_test_ro(struct super_block *sb, aufs_bindex_t bindex,
+	       struct inode *inode)
+{
+	int err;
+	struct inode *hi;
+
+	err = au_br_rdonly(au_sbr(sb, bindex));
+
+	/* pseudo-link after flushed may happen out of bounds */
+	if (!err
+	    && inode
+	    && au_ibstart(inode) <= bindex
+	    && bindex <= au_ibend(inode)) {
+		/*
+		 * permission check is unnecessary since vfsub routine
+		 * will be called later
+		 */
+		hi = au_h_iptr(inode, bindex);
+		if (hi)
+			err = IS_IMMUTABLE(hi) ? -EROFS : 0;
+	}
+
+	return err;
+}
+
+int au_test_h_perm(struct inode *h_inode, int mask)
+{
+	if (uid_eq(current_fsuid(), GLOBAL_ROOT_UID))
+		return 0;
+	return inode_permission(h_inode, mask);
+}
+
+int au_test_h_perm_sio(struct inode *h_inode, int mask)
+{
+	if (au_test_nfs(h_inode->i_sb)
+	    && (mask & MAY_WRITE)
+	    && S_ISDIR(h_inode->i_mode))
+		mask |= MAY_READ; /* force permission check */
+	return au_test_h_perm(h_inode, mask);
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/fs/aufs/inode.h
@@ -0,0 +1,685 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+ *
+ * This program, aufs is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * inode operations
+ */
+
+#ifndef __AUFS_INODE_H__
+#define __AUFS_INODE_H__
+
+#ifdef __KERNEL__
+
+#include <linux/fsnotify.h>
+#include "rwsem.h"
+
+struct vfsmount;
+
+struct au_hnotify {
+#ifdef CONFIG_AUFS_HNOTIFY
+#ifdef CONFIG_AUFS_HFSNOTIFY
+	/* never use fsnotify_add_vfsmount_mark() */
+	struct fsnotify_mark		hn_mark;
+#endif
+	struct inode			*hn_aufs_inode;	/* no get/put */
+#endif
+} ____cacheline_aligned_in_smp;
+
+struct au_hinode {
+	struct inode		*hi_inode;
+	aufs_bindex_t		hi_id;
+#ifdef CONFIG_AUFS_HNOTIFY
+	struct au_hnotify	*hi_notify;
+#endif
+
+	/* reference to the copied-up whiteout with get/put */
+	struct dentry		*hi_whdentry;
+};
+
+/* ig_flags */
+#define AuIG_HALF_REFRESHED		1
+#define au_ig_ftest(flags, name)	((flags) & AuIG_##name)
+#define au_ig_fset(flags, name) \
+	do { (flags) |= AuIG_##name; } while (0)
+#define au_ig_fclr(flags, name) \
+	do { (flags) &= ~AuIG_##name; } while (0)
+
+struct au_iigen {
+	spinlock_t	ig_spin;
+	__u32		ig_generation, ig_flags;
+};
+
+struct au_vdir;
+struct au_iinfo {
+	struct au_iigen		ii_generation;
+	struct super_block	*ii_hsb1;	/* no get/put */
+
+	struct au_rwsem		ii_rwsem;
+	aufs_bindex_t		ii_bstart, ii_bend;
+	__u32			ii_higen;
+	struct au_hinode	*ii_hinode;
+	struct au_vdir		*ii_vdir;
+};
+
+struct au_icntnr {
+	struct au_iinfo iinfo;
+	struct inode vfs_inode;
+} ____cacheline_aligned_in_smp;
+
+/* au_pin flags */
+#define AuPin_DI_LOCKED		1
+#define AuPin_MNT_WRITE		(1 << 1)
+#define au_ftest_pin(flags, name)	((flags) & AuPin_##name)
+#define au_fset_pin(flags, name) \
+	do { (flags) |= AuPin_##name; } while (0)
+#define au_fclr_pin(flags, name) \
+	do { (flags) &= ~AuPin_##name; } while (0)
+
+struct au_pin {
+	/* input */
+	struct dentry *dentry;
+	unsigned int udba;
+	unsigned char lsc_di, lsc_hi, flags;
+	aufs_bindex_t bindex;
+
+	/* output */
+	struct dentry *parent;
+	struct au_hinode *hdir;
+	struct vfsmount *h_mnt;
+
+	/* temporary unlock/relock for copyup */
+	struct dentry *h_dentry, *h_parent;
+	struct au_branch *br;
+	struct task_struct *task;
+};
+
+void au_pin_hdir_unlock(struct au_pin *p);
+int au_pin_hdir_lock(struct au_pin *p);
+int au_pin_hdir_relock(struct au_pin *p);
+void au_pin_hdir_set_owner(struct au_pin *p, struct task_struct *task);
+void au_pin_hdir_acquire_nest(struct au_pin *p);
+void au_pin_hdir_release(struct au_pin *p);
+
+/* ---------------------------------------------------------------------- */
+
+static inline struct au_iinfo *au_ii(struct inode *inode)
+{
+	struct au_iinfo *iinfo;
+
+	iinfo = &(container_of(inode, struct au_icntnr, vfs_inode)->iinfo);
+	if (iinfo->ii_hinode)
+		return iinfo;
+	return NULL; /* debugging bad_inode case */
+}
+
+/* ---------------------------------------------------------------------- */
+
+/* inode.c */
+struct inode *au_igrab(struct inode *inode);
+void au_refresh_iop(struct inode *inode, int force_getattr);
+int au_refresh_hinode_self(struct inode *inode);
+int au_refresh_hinode(struct inode *inode, struct dentry *dentry);
+int au_ino(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
+	   unsigned int d_type, ino_t *ino);
+struct inode *au_new_inode(struct dentry *dentry, int must_new);
+int au_test_ro(struct super_block *sb, aufs_bindex_t bindex,
+	       struct inode *inode);
+int au_test_h_perm(struct inode *h_inode, int mask);
+int au_test_h_perm_sio(struct inode *h_inode, int mask);
+
+static inline int au_wh_ino(struct super_block *sb, aufs_bindex_t bindex,
+			    ino_t h_ino, unsigned int d_type, ino_t *ino)
+{
+#ifdef CONFIG_AUFS_SHWH
+	return au_ino(sb, bindex, h_ino, d_type, ino);
+#else
+	return 0;
+#endif
+}
+
+/* i_op.c */
+enum {
+	AuIop_SYMLINK,
+	AuIop_DIR,
+	AuIop_OTHER,
+	AuIop_Last
+};
+extern struct inode_operations aufs_iop[AuIop_Last],
+	aufs_iop_nogetattr[AuIop_Last];
+
+/* au_wr_dir flags */
+#define AuWrDir_ADD_ENTRY	1
+#define AuWrDir_ISDIR		(1 << 1)
+#define AuWrDir_TMPFILE		(1 << 2)
+#define au_ftest_wrdir(flags, name)	((flags) & AuWrDir_##name)
+#define au_fset_wrdir(flags, name) \
+	do { (flags) |= AuWrDir_##name; } while (0)
+#define au_fclr_wrdir(flags, name) \
+	do { (flags) &= ~AuWrDir_##name; } while (0)
+
+struct au_wr_dir_args {
+	aufs_bindex_t force_btgt;
+	unsigned char flags;
+};
+int au_wr_dir(struct dentry *dentry, struct dentry *src_dentry,
+	      struct au_wr_dir_args *args);
+
+struct dentry *au_pinned_h_parent(struct au_pin *pin);
+void au_pin_init(struct au_pin *pin, struct dentry *dentry,
+		 aufs_bindex_t bindex, int lsc_di, int lsc_hi,
+		 unsigned int udba, unsigned char flags);
+int au_pin(struct au_pin *pin, struct dentry *dentry, aufs_bindex_t bindex,
+	   unsigned int udba, unsigned char flags) __must_check;
+int au_do_pin(struct au_pin *pin) __must_check;
+void au_unpin(struct au_pin *pin);
+int au_reval_for_attr(struct dentry *dentry, unsigned int sigen);
+
+#define AuIcpup_DID_CPUP	1
+#define au_ftest_icpup(flags, name)	((flags) & AuIcpup_##name)
+#define au_fset_icpup(flags, name) \
+	do { (flags) |= AuIcpup_##name; } while (0)
+#define au_fclr_icpup(flags, name) \
+	do { (flags) &= ~AuIcpup_##name; } while (0)
+
+struct au_icpup_args {
+	unsigned char flags;
+	unsigned char pin_flags;
+	aufs_bindex_t btgt;
+	unsigned int udba;
+	struct au_pin pin;
+	struct path h_path;
+	struct inode *h_inode;
+};
+
+int au_pin_and_icpup(struct dentry *dentry, struct iattr *ia,
+		     struct au_icpup_args *a);
+
+int au_h_path_getattr(struct dentry *dentry, int force, struct path *h_path);
+
+/* i_op_add.c */
+int au_may_add(struct dentry *dentry, aufs_bindex_t bindex,
+	       struct dentry *h_parent, int isdir);
+int aufs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode,
+	       dev_t dev);
+int aufs_symlink(struct inode *dir, struct dentry *dentry, const char *symname);
+int aufs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
+		bool want_excl);
+struct vfsub_aopen_args;
+int au_aopen_or_create(struct inode *dir, struct dentry *dentry,
+		       struct vfsub_aopen_args *args);
+int aufs_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode);
+int aufs_link(struct dentry *src_dentry, struct inode *dir,
+	      struct dentry *dentry);
+int aufs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode);
+
+/* i_op_del.c */
+int au_wr_dir_need_wh(struct dentry *dentry, int isdir, aufs_bindex_t *bcpup);
+int au_may_del(struct dentry *dentry, aufs_bindex_t bindex,
+	       struct dentry *h_parent, int isdir);
+int aufs_unlink(struct inode *dir, struct dentry *dentry);
+int aufs_rmdir(struct inode *dir, struct dentry *dentry);
+
+/* i_op_ren.c */
+int au_wbr(struct dentry *dentry, aufs_bindex_t btgt);
+int aufs_rename(struct inode *src_dir, struct dentry *src_dentry,
+		struct inode *dir, struct dentry *dentry);
+
+/* iinfo.c */
+struct inode *au_h_iptr(struct inode *inode, aufs_bindex_t bindex);
+void au_hiput(struct au_hinode *hinode);
+void au_set_hi_wh(struct inode *inode, aufs_bindex_t bindex,
+		  struct dentry *h_wh);
+unsigned int au_hi_flags(struct inode *inode, int isdir);
+
+/* hinode flags */
+#define AuHi_XINO	1
+#define AuHi_HNOTIFY	(1 << 1)
+#define au_ftest_hi(flags, name)	((flags) & AuHi_##name)
+#define au_fset_hi(flags, name) \
+	do { (flags) |= AuHi_##name; } while (0)
+#define au_fclr_hi(flags, name) \
+	do { (flags) &= ~AuHi_##name; } while (0)
+
+#ifndef CONFIG_AUFS_HNOTIFY
+#undef AuHi_HNOTIFY
+#define AuHi_HNOTIFY	0
+#endif
+
+void au_set_h_iptr(struct inode *inode, aufs_bindex_t bindex,
+		   struct inode *h_inode, unsigned int flags);
+
+void au_update_iigen(struct inode *inode, int half);
+void au_update_ibrange(struct inode *inode, int do_put_zero);
+
+void au_icntnr_init_once(void *_c);
+int au_iinfo_init(struct inode *inode);
+void au_iinfo_fin(struct inode *inode);
+int au_ii_realloc(struct au_iinfo *iinfo, int nbr);
+
+#ifdef CONFIG_PROC_FS
+/* plink.c */
+int au_plink_maint(struct super_block *sb, int flags);
+struct au_sbinfo;
+void au_plink_maint_leave(struct au_sbinfo *sbinfo);
+int au_plink_maint_enter(struct super_block *sb);
+#ifdef CONFIG_AUFS_DEBUG
+void au_plink_list(struct super_block *sb);
+#else
+AuStubVoid(au_plink_list, struct super_block *sb)
+#endif
+int au_plink_test(struct inode *inode);
+struct dentry *au_plink_lkup(struct inode *inode, aufs_bindex_t bindex);
+void au_plink_append(struct inode *inode, aufs_bindex_t bindex,
+		     struct dentry *h_dentry);
+void au_plink_put(struct super_block *sb, int verbose);
+void au_plink_clean(struct super_block *sb, int verbose);
+void au_plink_half_refresh(struct super_block *sb, aufs_bindex_t br_id);
+#else
+AuStubInt0(au_plink_maint, struct super_block *sb, int flags);
+AuStubVoid(au_plink_maint_leave, struct au_sbinfo *sbinfo);
+AuStubInt0(au_plink_maint_enter, struct super_block *sb);
+AuStubVoid(au_plink_list, struct super_block *sb);
+AuStubInt0(au_plink_test, struct inode *inode);
+AuStub(struct dentry *, au_plink_lkup, return NULL,
+       struct inode *inode, aufs_bindex_t bindex);
+AuStubVoid(au_plink_append, struct inode *inode, aufs_bindex_t bindex,
+	   struct dentry *h_dentry);
+AuStubVoid(au_plink_put, struct super_block *sb, int verbose);
+AuStubVoid(au_plink_clean, struct super_block *sb, int verbose);
+AuStubVoid(au_plink_half_refresh, struct super_block *sb, aufs_bindex_t br_id);
+#endif /* CONFIG_PROC_FS */
+
+#ifdef CONFIG_AUFS_XATTR
+/* xattr.c */
+int au_cpup_xattr(struct dentry *h_dst, struct dentry *h_src, int ignore_flags,
+		  unsigned int verbose);
+ssize_t aufs_listxattr(struct dentry *dentry, char *list, size_t size);
+ssize_t aufs_getxattr(struct dentry *dentry, const char *name, void *value,
+		      size_t size);
+int aufs_setxattr(struct dentry *dentry, const char *name, const void *value,
+		  size_t size, int flags);
+int aufs_removexattr(struct dentry *dentry, const char *name);
+
+/* void au_xattr_init(struct super_block *sb); */
+#else
+AuStubInt0(au_cpup_xattr, struct dentry *h_dst, struct dentry *h_src,
+	   int ignore_flags, unsigned int verbose);
+/* AuStubVoid(au_xattr_init, struct super_block *sb); */
+#endif
+
+#ifdef CONFIG_FS_POSIX_ACL
+struct posix_acl *aufs_get_acl(struct inode *inode, int type);
+int aufs_set_acl(struct inode *inode, struct posix_acl *acl, int type);
+#endif
+
+#if IS_ENABLED(CONFIG_AUFS_XATTR) || IS_ENABLED(CONFIG_FS_POSIX_ACL)
+enum {
+	AU_XATTR_SET,
+	AU_XATTR_REMOVE,
+	AU_ACL_SET
+};
+
+struct au_srxattr {
+	int type;
+	union {
+		struct {
+			const char	*name;
+			const void	*value;
+			size_t		size;
+			int		flags;
+		} set;
+		struct {
+			const char	*name;
+		} remove;
+		struct {
+			struct posix_acl *acl;
+			int		type;
+		} acl_set;
+	} u;
+};
+ssize_t au_srxattr(struct dentry *dentry, struct au_srxattr *arg);
+#endif
+
+/* ---------------------------------------------------------------------- */
+
+/* lock subclass for iinfo */
+enum {
+	AuLsc_II_CHILD,		/* child first */
+	AuLsc_II_CHILD2,	/* rename(2), link(2), and cpup at hnotify */
+	AuLsc_II_CHILD3,	/* copyup dirs */
+	AuLsc_II_PARENT,	/* see AuLsc_I_PARENT in vfsub.h */
+	AuLsc_II_PARENT2,
+	AuLsc_II_PARENT3,	/* copyup dirs */
+	AuLsc_II_NEW_CHILD
+};
+
+/*
+ * ii_read_lock_child, ii_write_lock_child,
+ * ii_read_lock_child2, ii_write_lock_child2,
+ * ii_read_lock_child3, ii_write_lock_child3,
+ * ii_read_lock_parent, ii_write_lock_parent,
+ * ii_read_lock_parent2, ii_write_lock_parent2,
+ * ii_read_lock_parent3, ii_write_lock_parent3,
+ * ii_read_lock_new_child, ii_write_lock_new_child,
+ */
+#define AuReadLockFunc(name, lsc) \
+static inline void ii_read_lock_##name(struct inode *i) \
+{ \
+	au_rw_read_lock_nested(&au_ii(i)->ii_rwsem, AuLsc_II_##lsc); \
+}
+
+#define AuWriteLockFunc(name, lsc) \
+static inline void ii_write_lock_##name(struct inode *i) \
+{ \
+	au_rw_write_lock_nested(&au_ii(i)->ii_rwsem, AuLsc_II_##lsc); \
+}
+
+#define AuRWLockFuncs(name, lsc) \
+	AuReadLockFunc(name, lsc) \
+	AuWriteLockFunc(name, lsc)
+
+AuRWLockFuncs(child, CHILD);
+AuRWLockFuncs(child2, CHILD2);
+AuRWLockFuncs(child3, CHILD3);
+AuRWLockFuncs(parent, PARENT);
+AuRWLockFuncs(parent2, PARENT2);
+AuRWLockFuncs(parent3, PARENT3);
+AuRWLockFuncs(new_child, NEW_CHILD);
+
+#undef AuReadLockFunc
+#undef AuWriteLockFunc
+#undef AuRWLockFuncs
+
+/*
+ * ii_read_unlock, ii_write_unlock, ii_downgrade_lock
+ */
+AuSimpleUnlockRwsemFuncs(ii, struct inode *i, &au_ii(i)->ii_rwsem);
+
+#define IiMustNoWaiters(i)	AuRwMustNoWaiters(&au_ii(i)->ii_rwsem)
+#define IiMustAnyLock(i)	AuRwMustAnyLock(&au_ii(i)->ii_rwsem)
+#define IiMustWriteLock(i)	AuRwMustWriteLock(&au_ii(i)->ii_rwsem)
+
+/* ---------------------------------------------------------------------- */
+
+static inline void au_icntnr_init(struct au_icntnr *c)
+{
+#ifdef CONFIG_AUFS_DEBUG
+	c->vfs_inode.i_mode = 0;
+#endif
+}
+
+static inline unsigned int au_iigen(struct inode *inode, struct au_iigen *iigen_arg)
+{
+	unsigned int gen;
+	struct au_iinfo *iinfo;
+	struct au_iigen *iigen;
+
+	iinfo = au_ii(inode);
+	iigen = &iinfo->ii_generation;
+	spin_lock(&iigen->ig_spin);
+	if (iigen_arg)
+		*iigen_arg = *iigen;
+	gen = iigen->ig_generation;
+	spin_unlock(&iigen->ig_spin);
+
+	return gen;
+}
+
+/* tiny test for inode number */
+/* tmpfs generation is too rough */
+static inline int au_test_higen(struct inode *inode, struct inode *h_inode)
+{
+	struct au_iinfo *iinfo;
+
+	iinfo = au_ii(inode);
+	AuRwMustAnyLock(&iinfo->ii_rwsem);
+	return !(iinfo->ii_hsb1 == h_inode->i_sb
+		 && iinfo->ii_higen == h_inode->i_generation);
+}
+
+static inline void au_iigen_dec(struct inode *inode)
+{
+	struct au_iinfo *iinfo;
+	struct au_iigen *iigen;
+
+	iinfo = au_ii(inode);
+	iigen = &iinfo->ii_generation;
+	spin_lock(&iigen->ig_spin);
+	iigen->ig_generation--;
+	spin_unlock(&iigen->ig_spin);
+}
+
+static inline int au_iigen_test(struct inode *inode, unsigned int sigen)
+{
+	int err;
+
+	err = 0;
+	if (unlikely(inode && au_iigen(inode, NULL) != sigen))
+		err = -EIO;
+
+	return err;
+}
+
+/* ---------------------------------------------------------------------- */
+
+static inline aufs_bindex_t au_ii_br_id(struct inode *inode,
+					aufs_bindex_t bindex)
+{
+	IiMustAnyLock(inode);
+	return au_ii(inode)->ii_hinode[0 + bindex].hi_id;
+}
+
+static inline aufs_bindex_t au_ibstart(struct inode *inode)
+{
+	IiMustAnyLock(inode);
+	return au_ii(inode)->ii_bstart;
+}
+
+static inline aufs_bindex_t au_ibend(struct inode *inode)
+{
+	IiMustAnyLock(inode);
+	return au_ii(inode)->ii_bend;
+}
+
+static inline struct au_vdir *au_ivdir(struct inode *inode)
+{
+	IiMustAnyLock(inode);
+	return au_ii(inode)->ii_vdir;
+}
+
+static inline struct dentry *au_hi_wh(struct inode *inode, aufs_bindex_t bindex)
+{
+	IiMustAnyLock(inode);
+	return au_ii(inode)->ii_hinode[0 + bindex].hi_whdentry;
+}
+
+static inline void au_set_ibstart(struct inode *inode, aufs_bindex_t bindex)
+{
+	IiMustWriteLock(inode);
+	au_ii(inode)->ii_bstart = bindex;
+}
+
+static inline void au_set_ibend(struct inode *inode, aufs_bindex_t bindex)
+{
+	IiMustWriteLock(inode);
+	au_ii(inode)->ii_bend = bindex;
+}
+
+static inline void au_set_ivdir(struct inode *inode, struct au_vdir *vdir)
+{
+	IiMustWriteLock(inode);
+	au_ii(inode)->ii_vdir = vdir;
+}
+
+static inline struct au_hinode *au_hi(struct inode *inode, aufs_bindex_t bindex)
+{
+	IiMustAnyLock(inode);
+	return au_ii(inode)->ii_hinode + bindex;
+}
+
+/* ---------------------------------------------------------------------- */
+
+static inline struct dentry *au_pinned_parent(struct au_pin *pin)
+{
+	if (pin)
+		return pin->parent;
+	return NULL;
+}
+
+static inline struct inode *au_pinned_h_dir(struct au_pin *pin)
+{
+	if (pin && pin->hdir)
+		return pin->hdir->hi_inode;
+	return NULL;
+}
+
+static inline struct au_hinode *au_pinned_hdir(struct au_pin *pin)
+{
+	if (pin)
+		return pin->hdir;
+	return NULL;
+}
+
+static inline void au_pin_set_dentry(struct au_pin *pin, struct dentry *dentry)
+{
+	if (pin)
+		pin->dentry = dentry;
+}
+
+static inline void au_pin_set_parent_lflag(struct au_pin *pin,
+					   unsigned char lflag)
+{
+	if (pin) {
+		if (lflag)
+			au_fset_pin(pin->flags, DI_LOCKED);
+		else
+			au_fclr_pin(pin->flags, DI_LOCKED);
+	}
+}
+
+#if 0 /* reserved */
+static inline void au_pin_set_parent(struct au_pin *pin, struct dentry *parent)
+{
+	if (pin) {
+		dput(pin->parent);
+		pin->parent = dget(parent);
+	}
+}
+#endif
+
+/* ---------------------------------------------------------------------- */
+
+struct au_branch;
+#ifdef CONFIG_AUFS_HNOTIFY
+struct au_hnotify_op {
+	void (*ctl)(struct au_hinode *hinode, int do_set);
+	int (*alloc)(struct au_hinode *hinode);
+
+	/*
+	 * if it returns true, the the caller should free hinode->hi_notify,
+	 * otherwise ->free() frees it.
+	 */
+	int (*free)(struct au_hinode *hinode,
+		    struct au_hnotify *hn) __must_check;
+
+	void (*fin)(void);
+	int (*init)(void);
+
+	int (*reset_br)(unsigned int udba, struct au_branch *br, int perm);
+	void (*fin_br)(struct au_branch *br);
+	int (*init_br)(struct au_branch *br, int perm);
+};
+
+/* hnotify.c */
+int au_hn_alloc(struct au_hinode *hinode, struct inode *inode);
+void au_hn_free(struct au_hinode *hinode);
+void au_hn_ctl(struct au_hinode *hinode, int do_set);
+void au_hn_reset(struct inode *inode, unsigned int flags);
+int au_hnotify(struct inode *h_dir, struct au_hnotify *hnotify, u32 mask,
+	       struct qstr *h_child_qstr, struct inode *h_child_inode);
+int au_hnotify_reset_br(unsigned int udba, struct au_branch *br, int perm);
+int au_hnotify_init_br(struct au_branch *br, int perm);
+void au_hnotify_fin_br(struct au_branch *br);
+int __init au_hnotify_init(void);
+void au_hnotify_fin(void);
+
+/* hfsnotify.c */
+extern const struct au_hnotify_op au_hnotify_op;
+
+static inline
+void au_hn_init(struct au_hinode *hinode)
+{
+	hinode->hi_notify = NULL;
+}
+
+static inline struct au_hnotify *au_hn(struct au_hinode *hinode)
+{
+	return hinode->hi_notify;
+}
+
+#else
+AuStub(int, au_hn_alloc, return -EOPNOTSUPP,
+       struct au_hinode *hinode __maybe_unused,
+       struct inode *inode __maybe_unused)
+AuStub(struct au_hnotify *, au_hn, return NULL, struct au_hinode *hinode)
+AuStubVoid(au_hn_free, struct au_hinode *hinode __maybe_unused)
+AuStubVoid(au_hn_ctl, struct au_hinode *hinode __maybe_unused,
+	   int do_set __maybe_unused)
+AuStubVoid(au_hn_reset, struct inode *inode __maybe_unused,
+	   unsigned int flags __maybe_unused)
+AuStubInt0(au_hnotify_reset_br, unsigned int udba __maybe_unused,
+	   struct au_branch *br __maybe_unused,
+	   int perm __maybe_unused)
+AuStubInt0(au_hnotify_init_br, struct au_branch *br __maybe_unused,
+	   int perm __maybe_unused)
+AuStubVoid(au_hnotify_fin_br, struct au_branch *br __maybe_unused)
+AuStubInt0(__init au_hnotify_init, void)
+AuStubVoid(au_hnotify_fin, void)
+AuStubVoid(au_hn_init, struct au_hinode *hinode __maybe_unused)
+#endif /* CONFIG_AUFS_HNOTIFY */
+
+static inline void au_hn_suspend(struct au_hinode *hdir)
+{
+	au_hn_ctl(hdir, /*do_set*/0);
+}
+
+static inline void au_hn_resume(struct au_hinode *hdir)
+{
+	au_hn_ctl(hdir, /*do_set*/1);
+}
+
+static inline void au_hn_imtx_lock(struct au_hinode *hdir)
+{
+	mutex_lock(&hdir->hi_inode->i_mutex);
+	au_hn_suspend(hdir);
+}
+
+static inline void au_hn_imtx_lock_nested(struct au_hinode *hdir,
+					  unsigned int sc __maybe_unused)
+{
+	mutex_lock_nested(&hdir->hi_inode->i_mutex, sc);
+	au_hn_suspend(hdir);
+}
+
+static inline void au_hn_imtx_unlock(struct au_hinode *hdir)
+{
+	au_hn_resume(hdir);
+	mutex_unlock(&hdir->hi_inode->i_mutex);
+}
+
+#endif /* __KERNEL__ */
+#endif /* __AUFS_INODE_H__ */
--- /dev/null
+++ zfcpdump-kernel-4.4/fs/aufs/ioctl.c
@@ -0,0 +1,219 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+ *
+ * This program, aufs is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * ioctl
+ * plink-management and readdir in userspace.
+ * assist the pathconf(3) wrapper library.
+ * move-down
+ * File-based Hierarchical Storage Management.
+ */
+
+#include <linux/compat.h>
+#include <linux/file.h>
+#include "aufs.h"
+
+static int au_wbr_fd(struct path *path, struct aufs_wbr_fd __user *arg)
+{
+	int err, fd;
+	aufs_bindex_t wbi, bindex, bend;
+	struct file *h_file;
+	struct super_block *sb;
+	struct dentry *root;
+	struct au_branch *br;
+	struct aufs_wbr_fd wbrfd = {
+		.oflags	= au_dir_roflags,
+		.brid	= -1
+	};
+	const int valid = O_RDONLY | O_NONBLOCK | O_LARGEFILE | O_DIRECTORY
+		| O_NOATIME | O_CLOEXEC;
+
+	AuDebugOn(wbrfd.oflags & ~valid);
+
+	if (arg) {
+		err = copy_from_user(&wbrfd, arg, sizeof(wbrfd));
+		if (unlikely(err)) {
+			err = -EFAULT;
+			goto out;
+		}
+
+		err = -EINVAL;
+		AuDbg("wbrfd{0%o, %d}\n", wbrfd.oflags, wbrfd.brid);
+		wbrfd.oflags |= au_dir_roflags;
+		AuDbg("0%o\n", wbrfd.oflags);
+		if (unlikely(wbrfd.oflags & ~valid))
+			goto out;
+	}
+
+	fd = get_unused_fd_flags(0);
+	err = fd;
+	if (unlikely(fd < 0))
+		goto out;
+
+	h_file = ERR_PTR(-EINVAL);
+	wbi = 0;
+	br = NULL;
+	sb = path->dentry->d_sb;
+	root = sb->s_root;
+	aufs_read_lock(root, AuLock_IR);
+	bend = au_sbend(sb);
+	if (wbrfd.brid >= 0) {
+		wbi = au_br_index(sb, wbrfd.brid);
+		if (unlikely(wbi < 0 || wbi > bend))
+			goto out_unlock;
+	}
+
+	h_file = ERR_PTR(-ENOENT);
+	br = au_sbr(sb, wbi);
+	if (!au_br_writable(br->br_perm)) {
+		if (arg)
+			goto out_unlock;
+
+		bindex = wbi + 1;
+		wbi = -1;
+		for (; bindex <= bend; bindex++) {
+			br = au_sbr(sb, bindex);
+			if (au_br_writable(br->br_perm)) {
+				wbi = bindex;
+				br = au_sbr(sb, wbi);
+				break;
+			}
+		}
+	}
+	AuDbg("wbi %d\n", wbi);
+	if (wbi >= 0)
+		h_file = au_h_open(root, wbi, wbrfd.oflags, NULL,
+				   /*force_wr*/0);
+
+out_unlock:
+	aufs_read_unlock(root, AuLock_IR);
+	err = PTR_ERR(h_file);
+	if (IS_ERR(h_file))
+		goto out_fd;
+
+	atomic_dec(&br->br_count); /* cf. au_h_open() */
+	fd_install(fd, h_file);
+	err = fd;
+	goto out; /* success */
+
+out_fd:
+	put_unused_fd(fd);
+out:
+	AuTraceErr(err);
+	return err;
+}
+
+/* ---------------------------------------------------------------------- */
+
+long aufs_ioctl_dir(struct file *file, unsigned int cmd, unsigned long arg)
+{
+	long err;
+	struct dentry *dentry;
+
+	switch (cmd) {
+	case AUFS_CTL_RDU:
+	case AUFS_CTL_RDU_INO:
+		err = au_rdu_ioctl(file, cmd, arg);
+		break;
+
+	case AUFS_CTL_WBR_FD:
+		err = au_wbr_fd(&file->f_path, (void __user *)arg);
+		break;
+
+	case AUFS_CTL_IBUSY:
+		err = au_ibusy_ioctl(file, arg);
+		break;
+
+	case AUFS_CTL_BRINFO:
+		err = au_brinfo_ioctl(file, arg);
+		break;
+
+	case AUFS_CTL_FHSM_FD:
+		dentry = file->f_path.dentry;
+		if (IS_ROOT(dentry))
+			err = au_fhsm_fd(dentry->d_sb, arg);
+		else
+			err = -ENOTTY;
+		break;
+
+	default:
+		/* do not call the lower */
+		AuDbg("0x%x\n", cmd);
+		err = -ENOTTY;
+	}
+
+	AuTraceErr(err);
+	return err;
+}
+
+long aufs_ioctl_nondir(struct file *file, unsigned int cmd, unsigned long arg)
+{
+	long err;
+
+	switch (cmd) {
+	case AUFS_CTL_MVDOWN:
+		err = au_mvdown(file->f_path.dentry, (void __user *)arg);
+		break;
+
+	case AUFS_CTL_WBR_FD:
+		err = au_wbr_fd(&file->f_path, (void __user *)arg);
+		break;
+
+	default:
+		/* do not call the lower */
+		AuDbg("0x%x\n", cmd);
+		err = -ENOTTY;
+	}
+
+	AuTraceErr(err);
+	return err;
+}
+
+#ifdef CONFIG_COMPAT
+long aufs_compat_ioctl_dir(struct file *file, unsigned int cmd,
+			   unsigned long arg)
+{
+	long err;
+
+	switch (cmd) {
+	case AUFS_CTL_RDU:
+	case AUFS_CTL_RDU_INO:
+		err = au_rdu_compat_ioctl(file, cmd, arg);
+		break;
+
+	case AUFS_CTL_IBUSY:
+		err = au_ibusy_compat_ioctl(file, arg);
+		break;
+
+	case AUFS_CTL_BRINFO:
+		err = au_brinfo_compat_ioctl(file, arg);
+		break;
+
+	default:
+		err = aufs_ioctl_dir(file, cmd, arg);
+	}
+
+	AuTraceErr(err);
+	return err;
+}
+
+long aufs_compat_ioctl_nondir(struct file *file, unsigned int cmd,
+			      unsigned long arg)
+{
+	return aufs_ioctl_nondir(file, cmd, (unsigned long)compat_ptr(arg));
+}
+#endif
--- /dev/null
+++ zfcpdump-kernel-4.4/fs/aufs/loop.c
@@ -0,0 +1,162 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+ *
+ * This program, aufs is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * support for loopback block device as a branch
+ */
+
+#include "aufs.h"
+
+/* added into drivers/block/loop.c */
+static struct file *(*backing_file_func)(struct super_block *sb);
+
+/*
+ * test if two lower dentries have overlapping branches.
+ */
+int au_test_loopback_overlap(struct super_block *sb, struct dentry *h_adding)
+{
+	struct super_block *h_sb;
+	struct file *backing_file;
+
+	if (unlikely(!backing_file_func)) {
+		/* don't load "loop" module here */
+		backing_file_func = symbol_get(loop_backing_file);
+		if (unlikely(!backing_file_func))
+			/* "loop" module is not loaded */
+			return 0;
+	}
+
+	h_sb = h_adding->d_sb;
+	backing_file = backing_file_func(h_sb);
+	if (!backing_file)
+		return 0;
+
+	h_adding = backing_file->f_path.dentry;
+	/*
+	 * h_adding can be local NFS.
+	 * in this case aufs cannot detect the loop.
+	 */
+	if (unlikely(h_adding->d_sb == sb))
+		return 1;
+	return !!au_test_subdir(h_adding, sb->s_root);
+}
+
+/* true if a kernel thread named 'loop[0-9].*' accesses a file */
+int au_test_loopback_kthread(void)
+{
+	int ret;
+	struct task_struct *tsk = current;
+	char c, comm[sizeof(tsk->comm)];
+
+	ret = 0;
+	if (tsk->flags & PF_KTHREAD) {
+		get_task_comm(comm, tsk);
+		c = comm[4];
+		ret = ('0' <= c && c <= '9'
+		       && !strncmp(comm, "loop", 4));
+	}
+
+	return ret;
+}
+
+/* ---------------------------------------------------------------------- */
+
+#define au_warn_loopback_step	16
+static int au_warn_loopback_nelem = au_warn_loopback_step;
+static unsigned long *au_warn_loopback_array;
+
+void au_warn_loopback(struct super_block *h_sb)
+{
+	int i, new_nelem;
+	unsigned long *a, magic;
+	static DEFINE_SPINLOCK(spin);
+
+	magic = h_sb->s_magic;
+	spin_lock(&spin);
+	a = au_warn_loopback_array;
+	for (i = 0; i < au_warn_loopback_nelem && *a; i++)
+		if (a[i] == magic) {
+			spin_unlock(&spin);
+			return;
+		}
+
+	/* h_sb is new to us, print it */
+	if (i < au_warn_loopback_nelem) {
+		a[i] = magic;
+		goto pr;
+	}
+
+	/* expand the array */
+	new_nelem = au_warn_loopback_nelem + au_warn_loopback_step;
+	a = au_kzrealloc(au_warn_loopback_array,
+			 au_warn_loopback_nelem * sizeof(unsigned long),
+			 new_nelem * sizeof(unsigned long), GFP_ATOMIC);
+	if (a) {
+		au_warn_loopback_nelem = new_nelem;
+		au_warn_loopback_array = a;
+		a[i] = magic;
+		goto pr;
+	}
+
+	spin_unlock(&spin);
+	AuWarn1("realloc failed, ignored\n");
+	return;
+
+pr:
+	spin_unlock(&spin);
+	pr_warn("you may want to try another patch for loopback file "
+		"on %s(0x%lx) branch\n", au_sbtype(h_sb), magic);
+}
+
+int au_loopback_init(void)
+{
+	int err;
+	struct super_block *sb __maybe_unused;
+
+	BUILD_BUG_ON(sizeof(sb->s_magic) != sizeof(unsigned long));
+
+	err = 0;
+	au_warn_loopback_array = kcalloc(au_warn_loopback_step,
+					 sizeof(unsigned long), GFP_NOFS);
+	if (unlikely(!au_warn_loopback_array))
+		err = -ENOMEM;
+
+	return err;
+}
+
+void au_loopback_fin(void)
+{
+	if (backing_file_func)
+		symbol_put(loop_backing_file);
+	kfree(au_warn_loopback_array);
+}
+
+/* ---------------------------------------------------------------------- */
+
+/* support the loopback block device insude aufs */
+
+struct file *aufs_real_loop(struct file *file)
+{
+	struct file *f;
+
+	BUG_ON(!au_test_aufs(file->f_path.dentry->d_sb));
+	fi_read_lock(file);
+	f = au_hf_top(file);
+	fi_read_unlock(file);
+	AuDebugOn(!f);
+	return f;
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/fs/aufs/loop.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+ *
+ * This program, aufs is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * support for loopback mount as a branch
+ */
+
+#ifndef __AUFS_LOOP_H__
+#define __AUFS_LOOP_H__
+
+#ifdef __KERNEL__
+
+struct dentry;
+struct super_block;
+
+#ifdef CONFIG_AUFS_BDEV_LOOP
+/* drivers/block/loop.c */
+struct file *loop_backing_file(struct super_block *sb);
+
+/* loop.c */
+int au_test_loopback_overlap(struct super_block *sb, struct dentry *h_adding);
+int au_test_loopback_kthread(void);
+void au_warn_loopback(struct super_block *h_sb);
+
+int au_loopback_init(void);
+void au_loopback_fin(void);
+
+struct file *aufs_real_loop(struct file *file);
+#else
+AuStub(struct file *, loop_backing_file, return NULL)
+
+AuStubInt0(au_test_loopback_overlap, struct super_block *sb,
+	   struct dentry *h_adding)
+AuStubInt0(au_test_loopback_kthread, void)
+AuStubVoid(au_warn_loopback, struct super_block *h_sb)
+
+AuStubInt0(au_loopback_init, void)
+AuStubVoid(au_loopback_fin, void)
+
+AuStub(struct file *, aufs_real_loop, return NULL, struct file *file)
+#endif /* BLK_DEV_LOOP */
+
+#endif /* __KERNEL__ */
+#endif /* __AUFS_LOOP_H__ */
--- /dev/null
+++ zfcpdump-kernel-4.4/fs/aufs/magic.mk
@@ -0,0 +1,30 @@
+
+# defined in ${srctree}/fs/fuse/inode.c
+# tristate
+ifdef CONFIG_FUSE_FS
+ccflags-y += -DFUSE_SUPER_MAGIC=0x65735546
+endif
+
+# defined in ${srctree}/fs/xfs/xfs_sb.h
+# tristate
+ifdef CONFIG_XFS_FS
+ccflags-y += -DXFS_SB_MAGIC=0x58465342
+endif
+
+# defined in ${srctree}/fs/configfs/mount.c
+# tristate
+ifdef CONFIG_CONFIGFS_FS
+ccflags-y += -DCONFIGFS_MAGIC=0x62656570
+endif
+
+# defined in ${srctree}/fs/ubifs/ubifs.h
+# tristate
+ifdef CONFIG_UBIFS_FS
+ccflags-y += -DUBIFS_SUPER_MAGIC=0x24051905
+endif
+
+# defined in ${srctree}/fs/hfsplus/hfsplus_raw.h
+# tristate
+ifdef CONFIG_HFSPLUS_FS
+ccflags-y += -DHFSPLUS_SUPER_MAGIC=0x482b
+endif
--- /dev/null
+++ zfcpdump-kernel-4.4/fs/aufs/module.c
@@ -0,0 +1,221 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+ *
+ * This program, aufs is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * module global variables and operations
+ */
+
+#include <linux/module.h>
+#include <linux/seq_file.h>
+#include "aufs.h"
+
+void *au_kzrealloc(void *p, unsigned int nused, unsigned int new_sz, gfp_t gfp)
+{
+	if (new_sz <= nused)
+		return p;
+
+	p = krealloc(p, new_sz, gfp);
+	if (p)
+		memset(p + nused, 0, new_sz - nused);
+	return p;
+}
+
+/* ---------------------------------------------------------------------- */
+
+/*
+ * aufs caches
+ */
+struct kmem_cache *au_cachep[AuCache_Last];
+static int __init au_cache_init(void)
+{
+	au_cachep[AuCache_DINFO] = AuCacheCtor(au_dinfo, au_di_init_once);
+	if (au_cachep[AuCache_DINFO])
+		/* SLAB_DESTROY_BY_RCU */
+		au_cachep[AuCache_ICNTNR] = AuCacheCtor(au_icntnr,
+							au_icntnr_init_once);
+	if (au_cachep[AuCache_ICNTNR])
+		au_cachep[AuCache_FINFO] = AuCacheCtor(au_finfo,
+						       au_fi_init_once);
+	if (au_cachep[AuCache_FINFO])
+		au_cachep[AuCache_VDIR] = AuCache(au_vdir);
+	if (au_cachep[AuCache_VDIR])
+		au_cachep[AuCache_DEHSTR] = AuCache(au_vdir_dehstr);
+	if (au_cachep[AuCache_DEHSTR])
+		return 0;
+
+	return -ENOMEM;
+}
+
+static void au_cache_fin(void)
+{
+	int i;
+
+	/*
+	 * Make sure all delayed rcu free inodes are flushed before we
+	 * destroy cache.
+	 */
+	rcu_barrier();
+
+	/* excluding AuCache_HNOTIFY */
+	BUILD_BUG_ON(AuCache_HNOTIFY + 1 != AuCache_Last);
+	for (i = 0; i < AuCache_HNOTIFY; i++) {
+		kmem_cache_destroy(au_cachep[i]);
+		au_cachep[i] = NULL;
+	}
+}
+
+/* ---------------------------------------------------------------------- */
+
+int au_dir_roflags;
+
+#ifdef CONFIG_AUFS_SBILIST
+/*
+ * iterate_supers_type() doesn't protect us from
+ * remounting (branch management)
+ */
+struct au_splhead au_sbilist;
+#endif
+
+struct lock_class_key au_lc_key[AuLcKey_Last];
+
+/*
+ * functions for module interface.
+ */
+MODULE_LICENSE("GPL");
+/* MODULE_LICENSE("GPL v2"); */
+MODULE_AUTHOR("Junjiro R. Okajima <aufs-users@lists.sourceforge.net>");
+MODULE_DESCRIPTION(AUFS_NAME
+	" -- Advanced multi layered unification filesystem");
+MODULE_VERSION(AUFS_VERSION);
+MODULE_ALIAS_FS(AUFS_NAME);
+
+/* this module parameter has no meaning when SYSFS is disabled */
+int sysaufs_brs = 1;
+MODULE_PARM_DESC(brs, "use <sysfs>/fs/aufs/si_*/brN");
+module_param_named(brs, sysaufs_brs, int, S_IRUGO);
+
+/* this module parameter has no meaning when USER_NS is disabled */
+static bool au_userns;
+MODULE_PARM_DESC(allow_userns, "allow unprivileged to mount under userns");
+module_param_named(allow_userns, au_userns, bool, S_IRUGO);
+
+/* ---------------------------------------------------------------------- */
+
+static char au_esc_chars[0x20 + 3]; /* 0x01-0x20, backslash, del, and NULL */
+
+int au_seq_path(struct seq_file *seq, struct path *path)
+{
+	int err;
+
+	err = seq_path(seq, path, au_esc_chars);
+	if (err > 0)
+		err = 0;
+	else if (err < 0)
+		err = -ENOMEM;
+
+	return err;
+}
+
+/* ---------------------------------------------------------------------- */
+
+static int __init aufs_init(void)
+{
+	int err, i;
+	char *p;
+
+	p = au_esc_chars;
+	for (i = 1; i <= ' '; i++)
+		*p++ = i;
+	*p++ = '\\';
+	*p++ = '\x7f';
+	*p = 0;
+
+	au_dir_roflags = au_file_roflags(O_DIRECTORY | O_LARGEFILE);
+
+	memcpy(aufs_iop_nogetattr, aufs_iop, sizeof(aufs_iop));
+	for (i = 0; i < AuIop_Last; i++)
+		aufs_iop_nogetattr[i].getattr = NULL;
+
+	au_sbilist_init();
+	sysaufs_brs_init();
+	au_debug_init();
+	au_dy_init();
+	err = sysaufs_init();
+	if (unlikely(err))
+		goto out;
+	err = au_procfs_init();
+	if (unlikely(err))
+		goto out_sysaufs;
+	err = au_wkq_init();
+	if (unlikely(err))
+		goto out_procfs;
+	err = au_loopback_init();
+	if (unlikely(err))
+		goto out_wkq;
+	err = au_hnotify_init();
+	if (unlikely(err))
+		goto out_loopback;
+	err = au_sysrq_init();
+	if (unlikely(err))
+		goto out_hin;
+	err = au_cache_init();
+	if (unlikely(err))
+		goto out_sysrq;
+
+	aufs_fs_type.fs_flags |= au_userns ? FS_USERNS_MOUNT : 0;
+	err = register_filesystem(&aufs_fs_type);
+	if (unlikely(err))
+		goto out_cache;
+
+	/* since we define pr_fmt, call printk directly */
+	printk(KERN_INFO AUFS_NAME " " AUFS_VERSION "\n");
+	goto out; /* success */
+
+out_cache:
+	au_cache_fin();
+out_sysrq:
+	au_sysrq_fin();
+out_hin:
+	au_hnotify_fin();
+out_loopback:
+	au_loopback_fin();
+out_wkq:
+	au_wkq_fin();
+out_procfs:
+	au_procfs_fin();
+out_sysaufs:
+	sysaufs_fin();
+	au_dy_fin();
+out:
+	return err;
+}
+
+static void __exit aufs_exit(void)
+{
+	unregister_filesystem(&aufs_fs_type);
+	au_cache_fin();
+	au_sysrq_fin();
+	au_hnotify_fin();
+	au_loopback_fin();
+	au_wkq_fin();
+	au_procfs_fin();
+	sysaufs_fin();
+	au_dy_fin();
+}
+
+module_init(aufs_init);
+module_exit(aufs_exit);
--- /dev/null
+++ zfcpdump-kernel-4.4/fs/aufs/module.h
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+ *
+ * This program, aufs is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * module initialization and module-global
+ */
+
+#ifndef __AUFS_MODULE_H__
+#define __AUFS_MODULE_H__
+
+#ifdef __KERNEL__
+
+#include <linux/slab.h>
+
+struct path;
+struct seq_file;
+
+/* module parameters */
+extern int sysaufs_brs;
+
+/* ---------------------------------------------------------------------- */
+
+extern int au_dir_roflags;
+
+enum {
+	AuLcNonDir_FIINFO,
+	AuLcNonDir_DIINFO,
+	AuLcNonDir_IIINFO,
+
+	AuLcDir_FIINFO,
+	AuLcDir_DIINFO,
+	AuLcDir_IIINFO,
+
+	AuLcSymlink_DIINFO,
+	AuLcSymlink_IIINFO,
+
+	AuLcKey_Last
+};
+extern struct lock_class_key au_lc_key[AuLcKey_Last];
+
+void *au_kzrealloc(void *p, unsigned int nused, unsigned int new_sz, gfp_t gfp);
+int au_seq_path(struct seq_file *seq, struct path *path);
+
+#ifdef CONFIG_PROC_FS
+/* procfs.c */
+int __init au_procfs_init(void);
+void au_procfs_fin(void);
+#else
+AuStubInt0(au_procfs_init, void);
+AuStubVoid(au_procfs_fin, void);
+#endif
+
+/* ---------------------------------------------------------------------- */
+
+/* kmem cache */
+enum {
+	AuCache_DINFO,
+	AuCache_ICNTNR,
+	AuCache_FINFO,
+	AuCache_VDIR,
+	AuCache_DEHSTR,
+	AuCache_HNOTIFY, /* must be last */
+	AuCache_Last
+};
+
+#define AuCacheFlags		(SLAB_RECLAIM_ACCOUNT | SLAB_MEM_SPREAD)
+#define AuCache(type)		KMEM_CACHE(type, AuCacheFlags)
+#define AuCacheCtor(type, ctor)	\
+	kmem_cache_create(#type, sizeof(struct type), \
+			  __alignof__(struct type), AuCacheFlags, ctor)
+
+extern struct kmem_cache *au_cachep[];
+
+#define AuCacheFuncs(name, index) \
+static inline struct au_##name *au_cache_alloc_##name(void) \
+{ return kmem_cache_alloc(au_cachep[AuCache_##index], GFP_NOFS); } \
+static inline void au_cache_free_##name(struct au_##name *p) \
+{ kmem_cache_free(au_cachep[AuCache_##index], p); }
+
+AuCacheFuncs(dinfo, DINFO);
+AuCacheFuncs(icntnr, ICNTNR);
+AuCacheFuncs(finfo, FINFO);
+AuCacheFuncs(vdir, VDIR);
+AuCacheFuncs(vdir_dehstr, DEHSTR);
+#ifdef CONFIG_AUFS_HNOTIFY
+AuCacheFuncs(hnotify, HNOTIFY);
+#endif
+
+#endif /* __KERNEL__ */
+#endif /* __AUFS_MODULE_H__ */
--- /dev/null
+++ zfcpdump-kernel-4.4/fs/aufs/mvdown.c
@@ -0,0 +1,703 @@
+/*
+ * Copyright (C) 2011-2015 Junjiro R. Okajima
+ *
+ * This program, aufs is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * move-down, opposite of copy-up
+ */
+
+#include "aufs.h"
+
+struct au_mvd_args {
+	struct {
+		struct super_block *h_sb;
+		struct dentry *h_parent;
+		struct au_hinode *hdir;
+		struct inode *h_dir, *h_inode;
+		struct au_pin pin;
+	} info[AUFS_MVDOWN_NARRAY];
+
+	struct aufs_mvdown mvdown;
+	struct dentry *dentry, *parent;
+	struct inode *inode, *dir;
+	struct super_block *sb;
+	aufs_bindex_t bopq, bwh, bfound;
+	unsigned char rename_lock;
+};
+
+#define mvd_errno		mvdown.au_errno
+#define mvd_bsrc		mvdown.stbr[AUFS_MVDOWN_UPPER].bindex
+#define mvd_src_brid		mvdown.stbr[AUFS_MVDOWN_UPPER].brid
+#define mvd_bdst		mvdown.stbr[AUFS_MVDOWN_LOWER].bindex
+#define mvd_dst_brid		mvdown.stbr[AUFS_MVDOWN_LOWER].brid
+
+#define mvd_h_src_sb		info[AUFS_MVDOWN_UPPER].h_sb
+#define mvd_h_src_parent	info[AUFS_MVDOWN_UPPER].h_parent
+#define mvd_hdir_src		info[AUFS_MVDOWN_UPPER].hdir
+#define mvd_h_src_dir		info[AUFS_MVDOWN_UPPER].h_dir
+#define mvd_h_src_inode		info[AUFS_MVDOWN_UPPER].h_inode
+#define mvd_pin_src		info[AUFS_MVDOWN_UPPER].pin
+
+#define mvd_h_dst_sb		info[AUFS_MVDOWN_LOWER].h_sb
+#define mvd_h_dst_parent	info[AUFS_MVDOWN_LOWER].h_parent
+#define mvd_hdir_dst		info[AUFS_MVDOWN_LOWER].hdir
+#define mvd_h_dst_dir		info[AUFS_MVDOWN_LOWER].h_dir
+#define mvd_h_dst_inode		info[AUFS_MVDOWN_LOWER].h_inode
+#define mvd_pin_dst		info[AUFS_MVDOWN_LOWER].pin
+
+#define AU_MVD_PR(flag, ...) do {			\
+		if (flag)				\
+			pr_err(__VA_ARGS__);		\
+	} while (0)
+
+static int find_lower_writable(struct au_mvd_args *a)
+{
+	struct super_block *sb;
+	aufs_bindex_t bindex, bend;
+	struct au_branch *br;
+
+	sb = a->sb;
+	bindex = a->mvd_bsrc;
+	bend = au_sbend(sb);
+	if (a->mvdown.flags & AUFS_MVDOWN_FHSM_LOWER)
+		for (bindex++; bindex <= bend; bindex++) {
+			br = au_sbr(sb, bindex);
+			if (au_br_fhsm(br->br_perm)
+			    && (!(au_br_sb(br)->s_flags & MS_RDONLY)))
+				return bindex;
+		}
+	else if (!(a->mvdown.flags & AUFS_MVDOWN_ROLOWER))
+		for (bindex++; bindex <= bend; bindex++) {
+			br = au_sbr(sb, bindex);
+			if (!au_br_rdonly(br))
+				return bindex;
+		}
+	else
+		for (bindex++; bindex <= bend; bindex++) {
+			br = au_sbr(sb, bindex);
+			if (!(au_br_sb(br)->s_flags & MS_RDONLY)) {
+				if (au_br_rdonly(br))
+					a->mvdown.flags
+						|= AUFS_MVDOWN_ROLOWER_R;
+				return bindex;
+			}
+		}
+
+	return -1;
+}
+
+/* make the parent dir on bdst */
+static int au_do_mkdir(const unsigned char dmsg, struct au_mvd_args *a)
+{
+	int err;
+
+	err = 0;
+	a->mvd_hdir_src = au_hi(a->dir, a->mvd_bsrc);
+	a->mvd_hdir_dst = au_hi(a->dir, a->mvd_bdst);
+	a->mvd_h_src_parent = au_h_dptr(a->parent, a->mvd_bsrc);
+	a->mvd_h_dst_parent = NULL;
+	if (au_dbend(a->parent) >= a->mvd_bdst)
+		a->mvd_h_dst_parent = au_h_dptr(a->parent, a->mvd_bdst);
+	if (!a->mvd_h_dst_parent) {
+		err = au_cpdown_dirs(a->dentry, a->mvd_bdst);
+		if (unlikely(err)) {
+			AU_MVD_PR(dmsg, "cpdown_dirs failed\n");
+			goto out;
+		}
+		a->mvd_h_dst_parent = au_h_dptr(a->parent, a->mvd_bdst);
+	}
+
+out:
+	AuTraceErr(err);
+	return err;
+}
+
+/* lock them all */
+static int au_do_lock(const unsigned char dmsg, struct au_mvd_args *a)
+{
+	int err;
+	struct dentry *h_trap;
+
+	a->mvd_h_src_sb = au_sbr_sb(a->sb, a->mvd_bsrc);
+	a->mvd_h_dst_sb = au_sbr_sb(a->sb, a->mvd_bdst);
+	err = au_pin(&a->mvd_pin_dst, a->dentry, a->mvd_bdst,
+		     au_opt_udba(a->sb),
+		     AuPin_MNT_WRITE | AuPin_DI_LOCKED);
+	AuTraceErr(err);
+	if (unlikely(err)) {
+		AU_MVD_PR(dmsg, "pin_dst failed\n");
+		goto out;
+	}
+
+	if (a->mvd_h_src_sb != a->mvd_h_dst_sb) {
+		a->rename_lock = 0;
+		au_pin_init(&a->mvd_pin_src, a->dentry, a->mvd_bsrc,
+			    AuLsc_DI_PARENT, AuLsc_I_PARENT3,
+			    au_opt_udba(a->sb),
+			    AuPin_MNT_WRITE | AuPin_DI_LOCKED);
+		err = au_do_pin(&a->mvd_pin_src);
+		AuTraceErr(err);
+		a->mvd_h_src_dir = d_inode(a->mvd_h_src_parent);
+		if (unlikely(err)) {
+			AU_MVD_PR(dmsg, "pin_src failed\n");
+			goto out_dst;
+		}
+		goto out; /* success */
+	}
+
+	a->rename_lock = 1;
+	au_pin_hdir_unlock(&a->mvd_pin_dst);
+	err = au_pin(&a->mvd_pin_src, a->dentry, a->mvd_bsrc,
+		     au_opt_udba(a->sb),
+		     AuPin_MNT_WRITE | AuPin_DI_LOCKED);
+	AuTraceErr(err);
+	a->mvd_h_src_dir = d_inode(a->mvd_h_src_parent);
+	if (unlikely(err)) {
+		AU_MVD_PR(dmsg, "pin_src failed\n");
+		au_pin_hdir_lock(&a->mvd_pin_dst);
+		goto out_dst;
+	}
+	au_pin_hdir_unlock(&a->mvd_pin_src);
+	h_trap = vfsub_lock_rename(a->mvd_h_src_parent, a->mvd_hdir_src,
+				   a->mvd_h_dst_parent, a->mvd_hdir_dst);
+	if (h_trap) {
+		err = (h_trap != a->mvd_h_src_parent);
+		if (err)
+			err = (h_trap != a->mvd_h_dst_parent);
+	}
+	BUG_ON(err); /* it should never happen */
+	if (unlikely(a->mvd_h_src_dir != au_pinned_h_dir(&a->mvd_pin_src))) {
+		err = -EBUSY;
+		AuTraceErr(err);
+		vfsub_unlock_rename(a->mvd_h_src_parent, a->mvd_hdir_src,
+				    a->mvd_h_dst_parent, a->mvd_hdir_dst);
+		au_pin_hdir_lock(&a->mvd_pin_src);
+		au_unpin(&a->mvd_pin_src);
+		au_pin_hdir_lock(&a->mvd_pin_dst);
+		goto out_dst;
+	}
+	goto out; /* success */
+
+out_dst:
+	au_unpin(&a->mvd_pin_dst);
+out:
+	AuTraceErr(err);
+	return err;
+}
+
+static void au_do_unlock(const unsigned char dmsg, struct au_mvd_args *a)
+{
+	if (!a->rename_lock)
+		au_unpin(&a->mvd_pin_src);
+	else {
+		vfsub_unlock_rename(a->mvd_h_src_parent, a->mvd_hdir_src,
+				    a->mvd_h_dst_parent, a->mvd_hdir_dst);
+		au_pin_hdir_lock(&a->mvd_pin_src);
+		au_unpin(&a->mvd_pin_src);
+		au_pin_hdir_lock(&a->mvd_pin_dst);
+	}
+	au_unpin(&a->mvd_pin_dst);
+}
+
+/* copy-down the file */
+static int au_do_cpdown(const unsigned char dmsg, struct au_mvd_args *a)
+{
+	int err;
+	struct au_cp_generic cpg = {
+		.dentry	= a->dentry,
+		.bdst	= a->mvd_bdst,
+		.bsrc	= a->mvd_bsrc,
+		.len	= -1,
+		.pin	= &a->mvd_pin_dst,
+		.flags	= AuCpup_DTIME | AuCpup_HOPEN
+	};
+
+	AuDbg("b%d, b%d\n", cpg.bsrc, cpg.bdst);
+	if (a->mvdown.flags & AUFS_MVDOWN_OWLOWER)
+		au_fset_cpup(cpg.flags, OVERWRITE);
+	if (a->mvdown.flags & AUFS_MVDOWN_ROLOWER)
+		au_fset_cpup(cpg.flags, RWDST);
+	err = au_sio_cpdown_simple(&cpg);
+	if (unlikely(err))
+		AU_MVD_PR(dmsg, "cpdown failed\n");
+
+	AuTraceErr(err);
+	return err;
+}
+
+/*
+ * unlink the whiteout on bdst if exist which may be created by UDBA while we
+ * were sleeping
+ */
+static int au_do_unlink_wh(const unsigned char dmsg, struct au_mvd_args *a)
+{
+	int err;
+	struct path h_path;
+	struct au_branch *br;
+	struct inode *delegated;
+
+	br = au_sbr(a->sb, a->mvd_bdst);
+	h_path.dentry = au_wh_lkup(a->mvd_h_dst_parent, &a->dentry->d_name, br);
+	err = PTR_ERR(h_path.dentry);
+	if (IS_ERR(h_path.dentry)) {
+		AU_MVD_PR(dmsg, "wh_lkup failed\n");
+		goto out;
+	}
+
+	err = 0;
+	if (d_is_positive(h_path.dentry)) {
+		h_path.mnt = au_br_mnt(br);
+		delegated = NULL;
+		err = vfsub_unlink(d_inode(a->mvd_h_dst_parent), &h_path,
+				   &delegated, /*force*/0);
+		if (unlikely(err == -EWOULDBLOCK)) {
+			pr_warn("cannot retry for NFSv4 delegation"
+				" for an internal unlink\n");
+			iput(delegated);
+		}
+		if (unlikely(err))
+			AU_MVD_PR(dmsg, "wh_unlink failed\n");
+	}
+	dput(h_path.dentry);
+
+out:
+	AuTraceErr(err);
+	return err;
+}
+
+/*
+ * unlink the topmost h_dentry
+ */
+static int au_do_unlink(const unsigned char dmsg, struct au_mvd_args *a)
+{
+	int err;
+	struct path h_path;
+	struct inode *delegated;
+
+	h_path.mnt = au_sbr_mnt(a->sb, a->mvd_bsrc);
+	h_path.dentry = au_h_dptr(a->dentry, a->mvd_bsrc);
+	delegated = NULL;
+	err = vfsub_unlink(a->mvd_h_src_dir, &h_path, &delegated, /*force*/0);
+	if (unlikely(err == -EWOULDBLOCK)) {
+		pr_warn("cannot retry for NFSv4 delegation"
+			" for an internal unlink\n");
+		iput(delegated);
+	}
+	if (unlikely(err))
+		AU_MVD_PR(dmsg, "unlink failed\n");
+
+	AuTraceErr(err);
+	return err;
+}
+
+/* Since mvdown succeeded, we ignore an error of this function */
+static void au_do_stfs(const unsigned char dmsg, struct au_mvd_args *a)
+{
+	int err;
+	struct au_branch *br;
+
+	a->mvdown.flags |= AUFS_MVDOWN_STFS_FAILED;
+	br = au_sbr(a->sb, a->mvd_bsrc);
+	err = au_br_stfs(br, &a->mvdown.stbr[AUFS_MVDOWN_UPPER].stfs);
+	if (!err) {
+		br = au_sbr(a->sb, a->mvd_bdst);
+		a->mvdown.stbr[AUFS_MVDOWN_LOWER].brid = br->br_id;
+		err = au_br_stfs(br, &a->mvdown.stbr[AUFS_MVDOWN_LOWER].stfs);
+	}
+	if (!err)
+		a->mvdown.flags &= ~AUFS_MVDOWN_STFS_FAILED;
+	else
+		AU_MVD_PR(dmsg, "statfs failed (%d), ignored\n", err);
+}
+
+/*
+ * copy-down the file and unlink the bsrc file.
+ * - unlink the bdst whout if exist
+ * - copy-down the file (with whtmp name and rename)
+ * - unlink the bsrc file
+ */
+static int au_do_mvdown(const unsigned char dmsg, struct au_mvd_args *a)
+{
+	int err;
+
+	err = au_do_mkdir(dmsg, a);
+	if (!err)
+		err = au_do_lock(dmsg, a);
+	if (unlikely(err))
+		goto out;
+
+	/*
+	 * do not revert the activities we made on bdst since they should be
+	 * harmless in aufs.
+	 */
+
+	err = au_do_cpdown(dmsg, a);
+	if (!err)
+		err = au_do_unlink_wh(dmsg, a);
+	if (!err && !(a->mvdown.flags & AUFS_MVDOWN_KUPPER))
+		err = au_do_unlink(dmsg, a);
+	if (unlikely(err))
+		goto out_unlock;
+
+	AuDbg("%pd2, 0x%x, %d --> %d\n",
+	      a->dentry, a->mvdown.flags, a->mvd_bsrc, a->mvd_bdst);
+	if (find_lower_writable(a) < 0)
+		a->mvdown.flags |= AUFS_MVDOWN_BOTTOM;
+
+	if (a->mvdown.flags & AUFS_MVDOWN_STFS)
+		au_do_stfs(dmsg, a);
+
+	/* maintain internal array */
+	if (!(a->mvdown.flags & AUFS_MVDOWN_KUPPER)) {
+		au_set_h_dptr(a->dentry, a->mvd_bsrc, NULL);
+		au_set_dbstart(a->dentry, a->mvd_bdst);
+		au_set_h_iptr(a->inode, a->mvd_bsrc, NULL, /*flags*/0);
+		au_set_ibstart(a->inode, a->mvd_bdst);
+	} else {
+		/* hide the lower */
+		au_set_h_dptr(a->dentry, a->mvd_bdst, NULL);
+		au_set_dbend(a->dentry, a->mvd_bsrc);
+		au_set_h_iptr(a->inode, a->mvd_bdst, NULL, /*flags*/0);
+		au_set_ibend(a->inode, a->mvd_bsrc);
+	}
+	if (au_dbend(a->dentry) < a->mvd_bdst)
+		au_set_dbend(a->dentry, a->mvd_bdst);
+	if (au_ibend(a->inode) < a->mvd_bdst)
+		au_set_ibend(a->inode, a->mvd_bdst);
+
+out_unlock:
+	au_do_unlock(dmsg, a);
+out:
+	AuTraceErr(err);
+	return err;
+}
+
+/* ---------------------------------------------------------------------- */
+
+/* make sure the file is idle */
+static int au_mvd_args_busy(const unsigned char dmsg, struct au_mvd_args *a)
+{
+	int err, plinked;
+
+	err = 0;
+	plinked = !!au_opt_test(au_mntflags(a->sb), PLINK);
+	if (au_dbstart(a->dentry) == a->mvd_bsrc
+	    && au_dcount(a->dentry) == 1
+	    && atomic_read(&a->inode->i_count) == 1
+	    /* && a->mvd_h_src_inode->i_nlink == 1 */
+	    && (!plinked || !au_plink_test(a->inode))
+	    && a->inode->i_nlink == 1)
+		goto out;
+
+	err = -EBUSY;
+	AU_MVD_PR(dmsg,
+		  "b%d, d{b%d, c%d?}, i{c%d?, l%u}, hi{l%u}, p{%d, %d}\n",
+		  a->mvd_bsrc, au_dbstart(a->dentry), au_dcount(a->dentry),
+		  atomic_read(&a->inode->i_count), a->inode->i_nlink,
+		  a->mvd_h_src_inode->i_nlink,
+		  plinked, plinked ? au_plink_test(a->inode) : 0);
+
+out:
+	AuTraceErr(err);
+	return err;
+}
+
+/* make sure the parent dir is fine */
+static int au_mvd_args_parent(const unsigned char dmsg,
+			      struct au_mvd_args *a)
+{
+	int err;
+	aufs_bindex_t bindex;
+
+	err = 0;
+	if (unlikely(au_alive_dir(a->parent))) {
+		err = -ENOENT;
+		AU_MVD_PR(dmsg, "parent dir is dead\n");
+		goto out;
+	}
+
+	a->bopq = au_dbdiropq(a->parent);
+	bindex = au_wbr_nonopq(a->dentry, a->mvd_bdst);
+	AuDbg("b%d\n", bindex);
+	if (unlikely((bindex >= 0 && bindex < a->mvd_bdst)
+		     || (a->bopq != -1 && a->bopq < a->mvd_bdst))) {
+		err = -EINVAL;
+		a->mvd_errno = EAU_MVDOWN_OPAQUE;
+		AU_MVD_PR(dmsg, "ancestor is opaque b%d, b%d\n",
+			  a->bopq, a->mvd_bdst);
+	}
+
+out:
+	AuTraceErr(err);
+	return err;
+}
+
+static int au_mvd_args_intermediate(const unsigned char dmsg,
+				    struct au_mvd_args *a)
+{
+	int err;
+	struct au_dinfo *dinfo, *tmp;
+
+	/* lookup the next lower positive entry */
+	err = -ENOMEM;
+	tmp = au_di_alloc(a->sb, AuLsc_DI_TMP);
+	if (unlikely(!tmp))
+		goto out;
+
+	a->bfound = -1;
+	a->bwh = -1;
+	dinfo = au_di(a->dentry);
+	au_di_cp(tmp, dinfo);
+	au_di_swap(tmp, dinfo);
+
+	/* returns the number of positive dentries */
+	err = au_lkup_dentry(a->dentry, a->mvd_bsrc + 1, /*type*/0);
+	if (!err)
+		a->bwh = au_dbwh(a->dentry);
+	else if (err > 0)
+		a->bfound = au_dbstart(a->dentry);
+
+	au_di_swap(tmp, dinfo);
+	au_rw_write_unlock(&tmp->di_rwsem);
+	au_di_free(tmp);
+	if (unlikely(err < 0))
+		AU_MVD_PR(dmsg, "failed look-up lower\n");
+
+	/*
+	 * here, we have these cases.
+	 * bfound == -1
+	 *	no positive dentry under bsrc. there are more sub-cases.
+	 *	bwh < 0
+	 *		there no whiteout, we can safely move-down.
+	 *	bwh <= bsrc
+	 *		impossible
+	 *	bsrc < bwh && bwh < bdst
+	 *		there is a whiteout on RO branch. cannot proceed.
+	 *	bwh == bdst
+	 *		there is a whiteout on the RW target branch. it should
+	 *		be removed.
+	 *	bdst < bwh
+	 *		there is a whiteout somewhere unrelated branch.
+	 * -1 < bfound && bfound <= bsrc
+	 *	impossible.
+	 * bfound < bdst
+	 *	found, but it is on RO branch between bsrc and bdst. cannot
+	 *	proceed.
+	 * bfound == bdst
+	 *	found, replace it if AUFS_MVDOWN_FORCE is set. otherwise return
+	 *	error.
+	 * bdst < bfound
+	 *	found, after we create the file on bdst, it will be hidden.
+	 */
+
+	AuDebugOn(a->bfound == -1
+		  && a->bwh != -1
+		  && a->bwh <= a->mvd_bsrc);
+	AuDebugOn(-1 < a->bfound
+		  && a->bfound <= a->mvd_bsrc);
+
+	err = -EINVAL;
+	if (a->bfound == -1
+	    && a->mvd_bsrc < a->bwh
+	    && a->bwh != -1
+	    && a->bwh < a->mvd_bdst) {
+		a->mvd_errno = EAU_MVDOWN_WHITEOUT;
+		AU_MVD_PR(dmsg, "bsrc %d, bdst %d, bfound %d, bwh %d\n",
+			  a->mvd_bsrc, a->mvd_bdst, a->bfound, a->bwh);
+		goto out;
+	} else if (a->bfound != -1 && a->bfound < a->mvd_bdst) {
+		a->mvd_errno = EAU_MVDOWN_UPPER;
+		AU_MVD_PR(dmsg, "bdst %d, bfound %d\n",
+			  a->mvd_bdst, a->bfound);
+		goto out;
+	}
+
+	err = 0; /* success */
+
+out:
+	AuTraceErr(err);
+	return err;
+}
+
+static int au_mvd_args_exist(const unsigned char dmsg, struct au_mvd_args *a)
+{
+	int err;
+
+	err = 0;
+	if (!(a->mvdown.flags & AUFS_MVDOWN_OWLOWER)
+	    && a->bfound == a->mvd_bdst)
+		err = -EEXIST;
+	AuTraceErr(err);
+	return err;
+}
+
+static int au_mvd_args(const unsigned char dmsg, struct au_mvd_args *a)
+{
+	int err;
+	struct au_branch *br;
+
+	err = -EISDIR;
+	if (unlikely(S_ISDIR(a->inode->i_mode)))
+		goto out;
+
+	err = -EINVAL;
+	if (!(a->mvdown.flags & AUFS_MVDOWN_BRID_UPPER))
+		a->mvd_bsrc = au_ibstart(a->inode);
+	else {
+		a->mvd_bsrc = au_br_index(a->sb, a->mvd_src_brid);
+		if (unlikely(a->mvd_bsrc < 0
+			     || (a->mvd_bsrc < au_dbstart(a->dentry)
+				 || au_dbend(a->dentry) < a->mvd_bsrc
+				 || !au_h_dptr(a->dentry, a->mvd_bsrc))
+			     || (a->mvd_bsrc < au_ibstart(a->inode)
+				 || au_ibend(a->inode) < a->mvd_bsrc
+				 || !au_h_iptr(a->inode, a->mvd_bsrc)))) {
+			a->mvd_errno = EAU_MVDOWN_NOUPPER;
+			AU_MVD_PR(dmsg, "no upper\n");
+			goto out;
+		}
+	}
+	if (unlikely(a->mvd_bsrc == au_sbend(a->sb))) {
+		a->mvd_errno = EAU_MVDOWN_BOTTOM;
+		AU_MVD_PR(dmsg, "on the bottom\n");
+		goto out;
+	}
+	a->mvd_h_src_inode = au_h_iptr(a->inode, a->mvd_bsrc);
+	br = au_sbr(a->sb, a->mvd_bsrc);
+	err = au_br_rdonly(br);
+	if (!(a->mvdown.flags & AUFS_MVDOWN_ROUPPER)) {
+		if (unlikely(err))
+			goto out;
+	} else if (!(vfsub_native_ro(a->mvd_h_src_inode)
+		     || IS_APPEND(a->mvd_h_src_inode))) {
+		if (err)
+			a->mvdown.flags |= AUFS_MVDOWN_ROUPPER_R;
+		/* go on */
+	} else
+		goto out;
+
+	err = -EINVAL;
+	if (!(a->mvdown.flags & AUFS_MVDOWN_BRID_LOWER)) {
+		a->mvd_bdst = find_lower_writable(a);
+		if (unlikely(a->mvd_bdst < 0)) {
+			a->mvd_errno = EAU_MVDOWN_BOTTOM;
+			AU_MVD_PR(dmsg, "no writable lower branch\n");
+			goto out;
+		}
+	} else {
+		a->mvd_bdst = au_br_index(a->sb, a->mvd_dst_brid);
+		if (unlikely(a->mvd_bdst < 0
+			     || au_sbend(a->sb) < a->mvd_bdst)) {
+			a->mvd_errno = EAU_MVDOWN_NOLOWERBR;
+			AU_MVD_PR(dmsg, "no lower brid\n");
+			goto out;
+		}
+	}
+
+	err = au_mvd_args_busy(dmsg, a);
+	if (!err)
+		err = au_mvd_args_parent(dmsg, a);
+	if (!err)
+		err = au_mvd_args_intermediate(dmsg, a);
+	if (!err)
+		err = au_mvd_args_exist(dmsg, a);
+	if (!err)
+		AuDbg("b%d, b%d\n", a->mvd_bsrc, a->mvd_bdst);
+
+out:
+	AuTraceErr(err);
+	return err;
+}
+
+int au_mvdown(struct dentry *dentry, struct aufs_mvdown __user *uarg)
+{
+	int err, e;
+	unsigned char dmsg;
+	struct au_mvd_args *args;
+	struct inode *inode;
+
+	inode = d_inode(dentry);
+	err = -EPERM;
+	if (unlikely(!capable(CAP_SYS_ADMIN)))
+		goto out;
+
+	err = -ENOMEM;
+	args = kmalloc(sizeof(*args), GFP_NOFS);
+	if (unlikely(!args))
+		goto out;
+
+	err = copy_from_user(&args->mvdown, uarg, sizeof(args->mvdown));
+	if (!err)
+		err = !access_ok(VERIFY_WRITE, uarg, sizeof(*uarg));
+	if (unlikely(err)) {
+		err = -EFAULT;
+		AuTraceErr(err);
+		goto out_free;
+	}
+	AuDbg("flags 0x%x\n", args->mvdown.flags);
+	args->mvdown.flags &= ~(AUFS_MVDOWN_ROLOWER_R | AUFS_MVDOWN_ROUPPER_R);
+	args->mvdown.au_errno = 0;
+	args->dentry = dentry;
+	args->inode = inode;
+	args->sb = dentry->d_sb;
+
+	err = -ENOENT;
+	dmsg = !!(args->mvdown.flags & AUFS_MVDOWN_DMSG);
+	args->parent = dget_parent(dentry);
+	args->dir = d_inode(args->parent);
+	mutex_lock_nested(&args->dir->i_mutex, I_MUTEX_PARENT);
+	dput(args->parent);
+	if (unlikely(args->parent != dentry->d_parent)) {
+		AU_MVD_PR(dmsg, "parent dir is moved\n");
+		goto out_dir;
+	}
+
+	mutex_lock_nested(&inode->i_mutex, I_MUTEX_CHILD);
+	err = aufs_read_lock(dentry, AuLock_DW | AuLock_FLUSH | AuLock_NOPLMW);
+	if (unlikely(err))
+		goto out_inode;
+
+	di_write_lock_parent(args->parent);
+	err = au_mvd_args(dmsg, args);
+	if (unlikely(err))
+		goto out_parent;
+
+	err = au_do_mvdown(dmsg, args);
+	if (unlikely(err))
+		goto out_parent;
+
+	au_cpup_attr_timesizes(args->dir);
+	au_cpup_attr_timesizes(inode);
+	if (!(args->mvdown.flags & AUFS_MVDOWN_KUPPER))
+		au_cpup_igen(inode, au_h_iptr(inode, args->mvd_bdst));
+	/* au_digen_dec(dentry); */
+
+out_parent:
+	di_write_unlock(args->parent);
+	aufs_read_unlock(dentry, AuLock_DW);
+out_inode:
+	mutex_unlock(&inode->i_mutex);
+out_dir:
+	mutex_unlock(&args->dir->i_mutex);
+out_free:
+	e = copy_to_user(uarg, &args->mvdown, sizeof(args->mvdown));
+	if (unlikely(e))
+		err = -EFAULT;
+	kfree(args);
+out:
+	AuTraceErr(err);
+	return err;
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/fs/aufs/opts.c
@@ -0,0 +1,1859 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+ *
+ * This program, aufs is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * mount options/flags
+ */
+
+#include <linux/namei.h>
+#include <linux/types.h> /* a distribution requires */
+#include <linux/parser.h>
+#include "aufs.h"
+
+/* ---------------------------------------------------------------------- */
+
+enum {
+	Opt_br,
+	Opt_add, Opt_del, Opt_mod, Opt_append, Opt_prepend,
+	Opt_idel, Opt_imod,
+	Opt_dirwh, Opt_rdcache, Opt_rdblk, Opt_rdhash,
+	Opt_rdblk_def, Opt_rdhash_def,
+	Opt_xino, Opt_noxino,
+	Opt_trunc_xino, Opt_trunc_xino_v, Opt_notrunc_xino,
+	Opt_trunc_xino_path, Opt_itrunc_xino,
+	Opt_trunc_xib, Opt_notrunc_xib,
+	Opt_shwh, Opt_noshwh,
+	Opt_plink, Opt_noplink, Opt_list_plink,
+	Opt_udba,
+	Opt_dio, Opt_nodio,
+	Opt_diropq_a, Opt_diropq_w,
+	Opt_warn_perm, Opt_nowarn_perm,
+	Opt_wbr_copyup, Opt_wbr_create,
+	Opt_fhsm_sec,
+	Opt_verbose, Opt_noverbose,
+	Opt_sum, Opt_nosum, Opt_wsum,
+	Opt_dirperm1, Opt_nodirperm1,
+	Opt_acl, Opt_noacl,
+	Opt_tail, Opt_ignore, Opt_ignore_silent, Opt_err
+};
+
+static match_table_t options = {
+	{Opt_br, "br=%s"},
+	{Opt_br, "br:%s"},
+
+	{Opt_add, "add=%d:%s"},
+	{Opt_add, "add:%d:%s"},
+	{Opt_add, "ins=%d:%s"},
+	{Opt_add, "ins:%d:%s"},
+	{Opt_append, "append=%s"},
+	{Opt_append, "append:%s"},
+	{Opt_prepend, "prepend=%s"},
+	{Opt_prepend, "prepend:%s"},
+
+	{Opt_del, "del=%s"},
+	{Opt_del, "del:%s"},
+	/* {Opt_idel, "idel:%d"}, */
+	{Opt_mod, "mod=%s"},
+	{Opt_mod, "mod:%s"},
+	/* {Opt_imod, "imod:%d:%s"}, */
+
+	{Opt_dirwh, "dirwh=%d"},
+
+	{Opt_xino, "xino=%s"},
+	{Opt_noxino, "noxino"},
+	{Opt_trunc_xino, "trunc_xino"},
+	{Opt_trunc_xino_v, "trunc_xino_v=%d:%d"},
+	{Opt_notrunc_xino, "notrunc_xino"},
+	{Opt_trunc_xino_path, "trunc_xino=%s"},
+	{Opt_itrunc_xino, "itrunc_xino=%d"},
+	/* {Opt_zxino, "zxino=%s"}, */
+	{Opt_trunc_xib, "trunc_xib"},
+	{Opt_notrunc_xib, "notrunc_xib"},
+
+#ifdef CONFIG_PROC_FS
+	{Opt_plink, "plink"},
+#else
+	{Opt_ignore_silent, "plink"},
+#endif
+
+	{Opt_noplink, "noplink"},
+
+#ifdef CONFIG_AUFS_DEBUG
+	{Opt_list_plink, "list_plink"},
+#endif
+
+	{Opt_udba, "udba=%s"},
+
+	{Opt_dio, "dio"},
+	{Opt_nodio, "nodio"},
+
+#ifdef CONFIG_AUFS_FHSM
+	{Opt_fhsm_sec, "fhsm_sec=%d"},
+#else
+	{Opt_ignore_silent, "fhsm_sec=%d"},
+#endif
+
+	{Opt_diropq_a, "diropq=always"},
+	{Opt_diropq_a, "diropq=a"},
+	{Opt_diropq_w, "diropq=whiteouted"},
+	{Opt_diropq_w, "diropq=w"},
+
+	{Opt_warn_perm, "warn_perm"},
+	{Opt_nowarn_perm, "nowarn_perm"},
+
+	/* keep them temporary */
+	{Opt_ignore_silent, "nodlgt"},
+	{Opt_ignore_silent, "clean_plink"},
+
+#ifdef CONFIG_AUFS_SHWH
+	{Opt_shwh, "shwh"},
+#endif
+	{Opt_noshwh, "noshwh"},
+
+	{Opt_dirperm1, "dirperm1"},
+	{Opt_nodirperm1, "nodirperm1"},
+
+	{Opt_verbose, "verbose"},
+	{Opt_verbose, "v"},
+	{Opt_noverbose, "noverbose"},
+	{Opt_noverbose, "quiet"},
+	{Opt_noverbose, "q"},
+	{Opt_noverbose, "silent"},
+
+	{Opt_sum, "sum"},
+	{Opt_nosum, "nosum"},
+	{Opt_wsum, "wsum"},
+
+	{Opt_rdcache, "rdcache=%d"},
+	{Opt_rdblk, "rdblk=%d"},
+	{Opt_rdblk_def, "rdblk=def"},
+	{Opt_rdhash, "rdhash=%d"},
+	{Opt_rdhash_def, "rdhash=def"},
+
+	{Opt_wbr_create, "create=%s"},
+	{Opt_wbr_create, "create_policy=%s"},
+	{Opt_wbr_copyup, "cpup=%s"},
+	{Opt_wbr_copyup, "copyup=%s"},
+	{Opt_wbr_copyup, "copyup_policy=%s"},
+
+	/* generic VFS flag */
+#ifdef CONFIG_FS_POSIX_ACL
+	{Opt_acl, "acl"},
+	{Opt_noacl, "noacl"},
+#else
+	{Opt_ignore_silent, "acl"},
+	{Opt_ignore_silent, "noacl"},
+#endif
+
+	/* internal use for the scripts */
+	{Opt_ignore_silent, "si=%s"},
+
+	{Opt_br, "dirs=%s"},
+	{Opt_ignore, "debug=%d"},
+	{Opt_ignore, "delete=whiteout"},
+	{Opt_ignore, "delete=all"},
+	{Opt_ignore, "imap=%s"},
+
+	/* temporary workaround, due to old mount(8)? */
+	{Opt_ignore_silent, "relatime"},
+
+	{Opt_err, NULL}
+};
+
+/* ---------------------------------------------------------------------- */
+
+static const char *au_parser_pattern(int val, match_table_t tbl)
+{
+	struct match_token *p;
+
+	p = tbl;
+	while (p->pattern) {
+		if (p->token == val)
+			return p->pattern;
+		p++;
+	}
+	BUG();
+	return "??";
+}
+
+static const char *au_optstr(int *val, match_table_t tbl)
+{
+	struct match_token *p;
+	int v;
+
+	v = *val;
+	if (!v)
+		goto out;
+	p = tbl;
+	while (p->pattern) {
+		if (p->token
+		    && (v & p->token) == p->token) {
+			*val &= ~p->token;
+			return p->pattern;
+		}
+		p++;
+	}
+
+out:
+	return NULL;
+}
+
+/* ---------------------------------------------------------------------- */
+
+static match_table_t brperm = {
+	{AuBrPerm_RO, AUFS_BRPERM_RO},
+	{AuBrPerm_RR, AUFS_BRPERM_RR},
+	{AuBrPerm_RW, AUFS_BRPERM_RW},
+	{0, NULL}
+};
+
+static match_table_t brattr = {
+	/* general */
+	{AuBrAttr_COO_REG, AUFS_BRATTR_COO_REG},
+	{AuBrAttr_COO_ALL, AUFS_BRATTR_COO_ALL},
+	/* 'unpin' attrib is meaningless since linux-3.18-rc1 */
+	{AuBrAttr_UNPIN, AUFS_BRATTR_UNPIN},
+#ifdef CONFIG_AUFS_FHSM
+	{AuBrAttr_FHSM, AUFS_BRATTR_FHSM},
+#endif
+#ifdef CONFIG_AUFS_XATTR
+	{AuBrAttr_ICEX, AUFS_BRATTR_ICEX},
+	{AuBrAttr_ICEX_SEC, AUFS_BRATTR_ICEX_SEC},
+	{AuBrAttr_ICEX_SYS, AUFS_BRATTR_ICEX_SYS},
+	{AuBrAttr_ICEX_TR, AUFS_BRATTR_ICEX_TR},
+	{AuBrAttr_ICEX_USR, AUFS_BRATTR_ICEX_USR},
+	{AuBrAttr_ICEX_OTH, AUFS_BRATTR_ICEX_OTH},
+#endif
+
+	/* ro/rr branch */
+	{AuBrRAttr_WH, AUFS_BRRATTR_WH},
+
+	/* rw branch */
+	{AuBrWAttr_MOO, AUFS_BRWATTR_MOO},
+	{AuBrWAttr_NoLinkWH, AUFS_BRWATTR_NLWH},
+
+	{0, NULL}
+};
+
+static int br_attr_val(char *str, match_table_t table, substring_t args[])
+{
+	int attr, v;
+	char *p;
+
+	attr = 0;
+	do {
+		p = strchr(str, '+');
+		if (p)
+			*p = 0;
+		v = match_token(str, table, args);
+		if (v) {
+			if (v & AuBrAttr_CMOO_Mask)
+				attr &= ~AuBrAttr_CMOO_Mask;
+			attr |= v;
+		} else {
+			if (p)
+				*p = '+';
+			pr_warn("ignored branch attribute %s\n", str);
+			break;
+		}
+		if (p)
+			str = p + 1;
+	} while (p);
+
+	return attr;
+}
+
+static int au_do_optstr_br_attr(au_br_perm_str_t *str, int perm)
+{
+	int sz;
+	const char *p;
+	char *q;
+
+	q = str->a;
+	*q = 0;
+	p = au_optstr(&perm, brattr);
+	if (p) {
+		sz = strlen(p);
+		memcpy(q, p, sz + 1);
+		q += sz;
+	} else
+		goto out;
+
+	do {
+		p = au_optstr(&perm, brattr);
+		if (p) {
+			*q++ = '+';
+			sz = strlen(p);
+			memcpy(q, p, sz + 1);
+			q += sz;
+		}
+	} while (p);
+
+out:
+	return q - str->a;
+}
+
+static int noinline_for_stack br_perm_val(char *perm)
+{
+	int val, bad, sz;
+	char *p;
+	substring_t args[MAX_OPT_ARGS];
+	au_br_perm_str_t attr;
+
+	p = strchr(perm, '+');
+	if (p)
+		*p = 0;
+	val = match_token(perm, brperm, args);
+	if (!val) {
+		if (p)
+			*p = '+';
+		pr_warn("ignored branch permission %s\n", perm);
+		val = AuBrPerm_RO;
+		goto out;
+	}
+	if (!p)
+		goto out;
+
+	val |= br_attr_val(p + 1, brattr, args);
+
+	bad = 0;
+	switch (val & AuBrPerm_Mask) {
+	case AuBrPerm_RO:
+	case AuBrPerm_RR:
+		bad = val & AuBrWAttr_Mask;
+		val &= ~AuBrWAttr_Mask;
+		break;
+	case AuBrPerm_RW:
+		bad = val & AuBrRAttr_Mask;
+		val &= ~AuBrRAttr_Mask;
+		break;
+	}
+
+	/*
+	 * 'unpin' attrib becomes meaningless since linux-3.18-rc1, but aufs
+	 * does not treat it as an error, just warning.
+	 * this is a tiny guard for the user operation.
+	 */
+	if (val & AuBrAttr_UNPIN) {
+		bad |= AuBrAttr_UNPIN;
+		val &= ~AuBrAttr_UNPIN;
+	}
+
+	if (unlikely(bad)) {
+		sz = au_do_optstr_br_attr(&attr, bad);
+		AuDebugOn(!sz);
+		pr_warn("ignored branch attribute %s\n", attr.a);
+	}
+
+out:
+	return val;
+}
+
+void au_optstr_br_perm(au_br_perm_str_t *str, int perm)
+{
+	au_br_perm_str_t attr;
+	const char *p;
+	char *q;
+	int sz;
+
+	q = str->a;
+	p = au_optstr(&perm, brperm);
+	AuDebugOn(!p || !*p);
+	sz = strlen(p);
+	memcpy(q, p, sz + 1);
+	q += sz;
+
+	sz = au_do_optstr_br_attr(&attr, perm);
+	if (sz) {
+		*q++ = '+';
+		memcpy(q, attr.a, sz + 1);
+	}
+
+	AuDebugOn(strlen(str->a) >= sizeof(str->a));
+}
+
+/* ---------------------------------------------------------------------- */
+
+static match_table_t udbalevel = {
+	{AuOpt_UDBA_REVAL, "reval"},
+	{AuOpt_UDBA_NONE, "none"},
+#ifdef CONFIG_AUFS_HNOTIFY
+	{AuOpt_UDBA_HNOTIFY, "notify"}, /* abstraction */
+#ifdef CONFIG_AUFS_HFSNOTIFY
+	{AuOpt_UDBA_HNOTIFY, "fsnotify"},
+#endif
+#endif
+	{-1, NULL}
+};
+
+static int noinline_for_stack udba_val(char *str)
+{
+	substring_t args[MAX_OPT_ARGS];
+
+	return match_token(str, udbalevel, args);
+}
+
+const char *au_optstr_udba(int udba)
+{
+	return au_parser_pattern(udba, udbalevel);
+}
+
+/* ---------------------------------------------------------------------- */
+
+static match_table_t au_wbr_create_policy = {
+	{AuWbrCreate_TDP, "tdp"},
+	{AuWbrCreate_TDP, "top-down-parent"},
+	{AuWbrCreate_RR, "rr"},
+	{AuWbrCreate_RR, "round-robin"},
+	{AuWbrCreate_MFS, "mfs"},
+	{AuWbrCreate_MFS, "most-free-space"},
+	{AuWbrCreate_MFSV, "mfs:%d"},
+	{AuWbrCreate_MFSV, "most-free-space:%d"},
+
+	{AuWbrCreate_MFSRR, "mfsrr:%d"},
+	{AuWbrCreate_MFSRRV, "mfsrr:%d:%d"},
+	{AuWbrCreate_PMFS, "pmfs"},
+	{AuWbrCreate_PMFSV, "pmfs:%d"},
+	{AuWbrCreate_PMFSRR, "pmfsrr:%d"},
+	{AuWbrCreate_PMFSRRV, "pmfsrr:%d:%d"},
+
+	{-1, NULL}
+};
+
+/*
+ * cf. linux/lib/parser.c and cmdline.c
+ * gave up calling memparse() since it uses simple_strtoull() instead of
+ * kstrto...().
+ */
+static int noinline_for_stack
+au_match_ull(substring_t *s, unsigned long long *result)
+{
+	int err;
+	unsigned int len;
+	char a[32];
+
+	err = -ERANGE;
+	len = s->to - s->from;
+	if (len + 1 <= sizeof(a)) {
+		memcpy(a, s->from, len);
+		a[len] = '\0';
+		err = kstrtoull(a, 0, result);
+	}
+	return err;
+}
+
+static int au_wbr_mfs_wmark(substring_t *arg, char *str,
+			    struct au_opt_wbr_create *create)
+{
+	int err;
+	unsigned long long ull;
+
+	err = 0;
+	if (!au_match_ull(arg, &ull))
+		create->mfsrr_watermark = ull;
+	else {
+		pr_err("bad integer in %s\n", str);
+		err = -EINVAL;
+	}
+
+	return err;
+}
+
+static int au_wbr_mfs_sec(substring_t *arg, char *str,
+			  struct au_opt_wbr_create *create)
+{
+	int n, err;
+
+	err = 0;
+	if (!match_int(arg, &n) && 0 <= n && n <= AUFS_MFS_MAX_SEC)
+		create->mfs_second = n;
+	else {
+		pr_err("bad integer in %s\n", str);
+		err = -EINVAL;
+	}
+
+	return err;
+}
+
+static int noinline_for_stack
+au_wbr_create_val(char *str, struct au_opt_wbr_create *create)
+{
+	int err, e;
+	substring_t args[MAX_OPT_ARGS];
+
+	err = match_token(str, au_wbr_create_policy, args);
+	create->wbr_create = err;
+	switch (err) {
+	case AuWbrCreate_MFSRRV:
+	case AuWbrCreate_PMFSRRV:
+		e = au_wbr_mfs_wmark(&args[0], str, create);
+		if (!e)
+			e = au_wbr_mfs_sec(&args[1], str, create);
+		if (unlikely(e))
+			err = e;
+		break;
+	case AuWbrCreate_MFSRR:
+	case AuWbrCreate_PMFSRR:
+		e = au_wbr_mfs_wmark(&args[0], str, create);
+		if (unlikely(e)) {
+			err = e;
+			break;
+		}
+		/*FALLTHROUGH*/
+	case AuWbrCreate_MFS:
+	case AuWbrCreate_PMFS:
+		create->mfs_second = AUFS_MFS_DEF_SEC;
+		break;
+	case AuWbrCreate_MFSV:
+	case AuWbrCreate_PMFSV:
+		e = au_wbr_mfs_sec(&args[0], str, create);
+		if (unlikely(e))
+			err = e;
+		break;
+	}
+
+	return err;
+}
+
+const char *au_optstr_wbr_create(int wbr_create)
+{
+	return au_parser_pattern(wbr_create, au_wbr_create_policy);
+}
+
+static match_table_t au_wbr_copyup_policy = {
+	{AuWbrCopyup_TDP, "tdp"},
+	{AuWbrCopyup_TDP, "top-down-parent"},
+	{AuWbrCopyup_BUP, "bup"},
+	{AuWbrCopyup_BUP, "bottom-up-parent"},
+	{AuWbrCopyup_BU, "bu"},
+	{AuWbrCopyup_BU, "bottom-up"},
+	{-1, NULL}
+};
+
+static int noinline_for_stack au_wbr_copyup_val(char *str)
+{
+	substring_t args[MAX_OPT_ARGS];
+
+	return match_token(str, au_wbr_copyup_policy, args);
+}
+
+const char *au_optstr_wbr_copyup(int wbr_copyup)
+{
+	return au_parser_pattern(wbr_copyup, au_wbr_copyup_policy);
+}
+
+/* ---------------------------------------------------------------------- */
+
+static const int lkup_dirflags = LOOKUP_FOLLOW | LOOKUP_DIRECTORY;
+
+static void dump_opts(struct au_opts *opts)
+{
+#ifdef CONFIG_AUFS_DEBUG
+	/* reduce stack space */
+	union {
+		struct au_opt_add *add;
+		struct au_opt_del *del;
+		struct au_opt_mod *mod;
+		struct au_opt_xino *xino;
+		struct au_opt_xino_itrunc *xino_itrunc;
+		struct au_opt_wbr_create *create;
+	} u;
+	struct au_opt *opt;
+
+	opt = opts->opt;
+	while (opt->type != Opt_tail) {
+		switch (opt->type) {
+		case Opt_add:
+			u.add = &opt->add;
+			AuDbg("add {b%d, %s, 0x%x, %p}\n",
+				  u.add->bindex, u.add->pathname, u.add->perm,
+				  u.add->path.dentry);
+			break;
+		case Opt_del:
+		case Opt_idel:
+			u.del = &opt->del;
+			AuDbg("del {%s, %p}\n",
+			      u.del->pathname, u.del->h_path.dentry);
+			break;
+		case Opt_mod:
+		case Opt_imod:
+			u.mod = &opt->mod;
+			AuDbg("mod {%s, 0x%x, %p}\n",
+				  u.mod->path, u.mod->perm, u.mod->h_root);
+			break;
+		case Opt_append:
+			u.add = &opt->add;
+			AuDbg("append {b%d, %s, 0x%x, %p}\n",
+				  u.add->bindex, u.add->pathname, u.add->perm,
+				  u.add->path.dentry);
+			break;
+		case Opt_prepend:
+			u.add = &opt->add;
+			AuDbg("prepend {b%d, %s, 0x%x, %p}\n",
+				  u.add->bindex, u.add->pathname, u.add->perm,
+				  u.add->path.dentry);
+			break;
+		case Opt_dirwh:
+			AuDbg("dirwh %d\n", opt->dirwh);
+			break;
+		case Opt_rdcache:
+			AuDbg("rdcache %d\n", opt->rdcache);
+			break;
+		case Opt_rdblk:
+			AuDbg("rdblk %u\n", opt->rdblk);
+			break;
+		case Opt_rdblk_def:
+			AuDbg("rdblk_def\n");
+			break;
+		case Opt_rdhash:
+			AuDbg("rdhash %u\n", opt->rdhash);
+			break;
+		case Opt_rdhash_def:
+			AuDbg("rdhash_def\n");
+			break;
+		case Opt_xino:
+			u.xino = &opt->xino;
+			AuDbg("xino {%s %pD}\n", u.xino->path, u.xino->file);
+			break;
+		case Opt_trunc_xino:
+			AuLabel(trunc_xino);
+			break;
+		case Opt_notrunc_xino:
+			AuLabel(notrunc_xino);
+			break;
+		case Opt_trunc_xino_path:
+		case Opt_itrunc_xino:
+			u.xino_itrunc = &opt->xino_itrunc;
+			AuDbg("trunc_xino %d\n", u.xino_itrunc->bindex);
+			break;
+		case Opt_noxino:
+			AuLabel(noxino);
+			break;
+		case Opt_trunc_xib:
+			AuLabel(trunc_xib);
+			break;
+		case Opt_notrunc_xib:
+			AuLabel(notrunc_xib);
+			break;
+		case Opt_shwh:
+			AuLabel(shwh);
+			break;
+		case Opt_noshwh:
+			AuLabel(noshwh);
+			break;
+		case Opt_dirperm1:
+			AuLabel(dirperm1);
+			break;
+		case Opt_nodirperm1:
+			AuLabel(nodirperm1);
+			break;
+		case Opt_plink:
+			AuLabel(plink);
+			break;
+		case Opt_noplink:
+			AuLabel(noplink);
+			break;
+		case Opt_list_plink:
+			AuLabel(list_plink);
+			break;
+		case Opt_udba:
+			AuDbg("udba %d, %s\n",
+				  opt->udba, au_optstr_udba(opt->udba));
+			break;
+		case Opt_dio:
+			AuLabel(dio);
+			break;
+		case Opt_nodio:
+			AuLabel(nodio);
+			break;
+		case Opt_diropq_a:
+			AuLabel(diropq_a);
+			break;
+		case Opt_diropq_w:
+			AuLabel(diropq_w);
+			break;
+		case Opt_warn_perm:
+			AuLabel(warn_perm);
+			break;
+		case Opt_nowarn_perm:
+			AuLabel(nowarn_perm);
+			break;
+		case Opt_verbose:
+			AuLabel(verbose);
+			break;
+		case Opt_noverbose:
+			AuLabel(noverbose);
+			break;
+		case Opt_sum:
+			AuLabel(sum);
+			break;
+		case Opt_nosum:
+			AuLabel(nosum);
+			break;
+		case Opt_wsum:
+			AuLabel(wsum);
+			break;
+		case Opt_wbr_create:
+			u.create = &opt->wbr_create;
+			AuDbg("create %d, %s\n", u.create->wbr_create,
+				  au_optstr_wbr_create(u.create->wbr_create));
+			switch (u.create->wbr_create) {
+			case AuWbrCreate_MFSV:
+			case AuWbrCreate_PMFSV:
+				AuDbg("%d sec\n", u.create->mfs_second);
+				break;
+			case AuWbrCreate_MFSRR:
+				AuDbg("%llu watermark\n",
+					  u.create->mfsrr_watermark);
+				break;
+			case AuWbrCreate_MFSRRV:
+			case AuWbrCreate_PMFSRRV:
+				AuDbg("%llu watermark, %d sec\n",
+					  u.create->mfsrr_watermark,
+					  u.create->mfs_second);
+				break;
+			}
+			break;
+		case Opt_wbr_copyup:
+			AuDbg("copyup %d, %s\n", opt->wbr_copyup,
+				  au_optstr_wbr_copyup(opt->wbr_copyup));
+			break;
+		case Opt_fhsm_sec:
+			AuDbg("fhsm_sec %u\n", opt->fhsm_second);
+			break;
+		case Opt_acl:
+			AuLabel(acl);
+			break;
+		case Opt_noacl:
+			AuLabel(noacl);
+			break;
+		default:
+			BUG();
+		}
+		opt++;
+	}
+#endif
+}
+
+void au_opts_free(struct au_opts *opts)
+{
+	struct au_opt *opt;
+
+	opt = opts->opt;
+	while (opt->type != Opt_tail) {
+		switch (opt->type) {
+		case Opt_add:
+		case Opt_append:
+		case Opt_prepend:
+			path_put(&opt->add.path);
+			break;
+		case Opt_del:
+		case Opt_idel:
+			path_put(&opt->del.h_path);
+			break;
+		case Opt_mod:
+		case Opt_imod:
+			dput(opt->mod.h_root);
+			break;
+		case Opt_xino:
+			fput(opt->xino.file);
+			break;
+		}
+		opt++;
+	}
+}
+
+static int opt_add(struct au_opt *opt, char *opt_str, unsigned long sb_flags,
+		   aufs_bindex_t bindex)
+{
+	int err;
+	struct au_opt_add *add = &opt->add;
+	char *p;
+
+	add->bindex = bindex;
+	add->perm = AuBrPerm_RO;
+	add->pathname = opt_str;
+	p = strchr(opt_str, '=');
+	if (p) {
+		*p++ = 0;
+		if (*p)
+			add->perm = br_perm_val(p);
+	}
+
+	err = vfsub_kern_path(add->pathname, lkup_dirflags, &add->path);
+	if (!err) {
+		if (!p) {
+			add->perm = AuBrPerm_RO;
+			if (au_test_fs_rr(add->path.dentry->d_sb))
+				add->perm = AuBrPerm_RR;
+			else if (!bindex && !(sb_flags & MS_RDONLY))
+				add->perm = AuBrPerm_RW;
+		}
+		opt->type = Opt_add;
+		goto out;
+	}
+	pr_err("lookup failed %s (%d)\n", add->pathname, err);
+	err = -EINVAL;
+
+out:
+	return err;
+}
+
+static int au_opts_parse_del(struct au_opt_del *del, substring_t args[])
+{
+	int err;
+
+	del->pathname = args[0].from;
+	AuDbg("del path %s\n", del->pathname);
+
+	err = vfsub_kern_path(del->pathname, lkup_dirflags, &del->h_path);
+	if (unlikely(err))
+		pr_err("lookup failed %s (%d)\n", del->pathname, err);
+
+	return err;
+}
+
+#if 0 /* reserved for future use */
+static int au_opts_parse_idel(struct super_block *sb, aufs_bindex_t bindex,
+			      struct au_opt_del *del, substring_t args[])
+{
+	int err;
+	struct dentry *root;
+
+	err = -EINVAL;
+	root = sb->s_root;
+	aufs_read_lock(root, AuLock_FLUSH);
+	if (bindex < 0 || au_sbend(sb) < bindex) {
+		pr_err("out of bounds, %d\n", bindex);
+		goto out;
+	}
+
+	err = 0;
+	del->h_path.dentry = dget(au_h_dptr(root, bindex));
+	del->h_path.mnt = mntget(au_sbr_mnt(sb, bindex));
+
+out:
+	aufs_read_unlock(root, !AuLock_IR);
+	return err;
+}
+#endif
+
+static int noinline_for_stack
+au_opts_parse_mod(struct au_opt_mod *mod, substring_t args[])
+{
+	int err;
+	struct path path;
+	char *p;
+
+	err = -EINVAL;
+	mod->path = args[0].from;
+	p = strchr(mod->path, '=');
+	if (unlikely(!p)) {
+		pr_err("no permssion %s\n", args[0].from);
+		goto out;
+	}
+
+	*p++ = 0;
+	err = vfsub_kern_path(mod->path, lkup_dirflags, &path);
+	if (unlikely(err)) {
+		pr_err("lookup failed %s (%d)\n", mod->path, err);
+		goto out;
+	}
+
+	mod->perm = br_perm_val(p);
+	AuDbg("mod path %s, perm 0x%x, %s\n", mod->path, mod->perm, p);
+	mod->h_root = dget(path.dentry);
+	path_put(&path);
+
+out:
+	return err;
+}
+
+#if 0 /* reserved for future use */
+static int au_opts_parse_imod(struct super_block *sb, aufs_bindex_t bindex,
+			      struct au_opt_mod *mod, substring_t args[])
+{
+	int err;
+	struct dentry *root;
+
+	err = -EINVAL;
+	root = sb->s_root;
+	aufs_read_lock(root, AuLock_FLUSH);
+	if (bindex < 0 || au_sbend(sb) < bindex) {
+		pr_err("out of bounds, %d\n", bindex);
+		goto out;
+	}
+
+	err = 0;
+	mod->perm = br_perm_val(args[1].from);
+	AuDbg("mod path %s, perm 0x%x, %s\n",
+	      mod->path, mod->perm, args[1].from);
+	mod->h_root = dget(au_h_dptr(root, bindex));
+
+out:
+	aufs_read_unlock(root, !AuLock_IR);
+	return err;
+}
+#endif
+
+static int au_opts_parse_xino(struct super_block *sb, struct au_opt_xino *xino,
+			      substring_t args[])
+{
+	int err;
+	struct file *file;
+
+	file = au_xino_create(sb, args[0].from, /*silent*/0);
+	err = PTR_ERR(file);
+	if (IS_ERR(file))
+		goto out;
+
+	err = -EINVAL;
+	if (unlikely(file->f_path.dentry->d_sb == sb)) {
+		fput(file);
+		pr_err("%s must be outside\n", args[0].from);
+		goto out;
+	}
+
+	err = 0;
+	xino->file = file;
+	xino->path = args[0].from;
+
+out:
+	return err;
+}
+
+static int noinline_for_stack
+au_opts_parse_xino_itrunc_path(struct super_block *sb,
+			       struct au_opt_xino_itrunc *xino_itrunc,
+			       substring_t args[])
+{
+	int err;
+	aufs_bindex_t bend, bindex;
+	struct path path;
+	struct dentry *root;
+
+	err = vfsub_kern_path(args[0].from, lkup_dirflags, &path);
+	if (unlikely(err)) {
+		pr_err("lookup failed %s (%d)\n", args[0].from, err);
+		goto out;
+	}
+
+	xino_itrunc->bindex = -1;
+	root = sb->s_root;
+	aufs_read_lock(root, AuLock_FLUSH);
+	bend = au_sbend(sb);
+	for (bindex = 0; bindex <= bend; bindex++) {
+		if (au_h_dptr(root, bindex) == path.dentry) {
+			xino_itrunc->bindex = bindex;
+			break;
+		}
+	}
+	aufs_read_unlock(root, !AuLock_IR);
+	path_put(&path);
+
+	if (unlikely(xino_itrunc->bindex < 0)) {
+		pr_err("no such branch %s\n", args[0].from);
+		err = -EINVAL;
+	}
+
+out:
+	return err;
+}
+
+/* called without aufs lock */
+int au_opts_parse(struct super_block *sb, char *str, struct au_opts *opts)
+{
+	int err, n, token;
+	aufs_bindex_t bindex;
+	unsigned char skipped;
+	struct dentry *root;
+	struct au_opt *opt, *opt_tail;
+	char *opt_str;
+	/* reduce the stack space */
+	union {
+		struct au_opt_xino_itrunc *xino_itrunc;
+		struct au_opt_wbr_create *create;
+	} u;
+	struct {
+		substring_t args[MAX_OPT_ARGS];
+	} *a;
+
+	err = -ENOMEM;
+	a = kmalloc(sizeof(*a), GFP_NOFS);
+	if (unlikely(!a))
+		goto out;
+
+	root = sb->s_root;
+	err = 0;
+	bindex = 0;
+	opt = opts->opt;
+	opt_tail = opt + opts->max_opt - 1;
+	opt->type = Opt_tail;
+	while (!err && (opt_str = strsep(&str, ",")) && *opt_str) {
+		err = -EINVAL;
+		skipped = 0;
+		token = match_token(opt_str, options, a->args);
+		switch (token) {
+		case Opt_br:
+			err = 0;
+			while (!err && (opt_str = strsep(&a->args[0].from, ":"))
+			       && *opt_str) {
+				err = opt_add(opt, opt_str, opts->sb_flags,
+					      bindex++);
+				if (unlikely(!err && ++opt > opt_tail)) {
+					err = -E2BIG;
+					break;
+				}
+				opt->type = Opt_tail;
+				skipped = 1;
+			}
+			break;
+		case Opt_add:
+			if (unlikely(match_int(&a->args[0], &n))) {
+				pr_err("bad integer in %s\n", opt_str);
+				break;
+			}
+			bindex = n;
+			err = opt_add(opt, a->args[1].from, opts->sb_flags,
+				      bindex);
+			if (!err)
+				opt->type = token;
+			break;
+		case Opt_append:
+			err = opt_add(opt, a->args[0].from, opts->sb_flags,
+				      /*dummy bindex*/1);
+			if (!err)
+				opt->type = token;
+			break;
+		case Opt_prepend:
+			err = opt_add(opt, a->args[0].from, opts->sb_flags,
+				      /*bindex*/0);
+			if (!err)
+				opt->type = token;
+			break;
+		case Opt_del:
+			err = au_opts_parse_del(&opt->del, a->args);
+			if (!err)
+				opt->type = token;
+			break;
+#if 0 /* reserved for future use */
+		case Opt_idel:
+			del->pathname = "(indexed)";
+			if (unlikely(match_int(&args[0], &n))) {
+				pr_err("bad integer in %s\n", opt_str);
+				break;
+			}
+			err = au_opts_parse_idel(sb, n, &opt->del, a->args);
+			if (!err)
+				opt->type = token;
+			break;
+#endif
+		case Opt_mod:
+			err = au_opts_parse_mod(&opt->mod, a->args);
+			if (!err)
+				opt->type = token;
+			break;
+#ifdef IMOD /* reserved for future use */
+		case Opt_imod:
+			u.mod->path = "(indexed)";
+			if (unlikely(match_int(&a->args[0], &n))) {
+				pr_err("bad integer in %s\n", opt_str);
+				break;
+			}
+			err = au_opts_parse_imod(sb, n, &opt->mod, a->args);
+			if (!err)
+				opt->type = token;
+			break;
+#endif
+		case Opt_xino:
+			err = au_opts_parse_xino(sb, &opt->xino, a->args);
+			if (!err)
+				opt->type = token;
+			break;
+
+		case Opt_trunc_xino_path:
+			err = au_opts_parse_xino_itrunc_path
+				(sb, &opt->xino_itrunc, a->args);
+			if (!err)
+				opt->type = token;
+			break;
+
+		case Opt_itrunc_xino:
+			u.xino_itrunc = &opt->xino_itrunc;
+			if (unlikely(match_int(&a->args[0], &n))) {
+				pr_err("bad integer in %s\n", opt_str);
+				break;
+			}
+			u.xino_itrunc->bindex = n;
+			aufs_read_lock(root, AuLock_FLUSH);
+			if (n < 0 || au_sbend(sb) < n) {
+				pr_err("out of bounds, %d\n", n);
+				aufs_read_unlock(root, !AuLock_IR);
+				break;
+			}
+			aufs_read_unlock(root, !AuLock_IR);
+			err = 0;
+			opt->type = token;
+			break;
+
+		case Opt_dirwh:
+			if (unlikely(match_int(&a->args[0], &opt->dirwh)))
+				break;
+			err = 0;
+			opt->type = token;
+			break;
+
+		case Opt_rdcache:
+			if (unlikely(match_int(&a->args[0], &n))) {
+				pr_err("bad integer in %s\n", opt_str);
+				break;
+			}
+			if (unlikely(n > AUFS_RDCACHE_MAX)) {
+				pr_err("rdcache must be smaller than %d\n",
+				       AUFS_RDCACHE_MAX);
+				break;
+			}
+			opt->rdcache = n;
+			err = 0;
+			opt->type = token;
+			break;
+		case Opt_rdblk:
+			if (unlikely(match_int(&a->args[0], &n)
+				     || n < 0
+				     || n > KMALLOC_MAX_SIZE)) {
+				pr_err("bad integer in %s\n", opt_str);
+				break;
+			}
+			if (unlikely(n && n < NAME_MAX)) {
+				pr_err("rdblk must be larger than %d\n",
+				       NAME_MAX);
+				break;
+			}
+			opt->rdblk = n;
+			err = 0;
+			opt->type = token;
+			break;
+		case Opt_rdhash:
+			if (unlikely(match_int(&a->args[0], &n)
+				     || n < 0
+				     || n * sizeof(struct hlist_head)
+				     > KMALLOC_MAX_SIZE)) {
+				pr_err("bad integer in %s\n", opt_str);
+				break;
+			}
+			opt->rdhash = n;
+			err = 0;
+			opt->type = token;
+			break;
+
+		case Opt_trunc_xino:
+		case Opt_notrunc_xino:
+		case Opt_noxino:
+		case Opt_trunc_xib:
+		case Opt_notrunc_xib:
+		case Opt_shwh:
+		case Opt_noshwh:
+		case Opt_dirperm1:
+		case Opt_nodirperm1:
+		case Opt_plink:
+		case Opt_noplink:
+		case Opt_list_plink:
+		case Opt_dio:
+		case Opt_nodio:
+		case Opt_diropq_a:
+		case Opt_diropq_w:
+		case Opt_warn_perm:
+		case Opt_nowarn_perm:
+		case Opt_verbose:
+		case Opt_noverbose:
+		case Opt_sum:
+		case Opt_nosum:
+		case Opt_wsum:
+		case Opt_rdblk_def:
+		case Opt_rdhash_def:
+		case Opt_acl:
+		case Opt_noacl:
+			err = 0;
+			opt->type = token;
+			break;
+
+		case Opt_udba:
+			opt->udba = udba_val(a->args[0].from);
+			if (opt->udba >= 0) {
+				err = 0;
+				opt->type = token;
+			} else
+				pr_err("wrong value, %s\n", opt_str);
+			break;
+
+		case Opt_wbr_create:
+			u.create = &opt->wbr_create;
+			u.create->wbr_create
+				= au_wbr_create_val(a->args[0].from, u.create);
+			if (u.create->wbr_create >= 0) {
+				err = 0;
+				opt->type = token;
+			} else
+				pr_err("wrong value, %s\n", opt_str);
+			break;
+		case Opt_wbr_copyup:
+			opt->wbr_copyup = au_wbr_copyup_val(a->args[0].from);
+			if (opt->wbr_copyup >= 0) {
+				err = 0;
+				opt->type = token;
+			} else
+				pr_err("wrong value, %s\n", opt_str);
+			break;
+
+		case Opt_fhsm_sec:
+			if (unlikely(match_int(&a->args[0], &n)
+				     || n < 0)) {
+				pr_err("bad integer in %s\n", opt_str);
+				break;
+			}
+			if (sysaufs_brs) {
+				opt->fhsm_second = n;
+				opt->type = token;
+			} else
+				pr_warn("ignored %s\n", opt_str);
+			err = 0;
+			break;
+
+		case Opt_ignore:
+			pr_warn("ignored %s\n", opt_str);
+			/*FALLTHROUGH*/
+		case Opt_ignore_silent:
+			skipped = 1;
+			err = 0;
+			break;
+		case Opt_err:
+			pr_err("unknown option %s\n", opt_str);
+			break;
+		}
+
+		if (!err && !skipped) {
+			if (unlikely(++opt > opt_tail)) {
+				err = -E2BIG;
+				opt--;
+				opt->type = Opt_tail;
+				break;
+			}
+			opt->type = Opt_tail;
+		}
+	}
+
+	kfree(a);
+	dump_opts(opts);
+	if (unlikely(err))
+		au_opts_free(opts);
+
+out:
+	return err;
+}
+
+static int au_opt_wbr_create(struct super_block *sb,
+			     struct au_opt_wbr_create *create)
+{
+	int err;
+	struct au_sbinfo *sbinfo;
+
+	SiMustWriteLock(sb);
+
+	err = 1; /* handled */
+	sbinfo = au_sbi(sb);
+	if (sbinfo->si_wbr_create_ops->fin) {
+		err = sbinfo->si_wbr_create_ops->fin(sb);
+		if (!err)
+			err = 1;
+	}
+
+	sbinfo->si_wbr_create = create->wbr_create;
+	sbinfo->si_wbr_create_ops = au_wbr_create_ops + create->wbr_create;
+	switch (create->wbr_create) {
+	case AuWbrCreate_MFSRRV:
+	case AuWbrCreate_MFSRR:
+	case AuWbrCreate_PMFSRR:
+	case AuWbrCreate_PMFSRRV:
+		sbinfo->si_wbr_mfs.mfsrr_watermark = create->mfsrr_watermark;
+		/*FALLTHROUGH*/
+	case AuWbrCreate_MFS:
+	case AuWbrCreate_MFSV:
+	case AuWbrCreate_PMFS:
+	case AuWbrCreate_PMFSV:
+		sbinfo->si_wbr_mfs.mfs_expire
+			= msecs_to_jiffies(create->mfs_second * MSEC_PER_SEC);
+		break;
+	}
+
+	if (sbinfo->si_wbr_create_ops->init)
+		sbinfo->si_wbr_create_ops->init(sb); /* ignore */
+
+	return err;
+}
+
+/*
+ * returns,
+ * plus: processed without an error
+ * zero: unprocessed
+ */
+static int au_opt_simple(struct super_block *sb, struct au_opt *opt,
+			 struct au_opts *opts)
+{
+	int err;
+	struct au_sbinfo *sbinfo;
+
+	SiMustWriteLock(sb);
+
+	err = 1; /* handled */
+	sbinfo = au_sbi(sb);
+	switch (opt->type) {
+	case Opt_udba:
+		sbinfo->si_mntflags &= ~AuOptMask_UDBA;
+		sbinfo->si_mntflags |= opt->udba;
+		opts->given_udba |= opt->udba;
+		break;
+
+	case Opt_plink:
+		au_opt_set(sbinfo->si_mntflags, PLINK);
+		break;
+	case Opt_noplink:
+		if (au_opt_test(sbinfo->si_mntflags, PLINK))
+			au_plink_put(sb, /*verbose*/1);
+		au_opt_clr(sbinfo->si_mntflags, PLINK);
+		break;
+	case Opt_list_plink:
+		if (au_opt_test(sbinfo->si_mntflags, PLINK))
+			au_plink_list(sb);
+		break;
+
+	case Opt_dio:
+		au_opt_set(sbinfo->si_mntflags, DIO);
+		au_fset_opts(opts->flags, REFRESH_DYAOP);
+		break;
+	case Opt_nodio:
+		au_opt_clr(sbinfo->si_mntflags, DIO);
+		au_fset_opts(opts->flags, REFRESH_DYAOP);
+		break;
+
+	case Opt_fhsm_sec:
+		au_fhsm_set(sbinfo, opt->fhsm_second);
+		break;
+
+	case Opt_diropq_a:
+		au_opt_set(sbinfo->si_mntflags, ALWAYS_DIROPQ);
+		break;
+	case Opt_diropq_w:
+		au_opt_clr(sbinfo->si_mntflags, ALWAYS_DIROPQ);
+		break;
+
+	case Opt_warn_perm:
+		au_opt_set(sbinfo->si_mntflags, WARN_PERM);
+		break;
+	case Opt_nowarn_perm:
+		au_opt_clr(sbinfo->si_mntflags, WARN_PERM);
+		break;
+
+	case Opt_verbose:
+		au_opt_set(sbinfo->si_mntflags, VERBOSE);
+		break;
+	case Opt_noverbose:
+		au_opt_clr(sbinfo->si_mntflags, VERBOSE);
+		break;
+
+	case Opt_sum:
+		au_opt_set(sbinfo->si_mntflags, SUM);
+		break;
+	case Opt_wsum:
+		au_opt_clr(sbinfo->si_mntflags, SUM);
+		au_opt_set(sbinfo->si_mntflags, SUM_W);
+	case Opt_nosum:
+		au_opt_clr(sbinfo->si_mntflags, SUM);
+		au_opt_clr(sbinfo->si_mntflags, SUM_W);
+		break;
+
+	case Opt_wbr_create:
+		err = au_opt_wbr_create(sb, &opt->wbr_create);
+		break;
+	case Opt_wbr_copyup:
+		sbinfo->si_wbr_copyup = opt->wbr_copyup;
+		sbinfo->si_wbr_copyup_ops = au_wbr_copyup_ops + opt->wbr_copyup;
+		break;
+
+	case Opt_dirwh:
+		sbinfo->si_dirwh = opt->dirwh;
+		break;
+
+	case Opt_rdcache:
+		sbinfo->si_rdcache
+			= msecs_to_jiffies(opt->rdcache * MSEC_PER_SEC);
+		break;
+	case Opt_rdblk:
+		sbinfo->si_rdblk = opt->rdblk;
+		break;
+	case Opt_rdblk_def:
+		sbinfo->si_rdblk = AUFS_RDBLK_DEF;
+		break;
+	case Opt_rdhash:
+		sbinfo->si_rdhash = opt->rdhash;
+		break;
+	case Opt_rdhash_def:
+		sbinfo->si_rdhash = AUFS_RDHASH_DEF;
+		break;
+
+	case Opt_shwh:
+		au_opt_set(sbinfo->si_mntflags, SHWH);
+		break;
+	case Opt_noshwh:
+		au_opt_clr(sbinfo->si_mntflags, SHWH);
+		break;
+
+	case Opt_dirperm1:
+		au_opt_set(sbinfo->si_mntflags, DIRPERM1);
+		break;
+	case Opt_nodirperm1:
+		au_opt_clr(sbinfo->si_mntflags, DIRPERM1);
+		break;
+
+	case Opt_trunc_xino:
+		au_opt_set(sbinfo->si_mntflags, TRUNC_XINO);
+		break;
+	case Opt_notrunc_xino:
+		au_opt_clr(sbinfo->si_mntflags, TRUNC_XINO);
+		break;
+
+	case Opt_trunc_xino_path:
+	case Opt_itrunc_xino:
+		err = au_xino_trunc(sb, opt->xino_itrunc.bindex);
+		if (!err)
+			err = 1;
+		break;
+
+	case Opt_trunc_xib:
+		au_fset_opts(opts->flags, TRUNC_XIB);
+		break;
+	case Opt_notrunc_xib:
+		au_fclr_opts(opts->flags, TRUNC_XIB);
+		break;
+
+	case Opt_acl:
+		sb->s_flags |= MS_POSIXACL;
+		break;
+	case Opt_noacl:
+		sb->s_flags &= ~MS_POSIXACL;
+		break;
+
+	default:
+		err = 0;
+		break;
+	}
+
+	return err;
+}
+
+/*
+ * returns tri-state.
+ * plus: processed without an error
+ * zero: unprocessed
+ * minus: error
+ */
+static int au_opt_br(struct super_block *sb, struct au_opt *opt,
+		     struct au_opts *opts)
+{
+	int err, do_refresh;
+
+	err = 0;
+	switch (opt->type) {
+	case Opt_append:
+		opt->add.bindex = au_sbend(sb) + 1;
+		if (opt->add.bindex < 0)
+			opt->add.bindex = 0;
+		goto add;
+	case Opt_prepend:
+		opt->add.bindex = 0;
+	add: /* indented label */
+	case Opt_add:
+		err = au_br_add(sb, &opt->add,
+				au_ftest_opts(opts->flags, REMOUNT));
+		if (!err) {
+			err = 1;
+			au_fset_opts(opts->flags, REFRESH);
+		}
+		break;
+
+	case Opt_del:
+	case Opt_idel:
+		err = au_br_del(sb, &opt->del,
+				au_ftest_opts(opts->flags, REMOUNT));
+		if (!err) {
+			err = 1;
+			au_fset_opts(opts->flags, TRUNC_XIB);
+			au_fset_opts(opts->flags, REFRESH);
+		}
+		break;
+
+	case Opt_mod:
+	case Opt_imod:
+		err = au_br_mod(sb, &opt->mod,
+				au_ftest_opts(opts->flags, REMOUNT),
+				&do_refresh);
+		if (!err) {
+			err = 1;
+			if (do_refresh)
+				au_fset_opts(opts->flags, REFRESH);
+		}
+		break;
+	}
+
+	return err;
+}
+
+static int au_opt_xino(struct super_block *sb, struct au_opt *opt,
+		       struct au_opt_xino **opt_xino,
+		       struct au_opts *opts)
+{
+	int err;
+	aufs_bindex_t bend, bindex;
+	struct dentry *root, *parent, *h_root;
+
+	err = 0;
+	switch (opt->type) {
+	case Opt_xino:
+		err = au_xino_set(sb, &opt->xino,
+				  !!au_ftest_opts(opts->flags, REMOUNT));
+		if (unlikely(err))
+			break;
+
+		*opt_xino = &opt->xino;
+		au_xino_brid_set(sb, -1);
+
+		/* safe d_parent access */
+		parent = opt->xino.file->f_path.dentry->d_parent;
+		root = sb->s_root;
+		bend = au_sbend(sb);
+		for (bindex = 0; bindex <= bend; bindex++) {
+			h_root = au_h_dptr(root, bindex);
+			if (h_root == parent) {
+				au_xino_brid_set(sb, au_sbr_id(sb, bindex));
+				break;
+			}
+		}
+		break;
+
+	case Opt_noxino:
+		au_xino_clr(sb);
+		au_xino_brid_set(sb, -1);
+		*opt_xino = (void *)-1;
+		break;
+	}
+
+	return err;
+}
+
+int au_opts_verify(struct super_block *sb, unsigned long sb_flags,
+		   unsigned int pending)
+{
+	int err, fhsm;
+	aufs_bindex_t bindex, bend;
+	unsigned char do_plink, skip, do_free, can_no_dreval;
+	struct au_branch *br;
+	struct au_wbr *wbr;
+	struct dentry *root, *dentry;
+	struct inode *dir, *h_dir;
+	struct au_sbinfo *sbinfo;
+	struct au_hinode *hdir;
+
+	SiMustAnyLock(sb);
+
+	sbinfo = au_sbi(sb);
+	AuDebugOn(!(sbinfo->si_mntflags & AuOptMask_UDBA));
+
+	if (!(sb_flags & MS_RDONLY)) {
+		if (unlikely(!au_br_writable(au_sbr_perm(sb, 0))))
+			pr_warn("first branch should be rw\n");
+		if (unlikely(au_opt_test(sbinfo->si_mntflags, SHWH)))
+			pr_warn("shwh should be used with ro\n");
+	}
+
+	if (au_opt_test((sbinfo->si_mntflags | pending), UDBA_HNOTIFY)
+	    && !au_opt_test(sbinfo->si_mntflags, XINO))
+		pr_warn("udba=*notify requires xino\n");
+
+	if (au_opt_test(sbinfo->si_mntflags, DIRPERM1))
+		pr_warn("dirperm1 breaks the protection"
+			" by the permission bits on the lower branch\n");
+
+	err = 0;
+	fhsm = 0;
+	root = sb->s_root;
+	dir = d_inode(root);
+	do_plink = !!au_opt_test(sbinfo->si_mntflags, PLINK);
+	can_no_dreval = !!au_opt_test((sbinfo->si_mntflags | pending),
+				      UDBA_NONE);
+	bend = au_sbend(sb);
+	for (bindex = 0; !err && bindex <= bend; bindex++) {
+		skip = 0;
+		h_dir = au_h_iptr(dir, bindex);
+		br = au_sbr(sb, bindex);
+
+		if ((br->br_perm & AuBrAttr_ICEX)
+		    && !h_dir->i_op->listxattr)
+			br->br_perm &= ~AuBrAttr_ICEX;
+#if 0
+		if ((br->br_perm & AuBrAttr_ICEX_SEC)
+		    && (au_br_sb(br)->s_flags & MS_NOSEC))
+			br->br_perm &= ~AuBrAttr_ICEX_SEC;
+#endif
+
+		do_free = 0;
+		wbr = br->br_wbr;
+		if (wbr)
+			wbr_wh_read_lock(wbr);
+
+		if (!au_br_writable(br->br_perm)) {
+			do_free = !!wbr;
+			skip = (!wbr
+				|| (!wbr->wbr_whbase
+				    && !wbr->wbr_plink
+				    && !wbr->wbr_orph));
+		} else if (!au_br_wh_linkable(br->br_perm)) {
+			/* skip = (!br->br_whbase && !br->br_orph); */
+			skip = (!wbr || !wbr->wbr_whbase);
+			if (skip && wbr) {
+				if (do_plink)
+					skip = !!wbr->wbr_plink;
+				else
+					skip = !wbr->wbr_plink;
+			}
+		} else {
+			/* skip = (br->br_whbase && br->br_ohph); */
+			skip = (wbr && wbr->wbr_whbase);
+			if (skip) {
+				if (do_plink)
+					skip = !!wbr->wbr_plink;
+				else
+					skip = !wbr->wbr_plink;
+			}
+		}
+		if (wbr)
+			wbr_wh_read_unlock(wbr);
+
+		if (can_no_dreval) {
+			dentry = br->br_path.dentry;
+			spin_lock(&dentry->d_lock);
+			if (dentry->d_flags &
+			    (DCACHE_OP_REVALIDATE | DCACHE_OP_WEAK_REVALIDATE))
+				can_no_dreval = 0;
+			spin_unlock(&dentry->d_lock);
+		}
+
+		if (au_br_fhsm(br->br_perm)) {
+			fhsm++;
+			AuDebugOn(!br->br_fhsm);
+		}
+
+		if (skip)
+			continue;
+
+		hdir = au_hi(dir, bindex);
+		au_hn_imtx_lock_nested(hdir, AuLsc_I_PARENT);
+		if (wbr)
+			wbr_wh_write_lock(wbr);
+		err = au_wh_init(br, sb);
+		if (wbr)
+			wbr_wh_write_unlock(wbr);
+		au_hn_imtx_unlock(hdir);
+
+		if (!err && do_free) {
+			kfree(wbr);
+			br->br_wbr = NULL;
+		}
+	}
+
+	if (can_no_dreval)
+		au_fset_si(sbinfo, NO_DREVAL);
+	else
+		au_fclr_si(sbinfo, NO_DREVAL);
+
+	if (fhsm >= 2) {
+		au_fset_si(sbinfo, FHSM);
+		for (bindex = bend; bindex >= 0; bindex--) {
+			br = au_sbr(sb, bindex);
+			if (au_br_fhsm(br->br_perm)) {
+				au_fhsm_set_bottom(sb, bindex);
+				break;
+			}
+		}
+	} else {
+		au_fclr_si(sbinfo, FHSM);
+		au_fhsm_set_bottom(sb, -1);
+	}
+
+	return err;
+}
+
+int au_opts_mount(struct super_block *sb, struct au_opts *opts)
+{
+	int err;
+	unsigned int tmp;
+	aufs_bindex_t bindex, bend;
+	struct au_opt *opt;
+	struct au_opt_xino *opt_xino, xino;
+	struct au_sbinfo *sbinfo;
+	struct au_branch *br;
+	struct inode *dir;
+
+	SiMustWriteLock(sb);
+
+	err = 0;
+	opt_xino = NULL;
+	opt = opts->opt;
+	while (err >= 0 && opt->type != Opt_tail)
+		err = au_opt_simple(sb, opt++, opts);
+	if (err > 0)
+		err = 0;
+	else if (unlikely(err < 0))
+		goto out;
+
+	/* disable xino and udba temporary */
+	sbinfo = au_sbi(sb);
+	tmp = sbinfo->si_mntflags;
+	au_opt_clr(sbinfo->si_mntflags, XINO);
+	au_opt_set_udba(sbinfo->si_mntflags, UDBA_REVAL);
+
+	opt = opts->opt;
+	while (err >= 0 && opt->type != Opt_tail)
+		err = au_opt_br(sb, opt++, opts);
+	if (err > 0)
+		err = 0;
+	else if (unlikely(err < 0))
+		goto out;
+
+	bend = au_sbend(sb);
+	if (unlikely(bend < 0)) {
+		err = -EINVAL;
+		pr_err("no branches\n");
+		goto out;
+	}
+
+	if (au_opt_test(tmp, XINO))
+		au_opt_set(sbinfo->si_mntflags, XINO);
+	opt = opts->opt;
+	while (!err && opt->type != Opt_tail)
+		err = au_opt_xino(sb, opt++, &opt_xino, opts);
+	if (unlikely(err))
+		goto out;
+
+	err = au_opts_verify(sb, sb->s_flags, tmp);
+	if (unlikely(err))
+		goto out;
+
+	/* restore xino */
+	if (au_opt_test(tmp, XINO) && !opt_xino) {
+		xino.file = au_xino_def(sb);
+		err = PTR_ERR(xino.file);
+		if (IS_ERR(xino.file))
+			goto out;
+
+		err = au_xino_set(sb, &xino, /*remount*/0);
+		fput(xino.file);
+		if (unlikely(err))
+			goto out;
+	}
+
+	/* restore udba */
+	tmp &= AuOptMask_UDBA;
+	sbinfo->si_mntflags &= ~AuOptMask_UDBA;
+	sbinfo->si_mntflags |= tmp;
+	bend = au_sbend(sb);
+	for (bindex = 0; bindex <= bend; bindex++) {
+		br = au_sbr(sb, bindex);
+		err = au_hnotify_reset_br(tmp, br, br->br_perm);
+		if (unlikely(err))
+			AuIOErr("hnotify failed on br %d, %d, ignored\n",
+				bindex, err);
+		/* go on even if err */
+	}
+	if (au_opt_test(tmp, UDBA_HNOTIFY)) {
+		dir = d_inode(sb->s_root);
+		au_hn_reset(dir, au_hi_flags(dir, /*isdir*/1) & ~AuHi_XINO);
+	}
+
+out:
+	return err;
+}
+
+int au_opts_remount(struct super_block *sb, struct au_opts *opts)
+{
+	int err, rerr;
+	unsigned char no_dreval;
+	struct inode *dir;
+	struct au_opt_xino *opt_xino;
+	struct au_opt *opt;
+	struct au_sbinfo *sbinfo;
+
+	SiMustWriteLock(sb);
+
+	err = 0;
+	dir = d_inode(sb->s_root);
+	sbinfo = au_sbi(sb);
+	opt_xino = NULL;
+	opt = opts->opt;
+	while (err >= 0 && opt->type != Opt_tail) {
+		err = au_opt_simple(sb, opt, opts);
+		if (!err)
+			err = au_opt_br(sb, opt, opts);
+		if (!err)
+			err = au_opt_xino(sb, opt, &opt_xino, opts);
+		opt++;
+	}
+	if (err > 0)
+		err = 0;
+	AuTraceErr(err);
+	/* go on even err */
+
+	no_dreval = !!au_ftest_si(sbinfo, NO_DREVAL);
+	rerr = au_opts_verify(sb, opts->sb_flags, /*pending*/0);
+	if (unlikely(rerr && !err))
+		err = rerr;
+
+	if (no_dreval != !!au_ftest_si(sbinfo, NO_DREVAL))
+		au_fset_opts(opts->flags, REFRESH_IDOP);
+
+	if (au_ftest_opts(opts->flags, TRUNC_XIB)) {
+		rerr = au_xib_trunc(sb);
+		if (unlikely(rerr && !err))
+			err = rerr;
+	}
+
+	/* will be handled by the caller */
+	if (!au_ftest_opts(opts->flags, REFRESH)
+	    && (opts->given_udba
+		|| au_opt_test(sbinfo->si_mntflags, XINO)
+		|| au_ftest_opts(opts->flags, REFRESH_IDOP)
+		    ))
+		au_fset_opts(opts->flags, REFRESH);
+
+	AuDbg("status 0x%x\n", opts->flags);
+	return err;
+}
+
+/* ---------------------------------------------------------------------- */
+
+unsigned int au_opt_udba(struct super_block *sb)
+{
+	return au_mntflags(sb) & AuOptMask_UDBA;
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/fs/aufs/opts.h
@@ -0,0 +1,211 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+ *
+ * This program, aufs is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * mount options/flags
+ */
+
+#ifndef __AUFS_OPTS_H__
+#define __AUFS_OPTS_H__
+
+#ifdef __KERNEL__
+
+#include <linux/path.h>
+
+struct file;
+struct super_block;
+
+/* ---------------------------------------------------------------------- */
+
+/* mount flags */
+#define AuOpt_XINO		1		/* external inode number bitmap
+						   and translation table */
+#define AuOpt_TRUNC_XINO	(1 << 1)	/* truncate xino files */
+#define AuOpt_UDBA_NONE		(1 << 2)	/* users direct branch access */
+#define AuOpt_UDBA_REVAL	(1 << 3)
+#define AuOpt_UDBA_HNOTIFY	(1 << 4)
+#define AuOpt_SHWH		(1 << 5)	/* show whiteout */
+#define AuOpt_PLINK		(1 << 6)	/* pseudo-link */
+#define AuOpt_DIRPERM1		(1 << 7)	/* ignore the lower dir's perm
+						   bits */
+#define AuOpt_ALWAYS_DIROPQ	(1 << 9)	/* policy to creating diropq */
+#define AuOpt_SUM		(1 << 10)	/* summation for statfs(2) */
+#define AuOpt_SUM_W		(1 << 11)	/* unimplemented */
+#define AuOpt_WARN_PERM		(1 << 12)	/* warn when add-branch */
+#define AuOpt_VERBOSE		(1 << 13)	/* busy inode when del-branch */
+#define AuOpt_DIO		(1 << 14)	/* direct io */
+
+#ifndef CONFIG_AUFS_HNOTIFY
+#undef AuOpt_UDBA_HNOTIFY
+#define AuOpt_UDBA_HNOTIFY	0
+#endif
+#ifndef CONFIG_AUFS_SHWH
+#undef AuOpt_SHWH
+#define AuOpt_SHWH		0
+#endif
+
+#define AuOpt_Def	(AuOpt_XINO \
+			 | AuOpt_UDBA_REVAL \
+			 | AuOpt_PLINK \
+			 /* | AuOpt_DIRPERM1 */ \
+			 | AuOpt_WARN_PERM)
+#define AuOptMask_UDBA	(AuOpt_UDBA_NONE \
+			 | AuOpt_UDBA_REVAL \
+			 | AuOpt_UDBA_HNOTIFY)
+
+#define au_opt_test(flags, name)	(flags & AuOpt_##name)
+#define au_opt_set(flags, name) do { \
+	BUILD_BUG_ON(AuOpt_##name & AuOptMask_UDBA); \
+	((flags) |= AuOpt_##name); \
+} while (0)
+#define au_opt_set_udba(flags, name) do { \
+	(flags) &= ~AuOptMask_UDBA; \
+	((flags) |= AuOpt_##name); \
+} while (0)
+#define au_opt_clr(flags, name) do { \
+	((flags) &= ~AuOpt_##name); \
+} while (0)
+
+static inline unsigned int au_opts_plink(unsigned int mntflags)
+{
+#ifdef CONFIG_PROC_FS
+	return mntflags;
+#else
+	return mntflags & ~AuOpt_PLINK;
+#endif
+}
+
+/* ---------------------------------------------------------------------- */
+
+/* policies to select one among multiple writable branches */
+enum {
+	AuWbrCreate_TDP,	/* top down parent */
+	AuWbrCreate_RR,		/* round robin */
+	AuWbrCreate_MFS,	/* most free space */
+	AuWbrCreate_MFSV,	/* mfs with seconds */
+	AuWbrCreate_MFSRR,	/* mfs then rr */
+	AuWbrCreate_MFSRRV,	/* mfs then rr with seconds */
+	AuWbrCreate_PMFS,	/* parent and mfs */
+	AuWbrCreate_PMFSV,	/* parent and mfs with seconds */
+	AuWbrCreate_PMFSRR,	/* parent, mfs and round-robin */
+	AuWbrCreate_PMFSRRV,	/* plus seconds */
+
+	AuWbrCreate_Def = AuWbrCreate_TDP
+};
+
+enum {
+	AuWbrCopyup_TDP,	/* top down parent */
+	AuWbrCopyup_BUP,	/* bottom up parent */
+	AuWbrCopyup_BU,		/* bottom up */
+
+	AuWbrCopyup_Def = AuWbrCopyup_TDP
+};
+
+/* ---------------------------------------------------------------------- */
+
+struct au_opt_add {
+	aufs_bindex_t	bindex;
+	char		*pathname;
+	int		perm;
+	struct path	path;
+};
+
+struct au_opt_del {
+	char		*pathname;
+	struct path	h_path;
+};
+
+struct au_opt_mod {
+	char		*path;
+	int		perm;
+	struct dentry	*h_root;
+};
+
+struct au_opt_xino {
+	char		*path;
+	struct file	*file;
+};
+
+struct au_opt_xino_itrunc {
+	aufs_bindex_t	bindex;
+};
+
+struct au_opt_wbr_create {
+	int			wbr_create;
+	int			mfs_second;
+	unsigned long long	mfsrr_watermark;
+};
+
+struct au_opt {
+	int type;
+	union {
+		struct au_opt_xino	xino;
+		struct au_opt_xino_itrunc xino_itrunc;
+		struct au_opt_add	add;
+		struct au_opt_del	del;
+		struct au_opt_mod	mod;
+		int			dirwh;
+		int			rdcache;
+		unsigned int		rdblk;
+		unsigned int		rdhash;
+		int			udba;
+		struct au_opt_wbr_create wbr_create;
+		int			wbr_copyup;
+		unsigned int		fhsm_second;
+	};
+};
+
+/* opts flags */
+#define AuOpts_REMOUNT		1
+#define AuOpts_REFRESH		(1 << 1)
+#define AuOpts_TRUNC_XIB	(1 << 2)
+#define AuOpts_REFRESH_DYAOP	(1 << 3)
+#define AuOpts_REFRESH_IDOP	(1 << 4)
+#define au_ftest_opts(flags, name)	((flags) & AuOpts_##name)
+#define au_fset_opts(flags, name) \
+	do { (flags) |= AuOpts_##name; } while (0)
+#define au_fclr_opts(flags, name) \
+	do { (flags) &= ~AuOpts_##name; } while (0)
+
+struct au_opts {
+	struct au_opt	*opt;
+	int		max_opt;
+
+	unsigned int	given_udba;
+	unsigned int	flags;
+	unsigned long	sb_flags;
+};
+
+/* ---------------------------------------------------------------------- */
+
+/* opts.c */
+void au_optstr_br_perm(au_br_perm_str_t *str, int perm);
+const char *au_optstr_udba(int udba);
+const char *au_optstr_wbr_copyup(int wbr_copyup);
+const char *au_optstr_wbr_create(int wbr_create);
+
+void au_opts_free(struct au_opts *opts);
+int au_opts_parse(struct super_block *sb, char *str, struct au_opts *opts);
+int au_opts_verify(struct super_block *sb, unsigned long sb_flags,
+		   unsigned int pending);
+int au_opts_mount(struct super_block *sb, struct au_opts *opts);
+int au_opts_remount(struct super_block *sb, struct au_opts *opts);
+
+unsigned int au_opt_udba(struct super_block *sb);
+
+#endif /* __KERNEL__ */
+#endif /* __AUFS_OPTS_H__ */
--- /dev/null
+++ zfcpdump-kernel-4.4/fs/aufs/plink.c
@@ -0,0 +1,528 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+ *
+ * This program, aufs is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * pseudo-link
+ */
+
+#include "aufs.h"
+
+/*
+ * the pseudo-link maintenance mode.
+ * during a user process maintains the pseudo-links,
+ * prohibit adding a new plink and branch manipulation.
+ *
+ * Flags
+ * NOPLM:
+ *	For entry functions which will handle plink, and i_mutex is already held
+ *	in VFS.
+ *	They cannot wait and should return an error at once.
+ *	Callers has to check the error.
+ * NOPLMW:
+ *	For entry functions which will handle plink, but i_mutex is not held
+ *	in VFS.
+ *	They can wait the plink maintenance mode to finish.
+ *
+ * They behave like F_SETLK and F_SETLKW.
+ * If the caller never handle plink, then both flags are unnecessary.
+ */
+
+int au_plink_maint(struct super_block *sb, int flags)
+{
+	int err;
+	pid_t pid, ppid;
+	struct au_sbinfo *sbi;
+
+	SiMustAnyLock(sb);
+
+	err = 0;
+	if (!au_opt_test(au_mntflags(sb), PLINK))
+		goto out;
+
+	sbi = au_sbi(sb);
+	pid = sbi->si_plink_maint_pid;
+	if (!pid || pid == current->pid)
+		goto out;
+
+	/* todo: it highly depends upon /sbin/mount.aufs */
+	rcu_read_lock();
+	ppid = task_pid_vnr(rcu_dereference(current->real_parent));
+	rcu_read_unlock();
+	if (pid == ppid)
+		goto out;
+
+	if (au_ftest_lock(flags, NOPLMW)) {
+		/* if there is no i_mutex lock in VFS, we don't need to wait */
+		/* AuDebugOn(!lockdep_depth(current)); */
+		while (sbi->si_plink_maint_pid) {
+			si_read_unlock(sb);
+			/* gave up wake_up_bit() */
+			wait_event(sbi->si_plink_wq, !sbi->si_plink_maint_pid);
+
+			if (au_ftest_lock(flags, FLUSH))
+				au_nwt_flush(&sbi->si_nowait);
+			si_noflush_read_lock(sb);
+		}
+	} else if (au_ftest_lock(flags, NOPLM)) {
+		AuDbg("ppid %d, pid %d\n", ppid, pid);
+		err = -EAGAIN;
+	}
+
+out:
+	return err;
+}
+
+void au_plink_maint_leave(struct au_sbinfo *sbinfo)
+{
+	spin_lock(&sbinfo->si_plink_maint_lock);
+	sbinfo->si_plink_maint_pid = 0;
+	spin_unlock(&sbinfo->si_plink_maint_lock);
+	wake_up_all(&sbinfo->si_plink_wq);
+}
+
+int au_plink_maint_enter(struct super_block *sb)
+{
+	int err;
+	struct au_sbinfo *sbinfo;
+
+	err = 0;
+	sbinfo = au_sbi(sb);
+	/* make sure i am the only one in this fs */
+	si_write_lock(sb, AuLock_FLUSH);
+	if (au_opt_test(au_mntflags(sb), PLINK)) {
+		spin_lock(&sbinfo->si_plink_maint_lock);
+		if (!sbinfo->si_plink_maint_pid)
+			sbinfo->si_plink_maint_pid = current->pid;
+		else
+			err = -EBUSY;
+		spin_unlock(&sbinfo->si_plink_maint_lock);
+	}
+	si_write_unlock(sb);
+
+	return err;
+}
+
+/* ---------------------------------------------------------------------- */
+
+#ifdef CONFIG_AUFS_DEBUG
+void au_plink_list(struct super_block *sb)
+{
+	int i;
+	struct au_sbinfo *sbinfo;
+	struct hlist_head *plink_hlist;
+	struct pseudo_link *plink;
+
+	SiMustAnyLock(sb);
+
+	sbinfo = au_sbi(sb);
+	AuDebugOn(!au_opt_test(au_mntflags(sb), PLINK));
+	AuDebugOn(au_plink_maint(sb, AuLock_NOPLM));
+
+	for (i = 0; i < AuPlink_NHASH; i++) {
+		plink_hlist = &sbinfo->si_plink[i].head;
+		rcu_read_lock();
+		hlist_for_each_entry_rcu(plink, plink_hlist, hlist)
+			AuDbg("%lu\n", plink->inode->i_ino);
+		rcu_read_unlock();
+	}
+}
+#endif
+
+/* is the inode pseudo-linked? */
+int au_plink_test(struct inode *inode)
+{
+	int found, i;
+	struct au_sbinfo *sbinfo;
+	struct hlist_head *plink_hlist;
+	struct pseudo_link *plink;
+
+	sbinfo = au_sbi(inode->i_sb);
+	AuRwMustAnyLock(&sbinfo->si_rwsem);
+	AuDebugOn(!au_opt_test(au_mntflags(inode->i_sb), PLINK));
+	AuDebugOn(au_plink_maint(inode->i_sb, AuLock_NOPLM));
+
+	found = 0;
+	i = au_plink_hash(inode->i_ino);
+	plink_hlist = &sbinfo->si_plink[i].head;
+	rcu_read_lock();
+	hlist_for_each_entry_rcu(plink, plink_hlist, hlist)
+		if (plink->inode == inode) {
+			found = 1;
+			break;
+		}
+	rcu_read_unlock();
+	return found;
+}
+
+/* ---------------------------------------------------------------------- */
+
+/*
+ * generate a name for plink.
+ * the file will be stored under AUFS_WH_PLINKDIR.
+ */
+/* 20 is max digits length of ulong 64 */
+#define PLINK_NAME_LEN	((20 + 1) * 2)
+
+static int plink_name(char *name, int len, struct inode *inode,
+		      aufs_bindex_t bindex)
+{
+	int rlen;
+	struct inode *h_inode;
+
+	h_inode = au_h_iptr(inode, bindex);
+	rlen = snprintf(name, len, "%lu.%lu", inode->i_ino, h_inode->i_ino);
+	return rlen;
+}
+
+struct au_do_plink_lkup_args {
+	struct dentry **errp;
+	struct qstr *tgtname;
+	struct dentry *h_parent;
+	struct au_branch *br;
+};
+
+static struct dentry *au_do_plink_lkup(struct qstr *tgtname,
+				       struct dentry *h_parent,
+				       struct au_branch *br)
+{
+	struct dentry *h_dentry;
+	struct mutex *h_mtx;
+
+	h_mtx = &d_inode(h_parent)->i_mutex;
+	mutex_lock_nested(h_mtx, AuLsc_I_CHILD2);
+	h_dentry = vfsub_lkup_one(tgtname, h_parent);
+	mutex_unlock(h_mtx);
+	return h_dentry;
+}
+
+static void au_call_do_plink_lkup(void *args)
+{
+	struct au_do_plink_lkup_args *a = args;
+	*a->errp = au_do_plink_lkup(a->tgtname, a->h_parent, a->br);
+}
+
+/* lookup the plink-ed @inode under the branch at @bindex */
+struct dentry *au_plink_lkup(struct inode *inode, aufs_bindex_t bindex)
+{
+	struct dentry *h_dentry, *h_parent;
+	struct au_branch *br;
+	int wkq_err;
+	char a[PLINK_NAME_LEN];
+	struct qstr tgtname = QSTR_INIT(a, 0);
+
+	AuDebugOn(au_plink_maint(inode->i_sb, AuLock_NOPLM));
+
+	br = au_sbr(inode->i_sb, bindex);
+	h_parent = br->br_wbr->wbr_plink;
+	tgtname.len = plink_name(a, sizeof(a), inode, bindex);
+
+	if (!uid_eq(current_fsuid(), GLOBAL_ROOT_UID)) {
+		struct au_do_plink_lkup_args args = {
+			.errp		= &h_dentry,
+			.tgtname	= &tgtname,
+			.h_parent	= h_parent,
+			.br		= br
+		};
+
+		wkq_err = au_wkq_wait(au_call_do_plink_lkup, &args);
+		if (unlikely(wkq_err))
+			h_dentry = ERR_PTR(wkq_err);
+	} else
+		h_dentry = au_do_plink_lkup(&tgtname, h_parent, br);
+
+	return h_dentry;
+}
+
+/* create a pseudo-link */
+static int do_whplink(struct qstr *tgt, struct dentry *h_parent,
+		      struct dentry *h_dentry, struct au_branch *br)
+{
+	int err;
+	struct path h_path = {
+		.mnt = au_br_mnt(br)
+	};
+	struct inode *h_dir, *delegated;
+
+	h_dir = d_inode(h_parent);
+	mutex_lock_nested(&h_dir->i_mutex, AuLsc_I_CHILD2);
+again:
+	h_path.dentry = vfsub_lkup_one(tgt, h_parent);
+	err = PTR_ERR(h_path.dentry);
+	if (IS_ERR(h_path.dentry))
+		goto out;
+
+	err = 0;
+	/* wh.plink dir is not monitored */
+	/* todo: is it really safe? */
+	if (d_is_positive(h_path.dentry)
+	    && d_inode(h_path.dentry) != d_inode(h_dentry)) {
+		delegated = NULL;
+		err = vfsub_unlink(h_dir, &h_path, &delegated, /*force*/0);
+		if (unlikely(err == -EWOULDBLOCK)) {
+			pr_warn("cannot retry for NFSv4 delegation"
+				" for an internal unlink\n");
+			iput(delegated);
+		}
+		dput(h_path.dentry);
+		h_path.dentry = NULL;
+		if (!err)
+			goto again;
+	}
+	if (!err && d_is_negative(h_path.dentry)) {
+		delegated = NULL;
+		err = vfsub_link(h_dentry, h_dir, &h_path, &delegated);
+		if (unlikely(err == -EWOULDBLOCK)) {
+			pr_warn("cannot retry for NFSv4 delegation"
+				" for an internal link\n");
+			iput(delegated);
+		}
+	}
+	dput(h_path.dentry);
+
+out:
+	mutex_unlock(&h_dir->i_mutex);
+	return err;
+}
+
+struct do_whplink_args {
+	int *errp;
+	struct qstr *tgt;
+	struct dentry *h_parent;
+	struct dentry *h_dentry;
+	struct au_branch *br;
+};
+
+static void call_do_whplink(void *args)
+{
+	struct do_whplink_args *a = args;
+	*a->errp = do_whplink(a->tgt, a->h_parent, a->h_dentry, a->br);
+}
+
+static int whplink(struct dentry *h_dentry, struct inode *inode,
+		   aufs_bindex_t bindex, struct au_branch *br)
+{
+	int err, wkq_err;
+	struct au_wbr *wbr;
+	struct dentry *h_parent;
+	char a[PLINK_NAME_LEN];
+	struct qstr tgtname = QSTR_INIT(a, 0);
+
+	wbr = au_sbr(inode->i_sb, bindex)->br_wbr;
+	h_parent = wbr->wbr_plink;
+	tgtname.len = plink_name(a, sizeof(a), inode, bindex);
+
+	/* always superio. */
+	if (!uid_eq(current_fsuid(), GLOBAL_ROOT_UID)) {
+		struct do_whplink_args args = {
+			.errp		= &err,
+			.tgt		= &tgtname,
+			.h_parent	= h_parent,
+			.h_dentry	= h_dentry,
+			.br		= br
+		};
+		wkq_err = au_wkq_wait(call_do_whplink, &args);
+		if (unlikely(wkq_err))
+			err = wkq_err;
+	} else
+		err = do_whplink(&tgtname, h_parent, h_dentry, br);
+
+	return err;
+}
+
+/* free a single plink */
+static void do_put_plink(struct pseudo_link *plink, int do_del)
+{
+	if (do_del)
+		hlist_del(&plink->hlist);
+	iput(plink->inode);
+	kfree(plink);
+}
+
+static void do_put_plink_rcu(struct rcu_head *rcu)
+{
+	struct pseudo_link *plink;
+
+	plink = container_of(rcu, struct pseudo_link, rcu);
+	iput(plink->inode);
+	kfree(plink);
+}
+
+/*
+ * create a new pseudo-link for @h_dentry on @bindex.
+ * the linked inode is held in aufs @inode.
+ */
+void au_plink_append(struct inode *inode, aufs_bindex_t bindex,
+		     struct dentry *h_dentry)
+{
+	struct super_block *sb;
+	struct au_sbinfo *sbinfo;
+	struct hlist_head *plink_hlist;
+	struct pseudo_link *plink, *tmp;
+	struct au_sphlhead *sphl;
+	int found, err, cnt, i;
+
+	sb = inode->i_sb;
+	sbinfo = au_sbi(sb);
+	AuDebugOn(!au_opt_test(au_mntflags(sb), PLINK));
+	AuDebugOn(au_plink_maint(sb, AuLock_NOPLM));
+
+	found = au_plink_test(inode);
+	if (found)
+		return;
+
+	i = au_plink_hash(inode->i_ino);
+	sphl = sbinfo->si_plink + i;
+	plink_hlist = &sphl->head;
+	tmp = kmalloc(sizeof(*plink), GFP_NOFS);
+	if (tmp)
+		tmp->inode = au_igrab(inode);
+	else {
+		err = -ENOMEM;
+		goto out;
+	}
+
+	spin_lock(&sphl->spin);
+	hlist_for_each_entry(plink, plink_hlist, hlist) {
+		if (plink->inode == inode) {
+			found = 1;
+			break;
+		}
+	}
+	if (!found)
+		hlist_add_head_rcu(&tmp->hlist, plink_hlist);
+	spin_unlock(&sphl->spin);
+	if (!found) {
+		cnt = au_sphl_count(sphl);
+#define msg "unexpectedly unblanced or too many pseudo-links"
+		if (cnt > AUFS_PLINK_WARN)
+			AuWarn1(msg ", %d\n", cnt);
+#undef msg
+		err = whplink(h_dentry, inode, bindex, au_sbr(sb, bindex));
+	} else {
+		do_put_plink(tmp, 0);
+		return;
+	}
+
+out:
+	if (unlikely(err)) {
+		pr_warn("err %d, damaged pseudo link.\n", err);
+		if (tmp) {
+			au_sphl_del_rcu(&tmp->hlist, sphl);
+			call_rcu(&tmp->rcu, do_put_plink_rcu);
+		}
+	}
+}
+
+/* free all plinks */
+void au_plink_put(struct super_block *sb, int verbose)
+{
+	int i, warned;
+	struct au_sbinfo *sbinfo;
+	struct hlist_head *plink_hlist;
+	struct hlist_node *tmp;
+	struct pseudo_link *plink;
+
+	SiMustWriteLock(sb);
+
+	sbinfo = au_sbi(sb);
+	AuDebugOn(!au_opt_test(au_mntflags(sb), PLINK));
+	AuDebugOn(au_plink_maint(sb, AuLock_NOPLM));
+
+	/* no spin_lock since sbinfo is write-locked */
+	warned = 0;
+	for (i = 0; i < AuPlink_NHASH; i++) {
+		plink_hlist = &sbinfo->si_plink[i].head;
+		if (!warned && verbose && !hlist_empty(plink_hlist)) {
+			pr_warn("pseudo-link is not flushed");
+			warned = 1;
+		}
+		hlist_for_each_entry_safe(plink, tmp, plink_hlist, hlist)
+			do_put_plink(plink, 0);
+		INIT_HLIST_HEAD(plink_hlist);
+	}
+}
+
+void au_plink_clean(struct super_block *sb, int verbose)
+{
+	struct dentry *root;
+
+	root = sb->s_root;
+	aufs_write_lock(root);
+	if (au_opt_test(au_mntflags(sb), PLINK))
+		au_plink_put(sb, verbose);
+	aufs_write_unlock(root);
+}
+
+static int au_plink_do_half_refresh(struct inode *inode, aufs_bindex_t br_id)
+{
+	int do_put;
+	aufs_bindex_t bstart, bend, bindex;
+
+	do_put = 0;
+	bstart = au_ibstart(inode);
+	bend = au_ibend(inode);
+	if (bstart >= 0) {
+		for (bindex = bstart; bindex <= bend; bindex++) {
+			if (!au_h_iptr(inode, bindex)
+			    || au_ii_br_id(inode, bindex) != br_id)
+				continue;
+			au_set_h_iptr(inode, bindex, NULL, 0);
+			do_put = 1;
+			break;
+		}
+		if (do_put)
+			for (bindex = bstart; bindex <= bend; bindex++)
+				if (au_h_iptr(inode, bindex)) {
+					do_put = 0;
+					break;
+				}
+	} else
+		do_put = 1;
+
+	return do_put;
+}
+
+/* free the plinks on a branch specified by @br_id */
+void au_plink_half_refresh(struct super_block *sb, aufs_bindex_t br_id)
+{
+	struct au_sbinfo *sbinfo;
+	struct hlist_head *plink_hlist;
+	struct hlist_node *tmp;
+	struct pseudo_link *plink;
+	struct inode *inode;
+	int i, do_put;
+
+	SiMustWriteLock(sb);
+
+	sbinfo = au_sbi(sb);
+	AuDebugOn(!au_opt_test(au_mntflags(sb), PLINK));
+	AuDebugOn(au_plink_maint(sb, AuLock_NOPLM));
+
+	/* no spin_lock since sbinfo is write-locked */
+	for (i = 0; i < AuPlink_NHASH; i++) {
+		plink_hlist = &sbinfo->si_plink[i].head;
+		hlist_for_each_entry_safe(plink, tmp, plink_hlist, hlist) {
+			inode = au_igrab(plink->inode);
+			ii_write_lock_child(inode);
+			do_put = au_plink_do_half_refresh(inode, br_id);
+			if (do_put)
+				do_put_plink(plink, 1);
+			ii_write_unlock(inode);
+			iput(inode);
+		}
+	}
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/fs/aufs/poll.c
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+ *
+ * This program, aufs is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * poll operation
+ * There is only one filesystem which implements ->poll operation, currently.
+ */
+
+#include "aufs.h"
+
+unsigned int aufs_poll(struct file *file, poll_table *wait)
+{
+	unsigned int mask;
+	int err;
+	struct file *h_file;
+	struct super_block *sb;
+
+	/* We should pretend an error happened. */
+	mask = POLLERR /* | POLLIN | POLLOUT */;
+	sb = file->f_path.dentry->d_sb;
+	si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW);
+
+	h_file = au_read_pre(file, /*keep_fi*/0);
+	err = PTR_ERR(h_file);
+	if (IS_ERR(h_file))
+		goto out;
+
+	/* it is not an error if h_file has no operation */
+	mask = DEFAULT_POLLMASK;
+	if (h_file->f_op->poll)
+		mask = h_file->f_op->poll(h_file, wait);
+	fput(h_file); /* instead of au_read_post() */
+
+out:
+	si_read_unlock(sb);
+	AuTraceErr((int)mask);
+	return mask;
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/fs/aufs/posix_acl.c
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2014-2015 Junjiro R. Okajima
+ *
+ * This program, aufs is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * posix acl operations
+ */
+
+#include <linux/fs.h>
+#include <linux/posix_acl.h>
+#include "aufs.h"
+
+struct posix_acl *aufs_get_acl(struct inode *inode, int type)
+{
+	struct posix_acl *acl;
+	int err;
+	aufs_bindex_t bindex;
+	struct inode *h_inode;
+	struct super_block *sb;
+
+	acl = NULL;
+	sb = inode->i_sb;
+	si_read_lock(sb, AuLock_FLUSH);
+	ii_read_lock_child(inode);
+	if (!(sb->s_flags & MS_POSIXACL))
+		goto out;
+
+	bindex = au_ibstart(inode);
+	h_inode = au_h_iptr(inode, bindex);
+	if (unlikely(!h_inode
+		     || ((h_inode->i_mode & S_IFMT)
+			 != (inode->i_mode & S_IFMT)))) {
+		err = au_busy_or_stale();
+		acl = ERR_PTR(err);
+		goto out;
+	}
+
+	/* always topmost only */
+	acl = get_acl(h_inode, type);
+
+out:
+	ii_read_unlock(inode);
+	si_read_unlock(sb);
+
+	AuTraceErrPtr(acl);
+	return acl;
+}
+
+int aufs_set_acl(struct inode *inode, struct posix_acl *acl, int type)
+{
+	int err;
+	ssize_t ssz;
+	struct dentry *dentry;
+	struct au_srxattr arg = {
+		.type = AU_ACL_SET,
+		.u.acl_set = {
+			.acl	= acl,
+			.type	= type
+		},
+	};
+
+	mutex_lock(&inode->i_mutex);
+	if (inode->i_ino == AUFS_ROOT_INO)
+		dentry = dget(inode->i_sb->s_root);
+	else {
+		dentry = d_find_alias(inode);
+		if (!dentry)
+			dentry = d_find_any_alias(inode);
+		if (!dentry) {
+			pr_warn("cannot handle this inode, "
+				"please report to aufs-users ML\n");
+			err = -ENOENT;
+			goto out;
+		}
+	}
+
+	ssz = au_srxattr(dentry, &arg);
+	dput(dentry);
+	err = ssz;
+	if (ssz >= 0)
+		err = 0;
+
+out:
+	mutex_unlock(&inode->i_mutex);
+	return err;
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/fs/aufs/procfs.c
@@ -0,0 +1,169 @@
+/*
+ * Copyright (C) 2010-2015 Junjiro R. Okajima
+ *
+ * This program, aufs is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * procfs interfaces
+ */
+
+#include <linux/proc_fs.h>
+#include "aufs.h"
+
+static int au_procfs_plm_release(struct inode *inode, struct file *file)
+{
+	struct au_sbinfo *sbinfo;
+
+	sbinfo = file->private_data;
+	if (sbinfo) {
+		au_plink_maint_leave(sbinfo);
+		kobject_put(&sbinfo->si_kobj);
+	}
+
+	return 0;
+}
+
+static void au_procfs_plm_write_clean(struct file *file)
+{
+	struct au_sbinfo *sbinfo;
+
+	sbinfo = file->private_data;
+	if (sbinfo)
+		au_plink_clean(sbinfo->si_sb, /*verbose*/0);
+}
+
+static int au_procfs_plm_write_si(struct file *file, unsigned long id)
+{
+	int err;
+	struct super_block *sb;
+	struct au_sbinfo *sbinfo;
+
+	err = -EBUSY;
+	if (unlikely(file->private_data))
+		goto out;
+
+	sb = NULL;
+	/* don't use au_sbilist_lock() here */
+	spin_lock(&au_sbilist.spin);
+	list_for_each_entry(sbinfo, &au_sbilist.head, si_list)
+		if (id == sysaufs_si_id(sbinfo)) {
+			kobject_get(&sbinfo->si_kobj);
+			sb = sbinfo->si_sb;
+			break;
+		}
+	spin_unlock(&au_sbilist.spin);
+
+	err = -EINVAL;
+	if (unlikely(!sb))
+		goto out;
+
+	err = au_plink_maint_enter(sb);
+	if (!err)
+		/* keep kobject_get() */
+		file->private_data = sbinfo;
+	else
+		kobject_put(&sbinfo->si_kobj);
+out:
+	return err;
+}
+
+/*
+ * Accept a valid "si=xxxx" only.
+ * Once it is accepted successfully, accept "clean" too.
+ */
+static ssize_t au_procfs_plm_write(struct file *file, const char __user *ubuf,
+				   size_t count, loff_t *ppos)
+{
+	ssize_t err;
+	unsigned long id;
+	/* last newline is allowed */
+	char buf[3 + sizeof(unsigned long) * 2 + 1];
+
+	err = -EACCES;
+	if (unlikely(!capable(CAP_SYS_ADMIN)))
+		goto out;
+
+	err = -EINVAL;
+	if (unlikely(count > sizeof(buf)))
+		goto out;
+
+	err = copy_from_user(buf, ubuf, count);
+	if (unlikely(err)) {
+		err = -EFAULT;
+		goto out;
+	}
+	buf[count] = 0;
+
+	err = -EINVAL;
+	if (!strcmp("clean", buf)) {
+		au_procfs_plm_write_clean(file);
+		goto out_success;
+	} else if (unlikely(strncmp("si=", buf, 3)))
+		goto out;
+
+	err = kstrtoul(buf + 3, 16, &id);
+	if (unlikely(err))
+		goto out;
+
+	err = au_procfs_plm_write_si(file, id);
+	if (unlikely(err))
+		goto out;
+
+out_success:
+	err = count; /* success */
+out:
+	return err;
+}
+
+static const struct file_operations au_procfs_plm_fop = {
+	.write		= au_procfs_plm_write,
+	.release	= au_procfs_plm_release,
+	.owner		= THIS_MODULE
+};
+
+/* ---------------------------------------------------------------------- */
+
+static struct proc_dir_entry *au_procfs_dir;
+
+void au_procfs_fin(void)
+{
+	remove_proc_entry(AUFS_PLINK_MAINT_NAME, au_procfs_dir);
+	remove_proc_entry(AUFS_PLINK_MAINT_DIR, NULL);
+}
+
+int __init au_procfs_init(void)
+{
+	int err;
+	struct proc_dir_entry *entry;
+
+	err = -ENOMEM;
+	au_procfs_dir = proc_mkdir(AUFS_PLINK_MAINT_DIR, NULL);
+	if (unlikely(!au_procfs_dir))
+		goto out;
+
+	entry = proc_create(AUFS_PLINK_MAINT_NAME, S_IFREG | S_IWUSR,
+			    au_procfs_dir, &au_procfs_plm_fop);
+	if (unlikely(!entry))
+		goto out_dir;
+
+	err = 0;
+	goto out; /* success */
+
+
+out_dir:
+	remove_proc_entry(AUFS_PLINK_MAINT_DIR, NULL);
+out:
+	return err;
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/fs/aufs/rdu.c
@@ -0,0 +1,388 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+ *
+ * This program, aufs is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * readdir in userspace.
+ */
+
+#include <linux/compat.h>
+#include <linux/fs_stack.h>
+#include <linux/security.h>
+#include "aufs.h"
+
+/* bits for struct aufs_rdu.flags */
+#define	AuRdu_CALLED	1
+#define	AuRdu_CONT	(1 << 1)
+#define	AuRdu_FULL	(1 << 2)
+#define au_ftest_rdu(flags, name)	((flags) & AuRdu_##name)
+#define au_fset_rdu(flags, name) \
+	do { (flags) |= AuRdu_##name; } while (0)
+#define au_fclr_rdu(flags, name) \
+	do { (flags) &= ~AuRdu_##name; } while (0)
+
+struct au_rdu_arg {
+	struct dir_context		ctx;
+	struct aufs_rdu			*rdu;
+	union au_rdu_ent_ul		ent;
+	unsigned long			end;
+
+	struct super_block		*sb;
+	int				err;
+};
+
+static int au_rdu_fill(struct dir_context *ctx, const char *name, int nlen,
+		       loff_t offset, u64 h_ino, unsigned int d_type)
+{
+	int err, len;
+	struct au_rdu_arg *arg = container_of(ctx, struct au_rdu_arg, ctx);
+	struct aufs_rdu *rdu = arg->rdu;
+	struct au_rdu_ent ent;
+
+	err = 0;
+	arg->err = 0;
+	au_fset_rdu(rdu->cookie.flags, CALLED);
+	len = au_rdu_len(nlen);
+	if (arg->ent.ul + len  < arg->end) {
+		ent.ino = h_ino;
+		ent.bindex = rdu->cookie.bindex;
+		ent.type = d_type;
+		ent.nlen = nlen;
+		if (unlikely(nlen > AUFS_MAX_NAMELEN))
+			ent.type = DT_UNKNOWN;
+
+		/* unnecessary to support mmap_sem since this is a dir */
+		err = -EFAULT;
+		if (copy_to_user(arg->ent.e, &ent, sizeof(ent)))
+			goto out;
+		if (copy_to_user(arg->ent.e->name, name, nlen))
+			goto out;
+		/* the terminating NULL */
+		if (__put_user(0, arg->ent.e->name + nlen))
+			goto out;
+		err = 0;
+		/* AuDbg("%p, %.*s\n", arg->ent.p, nlen, name); */
+		arg->ent.ul += len;
+		rdu->rent++;
+	} else {
+		err = -EFAULT;
+		au_fset_rdu(rdu->cookie.flags, FULL);
+		rdu->full = 1;
+		rdu->tail = arg->ent;
+	}
+
+out:
+	/* AuTraceErr(err); */
+	return err;
+}
+
+static int au_rdu_do(struct file *h_file, struct au_rdu_arg *arg)
+{
+	int err;
+	loff_t offset;
+	struct au_rdu_cookie *cookie = &arg->rdu->cookie;
+
+	/* we don't have to care (FMODE_32BITHASH | FMODE_64BITHASH) for ext4 */
+	offset = vfsub_llseek(h_file, cookie->h_pos, SEEK_SET);
+	err = offset;
+	if (unlikely(offset != cookie->h_pos))
+		goto out;
+
+	err = 0;
+	do {
+		arg->err = 0;
+		au_fclr_rdu(cookie->flags, CALLED);
+		/* smp_mb(); */
+		err = vfsub_iterate_dir(h_file, &arg->ctx);
+		if (err >= 0)
+			err = arg->err;
+	} while (!err
+		 && au_ftest_rdu(cookie->flags, CALLED)
+		 && !au_ftest_rdu(cookie->flags, FULL));
+	cookie->h_pos = h_file->f_pos;
+
+out:
+	AuTraceErr(err);
+	return err;
+}
+
+static int au_rdu(struct file *file, struct aufs_rdu *rdu)
+{
+	int err;
+	aufs_bindex_t bend;
+	struct au_rdu_arg arg = {
+		.ctx = {
+			.actor = au_rdu_fill
+		}
+	};
+	struct dentry *dentry;
+	struct inode *inode;
+	struct file *h_file;
+	struct au_rdu_cookie *cookie = &rdu->cookie;
+
+	err = !access_ok(VERIFY_WRITE, rdu->ent.e, rdu->sz);
+	if (unlikely(err)) {
+		err = -EFAULT;
+		AuTraceErr(err);
+		goto out;
+	}
+	rdu->rent = 0;
+	rdu->tail = rdu->ent;
+	rdu->full = 0;
+	arg.rdu = rdu;
+	arg.ent = rdu->ent;
+	arg.end = arg.ent.ul;
+	arg.end += rdu->sz;
+
+	err = -ENOTDIR;
+	if (unlikely(!file->f_op->iterate))
+		goto out;
+
+	err = security_file_permission(file, MAY_READ);
+	AuTraceErr(err);
+	if (unlikely(err))
+		goto out;
+
+	dentry = file->f_path.dentry;
+	inode = d_inode(dentry);
+#if 1
+	mutex_lock(&inode->i_mutex);
+#else
+	err = mutex_lock_killable(&inode->i_mutex);
+	AuTraceErr(err);
+	if (unlikely(err))
+		goto out;
+#endif
+
+	arg.sb = inode->i_sb;
+	err = si_read_lock(arg.sb, AuLock_FLUSH | AuLock_NOPLM);
+	if (unlikely(err))
+		goto out_mtx;
+	err = au_alive_dir(dentry);
+	if (unlikely(err))
+		goto out_si;
+	/* todo: reval? */
+	fi_read_lock(file);
+
+	err = -EAGAIN;
+	if (unlikely(au_ftest_rdu(cookie->flags, CONT)
+		     && cookie->generation != au_figen(file)))
+		goto out_unlock;
+
+	err = 0;
+	if (!rdu->blk) {
+		rdu->blk = au_sbi(arg.sb)->si_rdblk;
+		if (!rdu->blk)
+			rdu->blk = au_dir_size(file, /*dentry*/NULL);
+	}
+	bend = au_fbstart(file);
+	if (cookie->bindex < bend)
+		cookie->bindex = bend;
+	bend = au_fbend_dir(file);
+	/* AuDbg("b%d, b%d\n", cookie->bindex, bend); */
+	for (; !err && cookie->bindex <= bend;
+	     cookie->bindex++, cookie->h_pos = 0) {
+		h_file = au_hf_dir(file, cookie->bindex);
+		if (!h_file)
+			continue;
+
+		au_fclr_rdu(cookie->flags, FULL);
+		err = au_rdu_do(h_file, &arg);
+		AuTraceErr(err);
+		if (unlikely(au_ftest_rdu(cookie->flags, FULL) || err))
+			break;
+	}
+	AuDbg("rent %llu\n", rdu->rent);
+
+	if (!err && !au_ftest_rdu(cookie->flags, CONT)) {
+		rdu->shwh = !!au_opt_test(au_sbi(arg.sb)->si_mntflags, SHWH);
+		au_fset_rdu(cookie->flags, CONT);
+		cookie->generation = au_figen(file);
+	}
+
+	ii_read_lock_child(inode);
+	fsstack_copy_attr_atime(inode, au_h_iptr(inode, au_ibstart(inode)));
+	ii_read_unlock(inode);
+
+out_unlock:
+	fi_read_unlock(file);
+out_si:
+	si_read_unlock(arg.sb);
+out_mtx:
+	mutex_unlock(&inode->i_mutex);
+out:
+	AuTraceErr(err);
+	return err;
+}
+
+static int au_rdu_ino(struct file *file, struct aufs_rdu *rdu)
+{
+	int err;
+	ino_t ino;
+	unsigned long long nent;
+	union au_rdu_ent_ul *u;
+	struct au_rdu_ent ent;
+	struct super_block *sb;
+
+	err = 0;
+	nent = rdu->nent;
+	u = &rdu->ent;
+	sb = file->f_path.dentry->d_sb;
+	si_read_lock(sb, AuLock_FLUSH);
+	while (nent-- > 0) {
+		/* unnecessary to support mmap_sem since this is a dir */
+		err = copy_from_user(&ent, u->e, sizeof(ent));
+		if (!err)
+			err = !access_ok(VERIFY_WRITE, &u->e->ino, sizeof(ino));
+		if (unlikely(err)) {
+			err = -EFAULT;
+			AuTraceErr(err);
+			break;
+		}
+
+		/* AuDbg("b%d, i%llu\n", ent.bindex, ent.ino); */
+		if (!ent.wh)
+			err = au_ino(sb, ent.bindex, ent.ino, ent.type, &ino);
+		else
+			err = au_wh_ino(sb, ent.bindex, ent.ino, ent.type,
+					&ino);
+		if (unlikely(err)) {
+			AuTraceErr(err);
+			break;
+		}
+
+		err = __put_user(ino, &u->e->ino);
+		if (unlikely(err)) {
+			err = -EFAULT;
+			AuTraceErr(err);
+			break;
+		}
+		u->ul += au_rdu_len(ent.nlen);
+	}
+	si_read_unlock(sb);
+
+	return err;
+}
+
+/* ---------------------------------------------------------------------- */
+
+static int au_rdu_verify(struct aufs_rdu *rdu)
+{
+	AuDbg("rdu{%llu, %p, %u | %u | %llu, %u, %u | "
+	      "%llu, b%d, 0x%x, g%u}\n",
+	      rdu->sz, rdu->ent.e, rdu->verify[AufsCtlRduV_SZ],
+	      rdu->blk,
+	      rdu->rent, rdu->shwh, rdu->full,
+	      rdu->cookie.h_pos, rdu->cookie.bindex, rdu->cookie.flags,
+	      rdu->cookie.generation);
+
+	if (rdu->verify[AufsCtlRduV_SZ] == sizeof(*rdu))
+		return 0;
+
+	AuDbg("%u:%u\n",
+	      rdu->verify[AufsCtlRduV_SZ], (unsigned int)sizeof(*rdu));
+	return -EINVAL;
+}
+
+long au_rdu_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+	long err, e;
+	struct aufs_rdu rdu;
+	void __user *p = (void __user *)arg;
+
+	err = copy_from_user(&rdu, p, sizeof(rdu));
+	if (unlikely(err)) {
+		err = -EFAULT;
+		AuTraceErr(err);
+		goto out;
+	}
+	err = au_rdu_verify(&rdu);
+	if (unlikely(err))
+		goto out;
+
+	switch (cmd) {
+	case AUFS_CTL_RDU:
+		err = au_rdu(file, &rdu);
+		if (unlikely(err))
+			break;
+
+		e = copy_to_user(p, &rdu, sizeof(rdu));
+		if (unlikely(e)) {
+			err = -EFAULT;
+			AuTraceErr(err);
+		}
+		break;
+	case AUFS_CTL_RDU_INO:
+		err = au_rdu_ino(file, &rdu);
+		break;
+
+	default:
+		/* err = -ENOTTY; */
+		err = -EINVAL;
+	}
+
+out:
+	AuTraceErr(err);
+	return err;
+}
+
+#ifdef CONFIG_COMPAT
+long au_rdu_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+	long err, e;
+	struct aufs_rdu rdu;
+	void __user *p = compat_ptr(arg);
+
+	/* todo: get_user()? */
+	err = copy_from_user(&rdu, p, sizeof(rdu));
+	if (unlikely(err)) {
+		err = -EFAULT;
+		AuTraceErr(err);
+		goto out;
+	}
+	rdu.ent.e = compat_ptr(rdu.ent.ul);
+	err = au_rdu_verify(&rdu);
+	if (unlikely(err))
+		goto out;
+
+	switch (cmd) {
+	case AUFS_CTL_RDU:
+		err = au_rdu(file, &rdu);
+		if (unlikely(err))
+			break;
+
+		rdu.ent.ul = ptr_to_compat(rdu.ent.e);
+		rdu.tail.ul = ptr_to_compat(rdu.tail.e);
+		e = copy_to_user(p, &rdu, sizeof(rdu));
+		if (unlikely(e)) {
+			err = -EFAULT;
+			AuTraceErr(err);
+		}
+		break;
+	case AUFS_CTL_RDU_INO:
+		err = au_rdu_ino(file, &rdu);
+		break;
+
+	default:
+		/* err = -ENOTTY; */
+		err = -EINVAL;
+	}
+
+out:
+	AuTraceErr(err);
+	return err;
+}
+#endif
--- /dev/null
+++ zfcpdump-kernel-4.4/fs/aufs/rwsem.h
@@ -0,0 +1,191 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+ *
+ * This program, aufs is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * simple read-write semaphore wrappers
+ */
+
+#ifndef __AUFS_RWSEM_H__
+#define __AUFS_RWSEM_H__
+
+#ifdef __KERNEL__
+
+#include "debug.h"
+
+struct au_rwsem {
+	struct rw_semaphore	rwsem;
+#ifdef CONFIG_AUFS_DEBUG
+	/* just for debugging, not almighty counter */
+	atomic_t		rcnt, wcnt;
+#endif
+};
+
+#ifdef CONFIG_AUFS_DEBUG
+#define AuDbgCntInit(rw) do { \
+	atomic_set(&(rw)->rcnt, 0); \
+	atomic_set(&(rw)->wcnt, 0); \
+	smp_mb(); /* atomic set */ \
+} while (0)
+
+#define AuDbgRcntInc(rw)	atomic_inc(&(rw)->rcnt)
+#define AuDbgRcntDec(rw)	WARN_ON(atomic_dec_return(&(rw)->rcnt) < 0)
+#define AuDbgWcntInc(rw)	atomic_inc(&(rw)->wcnt)
+#define AuDbgWcntDec(rw)	WARN_ON(atomic_dec_return(&(rw)->wcnt) < 0)
+#else
+#define AuDbgCntInit(rw)	do {} while (0)
+#define AuDbgRcntInc(rw)	do {} while (0)
+#define AuDbgRcntDec(rw)	do {} while (0)
+#define AuDbgWcntInc(rw)	do {} while (0)
+#define AuDbgWcntDec(rw)	do {} while (0)
+#endif /* CONFIG_AUFS_DEBUG */
+
+/* to debug easier, do not make them inlined functions */
+#define AuRwMustNoWaiters(rw)	AuDebugOn(!list_empty(&(rw)->rwsem.wait_list))
+/* rwsem_is_locked() is unusable */
+#define AuRwMustReadLock(rw)	AuDebugOn(atomic_read(&(rw)->rcnt) <= 0)
+#define AuRwMustWriteLock(rw)	AuDebugOn(atomic_read(&(rw)->wcnt) <= 0)
+#define AuRwMustAnyLock(rw)	AuDebugOn(atomic_read(&(rw)->rcnt) <= 0 \
+					&& atomic_read(&(rw)->wcnt) <= 0)
+#define AuRwDestroy(rw)		AuDebugOn(atomic_read(&(rw)->rcnt) \
+					|| atomic_read(&(rw)->wcnt))
+
+#define au_rw_class(rw, key)	lockdep_set_class(&(rw)->rwsem, key)
+
+static inline void au_rw_init(struct au_rwsem *rw)
+{
+	AuDbgCntInit(rw);
+	init_rwsem(&rw->rwsem);
+}
+
+static inline void au_rw_init_wlock(struct au_rwsem *rw)
+{
+	au_rw_init(rw);
+	down_write(&rw->rwsem);
+	AuDbgWcntInc(rw);
+}
+
+static inline void au_rw_init_wlock_nested(struct au_rwsem *rw,
+					   unsigned int lsc)
+{
+	au_rw_init(rw);
+	down_write_nested(&rw->rwsem, lsc);
+	AuDbgWcntInc(rw);
+}
+
+static inline void au_rw_read_lock(struct au_rwsem *rw)
+{
+	down_read(&rw->rwsem);
+	AuDbgRcntInc(rw);
+}
+
+static inline void au_rw_read_lock_nested(struct au_rwsem *rw, unsigned int lsc)
+{
+	down_read_nested(&rw->rwsem, lsc);
+	AuDbgRcntInc(rw);
+}
+
+static inline void au_rw_read_unlock(struct au_rwsem *rw)
+{
+	AuRwMustReadLock(rw);
+	AuDbgRcntDec(rw);
+	up_read(&rw->rwsem);
+}
+
+static inline void au_rw_dgrade_lock(struct au_rwsem *rw)
+{
+	AuRwMustWriteLock(rw);
+	AuDbgRcntInc(rw);
+	AuDbgWcntDec(rw);
+	downgrade_write(&rw->rwsem);
+}
+
+static inline void au_rw_write_lock(struct au_rwsem *rw)
+{
+	down_write(&rw->rwsem);
+	AuDbgWcntInc(rw);
+}
+
+static inline void au_rw_write_lock_nested(struct au_rwsem *rw,
+					   unsigned int lsc)
+{
+	down_write_nested(&rw->rwsem, lsc);
+	AuDbgWcntInc(rw);
+}
+
+static inline void au_rw_write_unlock(struct au_rwsem *rw)
+{
+	AuRwMustWriteLock(rw);
+	AuDbgWcntDec(rw);
+	up_write(&rw->rwsem);
+}
+
+/* why is not _nested version defined */
+static inline int au_rw_read_trylock(struct au_rwsem *rw)
+{
+	int ret;
+
+	ret = down_read_trylock(&rw->rwsem);
+	if (ret)
+		AuDbgRcntInc(rw);
+	return ret;
+}
+
+static inline int au_rw_write_trylock(struct au_rwsem *rw)
+{
+	int ret;
+
+	ret = down_write_trylock(&rw->rwsem);
+	if (ret)
+		AuDbgWcntInc(rw);
+	return ret;
+}
+
+#undef AuDbgCntInit
+#undef AuDbgRcntInc
+#undef AuDbgRcntDec
+#undef AuDbgWcntInc
+#undef AuDbgWcntDec
+
+#define AuSimpleLockRwsemFuncs(prefix, param, rwsem) \
+static inline void prefix##_read_lock(param) \
+{ au_rw_read_lock(rwsem); } \
+static inline void prefix##_write_lock(param) \
+{ au_rw_write_lock(rwsem); } \
+static inline int prefix##_read_trylock(param) \
+{ return au_rw_read_trylock(rwsem); } \
+static inline int prefix##_write_trylock(param) \
+{ return au_rw_write_trylock(rwsem); }
+/* why is not _nested version defined */
+/* static inline void prefix##_read_trylock_nested(param, lsc)
+{ au_rw_read_trylock_nested(rwsem, lsc)); }
+static inline void prefix##_write_trylock_nestd(param, lsc)
+{ au_rw_write_trylock_nested(rwsem, lsc); } */
+
+#define AuSimpleUnlockRwsemFuncs(prefix, param, rwsem) \
+static inline void prefix##_read_unlock(param) \
+{ au_rw_read_unlock(rwsem); } \
+static inline void prefix##_write_unlock(param) \
+{ au_rw_write_unlock(rwsem); } \
+static inline void prefix##_downgrade_lock(param) \
+{ au_rw_dgrade_lock(rwsem); }
+
+#define AuSimpleRwsemFuncs(prefix, param, rwsem) \
+	AuSimpleLockRwsemFuncs(prefix, param, rwsem) \
+	AuSimpleUnlockRwsemFuncs(prefix, param, rwsem)
+
+#endif /* __KERNEL__ */
+#endif /* __AUFS_RWSEM_H__ */
--- /dev/null
+++ zfcpdump-kernel-4.4/fs/aufs/sbinfo.c
@@ -0,0 +1,366 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+ *
+ * This program, aufs is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * superblock private data
+ */
+
+#include "aufs.h"
+
+/*
+ * they are necessary regardless sysfs is disabled.
+ */
+void au_si_free(struct kobject *kobj)
+{
+	int i;
+	struct au_sbinfo *sbinfo;
+	char *locked __maybe_unused; /* debug only */
+
+	sbinfo = container_of(kobj, struct au_sbinfo, si_kobj);
+	for (i = 0; i < AuPlink_NHASH; i++)
+		AuDebugOn(!hlist_empty(&sbinfo->si_plink[i].head));
+	AuDebugOn(atomic_read(&sbinfo->si_nowait.nw_len));
+
+	AuDebugOn(!hlist_empty(&sbinfo->si_symlink.head));
+
+	au_rw_write_lock(&sbinfo->si_rwsem);
+	au_br_free(sbinfo);
+	au_rw_write_unlock(&sbinfo->si_rwsem);
+
+	AuDebugOn(radix_tree_gang_lookup
+		  (&sbinfo->au_si_pid.tree, (void **)&locked,
+		   /*first_index*/PID_MAX_DEFAULT - 1,
+		   /*max_items*/sizeof(locked)/sizeof(*locked)));
+
+	kfree(sbinfo->si_branch);
+	kfree(sbinfo->au_si_pid.bitmap);
+	mutex_destroy(&sbinfo->si_xib_mtx);
+	AuRwDestroy(&sbinfo->si_rwsem);
+
+	kfree(sbinfo);
+}
+
+int au_si_alloc(struct super_block *sb)
+{
+	int err, i;
+	struct au_sbinfo *sbinfo;
+	static struct lock_class_key aufs_si;
+
+	err = -ENOMEM;
+	sbinfo = kzalloc(sizeof(*sbinfo), GFP_NOFS);
+	if (unlikely(!sbinfo))
+		goto out;
+
+	BUILD_BUG_ON(sizeof(unsigned long) !=
+		     sizeof(*sbinfo->au_si_pid.bitmap));
+	sbinfo->au_si_pid.bitmap = kcalloc(BITS_TO_LONGS(PID_MAX_DEFAULT),
+					sizeof(*sbinfo->au_si_pid.bitmap),
+					GFP_NOFS);
+	if (unlikely(!sbinfo->au_si_pid.bitmap))
+		goto out_sbinfo;
+
+	/* will be reallocated separately */
+	sbinfo->si_branch = kzalloc(sizeof(*sbinfo->si_branch), GFP_NOFS);
+	if (unlikely(!sbinfo->si_branch))
+		goto out_pidmap;
+
+	err = sysaufs_si_init(sbinfo);
+	if (unlikely(err))
+		goto out_br;
+
+	au_nwt_init(&sbinfo->si_nowait);
+	au_rw_init_wlock(&sbinfo->si_rwsem);
+	au_rw_class(&sbinfo->si_rwsem, &aufs_si);
+	spin_lock_init(&sbinfo->au_si_pid.tree_lock);
+	INIT_RADIX_TREE(&sbinfo->au_si_pid.tree, GFP_ATOMIC | __GFP_NOFAIL);
+
+	atomic_long_set(&sbinfo->si_ninodes, 0);
+	atomic_long_set(&sbinfo->si_nfiles, 0);
+
+	sbinfo->si_bend = -1;
+	sbinfo->si_last_br_id = AUFS_BRANCH_MAX / 2;
+
+	sbinfo->si_wbr_copyup = AuWbrCopyup_Def;
+	sbinfo->si_wbr_create = AuWbrCreate_Def;
+	sbinfo->si_wbr_copyup_ops = au_wbr_copyup_ops + sbinfo->si_wbr_copyup;
+	sbinfo->si_wbr_create_ops = au_wbr_create_ops + sbinfo->si_wbr_create;
+
+	au_fhsm_init(sbinfo);
+
+	sbinfo->si_mntflags = au_opts_plink(AuOpt_Def);
+
+	au_sphl_init(&sbinfo->si_symlink);
+
+	sbinfo->si_xino_jiffy = jiffies;
+	sbinfo->si_xino_expire
+		= msecs_to_jiffies(AUFS_XINO_DEF_SEC * MSEC_PER_SEC);
+	mutex_init(&sbinfo->si_xib_mtx);
+	sbinfo->si_xino_brid = -1;
+	/* leave si_xib_last_pindex and si_xib_next_bit */
+
+	au_sphl_init(&sbinfo->si_aopen);
+
+	sbinfo->si_rdcache = msecs_to_jiffies(AUFS_RDCACHE_DEF * MSEC_PER_SEC);
+	sbinfo->si_rdblk = AUFS_RDBLK_DEF;
+	sbinfo->si_rdhash = AUFS_RDHASH_DEF;
+	sbinfo->si_dirwh = AUFS_DIRWH_DEF;
+
+	for (i = 0; i < AuPlink_NHASH; i++)
+		au_sphl_init(sbinfo->si_plink + i);
+	init_waitqueue_head(&sbinfo->si_plink_wq);
+	spin_lock_init(&sbinfo->si_plink_maint_lock);
+
+	au_sphl_init(&sbinfo->si_files);
+
+	/* with getattr by default */
+	sbinfo->si_iop_array = aufs_iop;
+
+	/* leave other members for sysaufs and si_mnt. */
+	sbinfo->si_sb = sb;
+	sb->s_fs_info = sbinfo;
+	si_pid_set(sb);
+	return 0; /* success */
+
+out_br:
+	kfree(sbinfo->si_branch);
+out_pidmap:
+	kfree(sbinfo->au_si_pid.bitmap);
+out_sbinfo:
+	kfree(sbinfo);
+out:
+	return err;
+}
+
+int au_sbr_realloc(struct au_sbinfo *sbinfo, int nbr)
+{
+	int err, sz;
+	struct au_branch **brp;
+
+	AuRwMustWriteLock(&sbinfo->si_rwsem);
+
+	err = -ENOMEM;
+	sz = sizeof(*brp) * (sbinfo->si_bend + 1);
+	if (unlikely(!sz))
+		sz = sizeof(*brp);
+	brp = au_kzrealloc(sbinfo->si_branch, sz, sizeof(*brp) * nbr, GFP_NOFS);
+	if (brp) {
+		sbinfo->si_branch = brp;
+		err = 0;
+	}
+
+	return err;
+}
+
+/* ---------------------------------------------------------------------- */
+
+unsigned int au_sigen_inc(struct super_block *sb)
+{
+	unsigned int gen;
+	struct inode *inode;
+
+	SiMustWriteLock(sb);
+
+	gen = ++au_sbi(sb)->si_generation;
+	au_update_digen(sb->s_root);
+	inode = d_inode(sb->s_root);
+	au_update_iigen(inode, /*half*/0);
+	inode->i_version++;
+	return gen;
+}
+
+aufs_bindex_t au_new_br_id(struct super_block *sb)
+{
+	aufs_bindex_t br_id;
+	int i;
+	struct au_sbinfo *sbinfo;
+
+	SiMustWriteLock(sb);
+
+	sbinfo = au_sbi(sb);
+	for (i = 0; i <= AUFS_BRANCH_MAX; i++) {
+		br_id = ++sbinfo->si_last_br_id;
+		AuDebugOn(br_id < 0);
+		if (br_id && au_br_index(sb, br_id) < 0)
+			return br_id;
+	}
+
+	return -1;
+}
+
+/* ---------------------------------------------------------------------- */
+
+/* it is ok that new 'nwt' tasks are appended while we are sleeping */
+int si_read_lock(struct super_block *sb, int flags)
+{
+	int err;
+
+	err = 0;
+	if (au_ftest_lock(flags, FLUSH))
+		au_nwt_flush(&au_sbi(sb)->si_nowait);
+
+	si_noflush_read_lock(sb);
+	err = au_plink_maint(sb, flags);
+	if (unlikely(err))
+		si_read_unlock(sb);
+
+	return err;
+}
+
+int si_write_lock(struct super_block *sb, int flags)
+{
+	int err;
+
+	if (au_ftest_lock(flags, FLUSH))
+		au_nwt_flush(&au_sbi(sb)->si_nowait);
+
+	si_noflush_write_lock(sb);
+	err = au_plink_maint(sb, flags);
+	if (unlikely(err))
+		si_write_unlock(sb);
+
+	return err;
+}
+
+/* dentry and super_block lock. call at entry point */
+int aufs_read_lock(struct dentry *dentry, int flags)
+{
+	int err;
+	struct super_block *sb;
+
+	sb = dentry->d_sb;
+	err = si_read_lock(sb, flags);
+	if (unlikely(err))
+		goto out;
+
+	if (au_ftest_lock(flags, DW))
+		di_write_lock_child(dentry);
+	else
+		di_read_lock_child(dentry, flags);
+
+	if (au_ftest_lock(flags, GEN)) {
+		err = au_digen_test(dentry, au_sigen(sb));
+		if (!au_opt_test(au_mntflags(sb), UDBA_NONE))
+			AuDebugOn(!err && au_dbrange_test(dentry));
+		else if (!err)
+			err = au_dbrange_test(dentry);
+		if (unlikely(err))
+			aufs_read_unlock(dentry, flags);
+	}
+
+out:
+	return err;
+}
+
+void aufs_read_unlock(struct dentry *dentry, int flags)
+{
+	if (au_ftest_lock(flags, DW))
+		di_write_unlock(dentry);
+	else
+		di_read_unlock(dentry, flags);
+	si_read_unlock(dentry->d_sb);
+}
+
+void aufs_write_lock(struct dentry *dentry)
+{
+	si_write_lock(dentry->d_sb, AuLock_FLUSH | AuLock_NOPLMW);
+	di_write_lock_child(dentry);
+}
+
+void aufs_write_unlock(struct dentry *dentry)
+{
+	di_write_unlock(dentry);
+	si_write_unlock(dentry->d_sb);
+}
+
+int aufs_read_and_write_lock2(struct dentry *d1, struct dentry *d2, int flags)
+{
+	int err;
+	unsigned int sigen;
+	struct super_block *sb;
+
+	sb = d1->d_sb;
+	err = si_read_lock(sb, flags);
+	if (unlikely(err))
+		goto out;
+
+	di_write_lock2_child(d1, d2, au_ftest_lock(flags, DIRS));
+
+	if (au_ftest_lock(flags, GEN)) {
+		sigen = au_sigen(sb);
+		err = au_digen_test(d1, sigen);
+		AuDebugOn(!err && au_dbrange_test(d1));
+		if (!err) {
+			err = au_digen_test(d2, sigen);
+			AuDebugOn(!err && au_dbrange_test(d2));
+		}
+		if (unlikely(err))
+			aufs_read_and_write_unlock2(d1, d2);
+	}
+
+out:
+	return err;
+}
+
+void aufs_read_and_write_unlock2(struct dentry *d1, struct dentry *d2)
+{
+	di_write_unlock2(d1, d2);
+	si_read_unlock(d1->d_sb);
+}
+
+/* ---------------------------------------------------------------------- */
+
+int si_pid_test_slow(struct super_block *sb)
+{
+	void *p;
+
+	rcu_read_lock();
+	p = radix_tree_lookup(&au_sbi(sb)->au_si_pid.tree, current->pid);
+	rcu_read_unlock();
+
+	return (long)!!p;
+}
+
+void si_pid_set_slow(struct super_block *sb)
+{
+	int err;
+	struct au_sbinfo *sbinfo;
+
+	AuDebugOn(si_pid_test_slow(sb));
+
+	sbinfo = au_sbi(sb);
+	err = radix_tree_preload(GFP_NOFS | __GFP_NOFAIL);
+	AuDebugOn(err);
+	spin_lock(&sbinfo->au_si_pid.tree_lock);
+	err = radix_tree_insert(&sbinfo->au_si_pid.tree, current->pid,
+				/*any valid ptr*/sb);
+	spin_unlock(&sbinfo->au_si_pid.tree_lock);
+	AuDebugOn(err);
+	radix_tree_preload_end();
+}
+
+void si_pid_clr_slow(struct super_block *sb)
+{
+	void *p;
+	struct au_sbinfo *sbinfo;
+
+	AuDebugOn(!si_pid_test_slow(sb));
+
+	sbinfo = au_sbi(sb);
+	spin_lock(&sbinfo->au_si_pid.tree_lock);
+	p = radix_tree_delete(&sbinfo->au_si_pid.tree, current->pid);
+	spin_unlock(&sbinfo->au_si_pid.tree_lock);
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/fs/aufs/spl.h
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+ *
+ * This program, aufs is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * simple list protected by a spinlock
+ */
+
+#ifndef __AUFS_SPL_H__
+#define __AUFS_SPL_H__
+
+#ifdef __KERNEL__
+
+struct au_splhead {
+	spinlock_t		spin;
+	struct list_head	head;
+};
+
+static inline void au_spl_init(struct au_splhead *spl)
+{
+	spin_lock_init(&spl->spin);
+	INIT_LIST_HEAD(&spl->head);
+}
+
+static inline void au_spl_add(struct list_head *list, struct au_splhead *spl)
+{
+	spin_lock(&spl->spin);
+	list_add(list, &spl->head);
+	spin_unlock(&spl->spin);
+}
+
+static inline void au_spl_del(struct list_head *list, struct au_splhead *spl)
+{
+	spin_lock(&spl->spin);
+	list_del(list);
+	spin_unlock(&spl->spin);
+}
+
+static inline void au_spl_del_rcu(struct list_head *list,
+				  struct au_splhead *spl)
+{
+	spin_lock(&spl->spin);
+	list_del_rcu(list);
+	spin_unlock(&spl->spin);
+}
+
+/* ---------------------------------------------------------------------- */
+
+struct au_sphlhead {
+	spinlock_t		spin;
+	struct hlist_head	head;
+};
+
+static inline void au_sphl_init(struct au_sphlhead *sphl)
+{
+	spin_lock_init(&sphl->spin);
+	INIT_HLIST_HEAD(&sphl->head);
+}
+
+static inline void au_sphl_add(struct hlist_node *hlist,
+			       struct au_sphlhead *sphl)
+{
+	spin_lock(&sphl->spin);
+	hlist_add_head(hlist, &sphl->head);
+	spin_unlock(&sphl->spin);
+}
+
+static inline void au_sphl_del(struct hlist_node *hlist,
+			       struct au_sphlhead *sphl)
+{
+	spin_lock(&sphl->spin);
+	hlist_del(hlist);
+	spin_unlock(&sphl->spin);
+}
+
+static inline void au_sphl_del_rcu(struct hlist_node *hlist,
+				   struct au_sphlhead *sphl)
+{
+	spin_lock(&sphl->spin);
+	hlist_del_rcu(hlist);
+	spin_unlock(&sphl->spin);
+}
+
+static inline unsigned long au_sphl_count(struct au_sphlhead *sphl)
+{
+	unsigned long cnt;
+	struct hlist_node *pos;
+
+	cnt = 0;
+	spin_lock(&sphl->spin);
+	hlist_for_each(pos, &sphl->head)
+		cnt++;
+	spin_unlock(&sphl->spin);
+	return cnt;
+}
+
+#endif /* __KERNEL__ */
+#endif /* __AUFS_SPL_H__ */
--- /dev/null
+++ zfcpdump-kernel-4.4/fs/aufs/super.c
@@ -0,0 +1,1042 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+ *
+ * This program, aufs is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * mount and super_block operations
+ */
+
+#include <linux/mm.h>
+#include <linux/seq_file.h>
+#include <linux/statfs.h>
+#include <linux/vmalloc.h>
+#include "aufs.h"
+
+/*
+ * super_operations
+ */
+static struct inode *aufs_alloc_inode(struct super_block *sb __maybe_unused)
+{
+	struct au_icntnr *c;
+
+	c = au_cache_alloc_icntnr();
+	if (c) {
+		au_icntnr_init(c);
+		c->vfs_inode.i_version = 1; /* sigen(sb); */
+		c->iinfo.ii_hinode = NULL;
+		return &c->vfs_inode;
+	}
+	return NULL;
+}
+
+static void aufs_destroy_inode_cb(struct rcu_head *head)
+{
+	struct inode *inode = container_of(head, struct inode, i_rcu);
+
+	INIT_HLIST_HEAD(&inode->i_dentry);
+	au_cache_free_icntnr(container_of(inode, struct au_icntnr, vfs_inode));
+}
+
+static void aufs_destroy_inode(struct inode *inode)
+{
+	au_iinfo_fin(inode);
+	call_rcu(&inode->i_rcu, aufs_destroy_inode_cb);
+}
+
+struct inode *au_iget_locked(struct super_block *sb, ino_t ino)
+{
+	struct inode *inode;
+	int err;
+
+	inode = iget_locked(sb, ino);
+	if (unlikely(!inode)) {
+		inode = ERR_PTR(-ENOMEM);
+		goto out;
+	}
+	if (!(inode->i_state & I_NEW))
+		goto out;
+
+	err = au_xigen_new(inode);
+	if (!err)
+		err = au_iinfo_init(inode);
+	if (!err)
+		inode->i_version++;
+	else {
+		iget_failed(inode);
+		inode = ERR_PTR(err);
+	}
+
+out:
+	/* never return NULL */
+	AuDebugOn(!inode);
+	AuTraceErrPtr(inode);
+	return inode;
+}
+
+/* lock free root dinfo */
+static int au_show_brs(struct seq_file *seq, struct super_block *sb)
+{
+	int err;
+	aufs_bindex_t bindex, bend;
+	struct path path;
+	struct au_hdentry *hdp;
+	struct au_branch *br;
+	au_br_perm_str_t perm;
+
+	err = 0;
+	bend = au_sbend(sb);
+	hdp = au_di(sb->s_root)->di_hdentry;
+	for (bindex = 0; !err && bindex <= bend; bindex++) {
+		br = au_sbr(sb, bindex);
+		path.mnt = au_br_mnt(br);
+		path.dentry = hdp[bindex].hd_dentry;
+		err = au_seq_path(seq, &path);
+		if (!err) {
+			au_optstr_br_perm(&perm, br->br_perm);
+			seq_printf(seq, "=%s", perm.a);
+			if (bindex != bend)
+				seq_putc(seq, ':');
+		}
+	}
+	if (unlikely(err || seq_has_overflowed(seq)))
+		err = -E2BIG;
+
+	return err;
+}
+
+static void au_show_wbr_create(struct seq_file *m, int v,
+			       struct au_sbinfo *sbinfo)
+{
+	const char *pat;
+
+	AuRwMustAnyLock(&sbinfo->si_rwsem);
+
+	seq_puts(m, ",create=");
+	pat = au_optstr_wbr_create(v);
+	switch (v) {
+	case AuWbrCreate_TDP:
+	case AuWbrCreate_RR:
+	case AuWbrCreate_MFS:
+	case AuWbrCreate_PMFS:
+		seq_puts(m, pat);
+		break;
+	case AuWbrCreate_MFSV:
+		seq_printf(m, /*pat*/"mfs:%lu",
+			   jiffies_to_msecs(sbinfo->si_wbr_mfs.mfs_expire)
+			   / MSEC_PER_SEC);
+		break;
+	case AuWbrCreate_PMFSV:
+		seq_printf(m, /*pat*/"pmfs:%lu",
+			   jiffies_to_msecs(sbinfo->si_wbr_mfs.mfs_expire)
+			   / MSEC_PER_SEC);
+		break;
+	case AuWbrCreate_MFSRR:
+		seq_printf(m, /*pat*/"mfsrr:%llu",
+			   sbinfo->si_wbr_mfs.mfsrr_watermark);
+		break;
+	case AuWbrCreate_MFSRRV:
+		seq_printf(m, /*pat*/"mfsrr:%llu:%lu",
+			   sbinfo->si_wbr_mfs.mfsrr_watermark,
+			   jiffies_to_msecs(sbinfo->si_wbr_mfs.mfs_expire)
+			   / MSEC_PER_SEC);
+		break;
+	case AuWbrCreate_PMFSRR:
+		seq_printf(m, /*pat*/"pmfsrr:%llu",
+			   sbinfo->si_wbr_mfs.mfsrr_watermark);
+		break;
+	case AuWbrCreate_PMFSRRV:
+		seq_printf(m, /*pat*/"pmfsrr:%llu:%lu",
+			   sbinfo->si_wbr_mfs.mfsrr_watermark,
+			   jiffies_to_msecs(sbinfo->si_wbr_mfs.mfs_expire)
+			   / MSEC_PER_SEC);
+		break;
+	}
+}
+
+static int au_show_xino(struct seq_file *seq, struct super_block *sb)
+{
+#ifdef CONFIG_SYSFS
+	return 0;
+#else
+	int err;
+	const int len = sizeof(AUFS_XINO_FNAME) - 1;
+	aufs_bindex_t bindex, brid;
+	struct qstr *name;
+	struct file *f;
+	struct dentry *d, *h_root;
+	struct au_hdentry *hdp;
+
+	AuRwMustAnyLock(&sbinfo->si_rwsem);
+
+	err = 0;
+	f = au_sbi(sb)->si_xib;
+	if (!f)
+		goto out;
+
+	/* stop printing the default xino path on the first writable branch */
+	h_root = NULL;
+	brid = au_xino_brid(sb);
+	if (brid >= 0) {
+		bindex = au_br_index(sb, brid);
+		hdp = au_di(sb->s_root)->di_hdentry;
+		h_root = hdp[0 + bindex].hd_dentry;
+	}
+	d = f->f_path.dentry;
+	name = &d->d_name;
+	/* safe ->d_parent because the file is unlinked */
+	if (d->d_parent == h_root
+	    && name->len == len
+	    && !memcmp(name->name, AUFS_XINO_FNAME, len))
+		goto out;
+
+	seq_puts(seq, ",xino=");
+	err = au_xino_path(seq, f);
+
+out:
+	return err;
+#endif
+}
+
+/* seq_file will re-call me in case of too long string */
+static int aufs_show_options(struct seq_file *m, struct dentry *dentry)
+{
+	int err;
+	unsigned int mnt_flags, v;
+	struct super_block *sb;
+	struct au_sbinfo *sbinfo;
+
+#define AuBool(name, str) do { \
+	v = au_opt_test(mnt_flags, name); \
+	if (v != au_opt_test(AuOpt_Def, name)) \
+		seq_printf(m, ",%s" #str, v ? "" : "no"); \
+} while (0)
+
+#define AuStr(name, str) do { \
+	v = mnt_flags & AuOptMask_##name; \
+	if (v != (AuOpt_Def & AuOptMask_##name)) \
+		seq_printf(m, "," #str "=%s", au_optstr_##str(v)); \
+} while (0)
+
+#define AuUInt(name, str, val) do { \
+	if (val != AUFS_##name##_DEF) \
+		seq_printf(m, "," #str "=%u", val); \
+} while (0)
+
+	sb = dentry->d_sb;
+	if (sb->s_flags & MS_POSIXACL)
+		seq_puts(m, ",acl");
+
+	/* lock free root dinfo */
+	si_noflush_read_lock(sb);
+	sbinfo = au_sbi(sb);
+	seq_printf(m, ",si=%lx", sysaufs_si_id(sbinfo));
+
+	mnt_flags = au_mntflags(sb);
+	if (au_opt_test(mnt_flags, XINO)) {
+		err = au_show_xino(m, sb);
+		if (unlikely(err))
+			goto out;
+	} else
+		seq_puts(m, ",noxino");
+
+	AuBool(TRUNC_XINO, trunc_xino);
+	AuStr(UDBA, udba);
+	AuBool(SHWH, shwh);
+	AuBool(PLINK, plink);
+	AuBool(DIO, dio);
+	AuBool(DIRPERM1, dirperm1);
+
+	v = sbinfo->si_wbr_create;
+	if (v != AuWbrCreate_Def)
+		au_show_wbr_create(m, v, sbinfo);
+
+	v = sbinfo->si_wbr_copyup;
+	if (v != AuWbrCopyup_Def)
+		seq_printf(m, ",cpup=%s", au_optstr_wbr_copyup(v));
+
+	v = au_opt_test(mnt_flags, ALWAYS_DIROPQ);
+	if (v != au_opt_test(AuOpt_Def, ALWAYS_DIROPQ))
+		seq_printf(m, ",diropq=%c", v ? 'a' : 'w');
+
+	AuUInt(DIRWH, dirwh, sbinfo->si_dirwh);
+
+	v = jiffies_to_msecs(sbinfo->si_rdcache) / MSEC_PER_SEC;
+	AuUInt(RDCACHE, rdcache, v);
+
+	AuUInt(RDBLK, rdblk, sbinfo->si_rdblk);
+	AuUInt(RDHASH, rdhash, sbinfo->si_rdhash);
+
+	au_fhsm_show(m, sbinfo);
+
+	AuBool(SUM, sum);
+	/* AuBool(SUM_W, wsum); */
+	AuBool(WARN_PERM, warn_perm);
+	AuBool(VERBOSE, verbose);
+
+out:
+	/* be sure to print "br:" last */
+	if (!sysaufs_brs) {
+		seq_puts(m, ",br:");
+		au_show_brs(m, sb);
+	}
+	si_read_unlock(sb);
+	return 0;
+
+#undef AuBool
+#undef AuStr
+#undef AuUInt
+}
+
+/* ---------------------------------------------------------------------- */
+
+/* sum mode which returns the summation for statfs(2) */
+
+static u64 au_add_till_max(u64 a, u64 b)
+{
+	u64 old;
+
+	old = a;
+	a += b;
+	if (old <= a)
+		return a;
+	return ULLONG_MAX;
+}
+
+static u64 au_mul_till_max(u64 a, long mul)
+{
+	u64 old;
+
+	old = a;
+	a *= mul;
+	if (old <= a)
+		return a;
+	return ULLONG_MAX;
+}
+
+static int au_statfs_sum(struct super_block *sb, struct kstatfs *buf)
+{
+	int err;
+	long bsize, factor;
+	u64 blocks, bfree, bavail, files, ffree;
+	aufs_bindex_t bend, bindex, i;
+	unsigned char shared;
+	struct path h_path;
+	struct super_block *h_sb;
+
+	err = 0;
+	bsize = LONG_MAX;
+	files = 0;
+	ffree = 0;
+	blocks = 0;
+	bfree = 0;
+	bavail = 0;
+	bend = au_sbend(sb);
+	for (bindex = 0; bindex <= bend; bindex++) {
+		h_path.mnt = au_sbr_mnt(sb, bindex);
+		h_sb = h_path.mnt->mnt_sb;
+		shared = 0;
+		for (i = 0; !shared && i < bindex; i++)
+			shared = (au_sbr_sb(sb, i) == h_sb);
+		if (shared)
+			continue;
+
+		/* sb->s_root for NFS is unreliable */
+		h_path.dentry = h_path.mnt->mnt_root;
+		err = vfs_statfs(&h_path, buf);
+		if (unlikely(err))
+			goto out;
+
+		if (bsize > buf->f_bsize) {
+			/*
+			 * we will reduce bsize, so we have to expand blocks
+			 * etc. to match them again
+			 */
+			factor = (bsize / buf->f_bsize);
+			blocks = au_mul_till_max(blocks, factor);
+			bfree = au_mul_till_max(bfree, factor);
+			bavail = au_mul_till_max(bavail, factor);
+			bsize = buf->f_bsize;
+		}
+
+		factor = (buf->f_bsize / bsize);
+		blocks = au_add_till_max(blocks,
+				au_mul_till_max(buf->f_blocks, factor));
+		bfree = au_add_till_max(bfree,
+				au_mul_till_max(buf->f_bfree, factor));
+		bavail = au_add_till_max(bavail,
+				au_mul_till_max(buf->f_bavail, factor));
+		files = au_add_till_max(files, buf->f_files);
+		ffree = au_add_till_max(ffree, buf->f_ffree);
+	}
+
+	buf->f_bsize = bsize;
+	buf->f_blocks = blocks;
+	buf->f_bfree = bfree;
+	buf->f_bavail = bavail;
+	buf->f_files = files;
+	buf->f_ffree = ffree;
+	buf->f_frsize = 0;
+
+out:
+	return err;
+}
+
+static int aufs_statfs(struct dentry *dentry, struct kstatfs *buf)
+{
+	int err;
+	struct path h_path;
+	struct super_block *sb;
+
+	/* lock free root dinfo */
+	sb = dentry->d_sb;
+	si_noflush_read_lock(sb);
+	if (!au_opt_test(au_mntflags(sb), SUM)) {
+		/* sb->s_root for NFS is unreliable */
+		h_path.mnt = au_sbr_mnt(sb, 0);
+		h_path.dentry = h_path.mnt->mnt_root;
+		err = vfs_statfs(&h_path, buf);
+	} else
+		err = au_statfs_sum(sb, buf);
+	si_read_unlock(sb);
+
+	if (!err) {
+		buf->f_type = AUFS_SUPER_MAGIC;
+		buf->f_namelen = AUFS_MAX_NAMELEN;
+		memset(&buf->f_fsid, 0, sizeof(buf->f_fsid));
+	}
+	/* buf->f_bsize = buf->f_blocks = buf->f_bfree = buf->f_bavail = -1; */
+
+	return err;
+}
+
+/* ---------------------------------------------------------------------- */
+
+static int aufs_sync_fs(struct super_block *sb, int wait)
+{
+	int err, e;
+	aufs_bindex_t bend, bindex;
+	struct au_branch *br;
+	struct super_block *h_sb;
+
+	err = 0;
+	si_noflush_read_lock(sb);
+	bend = au_sbend(sb);
+	for (bindex = 0; bindex <= bend; bindex++) {
+		br = au_sbr(sb, bindex);
+		if (!au_br_writable(br->br_perm))
+			continue;
+
+		h_sb = au_sbr_sb(sb, bindex);
+		if (h_sb->s_op->sync_fs) {
+			e = h_sb->s_op->sync_fs(h_sb, wait);
+			if (unlikely(e && !err))
+				err = e;
+			/* go on even if an error happens */
+		}
+	}
+	si_read_unlock(sb);
+
+	return err;
+}
+
+/* ---------------------------------------------------------------------- */
+
+/* final actions when unmounting a file system */
+static void aufs_put_super(struct super_block *sb)
+{
+	struct au_sbinfo *sbinfo;
+
+	sbinfo = au_sbi(sb);
+	if (!sbinfo)
+		return;
+
+	dbgaufs_si_fin(sbinfo);
+	kobject_put(&sbinfo->si_kobj);
+}
+
+/* ---------------------------------------------------------------------- */
+
+void *au_array_alloc(unsigned long long *hint, au_arraycb_t cb,
+		     struct super_block *sb, void *arg)
+{
+	void *array;
+	unsigned long long n, sz;
+
+	array = NULL;
+	n = 0;
+	if (!*hint)
+		goto out;
+
+	if (*hint > ULLONG_MAX / sizeof(array)) {
+		array = ERR_PTR(-EMFILE);
+		pr_err("hint %llu\n", *hint);
+		goto out;
+	}
+
+	sz = sizeof(array) * *hint;
+	array = kzalloc(sz, GFP_NOFS);
+	if (unlikely(!array))
+		array = vzalloc(sz);
+	if (unlikely(!array)) {
+		array = ERR_PTR(-ENOMEM);
+		goto out;
+	}
+
+	n = cb(sb, array, *hint, arg);
+	AuDebugOn(n > *hint);
+
+out:
+	*hint = n;
+	return array;
+}
+
+static unsigned long long au_iarray_cb(struct super_block *sb, void *a,
+				       unsigned long long max __maybe_unused,
+				       void *arg)
+{
+	unsigned long long n;
+	struct inode **p, *inode;
+	struct list_head *head;
+
+	n = 0;
+	p = a;
+	head = arg;
+	spin_lock(&sb->s_inode_list_lock);
+	list_for_each_entry(inode, head, i_sb_list) {
+		if (!is_bad_inode(inode)
+		    && au_ii(inode)->ii_bstart >= 0) {
+			spin_lock(&inode->i_lock);
+			if (atomic_read(&inode->i_count)) {
+				au_igrab(inode);
+				*p++ = inode;
+				n++;
+				AuDebugOn(n > max);
+			}
+			spin_unlock(&inode->i_lock);
+		}
+	}
+	spin_unlock(&sb->s_inode_list_lock);
+
+	return n;
+}
+
+struct inode **au_iarray_alloc(struct super_block *sb, unsigned long long *max)
+{
+	*max = atomic_long_read(&au_sbi(sb)->si_ninodes);
+	return au_array_alloc(max, au_iarray_cb, sb, &sb->s_inodes);
+}
+
+void au_iarray_free(struct inode **a, unsigned long long max)
+{
+	unsigned long long ull;
+
+	for (ull = 0; ull < max; ull++)
+		iput(a[ull]);
+	kvfree(a);
+}
+
+/* ---------------------------------------------------------------------- */
+
+/*
+ * refresh dentry and inode at remount time.
+ */
+/* todo: consolidate with simple_reval_dpath() and au_reval_for_attr() */
+static int au_do_refresh(struct dentry *dentry, unsigned int dir_flags,
+		      struct dentry *parent)
+{
+	int err;
+
+	di_write_lock_child(dentry);
+	di_read_lock_parent(parent, AuLock_IR);
+	err = au_refresh_dentry(dentry, parent);
+	if (!err && dir_flags)
+		au_hn_reset(d_inode(dentry), dir_flags);
+	di_read_unlock(parent, AuLock_IR);
+	di_write_unlock(dentry);
+
+	return err;
+}
+
+static int au_do_refresh_d(struct dentry *dentry, unsigned int sigen,
+			   struct au_sbinfo *sbinfo,
+			   const unsigned int dir_flags, unsigned int do_idop)
+{
+	int err;
+	struct dentry *parent;
+
+	err = 0;
+	parent = dget_parent(dentry);
+	if (!au_digen_test(parent, sigen) && au_digen_test(dentry, sigen)) {
+		if (d_really_is_positive(dentry)) {
+			if (!d_is_dir(dentry))
+				err = au_do_refresh(dentry, /*dir_flags*/0,
+						 parent);
+			else {
+				err = au_do_refresh(dentry, dir_flags, parent);
+				if (unlikely(err))
+					au_fset_si(sbinfo, FAILED_REFRESH_DIR);
+			}
+		} else
+			err = au_do_refresh(dentry, /*dir_flags*/0, parent);
+		AuDbgDentry(dentry);
+	}
+	dput(parent);
+
+	if (!err) {
+		if (do_idop)
+			au_refresh_dop(dentry, /*force_reval*/0);
+	} else
+		au_refresh_dop(dentry, /*force_reval*/1);
+
+	AuTraceErr(err);
+	return err;
+}
+
+static int au_refresh_d(struct super_block *sb, unsigned int do_idop)
+{
+	int err, i, j, ndentry, e;
+	unsigned int sigen;
+	struct au_dcsub_pages dpages;
+	struct au_dpage *dpage;
+	struct dentry **dentries, *d;
+	struct au_sbinfo *sbinfo;
+	struct dentry *root = sb->s_root;
+	const unsigned int dir_flags = au_hi_flags(d_inode(root), /*isdir*/1);
+
+	if (do_idop)
+		au_refresh_dop(root, /*force_reval*/0);
+
+	err = au_dpages_init(&dpages, GFP_NOFS);
+	if (unlikely(err))
+		goto out;
+	err = au_dcsub_pages(&dpages, root, NULL, NULL);
+	if (unlikely(err))
+		goto out_dpages;
+
+	sigen = au_sigen(sb);
+	sbinfo = au_sbi(sb);
+	for (i = 0; i < dpages.ndpage; i++) {
+		dpage = dpages.dpages + i;
+		dentries = dpage->dentries;
+		ndentry = dpage->ndentry;
+		for (j = 0; j < ndentry; j++) {
+			d = dentries[j];
+			e = au_do_refresh_d(d, sigen, sbinfo, dir_flags,
+					    do_idop);
+			if (unlikely(e && !err))
+				err = e;
+			/* go on even err */
+		}
+	}
+
+out_dpages:
+	au_dpages_free(&dpages);
+out:
+	return err;
+}
+
+static int au_refresh_i(struct super_block *sb, unsigned int do_idop)
+{
+	int err, e;
+	unsigned int sigen;
+	unsigned long long max, ull;
+	struct inode *inode, **array;
+
+	array = au_iarray_alloc(sb, &max);
+	err = PTR_ERR(array);
+	if (IS_ERR(array))
+		goto out;
+
+	err = 0;
+	sigen = au_sigen(sb);
+	for (ull = 0; ull < max; ull++) {
+		inode = array[ull];
+		if (unlikely(!inode))
+			break;
+
+		e = 0;
+		ii_write_lock_child(inode);
+		if (au_iigen(inode, NULL) != sigen) {
+			e = au_refresh_hinode_self(inode);
+			if (unlikely(e)) {
+				au_refresh_iop(inode, /*force_getattr*/1);
+				pr_err("error %d, i%lu\n", e, inode->i_ino);
+				if (!err)
+					err = e;
+				/* go on even if err */
+			}
+		}
+		if (!e && do_idop)
+			au_refresh_iop(inode, /*force_getattr*/0);
+		ii_write_unlock(inode);
+	}
+
+	au_iarray_free(array, max);
+
+out:
+	return err;
+}
+
+static void au_remount_refresh(struct super_block *sb, unsigned int do_idop)
+{
+	int err, e;
+	unsigned int udba;
+	aufs_bindex_t bindex, bend;
+	struct dentry *root;
+	struct inode *inode;
+	struct au_branch *br;
+	struct au_sbinfo *sbi;
+
+	au_sigen_inc(sb);
+	sbi = au_sbi(sb);
+	au_fclr_si(sbi, FAILED_REFRESH_DIR);
+
+	root = sb->s_root;
+	DiMustNoWaiters(root);
+	inode = d_inode(root);
+	IiMustNoWaiters(inode);
+
+	udba = au_opt_udba(sb);
+	bend = au_sbend(sb);
+	for (bindex = 0; bindex <= bend; bindex++) {
+		br = au_sbr(sb, bindex);
+		err = au_hnotify_reset_br(udba, br, br->br_perm);
+		if (unlikely(err))
+			AuIOErr("hnotify failed on br %d, %d, ignored\n",
+				bindex, err);
+		/* go on even if err */
+	}
+	au_hn_reset(inode, au_hi_flags(inode, /*isdir*/1));
+
+	if (do_idop) {
+		if (au_ftest_si(sbi, NO_DREVAL)) {
+			AuDebugOn(sb->s_d_op == &aufs_dop_noreval);
+			sb->s_d_op = &aufs_dop_noreval;
+			AuDebugOn(sbi->si_iop_array == aufs_iop_nogetattr);
+			sbi->si_iop_array = aufs_iop_nogetattr;
+		} else {
+			AuDebugOn(sb->s_d_op == &aufs_dop);
+			sb->s_d_op = &aufs_dop;
+			AuDebugOn(sbi->si_iop_array == aufs_iop);
+			sbi->si_iop_array = aufs_iop;
+		}
+		pr_info("reset to %pf and %pf\n",
+			sb->s_d_op, sbi->si_iop_array);
+	}
+
+	di_write_unlock(root);
+	err = au_refresh_d(sb, do_idop);
+	e = au_refresh_i(sb, do_idop);
+	if (unlikely(e && !err))
+		err = e;
+	/* aufs_write_lock() calls ..._child() */
+	di_write_lock_child(root);
+
+	au_cpup_attr_all(inode, /*force*/1);
+
+	if (unlikely(err))
+		AuIOErr("refresh failed, ignored, %d\n", err);
+}
+
+/* stop extra interpretation of errno in mount(8), and strange error messages */
+static int cvt_err(int err)
+{
+	AuTraceErr(err);
+
+	switch (err) {
+	case -ENOENT:
+	case -ENOTDIR:
+	case -EEXIST:
+	case -EIO:
+		err = -EINVAL;
+	}
+	return err;
+}
+
+static int aufs_remount_fs(struct super_block *sb, int *flags, char *data)
+{
+	int err, do_dx;
+	unsigned int mntflags;
+	struct au_opts opts = {
+		.opt = NULL
+	};
+	struct dentry *root;
+	struct inode *inode;
+	struct au_sbinfo *sbinfo;
+
+	err = 0;
+	root = sb->s_root;
+	if (!data || !*data) {
+		err = si_write_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
+		if (!err) {
+			di_write_lock_child(root);
+			err = au_opts_verify(sb, *flags, /*pending*/0);
+			aufs_write_unlock(root);
+		}
+		goto out;
+	}
+
+	err = -ENOMEM;
+	opts.opt = (void *)__get_free_page(GFP_NOFS);
+	if (unlikely(!opts.opt))
+		goto out;
+	opts.max_opt = PAGE_SIZE / sizeof(*opts.opt);
+	opts.flags = AuOpts_REMOUNT;
+	opts.sb_flags = *flags;
+
+	/* parse it before aufs lock */
+	err = au_opts_parse(sb, data, &opts);
+	if (unlikely(err))
+		goto out_opts;
+
+	sbinfo = au_sbi(sb);
+	inode = d_inode(root);
+	mutex_lock(&inode->i_mutex);
+	err = si_write_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
+	if (unlikely(err))
+		goto out_mtx;
+	di_write_lock_child(root);
+
+	/* au_opts_remount() may return an error */
+	err = au_opts_remount(sb, &opts);
+	au_opts_free(&opts);
+
+	if (au_ftest_opts(opts.flags, REFRESH))
+		au_remount_refresh(sb, au_ftest_opts(opts.flags, REFRESH_IDOP));
+
+	if (au_ftest_opts(opts.flags, REFRESH_DYAOP)) {
+		mntflags = au_mntflags(sb);
+		do_dx = !!au_opt_test(mntflags, DIO);
+		au_dy_arefresh(do_dx);
+	}
+
+	au_fhsm_wrote_all(sb, /*force*/1); /* ?? */
+	aufs_write_unlock(root);
+
+out_mtx:
+	mutex_unlock(&inode->i_mutex);
+out_opts:
+	free_page((unsigned long)opts.opt);
+out:
+	err = cvt_err(err);
+	AuTraceErr(err);
+	return err;
+}
+
+static const struct super_operations aufs_sop = {
+	.alloc_inode	= aufs_alloc_inode,
+	.destroy_inode	= aufs_destroy_inode,
+	/* always deleting, no clearing */
+	.drop_inode	= generic_delete_inode,
+	.show_options	= aufs_show_options,
+	.statfs		= aufs_statfs,
+	.put_super	= aufs_put_super,
+	.sync_fs	= aufs_sync_fs,
+	.remount_fs	= aufs_remount_fs,
+#ifdef CONFIG_AUFS_BDEV_LOOP
+	.real_loop	= aufs_real_loop
+#endif
+};
+
+/* ---------------------------------------------------------------------- */
+
+static int alloc_root(struct super_block *sb)
+{
+	int err;
+	struct inode *inode;
+	struct dentry *root;
+
+	err = -ENOMEM;
+	inode = au_iget_locked(sb, AUFS_ROOT_INO);
+	err = PTR_ERR(inode);
+	if (IS_ERR(inode))
+		goto out;
+
+	inode->i_op = aufs_iop + AuIop_DIR; /* with getattr by default */
+	inode->i_fop = &aufs_dir_fop;
+	inode->i_mode = S_IFDIR;
+	set_nlink(inode, 2);
+	unlock_new_inode(inode);
+
+	root = d_make_root(inode);
+	if (unlikely(!root))
+		goto out;
+	err = PTR_ERR(root);
+	if (IS_ERR(root))
+		goto out;
+
+	err = au_di_init(root);
+	if (!err) {
+		sb->s_root = root;
+		return 0; /* success */
+	}
+	dput(root);
+
+out:
+	return err;
+}
+
+static int aufs_fill_super(struct super_block *sb, void *raw_data,
+			   int silent __maybe_unused)
+{
+	int err;
+	struct au_opts opts = {
+		.opt = NULL
+	};
+	struct au_sbinfo *sbinfo;
+	struct dentry *root;
+	struct inode *inode;
+	char *arg = raw_data;
+
+	if (unlikely(!arg || !*arg)) {
+		err = -EINVAL;
+		pr_err("no arg\n");
+		goto out;
+	}
+
+	err = -ENOMEM;
+	opts.opt = (void *)__get_free_page(GFP_NOFS);
+	if (unlikely(!opts.opt))
+		goto out;
+	opts.max_opt = PAGE_SIZE / sizeof(*opts.opt);
+	opts.sb_flags = sb->s_flags;
+
+	err = au_si_alloc(sb);
+	if (unlikely(err))
+		goto out_opts;
+	sbinfo = au_sbi(sb);
+
+	/* all timestamps always follow the ones on the branch */
+	sb->s_flags |= MS_NOATIME | MS_NODIRATIME;
+	sb->s_op = &aufs_sop;
+	sb->s_d_op = &aufs_dop;
+	sb->s_magic = AUFS_SUPER_MAGIC;
+	sb->s_maxbytes = 0;
+	sb->s_stack_depth = 1;
+	au_export_init(sb);
+	/* au_xattr_init(sb); */
+
+	err = alloc_root(sb);
+	if (unlikely(err)) {
+		si_write_unlock(sb);
+		goto out_info;
+	}
+	root = sb->s_root;
+	inode = d_inode(root);
+
+	/*
+	 * actually we can parse options regardless aufs lock here.
+	 * but at remount time, parsing must be done before aufs lock.
+	 * so we follow the same rule.
+	 */
+	ii_write_lock_parent(inode);
+	aufs_write_unlock(root);
+	err = au_opts_parse(sb, arg, &opts);
+	if (unlikely(err))
+		goto out_root;
+
+	/* lock vfs_inode first, then aufs. */
+	mutex_lock(&inode->i_mutex);
+	aufs_write_lock(root);
+	err = au_opts_mount(sb, &opts);
+	au_opts_free(&opts);
+	if (!err && au_ftest_si(sbinfo, NO_DREVAL)) {
+		sb->s_d_op = &aufs_dop_noreval;
+		pr_info("%pf\n", sb->s_d_op);
+		au_refresh_dop(root, /*force_reval*/0);
+		sbinfo->si_iop_array = aufs_iop_nogetattr;
+		au_refresh_iop(inode, /*force_getattr*/0);
+	}
+	aufs_write_unlock(root);
+	mutex_unlock(&inode->i_mutex);
+	if (!err)
+		goto out_opts; /* success */
+
+out_root:
+	dput(root);
+	sb->s_root = NULL;
+out_info:
+	dbgaufs_si_fin(sbinfo);
+	kobject_put(&sbinfo->si_kobj);
+	sb->s_fs_info = NULL;
+out_opts:
+	free_page((unsigned long)opts.opt);
+out:
+	AuTraceErr(err);
+	err = cvt_err(err);
+	AuTraceErr(err);
+	return err;
+}
+
+/* ---------------------------------------------------------------------- */
+
+static struct dentry *aufs_mount(struct file_system_type *fs_type, int flags,
+				 const char *dev_name __maybe_unused,
+				 void *raw_data)
+{
+	struct dentry *root;
+	struct super_block *sb;
+
+	/* all timestamps always follow the ones on the branch */
+	/* mnt->mnt_flags |= MNT_NOATIME | MNT_NODIRATIME; */
+	root = mount_nodev(fs_type, flags, raw_data, aufs_fill_super);
+	if (IS_ERR(root))
+		goto out;
+
+	sb = root->d_sb;
+	si_write_lock(sb, !AuLock_FLUSH);
+	sysaufs_brs_add(sb, 0);
+	si_write_unlock(sb);
+	au_sbilist_add(sb);
+
+out:
+	return root;
+}
+
+static void aufs_kill_sb(struct super_block *sb)
+{
+	struct au_sbinfo *sbinfo;
+
+	sbinfo = au_sbi(sb);
+	if (sbinfo) {
+		au_sbilist_del(sb);
+		aufs_write_lock(sb->s_root);
+		au_fhsm_fin(sb);
+		if (sbinfo->si_wbr_create_ops->fin)
+			sbinfo->si_wbr_create_ops->fin(sb);
+		if (au_opt_test(sbinfo->si_mntflags, UDBA_HNOTIFY)) {
+			au_opt_set_udba(sbinfo->si_mntflags, UDBA_NONE);
+			au_remount_refresh(sb, /*do_idop*/0);
+		}
+		if (au_opt_test(sbinfo->si_mntflags, PLINK))
+			au_plink_put(sb, /*verbose*/1);
+		au_xino_clr(sb);
+		sbinfo->si_sb = NULL;
+		aufs_write_unlock(sb->s_root);
+		au_nwt_flush(&sbinfo->si_nowait);
+	}
+	kill_anon_super(sb);
+}
+
+struct file_system_type aufs_fs_type = {
+	.name		= AUFS_FSTYPE,
+	/* a race between rename and others */
+	.fs_flags	= FS_RENAME_DOES_D_MOVE,
+	.mount		= aufs_mount,
+	.kill_sb	= aufs_kill_sb,
+	/* no need to __module_get() and module_put(). */
+	.owner		= THIS_MODULE,
+};
--- /dev/null
+++ zfcpdump-kernel-4.4/fs/aufs/super.h
@@ -0,0 +1,641 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+ *
+ * This program, aufs is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * super_block operations
+ */
+
+#ifndef __AUFS_SUPER_H__
+#define __AUFS_SUPER_H__
+
+#ifdef __KERNEL__
+
+#include <linux/fs.h>
+#include <linux/kobject.h>
+#include "rwsem.h"
+#include "spl.h"
+#include "wkq.h"
+
+/* policies to select one among multiple writable branches */
+struct au_wbr_copyup_operations {
+	int (*copyup)(struct dentry *dentry);
+};
+
+#define AuWbr_DIR	1		/* target is a dir */
+#define AuWbr_PARENT	(1 << 1)	/* always require a parent */
+
+#define au_ftest_wbr(flags, name)	((flags) & AuWbr_##name)
+#define au_fset_wbr(flags, name)	{ (flags) |= AuWbr_##name; }
+#define au_fclr_wbr(flags, name)	{ (flags) &= ~AuWbr_##name; }
+
+struct au_wbr_create_operations {
+	int (*create)(struct dentry *dentry, unsigned int flags);
+	int (*init)(struct super_block *sb);
+	int (*fin)(struct super_block *sb);
+};
+
+struct au_wbr_mfs {
+	struct mutex	mfs_lock; /* protect this structure */
+	unsigned long	mfs_jiffy;
+	unsigned long	mfs_expire;
+	aufs_bindex_t	mfs_bindex;
+
+	unsigned long long	mfsrr_bytes;
+	unsigned long long	mfsrr_watermark;
+};
+
+struct pseudo_link {
+	union {
+		struct hlist_node hlist;
+		struct rcu_head rcu;
+	};
+	struct inode *inode;
+};
+
+#define AuPlink_NHASH 100
+static inline int au_plink_hash(ino_t ino)
+{
+	return ino % AuPlink_NHASH;
+}
+
+/* File-based Hierarchical Storage Management */
+struct au_fhsm {
+#ifdef CONFIG_AUFS_FHSM
+	/* allow only one process who can receive the notification */
+	spinlock_t		fhsm_spin;
+	pid_t			fhsm_pid;
+	wait_queue_head_t	fhsm_wqh;
+	atomic_t		fhsm_readable;
+
+	/* these are protected by si_rwsem */
+	unsigned long		fhsm_expire;
+	aufs_bindex_t		fhsm_bottom;
+#endif
+};
+
+struct au_branch;
+struct au_sbinfo {
+	/* nowait tasks in the system-wide workqueue */
+	struct au_nowait_tasks	si_nowait;
+
+	/*
+	 * tried sb->s_umount, but failed due to the dependecy between i_mutex.
+	 * rwsem for au_sbinfo is necessary.
+	 */
+	struct au_rwsem		si_rwsem;
+
+	/* prevent recursive locking in deleting inode */
+	struct {
+		unsigned long		*bitmap;
+		spinlock_t		tree_lock;
+		struct radix_tree_root	tree;
+	} au_si_pid;
+
+	/*
+	 * dirty approach to protect sb->sb_inodes and ->s_files (gone) from
+	 * remount.
+	 */
+	atomic_long_t		si_ninodes, si_nfiles;
+
+	/* branch management */
+	unsigned int		si_generation;
+
+	/* see AuSi_ flags */
+	unsigned char		au_si_status;
+
+	aufs_bindex_t		si_bend;
+
+	/* dirty trick to keep br_id plus */
+	unsigned int		si_last_br_id :
+				sizeof(aufs_bindex_t) * BITS_PER_BYTE - 1;
+	struct au_branch	**si_branch;
+
+	/* policy to select a writable branch */
+	unsigned char		si_wbr_copyup;
+	unsigned char		si_wbr_create;
+	struct au_wbr_copyup_operations *si_wbr_copyup_ops;
+	struct au_wbr_create_operations *si_wbr_create_ops;
+
+	/* round robin */
+	atomic_t		si_wbr_rr_next;
+
+	/* most free space */
+	struct au_wbr_mfs	si_wbr_mfs;
+
+	/* File-based Hierarchical Storage Management */
+	struct au_fhsm		si_fhsm;
+
+	/* mount flags */
+	/* include/asm-ia64/siginfo.h defines a macro named si_flags */
+	unsigned int		si_mntflags;
+
+	/* symlink to follow_link() and put_link() */
+	struct au_sphlhead	si_symlink;
+
+	/* external inode number (bitmap and translation table) */
+	vfs_readf_t		si_xread;
+	vfs_writef_t		si_xwrite;
+	struct file		*si_xib;
+	struct mutex		si_xib_mtx; /* protect xib members */
+	unsigned long		*si_xib_buf;
+	unsigned long		si_xib_last_pindex;
+	int			si_xib_next_bit;
+	aufs_bindex_t		si_xino_brid;
+	unsigned long		si_xino_jiffy;
+	unsigned long		si_xino_expire;
+	/* reserved for future use */
+	/* unsigned long long	si_xib_limit; */	/* Max xib file size */
+
+#ifdef CONFIG_AUFS_EXPORT
+	/* i_generation */
+	struct file		*si_xigen;
+	atomic_t		si_xigen_next;
+#endif
+
+	/* dirty trick to suppoer atomic_open */
+	struct au_sphlhead	si_aopen;
+
+	/* vdir parameters */
+	unsigned long		si_rdcache;	/* max cache time in jiffies */
+	unsigned int		si_rdblk;	/* deblk size */
+	unsigned int		si_rdhash;	/* hash size */
+
+	/*
+	 * If the number of whiteouts are larger than si_dirwh, leave all of
+	 * them after au_whtmp_ren to reduce the cost of rmdir(2).
+	 * future fsck.aufs or kernel thread will remove them later.
+	 * Otherwise, remove all whiteouts and the dir in rmdir(2).
+	 */
+	unsigned int		si_dirwh;
+
+	/* pseudo_link list */
+	struct au_sphlhead	si_plink[AuPlink_NHASH];
+	wait_queue_head_t	si_plink_wq;
+	spinlock_t		si_plink_maint_lock;
+	pid_t			si_plink_maint_pid;
+
+	/* file list */
+	struct au_sphlhead	si_files;
+
+	/* with/without getattr, brother of sb->s_d_op */
+	struct inode_operations *si_iop_array;
+
+	/*
+	 * sysfs and lifetime management.
+	 * this is not a small structure and it may be a waste of memory in case
+	 * of sysfs is disabled, particulary when many aufs-es are mounted.
+	 * but using sysfs is majority.
+	 */
+	struct kobject		si_kobj;
+#ifdef CONFIG_DEBUG_FS
+	struct dentry		 *si_dbgaufs;
+	struct dentry		 *si_dbgaufs_plink;
+	struct dentry		 *si_dbgaufs_xib;
+#ifdef CONFIG_AUFS_EXPORT
+	struct dentry		 *si_dbgaufs_xigen;
+#endif
+#endif
+
+#ifdef CONFIG_AUFS_SBILIST
+	struct list_head	si_list;
+#endif
+
+	/* dirty, necessary for unmounting, sysfs and sysrq */
+	struct super_block	*si_sb;
+};
+
+/* sbinfo status flags */
+/*
+ * set true when refresh_dirs() failed at remount time.
+ * then try refreshing dirs at access time again.
+ * if it is false, refreshing dirs at access time is unnecesary
+ */
+#define AuSi_FAILED_REFRESH_DIR	1
+#define AuSi_FHSM		(1 << 1)	/* fhsm is active now */
+#define AuSi_NO_DREVAL		(1 << 2)	/* disable all d_revalidate */
+
+#ifndef CONFIG_AUFS_FHSM
+#undef AuSi_FHSM
+#define AuSi_FHSM		0
+#endif
+
+static inline unsigned char au_do_ftest_si(struct au_sbinfo *sbi,
+					   unsigned int flag)
+{
+	AuRwMustAnyLock(&sbi->si_rwsem);
+	return sbi->au_si_status & flag;
+}
+#define au_ftest_si(sbinfo, name)	au_do_ftest_si(sbinfo, AuSi_##name)
+#define au_fset_si(sbinfo, name) do { \
+	AuRwMustWriteLock(&(sbinfo)->si_rwsem); \
+	(sbinfo)->au_si_status |= AuSi_##name; \
+} while (0)
+#define au_fclr_si(sbinfo, name) do { \
+	AuRwMustWriteLock(&(sbinfo)->si_rwsem); \
+	(sbinfo)->au_si_status &= ~AuSi_##name; \
+} while (0)
+
+/* ---------------------------------------------------------------------- */
+
+/* policy to select one among writable branches */
+#define AuWbrCopyup(sbinfo, ...) \
+	((sbinfo)->si_wbr_copyup_ops->copyup(__VA_ARGS__))
+#define AuWbrCreate(sbinfo, ...) \
+	((sbinfo)->si_wbr_create_ops->create(__VA_ARGS__))
+
+/* flags for si_read_lock()/aufs_read_lock()/di_read_lock() */
+#define AuLock_DW		1		/* write-lock dentry */
+#define AuLock_IR		(1 << 1)	/* read-lock inode */
+#define AuLock_IW		(1 << 2)	/* write-lock inode */
+#define AuLock_FLUSH		(1 << 3)	/* wait for 'nowait' tasks */
+#define AuLock_DIRS		(1 << 4)	/* target is a pair of dirs */
+#define AuLock_NOPLM		(1 << 5)	/* return err in plm mode */
+#define AuLock_NOPLMW		(1 << 6)	/* wait for plm mode ends */
+#define AuLock_GEN		(1 << 7)	/* test digen/iigen */
+#define au_ftest_lock(flags, name)	((flags) & AuLock_##name)
+#define au_fset_lock(flags, name) \
+	do { (flags) |= AuLock_##name; } while (0)
+#define au_fclr_lock(flags, name) \
+	do { (flags) &= ~AuLock_##name; } while (0)
+
+/* ---------------------------------------------------------------------- */
+
+/* super.c */
+extern struct file_system_type aufs_fs_type;
+struct inode *au_iget_locked(struct super_block *sb, ino_t ino);
+typedef unsigned long long (*au_arraycb_t)(struct super_block *sb, void *array,
+					   unsigned long long max, void *arg);
+void *au_array_alloc(unsigned long long *hint, au_arraycb_t cb,
+		     struct super_block *sb, void *arg);
+struct inode **au_iarray_alloc(struct super_block *sb, unsigned long long *max);
+void au_iarray_free(struct inode **a, unsigned long long max);
+
+/* sbinfo.c */
+void au_si_free(struct kobject *kobj);
+int au_si_alloc(struct super_block *sb);
+int au_sbr_realloc(struct au_sbinfo *sbinfo, int nbr);
+
+unsigned int au_sigen_inc(struct super_block *sb);
+aufs_bindex_t au_new_br_id(struct super_block *sb);
+
+int si_read_lock(struct super_block *sb, int flags);
+int si_write_lock(struct super_block *sb, int flags);
+int aufs_read_lock(struct dentry *dentry, int flags);
+void aufs_read_unlock(struct dentry *dentry, int flags);
+void aufs_write_lock(struct dentry *dentry);
+void aufs_write_unlock(struct dentry *dentry);
+int aufs_read_and_write_lock2(struct dentry *d1, struct dentry *d2, int flags);
+void aufs_read_and_write_unlock2(struct dentry *d1, struct dentry *d2);
+
+int si_pid_test_slow(struct super_block *sb);
+void si_pid_set_slow(struct super_block *sb);
+void si_pid_clr_slow(struct super_block *sb);
+
+/* wbr_policy.c */
+extern struct au_wbr_copyup_operations au_wbr_copyup_ops[];
+extern struct au_wbr_create_operations au_wbr_create_ops[];
+int au_cpdown_dirs(struct dentry *dentry, aufs_bindex_t bdst);
+int au_wbr_nonopq(struct dentry *dentry, aufs_bindex_t bindex);
+int au_wbr_do_copyup_bu(struct dentry *dentry, aufs_bindex_t bstart);
+
+/* mvdown.c */
+int au_mvdown(struct dentry *dentry, struct aufs_mvdown __user *arg);
+
+#ifdef CONFIG_AUFS_FHSM
+/* fhsm.c */
+
+static inline pid_t au_fhsm_pid(struct au_fhsm *fhsm)
+{
+	pid_t pid;
+
+	spin_lock(&fhsm->fhsm_spin);
+	pid = fhsm->fhsm_pid;
+	spin_unlock(&fhsm->fhsm_spin);
+
+	return pid;
+}
+
+void au_fhsm_wrote(struct super_block *sb, aufs_bindex_t bindex, int force);
+void au_fhsm_wrote_all(struct super_block *sb, int force);
+int au_fhsm_fd(struct super_block *sb, int oflags);
+int au_fhsm_br_alloc(struct au_branch *br);
+void au_fhsm_set_bottom(struct super_block *sb, aufs_bindex_t bindex);
+void au_fhsm_fin(struct super_block *sb);
+void au_fhsm_init(struct au_sbinfo *sbinfo);
+void au_fhsm_set(struct au_sbinfo *sbinfo, unsigned int sec);
+void au_fhsm_show(struct seq_file *seq, struct au_sbinfo *sbinfo);
+#else
+AuStubVoid(au_fhsm_wrote, struct super_block *sb, aufs_bindex_t bindex,
+	   int force)
+AuStubVoid(au_fhsm_wrote_all, struct super_block *sb, int force)
+AuStub(int, au_fhsm_fd, return -EOPNOTSUPP, struct super_block *sb, int oflags)
+AuStub(pid_t, au_fhsm_pid, return 0, struct au_fhsm *fhsm)
+AuStubInt0(au_fhsm_br_alloc, struct au_branch *br)
+AuStubVoid(au_fhsm_set_bottom, struct super_block *sb, aufs_bindex_t bindex)
+AuStubVoid(au_fhsm_fin, struct super_block *sb)
+AuStubVoid(au_fhsm_init, struct au_sbinfo *sbinfo)
+AuStubVoid(au_fhsm_set, struct au_sbinfo *sbinfo, unsigned int sec)
+AuStubVoid(au_fhsm_show, struct seq_file *seq, struct au_sbinfo *sbinfo)
+#endif
+
+/* ---------------------------------------------------------------------- */
+
+static inline struct au_sbinfo *au_sbi(struct super_block *sb)
+{
+	return sb->s_fs_info;
+}
+
+/* ---------------------------------------------------------------------- */
+
+#ifdef CONFIG_AUFS_EXPORT
+int au_test_nfsd(void);
+void au_export_init(struct super_block *sb);
+void au_xigen_inc(struct inode *inode);
+int au_xigen_new(struct inode *inode);
+int au_xigen_set(struct super_block *sb, struct file *base);
+void au_xigen_clr(struct super_block *sb);
+
+static inline int au_busy_or_stale(void)
+{
+	if (!au_test_nfsd())
+		return -EBUSY;
+	return -ESTALE;
+}
+#else
+AuStubInt0(au_test_nfsd, void)
+AuStubVoid(au_export_init, struct super_block *sb)
+AuStubVoid(au_xigen_inc, struct inode *inode)
+AuStubInt0(au_xigen_new, struct inode *inode)
+AuStubInt0(au_xigen_set, struct super_block *sb, struct file *base)
+AuStubVoid(au_xigen_clr, struct super_block *sb)
+AuStub(int, au_busy_or_stale, return -EBUSY, void)
+#endif /* CONFIG_AUFS_EXPORT */
+
+/* ---------------------------------------------------------------------- */
+
+#ifdef CONFIG_AUFS_SBILIST
+/* module.c */
+extern struct au_splhead au_sbilist;
+
+static inline void au_sbilist_init(void)
+{
+	au_spl_init(&au_sbilist);
+}
+
+static inline void au_sbilist_add(struct super_block *sb)
+{
+	au_spl_add(&au_sbi(sb)->si_list, &au_sbilist);
+}
+
+static inline void au_sbilist_del(struct super_block *sb)
+{
+	au_spl_del(&au_sbi(sb)->si_list, &au_sbilist);
+}
+
+#ifdef CONFIG_AUFS_MAGIC_SYSRQ
+static inline void au_sbilist_lock(void)
+{
+	spin_lock(&au_sbilist.spin);
+}
+
+static inline void au_sbilist_unlock(void)
+{
+	spin_unlock(&au_sbilist.spin);
+}
+#define AuGFP_SBILIST	GFP_ATOMIC
+#else
+AuStubVoid(au_sbilist_lock, void)
+AuStubVoid(au_sbilist_unlock, void)
+#define AuGFP_SBILIST	GFP_NOFS
+#endif /* CONFIG_AUFS_MAGIC_SYSRQ */
+#else
+AuStubVoid(au_sbilist_init, void)
+AuStubVoid(au_sbilist_add, struct super_block *sb)
+AuStubVoid(au_sbilist_del, struct super_block *sb)
+AuStubVoid(au_sbilist_lock, void)
+AuStubVoid(au_sbilist_unlock, void)
+#define AuGFP_SBILIST	GFP_NOFS
+#endif
+
+/* ---------------------------------------------------------------------- */
+
+static inline void dbgaufs_si_null(struct au_sbinfo *sbinfo)
+{
+	/*
+	 * This function is a dynamic '__init' function actually,
+	 * so the tiny check for si_rwsem is unnecessary.
+	 */
+	/* AuRwMustWriteLock(&sbinfo->si_rwsem); */
+#ifdef CONFIG_DEBUG_FS
+	sbinfo->si_dbgaufs = NULL;
+	sbinfo->si_dbgaufs_plink = NULL;
+	sbinfo->si_dbgaufs_xib = NULL;
+#ifdef CONFIG_AUFS_EXPORT
+	sbinfo->si_dbgaufs_xigen = NULL;
+#endif
+#endif
+}
+
+/* ---------------------------------------------------------------------- */
+
+static inline pid_t si_pid_bit(void)
+{
+	/* the origin of pid is 1, but the bitmap's is 0 */
+	return current->pid - 1;
+}
+
+static inline int si_pid_test(struct super_block *sb)
+{
+	pid_t bit;
+
+	bit = si_pid_bit();
+	if (bit < PID_MAX_DEFAULT)
+		return test_bit(bit, au_sbi(sb)->au_si_pid.bitmap);
+	return si_pid_test_slow(sb);
+}
+
+static inline void si_pid_set(struct super_block *sb)
+{
+	pid_t bit;
+
+	bit = si_pid_bit();
+	if (bit < PID_MAX_DEFAULT) {
+		AuDebugOn(test_bit(bit, au_sbi(sb)->au_si_pid.bitmap));
+		set_bit(bit, au_sbi(sb)->au_si_pid.bitmap);
+		/* smp_mb(); */
+	} else
+		si_pid_set_slow(sb);
+}
+
+static inline void si_pid_clr(struct super_block *sb)
+{
+	pid_t bit;
+
+	bit = si_pid_bit();
+	if (bit < PID_MAX_DEFAULT) {
+		AuDebugOn(!test_bit(bit, au_sbi(sb)->au_si_pid.bitmap));
+		clear_bit(bit, au_sbi(sb)->au_si_pid.bitmap);
+		/* smp_mb(); */
+	} else
+		si_pid_clr_slow(sb);
+}
+
+/* ---------------------------------------------------------------------- */
+
+/* lock superblock. mainly for entry point functions */
+/*
+ * __si_read_lock, __si_write_lock,
+ * __si_read_unlock, __si_write_unlock, __si_downgrade_lock
+ */
+AuSimpleRwsemFuncs(__si, struct super_block *sb, &au_sbi(sb)->si_rwsem);
+
+#define SiMustNoWaiters(sb)	AuRwMustNoWaiters(&au_sbi(sb)->si_rwsem)
+#define SiMustAnyLock(sb)	AuRwMustAnyLock(&au_sbi(sb)->si_rwsem)
+#define SiMustWriteLock(sb)	AuRwMustWriteLock(&au_sbi(sb)->si_rwsem)
+
+static inline void si_noflush_read_lock(struct super_block *sb)
+{
+	__si_read_lock(sb);
+	si_pid_set(sb);
+}
+
+static inline int si_noflush_read_trylock(struct super_block *sb)
+{
+	int locked;
+
+	locked = __si_read_trylock(sb);
+	if (locked)
+		si_pid_set(sb);
+	return locked;
+}
+
+static inline void si_noflush_write_lock(struct super_block *sb)
+{
+	__si_write_lock(sb);
+	si_pid_set(sb);
+}
+
+static inline int si_noflush_write_trylock(struct super_block *sb)
+{
+	int locked;
+
+	locked = __si_write_trylock(sb);
+	if (locked)
+		si_pid_set(sb);
+	return locked;
+}
+
+#if 0 /* reserved */
+static inline int si_read_trylock(struct super_block *sb, int flags)
+{
+	if (au_ftest_lock(flags, FLUSH))
+		au_nwt_flush(&au_sbi(sb)->si_nowait);
+	return si_noflush_read_trylock(sb);
+}
+#endif
+
+static inline void si_read_unlock(struct super_block *sb)
+{
+	si_pid_clr(sb);
+	__si_read_unlock(sb);
+}
+
+#if 0 /* reserved */
+static inline int si_write_trylock(struct super_block *sb, int flags)
+{
+	if (au_ftest_lock(flags, FLUSH))
+		au_nwt_flush(&au_sbi(sb)->si_nowait);
+	return si_noflush_write_trylock(sb);
+}
+#endif
+
+static inline void si_write_unlock(struct super_block *sb)
+{
+	si_pid_clr(sb);
+	__si_write_unlock(sb);
+}
+
+#if 0 /* reserved */
+static inline void si_downgrade_lock(struct super_block *sb)
+{
+	__si_downgrade_lock(sb);
+}
+#endif
+
+/* ---------------------------------------------------------------------- */
+
+static inline aufs_bindex_t au_sbend(struct super_block *sb)
+{
+	SiMustAnyLock(sb);
+	return au_sbi(sb)->si_bend;
+}
+
+static inline unsigned int au_mntflags(struct super_block *sb)
+{
+	SiMustAnyLock(sb);
+	return au_sbi(sb)->si_mntflags;
+}
+
+static inline unsigned int au_sigen(struct super_block *sb)
+{
+	SiMustAnyLock(sb);
+	return au_sbi(sb)->si_generation;
+}
+
+static inline void au_ninodes_inc(struct super_block *sb)
+{
+	atomic_long_inc(&au_sbi(sb)->si_ninodes);
+}
+
+static inline void au_ninodes_dec(struct super_block *sb)
+{
+	AuDebugOn(!atomic_long_read(&au_sbi(sb)->si_ninodes));
+	atomic_long_dec(&au_sbi(sb)->si_ninodes);
+}
+
+static inline void au_nfiles_inc(struct super_block *sb)
+{
+	atomic_long_inc(&au_sbi(sb)->si_nfiles);
+}
+
+static inline void au_nfiles_dec(struct super_block *sb)
+{
+	AuDebugOn(!atomic_long_read(&au_sbi(sb)->si_nfiles));
+	atomic_long_dec(&au_sbi(sb)->si_nfiles);
+}
+
+static inline struct au_branch *au_sbr(struct super_block *sb,
+				       aufs_bindex_t bindex)
+{
+	SiMustAnyLock(sb);
+	return au_sbi(sb)->si_branch[0 + bindex];
+}
+
+static inline void au_xino_brid_set(struct super_block *sb, aufs_bindex_t brid)
+{
+	SiMustWriteLock(sb);
+	au_sbi(sb)->si_xino_brid = brid;
+}
+
+static inline aufs_bindex_t au_xino_brid(struct super_block *sb)
+{
+	SiMustAnyLock(sb);
+	return au_sbi(sb)->si_xino_brid;
+}
+
+#endif /* __KERNEL__ */
+#endif /* __AUFS_SUPER_H__ */
--- /dev/null
+++ zfcpdump-kernel-4.4/fs/aufs/sysaufs.c
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+ *
+ * This program, aufs is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * sysfs interface and lifetime management
+ * they are necessary regardless sysfs is disabled.
+ */
+
+#include <linux/random.h>
+#include "aufs.h"
+
+unsigned long sysaufs_si_mask;
+struct kset *sysaufs_kset;
+
+#define AuSiAttr(_name) { \
+	.attr   = { .name = __stringify(_name), .mode = 0444 },	\
+	.show   = sysaufs_si_##_name,				\
+}
+
+static struct sysaufs_si_attr sysaufs_si_attr_xi_path = AuSiAttr(xi_path);
+struct attribute *sysaufs_si_attrs[] = {
+	&sysaufs_si_attr_xi_path.attr,
+	NULL,
+};
+
+static const struct sysfs_ops au_sbi_ops = {
+	.show   = sysaufs_si_show
+};
+
+static struct kobj_type au_sbi_ktype = {
+	.release	= au_si_free,
+	.sysfs_ops	= &au_sbi_ops,
+	.default_attrs	= sysaufs_si_attrs
+};
+
+/* ---------------------------------------------------------------------- */
+
+int sysaufs_si_init(struct au_sbinfo *sbinfo)
+{
+	int err;
+
+	sbinfo->si_kobj.kset = sysaufs_kset;
+	/* cf. sysaufs_name() */
+	err = kobject_init_and_add
+		(&sbinfo->si_kobj, &au_sbi_ktype, /*&sysaufs_kset->kobj*/NULL,
+		 SysaufsSiNamePrefix "%lx", sysaufs_si_id(sbinfo));
+
+	dbgaufs_si_null(sbinfo);
+	if (!err) {
+		err = dbgaufs_si_init(sbinfo);
+		if (unlikely(err))
+			kobject_put(&sbinfo->si_kobj);
+	}
+	return err;
+}
+
+void sysaufs_fin(void)
+{
+	dbgaufs_fin();
+	sysfs_remove_group(&sysaufs_kset->kobj, sysaufs_attr_group);
+	kset_unregister(sysaufs_kset);
+}
+
+int __init sysaufs_init(void)
+{
+	int err;
+
+	do {
+		get_random_bytes(&sysaufs_si_mask, sizeof(sysaufs_si_mask));
+	} while (!sysaufs_si_mask);
+
+	err = -EINVAL;
+	sysaufs_kset = kset_create_and_add(AUFS_NAME, NULL, fs_kobj);
+	if (unlikely(!sysaufs_kset))
+		goto out;
+	err = PTR_ERR(sysaufs_kset);
+	if (IS_ERR(sysaufs_kset))
+		goto out;
+	err = sysfs_create_group(&sysaufs_kset->kobj, sysaufs_attr_group);
+	if (unlikely(err)) {
+		kset_unregister(sysaufs_kset);
+		goto out;
+	}
+
+	err = dbgaufs_init();
+	if (unlikely(err))
+		sysaufs_fin();
+out:
+	return err;
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/fs/aufs/sysaufs.h
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+ *
+ * This program, aufs is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * sysfs interface and mount lifetime management
+ */
+
+#ifndef __SYSAUFS_H__
+#define __SYSAUFS_H__
+
+#ifdef __KERNEL__
+
+#include <linux/sysfs.h>
+#include "module.h"
+
+struct super_block;
+struct au_sbinfo;
+
+struct sysaufs_si_attr {
+	struct attribute attr;
+	int (*show)(struct seq_file *seq, struct super_block *sb);
+};
+
+/* ---------------------------------------------------------------------- */
+
+/* sysaufs.c */
+extern unsigned long sysaufs_si_mask;
+extern struct kset *sysaufs_kset;
+extern struct attribute *sysaufs_si_attrs[];
+int sysaufs_si_init(struct au_sbinfo *sbinfo);
+int __init sysaufs_init(void);
+void sysaufs_fin(void);
+
+/* ---------------------------------------------------------------------- */
+
+/* some people doesn't like to show a pointer in kernel */
+static inline unsigned long sysaufs_si_id(struct au_sbinfo *sbinfo)
+{
+	return sysaufs_si_mask ^ (unsigned long)sbinfo;
+}
+
+#define SysaufsSiNamePrefix	"si_"
+#define SysaufsSiNameLen	(sizeof(SysaufsSiNamePrefix) + 16)
+static inline void sysaufs_name(struct au_sbinfo *sbinfo, char *name)
+{
+	snprintf(name, SysaufsSiNameLen, SysaufsSiNamePrefix "%lx",
+		 sysaufs_si_id(sbinfo));
+}
+
+struct au_branch;
+#ifdef CONFIG_SYSFS
+/* sysfs.c */
+extern struct attribute_group *sysaufs_attr_group;
+
+int sysaufs_si_xi_path(struct seq_file *seq, struct super_block *sb);
+ssize_t sysaufs_si_show(struct kobject *kobj, struct attribute *attr,
+			 char *buf);
+long au_brinfo_ioctl(struct file *file, unsigned long arg);
+#ifdef CONFIG_COMPAT
+long au_brinfo_compat_ioctl(struct file *file, unsigned long arg);
+#endif
+
+void sysaufs_br_init(struct au_branch *br);
+void sysaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex);
+void sysaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex);
+
+#define sysaufs_brs_init()	do {} while (0)
+
+#else
+#define sysaufs_attr_group	NULL
+
+AuStubInt0(sysaufs_si_xi_path, struct seq_file *seq, struct super_block *sb)
+AuStub(ssize_t, sysaufs_si_show, return 0, struct kobject *kobj,
+       struct attribute *attr, char *buf)
+AuStubVoid(sysaufs_br_init, struct au_branch *br)
+AuStubVoid(sysaufs_brs_add, struct super_block *sb, aufs_bindex_t bindex)
+AuStubVoid(sysaufs_brs_del, struct super_block *sb, aufs_bindex_t bindex)
+
+static inline void sysaufs_brs_init(void)
+{
+	sysaufs_brs = 0;
+}
+
+#endif /* CONFIG_SYSFS */
+
+#endif /* __KERNEL__ */
+#endif /* __SYSAUFS_H__ */
--- /dev/null
+++ zfcpdump-kernel-4.4/fs/aufs/sysfs.c
@@ -0,0 +1,376 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+ *
+ * This program, aufs is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * sysfs interface
+ */
+
+#include <linux/compat.h>
+#include <linux/seq_file.h>
+#include "aufs.h"
+
+#ifdef CONFIG_AUFS_FS_MODULE
+/* this entry violates the "one line per file" policy of sysfs */
+static ssize_t config_show(struct kobject *kobj, struct kobj_attribute *attr,
+			   char *buf)
+{
+	ssize_t err;
+	static char *conf =
+/* this file is generated at compiling */
+#include "conf.str"
+		;
+
+	err = snprintf(buf, PAGE_SIZE, conf);
+	if (unlikely(err >= PAGE_SIZE))
+		err = -EFBIG;
+	return err;
+}
+
+static struct kobj_attribute au_config_attr = __ATTR_RO(config);
+#endif
+
+static struct attribute *au_attr[] = {
+#ifdef CONFIG_AUFS_FS_MODULE
+	&au_config_attr.attr,
+#endif
+	NULL,	/* need to NULL terminate the list of attributes */
+};
+
+static struct attribute_group sysaufs_attr_group_body = {
+	.attrs = au_attr
+};
+
+struct attribute_group *sysaufs_attr_group = &sysaufs_attr_group_body;
+
+/* ---------------------------------------------------------------------- */
+
+int sysaufs_si_xi_path(struct seq_file *seq, struct super_block *sb)
+{
+	int err;
+
+	SiMustAnyLock(sb);
+
+	err = 0;
+	if (au_opt_test(au_mntflags(sb), XINO)) {
+		err = au_xino_path(seq, au_sbi(sb)->si_xib);
+		seq_putc(seq, '\n');
+	}
+	return err;
+}
+
+/*
+ * the lifetime of branch is independent from the entry under sysfs.
+ * sysfs handles the lifetime of the entry, and never call ->show() after it is
+ * unlinked.
+ */
+static int sysaufs_si_br(struct seq_file *seq, struct super_block *sb,
+			 aufs_bindex_t bindex, int idx)
+{
+	int err;
+	struct path path;
+	struct dentry *root;
+	struct au_branch *br;
+	au_br_perm_str_t perm;
+
+	AuDbg("b%d\n", bindex);
+
+	err = 0;
+	root = sb->s_root;
+	di_read_lock_parent(root, !AuLock_IR);
+	br = au_sbr(sb, bindex);
+
+	switch (idx) {
+	case AuBrSysfs_BR:
+		path.mnt = au_br_mnt(br);
+		path.dentry = au_h_dptr(root, bindex);
+		err = au_seq_path(seq, &path);
+		if (!err) {
+			au_optstr_br_perm(&perm, br->br_perm);
+			seq_printf(seq, "=%s\n", perm.a);
+		}
+		break;
+	case AuBrSysfs_BRID:
+		seq_printf(seq, "%d\n", br->br_id);
+		break;
+	}
+	di_read_unlock(root, !AuLock_IR);
+	if (unlikely(err || seq_has_overflowed(seq)))
+		err = -E2BIG;
+
+	return err;
+}
+
+/* ---------------------------------------------------------------------- */
+
+static struct seq_file *au_seq(char *p, ssize_t len)
+{
+	struct seq_file *seq;
+
+	seq = kzalloc(sizeof(*seq), GFP_NOFS);
+	if (seq) {
+		/* mutex_init(&seq.lock); */
+		seq->buf = p;
+		seq->size = len;
+		return seq; /* success */
+	}
+
+	seq = ERR_PTR(-ENOMEM);
+	return seq;
+}
+
+#define SysaufsBr_PREFIX	"br"
+#define SysaufsBrid_PREFIX	"brid"
+
+/* todo: file size may exceed PAGE_SIZE */
+ssize_t sysaufs_si_show(struct kobject *kobj, struct attribute *attr,
+			char *buf)
+{
+	ssize_t err;
+	int idx;
+	long l;
+	aufs_bindex_t bend;
+	struct au_sbinfo *sbinfo;
+	struct super_block *sb;
+	struct seq_file *seq;
+	char *name;
+	struct attribute **cattr;
+
+	sbinfo = container_of(kobj, struct au_sbinfo, si_kobj);
+	sb = sbinfo->si_sb;
+
+	/*
+	 * prevent a race condition between sysfs and aufs.
+	 * for instance, sysfs_file_read() calls sysfs_get_active_two() which
+	 * prohibits maintaining the sysfs entries.
+	 * hew we acquire read lock after sysfs_get_active_two().
+	 * on the other hand, the remount process may maintain the sysfs/aufs
+	 * entries after acquiring write lock.
+	 * it can cause a deadlock.
+	 * simply we gave up processing read here.
+	 */
+	err = -EBUSY;
+	if (unlikely(!si_noflush_read_trylock(sb)))
+		goto out;
+
+	seq = au_seq(buf, PAGE_SIZE);
+	err = PTR_ERR(seq);
+	if (IS_ERR(seq))
+		goto out_unlock;
+
+	name = (void *)attr->name;
+	cattr = sysaufs_si_attrs;
+	while (*cattr) {
+		if (!strcmp(name, (*cattr)->name)) {
+			err = container_of(*cattr, struct sysaufs_si_attr, attr)
+				->show(seq, sb);
+			goto out_seq;
+		}
+		cattr++;
+	}
+
+	if (!strncmp(name, SysaufsBrid_PREFIX,
+		     sizeof(SysaufsBrid_PREFIX) - 1)) {
+		idx = AuBrSysfs_BRID;
+		name += sizeof(SysaufsBrid_PREFIX) - 1;
+	} else if (!strncmp(name, SysaufsBr_PREFIX,
+			    sizeof(SysaufsBr_PREFIX) - 1)) {
+		idx = AuBrSysfs_BR;
+		name += sizeof(SysaufsBr_PREFIX) - 1;
+	} else
+		  BUG();
+
+	err = kstrtol(name, 10, &l);
+	if (!err) {
+		bend = au_sbend(sb);
+		if (l <= bend)
+			err = sysaufs_si_br(seq, sb, (aufs_bindex_t)l, idx);
+		else
+			err = -ENOENT;
+	}
+
+out_seq:
+	if (!err) {
+		err = seq->count;
+		/* sysfs limit */
+		if (unlikely(err == PAGE_SIZE))
+			err = -EFBIG;
+	}
+	kfree(seq);
+out_unlock:
+	si_read_unlock(sb);
+out:
+	return err;
+}
+
+/* ---------------------------------------------------------------------- */
+
+static int au_brinfo(struct super_block *sb, union aufs_brinfo __user *arg)
+{
+	int err;
+	int16_t brid;
+	aufs_bindex_t bindex, bend;
+	size_t sz;
+	char *buf;
+	struct seq_file *seq;
+	struct au_branch *br;
+
+	si_read_lock(sb, AuLock_FLUSH);
+	bend = au_sbend(sb);
+	err = bend + 1;
+	if (!arg)
+		goto out;
+
+	err = -ENOMEM;
+	buf = (void *)__get_free_page(GFP_NOFS);
+	if (unlikely(!buf))
+		goto out;
+
+	seq = au_seq(buf, PAGE_SIZE);
+	err = PTR_ERR(seq);
+	if (IS_ERR(seq))
+		goto out_buf;
+
+	sz = sizeof(*arg) - offsetof(union aufs_brinfo, path);
+	for (bindex = 0; bindex <= bend; bindex++, arg++) {
+		err = !access_ok(VERIFY_WRITE, arg, sizeof(*arg));
+		if (unlikely(err))
+			break;
+
+		br = au_sbr(sb, bindex);
+		brid = br->br_id;
+		BUILD_BUG_ON(sizeof(brid) != sizeof(arg->id));
+		err = __put_user(brid, &arg->id);
+		if (unlikely(err))
+			break;
+
+		BUILD_BUG_ON(sizeof(br->br_perm) != sizeof(arg->perm));
+		err = __put_user(br->br_perm, &arg->perm);
+		if (unlikely(err))
+			break;
+
+		err = au_seq_path(seq, &br->br_path);
+		if (unlikely(err))
+			break;
+		seq_putc(seq, '\0');
+		if (!seq_has_overflowed(seq)) {
+			err = copy_to_user(arg->path, seq->buf, seq->count);
+			seq->count = 0;
+			if (unlikely(err))
+				break;
+		} else {
+			err = -E2BIG;
+			goto out_seq;
+		}
+	}
+	if (unlikely(err))
+		err = -EFAULT;
+
+out_seq:
+	kfree(seq);
+out_buf:
+	free_page((unsigned long)buf);
+out:
+	si_read_unlock(sb);
+	return err;
+}
+
+long au_brinfo_ioctl(struct file *file, unsigned long arg)
+{
+	return au_brinfo(file->f_path.dentry->d_sb, (void __user *)arg);
+}
+
+#ifdef CONFIG_COMPAT
+long au_brinfo_compat_ioctl(struct file *file, unsigned long arg)
+{
+	return au_brinfo(file->f_path.dentry->d_sb, compat_ptr(arg));
+}
+#endif
+
+/* ---------------------------------------------------------------------- */
+
+void sysaufs_br_init(struct au_branch *br)
+{
+	int i;
+	struct au_brsysfs *br_sysfs;
+	struct attribute *attr;
+
+	br_sysfs = br->br_sysfs;
+	for (i = 0; i < ARRAY_SIZE(br->br_sysfs); i++) {
+		attr = &br_sysfs->attr;
+		sysfs_attr_init(attr);
+		attr->name = br_sysfs->name;
+		attr->mode = S_IRUGO;
+		br_sysfs++;
+	}
+}
+
+void sysaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex)
+{
+	struct au_branch *br;
+	struct kobject *kobj;
+	struct au_brsysfs *br_sysfs;
+	int i;
+	aufs_bindex_t bend;
+
+	dbgaufs_brs_del(sb, bindex);
+
+	if (!sysaufs_brs)
+		return;
+
+	kobj = &au_sbi(sb)->si_kobj;
+	bend = au_sbend(sb);
+	for (; bindex <= bend; bindex++) {
+		br = au_sbr(sb, bindex);
+		br_sysfs = br->br_sysfs;
+		for (i = 0; i < ARRAY_SIZE(br->br_sysfs); i++) {
+			sysfs_remove_file(kobj, &br_sysfs->attr);
+			br_sysfs++;
+		}
+	}
+}
+
+void sysaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex)
+{
+	int err, i;
+	aufs_bindex_t bend;
+	struct kobject *kobj;
+	struct au_branch *br;
+	struct au_brsysfs *br_sysfs;
+
+	dbgaufs_brs_add(sb, bindex);
+
+	if (!sysaufs_brs)
+		return;
+
+	kobj = &au_sbi(sb)->si_kobj;
+	bend = au_sbend(sb);
+	for (; bindex <= bend; bindex++) {
+		br = au_sbr(sb, bindex);
+		br_sysfs = br->br_sysfs;
+		snprintf(br_sysfs[AuBrSysfs_BR].name, sizeof(br_sysfs->name),
+			 SysaufsBr_PREFIX "%d", bindex);
+		snprintf(br_sysfs[AuBrSysfs_BRID].name, sizeof(br_sysfs->name),
+			 SysaufsBrid_PREFIX "%d", bindex);
+		for (i = 0; i < ARRAY_SIZE(br->br_sysfs); i++) {
+			err = sysfs_create_file(kobj, &br_sysfs->attr);
+			if (unlikely(err))
+				pr_warn("failed %s under sysfs(%d)\n",
+					br_sysfs->name, err);
+			br_sysfs++;
+		}
+	}
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/fs/aufs/sysrq.c
@@ -0,0 +1,157 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+ *
+ * This program, aufs is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * magic sysrq hanlder
+ */
+
+/* #include <linux/sysrq.h> */
+#include <linux/writeback.h>
+#include "aufs.h"
+
+/* ---------------------------------------------------------------------- */
+
+static void sysrq_sb(struct super_block *sb)
+{
+	char *plevel;
+	struct au_sbinfo *sbinfo;
+	struct file *file;
+	struct au_sphlhead *files;
+	struct au_finfo *finfo;
+
+	plevel = au_plevel;
+	au_plevel = KERN_WARNING;
+
+	/* since we define pr_fmt, call printk directly */
+#define pr(str) printk(KERN_WARNING AUFS_NAME ": " str)
+
+	sbinfo = au_sbi(sb);
+	printk(KERN_WARNING "si=%lx\n", sysaufs_si_id(sbinfo));
+	pr("superblock\n");
+	au_dpri_sb(sb);
+
+#if 0
+	pr("root dentry\n");
+	au_dpri_dentry(sb->s_root);
+	pr("root inode\n");
+	au_dpri_inode(d_inode(sb->s_root));
+#endif
+
+#if 0
+	do {
+		int err, i, j, ndentry;
+		struct au_dcsub_pages dpages;
+		struct au_dpage *dpage;
+
+		err = au_dpages_init(&dpages, GFP_ATOMIC);
+		if (unlikely(err))
+			break;
+		err = au_dcsub_pages(&dpages, sb->s_root, NULL, NULL);
+		if (!err)
+			for (i = 0; i < dpages.ndpage; i++) {
+				dpage = dpages.dpages + i;
+				ndentry = dpage->ndentry;
+				for (j = 0; j < ndentry; j++)
+					au_dpri_dentry(dpage->dentries[j]);
+			}
+		au_dpages_free(&dpages);
+	} while (0);
+#endif
+
+#if 1
+	{
+		struct inode *i;
+
+		pr("isolated inode\n");
+		spin_lock(&sb->s_inode_list_lock);
+		list_for_each_entry(i, &sb->s_inodes, i_sb_list) {
+			spin_lock(&i->i_lock);
+			if (1 || hlist_empty(&i->i_dentry))
+				au_dpri_inode(i);
+			spin_unlock(&i->i_lock);
+		}
+		spin_unlock(&sb->s_inode_list_lock);
+	}
+#endif
+	pr("files\n");
+	files = &au_sbi(sb)->si_files;
+	spin_lock(&files->spin);
+	hlist_for_each_entry(finfo, &files->head, fi_hlist) {
+		umode_t mode;
+
+		file = finfo->fi_file;
+		mode = file_inode(file)->i_mode;
+		if (!special_file(mode))
+			au_dpri_file(file);
+	}
+	spin_unlock(&files->spin);
+	pr("done\n");
+
+#undef pr
+	au_plevel = plevel;
+}
+
+/* ---------------------------------------------------------------------- */
+
+/* module parameter */
+static char *aufs_sysrq_key = "a";
+module_param_named(sysrq, aufs_sysrq_key, charp, S_IRUGO);
+MODULE_PARM_DESC(sysrq, "MagicSysRq key for " AUFS_NAME);
+
+static void au_sysrq(int key __maybe_unused)
+{
+	struct au_sbinfo *sbinfo;
+
+	lockdep_off();
+	au_sbilist_lock();
+	list_for_each_entry(sbinfo, &au_sbilist.head, si_list)
+		sysrq_sb(sbinfo->si_sb);
+	au_sbilist_unlock();
+	lockdep_on();
+}
+
+static struct sysrq_key_op au_sysrq_op = {
+	.handler	= au_sysrq,
+	.help_msg	= "Aufs",
+	.action_msg	= "Aufs",
+	.enable_mask	= SYSRQ_ENABLE_DUMP
+};
+
+/* ---------------------------------------------------------------------- */
+
+int __init au_sysrq_init(void)
+{
+	int err;
+	char key;
+
+	err = -1;
+	key = *aufs_sysrq_key;
+	if ('a' <= key && key <= 'z')
+		err = register_sysrq_key(key, &au_sysrq_op);
+	if (unlikely(err))
+		pr_err("err %d, sysrq=%c\n", err, key);
+	return err;
+}
+
+void au_sysrq_fin(void)
+{
+	int err;
+
+	err = unregister_sysrq_key(*aufs_sysrq_key, &au_sysrq_op);
+	if (unlikely(err))
+		pr_err("err %d (ignored)\n", err);
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/fs/aufs/vdir.c
@@ -0,0 +1,888 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+ *
+ * This program, aufs is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * virtual or vertical directory
+ */
+
+#include "aufs.h"
+
+static unsigned int calc_size(int nlen)
+{
+	return ALIGN(sizeof(struct au_vdir_de) + nlen, sizeof(ino_t));
+}
+
+static int set_deblk_end(union au_vdir_deblk_p *p,
+			 union au_vdir_deblk_p *deblk_end)
+{
+	if (calc_size(0) <= deblk_end->deblk - p->deblk) {
+		p->de->de_str.len = 0;
+		/* smp_mb(); */
+		return 0;
+	}
+	return -1; /* error */
+}
+
+/* returns true or false */
+static int is_deblk_end(union au_vdir_deblk_p *p,
+			union au_vdir_deblk_p *deblk_end)
+{
+	if (calc_size(0) <= deblk_end->deblk - p->deblk)
+		return !p->de->de_str.len;
+	return 1;
+}
+
+static unsigned char *last_deblk(struct au_vdir *vdir)
+{
+	return vdir->vd_deblk[vdir->vd_nblk - 1];
+}
+
+/* ---------------------------------------------------------------------- */
+
+/* estimate the appropriate size for name hash table */
+unsigned int au_rdhash_est(loff_t sz)
+{
+	unsigned int n;
+
+	n = UINT_MAX;
+	sz >>= 10;
+	if (sz < n)
+		n = sz;
+	if (sz < AUFS_RDHASH_DEF)
+		n = AUFS_RDHASH_DEF;
+	/* pr_info("n %u\n", n); */
+	return n;
+}
+
+/*
+ * the allocated memory has to be freed by
+ * au_nhash_wh_free() or au_nhash_de_free().
+ */
+int au_nhash_alloc(struct au_nhash *nhash, unsigned int num_hash, gfp_t gfp)
+{
+	struct hlist_head *head;
+	unsigned int u;
+	size_t sz;
+
+	sz = sizeof(*nhash->nh_head) * num_hash;
+	head = kmalloc(sz, gfp);
+	if (head) {
+		nhash->nh_num = num_hash;
+		nhash->nh_head = head;
+		for (u = 0; u < num_hash; u++)
+			INIT_HLIST_HEAD(head++);
+		return 0; /* success */
+	}
+
+	return -ENOMEM;
+}
+
+static void nhash_count(struct hlist_head *head)
+{
+#if 0
+	unsigned long n;
+	struct hlist_node *pos;
+
+	n = 0;
+	hlist_for_each(pos, head)
+		n++;
+	pr_info("%lu\n", n);
+#endif
+}
+
+static void au_nhash_wh_do_free(struct hlist_head *head)
+{
+	struct au_vdir_wh *pos;
+	struct hlist_node *node;
+
+	hlist_for_each_entry_safe(pos, node, head, wh_hash)
+		kfree(pos);
+}
+
+static void au_nhash_de_do_free(struct hlist_head *head)
+{
+	struct au_vdir_dehstr *pos;
+	struct hlist_node *node;
+
+	hlist_for_each_entry_safe(pos, node, head, hash)
+		au_cache_free_vdir_dehstr(pos);
+}
+
+static void au_nhash_do_free(struct au_nhash *nhash,
+			     void (*free)(struct hlist_head *head))
+{
+	unsigned int n;
+	struct hlist_head *head;
+
+	n = nhash->nh_num;
+	if (!n)
+		return;
+
+	head = nhash->nh_head;
+	while (n-- > 0) {
+		nhash_count(head);
+		free(head++);
+	}
+	kfree(nhash->nh_head);
+}
+
+void au_nhash_wh_free(struct au_nhash *whlist)
+{
+	au_nhash_do_free(whlist, au_nhash_wh_do_free);
+}
+
+static void au_nhash_de_free(struct au_nhash *delist)
+{
+	au_nhash_do_free(delist, au_nhash_de_do_free);
+}
+
+/* ---------------------------------------------------------------------- */
+
+int au_nhash_test_longer_wh(struct au_nhash *whlist, aufs_bindex_t btgt,
+			    int limit)
+{
+	int num;
+	unsigned int u, n;
+	struct hlist_head *head;
+	struct au_vdir_wh *pos;
+
+	num = 0;
+	n = whlist->nh_num;
+	head = whlist->nh_head;
+	for (u = 0; u < n; u++, head++)
+		hlist_for_each_entry(pos, head, wh_hash)
+			if (pos->wh_bindex == btgt && ++num > limit)
+				return 1;
+	return 0;
+}
+
+static struct hlist_head *au_name_hash(struct au_nhash *nhash,
+				       unsigned char *name,
+				       unsigned int len)
+{
+	unsigned int v;
+	/* const unsigned int magic_bit = 12; */
+
+	AuDebugOn(!nhash->nh_num || !nhash->nh_head);
+
+	v = 0;
+	while (len--)
+		v += *name++;
+	/* v = hash_long(v, magic_bit); */
+	v %= nhash->nh_num;
+	return nhash->nh_head + v;
+}
+
+static int au_nhash_test_name(struct au_vdir_destr *str, const char *name,
+			      int nlen)
+{
+	return str->len == nlen && !memcmp(str->name, name, nlen);
+}
+
+/* returns found or not */
+int au_nhash_test_known_wh(struct au_nhash *whlist, char *name, int nlen)
+{
+	struct hlist_head *head;
+	struct au_vdir_wh *pos;
+	struct au_vdir_destr *str;
+
+	head = au_name_hash(whlist, name, nlen);
+	hlist_for_each_entry(pos, head, wh_hash) {
+		str = &pos->wh_str;
+		AuDbg("%.*s\n", str->len, str->name);
+		if (au_nhash_test_name(str, name, nlen))
+			return 1;
+	}
+	return 0;
+}
+
+/* returns found(true) or not */
+static int test_known(struct au_nhash *delist, char *name, int nlen)
+{
+	struct hlist_head *head;
+	struct au_vdir_dehstr *pos;
+	struct au_vdir_destr *str;
+
+	head = au_name_hash(delist, name, nlen);
+	hlist_for_each_entry(pos, head, hash) {
+		str = pos->str;
+		AuDbg("%.*s\n", str->len, str->name);
+		if (au_nhash_test_name(str, name, nlen))
+			return 1;
+	}
+	return 0;
+}
+
+static void au_shwh_init_wh(struct au_vdir_wh *wh, ino_t ino,
+			    unsigned char d_type)
+{
+#ifdef CONFIG_AUFS_SHWH
+	wh->wh_ino = ino;
+	wh->wh_type = d_type;
+#endif
+}
+
+/* ---------------------------------------------------------------------- */
+
+int au_nhash_append_wh(struct au_nhash *whlist, char *name, int nlen, ino_t ino,
+		       unsigned int d_type, aufs_bindex_t bindex,
+		       unsigned char shwh)
+{
+	int err;
+	struct au_vdir_destr *str;
+	struct au_vdir_wh *wh;
+
+	AuDbg("%.*s\n", nlen, name);
+	AuDebugOn(!whlist->nh_num || !whlist->nh_head);
+
+	err = -ENOMEM;
+	wh = kmalloc(sizeof(*wh) + nlen, GFP_NOFS);
+	if (unlikely(!wh))
+		goto out;
+
+	err = 0;
+	wh->wh_bindex = bindex;
+	if (shwh)
+		au_shwh_init_wh(wh, ino, d_type);
+	str = &wh->wh_str;
+	str->len = nlen;
+	memcpy(str->name, name, nlen);
+	hlist_add_head(&wh->wh_hash, au_name_hash(whlist, name, nlen));
+	/* smp_mb(); */
+
+out:
+	return err;
+}
+
+static int append_deblk(struct au_vdir *vdir)
+{
+	int err;
+	unsigned long ul;
+	const unsigned int deblk_sz = vdir->vd_deblk_sz;
+	union au_vdir_deblk_p p, deblk_end;
+	unsigned char **o;
+
+	err = -ENOMEM;
+	o = krealloc(vdir->vd_deblk, sizeof(*o) * (vdir->vd_nblk + 1),
+		     GFP_NOFS);
+	if (unlikely(!o))
+		goto out;
+
+	vdir->vd_deblk = o;
+	p.deblk = kmalloc(deblk_sz, GFP_NOFS);
+	if (p.deblk) {
+		ul = vdir->vd_nblk++;
+		vdir->vd_deblk[ul] = p.deblk;
+		vdir->vd_last.ul = ul;
+		vdir->vd_last.p.deblk = p.deblk;
+		deblk_end.deblk = p.deblk + deblk_sz;
+		err = set_deblk_end(&p, &deblk_end);
+	}
+
+out:
+	return err;
+}
+
+static int append_de(struct au_vdir *vdir, char *name, int nlen, ino_t ino,
+		     unsigned int d_type, struct au_nhash *delist)
+{
+	int err;
+	unsigned int sz;
+	const unsigned int deblk_sz = vdir->vd_deblk_sz;
+	union au_vdir_deblk_p p, *room, deblk_end;
+	struct au_vdir_dehstr *dehstr;
+
+	p.deblk = last_deblk(vdir);
+	deblk_end.deblk = p.deblk + deblk_sz;
+	room = &vdir->vd_last.p;
+	AuDebugOn(room->deblk < p.deblk || deblk_end.deblk <= room->deblk
+		  || !is_deblk_end(room, &deblk_end));
+
+	sz = calc_size(nlen);
+	if (unlikely(sz > deblk_end.deblk - room->deblk)) {
+		err = append_deblk(vdir);
+		if (unlikely(err))
+			goto out;
+
+		p.deblk = last_deblk(vdir);
+		deblk_end.deblk = p.deblk + deblk_sz;
+		/* smp_mb(); */
+		AuDebugOn(room->deblk != p.deblk);
+	}
+
+	err = -ENOMEM;
+	dehstr = au_cache_alloc_vdir_dehstr();
+	if (unlikely(!dehstr))
+		goto out;
+
+	dehstr->str = &room->de->de_str;
+	hlist_add_head(&dehstr->hash, au_name_hash(delist, name, nlen));
+	room->de->de_ino = ino;
+	room->de->de_type = d_type;
+	room->de->de_str.len = nlen;
+	memcpy(room->de->de_str.name, name, nlen);
+
+	err = 0;
+	room->deblk += sz;
+	if (unlikely(set_deblk_end(room, &deblk_end)))
+		err = append_deblk(vdir);
+	/* smp_mb(); */
+
+out:
+	return err;
+}
+
+/* ---------------------------------------------------------------------- */
+
+void au_vdir_free(struct au_vdir *vdir)
+{
+	unsigned char **deblk;
+
+	deblk = vdir->vd_deblk;
+	while (vdir->vd_nblk--)
+		kfree(*deblk++);
+	kfree(vdir->vd_deblk);
+	au_cache_free_vdir(vdir);
+}
+
+static struct au_vdir *alloc_vdir(struct file *file)
+{
+	struct au_vdir *vdir;
+	struct super_block *sb;
+	int err;
+
+	sb = file->f_path.dentry->d_sb;
+	SiMustAnyLock(sb);
+
+	err = -ENOMEM;
+	vdir = au_cache_alloc_vdir();
+	if (unlikely(!vdir))
+		goto out;
+
+	vdir->vd_deblk = kzalloc(sizeof(*vdir->vd_deblk), GFP_NOFS);
+	if (unlikely(!vdir->vd_deblk))
+		goto out_free;
+
+	vdir->vd_deblk_sz = au_sbi(sb)->si_rdblk;
+	if (!vdir->vd_deblk_sz) {
+		/* estimate the appropriate size for deblk */
+		vdir->vd_deblk_sz = au_dir_size(file, /*dentry*/NULL);
+		/* pr_info("vd_deblk_sz %u\n", vdir->vd_deblk_sz); */
+	}
+	vdir->vd_nblk = 0;
+	vdir->vd_version = 0;
+	vdir->vd_jiffy = 0;
+	err = append_deblk(vdir);
+	if (!err)
+		return vdir; /* success */
+
+	kfree(vdir->vd_deblk);
+
+out_free:
+	au_cache_free_vdir(vdir);
+out:
+	vdir = ERR_PTR(err);
+	return vdir;
+}
+
+static int reinit_vdir(struct au_vdir *vdir)
+{
+	int err;
+	union au_vdir_deblk_p p, deblk_end;
+
+	while (vdir->vd_nblk > 1) {
+		kfree(vdir->vd_deblk[vdir->vd_nblk - 1]);
+		/* vdir->vd_deblk[vdir->vd_nblk - 1] = NULL; */
+		vdir->vd_nblk--;
+	}
+	p.deblk = vdir->vd_deblk[0];
+	deblk_end.deblk = p.deblk + vdir->vd_deblk_sz;
+	err = set_deblk_end(&p, &deblk_end);
+	/* keep vd_dblk_sz */
+	vdir->vd_last.ul = 0;
+	vdir->vd_last.p.deblk = vdir->vd_deblk[0];
+	vdir->vd_version = 0;
+	vdir->vd_jiffy = 0;
+	/* smp_mb(); */
+	return err;
+}
+
+/* ---------------------------------------------------------------------- */
+
+#define AuFillVdir_CALLED	1
+#define AuFillVdir_WHABLE	(1 << 1)
+#define AuFillVdir_SHWH		(1 << 2)
+#define au_ftest_fillvdir(flags, name)	((flags) & AuFillVdir_##name)
+#define au_fset_fillvdir(flags, name) \
+	do { (flags) |= AuFillVdir_##name; } while (0)
+#define au_fclr_fillvdir(flags, name) \
+	do { (flags) &= ~AuFillVdir_##name; } while (0)
+
+#ifndef CONFIG_AUFS_SHWH
+#undef AuFillVdir_SHWH
+#define AuFillVdir_SHWH		0
+#endif
+
+struct fillvdir_arg {
+	struct dir_context	ctx;
+	struct file		*file;
+	struct au_vdir		*vdir;
+	struct au_nhash		delist;
+	struct au_nhash		whlist;
+	aufs_bindex_t		bindex;
+	unsigned int		flags;
+	int			err;
+};
+
+static int fillvdir(struct dir_context *ctx, const char *__name, int nlen,
+		    loff_t offset __maybe_unused, u64 h_ino,
+		    unsigned int d_type)
+{
+	struct fillvdir_arg *arg = container_of(ctx, struct fillvdir_arg, ctx);
+	char *name = (void *)__name;
+	struct super_block *sb;
+	ino_t ino;
+	const unsigned char shwh = !!au_ftest_fillvdir(arg->flags, SHWH);
+
+	arg->err = 0;
+	sb = arg->file->f_path.dentry->d_sb;
+	au_fset_fillvdir(arg->flags, CALLED);
+	/* smp_mb(); */
+	if (nlen <= AUFS_WH_PFX_LEN
+	    || memcmp(name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)) {
+		if (test_known(&arg->delist, name, nlen)
+		    || au_nhash_test_known_wh(&arg->whlist, name, nlen))
+			goto out; /* already exists or whiteouted */
+
+		arg->err = au_ino(sb, arg->bindex, h_ino, d_type, &ino);
+		if (!arg->err) {
+			if (unlikely(nlen > AUFS_MAX_NAMELEN))
+				d_type = DT_UNKNOWN;
+			arg->err = append_de(arg->vdir, name, nlen, ino,
+					     d_type, &arg->delist);
+		}
+	} else if (au_ftest_fillvdir(arg->flags, WHABLE)) {
+		name += AUFS_WH_PFX_LEN;
+		nlen -= AUFS_WH_PFX_LEN;
+		if (au_nhash_test_known_wh(&arg->whlist, name, nlen))
+			goto out; /* already whiteouted */
+
+		if (shwh)
+			arg->err = au_wh_ino(sb, arg->bindex, h_ino, d_type,
+					     &ino);
+		if (!arg->err) {
+			if (nlen <= AUFS_MAX_NAMELEN + AUFS_WH_PFX_LEN)
+				d_type = DT_UNKNOWN;
+			arg->err = au_nhash_append_wh
+				(&arg->whlist, name, nlen, ino, d_type,
+				 arg->bindex, shwh);
+		}
+	}
+
+out:
+	if (!arg->err)
+		arg->vdir->vd_jiffy = jiffies;
+	/* smp_mb(); */
+	AuTraceErr(arg->err);
+	return arg->err;
+}
+
+static int au_handle_shwh(struct super_block *sb, struct au_vdir *vdir,
+			  struct au_nhash *whlist, struct au_nhash *delist)
+{
+#ifdef CONFIG_AUFS_SHWH
+	int err;
+	unsigned int nh, u;
+	struct hlist_head *head;
+	struct au_vdir_wh *pos;
+	struct hlist_node *n;
+	char *p, *o;
+	struct au_vdir_destr *destr;
+
+	AuDebugOn(!au_opt_test(au_mntflags(sb), SHWH));
+
+	err = -ENOMEM;
+	o = p = (void *)__get_free_page(GFP_NOFS);
+	if (unlikely(!p))
+		goto out;
+
+	err = 0;
+	nh = whlist->nh_num;
+	memcpy(p, AUFS_WH_PFX, AUFS_WH_PFX_LEN);
+	p += AUFS_WH_PFX_LEN;
+	for (u = 0; u < nh; u++) {
+		head = whlist->nh_head + u;
+		hlist_for_each_entry_safe(pos, n, head, wh_hash) {
+			destr = &pos->wh_str;
+			memcpy(p, destr->name, destr->len);
+			err = append_de(vdir, o, destr->len + AUFS_WH_PFX_LEN,
+					pos->wh_ino, pos->wh_type, delist);
+			if (unlikely(err))
+				break;
+		}
+	}
+
+	free_page((unsigned long)o);
+
+out:
+	AuTraceErr(err);
+	return err;
+#else
+	return 0;
+#endif
+}
+
+static int au_do_read_vdir(struct fillvdir_arg *arg)
+{
+	int err;
+	unsigned int rdhash;
+	loff_t offset;
+	aufs_bindex_t bend, bindex, bstart;
+	unsigned char shwh;
+	struct file *hf, *file;
+	struct super_block *sb;
+
+	file = arg->file;
+	sb = file->f_path.dentry->d_sb;
+	SiMustAnyLock(sb);
+
+	rdhash = au_sbi(sb)->si_rdhash;
+	if (!rdhash)
+		rdhash = au_rdhash_est(au_dir_size(file, /*dentry*/NULL));
+	err = au_nhash_alloc(&arg->delist, rdhash, GFP_NOFS);
+	if (unlikely(err))
+		goto out;
+	err = au_nhash_alloc(&arg->whlist, rdhash, GFP_NOFS);
+	if (unlikely(err))
+		goto out_delist;
+
+	err = 0;
+	arg->flags = 0;
+	shwh = 0;
+	if (au_opt_test(au_mntflags(sb), SHWH)) {
+		shwh = 1;
+		au_fset_fillvdir(arg->flags, SHWH);
+	}
+	bstart = au_fbstart(file);
+	bend = au_fbend_dir(file);
+	for (bindex = bstart; !err && bindex <= bend; bindex++) {
+		hf = au_hf_dir(file, bindex);
+		if (!hf)
+			continue;
+
+		offset = vfsub_llseek(hf, 0, SEEK_SET);
+		err = offset;
+		if (unlikely(offset))
+			break;
+
+		arg->bindex = bindex;
+		au_fclr_fillvdir(arg->flags, WHABLE);
+		if (shwh
+		    || (bindex != bend
+			&& au_br_whable(au_sbr_perm(sb, bindex))))
+			au_fset_fillvdir(arg->flags, WHABLE);
+		do {
+			arg->err = 0;
+			au_fclr_fillvdir(arg->flags, CALLED);
+			/* smp_mb(); */
+			err = vfsub_iterate_dir(hf, &arg->ctx);
+			if (err >= 0)
+				err = arg->err;
+		} while (!err && au_ftest_fillvdir(arg->flags, CALLED));
+
+		/*
+		 * dir_relax() may be good for concurrency, but aufs should not
+		 * use it since it will cause a lockdep problem.
+		 */
+	}
+
+	if (!err && shwh)
+		err = au_handle_shwh(sb, arg->vdir, &arg->whlist, &arg->delist);
+
+	au_nhash_wh_free(&arg->whlist);
+
+out_delist:
+	au_nhash_de_free(&arg->delist);
+out:
+	return err;
+}
+
+static int read_vdir(struct file *file, int may_read)
+{
+	int err;
+	unsigned long expire;
+	unsigned char do_read;
+	struct fillvdir_arg arg = {
+		.ctx = {
+			.actor = fillvdir
+		}
+	};
+	struct inode *inode;
+	struct au_vdir *vdir, *allocated;
+
+	err = 0;
+	inode = file_inode(file);
+	IMustLock(inode);
+	SiMustAnyLock(inode->i_sb);
+
+	allocated = NULL;
+	do_read = 0;
+	expire = au_sbi(inode->i_sb)->si_rdcache;
+	vdir = au_ivdir(inode);
+	if (!vdir) {
+		do_read = 1;
+		vdir = alloc_vdir(file);
+		err = PTR_ERR(vdir);
+		if (IS_ERR(vdir))
+			goto out;
+		err = 0;
+		allocated = vdir;
+	} else if (may_read
+		   && (inode->i_version != vdir->vd_version
+		       || time_after(jiffies, vdir->vd_jiffy + expire))) {
+		do_read = 1;
+		err = reinit_vdir(vdir);
+		if (unlikely(err))
+			goto out;
+	}
+
+	if (!do_read)
+		return 0; /* success */
+
+	arg.file = file;
+	arg.vdir = vdir;
+	err = au_do_read_vdir(&arg);
+	if (!err) {
+		/* file->f_pos = 0; */ /* todo: ctx->pos? */
+		vdir->vd_version = inode->i_version;
+		vdir->vd_last.ul = 0;
+		vdir->vd_last.p.deblk = vdir->vd_deblk[0];
+		if (allocated)
+			au_set_ivdir(inode, allocated);
+	} else if (allocated)
+		au_vdir_free(allocated);
+
+out:
+	return err;
+}
+
+static int copy_vdir(struct au_vdir *tgt, struct au_vdir *src)
+{
+	int err, rerr;
+	unsigned long ul, n;
+	const unsigned int deblk_sz = src->vd_deblk_sz;
+
+	AuDebugOn(tgt->vd_nblk != 1);
+
+	err = -ENOMEM;
+	if (tgt->vd_nblk < src->vd_nblk) {
+		unsigned char **p;
+
+		p = krealloc(tgt->vd_deblk, sizeof(*p) * src->vd_nblk,
+			     GFP_NOFS);
+		if (unlikely(!p))
+			goto out;
+		tgt->vd_deblk = p;
+	}
+
+	if (tgt->vd_deblk_sz != deblk_sz) {
+		unsigned char *p;
+
+		tgt->vd_deblk_sz = deblk_sz;
+		p = krealloc(tgt->vd_deblk[0], deblk_sz, GFP_NOFS);
+		if (unlikely(!p))
+			goto out;
+		tgt->vd_deblk[0] = p;
+	}
+	memcpy(tgt->vd_deblk[0], src->vd_deblk[0], deblk_sz);
+	tgt->vd_version = src->vd_version;
+	tgt->vd_jiffy = src->vd_jiffy;
+
+	n = src->vd_nblk;
+	for (ul = 1; ul < n; ul++) {
+		tgt->vd_deblk[ul] = kmemdup(src->vd_deblk[ul], deblk_sz,
+					    GFP_NOFS);
+		if (unlikely(!tgt->vd_deblk[ul]))
+			goto out;
+		tgt->vd_nblk++;
+	}
+	tgt->vd_nblk = n;
+	tgt->vd_last.ul = tgt->vd_last.ul;
+	tgt->vd_last.p.deblk = tgt->vd_deblk[tgt->vd_last.ul];
+	tgt->vd_last.p.deblk += src->vd_last.p.deblk
+		- src->vd_deblk[src->vd_last.ul];
+	/* smp_mb(); */
+	return 0; /* success */
+
+out:
+	rerr = reinit_vdir(tgt);
+	BUG_ON(rerr);
+	return err;
+}
+
+int au_vdir_init(struct file *file)
+{
+	int err;
+	struct inode *inode;
+	struct au_vdir *vdir_cache, *allocated;
+
+	/* test file->f_pos here instead of ctx->pos */
+	err = read_vdir(file, !file->f_pos);
+	if (unlikely(err))
+		goto out;
+
+	allocated = NULL;
+	vdir_cache = au_fvdir_cache(file);
+	if (!vdir_cache) {
+		vdir_cache = alloc_vdir(file);
+		err = PTR_ERR(vdir_cache);
+		if (IS_ERR(vdir_cache))
+			goto out;
+		allocated = vdir_cache;
+	} else if (!file->f_pos && vdir_cache->vd_version != file->f_version) {
+		/* test file->f_pos here instead of ctx->pos */
+		err = reinit_vdir(vdir_cache);
+		if (unlikely(err))
+			goto out;
+	} else
+		return 0; /* success */
+
+	inode = file_inode(file);
+	err = copy_vdir(vdir_cache, au_ivdir(inode));
+	if (!err) {
+		file->f_version = inode->i_version;
+		if (allocated)
+			au_set_fvdir_cache(file, allocated);
+	} else if (allocated)
+		au_vdir_free(allocated);
+
+out:
+	return err;
+}
+
+static loff_t calc_offset(struct au_vdir *vdir)
+{
+	loff_t offset;
+	union au_vdir_deblk_p p;
+
+	p.deblk = vdir->vd_deblk[vdir->vd_last.ul];
+	offset = vdir->vd_last.p.deblk - p.deblk;
+	offset += vdir->vd_deblk_sz * vdir->vd_last.ul;
+	return offset;
+}
+
+/* returns true or false */
+static int seek_vdir(struct file *file, struct dir_context *ctx)
+{
+	int valid;
+	unsigned int deblk_sz;
+	unsigned long ul, n;
+	loff_t offset;
+	union au_vdir_deblk_p p, deblk_end;
+	struct au_vdir *vdir_cache;
+
+	valid = 1;
+	vdir_cache = au_fvdir_cache(file);
+	offset = calc_offset(vdir_cache);
+	AuDbg("offset %lld\n", offset);
+	if (ctx->pos == offset)
+		goto out;
+
+	vdir_cache->vd_last.ul = 0;
+	vdir_cache->vd_last.p.deblk = vdir_cache->vd_deblk[0];
+	if (!ctx->pos)
+		goto out;
+
+	valid = 0;
+	deblk_sz = vdir_cache->vd_deblk_sz;
+	ul = div64_u64(ctx->pos, deblk_sz);
+	AuDbg("ul %lu\n", ul);
+	if (ul >= vdir_cache->vd_nblk)
+		goto out;
+
+	n = vdir_cache->vd_nblk;
+	for (; ul < n; ul++) {
+		p.deblk = vdir_cache->vd_deblk[ul];
+		deblk_end.deblk = p.deblk + deblk_sz;
+		offset = ul;
+		offset *= deblk_sz;
+		while (!is_deblk_end(&p, &deblk_end) && offset < ctx->pos) {
+			unsigned int l;
+
+			l = calc_size(p.de->de_str.len);
+			offset += l;
+			p.deblk += l;
+		}
+		if (!is_deblk_end(&p, &deblk_end)) {
+			valid = 1;
+			vdir_cache->vd_last.ul = ul;
+			vdir_cache->vd_last.p = p;
+			break;
+		}
+	}
+
+out:
+	/* smp_mb(); */
+	AuTraceErr(!valid);
+	return valid;
+}
+
+int au_vdir_fill_de(struct file *file, struct dir_context *ctx)
+{
+	unsigned int l, deblk_sz;
+	union au_vdir_deblk_p deblk_end;
+	struct au_vdir *vdir_cache;
+	struct au_vdir_de *de;
+
+	vdir_cache = au_fvdir_cache(file);
+	if (!seek_vdir(file, ctx))
+		return 0;
+
+	deblk_sz = vdir_cache->vd_deblk_sz;
+	while (1) {
+		deblk_end.deblk = vdir_cache->vd_deblk[vdir_cache->vd_last.ul];
+		deblk_end.deblk += deblk_sz;
+		while (!is_deblk_end(&vdir_cache->vd_last.p, &deblk_end)) {
+			de = vdir_cache->vd_last.p.de;
+			AuDbg("%.*s, off%lld, i%lu, dt%d\n",
+			      de->de_str.len, de->de_str.name, ctx->pos,
+			      (unsigned long)de->de_ino, de->de_type);
+			if (unlikely(!dir_emit(ctx, de->de_str.name,
+					       de->de_str.len, de->de_ino,
+					       de->de_type))) {
+				/* todo: ignore the error caused by udba? */
+				/* return err; */
+				return 0;
+			}
+
+			l = calc_size(de->de_str.len);
+			vdir_cache->vd_last.p.deblk += l;
+			ctx->pos += l;
+		}
+		if (vdir_cache->vd_last.ul < vdir_cache->vd_nblk - 1) {
+			vdir_cache->vd_last.ul++;
+			vdir_cache->vd_last.p.deblk
+				= vdir_cache->vd_deblk[vdir_cache->vd_last.ul];
+			ctx->pos = deblk_sz * vdir_cache->vd_last.ul;
+			continue;
+		}
+		break;
+	}
+
+	/* smp_mb(); */
+	return 0;
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/fs/aufs/vfsub.c
@@ -0,0 +1,848 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+ *
+ * This program, aufs is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * sub-routines for VFS
+ */
+
+#include <linux/namei.h>
+#include <linux/security.h>
+#include <linux/splice.h>
+#include "aufs.h"
+
+int vfsub_update_h_iattr(struct path *h_path, int *did)
+{
+	int err;
+	struct kstat st;
+	struct super_block *h_sb;
+
+	/* for remote fs, leave work for its getattr or d_revalidate */
+	/* for bad i_attr fs, handle them in aufs_getattr() */
+	/* still some fs may acquire i_mutex. we need to skip them */
+	err = 0;
+	if (!did)
+		did = &err;
+	h_sb = h_path->dentry->d_sb;
+	*did = (!au_test_fs_remote(h_sb) && au_test_fs_refresh_iattr(h_sb));
+	if (*did)
+		err = vfs_getattr(h_path, &st);
+
+	return err;
+}
+
+/* ---------------------------------------------------------------------- */
+
+struct file *vfsub_dentry_open(struct path *path, int flags)
+{
+	struct file *file;
+
+	file = dentry_open(path, flags /* | __FMODE_NONOTIFY */,
+			   current_cred());
+	if (!IS_ERR_OR_NULL(file)
+	    && (file->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ)
+		i_readcount_inc(d_inode(path->dentry));
+
+	return file;
+}
+
+struct file *vfsub_filp_open(const char *path, int oflags, int mode)
+{
+	struct file *file;
+
+	lockdep_off();
+	file = filp_open(path,
+			 oflags /* | __FMODE_NONOTIFY */,
+			 mode);
+	lockdep_on();
+	if (IS_ERR(file))
+		goto out;
+	vfsub_update_h_iattr(&file->f_path, /*did*/NULL); /*ignore*/
+
+out:
+	return file;
+}
+
+/*
+ * Ideally this function should call VFS:do_last() in order to keep all its
+ * checkings. But it is very hard for aufs to regenerate several VFS internal
+ * structure such as nameidata. This is a second (or third) best approach.
+ * cf. linux/fs/namei.c:do_last(), lookup_open() and atomic_open().
+ */
+int vfsub_atomic_open(struct inode *dir, struct dentry *dentry,
+		      struct vfsub_aopen_args *args, struct au_branch *br)
+{
+	int err;
+	struct file *file = args->file;
+	/* copied from linux/fs/namei.c:atomic_open() */
+	struct dentry *const DENTRY_NOT_SET = (void *)-1UL;
+
+	IMustLock(dir);
+	AuDebugOn(!dir->i_op->atomic_open);
+
+	err = au_br_test_oflag(args->open_flag, br);
+	if (unlikely(err))
+		goto out;
+
+	args->file->f_path.dentry = DENTRY_NOT_SET;
+	args->file->f_path.mnt = au_br_mnt(br);
+	err = dir->i_op->atomic_open(dir, dentry, file, args->open_flag,
+				     args->create_mode, args->opened);
+	if (err >= 0) {
+		/* some filesystems don't set FILE_CREATED while succeeded? */
+		if (*args->opened & FILE_CREATED)
+			fsnotify_create(dir, dentry);
+	} else
+		goto out;
+
+
+	if (!err) {
+		/* todo: call VFS:may_open() here */
+		err = open_check_o_direct(file);
+		/* todo: ima_file_check() too? */
+		if (!err && (args->open_flag & __FMODE_EXEC))
+			err = deny_write_access(file);
+		if (unlikely(err))
+			/* note that the file is created and still opened */
+			goto out;
+	}
+
+	atomic_inc(&br->br_count);
+	fsnotify_open(file);
+
+out:
+	return err;
+}
+
+int vfsub_kern_path(const char *name, unsigned int flags, struct path *path)
+{
+	int err;
+
+	err = kern_path(name, flags, path);
+	if (!err && d_is_positive(path->dentry))
+		vfsub_update_h_iattr(path, /*did*/NULL); /*ignore*/
+	return err;
+}
+
+struct dentry *vfsub_lookup_one_len(const char *name, struct dentry *parent,
+				    int len)
+{
+	struct path path = {
+		.mnt = NULL
+	};
+
+	/* VFS checks it too, but by WARN_ON_ONCE() */
+	IMustLock(d_inode(parent));
+
+	path.dentry = lookup_one_len(name, parent, len);
+	if (IS_ERR(path.dentry))
+		goto out;
+	if (d_is_positive(path.dentry))
+		vfsub_update_h_iattr(&path, /*did*/NULL); /*ignore*/
+
+out:
+	AuTraceErrPtr(path.dentry);
+	return path.dentry;
+}
+
+void vfsub_call_lkup_one(void *args)
+{
+	struct vfsub_lkup_one_args *a = args;
+	*a->errp = vfsub_lkup_one(a->name, a->parent);
+}
+
+/* ---------------------------------------------------------------------- */
+
+struct dentry *vfsub_lock_rename(struct dentry *d1, struct au_hinode *hdir1,
+				 struct dentry *d2, struct au_hinode *hdir2)
+{
+	struct dentry *d;
+
+	lockdep_off();
+	d = lock_rename(d1, d2);
+	lockdep_on();
+	au_hn_suspend(hdir1);
+	if (hdir1 != hdir2)
+		au_hn_suspend(hdir2);
+
+	return d;
+}
+
+void vfsub_unlock_rename(struct dentry *d1, struct au_hinode *hdir1,
+			 struct dentry *d2, struct au_hinode *hdir2)
+{
+	au_hn_resume(hdir1);
+	if (hdir1 != hdir2)
+		au_hn_resume(hdir2);
+	lockdep_off();
+	unlock_rename(d1, d2);
+	lockdep_on();
+}
+
+/* ---------------------------------------------------------------------- */
+
+int vfsub_create(struct inode *dir, struct path *path, int mode, bool want_excl)
+{
+	int err;
+	struct dentry *d;
+
+	IMustLock(dir);
+
+	d = path->dentry;
+	path->dentry = d->d_parent;
+	err = security_path_mknod(path, d, mode, 0);
+	path->dentry = d;
+	if (unlikely(err))
+		goto out;
+
+	lockdep_off();
+	err = vfs_create(dir, path->dentry, mode, want_excl);
+	lockdep_on();
+	if (!err) {
+		struct path tmp = *path;
+		int did;
+
+		vfsub_update_h_iattr(&tmp, &did);
+		if (did) {
+			tmp.dentry = path->dentry->d_parent;
+			vfsub_update_h_iattr(&tmp, /*did*/NULL);
+		}
+		/*ignore*/
+	}
+
+out:
+	return err;
+}
+
+int vfsub_symlink(struct inode *dir, struct path *path, const char *symname)
+{
+	int err;
+	struct dentry *d;
+
+	IMustLock(dir);
+
+	d = path->dentry;
+	path->dentry = d->d_parent;
+	err = security_path_symlink(path, d, symname);
+	path->dentry = d;
+	if (unlikely(err))
+		goto out;
+
+	lockdep_off();
+	err = vfs_symlink(dir, path->dentry, symname);
+	lockdep_on();
+	if (!err) {
+		struct path tmp = *path;
+		int did;
+
+		vfsub_update_h_iattr(&tmp, &did);
+		if (did) {
+			tmp.dentry = path->dentry->d_parent;
+			vfsub_update_h_iattr(&tmp, /*did*/NULL);
+		}
+		/*ignore*/
+	}
+
+out:
+	return err;
+}
+
+int vfsub_mknod(struct inode *dir, struct path *path, int mode, dev_t dev)
+{
+	int err;
+	struct dentry *d;
+
+	IMustLock(dir);
+
+	d = path->dentry;
+	path->dentry = d->d_parent;
+	err = security_path_mknod(path, d, mode, new_encode_dev(dev));
+	path->dentry = d;
+	if (unlikely(err))
+		goto out;
+
+	lockdep_off();
+	err = vfs_mknod(dir, path->dentry, mode, dev);
+	lockdep_on();
+	if (!err) {
+		struct path tmp = *path;
+		int did;
+
+		vfsub_update_h_iattr(&tmp, &did);
+		if (did) {
+			tmp.dentry = path->dentry->d_parent;
+			vfsub_update_h_iattr(&tmp, /*did*/NULL);
+		}
+		/*ignore*/
+	}
+
+out:
+	return err;
+}
+
+static int au_test_nlink(struct inode *inode)
+{
+	const unsigned int link_max = UINT_MAX >> 1; /* rough margin */
+
+	if (!au_test_fs_no_limit_nlink(inode->i_sb)
+	    || inode->i_nlink < link_max)
+		return 0;
+	return -EMLINK;
+}
+
+int vfsub_link(struct dentry *src_dentry, struct inode *dir, struct path *path,
+	       struct inode **delegated_inode)
+{
+	int err;
+	struct dentry *d;
+
+	IMustLock(dir);
+
+	err = au_test_nlink(d_inode(src_dentry));
+	if (unlikely(err))
+		return err;
+
+	/* we don't call may_linkat() */
+	d = path->dentry;
+	path->dentry = d->d_parent;
+	err = security_path_link(src_dentry, path, d);
+	path->dentry = d;
+	if (unlikely(err))
+		goto out;
+
+	lockdep_off();
+	err = vfs_link(src_dentry, dir, path->dentry, delegated_inode);
+	lockdep_on();
+	if (!err) {
+		struct path tmp = *path;
+		int did;
+
+		/* fuse has different memory inode for the same inumber */
+		vfsub_update_h_iattr(&tmp, &did);
+		if (did) {
+			tmp.dentry = path->dentry->d_parent;
+			vfsub_update_h_iattr(&tmp, /*did*/NULL);
+			tmp.dentry = src_dentry;
+			vfsub_update_h_iattr(&tmp, /*did*/NULL);
+		}
+		/*ignore*/
+	}
+
+out:
+	return err;
+}
+
+int vfsub_rename(struct inode *src_dir, struct dentry *src_dentry,
+		 struct inode *dir, struct path *path,
+		 struct inode **delegated_inode)
+{
+	int err;
+	struct path tmp = {
+		.mnt	= path->mnt
+	};
+	struct dentry *d;
+
+	IMustLock(dir);
+	IMustLock(src_dir);
+
+	d = path->dentry;
+	path->dentry = d->d_parent;
+	tmp.dentry = src_dentry->d_parent;
+	err = security_path_rename(&tmp, src_dentry, path, d, /*flags*/0);
+	path->dentry = d;
+	if (unlikely(err))
+		goto out;
+
+	lockdep_off();
+	err = vfs_rename(src_dir, src_dentry, dir, path->dentry,
+			 delegated_inode, /*flags*/0);
+	lockdep_on();
+	if (!err) {
+		int did;
+
+		tmp.dentry = d->d_parent;
+		vfsub_update_h_iattr(&tmp, &did);
+		if (did) {
+			tmp.dentry = src_dentry;
+			vfsub_update_h_iattr(&tmp, /*did*/NULL);
+			tmp.dentry = src_dentry->d_parent;
+			vfsub_update_h_iattr(&tmp, /*did*/NULL);
+		}
+		/*ignore*/
+	}
+
+out:
+	return err;
+}
+
+int vfsub_mkdir(struct inode *dir, struct path *path, int mode)
+{
+	int err;
+	struct dentry *d;
+
+	IMustLock(dir);
+
+	d = path->dentry;
+	path->dentry = d->d_parent;
+	err = security_path_mkdir(path, d, mode);
+	path->dentry = d;
+	if (unlikely(err))
+		goto out;
+
+	lockdep_off();
+	err = vfs_mkdir(dir, path->dentry, mode);
+	lockdep_on();
+	if (!err) {
+		struct path tmp = *path;
+		int did;
+
+		vfsub_update_h_iattr(&tmp, &did);
+		if (did) {
+			tmp.dentry = path->dentry->d_parent;
+			vfsub_update_h_iattr(&tmp, /*did*/NULL);
+		}
+		/*ignore*/
+	}
+
+out:
+	return err;
+}
+
+int vfsub_rmdir(struct inode *dir, struct path *path)
+{
+	int err;
+	struct dentry *d;
+
+	IMustLock(dir);
+
+	d = path->dentry;
+	path->dentry = d->d_parent;
+	err = security_path_rmdir(path, d);
+	path->dentry = d;
+	if (unlikely(err))
+		goto out;
+
+	lockdep_off();
+	err = vfs_rmdir(dir, path->dentry);
+	lockdep_on();
+	if (!err) {
+		struct path tmp = {
+			.dentry	= path->dentry->d_parent,
+			.mnt	= path->mnt
+		};
+
+		vfsub_update_h_iattr(&tmp, /*did*/NULL); /*ignore*/
+	}
+
+out:
+	return err;
+}
+
+/* ---------------------------------------------------------------------- */
+
+/* todo: support mmap_sem? */
+ssize_t vfsub_read_u(struct file *file, char __user *ubuf, size_t count,
+		     loff_t *ppos)
+{
+	ssize_t err;
+
+	lockdep_off();
+	err = vfs_read(file, ubuf, count, ppos);
+	lockdep_on();
+	if (err >= 0)
+		vfsub_update_h_iattr(&file->f_path, /*did*/NULL); /*ignore*/
+	return err;
+}
+
+/* todo: kernel_read()? */
+ssize_t vfsub_read_k(struct file *file, void *kbuf, size_t count,
+		     loff_t *ppos)
+{
+	ssize_t err;
+	mm_segment_t oldfs;
+	union {
+		void *k;
+		char __user *u;
+	} buf;
+
+	buf.k = kbuf;
+	oldfs = get_fs();
+	set_fs(KERNEL_DS);
+	err = vfsub_read_u(file, buf.u, count, ppos);
+	set_fs(oldfs);
+	return err;
+}
+
+ssize_t vfsub_write_u(struct file *file, const char __user *ubuf, size_t count,
+		      loff_t *ppos)
+{
+	ssize_t err;
+
+	lockdep_off();
+	err = vfs_write(file, ubuf, count, ppos);
+	lockdep_on();
+	if (err >= 0)
+		vfsub_update_h_iattr(&file->f_path, /*did*/NULL); /*ignore*/
+	return err;
+}
+
+ssize_t vfsub_write_k(struct file *file, void *kbuf, size_t count, loff_t *ppos)
+{
+	ssize_t err;
+	mm_segment_t oldfs;
+	union {
+		void *k;
+		const char __user *u;
+	} buf;
+
+	buf.k = kbuf;
+	oldfs = get_fs();
+	set_fs(KERNEL_DS);
+	err = vfsub_write_u(file, buf.u, count, ppos);
+	set_fs(oldfs);
+	return err;
+}
+
+int vfsub_flush(struct file *file, fl_owner_t id)
+{
+	int err;
+
+	err = 0;
+	if (file->f_op->flush) {
+		if (!au_test_nfs(file->f_path.dentry->d_sb))
+			err = file->f_op->flush(file, id);
+		else {
+			lockdep_off();
+			err = file->f_op->flush(file, id);
+			lockdep_on();
+		}
+		if (!err)
+			vfsub_update_h_iattr(&file->f_path, /*did*/NULL);
+		/*ignore*/
+	}
+	return err;
+}
+
+int vfsub_iterate_dir(struct file *file, struct dir_context *ctx)
+{
+	int err;
+
+	AuDbg("%pD, ctx{%pf, %llu}\n", file, ctx->actor, ctx->pos);
+
+	lockdep_off();
+	err = iterate_dir(file, ctx);
+	lockdep_on();
+	if (err >= 0)
+		vfsub_update_h_iattr(&file->f_path, /*did*/NULL); /*ignore*/
+	return err;
+}
+
+long vfsub_splice_to(struct file *in, loff_t *ppos,
+		     struct pipe_inode_info *pipe, size_t len,
+		     unsigned int flags)
+{
+	long err;
+
+	lockdep_off();
+	err = do_splice_to(in, ppos, pipe, len, flags);
+	lockdep_on();
+	file_accessed(in);
+	if (err >= 0)
+		vfsub_update_h_iattr(&in->f_path, /*did*/NULL); /*ignore*/
+	return err;
+}
+
+long vfsub_splice_from(struct pipe_inode_info *pipe, struct file *out,
+		       loff_t *ppos, size_t len, unsigned int flags)
+{
+	long err;
+
+	lockdep_off();
+	err = do_splice_from(pipe, out, ppos, len, flags);
+	lockdep_on();
+	if (err >= 0)
+		vfsub_update_h_iattr(&out->f_path, /*did*/NULL); /*ignore*/
+	return err;
+}
+
+int vfsub_fsync(struct file *file, struct path *path, int datasync)
+{
+	int err;
+
+	/* file can be NULL */
+	lockdep_off();
+	err = vfs_fsync(file, datasync);
+	lockdep_on();
+	if (!err) {
+		if (!path) {
+			AuDebugOn(!file);
+			path = &file->f_path;
+		}
+		vfsub_update_h_iattr(path, /*did*/NULL); /*ignore*/
+	}
+	return err;
+}
+
+/* cf. open.c:do_sys_truncate() and do_sys_ftruncate() */
+int vfsub_trunc(struct path *h_path, loff_t length, unsigned int attr,
+		struct file *h_file)
+{
+	int err;
+	struct inode *h_inode;
+	struct super_block *h_sb;
+
+	if (!h_file) {
+		err = vfsub_truncate(h_path, length);
+		goto out;
+	}
+
+	h_inode = d_inode(h_path->dentry);
+	h_sb = h_inode->i_sb;
+	lockdep_off();
+	sb_start_write(h_sb);
+	lockdep_on();
+	err = locks_verify_truncate(h_inode, h_file, length);
+	if (!err)
+		err = security_path_truncate(h_path);
+	if (!err) {
+		lockdep_off();
+		err = do_truncate(h_path->dentry, length, attr, h_file);
+		lockdep_on();
+	}
+	lockdep_off();
+	sb_end_write(h_sb);
+	lockdep_on();
+
+out:
+	return err;
+}
+
+/* ---------------------------------------------------------------------- */
+
+struct au_vfsub_mkdir_args {
+	int *errp;
+	struct inode *dir;
+	struct path *path;
+	int mode;
+};
+
+static void au_call_vfsub_mkdir(void *args)
+{
+	struct au_vfsub_mkdir_args *a = args;
+	*a->errp = vfsub_mkdir(a->dir, a->path, a->mode);
+}
+
+int vfsub_sio_mkdir(struct inode *dir, struct path *path, int mode)
+{
+	int err, do_sio, wkq_err;
+
+	do_sio = au_test_h_perm_sio(dir, MAY_EXEC | MAY_WRITE);
+	if (!do_sio) {
+		lockdep_off();
+		err = vfsub_mkdir(dir, path, mode);
+		lockdep_on();
+	} else {
+		struct au_vfsub_mkdir_args args = {
+			.errp	= &err,
+			.dir	= dir,
+			.path	= path,
+			.mode	= mode
+		};
+		wkq_err = au_wkq_wait(au_call_vfsub_mkdir, &args);
+		if (unlikely(wkq_err))
+			err = wkq_err;
+	}
+
+	return err;
+}
+
+struct au_vfsub_rmdir_args {
+	int *errp;
+	struct inode *dir;
+	struct path *path;
+};
+
+static void au_call_vfsub_rmdir(void *args)
+{
+	struct au_vfsub_rmdir_args *a = args;
+	*a->errp = vfsub_rmdir(a->dir, a->path);
+}
+
+int vfsub_sio_rmdir(struct inode *dir, struct path *path)
+{
+	int err, do_sio, wkq_err;
+
+	do_sio = au_test_h_perm_sio(dir, MAY_EXEC | MAY_WRITE);
+	if (!do_sio) {
+		lockdep_off();
+		err = vfsub_rmdir(dir, path);
+		lockdep_on();
+	} else {
+		struct au_vfsub_rmdir_args args = {
+			.errp	= &err,
+			.dir	= dir,
+			.path	= path
+		};
+		wkq_err = au_wkq_wait(au_call_vfsub_rmdir, &args);
+		if (unlikely(wkq_err))
+			err = wkq_err;
+	}
+
+	return err;
+}
+
+/* ---------------------------------------------------------------------- */
+
+struct notify_change_args {
+	int *errp;
+	struct path *path;
+	struct iattr *ia;
+	struct inode **delegated_inode;
+};
+
+static void call_notify_change(void *args)
+{
+	struct notify_change_args *a = args;
+	struct inode *h_inode;
+
+	h_inode = d_inode(a->path->dentry);
+	IMustLock(h_inode);
+
+	*a->errp = -EPERM;
+	if (!IS_IMMUTABLE(h_inode) && !IS_APPEND(h_inode)) {
+		lockdep_off();
+		*a->errp = notify_change(a->path->dentry, a->ia,
+					 a->delegated_inode);
+		lockdep_on();
+		if (!*a->errp)
+			vfsub_update_h_iattr(a->path, /*did*/NULL); /*ignore*/
+	}
+	AuTraceErr(*a->errp);
+}
+
+int vfsub_notify_change(struct path *path, struct iattr *ia,
+			struct inode **delegated_inode)
+{
+	int err;
+	struct notify_change_args args = {
+		.errp			= &err,
+		.path			= path,
+		.ia			= ia,
+		.delegated_inode	= delegated_inode
+	};
+
+	call_notify_change(&args);
+
+	return err;
+}
+
+int vfsub_sio_notify_change(struct path *path, struct iattr *ia,
+			    struct inode **delegated_inode)
+{
+	int err, wkq_err;
+	struct notify_change_args args = {
+		.errp			= &err,
+		.path			= path,
+		.ia			= ia,
+		.delegated_inode	= delegated_inode
+	};
+
+	wkq_err = au_wkq_wait(call_notify_change, &args);
+	if (unlikely(wkq_err))
+		err = wkq_err;
+
+	return err;
+}
+
+/* ---------------------------------------------------------------------- */
+
+struct unlink_args {
+	int *errp;
+	struct inode *dir;
+	struct path *path;
+	struct inode **delegated_inode;
+};
+
+static void call_unlink(void *args)
+{
+	struct unlink_args *a = args;
+	struct dentry *d = a->path->dentry;
+	struct inode *h_inode;
+	const int stop_sillyrename = (au_test_nfs(d->d_sb)
+				      && au_dcount(d) == 1);
+
+	IMustLock(a->dir);
+
+	a->path->dentry = d->d_parent;
+	*a->errp = security_path_unlink(a->path, d);
+	a->path->dentry = d;
+	if (unlikely(*a->errp))
+		return;
+
+	if (!stop_sillyrename)
+		dget(d);
+	h_inode = NULL;
+	if (d_is_positive(d)) {
+		h_inode = d_inode(d);
+		ihold(h_inode);
+	}
+
+	lockdep_off();
+	*a->errp = vfs_unlink(a->dir, d, a->delegated_inode);
+	lockdep_on();
+	if (!*a->errp) {
+		struct path tmp = {
+			.dentry = d->d_parent,
+			.mnt	= a->path->mnt
+		};
+		vfsub_update_h_iattr(&tmp, /*did*/NULL); /*ignore*/
+	}
+
+	if (!stop_sillyrename)
+		dput(d);
+	if (h_inode)
+		iput(h_inode);
+
+	AuTraceErr(*a->errp);
+}
+
+/*
+ * @dir: must be locked.
+ * @dentry: target dentry.
+ */
+int vfsub_unlink(struct inode *dir, struct path *path,
+		 struct inode **delegated_inode, int force)
+{
+	int err;
+	struct unlink_args args = {
+		.errp			= &err,
+		.dir			= dir,
+		.path			= path,
+		.delegated_inode	= delegated_inode
+	};
+
+	if (!force)
+		call_unlink(&args);
+	else {
+		int wkq_err;
+
+		wkq_err = au_wkq_wait(call_unlink, &args);
+		if (unlikely(wkq_err))
+			err = wkq_err;
+	}
+
+	return err;
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/fs/aufs/vfsub.h
@@ -0,0 +1,287 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+ *
+ * This program, aufs is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * sub-routines for VFS
+ */
+
+#ifndef __AUFS_VFSUB_H__
+#define __AUFS_VFSUB_H__
+
+#ifdef __KERNEL__
+
+#include <linux/fs.h>
+#include <linux/mount.h>
+#include <linux/xattr.h>
+#include "debug.h"
+
+/* copied from linux/fs/internal.h */
+/* todo: BAD approach!! */
+extern void __mnt_drop_write(struct vfsmount *);
+extern int open_check_o_direct(struct file *f);
+
+/* ---------------------------------------------------------------------- */
+
+/* lock subclass for lower inode */
+/* default MAX_LOCKDEP_SUBCLASSES(8) is not enough */
+/* reduce? gave up. */
+enum {
+	AuLsc_I_Begin = I_MUTEX_PARENT2, /* 5 */
+	AuLsc_I_PARENT,		/* lower inode, parent first */
+	AuLsc_I_PARENT2,	/* copyup dirs */
+	AuLsc_I_PARENT3,	/* copyup wh */
+	AuLsc_I_CHILD,
+	AuLsc_I_CHILD2,
+	AuLsc_I_End
+};
+
+/* to debug easier, do not make them inlined functions */
+#define MtxMustLock(mtx)	AuDebugOn(!mutex_is_locked(mtx))
+#define IMustLock(i)		MtxMustLock(&(i)->i_mutex)
+
+/* ---------------------------------------------------------------------- */
+
+static inline void vfsub_drop_nlink(struct inode *inode)
+{
+	AuDebugOn(!inode->i_nlink);
+	drop_nlink(inode);
+}
+
+static inline void vfsub_dead_dir(struct inode *inode)
+{
+	AuDebugOn(!S_ISDIR(inode->i_mode));
+	inode->i_flags |= S_DEAD;
+	clear_nlink(inode);
+}
+
+static inline int vfsub_native_ro(struct inode *inode)
+{
+	return (inode->i_sb->s_flags & MS_RDONLY)
+		|| IS_RDONLY(inode)
+		/* || IS_APPEND(inode) */
+		|| IS_IMMUTABLE(inode);
+}
+
+/* ---------------------------------------------------------------------- */
+
+int vfsub_update_h_iattr(struct path *h_path, int *did);
+struct file *vfsub_dentry_open(struct path *path, int flags);
+struct file *vfsub_filp_open(const char *path, int oflags, int mode);
+struct vfsub_aopen_args {
+	struct file	*file;
+	unsigned int	open_flag;
+	umode_t		create_mode;
+	int		*opened;
+};
+struct au_branch;
+int vfsub_atomic_open(struct inode *dir, struct dentry *dentry,
+		      struct vfsub_aopen_args *args, struct au_branch *br);
+int vfsub_kern_path(const char *name, unsigned int flags, struct path *path);
+
+struct dentry *vfsub_lookup_one_len(const char *name, struct dentry *parent,
+				    int len);
+
+struct vfsub_lkup_one_args {
+	struct dentry **errp;
+	struct qstr *name;
+	struct dentry *parent;
+};
+
+static inline struct dentry *vfsub_lkup_one(struct qstr *name,
+					    struct dentry *parent)
+{
+	return vfsub_lookup_one_len(name->name, parent, name->len);
+}
+
+void vfsub_call_lkup_one(void *args);
+
+/* ---------------------------------------------------------------------- */
+
+static inline int vfsub_mnt_want_write(struct vfsmount *mnt)
+{
+	int err;
+
+	lockdep_off();
+	err = mnt_want_write(mnt);
+	lockdep_on();
+	return err;
+}
+
+static inline void vfsub_mnt_drop_write(struct vfsmount *mnt)
+{
+	lockdep_off();
+	mnt_drop_write(mnt);
+	lockdep_on();
+}
+
+#if 0 /* reserved */
+static inline void vfsub_mnt_drop_write_file(struct file *file)
+{
+	lockdep_off();
+	mnt_drop_write_file(file);
+	lockdep_on();
+}
+#endif
+
+/* ---------------------------------------------------------------------- */
+
+struct au_hinode;
+struct dentry *vfsub_lock_rename(struct dentry *d1, struct au_hinode *hdir1,
+				 struct dentry *d2, struct au_hinode *hdir2);
+void vfsub_unlock_rename(struct dentry *d1, struct au_hinode *hdir1,
+			 struct dentry *d2, struct au_hinode *hdir2);
+
+int vfsub_create(struct inode *dir, struct path *path, int mode,
+		 bool want_excl);
+int vfsub_symlink(struct inode *dir, struct path *path,
+		  const char *symname);
+int vfsub_mknod(struct inode *dir, struct path *path, int mode, dev_t dev);
+int vfsub_link(struct dentry *src_dentry, struct inode *dir,
+	       struct path *path, struct inode **delegated_inode);
+int vfsub_rename(struct inode *src_hdir, struct dentry *src_dentry,
+		 struct inode *hdir, struct path *path,
+		 struct inode **delegated_inode);
+int vfsub_mkdir(struct inode *dir, struct path *path, int mode);
+int vfsub_rmdir(struct inode *dir, struct path *path);
+
+/* ---------------------------------------------------------------------- */
+
+ssize_t vfsub_read_u(struct file *file, char __user *ubuf, size_t count,
+		     loff_t *ppos);
+ssize_t vfsub_read_k(struct file *file, void *kbuf, size_t count,
+			loff_t *ppos);
+ssize_t vfsub_write_u(struct file *file, const char __user *ubuf, size_t count,
+		      loff_t *ppos);
+ssize_t vfsub_write_k(struct file *file, void *kbuf, size_t count,
+		      loff_t *ppos);
+int vfsub_flush(struct file *file, fl_owner_t id);
+int vfsub_iterate_dir(struct file *file, struct dir_context *ctx);
+
+static inline loff_t vfsub_f_size_read(struct file *file)
+{
+	return i_size_read(file_inode(file));
+}
+
+static inline unsigned int vfsub_file_flags(struct file *file)
+{
+	unsigned int flags;
+
+	spin_lock(&file->f_lock);
+	flags = file->f_flags;
+	spin_unlock(&file->f_lock);
+
+	return flags;
+}
+
+#if 0 /* reserved */
+static inline void vfsub_file_accessed(struct file *h_file)
+{
+	file_accessed(h_file);
+	vfsub_update_h_iattr(&h_file->f_path, /*did*/NULL); /*ignore*/
+}
+#endif
+
+#if 0 /* reserved */
+static inline void vfsub_touch_atime(struct vfsmount *h_mnt,
+				     struct dentry *h_dentry)
+{
+	struct path h_path = {
+		.dentry	= h_dentry,
+		.mnt	= h_mnt
+	};
+	touch_atime(&h_path);
+	vfsub_update_h_iattr(&h_path, /*did*/NULL); /*ignore*/
+}
+#endif
+
+static inline int vfsub_update_time(struct inode *h_inode, struct timespec *ts,
+				    int flags)
+{
+	return generic_update_time(h_inode, ts, flags);
+	/* no vfsub_update_h_iattr() since we don't have struct path */
+}
+
+long vfsub_splice_to(struct file *in, loff_t *ppos,
+		     struct pipe_inode_info *pipe, size_t len,
+		     unsigned int flags);
+long vfsub_splice_from(struct pipe_inode_info *pipe, struct file *out,
+		       loff_t *ppos, size_t len, unsigned int flags);
+
+static inline long vfsub_truncate(struct path *path, loff_t length)
+{
+	long err;
+
+	lockdep_off();
+	err = vfs_truncate(path, length);
+	lockdep_on();
+	return err;
+}
+
+int vfsub_trunc(struct path *h_path, loff_t length, unsigned int attr,
+		struct file *h_file);
+int vfsub_fsync(struct file *file, struct path *path, int datasync);
+
+/* ---------------------------------------------------------------------- */
+
+static inline loff_t vfsub_llseek(struct file *file, loff_t offset, int origin)
+{
+	loff_t err;
+
+	lockdep_off();
+	err = vfs_llseek(file, offset, origin);
+	lockdep_on();
+	return err;
+}
+
+/* ---------------------------------------------------------------------- */
+
+int vfsub_sio_mkdir(struct inode *dir, struct path *path, int mode);
+int vfsub_sio_rmdir(struct inode *dir, struct path *path);
+int vfsub_sio_notify_change(struct path *path, struct iattr *ia,
+			    struct inode **delegated_inode);
+int vfsub_notify_change(struct path *path, struct iattr *ia,
+			struct inode **delegated_inode);
+int vfsub_unlink(struct inode *dir, struct path *path,
+		 struct inode **delegated_inode, int force);
+
+/* ---------------------------------------------------------------------- */
+
+static inline int vfsub_setxattr(struct dentry *dentry, const char *name,
+				 const void *value, size_t size, int flags)
+{
+	int err;
+
+	lockdep_off();
+	err = vfs_setxattr(dentry, name, value, size, flags);
+	lockdep_on();
+
+	return err;
+}
+
+static inline int vfsub_removexattr(struct dentry *dentry, const char *name)
+{
+	int err;
+
+	lockdep_off();
+	err = vfs_removexattr(dentry, name);
+	lockdep_on();
+
+	return err;
+}
+
+#endif /* __KERNEL__ */
+#endif /* __AUFS_VFSUB_H__ */
--- /dev/null
+++ zfcpdump-kernel-4.4/fs/aufs/wbr_policy.c
@@ -0,0 +1,765 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+ *
+ * This program, aufs is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * policies for selecting one among multiple writable branches
+ */
+
+#include <linux/statfs.h>
+#include "aufs.h"
+
+/* subset of cpup_attr() */
+static noinline_for_stack
+int au_cpdown_attr(struct path *h_path, struct dentry *h_src)
+{
+	int err, sbits;
+	struct iattr ia;
+	struct inode *h_isrc;
+
+	h_isrc = d_inode(h_src);
+	ia.ia_valid = ATTR_FORCE | ATTR_MODE | ATTR_UID | ATTR_GID;
+	ia.ia_mode = h_isrc->i_mode;
+	ia.ia_uid = h_isrc->i_uid;
+	ia.ia_gid = h_isrc->i_gid;
+	sbits = !!(ia.ia_mode & (S_ISUID | S_ISGID));
+	au_cpup_attr_flags(d_inode(h_path->dentry), h_isrc->i_flags);
+	/* no delegation since it is just created */
+	err = vfsub_sio_notify_change(h_path, &ia, /*delegated*/NULL);
+
+	/* is this nfs only? */
+	if (!err && sbits && au_test_nfs(h_path->dentry->d_sb)) {
+		ia.ia_valid = ATTR_FORCE | ATTR_MODE;
+		ia.ia_mode = h_isrc->i_mode;
+		err = vfsub_sio_notify_change(h_path, &ia, /*delegated*/NULL);
+	}
+
+	return err;
+}
+
+#define AuCpdown_PARENT_OPQ	1
+#define AuCpdown_WHED		(1 << 1)
+#define AuCpdown_MADE_DIR	(1 << 2)
+#define AuCpdown_DIROPQ		(1 << 3)
+#define au_ftest_cpdown(flags, name)	((flags) & AuCpdown_##name)
+#define au_fset_cpdown(flags, name) \
+	do { (flags) |= AuCpdown_##name; } while (0)
+#define au_fclr_cpdown(flags, name) \
+	do { (flags) &= ~AuCpdown_##name; } while (0)
+
+static int au_cpdown_dir_opq(struct dentry *dentry, aufs_bindex_t bdst,
+			     unsigned int *flags)
+{
+	int err;
+	struct dentry *opq_dentry;
+
+	opq_dentry = au_diropq_create(dentry, bdst);
+	err = PTR_ERR(opq_dentry);
+	if (IS_ERR(opq_dentry))
+		goto out;
+	dput(opq_dentry);
+	au_fset_cpdown(*flags, DIROPQ);
+
+out:
+	return err;
+}
+
+static int au_cpdown_dir_wh(struct dentry *dentry, struct dentry *h_parent,
+			    struct inode *dir, aufs_bindex_t bdst)
+{
+	int err;
+	struct path h_path;
+	struct au_branch *br;
+
+	br = au_sbr(dentry->d_sb, bdst);
+	h_path.dentry = au_wh_lkup(h_parent, &dentry->d_name, br);
+	err = PTR_ERR(h_path.dentry);
+	if (IS_ERR(h_path.dentry))
+		goto out;
+
+	err = 0;
+	if (d_is_positive(h_path.dentry)) {
+		h_path.mnt = au_br_mnt(br);
+		err = au_wh_unlink_dentry(au_h_iptr(dir, bdst), &h_path,
+					  dentry);
+	}
+	dput(h_path.dentry);
+
+out:
+	return err;
+}
+
+static int au_cpdown_dir(struct dentry *dentry, aufs_bindex_t bdst,
+			 struct au_pin *pin,
+			 struct dentry *h_parent, void *arg)
+{
+	int err, rerr;
+	aufs_bindex_t bopq, bstart;
+	struct path h_path;
+	struct dentry *parent;
+	struct inode *h_dir, *h_inode, *inode, *dir;
+	unsigned int *flags = arg;
+
+	bstart = au_dbstart(dentry);
+	/* dentry is di-locked */
+	parent = dget_parent(dentry);
+	dir = d_inode(parent);
+	h_dir = d_inode(h_parent);
+	AuDebugOn(h_dir != au_h_iptr(dir, bdst));
+	IMustLock(h_dir);
+
+	err = au_lkup_neg(dentry, bdst, /*wh*/0);
+	if (unlikely(err < 0))
+		goto out;
+	h_path.dentry = au_h_dptr(dentry, bdst);
+	h_path.mnt = au_sbr_mnt(dentry->d_sb, bdst);
+	err = vfsub_sio_mkdir(au_h_iptr(dir, bdst), &h_path,
+			      S_IRWXU | S_IRUGO | S_IXUGO);
+	if (unlikely(err))
+		goto out_put;
+	au_fset_cpdown(*flags, MADE_DIR);
+
+	bopq = au_dbdiropq(dentry);
+	au_fclr_cpdown(*flags, WHED);
+	au_fclr_cpdown(*flags, DIROPQ);
+	if (au_dbwh(dentry) == bdst)
+		au_fset_cpdown(*flags, WHED);
+	if (!au_ftest_cpdown(*flags, PARENT_OPQ) && bopq <= bdst)
+		au_fset_cpdown(*flags, PARENT_OPQ);
+	h_inode = d_inode(h_path.dentry);
+	mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD);
+	if (au_ftest_cpdown(*flags, WHED)) {
+		err = au_cpdown_dir_opq(dentry, bdst, flags);
+		if (unlikely(err)) {
+			mutex_unlock(&h_inode->i_mutex);
+			goto out_dir;
+		}
+	}
+
+	err = au_cpdown_attr(&h_path, au_h_dptr(dentry, bstart));
+	mutex_unlock(&h_inode->i_mutex);
+	if (unlikely(err))
+		goto out_opq;
+
+	if (au_ftest_cpdown(*flags, WHED)) {
+		err = au_cpdown_dir_wh(dentry, h_parent, dir, bdst);
+		if (unlikely(err))
+			goto out_opq;
+	}
+
+	inode = d_inode(dentry);
+	if (au_ibend(inode) < bdst)
+		au_set_ibend(inode, bdst);
+	au_set_h_iptr(inode, bdst, au_igrab(h_inode),
+		      au_hi_flags(inode, /*isdir*/1));
+	au_fhsm_wrote(dentry->d_sb, bdst, /*force*/0);
+	goto out; /* success */
+
+	/* revert */
+out_opq:
+	if (au_ftest_cpdown(*flags, DIROPQ)) {
+		mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD);
+		rerr = au_diropq_remove(dentry, bdst);
+		mutex_unlock(&h_inode->i_mutex);
+		if (unlikely(rerr)) {
+			AuIOErr("failed removing diropq for %pd b%d (%d)\n",
+				dentry, bdst, rerr);
+			err = -EIO;
+			goto out;
+		}
+	}
+out_dir:
+	if (au_ftest_cpdown(*flags, MADE_DIR)) {
+		rerr = vfsub_sio_rmdir(au_h_iptr(dir, bdst), &h_path);
+		if (unlikely(rerr)) {
+			AuIOErr("failed removing %pd b%d (%d)\n",
+				dentry, bdst, rerr);
+			err = -EIO;
+		}
+	}
+out_put:
+	au_set_h_dptr(dentry, bdst, NULL);
+	if (au_dbend(dentry) == bdst)
+		au_update_dbend(dentry);
+out:
+	dput(parent);
+	return err;
+}
+
+int au_cpdown_dirs(struct dentry *dentry, aufs_bindex_t bdst)
+{
+	int err;
+	unsigned int flags;
+
+	flags = 0;
+	err = au_cp_dirs(dentry, bdst, au_cpdown_dir, &flags);
+
+	return err;
+}
+
+/* ---------------------------------------------------------------------- */
+
+/* policies for create */
+
+int au_wbr_nonopq(struct dentry *dentry, aufs_bindex_t bindex)
+{
+	int err, i, j, ndentry;
+	aufs_bindex_t bopq;
+	struct au_dcsub_pages dpages;
+	struct au_dpage *dpage;
+	struct dentry **dentries, *parent, *d;
+
+	err = au_dpages_init(&dpages, GFP_NOFS);
+	if (unlikely(err))
+		goto out;
+	parent = dget_parent(dentry);
+	err = au_dcsub_pages_rev_aufs(&dpages, parent, /*do_include*/0);
+	if (unlikely(err))
+		goto out_free;
+
+	err = bindex;
+	for (i = 0; i < dpages.ndpage; i++) {
+		dpage = dpages.dpages + i;
+		dentries = dpage->dentries;
+		ndentry = dpage->ndentry;
+		for (j = 0; j < ndentry; j++) {
+			d = dentries[j];
+			di_read_lock_parent2(d, !AuLock_IR);
+			bopq = au_dbdiropq(d);
+			di_read_unlock(d, !AuLock_IR);
+			if (bopq >= 0 && bopq < err)
+				err = bopq;
+		}
+	}
+
+out_free:
+	dput(parent);
+	au_dpages_free(&dpages);
+out:
+	return err;
+}
+
+static int au_wbr_bu(struct super_block *sb, aufs_bindex_t bindex)
+{
+	for (; bindex >= 0; bindex--)
+		if (!au_br_rdonly(au_sbr(sb, bindex)))
+			return bindex;
+	return -EROFS;
+}
+
+/* top down parent */
+static int au_wbr_create_tdp(struct dentry *dentry,
+			     unsigned int flags __maybe_unused)
+{
+	int err;
+	aufs_bindex_t bstart, bindex;
+	struct super_block *sb;
+	struct dentry *parent, *h_parent;
+
+	sb = dentry->d_sb;
+	bstart = au_dbstart(dentry);
+	err = bstart;
+	if (!au_br_rdonly(au_sbr(sb, bstart)))
+		goto out;
+
+	err = -EROFS;
+	parent = dget_parent(dentry);
+	for (bindex = au_dbstart(parent); bindex < bstart; bindex++) {
+		h_parent = au_h_dptr(parent, bindex);
+		if (!h_parent || d_is_negative(h_parent))
+			continue;
+
+		if (!au_br_rdonly(au_sbr(sb, bindex))) {
+			err = bindex;
+			break;
+		}
+	}
+	dput(parent);
+
+	/* bottom up here */
+	if (unlikely(err < 0)) {
+		err = au_wbr_bu(sb, bstart - 1);
+		if (err >= 0)
+			err = au_wbr_nonopq(dentry, err);
+	}
+
+out:
+	AuDbg("b%d\n", err);
+	return err;
+}
+
+/* ---------------------------------------------------------------------- */
+
+/* an exception for the policy other than tdp */
+static int au_wbr_create_exp(struct dentry *dentry)
+{
+	int err;
+	aufs_bindex_t bwh, bdiropq;
+	struct dentry *parent;
+
+	err = -1;
+	bwh = au_dbwh(dentry);
+	parent = dget_parent(dentry);
+	bdiropq = au_dbdiropq(parent);
+	if (bwh >= 0) {
+		if (bdiropq >= 0)
+			err = min(bdiropq, bwh);
+		else
+			err = bwh;
+		AuDbg("%d\n", err);
+	} else if (bdiropq >= 0) {
+		err = bdiropq;
+		AuDbg("%d\n", err);
+	}
+	dput(parent);
+
+	if (err >= 0)
+		err = au_wbr_nonopq(dentry, err);
+
+	if (err >= 0 && au_br_rdonly(au_sbr(dentry->d_sb, err)))
+		err = -1;
+
+	AuDbg("%d\n", err);
+	return err;
+}
+
+/* ---------------------------------------------------------------------- */
+
+/* round robin */
+static int au_wbr_create_init_rr(struct super_block *sb)
+{
+	int err;
+
+	err = au_wbr_bu(sb, au_sbend(sb));
+	atomic_set(&au_sbi(sb)->si_wbr_rr_next, -err); /* less important */
+	/* smp_mb(); */
+
+	AuDbg("b%d\n", err);
+	return err;
+}
+
+static int au_wbr_create_rr(struct dentry *dentry, unsigned int flags)
+{
+	int err, nbr;
+	unsigned int u;
+	aufs_bindex_t bindex, bend;
+	struct super_block *sb;
+	atomic_t *next;
+
+	err = au_wbr_create_exp(dentry);
+	if (err >= 0)
+		goto out;
+
+	sb = dentry->d_sb;
+	next = &au_sbi(sb)->si_wbr_rr_next;
+	bend = au_sbend(sb);
+	nbr = bend + 1;
+	for (bindex = 0; bindex <= bend; bindex++) {
+		if (!au_ftest_wbr(flags, DIR)) {
+			err = atomic_dec_return(next) + 1;
+			/* modulo for 0 is meaningless */
+			if (unlikely(!err))
+				err = atomic_dec_return(next) + 1;
+		} else
+			err = atomic_read(next);
+		AuDbg("%d\n", err);
+		u = err;
+		err = u % nbr;
+		AuDbg("%d\n", err);
+		if (!au_br_rdonly(au_sbr(sb, err)))
+			break;
+		err = -EROFS;
+	}
+
+	if (err >= 0)
+		err = au_wbr_nonopq(dentry, err);
+
+out:
+	AuDbg("%d\n", err);
+	return err;
+}
+
+/* ---------------------------------------------------------------------- */
+
+/* most free space */
+static void au_mfs(struct dentry *dentry, struct dentry *parent)
+{
+	struct super_block *sb;
+	struct au_branch *br;
+	struct au_wbr_mfs *mfs;
+	struct dentry *h_parent;
+	aufs_bindex_t bindex, bend;
+	int err;
+	unsigned long long b, bavail;
+	struct path h_path;
+	/* reduce the stack usage */
+	struct kstatfs *st;
+
+	st = kmalloc(sizeof(*st), GFP_NOFS);
+	if (unlikely(!st)) {
+		AuWarn1("failed updating mfs(%d), ignored\n", -ENOMEM);
+		return;
+	}
+
+	bavail = 0;
+	sb = dentry->d_sb;
+	mfs = &au_sbi(sb)->si_wbr_mfs;
+	MtxMustLock(&mfs->mfs_lock);
+	mfs->mfs_bindex = -EROFS;
+	mfs->mfsrr_bytes = 0;
+	if (!parent) {
+		bindex = 0;
+		bend = au_sbend(sb);
+	} else {
+		bindex = au_dbstart(parent);
+		bend = au_dbtaildir(parent);
+	}
+
+	for (; bindex <= bend; bindex++) {
+		if (parent) {
+			h_parent = au_h_dptr(parent, bindex);
+			if (!h_parent || d_is_negative(h_parent))
+				continue;
+		}
+		br = au_sbr(sb, bindex);
+		if (au_br_rdonly(br))
+			continue;
+
+		/* sb->s_root for NFS is unreliable */
+		h_path.mnt = au_br_mnt(br);
+		h_path.dentry = h_path.mnt->mnt_root;
+		err = vfs_statfs(&h_path, st);
+		if (unlikely(err)) {
+			AuWarn1("failed statfs, b%d, %d\n", bindex, err);
+			continue;
+		}
+
+		/* when the available size is equal, select the lower one */
+		BUILD_BUG_ON(sizeof(b) < sizeof(st->f_bavail)
+			     || sizeof(b) < sizeof(st->f_bsize));
+		b = st->f_bavail * st->f_bsize;
+		br->br_wbr->wbr_bytes = b;
+		if (b >= bavail) {
+			bavail = b;
+			mfs->mfs_bindex = bindex;
+			mfs->mfs_jiffy = jiffies;
+		}
+	}
+
+	mfs->mfsrr_bytes = bavail;
+	AuDbg("b%d\n", mfs->mfs_bindex);
+	kfree(st);
+}
+
+static int au_wbr_create_mfs(struct dentry *dentry, unsigned int flags)
+{
+	int err;
+	struct dentry *parent;
+	struct super_block *sb;
+	struct au_wbr_mfs *mfs;
+
+	err = au_wbr_create_exp(dentry);
+	if (err >= 0)
+		goto out;
+
+	sb = dentry->d_sb;
+	parent = NULL;
+	if (au_ftest_wbr(flags, PARENT))
+		parent = dget_parent(dentry);
+	mfs = &au_sbi(sb)->si_wbr_mfs;
+	mutex_lock(&mfs->mfs_lock);
+	if (time_after(jiffies, mfs->mfs_jiffy + mfs->mfs_expire)
+	    || mfs->mfs_bindex < 0
+	    || au_br_rdonly(au_sbr(sb, mfs->mfs_bindex)))
+		au_mfs(dentry, parent);
+	mutex_unlock(&mfs->mfs_lock);
+	err = mfs->mfs_bindex;
+	dput(parent);
+
+	if (err >= 0)
+		err = au_wbr_nonopq(dentry, err);
+
+out:
+	AuDbg("b%d\n", err);
+	return err;
+}
+
+static int au_wbr_create_init_mfs(struct super_block *sb)
+{
+	struct au_wbr_mfs *mfs;
+
+	mfs = &au_sbi(sb)->si_wbr_mfs;
+	mutex_init(&mfs->mfs_lock);
+	mfs->mfs_jiffy = 0;
+	mfs->mfs_bindex = -EROFS;
+
+	return 0;
+}
+
+static int au_wbr_create_fin_mfs(struct super_block *sb __maybe_unused)
+{
+	mutex_destroy(&au_sbi(sb)->si_wbr_mfs.mfs_lock);
+	return 0;
+}
+
+/* ---------------------------------------------------------------------- */
+
+/* most free space and then round robin */
+static int au_wbr_create_mfsrr(struct dentry *dentry, unsigned int flags)
+{
+	int err;
+	struct au_wbr_mfs *mfs;
+
+	err = au_wbr_create_mfs(dentry, flags);
+	if (err >= 0) {
+		mfs = &au_sbi(dentry->d_sb)->si_wbr_mfs;
+		mutex_lock(&mfs->mfs_lock);
+		if (mfs->mfsrr_bytes < mfs->mfsrr_watermark)
+			err = au_wbr_create_rr(dentry, flags);
+		mutex_unlock(&mfs->mfs_lock);
+	}
+
+	AuDbg("b%d\n", err);
+	return err;
+}
+
+static int au_wbr_create_init_mfsrr(struct super_block *sb)
+{
+	int err;
+
+	au_wbr_create_init_mfs(sb); /* ignore */
+	err = au_wbr_create_init_rr(sb);
+
+	return err;
+}
+
+/* ---------------------------------------------------------------------- */
+
+/* top down parent and most free space */
+static int au_wbr_create_pmfs(struct dentry *dentry, unsigned int flags)
+{
+	int err, e2;
+	unsigned long long b;
+	aufs_bindex_t bindex, bstart, bend;
+	struct super_block *sb;
+	struct dentry *parent, *h_parent;
+	struct au_branch *br;
+
+	err = au_wbr_create_tdp(dentry, flags);
+	if (unlikely(err < 0))
+		goto out;
+	parent = dget_parent(dentry);
+	bstart = au_dbstart(parent);
+	bend = au_dbtaildir(parent);
+	if (bstart == bend)
+		goto out_parent; /* success */
+
+	e2 = au_wbr_create_mfs(dentry, flags);
+	if (e2 < 0)
+		goto out_parent; /* success */
+
+	/* when the available size is equal, select upper one */
+	sb = dentry->d_sb;
+	br = au_sbr(sb, err);
+	b = br->br_wbr->wbr_bytes;
+	AuDbg("b%d, %llu\n", err, b);
+
+	for (bindex = bstart; bindex <= bend; bindex++) {
+		h_parent = au_h_dptr(parent, bindex);
+		if (!h_parent || d_is_negative(h_parent))
+			continue;
+
+		br = au_sbr(sb, bindex);
+		if (!au_br_rdonly(br) && br->br_wbr->wbr_bytes > b) {
+			b = br->br_wbr->wbr_bytes;
+			err = bindex;
+			AuDbg("b%d, %llu\n", err, b);
+		}
+	}
+
+	if (err >= 0)
+		err = au_wbr_nonopq(dentry, err);
+
+out_parent:
+	dput(parent);
+out:
+	AuDbg("b%d\n", err);
+	return err;
+}
+
+/* ---------------------------------------------------------------------- */
+
+/*
+ * - top down parent
+ * - most free space with parent
+ * - most free space round-robin regardless parent
+ */
+static int au_wbr_create_pmfsrr(struct dentry *dentry, unsigned int flags)
+{
+	int err;
+	unsigned long long watermark;
+	struct super_block *sb;
+	struct au_branch *br;
+	struct au_wbr_mfs *mfs;
+
+	err = au_wbr_create_pmfs(dentry, flags | AuWbr_PARENT);
+	if (unlikely(err < 0))
+		goto out;
+
+	sb = dentry->d_sb;
+	br = au_sbr(sb, err);
+	mfs = &au_sbi(sb)->si_wbr_mfs;
+	mutex_lock(&mfs->mfs_lock);
+	watermark = mfs->mfsrr_watermark;
+	mutex_unlock(&mfs->mfs_lock);
+	if (br->br_wbr->wbr_bytes < watermark)
+		/* regardless the parent dir */
+		err = au_wbr_create_mfsrr(dentry, flags);
+
+out:
+	AuDbg("b%d\n", err);
+	return err;
+}
+
+/* ---------------------------------------------------------------------- */
+
+/* policies for copyup */
+
+/* top down parent */
+static int au_wbr_copyup_tdp(struct dentry *dentry)
+{
+	return au_wbr_create_tdp(dentry, /*flags, anything is ok*/0);
+}
+
+/* bottom up parent */
+static int au_wbr_copyup_bup(struct dentry *dentry)
+{
+	int err;
+	aufs_bindex_t bindex, bstart;
+	struct dentry *parent, *h_parent;
+	struct super_block *sb;
+
+	err = -EROFS;
+	sb = dentry->d_sb;
+	parent = dget_parent(dentry);
+	bstart = au_dbstart(parent);
+	for (bindex = au_dbstart(dentry); bindex >= bstart; bindex--) {
+		h_parent = au_h_dptr(parent, bindex);
+		if (!h_parent || d_is_negative(h_parent))
+			continue;
+
+		if (!au_br_rdonly(au_sbr(sb, bindex))) {
+			err = bindex;
+			break;
+		}
+	}
+	dput(parent);
+
+	/* bottom up here */
+	if (unlikely(err < 0))
+		err = au_wbr_bu(sb, bstart - 1);
+
+	AuDbg("b%d\n", err);
+	return err;
+}
+
+/* bottom up */
+int au_wbr_do_copyup_bu(struct dentry *dentry, aufs_bindex_t bstart)
+{
+	int err;
+
+	err = au_wbr_bu(dentry->d_sb, bstart);
+	AuDbg("b%d\n", err);
+	if (err > bstart)
+		err = au_wbr_nonopq(dentry, err);
+
+	AuDbg("b%d\n", err);
+	return err;
+}
+
+static int au_wbr_copyup_bu(struct dentry *dentry)
+{
+	int err;
+	aufs_bindex_t bstart;
+
+	bstart = au_dbstart(dentry);
+	err = au_wbr_do_copyup_bu(dentry, bstart);
+	return err;
+}
+
+/* ---------------------------------------------------------------------- */
+
+struct au_wbr_copyup_operations au_wbr_copyup_ops[] = {
+	[AuWbrCopyup_TDP] = {
+		.copyup	= au_wbr_copyup_tdp
+	},
+	[AuWbrCopyup_BUP] = {
+		.copyup	= au_wbr_copyup_bup
+	},
+	[AuWbrCopyup_BU] = {
+		.copyup	= au_wbr_copyup_bu
+	}
+};
+
+struct au_wbr_create_operations au_wbr_create_ops[] = {
+	[AuWbrCreate_TDP] = {
+		.create	= au_wbr_create_tdp
+	},
+	[AuWbrCreate_RR] = {
+		.create	= au_wbr_create_rr,
+		.init	= au_wbr_create_init_rr
+	},
+	[AuWbrCreate_MFS] = {
+		.create	= au_wbr_create_mfs,
+		.init	= au_wbr_create_init_mfs,
+		.fin	= au_wbr_create_fin_mfs
+	},
+	[AuWbrCreate_MFSV] = {
+		.create	= au_wbr_create_mfs,
+		.init	= au_wbr_create_init_mfs,
+		.fin	= au_wbr_create_fin_mfs
+	},
+	[AuWbrCreate_MFSRR] = {
+		.create	= au_wbr_create_mfsrr,
+		.init	= au_wbr_create_init_mfsrr,
+		.fin	= au_wbr_create_fin_mfs
+	},
+	[AuWbrCreate_MFSRRV] = {
+		.create	= au_wbr_create_mfsrr,
+		.init	= au_wbr_create_init_mfsrr,
+		.fin	= au_wbr_create_fin_mfs
+	},
+	[AuWbrCreate_PMFS] = {
+		.create	= au_wbr_create_pmfs,
+		.init	= au_wbr_create_init_mfs,
+		.fin	= au_wbr_create_fin_mfs
+	},
+	[AuWbrCreate_PMFSV] = {
+		.create	= au_wbr_create_pmfs,
+		.init	= au_wbr_create_init_mfs,
+		.fin	= au_wbr_create_fin_mfs
+	},
+	[AuWbrCreate_PMFSRR] = {
+		.create	= au_wbr_create_pmfsrr,
+		.init	= au_wbr_create_init_mfsrr,
+		.fin	= au_wbr_create_fin_mfs
+	},
+	[AuWbrCreate_PMFSRRV] = {
+		.create	= au_wbr_create_pmfsrr,
+		.init	= au_wbr_create_init_mfsrr,
+		.fin	= au_wbr_create_fin_mfs
+	}
+};
--- /dev/null
+++ zfcpdump-kernel-4.4/fs/aufs/whout.c
@@ -0,0 +1,1060 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+ *
+ * This program, aufs is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * whiteout for logical deletion and opaque directory
+ */
+
+#include "aufs.h"
+
+#define WH_MASK			S_IRUGO
+
+/*
+ * If a directory contains this file, then it is opaque.  We start with the
+ * .wh. flag so that it is blocked by lookup.
+ */
+static struct qstr diropq_name = QSTR_INIT(AUFS_WH_DIROPQ,
+					   sizeof(AUFS_WH_DIROPQ) - 1);
+
+/*
+ * generate whiteout name, which is NOT terminated by NULL.
+ * @name: original d_name.name
+ * @len: original d_name.len
+ * @wh: whiteout qstr
+ * returns zero when succeeds, otherwise error.
+ * succeeded value as wh->name should be freed by kfree().
+ */
+int au_wh_name_alloc(struct qstr *wh, const struct qstr *name)
+{
+	char *p;
+
+	if (unlikely(name->len > PATH_MAX - AUFS_WH_PFX_LEN))
+		return -ENAMETOOLONG;
+
+	wh->len = name->len + AUFS_WH_PFX_LEN;
+	p = kmalloc(wh->len, GFP_NOFS);
+	wh->name = p;
+	if (p) {
+		memcpy(p, AUFS_WH_PFX, AUFS_WH_PFX_LEN);
+		memcpy(p + AUFS_WH_PFX_LEN, name->name, name->len);
+		/* smp_mb(); */
+		return 0;
+	}
+	return -ENOMEM;
+}
+
+/* ---------------------------------------------------------------------- */
+
+/*
+ * test if the @wh_name exists under @h_parent.
+ * @try_sio specifies the necessary of super-io.
+ */
+int au_wh_test(struct dentry *h_parent, struct qstr *wh_name, int try_sio)
+{
+	int err;
+	struct dentry *wh_dentry;
+
+	if (!try_sio)
+		wh_dentry = vfsub_lkup_one(wh_name, h_parent);
+	else
+		wh_dentry = au_sio_lkup_one(wh_name, h_parent);
+	err = PTR_ERR(wh_dentry);
+	if (IS_ERR(wh_dentry)) {
+		if (err == -ENAMETOOLONG)
+			err = 0;
+		goto out;
+	}
+
+	err = 0;
+	if (d_is_negative(wh_dentry))
+		goto out_wh; /* success */
+
+	err = 1;
+	if (d_is_reg(wh_dentry))
+		goto out_wh; /* success */
+
+	err = -EIO;
+	AuIOErr("%pd Invalid whiteout entry type 0%o.\n",
+		wh_dentry, d_inode(wh_dentry)->i_mode);
+
+out_wh:
+	dput(wh_dentry);
+out:
+	return err;
+}
+
+/*
+ * test if the @h_dentry sets opaque or not.
+ */
+int au_diropq_test(struct dentry *h_dentry)
+{
+	int err;
+	struct inode *h_dir;
+
+	h_dir = d_inode(h_dentry);
+	err = au_wh_test(h_dentry, &diropq_name,
+			 au_test_h_perm_sio(h_dir, MAY_EXEC));
+	return err;
+}
+
+/*
+ * returns a negative dentry whose name is unique and temporary.
+ */
+struct dentry *au_whtmp_lkup(struct dentry *h_parent, struct au_branch *br,
+			     struct qstr *prefix)
+{
+	struct dentry *dentry;
+	int i;
+	char defname[NAME_MAX - AUFS_MAX_NAMELEN + DNAME_INLINE_LEN + 1],
+		*name, *p;
+	/* strict atomic_t is unnecessary here */
+	static unsigned short cnt;
+	struct qstr qs;
+
+	BUILD_BUG_ON(sizeof(cnt) * 2 > AUFS_WH_TMP_LEN);
+
+	name = defname;
+	qs.len = sizeof(defname) - DNAME_INLINE_LEN + prefix->len - 1;
+	if (unlikely(prefix->len > DNAME_INLINE_LEN)) {
+		dentry = ERR_PTR(-ENAMETOOLONG);
+		if (unlikely(qs.len > NAME_MAX))
+			goto out;
+		dentry = ERR_PTR(-ENOMEM);
+		name = kmalloc(qs.len + 1, GFP_NOFS);
+		if (unlikely(!name))
+			goto out;
+	}
+
+	/* doubly whiteout-ed */
+	memcpy(name, AUFS_WH_PFX AUFS_WH_PFX, AUFS_WH_PFX_LEN * 2);
+	p = name + AUFS_WH_PFX_LEN * 2;
+	memcpy(p, prefix->name, prefix->len);
+	p += prefix->len;
+	*p++ = '.';
+	AuDebugOn(name + qs.len + 1 - p <= AUFS_WH_TMP_LEN);
+
+	qs.name = name;
+	for (i = 0; i < 3; i++) {
+		sprintf(p, "%.*x", AUFS_WH_TMP_LEN, cnt++);
+		dentry = au_sio_lkup_one(&qs, h_parent);
+		if (IS_ERR(dentry) || d_is_negative(dentry))
+			goto out_name;
+		dput(dentry);
+	}
+	/* pr_warn("could not get random name\n"); */
+	dentry = ERR_PTR(-EEXIST);
+	AuDbg("%.*s\n", AuLNPair(&qs));
+	BUG();
+
+out_name:
+	if (name != defname)
+		kfree(name);
+out:
+	AuTraceErrPtr(dentry);
+	return dentry;
+}
+
+/*
+ * rename the @h_dentry on @br to the whiteouted temporary name.
+ */
+int au_whtmp_ren(struct dentry *h_dentry, struct au_branch *br)
+{
+	int err;
+	struct path h_path = {
+		.mnt = au_br_mnt(br)
+	};
+	struct inode *h_dir, *delegated;
+	struct dentry *h_parent;
+
+	h_parent = h_dentry->d_parent; /* dir inode is locked */
+	h_dir = d_inode(h_parent);
+	IMustLock(h_dir);
+
+	h_path.dentry = au_whtmp_lkup(h_parent, br, &h_dentry->d_name);
+	err = PTR_ERR(h_path.dentry);
+	if (IS_ERR(h_path.dentry))
+		goto out;
+
+	/* under the same dir, no need to lock_rename() */
+	delegated = NULL;
+	err = vfsub_rename(h_dir, h_dentry, h_dir, &h_path, &delegated);
+	AuTraceErr(err);
+	if (unlikely(err == -EWOULDBLOCK)) {
+		pr_warn("cannot retry for NFSv4 delegation"
+			" for an internal rename\n");
+		iput(delegated);
+	}
+	dput(h_path.dentry);
+
+out:
+	AuTraceErr(err);
+	return err;
+}
+
+/* ---------------------------------------------------------------------- */
+/*
+ * functions for removing a whiteout
+ */
+
+static int do_unlink_wh(struct inode *h_dir, struct path *h_path)
+{
+	int err, force;
+	struct inode *delegated;
+
+	/*
+	 * forces superio when the dir has a sticky bit.
+	 * this may be a violation of unix fs semantics.
+	 */
+	force = (h_dir->i_mode & S_ISVTX)
+		&& !uid_eq(current_fsuid(), d_inode(h_path->dentry)->i_uid);
+	delegated = NULL;
+	err = vfsub_unlink(h_dir, h_path, &delegated, force);
+	if (unlikely(err == -EWOULDBLOCK)) {
+		pr_warn("cannot retry for NFSv4 delegation"
+			" for an internal unlink\n");
+		iput(delegated);
+	}
+	return err;
+}
+
+int au_wh_unlink_dentry(struct inode *h_dir, struct path *h_path,
+			struct dentry *dentry)
+{
+	int err;
+
+	err = do_unlink_wh(h_dir, h_path);
+	if (!err && dentry)
+		au_set_dbwh(dentry, -1);
+
+	return err;
+}
+
+static int unlink_wh_name(struct dentry *h_parent, struct qstr *wh,
+			  struct au_branch *br)
+{
+	int err;
+	struct path h_path = {
+		.mnt = au_br_mnt(br)
+	};
+
+	err = 0;
+	h_path.dentry = vfsub_lkup_one(wh, h_parent);
+	if (IS_ERR(h_path.dentry))
+		err = PTR_ERR(h_path.dentry);
+	else {
+		if (d_is_reg(h_path.dentry))
+			err = do_unlink_wh(d_inode(h_parent), &h_path);
+		dput(h_path.dentry);
+	}
+
+	return err;
+}
+
+/* ---------------------------------------------------------------------- */
+/*
+ * initialize/clean whiteout for a branch
+ */
+
+static void au_wh_clean(struct inode *h_dir, struct path *whpath,
+			const int isdir)
+{
+	int err;
+	struct inode *delegated;
+
+	if (d_is_negative(whpath->dentry))
+		return;
+
+	if (isdir)
+		err = vfsub_rmdir(h_dir, whpath);
+	else {
+		delegated = NULL;
+		err = vfsub_unlink(h_dir, whpath, &delegated, /*force*/0);
+		if (unlikely(err == -EWOULDBLOCK)) {
+			pr_warn("cannot retry for NFSv4 delegation"
+				" for an internal unlink\n");
+			iput(delegated);
+		}
+	}
+	if (unlikely(err))
+		pr_warn("failed removing %pd (%d), ignored.\n",
+			whpath->dentry, err);
+}
+
+static int test_linkable(struct dentry *h_root)
+{
+	struct inode *h_dir = d_inode(h_root);
+
+	if (h_dir->i_op->link)
+		return 0;
+
+	pr_err("%pd (%s) doesn't support link(2), use noplink and rw+nolwh\n",
+	       h_root, au_sbtype(h_root->d_sb));
+	return -ENOSYS;
+}
+
+/* todo: should this mkdir be done in /sbin/mount.aufs helper? */
+static int au_whdir(struct inode *h_dir, struct path *path)
+{
+	int err;
+
+	err = -EEXIST;
+	if (d_is_negative(path->dentry)) {
+		int mode = S_IRWXU;
+
+		if (au_test_nfs(path->dentry->d_sb))
+			mode |= S_IXUGO;
+		err = vfsub_mkdir(h_dir, path, mode);
+	} else if (d_is_dir(path->dentry))
+		err = 0;
+	else
+		pr_err("unknown %pd exists\n", path->dentry);
+
+	return err;
+}
+
+struct au_wh_base {
+	const struct qstr *name;
+	struct dentry *dentry;
+};
+
+static void au_wh_init_ro(struct inode *h_dir, struct au_wh_base base[],
+			  struct path *h_path)
+{
+	h_path->dentry = base[AuBrWh_BASE].dentry;
+	au_wh_clean(h_dir, h_path, /*isdir*/0);
+	h_path->dentry = base[AuBrWh_PLINK].dentry;
+	au_wh_clean(h_dir, h_path, /*isdir*/1);
+	h_path->dentry = base[AuBrWh_ORPH].dentry;
+	au_wh_clean(h_dir, h_path, /*isdir*/1);
+}
+
+/*
+ * returns tri-state,
+ * minus: error, caller should print the message
+ * zero: succuess
+ * plus: error, caller should NOT print the message
+ */
+static int au_wh_init_rw_nolink(struct dentry *h_root, struct au_wbr *wbr,
+				int do_plink, struct au_wh_base base[],
+				struct path *h_path)
+{
+	int err;
+	struct inode *h_dir;
+
+	h_dir = d_inode(h_root);
+	h_path->dentry = base[AuBrWh_BASE].dentry;
+	au_wh_clean(h_dir, h_path, /*isdir*/0);
+	h_path->dentry = base[AuBrWh_PLINK].dentry;
+	if (do_plink) {
+		err = test_linkable(h_root);
+		if (unlikely(err)) {
+			err = 1;
+			goto out;
+		}
+
+		err = au_whdir(h_dir, h_path);
+		if (unlikely(err))
+			goto out;
+		wbr->wbr_plink = dget(base[AuBrWh_PLINK].dentry);
+	} else
+		au_wh_clean(h_dir, h_path, /*isdir*/1);
+	h_path->dentry = base[AuBrWh_ORPH].dentry;
+	err = au_whdir(h_dir, h_path);
+	if (unlikely(err))
+		goto out;
+	wbr->wbr_orph = dget(base[AuBrWh_ORPH].dentry);
+
+out:
+	return err;
+}
+
+/*
+ * for the moment, aufs supports the branch filesystem which does not support
+ * link(2). testing on FAT which does not support i_op->setattr() fully either,
+ * copyup failed. finally, such filesystem will not be used as the writable
+ * branch.
+ *
+ * returns tri-state, see above.
+ */
+static int au_wh_init_rw(struct dentry *h_root, struct au_wbr *wbr,
+			 int do_plink, struct au_wh_base base[],
+			 struct path *h_path)
+{
+	int err;
+	struct inode *h_dir;
+
+	WbrWhMustWriteLock(wbr);
+
+	err = test_linkable(h_root);
+	if (unlikely(err)) {
+		err = 1;
+		goto out;
+	}
+
+	/*
+	 * todo: should this create be done in /sbin/mount.aufs helper?
+	 */
+	err = -EEXIST;
+	h_dir = d_inode(h_root);
+	if (d_is_negative(base[AuBrWh_BASE].dentry)) {
+		h_path->dentry = base[AuBrWh_BASE].dentry;
+		err = vfsub_create(h_dir, h_path, WH_MASK, /*want_excl*/true);
+	} else if (d_is_reg(base[AuBrWh_BASE].dentry))
+		err = 0;
+	else
+		pr_err("unknown %pd2 exists\n", base[AuBrWh_BASE].dentry);
+	if (unlikely(err))
+		goto out;
+
+	h_path->dentry = base[AuBrWh_PLINK].dentry;
+	if (do_plink) {
+		err = au_whdir(h_dir, h_path);
+		if (unlikely(err))
+			goto out;
+		wbr->wbr_plink = dget(base[AuBrWh_PLINK].dentry);
+	} else
+		au_wh_clean(h_dir, h_path, /*isdir*/1);
+	wbr->wbr_whbase = dget(base[AuBrWh_BASE].dentry);
+
+	h_path->dentry = base[AuBrWh_ORPH].dentry;
+	err = au_whdir(h_dir, h_path);
+	if (unlikely(err))
+		goto out;
+	wbr->wbr_orph = dget(base[AuBrWh_ORPH].dentry);
+
+out:
+	return err;
+}
+
+/*
+ * initialize the whiteout base file/dir for @br.
+ */
+int au_wh_init(struct au_branch *br, struct super_block *sb)
+{
+	int err, i;
+	const unsigned char do_plink
+		= !!au_opt_test(au_mntflags(sb), PLINK);
+	struct inode *h_dir;
+	struct path path = br->br_path;
+	struct dentry *h_root = path.dentry;
+	struct au_wbr *wbr = br->br_wbr;
+	static const struct qstr base_name[] = {
+		[AuBrWh_BASE] = QSTR_INIT(AUFS_BASE_NAME,
+					  sizeof(AUFS_BASE_NAME) - 1),
+		[AuBrWh_PLINK] = QSTR_INIT(AUFS_PLINKDIR_NAME,
+					   sizeof(AUFS_PLINKDIR_NAME) - 1),
+		[AuBrWh_ORPH] = QSTR_INIT(AUFS_ORPHDIR_NAME,
+					  sizeof(AUFS_ORPHDIR_NAME) - 1)
+	};
+	struct au_wh_base base[] = {
+		[AuBrWh_BASE] = {
+			.name	= base_name + AuBrWh_BASE,
+			.dentry	= NULL
+		},
+		[AuBrWh_PLINK] = {
+			.name	= base_name + AuBrWh_PLINK,
+			.dentry	= NULL
+		},
+		[AuBrWh_ORPH] = {
+			.name	= base_name + AuBrWh_ORPH,
+			.dentry	= NULL
+		}
+	};
+
+	if (wbr)
+		WbrWhMustWriteLock(wbr);
+
+	for (i = 0; i < AuBrWh_Last; i++) {
+		/* doubly whiteouted */
+		struct dentry *d;
+
+		d = au_wh_lkup(h_root, (void *)base[i].name, br);
+		err = PTR_ERR(d);
+		if (IS_ERR(d))
+			goto out;
+
+		base[i].dentry = d;
+		AuDebugOn(wbr
+			  && wbr->wbr_wh[i]
+			  && wbr->wbr_wh[i] != base[i].dentry);
+	}
+
+	if (wbr)
+		for (i = 0; i < AuBrWh_Last; i++) {
+			dput(wbr->wbr_wh[i]);
+			wbr->wbr_wh[i] = NULL;
+		}
+
+	err = 0;
+	if (!au_br_writable(br->br_perm)) {
+		h_dir = d_inode(h_root);
+		au_wh_init_ro(h_dir, base, &path);
+	} else if (!au_br_wh_linkable(br->br_perm)) {
+		err = au_wh_init_rw_nolink(h_root, wbr, do_plink, base, &path);
+		if (err > 0)
+			goto out;
+		else if (err)
+			goto out_err;
+	} else {
+		err = au_wh_init_rw(h_root, wbr, do_plink, base, &path);
+		if (err > 0)
+			goto out;
+		else if (err)
+			goto out_err;
+	}
+	goto out; /* success */
+
+out_err:
+	pr_err("an error(%d) on the writable branch %pd(%s)\n",
+	       err, h_root, au_sbtype(h_root->d_sb));
+out:
+	for (i = 0; i < AuBrWh_Last; i++)
+		dput(base[i].dentry);
+	return err;
+}
+
+/* ---------------------------------------------------------------------- */
+/*
+ * whiteouts are all hard-linked usually.
+ * when its link count reaches a ceiling, we create a new whiteout base
+ * asynchronously.
+ */
+
+struct reinit_br_wh {
+	struct super_block *sb;
+	struct au_branch *br;
+};
+
+static void reinit_br_wh(void *arg)
+{
+	int err;
+	aufs_bindex_t bindex;
+	struct path h_path;
+	struct reinit_br_wh *a = arg;
+	struct au_wbr *wbr;
+	struct inode *dir, *delegated;
+	struct dentry *h_root;
+	struct au_hinode *hdir;
+
+	err = 0;
+	wbr = a->br->br_wbr;
+	/* big aufs lock */
+	si_noflush_write_lock(a->sb);
+	if (!au_br_writable(a->br->br_perm))
+		goto out;
+	bindex = au_br_index(a->sb, a->br->br_id);
+	if (unlikely(bindex < 0))
+		goto out;
+
+	di_read_lock_parent(a->sb->s_root, AuLock_IR);
+	dir = d_inode(a->sb->s_root);
+	hdir = au_hi(dir, bindex);
+	h_root = au_h_dptr(a->sb->s_root, bindex);
+	AuDebugOn(h_root != au_br_dentry(a->br));
+
+	au_hn_imtx_lock_nested(hdir, AuLsc_I_PARENT);
+	wbr_wh_write_lock(wbr);
+	err = au_h_verify(wbr->wbr_whbase, au_opt_udba(a->sb), hdir->hi_inode,
+			  h_root, a->br);
+	if (!err) {
+		h_path.dentry = wbr->wbr_whbase;
+		h_path.mnt = au_br_mnt(a->br);
+		delegated = NULL;
+		err = vfsub_unlink(hdir->hi_inode, &h_path, &delegated,
+				   /*force*/0);
+		if (unlikely(err == -EWOULDBLOCK)) {
+			pr_warn("cannot retry for NFSv4 delegation"
+				" for an internal unlink\n");
+			iput(delegated);
+		}
+	} else {
+		pr_warn("%pd is moved, ignored\n", wbr->wbr_whbase);
+		err = 0;
+	}
+	dput(wbr->wbr_whbase);
+	wbr->wbr_whbase = NULL;
+	if (!err)
+		err = au_wh_init(a->br, a->sb);
+	wbr_wh_write_unlock(wbr);
+	au_hn_imtx_unlock(hdir);
+	di_read_unlock(a->sb->s_root, AuLock_IR);
+	if (!err)
+		au_fhsm_wrote(a->sb, bindex, /*force*/0);
+
+out:
+	if (wbr)
+		atomic_dec(&wbr->wbr_wh_running);
+	atomic_dec(&a->br->br_count);
+	si_write_unlock(a->sb);
+	au_nwt_done(&au_sbi(a->sb)->si_nowait);
+	kfree(arg);
+	if (unlikely(err))
+		AuIOErr("err %d\n", err);
+}
+
+static void kick_reinit_br_wh(struct super_block *sb, struct au_branch *br)
+{
+	int do_dec, wkq_err;
+	struct reinit_br_wh *arg;
+
+	do_dec = 1;
+	if (atomic_inc_return(&br->br_wbr->wbr_wh_running) != 1)
+		goto out;
+
+	/* ignore ENOMEM */
+	arg = kmalloc(sizeof(*arg), GFP_NOFS);
+	if (arg) {
+		/*
+		 * dec(wh_running), kfree(arg) and dec(br_count)
+		 * in reinit function
+		 */
+		arg->sb = sb;
+		arg->br = br;
+		atomic_inc(&br->br_count);
+		wkq_err = au_wkq_nowait(reinit_br_wh, arg, sb, /*flags*/0);
+		if (unlikely(wkq_err)) {
+			atomic_dec(&br->br_wbr->wbr_wh_running);
+			atomic_dec(&br->br_count);
+			kfree(arg);
+		}
+		do_dec = 0;
+	}
+
+out:
+	if (do_dec)
+		atomic_dec(&br->br_wbr->wbr_wh_running);
+}
+
+/* ---------------------------------------------------------------------- */
+
+/*
+ * create the whiteout @wh.
+ */
+static int link_or_create_wh(struct super_block *sb, aufs_bindex_t bindex,
+			     struct dentry *wh)
+{
+	int err;
+	struct path h_path = {
+		.dentry = wh
+	};
+	struct au_branch *br;
+	struct au_wbr *wbr;
+	struct dentry *h_parent;
+	struct inode *h_dir, *delegated;
+
+	h_parent = wh->d_parent; /* dir inode is locked */
+	h_dir = d_inode(h_parent);
+	IMustLock(h_dir);
+
+	br = au_sbr(sb, bindex);
+	h_path.mnt = au_br_mnt(br);
+	wbr = br->br_wbr;
+	wbr_wh_read_lock(wbr);
+	if (wbr->wbr_whbase) {
+		delegated = NULL;
+		err = vfsub_link(wbr->wbr_whbase, h_dir, &h_path, &delegated);
+		if (unlikely(err == -EWOULDBLOCK)) {
+			pr_warn("cannot retry for NFSv4 delegation"
+				" for an internal link\n");
+			iput(delegated);
+		}
+		if (!err || err != -EMLINK)
+			goto out;
+
+		/* link count full. re-initialize br_whbase. */
+		kick_reinit_br_wh(sb, br);
+	}
+
+	/* return this error in this context */
+	err = vfsub_create(h_dir, &h_path, WH_MASK, /*want_excl*/true);
+	if (!err)
+		au_fhsm_wrote(sb, bindex, /*force*/0);
+
+out:
+	wbr_wh_read_unlock(wbr);
+	return err;
+}
+
+/* ---------------------------------------------------------------------- */
+
+/*
+ * create or remove the diropq.
+ */
+static struct dentry *do_diropq(struct dentry *dentry, aufs_bindex_t bindex,
+				unsigned int flags)
+{
+	struct dentry *opq_dentry, *h_dentry;
+	struct super_block *sb;
+	struct au_branch *br;
+	int err;
+
+	sb = dentry->d_sb;
+	br = au_sbr(sb, bindex);
+	h_dentry = au_h_dptr(dentry, bindex);
+	opq_dentry = vfsub_lkup_one(&diropq_name, h_dentry);
+	if (IS_ERR(opq_dentry))
+		goto out;
+
+	if (au_ftest_diropq(flags, CREATE)) {
+		err = link_or_create_wh(sb, bindex, opq_dentry);
+		if (!err) {
+			au_set_dbdiropq(dentry, bindex);
+			goto out; /* success */
+		}
+	} else {
+		struct path tmp = {
+			.dentry = opq_dentry,
+			.mnt	= au_br_mnt(br)
+		};
+		err = do_unlink_wh(au_h_iptr(d_inode(dentry), bindex), &tmp);
+		if (!err)
+			au_set_dbdiropq(dentry, -1);
+	}
+	dput(opq_dentry);
+	opq_dentry = ERR_PTR(err);
+
+out:
+	return opq_dentry;
+}
+
+struct do_diropq_args {
+	struct dentry **errp;
+	struct dentry *dentry;
+	aufs_bindex_t bindex;
+	unsigned int flags;
+};
+
+static void call_do_diropq(void *args)
+{
+	struct do_diropq_args *a = args;
+	*a->errp = do_diropq(a->dentry, a->bindex, a->flags);
+}
+
+struct dentry *au_diropq_sio(struct dentry *dentry, aufs_bindex_t bindex,
+			     unsigned int flags)
+{
+	struct dentry *diropq, *h_dentry;
+
+	h_dentry = au_h_dptr(dentry, bindex);
+	if (!au_test_h_perm_sio(d_inode(h_dentry), MAY_EXEC | MAY_WRITE))
+		diropq = do_diropq(dentry, bindex, flags);
+	else {
+		int wkq_err;
+		struct do_diropq_args args = {
+			.errp		= &diropq,
+			.dentry		= dentry,
+			.bindex		= bindex,
+			.flags		= flags
+		};
+
+		wkq_err = au_wkq_wait(call_do_diropq, &args);
+		if (unlikely(wkq_err))
+			diropq = ERR_PTR(wkq_err);
+	}
+
+	return diropq;
+}
+
+/* ---------------------------------------------------------------------- */
+
+/*
+ * lookup whiteout dentry.
+ * @h_parent: lower parent dentry which must exist and be locked
+ * @base_name: name of dentry which will be whiteouted
+ * returns dentry for whiteout.
+ */
+struct dentry *au_wh_lkup(struct dentry *h_parent, struct qstr *base_name,
+			  struct au_branch *br)
+{
+	int err;
+	struct qstr wh_name;
+	struct dentry *wh_dentry;
+
+	err = au_wh_name_alloc(&wh_name, base_name);
+	wh_dentry = ERR_PTR(err);
+	if (!err) {
+		wh_dentry = vfsub_lkup_one(&wh_name, h_parent);
+		kfree(wh_name.name);
+	}
+	return wh_dentry;
+}
+
+/*
+ * link/create a whiteout for @dentry on @bindex.
+ */
+struct dentry *au_wh_create(struct dentry *dentry, aufs_bindex_t bindex,
+			    struct dentry *h_parent)
+{
+	struct dentry *wh_dentry;
+	struct super_block *sb;
+	int err;
+
+	sb = dentry->d_sb;
+	wh_dentry = au_wh_lkup(h_parent, &dentry->d_name, au_sbr(sb, bindex));
+	if (!IS_ERR(wh_dentry) && d_is_negative(wh_dentry)) {
+		err = link_or_create_wh(sb, bindex, wh_dentry);
+		if (!err) {
+			au_set_dbwh(dentry, bindex);
+			au_fhsm_wrote(sb, bindex, /*force*/0);
+		} else {
+			dput(wh_dentry);
+			wh_dentry = ERR_PTR(err);
+		}
+	}
+
+	return wh_dentry;
+}
+
+/* ---------------------------------------------------------------------- */
+
+/* Delete all whiteouts in this directory on branch bindex. */
+static int del_wh_children(struct dentry *h_dentry, struct au_nhash *whlist,
+			   aufs_bindex_t bindex, struct au_branch *br)
+{
+	int err;
+	unsigned long ul, n;
+	struct qstr wh_name;
+	char *p;
+	struct hlist_head *head;
+	struct au_vdir_wh *pos;
+	struct au_vdir_destr *str;
+
+	err = -ENOMEM;
+	p = (void *)__get_free_page(GFP_NOFS);
+	wh_name.name = p;
+	if (unlikely(!wh_name.name))
+		goto out;
+
+	err = 0;
+	memcpy(p, AUFS_WH_PFX, AUFS_WH_PFX_LEN);
+	p += AUFS_WH_PFX_LEN;
+	n = whlist->nh_num;
+	head = whlist->nh_head;
+	for (ul = 0; !err && ul < n; ul++, head++) {
+		hlist_for_each_entry(pos, head, wh_hash) {
+			if (pos->wh_bindex != bindex)
+				continue;
+
+			str = &pos->wh_str;
+			if (str->len + AUFS_WH_PFX_LEN <= PATH_MAX) {
+				memcpy(p, str->name, str->len);
+				wh_name.len = AUFS_WH_PFX_LEN + str->len;
+				err = unlink_wh_name(h_dentry, &wh_name, br);
+				if (!err)
+					continue;
+				break;
+			}
+			AuIOErr("whiteout name too long %.*s\n",
+				str->len, str->name);
+			err = -EIO;
+			break;
+		}
+	}
+	free_page((unsigned long)wh_name.name);
+
+out:
+	return err;
+}
+
+struct del_wh_children_args {
+	int *errp;
+	struct dentry *h_dentry;
+	struct au_nhash *whlist;
+	aufs_bindex_t bindex;
+	struct au_branch *br;
+};
+
+static void call_del_wh_children(void *args)
+{
+	struct del_wh_children_args *a = args;
+	*a->errp = del_wh_children(a->h_dentry, a->whlist, a->bindex, a->br);
+}
+
+/* ---------------------------------------------------------------------- */
+
+struct au_whtmp_rmdir *au_whtmp_rmdir_alloc(struct super_block *sb, gfp_t gfp)
+{
+	struct au_whtmp_rmdir *whtmp;
+	int err;
+	unsigned int rdhash;
+
+	SiMustAnyLock(sb);
+
+	whtmp = kzalloc(sizeof(*whtmp), gfp);
+	if (unlikely(!whtmp)) {
+		whtmp = ERR_PTR(-ENOMEM);
+		goto out;
+	}
+
+	/* no estimation for dir size */
+	rdhash = au_sbi(sb)->si_rdhash;
+	if (!rdhash)
+		rdhash = AUFS_RDHASH_DEF;
+	err = au_nhash_alloc(&whtmp->whlist, rdhash, gfp);
+	if (unlikely(err)) {
+		kfree(whtmp);
+		whtmp = ERR_PTR(err);
+	}
+
+out:
+	return whtmp;
+}
+
+void au_whtmp_rmdir_free(struct au_whtmp_rmdir *whtmp)
+{
+	if (whtmp->br)
+		atomic_dec(&whtmp->br->br_count);
+	dput(whtmp->wh_dentry);
+	iput(whtmp->dir);
+	au_nhash_wh_free(&whtmp->whlist);
+	kfree(whtmp);
+}
+
+/*
+ * rmdir the whiteouted temporary named dir @h_dentry.
+ * @whlist: whiteouted children.
+ */
+int au_whtmp_rmdir(struct inode *dir, aufs_bindex_t bindex,
+		   struct dentry *wh_dentry, struct au_nhash *whlist)
+{
+	int err;
+	unsigned int h_nlink;
+	struct path h_tmp;
+	struct inode *wh_inode, *h_dir;
+	struct au_branch *br;
+
+	h_dir = d_inode(wh_dentry->d_parent); /* dir inode is locked */
+	IMustLock(h_dir);
+
+	br = au_sbr(dir->i_sb, bindex);
+	wh_inode = d_inode(wh_dentry);
+	mutex_lock_nested(&wh_inode->i_mutex, AuLsc_I_CHILD);
+
+	/*
+	 * someone else might change some whiteouts while we were sleeping.
+	 * it means this whlist may have an obsoleted entry.
+	 */
+	if (!au_test_h_perm_sio(wh_inode, MAY_EXEC | MAY_WRITE))
+		err = del_wh_children(wh_dentry, whlist, bindex, br);
+	else {
+		int wkq_err;
+		struct del_wh_children_args args = {
+			.errp		= &err,
+			.h_dentry	= wh_dentry,
+			.whlist		= whlist,
+			.bindex		= bindex,
+			.br		= br
+		};
+
+		wkq_err = au_wkq_wait(call_del_wh_children, &args);
+		if (unlikely(wkq_err))
+			err = wkq_err;
+	}
+	mutex_unlock(&wh_inode->i_mutex);
+
+	if (!err) {
+		h_tmp.dentry = wh_dentry;
+		h_tmp.mnt = au_br_mnt(br);
+		h_nlink = h_dir->i_nlink;
+		err = vfsub_rmdir(h_dir, &h_tmp);
+		/* some fs doesn't change the parent nlink in some cases */
+		h_nlink -= h_dir->i_nlink;
+	}
+
+	if (!err) {
+		if (au_ibstart(dir) == bindex) {
+			/* todo: dir->i_mutex is necessary */
+			au_cpup_attr_timesizes(dir);
+			if (h_nlink)
+				vfsub_drop_nlink(dir);
+		}
+		return 0; /* success */
+	}
+
+	pr_warn("failed removing %pd(%d), ignored\n", wh_dentry, err);
+	return err;
+}
+
+static void call_rmdir_whtmp(void *args)
+{
+	int err;
+	aufs_bindex_t bindex;
+	struct au_whtmp_rmdir *a = args;
+	struct super_block *sb;
+	struct dentry *h_parent;
+	struct inode *h_dir;
+	struct au_hinode *hdir;
+
+	/* rmdir by nfsd may cause deadlock with this i_mutex */
+	/* mutex_lock(&a->dir->i_mutex); */
+	err = -EROFS;
+	sb = a->dir->i_sb;
+	si_read_lock(sb, !AuLock_FLUSH);
+	if (!au_br_writable(a->br->br_perm))
+		goto out;
+	bindex = au_br_index(sb, a->br->br_id);
+	if (unlikely(bindex < 0))
+		goto out;
+
+	err = -EIO;
+	ii_write_lock_parent(a->dir);
+	h_parent = dget_parent(a->wh_dentry);
+	h_dir = d_inode(h_parent);
+	hdir = au_hi(a->dir, bindex);
+	err = vfsub_mnt_want_write(au_br_mnt(a->br));
+	if (unlikely(err))
+		goto out_mnt;
+	au_hn_imtx_lock_nested(hdir, AuLsc_I_PARENT);
+	err = au_h_verify(a->wh_dentry, au_opt_udba(sb), h_dir, h_parent,
+			  a->br);
+	if (!err)
+		err = au_whtmp_rmdir(a->dir, bindex, a->wh_dentry, &a->whlist);
+	au_hn_imtx_unlock(hdir);
+	vfsub_mnt_drop_write(au_br_mnt(a->br));
+
+out_mnt:
+	dput(h_parent);
+	ii_write_unlock(a->dir);
+out:
+	/* mutex_unlock(&a->dir->i_mutex); */
+	au_whtmp_rmdir_free(a);
+	si_read_unlock(sb);
+	au_nwt_done(&au_sbi(sb)->si_nowait);
+	if (unlikely(err))
+		AuIOErr("err %d\n", err);
+}
+
+void au_whtmp_kick_rmdir(struct inode *dir, aufs_bindex_t bindex,
+			 struct dentry *wh_dentry, struct au_whtmp_rmdir *args)
+{
+	int wkq_err;
+	struct super_block *sb;
+
+	IMustLock(dir);
+
+	/* all post-process will be done in do_rmdir_whtmp(). */
+	sb = dir->i_sb;
+	args->dir = au_igrab(dir);
+	args->br = au_sbr(sb, bindex);
+	atomic_inc(&args->br->br_count);
+	args->wh_dentry = dget(wh_dentry);
+	wkq_err = au_wkq_nowait(call_rmdir_whtmp, args, sb, /*flags*/0);
+	if (unlikely(wkq_err)) {
+		pr_warn("rmdir error %pd (%d), ignored\n", wh_dentry, wkq_err);
+		au_whtmp_rmdir_free(args);
+	}
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/fs/aufs/whout.h
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+ *
+ * This program, aufs is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * whiteout for logical deletion and opaque directory
+ */
+
+#ifndef __AUFS_WHOUT_H__
+#define __AUFS_WHOUT_H__
+
+#ifdef __KERNEL__
+
+#include "dir.h"
+
+/* whout.c */
+int au_wh_name_alloc(struct qstr *wh, const struct qstr *name);
+int au_wh_test(struct dentry *h_parent, struct qstr *wh_name, int try_sio);
+int au_diropq_test(struct dentry *h_dentry);
+struct au_branch;
+struct dentry *au_whtmp_lkup(struct dentry *h_parent, struct au_branch *br,
+			     struct qstr *prefix);
+int au_whtmp_ren(struct dentry *h_dentry, struct au_branch *br);
+int au_wh_unlink_dentry(struct inode *h_dir, struct path *h_path,
+			struct dentry *dentry);
+int au_wh_init(struct au_branch *br, struct super_block *sb);
+
+/* diropq flags */
+#define AuDiropq_CREATE	1
+#define au_ftest_diropq(flags, name)	((flags) & AuDiropq_##name)
+#define au_fset_diropq(flags, name) \
+	do { (flags) |= AuDiropq_##name; } while (0)
+#define au_fclr_diropq(flags, name) \
+	do { (flags) &= ~AuDiropq_##name; } while (0)
+
+struct dentry *au_diropq_sio(struct dentry *dentry, aufs_bindex_t bindex,
+			     unsigned int flags);
+struct dentry *au_wh_lkup(struct dentry *h_parent, struct qstr *base_name,
+			  struct au_branch *br);
+struct dentry *au_wh_create(struct dentry *dentry, aufs_bindex_t bindex,
+			    struct dentry *h_parent);
+
+/* real rmdir for the whiteout-ed dir */
+struct au_whtmp_rmdir {
+	struct inode *dir;
+	struct au_branch *br;
+	struct dentry *wh_dentry;
+	struct au_nhash whlist;
+};
+
+struct au_whtmp_rmdir *au_whtmp_rmdir_alloc(struct super_block *sb, gfp_t gfp);
+void au_whtmp_rmdir_free(struct au_whtmp_rmdir *whtmp);
+int au_whtmp_rmdir(struct inode *dir, aufs_bindex_t bindex,
+		   struct dentry *wh_dentry, struct au_nhash *whlist);
+void au_whtmp_kick_rmdir(struct inode *dir, aufs_bindex_t bindex,
+			 struct dentry *wh_dentry, struct au_whtmp_rmdir *args);
+
+/* ---------------------------------------------------------------------- */
+
+static inline struct dentry *au_diropq_create(struct dentry *dentry,
+					      aufs_bindex_t bindex)
+{
+	return au_diropq_sio(dentry, bindex, AuDiropq_CREATE);
+}
+
+static inline int au_diropq_remove(struct dentry *dentry, aufs_bindex_t bindex)
+{
+	return PTR_ERR(au_diropq_sio(dentry, bindex, !AuDiropq_CREATE));
+}
+
+#endif /* __KERNEL__ */
+#endif /* __AUFS_WHOUT_H__ */
--- /dev/null
+++ zfcpdump-kernel-4.4/fs/aufs/wkq.c
@@ -0,0 +1,213 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+ *
+ * This program, aufs is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * workqueue for asynchronous/super-io operations
+ * todo: try new dredential scheme
+ */
+
+#include <linux/module.h>
+#include "aufs.h"
+
+/* internal workqueue named AUFS_WKQ_NAME */
+
+static struct workqueue_struct *au_wkq;
+
+struct au_wkinfo {
+	struct work_struct wk;
+	struct kobject *kobj;
+
+	unsigned int flags; /* see wkq.h */
+
+	au_wkq_func_t func;
+	void *args;
+
+	struct completion *comp;
+};
+
+/* ---------------------------------------------------------------------- */
+
+static void wkq_func(struct work_struct *wk)
+{
+	struct au_wkinfo *wkinfo = container_of(wk, struct au_wkinfo, wk);
+
+	AuDebugOn(!uid_eq(current_fsuid(), GLOBAL_ROOT_UID));
+	AuDebugOn(rlimit(RLIMIT_FSIZE) != RLIM_INFINITY);
+
+	wkinfo->func(wkinfo->args);
+	if (au_ftest_wkq(wkinfo->flags, WAIT))
+		complete(wkinfo->comp);
+	else {
+		kobject_put(wkinfo->kobj);
+		module_put(THIS_MODULE); /* todo: ?? */
+		kfree(wkinfo);
+	}
+}
+
+/*
+ * Since struct completion is large, try allocating it dynamically.
+ */
+#if 1 /* defined(CONFIG_4KSTACKS) || defined(AuTest4KSTACKS) */
+#define AuWkqCompDeclare(name)	struct completion *comp = NULL
+
+static int au_wkq_comp_alloc(struct au_wkinfo *wkinfo, struct completion **comp)
+{
+	*comp = kmalloc(sizeof(**comp), GFP_NOFS);
+	if (*comp) {
+		init_completion(*comp);
+		wkinfo->comp = *comp;
+		return 0;
+	}
+	return -ENOMEM;
+}
+
+static void au_wkq_comp_free(struct completion *comp)
+{
+	kfree(comp);
+}
+
+#else
+
+/* no braces */
+#define AuWkqCompDeclare(name) \
+	DECLARE_COMPLETION_ONSTACK(_ ## name); \
+	struct completion *comp = &_ ## name
+
+static int au_wkq_comp_alloc(struct au_wkinfo *wkinfo, struct completion **comp)
+{
+	wkinfo->comp = *comp;
+	return 0;
+}
+
+static void au_wkq_comp_free(struct completion *comp __maybe_unused)
+{
+	/* empty */
+}
+#endif /* 4KSTACKS */
+
+static void au_wkq_run(struct au_wkinfo *wkinfo)
+{
+	if (au_ftest_wkq(wkinfo->flags, NEST)) {
+		if (au_wkq_test()) {
+			AuWarn1("wkq from wkq, unless silly-rename on NFS,"
+				" due to a dead dir by UDBA?\n");
+			AuDebugOn(au_ftest_wkq(wkinfo->flags, WAIT));
+		}
+	} else
+		au_dbg_verify_kthread();
+
+	if (au_ftest_wkq(wkinfo->flags, WAIT)) {
+		INIT_WORK_ONSTACK(&wkinfo->wk, wkq_func);
+		queue_work(au_wkq, &wkinfo->wk);
+	} else {
+		INIT_WORK(&wkinfo->wk, wkq_func);
+		schedule_work(&wkinfo->wk);
+	}
+}
+
+/*
+ * Be careful. It is easy to make deadlock happen.
+ * processA: lock, wkq and wait
+ * processB: wkq and wait, lock in wkq
+ * --> deadlock
+ */
+int au_wkq_do_wait(unsigned int flags, au_wkq_func_t func, void *args)
+{
+	int err;
+	AuWkqCompDeclare(comp);
+	struct au_wkinfo wkinfo = {
+		.flags	= flags,
+		.func	= func,
+		.args	= args
+	};
+
+	err = au_wkq_comp_alloc(&wkinfo, &comp);
+	if (!err) {
+		au_wkq_run(&wkinfo);
+		/* no timeout, no interrupt */
+		wait_for_completion(wkinfo.comp);
+		au_wkq_comp_free(comp);
+		destroy_work_on_stack(&wkinfo.wk);
+	}
+
+	return err;
+
+}
+
+/*
+ * Note: dget/dput() in func for aufs dentries are not supported. It will be a
+ * problem in a concurrent umounting.
+ */
+int au_wkq_nowait(au_wkq_func_t func, void *args, struct super_block *sb,
+		  unsigned int flags)
+{
+	int err;
+	struct au_wkinfo *wkinfo;
+
+	atomic_inc(&au_sbi(sb)->si_nowait.nw_len);
+
+	/*
+	 * wkq_func() must free this wkinfo.
+	 * it highly depends upon the implementation of workqueue.
+	 */
+	err = 0;
+	wkinfo = kmalloc(sizeof(*wkinfo), GFP_NOFS);
+	if (wkinfo) {
+		wkinfo->kobj = &au_sbi(sb)->si_kobj;
+		wkinfo->flags = flags & ~AuWkq_WAIT;
+		wkinfo->func = func;
+		wkinfo->args = args;
+		wkinfo->comp = NULL;
+		kobject_get(wkinfo->kobj);
+		__module_get(THIS_MODULE); /* todo: ?? */
+
+		au_wkq_run(wkinfo);
+	} else {
+		err = -ENOMEM;
+		au_nwt_done(&au_sbi(sb)->si_nowait);
+	}
+
+	return err;
+}
+
+/* ---------------------------------------------------------------------- */
+
+void au_nwt_init(struct au_nowait_tasks *nwt)
+{
+	atomic_set(&nwt->nw_len, 0);
+	/* smp_mb(); */ /* atomic_set */
+	init_waitqueue_head(&nwt->nw_wq);
+}
+
+void au_wkq_fin(void)
+{
+	destroy_workqueue(au_wkq);
+}
+
+int __init au_wkq_init(void)
+{
+	int err;
+
+	err = 0;
+	au_wkq = alloc_workqueue(AUFS_WKQ_NAME, 0, WQ_DFL_ACTIVE);
+	if (IS_ERR(au_wkq))
+		err = PTR_ERR(au_wkq);
+	else if (!au_wkq)
+		err = -ENOMEM;
+
+	return err;
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/fs/aufs/wkq.h
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+ *
+ * This program, aufs is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * workqueue for asynchronous/super-io operations
+ * todo: try new credentials management scheme
+ */
+
+#ifndef __AUFS_WKQ_H__
+#define __AUFS_WKQ_H__
+
+#ifdef __KERNEL__
+
+struct super_block;
+
+/* ---------------------------------------------------------------------- */
+
+/*
+ * in the next operation, wait for the 'nowait' tasks in system-wide workqueue
+ */
+struct au_nowait_tasks {
+	atomic_t		nw_len;
+	wait_queue_head_t	nw_wq;
+};
+
+/* ---------------------------------------------------------------------- */
+
+typedef void (*au_wkq_func_t)(void *args);
+
+/* wkq flags */
+#define AuWkq_WAIT	1
+#define AuWkq_NEST	(1 << 1)
+#define au_ftest_wkq(flags, name)	((flags) & AuWkq_##name)
+#define au_fset_wkq(flags, name) \
+	do { (flags) |= AuWkq_##name; } while (0)
+#define au_fclr_wkq(flags, name) \
+	do { (flags) &= ~AuWkq_##name; } while (0)
+
+#ifndef CONFIG_AUFS_HNOTIFY
+#undef AuWkq_NEST
+#define AuWkq_NEST	0
+#endif
+
+/* wkq.c */
+int au_wkq_do_wait(unsigned int flags, au_wkq_func_t func, void *args);
+int au_wkq_nowait(au_wkq_func_t func, void *args, struct super_block *sb,
+		  unsigned int flags);
+void au_nwt_init(struct au_nowait_tasks *nwt);
+int __init au_wkq_init(void);
+void au_wkq_fin(void);
+
+/* ---------------------------------------------------------------------- */
+
+static inline int au_wkq_test(void)
+{
+	return current->flags & PF_WQ_WORKER;
+}
+
+static inline int au_wkq_wait(au_wkq_func_t func, void *args)
+{
+	return au_wkq_do_wait(AuWkq_WAIT, func, args);
+}
+
+static inline void au_nwt_done(struct au_nowait_tasks *nwt)
+{
+	if (atomic_dec_and_test(&nwt->nw_len))
+		wake_up_all(&nwt->nw_wq);
+}
+
+static inline int au_nwt_flush(struct au_nowait_tasks *nwt)
+{
+	wait_event(nwt->nw_wq, !atomic_read(&nwt->nw_len));
+	return 0;
+}
+
+#endif /* __KERNEL__ */
+#endif /* __AUFS_WKQ_H__ */
--- /dev/null
+++ zfcpdump-kernel-4.4/fs/aufs/xattr.c
@@ -0,0 +1,344 @@
+/*
+ * Copyright (C) 2014-2015 Junjiro R. Okajima
+ *
+ * This program, aufs is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * handling xattr functions
+ */
+
+#include <linux/xattr.h>
+#include "aufs.h"
+
+static int au_xattr_ignore(int err, char *name, unsigned int ignore_flags)
+{
+	if (!ignore_flags)
+		goto out;
+	switch (err) {
+	case -ENOMEM:
+	case -EDQUOT:
+		goto out;
+	}
+
+	if ((ignore_flags & AuBrAttr_ICEX) == AuBrAttr_ICEX) {
+		err = 0;
+		goto out;
+	}
+
+#define cmp(brattr, prefix) do {					\
+		if (!strncmp(name, XATTR_##prefix##_PREFIX,		\
+			     XATTR_##prefix##_PREFIX_LEN)) {		\
+			if (ignore_flags & AuBrAttr_ICEX_##brattr)	\
+				err = 0;				\
+			goto out;					\
+		}							\
+	} while (0)
+
+	cmp(SEC, SECURITY);
+	cmp(SYS, SYSTEM);
+	cmp(TR, TRUSTED);
+	cmp(USR, USER);
+#undef cmp
+
+	if (ignore_flags & AuBrAttr_ICEX_OTH)
+		err = 0;
+
+out:
+	return err;
+}
+
+static const int au_xattr_out_of_list = AuBrAttr_ICEX_OTH << 1;
+
+static int au_do_cpup_xattr(struct dentry *h_dst, struct dentry *h_src,
+			    char *name, char **buf, unsigned int ignore_flags,
+			    unsigned int verbose)
+{
+	int err;
+	ssize_t ssz;
+	struct inode *h_idst;
+
+	ssz = vfs_getxattr_alloc(h_src, name, buf, 0, GFP_NOFS);
+	err = ssz;
+	if (unlikely(err <= 0)) {
+		if (err == -ENODATA
+		    || (err == -EOPNOTSUPP
+			&& ((ignore_flags & au_xattr_out_of_list)
+			    || (au_test_nfs_noacl(d_inode(h_src))
+				&& (!strcmp(name, XATTR_NAME_POSIX_ACL_ACCESS)
+				    || !strcmp(name,
+					       XATTR_NAME_POSIX_ACL_DEFAULT))))
+			    ))
+			err = 0;
+		if (err && (verbose || au_debug_test()))
+			pr_err("%s, err %d\n", name, err);
+		goto out;
+	}
+
+	/* unlock it temporary */
+	h_idst = d_inode(h_dst);
+	mutex_unlock(&h_idst->i_mutex);
+	err = vfsub_setxattr(h_dst, name, *buf, ssz, /*flags*/0);
+	mutex_lock_nested(&h_idst->i_mutex, AuLsc_I_CHILD2);
+	if (unlikely(err)) {
+		if (verbose || au_debug_test())
+			pr_err("%s, err %d\n", name, err);
+		err = au_xattr_ignore(err, name, ignore_flags);
+	}
+
+out:
+	return err;
+}
+
+int au_cpup_xattr(struct dentry *h_dst, struct dentry *h_src, int ignore_flags,
+		  unsigned int verbose)
+{
+	int err, unlocked, acl_access, acl_default;
+	ssize_t ssz;
+	struct inode *h_isrc, *h_idst;
+	char *value, *p, *o, *e;
+
+	/* try stopping to update the source inode while we are referencing */
+	/* there should not be the parent-child relationship between them */
+	h_isrc = d_inode(h_src);
+	h_idst = d_inode(h_dst);
+	mutex_unlock(&h_idst->i_mutex);
+	mutex_lock_nested(&h_isrc->i_mutex, AuLsc_I_CHILD);
+	mutex_lock_nested(&h_idst->i_mutex, AuLsc_I_CHILD2);
+	unlocked = 0;
+
+	/* some filesystems don't list POSIX ACL, for example tmpfs */
+	ssz = vfs_listxattr(h_src, NULL, 0);
+	err = ssz;
+	if (unlikely(err < 0)) {
+		AuTraceErr(err);
+		if (err == -ENODATA
+		    || err == -EOPNOTSUPP)
+			err = 0;	/* ignore */
+		goto out;
+	}
+
+	err = 0;
+	p = NULL;
+	o = NULL;
+	if (ssz) {
+		err = -ENOMEM;
+		p = kmalloc(ssz, GFP_NOFS);
+		o = p;
+		if (unlikely(!p))
+			goto out;
+		err = vfs_listxattr(h_src, p, ssz);
+	}
+	mutex_unlock(&h_isrc->i_mutex);
+	unlocked = 1;
+	AuDbg("err %d, ssz %zd\n", err, ssz);
+	if (unlikely(err < 0))
+		goto out_free;
+
+	err = 0;
+	e = p + ssz;
+	value = NULL;
+	acl_access = 0;
+	acl_default = 0;
+	while (!err && p < e) {
+		acl_access |= !strncmp(p, XATTR_NAME_POSIX_ACL_ACCESS,
+				       sizeof(XATTR_NAME_POSIX_ACL_ACCESS) - 1);
+		acl_default |= !strncmp(p, XATTR_NAME_POSIX_ACL_DEFAULT,
+					sizeof(XATTR_NAME_POSIX_ACL_DEFAULT)
+					- 1);
+		err = au_do_cpup_xattr(h_dst, h_src, p, &value, ignore_flags,
+				       verbose);
+		p += strlen(p) + 1;
+	}
+	AuTraceErr(err);
+	ignore_flags |= au_xattr_out_of_list;
+	if (!err && !acl_access) {
+		err = au_do_cpup_xattr(h_dst, h_src,
+				       XATTR_NAME_POSIX_ACL_ACCESS, &value,
+				       ignore_flags, verbose);
+		AuTraceErr(err);
+	}
+	if (!err && !acl_default) {
+		err = au_do_cpup_xattr(h_dst, h_src,
+				       XATTR_NAME_POSIX_ACL_DEFAULT, &value,
+				       ignore_flags, verbose);
+		AuTraceErr(err);
+	}
+
+	kfree(value);
+
+out_free:
+	kfree(o);
+out:
+	if (!unlocked)
+		mutex_unlock(&h_isrc->i_mutex);
+	AuTraceErr(err);
+	return err;
+}
+
+/* ---------------------------------------------------------------------- */
+
+enum {
+	AU_XATTR_LIST,
+	AU_XATTR_GET
+};
+
+struct au_lgxattr {
+	int type;
+	union {
+		struct {
+			char	*list;
+			size_t	size;
+		} list;
+		struct {
+			const char	*name;
+			void		*value;
+			size_t		size;
+		} get;
+	} u;
+};
+
+static ssize_t au_lgxattr(struct dentry *dentry, struct au_lgxattr *arg)
+{
+	ssize_t err;
+	struct path h_path;
+	struct super_block *sb;
+
+	sb = dentry->d_sb;
+	err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
+	if (unlikely(err))
+		goto out;
+	err = au_h_path_getattr(dentry, /*force*/1, &h_path);
+	if (unlikely(err))
+		goto out_si;
+	if (unlikely(!h_path.dentry))
+		/* illegally overlapped or something */
+		goto out_di; /* pretending success */
+
+	/* always topmost entry only */
+	switch (arg->type) {
+	case AU_XATTR_LIST:
+		err = vfs_listxattr(h_path.dentry,
+				    arg->u.list.list, arg->u.list.size);
+		break;
+	case AU_XATTR_GET:
+		err = vfs_getxattr(h_path.dentry,
+				   arg->u.get.name, arg->u.get.value,
+				   arg->u.get.size);
+		break;
+	}
+
+out_di:
+	di_read_unlock(dentry, AuLock_IR);
+out_si:
+	si_read_unlock(sb);
+out:
+	AuTraceErr(err);
+	return err;
+}
+
+ssize_t aufs_listxattr(struct dentry *dentry, char *list, size_t size)
+{
+	struct au_lgxattr arg = {
+		.type = AU_XATTR_LIST,
+		.u.list = {
+			.list	= list,
+			.size	= size
+		},
+	};
+
+	return au_lgxattr(dentry, &arg);
+}
+
+ssize_t aufs_getxattr(struct dentry *dentry, const char *name, void *value,
+		      size_t size)
+{
+	struct au_lgxattr arg = {
+		.type = AU_XATTR_GET,
+		.u.get = {
+			.name	= name,
+			.value	= value,
+			.size	= size
+		},
+	};
+
+	return au_lgxattr(dentry, &arg);
+}
+
+int aufs_setxattr(struct dentry *dentry, const char *name, const void *value,
+		  size_t size, int flags)
+{
+	struct au_srxattr arg = {
+		.type = AU_XATTR_SET,
+		.u.set = {
+			.name	= name,
+			.value	= value,
+			.size	= size,
+			.flags	= flags
+		},
+	};
+
+	return au_srxattr(dentry, &arg);
+}
+
+int aufs_removexattr(struct dentry *dentry, const char *name)
+{
+	struct au_srxattr arg = {
+		.type = AU_XATTR_REMOVE,
+		.u.remove = {
+			.name	= name
+		},
+	};
+
+	return au_srxattr(dentry, &arg);
+}
+
+/* ---------------------------------------------------------------------- */
+
+#if 0
+static size_t au_xattr_list(struct dentry *dentry, char *list, size_t list_size,
+			    const char *name, size_t name_len, int type)
+{
+	return aufs_listxattr(dentry, list, list_size);
+}
+
+static int au_xattr_get(struct dentry *dentry, const char *name, void *buffer,
+			size_t size, int type)
+{
+	return aufs_getxattr(dentry, name, buffer, size);
+}
+
+static int au_xattr_set(struct dentry *dentry, const char *name,
+			const void *value, size_t size, int flags, int type)
+{
+	return aufs_setxattr(dentry, name, value, size, flags);
+}
+
+static const struct xattr_handler au_xattr_handler = {
+	/* no prefix, no flags */
+	.list	= au_xattr_list,
+	.get	= au_xattr_get,
+	.set	= au_xattr_set
+	/* why no remove? */
+};
+
+static const struct xattr_handler *au_xattr_handlers[] = {
+	&au_xattr_handler
+};
+
+void au_xattr_init(struct super_block *sb)
+{
+	/* sb->s_xattr = au_xattr_handlers; */
+}
+#endif
--- /dev/null
+++ zfcpdump-kernel-4.4/fs/aufs/xino.c
@@ -0,0 +1,1318 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+ *
+ * This program, aufs is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * external inode number translation table and bitmap
+ */
+
+#include <linux/seq_file.h>
+#include <linux/statfs.h>
+#include "aufs.h"
+
+/* todo: unnecessary to support mmap_sem since kernel-space? */
+ssize_t xino_fread(vfs_readf_t func, struct file *file, void *kbuf, size_t size,
+		   loff_t *pos)
+{
+	ssize_t err;
+	mm_segment_t oldfs;
+	union {
+		void *k;
+		char __user *u;
+	} buf;
+
+	buf.k = kbuf;
+	oldfs = get_fs();
+	set_fs(KERNEL_DS);
+	do {
+		/* todo: signal_pending? */
+		err = func(file, buf.u, size, pos);
+	} while (err == -EAGAIN || err == -EINTR);
+	set_fs(oldfs);
+
+#if 0 /* reserved for future use */
+	if (err > 0)
+		fsnotify_access(file->f_path.dentry);
+#endif
+
+	return err;
+}
+
+/* ---------------------------------------------------------------------- */
+
+static ssize_t xino_fwrite_wkq(vfs_writef_t func, struct file *file, void *buf,
+			       size_t size, loff_t *pos);
+
+static ssize_t do_xino_fwrite(vfs_writef_t func, struct file *file, void *kbuf,
+			      size_t size, loff_t *pos)
+{
+	ssize_t err;
+	mm_segment_t oldfs;
+	union {
+		void *k;
+		const char __user *u;
+	} buf;
+	int i;
+	const int prevent_endless = 10;
+
+	i = 0;
+	buf.k = kbuf;
+	oldfs = get_fs();
+	set_fs(KERNEL_DS);
+	do {
+		err = func(file, buf.u, size, pos);
+		if (err == -EINTR
+		    && !au_wkq_test()
+		    && fatal_signal_pending(current)) {
+			set_fs(oldfs);
+			err = xino_fwrite_wkq(func, file, kbuf, size, pos);
+			BUG_ON(err == -EINTR);
+			oldfs = get_fs();
+			set_fs(KERNEL_DS);
+		}
+	} while (i++ < prevent_endless
+		 && (err == -EAGAIN || err == -EINTR));
+	set_fs(oldfs);
+
+#if 0 /* reserved for future use */
+	if (err > 0)
+		fsnotify_modify(file->f_path.dentry);
+#endif
+
+	return err;
+}
+
+struct do_xino_fwrite_args {
+	ssize_t *errp;
+	vfs_writef_t func;
+	struct file *file;
+	void *buf;
+	size_t size;
+	loff_t *pos;
+};
+
+static void call_do_xino_fwrite(void *args)
+{
+	struct do_xino_fwrite_args *a = args;
+	*a->errp = do_xino_fwrite(a->func, a->file, a->buf, a->size, a->pos);
+}
+
+static ssize_t xino_fwrite_wkq(vfs_writef_t func, struct file *file, void *buf,
+			       size_t size, loff_t *pos)
+{
+	ssize_t err;
+	int wkq_err;
+	struct do_xino_fwrite_args args = {
+		.errp	= &err,
+		.func	= func,
+		.file	= file,
+		.buf	= buf,
+		.size	= size,
+		.pos	= pos
+	};
+
+	/*
+	 * it breaks RLIMIT_FSIZE and normal user's limit,
+	 * users should care about quota and real 'filesystem full.'
+	 */
+	wkq_err = au_wkq_wait(call_do_xino_fwrite, &args);
+	if (unlikely(wkq_err))
+		err = wkq_err;
+
+	return err;
+}
+
+ssize_t xino_fwrite(vfs_writef_t func, struct file *file, void *buf,
+		    size_t size, loff_t *pos)
+{
+	ssize_t err;
+
+	if (rlimit(RLIMIT_FSIZE) == RLIM_INFINITY) {
+		lockdep_off();
+		err = do_xino_fwrite(func, file, buf, size, pos);
+		lockdep_on();
+	} else
+		err = xino_fwrite_wkq(func, file, buf, size, pos);
+
+	return err;
+}
+
+/* ---------------------------------------------------------------------- */
+
+/*
+ * create a new xinofile at the same place/path as @base_file.
+ */
+struct file *au_xino_create2(struct file *base_file, struct file *copy_src)
+{
+	struct file *file;
+	struct dentry *base, *parent;
+	struct inode *dir, *delegated;
+	struct qstr *name;
+	struct path path;
+	int err;
+
+	base = base_file->f_path.dentry;
+	parent = base->d_parent; /* dir inode is locked */
+	dir = d_inode(parent);
+	IMustLock(dir);
+
+	file = ERR_PTR(-EINVAL);
+	name = &base->d_name;
+	path.dentry = vfsub_lookup_one_len(name->name, parent, name->len);
+	if (IS_ERR(path.dentry)) {
+		file = (void *)path.dentry;
+		pr_err("%pd lookup err %ld\n",
+		       base, PTR_ERR(path.dentry));
+		goto out;
+	}
+
+	/* no need to mnt_want_write() since we call dentry_open() later */
+	err = vfs_create(dir, path.dentry, S_IRUGO | S_IWUGO, NULL);
+	if (unlikely(err)) {
+		file = ERR_PTR(err);
+		pr_err("%pd create err %d\n", base, err);
+		goto out_dput;
+	}
+
+	path.mnt = base_file->f_path.mnt;
+	file = vfsub_dentry_open(&path,
+				 O_RDWR | O_CREAT | O_EXCL | O_LARGEFILE
+				 /* | __FMODE_NONOTIFY */);
+	if (IS_ERR(file)) {
+		pr_err("%pd open err %ld\n", base, PTR_ERR(file));
+		goto out_dput;
+	}
+
+	delegated = NULL;
+	err = vfsub_unlink(dir, &file->f_path, &delegated, /*force*/0);
+	if (unlikely(err == -EWOULDBLOCK)) {
+		pr_warn("cannot retry for NFSv4 delegation"
+			" for an internal unlink\n");
+		iput(delegated);
+	}
+	if (unlikely(err)) {
+		pr_err("%pd unlink err %d\n", base, err);
+		goto out_fput;
+	}
+
+	if (copy_src) {
+		/* no one can touch copy_src xino */
+		err = au_copy_file(file, copy_src, vfsub_f_size_read(copy_src));
+		if (unlikely(err)) {
+			pr_err("%pd copy err %d\n", base, err);
+			goto out_fput;
+		}
+	}
+	goto out_dput; /* success */
+
+out_fput:
+	fput(file);
+	file = ERR_PTR(err);
+out_dput:
+	dput(path.dentry);
+out:
+	return file;
+}
+
+struct au_xino_lock_dir {
+	struct au_hinode *hdir;
+	struct dentry *parent;
+	struct mutex *mtx;
+};
+
+static void au_xino_lock_dir(struct super_block *sb, struct file *xino,
+			     struct au_xino_lock_dir *ldir)
+{
+	aufs_bindex_t brid, bindex;
+
+	ldir->hdir = NULL;
+	bindex = -1;
+	brid = au_xino_brid(sb);
+	if (brid >= 0)
+		bindex = au_br_index(sb, brid);
+	if (bindex >= 0) {
+		ldir->hdir = au_hi(d_inode(sb->s_root), bindex);
+		au_hn_imtx_lock_nested(ldir->hdir, AuLsc_I_PARENT);
+	} else {
+		ldir->parent = dget_parent(xino->f_path.dentry);
+		ldir->mtx = &d_inode(ldir->parent)->i_mutex;
+		mutex_lock_nested(ldir->mtx, AuLsc_I_PARENT);
+	}
+}
+
+static void au_xino_unlock_dir(struct au_xino_lock_dir *ldir)
+{
+	if (ldir->hdir)
+		au_hn_imtx_unlock(ldir->hdir);
+	else {
+		mutex_unlock(ldir->mtx);
+		dput(ldir->parent);
+	}
+}
+
+/* ---------------------------------------------------------------------- */
+
+/* trucate xino files asynchronously */
+
+int au_xino_trunc(struct super_block *sb, aufs_bindex_t bindex)
+{
+	int err;
+	unsigned long jiffy;
+	blkcnt_t blocks;
+	aufs_bindex_t bi, bend;
+	struct kstatfs *st;
+	struct au_branch *br;
+	struct file *new_xino, *file;
+	struct super_block *h_sb;
+	struct au_xino_lock_dir ldir;
+
+	err = -ENOMEM;
+	st = kmalloc(sizeof(*st), GFP_NOFS);
+	if (unlikely(!st))
+		goto out;
+
+	err = -EINVAL;
+	bend = au_sbend(sb);
+	if (unlikely(bindex < 0 || bend < bindex))
+		goto out_st;
+	br = au_sbr(sb, bindex);
+	file = br->br_xino.xi_file;
+	if (!file)
+		goto out_st;
+
+	err = vfs_statfs(&file->f_path, st);
+	if (unlikely(err))
+		AuErr1("statfs err %d, ignored\n", err);
+	jiffy = jiffies;
+	blocks = file_inode(file)->i_blocks;
+	pr_info("begin truncating xino(b%d), ib%llu, %llu/%llu free blks\n",
+		bindex, (u64)blocks, st->f_bfree, st->f_blocks);
+
+	au_xino_lock_dir(sb, file, &ldir);
+	/* mnt_want_write() is unnecessary here */
+	new_xino = au_xino_create2(file, file);
+	au_xino_unlock_dir(&ldir);
+	err = PTR_ERR(new_xino);
+	if (IS_ERR(new_xino)) {
+		pr_err("err %d, ignored\n", err);
+		goto out_st;
+	}
+	err = 0;
+	fput(file);
+	br->br_xino.xi_file = new_xino;
+
+	h_sb = au_br_sb(br);
+	for (bi = 0; bi <= bend; bi++) {
+		if (unlikely(bi == bindex))
+			continue;
+		br = au_sbr(sb, bi);
+		if (au_br_sb(br) != h_sb)
+			continue;
+
+		fput(br->br_xino.xi_file);
+		br->br_xino.xi_file = new_xino;
+		get_file(new_xino);
+	}
+
+	err = vfs_statfs(&new_xino->f_path, st);
+	if (!err) {
+		pr_info("end truncating xino(b%d), ib%llu, %llu/%llu free blks\n",
+			bindex, (u64)file_inode(new_xino)->i_blocks,
+			st->f_bfree, st->f_blocks);
+		if (file_inode(new_xino)->i_blocks < blocks)
+			au_sbi(sb)->si_xino_jiffy = jiffy;
+	} else
+		AuErr1("statfs err %d, ignored\n", err);
+
+out_st:
+	kfree(st);
+out:
+	return err;
+}
+
+struct xino_do_trunc_args {
+	struct super_block *sb;
+	struct au_branch *br;
+};
+
+static void xino_do_trunc(void *_args)
+{
+	struct xino_do_trunc_args *args = _args;
+	struct super_block *sb;
+	struct au_branch *br;
+	struct inode *dir;
+	int err;
+	aufs_bindex_t bindex;
+
+	err = 0;
+	sb = args->sb;
+	dir = d_inode(sb->s_root);
+	br = args->br;
+
+	si_noflush_write_lock(sb);
+	ii_read_lock_parent(dir);
+	bindex = au_br_index(sb, br->br_id);
+	err = au_xino_trunc(sb, bindex);
+	ii_read_unlock(dir);
+	if (unlikely(err))
+		pr_warn("err b%d, (%d)\n", bindex, err);
+	atomic_dec(&br->br_xino_running);
+	atomic_dec(&br->br_count);
+	si_write_unlock(sb);
+	au_nwt_done(&au_sbi(sb)->si_nowait);
+	kfree(args);
+}
+
+static int xino_trunc_test(struct super_block *sb, struct au_branch *br)
+{
+	int err;
+	struct kstatfs st;
+	struct au_sbinfo *sbinfo;
+
+	/* todo: si_xino_expire and the ratio should be customizable */
+	sbinfo = au_sbi(sb);
+	if (time_before(jiffies,
+			sbinfo->si_xino_jiffy + sbinfo->si_xino_expire))
+		return 0;
+
+	/* truncation border */
+	err = vfs_statfs(&br->br_xino.xi_file->f_path, &st);
+	if (unlikely(err)) {
+		AuErr1("statfs err %d, ignored\n", err);
+		return 0;
+	}
+	if (div64_u64(st.f_bfree * 100, st.f_blocks) >= AUFS_XINO_DEF_TRUNC)
+		return 0;
+
+	return 1;
+}
+
+static void xino_try_trunc(struct super_block *sb, struct au_branch *br)
+{
+	struct xino_do_trunc_args *args;
+	int wkq_err;
+
+	if (!xino_trunc_test(sb, br))
+		return;
+
+	if (atomic_inc_return(&br->br_xino_running) > 1)
+		goto out;
+
+	/* lock and kfree() will be called in trunc_xino() */
+	args = kmalloc(sizeof(*args), GFP_NOFS);
+	if (unlikely(!args)) {
+		AuErr1("no memory\n");
+		goto out_args;
+	}
+
+	atomic_inc(&br->br_count);
+	args->sb = sb;
+	args->br = br;
+	wkq_err = au_wkq_nowait(xino_do_trunc, args, sb, /*flags*/0);
+	if (!wkq_err)
+		return; /* success */
+
+	pr_err("wkq %d\n", wkq_err);
+	atomic_dec(&br->br_count);
+
+out_args:
+	kfree(args);
+out:
+	atomic_dec(&br->br_xino_running);
+}
+
+/* ---------------------------------------------------------------------- */
+
+static int au_xino_do_write(vfs_writef_t write, struct file *file,
+			    ino_t h_ino, ino_t ino)
+{
+	loff_t pos;
+	ssize_t sz;
+
+	pos = h_ino;
+	if (unlikely(au_loff_max / sizeof(ino) - 1 < pos)) {
+		AuIOErr1("too large hi%lu\n", (unsigned long)h_ino);
+		return -EFBIG;
+	}
+	pos *= sizeof(ino);
+	sz = xino_fwrite(write, file, &ino, sizeof(ino), &pos);
+	if (sz == sizeof(ino))
+		return 0; /* success */
+
+	AuIOErr("write failed (%zd)\n", sz);
+	return -EIO;
+}
+
+/*
+ * write @ino to the xinofile for the specified branch{@sb, @bindex}
+ * at the position of @h_ino.
+ * even if @ino is zero, it is written to the xinofile and means no entry.
+ * if the size of the xino file on a specific filesystem exceeds the watermark,
+ * try truncating it.
+ */
+int au_xino_write(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
+		  ino_t ino)
+{
+	int err;
+	unsigned int mnt_flags;
+	struct au_branch *br;
+
+	BUILD_BUG_ON(sizeof(long long) != sizeof(au_loff_max)
+		     || ((loff_t)-1) > 0);
+	SiMustAnyLock(sb);
+
+	mnt_flags = au_mntflags(sb);
+	if (!au_opt_test(mnt_flags, XINO))
+		return 0;
+
+	br = au_sbr(sb, bindex);
+	err = au_xino_do_write(au_sbi(sb)->si_xwrite, br->br_xino.xi_file,
+			       h_ino, ino);
+	if (!err) {
+		if (au_opt_test(mnt_flags, TRUNC_XINO)
+		    && au_test_fs_trunc_xino(au_br_sb(br)))
+			xino_try_trunc(sb, br);
+		return 0; /* success */
+	}
+
+	AuIOErr("write failed (%d)\n", err);
+	return -EIO;
+}
+
+/* ---------------------------------------------------------------------- */
+
+/* aufs inode number bitmap */
+
+static const int page_bits = (int)PAGE_SIZE * BITS_PER_BYTE;
+static ino_t xib_calc_ino(unsigned long pindex, int bit)
+{
+	ino_t ino;
+
+	AuDebugOn(bit < 0 || page_bits <= bit);
+	ino = AUFS_FIRST_INO + pindex * page_bits + bit;
+	return ino;
+}
+
+static void xib_calc_bit(ino_t ino, unsigned long *pindex, int *bit)
+{
+	AuDebugOn(ino < AUFS_FIRST_INO);
+	ino -= AUFS_FIRST_INO;
+	*pindex = ino / page_bits;
+	*bit = ino % page_bits;
+}
+
+static int xib_pindex(struct super_block *sb, unsigned long pindex)
+{
+	int err;
+	loff_t pos;
+	ssize_t sz;
+	struct au_sbinfo *sbinfo;
+	struct file *xib;
+	unsigned long *p;
+
+	sbinfo = au_sbi(sb);
+	MtxMustLock(&sbinfo->si_xib_mtx);
+	AuDebugOn(pindex > ULONG_MAX / PAGE_SIZE
+		  || !au_opt_test(sbinfo->si_mntflags, XINO));
+
+	if (pindex == sbinfo->si_xib_last_pindex)
+		return 0;
+
+	xib = sbinfo->si_xib;
+	p = sbinfo->si_xib_buf;
+	pos = sbinfo->si_xib_last_pindex;
+	pos *= PAGE_SIZE;
+	sz = xino_fwrite(sbinfo->si_xwrite, xib, p, PAGE_SIZE, &pos);
+	if (unlikely(sz != PAGE_SIZE))
+		goto out;
+
+	pos = pindex;
+	pos *= PAGE_SIZE;
+	if (vfsub_f_size_read(xib) >= pos + PAGE_SIZE)
+		sz = xino_fread(sbinfo->si_xread, xib, p, PAGE_SIZE, &pos);
+	else {
+		memset(p, 0, PAGE_SIZE);
+		sz = xino_fwrite(sbinfo->si_xwrite, xib, p, PAGE_SIZE, &pos);
+	}
+	if (sz == PAGE_SIZE) {
+		sbinfo->si_xib_last_pindex = pindex;
+		return 0; /* success */
+	}
+
+out:
+	AuIOErr1("write failed (%zd)\n", sz);
+	err = sz;
+	if (sz >= 0)
+		err = -EIO;
+	return err;
+}
+
+/* ---------------------------------------------------------------------- */
+
+static void au_xib_clear_bit(struct inode *inode)
+{
+	int err, bit;
+	unsigned long pindex;
+	struct super_block *sb;
+	struct au_sbinfo *sbinfo;
+
+	AuDebugOn(inode->i_nlink);
+
+	sb = inode->i_sb;
+	xib_calc_bit(inode->i_ino, &pindex, &bit);
+	AuDebugOn(page_bits <= bit);
+	sbinfo = au_sbi(sb);
+	mutex_lock(&sbinfo->si_xib_mtx);
+	err = xib_pindex(sb, pindex);
+	if (!err) {
+		clear_bit(bit, sbinfo->si_xib_buf);
+		sbinfo->si_xib_next_bit = bit;
+	}
+	mutex_unlock(&sbinfo->si_xib_mtx);
+}
+
+/* for s_op->delete_inode() */
+void au_xino_delete_inode(struct inode *inode, const int unlinked)
+{
+	int err;
+	unsigned int mnt_flags;
+	aufs_bindex_t bindex, bend, bi;
+	unsigned char try_trunc;
+	struct au_iinfo *iinfo;
+	struct super_block *sb;
+	struct au_hinode *hi;
+	struct inode *h_inode;
+	struct au_branch *br;
+	vfs_writef_t xwrite;
+
+	sb = inode->i_sb;
+	mnt_flags = au_mntflags(sb);
+	if (!au_opt_test(mnt_flags, XINO)
+	    || inode->i_ino == AUFS_ROOT_INO)
+		return;
+
+	if (unlinked) {
+		au_xigen_inc(inode);
+		au_xib_clear_bit(inode);
+	}
+
+	iinfo = au_ii(inode);
+	if (!iinfo)
+		return;
+
+	bindex = iinfo->ii_bstart;
+	if (bindex < 0)
+		return;
+
+	xwrite = au_sbi(sb)->si_xwrite;
+	try_trunc = !!au_opt_test(mnt_flags, TRUNC_XINO);
+	hi = iinfo->ii_hinode + bindex;
+	bend = iinfo->ii_bend;
+	for (; bindex <= bend; bindex++, hi++) {
+		h_inode = hi->hi_inode;
+		if (!h_inode
+		    || (!unlinked && h_inode->i_nlink))
+			continue;
+
+		/* inode may not be revalidated */
+		bi = au_br_index(sb, hi->hi_id);
+		if (bi < 0)
+			continue;
+
+		br = au_sbr(sb, bi);
+		err = au_xino_do_write(xwrite, br->br_xino.xi_file,
+				       h_inode->i_ino, /*ino*/0);
+		if (!err && try_trunc
+		    && au_test_fs_trunc_xino(au_br_sb(br)))
+			xino_try_trunc(sb, br);
+	}
+}
+
+/* get an unused inode number from bitmap */
+ino_t au_xino_new_ino(struct super_block *sb)
+{
+	ino_t ino;
+	unsigned long *p, pindex, ul, pend;
+	struct au_sbinfo *sbinfo;
+	struct file *file;
+	int free_bit, err;
+
+	if (!au_opt_test(au_mntflags(sb), XINO))
+		return iunique(sb, AUFS_FIRST_INO);
+
+	sbinfo = au_sbi(sb);
+	mutex_lock(&sbinfo->si_xib_mtx);
+	p = sbinfo->si_xib_buf;
+	free_bit = sbinfo->si_xib_next_bit;
+	if (free_bit < page_bits && !test_bit(free_bit, p))
+		goto out; /* success */
+	free_bit = find_first_zero_bit(p, page_bits);
+	if (free_bit < page_bits)
+		goto out; /* success */
+
+	pindex = sbinfo->si_xib_last_pindex;
+	for (ul = pindex - 1; ul < ULONG_MAX; ul--) {
+		err = xib_pindex(sb, ul);
+		if (unlikely(err))
+			goto out_err;
+		free_bit = find_first_zero_bit(p, page_bits);
+		if (free_bit < page_bits)
+			goto out; /* success */
+	}
+
+	file = sbinfo->si_xib;
+	pend = vfsub_f_size_read(file) / PAGE_SIZE;
+	for (ul = pindex + 1; ul <= pend; ul++) {
+		err = xib_pindex(sb, ul);
+		if (unlikely(err))
+			goto out_err;
+		free_bit = find_first_zero_bit(p, page_bits);
+		if (free_bit < page_bits)
+			goto out; /* success */
+	}
+	BUG();
+
+out:
+	set_bit(free_bit, p);
+	sbinfo->si_xib_next_bit = free_bit + 1;
+	pindex = sbinfo->si_xib_last_pindex;
+	mutex_unlock(&sbinfo->si_xib_mtx);
+	ino = xib_calc_ino(pindex, free_bit);
+	AuDbg("i%lu\n", (unsigned long)ino);
+	return ino;
+out_err:
+	mutex_unlock(&sbinfo->si_xib_mtx);
+	AuDbg("i0\n");
+	return 0;
+}
+
+/*
+ * read @ino from xinofile for the specified branch{@sb, @bindex}
+ * at the position of @h_ino.
+ * if @ino does not exist and @do_new is true, get new one.
+ */
+int au_xino_read(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
+		 ino_t *ino)
+{
+	int err;
+	ssize_t sz;
+	loff_t pos;
+	struct file *file;
+	struct au_sbinfo *sbinfo;
+
+	*ino = 0;
+	if (!au_opt_test(au_mntflags(sb), XINO))
+		return 0; /* no xino */
+
+	err = 0;
+	sbinfo = au_sbi(sb);
+	pos = h_ino;
+	if (unlikely(au_loff_max / sizeof(*ino) - 1 < pos)) {
+		AuIOErr1("too large hi%lu\n", (unsigned long)h_ino);
+		return -EFBIG;
+	}
+	pos *= sizeof(*ino);
+
+	file = au_sbr(sb, bindex)->br_xino.xi_file;
+	if (vfsub_f_size_read(file) < pos + sizeof(*ino))
+		return 0; /* no ino */
+
+	sz = xino_fread(sbinfo->si_xread, file, ino, sizeof(*ino), &pos);
+	if (sz == sizeof(*ino))
+		return 0; /* success */
+
+	err = sz;
+	if (unlikely(sz >= 0)) {
+		err = -EIO;
+		AuIOErr("xino read error (%zd)\n", sz);
+	}
+
+	return err;
+}
+
+/* ---------------------------------------------------------------------- */
+
+/* create and set a new xino file */
+
+struct file *au_xino_create(struct super_block *sb, char *fname, int silent)
+{
+	struct file *file;
+	struct dentry *h_parent, *d;
+	struct inode *h_dir, *inode;
+	int err;
+
+	/*
+	 * at mount-time, and the xino file is the default path,
+	 * hnotify is disabled so we have no notify events to ignore.
+	 * when a user specified the xino, we cannot get au_hdir to be ignored.
+	 */
+	file = vfsub_filp_open(fname, O_RDWR | O_CREAT | O_EXCL | O_LARGEFILE
+			       /* | __FMODE_NONOTIFY */,
+			       S_IRUGO | S_IWUGO);
+	if (IS_ERR(file)) {
+		if (!silent)
+			pr_err("open %s(%ld)\n", fname, PTR_ERR(file));
+		return file;
+	}
+
+	/* keep file count */
+	err = 0;
+	inode = file_inode(file);
+	h_parent = dget_parent(file->f_path.dentry);
+	h_dir = d_inode(h_parent);
+	mutex_lock_nested(&h_dir->i_mutex, AuLsc_I_PARENT);
+	/* mnt_want_write() is unnecessary here */
+	/* no delegation since it is just created */
+	if (inode->i_nlink)
+		err = vfsub_unlink(h_dir, &file->f_path, /*delegated*/NULL,
+				   /*force*/0);
+	mutex_unlock(&h_dir->i_mutex);
+	dput(h_parent);
+	if (unlikely(err)) {
+		if (!silent)
+			pr_err("unlink %s(%d)\n", fname, err);
+		goto out;
+	}
+
+	err = -EINVAL;
+	d = file->f_path.dentry;
+	if (unlikely(sb == d->d_sb)) {
+		if (!silent)
+			pr_err("%s must be outside\n", fname);
+		goto out;
+	}
+	if (unlikely(au_test_fs_bad_xino(d->d_sb))) {
+		if (!silent)
+			pr_err("xino doesn't support %s(%s)\n",
+			       fname, au_sbtype(d->d_sb));
+		goto out;
+	}
+	return file; /* success */
+
+out:
+	fput(file);
+	file = ERR_PTR(err);
+	return file;
+}
+
+/*
+ * find another branch who is on the same filesystem of the specified
+ * branch{@btgt}. search until @bend.
+ */
+static int is_sb_shared(struct super_block *sb, aufs_bindex_t btgt,
+			aufs_bindex_t bend)
+{
+	aufs_bindex_t bindex;
+	struct super_block *tgt_sb = au_sbr_sb(sb, btgt);
+
+	for (bindex = 0; bindex < btgt; bindex++)
+		if (unlikely(tgt_sb == au_sbr_sb(sb, bindex)))
+			return bindex;
+	for (bindex++; bindex <= bend; bindex++)
+		if (unlikely(tgt_sb == au_sbr_sb(sb, bindex)))
+			return bindex;
+	return -1;
+}
+
+/* ---------------------------------------------------------------------- */
+
+/*
+ * initialize the xinofile for the specified branch @br
+ * at the place/path where @base_file indicates.
+ * test whether another branch is on the same filesystem or not,
+ * if @do_test is true.
+ */
+int au_xino_br(struct super_block *sb, struct au_branch *br, ino_t h_ino,
+	       struct file *base_file, int do_test)
+{
+	int err;
+	ino_t ino;
+	aufs_bindex_t bend, bindex;
+	struct au_branch *shared_br, *b;
+	struct file *file;
+	struct super_block *tgt_sb;
+
+	shared_br = NULL;
+	bend = au_sbend(sb);
+	if (do_test) {
+		tgt_sb = au_br_sb(br);
+		for (bindex = 0; bindex <= bend; bindex++) {
+			b = au_sbr(sb, bindex);
+			if (tgt_sb == au_br_sb(b)) {
+				shared_br = b;
+				break;
+			}
+		}
+	}
+
+	if (!shared_br || !shared_br->br_xino.xi_file) {
+		struct au_xino_lock_dir ldir;
+
+		au_xino_lock_dir(sb, base_file, &ldir);
+		/* mnt_want_write() is unnecessary here */
+		file = au_xino_create2(base_file, NULL);
+		au_xino_unlock_dir(&ldir);
+		err = PTR_ERR(file);
+		if (IS_ERR(file))
+			goto out;
+		br->br_xino.xi_file = file;
+	} else {
+		br->br_xino.xi_file = shared_br->br_xino.xi_file;
+		get_file(br->br_xino.xi_file);
+	}
+
+	ino = AUFS_ROOT_INO;
+	err = au_xino_do_write(au_sbi(sb)->si_xwrite, br->br_xino.xi_file,
+			       h_ino, ino);
+	if (unlikely(err)) {
+		fput(br->br_xino.xi_file);
+		br->br_xino.xi_file = NULL;
+	}
+
+out:
+	return err;
+}
+
+/* ---------------------------------------------------------------------- */
+
+/* trucate a xino bitmap file */
+
+/* todo: slow */
+static int do_xib_restore(struct super_block *sb, struct file *file, void *page)
+{
+	int err, bit;
+	ssize_t sz;
+	unsigned long pindex;
+	loff_t pos, pend;
+	struct au_sbinfo *sbinfo;
+	vfs_readf_t func;
+	ino_t *ino;
+	unsigned long *p;
+
+	err = 0;
+	sbinfo = au_sbi(sb);
+	MtxMustLock(&sbinfo->si_xib_mtx);
+	p = sbinfo->si_xib_buf;
+	func = sbinfo->si_xread;
+	pend = vfsub_f_size_read(file);
+	pos = 0;
+	while (pos < pend) {
+		sz = xino_fread(func, file, page, PAGE_SIZE, &pos);
+		err = sz;
+		if (unlikely(sz <= 0))
+			goto out;
+
+		err = 0;
+		for (ino = page; sz > 0; ino++, sz -= sizeof(ino)) {
+			if (unlikely(*ino < AUFS_FIRST_INO))
+				continue;
+
+			xib_calc_bit(*ino, &pindex, &bit);
+			AuDebugOn(page_bits <= bit);
+			err = xib_pindex(sb, pindex);
+			if (!err)
+				set_bit(bit, p);
+			else
+				goto out;
+		}
+	}
+
+out:
+	return err;
+}
+
+static int xib_restore(struct super_block *sb)
+{
+	int err;
+	aufs_bindex_t bindex, bend;
+	void *page;
+
+	err = -ENOMEM;
+	page = (void *)__get_free_page(GFP_NOFS);
+	if (unlikely(!page))
+		goto out;
+
+	err = 0;
+	bend = au_sbend(sb);
+	for (bindex = 0; !err && bindex <= bend; bindex++)
+		if (!bindex || is_sb_shared(sb, bindex, bindex - 1) < 0)
+			err = do_xib_restore
+				(sb, au_sbr(sb, bindex)->br_xino.xi_file, page);
+		else
+			AuDbg("b%d\n", bindex);
+	free_page((unsigned long)page);
+
+out:
+	return err;
+}
+
+int au_xib_trunc(struct super_block *sb)
+{
+	int err;
+	ssize_t sz;
+	loff_t pos;
+	struct au_xino_lock_dir ldir;
+	struct au_sbinfo *sbinfo;
+	unsigned long *p;
+	struct file *file;
+
+	SiMustWriteLock(sb);
+
+	err = 0;
+	sbinfo = au_sbi(sb);
+	if (!au_opt_test(sbinfo->si_mntflags, XINO))
+		goto out;
+
+	file = sbinfo->si_xib;
+	if (vfsub_f_size_read(file) <= PAGE_SIZE)
+		goto out;
+
+	au_xino_lock_dir(sb, file, &ldir);
+	/* mnt_want_write() is unnecessary here */
+	file = au_xino_create2(sbinfo->si_xib, NULL);
+	au_xino_unlock_dir(&ldir);
+	err = PTR_ERR(file);
+	if (IS_ERR(file))
+		goto out;
+	fput(sbinfo->si_xib);
+	sbinfo->si_xib = file;
+
+	p = sbinfo->si_xib_buf;
+	memset(p, 0, PAGE_SIZE);
+	pos = 0;
+	sz = xino_fwrite(sbinfo->si_xwrite, sbinfo->si_xib, p, PAGE_SIZE, &pos);
+	if (unlikely(sz != PAGE_SIZE)) {
+		err = sz;
+		AuIOErr("err %d\n", err);
+		if (sz >= 0)
+			err = -EIO;
+		goto out;
+	}
+
+	mutex_lock(&sbinfo->si_xib_mtx);
+	/* mnt_want_write() is unnecessary here */
+	err = xib_restore(sb);
+	mutex_unlock(&sbinfo->si_xib_mtx);
+
+out:
+	return err;
+}
+
+/* ---------------------------------------------------------------------- */
+
+/*
+ * xino mount option handlers
+ */
+
+/* xino bitmap */
+static void xino_clear_xib(struct super_block *sb)
+{
+	struct au_sbinfo *sbinfo;
+
+	SiMustWriteLock(sb);
+
+	sbinfo = au_sbi(sb);
+	sbinfo->si_xread = NULL;
+	sbinfo->si_xwrite = NULL;
+	if (sbinfo->si_xib)
+		fput(sbinfo->si_xib);
+	sbinfo->si_xib = NULL;
+	free_page((unsigned long)sbinfo->si_xib_buf);
+	sbinfo->si_xib_buf = NULL;
+}
+
+static int au_xino_set_xib(struct super_block *sb, struct file *base)
+{
+	int err;
+	loff_t pos;
+	struct au_sbinfo *sbinfo;
+	struct file *file;
+
+	SiMustWriteLock(sb);
+
+	sbinfo = au_sbi(sb);
+	file = au_xino_create2(base, sbinfo->si_xib);
+	err = PTR_ERR(file);
+	if (IS_ERR(file))
+		goto out;
+	if (sbinfo->si_xib)
+		fput(sbinfo->si_xib);
+	sbinfo->si_xib = file;
+	sbinfo->si_xread = vfs_readf(file);
+	sbinfo->si_xwrite = vfs_writef(file);
+
+	err = -ENOMEM;
+	if (!sbinfo->si_xib_buf)
+		sbinfo->si_xib_buf = (void *)get_zeroed_page(GFP_NOFS);
+	if (unlikely(!sbinfo->si_xib_buf))
+		goto out_unset;
+
+	sbinfo->si_xib_last_pindex = 0;
+	sbinfo->si_xib_next_bit = 0;
+	if (vfsub_f_size_read(file) < PAGE_SIZE) {
+		pos = 0;
+		err = xino_fwrite(sbinfo->si_xwrite, file, sbinfo->si_xib_buf,
+				  PAGE_SIZE, &pos);
+		if (unlikely(err != PAGE_SIZE))
+			goto out_free;
+	}
+	err = 0;
+	goto out; /* success */
+
+out_free:
+	free_page((unsigned long)sbinfo->si_xib_buf);
+	sbinfo->si_xib_buf = NULL;
+	if (err >= 0)
+		err = -EIO;
+out_unset:
+	fput(sbinfo->si_xib);
+	sbinfo->si_xib = NULL;
+	sbinfo->si_xread = NULL;
+	sbinfo->si_xwrite = NULL;
+out:
+	return err;
+}
+
+/* xino for each branch */
+static void xino_clear_br(struct super_block *sb)
+{
+	aufs_bindex_t bindex, bend;
+	struct au_branch *br;
+
+	bend = au_sbend(sb);
+	for (bindex = 0; bindex <= bend; bindex++) {
+		br = au_sbr(sb, bindex);
+		if (!br || !br->br_xino.xi_file)
+			continue;
+
+		fput(br->br_xino.xi_file);
+		br->br_xino.xi_file = NULL;
+	}
+}
+
+static int au_xino_set_br(struct super_block *sb, struct file *base)
+{
+	int err;
+	ino_t ino;
+	aufs_bindex_t bindex, bend, bshared;
+	struct {
+		struct file *old, *new;
+	} *fpair, *p;
+	struct au_branch *br;
+	struct inode *inode;
+	vfs_writef_t writef;
+
+	SiMustWriteLock(sb);
+
+	err = -ENOMEM;
+	bend = au_sbend(sb);
+	fpair = kcalloc(bend + 1, sizeof(*fpair), GFP_NOFS);
+	if (unlikely(!fpair))
+		goto out;
+
+	inode = d_inode(sb->s_root);
+	ino = AUFS_ROOT_INO;
+	writef = au_sbi(sb)->si_xwrite;
+	for (bindex = 0, p = fpair; bindex <= bend; bindex++, p++) {
+		br = au_sbr(sb, bindex);
+		bshared = is_sb_shared(sb, bindex, bindex - 1);
+		if (bshared >= 0) {
+			/* shared xino */
+			*p = fpair[bshared];
+			get_file(p->new);
+		}
+
+		if (!p->new) {
+			/* new xino */
+			p->old = br->br_xino.xi_file;
+			p->new = au_xino_create2(base, br->br_xino.xi_file);
+			err = PTR_ERR(p->new);
+			if (IS_ERR(p->new)) {
+				p->new = NULL;
+				goto out_pair;
+			}
+		}
+
+		err = au_xino_do_write(writef, p->new,
+				       au_h_iptr(inode, bindex)->i_ino, ino);
+		if (unlikely(err))
+			goto out_pair;
+	}
+
+	for (bindex = 0, p = fpair; bindex <= bend; bindex++, p++) {
+		br = au_sbr(sb, bindex);
+		if (br->br_xino.xi_file)
+			fput(br->br_xino.xi_file);
+		get_file(p->new);
+		br->br_xino.xi_file = p->new;
+	}
+
+out_pair:
+	for (bindex = 0, p = fpair; bindex <= bend; bindex++, p++)
+		if (p->new)
+			fput(p->new);
+		else
+			break;
+	kfree(fpair);
+out:
+	return err;
+}
+
+void au_xino_clr(struct super_block *sb)
+{
+	struct au_sbinfo *sbinfo;
+
+	au_xigen_clr(sb);
+	xino_clear_xib(sb);
+	xino_clear_br(sb);
+	sbinfo = au_sbi(sb);
+	/* lvalue, do not call au_mntflags() */
+	au_opt_clr(sbinfo->si_mntflags, XINO);
+}
+
+int au_xino_set(struct super_block *sb, struct au_opt_xino *xino, int remount)
+{
+	int err, skip;
+	struct dentry *parent, *cur_parent;
+	struct qstr *dname, *cur_name;
+	struct file *cur_xino;
+	struct inode *dir;
+	struct au_sbinfo *sbinfo;
+
+	SiMustWriteLock(sb);
+
+	err = 0;
+	sbinfo = au_sbi(sb);
+	parent = dget_parent(xino->file->f_path.dentry);
+	if (remount) {
+		skip = 0;
+		dname = &xino->file->f_path.dentry->d_name;
+		cur_xino = sbinfo->si_xib;
+		if (cur_xino) {
+			cur_parent = dget_parent(cur_xino->f_path.dentry);
+			cur_name = &cur_xino->f_path.dentry->d_name;
+			skip = (cur_parent == parent
+				&& au_qstreq(dname, cur_name));
+			dput(cur_parent);
+		}
+		if (skip)
+			goto out;
+	}
+
+	au_opt_set(sbinfo->si_mntflags, XINO);
+	dir = d_inode(parent);
+	mutex_lock_nested(&dir->i_mutex, AuLsc_I_PARENT);
+	/* mnt_want_write() is unnecessary here */
+	err = au_xino_set_xib(sb, xino->file);
+	if (!err)
+		err = au_xigen_set(sb, xino->file);
+	if (!err)
+		err = au_xino_set_br(sb, xino->file);
+	mutex_unlock(&dir->i_mutex);
+	if (!err)
+		goto out; /* success */
+
+	/* reset all */
+	AuIOErr("failed creating xino(%d).\n", err);
+	au_xigen_clr(sb);
+	xino_clear_xib(sb);
+
+out:
+	dput(parent);
+	return err;
+}
+
+/* ---------------------------------------------------------------------- */
+
+/*
+ * create a xinofile at the default place/path.
+ */
+struct file *au_xino_def(struct super_block *sb)
+{
+	struct file *file;
+	char *page, *p;
+	struct au_branch *br;
+	struct super_block *h_sb;
+	struct path path;
+	aufs_bindex_t bend, bindex, bwr;
+
+	br = NULL;
+	bend = au_sbend(sb);
+	bwr = -1;
+	for (bindex = 0; bindex <= bend; bindex++) {
+		br = au_sbr(sb, bindex);
+		if (au_br_writable(br->br_perm)
+		    && !au_test_fs_bad_xino(au_br_sb(br))) {
+			bwr = bindex;
+			break;
+		}
+	}
+
+	if (bwr >= 0) {
+		file = ERR_PTR(-ENOMEM);
+		page = (void *)__get_free_page(GFP_NOFS);
+		if (unlikely(!page))
+			goto out;
+		path.mnt = au_br_mnt(br);
+		path.dentry = au_h_dptr(sb->s_root, bwr);
+		p = d_path(&path, page, PATH_MAX - sizeof(AUFS_XINO_FNAME));
+		file = (void *)p;
+		if (!IS_ERR(p)) {
+			strcat(p, "/" AUFS_XINO_FNAME);
+			AuDbg("%s\n", p);
+			file = au_xino_create(sb, p, /*silent*/0);
+			if (!IS_ERR(file))
+				au_xino_brid_set(sb, br->br_id);
+		}
+		free_page((unsigned long)page);
+	} else {
+		file = au_xino_create(sb, AUFS_XINO_DEFPATH, /*silent*/0);
+		if (IS_ERR(file))
+			goto out;
+		h_sb = file->f_path.dentry->d_sb;
+		if (unlikely(au_test_fs_bad_xino(h_sb))) {
+			pr_err("xino doesn't support %s(%s)\n",
+			       AUFS_XINO_DEFPATH, au_sbtype(h_sb));
+			fput(file);
+			file = ERR_PTR(-EINVAL);
+		}
+		if (!IS_ERR(file))
+			au_xino_brid_set(sb, -1);
+	}
+
+out:
+	return file;
+}
+
+/* ---------------------------------------------------------------------- */
+
+int au_xino_path(struct seq_file *seq, struct file *file)
+{
+	int err;
+
+	err = au_seq_path(seq, &file->f_path);
+	if (unlikely(err))
+		goto out;
+
+#define Deleted "\\040(deleted)"
+	seq->count -= sizeof(Deleted) - 1;
+	AuDebugOn(memcmp(seq->buf + seq->count, Deleted,
+			 sizeof(Deleted) - 1));
+#undef Deleted
+
+out:
+	return err;
+}
--- zfcpdump-kernel-4.4.orig/fs/autofs4/autofs_i.h
+++ zfcpdump-kernel-4.4/fs/autofs4/autofs_i.h
@@ -79,9 +79,13 @@ struct autofs_info {
 };
 
 #define AUTOFS_INF_EXPIRING	(1<<0) /* dentry is in the process of expiring */
-#define AUTOFS_INF_NO_RCU	(1<<1) /* the dentry is being considered
+#define AUTOFS_INF_WANT_EXPIRE	(1<<1) /* the dentry is being considered
 					* for expiry, so RCU_walk is
-					* not permitted
+					* not permitted.  If it progresses to
+					* actual expiry attempt, the flag is
+					* not cleared when EXPIRING is set -
+					* in that case it gets cleared only
+					* when it comes to clearing EXPIRING.
 					*/
 #define AUTOFS_INF_PENDING	(1<<2) /* dentry pending mount */
 
--- zfcpdump-kernel-4.4.orig/fs/autofs4/expire.c
+++ zfcpdump-kernel-4.4/fs/autofs4/expire.c
@@ -315,19 +315,17 @@ struct dentry *autofs4_expire_direct(str
 	if (ino->flags & AUTOFS_INF_PENDING)
 		goto out;
 	if (!autofs4_direct_busy(mnt, root, timeout, do_now)) {
-		ino->flags |= AUTOFS_INF_NO_RCU;
+		ino->flags |= AUTOFS_INF_WANT_EXPIRE;
 		spin_unlock(&sbi->fs_lock);
 		synchronize_rcu();
 		spin_lock(&sbi->fs_lock);
 		if (!autofs4_direct_busy(mnt, root, timeout, do_now)) {
 			ino->flags |= AUTOFS_INF_EXPIRING;
-			smp_mb();
-			ino->flags &= ~AUTOFS_INF_NO_RCU;
 			init_completion(&ino->expire_complete);
 			spin_unlock(&sbi->fs_lock);
 			return root;
 		}
-		ino->flags &= ~AUTOFS_INF_NO_RCU;
+		ino->flags &= ~AUTOFS_INF_WANT_EXPIRE;
 	}
 out:
 	spin_unlock(&sbi->fs_lock);
@@ -417,6 +415,7 @@ static struct dentry *should_expire(stru
 	}
 	return NULL;
 }
+
 /*
  * Find an eligible tree to time-out
  * A tree is eligible if :-
@@ -432,6 +431,7 @@ struct dentry *autofs4_expire_indirect(s
 	struct dentry *root = sb->s_root;
 	struct dentry *dentry;
 	struct dentry *expired;
+	struct dentry *found;
 	struct autofs_info *ino;
 
 	if (!root)
@@ -442,48 +442,54 @@ struct dentry *autofs4_expire_indirect(s
 
 	dentry = NULL;
 	while ((dentry = get_next_positive_subdir(dentry, root))) {
+		int flags = how;
+
 		spin_lock(&sbi->fs_lock);
 		ino = autofs4_dentry_ino(dentry);
-		if (ino->flags & AUTOFS_INF_NO_RCU)
-			expired = NULL;
-		else
-			expired = should_expire(dentry, mnt, timeout, how);
-		if (!expired) {
+		if (ino->flags & AUTOFS_INF_WANT_EXPIRE) {
 			spin_unlock(&sbi->fs_lock);
 			continue;
 		}
+		spin_unlock(&sbi->fs_lock);
+
+		expired = should_expire(dentry, mnt, timeout, flags);
+		if (!expired)
+			continue;
+
+		spin_lock(&sbi->fs_lock);
 		ino = autofs4_dentry_ino(expired);
-		ino->flags |= AUTOFS_INF_NO_RCU;
+		ino->flags |= AUTOFS_INF_WANT_EXPIRE;
 		spin_unlock(&sbi->fs_lock);
 		synchronize_rcu();
-		spin_lock(&sbi->fs_lock);
-		if (should_expire(expired, mnt, timeout, how)) {
-			if (expired != dentry)
-				dput(dentry);
-			goto found;
-		}
 
-		ino->flags &= ~AUTOFS_INF_NO_RCU;
+		/* Make sure a reference is not taken on found if
+		 * things have changed.
+		 */
+		flags &= ~AUTOFS_EXP_LEAVES;
+		found = should_expire(expired, mnt, timeout, how);
+		if (!found || found != expired)
+			/* Something has changed, continue */
+			goto next;
+
 		if (expired != dentry)
-			dput(expired);
+			dput(dentry);
+
+		spin_lock(&sbi->fs_lock);
+		goto found;
+next:
+		spin_lock(&sbi->fs_lock);
+		ino->flags &= ~AUTOFS_INF_WANT_EXPIRE;
 		spin_unlock(&sbi->fs_lock);
+		if (expired != dentry)
+			dput(expired);
 	}
 	return NULL;
 
 found:
 	DPRINTK("returning %p %pd", expired, expired);
 	ino->flags |= AUTOFS_INF_EXPIRING;
-	smp_mb();
-	ino->flags &= ~AUTOFS_INF_NO_RCU;
 	init_completion(&ino->expire_complete);
 	spin_unlock(&sbi->fs_lock);
-	spin_lock(&sbi->lookup_lock);
-	spin_lock(&expired->d_parent->d_lock);
-	spin_lock_nested(&expired->d_lock, DENTRY_D_LOCK_NESTED);
-	list_move(&expired->d_parent->d_subdirs, &expired->d_child);
-	spin_unlock(&expired->d_lock);
-	spin_unlock(&expired->d_parent->d_lock);
-	spin_unlock(&sbi->lookup_lock);
 	return expired;
 }
 
@@ -492,15 +498,27 @@ int autofs4_expire_wait(struct dentry *d
 	struct autofs_sb_info *sbi = autofs4_sbi(dentry->d_sb);
 	struct autofs_info *ino = autofs4_dentry_ino(dentry);
 	int status;
+	int state;
 
 	/* Block on any pending expire */
-	if (!(ino->flags & (AUTOFS_INF_EXPIRING | AUTOFS_INF_NO_RCU)))
+	if (!(ino->flags & AUTOFS_INF_WANT_EXPIRE))
 		return 0;
 	if (rcu_walk)
 		return -ECHILD;
 
+retry:
 	spin_lock(&sbi->fs_lock);
-	if (ino->flags & AUTOFS_INF_EXPIRING) {
+	state = ino->flags & (AUTOFS_INF_WANT_EXPIRE | AUTOFS_INF_EXPIRING);
+	if (state == AUTOFS_INF_WANT_EXPIRE) {
+		spin_unlock(&sbi->fs_lock);
+		/*
+		 * Possibly being selected for expire, wait until
+		 * it's selected or not.
+		 */
+		schedule_timeout_uninterruptible(HZ/10);
+		goto retry;
+	}
+	if (state & AUTOFS_INF_EXPIRING) {
 		spin_unlock(&sbi->fs_lock);
 
 		DPRINTK("waiting for expire %p name=%pd", dentry, dentry);
@@ -551,7 +569,7 @@ int autofs4_expire_run(struct super_bloc
 	ino = autofs4_dentry_ino(dentry);
 	/* avoid rapid-fire expire attempts if expiry fails */
 	ino->last_used = now;
-	ino->flags &= ~AUTOFS_INF_EXPIRING;
+	ino->flags &= ~(AUTOFS_INF_EXPIRING|AUTOFS_INF_WANT_EXPIRE);
 	complete_all(&ino->expire_complete);
 	spin_unlock(&sbi->fs_lock);
 
@@ -579,7 +597,7 @@ int autofs4_do_expire_multi(struct super
 		spin_lock(&sbi->fs_lock);
 		/* avoid rapid-fire expire attempts if expiry fails */
 		ino->last_used = now;
-		ino->flags &= ~AUTOFS_INF_EXPIRING;
+		ino->flags &= ~(AUTOFS_INF_EXPIRING|AUTOFS_INF_WANT_EXPIRE);
 		complete_all(&ino->expire_complete);
 		spin_unlock(&sbi->fs_lock);
 		dput(dentry);
--- zfcpdump-kernel-4.4.orig/fs/autofs4/root.c
+++ zfcpdump-kernel-4.4/fs/autofs4/root.c
@@ -455,7 +455,7 @@ static int autofs4_d_manage(struct dentr
 		 * a mount-trap.
 		 */
 		struct inode *inode;
-		if (ino->flags & (AUTOFS_INF_EXPIRING | AUTOFS_INF_NO_RCU))
+		if (ino->flags & AUTOFS_INF_WANT_EXPIRE)
 			return 0;
 		if (d_mountpoint(dentry))
 			return 0;
--- zfcpdump-kernel-4.4.orig/fs/autofs4/waitq.c
+++ zfcpdump-kernel-4.4/fs/autofs4/waitq.c
@@ -427,8 +427,8 @@ int autofs4_wait(struct autofs_sb_info *
 		memcpy(&wq->name, &qstr, sizeof(struct qstr));
 		wq->dev = autofs4_get_dev(sbi);
 		wq->ino = autofs4_get_ino(sbi);
-		wq->uid = current_uid();
-		wq->gid = current_gid();
+		wq->uid = current_real_cred()->uid;
+		wq->gid = current_real_cred()->gid;
 		wq->pid = pid;
 		wq->tgid = tgid;
 		wq->status = -EINTR; /* Status return if interrupted */
--- zfcpdump-kernel-4.4.orig/fs/block_dev.c
+++ zfcpdump-kernel-4.4/fs/block_dev.c
@@ -395,7 +395,7 @@ int bdev_read_page(struct block_device *
 	if (!ops->rw_page || bdev_get_integrity(bdev))
 		return result;
 
-	result = blk_queue_enter(bdev->bd_queue, GFP_KERNEL);
+	result = blk_queue_enter(bdev->bd_queue, false);
 	if (result)
 		return result;
 	result = ops->rw_page(bdev, sector + get_start_sect(bdev), page, READ);
@@ -432,7 +432,7 @@ int bdev_write_page(struct block_device
 
 	if (!ops->rw_page || bdev_get_integrity(bdev))
 		return -EOPNOTSUPP;
-	result = blk_queue_enter(bdev->bd_queue, GFP_KERNEL);
+	result = blk_queue_enter(bdev->bd_queue, false);
 	if (result)
 		return result;
 
@@ -1424,9 +1424,14 @@ struct block_device *blkdev_get_by_path(
 					void *holder)
 {
 	struct block_device *bdev;
+	int perm = 0;
 	int err;
 
-	bdev = lookup_bdev(path);
+	if (mode & FMODE_READ)
+		perm |= MAY_READ;
+	if (mode & FMODE_WRITE)
+		perm |= MAY_WRITE;
+	bdev = lookup_bdev(path, perm);
 	if (IS_ERR(bdev))
 		return bdev;
 
@@ -1505,6 +1510,20 @@ static int blkdev_open(struct inode * in
 	if (bdev == NULL)
 		return -ENOMEM;
 
+	/*
+	 * A negative i_writecount for bdev->bd_inode means that the bdev
+	 * or one of its paritions is mounted in a user namespace. Deny
+	 * writing for non-root in this case, otherwise an unprivileged
+	 * user can attack the kernel by modifying the backing store of a
+	 * mounted filesystem.
+	 */
+	if ((filp->f_mode & FMODE_WRITE) &&
+	    !file_ns_capable(filp, &init_user_ns, CAP_SYS_ADMIN) &&
+	    !atomic_inc_unless_negative(&bdev->bd_inode->i_writecount)) {
+		bdput(bdev);
+		return -EBUSY;
+	}
+
 	filp->f_mapping = bdev->bd_inode->i_mapping;
 
 	return blkdev_get(bdev, filp->f_mode, filp);
@@ -1606,6 +1625,9 @@ EXPORT_SYMBOL(blkdev_put);
 static int blkdev_close(struct inode * inode, struct file * filp)
 {
 	struct block_device *bdev = I_BDEV(filp->f_mapping->host);
+	if (filp->f_mode & FMODE_WRITE &&
+	    !file_ns_capable(filp, &init_user_ns, CAP_SYS_ADMIN))
+		atomic_dec(&bdev->bd_inode->i_writecount);
 	blkdev_put(bdev, filp->f_mode);
 	return 0;
 }
@@ -1739,12 +1761,14 @@ EXPORT_SYMBOL(ioctl_by_bdev);
 /**
  * lookup_bdev  - lookup a struct block_device by name
  * @pathname:	special file representing the block device
+ * @mask:	rights to check for (%MAY_READ, %MAY_WRITE, %MAY_EXEC)
  *
  * Get a reference to the blockdevice at @pathname in the current
  * namespace if possible and return it.  Return ERR_PTR(error)
- * otherwise.
+ * otherwise.  If @mask is non-zero, check for access rights to the
+ * inode at @pathname.
  */
-struct block_device *lookup_bdev(const char *pathname)
+struct block_device *lookup_bdev(const char *pathname, int mask)
 {
 	struct block_device *bdev;
 	struct inode *inode;
@@ -1759,6 +1783,11 @@ struct block_device *lookup_bdev(const c
 		return ERR_PTR(error);
 
 	inode = d_backing_inode(path.dentry);
+	if (mask != 0 && !capable(CAP_SYS_ADMIN)) {
+		error = __inode_permission(inode, mask);
+		if (error)
+			goto fail;
+	}
 	error = -ENOTBLK;
 	if (!S_ISBLK(inode->i_mode))
 		goto fail;
--- zfcpdump-kernel-4.4.orig/fs/btrfs/async-thread.c
+++ zfcpdump-kernel-4.4/fs/btrfs/async-thread.c
@@ -328,8 +328,8 @@ static inline void __btrfs_queue_work(st
 		list_add_tail(&work->ordered_list, &wq->ordered_list);
 		spin_unlock_irqrestore(&wq->list_lock, flags);
 	}
-	queue_work(wq->normal_wq, &work->normal_work);
 	trace_btrfs_work_queued(work);
+	queue_work(wq->normal_wq, &work->normal_work);
 }
 
 void btrfs_queue_work(struct btrfs_workqueue *wq,
--- zfcpdump-kernel-4.4.orig/fs/btrfs/backref.c
+++ zfcpdump-kernel-4.4/fs/btrfs/backref.c
@@ -1417,7 +1417,8 @@ char *btrfs_ref_to_path(struct btrfs_roo
 			read_extent_buffer(eb, dest + bytes_left,
 					   name_off, name_len);
 		if (eb != eb_in) {
-			btrfs_tree_read_unlock_blocking(eb);
+			if (!path->skip_locking)
+				btrfs_tree_read_unlock_blocking(eb);
 			free_extent_buffer(eb);
 		}
 		ret = btrfs_find_item(fs_root, path, parent, 0,
@@ -1437,9 +1438,10 @@ char *btrfs_ref_to_path(struct btrfs_roo
 		eb = path->nodes[0];
 		/* make sure we can use eb after releasing the path */
 		if (eb != eb_in) {
-			atomic_inc(&eb->refs);
-			btrfs_tree_read_lock(eb);
-			btrfs_set_lock_blocking_rw(eb, BTRFS_READ_LOCK);
+			if (!path->skip_locking)
+				btrfs_set_lock_blocking_rw(eb, BTRFS_READ_LOCK);
+			path->nodes[0] = NULL;
+			path->locks[0] = 0;
 		}
 		btrfs_release_path(path);
 		iref = btrfs_item_ptr(eb, slot, struct btrfs_inode_ref);
--- zfcpdump-kernel-4.4.orig/fs/btrfs/ctree.c
+++ zfcpdump-kernel-4.4/fs/btrfs/ctree.c
@@ -1551,6 +1551,7 @@ noinline int btrfs_cow_block(struct btrf
 		       trans->transid, root->fs_info->generation);
 
 	if (!should_cow_block(trans, root, buf)) {
+		trans->dirty = true;
 		*cow_ret = buf;
 		return 0;
 	}
@@ -2773,8 +2774,10 @@ again:
 			 * then we don't want to set the path blocking,
 			 * so we test it here
 			 */
-			if (!should_cow_block(trans, root, b))
+			if (!should_cow_block(trans, root, b)) {
+				trans->dirty = true;
 				goto cow_done;
+			}
 
 			/*
 			 * must have write locks on this node and the
--- zfcpdump-kernel-4.4.orig/fs/btrfs/ctree.h
+++ zfcpdump-kernel-4.4/fs/btrfs/ctree.h
@@ -1572,7 +1572,7 @@ struct btrfs_fs_info {
 
 	spinlock_t delayed_iput_lock;
 	struct list_head delayed_iputs;
-	struct rw_semaphore delayed_iput_sem;
+	struct mutex cleaner_delayed_iput_mutex;
 
 	/* this protects tree_mod_seq_list */
 	spinlock_t tree_mod_seq_lock;
@@ -1770,6 +1770,7 @@ struct btrfs_fs_info {
 	struct btrfs_workqueue *qgroup_rescan_workers;
 	struct completion qgroup_rescan_completion;
 	struct btrfs_work qgroup_rescan_work;
+	bool qgroup_rescan_running;	/* protected by qgroup_rescan_lock */
 
 	/* filesystem state */
 	unsigned long fs_state;
@@ -4014,6 +4015,7 @@ void btrfs_test_inode_set_ops(struct ino
 
 /* ioctl.c */
 long btrfs_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
+long btrfs_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
 void btrfs_update_iflags(struct inode *inode);
 void btrfs_inherit_iflags(struct inode *inode, struct inode *dir);
 int btrfs_is_empty_uuid(u8 *uuid);
--- zfcpdump-kernel-4.4.orig/fs/btrfs/delayed-inode.c
+++ zfcpdump-kernel-4.4/fs/btrfs/delayed-inode.c
@@ -1694,7 +1694,7 @@ int btrfs_should_delete_dir_index(struct
  *
  */
 int btrfs_readdir_delayed_dir_index(struct dir_context *ctx,
-				    struct list_head *ins_list)
+				    struct list_head *ins_list, bool *emitted)
 {
 	struct btrfs_dir_item *di;
 	struct btrfs_delayed_item *curr, *next;
@@ -1738,6 +1738,7 @@ int btrfs_readdir_delayed_dir_index(stru
 
 		if (over)
 			return 1;
+		*emitted = true;
 	}
 	return 0;
 }
--- zfcpdump-kernel-4.4.orig/fs/btrfs/delayed-inode.h
+++ zfcpdump-kernel-4.4/fs/btrfs/delayed-inode.h
@@ -144,7 +144,7 @@ void btrfs_put_delayed_items(struct list
 int btrfs_should_delete_dir_index(struct list_head *del_list,
 				  u64 index);
 int btrfs_readdir_delayed_dir_index(struct dir_context *ctx,
-				    struct list_head *ins_list);
+				    struct list_head *ins_list, bool *emitted);
 
 /* for init */
 int __init btrfs_delayed_inode_init(void);
--- zfcpdump-kernel-4.4.orig/fs/btrfs/disk-io.c
+++ zfcpdump-kernel-4.4/fs/btrfs/disk-io.c
@@ -1582,8 +1582,23 @@ int btrfs_init_fs_root(struct btrfs_root
 	ret = get_anon_bdev(&root->anon_dev);
 	if (ret)
 		goto free_writers;
+
+	mutex_lock(&root->objectid_mutex);
+	ret = btrfs_find_highest_objectid(root,
+					&root->highest_objectid);
+	if (ret) {
+		mutex_unlock(&root->objectid_mutex);
+		goto free_root_dev;
+	}
+
+	ASSERT(root->highest_objectid <= BTRFS_LAST_FREE_OBJECTID);
+
+	mutex_unlock(&root->objectid_mutex);
+
 	return 0;
 
+free_root_dev:
+	free_anon_bdev(root->anon_dev);
 free_writers:
 	btrfs_free_subvolume_writers(root->subv_writers);
 fail:
@@ -1762,7 +1777,6 @@ static int cleaner_kthread(void *arg)
 	int again;
 	struct btrfs_trans_handle *trans;
 
-	set_freezable();
 	do {
 		again = 0;
 
@@ -1782,7 +1796,10 @@ static int cleaner_kthread(void *arg)
 			goto sleep;
 		}
 
+		mutex_lock(&root->fs_info->cleaner_delayed_iput_mutex);
 		btrfs_run_delayed_iputs(root);
+		mutex_unlock(&root->fs_info->cleaner_delayed_iput_mutex);
+
 		again = btrfs_clean_one_deleted_snapshot(root);
 		mutex_unlock(&root->fs_info->cleaner_mutex);
 
@@ -2259,6 +2276,7 @@ static void btrfs_init_qgroup(struct btr
 	fs_info->quota_enabled = 0;
 	fs_info->pending_quota_state = 0;
 	fs_info->qgroup_ulist = NULL;
+	fs_info->qgroup_rescan_running = false;
 	mutex_init(&fs_info->qgroup_rescan_lock);
 }
 
@@ -2542,8 +2560,8 @@ int open_ctree(struct super_block *sb,
 	mutex_init(&fs_info->delete_unused_bgs_mutex);
 	mutex_init(&fs_info->reloc_mutex);
 	mutex_init(&fs_info->delalloc_root_mutex);
+	mutex_init(&fs_info->cleaner_delayed_iput_mutex);
 	seqlock_init(&fs_info->profiles_lock);
-	init_rwsem(&fs_info->delayed_iput_sem);
 
 	INIT_LIST_HEAD(&fs_info->dirty_cowonly_roots);
 	INIT_LIST_HEAD(&fs_info->space_info);
@@ -2668,6 +2686,7 @@ int open_ctree(struct super_block *sb,
 	if (btrfs_check_super_csum(bh->b_data)) {
 		printk(KERN_ERR "BTRFS: superblock checksum mismatch\n");
 		err = -EINVAL;
+		brelse(bh);
 		goto fail_alloc;
 	}
 
@@ -2900,6 +2919,18 @@ retry_root_backup:
 	tree_root->commit_root = btrfs_root_node(tree_root);
 	btrfs_set_root_refs(&tree_root->root_item, 1);
 
+	mutex_lock(&tree_root->objectid_mutex);
+	ret = btrfs_find_highest_objectid(tree_root,
+					&tree_root->highest_objectid);
+	if (ret) {
+		mutex_unlock(&tree_root->objectid_mutex);
+		goto recovery_tree_root;
+	}
+
+	ASSERT(tree_root->highest_objectid <= BTRFS_LAST_FREE_OBJECTID);
+
+	mutex_unlock(&tree_root->objectid_mutex);
+
 	ret = btrfs_read_roots(fs_info, tree_root);
 	if (ret)
 		goto recovery_tree_root;
@@ -3781,7 +3812,7 @@ void close_ctree(struct btrfs_root *root
 	smp_mb();
 
 	/* wait for the qgroup rescan worker to stop */
-	btrfs_qgroup_wait_for_completion(fs_info);
+	btrfs_qgroup_wait_for_completion(fs_info, false);
 
 	/* wait for the uuid_scan task to finish */
 	down(&fs_info->uuid_tree_rescan_sem);
--- zfcpdump-kernel-4.4.orig/fs/btrfs/extent-tree.c
+++ zfcpdump-kernel-4.4/fs/btrfs/extent-tree.c
@@ -4086,8 +4086,10 @@ commit_trans:
 		    !atomic_read(&root->fs_info->open_ioctl_trans)) {
 			need_commit--;
 
-			if (need_commit > 0)
+			if (need_commit > 0) {
+				btrfs_start_delalloc_roots(fs_info, 0, -1);
 				btrfs_wait_ordered_roots(fs_info, -1);
+			}
 
 			trans = btrfs_join_transaction(root);
 			if (IS_ERR(trans))
@@ -4100,11 +4102,12 @@ commit_trans:
 				if (ret)
 					return ret;
 				/*
-				 * make sure that all running delayed iput are
-				 * done
+				 * The cleaner kthread might still be doing iput
+				 * operations. Wait for it to finish so that
+				 * more space is released.
 				 */
-				down_write(&root->fs_info->delayed_iput_sem);
-				up_write(&root->fs_info->delayed_iput_sem);
+				mutex_lock(&root->fs_info->cleaner_delayed_iput_mutex);
+				mutex_unlock(&root->fs_info->cleaner_delayed_iput_mutex);
 				goto again;
 			} else {
 				btrfs_end_transaction(trans, root);
@@ -7853,7 +7856,7 @@ btrfs_init_new_buffer(struct btrfs_trans
 		set_extent_dirty(&trans->transaction->dirty_pages, buf->start,
 			 buf->start + buf->len - 1, GFP_NOFS);
 	}
-	trans->blocks_used++;
+	trans->dirty = true;
 	/* this returns a buffer locked for blocking */
 	return buf;
 }
--- zfcpdump-kernel-4.4.orig/fs/btrfs/extent_io.c
+++ zfcpdump-kernel-4.4/fs/btrfs/extent_io.c
@@ -2786,12 +2786,6 @@ struct bio *btrfs_bio_clone(struct bio *
 		btrfs_bio->csum = NULL;
 		btrfs_bio->csum_allocated = NULL;
 		btrfs_bio->end_io = NULL;
-
-#ifdef CONFIG_BLK_CGROUP
-		/* FIXME, put this into bio_clone_bioset */
-		if (bio->bi_css)
-			bio_associate_blkcg(new, bio->bi_css);
-#endif
 	}
 	return new;
 }
--- zfcpdump-kernel-4.4.orig/fs/btrfs/file.c
+++ zfcpdump-kernel-4.4/fs/btrfs/file.c
@@ -1526,27 +1526,24 @@ static noinline ssize_t __btrfs_buffered
 
 		reserve_bytes = num_pages << PAGE_CACHE_SHIFT;
 
-		if (BTRFS_I(inode)->flags & (BTRFS_INODE_NODATACOW |
-					     BTRFS_INODE_PREALLOC)) {
-			ret = check_can_nocow(inode, pos, &write_bytes);
-			if (ret < 0)
-				break;
-			if (ret > 0) {
-				/*
-				 * For nodata cow case, no need to reserve
-				 * data space.
-				 */
-				only_release_metadata = true;
-				/*
-				 * our prealloc extent may be smaller than
-				 * write_bytes, so scale down.
-				 */
-				num_pages = DIV_ROUND_UP(write_bytes + offset,
-							 PAGE_CACHE_SIZE);
-				reserve_bytes = num_pages << PAGE_CACHE_SHIFT;
-				goto reserve_metadata;
-			}
+		if ((BTRFS_I(inode)->flags & (BTRFS_INODE_NODATACOW |
+					      BTRFS_INODE_PREALLOC)) &&
+		    check_can_nocow(inode, pos, &write_bytes) > 0) {
+			/*
+			 * For nodata cow case, no need to reserve
+			 * data space.
+			 */
+			only_release_metadata = true;
+			/*
+			 * our prealloc extent may be smaller than
+			 * write_bytes, so scale down.
+			 */
+			num_pages = DIV_ROUND_UP(write_bytes + offset,
+						 PAGE_CACHE_SIZE);
+			reserve_bytes = num_pages << PAGE_CACHE_SHIFT;
+			goto reserve_metadata;
 		}
+
 		ret = btrfs_check_data_free_space(inode, pos, write_bytes);
 		if (ret < 0)
 			break;
@@ -1885,7 +1882,7 @@ static int start_ordered_ops(struct inod
  */
 int btrfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
 {
-	struct dentry *dentry = file->f_path.dentry;
+	struct dentry *dentry = file_dentry(file);
 	struct inode *inode = d_inode(dentry);
 	struct btrfs_root *root = BTRFS_I(inode)->root;
 	struct btrfs_trans_handle *trans;
@@ -2932,7 +2929,7 @@ const struct file_operations btrfs_file_
 	.fallocate	= btrfs_fallocate,
 	.unlocked_ioctl	= btrfs_ioctl,
 #ifdef CONFIG_COMPAT
-	.compat_ioctl	= btrfs_ioctl,
+	.compat_ioctl	= btrfs_compat_ioctl,
 #endif
 };
 
--- zfcpdump-kernel-4.4.orig/fs/btrfs/inode-map.c
+++ zfcpdump-kernel-4.4/fs/btrfs/inode-map.c
@@ -515,7 +515,7 @@ out:
 	return ret;
 }
 
-static int btrfs_find_highest_objectid(struct btrfs_root *root, u64 *objectid)
+int btrfs_find_highest_objectid(struct btrfs_root *root, u64 *objectid)
 {
 	struct btrfs_path *path;
 	int ret;
@@ -555,13 +555,6 @@ int btrfs_find_free_objectid(struct btrf
 	int ret;
 	mutex_lock(&root->objectid_mutex);
 
-	if (unlikely(root->highest_objectid < BTRFS_FIRST_FREE_OBJECTID)) {
-		ret = btrfs_find_highest_objectid(root,
-						  &root->highest_objectid);
-		if (ret)
-			goto out;
-	}
-
 	if (unlikely(root->highest_objectid >= BTRFS_LAST_FREE_OBJECTID)) {
 		ret = -ENOSPC;
 		goto out;
--- zfcpdump-kernel-4.4.orig/fs/btrfs/inode-map.h
+++ zfcpdump-kernel-4.4/fs/btrfs/inode-map.h
@@ -9,5 +9,6 @@ int btrfs_save_ino_cache(struct btrfs_ro
 			 struct btrfs_trans_handle *trans);
 
 int btrfs_find_free_objectid(struct btrfs_root *root, u64 *objectid);
+int btrfs_find_highest_objectid(struct btrfs_root *root, u64 *objectid);
 
 #endif
--- zfcpdump-kernel-4.4.orig/fs/btrfs/inode.c
+++ zfcpdump-kernel-4.4/fs/btrfs/inode.c
@@ -3142,8 +3142,6 @@ void btrfs_run_delayed_iputs(struct btrf
 	if (empty)
 		return;
 
-	down_read(&fs_info->delayed_iput_sem);
-
 	spin_lock(&fs_info->delayed_iput_lock);
 	list_splice_init(&fs_info->delayed_iputs, &list);
 	spin_unlock(&fs_info->delayed_iput_lock);
@@ -3154,8 +3152,6 @@ void btrfs_run_delayed_iputs(struct btrf
 		iput(delayed->inode);
 		kfree(delayed);
 	}
-
-	up_read(&root->fs_info->delayed_iput_sem);
 }
 
 /*
@@ -5741,6 +5737,7 @@ static int btrfs_real_readdir(struct fil
 	char *name_ptr;
 	int name_len;
 	int is_curr = 0;	/* ctx->pos points to the current index? */
+	bool emitted;
 
 	/* FIXME, use a real flag for deciding about the key type */
 	if (root->fs_info->tree_root == root)
@@ -5769,6 +5766,7 @@ static int btrfs_real_readdir(struct fil
 	if (ret < 0)
 		goto err;
 
+	emitted = false;
 	while (1) {
 		leaf = path->nodes[0];
 		slot = path->slots[0];
@@ -5848,6 +5846,7 @@ skip:
 
 			if (over)
 				goto nopos;
+			emitted = true;
 			di_len = btrfs_dir_name_len(leaf, di) +
 				 btrfs_dir_data_len(leaf, di) + sizeof(*di);
 			di_cur += di_len;
@@ -5860,11 +5859,20 @@ next:
 	if (key_type == BTRFS_DIR_INDEX_KEY) {
 		if (is_curr)
 			ctx->pos++;
-		ret = btrfs_readdir_delayed_dir_index(ctx, &ins_list);
+		ret = btrfs_readdir_delayed_dir_index(ctx, &ins_list, &emitted);
 		if (ret)
 			goto nopos;
 	}
 
+	/*
+	 * If we haven't emitted any dir entry, we must not touch ctx->pos as
+	 * it was was set to the termination value in previous call. We assume
+	 * that "." and ".." were emitted if we reach this point and set the
+	 * termination value as well for an empty directory.
+	 */
+	if (ctx->pos > 2 && !emitted)
+		goto nopos;
+
 	/* Reached end of directory/root. Bump pos past the last item. */
 	ctx->pos++;
 
@@ -6481,7 +6489,7 @@ out_unlock_inode:
 static int btrfs_link(struct dentry *old_dentry, struct inode *dir,
 		      struct dentry *dentry)
 {
-	struct btrfs_trans_handle *trans;
+	struct btrfs_trans_handle *trans = NULL;
 	struct btrfs_root *root = BTRFS_I(dir)->root;
 	struct inode *inode = d_inode(old_dentry);
 	u64 index;
@@ -6507,6 +6515,7 @@ static int btrfs_link(struct dentry *old
 	trans = btrfs_start_transaction(root, 5);
 	if (IS_ERR(trans)) {
 		err = PTR_ERR(trans);
+		trans = NULL;
 		goto fail;
 	}
 
@@ -6540,9 +6549,10 @@ static int btrfs_link(struct dentry *old
 		btrfs_log_new_name(trans, inode, NULL, parent);
 	}
 
-	btrfs_end_transaction(trans, root);
 	btrfs_balance_delayed_items(root);
 fail:
+	if (trans)
+		btrfs_end_transaction(trans, root);
 	if (drop_inode) {
 		inode_dec_link_count(inode);
 		iput(inode);
@@ -7985,6 +7995,7 @@ static void btrfs_endio_direct_read(stru
 
 	kfree(dip);
 
+	dio_bio->bi_error = bio->bi_error;
 	dio_end_io(dio_bio, bio->bi_error);
 
 	if (io_bio->end_io)
@@ -8030,6 +8041,7 @@ out_test:
 
 	kfree(dip);
 
+	dio_bio->bi_error = bio->bi_error;
 	dio_end_io(dio_bio, bio->bi_error);
 	bio_put(bio);
 }
@@ -8534,15 +8546,28 @@ int btrfs_readpage(struct file *file, st
 static int btrfs_writepage(struct page *page, struct writeback_control *wbc)
 {
 	struct extent_io_tree *tree;
-
+	struct inode *inode = page->mapping->host;
+	int ret;
 
 	if (current->flags & PF_MEMALLOC) {
 		redirty_page_for_writepage(wbc, page);
 		unlock_page(page);
 		return 0;
 	}
+
+	/*
+	 * If we are under memory pressure we will call this directly from the
+	 * VM, we need to make sure we have the inode referenced for the ordered
+	 * extent.  If not just return like we didn't do anything.
+	 */
+	if (!igrab(inode)) {
+		redirty_page_for_writepage(wbc, page);
+		return AOP_WRITEPAGE_ACTIVATE;
+	}
 	tree = &BTRFS_I(page->mapping->host)->io_tree;
-	return extent_write_full_page(tree, page, btrfs_get_extent, wbc);
+	ret = extent_write_full_page(tree, page, btrfs_get_extent, wbc);
+	btrfs_add_delayed_iput(inode);
+	return ret;
 }
 
 static int btrfs_writepages(struct address_space *mapping,
@@ -9636,9 +9661,11 @@ static int btrfs_symlink(struct inode *d
 	/*
 	 * 2 items for inode item and ref
 	 * 2 items for dir items
+	 * 1 item for updating parent inode item
+	 * 1 item for the inline extent item
 	 * 1 item for xattr if selinux is on
 	 */
-	trans = btrfs_start_transaction(root, 5);
+	trans = btrfs_start_transaction(root, 7);
 	if (IS_ERR(trans))
 		return PTR_ERR(trans);
 
@@ -10017,7 +10044,7 @@ static const struct file_operations btrf
 	.iterate	= btrfs_real_readdir,
 	.unlocked_ioctl	= btrfs_ioctl,
 #ifdef CONFIG_COMPAT
-	.compat_ioctl	= btrfs_ioctl,
+	.compat_ioctl	= btrfs_compat_ioctl,
 #endif
 	.release        = btrfs_release_file,
 	.fsync		= btrfs_sync_file,
--- zfcpdump-kernel-4.4.orig/fs/btrfs/ioctl.c
+++ zfcpdump-kernel-4.4/fs/btrfs/ioctl.c
@@ -568,6 +568,10 @@ static noinline int create_subvol(struct
 		goto fail;
 	}
 
+	mutex_lock(&new_root->objectid_mutex);
+	new_root->highest_objectid = new_dirid;
+	mutex_unlock(&new_root->objectid_mutex);
+
 	/*
 	 * insert the directory item
 	 */
@@ -1615,6 +1619,9 @@ static noinline int btrfs_ioctl_snap_cre
 	int namelen;
 	int ret = 0;
 
+	if (!S_ISDIR(file_inode(file)->i_mode))
+		return -ENOTDIR;
+
 	ret = mnt_want_write_file(file);
 	if (ret)
 		goto out;
@@ -1644,7 +1651,7 @@ static noinline int btrfs_ioctl_snap_cre
 
 		src_inode = file_inode(src.file);
 		if (src_inode->i_sb != file_inode(file)->i_sb) {
-			btrfs_info(BTRFS_I(src_inode)->root->fs_info,
+			btrfs_info(BTRFS_I(file_inode(file))->root->fs_info,
 				   "Snapshot src from another FS");
 			ret = -EXDEV;
 		} else if (!inode_owner_or_capable(src_inode)) {
@@ -1672,6 +1679,9 @@ static noinline int btrfs_ioctl_snap_cre
 	struct btrfs_ioctl_vol_args *vol_args;
 	int ret;
 
+	if (!S_ISDIR(file_inode(file)->i_mode))
+		return -ENOTDIR;
+
 	vol_args = memdup_user(arg, sizeof(*vol_args));
 	if (IS_ERR(vol_args))
 		return PTR_ERR(vol_args);
@@ -1695,6 +1705,9 @@ static noinline int btrfs_ioctl_snap_cre
 	bool readonly = false;
 	struct btrfs_qgroup_inherit *inherit = NULL;
 
+	if (!S_ISDIR(file_inode(file)->i_mode))
+		return -ENOTDIR;
+
 	vol_args = memdup_user(arg, sizeof(*vol_args));
 	if (IS_ERR(vol_args))
 		return PTR_ERR(vol_args);
@@ -2341,6 +2354,9 @@ static noinline int btrfs_ioctl_snap_des
 	int ret;
 	int err = 0;
 
+	if (!S_ISDIR(dir->i_mode))
+		return -ENOTDIR;
+
 	vol_args = memdup_user(arg, sizeof(*vol_args));
 	if (IS_ERR(vol_args))
 		return PTR_ERR(vol_args);
@@ -2782,24 +2798,29 @@ out:
 static struct page *extent_same_get_page(struct inode *inode, pgoff_t index)
 {
 	struct page *page;
-	struct extent_io_tree *tree = &BTRFS_I(inode)->io_tree;
 
 	page = grab_cache_page(inode->i_mapping, index);
 	if (!page)
-		return NULL;
+		return ERR_PTR(-ENOMEM);
 
 	if (!PageUptodate(page)) {
-		if (extent_read_full_page_nolock(tree, page, btrfs_get_extent,
-						 0))
-			return NULL;
+		int ret;
+
+		ret = btrfs_readpage(NULL, page);
+		if (ret)
+			return ERR_PTR(ret);
 		lock_page(page);
 		if (!PageUptodate(page)) {
 			unlock_page(page);
 			page_cache_release(page);
-			return NULL;
+			return ERR_PTR(-EIO);
+		}
+		if (page->mapping != inode->i_mapping) {
+			unlock_page(page);
+			page_cache_release(page);
+			return ERR_PTR(-EAGAIN);
 		}
 	}
-	unlock_page(page);
 
 	return page;
 }
@@ -2811,17 +2832,31 @@ static int gather_extent_pages(struct in
 	pgoff_t index = off >> PAGE_CACHE_SHIFT;
 
 	for (i = 0; i < num_pages; i++) {
+again:
 		pages[i] = extent_same_get_page(inode, index + i);
-		if (!pages[i])
-			return -ENOMEM;
+		if (IS_ERR(pages[i])) {
+			int err = PTR_ERR(pages[i]);
+
+			if (err == -EAGAIN)
+				goto again;
+			pages[i] = NULL;
+			return err;
+		}
 	}
 	return 0;
 }
 
-static inline void lock_extent_range(struct inode *inode, u64 off, u64 len)
+static int lock_extent_range(struct inode *inode, u64 off, u64 len,
+			     bool retry_range_locking)
 {
-	/* do any pending delalloc/csum calc on src, one way or
-	   another, and lock file content */
+	/*
+	 * Do any pending delalloc/csum calculations on inode, one way or
+	 * another, and lock file content.
+	 * The locking order is:
+	 *
+	 *   1) pages
+	 *   2) range in the inode's io tree
+	 */
 	while (1) {
 		struct btrfs_ordered_extent *ordered;
 		lock_extent(&BTRFS_I(inode)->io_tree, off, off + len - 1);
@@ -2839,8 +2874,11 @@ static inline void lock_extent_range(str
 		unlock_extent(&BTRFS_I(inode)->io_tree, off, off + len - 1);
 		if (ordered)
 			btrfs_put_ordered_extent(ordered);
+		if (!retry_range_locking)
+			return -EAGAIN;
 		btrfs_wait_ordered_range(inode, off, len);
 	}
+	return 0;
 }
 
 static void btrfs_double_inode_unlock(struct inode *inode1, struct inode *inode2)
@@ -2865,15 +2903,24 @@ static void btrfs_double_extent_unlock(s
 	unlock_extent(&BTRFS_I(inode2)->io_tree, loff2, loff2 + len - 1);
 }
 
-static void btrfs_double_extent_lock(struct inode *inode1, u64 loff1,
-				     struct inode *inode2, u64 loff2, u64 len)
+static int btrfs_double_extent_lock(struct inode *inode1, u64 loff1,
+				    struct inode *inode2, u64 loff2, u64 len,
+				    bool retry_range_locking)
 {
+	int ret;
+
 	if (inode1 < inode2) {
 		swap(inode1, inode2);
 		swap(loff1, loff2);
 	}
-	lock_extent_range(inode1, loff1, len);
-	lock_extent_range(inode2, loff2, len);
+	ret = lock_extent_range(inode1, loff1, len, retry_range_locking);
+	if (ret)
+		return ret;
+	ret = lock_extent_range(inode2, loff2, len, retry_range_locking);
+	if (ret)
+		unlock_extent(&BTRFS_I(inode1)->io_tree, loff1,
+			      loff1 + len - 1);
+	return ret;
 }
 
 struct cmp_pages {
@@ -2889,11 +2936,15 @@ static void btrfs_cmp_data_free(struct c
 
 	for (i = 0; i < cmp->num_pages; i++) {
 		pg = cmp->src_pages[i];
-		if (pg)
+		if (pg) {
+			unlock_page(pg);
 			page_cache_release(pg);
+		}
 		pg = cmp->dst_pages[i];
-		if (pg)
+		if (pg) {
+			unlock_page(pg);
 			page_cache_release(pg);
+		}
 	}
 	kfree(cmp->src_pages);
 	kfree(cmp->dst_pages);
@@ -2954,6 +3005,8 @@ static int btrfs_cmp_data(struct inode *
 
 		src_page = cmp->src_pages[i];
 		dst_page = cmp->dst_pages[i];
+		ASSERT(PageLocked(src_page));
+		ASSERT(PageLocked(dst_page));
 
 		addr = kmap_atomic(src_page);
 		dst_addr = kmap_atomic(dst_page);
@@ -3066,14 +3119,46 @@ static int btrfs_extent_same(struct inod
 		goto out_unlock;
 	}
 
+again:
 	ret = btrfs_cmp_data_prepare(src, loff, dst, dst_loff, olen, &cmp);
 	if (ret)
 		goto out_unlock;
 
 	if (same_inode)
-		lock_extent_range(src, same_lock_start, same_lock_len);
+		ret = lock_extent_range(src, same_lock_start, same_lock_len,
+					false);
 	else
-		btrfs_double_extent_lock(src, loff, dst, dst_loff, len);
+		ret = btrfs_double_extent_lock(src, loff, dst, dst_loff, len,
+					       false);
+	/*
+	 * If one of the inodes has dirty pages in the respective range or
+	 * ordered extents, we need to flush dellaloc and wait for all ordered
+	 * extents in the range. We must unlock the pages and the ranges in the
+	 * io trees to avoid deadlocks when flushing delalloc (requires locking
+	 * pages) and when waiting for ordered extents to complete (they require
+	 * range locking).
+	 */
+	if (ret == -EAGAIN) {
+		/*
+		 * Ranges in the io trees already unlocked. Now unlock all
+		 * pages before waiting for all IO to complete.
+		 */
+		btrfs_cmp_data_free(&cmp);
+		if (same_inode) {
+			btrfs_wait_ordered_range(src, same_lock_start,
+						 same_lock_len);
+		} else {
+			btrfs_wait_ordered_range(src, loff, len);
+			btrfs_wait_ordered_range(dst, dst_loff, len);
+		}
+		goto again;
+	}
+	ASSERT(ret == 0);
+	if (WARN_ON(ret)) {
+		/* ranges in the io trees already unlocked */
+		btrfs_cmp_data_free(&cmp);
+		return ret;
+	}
 
 	/* pass original length for comparison so we stay within i_size */
 	ret = btrfs_cmp_data(src, loff, dst, dst_loff, olen, &cmp);
@@ -3895,9 +3980,15 @@ static noinline long btrfs_ioctl_clone(s
 		u64 lock_start = min_t(u64, off, destoff);
 		u64 lock_len = max_t(u64, off, destoff) + len - lock_start;
 
-		lock_extent_range(src, lock_start, lock_len);
+		ret = lock_extent_range(src, lock_start, lock_len, true);
 	} else {
-		btrfs_double_extent_lock(src, off, inode, destoff, len);
+		ret = btrfs_double_extent_lock(src, off, inode, destoff, len,
+					       true);
+	}
+	ASSERT(ret == 0);
+	if (WARN_ON(ret)) {
+		/* ranges in the io trees already unlocked */
+		goto out_unlock;
 	}
 
 	ret = btrfs_clone(src, inode, off, olen, len, destoff, 0);
@@ -5042,7 +5133,7 @@ static long btrfs_ioctl_quota_rescan_wai
 	if (!capable(CAP_SYS_ADMIN))
 		return -EPERM;
 
-	return btrfs_qgroup_wait_for_completion(root->fs_info);
+	return btrfs_qgroup_wait_for_completion(root->fs_info, true);
 }
 
 static long _btrfs_ioctl_set_received_subvol(struct file *file,
@@ -5578,3 +5669,24 @@ long btrfs_ioctl(struct file *file, unsi
 
 	return -ENOTTY;
 }
+
+#ifdef CONFIG_COMPAT
+long btrfs_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+	switch (cmd) {
+	case FS_IOC32_GETFLAGS:
+		cmd = FS_IOC_GETFLAGS;
+		break;
+	case FS_IOC32_SETFLAGS:
+		cmd = FS_IOC_SETFLAGS;
+		break;
+	case FS_IOC32_GETVERSION:
+		cmd = FS_IOC_GETVERSION;
+		break;
+	default:
+		return -ENOIOCTLCMD;
+	}
+
+	return btrfs_ioctl(file, cmd, (unsigned long) compat_ptr(arg));
+}
+#endif
--- zfcpdump-kernel-4.4.orig/fs/btrfs/qgroup.c
+++ zfcpdump-kernel-4.4/fs/btrfs/qgroup.c
@@ -995,7 +995,7 @@ int btrfs_quota_disable(struct btrfs_tra
 		goto out;
 	fs_info->quota_enabled = 0;
 	fs_info->pending_quota_state = 0;
-	btrfs_qgroup_wait_for_completion(fs_info);
+	btrfs_qgroup_wait_for_completion(fs_info, false);
 	spin_lock(&fs_info->qgroup_lock);
 	quota_root = fs_info->quota_root;
 	fs_info->quota_root = NULL;
@@ -2283,6 +2283,10 @@ static void btrfs_qgroup_rescan_worker(s
 	int err = -ENOMEM;
 	int ret = 0;
 
+	mutex_lock(&fs_info->qgroup_rescan_lock);
+	fs_info->qgroup_rescan_running = true;
+	mutex_unlock(&fs_info->qgroup_rescan_lock);
+
 	path = btrfs_alloc_path();
 	if (!path)
 		goto out;
@@ -2349,6 +2353,9 @@ out:
 	}
 
 done:
+	mutex_lock(&fs_info->qgroup_rescan_lock);
+	fs_info->qgroup_rescan_running = false;
+	mutex_unlock(&fs_info->qgroup_rescan_lock);
 	complete_all(&fs_info->qgroup_rescan_completion);
 }
 
@@ -2467,20 +2474,26 @@ btrfs_qgroup_rescan(struct btrfs_fs_info
 	return 0;
 }
 
-int btrfs_qgroup_wait_for_completion(struct btrfs_fs_info *fs_info)
+int btrfs_qgroup_wait_for_completion(struct btrfs_fs_info *fs_info,
+				     bool interruptible)
 {
 	int running;
 	int ret = 0;
 
 	mutex_lock(&fs_info->qgroup_rescan_lock);
 	spin_lock(&fs_info->qgroup_lock);
-	running = fs_info->qgroup_flags & BTRFS_QGROUP_STATUS_FLAG_RESCAN;
+	running = fs_info->qgroup_rescan_running;
 	spin_unlock(&fs_info->qgroup_lock);
 	mutex_unlock(&fs_info->qgroup_rescan_lock);
 
-	if (running)
+	if (!running)
+		return 0;
+
+	if (interruptible)
 		ret = wait_for_completion_interruptible(
 					&fs_info->qgroup_rescan_completion);
+	else
+		wait_for_completion(&fs_info->qgroup_rescan_completion);
 
 	return ret;
 }
--- zfcpdump-kernel-4.4.orig/fs/btrfs/qgroup.h
+++ zfcpdump-kernel-4.4/fs/btrfs/qgroup.h
@@ -46,7 +46,8 @@ int btrfs_quota_disable(struct btrfs_tra
 			struct btrfs_fs_info *fs_info);
 int btrfs_qgroup_rescan(struct btrfs_fs_info *fs_info);
 void btrfs_qgroup_rescan_resume(struct btrfs_fs_info *fs_info);
-int btrfs_qgroup_wait_for_completion(struct btrfs_fs_info *fs_info);
+int btrfs_qgroup_wait_for_completion(struct btrfs_fs_info *fs_info,
+				     bool interruptible);
 int btrfs_add_qgroup_relation(struct btrfs_trans_handle *trans,
 			      struct btrfs_fs_info *fs_info, u64 src, u64 dst);
 int btrfs_del_qgroup_relation(struct btrfs_trans_handle *trans,
--- zfcpdump-kernel-4.4.orig/fs/btrfs/root-tree.c
+++ zfcpdump-kernel-4.4/fs/btrfs/root-tree.c
@@ -310,8 +310,16 @@ int btrfs_find_orphan_roots(struct btrfs
 		set_bit(BTRFS_ROOT_ORPHAN_ITEM_INSERTED, &root->state);
 
 		err = btrfs_insert_fs_root(root->fs_info, root);
+		/*
+		 * The root might have been inserted already, as before we look
+		 * for orphan roots, log replay might have happened, which
+		 * triggers a transaction commit and qgroup accounting, which
+		 * in turn reads and inserts fs roots while doing backref
+		 * walking.
+		 */
+		if (err == -EEXIST)
+			err = 0;
 		if (err) {
-			BUG_ON(err == -EEXIST);
 			btrfs_free_fs_root(root);
 			break;
 		}
--- zfcpdump-kernel-4.4.orig/fs/btrfs/send.c
+++ zfcpdump-kernel-4.4/fs/btrfs/send.c
@@ -1469,7 +1469,21 @@ static int read_symlink(struct btrfs_roo
 	ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
 	if (ret < 0)
 		goto out;
-	BUG_ON(ret);
+	if (ret) {
+		/*
+		 * An empty symlink inode. Can happen in rare error paths when
+		 * creating a symlink (transaction committed before the inode
+		 * eviction handler removed the symlink inode items and a crash
+		 * happened in between or the subvol was snapshoted in between).
+		 * Print an informative message to dmesg/syslog so that the user
+		 * can delete the symlink.
+		 */
+		btrfs_err(root->fs_info,
+			  "Found empty symlink inode %llu at root %llu",
+			  ino, root->root_key.objectid);
+		ret = -EIO;
+		goto out;
+	}
 
 	ei = btrfs_item_ptr(path->nodes[0], path->slots[0],
 			struct btrfs_file_extent_item);
--- zfcpdump-kernel-4.4.orig/fs/btrfs/super.c
+++ zfcpdump-kernel-4.4/fs/btrfs/super.c
@@ -239,7 +239,7 @@ void __btrfs_abort_transaction(struct bt
 	trans->aborted = errno;
 	/* Nothing used. The other threads that have joined this
 	 * transaction may be able to continue. */
-	if (!trans->blocks_used && list_empty(&trans->new_bgs)) {
+	if (!trans->dirty && list_empty(&trans->new_bgs)) {
 		const char *errstr;
 
 		errstr = btrfs_decode_error(errno);
@@ -1956,6 +1956,8 @@ static int btrfs_calc_avail_data_space(s
  * there are other factors that may change the result (like a new metadata
  * chunk).
  *
+ * If metadata is exhausted, f_bavail will be 0.
+ *
  * FIXME: not accurate for mixed block groups, total and free/used are ok,
  * available appears slightly larger.
  */
@@ -1967,11 +1969,13 @@ static int btrfs_statfs(struct dentry *d
 	struct btrfs_space_info *found;
 	u64 total_used = 0;
 	u64 total_free_data = 0;
+	u64 total_free_meta = 0;
 	int bits = dentry->d_sb->s_blocksize_bits;
 	__be32 *fsid = (__be32 *)fs_info->fsid;
 	unsigned factor = 1;
 	struct btrfs_block_rsv *block_rsv = &fs_info->global_block_rsv;
 	int ret;
+	u64 thresh = 0;
 
 	/*
 	 * holding chunk_muext to avoid allocating new chunks, holding
@@ -1997,6 +2001,8 @@ static int btrfs_statfs(struct dentry *d
 				}
 			}
 		}
+		if (found->flags & BTRFS_BLOCK_GROUP_METADATA)
+			total_free_meta += found->disk_total - found->disk_used;
 
 		total_used += found->disk_used;
 	}
@@ -2019,6 +2025,24 @@ static int btrfs_statfs(struct dentry *d
 	buf->f_bavail += div_u64(total_free_data, factor);
 	buf->f_bavail = buf->f_bavail >> bits;
 
+	/*
+	 * We calculate the remaining metadata space minus global reserve. If
+	 * this is (supposedly) smaller than zero, there's no space. But this
+	 * does not hold in practice, the exhausted state happens where's still
+	 * some positive delta. So we apply some guesswork and compare the
+	 * delta to a 4M threshold.  (Practically observed delta was ~2M.)
+	 *
+	 * We probably cannot calculate the exact threshold value because this
+	 * depends on the internal reservations requested by various
+	 * operations, so some operations that consume a few metadata will
+	 * succeed even if the Avail is zero. But this is better than the other
+	 * way around.
+	 */
+	thresh = 4 * 1024 * 1024;
+
+	if (total_free_meta - thresh < block_rsv->size)
+		buf->f_bavail = 0;
+
 	buf->f_type = BTRFS_SUPER_MAGIC;
 	buf->f_bsize = dentry->d_sb->s_blocksize;
 	buf->f_namelen = BTRFS_NAME_LEN;
--- zfcpdump-kernel-4.4.orig/fs/btrfs/transaction.h
+++ zfcpdump-kernel-4.4/fs/btrfs/transaction.h
@@ -110,7 +110,6 @@ struct btrfs_trans_handle {
 	u64 chunk_bytes_reserved;
 	unsigned long use_count;
 	unsigned long blocks_reserved;
-	unsigned long blocks_used;
 	unsigned long delayed_ref_updates;
 	struct btrfs_transaction *transaction;
 	struct btrfs_block_rsv *block_rsv;
@@ -121,6 +120,7 @@ struct btrfs_trans_handle {
 	bool can_flush_pending_bgs;
 	bool reloc_reserved;
 	bool sync;
+	bool dirty;
 	unsigned int type;
 	/*
 	 * this root is only needed to validate that the root passed to
--- zfcpdump-kernel-4.4.orig/fs/btrfs/tree-log.c
+++ zfcpdump-kernel-4.4/fs/btrfs/tree-log.c
@@ -2850,6 +2850,7 @@ int btrfs_sync_log(struct btrfs_trans_ha
 
 	if (log_root_tree->log_transid_committed >= root_log_ctx.log_transid) {
 		blk_finish_plug(&plug);
+		list_del_init(&root_log_ctx.list);
 		mutex_unlock(&log_root_tree->log_mutex);
 		ret = root_log_ctx.log_ret;
 		goto out;
@@ -4406,6 +4407,127 @@ static int btrfs_log_trailing_hole(struc
 	return ret;
 }
 
+/*
+ * When we are logging a new inode X, check if it doesn't have a reference that
+ * matches the reference from some other inode Y created in a past transaction
+ * and that was renamed in the current transaction. If we don't do this, then at
+ * log replay time we can lose inode Y (and all its files if it's a directory):
+ *
+ * mkdir /mnt/x
+ * echo "hello world" > /mnt/x/foobar
+ * sync
+ * mv /mnt/x /mnt/y
+ * mkdir /mnt/x                 # or touch /mnt/x
+ * xfs_io -c fsync /mnt/x
+ * <power fail>
+ * mount fs, trigger log replay
+ *
+ * After the log replay procedure, we would lose the first directory and all its
+ * files (file foobar).
+ * For the case where inode Y is not a directory we simply end up losing it:
+ *
+ * echo "123" > /mnt/foo
+ * sync
+ * mv /mnt/foo /mnt/bar
+ * echo "abc" > /mnt/foo
+ * xfs_io -c fsync /mnt/foo
+ * <power fail>
+ *
+ * We also need this for cases where a snapshot entry is replaced by some other
+ * entry (file or directory) otherwise we end up with an unreplayable log due to
+ * attempts to delete the snapshot entry (entry of type BTRFS_ROOT_ITEM_KEY) as
+ * if it were a regular entry:
+ *
+ * mkdir /mnt/x
+ * btrfs subvolume snapshot /mnt /mnt/x/snap
+ * btrfs subvolume delete /mnt/x/snap
+ * rmdir /mnt/x
+ * mkdir /mnt/x
+ * fsync /mnt/x or fsync some new file inside it
+ * <power fail>
+ *
+ * The snapshot delete, rmdir of x, mkdir of a new x and the fsync all happen in
+ * the same transaction.
+ */
+static int btrfs_check_ref_name_override(struct extent_buffer *eb,
+					 const int slot,
+					 const struct btrfs_key *key,
+					 struct inode *inode)
+{
+	int ret;
+	struct btrfs_path *search_path;
+	char *name = NULL;
+	u32 name_len = 0;
+	u32 item_size = btrfs_item_size_nr(eb, slot);
+	u32 cur_offset = 0;
+	unsigned long ptr = btrfs_item_ptr_offset(eb, slot);
+
+	search_path = btrfs_alloc_path();
+	if (!search_path)
+		return -ENOMEM;
+	search_path->search_commit_root = 1;
+	search_path->skip_locking = 1;
+
+	while (cur_offset < item_size) {
+		u64 parent;
+		u32 this_name_len;
+		u32 this_len;
+		unsigned long name_ptr;
+		struct btrfs_dir_item *di;
+
+		if (key->type == BTRFS_INODE_REF_KEY) {
+			struct btrfs_inode_ref *iref;
+
+			iref = (struct btrfs_inode_ref *)(ptr + cur_offset);
+			parent = key->offset;
+			this_name_len = btrfs_inode_ref_name_len(eb, iref);
+			name_ptr = (unsigned long)(iref + 1);
+			this_len = sizeof(*iref) + this_name_len;
+		} else {
+			struct btrfs_inode_extref *extref;
+
+			extref = (struct btrfs_inode_extref *)(ptr +
+							       cur_offset);
+			parent = btrfs_inode_extref_parent(eb, extref);
+			this_name_len = btrfs_inode_extref_name_len(eb, extref);
+			name_ptr = (unsigned long)&extref->name;
+			this_len = sizeof(*extref) + this_name_len;
+		}
+
+		if (this_name_len > name_len) {
+			char *new_name;
+
+			new_name = krealloc(name, this_name_len, GFP_NOFS);
+			if (!new_name) {
+				ret = -ENOMEM;
+				goto out;
+			}
+			name_len = this_name_len;
+			name = new_name;
+		}
+
+		read_extent_buffer(eb, name, name_ptr, this_name_len);
+		di = btrfs_lookup_dir_item(NULL, BTRFS_I(inode)->root,
+					   search_path, parent,
+					   name, this_name_len, 0);
+		if (di && !IS_ERR(di)) {
+			ret = 1;
+			goto out;
+		} else if (IS_ERR(di)) {
+			ret = PTR_ERR(di);
+			goto out;
+		}
+		btrfs_release_path(search_path);
+
+		cur_offset += this_len;
+	}
+	ret = 0;
+out:
+	btrfs_free_path(search_path);
+	kfree(name);
+	return ret;
+}
+
 /* log a single inode in the tree log.
  * At least one parent directory for this inode must exist in the tree
  * or be logged already.
@@ -4578,6 +4700,22 @@ again:
 		if (min_key.type == BTRFS_INODE_ITEM_KEY)
 			need_log_inode_item = false;
 
+		if ((min_key.type == BTRFS_INODE_REF_KEY ||
+		     min_key.type == BTRFS_INODE_EXTREF_KEY) &&
+		    BTRFS_I(inode)->generation == trans->transid) {
+			ret = btrfs_check_ref_name_override(path->nodes[0],
+							    path->slots[0],
+							    &min_key, inode);
+			if (ret < 0) {
+				err = ret;
+				goto out_unlock;
+			} else if (ret > 0) {
+				err = 1;
+				btrfs_set_log_full_commit(root->fs_info, trans);
+				goto out_unlock;
+			}
+		}
+
 		/* Skip xattrs, we log them later with btrfs_log_all_xattrs() */
 		if (min_key.type == BTRFS_XATTR_ITEM_KEY) {
 			if (ins_nr == 0)
--- zfcpdump-kernel-4.4.orig/fs/btrfs/volumes.c
+++ zfcpdump-kernel-4.4/fs/btrfs/volumes.c
@@ -232,6 +232,7 @@ static struct btrfs_device *__alloc_devi
 	spin_lock_init(&dev->reada_lock);
 	atomic_set(&dev->reada_in_flight, 0);
 	atomic_set(&dev->dev_stats_ccnt, 0);
+	btrfs_device_data_ordered_init(dev);
 	INIT_RADIX_TREE(&dev->reada_zones, GFP_NOFS & ~__GFP_DIRECT_RECLAIM);
 	INIT_RADIX_TREE(&dev->reada_extents, GFP_NOFS & ~__GFP_DIRECT_RECLAIM);
 
@@ -1257,6 +1258,15 @@ int find_free_dev_extent_start(struct bt
 	int ret;
 	int slot;
 	struct extent_buffer *l;
+	u64 min_search_start;
+
+	/*
+	 * We don't want to overwrite the superblock on the drive nor any area
+	 * used by the boot loader (grub for example), so we make sure to start
+	 * at an offset of at least 1MB.
+	 */
+	min_search_start = max(root->fs_info->alloc_start, 1024ull * 1024);
+	search_start = max(search_start, min_search_start);
 
 	path = btrfs_alloc_path();
 	if (!path)
@@ -1397,18 +1407,9 @@ int find_free_dev_extent(struct btrfs_tr
 			 struct btrfs_device *device, u64 num_bytes,
 			 u64 *start, u64 *len)
 {
-	struct btrfs_root *root = device->dev_root;
-	u64 search_start;
-
 	/* FIXME use last free of some kind */
-
-	/*
-	 * we don't want to overwrite the superblock on the drive,
-	 * so we make sure to start at an offset of at least 1MB
-	 */
-	search_start = max(root->fs_info->alloc_start, 1024ull * 1024);
 	return find_free_dev_extent_start(trans->transaction, device,
-					  num_bytes, search_start, start, len);
+					  num_bytes, 0, start, len);
 }
 
 static int btrfs_free_dev_extent(struct btrfs_trans_handle *trans,
@@ -6512,6 +6513,14 @@ int btrfs_read_sys_array(struct btrfs_ro
 				goto out_short_read;
 
 			num_stripes = btrfs_chunk_num_stripes(sb, chunk);
+			if (!num_stripes) {
+				printk(KERN_ERR
+	    "BTRFS: invalid number of stripes %u in sys_array at offset %u\n",
+					num_stripes, cur_offset);
+				ret = -EIO;
+				break;
+			}
+
 			len = btrfs_chunk_item_size(num_stripes);
 			if (cur_offset + len > array_size)
 				goto out_short_read;
--- zfcpdump-kernel-4.4.orig/fs/ceph/inode.c
+++ zfcpdump-kernel-4.4/fs/ceph/inode.c
@@ -1358,15 +1358,20 @@ static int fill_readdir_cache(struct ino
 
 	if (!ctl->page || pgoff != page_index(ctl->page)) {
 		ceph_readdir_cache_release(ctl);
-		ctl->page  = grab_cache_page(&dir->i_data, pgoff);
+		if (idx == 0)
+			ctl->page = grab_cache_page(&dir->i_data, pgoff);
+		else
+			ctl->page = find_lock_page(&dir->i_data, pgoff);
 		if (!ctl->page) {
 			ctl->index = -1;
-			return -ENOMEM;
+			return idx == 0 ? -ENOMEM : 0;
 		}
 		/* reading/filling the cache are serialized by
 		 * i_mutex, no need to use page lock */
 		unlock_page(ctl->page);
 		ctl->dentries = kmap(ctl->page);
+		if (idx == 0)
+			memset(ctl->dentries, 0, PAGE_CACHE_SIZE);
 	}
 
 	if (req->r_dir_release_cnt == atomic64_read(&ci->i_release_count) &&
--- zfcpdump-kernel-4.4.orig/fs/cifs/cifs_debug.c
+++ zfcpdump-kernel-4.4/fs/cifs/cifs_debug.c
@@ -50,7 +50,7 @@ void cifs_vfs_err(const char *fmt, ...)
 	vaf.fmt = fmt;
 	vaf.va = &args;
 
-	pr_err("CIFS VFS: %pV", &vaf);
+	pr_err_ratelimited("CIFS VFS: %pV", &vaf);
 
 	va_end(args);
 }
--- zfcpdump-kernel-4.4.orig/fs/cifs/cifs_debug.h
+++ zfcpdump-kernel-4.4/fs/cifs/cifs_debug.h
@@ -51,14 +51,13 @@ __printf(1, 2) void cifs_vfs_err(const c
 /* information message: e.g., configuration, major event */
 #define cifs_dbg(type, fmt, ...)					\
 do {									\
-	if (type == FYI) {						\
-		if (cifsFYI & CIFS_INFO) {				\
-			pr_debug("%s: " fmt, __FILE__, ##__VA_ARGS__);	\
-		}							\
+	if (type == FYI && cifsFYI & CIFS_INFO) {			\
+		pr_debug_ratelimited("%s: "				\
+			    fmt, __FILE__, ##__VA_ARGS__);		\
 	} else if (type == VFS) {					\
 		cifs_vfs_err(fmt, ##__VA_ARGS__);			\
 	} else if (type == NOISY && type != 0) {			\
-		pr_debug(fmt, ##__VA_ARGS__);				\
+		pr_debug_ratelimited(fmt, ##__VA_ARGS__);		\
 	}								\
 } while (0)
 
--- zfcpdump-kernel-4.4.orig/fs/cifs/cifs_fs_sb.h
+++ zfcpdump-kernel-4.4/fs/cifs/cifs_fs_sb.h
@@ -46,6 +46,9 @@
 #define CIFS_MOUNT_CIFS_BACKUPUID 0x200000 /* backup intent bit for a user */
 #define CIFS_MOUNT_CIFS_BACKUPGID 0x400000 /* backup intent bit for a group */
 #define CIFS_MOUNT_MAP_SFM_CHR	0x800000 /* SFM/MAC mapping for illegal chars */
+#define CIFS_MOUNT_USE_PREFIX_PATH 0x1000000 /* make subpath with unaccessible
+					      * root mountable
+					      */
 
 struct cifs_sb_info {
 	struct rb_root tlink_tree;
@@ -67,5 +70,6 @@ struct cifs_sb_info {
 	struct backing_dev_info bdi;
 	struct delayed_work prune_tlinks;
 	struct rcu_head rcu;
+	char *prepath;
 };
 #endif				/* _CIFS_FS_SB_H */
--- zfcpdump-kernel-4.4.orig/fs/cifs/cifs_unicode.c
+++ zfcpdump-kernel-4.4/fs/cifs/cifs_unicode.c
@@ -101,6 +101,12 @@ convert_sfm_char(const __u16 src_char, c
 	case SFM_SLASH:
 		*target = '\\';
 		break;
+	case SFM_SPACE:
+		*target = ' ';
+		break;
+	case SFM_PERIOD:
+		*target = '.';
+		break;
 	default:
 		return false;
 	}
@@ -404,7 +410,7 @@ static __le16 convert_to_sfu_char(char s
 	return dest_char;
 }
 
-static __le16 convert_to_sfm_char(char src_char)
+static __le16 convert_to_sfm_char(char src_char, bool end_of_string)
 {
 	__le16 dest_char;
 
@@ -427,6 +433,18 @@ static __le16 convert_to_sfm_char(char s
 	case '|':
 		dest_char = cpu_to_le16(SFM_PIPE);
 		break;
+	case '.':
+		if (end_of_string)
+			dest_char = cpu_to_le16(SFM_PERIOD);
+		else
+			dest_char = 0;
+		break;
+	case ' ':
+		if (end_of_string)
+			dest_char = cpu_to_le16(SFM_SPACE);
+		else
+			dest_char = 0;
+		break;
 	default:
 		dest_char = 0;
 	}
@@ -469,9 +487,16 @@ cifsConvertToUTF16(__le16 *target, const
 		/* see if we must remap this char */
 		if (map_chars == SFU_MAP_UNI_RSVD)
 			dst_char = convert_to_sfu_char(src_char);
-		else if (map_chars == SFM_MAP_UNI_RSVD)
-			dst_char = convert_to_sfm_char(src_char);
-		else
+		else if (map_chars == SFM_MAP_UNI_RSVD) {
+			bool end_of_string;
+
+			if (i == srclen - 1)
+				end_of_string = true;
+			else
+				end_of_string = false;
+
+			dst_char = convert_to_sfm_char(src_char, end_of_string);
+		} else
 			dst_char = 0;
 		/*
 		 * FIXME: We can not handle remapping backslash (UNI_SLASH)
--- zfcpdump-kernel-4.4.orig/fs/cifs/cifs_unicode.h
+++ zfcpdump-kernel-4.4/fs/cifs/cifs_unicode.h
@@ -64,6 +64,8 @@
 #define SFM_LESSTHAN    ((__u16) 0xF023)
 #define SFM_PIPE        ((__u16) 0xF027)
 #define SFM_SLASH       ((__u16) 0xF026)
+#define SFM_PERIOD	((__u16) 0xF028)
+#define SFM_SPACE	((__u16) 0xF029)
 
 /*
  * Mapping mechanism to use when one of the seven reserved characters is
--- zfcpdump-kernel-4.4.orig/fs/cifs/cifsencrypt.c
+++ zfcpdump-kernel-4.4/fs/cifs/cifsencrypt.c
@@ -714,7 +714,7 @@ setup_ntlmv2_rsp(struct cifs_ses *ses, c
 
 	ses->auth_key.response = kmalloc(baselen + tilen, GFP_KERNEL);
 	if (!ses->auth_key.response) {
-		rc = ENOMEM;
+		rc = -ENOMEM;
 		ses->auth_key.len = 0;
 		goto setup_ntlmv2_rsp_ret;
 	}
@@ -731,24 +731,26 @@ setup_ntlmv2_rsp(struct cifs_ses *ses, c
 
 	memcpy(ses->auth_key.response + baselen, tiblob, tilen);
 
+	mutex_lock(&ses->server->srv_mutex);
+
 	rc = crypto_hmacmd5_alloc(ses->server);
 	if (rc) {
 		cifs_dbg(VFS, "could not crypto alloc hmacmd5 rc %d\n", rc);
-		goto setup_ntlmv2_rsp_ret;
+		goto unlock;
 	}
 
 	/* calculate ntlmv2_hash */
 	rc = calc_ntlmv2_hash(ses, ntlmv2_hash, nls_cp);
 	if (rc) {
 		cifs_dbg(VFS, "could not get v2 hash rc %d\n", rc);
-		goto setup_ntlmv2_rsp_ret;
+		goto unlock;
 	}
 
 	/* calculate first part of the client response (CR1) */
 	rc = CalcNTLMv2_response(ses, ntlmv2_hash);
 	if (rc) {
 		cifs_dbg(VFS, "Could not calculate CR1 rc: %d\n", rc);
-		goto setup_ntlmv2_rsp_ret;
+		goto unlock;
 	}
 
 	/* now calculate the session key for NTLMv2 */
@@ -757,13 +759,13 @@ setup_ntlmv2_rsp(struct cifs_ses *ses, c
 	if (rc) {
 		cifs_dbg(VFS, "%s: Could not set NTLMV2 Hash as a key\n",
 			 __func__);
-		goto setup_ntlmv2_rsp_ret;
+		goto unlock;
 	}
 
 	rc = crypto_shash_init(&ses->server->secmech.sdeschmacmd5->shash);
 	if (rc) {
 		cifs_dbg(VFS, "%s: Could not init hmacmd5\n", __func__);
-		goto setup_ntlmv2_rsp_ret;
+		goto unlock;
 	}
 
 	rc = crypto_shash_update(&ses->server->secmech.sdeschmacmd5->shash,
@@ -771,7 +773,7 @@ setup_ntlmv2_rsp(struct cifs_ses *ses, c
 		CIFS_HMAC_MD5_HASH_SIZE);
 	if (rc) {
 		cifs_dbg(VFS, "%s: Could not update with response\n", __func__);
-		goto setup_ntlmv2_rsp_ret;
+		goto unlock;
 	}
 
 	rc = crypto_shash_final(&ses->server->secmech.sdeschmacmd5->shash,
@@ -779,6 +781,8 @@ setup_ntlmv2_rsp(struct cifs_ses *ses, c
 	if (rc)
 		cifs_dbg(VFS, "%s: Could not generate md5 hash\n", __func__);
 
+unlock:
+	mutex_unlock(&ses->server->srv_mutex);
 setup_ntlmv2_rsp_ret:
 	kfree(tiblob);
 
--- zfcpdump-kernel-4.4.orig/fs/cifs/cifsfs.c
+++ zfcpdump-kernel-4.4/fs/cifs/cifsfs.c
@@ -683,10 +683,14 @@ cifs_do_mount(struct file_system_type *f
 	cifs_sb->mountdata = kstrndup(data, PAGE_SIZE, GFP_KERNEL);
 	if (cifs_sb->mountdata == NULL) {
 		root = ERR_PTR(-ENOMEM);
-		goto out_cifs_sb;
+		goto out_free;
 	}
 
-	cifs_setup_cifs_sb(volume_info, cifs_sb);
+	rc = cifs_setup_cifs_sb(volume_info, cifs_sb);
+	if (rc) {
+		root = ERR_PTR(rc);
+		goto out_free;
+	}
 
 	rc = cifs_mount(cifs_sb, volume_info);
 	if (rc) {
@@ -694,7 +698,7 @@ cifs_do_mount(struct file_system_type *f
 			cifs_dbg(VFS, "cifs_mount failed w/return code = %d\n",
 				 rc);
 		root = ERR_PTR(rc);
-		goto out_mountdata;
+		goto out_free;
 	}
 
 	mnt_data.vol = volume_info;
@@ -724,7 +728,11 @@ cifs_do_mount(struct file_system_type *f
 		sb->s_flags |= MS_ACTIVE;
 	}
 
-	root = cifs_get_root(volume_info, sb);
+	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_USE_PREFIX_PATH)
+		root = dget(sb->s_root);
+	else
+		root = cifs_get_root(volume_info, sb);
+
 	if (IS_ERR(root))
 		goto out_super;
 
@@ -737,9 +745,9 @@ out:
 	cifs_cleanup_volume_info(volume_info);
 	return root;
 
-out_mountdata:
+out_free:
+	kfree(cifs_sb->prepath);
 	kfree(cifs_sb->mountdata);
-out_cifs_sb:
 	kfree(cifs_sb);
 out_nls:
 	unload_nls(volume_info->local_nls);
--- zfcpdump-kernel-4.4.orig/fs/cifs/cifsfs.h
+++ zfcpdump-kernel-4.4/fs/cifs/cifsfs.h
@@ -31,19 +31,15 @@
  * so that it will fit. We use hash_64 to convert the value to 31 bits, and
  * then add 1, to ensure that we don't end up with a 0 as the value.
  */
-#if BITS_PER_LONG == 64
 static inline ino_t
 cifs_uniqueid_to_ino_t(u64 fileid)
 {
+	if ((sizeof(ino_t)) < (sizeof(u64)))
+		return (ino_t)hash_64(fileid, (sizeof(ino_t) * 8) - 1) + 1;
+
 	return (ino_t)fileid;
+
 }
-#else
-static inline ino_t
-cifs_uniqueid_to_ino_t(u64 fileid)
-{
-	return (ino_t)hash_64(fileid, (sizeof(ino_t) * 8) - 1) + 1;
-}
-#endif
 
 extern struct file_system_type cifs_fs_type;
 extern const struct address_space_operations cifs_addr_ops;
--- zfcpdump-kernel-4.4.orig/fs/cifs/cifsproto.h
+++ zfcpdump-kernel-4.4/fs/cifs/cifsproto.h
@@ -185,7 +185,7 @@ extern int cifs_read_from_socket(struct
 extern int cifs_readv_from_socket(struct TCP_Server_Info *server,
 		struct kvec *iov_orig, unsigned int nr_segs,
 		unsigned int to_read);
-extern void cifs_setup_cifs_sb(struct smb_vol *pvolume_info,
+extern int cifs_setup_cifs_sb(struct smb_vol *pvolume_info,
 			       struct cifs_sb_info *cifs_sb);
 extern int cifs_match_super(struct super_block *, void *);
 extern void cifs_cleanup_volume_info(struct smb_vol *pvolume_info);
--- zfcpdump-kernel-4.4.orig/fs/cifs/cifssmb.c
+++ zfcpdump-kernel-4.4/fs/cifs/cifssmb.c
@@ -1396,11 +1396,10 @@ openRetry:
  * current bigbuf.
  */
 static int
-cifs_readv_discard(struct TCP_Server_Info *server, struct mid_q_entry *mid)
+discard_remaining_data(struct TCP_Server_Info *server)
 {
 	unsigned int rfclen = get_rfc1002_length(server->smallbuf);
 	int remaining = rfclen + 4 - server->total_read;
-	struct cifs_readdata *rdata = mid->callback_data;
 
 	while (remaining > 0) {
 		int length;
@@ -1414,10 +1413,20 @@ cifs_readv_discard(struct TCP_Server_Inf
 		remaining -= length;
 	}
 
-	dequeue_mid(mid, rdata->result);
 	return 0;
 }
 
+static int
+cifs_readv_discard(struct TCP_Server_Info *server, struct mid_q_entry *mid)
+{
+	int length;
+	struct cifs_readdata *rdata = mid->callback_data;
+
+	length = discard_remaining_data(server);
+	dequeue_mid(mid, rdata->result);
+	return length;
+}
+
 int
 cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid)
 {
@@ -1446,6 +1455,12 @@ cifs_readv_receive(struct TCP_Server_Inf
 		return length;
 	server->total_read += length;
 
+	if (server->ops->is_status_pending &&
+	    server->ops->is_status_pending(buf, server, 0)) {
+		discard_remaining_data(server);
+		return -1;
+	}
+
 	/* Was the SMB read successful? */
 	rdata->result = server->ops->map_error(buf, false);
 	if (rdata->result != 0) {
--- zfcpdump-kernel-4.4.orig/fs/cifs/connect.c
+++ zfcpdump-kernel-4.4/fs/cifs/connect.c
@@ -368,7 +368,6 @@ cifs_reconnect(struct TCP_Server_Info *s
 	server->session_key.response = NULL;
 	server->session_key.len = 0;
 	server->lstrp = jiffies;
-	mutex_unlock(&server->srv_mutex);
 
 	/* mark submitted MIDs for retry and issue callback */
 	INIT_LIST_HEAD(&retry_list);
@@ -381,6 +380,7 @@ cifs_reconnect(struct TCP_Server_Info *s
 		list_move(&mid_entry->qhead, &retry_list);
 	}
 	spin_unlock(&GlobalMid_Lock);
+	mutex_unlock(&server->srv_mutex);
 
 	cifs_dbg(FYI, "%s: issuing mid callbacks\n", __func__);
 	list_for_each_safe(tmp, tmp2, &retry_list) {
@@ -425,7 +425,9 @@ cifs_echo_request(struct work_struct *wo
 	 * server->ops->need_neg() == true. Also, no need to ping if
 	 * we got a response recently.
 	 */
-	if (!server->ops->need_neg || server->ops->need_neg(server) ||
+
+	if (server->tcpStatus == CifsNeedReconnect ||
+	    server->tcpStatus == CifsExiting || server->tcpStatus == CifsNew ||
 	    (server->ops->can_echo && !server->ops->can_echo(server)) ||
 	    time_before(jiffies, server->lstrp + SMB_ECHO_INTERVAL - HZ))
 		goto requeue_echo;
@@ -2810,6 +2812,24 @@ compare_mount_options(struct super_block
 	return 1;
 }
 
+static int
+match_prepath(struct super_block *sb, struct cifs_mnt_data *mnt_data)
+{
+	struct cifs_sb_info *old = CIFS_SB(sb);
+	struct cifs_sb_info *new = mnt_data->cifs_sb;
+
+	if (old->mnt_cifs_flags & CIFS_MOUNT_USE_PREFIX_PATH) {
+		if (!(new->mnt_cifs_flags & CIFS_MOUNT_USE_PREFIX_PATH))
+			return 0;
+		/* The prepath should be null terminated strings */
+		if (strcmp(new->prepath, old->prepath))
+			return 0;
+
+		return 1;
+	}
+	return 0;
+}
+
 int
 cifs_match_super(struct super_block *sb, void *data)
 {
@@ -2837,7 +2857,8 @@ cifs_match_super(struct super_block *sb,
 
 	if (!match_server(tcp_srv, volume_info) ||
 	    !match_session(ses, volume_info) ||
-	    !match_tcon(tcon, volume_info->UNC)) {
+	    !match_tcon(tcon, volume_info->UNC) ||
+	    !match_prepath(sb, mnt_data)) {
 		rc = 0;
 		goto out;
 	}
@@ -3252,7 +3273,7 @@ void reset_cifs_unix_caps(unsigned int x
 	}
 }
 
-void cifs_setup_cifs_sb(struct smb_vol *pvolume_info,
+int cifs_setup_cifs_sb(struct smb_vol *pvolume_info,
 			struct cifs_sb_info *cifs_sb)
 {
 	INIT_DELAYED_WORK(&cifs_sb->prune_tlinks, cifs_prune_tlinks);
@@ -3346,6 +3367,14 @@ void cifs_setup_cifs_sb(struct smb_vol *
 
 	if ((pvolume_info->cifs_acl) && (pvolume_info->dynperm))
 		cifs_dbg(VFS, "mount option dynperm ignored if cifsacl mount option supported\n");
+
+	if (pvolume_info->prepath) {
+		cifs_sb->prepath = kstrdup(pvolume_info->prepath, GFP_KERNEL);
+		if (cifs_sb->prepath == NULL)
+			return -ENOMEM;
+	}
+
+	return 0;
 }
 
 static void
@@ -3515,6 +3544,44 @@ cifs_get_volume_info(char *mount_data, c
 	return volume_info;
 }
 
+static int
+cifs_are_all_path_components_accessible(struct TCP_Server_Info *server,
+					unsigned int xid,
+					struct cifs_tcon *tcon,
+					struct cifs_sb_info *cifs_sb,
+					char *full_path)
+{
+	int rc;
+	char *s;
+	char sep, tmp;
+
+	sep = CIFS_DIR_SEP(cifs_sb);
+	s = full_path;
+
+	rc = server->ops->is_path_accessible(xid, tcon, cifs_sb, "");
+	while (rc == 0) {
+		/* skip separators */
+		while (*s == sep)
+			s++;
+		if (!*s)
+			break;
+		/* next separator */
+		while (*s && *s != sep)
+			s++;
+
+		/*
+		 * temporarily null-terminate the path at the end of
+		 * the current component
+		 */
+		tmp = *s;
+		*s = 0;
+		rc = server->ops->is_path_accessible(xid, tcon, cifs_sb,
+						     full_path);
+		*s = tmp;
+	}
+	return rc;
+}
+
 int
 cifs_mount(struct cifs_sb_info *cifs_sb, struct smb_vol *volume_info)
 {
@@ -3652,6 +3719,18 @@ remote_path_check:
 			kfree(full_path);
 			goto mount_fail_check;
 		}
+
+		if (rc != -EREMOTE) {
+			rc = cifs_are_all_path_components_accessible(server,
+							     xid, tcon, cifs_sb,
+							     full_path);
+			if (rc != 0) {
+				cifs_dbg(VFS, "cannot query dirs between root and final path, "
+					 "enabling CIFS_MOUNT_USE_PREFIX_PATH\n");
+				cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_USE_PREFIX_PATH;
+				rc = 0;
+			}
+		}
 		kfree(full_path);
 	}
 
@@ -3921,6 +4000,7 @@ cifs_umount(struct cifs_sb_info *cifs_sb
 
 	bdi_destroy(&cifs_sb->bdi);
 	kfree(cifs_sb->mountdata);
+	kfree(cifs_sb->prepath);
 	call_rcu(&cifs_sb->rcu, delayed_free);
 }
 
--- zfcpdump-kernel-4.4.orig/fs/cifs/dir.c
+++ zfcpdump-kernel-4.4/fs/cifs/dir.c
@@ -84,6 +84,7 @@ build_path_from_dentry(struct dentry *di
 	struct dentry *temp;
 	int namelen;
 	int dfsplen;
+	int pplen = 0;
 	char *full_path;
 	char dirsep;
 	struct cifs_sb_info *cifs_sb = CIFS_SB(direntry->d_sb);
@@ -95,8 +96,12 @@ build_path_from_dentry(struct dentry *di
 		dfsplen = strnlen(tcon->treeName, MAX_TREE_SIZE + 1);
 	else
 		dfsplen = 0;
+
+	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_USE_PREFIX_PATH)
+		pplen = cifs_sb->prepath ? strlen(cifs_sb->prepath) + 1 : 0;
+
 cifs_bp_rename_retry:
-	namelen = dfsplen;
+	namelen = dfsplen + pplen;
 	seq = read_seqbegin(&rename_lock);
 	rcu_read_lock();
 	for (temp = direntry; !IS_ROOT(temp);) {
@@ -137,7 +142,7 @@ cifs_bp_rename_retry:
 		}
 	}
 	rcu_read_unlock();
-	if (namelen != dfsplen || read_seqretry(&rename_lock, seq)) {
+	if (namelen != dfsplen + pplen || read_seqretry(&rename_lock, seq)) {
 		cifs_dbg(FYI, "did not end path lookup where expected. namelen=%ddfsplen=%d\n",
 			 namelen, dfsplen);
 		/* presumably this is only possible if racing with a rename
@@ -153,6 +158,17 @@ cifs_bp_rename_retry:
 	   those safely to '/' if any are found in the middle of the prepath */
 	/* BB test paths to Windows with '/' in the midst of prepath */
 
+	if (pplen) {
+		int i;
+
+		cifs_dbg(FYI, "using cifs_sb prepath <%s>\n", cifs_sb->prepath);
+		memcpy(full_path+dfsplen+1, cifs_sb->prepath, pplen-1);
+		full_path[dfsplen] = '\\';
+		for (i = 0; i < pplen-1; i++)
+			if (full_path[dfsplen+1+i] == '/')
+				full_path[dfsplen+1+i] = CIFS_DIR_SEP(cifs_sb);
+	}
+
 	if (dfsplen) {
 		strncpy(full_path, tcon->treeName, dfsplen);
 		if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) {
@@ -229,6 +245,13 @@ cifs_do_create(struct inode *inode, stru
 				goto cifs_create_get_file_info;
 			}
 
+			if (S_ISDIR(newinode->i_mode)) {
+				CIFSSMBClose(xid, tcon, fid->netfid);
+				iput(newinode);
+				rc = -EISDIR;
+				goto out;
+			}
+
 			if (!S_ISREG(newinode->i_mode)) {
 				/*
 				 * The server may allow us to open things like
@@ -399,10 +422,14 @@ cifs_create_set_dentry:
 	if (rc != 0) {
 		cifs_dbg(FYI, "Create worked, get_inode_info failed rc = %d\n",
 			 rc);
-		if (server->ops->close)
-			server->ops->close(xid, tcon, fid);
-		goto out;
+		goto out_err;
+	}
+
+	if (S_ISDIR(newinode->i_mode)) {
+		rc = -EISDIR;
+		goto out_err;
 	}
+
 	d_drop(direntry);
 	d_add(direntry, newinode);
 
@@ -410,6 +437,13 @@ out:
 	kfree(buf);
 	kfree(full_path);
 	return rc;
+
+out_err:
+	if (server->ops->close)
+		server->ops->close(xid, tcon, fid);
+	if (newinode)
+		iput(newinode);
+	goto out;
 }
 
 int
--- zfcpdump-kernel-4.4.orig/fs/cifs/inode.c
+++ zfcpdump-kernel-4.4/fs/cifs/inode.c
@@ -982,10 +982,26 @@ struct inode *cifs_root_iget(struct supe
 	struct inode *inode = NULL;
 	long rc;
 	struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb);
+	char *path = NULL;
+	int len;
+
+	if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_USE_PREFIX_PATH)
+	    && cifs_sb->prepath) {
+		len = strlen(cifs_sb->prepath);
+		path = kzalloc(len + 2 /* leading sep + null */, GFP_KERNEL);
+		if (path == NULL)
+			return ERR_PTR(-ENOMEM);
+		path[0] = '/';
+		memcpy(path+1, cifs_sb->prepath, len);
+	} else {
+		path = kstrdup("", GFP_KERNEL);
+		if (path == NULL)
+			return ERR_PTR(-ENOMEM);
+	}
 
 	xid = get_xid();
 	if (tcon->unix_ext) {
-		rc = cifs_get_inode_info_unix(&inode, "", sb, xid);
+		rc = cifs_get_inode_info_unix(&inode, path, sb, xid);
 		/* some servers mistakenly claim POSIX support */
 		if (rc != -EOPNOTSUPP)
 			goto iget_no_retry;
@@ -993,7 +1009,8 @@ struct inode *cifs_root_iget(struct supe
 		tcon->unix_ext = false;
 	}
 
-	rc = cifs_get_inode_info(&inode, "", NULL, sb, xid, NULL);
+	convert_delimiter(path, CIFS_DIR_SEP(cifs_sb));
+	rc = cifs_get_inode_info(&inode, path, NULL, sb, xid, NULL);
 
 iget_no_retry:
 	if (!inode) {
@@ -1022,6 +1039,7 @@ iget_no_retry:
 	}
 
 out:
+	kfree(path);
 	/* can not call macro free_xid here since in a void func
 	 * TODO: This is no longer true
 	 */
--- zfcpdump-kernel-4.4.orig/fs/cifs/ntlmssp.h
+++ zfcpdump-kernel-4.4/fs/cifs/ntlmssp.h
@@ -133,6 +133,6 @@ typedef struct _AUTHENTICATE_MESSAGE {
 
 int decode_ntlmssp_challenge(char *bcc_ptr, int blob_len, struct cifs_ses *ses);
 void build_ntlmssp_negotiate_blob(unsigned char *pbuffer, struct cifs_ses *ses);
-int build_ntlmssp_auth_blob(unsigned char *pbuffer, u16 *buflen,
+int build_ntlmssp_auth_blob(unsigned char **pbuffer, u16 *buflen,
 			struct cifs_ses *ses,
 			const struct nls_table *nls_cp);
--- zfcpdump-kernel-4.4.orig/fs/cifs/readdir.c
+++ zfcpdump-kernel-4.4/fs/cifs/readdir.c
@@ -847,6 +847,7 @@ int cifs_readdir(struct file *file, stru
 		 * if buggy server returns . and .. late do we want to
 		 * check for that here?
 		 */
+		*tmp_buf = 0;
 		rc = cifs_filldir(current_entry, file, ctx,
 				  tmp_buf, max_len);
 		if (rc) {
--- zfcpdump-kernel-4.4.orig/fs/cifs/sess.c
+++ zfcpdump-kernel-4.4/fs/cifs/sess.c
@@ -364,19 +364,43 @@ void build_ntlmssp_negotiate_blob(unsign
 	sec_blob->DomainName.MaximumLength = 0;
 }
 
-/* We do not malloc the blob, it is passed in pbuffer, because its
-   maximum possible size is fixed and small, making this approach cleaner.
-   This function returns the length of the data in the blob */
-int build_ntlmssp_auth_blob(unsigned char *pbuffer,
+static int size_of_ntlmssp_blob(struct cifs_ses *ses)
+{
+	int sz = sizeof(AUTHENTICATE_MESSAGE) + ses->auth_key.len
+		- CIFS_SESS_KEY_SIZE + CIFS_CPHTXT_SIZE + 2;
+
+	if (ses->domainName)
+		sz += 2 * strnlen(ses->domainName, CIFS_MAX_DOMAINNAME_LEN);
+	else
+		sz += 2;
+
+	if (ses->user_name)
+		sz += 2 * strnlen(ses->user_name, CIFS_MAX_USERNAME_LEN);
+	else
+		sz += 2;
+
+	return sz;
+}
+
+int build_ntlmssp_auth_blob(unsigned char **pbuffer,
 					u16 *buflen,
 				   struct cifs_ses *ses,
 				   const struct nls_table *nls_cp)
 {
 	int rc;
-	AUTHENTICATE_MESSAGE *sec_blob = (AUTHENTICATE_MESSAGE *)pbuffer;
+	AUTHENTICATE_MESSAGE *sec_blob;
 	__u32 flags;
 	unsigned char *tmp;
 
+	rc = setup_ntlmv2_rsp(ses, nls_cp);
+	if (rc) {
+		cifs_dbg(VFS, "Error %d during NTLMSSP authentication\n", rc);
+		*buflen = 0;
+		goto setup_ntlmv2_ret;
+	}
+	*pbuffer = kmalloc(size_of_ntlmssp_blob(ses), GFP_KERNEL);
+	sec_blob = (AUTHENTICATE_MESSAGE *)*pbuffer;
+
 	memcpy(sec_blob->Signature, NTLMSSP_SIGNATURE, 8);
 	sec_blob->MessageType = NtLmAuthenticate;
 
@@ -391,7 +415,7 @@ int build_ntlmssp_auth_blob(unsigned cha
 			flags |= NTLMSSP_NEGOTIATE_KEY_XCH;
 	}
 
-	tmp = pbuffer + sizeof(AUTHENTICATE_MESSAGE);
+	tmp = *pbuffer + sizeof(AUTHENTICATE_MESSAGE);
 	sec_blob->NegotiateFlags = cpu_to_le32(flags);
 
 	sec_blob->LmChallengeResponse.BufferOffset =
@@ -399,23 +423,27 @@ int build_ntlmssp_auth_blob(unsigned cha
 	sec_blob->LmChallengeResponse.Length = 0;
 	sec_blob->LmChallengeResponse.MaximumLength = 0;
 
-	sec_blob->NtChallengeResponse.BufferOffset = cpu_to_le32(tmp - pbuffer);
-	rc = setup_ntlmv2_rsp(ses, nls_cp);
-	if (rc) {
-		cifs_dbg(VFS, "Error %d during NTLMSSP authentication\n", rc);
-		goto setup_ntlmv2_ret;
+	sec_blob->NtChallengeResponse.BufferOffset =
+				cpu_to_le32(tmp - *pbuffer);
+	if (ses->user_name != NULL) {
+		memcpy(tmp, ses->auth_key.response + CIFS_SESS_KEY_SIZE,
+				ses->auth_key.len - CIFS_SESS_KEY_SIZE);
+		tmp += ses->auth_key.len - CIFS_SESS_KEY_SIZE;
+
+		sec_blob->NtChallengeResponse.Length =
+				cpu_to_le16(ses->auth_key.len - CIFS_SESS_KEY_SIZE);
+		sec_blob->NtChallengeResponse.MaximumLength =
+				cpu_to_le16(ses->auth_key.len - CIFS_SESS_KEY_SIZE);
+	} else {
+		/*
+		 * don't send an NT Response for anonymous access
+		 */
+		sec_blob->NtChallengeResponse.Length = 0;
+		sec_blob->NtChallengeResponse.MaximumLength = 0;
 	}
-	memcpy(tmp, ses->auth_key.response + CIFS_SESS_KEY_SIZE,
-			ses->auth_key.len - CIFS_SESS_KEY_SIZE);
-	tmp += ses->auth_key.len - CIFS_SESS_KEY_SIZE;
-
-	sec_blob->NtChallengeResponse.Length =
-			cpu_to_le16(ses->auth_key.len - CIFS_SESS_KEY_SIZE);
-	sec_blob->NtChallengeResponse.MaximumLength =
-			cpu_to_le16(ses->auth_key.len - CIFS_SESS_KEY_SIZE);
 
 	if (ses->domainName == NULL) {
-		sec_blob->DomainName.BufferOffset = cpu_to_le32(tmp - pbuffer);
+		sec_blob->DomainName.BufferOffset = cpu_to_le32(tmp - *pbuffer);
 		sec_blob->DomainName.Length = 0;
 		sec_blob->DomainName.MaximumLength = 0;
 		tmp += 2;
@@ -424,14 +452,14 @@ int build_ntlmssp_auth_blob(unsigned cha
 		len = cifs_strtoUTF16((__le16 *)tmp, ses->domainName,
 				      CIFS_MAX_USERNAME_LEN, nls_cp);
 		len *= 2; /* unicode is 2 bytes each */
-		sec_blob->DomainName.BufferOffset = cpu_to_le32(tmp - pbuffer);
+		sec_blob->DomainName.BufferOffset = cpu_to_le32(tmp - *pbuffer);
 		sec_blob->DomainName.Length = cpu_to_le16(len);
 		sec_blob->DomainName.MaximumLength = cpu_to_le16(len);
 		tmp += len;
 	}
 
 	if (ses->user_name == NULL) {
-		sec_blob->UserName.BufferOffset = cpu_to_le32(tmp - pbuffer);
+		sec_blob->UserName.BufferOffset = cpu_to_le32(tmp - *pbuffer);
 		sec_blob->UserName.Length = 0;
 		sec_blob->UserName.MaximumLength = 0;
 		tmp += 2;
@@ -440,13 +468,13 @@ int build_ntlmssp_auth_blob(unsigned cha
 		len = cifs_strtoUTF16((__le16 *)tmp, ses->user_name,
 				      CIFS_MAX_USERNAME_LEN, nls_cp);
 		len *= 2; /* unicode is 2 bytes each */
-		sec_blob->UserName.BufferOffset = cpu_to_le32(tmp - pbuffer);
+		sec_blob->UserName.BufferOffset = cpu_to_le32(tmp - *pbuffer);
 		sec_blob->UserName.Length = cpu_to_le16(len);
 		sec_blob->UserName.MaximumLength = cpu_to_le16(len);
 		tmp += len;
 	}
 
-	sec_blob->WorkstationName.BufferOffset = cpu_to_le32(tmp - pbuffer);
+	sec_blob->WorkstationName.BufferOffset = cpu_to_le32(tmp - *pbuffer);
 	sec_blob->WorkstationName.Length = 0;
 	sec_blob->WorkstationName.MaximumLength = 0;
 	tmp += 2;
@@ -455,19 +483,19 @@ int build_ntlmssp_auth_blob(unsigned cha
 		(ses->ntlmssp->server_flags & NTLMSSP_NEGOTIATE_EXTENDED_SEC))
 			&& !calc_seckey(ses)) {
 		memcpy(tmp, ses->ntlmssp->ciphertext, CIFS_CPHTXT_SIZE);
-		sec_blob->SessionKey.BufferOffset = cpu_to_le32(tmp - pbuffer);
+		sec_blob->SessionKey.BufferOffset = cpu_to_le32(tmp - *pbuffer);
 		sec_blob->SessionKey.Length = cpu_to_le16(CIFS_CPHTXT_SIZE);
 		sec_blob->SessionKey.MaximumLength =
 				cpu_to_le16(CIFS_CPHTXT_SIZE);
 		tmp += CIFS_CPHTXT_SIZE;
 	} else {
-		sec_blob->SessionKey.BufferOffset = cpu_to_le32(tmp - pbuffer);
+		sec_blob->SessionKey.BufferOffset = cpu_to_le32(tmp - *pbuffer);
 		sec_blob->SessionKey.Length = 0;
 		sec_blob->SessionKey.MaximumLength = 0;
 	}
 
+	*buflen = tmp - *pbuffer;
 setup_ntlmv2_ret:
-	*buflen = tmp - pbuffer;
 	return rc;
 }
 
@@ -670,20 +698,24 @@ sess_auth_lanman(struct sess_data *sess_
 
 	pSMB->req.hdr.Flags2 &= ~SMBFLG2_UNICODE;
 
-	/* no capabilities flags in old lanman negotiation */
-	pSMB->old_req.PasswordLength = cpu_to_le16(CIFS_AUTH_RESP_SIZE);
-
-	/* Calculate hash with password and copy into bcc_ptr.
-	 * Encryption Key (stored as in cryptkey) gets used if the
-	 * security mode bit in Negottiate Protocol response states
-	 * to use challenge/response method (i.e. Password bit is 1).
-	 */
-	rc = calc_lanman_hash(ses->password, ses->server->cryptkey,
-			      ses->server->sec_mode & SECMODE_PW_ENCRYPT ?
-			      true : false, lnm_session_key);
+	if (ses->user_name != NULL) {
+		/* no capabilities flags in old lanman negotiation */
+		pSMB->old_req.PasswordLength = cpu_to_le16(CIFS_AUTH_RESP_SIZE);
+
+		/* Calculate hash with password and copy into bcc_ptr.
+		 * Encryption Key (stored as in cryptkey) gets used if the
+		 * security mode bit in Negottiate Protocol response states
+		 * to use challenge/response method (i.e. Password bit is 1).
+		 */
+		rc = calc_lanman_hash(ses->password, ses->server->cryptkey,
+				      ses->server->sec_mode & SECMODE_PW_ENCRYPT ?
+				      true : false, lnm_session_key);
 
-	memcpy(bcc_ptr, (char *)lnm_session_key, CIFS_AUTH_RESP_SIZE);
-	bcc_ptr += CIFS_AUTH_RESP_SIZE;
+		memcpy(bcc_ptr, (char *)lnm_session_key, CIFS_AUTH_RESP_SIZE);
+		bcc_ptr += CIFS_AUTH_RESP_SIZE;
+	} else {
+		pSMB->old_req.PasswordLength = 0;
+	}
 
 	/*
 	 * can not sign if LANMAN negotiated so no need
@@ -769,27 +801,32 @@ sess_auth_ntlm(struct sess_data *sess_da
 	capabilities = cifs_ssetup_hdr(ses, pSMB);
 
 	pSMB->req_no_secext.Capabilities = cpu_to_le32(capabilities);
-	pSMB->req_no_secext.CaseInsensitivePasswordLength =
-			cpu_to_le16(CIFS_AUTH_RESP_SIZE);
-	pSMB->req_no_secext.CaseSensitivePasswordLength =
-			cpu_to_le16(CIFS_AUTH_RESP_SIZE);
-
-	/* calculate ntlm response and session key */
-	rc = setup_ntlm_response(ses, sess_data->nls_cp);
-	if (rc) {
-		cifs_dbg(VFS, "Error %d during NTLM authentication\n",
-				 rc);
-		goto out;
+	if (ses->user_name != NULL) {
+		pSMB->req_no_secext.CaseInsensitivePasswordLength =
+				cpu_to_le16(CIFS_AUTH_RESP_SIZE);
+		pSMB->req_no_secext.CaseSensitivePasswordLength =
+				cpu_to_le16(CIFS_AUTH_RESP_SIZE);
+
+		/* calculate ntlm response and session key */
+		rc = setup_ntlm_response(ses, sess_data->nls_cp);
+		if (rc) {
+			cifs_dbg(VFS, "Error %d during NTLM authentication\n",
+					 rc);
+			goto out;
+		}
+
+		/* copy ntlm response */
+		memcpy(bcc_ptr, ses->auth_key.response + CIFS_SESS_KEY_SIZE,
+				CIFS_AUTH_RESP_SIZE);
+		bcc_ptr += CIFS_AUTH_RESP_SIZE;
+		memcpy(bcc_ptr, ses->auth_key.response + CIFS_SESS_KEY_SIZE,
+				CIFS_AUTH_RESP_SIZE);
+		bcc_ptr += CIFS_AUTH_RESP_SIZE;
+	} else {
+		pSMB->req_no_secext.CaseInsensitivePasswordLength = 0;
+		pSMB->req_no_secext.CaseSensitivePasswordLength = 0;
 	}
 
-	/* copy ntlm response */
-	memcpy(bcc_ptr, ses->auth_key.response + CIFS_SESS_KEY_SIZE,
-			CIFS_AUTH_RESP_SIZE);
-	bcc_ptr += CIFS_AUTH_RESP_SIZE;
-	memcpy(bcc_ptr, ses->auth_key.response + CIFS_SESS_KEY_SIZE,
-			CIFS_AUTH_RESP_SIZE);
-	bcc_ptr += CIFS_AUTH_RESP_SIZE;
-
 	if (ses->capabilities & CAP_UNICODE) {
 		/* unicode strings must be word aligned */
 		if (sess_data->iov[0].iov_len % 2) {
@@ -878,23 +915,27 @@ sess_auth_ntlmv2(struct sess_data *sess_
 	/* LM2 password would be here if we supported it */
 	pSMB->req_no_secext.CaseInsensitivePasswordLength = 0;
 
-	/* calculate nlmv2 response and session key */
-	rc = setup_ntlmv2_rsp(ses, sess_data->nls_cp);
-	if (rc) {
-		cifs_dbg(VFS, "Error %d during NTLMv2 authentication\n", rc);
-		goto out;
+	if (ses->user_name != NULL) {
+		/* calculate nlmv2 response and session key */
+		rc = setup_ntlmv2_rsp(ses, sess_data->nls_cp);
+		if (rc) {
+			cifs_dbg(VFS, "Error %d during NTLMv2 authentication\n", rc);
+			goto out;
+		}
+
+		memcpy(bcc_ptr, ses->auth_key.response + CIFS_SESS_KEY_SIZE,
+				ses->auth_key.len - CIFS_SESS_KEY_SIZE);
+		bcc_ptr += ses->auth_key.len - CIFS_SESS_KEY_SIZE;
+
+		/* set case sensitive password length after tilen may get
+		 * assigned, tilen is 0 otherwise.
+		 */
+		pSMB->req_no_secext.CaseSensitivePasswordLength =
+			cpu_to_le16(ses->auth_key.len - CIFS_SESS_KEY_SIZE);
+	} else {
+		pSMB->req_no_secext.CaseSensitivePasswordLength = 0;
 	}
 
-	memcpy(bcc_ptr, ses->auth_key.response + CIFS_SESS_KEY_SIZE,
-			ses->auth_key.len - CIFS_SESS_KEY_SIZE);
-	bcc_ptr += ses->auth_key.len - CIFS_SESS_KEY_SIZE;
-
-	/* set case sensitive password length after tilen may get
-	 * assigned, tilen is 0 otherwise.
-	 */
-	pSMB->req_no_secext.CaseSensitivePasswordLength =
-		cpu_to_le16(ses->auth_key.len - CIFS_SESS_KEY_SIZE);
-
 	if (ses->capabilities & CAP_UNICODE) {
 		if (sess_data->iov[0].iov_len % 2) {
 			*bcc_ptr = 0;
@@ -1245,7 +1286,7 @@ sess_auth_rawntlmssp_authenticate(struct
 	struct cifs_ses *ses = sess_data->ses;
 	__u16 bytes_remaining;
 	char *bcc_ptr;
-	char *ntlmsspblob = NULL;
+	unsigned char *ntlmsspblob = NULL;
 	u16 blob_len;
 
 	cifs_dbg(FYI, "rawntlmssp session setup authenticate phase\n");
@@ -1258,19 +1299,7 @@ sess_auth_rawntlmssp_authenticate(struct
 	/* Build security blob before we assemble the request */
 	pSMB = (SESSION_SETUP_ANDX *)sess_data->iov[0].iov_base;
 	smb_buf = (struct smb_hdr *)pSMB;
-	/*
-	 * 5 is an empirical value, large enough to hold
-	 * authenticate message plus max 10 of av paris,
-	 * domain, user, workstation names, flags, etc.
-	 */
-	ntlmsspblob = kzalloc(5*sizeof(struct _AUTHENTICATE_MESSAGE),
-				GFP_KERNEL);
-	if (!ntlmsspblob) {
-		rc = -ENOMEM;
-		goto out;
-	}
-
-	rc = build_ntlmssp_auth_blob(ntlmsspblob,
+	rc = build_ntlmssp_auth_blob(&ntlmsspblob,
 					&blob_len, ses, sess_data->nls_cp);
 	if (rc)
 		goto out_free_ntlmsspblob;
--- zfcpdump-kernel-4.4.orig/fs/cifs/smb2glob.h
+++ zfcpdump-kernel-4.4/fs/cifs/smb2glob.h
@@ -44,6 +44,7 @@
 #define SMB2_OP_DELETE 7
 #define SMB2_OP_HARDLINK 8
 #define SMB2_OP_SET_EOF 9
+#define SMB2_OP_RMDIR 10
 
 /* Used when constructing chained read requests. */
 #define CHAINED_REQUEST 1
--- zfcpdump-kernel-4.4.orig/fs/cifs/smb2inode.c
+++ zfcpdump-kernel-4.4/fs/cifs/smb2inode.c
@@ -80,6 +80,10 @@ smb2_open_op_close(const unsigned int xi
 		 * SMB2_open() call.
 		 */
 		break;
+	case SMB2_OP_RMDIR:
+		tmprc = SMB2_rmdir(xid, tcon, fid.persistent_fid,
+				   fid.volatile_fid);
+		break;
 	case SMB2_OP_RENAME:
 		tmprc = SMB2_rename(xid, tcon, fid.persistent_fid,
 				    fid.volatile_fid, (__le16 *)data);
@@ -191,8 +195,8 @@ smb2_rmdir(const unsigned int xid, struc
 	   struct cifs_sb_info *cifs_sb)
 {
 	return smb2_open_op_close(xid, tcon, cifs_sb, name, DELETE, FILE_OPEN,
-				  CREATE_NOT_FILE | CREATE_DELETE_ON_CLOSE,
-				  NULL, SMB2_OP_DELETE);
+				  CREATE_NOT_FILE,
+				  NULL, SMB2_OP_RMDIR);
 }
 
 int
--- zfcpdump-kernel-4.4.orig/fs/cifs/smb2ops.c
+++ zfcpdump-kernel-4.4/fs/cifs/smb2ops.c
@@ -1039,6 +1039,9 @@ smb2_new_lease_key(struct cifs_fid *fid)
 	get_random_bytes(fid->lease_key, SMB2_LEASE_KEY_SIZE);
 }
 
+#define SMB2_SYMLINK_STRUCT_SIZE \
+	(sizeof(struct smb2_err_rsp) - 1 + sizeof(struct smb2_symlink_err_rsp))
+
 static int
 smb2_query_symlink(const unsigned int xid, struct cifs_tcon *tcon,
 		   const char *full_path, char **target_path,
@@ -1051,7 +1054,10 @@ smb2_query_symlink(const unsigned int xi
 	struct cifs_fid fid;
 	struct smb2_err_rsp *err_buf = NULL;
 	struct smb2_symlink_err_rsp *symlink;
-	unsigned int sub_len, sub_offset;
+	unsigned int sub_len;
+	unsigned int sub_offset;
+	unsigned int print_len;
+	unsigned int print_offset;
 
 	cifs_dbg(FYI, "%s: path: %s\n", __func__, full_path);
 
@@ -1072,11 +1078,33 @@ smb2_query_symlink(const unsigned int xi
 		kfree(utf16_path);
 		return -ENOENT;
 	}
+
+	if (le32_to_cpu(err_buf->ByteCount) < sizeof(struct smb2_symlink_err_rsp) ||
+	    get_rfc1002_length(err_buf) + 4 < SMB2_SYMLINK_STRUCT_SIZE) {
+		kfree(utf16_path);
+		return -ENOENT;
+	}
+
 	/* open must fail on symlink - reset rc */
 	rc = 0;
 	symlink = (struct smb2_symlink_err_rsp *)err_buf->ErrorData;
 	sub_len = le16_to_cpu(symlink->SubstituteNameLength);
 	sub_offset = le16_to_cpu(symlink->SubstituteNameOffset);
+	print_len = le16_to_cpu(symlink->PrintNameLength);
+	print_offset = le16_to_cpu(symlink->PrintNameOffset);
+
+	if (get_rfc1002_length(err_buf) + 4 <
+			SMB2_SYMLINK_STRUCT_SIZE + sub_offset + sub_len) {
+		kfree(utf16_path);
+		return -ENOENT;
+	}
+
+	if (get_rfc1002_length(err_buf) + 4 <
+			SMB2_SYMLINK_STRUCT_SIZE + print_offset + print_len) {
+		kfree(utf16_path);
+		return -ENOENT;
+	}
+
 	*target_path = cifs_strndup_from_utf16(
 				(char *)symlink->PathBuffer + sub_offset,
 				sub_len, true, cifs_sb->local_nls);
--- zfcpdump-kernel-4.4.orig/fs/cifs/smb2pdu.c
+++ zfcpdump-kernel-4.4/fs/cifs/smb2pdu.c
@@ -591,7 +591,7 @@ SMB2_sess_setup(const unsigned int xid,
 	u16 blob_length = 0;
 	struct key *spnego_key = NULL;
 	char *security_blob = NULL;
-	char *ntlmssp_blob = NULL;
+	unsigned char *ntlmssp_blob = NULL;
 	bool use_spnego = false; /* else use raw ntlmssp */
 
 	cifs_dbg(FYI, "Session Setup\n");
@@ -716,13 +716,7 @@ ssetup_ntlmssp_authenticate:
 		iov[1].iov_len = blob_length;
 	} else if (phase == NtLmAuthenticate) {
 		req->hdr.SessionId = ses->Suid;
-		ntlmssp_blob = kzalloc(sizeof(struct _NEGOTIATE_MESSAGE) + 500,
-				       GFP_KERNEL);
-		if (ntlmssp_blob == NULL) {
-			rc = -ENOMEM;
-			goto ssetup_exit;
-		}
-		rc = build_ntlmssp_auth_blob(ntlmssp_blob, &blob_length, ses,
+		rc = build_ntlmssp_auth_blob(&ntlmssp_blob, &blob_length, ses,
 					     nls_cp);
 		if (rc) {
 			cifs_dbg(FYI, "build_ntlmssp_auth_blob failed %d\n",
@@ -1109,21 +1103,25 @@ parse_lease_state(struct TCP_Server_Info
 {
 	char *data_offset;
 	struct create_context *cc;
-	unsigned int next = 0;
+	unsigned int next;
+	unsigned int remaining;
 	char *name;
 
 	data_offset = (char *)rsp + 4 + le32_to_cpu(rsp->CreateContextsOffset);
+	remaining = le32_to_cpu(rsp->CreateContextsLength);
 	cc = (struct create_context *)data_offset;
-	do {
-		cc = (struct create_context *)((char *)cc + next);
+	while (remaining >= sizeof(struct create_context)) {
 		name = le16_to_cpu(cc->NameOffset) + (char *)cc;
-		if (le16_to_cpu(cc->NameLength) != 4 ||
-		    strncmp(name, "RqLs", 4)) {
-			next = le32_to_cpu(cc->Next);
-			continue;
-		}
-		return server->ops->parse_lease_buf(cc, epoch);
-	} while (next != 0);
+		if (le16_to_cpu(cc->NameLength) == 4 &&
+		    strncmp(name, "RqLs", 4) == 0)
+			return server->ops->parse_lease_buf(cc, epoch);
+
+		next = le32_to_cpu(cc->Next);
+		if (!next)
+			break;
+		remaining -= next;
+		cc = (struct create_context *)((char *)cc + next);
+	}
 
 	return 0;
 }
@@ -1816,6 +1814,33 @@ SMB2_echo(struct TCP_Server_Info *server
 
 	cifs_dbg(FYI, "In echo request\n");
 
+	if (server->tcpStatus == CifsNeedNegotiate) {
+		struct list_head *tmp, *tmp2;
+		struct cifs_ses *ses;
+		struct cifs_tcon *tcon;
+
+		cifs_dbg(FYI, "Need negotiate, reconnecting tcons\n");
+		spin_lock(&cifs_tcp_ses_lock);
+		list_for_each(tmp, &server->smb_ses_list) {
+			ses = list_entry(tmp, struct cifs_ses, smb_ses_list);
+			list_for_each(tmp2, &ses->tcon_list) {
+				tcon = list_entry(tmp2, struct cifs_tcon,
+						  tcon_list);
+				/* add check for persistent handle reconnect */
+				if (tcon && tcon->need_reconnect) {
+					spin_unlock(&cifs_tcp_ses_lock);
+					rc = smb2_reconnect(SMB2_ECHO, tcon);
+					spin_lock(&cifs_tcp_ses_lock);
+				}
+			}
+		}
+		spin_unlock(&cifs_tcp_ses_lock);
+	}
+
+	/* if no session, renegotiate failed above */
+	if (server->tcpStatus == CifsNeedNegotiate)
+		return -EIO;
+
 	rc = small_smb2_init(SMB2_ECHO, NULL, (void **)&req);
 	if (rc)
 		return rc;
@@ -2573,6 +2598,22 @@ SMB2_rename(const unsigned int xid, stru
 }
 
 int
+SMB2_rmdir(const unsigned int xid, struct cifs_tcon *tcon,
+		  u64 persistent_fid, u64 volatile_fid)
+{
+	__u8 delete_pending = 1;
+	void *data;
+	unsigned int size;
+
+	data = &delete_pending;
+	size = 1; /* sizeof __u8 */
+
+	return send_set_info(xid, tcon, persistent_fid, volatile_fid,
+			current->tgid, FILE_DISPOSITION_INFORMATION, 1, &data,
+			&size);
+}
+
+int
 SMB2_set_hardlink(const unsigned int xid, struct cifs_tcon *tcon,
 		  u64 persistent_fid, u64 volatile_fid, __le16 *target_file)
 {
--- zfcpdump-kernel-4.4.orig/fs/cifs/smb2proto.h
+++ zfcpdump-kernel-4.4/fs/cifs/smb2proto.h
@@ -140,6 +140,8 @@ extern int SMB2_query_directory(const un
 extern int SMB2_rename(const unsigned int xid, struct cifs_tcon *tcon,
 		       u64 persistent_fid, u64 volatile_fid,
 		       __le16 *target_file);
+extern int SMB2_rmdir(const unsigned int xid, struct cifs_tcon *tcon,
+		      u64 persistent_fid, u64 volatile_fid);
 extern int SMB2_set_hardlink(const unsigned int xid, struct cifs_tcon *tcon,
 			     u64 persistent_fid, u64 volatile_fid,
 			     __le16 *target_file);
--- zfcpdump-kernel-4.4.orig/fs/cifs/transport.c
+++ zfcpdump-kernel-4.4/fs/cifs/transport.c
@@ -576,14 +576,16 @@ cifs_call_async(struct TCP_Server_Info *
 	cifs_in_send_dec(server);
 	cifs_save_when_sent(mid);
 
-	if (rc < 0)
+	if (rc < 0) {
 		server->sequence_number -= 2;
+		cifs_delete_mid(mid);
+	}
+
 	mutex_unlock(&server->srv_mutex);
 
 	if (rc == 0)
 		return 0;
 
-	cifs_delete_mid(mid);
 	add_credits_and_wake_if(server, credits, optype);
 	return rc;
 }
--- zfcpdump-kernel-4.4.orig/fs/coredump.c
+++ zfcpdump-kernel-4.4/fs/coredump.c
@@ -32,6 +32,9 @@
 #include <linux/pipe_fs_i.h>
 #include <linux/oom.h>
 #include <linux/compat.h>
+#include <linux/sched.h>
+#include <linux/fs.h>
+#include <linux/path.h>
 
 #include <asm/uaccess.h>
 #include <asm/mmu_context.h>
@@ -627,6 +630,8 @@ void do_coredump(const siginfo_t *siginf
 		}
 	} else {
 		struct inode *inode;
+		int open_flags = O_CREAT | O_RDWR | O_NOFOLLOW |
+				 O_LARGEFILE | O_EXCL;
 
 		if (cprm.limit < binfmt->min_coredump)
 			goto fail_unlock;
@@ -665,10 +670,27 @@ void do_coredump(const siginfo_t *siginf
 		 * what matters is that at least one of the two processes
 		 * writes its coredump successfully, not which one.
 		 */
-		cprm.file = filp_open(cn.corename,
-				 O_CREAT | 2 | O_NOFOLLOW |
-				 O_LARGEFILE | O_EXCL,
-				 0600);
+		if (need_suid_safe) {
+			/*
+			 * Using user namespaces, normal user tasks can change
+			 * their current->fs->root to point to arbitrary
+			 * directories. Since the intention of the "only dump
+			 * with a fully qualified path" rule is to control where
+			 * coredumps may be placed using root privileges,
+			 * current->fs->root must not be used. Instead, use the
+			 * root directory of init_task.
+			 */
+			struct path root;
+
+			task_lock(&init_task);
+			get_fs_root(init_task.fs, &root);
+			task_unlock(&init_task);
+			cprm.file = file_open_root(root.dentry, root.mnt,
+				cn.corename, open_flags, 0600);
+			path_put(&root);
+		} else {
+			cprm.file = filp_open(cn.corename, open_flags, 0600);
+		}
 		if (IS_ERR(cprm.file))
 			goto fail_unlock;
 
--- zfcpdump-kernel-4.4.orig/fs/dcache.c
+++ zfcpdump-kernel-4.4/fs/dcache.c
@@ -269,9 +269,6 @@ static inline int dname_external(const s
 	return dentry->d_name.name != dentry->d_iname;
 }
 
-/*
- * Make sure other CPUs see the inode attached before the type is set.
- */
 static inline void __d_set_inode_and_type(struct dentry *dentry,
 					  struct inode *inode,
 					  unsigned type_flags)
@@ -279,28 +276,18 @@ static inline void __d_set_inode_and_typ
 	unsigned flags;
 
 	dentry->d_inode = inode;
-	smp_wmb();
 	flags = READ_ONCE(dentry->d_flags);
 	flags &= ~(DCACHE_ENTRY_TYPE | DCACHE_FALLTHRU);
 	flags |= type_flags;
 	WRITE_ONCE(dentry->d_flags, flags);
 }
 
-/*
- * Ideally, we want to make sure that other CPUs see the flags cleared before
- * the inode is detached, but this is really a violation of RCU principles
- * since the ordering suggests we should always set inode before flags.
- *
- * We should instead replace or discard the entire dentry - but that sucks
- * performancewise on mass deletion/rename.
- */
 static inline void __d_clear_type_and_inode(struct dentry *dentry)
 {
 	unsigned flags = READ_ONCE(dentry->d_flags);
 
 	flags &= ~(DCACHE_ENTRY_TYPE | DCACHE_FALLTHRU);
 	WRITE_ONCE(dentry->d_flags, flags);
-	smp_wmb();
 	dentry->d_inode = NULL;
 }
 
@@ -370,9 +357,11 @@ static void dentry_unlink_inode(struct d
 	__releases(dentry->d_inode->i_lock)
 {
 	struct inode *inode = dentry->d_inode;
+
+	raw_write_seqcount_begin(&dentry->d_seq);
 	__d_clear_type_and_inode(dentry);
 	hlist_del_init(&dentry->d_u.d_alias);
-	dentry_rcuwalk_invalidate(dentry);
+	raw_write_seqcount_end(&dentry->d_seq);
 	spin_unlock(&dentry->d_lock);
 	spin_unlock(&inode->i_lock);
 	if (!inode->i_nlink)
@@ -589,7 +578,6 @@ static struct dentry *dentry_kill(struct
 
 failed:
 	spin_unlock(&dentry->d_lock);
-	cpu_relax();
 	return dentry; /* try again with same dentry */
 }
 
@@ -763,6 +751,8 @@ void dput(struct dentry *dentry)
 		return;
 
 repeat:
+	might_sleep();
+
 	rcu_read_lock();
 	if (likely(fast_dput(dentry))) {
 		rcu_read_unlock();
@@ -794,8 +784,10 @@ repeat:
 
 kill_it:
 	dentry = dentry_kill(dentry);
-	if (dentry)
+	if (dentry) {
+		cond_resched();
 		goto repeat;
+	}
 }
 EXPORT_SYMBOL(dput);
 
@@ -1167,7 +1159,7 @@ enum d_walk_ret {
  *
  * The @enter() and @finish() callbacks are called with d_lock held.
  */
-static void d_walk(struct dentry *parent, void *data,
+void d_walk(struct dentry *parent, void *data,
 		   enum d_walk_ret (*enter)(void *, struct dentry *),
 		   void (*finish)(void *))
 {
@@ -1272,6 +1264,7 @@ rename_retry:
 	seq = 1;
 	goto again;
 }
+EXPORT_SYMBOL(d_walk);
 
 /*
  * Search for at least 1 mount point in the dentry's subdirs.
@@ -1629,7 +1622,7 @@ struct dentry *d_alloc(struct dentry * p
 	struct dentry *dentry = __d_alloc(parent->d_sb, name);
 	if (!dentry)
 		return NULL;
-
+	dentry->d_flags |= DCACHE_RCUACCESS;
 	spin_lock(&parent->d_lock);
 	/*
 	 * don't need child lock because it is not subject
@@ -1677,7 +1670,8 @@ void d_set_d_op(struct dentry *dentry, c
 				DCACHE_OP_REVALIDATE	|
 				DCACHE_OP_WEAK_REVALIDATE	|
 				DCACHE_OP_DELETE	|
-				DCACHE_OP_SELECT_INODE));
+				DCACHE_OP_SELECT_INODE	|
+				DCACHE_OP_REAL));
 	dentry->d_op = op;
 	if (!op)
 		return;
@@ -1695,6 +1689,8 @@ void d_set_d_op(struct dentry *dentry, c
 		dentry->d_flags |= DCACHE_OP_PRUNE;
 	if (op->d_select_inode)
 		dentry->d_flags |= DCACHE_OP_SELECT_INODE;
+	if (op->d_real)
+		dentry->d_flags |= DCACHE_OP_REAL;
 
 }
 EXPORT_SYMBOL(d_set_d_op);
@@ -1757,8 +1753,9 @@ static void __d_instantiate(struct dentr
 	spin_lock(&dentry->d_lock);
 	if (inode)
 		hlist_add_head(&dentry->d_u.d_alias, &inode->i_dentry);
+	raw_write_seqcount_begin(&dentry->d_seq);
 	__d_set_inode_and_type(dentry, inode, add_flags);
-	dentry_rcuwalk_invalidate(dentry);
+	raw_write_seqcount_end(&dentry->d_seq);
 	spin_unlock(&dentry->d_lock);
 	fsnotify_d_instantiate(dentry, inode);
 }
@@ -2420,7 +2417,6 @@ static void __d_rehash(struct dentry * e
 {
 	BUG_ON(!d_unhashed(entry));
 	hlist_bl_lock(b);
-	entry->d_flags |= DCACHE_RCUACCESS;
 	hlist_bl_add_head_rcu(&entry->d_hash, b);
 	hlist_bl_unlock(b);
 }
@@ -2639,6 +2635,7 @@ static void __d_move(struct dentry *dent
 	/* ... and switch them in the tree */
 	if (IS_ROOT(dentry)) {
 		/* splicing a tree */
+		dentry->d_flags |= DCACHE_RCUACCESS;
 		dentry->d_parent = target->d_parent;
 		target->d_parent = target;
 		list_del_init(&target->d_child);
--- zfcpdump-kernel-4.4.orig/fs/debugfs/inode.c
+++ zfcpdump-kernel-4.4/fs/debugfs/inode.c
@@ -457,7 +457,7 @@ struct dentry *debugfs_create_automount(
 	if (unlikely(!inode))
 		return failed_creating(dentry);
 
-	inode->i_mode = S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO;
+	make_empty_dir_inode(inode);
 	inode->i_flags |= S_AUTOMOUNT;
 	inode->i_private = data;
 	dentry->d_fsdata = (void *)f;
--- zfcpdump-kernel-4.4.orig/fs/devpts/inode.c
+++ zfcpdump-kernel-4.4/fs/devpts/inode.c
@@ -128,6 +128,7 @@ static const match_table_t tokens = {
 struct pts_fs_info {
 	struct ida allocated_ptys;
 	struct pts_mount_opts mount_opts;
+	struct super_block *sb;
 	struct dentry *ptmx_dentry;
 };
 
@@ -358,7 +359,7 @@ static const struct super_operations dev
 	.show_options	= devpts_show_options,
 };
 
-static void *new_pts_fs_info(void)
+static void *new_pts_fs_info(struct super_block *sb)
 {
 	struct pts_fs_info *fsi;
 
@@ -369,6 +370,7 @@ static void *new_pts_fs_info(void)
 	ida_init(&fsi->allocated_ptys);
 	fsi->mount_opts.mode = DEVPTS_DEFAULT_MODE;
 	fsi->mount_opts.ptmxmode = DEVPTS_DEFAULT_PTMX_MODE;
+	fsi->sb = sb;
 
 	return fsi;
 }
@@ -384,7 +386,7 @@ devpts_fill_super(struct super_block *s,
 	s->s_op = &devpts_sops;
 	s->s_time_gran = 1;
 
-	s->s_fs_info = new_pts_fs_info();
+	s->s_fs_info = new_pts_fs_info(s);
 	if (!s->s_fs_info)
 		goto fail;
 
@@ -524,17 +526,14 @@ static struct file_system_type devpts_fs
  * to the System V naming convention
  */
 
-int devpts_new_index(struct inode *ptmx_inode)
+int devpts_new_index(struct pts_fs_info *fsi)
 {
-	struct super_block *sb = pts_sb_from_inode(ptmx_inode);
-	struct pts_fs_info *fsi;
 	int index;
 	int ida_ret;
 
-	if (!sb)
+	if (!fsi)
 		return -ENODEV;
 
-	fsi = DEVPTS_SB(sb);
 retry:
 	if (!ida_pre_get(&fsi->allocated_ptys, GFP_KERNEL))
 		return -ENOMEM;
@@ -564,17 +563,38 @@ retry:
 	return index;
 }
 
-void devpts_kill_index(struct inode *ptmx_inode, int idx)
+void devpts_kill_index(struct pts_fs_info *fsi, int idx)
 {
-	struct super_block *sb = pts_sb_from_inode(ptmx_inode);
-	struct pts_fs_info *fsi = DEVPTS_SB(sb);
-
 	mutex_lock(&allocated_ptys_lock);
 	ida_remove(&fsi->allocated_ptys, idx);
 	pty_count--;
 	mutex_unlock(&allocated_ptys_lock);
 }
 
+/*
+ * pty code needs to hold extra references in case of last /dev/tty close
+ */
+struct pts_fs_info *devpts_get_ref(struct inode *ptmx_inode, struct file *file)
+{
+	struct super_block *sb;
+	struct pts_fs_info *fsi;
+
+	sb = pts_sb_from_inode(ptmx_inode);
+	if (!sb)
+		return NULL;
+	fsi = DEVPTS_SB(sb);
+	if (!fsi)
+		return NULL;
+
+	atomic_inc(&sb->s_active);
+	return fsi;
+}
+
+void devpts_put_ref(struct pts_fs_info *fsi)
+{
+	deactivate_super(fsi->sb);
+}
+
 /**
  * devpts_pty_new -- create a new inode in /dev/pts/
  * @ptmx_inode: inode of the master
@@ -584,22 +604,21 @@ void devpts_kill_index(struct inode *ptm
  *
  * The created inode is returned. Remove it from /dev/pts/ by devpts_pty_kill.
  */
-struct inode *devpts_pty_new(struct inode *ptmx_inode, dev_t device, int index,
+struct inode *devpts_pty_new(struct pts_fs_info *fsi, dev_t device, int index,
 		void *priv)
 {
 	struct dentry *dentry;
-	struct super_block *sb = pts_sb_from_inode(ptmx_inode);
+	struct super_block *sb;
 	struct inode *inode;
 	struct dentry *root;
-	struct pts_fs_info *fsi;
 	struct pts_mount_opts *opts;
 	char s[12];
 
-	if (!sb)
+	if (!fsi)
 		return ERR_PTR(-ENODEV);
 
+	sb = fsi->sb;
 	root = sb->s_root;
-	fsi = DEVPTS_SB(sb);
 	opts = &fsi->mount_opts;
 
 	inode = new_inode(sb);
--- zfcpdump-kernel-4.4.orig/fs/direct-io.c
+++ zfcpdump-kernel-4.4/fs/direct-io.c
@@ -472,8 +472,8 @@ static int dio_bio_complete(struct dio *
 		dio->io_error = -EIO;
 
 	if (dio->is_async && dio->rw == READ && dio->should_dirty) {
-		bio_check_pages_dirty(bio);	/* transfers ownership */
 		err = bio->bi_error;
+		bio_check_pages_dirty(bio);	/* transfers ownership */
 	} else {
 		bio_for_each_segment_all(bvec, bio, i) {
 			struct page *page = bvec->bv_page;
--- zfcpdump-kernel-4.4.orig/fs/ecryptfs/file.c
+++ zfcpdump-kernel-4.4/fs/ecryptfs/file.c
@@ -112,7 +112,6 @@ static int ecryptfs_readdir(struct file
 		.sb = inode->i_sb,
 	};
 	lower_file = ecryptfs_file_to_lower(file);
-	lower_file->f_pos = ctx->pos;
 	rc = iterate_dir(lower_file, &buf.ctx);
 	ctx->pos = buf.ctx.pos;
 	if (rc < 0)
@@ -170,6 +169,19 @@ out:
 	return rc;
 }
 
+static int ecryptfs_mmap(struct file *file, struct vm_area_struct *vma)
+{
+	struct file *lower_file = ecryptfs_file_to_lower(file);
+	/*
+	 * Don't allow mmap on top of file systems that don't support it
+	 * natively.  If FILESYSTEM_MAX_STACK_DEPTH > 2 or ecryptfs
+	 * allows recursive mounting, this will need to be extended.
+	 */
+	if (!lower_file->f_op->mmap)
+		return -ENODEV;
+	return generic_file_mmap(file, vma);
+}
+
 /**
  * ecryptfs_open
  * @inode: inode speciying file to open
@@ -223,14 +235,6 @@ static int ecryptfs_open(struct inode *i
 	}
 	ecryptfs_set_file_lower(
 		file, ecryptfs_inode_to_private(inode)->lower_file);
-	if (d_is_dir(ecryptfs_dentry)) {
-		ecryptfs_printk(KERN_DEBUG, "This is a directory\n");
-		mutex_lock(&crypt_stat->cs_mutex);
-		crypt_stat->flags &= ~(ECRYPTFS_ENCRYPTED);
-		mutex_unlock(&crypt_stat->cs_mutex);
-		rc = 0;
-		goto out;
-	}
 	rc = read_or_initialize_metadata(ecryptfs_dentry);
 	if (rc)
 		goto out_put;
@@ -247,6 +251,45 @@ out:
 	return rc;
 }
 
+/**
+ * ecryptfs_dir_open
+ * @inode: inode speciying file to open
+ * @file: Structure to return filled in
+ *
+ * Opens the file specified by inode.
+ *
+ * Returns zero on success; non-zero otherwise
+ */
+static int ecryptfs_dir_open(struct inode *inode, struct file *file)
+{
+	struct dentry *ecryptfs_dentry = file->f_path.dentry;
+	/* Private value of ecryptfs_dentry allocated in
+	 * ecryptfs_lookup() */
+	struct ecryptfs_file_info *file_info;
+	struct file *lower_file;
+
+	/* Released in ecryptfs_release or end of function if failure */
+	file_info = kmem_cache_zalloc(ecryptfs_file_info_cache, GFP_KERNEL);
+	ecryptfs_set_file_private(file, file_info);
+	if (unlikely(!file_info)) {
+		ecryptfs_printk(KERN_ERR,
+				"Error attempting to allocate memory\n");
+		return -ENOMEM;
+	}
+	lower_file = dentry_open(ecryptfs_dentry_to_lower_path(ecryptfs_dentry),
+				 file->f_flags, current_cred());
+	if (IS_ERR(lower_file)) {
+		printk(KERN_ERR "%s: Error attempting to initialize "
+			"the lower file for the dentry with name "
+			"[%pd]; rc = [%ld]\n", __func__,
+			ecryptfs_dentry, PTR_ERR(lower_file));
+		kmem_cache_free(ecryptfs_file_info_cache, file_info);
+		return PTR_ERR(lower_file);
+	}
+	ecryptfs_set_file_lower(file, lower_file);
+	return 0;
+}
+
 static int ecryptfs_flush(struct file *file, fl_owner_t td)
 {
 	struct file *lower_file = ecryptfs_file_to_lower(file);
@@ -267,6 +310,19 @@ static int ecryptfs_release(struct inode
 	return 0;
 }
 
+static int ecryptfs_dir_release(struct inode *inode, struct file *file)
+{
+	fput(ecryptfs_file_to_lower(file));
+	kmem_cache_free(ecryptfs_file_info_cache,
+			ecryptfs_file_to_private(file));
+	return 0;
+}
+
+static loff_t ecryptfs_dir_llseek(struct file *file, loff_t offset, int whence)
+{
+	return vfs_llseek(ecryptfs_file_to_lower(file), offset, whence);
+}
+
 static int
 ecryptfs_fsync(struct file *file, loff_t start, loff_t end, int datasync)
 {
@@ -346,25 +402,21 @@ const struct file_operations ecryptfs_di
 #ifdef CONFIG_COMPAT
 	.compat_ioctl = ecryptfs_compat_ioctl,
 #endif
-	.open = ecryptfs_open,
-	.flush = ecryptfs_flush,
-	.release = ecryptfs_release,
+	.open = ecryptfs_dir_open,
+	.release = ecryptfs_dir_release,
 	.fsync = ecryptfs_fsync,
-	.fasync = ecryptfs_fasync,
-	.splice_read = generic_file_splice_read,
-	.llseek = default_llseek,
+	.llseek = ecryptfs_dir_llseek,
 };
 
 const struct file_operations ecryptfs_main_fops = {
 	.llseek = generic_file_llseek,
 	.read_iter = ecryptfs_read_update_atime,
 	.write_iter = generic_file_write_iter,
-	.iterate = ecryptfs_readdir,
 	.unlocked_ioctl = ecryptfs_unlocked_ioctl,
 #ifdef CONFIG_COMPAT
 	.compat_ioctl = ecryptfs_compat_ioctl,
 #endif
-	.mmap = generic_file_mmap,
+	.mmap = ecryptfs_mmap,
 	.open = ecryptfs_open,
 	.flush = ecryptfs_flush,
 	.release = ecryptfs_release,
--- zfcpdump-kernel-4.4.orig/fs/efivarfs/file.c
+++ zfcpdump-kernel-4.4/fs/efivarfs/file.c
@@ -10,6 +10,7 @@
 #include <linux/efi.h>
 #include <linux/fs.h>
 #include <linux/slab.h>
+#include <linux/mount.h>
 
 #include "internal.h"
 
@@ -103,9 +104,78 @@ out_free:
 	return size;
 }
 
+static int
+efivarfs_ioc_getxflags(struct file *file, void __user *arg)
+{
+	struct inode *inode = file->f_mapping->host;
+	unsigned int i_flags;
+	unsigned int flags = 0;
+
+	i_flags = inode->i_flags;
+	if (i_flags & S_IMMUTABLE)
+		flags |= FS_IMMUTABLE_FL;
+
+	if (copy_to_user(arg, &flags, sizeof(flags)))
+		return -EFAULT;
+	return 0;
+}
+
+static int
+efivarfs_ioc_setxflags(struct file *file, void __user *arg)
+{
+	struct inode *inode = file->f_mapping->host;
+	unsigned int flags;
+	unsigned int i_flags = 0;
+	int error;
+
+	if (!inode_owner_or_capable(inode))
+		return -EACCES;
+
+	if (copy_from_user(&flags, arg, sizeof(flags)))
+		return -EFAULT;
+
+	if (flags & ~FS_IMMUTABLE_FL)
+		return -EOPNOTSUPP;
+
+	if (!capable(CAP_LINUX_IMMUTABLE))
+		return -EPERM;
+
+	if (flags & FS_IMMUTABLE_FL)
+		i_flags |= S_IMMUTABLE;
+
+
+	error = mnt_want_write_file(file);
+	if (error)
+		return error;
+
+	mutex_lock(&inode->i_mutex);
+	inode_set_flags(inode, i_flags, S_IMMUTABLE);
+	mutex_unlock(&inode->i_mutex);
+
+	mnt_drop_write_file(file);
+
+	return 0;
+}
+
+long
+efivarfs_file_ioctl(struct file *file, unsigned int cmd, unsigned long p)
+{
+	void __user *arg = (void __user *)p;
+
+	switch (cmd) {
+	case FS_IOC_GETFLAGS:
+		return efivarfs_ioc_getxflags(file, arg);
+	case FS_IOC_SETFLAGS:
+		return efivarfs_ioc_setxflags(file, arg);
+	}
+
+	return -ENOTTY;
+}
+
 const struct file_operations efivarfs_file_operations = {
 	.open	= simple_open,
 	.read	= efivarfs_file_read,
 	.write	= efivarfs_file_write,
 	.llseek	= no_llseek,
+	.unlocked_ioctl = efivarfs_file_ioctl,
 };
--- zfcpdump-kernel-4.4.orig/fs/efivarfs/inode.c
+++ zfcpdump-kernel-4.4/fs/efivarfs/inode.c
@@ -15,7 +15,8 @@
 #include "internal.h"
 
 struct inode *efivarfs_get_inode(struct super_block *sb,
-				const struct inode *dir, int mode, dev_t dev)
+				const struct inode *dir, int mode,
+				dev_t dev, bool is_removable)
 {
 	struct inode *inode = new_inode(sb);
 
@@ -23,6 +24,7 @@ struct inode *efivarfs_get_inode(struct
 		inode->i_ino = get_next_ino();
 		inode->i_mode = mode;
 		inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
+		inode->i_flags = is_removable ? 0 : S_IMMUTABLE;
 		switch (mode & S_IFMT) {
 		case S_IFREG:
 			inode->i_fop = &efivarfs_file_operations;
@@ -102,22 +104,17 @@ static void efivarfs_hex_to_guid(const c
 static int efivarfs_create(struct inode *dir, struct dentry *dentry,
 			  umode_t mode, bool excl)
 {
-	struct inode *inode;
+	struct inode *inode = NULL;
 	struct efivar_entry *var;
 	int namelen, i = 0, err = 0;
+	bool is_removable = false;
 
 	if (!efivarfs_valid_name(dentry->d_name.name, dentry->d_name.len))
 		return -EINVAL;
 
-	inode = efivarfs_get_inode(dir->i_sb, dir, mode, 0);
-	if (!inode)
-		return -ENOMEM;
-
 	var = kzalloc(sizeof(struct efivar_entry), GFP_KERNEL);
-	if (!var) {
-		err = -ENOMEM;
-		goto out;
-	}
+	if (!var)
+		return -ENOMEM;
 
 	/* length of the variable name itself: remove GUID and separator */
 	namelen = dentry->d_name.len - EFI_VARIABLE_GUID_LEN - 1;
@@ -125,6 +122,16 @@ static int efivarfs_create(struct inode
 	efivarfs_hex_to_guid(dentry->d_name.name + namelen + 1,
 			&var->var.VendorGuid);
 
+	if (efivar_variable_is_removable(var->var.VendorGuid,
+					 dentry->d_name.name, namelen))
+		is_removable = true;
+
+	inode = efivarfs_get_inode(dir->i_sb, dir, mode, 0, is_removable);
+	if (!inode) {
+		err = -ENOMEM;
+		goto out;
+	}
+
 	for (i = 0; i < namelen; i++)
 		var->var.VariableName[i] = dentry->d_name.name[i];
 
@@ -138,7 +145,8 @@ static int efivarfs_create(struct inode
 out:
 	if (err) {
 		kfree(var);
-		iput(inode);
+		if (inode)
+			iput(inode);
 	}
 	return err;
 }
--- zfcpdump-kernel-4.4.orig/fs/efivarfs/internal.h
+++ zfcpdump-kernel-4.4/fs/efivarfs/internal.h
@@ -15,7 +15,8 @@ extern const struct file_operations efiv
 extern const struct inode_operations efivarfs_dir_inode_operations;
 extern bool efivarfs_valid_name(const char *str, int len);
 extern struct inode *efivarfs_get_inode(struct super_block *sb,
-			const struct inode *dir, int mode, dev_t dev);
+			const struct inode *dir, int mode, dev_t dev,
+			bool is_removable);
 
 extern struct list_head efivarfs_list;
 
--- zfcpdump-kernel-4.4.orig/fs/efivarfs/super.c
+++ zfcpdump-kernel-4.4/fs/efivarfs/super.c
@@ -118,8 +118,9 @@ static int efivarfs_callback(efi_char16_
 	struct dentry *dentry, *root = sb->s_root;
 	unsigned long size = 0;
 	char *name;
-	int len, i;
+	int len;
 	int err = -ENOMEM;
+	bool is_removable = false;
 
 	entry = kzalloc(sizeof(*entry), GFP_KERNEL);
 	if (!entry)
@@ -128,15 +129,17 @@ static int efivarfs_callback(efi_char16_
 	memcpy(entry->var.VariableName, name16, name_size);
 	memcpy(&(entry->var.VendorGuid), &vendor, sizeof(efi_guid_t));
 
-	len = ucs2_strlen(entry->var.VariableName);
+	len = ucs2_utf8size(entry->var.VariableName);
 
 	/* name, plus '-', plus GUID, plus NUL*/
 	name = kmalloc(len + 1 + EFI_VARIABLE_GUID_LEN + 1, GFP_KERNEL);
 	if (!name)
 		goto fail;
 
-	for (i = 0; i < len; i++)
-		name[i] = entry->var.VariableName[i] & 0xFF;
+	ucs2_as_utf8(name, entry->var.VariableName, len);
+
+	if (efivar_variable_is_removable(entry->var.VendorGuid, name, len))
+		is_removable = true;
 
 	name[len] = '-';
 
@@ -144,7 +147,8 @@ static int efivarfs_callback(efi_char16_
 
 	name[len + EFI_VARIABLE_GUID_LEN+1] = '\0';
 
-	inode = efivarfs_get_inode(sb, d_inode(root), S_IFREG | 0644, 0);
+	inode = efivarfs_get_inode(sb, d_inode(root), S_IFREG | 0644, 0,
+				   is_removable);
 	if (!inode)
 		goto fail_name;
 
@@ -200,7 +204,7 @@ static int efivarfs_fill_super(struct su
 	sb->s_d_op		= &efivarfs_d_ops;
 	sb->s_time_gran         = 1;
 
-	inode = efivarfs_get_inode(sb, NULL, S_IFDIR | 0755, 0);
+	inode = efivarfs_get_inode(sb, NULL, S_IFDIR | 0755, 0, true);
 	if (!inode)
 		return -ENOMEM;
 	inode->i_op = &efivarfs_dir_inode_operations;
--- zfcpdump-kernel-4.4.orig/fs/exec.c
+++ zfcpdump-kernel-4.4/fs/exec.c
@@ -57,6 +57,8 @@
 #include <linux/oom.h>
 #include <linux/compat.h>
 
+#include <trace/events/fs.h>
+
 #include <asm/uaccess.h>
 #include <asm/mmu_context.h>
 #include <asm/tlb.h>
@@ -103,6 +105,14 @@ bool path_noexec(const struct path *path
 	return (path->mnt->mnt_flags & MNT_NOEXEC) ||
 	       (path->mnt->mnt_sb->s_iflags & SB_I_NOEXEC);
 }
+EXPORT_SYMBOL(path_noexec);
+
+bool path_nosuid(const struct path *path)
+{
+	return !mnt_may_suid(path->mnt) ||
+	       (path->mnt->mnt_sb->s_iflags & SB_I_NOSUID);
+}
+EXPORT_SYMBOL(path_nosuid);
 
 #ifdef CONFIG_USELIB
 /*
@@ -793,6 +803,8 @@ static struct file *do_open_execat(int f
 	if (name->name[0] != '\0')
 		fsnotify_open(file);
 
+	trace_open_exec(name->name);
+
 out:
 	return file;
 
@@ -1295,7 +1307,7 @@ static void bprm_fill_uid(struct linux_b
 	bprm->cred->euid = current_euid();
 	bprm->cred->egid = current_egid();
 
-	if (bprm->file->f_path.mnt->mnt_flags & MNT_NOSUID)
+	if (path_nosuid(&bprm->file->f_path))
 		return;
 
 	if (task_no_new_privs(current))
--- zfcpdump-kernel-4.4.orig/fs/ext4/acl.c
+++ zfcpdump-kernel-4.4/fs/ext4/acl.c
@@ -13,7 +13,7 @@
  * Convert from filesystem to in-memory representation.
  */
 static struct posix_acl *
-ext4_acl_from_disk(const void *value, size_t size)
+ext4_acl_from_disk(struct super_block *sb, const void *value, size_t size)
 {
 	const char *end = (char *)value + size;
 	int n, count;
@@ -57,16 +57,20 @@ ext4_acl_from_disk(const void *value, si
 			if ((char *)value > end)
 				goto fail;
 			acl->a_entries[n].e_uid =
-				make_kuid(&init_user_ns,
+				make_kuid(sb->s_user_ns,
 					  le32_to_cpu(entry->e_id));
+			if (!uid_valid(acl->a_entries[n].e_uid))
+				goto fail;
 			break;
 		case ACL_GROUP:
 			value = (char *)value + sizeof(ext4_acl_entry);
 			if ((char *)value > end)
 				goto fail;
 			acl->a_entries[n].e_gid =
-				make_kgid(&init_user_ns,
+				make_kgid(sb->s_user_ns,
 					  le32_to_cpu(entry->e_id));
+			if (!gid_valid(acl->a_entries[n].e_gid))
+				goto fail;
 			break;
 
 		default:
@@ -86,11 +90,14 @@ fail:
  * Convert from in-memory to filesystem representation.
  */
 static void *
-ext4_acl_to_disk(const struct posix_acl *acl, size_t *size)
+ext4_acl_to_disk(struct super_block *sb, const struct posix_acl *acl,
+		 size_t *size)
 {
 	ext4_acl_header *ext_acl;
 	char *e;
 	size_t n;
+	uid_t uid;
+	gid_t gid;
 
 	*size = ext4_acl_size(acl->a_count);
 	ext_acl = kmalloc(sizeof(ext4_acl_header) + acl->a_count *
@@ -106,13 +113,17 @@ ext4_acl_to_disk(const struct posix_acl
 		entry->e_perm = cpu_to_le16(acl_e->e_perm);
 		switch (acl_e->e_tag) {
 		case ACL_USER:
-			entry->e_id = cpu_to_le32(
-				from_kuid(&init_user_ns, acl_e->e_uid));
+			uid = from_kuid(sb->s_user_ns, acl_e->e_uid);
+			if (uid == (uid_t)-1)
+				goto fail;
+			entry->e_id = cpu_to_le32(uid);
 			e += sizeof(ext4_acl_entry);
 			break;
 		case ACL_GROUP:
-			entry->e_id = cpu_to_le32(
-				from_kgid(&init_user_ns, acl_e->e_gid));
+			gid = from_kgid(sb->s_user_ns, acl_e->e_gid);
+			if (gid == (gid_t)-1)
+				goto fail;
+			entry->e_id = cpu_to_le32(gid);
 			e += sizeof(ext4_acl_entry);
 			break;
 
@@ -165,7 +176,7 @@ ext4_get_acl(struct inode *inode, int ty
 		retval = ext4_xattr_get(inode, name_index, "", value, retval);
 	}
 	if (retval > 0)
-		acl = ext4_acl_from_disk(value, retval);
+		acl = ext4_acl_from_disk(inode->i_sb, value, retval);
 	else if (retval == -ENODATA || retval == -ENOSYS)
 		acl = NULL;
 	else
@@ -218,7 +229,7 @@ __ext4_set_acl(handle_t *handle, struct
 		return -EINVAL;
 	}
 	if (acl) {
-		value = ext4_acl_to_disk(acl, &size);
+		value = ext4_acl_to_disk(inode->i_sb, acl, &size);
 		if (IS_ERR(value))
 			return (int)PTR_ERR(value);
 	}
--- zfcpdump-kernel-4.4.orig/fs/ext4/balloc.c
+++ zfcpdump-kernel-4.4/fs/ext4/balloc.c
@@ -191,7 +191,6 @@ static int ext4_init_block_bitmap(struct
 	/* If checksum is bad mark all blocks used to prevent allocation
 	 * essentially implementing a per-group read-only flag. */
 	if (!ext4_group_desc_csum_verify(sb, block_group, gdp)) {
-		ext4_error(sb, "Checksum bad for group %u", block_group);
 		grp = ext4_get_group_info(sb, block_group);
 		if (!EXT4_MB_GRP_BBITMAP_CORRUPT(grp))
 			percpu_counter_sub(&sbi->s_freeclusters_counter,
@@ -209,6 +208,9 @@ static int ext4_init_block_bitmap(struct
 	memset(bh->b_data, 0, sb->s_blocksize);
 
 	bit_max = ext4_num_base_meta_clusters(sb, block_group);
+	if ((bit_max >> 3) >= bh->b_size)
+		return -EFSCORRUPTED;
+
 	for (bit = 0; bit < bit_max; bit++)
 		ext4_set_bit(bit, bh->b_data);
 
@@ -442,14 +444,16 @@ ext4_read_block_bitmap_nowait(struct sup
 	}
 	ext4_lock_group(sb, block_group);
 	if (desc->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)) {
-
 		err = ext4_init_block_bitmap(sb, bh, block_group, desc);
 		set_bitmap_uptodate(bh);
 		set_buffer_uptodate(bh);
 		ext4_unlock_group(sb, block_group);
 		unlock_buffer(bh);
-		if (err)
+		if (err) {
+			ext4_error(sb, "Failed to init block bitmap for group "
+				   "%u: %d", block_group, err);
 			goto out;
+		}
 		goto verify;
 	}
 	ext4_unlock_group(sb, block_group);
@@ -561,8 +565,8 @@ static int ext4_has_free_clusters(struct
 
 	/* Hm, nope.  Are (enough) root reserved clusters available? */
 	if (uid_eq(sbi->s_resuid, current_fsuid()) ||
-	    (!gid_eq(sbi->s_resgid, GLOBAL_ROOT_GID) && in_group_p(sbi->s_resgid)) ||
-	    capable(CAP_SYS_RESOURCE) ||
+	    (!gid_eq(sbi->s_resgid, make_kgid(sbi->s_sb->s_user_ns, 0)) && in_group_p(sbi->s_resgid)) ||
+	    ns_capable(sbi->s_sb->s_user_ns, CAP_SYS_RESOURCE) ||
 	    (flags & EXT4_MB_USE_ROOT_BLOCKS)) {
 
 		if (free_clusters >= (nclusters + dirty_clusters +
--- zfcpdump-kernel-4.4.orig/fs/ext4/crypto_key.c
+++ zfcpdump-kernel-4.4/fs/ext4/crypto_key.c
@@ -213,9 +213,11 @@ retry:
 		res = -ENOKEY;
 		goto out;
 	}
+	down_read(&keyring_key->sem);
 	ukp = user_key_payload(keyring_key);
 	if (ukp->datalen != sizeof(struct ext4_encryption_key)) {
 		res = -EINVAL;
+		up_read(&keyring_key->sem);
 		goto out;
 	}
 	master_key = (struct ext4_encryption_key *)ukp->data;
@@ -226,10 +228,12 @@ retry:
 			    "ext4: key size incorrect: %d\n",
 			    master_key->size);
 		res = -ENOKEY;
+		up_read(&keyring_key->sem);
 		goto out;
 	}
 	res = ext4_derive_key_aes(ctx.nonce, master_key->raw,
 				  raw_key);
+	up_read(&keyring_key->sem);
 	if (res)
 		goto out;
 got_key:
--- zfcpdump-kernel-4.4.orig/fs/ext4/crypto_policy.c
+++ zfcpdump-kernel-4.4/fs/ext4/crypto_policy.c
@@ -102,6 +102,9 @@ static int ext4_create_encryption_contex
 int ext4_process_policy(const struct ext4_encryption_policy *policy,
 			struct inode *inode)
 {
+	if (!inode_owner_or_capable(inode))
+		return -EACCES;
+
 	if (policy->version != 0)
 		return -EINVAL;
 
--- zfcpdump-kernel-4.4.orig/fs/ext4/ext4.h
+++ zfcpdump-kernel-4.4/fs/ext4/ext4.h
@@ -850,6 +850,29 @@ do {									       \
 #include "extents_status.h"
 
 /*
+ * Lock subclasses for i_data_sem in the ext4_inode_info structure.
+ *
+ * These are needed to avoid lockdep false positives when we need to
+ * allocate blocks to the quota inode during ext4_map_blocks(), while
+ * holding i_data_sem for a normal (non-quota) inode.  Since we don't
+ * do quota tracking for the quota inode, this avoids deadlock (as
+ * well as infinite recursion, since it isn't turtles all the way
+ * down...)
+ *
+ *  I_DATA_SEM_NORMAL - Used for most inodes
+ *  I_DATA_SEM_OTHER  - Used by move_inode.c for the second normal inode
+ *			  where the second inode has larger inode number
+ *			  than the first
+ *  I_DATA_SEM_QUOTA  - Used for quota inodes only
+ */
+enum {
+	I_DATA_SEM_NORMAL = 0,
+	I_DATA_SEM_OTHER,
+	I_DATA_SEM_QUOTA,
+};
+
+
+/*
  * fourth extended file system inode data in memory
  */
 struct ext4_inode_info {
@@ -910,6 +933,15 @@ struct ext4_inode_info {
 	 * by other means, so we have i_data_sem.
 	 */
 	struct rw_semaphore i_data_sem;
+	/*
+	 * i_mmap_sem is for serializing page faults with truncate / punch hole
+	 * operations. We have to make sure that new page cannot be faulted in
+	 * a section of the inode that is being punched. We cannot easily use
+	 * i_data_sem for this since we need protection for the whole punch
+	 * operation and i_data_sem ranks below transaction start so we have
+	 * to occasionally drop it.
+	 */
+	struct rw_semaphore i_mmap_sem;
 	struct inode vfs_inode;
 	struct jbd2_inode *jinode;
 
@@ -2484,9 +2516,13 @@ extern int ext4_chunk_trans_blocks(struc
 extern int ext4_zero_partial_blocks(handle_t *handle, struct inode *inode,
 			     loff_t lstart, loff_t lend);
 extern int ext4_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf);
+extern int ext4_filemap_fault(struct vm_area_struct *vma, struct vm_fault *vmf);
 extern qsize_t *ext4_get_reserved_space(struct inode *inode);
 extern void ext4_da_update_reserve_space(struct inode *inode,
 					int used, int quota_claim);
+extern int ext4_get_next_extent(struct inode *inode, ext4_lblk_t lblk,
+				unsigned int map_len,
+				struct extent_status *result);
 
 /* indirect.c */
 extern int ext4_ind_map_blocks(handle_t *handle, struct inode *inode,
@@ -2848,6 +2884,9 @@ static inline int ext4_update_inode_size
 	return changed;
 }
 
+int ext4_update_disksize_before_punch(struct inode *inode, loff_t offset,
+				      loff_t len);
+
 struct ext4_group_info {
 	unsigned long   bb_state;
 	struct rb_root  bb_free_root;
--- zfcpdump-kernel-4.4.orig/fs/ext4/extents.c
+++ zfcpdump-kernel-4.4/fs/ext4/extents.c
@@ -376,9 +376,13 @@ static int ext4_valid_extent(struct inod
 	ext4_fsblk_t block = ext4_ext_pblock(ext);
 	int len = ext4_ext_get_actual_len(ext);
 	ext4_lblk_t lblock = le32_to_cpu(ext->ee_block);
-	ext4_lblk_t last = lblock + len - 1;
 
-	if (len == 0 || lblock > last)
+	/*
+	 * We allow neither:
+	 *  - zero length
+	 *  - overflow/wrap-around
+	 */
+	if (lblock + len <= lblock)
 		return 0;
 	return ext4_data_block_valid(EXT4_SB(inode->i_sb), block, len);
 }
@@ -469,6 +473,10 @@ static int __ext4_ext_check(const char *
 		error_msg = "invalid extent entries";
 		goto corrupted;
 	}
+	if (unlikely(depth > 32)) {
+		error_msg = "too large eh_depth";
+		goto corrupted;
+	}
 	/* Verify checksum on non-root extent tree nodes */
 	if (ext_depth(inode) != depth &&
 	    !ext4_extent_block_csum_verify(inode, eh)) {
@@ -2293,59 +2301,69 @@ static int ext4_fill_fiemap_extents(stru
 }
 
 /*
- * ext4_ext_put_gap_in_cache:
- * calculate boundaries of the gap that the requested block fits into
- * and cache this gap
+ * ext4_ext_determine_hole - determine hole around given block
+ * @inode:	inode we lookup in
+ * @path:	path in extent tree to @lblk
+ * @lblk:	pointer to logical block around which we want to determine hole
+ *
+ * Determine hole length (and start if easily possible) around given logical
+ * block. We don't try too hard to find the beginning of the hole but @path
+ * actually points to extent before @lblk, we provide it.
+ *
+ * The function returns the length of a hole starting at @lblk. We update @lblk
+ * to the beginning of the hole if we managed to find it.
  */
-static void
-ext4_ext_put_gap_in_cache(struct inode *inode, struct ext4_ext_path *path,
-				ext4_lblk_t block)
+static ext4_lblk_t ext4_ext_determine_hole(struct inode *inode,
+					   struct ext4_ext_path *path,
+					   ext4_lblk_t *lblk)
 {
 	int depth = ext_depth(inode);
-	ext4_lblk_t len;
-	ext4_lblk_t lblock;
 	struct ext4_extent *ex;
-	struct extent_status es;
+	ext4_lblk_t len;
 
 	ex = path[depth].p_ext;
 	if (ex == NULL) {
 		/* there is no extent yet, so gap is [0;-] */
-		lblock = 0;
+		*lblk = 0;
 		len = EXT_MAX_BLOCKS;
-		ext_debug("cache gap(whole file):");
-	} else if (block < le32_to_cpu(ex->ee_block)) {
-		lblock = block;
-		len = le32_to_cpu(ex->ee_block) - block;
-		ext_debug("cache gap(before): %u [%u:%u]",
-				block,
-				le32_to_cpu(ex->ee_block),
-				 ext4_ext_get_actual_len(ex));
-	} else if (block >= le32_to_cpu(ex->ee_block)
+	} else if (*lblk < le32_to_cpu(ex->ee_block)) {
+		len = le32_to_cpu(ex->ee_block) - *lblk;
+	} else if (*lblk >= le32_to_cpu(ex->ee_block)
 			+ ext4_ext_get_actual_len(ex)) {
 		ext4_lblk_t next;
-		lblock = le32_to_cpu(ex->ee_block)
-			+ ext4_ext_get_actual_len(ex);
 
+		*lblk = le32_to_cpu(ex->ee_block) + ext4_ext_get_actual_len(ex);
 		next = ext4_ext_next_allocated_block(path);
-		ext_debug("cache gap(after): [%u:%u] %u",
-				le32_to_cpu(ex->ee_block),
-				ext4_ext_get_actual_len(ex),
-				block);
-		BUG_ON(next == lblock);
-		len = next - lblock;
+		BUG_ON(next == *lblk);
+		len = next - *lblk;
 	} else {
 		BUG();
 	}
+	return len;
+}
 
-	ext4_es_find_delayed_extent_range(inode, lblock, lblock + len - 1, &es);
+/*
+ * ext4_ext_put_gap_in_cache:
+ * calculate boundaries of the gap that the requested block fits into
+ * and cache this gap
+ */
+static void
+ext4_ext_put_gap_in_cache(struct inode *inode, ext4_lblk_t hole_start,
+			  ext4_lblk_t hole_len)
+{
+	struct extent_status es;
+
+	ext4_es_find_delayed_extent_range(inode, hole_start,
+					  hole_start + hole_len - 1, &es);
 	if (es.es_len) {
 		/* There's delayed extent containing lblock? */
-		if (es.es_lblk <= lblock)
+		if (es.es_lblk <= hole_start)
 			return;
-		len = min(es.es_lblk - lblock, len);
+		hole_len = min(es.es_lblk - hole_start, hole_len);
 	}
-	ext_debug(" -> %u:%u\n", lblock, len);
-	ext4_es_insert_extent(inode, lblock, len, ~0, EXTENT_STATUS_HOLE);
+	ext_debug(" -> %u:%u\n", hole_start, hole_len);
+	ext4_es_insert_extent(inode, hole_start, hole_len, ~0,
+			      EXTENT_STATUS_HOLE);
 }
 
 /*
@@ -4368,11 +4386,22 @@ int ext4_ext_map_blocks(handle_t *handle
 	 * we couldn't try to create block if create flag is zero
 	 */
 	if ((flags & EXT4_GET_BLOCKS_CREATE) == 0) {
+		ext4_lblk_t hole_start, hole_len;
+
+		hole_start = map->m_lblk;
+		hole_len = ext4_ext_determine_hole(inode, path, &hole_start);
 		/*
 		 * put just found gap into cache to speed up
 		 * subsequent requests
 		 */
-		ext4_ext_put_gap_in_cache(inode, path, map->m_lblk);
+		ext4_ext_put_gap_in_cache(inode, hole_start, hole_len);
+
+		/* Update hole_len to reflect hole size after map->m_lblk */
+		if (hole_start != map->m_lblk)
+			hole_len -= map->m_lblk - hole_start;
+		map->m_pblk = 0;
+		map->m_len = min_t(unsigned int, map->m_len, hole_len);
+
 		goto out2;
 	}
 
@@ -4685,10 +4714,6 @@ static int ext4_alloc_file_blocks(struct
 	if (len <= EXT_UNWRITTEN_MAX_LEN)
 		flags |= EXT4_GET_BLOCKS_NO_NORMALIZE;
 
-	/* Wait all existing dio workers, newcomers will block on i_mutex */
-	ext4_inode_block_unlocked_dio(inode);
-	inode_dio_wait(inode);
-
 	/*
 	 * credits to insert 1 extent into extent tree
 	 */
@@ -4752,8 +4777,6 @@ retry:
 		goto retry;
 	}
 
-	ext4_inode_resume_unlocked_dio(inode);
-
 	return ret > 0 ? ret2 : ret;
 }
 
@@ -4770,7 +4793,6 @@ static long ext4_zero_range(struct file
 	int partial_begin, partial_end;
 	loff_t start, end;
 	ext4_lblk_t lblk;
-	struct address_space *mapping = inode->i_mapping;
 	unsigned int blkbits = inode->i_blkbits;
 
 	trace_ext4_zero_range(inode, offset, len, mode);
@@ -4786,17 +4808,6 @@ static long ext4_zero_range(struct file
 	}
 
 	/*
-	 * Write out all dirty pages to avoid race conditions
-	 * Then release them.
-	 */
-	if (mapping->nrpages && mapping_tagged(mapping, PAGECACHE_TAG_DIRTY)) {
-		ret = filemap_write_and_wait_range(mapping, offset,
-						   offset + len - 1);
-		if (ret)
-			return ret;
-	}
-
-	/*
 	 * Round up offset. This is not fallocate, we neet to zero out
 	 * blocks, so convert interior block aligned part of the range to
 	 * unwritten and possibly manually zero out unaligned parts of the
@@ -4839,6 +4850,10 @@ static long ext4_zero_range(struct file
 	if (mode & FALLOC_FL_KEEP_SIZE)
 		flags |= EXT4_GET_BLOCKS_KEEP_SIZE;
 
+	/* Wait all existing dio workers, newcomers will block on i_mutex */
+	ext4_inode_block_unlocked_dio(inode);
+	inode_dio_wait(inode);
+
 	/* Preallocate the range including the unaligned edges */
 	if (partial_begin || partial_end) {
 		ret = ext4_alloc_file_blocks(file,
@@ -4847,7 +4862,7 @@ static long ext4_zero_range(struct file
 				 round_down(offset, 1 << blkbits)) >> blkbits,
 				new_size, flags, mode);
 		if (ret)
-			goto out_mutex;
+			goto out_dio;
 
 	}
 
@@ -4856,16 +4871,23 @@ static long ext4_zero_range(struct file
 		flags |= (EXT4_GET_BLOCKS_CONVERT_UNWRITTEN |
 			  EXT4_EX_NOCACHE);
 
-		/* Now release the pages and zero block aligned part of pages*/
+		/*
+		 * Prevent page faults from reinstantiating pages we have
+		 * released from page cache.
+		 */
+		down_write(&EXT4_I(inode)->i_mmap_sem);
+		ret = ext4_update_disksize_before_punch(inode, offset, len);
+		if (ret) {
+			up_write(&EXT4_I(inode)->i_mmap_sem);
+			goto out_dio;
+		}
+		/* Now release the pages and zero block aligned part of pages */
 		truncate_pagecache_range(inode, start, end - 1);
 		inode->i_mtime = inode->i_ctime = ext4_current_time(inode);
 
-		/* Wait all existing dio workers, newcomers will block on i_mutex */
-		ext4_inode_block_unlocked_dio(inode);
-		inode_dio_wait(inode);
-
 		ret = ext4_alloc_file_blocks(file, lblk, max_blocks, new_size,
 					     flags, mode);
+		up_write(&EXT4_I(inode)->i_mmap_sem);
 		if (ret)
 			goto out_dio;
 	}
@@ -4998,8 +5020,13 @@ long ext4_fallocate(struct file *file, i
 			goto out;
 	}
 
+	/* Wait all existing dio workers, newcomers will block on i_mutex */
+	ext4_inode_block_unlocked_dio(inode);
+	inode_dio_wait(inode);
+
 	ret = ext4_alloc_file_blocks(file, lblk, max_blocks, new_size,
 				     flags, mode);
+	ext4_inode_resume_unlocked_dio(inode);
 	if (ret)
 		goto out;
 
@@ -5494,21 +5521,7 @@ int ext4_collapse_range(struct inode *in
 			return ret;
 	}
 
-	/*
-	 * Need to round down offset to be aligned with page size boundary
-	 * for page size > block size.
-	 */
-	ioffset = round_down(offset, PAGE_SIZE);
-
-	/* Write out all dirty pages */
-	ret = filemap_write_and_wait_range(inode->i_mapping, ioffset,
-					   LLONG_MAX);
-	if (ret)
-		return ret;
-
-	/* Take mutex lock */
 	mutex_lock(&inode->i_mutex);
-
 	/*
 	 * There is no need to overlap collapse range with EOF, in which case
 	 * it is effectively a truncate operation
@@ -5524,17 +5537,43 @@ int ext4_collapse_range(struct inode *in
 		goto out_mutex;
 	}
 
-	truncate_pagecache(inode, ioffset);
-
 	/* Wait for existing dio to complete */
 	ext4_inode_block_unlocked_dio(inode);
 	inode_dio_wait(inode);
 
+	/*
+	 * Prevent page faults from reinstantiating pages we have released from
+	 * page cache.
+	 */
+	down_write(&EXT4_I(inode)->i_mmap_sem);
+	/*
+	 * Need to round down offset to be aligned with page size boundary
+	 * for page size > block size.
+	 */
+	ioffset = round_down(offset, PAGE_SIZE);
+	/*
+	 * Write tail of the last page before removed range since it will get
+	 * removed from the page cache below.
+	 */
+	ret = filemap_write_and_wait_range(inode->i_mapping, ioffset, offset);
+	if (ret)
+		goto out_mmap;
+	/*
+	 * Write data that will be shifted to preserve them when discarding
+	 * page cache below. We are also protected from pages becoming dirty
+	 * by i_mmap_sem.
+	 */
+	ret = filemap_write_and_wait_range(inode->i_mapping, offset + len,
+					   LLONG_MAX);
+	if (ret)
+		goto out_mmap;
+	truncate_pagecache(inode, ioffset);
+
 	credits = ext4_writepage_trans_blocks(inode);
 	handle = ext4_journal_start(inode, EXT4_HT_TRUNCATE, credits);
 	if (IS_ERR(handle)) {
 		ret = PTR_ERR(handle);
-		goto out_dio;
+		goto out_mmap;
 	}
 
 	down_write(&EXT4_I(inode)->i_data_sem);
@@ -5573,7 +5612,8 @@ int ext4_collapse_range(struct inode *in
 
 out_stop:
 	ext4_journal_stop(handle);
-out_dio:
+out_mmap:
+	up_write(&EXT4_I(inode)->i_mmap_sem);
 	ext4_inode_resume_unlocked_dio(inode);
 out_mutex:
 	mutex_unlock(&inode->i_mutex);
@@ -5627,21 +5667,7 @@ int ext4_insert_range(struct inode *inod
 			return ret;
 	}
 
-	/*
-	 * Need to round down to align start offset to page size boundary
-	 * for page size > block size.
-	 */
-	ioffset = round_down(offset, PAGE_SIZE);
-
-	/* Write out all dirty pages */
-	ret = filemap_write_and_wait_range(inode->i_mapping, ioffset,
-			LLONG_MAX);
-	if (ret)
-		return ret;
-
-	/* Take mutex lock */
 	mutex_lock(&inode->i_mutex);
-
 	/* Currently just for extent based files */
 	if (!ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)) {
 		ret = -EOPNOTSUPP;
@@ -5660,17 +5686,32 @@ int ext4_insert_range(struct inode *inod
 		goto out_mutex;
 	}
 
-	truncate_pagecache(inode, ioffset);
-
 	/* Wait for existing dio to complete */
 	ext4_inode_block_unlocked_dio(inode);
 	inode_dio_wait(inode);
 
+	/*
+	 * Prevent page faults from reinstantiating pages we have released from
+	 * page cache.
+	 */
+	down_write(&EXT4_I(inode)->i_mmap_sem);
+	/*
+	 * Need to round down to align start offset to page size boundary
+	 * for page size > block size.
+	 */
+	ioffset = round_down(offset, PAGE_SIZE);
+	/* Write out all dirty pages */
+	ret = filemap_write_and_wait_range(inode->i_mapping, ioffset,
+			LLONG_MAX);
+	if (ret)
+		goto out_mmap;
+	truncate_pagecache(inode, ioffset);
+
 	credits = ext4_writepage_trans_blocks(inode);
 	handle = ext4_journal_start(inode, EXT4_HT_TRUNCATE, credits);
 	if (IS_ERR(handle)) {
 		ret = PTR_ERR(handle);
-		goto out_dio;
+		goto out_mmap;
 	}
 
 	/* Expand file to avoid data loss if there is error while shifting */
@@ -5741,7 +5782,8 @@ int ext4_insert_range(struct inode *inod
 
 out_stop:
 	ext4_journal_stop(handle);
-out_dio:
+out_mmap:
+	up_write(&EXT4_I(inode)->i_mmap_sem);
 	ext4_inode_resume_unlocked_dio(inode);
 out_mutex:
 	mutex_unlock(&inode->i_mutex);
--- zfcpdump-kernel-4.4.orig/fs/ext4/file.c
+++ zfcpdump-kernel-4.4/fs/ext4/file.c
@@ -209,15 +209,18 @@ static int ext4_dax_fault(struct vm_area
 {
 	int result;
 	handle_t *handle = NULL;
-	struct super_block *sb = file_inode(vma->vm_file)->i_sb;
+	struct inode *inode = file_inode(vma->vm_file);
+	struct super_block *sb = inode->i_sb;
 	bool write = vmf->flags & FAULT_FLAG_WRITE;
 
 	if (write) {
 		sb_start_pagefault(sb);
 		file_update_time(vma->vm_file);
+		down_read(&EXT4_I(inode)->i_mmap_sem);
 		handle = ext4_journal_start_sb(sb, EXT4_HT_WRITE_PAGE,
 						EXT4_DATA_TRANS_BLOCKS(sb));
-	}
+	} else
+		down_read(&EXT4_I(inode)->i_mmap_sem);
 
 	if (IS_ERR(handle))
 		result = VM_FAULT_SIGBUS;
@@ -228,8 +231,10 @@ static int ext4_dax_fault(struct vm_area
 	if (write) {
 		if (!IS_ERR(handle))
 			ext4_journal_stop(handle);
+		up_read(&EXT4_I(inode)->i_mmap_sem);
 		sb_end_pagefault(sb);
-	}
+	} else
+		up_read(&EXT4_I(inode)->i_mmap_sem);
 
 	return result;
 }
@@ -246,10 +251,12 @@ static int ext4_dax_pmd_fault(struct vm_
 	if (write) {
 		sb_start_pagefault(sb);
 		file_update_time(vma->vm_file);
+		down_read(&EXT4_I(inode)->i_mmap_sem);
 		handle = ext4_journal_start_sb(sb, EXT4_HT_WRITE_PAGE,
 				ext4_chunk_trans_blocks(inode,
 							PMD_SIZE / PAGE_SIZE));
-	}
+	} else
+		down_read(&EXT4_I(inode)->i_mmap_sem);
 
 	if (IS_ERR(handle))
 		result = VM_FAULT_SIGBUS;
@@ -260,30 +267,71 @@ static int ext4_dax_pmd_fault(struct vm_
 	if (write) {
 		if (!IS_ERR(handle))
 			ext4_journal_stop(handle);
+		up_read(&EXT4_I(inode)->i_mmap_sem);
 		sb_end_pagefault(sb);
-	}
+	} else
+		up_read(&EXT4_I(inode)->i_mmap_sem);
 
 	return result;
 }
 
 static int ext4_dax_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
 {
-	return dax_mkwrite(vma, vmf, ext4_get_block_dax,
-				ext4_end_io_unwritten);
+	int err;
+	struct inode *inode = file_inode(vma->vm_file);
+
+	sb_start_pagefault(inode->i_sb);
+	file_update_time(vma->vm_file);
+	down_read(&EXT4_I(inode)->i_mmap_sem);
+	err = __dax_mkwrite(vma, vmf, ext4_get_block_dax,
+			    ext4_end_io_unwritten);
+	up_read(&EXT4_I(inode)->i_mmap_sem);
+	sb_end_pagefault(inode->i_sb);
+
+	return err;
+}
+
+/*
+ * Handle write fault for VM_MIXEDMAP mappings. Similarly to ext4_dax_mkwrite()
+ * handler we check for races agaist truncate. Note that since we cycle through
+ * i_mmap_sem, we are sure that also any hole punching that began before we
+ * were called is finished by now and so if it included part of the file we
+ * are working on, our pte will get unmapped and the check for pte_same() in
+ * wp_pfn_shared() fails. Thus fault gets retried and things work out as
+ * desired.
+ */
+static int ext4_dax_pfn_mkwrite(struct vm_area_struct *vma,
+				struct vm_fault *vmf)
+{
+	struct inode *inode = file_inode(vma->vm_file);
+	struct super_block *sb = inode->i_sb;
+	int ret = VM_FAULT_NOPAGE;
+	loff_t size;
+
+	sb_start_pagefault(sb);
+	file_update_time(vma->vm_file);
+	down_read(&EXT4_I(inode)->i_mmap_sem);
+	size = (i_size_read(inode) + PAGE_SIZE - 1) >> PAGE_SHIFT;
+	if (vmf->pgoff >= size)
+		ret = VM_FAULT_SIGBUS;
+	up_read(&EXT4_I(inode)->i_mmap_sem);
+	sb_end_pagefault(sb);
+
+	return ret;
 }
 
 static const struct vm_operations_struct ext4_dax_vm_ops = {
 	.fault		= ext4_dax_fault,
 	.pmd_fault	= ext4_dax_pmd_fault,
 	.page_mkwrite	= ext4_dax_mkwrite,
-	.pfn_mkwrite	= dax_pfn_mkwrite,
+	.pfn_mkwrite	= ext4_dax_pfn_mkwrite,
 };
 #else
 #define ext4_dax_vm_ops	ext4_file_vm_ops
 #endif
 
 static const struct vm_operations_struct ext4_file_vm_ops = {
-	.fault		= filemap_fault,
+	.fault		= ext4_filemap_fault,
 	.map_pages	= filemap_map_pages,
 	.page_mkwrite   = ext4_page_mkwrite,
 };
@@ -387,7 +435,7 @@ static int ext4_file_open(struct inode *
  */
 static int ext4_find_unwritten_pgoff(struct inode *inode,
 				     int whence,
-				     struct ext4_map_blocks *map,
+				     ext4_lblk_t end_blk,
 				     loff_t *offset)
 {
 	struct pagevec pvec;
@@ -402,7 +450,7 @@ static int ext4_find_unwritten_pgoff(str
 	blkbits = inode->i_sb->s_blocksize_bits;
 	startoff = *offset;
 	lastoff = startoff;
-	endoff = (loff_t)(map->m_lblk + map->m_len) << blkbits;
+	endoff = (loff_t)end_blk << blkbits;
 
 	index = startoff >> PAGE_CACHE_SHIFT;
 	end = endoff >> PAGE_CACHE_SHIFT;
@@ -520,12 +568,11 @@ out:
 static loff_t ext4_seek_data(struct file *file, loff_t offset, loff_t maxsize)
 {
 	struct inode *inode = file->f_mapping->host;
-	struct ext4_map_blocks map;
 	struct extent_status es;
 	ext4_lblk_t start, last, end;
 	loff_t dataoff, isize;
 	int blkbits;
-	int ret = 0;
+	int ret;
 
 	mutex_lock(&inode->i_mutex);
 
@@ -542,41 +589,32 @@ static loff_t ext4_seek_data(struct file
 	dataoff = offset;
 
 	do {
-		map.m_lblk = last;
-		map.m_len = end - last + 1;
-		ret = ext4_map_blocks(NULL, inode, &map, 0);
-		if (ret > 0 && !(map.m_flags & EXT4_MAP_UNWRITTEN)) {
-			if (last != start)
-				dataoff = (loff_t)last << blkbits;
-			break;
+		ret = ext4_get_next_extent(inode, last, end - last + 1, &es);
+		if (ret <= 0) {
+			/* No extent found -> no data */
+			if (ret == 0)
+				ret = -ENXIO;
+			mutex_unlock(&inode->i_mutex);
+			return ret;
 		}
 
-		/*
-		 * If there is a delay extent at this offset,
-		 * it will be as a data.
-		 */
-		ext4_es_find_delayed_extent_range(inode, last, last, &es);
-		if (es.es_len != 0 && in_range(last, es.es_lblk, es.es_len)) {
-			if (last != start)
-				dataoff = (loff_t)last << blkbits;
+		last = es.es_lblk;
+		if (last != start)
+			dataoff = (loff_t)last << blkbits;
+		if (!ext4_es_is_unwritten(&es))
 			break;
-		}
 
 		/*
 		 * If there is a unwritten extent at this offset,
 		 * it will be as a data or a hole according to page
 		 * cache that has data or not.
 		 */
-		if (map.m_flags & EXT4_MAP_UNWRITTEN) {
-			int unwritten;
-			unwritten = ext4_find_unwritten_pgoff(inode, SEEK_DATA,
-							      &map, &dataoff);
-			if (unwritten)
-				break;
-		}
-
-		last++;
+		if (ext4_find_unwritten_pgoff(inode, SEEK_DATA,
+					      es.es_lblk + es.es_len, &dataoff))
+			break;
+		last += es.es_len;
 		dataoff = (loff_t)last << blkbits;
+		cond_resched();
 	} while (last <= end);
 
 	mutex_unlock(&inode->i_mutex);
@@ -593,12 +631,11 @@ static loff_t ext4_seek_data(struct file
 static loff_t ext4_seek_hole(struct file *file, loff_t offset, loff_t maxsize)
 {
 	struct inode *inode = file->f_mapping->host;
-	struct ext4_map_blocks map;
 	struct extent_status es;
 	ext4_lblk_t start, last, end;
 	loff_t holeoff, isize;
 	int blkbits;
-	int ret = 0;
+	int ret;
 
 	mutex_lock(&inode->i_mutex);
 
@@ -615,44 +652,30 @@ static loff_t ext4_seek_hole(struct file
 	holeoff = offset;
 
 	do {
-		map.m_lblk = last;
-		map.m_len = end - last + 1;
-		ret = ext4_map_blocks(NULL, inode, &map, 0);
-		if (ret > 0 && !(map.m_flags & EXT4_MAP_UNWRITTEN)) {
-			last += ret;
-			holeoff = (loff_t)last << blkbits;
-			continue;
+		ret = ext4_get_next_extent(inode, last, end - last + 1, &es);
+		if (ret < 0) {
+			mutex_unlock(&inode->i_mutex);
+			return ret;
 		}
-
-		/*
-		 * If there is a delay extent at this offset,
-		 * we will skip this extent.
-		 */
-		ext4_es_find_delayed_extent_range(inode, last, last, &es);
-		if (es.es_len != 0 && in_range(last, es.es_lblk, es.es_len)) {
-			last = es.es_lblk + es.es_len;
-			holeoff = (loff_t)last << blkbits;
-			continue;
+		/* Found a hole? */
+		if (ret == 0 || es.es_lblk > last) {
+			if (last != start)
+				holeoff = (loff_t)last << blkbits;
+			break;
 		}
-
 		/*
 		 * If there is a unwritten extent at this offset,
 		 * it will be as a data or a hole according to page
 		 * cache that has data or not.
 		 */
-		if (map.m_flags & EXT4_MAP_UNWRITTEN) {
-			int unwritten;
-			unwritten = ext4_find_unwritten_pgoff(inode, SEEK_HOLE,
-							      &map, &holeoff);
-			if (!unwritten) {
-				last += ret;
-				holeoff = (loff_t)last << blkbits;
-				continue;
-			}
-		}
+		if (ext4_es_is_unwritten(&es) &&
+		    ext4_find_unwritten_pgoff(inode, SEEK_HOLE,
+					      last + es.es_len, &holeoff))
+			break;
 
-		/* find a hole */
-		break;
+		last += es.es_len;
+		holeoff = (loff_t)last << blkbits;
+		cond_resched();
 	} while (last <= end);
 
 	mutex_unlock(&inode->i_mutex);
--- zfcpdump-kernel-4.4.orig/fs/ext4/ialloc.c
+++ zfcpdump-kernel-4.4/fs/ext4/ialloc.c
@@ -76,7 +76,6 @@ static int ext4_init_inode_bitmap(struct
 	/* If checksum is bad mark all blocks and inodes use to prevent
 	 * allocation, essentially implementing a per-group read-only flag. */
 	if (!ext4_group_desc_csum_verify(sb, block_group, gdp)) {
-		ext4_error(sb, "Checksum bad for group %u", block_group);
 		grp = ext4_get_group_info(sb, block_group);
 		if (!EXT4_MB_GRP_BBITMAP_CORRUPT(grp))
 			percpu_counter_sub(&sbi->s_freeclusters_counter,
@@ -191,8 +190,11 @@ ext4_read_inode_bitmap(struct super_bloc
 		set_buffer_verified(bh);
 		ext4_unlock_group(sb, block_group);
 		unlock_buffer(bh);
-		if (err)
+		if (err) {
+			ext4_error(sb, "Failed to init inode bitmap for group "
+				   "%u: %d", block_group, err);
 			goto out;
+		}
 		return bh;
 	}
 	ext4_unlock_group(sb, block_group);
@@ -762,6 +764,10 @@ struct inode *__ext4_new_inode(handle_t
 	if (!dir || !dir->i_nlink)
 		return ERR_PTR(-EPERM);
 
+	/* Supplied owner must be valid */
+	if (owner && (owner[0] == (uid_t)-1 || owner[1] == (uid_t)-1))
+		return ERR_PTR(-EOVERFLOW);
+
 	if ((ext4_encrypted_inode(dir) ||
 	     DUMMY_ENCRYPTION_ENABLED(EXT4_SB(dir->i_sb))) &&
 	    (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode))) {
@@ -774,7 +780,6 @@ struct inode *__ext4_new_inode(handle_t
 			nblocks += EXT4_DATA_TRANS_BLOCKS(dir->i_sb);
 		encrypt = 1;
 	}
-
 	sb = dir->i_sb;
 	ngroups = ext4_get_groups_count(sb);
 	trace_ext4_request_inode(dir, mode);
@@ -1141,25 +1146,20 @@ struct inode *ext4_orphan_get(struct sup
 	unsigned long max_ino = le32_to_cpu(EXT4_SB(sb)->s_es->s_inodes_count);
 	ext4_group_t block_group;
 	int bit;
-	struct buffer_head *bitmap_bh;
+	struct buffer_head *bitmap_bh = NULL;
 	struct inode *inode = NULL;
-	long err = -EIO;
+	int err = -EFSCORRUPTED;
 
-	/* Error cases - e2fsck has already cleaned up for us */
-	if (ino > max_ino) {
-		ext4_warning(sb, "bad orphan ino %lu!  e2fsck was run?", ino);
-		err = -EFSCORRUPTED;
-		goto error;
-	}
+	if (ino < EXT4_FIRST_INO(sb) || ino > max_ino)
+		goto bad_orphan;
 
 	block_group = (ino - 1) / EXT4_INODES_PER_GROUP(sb);
 	bit = (ino - 1) % EXT4_INODES_PER_GROUP(sb);
 	bitmap_bh = ext4_read_inode_bitmap(sb, block_group);
 	if (IS_ERR(bitmap_bh)) {
-		err = PTR_ERR(bitmap_bh);
-		ext4_warning(sb, "inode bitmap error %ld for orphan %lu",
-			     ino, err);
-		goto error;
+		ext4_error(sb, "inode bitmap error %ld for orphan %lu",
+			   ino, PTR_ERR(bitmap_bh));
+		return (struct inode *) bitmap_bh;
 	}
 
 	/* Having the inode bit set should be a 100% indicator that this
@@ -1170,15 +1170,21 @@ struct inode *ext4_orphan_get(struct sup
 		goto bad_orphan;
 
 	inode = ext4_iget(sb, ino);
-	if (IS_ERR(inode))
-		goto iget_failed;
+	if (IS_ERR(inode)) {
+		err = PTR_ERR(inode);
+		ext4_error(sb, "couldn't read orphan inode %lu (err %d)",
+			   ino, err);
+		return inode;
+	}
 
 	/*
-	 * If the orphans has i_nlinks > 0 then it should be able to be
-	 * truncated, otherwise it won't be removed from the orphan list
-	 * during processing and an infinite loop will result.
+	 * If the orphans has i_nlinks > 0 then it should be able to
+	 * be truncated, otherwise it won't be removed from the orphan
+	 * list during processing and an infinite loop will result.
+	 * Similarly, it must not be a bad inode.
 	 */
-	if (inode->i_nlink && !ext4_can_truncate(inode))
+	if ((inode->i_nlink && !ext4_can_truncate(inode)) ||
+	    is_bad_inode(inode))
 		goto bad_orphan;
 
 	if (NEXT_ORPHAN(inode) > max_ino)
@@ -1186,29 +1192,25 @@ struct inode *ext4_orphan_get(struct sup
 	brelse(bitmap_bh);
 	return inode;
 
-iget_failed:
-	err = PTR_ERR(inode);
-	inode = NULL;
 bad_orphan:
-	ext4_warning(sb, "bad orphan inode %lu!  e2fsck was run?", ino);
-	printk(KERN_WARNING "ext4_test_bit(bit=%d, block=%llu) = %d\n",
-	       bit, (unsigned long long)bitmap_bh->b_blocknr,
-	       ext4_test_bit(bit, bitmap_bh->b_data));
-	printk(KERN_WARNING "inode=%p\n", inode);
+	ext4_error(sb, "bad orphan inode %lu", ino);
+	if (bitmap_bh)
+		printk(KERN_ERR "ext4_test_bit(bit=%d, block=%llu) = %d\n",
+		       bit, (unsigned long long)bitmap_bh->b_blocknr,
+		       ext4_test_bit(bit, bitmap_bh->b_data));
 	if (inode) {
-		printk(KERN_WARNING "is_bad_inode(inode)=%d\n",
+		printk(KERN_ERR "is_bad_inode(inode)=%d\n",
 		       is_bad_inode(inode));
-		printk(KERN_WARNING "NEXT_ORPHAN(inode)=%u\n",
+		printk(KERN_ERR "NEXT_ORPHAN(inode)=%u\n",
 		       NEXT_ORPHAN(inode));
-		printk(KERN_WARNING "max_ino=%lu\n", max_ino);
-		printk(KERN_WARNING "i_nlink=%u\n", inode->i_nlink);
+		printk(KERN_ERR "max_ino=%lu\n", max_ino);
+		printk(KERN_ERR "i_nlink=%u\n", inode->i_nlink);
 		/* Avoid freeing blocks if we got a bad deleted inode */
 		if (inode->i_nlink == 0)
 			inode->i_blocks = 0;
 		iput(inode);
 	}
 	brelse(bitmap_bh);
-error:
 	return ERR_PTR(err);
 }
 
--- zfcpdump-kernel-4.4.orig/fs/ext4/indirect.c
+++ zfcpdump-kernel-4.4/fs/ext4/indirect.c
@@ -555,8 +555,23 @@ int ext4_ind_map_blocks(handle_t *handle
 		goto got_it;
 	}
 
-	/* Next simple case - plain lookup or failed read of indirect block */
-	if ((flags & EXT4_GET_BLOCKS_CREATE) == 0 || err == -EIO)
+	/* Next simple case - plain lookup failed */
+	if ((flags & EXT4_GET_BLOCKS_CREATE) == 0) {
+		unsigned epb = inode->i_sb->s_blocksize / sizeof(u32);
+		int i;
+
+		/* Count number blocks in a subtree under 'partial' */
+		count = 1;
+		for (i = 0; partial + i != chain + depth - 1; i++)
+			count *= epb;
+		/* Fill in size of a hole we found */
+		map->m_pblk = 0;
+		map->m_len = min_t(unsigned int, map->m_len, count);
+		goto cleanup;
+	}
+
+	/* Failed read of indirect block */
+	if (err == -EIO)
 		goto cleanup;
 
 	/*
--- zfcpdump-kernel-4.4.orig/fs/ext4/inode.c
+++ zfcpdump-kernel-4.4/fs/ext4/inode.c
@@ -51,26 +51,32 @@ static __u32 ext4_inode_csum(struct inod
 			      struct ext4_inode_info *ei)
 {
 	struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
-	__u16 csum_lo;
-	__u16 csum_hi = 0;
 	__u32 csum;
+	__u16 dummy_csum = 0;
+	int offset = offsetof(struct ext4_inode, i_checksum_lo);
+	unsigned int csum_size = sizeof(dummy_csum);
+
+	csum = ext4_chksum(sbi, ei->i_csum_seed, (__u8 *)raw, offset);
+	csum = ext4_chksum(sbi, csum, (__u8 *)&dummy_csum, csum_size);
+	offset += csum_size;
+	csum = ext4_chksum(sbi, csum, (__u8 *)raw + offset,
+			   EXT4_GOOD_OLD_INODE_SIZE - offset);
 
-	csum_lo = le16_to_cpu(raw->i_checksum_lo);
-	raw->i_checksum_lo = 0;
-	if (EXT4_INODE_SIZE(inode->i_sb) > EXT4_GOOD_OLD_INODE_SIZE &&
-	    EXT4_FITS_IN_INODE(raw, ei, i_checksum_hi)) {
-		csum_hi = le16_to_cpu(raw->i_checksum_hi);
-		raw->i_checksum_hi = 0;
+	if (EXT4_INODE_SIZE(inode->i_sb) > EXT4_GOOD_OLD_INODE_SIZE) {
+		offset = offsetof(struct ext4_inode, i_checksum_hi);
+		csum = ext4_chksum(sbi, csum, (__u8 *)raw +
+				   EXT4_GOOD_OLD_INODE_SIZE,
+				   offset - EXT4_GOOD_OLD_INODE_SIZE);
+		if (EXT4_FITS_IN_INODE(raw, ei, i_checksum_hi)) {
+			csum = ext4_chksum(sbi, csum, (__u8 *)&dummy_csum,
+					   csum_size);
+			offset += csum_size;
+			csum = ext4_chksum(sbi, csum, (__u8 *)raw + offset,
+					   EXT4_INODE_SIZE(inode->i_sb) -
+					   offset);
+		}
 	}
 
-	csum = ext4_chksum(sbi, ei->i_csum_seed, (__u8 *)raw,
-			   EXT4_INODE_SIZE(inode->i_sb));
-
-	raw->i_checksum_lo = cpu_to_le16(csum_lo);
-	if (EXT4_INODE_SIZE(inode->i_sb) > EXT4_GOOD_OLD_INODE_SIZE &&
-	    EXT4_FITS_IN_INODE(raw, ei, i_checksum_hi))
-		raw->i_checksum_hi = cpu_to_le16(csum_hi);
-
 	return csum;
 }
 
@@ -205,9 +211,9 @@ void ext4_evict_inode(struct inode *inod
 		 * Note that directories do not have this problem because they
 		 * don't use page cache.
 		 */
-		if (ext4_should_journal_data(inode) &&
-		    (S_ISLNK(inode->i_mode) || S_ISREG(inode->i_mode)) &&
-		    inode->i_ino != EXT4_JOURNAL_INO) {
+		if (inode->i_ino != EXT4_JOURNAL_INO &&
+		    ext4_should_journal_data(inode) &&
+		    (S_ISLNK(inode->i_mode) || S_ISREG(inode->i_mode))) {
 			journal_t *journal = EXT4_SB(inode->i_sb)->s_journal;
 			tid_t commit_tid = EXT4_I(inode)->i_datasync_tid;
 
@@ -445,13 +451,13 @@ static void ext4_map_blocks_es_recheck(h
  * Otherwise, call with ext4_ind_map_blocks() to handle indirect mapping
  * based files
  *
- * On success, it returns the number of blocks being mapped or allocated.
- * if create==0 and the blocks are pre-allocated and unwritten block,
- * the result buffer head is unmapped. If the create ==1, it will make sure
- * the buffer head is mapped.
+ * On success, it returns the number of blocks being mapped or allocated.  if
+ * create==0 and the blocks are pre-allocated and unwritten, the resulting @map
+ * is marked as unwritten. If the create == 1, it will mark @map as mapped.
  *
  * It returns 0 if plain look up failed (blocks have not been allocated), in
- * that case, buffer head is unmapped
+ * that case, @map is returned as unmapped but we still do fill map->m_len to
+ * indicate the length of a hole starting at map->m_lblk.
  *
  * It returns the error in case of allocation failure.
  */
@@ -494,6 +500,11 @@ int ext4_map_blocks(handle_t *handle, st
 				retval = map->m_len;
 			map->m_len = retval;
 		} else if (ext4_es_is_delayed(&es) || ext4_es_is_hole(&es)) {
+			map->m_pblk = 0;
+			retval = es.es_len - (map->m_lblk - es.es_lblk);
+			if (retval > map->m_len)
+				retval = map->m_len;
+			map->m_len = retval;
 			retval = 0;
 		} else {
 			BUG_ON(1);
@@ -657,6 +668,34 @@ has_zeroout:
 	return retval;
 }
 
+/*
+ * Update EXT4_MAP_FLAGS in bh->b_state. For buffer heads attached to pages
+ * we have to be careful as someone else may be manipulating b_state as well.
+ */
+static void ext4_update_bh_state(struct buffer_head *bh, unsigned long flags)
+{
+	unsigned long old_state;
+	unsigned long new_state;
+
+	flags &= EXT4_MAP_FLAGS;
+
+	/* Dummy buffer_head? Set non-atomically. */
+	if (!bh->b_page) {
+		bh->b_state = (bh->b_state & ~EXT4_MAP_FLAGS) | flags;
+		return;
+	}
+	/*
+	 * Someone else may be modifying b_state. Be careful! This is ugly but
+	 * once we get rid of using bh as a container for mapping information
+	 * to pass to / from get_block functions, this can go away.
+	 */
+	do {
+		old_state = READ_ONCE(bh->b_state);
+		new_state = (old_state & ~EXT4_MAP_FLAGS) | flags;
+	} while (unlikely(
+		 cmpxchg(&bh->b_state, old_state, new_state) != old_state));
+}
+
 /* Maximum number of blocks we map for direct IO at once. */
 #define DIO_MAX_BLOCKS 4096
 
@@ -693,7 +732,7 @@ static int _ext4_get_block(struct inode
 		ext4_io_end_t *io_end = ext4_inode_aio(inode);
 
 		map_bh(bh, inode->i_sb, map.m_pblk);
-		bh->b_state = (bh->b_state & ~EXT4_MAP_FLAGS) | map.m_flags;
+		ext4_update_bh_state(bh, map.m_flags);
 		if (IS_DAX(inode) && buffer_unwritten(bh)) {
 			/*
 			 * dgc: I suspect unwritten conversion on ext4+DAX is
@@ -1669,7 +1708,7 @@ int ext4_da_get_block_prep(struct inode
 		return ret;
 
 	map_bh(bh, inode->i_sb, map.m_pblk);
-	bh->b_state = (bh->b_state & ~EXT4_MAP_FLAGS) | map.m_flags;
+	ext4_update_bh_state(bh, map.m_flags);
 
 	if (buffer_unwritten(bh)) {
 		/* A delayed write to unwritten bh should be marked
@@ -2561,13 +2600,36 @@ retry:
 				done = true;
 			}
 		}
-		ext4_journal_stop(handle);
+		/*
+		 * Caution: If the handle is synchronous,
+		 * ext4_journal_stop() can wait for transaction commit
+		 * to finish which may depend on writeback of pages to
+		 * complete or on page lock to be released.  In that
+		 * case, we have to wait until after after we have
+		 * submitted all the IO, released page locks we hold,
+		 * and dropped io_end reference (for extent conversion
+		 * to be able to complete) before stopping the handle.
+		 */
+		if (!ext4_handle_valid(handle) || handle->h_sync == 0) {
+			ext4_journal_stop(handle);
+			handle = NULL;
+		}
 		/* Submit prepared bio */
 		ext4_io_submit(&mpd.io_submit);
 		/* Unlock pages we didn't use */
 		mpage_release_unused_pages(&mpd, give_up_on_write);
-		/* Drop our io_end reference we got from init */
-		ext4_put_io_end(mpd.io_submit.io_end);
+		/*
+		 * Drop our io_end reference we got from init. We have
+		 * to be careful and use deferred io_end finishing if
+		 * we are still holding the transaction as we can
+		 * release the last reference to io_end which may end
+		 * up doing unwritten extent conversion.
+		 */
+		if (handle) {
+			ext4_put_io_end_defer(mpd.io_submit.io_end);
+			ext4_journal_stop(handle);
+		} else
+			ext4_put_io_end(mpd.io_submit.io_end);
 
 		if (ret == -ENOSPC && sbi->s_journal) {
 			/*
@@ -3559,6 +3621,35 @@ int ext4_can_truncate(struct inode *inod
 }
 
 /*
+ * We have to make sure i_disksize gets properly updated before we truncate
+ * page cache due to hole punching or zero range. Otherwise i_disksize update
+ * can get lost as it may have been postponed to submission of writeback but
+ * that will never happen after we truncate page cache.
+ */
+int ext4_update_disksize_before_punch(struct inode *inode, loff_t offset,
+				      loff_t len)
+{
+	handle_t *handle;
+	loff_t size = i_size_read(inode);
+
+	WARN_ON(!mutex_is_locked(&inode->i_mutex));
+	if (offset > size || offset + len < size)
+		return 0;
+
+	if (EXT4_I(inode)->i_disksize >= size)
+		return 0;
+
+	handle = ext4_journal_start(inode, EXT4_HT_MISC, 1);
+	if (IS_ERR(handle))
+		return PTR_ERR(handle);
+	ext4_update_i_disksize(inode, size);
+	ext4_mark_inode_dirty(handle, inode);
+	ext4_journal_stop(handle);
+
+	return 0;
+}
+
+/*
  * ext4_punch_hole: punches a hole in a file by releaseing the blocks
  * associated with the given offset and length
  *
@@ -3623,17 +3714,26 @@ int ext4_punch_hole(struct inode *inode,
 
 	}
 
+	/* Wait all existing dio workers, newcomers will block on i_mutex */
+	ext4_inode_block_unlocked_dio(inode);
+	inode_dio_wait(inode);
+
+	/*
+	 * Prevent page faults from reinstantiating pages we have released from
+	 * page cache.
+	 */
+	down_write(&EXT4_I(inode)->i_mmap_sem);
 	first_block_offset = round_up(offset, sb->s_blocksize);
 	last_block_offset = round_down((offset + length), sb->s_blocksize) - 1;
 
 	/* Now release the pages and zero block aligned part of pages*/
-	if (last_block_offset > first_block_offset)
+	if (last_block_offset > first_block_offset) {
+		ret = ext4_update_disksize_before_punch(inode, offset, length);
+		if (ret)
+			goto out_dio;
 		truncate_pagecache_range(inode, first_block_offset,
 					 last_block_offset);
-
-	/* Wait all existing dio workers, newcomers will block on i_mutex */
-	ext4_inode_block_unlocked_dio(inode);
-	inode_dio_wait(inode);
+	}
 
 	if (ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS))
 		credits = ext4_writepage_trans_blocks(inode);
@@ -3680,16 +3780,12 @@ int ext4_punch_hole(struct inode *inode,
 	if (IS_SYNC(inode))
 		ext4_handle_sync(handle);
 
-	/* Now release the pages again to reduce race window */
-	if (last_block_offset > first_block_offset)
-		truncate_pagecache_range(inode, first_block_offset,
-					 last_block_offset);
-
 	inode->i_mtime = inode->i_ctime = ext4_current_time(inode);
 	ext4_mark_inode_dirty(handle, inode);
 out_stop:
 	ext4_journal_stop(handle);
 out_dio:
+	up_write(&EXT4_I(inode)->i_mmap_sem);
 	ext4_inode_resume_unlocked_dio(inode);
 out_mutex:
 	mutex_unlock(&inode->i_mutex);
@@ -4823,6 +4919,7 @@ int ext4_setattr(struct dentry *dentry,
 			} else
 				ext4_wait_for_tail_page_commit(inode);
 		}
+		down_write(&EXT4_I(inode)->i_mmap_sem);
 		/*
 		 * Truncate pagecache after we've waited for commit
 		 * in data=journal mode to make pages freeable.
@@ -4830,6 +4927,7 @@ int ext4_setattr(struct dentry *dentry,
 		truncate_pagecache(inode, inode->i_size);
 		if (shrink)
 			ext4_truncate(inode);
+		up_write(&EXT4_I(inode)->i_mmap_sem);
 	}
 
 	if (!rc) {
@@ -5081,6 +5179,8 @@ int ext4_mark_inode_dirty(handle_t *hand
 	might_sleep();
 	trace_ext4_mark_inode_dirty(inode, _RET_IP_);
 	err = ext4_reserve_inode_write(handle, inode, &iloc);
+	if (err)
+		return err;
 	if (ext4_handle_valid(handle) &&
 	    EXT4_I(inode)->i_extra_isize < sbi->s_want_extra_isize &&
 	    !ext4_test_inode_state(inode, EXT4_STATE_NO_EXPAND)) {
@@ -5097,8 +5197,6 @@ int ext4_mark_inode_dirty(handle_t *hand
 						      sbi->s_want_extra_isize,
 						      iloc, handle);
 			if (ret) {
-				ext4_set_inode_state(inode,
-						     EXT4_STATE_NO_EXPAND);
 				if (mnt_count !=
 					le16_to_cpu(sbi->s_es->s_mnt_count)) {
 					ext4_warning(inode->i_sb,
@@ -5111,9 +5209,7 @@ int ext4_mark_inode_dirty(handle_t *hand
 			}
 		}
 	}
-	if (!err)
-		err = ext4_mark_iloc_dirty(handle, inode, &iloc);
-	return err;
+	return ext4_mark_iloc_dirty(handle, inode, &iloc);
 }
 
 /*
@@ -5278,6 +5374,8 @@ int ext4_page_mkwrite(struct vm_area_str
 
 	sb_start_pagefault(inode->i_sb);
 	file_update_time(vma->vm_file);
+
+	down_read(&EXT4_I(inode)->i_mmap_sem);
 	/* Delalloc case is easy... */
 	if (test_opt(inode->i_sb, DELALLOC) &&
 	    !ext4_should_journal_data(inode) &&
@@ -5347,6 +5445,87 @@ retry_alloc:
 out_ret:
 	ret = block_page_mkwrite_return(ret);
 out:
+	up_read(&EXT4_I(inode)->i_mmap_sem);
 	sb_end_pagefault(inode->i_sb);
 	return ret;
 }
+
+int ext4_filemap_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
+{
+	struct inode *inode = file_inode(vma->vm_file);
+	int err;
+
+	down_read(&EXT4_I(inode)->i_mmap_sem);
+	err = filemap_fault(vma, vmf);
+	up_read(&EXT4_I(inode)->i_mmap_sem);
+
+	return err;
+}
+
+/*
+ * Find the first extent at or after @lblk in an inode that is not a hole.
+ * Search for @map_len blocks at most. The extent is returned in @result.
+ *
+ * The function returns 1 if we found an extent. The function returns 0 in
+ * case there is no extent at or after @lblk and in that case also sets
+ * @result->es_len to 0. In case of error, the error code is returned.
+ */
+int ext4_get_next_extent(struct inode *inode, ext4_lblk_t lblk,
+			 unsigned int map_len, struct extent_status *result)
+{
+	struct ext4_map_blocks map;
+	struct extent_status es = {};
+	int ret;
+
+	map.m_lblk = lblk;
+	map.m_len = map_len;
+
+	/*
+	 * For non-extent based files this loop may iterate several times since
+	 * we do not determine full hole size.
+	 */
+	while (map.m_len > 0) {
+		ret = ext4_map_blocks(NULL, inode, &map, 0);
+		if (ret < 0)
+			return ret;
+		/* There's extent covering m_lblk? Just return it. */
+		if (ret > 0) {
+			int status;
+
+			ext4_es_store_pblock(result, map.m_pblk);
+			result->es_lblk = map.m_lblk;
+			result->es_len = map.m_len;
+			if (map.m_flags & EXT4_MAP_UNWRITTEN)
+				status = EXTENT_STATUS_UNWRITTEN;
+			else
+				status = EXTENT_STATUS_WRITTEN;
+			ext4_es_store_status(result, status);
+			return 1;
+		}
+		ext4_es_find_delayed_extent_range(inode, map.m_lblk,
+						  map.m_lblk + map.m_len - 1,
+						  &es);
+		/* Is delalloc data before next block in extent tree? */
+		if (es.es_len && es.es_lblk < map.m_lblk + map.m_len) {
+			ext4_lblk_t offset = 0;
+
+			if (es.es_lblk < lblk)
+				offset = lblk - es.es_lblk;
+			result->es_lblk = es.es_lblk + offset;
+			ext4_es_store_pblock(result,
+					     ext4_es_pblock(&es) + offset);
+			result->es_len = es.es_len - offset;
+			ext4_es_store_status(result, ext4_es_status(&es));
+
+			return 1;
+		}
+		/* There's a hole at m_lblk, advance us after it */
+		map.m_lblk += map.m_len;
+		map_len -= map.m_len;
+		map.m_len = map_len;
+		cond_resched();
+	}
+	result->es_len = 0;
+	return 0;
+}
+
--- zfcpdump-kernel-4.4.orig/fs/ext4/ioctl.c
+++ zfcpdump-kernel-4.4/fs/ext4/ioctl.c
@@ -253,7 +253,7 @@ long ext4_ioctl(struct file *filp, unsig
 		 * This test looks nicer. Thanks to Pauline Middelink
 		 */
 		if ((flags ^ oldflags) & (EXT4_APPEND_FL | EXT4_IMMUTABLE_FL)) {
-			if (!capable(CAP_LINUX_IMMUTABLE))
+			if (!ns_capable(sb->s_user_ns, CAP_LINUX_IMMUTABLE))
 				goto flags_out;
 		}
 
@@ -262,7 +262,7 @@ long ext4_ioctl(struct file *filp, unsig
 		 * the relevant capability.
 		 */
 		if ((jflag ^ oldflags) & (EXT4_JOURNAL_DATA_FL)) {
-			if (!capable(CAP_SYS_RESOURCE))
+			if (!ns_capable(sb->s_user_ns, CAP_SYS_RESOURCE))
 				goto flags_out;
 		}
 		if ((flags ^ oldflags) & EXT4_EXTENTS_FL)
@@ -593,7 +593,7 @@ resizefs_out:
 		struct fstrim_range range;
 		int ret = 0;
 
-		if (!capable(CAP_SYS_ADMIN))
+		if (!ns_capable(sb->s_user_ns, CAP_SYS_ADMIN))
 			return -EPERM;
 
 		if (!blk_queue_discard(q))
@@ -629,7 +629,13 @@ resizefs_out:
 			goto encryption_policy_out;
 		}
 
+		err = mnt_want_write_file(filp);
+		if (err)
+			goto encryption_policy_out;
+
 		err = ext4_process_policy(&policy, inode);
+
+		mnt_drop_write_file(filp);
 encryption_policy_out:
 		return err;
 #else
--- zfcpdump-kernel-4.4.orig/fs/ext4/mballoc.c
+++ zfcpdump-kernel-4.4/fs/ext4/mballoc.c
@@ -815,7 +815,7 @@ static void mb_regenerate_buddy(struct e
  * for this page; do not hold this lock when calling this routine!
  */
 
-static int ext4_mb_init_cache(struct page *page, char *incore)
+static int ext4_mb_init_cache(struct page *page, char *incore, gfp_t gfp)
 {
 	ext4_group_t ngroups;
 	int blocksize;
@@ -848,7 +848,7 @@ static int ext4_mb_init_cache(struct pag
 	/* allocate buffer_heads to read bitmaps */
 	if (groups_per_page > 1) {
 		i = sizeof(struct buffer_head *) * groups_per_page;
-		bh = kzalloc(i, GFP_NOFS);
+		bh = kzalloc(i, gfp);
 		if (bh == NULL) {
 			err = -ENOMEM;
 			goto out;
@@ -983,7 +983,7 @@ out:
  * are on the same page e4b->bd_buddy_page is NULL and return value is 0.
  */
 static int ext4_mb_get_buddy_page_lock(struct super_block *sb,
-		ext4_group_t group, struct ext4_buddy *e4b)
+		ext4_group_t group, struct ext4_buddy *e4b, gfp_t gfp)
 {
 	struct inode *inode = EXT4_SB(sb)->s_buddy_cache;
 	int block, pnum, poff;
@@ -1002,7 +1002,7 @@ static int ext4_mb_get_buddy_page_lock(s
 	block = group * 2;
 	pnum = block / blocks_per_page;
 	poff = block % blocks_per_page;
-	page = find_or_create_page(inode->i_mapping, pnum, GFP_NOFS);
+	page = find_or_create_page(inode->i_mapping, pnum, gfp);
 	if (!page)
 		return -ENOMEM;
 	BUG_ON(page->mapping != inode->i_mapping);
@@ -1016,7 +1016,7 @@ static int ext4_mb_get_buddy_page_lock(s
 
 	block++;
 	pnum = block / blocks_per_page;
-	page = find_or_create_page(inode->i_mapping, pnum, GFP_NOFS);
+	page = find_or_create_page(inode->i_mapping, pnum, gfp);
 	if (!page)
 		return -ENOMEM;
 	BUG_ON(page->mapping != inode->i_mapping);
@@ -1042,7 +1042,7 @@ static void ext4_mb_put_buddy_page_lock(
  * calling this routine!
  */
 static noinline_for_stack
-int ext4_mb_init_group(struct super_block *sb, ext4_group_t group)
+int ext4_mb_init_group(struct super_block *sb, ext4_group_t group, gfp_t gfp)
 {
 
 	struct ext4_group_info *this_grp;
@@ -1062,7 +1062,7 @@ int ext4_mb_init_group(struct super_bloc
 	 * The call to ext4_mb_get_buddy_page_lock will mark the
 	 * page accessed.
 	 */
-	ret = ext4_mb_get_buddy_page_lock(sb, group, &e4b);
+	ret = ext4_mb_get_buddy_page_lock(sb, group, &e4b, gfp);
 	if (ret || !EXT4_MB_GRP_NEED_INIT(this_grp)) {
 		/*
 		 * somebody initialized the group
@@ -1072,7 +1072,7 @@ int ext4_mb_init_group(struct super_bloc
 	}
 
 	page = e4b.bd_bitmap_page;
-	ret = ext4_mb_init_cache(page, NULL);
+	ret = ext4_mb_init_cache(page, NULL, gfp);
 	if (ret)
 		goto err;
 	if (!PageUptodate(page)) {
@@ -1091,7 +1091,7 @@ int ext4_mb_init_group(struct super_bloc
 	}
 	/* init buddy cache */
 	page = e4b.bd_buddy_page;
-	ret = ext4_mb_init_cache(page, e4b.bd_bitmap);
+	ret = ext4_mb_init_cache(page, e4b.bd_bitmap, gfp);
 	if (ret)
 		goto err;
 	if (!PageUptodate(page)) {
@@ -1109,8 +1109,8 @@ err:
  * calling this routine!
  */
 static noinline_for_stack int
-ext4_mb_load_buddy(struct super_block *sb, ext4_group_t group,
-					struct ext4_buddy *e4b)
+ext4_mb_load_buddy_gfp(struct super_block *sb, ext4_group_t group,
+		       struct ext4_buddy *e4b, gfp_t gfp)
 {
 	int blocks_per_page;
 	int block;
@@ -1140,7 +1140,7 @@ ext4_mb_load_buddy(struct super_block *s
 		 * we need full data about the group
 		 * to make a good selection
 		 */
-		ret = ext4_mb_init_group(sb, group);
+		ret = ext4_mb_init_group(sb, group, gfp);
 		if (ret)
 			return ret;
 	}
@@ -1168,11 +1168,11 @@ ext4_mb_load_buddy(struct super_block *s
 			 * wait for it to initialize.
 			 */
 			page_cache_release(page);
-		page = find_or_create_page(inode->i_mapping, pnum, GFP_NOFS);
+		page = find_or_create_page(inode->i_mapping, pnum, gfp);
 		if (page) {
 			BUG_ON(page->mapping != inode->i_mapping);
 			if (!PageUptodate(page)) {
-				ret = ext4_mb_init_cache(page, NULL);
+				ret = ext4_mb_init_cache(page, NULL, gfp);
 				if (ret) {
 					unlock_page(page);
 					goto err;
@@ -1204,11 +1204,12 @@ ext4_mb_load_buddy(struct super_block *s
 	if (page == NULL || !PageUptodate(page)) {
 		if (page)
 			page_cache_release(page);
-		page = find_or_create_page(inode->i_mapping, pnum, GFP_NOFS);
+		page = find_or_create_page(inode->i_mapping, pnum, gfp);
 		if (page) {
 			BUG_ON(page->mapping != inode->i_mapping);
 			if (!PageUptodate(page)) {
-				ret = ext4_mb_init_cache(page, e4b->bd_bitmap);
+				ret = ext4_mb_init_cache(page, e4b->bd_bitmap,
+							 gfp);
 				if (ret) {
 					unlock_page(page);
 					goto err;
@@ -1247,6 +1248,12 @@ err:
 	return ret;
 }
 
+static int ext4_mb_load_buddy(struct super_block *sb, ext4_group_t group,
+			      struct ext4_buddy *e4b)
+{
+	return ext4_mb_load_buddy_gfp(sb, group, e4b, GFP_NOFS);
+}
+
 static void ext4_mb_unload_buddy(struct ext4_buddy *e4b)
 {
 	if (e4b->bd_bitmap_page)
@@ -1259,6 +1266,7 @@ static void ext4_mb_unload_buddy(struct
 static int mb_find_order_for_block(struct ext4_buddy *e4b, int block)
 {
 	int order = 1;
+	int bb_incr = 1 << (e4b->bd_blkbits - 1);
 	void *bb;
 
 	BUG_ON(e4b->bd_bitmap == e4b->bd_buddy);
@@ -1271,7 +1279,8 @@ static int mb_find_order_for_block(struc
 			/* this block is part of buddy of order 'order' */
 			return order;
 		}
-		bb += 1 << (e4b->bd_blkbits - order);
+		bb += bb_incr;
+		bb_incr >>= 1;
 		order++;
 	}
 	return 0;
@@ -2045,7 +2054,7 @@ static int ext4_mb_good_group(struct ext
 
 	/* We only do this if the grp has never been initialized */
 	if (unlikely(EXT4_MB_GRP_NEED_INIT(grp))) {
-		int ret = ext4_mb_init_group(ac->ac_sb, group);
+		int ret = ext4_mb_init_group(ac->ac_sb, group, GFP_NOFS);
 		if (ret)
 			return ret;
 	}
@@ -2576,7 +2585,7 @@ int ext4_mb_init(struct super_block *sb)
 {
 	struct ext4_sb_info *sbi = EXT4_SB(sb);
 	unsigned i, j;
-	unsigned offset;
+	unsigned offset, offset_incr;
 	unsigned max;
 	int ret;
 
@@ -2605,11 +2614,13 @@ int ext4_mb_init(struct super_block *sb)
 
 	i = 1;
 	offset = 0;
+	offset_incr = 1 << (sb->s_blocksize_bits - 1);
 	max = sb->s_blocksize << 2;
 	do {
 		sbi->s_mb_offsets[i] = offset;
 		sbi->s_mb_maxs[i] = max;
-		offset += 1 << (sb->s_blocksize_bits - i);
+		offset += offset_incr;
+		offset_incr = offset_incr >> 1;
 		max = max >> 1;
 		i++;
 	} while (i <= sb->s_blocksize_bits + 1);
@@ -2928,7 +2939,7 @@ ext4_mb_mark_diskspace_used(struct ext4_
 		ext4_error(sb, "Allocating blocks %llu-%llu which overlap "
 			   "fs metadata", block, block+len);
 		/* File system mounted not to panic on error
-		 * Fix the bitmap and repeat the block allocation
+		 * Fix the bitmap and return EFSCORRUPTED
 		 * We leak some of the blocks here.
 		 */
 		ext4_lock_group(sb, ac->ac_b_ex.fe_group);
@@ -2937,7 +2948,7 @@ ext4_mb_mark_diskspace_used(struct ext4_
 		ext4_unlock_group(sb, ac->ac_b_ex.fe_group);
 		err = ext4_handle_dirty_metadata(handle, NULL, bitmap_bh);
 		if (!err)
-			err = -EAGAIN;
+			err = -EFSCORRUPTED;
 		goto out_err;
 	}
 
@@ -4502,18 +4513,7 @@ repeat:
 	}
 	if (likely(ac->ac_status == AC_STATUS_FOUND)) {
 		*errp = ext4_mb_mark_diskspace_used(ac, handle, reserv_clstrs);
-		if (*errp == -EAGAIN) {
-			/*
-			 * drop the reference that we took
-			 * in ext4_mb_use_best_found
-			 */
-			ext4_mb_release_context(ac);
-			ac->ac_b_ex.fe_group = 0;
-			ac->ac_b_ex.fe_start = 0;
-			ac->ac_b_ex.fe_len = 0;
-			ac->ac_status = AC_STATUS_CONTINUE;
-			goto repeat;
-		} else if (*errp) {
+		if (*errp) {
 			ext4_discard_allocated_blocks(ac);
 			goto errout;
 		} else {
@@ -4815,7 +4815,9 @@ do_more:
 #endif
 	trace_ext4_mballoc_free(sb, inode, block_group, bit, count_clusters);
 
-	err = ext4_mb_load_buddy(sb, block_group, &e4b);
+	/* __GFP_NOFAIL: retry infinitely, ignore TIF_MEMDIE and memcg limit. */
+	err = ext4_mb_load_buddy_gfp(sb, block_group, &e4b,
+				     GFP_NOFS|__GFP_NOFAIL);
 	if (err)
 		goto error_return;
 
@@ -5217,7 +5219,7 @@ int ext4_trim_fs(struct super_block *sb,
 		grp = ext4_get_group_info(sb, group);
 		/* We only do this if the grp has never been initialized */
 		if (unlikely(EXT4_MB_GRP_NEED_INIT(grp))) {
-			ret = ext4_mb_init_group(sb, group);
+			ret = ext4_mb_init_group(sb, group, GFP_NOFS);
 			if (ret)
 				break;
 		}
--- zfcpdump-kernel-4.4.orig/fs/ext4/move_extent.c
+++ zfcpdump-kernel-4.4/fs/ext4/move_extent.c
@@ -60,10 +60,10 @@ ext4_double_down_write_data_sem(struct i
 {
 	if (first < second) {
 		down_write(&EXT4_I(first)->i_data_sem);
-		down_write_nested(&EXT4_I(second)->i_data_sem, SINGLE_DEPTH_NESTING);
+		down_write_nested(&EXT4_I(second)->i_data_sem, I_DATA_SEM_OTHER);
 	} else {
 		down_write(&EXT4_I(second)->i_data_sem);
-		down_write_nested(&EXT4_I(first)->i_data_sem, SINGLE_DEPTH_NESTING);
+		down_write_nested(&EXT4_I(first)->i_data_sem, I_DATA_SEM_OTHER);
 
 	}
 }
@@ -265,11 +265,12 @@ move_extent_per_page(struct file *o_filp
 	ext4_lblk_t orig_blk_offset, donor_blk_offset;
 	unsigned long blocksize = orig_inode->i_sb->s_blocksize;
 	unsigned int tmp_data_size, data_size, replaced_size;
-	int err2, jblocks, retries = 0;
+	int i, err2, jblocks, retries = 0;
 	int replaced_count = 0;
 	int from = data_offset_in_page << orig_inode->i_blkbits;
 	int blocks_per_page = PAGE_CACHE_SIZE >> orig_inode->i_blkbits;
 	struct super_block *sb = orig_inode->i_sb;
+	struct buffer_head *bh = NULL;
 
 	/*
 	 * It needs twice the amount of ordinary journal buffers because
@@ -380,8 +381,17 @@ data_copy:
 	}
 	/* Perform all necessary steps similar write_begin()/write_end()
 	 * but keeping in mind that i_size will not change */
-	*err = __block_write_begin(pagep[0], from, replaced_size,
-				   ext4_get_block);
+	if (!page_has_buffers(pagep[0]))
+		create_empty_buffers(pagep[0], 1 << orig_inode->i_blkbits, 0);
+	bh = page_buffers(pagep[0]);
+	for (i = 0; i < data_offset_in_page; i++)
+		bh = bh->b_this_page;
+	for (i = 0; i < block_len_in_page; i++) {
+		*err = ext4_get_block(orig_inode, orig_blk_offset + i, bh, 0);
+		if (*err < 0)
+			break;
+		bh = bh->b_this_page;
+	}
 	if (!*err)
 		*err = block_commit_write(pagep[0], from, from + replaced_size);
 
@@ -473,6 +483,13 @@ mext_check_arguments(struct inode *orig_
 			orig_inode->i_ino, donor_inode->i_ino);
 		return -EBUSY;
 	}
+
+	if (IS_NOQUOTA(orig_inode) || IS_NOQUOTA(donor_inode)) {
+		ext4_debug("ext4 move extent: The argument files should "
+			"not be quota files [ino:orig %lu, donor %lu]\n",
+			orig_inode->i_ino, donor_inode->i_ino);
+		return -EBUSY;
+	}
 
 	/* Ext4 move extent supports only extent based file */
 	if (!(ext4_test_inode_flag(orig_inode, EXT4_INODE_EXTENTS))) {
--- zfcpdump-kernel-4.4.orig/fs/ext4/namei.c
+++ zfcpdump-kernel-4.4/fs/ext4/namei.c
@@ -420,15 +420,14 @@ static __le32 ext4_dx_csum(struct inode
 	struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
 	struct ext4_inode_info *ei = EXT4_I(inode);
 	__u32 csum;
-	__le32 save_csum;
 	int size;
+	__u32 dummy_csum = 0;
+	int offset = offsetof(struct dx_tail, dt_checksum);
 
 	size = count_offset + (count * sizeof(struct dx_entry));
-	save_csum = t->dt_checksum;
-	t->dt_checksum = 0;
 	csum = ext4_chksum(sbi, ei->i_csum_seed, (__u8 *)dirent, size);
-	csum = ext4_chksum(sbi, csum, (__u8 *)t, sizeof(struct dx_tail));
-	t->dt_checksum = save_csum;
+	csum = ext4_chksum(sbi, csum, (__u8 *)t, offset);
+	csum = ext4_chksum(sbi, csum, (__u8 *)&dummy_csum, sizeof(dummy_csum));
 
 	return cpu_to_le32(csum);
 }
@@ -2809,7 +2808,7 @@ int ext4_orphan_add(handle_t *handle, st
 			 * list entries can cause panics at unmount time.
 			 */
 			mutex_lock(&sbi->s_orphan_lock);
-			list_del(&EXT4_I(inode)->i_orphan);
+			list_del_init(&EXT4_I(inode)->i_orphan);
 			mutex_unlock(&sbi->s_orphan_lock);
 		}
 	}
--- zfcpdump-kernel-4.4.orig/fs/ext4/resize.c
+++ zfcpdump-kernel-4.4/fs/ext4/resize.c
@@ -20,7 +20,7 @@ int ext4_resize_begin(struct super_block
 {
 	int ret = 0;
 
-	if (!capable(CAP_SYS_RESOURCE))
+	if (!ns_capable(sb->s_user_ns, CAP_SYS_RESOURCE))
 		return -EPERM;
 
 	/*
@@ -198,7 +198,7 @@ static struct ext4_new_flex_group_data *
 	if (flex_gd == NULL)
 		goto out3;
 
-	if (flexbg_size >= UINT_MAX / sizeof(struct ext4_new_flex_group_data))
+	if (flexbg_size >= UINT_MAX / sizeof(struct ext4_new_group_data))
 		goto out2;
 	flex_gd->count = flexbg_size;
 
--- zfcpdump-kernel-4.4.orig/fs/ext4/super.c
+++ zfcpdump-kernel-4.4/fs/ext4/super.c
@@ -38,6 +38,7 @@
 #include <linux/log2.h>
 #include <linux/crc16.h>
 #include <linux/cleancache.h>
+#include <linux/user_namespace.h>
 #include <asm/uaccess.h>
 
 #include <linux/kthread.h>
@@ -80,13 +81,17 @@ static void ext4_destroy_lazyinit_thread
 static void ext4_unregister_li_request(struct super_block *sb);
 static void ext4_clear_request_list(void);
 
+static bool userns_mounts = false;
+module_param(userns_mounts, bool, 0644);
+MODULE_PARM_DESC(userns_mounts, "Allow mounts from unprivileged user namespaces");
+
 #if !defined(CONFIG_EXT2_FS) && !defined(CONFIG_EXT2_FS_MODULE) && defined(CONFIG_EXT4_USE_FOR_EXT2)
 static struct file_system_type ext2_fs_type = {
 	.owner		= THIS_MODULE,
 	.name		= "ext2",
 	.mount		= ext4_mount,
 	.kill_sb	= kill_block_super,
-	.fs_flags	= FS_REQUIRES_DEV,
+	.fs_flags	= FS_REQUIRES_DEV | FS_USERNS_MOUNT,
 };
 MODULE_ALIAS_FS("ext2");
 MODULE_ALIAS("ext2");
@@ -101,7 +106,7 @@ static struct file_system_type ext3_fs_t
 	.name		= "ext3",
 	.mount		= ext4_mount,
 	.kill_sb	= kill_block_super,
-	.fs_flags	= FS_REQUIRES_DEV,
+	.fs_flags	= FS_REQUIRES_DEV | FS_USERNS_MOUNT,
 };
 MODULE_ALIAS_FS("ext3");
 MODULE_ALIAS("ext3");
@@ -958,6 +963,7 @@ static void init_once(void *foo)
 	INIT_LIST_HEAD(&ei->i_orphan);
 	init_rwsem(&ei->xattr_sem);
 	init_rwsem(&ei->i_data_sem);
+	init_rwsem(&ei->i_mmap_sem);
 	inode_init_once(&ei->vfs_inode);
 }
 
@@ -1292,9 +1298,9 @@ static int set_qf_name(struct super_bloc
 		return -1;
 	}
 	if (ext4_has_feature_quota(sb)) {
-		ext4_msg(sb, KERN_ERR, "Cannot set journaled quota options "
-			 "when QUOTA feature is enabled");
-		return -1;
+		ext4_msg(sb, KERN_INFO, "Journaled quota options "
+			 "ignored when QUOTA feature is enabled");
+		return 1;
 	}
 	qname = match_strdup(args);
 	if (!qname) {
@@ -1512,6 +1518,13 @@ static int handle_mount_opt(struct super
 		return -1;
 	}
 
+	if (token == Opt_err_panic && !capable(CAP_SYS_ADMIN)) {
+		ext4_msg(sb, KERN_ERR,
+			 "Mount option \"%s\" not allowed for unprivileged mounts",
+			 opt);
+		return -1;
+	}
+
 	if (args->from && !(m->flags & MOPT_STRING) && match_int(args, &arg))
 		return -1;
 	if (args->from && (m->flags & MOPT_GTE0) && (arg < 0))
@@ -1560,14 +1573,14 @@ static int handle_mount_opt(struct super
 	} else if (token == Opt_stripe) {
 		sbi->s_stripe = arg;
 	} else if (token == Opt_resuid) {
-		uid = make_kuid(current_user_ns(), arg);
+		uid = make_kuid(sb->s_user_ns, arg);
 		if (!uid_valid(uid)) {
 			ext4_msg(sb, KERN_ERR, "Invalid uid value %d", arg);
 			return -1;
 		}
 		sbi->s_resuid = uid;
 	} else if (token == Opt_resgid) {
-		gid = make_kgid(current_user_ns(), arg);
+		gid = make_kgid(sb->s_user_ns, arg);
 		if (!gid_valid(gid)) {
 			ext4_msg(sb, KERN_ERR, "Invalid gid value %d", arg);
 			return -1;
@@ -1606,6 +1619,19 @@ static int handle_mount_opt(struct super
 			return -1;
 		}
 
+		/*
+		 * Refuse access for unprivileged mounts if the user does
+		 * not have rw access to the journal device via the supplied
+		 * path.
+		 */
+		if (!capable(CAP_SYS_ADMIN) &&
+		    inode_permission(d_inode(path.dentry), MAY_READ|MAY_WRITE)) {
+			ext4_msg(sb, KERN_ERR,
+				 "error: Insufficient access to journal path %s",
+				 journal_path);
+			return -1;
+		}
+
 		journal_inode = d_inode(path.dentry);
 		if (!S_ISBLK(journal_inode->i_mode)) {
 			ext4_msg(sb, KERN_ERR, "error: journal path %s "
@@ -1657,10 +1683,10 @@ static int handle_mount_opt(struct super
 			return -1;
 		}
 		if (ext4_has_feature_quota(sb)) {
-			ext4_msg(sb, KERN_ERR,
-				 "Cannot set journaled quota options "
+			ext4_msg(sb, KERN_INFO,
+				 "Quota format mount options ignored "
 				 "when QUOTA feature is enabled");
-			return -1;
+			return 1;
 		}
 		sbi->s_jquota_fmt = m->mount_opt;
 #endif
@@ -1721,11 +1747,11 @@ static int parse_options(char *options,
 #ifdef CONFIG_QUOTA
 	if (ext4_has_feature_quota(sb) &&
 	    (test_opt(sb, USRQUOTA) || test_opt(sb, GRPQUOTA))) {
-		ext4_msg(sb, KERN_ERR, "Cannot set quota options when QUOTA "
-			 "feature is enabled");
-		return 0;
-	}
-	if (sbi->s_qf_names[USRQUOTA] || sbi->s_qf_names[GRPQUOTA]) {
+		ext4_msg(sb, KERN_INFO, "Quota feature enabled, usrquota and grpquota "
+			 "mount options ignored.");
+		clear_opt(sb, USRQUOTA);
+		clear_opt(sb, GRPQUOTA);
+	} else if (sbi->s_qf_names[USRQUOTA] || sbi->s_qf_names[GRPQUOTA]) {
 		if (test_opt(sb, USRQUOTA) && sbi->s_qf_names[USRQUOTA])
 			clear_opt(sb, USRQUOTA);
 
@@ -1839,14 +1865,14 @@ static int _ext4_show_options(struct seq
 		SEQ_OPTS_PRINT("%s", token2str(m->token));
 	}
 
-	if (nodefs || !uid_eq(sbi->s_resuid, make_kuid(&init_user_ns, EXT4_DEF_RESUID)) ||
+	if (nodefs || !uid_eq(sbi->s_resuid, make_kuid(sb->s_user_ns, EXT4_DEF_RESUID)) ||
 	    le16_to_cpu(es->s_def_resuid) != EXT4_DEF_RESUID)
 		SEQ_OPTS_PRINT("resuid=%u",
-				from_kuid_munged(&init_user_ns, sbi->s_resuid));
-	if (nodefs || !gid_eq(sbi->s_resgid, make_kgid(&init_user_ns, EXT4_DEF_RESGID)) ||
+				from_kuid_munged(sb->s_user_ns, sbi->s_resuid));
+	if (nodefs || !gid_eq(sbi->s_resgid, make_kgid(sb->s_user_ns, EXT4_DEF_RESGID)) ||
 	    le16_to_cpu(es->s_def_resgid) != EXT4_DEF_RESGID)
 		SEQ_OPTS_PRINT("resgid=%u",
-				from_kgid_munged(&init_user_ns, sbi->s_resgid));
+				from_kgid_munged(sb->s_user_ns, sbi->s_resgid));
 	def_errors = nodefs ? -1 : le16_to_cpu(es->s_errors);
 	if (test_opt(sb, ERRORS_RO) && def_errors != EXT4_ERRORS_RO)
 		SEQ_OPTS_PUTS("errors=remount-ro");
@@ -2029,23 +2055,25 @@ failed:
 static __le16 ext4_group_desc_csum(struct super_block *sb, __u32 block_group,
 				   struct ext4_group_desc *gdp)
 {
-	int offset;
+	int offset = offsetof(struct ext4_group_desc, bg_checksum);
 	__u16 crc = 0;
 	__le32 le_group = cpu_to_le32(block_group);
 	struct ext4_sb_info *sbi = EXT4_SB(sb);
 
 	if (ext4_has_metadata_csum(sbi->s_sb)) {
 		/* Use new metadata_csum algorithm */
-		__le16 save_csum;
 		__u32 csum32;
+		__u16 dummy_csum = 0;
 
-		save_csum = gdp->bg_checksum;
-		gdp->bg_checksum = 0;
 		csum32 = ext4_chksum(sbi, sbi->s_csum_seed, (__u8 *)&le_group,
 				     sizeof(le_group));
-		csum32 = ext4_chksum(sbi, csum32, (__u8 *)gdp,
-				     sbi->s_desc_size);
-		gdp->bg_checksum = save_csum;
+		csum32 = ext4_chksum(sbi, csum32, (__u8 *)gdp, offset);
+		csum32 = ext4_chksum(sbi, csum32, (__u8 *)&dummy_csum,
+				     sizeof(dummy_csum));
+		offset += sizeof(dummy_csum);
+		if (offset < sbi->s_desc_size)
+			csum32 = ext4_chksum(sbi, csum32, (__u8 *)gdp + offset,
+					     sbi->s_desc_size - offset);
 
 		crc = csum32 & 0xFFFF;
 		goto out;
@@ -2055,8 +2083,6 @@ static __le16 ext4_group_desc_csum(struc
 	if (!ext4_has_feature_gdt_csum(sb))
 		return 0;
 
-	offset = offsetof(struct ext4_group_desc, bg_checksum);
-
 	crc = crc16(~0, sbi->s_es->s_uuid, sizeof(sbi->s_es->s_uuid));
 	crc = crc16(crc, (__u8 *)&le_group, sizeof(le_group));
 	crc = crc16(crc, (__u8 *)gdp, offset);
@@ -2092,6 +2118,7 @@ void ext4_group_desc_csum_set(struct sup
 
 /* Called at mount-time, super-block is locked */
 static int ext4_check_descriptors(struct super_block *sb,
+				  ext4_fsblk_t sb_block,
 				  ext4_group_t *first_not_zeroed)
 {
 	struct ext4_sb_info *sbi = EXT4_SB(sb);
@@ -2122,6 +2149,11 @@ static int ext4_check_descriptors(struct
 			grp = i;
 
 		block_bitmap = ext4_block_bitmap(sb, gdp);
+		if (block_bitmap == sb_block) {
+			ext4_msg(sb, KERN_ERR, "ext4_check_descriptors: "
+				 "Block bitmap for group %u overlaps "
+				 "superblock", i);
+		}
 		if (block_bitmap < first_block || block_bitmap > last_block) {
 			ext4_msg(sb, KERN_ERR, "ext4_check_descriptors: "
 			       "Block bitmap for group %u not in group "
@@ -2129,6 +2161,11 @@ static int ext4_check_descriptors(struct
 			return 0;
 		}
 		inode_bitmap = ext4_inode_bitmap(sb, gdp);
+		if (inode_bitmap == sb_block) {
+			ext4_msg(sb, KERN_ERR, "ext4_check_descriptors: "
+				 "Inode bitmap for group %u overlaps "
+				 "superblock", i);
+		}
 		if (inode_bitmap < first_block || inode_bitmap > last_block) {
 			ext4_msg(sb, KERN_ERR, "ext4_check_descriptors: "
 			       "Inode bitmap for group %u not in group "
@@ -2136,6 +2173,11 @@ static int ext4_check_descriptors(struct
 			return 0;
 		}
 		inode_table = ext4_inode_table(sb, gdp);
+		if (inode_table == sb_block) {
+			ext4_msg(sb, KERN_ERR, "ext4_check_descriptors: "
+				 "Inode table for group %u overlaps "
+				 "superblock", i);
+		}
 		if (inode_table < first_block ||
 		    inode_table + sbi->s_itb_per_group - 1 > last_block) {
 			ext4_msg(sb, KERN_ERR, "ext4_check_descriptors: "
@@ -2239,6 +2281,16 @@ static void ext4_orphan_cleanup(struct s
 	while (es->s_last_orphan) {
 		struct inode *inode;
 
+		/*
+		 * We may have encountered an error during cleanup; if
+		 * so, skip the rest.
+		 */
+		if (EXT4_SB(sb)->s_mount_state & EXT4_ERROR_FS) {
+			jbd_debug(1, "Skipping orphan recovery on fs with errors.\n");
+			es->s_last_orphan = 0;
+			break;
+		}
+
 		inode = ext4_orphan_get(sb, le32_to_cpu(es->s_last_orphan));
 		if (IS_ERR(inode)) {
 			es->s_last_orphan = 0;
@@ -3122,6 +3174,9 @@ static int ext4_fill_super(struct super_
 	unsigned int journal_ioprio = DEFAULT_JOURNAL_IOPRIO;
 	ext4_group_t first_not_zeroed;
 
+	if (!userns_mounts && !capable(CAP_SYS_ADMIN))
+		return -EPERM;
+
 	sbi = kzalloc(sizeof(*sbi), GFP_KERNEL);
 	if (!sbi)
 		goto out_free_orig;
@@ -3243,19 +3298,26 @@ static int ext4_fill_super(struct super_
 	else if ((def_mount_opts & EXT4_DEFM_JMODE) == EXT4_DEFM_JMODE_WBACK)
 		set_opt(sb, WRITEBACK_DATA);
 
-	if (le16_to_cpu(sbi->s_es->s_errors) == EXT4_ERRORS_PANIC)
+	if (le16_to_cpu(sbi->s_es->s_errors) == EXT4_ERRORS_PANIC) {
+		if (!capable(CAP_SYS_ADMIN))
+			goto failed_mount;
 		set_opt(sb, ERRORS_PANIC);
-	else if (le16_to_cpu(sbi->s_es->s_errors) == EXT4_ERRORS_CONTINUE)
+	} else if (le16_to_cpu(sbi->s_es->s_errors) == EXT4_ERRORS_CONTINUE) {
 		set_opt(sb, ERRORS_CONT);
-	else
+	} else {
 		set_opt(sb, ERRORS_RO);
+	}
 	/* block_validity enabled by default; disable with noblock_validity */
 	set_opt(sb, BLOCK_VALIDITY);
 	if (def_mount_opts & EXT4_DEFM_DISCARD)
 		set_opt(sb, DISCARD);
 
-	sbi->s_resuid = make_kuid(&init_user_ns, le16_to_cpu(es->s_def_resuid));
-	sbi->s_resgid = make_kgid(&init_user_ns, le16_to_cpu(es->s_def_resgid));
+	sbi->s_resuid = make_kuid(sb->s_user_ns, le16_to_cpu(es->s_def_resuid));
+	if (!uid_valid(sbi->s_resuid))
+		sbi->s_resuid = make_kuid(sb->s_user_ns, EXT4_DEF_RESUID);
+	sbi->s_resgid = make_kgid(sb->s_user_ns, le16_to_cpu(es->s_def_resgid));
+	if (!gid_valid(sbi->s_resgid))
+		sbi->s_resgid = make_kgid(sb->s_user_ns, EXT4_DEF_RESGID);
 	sbi->s_commit_interval = JBD2_DEFAULT_MAX_COMMIT_AGE * HZ;
 	sbi->s_min_batch_time = EXT4_DEF_MIN_BATCH_TIME;
 	sbi->s_max_batch_time = EXT4_DEF_MAX_BATCH_TIME;
@@ -3371,6 +3433,13 @@ static int ext4_fill_super(struct super_
 		goto failed_mount;
 	}
 
+	if (le16_to_cpu(sbi->s_es->s_reserved_gdt_blocks) > (blocksize / 4)) {
+		ext4_msg(sb, KERN_ERR,
+			 "Number of reserved GDT blocks insanely large: %d",
+			 le16_to_cpu(sbi->s_es->s_reserved_gdt_blocks));
+		goto failed_mount;
+	}
+
 	if (sbi->s_mount_opt & EXT4_MOUNT_DAX) {
 		if (blocksize != PAGE_SIZE) {
 			ext4_msg(sb, KERN_ERR,
@@ -3622,7 +3691,7 @@ static int ext4_fill_super(struct super_
 			goto failed_mount2;
 		}
 	}
-	if (!ext4_check_descriptors(sb, &first_not_zeroed)) {
+	if (!ext4_check_descriptors(sb, logical_sb_block, &first_not_zeroed)) {
 		ext4_msg(sb, KERN_ERR, "group descriptors corrupted!");
 		ret = -EFSCORRUPTED;
 		goto failed_mount2;
@@ -4013,6 +4082,7 @@ failed_mount:
 	ext4_blkdev_remove(sbi);
 	brelse(bh);
 out_fail:
+	/* sb->s_user_ns will be put when sb is destroyed */
 	sb->s_fs_info = NULL;
 	kfree(sbi->s_blockgroup_lock);
 	kfree(sbi);
@@ -4936,6 +5006,20 @@ static int ext4_quota_on_mount(struct su
 					EXT4_SB(sb)->s_jquota_fmt, type);
 }
 
+static void lockdep_set_quota_inode(struct inode *inode, int subclass)
+{
+	struct ext4_inode_info *ei = EXT4_I(inode);
+
+	/* The first argument of lockdep_set_subclass has to be
+	 * *exactly* the same as the argument to init_rwsem() --- in
+	 * this case, in init_once() --- or lockdep gets unhappy
+	 * because the name of the lock is set using the
+	 * stringification of the argument to init_rwsem().
+	 */
+	(void) ei;	/* shut up clang warning if !CONFIG_LOCKDEP */
+	lockdep_set_subclass(&ei->i_data_sem, subclass);
+}
+
 /*
  * Standard function to be called on quota_on
  */
@@ -4975,8 +5059,12 @@ static int ext4_quota_on(struct super_bl
 		if (err)
 			return err;
 	}
-
-	return dquot_quota_on(sb, type, format_id, path);
+	lockdep_set_quota_inode(path->dentry->d_inode, I_DATA_SEM_QUOTA);
+	err = dquot_quota_on(sb, type, format_id, path);
+	if (err)
+		lockdep_set_quota_inode(path->dentry->d_inode,
+					     I_DATA_SEM_NORMAL);
+	return err;
 }
 
 static int ext4_quota_enable(struct super_block *sb, int type, int format_id,
@@ -5002,8 +5090,11 @@ static int ext4_quota_enable(struct supe
 
 	/* Don't account quota for quota files to avoid recursion */
 	qf_inode->i_flags |= S_NOQUOTA;
+	lockdep_set_quota_inode(qf_inode, I_DATA_SEM_QUOTA);
 	err = dquot_enable(qf_inode, type, format_id, flags);
 	iput(qf_inode);
+	if (err)
+		lockdep_set_quota_inode(qf_inode, I_DATA_SEM_NORMAL);
 
 	return err;
 }
@@ -5228,7 +5319,7 @@ static struct file_system_type ext4_fs_t
 	.name		= "ext4",
 	.mount		= ext4_mount,
 	.kill_sb	= kill_block_super,
-	.fs_flags	= FS_REQUIRES_DEV,
+	.fs_flags	= FS_REQUIRES_DEV | FS_USERNS_MOUNT,
 };
 MODULE_ALIAS_FS("ext4");
 
--- zfcpdump-kernel-4.4.orig/fs/ext4/truncate.h
+++ zfcpdump-kernel-4.4/fs/ext4/truncate.h
@@ -10,8 +10,10 @@
  */
 static inline void ext4_truncate_failed_write(struct inode *inode)
 {
+	down_write(&EXT4_I(inode)->i_mmap_sem);
 	truncate_inode_pages(inode->i_mapping, inode->i_size);
 	ext4_truncate(inode);
+	up_write(&EXT4_I(inode)->i_mmap_sem);
 }
 
 /*
--- zfcpdump-kernel-4.4.orig/fs/ext4/xattr.c
+++ zfcpdump-kernel-4.4/fs/ext4/xattr.c
@@ -123,17 +123,18 @@ static __le32 ext4_xattr_block_csum(stru
 {
 	struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
 	__u32 csum;
-	__le32 save_csum;
 	__le64 dsk_block_nr = cpu_to_le64(block_nr);
+	__u32 dummy_csum = 0;
+	int offset = offsetof(struct ext4_xattr_header, h_checksum);
 
-	save_csum = hdr->h_checksum;
-	hdr->h_checksum = 0;
 	csum = ext4_chksum(sbi, sbi->s_csum_seed, (__u8 *)&dsk_block_nr,
 			   sizeof(dsk_block_nr));
-	csum = ext4_chksum(sbi, csum, (__u8 *)hdr,
-			   EXT4_BLOCK_SIZE(inode->i_sb));
+	csum = ext4_chksum(sbi, csum, (__u8 *)hdr, offset);
+	csum = ext4_chksum(sbi, csum, (__u8 *)&dummy_csum, sizeof(dummy_csum));
+	offset += sizeof(dummy_csum);
+	csum = ext4_chksum(sbi, csum, (__u8 *)hdr + offset,
+			   EXT4_BLOCK_SIZE(inode->i_sb) - offset);
 
-	hdr->h_checksum = save_csum;
 	return cpu_to_le32(csum);
 }
 
@@ -1264,15 +1265,19 @@ int ext4_expand_extra_isize_ea(struct in
 	size_t min_offs, free;
 	int total_ino;
 	void *base, *start, *end;
-	int extra_isize = 0, error = 0, tried_min_extra_isize = 0;
+	int error = 0, tried_min_extra_isize = 0;
 	int s_min_extra_isize = le16_to_cpu(EXT4_SB(inode->i_sb)->s_es->s_min_extra_isize);
+	int isize_diff;	/* How much do we need to grow i_extra_isize */
 
 	down_write(&EXT4_I(inode)->xattr_sem);
+	/*
+	 * Set EXT4_STATE_NO_EXPAND to avoid recursion when marking inode dirty
+	 */
+	ext4_set_inode_state(inode, EXT4_STATE_NO_EXPAND);
 retry:
-	if (EXT4_I(inode)->i_extra_isize >= new_extra_isize) {
-		up_write(&EXT4_I(inode)->xattr_sem);
-		return 0;
-	}
+	isize_diff = new_extra_isize - EXT4_I(inode)->i_extra_isize;
+	if (EXT4_I(inode)->i_extra_isize >= new_extra_isize)
+		goto out;
 
 	header = IHDR(inode, raw_inode);
 	entry = IFIRST(header);
@@ -1289,7 +1294,7 @@ retry:
 	total_ino = sizeof(struct ext4_xattr_ibody_header);
 
 	free = ext4_xattr_free_space(last, &min_offs, base, &total_ino);
-	if (free >= new_extra_isize) {
+	if (free >= isize_diff) {
 		entry = IFIRST(header);
 		ext4_xattr_shift_entries(entry,	EXT4_I(inode)->i_extra_isize
 				- new_extra_isize, (void *)raw_inode +
@@ -1297,8 +1302,7 @@ retry:
 				(void *)header, total_ino,
 				inode->i_sb->s_blocksize);
 		EXT4_I(inode)->i_extra_isize = new_extra_isize;
-		error = 0;
-		goto cleanup;
+		goto out;
 	}
 
 	/*
@@ -1321,7 +1325,7 @@ retry:
 		end = bh->b_data + bh->b_size;
 		min_offs = end - base;
 		free = ext4_xattr_free_space(first, &min_offs, base, NULL);
-		if (free < new_extra_isize) {
+		if (free < isize_diff) {
 			if (!tried_min_extra_isize && s_min_extra_isize) {
 				tried_min_extra_isize++;
 				new_extra_isize = s_min_extra_isize;
@@ -1335,7 +1339,7 @@ retry:
 		free = inode->i_sb->s_blocksize;
 	}
 
-	while (new_extra_isize > 0) {
+	while (isize_diff > 0) {
 		size_t offs, size, entry_size;
 		struct ext4_xattr_entry *small_entry = NULL;
 		struct ext4_xattr_info i = {
@@ -1366,7 +1370,7 @@ retry:
 			EXT4_XATTR_SIZE(le32_to_cpu(last->e_value_size)) +
 					EXT4_XATTR_LEN(last->e_name_len);
 			if (total_size <= free && total_size < min_total_size) {
-				if (total_size < new_extra_isize) {
+				if (total_size < isize_diff) {
 					small_entry = last;
 				} else {
 					entry = last;
@@ -1421,22 +1425,22 @@ retry:
 		error = ext4_xattr_ibody_set(handle, inode, &i, is);
 		if (error)
 			goto cleanup;
+		total_ino -= entry_size;
 
 		entry = IFIRST(header);
-		if (entry_size + EXT4_XATTR_SIZE(size) >= new_extra_isize)
-			shift_bytes = new_extra_isize;
+		if (entry_size + EXT4_XATTR_SIZE(size) >= isize_diff)
+			shift_bytes = isize_diff;
 		else
-			shift_bytes = entry_size + size;
+			shift_bytes = entry_size + EXT4_XATTR_SIZE(size);
 		/* Adjust the offsets and shift the remaining entries ahead */
-		ext4_xattr_shift_entries(entry, EXT4_I(inode)->i_extra_isize -
-			shift_bytes, (void *)raw_inode +
-			EXT4_GOOD_OLD_INODE_SIZE + extra_isize + shift_bytes,
-			(void *)header, total_ino - entry_size,
-			inode->i_sb->s_blocksize);
-
-		extra_isize += shift_bytes;
-		new_extra_isize -= shift_bytes;
-		EXT4_I(inode)->i_extra_isize = extra_isize;
+		ext4_xattr_shift_entries(entry, -shift_bytes,
+			(void *)raw_inode + EXT4_GOOD_OLD_INODE_SIZE +
+			EXT4_I(inode)->i_extra_isize + shift_bytes,
+			(void *)header, total_ino, inode->i_sb->s_blocksize);
+
+		isize_diff -= shift_bytes;
+		EXT4_I(inode)->i_extra_isize += shift_bytes;
+		header = IHDR(inode, raw_inode);
 
 		i.name = b_entry_name;
 		i.value = buffer;
@@ -1458,6 +1462,8 @@ retry:
 		kfree(bs);
 	}
 	brelse(bh);
+out:
+	ext4_clear_inode_state(inode, EXT4_STATE_NO_EXPAND);
 	up_write(&EXT4_I(inode)->xattr_sem);
 	return 0;
 
@@ -1469,6 +1475,10 @@ cleanup:
 	kfree(is);
 	kfree(bs);
 	brelse(bh);
+	/*
+	 * We deliberately leave EXT4_STATE_NO_EXPAND set here since inode
+	 * size expansion failed.
+	 */
 	up_write(&EXT4_I(inode)->xattr_sem);
 	return error;
 }
--- zfcpdump-kernel-4.4.orig/fs/f2fs/crypto_policy.c
+++ zfcpdump-kernel-4.4/fs/f2fs/crypto_policy.c
@@ -89,6 +89,9 @@ static int f2fs_create_encryption_contex
 int f2fs_process_policy(const struct f2fs_encryption_policy *policy,
 			struct inode *inode)
 {
+	if (!inode_owner_or_capable(inode))
+		return -EACCES;
+
 	if (policy->version != 0)
 		return -EINVAL;
 
--- zfcpdump-kernel-4.4.orig/fs/fhandle.c
+++ zfcpdump-kernel-4.4/fs/fhandle.c
@@ -228,7 +228,7 @@ long do_handle_open(int mountdirfd,
 		path_put(&path);
 		return fd;
 	}
-	file = file_open_root(path.dentry, path.mnt, "", open_flag);
+	file = file_open_root(path.dentry, path.mnt, "", open_flag, 0);
 	if (IS_ERR(file)) {
 		put_unused_fd(fd);
 		retval =  PTR_ERR(file);
--- zfcpdump-kernel-4.4.orig/fs/file_table.c
+++ zfcpdump-kernel-4.4/fs/file_table.c
@@ -147,6 +147,7 @@ over:
 	}
 	return ERR_PTR(-ENFILE);
 }
+EXPORT_SYMBOL(get_empty_filp);
 
 /**
  * alloc_file - allocate and initialize a 'struct file'
@@ -308,6 +309,7 @@ void put_filp(struct file *file)
 		file_free(file);
 	}
 }
+EXPORT_SYMBOL(put_filp);
 
 void __init files_init(void)
 { 
--- zfcpdump-kernel-4.4.orig/fs/fs-writeback.c
+++ zfcpdump-kernel-4.4/fs/fs-writeback.c
@@ -223,6 +223,9 @@ static void wb_wait_for_completion(struc
 #define WB_FRN_HIST_MAX_SLOTS	(WB_FRN_HIST_THR_SLOTS / 2 + 1)
 					/* one round can affect upto 5 slots */
 
+static atomic_t isw_nr_in_flight = ATOMIC_INIT(0);
+static struct workqueue_struct *isw_wq;
+
 void __inode_attach_wb(struct inode *inode, struct page *page)
 {
 	struct backing_dev_info *bdi = inode_to_bdi(inode);
@@ -278,13 +281,15 @@ locked_inode_to_wb_and_lock_list(struct
 		wb_get(wb);
 		spin_unlock(&inode->i_lock);
 		spin_lock(&wb->list_lock);
-		wb_put(wb);		/* not gonna deref it anymore */
 
 		/* i_wb may have changed inbetween, can't use inode_to_wb() */
-		if (likely(wb == inode->i_wb))
-			return wb;	/* @inode already has ref */
+		if (likely(wb == inode->i_wb)) {
+			wb_put(wb);	/* @inode already has ref */
+			return wb;
+		}
 
 		spin_unlock(&wb->list_lock);
+		wb_put(wb);
 		cpu_relax();
 		spin_lock(&inode->i_lock);
 	}
@@ -424,6 +429,8 @@ skip_switch:
 
 	iput(inode);
 	kfree(isw);
+
+	atomic_dec(&isw_nr_in_flight);
 }
 
 static void inode_switch_wbs_rcu_fn(struct rcu_head *rcu_head)
@@ -433,7 +440,7 @@ static void inode_switch_wbs_rcu_fn(stru
 
 	/* needs to grab bh-unsafe locks, bounce to work item */
 	INIT_WORK(&isw->work, inode_switch_wbs_work_fn);
-	schedule_work(&isw->work);
+	queue_work(isw_wq, &isw->work);
 }
 
 /**
@@ -469,7 +476,8 @@ static void inode_switch_wbs(struct inod
 
 	/* while holding I_WB_SWITCH, no one else can update the association */
 	spin_lock(&inode->i_lock);
-	if (inode->i_state & (I_WB_SWITCH | I_FREEING) ||
+	if (!(inode->i_sb->s_flags & MS_ACTIVE) ||
+	    inode->i_state & (I_WB_SWITCH | I_FREEING) ||
 	    inode_to_wb(inode) == isw->new_wb) {
 		spin_unlock(&inode->i_lock);
 		goto out_free;
@@ -480,6 +488,8 @@ static void inode_switch_wbs(struct inod
 	ihold(inode);
 	isw->inode = inode;
 
+	atomic_inc(&isw_nr_in_flight);
+
 	/*
 	 * In addition to synchronizing among switchers, I_WB_SWITCH tells
 	 * the RCU protected stat update paths to grab the mapping's
@@ -842,6 +852,33 @@ restart:
 		wb_put(last_wb);
 }
 
+/**
+ * cgroup_writeback_umount - flush inode wb switches for umount
+ *
+ * This function is called when a super_block is about to be destroyed and
+ * flushes in-flight inode wb switches.  An inode wb switch goes through
+ * RCU and then workqueue, so the two need to be flushed in order to ensure
+ * that all previously scheduled switches are finished.  As wb switches are
+ * rare occurrences and synchronize_rcu() can take a while, perform
+ * flushing iff wb switches are in flight.
+ */
+void cgroup_writeback_umount(void)
+{
+	if (atomic_read(&isw_nr_in_flight)) {
+		synchronize_rcu();
+		flush_workqueue(isw_wq);
+	}
+}
+
+static int __init cgroup_writeback_init(void)
+{
+	isw_wq = alloc_workqueue("inode_switch_wbs", 0, 0);
+	if (!isw_wq)
+		return -ENOMEM;
+	return 0;
+}
+fs_initcall(cgroup_writeback_init);
+
 #else	/* CONFIG_CGROUP_WRITEBACK */
 
 static struct bdi_writeback *
@@ -1255,6 +1292,7 @@ __writeback_single_inode(struct inode *i
 	dirty = inode->i_state & I_DIRTY;
 	if (inode->i_state & I_DIRTY_TIME) {
 		if ((dirty & (I_DIRTY_SYNC | I_DIRTY_DATASYNC)) ||
+		    wbc->sync_mode == WB_SYNC_ALL ||
 		    unlikely(inode->i_state & I_DIRTY_TIME_EXPIRED) ||
 		    unlikely(time_after(jiffies,
 					(inode->dirtied_time_when +
@@ -1304,10 +1342,10 @@ __writeback_single_inode(struct inode *i
  * we go e.g. from filesystem. Flusher thread uses __writeback_single_inode()
  * and does more profound writeback list handling in writeback_sb_inodes().
  */
-static int
-writeback_single_inode(struct inode *inode, struct bdi_writeback *wb,
-		       struct writeback_control *wbc)
+static int writeback_single_inode(struct inode *inode,
+				  struct writeback_control *wbc)
 {
+	struct bdi_writeback *wb;
 	int ret = 0;
 
 	spin_lock(&inode->i_lock);
@@ -1345,7 +1383,8 @@ writeback_single_inode(struct inode *ino
 	ret = __writeback_single_inode(inode, wbc);
 
 	wbc_detach_inode(wbc);
-	spin_lock(&wb->list_lock);
+
+	wb = inode_to_wb_and_lock_list(inode);
 	spin_lock(&inode->i_lock);
 	/*
 	 * If inode is clean, remove it from writeback lists. Otherwise don't
@@ -1420,6 +1459,7 @@ static long writeback_sb_inodes(struct s
 
 	while (!list_empty(&wb->b_io)) {
 		struct inode *inode = wb_inode(wb->b_io.prev);
+		struct bdi_writeback *tmp_wb;
 
 		if (inode->i_sb != sb) {
 			if (work->sb) {
@@ -1510,15 +1550,23 @@ static long writeback_sb_inodes(struct s
 			cond_resched();
 		}
 
-
-		spin_lock(&wb->list_lock);
+		/*
+		 * Requeue @inode if still dirty.  Be careful as @inode may
+		 * have been switched to another wb in the meantime.
+		 */
+		tmp_wb = inode_to_wb_and_lock_list(inode);
 		spin_lock(&inode->i_lock);
 		if (!(inode->i_state & I_DIRTY_ALL))
 			wrote++;
-		requeue_inode(inode, wb, &wbc);
+		requeue_inode(inode, tmp_wb, &wbc);
 		inode_sync_complete(inode);
 		spin_unlock(&inode->i_lock);
 
+		if (unlikely(tmp_wb != wb)) {
+			spin_unlock(&tmp_wb->list_lock);
+			spin_lock(&wb->list_lock);
+		}
+
 		/*
 		 * bail out to wb_writeback() often enough to check
 		 * background threshold and other termination conditions.
@@ -2305,7 +2353,6 @@ EXPORT_SYMBOL(sync_inodes_sb);
  */
 int write_inode_now(struct inode *inode, int sync)
 {
-	struct bdi_writeback *wb = &inode_to_bdi(inode)->wb;
 	struct writeback_control wbc = {
 		.nr_to_write = LONG_MAX,
 		.sync_mode = sync ? WB_SYNC_ALL : WB_SYNC_NONE,
@@ -2317,7 +2364,7 @@ int write_inode_now(struct inode *inode,
 		wbc.nr_to_write = 0;
 
 	might_sleep();
-	return writeback_single_inode(inode, wb, &wbc);
+	return writeback_single_inode(inode, &wbc);
 }
 EXPORT_SYMBOL(write_inode_now);
 
@@ -2334,7 +2381,7 @@ EXPORT_SYMBOL(write_inode_now);
  */
 int sync_inode(struct inode *inode, struct writeback_control *wbc)
 {
-	return writeback_single_inode(inode, &inode_to_bdi(inode)->wb, wbc);
+	return writeback_single_inode(inode, wbc);
 }
 EXPORT_SYMBOL(sync_inode);
 
--- zfcpdump-kernel-4.4.orig/fs/fuse/cuse.c
+++ zfcpdump-kernel-4.4/fs/fuse/cuse.c
@@ -48,6 +48,7 @@
 #include <linux/stat.h>
 #include <linux/module.h>
 #include <linux/uio.h>
+#include <linux/user_namespace.h>
 
 #include "fuse_i.h"
 
@@ -90,7 +91,7 @@ static struct list_head *cuse_conntbl_he
 
 static ssize_t cuse_read_iter(struct kiocb *kiocb, struct iov_iter *to)
 {
-	struct fuse_io_priv io = { .async = 0, .file = kiocb->ki_filp };
+	struct fuse_io_priv io = FUSE_IO_PRIV_SYNC(kiocb->ki_filp);
 	loff_t pos = 0;
 
 	return fuse_direct_io(&io, to, &pos, FUSE_DIO_CUSE);
@@ -98,7 +99,7 @@ static ssize_t cuse_read_iter(struct kio
 
 static ssize_t cuse_write_iter(struct kiocb *kiocb, struct iov_iter *from)
 {
-	struct fuse_io_priv io = { .async = 0, .file = kiocb->ki_filp };
+	struct fuse_io_priv io = FUSE_IO_PRIV_SYNC(kiocb->ki_filp);
 	loff_t pos = 0;
 	/*
 	 * No locking or generic_write_checks(), the server is
@@ -498,7 +499,7 @@ static int cuse_channel_open(struct inod
 	if (!cc)
 		return -ENOMEM;
 
-	fuse_conn_init(&cc->fc);
+	fuse_conn_init(&cc->fc, current_user_ns());
 
 	fud = fuse_dev_alloc(&cc->fc);
 	if (!fud) {
--- zfcpdump-kernel-4.4.orig/fs/fuse/dev.c
+++ zfcpdump-kernel-4.4/fs/fuse/dev.c
@@ -19,6 +19,7 @@
 #include <linux/pipe_fs_i.h>
 #include <linux/swap.h>
 #include <linux/splice.h>
+#include <linux/sched.h>
 
 MODULE_ALIAS_MISCDEV(FUSE_MINOR);
 MODULE_ALIAS("devname:fuse");
@@ -124,11 +125,11 @@ static void __fuse_put_request(struct fu
 	atomic_dec(&req->count);
 }
 
-static void fuse_req_init_context(struct fuse_req *req)
+static void fuse_req_init_context(struct fuse_conn *fc, struct fuse_req *req)
 {
-	req->in.h.uid = from_kuid_munged(&init_user_ns, current_fsuid());
-	req->in.h.gid = from_kgid_munged(&init_user_ns, current_fsgid());
-	req->in.h.pid = current->pid;
+	req->in.h.uid = from_kuid(fc->user_ns, current_fsuid());
+	req->in.h.gid = from_kgid(fc->user_ns, current_fsgid());
+	req->in.h.pid = pid_nr_ns(task_pid(current), fc->pid_ns);
 }
 
 void fuse_set_initialized(struct fuse_conn *fc)
@@ -181,10 +182,14 @@ static struct fuse_req *__fuse_get_req(s
 		goto out;
 	}
 
-	fuse_req_init_context(req);
+	fuse_req_init_context(fc, req);
 	__set_bit(FR_WAITING, &req->flags);
 	if (for_background)
 		__set_bit(FR_BACKGROUND, &req->flags);
+	if (req->in.h.uid == (uid_t)-1 || req->in.h.gid == (gid_t)-1) {
+		fuse_put_request(fc, req);
+		return ERR_PTR(-EOVERFLOW);
+	}
 
 	return req;
 
@@ -274,7 +279,7 @@ struct fuse_req *fuse_get_req_nofail_nop
 	if (!req)
 		req = get_reserved_req(fc, file);
 
-	fuse_req_init_context(req);
+	fuse_req_init_context(fc, req);
 	__set_bit(FR_WAITING, &req->flags);
 	__clear_bit(FR_BACKGROUND, &req->flags);
 	return req;
@@ -1243,6 +1248,10 @@ static ssize_t fuse_dev_do_read(struct f
 	struct fuse_in *in;
 	unsigned reqsize;
 
+	if (task_active_pid_ns(current) != fc->pid_ns ||
+	    current_user_ns() != fc->user_ns)
+		return -EIO;
+
  restart:
 	spin_lock(&fiq->waitq.lock);
 	err = -EAGAIN;
@@ -1872,6 +1881,10 @@ static ssize_t fuse_dev_do_write(struct
 	struct fuse_req *req;
 	struct fuse_out_header oh;
 
+	if (task_active_pid_ns(current) != fc->pid_ns ||
+	    current_user_ns() != fc->user_ns)
+		return -EIO;
+
 	if (nbytes < sizeof(struct fuse_out_header))
 		return -EINVAL;
 
--- zfcpdump-kernel-4.4.orig/fs/fuse/dir.c
+++ zfcpdump-kernel-4.4/fs/fuse/dir.c
@@ -841,8 +841,8 @@ static void fuse_fillattr(struct inode *
 	stat->ino = attr->ino;
 	stat->mode = (inode->i_mode & S_IFMT) | (attr->mode & 07777);
 	stat->nlink = attr->nlink;
-	stat->uid = make_kuid(&init_user_ns, attr->uid);
-	stat->gid = make_kgid(&init_user_ns, attr->gid);
+	stat->uid = inode->i_uid;
+	stat->gid = inode->i_gid;
 	stat->rdev = inode->i_rdev;
 	stat->atime.tv_sec = attr->atime;
 	stat->atime.tv_nsec = attr->atimensec;
@@ -1015,7 +1015,7 @@ int fuse_allow_current_process(struct fu
 	const struct cred *cred;
 
 	if (fc->flags & FUSE_ALLOW_OTHER)
-		return 1;
+		return current_in_userns(fc->user_ns);
 
 	cred = current_cred();
 	if (uid_eq(cred->euid, fc->user_id) &&
@@ -1455,17 +1455,17 @@ static bool update_mtime(unsigned ivalid
 	return true;
 }
 
-static void iattr_to_fattr(struct iattr *iattr, struct fuse_setattr_in *arg,
-			   bool trust_local_cmtime)
+static void iattr_to_fattr(struct fuse_conn *fc, struct iattr *iattr,
+			   struct fuse_setattr_in *arg, bool trust_local_cmtime)
 {
 	unsigned ivalid = iattr->ia_valid;
 
 	if (ivalid & ATTR_MODE)
 		arg->valid |= FATTR_MODE,   arg->mode = iattr->ia_mode;
 	if (ivalid & ATTR_UID)
-		arg->valid |= FATTR_UID,    arg->uid = from_kuid(&init_user_ns, iattr->ia_uid);
+		arg->valid |= FATTR_UID,    arg->uid = from_kuid(fc->user_ns, iattr->ia_uid);
 	if (ivalid & ATTR_GID)
-		arg->valid |= FATTR_GID,    arg->gid = from_kgid(&init_user_ns, iattr->ia_gid);
+		arg->valid |= FATTR_GID,    arg->gid = from_kgid(fc->user_ns, iattr->ia_gid);
 	if (ivalid & ATTR_SIZE)
 		arg->valid |= FATTR_SIZE,   arg->size = iattr->ia_size;
 	if (ivalid & ATTR_ATIME) {
@@ -1625,7 +1625,7 @@ int fuse_do_setattr(struct inode *inode,
 
 	memset(&inarg, 0, sizeof(inarg));
 	memset(&outarg, 0, sizeof(outarg));
-	iattr_to_fattr(attr, &inarg, trust_local_cmtime);
+	iattr_to_fattr(fc, attr, &inarg, trust_local_cmtime);
 	if (file) {
 		struct fuse_file *ff = file->private_data;
 		inarg.valid |= FATTR_FH;
--- zfcpdump-kernel-4.4.orig/fs/fuse/file.c
+++ zfcpdump-kernel-4.4/fs/fuse/file.c
@@ -417,6 +417,15 @@ static int fuse_flush(struct file *file,
 	fuse_sync_writes(inode);
 	mutex_unlock(&inode->i_mutex);
 
+	if (test_bit(AS_ENOSPC, &file->f_mapping->flags) &&
+	    test_and_clear_bit(AS_ENOSPC, &file->f_mapping->flags))
+		err = -ENOSPC;
+	if (test_bit(AS_EIO, &file->f_mapping->flags) &&
+	    test_and_clear_bit(AS_EIO, &file->f_mapping->flags))
+		err = -EIO;
+	if (err)
+		return err;
+
 	req = fuse_get_req_nofail_nopages(fc, file);
 	memset(&inarg, 0, sizeof(inarg));
 	inarg.fh = ff->fh;
@@ -462,6 +471,21 @@ int fuse_fsync_common(struct file *file,
 		goto out;
 
 	fuse_sync_writes(inode);
+
+	/*
+	 * Due to implementation of fuse writeback
+	 * filemap_write_and_wait_range() does not catch errors.
+	 * We have to do this directly after fuse_sync_writes()
+	 */
+	if (test_bit(AS_ENOSPC, &file->f_mapping->flags) &&
+	    test_and_clear_bit(AS_ENOSPC, &file->f_mapping->flags))
+		err = -ENOSPC;
+	if (test_bit(AS_EIO, &file->f_mapping->flags) &&
+	    test_and_clear_bit(AS_EIO, &file->f_mapping->flags))
+		err = -EIO;
+	if (err)
+		goto out;
+
 	err = sync_inode_metadata(inode, 1);
 	if (err)
 		goto out;
@@ -516,18 +540,23 @@ void fuse_read_fill(struct fuse_req *req
 	req->out.args[0].size = count;
 }
 
-static void fuse_release_user_pages(struct fuse_req *req, int write)
+static void fuse_release_user_pages(struct fuse_req *req, bool should_dirty)
 {
 	unsigned i;
 
 	for (i = 0; i < req->num_pages; i++) {
 		struct page *page = req->pages[i];
-		if (write)
+		if (should_dirty)
 			set_page_dirty_lock(page);
 		put_page(page);
 	}
 }
 
+static void fuse_io_release(struct kref *kref)
+{
+	kfree(container_of(kref, struct fuse_io_priv, refcnt));
+}
+
 static ssize_t fuse_get_res_by_io(struct fuse_io_priv *io)
 {
 	if (io->err)
@@ -585,8 +614,9 @@ static void fuse_aio_complete(struct fus
 		}
 
 		io->iocb->ki_complete(io->iocb, res, 0);
-		kfree(io);
 	}
+
+	kref_put(&io->refcnt, fuse_io_release);
 }
 
 static void fuse_aio_complete_req(struct fuse_conn *fc, struct fuse_req *req)
@@ -613,6 +643,7 @@ static size_t fuse_async_req_send(struct
 		size_t num_bytes, struct fuse_io_priv *io)
 {
 	spin_lock(&io->lock);
+	kref_get(&io->refcnt);
 	io->size += num_bytes;
 	io->reqs++;
 	spin_unlock(&io->lock);
@@ -691,7 +722,7 @@ static void fuse_short_read(struct fuse_
 
 static int fuse_do_readpage(struct file *file, struct page *page)
 {
-	struct fuse_io_priv io = { .async = 0, .file = file };
+	struct fuse_io_priv io = FUSE_IO_PRIV_SYNC(file);
 	struct inode *inode = page->mapping->host;
 	struct fuse_conn *fc = get_fuse_conn(inode);
 	struct fuse_req *req;
@@ -984,7 +1015,7 @@ static size_t fuse_send_write_pages(stru
 	size_t res;
 	unsigned offset;
 	unsigned i;
-	struct fuse_io_priv io = { .async = 0, .file = file };
+	struct fuse_io_priv io = FUSE_IO_PRIV_SYNC(file);
 
 	for (i = 0; i < req->num_pages; i++)
 		fuse_wait_on_page_writeback(inode, req->pages[i]->index);
@@ -1300,6 +1331,7 @@ ssize_t fuse_direct_io(struct fuse_io_pr
 		       loff_t *ppos, int flags)
 {
 	int write = flags & FUSE_DIO_WRITE;
+	bool should_dirty = !write && iter_is_iovec(iter);
 	int cuse = flags & FUSE_DIO_CUSE;
 	struct file *file = io->file;
 	struct inode *inode = file->f_mapping->host;
@@ -1344,7 +1376,7 @@ ssize_t fuse_direct_io(struct fuse_io_pr
 			nres = fuse_send_read(req, io, pos, nbytes, owner);
 
 		if (!io->async)
-			fuse_release_user_pages(req, !write);
+			fuse_release_user_pages(req, should_dirty);
 		if (req->out.h.error) {
 			if (!res)
 				res = req->out.h.error;
@@ -1398,7 +1430,7 @@ static ssize_t __fuse_direct_read(struct
 
 static ssize_t fuse_direct_read_iter(struct kiocb *iocb, struct iov_iter *to)
 {
-	struct fuse_io_priv io = { .async = 0, .file = iocb->ki_filp };
+	struct fuse_io_priv io = FUSE_IO_PRIV_SYNC(iocb->ki_filp);
 	return __fuse_direct_read(&io, to, &iocb->ki_pos);
 }
 
@@ -1406,7 +1438,7 @@ static ssize_t fuse_direct_write_iter(st
 {
 	struct file *file = iocb->ki_filp;
 	struct inode *inode = file_inode(file);
-	struct fuse_io_priv io = { .async = 0, .file = file };
+	struct fuse_io_priv io = FUSE_IO_PRIV_SYNC(file);
 	ssize_t res;
 
 	if (is_bad_inode(inode))
@@ -2061,7 +2093,8 @@ static int fuse_direct_mmap(struct file
 	return generic_file_mmap(file, vma);
 }
 
-static int convert_fuse_file_lock(const struct fuse_file_lock *ffl,
+static int convert_fuse_file_lock(struct fuse_conn *fc,
+				  const struct fuse_file_lock *ffl,
 				  struct file_lock *fl)
 {
 	switch (ffl->type) {
@@ -2076,7 +2109,14 @@ static int convert_fuse_file_lock(const
 
 		fl->fl_start = ffl->start;
 		fl->fl_end = ffl->end;
-		fl->fl_pid = ffl->pid;
+
+		/*
+		 * Convert pid into the caller's pid namespace. If the pid
+		 * does not map into the namespace fl_pid will get set to 0.
+		 */
+		rcu_read_lock();
+		fl->fl_pid = pid_vnr(find_pid_ns(ffl->pid, fc->pid_ns));
+		rcu_read_unlock();
 		break;
 
 	default:
@@ -2125,7 +2165,7 @@ static int fuse_getlk(struct file *file,
 	args.out.args[0].value = &outarg;
 	err = fuse_simple_request(fc, &args);
 	if (!err)
-		err = convert_fuse_file_lock(&outarg.lk, fl);
+		err = convert_fuse_file_lock(fc, &outarg.lk, fl);
 
 	return err;
 }
@@ -2137,7 +2177,8 @@ static int fuse_setlk(struct file *file,
 	FUSE_ARGS(args);
 	struct fuse_lk_in inarg;
 	int opcode = (fl->fl_flags & FL_SLEEP) ? FUSE_SETLKW : FUSE_SETLK;
-	pid_t pid = fl->fl_type != F_UNLCK ? current->tgid : 0;
+	struct pid *pid = fl->fl_type != F_UNLCK ? task_tgid(current) : NULL;
+	pid_t pid_nr = pid_nr_ns(pid, fc->pid_ns);
 	int err;
 
 	if (fl->fl_lmops && fl->fl_lmops->lm_grant) {
@@ -2149,7 +2190,10 @@ static int fuse_setlk(struct file *file,
 	if (fl->fl_flags & FL_CLOSE)
 		return 0;
 
-	fuse_lk_fill(&args, file, fl, opcode, pid, flock, &inarg);
+	if (pid && pid_nr == 0)
+		return -EOVERFLOW;
+
+	fuse_lk_fill(&args, file, fl, opcode, pid_nr, flock, &inarg);
 	err = fuse_simple_request(fc, &args);
 
 	/* locking is restartable */
@@ -2786,6 +2830,7 @@ fuse_direct_IO(struct kiocb *iocb, struc
 	loff_t i_size;
 	size_t count = iov_iter_count(iter);
 	struct fuse_io_priv *io;
+	bool is_sync = is_sync_kiocb(iocb);
 
 	pos = offset;
 	inode = file->f_mapping->host;
@@ -2806,6 +2851,7 @@ fuse_direct_IO(struct kiocb *iocb, struc
 	if (!io)
 		return -ENOMEM;
 	spin_lock_init(&io->lock);
+	kref_init(&io->refcnt);
 	io->reqs = 1;
 	io->bytes = -1;
 	io->size = 0;
@@ -2825,12 +2871,18 @@ fuse_direct_IO(struct kiocb *iocb, struc
 	 * to wait on real async I/O requests, so we must submit this request
 	 * synchronously.
 	 */
-	if (!is_sync_kiocb(iocb) && (offset + count > i_size) &&
+	if (!is_sync && (offset + count > i_size) &&
 	    iov_iter_rw(iter) == WRITE)
 		io->async = false;
 
-	if (io->async && is_sync_kiocb(iocb))
+	if (io->async && is_sync) {
+		/*
+		 * Additional reference to keep io around after
+		 * calling fuse_aio_complete()
+		 */
+		kref_get(&io->refcnt);
 		io->done = &wait;
+	}
 
 	if (iov_iter_rw(iter) == WRITE) {
 		ret = fuse_direct_io(io, iter, &pos, FUSE_DIO_WRITE);
@@ -2843,14 +2895,14 @@ fuse_direct_IO(struct kiocb *iocb, struc
 		fuse_aio_complete(io, ret < 0 ? ret : 0, -1);
 
 		/* we have a non-extending, async request, so return */
-		if (!is_sync_kiocb(iocb))
+		if (!is_sync)
 			return -EIOCBQUEUED;
 
 		wait_for_completion(&wait);
 		ret = fuse_get_res_by_io(io);
 	}
 
-	kfree(io);
+	kref_put(&io->refcnt, fuse_io_release);
 
 	if (iov_iter_rw(iter) == WRITE) {
 		if (ret > 0)
--- zfcpdump-kernel-4.4.orig/fs/fuse/fuse_i.h
+++ zfcpdump-kernel-4.4/fs/fuse/fuse_i.h
@@ -22,6 +22,9 @@
 #include <linux/rbtree.h>
 #include <linux/poll.h>
 #include <linux/workqueue.h>
+#include <linux/pid_namespace.h>
+#include <linux/user_namespace.h>
+#include <linux/kref.h>
 
 /** Max number of pages that can be used in a single read request */
 #define FUSE_MAX_PAGES_PER_REQ 32
@@ -243,6 +246,7 @@ struct fuse_args {
 
 /** The request IO state (for asynchronous processing) */
 struct fuse_io_priv {
+	struct kref refcnt;
 	int async;
 	spinlock_t lock;
 	unsigned reqs;
@@ -256,6 +260,13 @@ struct fuse_io_priv {
 	struct completion *done;
 };
 
+#define FUSE_IO_PRIV_SYNC(f) \
+{					\
+	.refcnt = { ATOMIC_INIT(1) },	\
+	.async = 0,			\
+	.file = f,			\
+}
+
 /**
  * Request flags
  *
@@ -456,6 +467,12 @@ struct fuse_conn {
 	/** The group id for this mount */
 	kgid_t group_id;
 
+	/** The pid namespace for this mount */
+	struct pid_namespace *pid_ns;
+
+	/** The user namespace for this mount */
+	struct user_namespace *user_ns;
+
 	/** The fuse mount flags for this mount */
 	unsigned flags;
 
@@ -851,7 +868,7 @@ struct fuse_conn *fuse_conn_get(struct f
 /**
  * Initialize fuse_conn
  */
-void fuse_conn_init(struct fuse_conn *fc);
+void fuse_conn_init(struct fuse_conn *fc, struct user_namespace *user_ns);
 
 /**
  * Release reference to fuse_conn
--- zfcpdump-kernel-4.4.orig/fs/fuse/inode.c
+++ zfcpdump-kernel-4.4/fs/fuse/inode.c
@@ -20,6 +20,7 @@
 #include <linux/random.h>
 #include <linux/sched.h>
 #include <linux/exportfs.h>
+#include <linux/pid_namespace.h>
 
 MODULE_AUTHOR("Miklos Szeredi <miklos@szeredi.hu>");
 MODULE_DESCRIPTION("Filesystem in Userspace");
@@ -47,6 +48,10 @@ MODULE_PARM_DESC(max_user_congthresh,
  "Global limit for the maximum congestion threshold an "
  "unprivileged user can set");
 
+static bool userns_mounts;
+module_param(userns_mounts, bool, 0644);
+MODULE_PARM_DESC(userns_mounts, "Allow mounts from unprivileged user namespaces");
+
 #define FUSE_SUPER_MAGIC 0x65735546
 
 #define FUSE_DEFAULT_BLKSIZE 512
@@ -166,8 +171,8 @@ void fuse_change_attributes_common(struc
 	inode->i_ino     = fuse_squash_ino(attr->ino);
 	inode->i_mode    = (inode->i_mode & S_IFMT) | (attr->mode & 07777);
 	set_nlink(inode, attr->nlink);
-	inode->i_uid     = make_kuid(&init_user_ns, attr->uid);
-	inode->i_gid     = make_kgid(&init_user_ns, attr->gid);
+	inode->i_uid     = make_kuid(fc->user_ns, attr->uid);
+	inode->i_gid     = make_kgid(fc->user_ns, attr->gid);
 	inode->i_blocks  = attr->blocks;
 	inode->i_atime.tv_sec   = attr->atime;
 	inode->i_atime.tv_nsec  = attr->atimensec;
@@ -466,7 +471,8 @@ static int fuse_match_uint(substring_t *
 	return err;
 }
 
-static int parse_fuse_opt(char *opt, struct fuse_mount_data *d, int is_bdev)
+static int parse_fuse_opt(char *opt, struct fuse_mount_data *d, int is_bdev,
+			  struct user_namespace *user_ns)
 {
 	char *p;
 	memset(d, 0, sizeof(struct fuse_mount_data));
@@ -502,7 +508,7 @@ static int parse_fuse_opt(char *opt, str
 		case OPT_USER_ID:
 			if (fuse_match_uint(&args[0], &uv))
 				return 0;
-			d->user_id = make_kuid(current_user_ns(), uv);
+			d->user_id = make_kuid(user_ns, uv);
 			if (!uid_valid(d->user_id))
 				return 0;
 			d->user_id_present = 1;
@@ -511,7 +517,7 @@ static int parse_fuse_opt(char *opt, str
 		case OPT_GROUP_ID:
 			if (fuse_match_uint(&args[0], &uv))
 				return 0;
-			d->group_id = make_kgid(current_user_ns(), uv);
+			d->group_id = make_kgid(user_ns, uv);
 			if (!gid_valid(d->group_id))
 				return 0;
 			d->group_id_present = 1;
@@ -554,8 +560,10 @@ static int fuse_show_options(struct seq_
 	struct super_block *sb = root->d_sb;
 	struct fuse_conn *fc = get_fuse_conn_super(sb);
 
-	seq_printf(m, ",user_id=%u", from_kuid_munged(&init_user_ns, fc->user_id));
-	seq_printf(m, ",group_id=%u", from_kgid_munged(&init_user_ns, fc->group_id));
+	seq_printf(m, ",user_id=%u",
+		   from_kuid_munged(fc->user_ns, fc->user_id));
+	seq_printf(m, ",group_id=%u",
+		   from_kgid_munged(fc->user_ns, fc->group_id));
 	if (fc->flags & FUSE_DEFAULT_PERMISSIONS)
 		seq_puts(m, ",default_permissions");
 	if (fc->flags & FUSE_ALLOW_OTHER)
@@ -586,7 +594,7 @@ static void fuse_pqueue_init(struct fuse
 	fpq->connected = 1;
 }
 
-void fuse_conn_init(struct fuse_conn *fc)
+void fuse_conn_init(struct fuse_conn *fc, struct user_namespace *user_ns)
 {
 	memset(fc, 0, sizeof(*fc));
 	spin_lock_init(&fc->lock);
@@ -609,6 +617,8 @@ void fuse_conn_init(struct fuse_conn *fc
 	fc->connected = 1;
 	fc->attr_version = 1;
 	get_random_bytes(&fc->scramble_key, sizeof(fc->scramble_key));
+	fc->pid_ns = get_pid_ns(task_active_pid_ns(current));
+	fc->user_ns = get_user_ns(user_ns);
 }
 EXPORT_SYMBOL_GPL(fuse_conn_init);
 
@@ -617,6 +627,8 @@ void fuse_conn_put(struct fuse_conn *fc)
 	if (atomic_dec_and_test(&fc->count)) {
 		if (fc->destroy_req)
 			fuse_request_free(fc->destroy_req);
+		put_pid_ns(fc->pid_ns);
+		put_user_ns(fc->user_ns);
 		fc->release(fc);
 	}
 }
@@ -926,7 +938,7 @@ static void fuse_send_init(struct fuse_c
 	arg->flags |= FUSE_ASYNC_READ | FUSE_POSIX_LOCKS | FUSE_ATOMIC_O_TRUNC |
 		FUSE_EXPORT_SUPPORT | FUSE_BIG_WRITES | FUSE_DONT_MASK |
 		FUSE_SPLICE_WRITE | FUSE_SPLICE_MOVE | FUSE_SPLICE_READ |
-		FUSE_FLOCK_LOCKS | FUSE_IOCTL_DIR | FUSE_AUTO_INVAL_DATA |
+		FUSE_FLOCK_LOCKS | FUSE_HAS_IOCTL_DIR | FUSE_AUTO_INVAL_DATA |
 		FUSE_DO_READDIRPLUS | FUSE_READDIRPLUS_AUTO | FUSE_ASYNC_DIO |
 		FUSE_WRITEBACK_CACHE | FUSE_NO_OPEN_SUPPORT;
 	req->in.h.opcode = FUSE_INIT;
@@ -1037,13 +1049,16 @@ static int fuse_fill_super(struct super_
 	int err;
 	int is_bdev = sb->s_bdev != NULL;
 
+	if (!userns_mounts && !capable(CAP_SYS_ADMIN))
+		return -EPERM;
+
 	err = -EINVAL;
 	if (sb->s_flags & MS_MANDLOCK)
 		goto err;
 
 	sb->s_flags &= ~(MS_NOSEC | MS_I_VERSION);
 
-	if (!parse_fuse_opt(data, &d, is_bdev))
+	if (!parse_fuse_opt(data, &d, is_bdev, sb->s_user_ns))
 		goto err;
 
 	if (is_bdev) {
@@ -1067,8 +1082,12 @@ static int fuse_fill_super(struct super_
 	if (!file)
 		goto err;
 
-	if ((file->f_op != &fuse_dev_operations) ||
-	    (file->f_cred->user_ns != &init_user_ns))
+	/*
+	 * Require mount to happen from the same user namespace which
+	 * opened /dev/fuse to prevent potential attacks.
+	 */
+	if (file->f_op != &fuse_dev_operations ||
+	    file->f_cred->user_ns != sb->s_user_ns)
 		goto err_fput;
 
 	fc = kmalloc(sizeof(*fc), GFP_KERNEL);
@@ -1076,7 +1095,7 @@ static int fuse_fill_super(struct super_
 	if (!fc)
 		goto err_fput;
 
-	fuse_conn_init(fc);
+	fuse_conn_init(fc, sb->s_user_ns);
 	fc->release = fuse_free_conn;
 
 	fud = fuse_dev_alloc(fc);
@@ -1187,7 +1206,7 @@ static void fuse_kill_sb_anon(struct sup
 static struct file_system_type fuse_fs_type = {
 	.owner		= THIS_MODULE,
 	.name		= "fuse",
-	.fs_flags	= FS_HAS_SUBTYPE,
+	.fs_flags	= FS_HAS_SUBTYPE | FS_USERNS_MOUNT,
 	.mount		= fuse_mount,
 	.kill_sb	= fuse_kill_sb_anon,
 };
@@ -1219,7 +1238,7 @@ static struct file_system_type fuseblk_f
 	.name		= "fuseblk",
 	.mount		= fuse_mount_blk,
 	.kill_sb	= fuse_kill_sb_blk,
-	.fs_flags	= FS_REQUIRES_DEV | FS_HAS_SUBTYPE,
+	.fs_flags	= FS_REQUIRES_DEV | FS_HAS_SUBTYPE | FS_USERNS_MOUNT,
 };
 MODULE_ALIAS_FS("fuseblk");
 
--- zfcpdump-kernel-4.4.orig/fs/hostfs/hostfs_kern.c
+++ zfcpdump-kernel-4.4/fs/hostfs/hostfs_kern.c
@@ -730,15 +730,13 @@ static int hostfs_mknod(struct inode *di
 
 	init_special_inode(inode, mode, dev);
 	err = do_mknod(name, mode, MAJOR(dev), MINOR(dev));
-	if (!err)
+	if (err)
 		goto out_free;
 
 	err = read_name(inode, name);
 	__putname(name);
 	if (err)
 		goto out_put;
-	if (err)
-		goto out_put;
 
 	d_instantiate(dentry, inode);
 	return 0;
@@ -961,10 +959,11 @@ static int hostfs_fill_sb_common(struct
 
 	if (S_ISLNK(root_inode->i_mode)) {
 		char *name = follow_link(host_root_path);
-		if (IS_ERR(name))
+		if (IS_ERR(name)) {
 			err = PTR_ERR(name);
-		else
-			err = read_name(root_inode, name);
+			goto out_put;
+		}
+		err = read_name(root_inode, name);
 		kfree(name);
 		if (err)
 			goto out_put;
--- zfcpdump-kernel-4.4.orig/fs/hpfs/namei.c
+++ zfcpdump-kernel-4.4/fs/hpfs/namei.c
@@ -375,12 +375,11 @@ static int hpfs_unlink(struct inode *dir
 	struct inode *inode = d_inode(dentry);
 	dnode_secno dno;
 	int r;
-	int rep = 0;
 	int err;
 
 	hpfs_lock(dir->i_sb);
 	hpfs_adjust_length(name, &len);
-again:
+
 	err = -ENOENT;
 	de = map_dirent(dir, hpfs_i(dir)->i_dno, name, len, &dno, &qbh);
 	if (!de)
@@ -400,33 +399,9 @@ again:
 		hpfs_error(dir->i_sb, "there was error when removing dirent");
 		err = -EFSERROR;
 		break;
-	case 2:		/* no space for deleting, try to truncate file */
-
+	case 2:		/* no space for deleting */
 		err = -ENOSPC;
-		if (rep++)
-			break;
-
-		dentry_unhash(dentry);
-		if (!d_unhashed(dentry)) {
-			hpfs_unlock(dir->i_sb);
-			return -ENOSPC;
-		}
-		if (generic_permission(inode, MAY_WRITE) ||
-		    !S_ISREG(inode->i_mode) ||
-		    get_write_access(inode)) {
-			d_rehash(dentry);
-		} else {
-			struct iattr newattrs;
-			/*pr_info("truncating file before delete.\n");*/
-			newattrs.ia_size = 0;
-			newattrs.ia_valid = ATTR_SIZE | ATTR_CTIME;
-			err = notify_change(dentry, &newattrs, NULL);
-			put_write_access(inode);
-			if (!err)
-				goto again;
-		}
-		hpfs_unlock(dir->i_sb);
-		return -ENOSPC;
+		break;
 	default:
 		drop_nlink(inode);
 		err = 0;
--- zfcpdump-kernel-4.4.orig/fs/hpfs/super.c
+++ zfcpdump-kernel-4.4/fs/hpfs/super.c
@@ -15,6 +15,7 @@
 #include <linux/sched.h>
 #include <linux/bitmap.h>
 #include <linux/slab.h>
+#include <linux/seq_file.h>
 
 /* Mark the filesystem dirty, so that chkdsk checks it when os/2 booted */
 
@@ -453,10 +454,6 @@ static int hpfs_remount_fs(struct super_
 	int lowercase, eas, chk, errs, chkdsk, timeshift;
 	int o;
 	struct hpfs_sb_info *sbi = hpfs_sb(s);
-	char *new_opts = kstrdup(data, GFP_KERNEL);
-
-	if (!new_opts)
-		return -ENOMEM;
 
 	sync_filesystem(s);
 
@@ -493,17 +490,44 @@ static int hpfs_remount_fs(struct super_
 
 	if (!(*flags & MS_RDONLY)) mark_dirty(s, 1);
 
-	replace_mount_options(s, new_opts);
-
 	hpfs_unlock(s);
 	return 0;
 
 out_err:
 	hpfs_unlock(s);
-	kfree(new_opts);
 	return -EINVAL;
 }
 
+static int hpfs_show_options(struct seq_file *seq, struct dentry *root)
+{
+	struct hpfs_sb_info *sbi = hpfs_sb(root->d_sb);
+
+	seq_printf(seq, ",uid=%u", from_kuid_munged(&init_user_ns, sbi->sb_uid));
+	seq_printf(seq, ",gid=%u", from_kgid_munged(&init_user_ns, sbi->sb_gid));
+	seq_printf(seq, ",umask=%03o", (~sbi->sb_mode & 0777));
+	if (sbi->sb_lowercase)
+		seq_printf(seq, ",case=lower");
+	if (!sbi->sb_chk)
+		seq_printf(seq, ",check=none");
+	if (sbi->sb_chk == 2)
+		seq_printf(seq, ",check=strict");
+	if (!sbi->sb_err)
+		seq_printf(seq, ",errors=continue");
+	if (sbi->sb_err == 2)
+		seq_printf(seq, ",errors=panic");
+	if (!sbi->sb_chkdsk)
+		seq_printf(seq, ",chkdsk=no");
+	if (sbi->sb_chkdsk == 2)
+		seq_printf(seq, ",chkdsk=always");
+	if (!sbi->sb_eas)
+		seq_printf(seq, ",eas=no");
+	if (sbi->sb_eas == 1)
+		seq_printf(seq, ",eas=ro");
+	if (sbi->sb_timeshift)
+		seq_printf(seq, ",timeshift=%d", sbi->sb_timeshift);
+	return 0;
+}
+
 /* Super operations */
 
 static const struct super_operations hpfs_sops =
@@ -514,7 +538,7 @@ static const struct super_operations hpf
 	.put_super	= hpfs_put_super,
 	.statfs		= hpfs_statfs,
 	.remount_fs	= hpfs_remount_fs,
-	.show_options	= generic_show_options,
+	.show_options	= hpfs_show_options,
 };
 
 static int hpfs_fill_super(struct super_block *s, void *options, int silent)
@@ -537,8 +561,6 @@ static int hpfs_fill_super(struct super_
 
 	int o;
 
-	save_mount_options(s, options);
-
 	sbi = kzalloc(sizeof(*sbi), GFP_KERNEL);
 	if (!sbi) {
 		return -ENOMEM;
--- zfcpdump-kernel-4.4.orig/fs/hugetlbfs/inode.c
+++ zfcpdump-kernel-4.4/fs/hugetlbfs/inode.c
@@ -463,6 +463,7 @@ hugetlb_vmdelete_list(struct rb_root *ro
 	 */
 	vma_interval_tree_foreach(vma, root, start, end ? end : ULONG_MAX) {
 		unsigned long v_offset;
+		unsigned long v_end;
 
 		/*
 		 * Can the expression below overflow on 32-bit arches?
@@ -475,15 +476,17 @@ hugetlb_vmdelete_list(struct rb_root *ro
 		else
 			v_offset = 0;
 
-		if (end) {
-			end = ((end - start) << PAGE_SHIFT) +
-			       vma->vm_start + v_offset;
-			if (end > vma->vm_end)
-				end = vma->vm_end;
-		} else
-			end = vma->vm_end;
+		if (!end)
+			v_end = vma->vm_end;
+		else {
+			v_end = ((end - vma->vm_pgoff) << PAGE_SHIFT)
+							+ vma->vm_start;
+			if (v_end > vma->vm_end)
+				v_end = vma->vm_end;
+		}
 
-		unmap_hugepage_range(vma, vma->vm_start + v_offset, end, NULL);
+		unmap_hugepage_range(vma, vma->vm_start + v_offset, v_end,
+									NULL);
 	}
 }
 
--- zfcpdump-kernel-4.4.orig/fs/inode.c
+++ zfcpdump-kernel-4.4/fs/inode.c
@@ -1684,7 +1684,8 @@ int should_remove_suid(struct dentry *de
 	if (unlikely((mode & S_ISGID) && (mode & S_IXGRP)))
 		kill |= ATTR_KILL_SGID;
 
-	if (unlikely(kill && !capable(CAP_FSETID) && S_ISREG(mode)))
+	if (unlikely(kill && !ns_capable(dentry->d_sb->s_user_ns, CAP_FSETID) &&
+		     S_ISREG(mode)))
 		return kill;
 
 	return 0;
@@ -1733,8 +1734,8 @@ static int __remove_privs(struct dentry
  */
 int file_remove_privs(struct file *file)
 {
-	struct dentry *dentry = file->f_path.dentry;
-	struct inode *inode = d_inode(dentry);
+	struct dentry *dentry = file_dentry(file);
+	struct inode *inode = file_inode(file);
 	int kill;
 	int error = 0;
 
@@ -1742,7 +1743,7 @@ int file_remove_privs(struct file *file)
 	if (IS_NOSEC(inode))
 		return 0;
 
-	kill = file_needs_remove_privs(file);
+	kill = dentry_needs_remove_privs(dentry);
 	if (kill < 0)
 		return kill;
 	if (kill)
--- zfcpdump-kernel-4.4.orig/fs/ioctl.c
+++ zfcpdump-kernel-4.4/fs/ioctl.c
@@ -519,7 +519,7 @@ static int ioctl_fsfreeze(struct file *f
 {
 	struct super_block *sb = file_inode(filp)->i_sb;
 
-	if (!capable(CAP_SYS_ADMIN))
+	if (!ns_capable(sb->s_user_ns, CAP_SYS_ADMIN))
 		return -EPERM;
 
 	/* If filesystem doesn't support freeze feature, return. */
@@ -536,7 +536,7 @@ static int ioctl_fsthaw(struct file *fil
 {
 	struct super_block *sb = file_inode(filp)->i_sb;
 
-	if (!capable(CAP_SYS_ADMIN))
+	if (!ns_capable(sb->s_user_ns, CAP_SYS_ADMIN))
 		return -EPERM;
 
 	/* Thaw */
--- zfcpdump-kernel-4.4.orig/fs/isofs/rock.c
+++ zfcpdump-kernel-4.4/fs/isofs/rock.c
@@ -203,6 +203,8 @@ int get_rock_ridge_filename(struct iso_d
 	int retnamlen = 0;
 	int truncate = 0;
 	int ret = 0;
+	char *p;
+	int len;
 
 	if (!ISOFS_SB(inode->i_sb)->s_rock)
 		return 0;
@@ -267,12 +269,17 @@ repeat:
 					rr->u.NM.flags);
 				break;
 			}
-			if ((strlen(retname) + rr->len - 5) >= 254) {
+			len = rr->len - 5;
+			if (retnamlen + len >= 254) {
 				truncate = 1;
 				break;
 			}
-			strncat(retname, rr->u.NM.name, rr->len - 5);
-			retnamlen += rr->len - 5;
+			p = memchr(rr->u.NM.name, '\0', len);
+			if (unlikely(p))
+				len = p - rr->u.NM.name;
+			memcpy(retname + retnamlen, rr->u.NM.name, len);
+			retnamlen += len;
+			retname[retnamlen] = '\0';
 			break;
 		case SIG('R', 'E'):
 			kfree(rs.buffer);
--- zfcpdump-kernel-4.4.orig/fs/jbd2/commit.c
+++ zfcpdump-kernel-4.4/fs/jbd2/commit.c
@@ -124,7 +124,7 @@ static int journal_submit_commit_record(
 	struct commit_header *tmp;
 	struct buffer_head *bh;
 	int ret;
-	struct timespec now = current_kernel_time();
+	struct timespec64 now = current_kernel_time64();
 
 	*cbh = NULL;
 
--- zfcpdump-kernel-4.4.orig/fs/jbd2/journal.c
+++ zfcpdump-kernel-4.4/fs/jbd2/journal.c
@@ -1408,11 +1408,12 @@ out:
 /**
  * jbd2_mark_journal_empty() - Mark on disk journal as empty.
  * @journal: The journal to update.
+ * @write_op: With which operation should we write the journal sb
  *
  * Update a journal's dynamic superblock fields to show that journal is empty.
  * Write updated superblock to disk waiting for IO to complete.
  */
-static void jbd2_mark_journal_empty(journal_t *journal)
+static void jbd2_mark_journal_empty(journal_t *journal, int write_op)
 {
 	journal_superblock_t *sb = journal->j_superblock;
 
@@ -1430,7 +1431,7 @@ static void jbd2_mark_journal_empty(jour
 	sb->s_start    = cpu_to_be32(0);
 	read_unlock(&journal->j_state_lock);
 
-	jbd2_write_superblock(journal, WRITE_FUA);
+	jbd2_write_superblock(journal, write_op);
 
 	/* Log is no longer empty */
 	write_lock(&journal->j_state_lock);
@@ -1716,7 +1717,13 @@ int jbd2_journal_destroy(journal_t *jour
 	if (journal->j_sb_buffer) {
 		if (!is_journal_aborted(journal)) {
 			mutex_lock(&journal->j_checkpoint_mutex);
-			jbd2_mark_journal_empty(journal);
+
+			write_lock(&journal->j_state_lock);
+			journal->j_tail_sequence =
+				++journal->j_transaction_sequence;
+			write_unlock(&journal->j_state_lock);
+
+			jbd2_mark_journal_empty(journal, WRITE_FLUSH_FUA);
 			mutex_unlock(&journal->j_checkpoint_mutex);
 		} else
 			err = -EIO;
@@ -1975,7 +1982,7 @@ int jbd2_journal_flush(journal_t *journa
 	 * the magic code for a fully-recovered superblock.  Any future
 	 * commits of data to the journal will restore the current
 	 * s_start value. */
-	jbd2_mark_journal_empty(journal);
+	jbd2_mark_journal_empty(journal, WRITE_FUA);
 	mutex_unlock(&journal->j_checkpoint_mutex);
 	write_lock(&journal->j_state_lock);
 	J_ASSERT(!journal->j_running_transaction);
@@ -2021,7 +2028,7 @@ int jbd2_journal_wipe(journal_t *journal
 	if (write) {
 		/* Lock to make assertions happy... */
 		mutex_lock(&journal->j_checkpoint_mutex);
-		jbd2_mark_journal_empty(journal);
+		jbd2_mark_journal_empty(journal, WRITE_FUA);
 		mutex_unlock(&journal->j_checkpoint_mutex);
 	}
 
--- zfcpdump-kernel-4.4.orig/fs/jffs2/README.Locking
+++ zfcpdump-kernel-4.4/fs/jffs2/README.Locking
@@ -2,10 +2,6 @@
 	JFFS2 LOCKING DOCUMENTATION
 	---------------------------
 
-At least theoretically, JFFS2 does not require the Big Kernel Lock
-(BKL), which was always helpfully obtained for it by Linux 2.4 VFS
-code. It has its own locking, as described below.
-
 This document attempts to describe the existing locking rules for
 JFFS2. It is not expected to remain perfectly up to date, but ought to
 be fairly close.
@@ -69,6 +65,7 @@ Ordering constraints:
 	   any f->sem held.
 	2. Never attempt to lock two file mutexes in one thread.
 	   No ordering rules have been made for doing so.
+	3. Never lock a page cache page with f->sem held.
 
 
 	erase_completion_lock spinlock
--- zfcpdump-kernel-4.4.orig/fs/jffs2/build.c
+++ zfcpdump-kernel-4.4/fs/jffs2/build.c
@@ -49,7 +49,8 @@ next_inode(int *i, struct jffs2_inode_ca
 
 
 static void jffs2_build_inode_pass1(struct jffs2_sb_info *c,
-				    struct jffs2_inode_cache *ic)
+				    struct jffs2_inode_cache *ic,
+				    int *dir_hardlinks)
 {
 	struct jffs2_full_dirent *fd;
 
@@ -68,19 +69,21 @@ static void jffs2_build_inode_pass1(stru
 			dbg_fsbuild("child \"%s\" (ino #%u) of dir ino #%u doesn't exist!\n",
 				  fd->name, fd->ino, ic->ino);
 			jffs2_mark_node_obsolete(c, fd->raw);
+			/* Clear the ic/raw union so it doesn't cause problems later. */
+			fd->ic = NULL;
 			continue;
 		}
 
+		/* From this point, fd->raw is no longer used so we can set fd->ic */
+		fd->ic = child_ic;
+		child_ic->pino_nlink++;
+		/* If we appear (at this stage) to have hard-linked directories,
+		 * set a flag to trigger a scan later */
 		if (fd->type == DT_DIR) {
-			if (child_ic->pino_nlink) {
-				JFFS2_ERROR("child dir \"%s\" (ino #%u) of dir ino #%u appears to be a hard link\n",
-					    fd->name, fd->ino, ic->ino);
-				/* TODO: What do we do about it? */
-			} else {
-				child_ic->pino_nlink = ic->ino;
-			}
-		} else
-			child_ic->pino_nlink++;
+			child_ic->flags |= INO_FLAGS_IS_DIR;
+			if (child_ic->pino_nlink > 1)
+				*dir_hardlinks = 1;
+		}
 
 		dbg_fsbuild("increased nlink for child \"%s\" (ino #%u)\n", fd->name, fd->ino);
 		/* Can't free scan_dents so far. We might need them in pass 2 */
@@ -94,8 +97,7 @@ static void jffs2_build_inode_pass1(stru
 */
 static int jffs2_build_filesystem(struct jffs2_sb_info *c)
 {
-	int ret;
-	int i;
+	int ret, i, dir_hardlinks = 0;
 	struct jffs2_inode_cache *ic;
 	struct jffs2_full_dirent *fd;
 	struct jffs2_full_dirent *dead_fds = NULL;
@@ -119,7 +121,7 @@ static int jffs2_build_filesystem(struct
 	/* Now scan the directory tree, increasing nlink according to every dirent found. */
 	for_each_inode(i, c, ic) {
 		if (ic->scan_dents) {
-			jffs2_build_inode_pass1(c, ic);
+			jffs2_build_inode_pass1(c, ic, &dir_hardlinks);
 			cond_resched();
 		}
 	}
@@ -155,6 +157,20 @@ static int jffs2_build_filesystem(struct
 	}
 
 	dbg_fsbuild("pass 2a complete\n");
+
+	if (dir_hardlinks) {
+		/* If we detected directory hardlinks earlier, *hopefully*
+		 * they are gone now because some of the links were from
+		 * dead directories which still had some old dirents lying
+		 * around and not yet garbage-collected, but which have
+		 * been discarded above. So clear the pino_nlink field
+		 * in each directory, so that the final scan below can
+		 * print appropriate warnings. */
+		for_each_inode(i, c, ic) {
+			if (ic->flags & INO_FLAGS_IS_DIR)
+				ic->pino_nlink = 0;
+		}
+	}
 	dbg_fsbuild("freeing temporary data structures\n");
 
 	/* Finally, we can scan again and free the dirent structs */
@@ -162,6 +178,33 @@ static int jffs2_build_filesystem(struct
 		while(ic->scan_dents) {
 			fd = ic->scan_dents;
 			ic->scan_dents = fd->next;
+			/* We do use the pino_nlink field to count nlink of
+			 * directories during fs build, so set it to the
+			 * parent ino# now. Now that there's hopefully only
+			 * one. */
+			if (fd->type == DT_DIR) {
+				if (!fd->ic) {
+					/* We'll have complained about it and marked the coresponding
+					   raw node obsolete already. Just skip it. */
+					continue;
+				}
+
+				/* We *have* to have set this in jffs2_build_inode_pass1() */
+				BUG_ON(!(fd->ic->flags & INO_FLAGS_IS_DIR));
+
+				/* We clear ic->pino_nlink ∀ directories' ic *only* if dir_hardlinks
+				 * is set. Otherwise, we know this should never trigger anyway, so
+				 * we don't do the check. And ic->pino_nlink still contains the nlink
+				 * value (which is 1). */
+				if (dir_hardlinks && fd->ic->pino_nlink) {
+					JFFS2_ERROR("child dir \"%s\" (ino #%u) of dir ino #%u is also hard linked from dir ino #%u\n",
+						    fd->name, fd->ino, ic->ino, fd->ic->pino_nlink);
+					/* Should we unlink it from its previous parent? */
+				}
+
+				/* For directories, ic->pino_nlink holds that parent inode # */
+				fd->ic->pino_nlink = ic->ino;
+			}
 			jffs2_free_full_dirent(fd);
 		}
 		ic->scan_dents = NULL;
@@ -240,11 +283,7 @@ static void jffs2_build_remove_unlinked_
 
 			/* Reduce nlink of the child. If it's now zero, stick it on the
 			   dead_fds list to be cleaned up later. Else just free the fd */
-
-			if (fd->type == DT_DIR)
-				child_ic->pino_nlink = 0;
-			else
-				child_ic->pino_nlink--;
+			child_ic->pino_nlink--;
 
 			if (!child_ic->pino_nlink) {
 				dbg_fsbuild("inode #%u (\"%s\") now has no links; adding to dead_fds list.\n",
--- zfcpdump-kernel-4.4.orig/fs/jffs2/dir.c
+++ zfcpdump-kernel-4.4/fs/jffs2/dir.c
@@ -843,9 +843,14 @@ static int jffs2_rename (struct inode *o
 
 		pr_notice("%s(): Link succeeded, unlink failed (err %d). You now have a hard link\n",
 			  __func__, ret);
-		/* Might as well let the VFS know */
-		d_instantiate(new_dentry, d_inode(old_dentry));
-		ihold(d_inode(old_dentry));
+		/*
+		 * We can't keep the target in dcache after that.
+		 * For one thing, we can't afford dentry aliases for directories.
+		 * For another, if there was a victim, we _can't_ set new inode
+		 * for that sucker and we have to trigger mount eviction - the
+		 * caller won't do it on its own since we are returning an error.
+		 */
+		d_invalidate(new_dentry);
 		new_dir_i->i_mtime = new_dir_i->i_ctime = ITIME(now);
 		return ret;
 	}
--- zfcpdump-kernel-4.4.orig/fs/jffs2/file.c
+++ zfcpdump-kernel-4.4/fs/jffs2/file.c
@@ -137,39 +137,33 @@ static int jffs2_write_begin(struct file
 	struct page *pg;
 	struct inode *inode = mapping->host;
 	struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
-	struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb);
-	struct jffs2_raw_inode ri;
-	uint32_t alloc_len = 0;
 	pgoff_t index = pos >> PAGE_CACHE_SHIFT;
 	uint32_t pageofs = index << PAGE_CACHE_SHIFT;
 	int ret = 0;
 
-	jffs2_dbg(1, "%s()\n", __func__);
-
-	if (pageofs > inode->i_size) {
-		ret = jffs2_reserve_space(c, sizeof(ri), &alloc_len,
-					  ALLOC_NORMAL, JFFS2_SUMMARY_INODE_SIZE);
-		if (ret)
-			return ret;
-	}
-
-	mutex_lock(&f->sem);
 	pg = grab_cache_page_write_begin(mapping, index, flags);
-	if (!pg) {
-		if (alloc_len)
-			jffs2_complete_reservation(c);
-		mutex_unlock(&f->sem);
+	if (!pg)
 		return -ENOMEM;
-	}
 	*pagep = pg;
 
-	if (alloc_len) {
+	jffs2_dbg(1, "%s()\n", __func__);
+
+	if (pageofs > inode->i_size) {
 		/* Make new hole frag from old EOF to new page */
+		struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb);
+		struct jffs2_raw_inode ri;
 		struct jffs2_full_dnode *fn;
+		uint32_t alloc_len;
 
 		jffs2_dbg(1, "Writing new hole frag 0x%x-0x%x between current EOF and new page\n",
 			  (unsigned int)inode->i_size, pageofs);
 
+		ret = jffs2_reserve_space(c, sizeof(ri), &alloc_len,
+					  ALLOC_NORMAL, JFFS2_SUMMARY_INODE_SIZE);
+		if (ret)
+			goto out_page;
+
+		mutex_lock(&f->sem);
 		memset(&ri, 0, sizeof(ri));
 
 		ri.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
@@ -196,6 +190,7 @@ static int jffs2_write_begin(struct file
 		if (IS_ERR(fn)) {
 			ret = PTR_ERR(fn);
 			jffs2_complete_reservation(c);
+			mutex_unlock(&f->sem);
 			goto out_page;
 		}
 		ret = jffs2_add_full_dnode_to_inode(c, f, fn);
@@ -210,10 +205,12 @@ static int jffs2_write_begin(struct file
 			jffs2_mark_node_obsolete(c, fn->raw);
 			jffs2_free_full_dnode(fn);
 			jffs2_complete_reservation(c);
+			mutex_unlock(&f->sem);
 			goto out_page;
 		}
 		jffs2_complete_reservation(c);
 		inode->i_size = pageofs;
+		mutex_unlock(&f->sem);
 	}
 
 	/*
@@ -222,18 +219,18 @@ static int jffs2_write_begin(struct file
 	 * case of a short-copy.
 	 */
 	if (!PageUptodate(pg)) {
+		mutex_lock(&f->sem);
 		ret = jffs2_do_readpage_nolock(inode, pg);
+		mutex_unlock(&f->sem);
 		if (ret)
 			goto out_page;
 	}
-	mutex_unlock(&f->sem);
 	jffs2_dbg(1, "end write_begin(). pg->flags %lx\n", pg->flags);
 	return ret;
 
 out_page:
 	unlock_page(pg);
 	page_cache_release(pg);
-	mutex_unlock(&f->sem);
 	return ret;
 }
 
--- zfcpdump-kernel-4.4.orig/fs/jffs2/gc.c
+++ zfcpdump-kernel-4.4/fs/jffs2/gc.c
@@ -1296,14 +1296,17 @@ static int jffs2_garbage_collect_dnode(s
 		BUG_ON(start > orig_start);
 	}
 
-	/* First, use readpage() to read the appropriate page into the page cache */
-	/* Q: What happens if we actually try to GC the _same_ page for which commit_write()
-	 *    triggered garbage collection in the first place?
-	 * A: I _think_ it's OK. read_cache_page shouldn't deadlock, we'll write out the
-	 *    page OK. We'll actually write it out again in commit_write, which is a little
-	 *    suboptimal, but at least we're correct.
-	 */
+	/* The rules state that we must obtain the page lock *before* f->sem, so
+	 * drop f->sem temporarily. Since we also hold c->alloc_sem, nothing's
+	 * actually going to *change* so we're safe; we only allow reading.
+	 *
+	 * It is important to note that jffs2_write_begin() will ensure that its
+	 * page is marked Uptodate before allocating space. That means that if we
+	 * end up here trying to GC the *same* page that jffs2_write_begin() is
+	 * trying to write out, read_cache_page() will not deadlock. */
+	mutex_unlock(&f->sem);
 	pg_ptr = jffs2_gc_fetch_page(c, f, start, &pg);
+	mutex_lock(&f->sem);
 
 	if (IS_ERR(pg_ptr)) {
 		pr_warn("read_cache_page() returned error: %ld\n",
--- zfcpdump-kernel-4.4.orig/fs/jffs2/nodelist.h
+++ zfcpdump-kernel-4.4/fs/jffs2/nodelist.h
@@ -194,6 +194,7 @@ struct jffs2_inode_cache {
 #define INO_STATE_CLEARING	6	/* In clear_inode() */
 
 #define INO_FLAGS_XATTR_CHECKED	0x01	/* has no duplicate xattr_ref */
+#define INO_FLAGS_IS_DIR	0x02	/* is a directory */
 
 #define RAWNODE_CLASS_INODE_CACHE	0
 #define RAWNODE_CLASS_XATTR_DATUM	1
@@ -249,7 +250,10 @@ struct jffs2_readinode_info
 
 struct jffs2_full_dirent
 {
-	struct jffs2_raw_node_ref *raw;
+	union {
+		struct jffs2_raw_node_ref *raw;
+		struct jffs2_inode_cache *ic; /* Just during part of build */
+	};
 	struct jffs2_full_dirent *next;
 	uint32_t version;
 	uint32_t ino; /* == zero for unlink */
--- zfcpdump-kernel-4.4.orig/fs/kernfs/dir.c
+++ zfcpdump-kernel-4.4/fs/kernfs/dir.c
@@ -44,28 +44,123 @@ static int kernfs_name_locked(struct ker
 	return strlcpy(buf, kn->parent ? kn->name : "/", buflen);
 }
 
-static char * __must_check kernfs_path_locked(struct kernfs_node *kn, char *buf,
-					      size_t buflen)
+/* kernfs_node_depth - compute depth from @from to @to */
+static size_t kernfs_depth(struct kernfs_node *from, struct kernfs_node *to)
 {
-	char *p = buf + buflen;
-	int len;
+	size_t depth = 0;
 
-	*--p = '\0';
+	while (to->parent && to != from) {
+		depth++;
+		to = to->parent;
+	}
+	return depth;
+}
 
-	do {
-		len = strlen(kn->name);
-		if (p - buf < len + 1) {
-			buf[0] = '\0';
-			p = NULL;
-			break;
-		}
-		p -= len;
-		memcpy(p, kn->name, len);
-		*--p = '/';
-		kn = kn->parent;
-	} while (kn && kn->parent);
+static struct kernfs_node *kernfs_common_ancestor(struct kernfs_node *a,
+						  struct kernfs_node *b)
+{
+	size_t da, db;
+	struct kernfs_root *ra = kernfs_root(a), *rb = kernfs_root(b);
+
+	if (ra != rb)
+		return NULL;
+
+	da = kernfs_depth(ra->kn, a);
+	db = kernfs_depth(rb->kn, b);
+
+	while (da > db) {
+		a = a->parent;
+		da--;
+	}
+	while (db > da) {
+		b = b->parent;
+		db--;
+	}
+
+	/* worst case b and a will be the same at root */
+	while (b != a) {
+		b = b->parent;
+		a = a->parent;
+	}
+
+	return a;
+}
+
+/**
+ * kernfs_path_from_node_locked - find a pseudo-absolute path to @kn_to,
+ * where kn_from is treated as root of the path.
+ * @kn_from: kernfs node which should be treated as root for the path
+ * @kn_to: kernfs node to which path is needed
+ * @buf: buffer to copy the path into
+ * @buflen: size of @buf
+ *
+ * We need to handle couple of scenarios here:
+ * [1] when @kn_from is an ancestor of @kn_to at some level
+ * kn_from: /n1/n2/n3
+ * kn_to:   /n1/n2/n3/n4/n5
+ * result:  /n4/n5
+ *
+ * [2] when @kn_from is on a different hierarchy and we need to find common
+ * ancestor between @kn_from and @kn_to.
+ * kn_from: /n1/n2/n3/n4
+ * kn_to:   /n1/n2/n5
+ * result:  /../../n5
+ * OR
+ * kn_from: /n1/n2/n3/n4/n5   [depth=5]
+ * kn_to:   /n1/n2/n3         [depth=3]
+ * result:  /../..
+ *
+ * return value: length of the string.  If greater than buflen,
+ * then contents of buf are undefined.  On error, -1 is returned.
+ */
+static int
+kernfs_path_from_node_locked(struct kernfs_node *kn_to,
+			     struct kernfs_node *kn_from, char *buf,
+			     size_t buflen)
+{
+	struct kernfs_node *kn, *common;
+	const char parent_str[] = "/..";
+	size_t depth_from, depth_to, len = 0, nlen = 0;
+	char *p;
+	int i;
+
+	if (!kn_from)
+		kn_from = kernfs_root(kn_to)->kn;
+
+	if (kn_from == kn_to)
+		return strlcpy(buf, "/", buflen);
+
+	common = kernfs_common_ancestor(kn_from, kn_to);
+	if (WARN_ON(!common))
+		return -1;
+
+	depth_to = kernfs_depth(common, kn_to);
+	depth_from = kernfs_depth(common, kn_from);
+
+	if (buf)
+		buf[0] = '\0';
+
+	for (i = 0; i < depth_from; i++)
+		len += strlcpy(buf + len, parent_str,
+			       len < buflen ? buflen - len : 0);
 
-	return p;
+	/* Calculate how many bytes we need for the rest */
+	for (kn = kn_to; kn != common; kn = kn->parent)
+		nlen += strlen(kn->name) + 1;
+
+	if (len + nlen >= buflen)
+		return len + nlen;
+
+	p = buf + len + nlen;
+	*p = '\0';
+	for (kn = kn_to; kn != common; kn = kn->parent) {
+		nlen = strlen(kn->name);
+		p -= nlen;
+		memcpy(p, kn->name, nlen);
+		*(--p) = '/';
+	}
+
+	return len + nlen;
 }
 
 /**
@@ -115,6 +210,34 @@ size_t kernfs_path_len(struct kernfs_nod
 }
 
 /**
+ * kernfs_path_from_node - build path of node @to relative to @from.
+ * @from: parent kernfs_node relative to which we need to build the path
+ * @to: kernfs_node of interest
+ * @buf: buffer to copy @to's path into
+ * @buflen: size of @buf
+ *
+ * Builds @to's path relative to @from in @buf. @from and @to must
+ * be on the same kernfs-root. If @from is not parent of @to, then a relative
+ * path (which includes '..'s) as needed to reach from @from to @to is
+ * returned.
+ *
+ * If @buf isn't long enough, the return value will be greater than @buflen
+ * and @buf contents are undefined.
+ */
+int kernfs_path_from_node(struct kernfs_node *to, struct kernfs_node *from,
+			  char *buf, size_t buflen)
+{
+	unsigned long flags;
+	int ret;
+
+	spin_lock_irqsave(&kernfs_rename_lock, flags);
+	ret = kernfs_path_from_node_locked(to, from, buf, buflen);
+	spin_unlock_irqrestore(&kernfs_rename_lock, flags);
+	return ret;
+}
+EXPORT_SYMBOL_GPL(kernfs_path_from_node);
+
+/**
  * kernfs_path - build full path of a given node
  * @kn: kernfs_node of interest
  * @buf: buffer to copy @kn's name into
@@ -127,13 +250,12 @@ size_t kernfs_path_len(struct kernfs_nod
  */
 char *kernfs_path(struct kernfs_node *kn, char *buf, size_t buflen)
 {
-	unsigned long flags;
-	char *p;
+	int ret;
 
-	spin_lock_irqsave(&kernfs_rename_lock, flags);
-	p = kernfs_path_locked(kn, buf, buflen);
-	spin_unlock_irqrestore(&kernfs_rename_lock, flags);
-	return p;
+	ret = kernfs_path_from_node(kn, NULL, buf, buflen);
+	if (ret < 0 || ret >= buflen)
+		return NULL;
+	return buf;
 }
 EXPORT_SYMBOL_GPL(kernfs_path);
 
@@ -164,17 +286,25 @@ void pr_cont_kernfs_name(struct kernfs_n
 void pr_cont_kernfs_path(struct kernfs_node *kn)
 {
 	unsigned long flags;
-	char *p;
+	int sz;
 
 	spin_lock_irqsave(&kernfs_rename_lock, flags);
 
-	p = kernfs_path_locked(kn, kernfs_pr_cont_buf,
-			       sizeof(kernfs_pr_cont_buf));
-	if (p)
-		pr_cont("%s", p);
-	else
-		pr_cont("<name too long>");
+	sz = kernfs_path_from_node_locked(kn, NULL, kernfs_pr_cont_buf,
+					  sizeof(kernfs_pr_cont_buf));
+	if (sz < 0) {
+		pr_cont("(error)");
+		goto out;
+	}
+
+	if (sz >= sizeof(kernfs_pr_cont_buf)) {
+		pr_cont("(name too long)");
+		goto out;
+	}
+
+	pr_cont("%s", kernfs_pr_cont_buf);
 
+out:
 	spin_unlock_irqrestore(&kernfs_rename_lock, flags);
 }
 
--- zfcpdump-kernel-4.4.orig/fs/kernfs/file.c
+++ zfcpdump-kernel-4.4/fs/kernfs/file.c
@@ -833,21 +833,35 @@ repeat:
 	mutex_lock(&kernfs_mutex);
 
 	list_for_each_entry(info, &kernfs_root(kn)->supers, node) {
+		struct kernfs_node *parent;
 		struct inode *inode;
-		struct dentry *dentry;
 
+		/*
+		 * We want fsnotify_modify() on @kn but as the
+		 * modifications aren't originating from userland don't
+		 * have the matching @file available.  Look up the inodes
+		 * and generate the events manually.
+		 */
 		inode = ilookup(info->sb, kn->ino);
 		if (!inode)
 			continue;
 
-		dentry = d_find_any_alias(inode);
-		if (dentry) {
-			fsnotify_parent(NULL, dentry, FS_MODIFY);
-			fsnotify(inode, FS_MODIFY, inode, FSNOTIFY_EVENT_INODE,
-				 NULL, 0);
-			dput(dentry);
+		parent = kernfs_get_parent(kn);
+		if (parent) {
+			struct inode *p_inode;
+
+			p_inode = ilookup(info->sb, parent->ino);
+			if (p_inode) {
+				fsnotify(p_inode, FS_MODIFY | FS_EVENT_ON_CHILD,
+					 inode, FSNOTIFY_EVENT_INODE, kn->name, 0);
+				iput(p_inode);
+			}
+
+			kernfs_put(parent);
 		}
 
+		fsnotify(inode, FS_MODIFY, inode, FSNOTIFY_EVENT_INODE,
+			 kn->name, 0);
 		iput(inode);
 	}
 
--- zfcpdump-kernel-4.4.orig/fs/kernfs/inode.c
+++ zfcpdump-kernel-4.4/fs/kernfs/inode.c
@@ -117,6 +117,8 @@ int kernfs_iop_setattr(struct dentry *de
 
 	if (!kn)
 		return -EINVAL;
+	if (!uid_valid(inode->i_uid) || !gid_valid(inode->i_gid))
+		return -EPERM;
 
 	mutex_lock(&kernfs_mutex);
 	error = inode_change_ok(inode, iattr);
--- zfcpdump-kernel-4.4.orig/fs/kernfs/mount.c
+++ zfcpdump-kernel-4.4/fs/kernfs/mount.c
@@ -14,6 +14,8 @@
 #include <linux/magic.h>
 #include <linux/slab.h>
 #include <linux/pagemap.h>
+#include <linux/namei.h>
+#include <linux/seq_file.h>
 
 #include "kernfs-internal.h"
 
@@ -39,6 +41,19 @@ static int kernfs_sop_show_options(struc
 	return 0;
 }
 
+static int kernfs_sop_show_path(struct seq_file *sf, struct dentry *dentry)
+{
+	struct kernfs_node *node = dentry->d_fsdata;
+	struct kernfs_root *root = kernfs_root(node);
+	struct kernfs_syscall_ops *scops = root->syscall_ops;
+
+	if (scops && scops->show_path)
+		return scops->show_path(sf, node, root);
+
+	seq_dentry(sf, dentry, " \t\n\\");
+	return 0;
+}
+
 const struct super_operations kernfs_sops = {
 	.statfs		= simple_statfs,
 	.drop_inode	= generic_delete_inode,
@@ -46,6 +61,7 @@ const struct super_operations kernfs_sop
 
 	.remount_fs	= kernfs_sop_remount_fs,
 	.show_options	= kernfs_sop_show_options,
+	.show_path	= kernfs_sop_show_path,
 };
 
 /**
@@ -62,6 +78,74 @@ struct kernfs_root *kernfs_root_from_sb(
 	return NULL;
 }
 
+/*
+ * find the next ancestor in the path down to @child, where @parent was the
+ * ancestor whose descendant we want to find.
+ *
+ * Say the path is /a/b/c/d.  @child is d, @parent is NULL.  We return the root
+ * node.  If @parent is b, then we return the node for c.
+ * Passing in d as @parent is not ok.
+ */
+static struct kernfs_node *
+find_next_ancestor(struct kernfs_node *child, struct kernfs_node *parent)
+{
+	if (child == parent) {
+		pr_crit_once("BUG in find_next_ancestor: called with parent == child");
+		return NULL;
+	}
+
+	while (child->parent != parent) {
+		if (!child->parent)
+			return NULL;
+		child = child->parent;
+	}
+
+	return child;
+}
+
+/**
+ * kernfs_node_dentry - get a dentry for the given kernfs_node
+ * @kn: kernfs_node for which a dentry is needed
+ * @sb: the kernfs super_block
+ */
+struct dentry *kernfs_node_dentry(struct kernfs_node *kn,
+				  struct super_block *sb)
+{
+	struct dentry *dentry;
+	struct kernfs_node *knparent = NULL;
+
+	BUG_ON(sb->s_op != &kernfs_sops);
+
+	dentry = dget(sb->s_root);
+
+	/* Check if this is the root kernfs_node */
+	if (!kn->parent)
+		return dentry;
+
+	knparent = find_next_ancestor(kn, NULL);
+	if (WARN_ON(!knparent))
+		return ERR_PTR(-EINVAL);
+
+	do {
+		struct dentry *dtmp;
+		struct kernfs_node *kntmp;
+
+		if (kn == knparent)
+			return dentry;
+		kntmp = find_next_ancestor(kn, knparent);
+		if (WARN_ON(!kntmp))
+			return ERR_PTR(-EINVAL);
+		mutex_lock(&d_inode(dentry)->i_mutex);
+		dtmp = lookup_one_len(kntmp->name, dentry, strlen(kntmp->name));
+		mutex_unlock(&d_inode(dentry)->i_mutex);
+		dput(dentry);
+		if (IS_ERR(dtmp))
+			return dtmp;
+		knparent = kntmp;
+		dentry = dtmp;
+	} while (1);
+}
+
 static int kernfs_fill_super(struct super_block *sb, unsigned long magic)
 {
 	struct kernfs_super_info *info = kernfs_info(sb);
@@ -69,6 +153,8 @@ static int kernfs_fill_super(struct supe
 	struct dentry *root;
 
 	info->sb = sb;
+	/* Userspace would break if executables appear on sysfs */
+	sb->s_iflags |= SB_I_NOEXEC;
 	sb->s_blocksize = PAGE_CACHE_SIZE;
 	sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
 	sb->s_magic = magic;
@@ -158,7 +244,8 @@ struct dentry *kernfs_mount_ns(struct fi
 	info->root = root;
 	info->ns = ns;
 
-	sb = sget(fs_type, kernfs_test_super, kernfs_set_super, flags, info);
+	sb = sget_userns(fs_type, kernfs_test_super, kernfs_set_super, flags,
+			 &init_user_ns, info);
 	if (IS_ERR(sb) || sb->s_fs_info != info)
 		kfree(info);
 	if (IS_ERR(sb))
--- zfcpdump-kernel-4.4.orig/fs/locks.c
+++ zfcpdump-kernel-4.4/fs/locks.c
@@ -1602,7 +1602,7 @@ generic_add_lease(struct file *filp, lon
 {
 	struct file_lock *fl, *my_fl = NULL, *lease;
 	struct dentry *dentry = filp->f_path.dentry;
-	struct inode *inode = dentry->d_inode;
+	struct inode *inode = file_inode(filp);
 	struct file_lock_context *ctx;
 	bool is_deleg = (*flp)->fl_flags & FL_DELEG;
 	int error;
@@ -2182,7 +2182,6 @@ int fcntl_setlk(unsigned int fd, struct
 		goto out;
 	}
 
-again:
 	error = flock_to_posix_lock(filp, file_lock, &flock);
 	if (error)
 		goto out;
@@ -2224,19 +2223,22 @@ again:
 	 * Attempt to detect a close/fcntl race and recover by
 	 * releasing the lock that was just acquired.
 	 */
-	/*
-	 * we need that spin_lock here - it prevents reordering between
-	 * update of i_flctx->flc_posix and check for it done in close().
-	 * rcu_read_lock() wouldn't do.
-	 */
-	spin_lock(&current->files->file_lock);
-	f = fcheck(fd);
-	spin_unlock(&current->files->file_lock);
-	if (!error && f != filp && flock.l_type != F_UNLCK) {
-		flock.l_type = F_UNLCK;
-		goto again;
+	if (!error && file_lock->fl_type != F_UNLCK) {
+		/*
+		 * We need that spin_lock here - it prevents reordering between
+		 * update of i_flctx->flc_posix and check for it done in
+		 * close(). rcu_read_lock() wouldn't do.
+		 */
+		spin_lock(&current->files->file_lock);
+		f = fcheck(fd);
+		spin_unlock(&current->files->file_lock);
+		if (f != filp) {
+			file_lock->fl_type = F_UNLCK;
+			error = do_lock_file_wait(filp, cmd, file_lock);
+			WARN_ON_ONCE(error);
+			error = -EBADF;
+		}
 	}
-
 out:
 	locks_free_lock(file_lock);
 	return error;
@@ -2322,7 +2324,6 @@ int fcntl_setlk64(unsigned int fd, struc
 		goto out;
 	}
 
-again:
 	error = flock64_to_posix_lock(filp, file_lock, &flock);
 	if (error)
 		goto out;
@@ -2364,14 +2365,22 @@ again:
 	 * Attempt to detect a close/fcntl race and recover by
 	 * releasing the lock that was just acquired.
 	 */
-	spin_lock(&current->files->file_lock);
-	f = fcheck(fd);
-	spin_unlock(&current->files->file_lock);
-	if (!error && f != filp && flock.l_type != F_UNLCK) {
-		flock.l_type = F_UNLCK;
-		goto again;
+	if (!error && file_lock->fl_type != F_UNLCK) {
+		/*
+		 * We need that spin_lock here - it prevents reordering between
+		 * update of i_flctx->flc_posix and check for it done in
+		 * close(). rcu_read_lock() wouldn't do.
+		 */
+		spin_lock(&current->files->file_lock);
+		f = fcheck(fd);
+		spin_unlock(&current->files->file_lock);
+		if (f != filp) {
+			file_lock->fl_type = F_UNLCK;
+			error = do_lock_file_wait(filp, cmd, file_lock);
+			WARN_ON_ONCE(error);
+			error = -EBADF;
+		}
 	}
-
 out:
 	locks_free_lock(file_lock);
 	return error;
--- zfcpdump-kernel-4.4.orig/fs/namei.c
+++ zfcpdump-kernel-4.4/fs/namei.c
@@ -35,6 +35,7 @@
 #include <linux/fs_struct.h>
 #include <linux/posix_acl.h>
 #include <linux/hash.h>
+#include <linux/init_task.h>
 #include <asm/uaccess.h>
 
 #include "internal.h"
@@ -865,8 +866,8 @@ static inline void put_link(struct namei
 		path_put(&last->link);
 }
 
-int sysctl_protected_symlinks __read_mostly = 0;
-int sysctl_protected_hardlinks __read_mostly = 0;
+int sysctl_protected_symlinks __read_mostly = 1;
+int sysctl_protected_hardlinks __read_mostly = 1;
 
 /**
  * may_follow_link - Check symlink following for unsafe situations
@@ -887,6 +888,7 @@ static inline int may_follow_link(struct
 {
 	const struct inode *inode;
 	const struct inode *parent;
+	kuid_t puid;
 
 	if (!sysctl_protected_symlinks)
 		return 0;
@@ -902,7 +904,8 @@ static inline int may_follow_link(struct
 		return 0;
 
 	/* Allowed if parent directory and link owner match. */
-	if (uid_eq(parent->i_uid, inode->i_uid))
+	puid = parent->i_uid;
+	if (uid_valid(puid) && uid_eq(puid, inode->i_uid))
 		return 0;
 
 	if (nd->flags & LOOKUP_RCU)
@@ -1084,6 +1087,7 @@ static int follow_automount(struct path
 			    bool *need_mntput)
 {
 	struct vfsmount *mnt;
+	const struct cred *old_cred;
 	int err;
 
 	if (!path->dentry->d_op || !path->dentry->d_op->d_automount)
@@ -1105,11 +1109,16 @@ static int follow_automount(struct path
 	    path->dentry->d_inode)
 		return -EISDIR;
 
+	if (path->dentry->d_sb->s_user_ns != &init_user_ns)
+		return -EACCES;
+
 	nd->total_link_count++;
 	if (nd->total_link_count >= 40)
 		return -ELOOP;
 
+	old_cred = override_creds(&init_cred);
 	mnt = path->dentry->d_op->d_automount(path);
+	revert_creds(old_cred);
 	if (IS_ERR(mnt)) {
 		/*
 		 * The filesystem is allowed to return -EISDIR here to indicate
@@ -1711,6 +1720,11 @@ static inline int should_follow_link(str
 		return 0;
 	if (!follow)
 		return 0;
+	/* make sure that d_is_symlink above matches inode */
+	if (nd->flags & LOOKUP_RCU) {
+		if (read_seqcount_retry(&link->dentry->d_seq, seq))
+			return -ECHILD;
+	}
 	return pick_link(nd, link, inode, seq);
 }
 
@@ -1742,11 +1756,11 @@ static int walk_component(struct nameida
 		if (err < 0)
 			return err;
 
-		inode = d_backing_inode(path.dentry);
 		seq = 0;	/* we are already out of RCU mode */
 		err = -ENOENT;
 		if (d_is_negative(path.dentry))
 			goto out_path_put;
+		inode = d_backing_inode(path.dentry);
 	}
 
 	if (flags & WALK_PUT)
@@ -2901,22 +2915,10 @@ no_open:
 		dentry = lookup_real(dir, dentry, nd->flags);
 		if (IS_ERR(dentry))
 			return PTR_ERR(dentry);
-
-		if (create_error) {
-			int open_flag = op->open_flag;
-
-			error = create_error;
-			if ((open_flag & O_EXCL)) {
-				if (!dentry->d_inode)
-					goto out;
-			} else if (!dentry->d_inode) {
-				goto out;
-			} else if ((open_flag & O_TRUNC) &&
-				   d_is_reg(dentry)) {
-				goto out;
-			}
-			/* will fail later, go on to get the right error */
-		}
+	}
+	if (create_error && !dentry->d_inode) {
+		error = create_error;
+		goto out;
 	}
 looked_up:
 	path->dentry = dentry;
@@ -3130,12 +3132,12 @@ retry_lookup:
 		return error;
 
 	BUG_ON(nd->flags & LOOKUP_RCU);
-	inode = d_backing_inode(path.dentry);
 	seq = 0;	/* out of RCU mode, so the value doesn't matter */
 	if (unlikely(d_is_negative(path.dentry))) {
 		path_to_nameidata(&path, nd);
 		return -ENOENT;
 	}
+	inode = d_backing_inode(path.dentry);
 finish_lookup:
 	if (nd->depth)
 		put_link(nd);
@@ -3144,11 +3146,6 @@ finish_lookup:
 	if (unlikely(error))
 		return error;
 
-	if (unlikely(d_is_symlink(path.dentry)) && !(open_flag & O_PATH)) {
-		path_to_nameidata(&path, nd);
-		return -ELOOP;
-	}
-
 	if ((nd->flags & LOOKUP_RCU) || nd->path.mnt != path.mnt) {
 		path_to_nameidata(&path, nd);
 	} else {
@@ -3167,6 +3164,10 @@ finish_open:
 		return error;
 	}
 	audit_inode(nd->name, nd->path.dentry, 0);
+	if (unlikely(d_is_symlink(nd->path.dentry)) && !(open_flag & O_PATH)) {
+		error = -ELOOP;
+		goto out;
+	}
 	error = -EISDIR;
 	if ((open_flag & O_CREAT) && d_is_dir(nd->path.dentry))
 		goto out;
@@ -3210,6 +3211,10 @@ opened:
 			goto exit_fput;
 	}
 out:
+	if (unlikely(error > 0)) {
+		WARN_ON(1);
+		error = -EINVAL;
+	}
 	if (got_write)
 		mnt_drop_write(nd->path.mnt);
 	path_put(&save_parent);
@@ -4187,7 +4192,11 @@ int vfs_rename(struct inode *old_dir, st
 	bool new_is_dir = false;
 	unsigned max_links = new_dir->i_sb->s_max_links;
 
-	if (source == target)
+	/*
+	 * Check source == target.
+	 * On overlayfs need to look at underlying inodes.
+	 */
+	if (vfs_select_inode(old_dentry, 0) == vfs_select_inode(new_dentry, 0))
 		return 0;
 
 	error = may_delete(old_dir, old_dentry, is_dir);
--- zfcpdump-kernel-4.4.orig/fs/namespace.c
+++ zfcpdump-kernel-4.4/fs/namespace.c
@@ -463,6 +463,7 @@ void __mnt_drop_write(struct vfsmount *m
 	mnt_dec_writers(real_mount(mnt));
 	preempt_enable();
 }
+EXPORT_SYMBOL_GPL(__mnt_drop_write);
 
 /**
  * mnt_drop_write - give up write access to a mount
@@ -1510,7 +1511,7 @@ static int do_umount(struct mount *mnt,
 		 * Special case for "unmounting" root ...
 		 * we just try to remount it readonly.
 		 */
-		if (!capable(CAP_SYS_ADMIN))
+		if (!ns_capable(sb->s_user_ns, CAP_SYS_ADMIN))
 			return -EPERM;
 		down_write(&sb->s_umount);
 		if (!(sb->s_flags & MS_RDONLY))
@@ -1562,6 +1563,7 @@ void __detach_mounts(struct dentry *dent
 		goto out_unlock;
 
 	lock_mount_hash();
+	event++;
 	while (!hlist_empty(&mp->m_list)) {
 		mnt = hlist_entry(mp->m_list.first, struct mount, mnt_mp_list);
 		if (mnt->mnt.mnt_flags & MNT_UMOUNT) {
@@ -1803,6 +1805,7 @@ int iterate_mounts(int (*f)(struct vfsmo
 	}
 	return 0;
 }
+EXPORT_SYMBOL(iterate_mounts);
 
 static void cleanup_group_ids(struct mount *mnt, struct mount *end)
 {
@@ -2205,7 +2208,7 @@ static int do_remount(struct path *path,
 	down_write(&sb->s_umount);
 	if (flags & MS_BIND)
 		err = change_mount_flags(path->mnt, flags);
-	else if (!capable(CAP_SYS_ADMIN))
+	else if (!ns_capable(sb->s_user_ns, CAP_SYS_ADMIN))
 		err = -EPERM;
 	else
 		err = do_remount_sb(sb, flags, data, 0);
@@ -2381,6 +2384,9 @@ static int do_new_mount(struct path *pat
 	struct vfsmount *mnt;
 	int err;
 
+	if (!ns_capable(current_user_ns(), CAP_SYS_ADMIN))
+		return -EPERM;
+
 	if (!fstype)
 		return -EINVAL;
 
@@ -2401,8 +2407,10 @@ static int do_new_mount(struct path *pat
 			mnt_flags |= MNT_NODEV | MNT_LOCK_NODEV;
 		}
 		if (type->fs_flags & FS_USERNS_VISIBLE) {
-			if (!fs_fully_visible(type, &mnt_flags))
+			if (!fs_fully_visible(type, &mnt_flags)) {
+				put_filesystem(type);
 				return -EPERM;
+			}
 		}
 	}
 
@@ -3236,6 +3244,10 @@ static bool fs_fully_visible(struct file
 		if (mnt->mnt.mnt_sb->s_iflags & SB_I_NOEXEC)
 			mnt_flags &= ~(MNT_LOCK_NOSUID | MNT_LOCK_NOEXEC);
 
+		/* Don't miss readonly hidden in the superblock flags */
+		if (mnt->mnt.mnt_sb->s_flags & MS_RDONLY)
+			mnt_flags |= MNT_LOCK_READONLY;
+
 		/* Verify the mount flags are equal to or more permissive
 		 * than the proposed new mount.
 		 */
@@ -3262,7 +3274,7 @@ static bool fs_fully_visible(struct file
 		list_for_each_entry(child, &mnt->mnt_mounts, mnt_child) {
 			struct inode *inode = child->mnt_mountpoint->d_inode;
 			/* Only worry about locked mounts */
-			if (!(mnt_flags & MNT_LOCKED))
+			if (!(child->mnt.mnt_flags & MNT_LOCKED))
 				continue;
 			/* Is the directory permanetly empty? */
 			if (!is_empty_dir_inode(inode))
@@ -3283,6 +3295,19 @@ found:
 	return visible;
 }
 
+bool mnt_may_suid(struct vfsmount *mnt)
+{
+	/*
+	 * Foreign mounts (accessed via fchdir or through /proc
+	 * symlinks) are always treated as if they are nosuid.  This
+	 * prevents namespaces from trusting potentially unsafe
+	 * suid/sgid bits, file caps, or security labels that originate
+	 * in other namespaces.
+	 */
+	return !(mnt->mnt_flags & MNT_NOSUID) && check_mnt(real_mount(mnt)) &&
+	       current_in_userns(mnt->mnt_sb->s_user_ns);
+}
+
 static struct ns_common *mntns_get(struct task_struct *task)
 {
 	struct ns_common *ns = NULL;
--- zfcpdump-kernel-4.4.orig/fs/ncpfs/dir.c
+++ zfcpdump-kernel-4.4/fs/ncpfs/dir.c
@@ -633,7 +633,7 @@ ncp_fill_cache(struct file *file, struct
 				d_rehash(newdent);
 		} else {
 			spin_lock(&dentry->d_lock);
-			NCP_FINFO(inode)->flags &= ~NCPI_DIR_CACHE;
+			NCP_FINFO(dir)->flags &= ~NCPI_DIR_CACHE;
 			spin_unlock(&dentry->d_lock);
 		}
 	} else {
--- zfcpdump-kernel-4.4.orig/fs/nfs/callback.c
+++ zfcpdump-kernel-4.4/fs/nfs/callback.c
@@ -275,6 +275,7 @@ static int nfs_callback_up_net(int minor
 err_socks:
 	svc_rpcb_cleanup(serv, net);
 err_bind:
+	nn->cb_users[minorversion]--;
 	dprintk("NFS: Couldn't create callback socket: err = %d; "
 			"net = %p\n", ret, net);
 	return ret;
--- zfcpdump-kernel-4.4.orig/fs/nfs/callback_xdr.c
+++ zfcpdump-kernel-4.4/fs/nfs/callback_xdr.c
@@ -912,7 +912,7 @@ static __be32 nfs4_callback_compound(str
 	if (hdr_arg.minorversion == 0) {
 		cps.clp = nfs4_find_client_ident(SVC_NET(rqstp), hdr_arg.cb_ident);
 		if (!cps.clp || !check_gss_callback_principal(cps.clp, rqstp))
-			return rpc_drop_reply;
+			goto out_invalidcred;
 	}
 
 	cps.minorversion = hdr_arg.minorversion;
@@ -940,6 +940,10 @@ static __be32 nfs4_callback_compound(str
 	nfs_put_client(cps.clp);
 	dprintk("%s: done, status = %u\n", __func__, ntohl(status));
 	return rpc_success;
+
+out_invalidcred:
+	pr_warn_ratelimited("NFS: NFSv4 callback contains invalid cred\n");
+	return rpc_autherr_badcred;
 }
 
 /*
--- zfcpdump-kernel-4.4.orig/fs/nfs/dir.c
+++ zfcpdump-kernel-4.4/fs/nfs/dir.c
@@ -377,7 +377,7 @@ int nfs_readdir_xdr_filler(struct page *
  again:
 	timestamp = jiffies;
 	gencount = nfs_inc_attr_generation_counter();
-	error = NFS_PROTO(inode)->readdir(file->f_path.dentry, cred, entry->cookie, pages,
+	error = NFS_PROTO(inode)->readdir(file_dentry(file), cred, entry->cookie, pages,
 					  NFS_SERVER(inode)->dtsize, desc->plus);
 	if (error < 0) {
 		/* We requested READDIRPLUS, but the server doesn't grok it */
@@ -560,7 +560,7 @@ int nfs_readdir_page_filler(nfs_readdir_
 		count++;
 
 		if (desc->plus != 0)
-			nfs_prime_dcache(desc->file->f_path.dentry, entry);
+			nfs_prime_dcache(file_dentry(desc->file), entry);
 
 		status = nfs_readdir_add_to_array(entry, page);
 		if (status != 0)
@@ -864,7 +864,7 @@ static bool nfs_dir_mapping_need_revalid
  */
 static int nfs_readdir(struct file *file, struct dir_context *ctx)
 {
-	struct dentry	*dentry = file->f_path.dentry;
+	struct dentry	*dentry = file_dentry(file);
 	struct inode	*inode = d_inode(dentry);
 	nfs_readdir_descriptor_t my_desc,
 			*desc = &my_desc;
@@ -1531,9 +1531,9 @@ int nfs_atomic_open(struct inode *dir, s
 		err = PTR_ERR(inode);
 		trace_nfs_atomic_open_exit(dir, ctx, open_flags, err);
 		put_nfs_open_context(ctx);
+		d_drop(dentry);
 		switch (err) {
 		case -ENOENT:
-			d_drop(dentry);
 			d_add(dentry, NULL);
 			nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
 			break;
--- zfcpdump-kernel-4.4.orig/fs/nfs/filelayout/filelayout.c
+++ zfcpdump-kernel-4.4/fs/nfs/filelayout/filelayout.c
@@ -374,8 +374,7 @@ static int filelayout_commit_done_cb(str
 		return -EAGAIN;
 	}
 
-	if (data->verf.committed == NFS_UNSTABLE)
-		pnfs_set_layoutcommit(data->inode, data->lseg, data->lwb);
+	pnfs_set_layoutcommit(data->inode, data->lseg, data->lwb);
 
 	return 0;
 }
--- zfcpdump-kernel-4.4.orig/fs/nfs/flexfilelayout/flexfilelayout.c
+++ zfcpdump-kernel-4.4/fs/nfs/flexfilelayout/flexfilelayout.c
@@ -145,7 +145,7 @@ static bool ff_mirror_match_fh(const str
 		return false;
 	for (i = 0; i < m1->fh_versions_cnt; i++) {
 		bool found_fh = false;
-		for (j = 0; j < m2->fh_versions_cnt; i++) {
+		for (j = 0; j < m2->fh_versions_cnt; j++) {
 			if (nfs_compare_fh(&m1->fh_versions[i],
 					&m2->fh_versions[j]) == 0) {
 				found_fh = true;
@@ -1414,8 +1414,7 @@ static int ff_layout_commit_done_cb(stru
 		return -EAGAIN;
 	}
 
-	if (data->verf.committed == NFS_UNSTABLE
-	    && ff_layout_need_layoutcommit(data->lseg))
+	if (ff_layout_need_layoutcommit(data->lseg))
 		pnfs_set_layoutcommit(data->inode, data->lseg, data->lwb);
 
 	return 0;
@@ -1859,11 +1858,9 @@ ff_layout_encode_layoutreturn(struct pnf
 	start = xdr_reserve_space(xdr, 4);
 	BUG_ON(!start);
 
-	if (ff_layout_encode_ioerr(flo, xdr, args))
-		goto out;
-
+	ff_layout_encode_ioerr(flo, xdr, args);
 	ff_layout_encode_iostats(flo, xdr, args);
-out:
+
 	*start = cpu_to_be32((xdr->p - start - 1) * 4);
 	dprintk("%s: Return\n", __func__);
 }
--- zfcpdump-kernel-4.4.orig/fs/nfs/inode.c
+++ zfcpdump-kernel-4.4/fs/nfs/inode.c
@@ -927,7 +927,7 @@ int nfs_open(struct inode *inode, struct
 {
 	struct nfs_open_context *ctx;
 
-	ctx = alloc_nfs_open_context(filp->f_path.dentry, filp->f_mode);
+	ctx = alloc_nfs_open_context(file_dentry(filp), filp->f_mode);
 	if (IS_ERR(ctx))
 		return PTR_ERR(ctx);
 	nfs_file_set_open_context(filp, ctx);
@@ -1641,6 +1641,7 @@ static int nfs_update_inode(struct inode
 	unsigned long invalid = 0;
 	unsigned long now = jiffies;
 	unsigned long save_cache_validity;
+	bool cache_revalidated = true;
 
 	dfprintk(VFS, "NFS: %s(%s/%lu fh_crc=0x%08x ct=%d info=0x%x)\n",
 			__func__, inode->i_sb->s_id, inode->i_ino,
@@ -1702,22 +1703,28 @@ static int nfs_update_inode(struct inode
 				nfs_force_lookup_revalidate(inode);
 			inode->i_version = fattr->change_attr;
 		}
-	} else
+	} else {
 		nfsi->cache_validity |= save_cache_validity;
+		cache_revalidated = false;
+	}
 
 	if (fattr->valid & NFS_ATTR_FATTR_MTIME) {
 		memcpy(&inode->i_mtime, &fattr->mtime, sizeof(inode->i_mtime));
-	} else if (server->caps & NFS_CAP_MTIME)
+	} else if (server->caps & NFS_CAP_MTIME) {
 		nfsi->cache_validity |= save_cache_validity &
 				(NFS_INO_INVALID_ATTR
 				| NFS_INO_REVAL_FORCED);
+		cache_revalidated = false;
+	}
 
 	if (fattr->valid & NFS_ATTR_FATTR_CTIME) {
 		memcpy(&inode->i_ctime, &fattr->ctime, sizeof(inode->i_ctime));
-	} else if (server->caps & NFS_CAP_CTIME)
+	} else if (server->caps & NFS_CAP_CTIME) {
 		nfsi->cache_validity |= save_cache_validity &
 				(NFS_INO_INVALID_ATTR
 				| NFS_INO_REVAL_FORCED);
+		cache_revalidated = false;
+	}
 
 	/* Check if our cached file size is stale */
 	if (fattr->valid & NFS_ATTR_FATTR_SIZE) {
@@ -1737,19 +1744,23 @@ static int nfs_update_inode(struct inode
 					(long long)cur_isize,
 					(long long)new_isize);
 		}
-	} else
+	} else {
 		nfsi->cache_validity |= save_cache_validity &
 				(NFS_INO_INVALID_ATTR
 				| NFS_INO_REVAL_PAGECACHE
 				| NFS_INO_REVAL_FORCED);
+		cache_revalidated = false;
+	}
 
 
 	if (fattr->valid & NFS_ATTR_FATTR_ATIME)
 		memcpy(&inode->i_atime, &fattr->atime, sizeof(inode->i_atime));
-	else if (server->caps & NFS_CAP_ATIME)
+	else if (server->caps & NFS_CAP_ATIME) {
 		nfsi->cache_validity |= save_cache_validity &
 				(NFS_INO_INVALID_ATIME
 				| NFS_INO_REVAL_FORCED);
+		cache_revalidated = false;
+	}
 
 	if (fattr->valid & NFS_ATTR_FATTR_MODE) {
 		if ((inode->i_mode & S_IALLUGO) != (fattr->mode & S_IALLUGO)) {
@@ -1758,36 +1769,42 @@ static int nfs_update_inode(struct inode
 			inode->i_mode = newmode;
 			invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL;
 		}
-	} else if (server->caps & NFS_CAP_MODE)
+	} else if (server->caps & NFS_CAP_MODE) {
 		nfsi->cache_validity |= save_cache_validity &
 				(NFS_INO_INVALID_ATTR
 				| NFS_INO_INVALID_ACCESS
 				| NFS_INO_INVALID_ACL
 				| NFS_INO_REVAL_FORCED);
+		cache_revalidated = false;
+	}
 
 	if (fattr->valid & NFS_ATTR_FATTR_OWNER) {
 		if (!uid_eq(inode->i_uid, fattr->uid)) {
 			invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL;
 			inode->i_uid = fattr->uid;
 		}
-	} else if (server->caps & NFS_CAP_OWNER)
+	} else if (server->caps & NFS_CAP_OWNER) {
 		nfsi->cache_validity |= save_cache_validity &
 				(NFS_INO_INVALID_ATTR
 				| NFS_INO_INVALID_ACCESS
 				| NFS_INO_INVALID_ACL
 				| NFS_INO_REVAL_FORCED);
+		cache_revalidated = false;
+	}
 
 	if (fattr->valid & NFS_ATTR_FATTR_GROUP) {
 		if (!gid_eq(inode->i_gid, fattr->gid)) {
 			invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL;
 			inode->i_gid = fattr->gid;
 		}
-	} else if (server->caps & NFS_CAP_OWNER_GROUP)
+	} else if (server->caps & NFS_CAP_OWNER_GROUP) {
 		nfsi->cache_validity |= save_cache_validity &
 				(NFS_INO_INVALID_ATTR
 				| NFS_INO_INVALID_ACCESS
 				| NFS_INO_INVALID_ACL
 				| NFS_INO_REVAL_FORCED);
+		cache_revalidated = false;
+	}
 
 	if (fattr->valid & NFS_ATTR_FATTR_NLINK) {
 		if (inode->i_nlink != fattr->nlink) {
@@ -1796,19 +1813,22 @@ static int nfs_update_inode(struct inode
 				invalid |= NFS_INO_INVALID_DATA;
 			set_nlink(inode, fattr->nlink);
 		}
-	} else if (server->caps & NFS_CAP_NLINK)
+	} else if (server->caps & NFS_CAP_NLINK) {
 		nfsi->cache_validity |= save_cache_validity &
 				(NFS_INO_INVALID_ATTR
 				| NFS_INO_REVAL_FORCED);
+		cache_revalidated = false;
+	}
 
 	if (fattr->valid & NFS_ATTR_FATTR_SPACE_USED) {
 		/*
 		 * report the blocks in 512byte units
 		 */
 		inode->i_blocks = nfs_calc_block_size(fattr->du.nfs3.used);
- 	}
-	if (fattr->valid & NFS_ATTR_FATTR_BLOCKS_USED)
+	} else if (fattr->valid & NFS_ATTR_FATTR_BLOCKS_USED)
 		inode->i_blocks = fattr->du.nfs2.blocks;
+	else
+		cache_revalidated = false;
 
 	/* Update attrtimeo value if we're out of the unstable period */
 	if (invalid & NFS_INO_INVALID_ATTR) {
@@ -1818,9 +1838,13 @@ static int nfs_update_inode(struct inode
 		/* Set barrier to be more recent than all outstanding updates */
 		nfsi->attr_gencount = nfs_inc_attr_generation_counter();
 	} else {
-		if (!time_in_range_open(now, nfsi->attrtimeo_timestamp, nfsi->attrtimeo_timestamp + nfsi->attrtimeo)) {
-			if ((nfsi->attrtimeo <<= 1) > NFS_MAXATTRTIMEO(inode))
-				nfsi->attrtimeo = NFS_MAXATTRTIMEO(inode);
+		if (cache_revalidated) {
+			if (!time_in_range_open(now, nfsi->attrtimeo_timestamp,
+				nfsi->attrtimeo_timestamp + nfsi->attrtimeo)) {
+				nfsi->attrtimeo <<= 1;
+				if (nfsi->attrtimeo > NFS_MAXATTRTIMEO(inode))
+					nfsi->attrtimeo = NFS_MAXATTRTIMEO(inode);
+			}
 			nfsi->attrtimeo_timestamp = now;
 		}
 		/* Set the barrier to be more recent than this fattr */
@@ -1829,7 +1853,7 @@ static int nfs_update_inode(struct inode
 	}
 
 	/* Don't declare attrcache up to date if there were no attrs! */
-	if (fattr->valid != 0)
+	if (cache_revalidated)
 		invalid &= ~NFS_INO_INVALID_ATTR;
 
 	/* Don't invalidate the data if we were to blame */
--- zfcpdump-kernel-4.4.orig/fs/nfs/nfs4file.c
+++ zfcpdump-kernel-4.4/fs/nfs/nfs4file.c
@@ -26,7 +26,7 @@ static int
 nfs4_file_open(struct inode *inode, struct file *filp)
 {
 	struct nfs_open_context *ctx;
-	struct dentry *dentry = filp->f_path.dentry;
+	struct dentry *dentry = file_dentry(filp);
 	struct dentry *parent = NULL;
 	struct inode *dir;
 	unsigned openflags = filp->f_flags;
@@ -57,7 +57,7 @@ nfs4_file_open(struct inode *inode, stru
 	parent = dget_parent(dentry);
 	dir = d_inode(parent);
 
-	ctx = alloc_nfs_open_context(filp->f_path.dentry, filp->f_mode);
+	ctx = alloc_nfs_open_context(file_dentry(filp), filp->f_mode);
 	err = PTR_ERR(ctx);
 	if (IS_ERR(ctx))
 		goto out;
--- zfcpdump-kernel-4.4.orig/fs/nfs/nfs4proc.c
+++ zfcpdump-kernel-4.4/fs/nfs/nfs4proc.c
@@ -1385,6 +1385,7 @@ static void __update_open_stateid(struct
 	 * Protect the call to nfs4_state_set_mode_locked and
 	 * serialise the stateid update
 	 */
+	spin_lock(&state->owner->so_lock);
 	write_seqlock(&state->seqlock);
 	if (deleg_stateid != NULL) {
 		nfs4_stateid_copy(&state->stateid, deleg_stateid);
@@ -1393,7 +1394,6 @@ static void __update_open_stateid(struct
 	if (open_stateid != NULL)
 		nfs_set_open_stateid_locked(state, open_stateid, fmode);
 	write_sequnlock(&state->seqlock);
-	spin_lock(&state->owner->so_lock);
 	update_open_stateflags(state, fmode);
 	spin_unlock(&state->owner->so_lock);
 }
@@ -2461,9 +2461,9 @@ static int _nfs4_open_and_get_state(stru
 		dentry = d_add_unique(dentry, igrab(state->inode));
 		if (dentry == NULL) {
 			dentry = opendata->dentry;
-		} else if (dentry != ctx->dentry) {
+		} else {
 			dput(ctx->dentry);
-			ctx->dentry = dget(dentry);
+			ctx->dentry = dentry;
 		}
 		nfs_set_verifier(dentry,
 				nfs_save_change_attribute(d_inode(opendata->dir)));
@@ -2854,12 +2854,11 @@ static void nfs4_close_prepare(struct rp
 			call_close |= is_wronly;
 		else if (is_wronly)
 			calldata->arg.fmode |= FMODE_WRITE;
+		if (calldata->arg.fmode != (FMODE_READ|FMODE_WRITE))
+			call_close |= is_rdwr;
 	} else if (is_rdwr)
 		calldata->arg.fmode |= FMODE_READ|FMODE_WRITE;
 
-	if (calldata->arg.fmode == 0)
-		call_close |= is_rdwr;
-
 	if (!nfs4_valid_open_stateid(state))
 		call_close = 0;
 	spin_unlock(&state->owner->so_lock);
@@ -7425,12 +7424,20 @@ static int _nfs4_proc_create_session(str
 	status = rpc_call_sync(session->clp->cl_rpcclient, &msg, RPC_TASK_TIMEOUT);
 	trace_nfs4_create_session(clp, status);
 
+	switch (status) {
+	case -NFS4ERR_STALE_CLIENTID:
+	case -NFS4ERR_DELAY:
+	case -ETIMEDOUT:
+	case -EACCES:
+	case -EAGAIN:
+		goto out;
+	};
+
+	clp->cl_seqid++;
 	if (!status) {
 		/* Verify the session's negotiated channel_attrs values */
 		status = nfs4_verify_channel_attrs(&args, &res);
 		/* Increment the clientid slot sequence id */
-		if (clp->cl_seqid == res.seqid)
-			clp->cl_seqid++;
 		if (status)
 			goto out;
 		nfs4_update_session(session, &res);
@@ -8054,7 +8061,6 @@ static void nfs4_layoutreturn_release(vo
 		pnfs_set_layout_stateid(lo, &lrp->res.stateid, true);
 	pnfs_mark_matching_lsegs_invalid(lo, &freeme, &lrp->args.range);
 	pnfs_clear_layoutreturn_waitbit(lo);
-	lo->plh_block_lgets--;
 	spin_unlock(&lo->plh_inode->i_lock);
 	pnfs_free_lseg_list(&freeme);
 	pnfs_put_layout_hdr(lrp->args.layout);
--- zfcpdump-kernel-4.4.orig/fs/nfs/pnfs.c
+++ zfcpdump-kernel-4.4/fs/nfs/pnfs.c
@@ -365,6 +365,9 @@ pnfs_layout_need_return(struct pnfs_layo
 static bool
 pnfs_prepare_layoutreturn(struct pnfs_layout_hdr *lo)
 {
+	/* Serialise LAYOUTGET/LAYOUTRETURN */
+	if (atomic_read(&lo->plh_outstanding) != 0)
+		return false;
 	if (test_and_set_bit(NFS_LAYOUT_RETURN, &lo->plh_flags))
 		return false;
 	lo->plh_return_iomode = 0;
@@ -1530,6 +1533,7 @@ pnfs_update_layout(struct inode *ino,
 		goto out;
 
 lookup_again:
+	nfs4_client_recover_expired_lease(clp);
 	first = false;
 	spin_lock(&ino->i_lock);
 	lo = pnfs_find_alloc_layout(ino, ctx, gfp_flags);
--- zfcpdump-kernel-4.4.orig/fs/nfs/write.c
+++ zfcpdump-kernel-4.4/fs/nfs/write.c
@@ -1261,6 +1261,9 @@ int nfs_updatepage(struct file *file, st
 	dprintk("NFS:       nfs_updatepage(%pD2 %d@%lld)\n",
 		file, count, (long long)(page_file_offset(page) + offset));
 
+	if (!count)
+		goto out;
+
 	if (nfs_can_extend_write(file, page, inode)) {
 		count = max(count + offset, nfs_page_length(page));
 		offset = 0;
@@ -1271,7 +1274,7 @@ int nfs_updatepage(struct file *file, st
 		nfs_set_pageerror(page);
 	else
 		__set_page_dirty_nobuffers(page);
-
+out:
 	dprintk("NFS:       nfs_updatepage returns %d (isize %lld)\n",
 			status, (long long)i_size_read(inode));
 	return status;
--- zfcpdump-kernel-4.4.orig/fs/nfsd/nfs2acl.c
+++ zfcpdump-kernel-4.4/fs/nfsd/nfs2acl.c
@@ -104,22 +104,21 @@ static __be32 nfsacld_proc_setacl(struct
 		goto out;
 
 	inode = d_inode(fh->fh_dentry);
-	if (!IS_POSIXACL(inode) || !inode->i_op->set_acl) {
-		error = -EOPNOTSUPP;
-		goto out_errno;
-	}
 
 	error = fh_want_write(fh);
 	if (error)
 		goto out_errno;
 
-	error = inode->i_op->set_acl(inode, argp->acl_access, ACL_TYPE_ACCESS);
+	fh_lock(fh);
+
+	error = set_posix_acl(inode, ACL_TYPE_ACCESS, argp->acl_access);
 	if (error)
-		goto out_drop_write;
-	error = inode->i_op->set_acl(inode, argp->acl_default,
-				     ACL_TYPE_DEFAULT);
+		goto out_drop_lock;
+	error = set_posix_acl(inode, ACL_TYPE_DEFAULT, argp->acl_default);
 	if (error)
-		goto out_drop_write;
+		goto out_drop_lock;
+
+	fh_unlock(fh);
 
 	fh_drop_write(fh);
 
@@ -131,7 +130,8 @@ out:
 	posix_acl_release(argp->acl_access);
 	posix_acl_release(argp->acl_default);
 	return nfserr;
-out_drop_write:
+out_drop_lock:
+	fh_unlock(fh);
 	fh_drop_write(fh);
 out_errno:
 	nfserr = nfserrno(error);
--- zfcpdump-kernel-4.4.orig/fs/nfsd/nfs3acl.c
+++ zfcpdump-kernel-4.4/fs/nfsd/nfs3acl.c
@@ -95,22 +95,20 @@ static __be32 nfsd3_proc_setacl(struct s
 		goto out;
 
 	inode = d_inode(fh->fh_dentry);
-	if (!IS_POSIXACL(inode) || !inode->i_op->set_acl) {
-		error = -EOPNOTSUPP;
-		goto out_errno;
-	}
 
 	error = fh_want_write(fh);
 	if (error)
 		goto out_errno;
 
-	error = inode->i_op->set_acl(inode, argp->acl_access, ACL_TYPE_ACCESS);
+	fh_lock(fh);
+
+	error = set_posix_acl(inode, ACL_TYPE_ACCESS, argp->acl_access);
 	if (error)
-		goto out_drop_write;
-	error = inode->i_op->set_acl(inode, argp->acl_default,
-				     ACL_TYPE_DEFAULT);
+		goto out_drop_lock;
+	error = set_posix_acl(inode, ACL_TYPE_DEFAULT, argp->acl_default);
 
-out_drop_write:
+out_drop_lock:
+	fh_unlock(fh);
 	fh_drop_write(fh);
 out_errno:
 	nfserr = nfserrno(error);
--- zfcpdump-kernel-4.4.orig/fs/nfsd/nfs4acl.c
+++ zfcpdump-kernel-4.4/fs/nfsd/nfs4acl.c
@@ -770,9 +770,6 @@ nfsd4_set_nfs4_acl(struct svc_rqst *rqst
 	dentry = fhp->fh_dentry;
 	inode = d_inode(dentry);
 
-	if (!inode->i_op->set_acl || !IS_POSIXACL(inode))
-		return nfserr_attrnotsupp;
-
 	if (S_ISDIR(inode->i_mode))
 		flags = NFS4_ACL_DIR;
 
@@ -782,16 +779,19 @@ nfsd4_set_nfs4_acl(struct svc_rqst *rqst
 	if (host_error < 0)
 		goto out_nfserr;
 
-	host_error = inode->i_op->set_acl(inode, pacl, ACL_TYPE_ACCESS);
+	fh_lock(fhp);
+
+	host_error = set_posix_acl(inode, ACL_TYPE_ACCESS, pacl);
 	if (host_error < 0)
-		goto out_release;
+		goto out_drop_lock;
 
 	if (S_ISDIR(inode->i_mode)) {
-		host_error = inode->i_op->set_acl(inode, dpacl,
-						  ACL_TYPE_DEFAULT);
+		host_error = set_posix_acl(inode, ACL_TYPE_DEFAULT, dpacl);
 	}
 
-out_release:
+out_drop_lock:
+	fh_unlock(fhp);
+
 	posix_acl_release(pacl);
 	posix_acl_release(dpacl);
 out_nfserr:
--- zfcpdump-kernel-4.4.orig/fs/nfsd/nfs4callback.c
+++ zfcpdump-kernel-4.4/fs/nfsd/nfs4callback.c
@@ -710,22 +710,6 @@ static struct rpc_cred *get_backchannel_
 	}
 }
 
-static struct rpc_clnt *create_backchannel_client(struct rpc_create_args *args)
-{
-	struct rpc_xprt *xprt;
-
-	if (args->protocol != XPRT_TRANSPORT_BC_TCP)
-		return rpc_create(args);
-
-	xprt = args->bc_xprt->xpt_bc_xprt;
-	if (xprt) {
-		xprt_get(xprt);
-		return rpc_create_xprt(args, xprt);
-	}
-
-	return rpc_create(args);
-}
-
 static int setup_callback_client(struct nfs4_client *clp, struct nfs4_cb_conn *conn, struct nfsd4_session *ses)
 {
 	int maxtime = max_cb_time(clp->net);
@@ -768,7 +752,7 @@ static int setup_callback_client(struct
 		args.authflavor = ses->se_cb_sec.flavor;
 	}
 	/* Create RPC client */
-	client = create_backchannel_client(&args);
+	client = rpc_create(&args);
 	if (IS_ERR(client)) {
 		dprintk("NFSD: couldn't create callback client: %ld\n",
 			PTR_ERR(client));
--- zfcpdump-kernel-4.4.orig/fs/nfsd/nfs4proc.c
+++ zfcpdump-kernel-4.4/fs/nfsd/nfs4proc.c
@@ -877,6 +877,7 @@ nfsd4_secinfo(struct svc_rqst *rqstp, st
 				    &exp, &dentry);
 	if (err)
 		return err;
+	fh_unlock(&cstate->current_fh);
 	if (d_really_is_negative(dentry)) {
 		exp_put(exp);
 		err = nfserr_noent;
--- zfcpdump-kernel-4.4.orig/fs/nfsd/nfs4state.c
+++ zfcpdump-kernel-4.4/fs/nfsd/nfs4state.c
@@ -1200,27 +1200,6 @@ free_ol_stateid_reaplist(struct list_hea
 	}
 }
 
-static void release_lockowner(struct nfs4_lockowner *lo)
-{
-	struct nfs4_client *clp = lo->lo_owner.so_client;
-	struct nfs4_ol_stateid *stp;
-	struct list_head reaplist;
-
-	INIT_LIST_HEAD(&reaplist);
-
-	spin_lock(&clp->cl_lock);
-	unhash_lockowner_locked(lo);
-	while (!list_empty(&lo->lo_owner.so_stateids)) {
-		stp = list_first_entry(&lo->lo_owner.so_stateids,
-				struct nfs4_ol_stateid, st_perstateowner);
-		WARN_ON(!unhash_lock_stateid(stp));
-		put_ol_stateid_locked(stp, &reaplist);
-	}
-	spin_unlock(&clp->cl_lock);
-	free_ol_stateid_reaplist(&reaplist);
-	nfs4_put_stateowner(&lo->lo_owner);
-}
-
 static void release_open_stateid_locks(struct nfs4_ol_stateid *open_stp,
 				       struct list_head *reaplist)
 {
@@ -3452,6 +3431,10 @@ init_open_stateid(struct nfs4_ol_stateid
 	struct nfs4_openowner *oo = open->op_openowner;
 	struct nfs4_ol_stateid *retstp = NULL;
 
+	/* We are moving these outside of the spinlocks to avoid the warnings */
+	mutex_init(&stp->st_mutex);
+	mutex_lock(&stp->st_mutex);
+
 	spin_lock(&oo->oo_owner.so_client->cl_lock);
 	spin_lock(&fp->fi_lock);
 
@@ -3467,13 +3450,17 @@ init_open_stateid(struct nfs4_ol_stateid
 	stp->st_access_bmap = 0;
 	stp->st_deny_bmap = 0;
 	stp->st_openstp = NULL;
-	init_rwsem(&stp->st_rwsem);
 	list_add(&stp->st_perstateowner, &oo->oo_owner.so_stateids);
 	list_add(&stp->st_perfile, &fp->fi_stateids);
 
 out_unlock:
 	spin_unlock(&fp->fi_lock);
 	spin_unlock(&oo->oo_owner.so_client->cl_lock);
+	if (retstp) {
+		mutex_lock(&retstp->st_mutex);
+		/* Not that we need to, just for neatness */
+		mutex_unlock(&stp->st_mutex);
+	}
 	return retstp;
 }
 
@@ -4300,32 +4287,34 @@ nfsd4_process_open2(struct svc_rqst *rqs
 	 */
 	if (stp) {
 		/* Stateid was found, this is an OPEN upgrade */
-		down_read(&stp->st_rwsem);
+		mutex_lock(&stp->st_mutex);
 		status = nfs4_upgrade_open(rqstp, fp, current_fh, stp, open);
 		if (status) {
-			up_read(&stp->st_rwsem);
+			mutex_unlock(&stp->st_mutex);
 			goto out;
 		}
 	} else {
 		stp = open->op_stp;
 		open->op_stp = NULL;
+		/*
+		 * init_open_stateid() either returns a locked stateid
+		 * it found, or initializes and locks the new one we passed in
+		 */
 		swapstp = init_open_stateid(stp, fp, open);
 		if (swapstp) {
 			nfs4_put_stid(&stp->st_stid);
 			stp = swapstp;
-			down_read(&stp->st_rwsem);
 			status = nfs4_upgrade_open(rqstp, fp, current_fh,
 						stp, open);
 			if (status) {
-				up_read(&stp->st_rwsem);
+				mutex_unlock(&stp->st_mutex);
 				goto out;
 			}
 			goto upgrade_out;
 		}
-		down_read(&stp->st_rwsem);
 		status = nfs4_get_vfs_file(rqstp, fp, current_fh, stp, open);
 		if (status) {
-			up_read(&stp->st_rwsem);
+			mutex_unlock(&stp->st_mutex);
 			release_open_stateid(stp);
 			goto out;
 		}
@@ -4337,7 +4326,7 @@ nfsd4_process_open2(struct svc_rqst *rqs
 	}
 upgrade_out:
 	nfs4_inc_and_copy_stateid(&open->op_stateid, &stp->st_stid);
-	up_read(&stp->st_rwsem);
+	mutex_unlock(&stp->st_mutex);
 
 	if (nfsd4_has_session(&resp->cstate)) {
 		if (open->op_deleg_want & NFS4_SHARE_WANT_NO_DELEG) {
@@ -4872,6 +4861,32 @@ nfsd4_test_stateid(struct svc_rqst *rqst
 	return nfs_ok;
 }
 
+static __be32
+nfsd4_free_lock_stateid(stateid_t *stateid, struct nfs4_stid *s)
+{
+	struct nfs4_ol_stateid *stp = openlockstateid(s);
+	__be32 ret;
+
+	mutex_lock(&stp->st_mutex);
+
+	ret = check_stateid_generation(stateid, &s->sc_stateid, 1);
+	if (ret)
+		goto out;
+
+	ret = nfserr_locks_held;
+	if (check_for_locks(stp->st_stid.sc_file,
+			    lockowner(stp->st_stateowner)))
+		goto out;
+
+	release_lock_stateid(stp);
+	ret = nfs_ok;
+
+out:
+	mutex_unlock(&stp->st_mutex);
+	nfs4_put_stid(s);
+	return ret;
+}
+
 __be32
 nfsd4_free_stateid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
 		   struct nfsd4_free_stateid *free_stateid)
@@ -4879,7 +4894,6 @@ nfsd4_free_stateid(struct svc_rqst *rqst
 	stateid_t *stateid = &free_stateid->fr_stateid;
 	struct nfs4_stid *s;
 	struct nfs4_delegation *dp;
-	struct nfs4_ol_stateid *stp;
 	struct nfs4_client *cl = cstate->session->se_client;
 	__be32 ret = nfserr_bad_stateid;
 
@@ -4898,18 +4912,9 @@ nfsd4_free_stateid(struct svc_rqst *rqst
 		ret = nfserr_locks_held;
 		break;
 	case NFS4_LOCK_STID:
-		ret = check_stateid_generation(stateid, &s->sc_stateid, 1);
-		if (ret)
-			break;
-		stp = openlockstateid(s);
-		ret = nfserr_locks_held;
-		if (check_for_locks(stp->st_stid.sc_file,
-				    lockowner(stp->st_stateowner)))
-			break;
-		WARN_ON(!unhash_lock_stateid(stp));
+		atomic_inc(&s->sc_count);
 		spin_unlock(&cl->cl_lock);
-		nfs4_put_stid(s);
-		ret = nfs_ok;
+		ret = nfsd4_free_lock_stateid(stateid, s);
 		goto out;
 	case NFS4_REVOKED_DELEG_STID:
 		dp = delegstateid(s);
@@ -4950,12 +4955,12 @@ static __be32 nfs4_seqid_op_checks(struc
 		 * revoked delegations are kept only for free_stateid.
 		 */
 		return nfserr_bad_stateid;
-	down_write(&stp->st_rwsem);
+	mutex_lock(&stp->st_mutex);
 	status = check_stateid_generation(stateid, &stp->st_stid.sc_stateid, nfsd4_has_session(cstate));
 	if (status == nfs_ok)
 		status = nfs4_check_fh(current_fh, &stp->st_stid);
 	if (status != nfs_ok)
-		up_write(&stp->st_rwsem);
+		mutex_unlock(&stp->st_mutex);
 	return status;
 }
 
@@ -5003,7 +5008,7 @@ static __be32 nfs4_preprocess_confirmed_
 		return status;
 	oo = openowner(stp->st_stateowner);
 	if (!(oo->oo_flags & NFS4_OO_CONFIRMED)) {
-		up_write(&stp->st_rwsem);
+		mutex_unlock(&stp->st_mutex);
 		nfs4_put_stid(&stp->st_stid);
 		return nfserr_bad_stateid;
 	}
@@ -5035,12 +5040,12 @@ nfsd4_open_confirm(struct svc_rqst *rqst
 	oo = openowner(stp->st_stateowner);
 	status = nfserr_bad_stateid;
 	if (oo->oo_flags & NFS4_OO_CONFIRMED) {
-		up_write(&stp->st_rwsem);
+		mutex_unlock(&stp->st_mutex);
 		goto put_stateid;
 	}
 	oo->oo_flags |= NFS4_OO_CONFIRMED;
 	nfs4_inc_and_copy_stateid(&oc->oc_resp_stateid, &stp->st_stid);
-	up_write(&stp->st_rwsem);
+	mutex_unlock(&stp->st_mutex);
 	dprintk("NFSD: %s: success, seqid=%d stateid=" STATEID_FMT "\n",
 		__func__, oc->oc_seqid, STATEID_VAL(&stp->st_stid.sc_stateid));
 
@@ -5116,7 +5121,7 @@ nfsd4_open_downgrade(struct svc_rqst *rq
 	nfs4_inc_and_copy_stateid(&od->od_stateid, &stp->st_stid);
 	status = nfs_ok;
 put_stateid:
-	up_write(&stp->st_rwsem);
+	mutex_unlock(&stp->st_mutex);
 	nfs4_put_stid(&stp->st_stid);
 out:
 	nfsd4_bump_seqid(cstate, status);
@@ -5169,7 +5174,7 @@ nfsd4_close(struct svc_rqst *rqstp, stru
 	if (status)
 		goto out; 
 	nfs4_inc_and_copy_stateid(&close->cl_stateid, &stp->st_stid);
-	up_write(&stp->st_rwsem);
+	mutex_unlock(&stp->st_mutex);
 
 	nfsd4_close_open_stateid(stp);
 
@@ -5395,7 +5400,7 @@ init_lock_stateid(struct nfs4_ol_stateid
 	stp->st_access_bmap = 0;
 	stp->st_deny_bmap = open_stp->st_deny_bmap;
 	stp->st_openstp = open_stp;
-	init_rwsem(&stp->st_rwsem);
+	mutex_init(&stp->st_mutex);
 	list_add(&stp->st_locks, &open_stp->st_locks);
 	list_add(&stp->st_perstateowner, &lo->lo_owner.so_stateids);
 	spin_lock(&fp->fi_lock);
@@ -5476,7 +5481,7 @@ static __be32
 lookup_or_create_lock_state(struct nfsd4_compound_state *cstate,
 			    struct nfs4_ol_stateid *ost,
 			    struct nfsd4_lock *lock,
-			    struct nfs4_ol_stateid **lst, bool *new)
+			    struct nfs4_ol_stateid **plst, bool *new)
 {
 	__be32 status;
 	struct nfs4_file *fi = ost->st_stid.sc_file;
@@ -5484,7 +5489,9 @@ lookup_or_create_lock_state(struct nfsd4
 	struct nfs4_client *cl = oo->oo_owner.so_client;
 	struct inode *inode = d_inode(cstate->current_fh.fh_dentry);
 	struct nfs4_lockowner *lo;
+	struct nfs4_ol_stateid *lst;
 	unsigned int strhashval;
+	bool hashed;
 
 	lo = find_lockowner_str(cl, &lock->lk_new_owner);
 	if (!lo) {
@@ -5500,12 +5507,27 @@ lookup_or_create_lock_state(struct nfsd4
 			goto out;
 	}
 
-	*lst = find_or_create_lock_stateid(lo, fi, inode, ost, new);
-	if (*lst == NULL) {
+retry:
+	lst = find_or_create_lock_stateid(lo, fi, inode, ost, new);
+	if (lst == NULL) {
 		status = nfserr_jukebox;
 		goto out;
 	}
+
+	mutex_lock(&lst->st_mutex);
+
+	/* See if it's still hashed to avoid race with FREE_STATEID */
+	spin_lock(&cl->cl_lock);
+	hashed = !list_empty(&lst->st_perfile);
+	spin_unlock(&cl->cl_lock);
+
+	if (!hashed) {
+		mutex_unlock(&lst->st_mutex);
+		nfs4_put_stid(&lst->st_stid);
+		goto retry;
+	}
 	status = nfs_ok;
+	*plst = lst;
 out:
 	nfs4_put_stateowner(&lo->lo_owner);
 	return status;
@@ -5564,7 +5586,7 @@ nfsd4_lock(struct svc_rqst *rqstp, struc
 					&open_stp, nn);
 		if (status)
 			goto out;
-		up_write(&open_stp->st_rwsem);
+		mutex_unlock(&open_stp->st_mutex);
 		open_sop = openowner(open_stp->st_stateowner);
 		status = nfserr_bad_stateid;
 		if (!same_clid(&open_sop->oo_owner.so_client->cl_clientid,
@@ -5572,8 +5594,6 @@ nfsd4_lock(struct svc_rqst *rqstp, struc
 			goto out;
 		status = lookup_or_create_lock_state(cstate, open_stp, lock,
 							&lock_stp, &new);
-		if (status == nfs_ok)
-			down_write(&lock_stp->st_rwsem);
 	} else {
 		status = nfs4_preprocess_seqid_op(cstate,
 				       lock->lk_old_lock_seqid,
@@ -5677,7 +5697,7 @@ out:
 		    seqid_mutating_err(ntohl(status)))
 			lock_sop->lo_owner.so_seqid++;
 
-		up_write(&lock_stp->st_rwsem);
+		mutex_unlock(&lock_stp->st_mutex);
 
 		/*
 		 * If this is a new, never-before-used stateid, and we are
@@ -5847,7 +5867,7 @@ nfsd4_locku(struct svc_rqst *rqstp, stru
 fput:
 	fput(filp);
 put_stateid:
-	up_write(&stp->st_rwsem);
+	mutex_unlock(&stp->st_mutex);
 	nfs4_put_stid(&stp->st_stid);
 out:
 	nfsd4_bump_seqid(cstate, status);
@@ -5911,6 +5931,7 @@ nfsd4_release_lockowner(struct svc_rqst
 	__be32 status;
 	struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id);
 	struct nfs4_client *clp;
+	LIST_HEAD (reaplist);
 
 	dprintk("nfsd4_release_lockowner clientid: (%08x/%08x):\n",
 		clid->cl_boot, clid->cl_id);
@@ -5941,9 +5962,23 @@ nfsd4_release_lockowner(struct svc_rqst
 		nfs4_get_stateowner(sop);
 		break;
 	}
+	if (!lo) {
+		spin_unlock(&clp->cl_lock);
+		return status;
+	}
+
+	unhash_lockowner_locked(lo);
+	while (!list_empty(&lo->lo_owner.so_stateids)) {
+		stp = list_first_entry(&lo->lo_owner.so_stateids,
+				       struct nfs4_ol_stateid,
+				       st_perstateowner);
+		WARN_ON(!unhash_lock_stateid(stp));
+		put_ol_stateid_locked(stp, &reaplist);
+	}
 	spin_unlock(&clp->cl_lock);
-	if (lo)
-		release_lockowner(lo);
+	free_ol_stateid_reaplist(&reaplist);
+	nfs4_put_stateowner(&lo->lo_owner);
+
 	return status;
 }
 
--- zfcpdump-kernel-4.4.orig/fs/nfsd/nfs4xdr.c
+++ zfcpdump-kernel-4.4/fs/nfsd/nfs4xdr.c
@@ -1072,8 +1072,9 @@ nfsd4_decode_rename(struct nfsd4_compoun
 
 	READ_BUF(4);
 	rename->rn_snamelen = be32_to_cpup(p++);
-	READ_BUF(rename->rn_snamelen + 4);
+	READ_BUF(rename->rn_snamelen);
 	SAVEMEM(rename->rn_sname, rename->rn_snamelen);
+	READ_BUF(4);
 	rename->rn_tnamelen = be32_to_cpup(p++);
 	READ_BUF(rename->rn_tnamelen);
 	SAVEMEM(rename->rn_tname, rename->rn_tnamelen);
@@ -1155,13 +1156,14 @@ nfsd4_decode_setclientid(struct nfsd4_co
 	READ_BUF(8);
 	setclientid->se_callback_prog = be32_to_cpup(p++);
 	setclientid->se_callback_netid_len = be32_to_cpup(p++);
-
-	READ_BUF(setclientid->se_callback_netid_len + 4);
+	READ_BUF(setclientid->se_callback_netid_len);
 	SAVEMEM(setclientid->se_callback_netid_val, setclientid->se_callback_netid_len);
+	READ_BUF(4);
 	setclientid->se_callback_addr_len = be32_to_cpup(p++);
 
-	READ_BUF(setclientid->se_callback_addr_len + 4);
+	READ_BUF(setclientid->se_callback_addr_len);
 	SAVEMEM(setclientid->se_callback_addr_val, setclientid->se_callback_addr_len);
+	READ_BUF(4);
 	setclientid->se_callback_ident = be32_to_cpup(p++);
 
 	DECODE_TAIL;
@@ -1815,8 +1817,9 @@ nfsd4_decode_compound(struct nfsd4_compo
 
 	READ_BUF(4);
 	argp->taglen = be32_to_cpup(p++);
-	READ_BUF(argp->taglen + 8);
+	READ_BUF(argp->taglen);
 	SAVEMEM(argp->tag, argp->taglen);
+	READ_BUF(8);
 	argp->minorversion = be32_to_cpup(p++);
 	argp->opcnt = be32_to_cpup(p++);
 	max_reply += 4 + (XDR_QUADLEN(argp->taglen) << 2);
--- zfcpdump-kernel-4.4.orig/fs/nfsd/nfsctl.c
+++ zfcpdump-kernel-4.4/fs/nfsd/nfsctl.c
@@ -1154,20 +1154,15 @@ static int nfsd_fill_super(struct super_
 #endif
 		/* last one */ {""}
 	};
-	struct net *net = data;
-	int ret;
-
-	ret = simple_fill_super(sb, 0x6e667364, nfsd_files);
-	if (ret)
-		return ret;
-	sb->s_fs_info = get_net(net);
-	return 0;
+	get_net(sb->s_fs_info);
+	return simple_fill_super(sb, 0x6e667364, nfsd_files);
 }
 
 static struct dentry *nfsd_mount(struct file_system_type *fs_type,
 	int flags, const char *dev_name, void *data)
 {
-	return mount_ns(fs_type, flags, current->nsproxy->net_ns, nfsd_fill_super);
+	struct net *net = current->nsproxy->net_ns;
+	return mount_ns(fs_type, flags, data, net, net->user_ns, nfsd_fill_super);
 }
 
 static void nfsd_umount(struct super_block *sb)
--- zfcpdump-kernel-4.4.orig/fs/nfsd/state.h
+++ zfcpdump-kernel-4.4/fs/nfsd/state.h
@@ -535,7 +535,7 @@ struct nfs4_ol_stateid {
 	unsigned char			st_access_bmap;
 	unsigned char			st_deny_bmap;
 	struct nfs4_ol_stateid		*st_openstp;
-	struct rw_semaphore		st_rwsem;
+	struct mutex			st_mutex;
 };
 
 static inline struct nfs4_ol_stateid *openlockstateid(struct nfs4_stid *s)
--- zfcpdump-kernel-4.4.orig/fs/nilfs2/the_nilfs.c
+++ zfcpdump-kernel-4.4/fs/nilfs2/the_nilfs.c
@@ -443,7 +443,7 @@ static int nilfs_valid_sb(struct nilfs_s
 	if (!sbp || le16_to_cpu(sbp->s_magic) != NILFS_SUPER_MAGIC)
 		return 0;
 	bytes = le16_to_cpu(sbp->s_bytes);
-	if (bytes > BLOCK_SIZE)
+	if (bytes < sumoff + 4 || bytes > BLOCK_SIZE)
 		return 0;
 	crc = crc32_le(le32_to_cpu(sbp->s_crc_seed), (unsigned char *)sbp,
 		       sumoff);
--- zfcpdump-kernel-4.4.orig/fs/notify/fanotify/fanotify.c
+++ zfcpdump-kernel-4.4/fs/notify/fanotify/fanotify.c
@@ -67,18 +67,7 @@ static int fanotify_get_response(struct
 
 	pr_debug("%s: group=%p event=%p\n", __func__, group, event);
 
-	wait_event(group->fanotify_data.access_waitq, event->response ||
-				atomic_read(&group->fanotify_data.bypass_perm));
-
-	if (!event->response) {	/* bypass_perm set */
-		/*
-		 * Event was canceled because group is being destroyed. Remove
-		 * it from group's event list because we are responsible for
-		 * freeing the permission event.
-		 */
-		fsnotify_remove_event(group, &event->fae.fse);
-		return 0;
-	}
+	wait_event(group->fanotify_data.access_waitq, event->response);
 
 	/* userspace responded, convert to something usable */
 	switch (event->response) {
--- zfcpdump-kernel-4.4.orig/fs/notify/fanotify/fanotify_user.c
+++ zfcpdump-kernel-4.4/fs/notify/fanotify/fanotify_user.c
@@ -358,16 +358,20 @@ static int fanotify_release(struct inode
 
 #ifdef CONFIG_FANOTIFY_ACCESS_PERMISSIONS
 	struct fanotify_perm_event_info *event, *next;
+	struct fsnotify_event *fsn_event;
 
 	/*
-	 * There may be still new events arriving in the notification queue
-	 * but since userspace cannot use fanotify fd anymore, no event can
-	 * enter or leave access_list by now.
+	 * Stop new events from arriving in the notification queue. since
+	 * userspace cannot use fanotify fd anymore, no event can enter or
+	 * leave access_list by now either.
 	 */
-	spin_lock(&group->fanotify_data.access_lock);
-
-	atomic_inc(&group->fanotify_data.bypass_perm);
+	fsnotify_group_stop_queueing(group);
 
+	/*
+	 * Process all permission events on access_list and notification queue
+	 * and simulate reply from userspace.
+	 */
+	spin_lock(&group->fanotify_data.access_lock);
 	list_for_each_entry_safe(event, next, &group->fanotify_data.access_list,
 				 fae.fse.list) {
 		pr_debug("%s: found group=%p event=%p\n", __func__, group,
@@ -379,12 +383,21 @@ static int fanotify_release(struct inode
 	spin_unlock(&group->fanotify_data.access_lock);
 
 	/*
-	 * Since bypass_perm is set, newly queued events will not wait for
-	 * access response. Wake up the already sleeping ones now.
-	 * synchronize_srcu() in fsnotify_destroy_group() will wait for all
-	 * processes sleeping in fanotify_handle_event() waiting for access
-	 * response and thus also for all permission events to be freed.
+	 * Destroy all non-permission events. For permission events just
+	 * dequeue them and set the response. They will be freed once the
+	 * response is consumed and fanotify_get_response() returns.
 	 */
+	mutex_lock(&group->notification_mutex);
+	while (!fsnotify_notify_queue_is_empty(group)) {
+		fsn_event = fsnotify_remove_first_event(group);
+		if (!(fsn_event->mask & FAN_ALL_PERM_EVENTS))
+			fsnotify_destroy_event(group, fsn_event);
+		else
+			FANOTIFY_PE(fsn_event)->response = FAN_ALLOW;
+	}
+	mutex_unlock(&group->notification_mutex);
+
+	/* Response for all permission events it set, wakeup waiters */
 	wake_up(&group->fanotify_data.access_waitq);
 #endif
 
@@ -755,7 +768,6 @@ SYSCALL_DEFINE2(fanotify_init, unsigned
 	spin_lock_init(&group->fanotify_data.access_lock);
 	init_waitqueue_head(&group->fanotify_data.access_waitq);
 	INIT_LIST_HEAD(&group->fanotify_data.access_list);
-	atomic_set(&group->fanotify_data.bypass_perm, 0);
 #endif
 	switch (flags & FAN_ALL_CLASS_BITS) {
 	case FAN_CLASS_NOTIF:
--- zfcpdump-kernel-4.4.orig/fs/notify/group.c
+++ zfcpdump-kernel-4.4/fs/notify/group.c
@@ -22,6 +22,7 @@
 #include <linux/srcu.h>
 #include <linux/rculist.h>
 #include <linux/wait.h>
+#include <linux/module.h>
 
 #include <linux/fsnotify_backend.h>
 #include "fsnotify.h"
@@ -40,6 +41,17 @@ static void fsnotify_final_destroy_group
 }
 
 /*
+ * Stop queueing new events for this group. Once this function returns
+ * fsnotify_add_event() will not add any new events to the group's queue.
+ */
+void fsnotify_group_stop_queueing(struct fsnotify_group *group)
+{
+	mutex_lock(&group->notification_mutex);
+	group->shutdown = true;
+	mutex_unlock(&group->notification_mutex);
+}
+
+/*
  * Trying to get rid of a group. Remove all marks, flush all events and release
  * the group reference.
  * Note that another thread calling fsnotify_clear_marks_by_group() may still
@@ -47,6 +59,14 @@ static void fsnotify_final_destroy_group
  */
 void fsnotify_destroy_group(struct fsnotify_group *group)
 {
+	/*
+	 * Stop queueing new events. The code below is careful enough to not
+	 * require this but fanotify needs to stop queuing events even before
+	 * fsnotify_destroy_group() is called and this makes the other callers
+	 * of fsnotify_destroy_group() to see the same behavior.
+	 */
+	fsnotify_group_stop_queueing(group);
+
 	/* clear all inode marks for this group */
 	fsnotify_clear_marks_by_group(group);
 
@@ -72,6 +92,7 @@ void fsnotify_get_group(struct fsnotify_
 {
 	atomic_inc(&group->refcnt);
 }
+EXPORT_SYMBOL(fsnotify_get_group);
 
 /*
  * Drop a reference to a group.  Free it if it's through.
@@ -81,6 +102,7 @@ void fsnotify_put_group(struct fsnotify_
 	if (atomic_dec_and_test(&group->refcnt))
 		fsnotify_final_destroy_group(group);
 }
+EXPORT_SYMBOL(fsnotify_put_group);
 
 /*
  * Create a new fsnotify_group and hold a reference for the group returned.
@@ -109,6 +131,7 @@ struct fsnotify_group *fsnotify_alloc_gr
 
 	return group;
 }
+EXPORT_SYMBOL(fsnotify_alloc_group);
 
 int fsnotify_fasync(int fd, struct file *file, int on)
 {
--- zfcpdump-kernel-4.4.orig/fs/notify/mark.c
+++ zfcpdump-kernel-4.4/fs/notify/mark.c
@@ -109,6 +109,7 @@ void fsnotify_put_mark(struct fsnotify_m
 		mark->free_mark(mark);
 	}
 }
+EXPORT_SYMBOL(fsnotify_put_mark);
 
 /* Calculate mask of events for a list of marks */
 u32 fsnotify_recalc_mask(struct hlist_head *head)
@@ -208,6 +209,7 @@ void fsnotify_destroy_mark(struct fsnoti
 	mutex_unlock(&group->mark_mutex);
 	fsnotify_free_mark(mark);
 }
+EXPORT_SYMBOL(fsnotify_destroy_mark);
 
 void fsnotify_destroy_marks(struct hlist_head *head, spinlock_t *lock)
 {
@@ -392,6 +394,7 @@ err:
 
 	return ret;
 }
+EXPORT_SYMBOL(fsnotify_add_mark);
 
 int fsnotify_add_mark(struct fsnotify_mark *mark, struct fsnotify_group *group,
 		      struct inode *inode, struct vfsmount *mnt, int allow_dups)
@@ -492,6 +495,7 @@ void fsnotify_init_mark(struct fsnotify_
 	atomic_set(&mark->refcnt, 1);
 	mark->free_mark = free_mark;
 }
+EXPORT_SYMBOL(fsnotify_init_mark);
 
 static int fsnotify_mark_destroy(void *ignored)
 {
--- zfcpdump-kernel-4.4.orig/fs/notify/notification.c
+++ zfcpdump-kernel-4.4/fs/notify/notification.c
@@ -82,7 +82,8 @@ void fsnotify_destroy_event(struct fsnot
  * Add an event to the group notification queue.  The group can later pull this
  * event off the queue to deal with.  The function returns 0 if the event was
  * added to the queue, 1 if the event was merged with some other queued event,
- * 2 if the queue of events has overflown.
+ * 2 if the event was not queued - either the queue of events has overflown
+ * or the group is shutting down.
  */
 int fsnotify_add_event(struct fsnotify_group *group,
 		       struct fsnotify_event *event,
@@ -96,6 +97,11 @@ int fsnotify_add_event(struct fsnotify_g
 
 	mutex_lock(&group->notification_mutex);
 
+	if (group->shutdown) {
+		mutex_unlock(&group->notification_mutex);
+		return 2;
+	}
+
 	if (group->q_len >= group->max_events) {
 		ret = 2;
 		/* Queue overflow event only if it isn't already queued */
@@ -126,21 +132,6 @@ queue:
 }
 
 /*
- * Remove @event from group's notification queue. It is the responsibility of
- * the caller to destroy the event.
- */
-void fsnotify_remove_event(struct fsnotify_group *group,
-			   struct fsnotify_event *event)
-{
-	mutex_lock(&group->notification_mutex);
-	if (!list_empty(&event->list)) {
-		list_del_init(&event->list);
-		group->q_len--;
-	}
-	mutex_unlock(&group->notification_mutex);
-}
-
-/*
  * Remove and return the first event from the notification list.  It is the
  * responsibility of the caller to destroy the obtained event
  */
--- zfcpdump-kernel-4.4.orig/fs/ocfs2/acl.c
+++ zfcpdump-kernel-4.4/fs/ocfs2/acl.c
@@ -322,3 +322,90 @@ struct posix_acl *ocfs2_iop_get_acl(stru
 	brelse(di_bh);
 	return acl;
 }
+
+int ocfs2_acl_chmod(struct inode *inode, struct buffer_head *bh)
+{
+	struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
+	struct posix_acl *acl;
+	int ret;
+
+	if (S_ISLNK(inode->i_mode))
+		return -EOPNOTSUPP;
+
+	if (!(osb->s_mount_opt & OCFS2_MOUNT_POSIX_ACL))
+		return 0;
+
+	acl = ocfs2_get_acl_nolock(inode, ACL_TYPE_ACCESS, bh);
+	if (IS_ERR(acl) || !acl)
+		return PTR_ERR(acl);
+	ret = __posix_acl_chmod(&acl, GFP_KERNEL, inode->i_mode);
+	if (ret)
+		return ret;
+	ret = ocfs2_set_acl(NULL, inode, NULL, ACL_TYPE_ACCESS,
+			    acl, NULL, NULL);
+	posix_acl_release(acl);
+	return ret;
+}
+
+/*
+ * Initialize the ACLs of a new inode. If parent directory has default ACL,
+ * then clone to new inode. Called from ocfs2_mknod.
+ */
+int ocfs2_init_acl(handle_t *handle,
+		   struct inode *inode,
+		   struct inode *dir,
+		   struct buffer_head *di_bh,
+		   struct buffer_head *dir_bh,
+		   struct ocfs2_alloc_context *meta_ac,
+		   struct ocfs2_alloc_context *data_ac)
+{
+	struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
+	struct posix_acl *acl = NULL;
+	int ret = 0, ret2;
+	umode_t mode;
+
+	if (!S_ISLNK(inode->i_mode)) {
+		if (osb->s_mount_opt & OCFS2_MOUNT_POSIX_ACL) {
+			acl = ocfs2_get_acl_nolock(dir, ACL_TYPE_DEFAULT,
+						   dir_bh);
+			if (IS_ERR(acl))
+				return PTR_ERR(acl);
+		}
+		if (!acl) {
+			mode = inode->i_mode & ~current_umask();
+			ret = ocfs2_acl_set_mode(inode, di_bh, handle, mode);
+			if (ret) {
+				mlog_errno(ret);
+				goto cleanup;
+			}
+		}
+	}
+	if ((osb->s_mount_opt & OCFS2_MOUNT_POSIX_ACL) && acl) {
+		if (S_ISDIR(inode->i_mode)) {
+			ret = ocfs2_set_acl(handle, inode, di_bh,
+					    ACL_TYPE_DEFAULT, acl,
+					    meta_ac, data_ac);
+			if (ret)
+				goto cleanup;
+		}
+		mode = inode->i_mode;
+		ret = __posix_acl_create(&acl, GFP_NOFS, &mode);
+		if (ret < 0)
+			return ret;
+
+		ret2 = ocfs2_acl_set_mode(inode, di_bh, handle, mode);
+		if (ret2) {
+			mlog_errno(ret2);
+			ret = ret2;
+			goto cleanup;
+		}
+		if (ret > 0) {
+			ret = ocfs2_set_acl(handle, inode,
+					    di_bh, ACL_TYPE_ACCESS,
+					    acl, meta_ac, data_ac);
+		}
+	}
+cleanup:
+	posix_acl_release(acl);
+	return ret;
+}
--- zfcpdump-kernel-4.4.orig/fs/ocfs2/acl.h
+++ zfcpdump-kernel-4.4/fs/ocfs2/acl.h
@@ -35,5 +35,10 @@ int ocfs2_set_acl(handle_t *handle,
 			 struct posix_acl *acl,
 			 struct ocfs2_alloc_context *meta_ac,
 			 struct ocfs2_alloc_context *data_ac);
+extern int ocfs2_acl_chmod(struct inode *, struct buffer_head *);
+extern int ocfs2_init_acl(handle_t *, struct inode *, struct inode *,
+			  struct buffer_head *, struct buffer_head *,
+			  struct ocfs2_alloc_context *,
+			  struct ocfs2_alloc_context *);
 
 #endif /* OCFS2_ACL_H */
--- zfcpdump-kernel-4.4.orig/fs/ocfs2/aops.c
+++ zfcpdump-kernel-4.4/fs/ocfs2/aops.c
@@ -956,6 +956,7 @@ clean_orphan:
 		tmp_ret = ocfs2_del_inode_from_orphan(osb, inode, di_bh,
 				update_isize, end);
 		if (tmp_ret < 0) {
+			ocfs2_inode_unlock(inode, 1);
 			ret = tmp_ret;
 			mlog_errno(ret);
 			brelse(di_bh);
--- zfcpdump-kernel-4.4.orig/fs/ocfs2/dlm/dlmconvert.c
+++ zfcpdump-kernel-4.4/fs/ocfs2/dlm/dlmconvert.c
@@ -287,6 +287,19 @@ enum dlm_status dlmconvert_remote(struct
 		status = DLM_DENIED;
 		goto bail;
 	}
+
+	if (lock->ml.type == type && lock->ml.convert_type == LKM_IVMODE) {
+		mlog(0, "last convert request returned DLM_RECOVERING, but "
+		     "owner has already queued and sent ast to me. res %.*s, "
+		     "(cookie=%u:%llu, type=%d, conv=%d)\n",
+		     res->lockname.len, res->lockname.name,
+		     dlm_get_lock_cookie_node(be64_to_cpu(lock->ml.cookie)),
+		     dlm_get_lock_cookie_seq(be64_to_cpu(lock->ml.cookie)),
+		     lock->ml.type, lock->ml.convert_type);
+		status = DLM_NORMAL;
+		goto bail;
+	}
+
 	res->state |= DLM_LOCK_RES_IN_PROGRESS;
 	/* move lock to local convert queue */
 	/* do not alter lock refcount.  switching lists. */
@@ -315,13 +328,22 @@ enum dlm_status dlmconvert_remote(struct
 
 	spin_lock(&res->spinlock);
 	res->state &= ~DLM_LOCK_RES_IN_PROGRESS;
-	lock->convert_pending = 0;
-	/* if it failed, move it back to granted queue */
+	/* if it failed, move it back to granted queue.
+	 * if master returns DLM_NORMAL and then down before sending ast,
+	 * it may have already been moved to granted queue, reset to
+	 * DLM_RECOVERING and retry convert */
 	if (status != DLM_NORMAL) {
 		if (status != DLM_NOTQUEUED)
 			dlm_error(status);
 		dlm_revert_pending_convert(res, lock);
+	} else if (!lock->convert_pending) {
+		mlog(0, "%s: res %.*s, owner died and lock has been moved back "
+				"to granted list, retry convert.\n",
+				dlm->name, res->lockname.len, res->lockname.name);
+		status = DLM_RECOVERING;
 	}
+
+	lock->convert_pending = 0;
 bail:
 	spin_unlock(&res->spinlock);
 
--- zfcpdump-kernel-4.4.orig/fs/ocfs2/dlm/dlmmaster.c
+++ zfcpdump-kernel-4.4/fs/ocfs2/dlm/dlmmaster.c
@@ -2519,6 +2519,11 @@ static int dlm_migrate_lockres(struct dl
 	spin_lock(&dlm->master_lock);
 	ret = dlm_add_migration_mle(dlm, res, mle, &oldmle, name,
 				    namelen, target, dlm->node_num);
+	/* get an extra reference on the mle.
+	 * otherwise the assert_master from the new
+	 * master will destroy this.
+	 */
+	dlm_get_mle_inuse(mle);
 	spin_unlock(&dlm->master_lock);
 	spin_unlock(&dlm->spinlock);
 
@@ -2554,6 +2559,7 @@ fail:
 		if (mle_added) {
 			dlm_mle_detach_hb_events(dlm, mle);
 			dlm_put_mle(mle);
+			dlm_put_mle_inuse(mle);
 		} else if (mle) {
 			kmem_cache_free(dlm_mle_cache, mle);
 			mle = NULL;
@@ -2571,17 +2577,6 @@ fail:
 	 * ensure that all assert_master work is flushed. */
 	flush_workqueue(dlm->dlm_worker);
 
-	/* get an extra reference on the mle.
-	 * otherwise the assert_master from the new
-	 * master will destroy this.
-	 * also, make sure that all callers of dlm_get_mle
-	 * take both dlm->spinlock and dlm->master_lock */
-	spin_lock(&dlm->spinlock);
-	spin_lock(&dlm->master_lock);
-	dlm_get_mle_inuse(mle);
-	spin_unlock(&dlm->master_lock);
-	spin_unlock(&dlm->spinlock);
-
 	/* notify new node and send all lock state */
 	/* call send_one_lockres with migration flag.
 	 * this serves as notice to the target node that a
@@ -3312,6 +3307,15 @@ top:
 			    mle->new_master != dead_node)
 				continue;
 
+			if (mle->new_master == dead_node && mle->inuse) {
+				mlog(ML_NOTICE, "%s: target %u died during "
+						"migration from %u, the MLE is "
+						"still keep used, ignore it!\n",
+						dlm->name, dead_node,
+						mle->master);
+				continue;
+			}
+
 			/* If we have reached this point, this mle needs to be
 			 * removed from the list and freed. */
 			dlm_clean_migration_mle(dlm, mle);
--- zfcpdump-kernel-4.4.orig/fs/ocfs2/dlm/dlmrecovery.c
+++ zfcpdump-kernel-4.4/fs/ocfs2/dlm/dlmrecovery.c
@@ -2064,7 +2064,6 @@ void dlm_move_lockres_to_recovery_list(s
 			dlm_lock_get(lock);
 			if (lock->convert_pending) {
 				/* move converting lock back to granted */
-				BUG_ON(i != DLM_CONVERTING_LIST);
 				mlog(0, "node died with convert pending "
 				     "on %.*s. move back to granted list.\n",
 				     res->lockname.len, res->lockname.name);
@@ -2360,6 +2359,8 @@ static void dlm_do_local_recovery_cleanu
 						break;
 					}
 				}
+				dlm_lockres_clear_refmap_bit(dlm, res,
+						dead_node);
 				spin_unlock(&res->spinlock);
 				continue;
 			}
--- zfcpdump-kernel-4.4.orig/fs/ocfs2/dlmglue.c
+++ zfcpdump-kernel-4.4/fs/ocfs2/dlmglue.c
@@ -1390,6 +1390,7 @@ static int __ocfs2_cluster_lock(struct o
 	unsigned int gen;
 	int noqueue_attempted = 0;
 	int dlm_locked = 0;
+	int kick_dc = 0;
 
 	if (!(lockres->l_flags & OCFS2_LOCK_INITIALIZED)) {
 		mlog_errno(-EINVAL);
@@ -1524,7 +1525,12 @@ update_holders:
 unlock:
 	lockres_clear_flags(lockres, OCFS2_LOCK_UPCONVERT_FINISHING);
 
+	/* ocfs2_unblock_lock reques on seeing OCFS2_LOCK_UPCONVERT_FINISHING */
+	kick_dc = (lockres->l_flags & OCFS2_LOCK_BLOCKED);
+
 	spin_unlock_irqrestore(&lockres->l_lock, flags);
+	if (kick_dc)
+		ocfs2_wake_downconvert_thread(osb);
 out:
 	/*
 	 * This is helping work around a lock inversion between the page lock
--- zfcpdump-kernel-4.4.orig/fs/ocfs2/file.c
+++ zfcpdump-kernel-4.4/fs/ocfs2/file.c
@@ -1268,20 +1268,20 @@ bail_unlock_rw:
 	if (size_change)
 		ocfs2_rw_unlock(inode, 1);
 bail:
-	brelse(bh);
 
 	/* Release quota pointers in case we acquired them */
 	for (qtype = 0; qtype < OCFS2_MAXQUOTAS; qtype++)
 		dqput(transfer_to[qtype]);
 
 	if (!status && attr->ia_valid & ATTR_MODE) {
-		status = posix_acl_chmod(inode, inode->i_mode);
+		status = ocfs2_acl_chmod(inode, bh);
 		if (status < 0)
 			mlog_errno(status);
 	}
 	if (inode_locked)
 		ocfs2_inode_unlock(inode, 1);
 
+	brelse(bh);
 	return status;
 }
 
@@ -1536,7 +1536,8 @@ static int ocfs2_zero_partial_clusters(s
 				       u64 start, u64 len)
 {
 	int ret = 0;
-	u64 tmpend, end = start + len;
+	u64 tmpend = 0;
+	u64 end = start + len;
 	struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
 	unsigned int csize = osb->s_clustersize;
 	handle_t *handle;
@@ -1568,18 +1569,31 @@ static int ocfs2_zero_partial_clusters(s
 	}
 
 	/*
-	 * We want to get the byte offset of the end of the 1st cluster.
+	 * If start is on a cluster boundary and end is somewhere in another
+	 * cluster, we have not COWed the cluster starting at start, unless
+	 * end is also within the same cluster. So, in this case, we skip this
+	 * first call to ocfs2_zero_range_for_truncate() truncate and move on
+	 * to the next one.
 	 */
-	tmpend = (u64)osb->s_clustersize + (start & ~(osb->s_clustersize - 1));
-	if (tmpend > end)
-		tmpend = end;
-
-	trace_ocfs2_zero_partial_clusters_range1((unsigned long long)start,
-						 (unsigned long long)tmpend);
-
-	ret = ocfs2_zero_range_for_truncate(inode, handle, start, tmpend);
-	if (ret)
-		mlog_errno(ret);
+	if ((start & (csize - 1)) != 0) {
+		/*
+		 * We want to get the byte offset of the end of the 1st
+		 * cluster.
+		 */
+		tmpend = (u64)osb->s_clustersize +
+			(start & ~(osb->s_clustersize - 1));
+		if (tmpend > end)
+			tmpend = end;
+
+		trace_ocfs2_zero_partial_clusters_range1(
+			(unsigned long long)start,
+			(unsigned long long)tmpend);
+
+		ret = ocfs2_zero_range_for_truncate(inode, handle, start,
+						    tmpend);
+		if (ret)
+			mlog_errno(ret);
+	}
 
 	if (tmpend < end) {
 		/*
--- zfcpdump-kernel-4.4.orig/fs/ocfs2/namei.c
+++ zfcpdump-kernel-4.4/fs/ocfs2/namei.c
@@ -259,7 +259,6 @@ static int ocfs2_mknod(struct inode *dir
 	struct ocfs2_dir_lookup_result lookup = { NULL, };
 	sigset_t oldset;
 	int did_block_signals = 0;
-	struct posix_acl *default_acl = NULL, *acl = NULL;
 	struct ocfs2_dentry_lock *dl = NULL;
 
 	trace_ocfs2_mknod(dir, dentry, dentry->d_name.len, dentry->d_name.name,
@@ -367,12 +366,6 @@ static int ocfs2_mknod(struct inode *dir
 		goto leave;
 	}
 
-	status = posix_acl_create(dir, &inode->i_mode, &default_acl, &acl);
-	if (status) {
-		mlog_errno(status);
-		goto leave;
-	}
-
 	handle = ocfs2_start_trans(osb, ocfs2_mknod_credits(osb->sb,
 							    S_ISDIR(mode),
 							    xattr_credits));
@@ -421,16 +414,8 @@ static int ocfs2_mknod(struct inode *dir
 		inc_nlink(dir);
 	}
 
-	if (default_acl) {
-		status = ocfs2_set_acl(handle, inode, new_fe_bh,
-				       ACL_TYPE_DEFAULT, default_acl,
-				       meta_ac, data_ac);
-	}
-	if (!status && acl) {
-		status = ocfs2_set_acl(handle, inode, new_fe_bh,
-				       ACL_TYPE_ACCESS, acl,
-				       meta_ac, data_ac);
-	}
+	status = ocfs2_init_acl(handle, inode, dir, new_fe_bh, parent_fe_bh,
+			 meta_ac, data_ac);
 
 	if (status < 0) {
 		mlog_errno(status);
@@ -472,10 +457,6 @@ static int ocfs2_mknod(struct inode *dir
 	d_instantiate(dentry, inode);
 	status = 0;
 leave:
-	if (default_acl)
-		posix_acl_release(default_acl);
-	if (acl)
-		posix_acl_release(acl);
 	if (status < 0 && did_quota_inode)
 		dquot_free_inode(inode);
 	if (handle)
--- zfcpdump-kernel-4.4.orig/fs/ocfs2/quota_global.c
+++ zfcpdump-kernel-4.4/fs/ocfs2/quota_global.c
@@ -66,7 +66,7 @@
 
 static void qsync_work_fn(struct work_struct *work);
 
-static void ocfs2_global_disk2memdqb(struct dquot *dquot, void *dp)
+static int ocfs2_global_disk2memdqb(struct dquot *dquot, void *dp)
 {
 	struct ocfs2_global_disk_dqblk *d = dp;
 	struct mem_dqblk *m = &dquot->dq_dqb;
@@ -89,9 +89,10 @@ static void ocfs2_global_disk2memdqb(str
 	if (!test_bit(DQ_LASTSET_B + QIF_ITIME_B, &dquot->dq_flags))
 		m->dqb_itime = le64_to_cpu(d->dqb_itime);
 	OCFS2_DQUOT(dquot)->dq_use_count = le32_to_cpu(d->dqb_use_count);
+	return 0;
 }
 
-static void ocfs2_global_mem2diskdqb(void *dp, struct dquot *dquot)
+static int ocfs2_global_mem2diskdqb(void *dp, struct dquot *dquot)
 {
 	struct ocfs2_global_disk_dqblk *d = dp;
 	struct mem_dqblk *m = &dquot->dq_dqb;
@@ -107,6 +108,7 @@ static void ocfs2_global_mem2diskdqb(voi
 	d->dqb_btime = cpu_to_le64(m->dqb_btime);
 	d->dqb_itime = cpu_to_le64(m->dqb_itime);
 	d->dqb_pad1 = d->dqb_pad2 = 0;
+	return 0;
 }
 
 static int ocfs2_global_is_id(void *dp, struct dquot *dquot)
--- zfcpdump-kernel-4.4.orig/fs/ocfs2/refcounttree.c
+++ zfcpdump-kernel-4.4/fs/ocfs2/refcounttree.c
@@ -4248,20 +4248,12 @@ static int ocfs2_reflink(struct dentry *
 	struct inode *inode = d_inode(old_dentry);
 	struct buffer_head *old_bh = NULL;
 	struct inode *new_orphan_inode = NULL;
-	struct posix_acl *default_acl, *acl;
-	umode_t mode;
 
 	if (!ocfs2_refcount_tree(OCFS2_SB(inode->i_sb)))
 		return -EOPNOTSUPP;
 
-	mode = inode->i_mode;
-	error = posix_acl_create(dir, &mode, &default_acl, &acl);
-	if (error) {
-		mlog_errno(error);
-		return error;
-	}
 
-	error = ocfs2_create_inode_in_orphan(dir, mode,
+	error = ocfs2_create_inode_in_orphan(dir, inode->i_mode,
 					     &new_orphan_inode);
 	if (error) {
 		mlog_errno(error);
@@ -4300,16 +4292,11 @@ static int ocfs2_reflink(struct dentry *
 	/* If the security isn't preserved, we need to re-initialize them. */
 	if (!preserve) {
 		error = ocfs2_init_security_and_acl(dir, new_orphan_inode,
-						    &new_dentry->d_name,
-						    default_acl, acl);
+						    &new_dentry->d_name);
 		if (error)
 			mlog_errno(error);
 	}
 out:
-	if (default_acl)
-		posix_acl_release(default_acl);
-	if (acl)
-		posix_acl_release(acl);
 	if (!error) {
 		error = ocfs2_mv_orphaned_inode_to_new(dir, new_orphan_inode,
 						       new_dentry);
--- zfcpdump-kernel-4.4.orig/fs/ocfs2/xattr.c
+++ zfcpdump-kernel-4.4/fs/ocfs2/xattr.c
@@ -7197,12 +7197,10 @@ out:
  */
 int ocfs2_init_security_and_acl(struct inode *dir,
 				struct inode *inode,
-				const struct qstr *qstr,
-				struct posix_acl *default_acl,
-				struct posix_acl *acl)
+				const struct qstr *qstr)
 {
-	struct buffer_head *dir_bh = NULL;
 	int ret = 0;
+	struct buffer_head *dir_bh = NULL;
 
 	ret = ocfs2_init_security_get(inode, dir, qstr, NULL);
 	if (ret) {
@@ -7215,11 +7213,9 @@ int ocfs2_init_security_and_acl(struct i
 		mlog_errno(ret);
 		goto leave;
 	}
-
-	if (!ret && default_acl)
-		ret = ocfs2_iop_set_acl(inode, default_acl, ACL_TYPE_DEFAULT);
-	if (!ret && acl)
-		ret = ocfs2_iop_set_acl(inode, acl, ACL_TYPE_ACCESS);
+	ret = ocfs2_init_acl(NULL, inode, dir, NULL, dir_bh, NULL, NULL);
+	if (ret)
+		mlog_errno(ret);
 
 	ocfs2_inode_unlock(dir, 0);
 	brelse(dir_bh);
--- zfcpdump-kernel-4.4.orig/fs/ocfs2/xattr.h
+++ zfcpdump-kernel-4.4/fs/ocfs2/xattr.h
@@ -94,7 +94,5 @@ int ocfs2_reflink_xattrs(struct inode *o
 			 bool preserve_security);
 int ocfs2_init_security_and_acl(struct inode *dir,
 				struct inode *inode,
-				const struct qstr *qstr,
-				struct posix_acl *default_acl,
-				struct posix_acl *acl);
+				const struct qstr *qstr);
 #endif /* OCFS2_XATTR_H */
--- zfcpdump-kernel-4.4.orig/fs/open.c
+++ zfcpdump-kernel-4.4/fs/open.c
@@ -34,6 +34,9 @@
 
 #include "internal.h"
 
+#define CREATE_TRACE_POINTS
+#include <trace/events/fs.h>
+
 int do_truncate(struct dentry *dentry, loff_t length, unsigned int time_attrs,
 	struct file *filp)
 {
@@ -64,6 +67,7 @@ int do_truncate(struct dentry *dentry, l
 	mutex_unlock(&dentry->d_inode->i_mutex);
 	return ret;
 }
+EXPORT_SYMBOL(do_truncate);
 
 long vfs_truncate(struct path *path, loff_t length)
 {
@@ -678,6 +682,7 @@ int open_check_o_direct(struct file *f)
 	}
 	return 0;
 }
+EXPORT_SYMBOL(open_check_o_direct);
 
 static int do_dentry_open(struct file *f,
 			  struct inode *inode,
@@ -840,16 +845,12 @@ EXPORT_SYMBOL(file_path);
 int vfs_open(const struct path *path, struct file *file,
 	     const struct cred *cred)
 {
-	struct dentry *dentry = path->dentry;
-	struct inode *inode = dentry->d_inode;
+	struct inode *inode = vfs_select_inode(path->dentry, file->f_flags);
 
-	file->f_path = *path;
-	if (dentry->d_flags & DCACHE_OP_SELECT_INODE) {
-		inode = dentry->d_op->d_select_inode(dentry, file->f_flags);
-		if (IS_ERR(inode))
-			return PTR_ERR(inode);
-	}
+	if (IS_ERR(inode))
+		return PTR_ERR(inode);
 
+	file->f_path = *path;
 	return do_dentry_open(file, inode, NULL, cred);
 }
 
@@ -995,14 +996,12 @@ struct file *filp_open(const char *filen
 EXPORT_SYMBOL(filp_open);
 
 struct file *file_open_root(struct dentry *dentry, struct vfsmount *mnt,
-			    const char *filename, int flags)
+			    const char *filename, int flags, umode_t mode)
 {
 	struct open_flags op;
-	int err = build_open_flags(flags, 0, &op);
+	int err = build_open_flags(flags, mode, &op);
 	if (err)
 		return ERR_PTR(err);
-	if (flags & O_CREAT)
-		return ERR_PTR(-EINVAL);
 	return do_file_open_root(dentry, mnt, filename, &op);
 }
 EXPORT_SYMBOL(file_open_root);
@@ -1029,6 +1028,7 @@ long do_sys_open(int dfd, const char __u
 		} else {
 			fsnotify_open(f);
 			fd_install(fd, f);
+			trace_do_sys_open(tmp->name, flags, mode);
 		}
 	}
 	putname(tmp);
--- zfcpdump-kernel-4.4.orig/fs/overlayfs/Kconfig
+++ zfcpdump-kernel-4.4/fs/overlayfs/Kconfig
@@ -8,3 +8,10 @@ config OVERLAY_FS
 	  merged with the 'upper' object.
 
 	  For more information see Documentation/filesystems/overlayfs.txt
+
+config OVERLAY_FS_V1
+	bool "Overlayfs filesystem (V1) format support"
+	help
+	  Support the older whiteout format overlayfs filesystems via
+	  the overlay module.  This is needed to support legacy kernels
+	  built using the original overlayfs patch set.
--- zfcpdump-kernel-4.4.orig/fs/overlayfs/copy_up.c
+++ zfcpdump-kernel-4.4/fs/overlayfs/copy_up.c
@@ -22,9 +22,9 @@
 
 int ovl_copy_xattr(struct dentry *old, struct dentry *new)
 {
-	ssize_t list_size, size;
-	char *buf, *name, *value;
-	int error;
+	ssize_t list_size, size, value_size = 0;
+	char *buf, *name, *value = NULL;
+	int uninitialized_var(error);
 
 	if (!old->d_inode->i_op->getxattr ||
 	    !new->d_inode->i_op->getxattr)
@@ -41,29 +41,42 @@ int ovl_copy_xattr(struct dentry *old, s
 	if (!buf)
 		return -ENOMEM;
 
-	error = -ENOMEM;
-	value = kmalloc(XATTR_SIZE_MAX, GFP_KERNEL);
-	if (!value)
-		goto out;
-
 	list_size = vfs_listxattr(old, buf, list_size);
 	if (list_size <= 0) {
 		error = list_size;
-		goto out_free_value;
+		goto out;
 	}
 
 	for (name = buf; name < (buf + list_size); name += strlen(name) + 1) {
-		size = vfs_getxattr(old, name, value, XATTR_SIZE_MAX);
-		if (size <= 0) {
+		if (ovl_is_private_xattr(name))
+			continue;
+retry:
+		size = vfs_getxattr(old, name, value, value_size);
+		if (size == -ERANGE)
+			size = vfs_getxattr(old, name, NULL, 0);
+
+		if (size < 0) {
 			error = size;
-			goto out_free_value;
+			break;
+		}
+
+		if (size > value_size) {
+			void *new;
+
+			new = krealloc(value, size, GFP_KERNEL);
+			if (!new) {
+				error = -ENOMEM;
+				break;
+			}
+			value = new;
+			value_size = size;
+			goto retry;
 		}
+
 		error = vfs_setxattr(new, name, value, size, 0);
 		if (error)
-			goto out_free_value;
+			break;
 	}
-
-out_free_value:
 	kfree(value);
 out:
 	kfree(buf);
@@ -172,10 +185,19 @@ int ovl_set_attr(struct dentry *upperden
 {
 	int err = 0;
 
+	/*
+	 * For the most part we want to set the mode bits before setting
+	 * the user, otherwise the current context might lack permission
+	 * for setting the mode. However for sxid/sticky bits we want
+	 * the operation to fail if the current user isn't privileged
+	 * towards the resulting inode. So we first set the mode but
+	 * exclude the sxid/sticky bits, then set the user, then set the
+	 * mode again if any of the sxid/sticky bits are set.
+	 */
 	if (!S_ISLNK(stat->mode)) {
 		struct iattr attr = {
 			.ia_valid = ATTR_MODE,
-			.ia_mode = stat->mode,
+			.ia_mode = stat->mode & ~(S_ISUID|S_ISGID|S_ISVTX),
 		};
 		err = notify_change(upperdentry, &attr, NULL);
 	}
@@ -187,6 +209,14 @@ int ovl_set_attr(struct dentry *upperden
 		};
 		err = notify_change(upperdentry, &attr, NULL);
 	}
+	if (!err && !S_ISLNK(stat->mode) &&
+	    (stat->mode & (S_ISUID|S_ISGID|S_ISVTX))) {
+		struct iattr attr = {
+			.ia_valid = ATTR_MODE,
+			.ia_mode = stat->mode,
+		};
+		err = notify_change(upperdentry, &attr, NULL);
+	}
 	if (!err)
 		ovl_set_timestamps(upperdentry, stat);
 
@@ -298,9 +328,17 @@ int ovl_copy_up_one(struct dentry *paren
 	if (WARN_ON(!workdir))
 		return -EROFS;
 
+	err = ovl_dentry_root_may(dentry, lowerpath, MAY_READ);
+	if (err)
+		return err;
+
 	ovl_path_upper(parent, &parentpath);
 	upperdir = parentpath.dentry;
 
+	err = ovl_dentry_root_may(dentry, &parentpath, MAY_WRITE);
+	if (err)
+		return err;
+
 	err = vfs_getattr(&parentpath, &pstat);
 	if (err)
 		return err;
@@ -312,26 +350,9 @@ int ovl_copy_up_one(struct dentry *paren
 	}
 
 	err = -ENOMEM;
-	override_cred = prepare_creds();
+	override_cred = ovl_prepare_creds(dentry->d_sb);
 	if (!override_cred)
 		goto out_free_link;
-
-	override_cred->fsuid = stat->uid;
-	override_cred->fsgid = stat->gid;
-	/*
-	 * CAP_SYS_ADMIN for copying up extended attributes
-	 * CAP_DAC_OVERRIDE for create
-	 * CAP_FOWNER for chmod, timestamp update
-	 * CAP_FSETID for chmod
-	 * CAP_CHOWN for chown
-	 * CAP_MKNOD for mknod
-	 */
-	cap_raise(override_cred->cap_effective, CAP_SYS_ADMIN);
-	cap_raise(override_cred->cap_effective, CAP_DAC_OVERRIDE);
-	cap_raise(override_cred->cap_effective, CAP_FOWNER);
-	cap_raise(override_cred->cap_effective, CAP_FSETID);
-	cap_raise(override_cred->cap_effective, CAP_CHOWN);
-	cap_raise(override_cred->cap_effective, CAP_MKNOD);
 	old_cred = override_creds(override_cred);
 
 	err = -EIO;
--- zfcpdump-kernel-4.4.orig/fs/overlayfs/dir.c
+++ zfcpdump-kernel-4.4/fs/overlayfs/dir.c
@@ -12,6 +12,7 @@
 #include <linux/xattr.h>
 #include <linux/security.h>
 #include <linux/cred.h>
+#include <linux/sched.h>
 #include "overlayfs.h"
 
 void ovl_cleanup(struct inode *wdir, struct dentry *wdentry)
@@ -48,6 +49,34 @@ struct dentry *ovl_lookup_temp(struct de
 	return temp;
 }
 
+#ifdef CONFIG_OVERLAY_FS_V1
+static const char *ovl_whiteout_symlink = "(overlay-whiteout)";
+int ovl_do_whiteout_v1(struct inode *workdir,
+			      struct dentry *dentry)
+{
+	int err;
+
+	err = vfs_symlink(workdir, dentry, ovl_whiteout_symlink);
+	if (err)
+		return err;
+
+	err = ovl_do_setxattr(dentry, ovl_whiteout_xattr, "y", 1, 0);
+	if (err)
+		vfs_unlink(workdir, dentry, NULL);
+
+	if (err) {
+		/*
+		 * There's no way to recover from failure to whiteout.
+		 * What should we do?  Log a big fat error and... ?
+		 */
+		pr_err("overlayfs: ERROR - failed to whiteout '%s'\n",
+		       dentry->d_name.name);
+	}
+
+	return err;
+}
+#endif
+
 /* caller holds i_mutex on workdir */
 static struct dentry *ovl_whiteout(struct dentry *workdir,
 				   struct dentry *dentry)
@@ -60,7 +89,7 @@ static struct dentry *ovl_whiteout(struc
 	if (IS_ERR(whiteout))
 		return whiteout;
 
-	err = ovl_do_whiteout(wdir, whiteout);
+	err = ovl_do_whiteout(wdir, whiteout, dentry);
 	if (err) {
 		dput(whiteout);
 		whiteout = ERR_PTR(err);
@@ -321,6 +350,11 @@ static int ovl_create_over_whiteout(stru
 	struct inode *wdir = workdir->d_inode;
 	struct dentry *upperdir = ovl_dentry_upper(dentry->d_parent);
 	struct inode *udir = upperdir->d_inode;
+	struct iattr attr = {
+		.ia_valid = ATTR_UID | ATTR_GID,
+		.ia_uid = stat->uid,
+		.ia_gid = stat->gid,
+	};
 	struct dentry *upper;
 	struct dentry *newdentry;
 	int err;
@@ -346,6 +380,11 @@ static int ovl_create_over_whiteout(stru
 	err = ovl_create_real(wdir, newdentry, stat, link, hardlink, true);
 	if (err)
 		goto out_dput2;
+	mutex_lock(&newdentry->d_inode->i_mutex);
+	err = notify_change(newdentry, &attr, NULL);
+	mutex_unlock(&newdentry->d_inode->i_mutex);
+	if (err)
+		goto out_cleanup;
 
 	if (S_ISDIR(stat->mode)) {
 		err = ovl_set_opaque(newdentry);
@@ -390,6 +429,8 @@ static int ovl_create_or_link(struct den
 	struct kstat stat = {
 		.mode = mode,
 		.rdev = rdev,
+		.uid  = current->cred->fsuid,
+		.gid  = current->cred->fsgid,
 	};
 
 	err = -ENOMEM;
@@ -408,18 +449,9 @@ static int ovl_create_or_link(struct den
 		struct cred *override_cred;
 
 		err = -ENOMEM;
-		override_cred = prepare_creds();
+		override_cred = ovl_prepare_creds(dentry->d_sb);
 		if (!override_cred)
 			goto out_iput;
-
-		/*
-		 * CAP_SYS_ADMIN for setting opaque xattr
-		 * CAP_DAC_OVERRIDE for create in workdir, rename
-		 * CAP_FOWNER for removing whiteout from sticky dir
-		 */
-		cap_raise(override_cred->cap_effective, CAP_SYS_ADMIN);
-		cap_raise(override_cred->cap_effective, CAP_DAC_OVERRIDE);
-		cap_raise(override_cred->cap_effective, CAP_FOWNER);
 		old_cred = override_creds(override_cred);
 
 		err = ovl_create_over_whiteout(dentry, inode, &stat, link,
@@ -511,6 +543,7 @@ static int ovl_remove_and_whiteout(struc
 	struct dentry *upper;
 	struct dentry *opaquedir = NULL;
 	int err;
+	int flags = 0;
 
 	if (WARN_ON(!workdir))
 		return -EROFS;
@@ -540,46 +573,39 @@ static int ovl_remove_and_whiteout(struc
 	if (err)
 		goto out_dput;
 
-	whiteout = ovl_whiteout(workdir, dentry);
-	err = PTR_ERR(whiteout);
-	if (IS_ERR(whiteout))
+	upper = lookup_one_len(dentry->d_name.name, upperdir,
+			       dentry->d_name.len);
+	err = PTR_ERR(upper);
+	if (IS_ERR(upper))
 		goto out_unlock;
 
-	upper = ovl_dentry_upper(dentry);
-	if (!upper) {
-		upper = lookup_one_len(dentry->d_name.name, upperdir,
-				       dentry->d_name.len);
-		err = PTR_ERR(upper);
-		if (IS_ERR(upper))
-			goto kill_whiteout;
-
-		err = ovl_do_rename(wdir, whiteout, udir, upper, 0);
-		dput(upper);
-		if (err)
-			goto kill_whiteout;
-	} else {
-		int flags = 0;
+	err = -ESTALE;
+	if ((opaquedir && upper != opaquedir) ||
+	    (!opaquedir && ovl_dentry_upper(dentry) &&
+	     upper != ovl_dentry_upper(dentry))) {
+		goto out_dput_upper;
+	}
 
-		if (opaquedir)
-			upper = opaquedir;
-		err = -ESTALE;
-		if (upper->d_parent != upperdir)
-			goto kill_whiteout;
+	whiteout = ovl_whiteout(workdir, dentry);
+	err = PTR_ERR(whiteout);
+	if (IS_ERR(whiteout))
+		goto out_dput_upper;
 
-		if (is_dir)
-			flags |= RENAME_EXCHANGE;
+	if (d_is_dir(upper))
+		flags = RENAME_EXCHANGE;
 
-		err = ovl_do_rename(wdir, whiteout, udir, upper, flags);
-		if (err)
-			goto kill_whiteout;
+	err = ovl_do_rename(wdir, whiteout, udir, upper, flags);
+	if (err)
+		goto kill_whiteout;
+	if (flags)
+		ovl_cleanup(wdir, upper);
 
-		if (is_dir)
-			ovl_cleanup(wdir, upper);
-	}
 	ovl_dentry_version_inc(dentry->d_parent);
 out_d_drop:
 	d_drop(dentry);
 	dput(whiteout);
+out_dput_upper:
+	dput(upper);
 out_unlock:
 	unlock_rename(workdir, upperdir);
 out_dput:
@@ -596,21 +622,25 @@ static int ovl_remove_upper(struct dentr
 {
 	struct dentry *upperdir = ovl_dentry_upper(dentry->d_parent);
 	struct inode *dir = upperdir->d_inode;
-	struct dentry *upper = ovl_dentry_upper(dentry);
+	struct dentry *upper;
 	int err;
 
 	mutex_lock_nested(&dir->i_mutex, I_MUTEX_PARENT);
+	upper = lookup_one_len(dentry->d_name.name, upperdir,
+			       dentry->d_name.len);
+	err = PTR_ERR(upper);
+	if (IS_ERR(upper))
+		goto out_unlock;
+
 	err = -ESTALE;
-	if (upper->d_parent == upperdir) {
-		/* Don't let d_delete() think it can reset d_inode */
-		dget(upper);
+	if (upper == ovl_dentry_upper(dentry)) {
 		if (is_dir)
 			err = vfs_rmdir(dir, upper);
 		else
 			err = vfs_unlink(dir, upper, NULL);
-		dput(upper);
 		ovl_dentry_version_inc(dentry->d_parent);
 	}
+	dput(upper);
 
 	/*
 	 * Keeping this dentry hashed would mean having to release
@@ -618,7 +648,9 @@ static int ovl_remove_upper(struct dentr
 	 * sole user of this dentry.  Too tricky...  Just unhash for
 	 * now.
 	 */
-	d_drop(dentry);
+	if (!err)
+		d_drop(dentry);
+out_unlock:
 	mutex_unlock(&dir->i_mutex);
 
 	return err;
@@ -660,22 +692,9 @@ static int ovl_do_remove(struct dentry *
 		struct cred *override_cred;
 
 		err = -ENOMEM;
-		override_cred = prepare_creds();
+		override_cred = ovl_prepare_creds(dentry->d_sb);
 		if (!override_cred)
 			goto out_drop_write;
-
-		/*
-		 * CAP_SYS_ADMIN for setting xattr on whiteout, opaque dir
-		 * CAP_DAC_OVERRIDE for create in workdir, rename
-		 * CAP_FOWNER for removing whiteout from sticky dir
-		 * CAP_FSETID for chmod of opaque dir
-		 * CAP_CHOWN for chown of opaque dir
-		 */
-		cap_raise(override_cred->cap_effective, CAP_SYS_ADMIN);
-		cap_raise(override_cred->cap_effective, CAP_DAC_OVERRIDE);
-		cap_raise(override_cred->cap_effective, CAP_FOWNER);
-		cap_raise(override_cred->cap_effective, CAP_FSETID);
-		cap_raise(override_cred->cap_effective, CAP_CHOWN);
 		old_cred = override_creds(override_cred);
 
 		err = ovl_remove_and_whiteout(dentry, is_dir);
@@ -699,6 +718,51 @@ static int ovl_rmdir(struct inode *dir,
 	return ovl_do_remove(dentry, true);
 }
 
+/*
+ * ovl_downgrade_whiteout -- build a symlink whiteout and install it
+ * over the existing chardev whiteout.
+ */
+static void ovl_downgrade_whiteout(struct dentry *old_upperdir,
+				   struct dentry *old)
+{
+	struct dentry *workdir = ovl_workdir(old);
+	struct dentry *legacy_whiteout = NULL;
+	struct dentry *whtdentry;
+	int err;
+
+	err = ovl_lock_rename_workdir(workdir, old_upperdir);
+	if (err)
+		goto out;
+
+	whtdentry = lookup_one_len(old->d_name.name, old_upperdir,
+				   old->d_name.len);
+	if (IS_ERR(whtdentry)) {
+		err = PTR_ERR(whtdentry);
+		goto out_unlock_workdir;
+	}
+
+	legacy_whiteout = ovl_whiteout(workdir, old);
+	if (IS_ERR(legacy_whiteout)) {
+		err = PTR_ERR(legacy_whiteout);
+		goto out_dput;
+	}
+
+	err = ovl_do_rename(workdir->d_inode, legacy_whiteout,
+			    old_upperdir->d_inode, whtdentry, 0);
+	if (err)
+		ovl_cleanup(workdir->d_inode, legacy_whiteout);
+
+out_dput:
+	dput(whtdentry);
+	dput(legacy_whiteout);
+out_unlock_workdir:
+	unlock_rename(workdir, old_upperdir);
+out:
+	if (err)
+		pr_err("overlayfs: dowgrade of '%pd2' whiteout failed (%i)\n",
+		       old, err);
+}
+
 static int ovl_rename2(struct inode *olddir, struct dentry *old,
 		       struct inode *newdir, struct dentry *new,
 		       unsigned int flags)
@@ -791,22 +855,9 @@ static int ovl_rename2(struct inode *old
 
 	if (old_opaque || new_opaque) {
 		err = -ENOMEM;
-		override_cred = prepare_creds();
+		override_cred = ovl_prepare_creds(old->d_sb);
 		if (!override_cred)
 			goto out_drop_write;
-
-		/*
-		 * CAP_SYS_ADMIN for setting xattr on whiteout, opaque dir
-		 * CAP_DAC_OVERRIDE for create in workdir
-		 * CAP_FOWNER for removing whiteout from sticky dir
-		 * CAP_FSETID for chmod of opaque dir
-		 * CAP_CHOWN for chown of opaque dir
-		 */
-		cap_raise(override_cred->cap_effective, CAP_SYS_ADMIN);
-		cap_raise(override_cred->cap_effective, CAP_DAC_OVERRIDE);
-		cap_raise(override_cred->cap_effective, CAP_FOWNER);
-		cap_raise(override_cred->cap_effective, CAP_FSETID);
-		cap_raise(override_cred->cap_effective, CAP_CHOWN);
 		old_cred = override_creds(override_cred);
 	}
 
@@ -839,29 +890,39 @@ static int ovl_rename2(struct inode *old
 
 	trap = lock_rename(new_upperdir, old_upperdir);
 
-	olddentry = ovl_dentry_upper(old);
-	newdentry = ovl_dentry_upper(new);
-	if (newdentry) {
+
+	olddentry = lookup_one_len(old->d_name.name, old_upperdir,
+				   old->d_name.len);
+	err = PTR_ERR(olddentry);
+	if (IS_ERR(olddentry))
+		goto out_unlock;
+
+	err = -ESTALE;
+	if (olddentry != ovl_dentry_upper(old))
+		goto out_dput_old;
+
+	newdentry = lookup_one_len(new->d_name.name, new_upperdir,
+				   new->d_name.len);
+	err = PTR_ERR(newdentry);
+	if (IS_ERR(newdentry))
+		goto out_dput_old;
+
+	err = -ESTALE;
+	if (ovl_dentry_upper(new)) {
 		if (opaquedir) {
-			newdentry = opaquedir;
-			opaquedir = NULL;
+			if (newdentry != opaquedir)
+				goto out_dput;
 		} else {
-			dget(newdentry);
+			if (newdentry != ovl_dentry_upper(new))
+				goto out_dput;
 		}
 	} else {
 		new_create = true;
-		newdentry = lookup_one_len(new->d_name.name, new_upperdir,
-					   new->d_name.len);
-		err = PTR_ERR(newdentry);
-		if (IS_ERR(newdentry))
-			goto out_unlock;
+		if (!d_is_negative(newdentry) &&
+		    (!new_opaque || !ovl_is_whiteout(newdentry,ovl_config_legacy(new))))
+			goto out_dput;
 	}
 
-	err = -ESTALE;
-	if (olddentry->d_parent != old_upperdir)
-		goto out_dput;
-	if (newdentry->d_parent != new_upperdir)
-		goto out_dput;
 	if (olddentry == trap)
 		goto out_dput;
 	if (newdentry == trap)
@@ -903,6 +964,13 @@ static int ovl_rename2(struct inode *old
 	if (!overwrite && new_is_dir && !old_opaque && new_opaque)
 		ovl_remove_opaque(newdentry);
 
+	/*
+	 * Old dentry now lives in different location. Dentries in
+	 * lowerstack are stale. We cannot drop them here because
+	 * access to them is lockless. This could be only pure upper
+	 * or opaque directory - numlower is zero. Or upper non-dir
+	 * entry - its pureness is tracked by flag opaque.
+	 */
 	if (old_opaque != new_opaque) {
 		ovl_dentry_set_opaque(old, new_opaque);
 		if (!overwrite)
@@ -917,8 +985,13 @@ static int ovl_rename2(struct inode *old
 
 out_dput:
 	dput(newdentry);
+out_dput_old:
+	dput(olddentry);
 out_unlock:
 	unlock_rename(new_upperdir, old_upperdir);
+
+	if (!err && ovl_config_legacy(old) && flags & RENAME_WHITEOUT)
+		ovl_downgrade_whiteout(old_upperdir, old);
 out_revert_creds:
 	if (old_opaque || new_opaque) {
 		revert_creds(old_cred);
--- zfcpdump-kernel-4.4.orig/fs/overlayfs/inode.c
+++ zfcpdump-kernel-4.4/fs/overlayfs/inode.c
@@ -42,6 +42,19 @@ int ovl_setattr(struct dentry *dentry, s
 	int err;
 	struct dentry *upperdentry;
 
+	/*
+	 * Check for permissions before trying to copy-up.  This is redundant
+	 * since it will be rechecked later by ->setattr() on upper dentry.  But
+	 * without this, copy-up can be triggered by just about anybody.
+	 *
+	 * We don't initialize inode->size, which just means that
+	 * inode_newsize_ok() will always check against MAX_LFS_FILESIZE and not
+	 * check for a swapfile (which this won't be anyway).
+	 */
+	err = inode_change_ok(dentry->d_inode, attr);
+	if (err)
+		return err;
+
 	err = ovl_want_write(dentry);
 	if (err)
 		goto out;
@@ -50,8 +63,13 @@ int ovl_setattr(struct dentry *dentry, s
 	if (!err) {
 		upperdentry = ovl_dentry_upper(dentry);
 
+		if (attr->ia_valid & (ATTR_KILL_SUID|ATTR_KILL_SGID))
+			attr->ia_valid &= ~ATTR_MODE;
+
 		mutex_lock(&upperdentry->d_inode->i_mutex);
 		err = notify_change(upperdentry, attr, NULL);
+		if (!err)
+			ovl_copyattr(upperdentry->d_inode, dentry->d_inode);
 		mutex_unlock(&upperdentry->d_inode->i_mutex);
 	}
 	ovl_drop_write(dentry);
@@ -201,7 +219,7 @@ static int ovl_readlink(struct dentry *d
 }
 
 
-static bool ovl_is_private_xattr(const char *name)
+bool ovl_is_private_xattr(const char *name)
 {
 	return strncmp(name, OVL_XATTR_PRE_NAME, OVL_XATTR_PRE_LEN) == 0;
 }
@@ -259,7 +277,8 @@ ssize_t ovl_listxattr(struct dentry *den
 	struct path realpath;
 	enum ovl_path_type type = ovl_path_real(dentry, &realpath);
 	ssize_t res;
-	int off;
+	size_t len;
+	char *s;
 
 	res = vfs_listxattr(realpath.dentry, list, size);
 	if (res <= 0 || size == 0)
@@ -269,17 +288,19 @@ ssize_t ovl_listxattr(struct dentry *den
 		return res;
 
 	/* filter out private xattrs */
-	for (off = 0; off < res;) {
-		char *s = list + off;
-		size_t slen = strlen(s) + 1;
+	for (s = list, len = res; len;) {
+		size_t slen = strnlen(s, len) + 1;
 
-		BUG_ON(off + slen > res);
+		/* underlying fs providing us with an broken xattr list? */
+		if (WARN_ON(slen > len))
+			return -EIO;
 
+		len -= slen;
 		if (ovl_is_private_xattr(s)) {
 			res -= slen;
-			memmove(s, s + slen, res - off);
+			memmove(s, s + slen, len);
 		} else {
-			off += slen;
+			s += slen;
 		}
 	}
 
@@ -397,12 +418,11 @@ struct inode *ovl_new_inode(struct super
 	if (!inode)
 		return NULL;
 
-	mode &= S_IFMT;
-
 	inode->i_ino = get_next_ino();
 	inode->i_mode = mode;
 	inode->i_flags |= S_NOATIME | S_NOCMTIME;
 
+	mode &= S_IFMT;
 	switch (mode) {
 	case S_IFDIR:
 		inode->i_private = oe;
--- zfcpdump-kernel-4.4.orig/fs/overlayfs/overlayfs.h
+++ zfcpdump-kernel-4.4/fs/overlayfs/overlayfs.h
@@ -27,6 +27,8 @@ enum ovl_path_type {
 #define OVL_XATTR_PRE_LEN  16
 #define OVL_XATTR_OPAQUE   OVL_XATTR_PRE_NAME"opaque"
 
+extern const char *ovl_whiteout_xattr; /* XXX: should be ^^ */
+
 static inline int ovl_do_rmdir(struct inode *dir, struct dentry *dentry)
 {
 	int err = vfs_rmdir(dir, dentry);
@@ -93,7 +95,14 @@ static inline int ovl_do_symlink(struct
 static inline int ovl_do_setxattr(struct dentry *dentry, const char *name,
 				  const void *value, size_t size, int flags)
 {
-	int err = vfs_setxattr(dentry, name, value, size, flags);
+	struct inode *inode = dentry->d_inode;
+	int err = -EOPNOTSUPP;
+
+	mutex_lock(&inode->i_mutex);
+	if (inode->i_op->setxattr)
+		err = inode->i_op->setxattr(dentry, name, value, size, flags);
+	mutex_unlock(&inode->i_mutex);
+
 	pr_debug("setxattr(%pd2, \"%s\", \"%*s\", 0x%x) = %i\n",
 		 dentry, name, (int) size, (char *) value, flags, err);
 	return err;
@@ -101,7 +110,14 @@ static inline int ovl_do_setxattr(struct
 
 static inline int ovl_do_removexattr(struct dentry *dentry, const char *name)
 {
-	int err = vfs_removexattr(dentry, name);
+	struct inode *inode = dentry->d_inode;
+	int err = -EOPNOTSUPP;
+
+	mutex_lock(&inode->i_mutex);
+	if (inode->i_op->removexattr)
+		err = inode->i_op->removexattr(dentry, name);
+	mutex_unlock(&inode->i_mutex);
+
 	pr_debug("removexattr(%pd2, \"%s\") = %i\n", dentry, name, err);
 	return err;
 }
@@ -124,13 +140,30 @@ static inline int ovl_do_rename(struct i
 	return err;
 }
 
-static inline int ovl_do_whiteout(struct inode *dir, struct dentry *dentry)
+#ifdef CONFIG_OVERLAY_FS_V1
+extern int ovl_config_legacy(struct dentry *dentry);
+#else
+#define ovl_config_legacy(x) (0)
+#endif
+
+int ovl_do_whiteout_v1(struct inode *dir, struct dentry *dentry);
+
+static inline int ovl_do_whiteout_v2(struct inode *dir, struct dentry *dentry)
 {
 	int err = vfs_whiteout(dir, dentry);
 	pr_debug("whiteout(%pd2) = %i\n", dentry, err);
 	return err;
 }
+static inline int ovl_do_whiteout(struct inode *dir, struct dentry *dentry,
+				  struct dentry *ovlentry)
+{
+	if (ovl_config_legacy(ovlentry))
+		return ovl_do_whiteout_v1(dir, dentry);
+
+	return ovl_do_whiteout_v2(dir, dentry);
+}
 
+struct cred *ovl_prepare_creds(struct super_block *sb);
 enum ovl_path_type ovl_path_type(struct dentry *dentry);
 u64 ovl_dentry_version_get(struct dentry *dentry);
 void ovl_dentry_version_inc(struct dentry *dentry);
@@ -149,7 +182,7 @@ int ovl_want_write(struct dentry *dentry
 void ovl_drop_write(struct dentry *dentry);
 bool ovl_dentry_is_opaque(struct dentry *dentry);
 void ovl_dentry_set_opaque(struct dentry *dentry, bool opaque);
-bool ovl_is_whiteout(struct dentry *dentry);
+bool ovl_is_whiteout(struct dentry *dentry, int is_legacy);
 void ovl_dentry_update(struct dentry *dentry, struct dentry *upperdentry);
 struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry,
 			  unsigned int flags);
@@ -157,6 +190,7 @@ struct file *ovl_path_open(struct path *
 
 struct dentry *ovl_upper_create(struct dentry *upperdir, struct dentry *dentry,
 				struct kstat *stat, const char *link);
+int ovl_dentry_root_may(struct dentry *dentry, struct path *realpath, int mode);
 
 /* readdir.c */
 extern const struct file_operations ovl_dir_operations;
@@ -174,6 +208,7 @@ ssize_t ovl_getxattr(struct dentry *dent
 ssize_t ovl_listxattr(struct dentry *dentry, char *list, size_t size);
 int ovl_removexattr(struct dentry *dentry, const char *name);
 struct inode *ovl_d_select_inode(struct dentry *dentry, unsigned file_flags);
+bool ovl_is_private_xattr(const char *name);
 
 struct inode *ovl_new_inode(struct super_block *sb, umode_t mode,
 			    struct ovl_entry *oe);
@@ -181,6 +216,7 @@ static inline void ovl_copyattr(struct i
 {
 	to->i_uid = from->i_uid;
 	to->i_gid = from->i_gid;
+	to->i_mode = from->i_mode;
 }
 
 /* dir.c */
--- zfcpdump-kernel-4.4.orig/fs/overlayfs/readdir.c
+++ zfcpdump-kernel-4.4/fs/overlayfs/readdir.c
@@ -14,6 +14,7 @@
 #include <linux/xattr.h>
 #include <linux/rbtree.h>
 #include <linux/security.h>
+#include <linux/sched.h>
 #include <linux/cred.h>
 #include "overlayfs.h"
 
@@ -36,6 +37,7 @@ struct ovl_dir_cache {
 
 struct ovl_readdir_data {
 	struct dir_context ctx;
+	struct dentry *dentry;
 	bool is_merge;
 	struct rb_root root;
 	struct list_head *list;
@@ -43,6 +45,7 @@ struct ovl_readdir_data {
 	struct ovl_cache_entry *first_maybe_whiteout;
 	int count;
 	int err;
+	int is_legacy;
 };
 
 struct ovl_dir_file {
@@ -98,7 +101,7 @@ static struct ovl_cache_entry *ovl_cache
 	p->ino = ino;
 	p->is_whiteout = false;
 
-	if (d_type == DT_CHR) {
+	if ((d_type == DT_CHR && !rdd->is_legacy) || (d_type == DT_LNK && rdd->is_legacy)) {
 		p->next_maybe_whiteout = rdd->first_maybe_whiteout;
 		rdd->first_maybe_whiteout = p;
 	}
@@ -207,14 +210,9 @@ static int ovl_check_whiteouts(struct de
 	const struct cred *old_cred;
 	struct cred *override_cred;
 
-	override_cred = prepare_creds();
+	override_cred = ovl_prepare_creds(rdd->dentry->d_sb);
 	if (!override_cred)
 		return -ENOMEM;
-
-	/*
-	 * CAP_DAC_OVERRIDE for lookup
-	 */
-	cap_raise(override_cred->cap_effective, CAP_DAC_OVERRIDE);
 	old_cred = override_creds(override_cred);
 
 	err = mutex_lock_killable(&dir->d_inode->i_mutex);
@@ -224,7 +222,7 @@ static int ovl_check_whiteouts(struct de
 			rdd->first_maybe_whiteout = p->next_maybe_whiteout;
 			dentry = lookup_one_len(p->name, dir, p->len);
 			if (!IS_ERR(dentry)) {
-				p->is_whiteout = ovl_is_whiteout(dentry);
+				p->is_whiteout = ovl_is_whiteout(dentry, rdd->is_legacy);
 				dput(dentry);
 			}
 		}
@@ -287,15 +285,21 @@ static int ovl_dir_read_merged(struct de
 	struct path realpath;
 	struct ovl_readdir_data rdd = {
 		.ctx.actor = ovl_fill_merge,
+		.dentry = dentry,
 		.list = list,
 		.root = RB_ROOT,
 		.is_merge = false,
+		.is_legacy = ovl_config_legacy(dentry),
 	};
 	int idx, next;
 
 	for (idx = 0; idx != -1; idx = next) {
 		next = ovl_path_next(idx, dentry, &realpath);
 
+		err = ovl_dentry_root_may(dentry, &realpath, MAY_READ);
+		if (err)
+			break;
+
 		if (next != -1) {
 			err = ovl_dir_read(&realpath, &rdd);
 			if (err)
@@ -369,8 +373,13 @@ static int ovl_iterate(struct file *file
 	if (!ctx->pos)
 		ovl_dir_reset(file);
 
-	if (od->is_real)
+	if (od->is_real) {
+		int res = ovl_dentry_root_may(dentry, &(od->realfile->f_path), MAY_READ);
+		if (res)
+			return res;
+
 		return iterate_dir(od->realfile, ctx);
+	}
 
 	if (!od->cache) {
 		struct ovl_dir_cache *cache;
@@ -571,7 +580,8 @@ void ovl_cleanup_whiteouts(struct dentry
 			       (int) PTR_ERR(dentry));
 			continue;
 		}
-		ovl_cleanup(upper->d_inode, dentry);
+		if (dentry->d_inode)
+			ovl_cleanup(upper->d_inode, dentry);
 		dput(dentry);
 	}
 	mutex_unlock(&upper->d_inode->i_mutex);
--- zfcpdump-kernel-4.4.orig/fs/overlayfs/super.c
+++ zfcpdump-kernel-4.4/fs/overlayfs/super.c
@@ -9,6 +9,7 @@
 
 #include <linux/fs.h>
 #include <linux/namei.h>
+#include <linux/pagemap.h>
 #include <linux/xattr.h>
 #include <linux/security.h>
 #include <linux/mount.h>
@@ -39,8 +40,10 @@ struct ovl_fs {
 	struct vfsmount **lower_mnt;
 	struct dentry *workdir;
 	long lower_namelen;
+	int legacy;
 	/* pathnames of lower and upper dirs, for show_options */
 	struct ovl_config config;
+	struct cred *mounter_creds;
 };
 
 struct ovl_dir_cache;
@@ -62,6 +65,27 @@ struct ovl_entry {
 
 #define OVL_MAX_STACK 500
 
+/*
+ * Returns a set of credentials suitable for overlayfs internal
+ * operations which require elevated capabilities, equivalent to those
+ * of the user which mounted the superblock. Caller must put the
+ * returned credentials.
+ */
+struct cred *ovl_prepare_creds(struct super_block *sb)
+{
+	struct ovl_fs *ofs = sb->s_fs_info;
+	struct cred *new_cred;
+
+	if (sb->s_magic != OVERLAYFS_SUPER_MAGIC)
+		return NULL;
+
+	new_cred = clone_cred(ofs->mounter_creds);
+	if (!new_cred)
+		return NULL;
+
+	return new_cred;
+}
+
 static struct dentry *__ovl_dentry_lower(struct ovl_entry *oe)
 {
 	return oe->numlower ? oe->lowerstack[0].dentry : NULL;
@@ -75,12 +99,14 @@ enum ovl_path_type ovl_path_type(struct
 	if (oe->__upperdentry) {
 		type = __OVL_PATH_UPPER;
 
-		if (oe->numlower) {
-			if (S_ISDIR(dentry->d_inode->i_mode))
-				type |= __OVL_PATH_MERGE;
-		} else if (!oe->opaque) {
+		/*
+		 * Non-dir dentry can hold lower dentry from previous
+		 * location. Its purity depends only on opaque flag.
+		 */
+		if (oe->numlower && S_ISDIR(dentry->d_inode->i_mode))
+			type |= __OVL_PATH_MERGE;
+		else if (!oe->opaque)
 			type |= __OVL_PATH_PURE;
-		}
 	} else {
 		if (oe->numlower > 1)
 			type |= __OVL_PATH_MERGE;
@@ -236,13 +262,72 @@ u64 ovl_dentry_version_get(struct dentry
 	return oe->version;
 }
 
-bool ovl_is_whiteout(struct dentry *dentry)
+int ovl_dentry_root_may(struct dentry *dentry, struct path *realpath, int mode)
+{
+	const struct cred *old_cred;
+	int err = 0;
+        struct ovl_fs *ofs = dentry->d_sb->s_fs_info;
+
+	old_cred = override_creds(ofs->mounter_creds);
+
+	if (inode_permission(realpath->dentry->d_inode, mode))
+		err = -EACCES;
+
+	revert_creds(old_cred);
+
+	return err;
+}
+
+#ifdef CONFIG_OVERLAY_FS_V1
+int ovl_config_legacy(struct dentry *dentry)
+{
+	struct super_block *sb = dentry->d_sb;
+	struct ovl_fs *ufs = sb->s_fs_info;
+
+	return ufs->legacy;
+}
+
+const char *ovl_whiteout_xattr = "trusted.overlay.whiteout";
+
+bool ovl_is_whiteout_v1(struct dentry *dentry)
+{
+	int res;
+	char val;
+
+	if (!dentry)
+		return false;
+	if (!dentry->d_inode)
+		return false;
+	if (!S_ISLNK(dentry->d_inode->i_mode))
+		return false;
+	if (!dentry->d_inode->i_op->getxattr)
+		return false;
+
+	res = dentry->d_inode->i_op->getxattr(dentry, ovl_whiteout_xattr, &val, 1);
+	if (res == 1 && val == 'y')
+		return true;
+
+	return false;
+}
+#else
+#define ovl_is_whiteout_v1(x) (0)
+#endif
+
+bool ovl_is_whiteout_v2(struct dentry *dentry)
 {
 	struct inode *inode = dentry->d_inode;
 
 	return inode && IS_WHITEOUT(inode);
 }
 
+bool ovl_is_whiteout(struct dentry *dentry, int is_legacy)
+{
+	if (is_legacy)
+		return ovl_is_whiteout_v2(dentry) || ovl_is_whiteout_v1(dentry);
+
+	return ovl_is_whiteout_v2(dentry);
+}
+
 static bool ovl_is_opaquedir(struct dentry *dentry)
 {
 	int res;
@@ -273,6 +358,37 @@ static void ovl_dentry_release(struct de
 	}
 }
 
+static struct dentry *ovl_d_real(struct dentry *dentry, struct inode *inode)
+{
+	struct dentry *real;
+
+	if (d_is_dir(dentry)) {
+		if (!inode || inode == d_inode(dentry))
+			return dentry;
+		goto bug;
+	}
+
+	real = ovl_dentry_upper(dentry);
+	if (real && (!inode || inode == d_inode(real)))
+		return real;
+
+	real = ovl_dentry_lower(dentry);
+	if (!real)
+		goto bug;
+
+	if (!inode || inode == d_inode(real))
+		return real;
+
+	/* Handle recursion */
+	if (real->d_flags & DCACHE_OP_REAL)
+		return real->d_op->d_real(real, inode);
+
+bug:
+	WARN(1, "ovl_d_real(%pd4, %s:%lu\n): real dentry not found\n", dentry,
+	     inode ? inode->i_sb->s_id : "NULL", inode ? inode->i_ino : 0);
+	return dentry;
+}
+
 static int ovl_dentry_revalidate(struct dentry *dentry, unsigned int flags)
 {
 	struct ovl_entry *oe = dentry->d_fsdata;
@@ -317,10 +433,13 @@ static int ovl_dentry_weak_revalidate(st
 static const struct dentry_operations ovl_dentry_operations = {
 	.d_release = ovl_dentry_release,
 	.d_select_inode = ovl_d_select_inode,
+	.d_real = ovl_d_real,
 };
 
 static const struct dentry_operations ovl_reval_dentry_operations = {
 	.d_release = ovl_dentry_release,
+	.d_select_inode = ovl_d_select_inode,
+	.d_real = ovl_d_real,
 	.d_revalidate = ovl_dentry_revalidate,
 	.d_weak_revalidate = ovl_dentry_weak_revalidate,
 };
@@ -339,7 +458,8 @@ static struct ovl_entry *ovl_alloc_entry
 static bool ovl_dentry_remote(struct dentry *dentry)
 {
 	return dentry->d_flags &
-		(DCACHE_OP_REVALIDATE | DCACHE_OP_WEAK_REVALIDATE);
+		(DCACHE_OP_REVALIDATE | DCACHE_OP_WEAK_REVALIDATE |
+		 DCACHE_OP_REAL);
 }
 
 static bool ovl_dentry_weird(struct dentry *dentry)
@@ -407,6 +527,7 @@ struct dentry *ovl_lookup(struct inode *
 	struct dentry *this, *prev = NULL;
 	unsigned int i;
 	int err;
+	int is_legacy = ovl_config_legacy(dentry);
 
 	upperdir = ovl_upperdentry_dereference(poe);
 	if (upperdir) {
@@ -421,7 +542,7 @@ struct dentry *ovl_lookup(struct inode *
 				err = -EREMOTE;
 				goto out;
 			}
-			if (ovl_is_whiteout(this)) {
+			if (ovl_is_whiteout(this, is_legacy)) {
 				dput(this);
 				this = NULL;
 				upperopaque = true;
@@ -455,7 +576,7 @@ struct dentry *ovl_lookup(struct inode *
 		}
 		if (!this)
 			continue;
-		if (ovl_is_whiteout(this)) {
+		if (ovl_is_whiteout(this, is_legacy)) {
 			dput(this);
 			break;
 		}
@@ -540,6 +661,7 @@ static void ovl_put_super(struct super_b
 	struct ovl_fs *ufs = sb->s_fs_info;
 	unsigned i;
 
+	put_cred(ufs->mounter_creds);
 	dput(ufs->workdir);
 	mntput(ufs->upper_mnt);
 	for (i = 0; i < ufs->numlower; i++)
@@ -725,6 +847,10 @@ retry:
 		struct kstat stat = {
 			.mode = S_IFDIR | 0,
 		};
+		struct iattr attr = {
+			.ia_valid = ATTR_MODE,
+			.ia_mode = stat.mode,
+		};
 
 		if (work->d_inode) {
 			err = -EEXIST;
@@ -740,6 +866,21 @@ retry:
 		err = ovl_create_real(dir, work, &stat, NULL, NULL, true);
 		if (err)
 			goto out_dput;
+
+		err = vfs_removexattr(work, XATTR_NAME_POSIX_ACL_DEFAULT);
+		if (err && err != -ENODATA && err != -EOPNOTSUPP)
+			goto out_dput;
+
+		err = vfs_removexattr(work, XATTR_NAME_POSIX_ACL_ACCESS);
+		if (err && err != -ENODATA && err != -EOPNOTSUPP)
+			goto out_dput;
+
+		/* Clear any inherited mode bits */
+		inode_lock(work->d_inode);
+		err = notify_change(work, &attr, NULL);
+		inode_unlock(work->d_inode);
+		if (err)
+			goto out_dput;
 	}
 out_unlock:
 	mutex_unlock(&dir->i_mutex);
@@ -910,6 +1051,7 @@ static int ovl_fill_super(struct super_b
 	}
 
 	sb->s_stack_depth = 0;
+	sb->s_maxbytes = MAX_LFS_FILESIZE;
 	if (ufs->config.upperdir) {
 		if (!ufs->config.workdir) {
 			pr_err("overlayfs: missing 'workdir'\n");
@@ -988,6 +1130,9 @@ static int ovl_fill_super(struct super_b
 			goto out_put_lowerpath;
 		}
 
+		if (ufs->upper_mnt->mnt_flags & MNT_NOSUID)
+			sb->s_iflags |= SB_I_NOSUID;
+
 		ufs->workdir = ovl_workdir_create(ufs->upper_mnt, workpath.dentry);
 		err = PTR_ERR(ufs->workdir);
 		if (IS_ERR(ufs->workdir)) {
@@ -1016,6 +1161,9 @@ static int ovl_fill_super(struct super_b
 		 */
 		mnt->mnt_flags |= MNT_READONLY;
 
+		if (mnt->mnt_flags & MNT_NOSUID)
+			sb->s_iflags |= SB_I_NOSUID;
+
 		ufs->lower_mnt[ufs->numlower] = mnt;
 		ufs->numlower++;
 	}
@@ -1038,6 +1186,11 @@ static int ovl_fill_super(struct super_b
 	if (!root_dentry)
 		goto out_free_oe;
 
+	/* Record the mounter. */
+	ufs->mounter_creds = prepare_creds();
+	if (!ufs->mounter_creds)
+		goto out_put_root;
+
 	mntput(upperpath.mnt);
 	for (i = 0; i < numlower; i++)
 		mntput(stack[i].mnt);
@@ -1053,6 +1206,9 @@ static int ovl_fill_super(struct super_b
 
 	root_dentry->d_fsdata = oe;
 
+	ovl_copyattr(ovl_dentry_real(root_dentry)->d_inode,
+		     root_dentry->d_inode);
+
 	sb->s_magic = OVERLAYFS_SUPER_MAGIC;
 	sb->s_op = &ovl_super_operations;
 	sb->s_root = root_dentry;
@@ -1060,6 +1216,8 @@ static int ovl_fill_super(struct super_b
 
 	return 0;
 
+out_put_root:
+	dput(root_dentry);
 out_free_oe:
 	kfree(oe);
 out_put_lower_mnt:
@@ -1099,17 +1257,63 @@ static struct file_system_type ovl_fs_ty
 	.name		= "overlay",
 	.mount		= ovl_mount,
 	.kill_sb	= kill_anon_super,
+	.fs_flags	= FS_USERNS_MOUNT,
 };
 MODULE_ALIAS_FS("overlay");
 
+#ifdef CONFIG_OVERLAY_FS_V1
+static int ovl_v1_fill_super(struct super_block *sb, void *data, int silent)
+{
+	int ret;
+	struct ovl_fs *ufs;
+
+	ret = ovl_fill_super(sb, data, silent);
+	if (ret)
+		return ret;
+
+	/* Mark this as a overlayfs format. */
+	ufs = sb->s_fs_info;
+	ufs->legacy = 1;
+
+	return ret;
+}
+
+static struct dentry *ovl_mount_v1(struct file_system_type *fs_type, int flags,
+				const char *dev_name, void *raw_data)
+{
+	return mount_nodev(fs_type, flags, raw_data, ovl_v1_fill_super);
+}
+
+static struct file_system_type ovl_v1_fs_type = {
+	.owner		= THIS_MODULE,
+	.name		= "overlayfs",
+	.mount		= ovl_mount_v1,
+	.kill_sb	= kill_anon_super,
+	.fs_flags	= FS_USERNS_MOUNT,  /* XXX */
+};
+MODULE_ALIAS_FS("overlayfs");
+MODULE_ALIAS("overlayfs");
+#endif
+
 static int __init ovl_init(void)
 {
+	int ret;
+
+	if (IS_ENABLED(CONFIG_OVERLAY_FS_V1)) {
+		ret = register_filesystem(&ovl_v1_fs_type);
+		if (ret)
+			return ret;
+	}
+
 	return register_filesystem(&ovl_fs_type);
 }
 
 static void __exit ovl_exit(void)
 {
 	unregister_filesystem(&ovl_fs_type);
+
+	if (IS_ENABLED(CONFIG_OVERLAY_FS_V1))
+		unregister_filesystem(&ovl_v1_fs_type);
 }
 
 module_init(ovl_init);
--- zfcpdump-kernel-4.4.orig/fs/pipe.c
+++ zfcpdump-kernel-4.4/fs/pipe.c
@@ -38,6 +38,12 @@ unsigned int pipe_max_size = 1048576;
  */
 unsigned int pipe_min_size = PAGE_SIZE;
 
+/* Maximum allocatable pages per user. Hard limit is unset by default, soft
+ * matches default values.
+ */
+unsigned long pipe_user_pages_hard;
+unsigned long pipe_user_pages_soft = PIPE_DEF_BUFFERS * INR_OPEN_CUR;
+
 /*
  * We use a start+len construction, which provides full use of the 
  * allocated memory.
@@ -583,20 +589,49 @@ pipe_fasync(int fd, struct file *filp, i
 	return retval;
 }
 
+static void account_pipe_buffers(struct pipe_inode_info *pipe,
+                                 unsigned long old, unsigned long new)
+{
+	atomic_long_add(new - old, &pipe->user->pipe_bufs);
+}
+
+static bool too_many_pipe_buffers_soft(struct user_struct *user)
+{
+	return pipe_user_pages_soft &&
+	       atomic_long_read(&user->pipe_bufs) >= pipe_user_pages_soft;
+}
+
+static bool too_many_pipe_buffers_hard(struct user_struct *user)
+{
+	return pipe_user_pages_hard &&
+	       atomic_long_read(&user->pipe_bufs) >= pipe_user_pages_hard;
+}
+
 struct pipe_inode_info *alloc_pipe_info(void)
 {
 	struct pipe_inode_info *pipe;
 
 	pipe = kzalloc(sizeof(struct pipe_inode_info), GFP_KERNEL);
 	if (pipe) {
-		pipe->bufs = kzalloc(sizeof(struct pipe_buffer) * PIPE_DEF_BUFFERS, GFP_KERNEL);
+		unsigned long pipe_bufs = PIPE_DEF_BUFFERS;
+		struct user_struct *user = get_current_user();
+
+		if (!too_many_pipe_buffers_hard(user)) {
+			if (too_many_pipe_buffers_soft(user))
+				pipe_bufs = 1;
+			pipe->bufs = kzalloc(sizeof(struct pipe_buffer) * pipe_bufs, GFP_KERNEL);
+		}
+
 		if (pipe->bufs) {
 			init_waitqueue_head(&pipe->wait);
 			pipe->r_counter = pipe->w_counter = 1;
-			pipe->buffers = PIPE_DEF_BUFFERS;
+			pipe->buffers = pipe_bufs;
+			pipe->user = user;
+			account_pipe_buffers(pipe, 0, pipe_bufs);
 			mutex_init(&pipe->mutex);
 			return pipe;
 		}
+		free_uid(user);
 		kfree(pipe);
 	}
 
@@ -607,6 +642,8 @@ void free_pipe_info(struct pipe_inode_in
 {
 	int i;
 
+	account_pipe_buffers(pipe, pipe->buffers, 0);
+	free_uid(pipe->user);
 	for (i = 0; i < pipe->buffers; i++) {
 		struct pipe_buffer *buf = pipe->bufs + i;
 		if (buf->ops)
@@ -998,6 +1035,7 @@ static long pipe_set_size(struct pipe_in
 			memcpy(bufs + head, pipe->bufs, tail * sizeof(struct pipe_buffer));
 	}
 
+	account_pipe_buffers(pipe, pipe->buffers, nr_pages);
 	pipe->curbuf = 0;
 	kfree(pipe->bufs);
 	pipe->bufs = bufs;
@@ -1069,6 +1107,11 @@ long pipe_fcntl(struct file *file, unsig
 		if (!capable(CAP_SYS_RESOURCE) && size > pipe_max_size) {
 			ret = -EPERM;
 			goto out;
+		} else if ((too_many_pipe_buffers_hard(pipe->user) ||
+			    too_many_pipe_buffers_soft(pipe->user)) &&
+		           !capable(CAP_SYS_RESOURCE) && !capable(CAP_SYS_ADMIN)) {
+			ret = -EPERM;
+			goto out;
 		}
 		ret = pipe_set_size(pipe, nr_pages);
 		break;
--- zfcpdump-kernel-4.4.orig/fs/pnode.c
+++ zfcpdump-kernel-4.4/fs/pnode.c
@@ -198,10 +198,15 @@ static struct mount *next_group(struct m
 
 /* all accesses are serialized by namespace_sem */
 static struct user_namespace *user_ns;
-static struct mount *last_dest, *last_source, *dest_master;
+static struct mount *last_dest, *first_source, *last_source, *dest_master;
 static struct mountpoint *mp;
 static struct hlist_head *list;
 
+static inline bool peers(struct mount *m1, struct mount *m2)
+{
+	return m1->mnt_group_id == m2->mnt_group_id && m1->mnt_group_id;
+}
+
 static int propagate_one(struct mount *m)
 {
 	struct mount *child;
@@ -212,24 +217,26 @@ static int propagate_one(struct mount *m
 	/* skip if mountpoint isn't covered by it */
 	if (!is_subdir(mp->m_dentry, m->mnt.mnt_root))
 		return 0;
-	if (m->mnt_group_id == last_dest->mnt_group_id) {
+	if (peers(m, last_dest)) {
 		type = CL_MAKE_SHARED;
 	} else {
 		struct mount *n, *p;
+		bool done;
 		for (n = m; ; n = p) {
 			p = n->mnt_master;
-			if (p == dest_master || IS_MNT_MARKED(p)) {
-				while (last_dest->mnt_master != p) {
-					last_source = last_source->mnt_master;
-					last_dest = last_source->mnt_parent;
-				}
-				if (n->mnt_group_id != last_dest->mnt_group_id) {
-					last_source = last_source->mnt_master;
-					last_dest = last_source->mnt_parent;
-				}
+			if (p == dest_master || IS_MNT_MARKED(p))
 				break;
-			}
 		}
+		do {
+			struct mount *parent = last_source->mnt_parent;
+			if (last_source == first_source)
+				break;
+			done = parent->mnt_master == p;
+			if (done && peers(n, parent))
+				break;
+			last_source = last_source->mnt_master;
+		} while (!done);
+
 		type = CL_SLAVE;
 		/* beginning of peer group among the slaves? */
 		if (IS_MNT_SHARED(m))
@@ -281,6 +288,7 @@ int propagate_mnt(struct mount *dest_mnt
 	 */
 	user_ns = current->nsproxy->mnt_ns->user_ns;
 	last_dest = dest_mnt;
+	first_source = source_mnt;
 	last_source = source_mnt;
 	mp = dest_mp;
 	list = tree_list;
--- zfcpdump-kernel-4.4.orig/fs/posix_acl.c
+++ zfcpdump-kernel-4.4/fs/posix_acl.c
@@ -595,59 +595,77 @@ EXPORT_SYMBOL_GPL(posix_acl_create);
 /*
  * Fix up the uids and gids in posix acl extended attributes in place.
  */
-static void posix_acl_fix_xattr_userns(
+static int posix_acl_fix_xattr_userns(
 	struct user_namespace *to, struct user_namespace *from,
 	void *value, size_t size)
 {
 	posix_acl_xattr_header *header = (posix_acl_xattr_header *)value;
 	posix_acl_xattr_entry *entry = (posix_acl_xattr_entry *)(header+1), *end;
 	int count;
-	kuid_t uid;
-	kgid_t gid;
+	kuid_t kuid;
+	uid_t uid;
+	kgid_t kgid;
+	gid_t gid;
 
 	if (!value)
-		return;
+		return 0;
 	if (size < sizeof(posix_acl_xattr_header))
-		return;
+		return 0;
 	if (header->a_version != cpu_to_le32(POSIX_ACL_XATTR_VERSION))
-		return;
+		return 0;
 
 	count = posix_acl_xattr_count(size);
 	if (count < 0)
-		return;
+		return 0;
 	if (count == 0)
-		return;
+		return 0;
 
 	for (end = entry + count; entry != end; entry++) {
 		switch(le16_to_cpu(entry->e_tag)) {
 		case ACL_USER:
-			uid = make_kuid(from, le32_to_cpu(entry->e_id));
-			entry->e_id = cpu_to_le32(from_kuid(to, uid));
+			kuid = make_kuid(from, le32_to_cpu(entry->e_id));
+			if (!uid_valid(kuid))
+				return -EOVERFLOW;
+			uid = from_kuid(to, kuid);
+			if (uid == (uid_t)-1)
+				return -EOVERFLOW;
+			entry->e_id = cpu_to_le32(uid);
 			break;
 		case ACL_GROUP:
-			gid = make_kgid(from, le32_to_cpu(entry->e_id));
-			entry->e_id = cpu_to_le32(from_kgid(to, gid));
+			kgid = make_kgid(from, le32_to_cpu(entry->e_id));
+			if (!gid_valid(kgid))
+				return -EOVERFLOW;
+			gid = from_kgid(to, kgid);
+			if (gid == (gid_t)-1)
+				return -EOVERFLOW;
+			entry->e_id = cpu_to_le32(gid);
 			break;
 		default:
 			break;
 		}
 	}
+
+	return 0;
 }
 
-void posix_acl_fix_xattr_from_user(void *value, size_t size)
+int
+posix_acl_fix_xattr_from_user(struct user_namespace *target_ns, void *value,
+			      size_t size)
 {
-	struct user_namespace *user_ns = current_user_ns();
-	if (user_ns == &init_user_ns)
-		return;
-	posix_acl_fix_xattr_userns(&init_user_ns, user_ns, value, size);
+	struct user_namespace *source_ns = current_user_ns();
+	if (source_ns == target_ns)
+		return 0;
+	return posix_acl_fix_xattr_userns(target_ns, source_ns, value, size);
 }
 
-void posix_acl_fix_xattr_to_user(void *value, size_t size)
+int
+posix_acl_fix_xattr_to_user(struct user_namespace *source_ns, void *value,
+			    size_t size)
 {
-	struct user_namespace *user_ns = current_user_ns();
-	if (user_ns == &init_user_ns)
-		return;
-	posix_acl_fix_xattr_userns(user_ns, &init_user_ns, value, size);
+	struct user_namespace *target_ns = current_user_ns();
+	if (target_ns == source_ns)
+		return 0;
+	return posix_acl_fix_xattr_userns(target_ns, source_ns, value, size);
 }
 
 /*
@@ -782,12 +800,34 @@ posix_acl_xattr_get(const struct xattr_h
 	if (acl == NULL)
 		return -ENODATA;
 
-	error = posix_acl_to_xattr(&init_user_ns, acl, value, size);
+	error = posix_acl_to_xattr(dentry->d_sb->s_user_ns, acl, value, size);
 	posix_acl_release(acl);
 
 	return error;
 }
 
+int
+set_posix_acl(struct inode *inode, int type, struct posix_acl *acl)
+{
+	if (!IS_POSIXACL(inode))
+		return -EOPNOTSUPP;
+	if (!inode->i_op->set_acl)
+		return -EOPNOTSUPP;
+
+	if (type == ACL_TYPE_DEFAULT && !S_ISDIR(inode->i_mode))
+		return acl ? -EACCES : 0;
+	if (!inode_owner_or_capable(inode))
+		return -EPERM;
+
+	if (acl) {
+		int ret = posix_acl_valid(acl);
+		if (ret)
+			return ret;
+	}
+	return inode->i_op->set_acl(inode, acl, type);
+}
+EXPORT_SYMBOL(set_posix_acl);
+
 static int
 posix_acl_xattr_set(const struct xattr_handler *handler,
 		    struct dentry *dentry, const char *name,
@@ -799,30 +839,14 @@ posix_acl_xattr_set(const struct xattr_h
 
 	if (strcmp(name, "") != 0)
 		return -EINVAL;
-	if (!IS_POSIXACL(inode))
-		return -EOPNOTSUPP;
-	if (!inode->i_op->set_acl)
-		return -EOPNOTSUPP;
-
-	if (handler->flags == ACL_TYPE_DEFAULT && !S_ISDIR(inode->i_mode))
-		return value ? -EACCES : 0;
-	if (!inode_owner_or_capable(inode))
-		return -EPERM;
 
 	if (value) {
-		acl = posix_acl_from_xattr(&init_user_ns, value, size);
+		acl = posix_acl_from_xattr(dentry->d_sb->s_user_ns, value,
+					   size);
 		if (IS_ERR(acl))
 			return PTR_ERR(acl);
-
-		if (acl) {
-			ret = posix_acl_valid(acl);
-			if (ret)
-				goto out;
-		}
 	}
-
-	ret = inode->i_op->set_acl(inode, acl, handler->flags);
-out:
+	ret = set_posix_acl(inode, handler->flags, acl);
 	posix_acl_release(acl);
 	return ret;
 }
--- zfcpdump-kernel-4.4.orig/fs/proc/Makefile
+++ zfcpdump-kernel-4.4/fs/proc/Makefile
@@ -30,3 +30,4 @@ proc-$(CONFIG_PROC_KCORE)	+= kcore.o
 proc-$(CONFIG_PROC_VMCORE)	+= vmcore.o
 proc-$(CONFIG_PRINTK)	+= kmsg.o
 proc-$(CONFIG_PROC_PAGE_MONITOR)	+= page.o
+proc-y	+= version_signature.o
--- zfcpdump-kernel-4.4.orig/fs/proc/array.c
+++ zfcpdump-kernel-4.4/fs/proc/array.c
@@ -395,7 +395,7 @@ static int do_task_stat(struct seq_file
 
 	state = *get_task_state(task);
 	vsize = eip = esp = 0;
-	permitted = ptrace_may_access(task, PTRACE_MODE_READ | PTRACE_MODE_NOAUDIT);
+	permitted = ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS | PTRACE_MODE_NOAUDIT);
 	mm = get_task_mm(task);
 	if (mm) {
 		vsize = task_vsize(mm);
--- zfcpdump-kernel-4.4.orig/fs/proc/base.c
+++ zfcpdump-kernel-4.4/fs/proc/base.c
@@ -403,7 +403,7 @@ static const struct file_operations proc
 static int proc_pid_auxv(struct seq_file *m, struct pid_namespace *ns,
 			 struct pid *pid, struct task_struct *task)
 {
-	struct mm_struct *mm = mm_access(task, PTRACE_MODE_READ);
+	struct mm_struct *mm = mm_access(task, PTRACE_MODE_READ_FSCREDS);
 	if (mm && !IS_ERR(mm)) {
 		unsigned int nwords = 0;
 		do {
@@ -430,7 +430,8 @@ static int proc_pid_wchan(struct seq_fil
 
 	wchan = get_wchan(task);
 
-	if (wchan && ptrace_may_access(task, PTRACE_MODE_READ) && !lookup_symbol_name(wchan, symname))
+	if (wchan && ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS)
+			&& !lookup_symbol_name(wchan, symname))
 		seq_printf(m, "%s", symname);
 	else
 		seq_putc(m, '0');
@@ -444,7 +445,7 @@ static int lock_trace(struct task_struct
 	int err = mutex_lock_killable(&task->signal->cred_guard_mutex);
 	if (err)
 		return err;
-	if (!ptrace_may_access(task, PTRACE_MODE_ATTACH)) {
+	if (!ptrace_may_access(task, PTRACE_MODE_ATTACH_FSCREDS)) {
 		mutex_unlock(&task->signal->cred_guard_mutex);
 		return -EPERM;
 	}
@@ -697,7 +698,7 @@ static int proc_fd_access_allowed(struct
 	 */
 	task = get_proc_task(inode);
 	if (task) {
-		allowed = ptrace_may_access(task, PTRACE_MODE_READ);
+		allowed = ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS);
 		put_task_struct(task);
 	}
 	return allowed;
@@ -710,6 +711,8 @@ int proc_setattr(struct dentry *dentry,
 
 	if (attr->ia_valid & ATTR_MODE)
 		return -EPERM;
+	if (!uid_valid(inode->i_uid) || !gid_valid(inode->i_gid))
+		return -EPERM;
 
 	error = inode_change_ok(inode, attr);
 	if (error)
@@ -732,7 +735,7 @@ static bool has_pid_permissions(struct p
 		return true;
 	if (in_group_p(pid->pid_gid))
 		return true;
-	return ptrace_may_access(task, PTRACE_MODE_READ);
+	return ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS);
 }
 
 
@@ -809,7 +812,7 @@ struct mm_struct *proc_mem_open(struct i
 	struct mm_struct *mm = ERR_PTR(-ESRCH);
 
 	if (task) {
-		mm = mm_access(task, mode);
+		mm = mm_access(task, mode | PTRACE_MODE_FSCREDS);
 		put_task_struct(task);
 
 		if (!IS_ERR_OR_NULL(mm)) {
@@ -953,7 +956,8 @@ static ssize_t environ_read(struct file
 	int ret = 0;
 	struct mm_struct *mm = file->private_data;
 
-	if (!mm)
+	/* Ensure the process spawned far enough to have an environment. */
+	if (!mm || !mm->env_end)
 		return 0;
 
 	page = (char *)__get_free_page(GFP_TEMPORARY);
@@ -1543,18 +1547,13 @@ static const struct file_operations proc
 static int proc_exe_link(struct dentry *dentry, struct path *exe_path)
 {
 	struct task_struct *task;
-	struct mm_struct *mm;
 	struct file *exe_file;
 
 	task = get_proc_task(d_inode(dentry));
 	if (!task)
 		return -ENOENT;
-	mm = get_task_mm(task);
+	exe_file = get_task_exe_file(task);
 	put_task_struct(task);
-	if (!mm)
-		return -ENOENT;
-	exe_file = get_mm_exe_file(mm);
-	mmput(mm);
 	if (exe_file) {
 		*exe_path = exe_file->f_path;
 		path_get(&exe_file->f_path);
@@ -1856,7 +1855,7 @@ static int map_files_d_revalidate(struct
 	if (!task)
 		goto out_notask;
 
-	mm = mm_access(task, PTRACE_MODE_READ);
+	mm = mm_access(task, PTRACE_MODE_READ_FSCREDS);
 	if (IS_ERR_OR_NULL(mm))
 		goto out;
 
@@ -1921,7 +1920,7 @@ static int proc_map_files_get_link(struc
 	down_read(&mm->mmap_sem);
 	vma = find_exact_vma(mm, vm_start, vm_end);
 	if (vma && vma->vm_file) {
-		*path = vma->vm_file->f_path;
+		*path = vma_pr_or_file(vma)->f_path;
 		path_get(path);
 		rc = 0;
 	}
@@ -2007,7 +2006,7 @@ static struct dentry *proc_map_files_loo
 		goto out;
 
 	result = -EACCES;
-	if (!ptrace_may_access(task, PTRACE_MODE_READ))
+	if (!ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS))
 		goto out_put_task;
 
 	result = -ENOENT;
@@ -2060,7 +2059,7 @@ proc_map_files_readdir(struct file *file
 		goto out;
 
 	ret = -EACCES;
-	if (!ptrace_may_access(task, PTRACE_MODE_READ))
+	if (!ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS))
 		goto out_put_task;
 
 	ret = 0;
@@ -2530,7 +2529,7 @@ static int do_io_accounting(struct task_
 	if (result)
 		return result;
 
-	if (!ptrace_may_access(task, PTRACE_MODE_READ)) {
+	if (!ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS)) {
 		result = -EACCES;
 		goto out_unlock;
 	}
--- zfcpdump-kernel-4.4.orig/fs/proc/generic.c
+++ zfcpdump-kernel-4.4/fs/proc/generic.c
@@ -105,6 +105,9 @@ static int proc_notify_change(struct den
 	struct proc_dir_entry *de = PDE(inode);
 	int error;
 
+	if (!uid_valid(inode->i_uid) || !gid_valid(inode->i_gid))
+		return -EPERM;
+
 	error = inode_change_ok(inode, iattr);
 	if (error)
 		return error;
@@ -477,6 +480,7 @@ struct proc_dir_entry *proc_create_mount
 	}
 	return ent;
 }
+EXPORT_SYMBOL(proc_create_mount_point);
 
 struct proc_dir_entry *proc_create_data(const char *name, umode_t mode,
 					struct proc_dir_entry *parent,
--- zfcpdump-kernel-4.4.orig/fs/proc/internal.h
+++ zfcpdump-kernel-4.4/fs/proc/internal.h
@@ -195,7 +195,6 @@ static inline bool is_empty_pde(const st
 {
 	return S_ISDIR(pde->mode) && !pde->proc_iops;
 }
-struct proc_dir_entry *proc_create_mount_point(const char *name);
 
 /*
  * inode.c
--- zfcpdump-kernel-4.4.orig/fs/proc/meminfo.c
+++ zfcpdump-kernel-4.4/fs/proc/meminfo.c
@@ -29,10 +29,7 @@ static int meminfo_proc_show(struct seq_
 	unsigned long committed;
 	long cached;
 	long available;
-	unsigned long pagecache;
-	unsigned long wmark_low = 0;
 	unsigned long pages[NR_LRU_LISTS];
-	struct zone *zone;
 	int lru;
 
 /*
@@ -51,36 +48,7 @@ static int meminfo_proc_show(struct seq_
 	for (lru = LRU_BASE; lru < NR_LRU_LISTS; lru++)
 		pages[lru] = global_page_state(NR_LRU_BASE + lru);
 
-	for_each_zone(zone)
-		wmark_low += zone->watermark[WMARK_LOW];
-
-	/*
-	 * Estimate the amount of memory available for userspace allocations,
-	 * without causing swapping.
-	 *
-	 * Free memory cannot be taken below the low watermark, before the
-	 * system starts swapping.
-	 */
-	available = i.freeram - wmark_low;
-
-	/*
-	 * Not all the page cache can be freed, otherwise the system will
-	 * start swapping. Assume at least half of the page cache, or the
-	 * low watermark worth of cache, needs to stay.
-	 */
-	pagecache = pages[LRU_ACTIVE_FILE] + pages[LRU_INACTIVE_FILE];
-	pagecache -= min(pagecache / 2, wmark_low);
-	available += pagecache;
-
-	/*
-	 * Part of the reclaimable slab consists of items that are in use,
-	 * and cannot be freed. Cap this estimate at the low watermark.
-	 */
-	available += global_page_state(NR_SLAB_RECLAIMABLE) -
-		     min(global_page_state(NR_SLAB_RECLAIMABLE) / 2, wmark_low);
-
-	if (available < 0)
-		available = 0;
+	available = si_mem_available();
 
 	/*
 	 * Tagged format, for easy grepping and expansion.
--- zfcpdump-kernel-4.4.orig/fs/proc/namespaces.c
+++ zfcpdump-kernel-4.4/fs/proc/namespaces.c
@@ -28,6 +28,9 @@ static const struct proc_ns_operations *
 	&userns_operations,
 #endif
 	&mntns_operations,
+#ifdef CONFIG_CGROUPS
+	&cgroupns_operations,
+#endif
 };
 
 static const char *proc_ns_follow_link(struct dentry *dentry, void **cookie)
@@ -42,7 +45,7 @@ static const char *proc_ns_follow_link(s
 	if (!task)
 		return error;
 
-	if (ptrace_may_access(task, PTRACE_MODE_READ)) {
+	if (ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS)) {
 		error = ns_get_path(&ns_path, task, ns_ops);
 		if (!error)
 			nd_jump_link(&ns_path);
@@ -63,7 +66,7 @@ static int proc_ns_readlink(struct dentr
 	if (!task)
 		return res;
 
-	if (ptrace_may_access(task, PTRACE_MODE_READ)) {
+	if (ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS)) {
 		res = ns_get_name(name, sizeof(name), task, ns_ops);
 		if (res >= 0)
 			res = readlink_copy(buffer, buflen, name);
--- zfcpdump-kernel-4.4.orig/fs/proc/nommu.c
+++ zfcpdump-kernel-4.4/fs/proc/nommu.c
@@ -45,7 +45,10 @@ static int nommu_region_show(struct seq_
 	file = region->vm_file;
 
 	if (file) {
-		struct inode *inode = file_inode(region->vm_file);
+		struct inode *inode;
+
+		file = vmr_pr_or_file(region);
+		inode = file_inode(file);
 		dev = inode->i_sb->s_dev;
 		ino = inode->i_ino;
 	}
--- zfcpdump-kernel-4.4.orig/fs/proc/proc_sysctl.c
+++ zfcpdump-kernel-4.4/fs/proc/proc_sysctl.c
@@ -752,6 +752,8 @@ static int proc_sys_setattr(struct dentr
 
 	if (attr->ia_valid & (ATTR_MODE | ATTR_UID | ATTR_GID))
 		return -EPERM;
+	if (!uid_valid(inode->i_uid) || !gid_valid(inode->i_gid))
+		return -EPERM;
 
 	error = inode_change_ok(inode, attr);
 	if (error)
--- zfcpdump-kernel-4.4.orig/fs/proc/root.c
+++ zfcpdump-kernel-4.4/fs/proc/root.c
@@ -117,10 +117,18 @@ static struct dentry *proc_mount(struct
 			return ERR_PTR(-EPERM);
 	}
 
-	sb = sget(fs_type, proc_test_super, proc_set_super, flags, ns);
+	sb = sget_userns(fs_type, proc_test_super, proc_set_super, flags,
+			 ns->user_ns, ns);
 	if (IS_ERR(sb))
 		return ERR_CAST(sb);
 
+	/*
+	 * procfs isn't actually a stacking filesystem; however, there is
+	 * too much magic going on inside it to permit stacking things on
+	 * top of it
+	 */
+	sb->s_stack_depth = FILESYSTEM_MAX_STACK_DEPTH;
+
 	if (!proc_parse_options(options, ns)) {
 		deactivate_locked_super(sb);
 		return ERR_PTR(-EINVAL);
--- zfcpdump-kernel-4.4.orig/fs/proc/task_mmu.c
+++ zfcpdump-kernel-4.4/fs/proc/task_mmu.c
@@ -248,23 +248,29 @@ static int do_maps_open(struct inode *in
 				sizeof(struct proc_maps_private));
 }
 
-static pid_t pid_of_stack(struct proc_maps_private *priv,
-				struct vm_area_struct *vma, bool is_pid)
+/*
+ * Indicate if the VMA is a stack for the given task; for
+ * /proc/PID/maps that is the stack of the main task.
+ */
+static int is_stack(struct proc_maps_private *priv,
+		    struct vm_area_struct *vma, int is_pid)
 {
-	struct inode *inode = priv->inode;
-	struct task_struct *task;
-	pid_t ret = 0;
+	int stack = 0;
 
-	rcu_read_lock();
-	task = pid_task(proc_pid(inode), PIDTYPE_PID);
-	if (task) {
-		task = task_of_stack(task, vma, is_pid);
+	if (is_pid) {
+		stack = vma->vm_start <= vma->vm_mm->start_stack &&
+			vma->vm_end >= vma->vm_mm->start_stack;
+	} else {
+		struct inode *inode = priv->inode;
+		struct task_struct *task;
+
+		rcu_read_lock();
+		task = pid_task(proc_pid(inode), PIDTYPE_PID);
 		if (task)
-			ret = task_pid_nr_ns(task, inode->i_sb->s_fs_info);
+			stack = vma_is_stack_for_task(vma, task);
+		rcu_read_unlock();
 	}
-	rcu_read_unlock();
-
-	return ret;
+	return stack;
 }
 
 static void
@@ -281,7 +287,10 @@ show_map_vma(struct seq_file *m, struct
 	const char *name = NULL;
 
 	if (file) {
-		struct inode *inode = file_inode(vma->vm_file);
+		struct inode *inode;
+
+		file = vma_pr_or_file(vma);
+		inode = file_inode(file);
 		dev = inode->i_sb->s_dev;
 		ino = inode->i_ino;
 		pgoff = ((loff_t)vma->vm_pgoff) << PAGE_SHIFT;
@@ -324,8 +333,6 @@ show_map_vma(struct seq_file *m, struct
 
 	name = arch_vma_name(vma);
 	if (!name) {
-		pid_t tid;
-
 		if (!mm) {
 			name = "[vdso]";
 			goto done;
@@ -337,21 +344,8 @@ show_map_vma(struct seq_file *m, struct
 			goto done;
 		}
 
-		tid = pid_of_stack(priv, vma, is_pid);
-		if (tid != 0) {
-			/*
-			 * Thread stack in /proc/PID/task/TID/maps or
-			 * the main process stack.
-			 */
-			if (!is_pid || (vma->vm_start <= mm->start_stack &&
-			    vma->vm_end >= mm->start_stack)) {
-				name = "[stack]";
-			} else {
-				/* Thread stack in /proc/PID/maps */
-				seq_pad(m, ' ');
-				seq_printf(m, "[stack:%d]", tid);
-			}
-		}
+		if (is_stack(priv, vma, is_pid))
+			name = "[stack]";
 	}
 
 done:
@@ -1435,6 +1429,32 @@ static struct page *can_gather_numa_stat
 	return page;
 }
 
+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
+static struct page *can_gather_numa_stats_pmd(pmd_t pmd,
+					      struct vm_area_struct *vma,
+					      unsigned long addr)
+{
+	struct page *page;
+	int nid;
+
+	if (!pmd_present(pmd))
+		return NULL;
+
+	page = vm_normal_page_pmd(vma, addr, pmd);
+	if (!page)
+		return NULL;
+
+	if (PageReserved(page))
+		return NULL;
+
+	nid = page_to_nid(page);
+	if (!node_isset(nid, node_states[N_MEMORY]))
+		return NULL;
+
+	return page;
+}
+#endif
+
 static int gather_pte_stats(pmd_t *pmd, unsigned long addr,
 		unsigned long end, struct mm_walk *walk)
 {
@@ -1444,13 +1464,13 @@ static int gather_pte_stats(pmd_t *pmd,
 	pte_t *orig_pte;
 	pte_t *pte;
 
+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
 	if (pmd_trans_huge_lock(pmd, vma, &ptl) == 1) {
-		pte_t huge_pte = *(pte_t *)pmd;
 		struct page *page;
 
-		page = can_gather_numa_stats(huge_pte, vma, addr);
+		page = can_gather_numa_stats_pmd(*pmd, vma, addr);
 		if (page)
-			gather_stats(page, md, pte_dirty(huge_pte),
+			gather_stats(page, md, pmd_dirty(*pmd),
 				     HPAGE_PMD_SIZE/PAGE_SIZE);
 		spin_unlock(ptl);
 		return 0;
@@ -1458,6 +1478,7 @@ static int gather_pte_stats(pmd_t *pmd,
 
 	if (pmd_trans_unstable(pmd))
 		return 0;
+#endif
 	orig_pte = pte = pte_offset_map_lock(walk->mm, pmd, addr, &ptl);
 	do {
 		struct page *page = can_gather_numa_stats(*pte, vma, addr);
@@ -1473,18 +1494,19 @@ static int gather_pte_stats(pmd_t *pmd,
 static int gather_hugetlb_stats(pte_t *pte, unsigned long hmask,
 		unsigned long addr, unsigned long end, struct mm_walk *walk)
 {
+	pte_t huge_pte = huge_ptep_get(pte);
 	struct numa_maps *md;
 	struct page *page;
 
-	if (!pte_present(*pte))
+	if (!pte_present(huge_pte))
 		return 0;
 
-	page = pte_page(*pte);
+	page = pte_page(huge_pte);
 	if (!page)
 		return 0;
 
 	md = walk->private;
-	gather_stats(page, md, pte_dirty(*pte), 1);
+	gather_stats(page, md, pte_dirty(huge_pte), 1);
 	return 0;
 }
 
@@ -1505,7 +1527,7 @@ static int show_numa_map(struct seq_file
 	struct proc_maps_private *proc_priv = &numa_priv->proc_maps;
 	struct vm_area_struct *vma = v;
 	struct numa_maps *md = &numa_priv->md;
-	struct file *file = vma->vm_file;
+	struct file *file = vma_pr_or_file(vma);
 	struct mm_struct *mm = vma->vm_mm;
 	struct mm_walk walk = {
 		.hugetlb_entry = gather_hugetlb_stats,
@@ -1538,19 +1560,8 @@ static int show_numa_map(struct seq_file
 		seq_file_path(m, file, "\n\t= ");
 	} else if (vma->vm_start <= mm->brk && vma->vm_end >= mm->start_brk) {
 		seq_puts(m, " heap");
-	} else {
-		pid_t tid = pid_of_stack(proc_priv, vma, is_pid);
-		if (tid != 0) {
-			/*
-			 * Thread stack in /proc/PID/task/TID/maps or
-			 * the main process stack.
-			 */
-			if (!is_pid || (vma->vm_start <= mm->start_stack &&
-			    vma->vm_end >= mm->start_stack))
-				seq_puts(m, " stack");
-			else
-				seq_printf(m, " stack:%d", tid);
-		}
+	} else if (is_stack(proc_priv, vma, is_pid)) {
+		seq_puts(m, " stack");
 	}
 
 	if (is_vm_hugetlb_page(vma))
--- zfcpdump-kernel-4.4.orig/fs/proc/task_nommu.c
+++ zfcpdump-kernel-4.4/fs/proc/task_nommu.c
@@ -123,23 +123,26 @@ unsigned long task_statm(struct mm_struc
 	return size;
 }
 
-static pid_t pid_of_stack(struct proc_maps_private *priv,
-				struct vm_area_struct *vma, bool is_pid)
+static int is_stack(struct proc_maps_private *priv,
+		    struct vm_area_struct *vma, int is_pid)
 {
-	struct inode *inode = priv->inode;
-	struct task_struct *task;
-	pid_t ret = 0;
-
-	rcu_read_lock();
-	task = pid_task(proc_pid(inode), PIDTYPE_PID);
-	if (task) {
-		task = task_of_stack(task, vma, is_pid);
+	struct mm_struct *mm = vma->vm_mm;
+	int stack = 0;
+
+	if (is_pid) {
+		stack = vma->vm_start <= mm->start_stack &&
+			vma->vm_end >= mm->start_stack;
+	} else {
+		struct inode *inode = priv->inode;
+		struct task_struct *task;
+
+		rcu_read_lock();
+		task = pid_task(proc_pid(inode), PIDTYPE_PID);
 		if (task)
-			ret = task_pid_nr_ns(task, inode->i_sb->s_fs_info);
+			stack = vma_is_stack_for_task(vma, task);
+		rcu_read_unlock();
 	}
-	rcu_read_unlock();
-
-	return ret;
+	return stack;
 }
 
 /*
@@ -160,7 +163,10 @@ static int nommu_vma_show(struct seq_fil
 	file = vma->vm_file;
 
 	if (file) {
-		struct inode *inode = file_inode(vma->vm_file);
+		struct inode *inode;
+
+		file = vma_pr_or_file(vma);
+		inode = file_inode(file);
 		dev = inode->i_sb->s_dev;
 		ino = inode->i_ino;
 		pgoff = (loff_t)vma->vm_pgoff << PAGE_SHIFT;
@@ -181,21 +187,9 @@ static int nommu_vma_show(struct seq_fil
 	if (file) {
 		seq_pad(m, ' ');
 		seq_file_path(m, file, "");
-	} else if (mm) {
-		pid_t tid = pid_of_stack(priv, vma, is_pid);
-
-		if (tid != 0) {
-			seq_pad(m, ' ');
-			/*
-			 * Thread stack in /proc/PID/task/TID/maps or
-			 * the main process stack.
-			 */
-			if (!is_pid || (vma->vm_start <= mm->start_stack &&
-			    vma->vm_end >= mm->start_stack))
-				seq_printf(m, "[stack]");
-			else
-				seq_printf(m, "[stack:%d]", tid);
-		}
+	} else if (mm && is_stack(priv, vma, is_pid)) {
+		seq_pad(m, ' ');
+		seq_printf(m, "[stack]");
 	}
 
 	seq_putc(m, '\n');
--- /dev/null
+++ zfcpdump-kernel-4.4/fs/proc/version_signature.c
@@ -0,0 +1,32 @@
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/init.h>
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
+#include <linux/utsname.h>
+
+static int version_signature_proc_show(struct seq_file *m, void *v)
+{
+	seq_printf(m, "%s\n", CONFIG_VERSION_SIGNATURE);
+	return 0;
+}
+
+static int version_signature_proc_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, version_signature_proc_show, NULL);
+}
+
+static const struct file_operations version_signature_proc_fops = {
+	.open		= version_signature_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
+static int __init proc_version_signature_init(void)
+{
+	proc_create("version_signature", 0, NULL, &version_signature_proc_fops);
+	return 0;
+}
+module_init(proc_version_signature_init);
--- zfcpdump-kernel-4.4.orig/fs/proc_namespace.c
+++ zfcpdump-kernel-4.4/fs/proc_namespace.c
@@ -197,6 +197,8 @@ static int show_vfsstat(struct seq_file
 	if (sb->s_op->show_devname) {
 		seq_puts(m, "device ");
 		err = sb->s_op->show_devname(m, mnt_path.dentry);
+		if (err)
+			goto out;
 	} else {
 		if (r->mnt_devname) {
 			seq_puts(m, "device ");
--- zfcpdump-kernel-4.4.orig/fs/pstore/inode.c
+++ zfcpdump-kernel-4.4/fs/pstore/inode.c
@@ -178,7 +178,6 @@ static loff_t pstore_file_llseek(struct
 }
 
 static const struct file_operations pstore_file_operations = {
-	.owner		= THIS_MODULE,
 	.open		= pstore_file_open,
 	.read		= pstore_file_read,
 	.llseek		= pstore_file_llseek,
--- zfcpdump-kernel-4.4.orig/fs/quota/dquot.c
+++ zfcpdump-kernel-4.4/fs/quota/dquot.c
@@ -741,7 +741,7 @@ void dqput(struct dquot *dquot)
 	if (!atomic_read(&dquot->dq_count)) {
 		quota_error(dquot->dq_sb, "trying to free free dquot of %s %d",
 			    quotatypes[dquot->dq_id.type],
-			    from_kqid(&init_user_ns, dquot->dq_id));
+			    from_kqid(dquot->dq_sb->s_user_ns, dquot->dq_id));
 		BUG();
 	}
 #endif
@@ -834,6 +834,12 @@ struct dquot *dqget(struct super_block *
 	unsigned int hashent = hashfn(sb, qid);
 	struct dquot *dquot, *empty = NULL;
 
+	/* qid must be valid and must map into sb's userns */
+	if (!qid_valid(qid))
+		return ERR_PTR(-EINVAL);
+	if (from_kqid(sb->s_user_ns, qid) == (qid_t)-1)
+		return ERR_PTR(-EOVERFLOW);
+
         if (!sb_has_quota_active(sb, qid.type))
 		return ERR_PTR(-ESRCH);
 we_slept:
@@ -1398,7 +1404,7 @@ static int dquot_active(const struct ino
 static int __dquot_initialize(struct inode *inode, int type)
 {
 	int cnt, init_needed = 0;
-	struct dquot **dquots, *got[MAXQUOTAS];
+	struct dquot **dquots, *got[MAXQUOTAS] = {};
 	struct super_block *sb = inode->i_sb;
 	qsize_t rsv;
 	int ret = 0;
@@ -1415,7 +1421,6 @@ static int __dquot_initialize(struct ino
 		int rc;
 		struct dquot *dquot;
 
-		got[cnt] = NULL;
 		if (type != -1 && cnt != type)
 			continue;
 		/*
--- zfcpdump-kernel-4.4.orig/fs/quota/quota.c
+++ zfcpdump-kernel-4.4/fs/quota/quota.c
@@ -733,7 +733,7 @@ static struct super_block *quotactl_bloc
 
 	if (IS_ERR(tmp))
 		return ERR_CAST(tmp);
-	bdev = lookup_bdev(tmp->name);
+	bdev = lookup_bdev(tmp->name, 0);
 	putname(tmp);
 	if (IS_ERR(bdev))
 		return ERR_CAST(bdev);
--- zfcpdump-kernel-4.4.orig/fs/quota/quota_tree.c
+++ zfcpdump-kernel-4.4/fs/quota/quota_tree.c
@@ -25,8 +25,10 @@ MODULE_LICENSE("GPL");
 static int get_index(struct qtree_mem_dqinfo *info, struct kqid qid, int depth)
 {
 	unsigned int epb = info->dqi_usable_bs >> 2;
-	qid_t id = from_kqid(&init_user_ns, qid);
+	qid_t id = from_kqid(info->dqi_sb->s_user_ns, qid);
 
+	if (id == (qid_t)-1)
+		return -EOVERFLOW;
 	depth = info->dqi_qtree_depth - depth - 1;
 	while (depth--)
 		id /= epb;
@@ -292,7 +294,7 @@ static int do_insert_tree(struct qtree_m
 			  uint *treeblk, int depth)
 {
 	char *buf = getdqbuf(info->dqi_usable_bs);
-	int ret = 0, newson = 0, newact = 0;
+	int ret = 0, newson = 0, newact = 0, index;
 	__le32 *ref;
 	uint newblk;
 
@@ -314,7 +316,12 @@ static int do_insert_tree(struct qtree_m
 		}
 	}
 	ref = (__le32 *)buf;
-	newblk = le32_to_cpu(ref[get_index(info, dquot->dq_id, depth)]);
+	index = get_index(info, dquot->dq_id, depth);
+	if (index < 0) {
+		ret = index;
+		goto out_buf;
+	}
+	newblk = le32_to_cpu(ref[index]);
 	if (!newblk)
 		newson = 1;
 	if (depth == info->dqi_qtree_depth - 1) {
@@ -322,8 +329,7 @@ static int do_insert_tree(struct qtree_m
 		if (newblk) {
 			quota_error(dquot->dq_sb, "Inserting already present "
 				    "quota entry (block %u)",
-				    le32_to_cpu(ref[get_index(info,
-						dquot->dq_id, depth)]));
+				    le32_to_cpu(ref[index]));
 			ret = -EIO;
 			goto out_buf;
 		}
@@ -333,8 +339,7 @@ static int do_insert_tree(struct qtree_m
 		ret = do_insert_tree(info, dquot, &newblk, depth+1);
 	}
 	if (newson && ret >= 0) {
-		ref[get_index(info, dquot->dq_id, depth)] =
-							cpu_to_le32(newblk);
+		ref[index] = cpu_to_le32(newblk);
 		ret = write_blk(info, *treeblk, buf);
 	} else if (newact && ret < 0) {
 		put_free_dqblk(info, buf, *treeblk);
@@ -384,8 +389,10 @@ int qtree_write_dquot(struct qtree_mem_d
 		}
 	}
 	spin_lock(&dq_data_lock);
-	info->dqi_ops->mem2disk_dqblk(ddquot, dquot);
+	ret = info->dqi_ops->mem2disk_dqblk(ddquot, dquot);
 	spin_unlock(&dq_data_lock);
+	if (ret)
+		goto out_free;
 	ret = sb->s_op->quota_write(sb, type, ddquot, info->dqi_entry_size,
 				    dquot->dq_off);
 	if (ret != info->dqi_entry_size) {
@@ -396,8 +403,9 @@ int qtree_write_dquot(struct qtree_mem_d
 		ret = 0;
 	}
 	dqstats_inc(DQST_WRITES);
-	kfree(ddquot);
 
+out_free:
+	kfree(ddquot);
 	return ret;
 }
 EXPORT_SYMBOL(qtree_write_dquot);
@@ -468,7 +476,7 @@ static int remove_tree(struct qtree_mem_
 		       uint *blk, int depth)
 {
 	char *buf = getdqbuf(info->dqi_usable_bs);
-	int ret = 0;
+	int ret = 0, index;
 	uint newblk;
 	__le32 *ref = (__le32 *)buf;
 
@@ -480,7 +488,12 @@ static int remove_tree(struct qtree_mem_
 			    *blk);
 		goto out_buf;
 	}
-	newblk = le32_to_cpu(ref[get_index(info, dquot->dq_id, depth)]);
+	index = get_index(info, dquot->dq_id, depth);
+	if (index < 0) {
+		ret = index;
+		goto out_buf;
+	}
+	newblk = le32_to_cpu(ref[index]);
 	if (depth == info->dqi_qtree_depth - 1) {
 		ret = free_dqentry(info, dquot, newblk);
 		newblk = 0;
@@ -489,7 +502,7 @@ static int remove_tree(struct qtree_mem_
 	}
 	if (ret >= 0 && !newblk) {
 		int i;
-		ref[get_index(info, dquot->dq_id, depth)] = cpu_to_le32(0);
+		ref[index] = cpu_to_le32(0);
 		/* Block got empty? */
 		for (i = 0; i < (info->dqi_usable_bs >> 2) && !ref[i]; i++)
 			;
@@ -548,7 +561,7 @@ static loff_t find_block_dqentry(struct
 	if (i == qtree_dqstr_in_blk(info)) {
 		quota_error(dquot->dq_sb,
 			    "Quota for id %u referenced but not present",
-			    from_kqid(&init_user_ns, dquot->dq_id));
+			    from_kqid(dquot->dq_sb->s_user_ns, dquot->dq_id));
 		ret = -EIO;
 		goto out_buf;
 	} else {
@@ -565,7 +578,7 @@ static loff_t find_tree_dqentry(struct q
 				struct dquot *dquot, uint blk, int depth)
 {
 	char *buf = getdqbuf(info->dqi_usable_bs);
-	loff_t ret = 0;
+	loff_t ret = 0, index;
 	__le32 *ref = (__le32 *)buf;
 
 	if (!buf)
@@ -577,7 +590,12 @@ static loff_t find_tree_dqentry(struct q
 		goto out_buf;
 	}
 	ret = 0;
-	blk = le32_to_cpu(ref[get_index(info, dquot->dq_id, depth)]);
+	index = get_index(info, dquot->dq_id, depth);
+	if (index < 0) {
+		ret = index;
+		goto out_buf;
+	}
+	blk = le32_to_cpu(ref[index]);
 	if (!blk)	/* No reference? */
 		goto out_buf;
 	if (depth < info->dqi_qtree_depth - 1)
@@ -602,7 +620,7 @@ int qtree_read_dquot(struct qtree_mem_dq
 	struct super_block *sb = dquot->dq_sb;
 	loff_t offset;
 	char *ddquot;
-	int ret = 0;
+	int ret = 0, err;
 
 #ifdef __QUOTA_QT_PARANOIA
 	/* Invalidated quota? */
@@ -618,7 +636,7 @@ int qtree_read_dquot(struct qtree_mem_dq
 			if (offset < 0)
 				quota_error(sb,"Can't read quota structure "
 					    "for id %u",
-					    from_kqid(&init_user_ns,
+					    from_kqid(sb->s_user_ns,
 						      dquot->dq_id));
 			dquot->dq_off = 0;
 			set_bit(DQ_FAKE_B, &dquot->dq_flags);
@@ -637,18 +655,20 @@ int qtree_read_dquot(struct qtree_mem_dq
 		if (ret >= 0)
 			ret = -EIO;
 		quota_error(sb, "Error while reading quota structure for id %u",
-			    from_kqid(&init_user_ns, dquot->dq_id));
+			    from_kqid(sb->s_user_ns, dquot->dq_id));
 		set_bit(DQ_FAKE_B, &dquot->dq_flags);
 		memset(&dquot->dq_dqb, 0, sizeof(struct mem_dqblk));
 		kfree(ddquot);
 		goto out;
 	}
 	spin_lock(&dq_data_lock);
-	info->dqi_ops->disk2mem_dqblk(dquot, ddquot);
-	if (!dquot->dq_dqb.dqb_bhardlimit &&
-	    !dquot->dq_dqb.dqb_bsoftlimit &&
-	    !dquot->dq_dqb.dqb_ihardlimit &&
-	    !dquot->dq_dqb.dqb_isoftlimit)
+	err = info->dqi_ops->disk2mem_dqblk(dquot, ddquot);
+	if (err)
+		ret = err;
+	else if (!dquot->dq_dqb.dqb_bhardlimit &&
+		 !dquot->dq_dqb.dqb_bsoftlimit &&
+		 !dquot->dq_dqb.dqb_ihardlimit &&
+		 !dquot->dq_dqb.dqb_isoftlimit)
 		set_bit(DQ_FAKE_B, &dquot->dq_flags);
 	spin_unlock(&dq_data_lock);
 	kfree(ddquot);
--- zfcpdump-kernel-4.4.orig/fs/quota/quota_v1.c
+++ zfcpdump-kernel-4.4/fs/quota/quota_v1.c
@@ -56,15 +56,20 @@ static int v1_read_dqblk(struct dquot *d
 {
 	int type = dquot->dq_id.type;
 	struct v1_disk_dqblk dqblk;
+	qid_t qid;
 
 	if (!sb_dqopt(dquot->dq_sb)->files[type])
 		return -EINVAL;
 
+	qid = from_kqid(dquot->dq_sb->s_user_ns, dquot->dq_id);
+	if (qid == (qid_t)-1)
+		return -EOVERFLOW;
+
 	/* Set structure to 0s in case read fails/is after end of file */
 	memset(&dqblk, 0, sizeof(struct v1_disk_dqblk));
 	dquot->dq_sb->s_op->quota_read(dquot->dq_sb, type, (char *)&dqblk,
 			sizeof(struct v1_disk_dqblk),
-			v1_dqoff(from_kqid(&init_user_ns, dquot->dq_id)));
+			v1_dqoff(qid));
 
 	v1_disk2mem_dqblk(&dquot->dq_dqb, &dqblk);
 	if (dquot->dq_dqb.dqb_bhardlimit == 0 &&
@@ -82,6 +87,10 @@ static int v1_commit_dqblk(struct dquot
 	short type = dquot->dq_id.type;
 	ssize_t ret;
 	struct v1_disk_dqblk dqblk;
+	qid_t qid = from_kqid(dquot->dq_sb->s_user_ns, dquot->dq_id);
+
+	if (qid == (qid_t)-1)
+		return -EOVERFLOW;
 
 	v1_mem2disk_dqblk(&dqblk, &dquot->dq_dqb);
 	if (((type == USRQUOTA) && uid_eq(dquot->dq_id.uid, GLOBAL_ROOT_UID)) ||
@@ -95,7 +104,7 @@ static int v1_commit_dqblk(struct dquot
 	if (sb_dqopt(dquot->dq_sb)->files[type])
 		ret = dquot->dq_sb->s_op->quota_write(dquot->dq_sb, type,
 			(char *)&dqblk, sizeof(struct v1_disk_dqblk),
-			v1_dqoff(from_kqid(&init_user_ns, dquot->dq_id)));
+			v1_dqoff(qid));
 	if (ret != sizeof(struct v1_disk_dqblk)) {
 		quota_error(dquot->dq_sb, "dquota write failed");
 		if (ret >= 0)
--- zfcpdump-kernel-4.4.orig/fs/quota/quota_v2.c
+++ zfcpdump-kernel-4.4/fs/quota/quota_v2.c
@@ -23,11 +23,11 @@ MODULE_LICENSE("GPL");
 
 #define __QUOTA_V2_PARANOIA
 
-static void v2r0_mem2diskdqb(void *dp, struct dquot *dquot);
-static void v2r0_disk2memdqb(struct dquot *dquot, void *dp);
+static int v2r0_mem2diskdqb(void *dp, struct dquot *dquot);
+static int v2r0_disk2memdqb(struct dquot *dquot, void *dp);
 static int v2r0_is_id(void *dp, struct dquot *dquot);
-static void v2r1_mem2diskdqb(void *dp, struct dquot *dquot);
-static void v2r1_disk2memdqb(struct dquot *dquot, void *dp);
+static int v2r1_mem2diskdqb(void *dp, struct dquot *dquot);
+static int v2r1_disk2memdqb(struct dquot *dquot, void *dp);
 static int v2r1_is_id(void *dp, struct dquot *dquot);
 
 static struct qtree_fmt_operations v2r0_qtree_ops = {
@@ -177,7 +177,7 @@ static int v2_write_file_info(struct sup
 	return 0;
 }
 
-static void v2r0_disk2memdqb(struct dquot *dquot, void *dp)
+static int v2r0_disk2memdqb(struct dquot *dquot, void *dp)
 {
 	struct v2r0_disk_dqblk *d = dp, empty;
 	struct mem_dqblk *m = &dquot->dq_dqb;
@@ -195,14 +195,19 @@ static void v2r0_disk2memdqb(struct dquo
 	empty.dqb_itime = cpu_to_le64(1);
 	if (!memcmp(&empty, dp, sizeof(struct v2r0_disk_dqblk)))
 		m->dqb_itime = 0;
+	return 0;
 }
 
-static void v2r0_mem2diskdqb(void *dp, struct dquot *dquot)
+static int v2r0_mem2diskdqb(void *dp, struct dquot *dquot)
 {
 	struct v2r0_disk_dqblk *d = dp;
 	struct mem_dqblk *m = &dquot->dq_dqb;
 	struct qtree_mem_dqinfo *info =
 			sb_dqinfo(dquot->dq_sb, dquot->dq_id.type)->dqi_priv;
+	qid_t qid = from_kqid(dquot->dq_sb->s_user_ns, dquot->dq_id);
+
+	if (qid == (qid_t)-1)
+		return -EOVERFLOW;
 
 	d->dqb_ihardlimit = cpu_to_le32(m->dqb_ihardlimit);
 	d->dqb_isoftlimit = cpu_to_le32(m->dqb_isoftlimit);
@@ -212,9 +217,10 @@ static void v2r0_mem2diskdqb(void *dp, s
 	d->dqb_bsoftlimit = cpu_to_le32(v2_stoqb(m->dqb_bsoftlimit));
 	d->dqb_curspace = cpu_to_le64(m->dqb_curspace);
 	d->dqb_btime = cpu_to_le64(m->dqb_btime);
-	d->dqb_id = cpu_to_le32(from_kqid(&init_user_ns, dquot->dq_id));
+	d->dqb_id = cpu_to_le32(qid);
 	if (qtree_entry_unused(info, dp))
 		d->dqb_itime = cpu_to_le64(1);
+	return 0;
 }
 
 static int v2r0_is_id(void *dp, struct dquot *dquot)
@@ -222,15 +228,18 @@ static int v2r0_is_id(void *dp, struct d
 	struct v2r0_disk_dqblk *d = dp;
 	struct qtree_mem_dqinfo *info =
 			sb_dqinfo(dquot->dq_sb, dquot->dq_id.type)->dqi_priv;
+	struct kqid qid;
 
 	if (qtree_entry_unused(info, dp))
 		return 0;
-	return qid_eq(make_kqid(&init_user_ns, dquot->dq_id.type,
-				le32_to_cpu(d->dqb_id)),
-		      dquot->dq_id);
+	qid = make_kqid(dquot->dq_sb->s_user_ns, dquot->dq_id.type,
+			le32_to_cpu(d->dqb_id));
+	if (!qid_valid(qid))
+		return 0;
+	return qid_eq(qid, dquot->dq_id);
 }
 
-static void v2r1_disk2memdqb(struct dquot *dquot, void *dp)
+static int v2r1_disk2memdqb(struct dquot *dquot, void *dp)
 {
 	struct v2r1_disk_dqblk *d = dp, empty;
 	struct mem_dqblk *m = &dquot->dq_dqb;
@@ -248,14 +257,19 @@ static void v2r1_disk2memdqb(struct dquo
 	empty.dqb_itime = cpu_to_le64(1);
 	if (!memcmp(&empty, dp, sizeof(struct v2r1_disk_dqblk)))
 		m->dqb_itime = 0;
+	return 0;
 }
 
-static void v2r1_mem2diskdqb(void *dp, struct dquot *dquot)
+static int v2r1_mem2diskdqb(void *dp, struct dquot *dquot)
 {
 	struct v2r1_disk_dqblk *d = dp;
 	struct mem_dqblk *m = &dquot->dq_dqb;
 	struct qtree_mem_dqinfo *info =
 			sb_dqinfo(dquot->dq_sb, dquot->dq_id.type)->dqi_priv;
+	qid_t qid = from_kqid(dquot->dq_sb->s_user_ns, dquot->dq_id);
+
+	if (qid == (qid_t)-1)
+		return -EOVERFLOW;
 
 	d->dqb_ihardlimit = cpu_to_le64(m->dqb_ihardlimit);
 	d->dqb_isoftlimit = cpu_to_le64(m->dqb_isoftlimit);
@@ -265,9 +279,10 @@ static void v2r1_mem2diskdqb(void *dp, s
 	d->dqb_bsoftlimit = cpu_to_le64(v2_stoqb(m->dqb_bsoftlimit));
 	d->dqb_curspace = cpu_to_le64(m->dqb_curspace);
 	d->dqb_btime = cpu_to_le64(m->dqb_btime);
-	d->dqb_id = cpu_to_le32(from_kqid(&init_user_ns, dquot->dq_id));
+	d->dqb_id = cpu_to_le32(qid);
 	if (qtree_entry_unused(info, dp))
 		d->dqb_itime = cpu_to_le64(1);
+	return 0;
 }
 
 static int v2r1_is_id(void *dp, struct dquot *dquot)
@@ -278,7 +293,7 @@ static int v2r1_is_id(void *dp, struct d
 
 	if (qtree_entry_unused(info, dp))
 		return 0;
-	return qid_eq(make_kqid(&init_user_ns, dquot->dq_id.type,
+	return qid_eq(make_kqid(dquot->dq_sb->s_user_ns, dquot->dq_id.type,
 				le32_to_cpu(d->dqb_id)),
 		      dquot->dq_id);
 }
--- zfcpdump-kernel-4.4.orig/fs/read_write.c
+++ zfcpdump-kernel-4.4/fs/read_write.c
@@ -494,6 +494,30 @@ ssize_t __vfs_write(struct file *file, c
 }
 EXPORT_SYMBOL(__vfs_write);
 
+vfs_readf_t vfs_readf(struct file *file)
+{
+	const struct file_operations *fop = file->f_op;
+
+	if (fop->read)
+		return fop->read;
+	if (fop->read_iter)
+		return new_sync_read;
+	return ERR_PTR(-ENOSYS);
+}
+EXPORT_SYMBOL(vfs_readf);
+
+vfs_writef_t vfs_writef(struct file *file)
+{
+	const struct file_operations *fop = file->f_op;
+
+	if (fop->write)
+		return fop->write;
+	if (fop->write_iter)
+		return new_sync_write;
+	return ERR_PTR(-ENOSYS);
+}
+EXPORT_SYMBOL(vfs_writef);
+
 ssize_t __kernel_write(struct file *file, const char *buf, size_t count, loff_t *pos)
 {
 	mm_segment_t old_fs;
--- zfcpdump-kernel-4.4.orig/fs/reiserfs/ibalance.c
+++ zfcpdump-kernel-4.4/fs/reiserfs/ibalance.c
@@ -1153,8 +1153,9 @@ int balance_internal(struct tree_balance
 				       insert_ptr);
 	}
 
-	memcpy(new_insert_key_addr, &new_insert_key, KEY_SIZE);
 	insert_ptr[0] = new_insert_ptr;
+	if (new_insert_ptr)
+		memcpy(new_insert_key_addr, &new_insert_key, KEY_SIZE);
 
 	return order;
 }
--- zfcpdump-kernel-4.4.orig/fs/seq_file.c
+++ zfcpdump-kernel-4.4/fs/seq_file.c
@@ -222,8 +222,10 @@ ssize_t seq_read(struct file *file, char
 		size -= n;
 		buf += n;
 		copied += n;
-		if (!m->count)
+		if (!m->count) {
+			m->from = 0;
 			m->index++;
+		}
 		if (!size)
 			goto Done;
 	}
--- zfcpdump-kernel-4.4.orig/fs/splice.c
+++ zfcpdump-kernel-4.4/fs/splice.c
@@ -185,6 +185,9 @@ ssize_t splice_to_pipe(struct pipe_inode
 	unsigned int spd_pages = spd->nr_pages;
 	int ret, do_wakeup, page_nr;
 
+	if (!spd_pages)
+		return 0;
+
 	ret = 0;
 	do_wakeup = 0;
 	page_nr = 0;
@@ -1110,8 +1113,8 @@ EXPORT_SYMBOL(generic_splice_sendpage);
 /*
  * Attempt to initiate a splice from pipe to file.
  */
-static long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
-			   loff_t *ppos, size_t len, unsigned int flags)
+long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
+		    loff_t *ppos, size_t len, unsigned int flags)
 {
 	ssize_t (*splice_write)(struct pipe_inode_info *, struct file *,
 				loff_t *, size_t, unsigned int);
@@ -1123,13 +1126,14 @@ static long do_splice_from(struct pipe_i
 
 	return splice_write(pipe, out, ppos, len, flags);
 }
+EXPORT_SYMBOL(do_splice_from);
 
 /*
  * Attempt to initiate a splice from a file to a pipe.
  */
-static long do_splice_to(struct file *in, loff_t *ppos,
-			 struct pipe_inode_info *pipe, size_t len,
-			 unsigned int flags)
+long do_splice_to(struct file *in, loff_t *ppos,
+		  struct pipe_inode_info *pipe, size_t len,
+		  unsigned int flags)
 {
 	ssize_t (*splice_read)(struct file *, loff_t *,
 			       struct pipe_inode_info *, size_t, unsigned int);
@@ -1149,6 +1153,7 @@ static long do_splice_to(struct file *in
 
 	return splice_read(in, ppos, pipe, len, flags);
 }
+EXPORT_SYMBOL(do_splice_to);
 
 /**
  * splice_direct_to_actor - splices data directly between two non-pipes
--- zfcpdump-kernel-4.4.orig/fs/super.c
+++ zfcpdump-kernel-4.4/fs/super.c
@@ -33,6 +33,7 @@
 #include <linux/cleancache.h>
 #include <linux/fsnotify.h>
 #include <linux/lockdep.h>
+#include <linux/user_namespace.h>
 #include "internal.h"
 
 
@@ -165,6 +166,7 @@ static void destroy_super(struct super_b
 	list_lru_destroy(&s->s_inode_lru);
 	security_sb_free(s);
 	WARN_ON(!list_empty(&s->s_mounts));
+	put_user_ns(s->s_user_ns);
 	kfree(s->s_subtype);
 	kfree(s->s_options);
 	call_rcu(&s->rcu, destroy_super_rcu);
@@ -174,11 +176,13 @@ static void destroy_super(struct super_b
  *	alloc_super	-	create new superblock
  *	@type:	filesystem type superblock should belong to
  *	@flags: the mount flags
+ *	@user_ns: User namespace for the super_block
  *
  *	Allocates and initializes a new &struct super_block.  alloc_super()
  *	returns a pointer new superblock or %NULL if allocation had failed.
  */
-static struct super_block *alloc_super(struct file_system_type *type, int flags)
+static struct super_block *alloc_super(struct file_system_type *type, int flags,
+				       struct user_namespace *user_ns)
 {
 	struct super_block *s = kzalloc(sizeof(struct super_block),  GFP_USER);
 	static const struct super_operations default_op;
@@ -188,6 +192,7 @@ static struct super_block *alloc_super(s
 		return NULL;
 
 	INIT_LIST_HEAD(&s->s_mounts);
+	s->s_user_ns = get_user_ns(user_ns);
 
 	if (security_sb_alloc(s))
 		goto fail;
@@ -415,6 +420,7 @@ void generic_shutdown_super(struct super
 		sb->s_flags &= ~MS_ACTIVE;
 
 		fsnotify_unmount_inodes(sb);
+		cgroup_writeback_umount();
 
 		evict_inodes(sb);
 
@@ -442,17 +448,18 @@ void generic_shutdown_super(struct super
 EXPORT_SYMBOL(generic_shutdown_super);
 
 /**
- *	sget	-	find or create a superblock
+ *	sget_userns -	find or create a superblock
  *	@type:	filesystem type superblock should belong to
  *	@test:	comparison callback
  *	@set:	setup callback
  *	@flags:	mount flags
+ *	@user_ns: User namespace for the super_block
  *	@data:	argument to each of them
  */
-struct super_block *sget(struct file_system_type *type,
+struct super_block *sget_userns(struct file_system_type *type,
 			int (*test)(struct super_block *,void *),
 			int (*set)(struct super_block *,void *),
-			int flags,
+			int flags, struct user_namespace *user_ns,
 			void *data)
 {
 	struct super_block *s = NULL;
@@ -465,6 +472,14 @@ retry:
 		hlist_for_each_entry(old, &type->fs_supers, s_instances) {
 			if (!test(old, data))
 				continue;
+			if (user_ns != old->s_user_ns) {
+				spin_unlock(&sb_lock);
+				if (s) {
+					up_write(&s->s_umount);
+					destroy_super(s);
+				}
+				return ERR_PTR(-EBUSY);
+			}
 			if (!grab_super(old))
 				goto retry;
 			if (s) {
@@ -477,7 +492,7 @@ retry:
 	}
 	if (!s) {
 		spin_unlock(&sb_lock);
-		s = alloc_super(type, flags);
+		s = alloc_super(type, flags, user_ns);
 		if (!s)
 			return ERR_PTR(-ENOMEM);
 		goto retry;
@@ -500,6 +515,31 @@ retry:
 	return s;
 }
 
+EXPORT_SYMBOL(sget_userns);
+
+/**
+ *	sget	-	find or create a superblock
+ *	@type:	  filesystem type superblock should belong to
+ *	@test:	  comparison callback
+ *	@set:	  setup callback
+ *	@flags:	  mount flags
+ *	@data:	  argument to each of them
+ */
+struct super_block *sget(struct file_system_type *type,
+			int (*test)(struct super_block *,void *),
+			int (*set)(struct super_block *,void *),
+			int flags,
+			void *data)
+{
+	struct user_namespace *user_ns = current_user_ns();
+
+	/* Ensure the requestor has permissions over the target filesystem */
+	if (!(flags & MS_KERNMOUNT) && !ns_capable(user_ns, CAP_SYS_ADMIN))
+		return ERR_PTR(-EPERM);
+
+	return sget_userns(type, test, set, flags, user_ns, data);
+}
+
 EXPORT_SYMBOL(sget);
 
 void drop_super(struct super_block *sb)
@@ -917,12 +957,20 @@ static int ns_set_super(struct super_blo
 	return set_anon_super(sb, NULL);
 }
 
-struct dentry *mount_ns(struct file_system_type *fs_type, int flags,
-	void *data, int (*fill_super)(struct super_block *, void *, int))
+struct dentry *mount_ns(struct file_system_type *fs_type,
+	int flags, void *data, void *ns, struct user_namespace *user_ns,
+	int (*fill_super)(struct super_block *, void *, int))
 {
 	struct super_block *sb;
 
-	sb = sget(fs_type, ns_test_super, ns_set_super, flags, data);
+	/* Don't allow mounting unless the caller has CAP_SYS_ADMIN
+	 * over the namespace.
+	 */
+	if (!(flags & MS_KERNMOUNT) && !ns_capable(user_ns, CAP_SYS_ADMIN))
+		return ERR_PTR(-EPERM);
+
+	sb = sget_userns(fs_type, ns_test_super, ns_set_super, flags,
+			 user_ns, ns);
 	if (IS_ERR(sb))
 		return ERR_CAST(sb);
 
@@ -977,6 +1025,23 @@ struct dentry *mount_bdev(struct file_sy
 	if (IS_ERR(bdev))
 		return ERR_CAST(bdev);
 
+	if (current_user_ns() != &init_user_ns) {
+		/*
+		 * For userns mounts, disallow mounting if bdev is open for
+		 * writing
+		 */
+		if (!atomic_dec_unless_positive(&bdev->bd_inode->i_writecount)) {
+			error = -EBUSY;
+			goto error_bdev;
+		}
+		if (bdev->bd_contains != bdev &&
+		    !atomic_dec_unless_positive(&bdev->bd_contains->bd_inode->i_writecount)) {
+			atomic_inc(&bdev->bd_inode->i_writecount);
+			error = -EBUSY;
+			goto error_bdev;
+		}
+	}
+
 	/*
 	 * once the super is inserted into the list by sget, s_umount
 	 * will protect the lockfs code from trying to start a snapshot
@@ -986,7 +1051,7 @@ struct dentry *mount_bdev(struct file_sy
 	if (bdev->bd_fsfreeze_count > 0) {
 		mutex_unlock(&bdev->bd_fsfreeze_mutex);
 		error = -EBUSY;
-		goto error_bdev;
+		goto error_inc;
 	}
 	s = sget(fs_type, test_bdev_super, set_bdev_super, flags | MS_NOSEC,
 		 bdev);
@@ -998,7 +1063,7 @@ struct dentry *mount_bdev(struct file_sy
 		if ((flags ^ s->s_flags) & MS_RDONLY) {
 			deactivate_locked_super(s);
 			error = -EBUSY;
-			goto error_bdev;
+			goto error_inc;
 		}
 
 		/*
@@ -1031,6 +1096,12 @@ struct dentry *mount_bdev(struct file_sy
 
 error_s:
 	error = PTR_ERR(s);
+error_inc:
+	if (current_user_ns() != &init_user_ns) {
+		atomic_inc(&bdev->bd_inode->i_writecount);
+		if (bdev->bd_contains != bdev)
+			atomic_inc(&bdev->bd_contains->bd_inode->i_writecount);
+	}
 error_bdev:
 	blkdev_put(bdev, mode);
 error:
@@ -1047,6 +1118,11 @@ void kill_block_super(struct super_block
 	generic_shutdown_super(sb);
 	sync_blockdev(bdev);
 	WARN_ON_ONCE(!(mode & FMODE_EXCL));
+	if (sb->s_user_ns != &init_user_ns) {
+		atomic_inc(&bdev->bd_inode->i_writecount);
+		if (bdev->bd_contains != bdev)
+			atomic_inc(&bdev->bd_contains->bd_inode->i_writecount);
+	}
 	blkdev_put(bdev, mode | FMODE_EXCL);
 }
 
--- zfcpdump-kernel-4.4.orig/fs/sysfs/file.c
+++ zfcpdump-kernel-4.4/fs/sysfs/file.c
@@ -114,9 +114,15 @@ static ssize_t sysfs_kf_read(struct kern
 	 * If buf != of->prealloc_buf, we don't know how
 	 * large it is, so cannot safely pass it to ->show
 	 */
-	if (pos || WARN_ON_ONCE(buf != of->prealloc_buf))
+	if (WARN_ON_ONCE(buf != of->prealloc_buf))
 		return 0;
 	len = ops->show(kobj, of->kn->priv, buf);
+	if (pos) {
+		if (len <= pos)
+			return 0;
+		len -= pos;
+		memmove(buf, buf + pos, len);
+	}
 	return min(count, len);
 }
 
--- zfcpdump-kernel-4.4.orig/fs/sysfs/mount.c
+++ zfcpdump-kernel-4.4/fs/sysfs/mount.c
@@ -40,9 +40,6 @@ static struct dentry *sysfs_mount(struct
 				SYSFS_MAGIC, &new_sb, ns);
 	if (IS_ERR(root) || !new_sb)
 		kobj_ns_drop(KOBJ_NS_TYPE_NET, ns);
-	else if (new_sb)
-		/* Userspace would break if executables appear on sysfs */
-		root->d_sb->s_iflags |= SB_I_NOEXEC;
 
 	return root;
 }
--- zfcpdump-kernel-4.4.orig/fs/timerfd.c
+++ zfcpdump-kernel-4.4/fs/timerfd.c
@@ -153,7 +153,7 @@ static ktime_t timerfd_get_remaining(str
 	if (isalarm(ctx))
 		remaining = alarm_expires_remaining(&ctx->t.alarm);
 	else
-		remaining = hrtimer_expires_remaining(&ctx->t.tmr);
+		remaining = hrtimer_expires_remaining_adjusted(&ctx->t.tmr);
 
 	return remaining.tv64 < 0 ? ktime_set(0, 0): remaining;
 }
--- zfcpdump-kernel-4.4.orig/fs/ubifs/file.c
+++ zfcpdump-kernel-4.4/fs/ubifs/file.c
@@ -52,6 +52,7 @@
 #include "ubifs.h"
 #include <linux/mount.h>
 #include <linux/slab.h>
+#include <linux/migrate.h>
 
 static int read_block(struct inode *inode, void *addr, unsigned int block,
 		      struct ubifs_data_node *dn)
@@ -1452,6 +1453,26 @@ static int ubifs_set_page_dirty(struct p
 	return ret;
 }
 
+#ifdef CONFIG_MIGRATION
+static int ubifs_migrate_page(struct address_space *mapping,
+		struct page *newpage, struct page *page, enum migrate_mode mode)
+{
+	int rc;
+
+	rc = migrate_page_move_mapping(mapping, newpage, page, NULL, mode, 0);
+	if (rc != MIGRATEPAGE_SUCCESS)
+		return rc;
+
+	if (PagePrivate(page)) {
+		ClearPagePrivate(page);
+		SetPagePrivate(newpage);
+	}
+
+	migrate_page_copy(newpage, page);
+	return MIGRATEPAGE_SUCCESS;
+}
+#endif
+
 static int ubifs_releasepage(struct page *page, gfp_t unused_gfp_flags)
 {
 	/*
@@ -1591,6 +1612,9 @@ const struct address_space_operations ub
 	.write_end      = ubifs_write_end,
 	.invalidatepage = ubifs_invalidatepage,
 	.set_page_dirty = ubifs_set_page_dirty,
+#ifdef CONFIG_MIGRATION
+	.migratepage	= ubifs_migrate_page,
+#endif
 	.releasepage    = ubifs_releasepage,
 };
 
--- zfcpdump-kernel-4.4.orig/fs/ubifs/tnc_commit.c
+++ zfcpdump-kernel-4.4/fs/ubifs/tnc_commit.c
@@ -370,7 +370,7 @@ static int layout_in_gaps(struct ubifs_i
 
 	p = c->gap_lebs;
 	do {
-		ubifs_assert(p < c->gap_lebs + sizeof(int) * c->lst.idx_lebs);
+		ubifs_assert(p < c->gap_lebs + c->lst.idx_lebs);
 		written = layout_leb_in_gaps(c, p);
 		if (written < 0) {
 			err = written;
--- zfcpdump-kernel-4.4.orig/fs/udf/inode.c
+++ zfcpdump-kernel-4.4/fs/udf/inode.c
@@ -2047,14 +2047,29 @@ void udf_write_aext(struct inode *inode,
 		epos->offset += adsize;
 }
 
+/*
+ * Only 1 indirect extent in a row really makes sense but allow upto 16 in case
+ * someone does some weird stuff.
+ */
+#define UDF_MAX_INDIR_EXTS 16
+
 int8_t udf_next_aext(struct inode *inode, struct extent_position *epos,
 		     struct kernel_lb_addr *eloc, uint32_t *elen, int inc)
 {
 	int8_t etype;
+	unsigned int indirections = 0;
 
 	while ((etype = udf_current_aext(inode, epos, eloc, elen, inc)) ==
 	       (EXT_NEXT_EXTENT_ALLOCDECS >> 30)) {
 		int block;
+
+		if (++indirections > UDF_MAX_INDIR_EXTS) {
+			udf_err(inode->i_sb,
+				"too many indirect extents in inode %lu\n",
+				inode->i_ino);
+			return -1;
+		}
+
 		epos->block = *eloc;
 		epos->offset = sizeof(struct allocExtDesc);
 		brelse(epos->bh);
--- zfcpdump-kernel-4.4.orig/fs/udf/unicode.c
+++ zfcpdump-kernel-4.4/fs/udf/unicode.c
@@ -128,11 +128,15 @@ int udf_CS0toUTF8(struct ustr *utf_o, co
 		if (c < 0x80U)
 			utf_o->u_name[utf_o->u_len++] = (uint8_t)c;
 		else if (c < 0x800U) {
+			if (utf_o->u_len > (UDF_NAME_LEN - 4))
+				break;
 			utf_o->u_name[utf_o->u_len++] =
 						(uint8_t)(0xc0 | (c >> 6));
 			utf_o->u_name[utf_o->u_len++] =
 						(uint8_t)(0x80 | (c & 0x3f));
 		} else {
+			if (utf_o->u_len > (UDF_NAME_LEN - 5))
+				break;
 			utf_o->u_name[utf_o->u_len++] =
 						(uint8_t)(0xe0 | (c >> 12));
 			utf_o->u_name[utf_o->u_len++] =
@@ -173,17 +177,22 @@ int udf_CS0toUTF8(struct ustr *utf_o, co
 static int udf_UTF8toCS0(dstring *ocu, struct ustr *utf, int length)
 {
 	unsigned c, i, max_val, utf_char;
-	int utf_cnt, u_len;
+	int utf_cnt, u_len, u_ch;
 
 	memset(ocu, 0, sizeof(dstring) * length);
 	ocu[0] = 8;
 	max_val = 0xffU;
+	u_ch = 1;
 
 try_again:
 	u_len = 0U;
 	utf_char = 0U;
 	utf_cnt = 0U;
 	for (i = 0U; i < utf->u_len; i++) {
+		/* Name didn't fit? */
+		if (u_len + 1 + u_ch >= length)
+			return 0;
+
 		c = (uint8_t)utf->u_name[i];
 
 		/* Complete a multi-byte UTF-8 character */
@@ -225,6 +234,7 @@ try_again:
 			if (max_val == 0xffU) {
 				max_val = 0xffffU;
 				ocu[0] = (uint8_t)0x10U;
+				u_ch = 2;
 				goto try_again;
 			}
 			goto error_out;
@@ -277,7 +287,7 @@ static int udf_CS0toNLS(struct nls_table
 			c = (c << 8) | ocu[i++];
 
 		len = nls->uni2char(c, &utf_o->u_name[utf_o->u_len],
-				    UDF_NAME_LEN - utf_o->u_len);
+				    UDF_NAME_LEN - 2 - utf_o->u_len);
 		/* Valid character? */
 		if (len >= 0)
 			utf_o->u_len += len;
@@ -295,15 +305,19 @@ static int udf_NLStoCS0(struct nls_table
 	int len;
 	unsigned i, max_val;
 	uint16_t uni_char;
-	int u_len;
+	int u_len, u_ch;
 
 	memset(ocu, 0, sizeof(dstring) * length);
 	ocu[0] = 8;
 	max_val = 0xffU;
+	u_ch = 1;
 
 try_again:
 	u_len = 0U;
 	for (i = 0U; i < uni->u_len; i++) {
+		/* Name didn't fit? */
+		if (u_len + 1 + u_ch >= length)
+			return 0;
 		len = nls->char2uni(&uni->u_name[i], uni->u_len - i, &uni_char);
 		if (!len)
 			continue;
@@ -316,6 +330,7 @@ try_again:
 		if (uni_char > max_val) {
 			max_val = 0xffffU;
 			ocu[0] = (uint8_t)0x10U;
+			u_ch = 2;
 			goto try_again;
 		}
 
--- zfcpdump-kernel-4.4.orig/fs/userfaultfd.c
+++ zfcpdump-kernel-4.4/fs/userfaultfd.c
@@ -287,6 +287,12 @@ int handle_userfault(struct vm_area_stru
 		goto out;
 
 	/*
+	 * We don't do userfault handling for the final child pid update.
+	 */
+	if (current->flags & PF_EXITING)
+		goto out;
+
+	/*
 	 * Check that we can return VM_FAULT_RETRY.
 	 *
 	 * NOTE: it should become possible to return VM_FAULT_RETRY
--- zfcpdump-kernel-4.4.orig/fs/xattr.c
+++ zfcpdump-kernel-4.4/fs/xattr.c
@@ -207,6 +207,7 @@ vfs_getxattr_alloc(struct dentry *dentry
 	*xattr_value = value;
 	return error;
 }
+EXPORT_SYMBOL(vfs_getxattr_alloc);
 
 /* Compare an extended attribute value with the given value */
 int vfs_xattr_cmp(struct dentry *dentry, const char *xattr_name,
@@ -351,8 +352,12 @@ setxattr(struct dentry *d, const char __
 			goto out;
 		}
 		if ((strcmp(kname, XATTR_NAME_POSIX_ACL_ACCESS) == 0) ||
-		    (strcmp(kname, XATTR_NAME_POSIX_ACL_DEFAULT) == 0))
-			posix_acl_fix_xattr_from_user(kvalue, size);
+		    (strcmp(kname, XATTR_NAME_POSIX_ACL_DEFAULT) == 0)) {
+			error = posix_acl_fix_xattr_from_user(d->d_sb->s_user_ns,
+							      kvalue, size);
+			if (error)
+				goto out;
+		}
 	}
 
 	error = vfs_setxattr(d, kname, kvalue, size, flags);
@@ -452,9 +457,14 @@ getxattr(struct dentry *d, const char __
 	error = vfs_getxattr(d, kname, kvalue, size);
 	if (error > 0) {
 		if ((strcmp(kname, XATTR_NAME_POSIX_ACL_ACCESS) == 0) ||
-		    (strcmp(kname, XATTR_NAME_POSIX_ACL_DEFAULT) == 0))
-			posix_acl_fix_xattr_to_user(kvalue, size);
-		if (size && copy_to_user(value, kvalue, error))
+		    (strcmp(kname, XATTR_NAME_POSIX_ACL_DEFAULT) == 0)) {
+			int ret;
+			ret = posix_acl_fix_xattr_to_user(d->d_sb->s_user_ns,
+							  kvalue, size);
+			if (ret)
+				error = ret;
+		}
+		if (error > 0 && size && copy_to_user(value, kvalue, error))
 			error = -EFAULT;
 	} else if (error == -ERANGE && size >= XATTR_SIZE_MAX) {
 		/* The file system tried to returned a value bigger
--- zfcpdump-kernel-4.4.orig/fs/xfs/libxfs/xfs_alloc.c
+++ zfcpdump-kernel-4.4/fs/xfs/libxfs/xfs_alloc.c
@@ -535,6 +535,7 @@ xfs_agfl_write_verify(
 }
 
 const struct xfs_buf_ops xfs_agfl_buf_ops = {
+	.name = "xfs_agfl",
 	.verify_read = xfs_agfl_read_verify,
 	.verify_write = xfs_agfl_write_verify,
 };
@@ -2339,6 +2340,7 @@ xfs_agf_write_verify(
 }
 
 const struct xfs_buf_ops xfs_agf_buf_ops = {
+	.name = "xfs_agf",
 	.verify_read = xfs_agf_read_verify,
 	.verify_write = xfs_agf_write_verify,
 };
--- zfcpdump-kernel-4.4.orig/fs/xfs/libxfs/xfs_alloc_btree.c
+++ zfcpdump-kernel-4.4/fs/xfs/libxfs/xfs_alloc_btree.c
@@ -379,6 +379,7 @@ xfs_allocbt_write_verify(
 }
 
 const struct xfs_buf_ops xfs_allocbt_buf_ops = {
+	.name = "xfs_allocbt",
 	.verify_read = xfs_allocbt_read_verify,
 	.verify_write = xfs_allocbt_write_verify,
 };
--- zfcpdump-kernel-4.4.orig/fs/xfs/libxfs/xfs_attr_leaf.c
+++ zfcpdump-kernel-4.4/fs/xfs/libxfs/xfs_attr_leaf.c
@@ -328,6 +328,7 @@ xfs_attr3_leaf_read_verify(
 }
 
 const struct xfs_buf_ops xfs_attr3_leaf_buf_ops = {
+	.name = "xfs_attr3_leaf",
 	.verify_read = xfs_attr3_leaf_read_verify,
 	.verify_write = xfs_attr3_leaf_write_verify,
 };
--- zfcpdump-kernel-4.4.orig/fs/xfs/libxfs/xfs_attr_remote.c
+++ zfcpdump-kernel-4.4/fs/xfs/libxfs/xfs_attr_remote.c
@@ -201,6 +201,7 @@ xfs_attr3_rmt_write_verify(
 }
 
 const struct xfs_buf_ops xfs_attr3_rmt_buf_ops = {
+	.name = "xfs_attr3_rmt",
 	.verify_read = xfs_attr3_rmt_read_verify,
 	.verify_write = xfs_attr3_rmt_write_verify,
 };
--- zfcpdump-kernel-4.4.orig/fs/xfs/libxfs/xfs_bmap_btree.c
+++ zfcpdump-kernel-4.4/fs/xfs/libxfs/xfs_bmap_btree.c
@@ -720,6 +720,7 @@ xfs_bmbt_write_verify(
 }
 
 const struct xfs_buf_ops xfs_bmbt_buf_ops = {
+	.name = "xfs_bmbt",
 	.verify_read = xfs_bmbt_read_verify,
 	.verify_write = xfs_bmbt_write_verify,
 };
--- zfcpdump-kernel-4.4.orig/fs/xfs/libxfs/xfs_da_btree.c
+++ zfcpdump-kernel-4.4/fs/xfs/libxfs/xfs_da_btree.c
@@ -245,6 +245,7 @@ xfs_da3_node_read_verify(
 }
 
 const struct xfs_buf_ops xfs_da3_node_buf_ops = {
+	.name = "xfs_da3_node",
 	.verify_read = xfs_da3_node_read_verify,
 	.verify_write = xfs_da3_node_write_verify,
 };
--- zfcpdump-kernel-4.4.orig/fs/xfs/libxfs/xfs_dir2_block.c
+++ zfcpdump-kernel-4.4/fs/xfs/libxfs/xfs_dir2_block.c
@@ -123,6 +123,7 @@ xfs_dir3_block_write_verify(
 }
 
 const struct xfs_buf_ops xfs_dir3_block_buf_ops = {
+	.name = "xfs_dir3_block",
 	.verify_read = xfs_dir3_block_read_verify,
 	.verify_write = xfs_dir3_block_write_verify,
 };
--- zfcpdump-kernel-4.4.orig/fs/xfs/libxfs/xfs_dir2_data.c
+++ zfcpdump-kernel-4.4/fs/xfs/libxfs/xfs_dir2_data.c
@@ -305,11 +305,13 @@ xfs_dir3_data_write_verify(
 }
 
 const struct xfs_buf_ops xfs_dir3_data_buf_ops = {
+	.name = "xfs_dir3_data",
 	.verify_read = xfs_dir3_data_read_verify,
 	.verify_write = xfs_dir3_data_write_verify,
 };
 
 static const struct xfs_buf_ops xfs_dir3_data_reada_buf_ops = {
+	.name = "xfs_dir3_data_reada",
 	.verify_read = xfs_dir3_data_reada_verify,
 	.verify_write = xfs_dir3_data_write_verify,
 };
--- zfcpdump-kernel-4.4.orig/fs/xfs/libxfs/xfs_dir2_leaf.c
+++ zfcpdump-kernel-4.4/fs/xfs/libxfs/xfs_dir2_leaf.c
@@ -245,11 +245,13 @@ xfs_dir3_leafn_write_verify(
 }
 
 const struct xfs_buf_ops xfs_dir3_leaf1_buf_ops = {
+	.name = "xfs_dir3_leaf1",
 	.verify_read = xfs_dir3_leaf1_read_verify,
 	.verify_write = xfs_dir3_leaf1_write_verify,
 };
 
 const struct xfs_buf_ops xfs_dir3_leafn_buf_ops = {
+	.name = "xfs_dir3_leafn",
 	.verify_read = xfs_dir3_leafn_read_verify,
 	.verify_write = xfs_dir3_leafn_write_verify,
 };
--- zfcpdump-kernel-4.4.orig/fs/xfs/libxfs/xfs_dir2_node.c
+++ zfcpdump-kernel-4.4/fs/xfs/libxfs/xfs_dir2_node.c
@@ -150,6 +150,7 @@ xfs_dir3_free_write_verify(
 }
 
 const struct xfs_buf_ops xfs_dir3_free_buf_ops = {
+	.name = "xfs_dir3_free",
 	.verify_read = xfs_dir3_free_read_verify,
 	.verify_write = xfs_dir3_free_write_verify,
 };
--- zfcpdump-kernel-4.4.orig/fs/xfs/libxfs/xfs_dquot_buf.c
+++ zfcpdump-kernel-4.4/fs/xfs/libxfs/xfs_dquot_buf.c
@@ -54,7 +54,7 @@ xfs_dqcheck(
 	xfs_dqid_t	 id,
 	uint		 type,	  /* used only when IO_dorepair is true */
 	uint		 flags,
-	char		 *str)
+	const char	 *str)
 {
 	xfs_dqblk_t	 *d = (xfs_dqblk_t *)ddq;
 	int		errs = 0;
@@ -207,7 +207,8 @@ xfs_dquot_buf_verify_crc(
 STATIC bool
 xfs_dquot_buf_verify(
 	struct xfs_mount	*mp,
-	struct xfs_buf		*bp)
+	struct xfs_buf		*bp,
+	int			warn)
 {
 	struct xfs_dqblk	*d = (struct xfs_dqblk *)bp->b_addr;
 	xfs_dqid_t		id = 0;
@@ -240,8 +241,7 @@ xfs_dquot_buf_verify(
 		if (i == 0)
 			id = be32_to_cpu(ddq->d_id);
 
-		error = xfs_dqcheck(mp, ddq, id + i, 0, XFS_QMOPT_DOWARN,
-				       "xfs_dquot_buf_verify");
+		error = xfs_dqcheck(mp, ddq, id + i, 0, warn, __func__);
 		if (error)
 			return false;
 	}
@@ -256,7 +256,7 @@ xfs_dquot_buf_read_verify(
 
 	if (!xfs_dquot_buf_verify_crc(mp, bp))
 		xfs_buf_ioerror(bp, -EFSBADCRC);
-	else if (!xfs_dquot_buf_verify(mp, bp))
+	else if (!xfs_dquot_buf_verify(mp, bp, XFS_QMOPT_DOWARN))
 		xfs_buf_ioerror(bp, -EFSCORRUPTED);
 
 	if (bp->b_error)
@@ -264,6 +264,25 @@ xfs_dquot_buf_read_verify(
 }
 
 /*
+ * readahead errors are silent and simply leave the buffer as !done so a real
+ * read will then be run with the xfs_dquot_buf_ops verifier. See
+ * xfs_inode_buf_verify() for why we use EIO and ~XBF_DONE here rather than
+ * reporting the failure.
+ */
+static void
+xfs_dquot_buf_readahead_verify(
+	struct xfs_buf	*bp)
+{
+	struct xfs_mount	*mp = bp->b_target->bt_mount;
+
+	if (!xfs_dquot_buf_verify_crc(mp, bp) ||
+	    !xfs_dquot_buf_verify(mp, bp, 0)) {
+		xfs_buf_ioerror(bp, -EIO);
+		bp->b_flags &= ~XBF_DONE;
+	}
+}
+
+/*
  * we don't calculate the CRC here as that is done when the dquot is flushed to
  * the buffer after the update is done. This ensures that the dquot in the
  * buffer always has an up-to-date CRC value.
@@ -274,7 +293,7 @@ xfs_dquot_buf_write_verify(
 {
 	struct xfs_mount	*mp = bp->b_target->bt_mount;
 
-	if (!xfs_dquot_buf_verify(mp, bp)) {
+	if (!xfs_dquot_buf_verify(mp, bp, XFS_QMOPT_DOWARN)) {
 		xfs_buf_ioerror(bp, -EFSCORRUPTED);
 		xfs_verifier_error(bp);
 		return;
@@ -282,7 +301,13 @@ xfs_dquot_buf_write_verify(
 }
 
 const struct xfs_buf_ops xfs_dquot_buf_ops = {
+	.name = "xfs_dquot",
 	.verify_read = xfs_dquot_buf_read_verify,
 	.verify_write = xfs_dquot_buf_write_verify,
 };
 
+const struct xfs_buf_ops xfs_dquot_buf_ra_ops = {
+	.name = "xfs_dquot_ra",
+	.verify_read = xfs_dquot_buf_readahead_verify,
+	.verify_write = xfs_dquot_buf_write_verify,
+};
--- zfcpdump-kernel-4.4.orig/fs/xfs/libxfs/xfs_format.h
+++ zfcpdump-kernel-4.4/fs/xfs/libxfs/xfs_format.h
@@ -786,7 +786,7 @@ typedef struct xfs_agfl {
 	__be64		agfl_lsn;
 	__be32		agfl_crc;
 	__be32		agfl_bno[];	/* actually XFS_AGFL_SIZE(mp) */
-} xfs_agfl_t;
+} __attribute__((packed)) xfs_agfl_t;
 
 #define XFS_AGFL_CRC_OFF	offsetof(struct xfs_agfl, agfl_crc)
 
--- zfcpdump-kernel-4.4.orig/fs/xfs/libxfs/xfs_ialloc.c
+++ zfcpdump-kernel-4.4/fs/xfs/libxfs/xfs_ialloc.c
@@ -2572,6 +2572,7 @@ xfs_agi_write_verify(
 }
 
 const struct xfs_buf_ops xfs_agi_buf_ops = {
+	.name = "xfs_agi",
 	.verify_read = xfs_agi_read_verify,
 	.verify_write = xfs_agi_write_verify,
 };
--- zfcpdump-kernel-4.4.orig/fs/xfs/libxfs/xfs_ialloc_btree.c
+++ zfcpdump-kernel-4.4/fs/xfs/libxfs/xfs_ialloc_btree.c
@@ -304,6 +304,7 @@ xfs_inobt_write_verify(
 }
 
 const struct xfs_buf_ops xfs_inobt_buf_ops = {
+	.name = "xfs_inobt",
 	.verify_read = xfs_inobt_read_verify,
 	.verify_write = xfs_inobt_write_verify,
 };
--- zfcpdump-kernel-4.4.orig/fs/xfs/libxfs/xfs_inode_buf.c
+++ zfcpdump-kernel-4.4/fs/xfs/libxfs/xfs_inode_buf.c
@@ -62,11 +62,14 @@ xfs_inobp_check(
  * has not had the inode cores stamped into it. Hence for readahead, the buffer
  * may be potentially invalid.
  *
- * If the readahead buffer is invalid, we don't want to mark it with an error,
- * but we do want to clear the DONE status of the buffer so that a followup read
- * will re-read it from disk. This will ensure that we don't get an unnecessary
- * warnings during log recovery and we don't get unnecssary panics on debug
- * kernels.
+ * If the readahead buffer is invalid, we need to mark it with an error and
+ * clear the DONE status of the buffer so that a followup read will re-read it
+ * from disk. We don't report the error otherwise to avoid warnings during log
+ * recovery and we don't get unnecssary panics on debug kernels. We use EIO here
+ * because all we want to do is say readahead failed; there is no-one to report
+ * the error to, so this will distinguish it from a non-ra verifier failure.
+ * Changes to this readahead error behavour also need to be reflected in
+ * xfs_dquot_buf_readahead_verify().
  */
 static void
 xfs_inode_buf_verify(
@@ -93,6 +96,7 @@ xfs_inode_buf_verify(
 						XFS_RANDOM_ITOBP_INOTOBP))) {
 			if (readahead) {
 				bp->b_flags &= ~XBF_DONE;
+				xfs_buf_ioerror(bp, -EIO);
 				return;
 			}
 
@@ -132,11 +136,13 @@ xfs_inode_buf_write_verify(
 }
 
 const struct xfs_buf_ops xfs_inode_buf_ops = {
+	.name = "xfs_inode",
 	.verify_read = xfs_inode_buf_read_verify,
 	.verify_write = xfs_inode_buf_write_verify,
 };
 
 const struct xfs_buf_ops xfs_inode_buf_ra_ops = {
+	.name = "xxfs_inode_ra",
 	.verify_read = xfs_inode_buf_readahead_verify,
 	.verify_write = xfs_inode_buf_write_verify,
 };
--- zfcpdump-kernel-4.4.orig/fs/xfs/libxfs/xfs_quota_defs.h
+++ zfcpdump-kernel-4.4/fs/xfs/libxfs/xfs_quota_defs.h
@@ -153,7 +153,7 @@ typedef __uint16_t	xfs_qwarncnt_t;
 #define XFS_QMOPT_RESBLK_MASK	(XFS_QMOPT_RES_REGBLKS | XFS_QMOPT_RES_RTBLKS)
 
 extern int xfs_dqcheck(struct xfs_mount *mp, xfs_disk_dquot_t *ddq,
-		       xfs_dqid_t id, uint type, uint flags, char *str);
+		       xfs_dqid_t id, uint type, uint flags, const char *str);
 extern int xfs_calc_dquots_per_chunk(unsigned int nbblks);
 
 #endif	/* __XFS_QUOTA_H__ */
--- zfcpdump-kernel-4.4.orig/fs/xfs/libxfs/xfs_sb.c
+++ zfcpdump-kernel-4.4/fs/xfs/libxfs/xfs_sb.c
@@ -581,7 +581,8 @@ xfs_sb_verify(
 	 * Only check the in progress field for the primary superblock as
 	 * mkfs.xfs doesn't clear it from secondary superblocks.
 	 */
-	return xfs_mount_validate_sb(mp, &sb, bp->b_bn == XFS_SB_DADDR,
+	return xfs_mount_validate_sb(mp, &sb,
+				     bp->b_maps[0].bm_bn == XFS_SB_DADDR,
 				     check_version);
 }
 
@@ -679,11 +680,13 @@ xfs_sb_write_verify(
 }
 
 const struct xfs_buf_ops xfs_sb_buf_ops = {
+	.name = "xfs_sb",
 	.verify_read = xfs_sb_read_verify,
 	.verify_write = xfs_sb_write_verify,
 };
 
 const struct xfs_buf_ops xfs_sb_quiet_buf_ops = {
+	.name = "xfs_sb_quiet",
 	.verify_read = xfs_sb_quiet_read_verify,
 	.verify_write = xfs_sb_write_verify,
 };
--- zfcpdump-kernel-4.4.orig/fs/xfs/libxfs/xfs_shared.h
+++ zfcpdump-kernel-4.4/fs/xfs/libxfs/xfs_shared.h
@@ -49,6 +49,7 @@ extern const struct xfs_buf_ops xfs_inob
 extern const struct xfs_buf_ops xfs_inode_buf_ops;
 extern const struct xfs_buf_ops xfs_inode_buf_ra_ops;
 extern const struct xfs_buf_ops xfs_dquot_buf_ops;
+extern const struct xfs_buf_ops xfs_dquot_buf_ra_ops;
 extern const struct xfs_buf_ops xfs_sb_buf_ops;
 extern const struct xfs_buf_ops xfs_sb_quiet_buf_ops;
 extern const struct xfs_buf_ops xfs_symlink_buf_ops;
--- zfcpdump-kernel-4.4.orig/fs/xfs/libxfs/xfs_symlink_remote.c
+++ zfcpdump-kernel-4.4/fs/xfs/libxfs/xfs_symlink_remote.c
@@ -168,6 +168,7 @@ xfs_symlink_write_verify(
 }
 
 const struct xfs_buf_ops xfs_symlink_buf_ops = {
+	.name = "xfs_symlink",
 	.verify_read = xfs_symlink_read_verify,
 	.verify_write = xfs_symlink_write_verify,
 };
--- zfcpdump-kernel-4.4.orig/fs/xfs/xfs_attr_list.c
+++ zfcpdump-kernel-4.4/fs/xfs/xfs_attr_list.c
@@ -202,8 +202,10 @@ xfs_attr_shortform_list(xfs_attr_list_co
 					sbp->namelen,
 					sbp->valuelen,
 					&sbp->name[sbp->namelen]);
-		if (error)
+		if (error) {
+			kmem_free(sbuf);
 			return error;
+		}
 		if (context->seen_enough)
 			break;
 		cursor->offset++;
@@ -454,14 +456,13 @@ xfs_attr3_leaf_list_int(
 				args.rmtblkcnt = xfs_attr3_rmt_blocks(
 							args.dp->i_mount, valuelen);
 				retval = xfs_attr_rmtval_get(&args);
-				if (retval)
-					return retval;
-				retval = context->put_listent(context,
-						entry->flags,
-						name_rmt->name,
-						(int)name_rmt->namelen,
-						valuelen,
-						args.value);
+				if (!retval)
+					retval = context->put_listent(context,
+							entry->flags,
+							name_rmt->name,
+							(int)name_rmt->namelen,
+							valuelen,
+							args.value);
 				kmem_free(args.value);
 			} else {
 				retval = context->put_listent(context,
--- zfcpdump-kernel-4.4.orig/fs/xfs/xfs_buf.c
+++ zfcpdump-kernel-4.4/fs/xfs/xfs_buf.c
@@ -604,6 +604,13 @@ found:
 		}
 	}
 
+	/*
+	 * Clear b_error if this is a lookup from a caller that doesn't expect
+	 * valid data to be found in the buffer.
+	 */
+	if (!(flags & XBF_READ))
+		xfs_buf_ioerror(bp, 0);
+
 	XFS_STATS_INC(target->bt_mount, xb_get);
 	trace_xfs_buf_get(bp, flags, _RET_IP_);
 	return bp;
@@ -1520,6 +1527,16 @@ xfs_wait_buftarg(
 	LIST_HEAD(dispose);
 	int loop = 0;
 
+	/*
+	 * We need to flush the buffer workqueue to ensure that all IO
+	 * completion processing is 100% done. Just waiting on buffer locks is
+	 * not sufficient for async IO as the reference count held over IO is
+	 * not released until after the buffer lock is dropped. Hence we need to
+	 * ensure here that all reference counts have been dropped before we
+	 * start walking the LRU list.
+	 */
+	flush_workqueue(btp->bt_mount->m_buf_workqueue);
+
 	/* loop until there is nothing left on the lru list. */
 	while (list_lru_count(&btp->bt_lru)) {
 		list_lru_walk(&btp->bt_lru, xfs_buftarg_wait_rele,
--- zfcpdump-kernel-4.4.orig/fs/xfs/xfs_buf.h
+++ zfcpdump-kernel-4.4/fs/xfs/xfs_buf.h
@@ -132,6 +132,7 @@ struct xfs_buf_map {
 	struct xfs_buf_map (map) = { .bm_bn = (blkno), .bm_len = (numblk) };
 
 struct xfs_buf_ops {
+	char *name;
 	void (*verify_read)(struct xfs_buf *);
 	void (*verify_write)(struct xfs_buf *);
 };
--- zfcpdump-kernel-4.4.orig/fs/xfs/xfs_error.c
+++ zfcpdump-kernel-4.4/fs/xfs/xfs_error.c
@@ -164,9 +164,9 @@ xfs_verifier_error(
 {
 	struct xfs_mount *mp = bp->b_target->bt_mount;
 
-	xfs_alert(mp, "Metadata %s detected at %pF, block 0x%llx",
+	xfs_alert(mp, "Metadata %s detected at %pF, %s block 0x%llx",
 		  bp->b_error == -EFSBADCRC ? "CRC error" : "corruption",
-		  __return_address, bp->b_bn);
+		  __return_address, bp->b_ops->name, bp->b_bn);
 
 	xfs_alert(mp, "Unmount and run xfs_repair");
 
--- zfcpdump-kernel-4.4.orig/fs/xfs/xfs_fsops.c
+++ zfcpdump-kernel-4.4/fs/xfs/xfs_fsops.c
@@ -243,8 +243,8 @@ xfs_growfs_data_private(
 		agf->agf_roots[XFS_BTNUM_CNTi] = cpu_to_be32(XFS_CNT_BLOCK(mp));
 		agf->agf_levels[XFS_BTNUM_BNOi] = cpu_to_be32(1);
 		agf->agf_levels[XFS_BTNUM_CNTi] = cpu_to_be32(1);
-		agf->agf_flfirst = 0;
-		agf->agf_fllast = cpu_to_be32(XFS_AGFL_SIZE(mp) - 1);
+		agf->agf_flfirst = cpu_to_be32(1);
+		agf->agf_fllast = 0;
 		agf->agf_flcount = 0;
 		tmpsize = agsize - XFS_PREALLOC_BLOCKS(mp);
 		agf->agf_freeblks = cpu_to_be32(tmpsize);
--- zfcpdump-kernel-4.4.orig/fs/xfs/xfs_inode.c
+++ zfcpdump-kernel-4.4/fs/xfs/xfs_inode.c
@@ -3220,13 +3220,14 @@ xfs_iflush_cluster(
 		 * We need to check under the i_flags_lock for a valid inode
 		 * here. Skip it if it is not valid or the wrong inode.
 		 */
-		spin_lock(&ip->i_flags_lock);
-		if (!ip->i_ino ||
+		spin_lock(&iq->i_flags_lock);
+		if (!iq->i_ino ||
+		    __xfs_iflags_test(iq, XFS_ISTALE) ||
 		    (XFS_INO_TO_AGINO(mp, iq->i_ino) & mask) != first_index) {
-			spin_unlock(&ip->i_flags_lock);
+			spin_unlock(&iq->i_flags_lock);
 			continue;
 		}
-		spin_unlock(&ip->i_flags_lock);
+		spin_unlock(&iq->i_flags_lock);
 
 		/*
 		 * Do an un-protected check to see if the inode is dirty and
@@ -3342,7 +3343,7 @@ xfs_iflush(
 	struct xfs_buf		**bpp)
 {
 	struct xfs_mount	*mp = ip->i_mount;
-	struct xfs_buf		*bp;
+	struct xfs_buf		*bp = NULL;
 	struct xfs_dinode	*dip;
 	int			error;
 
@@ -3384,14 +3385,22 @@ xfs_iflush(
 	}
 
 	/*
-	 * Get the buffer containing the on-disk inode.
+	 * Get the buffer containing the on-disk inode. We are doing a try-lock
+	 * operation here, so we may get  an EAGAIN error. In that case, we
+	 * simply want to return with the inode still dirty.
+	 *
+	 * If we get any other error, we effectively have a corruption situation
+	 * and we cannot flush the inode, so we treat it the same as failing
+	 * xfs_iflush_int().
 	 */
 	error = xfs_imap_to_bp(mp, NULL, &ip->i_imap, &dip, &bp, XBF_TRYLOCK,
 			       0);
-	if (error || !bp) {
+	if (error == -EAGAIN) {
 		xfs_ifunlock(ip);
 		return error;
 	}
+	if (error)
+		goto corrupt_out;
 
 	/*
 	 * First flush out the inode that xfs_iflush was called with.
@@ -3419,7 +3428,8 @@ xfs_iflush(
 	return 0;
 
 corrupt_out:
-	xfs_buf_relse(bp);
+	if (bp)
+		xfs_buf_relse(bp);
 	xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE);
 cluster_corrupt_out:
 	error = -EFSCORRUPTED;
--- zfcpdump-kernel-4.4.orig/fs/xfs/xfs_log_recover.c
+++ zfcpdump-kernel-4.4/fs/xfs/xfs_log_recover.c
@@ -3204,6 +3204,7 @@ xlog_recover_dquot_ra_pass2(
 	struct xfs_disk_dquot	*recddq;
 	struct xfs_dq_logformat	*dq_f;
 	uint			type;
+	int			len;
 
 
 	if (mp->m_qflags == 0)
@@ -3224,8 +3225,12 @@ xlog_recover_dquot_ra_pass2(
 	ASSERT(dq_f);
 	ASSERT(dq_f->qlf_len == 1);
 
-	xfs_buf_readahead(mp->m_ddev_targp, dq_f->qlf_blkno,
-			  XFS_FSB_TO_BB(mp, dq_f->qlf_len), NULL);
+	len = XFS_FSB_TO_BB(mp, dq_f->qlf_len);
+	if (xlog_peek_buffer_cancelled(log, dq_f->qlf_blkno, len, 0))
+		return;
+
+	xfs_buf_readahead(mp->m_ddev_targp, dq_f->qlf_blkno, len,
+			  &xfs_dquot_buf_ra_ops);
 }
 
 STATIC void
--- zfcpdump-kernel-4.4.orig/fs/xfs/xfs_super.c
+++ zfcpdump-kernel-4.4/fs/xfs/xfs_super.c
@@ -1233,6 +1233,16 @@ xfs_fs_remount(
 			return -EINVAL;
 		}
 
+		if (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_5 &&
+		    xfs_sb_has_ro_compat_feature(sbp,
+					XFS_SB_FEAT_RO_COMPAT_UNKNOWN)) {
+			xfs_warn(mp,
+"ro->rw transition prohibited on unknown (0x%x) ro-compat filesystem",
+				(sbp->sb_features_ro_compat &
+					XFS_SB_FEAT_RO_COMPAT_UNKNOWN));
+			return -EINVAL;
+		}
+
 		mp->m_flags &= ~XFS_MOUNT_RDONLY;
 
 		/*
--- zfcpdump-kernel-4.4.orig/fs/xfs/xfs_trans_ail.c
+++ zfcpdump-kernel-4.4/fs/xfs/xfs_trans_ail.c
@@ -497,7 +497,6 @@ xfsaild(
 	long		tout = 0;	/* milliseconds */
 
 	current->flags |= PF_MEMALLOC;
-	set_freezable();
 
 	while (!kthread_should_stop()) {
 		if (tout && tout <= 20)
--- zfcpdump-kernel-4.4.orig/include/asm-generic/barrier.h
+++ zfcpdump-kernel-4.4/include/asm-generic/barrier.h
@@ -54,22 +54,38 @@
 #define read_barrier_depends()		do { } while (0)
 #endif
 
+#ifndef __smp_mb
+#define __smp_mb()	mb()
+#endif
+
+#ifndef __smp_rmb
+#define __smp_rmb()	rmb()
+#endif
+
+#ifndef __smp_wmb
+#define __smp_wmb()	wmb()
+#endif
+
+#ifndef __smp_read_barrier_depends
+#define __smp_read_barrier_depends()	read_barrier_depends()
+#endif
+
 #ifdef CONFIG_SMP
 
 #ifndef smp_mb
-#define smp_mb()	mb()
+#define smp_mb()	__smp_mb()
 #endif
 
 #ifndef smp_rmb
-#define smp_rmb()	rmb()
+#define smp_rmb()	__smp_rmb()
 #endif
 
 #ifndef smp_wmb
-#define smp_wmb()	wmb()
+#define smp_wmb()	__smp_wmb()
 #endif
 
 #ifndef smp_read_barrier_depends
-#define smp_read_barrier_depends()	read_barrier_depends()
+#define smp_read_barrier_depends()	__smp_read_barrier_depends()
 #endif
 
 #else	/* !CONFIG_SMP */
@@ -92,32 +108,104 @@
 
 #endif	/* CONFIG_SMP */
 
+#ifndef __smp_store_mb
+#define __smp_store_mb(var, value)  do { WRITE_ONCE(var, value); __smp_mb(); } while (0)
+#endif
+
+#ifndef __smp_mb__before_atomic
+#define __smp_mb__before_atomic()	__smp_mb()
+#endif
+
+#ifndef __smp_mb__after_atomic
+#define __smp_mb__after_atomic()	__smp_mb()
+#endif
+
+#ifndef __smp_store_release
+#define __smp_store_release(p, v)					\
+do {									\
+	compiletime_assert_atomic_type(*p);				\
+	__smp_mb();							\
+	WRITE_ONCE(*p, v);						\
+} while (0)
+#endif
+
+#ifndef __smp_load_acquire
+#define __smp_load_acquire(p)						\
+({									\
+	typeof(*p) ___p1 = READ_ONCE(*p);				\
+	compiletime_assert_atomic_type(*p);				\
+	__smp_mb();							\
+	___p1;								\
+})
+#endif
+
+#ifdef CONFIG_SMP
+
+#ifndef smp_store_mb
+#define smp_store_mb(var, value)  __smp_store_mb(var, value)
+#endif
+
+#ifndef smp_mb__before_atomic
+#define smp_mb__before_atomic()	__smp_mb__before_atomic()
+#endif
+
+#ifndef smp_mb__after_atomic
+#define smp_mb__after_atomic()	__smp_mb__after_atomic()
+#endif
+
+#ifndef smp_store_release
+#define smp_store_release(p, v) __smp_store_release(p, v)
+#endif
+
+#ifndef smp_load_acquire
+#define smp_load_acquire(p) __smp_load_acquire(p)
+#endif
+
+#else	/* !CONFIG_SMP */
+
 #ifndef smp_store_mb
-#define smp_store_mb(var, value)  do { WRITE_ONCE(var, value); mb(); } while (0)
+#define smp_store_mb(var, value)  do { WRITE_ONCE(var, value); barrier(); } while (0)
 #endif
 
 #ifndef smp_mb__before_atomic
-#define smp_mb__before_atomic()	smp_mb()
+#define smp_mb__before_atomic()	barrier()
 #endif
 
 #ifndef smp_mb__after_atomic
-#define smp_mb__after_atomic()	smp_mb()
+#define smp_mb__after_atomic()	barrier()
 #endif
 
+#ifndef smp_store_release
 #define smp_store_release(p, v)						\
 do {									\
 	compiletime_assert_atomic_type(*p);				\
-	smp_mb();							\
+	barrier();							\
 	WRITE_ONCE(*p, v);						\
 } while (0)
+#endif
 
+#ifndef smp_load_acquire
 #define smp_load_acquire(p)						\
 ({									\
 	typeof(*p) ___p1 = READ_ONCE(*p);				\
 	compiletime_assert_atomic_type(*p);				\
-	smp_mb();							\
+	barrier();							\
 	___p1;								\
 })
+#endif
+
+#endif
+
+/* Barriers for virtual machine guests when talking to an SMP host */
+#define virt_mb() __smp_mb()
+#define virt_rmb() __smp_rmb()
+#define virt_wmb() __smp_wmb()
+#define virt_read_barrier_depends() __smp_read_barrier_depends()
+#define virt_store_mb(var, value) __smp_store_mb(var, value)
+#define virt_mb__before_atomic() __smp_mb__before_atomic()
+#define virt_mb__after_atomic()	__smp_mb__after_atomic()
+#define virt_store_release(p, v) __smp_store_release(p, v)
+#define virt_load_acquire(p) __smp_load_acquire(p)
 
 #endif /* !__ASSEMBLY__ */
 #endif /* __ASM_GENERIC_BARRIER_H */
--- zfcpdump-kernel-4.4.orig/include/asm-generic/bitops/lock.h
+++ zfcpdump-kernel-4.4/include/asm-generic/bitops/lock.h
@@ -29,16 +29,16 @@ do {					\
  * @nr: the bit to set
  * @addr: the address to start counting from
  *
- * This operation is like clear_bit_unlock, however it is not atomic.
- * It does provide release barrier semantics so it can be used to unlock
- * a bit lock, however it would only be used if no other CPU can modify
- * any bits in the memory until the lock is released (a good example is
- * if the bit lock itself protects access to the other bits in the word).
+ * A weaker form of clear_bit_unlock() as used by __bit_lock_unlock(). If all
+ * the bits in the word are protected by this lock some archs can use weaker
+ * ops to safely unlock.
+ *
+ * See for example x86's implementation.
  */
 #define __clear_bit_unlock(nr, addr)	\
 do {					\
-	smp_mb();			\
-	__clear_bit(nr, addr);		\
+	smp_mb__before_atomic();	\
+	clear_bit(nr, addr);		\
 } while (0)
 
 #endif /* _ASM_GENERIC_BITOPS_LOCK_H_ */
--- zfcpdump-kernel-4.4.orig/include/asm-generic/cputime_nsecs.h
+++ zfcpdump-kernel-4.4/include/asm-generic/cputime_nsecs.h
@@ -75,7 +75,7 @@ typedef u64 __nocast cputime64_t;
  */
 static inline cputime_t timespec_to_cputime(const struct timespec *val)
 {
-	u64 ret = val->tv_sec * NSEC_PER_SEC + val->tv_nsec;
+	u64 ret = (u64)val->tv_sec * NSEC_PER_SEC + val->tv_nsec;
 	return (__force cputime_t) ret;
 }
 static inline void cputime_to_timespec(const cputime_t ct, struct timespec *val)
@@ -91,7 +91,8 @@ static inline void cputime_to_timespec(c
  */
 static inline cputime_t timeval_to_cputime(const struct timeval *val)
 {
-	u64 ret = val->tv_sec * NSEC_PER_SEC + val->tv_usec * NSEC_PER_USEC;
+	u64 ret = (u64)val->tv_sec * NSEC_PER_SEC +
+			val->tv_usec * NSEC_PER_USEC;
 	return (__force cputime_t) ret;
 }
 static inline void cputime_to_timeval(const cputime_t ct, struct timeval *val)
--- zfcpdump-kernel-4.4.orig/include/asm-generic/futex.h
+++ zfcpdump-kernel-4.4/include/asm-generic/futex.h
@@ -108,11 +108,15 @@ futex_atomic_cmpxchg_inatomic(u32 *uval,
 	u32 val;
 
 	preempt_disable();
-	if (unlikely(get_user(val, uaddr) != 0))
+	if (unlikely(get_user(val, uaddr) != 0)) {
+		preempt_enable();
 		return -EFAULT;
+	}
 
-	if (val == oldval && unlikely(put_user(newval, uaddr) != 0))
+	if (val == oldval && unlikely(put_user(newval, uaddr) != 0)) {
+		preempt_enable();
 		return -EFAULT;
+	}
 
 	*uval = val;
 	preempt_enable();
--- zfcpdump-kernel-4.4.orig/include/asm-generic/qspinlock.h
+++ zfcpdump-kernel-4.4/include/asm-generic/qspinlock.h
@@ -21,14 +21,33 @@
 #include <asm-generic/qspinlock_types.h>
 
 /**
+ * queued_spin_unlock_wait - wait until the _current_ lock holder releases the lock
+ * @lock : Pointer to queued spinlock structure
+ *
+ * There is a very slight possibility of live-lock if the lockers keep coming
+ * and the waiter is just unfortunate enough to not see any unlock state.
+ */
+#ifndef queued_spin_unlock_wait
+extern void queued_spin_unlock_wait(struct qspinlock *lock);
+#endif
+
+/**
  * queued_spin_is_locked - is the spinlock locked?
  * @lock: Pointer to queued spinlock structure
  * Return: 1 if it is locked, 0 otherwise
  */
+#ifndef queued_spin_is_locked
 static __always_inline int queued_spin_is_locked(struct qspinlock *lock)
 {
+	/*
+	 * See queued_spin_unlock_wait().
+	 *
+	 * Any !0 state indicates it is locked, even if _Q_LOCKED_VAL
+	 * isn't immediately observable.
+	 */
 	return atomic_read(&lock->val);
 }
+#endif
 
 /**
  * queued_spin_value_unlocked - is the spinlock structure unlocked?
@@ -98,19 +117,6 @@ static __always_inline void queued_spin_
 }
 #endif
 
-/**
- * queued_spin_unlock_wait - wait until current lock holder releases the lock
- * @lock : Pointer to queued spinlock structure
- *
- * There is a very slight possibility of live-lock if the lockers keep coming
- * and the waiter is just unfortunate enough to not see any unlock state.
- */
-static inline void queued_spin_unlock_wait(struct qspinlock *lock)
-{
-	while (atomic_read(&lock->val) & _Q_LOCKED_MASK)
-		cpu_relax();
-}
-
 #ifndef virt_spin_lock
 static __always_inline bool virt_spin_lock(struct qspinlock *lock)
 {
@@ -119,11 +125,6 @@ static __always_inline bool virt_spin_lo
 #endif
 
 /*
- * Initializier
- */
-#define	__ARCH_SPIN_LOCK_UNLOCKED	{ ATOMIC_INIT(0) }
-
-/*
  * Remapping spinlock architecture specific functions to the corresponding
  * queued spinlock functions.
  */
--- zfcpdump-kernel-4.4.orig/include/asm-generic/qspinlock_types.h
+++ zfcpdump-kernel-4.4/include/asm-generic/qspinlock_types.h
@@ -33,6 +33,11 @@ typedef struct qspinlock {
 } arch_spinlock_t;
 
 /*
+ * Initializier
+ */
+#define	__ARCH_SPIN_LOCK_UNLOCKED	{ ATOMIC_INIT(0) }
+
+/*
  * Bitfields in the atomic value:
  *
  * When NR_CPUS < 16K
--- zfcpdump-kernel-4.4.orig/include/asm-generic/siginfo.h
+++ zfcpdump-kernel-4.4/include/asm-generic/siginfo.h
@@ -17,21 +17,6 @@
 struct siginfo;
 void do_schedule_next_timer(struct siginfo *info);
 
-#ifndef HAVE_ARCH_COPY_SIGINFO
-
-#include <linux/string.h>
-
-static inline void copy_siginfo(struct siginfo *to, struct siginfo *from)
-{
-	if (from->si_code < 0)
-		memcpy(to, from, sizeof(*to));
-	else
-		/* _sigchld is currently the largest know union member */
-		memcpy(to, from, __ARCH_SI_PREAMBLE_SIZE + sizeof(from->_sifields._sigchld));
-}
-
-#endif
-
 extern int copy_siginfo_to_user(struct siginfo __user *to, const struct siginfo *from);
 
 #endif
--- zfcpdump-kernel-4.4.orig/include/asm-generic/uaccess.h
+++ zfcpdump-kernel-4.4/include/asm-generic/uaccess.h
@@ -230,14 +230,18 @@ extern int __put_user_bad(void) __attrib
 	might_fault();						\
 	access_ok(VERIFY_READ, __p, sizeof(*ptr)) ?		\
 		__get_user((x), (__typeof__(*(ptr)) *)__p) :	\
-		-EFAULT;					\
+		((x) = (__typeof__(*(ptr)))0,-EFAULT);		\
 })
 
 #ifndef __get_user_fn
 static inline int __get_user_fn(size_t size, const void __user *ptr, void *x)
 {
-	size = __copy_from_user(x, ptr, size);
-	return size ? -EFAULT : size;
+	size_t n = __copy_from_user(x, ptr, size);
+	if (unlikely(n)) {
+		memset(x + (size - n), 0, n);
+		return -EFAULT;
+	}
+	return 0;
 }
 
 #define __get_user_fn(sz, u, k)	__get_user_fn(sz, u, k)
@@ -257,11 +261,13 @@ extern int __get_user_bad(void) __attrib
 static inline long copy_from_user(void *to,
 		const void __user * from, unsigned long n)
 {
+	unsigned long res = n;
 	might_fault();
-	if (access_ok(VERIFY_READ, from, n))
-		return __copy_from_user(to, from, n);
-	else
-		return n;
+	if (likely(access_ok(VERIFY_READ, from, n)))
+		res = __copy_from_user(to, from, n);
+	if (unlikely(res))
+		memset(to + (n - res), 0, res);
+	return res;
 }
 
 static inline long copy_to_user(void __user *to,
--- zfcpdump-kernel-4.4.orig/include/asm-generic/vmlinux.lds.h
+++ zfcpdump-kernel-4.4/include/asm-generic/vmlinux.lds.h
@@ -531,15 +531,19 @@
 
 #define INIT_TEXT							\
 	*(.init.text)							\
+	*(.text.startup)						\
 	MEM_DISCARD(init.text)
 
 #define EXIT_DATA							\
 	*(.exit.data)							\
+	*(.fini_array)							\
+	*(.dtors)							\
 	MEM_DISCARD(exit.data)						\
 	MEM_DISCARD(exit.rodata)
 
 #define EXIT_TEXT							\
 	*(.exit.text)							\
+	*(.text.exit)							\
 	MEM_DISCARD(exit.text)
 
 #define EXIT_CALL							\
--- /dev/null
+++ zfcpdump-kernel-4.4/include/crypto/ghash.h
@@ -0,0 +1,23 @@
+/*
+ * Common values for GHASH algorithms
+ */
+
+#ifndef __CRYPTO_GHASH_H__
+#define __CRYPTO_GHASH_H__
+
+#include <linux/types.h>
+#include <crypto/gf128mul.h>
+
+#define GHASH_BLOCK_SIZE	16
+#define GHASH_DIGEST_SIZE	16
+
+struct ghash_ctx {
+	struct gf128mul_4k *gf128;
+};
+
+struct ghash_desc_ctx {
+	u8 buffer[GHASH_BLOCK_SIZE];
+	u32 bytes;
+};
+
+#endif
--- zfcpdump-kernel-4.4.orig/include/crypto/hash.h
+++ zfcpdump-kernel-4.4/include/crypto/hash.h
@@ -204,6 +204,7 @@ struct crypto_ahash {
 		      unsigned int keylen);
 
 	unsigned int reqsize;
+	bool has_setkey;
 	struct crypto_tfm base;
 };
 
@@ -375,6 +376,11 @@ static inline void *ahash_request_ctx(st
 int crypto_ahash_setkey(struct crypto_ahash *tfm, const u8 *key,
 			unsigned int keylen);
 
+static inline bool crypto_ahash_has_setkey(struct crypto_ahash *tfm)
+{
+	return tfm->has_setkey;
+}
+
 /**
  * crypto_ahash_finup() - update and finalize message digest
  * @req: reference to the ahash_request handle that holds all information
--- zfcpdump-kernel-4.4.orig/include/crypto/hash_info.h
+++ zfcpdump-kernel-4.4/include/crypto/hash_info.h
@@ -34,6 +34,9 @@
 #define TGR160_DIGEST_SIZE 20
 #define TGR192_DIGEST_SIZE 24
 
+/* not defined in include/crypto/ */
+#define SM3256_DIGEST_SIZE 32
+
 extern const char *const hash_algo_name[HASH_ALGO__LAST];
 extern const int hash_digest_size[HASH_ALGO__LAST];
 
--- zfcpdump-kernel-4.4.orig/include/crypto/if_alg.h
+++ zfcpdump-kernel-4.4/include/crypto/if_alg.h
@@ -30,6 +30,9 @@ struct alg_sock {
 
 	struct sock *parent;
 
+	unsigned int refcnt;
+	unsigned int nokey_refcnt;
+
 	const struct af_alg_type *type;
 	void *private;
 };
@@ -50,9 +53,11 @@ struct af_alg_type {
 	void (*release)(void *private);
 	int (*setkey)(void *private, const u8 *key, unsigned int keylen);
 	int (*accept)(void *private, struct sock *sk);
+	int (*accept_nokey)(void *private, struct sock *sk);
 	int (*setauthsize)(void *private, unsigned int authsize);
 
 	struct proto_ops *ops;
+	struct proto_ops *ops_nokey;
 	struct module *owner;
 	char name[14];
 };
@@ -67,6 +72,7 @@ int af_alg_register_type(const struct af
 int af_alg_unregister_type(const struct af_alg_type *type);
 
 int af_alg_release(struct socket *sock);
+void af_alg_release_parent(struct sock *sk);
 int af_alg_accept(struct sock *sk, struct socket *newsock);
 
 int af_alg_make_sg(struct af_alg_sgl *sgl, struct iov_iter *iter, int len);
@@ -83,11 +89,6 @@ static inline struct alg_sock *alg_sk(st
 	return (struct alg_sock *)sk;
 }
 
-static inline void af_alg_release_parent(struct sock *sk)
-{
-	sock_put(alg_sk(sk)->parent);
-}
-
 static inline void af_alg_init_completion(struct af_alg_completion *completion)
 {
 	init_completion(&completion->completion);
--- zfcpdump-kernel-4.4.orig/include/crypto/public_key.h
+++ zfcpdump-kernel-4.4/include/crypto/public_key.h
@@ -24,7 +24,6 @@ enum pkey_algo {
 };
 
 extern const char *const pkey_algo_name[PKEY_ALGO__LAST];
-extern const struct public_key_algorithm *pkey_algo[PKEY_ALGO__LAST];
 
 /* asymmetric key implementation supports only up to SHA224 */
 #define PKEY_HASH__LAST		(HASH_ALGO_SHA224 + 1)
@@ -59,31 +58,10 @@ extern const char *const key_being_used_
  * part.
  */
 struct public_key {
-	const struct public_key_algorithm *algo;
-	u8	capabilities;
-#define PKEY_CAN_ENCRYPT	0x01
-#define PKEY_CAN_DECRYPT	0x02
-#define PKEY_CAN_SIGN		0x04
-#define PKEY_CAN_VERIFY		0x08
+	void *key;
+	u32 keylen;
 	enum pkey_algo pkey_algo : 8;
 	enum pkey_id_type id_type : 8;
-	union {
-		MPI	mpi[5];
-		struct {
-			MPI	p;	/* DSA prime */
-			MPI	q;	/* DSA group order */
-			MPI	g;	/* DSA group generator */
-			MPI	y;	/* DSA public-key value = g^x mod p */
-			MPI	x;	/* DSA secret exponent (if present) */
-		} dsa;
-		struct {
-			MPI	n;	/* RSA public modulus */
-			MPI	e;	/* RSA public encryption exponent */
-			MPI	d;	/* RSA secret encryption exponent (if present) */
-			MPI	p;	/* RSA secret prime (if present) */
-			MPI	q;	/* RSA secret prime (if present) */
-		} rsa;
-	};
 };
 
 extern void public_key_destroy(void *payload);
@@ -92,6 +70,8 @@ extern void public_key_destroy(void *pay
  * Public key cryptography signature data
  */
 struct public_key_signature {
+	u8 *s;			/* Signature */
+	u32 s_size;		/* Number of bytes in signature */
 	u8 *digest;
 	u8 digest_size;			/* Number of bytes in digest */
 	u8 nr_mpi;			/* Occupancy of mpi[] */
@@ -109,6 +89,7 @@ struct public_key_signature {
 	};
 };
 
+extern struct asymmetric_key_subtype public_key_subtype;
 struct key;
 extern int verify_signature(const struct key *key,
 			    const struct public_key_signature *sig);
@@ -119,4 +100,9 @@ extern struct key *x509_request_asymmetr
 					       const struct asymmetric_key_id *skid,
 					       bool partial);
 
+int public_key_verify_signature(const struct public_key *pkey,
+				const struct public_key_signature *sig);
+
+int rsa_verify_signature(const struct public_key *pkey,
+			 const struct public_key_signature *sig);
 #endif /* _LINUX_PUBLIC_KEY_H */
--- zfcpdump-kernel-4.4.orig/include/crypto/skcipher.h
+++ zfcpdump-kernel-4.4/include/crypto/skcipher.h
@@ -61,6 +61,8 @@ struct crypto_skcipher {
 	unsigned int ivsize;
 	unsigned int reqsize;
 
+	bool has_setkey;
+
 	struct crypto_tfm base;
 };
 
@@ -305,6 +307,11 @@ static inline int crypto_skcipher_setkey
 	return tfm->setkey(tfm, key, keylen);
 }
 
+static inline bool crypto_skcipher_has_setkey(struct crypto_skcipher *tfm)
+{
+	return tfm->has_setkey;
+}
+
 /**
  * crypto_skcipher_reqtfm() - obtain cipher handle from request
  * @req: skcipher_request out of which the cipher handle is to be obtained
--- zfcpdump-kernel-4.4.orig/include/crypto/xts.h
+++ zfcpdump-kernel-4.4/include/crypto/xts.h
@@ -2,6 +2,9 @@
 #define _CRYPTO_XTS_H
 
 #include <crypto/b128ops.h>
+#include <linux/crypto.h>
+#include <crypto/algapi.h>
+#include <linux/fips.h>
 
 struct scatterlist;
 struct blkcipher_desc;
@@ -24,4 +27,28 @@ int xts_crypt(struct blkcipher_desc *des
 	      struct scatterlist *src, unsigned int nbytes,
 	      struct xts_crypt_req *req);
 
+static inline int xts_check_key(struct crypto_tfm *tfm,
+				const u8 *key, unsigned int keylen)
+{
+	u32 *flags = &tfm->crt_flags;
+
+	/*
+	 * key consists of keys of equal size concatenated, therefore
+	 * the length must be even.
+	 */
+	if (keylen % 2) {
+		*flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
+		return -EINVAL;
+	}
+
+	/* ensure that the AES and tweak key are not identical */
+	if (fips_enabled &&
+	    !crypto_memneq(key, key + (keylen / 2), keylen / 2)) {
+		*flags |= CRYPTO_TFM_RES_WEAK_KEY;
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
 #endif  /* _CRYPTO_XTS_H */
--- zfcpdump-kernel-4.4.orig/include/drm/drmP.h
+++ zfcpdump-kernel-4.4/include/drm/drmP.h
@@ -1108,6 +1108,7 @@ static inline int drm_pci_set_busid(stru
 #define DRM_PCIE_SPEED_80 4
 
 extern int drm_pcie_get_speed_cap_mask(struct drm_device *dev, u32 *speed_mask);
+extern int drm_pcie_get_max_link_width(struct drm_device *dev, u32 *mlw);
 
 /* platform section */
 extern int drm_platform_init(struct drm_driver *driver, struct platform_device *platform_device);
@@ -1121,4 +1122,7 @@ static __inline__ bool drm_can_sleep(voi
 	return true;
 }
 
+/* helper for handling conditionals in various for_each macros */
+#define for_each_if(condition) if (!(condition)) {} else
+
 #endif
--- zfcpdump-kernel-4.4.orig/include/drm/drm_atomic.h
+++ zfcpdump-kernel-4.4/include/drm/drm_atomic.h
@@ -130,10 +130,6 @@ int __must_check
 drm_atomic_add_affected_planes(struct drm_atomic_state *state,
 			       struct drm_crtc *crtc);
 
-int
-drm_atomic_connectors_for_crtc(struct drm_atomic_state *state,
-			       struct drm_crtc *crtc);
-
 void drm_atomic_legacy_backoff(struct drm_atomic_state *state);
 
 void
@@ -149,7 +145,7 @@ int __must_check drm_atomic_async_commit
 	     ((connector) = (state)->connectors[__i],			\
 	     (connector_state) = (state)->connector_states[__i], 1); 	\
 	     (__i)++)							\
-		if (connector)
+		for_each_if (connector)
 
 #define for_each_crtc_in_state(state, crtc, crtc_state, __i)	\
 	for ((__i) = 0;						\
@@ -157,7 +153,7 @@ int __must_check drm_atomic_async_commit
 	     ((crtc) = (state)->crtcs[__i],			\
 	     (crtc_state) = (state)->crtc_states[__i], 1);	\
 	     (__i)++)						\
-		if (crtc_state)
+		for_each_if (crtc_state)
 
 #define for_each_plane_in_state(state, plane, plane_state, __i)		\
 	for ((__i) = 0;							\
@@ -165,7 +161,7 @@ int __must_check drm_atomic_async_commit
 	     ((plane) = (state)->planes[__i],				\
 	     (plane_state) = (state)->plane_states[__i], 1);		\
 	     (__i)++)							\
-		if (plane_state)
+		for_each_if (plane_state)
 static inline bool
 drm_atomic_crtc_needs_modeset(struct drm_crtc_state *state)
 {
--- zfcpdump-kernel-4.4.orig/include/drm/drm_atomic_helper.h
+++ zfcpdump-kernel-4.4/include/drm/drm_atomic_helper.h
@@ -42,6 +42,10 @@ int drm_atomic_helper_commit(struct drm_
 			     struct drm_atomic_state *state,
 			     bool async);
 
+bool drm_atomic_helper_framebuffer_changed(struct drm_device *dev,
+					   struct drm_atomic_state *old_state,
+					   struct drm_crtc *crtc);
+
 void drm_atomic_helper_wait_for_vblanks(struct drm_device *dev,
 					struct drm_atomic_state *old_state);
 
@@ -81,6 +85,12 @@ int drm_atomic_helper_set_config(struct
 int __drm_atomic_helper_set_config(struct drm_mode_set *set,
 		struct drm_atomic_state *state);
 
+int drm_atomic_helper_disable_all(struct drm_device *dev,
+				  struct drm_modeset_acquire_ctx *ctx);
+struct drm_atomic_state *drm_atomic_helper_suspend(struct drm_device *dev);
+int drm_atomic_helper_resume(struct drm_device *dev,
+			     struct drm_atomic_state *state);
+
 int drm_atomic_helper_crtc_set_property(struct drm_crtc *crtc,
 					struct drm_property *property,
 					uint64_t val);
@@ -118,6 +128,8 @@ void __drm_atomic_helper_plane_destroy_s
 void drm_atomic_helper_plane_destroy_state(struct drm_plane *plane,
 					  struct drm_plane_state *state);
 
+void __drm_atomic_helper_connector_reset(struct drm_connector *connector,
+					 struct drm_connector_state *conn_state);
 void drm_atomic_helper_connector_reset(struct drm_connector *connector);
 void
 __drm_atomic_helper_connector_duplicate_state(struct drm_connector *connector,
@@ -132,6 +144,9 @@ __drm_atomic_helper_connector_destroy_st
 					    struct drm_connector_state *state);
 void drm_atomic_helper_connector_destroy_state(struct drm_connector *connector,
 					  struct drm_connector_state *state);
+void drm_atomic_helper_legacy_gamma_set(struct drm_crtc *crtc,
+					u16 *red, u16 *green, u16 *blue,
+					uint32_t start, uint32_t size);
 
 /**
  * drm_atomic_crtc_for_each_plane - iterate over planes currently attached to CRTC
--- zfcpdump-kernel-4.4.orig/include/drm/drm_cache.h
+++ zfcpdump-kernel-4.4/include/drm/drm_cache.h
@@ -35,4 +35,15 @@
 
 void drm_clflush_pages(struct page *pages[], unsigned long num_pages);
 
+static inline bool drm_arch_can_wc_memory(void)
+{
+#if defined(CONFIG_PPC) && !defined(CONFIG_NOT_COHERENT_CACHE)
+	return false;
+#elif defined(CONFIG_MIPS) && defined(CONFIG_CPU_LOONGSON3)
+	return false;
+#else
+	return true;
+#endif
+}
+
 #endif
--- zfcpdump-kernel-4.4.orig/include/drm/drm_crtc.h
+++ zfcpdump-kernel-4.4/include/drm/drm_crtc.h
@@ -259,11 +259,20 @@ struct drm_atomic_state;
  * @mode_changed: crtc_state->mode or crtc_state->enable has been changed
  * @active_changed: crtc_state->active has been toggled.
  * @connectors_changed: connectors to this crtc have been updated
+ * @color_mgmt_changed: color management properties have changed (degamma or
+ *	gamma LUT or CSC matrix)
  * @plane_mask: bitmask of (1 << drm_plane_index(plane)) of attached planes
+ * @connector_mask: bitmask of (1 << drm_connector_index(connector)) of attached connectors
+ * @encoder_mask: bitmask of (1 << drm_encoder_index(encoder)) of attached encoders
  * @last_vblank_count: for helpers and drivers to capture the vblank of the
  * 	update to ensure framebuffer cleanup isn't done too early
  * @adjusted_mode: for use by helpers and drivers to compute adjusted mode timings
  * @mode: current mode timings
+ * @degamma_lut: Lookup table for converting framebuffer pixel data
+ *	before apply the conversion matrix
+ * @ctm: Transformation matrix
+ * @gamma_lut: Lookup table for converting pixel data after the
+ *	conversion matrix
  * @event: optional pointer to a DRM event to signal upon completion of the
  * 	state update
  * @state: backpointer to global drm_atomic_state
@@ -285,6 +294,7 @@ struct drm_crtc_state {
 	bool mode_changed : 1;
 	bool active_changed : 1;
 	bool connectors_changed : 1;
+	bool color_mgmt_changed : 1;
 
 	/* attached planes bitmask:
 	 * WARNING: transitional helpers do not maintain plane_mask so
@@ -293,6 +303,9 @@ struct drm_crtc_state {
 	 */
 	u32 plane_mask;
 
+	u32 connector_mask;
+	u32 encoder_mask;
+
 	/* last_vblank_count: for vblank waits before cleanup */
 	u32 last_vblank_count;
 
@@ -304,6 +317,11 @@ struct drm_crtc_state {
 	/* blob property to expose current mode to atomic userspace */
 	struct drm_property_blob *mode_blob;
 
+	/* blob property to expose color management to userspace */
+	struct drm_property_blob *degamma_lut;
+	struct drm_property_blob *ctm;
+	struct drm_property_blob *gamma_lut;
+
 	struct drm_pending_vblank_event *event;
 
 	struct drm_atomic_state *state;
@@ -458,7 +476,7 @@ struct drm_crtc {
 	int x, y;
 	const struct drm_crtc_funcs *funcs;
 
-	/* CRTC gamma size for reporting to userspace */
+	/* Legacy FB CRTC gamma size for reporting to userspace */
 	uint32_t gamma_size;
 	uint16_t *gamma_store;
 
@@ -1038,6 +1056,15 @@ struct drm_mode_config_funcs {
  * @property_blob_list: list of all the blob property objects
  * @blob_lock: mutex for blob property allocation and management
  * @*_property: core property tracking
+ * @degamma_lut_property: LUT used to convert the framebuffer's colors to linear
+ *	gamma
+ * @degamma_lut_size_property: size of the degamma LUT as supported by the
+ *	driver (read-only)
+ * @ctm_property: Matrix used to convert colors after the lookup in the
+ *	degamma LUT
+ * @gamma_lut_property: LUT used to convert the colors, after the CSC matrix, to
+ *	the gamma space of the connected screen (read-only)
+ * @gamma_lut_size_property: size of the gamma LUT as supported by the driver
  * @preferred_depth: preferred RBG pixel depth, used by fb helpers
  * @prefer_shadow: hint to userspace to prefer shadow-fb rendering
  * @async_page_flip: does this device support async flips on the primary plane?
@@ -1139,6 +1166,13 @@ struct drm_mode_config {
 	struct drm_property *aspect_ratio_property;
 	struct drm_property *dirty_info_property;
 
+	/* Optional color correction properties */
+	struct drm_property *degamma_lut_property;
+	struct drm_property *degamma_lut_size_property;
+	struct drm_property *ctm_property;
+	struct drm_property *gamma_lut_property;
+	struct drm_property *gamma_lut_size_property;
+
 	/* properties for virtual machine layout */
 	struct drm_property *suggested_x_property;
 	struct drm_property *suggested_y_property;
@@ -1166,8 +1200,19 @@ struct drm_mode_config {
  */
 #define drm_for_each_plane_mask(plane, dev, plane_mask) \
 	list_for_each_entry((plane), &(dev)->mode_config.plane_list, head) \
-		if ((plane_mask) & (1 << drm_plane_index(plane)))
+		for_each_if ((plane_mask) & (1 << drm_plane_index(plane)))
 
+/**
+ * drm_for_each_encoder_mask - iterate over encoders specified by bitmask
+ * @encoder: the loop cursor
+ * @dev: the DRM device
+ * @encoder_mask: bitmask of encoder indices
+ *
+ * Iterate over all encoders specified by bitmask.
+ */
+#define drm_for_each_encoder_mask(encoder, dev, encoder_mask) \
+	list_for_each_entry((encoder), &(dev)->mode_config.encoder_list, head) \
+		for_each_if ((encoder_mask) & (1 << drm_encoder_index(encoder)))
 
 #define obj_to_crtc(x) container_of(x, struct drm_crtc, base)
 #define obj_to_connector(x) container_of(x, struct drm_connector, base)
@@ -1237,6 +1282,7 @@ extern int drm_encoder_init(struct drm_d
 			    struct drm_encoder *encoder,
 			    const struct drm_encoder_funcs *funcs,
 			    int encoder_type);
+extern unsigned int drm_encoder_index(struct drm_encoder *encoder);
 
 /**
  * drm_encoder_crtc_ok - can a given crtc drive a given encoder?
@@ -1540,10 +1586,29 @@ static inline struct drm_property *drm_p
 	return mo ? obj_to_property(mo) : NULL;
 }
 
+/*
+ * Extract a degamma/gamma LUT value provided by user and round it to the
+ * precision supported by the hardware.
+ */
+static inline uint32_t drm_color_lut_extract(uint32_t user_input,
+					     uint32_t bit_precision)
+{
+	uint32_t val = user_input;
+	uint32_t max = 0xffff >> (16 - bit_precision);
+
+	/* Round only if we're not using full precision. */
+	if (bit_precision < 16) {
+		val += 1UL << (16 - bit_precision - 1);
+		val >>= 16 - bit_precision;
+	}
+
+	return clamp_val(val, 0, max);
+}
+
 /* Plane list iterator for legacy (overlay only) planes. */
 #define drm_for_each_legacy_plane(plane, dev) \
 	list_for_each_entry(plane, &(dev)->mode_config.plane_list, head) \
-		if (plane->type == DRM_PLANE_TYPE_OVERLAY)
+		for_each_if (plane->type == DRM_PLANE_TYPE_OVERLAY)
 
 #define drm_for_each_plane(plane, dev) \
 	list_for_each_entry(plane, &(dev)->mode_config.plane_list, head)
--- zfcpdump-kernel-4.4.orig/include/drm/drm_crtc_helper.h
+++ zfcpdump-kernel-4.4/include/drm/drm_crtc_helper.h
@@ -189,6 +189,9 @@ extern bool drm_crtc_helper_set_mode(str
 				     struct drm_display_mode *mode,
 				     int x, int y,
 				     struct drm_framebuffer *old_fb);
+extern void drm_helper_crtc_enable_color_mgmt(struct drm_crtc *crtc,
+					      int degamma_lut_size,
+					      int gamma_lut_size);
 extern bool drm_helper_crtc_in_use(struct drm_crtc *crtc);
 extern bool drm_helper_encoder_in_use(struct drm_encoder *encoder);
 
--- /dev/null
+++ zfcpdump-kernel-4.4/include/drm/drm_dp_aux_dev.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright © 2015 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Rafael Antognolli <rafael.antognolli@intel.com>
+ *
+ */
+
+#ifndef DRM_DP_AUX_DEV
+#define DRM_DP_AUX_DEV
+
+#include <drm/drm_dp_helper.h>
+
+#ifdef CONFIG_DRM_DP_AUX_CHARDEV
+
+int drm_dp_aux_dev_init(void);
+void drm_dp_aux_dev_exit(void);
+int drm_dp_aux_register_devnode(struct drm_dp_aux *aux);
+void drm_dp_aux_unregister_devnode(struct drm_dp_aux *aux);
+
+#else
+
+static inline int drm_dp_aux_dev_init(void)
+{
+	return 0;
+}
+
+static inline void drm_dp_aux_dev_exit(void)
+{
+}
+
+static inline int drm_dp_aux_register_devnode(struct drm_dp_aux *aux)
+{
+	return 0;
+}
+
+static inline void drm_dp_aux_unregister_devnode(struct drm_dp_aux *aux)
+{
+}
+
+#endif
+
+#endif
--- /dev/null
+++ zfcpdump-kernel-4.4/include/drm/drm_dp_dual_mode_helper.h
@@ -0,0 +1,92 @@
+/*
+ * Copyright © 2016 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef DRM_DP_DUAL_MODE_HELPER_H
+#define DRM_DP_DUAL_MODE_HELPER_H
+
+#include <linux/types.h>
+
+/*
+ * Optional for type 1 DVI adaptors
+ * Mandatory for type 1 HDMI and type 2 adaptors
+ */
+#define DP_DUAL_MODE_HDMI_ID 0x00 /* 00-0f */
+#define  DP_DUAL_MODE_HDMI_ID_LEN 16
+/*
+ * Optional for type 1 adaptors
+ * Mandatory for type 2 adaptors
+ */
+#define DP_DUAL_MODE_ADAPTOR_ID 0x10
+#define  DP_DUAL_MODE_REV_MASK 0x07
+#define  DP_DUAL_MODE_REV_TYPE2 0x00
+#define  DP_DUAL_MODE_TYPE_MASK 0xf0
+#define  DP_DUAL_MODE_TYPE_TYPE2 0xa0
+#define DP_DUAL_MODE_IEEE_OUI 0x11 /* 11-13*/
+#define  DP_DUAL_IEEE_OUI_LEN 3
+#define DP_DUAL_DEVICE_ID 0x14 /* 14-19 */
+#define  DP_DUAL_DEVICE_ID_LEN 6
+#define DP_DUAL_MODE_HARDWARE_REV 0x1a
+#define DP_DUAL_MODE_FIRMWARE_MAJOR_REV 0x1b
+#define DP_DUAL_MODE_FIRMWARE_MINOR_REV 0x1c
+#define DP_DUAL_MODE_MAX_TMDS_CLOCK 0x1d
+#define DP_DUAL_MODE_I2C_SPEED_CAP 0x1e
+#define DP_DUAL_MODE_TMDS_OEN 0x20
+#define  DP_DUAL_MODE_TMDS_DISABLE 0x01
+#define DP_DUAL_MODE_HDMI_PIN_CTRL 0x21
+#define  DP_DUAL_MODE_CEC_ENABLE 0x01
+#define DP_DUAL_MODE_I2C_SPEED_CTRL 0x22
+
+struct i2c_adapter;
+
+ssize_t drm_dp_dual_mode_read(struct i2c_adapter *adapter,
+			      u8 offset, void *buffer, size_t size);
+ssize_t drm_dp_dual_mode_write(struct i2c_adapter *adapter,
+			       u8 offset, const void *buffer, size_t size);
+
+/**
+ * enum drm_dp_dual_mode_type - Type of the DP dual mode adaptor
+ * @DRM_DP_DUAL_MODE_NONE: No DP dual mode adaptor
+ * @DRM_DP_DUAL_MODE_UNKNOWN: Could be either none or type 1 DVI adaptor
+ * @DRM_DP_DUAL_MODE_TYPE1_DVI: Type 1 DVI adaptor
+ * @DRM_DP_DUAL_MODE_TYPE1_HDMI: Type 1 HDMI adaptor
+ * @DRM_DP_DUAL_MODE_TYPE2_DVI: Type 2 DVI adaptor
+ * @DRM_DP_DUAL_MODE_TYPE2_HDMI: Type 2 HDMI adaptor
+ */
+enum drm_dp_dual_mode_type {
+	DRM_DP_DUAL_MODE_NONE,
+	DRM_DP_DUAL_MODE_UNKNOWN,
+	DRM_DP_DUAL_MODE_TYPE1_DVI,
+	DRM_DP_DUAL_MODE_TYPE1_HDMI,
+	DRM_DP_DUAL_MODE_TYPE2_DVI,
+	DRM_DP_DUAL_MODE_TYPE2_HDMI,
+};
+
+enum drm_dp_dual_mode_type drm_dp_dual_mode_detect(struct i2c_adapter *adapter);
+int drm_dp_dual_mode_max_tmds_clock(enum drm_dp_dual_mode_type type,
+				    struct i2c_adapter *adapter);
+int drm_dp_dual_mode_get_tmds_output(enum drm_dp_dual_mode_type type,
+				     struct i2c_adapter *adapter, bool *enabled);
+int drm_dp_dual_mode_set_tmds_output(enum drm_dp_dual_mode_type type,
+				     struct i2c_adapter *adapter, bool enable);
+const char *drm_dp_get_dual_mode_type_name(enum drm_dp_dual_mode_type type);
+
+#endif
--- zfcpdump-kernel-4.4.orig/include/drm/drm_dp_mst_helper.h
+++ zfcpdump-kernel-4.4/include/drm/drm_dp_mst_helper.h
@@ -44,8 +44,6 @@ struct drm_dp_vcpi {
 /**
  * struct drm_dp_mst_port - MST port
  * @kref: reference count for this port.
- * @guid_valid: for DP 1.2 devices if we have validated the GUID.
- * @guid: guid for DP 1.2 device on this port.
  * @port_num: port number
  * @input: if this port is an input port.
  * @mcs: message capability status - DP 1.2 spec.
@@ -70,10 +68,6 @@ struct drm_dp_vcpi {
 struct drm_dp_mst_port {
 	struct kref kref;
 
-	/* if dpcd 1.2 device is on this port - its GUID info */
-	bool guid_valid;
-	u8 guid[16];
-
 	u8 port_num;
 	bool input;
 	bool mcs;
@@ -94,6 +88,7 @@ struct drm_dp_mst_port {
 	struct drm_dp_mst_topology_mgr *mgr;
 
 	struct edid *cached_edid; /* for DP logical ports - make tiling work */
+	bool has_audio;
 };
 
 /**
@@ -109,10 +104,12 @@ struct drm_dp_mst_port {
  * @tx_slots: transmission slots for this device.
  * @last_seqno: last sequence number used to talk to this.
  * @link_address_sent: if a link address message has been sent to this device yet.
+ * @guid: guid for DP 1.2 branch device. port under this branch can be
+ * identified by port #.
  *
  * This structure represents an MST branch device, there is one
- * primary branch device at the root, along with any others connected
- * to downstream ports
+ * primary branch device at the root, along with any other branches connected
+ * to downstream port of parent branches.
  */
 struct drm_dp_mst_branch {
 	struct kref kref;
@@ -131,6 +128,9 @@ struct drm_dp_mst_branch {
 	struct drm_dp_sideband_msg_tx *tx_slots[2];
 	int last_seqno;
 	bool link_address_sent;
+
+	/* global unique identifier to identify branch devices */
+	u8 guid[16];
 };
 
 
@@ -215,13 +215,13 @@ struct drm_dp_sideband_msg_rx {
 	struct drm_dp_sideband_msg_hdr initial_hdr;
 };
 
-
+#define DRM_DP_MAX_SDP_STREAMS 16
 struct drm_dp_allocate_payload {
 	u8 port_number;
 	u8 number_sdp_streams;
 	u8 vcpi;
 	u16 pbn;
-	u8 sdp_stream_sink[8];
+	u8 sdp_stream_sink[DRM_DP_MAX_SDP_STREAMS];
 };
 
 struct drm_dp_allocate_payload_ack_reply {
@@ -405,11 +405,9 @@ struct drm_dp_payload {
  * @conn_base_id: DRM connector ID this mgr is connected to.
  * @down_rep_recv: msg receiver state for down replies.
  * @up_req_recv: msg receiver state for up requests.
- * @lock: protects mst state, primary, guid, dpcd.
+ * @lock: protects mst state, primary, dpcd.
  * @mst_state: if this manager is enabled for an MST capable port.
  * @mst_primary: pointer to the primary branch device.
- * @guid_valid: GUID valid for the primary branch device.
- * @guid: GUID for primary port.
  * @dpcd: cache of DPCD for primary port.
  * @pbn_div: PBN to slots divisor.
  *
@@ -431,13 +429,11 @@ struct drm_dp_mst_topology_mgr {
 	struct drm_dp_sideband_msg_rx up_req_recv;
 
 	/* pointer to info about the initial MST device */
-	struct mutex lock; /* protects mst_state + primary + guid + dpcd */
+	struct mutex lock; /* protects mst_state + primary + dpcd */
 
 	bool mst_state;
 	struct drm_dp_mst_branch *mst_primary;
-	/* primary MST device GUID */
-	bool guid_valid;
-	u8 guid[16];
+
 	u8 dpcd[DP_RECEIVER_CAP_SIZE];
 	u8 sink_count;
 	int pbn_div;
@@ -450,9 +446,7 @@ struct drm_dp_mst_topology_mgr {
 	   the mstb tx_slots and txmsg->state once they are queued */
 	struct mutex qlock;
 	struct list_head tx_msg_downq;
-	struct list_head tx_msg_upq;
 	bool tx_down_in_progress;
-	bool tx_up_in_progress;
 
 	/* payload info + lock for it */
 	struct mutex payload_lock;
@@ -484,6 +478,8 @@ int drm_dp_mst_hpd_irq(struct drm_dp_mst
 
 enum drm_connector_status drm_dp_mst_detect_port(struct drm_connector *connector, struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_port *port);
 
+bool drm_dp_mst_port_has_audio(struct drm_dp_mst_topology_mgr *mgr,
+					struct drm_dp_mst_port *port);
 struct edid *drm_dp_mst_get_edid(struct drm_connector *connector, struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_port *port);
 
 
--- zfcpdump-kernel-4.4.orig/include/drm/drm_fb_helper.h
+++ zfcpdump-kernel-4.4/include/drm/drm_fb_helper.h
@@ -148,6 +148,7 @@ struct drm_fb_helper {
 };
 
 #ifdef CONFIG_DRM_FBDEV_EMULATION
+int drm_fb_helper_modinit(void);
 void drm_fb_helper_prepare(struct drm_device *dev, struct drm_fb_helper *helper,
 			   const struct drm_fb_helper_funcs *funcs);
 int drm_fb_helper_init(struct drm_device *dev,
@@ -212,6 +213,11 @@ int drm_fb_helper_add_one_connector(stru
 int drm_fb_helper_remove_one_connector(struct drm_fb_helper *fb_helper,
 				       struct drm_connector *connector);
 #else
+static inline int drm_fb_helper_modinit(void)
+{
+	return 0;
+}
+
 static inline void drm_fb_helper_prepare(struct drm_device *dev,
 					struct drm_fb_helper *helper,
 					const struct drm_fb_helper_funcs *funcs)
--- zfcpdump-kernel-4.4.orig/include/drm/drm_fixed.h
+++ zfcpdump-kernel-4.4/include/drm/drm_fixed.h
@@ -73,18 +73,28 @@ static inline u32 dfixed_div(fixed20_12
 #define DRM_FIXED_ONE		(1ULL << DRM_FIXED_POINT)
 #define DRM_FIXED_DECIMAL_MASK	(DRM_FIXED_ONE - 1)
 #define DRM_FIXED_DIGITS_MASK	(~DRM_FIXED_DECIMAL_MASK)
+#define DRM_FIXED_EPSILON	1LL
+#define DRM_FIXED_ALMOST_ONE	(DRM_FIXED_ONE - DRM_FIXED_EPSILON)
 
 static inline s64 drm_int2fixp(int a)
 {
 	return ((s64)a) << DRM_FIXED_POINT;
 }
 
-static inline int drm_fixp2int(int64_t a)
+static inline int drm_fixp2int(s64 a)
 {
 	return ((s64)a) >> DRM_FIXED_POINT;
 }
 
-static inline unsigned drm_fixp_msbset(int64_t a)
+static inline int drm_fixp2int_ceil(s64 a)
+{
+	if (a > 0)
+		return drm_fixp2int(a + DRM_FIXED_ALMOST_ONE);
+	else
+		return drm_fixp2int(a - DRM_FIXED_ALMOST_ONE);
+}
+
+static inline unsigned drm_fixp_msbset(s64 a)
 {
 	unsigned shift, sign = (a >> 63) & 1;
 
@@ -136,6 +146,45 @@ static inline s64 drm_fixp_div(s64 a, s6
 	return result;
 }
 
+static inline s64 drm_fixp_from_fraction(s64 a, s64 b)
+{
+	s64 res;
+	bool a_neg = a < 0;
+	bool b_neg = b < 0;
+	u64 a_abs = a_neg ? -a : a;
+	u64 b_abs = b_neg ? -b : b;
+	u64 rem;
+
+	/* determine integer part */
+	u64 res_abs  = div64_u64_rem(a_abs, b_abs, &rem);
+
+	/* determine fractional part */
+	{
+		u32 i = DRM_FIXED_POINT;
+
+		do {
+			rem <<= 1;
+			res_abs <<= 1;
+			if (rem >= b_abs) {
+				res_abs |= 1;
+				rem -= b_abs;
+			}
+		} while (--i != 0);
+	}
+
+	/* round up LSB */
+	{
+		u64 summand = (rem << 1) >= b_abs;
+
+		res_abs += summand;
+	}
+
+	res = (s64) res_abs;
+	if (a_neg ^ b_neg)
+		res = -res;
+	return res;
+}
+
 static inline s64 drm_fixp_exp(s64 x)
 {
 	s64 tolerance = div64_s64(DRM_FIXED_ONE, 1000000);
--- zfcpdump-kernel-4.4.orig/include/drm/drm_mem_util.h
+++ zfcpdump-kernel-4.4/include/drm/drm_mem_util.h
@@ -54,6 +54,25 @@ static __inline__ void *drm_malloc_ab(si
 			 GFP_KERNEL | __GFP_HIGHMEM, PAGE_KERNEL);
 }
 
+static __inline__ void *drm_malloc_gfp(size_t nmemb, size_t size, gfp_t gfp)
+{
+	if (size != 0 && nmemb > SIZE_MAX / size)
+		return NULL;
+
+	if (size * nmemb <= PAGE_SIZE)
+		return kmalloc(nmemb * size, gfp);
+
+	if (gfp & __GFP_RECLAIMABLE) {
+		void *ptr = kmalloc(nmemb * size,
+				    gfp | __GFP_NOWARN | __GFP_NORETRY);
+		if (ptr)
+			return ptr;
+	}
+
+	return __vmalloc(size * nmemb,
+			 gfp | __GFP_HIGHMEM, PAGE_KERNEL);
+}
+
 static __inline void drm_free_large(void *ptr)
 {
 	kvfree(ptr);
--- zfcpdump-kernel-4.4.orig/include/drm/drm_mipi_dsi.h
+++ zfcpdump-kernel-4.4/include/drm/drm_mipi_dsi.h
@@ -163,6 +163,31 @@ static inline struct mipi_dsi_device *to
 	return container_of(dev, struct mipi_dsi_device, dev);
 }
 
+/**
+ * mipi_dsi_pixel_format_to_bpp - obtain the number of bits per pixel for any
+ *                                given pixel format defined by the MIPI DSI
+ *                                specification
+ * @fmt: MIPI DSI pixel format
+ *
+ * Returns: The number of bits per pixel of the given pixel format.
+ */
+static inline int mipi_dsi_pixel_format_to_bpp(enum mipi_dsi_pixel_format fmt)
+{
+	switch (fmt) {
+	case MIPI_DSI_FMT_RGB888:
+	case MIPI_DSI_FMT_RGB666:
+		return 24;
+
+	case MIPI_DSI_FMT_RGB666_PACKED:
+		return 18;
+
+	case MIPI_DSI_FMT_RGB565:
+		return 16;
+	}
+
+	return -EINVAL;
+}
+
 struct mipi_dsi_device *of_find_mipi_dsi_device_by_node(struct device_node *np);
 int mipi_dsi_attach(struct mipi_dsi_device *dsi);
 int mipi_dsi_detach(struct mipi_dsi_device *dsi);
--- zfcpdump-kernel-4.4.orig/include/drm/drm_modeset_lock.h
+++ zfcpdump-kernel-4.4/include/drm/drm_modeset_lock.h
@@ -138,7 +138,7 @@ void drm_warn_on_modeset_not_all_locked(
 struct drm_modeset_acquire_ctx *
 drm_modeset_legacy_acquire_ctx(struct drm_crtc *crtc);
 
-int drm_modeset_lock_all_crtcs(struct drm_device *dev,
-		struct drm_modeset_acquire_ctx *ctx);
+int drm_modeset_lock_all_ctx(struct drm_device *dev,
+			     struct drm_modeset_acquire_ctx *ctx);
 
 #endif /* DRM_MODESET_LOCK_H_ */
--- zfcpdump-kernel-4.4.orig/include/drm/drm_rect.h
+++ zfcpdump-kernel-4.4/include/drm/drm_rect.h
@@ -162,7 +162,8 @@ int drm_rect_calc_hscale_relaxed(struct
 int drm_rect_calc_vscale_relaxed(struct drm_rect *src,
 				 struct drm_rect *dst,
 				 int min_vscale, int max_vscale);
-void drm_rect_debug_print(const struct drm_rect *r, bool fixed_point);
+void drm_rect_debug_print(const char *prefix,
+			  const struct drm_rect *r, bool fixed_point);
 void drm_rect_rotate(struct drm_rect *r,
 		     int width, int height,
 		     unsigned int rotation);
--- zfcpdump-kernel-4.4.orig/include/drm/i915_component.h
+++ zfcpdump-kernel-4.4/include/drm/i915_component.h
@@ -46,6 +46,20 @@ struct i915_audio_component_ops {
 	void (*codec_wake_override)(struct device *, bool enable);
 	int (*get_cdclk_freq)(struct device *);
 	int (*sync_audio_rate)(struct device *, int port, int rate);
+	/**
+	 * @get_eld: fill the audio state and ELD bytes for the given port
+	 *
+	 * Called from audio driver to get the HDMI/DP audio state of the given
+	 * digital port, and also fetch ELD bytes to the given pointer.
+	 *
+	 * It returns the byte size of the original ELD (not the actually
+	 * copied size), zero for an invalid ELD, or a negative error code.
+	 *
+	 * Note that the returned size may be over @max_bytes.  Then it
+	 * implies that only a part of ELD has been copied to the buffer.
+	 */
+	int (*get_eld)(struct device *, int port, bool *enabled,
+		       unsigned char *buf, int max_bytes);
 };
 
 struct i915_audio_component_audio_ops {
--- /dev/null
+++ zfcpdump-kernel-4.4/include/drm/i915_drm_bpo.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+#ifndef _I915_DRM_BPO_H_
+#define _I915_DRM_BPO_H_
+
+/* For use by IPS driver */
+extern unsigned long i915_bpo_read_mch_val(void);
+extern bool i915_bpo_gpu_raise(void);
+extern bool i915_bpo_gpu_lower(void);
+extern bool i915_bpo_gpu_busy(void);
+extern bool i915_bpo_gpu_turbo_disable(void);
+
+#endif				/* _I915_DRM_BPO_H_ */
--- zfcpdump-kernel-4.4.orig/include/drm/i915_pciids.h
+++ zfcpdump-kernel-4.4/include/drm/i915_pciids.h
@@ -277,18 +277,63 @@
 	INTEL_VGA_DEVICE(0x191D, info)  /* WKS GT2 */
 
 #define INTEL_SKL_GT3_IDS(info) \
+	INTEL_VGA_DEVICE(0x1923, info), /* ULT GT3 */ \
 	INTEL_VGA_DEVICE(0x1926, info), /* ULT GT3 */ \
+	INTEL_VGA_DEVICE(0x1927, info), /* ULT GT3 */ \
 	INTEL_VGA_DEVICE(0x192B, info), /* Halo GT3 */ \
-	INTEL_VGA_DEVICE(0x192A, info) /* SRV GT3 */ \
+	INTEL_VGA_DEVICE(0x192A, info)  /* SRV GT3 */
 
-#define INTEL_SKL_IDS(info) \
+#define INTEL_SKL_GT4_IDS(info) \
+	INTEL_VGA_DEVICE(0x1932, info), /* DT GT4 */ \
+	INTEL_VGA_DEVICE(0x193B, info), /* Halo GT4 */ \
+	INTEL_VGA_DEVICE(0x193D, info), /* WKS GT4 */ \
+	INTEL_VGA_DEVICE(0x193A, info)  /* SRV GT4 */
+
+#define INTEL_SKL_IDS(info)	 \
 	INTEL_SKL_GT1_IDS(info), \
 	INTEL_SKL_GT2_IDS(info), \
-	INTEL_SKL_GT3_IDS(info)
+	INTEL_SKL_GT3_IDS(info), \
+	INTEL_SKL_GT4_IDS(info)
 
 #define INTEL_BXT_IDS(info) \
 	INTEL_VGA_DEVICE(0x0A84, info), \
 	INTEL_VGA_DEVICE(0x1A84, info), \
-	INTEL_VGA_DEVICE(0x5A84, info)
+	INTEL_VGA_DEVICE(0x1A85, info), \
+	INTEL_VGA_DEVICE(0x5A84, info), /* APL HD Graphics 505 */ \
+	INTEL_VGA_DEVICE(0x5A85, info)  /* APL HD Graphics 500 */
+
+#define INTEL_KBL_GT1_IDS(info)	\
+	INTEL_VGA_DEVICE(0x5913, info), /* ULT GT1.5 */ \
+	INTEL_VGA_DEVICE(0x5915, info), /* ULX GT1.5 */ \
+	INTEL_VGA_DEVICE(0x5917, info), /* DT  GT1.5 */ \
+	INTEL_VGA_DEVICE(0x5906, info), /* ULT GT1 */ \
+	INTEL_VGA_DEVICE(0x590E, info), /* ULX GT1 */ \
+	INTEL_VGA_DEVICE(0x5902, info), /* DT  GT1 */ \
+	INTEL_VGA_DEVICE(0x5908, info), /* Halo GT1 */ \
+	INTEL_VGA_DEVICE(0x590B, info), /* Halo GT1 */ \
+	INTEL_VGA_DEVICE(0x590A, info) /* SRV GT1 */
+
+#define INTEL_KBL_GT2_IDS(info)	\
+	INTEL_VGA_DEVICE(0x5916, info), /* ULT GT2 */ \
+	INTEL_VGA_DEVICE(0x5921, info), /* ULT GT2F */ \
+	INTEL_VGA_DEVICE(0x591E, info), /* ULX GT2 */ \
+	INTEL_VGA_DEVICE(0x5912, info), /* DT  GT2 */ \
+	INTEL_VGA_DEVICE(0x591B, info), /* Halo GT2 */ \
+	INTEL_VGA_DEVICE(0x591A, info), /* SRV GT2 */ \
+	INTEL_VGA_DEVICE(0x591D, info) /* WKS GT2 */
+
+#define INTEL_KBL_GT3_IDS(info) \
+	INTEL_VGA_DEVICE(0x5923, info), /* ULT GT3 */ \
+	INTEL_VGA_DEVICE(0x5926, info), /* ULT GT3 */ \
+	INTEL_VGA_DEVICE(0x5927, info) /* ULT GT3 */
+
+#define INTEL_KBL_GT4_IDS(info) \
+	INTEL_VGA_DEVICE(0x593B, info) /* Halo GT4 */
+
+#define INTEL_KBL_IDS(info) \
+	INTEL_KBL_GT1_IDS(info), \
+	INTEL_KBL_GT2_IDS(info), \
+	INTEL_KBL_GT3_IDS(info), \
+	INTEL_KBL_GT4_IDS(info)
 
 #endif /* _I915_PCIIDS_H */
--- zfcpdump-kernel-4.4.orig/include/drm/ttm/ttm_bo_api.h
+++ zfcpdump-kernel-4.4/include/drm/ttm/ttm_bo_api.h
@@ -316,6 +316,20 @@ ttm_bo_reference(struct ttm_buffer_objec
  */
 extern int ttm_bo_wait(struct ttm_buffer_object *bo, bool lazy,
 		       bool interruptible, bool no_wait);
+
+/**
+ * ttm_bo_mem_compat - Check if proposed placement is compatible with a bo
+ *
+ * @placement:  Return immediately if buffer is busy.
+ * @mem:  The struct ttm_mem_reg indicating the region where the bo resides
+ * @new_flags: Describes compatible placement found
+ *
+ * Returns true if the placement is compatible
+ */
+extern bool ttm_bo_mem_compat(struct ttm_placement *placement,
+			      struct ttm_mem_reg *mem,
+			      uint32_t *new_flags);
+
 /**
  * ttm_bo_validate
  *
@@ -383,6 +397,16 @@ extern void ttm_bo_add_to_lru(struct ttm
  */
 extern int ttm_bo_del_from_lru(struct ttm_buffer_object *bo);
 
+/**
+ * ttm_bo_move_to_lru_tail
+ *
+ * @bo: The buffer object.
+ *
+ * Move this BO to the tail of all lru lists used to lookup and reserve an
+ * object. This function must be called with struct ttm_bo_global::lru_lock
+ * held, and is used to make a BO less likely to be considered for eviction.
+ */
+extern void ttm_bo_move_to_lru_tail(struct ttm_buffer_object *bo);
 
 /**
  * ttm_bo_lock_delayed_workqueue
--- zfcpdump-kernel-4.4.orig/include/keys/system_keyring.h
+++ zfcpdump-kernel-4.4/include/keys/system_keyring.h
@@ -35,4 +35,32 @@ extern int system_verify_data(const void
 			      enum key_being_used_for usage);
 #endif
 
+#ifdef CONFIG_SYSTEM_BLACKLIST_KEYRING
+extern struct key *system_blacklist_keyring;
+#endif
+
+#ifdef CONFIG_IMA_MOK_KEYRING
+extern struct key *ima_mok_keyring;
+extern struct key *ima_blacklist_keyring;
+
+static inline struct key *get_ima_mok_keyring(void)
+{
+	return ima_mok_keyring;
+}
+static inline struct key *get_ima_blacklist_keyring(void)
+{
+	return ima_blacklist_keyring;
+}
+#else
+static inline struct key *get_ima_mok_keyring(void)
+{
+	return NULL;
+}
+static inline struct key *get_ima_blacklist_keyring(void)
+{
+	return NULL;
+}
+#endif /* CONFIG_IMA_MOK_KEYRING */
+
+
 #endif /* _KEYS_SYSTEM_KEYRING_H */
--- zfcpdump-kernel-4.4.orig/include/keys/trusted-type.h
+++ zfcpdump-kernel-4.4/include/keys/trusted-type.h
@@ -18,6 +18,7 @@
 #define MAX_KEY_SIZE			128
 #define MAX_BLOB_SIZE			512
 #define MAX_PCRINFO_SIZE		64
+#define MAX_DIGEST_SIZE			64
 
 struct trusted_key_payload {
 	struct rcu_head rcu;
@@ -36,6 +37,10 @@ struct trusted_key_options {
 	uint32_t pcrinfo_len;
 	unsigned char pcrinfo[MAX_PCRINFO_SIZE];
 	int pcrlock;
+	uint32_t hash;
+	uint32_t policydigest_len;
+	unsigned char policydigest[MAX_DIGEST_SIZE];
+	uint32_t policyhandle;
 };
 
 extern struct key_type key_type_trusted;
--- zfcpdump-kernel-4.4.orig/include/linux/acpi.h
+++ zfcpdump-kernel-4.4/include/linux/acpi.h
@@ -920,7 +920,7 @@ static inline struct fwnode_handle *acpi
 	return NULL;
 }
 
-#define ACPI_DECLARE_PROBE_ENTRY(table, name, table_id, subtable, validate, data, fn) \
+#define ACPI_DECLARE_PROBE_ENTRY(table, name, table_id, subtable, valid, data, fn) \
 	static const void * __acpi_table_##name[]			\
 		__attribute__((unused))					\
 		 = { (void *) table_id,					\
--- zfcpdump-kernel-4.4.orig/include/linux/ata.h
+++ zfcpdump-kernel-4.4/include/linux/ata.h
@@ -487,8 +487,8 @@ enum ata_tf_protocols {
 };
 
 enum ata_ioctls {
-	ATA_IOC_GET_IO32	= 0x309,
-	ATA_IOC_SET_IO32	= 0x324,
+	ATA_IOC_GET_IO32	= 0x309, /* HDIO_GET_32BIT */
+	ATA_IOC_SET_IO32	= 0x324, /* HDIO_SET_32BIT */
 };
 
 /* core structures */
--- zfcpdump-kernel-4.4.orig/include/linux/atomic.h
+++ zfcpdump-kernel-4.4/include/linux/atomic.h
@@ -34,20 +34,29 @@
  * The idea here is to build acquire/release variants by adding explicit
  * barriers on top of the relaxed variant. In the case where the relaxed
  * variant is already fully ordered, no additional barriers are needed.
+ *
+ * Besides, if an arch has a special barrier for acquire/release, it could
+ * implement its own __atomic_op_* and use the same framework for building
+ * variants
  */
+#ifndef __atomic_op_acquire
 #define __atomic_op_acquire(op, args...)				\
 ({									\
 	typeof(op##_relaxed(args)) __ret  = op##_relaxed(args);		\
 	smp_mb__after_atomic();						\
 	__ret;								\
 })
+#endif
 
+#ifndef __atomic_op_release
 #define __atomic_op_release(op, args...)				\
 ({									\
 	smp_mb__before_atomic();					\
 	op##_relaxed(args);						\
 })
+#endif
 
+#ifndef __atomic_op_fence
 #define __atomic_op_fence(op, args...)					\
 ({									\
 	typeof(op##_relaxed(args)) __ret;				\
@@ -56,6 +65,7 @@
 	smp_mb__after_atomic();						\
 	__ret;								\
 })
+#endif
 
 /* atomic_add_return_relaxed */
 #ifndef atomic_add_return_relaxed
--- zfcpdump-kernel-4.4.orig/include/linux/backing-dev-defs.h
+++ zfcpdump-kernel-4.4/include/linux/backing-dev-defs.h
@@ -163,6 +163,7 @@ struct backing_dev_info {
 	wait_queue_head_t wb_waitq;
 
 	struct device *dev;
+	struct device *owner;
 
 	struct timer_list laptop_mode_wb_timer;
 
--- zfcpdump-kernel-4.4.orig/include/linux/backing-dev.h
+++ zfcpdump-kernel-4.4/include/linux/backing-dev.h
@@ -24,6 +24,7 @@ __printf(3, 4)
 int bdi_register(struct backing_dev_info *bdi, struct device *parent,
 		const char *fmt, ...);
 int bdi_register_dev(struct backing_dev_info *bdi, dev_t dev);
+int bdi_register_owner(struct backing_dev_info *bdi, struct device *owner);
 void bdi_unregister(struct backing_dev_info *bdi);
 
 int __must_check bdi_setup_and_register(struct backing_dev_info *, char *);
--- zfcpdump-kernel-4.4.orig/include/linux/bcma/bcma.h
+++ zfcpdump-kernel-4.4/include/linux/bcma/bcma.h
@@ -156,6 +156,7 @@ struct bcma_host_ops {
 #define BCMA_CORE_DEFAULT		0xFFF
 
 #define BCMA_MAX_NR_CORES		16
+#define BCMA_CORE_SIZE			0x1000
 
 /* Chip IDs of PCIe devices */
 #define BCMA_CHIP_ID_BCM4313	0x4313
--- zfcpdump-kernel-4.4.orig/include/linux/bio.h
+++ zfcpdump-kernel-4.4/include/linux/bio.h
@@ -310,6 +310,38 @@ static inline void bio_clear_flag(struct
 	bio->bi_flags &= ~(1U << bit);
 }
 
+static inline void bio_get_first_bvec(struct bio *bio, struct bio_vec *bv)
+{
+	*bv = bio_iovec(bio);
+}
+
+static inline void bio_get_last_bvec(struct bio *bio, struct bio_vec *bv)
+{
+	struct bvec_iter iter = bio->bi_iter;
+	int idx;
+
+	if (unlikely(!bio_multiple_segments(bio))) {
+		*bv = bio_iovec(bio);
+		return;
+	}
+
+	bio_advance_iter(bio, &iter, iter.bi_size);
+
+	if (!iter.bi_bvec_done)
+		idx = iter.bi_idx - 1;
+	else	/* in the middle of bvec */
+		idx = iter.bi_idx;
+
+	*bv = bio->bi_io_vec[idx];
+
+	/*
+	 * iter.bi_bvec_done records actual length of the last bvec
+	 * if this bio ends in the middle of one io vector
+	 */
+	if (iter.bi_bvec_done)
+		bv->bv_len = iter.bi_bvec_done;
+}
+
 enum bip_flags {
 	BIP_BLOCK_INTEGRITY	= 1 << 0, /* block layer owns integrity data */
 	BIP_MAPPED_INTEGRITY	= 1 << 1, /* ref tag has been remapped */
@@ -318,16 +350,6 @@ enum bip_flags {
 	BIP_IP_CHECKSUM		= 1 << 4, /* IP checksum */
 };
 
-#if defined(CONFIG_BLK_DEV_INTEGRITY)
-
-static inline struct bio_integrity_payload *bio_integrity(struct bio *bio)
-{
-	if (bio->bi_rw & REQ_INTEGRITY)
-		return bio->bi_integrity;
-
-	return NULL;
-}
-
 /*
  * bio integrity payload
  */
@@ -349,6 +371,16 @@ struct bio_integrity_payload {
 	struct bio_vec		bip_inline_vecs[0];/* embedded bvec array */
 };
 
+#if defined(CONFIG_BLK_DEV_INTEGRITY)
+
+static inline struct bio_integrity_payload *bio_integrity(struct bio *bio)
+{
+	if (bio->bi_rw & REQ_INTEGRITY)
+		return bio->bi_integrity;
+
+	return NULL;
+}
+
 static inline bool bio_integrity_flagged(struct bio *bio, enum bip_flags flag)
 {
 	struct bio_integrity_payload *bip = bio_integrity(bio);
@@ -495,11 +527,14 @@ extern unsigned int bvec_nr_vecs(unsigne
 int bio_associate_blkcg(struct bio *bio, struct cgroup_subsys_state *blkcg_css);
 int bio_associate_current(struct bio *bio);
 void bio_disassociate_task(struct bio *bio);
+void bio_clone_blkcg_association(struct bio *dst, struct bio *src);
 #else	/* CONFIG_BLK_CGROUP */
 static inline int bio_associate_blkcg(struct bio *bio,
 			struct cgroup_subsys_state *blkcg_css) { return 0; }
 static inline int bio_associate_current(struct bio *bio) { return -ENOENT; }
 static inline void bio_disassociate_task(struct bio *bio) { }
+static inline void bio_clone_blkcg_association(struct bio *dst,
+			struct bio *src) { }
 #endif	/* CONFIG_BLK_CGROUP */
 
 #ifdef CONFIG_HIGHMEM
@@ -795,6 +830,18 @@ static inline bool bio_integrity_flagged
 	return false;
 }
 
+static inline void *bio_integrity_alloc(struct bio * bio, gfp_t gfp,
+								unsigned int nr)
+{
+	return ERR_PTR(-EINVAL);
+}
+
+static inline int bio_integrity_add_page(struct bio *bio, struct page *page,
+					unsigned int len, unsigned int offset)
+{
+	return 0;
+}
+
 #endif /* CONFIG_BLK_DEV_INTEGRITY */
 
 #endif /* CONFIG_BLOCK */
--- zfcpdump-kernel-4.4.orig/include/linux/bitmap.h
+++ zfcpdump-kernel-4.4/include/linux/bitmap.h
@@ -59,6 +59,8 @@
  * bitmap_find_free_region(bitmap, bits, order)	Find and allocate bit region
  * bitmap_release_region(bitmap, pos, order)	Free specified bit region
  * bitmap_allocate_region(bitmap, pos, order)	Allocate specified bit region
+ * bitmap_from_u32array(dst, nbits, buf, nwords) *dst = *buf (nwords 32b words)
+ * bitmap_to_u32array(buf, nwords, src, nbits)	*buf = *dst (nwords 32b words)
  */
 
 /*
@@ -163,6 +165,14 @@ extern void bitmap_fold(unsigned long *d
 extern int bitmap_find_free_region(unsigned long *bitmap, unsigned int bits, int order);
 extern void bitmap_release_region(unsigned long *bitmap, unsigned int pos, int order);
 extern int bitmap_allocate_region(unsigned long *bitmap, unsigned int pos, int order);
+extern unsigned int bitmap_from_u32array(unsigned long *bitmap,
+					 unsigned int nbits,
+					 const u32 *buf,
+					 unsigned int nwords);
+extern unsigned int bitmap_to_u32array(u32 *buf,
+				       unsigned int nwords,
+				       const unsigned long *bitmap,
+				       unsigned int nbits);
 #ifdef __BIG_ENDIAN
 extern void bitmap_copy_le(unsigned long *dst, const unsigned long *src, unsigned int nbits);
 #else
--- zfcpdump-kernel-4.4.orig/include/linux/blk-mq.h
+++ zfcpdump-kernel-4.4/include/linux/blk-mq.h
@@ -188,8 +188,14 @@ void blk_mq_insert_request(struct reques
 void blk_mq_free_request(struct request *rq);
 void blk_mq_free_hctx_request(struct blk_mq_hw_ctx *, struct request *rq);
 bool blk_mq_can_queue(struct blk_mq_hw_ctx *);
+
+enum {
+	BLK_MQ_REQ_NOWAIT	= (1 << 0), /* return when out of requests */
+	BLK_MQ_REQ_RESERVED	= (1 << 1), /* allocate from reserved pool */
+};
+
 struct request *blk_mq_alloc_request(struct request_queue *q, int rw,
-		gfp_t gfp, bool reserved);
+		unsigned int flags);
 struct request *blk_mq_tag_to_rq(struct blk_mq_tags *tags, unsigned int tag);
 struct cpumask *blk_mq_tags_cpumask(struct blk_mq_tags *tags);
 
@@ -255,22 +261,8 @@ static inline void *blk_mq_rq_to_pdu(str
 	for ((i) = 0; (i) < (q)->nr_hw_queues &&			\
 	     ({ hctx = (q)->queue_hw_ctx[i]; 1; }); (i)++)
 
-#define queue_for_each_ctx(q, ctx, i)					\
-	for ((i) = 0; (i) < (q)->nr_queues &&				\
-	     ({ ctx = per_cpu_ptr((q)->queue_ctx, (i)); 1; }); (i)++)
-
 #define hctx_for_each_ctx(hctx, ctx, i)					\
 	for ((i) = 0; (i) < (hctx)->nr_ctx &&				\
 	     ({ ctx = (hctx)->ctxs[(i)]; 1; }); (i)++)
 
-#define blk_ctx_sum(q, sum)						\
-({									\
-	struct blk_mq_ctx *__x;						\
-	unsigned int __ret = 0, __i;					\
-									\
-	queue_for_each_ctx((q), __x, __i)				\
-		__ret += sum;						\
-	__ret;								\
-})
-
 #endif
--- zfcpdump-kernel-4.4.orig/include/linux/blkdev.h
+++ zfcpdump-kernel-4.4/include/linux/blkdev.h
@@ -408,6 +408,7 @@ struct request_queue {
 
 	unsigned int		rq_timeout;
 	struct timer_list	timeout;
+	struct work_struct	timeout_work;
 	struct list_head	timeout_list;
 
 	struct list_head	icq_list;
@@ -794,7 +795,7 @@ extern int scsi_cmd_ioctl(struct request
 extern int sg_scsi_ioctl(struct request_queue *, struct gendisk *, fmode_t,
 			 struct scsi_ioctl_command __user *);
 
-extern int blk_queue_enter(struct request_queue *q, gfp_t gfp);
+extern int blk_queue_enter(struct request_queue *q, bool nowait);
 extern void blk_queue_exit(struct request_queue *q);
 extern void blk_start_queue(struct request_queue *q);
 extern void blk_start_queue_async(struct request_queue *q);
@@ -890,7 +891,7 @@ static inline unsigned int blk_rq_get_ma
 {
 	struct request_queue *q = rq->q;
 
-	if (unlikely(rq->cmd_type == REQ_TYPE_BLOCK_PC))
+	if (unlikely(rq->cmd_type != REQ_TYPE_FS))
 		return q->limits.max_hw_sectors;
 
 	if (!q->limits.chunk_sectors || (rq->cmd_flags & REQ_DISCARD))
@@ -1367,6 +1368,13 @@ static inline void put_dev_sector(Sector
 	page_cache_release(p.v);
 }
 
+static inline bool __bvec_gap_to_prev(struct request_queue *q,
+				struct bio_vec *bprv, unsigned int offset)
+{
+	return offset ||
+		((bprv->bv_offset + bprv->bv_len) & queue_virt_boundary(q));
+}
+
 /*
  * Check if adding a bio_vec after bprv with offset would create a gap in
  * the SG list. Most drivers don't care about this, but some do.
@@ -1376,18 +1384,22 @@ static inline bool bvec_gap_to_prev(stru
 {
 	if (!queue_virt_boundary(q))
 		return false;
-	return offset ||
-		((bprv->bv_offset + bprv->bv_len) & queue_virt_boundary(q));
+	return __bvec_gap_to_prev(q, bprv, offset);
 }
 
 static inline bool bio_will_gap(struct request_queue *q, struct bio *prev,
 			 struct bio *next)
 {
-	if (!bio_has_data(prev))
-		return false;
+	if (bio_has_data(prev) && queue_virt_boundary(q)) {
+		struct bio_vec pb, nb;
+
+		bio_get_last_bvec(prev, &pb);
+		bio_get_first_bvec(next, &nb);
 
-	return bvec_gap_to_prev(q, &prev->bi_io_vec[prev->bi_vcnt - 1],
-				next->bi_io_vec[0].bv_offset);
+		return __bvec_gap_to_prev(q, &pb, nb.bv_offset);
+	}
+
+	return false;
 }
 
 static inline bool req_gap_back_merge(struct request *req, struct bio *bio)
--- zfcpdump-kernel-4.4.orig/include/linux/bpf.h
+++ zfcpdump-kernel-4.4/include/linux/bpf.h
@@ -165,12 +165,13 @@ void bpf_register_prog_type(struct bpf_p
 void bpf_register_map_type(struct bpf_map_type_list *tl);
 
 struct bpf_prog *bpf_prog_get(u32 ufd);
+struct bpf_prog *bpf_prog_inc(struct bpf_prog *prog);
 void bpf_prog_put(struct bpf_prog *prog);
 void bpf_prog_put_rcu(struct bpf_prog *prog);
 
 struct bpf_map *bpf_map_get_with_uref(u32 ufd);
 struct bpf_map *__bpf_map_get(struct fd f);
-void bpf_map_inc(struct bpf_map *map, bool uref);
+struct bpf_map *bpf_map_inc(struct bpf_map *map, bool uref);
 void bpf_map_put_with_uref(struct bpf_map *map);
 void bpf_map_put(struct bpf_map *map);
 
@@ -197,6 +198,10 @@ static inline struct bpf_prog *bpf_prog_
 static inline void bpf_prog_put(struct bpf_prog *prog)
 {
 }
+
+static inline void bpf_prog_put_rcu(struct bpf_prog *prog)
+{
+}
 #endif /* CONFIG_BPF_SYSCALL */
 
 /* verifier prototypes for helper functions called from eBPF programs */
--- zfcpdump-kernel-4.4.orig/include/linux/can/dev.h
+++ zfcpdump-kernel-4.4/include/linux/can/dev.h
@@ -32,6 +32,7 @@ enum can_mode {
  * CAN common private data
  */
 struct can_priv {
+	struct net_device *dev;
 	struct can_device_stats can_stats;
 
 	struct can_bittiming bittiming, data_bittiming;
@@ -40,11 +41,14 @@ struct can_priv {
 	struct can_clock clock;
 
 	enum can_state state;
-	u32 ctrlmode;
-	u32 ctrlmode_supported;
+
+	/* CAN controller features - see include/uapi/linux/can/netlink.h */
+	u32 ctrlmode;		/* current options setting */
+	u32 ctrlmode_supported;	/* options that can be modified by netlink */
+	u32 ctrlmode_static;	/* static enabled options for driver/hardware */
 
 	int restart_ms;
-	struct timer_list restart_timer;
+	struct delayed_work restart_work;
 
 	int (*do_set_bittiming)(struct net_device *dev);
 	int (*do_set_data_bittiming)(struct net_device *dev);
@@ -108,6 +112,21 @@ static inline bool can_is_canfd_skb(cons
 	return skb->len == CANFD_MTU;
 }
 
+/* helper to define static CAN controller features at device creation time */
+static inline void can_set_static_ctrlmode(struct net_device *dev,
+					   u32 static_mode)
+{
+	struct can_priv *priv = netdev_priv(dev);
+
+	/* alloc_candev() succeeded => netdev_priv() is valid at this point */
+	priv->ctrlmode = static_mode;
+	priv->ctrlmode_static = static_mode;
+
+	/* override MTU which was set by default in can_setup()? */
+	if (static_mode & CAN_CTRLMODE_FD)
+		dev->mtu = CANFD_MTU;
+}
+
 /* get data length from can_dlc with sanitized can_dlc */
 u8 can_dlc2len(u8 can_dlc);
 
--- zfcpdump-kernel-4.4.orig/include/linux/capability.h
+++ zfcpdump-kernel-4.4/include/linux/capability.h
@@ -214,6 +214,7 @@ extern bool has_ns_capability_noaudit(st
 				      struct user_namespace *ns, int cap);
 extern bool capable(int cap);
 extern bool ns_capable(struct user_namespace *ns, int cap);
+extern bool ns_capable_noaudit(struct user_namespace *ns, int cap);
 #else
 static inline bool has_capability(struct task_struct *t, int cap)
 {
@@ -241,6 +242,10 @@ static inline bool ns_capable(struct use
 {
 	return true;
 }
+static inline bool ns_capable_noaudit(struct user_namespace *ns, int cap)
+{
+	return true;
+}
 #endif /* CONFIG_MULTIUSER */
 extern bool capable_wrt_inode_uidgid(const struct inode *inode, int cap);
 extern bool file_ns_capable(const struct file *file, struct user_namespace *ns, int cap);
--- zfcpdump-kernel-4.4.orig/include/linux/ceph/messenger.h
+++ zfcpdump-kernel-4.4/include/linux/ceph/messenger.h
@@ -220,6 +220,7 @@ struct ceph_connection {
 	struct ceph_entity_addr actual_peer_addr;
 
 	/* message out temps */
+	struct ceph_msg_header out_hdr;
 	struct ceph_msg *out_msg;        /* sending message (== tail of
 					    out_sent) */
 	bool out_msg_done;
@@ -229,7 +230,6 @@ struct ceph_connection {
 	int out_kvec_left;   /* kvec's left in out_kvec */
 	int out_skip;        /* skip this many bytes */
 	int out_kvec_bytes;  /* total bytes left */
-	bool out_kvec_is_msg; /* kvec refers to out_msg */
 	int out_more;        /* there is more data after the kvecs */
 	__le64 out_temp_ack; /* for writing an ack */
 	struct ceph_timespec out_temp_keepalive2; /* for writing keepalive2
--- zfcpdump-kernel-4.4.orig/include/linux/cgroup-defs.h
+++ zfcpdump-kernel-4.4/include/linux/cgroup-defs.h
@@ -133,6 +133,12 @@ struct cgroup_subsys_state {
 	 */
 	u64 serial_nr;
 
+	/*
+	 * Incremented by online self and children.  Used to guarantee that
+	 * parents are not offlined before their children.
+	 */
+	atomic_t online_cnt;
+
 	/* percpu_ref killing and RCU release */
 	struct rcu_head rcu_head;
 	struct work_struct destroy_work;
@@ -210,6 +216,9 @@ struct css_set {
 	/* all css_task_iters currently walking this cset */
 	struct list_head task_iters;
 
+	/* dead and being drained, ignore for migration */
+	bool dead;
+
 	/* For RCU-protected deletion */
 	struct rcu_head rcu_head;
 };
@@ -425,6 +434,7 @@ struct cgroup_subsys {
 	int (*can_attach)(struct cgroup_taskset *tset);
 	void (*cancel_attach)(struct cgroup_taskset *tset);
 	void (*attach)(struct cgroup_taskset *tset);
+	void (*post_attach)(void);
 	int (*can_fork)(struct task_struct *task, void **priv_p);
 	void (*cancel_fork)(struct task_struct *task, void *priv);
 	void (*fork)(struct task_struct *task, void *priv);
--- zfcpdump-kernel-4.4.orig/include/linux/cgroup.h
+++ zfcpdump-kernel-4.4/include/linux/cgroup.h
@@ -17,6 +17,11 @@
 #include <linux/seq_file.h>
 #include <linux/kernfs.h>
 #include <linux/jump_label.h>
+#include <linux/nsproxy.h>
+#include <linux/types.h>
+#include <linux/ns_common.h>
+#include <linux/nsproxy.h>
+#include <linux/user_namespace.h>
 
 #include <linux/cgroup-defs.h>
 
@@ -554,4 +559,48 @@ static inline int cgroup_init(void) { re
 
 #endif /* !CONFIG_CGROUPS */
 
+struct cgroup_namespace {
+	atomic_t		count;
+	struct ns_common	ns;
+	struct user_namespace	*user_ns;
+	struct css_set          *root_cset;
+};
+
+extern struct cgroup_namespace init_cgroup_ns;
+
+#ifdef CONFIG_CGROUPS
+
+void free_cgroup_ns(struct cgroup_namespace *ns);
+
+struct cgroup_namespace *
+copy_cgroup_ns(unsigned long flags, struct user_namespace *user_ns,
+	       struct cgroup_namespace *old_ns);
+
+char *cgroup_path_ns(struct cgroup *cgrp, char *buf, size_t buflen,
+		     struct cgroup_namespace *ns);
+
+#else /* !CONFIG_CGROUPS */
+
+static inline void free_cgroup_ns(struct cgroup_namespace *ns) { }
+static inline struct cgroup_namespace *
+copy_cgroup_ns(unsigned long flags, struct user_namespace *user_ns,
+	       struct cgroup_namespace *old_ns)
+{
+	return old_ns;
+}
+
+#endif /* !CONFIG_CGROUPS */
+
+static inline void get_cgroup_ns(struct cgroup_namespace *ns)
+{
+	if (ns)
+		atomic_inc(&ns->count);
+}
+
+static inline void put_cgroup_ns(struct cgroup_namespace *ns)
+{
+	if (ns && atomic_dec_and_test(&ns->count))
+		free_cgroup_ns(ns);
+}
+
 #endif /* _LINUX_CGROUP_H */
--- zfcpdump-kernel-4.4.orig/include/linux/clk-provider.h
+++ zfcpdump-kernel-4.4/include/linux/clk-provider.h
@@ -384,6 +384,7 @@ struct clk_divider {
 #define CLK_DIVIDER_MAX_AT_ZERO		BIT(6)
 
 extern const struct clk_ops clk_divider_ops;
+extern const struct clk_ops clk_divider_ro_ops;
 
 unsigned long divider_recalc_rate(struct clk_hw *hw, unsigned long parent_rate,
 		unsigned int val, const struct clk_div_table *table,
--- zfcpdump-kernel-4.4.orig/include/linux/compiler-gcc.h
+++ zfcpdump-kernel-4.4/include/linux/compiler-gcc.h
@@ -199,7 +199,7 @@
 #define unreachable() __builtin_unreachable()
 
 /* Mark a function definition as prohibited from being cloned. */
-#define __noclone	__attribute__((__noclone__))
+#define __noclone	__attribute__((__noclone__, __optimize__("no-tracer")))
 
 #endif /* GCC_VERSION >= 40500 */
 
--- zfcpdump-kernel-4.4.orig/include/linux/compiler.h
+++ zfcpdump-kernel-4.4/include/linux/compiler.h
@@ -144,7 +144,7 @@ void ftrace_likely_update(struct ftrace_
  */
 #define if(cond, ...) __trace_if( (cond , ## __VA_ARGS__) )
 #define __trace_if(cond) \
-	if (__builtin_constant_p((cond)) ? !!(cond) :			\
+	if (__builtin_constant_p(!!(cond)) ? !!(cond) :			\
 	({								\
 		int ______r;						\
 		static struct ftrace_branch_data			\
--- zfcpdump-kernel-4.4.orig/include/linux/console.h
+++ zfcpdump-kernel-4.4/include/linux/console.h
@@ -150,6 +150,7 @@ extern int console_trylock(void);
 extern void console_unlock(void);
 extern void console_conditional_schedule(void);
 extern void console_unblank(void);
+extern void console_flush_on_panic(void);
 extern struct tty_driver *console_device(int *);
 extern void console_stop(struct console *);
 extern void console_start(struct console *);
--- zfcpdump-kernel-4.4.orig/include/linux/cred.h
+++ zfcpdump-kernel-4.4/include/linux/cred.h
@@ -166,6 +166,7 @@ extern int commit_creds(struct cred *);
 extern void abort_creds(struct cred *);
 extern const struct cred *override_creds(const struct cred *);
 extern void revert_creds(const struct cred *);
+extern struct cred *clone_cred(const struct cred *old);
 extern struct cred *prepare_kernel_cred(struct task_struct *);
 extern int change_create_files_as(struct cred *, struct inode *);
 extern int set_security_override(struct cred *, u32);
--- zfcpdump-kernel-4.4.orig/include/linux/dcache.h
+++ zfcpdump-kernel-4.4/include/linux/dcache.h
@@ -161,6 +161,7 @@ struct dentry_operations {
 	struct vfsmount *(*d_automount)(struct path *);
 	int (*d_manage)(struct dentry *, bool);
 	struct inode *(*d_select_inode)(struct dentry *, unsigned);
+	struct dentry *(*d_real)(struct dentry *, struct inode *);
 } ____cacheline_aligned;
 
 /*
@@ -227,6 +228,7 @@ struct dentry_operations {
 #define DCACHE_MAY_FREE			0x00800000
 #define DCACHE_FALLTHRU			0x01000000 /* Fall through to lower layer */
 #define DCACHE_OP_SELECT_INODE		0x02000000 /* Unioned entry: dcache op selects inode */
+#define DCACHE_OP_REAL			0x08000000
 
 extern seqlock_t rename_lock;
 
@@ -409,9 +411,7 @@ static inline bool d_mountpoint(const st
  */
 static inline unsigned __d_entry_type(const struct dentry *dentry)
 {
-	unsigned type = READ_ONCE(dentry->d_flags);
-	smp_rmb();
-	return type & DCACHE_ENTRY_TYPE;
+	return dentry->d_flags & DCACHE_ENTRY_TYPE;
 }
 
 static inline bool d_is_miss(const struct dentry *dentry)
@@ -584,4 +584,36 @@ static inline struct dentry *d_backing_d
 	return upper;
 }
 
+static inline struct dentry *d_real(struct dentry *dentry)
+{
+	if (unlikely(dentry->d_flags & DCACHE_OP_REAL))
+		return dentry->d_op->d_real(dentry, NULL);
+	else
+		return dentry;
+}
+
+static inline struct inode *vfs_select_inode(struct dentry *dentry,
+					     unsigned open_flags)
+{
+	struct inode *inode = d_inode(dentry);
+
+	if (inode && unlikely(dentry->d_flags & DCACHE_OP_SELECT_INODE))
+		inode = dentry->d_op->d_select_inode(dentry, open_flags);
+
+	return inode;
+}
+
+/**
+ * d_real_inode - Return the real inode
+ * @dentry: The dentry to query
+ *
+ * If dentry is on an union/overlay, then return the underlying, real inode.
+ * Otherwise return d_inode().
+ */
+static inline struct inode *d_real_inode(struct dentry *dentry)
+{
+	return d_backing_inode(d_real(dentry));
+}
+
+
 #endif	/* __LINUX_DCACHE_H */
--- zfcpdump-kernel-4.4.orig/include/linux/device-mapper.h
+++ zfcpdump-kernel-4.4/include/linux/device-mapper.h
@@ -124,6 +124,8 @@ struct dm_dev {
 	char name[16];
 };
 
+dev_t dm_get_dev_t(const char *path);
+
 /*
  * Constructors should call these functions to ensure destination devices
  * are opened/closed correctly.
--- zfcpdump-kernel-4.4.orig/include/linux/devpts_fs.h
+++ zfcpdump-kernel-4.4/include/linux/devpts_fs.h
@@ -15,34 +15,24 @@
 
 #include <linux/errno.h>
 
+struct pts_fs_info;
+
 #ifdef CONFIG_UNIX98_PTYS
 
-int devpts_new_index(struct inode *ptmx_inode);
-void devpts_kill_index(struct inode *ptmx_inode, int idx);
+/* Look up a pts fs info and get a ref to it */
+struct pts_fs_info *devpts_get_ref(struct inode *, struct file *);
+void devpts_put_ref(struct pts_fs_info *);
+
+int devpts_new_index(struct pts_fs_info *);
+void devpts_kill_index(struct pts_fs_info *, int);
+
 /* mknod in devpts */
-struct inode *devpts_pty_new(struct inode *ptmx_inode, dev_t device, int index,
-		void *priv);
+struct inode *devpts_pty_new(struct pts_fs_info *, dev_t, int, void *);
 /* get private structure */
 void *devpts_get_priv(struct inode *pts_inode);
 /* unlink */
 void devpts_pty_kill(struct inode *inode);
 
-#else
-
-/* Dummy stubs in the no-pty case */
-static inline int devpts_new_index(struct inode *ptmx_inode) { return -EINVAL; }
-static inline void devpts_kill_index(struct inode *ptmx_inode, int idx) { }
-static inline struct inode *devpts_pty_new(struct inode *ptmx_inode,
-		dev_t device, int index, void *priv)
-{
-	return ERR_PTR(-EINVAL);
-}
-static inline void *devpts_get_priv(struct inode *pts_inode)
-{
-	return NULL;
-}
-static inline void devpts_pty_kill(struct inode *inode) { }
-
 #endif
 
 
--- zfcpdump-kernel-4.4.orig/include/linux/dqblk_qtree.h
+++ zfcpdump-kernel-4.4/include/linux/dqblk_qtree.h
@@ -18,8 +18,8 @@ struct dquot;
 
 /* Operations */
 struct qtree_fmt_operations {
-	void (*mem2disk_dqblk)(void *disk, struct dquot *dquot);	/* Convert given entry from in memory format to disk one */
-	void (*disk2mem_dqblk)(struct dquot *dquot, void *disk);	/* Convert given entry from disk format to in memory one */
+	int (*mem2disk_dqblk)(void *disk, struct dquot *dquot);	/* Convert given entry from in memory format to disk one */
+	int (*disk2mem_dqblk)(struct dquot *dquot, void *disk);	/* Convert given entry from disk format to in memory one */
 	int (*is_id)(void *disk, struct dquot *dquot);	/* Is this structure for given id? */
 };
 
--- zfcpdump-kernel-4.4.orig/include/linux/edac.h
+++ zfcpdump-kernel-4.4/include/linux/edac.h
@@ -237,8 +237,10 @@ enum mem_type {
 #define MEM_FLAG_FB_DDR2        BIT(MEM_FB_DDR2)
 #define MEM_FLAG_RDDR2          BIT(MEM_RDDR2)
 #define MEM_FLAG_XDR            BIT(MEM_XDR)
-#define MEM_FLAG_DDR3		 BIT(MEM_DDR3)
-#define MEM_FLAG_RDDR3		 BIT(MEM_RDDR3)
+#define MEM_FLAG_DDR3           BIT(MEM_DDR3)
+#define MEM_FLAG_RDDR3          BIT(MEM_RDDR3)
+#define MEM_FLAG_DDR4           BIT(MEM_DDR4)
+#define MEM_FLAG_RDDR4          BIT(MEM_RDDR4)
 
 /**
  * enum edac-type - Error Detection and Correction capabilities and mode
--- zfcpdump-kernel-4.4.orig/include/linux/efi.h
+++ zfcpdump-kernel-4.4/include/linux/efi.h
@@ -97,6 +97,7 @@ typedef	struct {
 #define EFI_MEMORY_WP		((u64)0x0000000000001000ULL)	/* write-protect */
 #define EFI_MEMORY_RP		((u64)0x0000000000002000ULL)	/* read-protect */
 #define EFI_MEMORY_XP		((u64)0x0000000000004000ULL)	/* execute-protect */
+#define EFI_MEMORY_NV		((u64)0x0000000000008000ULL)	/* non-volatile */
 #define EFI_MEMORY_MORE_RELIABLE \
 				((u64)0x0000000000010000ULL)	/* higher reliability */
 #define EFI_MEMORY_RO		((u64)0x0000000000020000ULL)	/* read-only */
@@ -299,7 +300,7 @@ typedef struct {
 	void *open_protocol_information;
 	void *protocols_per_handle;
 	void *locate_handle_buffer;
-	void *locate_protocol;
+	efi_status_t (*locate_protocol)(efi_guid_t *, void *, void **);
 	void *install_multiple_protocol_interfaces;
 	void *uninstall_multiple_protocol_interfaces;
 	void *calculate_crc32;
@@ -507,10 +508,6 @@ typedef efi_status_t efi_get_next_variab
 typedef efi_status_t efi_set_variable_t (efi_char16_t *name, efi_guid_t *vendor, 
 					 u32 attr, unsigned long data_size,
 					 void *data);
-typedef efi_status_t
-efi_set_variable_nonblocking_t(efi_char16_t *name, efi_guid_t *vendor,
-			       u32 attr, unsigned long data_size, void *data);
-
 typedef efi_status_t efi_get_next_high_mono_count_t (u32 *count);
 typedef void efi_reset_system_t (int reset_type, efi_status_t status,
 				 unsigned long data_size, efi_char16_t *data);
@@ -529,7 +526,9 @@ typedef efi_status_t efi_query_capsule_c
 					      unsigned long count,
 					      u64 *max_size,
 					      int *reset_type);
-typedef efi_status_t efi_query_variable_store_t(u32 attributes, unsigned long size);
+typedef efi_status_t efi_query_variable_store_t(u32 attributes,
+						unsigned long size,
+						bool nonblocking);
 
 void efi_native_runtime_setup(void);
 
@@ -537,73 +536,110 @@ void efi_native_runtime_setup(void);
  *  EFI Configuration Table and GUID definitions
  */
 #define NULL_GUID \
-    EFI_GUID(  0x00000000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 )
+	EFI_GUID(0x00000000, 0x0000, 0x0000, \
+		 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00)
 
 #define MPS_TABLE_GUID    \
-    EFI_GUID(  0xeb9d2d2f, 0x2d88, 0x11d3, 0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d )
+	EFI_GUID(0xeb9d2d2f, 0x2d88, 0x11d3, \
+		 0x9a, 0x16, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d)
 
 #define ACPI_TABLE_GUID    \
-    EFI_GUID(  0xeb9d2d30, 0x2d88, 0x11d3, 0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d )
+	EFI_GUID(0xeb9d2d30, 0x2d88, 0x11d3, \
+		 0x9a, 0x16, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d)
 
 #define ACPI_20_TABLE_GUID    \
-    EFI_GUID(  0x8868e871, 0xe4f1, 0x11d3, 0xbc, 0x22, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81 )
+	EFI_GUID(0x8868e871, 0xe4f1, 0x11d3, \
+		 0xbc, 0x22, 0x00, 0x80, 0xc7, 0x3c, 0x88, 0x81)
 
 #define SMBIOS_TABLE_GUID    \
-    EFI_GUID(  0xeb9d2d31, 0x2d88, 0x11d3, 0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d )
+	EFI_GUID(0xeb9d2d31, 0x2d88, 0x11d3, \
+		 0x9a, 0x16, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d)
 
 #define SMBIOS3_TABLE_GUID    \
-    EFI_GUID(  0xf2fd1544, 0x9794, 0x4a2c, 0x99, 0x2e, 0xe5, 0xbb, 0xcf, 0x20, 0xe3, 0x94 )
+	EFI_GUID(0xf2fd1544, 0x9794, 0x4a2c, \
+		 0x99, 0x2e, 0xe5, 0xbb, 0xcf, 0x20, 0xe3, 0x94)
 
 #define SAL_SYSTEM_TABLE_GUID    \
-    EFI_GUID(  0xeb9d2d32, 0x2d88, 0x11d3, 0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d )
+	EFI_GUID(0xeb9d2d32, 0x2d88, 0x11d3, \
+		 0x9a, 0x16, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d)
 
 #define HCDP_TABLE_GUID	\
-    EFI_GUID(  0xf951938d, 0x620b, 0x42ef, 0x82, 0x79, 0xa8, 0x4b, 0x79, 0x61, 0x78, 0x98 )
+	EFI_GUID(0xf951938d, 0x620b, 0x42ef, \
+		 0x82, 0x79, 0xa8, 0x4b, 0x79, 0x61, 0x78, 0x98)
 
 #define UGA_IO_PROTOCOL_GUID \
-    EFI_GUID(  0x61a4d49e, 0x6f68, 0x4f1b, 0xb9, 0x22, 0xa8, 0x6e, 0xed, 0xb, 0x7, 0xa2 )
+	EFI_GUID(0x61a4d49e, 0x6f68, 0x4f1b, \
+		 0xb9, 0x22, 0xa8, 0x6e, 0xed, 0x0b, 0x07, 0xa2)
 
 #define EFI_GLOBAL_VARIABLE_GUID \
-    EFI_GUID(  0x8be4df61, 0x93ca, 0x11d2, 0xaa, 0x0d, 0x00, 0xe0, 0x98, 0x03, 0x2b, 0x8c )
+	EFI_GUID(0x8be4df61, 0x93ca, 0x11d2, \
+		 0xaa, 0x0d, 0x00, 0xe0, 0x98, 0x03, 0x2b, 0x8c)
 
 #define UV_SYSTEM_TABLE_GUID \
-    EFI_GUID(  0x3b13a7d4, 0x633e, 0x11dd, 0x93, 0xec, 0xda, 0x25, 0x56, 0xd8, 0x95, 0x93 )
+	EFI_GUID(0x3b13a7d4, 0x633e, 0x11dd, \
+		 0x93, 0xec, 0xda, 0x25, 0x56, 0xd8, 0x95, 0x93)
 
 #define LINUX_EFI_CRASH_GUID \
-    EFI_GUID(  0xcfc8fc79, 0xbe2e, 0x4ddc, 0x97, 0xf0, 0x9f, 0x98, 0xbf, 0xe2, 0x98, 0xa0 )
+	EFI_GUID(0xcfc8fc79, 0xbe2e, 0x4ddc, \
+		 0x97, 0xf0, 0x9f, 0x98, 0xbf, 0xe2, 0x98, 0xa0)
 
 #define LOADED_IMAGE_PROTOCOL_GUID \
-    EFI_GUID(  0x5b1b31a1, 0x9562, 0x11d2, 0x8e, 0x3f, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b )
+	EFI_GUID(0x5b1b31a1, 0x9562, 0x11d2, \
+		 0x8e, 0x3f, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b)
 
 #define EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID \
-    EFI_GUID(  0x9042a9de, 0x23dc, 0x4a38, 0x96, 0xfb, 0x7a, 0xde, 0xd0, 0x80, 0x51, 0x6a )
+	EFI_GUID(0x9042a9de, 0x23dc, 0x4a38, \
+		 0x96, 0xfb, 0x7a, 0xde, 0xd0, 0x80, 0x51, 0x6a)
 
 #define EFI_UGA_PROTOCOL_GUID \
-    EFI_GUID(  0x982c298b, 0xf4fa, 0x41cb, 0xb8, 0x38, 0x77, 0xaa, 0x68, 0x8f, 0xb8, 0x39 )
+	EFI_GUID(0x982c298b, 0xf4fa, 0x41cb, \
+		 0xb8, 0x38, 0x77, 0xaa, 0x68, 0x8f, 0xb8, 0x39)
 
 #define EFI_PCI_IO_PROTOCOL_GUID \
-    EFI_GUID(  0x4cf5b200, 0x68b8, 0x4ca5, 0x9e, 0xec, 0xb2, 0x3e, 0x3f, 0x50, 0x2, 0x9a )
+	EFI_GUID(0x4cf5b200, 0x68b8, 0x4ca5, \
+		 0x9e, 0xec, 0xb2, 0x3e, 0x3f, 0x50, 0x02, 0x9a)
 
 #define EFI_FILE_INFO_ID \
-    EFI_GUID(  0x9576e92, 0x6d3f, 0x11d2, 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b )
+	EFI_GUID(0x9576e92, 0x6d3f, 0x11d2, \
+		 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b)
 
 #define EFI_SYSTEM_RESOURCE_TABLE_GUID \
-    EFI_GUID(  0xb122a263, 0x3661, 0x4f68, 0x99, 0x29, 0x78, 0xf8, 0xb0, 0xd6, 0x21, 0x80 )
+	EFI_GUID(0xb122a263, 0x3661, 0x4f68, \
+		 0x99, 0x29, 0x78, 0xf8, 0xb0, 0xd6, 0x21, 0x80)
 
 #define EFI_FILE_SYSTEM_GUID \
-    EFI_GUID(  0x964e5b22, 0x6459, 0x11d2, 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b )
+	EFI_GUID(0x964e5b22, 0x6459, 0x11d2, \
+		 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b)
 
 #define DEVICE_TREE_GUID \
-    EFI_GUID(  0xb1b621d5, 0xf19c, 0x41a5, 0x83, 0x0b, 0xd9, 0x15, 0x2c, 0x69, 0xaa, 0xe0 )
+	EFI_GUID(0xb1b621d5, 0xf19c, 0x41a5, \
+		 0x83, 0x0b, 0xd9, 0x15, 0x2c, 0x69, 0xaa, 0xe0)
 
 #define EFI_PROPERTIES_TABLE_GUID \
-    EFI_GUID(  0x880aaca3, 0x4adc, 0x4a04, 0x90, 0x79, 0xb7, 0x47, 0x34, 0x08, 0x25, 0xe5 )
+	EFI_GUID(0x880aaca3, 0x4adc, 0x4a04, \
+		 0x90, 0x79, 0xb7, 0x47, 0x34, 0x08, 0x25, 0xe5)
+
+#define EFI_RNG_PROTOCOL_GUID \
+	EFI_GUID(0x3152bca5, 0xeade, 0x433d, \
+		 0x86, 0x2e, 0xc0, 0x1c, 0xdc, 0x29, 0x1f, 0x44)
+
+#define EFI_CERT_SHA256_GUID \
+    EFI_GUID(  0xc1c41626, 0x504c, 0x4092, 0xac, 0xa9, 0x41, 0xf9, 0x36, 0x93, 0x43, 0x28 )
+
+#define EFI_CERT_X509_GUID \
+    EFI_GUID(  0xa5c059a1, 0x94e4, 0x4aa7, 0x87, 0xb5, 0xab, 0x15, 0x5c, 0x2b, 0xf0, 0x72 )
 
 typedef struct {
 	efi_guid_t guid;
 	u64 table;
 } efi_config_table_64_t;
 
+#define EFI_IMAGE_SECURITY_DATABASE_GUID \
+    EFI_GUID(  0xd719b2cb, 0x3d3a, 0x4596, 0xa3, 0xbc, 0xda, 0xd0, 0x0e, 0x67, 0x65, 0x6f )
+
+#define EFI_SHIM_LOCK_GUID \
+    EFI_GUID(  0x605dab50, 0xe046, 0x4300, 0xab, 0xb6, 0x3d, 0xd8, 0x10, 0xdd, 0x8b, 0x23 )
+
 typedef struct {
 	efi_guid_t guid;
 	u32 table;
@@ -823,6 +859,20 @@ typedef struct {
 
 #define EFI_INVALID_TABLE_ADDR		(~0UL)
 
+typedef struct  {
+	efi_guid_t signature_owner;
+	u8 signature_data[];
+} efi_signature_data_t;
+
+typedef struct {
+	efi_guid_t signature_type;
+	u32 signature_list_size;
+	u32 signature_header_size;
+	u32 signature_size;
+	u8 signature_header[];
+	/* efi_signature_data_t signatures[][] */
+} efi_signature_list_t;
+
 /*
  * All runtime access to EFI goes through this structure:
  */
@@ -851,8 +901,9 @@ extern struct efi {
 	efi_get_variable_t *get_variable;
 	efi_get_next_variable_t *get_next_variable;
 	efi_set_variable_t *set_variable;
-	efi_set_variable_nonblocking_t *set_variable_nonblocking;
+	efi_set_variable_t *set_variable_nonblocking;
 	efi_query_variable_info_t *query_variable_info;
+	efi_query_variable_info_t *query_variable_info_nonblocking;
 	efi_update_capsule_t *update_capsule;
 	efi_query_capsule_caps_t *query_capsule_caps;
 	efi_get_next_high_mono_count_t *get_next_high_mono_count;
@@ -884,13 +935,17 @@ extern void efi_enter_virtual_mode (void
 #ifdef CONFIG_X86
 extern void efi_late_init(void);
 extern void efi_free_boot_services(void);
-extern efi_status_t efi_query_variable_store(u32 attributes, unsigned long size);
+extern efi_status_t efi_query_variable_store(u32 attributes,
+					     unsigned long size,
+					     bool nonblocking);
 extern void efi_find_mirror(void);
 #else
 static inline void efi_late_init(void) {}
 static inline void efi_free_boot_services(void) {}
 
-static inline efi_status_t efi_query_variable_store(u32 attributes, unsigned long size)
+static inline efi_status_t efi_query_variable_store(u32 attributes,
+						    unsigned long size,
+						    bool nonblocking)
 {
 	return EFI_SUCCESS;
 }
@@ -941,6 +996,10 @@ static inline void efi_fake_memmap(void)
 char * __init efi_md_typeattr_format(char *buf, size_t size,
 				     const efi_memory_desc_t *md);
 
+struct key;
+extern int __init parse_efi_signature_list(const void *data, size_t size,
+					   struct key *keyring);
+
 /**
  * efi_range_is_wc - check the WC bit on an address range
  * @start: starting kvirt address
@@ -980,6 +1039,8 @@ extern int __init efi_setup_pcdp_console
 #define EFI_ARCH_1		7	/* First arch-specific bit */
 #define EFI_DBG			8	/* Print additional debug info at runtime */
 #define EFI_NX_PE_DATA		9	/* Can runtime data regions be mapped non-executable? */
+#define EFI_SECURE_BOOT		10	/* Are we in Secure Boot mode? */
+#define EFI_MOKSBSTATE_DISABLED	11	/* Secure boot mode disabled in the MOK */
 
 #ifdef CONFIG_EFI
 /*
@@ -1091,7 +1152,7 @@ struct efivar_operations {
 	efi_get_variable_t *get_variable;
 	efi_get_next_variable_t *get_next_variable;
 	efi_set_variable_t *set_variable;
-	efi_set_variable_nonblocking_t *set_variable_nonblocking;
+	efi_set_variable_t *set_variable_nonblocking;
 	efi_query_variable_store_t *query_variable_store;
 };
 
@@ -1199,7 +1260,10 @@ int efivar_entry_iter(int (*func)(struct
 struct efivar_entry *efivar_entry_find(efi_char16_t *name, efi_guid_t guid,
 				       struct list_head *head, bool remove);
 
-bool efivar_validate(efi_char16_t *var_name, u8 *data, unsigned long len);
+bool efivar_validate(efi_guid_t vendor, efi_char16_t *var_name, u8 *data,
+		     unsigned long data_size);
+bool efivar_variable_is_removable(efi_guid_t vendor, const char *name,
+				  size_t len);
 
 extern struct work_struct efivar_work;
 void efivar_run_worker(void);
--- zfcpdump-kernel-4.4.orig/include/linux/etherdevice.h
+++ zfcpdump-kernel-4.4/include/linux/etherdevice.h
@@ -29,6 +29,9 @@
 #include <asm/bitsperlong.h>
 
 #ifdef __KERNEL__
+struct device;
+int eth_platform_get_mac_address(struct device *dev, u8 *mac_addr);
+unsigned char *arch_get_platform_get_mac_address(void);
 u32 eth_get_headlen(void *data, unsigned int max_len);
 __be16 eth_type_trans(struct sk_buff *skb, struct net_device *dev);
 extern const struct header_ops eth_header_ops;
--- zfcpdump-kernel-4.4.orig/include/linux/ethtool.h
+++ zfcpdump-kernel-4.4/include/linux/ethtool.h
@@ -12,6 +12,7 @@
 #ifndef _LINUX_ETHTOOL_H
 #define _LINUX_ETHTOOL_H
 
+#include <linux/bitmap.h>
 #include <linux/compat.h>
 #include <uapi/linux/ethtool.h>
 
@@ -40,9 +41,6 @@ struct compat_ethtool_rxnfc {
 
 #include <linux/rculist.h>
 
-extern int __ethtool_get_settings(struct net_device *dev,
-				  struct ethtool_cmd *cmd);
-
 /**
  * enum ethtool_phys_id_state - indicator state for physical identification
  * @ETHTOOL_ID_INACTIVE: Physical ID indicator should be deactivated
@@ -97,13 +95,74 @@ static inline u32 ethtool_rxfh_indir_def
 	return index % n_rx_rings;
 }
 
+/* number of link mode bits/ulongs handled internally by kernel */
+#define __ETHTOOL_LINK_MODE_MASK_NBITS			\
+	(__ETHTOOL_LINK_MODE_LAST + 1)
+
+/* declare a link mode bitmap */
+#define __ETHTOOL_DECLARE_LINK_MODE_MASK(name)		\
+	DECLARE_BITMAP(name, __ETHTOOL_LINK_MODE_MASK_NBITS)
+
+/* drivers must ignore base.cmd and base.link_mode_masks_nwords
+ * fields, but they are allowed to overwrite them (will be ignored).
+ */
+struct ethtool_link_ksettings {
+	struct ethtool_link_settings base;
+	struct {
+		__ETHTOOL_DECLARE_LINK_MODE_MASK(supported);
+		__ETHTOOL_DECLARE_LINK_MODE_MASK(advertising);
+		__ETHTOOL_DECLARE_LINK_MODE_MASK(lp_advertising);
+	} link_modes;
+};
+
+/**
+ * ethtool_link_ksettings_zero_link_mode - clear link_ksettings link mode mask
+ *   @ptr : pointer to struct ethtool_link_ksettings
+ *   @name : one of supported/advertising/lp_advertising
+ */
+#define ethtool_link_ksettings_zero_link_mode(ptr, name)		\
+	bitmap_zero((ptr)->link_modes.name, __ETHTOOL_LINK_MODE_MASK_NBITS)
+
+/**
+ * ethtool_link_ksettings_add_link_mode - set bit in link_ksettings
+ * link mode mask
+ *   @ptr : pointer to struct ethtool_link_ksettings
+ *   @name : one of supported/advertising/lp_advertising
+ *   @mode : one of the ETHTOOL_LINK_MODE_*_BIT
+ * (not atomic, no bound checking)
+ */
+#define ethtool_link_ksettings_add_link_mode(ptr, name, mode)		\
+	__set_bit(ETHTOOL_LINK_MODE_ ## mode ## _BIT, (ptr)->link_modes.name)
+
+/**
+ * ethtool_link_ksettings_test_link_mode - test bit in ksettings link mode mask
+ *   @ptr : pointer to struct ethtool_link_ksettings
+ *   @name : one of supported/advertising/lp_advertising
+ *   @mode : one of the ETHTOOL_LINK_MODE_*_BIT
+ * (not atomic, no bound checking)
+ *
+ * Returns true/false.
+ */
+#define ethtool_link_ksettings_test_link_mode(ptr, name, mode)		\
+	test_bit(ETHTOOL_LINK_MODE_ ## mode ## _BIT, (ptr)->link_modes.name)
+
+extern int
+__ethtool_get_link_ksettings(struct net_device *dev,
+			     struct ethtool_link_ksettings *link_ksettings);
+
+/* DEPRECATED, use __ethtool_get_link_ksettings */
+extern int __ethtool_get_settings(struct net_device *dev,
+				  struct ethtool_cmd *cmd);
+
 /**
  * struct ethtool_ops - optional netdev operations
- * @get_settings: Get various device settings including Ethernet link
+ * @get_settings: DEPRECATED, use %get_link_ksettings/%set_link_ksettings
+ *	API. Get various device settings including Ethernet link
  *	settings. The @cmd parameter is expected to have been cleared
- *	before get_settings is called. Returns a negative error code or
- *	zero.
- * @set_settings: Set various device settings including Ethernet link
+ *	before get_settings is called. Returns a negative error code
+ *	or zero.
+ * @set_settings: DEPRECATED, use %get_link_ksettings/%set_link_ksettings
+ *	API. Set various device settings including Ethernet link
  *	settings.  Returns a negative error code or zero.
  * @get_drvinfo: Report driver/device information.  Should only set the
  *	@driver, @version, @fw_version and @bus_info fields.  If not
@@ -201,6 +260,19 @@ static inline u32 ethtool_rxfh_indir_def
  * @get_module_eeprom: Get the eeprom information from the plug-in module
  * @get_eee: Get Energy-Efficient (EEE) supported and status.
  * @set_eee: Set EEE status (enable/disable) as well as LPI timers.
+ * @get_link_ksettings: When defined, takes precedence over the
+ *	%get_settings method. Get various device settings
+ *	including Ethernet link settings. The %cmd and
+ *	%link_mode_masks_nwords fields should be ignored (use
+ *	%__ETHTOOL_LINK_MODE_MASK_NBITS instead of the latter), any
+ *	change to them will be overwritten by kernel. Returns a
+ *	negative error code or zero.
+ * @set_link_ksettings: When defined, takes precedence over the
+ *	%set_settings method. Set various device settings including
+ *	Ethernet link settings. The %cmd and %link_mode_masks_nwords
+ *	fields should be ignored (use %__ETHTOOL_LINK_MODE_MASK_NBITS
+ *	instead of the latter), any change to them will be overwritten
+ *	by kernel. Returns a negative error code or zero.
  *
  * All operations are optional (i.e. the function pointer may be set
  * to %NULL) and callers must take this into account.  Callers must
@@ -279,7 +351,9 @@ struct ethtool_ops {
 			       const struct ethtool_tunable *, void *);
 	int	(*set_tunable)(struct net_device *,
 			       const struct ethtool_tunable *, const void *);
-
-
+	int	(*get_link_ksettings)(struct net_device *,
+				      struct ethtool_link_ksettings *);
+	int	(*set_link_ksettings)(struct net_device *,
+				      const struct ethtool_link_ksettings *);
 };
 #endif /* _LINUX_ETHTOOL_H */
--- zfcpdump-kernel-4.4.orig/include/linux/file.h
+++ zfcpdump-kernel-4.4/include/linux/file.h
@@ -19,6 +19,7 @@ struct dentry;
 struct path;
 extern struct file *alloc_file(struct path *, fmode_t mode,
 	const struct file_operations *fop);
+extern struct file *get_empty_filp(void);
 
 static inline void fput_light(struct file *file, int fput_needed)
 {
--- zfcpdump-kernel-4.4.orig/include/linux/filter.h
+++ zfcpdump-kernel-4.4/include/linux/filter.h
@@ -446,8 +446,12 @@ int bpf_prog_create_from_user(struct bpf
 void bpf_prog_destroy(struct bpf_prog *fp);
 
 int sk_attach_filter(struct sock_fprog *fprog, struct sock *sk);
+int __sk_attach_filter(struct sock_fprog *fprog, struct sock *sk,
+		       bool locked);
 int sk_attach_bpf(u32 ufd, struct sock *sk);
 int sk_detach_filter(struct sock *sk);
+int __sk_detach_filter(struct sock *sk, bool locked);
+
 int sk_get_filter(struct sock *sk, struct sock_filter __user *filter,
 		  unsigned int len);
 
--- zfcpdump-kernel-4.4.orig/include/linux/fs.h
+++ zfcpdump-kernel-4.4/include/linux/fs.h
@@ -710,6 +710,31 @@ enum inode_i_mutex_lock_class
 	I_MUTEX_PARENT2,
 };
 
+static inline void inode_lock(struct inode *inode)
+{
+	mutex_lock(&inode->i_mutex);
+}
+
+static inline void inode_unlock(struct inode *inode)
+{
+	mutex_unlock(&inode->i_mutex);
+}
+
+static inline int inode_trylock(struct inode *inode)
+{
+	return mutex_trylock(&inode->i_mutex);
+}
+
+static inline int inode_is_locked(struct inode *inode)
+{
+	return mutex_is_locked(&inode->i_mutex);
+}
+
+static inline void inode_lock_nested(struct inode *inode, unsigned subclass)
+{
+	mutex_lock_nested(&inode->i_mutex, subclass);
+}
+
 void lock_two_nondirectories(struct inode *, struct inode*);
 void unlock_two_nondirectories(struct inode *, struct inode*);
 
@@ -768,31 +793,6 @@ static inline void i_size_write(struct i
 #endif
 }
 
-/* Helper functions so that in most cases filesystems will
- * not need to deal directly with kuid_t and kgid_t and can
- * instead deal with the raw numeric values that are stored
- * in the filesystem.
- */
-static inline uid_t i_uid_read(const struct inode *inode)
-{
-	return from_kuid(&init_user_ns, inode->i_uid);
-}
-
-static inline gid_t i_gid_read(const struct inode *inode)
-{
-	return from_kgid(&init_user_ns, inode->i_gid);
-}
-
-static inline void i_uid_write(struct inode *inode, uid_t uid)
-{
-	inode->i_uid = make_kuid(&init_user_ns, uid);
-}
-
-static inline void i_gid_write(struct inode *inode, gid_t gid)
-{
-	inode->i_gid = make_kgid(&init_user_ns, gid);
-}
-
 static inline unsigned iminor(const struct inode *inode)
 {
 	return MINOR(inode->i_rdev);
@@ -1207,6 +1207,16 @@ static inline struct inode *file_inode(c
 	return f->f_inode;
 }
 
+static inline struct dentry *file_dentry(const struct file *file)
+{
+	struct dentry *dentry = file->f_path.dentry;
+
+	if (unlikely(dentry->d_flags & DCACHE_OP_REAL))
+		return dentry->d_op->d_real(dentry, file_inode(file));
+	else
+		return dentry;
+}
+
 static inline int locks_lock_file_wait(struct file *filp, struct file_lock *fl)
 {
 	return locks_lock_inode_wait(file_inode(filp), fl);
@@ -1254,6 +1264,7 @@ struct mm_struct;
 /* sb->s_iflags */
 #define SB_I_CGROUPWB	0x00000001	/* cgroup-aware writeback enabled */
 #define SB_I_NOEXEC	0x00000002	/* Ignore executables on this fs */
+#define SB_I_NOSUID	0x00000004	/* Ignore suid on this fs */
 
 /* Possible states of 'frozen' field */
 enum {
@@ -1355,6 +1366,13 @@ struct super_block {
 	struct hlist_head s_pins;
 
 	/*
+	 * Context in which to interpret filesystem uids, gids,
+	 * quotas, device nodes, extended attributes and security
+	 * labels.
+	 */
+	struct user_namespace *s_user_ns;
+
+	/*
 	 * Keep the lru lists last in the structure so they always sit on their
 	 * own individual cachelines.
 	 */
@@ -1375,6 +1393,31 @@ struct super_block {
 	struct list_head	s_inodes;	/* all inodes */
 };
 
+/* Helper functions so that in most cases filesystems will
+ * not need to deal directly with kuid_t and kgid_t and can
+ * instead deal with the raw numeric values that are stored
+ * in the filesystem.
+ */
+static inline uid_t i_uid_read(const struct inode *inode)
+{
+	return from_kuid_munged(inode->i_sb->s_user_ns, inode->i_uid);
+}
+
+static inline gid_t i_gid_read(const struct inode *inode)
+{
+	return from_kgid_munged(inode->i_sb->s_user_ns, inode->i_gid);
+}
+
+static inline void i_uid_write(struct inode *inode, uid_t uid)
+{
+	inode->i_uid = make_kuid(inode->i_sb->s_user_ns, uid);
+}
+
+static inline void i_gid_write(struct inode *inode, gid_t gid)
+{
+	inode->i_gid = make_kgid(inode->i_sb->s_user_ns, gid);
+}
+
 extern struct timespec current_fs_time(struct super_block *sb);
 
 /*
@@ -1672,6 +1715,12 @@ ssize_t rw_copy_check_uvector(int type,
 			      struct iovec *fast_pointer,
 			      struct iovec **ret_pointer);
 
+typedef ssize_t (*vfs_readf_t)(struct file *, char __user *, size_t, loff_t *);
+typedef ssize_t (*vfs_writef_t)(struct file *, const char __user *, size_t,
+				loff_t *);
+vfs_readf_t vfs_readf(struct file *file);
+vfs_writef_t vfs_writef(struct file *file);
+
 extern ssize_t __vfs_read(struct file *, char __user *, size_t, loff_t *);
 extern ssize_t __vfs_write(struct file *, const char __user *, size_t, loff_t *);
 extern ssize_t vfs_read(struct file *, char __user *, size_t, loff_t *);
@@ -1713,6 +1762,10 @@ struct super_operations {
 				  struct shrink_control *);
 	long (*free_cached_objects)(struct super_block *,
 				    struct shrink_control *);
+#if defined(CONFIG_BLK_DEV_LOOP) ||  defined(CONFIG_BLK_DEV_LOOP_MODULE)
+	/* and aufs */
+	struct file *(*real_loop)(struct file *);
+#endif
 };
 
 /*
@@ -1948,8 +2001,9 @@ struct file_system_type {
 
 #define MODULE_ALIAS_FS(NAME) MODULE_ALIAS("fs-" NAME)
 
-extern struct dentry *mount_ns(struct file_system_type *fs_type, int flags,
-	void *data, int (*fill_super)(struct super_block *, void *, int));
+extern struct dentry *mount_ns(struct file_system_type *fs_type,
+	int flags, void *data, void *ns, struct user_namespace *user_ns,
+	int (*fill_super)(struct super_block *, void *, int));
 extern struct dentry *mount_bdev(struct file_system_type *fs_type,
 	int flags, const char *dev_name, void *data,
 	int (*fill_super)(struct super_block *, void *, int));
@@ -1969,6 +2023,11 @@ void deactivate_locked_super(struct supe
 int set_anon_super(struct super_block *s, void *data);
 int get_anon_bdev(dev_t *);
 void free_anon_bdev(dev_t);
+struct super_block *sget_userns(struct file_system_type *type,
+			int (*test)(struct super_block *,void *),
+			int (*set)(struct super_block *,void *),
+			int flags, struct user_namespace *user_ns,
+			void *data);
 struct super_block *sget(struct file_system_type *type,
 			int (*test)(struct super_block *,void *),
 			int (*set)(struct super_block *,void *),
@@ -2217,7 +2276,7 @@ extern long do_sys_open(int dfd, const c
 extern struct file *file_open_name(struct filename *, int, umode_t);
 extern struct file *filp_open(const char *, int, umode_t);
 extern struct file *file_open_root(struct dentry *, struct vfsmount *,
-				   const char *, int);
+				   const char *, int, umode_t);
 extern struct file * dentry_open(const struct path *, int, const struct cred *);
 extern int filp_close(struct file *, fl_owner_t id);
 
@@ -2360,7 +2419,7 @@ static inline void unregister_chrdev(uns
 #define BLKDEV_MAJOR_HASH_SIZE	255
 extern const char *__bdevname(dev_t, char *buffer);
 extern const char *bdevname(struct block_device *bdev, char *buffer);
-extern struct block_device *lookup_bdev(const char *);
+extern struct block_device *lookup_bdev(const char *, int mask);
 extern void blkdev_show(struct seq_file *,off_t);
 
 #else
@@ -3019,11 +3078,12 @@ static inline bool dir_emit_dots(struct
 }
 static inline bool dir_relax(struct inode *inode)
 {
-	mutex_unlock(&inode->i_mutex);
-	mutex_lock(&inode->i_mutex);
+	inode_unlock(inode);
+	inode_lock(inode);
 	return !IS_DEADDIR(inode);
 }
 
 extern bool path_noexec(const struct path *path);
+extern bool path_nosuid(const struct path *path);
 
 #endif /* _LINUX_FS_H */
--- zfcpdump-kernel-4.4.orig/include/linux/fsnotify_backend.h
+++ zfcpdump-kernel-4.4/include/linux/fsnotify_backend.h
@@ -148,6 +148,7 @@ struct fsnotify_group {
 	#define FS_PRIO_1	1 /* fanotify content based access control */
 	#define FS_PRIO_2	2 /* fanotify pre-content access */
 	unsigned int priority;
+	bool shutdown;		/* group is being shut down, don't queue more events */
 
 	/* stores all fastpath marks assoc with this group so they can be cleaned on unregister */
 	struct mutex mark_mutex;	/* protect marks_list */
@@ -179,7 +180,6 @@ struct fsnotify_group {
 			spinlock_t access_lock;
 			struct list_head access_list;
 			wait_queue_head_t access_waitq;
-			atomic_t bypass_perm;
 #endif /* CONFIG_FANOTIFY_ACCESS_PERMISSIONS */
 			int f_flags;
 			unsigned int max_marks;
@@ -308,6 +308,8 @@ extern struct fsnotify_group *fsnotify_a
 extern void fsnotify_get_group(struct fsnotify_group *group);
 /* drop reference on a group from fsnotify_alloc_group */
 extern void fsnotify_put_group(struct fsnotify_group *group);
+/* group destruction begins, stop queuing new events */
+extern void fsnotify_group_stop_queueing(struct fsnotify_group *group);
 /* destroy group */
 extern void fsnotify_destroy_group(struct fsnotify_group *group);
 /* fasync handler function */
@@ -320,8 +322,6 @@ extern int fsnotify_add_event(struct fsn
 			      struct fsnotify_event *event,
 			      int (*merge)(struct list_head *,
 					   struct fsnotify_event *));
-/* Remove passed event from groups notification queue */
-extern void fsnotify_remove_event(struct fsnotify_group *group, struct fsnotify_event *event);
 /* true if the group notification queue is empty */
 extern bool fsnotify_notify_queue_is_empty(struct fsnotify_group *group);
 /* return, but do not dequeue the first event on the notification queue */
--- zfcpdump-kernel-4.4.orig/include/linux/gfp.h
+++ zfcpdump-kernel-4.4/include/linux/gfp.h
@@ -322,22 +322,29 @@ static inline bool gfpflags_allow_blocki
  *       0xe    => BAD (MOVABLE+DMA32+HIGHMEM)
  *       0xf    => BAD (MOVABLE+DMA32+HIGHMEM+DMA)
  *
- * ZONES_SHIFT must be <= 2 on 32 bit platforms.
+ * GFP_ZONES_SHIFT must be <= 2 on 32 bit platforms.
  */
 
-#if 16 * ZONES_SHIFT > BITS_PER_LONG
-#error ZONES_SHIFT too large to create GFP_ZONE_TABLE integer
+#if defined(CONFIG_ZONE_DEVICE) && (MAX_NR_ZONES-1) <= 4
+/* ZONE_DEVICE is not a valid GFP zone specifier */
+#define GFP_ZONES_SHIFT 2
+#else
+#define GFP_ZONES_SHIFT ZONES_SHIFT
+#endif
+
+#if 16 * GFP_ZONES_SHIFT > BITS_PER_LONG
+#error GFP_ZONES_SHIFT too large to create GFP_ZONE_TABLE integer
 #endif
 
 #define GFP_ZONE_TABLE ( \
-	(ZONE_NORMAL << 0 * ZONES_SHIFT)				      \
-	| (OPT_ZONE_DMA << ___GFP_DMA * ZONES_SHIFT)			      \
-	| (OPT_ZONE_HIGHMEM << ___GFP_HIGHMEM * ZONES_SHIFT)		      \
-	| (OPT_ZONE_DMA32 << ___GFP_DMA32 * ZONES_SHIFT)		      \
-	| (ZONE_NORMAL << ___GFP_MOVABLE * ZONES_SHIFT)			      \
-	| (OPT_ZONE_DMA << (___GFP_MOVABLE | ___GFP_DMA) * ZONES_SHIFT)	      \
-	| (ZONE_MOVABLE << (___GFP_MOVABLE | ___GFP_HIGHMEM) * ZONES_SHIFT)   \
-	| (OPT_ZONE_DMA32 << (___GFP_MOVABLE | ___GFP_DMA32) * ZONES_SHIFT)   \
+	(ZONE_NORMAL << 0 * GFP_ZONES_SHIFT)				       \
+	| (OPT_ZONE_DMA << ___GFP_DMA * GFP_ZONES_SHIFT)		       \
+	| (OPT_ZONE_HIGHMEM << ___GFP_HIGHMEM * GFP_ZONES_SHIFT)	       \
+	| (OPT_ZONE_DMA32 << ___GFP_DMA32 * GFP_ZONES_SHIFT)		       \
+	| (ZONE_NORMAL << ___GFP_MOVABLE * GFP_ZONES_SHIFT)		       \
+	| (OPT_ZONE_DMA << (___GFP_MOVABLE | ___GFP_DMA) * GFP_ZONES_SHIFT)    \
+	| (ZONE_MOVABLE << (___GFP_MOVABLE | ___GFP_HIGHMEM) * GFP_ZONES_SHIFT)\
+	| (OPT_ZONE_DMA32 << (___GFP_MOVABLE | ___GFP_DMA32) * GFP_ZONES_SHIFT)\
 )
 
 /*
@@ -362,8 +369,8 @@ static inline enum zone_type gfp_zone(gf
 	enum zone_type z;
 	int bit = (__force int) (flags & GFP_ZONEMASK);
 
-	z = (GFP_ZONE_TABLE >> (bit * ZONES_SHIFT)) &
-					 ((1 << ZONES_SHIFT) - 1);
+	z = (GFP_ZONE_TABLE >> (bit * GFP_ZONES_SHIFT)) &
+					 ((1 << GFP_ZONES_SHIFT) - 1);
 	VM_BUG_ON((GFP_ZONE_BAD >> bit) & 1);
 	return z;
 }
--- zfcpdump-kernel-4.4.orig/include/linux/hash.h
+++ zfcpdump-kernel-4.4/include/linux/hash.h
@@ -32,12 +32,28 @@
 #error Wordsize not 32 or 64
 #endif
 
+/*
+ * The above primes are actively bad for hashing, since they are
+ * too sparse. The 32-bit one is mostly ok, the 64-bit one causes
+ * real problems. Besides, the "prime" part is pointless for the
+ * multiplicative hash.
+ *
+ * Although a random odd number will do, it turns out that the golden
+ * ratio phi = (sqrt(5)-1)/2, or its negative, has particularly nice
+ * properties.
+ *
+ * These are the negative, (1 - phi) = (phi^2) = (3 - sqrt(5))/2.
+ * (See Knuth vol 3, section 6.4, exercise 9.)
+ */
+#define GOLDEN_RATIO_32 0x61C88647
+#define GOLDEN_RATIO_64 0x61C8864680B583EBull
+
 static __always_inline u64 hash_64(u64 val, unsigned int bits)
 {
 	u64 hash = val;
 
-#if defined(CONFIG_ARCH_HAS_FAST_MULTIPLIER) && BITS_PER_LONG == 64
-	hash = hash * GOLDEN_RATIO_PRIME_64;
+#if BITS_PER_LONG == 64
+	hash = hash * GOLDEN_RATIO_64;
 #else
 	/*  Sigh, gcc can't optimise this alone like it does for 32 bits. */
 	u64 n = hash;
--- zfcpdump-kernel-4.4.orig/include/linux/hrtimer.h
+++ zfcpdump-kernel-4.4/include/linux/hrtimer.h
@@ -87,7 +87,8 @@ enum hrtimer_restart {
  * @function:	timer expiry callback function
  * @base:	pointer to the timer base (per cpu and per clock)
  * @state:	state information (See bit values above)
- * @start_pid: timer statistics field to store the pid of the task which
+ * @is_rel:	Set if the timer was armed relative
+ * @start_pid:  timer statistics field to store the pid of the task which
  *		started the timer
  * @start_site:	timer statistics field to store the site where the timer
  *		was started
@@ -101,7 +102,8 @@ struct hrtimer {
 	ktime_t				_softexpires;
 	enum hrtimer_restart		(*function)(struct hrtimer *);
 	struct hrtimer_clock_base	*base;
-	unsigned long			state;
+	u8				state;
+	u8				is_rel;
 #ifdef CONFIG_TIMER_STATS
 	int				start_pid;
 	void				*start_site;
@@ -321,6 +323,27 @@ static inline void clock_was_set_delayed
 
 #endif
 
+static inline ktime_t
+__hrtimer_expires_remaining_adjusted(const struct hrtimer *timer, ktime_t now)
+{
+	ktime_t rem = ktime_sub(timer->node.expires, now);
+
+	/*
+	 * Adjust relative timers for the extra we added in
+	 * hrtimer_start_range_ns() to prevent short timeouts.
+	 */
+	if (IS_ENABLED(CONFIG_TIME_LOW_RES) && timer->is_rel)
+		rem.tv64 -= hrtimer_resolution;
+	return rem;
+}
+
+static inline ktime_t
+hrtimer_expires_remaining_adjusted(const struct hrtimer *timer)
+{
+	return __hrtimer_expires_remaining_adjusted(timer,
+						    timer->base->get_time());
+}
+
 extern void clock_was_set(void);
 #ifdef CONFIG_TIMERFD
 extern void timerfd_clock_was_set(void);
@@ -390,7 +413,12 @@ static inline void hrtimer_restart(struc
 }
 
 /* Query timers: */
-extern ktime_t hrtimer_get_remaining(const struct hrtimer *timer);
+extern ktime_t __hrtimer_get_remaining(const struct hrtimer *timer, bool adjust);
+
+static inline ktime_t hrtimer_get_remaining(const struct hrtimer *timer)
+{
+	return __hrtimer_get_remaining(timer, false);
+}
 
 extern u64 hrtimer_get_next_event(void);
 
--- zfcpdump-kernel-4.4.orig/include/linux/hyperv.h
+++ zfcpdump-kernel-4.4/include/linux/hyperv.h
@@ -126,6 +126,8 @@ struct hv_ring_buffer_info {
 
 	u32 ring_datasize;		/* < ring_size */
 	u32 ring_data_startoffset;
+	u32 priv_write_index;
+	u32 priv_read_index;
 };
 
 /*
@@ -141,8 +143,6 @@ hv_get_ringbuffer_availbytes(struct hv_r
 {
 	u32 read_loc, write_loc, dsize;
 
-	smp_read_barrier_depends();
-
 	/* Capture the read/write indices before they changed */
 	read_loc = rbi->ring_buffer->read_index;
 	write_loc = rbi->ring_buffer->write_index;
@@ -153,6 +153,33 @@ hv_get_ringbuffer_availbytes(struct hv_r
 	*read = dsize - *write;
 }
 
+static inline u32 hv_get_bytes_to_read(struct hv_ring_buffer_info *rbi)
+{
+	u32 read_loc, write_loc, dsize, read;
+
+	dsize = rbi->ring_datasize;
+	read_loc = rbi->ring_buffer->read_index;
+	write_loc = READ_ONCE(rbi->ring_buffer->write_index);
+
+	read = write_loc >= read_loc ? (write_loc - read_loc) :
+		(dsize - read_loc) + write_loc;
+
+	return read;
+}
+
+static inline u32 hv_get_bytes_to_write(struct hv_ring_buffer_info *rbi)
+{
+	u32 read_loc, write_loc, dsize, write;
+
+	dsize = rbi->ring_datasize;
+	read_loc = READ_ONCE(rbi->ring_buffer->read_index);
+	write_loc = rbi->ring_buffer->write_index;
+
+	write = write_loc >= read_loc ? dsize - (write_loc - read_loc) :
+		read_loc - write_loc;
+	return write;
+}
+
 /*
  * VMBUS version is 32 bit entity broken up into
  * two 16 bit quantities: major_number. minor_number.
@@ -237,6 +264,7 @@ struct vmbus_channel_offer {
 #define VMBUS_CHANNEL_LOOPBACK_OFFER			0x100
 #define VMBUS_CHANNEL_PARENT_OFFER			0x200
 #define VMBUS_CHANNEL_REQUEST_MONITORED_NOTIFICATION	0x400
+#define VMBUS_CHANNEL_TLNPI_PROVIDER_OFFER		0x2000
 
 struct vmpacket_descriptor {
 	u16 type;
@@ -393,6 +421,10 @@ enum vmbus_channel_message_type {
 	CHANNELMSG_VERSION_RESPONSE		= 15,
 	CHANNELMSG_UNLOAD			= 16,
 	CHANNELMSG_UNLOAD_RESPONSE		= 17,
+	CHANNELMSG_18				= 18,
+	CHANNELMSG_19				= 19,
+	CHANNELMSG_20				= 20,
+	CHANNELMSG_TL_CONNECT_REQUEST		= 21,
 	CHANNELMSG_COUNT
 };
 
@@ -563,6 +595,13 @@ struct vmbus_channel_initiate_contact {
 	u64 monitor_page2;
 } __packed;
 
+/* Hyper-V socket: guest's connect()-ing to host */
+struct vmbus_channel_tl_connect_request {
+	struct vmbus_channel_message_header header;
+	uuid_le guest_endpoint_id;
+	uuid_le host_service_id;
+} __packed;
+
 struct vmbus_channel_version_response {
 	struct vmbus_channel_message_header header;
 	u8 version_supported;
@@ -630,6 +669,37 @@ struct hv_input_signal_event_buffer {
 	struct hv_input_signal_event event;
 };
 
+enum hv_signal_policy {
+	HV_SIGNAL_POLICY_DEFAULT = 0,
+	HV_SIGNAL_POLICY_EXPLICIT,
+};
+
+enum vmbus_device_type {
+	HV_IDE = 0,
+	HV_SCSI,
+	HV_FC,
+	HV_NIC,
+	HV_ND,
+	HV_PCIE,
+	HV_FB,
+	HV_KBD,
+	HV_MOUSE,
+	HV_KVP,
+	HV_TS,
+	HV_HB,
+	HV_SHUTDOWN,
+	HV_FCOPY,
+	HV_BACKUP,
+	HV_DM,
+	HV_UNKOWN,
+};
+
+struct vmbus_device {
+	u16  dev_type;
+	uuid_le guid;
+	bool perf_device;
+};
+
 struct vmbus_channel {
 	/* Unique channel id */
 	int id;
@@ -725,6 +795,12 @@ struct vmbus_channel {
 	void (*sc_creation_callback)(struct vmbus_channel *new_sc);
 
 	/*
+	 * Channel rescind callback. Some channels (the hvsock ones), need to
+	 * register a callback which is invoked in vmbus_onoffer_rescind().
+	 */
+	void (*chn_rescind_callback)(struct vmbus_channel *channel);
+
+	/*
 	 * The spinlock to protect the structure. It is being used to protect
 	 * test-and-set access to various attributes of the structure as well
 	 * as all sc_list operations.
@@ -757,8 +833,43 @@ struct vmbus_channel {
 	 * link up channels based on their CPU affinity.
 	 */
 	struct list_head percpu_list;
+	/*
+	 * Host signaling policy: The default policy will be
+	 * based on the ring buffer state. We will also support
+	 * a policy where the client driver can have explicit
+	 * signaling control.
+	 */
+	enum hv_signal_policy  signal_policy;
+	/*
+	 * On the channel send side, many of the VMBUS
+	 * device drivers explicity serialize access to the
+	 * outgoing ring buffer. Give more control to the
+	 * VMBUS device drivers in terms how to serialize
+	 * accesss to the outgoing ring buffer.
+	 * The default behavior will be to aquire the
+	 * ring lock to preserve the current behavior.
+	 */
+	bool acquire_ring_lock;
+
 };
 
+static inline void set_channel_lock_state(struct vmbus_channel *c, bool state)
+{
+	c->acquire_ring_lock = state;
+}
+
+static inline bool is_hvsock_channel(const struct vmbus_channel *c)
+{
+	return !!(c->offermsg.offer.chn_flags &
+		  VMBUS_CHANNEL_TLNPI_PROVIDER_OFFER);
+}
+
+static inline void set_channel_signal_state(struct vmbus_channel *c,
+					    enum hv_signal_policy policy)
+{
+	c->signal_policy = policy;
+}
+
 static inline void set_channel_read_state(struct vmbus_channel *c, bool state)
 {
 	c->batched_reading = state;
@@ -774,6 +885,12 @@ static inline void *get_per_channel_stat
 	return c->per_channel_state;
 }
 
+static inline void set_channel_pending_send_size(struct vmbus_channel *c,
+						 u32 size)
+{
+	c->outbound.ring_buffer->pending_send_sz = size;
+}
+
 void vmbus_onmessage(void *context);
 
 int vmbus_request_offers(void);
@@ -785,6 +902,9 @@ int vmbus_request_offers(void);
 void vmbus_set_sc_create_callback(struct vmbus_channel *primary_channel,
 			void (*sc_cr_cb)(struct vmbus_channel *new_sc));
 
+void vmbus_set_chn_rescind_callback(struct vmbus_channel *channel,
+		void (*chn_rescind_cb)(struct vmbus_channel *));
+
 /*
  * Retrieve the (sub) channel on which to send an outgoing request.
  * When a primary channel has multiple sub-channels, we choose a
@@ -924,6 +1044,20 @@ extern void vmbus_ontimer(unsigned long
 struct hv_driver {
 	const char *name;
 
+	/*
+	 * A hvsock offer, which has a VMBUS_CHANNEL_TLNPI_PROVIDER_OFFER
+	 * channel flag, actually doesn't mean a synthetic device because the
+	 * offer's if_type/if_instance can change for every new hvsock
+	 * connection.
+	 *
+	 * However, to facilitate the notification of new-offer/rescind-offer
+	 * from vmbus driver to hvsock driver, we can handle hvsock offer as
+	 * a special vmbus device, and hence we need the below flag to
+	 * indicate if the driver is the hvsock driver or not: we need to
+	 * specially treat the hvosck offer & driver in vmbus_match().
+	 */
+	bool hvsock;
+
 	/* the device type supported by this driver */
 	uuid_le dev_type;
 	const struct hv_vmbus_device_id *id_table;
@@ -943,6 +1077,8 @@ struct hv_device {
 
 	/* the device instance id of this device */
 	uuid_le dev_instance;
+	u16 vendor_id;
+	u16 device_id;
 
 	struct device device;
 
@@ -978,21 +1114,15 @@ int __must_check __vmbus_driver_register
 					 const char *mod_name);
 void vmbus_driver_unregister(struct hv_driver *hv_driver);
 
+void vmbus_hvsock_device_unregister(struct vmbus_channel *channel);
+
 int vmbus_allocate_mmio(struct resource **new, struct hv_device *device_obj,
 			resource_size_t min, resource_size_t max,
 			resource_size_t size, resource_size_t align,
 			bool fb_overlap_ok);
-
-/**
- * VMBUS_DEVICE - macro used to describe a specific hyperv vmbus device
- *
- * This macro is used to create a struct hv_vmbus_device_id that matches a
- * specific device.
- */
-#define VMBUS_DEVICE(g0, g1, g2, g3, g4, g5, g6, g7,	\
-		     g8, g9, ga, gb, gc, gd, ge, gf)	\
-	.guid = { g0, g1, g2, g3, g4, g5, g6, g7,	\
-		  g8, g9, ga, gb, gc, gd, ge, gf },
+void vmbus_free_mmio(resource_size_t start, resource_size_t size);
+int vmbus_cpu_number_to_vp_number(int cpu_number);
+u64 hv_do_hypercall(u64 control, void *input, void *output);
 
 /*
  * GUID definitions of various offer types - services offered to the guest.
@@ -1003,118 +1133,102 @@ int vmbus_allocate_mmio(struct resource
  * {f8615163-df3e-46c5-913f-f2d2f965ed0e}
  */
 #define HV_NIC_GUID \
-	.guid = { \
-			0x63, 0x51, 0x61, 0xf8, 0x3e, 0xdf, 0xc5, 0x46, \
-			0x91, 0x3f, 0xf2, 0xd2, 0xf9, 0x65, 0xed, 0x0e \
-		}
+	.guid = UUID_LE(0xf8615163, 0xdf3e, 0x46c5, 0x91, 0x3f, \
+			0xf2, 0xd2, 0xf9, 0x65, 0xed, 0x0e)
 
 /*
  * IDE GUID
  * {32412632-86cb-44a2-9b5c-50d1417354f5}
  */
 #define HV_IDE_GUID \
-	.guid = { \
-			0x32, 0x26, 0x41, 0x32, 0xcb, 0x86, 0xa2, 0x44, \
-			0x9b, 0x5c, 0x50, 0xd1, 0x41, 0x73, 0x54, 0xf5 \
-		}
+	.guid = UUID_LE(0x32412632, 0x86cb, 0x44a2, 0x9b, 0x5c, \
+			0x50, 0xd1, 0x41, 0x73, 0x54, 0xf5)
 
 /*
  * SCSI GUID
  * {ba6163d9-04a1-4d29-b605-72e2ffb1dc7f}
  */
 #define HV_SCSI_GUID \
-	.guid = { \
-			0xd9, 0x63, 0x61, 0xba, 0xa1, 0x04, 0x29, 0x4d, \
-			0xb6, 0x05, 0x72, 0xe2, 0xff, 0xb1, 0xdc, 0x7f \
-		}
+	.guid = UUID_LE(0xba6163d9, 0x04a1, 0x4d29, 0xb6, 0x05, \
+			0x72, 0xe2, 0xff, 0xb1, 0xdc, 0x7f)
 
 /*
  * Shutdown GUID
  * {0e0b6031-5213-4934-818b-38d90ced39db}
  */
 #define HV_SHUTDOWN_GUID \
-	.guid = { \
-			0x31, 0x60, 0x0b, 0x0e, 0x13, 0x52, 0x34, 0x49, \
-			0x81, 0x8b, 0x38, 0xd9, 0x0c, 0xed, 0x39, 0xdb \
-		}
+	.guid = UUID_LE(0x0e0b6031, 0x5213, 0x4934, 0x81, 0x8b, \
+			0x38, 0xd9, 0x0c, 0xed, 0x39, 0xdb)
 
 /*
  * Time Synch GUID
  * {9527E630-D0AE-497b-ADCE-E80AB0175CAF}
  */
 #define HV_TS_GUID \
-	.guid = { \
-			0x30, 0xe6, 0x27, 0x95, 0xae, 0xd0, 0x7b, 0x49, \
-			0xad, 0xce, 0xe8, 0x0a, 0xb0, 0x17, 0x5c, 0xaf \
-		}
+	.guid = UUID_LE(0x9527e630, 0xd0ae, 0x497b, 0xad, 0xce, \
+			0xe8, 0x0a, 0xb0, 0x17, 0x5c, 0xaf)
 
 /*
  * Heartbeat GUID
  * {57164f39-9115-4e78-ab55-382f3bd5422d}
  */
 #define HV_HEART_BEAT_GUID \
-	.guid = { \
-			0x39, 0x4f, 0x16, 0x57, 0x15, 0x91, 0x78, 0x4e, \
-			0xab, 0x55, 0x38, 0x2f, 0x3b, 0xd5, 0x42, 0x2d \
-		}
+	.guid = UUID_LE(0x57164f39, 0x9115, 0x4e78, 0xab, 0x55, \
+			0x38, 0x2f, 0x3b, 0xd5, 0x42, 0x2d)
 
 /*
  * KVP GUID
  * {a9a0f4e7-5a45-4d96-b827-8a841e8c03e6}
  */
 #define HV_KVP_GUID \
-	.guid = { \
-			0xe7, 0xf4, 0xa0, 0xa9, 0x45, 0x5a, 0x96, 0x4d, \
-			0xb8, 0x27, 0x8a, 0x84, 0x1e, 0x8c, 0x3,  0xe6 \
-		}
+	.guid = UUID_LE(0xa9a0f4e7, 0x5a45, 0x4d96, 0xb8, 0x27, \
+			0x8a, 0x84, 0x1e, 0x8c, 0x03, 0xe6)
 
 /*
  * Dynamic memory GUID
  * {525074dc-8985-46e2-8057-a307dc18a502}
  */
 #define HV_DM_GUID \
-	.guid = { \
-			0xdc, 0x74, 0x50, 0X52, 0x85, 0x89, 0xe2, 0x46, \
-			0x80, 0x57, 0xa3, 0x07, 0xdc, 0x18, 0xa5, 0x02 \
-		}
+	.guid = UUID_LE(0x525074dc, 0x8985, 0x46e2, 0x80, 0x57, \
+			0xa3, 0x07, 0xdc, 0x18, 0xa5, 0x02)
 
 /*
  * Mouse GUID
  * {cfa8b69e-5b4a-4cc0-b98b-8ba1a1f3f95a}
  */
 #define HV_MOUSE_GUID \
-	.guid = { \
-			0x9e, 0xb6, 0xa8, 0xcf, 0x4a, 0x5b, 0xc0, 0x4c, \
-			0xb9, 0x8b, 0x8b, 0xa1, 0xa1, 0xf3, 0xf9, 0x5a \
-		}
+	.guid = UUID_LE(0xcfa8b69e, 0x5b4a, 0x4cc0, 0xb9, 0x8b, \
+			0x8b, 0xa1, 0xa1, 0xf3, 0xf9, 0x5a)
+
+/*
+ * Keyboard GUID
+ * {f912ad6d-2b17-48ea-bd65-f927a61c7684}
+ */
+#define HV_KBD_GUID \
+	.guid = UUID_LE(0xf912ad6d, 0x2b17, 0x48ea, 0xbd, 0x65, \
+			0xf9, 0x27, 0xa6, 0x1c, 0x76, 0x84)
 
 /*
  * VSS (Backup/Restore) GUID
  */
 #define HV_VSS_GUID \
-	.guid = { \
-			0x29, 0x2e, 0xfa, 0x35, 0x23, 0xea, 0x36, 0x42, \
-			0x96, 0xae, 0x3a, 0x6e, 0xba, 0xcb, 0xa4,  0x40 \
-		}
+	.guid = UUID_LE(0x35fa2e29, 0xea23, 0x4236, 0x96, 0xae, \
+			0x3a, 0x6e, 0xba, 0xcb, 0xa4, 0x40)
 /*
  * Synthetic Video GUID
  * {DA0A7802-E377-4aac-8E77-0558EB1073F8}
  */
 #define HV_SYNTHVID_GUID \
-	.guid = { \
-			0x02, 0x78, 0x0a, 0xda, 0x77, 0xe3, 0xac, 0x4a, \
-			0x8e, 0x77, 0x05, 0x58, 0xeb, 0x10, 0x73, 0xf8 \
-		}
+	.guid = UUID_LE(0xda0a7802, 0xe377, 0x4aac, 0x8e, 0x77, \
+			0x05, 0x58, 0xeb, 0x10, 0x73, 0xf8)
 
 /*
  * Synthetic FC GUID
  * {2f9bcc4a-0069-4af3-b76b-6fd0be528cda}
  */
 #define HV_SYNTHFC_GUID \
-	.guid = { \
-			0x4A, 0xCC, 0x9B, 0x2F, 0x69, 0x00, 0xF3, 0x4A, \
-			0xB7, 0x6B, 0x6F, 0xD0, 0xBE, 0x52, 0x8C, 0xDA \
-		}
+	.guid = UUID_LE(0x2f9bcc4a, 0x0069, 0x4af3, 0xb7, 0x6b, \
+			0x6f, 0xd0, 0xbe, 0x52, 0x8c, 0xda)
 
 /*
  * Guest File Copy Service
@@ -1122,20 +1236,25 @@ int vmbus_allocate_mmio(struct resource
  */
 
 #define HV_FCOPY_GUID \
-	.guid = { \
-			0xE3, 0x4B, 0xD1, 0x34, 0xE4, 0xDE, 0xC8, 0x41, \
-			0x9A, 0xE7, 0x6B, 0x17, 0x49, 0x77, 0xC1, 0x92 \
-		}
+	.guid = UUID_LE(0x34d14be3, 0xdee4, 0x41c8, 0x9a, 0xe7, \
+			0x6b, 0x17, 0x49, 0x77, 0xc1, 0x92)
 
 /*
  * NetworkDirect. This is the guest RDMA service.
  * {8c2eaf3d-32a7-4b09-ab99-bd1f1c86b501}
  */
 #define HV_ND_GUID \
-	.guid = { \
-			0x3d, 0xaf, 0x2e, 0x8c, 0xa7, 0x32, 0x09, 0x4b, \
-			0xab, 0x99, 0xbd, 0x1f, 0x1c, 0x86, 0xb5, 0x01 \
-		}
+	.guid = UUID_LE(0x8c2eaf3d, 0x32a7, 0x4b09, 0xab, 0x99, \
+			0xbd, 0x1f, 0x1c, 0x86, 0xb5, 0x01)
+
+/*
+ * PCI Express Pass Through
+ * {44C4F61D-4444-4400-9D52-802E27EDE19F}
+ */
+
+#define HV_PCIE_GUID \
+	.guid = UUID_LE(0x44c4f61d, 0x4444, 0x4400, 0x9d, 0x52, \
+			0x80, 0x2e, 0x27, 0xed, 0xe1, 0x9f)
 
 /*
  * Common header for Hyper-V ICs
@@ -1161,6 +1280,7 @@ int vmbus_allocate_mmio(struct resource
 
 struct hv_util_service {
 	u8 *recv_buffer;
+	void *channel;
 	void (*util_cb)(void *);
 	int (*util_init)(struct hv_util_service *);
 	void (*util_deinit)(void);
@@ -1245,4 +1365,145 @@ void hv_process_channel_removal(struct v
 
 extern __u32 vmbus_proto_version;
 
+int vmbus_send_tl_connect_request(const uuid_le *shv_guest_servie_id,
+				  const uuid_le *shv_host_servie_id);
+void vmbus_set_event(struct vmbus_channel *channel);
+
+/* Get the start of the ring buffer. */
+static inline void *
+hv_get_ring_buffer(struct hv_ring_buffer_info *ring_info)
+{
+	return (void *)ring_info->ring_buffer->buffer;
+}
+
+/*
+ * To optimize the flow management on the send-side,
+ * when the sender is blocked because of lack of
+ * sufficient space in the ring buffer, potential the
+ * consumer of the ring buffer can signal the producer.
+ * This is controlled by the following parameters:
+ *
+ * 1. pending_send_sz: This is the size in bytes that the
+ *    producer is trying to send.
+ * 2. The feature bit feat_pending_send_sz set to indicate if
+ *    the consumer of the ring will signal when the ring
+ *    state transitions from being full to a state where
+ *    there is room for the producer to send the pending packet.
+ */
+
+static inline  bool hv_need_to_signal_on_read(struct hv_ring_buffer_info *rbi)
+{
+	u32 cur_write_sz;
+	u32 pending_sz;
+
+	/*
+	 * Issue a full memory barrier before making the signaling decision.
+	 * Here is the reason for having this barrier:
+	 * If the reading of the pend_sz (in this function)
+	 * were to be reordered and read before we commit the new read
+	 * index (in the calling function)  we could
+	 * have a problem. If the host were to set the pending_sz after we
+	 * have sampled pending_sz and go to sleep before we commit the
+	 * read index, we could miss sending the interrupt. Issue a full
+	 * memory barrier to address this.
+	 */
+	virt_mb();
+
+	pending_sz = READ_ONCE(rbi->ring_buffer->pending_send_sz);
+	/* If the other end is not blocked on write don't bother. */
+	if (pending_sz == 0)
+		return false;
+
+	cur_write_sz = hv_get_bytes_to_write(rbi);
+
+	if (cur_write_sz >= pending_sz)
+		return true;
+
+	return false;
+}
+
+/*
+ * An API to support in-place processing of incoming VMBUS packets.
+ */
+#define VMBUS_PKT_TRAILER	8
+
+static inline struct vmpacket_descriptor *
+get_next_pkt_raw(struct vmbus_channel *channel)
+{
+	struct hv_ring_buffer_info *ring_info = &channel->inbound;
+	u32 read_loc = ring_info->priv_read_index;
+	void *ring_buffer = hv_get_ring_buffer(ring_info);
+	struct vmpacket_descriptor *cur_desc;
+	u32 packetlen;
+	u32 dsize = ring_info->ring_datasize;
+	u32 delta = read_loc - ring_info->ring_buffer->read_index;
+	u32 bytes_avail_toread = (hv_get_bytes_to_read(ring_info) - delta);
+
+	if (bytes_avail_toread < sizeof(struct vmpacket_descriptor))
+		return NULL;
+
+	if ((read_loc + sizeof(*cur_desc)) > dsize)
+		return NULL;
+
+	cur_desc = ring_buffer + read_loc;
+	packetlen = cur_desc->len8 << 3;
+
+	/*
+	 * If the packet under consideration is wrapping around,
+	 * return failure.
+	 */
+	if ((read_loc + packetlen + VMBUS_PKT_TRAILER) > (dsize - 1))
+		return NULL;
+
+	return cur_desc;
+}
+
+/*
+ * A helper function to step through packets "in-place"
+ * This API is to be called after each successful call
+ * get_next_pkt_raw().
+ */
+static inline void put_pkt_raw(struct vmbus_channel *channel,
+				struct vmpacket_descriptor *desc)
+{
+	struct hv_ring_buffer_info *ring_info = &channel->inbound;
+	u32 read_loc = ring_info->priv_read_index;
+	u32 packetlen = desc->len8 << 3;
+	u32 dsize = ring_info->ring_datasize;
+
+	if ((read_loc + packetlen + VMBUS_PKT_TRAILER) > dsize)
+		BUG();
+	/*
+	 * Include the packet trailer.
+	 */
+	ring_info->priv_read_index += packetlen + VMBUS_PKT_TRAILER;
+}
+
+/*
+ * This call commits the read index and potentially signals the host.
+ * Here is the pattern for using the "in-place" consumption APIs:
+ *
+ * while (get_next_pkt_raw() {
+ *	process the packet "in-place";
+ *	put_pkt_raw();
+ * }
+ * if (packets processed in place)
+ *	commit_rd_index();
+ */
+static inline void commit_rd_index(struct vmbus_channel *channel)
+{
+	struct hv_ring_buffer_info *ring_info = &channel->inbound;
+	/*
+	 * Make sure all reads are done before we update the read index since
+	 * the writer may start writing to the read area once the read index
+	 * is updated.
+	 */
+	virt_rmb();
+	ring_info->ring_buffer->read_index = ring_info->priv_read_index;
+
+	if (hv_need_to_signal_on_read(ring_info))
+		vmbus_set_event(channel);
+}
+
+
 #endif /* _HYPERV_H */
--- zfcpdump-kernel-4.4.orig/include/linux/i8042.h
+++ zfcpdump-kernel-4.4/include/linux/i8042.h
@@ -62,7 +62,6 @@ struct serio;
 void i8042_lock_chip(void);
 void i8042_unlock_chip(void);
 int i8042_command(unsigned char *param, int command);
-bool i8042_check_port_owner(const struct serio *);
 int i8042_install_filter(bool (*filter)(unsigned char data, unsigned char str,
 					struct serio *serio));
 int i8042_remove_filter(bool (*filter)(unsigned char data, unsigned char str,
@@ -83,11 +82,6 @@ static inline int i8042_command(unsigned
 	return -ENODEV;
 }
 
-static inline bool i8042_check_port_owner(const struct serio *serio)
-{
-	return false;
-}
-
 static inline int i8042_install_filter(bool (*filter)(unsigned char data, unsigned char str,
 					struct serio *serio))
 {
--- zfcpdump-kernel-4.4.orig/include/linux/if_bridge.h
+++ zfcpdump-kernel-4.4/include/linux/if_bridge.h
@@ -46,10 +46,6 @@ struct br_ip_list {
 #define BR_LEARNING_SYNC	BIT(9)
 #define BR_PROXYARP_WIFI	BIT(10)
 
-/* values as per ieee8021QBridgeFdbAgingTime */
-#define BR_MIN_AGEING_TIME	(10 * HZ)
-#define BR_MAX_AGEING_TIME	(1000000 * HZ)
-
 #define BR_DEFAULT_AGEING_TIME	(300 * HZ)
 
 extern void brioctl_set(int (*ioctl_hook)(struct net *, unsigned int, void __user *));
--- zfcpdump-kernel-4.4.orig/include/linux/intel-iommu.h
+++ zfcpdump-kernel-4.4/include/linux/intel-iommu.h
@@ -235,6 +235,9 @@ static inline void dmar_writeq(void __io
 /* low 64 bit */
 #define dma_frcd_page_addr(d) (d & (((u64)-1) << PAGE_SHIFT))
 
+/* PRS_REG */
+#define DMA_PRS_PPR	((u32)1)
+
 #define IOMMU_WAIT_OP(iommu, offset, op, cond, sts)			\
 do {									\
 	cycles_t start_time = get_cycles();				\
--- zfcpdump-kernel-4.4.orig/include/linux/irq.h
+++ zfcpdump-kernel-4.4/include/linux/irq.h
@@ -916,6 +916,16 @@ static inline void irq_gc_lock(struct ir
 static inline void irq_gc_unlock(struct irq_chip_generic *gc) { }
 #endif
 
+/*
+ * The irqsave variants are for usage in non interrupt code. Do not use
+ * them in irq_chip callbacks. Use irq_gc_lock() instead.
+ */
+#define irq_gc_lock_irqsave(gc, flags)	\
+	raw_spin_lock_irqsave(&(gc)->lock, flags)
+
+#define irq_gc_unlock_irqrestore(gc, flags)	\
+	raw_spin_unlock_irqrestore(&(gc)->lock, flags)
+
 static inline void irq_reg_writel(struct irq_chip_generic *gc,
 				  u32 val, int reg_offset)
 {
--- zfcpdump-kernel-4.4.orig/include/linux/irqchip/arm-gic-v3.h
+++ zfcpdump-kernel-4.4/include/linux/irqchip/arm-gic-v3.h
@@ -301,7 +301,7 @@
 #define ICC_SGI1R_AFFINITY_1_SHIFT	16
 #define ICC_SGI1R_AFFINITY_1_MASK	(0xff << ICC_SGI1R_AFFINITY_1_SHIFT)
 #define ICC_SGI1R_SGI_ID_SHIFT		24
-#define ICC_SGI1R_SGI_ID_MASK		(0xff << ICC_SGI1R_SGI_ID_SHIFT)
+#define ICC_SGI1R_SGI_ID_MASK		(0xfULL << ICC_SGI1R_SGI_ID_SHIFT)
 #define ICC_SGI1R_AFFINITY_2_SHIFT	32
 #define ICC_SGI1R_AFFINITY_2_MASK	(0xffULL << ICC_SGI1R_AFFINITY_1_SHIFT)
 #define ICC_SGI1R_IRQ_ROUTING_MODE_BIT	40
--- zfcpdump-kernel-4.4.orig/include/linux/irqchip/arm-gic.h
+++ zfcpdump-kernel-4.4/include/linux/irqchip/arm-gic.h
@@ -106,7 +106,8 @@ int gic_cpu_if_down(unsigned int gic_nr)
 void gic_init(unsigned int nr, int start,
 	      void __iomem *dist , void __iomem *cpu);
 
-int gicv2m_of_init(struct device_node *node, struct irq_domain *parent);
+int gicv2m_init(struct fwnode_handle *parent_handle,
+		struct irq_domain *parent);
 
 void gic_send_sgi(unsigned int cpu_id, unsigned int irq);
 int gic_get_cpu_id(unsigned int cpu);
--- zfcpdump-kernel-4.4.orig/include/linux/irqdomain.h
+++ zfcpdump-kernel-4.4/include/linux/irqdomain.h
@@ -211,6 +211,11 @@ static inline struct fwnode_handle *of_n
 	return node ? &node->fwnode : NULL;
 }
 
+static inline bool is_fwnode_irqchip(struct fwnode_handle *fwnode)
+{
+	return fwnode && fwnode->type == FWNODE_IRQCHIP;
+}
+
 static inline struct irq_domain *irq_find_matching_host(struct device_node *node,
 							enum irq_domain_bus_token bus_token)
 {
@@ -410,6 +415,11 @@ static inline bool irq_domain_is_hierarc
 static inline void irq_dispose_mapping(unsigned int virq) { }
 static inline void irq_domain_activate_irq(struct irq_data *data) { }
 static inline void irq_domain_deactivate_irq(struct irq_data *data) { }
+static inline struct irq_domain *irq_find_matching_fwnode(
+	struct fwnode_handle *fwnode, enum irq_domain_bus_token bus_token)
+{
+	return NULL;
+}
 #endif /* !CONFIG_IRQ_DOMAIN */
 
 #endif /* _LINUX_IRQDOMAIN_H */
--- zfcpdump-kernel-4.4.orig/include/linux/jump_label.h
+++ zfcpdump-kernel-4.4/include/linux/jump_label.h
@@ -117,13 +117,18 @@ struct module;
 
 #include <linux/atomic.h>
 
+#ifdef HAVE_JUMP_LABEL
+
 static inline int static_key_count(struct static_key *key)
 {
-	return atomic_read(&key->enabled);
+	/*
+	 * -1 means the first static_key_slow_inc() is in progress.
+	 *  static_key_enabled() must return true, so return 1 here.
+	 */
+	int n = atomic_read(&key->enabled);
+	return n >= 0 ? n : 1;
 }
 
-#ifdef HAVE_JUMP_LABEL
-
 #define JUMP_TYPE_FALSE	0UL
 #define JUMP_TYPE_TRUE	1UL
 #define JUMP_TYPE_MASK	1UL
@@ -162,6 +167,11 @@ extern void jump_label_apply_nops(struct
 
 #else  /* !HAVE_JUMP_LABEL */
 
+static inline int static_key_count(struct static_key *key)
+{
+	return atomic_read(&key->enabled);
+}
+
 static __always_inline void jump_label_init(void)
 {
 	static_key_initialized = true;
--- zfcpdump-kernel-4.4.orig/include/linux/kernel.h
+++ zfcpdump-kernel-4.4/include/linux/kernel.h
@@ -202,26 +202,26 @@ extern int _cond_resched(void);
 
 /**
  * abs - return absolute value of an argument
- * @x: the value.  If it is unsigned type, it is converted to signed type first
- *   (s64, long or int depending on its size).
+ * @x: the value.  If it is unsigned type, it is converted to signed type first.
+ *     char is treated as if it was signed (regardless of whether it really is)
+ *     but the macro's return type is preserved as char.
  *
- * Return: an absolute value of x.  If x is 64-bit, macro's return type is s64,
- *   otherwise it is signed long.
+ * Return: an absolute value of x.
  */
-#define abs(x) __builtin_choose_expr(sizeof(x) == sizeof(s64), ({	\
-		s64 __x = (x);						\
-		(__x < 0) ? -__x : __x;					\
-	}), ({								\
-		long ret;						\
-		if (sizeof(x) == sizeof(long)) {			\
-			long __x = (x);					\
-			ret = (__x < 0) ? -__x : __x;			\
-		} else {						\
-			int __x = (x);					\
-			ret = (__x < 0) ? -__x : __x;			\
-		}							\
-		ret;							\
-	}))
+#define abs(x)	__abs_choose_expr(x, long long,				\
+		__abs_choose_expr(x, long,				\
+		__abs_choose_expr(x, int,				\
+		__abs_choose_expr(x, short,				\
+		__abs_choose_expr(x, char,				\
+		__builtin_choose_expr(					\
+			__builtin_types_compatible_p(typeof(x), char),	\
+			(char)({ signed char __x = (x); __x<0?-__x:__x; }), \
+			((void)0)))))))
+
+#define __abs_choose_expr(x, type, other) __builtin_choose_expr(	\
+	__builtin_types_compatible_p(typeof(x),   signed type) ||	\
+	__builtin_types_compatible_p(typeof(x), unsigned type),		\
+	({ signed type __x = (x); __x < 0 ? -__x : __x; }), other)
 
 /**
  * reciprocal_scale - "scale" a value into range [0, ep_ro)
@@ -607,7 +607,7 @@ do {							\
 
 #define do_trace_printk(fmt, args...)					\
 do {									\
-	static const char *trace_printk_fmt				\
+	static const char *trace_printk_fmt __used			\
 		__attribute__((section("__trace_printk_fmt"))) =	\
 		__builtin_constant_p(fmt) ? fmt : NULL;			\
 									\
@@ -651,7 +651,7 @@ int __trace_printk(unsigned long ip, con
  */
 
 #define trace_puts(str) ({						\
-	static const char *trace_printk_fmt				\
+	static const char *trace_printk_fmt __used			\
 		__attribute__((section("__trace_printk_fmt"))) =	\
 		__builtin_constant_p(str) ? str : NULL;			\
 									\
@@ -673,7 +673,7 @@ extern void trace_dump_stack(int skip);
 #define ftrace_vprintk(fmt, vargs)					\
 do {									\
 	if (__builtin_constant_p(fmt)) {				\
-		static const char *trace_printk_fmt			\
+		static const char *trace_printk_fmt __used		\
 		  __attribute__((section("__trace_printk_fmt"))) =	\
 			__builtin_constant_p(fmt) ? fmt : NULL;		\
 									\
--- zfcpdump-kernel-4.4.orig/include/linux/kernfs.h
+++ zfcpdump-kernel-4.4/include/linux/kernfs.h
@@ -152,6 +152,8 @@ struct kernfs_syscall_ops {
 	int (*rmdir)(struct kernfs_node *kn);
 	int (*rename)(struct kernfs_node *kn, struct kernfs_node *new_parent,
 		      const char *new_name);
+	int (*show_path)(struct seq_file *sf, struct kernfs_node *kn,
+			 struct kernfs_root *root);
 };
 
 struct kernfs_root {
@@ -267,8 +269,9 @@ static inline bool kernfs_ns_enabled(str
 
 int kernfs_name(struct kernfs_node *kn, char *buf, size_t buflen);
 size_t kernfs_path_len(struct kernfs_node *kn);
-char * __must_check kernfs_path(struct kernfs_node *kn, char *buf,
-				size_t buflen);
+int kernfs_path_from_node(struct kernfs_node *root_kn, struct kernfs_node *kn,
+			  char *buf, size_t buflen);
+char *kernfs_path(struct kernfs_node *kn, char *buf, size_t buflen);
 void pr_cont_kernfs_name(struct kernfs_node *kn);
 void pr_cont_kernfs_path(struct kernfs_node *kn);
 struct kernfs_node *kernfs_get_parent(struct kernfs_node *kn);
@@ -281,6 +284,8 @@ struct kernfs_node *kernfs_node_from_den
 struct kernfs_root *kernfs_root_from_sb(struct super_block *sb);
 struct inode *kernfs_get_inode(struct super_block *sb, struct kernfs_node *kn);
 
+struct dentry *kernfs_node_dentry(struct kernfs_node *kn,
+				  struct super_block *sb);
 struct kernfs_root *kernfs_create_root(struct kernfs_syscall_ops *scops,
 				       unsigned int flags, void *priv);
 void kernfs_destroy_root(struct kernfs_root *root);
@@ -336,8 +341,8 @@ static inline int kernfs_name(struct ker
 static inline size_t kernfs_path_len(struct kernfs_node *kn)
 { return 0; }
 
-static inline char * __must_check kernfs_path(struct kernfs_node *kn, char *buf,
-					      size_t buflen)
+static inline char *kernfs_path(struct kernfs_node *kn, char *buf,
+				size_t buflen)
 { return NULL; }
 
 static inline void pr_cont_kernfs_name(struct kernfs_node *kn) { }
--- zfcpdump-kernel-4.4.orig/include/linux/key.h
+++ zfcpdump-kernel-4.4/include/linux/key.h
@@ -218,6 +218,7 @@ extern struct key *key_alloc(struct key_
 #define KEY_ALLOC_QUOTA_OVERRUN	0x0001	/* add to quota, permit even if overrun */
 #define KEY_ALLOC_NOT_IN_QUOTA	0x0002	/* not in quota */
 #define KEY_ALLOC_TRUSTED	0x0004	/* Key should be flagged as trusted */
+#define KEY_ALLOC_BUILT_IN	0x0008	/* Key is built into kernel */
 
 extern void key_revoke(struct key *key);
 extern void key_invalidate(struct key *key);
--- zfcpdump-kernel-4.4.orig/include/linux/kvm_host.h
+++ zfcpdump-kernel-4.4/include/linux/kvm_host.h
@@ -143,6 +143,8 @@ static inline bool is_error_page(struct
 #define KVM_REQ_HV_CRASH          27
 #define KVM_REQ_IOAPIC_EOI_EXIT   28
 #define KVM_REQ_HV_RESET          29
+#define KVM_REQ_HV_EXIT           30
+#define KVM_REQ_HV_STIMER         31
 
 #define KVM_USERSPACE_IRQ_SOURCE_ID		0
 #define KVM_IRQFD_RESAMPLE_IRQ_SOURCE_ID	1
@@ -318,6 +320,11 @@ struct kvm_s390_adapter_int {
 	u32 adapter_id;
 };
 
+struct kvm_hv_sint {
+	u32 vcpu;
+	u32 sint;
+};
+
 struct kvm_kernel_irq_routing_entry {
 	u32 gsi;
 	u32 type;
@@ -331,6 +338,7 @@ struct kvm_kernel_irq_routing_entry {
 		} irqchip;
 		struct msi_msg msi;
 		struct kvm_s390_adapter_int adapter;
+		struct kvm_hv_sint hv_sint;
 	};
 	struct hlist_node link;
 };
@@ -443,6 +451,8 @@ struct kvm {
 
 #define vcpu_debug(vcpu, fmt, ...)					\
 	kvm_debug("vcpu%i " fmt, (vcpu)->vcpu_id, ## __VA_ARGS__)
+#define vcpu_err(vcpu, fmt, ...)					\
+	kvm_err("vcpu%i " fmt, (vcpu)->vcpu_id, ## __VA_ARGS__)
 
 static inline struct kvm_vcpu *kvm_get_vcpu(struct kvm *kvm, int i)
 {
--- zfcpdump-kernel-4.4.orig/include/linux/libata.h
+++ zfcpdump-kernel-4.4/include/linux/libata.h
@@ -718,7 +718,7 @@ struct ata_device {
 	union {
 		u16		id[ATA_ID_WORDS]; /* IDENTIFY xxx DEVICE data */
 		u32		gscr[SATA_PMP_GSCR_DWORDS]; /* PMP GSCR block */
-	};
+	} ____cacheline_aligned;
 
 	/* DEVSLP Timing Variables from Identify Device Data Log */
 	u8			devslp_timing[ATA_LOG_DEVSLP_SIZE];
--- zfcpdump-kernel-4.4.orig/include/linux/lightnvm.h
+++ zfcpdump-kernel-4.4/include/linux/lightnvm.h
@@ -1,6 +1,8 @@
 #ifndef NVM_H
 #define NVM_H
 
+#include <linux/types.h>
+
 enum {
 	NVM_IO_OK = 0,
 	NVM_IO_REQUEUE = 1,
@@ -11,12 +13,74 @@ enum {
 	NVM_IOTYPE_GC = 1,
 };
 
+#define NVM_BLK_BITS (16)
+#define NVM_PG_BITS  (16)
+#define NVM_SEC_BITS (8)
+#define NVM_PL_BITS  (8)
+#define NVM_LUN_BITS (8)
+#define NVM_CH_BITS  (8)
+
+struct ppa_addr {
+	/* Generic structure for all addresses */
+	union {
+		struct {
+			u64 blk		: NVM_BLK_BITS;
+			u64 pg		: NVM_PG_BITS;
+			u64 sec		: NVM_SEC_BITS;
+			u64 pl		: NVM_PL_BITS;
+			u64 lun		: NVM_LUN_BITS;
+			u64 ch		: NVM_CH_BITS;
+		} g;
+
+		u64 ppa;
+	};
+};
+
+struct nvm_rq;
+struct nvm_id;
+struct nvm_dev;
+
+typedef int (nvm_l2p_update_fn)(u64, u32, __le64 *, void *);
+typedef int (nvm_bb_update_fn)(struct ppa_addr, int, u8 *, void *);
+typedef int (nvm_id_fn)(struct nvm_dev *, struct nvm_id *);
+typedef int (nvm_get_l2p_tbl_fn)(struct nvm_dev *, u64, u32,
+				nvm_l2p_update_fn *, void *);
+typedef int (nvm_op_bb_tbl_fn)(struct nvm_dev *, struct ppa_addr, int,
+				nvm_bb_update_fn *, void *);
+typedef int (nvm_op_set_bb_fn)(struct nvm_dev *, struct nvm_rq *, int);
+typedef int (nvm_submit_io_fn)(struct nvm_dev *, struct nvm_rq *);
+typedef int (nvm_erase_blk_fn)(struct nvm_dev *, struct nvm_rq *);
+typedef void *(nvm_create_dma_pool_fn)(struct nvm_dev *, char *);
+typedef void (nvm_destroy_dma_pool_fn)(void *);
+typedef void *(nvm_dev_dma_alloc_fn)(struct nvm_dev *, void *, gfp_t,
+								dma_addr_t *);
+typedef void (nvm_dev_dma_free_fn)(void *, void*, dma_addr_t);
+
+struct nvm_dev_ops {
+	nvm_id_fn		*identity;
+	nvm_get_l2p_tbl_fn	*get_l2p_tbl;
+	nvm_op_bb_tbl_fn	*get_bb_tbl;
+	nvm_op_set_bb_fn	*set_bb_tbl;
+
+	nvm_submit_io_fn	*submit_io;
+	nvm_erase_blk_fn	*erase_block;
+
+	nvm_create_dma_pool_fn	*create_dma_pool;
+	nvm_destroy_dma_pool_fn	*destroy_dma_pool;
+	nvm_dev_dma_alloc_fn	*dev_dma_alloc;
+	nvm_dev_dma_free_fn	*dev_dma_free;
+
+	unsigned int		max_phys_sect;
+};
+
+
+
 #ifdef CONFIG_NVM
 
 #include <linux/blkdev.h>
-#include <linux/types.h>
 #include <linux/file.h>
 #include <linux/dmapool.h>
+#include <uapi/linux/lightnvm.h>
 
 enum {
 	/* HW Responsibilities */
@@ -58,8 +122,29 @@ enum {
 	/* Block Types */
 	NVM_BLK_T_FREE		= 0x0,
 	NVM_BLK_T_BAD		= 0x1,
-	NVM_BLK_T_DEV		= 0x2,
-	NVM_BLK_T_HOST		= 0x4,
+	NVM_BLK_T_GRWN_BAD	= 0x2,
+	NVM_BLK_T_DEV		= 0x4,
+	NVM_BLK_T_HOST		= 0x8,
+
+	/* Memory capabilities */
+	NVM_ID_CAP_SLC		= 0x1,
+	NVM_ID_CAP_CMD_SUSPEND	= 0x2,
+	NVM_ID_CAP_SCRAMBLE	= 0x4,
+	NVM_ID_CAP_ENCRYPT	= 0x8,
+
+	/* Memory types */
+	NVM_ID_FMTYPE_SLC	= 0,
+	NVM_ID_FMTYPE_MLC	= 1,
+};
+
+struct nvm_id_lp_mlc {
+	u16	num_pairs;
+	u8	pairs[886];
+};
+
+struct nvm_id_lp_tbl {
+	__u8	id[8];
+	struct nvm_id_lp_mlc mlc;
 };
 
 struct nvm_id_group {
@@ -82,6 +167,8 @@ struct nvm_id_group {
 	u32	mpos;
 	u32	mccap;
 	u16	cpar;
+
+	struct nvm_id_lp_tbl lptbl;
 };
 
 struct nvm_addr_format {
@@ -125,28 +212,8 @@ struct nvm_tgt_instance {
 #define NVM_VERSION_MINOR 0
 #define NVM_VERSION_PATCH 0
 
-#define NVM_BLK_BITS (16)
-#define NVM_PG_BITS  (16)
-#define NVM_SEC_BITS (8)
-#define NVM_PL_BITS  (8)
-#define NVM_LUN_BITS (8)
-#define NVM_CH_BITS  (8)
-
-struct ppa_addr {
-	/* Generic structure for all addresses */
-	union {
-		struct {
-			u64 blk		: NVM_BLK_BITS;
-			u64 pg		: NVM_PG_BITS;
-			u64 sec		: NVM_SEC_BITS;
-			u64 pl		: NVM_PL_BITS;
-			u64 lun		: NVM_LUN_BITS;
-			u64 ch		: NVM_CH_BITS;
-		} g;
-
-		u64 ppa;
-	};
-};
+struct nvm_rq;
+typedef void (nvm_end_io_fn)(struct nvm_rq *);
 
 struct nvm_rq {
 	struct nvm_tgt_instance *ins;
@@ -164,9 +231,14 @@ struct nvm_rq {
 	void *metadata;
 	dma_addr_t dma_metadata;
 
+	struct completion *wait;
+	nvm_end_io_fn *end_io;
+
 	uint8_t opcode;
 	uint16_t nr_pages;
 	uint16_t flags;
+
+	int error;
 };
 
 static inline struct nvm_rq *nvm_rq_from_pdu(void *pdu)
@@ -181,51 +253,31 @@ static inline void *nvm_rq_to_pdu(struct
 
 struct nvm_block;
 
-typedef int (nvm_l2p_update_fn)(u64, u32, __le64 *, void *);
-typedef int (nvm_bb_update_fn)(struct ppa_addr, int, u8 *, void *);
-typedef int (nvm_id_fn)(struct nvm_dev *, struct nvm_id *);
-typedef int (nvm_get_l2p_tbl_fn)(struct nvm_dev *, u64, u32,
-				nvm_l2p_update_fn *, void *);
-typedef int (nvm_op_bb_tbl_fn)(struct nvm_dev *, struct ppa_addr, int,
-				nvm_bb_update_fn *, void *);
-typedef int (nvm_op_set_bb_fn)(struct nvm_dev *, struct nvm_rq *, int);
-typedef int (nvm_submit_io_fn)(struct nvm_dev *, struct nvm_rq *);
-typedef int (nvm_erase_blk_fn)(struct nvm_dev *, struct nvm_rq *);
-typedef void *(nvm_create_dma_pool_fn)(struct nvm_dev *, char *);
-typedef void (nvm_destroy_dma_pool_fn)(void *);
-typedef void *(nvm_dev_dma_alloc_fn)(struct nvm_dev *, void *, gfp_t,
-								dma_addr_t *);
-typedef void (nvm_dev_dma_free_fn)(void *, void*, dma_addr_t);
-
-struct nvm_dev_ops {
-	nvm_id_fn		*identity;
-	nvm_get_l2p_tbl_fn	*get_l2p_tbl;
-	nvm_op_bb_tbl_fn	*get_bb_tbl;
-	nvm_op_set_bb_fn	*set_bb_tbl;
-
-	nvm_submit_io_fn	*submit_io;
-	nvm_erase_blk_fn	*erase_block;
-
-	nvm_create_dma_pool_fn	*create_dma_pool;
-	nvm_destroy_dma_pool_fn	*destroy_dma_pool;
-	nvm_dev_dma_alloc_fn	*dev_dma_alloc;
-	nvm_dev_dma_free_fn	*dev_dma_free;
-
-	unsigned int		max_phys_sect;
-};
-
 struct nvm_lun {
 	int id;
 
 	int lun_id;
 	int chnl_id;
 
-	unsigned int nr_inuse_blocks;	/* Number of used blocks */
+	/* It is up to the target to mark blocks as closed. If the target does
+	 * not do it, all blocks are marked as open, and nr_open_blocks
+	 * represents the number of blocks in use
+	 */
+	unsigned int nr_open_blocks;	/* Number of used, writable blocks */
+	unsigned int nr_closed_blocks;	/* Number of used, read-only blocks */
 	unsigned int nr_free_blocks;	/* Number of unused blocks */
 	unsigned int nr_bad_blocks;	/* Number of bad blocks */
-	struct nvm_block *blocks;
 
 	spinlock_t lock;
+
+	struct nvm_block *blocks;
+};
+
+enum {
+	NVM_BLK_ST_FREE =	0x1,	/* Free block */
+	NVM_BLK_ST_OPEN =	0x2,	/* Open block - read-write */
+	NVM_BLK_ST_CLOSED =	0x4,	/* Closed block - read-only */
+	NVM_BLK_ST_BAD =	0x8,	/* Bad block */
 };
 
 struct nvm_block {
@@ -234,7 +286,16 @@ struct nvm_block {
 	unsigned long id;
 
 	void *priv;
-	int type;
+	int state;
+};
+
+/* system block cpu representation */
+struct nvm_sb_info {
+	unsigned long		seqnr;
+	unsigned long		erase_cnt;
+	unsigned int		version;
+	char			mmtype[NVM_MMTYPE_LEN];
+	struct ppa_addr		fs_ppa;
 };
 
 struct nvm_dev {
@@ -247,6 +308,9 @@ struct nvm_dev {
 	struct nvmm_type *mt;
 	void *mp;
 
+	/* System blocks */
+	struct nvm_sb_info sb;
+
 	/* Device information */
 	int nr_chnls;
 	int nr_planes;
@@ -256,6 +320,7 @@ struct nvm_dev {
 	int blks_per_lun;
 	int sec_size;
 	int oob_size;
+	int mccap;
 	struct nvm_addr_format ppaf;
 
 	/* Calculated/Cached values. These do not reflect the actual usable
@@ -268,6 +333,10 @@ struct nvm_dev {
 	int sec_per_blk;
 	int sec_per_lun;
 
+	/* lower page table */
+	int lps_per_blk;
+	int *lptbl;
+
 	unsigned long total_pages;
 	unsigned long total_blocks;
 	int nr_luns;
@@ -280,6 +349,8 @@ struct nvm_dev {
 	/* Backend device */
 	struct request_queue *q;
 	char name[DISK_NAME_LEN];
+
+	struct mutex mlock;
 };
 
 static inline struct ppa_addr generic_to_dev_addr(struct nvm_dev *dev,
@@ -345,9 +416,13 @@ static inline struct ppa_addr block_to_p
 	return ppa;
 }
 
+static inline int ppa_to_slc(struct nvm_dev *dev, int slc_pg)
+{
+	return dev->lptbl[slc_pg];
+}
+
 typedef blk_qc_t (nvm_tgt_make_rq_fn)(struct request_queue *, struct bio *);
 typedef sector_t (nvm_tgt_capacity_fn)(void *);
-typedef int (nvm_tgt_end_io_fn)(struct nvm_rq *, int);
 typedef void *(nvm_tgt_init_fn)(struct nvm_dev *, struct gendisk *, int, int);
 typedef void (nvm_tgt_exit_fn)(void *);
 
@@ -358,7 +433,7 @@ struct nvm_tgt_type {
 	/* target entry points */
 	nvm_tgt_make_rq_fn *make_rq;
 	nvm_tgt_capacity_fn *capacity;
-	nvm_tgt_end_io_fn *end_io;
+	nvm_end_io_fn *end_io;
 
 	/* module-specific init/teardown */
 	nvm_tgt_init_fn *init;
@@ -383,7 +458,6 @@ typedef int (nvmm_open_blk_fn)(struct nv
 typedef int (nvmm_close_blk_fn)(struct nvm_dev *, struct nvm_block *);
 typedef void (nvmm_flush_blk_fn)(struct nvm_dev *, struct nvm_block *);
 typedef int (nvmm_submit_io_fn)(struct nvm_dev *, struct nvm_rq *);
-typedef int (nvmm_end_io_fn)(struct nvm_rq *, int);
 typedef int (nvmm_erase_blk_fn)(struct nvm_dev *, struct nvm_block *,
 								unsigned long);
 typedef struct nvm_lun *(nvmm_get_lun_fn)(struct nvm_dev *, int);
@@ -397,6 +471,8 @@ struct nvmm_type {
 	nvmm_unregister_fn *unregister_mgr;
 
 	/* Block administration callbacks */
+	nvmm_get_blk_fn *get_blk_unlocked;
+	nvmm_put_blk_fn *put_blk_unlocked;
 	nvmm_get_blk_fn *get_blk;
 	nvmm_put_blk_fn *put_blk;
 	nvmm_open_blk_fn *open_blk;
@@ -404,7 +480,6 @@ struct nvmm_type {
 	nvmm_flush_blk_fn *flush_blk;
 
 	nvmm_submit_io_fn *submit_io;
-	nvmm_end_io_fn *end_io;
 	nvmm_erase_blk_fn *erase_blk;
 
 	/* Configuration management */
@@ -418,6 +493,10 @@ struct nvmm_type {
 extern int nvm_register_mgr(struct nvmm_type *);
 extern void nvm_unregister_mgr(struct nvmm_type *);
 
+extern struct nvm_block *nvm_get_blk_unlocked(struct nvm_dev *,
+					struct nvm_lun *, unsigned long);
+extern void nvm_put_blk_unlocked(struct nvm_dev *, struct nvm_block *);
+
 extern struct nvm_block *nvm_get_blk(struct nvm_dev *, struct nvm_lun *,
 								unsigned long);
 extern void nvm_put_blk(struct nvm_dev *, struct nvm_block *);
@@ -427,7 +506,36 @@ extern int nvm_register(struct request_q
 extern void nvm_unregister(char *);
 
 extern int nvm_submit_io(struct nvm_dev *, struct nvm_rq *);
+extern void nvm_generic_to_addr_mode(struct nvm_dev *, struct nvm_rq *);
+extern void nvm_addr_to_generic_mode(struct nvm_dev *, struct nvm_rq *);
+extern int nvm_set_rqd_ppalist(struct nvm_dev *, struct nvm_rq *,
+							struct ppa_addr *, int);
+extern void nvm_free_rqd_ppalist(struct nvm_dev *, struct nvm_rq *);
+extern int nvm_erase_ppa(struct nvm_dev *, struct ppa_addr *, int);
 extern int nvm_erase_blk(struct nvm_dev *, struct nvm_block *);
+extern void nvm_end_io(struct nvm_rq *, int);
+extern int nvm_submit_ppa(struct nvm_dev *, struct ppa_addr *, int, int, int,
+								void *, int);
+
+/* sysblk.c */
+#define NVM_SYSBLK_MAGIC 0x4E564D53 /* "NVMS" */
+
+/* system block on disk representation */
+struct nvm_system_block {
+	__be32			magic;		/* magic signature */
+	__be32			seqnr;		/* sequence number */
+	__be32			erase_cnt;	/* erase count */
+	__be16			version;	/* version number */
+	u8			mmtype[NVM_MMTYPE_LEN]; /* media manager name */
+	__be64			fs_ppa;		/* PPA for media manager
+						 * superblock */
+};
+
+extern int nvm_get_sysblock(struct nvm_dev *, struct nvm_sb_info *);
+extern int nvm_update_sysblock(struct nvm_dev *, struct nvm_sb_info *);
+extern int nvm_init_sysblock(struct nvm_dev *, struct nvm_sb_info *);
+
+extern int nvm_dev_factory(struct nvm_dev *, int flags);
 #else /* CONFIG_NVM */
 struct nvm_dev_ops;
 
--- zfcpdump-kernel-4.4.orig/include/linux/livepatch.h
+++ zfcpdump-kernel-4.4/include/linux/livepatch.h
@@ -37,8 +37,9 @@ enum klp_state {
  * struct klp_func - function structure for live patching
  * @old_name:	name of the function to be patched
  * @new_func:	pointer to the patched function code
- * @old_addr:	a hint conveying at what address the old function
- *		can be found (optional, vmlinux patches only)
+ * @old_sympos: a hint indicating which symbol position the old function
+ *		can be found (optional)
+ * @old_addr:	the address of the function being patched
  * @kobj:	kobject for sysfs resources
  * @state:	tracks function-level patch application state
  * @stack_node:	list node for klp_ops func_stack list
@@ -48,16 +49,16 @@ struct klp_func {
 	const char *old_name;
 	void *new_func;
 	/*
-	 * The old_addr field is optional and can be used to resolve
-	 * duplicate symbol names in the vmlinux object.  If this
-	 * information is not present, the symbol is located by name
-	 * with kallsyms. If the name is not unique and old_addr is
-	 * not provided, the patch application fails as there is no
-	 * way to resolve the ambiguity.
+	 * The old_sympos field is optional and can be used to resolve
+	 * duplicate symbol names in livepatch objects. If this field is zero,
+	 * it is expected the symbol is unique, otherwise patching fails. If
+	 * this value is greater than zero then that occurrence of the symbol
+	 * in kallsyms for the given object is used.
 	 */
-	unsigned long old_addr;
+	unsigned long old_sympos;
 
 	/* internal */
+	unsigned long old_addr;
 	struct kobject kobj;
 	enum klp_state state;
 	struct list_head stack_node;
@@ -66,8 +67,7 @@ struct klp_func {
 /**
  * struct klp_reloc - relocation structure for live patching
  * @loc:	address where the relocation will be written
- * @val:	address of the referenced symbol (optional,
- *		vmlinux	patches only)
+ * @sympos:	position in kallsyms to disambiguate symbols (optional)
  * @type:	ELF relocation type
  * @name:	name of the referenced symbol (for lookup/verification)
  * @addend:	offset from the referenced symbol
@@ -75,7 +75,7 @@ struct klp_func {
  */
 struct klp_reloc {
 	unsigned long loc;
-	unsigned long val;
+	unsigned long sympos;
 	unsigned long type;
 	const char *name;
 	int addend;
--- zfcpdump-kernel-4.4.orig/include/linux/memcontrol.h
+++ zfcpdump-kernel-4.4/include/linux/memcontrol.h
@@ -174,6 +174,11 @@ struct mem_cgroup_thresholds {
 	struct mem_cgroup_threshold_ary *spare;
 };
 
+struct mem_cgroup_id {
+	int id;
+	atomic_t ref;
+};
+
 /*
  * The memory controller data structure. The memory controller controls both
  * page cache and RSS per cgroup. We would eventually like to provide
@@ -183,6 +188,9 @@ struct mem_cgroup_thresholds {
 struct mem_cgroup {
 	struct cgroup_subsys_state css;
 
+	/* Private memcg ID. Used to ID objects that outlive the cgroup */
+	struct mem_cgroup_id id;
+
 	/* Accounted resources */
 	struct page_counter memory;
 	struct page_counter memsw;
--- zfcpdump-kernel-4.4.orig/include/linux/mfd/core.h
+++ zfcpdump-kernel-4.4/include/linux/mfd/core.h
@@ -17,6 +17,7 @@
 #include <linux/platform_device.h>
 
 struct irq_domain;
+struct property_set;
 
 /* Matches ACPI PNP id, either _HID or _CID, or ACPI _ADR */
 struct mfd_cell_acpi_match {
@@ -44,6 +45,10 @@ struct mfd_cell {
 	/* platform data passed to the sub devices drivers */
 	void			*platform_data;
 	size_t			pdata_size;
+
+	/* device properties passed to the sub devices drivers */
+	const struct property_set *pset;
+
 	/*
 	 * Device Tree compatible string
 	 * See: Documentation/devicetree/usage-model.txt Chapter 2.2 for details
--- zfcpdump-kernel-4.4.orig/include/linux/mfd/cros_ec.h
+++ zfcpdump-kernel-4.4/include/linux/mfd/cros_ec.h
@@ -224,6 +224,21 @@ int cros_ec_cmd_xfer(struct cros_ec_devi
 		     struct cros_ec_command *msg);
 
 /**
+ * cros_ec_cmd_xfer_status - Send a command to the ChromeOS EC
+ *
+ * This function is identical to cros_ec_cmd_xfer, except it returns success
+ * status only if both the command was transmitted successfully and the EC
+ * replied with success status. It's not necessary to check msg->result when
+ * using this function.
+ *
+ * @ec_dev: EC device
+ * @msg: Message to write
+ * @return: Num. of bytes transferred on success, <0 on failure
+ */
+int cros_ec_cmd_xfer_status(struct cros_ec_device *ec_dev,
+			    struct cros_ec_command *msg);
+
+/**
  * cros_ec_remove - Remove a ChromeOS EC
  *
  * Call this to deregister a ChromeOS EC, then clean up any private data.
--- zfcpdump-kernel-4.4.orig/include/linux/mfd/samsung/s2mps11.h
+++ zfcpdump-kernel-4.4/include/linux/mfd/samsung/s2mps11.h
@@ -173,10 +173,12 @@ enum s2mps11_regulators {
 
 #define S2MPS11_LDO_VSEL_MASK	0x3F
 #define S2MPS11_BUCK_VSEL_MASK	0xFF
+#define S2MPS11_BUCK9_VSEL_MASK	0x1F
 #define S2MPS11_ENABLE_MASK	(0x03 << S2MPS11_ENABLE_SHIFT)
 #define S2MPS11_ENABLE_SHIFT	0x06
 #define S2MPS11_LDO_N_VOLTAGES	(S2MPS11_LDO_VSEL_MASK + 1)
 #define S2MPS11_BUCK_N_VOLTAGES (S2MPS11_BUCK_VSEL_MASK + 1)
+#define S2MPS11_BUCK9_N_VOLTAGES (S2MPS11_BUCK9_VSEL_MASK + 1)
 #define S2MPS11_RAMP_DELAY	25000		/* uV/us */
 
 #define S2MPS11_CTRL1_PWRHOLD_MASK	BIT(4)
--- zfcpdump-kernel-4.4.orig/include/linux/mfd/ti_am335x_tscadc.h
+++ zfcpdump-kernel-4.4/include/linux/mfd/ti_am335x_tscadc.h
@@ -138,16 +138,16 @@
 /*
  * time in us for processing a single channel, calculated as follows:
  *
- * num cycles = open delay + (sample delay + conv time) * averaging
+ * max num cycles = open delay + (sample delay + conv time) * averaging
  *
- * num cycles: 152 + (1 + 13) * 16 = 376
+ * max num cycles: 262143 + (255 + 13) * 16 = 266431
  *
  * clock frequency: 26MHz / 8 = 3.25MHz
  * clock period: 1 / 3.25MHz = 308ns
  *
- * processing time: 376 * 308ns = 116us
+ * max processing time: 266431 * 308ns = 83ms(approx)
  */
-#define IDLE_TIMEOUT 116 /* microsec */
+#define IDLE_TIMEOUT 83 /* milliseconds */
 
 #define TSCADC_CELLS		2
 
--- zfcpdump-kernel-4.4.orig/include/linux/mlx4/device.h
+++ zfcpdump-kernel-4.4/include/linux/mlx4/device.h
@@ -44,6 +44,8 @@
 
 #include <linux/timecounter.h>
 
+#define DEFAULT_UAR_PAGE_SHIFT  12
+
 #define MAX_MSIX_P_PORT		17
 #define MAX_MSIX		64
 #define MIN_MSIX_P_PORT		5
@@ -822,6 +824,11 @@ struct mlx4_vf_dev {
 	u8			n_ports;
 };
 
+enum mlx4_pci_status {
+	MLX4_PCI_STATUS_DISABLED,
+	MLX4_PCI_STATUS_ENABLED,
+};
+
 struct mlx4_dev_persistent {
 	struct pci_dev	       *pdev;
 	struct mlx4_dev	       *dev;
@@ -835,6 +842,8 @@ struct mlx4_dev_persistent {
 	u8		state;
 	struct mutex	interface_state_mutex; /* protect SW state */
 	u8	interface_state;
+	struct mutex		pci_status_mutex; /* sync pci state */
+	enum mlx4_pci_status	pci_status;
 };
 
 struct mlx4_dev {
@@ -853,6 +862,7 @@ struct mlx4_dev {
 	u64			regid_promisc_array[MLX4_MAX_PORTS + 1];
 	u64			regid_allmulti_array[MLX4_MAX_PORTS + 1];
 	struct mlx4_vf_dev     *dev_vfs;
+	u8  uar_page_shift;
 };
 
 struct mlx4_clock_params {
@@ -1527,4 +1537,14 @@ int mlx4_ACCESS_PTYS_REG(struct mlx4_dev
 int mlx4_get_internal_clock_params(struct mlx4_dev *dev,
 				   struct mlx4_clock_params *params);
 
+static inline int mlx4_to_hw_uar_index(struct mlx4_dev *dev, int index)
+{
+	return (index << (PAGE_SHIFT - dev->uar_page_shift));
+}
+
+static inline int mlx4_get_num_reserved_uar(struct mlx4_dev *dev)
+{
+	/* The first 128 UARs are used for EQ doorbells */
+	return (128 >> (PAGE_SHIFT - dev->uar_page_shift));
+}
 #endif /* MLX4_DEVICE_H */
--- zfcpdump-kernel-4.4.orig/include/linux/mlx5/cq.h
+++ zfcpdump-kernel-4.4/include/linux/mlx5/cq.h
@@ -45,7 +45,7 @@ struct mlx5_core_cq {
 	atomic_t		refcount;
 	struct completion	free;
 	unsigned		vector;
-	int			irqn;
+	unsigned int		irqn;
 	void (*comp)		(struct mlx5_core_cq *);
 	void (*event)		(struct mlx5_core_cq *, enum mlx5_event);
 	struct mlx5_uar	       *uar;
--- zfcpdump-kernel-4.4.orig/include/linux/mlx5/device.h
+++ zfcpdump-kernel-4.4/include/linux/mlx5/device.h
@@ -251,6 +251,7 @@ enum mlx5_event {
 	MLX5_EVENT_TYPE_PAGE_REQUEST	   = 0xb,
 
 	MLX5_EVENT_TYPE_PAGE_FAULT	   = 0xc,
+	MLX5_EVENT_TYPE_NIC_VPORT_CHANGE   = 0xd,
 };
 
 enum {
@@ -334,6 +335,17 @@ enum {
 	MLX5_CAP_OFF_CMDIF_CSUM		= 46,
 };
 
+enum {
+	/*
+	 * Max wqe size for rdma read is 512 bytes, so this
+	 * limits our max_sge_rd as the wqe needs to fit:
+	 * - ctrl segment (16 bytes)
+	 * - rdma segment (16 bytes)
+	 * - scatter elements (16 bytes each)
+	 */
+	MLX5_MAX_SGE_RD	= (512 - 16 - 16) / 16
+};
+
 struct mlx5_inbox_hdr {
 	__be16		opcode;
 	u8		rsvd[4];
@@ -520,6 +532,12 @@ struct mlx5_eqe_page_fault {
 	__be32 flags_qpn;
 } __packed;
 
+struct mlx5_eqe_vport_change {
+	u8		rsvd0[2];
+	__be16		vport_num;
+	__be32		rsvd1[6];
+} __packed;
+
 union ev_data {
 	__be32				raw[7];
 	struct mlx5_eqe_cmd		cmd;
@@ -532,6 +550,7 @@ union ev_data {
 	struct mlx5_eqe_stall_vl	stall_vl;
 	struct mlx5_eqe_page_req	req_pages;
 	struct mlx5_eqe_page_fault	page_fault;
+	struct mlx5_eqe_vport_change	vport_change;
 } __packed;
 
 struct mlx5_eqe {
@@ -1067,6 +1086,12 @@ enum {
 };
 
 enum {
+	MLX5_ESW_VPORT_ADMIN_STATE_DOWN  = 0x0,
+	MLX5_ESW_VPORT_ADMIN_STATE_UP    = 0x1,
+	MLX5_ESW_VPORT_ADMIN_STATE_AUTO  = 0x2,
+};
+
+enum {
 	MLX5_L3_PROT_TYPE_IPV4		= 0,
 	MLX5_L3_PROT_TYPE_IPV6		= 1,
 };
@@ -1102,6 +1127,12 @@ enum {
 	MLX5_FLOW_CONTEXT_DEST_TYPE_TIR		= 2,
 };
 
+enum mlx5_list_type {
+	MLX5_NVPRT_LIST_TYPE_UC   = 0x0,
+	MLX5_NVPRT_LIST_TYPE_MC   = 0x1,
+	MLX5_NVPRT_LIST_TYPE_VLAN = 0x2,
+};
+
 enum {
 	MLX5_RQC_RQ_TYPE_MEMORY_RQ_INLINE = 0x0,
 	MLX5_RQC_RQ_TYPE_MEMORY_RQ_RPM    = 0x1,
@@ -1124,6 +1155,8 @@ enum mlx5_cap_type {
 	MLX5_CAP_IPOIB_OFFLOADS,
 	MLX5_CAP_EOIB_OFFLOADS,
 	MLX5_CAP_FLOW_TABLE,
+	MLX5_CAP_ESWITCH_FLOW_TABLE,
+	MLX5_CAP_ESWITCH,
 	/* NUM OF CAP Types */
 	MLX5_CAP_NUM
 };
@@ -1161,6 +1194,28 @@ enum mlx5_cap_type {
 #define MLX5_CAP_FLOWTABLE_MAX(mdev, cap) \
 	MLX5_GET(flow_table_nic_cap, mdev->hca_caps_max[MLX5_CAP_FLOW_TABLE], cap)
 
+#define MLX5_CAP_ESW_FLOWTABLE(mdev, cap) \
+	MLX5_GET(flow_table_eswitch_cap, \
+		 mdev->hca_caps_cur[MLX5_CAP_ESWITCH_FLOW_TABLE], cap)
+
+#define MLX5_CAP_ESW_FLOWTABLE_MAX(mdev, cap) \
+	MLX5_GET(flow_table_eswitch_cap, \
+		 mdev->hca_caps_max[MLX5_CAP_ESWITCH_FLOW_TABLE], cap)
+
+#define MLX5_CAP_ESW_FLOWTABLE_FDB(mdev, cap) \
+	MLX5_CAP_ESW_FLOWTABLE(mdev, flow_table_properties_nic_esw_fdb.cap)
+
+#define MLX5_CAP_ESW_FLOWTABLE_FDB_MAX(mdev, cap) \
+	MLX5_CAP_ESW_FLOWTABLE_MAX(mdev, flow_table_properties_nic_esw_fdb.cap)
+
+#define MLX5_CAP_ESW(mdev, cap) \
+	MLX5_GET(e_switch_cap, \
+		 mdev->hca_caps_cur[MLX5_CAP_ESWITCH], cap)
+
+#define MLX5_CAP_ESW_MAX(mdev, cap) \
+	MLX5_GET(e_switch_cap, \
+		 mdev->hca_caps_max[MLX5_CAP_ESWITCH], cap)
+
 #define MLX5_CAP_ODP(mdev, cap)\
 	MLX5_GET(odp_cap, mdev->hca_caps_cur[MLX5_CAP_ODP], cap)
 
--- zfcpdump-kernel-4.4.orig/include/linux/mlx5/driver.h
+++ zfcpdump-kernel-4.4/include/linux/mlx5/driver.h
@@ -303,7 +303,7 @@ struct mlx5_eq {
 	u32			cons_index;
 	struct mlx5_buf		buf;
 	int			size;
-	u8			irqn;
+	unsigned int		irqn;
 	u8			eqn;
 	int			nent;
 	u64			mask;
@@ -426,11 +426,23 @@ struct mlx5_mr_table {
 	struct radix_tree_root	tree;
 };
 
+struct mlx5_vf_context {
+	int	enabled;
+};
+
+struct mlx5_core_sriov {
+	struct mlx5_vf_context	*vfs_ctx;
+	int			num_vfs;
+	int			enabled_vfs;
+};
+
 struct mlx5_irq_info {
 	cpumask_var_t mask;
 	char name[MLX5_MAX_IRQ_NAME];
 };
 
+struct mlx5_eswitch;
+
 struct mlx5_priv {
 	char			name[MLX5_MAX_NAME_LEN];
 	struct mlx5_eq_table	eq_table;
@@ -447,6 +459,7 @@ struct mlx5_priv {
 	int			fw_pages;
 	atomic_t		reg_pages;
 	struct list_head	free_list;
+	int			vfs_pages;
 
 	struct mlx5_core_health health;
 
@@ -485,6 +498,10 @@ struct mlx5_priv {
 	struct list_head        dev_list;
 	struct list_head        ctx_list;
 	spinlock_t              ctx_lock;
+
+	struct mlx5_eswitch     *eswitch;
+	struct mlx5_core_sriov	sriov;
+	unsigned long		pci_dev_data;
 };
 
 enum mlx5_device_state {
@@ -493,8 +510,9 @@ enum mlx5_device_state {
 };
 
 enum mlx5_interface_state {
-	MLX5_INTERFACE_STATE_DOWN,
-	MLX5_INTERFACE_STATE_UP,
+	MLX5_INTERFACE_STATE_DOWN = BIT(0),
+	MLX5_INTERFACE_STATE_UP = BIT(1),
+	MLX5_INTERFACE_STATE_SHUTDOWN = BIT(2),
 };
 
 enum mlx5_pci_status {
@@ -518,7 +536,7 @@ struct mlx5_core_dev {
 	enum mlx5_device_state	state;
 	/* sync interface state */
 	struct mutex		intf_state_mutex;
-	enum mlx5_interface_state interface_state;
+	unsigned long		intf_state;
 	void			(*event) (struct mlx5_core_dev *dev,
 					  enum mlx5_dev_event event,
 					  unsigned long param);
@@ -739,6 +757,8 @@ void mlx5_pagealloc_init(struct mlx5_cor
 void mlx5_pagealloc_cleanup(struct mlx5_core_dev *dev);
 int mlx5_pagealloc_start(struct mlx5_core_dev *dev);
 void mlx5_pagealloc_stop(struct mlx5_core_dev *dev);
+int mlx5_sriov_init(struct mlx5_core_dev *dev);
+int mlx5_sriov_cleanup(struct mlx5_core_dev *dev);
 void mlx5_core_req_pages_handler(struct mlx5_core_dev *dev, u16 func_id,
 				 s32 npages);
 int mlx5_satisfy_startup_pages(struct mlx5_core_dev *dev, int boot);
@@ -762,7 +782,8 @@ int mlx5_create_map_eq(struct mlx5_core_
 int mlx5_destroy_unmap_eq(struct mlx5_core_dev *dev, struct mlx5_eq *eq);
 int mlx5_start_eqs(struct mlx5_core_dev *dev);
 int mlx5_stop_eqs(struct mlx5_core_dev *dev);
-int mlx5_vector2eqn(struct mlx5_core_dev *dev, int vector, int *eqn, int *irqn);
+int mlx5_vector2eqn(struct mlx5_core_dev *dev, int vector, int *eqn,
+		    unsigned int *irqn);
 int mlx5_core_attach_mcg(struct mlx5_core_dev *dev, union ib_gid *mgid, u32 qpn);
 int mlx5_core_detach_mcg(struct mlx5_core_dev *dev, union ib_gid *mgid, u32 qpn);
 
@@ -772,37 +793,6 @@ int mlx5_core_access_reg(struct mlx5_cor
 			 int size_in, void *data_out, int size_out,
 			 u16 reg_num, int arg, int write);
 
-int mlx5_set_port_caps(struct mlx5_core_dev *dev, u8 port_num, u32 caps);
-int mlx5_query_port_ptys(struct mlx5_core_dev *dev, u32 *ptys,
-			 int ptys_size, int proto_mask, u8 local_port);
-int mlx5_query_port_proto_cap(struct mlx5_core_dev *dev,
-			      u32 *proto_cap, int proto_mask);
-int mlx5_query_port_proto_admin(struct mlx5_core_dev *dev,
-				u32 *proto_admin, int proto_mask);
-int mlx5_query_port_link_width_oper(struct mlx5_core_dev *dev,
-				    u8 *link_width_oper, u8 local_port);
-int mlx5_query_port_proto_oper(struct mlx5_core_dev *dev,
-			       u8 *proto_oper, int proto_mask,
-			       u8 local_port);
-int mlx5_set_port_proto(struct mlx5_core_dev *dev, u32 proto_admin,
-			int proto_mask);
-int mlx5_set_port_admin_status(struct mlx5_core_dev *dev,
-			       enum mlx5_port_status status);
-int mlx5_query_port_admin_status(struct mlx5_core_dev *dev,
-				 enum mlx5_port_status *status);
-
-int mlx5_set_port_mtu(struct mlx5_core_dev *dev, int mtu, u8 port);
-void mlx5_query_port_max_mtu(struct mlx5_core_dev *dev, int *max_mtu, u8 port);
-void mlx5_query_port_oper_mtu(struct mlx5_core_dev *dev, int *oper_mtu,
-			      u8 port);
-
-int mlx5_query_port_vl_hw_cap(struct mlx5_core_dev *dev,
-			      u8 *vl_hw_cap, u8 local_port);
-
-int mlx5_set_port_pause(struct mlx5_core_dev *dev, u32 rx_pause, u32 tx_pause);
-int mlx5_query_port_pause(struct mlx5_core_dev *dev,
-			  u32 *rx_pause, u32 *tx_pause);
-
 int mlx5_debug_eq_add(struct mlx5_core_dev *dev, struct mlx5_eq *eq);
 void mlx5_debug_eq_remove(struct mlx5_core_dev *dev, struct mlx5_eq *eq);
 int mlx5_core_eq_query(struct mlx5_core_dev *dev, struct mlx5_eq *eq,
@@ -884,6 +874,15 @@ struct mlx5_profile {
 	} mr_cache[MAX_MR_CACHE_ENTRIES];
 };
 
+enum {
+	MLX5_PCI_DEV_IS_VF		= 1 << 0,
+};
+
+static inline int mlx5_core_is_pf(struct mlx5_core_dev *dev)
+{
+	return !(dev->priv.pci_dev_data & MLX5_PCI_DEV_IS_VF);
+}
+
 static inline int mlx5_get_gid_table_len(u16 param)
 {
 	if (param > 4) {
--- zfcpdump-kernel-4.4.orig/include/linux/mlx5/flow_table.h
+++ zfcpdump-kernel-4.4/include/linux/mlx5/flow_table.h
@@ -41,6 +41,15 @@ struct mlx5_flow_table_group {
 	u32	match_criteria[MLX5_ST_SZ_DW(fte_match_param)];
 };
 
+struct mlx5_flow_destination {
+	enum mlx5_flow_destination_type	type;
+	union {
+		u32			tir_num;
+		void			*ft;
+		u32			vport_num;
+	};
+};
+
 void *mlx5_create_flow_table(struct mlx5_core_dev *dev, u8 level, u8 table_type,
 			     u16 num_groups,
 			     struct mlx5_flow_table_group *group);
--- zfcpdump-kernel-4.4.orig/include/linux/mlx5/mlx5_ifc.h
+++ zfcpdump-kernel-4.4/include/linux/mlx5/mlx5_ifc.h
@@ -447,6 +447,29 @@ struct mlx5_ifc_flow_table_nic_cap_bits
 	u8         reserved_3[0x7200];
 };
 
+struct mlx5_ifc_flow_table_eswitch_cap_bits {
+	u8     reserved_0[0x200];
+
+	struct mlx5_ifc_flow_table_prop_layout_bits flow_table_properties_nic_esw_fdb;
+
+	struct mlx5_ifc_flow_table_prop_layout_bits flow_table_properties_esw_acl_ingress;
+
+	struct mlx5_ifc_flow_table_prop_layout_bits flow_table_properties_esw_acl_egress;
+
+	u8      reserved_1[0x7800];
+};
+
+struct mlx5_ifc_e_switch_cap_bits {
+	u8         vport_svlan_strip[0x1];
+	u8         vport_cvlan_strip[0x1];
+	u8         vport_svlan_insert[0x1];
+	u8         vport_cvlan_insert_if_not_exist[0x1];
+	u8         vport_cvlan_insert_overwrite[0x1];
+	u8         reserved_0[0x1b];
+
+	u8         reserved_1[0x7e0];
+};
+
 struct mlx5_ifc_per_protocol_networking_offload_caps_bits {
 	u8         csum_cap[0x1];
 	u8         vlan_cap[0x1];
@@ -665,7 +688,9 @@ struct mlx5_ifc_cmd_hca_cap_bits {
 	u8         reserved_17[0x1];
 	u8         ets[0x1];
 	u8         nic_flow_table[0x1];
-	u8         reserved_18[0x4];
+	u8         eswitch_flow_table[0x1];
+	u8	   early_vf_enable;
+	u8         reserved_18[0x2];
 	u8         local_ca_ack_delay[0x5];
 	u8         reserved_19[0x6];
 	u8         port_type[0x2];
@@ -787,27 +812,36 @@ struct mlx5_ifc_cmd_hca_cap_bits {
 	u8         reserved_60[0x1b];
 	u8         log_max_wq_sz[0x5];
 
-	u8         reserved_61[0xa0];
-
+	u8         nic_vport_change_event[0x1];
+	u8         reserved_61[0xa];
+	u8         log_max_vlan_list[0x5];
 	u8         reserved_62[0x3];
+	u8         log_max_current_mc_list[0x5];
+	u8         reserved_63[0x3];
+	u8         log_max_current_uc_list[0x5];
+
+	u8         reserved_64[0x80];
+
+	u8         reserved_65[0x3];
 	u8         log_max_l2_table[0x5];
-	u8         reserved_63[0x8];
+	u8         reserved_66[0x8];
 	u8         log_uar_page_sz[0x10];
 
-	u8         reserved_64[0x100];
+	u8         reserved_67[0xe0];
 
-	u8         reserved_65[0x1f];
+	u8         reserved_68[0x1f];
 	u8         cqe_zip[0x1];
 
 	u8         cqe_zip_timeout[0x10];
 	u8         cqe_zip_max_num[0x10];
 
-	u8         reserved_66[0x220];
+	u8         reserved_69[0x220];
 };
 
-enum {
-	MLX5_DEST_FORMAT_STRUCT_DESTINATION_TYPE_FLOW_TABLE_  = 0x1,
-	MLX5_DEST_FORMAT_STRUCT_DESTINATION_TYPE_TIR          = 0x2,
+enum mlx5_flow_destination_type {
+	MLX5_FLOW_DESTINATION_TYPE_VPORT        = 0x0,
+	MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE   = 0x1,
+	MLX5_FLOW_DESTINATION_TYPE_TIR          = 0x2,
 };
 
 struct mlx5_ifc_dest_format_struct_bits {
@@ -900,6 +934,13 @@ struct mlx5_ifc_mac_address_layout_bits
 	u8         mac_addr_31_0[0x20];
 };
 
+struct mlx5_ifc_vlan_layout_bits {
+	u8         reserved_0[0x14];
+	u8         vlan[0x0c];
+
+	u8         reserved_1[0x20];
+};
+
 struct mlx5_ifc_cong_control_r_roce_ecn_np_bits {
 	u8         reserved_0[0xa0];
 
@@ -1829,6 +1870,8 @@ union mlx5_ifc_hca_cap_union_bits {
 	struct mlx5_ifc_roce_cap_bits roce_cap;
 	struct mlx5_ifc_per_protocol_networking_offload_caps_bits per_protocol_networking_offload_caps;
 	struct mlx5_ifc_flow_table_nic_cap_bits flow_table_nic_cap;
+	struct mlx5_ifc_flow_table_eswitch_cap_bits flow_table_eswitch_cap;
+	struct mlx5_ifc_e_switch_cap_bits e_switch_cap;
 	u8         reserved_0[0x8000];
 };
 
@@ -2133,24 +2176,35 @@ struct mlx5_ifc_rmpc_bits {
 	struct mlx5_ifc_wq_bits wq;
 };
 
-enum {
-	MLX5_NIC_VPORT_CONTEXT_ALLOWED_LIST_TYPE_CURRENT_UC_MAC_ADDRESS  = 0x0,
-};
-
 struct mlx5_ifc_nic_vport_context_bits {
 	u8         reserved_0[0x1f];
 	u8         roce_en[0x1];
 
-	u8         reserved_1[0x760];
-
-	u8         reserved_2[0x5];
+	u8         arm_change_event[0x1];
+	u8         reserved_1[0x1a];
+	u8         event_on_mtu[0x1];
+	u8         event_on_promisc_change[0x1];
+	u8         event_on_vlan_change[0x1];
+	u8         event_on_mc_address_change[0x1];
+	u8         event_on_uc_address_change[0x1];
+
+	u8         reserved_2[0xf0];
+
+	u8         mtu[0x10];
+
+	u8         reserved_3[0x640];
+
+	u8         promisc_uc[0x1];
+	u8         promisc_mc[0x1];
+	u8         promisc_all[0x1];
+	u8         reserved_4[0x2];
 	u8         allowed_list_type[0x3];
-	u8         reserved_3[0xc];
+	u8         reserved_5[0xc];
 	u8         allowed_list_size[0xc];
 
 	struct mlx5_ifc_mac_address_layout_bits permanent_address;
 
-	u8         reserved_4[0x20];
+	u8         reserved_6[0x20];
 
 	u8         current_uc_mac_address[0][0x40];
 };
@@ -2263,6 +2317,26 @@ struct mlx5_ifc_hca_vport_context_bits {
 	u8         reserved_6[0xca0];
 };
 
+struct mlx5_ifc_esw_vport_context_bits {
+	u8         reserved_0[0x3];
+	u8         vport_svlan_strip[0x1];
+	u8         vport_cvlan_strip[0x1];
+	u8         vport_svlan_insert[0x1];
+	u8         vport_cvlan_insert[0x2];
+	u8         reserved_1[0x18];
+
+	u8         reserved_2[0x20];
+
+	u8         svlan_cfi[0x1];
+	u8         svlan_pcp[0x3];
+	u8         svlan_id[0xc];
+	u8         cvlan_cfi[0x1];
+	u8         cvlan_pcp[0x3];
+	u8         cvlan_id[0xc];
+
+	u8         reserved_3[0x7a0];
+};
+
 enum {
 	MLX5_EQC_STATUS_OK                = 0x0,
 	MLX5_EQC_STATUS_EQ_WRITE_FAILURE  = 0xa,
@@ -2940,6 +3014,7 @@ struct mlx5_ifc_query_vport_state_out_bi
 
 enum {
 	MLX5_QUERY_VPORT_STATE_IN_OP_MOD_VNIC_VPORT  = 0x0,
+	MLX5_QUERY_VPORT_STATE_IN_OP_MOD_ESW_VPORT   = 0x1,
 };
 
 struct mlx5_ifc_query_vport_state_in_bits {
@@ -3700,6 +3775,64 @@ struct mlx5_ifc_query_flow_group_in_bits
 	u8         reserved_5[0x120];
 };
 
+struct mlx5_ifc_query_esw_vport_context_out_bits {
+	u8         status[0x8];
+	u8         reserved_0[0x18];
+
+	u8         syndrome[0x20];
+
+	u8         reserved_1[0x40];
+
+	struct mlx5_ifc_esw_vport_context_bits esw_vport_context;
+};
+
+struct mlx5_ifc_query_esw_vport_context_in_bits {
+	u8         opcode[0x10];
+	u8         reserved_0[0x10];
+
+	u8         reserved_1[0x10];
+	u8         op_mod[0x10];
+
+	u8         other_vport[0x1];
+	u8         reserved_2[0xf];
+	u8         vport_number[0x10];
+
+	u8         reserved_3[0x20];
+};
+
+struct mlx5_ifc_modify_esw_vport_context_out_bits {
+	u8         status[0x8];
+	u8         reserved_0[0x18];
+
+	u8         syndrome[0x20];
+
+	u8         reserved_1[0x40];
+};
+
+struct mlx5_ifc_esw_vport_context_fields_select_bits {
+	u8         reserved[0x1c];
+	u8         vport_cvlan_insert[0x1];
+	u8         vport_svlan_insert[0x1];
+	u8         vport_cvlan_strip[0x1];
+	u8         vport_svlan_strip[0x1];
+};
+
+struct mlx5_ifc_modify_esw_vport_context_in_bits {
+	u8         opcode[0x10];
+	u8         reserved_0[0x10];
+
+	u8         reserved_1[0x10];
+	u8         op_mod[0x10];
+
+	u8         other_vport[0x1];
+	u8         reserved_2[0xf];
+	u8         vport_number[0x10];
+
+	struct mlx5_ifc_esw_vport_context_fields_select_bits field_select;
+
+	struct mlx5_ifc_esw_vport_context_bits esw_vport_context;
+};
+
 struct mlx5_ifc_query_eq_out_bits {
 	u8         status[0x8];
 	u8         reserved_0[0x18];
@@ -4228,7 +4361,10 @@ struct mlx5_ifc_modify_nic_vport_context
 };
 
 struct mlx5_ifc_modify_nic_vport_field_select_bits {
-	u8         reserved_0[0x1c];
+	u8         reserved_0[0x19];
+	u8         mtu[0x1];
+	u8         change_event[0x1];
+	u8         promisc[0x1];
 	u8         permanent_address[0x1];
 	u8         addresses_list[0x1];
 	u8         roce_en[0x1];
--- /dev/null
+++ zfcpdump-kernel-4.4/include/linux/mlx5/port.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2016, Mellanox Technologies. All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef __MLX5_PORT_H__
+#define __MLX5_PORT_H__
+
+#include <linux/mlx5/driver.h>
+
+int mlx5_set_port_caps(struct mlx5_core_dev *dev, u8 port_num, u32 caps);
+int mlx5_query_port_ptys(struct mlx5_core_dev *dev, u32 *ptys,
+			 int ptys_size, int proto_mask, u8 local_port);
+int mlx5_query_port_proto_cap(struct mlx5_core_dev *dev,
+			      u32 *proto_cap, int proto_mask);
+int mlx5_query_port_proto_admin(struct mlx5_core_dev *dev,
+				u32 *proto_admin, int proto_mask);
+int mlx5_query_port_link_width_oper(struct mlx5_core_dev *dev,
+				    u8 *link_width_oper, u8 local_port);
+int mlx5_query_port_proto_oper(struct mlx5_core_dev *dev,
+			       u8 *proto_oper, int proto_mask,
+			       u8 local_port);
+int mlx5_set_port_proto(struct mlx5_core_dev *dev, u32 proto_admin,
+			int proto_mask);
+int mlx5_set_port_admin_status(struct mlx5_core_dev *dev,
+			       enum mlx5_port_status status);
+int mlx5_query_port_admin_status(struct mlx5_core_dev *dev,
+				 enum mlx5_port_status *status);
+
+int mlx5_set_port_mtu(struct mlx5_core_dev *dev, u16 mtu, u8 port);
+void mlx5_query_port_max_mtu(struct mlx5_core_dev *dev, u16 *max_mtu, u8 port);
+void mlx5_query_port_oper_mtu(struct mlx5_core_dev *dev, u16 *oper_mtu,
+			      u8 port);
+
+int mlx5_query_port_vl_hw_cap(struct mlx5_core_dev *dev,
+			      u8 *vl_hw_cap, u8 local_port);
+
+int mlx5_set_port_pause(struct mlx5_core_dev *dev, u32 rx_pause, u32 tx_pause);
+int mlx5_query_port_pause(struct mlx5_core_dev *dev,
+			  u32 *rx_pause, u32 *tx_pause);
+
+#endif /* __MLX5_PORT_H__ */
--- zfcpdump-kernel-4.4.orig/include/linux/mlx5/qp.h
+++ zfcpdump-kernel-4.4/include/linux/mlx5/qp.h
@@ -160,6 +160,7 @@ enum {
 enum {
 	MLX5_FENCE_MODE_NONE			= 0 << 5,
 	MLX5_FENCE_MODE_INITIATOR_SMALL		= 1 << 5,
+	MLX5_FENCE_MODE_FENCE			= 2 << 5,
 	MLX5_FENCE_MODE_STRONG_ORDERING		= 3 << 5,
 	MLX5_FENCE_MODE_SMALL_AND_FENCE		= 4 << 5,
 };
@@ -534,9 +535,9 @@ struct mlx5_destroy_qp_mbox_out {
 struct mlx5_modify_qp_mbox_in {
 	struct mlx5_inbox_hdr	hdr;
 	__be32			qpn;
-	u8			rsvd1[4];
-	__be32			optparam;
 	u8			rsvd0[4];
+	__be32			optparam;
+	u8			rsvd1[4];
 	struct mlx5_qp_context	ctx;
 };
 
--- zfcpdump-kernel-4.4.orig/include/linux/mlx5/vport.h
+++ zfcpdump-kernel-4.4/include/linux/mlx5/vport.h
@@ -34,9 +34,17 @@
 #define __MLX5_VPORT_H__
 
 #include <linux/mlx5/driver.h>
+#include <linux/mlx5/device.h>
 
-u8 mlx5_query_vport_state(struct mlx5_core_dev *mdev, u8 opmod);
-void mlx5_query_nic_vport_mac_address(struct mlx5_core_dev *mdev, u8 *addr);
+u8 mlx5_query_vport_state(struct mlx5_core_dev *mdev, u8 opmod, u16 vport);
+u8 mlx5_query_vport_admin_state(struct mlx5_core_dev *mdev, u8 opmod,
+				u16 vport);
+int mlx5_modify_vport_admin_state(struct mlx5_core_dev *mdev, u8 opmod,
+				  u16 vport, u8 state);
+int mlx5_query_nic_vport_mac_address(struct mlx5_core_dev *mdev,
+				     u16 vport, u8 *addr);
+int mlx5_modify_nic_vport_mac_address(struct mlx5_core_dev *dev,
+				      u16 vport, u8 *addr);
 int mlx5_query_hca_vport_gid(struct mlx5_core_dev *dev, u8 other_vport,
 			     u8 port_num, u16  vf_num, u16 gid_index,
 			     union ib_gid *gid);
@@ -51,5 +59,30 @@ int mlx5_query_hca_vport_system_image_gu
 					   u64 *sys_image_guid);
 int mlx5_query_hca_vport_node_guid(struct mlx5_core_dev *dev,
 				   u64 *node_guid);
+int mlx5_query_nic_vport_mac_list(struct mlx5_core_dev *dev,
+				  u32 vport,
+				  enum mlx5_list_type list_type,
+				  u8 addr_list[][ETH_ALEN],
+				  int *list_size);
+int mlx5_modify_nic_vport_mac_list(struct mlx5_core_dev *dev,
+				   enum mlx5_list_type list_type,
+				   u8 addr_list[][ETH_ALEN],
+				   int list_size);
+int mlx5_query_nic_vport_promisc(struct mlx5_core_dev *mdev,
+				 u32 vport,
+				 int *promisc_uc,
+				 int *promisc_mc,
+				 int *promisc_all);
+int mlx5_modify_nic_vport_promisc(struct mlx5_core_dev *mdev,
+				  int promisc_uc,
+				  int promisc_mc,
+				  int promisc_all);
+int mlx5_query_nic_vport_vlans(struct mlx5_core_dev *dev,
+			       u32 vport,
+			       u16 vlans[],
+			       int *size);
+int mlx5_modify_nic_vport_vlans(struct mlx5_core_dev *dev,
+				u16 vlans[],
+				int list_size);
 
 #endif /* __MLX5_VPORT_H__ */
--- zfcpdump-kernel-4.4.orig/include/linux/mm.h
+++ zfcpdump-kernel-4.4/include/linux/mm.h
@@ -1084,6 +1084,8 @@ struct zap_details {
 
 struct page *vm_normal_page(struct vm_area_struct *vma, unsigned long addr,
 		pte_t pte);
+struct page *vm_normal_page_pmd(struct vm_area_struct *vma, unsigned long addr,
+				pmd_t pmd);
 
 int zap_vma_ptes(struct vm_area_struct *vma, unsigned long address,
 		unsigned long size);
@@ -1183,6 +1185,28 @@ static inline int fixup_user_fault(struc
 }
 #endif
 
+extern void vma_do_file_update_time(struct vm_area_struct *, const char[], int);
+extern struct file *vma_do_pr_or_file(struct vm_area_struct *, const char[],
+				      int);
+extern void vma_do_get_file(struct vm_area_struct *, const char[], int);
+extern void vma_do_fput(struct vm_area_struct *, const char[], int);
+
+#define vma_file_update_time(vma)	vma_do_file_update_time(vma, __func__, \
+								__LINE__)
+#define vma_pr_or_file(vma)		vma_do_pr_or_file(vma, __func__, \
+							  __LINE__)
+#define vma_get_file(vma)		vma_do_get_file(vma, __func__, __LINE__)
+#define vma_fput(vma)			vma_do_fput(vma, __func__, __LINE__)
+
+#ifndef CONFIG_MMU
+extern struct file *vmr_do_pr_or_file(struct vm_region *, const char[], int);
+extern void vmr_do_fput(struct vm_region *, const char[], int);
+
+#define vmr_pr_or_file(region)		vmr_do_pr_or_file(region, __func__, \
+							  __LINE__)
+#define vmr_fput(region)		vmr_do_fput(region, __func__, __LINE__)
+#endif /* !CONFIG_MMU */
+
 extern int access_process_vm(struct task_struct *tsk, unsigned long addr, void *buf, int len, int write);
 extern int access_remote_vm(struct mm_struct *mm, unsigned long addr,
 		void *buf, int len, int write);
@@ -1309,8 +1333,7 @@ static inline int stack_guard_page_end(s
 		!vma_growsup(vma->vm_next, addr);
 }
 
-extern struct task_struct *task_of_stack(struct task_struct *task,
-				struct vm_area_struct *vma, bool in_group);
+int vma_is_stack_for_task(struct vm_area_struct *vma, struct task_struct *t);
 
 extern unsigned long move_page_tables(struct vm_area_struct *vma,
 		unsigned long old_addr, struct vm_area_struct *new_vma,
@@ -1694,7 +1717,7 @@ extern void free_highmem_page(struct pag
 extern void adjust_managed_page_count(struct page *page, long count);
 extern void mem_init_print_info(const char *str);
 
-extern void reserve_bootmem_region(unsigned long start, unsigned long end);
+extern void reserve_bootmem_region(phys_addr_t start, phys_addr_t end);
 
 /* Free the reserved page into the buddy system, so it gets managed. */
 static inline void __free_reserved_page(struct page *page)
@@ -1806,6 +1829,7 @@ extern int __meminit init_per_zone_wmark
 extern void mem_init(void);
 extern void __init mmap_init(void);
 extern void show_mem(unsigned int flags);
+extern long si_mem_available(void);
 extern void si_meminfo(struct sysinfo * val);
 extern void si_meminfo_node(struct sysinfo *val, int nid);
 
@@ -1897,6 +1921,7 @@ extern void mm_drop_all_locks(struct mm_
 
 extern void set_mm_exe_file(struct mm_struct *mm, struct file *new_exe_file);
 extern struct file *get_mm_exe_file(struct mm_struct *mm);
+extern struct file *get_task_exe_file(struct task_struct *task);
 
 extern int may_expand_vm(struct mm_struct *mm, unsigned long npages);
 extern struct vm_area_struct *_install_special_mapping(struct mm_struct *mm,
@@ -2110,6 +2135,7 @@ static inline struct page *follow_page(s
 #define FOLL_MIGRATION	0x400	/* wait for page to replace migration entry */
 #define FOLL_TRIED	0x800	/* a retry, previous pass started an IO */
 #define FOLL_MLOCK	0x1000	/* lock present pages */
+#define FOLL_COW	0x4000	/* internal GUP flag */
 
 typedef int (*pte_fn_t)(pte_t *pte, pgtable_t token, unsigned long addr,
 			void *data);
--- zfcpdump-kernel-4.4.orig/include/linux/mm_types.h
+++ zfcpdump-kernel-4.4/include/linux/mm_types.h
@@ -272,6 +272,7 @@ struct vm_region {
 	unsigned long	vm_top;		/* region allocated to here */
 	unsigned long	vm_pgoff;	/* the offset in vm_file corresponding to vm_start */
 	struct file	*vm_file;	/* the backing file or NULL */
+	struct file	*vm_prfile;	/* the virtual backing file or NULL */
 
 	int		vm_usage;	/* region usage count (access under nommu_region_sem) */
 	bool		vm_icache_flushed : 1; /* true if the icache has been flushed for
@@ -346,6 +347,7 @@ struct vm_area_struct {
 	unsigned long vm_pgoff;		/* Offset (within vm_file) in PAGE_SIZE
 					   units, *not* PAGE_CACHE_SIZE */
 	struct file * vm_file;		/* File we map to (can be NULL). */
+	struct file *vm_prfile;		/* shadow of vm_file */
 	void * vm_private_data;		/* was vm_pte (shared mem) */
 
 #ifndef CONFIG_MMU
--- zfcpdump-kernel-4.4.orig/include/linux/mmc/dw_mmc.h
+++ zfcpdump-kernel-4.4/include/linux/mmc/dw_mmc.h
@@ -172,7 +172,7 @@ struct dw_mci {
 	/* For edmac */
 	struct dw_mci_dma_slave *dms;
 	/* Registers's physical base address */
-	void                    *phy_regs;
+	resource_size_t		phy_regs;
 
 	u32			cmd_status;
 	u32			data_status;
--- zfcpdump-kernel-4.4.orig/include/linux/mod_devicetable.h
+++ zfcpdump-kernel-4.4/include/linux/mod_devicetable.h
@@ -404,7 +404,7 @@ struct virtio_device_id {
  * For Hyper-V devices we use the device guid as the id.
  */
 struct hv_vmbus_device_id {
-	__u8 guid[16];
+	uuid_le guid;
 	kernel_ulong_t driver_data;	/* Data private to the driver */
 };
 
--- zfcpdump-kernel-4.4.orig/include/linux/module.h
+++ zfcpdump-kernel-4.4/include/linux/module.h
@@ -273,6 +273,12 @@ const struct exception_table_entry *sear
 
 struct notifier_block;
 
+#ifdef CONFIG_MODULE_SIG
+extern void enforce_signed_modules(void);
+#else
+static inline void enforce_signed_modules(void) {};
+#endif
+
 #ifdef CONFIG_MODULES
 
 extern int modules_disabled; /* for sysctl */
@@ -302,6 +308,34 @@ struct mod_tree_node {
 	struct latch_tree_node node;
 };
 
+struct module_layout {
+	/* The actual code + data. */
+	void *base;
+	/* Total size. */
+	unsigned int size;
+	/* The size of the executable code.  */
+	unsigned int text_size;
+	/* Size of RO section of the module (text+rodata) */
+	unsigned int ro_size;
+
+#ifdef CONFIG_MODULES_TREE_LOOKUP
+	struct mod_tree_node mtn;
+#endif
+};
+
+#ifdef CONFIG_MODULES_TREE_LOOKUP
+/* Only touch one cacheline for common rbtree-for-core-layout case. */
+#define __module_layout_align ____cacheline_aligned
+#else
+#define __module_layout_align
+#endif
+
+struct mod_kallsyms {
+	Elf_Sym *symtab;
+	unsigned int num_symtab;
+	char *strtab;
+};
+
 struct module {
 	enum module_state state;
 
@@ -366,37 +400,9 @@ struct module {
 	/* Startup function. */
 	int (*init)(void);
 
-	/*
-	 * If this is non-NULL, vfree() after init() returns.
-	 *
-	 * Cacheline align here, such that:
-	 *   module_init, module_core, init_size, core_size,
-	 *   init_text_size, core_text_size and mtn_core::{mod,node[0]}
-	 * are on the same cacheline.
-	 */
-	void *module_init	____cacheline_aligned;
-
-	/* Here is the actual code + data, vfree'd on unload. */
-	void *module_core;
-
-	/* Here are the sizes of the init and core sections */
-	unsigned int init_size, core_size;
-
-	/* The size of the executable code in each section.  */
-	unsigned int init_text_size, core_text_size;
-
-#ifdef CONFIG_MODULES_TREE_LOOKUP
-	/*
-	 * We want mtn_core::{mod,node[0]} to be in the same cacheline as the
-	 * above entries such that a regular lookup will only touch one
-	 * cacheline.
-	 */
-	struct mod_tree_node	mtn_core;
-	struct mod_tree_node	mtn_init;
-#endif
-
-	/* Size of RO sections of the module (text+rodata) */
-	unsigned int init_ro_size, core_ro_size;
+	/* Core layout: rbtree is accessed frequently, so keep together. */
+	struct module_layout core_layout __module_layout_align;
+	struct module_layout init_layout;
 
 	/* Arch-specific module values */
 	struct mod_arch_specific arch;
@@ -411,15 +417,10 @@ struct module {
 #endif
 
 #ifdef CONFIG_KALLSYMS
-	/*
-	 * We keep the symbol and string tables for kallsyms.
-	 * The core_* fields below are temporary, loader-only (they
-	 * could really be discarded after module init).
-	 */
-	Elf_Sym *symtab, *core_symtab;
-	unsigned int num_symtab, core_num_syms;
-	char *strtab, *core_strtab;
-
+	/* Protected by RCU and/or module_mutex: use rcu_dereference() */
+	struct mod_kallsyms *kallsyms;
+	struct mod_kallsyms core_kallsyms;
+	
 	/* Section attributes */
 	struct module_sect_attrs *sect_attrs;
 
@@ -505,15 +506,15 @@ bool is_module_text_address(unsigned lon
 static inline bool within_module_core(unsigned long addr,
 				      const struct module *mod)
 {
-	return (unsigned long)mod->module_core <= addr &&
-	       addr < (unsigned long)mod->module_core + mod->core_size;
+	return (unsigned long)mod->core_layout.base <= addr &&
+	       addr < (unsigned long)mod->core_layout.base + mod->core_layout.size;
 }
 
 static inline bool within_module_init(unsigned long addr,
 				      const struct module *mod)
 {
-	return (unsigned long)mod->module_init <= addr &&
-	       addr < (unsigned long)mod->module_init + mod->init_size;
+	return (unsigned long)mod->init_layout.base <= addr &&
+	       addr < (unsigned long)mod->init_layout.base + mod->init_layout.size;
 }
 
 static inline bool within_module(unsigned long addr, const struct module *mod)
@@ -635,6 +636,8 @@ static inline bool module_requested_asyn
 	return module && module->async_probe_requested;
 }
 
+extern bool secure_modules(void);
+
 #else /* !CONFIG_MODULES... */
 
 /* Given an address, look for it in the exception tables. */
@@ -751,6 +754,10 @@ static inline bool module_requested_asyn
 	return false;
 }
 
+static inline bool secure_modules(void)
+{
+	return false;
+}
 #endif /* CONFIG_MODULES */
 
 #ifdef CONFIG_SYSFS
@@ -768,9 +775,13 @@ extern int module_sysfs_initialized;
 #ifdef CONFIG_DEBUG_SET_MODULE_RONX
 extern void set_all_modules_text_rw(void);
 extern void set_all_modules_text_ro(void);
+extern void module_enable_ro(const struct module *mod);
+extern void module_disable_ro(const struct module *mod);
 #else
 static inline void set_all_modules_text_rw(void) { }
 static inline void set_all_modules_text_ro(void) { }
+static inline void module_enable_ro(const struct module *mod) { }
+static inline void module_disable_ro(const struct module *mod) { }
 #endif
 
 #ifdef CONFIG_GENERIC_BUG
--- zfcpdump-kernel-4.4.orig/include/linux/mount.h
+++ zfcpdump-kernel-4.4/include/linux/mount.h
@@ -81,6 +81,7 @@ extern void mntput(struct vfsmount *mnt)
 extern struct vfsmount *mntget(struct vfsmount *mnt);
 extern struct vfsmount *mnt_clone_internal(struct path *path);
 extern int __mnt_is_readonly(struct vfsmount *mnt);
+extern bool mnt_may_suid(struct vfsmount *mnt);
 
 struct path;
 extern struct vfsmount *clone_private_mount(struct path *path);
--- zfcpdump-kernel-4.4.orig/include/linux/msi.h
+++ zfcpdump-kernel-4.4/include/linux/msi.h
@@ -254,12 +254,12 @@ enum {
 	 * callbacks.
 	 */
 	MSI_FLAG_USE_DEF_CHIP_OPS	= (1 << 1),
-	/* Build identity map between hwirq and irq */
-	MSI_FLAG_IDENTITY_MAP		= (1 << 2),
 	/* Support multiple PCI MSI interrupts */
-	MSI_FLAG_MULTI_PCI_MSI		= (1 << 3),
+	MSI_FLAG_MULTI_PCI_MSI		= (1 << 2),
 	/* Support PCI MSIX interrupts */
-	MSI_FLAG_PCI_MSIX		= (1 << 4),
+	MSI_FLAG_PCI_MSIX		= (1 << 3),
+	/* Needs early activate, required for PCI */
+	MSI_FLAG_ACTIVATE_EARLY		= (1 << 4),
 };
 
 int msi_domain_set_affinity(struct irq_data *data, const struct cpumask *mask,
--- zfcpdump-kernel-4.4.orig/include/linux/net.h
+++ zfcpdump-kernel-4.4/include/linux/net.h
@@ -245,7 +245,16 @@ do {								\
 	net_ratelimited_function(pr_warn, fmt, ##__VA_ARGS__)
 #define net_info_ratelimited(fmt, ...)				\
 	net_ratelimited_function(pr_info, fmt, ##__VA_ARGS__)
-#if defined(DEBUG)
+#if defined(CONFIG_DYNAMIC_DEBUG)
+#define net_dbg_ratelimited(fmt, ...)					\
+do {									\
+	DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, fmt);			\
+	if (unlikely(descriptor.flags & _DPRINTK_FLAGS_PRINT) &&	\
+	    net_ratelimit())						\
+		__dynamic_pr_debug(&descriptor, pr_fmt(fmt),		\
+		                   ##__VA_ARGS__);			\
+} while (0)
+#elif defined(DEBUG)
 #define net_dbg_ratelimited(fmt, ...)				\
 	net_ratelimited_function(pr_debug, fmt, ##__VA_ARGS__)
 #else
--- zfcpdump-kernel-4.4.orig/include/linux/netdev_features.h
+++ zfcpdump-kernel-4.4/include/linux/netdev_features.h
@@ -52,7 +52,7 @@ enum {
 		NETIF_F_GSO_TUNNEL_REMCSUM_BIT,
 
 	NETIF_F_FCOE_CRC_BIT,		/* FCoE CRC32 */
-	NETIF_F_SCTP_CSUM_BIT,		/* SCTP checksum offload */
+	NETIF_F_SCTP_CRC_BIT,		/* SCTP checksum offload */
 	NETIF_F_FCOE_MTU_BIT,		/* Supports max FCoE MTU, 2158 bytes*/
 	NETIF_F_NTUPLE_BIT,		/* N-tuple filters supported */
 	NETIF_F_RXHASH_BIT,		/* Receive hashing offload */
@@ -67,6 +67,8 @@ enum {
 	NETIF_F_HW_L2FW_DOFFLOAD_BIT,	/* Allow L2 Forwarding in Hardware */
 	NETIF_F_BUSY_POLL_BIT,		/* Busy poll */
 
+	NETIF_F_HW_TC_BIT,		/* Offload TC infrastructure */
+
 	/*
 	 * Add your fresh new feature above and remember to update
 	 * netdev_features_strings[] in net/core/ethtool.c and maybe
@@ -103,7 +105,7 @@ enum {
 #define NETIF_F_NTUPLE		__NETIF_F(NTUPLE)
 #define NETIF_F_RXCSUM		__NETIF_F(RXCSUM)
 #define NETIF_F_RXHASH		__NETIF_F(RXHASH)
-#define NETIF_F_SCTP_CSUM	__NETIF_F(SCTP_CSUM)
+#define NETIF_F_SCTP_CRC	__NETIF_F(SCTP_CRC)
 #define NETIF_F_SG		__NETIF_F(SG)
 #define NETIF_F_TSO6		__NETIF_F(TSO6)
 #define NETIF_F_TSO_ECN		__NETIF_F(TSO_ECN)
@@ -124,6 +126,7 @@ enum {
 #define NETIF_F_HW_VLAN_STAG_TX	__NETIF_F(HW_VLAN_STAG_TX)
 #define NETIF_F_HW_L2FW_DOFFLOAD	__NETIF_F(HW_L2FW_DOFFLOAD)
 #define NETIF_F_BUSY_POLL	__NETIF_F(BUSY_POLL)
+#define NETIF_F_HW_TC		__NETIF_F(HW_TC)
 
 #define for_each_netdev_feature(mask_addr, bit)	\
 	for_each_set_bit(bit, (unsigned long *)mask_addr, NETDEV_FEATURE_COUNT)
--- zfcpdump-kernel-4.4.orig/include/linux/netdevice.h
+++ zfcpdump-kernel-4.4/include/linux/netdevice.h
@@ -51,6 +51,7 @@
 #include <linux/neighbour.h>
 #include <uapi/linux/netdevice.h>
 #include <uapi/linux/if_bonding.h>
+#include <uapi/linux/pkt_cls.h>
 
 struct netpoll_info;
 struct device;
@@ -132,7 +133,9 @@ static inline bool dev_xmit_complete(int
  *	used.
  */
 
-#if defined(CONFIG_WLAN) || IS_ENABLED(CONFIG_AX25)
+#if defined(CONFIG_HYPERV_NET)
+# define LL_MAX_HEADER 128
+#elif defined(CONFIG_WLAN) || IS_ENABLED(CONFIG_AX25)
 # if defined(CONFIG_MAC80211_MESH)
 #  define LL_MAX_HEADER 128
 # else
@@ -265,6 +268,7 @@ struct header_ops {
 	void	(*cache_update)(struct hh_cache *hh,
 				const struct net_device *dev,
 				const unsigned char *haddr);
+	bool	(*validate)(const char *ll_header, unsigned int len);
 };
 
 /* These flag bits are private to the generic network queueing
@@ -510,7 +514,6 @@ static inline void napi_enable(struct na
 	clear_bit(NAPI_STATE_NPSVC, &n->state);
 }
 
-#ifdef CONFIG_SMP
 /**
  *	napi_synchronize - wait until NAPI is not running
  *	@n: napi context
@@ -521,12 +524,12 @@ static inline void napi_enable(struct na
  */
 static inline void napi_synchronize(const struct napi_struct *n)
 {
-	while (test_bit(NAPI_STATE_SCHED, &n->state))
-		msleep(1);
+	if (IS_ENABLED(CONFIG_SMP))
+		while (test_bit(NAPI_STATE_SCHED, &n->state))
+			msleep(1);
+	else
+		barrier();
 }
-#else
-# define napi_synchronize(n)	barrier()
-#endif
 
 enum netdev_queue_state_t {
 	__QUEUE_STATE_DRV_XOFF,
@@ -777,6 +780,25 @@ static inline bool netdev_phys_item_id_s
 typedef u16 (*select_queue_fallback_t)(struct net_device *dev,
 				       struct sk_buff *skb);
 
+/* These structures hold the attributes of qdisc and classifiers
+ * that are being passed to the netdevice through the setup_tc op.
+ */
+enum {
+	TC_SETUP_MQPRIO,
+	TC_SETUP_CLSU32,
+};
+
+struct tc_cls_u32_offload;
+
+struct tc_to_netdev {
+	unsigned int type;
+	union {
+		u8 tc;
+		struct tc_cls_u32_offload *cls_u32;
+	};
+};
+
+
 /*
  * This structure defines the management hooks for network devices.
  * The following hooks can be defined; unless noted otherwise, they are
@@ -1011,6 +1033,19 @@ typedef u16 (*select_queue_fallback_t)(s
  *	a new port starts listening. The operation is protected by the
  *	vxlan_net->sock_lock.
  *
+ * void (*ndo_add_geneve_port)(struct net_device *dev,
+ *			      sa_family_t sa_family, __be16 port);
+ *	Called by geneve to notify a driver about the UDP port and socket
+ *	address family that geneve is listnening to. It is called only when
+ *	a new port starts listening. The operation is protected by the
+ *	geneve_net->sock_lock.
+ *
+ * void (*ndo_del_geneve_port)(struct net_device *dev,
+ *			      sa_family_t sa_family, __be16 port);
+ *	Called by geneve to notify the driver about a UDP port and socket
+ *	address family that geneve is not listening to anymore. The operation
+ *	is protected by the geneve_net->sock_lock.
+ *
  * void (*ndo_del_vxlan_port)(struct  net_device *dev,
  *			      sa_family_t sa_family, __be16 port);
  *	Called by vxlan to notify the driver about a UDP port and socket
@@ -1133,7 +1168,10 @@ struct net_device_ops {
 	int			(*ndo_set_vf_rss_query_en)(
 						   struct net_device *dev,
 						   int vf, bool setting);
-	int			(*ndo_setup_tc)(struct net_device *dev, u8 tc);
+	int			(*ndo_setup_tc)(struct net_device *dev,
+						u32 handle,
+						__be16 protocol,
+						struct tc_to_netdev *tc);
 #if IS_ENABLED(CONFIG_FCOE)
 	int			(*ndo_fcoe_enable)(struct net_device *dev);
 	int			(*ndo_fcoe_disable)(struct net_device *dev);
@@ -1215,7 +1253,12 @@ struct net_device_ops {
 	void			(*ndo_del_vxlan_port)(struct  net_device *dev,
 						      sa_family_t sa_family,
 						      __be16 port);
-
+	void			(*ndo_add_geneve_port)(struct  net_device *dev,
+						       sa_family_t sa_family,
+						       __be16 port);
+	void			(*ndo_del_geneve_port)(struct  net_device *dev,
+						       sa_family_t sa_family,
+						       __be16 port);
 	void*			(*ndo_dfwd_add_station)(struct net_device *pdev,
 							struct net_device *dev);
 	void			(*ndo_dfwd_del_station)(struct net_device *pdev,
@@ -1271,6 +1314,8 @@ struct net_device_ops {
  * @IFF_NO_QUEUE: device can run without qdisc attached
  * @IFF_OPENVSWITCH: device is a Open vSwitch master
  * @IFF_L3MDEV_SLAVE: device is enslaved to an L3 master device
+ * @IFF_TEAM: device is a team device
+ * @IFF_RXFH_CONFIGURED: device has had Rx Flow indirection table configured
  */
 enum netdev_priv_flags {
 	IFF_802_1Q_VLAN			= 1<<0,
@@ -1297,6 +1342,8 @@ enum netdev_priv_flags {
 	IFF_NO_QUEUE			= 1<<21,
 	IFF_OPENVSWITCH			= 1<<22,
 	IFF_L3MDEV_SLAVE		= 1<<23,
+	IFF_TEAM			= 1<<24,
+	IFF_RXFH_CONFIGURED		= 1<<25,
 };
 
 #define IFF_802_1Q_VLAN			IFF_802_1Q_VLAN
@@ -1323,6 +1370,8 @@ enum netdev_priv_flags {
 #define IFF_NO_QUEUE			IFF_NO_QUEUE
 #define IFF_OPENVSWITCH			IFF_OPENVSWITCH
 #define IFF_L3MDEV_SLAVE		IFF_L3MDEV_SLAVE
+#define IFF_TEAM			IFF_TEAM
+#define IFF_RXFH_CONFIGURED		IFF_RXFH_CONFIGURED
 
 /**
  *	struct net_device - The DEVICE structure.
@@ -1398,8 +1447,7 @@ enum netdev_priv_flags {
  *	@dma:		DMA channel
  *	@mtu:		Interface MTU value
  *	@type:		Interface hardware type
- *	@hard_header_len: Hardware header length, which means that this is the
- *			  minimum size of a packet.
+ *	@hard_header_len: Maximum hardware header length.
  *
  *	@needed_headroom: Extra headroom the hardware may need, but not in all
  *			  cases can this be guaranteed
@@ -1987,8 +2035,8 @@ struct napi_gro_cb {
 	/* This is non-zero if the packet may be of the same flow. */
 	u8	same_flow:1;
 
-	/* Used in udp_gro_receive */
-	u8	udp_mark:1;
+	/* Used in tunnel GRO receive */
+	u8	encap_mark:1;
 
 	/* GRO checksum is valid */
 	u8	csum_valid:1;
@@ -2004,7 +2052,10 @@ struct napi_gro_cb {
 	/* Used in foo-over-udp, set in udp[46]_gro_receive */
 	u8	is_ipv6:1;
 
-	/* 7 bit hole */
+	/* Number of gro_receive callbacks this packet already went through */
+	u8 recursion_counter:4;
+
+	/* 3 bit hole */
 
 	/* used to support CHECKSUM_COMPLETE for tunneling protocols */
 	__wsum	csum;
@@ -2015,6 +2066,25 @@ struct napi_gro_cb {
 
 #define NAPI_GRO_CB(skb) ((struct napi_gro_cb *)(skb)->cb)
 
+#define GRO_RECURSION_LIMIT 15
+static inline int gro_recursion_inc_test(struct sk_buff *skb)
+{
+	return ++NAPI_GRO_CB(skb)->recursion_counter == GRO_RECURSION_LIMIT;
+}
+
+typedef struct sk_buff **(*gro_receive_t)(struct sk_buff **, struct sk_buff *);
+static inline struct sk_buff **call_gro_receive(gro_receive_t cb,
+						struct sk_buff **head,
+						struct sk_buff *skb)
+{
+	if (gro_recursion_inc_test(skb)) {
+		NAPI_GRO_CB(skb)->flush |= 1;
+		return NULL;
+	}
+
+	return cb(head, skb);
+}
+
 struct packet_type {
 	__be16			type;	/* This is really htons(ether_type). */
 	struct net_device	*dev;	/* NULL is wildcarded here	     */
@@ -2493,6 +2563,24 @@ static inline int dev_parse_header(const
 	return dev->header_ops->parse(skb, haddr);
 }
 
+/* ll_header must have at least hard_header_len allocated */
+static inline bool dev_validate_header(const struct net_device *dev,
+				       char *ll_header, int len)
+{
+	if (likely(len >= dev->hard_header_len))
+		return true;
+
+	if (capable(CAP_SYS_RAWIO)) {
+		memset(ll_header + len, 0, dev->hard_header_len - len);
+		return true;
+	}
+
+	if (dev->header_ops && dev->header_ops->validate)
+		return dev->header_ops->validate(ll_header, len);
+
+	return false;
+}
+
 typedef int gifconf_func_t(struct net_device * dev, char __user * bufptr, int len);
 int register_gifconf(unsigned int family, gifconf_func_t *gifconf);
 static inline int unregister_gifconf(unsigned int family)
@@ -3019,6 +3107,7 @@ static inline void napi_free_frags(struc
 	napi->skb = NULL;
 }
 
+bool netdev_is_rx_handler_busy(struct net_device *dev);
 int netdev_rx_handler_register(struct net_device *dev,
 			       rx_handler_func_t *rx_handler,
 			       void *rx_handler_data);
@@ -3868,6 +3957,31 @@ static inline bool netif_is_ovs_master(c
 	return dev->priv_flags & IFF_OPENVSWITCH;
 }
 
+static inline bool netif_is_team_master(struct net_device *dev)
+{
+	return dev->priv_flags & IFF_TEAM;
+}
+
+static inline bool netif_is_team_port(struct net_device *dev)
+{
+	return dev->priv_flags & IFF_TEAM_PORT;
+}
+
+static inline bool netif_is_lag_master(struct net_device *dev)
+{
+	return netif_is_bond_master(dev) || netif_is_team_master(dev);
+}
+
+static inline bool netif_is_lag_port(struct net_device *dev)
+{
+	return netif_is_bond_slave(dev) || netif_is_team_port(dev);
+}
+
+static inline bool netif_is_rxfh_configured(const struct net_device *dev)
+{
+	return dev->priv_flags & IFF_RXFH_CONFIGURED;
+}
+
 /* This device needs to keep skb dst for qdisc enqueue or ndo_start_xmit() */
 static inline void netif_keep_dst(struct net_device *dev)
 {
--- zfcpdump-kernel-4.4.orig/include/linux/netfilter/x_tables.h
+++ zfcpdump-kernel-4.4/include/linux/netfilter/x_tables.h
@@ -239,11 +239,18 @@ void xt_unregister_match(struct xt_match
 int xt_register_matches(struct xt_match *match, unsigned int n);
 void xt_unregister_matches(struct xt_match *match, unsigned int n);
 
+int xt_check_entry_offsets(const void *base, const char *elems,
+			   unsigned int target_offset,
+			   unsigned int next_offset);
+
 int xt_check_match(struct xt_mtchk_param *, unsigned int size, u_int8_t proto,
 		   bool inv_proto);
 int xt_check_target(struct xt_tgchk_param *, unsigned int size, u_int8_t proto,
 		    bool inv_proto);
 
+void *xt_copy_counters_from_user(const void __user *user, unsigned int len,
+				 struct xt_counters_info *info, bool compat);
+
 struct xt_table *xt_register_table(struct net *net,
 				   const struct xt_table *table,
 				   struct xt_table_info *bootstrap,
@@ -478,7 +485,7 @@ void xt_compat_init_offsets(u_int8_t af,
 int xt_compat_calc_jump(u_int8_t af, unsigned int offset);
 
 int xt_compat_match_offset(const struct xt_match *match);
-int xt_compat_match_from_user(struct xt_entry_match *m, void **dstptr,
+void xt_compat_match_from_user(struct xt_entry_match *m, void **dstptr,
 			      unsigned int *size);
 int xt_compat_match_to_user(const struct xt_entry_match *m,
 			    void __user **dstptr, unsigned int *size);
@@ -488,6 +495,9 @@ void xt_compat_target_from_user(struct x
 				unsigned int *size);
 int xt_compat_target_to_user(const struct xt_entry_target *t,
 			     void __user **dstptr, unsigned int *size);
+int xt_compat_check_entry_offsets(const void *base, const char *elems,
+				  unsigned int target_offset,
+				  unsigned int next_offset);
 
 #endif /* CONFIG_COMPAT */
 #endif /* _X_TABLES_H */
--- zfcpdump-kernel-4.4.orig/include/linux/nfs_fs.h
+++ zfcpdump-kernel-4.4/include/linux/nfs_fs.h
@@ -544,9 +544,7 @@ extern int  nfs_readpage_async(struct nf
 
 static inline loff_t nfs_size_to_loff_t(__u64 size)
 {
-	if (size > (__u64) OFFSET_MAX - 1)
-		return OFFSET_MAX - 1;
-	return (loff_t) size;
+	return min_t(u64, size, OFFSET_MAX);
 }
 
 static inline ino_t
--- zfcpdump-kernel-4.4.orig/include/linux/nsproxy.h
+++ zfcpdump-kernel-4.4/include/linux/nsproxy.h
@@ -8,6 +8,7 @@ struct mnt_namespace;
 struct uts_namespace;
 struct ipc_namespace;
 struct pid_namespace;
+struct cgroup_namespace;
 struct fs_struct;
 
 /*
@@ -33,6 +34,7 @@ struct nsproxy {
 	struct mnt_namespace *mnt_ns;
 	struct pid_namespace *pid_ns_for_children;
 	struct net 	     *net_ns;
+	struct cgroup_namespace *cgroup_ns;
 };
 extern struct nsproxy init_nsproxy;
 
--- zfcpdump-kernel-4.4.orig/include/linux/nvme.h
+++ zfcpdump-kernel-4.4/include/linux/nvme.h
@@ -17,20 +17,19 @@
 
 #include <linux/types.h>
 
-struct nvme_bar {
-	__u64			cap;	/* Controller Capabilities */
-	__u32			vs;	/* Version */
-	__u32			intms;	/* Interrupt Mask Set */
-	__u32			intmc;	/* Interrupt Mask Clear */
-	__u32			cc;	/* Controller Configuration */
-	__u32			rsvd1;	/* Reserved */
-	__u32			csts;	/* Controller Status */
-	__u32			nssr;	/* Subsystem Reset */
-	__u32			aqa;	/* Admin Queue Attributes */
-	__u64			asq;	/* Admin SQ Base Address */
-	__u64			acq;	/* Admin CQ Base Address */
-	__u32			cmbloc; /* Controller Memory Buffer Location */
-	__u32			cmbsz;  /* Controller Memory Buffer Size */
+enum {
+	NVME_REG_CAP	= 0x0000,	/* Controller Capabilities */
+	NVME_REG_VS	= 0x0008,	/* Version */
+	NVME_REG_INTMS	= 0x000c,	/* Interrupt Mask Set */
+	NVME_REG_INTMC	= 0x0010,	/* Interrupt Mask Set */
+	NVME_REG_CC	= 0x0014,	/* Controller Configuration */
+	NVME_REG_CSTS	= 0x001c,	/* Controller Status */
+	NVME_REG_NSSR	= 0x0020,	/* NVM Subsystem Reset */
+	NVME_REG_AQA	= 0x0024,	/* Admin Queue Attributes */
+	NVME_REG_ASQ	= 0x0028,	/* Admin SQ Base Address */
+	NVME_REG_ACQ	= 0x0030,	/* Admin SQ Base Address */
+	NVME_REG_CMBLOC = 0x0038,	/* Controller Memory Buffer Location */
+	NVME_REG_CMBSZ	= 0x003c,	/* Controller Memory Buffer Size */
 };
 
 #define NVME_CAP_MQES(cap)	((cap) & 0xffff)
--- zfcpdump-kernel-4.4.orig/include/linux/nvmem-consumer.h
+++ zfcpdump-kernel-4.4/include/linux/nvmem-consumer.h
@@ -74,7 +74,7 @@ static inline void nvmem_cell_put(struct
 {
 }
 
-static inline char *nvmem_cell_read(struct nvmem_cell *cell, size_t *len)
+static inline void *nvmem_cell_read(struct nvmem_cell *cell, size_t *len)
 {
 	return ERR_PTR(-ENOSYS);
 }
--- zfcpdump-kernel-4.4.orig/include/linux/of.h
+++ zfcpdump-kernel-4.4/include/linux/of.h
@@ -685,6 +685,15 @@ static inline int of_node_to_nid(struct
 }
 #endif
 
+#ifdef CONFIG_OF_NUMA
+extern int of_numa_init(void);
+#else
+static inline int of_numa_init(void)
+{
+	return -ENOSYS;
+}
+#endif
+
 static inline struct device_node *of_find_matching_node(
 	struct device_node *from,
 	const struct of_device_id *matches)
--- zfcpdump-kernel-4.4.orig/include/linux/page-flags-layout.h
+++ zfcpdump-kernel-4.4/include/linux/page-flags-layout.h
@@ -17,6 +17,8 @@
 #define ZONES_SHIFT 1
 #elif MAX_NR_ZONES <= 4
 #define ZONES_SHIFT 2
+#elif MAX_NR_ZONES <= 8
+#define ZONES_SHIFT 3
 #else
 #error ZONES_SHIFT -- too many zones configured adjust calculation
 #endif
--- zfcpdump-kernel-4.4.orig/include/linux/pagemap.h
+++ zfcpdump-kernel-4.4/include/linux/pagemap.h
@@ -601,56 +601,56 @@ static inline int fault_in_pages_readabl
  */
 static inline int fault_in_multipages_writeable(char __user *uaddr, int size)
 {
-	int ret = 0;
 	char __user *end = uaddr + size - 1;
 
 	if (unlikely(size == 0))
-		return ret;
+		return 0;
 
+	if (unlikely(uaddr > end))
+		return -EFAULT;
 	/*
 	 * Writing zeroes into userspace here is OK, because we know that if
 	 * the zero gets there, we'll be overwriting it.
 	 */
-	while (uaddr <= end) {
-		ret = __put_user(0, uaddr);
-		if (ret != 0)
-			return ret;
+	do {
+		if (unlikely(__put_user(0, uaddr) != 0))
+			return -EFAULT;
 		uaddr += PAGE_SIZE;
-	}
+	} while (uaddr <= end);
 
 	/* Check whether the range spilled into the next page. */
 	if (((unsigned long)uaddr & PAGE_MASK) ==
 			((unsigned long)end & PAGE_MASK))
-		ret = __put_user(0, end);
+		return __put_user(0, end);
 
-	return ret;
+	return 0;
 }
 
 static inline int fault_in_multipages_readable(const char __user *uaddr,
 					       int size)
 {
 	volatile char c;
-	int ret = 0;
 	const char __user *end = uaddr + size - 1;
 
 	if (unlikely(size == 0))
-		return ret;
+		return 0;
+
+	if (unlikely(uaddr > end))
+		return -EFAULT;
 
-	while (uaddr <= end) {
-		ret = __get_user(c, uaddr);
-		if (ret != 0)
-			return ret;
+	do {
+		if (unlikely(__get_user(c, uaddr) != 0))
+			return -EFAULT;
 		uaddr += PAGE_SIZE;
-	}
+	} while (uaddr <= end);
 
 	/* Check whether the range spilled into the next page. */
 	if (((unsigned long)uaddr & PAGE_MASK) ==
 			((unsigned long)end & PAGE_MASK)) {
-		ret = __get_user(c, end);
-		(void)c;
+		return __get_user(c, end);
 	}
 
-	return ret;
+	return 0;
 }
 
 int add_to_page_cache_locked(struct page *page, struct address_space *mapping,
--- zfcpdump-kernel-4.4.orig/include/linux/pci.h
+++ zfcpdump-kernel-4.4/include/linux/pci.h
@@ -359,6 +359,7 @@ struct pci_dev {
 	unsigned int	io_window_1k:1;	/* Intel P2P bridge 1K I/O windows */
 	unsigned int	irq_managed:1;
 	unsigned int	has_secondary_link:1;
+	unsigned int	non_compliant_bars:1;	/* broken BARs; ignore them */
 	pci_dev_flags_t dev_flags;
 	atomic_t	enable_cnt;	/* pci_enable_device has been called */
 
@@ -988,23 +989,6 @@ static inline int pci_is_managed(struct
 	return pdev->is_managed;
 }
 
-static inline void pci_set_managed_irq(struct pci_dev *pdev, unsigned int irq)
-{
-	pdev->irq = irq;
-	pdev->irq_managed = 1;
-}
-
-static inline void pci_reset_managed_irq(struct pci_dev *pdev)
-{
-	pdev->irq = 0;
-	pdev->irq_managed = 0;
-}
-
-static inline bool pci_has_managed_irq(struct pci_dev *pdev)
-{
-	return pdev->irq_managed && pdev->irq > 0;
-}
-
 void pci_disable_device(struct pci_dev *dev);
 
 extern unsigned int pcibios_max_latency;
@@ -1517,6 +1501,10 @@ static inline int pci_get_new_domain_nr(
 
 #include <asm/pci.h>
 
+#ifndef pci_root_bus_fwnode
+#define pci_root_bus_fwnode(bus)	NULL
+#endif
+
 /* these helpers provide future and backwards compatibility
  * for accessing popular PCI BAR info */
 #define pci_resource_start(dev, bar)	((dev)->resource[(bar)].start)
@@ -1946,6 +1934,16 @@ static inline struct irq_domain *
 pci_host_bridge_of_msi_domain(struct pci_bus *bus) { return NULL; }
 #endif  /* CONFIG_OF */
 
+#ifdef CONFIG_ACPI
+struct irq_domain *pci_host_bridge_acpi_msi_domain(struct pci_bus *bus);
+
+void
+pci_msi_register_fwnode_provider(struct fwnode_handle *(*fn)(struct device *));
+#else
+static inline struct irq_domain *
+pci_host_bridge_acpi_msi_domain(struct pci_bus *bus) { return NULL; }
+#endif
+
 #ifdef CONFIG_EEH
 static inline struct eeh_dev *pci_dev_to_eeh_dev(struct pci_dev *pdev)
 {
--- zfcpdump-kernel-4.4.orig/include/linux/pci_ids.h
+++ zfcpdump-kernel-4.4/include/linux/pci_ids.h
@@ -2495,6 +2495,13 @@
 #define PCI_DEVICE_ID_KORENIX_JETCARDF2	0x1700
 #define PCI_DEVICE_ID_KORENIX_JETCARDF3	0x17ff
 
+#define PCI_VENDOR_ID_NETRONOME		0x19ee
+#define PCI_DEVICE_ID_NETRONOME_NFP3200	0x3200
+#define PCI_DEVICE_ID_NETRONOME_NFP3240	0x3240
+#define PCI_DEVICE_ID_NETRONOME_NFP4000	0x4000
+#define PCI_DEVICE_ID_NETRONOME_NFP6000	0x6000
+#define PCI_DEVICE_ID_NETRONOME_NFP6000_VF	0x6003
+
 #define PCI_VENDOR_ID_QMI		0x1a32
 
 #define PCI_VENDOR_ID_AZWAVE		0x1a3b
--- zfcpdump-kernel-4.4.orig/include/linux/perf/arm_pmu.h
+++ zfcpdump-kernel-4.4/include/linux/perf/arm_pmu.h
@@ -111,8 +111,6 @@ struct arm_pmu {
 
 #define to_arm_pmu(p) (container_of(p, struct arm_pmu, pmu))
 
-int armpmu_register(struct arm_pmu *armpmu, int type);
-
 u64 armpmu_event_update(struct perf_event *event);
 
 int armpmu_event_set_period(struct perf_event *event);
--- zfcpdump-kernel-4.4.orig/include/linux/perf_event.h
+++ zfcpdump-kernel-4.4/include/linux/perf_event.h
@@ -121,6 +121,7 @@ struct hw_perf_event {
 		struct { /* intel_cqm */
 			int			cqm_state;
 			u32			cqm_rmid;
+			int			is_group_event;
 			struct list_head	cqm_events_entry;
 			struct list_head	cqm_groups_entry;
 			struct list_head	cqm_group_entry;
--- zfcpdump-kernel-4.4.orig/include/linux/pipe_fs_i.h
+++ zfcpdump-kernel-4.4/include/linux/pipe_fs_i.h
@@ -42,6 +42,7 @@ struct pipe_buffer {
  *	@fasync_readers: reader side fasync
  *	@fasync_writers: writer side fasync
  *	@bufs: the circular array of pipe buffers
+ *	@user: the user who created this pipe
  **/
 struct pipe_inode_info {
 	struct mutex mutex;
@@ -57,6 +58,7 @@ struct pipe_inode_info {
 	struct fasync_struct *fasync_readers;
 	struct fasync_struct *fasync_writers;
 	struct pipe_buffer *bufs;
+	struct user_struct *user;
 };
 
 /*
@@ -123,6 +125,8 @@ void pipe_unlock(struct pipe_inode_info
 void pipe_double_lock(struct pipe_inode_info *, struct pipe_inode_info *);
 
 extern unsigned int pipe_max_size, pipe_min_size;
+extern unsigned long pipe_user_pages_hard;
+extern unsigned long pipe_user_pages_soft;
 int pipe_proc_fn(struct ctl_table *, int, void __user *, size_t *, loff_t *);
 
 
--- zfcpdump-kernel-4.4.orig/include/linux/platform_data/asoc-s3c.h
+++ zfcpdump-kernel-4.4/include/linux/platform_data/asoc-s3c.h
@@ -39,6 +39,10 @@ struct samsung_i2s {
  */
 struct s3c_audio_pdata {
 	int (*cfg_gpio)(struct platform_device *);
+	void *dma_playback;
+	void *dma_capture;
+	void *dma_play_sec;
+	void *dma_capture_mic;
 	union {
 		struct samsung_i2s i2s;
 	} type;
--- /dev/null
+++ zfcpdump-kernel-4.4/include/linux/platform_data/pwm_omap_dmtimer.h
@@ -0,0 +1,69 @@
+/*
+ * include/linux/platform_data/pwm_omap_dmtimer.h
+ *
+ * OMAP Dual-Mode Timer PWM platform data
+ *
+ * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/
+ * Tarun Kanti DebBarma <tarun.kanti@ti.com>
+ * Thara Gopinath <thara@ti.com>
+ *
+ * Platform device conversion and hwmod support.
+ *
+ * Copyright (C) 2005 Nokia Corporation
+ * Author: Lauri Leukkunen <lauri.leukkunen@nokia.com>
+ * PWM and clock framework support by Timo Teras.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the  GNU General Public License along
+ * with this program; if not, write  to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef __PWM_OMAP_DMTIMER_PDATA_H
+#define __PWM_OMAP_DMTIMER_PDATA_H
+
+/* trigger types */
+#define PWM_OMAP_DMTIMER_TRIGGER_NONE			0x00
+#define PWM_OMAP_DMTIMER_TRIGGER_OVERFLOW		0x01
+#define PWM_OMAP_DMTIMER_TRIGGER_OVERFLOW_AND_COMPARE	0x02
+
+struct omap_dm_timer;
+typedef struct omap_dm_timer pwm_omap_dmtimer;
+
+struct pwm_omap_dmtimer_pdata {
+	pwm_omap_dmtimer *(*request_by_node)(struct device_node *np);
+	int	(*free)(pwm_omap_dmtimer *timer);
+
+	void	(*enable)(pwm_omap_dmtimer *timer);
+	void	(*disable)(pwm_omap_dmtimer *timer);
+
+	struct clk *(*get_fclk)(pwm_omap_dmtimer *timer);
+
+	int	(*start)(pwm_omap_dmtimer *timer);
+	int	(*stop)(pwm_omap_dmtimer *timer);
+
+	int	(*set_load)(pwm_omap_dmtimer *timer, int autoreload,
+			unsigned int value);
+	int	(*set_match)(pwm_omap_dmtimer *timer, int enable,
+			unsigned int match);
+	int	(*set_pwm)(pwm_omap_dmtimer *timer, int def_on,
+			int toggle, int trigger);
+	int	(*set_prescaler)(pwm_omap_dmtimer *timer, int prescaler);
+
+	int	(*write_counter)(pwm_omap_dmtimer *timer, unsigned int value);
+};
+
+#endif /* __PWM_OMAP_DMTIMER_PDATA_H */
--- zfcpdump-kernel-4.4.orig/include/linux/platform_device.h
+++ zfcpdump-kernel-4.4/include/linux/platform_device.h
@@ -18,6 +18,7 @@
 #define PLATFORM_DEVID_AUTO	(-2)
 
 struct mfd_cell;
+struct property_set;
 
 struct platform_device {
 	const char	*name;
@@ -70,6 +71,8 @@ struct platform_device_info {
 		const void *data;
 		size_t size_data;
 		u64 dma_mask;
+
+		const struct property_set *pset;
 };
 extern struct platform_device *platform_device_register_full(
 		const struct platform_device_info *pdevinfo);
@@ -167,6 +170,8 @@ extern int platform_device_add_resources
 					 unsigned int num);
 extern int platform_device_add_data(struct platform_device *pdev,
 				    const void *data, size_t size);
+extern int platform_device_add_properties(struct platform_device *pdev,
+					  const struct property_set *pset);
 extern int platform_device_add(struct platform_device *pdev);
 extern void platform_device_del(struct platform_device *pdev);
 extern void platform_device_put(struct platform_device *pdev);
--- zfcpdump-kernel-4.4.orig/include/linux/pm_runtime.h
+++ zfcpdump-kernel-4.4/include/linux/pm_runtime.h
@@ -39,6 +39,7 @@ extern int pm_runtime_force_resume(struc
 extern int __pm_runtime_idle(struct device *dev, int rpmflags);
 extern int __pm_runtime_suspend(struct device *dev, int rpmflags);
 extern int __pm_runtime_resume(struct device *dev, int rpmflags);
+extern int pm_runtime_get_if_in_use(struct device *dev);
 extern int pm_schedule_suspend(struct device *dev, unsigned int delay);
 extern int __pm_runtime_set_status(struct device *dev, unsigned int status);
 extern int pm_runtime_barrier(struct device *dev);
@@ -143,6 +144,10 @@ static inline int pm_schedule_suspend(st
 {
 	return -ENOSYS;
 }
+static inline int pm_runtime_get_if_in_use(struct device *dev)
+{
+	return -EINVAL;
+}
 static inline int __pm_runtime_set_status(struct device *dev,
 					    unsigned int status) { return 0; }
 static inline int pm_runtime_barrier(struct device *dev) { return 0; }
--- zfcpdump-kernel-4.4.orig/include/linux/posix_acl_xattr.h
+++ zfcpdump-kernel-4.4/include/linux/posix_acl_xattr.h
@@ -53,14 +53,23 @@ posix_acl_xattr_count(size_t size)
 }
 
 #ifdef CONFIG_FS_POSIX_ACL
-void posix_acl_fix_xattr_from_user(void *value, size_t size);
-void posix_acl_fix_xattr_to_user(void *value, size_t size);
+int posix_acl_fix_xattr_from_user(struct user_namespace *target_ns,
+				  void *value, size_t size);
+int posix_acl_fix_xattr_to_user(struct user_namespace *source_ns, void *value,
+				size_t size);
 #else
-static inline void posix_acl_fix_xattr_from_user(void *value, size_t size)
+static inline int
+posix_acl_fix_xattr_from_user(struct user_namespace *target_ns, void *value,
+			      size_t size)
 {
+	return 0;
 }
-static inline void posix_acl_fix_xattr_to_user(void *value, size_t size)
+
+static inline int
+posix_acl_fix_xattr_to_user(struct user_namespace *source_ns, void *value,
+			    size_t size)
 {
+	return 0;
 }
 #endif
 
--- zfcpdump-kernel-4.4.orig/include/linux/pps_kernel.h
+++ zfcpdump-kernel-4.4/include/linux/pps_kernel.h
@@ -111,22 +111,17 @@ static inline void timespec_to_pps_ktime
 	kt->nsec = ts.tv_nsec;
 }
 
-#ifdef CONFIG_NTP_PPS
-
 static inline void pps_get_ts(struct pps_event_time *ts)
 {
-	ktime_get_raw_and_real_ts64(&ts->ts_raw, &ts->ts_real);
-}
-
-#else /* CONFIG_NTP_PPS */
+	struct system_time_snapshot snap;
 
-static inline void pps_get_ts(struct pps_event_time *ts)
-{
-	ktime_get_real_ts64(&ts->ts_real);
+	ktime_get_snapshot(&snap);
+	ts->ts_real = ktime_to_timespec64(snap.real);
+#ifdef CONFIG_NTP_PPS
+	ts->ts_raw = ktime_to_timespec64(snap.raw);
+#endif
 }
 
-#endif /* CONFIG_NTP_PPS */
-
 /* Subtract known time delay from PPS event time(s) */
 static inline void pps_sub_ts(struct pps_event_time *ts, struct timespec64 delta)
 {
--- zfcpdump-kernel-4.4.orig/include/linux/proc_fs.h
+++ zfcpdump-kernel-4.4/include/linux/proc_fs.h
@@ -21,6 +21,7 @@ extern struct proc_dir_entry *proc_mkdir
 					      struct proc_dir_entry *, void *);
 extern struct proc_dir_entry *proc_mkdir_mode(const char *, umode_t,
 					      struct proc_dir_entry *);
+struct proc_dir_entry *proc_create_mount_point(const char *name);
  
 extern struct proc_dir_entry *proc_create_data(const char *, umode_t,
 					       struct proc_dir_entry *,
@@ -56,6 +57,7 @@ static inline struct proc_dir_entry *pro
 		struct proc_dir_entry *parent,const char *dest) { return NULL;}
 static inline struct proc_dir_entry *proc_mkdir(const char *name,
 	struct proc_dir_entry *parent) {return NULL;}
+static inline struct proc_dir_entry *proc_create_mount_point(const char *name) { return NULL; }
 static inline struct proc_dir_entry *proc_mkdir_data(const char *name,
 	umode_t mode, struct proc_dir_entry *parent, void *data) { return NULL; }
 static inline struct proc_dir_entry *proc_mkdir_mode(const char *name,
--- zfcpdump-kernel-4.4.orig/include/linux/proc_ns.h
+++ zfcpdump-kernel-4.4/include/linux/proc_ns.h
@@ -9,6 +9,8 @@
 struct pid_namespace;
 struct nsproxy;
 struct path;
+struct task_struct;
+struct inode;
 
 struct proc_ns_operations {
 	const char *name;
@@ -24,6 +26,7 @@ extern const struct proc_ns_operations i
 extern const struct proc_ns_operations pidns_operations;
 extern const struct proc_ns_operations userns_operations;
 extern const struct proc_ns_operations mntns_operations;
+extern const struct proc_ns_operations cgroupns_operations;
 
 /*
  * We always define these enumerators
@@ -34,6 +37,7 @@ enum {
 	PROC_UTS_INIT_INO	= 0xEFFFFFFEU,
 	PROC_USER_INIT_INO	= 0xEFFFFFFDU,
 	PROC_PID_INIT_INO	= 0xEFFFFFFCU,
+	PROC_CGROUP_INIT_INO	= 0xEFFFFFFBU,
 };
 
 #ifdef CONFIG_PROC_FS
--- zfcpdump-kernel-4.4.orig/include/linux/property.h
+++ zfcpdump-kernel-4.4/include/linux/property.h
@@ -73,8 +73,8 @@ int fwnode_property_match_string(struct
 struct fwnode_handle *device_get_next_child_node(struct device *dev,
 						 struct fwnode_handle *child);
 
-#define device_for_each_child_node(dev, child) \
-	for (child = device_get_next_child_node(dev, NULL); child; \
+#define device_for_each_child_node(dev, child)				\
+	for (child = device_get_next_child_node(dev, NULL); child;	\
 	     child = device_get_next_child_node(dev, child))
 
 void fwnode_handle_put(struct fwnode_handle *fwnode);
@@ -144,24 +144,92 @@ static inline int fwnode_property_read_u
 /**
  * struct property_entry - "Built-in" device property representation.
  * @name: Name of the property.
- * @type: Type of the property.
- * @nval: Number of items of type @type making up the value.
- * @value: Value of the property (an array of @nval items of type @type).
+ * @length: Length of data making up the value.
+ * @is_array: True when the property is an array.
+ * @is_string: True when property is a string.
+ * @pointer: Pointer to the property (an array of items of the given type).
+ * @value: Value of the property (when it is a single item of the given type).
  */
 struct property_entry {
 	const char *name;
-	enum dev_prop_type type;
-	size_t nval;
+	size_t length;
+	bool is_array;
+	bool is_string;
 	union {
-		void *raw_data;
-		u8 *u8_data;
-		u16 *u16_data;
-		u32 *u32_data;
-		u64 *u64_data;
-		const char **str;
-	} value;
+		union {
+			void *raw_data;
+			u8 *u8_data;
+			u16 *u16_data;
+			u32 *u32_data;
+			u64 *u64_data;
+			const char **str;
+		} pointer;
+		union {
+			unsigned long long raw_data;
+			u8 u8_data;
+			u16 u16_data;
+			u32 u32_data;
+			u64 u64_data;
+			const char *str;
+		} value;
+	};
 };
 
+#define PROPERTY_ENTRY_INTEGER_ARRAY(_name_, _type_, _val_)	\
+{								\
+	.name = _name_,						\
+	.length = ARRAY_SIZE(_val_) * sizeof(_type_),		\
+	.is_array = true,					\
+	.pointer._type_##_data = _val_,				\
+}
+
+#define PROPERTY_ENTRY_U8_ARRAY(_name_, _val_)			\
+	PROPERTY_ENTRY_INTEGER_ARRAY(_name_, u8, _val_)
+#define PROPERTY_ENTRY_U16_ARRAY(_name_, _val_)			\
+	PROPERTY_ENTRY_INTEGER_ARRAY(_name_, u16, _val_)
+#define PROPERTY_ENTRY_U32_ARRAY(_name_, _val_)			\
+	PROPERTY_ENTRY_INTEGER_ARRAY(_name_, u32, _val_)
+#define PROPERTY_ENTRY_U64_ARRAY(_name_, _val_)			\
+	PROPERTY_ENTRY_INTEGER_ARRAY(_name_, u64, _val_)
+
+#define PROPERTY_ENTRY_STRING_ARRAY(_name_, _val_)		\
+{								\
+	.name = _name_,						\
+	.length = ARRAY_SIZE(_val_) * sizeof(const char *),	\
+	.is_array = true,					\
+	.is_string = true,					\
+	.pointer.str = _val_,					\
+}
+
+#define PROPERTY_ENTRY_INTEGER(_name_, _type_, _val_)	\
+{							\
+	.name = _name_,					\
+	.length = sizeof(_type_),			\
+	.value._type_##_data = _val_,			\
+}
+
+#define PROPERTY_ENTRY_U8(_name_, _val_)		\
+	PROPERTY_ENTRY_INTEGER(_name_, u8, _val_)
+#define PROPERTY_ENTRY_U16(_name_, _val_)		\
+	PROPERTY_ENTRY_INTEGER(_name_, u16, _val_)
+#define PROPERTY_ENTRY_U32(_name_, _val_)		\
+	PROPERTY_ENTRY_INTEGER(_name_, u32, _val_)
+#define PROPERTY_ENTRY_U64(_name_, _val_)		\
+	PROPERTY_ENTRY_INTEGER(_name_, u64, _val_)
+
+#define PROPERTY_ENTRY_STRING(_name_, _val_)		\
+{							\
+	.name = _name_,					\
+	.length = sizeof(_val_),			\
+	.is_string = true,				\
+	.value.str = _val_,				\
+}
+
+#define PROPERTY_ENTRY_BOOL(_name_)		\
+{						\
+	.name = _name_,				\
+}
+
 /**
  * struct property_set - Collection of "built-in" device properties.
  * @fwnode: Handle to be pointed to by the fwnode field of struct device.
@@ -172,7 +240,8 @@ struct property_set {
 	struct property_entry *properties;
 };
 
-void device_add_property_set(struct device *dev, struct property_set *pset);
+int device_add_property_set(struct device *dev, const struct property_set *pset);
+void device_remove_property_set(struct device *dev);
 
 bool device_dma_supported(struct device *dev);
 
--- zfcpdump-kernel-4.4.orig/include/linux/ptp_clock_kernel.h
+++ zfcpdump-kernel-4.4/include/linux/ptp_clock_kernel.h
@@ -38,6 +38,7 @@ struct ptp_clock_request {
 	};
 };
 
+struct system_device_crosststamp;
 /**
  * struct ptp_clock_info - decribes a PTP hardware clock
  *
@@ -67,6 +68,11 @@ struct ptp_clock_request {
  * @gettime64:  Reads the current time from the hardware clock.
  *              parameter ts: Holds the result.
  *
+ * @getcrosststamp:  Reads the current time from the hardware clock and
+ *                   system clock simultaneously.
+ *                   parameter cts: Contains timestamp (device,system) pair,
+ *                   where system time is realtime and monotonic.
+ *
  * @settime64:  Set the current time on the hardware clock.
  *              parameter ts: Time value to set.
  *
@@ -105,6 +111,8 @@ struct ptp_clock_info {
 	int (*adjfreq)(struct ptp_clock_info *ptp, s32 delta);
 	int (*adjtime)(struct ptp_clock_info *ptp, s64 delta);
 	int (*gettime64)(struct ptp_clock_info *ptp, struct timespec64 *ts);
+	int (*getcrosststamp)(struct ptp_clock_info *ptp,
+			      struct system_device_crosststamp *cts);
 	int (*settime64)(struct ptp_clock_info *p, const struct timespec64 *ts);
 	int (*enable)(struct ptp_clock_info *ptp,
 		      struct ptp_clock_request *request, int on);
--- zfcpdump-kernel-4.4.orig/include/linux/ptrace.h
+++ zfcpdump-kernel-4.4/include/linux/ptrace.h
@@ -57,7 +57,29 @@ extern void exit_ptrace(struct task_stru
 #define PTRACE_MODE_READ	0x01
 #define PTRACE_MODE_ATTACH	0x02
 #define PTRACE_MODE_NOAUDIT	0x04
-/* Returns true on success, false on denial. */
+#define PTRACE_MODE_FSCREDS 0x08
+#define PTRACE_MODE_REALCREDS 0x10
+
+/* shorthands for READ/ATTACH and FSCREDS/REALCREDS combinations */
+#define PTRACE_MODE_READ_FSCREDS (PTRACE_MODE_READ | PTRACE_MODE_FSCREDS)
+#define PTRACE_MODE_READ_REALCREDS (PTRACE_MODE_READ | PTRACE_MODE_REALCREDS)
+#define PTRACE_MODE_ATTACH_FSCREDS (PTRACE_MODE_ATTACH | PTRACE_MODE_FSCREDS)
+#define PTRACE_MODE_ATTACH_REALCREDS (PTRACE_MODE_ATTACH | PTRACE_MODE_REALCREDS)
+
+/**
+ * ptrace_may_access - check whether the caller is permitted to access
+ * a target task.
+ * @task: target task
+ * @mode: selects type of access and caller credentials
+ *
+ * Returns true on success, false on denial.
+ *
+ * One of the flags PTRACE_MODE_FSCREDS and PTRACE_MODE_REALCREDS must
+ * be set in @mode to specify whether the access was requested through
+ * a filesystem syscall (should use effective capabilities and fsuid
+ * of the caller) or through an explicit syscall such as
+ * process_vm_writev or ptrace (and should use the real credentials).
+ */
 extern bool ptrace_may_access(struct task_struct *task, unsigned int mode);
 
 static inline int ptrace_reparented(struct task_struct *child)
--- zfcpdump-kernel-4.4.orig/include/linux/radix-tree.h
+++ zfcpdump-kernel-4.4/include/linux/radix-tree.h
@@ -370,12 +370,28 @@ void **radix_tree_next_chunk(struct radi
 			     struct radix_tree_iter *iter, unsigned flags);
 
 /**
+ * radix_tree_iter_retry - retry this chunk of the iteration
+ * @iter:	iterator state
+ *
+ * If we iterate over a tree protected only by the RCU lock, a race
+ * against deletion or creation may result in seeing a slot for which
+ * radix_tree_deref_retry() returns true.  If so, call this function
+ * and continue the iteration.
+ */
+static inline __must_check
+void **radix_tree_iter_retry(struct radix_tree_iter *iter)
+{
+	iter->next_index = iter->index;
+	return NULL;
+}
+
+/**
  * radix_tree_chunk_size - get current chunk size
  *
  * @iter:	pointer to radix tree iterator
  * Returns:	current chunk size
  */
-static __always_inline unsigned
+static __always_inline long
 radix_tree_chunk_size(struct radix_tree_iter *iter)
 {
 	return iter->next_index - iter->index;
@@ -409,9 +425,9 @@ radix_tree_next_slot(void **slot, struct
 			return slot + offset + 1;
 		}
 	} else {
-		unsigned size = radix_tree_chunk_size(iter) - 1;
+		long size = radix_tree_chunk_size(iter);
 
-		while (size--) {
+		while (--size > 0) {
 			slot++;
 			iter->index++;
 			if (likely(*slot))
--- zfcpdump-kernel-4.4.orig/include/linux/rmap.h
+++ zfcpdump-kernel-4.4/include/linux/rmap.h
@@ -108,20 +108,6 @@ static inline void put_anon_vma(struct a
 		__put_anon_vma(anon_vma);
 }
 
-static inline void vma_lock_anon_vma(struct vm_area_struct *vma)
-{
-	struct anon_vma *anon_vma = vma->anon_vma;
-	if (anon_vma)
-		down_write(&anon_vma->root->rwsem);
-}
-
-static inline void vma_unlock_anon_vma(struct vm_area_struct *vma)
-{
-	struct anon_vma *anon_vma = vma->anon_vma;
-	if (anon_vma)
-		up_write(&anon_vma->root->rwsem);
-}
-
 static inline void anon_vma_lock_write(struct anon_vma *anon_vma)
 {
 	down_write(&anon_vma->root->rwsem);
--- zfcpdump-kernel-4.4.orig/include/linux/sched.h
+++ zfcpdump-kernel-4.4/include/linux/sched.h
@@ -830,6 +830,8 @@ struct user_struct {
 	unsigned long mq_bytes;	/* How many bytes can be allocated to mqueue? */
 #endif
 	unsigned long locked_shm; /* How many pages of mlocked shm ? */
+	unsigned long unix_inflight;	/* How many files in flight in unix sockets */
+	atomic_long_t pipe_bufs;  /* how many pages are allocated in pipe buffers */
 
 #ifdef CONFIG_KEYS
 	struct key *uid_keyring;	/* UID specific keyring */
--- zfcpdump-kernel-4.4.orig/include/linux/security.h
+++ zfcpdump-kernel-4.4/include/linux/security.h
@@ -28,6 +28,7 @@
 #include <linux/err.h>
 #include <linux/string.h>
 #include <linux/mm.h>
+#include <linux/fs.h>
 
 struct linux_binprm;
 struct cred;
@@ -1585,7 +1586,15 @@ static inline void security_audit_rule_f
 #endif /* CONFIG_AUDIT */
 
 #ifdef CONFIG_SECURITYFS
-
+extern int securityfs_pin_fs(void);
+extern int __securityfs_setup_d_inode(struct inode *dir, struct dentry *dentry,
+				      umode_t mode, void *data,
+				      const struct file_operations *fops,
+				      const struct inode_operations *iops);
+extern struct dentry *securityfs_create_dentry(const char *name, umode_t mode,
+				        struct dentry *parent, void *data,
+					const struct file_operations *fops,
+					const struct inode_operations *iops);
 extern struct dentry *securityfs_create_file(const char *name, umode_t mode,
 					     struct dentry *parent, void *data,
 					     const struct file_operations *fops);
@@ -1593,6 +1602,28 @@ extern struct dentry *securityfs_create_
 extern void securityfs_remove(struct dentry *dentry);
 
 #else /* CONFIG_SECURITYFS */
+static inline int securityfs_pin_fs(void)
+{
+	return -ENODEV;
+}
+
+static inline int __securityfs_setup_d_inode(struct inode *dir,
+					struct dentry *dentry,
+					umode_t mode, void *data,
+					const struct file_operations *fops,
+					const struct inode_operations *iops)
+{
+	return -ENODEV;
+}
+
+static inline struct dentry *securityfs_create_dentry(const char *name,
+					umode_t mode,
+					struct dentry *parent, void *data,
+					const struct file_operations *fops,
+					const struct inode_operations *iops)
+{
+	return ERR_PTR(-ENODEV);
+}
 
 static inline struct dentry *securityfs_create_dir(const char *name,
 						   struct dentry *parent)
--- zfcpdump-kernel-4.4.orig/include/linux/serio.h
+++ zfcpdump-kernel-4.4/include/linux/serio.h
@@ -31,7 +31,8 @@ struct serio {
 
 	struct serio_device_id id;
 
-	spinlock_t lock;		/* protects critical sections from port's interrupt handler */
+	/* Protects critical sections from port's interrupt handler */
+	spinlock_t lock;
 
 	int (*write)(struct serio *, unsigned char);
 	int (*open)(struct serio *);
@@ -40,16 +41,29 @@ struct serio {
 	void (*stop)(struct serio *);
 
 	struct serio *parent;
-	struct list_head child_node;	/* Entry in parent->children list */
+	/* Entry in parent->children list */
+	struct list_head child_node;
 	struct list_head children;
-	unsigned int depth;		/* level of nesting in serio hierarchy */
+	/* Level of nesting in serio hierarchy */
+	unsigned int depth;
 
-	struct serio_driver *drv;	/* accessed from interrupt, must be protected by serio->lock and serio->sem */
-	struct mutex drv_mutex;		/* protects serio->drv so attributes can pin driver */
+	/*
+	 * serio->drv is accessed from interrupt handlers; when modifying
+	 * caller should acquire serio->drv_mutex and serio->lock.
+	 */
+	struct serio_driver *drv;
+	/* Protects serio->drv so attributes can pin current driver */
+	struct mutex drv_mutex;
 
 	struct device dev;
 
 	struct list_head node;
+
+	/*
+	 * For use by PS/2 layer when several ports share hardware and
+	 * may get indigestion when exposed to concurrent access (i8042).
+	 */
+	struct mutex *ps2_cmd_mutex;
 };
 #define to_serio_port(d)	container_of(d, struct serio, dev)
 
--- zfcpdump-kernel-4.4.orig/include/linux/shmem_fs.h
+++ zfcpdump-kernel-4.4/include/linux/shmem_fs.h
@@ -15,10 +15,7 @@ struct shmem_inode_info {
 	unsigned int		seals;		/* shmem seals */
 	unsigned long		flags;
 	unsigned long		alloced;	/* data pages alloced to file */
-	union {
-		unsigned long	swapped;	/* subtotal assigned to swap */
-		char		*symlink;	/* unswappable short symlink */
-	};
+	unsigned long		swapped;	/* subtotal assigned to swap */
 	struct shared_policy	policy;		/* NUMA memory alloc policy */
 	struct list_head	swaplist;	/* chain of maybes on swap */
 	struct simple_xattrs	xattrs;		/* list of xattrs */
@@ -26,10 +23,13 @@ struct shmem_inode_info {
 };
 
 struct shmem_sb_info {
+	struct mutex idr_lock;
+	bool idr_nouse;
+	struct idr idr;		    /* manages inode-number */
 	unsigned long max_blocks;   /* How many blocks are allowed */
 	struct percpu_counter used_blocks;  /* How many are allocated */
-	unsigned long max_inodes;   /* How many inodes are allowed */
-	unsigned long free_inodes;  /* How many are left for allocation */
+	int max_inodes;		    /* How many inodes are allowed */
+	int free_inodes;	    /* How many are left for allocation */
 	spinlock_t stat_lock;	    /* Serialize shmem_sb_info changes */
 	kuid_t uid;		    /* Mount uid for root directory */
 	kgid_t gid;		    /* Mount gid for root directory */
--- zfcpdump-kernel-4.4.orig/include/linux/signal.h
+++ zfcpdump-kernel-4.4/include/linux/signal.h
@@ -28,6 +28,21 @@ struct sigpending {
 	sigset_t signal;
 };
 
+#ifndef HAVE_ARCH_COPY_SIGINFO
+
+#include <linux/string.h>
+
+static inline void copy_siginfo(struct siginfo *to, struct siginfo *from)
+{
+	if (from->si_code < 0)
+		memcpy(to, from, sizeof(*to));
+	else
+		/* _sigchld is currently the largest know union member */
+		memcpy(to, from, __ARCH_SI_PREAMBLE_SIZE + sizeof(from->_sifields._sigchld));
+}
+
+#endif
+
 /*
  * Define some primitives to manipulate sigset_t.
  */
--- zfcpdump-kernel-4.4.orig/include/linux/skbuff.h
+++ zfcpdump-kernel-4.4/include/linux/skbuff.h
@@ -219,6 +219,7 @@ struct sk_buff;
 #else
 #define MAX_SKB_FRAGS (65536/PAGE_SIZE + 1)
 #endif
+extern int sysctl_max_skb_frags;
 
 typedef struct skb_frag_struct skb_frag_t;
 
@@ -981,6 +982,7 @@ __skb_set_sw_hash(struct sk_buff *skb, _
 }
 
 void __skb_get_hash(struct sk_buff *skb);
+u32 __skb_get_hash_symmetric(struct sk_buff *skb);
 u32 skb_get_poff(const struct sk_buff *skb);
 u32 __skb_get_poff(const struct sk_buff *skb, void *data,
 		   const struct flow_keys *keys, int hlen);
@@ -1907,6 +1909,30 @@ static inline void skb_reserve(struct sk
 	skb->tail += len;
 }
 
+/**
+ *	skb_tailroom_reserve - adjust reserved_tailroom
+ *	@skb: buffer to alter
+ *	@mtu: maximum amount of headlen permitted
+ *	@needed_tailroom: minimum amount of reserved_tailroom
+ *
+ *	Set reserved_tailroom so that headlen can be as large as possible but
+ *	not larger than mtu and tailroom cannot be smaller than
+ *	needed_tailroom.
+ *	The required headroom should already have been reserved before using
+ *	this function.
+ */
+static inline void skb_tailroom_reserve(struct sk_buff *skb, unsigned int mtu,
+					unsigned int needed_tailroom)
+{
+	SKB_LINEAR_ASSERT(skb);
+	if (mtu < skb_tailroom(skb) - needed_tailroom)
+		/* use at most mtu */
+		skb->reserved_tailroom = skb_tailroom(skb) - mtu;
+	else
+		/* use up to all available space */
+		skb->reserved_tailroom = needed_tailroom;
+}
+
 #define ENCAP_TYPE_ETHER	0
 #define ENCAP_TYPE_IPPROTO	1
 
@@ -2317,6 +2343,9 @@ static inline struct sk_buff *napi_alloc
 {
 	return __napi_alloc_skb(napi, length, GFP_ATOMIC);
 }
+void napi_consume_skb(struct sk_buff *skb, int budget);
+
+void __kfree_skb_flush(void);
 
 /**
  * __dev_alloc_pages - allocate page for network Rx
@@ -2539,6 +2568,13 @@ static inline int skb_clone_writable(con
 	       skb_headroom(skb) + len <= skb->hdr_len;
 }
 
+static inline int skb_try_make_writable(struct sk_buff *skb,
+					unsigned int write_len)
+{
+	return skb_cloned(skb) && !skb_clone_writable(skb, write_len) &&
+	       pskb_expand_head(skb, 0, 0, GFP_ATOMIC);
+}
+
 static inline int __skb_cow(struct sk_buff *skb, unsigned int headroom,
 			    int cloned)
 {
@@ -2723,6 +2759,42 @@ static inline void skb_postpull_rcsum(st
 
 unsigned char *skb_pull_rcsum(struct sk_buff *skb, unsigned int len);
 
+static inline void skb_postpush_rcsum(struct sk_buff *skb,
+				      const void *start, unsigned int len)
+{
+	/* For performing the reverse operation to skb_postpull_rcsum(),
+	 * we can instead of ...
+	 *
+	 *   skb->csum = csum_add(skb->csum, csum_partial(start, len, 0));
+	 *
+	 * ... just use this equivalent version here to save a few
+	 * instructions. Feeding csum of 0 in csum_partial() and later
+	 * on adding skb->csum is equivalent to feed skb->csum in the
+	 * first place.
+	 */
+	if (skb->ip_summed == CHECKSUM_COMPLETE)
+		skb->csum = csum_partial(start, len, skb->csum);
+}
+
+/**
+ *	skb_push_rcsum - push skb and update receive checksum
+ *	@skb: buffer to update
+ *	@len: length of data pulled
+ *
+ *	This function performs an skb_push on the packet and updates
+ *	the CHECKSUM_COMPLETE checksum.  It should be used on
+ *	receive path processing instead of skb_push unless you know
+ *	that the checksum difference is zero (e.g., a valid IP header)
+ *	or you are setting ip_summed to CHECKSUM_NONE.
+ */
+static inline unsigned char *skb_push_rcsum(struct sk_buff *skb,
+					    unsigned int len)
+{
+	skb_push(skb, len);
+	skb_postpush_rcsum(skb, skb->data, len);
+	return skb->data;
+}
+
 /**
  *	pskb_trim_rcsum - trim received skb and update checksum
  *	@skb: buffer to trim
@@ -3446,7 +3518,8 @@ struct skb_gso_cb {
 	int	encap_level;
 	__u16	csum_start;
 };
-#define SKB_GSO_CB(skb) ((struct skb_gso_cb *)(skb)->cb)
+#define SKB_SGO_CB_OFFSET	32
+#define SKB_GSO_CB(skb) ((struct skb_gso_cb *)((skb)->cb + SKB_SGO_CB_OFFSET))
 
 static inline int skb_tnl_header_len(const struct sk_buff *inner_skb)
 {
--- zfcpdump-kernel-4.4.orig/include/linux/smc91x.h
+++ zfcpdump-kernel-4.4/include/linux/smc91x.h
@@ -1,6 +1,16 @@
 #ifndef __SMC91X_H__
 #define __SMC91X_H__
 
+/*
+ * These bits define which access sizes a platform can support, rather
+ * than the maximal access size.  So, if your platform can do 16-bit
+ * and 32-bit accesses to the SMC91x device, but not 8-bit, set both
+ * SMC91X_USE_16BIT and SMC91X_USE_32BIT.
+ *
+ * The SMC91x driver requires at least one of SMC91X_USE_8BIT or
+ * SMC91X_USE_16BIT to be supported - just setting SMC91X_USE_32BIT is
+ * an invalid configuration.
+ */
 #define SMC91X_USE_8BIT (1 << 0)
 #define SMC91X_USE_16BIT (1 << 1)
 #define SMC91X_USE_32BIT (1 << 2)
--- zfcpdump-kernel-4.4.orig/include/linux/sock_diag.h
+++ zfcpdump-kernel-4.4/include/linux/sock_diag.h
@@ -35,6 +35,9 @@ enum sknetlink_groups sock_diag_destroy_
 {
 	switch (sk->sk_family) {
 	case AF_INET:
+		if (sk->sk_type == SOCK_RAW)
+			return SKNLGRP_NONE;
+
 		switch (sk->sk_protocol) {
 		case IPPROTO_TCP:
 			return SKNLGRP_INET_TCP_DESTROY;
@@ -44,6 +47,9 @@ enum sknetlink_groups sock_diag_destroy_
 			return SKNLGRP_NONE;
 		}
 	case AF_INET6:
+		if (sk->sk_type == SOCK_RAW)
+			return SKNLGRP_NONE;
+
 		switch (sk->sk_protocol) {
 		case IPPROTO_TCP:
 			return SKNLGRP_INET6_TCP_DESTROY;
--- zfcpdump-kernel-4.4.orig/include/linux/splice.h
+++ zfcpdump-kernel-4.4/include/linux/splice.h
@@ -83,4 +83,10 @@ extern void splice_shrink_spd(struct spl
 extern void spd_release_page(struct splice_pipe_desc *, unsigned int);
 
 extern const struct pipe_buf_operations page_cache_pipe_buf_ops;
+
+extern long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
+			   loff_t *ppos, size_t len, unsigned int flags);
+extern long do_splice_to(struct file *in, loff_t *ppos,
+			 struct pipe_inode_info *pipe, size_t len,
+			 unsigned int flags);
 #endif
--- zfcpdump-kernel-4.4.orig/include/linux/sunrpc/clnt.h
+++ zfcpdump-kernel-4.4/include/linux/sunrpc/clnt.h
@@ -135,8 +135,6 @@ struct rpc_create_args {
 #define RPC_CLNT_CREATE_NO_RETRANS_TIMEOUT	(1UL << 9)
 
 struct rpc_clnt *rpc_create(struct rpc_create_args *args);
-struct rpc_clnt *rpc_create_xprt(struct rpc_create_args *args,
-					struct rpc_xprt *xprt);
 struct rpc_clnt	*rpc_bind_new_program(struct rpc_clnt *,
 				const struct rpc_program *, u32);
 void rpc_task_reset_client(struct rpc_task *task, struct rpc_clnt *clnt);
--- zfcpdump-kernel-4.4.orig/include/linux/sysctl.h
+++ zfcpdump-kernel-4.4/include/linux/sysctl.h
@@ -41,6 +41,8 @@ extern int proc_dostring(struct ctl_tabl
 			 void __user *, size_t *, loff_t *);
 extern int proc_dointvec(struct ctl_table *, int,
 			 void __user *, size_t *, loff_t *);
+extern int proc_douintvec(struct ctl_table *, int,
+			 void __user *, size_t *, loff_t *);
 extern int proc_dointvec_minmax(struct ctl_table *, int,
 				void __user *, size_t *, loff_t *);
 extern int proc_dointvec_jiffies(struct ctl_table *, int,
--- zfcpdump-kernel-4.4.orig/include/linux/thermal.h
+++ zfcpdump-kernel-4.4/include/linux/thermal.h
@@ -43,6 +43,9 @@
 /* Default weight of a bound cooling device */
 #define THERMAL_WEIGHT_DEFAULT 0
 
+/* use value, which < 0K, to indicate an invalid/uninitialized temperature */
+#define THERMAL_TEMP_INVALID	-274000
+
 /* Unit conversion macros */
 #define DECI_KELVIN_TO_CELSIUS(t)	({			\
 	long _t = (t);						\
@@ -153,6 +156,7 @@ struct thermal_attr {
  * @trip_hyst_attrs:	attributes for trip points for sysfs: trip hysteresis
  * @devdata:	private pointer for device private data
  * @trips:	number of trip points the thermal zone supports
+ * @trips_disabled;	bitmap for disabled trips
  * @passive_delay:	number of milliseconds to wait between polls when
  *			performing passive cooling.
  * @polling_delay:	number of milliseconds to wait between polls when
@@ -167,6 +171,7 @@ struct thermal_attr {
  * @forced_passive:	If > 0, temperature at which to switch on all ACPI
  *			processor cooling devices.  Currently only used by the
  *			step-wise governor.
+ * @need_update:	if equals 1, thermal_zone_device_update needs to be invoked.
  * @ops:	operations this &thermal_zone_device supports
  * @tzp:	thermal zone parameters
  * @governor:	pointer to the governor for this thermal zone
@@ -187,6 +192,7 @@ struct thermal_zone_device {
 	struct thermal_attr *trip_hyst_attrs;
 	void *devdata;
 	int trips;
+	unsigned long trips_disabled;	/* bitmap for disabled trips */
 	int passive_delay;
 	int polling_delay;
 	int temperature;
@@ -194,6 +200,7 @@ struct thermal_zone_device {
 	int emul_temperature;
 	int passive;
 	unsigned int forced_passive;
+	atomic_t need_update;
 	struct thermal_zone_device_ops *ops;
 	struct thermal_zone_params *tzp;
 	struct thermal_governor *governor;
--- zfcpdump-kernel-4.4.orig/include/linux/time.h
+++ zfcpdump-kernel-4.4/include/linux/time.h
@@ -125,6 +125,32 @@ static inline bool timeval_valid(const s
 
 extern struct timespec timespec_trunc(struct timespec t, unsigned gran);
 
+/*
+ * Validates if a timespec/timeval used to inject a time offset is valid.
+ * Offsets can be postive or negative. The value of the timeval/timespec
+ * is the sum of its fields, but *NOTE*: the field tv_usec/tv_nsec must
+ * always be non-negative.
+ */
+static inline bool timeval_inject_offset_valid(const struct timeval *tv)
+{
+	/* We don't check the tv_sec as it can be positive or negative */
+
+	/* Can't have more microseconds then a second */
+	if (tv->tv_usec < 0 || tv->tv_usec >= USEC_PER_SEC)
+		return false;
+	return true;
+}
+
+static inline bool timespec_inject_offset_valid(const struct timespec *ts)
+{
+	/* We don't check the tv_sec as it can be positive or negative */
+
+	/* Can't have more nanoseconds then a second */
+	if (ts->tv_nsec < 0 || ts->tv_nsec >= NSEC_PER_SEC)
+		return false;
+	return true;
+}
+
 #define CURRENT_TIME		(current_kernel_time())
 #define CURRENT_TIME_SEC	((struct timespec) { get_seconds(), 0 })
 
--- zfcpdump-kernel-4.4.orig/include/linux/timekeeper_internal.h
+++ zfcpdump-kernel-4.4/include/linux/timekeeper_internal.h
@@ -50,6 +50,7 @@ struct tk_read_base {
  * @offs_tai:		Offset clock monotonic -> clock tai
  * @tai_offset:		The current UTC to TAI offset in seconds
  * @clock_was_set_seq:	The sequence number of clock was set events
+ * @cs_was_changed_seq:	The sequence number of clocksource change events
  * @next_leap_ktime:	CLOCK_MONOTONIC time value of a pending leap-second
  * @raw_time:		Monotonic raw base time in timespec64 format
  * @cycle_interval:	Number of clock cycles in one NTP interval
@@ -91,6 +92,7 @@ struct timekeeper {
 	ktime_t			offs_tai;
 	s32			tai_offset;
 	unsigned int		clock_was_set_seq;
+	u8			cs_was_changed_seq;
 	ktime_t			next_leap_ktime;
 	struct timespec64	raw_time;
 
--- zfcpdump-kernel-4.4.orig/include/linux/timekeeping.h
+++ zfcpdump-kernel-4.4/include/linux/timekeeping.h
@@ -267,6 +267,64 @@ extern void ktime_get_raw_and_real_ts64(
 				        struct timespec64 *ts_real);
 
 /*
+ * struct system_time_snapshot - simultaneous raw/real time capture with
+ *	counter value
+ * @cycles:	Clocksource counter value to produce the system times
+ * @real:	Realtime system time
+ * @raw:	Monotonic raw system time
+ * @clock_was_set_seq:	The sequence number of clock was set events
+ * @cs_was_changed_seq:	The sequence number of clocksource change events
+ */
+struct system_time_snapshot {
+	cycle_t		cycles;
+	ktime_t		real;
+	ktime_t		raw;
+	unsigned int	clock_was_set_seq;
+	u8		cs_was_changed_seq;
+};
+
+/*
+ * struct system_device_crosststamp - system/device cross-timestamp
+ *	(syncronized capture)
+ * @device:		Device time
+ * @sys_realtime:	Realtime simultaneous with device time
+ * @sys_monoraw:	Monotonic raw simultaneous with device time
+ */
+struct system_device_crosststamp {
+	ktime_t device;
+	ktime_t sys_realtime;
+	ktime_t sys_monoraw;
+};
+
+/*
+ * struct system_counterval_t - system counter value with the pointer to the
+ *	corresponding clocksource
+ * @cycles:	System counter value
+ * @cs:		Clocksource corresponding to system counter value. Used by
+ *	timekeeping code to verify comparibility of two cycle values
+ */
+struct system_counterval_t {
+	cycle_t			cycles;
+	struct clocksource	*cs;
+};
+
+/*
+ * Get cross timestamp between system clock and device clock
+ */
+extern int get_device_system_crosststamp(
+			int (*get_time_fn)(ktime_t *device_time,
+				struct system_counterval_t *system_counterval,
+				void *ctx),
+			void *ctx,
+			struct system_time_snapshot *history,
+			struct system_device_crosststamp *xtstamp);
+
+/*
+ * Simultaneously snapshot realtime and monotonic raw clocks
+ */
+extern void ktime_get_snapshot(struct system_time_snapshot *systime_snapshot);
+
+/*
  * Persistent clock related interfaces
  */
 extern int persistent_clock_is_local;
--- zfcpdump-kernel-4.4.orig/include/linux/trace_events.h
+++ zfcpdump-kernel-4.4/include/linux/trace_events.h
@@ -568,6 +568,8 @@ enum {
 	FILTER_DYN_STRING,
 	FILTER_PTR_STRING,
 	FILTER_TRACE_FN,
+	FILTER_COMM,
+	FILTER_CPU,
 };
 
 extern int trace_event_raw_init(struct trace_event_call *call);
--- zfcpdump-kernel-4.4.orig/include/linux/tracepoint.h
+++ zfcpdump-kernel-4.4/include/linux/tracepoint.h
@@ -14,8 +14,10 @@
  * See the file COPYING for more details.
  */
 
+#include <linux/smp.h>
 #include <linux/errno.h>
 #include <linux/types.h>
+#include <linux/cpumask.h>
 #include <linux/rcupdate.h>
 #include <linux/static_key.h>
 
@@ -352,15 +354,19 @@ extern void syscall_unregfunc(void);
  * "void *__data, proto" as the callback prototype.
  */
 #define DECLARE_TRACE_NOARGS(name)					\
-		__DECLARE_TRACE(name, void, , 1, void *__data, __data)
+	__DECLARE_TRACE(name, void, ,					\
+			cpu_online(raw_smp_processor_id()),		\
+			void *__data, __data)
 
 #define DECLARE_TRACE(name, proto, args)				\
-		__DECLARE_TRACE(name, PARAMS(proto), PARAMS(args), 1,	\
-				PARAMS(void *__data, proto),		\
-				PARAMS(__data, args))
+	__DECLARE_TRACE(name, PARAMS(proto), PARAMS(args),		\
+			cpu_online(raw_smp_processor_id()),		\
+			PARAMS(void *__data, proto),			\
+			PARAMS(__data, args))
 
 #define DECLARE_TRACE_CONDITION(name, proto, args, cond)		\
-	__DECLARE_TRACE(name, PARAMS(proto), PARAMS(args), PARAMS(cond), \
+	__DECLARE_TRACE(name, PARAMS(proto), PARAMS(args),		\
+			cpu_online(raw_smp_processor_id()) && (PARAMS(cond)), \
 			PARAMS(void *__data, proto),			\
 			PARAMS(__data, args))
 
--- zfcpdump-kernel-4.4.orig/include/linux/tty.h
+++ zfcpdump-kernel-4.4/include/linux/tty.h
@@ -338,7 +338,6 @@ struct tty_file_private {
 #define TTY_EXCLUSIVE 		3	/* Exclusive open mode */
 #define TTY_DEBUG 		4	/* Debugging */
 #define TTY_DO_WRITE_WAKEUP 	5	/* Call write_wakeup after queuing new */
-#define TTY_OTHER_DONE		6	/* Closed pty has completed input processing */
 #define TTY_LDISC_OPEN	 	11	/* Line discipline is open */
 #define TTY_PTY_LOCK 		16	/* pty private */
 #define TTY_NO_WRITE_SPLIT 	17	/* Preserve write boundaries to driver */
@@ -469,6 +468,7 @@ extern void tty_buffer_init(struct tty_p
 extern void tty_buffer_set_lock_subclass(struct tty_port *port);
 extern bool tty_buffer_restart_work(struct tty_port *port);
 extern bool tty_buffer_cancel_work(struct tty_port *port);
+extern void tty_buffer_flush_work(struct tty_port *port);
 extern speed_t tty_termios_baud_rate(struct ktermios *termios);
 extern speed_t tty_termios_input_baud_rate(struct ktermios *termios);
 extern void tty_termios_encode_baud_rate(struct ktermios *termios,
@@ -594,7 +594,7 @@ static inline int tty_ldisc_receive_buf(
 		count = ld->ops->receive_buf2(ld->tty, p, f, count);
 	else {
 		count = min_t(int, count, ld->tty->receive_room);
-		if (count)
+		if (count && ld->ops->receive_buf)
 			ld->ops->receive_buf(ld->tty, p, f, count);
 	}
 	return count;
@@ -654,6 +654,7 @@ extern long vt_compat_ioctl(struct tty_s
 /* tty_mutex.c */
 /* functions for preparation of BKL removal */
 extern void __lockfunc tty_lock(struct tty_struct *tty);
+extern int  tty_lock_interruptible(struct tty_struct *tty);
 extern void __lockfunc tty_unlock(struct tty_struct *tty);
 extern void __lockfunc tty_lock_slave(struct tty_struct *tty);
 extern void __lockfunc tty_unlock_slave(struct tty_struct *tty);
--- zfcpdump-kernel-4.4.orig/include/linux/ucs2_string.h
+++ zfcpdump-kernel-4.4/include/linux/ucs2_string.h
@@ -11,4 +11,8 @@ unsigned long ucs2_strlen(const ucs2_cha
 unsigned long ucs2_strsize(const ucs2_char_t *data, unsigned long maxlength);
 int ucs2_strncmp(const ucs2_char_t *a, const ucs2_char_t *b, size_t len);
 
+unsigned long ucs2_utf8size(const ucs2_char_t *src);
+unsigned long ucs2_as_utf8(u8 *dest, const ucs2_char_t *src,
+			   unsigned long maxlength);
+
 #endif /* _LINUX_UCS2_STRING_H_ */
--- zfcpdump-kernel-4.4.orig/include/linux/uidgid.h
+++ zfcpdump-kernel-4.4/include/linux/uidgid.h
@@ -117,6 +117,16 @@ static inline bool gid_valid(kgid_t gid)
 	return __kgid_val(gid) != (gid_t) -1;
 }
 
+static inline bool uid_valid_eq(kuid_t left, kuid_t right)
+{
+	return uid_eq(left, right) && uid_valid(left);
+}
+
+static inline bool gid_valid_eq(kgid_t left, kgid_t right)
+{
+	return gid_eq(left, right) && gid_valid(left);
+}
+
 #ifdef CONFIG_USER_NS
 
 extern kuid_t make_kuid(struct user_namespace *from, uid_t uid);
--- zfcpdump-kernel-4.4.orig/include/linux/uio.h
+++ zfcpdump-kernel-4.4/include/linux/uio.h
@@ -76,7 +76,7 @@ size_t iov_iter_copy_from_user_atomic(st
 		struct iov_iter *i, unsigned long offset, size_t bytes);
 void iov_iter_advance(struct iov_iter *i, size_t bytes);
 int iov_iter_fault_in_readable(struct iov_iter *i, size_t bytes);
-int iov_iter_fault_in_multipages_readable(struct iov_iter *i, size_t bytes);
+#define iov_iter_fault_in_multipages_readable iov_iter_fault_in_readable
 size_t iov_iter_single_seg_count(const struct iov_iter *i);
 size_t copy_page_to_iter(struct page *page, size_t offset, size_t bytes,
 			 struct iov_iter *i);
--- zfcpdump-kernel-4.4.orig/include/linux/usb.h
+++ zfcpdump-kernel-4.4/include/linux/usb.h
@@ -50,6 +50,7 @@ struct ep_device;
  * struct usb_host_endpoint - host-side endpoint descriptor and queue
  * @desc: descriptor for this endpoint, wMaxPacketSize in native byteorder
  * @ss_ep_comp: SuperSpeed companion descriptor for this endpoint
+ * @ssp_isoc_ep_comp: SuperSpeedPlus isoc companion descriptor for this endpoint
  * @urb_list: urbs queued to this endpoint; maintained by usbcore
  * @hcpriv: for use by HCD; typically holds hardware dma queue head (QH)
  *	with one or more transfer descriptors (TDs) per urb
@@ -65,6 +66,7 @@ struct ep_device;
 struct usb_host_endpoint {
 	struct usb_endpoint_descriptor		desc;
 	struct usb_ss_ep_comp_descriptor	ss_ep_comp;
+	struct usb_ssp_isoc_ep_comp_descriptor	ssp_isoc_ep_comp;
 	struct list_head		urb_list;
 	void				*hcpriv;
 	struct ep_device		*ep_dev;	/* For sysfs info */
@@ -330,6 +332,7 @@ struct usb_host_bos {
 	struct usb_ss_cap_descriptor	*ss_cap;
 	struct usb_ssp_cap_descriptor	*ssp_cap;
 	struct usb_ss_container_id_descriptor	*ss_id;
+	struct usb_ptm_cap_descriptor	*ptm_cap;
 };
 
 int __usb_get_extra_descriptor(char *buffer, unsigned size,
@@ -371,14 +374,13 @@ struct usb_bus {
 
 	int devnum_next;		/* Next open device number in
 					 * round-robin allocation */
+	struct mutex devnum_next_mutex; /* devnum_next mutex */
 
 	struct usb_devmap devmap;	/* device address allocation map */
 	struct usb_device *root_hub;	/* Root hub */
 	struct usb_bus *hs_companion;	/* Companion EHCI bus, if any */
 	struct list_head bus_list;	/* list of busses */
 
-	struct mutex usb_address0_mutex; /* unaddressed device mutex */
-
 	int bandwidth_allocated;	/* on this bus: how much of the time
 					 * reserved for periodic (intr/iso)
 					 * requests is used, on average?
@@ -511,6 +513,8 @@ struct usb3_lpm_parameters {
  * @usb2_hw_lpm_enabled: USB2 hardware LPM is enabled
  * @usb2_hw_lpm_allowed: Userspace allows USB 2.0 LPM to be enabled
  * @usb3_lpm_enabled: USB3 hardware LPM enabled
+ * @usb3_lpm_u1_enabled: USB3 hardware U1 LPM enabled
+ * @usb3_lpm_u2_enabled: USB3 hardware U2 LPM enabled
  * @string_langid: language ID for strings
  * @product: iProduct string, if present (static)
  * @manufacturer: iManufacturer string, if present (static)
@@ -584,6 +588,8 @@ struct usb_device {
 	unsigned usb2_hw_lpm_enabled:1;
 	unsigned usb2_hw_lpm_allowed:1;
 	unsigned usb3_lpm_enabled:1;
+	unsigned usb3_lpm_u1_enabled:1;
+	unsigned usb3_lpm_u2_enabled:1;
 	int string_langid;
 
 	/* static strings from the device */
@@ -1064,7 +1070,7 @@ struct usbdrv_wrap {
  *	for interfaces bound to this driver.
  * @soft_unbind: if set to 1, the USB core will not kill URBs and disable
  *	endpoints before calling the driver's disconnect method.
- * @disable_hub_initiated_lpm: if set to 0, the USB core will not allow hubs
+ * @disable_hub_initiated_lpm: if set to 1, the USB core will not allow hubs
  *	to initiate lower power link state transitions when an idle timeout
  *	occurs.  Device-initiated USB 3.0 link PM will still be allowed.
  *
--- zfcpdump-kernel-4.4.orig/include/linux/usb/ehci_def.h
+++ zfcpdump-kernel-4.4/include/linux/usb/ehci_def.h
@@ -180,11 +180,11 @@ struct ehci_regs {
  * PORTSCx
  */
 	/* HOSTPC: offset 0x84 */
-	u32		hostpc[1];	/* HOSTPC extension */
+	u32		hostpc[0];	/* HOSTPC extension */
 #define HOSTPC_PHCD	(1<<22)		/* Phy clock disable */
 #define HOSTPC_PSPD	(3<<25)		/* Port speed detection */
 
-	u32		reserved5[16];
+	u32		reserved5[17];
 
 	/* USBMODE_EX: offset 0xc8 */
 	u32		usbmode_ex;	/* USB Device mode extension */
--- zfcpdump-kernel-4.4.orig/include/linux/usb/hcd.h
+++ zfcpdump-kernel-4.4/include/linux/usb/hcd.h
@@ -180,6 +180,7 @@ struct usb_hcd {
 	 * bandwidth_mutex should be dropped after a successful control message
 	 * to the device, or resetting the bandwidth after a failed attempt.
 	 */
+	struct mutex		*address0_mutex;
 	struct mutex		*bandwidth_mutex;
 	struct usb_hcd		*shared_hcd;
 	struct usb_hcd		*primary_hcd;
--- zfcpdump-kernel-4.4.orig/include/linux/usb_usual.h
+++ zfcpdump-kernel-4.4/include/linux/usb_usual.h
@@ -79,6 +79,8 @@
 		/* Cannot handle MI_REPORT_SUPPORTED_OPERATION_CODES */	\
 	US_FLAG(MAX_SECTORS_240,	0x08000000)		\
 		/* Sets max_sectors to 240 */			\
+	US_FLAG(NO_REPORT_LUNS,	0x10000000)			\
+		/* Cannot handle REPORT_LUNS */			\
 
 #define US_FLAG(name, value)	US_FL_##name = value ,
 enum { US_DO_ALL_FLAGS };
--- zfcpdump-kernel-4.4.orig/include/linux/user_namespace.h
+++ zfcpdump-kernel-4.4/include/linux/user_namespace.h
@@ -72,6 +72,7 @@ extern ssize_t proc_projid_map_write(str
 extern ssize_t proc_setgroups_write(struct file *, const char __user *, size_t, loff_t *);
 extern int proc_setgroups_show(struct seq_file *m, void *v);
 extern bool userns_may_setgroups(const struct user_namespace *ns);
+extern bool current_in_userns(const struct user_namespace *target_ns);
 #else
 
 static inline struct user_namespace *get_user_ns(struct user_namespace *ns)
@@ -100,6 +101,11 @@ static inline bool userns_may_setgroups(
 {
 	return true;
 }
+
+static inline bool current_in_userns(const struct user_namespace *target_ns)
+{
+	return true;
+}
 #endif
 
 #endif /* _LINUX_USER_H */
--- zfcpdump-kernel-4.4.orig/include/linux/vt_kern.h
+++ zfcpdump-kernel-4.4/include/linux/vt_kern.h
@@ -130,7 +130,8 @@ int con_copy_unimap(struct vc_data *dst_
 void vt_event_post(unsigned int event, unsigned int old, unsigned int new);
 int vt_waitactive(int n);
 void change_console(struct vc_data *new_vc);
-void reset_vc(struct vc_data *vc);
+void reset_vc(struct vc_data *vc, int mode);
+
 extern int do_unbind_con_driver(const struct consw *csw, int first, int last,
 			     int deflt);
 int vty_init(const struct file_operations *console_fops);
--- zfcpdump-kernel-4.4.orig/include/linux/writeback.h
+++ zfcpdump-kernel-4.4/include/linux/writeback.h
@@ -198,6 +198,7 @@ void wbc_attach_and_unlock_inode(struct
 void wbc_detach_inode(struct writeback_control *wbc);
 void wbc_account_io(struct writeback_control *wbc, struct page *page,
 		    size_t bytes);
+void cgroup_writeback_umount(void);
 
 /**
  * inode_attach_wb - associate an inode with its wb
@@ -301,6 +302,10 @@ static inline void wbc_account_io(struct
 {
 }
 
+static inline void cgroup_writeback_umount(void)
+{
+}
+
 #endif	/* CONFIG_CGROUP_WRITEBACK */
 
 /*
--- zfcpdump-kernel-4.4.orig/include/media/videobuf2-core.h
+++ zfcpdump-kernel-4.4/include/media/videobuf2-core.h
@@ -363,6 +363,7 @@ struct vb2_ops {
 };
 
 struct vb2_buf_ops {
+	int (*verify_planes_array)(struct vb2_buffer *vb, const void *pb);
 	int (*fill_user_buffer)(struct vb2_buffer *vb, void *pb);
 	int (*fill_vb2_buffer)(struct vb2_buffer *vb, const void *pb,
 				struct vb2_plane *planes);
--- zfcpdump-kernel-4.4.orig/include/misc/cxl.h
+++ zfcpdump-kernel-4.4/include/misc/cxl.h
@@ -30,9 +30,6 @@ struct cxl_afu *cxl_pci_to_afu(struct pc
 /* Get the AFU conf record number associated with a pci_dev */
 unsigned int cxl_pci_to_cfg_record(struct pci_dev *dev);
 
-/* Get the physical device (ie. the PCIe card) which the AFU is attached */
-struct device *cxl_get_phys_dev(struct pci_dev *dev);
-
 
 /*
  * Context lifetime overview:
@@ -210,4 +207,9 @@ ssize_t cxl_fd_read(struct file *file, c
 void cxl_perst_reloads_same_image(struct cxl_afu *afu,
 				  bool perst_reloads_same_image);
 
+/*
+ * Read the VPD for the card where the AFU resides
+ */
+ssize_t cxl_read_adapter_vpd(struct pci_dev *dev, void *buf, size_t count);
+
 #endif /* _MISC_CXL_H */
--- zfcpdump-kernel-4.4.orig/include/net/af_unix.h
+++ zfcpdump-kernel-4.4/include/net/af_unix.h
@@ -6,8 +6,8 @@
 #include <linux/mutex.h>
 #include <net/sock.h>
 
-void unix_inflight(struct file *fp);
-void unix_notinflight(struct file *fp);
+void unix_inflight(struct user_struct *user, struct file *fp);
+void unix_notinflight(struct user_struct *user, struct file *fp);
 void unix_gc(void);
 void wait_for_unix_gc(void);
 struct sock *unix_get_socket(struct file *filp);
@@ -52,7 +52,7 @@ struct unix_sock {
 	struct sock		sk;
 	struct unix_address     *addr;
 	struct path		path;
-	struct mutex		readlock;
+	struct mutex		iolock, bindlock;
 	struct sock		*peer;
 	struct list_head	link;
 	atomic_long_t		inflight;
--- zfcpdump-kernel-4.4.orig/include/net/bluetooth/hci_core.h
+++ zfcpdump-kernel-4.4/include/net/bluetooth/hci_core.h
@@ -394,6 +394,7 @@ struct hci_dev {
 	int (*close)(struct hci_dev *hdev);
 	int (*flush)(struct hci_dev *hdev);
 	int (*setup)(struct hci_dev *hdev);
+	void (*post_open)(struct hci_dev *hdev);
 	int (*shutdown)(struct hci_dev *hdev);
 	int (*send)(struct hci_dev *hdev, struct sk_buff *skb);
 	void (*notify)(struct hci_dev *hdev, unsigned int evt);
--- zfcpdump-kernel-4.4.orig/include/net/bonding.h
+++ zfcpdump-kernel-4.4/include/net/bonding.h
@@ -214,6 +214,7 @@ struct bonding {
 	 * ALB mode (6) - to sync the use and modifications of its hash table
 	 */
 	spinlock_t mode_lock;
+	spinlock_t stats_lock;
 	u8	 send_peer_notif;
 	u8       igmp_retrans;
 #ifdef CONFIG_PROC_FS
--- zfcpdump-kernel-4.4.orig/include/net/codel.h
+++ zfcpdump-kernel-4.4/include/net/codel.h
@@ -162,12 +162,14 @@ struct codel_vars {
  * struct codel_stats - contains codel shared variables and stats
  * @maxpacket:	largest packet we've seen so far
  * @drop_count:	temp count of dropped packets in dequeue()
+ * @drop_len:	bytes of dropped packets in dequeue()
  * ecn_mark:	number of packets we ECN marked instead of dropping
  * ce_mark:	number of packets CE marked because sojourn time was above ce_threshold
  */
 struct codel_stats {
 	u32		maxpacket;
 	u32		drop_count;
+	u32		drop_len;
 	u32		ecn_mark;
 	u32		ce_mark;
 };
@@ -308,6 +310,7 @@ static struct sk_buff *codel_dequeue(str
 								  vars->rec_inv_sqrt);
 					goto end;
 				}
+				stats->drop_len += qdisc_pkt_len(skb);
 				qdisc_drop(skb, sch);
 				stats->drop_count++;
 				skb = dequeue_func(vars, sch);
@@ -330,6 +333,7 @@ static struct sk_buff *codel_dequeue(str
 		if (params->ecn && INET_ECN_set_ce(skb)) {
 			stats->ecn_mark++;
 		} else {
+			stats->drop_len += qdisc_pkt_len(skb);
 			qdisc_drop(skb, sch);
 			stats->drop_count++;
 
--- zfcpdump-kernel-4.4.orig/include/net/dst_metadata.h
+++ zfcpdump-kernel-4.4/include/net/dst_metadata.h
@@ -44,6 +44,24 @@ static inline bool skb_valid_dst(const s
 	return dst && !(dst->flags & DST_METADATA);
 }
 
+static inline int skb_metadata_dst_cmp(const struct sk_buff *skb_a,
+				       const struct sk_buff *skb_b)
+{
+	const struct metadata_dst *a, *b;
+
+	if (!(skb_a->_skb_refdst | skb_b->_skb_refdst))
+		return 0;
+
+	a = (const struct metadata_dst *) skb_dst(skb_a);
+	b = (const struct metadata_dst *) skb_dst(skb_b);
+
+	if (!a != !b || a->u.tun_info.options_len != b->u.tun_info.options_len)
+		return 1;
+
+	return memcmp(&a->u.tun_info, &b->u.tun_info,
+		      sizeof(a->u.tun_info) + a->u.tun_info.options_len);
+}
+
 struct metadata_dst *metadata_dst_alloc(u8 optslen, gfp_t flags);
 struct metadata_dst __percpu *metadata_dst_alloc_percpu(u8 optslen, gfp_t flags);
 
--- zfcpdump-kernel-4.4.orig/include/net/geneve.h
+++ zfcpdump-kernel-4.4/include/net/geneve.h
@@ -62,6 +62,14 @@ struct genevehdr {
 	struct geneve_opt options[];
 };
 
+#if IS_ENABLED(CONFIG_GENEVE)
+void geneve_get_rx_port(struct net_device *netdev);
+#else
+static inline void geneve_get_rx_port(struct net_device *netdev)
+{
+}
+#endif
+
 #ifdef CONFIG_INET
 struct net_device *geneve_dev_create_fb(struct net *net, const char *name,
 					u8 name_assign_type, u16 dst_port);
--- zfcpdump-kernel-4.4.orig/include/net/inet_connection_sock.h
+++ zfcpdump-kernel-4.4/include/net/inet_connection_sock.h
@@ -270,8 +270,9 @@ struct dst_entry *inet_csk_route_child_s
 					    struct sock *newsk,
 					    const struct request_sock *req);
 
-void inet_csk_reqsk_queue_add(struct sock *sk, struct request_sock *req,
-			      struct sock *child);
+struct sock *inet_csk_reqsk_queue_add(struct sock *sk,
+				      struct request_sock *req,
+				      struct sock *child);
 void inet_csk_reqsk_queue_hash_add(struct sock *sk, struct request_sock *req,
 				   unsigned long timeout);
 struct sock *inet_csk_complete_hashdance(struct sock *sk, struct sock *child,
--- zfcpdump-kernel-4.4.orig/include/net/inet_ecn.h
+++ zfcpdump-kernel-4.4/include/net/inet_ecn.h
@@ -111,11 +111,24 @@ static inline void ipv4_copy_dscp(unsign
 
 struct ipv6hdr;
 
-static inline int IP6_ECN_set_ce(struct ipv6hdr *iph)
+/* Note:
+ * IP_ECN_set_ce() has to tweak IPV4 checksum when setting CE,
+ * meaning both changes have no effect on skb->csum if/when CHECKSUM_COMPLETE
+ * In IPv6 case, no checksum compensates the change in IPv6 header,
+ * so we have to update skb->csum.
+ */
+static inline int IP6_ECN_set_ce(struct sk_buff *skb, struct ipv6hdr *iph)
 {
+	__be32 from, to;
+
 	if (INET_ECN_is_not_ect(ipv6_get_dsfield(iph)))
 		return 0;
-	*(__be32*)iph |= htonl(INET_ECN_CE << 20);
+
+	from = *(__be32 *)iph;
+	to = from | htonl(INET_ECN_CE << 20);
+	*(__be32 *)iph = to;
+	if (skb->ip_summed == CHECKSUM_COMPLETE)
+		skb->csum = csum_add(csum_sub(skb->csum, from), to);
 	return 1;
 }
 
@@ -142,7 +155,7 @@ static inline int INET_ECN_set_ce(struct
 	case cpu_to_be16(ETH_P_IPV6):
 		if (skb_network_header(skb) + sizeof(struct ipv6hdr) <=
 		    skb_tail_pointer(skb))
-			return IP6_ECN_set_ce(ipv6_hdr(skb));
+			return IP6_ECN_set_ce(skb, ipv6_hdr(skb));
 		break;
 	}
 
--- zfcpdump-kernel-4.4.orig/include/net/ip6_route.h
+++ zfcpdump-kernel-4.4/include/net/ip6_route.h
@@ -64,8 +64,16 @@ static inline bool rt6_need_strict(const
 
 void ip6_route_input(struct sk_buff *skb);
 
-struct dst_entry *ip6_route_output(struct net *net, const struct sock *sk,
-				   struct flowi6 *fl6);
+struct dst_entry *ip6_route_output_flags(struct net *net, const struct sock *sk,
+					 struct flowi6 *fl6, int flags);
+
+static inline struct dst_entry *ip6_route_output(struct net *net,
+						 const struct sock *sk,
+						 struct flowi6 *fl6)
+{
+	return ip6_route_output_flags(net, sk, fl6, 0);
+}
+
 struct dst_entry *ip6_route_lookup(struct net *net, struct flowi6 *fl6,
 				   int flags);
 
--- zfcpdump-kernel-4.4.orig/include/net/ip_fib.h
+++ zfcpdump-kernel-4.4/include/net/ip_fib.h
@@ -61,6 +61,7 @@ struct fib_nh_exception {
 	struct rtable __rcu		*fnhe_rth_input;
 	struct rtable __rcu		*fnhe_rth_output;
 	unsigned long			fnhe_stamp;
+	struct rcu_head			rcu;
 };
 
 struct fnhe_hash_bucket {
--- zfcpdump-kernel-4.4.orig/include/net/ip_tunnels.h
+++ zfcpdump-kernel-4.4/include/net/ip_tunnels.h
@@ -91,6 +91,28 @@ struct ip_tunnel_dst {
 };
 
 struct metadata_dst;
+/* A fan overlay /8 (250.0.0.0/8, for example) maps to exactly one /16
+ * underlay (10.88.0.0/16, for example).  Multiple local addresses within
+ * the /16 may be used, but a particular overlay may not span
+ * multiple underlay subnets.
+ *
+ * We store one underlay, indexed by the overlay's high order octet.
+ */
+#define FAN_OVERLAY_CNT		256
+
+struct ip_fan_map {
+	__be32			underlay;
+	__be32			overlay;
+	u16			underlay_prefix;
+	u16			overlay_prefix;
+	u32			overlay_mask;
+	struct list_head	list;
+	struct rcu_head		rcu;
+};
+
+struct ip_tunnel_fan {
+	struct list_head	fan_maps;
+};
 
 struct ip_tunnel {
 	struct ip_tunnel __rcu	*next;
@@ -123,6 +145,7 @@ struct ip_tunnel {
 #endif
 	struct ip_tunnel_prl_entry __rcu *prl;	/* potential router list */
 	unsigned int		prl_count;	/* # of entries in PRL */
+	struct ip_tunnel_fan	fan;
 	int			ip_tnl_net_id;
 	struct gro_cells	gro_cells;
 	bool			collect_md;
@@ -144,6 +167,11 @@ struct ip_tunnel {
 
 #define TUNNEL_OPTIONS_PRESENT	(TUNNEL_GENEVE_OPT | TUNNEL_VXLAN_OPT)
 
+static inline int fan_has_map(const struct ip_tunnel_fan *fan)
+{
+	return !list_empty(&fan->fan_maps);
+}
+
 struct tnl_ptk_info {
 	__be16 flags;
 	__be16 proto;
@@ -230,6 +258,7 @@ void ip_tunnel_xmit(struct sk_buff *skb,
 int ip_tunnel_ioctl(struct net_device *dev, struct ip_tunnel_parm *p, int cmd);
 int ip_tunnel_encap(struct sk_buff *skb, struct ip_tunnel *t,
 		    u8 *protocol, struct flowi4 *fl4);
+int __ip_tunnel_change_mtu(struct net_device *dev, int new_mtu, bool strict);
 int ip_tunnel_change_mtu(struct net_device *dev, int new_mtu);
 
 struct rtnl_link_stats64 *ip_tunnel_get_stats64(struct net_device *dev,
@@ -282,6 +311,22 @@ struct metadata_dst *iptunnel_metadata_r
 struct sk_buff *iptunnel_handle_offloads(struct sk_buff *skb, bool gre_csum,
 					 int gso_type_mask);
 
+static inline int iptunnel_pull_offloads(struct sk_buff *skb)
+{
+	if (skb_is_gso(skb)) {
+		int err;
+
+		err = skb_unclone(skb, GFP_ATOMIC);
+		if (unlikely(err))
+			return err;
+		skb_shinfo(skb)->gso_type &= ~(NETIF_F_GSO_ENCAP_ALL >>
+					       NETIF_F_GSO_SHIFT);
+	}
+
+	skb->encapsulation = 0;
+	return 0;
+}
+
 static inline void iptunnel_xmit_stats(int err,
 				       struct net_device_stats *err_stats,
 				       struct pcpu_sw_netstats __percpu *stats)
--- zfcpdump-kernel-4.4.orig/include/net/ip_vs.h
+++ zfcpdump-kernel-4.4/include/net/ip_vs.h
@@ -1588,6 +1588,23 @@ static inline void ip_vs_conn_drop_connt
 }
 #endif /* CONFIG_IP_VS_NFCT */
 
+/* Really using conntrack? */
+static inline bool ip_vs_conn_uses_conntrack(struct ip_vs_conn *cp,
+					     struct sk_buff *skb)
+{
+#ifdef CONFIG_IP_VS_NFCT
+	enum ip_conntrack_info ctinfo;
+	struct nf_conn *ct;
+
+	if (!(cp->flags & IP_VS_CONN_F_NFCT))
+		return false;
+	ct = nf_ct_get(skb, &ctinfo);
+	if (ct && !nf_ct_is_untracked(ct))
+		return true;
+#endif
+	return false;
+}
+
 static inline int
 ip_vs_dest_conn_overhead(struct ip_vs_dest *dest)
 {
--- zfcpdump-kernel-4.4.orig/include/net/iw_handler.h
+++ zfcpdump-kernel-4.4/include/net/iw_handler.h
@@ -439,6 +439,12 @@ int dev_get_wireless_info(char *buffer,
 /* Send a single event to user space */
 void wireless_send_event(struct net_device *dev, unsigned int cmd,
 			 union iwreq_data *wrqu, const char *extra);
+#ifdef CONFIG_WEXT_CORE
+/* flush all previous wext events - if work is done from netdev notifiers */
+void wireless_nlevent_flush(void);
+#else
+static inline void wireless_nlevent_flush(void) {}
+#endif
 
 /* We may need a function to send a stream of events to user space.
  * More on that later... */
--- zfcpdump-kernel-4.4.orig/include/net/pkt_cls.h
+++ zfcpdump-kernel-4.4/include/net/pkt_cls.h
@@ -358,4 +358,38 @@ tcf_match_indev(struct sk_buff *skb, int
 }
 #endif /* CONFIG_NET_CLS_IND */
 
+struct tc_cls_u32_knode {
+	struct tcf_exts *exts;
+	u8 fshift;
+	u32 handle;
+	u32 val;
+	u32 mask;
+	u32 link_handle;
+	struct tc_u32_sel *sel;
+};
+
+struct tc_cls_u32_hnode {
+	u32 handle;
+	u32 prio;
+	unsigned int divisor;
+};
+
+enum tc_clsu32_command {
+	TC_CLSU32_NEW_KNODE,
+	TC_CLSU32_REPLACE_KNODE,
+	TC_CLSU32_DELETE_KNODE,
+	TC_CLSU32_NEW_HNODE,
+	TC_CLSU32_REPLACE_HNODE,
+	TC_CLSU32_DELETE_HNODE,
+};
+
+struct tc_cls_u32_offload {
+	/* knode values */
+	enum tc_clsu32_command command;
+	union {
+		struct tc_cls_u32_knode knode;
+		struct tc_cls_u32_hnode hnode;
+	};
+};
+
 #endif
--- zfcpdump-kernel-4.4.orig/include/net/sch_generic.h
+++ zfcpdump-kernel-4.4/include/net/sch_generic.h
@@ -396,7 +396,8 @@ struct Qdisc *dev_graft_qdisc(struct net
 			      struct Qdisc *qdisc);
 void qdisc_reset(struct Qdisc *qdisc);
 void qdisc_destroy(struct Qdisc *qdisc);
-void qdisc_tree_decrease_qlen(struct Qdisc *qdisc, unsigned int n);
+void qdisc_tree_reduce_backlog(struct Qdisc *qdisc, unsigned int n,
+			       unsigned int len);
 struct Qdisc *qdisc_alloc(struct netdev_queue *dev_queue,
 			  const struct Qdisc_ops *ops);
 struct Qdisc *qdisc_create_dflt(struct netdev_queue *dev_queue,
@@ -698,6 +699,23 @@ static inline void qdisc_reset_queue(str
 	sch->qstats.backlog = 0;
 }
 
+static inline struct Qdisc *qdisc_replace(struct Qdisc *sch, struct Qdisc *new,
+					  struct Qdisc **pold)
+{
+	struct Qdisc *old;
+
+	sch_tree_lock(sch);
+	old = *pold;
+	*pold = new;
+	if (old != NULL) {
+		qdisc_tree_reduce_backlog(old, old->q.qlen, old->qstats.backlog);
+		qdisc_reset(old);
+	}
+	sch_tree_unlock(sch);
+
+	return old;
+}
+
 static inline unsigned int __qdisc_queue_drop(struct Qdisc *sch,
 					      struct sk_buff_head *list)
 {
--- zfcpdump-kernel-4.4.orig/include/net/scm.h
+++ zfcpdump-kernel-4.4/include/net/scm.h
@@ -21,6 +21,7 @@ struct scm_creds {
 struct scm_fp_list {
 	short			count;
 	short			max;
+	struct user_struct	*user;
 	struct file		*fp[SCM_MAX_FD];
 };
 
--- zfcpdump-kernel-4.4.orig/include/net/switchdev.h
+++ zfcpdump-kernel-4.4/include/net/switchdev.h
@@ -88,7 +88,7 @@ struct switchdev_obj_ipv4_fib {
 	struct switchdev_obj obj;
 	u32 dst;
 	int dst_len;
-	struct fib_info fi;
+	struct fib_info *fi;
 	u8 tos;
 	u8 type;
 	u32 nlflags;
--- zfcpdump-kernel-4.4.orig/include/net/tc_act/tc_gact.h
+++ zfcpdump-kernel-4.4/include/net/tc_act/tc_gact.h
@@ -2,6 +2,7 @@
 #define __NET_TC_GACT_H
 
 #include <net/act_api.h>
+#include <linux/tc_act/tc_gact.h>
 
 struct tcf_gact {
 	struct tcf_common	common;
@@ -15,4 +16,19 @@ struct tcf_gact {
 #define to_gact(a) \
 	container_of(a->priv, struct tcf_gact, common)
 
+#ifdef CONFIG_NET_CLS_ACT
+static inline bool is_tcf_gact_shot(const struct tc_action *a)
+{
+	struct tcf_gact *gact;
+
+	if (a->ops && a->ops->type != TCA_ACT_GACT)
+		return false;
+
+	gact = a->priv;
+	if (gact->tcf_action == TC_ACT_SHOT)
+		return true;
+
+	return false;
+}
+#endif
 #endif /* __NET_TC_GACT_H */
--- zfcpdump-kernel-4.4.orig/include/net/tcp.h
+++ zfcpdump-kernel-4.4/include/net/tcp.h
@@ -449,7 +449,7 @@ const u8 *tcp_parse_md5sig_option(const
 
 void tcp_v4_send_check(struct sock *sk, struct sk_buff *skb);
 void tcp_v4_mtu_reduced(struct sock *sk);
-void tcp_req_err(struct sock *sk, u32 seq);
+void tcp_req_err(struct sock *sk, u32 seq, bool abort);
 int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb);
 struct sock *tcp_create_openreq_child(const struct sock *sk,
 				      struct request_sock *req,
@@ -1510,6 +1510,8 @@ static inline void tcp_check_send_head(s
 {
 	if (sk->sk_send_head == skb_unlinked)
 		sk->sk_send_head = NULL;
+	if (tcp_sk(sk)->highest_sack == skb_unlinked)
+		tcp_sk(sk)->highest_sack = NULL;
 }
 
 static inline void tcp_init_send_head(struct sock *sk)
--- zfcpdump-kernel-4.4.orig/include/net/vxlan.h
+++ zfcpdump-kernel-4.4/include/net/vxlan.h
@@ -161,6 +161,8 @@ struct vxlan_dev {
 	struct vxlan_rdst default_dst;	/* default destination */
 	u32		  flags;	/* VXLAN_F_* in vxlan.h */
 
+	struct ip_tunnel_fan fan;
+
 	struct timer_list age_timer;
 	spinlock_t	  hash_lock;
 	unsigned int	  addrcnt;
--- zfcpdump-kernel-4.4.orig/include/rdma/ib.h
+++ zfcpdump-kernel-4.4/include/rdma/ib.h
@@ -34,6 +34,7 @@
 #define _RDMA_IB_H
 
 #include <linux/types.h>
+#include <linux/sched.h>
 
 struct ib_addr {
 	union {
@@ -86,4 +87,19 @@ struct sockaddr_ib {
 	__u64			sib_scope_id;
 };
 
+/*
+ * The IB interfaces that use write() as bi-directional ioctl() are
+ * fundamentally unsafe, since there are lots of ways to trigger "write()"
+ * calls from various contexts with elevated privileges. That includes the
+ * traditional suid executable error message writes, but also various kernel
+ * interfaces that can write to file descriptors.
+ *
+ * This function provides protection for the legacy API by restricting the
+ * calling context.
+ */
+static inline bool ib_safe_file_access(struct file *filp)
+{
+	return filp->f_cred == current_cred() && segment_eq(get_fs(), USER_DS);
+}
+
 #endif /* _RDMA_IB_H */
--- zfcpdump-kernel-4.4.orig/include/scsi/libiscsi.h
+++ zfcpdump-kernel-4.4/include/scsi/libiscsi.h
@@ -331,19 +331,12 @@ struct iscsi_session {
 	struct iscsi_transport	*tt;
 	struct Scsi_Host	*host;
 	struct iscsi_conn	*leadconn;	/* leading connection */
-	/* Between the forward and the backward locks exists a strict locking
-	 * hierarchy. The mutual exclusion zone protected by the forward lock
-	 * can enclose the mutual exclusion zone protected by the backward lock
-	 * but not vice versa.
-	 */
-	spinlock_t		frwd_lock;	/* protects session state, *
-						 * cmdsn, queued_cmdsn     *
+	spinlock_t		lock;		/* protects session state, *
+						 * sequence numbers,       *
 						 * session resources:      *
-						 * - cmdpool kfifo_out ,   *
-						 * - mgmtpool,		   */
-	spinlock_t		back_lock;	/* protects cmdsn_exp      *
-						 * cmdsn_max,              *
-						 * cmdpool kfifo_in        */
+						 * - cmdpool,		   *
+						 * - mgmtpool,		   *
+						 * - r2tpool		   */
 	int			state;		/* session state           */
 	int			age;		/* counts session re-opens */
 
--- zfcpdump-kernel-4.4.orig/include/scsi/libiscsi_tcp.h
+++ zfcpdump-kernel-4.4/include/scsi/libiscsi_tcp.h
@@ -83,8 +83,6 @@ struct iscsi_tcp_task {
 	struct iscsi_pool	r2tpool;
 	struct kfifo		r2tqueue;
 	void			*dd_data;
-	spinlock_t		pool2queue;
-	spinlock_t		queue2pool;
 };
 
 enum {
--- zfcpdump-kernel-4.4.orig/include/scsi/scsi_device.h
+++ zfcpdump-kernel-4.4/include/scsi/scsi_device.h
@@ -175,6 +175,7 @@ struct scsi_device {
 	unsigned no_dif:1;	/* T10 PI (DIF) should be disabled */
 	unsigned broken_fua:1;		/* Don't set FUA bit */
 	unsigned lun_in_cdb:1;		/* Store LUN bits in CDB[1] */
+	unsigned synchronous_alua:1;	/* Synchronous ALUA commands */
 
 	atomic_t disk_events_disable_depth; /* disable depth for disk events */
 
@@ -239,6 +240,7 @@ scmd_printk(const char *, const struct s
 enum scsi_target_state {
 	STARGET_CREATED = 1,
 	STARGET_RUNNING,
+	STARGET_REMOVE,
 	STARGET_DEL,
 };
 
@@ -414,6 +416,8 @@ static inline int scsi_execute_req(struc
 }
 extern void sdev_disable_disk_events(struct scsi_device *sdev);
 extern void sdev_enable_disk_events(struct scsi_device *sdev);
+extern int scsi_vpd_lun_id(struct scsi_device *, char *, size_t);
+extern int scsi_vpd_tpg_id(struct scsi_device *, int *);
 
 #ifdef CONFIG_PM
 extern int scsi_autopm_get_device(struct scsi_device *);
--- zfcpdump-kernel-4.4.orig/include/scsi/scsi_devinfo.h
+++ zfcpdump-kernel-4.4/include/scsi/scsi_devinfo.h
@@ -37,5 +37,6 @@
 #define BLIST_TRY_VPD_PAGES	0x10000000 /* Attempt to read VPD pages */
 #define BLIST_NO_RSOC		0x20000000 /* don't try to issue RSOC */
 #define BLIST_MAX_1024		0x40000000 /* maximum 1024 sector cdb length */
+#define BLIST_SYNC_ALUA		0x80000000 /* Synchronous ALUA commands */
 
 #endif
--- zfcpdump-kernel-4.4.orig/include/scsi/scsi_dh.h
+++ zfcpdump-kernel-4.4/include/scsi/scsi_dh.h
@@ -52,6 +52,7 @@ enum {
 	SCSI_DH_TIMED_OUT,
 	SCSI_DH_RES_TEMP_UNAVAIL,
 	SCSI_DH_DEV_OFFLINED,
+	SCSI_DH_NOMEM,
 	SCSI_DH_NOSYS,
 	SCSI_DH_DRIVER_MAX,
 };
--- /dev/null
+++ zfcpdump-kernel-4.4/include/scsi/viosrp.h
@@ -0,0 +1,212 @@
+/*****************************************************************************/
+/* srp.h -- SCSI RDMA Protocol definitions                                   */
+/*                                                                           */
+/* Written By: Colin Devilbis, IBM Corporation                               */
+/*                                                                           */
+/* Copyright (C) 2003 IBM Corporation                                        */
+/*                                                                           */
+/* This program is free software; you can redistribute it and/or modify      */
+/* it under the terms of the GNU General Public License as published by      */
+/* the Free Software Foundation; either version 2 of the License, or         */
+/* (at your option) any later version.                                       */
+/*                                                                           */
+/* This program is distributed in the hope that it will be useful,           */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of            */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the             */
+/* GNU General Public License for more details.                              */
+/*                                                                           */
+/* This file contains structures and definitions for IBM RPA (RS/6000        */
+/* platform architecture) implementation of the SRP (SCSI RDMA Protocol)     */
+/* standard.  SRP is used on IBM iSeries and pSeries platforms to send SCSI  */
+/* commands between logical partitions.                                      */
+/*                                                                           */
+/* SRP Information Units (IUs) are sent on a "Command/Response Queue" (CRQ)  */
+/* between partitions.  The definitions in this file are architected,        */
+/* and cannot be changed without breaking compatibility with other versions  */
+/* of Linux and other operating systems (AIX, OS/400) that talk this protocol*/
+/* between logical partitions                                                */
+/*****************************************************************************/
+#ifndef VIOSRP_H
+#define VIOSRP_H
+#include <scsi/srp.h>
+
+#define SRP_VERSION "16.a"
+#define SRP_MAX_IU_LEN	256
+#define SRP_MAX_LOC_LEN 32
+
+union srp_iu {
+	struct srp_login_req login_req;
+	struct srp_login_rsp login_rsp;
+	struct srp_login_rej login_rej;
+	struct srp_i_logout i_logout;
+	struct srp_t_logout t_logout;
+	struct srp_tsk_mgmt tsk_mgmt;
+	struct srp_cmd cmd;
+	struct srp_rsp rsp;
+	u8 reserved[SRP_MAX_IU_LEN];
+};
+
+enum viosrp_crq_formats {
+	VIOSRP_SRP_FORMAT = 0x01,
+	VIOSRP_MAD_FORMAT = 0x02,
+	VIOSRP_OS400_FORMAT = 0x03,
+	VIOSRP_AIX_FORMAT = 0x04,
+	VIOSRP_LINUX_FORMAT = 0x06,
+	VIOSRP_INLINE_FORMAT = 0x07
+};
+
+enum viosrp_crq_status {
+	VIOSRP_OK = 0x0,
+	VIOSRP_NONRECOVERABLE_ERR = 0x1,
+	VIOSRP_VIOLATES_MAX_XFER = 0x2,
+	VIOSRP_PARTNER_PANIC = 0x3,
+	VIOSRP_DEVICE_BUSY = 0x8,
+	VIOSRP_ADAPTER_FAIL = 0x10,
+	VIOSRP_OK2 = 0x99,
+};
+
+struct viosrp_crq {
+	u8 valid;		/* used by RPA */
+	u8 format;		/* SCSI vs out-of-band */
+	u8 reserved;
+	u8 status;		/* non-scsi failure? (e.g. DMA failure) */
+	__be16 timeout;		/* in seconds */
+	__be16 IU_length;		/* in bytes */
+	__be64 IU_data_ptr;	/* the TCE for transferring data */
+};
+
+/* MADs are Management requests above and beyond the IUs defined in the SRP
+ * standard.
+ */
+enum viosrp_mad_types {
+	VIOSRP_EMPTY_IU_TYPE = 0x01,
+	VIOSRP_ERROR_LOG_TYPE = 0x02,
+	VIOSRP_ADAPTER_INFO_TYPE = 0x03,
+	VIOSRP_HOST_CONFIG_TYPE = 0x04,
+	VIOSRP_CAPABILITIES_TYPE = 0x05,
+	VIOSRP_ENABLE_FAST_FAIL = 0x08,
+};
+
+enum viosrp_mad_status {
+	VIOSRP_MAD_SUCCESS = 0x00,
+	VIOSRP_MAD_NOT_SUPPORTED = 0xF1,
+	VIOSRP_MAD_FAILED = 0xF7,
+};
+
+enum viosrp_capability_type {
+	MIGRATION_CAPABILITIES = 0x01,
+	RESERVATION_CAPABILITIES = 0x02,
+};
+
+enum viosrp_capability_support {
+	SERVER_DOES_NOT_SUPPORTS_CAP = 0x0,
+	SERVER_SUPPORTS_CAP = 0x01,
+	SERVER_CAP_DATA = 0x02,
+};
+
+enum viosrp_reserve_type {
+	CLIENT_RESERVE_SCSI_2 = 0x01,
+};
+
+enum viosrp_capability_flag {
+	CLIENT_MIGRATED = 0x01,
+	CLIENT_RECONNECT = 0x02,
+	CAP_LIST_SUPPORTED = 0x04,
+	CAP_LIST_DATA = 0x08,
+};
+
+/*
+ * Common MAD header
+ */
+struct mad_common {
+	__be32 type;
+	__be16 status;
+	__be16 length;
+	__be64 tag;
+};
+
+/*
+ * All SRP (and MAD) requests normally flow from the
+ * client to the server.  There is no way for the server to send
+ * an asynchronous message back to the client.  The Empty IU is used
+ * to hang out a meaningless request to the server so that it can respond
+ * asynchrouously with something like a SCSI AER
+ */
+struct viosrp_empty_iu {
+	struct mad_common common;
+	__be64 buffer;
+	__be32 port;
+};
+
+struct viosrp_error_log {
+	struct mad_common common;
+	__be64 buffer;
+};
+
+struct viosrp_adapter_info {
+	struct mad_common common;
+	__be64 buffer;
+};
+
+struct viosrp_host_config {
+	struct mad_common common;
+	__be64 buffer;
+};
+
+struct viosrp_fast_fail {
+	struct mad_common common;
+};
+
+struct viosrp_capabilities {
+	struct mad_common common;
+	__be64 buffer;
+};
+
+struct mad_capability_common {
+	__be32 cap_type;
+	__be16 length;
+	__be16 server_support;
+};
+
+struct mad_reserve_cap {
+	struct mad_capability_common common;
+	__be32 type;
+};
+
+struct mad_migration_cap {
+	struct mad_capability_common common;
+	__be32 ecl;
+};
+
+struct capabilities {
+	__be32 flags;
+	char name[SRP_MAX_LOC_LEN];
+	char loc[SRP_MAX_LOC_LEN];
+	struct mad_migration_cap migration;
+	struct mad_reserve_cap reserve;
+};
+
+union mad_iu {
+	struct viosrp_empty_iu empty_iu;
+	struct viosrp_error_log error_log;
+	struct viosrp_adapter_info adapter_info;
+	struct viosrp_host_config host_config;
+	struct viosrp_fast_fail fast_fail;
+	struct viosrp_capabilities capabilities;
+};
+
+union viosrp_iu {
+	union srp_iu srp;
+	union mad_iu mad;
+};
+
+struct mad_adapter_info_data {
+	char srp_version[8];
+	char partition_name[96];
+	__be32 partition_number;
+	__be32 mad_version;
+	__be32 os_type;
+	__be32 port_max_txu[8];	/* per-port maximum transfer */
+};
+
+#endif
--- zfcpdump-kernel-4.4.orig/include/sound/hda_i915.h
+++ zfcpdump-kernel-4.4/include/sound/hda_i915.h
@@ -11,6 +11,7 @@ int snd_hdac_set_codec_wakeup(struct hda
 int snd_hdac_display_power(struct hdac_bus *bus, bool enable);
 int snd_hdac_get_display_clk(struct hdac_bus *bus);
 int snd_hdac_i915_init(struct hdac_bus *bus);
+int snd_hdac_i915_init_bpo(struct hdac_bus *bus);
 int snd_hdac_i915_exit(struct hdac_bus *bus);
 int snd_hdac_i915_register_notifier(const struct i915_audio_component_audio_ops *);
 #else
@@ -30,6 +31,10 @@ static inline int snd_hdac_i915_init(str
 {
 	return -ENODEV;
 }
+static inline int snd_hdac_i915_init_bpo(struct hdac_bus *bus)
+{
+	return -ENODEV;
+}
 static inline int snd_hdac_i915_exit(struct hdac_bus *bus)
 {
 	return 0;
--- zfcpdump-kernel-4.4.orig/include/sound/rawmidi.h
+++ zfcpdump-kernel-4.4/include/sound/rawmidi.h
@@ -167,6 +167,10 @@ int snd_rawmidi_transmit_peek(struct snd
 int snd_rawmidi_transmit_ack(struct snd_rawmidi_substream *substream, int count);
 int snd_rawmidi_transmit(struct snd_rawmidi_substream *substream,
 			 unsigned char *buffer, int count);
+int __snd_rawmidi_transmit_peek(struct snd_rawmidi_substream *substream,
+			      unsigned char *buffer, int count);
+int __snd_rawmidi_transmit_ack(struct snd_rawmidi_substream *substream,
+			       int count);
 
 /* main midi functions */
 
--- zfcpdump-kernel-4.4.orig/include/target/target_core_backend.h
+++ zfcpdump-kernel-4.4/include/target/target_core_backend.h
@@ -94,5 +94,8 @@ sense_reason_t passthrough_parse_cdb(str
 	sense_reason_t (*exec_cmd)(struct se_cmd *cmd));
 
 bool target_sense_desc_format(struct se_device *dev);
+sector_t target_to_linux_sector(struct se_device *dev, sector_t lb);
+bool target_configure_unmap_from_queue(struct se_dev_attrib *attrib,
+				       struct request_queue *q);
 
 #endif /* TARGET_CORE_BACKEND_H */
--- zfcpdump-kernel-4.4.orig/include/target/target_core_base.h
+++ zfcpdump-kernel-4.4/include/target/target_core_base.h
@@ -138,6 +138,9 @@ enum se_cmd_flags_table {
 	SCF_COMPARE_AND_WRITE		= 0x00080000,
 	SCF_COMPARE_AND_WRITE_POST	= 0x00100000,
 	SCF_PASSTHROUGH_PROT_SG_TO_MEM_NOALLOC = 0x00200000,
+	SCF_ACK_KREF			= 0x00400000,
+	SCF_USE_CPUID			= 0x00800000,
+	SCF_TASK_ATTR_SET		= 0x01000000,
 };
 
 /* struct se_dev_entry->lun_flags and struct se_lun->lun_access */
@@ -185,6 +188,7 @@ enum target_sc_flags_table {
 	TARGET_SCF_BIDI_OP		= 0x01,
 	TARGET_SCF_ACK_KREF		= 0x02,
 	TARGET_SCF_UNKNOWN_SIZE		= 0x04,
+	TARGET_SCF_USE_CPUID	= 0x08,
 };
 
 /* fabric independent task management function values */
@@ -490,6 +494,8 @@ struct se_cmd {
 #define CMD_T_DEV_ACTIVE	(1 << 7)
 #define CMD_T_REQUEST_STOP	(1 << 8)
 #define CMD_T_BUSY		(1 << 9)
+#define CMD_T_TAS		(1 << 10)
+#define CMD_T_FABRIC_STOP	(1 << 11)
 	spinlock_t		t_state_lock;
 	struct kref		cmd_kref;
 	struct completion	t_transport_stop_comp;
@@ -526,6 +532,7 @@ struct se_cmd {
 	unsigned int		t_prot_nents;
 	sense_reason_t		pi_err;
 	sector_t		bad_sector;
+	int			cpuid;
 };
 
 struct se_ua {
--- zfcpdump-kernel-4.4.orig/include/target/target_core_fabric.h
+++ zfcpdump-kernel-4.4/include/target/target_core_fabric.h
@@ -108,6 +108,12 @@ void target_unregister_template(const st
 int target_depend_item(struct config_item *item);
 void target_undepend_item(struct config_item *item);
 
+struct se_session *target_alloc_session(struct se_portal_group *,
+		unsigned int, unsigned int, enum target_prot_op prot_op,
+		const char *, void *,
+		int (*callback)(struct se_portal_group *,
+				struct se_session *, void *));
+
 struct se_session *transport_init_session(enum target_prot_op);
 int transport_alloc_session_tags(struct se_session *, unsigned int,
 		unsigned int);
@@ -163,7 +169,6 @@ int	core_tmr_alloc_req(struct se_cmd *,
 void	core_tmr_release_req(struct se_tmr_req *);
 int	transport_generic_handle_tmr(struct se_cmd *);
 void	transport_generic_request_failure(struct se_cmd *, sense_reason_t);
-void	__target_execute_cmd(struct se_cmd *);
 int	transport_lookup_tmr_lun(struct se_cmd *, u64);
 void	core_allocate_nexus_loss_ua(struct se_node_acl *acl);
 
--- /dev/null
+++ zfcpdump-kernel-4.4/include/trace/events/fs.h
@@ -0,0 +1,53 @@
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM fs
+
+#if !defined(_TRACE_FS_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_FS_H
+
+#include <linux/fs.h>
+#include <linux/tracepoint.h>
+
+TRACE_EVENT(do_sys_open,
+
+	TP_PROTO(const char *filename, int flags, int mode),
+
+	TP_ARGS(filename, flags, mode),
+
+	TP_STRUCT__entry(
+		__string(	filename, filename		)
+		__field(	int, flags			)
+		__field(	int, mode			)
+	),
+
+	TP_fast_assign(
+		__assign_str(filename, filename);
+		__entry->flags = flags;
+		__entry->mode = mode;
+	),
+
+	TP_printk("\"%s\" %x %o",
+		  __get_str(filename), __entry->flags, __entry->mode)
+);
+
+TRACE_EVENT(open_exec,
+
+	TP_PROTO(const char *filename),
+
+	TP_ARGS(filename),
+
+	TP_STRUCT__entry(
+		__string(	filename, filename		)
+	),
+
+	TP_fast_assign(
+		__assign_str(filename, filename);
+	),
+
+	TP_printk("\"%s\"",
+		  __get_str(filename))
+);
+
+#endif /* _TRACE_FS_H */
+
+/* This part must be outside protection */
+#include <trace/define_trace.h>
--- zfcpdump-kernel-4.4.orig/include/trace/events/power.h
+++ zfcpdump-kernel-4.4/include/trace/events/power.h
@@ -38,6 +38,28 @@ DEFINE_EVENT(cpu, cpu_idle,
 	TP_ARGS(state, cpu_id)
 );
 
+TRACE_EVENT(powernv_throttle,
+
+	TP_PROTO(int chip_id, const char *reason, int pmax),
+
+	TP_ARGS(chip_id, reason, pmax),
+
+	TP_STRUCT__entry(
+		__field(int, chip_id)
+		__string(reason, reason)
+		__field(int, pmax)
+	),
+
+	TP_fast_assign(
+		__entry->chip_id = chip_id;
+		__assign_str(reason, reason);
+		__entry->pmax = pmax;
+	),
+
+	TP_printk("Chip %d Pmax %d %s", __entry->chip_id,
+		  __entry->pmax, __get_str(reason))
+);
+
 TRACE_EVENT(pstate_sample,
 
 	TP_PROTO(u32 core_busy,
--- zfcpdump-kernel-4.4.orig/include/trace/events/sunrpc.h
+++ zfcpdump-kernel-4.4/include/trace/events/sunrpc.h
@@ -529,20 +529,27 @@ TRACE_EVENT(svc_xprt_do_enqueue,
 
 	TP_STRUCT__entry(
 		__field(struct svc_xprt *, xprt)
-		__field_struct(struct sockaddr_storage, ss)
 		__field(int, pid)
 		__field(unsigned long, flags)
+		__dynamic_array(unsigned char, addr, xprt != NULL ?
+			xprt->xpt_remotelen : 0)
 	),
 
 	TP_fast_assign(
 		__entry->xprt = xprt;
-		xprt ? memcpy(&__entry->ss, &xprt->xpt_remote, sizeof(__entry->ss)) : memset(&__entry->ss, 0, sizeof(__entry->ss));
 		__entry->pid = rqst? rqst->rq_task->pid : 0;
-		__entry->flags = xprt ? xprt->xpt_flags : 0;
+		if (xprt) {
+			memcpy(__get_dynamic_array(addr),
+				&xprt->xpt_remote,
+				xprt->xpt_remotelen);
+			__entry->flags = xprt->xpt_flags;
+		} else
+			__entry->flags = 0;
 	),
 
 	TP_printk("xprt=0x%p addr=%pIScp pid=%d flags=%s", __entry->xprt,
-		(struct sockaddr *)&__entry->ss,
+		__get_dynamic_array_len(addr) != 0 ?
+			(struct sockaddr *)__get_dynamic_array(addr) : NULL,
 		__entry->pid, show_svc_xprt_flags(__entry->flags))
 );
 
@@ -553,18 +560,25 @@ TRACE_EVENT(svc_xprt_dequeue,
 
 	TP_STRUCT__entry(
 		__field(struct svc_xprt *, xprt)
-		__field_struct(struct sockaddr_storage, ss)
 		__field(unsigned long, flags)
+		__dynamic_array(unsigned char, addr, xprt != NULL ?
+			xprt->xpt_remotelen : 0)
 	),
 
 	TP_fast_assign(
-		__entry->xprt = xprt,
-		xprt ? memcpy(&__entry->ss, &xprt->xpt_remote, sizeof(__entry->ss)) : memset(&__entry->ss, 0, sizeof(__entry->ss));
-		__entry->flags = xprt ? xprt->xpt_flags : 0;
+		__entry->xprt = xprt;
+		if (xprt) {
+			memcpy(__get_dynamic_array(addr),
+					&xprt->xpt_remote,
+					xprt->xpt_remotelen);
+			__entry->flags = xprt->xpt_flags;
+		} else
+			__entry->flags = 0;
 	),
 
 	TP_printk("xprt=0x%p addr=%pIScp flags=%s", __entry->xprt,
-		(struct sockaddr *)&__entry->ss,
+		__get_dynamic_array_len(addr) != 0 ?
+			(struct sockaddr *)__get_dynamic_array(addr) : NULL,
 		show_svc_xprt_flags(__entry->flags))
 );
 
@@ -592,19 +606,26 @@ TRACE_EVENT(svc_handle_xprt,
 	TP_STRUCT__entry(
 		__field(struct svc_xprt *, xprt)
 		__field(int, len)
-		__field_struct(struct sockaddr_storage, ss)
 		__field(unsigned long, flags)
+		__dynamic_array(unsigned char, addr, xprt != NULL ?
+			xprt->xpt_remotelen : 0)
 	),
 
 	TP_fast_assign(
 		__entry->xprt = xprt;
-		xprt ? memcpy(&__entry->ss, &xprt->xpt_remote, sizeof(__entry->ss)) : memset(&__entry->ss, 0, sizeof(__entry->ss));
 		__entry->len = len;
-		__entry->flags = xprt ? xprt->xpt_flags : 0;
+		if (xprt) {
+			memcpy(__get_dynamic_array(addr),
+					&xprt->xpt_remote,
+					xprt->xpt_remotelen);
+			__entry->flags = xprt->xpt_flags;
+		} else
+			__entry->flags = 0;
 	),
 
 	TP_printk("xprt=0x%p addr=%pIScp len=%d flags=%s", __entry->xprt,
-		(struct sockaddr *)&__entry->ss,
+		__get_dynamic_array_len(addr) != 0 ?
+			(struct sockaddr *)__get_dynamic_array(addr) : NULL,
 		__entry->len, show_svc_xprt_flags(__entry->flags))
 );
 #endif /* _TRACE_SUNRPC_H */
--- zfcpdump-kernel-4.4.orig/include/uapi/drm/drm_mode.h
+++ zfcpdump-kernel-4.4/include/uapi/drm/drm_mode.h
@@ -487,6 +487,21 @@ struct drm_mode_crtc_lut {
 	__u64 blue;
 };
 
+struct drm_color_ctm {
+	/* Conversion matrix in S31.32 format. */
+	__s64 matrix[9];
+};
+
+struct drm_color_lut {
+	/*
+	 * Data is U0.16 fixed point format.
+	 */
+	__u16 red;
+	__u16 green;
+	__u16 blue;
+	__u16 reserved;
+};
+
 #define DRM_MODE_PAGE_FLIP_EVENT 0x01
 #define DRM_MODE_PAGE_FLIP_ASYNC 0x02
 #define DRM_MODE_PAGE_FLIP_FLAGS (DRM_MODE_PAGE_FLIP_EVENT|DRM_MODE_PAGE_FLIP_ASYNC)
--- zfcpdump-kernel-4.4.orig/include/uapi/drm/i915_drm.h
+++ zfcpdump-kernel-4.4/include/uapi/drm/i915_drm.h
@@ -356,6 +356,7 @@ typedef struct drm_i915_irq_wait {
 #define I915_PARAM_EU_TOTAL		 34
 #define I915_PARAM_HAS_GPU_RESET	 35
 #define I915_PARAM_HAS_RESOURCE_STREAMER 36
+#define I915_PARAM_HAS_EXEC_SOFTPIN     37
 
 typedef struct drm_i915_getparam {
 	__s32 param;
@@ -682,8 +683,12 @@ struct drm_i915_gem_exec_object2 {
 	__u64 alignment;
 
 	/**
-	 * Returned value of the updated offset of the object, for future
-	 * presumed_offset writes.
+	 * When the EXEC_OBJECT_PINNED flag is specified this is populated by
+	 * the user with the GTT offset at which this object will be pinned.
+	 * When the I915_EXEC_NO_RELOC flag is specified this must contain the
+	 * presumed_offset of the object.
+	 * During execbuffer2 the kernel populates it with the value of the
+	 * current GTT offset of the object, for future presumed_offset writes.
 	 */
 	__u64 offset;
 
@@ -691,7 +696,8 @@ struct drm_i915_gem_exec_object2 {
 #define EXEC_OBJECT_NEEDS_GTT	(1<<1)
 #define EXEC_OBJECT_WRITE	(1<<2)
 #define EXEC_OBJECT_SUPPORTS_48B_ADDRESS (1<<3)
-#define __EXEC_OBJECT_UNKNOWN_FLAGS -(EXEC_OBJECT_SUPPORTS_48B_ADDRESS<<1)
+#define EXEC_OBJECT_PINNED     (1<<4)
+#define __EXEC_OBJECT_UNKNOWN_FLAGS -(EXEC_OBJECT_PINNED<<1)
 	__u64 flags;
 
 	__u64 rsvd1;
@@ -766,10 +772,12 @@ struct drm_i915_gem_execbuffer2 {
 #define I915_EXEC_HANDLE_LUT		(1<<12)
 
 /** Used for switching BSD rings on the platforms with two BSD rings */
-#define I915_EXEC_BSD_MASK		(3<<13)
-#define I915_EXEC_BSD_DEFAULT		(0<<13) /* default ping-pong mode */
-#define I915_EXEC_BSD_RING1		(1<<13)
-#define I915_EXEC_BSD_RING2		(2<<13)
+#define I915_EXEC_BSD_SHIFT     (13)
+#define I915_EXEC_BSD_MASK	(3 << I915_EXEC_BSD_SHIFT)
+/* default ping-pong mode */
+#define I915_EXEC_BSD_DEFAULT	(0 << I915_EXEC_BSD_SHIFT)
+#define I915_EXEC_BSD_RING1	(1 << I915_EXEC_BSD_SHIFT)
+#define I915_EXEC_BSD_RING2	(2 << I915_EXEC_BSD_SHIFT)
 
 /** Tell the kernel that the batchbuffer is processed by
  *  the resource streamer.
@@ -1125,8 +1133,9 @@ struct drm_i915_gem_context_param {
 	__u32 ctx_id;
 	__u32 size;
 	__u64 param;
-#define I915_CONTEXT_PARAM_BAN_PERIOD 0x1
-#define I915_CONTEXT_PARAM_NO_ZEROMAP 0x2
+#define I915_CONTEXT_PARAM_BAN_PERIOD	0x1
+#define I915_CONTEXT_PARAM_NO_ZEROMAP	0x2
+#define I915_CONTEXT_PARAM_GTT_SIZE	0x3
 	__u64 value;
 };
 
--- zfcpdump-kernel-4.4.orig/include/uapi/linux/Kbuild
+++ zfcpdump-kernel-4.4/include/uapi/linux/Kbuild
@@ -59,6 +59,7 @@ header-y += atmsvc.h
 header-y += atm_tcp.h
 header-y += atm_zatm.h
 header-y += audit.h
+header-y += aufs_type.h
 header-y += auto_fs4.h
 header-y += auto_fs.h
 header-y += auxvec.h
@@ -307,7 +308,7 @@ header-y += nfs_mount.h
 header-y += nl80211.h
 header-y += n_r3964.h
 header-y += nubus.h
-header-y += nvme.h
+header-y += nvme_ioctl.h
 header-y += nvram.h
 header-y += omap3isp.h
 header-y += omapfb.h
--- /dev/null
+++ zfcpdump-kernel-4.4/include/uapi/linux/aufs_type.h
@@ -0,0 +1,419 @@
+/*
+ * Copyright (C) 2005-2015 Junjiro R. Okajima
+ *
+ * This program, aufs is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __AUFS_TYPE_H__
+#define __AUFS_TYPE_H__
+
+#define AUFS_NAME	"aufs"
+
+#ifdef __KERNEL__
+/*
+ * define it before including all other headers.
+ * sched.h may use pr_* macros before defining "current", so define the
+ * no-current version first, and re-define later.
+ */
+#define pr_fmt(fmt)	AUFS_NAME " %s:%d: " fmt, __func__, __LINE__
+#include <linux/sched.h>
+#undef pr_fmt
+#define pr_fmt(fmt) \
+		AUFS_NAME " %s:%d:%.*s[%d]: " fmt, __func__, __LINE__, \
+		(int)sizeof(current->comm), current->comm, current->pid
+#else
+#include <stdint.h>
+#include <sys/types.h>
+#endif /* __KERNEL__ */
+
+#include <linux/limits.h>
+
+#define AUFS_VERSION	"4.x-rcN-20160111"
+
+/* todo? move this to linux-2.6.19/include/magic.h */
+#define AUFS_SUPER_MAGIC	('a' << 24 | 'u' << 16 | 'f' << 8 | 's')
+
+/* ---------------------------------------------------------------------- */
+
+#ifdef CONFIG_AUFS_BRANCH_MAX_127
+typedef int8_t aufs_bindex_t;
+#define AUFS_BRANCH_MAX 127
+#else
+typedef int16_t aufs_bindex_t;
+#ifdef CONFIG_AUFS_BRANCH_MAX_511
+#define AUFS_BRANCH_MAX 511
+#elif defined(CONFIG_AUFS_BRANCH_MAX_1023)
+#define AUFS_BRANCH_MAX 1023
+#elif defined(CONFIG_AUFS_BRANCH_MAX_32767)
+#define AUFS_BRANCH_MAX 32767
+#endif
+#endif
+
+#ifdef __KERNEL__
+#ifndef AUFS_BRANCH_MAX
+#error unknown CONFIG_AUFS_BRANCH_MAX value
+#endif
+#endif /* __KERNEL__ */
+
+/* ---------------------------------------------------------------------- */
+
+#define AUFS_FSTYPE		AUFS_NAME
+
+#define AUFS_ROOT_INO		2
+#define AUFS_FIRST_INO		11
+
+#define AUFS_WH_PFX		".wh."
+#define AUFS_WH_PFX_LEN		((int)sizeof(AUFS_WH_PFX) - 1)
+#define AUFS_WH_TMP_LEN		4
+/* a limit for rmdir/rename a dir and copyup */
+#define AUFS_MAX_NAMELEN	(NAME_MAX \
+				- AUFS_WH_PFX_LEN * 2	/* doubly whiteouted */\
+				- 1			/* dot */\
+				- AUFS_WH_TMP_LEN)	/* hex */
+#define AUFS_XINO_FNAME		"." AUFS_NAME ".xino"
+#define AUFS_XINO_DEFPATH	"/tmp/" AUFS_XINO_FNAME
+#define AUFS_XINO_DEF_SEC	30 /* seconds */
+#define AUFS_XINO_DEF_TRUNC	45 /* percentage */
+#define AUFS_DIRWH_DEF		3
+#define AUFS_RDCACHE_DEF	10 /* seconds */
+#define AUFS_RDCACHE_MAX	3600 /* seconds */
+#define AUFS_RDBLK_DEF		512 /* bytes */
+#define AUFS_RDHASH_DEF		32
+#define AUFS_WKQ_NAME		AUFS_NAME "d"
+#define AUFS_MFS_DEF_SEC	30 /* seconds */
+#define AUFS_MFS_MAX_SEC	3600 /* seconds */
+#define AUFS_FHSM_CACHE_DEF_SEC	30 /* seconds */
+#define AUFS_PLINK_WARN		50 /* number of plinks in a single bucket */
+
+/* pseudo-link maintenace under /proc */
+#define AUFS_PLINK_MAINT_NAME	"plink_maint"
+#define AUFS_PLINK_MAINT_DIR	"fs/" AUFS_NAME
+#define AUFS_PLINK_MAINT_PATH	AUFS_PLINK_MAINT_DIR "/" AUFS_PLINK_MAINT_NAME
+
+#define AUFS_DIROPQ_NAME	AUFS_WH_PFX ".opq" /* whiteouted doubly */
+#define AUFS_WH_DIROPQ		AUFS_WH_PFX AUFS_DIROPQ_NAME
+
+#define AUFS_BASE_NAME		AUFS_WH_PFX AUFS_NAME
+#define AUFS_PLINKDIR_NAME	AUFS_WH_PFX "plnk"
+#define AUFS_ORPHDIR_NAME	AUFS_WH_PFX "orph"
+
+/* doubly whiteouted */
+#define AUFS_WH_BASE		AUFS_WH_PFX AUFS_BASE_NAME
+#define AUFS_WH_PLINKDIR	AUFS_WH_PFX AUFS_PLINKDIR_NAME
+#define AUFS_WH_ORPHDIR		AUFS_WH_PFX AUFS_ORPHDIR_NAME
+
+/* branch permissions and attributes */
+#define AUFS_BRPERM_RW		"rw"
+#define AUFS_BRPERM_RO		"ro"
+#define AUFS_BRPERM_RR		"rr"
+#define AUFS_BRATTR_COO_REG	"coo_reg"
+#define AUFS_BRATTR_COO_ALL	"coo_all"
+#define AUFS_BRATTR_FHSM	"fhsm"
+#define AUFS_BRATTR_UNPIN	"unpin"
+#define AUFS_BRATTR_ICEX	"icex"
+#define AUFS_BRATTR_ICEX_SEC	"icexsec"
+#define AUFS_BRATTR_ICEX_SYS	"icexsys"
+#define AUFS_BRATTR_ICEX_TR	"icextr"
+#define AUFS_BRATTR_ICEX_USR	"icexusr"
+#define AUFS_BRATTR_ICEX_OTH	"icexoth"
+#define AUFS_BRRATTR_WH		"wh"
+#define AUFS_BRWATTR_NLWH	"nolwh"
+#define AUFS_BRWATTR_MOO	"moo"
+
+#define AuBrPerm_RW		1		/* writable, hardlinkable wh */
+#define AuBrPerm_RO		(1 << 1)	/* readonly */
+#define AuBrPerm_RR		(1 << 2)	/* natively readonly */
+#define AuBrPerm_Mask		(AuBrPerm_RW | AuBrPerm_RO | AuBrPerm_RR)
+
+#define AuBrAttr_COO_REG	(1 << 3)	/* copy-up on open */
+#define AuBrAttr_COO_ALL	(1 << 4)
+#define AuBrAttr_COO_Mask	(AuBrAttr_COO_REG | AuBrAttr_COO_ALL)
+
+#define AuBrAttr_FHSM		(1 << 5)	/* file-based hsm */
+#define AuBrAttr_UNPIN		(1 << 6)	/* rename-able top dir of
+						   branch. meaningless since
+						   linux-3.18-rc1 */
+
+/* ignore error in copying XATTR */
+#define AuBrAttr_ICEX_SEC	(1 << 7)
+#define AuBrAttr_ICEX_SYS	(1 << 8)
+#define AuBrAttr_ICEX_TR	(1 << 9)
+#define AuBrAttr_ICEX_USR	(1 << 10)
+#define AuBrAttr_ICEX_OTH	(1 << 11)
+#define AuBrAttr_ICEX		(AuBrAttr_ICEX_SEC	\
+				 | AuBrAttr_ICEX_SYS	\
+				 | AuBrAttr_ICEX_TR	\
+				 | AuBrAttr_ICEX_USR	\
+				 | AuBrAttr_ICEX_OTH)
+
+#define AuBrRAttr_WH		(1 << 12)	/* whiteout-able */
+#define AuBrRAttr_Mask		AuBrRAttr_WH
+
+#define AuBrWAttr_NoLinkWH	(1 << 13)	/* un-hardlinkable whiteouts */
+#define AuBrWAttr_MOO		(1 << 14)	/* move-up on open */
+#define AuBrWAttr_Mask		(AuBrWAttr_NoLinkWH | AuBrWAttr_MOO)
+
+#define AuBrAttr_CMOO_Mask	(AuBrAttr_COO_Mask | AuBrWAttr_MOO)
+
+/* #warning test userspace */
+#ifdef __KERNEL__
+#ifndef CONFIG_AUFS_FHSM
+#undef AuBrAttr_FHSM
+#define AuBrAttr_FHSM		0
+#endif
+#ifndef CONFIG_AUFS_XATTR
+#undef	AuBrAttr_ICEX
+#define AuBrAttr_ICEX		0
+#undef	AuBrAttr_ICEX_SEC
+#define AuBrAttr_ICEX_SEC	0
+#undef	AuBrAttr_ICEX_SYS
+#define AuBrAttr_ICEX_SYS	0
+#undef	AuBrAttr_ICEX_TR
+#define AuBrAttr_ICEX_TR	0
+#undef	AuBrAttr_ICEX_USR
+#define AuBrAttr_ICEX_USR	0
+#undef	AuBrAttr_ICEX_OTH
+#define AuBrAttr_ICEX_OTH	0
+#endif
+#endif
+
+/* the longest combination */
+/* AUFS_BRATTR_ICEX and AUFS_BRATTR_ICEX_TR don't affect here */
+#define AuBrPermStrSz	sizeof(AUFS_BRPERM_RW			\
+			       "+" AUFS_BRATTR_COO_REG		\
+			       "+" AUFS_BRATTR_FHSM		\
+			       "+" AUFS_BRATTR_UNPIN		\
+			       "+" AUFS_BRATTR_ICEX_SEC		\
+			       "+" AUFS_BRATTR_ICEX_SYS		\
+			       "+" AUFS_BRATTR_ICEX_USR		\
+			       "+" AUFS_BRATTR_ICEX_OTH		\
+			       "+" AUFS_BRWATTR_NLWH)
+
+typedef struct {
+	char a[AuBrPermStrSz];
+} au_br_perm_str_t;
+
+static inline int au_br_writable(int brperm)
+{
+	return brperm & AuBrPerm_RW;
+}
+
+static inline int au_br_whable(int brperm)
+{
+	return brperm & (AuBrPerm_RW | AuBrRAttr_WH);
+}
+
+static inline int au_br_wh_linkable(int brperm)
+{
+	return !(brperm & AuBrWAttr_NoLinkWH);
+}
+
+static inline int au_br_cmoo(int brperm)
+{
+	return brperm & AuBrAttr_CMOO_Mask;
+}
+
+static inline int au_br_fhsm(int brperm)
+{
+	return brperm & AuBrAttr_FHSM;
+}
+
+/* ---------------------------------------------------------------------- */
+
+/* ioctl */
+enum {
+	/* readdir in userspace */
+	AuCtl_RDU,
+	AuCtl_RDU_INO,
+
+	AuCtl_WBR_FD,	/* pathconf wrapper */
+	AuCtl_IBUSY,	/* busy inode */
+	AuCtl_MVDOWN,	/* move-down */
+	AuCtl_BR,	/* info about branches */
+	AuCtl_FHSM_FD	/* connection for fhsm */
+};
+
+/* borrowed from linux/include/linux/kernel.h */
+#ifndef ALIGN
+#define ALIGN(x, a)		__ALIGN_MASK(x, (typeof(x))(a)-1)
+#define __ALIGN_MASK(x, mask)	(((x)+(mask))&~(mask))
+#endif
+
+/* borrowed from linux/include/linux/compiler-gcc3.h */
+#ifndef __aligned
+#define __aligned(x)			__attribute__((aligned(x)))
+#endif
+
+#ifdef __KERNEL__
+#ifndef __packed
+#define __packed			__attribute__((packed))
+#endif
+#endif
+
+struct au_rdu_cookie {
+	uint64_t	h_pos;
+	int16_t		bindex;
+	uint8_t		flags;
+	uint8_t		pad;
+	uint32_t	generation;
+} __aligned(8);
+
+struct au_rdu_ent {
+	uint64_t	ino;
+	int16_t		bindex;
+	uint8_t		type;
+	uint8_t		nlen;
+	uint8_t		wh;
+	char		name[0];
+} __aligned(8);
+
+static inline int au_rdu_len(int nlen)
+{
+	/* include the terminating NULL */
+	return ALIGN(sizeof(struct au_rdu_ent) + nlen + 1,
+		     sizeof(uint64_t));
+}
+
+union au_rdu_ent_ul {
+	struct au_rdu_ent __user	*e;
+	uint64_t			ul;
+};
+
+enum {
+	AufsCtlRduV_SZ,
+	AufsCtlRduV_End
+};
+
+struct aufs_rdu {
+	/* input */
+	union {
+		uint64_t	sz;	/* AuCtl_RDU */
+		uint64_t	nent;	/* AuCtl_RDU_INO */
+	};
+	union au_rdu_ent_ul	ent;
+	uint16_t		verify[AufsCtlRduV_End];
+
+	/* input/output */
+	uint32_t		blk;
+
+	/* output */
+	union au_rdu_ent_ul	tail;
+	/* number of entries which were added in a single call */
+	uint64_t		rent;
+	uint8_t			full;
+	uint8_t			shwh;
+
+	struct au_rdu_cookie	cookie;
+} __aligned(8);
+
+/* ---------------------------------------------------------------------- */
+
+struct aufs_wbr_fd {
+	uint32_t	oflags;
+	int16_t		brid;
+} __aligned(8);
+
+/* ---------------------------------------------------------------------- */
+
+struct aufs_ibusy {
+	uint64_t	ino, h_ino;
+	int16_t		bindex;
+} __aligned(8);
+
+/* ---------------------------------------------------------------------- */
+
+/* error code for move-down */
+/* the actual message strings are implemented in aufs-util.git */
+enum {
+	EAU_MVDOWN_OPAQUE = 1,
+	EAU_MVDOWN_WHITEOUT,
+	EAU_MVDOWN_UPPER,
+	EAU_MVDOWN_BOTTOM,
+	EAU_MVDOWN_NOUPPER,
+	EAU_MVDOWN_NOLOWERBR,
+	EAU_Last
+};
+
+/* flags for move-down */
+#define AUFS_MVDOWN_DMSG	1
+#define AUFS_MVDOWN_OWLOWER	(1 << 1)	/* overwrite lower */
+#define AUFS_MVDOWN_KUPPER	(1 << 2)	/* keep upper */
+#define AUFS_MVDOWN_ROLOWER	(1 << 3)	/* do even if lower is RO */
+#define AUFS_MVDOWN_ROLOWER_R	(1 << 4)	/* did on lower RO */
+#define AUFS_MVDOWN_ROUPPER	(1 << 5)	/* do even if upper is RO */
+#define AUFS_MVDOWN_ROUPPER_R	(1 << 6)	/* did on upper RO */
+#define AUFS_MVDOWN_BRID_UPPER	(1 << 7)	/* upper brid */
+#define AUFS_MVDOWN_BRID_LOWER	(1 << 8)	/* lower brid */
+#define AUFS_MVDOWN_FHSM_LOWER	(1 << 9)	/* find fhsm attr for lower */
+#define AUFS_MVDOWN_STFS	(1 << 10)	/* req. stfs */
+#define AUFS_MVDOWN_STFS_FAILED	(1 << 11)	/* output: stfs is unusable */
+#define AUFS_MVDOWN_BOTTOM	(1 << 12)	/* output: no more lowers */
+
+/* index for move-down */
+enum {
+	AUFS_MVDOWN_UPPER,
+	AUFS_MVDOWN_LOWER,
+	AUFS_MVDOWN_NARRAY
+};
+
+/*
+ * additional info of move-down
+ * number of free blocks and inodes.
+ * subset of struct kstatfs, but smaller and always 64bit.
+ */
+struct aufs_stfs {
+	uint64_t	f_blocks;
+	uint64_t	f_bavail;
+	uint64_t	f_files;
+	uint64_t	f_ffree;
+};
+
+struct aufs_stbr {
+	int16_t			brid;	/* optional input */
+	int16_t			bindex;	/* output */
+	struct aufs_stfs	stfs;	/* output when AUFS_MVDOWN_STFS set */
+} __aligned(8);
+
+struct aufs_mvdown {
+	uint32_t		flags;			/* input/output */
+	struct aufs_stbr	stbr[AUFS_MVDOWN_NARRAY]; /* input/output */
+	int8_t			au_errno;		/* output */
+} __aligned(8);
+
+/* ---------------------------------------------------------------------- */
+
+union aufs_brinfo {
+	/* PATH_MAX may differ between kernel-space and user-space */
+	char	_spacer[4096];
+	struct {
+		int16_t	id;
+		int	perm;
+		char	path[0];
+	};
+} __aligned(8);
+
+/* ---------------------------------------------------------------------- */
+
+#define AuCtlType		'A'
+#define AUFS_CTL_RDU		_IOWR(AuCtlType, AuCtl_RDU, struct aufs_rdu)
+#define AUFS_CTL_RDU_INO	_IOWR(AuCtlType, AuCtl_RDU_INO, struct aufs_rdu)
+#define AUFS_CTL_WBR_FD		_IOW(AuCtlType, AuCtl_WBR_FD, \
+				     struct aufs_wbr_fd)
+#define AUFS_CTL_IBUSY		_IOWR(AuCtlType, AuCtl_IBUSY, struct aufs_ibusy)
+#define AUFS_CTL_MVDOWN		_IOWR(AuCtlType, AuCtl_MVDOWN, \
+				      struct aufs_mvdown)
+#define AUFS_CTL_BRINFO		_IOW(AuCtlType, AuCtl_BR, union aufs_brinfo)
+#define AUFS_CTL_FHSM_FD	_IOW(AuCtlType, AuCtl_FHSM_FD, int)
+
+#endif /* __AUFS_TYPE_H__ */
--- zfcpdump-kernel-4.4.orig/include/uapi/linux/ethtool.h
+++ zfcpdump-kernel-4.4/include/uapi/linux/ethtool.h
@@ -16,12 +16,17 @@
 #include <linux/types.h>
 #include <linux/if_ether.h>
 
+#ifndef __KERNEL__
+#include <limits.h> /* for INT_MAX */
+#endif
+
 /* All structures exposed to userland should be defined such that they
  * have the same layout for 32-bit and 64-bit userland.
  */
 
 /**
- * struct ethtool_cmd - link control and status
+ * struct ethtool_cmd - DEPRECATED, link control and status
+ * This structure is DEPRECATED, please use struct ethtool_link_settings.
  * @cmd: Command number = %ETHTOOL_GSET or %ETHTOOL_SSET
  * @supported: Bitmask of %SUPPORTED_* flags for the link modes,
  *	physical connectors and other link features for which the
@@ -1146,8 +1151,12 @@ enum ethtool_sfeatures_retval_bits {
 
 
 /* CMDs currently supported */
-#define ETHTOOL_GSET		0x00000001 /* Get settings. */
-#define ETHTOOL_SSET		0x00000002 /* Set settings. */
+#define ETHTOOL_GSET		0x00000001 /* DEPRECATED, Get settings.
+					    * Please use ETHTOOL_GLINKSETTINGS
+					    */
+#define ETHTOOL_SSET		0x00000002 /* DEPRECATED, Set settings.
+					    * Please use ETHTOOL_SLINKSETTINGS
+					    */
 #define ETHTOOL_GDRVINFO	0x00000003 /* Get driver info. */
 #define ETHTOOL_GREGS		0x00000004 /* Get NIC registers. */
 #define ETHTOOL_GWOL		0x00000005 /* Get wake-on-lan options. */
@@ -1226,73 +1235,139 @@ enum ethtool_sfeatures_retval_bits {
 #define ETHTOOL_GTUNABLE	0x00000048 /* Get tunable configuration */
 #define ETHTOOL_STUNABLE	0x00000049 /* Set tunable configuration */
 
+#define ETHTOOL_GLINKSETTINGS	0x0000004c /* Get ethtool_link_settings */
+#define ETHTOOL_SLINKSETTINGS	0x0000004d /* Set ethtool_link_settings */
+
+
 /* compatibility with older code */
 #define SPARC_ETH_GSET		ETHTOOL_GSET
 #define SPARC_ETH_SSET		ETHTOOL_SSET
 
-#define SUPPORTED_10baseT_Half		(1 << 0)
-#define SUPPORTED_10baseT_Full		(1 << 1)
-#define SUPPORTED_100baseT_Half		(1 << 2)
-#define SUPPORTED_100baseT_Full		(1 << 3)
-#define SUPPORTED_1000baseT_Half	(1 << 4)
-#define SUPPORTED_1000baseT_Full	(1 << 5)
-#define SUPPORTED_Autoneg		(1 << 6)
-#define SUPPORTED_TP			(1 << 7)
-#define SUPPORTED_AUI			(1 << 8)
-#define SUPPORTED_MII			(1 << 9)
-#define SUPPORTED_FIBRE			(1 << 10)
-#define SUPPORTED_BNC			(1 << 11)
-#define SUPPORTED_10000baseT_Full	(1 << 12)
-#define SUPPORTED_Pause			(1 << 13)
-#define SUPPORTED_Asym_Pause		(1 << 14)
-#define SUPPORTED_2500baseX_Full	(1 << 15)
-#define SUPPORTED_Backplane		(1 << 16)
-#define SUPPORTED_1000baseKX_Full	(1 << 17)
-#define SUPPORTED_10000baseKX4_Full	(1 << 18)
-#define SUPPORTED_10000baseKR_Full	(1 << 19)
-#define SUPPORTED_10000baseR_FEC	(1 << 20)
-#define SUPPORTED_20000baseMLD2_Full	(1 << 21)
-#define SUPPORTED_20000baseKR2_Full	(1 << 22)
-#define SUPPORTED_40000baseKR4_Full	(1 << 23)
-#define SUPPORTED_40000baseCR4_Full	(1 << 24)
-#define SUPPORTED_40000baseSR4_Full	(1 << 25)
-#define SUPPORTED_40000baseLR4_Full	(1 << 26)
-#define SUPPORTED_56000baseKR4_Full	(1 << 27)
-#define SUPPORTED_56000baseCR4_Full	(1 << 28)
-#define SUPPORTED_56000baseSR4_Full	(1 << 29)
-#define SUPPORTED_56000baseLR4_Full	(1 << 30)
-
-#define ADVERTISED_10baseT_Half		(1 << 0)
-#define ADVERTISED_10baseT_Full		(1 << 1)
-#define ADVERTISED_100baseT_Half	(1 << 2)
-#define ADVERTISED_100baseT_Full	(1 << 3)
-#define ADVERTISED_1000baseT_Half	(1 << 4)
-#define ADVERTISED_1000baseT_Full	(1 << 5)
-#define ADVERTISED_Autoneg		(1 << 6)
-#define ADVERTISED_TP			(1 << 7)
-#define ADVERTISED_AUI			(1 << 8)
-#define ADVERTISED_MII			(1 << 9)
-#define ADVERTISED_FIBRE		(1 << 10)
-#define ADVERTISED_BNC			(1 << 11)
-#define ADVERTISED_10000baseT_Full	(1 << 12)
-#define ADVERTISED_Pause		(1 << 13)
-#define ADVERTISED_Asym_Pause		(1 << 14)
-#define ADVERTISED_2500baseX_Full	(1 << 15)
-#define ADVERTISED_Backplane		(1 << 16)
-#define ADVERTISED_1000baseKX_Full	(1 << 17)
-#define ADVERTISED_10000baseKX4_Full	(1 << 18)
-#define ADVERTISED_10000baseKR_Full	(1 << 19)
-#define ADVERTISED_10000baseR_FEC	(1 << 20)
-#define ADVERTISED_20000baseMLD2_Full	(1 << 21)
-#define ADVERTISED_20000baseKR2_Full	(1 << 22)
-#define ADVERTISED_40000baseKR4_Full	(1 << 23)
-#define ADVERTISED_40000baseCR4_Full	(1 << 24)
-#define ADVERTISED_40000baseSR4_Full	(1 << 25)
-#define ADVERTISED_40000baseLR4_Full	(1 << 26)
-#define ADVERTISED_56000baseKR4_Full	(1 << 27)
-#define ADVERTISED_56000baseCR4_Full	(1 << 28)
-#define ADVERTISED_56000baseSR4_Full	(1 << 29)
-#define ADVERTISED_56000baseLR4_Full	(1 << 30)
+/* Link mode bit indices */
+enum ethtool_link_mode_bit_indices {
+	ETHTOOL_LINK_MODE_10baseT_Half_BIT	= 0,
+	ETHTOOL_LINK_MODE_10baseT_Full_BIT	= 1,
+	ETHTOOL_LINK_MODE_100baseT_Half_BIT	= 2,
+	ETHTOOL_LINK_MODE_100baseT_Full_BIT	= 3,
+	ETHTOOL_LINK_MODE_1000baseT_Half_BIT	= 4,
+	ETHTOOL_LINK_MODE_1000baseT_Full_BIT	= 5,
+	ETHTOOL_LINK_MODE_Autoneg_BIT		= 6,
+	ETHTOOL_LINK_MODE_TP_BIT		= 7,
+	ETHTOOL_LINK_MODE_AUI_BIT		= 8,
+	ETHTOOL_LINK_MODE_MII_BIT		= 9,
+	ETHTOOL_LINK_MODE_FIBRE_BIT		= 10,
+	ETHTOOL_LINK_MODE_BNC_BIT		= 11,
+	ETHTOOL_LINK_MODE_10000baseT_Full_BIT	= 12,
+	ETHTOOL_LINK_MODE_Pause_BIT		= 13,
+	ETHTOOL_LINK_MODE_Asym_Pause_BIT	= 14,
+	ETHTOOL_LINK_MODE_2500baseX_Full_BIT	= 15,
+	ETHTOOL_LINK_MODE_Backplane_BIT		= 16,
+	ETHTOOL_LINK_MODE_1000baseKX_Full_BIT	= 17,
+	ETHTOOL_LINK_MODE_10000baseKX4_Full_BIT	= 18,
+	ETHTOOL_LINK_MODE_10000baseKR_Full_BIT	= 19,
+	ETHTOOL_LINK_MODE_10000baseR_FEC_BIT	= 20,
+	ETHTOOL_LINK_MODE_20000baseMLD2_Full_BIT = 21,
+	ETHTOOL_LINK_MODE_20000baseKR2_Full_BIT	= 22,
+	ETHTOOL_LINK_MODE_40000baseKR4_Full_BIT	= 23,
+	ETHTOOL_LINK_MODE_40000baseCR4_Full_BIT	= 24,
+	ETHTOOL_LINK_MODE_40000baseSR4_Full_BIT	= 25,
+	ETHTOOL_LINK_MODE_40000baseLR4_Full_BIT	= 26,
+	ETHTOOL_LINK_MODE_56000baseKR4_Full_BIT	= 27,
+	ETHTOOL_LINK_MODE_56000baseCR4_Full_BIT	= 28,
+	ETHTOOL_LINK_MODE_56000baseSR4_Full_BIT	= 29,
+	ETHTOOL_LINK_MODE_56000baseLR4_Full_BIT	= 30,
+
+	/* Last allowed bit for __ETHTOOL_LINK_MODE_LEGACY_MASK is bit
+	 * 31. Please do NOT define any SUPPORTED_* or ADVERTISED_*
+	 * macro for bits > 31. The only way to use indices > 31 is to
+	 * use the new ETHTOOL_GLINKSETTINGS/ETHTOOL_SLINKSETTINGS API.
+	 */
+
+	__ETHTOOL_LINK_MODE_LAST
+	  = ETHTOOL_LINK_MODE_56000baseLR4_Full_BIT,
+};
+
+#define __ETHTOOL_LINK_MODE_LEGACY_MASK(base_name)	\
+	(1UL << (ETHTOOL_LINK_MODE_ ## base_name ## _BIT))
+
+/* DEPRECATED macros. Please migrate to
+ * ETHTOOL_GLINKSETTINGS/ETHTOOL_SLINKSETTINGS API. Please do NOT
+ * define any new SUPPORTED_* macro for bits > 31.
+ */
+#define SUPPORTED_10baseT_Half		__ETHTOOL_LINK_MODE_LEGACY_MASK(10baseT_Half)
+#define SUPPORTED_10baseT_Full		__ETHTOOL_LINK_MODE_LEGACY_MASK(10baseT_Full)
+#define SUPPORTED_100baseT_Half		__ETHTOOL_LINK_MODE_LEGACY_MASK(100baseT_Half)
+#define SUPPORTED_100baseT_Full		__ETHTOOL_LINK_MODE_LEGACY_MASK(100baseT_Full)
+#define SUPPORTED_1000baseT_Half	__ETHTOOL_LINK_MODE_LEGACY_MASK(1000baseT_Half)
+#define SUPPORTED_1000baseT_Full	__ETHTOOL_LINK_MODE_LEGACY_MASK(1000baseT_Full)
+#define SUPPORTED_Autoneg		__ETHTOOL_LINK_MODE_LEGACY_MASK(Autoneg)
+#define SUPPORTED_TP			__ETHTOOL_LINK_MODE_LEGACY_MASK(TP)
+#define SUPPORTED_AUI			__ETHTOOL_LINK_MODE_LEGACY_MASK(AUI)
+#define SUPPORTED_MII			__ETHTOOL_LINK_MODE_LEGACY_MASK(MII)
+#define SUPPORTED_FIBRE			__ETHTOOL_LINK_MODE_LEGACY_MASK(FIBRE)
+#define SUPPORTED_BNC			__ETHTOOL_LINK_MODE_LEGACY_MASK(BNC)
+#define SUPPORTED_10000baseT_Full	__ETHTOOL_LINK_MODE_LEGACY_MASK(10000baseT_Full)
+#define SUPPORTED_Pause			__ETHTOOL_LINK_MODE_LEGACY_MASK(Pause)
+#define SUPPORTED_Asym_Pause		__ETHTOOL_LINK_MODE_LEGACY_MASK(Asym_Pause)
+#define SUPPORTED_2500baseX_Full	__ETHTOOL_LINK_MODE_LEGACY_MASK(2500baseX_Full)
+#define SUPPORTED_Backplane		__ETHTOOL_LINK_MODE_LEGACY_MASK(Backplane)
+#define SUPPORTED_1000baseKX_Full	__ETHTOOL_LINK_MODE_LEGACY_MASK(1000baseKX_Full)
+#define SUPPORTED_10000baseKX4_Full	__ETHTOOL_LINK_MODE_LEGACY_MASK(10000baseKX4_Full)
+#define SUPPORTED_10000baseKR_Full	__ETHTOOL_LINK_MODE_LEGACY_MASK(10000baseKR_Full)
+#define SUPPORTED_10000baseR_FEC	__ETHTOOL_LINK_MODE_LEGACY_MASK(10000baseR_FEC)
+#define SUPPORTED_20000baseMLD2_Full	__ETHTOOL_LINK_MODE_LEGACY_MASK(20000baseMLD2_Full)
+#define SUPPORTED_20000baseKR2_Full	__ETHTOOL_LINK_MODE_LEGACY_MASK(20000baseKR2_Full)
+#define SUPPORTED_40000baseKR4_Full	__ETHTOOL_LINK_MODE_LEGACY_MASK(40000baseKR4_Full)
+#define SUPPORTED_40000baseCR4_Full	__ETHTOOL_LINK_MODE_LEGACY_MASK(40000baseCR4_Full)
+#define SUPPORTED_40000baseSR4_Full	__ETHTOOL_LINK_MODE_LEGACY_MASK(40000baseSR4_Full)
+#define SUPPORTED_40000baseLR4_Full	__ETHTOOL_LINK_MODE_LEGACY_MASK(40000baseLR4_Full)
+#define SUPPORTED_56000baseKR4_Full	__ETHTOOL_LINK_MODE_LEGACY_MASK(56000baseKR4_Full)
+#define SUPPORTED_56000baseCR4_Full	__ETHTOOL_LINK_MODE_LEGACY_MASK(56000baseCR4_Full)
+#define SUPPORTED_56000baseSR4_Full	__ETHTOOL_LINK_MODE_LEGACY_MASK(56000baseSR4_Full)
+#define SUPPORTED_56000baseLR4_Full	__ETHTOOL_LINK_MODE_LEGACY_MASK(56000baseLR4_Full)
+/* Please do not define any new SUPPORTED_* macro for bits > 31, see
+ * notice above.
+ */
+
+/*
+ * DEPRECATED macros. Please migrate to
+ * ETHTOOL_GLINKSETTINGS/ETHTOOL_SLINKSETTINGS API. Please do NOT
+ * define any new ADERTISE_* macro for bits > 31.
+ */
+#define ADVERTISED_10baseT_Half		__ETHTOOL_LINK_MODE_LEGACY_MASK(10baseT_Half)
+#define ADVERTISED_10baseT_Full		__ETHTOOL_LINK_MODE_LEGACY_MASK(10baseT_Full)
+#define ADVERTISED_100baseT_Half	__ETHTOOL_LINK_MODE_LEGACY_MASK(100baseT_Half)
+#define ADVERTISED_100baseT_Full	__ETHTOOL_LINK_MODE_LEGACY_MASK(100baseT_Full)
+#define ADVERTISED_1000baseT_Half	__ETHTOOL_LINK_MODE_LEGACY_MASK(1000baseT_Half)
+#define ADVERTISED_1000baseT_Full	__ETHTOOL_LINK_MODE_LEGACY_MASK(1000baseT_Full)
+#define ADVERTISED_Autoneg		__ETHTOOL_LINK_MODE_LEGACY_MASK(Autoneg)
+#define ADVERTISED_TP			__ETHTOOL_LINK_MODE_LEGACY_MASK(TP)
+#define ADVERTISED_AUI			__ETHTOOL_LINK_MODE_LEGACY_MASK(AUI)
+#define ADVERTISED_MII			__ETHTOOL_LINK_MODE_LEGACY_MASK(MII)
+#define ADVERTISED_FIBRE		__ETHTOOL_LINK_MODE_LEGACY_MASK(FIBRE)
+#define ADVERTISED_BNC			__ETHTOOL_LINK_MODE_LEGACY_MASK(BNC)
+#define ADVERTISED_10000baseT_Full	__ETHTOOL_LINK_MODE_LEGACY_MASK(10000baseT_Full)
+#define ADVERTISED_Pause		__ETHTOOL_LINK_MODE_LEGACY_MASK(Pause)
+#define ADVERTISED_Asym_Pause		__ETHTOOL_LINK_MODE_LEGACY_MASK(Asym_Pause)
+#define ADVERTISED_2500baseX_Full	__ETHTOOL_LINK_MODE_LEGACY_MASK(2500baseX_Full)
+#define ADVERTISED_Backplane		__ETHTOOL_LINK_MODE_LEGACY_MASK(Backplane)
+#define ADVERTISED_1000baseKX_Full	__ETHTOOL_LINK_MODE_LEGACY_MASK(1000baseKX_Full)
+#define ADVERTISED_10000baseKX4_Full	__ETHTOOL_LINK_MODE_LEGACY_MASK(10000baseKX4_Full)
+#define ADVERTISED_10000baseKR_Full	__ETHTOOL_LINK_MODE_LEGACY_MASK(10000baseKR_Full)
+#define ADVERTISED_10000baseR_FEC	__ETHTOOL_LINK_MODE_LEGACY_MASK(10000baseR_FEC)
+#define ADVERTISED_20000baseMLD2_Full	__ETHTOOL_LINK_MODE_LEGACY_MASK(20000baseMLD2_Full)
+#define ADVERTISED_20000baseKR2_Full	__ETHTOOL_LINK_MODE_LEGACY_MASK(20000baseKR2_Full)
+#define ADVERTISED_40000baseKR4_Full	__ETHTOOL_LINK_MODE_LEGACY_MASK(40000baseKR4_Full)
+#define ADVERTISED_40000baseCR4_Full	__ETHTOOL_LINK_MODE_LEGACY_MASK(40000baseCR4_Full)
+#define ADVERTISED_40000baseSR4_Full	__ETHTOOL_LINK_MODE_LEGACY_MASK(40000baseSR4_Full)
+#define ADVERTISED_40000baseLR4_Full	__ETHTOOL_LINK_MODE_LEGACY_MASK(40000baseLR4_Full)
+#define ADVERTISED_56000baseKR4_Full	__ETHTOOL_LINK_MODE_LEGACY_MASK(56000baseKR4_Full)
+#define ADVERTISED_56000baseCR4_Full	__ETHTOOL_LINK_MODE_LEGACY_MASK(56000baseCR4_Full)
+#define ADVERTISED_56000baseSR4_Full	__ETHTOOL_LINK_MODE_LEGACY_MASK(56000baseSR4_Full)
+#define ADVERTISED_56000baseLR4_Full	__ETHTOOL_LINK_MODE_LEGACY_MASK(56000baseLR4_Full)
+/* Please do not define any new ADVERTISED_* macro for bits > 31, see
+ * notice above.
+ */
 
 /* The following are all involved in forcing a particular link
  * mode for the device for setting things.  When getting the
@@ -1316,11 +1391,28 @@ enum ethtool_sfeatures_retval_bits {
 
 #define SPEED_UNKNOWN		-1
 
+static inline int ethtool_validate_speed(__u32 speed)
+{
+	return speed <= INT_MAX || speed == SPEED_UNKNOWN;
+}
+
 /* Duplex, half or full. */
 #define DUPLEX_HALF		0x00
 #define DUPLEX_FULL		0x01
 #define DUPLEX_UNKNOWN		0xff
 
+static inline int ethtool_validate_duplex(__u8 duplex)
+{
+	switch (duplex) {
+	case DUPLEX_HALF:
+	case DUPLEX_FULL:
+	case DUPLEX_UNKNOWN:
+		return 1;
+	}
+
+	return 0;
+}
+
 /* Which connector port. */
 #define PORT_TP			0x00
 #define PORT_AUI		0x01
@@ -1438,4 +1530,123 @@ enum ethtool_reset_flags {
 };
 #define ETH_RESET_SHARED_SHIFT	16
 
+
+/**
+ * struct ethtool_link_settings - link control and status
+ *
+ * IMPORTANT, Backward compatibility notice: When implementing new
+ *	user-space tools, please first try %ETHTOOL_GLINKSETTINGS, and
+ *	if it succeeds use %ETHTOOL_SLINKSETTINGS to change link
+ *	settings; do not use %ETHTOOL_SSET if %ETHTOOL_GLINKSETTINGS
+ *	succeeded: stick to %ETHTOOL_GLINKSETTINGS/%SLINKSETTINGS in
+ *	that case.  Conversely, if %ETHTOOL_GLINKSETTINGS fails, use
+ *	%ETHTOOL_GSET to query and %ETHTOOL_SSET to change link
+ *	settings; do not use %ETHTOOL_SLINKSETTINGS if
+ *	%ETHTOOL_GLINKSETTINGS failed: stick to
+ *	%ETHTOOL_GSET/%ETHTOOL_SSET in that case.
+ *
+ * @cmd: Command number = %ETHTOOL_GLINKSETTINGS or %ETHTOOL_SLINKSETTINGS
+ * @speed: Link speed (Mbps)
+ * @duplex: Duplex mode; one of %DUPLEX_*
+ * @port: Physical connector type; one of %PORT_*
+ * @phy_address: MDIO address of PHY (transceiver); 0 or 255 if not
+ *	applicable.  For clause 45 PHYs this is the PRTAD.
+ * @autoneg: Enable/disable autonegotiation and auto-detection;
+ *	either %AUTONEG_DISABLE or %AUTONEG_ENABLE
+ * @mdio_support: Bitmask of %ETH_MDIO_SUPPORTS_* flags for the MDIO
+ *	protocols supported by the interface; 0 if unknown.
+ *	Read-only.
+ * @eth_tp_mdix: Ethernet twisted-pair MDI(-X) status; one of
+ *	%ETH_TP_MDI_*.  If the status is unknown or not applicable, the
+ *	value will be %ETH_TP_MDI_INVALID.  Read-only.
+ * @eth_tp_mdix_ctrl: Ethernet twisted pair MDI(-X) control; one of
+ *	%ETH_TP_MDI_*.  If MDI(-X) control is not implemented, reads
+ *	yield %ETH_TP_MDI_INVALID and writes may be ignored or rejected.
+ *	When written successfully, the link should be renegotiated if
+ *	necessary.
+ * @link_mode_masks_nwords: Number of 32-bit words for each of the
+ *	supported, advertising, lp_advertising link mode bitmaps. For
+ *	%ETHTOOL_GLINKSETTINGS: on entry, number of words passed by user
+ *	(>= 0); on return, if handshake in progress, negative if
+ *	request size unsupported by kernel: absolute value indicates
+ *	kernel recommended size and cmd field is 0, as well as all the
+ *	other fields; otherwise (handshake completed), strictly
+ *	positive to indicate size used by kernel and cmd field is
+ *	%ETHTOOL_GLINKSETTINGS, all other fields populated by driver. For
+ *	%ETHTOOL_SLINKSETTINGS: must be valid on entry, ie. a positive
+ *	value returned previously by %ETHTOOL_GLINKSETTINGS, otherwise
+ *	refused. For drivers: ignore this field (use kernel's
+ *	__ETHTOOL_LINK_MODE_MASK_NBITS instead), any change to it will
+ *	be overwritten by kernel.
+ * @supported: Bitmap with each bit meaning given by
+ *	%ethtool_link_mode_bit_indices for the link modes, physical
+ *	connectors and other link features for which the interface
+ *	supports autonegotiation or auto-detection.  Read-only.
+ * @advertising: Bitmap with each bit meaning given by
+ *	%ethtool_link_mode_bit_indices for the link modes, physical
+ *	connectors and other link features that are advertised through
+ *	autonegotiation or enabled for auto-detection.
+ * @lp_advertising: Bitmap with each bit meaning given by
+ *	%ethtool_link_mode_bit_indices for the link modes, and other
+ *	link features that the link partner advertised through
+ *	autonegotiation; 0 if unknown or not applicable.  Read-only.
+ *
+ * If autonegotiation is disabled, the speed and @duplex represent the
+ * fixed link mode and are writable if the driver supports multiple
+ * link modes.  If it is enabled then they are read-only; if the link
+ * is up they represent the negotiated link mode; if the link is down,
+ * the speed is 0, %SPEED_UNKNOWN or the highest enabled speed and
+ * @duplex is %DUPLEX_UNKNOWN or the best enabled duplex mode.
+ *
+ * Some hardware interfaces may have multiple PHYs and/or physical
+ * connectors fitted or do not allow the driver to detect which are
+ * fitted.  For these interfaces @port and/or @phy_address may be
+ * writable, possibly dependent on @autoneg being %AUTONEG_DISABLE.
+ * Otherwise, attempts to write different values may be ignored or
+ * rejected.
+ *
+ * Deprecated %ethtool_cmd fields transceiver, maxtxpkt and maxrxpkt
+ * are not available in %ethtool_link_settings. Until all drivers are
+ * converted to ignore them or to the new %ethtool_link_settings API,
+ * for both queries and changes, users should always try
+ * %ETHTOOL_GLINKSETTINGS first, and if it fails with -ENOTSUPP stick
+ * only to %ETHTOOL_GSET and %ETHTOOL_SSET consistently. If it
+ * succeeds, then users should stick to %ETHTOOL_GLINKSETTINGS and
+ * %ETHTOOL_SLINKSETTINGS (which would support drivers implementing
+ * either %ethtool_cmd or %ethtool_link_settings).
+ *
+ * Users should assume that all fields not marked read-only are
+ * writable and subject to validation by the driver.  They should use
+ * %ETHTOOL_GLINKSETTINGS to get the current values before making specific
+ * changes and then applying them with %ETHTOOL_SLINKSETTINGS.
+ *
+ * Drivers that implement %get_link_ksettings and/or
+ * %set_link_ksettings should ignore the @cmd
+ * and @link_mode_masks_nwords fields (any change to them overwritten
+ * by kernel), and rely only on kernel's internal
+ * %__ETHTOOL_LINK_MODE_MASK_NBITS and
+ * %ethtool_link_mode_mask_t. Drivers that implement
+ * %set_link_ksettings() should validate all fields other than @cmd
+ * and @link_mode_masks_nwords that are not described as read-only or
+ * deprecated, and must ignore all fields described as read-only.
+ */
+struct ethtool_link_settings {
+	__u32	cmd;
+	__u32	speed;
+	__u8	duplex;
+	__u8	port;
+	__u8	phy_address;
+	__u8	autoneg;
+	__u8	mdio_support;
+	__u8	eth_tp_mdix;
+	__u8	eth_tp_mdix_ctrl;
+	__s8	link_mode_masks_nwords;
+	__u32	reserved[8];
+	__u32	link_mode_masks[0];
+	/* layout of link_mode_masks fields:
+	 * __u32 map_supported[link_mode_masks_nwords];
+	 * __u32 map_advertising[link_mode_masks_nwords];
+	 * __u32 map_lp_advertising[link_mode_masks_nwords];
+	 */
+};
 #endif /* _UAPI_LINUX_ETHTOOL_H */
--- zfcpdump-kernel-4.4.orig/include/uapi/linux/genetlink.h
+++ zfcpdump-kernel-4.4/include/uapi/linux/genetlink.h
@@ -21,6 +21,7 @@ struct genlmsghdr {
 #define GENL_CMD_CAP_DO		0x02
 #define GENL_CMD_CAP_DUMP	0x04
 #define GENL_CMD_CAP_HASPOL	0x08
+#define GENL_UNS_ADMIN_PERM	0x10
 
 /*
  * List of reserved static generic netlink identifiers:
--- zfcpdump-kernel-4.4.orig/include/uapi/linux/hash_info.h
+++ zfcpdump-kernel-4.4/include/uapi/linux/hash_info.h
@@ -31,6 +31,7 @@ enum hash_algo {
 	HASH_ALGO_TGR_128,
 	HASH_ALGO_TGR_160,
 	HASH_ALGO_TGR_192,
+	HASH_ALGO_SM3_256,
 	HASH_ALGO__LAST
 };
 
--- zfcpdump-kernel-4.4.orig/include/uapi/linux/hyperv.h
+++ zfcpdump-kernel-4.4/include/uapi/linux/hyperv.h
@@ -313,6 +313,7 @@ enum hv_kvp_exchg_pool {
 #define HV_INVALIDARG			0x80070057
 #define HV_GUID_NOTFOUND		0x80041002
 #define HV_ERROR_ALREADY_EXISTS		0x80070050
+#define HV_ERROR_DISK_FULL		0x80070070
 
 #define ADDR_FAMILY_NONE	0x00
 #define ADDR_FAMILY_IPV4	0x01
--- zfcpdump-kernel-4.4.orig/include/uapi/linux/if.h
+++ zfcpdump-kernel-4.4/include/uapi/linux/if.h
@@ -19,14 +19,20 @@
 #ifndef _LINUX_IF_H
 #define _LINUX_IF_H
 
+#include <linux/libc-compat.h>          /* for compatibility with glibc */
 #include <linux/types.h>		/* for "__kernel_caddr_t" et al	*/
 #include <linux/socket.h>		/* for "struct sockaddr" et al	*/
 #include <linux/compiler.h>		/* for "__user" et al           */
 
+#if __UAPI_DEF_IF_IFNAMSIZ
 #define	IFNAMSIZ	16
+#endif /* __UAPI_DEF_IF_IFNAMSIZ */
 #define	IFALIASZ	256
 #include <linux/hdlc/ioctl.h>
 
+/* For glibc compatibility. An empty enum does not compile. */
+#if __UAPI_DEF_IF_NET_DEVICE_FLAGS_LOWER_UP_DORMANT_ECHO != 0 && \
+    __UAPI_DEF_IF_NET_DEVICE_FLAGS != 0
 /**
  * enum net_device_flags - &struct net_device flags
  *
@@ -68,6 +74,8 @@
  * @IFF_ECHO: echo sent packets. Volatile.
  */
 enum net_device_flags {
+/* for compatibility with glibc net/if.h */
+#if __UAPI_DEF_IF_NET_DEVICE_FLAGS
 	IFF_UP				= 1<<0,  /* sysfs */
 	IFF_BROADCAST			= 1<<1,  /* volatile */
 	IFF_DEBUG			= 1<<2,  /* sysfs */
@@ -84,11 +92,17 @@ enum net_device_flags {
 	IFF_PORTSEL			= 1<<13, /* sysfs */
 	IFF_AUTOMEDIA			= 1<<14, /* sysfs */
 	IFF_DYNAMIC			= 1<<15, /* sysfs */
+#endif /* __UAPI_DEF_IF_NET_DEVICE_FLAGS */
+#if __UAPI_DEF_IF_NET_DEVICE_FLAGS_LOWER_UP_DORMANT_ECHO
 	IFF_LOWER_UP			= 1<<16, /* volatile */
 	IFF_DORMANT			= 1<<17, /* volatile */
 	IFF_ECHO			= 1<<18, /* volatile */
+#endif /* __UAPI_DEF_IF_NET_DEVICE_FLAGS_LOWER_UP_DORMANT_ECHO */
 };
+#endif /* __UAPI_DEF_IF_NET_DEVICE_FLAGS_LOWER_UP_DORMANT_ECHO != 0 && __UAPI_DEF_IF_NET_DEVICE_FLAGS != 0 */
 
+/* for compatibility with glibc net/if.h */
+#if __UAPI_DEF_IF_NET_DEVICE_FLAGS
 #define IFF_UP				IFF_UP
 #define IFF_BROADCAST			IFF_BROADCAST
 #define IFF_DEBUG			IFF_DEBUG
@@ -105,9 +119,13 @@ enum net_device_flags {
 #define IFF_PORTSEL			IFF_PORTSEL
 #define IFF_AUTOMEDIA			IFF_AUTOMEDIA
 #define IFF_DYNAMIC			IFF_DYNAMIC
+#endif /* __UAPI_DEF_IF_NET_DEVICE_FLAGS */
+
+#if __UAPI_DEF_IF_NET_DEVICE_FLAGS_LOWER_UP_DORMANT_ECHO
 #define IFF_LOWER_UP			IFF_LOWER_UP
 #define IFF_DORMANT			IFF_DORMANT
 #define IFF_ECHO			IFF_ECHO
+#endif /* __UAPI_DEF_IF_NET_DEVICE_FLAGS_LOWER_UP_DORMANT_ECHO */
 
 #define IFF_VOLATILE	(IFF_LOOPBACK|IFF_POINTOPOINT|IFF_BROADCAST|IFF_ECHO|\
 		IFF_MASTER|IFF_SLAVE|IFF_RUNNING|IFF_LOWER_UP|IFF_DORMANT)
@@ -166,6 +184,8 @@ enum {
  *	being very small might be worth keeping for clean configuration.
  */
 
+/* for compatibility with glibc net/if.h */
+#if __UAPI_DEF_IF_IFMAP
 struct ifmap {
 	unsigned long mem_start;
 	unsigned long mem_end;
@@ -175,6 +195,7 @@ struct ifmap {
 	unsigned char port;
 	/* 3 bytes spare */
 };
+#endif /* __UAPI_DEF_IF_IFMAP */
 
 struct if_settings {
 	unsigned int type;	/* Type of physical device or protocol */
@@ -200,6 +221,8 @@ struct if_settings {
  * remainder may be interface specific.
  */
 
+/* for compatibility with glibc net/if.h */
+#if __UAPI_DEF_IF_IFREQ
 struct ifreq {
 #define IFHWADDRLEN	6
 	union
@@ -223,6 +246,7 @@ struct ifreq {
 		struct	if_settings ifru_settings;
 	} ifr_ifru;
 };
+#endif /* __UAPI_DEF_IF_IFREQ */
 
 #define ifr_name	ifr_ifrn.ifrn_name	/* interface name 	*/
 #define ifr_hwaddr	ifr_ifru.ifru_hwaddr	/* MAC address 		*/
@@ -249,6 +273,8 @@ struct ifreq {
  * must know all networks accessible).
  */
 
+/* for compatibility with glibc net/if.h */
+#if __UAPI_DEF_IF_IFCONF
 struct ifconf  {
 	int	ifc_len;			/* size of buffer	*/
 	union {
@@ -256,6 +282,8 @@ struct ifconf  {
 		struct ifreq __user *ifcu_req;
 	} ifc_ifcu;
 };
+#endif /* __UAPI_DEF_IF_IFCONF */
+
 #define	ifc_buf	ifc_ifcu.ifcu_buf		/* buffer address	*/
 #define	ifc_req	ifc_ifcu.ifcu_req		/* array of structures	*/
 
--- zfcpdump-kernel-4.4.orig/include/uapi/linux/if_link.h
+++ zfcpdump-kernel-4.4/include/uapi/linux/if_link.h
@@ -443,6 +443,7 @@ enum {
 	IFLA_VXLAN_GBP,
 	IFLA_VXLAN_REMCSUM_NOPARTIAL,
 	IFLA_VXLAN_COLLECT_METADATA,
+	IFLA_VXLAN_FAN_MAP = 33,
 	__IFLA_VXLAN_MAX
 };
 #define IFLA_VXLAN_MAX	(__IFLA_VXLAN_MAX - 1)
@@ -462,6 +463,9 @@ enum {
 	IFLA_GENEVE_PORT,	/* destination port */
 	IFLA_GENEVE_COLLECT_METADATA,
 	IFLA_GENEVE_REMOTE6,
+	IFLA_GENEVE_UDP_CSUM,
+	IFLA_GENEVE_UDP_ZERO_CSUM6_TX,
+	IFLA_GENEVE_UDP_ZERO_CSUM6_RX,
 	__IFLA_GENEVE_MAX
 };
 #define IFLA_GENEVE_MAX	(__IFLA_GENEVE_MAX - 1)
--- zfcpdump-kernel-4.4.orig/include/uapi/linux/if_tunnel.h
+++ zfcpdump-kernel-4.4/include/uapi/linux/if_tunnel.h
@@ -57,6 +57,10 @@ enum {
 	IFLA_IPTUN_ENCAP_FLAGS,
 	IFLA_IPTUN_ENCAP_SPORT,
 	IFLA_IPTUN_ENCAP_DPORT,
+
+	__IFLA_IPTUN_VENDOR_BREAK, /* Ensure new entries do not hit the below. */
+	IFLA_IPTUN_FAN_MAP = 33,
+
 	__IFLA_IPTUN_MAX,
 };
 #define IFLA_IPTUN_MAX	(__IFLA_IPTUN_MAX - 1)
@@ -132,4 +136,20 @@ enum {
 };
 
 #define IFLA_VTI_MAX	(__IFLA_VTI_MAX - 1)
+
+enum {
+	IFLA_FAN_UNSPEC,
+	IFLA_FAN_MAPPING,
+	__IFLA_FAN_MAX,
+};
+
+#define IFLA_FAN_MAX (__IFLA_FAN_MAX - 1)
+
+struct ifla_fan_map {
+	__be32		underlay;
+	__be32		overlay;
+	__u16		underlay_prefix;
+	__u16		overlay_prefix;
+};
+
 #endif /* _UAPI_IF_TUNNEL_H_ */
--- zfcpdump-kernel-4.4.orig/include/uapi/linux/kd.h
+++ zfcpdump-kernel-4.4/include/uapi/linux/kd.h
@@ -45,6 +45,8 @@ struct consolefontdesc {
 #define		KD_GRAPHICS	0x01
 #define		KD_TEXT0	0x02	/* obsolete */
 #define		KD_TEXT1	0x03	/* obsolete */
+#define		KD_TRANSPARENT	0x04
+
 #define KDGETMODE	0x4B3B	/* get current mode */
 
 #define KDMAPDISP	0x4B3C	/* map display into address space */
--- zfcpdump-kernel-4.4.orig/include/uapi/linux/kvm.h
+++ zfcpdump-kernel-4.4/include/uapi/linux/kvm.h
@@ -154,6 +154,20 @@ struct kvm_s390_skeys {
 	__u32 flags;
 	__u32 reserved[9];
 };
+
+struct kvm_hyperv_exit {
+#define KVM_EXIT_HYPERV_SYNIC          1
+	__u32 type;
+	union {
+		struct {
+			__u32 msr;
+			__u64 control;
+			__u64 evt_page;
+			__u64 msg_page;
+		} synic;
+	} u;
+};
+
 #define KVM_S390_GET_SKEYS_NONE   1
 #define KVM_S390_SKEYS_MAX        1048576
 
@@ -184,6 +198,7 @@ struct kvm_s390_skeys {
 #define KVM_EXIT_SYSTEM_EVENT     24
 #define KVM_EXIT_S390_STSI        25
 #define KVM_EXIT_IOAPIC_EOI       26
+#define KVM_EXIT_HYPERV           27
 
 /* For KVM_EXIT_INTERNAL_ERROR */
 /* Emulate instruction failed. */
@@ -338,6 +353,8 @@ struct kvm_run {
 		struct {
 			__u8 vector;
 		} eoi;
+		/* KVM_EXIT_HYPERV */
+		struct kvm_hyperv_exit hyperv;
 		/* Fix the size of the union. */
 		char padding[256];
 	};
@@ -831,6 +848,7 @@ struct kvm_ppc_smmu_info {
 #define KVM_CAP_GUEST_DEBUG_HW_WPS 120
 #define KVM_CAP_SPLIT_IRQCHIP 121
 #define KVM_CAP_IOEVENTFD_ANY_LENGTH 122
+#define KVM_CAP_HYPERV_SYNIC 123
 
 #ifdef KVM_CAP_IRQ_ROUTING
 
@@ -854,10 +872,16 @@ struct kvm_irq_routing_s390_adapter {
 	__u32 adapter_id;
 };
 
+struct kvm_irq_routing_hv_sint {
+	__u32 vcpu;
+	__u32 sint;
+};
+
 /* gsi routing entry types */
 #define KVM_IRQ_ROUTING_IRQCHIP 1
 #define KVM_IRQ_ROUTING_MSI 2
 #define KVM_IRQ_ROUTING_S390_ADAPTER 3
+#define KVM_IRQ_ROUTING_HV_SINT 4
 
 struct kvm_irq_routing_entry {
 	__u32 gsi;
@@ -868,6 +892,7 @@ struct kvm_irq_routing_entry {
 		struct kvm_irq_routing_irqchip irqchip;
 		struct kvm_irq_routing_msi msi;
 		struct kvm_irq_routing_s390_adapter adapter;
+		struct kvm_irq_routing_hv_sint hv_sint;
 		__u32 pad[8];
 	} u;
 };
--- zfcpdump-kernel-4.4.orig/include/uapi/linux/libc-compat.h
+++ zfcpdump-kernel-4.4/include/uapi/linux/libc-compat.h
@@ -51,6 +51,40 @@
 /* We have included glibc headers... */
 #if defined(__GLIBC__)
 
+/* Coordinate with glibc net/if.h header. */
+#if defined(_NET_IF_H) && defined(__USE_MISC)
+
+/* GLIBC headers included first so don't define anything
+ * that would already be defined. */
+
+#define __UAPI_DEF_IF_IFCONF 0
+#define __UAPI_DEF_IF_IFMAP 0
+#define __UAPI_DEF_IF_IFNAMSIZ 0
+#define __UAPI_DEF_IF_IFREQ 0
+/* Everything up to IFF_DYNAMIC, matches net/if.h until glibc 2.23 */
+#define __UAPI_DEF_IF_NET_DEVICE_FLAGS 0
+/* For the future if glibc adds IFF_LOWER_UP, IFF_DORMANT and IFF_ECHO */
+#ifndef __UAPI_DEF_IF_NET_DEVICE_FLAGS_LOWER_UP_DORMANT_ECHO
+#define __UAPI_DEF_IF_NET_DEVICE_FLAGS_LOWER_UP_DORMANT_ECHO 1
+#endif /* __UAPI_DEF_IF_NET_DEVICE_FLAGS_LOWER_UP_DORMANT_ECHO */
+
+#else /* _NET_IF_H */
+
+/* Linux headers included first, and we must define everything
+ * we need. The expectation is that glibc will check the
+ * __UAPI_DEF_* defines and adjust appropriately. */
+
+#define __UAPI_DEF_IF_IFCONF 1
+#define __UAPI_DEF_IF_IFMAP 1
+#define __UAPI_DEF_IF_IFNAMSIZ 1
+#define __UAPI_DEF_IF_IFREQ 1
+/* Everything up to IFF_DYNAMIC, matches net/if.h until glibc 2.23 */
+#define __UAPI_DEF_IF_NET_DEVICE_FLAGS 1
+/* For the future if glibc adds IFF_LOWER_UP, IFF_DORMANT and IFF_ECHO */
+#define __UAPI_DEF_IF_NET_DEVICE_FLAGS_LOWER_UP_DORMANT_ECHO 1
+
+#endif /* _NET_IF_H */
+
 /* Coordinate with glibc netinet/in.h header. */
 #if defined(_NETINET_IN_H)
 
@@ -117,6 +151,16 @@
  * that we need. */
 #else /* !defined(__GLIBC__) */
 
+/* Definitions for if.h */
+#define __UAPI_DEF_IF_IFCONF 1
+#define __UAPI_DEF_IF_IFMAP 1
+#define __UAPI_DEF_IF_IFNAMSIZ 1
+#define __UAPI_DEF_IF_IFREQ 1
+/* Everything up to IFF_DYNAMIC, matches net/if.h until glibc 2.23 */
+#define __UAPI_DEF_IF_NET_DEVICE_FLAGS 1
+/* For the future if glibc adds IFF_LOWER_UP, IFF_DORMANT and IFF_ECHO */
+#define __UAPI_DEF_IF_NET_DEVICE_FLAGS_LOWER_UP_DORMANT_ECHO 1
+
 /* Definitions for in.h */
 #define __UAPI_DEF_IN_ADDR		1
 #define __UAPI_DEF_IN_IPPROTO		1
--- zfcpdump-kernel-4.4.orig/include/uapi/linux/lightnvm.h
+++ zfcpdump-kernel-4.4/include/uapi/linux/lightnvm.h
@@ -33,6 +33,7 @@
 
 #define NVM_TTYPE_NAME_MAX 48
 #define NVM_TTYPE_MAX 63
+#define NVM_MMTYPE_LEN 8
 
 #define NVM_CTRL_FILE "/dev/lightnvm/control"
 
@@ -100,6 +101,26 @@ struct nvm_ioctl_remove {
 	__u32 flags;
 };
 
+struct nvm_ioctl_dev_init {
+	char dev[DISK_NAME_LEN];		/* open-channel SSD device */
+	char mmtype[NVM_MMTYPE_LEN];		/* register to media manager */
+
+	__u32 flags;
+};
+
+enum {
+	NVM_FACTORY_ERASE_ONLY_USER	= 1 << 0, /* erase only blocks used as
+						   * host blks or grown blks */
+	NVM_FACTORY_RESET_HOST_BLKS	= 1 << 1, /* remove host blk marks */
+	NVM_FACTORY_RESET_GRWN_BBLKS	= 1 << 2, /* remove grown blk marks */
+	NVM_FACTORY_NR_BITS		= 1 << 3, /* stops here */
+};
+
+struct nvm_ioctl_dev_factory {
+	char dev[DISK_NAME_LEN];
+
+	__u32 flags;
+};
 
 /* The ioctl type, 'L', 0x20 - 0x2F documented in ioctl-number.txt */
 enum {
@@ -110,6 +131,12 @@ enum {
 	/* device level cmds */
 	NVM_DEV_CREATE_CMD,
 	NVM_DEV_REMOVE_CMD,
+
+	/* Init a device to support LightNVM media managers */
+	NVM_DEV_INIT_CMD,
+
+	/* Factory reset device */
+	NVM_DEV_FACTORY_CMD,
 };
 
 #define NVM_IOCTL 'L' /* 0x4c */
@@ -122,6 +149,10 @@ enum {
 						struct nvm_ioctl_create)
 #define NVM_DEV_REMOVE		_IOW(NVM_IOCTL, NVM_DEV_REMOVE_CMD, \
 						struct nvm_ioctl_remove)
+#define NVM_DEV_INIT		_IOW(NVM_IOCTL, NVM_DEV_INIT_CMD, \
+						struct nvm_ioctl_dev_init)
+#define NVM_DEV_FACTORY		_IOW(NVM_IOCTL, NVM_DEV_FACTORY_CMD, \
+						struct nvm_ioctl_dev_factory)
 
 #define NVM_VERSION_MAJOR	1
 #define NVM_VERSION_MINOR	0
--- zfcpdump-kernel-4.4.orig/include/uapi/linux/ptp_clock.h
+++ zfcpdump-kernel-4.4/include/uapi/linux/ptp_clock.h
@@ -51,7 +51,9 @@ struct ptp_clock_caps {
 	int n_per_out; /* Number of programmable periodic signals. */
 	int pps;       /* Whether the clock supports a PPS callback. */
 	int n_pins;    /* Number of input/output pins. */
-	int rsv[14];   /* Reserved for future use. */
+	/* Whether the clock supports precise system-device cross timestamps */
+	int cross_timestamping;
+	int rsv[13];   /* Reserved for future use. */
 };
 
 struct ptp_extts_request {
@@ -81,6 +83,13 @@ struct ptp_sys_offset {
 	struct ptp_clock_time ts[2 * PTP_MAX_SAMPLES + 1];
 };
 
+struct ptp_sys_offset_precise {
+	struct ptp_clock_time device;
+	struct ptp_clock_time sys_realtime;
+	struct ptp_clock_time sys_monoraw;
+	unsigned int rsv[4];    /* Reserved for future use. */
+};
+
 enum ptp_pin_function {
 	PTP_PF_NONE,
 	PTP_PF_EXTTS,
@@ -124,6 +133,8 @@ struct ptp_pin_desc {
 #define PTP_SYS_OFFSET     _IOW(PTP_CLK_MAGIC, 5, struct ptp_sys_offset)
 #define PTP_PIN_GETFUNC    _IOWR(PTP_CLK_MAGIC, 6, struct ptp_pin_desc)
 #define PTP_PIN_SETFUNC    _IOW(PTP_CLK_MAGIC, 7, struct ptp_pin_desc)
+#define PTP_SYS_OFFSET_PRECISE \
+	_IOWR(PTP_CLK_MAGIC, 8, struct ptp_sys_offset_precise)
 
 struct ptp_extts_event {
 	struct ptp_clock_time t; /* Time event occured. */
--- zfcpdump-kernel-4.4.orig/include/uapi/linux/sched.h
+++ zfcpdump-kernel-4.4/include/uapi/linux/sched.h
@@ -21,8 +21,7 @@
 #define CLONE_DETACHED		0x00400000	/* Unused, ignored */
 #define CLONE_UNTRACED		0x00800000	/* set if the tracing process can't force CLONE_PTRACE on this clone */
 #define CLONE_CHILD_SETTID	0x01000000	/* set the TID in the child */
-/* 0x02000000 was previously the unused CLONE_STOPPED (Start in stopped state)
-   and is now available for re-use. */
+#define CLONE_NEWCGROUP		0x02000000	/* New cgroup namespace */
 #define CLONE_NEWUTS		0x04000000	/* New utsname namespace */
 #define CLONE_NEWIPC		0x08000000	/* New ipc namespace */
 #define CLONE_NEWUSER		0x10000000	/* New user namespace */
--- zfcpdump-kernel-4.4.orig/include/uapi/linux/usb/ch11.h
+++ zfcpdump-kernel-4.4/include/uapi/linux/usb/ch11.h
@@ -30,6 +30,14 @@
 #define USB_RT_PORT	(USB_TYPE_CLASS | USB_RECIP_OTHER)
 
 /*
+ * Port status type for GetPortStatus requests added in USB 3.1
+ * See USB 3.1 spec Table 10-12
+ */
+#define HUB_PORT_STATUS		0
+#define HUB_PORT_PD_STATUS	1
+#define HUB_EXT_PORT_STATUS	2
+
+/*
  * Hub class requests
  * See USB 2.0 spec Table 11-16
  */
@@ -97,10 +105,13 @@
 /*
  * Hub Status and Hub Change results
  * See USB 2.0 spec Table 11-19 and Table 11-20
+ * USB 3.1 extends the port status request and may return 4 additional bytes.
+ * See USB 3.1 spec section 10.16.2.6 Table 10-12 and 10-15
  */
 struct usb_port_status {
 	__le16 wPortStatus;
 	__le16 wPortChange;
+	__le32 dwExtPortStatus;
 } __attribute__ ((packed));
 
 /*
@@ -173,6 +184,16 @@ struct usb_port_status {
 #define USB_PORT_STAT_C_CONFIG_ERROR	0x0080
 
 /*
+ * USB 3.1 dwExtPortStatus field masks
+ * See USB 3.1 spec 10.16.2.6.3 Table 10-15
+ */
+
+#define USB_EXT_PORT_STAT_RX_SPEED_ID	0x0000000f
+#define USB_EXT_PORT_STAT_TX_SPEED_ID	0x000000f0
+#define USB_EXT_PORT_STAT_RX_LANES	0x00000f00
+#define USB_EXT_PORT_STAT_TX_LANES	0x0000f000
+
+/*
  * wHubCharacteristics (masks)
  * See USB 2.0 spec Table 11-13, offset 3
  */
--- zfcpdump-kernel-4.4.orig/include/uapi/linux/usb/ch9.h
+++ zfcpdump-kernel-4.4/include/uapi/linux/usb/ch9.h
@@ -234,6 +234,8 @@ struct usb_ctrlrequest {
 #define USB_DT_PIPE_USAGE		0x24
 /* From the USB 3.0 spec */
 #define	USB_DT_SS_ENDPOINT_COMP		0x30
+/* From the USB 3.1 spec */
+#define	USB_DT_SSP_ISOC_ENDPOINT_COMP	0x31
 
 /* Conventional codes for class-specific descriptors.  The convention is
  * defined in the USB "Common Class" Spec (3.11).  Individual class specs
@@ -613,6 +615,20 @@ static inline int usb_endpoint_interrupt
 
 /*-------------------------------------------------------------------------*/
 
+/* USB_DT_SSP_ISOC_ENDPOINT_COMP: SuperSpeedPlus Isochronous Endpoint Companion
+ * descriptor
+ */
+struct usb_ssp_isoc_ep_comp_descriptor {
+	__u8  bLength;
+	__u8  bDescriptorType;
+	__le16 wReseved;
+	__le32 dwBytesPerInterval;
+} __attribute__ ((packed));
+
+#define USB_DT_SSP_ISOC_EP_COMP_SIZE		8
+
+/*-------------------------------------------------------------------------*/
+
 /* USB_DT_SS_ENDPOINT_COMP: SuperSpeed Endpoint Companion descriptor */
 struct usb_ss_ep_comp_descriptor {
 	__u8  bLength;
@@ -646,6 +662,8 @@ usb_ss_max_streams(const struct usb_ss_e
 
 /* Bits 1:0 of bmAttributes if this is an isoc endpoint */
 #define USB_SS_MULT(p)			(1 + ((p) & 0x3))
+/* Bit 7 of bmAttributes if a SSP isoc endpoint companion descriptor exists */
+#define USB_SS_SSP_ISOC_COMP(p)		((p) & (1 << 7))
 
 /*-------------------------------------------------------------------------*/
 
@@ -894,6 +912,16 @@ struct usb_ssp_cap_descriptor {
 #define USB_SSP_SUBLINK_SPEED_LSM	(0xff << 16)	/* Lanespeed mantissa */
 } __attribute__((packed));
 
+/*
+ * Precision time measurement capability descriptor: advertised by devices and
+ * hubs that support PTM
+ */
+#define	USB_PTM_CAP_TYPE	0xb
+struct usb_ptm_cap_descriptor {
+	__u8  bLength;
+	__u8  bDescriptorType;
+	__u8  bDevCapabilityType;
+} __attribute__((packed));
 
 /*-------------------------------------------------------------------------*/
 
@@ -954,6 +982,7 @@ enum usb_device_speed {
 	USB_SPEED_HIGH,				/* usb 2.0 */
 	USB_SPEED_WIRELESS,			/* wireless (usb 2.5) */
 	USB_SPEED_SUPER,			/* usb 3.0 */
+	USB_SPEED_SUPER_PLUS,			/* usb 3.1 */
 };
 
 
--- zfcpdump-kernel-4.4.orig/include/uapi/linux/v4l2-dv-timings.h
+++ zfcpdump-kernel-4.4/include/uapi/linux/v4l2-dv-timings.h
@@ -183,7 +183,8 @@
 
 #define V4L2_DV_BT_CEA_3840X2160P24 { \
 	.type = V4L2_DV_BT_656_1120, \
-	V4L2_INIT_BT_TIMINGS(3840, 2160, 0, V4L2_DV_HSYNC_POS_POL, \
+	V4L2_INIT_BT_TIMINGS(3840, 2160, 0, \
+		V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \
 		297000000, 1276, 88, 296, 8, 10, 72, 0, 0, 0, \
 		V4L2_DV_BT_STD_CEA861, \
 		V4L2_DV_FL_CAN_REDUCE_FPS | V4L2_DV_FL_IS_CE_VIDEO) \
@@ -191,14 +192,16 @@
 
 #define V4L2_DV_BT_CEA_3840X2160P25 { \
 	.type = V4L2_DV_BT_656_1120, \
-	V4L2_INIT_BT_TIMINGS(3840, 2160, 0, V4L2_DV_HSYNC_POS_POL, \
+	V4L2_INIT_BT_TIMINGS(3840, 2160, 0, \
+		V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \
 		297000000, 1056, 88, 296, 8, 10, 72, 0, 0, 0, \
 		V4L2_DV_BT_STD_CEA861, V4L2_DV_FL_IS_CE_VIDEO) \
 }
 
 #define V4L2_DV_BT_CEA_3840X2160P30 { \
 	.type = V4L2_DV_BT_656_1120, \
-	V4L2_INIT_BT_TIMINGS(3840, 2160, 0, V4L2_DV_HSYNC_POS_POL, \
+	V4L2_INIT_BT_TIMINGS(3840, 2160, 0, \
+		V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \
 		297000000, 176, 88, 296, 8, 10, 72, 0, 0, 0, \
 		V4L2_DV_BT_STD_CEA861, \
 		V4L2_DV_FL_CAN_REDUCE_FPS | V4L2_DV_FL_IS_CE_VIDEO) \
@@ -206,14 +209,16 @@
 
 #define V4L2_DV_BT_CEA_3840X2160P50 { \
 	.type = V4L2_DV_BT_656_1120, \
-	V4L2_INIT_BT_TIMINGS(3840, 2160, 0, V4L2_DV_HSYNC_POS_POL, \
+	V4L2_INIT_BT_TIMINGS(3840, 2160, 0, \
+		V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \
 		594000000, 1056, 88, 296, 8, 10, 72, 0, 0, 0, \
 		V4L2_DV_BT_STD_CEA861, V4L2_DV_FL_IS_CE_VIDEO) \
 }
 
 #define V4L2_DV_BT_CEA_3840X2160P60 { \
 	.type = V4L2_DV_BT_656_1120, \
-	V4L2_INIT_BT_TIMINGS(3840, 2160, 0, V4L2_DV_HSYNC_POS_POL, \
+	V4L2_INIT_BT_TIMINGS(3840, 2160, 0, \
+		V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \
 		594000000, 176, 88, 296, 8, 10, 72, 0, 0, 0, \
 		V4L2_DV_BT_STD_CEA861, \
 		V4L2_DV_FL_CAN_REDUCE_FPS | V4L2_DV_FL_IS_CE_VIDEO) \
@@ -221,7 +226,8 @@
 
 #define V4L2_DV_BT_CEA_4096X2160P24 { \
 	.type = V4L2_DV_BT_656_1120, \
-	V4L2_INIT_BT_TIMINGS(4096, 2160, 0, V4L2_DV_HSYNC_POS_POL, \
+	V4L2_INIT_BT_TIMINGS(4096, 2160, 0, \
+		V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \
 		297000000, 1020, 88, 296, 8, 10, 72, 0, 0, 0, \
 		V4L2_DV_BT_STD_CEA861, \
 		V4L2_DV_FL_CAN_REDUCE_FPS | V4L2_DV_FL_IS_CE_VIDEO) \
@@ -229,14 +235,16 @@
 
 #define V4L2_DV_BT_CEA_4096X2160P25 { \
 	.type = V4L2_DV_BT_656_1120, \
-	V4L2_INIT_BT_TIMINGS(4096, 2160, 0, V4L2_DV_HSYNC_POS_POL, \
+	V4L2_INIT_BT_TIMINGS(4096, 2160, 0, \
+		V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \
 		297000000, 968, 88, 128, 8, 10, 72, 0, 0, 0, \
 		V4L2_DV_BT_STD_CEA861, V4L2_DV_FL_IS_CE_VIDEO) \
 }
 
 #define V4L2_DV_BT_CEA_4096X2160P30 { \
 	.type = V4L2_DV_BT_656_1120, \
-	V4L2_INIT_BT_TIMINGS(4096, 2160, 0, V4L2_DV_HSYNC_POS_POL, \
+	V4L2_INIT_BT_TIMINGS(4096, 2160, 0, \
+		V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \
 		297000000, 88, 88, 128, 8, 10, 72, 0, 0, 0, \
 		V4L2_DV_BT_STD_CEA861, \
 		V4L2_DV_FL_CAN_REDUCE_FPS | V4L2_DV_FL_IS_CE_VIDEO) \
@@ -244,14 +252,16 @@
 
 #define V4L2_DV_BT_CEA_4096X2160P50 { \
 	.type = V4L2_DV_BT_656_1120, \
-	V4L2_INIT_BT_TIMINGS(4096, 2160, 0, V4L2_DV_HSYNC_POS_POL, \
+	V4L2_INIT_BT_TIMINGS(4096, 2160, 0, \
+		V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \
 		594000000, 968, 88, 128, 8, 10, 72, 0, 0, 0, \
 		V4L2_DV_BT_STD_CEA861, V4L2_DV_FL_IS_CE_VIDEO) \
 }
 
 #define V4L2_DV_BT_CEA_4096X2160P60 { \
 	.type = V4L2_DV_BT_656_1120, \
-	V4L2_INIT_BT_TIMINGS(4096, 2160, 0, V4L2_DV_HSYNC_POS_POL, \
+	V4L2_INIT_BT_TIMINGS(4096, 2160, 0, \
+		V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \
 		594000000, 88, 88, 128, 8, 10, 72, 0, 0, 0, \
 		V4L2_DV_BT_STD_CEA861, \
 		V4L2_DV_FL_CAN_REDUCE_FPS | V4L2_DV_FL_IS_CE_VIDEO) \
--- zfcpdump-kernel-4.4.orig/include/uapi/linux/videodev2.h
+++ zfcpdump-kernel-4.4/include/uapi/linux/videodev2.h
@@ -621,6 +621,9 @@ struct v4l2_pix_format {
 #define V4L2_PIX_FMT_JPGL	v4l2_fourcc('J', 'P', 'G', 'L') /* JPEG-Lite */
 #define V4L2_PIX_FMT_SE401      v4l2_fourcc('S', '4', '0', '1') /* se401 janggu compressed rgb */
 #define V4L2_PIX_FMT_S5C_UYVY_JPG v4l2_fourcc('S', '5', 'C', 'I') /* S5C73M3 interleaved UYVY/JPEG */
+#define V4L2_PIX_FMT_Y8I      v4l2_fourcc('Y', '8', 'I', ' ') /* Greyscale 8-bit L/R interleaved */
+#define V4L2_PIX_FMT_Y12I     v4l2_fourcc('Y', '1', '2', 'I') /* Greyscale 12-bit L/R interleaved */
+#define V4L2_PIX_FMT_Z16      v4l2_fourcc('Z', '1', '6', ' ') /* Depth data 16-bit */
 
 /* SDR formats - used only for Software Defined Radio devices */
 #define V4L2_SDR_FMT_CU8          v4l2_fourcc('C', 'U', '0', '8') /* IQ u8 */
--- zfcpdump-kernel-4.4.orig/include/uapi/linux/virtio_balloon.h
+++ zfcpdump-kernel-4.4/include/uapi/linux/virtio_balloon.h
@@ -51,7 +51,8 @@ struct virtio_balloon_config {
 #define VIRTIO_BALLOON_S_MINFLT   3   /* Number of minor faults */
 #define VIRTIO_BALLOON_S_MEMFREE  4   /* Total amount of free memory */
 #define VIRTIO_BALLOON_S_MEMTOT   5   /* Total amount of memory */
-#define VIRTIO_BALLOON_S_NR       6
+#define VIRTIO_BALLOON_S_AVAIL    6   /* Available memory as in /proc */
+#define VIRTIO_BALLOON_S_NR       7
 
 /*
  * Memory statistics structure.
--- zfcpdump-kernel-4.4.orig/include/uapi/misc/cxl.h
+++ zfcpdump-kernel-4.4/include/uapi/misc/cxl.h
@@ -55,11 +55,35 @@ struct cxl_afu_id {
 	__u64 reserved6;
 };
 
+/* base adapter image header is included in the image */
+#define CXL_AI_NEED_HEADER	0x0000000000000001ULL
+#define CXL_AI_ALL		CXL_AI_NEED_HEADER
+
+#define CXL_AI_HEADER_SIZE 128
+#define CXL_AI_BUFFER_SIZE 4096
+#define CXL_AI_MAX_ENTRIES 256
+#define CXL_AI_MAX_CHUNK_SIZE (CXL_AI_BUFFER_SIZE * CXL_AI_MAX_ENTRIES)
+
+struct cxl_adapter_image {
+	__u64 flags;
+	__u64 data;
+	__u64 len_data;
+	__u64 len_image;
+	__u64 reserved1;
+	__u64 reserved2;
+	__u64 reserved3;
+	__u64 reserved4;
+};
+
 /* ioctl numbers */
 #define CXL_MAGIC 0xCA
+/* AFU devices */
 #define CXL_IOCTL_START_WORK		_IOW(CXL_MAGIC, 0x00, struct cxl_ioctl_start_work)
 #define CXL_IOCTL_GET_PROCESS_ELEMENT	_IOR(CXL_MAGIC, 0x01, __u32)
 #define CXL_IOCTL_GET_AFU_ID            _IOR(CXL_MAGIC, 0x02, struct cxl_afu_id)
+/* adapter devices */
+#define CXL_IOCTL_DOWNLOAD_IMAGE        _IOW(CXL_MAGIC, 0x0A, struct cxl_adapter_image)
+#define CXL_IOCTL_VALIDATE_IMAGE        _IOW(CXL_MAGIC, 0x0B, struct cxl_adapter_image)
 
 #define CXL_READ_MIN_SIZE 0x1000 /* 4K */
 
--- zfcpdump-kernel-4.4.orig/include/uapi/scsi/cxlflash_ioctl.h
+++ zfcpdump-kernel-4.4/include/uapi/scsi/cxlflash_ioctl.h
@@ -31,6 +31,16 @@ struct dk_cxlflash_hdr {
 };
 
 /*
+ * Return flag definitions available to all ioctls
+ *
+ * Similar to the input flags, these are grown from the bottom-up with the
+ * intention that ioctl-specific return flag definitions would grow from the
+ * top-down, allowing the two sets to co-exist. While not required/enforced
+ * at this time, this provides future flexibility.
+ */
+#define DK_CXLFLASH_ALL_PORTS_ACTIVE	0x0000000000000001ULL
+
+/*
  * Notes:
  * -----
  * The 'context_id' field of all ioctl structures contains the context
--- zfcpdump-kernel-4.4.orig/include/video/imx-ipu-v3.h
+++ zfcpdump-kernel-4.4/include/video/imx-ipu-v3.h
@@ -16,6 +16,7 @@
 #include <linux/videodev2.h>
 #include <linux/bitmap.h>
 #include <linux/fb.h>
+#include <linux/of.h>
 #include <media/v4l2-mediabus.h>
 #include <video/videomode.h>
 
@@ -344,6 +345,7 @@ struct ipu_client_platformdata {
 	int dc;
 	int dp;
 	int dma[2];
+	struct device_node *of_node;
 };
 
 #endif /* __DRM_IPU_H__ */
--- zfcpdump-kernel-4.4.orig/include/xen/page.h
+++ zfcpdump-kernel-4.4/include/xen/page.h
@@ -15,9 +15,9 @@
  */
 
 #define xen_pfn_to_page(xen_pfn)	\
-	((pfn_to_page(((unsigned long)(xen_pfn) << XEN_PAGE_SHIFT) >> PAGE_SHIFT)))
+	(pfn_to_page((unsigned long)(xen_pfn) >> (PAGE_SHIFT - XEN_PAGE_SHIFT)))
 #define page_to_xen_pfn(page)		\
-	(((page_to_pfn(page)) << PAGE_SHIFT) >> XEN_PAGE_SHIFT)
+	((page_to_pfn(page)) << (PAGE_SHIFT - XEN_PAGE_SHIFT))
 
 #define XEN_PFN_PER_PAGE	(PAGE_SIZE / XEN_PAGE_SIZE)
 
--- zfcpdump-kernel-4.4.orig/init/Kconfig
+++ zfcpdump-kernel-4.4/init/Kconfig
@@ -208,6 +208,15 @@ config DEFAULT_HOSTNAME
 	  but you may wish to use a different default here to make a minimal
 	  system more usable with less configuration.
 
+config VERSION_SIGNATURE
+	string "Arbitrary version signature"
+	help
+	  This string will be created in a file, /proc/version_signature. It
+	  is useful in determining arbitrary data about your kernel. For instance,
+	  if you have several kernels of the same version, but need to keep track
+	  of a revision of the same kernel, but not affect it's ability to load
+	  compatible modules, this is the easiest way to do that.
+
 config SWAP
 	bool "Support for paging of anonymous memory (swap)"
 	depends on MMU && BLOCK
@@ -1795,6 +1804,15 @@ config SYSTEM_DATA_VERIFICATION
 	  module verification, kexec image verification and firmware blob
 	  verification.
 
+config SYSTEM_BLACKLIST_KEYRING
+	bool "Provide system-wide ring of blacklisted keys"
+	depends on KEYS
+	help
+	  Provide a system keyring to which blacklisted keys can be added.
+	  Keys in the keyring are considered entirely untrusted.  Keys in this
+	  keyring are used by the module signature checking to reject loading
+	  of modules signed with a blacklisted key.
+
 config PROFILING
 	bool "Profiling support"
 	help
@@ -1936,6 +1954,15 @@ config MODULE_SIG_ALL
 comment "Do not forget to sign required modules with scripts/sign-file"
 	depends on MODULE_SIG_FORCE && !MODULE_SIG_ALL
 
+config MODULE_SIG_UEFI
+	bool "Allow modules signed with certs stored in UEFI"
+	depends on MODULE_SIG && SYSTEM_BLACKLIST_KEYRING && EFI
+	select EFI_SIGNATURE_LIST_PARSER
+	help
+	  This will import certificates stored in UEFI and allow modules
+	  signed with those to be loaded.  It will also disallow loading
+	  of modules stored in the UEFI dbx variable.
+
 choice
 	prompt "Which hash algorithm should modules be signed with?"
 	depends on MODULE_SIG
--- zfcpdump-kernel-4.4.orig/init/noinitramfs.c
+++ zfcpdump-kernel-4.4/init/noinitramfs.c
@@ -22,6 +22,8 @@
 #include <linux/kdev_t.h>
 #include <linux/syscalls.h>
 
+LIST_HEAD(populate_rootfs_domain);
+
 /*
  * Create a simple rootfs that is similar to the default initramfs
  */
--- zfcpdump-kernel-4.4.orig/init/version.c
+++ zfcpdump-kernel-4.4/init/version.c
@@ -45,7 +45,11 @@ EXPORT_SYMBOL_GPL(init_uts_ns);
 /* FIXED STRINGS! Don't touch! */
 const char linux_banner[] =
 	"Linux version " UTS_RELEASE " (" LINUX_COMPILE_BY "@"
-	LINUX_COMPILE_HOST ") (" LINUX_COMPILER ") " UTS_VERSION "\n";
+	LINUX_COMPILE_HOST ") (" LINUX_COMPILER ") " UTS_VERSION
+#ifdef CONFIG_VERSION_SIGNATURE
+        " (" CONFIG_VERSION_SIGNATURE ")"
+#endif
+	"\n";
 
 const char linux_proc_banner[] =
 	"%s version %s"
--- zfcpdump-kernel-4.4.orig/ipc/mqueue.c
+++ zfcpdump-kernel-4.4/ipc/mqueue.c
@@ -305,8 +305,9 @@ err:
 static int mqueue_fill_super(struct super_block *sb, void *data, int silent)
 {
 	struct inode *inode;
-	struct ipc_namespace *ns = data;
+	struct ipc_namespace *ns = sb->s_fs_info;
 
+	sb->s_iflags |= SB_I_NOEXEC;
 	sb->s_blocksize = PAGE_CACHE_SIZE;
 	sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
 	sb->s_magic = MQUEUE_MAGIC;
@@ -326,17 +327,14 @@ static struct dentry *mqueue_mount(struc
 			 int flags, const char *dev_name,
 			 void *data)
 {
-	if (!(flags & MS_KERNMOUNT)) {
-		struct ipc_namespace *ns = current->nsproxy->ipc_ns;
-		/* Don't allow mounting unless the caller has CAP_SYS_ADMIN
-		 * over the ipc namespace.
-		 */
-		if (!ns_capable(ns->user_ns, CAP_SYS_ADMIN))
-			return ERR_PTR(-EPERM);
-
-		data = ns;
+	struct ipc_namespace *ns;
+	if (flags & MS_KERNMOUNT) {
+		ns = data;
+		data = NULL;
+	} else {
+		ns = current->nsproxy->ipc_ns;
 	}
-	return mount_ns(fs_type, flags, data, mqueue_fill_super);
+	return mount_ns(fs_type, flags, data, ns, ns->user_ns, mqueue_fill_super);
 }
 
 static void init_once(void *foo)
--- zfcpdump-kernel-4.4.orig/ipc/msg.c
+++ zfcpdump-kernel-4.4/ipc/msg.c
@@ -680,7 +680,7 @@ long do_msgsnd(int msqid, long mtype, vo
 		rcu_read_lock();
 		ipc_lock_object(&msq->q_perm);
 
-		ipc_rcu_putref(msq, ipc_rcu_free);
+		ipc_rcu_putref(msq, msg_rcu_free);
 		/* raced with RMID? */
 		if (!ipc_valid_object(&msq->q_perm)) {
 			err = -EIDRM;
--- zfcpdump-kernel-4.4.orig/ipc/namespace.c
+++ zfcpdump-kernel-4.4/ipc/namespace.c
@@ -34,8 +34,11 @@ static struct ipc_namespace *create_ipc_
 	ns->ns.ops = &ipcns_operations;
 
 	atomic_set(&ns->count, 1);
+	ns->user_ns = get_user_ns(user_ns);
+
 	err = mq_init_ns(ns);
 	if (err) {
+		put_user_ns(ns->user_ns);
 		ns_free_inum(&ns->ns);
 		kfree(ns);
 		return ERR_PTR(err);
@@ -46,8 +49,6 @@ static struct ipc_namespace *create_ipc_
 	msg_init_ns(ns);
 	shm_init_ns(ns);
 
-	ns->user_ns = get_user_ns(user_ns);
-
 	return ns;
 }
 
--- zfcpdump-kernel-4.4.orig/ipc/sem.c
+++ zfcpdump-kernel-4.4/ipc/sem.c
@@ -442,7 +442,7 @@ static inline struct sem_array *sem_obta
 static inline void sem_lock_and_putref(struct sem_array *sma)
 {
 	sem_lock(sma, NULL, -1);
-	ipc_rcu_putref(sma, ipc_rcu_free);
+	ipc_rcu_putref(sma, sem_rcu_free);
 }
 
 static inline void sem_rmid(struct ipc_namespace *ns, struct sem_array *s)
@@ -1385,7 +1385,7 @@ static int semctl_main(struct ipc_namesp
 			rcu_read_unlock();
 			sem_io = ipc_alloc(sizeof(ushort)*nsems);
 			if (sem_io == NULL) {
-				ipc_rcu_putref(sma, ipc_rcu_free);
+				ipc_rcu_putref(sma, sem_rcu_free);
 				return -ENOMEM;
 			}
 
@@ -1419,20 +1419,20 @@ static int semctl_main(struct ipc_namesp
 		if (nsems > SEMMSL_FAST) {
 			sem_io = ipc_alloc(sizeof(ushort)*nsems);
 			if (sem_io == NULL) {
-				ipc_rcu_putref(sma, ipc_rcu_free);
+				ipc_rcu_putref(sma, sem_rcu_free);
 				return -ENOMEM;
 			}
 		}
 
 		if (copy_from_user(sem_io, p, nsems*sizeof(ushort))) {
-			ipc_rcu_putref(sma, ipc_rcu_free);
+			ipc_rcu_putref(sma, sem_rcu_free);
 			err = -EFAULT;
 			goto out_free;
 		}
 
 		for (i = 0; i < nsems; i++) {
 			if (sem_io[i] > SEMVMX) {
-				ipc_rcu_putref(sma, ipc_rcu_free);
+				ipc_rcu_putref(sma, sem_rcu_free);
 				err = -ERANGE;
 				goto out_free;
 			}
@@ -1722,7 +1722,7 @@ static struct sem_undo *find_alloc_undo(
 	/* step 2: allocate new undo structure */
 	new = kzalloc(sizeof(struct sem_undo) + sizeof(short)*nsems, GFP_KERNEL);
 	if (!new) {
-		ipc_rcu_putref(sma, ipc_rcu_free);
+		ipc_rcu_putref(sma, sem_rcu_free);
 		return ERR_PTR(-ENOMEM);
 	}
 
@@ -1984,6 +1984,14 @@ sleep_again:
 	error = get_queue_result(&queue);
 
 	/*
+	 * wake_up_sem_queue_do operates on queue without locking, so we
+	 * need a barrier here to order our read of queue.status and the
+	 * subsequent reuse of queue (queue is on the stack so will be
+	 * most likely reused in the next function call).
+	 */
+	smp_mb();
+
+	/*
 	 * Array removed? If yes, leave without sem_unlock().
 	 */
 	if (IS_ERR(sma)) {
--- zfcpdump-kernel-4.4.orig/ipc/shm.c
+++ zfcpdump-kernel-4.4/ipc/shm.c
@@ -156,11 +156,12 @@ static inline struct shmid_kernel *shm_l
 	struct kern_ipc_perm *ipcp = ipc_lock(&shm_ids(ns), id);
 
 	/*
-	 * We raced in the idr lookup or with shm_destroy().  Either way, the
-	 * ID is busted.
+	 * Callers of shm_lock() must validate the status of the returned ipc
+	 * object pointer (as returned by ipc_lock()), and error out as
+	 * appropriate.
 	 */
-	WARN_ON(IS_ERR(ipcp));
-
+	if (IS_ERR(ipcp))
+		return (void *)ipcp;
 	return container_of(ipcp, struct shmid_kernel, shm_perm);
 }
 
@@ -186,18 +187,33 @@ static inline void shm_rmid(struct ipc_n
 }
 
 
-/* This is called by fork, once for every shm attach. */
-static void shm_open(struct vm_area_struct *vma)
+static int __shm_open(struct vm_area_struct *vma)
 {
 	struct file *file = vma->vm_file;
 	struct shm_file_data *sfd = shm_file_data(file);
 	struct shmid_kernel *shp;
 
 	shp = shm_lock(sfd->ns, sfd->id);
+
+	if (IS_ERR(shp))
+		return PTR_ERR(shp);
+
 	shp->shm_atim = get_seconds();
 	shp->shm_lprid = task_tgid_vnr(current);
 	shp->shm_nattch++;
 	shm_unlock(shp);
+	return 0;
+}
+
+/* This is called by fork, once for every shm attach. */
+static void shm_open(struct vm_area_struct *vma)
+{
+	int err = __shm_open(vma);
+	/*
+	 * We raced in the idr lookup or with shm_destroy().
+	 * Either way, the ID is busted.
+	 */
+	WARN_ON_ONCE(err);
 }
 
 /*
@@ -260,6 +276,14 @@ static void shm_close(struct vm_area_str
 	down_write(&shm_ids(ns).rwsem);
 	/* remove from the list of attaches of the shm segment */
 	shp = shm_lock(ns, sfd->id);
+
+	/*
+	 * We raced in the idr lookup or with shm_destroy().
+	 * Either way, the ID is busted.
+	 */
+	if (WARN_ON_ONCE(IS_ERR(shp)))
+		goto done; /* no-op */
+
 	shp->shm_lprid = task_tgid_vnr(current);
 	shp->shm_dtim = get_seconds();
 	shp->shm_nattch--;
@@ -267,6 +291,7 @@ static void shm_close(struct vm_area_str
 		shm_destroy(ns, shp);
 	else
 		shm_unlock(shp);
+done:
 	up_write(&shm_ids(ns).rwsem);
 }
 
@@ -388,17 +413,25 @@ static int shm_mmap(struct file *file, s
 	struct shm_file_data *sfd = shm_file_data(file);
 	int ret;
 
+	/*
+	 * In case of remap_file_pages() emulation, the file can represent
+	 * removed IPC ID: propogate shm_lock() error to caller.
+	 */
+	ret =__shm_open(vma);
+	if (ret)
+		return ret;
+
 	ret = sfd->file->f_op->mmap(sfd->file, vma);
-	if (ret != 0)
+	if (ret) {
+		shm_close(vma);
 		return ret;
+	}
 	sfd->vm_ops = vma->vm_ops;
 #ifdef CONFIG_MMU
 	WARN_ON(!sfd->vm_ops->fault);
 #endif
 	vma->vm_ops = &shm_vm_ops;
-	shm_open(vma);
-
-	return ret;
+	return 0;
 }
 
 static int shm_release(struct inode *ino, struct file *file)
--- zfcpdump-kernel-4.4.orig/kernel/Makefile
+++ zfcpdump-kernel-4.4/kernel/Makefile
@@ -47,6 +47,7 @@ endif
 obj-$(CONFIG_UID16) += uid16.o
 obj-$(CONFIG_MODULES) += module.o
 obj-$(CONFIG_MODULE_SIG) += module_signing.o
+obj-$(CONFIG_MODULE_SIG_UEFI) += modsign_uefi.o
 obj-$(CONFIG_KALLSYMS) += kallsyms.o
 obj-$(CONFIG_BSD_PROCESS_ACCT) += acct.o
 obj-$(CONFIG_KEXEC_CORE) += kexec_core.o
@@ -104,6 +105,8 @@ obj-$(CONFIG_MEMBARRIER) += membarrier.o
 
 obj-$(CONFIG_HAS_IOMEM) += memremap.o
 
+$(obj)/modsign_uefi.o: KBUILD_CFLAGS += -fshort-wchar
+
 $(obj)/configs.o: $(obj)/config_data.h
 
 # config_data.h contains the same information as ikconfig.h but gzipped.
--- zfcpdump-kernel-4.4.orig/kernel/async.c
+++ zfcpdump-kernel-4.4/kernel/async.c
@@ -326,3 +326,4 @@ bool current_is_async(void)
 
 	return worker && worker->current_func == async_run_entry_fn;
 }
+EXPORT_SYMBOL_GPL(current_is_async);
--- zfcpdump-kernel-4.4.orig/kernel/audit_watch.c
+++ zfcpdump-kernel-4.4/kernel/audit_watch.c
@@ -19,6 +19,7 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
+#include <linux/file.h>
 #include <linux/kernel.h>
 #include <linux/audit.h>
 #include <linux/kthread.h>
@@ -544,10 +545,11 @@ int audit_exe_compare(struct task_struct
 	unsigned long ino;
 	dev_t dev;
 
-	rcu_read_lock();
-	exe_file = rcu_dereference(tsk->mm->exe_file);
+	exe_file = get_task_exe_file(tsk);
+	if (!exe_file)
+		return 0;
 	ino = exe_file->f_inode->i_ino;
 	dev = exe_file->f_inode->i_sb->s_dev;
-	rcu_read_unlock();
+	fput(exe_file);
 	return audit_mark_compare(mark, ino, dev);
 }
--- zfcpdump-kernel-4.4.orig/kernel/auditsc.c
+++ zfcpdump-kernel-4.4/kernel/auditsc.c
@@ -73,6 +73,7 @@
 #include <linux/compat.h>
 #include <linux/ctype.h>
 #include <linux/string.h>
+#include <linux/uaccess.h>
 #include <uapi/linux/limits.h>
 
 #include "audit.h"
@@ -82,7 +83,8 @@
 #define AUDITSC_SUCCESS 1
 #define AUDITSC_FAILURE 2
 
-/* no execve audit message should be longer than this (userspace limits) */
+/* no execve audit message should be longer than this (userspace limits),
+ * see the note near the top of audit_log_execve_info() about this value */
 #define MAX_EXECVE_AUDIT_LEN 7500
 
 /* max length to print of cmdline/proctitle value during audit */
@@ -988,184 +990,178 @@ static int audit_log_pid_context(struct
 	return rc;
 }
 
-/*
- * to_send and len_sent accounting are very loose estimates.  We aren't
- * really worried about a hard cap to MAX_EXECVE_AUDIT_LEN so much as being
- * within about 500 bytes (next page boundary)
- *
- * why snprintf?  an int is up to 12 digits long.  if we just assumed when
- * logging that a[%d]= was going to be 16 characters long we would be wasting
- * space in every audit message.  In one 7500 byte message we can log up to
- * about 1000 min size arguments.  That comes down to about 50% waste of space
- * if we didn't do the snprintf to find out how long arg_num_len was.
- */
-static int audit_log_single_execve_arg(struct audit_context *context,
-					struct audit_buffer **ab,
-					int arg_num,
-					size_t *len_sent,
-					const char __user *p,
-					char *buf)
-{
-	char arg_num_len_buf[12];
-	const char __user *tmp_p = p;
-	/* how many digits are in arg_num? 5 is the length of ' a=""' */
-	size_t arg_num_len = snprintf(arg_num_len_buf, 12, "%d", arg_num) + 5;
-	size_t len, len_left, to_send;
-	size_t max_execve_audit_len = MAX_EXECVE_AUDIT_LEN;
-	unsigned int i, has_cntl = 0, too_long = 0;
-	int ret;
-
-	/* strnlen_user includes the null we don't want to send */
-	len_left = len = strnlen_user(p, MAX_ARG_STRLEN) - 1;
+static void audit_log_execve_info(struct audit_context *context,
+				  struct audit_buffer **ab)
+{
+	long len_max;
+	long len_rem;
+	long len_full;
+	long len_buf;
+	long len_abuf;
+	long len_tmp;
+	bool require_data;
+	bool encode;
+	unsigned int iter;
+	unsigned int arg;
+	char *buf_head;
+	char *buf;
+	const char __user *p = (const char __user *)current->mm->arg_start;
 
-	/*
-	 * We just created this mm, if we can't find the strings
-	 * we just copied into it something is _very_ wrong. Similar
-	 * for strings that are too long, we should not have created
-	 * any.
-	 */
-	if (WARN_ON_ONCE(len < 0 || len > MAX_ARG_STRLEN - 1)) {
-		send_sig(SIGKILL, current, 0);
-		return -1;
+	/* NOTE: this buffer needs to be large enough to hold all the non-arg
+	 *       data we put in the audit record for this argument (see the
+	 *       code below) ... at this point in time 96 is plenty */
+	char abuf[96];
+
+	/* NOTE: we set MAX_EXECVE_AUDIT_LEN to a rather arbitrary limit, the
+	 *       current value of 7500 is not as important as the fact that it
+	 *       is less than 8k, a setting of 7500 gives us plenty of wiggle
+	 *       room if we go over a little bit in the logging below */
+	WARN_ON_ONCE(MAX_EXECVE_AUDIT_LEN > 7500);
+	len_max = MAX_EXECVE_AUDIT_LEN;
+
+	/* scratch buffer to hold the userspace args */
+	buf_head = kmalloc(MAX_EXECVE_AUDIT_LEN + 1, GFP_KERNEL);
+	if (!buf_head) {
+		audit_panic("out of memory for argv string");
+		return;
 	}
+	buf = buf_head;
+
+	audit_log_format(*ab, "argc=%d", context->execve.argc);
 
-	/* walk the whole argument looking for non-ascii chars */
+	len_rem = len_max;
+	len_buf = 0;
+	len_full = 0;
+	require_data = true;
+	encode = false;
+	iter = 0;
+	arg = 0;
 	do {
-		if (len_left > MAX_EXECVE_AUDIT_LEN)
-			to_send = MAX_EXECVE_AUDIT_LEN;
-		else
-			to_send = len_left;
-		ret = copy_from_user(buf, tmp_p, to_send);
-		/*
-		 * There is no reason for this copy to be short. We just
-		 * copied them here, and the mm hasn't been exposed to user-
-		 * space yet.
-		 */
-		if (ret) {
-			WARN_ON(1);
-			send_sig(SIGKILL, current, 0);
-			return -1;
-		}
-		buf[to_send] = '\0';
-		has_cntl = audit_string_contains_control(buf, to_send);
-		if (has_cntl) {
-			/*
-			 * hex messages get logged as 2 bytes, so we can only
-			 * send half as much in each message
-			 */
-			max_execve_audit_len = MAX_EXECVE_AUDIT_LEN / 2;
-			break;
-		}
-		len_left -= to_send;
-		tmp_p += to_send;
-	} while (len_left > 0);
-
-	len_left = len;
-
-	if (len > max_execve_audit_len)
-		too_long = 1;
-
-	/* rewalk the argument actually logging the message */
-	for (i = 0; len_left > 0; i++) {
-		int room_left;
-
-		if (len_left > max_execve_audit_len)
-			to_send = max_execve_audit_len;
-		else
-			to_send = len_left;
-
-		/* do we have space left to send this argument in this ab? */
-		room_left = MAX_EXECVE_AUDIT_LEN - arg_num_len - *len_sent;
-		if (has_cntl)
-			room_left -= (to_send * 2);
-		else
-			room_left -= to_send;
-		if (room_left < 0) {
-			*len_sent = 0;
-			audit_log_end(*ab);
-			*ab = audit_log_start(context, GFP_KERNEL, AUDIT_EXECVE);
-			if (!*ab)
-				return 0;
-		}
+		/* NOTE: we don't ever want to trust this value for anything
+		 *       serious, but the audit record format insists we
+		 *       provide an argument length for really long arguments,
+		 *       e.g. > MAX_EXECVE_AUDIT_LEN, so we have no choice but
+		 *       to use strncpy_from_user() to obtain this value for
+		 *       recording in the log, although we don't use it
+		 *       anywhere here to avoid a double-fetch problem */
+		if (len_full == 0)
+			len_full = strnlen_user(p, MAX_ARG_STRLEN) - 1;
+
+		/* read more data from userspace */
+		if (require_data) {
+			/* can we make more room in the buffer? */
+			if (buf != buf_head) {
+				memmove(buf_head, buf, len_buf);
+				buf = buf_head;
+			}
 
-		/*
-		 * first record needs to say how long the original string was
-		 * so we can be sure nothing was lost.
-		 */
-		if ((i == 0) && (too_long))
-			audit_log_format(*ab, " a%d_len=%zu", arg_num,
-					 has_cntl ? 2*len : len);
-
-		/*
-		 * normally arguments are small enough to fit and we already
-		 * filled buf above when we checked for control characters
-		 * so don't bother with another copy_from_user
-		 */
-		if (len >= max_execve_audit_len)
-			ret = copy_from_user(buf, p, to_send);
-		else
-			ret = 0;
-		if (ret) {
-			WARN_ON(1);
-			send_sig(SIGKILL, current, 0);
-			return -1;
-		}
-		buf[to_send] = '\0';
+			/* fetch as much as we can of the argument */
+			len_tmp = strncpy_from_user(&buf_head[len_buf], p,
+						    len_max - len_buf);
+			if (len_tmp == -EFAULT) {
+				/* unable to copy from userspace */
+				send_sig(SIGKILL, current, 0);
+				goto out;
+			} else if (len_tmp == (len_max - len_buf)) {
+				/* buffer is not large enough */
+				require_data = true;
+				/* NOTE: if we are going to span multiple
+				 *       buffers force the encoding so we stand
+				 *       a chance at a sane len_full value and
+				 *       consistent record encoding */
+				encode = true;
+				len_full = len_full * 2;
+				p += len_tmp;
+			} else {
+				require_data = false;
+				if (!encode)
+					encode = audit_string_contains_control(
+								buf, len_tmp);
+				/* try to use a trusted value for len_full */
+				if (len_full < len_max)
+					len_full = (encode ?
+						    len_tmp * 2 : len_tmp);
+				p += len_tmp + 1;
+			}
+			len_buf += len_tmp;
+			buf_head[len_buf] = '\0';
 
-		/* actually log it */
-		audit_log_format(*ab, " a%d", arg_num);
-		if (too_long)
-			audit_log_format(*ab, "[%d]", i);
-		audit_log_format(*ab, "=");
-		if (has_cntl)
-			audit_log_n_hex(*ab, buf, to_send);
-		else
-			audit_log_string(*ab, buf);
-
-		p += to_send;
-		len_left -= to_send;
-		*len_sent += arg_num_len;
-		if (has_cntl)
-			*len_sent += to_send * 2;
-		else
-			*len_sent += to_send;
-	}
-	/* include the null we didn't log */
-	return len + 1;
-}
+			/* length of the buffer in the audit record? */
+			len_abuf = (encode ? len_buf * 2 : len_buf + 2);
+		}
 
-static void audit_log_execve_info(struct audit_context *context,
-				  struct audit_buffer **ab)
-{
-	int i, len;
-	size_t len_sent = 0;
-	const char __user *p;
-	char *buf;
+		/* write as much as we can to the audit log */
+		if (len_buf > 0) {
+			/* NOTE: some magic numbers here - basically if we
+			 *       can't fit a reasonable amount of data into the
+			 *       existing audit buffer, flush it and start with
+			 *       a new buffer */
+			if ((sizeof(abuf) + 8) > len_rem) {
+				len_rem = len_max;
+				audit_log_end(*ab);
+				*ab = audit_log_start(context,
+						      GFP_KERNEL, AUDIT_EXECVE);
+				if (!*ab)
+					goto out;
+			}
 
-	p = (const char __user *)current->mm->arg_start;
+			/* create the non-arg portion of the arg record */
+			len_tmp = 0;
+			if (require_data || (iter > 0) ||
+			    ((len_abuf + sizeof(abuf)) > len_rem)) {
+				if (iter == 0) {
+					len_tmp += snprintf(&abuf[len_tmp],
+							sizeof(abuf) - len_tmp,
+							" a%d_len=%lu",
+							arg, len_full);
+				}
+				len_tmp += snprintf(&abuf[len_tmp],
+						    sizeof(abuf) - len_tmp,
+						    " a%d[%d]=", arg, iter++);
+			} else
+				len_tmp += snprintf(&abuf[len_tmp],
+						    sizeof(abuf) - len_tmp,
+						    " a%d=", arg);
+			WARN_ON(len_tmp >= sizeof(abuf));
+			abuf[sizeof(abuf) - 1] = '\0';
+
+			/* log the arg in the audit record */
+			audit_log_format(*ab, "%s", abuf);
+			len_rem -= len_tmp;
+			len_tmp = len_buf;
+			if (encode) {
+				if (len_abuf > len_rem)
+					len_tmp = len_rem / 2; /* encoding */
+				audit_log_n_hex(*ab, buf, len_tmp);
+				len_rem -= len_tmp * 2;
+				len_abuf -= len_tmp * 2;
+			} else {
+				if (len_abuf > len_rem)
+					len_tmp = len_rem - 2; /* quotes */
+				audit_log_n_string(*ab, buf, len_tmp);
+				len_rem -= len_tmp + 2;
+				/* don't subtract the "2" because we still need
+				 * to add quotes to the remaining string */
+				len_abuf -= len_tmp;
+			}
+			len_buf -= len_tmp;
+			buf += len_tmp;
+		}
 
-	audit_log_format(*ab, "argc=%d", context->execve.argc);
+		/* ready to move to the next argument? */
+		if ((len_buf == 0) && !require_data) {
+			arg++;
+			iter = 0;
+			len_full = 0;
+			require_data = true;
+			encode = false;
+		}
+	} while (arg < context->execve.argc);
 
-	/*
-	 * we need some kernel buffer to hold the userspace args.  Just
-	 * allocate one big one rather than allocating one of the right size
-	 * for every single argument inside audit_log_single_execve_arg()
-	 * should be <8k allocation so should be pretty safe.
-	 */
-	buf = kmalloc(MAX_EXECVE_AUDIT_LEN + 1, GFP_KERNEL);
-	if (!buf) {
-		audit_panic("out of memory for argv string");
-		return;
-	}
+	/* NOTE: the caller handles the final audit_log_end() call */
 
-	for (i = 0; i < context->execve.argc; i++) {
-		len = audit_log_single_execve_arg(context, ab, i,
-						  &len_sent, p, buf);
-		if (len <= 0)
-			break;
-		p += len;
-	}
-	kfree(buf);
+out:
+	kfree(buf_head);
 }
 
 static void show_special(struct audit_context *context, int *call_panic)
--- zfcpdump-kernel-4.4.orig/kernel/bpf/helpers.c
+++ zfcpdump-kernel-4.4/kernel/bpf/helpers.c
@@ -166,7 +166,7 @@ static u64 bpf_get_current_comm(u64 r1,
 	if (!task)
 		return -EINVAL;
 
-	memcpy(buf, task->comm, min_t(size_t, size, sizeof(task->comm)));
+	strlcpy(buf, task->comm, min_t(size_t, size, sizeof(task->comm)));
 	return 0;
 }
 
--- zfcpdump-kernel-4.4.orig/kernel/bpf/inode.c
+++ zfcpdump-kernel-4.4/kernel/bpf/inode.c
@@ -31,10 +31,10 @@ static void *bpf_any_get(void *raw, enum
 {
 	switch (type) {
 	case BPF_TYPE_PROG:
-		atomic_inc(&((struct bpf_prog *)raw)->aux->refcnt);
+		raw = bpf_prog_inc(raw);
 		break;
 	case BPF_TYPE_MAP:
-		bpf_map_inc(raw, true);
+		raw = bpf_map_inc(raw, true);
 		break;
 	default:
 		WARN_ON_ONCE(1);
@@ -277,7 +277,8 @@ static void *bpf_obj_do_get(const struct
 		goto out;
 
 	raw = bpf_any_get(inode->i_private, *type);
-	touch_atime(&path);
+	if (!IS_ERR(raw))
+		touch_atime(&path);
 
 	path_put(&path);
 	return raw;
@@ -357,7 +358,7 @@ static int bpf_fill_super(struct super_b
 static struct dentry *bpf_mount(struct file_system_type *type, int flags,
 				const char *dev_name, void *data)
 {
-	return mount_ns(type, flags, current->nsproxy->mnt_ns, bpf_fill_super);
+	return mount_nodev(type, flags, data, bpf_fill_super);
 }
 
 static struct file_system_type bpf_fs_type = {
@@ -365,7 +366,6 @@ static struct file_system_type bpf_fs_ty
 	.name		= "bpf",
 	.mount		= bpf_mount,
 	.kill_sb	= kill_litter_super,
-	.fs_flags	= FS_USERNS_MOUNT,
 };
 
 MODULE_ALIAS_FS("bpf");
--- zfcpdump-kernel-4.4.orig/kernel/bpf/syscall.c
+++ zfcpdump-kernel-4.4/kernel/bpf/syscall.c
@@ -181,11 +181,18 @@ struct bpf_map *__bpf_map_get(struct fd
 	return f.file->private_data;
 }
 
-void bpf_map_inc(struct bpf_map *map, bool uref)
+/* prog's and map's refcnt limit */
+#define BPF_MAX_REFCNT 32768
+
+struct bpf_map *bpf_map_inc(struct bpf_map *map, bool uref)
 {
-	atomic_inc(&map->refcnt);
+	if (atomic_inc_return(&map->refcnt) > BPF_MAX_REFCNT) {
+		atomic_dec(&map->refcnt);
+		return ERR_PTR(-EBUSY);
+	}
 	if (uref)
 		atomic_inc(&map->usercnt);
+	return map;
 }
 
 struct bpf_map *bpf_map_get_with_uref(u32 ufd)
@@ -197,7 +204,7 @@ struct bpf_map *bpf_map_get_with_uref(u3
 	if (IS_ERR(map))
 		return map;
 
-	bpf_map_inc(map, true);
+	map = bpf_map_inc(map, true);
 	fdput(f);
 
 	return map;
@@ -580,6 +587,15 @@ static struct bpf_prog *__bpf_prog_get(s
 	return f.file->private_data;
 }
 
+struct bpf_prog *bpf_prog_inc(struct bpf_prog *prog)
+{
+	if (atomic_inc_return(&prog->aux->refcnt) > BPF_MAX_REFCNT) {
+		atomic_dec(&prog->aux->refcnt);
+		return ERR_PTR(-EBUSY);
+	}
+	return prog;
+}
+
 /* called by sockets/tracing/seccomp before attaching program to an event
  * pairs with bpf_prog_put()
  */
@@ -592,7 +608,7 @@ struct bpf_prog *bpf_prog_get(u32 ufd)
 	if (IS_ERR(prog))
 		return prog;
 
-	atomic_inc(&prog->aux->refcnt);
+	prog = bpf_prog_inc(prog);
 	fdput(f);
 
 	return prog;
--- zfcpdump-kernel-4.4.orig/kernel/bpf/verifier.c
+++ zfcpdump-kernel-4.4/kernel/bpf/verifier.c
@@ -239,15 +239,6 @@ static const char * const reg_type_str[]
 	[CONST_IMM]		= "imm",
 };
 
-static const struct {
-	int map_type;
-	int func_id;
-} func_limit[] = {
-	{BPF_MAP_TYPE_PROG_ARRAY, BPF_FUNC_tail_call},
-	{BPF_MAP_TYPE_PERF_EVENT_ARRAY, BPF_FUNC_perf_event_read},
-	{BPF_MAP_TYPE_PERF_EVENT_ARRAY, BPF_FUNC_perf_event_output},
-};
-
 static void print_verifier_state(struct verifier_env *env)
 {
 	enum bpf_reg_type t;
@@ -898,24 +889,44 @@ static int check_func_arg(struct verifie
 
 static int check_map_func_compatibility(struct bpf_map *map, int func_id)
 {
-	bool bool_map, bool_func;
-	int i;
-
 	if (!map)
 		return 0;
 
-	for (i = 0; i < ARRAY_SIZE(func_limit); i++) {
-		bool_map = (map->map_type == func_limit[i].map_type);
-		bool_func = (func_id == func_limit[i].func_id);
-		/* only when map & func pair match it can continue.
-		 * don't allow any other map type to be passed into
-		 * the special func;
-		 */
-		if (bool_func && bool_map != bool_func)
-			return -EINVAL;
+	/* We need a two way check, first is from map perspective ... */
+	switch (map->map_type) {
+	case BPF_MAP_TYPE_PROG_ARRAY:
+		if (func_id != BPF_FUNC_tail_call)
+			goto error;
+		break;
+	case BPF_MAP_TYPE_PERF_EVENT_ARRAY:
+		if (func_id != BPF_FUNC_perf_event_read &&
+		    func_id != BPF_FUNC_perf_event_output)
+			goto error;
+		break;
+	default:
+		break;
+	}
+
+	/* ... and second from the function itself. */
+	switch (func_id) {
+	case BPF_FUNC_tail_call:
+		if (map->map_type != BPF_MAP_TYPE_PROG_ARRAY)
+			goto error;
+		break;
+	case BPF_FUNC_perf_event_read:
+	case BPF_FUNC_perf_event_output:
+		if (map->map_type != BPF_MAP_TYPE_PERF_EVENT_ARRAY)
+			goto error;
+		break;
+	default:
+		break;
 	}
 
 	return 0;
+error:
+	verbose("cannot pass map_type %d into func %d\n",
+		map->map_type, func_id);
+	return -EINVAL;
 }
 
 static int check_call(struct verifier_env *env, int func_id)
@@ -1121,6 +1132,16 @@ static int check_alu_op(struct verifier_
 			return -EINVAL;
 		}
 
+		if ((opcode == BPF_LSH || opcode == BPF_RSH ||
+		     opcode == BPF_ARSH) && BPF_SRC(insn->code) == BPF_K) {
+			int size = BPF_CLASS(insn->code) == BPF_ALU64 ? 64 : 32;
+
+			if (insn->imm < 0 || insn->imm >= size) {
+				verbose("invalid shift %d\n", insn->imm);
+				return -EINVAL;
+			}
+		}
+
 		/* pattern match 'bpf_add Rx, imm' instruction */
 		if (opcode == BPF_ADD && BPF_CLASS(insn->code) == BPF_ALU64 &&
 		    regs[insn->dst_reg].type == FRAME_PTR &&
@@ -1338,6 +1359,7 @@ static int check_ld_abs(struct verifier_
 	}
 
 	if (insn->dst_reg != BPF_REG_0 || insn->off != 0 ||
+	    BPF_SIZE(insn->code) == BPF_DW ||
 	    (mode == BPF_ABS && insn->src_reg != BPF_REG_0)) {
 		verbose("BPF_LD_ABS uses reserved fields\n");
 		return -EINVAL;
@@ -1993,7 +2015,6 @@ static int replace_map_fd_with_map_ptr(s
 			if (IS_ERR(map)) {
 				verbose("fd %d is not pointing to valid bpf_map\n",
 					insn->imm);
-				fdput(f);
 				return PTR_ERR(map);
 			}
 
@@ -2013,15 +2034,18 @@ static int replace_map_fd_with_map_ptr(s
 				return -E2BIG;
 			}
 
-			/* remember this map */
-			env->used_maps[env->used_map_cnt++] = map;
-
 			/* hold the map. If the program is rejected by verifier,
 			 * the map will be released by release_maps() or it
 			 * will be used by the valid program until it's unloaded
 			 * and all maps are released in free_bpf_prog_info()
 			 */
-			bpf_map_inc(map, false);
+			map = bpf_map_inc(map, false);
+			if (IS_ERR(map)) {
+				fdput(f);
+				return PTR_ERR(map);
+			}
+			env->used_maps[env->used_map_cnt++] = map;
+
 			fdput(f);
 next_insn:
 			insn++;
@@ -2072,7 +2096,7 @@ static void adjust_branches(struct bpf_p
 		/* adjust offset of jmps if necessary */
 		if (i < pos && i + insn->off + 1 > pos)
 			insn->off += delta;
-		else if (i > pos && i + insn->off + 1 < pos)
+		else if (i > pos + delta && i + insn->off + 1 <= pos + delta)
 			insn->off -= delta;
 	}
 }
--- zfcpdump-kernel-4.4.orig/kernel/capability.c
+++ zfcpdump-kernel-4.4/kernel/capability.c
@@ -361,6 +361,24 @@ bool has_capability_noaudit(struct task_
 	return has_ns_capability_noaudit(t, &init_user_ns, cap);
 }
 
+static bool ns_capable_common(struct user_namespace *ns, int cap, bool audit)
+{
+	int capable;
+
+	if (unlikely(!cap_valid(cap))) {
+		pr_crit("capable() called with invalid cap=%u\n", cap);
+		BUG();
+	}
+
+	capable = audit ? security_capable(current_cred(), ns, cap) :
+			  security_capable_noaudit(current_cred(), ns, cap);
+	if (capable == 0) {
+		current->flags |= PF_SUPERPRIV;
+		return true;
+	}
+	return false;
+}
+
 /**
  * ns_capable - Determine if the current task has a superior capability in effect
  * @ns:  The usernamespace we want the capability in
@@ -374,19 +392,27 @@ bool has_capability_noaudit(struct task_
  */
 bool ns_capable(struct user_namespace *ns, int cap)
 {
-	if (unlikely(!cap_valid(cap))) {
-		pr_crit("capable() called with invalid cap=%u\n", cap);
-		BUG();
-	}
-
-	if (security_capable(current_cred(), ns, cap) == 0) {
-		current->flags |= PF_SUPERPRIV;
-		return true;
-	}
-	return false;
+	return ns_capable_common(ns, cap, true);
 }
 EXPORT_SYMBOL(ns_capable);
 
+/**
+ * ns_capable_noaudit - Determine if the current task has a superior capability
+ * (unaudited) in effect
+ * @ns:  The usernamespace we want the capability in
+ * @cap: The capability to be tested for
+ *
+ * Return true if the current task has the given superior capability currently
+ * available for use, false if not.
+ *
+ * This sets PF_SUPERPRIV on the task if the capability is available on the
+ * assumption that it's about to be used.
+ */
+bool ns_capable_noaudit(struct user_namespace *ns, int cap)
+{
+	return ns_capable_common(ns, cap, false);
+}
+EXPORT_SYMBOL(ns_capable_noaudit);
 
 /**
  * capable - Determine if the current task has a superior capability in effect
--- zfcpdump-kernel-4.4.orig/kernel/cgroup.c
+++ zfcpdump-kernel-4.4/kernel/cgroup.c
@@ -57,8 +57,12 @@
 #include <linux/vmalloc.h> /* TODO: replace with more sophisticated array */
 #include <linux/kthread.h>
 #include <linux/delay.h>
-
+#include <linux/cpuset.h>
 #include <linux/atomic.h>
+#include <linux/cpuset.h>
+#include <linux/nsproxy.h>
+#include <linux/proc_ns.h>
+#include <net/sock.h>
 
 /*
  * pidlists linger the following amount before being destroyed.  The goal
@@ -208,6 +212,15 @@ static unsigned long have_fork_callback
 static unsigned long have_exit_callback __read_mostly;
 static unsigned long have_free_callback __read_mostly;
 
+/* Cgroup namespace for init task */
+struct cgroup_namespace init_cgroup_ns = {
+	.count		= { .counter = 2, },
+	.user_ns	= &init_user_ns,
+	.ns.ops		= &cgroupns_operations,
+	.ns.inum	= PROC_CGROUP_INIT_INO,
+	.root_cset	= &init_css_set,
+};
+
 /* Ditto for the can_fork callback. */
 static unsigned long have_canfork_callback __read_mostly;
 
@@ -1159,6 +1172,41 @@ static void cgroup_destroy_root(struct c
 	cgroup_free_root(root);
 }
 
+/*
+ * look up cgroup associated with current task's cgroup namespace on the
+ * specified hierarchy
+ */
+static struct cgroup *
+current_cgns_cgroup_from_root(struct cgroup_root *root)
+{
+	struct cgroup *res = NULL;
+	struct css_set *cset;
+
+	lockdep_assert_held(&css_set_lock);
+
+	rcu_read_lock();
+
+	cset = current->nsproxy->cgroup_ns->root_cset;
+	if (cset == &init_css_set) {
+		res = &root->cgrp;
+	} else {
+		struct cgrp_cset_link *link;
+
+		list_for_each_entry(link, &cset->cgrp_links, cgrp_link) {
+			struct cgroup *c = link->cgrp;
+
+			if (c->root == root) {
+				res = c;
+				break;
+			}
+		}
+	}
+	rcu_read_unlock();
+
+	BUG_ON(!res);
+	return res;
+}
+
 /* look up cgroup associated with given css_set on the specified hierarchy */
 static struct cgroup *cset_cgroup_from_root(struct css_set *cset,
 					    struct cgroup_root *root)
@@ -1576,6 +1624,33 @@ static int rebind_subsystems(struct cgro
 	return 0;
 }
 
+static int cgroup_show_path(struct seq_file *sf, struct kernfs_node *kf_node,
+			    struct kernfs_root *kf_root)
+{
+	int len = 0;
+	char *buf = NULL;
+	struct cgroup_root *kf_cgroot = cgroup_root_from_kf(kf_root);
+	struct cgroup *ns_cgroup;
+
+	buf = kmalloc(PATH_MAX, GFP_KERNEL);
+	if (!buf)
+		return -ENOMEM;
+
+	spin_lock_bh(&css_set_lock);
+	ns_cgroup = current_cgns_cgroup_from_root(kf_cgroot);
+	len = kernfs_path_from_node(kf_node, ns_cgroup->kn, buf, PATH_MAX);
+	spin_unlock_bh(&css_set_lock);
+
+	if (len >= PATH_MAX)
+		len = -ERANGE;
+	else if (len > 0) {
+		seq_escape(sf, buf, " \t\n\\");
+		len = 0;
+	}
+	kfree(buf);
+	return len;
+}
+
 static int cgroup_show_options(struct seq_file *seq,
 			       struct kernfs_root *kf_root)
 {
@@ -2005,6 +2080,7 @@ static struct dentry *cgroup_mount(struc
 			 void *data)
 {
 	struct super_block *pinned_sb = NULL;
+	struct cgroup_namespace *ns = current->nsproxy->cgroup_ns;
 	struct cgroup_subsys *ss;
 	struct cgroup_root *root;
 	struct cgroup_sb_opts opts;
@@ -2013,6 +2089,14 @@ static struct dentry *cgroup_mount(struc
 	int i;
 	bool new_sb;
 
+	get_cgroup_ns(ns);
+
+	/* Check if the caller has permission to mount. */
+	if (!ns_capable(ns->user_ns, CAP_SYS_ADMIN)) {
+		put_cgroup_ns(ns);
+		return ERR_PTR(-EPERM);
+	}
+
 	/*
 	 * The first time anyone tries to mount a cgroup, enable the list
 	 * linking each css_set to its tasks and fix up all existing tasks.
@@ -2126,6 +2210,16 @@ static struct dentry *cgroup_mount(struc
 		goto out_unlock;
 	}
 
+	/*
+	 * We know this subsystem has not yet been bound.  Users in a non-init
+	 * user namespace may only mount hierarchies with no bound subsystems,
+	 * i.e. 'none,name=user1'
+	 */
+	if (!opts.none && !capable(CAP_SYS_ADMIN)) {
+		ret = -EPERM;
+		goto out_unlock;
+	}
+
 	root = kzalloc(sizeof(*root), GFP_KERNEL);
 	if (!root) {
 		ret = -ENOMEM;
@@ -2144,11 +2238,36 @@ out_free:
 	kfree(opts.release_agent);
 	kfree(opts.name);
 
-	if (ret)
+	if (ret) {
+		put_cgroup_ns(ns);
 		return ERR_PTR(ret);
+	}
 
 	dentry = kernfs_mount(fs_type, flags, root->kf_root,
-				CGROUP_SUPER_MAGIC, &new_sb);
+			      CGROUP_SUPER_MAGIC, &new_sb);
+
+	/*
+	 * In non-init cgroup namespace, instead of root cgroup's
+	 * dentry, we return the dentry corresponding to the
+	 * cgroupns->root_cgrp.
+	 */
+	if (!IS_ERR(dentry) && ns != &init_cgroup_ns) {
+		struct dentry *nsdentry;
+		struct cgroup *cgrp;
+
+		mutex_lock(&cgroup_mutex);
+		spin_lock_bh(&css_set_lock);
+
+		cgrp = cset_cgroup_from_root(ns->root_cset, root);
+
+		spin_unlock_bh(&css_set_lock);
+		mutex_unlock(&cgroup_mutex);
+
+		nsdentry = kernfs_node_dentry(cgrp->kn, dentry->d_sb);
+		dput(dentry);
+		dentry = nsdentry;
+	}
+
 	if (IS_ERR(dentry) || !new_sb)
 		cgroup_put(&root->cgrp);
 
@@ -2161,6 +2280,7 @@ out_free:
 		deactivate_super(pinned_sb);
 	}
 
+	put_cgroup_ns(ns);
 	return dentry;
 }
 
@@ -2189,8 +2309,39 @@ static struct file_system_type cgroup_fs
 	.name = "cgroup",
 	.mount = cgroup_mount,
 	.kill_sb = cgroup_kill_sb,
+	.fs_flags = FS_USERNS_MOUNT,
 };
 
+static char *
+cgroup_path_ns_locked(struct cgroup *cgrp, char *buf, size_t buflen,
+		      struct cgroup_namespace *ns)
+{
+	int ret;
+	struct cgroup *root = cset_cgroup_from_root(ns->root_cset, cgrp->root);
+
+	ret = kernfs_path_from_node(cgrp->kn, root->kn, buf, buflen);
+	if (ret < 0 || ret >= buflen)
+		return NULL;
+	return buf;
+}
+
+char *cgroup_path_ns(struct cgroup *cgrp, char *buf, size_t buflen,
+		     struct cgroup_namespace *ns)
+{
+	char *ret;
+
+	mutex_lock(&cgroup_mutex);
+	spin_lock_bh(&css_set_lock);
+
+	ret = cgroup_path_ns_locked(cgrp, buf, buflen, ns);
+
+	spin_unlock_bh(&css_set_lock);
+	mutex_unlock(&cgroup_mutex);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(cgroup_path_ns);
+
 /**
  * task_cgroup_path - cgroup path of a task in the first cgroup hierarchy
  * @task: target task
@@ -2218,7 +2369,8 @@ char *task_cgroup_path(struct task_struc
 
 	if (root) {
 		cgrp = task_cgroup_from_root(task, root);
-		path = cgroup_path(cgrp, buf, buflen);
+		path = cgroup_path_ns_locked(cgrp, buf, buflen,
+					     &init_cgroup_ns);
 	} else {
 		/* if no hierarchy exists, everyone is in "/" */
 		if (strlcpy(buf, "/", buflen) < buflen)
@@ -2498,6 +2650,14 @@ static void cgroup_migrate_add_src(struc
 	lockdep_assert_held(&cgroup_mutex);
 	lockdep_assert_held(&css_set_lock);
 
+	/*
+	 * If ->dead, @src_set is associated with one or more dead cgroups
+	 * and doesn't contain any migratable tasks.  Ignore it early so
+	 * that the rest of migration path doesn't get confused by it.
+	 */
+	if (src_cset->dead)
+		return;
+
 	src_cgrp = cset_cgroup_from_root(src_cset, dst_cgrp->root);
 
 	if (!list_empty(&src_cset->mg_preload_node))
@@ -2713,9 +2873,10 @@ static ssize_t __cgroup_procs_write(stru
 				    size_t nbytes, loff_t off, bool threadgroup)
 {
 	struct task_struct *tsk;
+	struct cgroup_subsys *ss;
 	struct cgroup *cgrp;
 	pid_t pid;
-	int ret;
+	int ssid, ret;
 
 	if (kstrtoint(strstrip(buf), 0, &pid) || pid < 0)
 		return -EINVAL;
@@ -2763,6 +2924,9 @@ out_unlock_rcu:
 	rcu_read_unlock();
 out_unlock_threadgroup:
 	percpu_up_write(&cgroup_threadgroup_rwsem);
+	for_each_subsys(ss, ssid)
+		if (ss->post_attach)
+			ss->post_attach();
 	cgroup_kn_unlock(of->kn);
 	return ret ?: nbytes;
 }
@@ -4680,14 +4844,15 @@ static void css_free_work_fn(struct work
 
 	if (ss) {
 		/* css free path */
+		struct cgroup_subsys_state *parent = css->parent;
 		int id = css->id;
 
-		if (css->parent)
-			css_put(css->parent);
-
 		ss->css_free(css);
 		cgroup_idr_remove(&ss->css_idr, id);
 		cgroup_put(cgrp);
+
+		if (parent)
+			css_put(parent);
 	} else {
 		/* cgroup free path */
 		atomic_dec(&cgrp->root->nr_cgrps);
@@ -4780,9 +4945,11 @@ static void init_and_link_css(struct cgr
 	memset(css, 0, sizeof(*css));
 	css->cgroup = cgrp;
 	css->ss = ss;
+	css->id = -1;
 	INIT_LIST_HEAD(&css->sibling);
 	INIT_LIST_HEAD(&css->children);
 	css->serial_nr = css_serial_nr_next++;
+	atomic_set(&css->online_cnt, 0);
 
 	if (cgroup_parent(cgrp)) {
 		css->parent = cgroup_css(cgroup_parent(cgrp), ss);
@@ -4805,6 +4972,10 @@ static int online_css(struct cgroup_subs
 	if (!ret) {
 		css->flags |= CSS_ONLINE;
 		rcu_assign_pointer(css->cgroup->subsys[ss->id], css);
+
+		atomic_inc(&css->online_cnt);
+		if (css->parent)
+			atomic_inc(&css->parent->online_cnt);
 	}
 	return ret;
 }
@@ -5036,10 +5207,15 @@ static void css_killed_work_fn(struct wo
 		container_of(work, struct cgroup_subsys_state, destroy_work);
 
 	mutex_lock(&cgroup_mutex);
-	offline_css(css);
-	mutex_unlock(&cgroup_mutex);
 
-	css_put(css);
+	do {
+		offline_css(css);
+		css_put(css);
+		/* @css can't go away while we're holding cgroup_mutex */
+		css = css->parent;
+	} while (css && atomic_dec_and_test(&css->online_cnt));
+
+	mutex_unlock(&cgroup_mutex);
 }
 
 /* css kill confirmation processing requires process context, bounce */
@@ -5048,8 +5224,10 @@ static void css_killed_ref_fn(struct per
 	struct cgroup_subsys_state *css =
 		container_of(ref, struct cgroup_subsys_state, refcnt);
 
-	INIT_WORK(&css->destroy_work, css_killed_work_fn);
-	queue_work(cgroup_destroy_wq, &css->destroy_work);
+	if (atomic_dec_and_test(&css->online_cnt)) {
+		INIT_WORK(&css->destroy_work, css_killed_work_fn);
+		queue_work(cgroup_destroy_wq, &css->destroy_work);
+	}
 }
 
 /**
@@ -5118,6 +5296,7 @@ static int cgroup_destroy_locked(struct
 	__releases(&cgroup_mutex) __acquires(&cgroup_mutex)
 {
 	struct cgroup_subsys_state *css;
+	struct cgrp_cset_link *link;
 	int ssid;
 
 	lockdep_assert_held(&cgroup_mutex);
@@ -5138,11 +5317,18 @@ static int cgroup_destroy_locked(struct
 		return -EBUSY;
 
 	/*
-	 * Mark @cgrp dead.  This prevents further task migration and child
-	 * creation by disabling cgroup_lock_live_group().
+	 * Mark @cgrp and the associated csets dead.  The former prevents
+	 * further task migration and child creation by disabling
+	 * cgroup_lock_live_group().  The latter makes the csets ignored by
+	 * the migration path.
 	 */
 	cgrp->self.flags &= ~CSS_ONLINE;
 
+	spin_lock_bh(&css_set_lock);
+	list_for_each_entry(link, &cgrp->cset_links, cset_link)
+		link->cset->dead = true;
+	spin_unlock_bh(&css_set_lock);
+
 	/* initiate massacre of all css's */
 	for_each_css(css, ssid, cgrp)
 		kill_css(css);
@@ -5182,6 +5368,7 @@ static struct kernfs_syscall_ops cgroup_
 	.mkdir			= cgroup_mkdir,
 	.rmdir			= cgroup_rmdir,
 	.rename			= cgroup_rename,
+	.show_path		= cgroup_show_path,
 };
 
 static void __init cgroup_init_subsys(struct cgroup_subsys *ss, bool early)
@@ -5291,6 +5478,8 @@ int __init cgroup_init(void)
 	BUG_ON(cgroup_init_cftypes(NULL, cgroup_dfl_base_files));
 	BUG_ON(cgroup_init_cftypes(NULL, cgroup_legacy_base_files));
 
+	get_user_ns(init_cgroup_ns.user_ns);
+
 	mutex_lock(&cgroup_mutex);
 
 	/* Add init_css_set to the hash table */
@@ -5427,7 +5616,8 @@ int proc_cgroup_show(struct seq_file *m,
 		 * " (deleted)" is appended to the cgroup path.
 		 */
 		if (cgroup_on_dfl(cgrp) || !(tsk->flags & PF_EXITING)) {
-			path = cgroup_path(cgrp, buf, PATH_MAX);
+			path = cgroup_path_ns_locked(cgrp, buf, PATH_MAX,
+						     current->nsproxy->cgroup_ns);
 			if (!path) {
 				retval = -ENAMETOOLONG;
 				goto out_unlock;
@@ -5725,7 +5915,10 @@ static void cgroup_release_agent(struct
 	if (!pathbuf || !agentbuf)
 		goto out;
 
-	path = cgroup_path(cgrp, pathbuf, PATH_MAX);
+	spin_lock_bh(&css_set_lock);
+	path = cgroup_path_ns_locked(cgrp, pathbuf, PATH_MAX,
+				     &init_cgroup_ns);
+	spin_unlock_bh(&css_set_lock);
 	if (!path)
 		goto out;
 
@@ -5822,6 +6015,133 @@ struct cgroup_subsys_state *css_from_id(
 	return id > 0 ? idr_find(&ss->css_idr, id) : NULL;
 }
 
+/* cgroup namespaces */
+
+static struct cgroup_namespace *alloc_cgroup_ns(void)
+{
+	struct cgroup_namespace *new_ns;
+	int ret;
+
+	new_ns = kzalloc(sizeof(struct cgroup_namespace), GFP_KERNEL);
+	if (!new_ns)
+		return ERR_PTR(-ENOMEM);
+	ret = ns_alloc_inum(&new_ns->ns);
+	if (ret) {
+		kfree(new_ns);
+		return ERR_PTR(ret);
+	}
+	atomic_set(&new_ns->count, 1);
+	new_ns->ns.ops = &cgroupns_operations;
+	return new_ns;
+}
+
+void free_cgroup_ns(struct cgroup_namespace *ns)
+{
+	put_css_set(ns->root_cset);
+	put_user_ns(ns->user_ns);
+	ns_free_inum(&ns->ns);
+	kfree(ns);
+}
+EXPORT_SYMBOL(free_cgroup_ns);
+
+struct cgroup_namespace *
+copy_cgroup_ns(unsigned long flags, struct user_namespace *user_ns,
+	       struct cgroup_namespace *old_ns)
+{
+	struct cgroup_namespace *new_ns;
+	struct css_set *cset;
+
+	BUG_ON(!old_ns);
+
+	if (!(flags & CLONE_NEWCGROUP)) {
+		get_cgroup_ns(old_ns);
+		return old_ns;
+	}
+
+	/* Allow only sysadmin to create cgroup namespace. */
+	if (!ns_capable(user_ns, CAP_SYS_ADMIN))
+		return ERR_PTR(-EPERM);
+
+	mutex_lock(&cgroup_mutex);
+	spin_lock_bh(&css_set_lock);
+
+	cset = task_css_set(current);
+	get_css_set(cset);
+
+	spin_unlock_bh(&css_set_lock);
+	mutex_unlock(&cgroup_mutex);
+
+	new_ns = alloc_cgroup_ns();
+	if (IS_ERR(new_ns)) {
+		put_css_set(cset);
+		return new_ns;
+	}
+
+	new_ns->user_ns = get_user_ns(user_ns);
+	new_ns->root_cset = cset;
+
+	return new_ns;
+}
+
+static inline struct cgroup_namespace *to_cg_ns(struct ns_common *ns)
+{
+	return container_of(ns, struct cgroup_namespace, ns);
+}
+
+static int cgroupns_install(struct nsproxy *nsproxy, struct ns_common *ns)
+{
+	struct cgroup_namespace *cgroup_ns = to_cg_ns(ns);
+
+	if (!ns_capable(current_user_ns(), CAP_SYS_ADMIN) ||
+	    !ns_capable(cgroup_ns->user_ns, CAP_SYS_ADMIN))
+		return -EPERM;
+
+	/* Don't need to do anything if we are attaching to our own cgroupns. */
+	if (cgroup_ns == nsproxy->cgroup_ns)
+		return 0;
+
+	get_cgroup_ns(cgroup_ns);
+	put_cgroup_ns(nsproxy->cgroup_ns);
+	nsproxy->cgroup_ns = cgroup_ns;
+
+	return 0;
+}
+
+static struct ns_common *cgroupns_get(struct task_struct *task)
+{
+	struct cgroup_namespace *ns = NULL;
+	struct nsproxy *nsproxy;
+
+	task_lock(task);
+	nsproxy = task->nsproxy;
+	if (nsproxy) {
+		ns = nsproxy->cgroup_ns;
+		get_cgroup_ns(ns);
+	}
+	task_unlock(task);
+
+	return ns ? &ns->ns : NULL;
+}
+
+static void cgroupns_put(struct ns_common *ns)
+{
+	put_cgroup_ns(to_cg_ns(ns));
+}
+
+const struct proc_ns_operations cgroupns_operations = {
+	.name		= "cgroup",
+	.type		= CLONE_NEWCGROUP,
+	.get		= cgroupns_get,
+	.put		= cgroupns_put,
+	.install	= cgroupns_install,
+};
+
+static __init int cgroup_namespaces_init(void)
+{
+	return 0;
+}
+subsys_initcall(cgroup_namespaces_init);
+
 #ifdef CONFIG_CGROUP_DEBUG
 static struct cgroup_subsys_state *
 debug_css_alloc(struct cgroup_subsys_state *parent_css)
--- zfcpdump-kernel-4.4.orig/kernel/configs/tiny.config
+++ zfcpdump-kernel-4.4/kernel/configs/tiny.config
@@ -1,4 +1,12 @@
+# CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE is not set
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+# CONFIG_KERNEL_GZIP is not set
+# CONFIG_KERNEL_BZIP2 is not set
+# CONFIG_KERNEL_LZMA is not set
 CONFIG_KERNEL_XZ=y
+# CONFIG_KERNEL_LZO is not set
+# CONFIG_KERNEL_LZ4 is not set
 CONFIG_OPTIMIZE_INLINING=y
+# CONFIG_SLAB is not set
+# CONFIG_SLUB is not set
 CONFIG_SLOB=y
--- zfcpdump-kernel-4.4.orig/kernel/cpuset.c
+++ zfcpdump-kernel-4.4/kernel/cpuset.c
@@ -57,7 +57,6 @@
 #include <asm/uaccess.h>
 #include <linux/atomic.h>
 #include <linux/mutex.h>
-#include <linux/workqueue.h>
 #include <linux/cgroup.h>
 #include <linux/wait.h>
 
@@ -286,6 +285,8 @@ static struct cpuset top_cpuset = {
 static DEFINE_MUTEX(cpuset_mutex);
 static DEFINE_SPINLOCK(callback_lock);
 
+static struct workqueue_struct *cpuset_migrate_mm_wq;
+
 /*
  * CPU / memory hotplug is handled asynchronously.
  */
@@ -323,8 +324,7 @@ static struct file_system_type cpuset_fs
 /*
  * Return in pmask the portion of a cpusets's cpus_allowed that
  * are online.  If none are online, walk up the cpuset hierarchy
- * until we find one that does have some online cpus.  The top
- * cpuset always has some cpus online.
+ * until we find one that does have some online cpus.
  *
  * One way or another, we guarantee to return some non-empty subset
  * of cpu_online_mask.
@@ -333,8 +333,20 @@ static struct file_system_type cpuset_fs
  */
 static void guarantee_online_cpus(struct cpuset *cs, struct cpumask *pmask)
 {
-	while (!cpumask_intersects(cs->effective_cpus, cpu_online_mask))
+	while (!cpumask_intersects(cs->effective_cpus, cpu_online_mask)) {
 		cs = parent_cs(cs);
+		if (unlikely(!cs)) {
+			/*
+			 * The top cpuset doesn't have any online cpu as a
+			 * consequence of a race between cpuset_hotplug_work
+			 * and cpu hotplug notifier.  But we know the top
+			 * cpuset's effective_cpus is on its way to to be
+			 * identical to cpu_online_mask.
+			 */
+			cpumask_copy(pmask, cpu_online_mask);
+			return;
+		}
+	}
 	cpumask_and(pmask, cs->effective_cpus, cpu_online_mask);
 }
 
@@ -971,31 +983,51 @@ static int update_cpumask(struct cpuset
 }
 
 /*
- * cpuset_migrate_mm
- *
- *    Migrate memory region from one set of nodes to another.
- *
- *    Temporarilly set tasks mems_allowed to target nodes of migration,
- *    so that the migration code can allocate pages on these nodes.
- *
- *    While the mm_struct we are migrating is typically from some
- *    other task, the task_struct mems_allowed that we are hacking
- *    is for our current task, which must allocate new pages for that
- *    migrating memory region.
+ * Migrate memory region from one set of nodes to another.  This is
+ * performed asynchronously as it can be called from process migration path
+ * holding locks involved in process management.  All mm migrations are
+ * performed in the queued order and can be waited for by flushing
+ * cpuset_migrate_mm_wq.
  */
 
+struct cpuset_migrate_mm_work {
+	struct work_struct	work;
+	struct mm_struct	*mm;
+	nodemask_t		from;
+	nodemask_t		to;
+};
+
+static void cpuset_migrate_mm_workfn(struct work_struct *work)
+{
+	struct cpuset_migrate_mm_work *mwork =
+		container_of(work, struct cpuset_migrate_mm_work, work);
+
+	/* on a wq worker, no need to worry about %current's mems_allowed */
+	do_migrate_pages(mwork->mm, &mwork->from, &mwork->to, MPOL_MF_MOVE_ALL);
+	mmput(mwork->mm);
+	kfree(mwork);
+}
+
 static void cpuset_migrate_mm(struct mm_struct *mm, const nodemask_t *from,
 							const nodemask_t *to)
 {
-	struct task_struct *tsk = current;
+	struct cpuset_migrate_mm_work *mwork;
 
-	tsk->mems_allowed = *to;
-
-	do_migrate_pages(mm, from, to, MPOL_MF_MOVE_ALL);
+	mwork = kzalloc(sizeof(*mwork), GFP_KERNEL);
+	if (mwork) {
+		mwork->mm = mm;
+		mwork->from = *from;
+		mwork->to = *to;
+		INIT_WORK(&mwork->work, cpuset_migrate_mm_workfn);
+		queue_work(cpuset_migrate_mm_wq, &mwork->work);
+	} else {
+		mmput(mm);
+	}
+}
 
-	rcu_read_lock();
-	guarantee_online_mems(task_cs(tsk), &tsk->mems_allowed);
-	rcu_read_unlock();
+static void cpuset_post_attach(void)
+{
+	flush_workqueue(cpuset_migrate_mm_wq);
 }
 
 /*
@@ -1096,7 +1128,8 @@ static void update_tasks_nodemask(struct
 		mpol_rebind_mm(mm, &cs->mems_allowed);
 		if (migrate)
 			cpuset_migrate_mm(mm, &cs->old_mems_allowed, &newmems);
-		mmput(mm);
+		else
+			mmput(mm);
 	}
 	css_task_iter_end(&it);
 
@@ -1541,11 +1574,11 @@ static void cpuset_attach(struct cgroup_
 			 * @old_mems_allowed is the right nodesets that we
 			 * migrate mm from.
 			 */
-			if (is_memory_migrate(cs)) {
+			if (is_memory_migrate(cs))
 				cpuset_migrate_mm(mm, &oldcs->old_mems_allowed,
 						  &cpuset_attach_nodemask_to);
-			}
-			mmput(mm);
+			else
+				mmput(mm);
 		}
 	}
 
@@ -1710,6 +1743,7 @@ out_unlock:
 	mutex_unlock(&cpuset_mutex);
 	kernfs_unbreak_active_protection(of->kn);
 	css_put(&cs->css);
+	flush_workqueue(cpuset_migrate_mm_wq);
 	return retval ?: nbytes;
 }
 
@@ -2051,6 +2085,20 @@ static void cpuset_bind(struct cgroup_su
 	mutex_unlock(&cpuset_mutex);
 }
 
+/*
+ * Make sure the new task conform to the current state of its parent,
+ * which could have been changed by cpuset just after it inherits the
+ * state from the parent and before it sits on the cgroup's task list.
+ */
+void cpuset_fork(struct task_struct *task, void *priv)
+{
+	if (task_css_is_root(task, cpuset_cgrp_id))
+		return;
+
+	set_cpus_allowed_ptr(task, &current->cpus_allowed);
+	task->mems_allowed = current->mems_allowed;
+}
+
 struct cgroup_subsys cpuset_cgrp_subsys = {
 	.css_alloc	= cpuset_css_alloc,
 	.css_online	= cpuset_css_online,
@@ -2059,7 +2107,9 @@ struct cgroup_subsys cpuset_cgrp_subsys
 	.can_attach	= cpuset_can_attach,
 	.cancel_attach	= cpuset_cancel_attach,
 	.attach		= cpuset_attach,
+	.post_attach	= cpuset_post_attach,
 	.bind		= cpuset_bind,
+	.fork		= cpuset_fork,
 	.legacy_cftypes	= files,
 	.early_init	= 1,
 };
@@ -2355,6 +2405,9 @@ void __init cpuset_init_smp(void)
 	top_cpuset.effective_mems = node_states[N_MEMORY];
 
 	register_hotmemory_notifier(&cpuset_track_online_nodes_nb);
+
+	cpuset_migrate_mm_wq = alloc_ordered_workqueue("cpuset_migrate_mm", 0);
+	BUG_ON(!cpuset_migrate_mm_wq);
 }
 
 /**
@@ -2683,10 +2736,10 @@ int proc_cpuset_show(struct seq_file *m,
 		goto out;
 
 	retval = -ENAMETOOLONG;
-	rcu_read_lock();
-	css = task_css(tsk, cpuset_cgrp_id);
-	p = cgroup_path(css->cgroup, buf, PATH_MAX);
-	rcu_read_unlock();
+	css = task_get_css(tsk, cpuset_cgrp_id);
+	p = cgroup_path_ns(css->cgroup, buf, PATH_MAX,
+			   current->nsproxy->cgroup_ns);
+	css_put(css);
 	if (!p)
 		goto out_free;
 	seq_puts(m, p);
--- zfcpdump-kernel-4.4.orig/kernel/cred.c
+++ zfcpdump-kernel-4.4/kernel/cred.c
@@ -574,38 +574,30 @@ void __init cred_init(void)
 }
 
 /**
- * prepare_kernel_cred - Prepare a set of credentials for a kernel service
- * @daemon: A userspace daemon to be used as a reference
- *
- * Prepare a set of credentials for a kernel service.  This can then be used to
- * override a task's own credentials so that work can be done on behalf of that
- * task that requires a different subjective context.
- *
- * @daemon is used to provide a base for the security record, but can be NULL.
- * If @daemon is supplied, then the security data will be derived from that;
- * otherwise they'll be set to 0 and no groups, full capabilities and no keys.
+ * clone_cred - Create a new copy of a set of credentials
+ * @old: Credentials to be copied
  *
- * The caller may change these controls afterwards if desired.
+ * Prepare a new set of credentials that is an exact copy of @old. This can
+ * optionally be modified and used to override a task's own credentials so
+ * that work can be done on behalf of that task that requires a different
+ * subjective context.
  *
- * Returns the new credentials or NULL if out of memory.
+ * Returns the new credentials or NULL if @old is NULL or if out of memory.
  *
  * Does not take, and does not return holding current->cred_replace_mutex.
  */
-struct cred *prepare_kernel_cred(struct task_struct *daemon)
+struct cred *clone_cred(const struct cred *old)
 {
-	const struct cred *old;
 	struct cred *new;
 
+	if (!old)
+		return NULL;
+
 	new = kmem_cache_alloc(cred_jar, GFP_KERNEL);
 	if (!new)
 		return NULL;
 
-	kdebug("prepare_kernel_cred() alloc %p", new);
-
-	if (daemon)
-		old = get_task_cred(daemon);
-	else
-		old = get_cred(&init_cred);
+	kdebug("clone_cred() alloc %p", new);
 
 	validate_creds(old);
 
@@ -630,15 +622,47 @@ struct cred *prepare_kernel_cred(struct
 	if (security_prepare_creds(new, old, GFP_KERNEL) < 0)
 		goto error;
 
-	put_cred(old);
 	validate_creds(new);
 	return new;
 
 error:
 	put_cred(new);
-	put_cred(old);
 	return NULL;
 }
+EXPORT_SYMBOL(clone_cred);
+
+/**
+ * prepare_kernel_cred - Prepare a set of credentials for a kernel service
+ * @daemon: A userspace daemon to be used as a reference
+ *
+ * Prepare a set of credentials for a kernel service.  This can then be used to
+ * override a task's own credentials so that work can be done on behalf of that
+ * task that requires a different subjective context.
+ *
+ * @daemon is used to provide a base for the security record, but can be NULL.
+ * If @daemon is supplied, then the security data will be derived from that;
+ * otherwise they'll be set to 0 and no groups, full capabilities and no keys.
+ *
+ * The caller may change these controls afterwards if desired.
+ *
+ * Returns the new credentials or NULL if out of memory.
+ *
+ * Does not take, and does not return holding current->cred_replace_mutex.
+ */
+struct cred *prepare_kernel_cred(struct task_struct *daemon)
+{
+	const struct cred *old;
+	struct cred *new;
+
+	if (daemon)
+		old = get_task_cred(daemon);
+	else
+		old = get_cred(&init_cred);
+
+	new = clone_cred(old);
+	put_cred(old);
+	return new;
+}
 EXPORT_SYMBOL(prepare_kernel_cred);
 
 /**
@@ -689,6 +713,8 @@ EXPORT_SYMBOL(set_security_override_from
  */
 int set_create_files_as(struct cred *new, struct inode *inode)
 {
+	if (!uid_valid(inode->i_uid) || !gid_valid(inode->i_gid))
+		return -EINVAL;
 	new->fsuid = inode->i_uid;
 	new->fsgid = inode->i_gid;
 	return security_kernel_create_files_as(new, inode);
--- zfcpdump-kernel-4.4.orig/kernel/debug/kdb/kdb_main.c
+++ zfcpdump-kernel-4.4/kernel/debug/kdb/kdb_main.c
@@ -2021,7 +2021,7 @@ static int kdb_lsmod(int argc, const cha
 			continue;
 
 		kdb_printf("%-20s%8u  0x%p ", mod->name,
-			   mod->core_size, (void *)mod);
+			   mod->core_layout.size, (void *)mod);
 #ifdef CONFIG_MODULE_UNLOAD
 		kdb_printf("%4d ", module_refcount(mod));
 #endif
@@ -2031,7 +2031,7 @@ static int kdb_lsmod(int argc, const cha
 			kdb_printf(" (Loading)");
 		else
 			kdb_printf(" (Live)");
-		kdb_printf(" 0x%p", mod->module_core);
+		kdb_printf(" 0x%p", mod->core_layout.base);
 
 #ifdef CONFIG_MODULE_UNLOAD
 		{
--- zfcpdump-kernel-4.4.orig/kernel/events/core.c
+++ zfcpdump-kernel-4.4/kernel/events/core.c
@@ -946,6 +946,7 @@ static void put_ctx(struct perf_event_co
  * function.
  *
  * Lock order:
+ *    cred_guard_mutex
  *	task_struct::perf_event_mutex
  *	  perf_event_context::mutex
  *	    perf_event_context::lock
@@ -1538,12 +1539,33 @@ static int __init perf_workqueue_init(vo
 
 core_initcall(perf_workqueue_init);
 
-static inline int pmu_filter_match(struct perf_event *event)
+static inline int __pmu_filter_match(struct perf_event *event)
 {
 	struct pmu *pmu = event->pmu;
 	return pmu->filter_match ? pmu->filter_match(event) : 1;
 }
 
+/*
+ * Check whether we should attempt to schedule an event group based on
+ * PMU-specific filtering. An event group can consist of HW and SW events,
+ * potentially with a SW leader, so we must check all the filters, to
+ * determine whether a group is schedulable:
+ */
+static inline int pmu_filter_match(struct perf_event *event)
+{
+	struct perf_event *child;
+
+	if (!__pmu_filter_match(event))
+		return 0;
+
+	list_for_each_entry(child, &event->sibling_list, group_entry) {
+		if (!__pmu_filter_match(child))
+			return 0;
+	}
+
+	return 1;
+}
+
 static inline int
 event_filter_match(struct perf_event *event)
 {
@@ -1580,14 +1602,14 @@ event_sched_out(struct perf_event *event
 
 	perf_pmu_disable(event->pmu);
 
+	event->tstamp_stopped = tstamp;
+	event->pmu->del(event, 0);
+	event->oncpu = -1;
 	event->state = PERF_EVENT_STATE_INACTIVE;
 	if (event->pending_disable) {
 		event->pending_disable = 0;
 		event->state = PERF_EVENT_STATE_OFF;
 	}
-	event->tstamp_stopped = tstamp;
-	event->pmu->del(event, 0);
-	event->oncpu = -1;
 
 	if (!is_software_event(event))
 		cpuctx->active_oncpu--;
@@ -3418,7 +3440,6 @@ static struct task_struct *
 find_lively_task_by_vpid(pid_t vpid)
 {
 	struct task_struct *task;
-	int err;
 
 	rcu_read_lock();
 	if (!vpid)
@@ -3432,16 +3453,7 @@ find_lively_task_by_vpid(pid_t vpid)
 	if (!task)
 		return ERR_PTR(-ESRCH);
 
-	/* Reuse ptrace permission checks for now. */
-	err = -EACCES;
-	if (!ptrace_may_access(task, PTRACE_MODE_READ))
-		goto errout;
-
 	return task;
-errout:
-	put_task_struct(task);
-	return ERR_PTR(err);
-
 }
 
 /*
@@ -7110,7 +7122,7 @@ static void perf_event_free_bpf_prog(str
 	prog = event->tp_event->prog;
 	if (prog) {
 		event->tp_event->prog = NULL;
-		bpf_prog_put(prog);
+		bpf_prog_put_rcu(prog);
 	}
 }
 
@@ -7979,6 +7991,9 @@ perf_event_alloc(struct perf_event_attr
 		}
 	}
 
+	/* symmetric to unaccount_event() in _free_event() */
+	account_event(event);
+
 	return event;
 
 err_per_task:
@@ -8325,6 +8340,24 @@ SYSCALL_DEFINE5(perf_event_open,
 
 	get_online_cpus();
 
+	if (task) {
+		err = mutex_lock_interruptible(&task->signal->cred_guard_mutex);
+		if (err)
+			goto err_cpus;
+
+		/*
+		 * Reuse ptrace permission checks for now.
+		 *
+		 * We must hold cred_guard_mutex across this and any potential
+		 * perf_install_in_context() call for this new event to
+		 * serialize against exec() altering our credentials (and the
+		 * perf_event_exit_task() that could imply).
+		 */
+		err = -EACCES;
+		if (!ptrace_may_access(task, PTRACE_MODE_READ_REALCREDS))
+			goto err_cred;
+	}
+
 	if (flags & PERF_FLAG_PID_CGROUP)
 		cgroup_fd = pid;
 
@@ -8332,7 +8365,7 @@ SYSCALL_DEFINE5(perf_event_open,
 				 NULL, NULL, cgroup_fd);
 	if (IS_ERR(event)) {
 		err = PTR_ERR(event);
-		goto err_cpus;
+		goto err_cred;
 	}
 
 	if (is_sampling_event(event)) {
@@ -8342,8 +8375,6 @@ SYSCALL_DEFINE5(perf_event_open,
 		}
 	}
 
-	account_event(event);
-
 	/*
 	 * Special case software events and allow them to be part of
 	 * any hardware group.
@@ -8393,11 +8424,6 @@ SYSCALL_DEFINE5(perf_event_open,
 		goto err_context;
 	}
 
-	if (task) {
-		put_task_struct(task);
-		task = NULL;
-	}
-
 	/*
 	 * Look up the group leader (we will attach this event to it):
 	 */
@@ -8485,6 +8511,11 @@ SYSCALL_DEFINE5(perf_event_open,
 
 	WARN_ON_ONCE(ctx->parent_ctx);
 
+	/*
+	 * This is the point on no return; we cannot fail hereafter. This is
+	 * where we start modifying current state.
+	 */
+
 	if (move_group) {
 		/*
 		 * See perf_event_ctx_lock() for comments on the details
@@ -8554,6 +8585,11 @@ SYSCALL_DEFINE5(perf_event_open,
 		mutex_unlock(&gctx->mutex);
 	mutex_unlock(&ctx->mutex);
 
+	if (task) {
+		mutex_unlock(&task->signal->cred_guard_mutex);
+		put_task_struct(task);
+	}
+
 	put_online_cpus();
 
 	event->owner = current;
@@ -8582,7 +8618,15 @@ err_context:
 	perf_unpin_context(ctx);
 	put_ctx(ctx);
 err_alloc:
-	free_event(event);
+	/*
+	 * If event_file is set, the fput() above will have called ->release()
+	 * and that will take care of freeing the event.
+	 */
+	if (!event_file)
+		free_event(event);
+err_cred:
+	if (task)
+		mutex_unlock(&task->signal->cred_guard_mutex);
 err_cpus:
 	put_online_cpus();
 err_task:
@@ -8626,8 +8670,6 @@ perf_event_create_kernel_counter(struct
 	/* Mark owner so we could distinguish it from user events. */
 	event->owner = EVENT_OWNER_KERNEL;
 
-	account_event(event);
-
 	ctx = find_get_context(event->pmu, task, event);
 	if (IS_ERR(ctx)) {
 		err = PTR_ERR(ctx);
@@ -8864,6 +8906,9 @@ static void perf_event_exit_task_context
 
 /*
  * When a child task exits, feed back event values to parent events.
+ *
+ * Can be called with cred_guard_mutex held when called from
+ * install_exec_creds().
  */
 void perf_event_exit_task(struct task_struct *child)
 {
--- zfcpdump-kernel-4.4.orig/kernel/events/ring_buffer.c
+++ zfcpdump-kernel-4.4/kernel/events/ring_buffer.c
@@ -347,6 +347,7 @@ void perf_aux_output_end(struct perf_out
 			 bool truncated)
 {
 	struct ring_buffer *rb = handle->rb;
+	bool wakeup = truncated;
 	unsigned long aux_head;
 	u64 flags = 0;
 
@@ -375,9 +376,16 @@ void perf_aux_output_end(struct perf_out
 	aux_head = rb->user_page->aux_head = local_read(&rb->aux_head);
 
 	if (aux_head - local_read(&rb->aux_wakeup) >= rb->aux_watermark) {
-		perf_output_wakeup(handle);
+		wakeup = true;
 		local_add(rb->aux_watermark, &rb->aux_wakeup);
 	}
+
+	if (wakeup) {
+		if (truncated)
+			handle->event->pending_disable = 1;
+		perf_output_wakeup(handle);
+	}
+
 	handle->event = NULL;
 
 	local_set(&rb->aux_nest, 0);
--- zfcpdump-kernel-4.4.orig/kernel/events/uprobes.c
+++ zfcpdump-kernel-4.4/kernel/events/uprobes.c
@@ -171,8 +171,10 @@ static int __replace_page(struct vm_area
 	mmu_notifier_invalidate_range_start(mm, mmun_start, mmun_end);
 	err = -EAGAIN;
 	ptep = page_check_address(page, mm, addr, &ptl, 0);
-	if (!ptep)
+	if (!ptep) {
+		mem_cgroup_cancel_charge(kpage, memcg);
 		goto unlock;
+	}
 
 	get_page(kpage);
 	page_add_new_anon_rmap(kpage, vma, addr);
@@ -199,7 +201,6 @@ static int __replace_page(struct vm_area
 
 	err = 0;
  unlock:
-	mem_cgroup_cancel_charge(kpage, memcg);
 	mmu_notifier_invalidate_range_end(mm, mmun_start, mmun_end);
 	unlock_page(page);
 	return err;
--- zfcpdump-kernel-4.4.orig/kernel/exit.c
+++ zfcpdump-kernel-4.4/kernel/exit.c
@@ -918,17 +918,28 @@ static int eligible_pid(struct wait_opts
 		task_pid_type(p, wo->wo_type) == wo->wo_pid;
 }
 
-static int eligible_child(struct wait_opts *wo, struct task_struct *p)
+static int
+eligible_child(struct wait_opts *wo, bool ptrace, struct task_struct *p)
 {
 	if (!eligible_pid(wo, p))
 		return 0;
-	/* Wait for all children (clone and not) if __WALL is set;
-	 * otherwise, wait for clone children *only* if __WCLONE is
-	 * set; otherwise, wait for non-clone children *only*.  (Note:
-	 * A "clone" child here is one that reports to its parent
-	 * using a signal other than SIGCHLD.) */
-	if (((p->exit_signal != SIGCHLD) ^ !!(wo->wo_flags & __WCLONE))
-	    && !(wo->wo_flags & __WALL))
+
+	/*
+	 * Wait for all children (clone and not) if __WALL is set or
+	 * if it is traced by us.
+	 */
+	if (ptrace || (wo->wo_flags & __WALL))
+		return 1;
+
+	/*
+	 * Otherwise, wait for clone children *only* if __WCLONE is set;
+	 * otherwise, wait for non-clone children *only*.
+	 *
+	 * Note: a "clone" child here is one that reports to its parent
+	 * using a signal other than SIGCHLD, or a non-leader thread which
+	 * we can only see if it is traced by us.
+	 */
+	if ((p->exit_signal != SIGCHLD) ^ !!(wo->wo_flags & __WCLONE))
 		return 0;
 
 	return 1;
@@ -1301,7 +1312,7 @@ static int wait_consider_task(struct wai
 	if (unlikely(exit_state == EXIT_DEAD))
 		return 0;
 
-	ret = eligible_child(wo, p);
+	ret = eligible_child(wo, ptrace, p);
 	if (!ret)
 		return ret;
 
--- zfcpdump-kernel-4.4.orig/kernel/fork.c
+++ zfcpdump-kernel-4.4/kernel/fork.c
@@ -87,6 +87,11 @@
 
 #define CREATE_TRACE_POINTS
 #include <trace/events/task.h>
+#ifdef CONFIG_USER_NS
+extern int unprivileged_userns_clone;
+#else
+#define unprivileged_userns_clone 0
+#endif
 
 /*
  * Minimum number of threads to boot the kernel
@@ -331,13 +336,14 @@ void set_task_stack_end_magic(struct tas
 	*stackend = STACK_END_MAGIC;	/* for overflow detection */
 }
 
-static struct task_struct *dup_task_struct(struct task_struct *orig)
+static struct task_struct *dup_task_struct(struct task_struct *orig, int node)
 {
 	struct task_struct *tsk;
 	struct thread_info *ti;
-	int node = tsk_fork_get_node(orig);
 	int err;
 
+	if (node == NUMA_NO_NODE)
+		node = tsk_fork_get_node(orig);
 	tsk = alloc_task_struct_node(node);
 	if (!tsk)
 		return NULL;
@@ -465,7 +471,7 @@ static int dup_mmap(struct mm_struct *mm
 			struct inode *inode = file_inode(file);
 			struct address_space *mapping = file->f_mapping;
 
-			get_file(file);
+			vma_get_file(tmp);
 			if (tmp->vm_flags & VM_DENYWRITE)
 				atomic_dec(&inode->i_writecount);
 			i_mmap_lock_write(mapping);
@@ -764,6 +770,29 @@ struct file *get_mm_exe_file(struct mm_s
 EXPORT_SYMBOL(get_mm_exe_file);
 
 /**
+ * get_task_exe_file - acquire a reference to the task's executable file
+ *
+ * Returns %NULL if task's mm (if any) has no associated executable file or
+ * this is a kernel thread with borrowed mm (see the comment above get_task_mm).
+ * User must release file via fput().
+ */
+struct file *get_task_exe_file(struct task_struct *task)
+{
+	struct file *exe_file = NULL;
+	struct mm_struct *mm;
+
+	task_lock(task);
+	mm = task->mm;
+	if (mm) {
+		if (!(task->flags & PF_KTHREAD))
+			exe_file = get_mm_exe_file(mm);
+	}
+	task_unlock(task);
+	return exe_file;
+}
+EXPORT_SYMBOL(get_task_exe_file);
+
+/**
  * get_task_mm - acquire a reference to the task's mm
  *
  * Returns %NULL if the task has no mm.  Checks PF_KTHREAD (meaning
@@ -878,14 +907,12 @@ void mm_release(struct task_struct *tsk,
 	deactivate_mm(tsk, mm);
 
 	/*
-	 * If we're exiting normally, clear a user-space tid field if
-	 * requested.  We leave this alone when dying by signal, to leave
-	 * the value intact in a core dump, and to save the unnecessary
-	 * trouble, say, a killed vfork parent shouldn't touch this mm.
-	 * Userland only wants this done for a sys_exit.
+	 * Signal userspace if we're not exiting with a core dump
+	 * because we want to leave the value intact for debugging
+	 * purposes.
 	 */
 	if (tsk->clear_child_tid) {
-		if (!(tsk->flags & PF_SIGNALED) &&
+		if (!(tsk->signal->flags & SIGNAL_GROUP_COREDUMP) &&
 		    atomic_read(&mm->mm_users) > 1) {
 			/*
 			 * We don't check the error code - if userspace has
@@ -1246,7 +1273,8 @@ static struct task_struct *copy_process(
 					int __user *child_tidptr,
 					struct pid *pid,
 					int trace,
-					unsigned long tls)
+					unsigned long tls,
+					int node)
 {
 	int retval;
 	struct task_struct *p;
@@ -1258,6 +1286,10 @@ static struct task_struct *copy_process(
 	if ((clone_flags & (CLONE_NEWUSER|CLONE_FS)) == (CLONE_NEWUSER|CLONE_FS))
 		return ERR_PTR(-EINVAL);
 
+	if ((clone_flags & CLONE_NEWUSER) && !unprivileged_userns_clone)
+		if (!capable(CAP_SYS_ADMIN))
+			return ERR_PTR(-EPERM);
+
 	/*
 	 * Thread groups must share signals as well, and detached threads
 	 * can only be started up within the thread group.
@@ -1299,7 +1331,7 @@ static struct task_struct *copy_process(
 		goto fork_out;
 
 	retval = -ENOMEM;
-	p = dup_task_struct(current);
+	p = dup_task_struct(current, node);
 	if (!p)
 		goto fork_out;
 
@@ -1369,7 +1401,6 @@ static struct task_struct *copy_process(
 	p->real_start_time = ktime_get_boot_ns();
 	p->io_context = NULL;
 	p->audit_context = NULL;
-	threadgroup_change_begin(current);
 	cgroup_fork(p);
 #ifdef CONFIG_NUMA
 	p->mempolicy = mpol_dup(p->mempolicy);
@@ -1521,6 +1552,7 @@ static struct task_struct *copy_process(
 	INIT_LIST_HEAD(&p->thread_group);
 	p->task_works = NULL;
 
+	threadgroup_change_begin(current);
 	/*
 	 * Ensure that the cgroup subsystem policies allow the new process to be
 	 * forked. It should be noted the the new process's css_set can be changed
@@ -1621,6 +1653,7 @@ static struct task_struct *copy_process(
 bad_fork_cancel_cgroup:
 	cgroup_cancel_fork(p, cgrp_ss_priv);
 bad_fork_free_pid:
+	threadgroup_change_end(current);
 	if (pid != &init_struct_pid)
 		free_pid(pid);
 bad_fork_cleanup_io:
@@ -1651,7 +1684,6 @@ bad_fork_cleanup_policy:
 	mpol_put(p->mempolicy);
 bad_fork_cleanup_threadgroup_lock:
 #endif
-	threadgroup_change_end(current);
 	delayacct_tsk_free(p);
 bad_fork_cleanup_count:
 	atomic_dec(&p->cred->user->processes);
@@ -1675,7 +1707,8 @@ static inline void init_idle_pids(struct
 struct task_struct *fork_idle(int cpu)
 {
 	struct task_struct *task;
-	task = copy_process(CLONE_VM, 0, 0, NULL, &init_struct_pid, 0, 0);
+	task = copy_process(CLONE_VM, 0, 0, NULL, &init_struct_pid, 0, 0,
+			    cpu_to_node(cpu));
 	if (!IS_ERR(task)) {
 		init_idle_pids(task->pids);
 		init_idle(task, cpu);
@@ -1720,7 +1753,7 @@ long _do_fork(unsigned long clone_flags,
 	}
 
 	p = copy_process(clone_flags, stack_start, stack_size,
-			 child_tidptr, NULL, trace, tls);
+			 child_tidptr, NULL, trace, tls, NUMA_NO_NODE);
 	/*
 	 * Do this prior waking up the new thread - the thread pointer
 	 * might get invalid after that point, if the thread exits quickly.
@@ -1882,7 +1915,7 @@ static int check_unshare_flags(unsigned
 	if (unshare_flags & ~(CLONE_THREAD|CLONE_FS|CLONE_NEWNS|CLONE_SIGHAND|
 				CLONE_VM|CLONE_FILES|CLONE_SYSVSEM|
 				CLONE_NEWUTS|CLONE_NEWIPC|CLONE_NEWNET|
-				CLONE_NEWUSER|CLONE_NEWPID))
+				CLONE_NEWUSER|CLONE_NEWPID|CLONE_NEWCGROUP))
 		return -EINVAL;
 	/*
 	 * Not implemented, but pretend it works if there is nothing
@@ -1984,6 +2017,12 @@ SYSCALL_DEFINE1(unshare, unsigned long,
 	if (unshare_flags & CLONE_NEWNS)
 		unshare_flags |= CLONE_FS;
 
+	if ((unshare_flags & CLONE_NEWUSER) && !unprivileged_userns_clone) {
+		err = -EPERM;
+		if (!capable(CAP_SYS_ADMIN))
+			goto bad_unshare_out;
+	}
+
 	err = check_unshare_flags(unshare_flags);
 	if (err)
 		goto bad_unshare_out;
--- zfcpdump-kernel-4.4.orig/kernel/futex.c
+++ zfcpdump-kernel-4.4/kernel/futex.c
@@ -1244,10 +1244,20 @@ static int wake_futex_pi(u32 __user *uad
 	if (unlikely(should_fail_futex(true)))
 		ret = -EFAULT;
 
-	if (cmpxchg_futex_value_locked(&curval, uaddr, uval, newval))
+	if (cmpxchg_futex_value_locked(&curval, uaddr, uval, newval)) {
 		ret = -EFAULT;
-	else if (curval != uval)
-		ret = -EINVAL;
+	} else if (curval != uval) {
+		/*
+		 * If a unconditional UNLOCK_PI operation (user space did not
+		 * try the TID->0 transition) raced with a waiter setting the
+		 * FUTEX_WAITERS flag between get_user() and locking the hash
+		 * bucket lock, retry the operation.
+		 */
+		if ((FUTEX_TID_MASK & curval) == uval)
+			ret = -EAGAIN;
+		else
+			ret = -EINVAL;
+	}
 	if (ret) {
 		raw_spin_unlock(&pi_state->pi_mutex.wait_lock);
 		return ret;
@@ -1474,8 +1484,8 @@ void requeue_futex(struct futex_q *q, st
 	if (likely(&hb1->chain != &hb2->chain)) {
 		plist_del(&q->list, &hb1->chain);
 		hb_waiters_dec(hb1);
-		plist_add(&q->list, &hb2->chain);
 		hb_waiters_inc(hb2);
+		plist_add(&q->list, &hb2->chain);
 		q->lock_ptr = &hb2->lock;
 	}
 	get_futex_key_refs(key2);
@@ -2538,6 +2548,15 @@ retry:
 		if (ret == -EFAULT)
 			goto pi_faulted;
 		/*
+		 * A unconditional UNLOCK_PI op raced against a waiter
+		 * setting the FUTEX_WAITERS bit. Try again.
+		 */
+		if (ret == -EAGAIN) {
+			spin_unlock(&hb->lock);
+			put_futex_key(&key);
+			goto retry;
+		}
+		/*
 		 * wake_futex_pi has detected invalid state. Tell user
 		 * space.
 		 */
@@ -2755,6 +2774,11 @@ static int futex_wait_requeue_pi(u32 __u
 		if (q.pi_state && (q.pi_state->owner != current)) {
 			spin_lock(q.lock_ptr);
 			ret = fixup_pi_state_owner(uaddr2, &q, current);
+			/*
+			 * Drop the reference to the pi state which
+			 * the requeue_pi() code acquired for us.
+			 */
+			free_pi_state(q.pi_state);
 			spin_unlock(q.lock_ptr);
 		}
 	} else {
@@ -2881,7 +2905,7 @@ SYSCALL_DEFINE3(get_robust_list, int, pi
 	}
 
 	ret = -EPERM;
-	if (!ptrace_may_access(p, PTRACE_MODE_READ))
+	if (!ptrace_may_access(p, PTRACE_MODE_READ_REALCREDS))
 		goto err_unlock;
 
 	head = p->robust_list;
--- zfcpdump-kernel-4.4.orig/kernel/futex_compat.c
+++ zfcpdump-kernel-4.4/kernel/futex_compat.c
@@ -155,7 +155,7 @@ COMPAT_SYSCALL_DEFINE3(get_robust_list,
 	}
 
 	ret = -EPERM;
-	if (!ptrace_may_access(p, PTRACE_MODE_READ))
+	if (!ptrace_may_access(p, PTRACE_MODE_READ_REALCREDS))
 		goto err_unlock;
 
 	head = p->compat_robust_list;
--- zfcpdump-kernel-4.4.orig/kernel/gcov/base.c
+++ zfcpdump-kernel-4.4/kernel/gcov/base.c
@@ -123,11 +123,6 @@ void gcov_enable_events(void)
 }
 
 #ifdef CONFIG_MODULES
-static inline int within(void *addr, void *start, unsigned long size)
-{
-	return ((addr >= start) && (addr < start + size));
-}
-
 /* Update list and generate events when modules are unloaded. */
 static int gcov_module_notifier(struct notifier_block *nb, unsigned long event,
 				void *data)
@@ -142,7 +137,7 @@ static int gcov_module_notifier(struct n
 
 	/* Remove entries located in module from linked list. */
 	while ((info = gcov_info_next(info))) {
-		if (within(info, mod->module_core, mod->core_size)) {
+		if (within_module((unsigned long)info, mod)) {
 			gcov_info_unlink(prev, info);
 			if (gcov_events_enabled)
 				gcov_event(GCOV_REMOVE, info);
--- zfcpdump-kernel-4.4.orig/kernel/irq/Kconfig
+++ zfcpdump-kernel-4.4/kernel/irq/Kconfig
@@ -91,6 +91,10 @@ config IRQ_DOMAIN_DEBUG
 config IRQ_FORCED_THREADING
        bool
 
+config IRQ_FORCED_THREADING_DEFAULT
+	bool "Use IRQ threading by default"
+	depends on IRQ_FORCED_THREADING
+
 config SPARSE_IRQ
 	bool "Support sparse irq numbering" if MAY_HAVE_SPARSE_IRQ
 	---help---
--- zfcpdump-kernel-4.4.orig/kernel/irq/chip.c
+++ zfcpdump-kernel-4.4/kernel/irq/chip.c
@@ -950,6 +950,7 @@ void irq_chip_ack_parent(struct irq_data
 	data = data->parent_data;
 	data->chip->irq_ack(data);
 }
+EXPORT_SYMBOL_GPL(irq_chip_ack_parent);
 
 /**
  * irq_chip_mask_parent - Mask the parent interrupt
--- zfcpdump-kernel-4.4.orig/kernel/irq/handle.c
+++ zfcpdump-kernel-4.4/kernel/irq/handle.c
@@ -138,7 +138,8 @@ irqreturn_t handle_irq_event_percpu(stru
 	unsigned int flags = 0, irq = desc->irq_data.irq;
 	struct irqaction *action = desc->action;
 
-	do {
+	/* action might have become NULL since we dropped the lock */
+	while (action) {
 		irqreturn_t res;
 
 		trace_irq_handler_entry(irq, action);
@@ -173,7 +174,7 @@ irqreturn_t handle_irq_event_percpu(stru
 
 		retval |= res;
 		action = action->next;
-	} while (action);
+	}
 
 	add_interrupt_randomness(irq, flags);
 
--- zfcpdump-kernel-4.4.orig/kernel/irq/irqdomain.c
+++ zfcpdump-kernel-4.4/kernel/irq/irqdomain.c
@@ -60,6 +60,7 @@ struct fwnode_handle *irq_domain_alloc_f
 	fwid->fwnode.type = FWNODE_IRQCHIP;
 	return &fwid->fwnode;
 }
+EXPORT_SYMBOL_GPL(irq_domain_alloc_fwnode);
 
 /**
  * irq_domain_free_fwnode - Free a non-OF-backed fwnode_handle
@@ -70,13 +71,14 @@ void irq_domain_free_fwnode(struct fwnod
 {
 	struct irqchip_fwid *fwid;
 
-	if (WARN_ON(fwnode->type != FWNODE_IRQCHIP))
+	if (WARN_ON(!is_fwnode_irqchip(fwnode)))
 		return;
 
 	fwid = container_of(fwnode, struct irqchip_fwid, fwnode);
 	kfree(fwid->name);
 	kfree(fwid);
 }
+EXPORT_SYMBOL_GPL(irq_domain_free_fwnode);
 
 /**
  * __irq_domain_add() - Allocate a new irq_domain data structure
@@ -1013,6 +1015,7 @@ struct irq_data *irq_domain_get_irq_data
 
 	return NULL;
 }
+EXPORT_SYMBOL_GPL(irq_domain_get_irq_data);
 
 /**
  * irq_domain_set_hwirq_and_chip - Set hwirq and irqchip of @virq at @domain
@@ -1343,6 +1346,7 @@ struct irq_data *irq_domain_get_irq_data
 
 	return (irq_data && irq_data->domain == domain) ? irq_data : NULL;
 }
+EXPORT_SYMBOL_GPL(irq_domain_get_irq_data);
 
 /**
  * irq_domain_set_info - Set the complete data for a @virq in @domain
--- zfcpdump-kernel-4.4.orig/kernel/irq/manage.c
+++ zfcpdump-kernel-4.4/kernel/irq/manage.c
@@ -22,14 +22,20 @@
 #include "internals.h"
 
 #ifdef CONFIG_IRQ_FORCED_THREADING
-__read_mostly bool force_irqthreads;
+__read_mostly bool force_irqthreads = IS_ENABLED(CONFIG_IRQ_FORCED_THREADING_DEFAULT);
 
 static int __init setup_forced_irqthreads(char *arg)
 {
 	force_irqthreads = true;
 	return 0;
 }
+static int __init setup_no_irqthreads(char *arg)
+{
+	force_irqthreads = false;
+	return 0;
+}
 early_param("threadirqs", setup_forced_irqthreads);
+early_param("nothreadirqs", setup_no_irqthreads);
 #endif
 
 static void __synchronize_hardirq(struct irq_desc *desc)
--- zfcpdump-kernel-4.4.orig/kernel/irq/msi.c
+++ zfcpdump-kernel-4.4/kernel/irq/msi.c
@@ -268,7 +268,7 @@ int msi_domain_alloc_irqs(struct irq_dom
 	struct msi_domain_ops *ops = info->ops;
 	msi_alloc_info_t arg;
 	struct msi_desc *desc;
-	int i, ret, virq = -1;
+	int i, ret, virq;
 
 	ret = ops->msi_check(domain, info, dev);
 	if (ret == 0)
@@ -278,12 +278,8 @@ int msi_domain_alloc_irqs(struct irq_dom
 
 	for_each_msi_entry(desc, dev) {
 		ops->set_desc(&arg, desc);
-		if (info->flags & MSI_FLAG_IDENTITY_MAP)
-			virq = (int)ops->get_hwirq(info, &arg);
-		else
-			virq = -1;
 
-		virq = __irq_domain_alloc_irqs(domain, virq, desc->nvec_used,
+		virq = __irq_domain_alloc_irqs(domain, -1, desc->nvec_used,
 					       dev_to_node(dev), &arg, false);
 		if (virq < 0) {
 			ret = -ENOSPC;
@@ -302,11 +298,23 @@ int msi_domain_alloc_irqs(struct irq_dom
 		ops->msi_finish(&arg, 0);
 
 	for_each_msi_entry(desc, dev) {
+		virq = desc->irq;
 		if (desc->nvec_used == 1)
 			dev_dbg(dev, "irq %d for MSI\n", virq);
 		else
 			dev_dbg(dev, "irq [%d-%d] for MSI\n",
 				virq, virq + desc->nvec_used - 1);
+		/*
+		 * This flag is set by the PCI layer as we need to activate
+		 * the MSI entries before the PCI layer enables MSI in the
+		 * card. Otherwise the card latches a random msi message.
+		 */
+		if (info->flags & MSI_FLAG_ACTIVATE_EARLY) {
+			struct irq_data *irq_data;
+
+			irq_data = irq_domain_get_irq_data(domain, desc->irq);
+			irq_domain_activate_irq(irq_data);
+		}
 	}
 
 	return 0;
--- zfcpdump-kernel-4.4.orig/kernel/jump_label.c
+++ zfcpdump-kernel-4.4/kernel/jump_label.c
@@ -58,13 +58,36 @@ static void jump_label_update(struct sta
 
 void static_key_slow_inc(struct static_key *key)
 {
+	int v, v1;
+
 	STATIC_KEY_CHECK_USE();
-	if (atomic_inc_not_zero(&key->enabled))
-		return;
+
+	/*
+	 * Careful if we get concurrent static_key_slow_inc() calls;
+	 * later calls must wait for the first one to _finish_ the
+	 * jump_label_update() process.  At the same time, however,
+	 * the jump_label_update() call below wants to see
+	 * static_key_enabled(&key) for jumps to be updated properly.
+	 *
+	 * So give a special meaning to negative key->enabled: it sends
+	 * static_key_slow_inc() down the slow path, and it is non-zero
+	 * so it counts as "enabled" in jump_label_update().  Note that
+	 * atomic_inc_unless_negative() checks >= 0, so roll our own.
+	 */
+	for (v = atomic_read(&key->enabled); v > 0; v = v1) {
+		v1 = atomic_cmpxchg(&key->enabled, v, v + 1);
+		if (likely(v1 == v))
+			return;
+	}
 
 	jump_label_lock();
-	if (atomic_inc_return(&key->enabled) == 1)
+	if (atomic_read(&key->enabled) == 0) {
+		atomic_set(&key->enabled, -1);
 		jump_label_update(key);
+		atomic_set(&key->enabled, 1);
+	} else {
+		atomic_inc(&key->enabled);
+	}
 	jump_label_unlock();
 }
 EXPORT_SYMBOL_GPL(static_key_slow_inc);
@@ -72,6 +95,13 @@ EXPORT_SYMBOL_GPL(static_key_slow_inc);
 static void __static_key_slow_dec(struct static_key *key,
 		unsigned long rate_limit, struct delayed_work *work)
 {
+	/*
+	 * The negative count check is valid even when a negative
+	 * key->enabled is in use by static_key_slow_inc(); a
+	 * __static_key_slow_dec() before the first static_key_slow_inc()
+	 * returns is unbalanced, because all other static_key_slow_inc()
+	 * instances block while the update is in progress.
+	 */
 	if (!atomic_dec_and_mutex_lock(&key->enabled, &jump_label_mutex)) {
 		WARN(atomic_read(&key->enabled) < 0,
 		     "jump label: negative count!\n");
--- zfcpdump-kernel-4.4.orig/kernel/kcmp.c
+++ zfcpdump-kernel-4.4/kernel/kcmp.c
@@ -122,8 +122,8 @@ SYSCALL_DEFINE5(kcmp, pid_t, pid1, pid_t
 			&task2->signal->cred_guard_mutex);
 	if (ret)
 		goto err;
-	if (!ptrace_may_access(task1, PTRACE_MODE_READ) ||
-	    !ptrace_may_access(task2, PTRACE_MODE_READ)) {
+	if (!ptrace_may_access(task1, PTRACE_MODE_READ_REALCREDS) ||
+	    !ptrace_may_access(task2, PTRACE_MODE_READ_REALCREDS)) {
 		ret = -EPERM;
 		goto err_unlock;
 	}
--- zfcpdump-kernel-4.4.orig/kernel/kexec.c
+++ zfcpdump-kernel-4.4/kernel/kexec.c
@@ -17,6 +17,7 @@
 #include <linux/syscalls.h>
 #include <linux/vmalloc.h>
 #include <linux/slab.h>
+#include <linux/module.h>
 
 #include "kexec_internal.h"
 
@@ -131,7 +132,7 @@ SYSCALL_DEFINE4(kexec_load, unsigned lon
 	int result;
 
 	/* We only trust the superuser with rebooting the system. */
-	if (!capable(CAP_SYS_BOOT) || kexec_load_disabled)
+	if (!capable(CAP_SYS_BOOT) || kexec_load_disabled || secure_modules())
 		return -EPERM;
 
 	/*
--- zfcpdump-kernel-4.4.orig/kernel/kexec_file.c
+++ zfcpdump-kernel-4.4/kernel/kexec_file.c
@@ -934,7 +934,10 @@ int kexec_load_purgatory(struct kimage *
 	return 0;
 out:
 	vfree(pi->sechdrs);
+	pi->sechdrs = NULL;
+
 	vfree(pi->purgatory_buf);
+	pi->purgatory_buf = NULL;
 	return ret;
 }
 
--- zfcpdump-kernel-4.4.orig/kernel/kthread.c
+++ zfcpdump-kernel-4.4/kernel/kthread.c
@@ -295,6 +295,17 @@ struct task_struct *kthread_create_on_no
 	 * new kernel thread.
 	 */
 	if (unlikely(wait_for_completion_killable(&done))) {
+		int i = 0;
+
+		/*
+		 * I got SIGKILL, but wait for 10 more seconds for completion
+		 * unless chosen by the OOM killer. This delay is there as a
+		 * workaround for boot failure caused by SIGKILL upon device
+		 * driver initialization timeout.
+		 */
+		while (i++ < 10 && !test_tsk_thread_flag(current, TIF_MEMDIE))
+			if (wait_for_completion_timeout(&done, HZ))
+				goto ready;
 		/*
 		 * If I was SIGKILLed before kthreadd (or new kernel thread)
 		 * calls complete(), leave the cleanup of this structure to
@@ -308,6 +319,7 @@ struct task_struct *kthread_create_on_no
 		 */
 		wait_for_completion(&done);
 	}
+ready:
 	task = create->result;
 	if (!IS_ERR(task)) {
 		static const struct sched_param param = { .sched_priority = 0 };
--- zfcpdump-kernel-4.4.orig/kernel/livepatch/core.c
+++ zfcpdump-kernel-4.4/kernel/livepatch/core.c
@@ -28,6 +28,7 @@
 #include <linux/list.h>
 #include <linux/kallsyms.h>
 #include <linux/livepatch.h>
+#include <asm/cacheflush.h>
 
 /**
  * struct klp_ops - structure for tracking registered ftrace ops structs
@@ -135,13 +136,8 @@ struct klp_find_arg {
 	const char *objname;
 	const char *name;
 	unsigned long addr;
-	/*
-	 * If count == 0, the symbol was not found. If count == 1, a unique
-	 * match was found and addr is set.  If count > 1, there is
-	 * unresolvable ambiguity among "count" number of symbols with the same
-	 * name in the same object.
-	 */
 	unsigned long count;
+	unsigned long pos;
 };
 
 static int klp_find_callback(void *data, const char *name,
@@ -158,37 +154,48 @@ static int klp_find_callback(void *data,
 	if (args->objname && strcmp(args->objname, mod->name))
 		return 0;
 
-	/*
-	 * args->addr might be overwritten if another match is found
-	 * but klp_find_object_symbol() handles this and only returns the
-	 * addr if count == 1.
-	 */
 	args->addr = addr;
 	args->count++;
 
+	/*
+	 * Finish the search when the symbol is found for the desired position
+	 * or the position is not defined for a non-unique symbol.
+	 */
+	if ((args->pos && (args->count == args->pos)) ||
+	    (!args->pos && (args->count > 1)))
+		return 1;
+
 	return 0;
 }
 
 static int klp_find_object_symbol(const char *objname, const char *name,
-				  unsigned long *addr)
+				  unsigned long sympos, unsigned long *addr)
 {
 	struct klp_find_arg args = {
 		.objname = objname,
 		.name = name,
 		.addr = 0,
-		.count = 0
+		.count = 0,
+		.pos = sympos,
 	};
 
 	mutex_lock(&module_mutex);
 	kallsyms_on_each_symbol(klp_find_callback, &args);
 	mutex_unlock(&module_mutex);
 
-	if (args.count == 0)
+	/*
+	 * Ensure an address was found. If sympos is 0, ensure symbol is unique;
+	 * otherwise ensure the symbol position count matches sympos.
+	 */
+	if (args.addr == 0)
 		pr_err("symbol '%s' not found in symbol table\n", name);
-	else if (args.count > 1)
+	else if (args.count > 1 && sympos == 0) {
 		pr_err("unresolvable ambiguity (%lu matches) on symbol '%s' in object '%s'\n",
 		       args.count, name, objname);
-	else {
+	} else if (sympos != args.count && sympos > 0) {
+		pr_err("symbol position %lu for symbol '%s' in object '%s' not found\n",
+		       sympos, name, objname ? objname : "vmlinux");
+	} else {
 		*addr = args.addr;
 		return 0;
 	}
@@ -197,66 +204,6 @@ static int klp_find_object_symbol(const
 	return -EINVAL;
 }
 
-struct klp_verify_args {
-	const char *name;
-	const unsigned long addr;
-};
-
-static int klp_verify_callback(void *data, const char *name,
-			       struct module *mod, unsigned long addr)
-{
-	struct klp_verify_args *args = data;
-
-	if (!mod &&
-	    !strcmp(args->name, name) &&
-	    args->addr == addr)
-		return 1;
-
-	return 0;
-}
-
-static int klp_verify_vmlinux_symbol(const char *name, unsigned long addr)
-{
-	struct klp_verify_args args = {
-		.name = name,
-		.addr = addr,
-	};
-	int ret;
-
-	mutex_lock(&module_mutex);
-	ret = kallsyms_on_each_symbol(klp_verify_callback, &args);
-	mutex_unlock(&module_mutex);
-
-	if (!ret) {
-		pr_err("symbol '%s' not found at specified address 0x%016lx, kernel mismatch?\n",
-			name, addr);
-		return -EINVAL;
-	}
-
-	return 0;
-}
-
-static int klp_find_verify_func_addr(struct klp_object *obj,
-				     struct klp_func *func)
-{
-	int ret;
-
-#if defined(CONFIG_RANDOMIZE_BASE)
-	/* If KASLR has been enabled, adjust old_addr accordingly */
-	if (kaslr_enabled() && func->old_addr)
-		func->old_addr += kaslr_offset();
-#endif
-
-	if (!func->old_addr || klp_is_module(obj))
-		ret = klp_find_object_symbol(obj->name, func->old_name,
-					     &func->old_addr);
-	else
-		ret = klp_verify_vmlinux_symbol(func->old_name,
-						func->old_addr);
-
-	return ret;
-}
-
 /*
  * external symbols are located outside the parent object (where the parent
  * object is either vmlinux or the kmod being patched).
@@ -276,14 +223,18 @@ static int klp_find_external_symbol(stru
 	}
 	preempt_enable();
 
-	/* otherwise check if it's in another .o within the patch module */
-	return klp_find_object_symbol(pmod->name, name, addr);
+	/*
+	 * Check if it's in another .o within the patch module. This also
+	 * checks that the external symbol is unique.
+	 */
+	return klp_find_object_symbol(pmod->name, name, 0, addr);
 }
 
 static int klp_write_object_relocations(struct module *pmod,
 					struct klp_object *obj)
 {
-	int ret;
+	int ret = 0;
+	unsigned long val;
 	struct klp_reloc *reloc;
 
 	if (WARN_ON(!klp_is_object_loaded(obj)))
@@ -292,41 +243,38 @@ static int klp_write_object_relocations(
 	if (WARN_ON(!obj->relocs))
 		return -EINVAL;
 
+	module_disable_ro(pmod);
+
 	for (reloc = obj->relocs; reloc->name; reloc++) {
-		if (!klp_is_module(obj)) {
+		/* discover the address of the referenced symbol */
+		if (reloc->external) {
+			if (reloc->sympos > 0) {
+				pr_err("non-zero sympos for external reloc symbol '%s' is not supported\n",
+				       reloc->name);
+				ret = -EINVAL;
+				goto out;
+			}
+			ret = klp_find_external_symbol(pmod, reloc->name, &val);
+		} else
+			ret = klp_find_object_symbol(obj->name,
+						     reloc->name,
+						     reloc->sympos,
+						     &val);
+		if (ret)
+			goto out;
 
-#if defined(CONFIG_RANDOMIZE_BASE)
-			/* If KASLR has been enabled, adjust old value accordingly */
-			if (kaslr_enabled())
-				reloc->val += kaslr_offset();
-#endif
-			ret = klp_verify_vmlinux_symbol(reloc->name,
-							reloc->val);
-			if (ret)
-				return ret;
-		} else {
-			/* module, reloc->val needs to be discovered */
-			if (reloc->external)
-				ret = klp_find_external_symbol(pmod,
-							       reloc->name,
-							       &reloc->val);
-			else
-				ret = klp_find_object_symbol(obj->mod->name,
-							     reloc->name,
-							     &reloc->val);
-			if (ret)
-				return ret;
-		}
 		ret = klp_write_module_reloc(pmod, reloc->type, reloc->loc,
-					     reloc->val + reloc->addend);
+					     val + reloc->addend);
 		if (ret) {
 			pr_err("relocation failed for symbol '%s' at 0x%016lx (%d)\n",
-			       reloc->name, reloc->val, ret);
-			return ret;
+			       reloc->name, val, ret);
+			goto out;
 		}
 	}
 
-	return 0;
+out:
+	module_enable_ro(pmod);
+	return ret;
 }
 
 static void notrace klp_ftrace_handler(unsigned long ip,
@@ -593,7 +541,7 @@ EXPORT_SYMBOL_GPL(klp_enable_patch);
  * /sys/kernel/livepatch/<patch>
  * /sys/kernel/livepatch/<patch>/enabled
  * /sys/kernel/livepatch/<patch>/<object>
- * /sys/kernel/livepatch/<patch>/<object>/<func>
+ * /sys/kernel/livepatch/<patch>/<object>/<function,sympos>
  */
 
 static ssize_t enabled_store(struct kobject *kobj, struct kobj_attribute *attr,
@@ -738,8 +686,14 @@ static int klp_init_func(struct klp_obje
 	INIT_LIST_HEAD(&func->stack_node);
 	func->state = KLP_DISABLED;
 
+	/* The format for the sysfs directory is <function,sympos> where sympos
+	 * is the nth occurrence of this symbol in kallsyms for the patched
+	 * object. If the user selects 0 for old_sympos, then 1 will be used
+	 * since a unique symbol will be the first occurrence.
+	 */
 	return kobject_init_and_add(&func->kobj, &klp_ktype_func,
-				    &obj->kobj, "%s", func->old_name);
+				    &obj->kobj, "%s,%lu", func->old_name,
+				    func->old_sympos ? func->old_sympos : 1);
 }
 
 /* parts of the initialization that is done only when the object is loaded */
@@ -756,7 +710,9 @@ static int klp_init_object_loaded(struct
 	}
 
 	klp_for_each_func(obj, func) {
-		ret = klp_find_verify_func_addr(obj, func);
+		ret = klp_find_object_symbol(obj->name, func->old_name,
+					     func->old_sympos,
+					     &func->old_addr);
 		if (ret)
 			return ret;
 	}
--- zfcpdump-kernel-4.4.orig/kernel/locking/mcs_spinlock.h
+++ zfcpdump-kernel-4.4/kernel/locking/mcs_spinlock.h
@@ -67,7 +67,13 @@ void mcs_spin_lock(struct mcs_spinlock *
 	node->locked = 0;
 	node->next   = NULL;
 
-	prev = xchg_acquire(lock, node);
+	/*
+	 * We rely on the full barrier with global transitivity implied by the
+	 * below xchg() to order the initialization stores above against any
+	 * observation of @node. And to provide the ACQUIRE ordering associated
+	 * with a LOCK primitive.
+	 */
+	prev = xchg(lock, node);
 	if (likely(prev == NULL)) {
 		/*
 		 * Lock acquired, don't need to set node->locked to 1. Threads
--- zfcpdump-kernel-4.4.orig/kernel/locking/mutex.c
+++ zfcpdump-kernel-4.4/kernel/locking/mutex.c
@@ -486,9 +486,6 @@ __ww_mutex_lock_check_stamp(struct mutex
 	if (!hold_ctx)
 		return 0;
 
-	if (unlikely(ctx == hold_ctx))
-		return -EALREADY;
-
 	if (ctx->stamp - hold_ctx->stamp <= LONG_MAX &&
 	    (ctx->stamp != hold_ctx->stamp || ctx > hold_ctx)) {
 #ifdef CONFIG_DEBUG_MUTEXES
@@ -514,6 +511,12 @@ __mutex_lock_common(struct mutex *lock,
 	unsigned long flags;
 	int ret;
 
+	if (use_ww_ctx) {
+		struct ww_mutex *ww = container_of(lock, struct ww_mutex, base);
+		if (unlikely(ww_ctx == READ_ONCE(ww->ctx)))
+			return -EALREADY;
+	}
+
 	preempt_disable();
 	mutex_acquire_nest(&lock->dep_map, subclass, 0, nest_lock, ip);
 
--- zfcpdump-kernel-4.4.orig/kernel/locking/qspinlock.c
+++ zfcpdump-kernel-4.4/kernel/locking/qspinlock.c
@@ -255,6 +255,66 @@ static __always_inline void __pv_wait_he
 #define queued_spin_lock_slowpath	native_queued_spin_lock_slowpath
 #endif
 
+/*
+ * queued_spin_lock_slowpath() can (load-)ACQUIRE the lock before
+ * issuing an _unordered_ store to set _Q_LOCKED_VAL.
+ *
+ * This means that the store can be delayed, but no later than the
+ * store-release from the unlock. This means that simply observing
+ * _Q_LOCKED_VAL is not sufficient to determine if the lock is acquired.
+ *
+ * There are two paths that can issue the unordered store:
+ *
+ *  (1) clear_pending_set_locked():	*,1,0 -> *,0,1
+ *
+ *  (2) set_locked():			t,0,0 -> t,0,1 ; t != 0
+ *      atomic_cmpxchg_relaxed():	t,0,0 -> 0,0,1
+ *
+ * However, in both cases we have other !0 state we've set before to queue
+ * ourseves:
+ *
+ * For (1) we have the atomic_cmpxchg_acquire() that set _Q_PENDING_VAL, our
+ * load is constrained by that ACQUIRE to not pass before that, and thus must
+ * observe the store.
+ *
+ * For (2) we have a more intersting scenario. We enqueue ourselves using
+ * xchg_tail(), which ends up being a RELEASE. This in itself is not
+ * sufficient, however that is followed by an smp_cond_acquire() on the same
+ * word, giving a RELEASE->ACQUIRE ordering. This again constrains our load and
+ * guarantees we must observe that store.
+ *
+ * Therefore both cases have other !0 state that is observable before the
+ * unordered locked byte store comes through. This means we can use that to
+ * wait for the lock store, and then wait for an unlock.
+ */
+#ifndef queued_spin_unlock_wait
+void queued_spin_unlock_wait(struct qspinlock *lock)
+{
+	u32 val;
+
+	for (;;) {
+		val = atomic_read(&lock->val);
+
+		if (!val) /* not locked, we're done */
+			goto done;
+
+		if (val & _Q_LOCKED_MASK) /* locked, go wait for unlock */
+			break;
+
+		/* not locked, but pending, wait until we observe the lock */
+		cpu_relax();
+	}
+
+	/* any unlock is good */
+	while (atomic_read(&lock->val) & _Q_LOCKED_MASK)
+		cpu_relax();
+
+done:
+	smp_rmb(); /* CTRL + RMB -> ACQUIRE */
+}
+EXPORT_SYMBOL(queued_spin_unlock_wait);
+#endif
+
 #endif /* _GEN_PV_LOCK_SLOWPATH */
 
 /**
--- zfcpdump-kernel-4.4.orig/kernel/memremap.c
+++ zfcpdump-kernel-4.4/kernel/memremap.c
@@ -111,7 +111,7 @@ EXPORT_SYMBOL(memunmap);
 
 static void devm_memremap_release(struct device *dev, void *res)
 {
-	memunmap(res);
+	memunmap(*(void **)res);
 }
 
 static int devm_memremap_match(struct device *dev, void *res, void *match_data)
@@ -133,8 +133,10 @@ void *devm_memremap(struct device *dev,
 	if (addr) {
 		*ptr = addr;
 		devres_add(dev, ptr);
-	} else
+	} else {
 		devres_free(ptr);
+		return ERR_PTR(-ENXIO);
+	}
 
 	return addr;
 }
--- /dev/null
+++ zfcpdump-kernel-4.4/kernel/modsign_uefi.c
@@ -0,0 +1,114 @@
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/cred.h>
+#include <linux/err.h>
+#include <linux/efi.h>
+#include <linux/slab.h>
+#include <keys/asymmetric-type.h>
+#include <keys/system_keyring.h>
+#include "module-internal.h"
+
+static __init int check_ignore_db(void)
+{
+	efi_status_t status;
+	unsigned int db = 0;
+	unsigned long size = sizeof(db);
+	efi_guid_t guid = EFI_SHIM_LOCK_GUID;
+
+	/* Check and see if the MokIgnoreDB variable exists.  If that fails
+	 * then we don't ignore DB.  If it succeeds, we do.
+	 */
+	status = efi.get_variable(L"MokIgnoreDB", &guid, NULL, &size, &db);
+	if (status != EFI_SUCCESS)
+		return 0;
+
+	return 1;
+}
+
+static __init void *get_cert_list(efi_char16_t *name, efi_guid_t *guid, unsigned long *size)
+{
+	efi_status_t status;
+	unsigned long lsize = 4;
+	unsigned long tmpdb[4];
+	void *db = NULL;
+
+	status = efi.get_variable(name, guid, NULL, &lsize, &tmpdb);
+	if (status != EFI_BUFFER_TOO_SMALL) {
+		pr_err("Couldn't get size: 0x%lx\n", status);
+		return NULL;
+	}
+
+	db = kmalloc(lsize, GFP_KERNEL);
+	if (!db) {
+		pr_err("Couldn't allocate memory for uefi cert list\n");
+		goto out;
+	}
+
+	status = efi.get_variable(name, guid, NULL, &lsize, db);
+	if (status != EFI_SUCCESS) {
+		kfree(db);
+		db = NULL;
+		pr_err("Error reading db var: 0x%lx\n", status);
+	}
+out:
+	*size = lsize;
+	return db;
+}
+
+/*
+ *  * Load the certs contained in the UEFI databases
+ *   */
+static int __init load_uefi_certs(void)
+{
+	efi_guid_t secure_var = EFI_IMAGE_SECURITY_DATABASE_GUID;
+	efi_guid_t mok_var = EFI_SHIM_LOCK_GUID;
+	void *db = NULL, *dbx = NULL, *mok = NULL;
+	unsigned long dbsize = 0, dbxsize = 0, moksize = 0;
+	int ignore_db, rc = 0;
+
+	/* Check if SB is enabled and just return if not */
+	if (!efi_enabled(EFI_SECURE_BOOT))
+		return 0;
+
+	/* See if the user has setup Ignore DB mode */
+	ignore_db = check_ignore_db();
+
+	/* Get db, MokListRT, and dbx.  They might not exist, so it isn't
+	 * an error if we can't get them.
+	 */
+	if (!ignore_db) {
+		db = get_cert_list(L"db", &secure_var, &dbsize);
+		if (!db) {
+			pr_err("MODSIGN: Couldn't get UEFI db list\n");
+		} else {
+			rc = parse_efi_signature_list(db, dbsize, system_trusted_keyring);
+			if (rc)
+				pr_err("Couldn't parse db signatures: %d\n", rc);
+			kfree(db);
+		}
+	}
+
+	mok = get_cert_list(L"MokListRT", &mok_var, &moksize);
+	if (!mok) {
+		pr_info("MODSIGN: Couldn't get UEFI MokListRT\n");
+	} else {
+		rc = parse_efi_signature_list(mok, moksize, system_trusted_keyring);
+		if (rc)
+			pr_err("Couldn't parse MokListRT signatures: %d\n", rc);
+		kfree(mok);
+	}
+
+	dbx = get_cert_list(L"dbx", &secure_var, &dbxsize);
+	if (!dbx) {
+		pr_info("MODSIGN: Couldn't get UEFI dbx list\n");
+	} else {
+		rc = parse_efi_signature_list(dbx, dbxsize,
+			system_blacklist_keyring);
+		if (rc)
+			pr_err("Couldn't parse dbx signatures: %d\n", rc);
+		kfree(dbx);
+	}
+
+	return rc;
+}
+late_initcall(load_uefi_certs);
--- zfcpdump-kernel-4.4.orig/kernel/module.c
+++ zfcpdump-kernel-4.4/kernel/module.c
@@ -80,15 +80,6 @@
 # define debug_align(X) (X)
 #endif
 
-/*
- * Given BASE and SIZE this macro calculates the number of pages the
- * memory regions occupies
- */
-#define MOD_NUMBER_OF_PAGES(BASE, SIZE) (((SIZE) > 0) ?		\
-		(PFN_DOWN((unsigned long)(BASE) + (SIZE) - 1) -	\
-			 PFN_DOWN((unsigned long)BASE) + 1)	\
-		: (0UL))
-
 /* If this is set, the section belongs in the init part of the module */
 #define INIT_OFFSET_MASK (1UL << (BITS_PER_LONG-1))
 
@@ -108,13 +99,6 @@ static LIST_HEAD(modules);
  * Use a latched RB-tree for __module_address(); this allows us to use
  * RCU-sched lookups of the address from any context.
  *
- * Because modules have two address ranges: init and core, we need two
- * latch_tree_nodes entries. Therefore we need the back-pointer from
- * mod_tree_node.
- *
- * Because init ranges are short lived we mark them unlikely and have placed
- * them outside the critical cacheline in struct module.
- *
  * This is conditional on PERF_EVENTS || TRACING because those can really hit
  * __module_address() hard by doing a lot of stack unwinding; potentially from
  * NMI context.
@@ -122,24 +106,16 @@ static LIST_HEAD(modules);
 
 static __always_inline unsigned long __mod_tree_val(struct latch_tree_node *n)
 {
-	struct mod_tree_node *mtn = container_of(n, struct mod_tree_node, node);
-	struct module *mod = mtn->mod;
-
-	if (unlikely(mtn == &mod->mtn_init))
-		return (unsigned long)mod->module_init;
+	struct module_layout *layout = container_of(n, struct module_layout, mtn.node);
 
-	return (unsigned long)mod->module_core;
+	return (unsigned long)layout->base;
 }
 
 static __always_inline unsigned long __mod_tree_size(struct latch_tree_node *n)
 {
-	struct mod_tree_node *mtn = container_of(n, struct mod_tree_node, node);
-	struct module *mod = mtn->mod;
+	struct module_layout *layout = container_of(n, struct module_layout, mtn.node);
 
-	if (unlikely(mtn == &mod->mtn_init))
-		return (unsigned long)mod->init_size;
-
-	return (unsigned long)mod->core_size;
+	return (unsigned long)layout->size;
 }
 
 static __always_inline bool
@@ -197,23 +173,23 @@ static void __mod_tree_remove(struct mod
  */
 static void mod_tree_insert(struct module *mod)
 {
-	mod->mtn_core.mod = mod;
-	mod->mtn_init.mod = mod;
+	mod->core_layout.mtn.mod = mod;
+	mod->init_layout.mtn.mod = mod;
 
-	__mod_tree_insert(&mod->mtn_core);
-	if (mod->init_size)
-		__mod_tree_insert(&mod->mtn_init);
+	__mod_tree_insert(&mod->core_layout.mtn);
+	if (mod->init_layout.size)
+		__mod_tree_insert(&mod->init_layout.mtn);
 }
 
 static void mod_tree_remove_init(struct module *mod)
 {
-	if (mod->init_size)
-		__mod_tree_remove(&mod->mtn_init);
+	if (mod->init_layout.size)
+		__mod_tree_remove(&mod->init_layout.mtn);
 }
 
 static void mod_tree_remove(struct module *mod)
 {
-	__mod_tree_remove(&mod->mtn_core);
+	__mod_tree_remove(&mod->core_layout.mtn);
 	mod_tree_remove_init(mod);
 }
 
@@ -267,9 +243,9 @@ static void __mod_update_bounds(void *ba
 
 static void mod_update_bounds(struct module *mod)
 {
-	__mod_update_bounds(mod->module_core, mod->core_size);
-	if (mod->init_size)
-		__mod_update_bounds(mod->module_init, mod->init_size);
+	__mod_update_bounds(mod->core_layout.base, mod->core_layout.size);
+	if (mod->init_layout.size)
+		__mod_update_bounds(mod->init_layout.base, mod->init_layout.size);
 }
 
 #ifdef CONFIG_KGDB_KDB
@@ -327,6 +303,9 @@ struct load_info {
 	struct _ddebug *debug;
 	unsigned int num_debug;
 	bool sig_ok;
+#ifdef CONFIG_KALLSYMS
+	unsigned long mod_kallsyms_init_off;
+#endif
 	struct {
 		unsigned int sym, str, mod, vers, info, pcpu;
 	} index;
@@ -1214,7 +1193,7 @@ struct module_attribute module_uevent =
 static ssize_t show_coresize(struct module_attribute *mattr,
 			     struct module_kobject *mk, char *buffer)
 {
-	return sprintf(buffer, "%u\n", mk->mod->core_size);
+	return sprintf(buffer, "%u\n", mk->mod->core_layout.size);
 }
 
 static struct module_attribute modinfo_coresize =
@@ -1223,7 +1202,7 @@ static struct module_attribute modinfo_c
 static ssize_t show_initsize(struct module_attribute *mattr,
 			     struct module_kobject *mk, char *buffer)
 {
-	return sprintf(buffer, "%u\n", mk->mod->init_size);
+	return sprintf(buffer, "%u\n", mk->mod->init_layout.size);
 }
 
 static struct module_attribute modinfo_initsize =
@@ -1873,64 +1852,75 @@ static void mod_sysfs_teardown(struct mo
 /*
  * LKM RO/NX protection: protect module's text/ro-data
  * from modification and any data from execution.
+ *
+ * General layout of module is:
+ *          [text] [read-only-data] [writable data]
+ * text_size -----^                ^               ^
+ * ro_size ------------------------|               |
+ * size -------------------------------------------|
+ *
+ * These values are always page-aligned (as is base)
  */
-void set_page_attributes(void *start, void *end, int (*set)(unsigned long start, int num_pages))
+static void frob_text(const struct module_layout *layout,
+		      int (*set_memory)(unsigned long start, int num_pages))
 {
-	unsigned long begin_pfn = PFN_DOWN((unsigned long)start);
-	unsigned long end_pfn = PFN_DOWN((unsigned long)end);
+	BUG_ON((unsigned long)layout->base & (PAGE_SIZE-1));
+	BUG_ON((unsigned long)layout->text_size & (PAGE_SIZE-1));
+	set_memory((unsigned long)layout->base,
+		   layout->text_size >> PAGE_SHIFT);
+}
 
-	if (end_pfn > begin_pfn)
-		set(begin_pfn << PAGE_SHIFT, end_pfn - begin_pfn);
+static void frob_rodata(const struct module_layout *layout,
+			int (*set_memory)(unsigned long start, int num_pages))
+{
+	BUG_ON((unsigned long)layout->base & (PAGE_SIZE-1));
+	BUG_ON((unsigned long)layout->text_size & (PAGE_SIZE-1));
+	BUG_ON((unsigned long)layout->ro_size & (PAGE_SIZE-1));
+	set_memory((unsigned long)layout->base + layout->text_size,
+		   (layout->ro_size - layout->text_size) >> PAGE_SHIFT);
 }
 
-static void set_section_ro_nx(void *base,
-			unsigned long text_size,
-			unsigned long ro_size,
-			unsigned long total_size)
+static void frob_writable_data(const struct module_layout *layout,
+			       int (*set_memory)(unsigned long start, int num_pages))
 {
-	/* begin and end PFNs of the current subsection */
-	unsigned long begin_pfn;
-	unsigned long end_pfn;
+	BUG_ON((unsigned long)layout->base & (PAGE_SIZE-1));
+	BUG_ON((unsigned long)layout->ro_size & (PAGE_SIZE-1));
+	BUG_ON((unsigned long)layout->size & (PAGE_SIZE-1));
+	set_memory((unsigned long)layout->base + layout->ro_size,
+		   (layout->size - layout->ro_size) >> PAGE_SHIFT);
+}
 
-	/*
-	 * Set RO for module text and RO-data:
-	 * - Always protect first page.
-	 * - Do not protect last partial page.
-	 */
-	if (ro_size > 0)
-		set_page_attributes(base, base + ro_size, set_memory_ro);
+/* livepatching wants to disable read-only so it can frob module. */
+void module_disable_ro(const struct module *mod)
+{
+	frob_text(&mod->core_layout, set_memory_rw);
+	frob_rodata(&mod->core_layout, set_memory_rw);
+	frob_text(&mod->init_layout, set_memory_rw);
+	frob_rodata(&mod->init_layout, set_memory_rw);
+}
 
-	/*
-	 * Set NX permissions for module data:
-	 * - Do not protect first partial page.
-	 * - Always protect last page.
-	 */
-	if (total_size > text_size) {
-		begin_pfn = PFN_UP((unsigned long)base + text_size);
-		end_pfn = PFN_UP((unsigned long)base + total_size);
-		if (end_pfn > begin_pfn)
-			set_memory_nx(begin_pfn << PAGE_SHIFT, end_pfn - begin_pfn);
-	}
+void module_enable_ro(const struct module *mod)
+{
+	frob_text(&mod->core_layout, set_memory_ro);
+	frob_rodata(&mod->core_layout, set_memory_ro);
+	frob_text(&mod->init_layout, set_memory_ro);
+	frob_rodata(&mod->init_layout, set_memory_ro);
 }
 
-static void unset_module_core_ro_nx(struct module *mod)
+static void module_enable_nx(const struct module *mod)
 {
-	set_page_attributes(mod->module_core + mod->core_text_size,
-		mod->module_core + mod->core_size,
-		set_memory_x);
-	set_page_attributes(mod->module_core,
-		mod->module_core + mod->core_ro_size,
-		set_memory_rw);
+	frob_rodata(&mod->core_layout, set_memory_nx);
+	frob_writable_data(&mod->core_layout, set_memory_nx);
+	frob_rodata(&mod->init_layout, set_memory_nx);
+	frob_writable_data(&mod->init_layout, set_memory_nx);
 }
 
-static void unset_module_init_ro_nx(struct module *mod)
+static void module_disable_nx(const struct module *mod)
 {
-	set_page_attributes(mod->module_init + mod->init_text_size,
-		mod->module_init + mod->init_size,
-		set_memory_x);
-	set_page_attributes(mod->module_init,
-		mod->module_init + mod->init_ro_size,
-		set_memory_rw);
+	frob_rodata(&mod->core_layout, set_memory_x);
+	frob_writable_data(&mod->core_layout, set_memory_x);
+	frob_rodata(&mod->init_layout, set_memory_x);
+	frob_writable_data(&mod->init_layout, set_memory_x);
 }
 
 /* Iterate through all modules and set each module's text as RW */
@@ -1942,16 +1932,9 @@ void set_all_modules_text_rw(void)
 	list_for_each_entry_rcu(mod, &modules, list) {
 		if (mod->state == MODULE_STATE_UNFORMED)
 			continue;
-		if ((mod->module_core) && (mod->core_text_size)) {
-			set_page_attributes(mod->module_core,
-						mod->module_core + mod->core_text_size,
-						set_memory_rw);
-		}
-		if ((mod->module_init) && (mod->init_text_size)) {
-			set_page_attributes(mod->module_init,
-						mod->module_init + mod->init_text_size,
-						set_memory_rw);
-		}
+
+		frob_text(&mod->core_layout, set_memory_rw);
+		frob_text(&mod->init_layout, set_memory_rw);
 	}
 	mutex_unlock(&module_mutex);
 }
@@ -1965,23 +1948,25 @@ void set_all_modules_text_ro(void)
 	list_for_each_entry_rcu(mod, &modules, list) {
 		if (mod->state == MODULE_STATE_UNFORMED)
 			continue;
-		if ((mod->module_core) && (mod->core_text_size)) {
-			set_page_attributes(mod->module_core,
-						mod->module_core + mod->core_text_size,
-						set_memory_ro);
-		}
-		if ((mod->module_init) && (mod->init_text_size)) {
-			set_page_attributes(mod->module_init,
-						mod->module_init + mod->init_text_size,
-						set_memory_ro);
-		}
+
+		frob_text(&mod->core_layout, set_memory_ro);
+		frob_text(&mod->init_layout, set_memory_ro);
 	}
 	mutex_unlock(&module_mutex);
 }
+
+static void disable_ro_nx(const struct module_layout *layout)
+{
+	frob_text(layout, set_memory_rw);
+	frob_rodata(layout, set_memory_rw);
+	frob_rodata(layout, set_memory_x);
+	frob_writable_data(layout, set_memory_x);
+}
+
 #else
-static inline void set_section_ro_nx(void *base, unsigned long text_size, unsigned long ro_size, unsigned long total_size) { }
-static void unset_module_core_ro_nx(struct module *mod) { }
-static void unset_module_init_ro_nx(struct module *mod) { }
+static void disable_ro_nx(const struct module_layout *layout) { }
+static void module_enable_nx(const struct module *mod) { }
+static void module_disable_nx(const struct module *mod) { }
 #endif
 
 void __weak module_memfree(void *module_region)
@@ -2033,19 +2018,19 @@ static void free_module(struct module *m
 	synchronize_sched();
 	mutex_unlock(&module_mutex);
 
-	/* This may be NULL, but that's OK */
-	unset_module_init_ro_nx(mod);
+	/* This may be empty, but that's OK */
+	disable_ro_nx(&mod->init_layout);
 	module_arch_freeing_init(mod);
-	module_memfree(mod->module_init);
+	module_memfree(mod->init_layout.base);
 	kfree(mod->args);
 	percpu_modfree(mod);
 
 	/* Free lock-classes; relies on the preceding sync_rcu(). */
-	lockdep_free_key_range(mod->module_core, mod->core_size);
+	lockdep_free_key_range(mod->core_layout.base, mod->core_layout.size);
 
 	/* Finally, free the core (containing the module structure) */
-	unset_module_core_ro_nx(mod);
-	module_memfree(mod->module_core);
+	disable_ro_nx(&mod->core_layout);
+	module_memfree(mod->core_layout.base);
 
 #ifdef CONFIG_MPU
 	update_protections(current->mm);
@@ -2248,20 +2233,20 @@ static void layout_sections(struct modul
 			    || s->sh_entsize != ~0UL
 			    || strstarts(sname, ".init"))
 				continue;
-			s->sh_entsize = get_offset(mod, &mod->core_size, s, i);
+			s->sh_entsize = get_offset(mod, &mod->core_layout.size, s, i);
 			pr_debug("\t%s\n", sname);
 		}
 		switch (m) {
 		case 0: /* executable */
-			mod->core_size = debug_align(mod->core_size);
-			mod->core_text_size = mod->core_size;
+			mod->core_layout.size = debug_align(mod->core_layout.size);
+			mod->core_layout.text_size = mod->core_layout.size;
 			break;
 		case 1: /* RO: text and ro-data */
-			mod->core_size = debug_align(mod->core_size);
-			mod->core_ro_size = mod->core_size;
+			mod->core_layout.size = debug_align(mod->core_layout.size);
+			mod->core_layout.ro_size = mod->core_layout.size;
 			break;
 		case 3: /* whole core */
-			mod->core_size = debug_align(mod->core_size);
+			mod->core_layout.size = debug_align(mod->core_layout.size);
 			break;
 		}
 	}
@@ -2277,21 +2262,21 @@ static void layout_sections(struct modul
 			    || s->sh_entsize != ~0UL
 			    || !strstarts(sname, ".init"))
 				continue;
-			s->sh_entsize = (get_offset(mod, &mod->init_size, s, i)
+			s->sh_entsize = (get_offset(mod, &mod->init_layout.size, s, i)
 					 | INIT_OFFSET_MASK);
 			pr_debug("\t%s\n", sname);
 		}
 		switch (m) {
 		case 0: /* executable */
-			mod->init_size = debug_align(mod->init_size);
-			mod->init_text_size = mod->init_size;
+			mod->init_layout.size = debug_align(mod->init_layout.size);
+			mod->init_layout.text_size = mod->init_layout.size;
 			break;
 		case 1: /* RO: text and ro-data */
-			mod->init_size = debug_align(mod->init_size);
-			mod->init_ro_size = mod->init_size;
+			mod->init_layout.size = debug_align(mod->init_layout.size);
+			mod->init_layout.ro_size = mod->init_layout.size;
 			break;
 		case 3: /* whole init */
-			mod->init_size = debug_align(mod->init_size);
+			mod->init_layout.size = debug_align(mod->init_layout.size);
 			break;
 		}
 	}
@@ -2401,7 +2386,7 @@ static char elf_type(const Elf_Sym *sym,
 	}
 	if (sym->st_shndx == SHN_UNDEF)
 		return 'U';
-	if (sym->st_shndx == SHN_ABS)
+	if (sym->st_shndx == SHN_ABS || sym->st_shndx == info->index.pcpu)
 		return 'a';
 	if (sym->st_shndx >= SHN_LORESERVE)
 		return '?';
@@ -2430,7 +2415,7 @@ static char elf_type(const Elf_Sym *sym,
 }
 
 static bool is_core_symbol(const Elf_Sym *src, const Elf_Shdr *sechdrs,
-			unsigned int shnum)
+			unsigned int shnum, unsigned int pcpundx)
 {
 	const Elf_Shdr *sec;
 
@@ -2439,6 +2424,11 @@ static bool is_core_symbol(const Elf_Sym
 	    || !src->st_name)
 		return false;
 
+#ifdef CONFIG_KALLSYMS_ALL
+	if (src->st_shndx == pcpundx)
+		return true;
+#endif
+
 	sec = sechdrs + src->st_shndx;
 	if (!(sec->sh_flags & SHF_ALLOC)
 #ifndef CONFIG_KALLSYMS_ALL
@@ -2466,7 +2456,7 @@ static void layout_symtab(struct module
 
 	/* Put symbol section at end of init part of module. */
 	symsect->sh_flags |= SHF_ALLOC;
-	symsect->sh_entsize = get_offset(mod, &mod->init_size, symsect,
+	symsect->sh_entsize = get_offset(mod, &mod->init_layout.size, symsect,
 					 info->index.sym) | INIT_OFFSET_MASK;
 	pr_debug("\t%s\n", info->secstrings + symsect->sh_name);
 
@@ -2476,26 +2466,38 @@ static void layout_symtab(struct module
 	/* Compute total space required for the core symbols' strtab. */
 	for (ndst = i = 0; i < nsrc; i++) {
 		if (i == 0 ||
-		    is_core_symbol(src+i, info->sechdrs, info->hdr->e_shnum)) {
+		    is_core_symbol(src+i, info->sechdrs, info->hdr->e_shnum,
+				   info->index.pcpu)) {
 			strtab_size += strlen(&info->strtab[src[i].st_name])+1;
 			ndst++;
 		}
 	}
 
 	/* Append room for core symbols at end of core part. */
-	info->symoffs = ALIGN(mod->core_size, symsect->sh_addralign ?: 1);
-	info->stroffs = mod->core_size = info->symoffs + ndst * sizeof(Elf_Sym);
-	mod->core_size += strtab_size;
-	mod->core_size = debug_align(mod->core_size);
+	info->symoffs = ALIGN(mod->core_layout.size, symsect->sh_addralign ?: 1);
+	info->stroffs = mod->core_layout.size = info->symoffs + ndst * sizeof(Elf_Sym);
+	mod->core_layout.size += strtab_size;
+	mod->core_layout.size = debug_align(mod->core_layout.size);
 
 	/* Put string table section at end of init part of module. */
 	strsect->sh_flags |= SHF_ALLOC;
-	strsect->sh_entsize = get_offset(mod, &mod->init_size, strsect,
+	strsect->sh_entsize = get_offset(mod, &mod->init_layout.size, strsect,
 					 info->index.str) | INIT_OFFSET_MASK;
-	mod->init_size = debug_align(mod->init_size);
 	pr_debug("\t%s\n", info->secstrings + strsect->sh_name);
+
+	/* We'll tack temporary mod_kallsyms on the end. */
+	mod->init_layout.size = ALIGN(mod->init_layout.size,
+				      __alignof__(struct mod_kallsyms));
+	info->mod_kallsyms_init_off = mod->init_layout.size;
+	mod->init_layout.size += sizeof(struct mod_kallsyms);
+	mod->init_layout.size = debug_align(mod->init_layout.size);
 }
 
+/*
+ * We use the full symtab and strtab which layout_symtab arranged to
+ * be appended to the init section.  Later we switch to the cut-down
+ * core-only ones.
+ */
 static void add_kallsyms(struct module *mod, const struct load_info *info)
 {
 	unsigned int i, ndst;
@@ -2504,28 +2506,34 @@ static void add_kallsyms(struct module *
 	char *s;
 	Elf_Shdr *symsec = &info->sechdrs[info->index.sym];
 
-	mod->symtab = (void *)symsec->sh_addr;
-	mod->num_symtab = symsec->sh_size / sizeof(Elf_Sym);
+	/* Set up to point into init section. */
+	mod->kallsyms = mod->init_layout.base + info->mod_kallsyms_init_off;
+
+	mod->kallsyms->symtab = (void *)symsec->sh_addr;
+	mod->kallsyms->num_symtab = symsec->sh_size / sizeof(Elf_Sym);
 	/* Make sure we get permanent strtab: don't use info->strtab. */
-	mod->strtab = (void *)info->sechdrs[info->index.str].sh_addr;
+	mod->kallsyms->strtab = (void *)info->sechdrs[info->index.str].sh_addr;
 
 	/* Set types up while we still have access to sections. */
-	for (i = 0; i < mod->num_symtab; i++)
-		mod->symtab[i].st_info = elf_type(&mod->symtab[i], info);
-
-	mod->core_symtab = dst = mod->module_core + info->symoffs;
-	mod->core_strtab = s = mod->module_core + info->stroffs;
-	src = mod->symtab;
-	for (ndst = i = 0; i < mod->num_symtab; i++) {
+	for (i = 0; i < mod->kallsyms->num_symtab; i++)
+		mod->kallsyms->symtab[i].st_info
+			= elf_type(&mod->kallsyms->symtab[i], info);
+
+	/* Now populate the cut down core kallsyms for after init. */
+	mod->core_kallsyms.symtab = dst = mod->core_layout.base + info->symoffs;
+	mod->core_kallsyms.strtab = s = mod->core_layout.base + info->stroffs;
+	src = mod->kallsyms->symtab;
+	for (ndst = i = 0; i < mod->kallsyms->num_symtab; i++) {
 		if (i == 0 ||
-		    is_core_symbol(src+i, info->sechdrs, info->hdr->e_shnum)) {
+		    is_core_symbol(src+i, info->sechdrs, info->hdr->e_shnum,
+				   info->index.pcpu)) {
 			dst[ndst] = src[i];
-			dst[ndst++].st_name = s - mod->core_strtab;
-			s += strlcpy(s, &mod->strtab[src[i].st_name],
+			dst[ndst++].st_name = s - mod->core_kallsyms.strtab;
+			s += strlcpy(s, &mod->kallsyms->strtab[src[i].st_name],
 				     KSYM_NAME_LEN) + 1;
 		}
 	}
-	mod->core_num_syms = ndst;
+	mod->core_kallsyms.num_symtab = ndst;
 }
 #else
 static inline void layout_symtab(struct module *mod, struct load_info *info)
@@ -2587,13 +2595,18 @@ static inline void kmemleak_load_module(
 #endif
 
 #ifdef CONFIG_MODULE_SIG
-static int module_sig_check(struct load_info *info)
+static int module_sig_check(struct load_info *info, int flags)
 {
 	int err = -ENOKEY;
 	const unsigned long markerlen = sizeof(MODULE_SIG_STRING) - 1;
 	const void *mod = info->hdr;
 
-	if (info->len > markerlen &&
+	/*
+	 * Require flags == 0, as a module with version information
+	 * removed is no longer the module that was signed
+	 */
+	if (flags == 0 &&
+	    info->len > markerlen &&
 	    memcmp(mod + info->len - markerlen, MODULE_SIG_STRING, markerlen) == 0) {
 		/* We truncate the module to discard the signature */
 		info->len -= markerlen;
@@ -2612,7 +2625,7 @@ static int module_sig_check(struct load_
 	return err;
 }
 #else /* !CONFIG_MODULE_SIG */
-static int module_sig_check(struct load_info *info)
+static int module_sig_check(struct load_info *info, int flags)
 {
 	return 0;
 }
@@ -2964,7 +2977,7 @@ static int move_module(struct module *mo
 	void *ptr;
 
 	/* Do the allocs. */
-	ptr = module_alloc(mod->core_size);
+	ptr = module_alloc(mod->core_layout.size);
 	/*
 	 * The pointer to this block is stored in the module structure
 	 * which is inside the block. Just mark it as not being a
@@ -2974,11 +2987,11 @@ static int move_module(struct module *mo
 	if (!ptr)
 		return -ENOMEM;
 
-	memset(ptr, 0, mod->core_size);
-	mod->module_core = ptr;
+	memset(ptr, 0, mod->core_layout.size);
+	mod->core_layout.base = ptr;
 
-	if (mod->init_size) {
-		ptr = module_alloc(mod->init_size);
+	if (mod->init_layout.size) {
+		ptr = module_alloc(mod->init_layout.size);
 		/*
 		 * The pointer to this block is stored in the module structure
 		 * which is inside the block. This block doesn't need to be
@@ -2987,13 +3000,13 @@ static int move_module(struct module *mo
 		 */
 		kmemleak_ignore(ptr);
 		if (!ptr) {
-			module_memfree(mod->module_core);
+			module_memfree(mod->core_layout.base);
 			return -ENOMEM;
 		}
-		memset(ptr, 0, mod->init_size);
-		mod->module_init = ptr;
+		memset(ptr, 0, mod->init_layout.size);
+		mod->init_layout.base = ptr;
 	} else
-		mod->module_init = NULL;
+		mod->init_layout.base = NULL;
 
 	/* Transfer each section which specifies SHF_ALLOC */
 	pr_debug("final section addresses:\n");
@@ -3005,10 +3018,10 @@ static int move_module(struct module *mo
 			continue;
 
 		if (shdr->sh_entsize & INIT_OFFSET_MASK)
-			dest = mod->module_init
+			dest = mod->init_layout.base
 				+ (shdr->sh_entsize & ~INIT_OFFSET_MASK);
 		else
-			dest = mod->module_core + shdr->sh_entsize;
+			dest = mod->core_layout.base + shdr->sh_entsize;
 
 		if (shdr->sh_type != SHT_NOBITS)
 			memcpy(dest, (void *)shdr->sh_addr, shdr->sh_size);
@@ -3070,12 +3083,12 @@ static void flush_module_icache(const st
 	 * Do it before processing of module parameters, so the module
 	 * can provide parameter accessor functions of its own.
 	 */
-	if (mod->module_init)
-		flush_icache_range((unsigned long)mod->module_init,
-				   (unsigned long)mod->module_init
-				   + mod->init_size);
-	flush_icache_range((unsigned long)mod->module_core,
-			   (unsigned long)mod->module_core + mod->core_size);
+	if (mod->init_layout.base)
+		flush_icache_range((unsigned long)mod->init_layout.base,
+				   (unsigned long)mod->init_layout.base
+				   + mod->init_layout.size);
+	flush_icache_range((unsigned long)mod->core_layout.base,
+			   (unsigned long)mod->core_layout.base + mod->core_layout.size);
 
 	set_fs(old_fs);
 }
@@ -3133,8 +3146,8 @@ static void module_deallocate(struct mod
 {
 	percpu_modfree(mod);
 	module_arch_freeing_init(mod);
-	module_memfree(mod->module_init);
-	module_memfree(mod->module_core);
+	module_memfree(mod->init_layout.base);
+	module_memfree(mod->core_layout.base);
 }
 
 int __weak module_finalize(const Elf_Ehdr *hdr,
@@ -3221,7 +3234,7 @@ static noinline int do_init_module(struc
 		ret = -ENOMEM;
 		goto fail;
 	}
-	freeinit->module_init = mod->module_init;
+	freeinit->module_init = mod->init_layout.base;
 
 	/*
 	 * We want to find out whether @mod uses async during init.  Clear
@@ -3274,17 +3287,16 @@ static noinline int do_init_module(struc
 	module_put(mod);
 	trim_init_extable(mod);
 #ifdef CONFIG_KALLSYMS
-	mod->num_symtab = mod->core_num_syms;
-	mod->symtab = mod->core_symtab;
-	mod->strtab = mod->core_strtab;
+	/* Switch to core kallsyms now init is done: kallsyms may be walking! */
+	rcu_assign_pointer(mod->kallsyms, &mod->core_kallsyms);
 #endif
 	mod_tree_remove_init(mod);
-	unset_module_init_ro_nx(mod);
+	disable_ro_nx(&mod->init_layout);
 	module_arch_freeing_init(mod);
-	mod->module_init = NULL;
-	mod->init_size = 0;
-	mod->init_ro_size = 0;
-	mod->init_text_size = 0;
+	mod->init_layout.base = NULL;
+	mod->init_layout.size = 0;
+	mod->init_layout.ro_size = 0;
+	mod->init_layout.text_size = 0;
 	/*
 	 * We want to free module_init, but be aware that kallsyms may be
 	 * walking this with preempt disabled.  In all the failure paths, we
@@ -3373,17 +3385,9 @@ static int complete_formation(struct mod
 	/* This relies on module_mutex for list integrity. */
 	module_bug_finalize(info->hdr, info->sechdrs, mod);
 
-	/* Set RO and NX regions for core */
-	set_section_ro_nx(mod->module_core,
-				mod->core_text_size,
-				mod->core_ro_size,
-				mod->core_size);
-
-	/* Set RO and NX regions for init */
-	set_section_ro_nx(mod->module_init,
-				mod->init_text_size,
-				mod->init_ro_size,
-				mod->init_size);
+	/* Set RO and NX regions */
+	module_enable_ro(mod);
+	module_enable_nx(mod);
 
 	/* Mark state as coming so strong_try_module_get() ignores us,
 	 * but kallsyms etc. can see us. */
@@ -3426,7 +3430,7 @@ static int load_module(struct load_info
 	long err;
 	char *after_dashes;
 
-	err = module_sig_check(info);
+	err = module_sig_check(info, flags);
 	if (err)
 		goto free_copy;
 
@@ -3515,7 +3519,7 @@ static int load_module(struct load_info
 
 	/* Module is ready to execute: parsing args may do that. */
 	after_dashes = parse_args(mod->name, mod->args, mod->kp, mod->num_kp,
-				  -32768, 32767, NULL,
+				  -32768, 32767, mod,
 				  unknown_module_param_cb);
 	if (IS_ERR(after_dashes)) {
 		err = PTR_ERR(after_dashes);
@@ -3548,8 +3552,8 @@ static int load_module(struct load_info
 				     MODULE_STATE_GOING, mod);
 
 	/* we can't deallocate the module until we clear memory protection */
-	unset_module_init_ro_nx(mod);
-	unset_module_core_ro_nx(mod);
+	module_disable_ro(mod);
+	module_disable_nx(mod);
 
  ddebug_cleanup:
 	dynamic_debug_remove(info->debug);
@@ -3578,7 +3582,7 @@ static int load_module(struct load_info
 	 */
 	ftrace_release_mod(mod);
 	/* Free lock-classes; relies on the preceding sync_rcu() */
-	lockdep_free_key_range(mod->module_core, mod->core_size);
+	lockdep_free_key_range(mod->core_layout.base, mod->core_layout.size);
 
 	module_deallocate(mod, info);
  free_copy:
@@ -3646,6 +3650,11 @@ static inline int is_arm_mapping_symbol(
 	       && (str[2] == '\0' || str[2] == '.');
 }
 
+static const char *symname(struct mod_kallsyms *kallsyms, unsigned int symnum)
+{
+	return kallsyms->strtab + kallsyms->symtab[symnum].st_name;
+}
+
 static const char *get_ksymbol(struct module *mod,
 			       unsigned long addr,
 			       unsigned long *size,
@@ -3653,41 +3662,42 @@ static const char *get_ksymbol(struct mo
 {
 	unsigned int i, best = 0;
 	unsigned long nextval;
+	struct mod_kallsyms *kallsyms = rcu_dereference_sched(mod->kallsyms);
 
 	/* At worse, next value is at end of module */
 	if (within_module_init(addr, mod))
-		nextval = (unsigned long)mod->module_init+mod->init_text_size;
+		nextval = (unsigned long)mod->init_layout.base+mod->init_layout.text_size;
 	else
-		nextval = (unsigned long)mod->module_core+mod->core_text_size;
+		nextval = (unsigned long)mod->core_layout.base+mod->core_layout.text_size;
 
 	/* Scan for closest preceding symbol, and next symbol. (ELF
 	   starts real symbols at 1). */
-	for (i = 1; i < mod->num_symtab; i++) {
-		if (mod->symtab[i].st_shndx == SHN_UNDEF)
+	for (i = 1; i < kallsyms->num_symtab; i++) {
+		if (kallsyms->symtab[i].st_shndx == SHN_UNDEF)
 			continue;
 
 		/* We ignore unnamed symbols: they're uninformative
 		 * and inserted at a whim. */
-		if (mod->symtab[i].st_value <= addr
-		    && mod->symtab[i].st_value > mod->symtab[best].st_value
-		    && *(mod->strtab + mod->symtab[i].st_name) != '\0'
-		    && !is_arm_mapping_symbol(mod->strtab + mod->symtab[i].st_name))
+		if (*symname(kallsyms, i) == '\0'
+		    || is_arm_mapping_symbol(symname(kallsyms, i)))
+			continue;
+
+		if (kallsyms->symtab[i].st_value <= addr
+		    && kallsyms->symtab[i].st_value > kallsyms->symtab[best].st_value)
 			best = i;
-		if (mod->symtab[i].st_value > addr
-		    && mod->symtab[i].st_value < nextval
-		    && *(mod->strtab + mod->symtab[i].st_name) != '\0'
-		    && !is_arm_mapping_symbol(mod->strtab + mod->symtab[i].st_name))
-			nextval = mod->symtab[i].st_value;
+		if (kallsyms->symtab[i].st_value > addr
+		    && kallsyms->symtab[i].st_value < nextval)
+			nextval = kallsyms->symtab[i].st_value;
 	}
 
 	if (!best)
 		return NULL;
 
 	if (size)
-		*size = nextval - mod->symtab[best].st_value;
+		*size = nextval - kallsyms->symtab[best].st_value;
 	if (offset)
-		*offset = addr - mod->symtab[best].st_value;
-	return mod->strtab + mod->symtab[best].st_name;
+		*offset = addr - kallsyms->symtab[best].st_value;
+	return symname(kallsyms, best);
 }
 
 /* For kallsyms to ask for address resolution.  NULL means not found.  Careful
@@ -3777,19 +3787,21 @@ int module_get_kallsym(unsigned int symn
 
 	preempt_disable();
 	list_for_each_entry_rcu(mod, &modules, list) {
+		struct mod_kallsyms *kallsyms;
+
 		if (mod->state == MODULE_STATE_UNFORMED)
 			continue;
-		if (symnum < mod->num_symtab) {
-			*value = mod->symtab[symnum].st_value;
-			*type = mod->symtab[symnum].st_info;
-			strlcpy(name, mod->strtab + mod->symtab[symnum].st_name,
-				KSYM_NAME_LEN);
+		kallsyms = rcu_dereference_sched(mod->kallsyms);
+		if (symnum < kallsyms->num_symtab) {
+			*value = kallsyms->symtab[symnum].st_value;
+			*type = kallsyms->symtab[symnum].st_info;
+			strlcpy(name, symname(kallsyms, symnum), KSYM_NAME_LEN);
 			strlcpy(module_name, mod->name, MODULE_NAME_LEN);
 			*exported = is_exported(name, *value, mod);
 			preempt_enable();
 			return 0;
 		}
-		symnum -= mod->num_symtab;
+		symnum -= kallsyms->num_symtab;
 	}
 	preempt_enable();
 	return -ERANGE;
@@ -3798,11 +3810,12 @@ int module_get_kallsym(unsigned int symn
 static unsigned long mod_find_symname(struct module *mod, const char *name)
 {
 	unsigned int i;
+	struct mod_kallsyms *kallsyms = rcu_dereference_sched(mod->kallsyms);
 
-	for (i = 0; i < mod->num_symtab; i++)
-		if (strcmp(name, mod->strtab+mod->symtab[i].st_name) == 0 &&
-		    mod->symtab[i].st_info != 'U')
-			return mod->symtab[i].st_value;
+	for (i = 0; i < kallsyms->num_symtab; i++)
+		if (strcmp(name, symname(kallsyms, i)) == 0 &&
+		    kallsyms->symtab[i].st_info != 'U')
+			return kallsyms->symtab[i].st_value;
 	return 0;
 }
 
@@ -3841,11 +3854,14 @@ int module_kallsyms_on_each_symbol(int (
 	module_assert_mutex();
 
 	list_for_each_entry(mod, &modules, list) {
+		/* We hold module_mutex: no need for rcu_dereference_sched */
+		struct mod_kallsyms *kallsyms = mod->kallsyms;
+
 		if (mod->state == MODULE_STATE_UNFORMED)
 			continue;
-		for (i = 0; i < mod->num_symtab; i++) {
-			ret = fn(data, mod->strtab + mod->symtab[i].st_name,
-				 mod, mod->symtab[i].st_value);
+		for (i = 0; i < kallsyms->num_symtab; i++) {
+			ret = fn(data, symname(kallsyms, i),
+				 mod, kallsyms->symtab[i].st_value);
 			if (ret != 0)
 				return ret;
 		}
@@ -3905,7 +3921,7 @@ static int m_show(struct seq_file *m, vo
 		return 0;
 
 	seq_printf(m, "%s %u",
-		   mod->name, mod->init_size + mod->core_size);
+		   mod->name, mod->init_layout.size + mod->core_layout.size);
 	print_unload_info(m, mod);
 
 	/* Informative for users. */
@@ -3914,7 +3930,7 @@ static int m_show(struct seq_file *m, vo
 		   mod->state == MODULE_STATE_COMING ? "Loading" :
 		   "Live");
 	/* Used by oprofile and other similar tools. */
-	seq_printf(m, " 0x%pK", mod->module_core);
+	seq_printf(m, " 0x%pK", mod->core_layout.base);
 
 	/* Taints info */
 	if (mod->taints)
@@ -4057,8 +4073,8 @@ struct module *__module_text_address(uns
 	struct module *mod = __module_address(addr);
 	if (mod) {
 		/* Make sure it's within the text section. */
-		if (!within(addr, mod->module_init, mod->init_text_size)
-		    && !within(addr, mod->module_core, mod->core_text_size))
+		if (!within(addr, mod->init_layout.base, mod->init_layout.text_size)
+		    && !within(addr, mod->core_layout.base, mod->core_layout.text_size))
 			mod = NULL;
 	}
 	return mod;
@@ -4097,3 +4113,20 @@ void module_layout(struct module *mod,
 }
 EXPORT_SYMBOL(module_layout);
 #endif
+
+#ifdef CONFIG_MODULE_SIG
+void enforce_signed_modules(void)
+{
+	sig_enforce = true;
+}
+#endif
+
+bool secure_modules(void)
+{
+#ifdef CONFIG_MODULE_SIG
+	return (sig_enforce || modules_disabled);
+#else
+	return modules_disabled;
+#endif
+}
+EXPORT_SYMBOL(secure_modules);
--- zfcpdump-kernel-4.4.orig/kernel/nsproxy.c
+++ zfcpdump-kernel-4.4/kernel/nsproxy.c
@@ -25,6 +25,7 @@
 #include <linux/proc_ns.h>
 #include <linux/file.h>
 #include <linux/syscalls.h>
+#include <linux/cgroup.h>
 
 static struct kmem_cache *nsproxy_cachep;
 
@@ -39,6 +40,9 @@ struct nsproxy init_nsproxy = {
 #ifdef CONFIG_NET
 	.net_ns			= &init_net,
 #endif
+#ifdef CONFIG_CGROUPS
+	.cgroup_ns		= &init_cgroup_ns,
+#endif
 };
 
 static inline struct nsproxy *create_nsproxy(void)
@@ -92,6 +96,13 @@ static struct nsproxy *create_new_namesp
 		goto out_pid;
 	}
 
+	new_nsp->cgroup_ns = copy_cgroup_ns(flags, user_ns,
+					    tsk->nsproxy->cgroup_ns);
+	if (IS_ERR(new_nsp->cgroup_ns)) {
+		err = PTR_ERR(new_nsp->cgroup_ns);
+		goto out_cgroup;
+	}
+
 	new_nsp->net_ns = copy_net_ns(flags, user_ns, tsk->nsproxy->net_ns);
 	if (IS_ERR(new_nsp->net_ns)) {
 		err = PTR_ERR(new_nsp->net_ns);
@@ -101,6 +112,8 @@ static struct nsproxy *create_new_namesp
 	return new_nsp;
 
 out_net:
+	put_cgroup_ns(new_nsp->cgroup_ns);
+out_cgroup:
 	if (new_nsp->pid_ns_for_children)
 		put_pid_ns(new_nsp->pid_ns_for_children);
 out_pid:
@@ -128,7 +141,8 @@ int copy_namespaces(unsigned long flags,
 	struct nsproxy *new_ns;
 
 	if (likely(!(flags & (CLONE_NEWNS | CLONE_NEWUTS | CLONE_NEWIPC |
-			      CLONE_NEWPID | CLONE_NEWNET)))) {
+			      CLONE_NEWPID | CLONE_NEWNET |
+			      CLONE_NEWCGROUP)))) {
 		get_nsproxy(old_ns);
 		return 0;
 	}
@@ -165,6 +179,7 @@ void free_nsproxy(struct nsproxy *ns)
 		put_ipc_ns(ns->ipc_ns);
 	if (ns->pid_ns_for_children)
 		put_pid_ns(ns->pid_ns_for_children);
+	put_cgroup_ns(ns->cgroup_ns);
 	put_net(ns->net_ns);
 	kmem_cache_free(nsproxy_cachep, ns);
 }
@@ -180,7 +195,7 @@ int unshare_nsproxy_namespaces(unsigned
 	int err = 0;
 
 	if (!(unshare_flags & (CLONE_NEWNS | CLONE_NEWUTS | CLONE_NEWIPC |
-			       CLONE_NEWNET | CLONE_NEWPID)))
+			       CLONE_NEWNET | CLONE_NEWPID | CLONE_NEWCGROUP)))
 		return 0;
 
 	user_ns = new_cred ? new_cred->user_ns : current_user_ns();
--- zfcpdump-kernel-4.4.orig/kernel/panic.c
+++ zfcpdump-kernel-4.4/kernel/panic.c
@@ -157,8 +157,7 @@ void panic(const char *fmt, ...)
 	 * panic() is not being callled from OOPS.
 	 */
 	debug_locks_off();
-	console_trylock();
-	console_unlock();
+	console_flush_on_panic();
 
 	if (!panic_blink)
 		panic_blink = no_blink;
--- zfcpdump-kernel-4.4.orig/kernel/power/hibernate.c
+++ zfcpdump-kernel-4.4/kernel/power/hibernate.c
@@ -29,6 +29,7 @@
 #include <linux/ctype.h>
 #include <linux/genhd.h>
 #include <linux/ktime.h>
+#include <linux/module.h>
 #include <trace/events/power.h>
 
 #include "power.h"
@@ -66,7 +67,7 @@ static const struct platform_hibernation
 
 bool hibernation_available(void)
 {
-	return (nohibernate == 0);
+	return ((nohibernate == 0) && !secure_modules());
 }
 
 /**
@@ -299,12 +300,12 @@ static int create_image(int platform_mod
 	save_processor_state();
 	trace_suspend_resume(TPS("machine_suspend"), PM_EVENT_HIBERNATE, true);
 	error = swsusp_arch_suspend();
+	/* Restore control flow magically appears here */
+	restore_processor_state();
 	trace_suspend_resume(TPS("machine_suspend"), PM_EVENT_HIBERNATE, false);
 	if (error)
 		printk(KERN_ERR "PM: Error %d creating hibernation image\n",
 			error);
-	/* Restore control flow magically appears here */
-	restore_processor_state();
 	if (!in_suspend)
 		events_check_enabled = false;
 
@@ -339,6 +340,7 @@ int hibernation_snapshot(int platform_mo
 	pm_message_t msg;
 	int error;
 
+	pm_suspend_clear_flags();
 	error = platform_begin(platform_mode);
 	if (error)
 		goto Close;
--- zfcpdump-kernel-4.4.orig/kernel/power/snapshot.c
+++ zfcpdump-kernel-4.4/kernel/power/snapshot.c
@@ -765,9 +765,9 @@ static bool memory_bm_pfn_present(struct
  */
 static bool rtree_next_node(struct memory_bitmap *bm)
 {
-	bm->cur.node = list_entry(bm->cur.node->list.next,
-				  struct rtree_node, list);
-	if (&bm->cur.node->list != &bm->cur.zone->leaves) {
+	if (!list_is_last(&bm->cur.node->list, &bm->cur.zone->leaves)) {
+		bm->cur.node = list_entry(bm->cur.node->list.next,
+					  struct rtree_node, list);
 		bm->cur.node_pfn += BM_BITS_PER_BLOCK;
 		bm->cur.node_bit  = 0;
 		touch_softlockup_watchdog();
@@ -775,9 +775,9 @@ static bool rtree_next_node(struct memor
 	}
 
 	/* No more nodes, goto next zone */
-	bm->cur.zone = list_entry(bm->cur.zone->list.next,
+	if (!list_is_last(&bm->cur.zone->list, &bm->zones)) {
+		bm->cur.zone = list_entry(bm->cur.zone->list.next,
 				  struct mem_zone_bm_rtree, list);
-	if (&bm->cur.zone->list != &bm->zones) {
 		bm->cur.node = list_entry(bm->cur.zone->leaves.next,
 					  struct rtree_node, list);
 		bm->cur.node_pfn = 0;
--- zfcpdump-kernel-4.4.orig/kernel/printk/braille.c
+++ zfcpdump-kernel-4.4/kernel/printk/braille.c
@@ -9,10 +9,10 @@
 
 char *_braille_console_setup(char **str, char **brl_options)
 {
-	if (!memcmp(*str, "brl,", 4)) {
+	if (!strncmp(*str, "brl,", 4)) {
 		*brl_options = "";
 		*str += 4;
-	} else if (!memcmp(str, "brl=", 4)) {
+	} else if (!strncmp(*str, "brl=", 4)) {
 		*brl_options = *str + 4;
 		*str = strchr(*brl_options, ',');
 		if (!*str)
--- zfcpdump-kernel-4.4.orig/kernel/printk/printk.c
+++ zfcpdump-kernel-4.4/kernel/printk/printk.c
@@ -1809,20 +1809,12 @@ asmlinkage int vprintk_emit(int facility
 	if (!in_sched) {
 		lockdep_off();
 		/*
-		 * Disable preemption to avoid being preempted while holding
-		 * console_sem which would prevent anyone from printing to
-		 * console
-		 */
-		preempt_disable();
-
-		/*
 		 * Try to acquire and then immediately release the console
 		 * semaphore.  The release will print out buffers and wake up
 		 * /dev/kmsg and syslog() users.
 		 */
 		if (console_trylock_for_printk())
 			console_unlock();
-		preempt_enable();
 		lockdep_on();
 	}
 
@@ -2173,7 +2165,20 @@ int console_trylock(void)
 		return 0;
 	}
 	console_locked = 1;
-	console_may_schedule = 0;
+	/*
+	 * When PREEMPT_COUNT disabled we can't reliably detect if it's
+	 * safe to schedule (e.g. calling printk while holding a spin_lock),
+	 * because preempt_disable()/preempt_enable() are just barriers there
+	 * and preempt_count() is always 0.
+	 *
+	 * RCU read sections have a separate preemption counter when
+	 * PREEMPT_RCU enabled thus we must take extra care and check
+	 * rcu_preempt_depth(), otherwise RCU read sections modify
+	 * preempt_count().
+	 */
+	console_may_schedule = !oops_in_progress &&
+			preemptible() &&
+			!rcu_preempt_depth();
 	return 1;
 }
 EXPORT_SYMBOL(console_trylock);
@@ -2233,13 +2238,24 @@ void console_unlock(void)
 	static u64 seen_seq;
 	unsigned long flags;
 	bool wake_klogd = false;
-	bool retry;
+	bool do_cond_resched, retry;
 
 	if (console_suspended) {
 		up_console_sem();
 		return;
 	}
 
+	/*
+	 * Console drivers are called under logbuf_lock, so
+	 * @console_may_schedule should be cleared before; however, we may
+	 * end up dumping a lot of lines, for example, if called from
+	 * console registration path, and should invoke cond_resched()
+	 * between lines if allowable.  Not doing so can cause a very long
+	 * scheduling stall on a slow console leading to RCU stall and
+	 * softlockup warnings which exacerbate the issue with more
+	 * messages practically incapacitating the system.
+	 */
+	do_cond_resched = console_may_schedule;
 	console_may_schedule = 0;
 
 	/* flush buffered message fragment immediately to console */
@@ -2311,6 +2327,9 @@ skip:
 		call_console_drivers(level, ext_text, ext_len, text, len);
 		start_critical_timings();
 		local_irq_restore(flags);
+
+		if (do_cond_resched)
+			cond_resched();
 	}
 	console_locked = 0;
 
@@ -2378,6 +2397,25 @@ void console_unblank(void)
 	console_unlock();
 }
 
+/**
+ * console_flush_on_panic - flush console content on panic
+ *
+ * Immediately output all pending messages no matter what.
+ */
+void console_flush_on_panic(void)
+{
+	/*
+	 * If someone else is holding the console lock, trylock will fail
+	 * and may_schedule may be set.  Ignore and proceed to unlock so
+	 * that messages are flushed out.  As this can be called from any
+	 * context and we don't want to get preempted while flushing,
+	 * ensure may_schedule is cleared.
+	 */
+	console_trylock();
+	console_may_schedule = 0;
+	console_unlock();
+}
+
 /*
  * Return the console tty driver structure and its associated index
  */
--- zfcpdump-kernel-4.4.orig/kernel/ptrace.c
+++ zfcpdump-kernel-4.4/kernel/ptrace.c
@@ -207,18 +207,46 @@ static int ptrace_check_attach(struct ta
 	return ret;
 }
 
-static int ptrace_has_cap(struct user_namespace *ns, unsigned int mode)
+static bool ptrace_has_cap(const struct cred *tcred, unsigned int mode)
 {
+	struct user_namespace *tns = tcred->user_ns;
+	struct user_namespace *curns = current_cred()->user_ns;
+
+	/* When a root-owned process enters a user namespace created by a
+	 * malicious user, the user shouldn't be able to execute code under
+	 * uid 0 by attaching to the root-owned process via ptrace.
+	 * Therefore, similar to the capable_wrt_inode_uidgid() check,
+	 * verify that all the uids and gids of the target process are
+	 * mapped into the current namespace.
+	 * No fsuid/fsgid check because __ptrace_may_access doesn't do it
+	 * either.
+	 */
+	if (!kuid_has_mapping(curns, tcred->euid) ||
+			!kuid_has_mapping(curns, tcred->suid) ||
+			!kuid_has_mapping(curns, tcred->uid)  ||
+			!kgid_has_mapping(curns, tcred->egid) ||
+			!kgid_has_mapping(curns, tcred->sgid) ||
+			!kgid_has_mapping(curns, tcred->gid))
+		return false;
+
 	if (mode & PTRACE_MODE_NOAUDIT)
-		return has_ns_capability_noaudit(current, ns, CAP_SYS_PTRACE);
+		return has_ns_capability_noaudit(current, tns, CAP_SYS_PTRACE);
 	else
-		return has_ns_capability(current, ns, CAP_SYS_PTRACE);
+		return has_ns_capability(current, tns, CAP_SYS_PTRACE);
 }
 
 /* Returns 0 on success, -errno on denial. */
 static int __ptrace_may_access(struct task_struct *task, unsigned int mode)
 {
 	const struct cred *cred = current_cred(), *tcred;
+	int dumpable = 0;
+	kuid_t caller_uid;
+	kgid_t caller_gid;
+
+	if (!(mode & PTRACE_MODE_FSCREDS) == !(mode & PTRACE_MODE_REALCREDS)) {
+		WARN(1, "denying ptrace access check without PTRACE_MODE_*CREDS\n");
+		return -EPERM;
+	}
 
 	/* May we inspect the given task?
 	 * This check is used both for attaching with ptrace
@@ -228,20 +256,35 @@ static int __ptrace_may_access(struct ta
 	 * because setting up the necessary parent/child relationship
 	 * or halting the specified task is impossible.
 	 */
-	int dumpable = 0;
+
 	/* Don't let security modules deny introspection */
 	if (same_thread_group(task, current))
 		return 0;
 	rcu_read_lock();
+	if (mode & PTRACE_MODE_FSCREDS) {
+		caller_uid = cred->fsuid;
+		caller_gid = cred->fsgid;
+	} else {
+		/*
+		 * Using the euid would make more sense here, but something
+		 * in userland might rely on the old behavior, and this
+		 * shouldn't be a security problem since
+		 * PTRACE_MODE_REALCREDS implies that the caller explicitly
+		 * used a syscall that requests access to another process
+		 * (and not a filesystem syscall to procfs).
+		 */
+		caller_uid = cred->uid;
+		caller_gid = cred->gid;
+	}
 	tcred = __task_cred(task);
-	if (uid_eq(cred->uid, tcred->euid) &&
-	    uid_eq(cred->uid, tcred->suid) &&
-	    uid_eq(cred->uid, tcred->uid)  &&
-	    gid_eq(cred->gid, tcred->egid) &&
-	    gid_eq(cred->gid, tcred->sgid) &&
-	    gid_eq(cred->gid, tcred->gid))
+	if (uid_eq(caller_uid, tcred->euid) &&
+	    uid_eq(caller_uid, tcred->suid) &&
+	    uid_eq(caller_uid, tcred->uid)  &&
+	    gid_eq(caller_gid, tcred->egid) &&
+	    gid_eq(caller_gid, tcred->sgid) &&
+	    gid_eq(caller_gid, tcred->gid))
 		goto ok;
-	if (ptrace_has_cap(tcred->user_ns, mode))
+	if (ptrace_has_cap(tcred, mode))
 		goto ok;
 	rcu_read_unlock();
 	return -EPERM;
@@ -252,7 +295,7 @@ ok:
 		dumpable = get_dumpable(task->mm);
 	rcu_read_lock();
 	if (dumpable != SUID_DUMP_USER &&
-	    !ptrace_has_cap(__task_cred(task)->user_ns, mode)) {
+	    !ptrace_has_cap(__task_cred(task), mode)) {
 		rcu_read_unlock();
 		return -EPERM;
 	}
@@ -306,7 +349,7 @@ static int ptrace_attach(struct task_str
 		goto out;
 
 	task_lock(task);
-	retval = __ptrace_may_access(task, PTRACE_MODE_ATTACH);
+	retval = __ptrace_may_access(task, PTRACE_MODE_ATTACH_REALCREDS);
 	task_unlock(task);
 	if (retval)
 		goto unlock_creds;
--- zfcpdump-kernel-4.4.orig/kernel/resource.c
+++ zfcpdump-kernel-4.4/kernel/resource.c
@@ -1083,9 +1083,10 @@ struct resource * __request_region(struc
 		if (!conflict)
 			break;
 		if (conflict != parent) {
-			parent = conflict;
-			if (!(conflict->flags & IORESOURCE_BUSY))
+			if (!(conflict->flags & IORESOURCE_BUSY)) {
+				parent = conflict;
 				continue;
+			}
 		}
 		if (conflict->flags & flags & IORESOURCE_MUXED) {
 			add_wait_queue(&muxed_resource_wait, &wait);
--- zfcpdump-kernel-4.4.orig/kernel/sched/core.c
+++ zfcpdump-kernel-4.4/kernel/sched/core.c
@@ -627,7 +627,10 @@ int get_nohz_timer_target(void)
 	rcu_read_lock();
 	for_each_domain(cpu, sd) {
 		for_each_cpu(i, sched_domain_span(sd)) {
-			if (!idle_cpu(i) && is_housekeeping_cpu(cpu)) {
+			if (cpu == i)
+				continue;
+
+			if (!idle_cpu(i) && is_housekeeping_cpu(i)) {
 				cpu = i;
 				goto unlock;
 			}
@@ -1942,6 +1945,28 @@ try_to_wake_up(struct task_struct *p, un
 	success = 1; /* we're going to change ->state */
 	cpu = task_cpu(p);
 
+	/*
+	 * Ensure we load p->on_rq _after_ p->state, otherwise it would
+	 * be possible to, falsely, observe p->on_rq == 0 and get stuck
+	 * in smp_cond_load_acquire() below.
+	 *
+	 * sched_ttwu_pending()                 try_to_wake_up()
+	 *   [S] p->on_rq = 1;                  [L] P->state
+	 *       UNLOCK rq->lock  -----.
+	 *                              \
+	 *				 +---   RMB
+	 * schedule()                   /
+	 *       LOCK rq->lock    -----'
+	 *       UNLOCK rq->lock
+	 *
+	 * [task p]
+	 *   [S] p->state = UNINTERRUPTIBLE     [L] p->on_rq
+	 *
+	 * Pairs with the UNLOCK+LOCK on rq->lock from the
+	 * last wakeup of our task and the schedule that got our task
+	 * current.
+	 */
+	smp_rmb();
 	if (p->on_rq && ttwu_remote(p, wake_flags))
 		goto stat;
 
@@ -3008,7 +3033,8 @@ static noinline void __schedule_bug(stru
 static inline void schedule_debug(struct task_struct *prev)
 {
 #ifdef CONFIG_SCHED_STACK_END_CHECK
-	BUG_ON(task_stack_end_corrupted(prev));
+	if (task_stack_end_corrupted(prev))
+		panic("corrupted stack end detected inside scheduler\n");
 #endif
 
 	if (unlikely(in_atomic_preempt_off())) {
@@ -4950,14 +4976,16 @@ void show_state_filter(unsigned long sta
 		/*
 		 * reset the NMI-timeout, listing all files on a slow
 		 * console might take a lot of time:
+		 * Also, reset softlockup watchdogs on all CPUs, because
+		 * another CPU might be blocked waiting for us to process
+		 * an IPI.
 		 */
 		touch_nmi_watchdog();
+		touch_all_softlockup_watchdogs();
 		if (!state_filter || (p->state & state_filter))
 			sched_show_task(p);
 	}
 
-	touch_all_softlockup_watchdogs();
-
 #ifdef CONFIG_SCHED_DEBUG
 	sysrq_sched_debug_show();
 #endif
@@ -5525,6 +5553,7 @@ migration_call(struct notifier_block *nf
 
 	case CPU_UP_PREPARE:
 		rq->calc_load_update = calc_load_update;
+		account_reset_rq(rq);
 		break;
 
 	case CPU_ONLINE:
@@ -6738,7 +6767,7 @@ static void sched_init_numa(void)
 
 			sched_domains_numa_masks[i][j] = mask;
 
-			for (k = 0; k < nr_node_ids; k++) {
+			for_each_node(k) {
 				if (node_distance(j, k) > sched_domains_numa_distance[i])
 					continue;
 
@@ -7692,7 +7721,7 @@ void set_curr_task(int cpu, struct task_
 /* task_group_lock serializes the addition/removal of task groups */
 static DEFINE_SPINLOCK(task_group_lock);
 
-static void free_sched_group(struct task_group *tg)
+static void sched_free_group(struct task_group *tg)
 {
 	free_fair_sched_group(tg);
 	free_rt_sched_group(tg);
@@ -7718,7 +7747,7 @@ struct task_group *sched_create_group(st
 	return tg;
 
 err:
-	free_sched_group(tg);
+	sched_free_group(tg);
 	return ERR_PTR(-ENOMEM);
 }
 
@@ -7738,17 +7767,16 @@ void sched_online_group(struct task_grou
 }
 
 /* rcu callback to free various structures associated with a task group */
-static void free_sched_group_rcu(struct rcu_head *rhp)
+static void sched_free_group_rcu(struct rcu_head *rhp)
 {
 	/* now it should be safe to free those cfs_rqs */
-	free_sched_group(container_of(rhp, struct task_group, rcu));
+	sched_free_group(container_of(rhp, struct task_group, rcu));
 }
 
-/* Destroy runqueue etc associated with a task group */
 void sched_destroy_group(struct task_group *tg)
 {
 	/* wait for possible concurrent references to cfs_rqs complete */
-	call_rcu(&tg->rcu, free_sched_group_rcu);
+	call_rcu(&tg->rcu, sched_free_group_rcu);
 }
 
 void sched_offline_group(struct task_group *tg)
@@ -8209,31 +8237,26 @@ cpu_cgroup_css_alloc(struct cgroup_subsy
 	if (IS_ERR(tg))
 		return ERR_PTR(-ENOMEM);
 
+	sched_online_group(tg, parent);
+
 	return &tg->css;
 }
 
-static int cpu_cgroup_css_online(struct cgroup_subsys_state *css)
+static void cpu_cgroup_css_released(struct cgroup_subsys_state *css)
 {
 	struct task_group *tg = css_tg(css);
-	struct task_group *parent = css_tg(css->parent);
 
-	if (parent)
-		sched_online_group(tg, parent);
-	return 0;
+	sched_offline_group(tg);
 }
 
 static void cpu_cgroup_css_free(struct cgroup_subsys_state *css)
 {
 	struct task_group *tg = css_tg(css);
 
-	sched_destroy_group(tg);
-}
-
-static void cpu_cgroup_css_offline(struct cgroup_subsys_state *css)
-{
-	struct task_group *tg = css_tg(css);
-
-	sched_offline_group(tg);
+	/*
+	 * Relies on the RCU grace period between css_released() and this.
+	 */
+	sched_free_group(tg);
 }
 
 static void cpu_cgroup_fork(struct task_struct *task, void *private)
@@ -8593,9 +8616,8 @@ static struct cftype cpu_files[] = {
 
 struct cgroup_subsys cpu_cgrp_subsys = {
 	.css_alloc	= cpu_cgroup_css_alloc,
+	.css_released	= cpu_cgroup_css_released,
 	.css_free	= cpu_cgroup_css_free,
-	.css_online	= cpu_cgroup_css_online,
-	.css_offline	= cpu_cgroup_css_offline,
 	.fork		= cpu_cgroup_fork,
 	.can_attach	= cpu_cgroup_can_attach,
 	.attach		= cpu_cgroup_attach,
--- zfcpdump-kernel-4.4.orig/kernel/sched/cputime.c
+++ zfcpdump-kernel-4.4/kernel/sched/cputime.c
@@ -259,21 +259,21 @@ static __always_inline bool steal_accoun
 #ifdef CONFIG_PARAVIRT
 	if (static_key_false(&paravirt_steal_enabled)) {
 		u64 steal;
-		cputime_t steal_ct;
+		unsigned long steal_jiffies;
 
 		steal = paravirt_steal_clock(smp_processor_id());
 		steal -= this_rq()->prev_steal_time;
 
 		/*
-		 * cputime_t may be less precise than nsecs (eg: if it's
-		 * based on jiffies). Lets cast the result to cputime
+		 * steal is in nsecs but our caller is expecting steal
+		 * time in jiffies. Lets cast the result to jiffies
 		 * granularity and account the rest on the next rounds.
 		 */
-		steal_ct = nsecs_to_cputime(steal);
-		this_rq()->prev_steal_time += cputime_to_nsecs(steal_ct);
+		steal_jiffies = nsecs_to_jiffies(steal);
+		this_rq()->prev_steal_time += jiffies_to_nsecs(steal_jiffies);
 
-		account_steal_time(steal_ct);
-		return steal_ct;
+		account_steal_time(jiffies_to_cputime(steal_jiffies));
+		return steal_jiffies;
 	}
 #endif
 	return false;
@@ -600,19 +600,25 @@ static void cputime_adjust(struct task_c
 	stime = curr->stime;
 	utime = curr->utime;
 
-	if (utime == 0) {
-		stime = rtime;
+	/*
+	 * If either stime or both stime and utime are 0, assume all runtime is
+	 * userspace. Once a task gets some ticks, the monotonicy code at
+	 * 'update' will ensure things converge to the observed ratio.
+	 */
+	if (stime == 0) {
+		utime = rtime;
 		goto update;
 	}
 
-	if (stime == 0) {
-		utime = rtime;
+	if (utime == 0) {
+		stime = rtime;
 		goto update;
 	}
 
 	stime = scale_stime((__force u64)stime, (__force u64)rtime,
 			    (__force u64)(stime + utime));
 
+update:
 	/*
 	 * Make sure stime doesn't go backwards; this preserves monotonicity
 	 * for utime because rtime is monotonic.
@@ -635,7 +641,6 @@ static void cputime_adjust(struct task_c
 		stime = rtime - utime;
 	}
 
-update:
 	prev->stime = stime;
 	prev->utime = utime;
 out:
--- zfcpdump-kernel-4.4.orig/kernel/sched/fair.c
+++ zfcpdump-kernel-4.4/kernel/sched/fair.c
@@ -687,8 +687,6 @@ void init_entity_runnable_average(struct
 	/* when this task enqueue'ed, it will contribute to its cfs_rq's load_avg */
 }
 
-static inline unsigned long cfs_rq_runnable_load_avg(struct cfs_rq *cfs_rq);
-static inline unsigned long cfs_rq_load_avg(struct cfs_rq *cfs_rq);
 #else
 void init_entity_runnable_average(struct sched_entity *se)
 {
@@ -1193,8 +1191,6 @@ static void task_numa_assign(struct task
 {
 	if (env->best_task)
 		put_task_struct(env->best_task);
-	if (p)
-		get_task_struct(p);
 
 	env->best_task = p;
 	env->best_imp = imp;
@@ -1262,20 +1258,30 @@ static void task_numa_compare(struct tas
 	long imp = env->p->numa_group ? groupimp : taskimp;
 	long moveimp = imp;
 	int dist = env->dist;
+	bool assigned = false;
 
 	rcu_read_lock();
 
 	raw_spin_lock_irq(&dst_rq->lock);
 	cur = dst_rq->curr;
 	/*
-	 * No need to move the exiting task, and this ensures that ->curr
-	 * wasn't reaped and thus get_task_struct() in task_numa_assign()
-	 * is safe under RCU read lock.
-	 * Note that rcu_read_lock() itself can't protect from the final
-	 * put_task_struct() after the last schedule().
+	 * No need to move the exiting task or idle task.
 	 */
 	if ((cur->flags & PF_EXITING) || is_idle_task(cur))
 		cur = NULL;
+	else {
+		/*
+		 * The task_struct must be protected here to protect the
+		 * p->numa_faults access in the task_weight since the
+		 * numa_faults could already be freed in the following path:
+		 * finish_task_switch()
+		 *     --> put_task_struct()
+		 *         --> __put_task_struct()
+		 *             --> task_numa_free()
+		 */
+		get_task_struct(cur);
+	}
+
 	raw_spin_unlock_irq(&dst_rq->lock);
 
 	/*
@@ -1359,6 +1365,7 @@ balance:
 		 */
 		if (!load_too_imbalanced(src_load, dst_load, env)) {
 			imp = moveimp - 1;
+			put_task_struct(cur);
 			cur = NULL;
 			goto assign;
 		}
@@ -1384,9 +1391,16 @@ balance:
 		env->dst_cpu = select_idle_sibling(env->p, env->dst_cpu);
 
 assign:
+	assigned = true;
 	task_numa_assign(env, cur, imp);
 unlock:
 	rcu_read_unlock();
+	/*
+	 * The dst_rq->curr isn't assigned. The protection for task_struct is
+	 * finished.
+	 */
+	if (cur && !assigned)
+		put_task_struct(cur);
 }
 
 static void task_numa_find_cpu(struct task_numa_env *env,
@@ -2682,6 +2696,23 @@ static inline void update_tg_load_avg(st
 
 static inline u64 cfs_rq_clock_task(struct cfs_rq *cfs_rq);
 
+/*
+ * Unsigned subtract and clamp on underflow.
+ *
+ * Explicitly do a load-store to ensure the intermediate value never hits
+ * memory. This allows lockless observations without ever seeing the negative
+ * values.
+ */
+#define sub_positive(_ptr, _val) do {				\
+	typeof(_ptr) ptr = (_ptr);				\
+	typeof(*ptr) val = (_val);				\
+	typeof(*ptr) res, var = READ_ONCE(*ptr);		\
+	res = var - val;					\
+	if (res > var)						\
+		res = 0;					\
+	WRITE_ONCE(*ptr, res);					\
+} while (0)
+
 /* Group cfs_rq's load_avg is used for task_h_load and update_cfs_share */
 static inline int update_cfs_rq_load_avg(u64 now, struct cfs_rq *cfs_rq)
 {
@@ -2690,15 +2721,15 @@ static inline int update_cfs_rq_load_avg
 
 	if (atomic_long_read(&cfs_rq->removed_load_avg)) {
 		s64 r = atomic_long_xchg(&cfs_rq->removed_load_avg, 0);
-		sa->load_avg = max_t(long, sa->load_avg - r, 0);
-		sa->load_sum = max_t(s64, sa->load_sum - r * LOAD_AVG_MAX, 0);
+		sub_positive(&sa->load_avg, r);
+		sub_positive(&sa->load_sum, r * LOAD_AVG_MAX);
 		removed = 1;
 	}
 
 	if (atomic_long_read(&cfs_rq->removed_util_avg)) {
 		long r = atomic_long_xchg(&cfs_rq->removed_util_avg, 0);
-		sa->util_avg = max_t(long, sa->util_avg - r, 0);
-		sa->util_sum = max_t(s32, sa->util_sum - r * LOAD_AVG_MAX, 0);
+		sub_positive(&sa->util_avg, r);
+		sub_positive(&sa->util_sum, r * LOAD_AVG_MAX);
 	}
 
 	decayed = __update_load_avg(now, cpu_of(rq_of(cfs_rq)), sa,
@@ -2764,10 +2795,10 @@ static void detach_entity_load_avg(struc
 			  &se->avg, se->on_rq * scale_load_down(se->load.weight),
 			  cfs_rq->curr == se, NULL);
 
-	cfs_rq->avg.load_avg = max_t(long, cfs_rq->avg.load_avg - se->avg.load_avg, 0);
-	cfs_rq->avg.load_sum = max_t(s64,  cfs_rq->avg.load_sum - se->avg.load_sum, 0);
-	cfs_rq->avg.util_avg = max_t(long, cfs_rq->avg.util_avg - se->avg.util_avg, 0);
-	cfs_rq->avg.util_sum = max_t(s32,  cfs_rq->avg.util_sum - se->avg.util_sum, 0);
+	sub_positive(&cfs_rq->avg.load_avg, se->avg.load_avg);
+	sub_positive(&cfs_rq->avg.load_sum, se->avg.load_sum);
+	sub_positive(&cfs_rq->avg.util_avg, se->avg.util_avg);
+	sub_positive(&cfs_rq->avg.util_sum, se->avg.util_sum);
 }
 
 /* Add the load generated by se into cfs_rq's load average */
@@ -4577,19 +4608,24 @@ static long effective_load(struct task_g
 		return wl;
 
 	for_each_sched_entity(se) {
-		long w, W;
+		struct cfs_rq *cfs_rq = se->my_q;
+		long W, w = cfs_rq_load_avg(cfs_rq);
 
-		tg = se->my_q->tg;
+		tg = cfs_rq->tg;
 
 		/*
 		 * W = @wg + \Sum rw_j
 		 */
-		W = wg + calc_tg_weight(tg, se->my_q);
+		W = wg + atomic_long_read(&tg->load_avg);
+
+		/* Ensure \Sum rw_j >= rw_i */
+		W -= cfs_rq->tg_load_avg_contrib;
+		W += w;
 
 		/*
 		 * w = rw_i + @wl
 		 */
-		w = cfs_rq_load_avg(se->my_q) + wl;
+		w += wl;
 
 		/*
 		 * wl = S * s'_i; see (2)
--- zfcpdump-kernel-4.4.orig/kernel/sched/loadavg.c
+++ zfcpdump-kernel-4.4/kernel/sched/loadavg.c
@@ -99,10 +99,13 @@ long calc_load_fold_active(struct rq *th
 static unsigned long
 calc_load(unsigned long load, unsigned long exp, unsigned long active)
 {
-	load *= exp;
-	load += active * (FIXED_1 - exp);
-	load += 1UL << (FSHIFT - 1);
-	return load >> FSHIFT;
+	unsigned long newload;
+
+	newload = load * exp + active * (FIXED_1 - exp);
+	if (active >= load)
+		newload += FIXED_1-1;
+
+	return newload / FIXED_1;
 }
 
 #ifdef CONFIG_NO_HZ_COMMON
--- zfcpdump-kernel-4.4.orig/kernel/sched/sched.h
+++ zfcpdump-kernel-4.4/kernel/sched/sched.h
@@ -1770,3 +1770,16 @@ static inline u64 irq_time_read(int cpu)
 }
 #endif /* CONFIG_64BIT */
 #endif /* CONFIG_IRQ_TIME_ACCOUNTING */
+
+static inline void account_reset_rq(struct rq *rq)
+{
+#ifdef CONFIG_IRQ_TIME_ACCOUNTING
+	rq->prev_irq_time = 0;
+#endif
+#ifdef CONFIG_PARAVIRT
+	rq->prev_steal_time = 0;
+#endif
+#ifdef CONFIG_PARAVIRT_TIME_ACCOUNTING
+	rq->prev_steal_time_rq = 0;
+#endif
+}
--- zfcpdump-kernel-4.4.orig/kernel/seccomp.c
+++ zfcpdump-kernel-4.4/kernel/seccomp.c
@@ -316,24 +316,24 @@ static inline void seccomp_sync_threads(
 		put_seccomp_filter(thread);
 		smp_store_release(&thread->seccomp.filter,
 				  caller->seccomp.filter);
+
+		/*
+		 * Don't let an unprivileged task work around
+		 * the no_new_privs restriction by creating
+		 * a thread that sets it up, enters seccomp,
+		 * then dies.
+		 */
+		if (task_no_new_privs(caller))
+			task_set_no_new_privs(thread);
+
 		/*
 		 * Opt the other thread into seccomp if needed.
 		 * As threads are considered to be trust-realm
 		 * equivalent (see ptrace_may_access), it is safe to
 		 * allow one thread to transition the other.
 		 */
-		if (thread->seccomp.mode == SECCOMP_MODE_DISABLED) {
-			/*
-			 * Don't let an unprivileged task work around
-			 * the no_new_privs restriction by creating
-			 * a thread that sets it up, enters seccomp,
-			 * then dies.
-			 */
-			if (task_no_new_privs(caller))
-				task_set_no_new_privs(thread);
-
+		if (thread->seccomp.mode == SECCOMP_MODE_DISABLED)
 			seccomp_assign_mode(thread, SECCOMP_MODE_FILTER);
-		}
 	}
 }
 
--- zfcpdump-kernel-4.4.orig/kernel/sys.c
+++ zfcpdump-kernel-4.4/kernel/sys.c
@@ -1099,6 +1099,21 @@ out:
 DECLARE_RWSEM(uts_sem);
 
 #ifdef COMPAT_UTS_MACHINE
+static char compat_uts_machine[__OLD_UTS_LEN+1] = COMPAT_UTS_MACHINE;
+
+static int __init parse_compat_uts_machine(char *arg)
+{
+	strncpy(compat_uts_machine, arg, __OLD_UTS_LEN);
+	compat_uts_machine[__OLD_UTS_LEN] = 0;
+	return 0;
+}
+early_param("compat_uts_machine", parse_compat_uts_machine);
+
+#undef COMPAT_UTS_MACHINE
+#define COMPAT_UTS_MACHINE compat_uts_machine
+#endif
+
+#ifdef COMPAT_UTS_MACHINE
 #define override_architecture(name) \
 	(personality(current->personality) == PER_LINUX32 && \
 	 copy_to_user(name->machine, COMPAT_UTS_MACHINE, \
@@ -1853,11 +1868,13 @@ static int prctl_set_mm_map(int opt, con
 		user_auxv[AT_VECTOR_SIZE - 1] = AT_NULL;
 	}
 
-	if (prctl_map.exe_fd != (u32)-1)
+	if (prctl_map.exe_fd != (u32)-1) {
 		error = prctl_set_mm_exe_file(mm, prctl_map.exe_fd);
-	down_read(&mm->mmap_sem);
-	if (error)
-		goto out;
+		if (error)
+			return error;
+	}
+
+	down_write(&mm->mmap_sem);
 
 	/*
 	 * We don't validate if these members are pointing to
@@ -1894,10 +1911,8 @@ static int prctl_set_mm_map(int opt, con
 	if (prctl_map.auxv_size)
 		memcpy(mm->saved_auxv, user_auxv, sizeof(user_auxv));
 
-	error = 0;
-out:
-	up_read(&mm->mmap_sem);
-	return error;
+	up_write(&mm->mmap_sem);
+	return 0;
 }
 #endif /* CONFIG_CHECKPOINT_RESTORE */
 
@@ -1963,7 +1978,7 @@ static int prctl_set_mm(int opt, unsigne
 
 	error = -EINVAL;
 
-	down_read(&mm->mmap_sem);
+	down_write(&mm->mmap_sem);
 	vma = find_vma(mm, addr);
 
 	prctl_map.start_code	= mm->start_code;
@@ -2056,7 +2071,7 @@ static int prctl_set_mm(int opt, unsigne
 
 	error = 0;
 out:
-	up_read(&mm->mmap_sem);
+	up_write(&mm->mmap_sem);
 	return error;
 }
 
--- zfcpdump-kernel-4.4.orig/kernel/sysctl.c
+++ zfcpdump-kernel-4.4/kernel/sysctl.c
@@ -65,6 +65,7 @@
 #include <linux/sched/sysctl.h>
 #include <linux/kexec.h>
 #include <linux/bpf.h>
+#include <linux/efi.h>
 
 #include <asm/uaccess.h>
 #include <asm/processor.h>
@@ -103,6 +104,9 @@ extern int core_uses_pid;
 extern char core_pattern[];
 extern unsigned int core_pipe_limit;
 #endif
+#ifdef CONFIG_USER_NS
+extern int unprivileged_userns_clone;
+#endif
 extern int pid_max;
 extern int pid_max_min, pid_max_max;
 extern int percpu_pagelist_fraction;
@@ -276,8 +280,38 @@ static int min_extfrag_threshold;
 static int max_extfrag_threshold = 1000;
 #endif
 
+static unsigned int secure_boot_enabled;
+int secure_boot_proc_handler(struct ctl_table *table, int write,
+	void __user *buffer, size_t *lenp, loff_t *ppos)
+{
+	secure_boot_enabled = efi_enabled(EFI_SECURE_BOOT);
+	return proc_dointvec(table, write, buffer, lenp, ppos);
+}
+
+static unsigned int moksbstate_disabled;
+int moksbstate_disabled_proc_handler(struct ctl_table *table, int write,
+	void __user *buffer, size_t *lenp, loff_t *ppos)
+{
+	moksbstate_disabled = efi_enabled(EFI_MOKSBSTATE_DISABLED);
+	return proc_dointvec(table, write, buffer, lenp, ppos);
+}
+
 static struct ctl_table kern_table[] = {
 	{
+		.procname   = "secure_boot",
+		.data       = &secure_boot_enabled,
+		.maxlen     = sizeof(unsigned int),
+		.mode       = 0444,
+		.proc_handler   = secure_boot_proc_handler,
+	},
+	{
+		.procname   = "moksbstate_disabled",
+		.data       = &moksbstate_disabled,
+		.maxlen     = sizeof(unsigned int),
+		.mode       = 0444,
+		.proc_handler   = moksbstate_disabled_proc_handler,
+	},
+	{
 		.procname	= "sched_child_runs_first",
 		.data		= &sysctl_sched_child_runs_first,
 		.maxlen		= sizeof(unsigned int),
@@ -482,6 +516,15 @@ static struct ctl_table kern_table[] = {
 		.proc_handler	= proc_dointvec,
 	},
 #endif
+#ifdef CONFIG_USER_NS
+	{
+		.procname	= "unprivileged_userns_clone",
+		.data		= &unprivileged_userns_clone,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= proc_dointvec,
+	},
+#endif
 #ifdef CONFIG_PROC_SYSCTL
 	{
 		.procname	= "tainted",
@@ -1735,6 +1778,20 @@ static struct ctl_table fs_table[] = {
 		.proc_handler	= &pipe_proc_fn,
 		.extra1		= &pipe_min_size,
 	},
+	{
+		.procname	= "pipe-user-pages-hard",
+		.data		= &pipe_user_pages_hard,
+		.maxlen		= sizeof(pipe_user_pages_hard),
+		.mode		= 0644,
+		.proc_handler	= proc_doulongvec_minmax,
+	},
+	{
+		.procname	= "pipe-user-pages-soft",
+		.data		= &pipe_user_pages_soft,
+		.maxlen		= sizeof(pipe_user_pages_soft),
+		.mode		= 0644,
+		.proc_handler	= proc_doulongvec_minmax,
+	},
 	{ }
 };
 
@@ -2037,6 +2094,21 @@ static int do_proc_dointvec_conv(bool *n
 	return 0;
 }
 
+static int do_proc_douintvec_conv(bool *negp, unsigned long *lvalp,
+				 int *valp,
+				 int write, void *data)
+{
+	if (write) {
+		if (*negp)
+			return -EINVAL;
+		*valp = *lvalp;
+	} else {
+		unsigned int val = *valp;
+		*lvalp = (unsigned long)val;
+	}
+	return 0;
+}
+
 static const char proc_wspace_sep[] = { ' ', '\t', '\n' };
 
 static int __do_proc_dointvec(void *tbl_data, struct ctl_table *table,
@@ -2164,8 +2236,27 @@ static int do_proc_dointvec(struct ctl_t
 int proc_dointvec(struct ctl_table *table, int write,
 		     void __user *buffer, size_t *lenp, loff_t *ppos)
 {
-    return do_proc_dointvec(table,write,buffer,lenp,ppos,
-		    	    NULL,NULL);
+	return do_proc_dointvec(table, write, buffer, lenp, ppos, NULL, NULL);
+}
+
+/**
+ * proc_douintvec - read a vector of unsigned integers
+ * @table: the sysctl table
+ * @write: %TRUE if this is a write to the sysctl file
+ * @buffer: the user buffer
+ * @lenp: the size of the user buffer
+ * @ppos: file position
+ *
+ * Reads/writes up to table->maxlen/sizeof(unsigned int) unsigned integer
+ * values from/to the user buffer, treated as an ASCII string.
+ *
+ * Returns 0 on success.
+ */
+int proc_douintvec(struct ctl_table *table, int write,
+		     void __user *buffer, size_t *lenp, loff_t *ppos)
+{
+	return do_proc_dointvec(table, write, buffer, lenp, ppos,
+				do_proc_douintvec_conv, NULL);
 }
 
 /*
@@ -2778,6 +2869,12 @@ int proc_dointvec(struct ctl_table *tabl
 	return -ENOSYS;
 }
 
+int proc_douintvec(struct ctl_table *table, int write,
+		  void __user *buffer, size_t *lenp, loff_t *ppos)
+{
+	return -ENOSYS;
+}
+
 int proc_dointvec_minmax(struct ctl_table *table, int write,
 		    void __user *buffer, size_t *lenp, loff_t *ppos)
 {
@@ -2823,6 +2920,7 @@ int proc_doulongvec_ms_jiffies_minmax(st
  * exception granted :-)
  */
 EXPORT_SYMBOL(proc_dointvec);
+EXPORT_SYMBOL(proc_douintvec);
 EXPORT_SYMBOL(proc_dointvec_jiffies);
 EXPORT_SYMBOL(proc_dointvec_minmax);
 EXPORT_SYMBOL(proc_dointvec_userhz_jiffies);
--- zfcpdump-kernel-4.4.orig/kernel/sysctl_binary.c
+++ zfcpdump-kernel-4.4/kernel/sysctl_binary.c
@@ -1321,7 +1321,7 @@ static ssize_t binary_sysctl(const int *
 	}
 
 	mnt = task_active_pid_ns(current)->proc_mnt;
-	file = file_open_root(mnt->mnt_root, mnt, pathname, flags);
+	file = file_open_root(mnt->mnt_root, mnt, pathname, flags, 0);
 	result = PTR_ERR(file);
 	if (IS_ERR(file))
 		goto out_putname;
--- zfcpdump-kernel-4.4.orig/kernel/time/clocksource.c
+++ zfcpdump-kernel-4.4/kernel/time/clocksource.c
@@ -323,13 +323,42 @@ static void clocksource_enqueue_watchdog
 		/* cs is a watchdog. */
 		if (cs->flags & CLOCK_SOURCE_IS_CONTINUOUS)
 			cs->flags |= CLOCK_SOURCE_VALID_FOR_HRES;
+	}
+	spin_unlock_irqrestore(&watchdog_lock, flags);
+}
+
+static void clocksource_select_watchdog(bool fallback)
+{
+	struct clocksource *cs, *old_wd;
+	unsigned long flags;
+
+	spin_lock_irqsave(&watchdog_lock, flags);
+	/* save current watchdog */
+	old_wd = watchdog;
+	if (fallback)
+		watchdog = NULL;
+
+	list_for_each_entry(cs, &clocksource_list, list) {
+		/* cs is a clocksource to be watched. */
+		if (cs->flags & CLOCK_SOURCE_MUST_VERIFY)
+			continue;
+
+		/* Skip current if we were requested for a fallback. */
+		if (fallback && cs == old_wd)
+			continue;
+
 		/* Pick the best watchdog. */
-		if (!watchdog || cs->rating > watchdog->rating) {
+		if (!watchdog || cs->rating > watchdog->rating)
 			watchdog = cs;
-			/* Reset watchdog cycles */
-			clocksource_reset_watchdog();
-		}
 	}
+	/* If we failed to find a fallback restore the old one. */
+	if (!watchdog)
+		watchdog = old_wd;
+
+	/* If we changed the watchdog we need to reset cycles. */
+	if (watchdog != old_wd)
+		clocksource_reset_watchdog();
+
 	/* Check if the watchdog timer needs to be started. */
 	clocksource_start_watchdog();
 	spin_unlock_irqrestore(&watchdog_lock, flags);
@@ -404,6 +433,7 @@ static void clocksource_enqueue_watchdog
 		cs->flags |= CLOCK_SOURCE_VALID_FOR_HRES;
 }
 
+static void clocksource_select_watchdog(bool fallback) { }
 static inline void clocksource_dequeue_watchdog(struct clocksource *cs) { }
 static inline void clocksource_resume_watchdog(void) { }
 static inline int __clocksource_watchdog_kthread(void) { return 0; }
@@ -736,6 +766,7 @@ int __clocksource_register_scale(struct
 	clocksource_enqueue(cs);
 	clocksource_enqueue_watchdog(cs);
 	clocksource_select();
+	clocksource_select_watchdog(false);
 	mutex_unlock(&clocksource_mutex);
 	return 0;
 }
@@ -758,6 +789,7 @@ void clocksource_change_rating(struct cl
 	mutex_lock(&clocksource_mutex);
 	__clocksource_change_rating(cs, rating);
 	clocksource_select();
+	clocksource_select_watchdog(false);
 	mutex_unlock(&clocksource_mutex);
 }
 EXPORT_SYMBOL(clocksource_change_rating);
@@ -767,12 +799,12 @@ EXPORT_SYMBOL(clocksource_change_rating)
  */
 static int clocksource_unbind(struct clocksource *cs)
 {
-	/*
-	 * I really can't convince myself to support this on hardware
-	 * designed by lobotomized monkeys.
-	 */
-	if (clocksource_is_watchdog(cs))
-		return -EBUSY;
+	if (clocksource_is_watchdog(cs)) {
+		/* Select and try to install a replacement watchdog. */
+		clocksource_select_watchdog(true);
+		if (clocksource_is_watchdog(cs))
+			return -EBUSY;
+	}
 
 	if (cs == curr_clocksource) {
 		/* Select and try to install a replacement clock source */
--- zfcpdump-kernel-4.4.orig/kernel/time/hrtimer.c
+++ zfcpdump-kernel-4.4/kernel/time/hrtimer.c
@@ -897,10 +897,10 @@ static int enqueue_hrtimer(struct hrtime
  */
 static void __remove_hrtimer(struct hrtimer *timer,
 			     struct hrtimer_clock_base *base,
-			     unsigned long newstate, int reprogram)
+			     u8 newstate, int reprogram)
 {
 	struct hrtimer_cpu_base *cpu_base = base->cpu_base;
-	unsigned int state = timer->state;
+	u8 state = timer->state;
 
 	timer->state = newstate;
 	if (!(state & HRTIMER_STATE_ENQUEUED))
@@ -930,7 +930,7 @@ static inline int
 remove_hrtimer(struct hrtimer *timer, struct hrtimer_clock_base *base, bool restart)
 {
 	if (hrtimer_is_queued(timer)) {
-		unsigned long state = timer->state;
+		u8 state = timer->state;
 		int reprogram;
 
 		/*
@@ -954,6 +954,22 @@ remove_hrtimer(struct hrtimer *timer, st
 	return 0;
 }
 
+static inline ktime_t hrtimer_update_lowres(struct hrtimer *timer, ktime_t tim,
+					    const enum hrtimer_mode mode)
+{
+#ifdef CONFIG_TIME_LOW_RES
+	/*
+	 * CONFIG_TIME_LOW_RES indicates that the system has no way to return
+	 * granular time values. For relative timers we add hrtimer_resolution
+	 * (i.e. one jiffie) to prevent short timeouts.
+	 */
+	timer->is_rel = mode & HRTIMER_MODE_REL;
+	if (timer->is_rel)
+		tim = ktime_add_safe(tim, ktime_set(0, hrtimer_resolution));
+#endif
+	return tim;
+}
+
 /**
  * hrtimer_start_range_ns - (re)start an hrtimer on the current CPU
  * @timer:	the timer to be added
@@ -974,19 +990,10 @@ void hrtimer_start_range_ns(struct hrtim
 	/* Remove an active timer from the queue: */
 	remove_hrtimer(timer, base, true);
 
-	if (mode & HRTIMER_MODE_REL) {
+	if (mode & HRTIMER_MODE_REL)
 		tim = ktime_add_safe(tim, base->get_time());
-		/*
-		 * CONFIG_TIME_LOW_RES is a temporary way for architectures
-		 * to signal that they simply return xtime in
-		 * do_gettimeoffset(). In this case we want to round up by
-		 * resolution when starting a relative timer, to avoid short
-		 * timeouts. This will go away with the GTOD framework.
-		 */
-#ifdef CONFIG_TIME_LOW_RES
-		tim = ktime_add_safe(tim, ktime_set(0, hrtimer_resolution));
-#endif
-	}
+
+	tim = hrtimer_update_lowres(timer, tim, mode);
 
 	hrtimer_set_expires_range_ns(timer, tim, delta_ns);
 
@@ -1074,19 +1081,23 @@ EXPORT_SYMBOL_GPL(hrtimer_cancel);
 /**
  * hrtimer_get_remaining - get remaining time for the timer
  * @timer:	the timer to read
+ * @adjust:	adjust relative timers when CONFIG_TIME_LOW_RES=y
  */
-ktime_t hrtimer_get_remaining(const struct hrtimer *timer)
+ktime_t __hrtimer_get_remaining(const struct hrtimer *timer, bool adjust)
 {
 	unsigned long flags;
 	ktime_t rem;
 
 	lock_hrtimer_base(timer, &flags);
-	rem = hrtimer_expires_remaining(timer);
+	if (IS_ENABLED(CONFIG_TIME_LOW_RES) && adjust)
+		rem = hrtimer_expires_remaining_adjusted(timer);
+	else
+		rem = hrtimer_expires_remaining(timer);
 	unlock_hrtimer_base(timer, &flags);
 
 	return rem;
 }
-EXPORT_SYMBOL_GPL(hrtimer_get_remaining);
+EXPORT_SYMBOL_GPL(__hrtimer_get_remaining);
 
 #ifdef CONFIG_NO_HZ_COMMON
 /**
@@ -1220,6 +1231,14 @@ static void __run_hrtimer(struct hrtimer
 	fn = timer->function;
 
 	/*
+	 * Clear the 'is relative' flag for the TIME_LOW_RES case. If the
+	 * timer is restarted with a period then it becomes an absolute
+	 * timer. If its not restarted it does not matter.
+	 */
+	if (IS_ENABLED(CONFIG_TIME_LOW_RES))
+		timer->is_rel = false;
+
+	/*
 	 * Because we run timers from hardirq context, there is no chance
 	 * they get migrated to another cpu, therefore its safe to unlock
 	 * the timer base.
--- zfcpdump-kernel-4.4.orig/kernel/time/itimer.c
+++ zfcpdump-kernel-4.4/kernel/time/itimer.c
@@ -26,7 +26,7 @@
  */
 static struct timeval itimer_get_remtime(struct hrtimer *timer)
 {
-	ktime_t rem = hrtimer_get_remaining(timer);
+	ktime_t rem = __hrtimer_get_remaining(timer, true);
 
 	/*
 	 * Racy but safe: if the itimer expires after the above
--- zfcpdump-kernel-4.4.orig/kernel/time/ntp.c
+++ zfcpdump-kernel-4.4/kernel/time/ntp.c
@@ -674,8 +674,24 @@ int ntp_validate_timex(struct timex *txc
 			return -EINVAL;
 	}
 
-	if ((txc->modes & ADJ_SETOFFSET) && (!capable(CAP_SYS_TIME)))
-		return -EPERM;
+	if (txc->modes & ADJ_SETOFFSET) {
+		/* In order to inject time, you gotta be super-user! */
+		if (!capable(CAP_SYS_TIME))
+			return -EPERM;
+
+		if (txc->modes & ADJ_NANO) {
+			struct timespec ts;
+
+			ts.tv_sec = txc->time.tv_sec;
+			ts.tv_nsec = txc->time.tv_usec;
+			if (!timespec_inject_offset_valid(&ts))
+				return -EINVAL;
+
+		} else {
+			if (!timeval_inject_offset_valid(&txc->time))
+				return -EINVAL;
+		}
+	}
 
 	/*
 	 * Check for potential multiplication overflows that can
--- zfcpdump-kernel-4.4.orig/kernel/time/posix-clock.c
+++ zfcpdump-kernel-4.4/kernel/time/posix-clock.c
@@ -69,10 +69,10 @@ static ssize_t posix_clock_read(struct f
 static unsigned int posix_clock_poll(struct file *fp, poll_table *wait)
 {
 	struct posix_clock *clk = get_posix_clock(fp);
-	int result = 0;
+	unsigned int result = 0;
 
 	if (!clk)
-		return -ENODEV;
+		return POLLERR;
 
 	if (clk->ops.poll)
 		result = clk->ops.poll(clk, fp, wait);
--- zfcpdump-kernel-4.4.orig/kernel/time/posix-cpu-timers.c
+++ zfcpdump-kernel-4.4/kernel/time/posix-cpu-timers.c
@@ -808,6 +808,7 @@ static void posix_cpu_timer_get(struct k
 			timer->it.cpu.expires = 0;
 			sample_to_timespec(timer->it_clock, timer->it.cpu.expires,
 					   &itp->it_value);
+			return;
 		} else {
 			cpu_timer_sample_group(timer->it_clock, p, &now);
 			unlock_task_sighand(p, &flags);
--- zfcpdump-kernel-4.4.orig/kernel/time/posix-timers.c
+++ zfcpdump-kernel-4.4/kernel/time/posix-timers.c
@@ -760,7 +760,7 @@ common_timer_get(struct k_itimer *timr,
 	    (timr->it_sigev_notify & ~SIGEV_THREAD_ID) == SIGEV_NONE))
 		timr->it_overrun += (unsigned int) hrtimer_forward(timer, now, iv);
 
-	remaining = ktime_sub(hrtimer_get_expires(timer), now);
+	remaining = __hrtimer_expires_remaining_adjusted(timer, now);
 	/* Return 0 only, when the timer is expired and not pending */
 	if (remaining.tv64 <= 0) {
 		/*
--- zfcpdump-kernel-4.4.orig/kernel/time/tick-sched.c
+++ zfcpdump-kernel-4.4/kernel/time/tick-sched.c
@@ -977,9 +977,9 @@ static void tick_nohz_switch_to_nohz(voi
 	/* Get the next period */
 	next = tick_init_jiffy_update();
 
-	hrtimer_forward_now(&ts->sched_timer, tick_period);
 	hrtimer_set_expires(&ts->sched_timer, next);
-	tick_program_event(next, 1);
+	hrtimer_forward_now(&ts->sched_timer, tick_period);
+	tick_program_event(hrtimer_get_expires(&ts->sched_timer), 1);
 	tick_nohz_activate(ts, NOHZ_MODE_LOWRES);
 }
 
--- zfcpdump-kernel-4.4.orig/kernel/time/timekeeping.c
+++ zfcpdump-kernel-4.4/kernel/time/timekeeping.c
@@ -233,6 +233,7 @@ static void tk_setup_internals(struct ti
 	u64 tmp, ntpinterval;
 	struct clocksource *old_clock;
 
+	++tk->cs_was_changed_seq;
 	old_clock = tk->tkr_mono.clock;
 	tk->tkr_mono.clock = clock;
 	tk->tkr_mono.read = clock->read;
@@ -298,13 +299,11 @@ u32 (*arch_gettimeoffset)(void) = defaul
 static inline u32 arch_gettimeoffset(void) { return 0; }
 #endif
 
-static inline s64 timekeeping_get_ns(struct tk_read_base *tkr)
+static inline s64 timekeeping_delta_to_ns(struct tk_read_base *tkr,
+					  cycle_t delta)
 {
-	cycle_t delta;
 	s64 nsec;
 
-	delta = timekeeping_get_delta(tkr);
-
 	nsec = delta * tkr->mult + tkr->xtime_nsec;
 	nsec >>= tkr->shift;
 
@@ -312,6 +311,24 @@ static inline s64 timekeeping_get_ns(str
 	return nsec + arch_gettimeoffset();
 }
 
+static inline s64 timekeeping_get_ns(struct tk_read_base *tkr)
+{
+	cycle_t delta;
+
+	delta = timekeeping_get_delta(tkr);
+	return timekeeping_delta_to_ns(tkr, delta);
+}
+
+static inline s64 timekeeping_cycles_to_ns(struct tk_read_base *tkr,
+					    cycle_t cycles)
+{
+	cycle_t delta;
+
+	/* calculate the delta since the last update_wall_time */
+	delta = clocksource_delta(cycles, tkr->cycle_last, tkr->mask);
+	return timekeeping_delta_to_ns(tkr, delta);
+}
+
 /**
  * update_fast_timekeeper - Update the fast and NMI safe monotonic timekeeper.
  * @tkr: Timekeeping readout base from which we take the update
@@ -384,7 +401,10 @@ static __always_inline u64 __ktime_get_f
 	do {
 		seq = raw_read_seqcount_latch(&tkf->seq);
 		tkr = tkf->base + (seq & 0x01);
-		now = ktime_to_ns(tkr->base) + timekeeping_get_ns(tkr);
+		now = ktime_to_ns(tkr->base);
+
+		now += clocksource_delta(tkr->read(tkr->clock),
+					 tkr->cycle_last, tkr->mask);
 	} while (read_seqcount_retry(&tkf->seq, seq));
 
 	return now;
@@ -846,43 +866,274 @@ time64_t ktime_get_real_seconds(void)
 }
 EXPORT_SYMBOL_GPL(ktime_get_real_seconds);
 
-#ifdef CONFIG_NTP_PPS
+/**
+ * __ktime_get_real_seconds - The same as ktime_get_real_seconds
+ * but without the sequence counter protect. This internal function
+ * is called just when timekeeping lock is already held.
+ */
+time64_t __ktime_get_real_seconds(void)
+{
+	struct timekeeper *tk = &tk_core.timekeeper;
+
+	return tk->xtime_sec;
+}
 
 /**
- * ktime_get_raw_and_real_ts64 - get day and raw monotonic time in timespec format
- * @ts_raw:	pointer to the timespec to be set to raw monotonic time
- * @ts_real:	pointer to the timespec to be set to the time of day
- *
- * This function reads both the time of day and raw monotonic time at the
- * same time atomically and stores the resulting timestamps in timespec
- * format.
+ * ktime_get_snapshot - snapshots the realtime/monotonic raw clocks with counter
+ * @systime_snapshot:	pointer to struct receiving the system time snapshot
  */
-void ktime_get_raw_and_real_ts64(struct timespec64 *ts_raw, struct timespec64 *ts_real)
+void ktime_get_snapshot(struct system_time_snapshot *systime_snapshot)
 {
 	struct timekeeper *tk = &tk_core.timekeeper;
 	unsigned long seq;
-	s64 nsecs_raw, nsecs_real;
+	ktime_t base_raw;
+	ktime_t base_real;
+	s64 nsec_raw;
+	s64 nsec_real;
+	cycle_t now;
 
 	WARN_ON_ONCE(timekeeping_suspended);
 
 	do {
 		seq = read_seqcount_begin(&tk_core.seq);
 
-		*ts_raw = tk->raw_time;
-		ts_real->tv_sec = tk->xtime_sec;
-		ts_real->tv_nsec = 0;
+		now = tk->tkr_mono.read(tk->tkr_mono.clock);
+		systime_snapshot->cs_was_changed_seq = tk->cs_was_changed_seq;
+		systime_snapshot->clock_was_set_seq = tk->clock_was_set_seq;
+		base_real = ktime_add(tk->tkr_mono.base,
+				      tk_core.timekeeper.offs_real);
+		base_raw = tk->tkr_raw.base;
+		nsec_real = timekeeping_cycles_to_ns(&tk->tkr_mono, now);
+		nsec_raw  = timekeeping_cycles_to_ns(&tk->tkr_raw, now);
+	} while (read_seqcount_retry(&tk_core.seq, seq));
+
+	systime_snapshot->cycles = now;
+	systime_snapshot->real = ktime_add_ns(base_real, nsec_real);
+	systime_snapshot->raw = ktime_add_ns(base_raw, nsec_raw);
+}
+EXPORT_SYMBOL_GPL(ktime_get_snapshot);
 
-		nsecs_raw  = timekeeping_get_ns(&tk->tkr_raw);
-		nsecs_real = timekeeping_get_ns(&tk->tkr_mono);
+/* Scale base by mult/div checking for overflow */
+static int scale64_check_overflow(u64 mult, u64 div, u64 *base)
+{
+	u64 tmp, rem;
 
-	} while (read_seqcount_retry(&tk_core.seq, seq));
+	tmp = div64_u64_rem(*base, div, &rem);
+
+	if (((int)sizeof(u64)*8 - fls64(mult) < fls64(tmp)) ||
+	    ((int)sizeof(u64)*8 - fls64(mult) < fls64(rem)))
+		return -EOVERFLOW;
+	tmp *= mult;
+	rem *= mult;
+
+	do_div(rem, div);
+	*base = tmp + rem;
+	return 0;
+}
+
+/**
+ * adjust_historical_crosststamp - adjust crosstimestamp previous to current interval
+ * @history:			Snapshot representing start of history
+ * @partial_history_cycles:	Cycle offset into history (fractional part)
+ * @total_history_cycles:	Total history length in cycles
+ * @discontinuity:		True indicates clock was set on history period
+ * @ts:				Cross timestamp that should be adjusted using
+ *	partial/total ratio
+ *
+ * Helper function used by get_device_system_crosststamp() to correct the
+ * crosstimestamp corresponding to the start of the current interval to the
+ * system counter value (timestamp point) provided by the driver. The
+ * total_history_* quantities are the total history starting at the provided
+ * reference point and ending at the start of the current interval. The cycle
+ * count between the driver timestamp point and the start of the current
+ * interval is partial_history_cycles.
+ */
+static int adjust_historical_crosststamp(struct system_time_snapshot *history,
+					 cycle_t partial_history_cycles,
+					 cycle_t total_history_cycles,
+					 bool discontinuity,
+					 struct system_device_crosststamp *ts)
+{
+	struct timekeeper *tk = &tk_core.timekeeper;
+	u64 corr_raw, corr_real;
+	bool interp_forward;
+	int ret;
+
+	if (total_history_cycles == 0 || partial_history_cycles == 0)
+		return 0;
+
+	/* Interpolate shortest distance from beginning or end of history */
+	interp_forward = partial_history_cycles > total_history_cycles/2 ?
+		true : false;
+	partial_history_cycles = interp_forward ?
+		total_history_cycles - partial_history_cycles :
+		partial_history_cycles;
+
+	/*
+	 * Scale the monotonic raw time delta by:
+	 *	partial_history_cycles / total_history_cycles
+	 */
+	corr_raw = (u64)ktime_to_ns(
+		ktime_sub(ts->sys_monoraw, history->raw));
+	ret = scale64_check_overflow(partial_history_cycles,
+				     total_history_cycles, &corr_raw);
+	if (ret)
+		return ret;
+
+	/*
+	 * If there is a discontinuity in the history, scale monotonic raw
+	 *	correction by:
+	 *	mult(real)/mult(raw) yielding the realtime correction
+	 * Otherwise, calculate the realtime correction similar to monotonic
+	 *	raw calculation
+	 */
+	if (discontinuity) {
+		corr_real = mul_u64_u32_div
+			(corr_raw, tk->tkr_mono.mult, tk->tkr_raw.mult);
+	} else {
+		corr_real = (u64)ktime_to_ns(
+			ktime_sub(ts->sys_realtime, history->real));
+		ret = scale64_check_overflow(partial_history_cycles,
+					     total_history_cycles, &corr_real);
+		if (ret)
+			return ret;
+	}
+
+	/* Fixup monotonic raw and real time time values */
+	if (interp_forward) {
+		ts->sys_monoraw = ktime_add_ns(history->raw, corr_raw);
+		ts->sys_realtime = ktime_add_ns(history->real, corr_real);
+	} else {
+		ts->sys_monoraw = ktime_sub_ns(ts->sys_monoraw, corr_raw);
+		ts->sys_realtime = ktime_sub_ns(ts->sys_realtime, corr_real);
+	}
+
+	return 0;
+}
 
-	timespec64_add_ns(ts_raw, nsecs_raw);
-	timespec64_add_ns(ts_real, nsecs_real);
+/*
+ * cycle_between - true if test occurs chronologically between before and after
+ */
+static bool cycle_between(cycle_t before, cycle_t test, cycle_t after)
+{
+	if (test > before && test < after)
+		return true;
+	if (test < before && before > after)
+		return true;
+	return false;
 }
-EXPORT_SYMBOL(ktime_get_raw_and_real_ts64);
 
-#endif /* CONFIG_NTP_PPS */
+/**
+ * get_device_system_crosststamp - Synchronously capture system/device timestamp
+ * @get_time_fn:	Callback to get simultaneous device time and
+ *	system counter from the device driver
+ * @ctx:		Context passed to get_time_fn()
+ * @history_begin:	Historical reference point used to interpolate system
+ *	time when counter provided by the driver is before the current interval
+ * @xtstamp:		Receives simultaneously captured system and device time
+ *
+ * Reads a timestamp from a device and correlates it to system time
+ */
+int get_device_system_crosststamp(int (*get_time_fn)
+				  (ktime_t *device_time,
+				   struct system_counterval_t *sys_counterval,
+				   void *ctx),
+				  void *ctx,
+				  struct system_time_snapshot *history_begin,
+				  struct system_device_crosststamp *xtstamp)
+{
+	struct system_counterval_t system_counterval;
+	struct timekeeper *tk = &tk_core.timekeeper;
+	cycle_t cycles, now, interval_start;
+	unsigned int clock_was_set_seq = 0;
+	ktime_t base_real, base_raw;
+	s64 nsec_real, nsec_raw;
+	u8 cs_was_changed_seq;
+	unsigned long seq;
+	bool do_interp;
+	int ret;
+
+	do {
+		seq = read_seqcount_begin(&tk_core.seq);
+		/*
+		 * Try to synchronously capture device time and a system
+		 * counter value calling back into the device driver
+		 */
+		ret = get_time_fn(&xtstamp->device, &system_counterval, ctx);
+		if (ret)
+			return ret;
+
+		/*
+		 * Verify that the clocksource associated with the captured
+		 * system counter value is the same as the currently installed
+		 * timekeeper clocksource
+		 */
+		if (tk->tkr_mono.clock != system_counterval.cs)
+			return -ENODEV;
+		cycles = system_counterval.cycles;
+
+		/*
+		 * Check whether the system counter value provided by the
+		 * device driver is on the current timekeeping interval.
+		 */
+		now = tk->tkr_mono.read(tk->tkr_mono.clock);
+		interval_start = tk->tkr_mono.cycle_last;
+		if (!cycle_between(interval_start, cycles, now)) {
+			clock_was_set_seq = tk->clock_was_set_seq;
+			cs_was_changed_seq = tk->cs_was_changed_seq;
+			cycles = interval_start;
+			do_interp = true;
+		} else {
+			do_interp = false;
+		}
+
+		base_real = ktime_add(tk->tkr_mono.base,
+				      tk_core.timekeeper.offs_real);
+		base_raw = tk->tkr_raw.base;
+
+		nsec_real = timekeeping_cycles_to_ns(&tk->tkr_mono,
+						     system_counterval.cycles);
+		nsec_raw = timekeeping_cycles_to_ns(&tk->tkr_raw,
+						    system_counterval.cycles);
+	} while (read_seqcount_retry(&tk_core.seq, seq));
+
+	xtstamp->sys_realtime = ktime_add_ns(base_real, nsec_real);
+	xtstamp->sys_monoraw = ktime_add_ns(base_raw, nsec_raw);
+
+	/*
+	 * Interpolate if necessary, adjusting back from the start of the
+	 * current interval
+	 */
+	if (do_interp) {
+		cycle_t partial_history_cycles, total_history_cycles;
+		bool discontinuity;
+
+		/*
+		 * Check that the counter value occurs after the provided
+		 * history reference and that the history doesn't cross a
+		 * clocksource change
+		 */
+		if (!history_begin ||
+		    !cycle_between(history_begin->cycles,
+				   system_counterval.cycles, cycles) ||
+		    history_begin->cs_was_changed_seq != cs_was_changed_seq)
+			return -EINVAL;
+		partial_history_cycles = cycles - system_counterval.cycles;
+		total_history_cycles = cycles - history_begin->cycles;
+		discontinuity =
+			history_begin->clock_was_set_seq != clock_was_set_seq;
+
+		ret = adjust_historical_crosststamp(history_begin,
+						    partial_history_cycles,
+						    total_history_cycles,
+						    discontinuity, xtstamp);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(get_device_system_crosststamp);
 
 /**
  * do_gettimeofday - Returns the time of day in a timeval
@@ -959,7 +1210,7 @@ int timekeeping_inject_offset(struct tim
 	struct timespec64 ts64, tmp;
 	int ret = 0;
 
-	if ((unsigned long)ts->tv_nsec >= NSEC_PER_SEC)
+	if (!timespec_inject_offset_valid(ts))
 		return -EINVAL;
 
 	ts64 = timespec_to_timespec64(*ts);
@@ -1592,9 +1843,12 @@ static __always_inline void timekeeping_
 {
 	s64 interval = tk->cycle_interval;
 	s64 xinterval = tk->xtime_interval;
+	u32 base = tk->tkr_mono.clock->mult;
+	u32 max = tk->tkr_mono.clock->maxadj;
+	u32 cur_adj = tk->tkr_mono.mult;
 	s64 tick_error;
 	bool negative;
-	u32 adj;
+	u32 adj_scale;
 
 	/* Remove any current error adj from freq calculation */
 	if (tk->ntp_err_mult)
@@ -1613,13 +1867,33 @@ static __always_inline void timekeeping_
 	/* preserve the direction of correction */
 	negative = (tick_error < 0);
 
-	/* Sort out the magnitude of the correction */
+	/* If any adjustment would pass the max, just return */
+	if (negative && (cur_adj - 1) <= (base - max))
+		return;
+	if (!negative && (cur_adj + 1) >= (base + max))
+		return;
+	/*
+	 * Sort out the magnitude of the correction, but
+	 * avoid making so large a correction that we go
+	 * over the max adjustment.
+	 */
+	adj_scale = 0;
 	tick_error = abs(tick_error);
-	for (adj = 0; tick_error > interval; adj++)
+	while (tick_error > interval) {
+		u32 adj = 1 << (adj_scale + 1);
+
+		/* Check if adjustment gets us within 1 unit from the max */
+		if (negative && (cur_adj - adj) <= (base - max))
+			break;
+		if (!negative && (cur_adj + adj) >= (base + max))
+			break;
+
+		adj_scale++;
 		tick_error >>= 1;
+	}
 
 	/* scale the corrections */
-	timekeeping_apply_adjustment(tk, offset, negative, adj);
+	timekeeping_apply_adjustment(tk, offset, negative, adj_scale);
 }
 
 /*
--- zfcpdump-kernel-4.4.orig/kernel/time/timekeeping_debug.c
+++ zfcpdump-kernel-4.4/kernel/time/timekeeping_debug.c
@@ -23,7 +23,9 @@
 
 #include "timekeeping_internal.h"
 
-static unsigned int sleep_time_bin[32] = {0};
+#define NUM_BINS 32
+
+static unsigned int sleep_time_bin[NUM_BINS] = {0};
 
 static int tk_debug_show_sleep_time(struct seq_file *s, void *data)
 {
@@ -69,6 +71,9 @@ late_initcall(tk_debug_sleep_time_init);
 
 void tk_debug_account_sleep_time(struct timespec64 *t)
 {
-	sleep_time_bin[fls(t->tv_sec)]++;
+	/* Cap bin index so we don't overflow the array */
+	int bin = min(fls(t->tv_sec), NUM_BINS-1);
+
+	sleep_time_bin[bin]++;
 }
 
--- zfcpdump-kernel-4.4.orig/kernel/time/timekeeping_internal.h
+++ zfcpdump-kernel-4.4/kernel/time/timekeeping_internal.h
@@ -17,7 +17,11 @@ static inline cycle_t clocksource_delta(
 {
 	cycle_t ret = (now - last) & mask;
 
-	return (s64) ret > 0 ? ret : 0;
+	/*
+	 * Prevent time going backwards by checking the MSB of mask in
+	 * the result. If set, return 0.
+	 */
+	return ret & ~(mask >> 1) ? 0 : ret;
 }
 #else
 static inline cycle_t clocksource_delta(cycle_t now, cycle_t last, cycle_t mask)
@@ -26,4 +30,6 @@ static inline cycle_t clocksource_delta(
 }
 #endif
 
+extern time64_t __ktime_get_real_seconds(void);
+
 #endif /* _TIMEKEEPING_INTERNAL_H */
--- zfcpdump-kernel-4.4.orig/kernel/time/timer_list.c
+++ zfcpdump-kernel-4.4/kernel/time/timer_list.c
@@ -69,7 +69,7 @@ print_timer(struct seq_file *m, struct h
 	print_name_offset(m, taddr);
 	SEQ_printf(m, ", ");
 	print_name_offset(m, timer->function);
-	SEQ_printf(m, ", S:%02lx", timer->state);
+	SEQ_printf(m, ", S:%02x", timer->state);
 #ifdef CONFIG_TIMER_STATS
 	SEQ_printf(m, ", ");
 	print_name_offset(m, timer->start_site);
--- zfcpdump-kernel-4.4.orig/kernel/trace/Makefile
+++ zfcpdump-kernel-4.4/kernel/trace/Makefile
@@ -1,4 +1,8 @@
 
+# We are fully aware of the dangers of __builtin_return_address()
+FRAME_CFLAGS := $(call cc-disable-warning,frame-address)
+KBUILD_CFLAGS += $(FRAME_CFLAGS)
+
 # Do not instrument the tracer itself:
 
 ifdef CONFIG_FUNCTION_TRACER
--- zfcpdump-kernel-4.4.orig/kernel/trace/power-traces.c
+++ zfcpdump-kernel-4.4/kernel/trace/power-traces.c
@@ -15,4 +15,5 @@
 
 EXPORT_TRACEPOINT_SYMBOL_GPL(suspend_resume);
 EXPORT_TRACEPOINT_SYMBOL_GPL(cpu_idle);
+EXPORT_TRACEPOINT_SYMBOL_GPL(powernv_throttle);
 
--- zfcpdump-kernel-4.4.orig/kernel/trace/ring_buffer.c
+++ zfcpdump-kernel-4.4/kernel/trace/ring_buffer.c
@@ -437,7 +437,7 @@ struct ring_buffer_per_cpu {
 	raw_spinlock_t			reader_lock;	/* serialize readers */
 	arch_spinlock_t			lock;
 	struct lock_class_key		lock_key;
-	unsigned int			nr_pages;
+	unsigned long			nr_pages;
 	unsigned int			current_context;
 	struct list_head		*pages;
 	struct buffer_page		*head_page;	/* read from head */
@@ -458,7 +458,7 @@ struct ring_buffer_per_cpu {
 	u64				write_stamp;
 	u64				read_stamp;
 	/* ring buffer pages to update, > 0 to add, < 0 to remove */
-	int				nr_pages_to_update;
+	long				nr_pages_to_update;
 	struct list_head		new_pages; /* new pages to add */
 	struct work_struct		update_pages_work;
 	struct completion		update_done;
@@ -1137,10 +1137,10 @@ static int rb_check_pages(struct ring_bu
 	return 0;
 }
 
-static int __rb_allocate_pages(int nr_pages, struct list_head *pages, int cpu)
+static int __rb_allocate_pages(long nr_pages, struct list_head *pages, int cpu)
 {
-	int i;
 	struct buffer_page *bpage, *tmp;
+	long i;
 
 	for (i = 0; i < nr_pages; i++) {
 		struct page *page;
@@ -1177,7 +1177,7 @@ free_pages:
 }
 
 static int rb_allocate_pages(struct ring_buffer_per_cpu *cpu_buffer,
-			     unsigned nr_pages)
+			     unsigned long nr_pages)
 {
 	LIST_HEAD(pages);
 
@@ -1202,7 +1202,7 @@ static int rb_allocate_pages(struct ring
 }
 
 static struct ring_buffer_per_cpu *
-rb_allocate_cpu_buffer(struct ring_buffer *buffer, int nr_pages, int cpu)
+rb_allocate_cpu_buffer(struct ring_buffer *buffer, long nr_pages, int cpu)
 {
 	struct ring_buffer_per_cpu *cpu_buffer;
 	struct buffer_page *bpage;
@@ -1302,8 +1302,9 @@ struct ring_buffer *__ring_buffer_alloc(
 					struct lock_class_key *key)
 {
 	struct ring_buffer *buffer;
+	long nr_pages;
 	int bsize;
-	int cpu, nr_pages;
+	int cpu;
 
 	/* keep it in its own cache line */
 	buffer = kzalloc(ALIGN(sizeof(*buffer), cache_line_size()),
@@ -1429,12 +1430,12 @@ static inline unsigned long rb_page_writ
 }
 
 static int
-rb_remove_pages(struct ring_buffer_per_cpu *cpu_buffer, unsigned int nr_pages)
+rb_remove_pages(struct ring_buffer_per_cpu *cpu_buffer, unsigned long nr_pages)
 {
 	struct list_head *tail_page, *to_remove, *next_page;
 	struct buffer_page *to_remove_page, *tmp_iter_page;
 	struct buffer_page *last_page, *first_page;
-	unsigned int nr_removed;
+	unsigned long nr_removed;
 	unsigned long head_bit;
 	int page_entries;
 
@@ -1651,7 +1652,7 @@ int ring_buffer_resize(struct ring_buffe
 			int cpu_id)
 {
 	struct ring_buffer_per_cpu *cpu_buffer;
-	unsigned nr_pages;
+	unsigned long nr_pages;
 	int cpu, err = 0;
 
 	/*
@@ -1665,14 +1666,13 @@ int ring_buffer_resize(struct ring_buffe
 	    !cpumask_test_cpu(cpu_id, buffer->cpumask))
 		return size;
 
-	size = DIV_ROUND_UP(size, BUF_PAGE_SIZE);
-	size *= BUF_PAGE_SIZE;
+	nr_pages = DIV_ROUND_UP(size, BUF_PAGE_SIZE);
 
 	/* we need a minimum of two pages */
-	if (size < BUF_PAGE_SIZE * 2)
-		size = BUF_PAGE_SIZE * 2;
+	if (nr_pages < 2)
+		nr_pages = 2;
 
-	nr_pages = DIV_ROUND_UP(size, BUF_PAGE_SIZE);
+	size = nr_pages * BUF_PAGE_SIZE;
 
 	/*
 	 * Don't succeed if resizing is disabled, as a reader might be
@@ -4645,8 +4645,9 @@ static int rb_cpu_notify(struct notifier
 	struct ring_buffer *buffer =
 		container_of(self, struct ring_buffer, cpu_notify);
 	long cpu = (long)hcpu;
-	int cpu_i, nr_pages_same;
-	unsigned int nr_pages;
+	long nr_pages_same;
+	int cpu_i;
+	unsigned long nr_pages;
 
 	switch (action) {
 	case CPU_UP_PREPARE:
--- zfcpdump-kernel-4.4.orig/kernel/trace/trace.c
+++ zfcpdump-kernel-4.4/kernel/trace/trace.c
@@ -1751,7 +1751,7 @@ void trace_buffer_unlock_commit_regs(str
 {
 	__buffer_unlock_commit(buffer, event);
 
-	ftrace_trace_stack(tr, buffer, flags, 6, pc, regs);
+	ftrace_trace_stack(tr, buffer, flags, 0, pc, regs);
 	ftrace_trace_userstack(buffer, flags, pc);
 }
 EXPORT_SYMBOL_GPL(trace_buffer_unlock_commit_regs);
@@ -4727,19 +4727,20 @@ tracing_read_pipe(struct file *filp, cha
 	struct trace_iterator *iter = filp->private_data;
 	ssize_t sret;
 
-	/* return any leftover data */
-	sret = trace_seq_to_user(&iter->seq, ubuf, cnt);
-	if (sret != -EBUSY)
-		return sret;
-
-	trace_seq_init(&iter->seq);
-
 	/*
 	 * Avoid more than one consumer on a single file descriptor
 	 * This is just a matter of traces coherency, the ring buffer itself
 	 * is protected.
 	 */
 	mutex_lock(&iter->mutex);
+
+	/* return any leftover data */
+	sret = trace_seq_to_user(&iter->seq, ubuf, cnt);
+	if (sret != -EBUSY)
+		goto out;
+
+	trace_seq_init(&iter->seq);
+
 	if (iter->trace->read) {
 		sret = iter->trace->read(iter, filp, ubuf, cnt, ppos);
 		if (sret)
@@ -4949,7 +4950,10 @@ static ssize_t tracing_splice_read_pipe(
 
 	spd.nr_pages = i;
 
-	ret = splice_to_pipe(pipe, &spd);
+	if (i)
+		ret = splice_to_pipe(pipe, &spd);
+	else
+		ret = 0;
 out:
 	splice_shrink_spd(&spd);
 	return ret;
@@ -5763,9 +5767,6 @@ tracing_buffers_splice_read(struct file
 		return -EBUSY;
 #endif
 
-	if (splice_grow_spd(pipe, &spd))
-		return -ENOMEM;
-
 	if (*ppos & (PAGE_SIZE - 1))
 		return -EINVAL;
 
@@ -5775,6 +5776,9 @@ tracing_buffers_splice_read(struct file
 		len &= PAGE_MASK;
 	}
 
+	if (splice_grow_spd(pipe, &spd))
+		return -ENOMEM;
+
  again:
 	trace_access_lock(iter->cpu_file);
 	entries = ring_buffer_entries_cpu(iter->trace_buffer->buffer, iter->cpu_file);
@@ -5832,19 +5836,21 @@ tracing_buffers_splice_read(struct file
 	/* did we read anything? */
 	if (!spd.nr_pages) {
 		if (ret)
-			return ret;
+			goto out;
 
+		ret = -EAGAIN;
 		if ((file->f_flags & O_NONBLOCK) || (flags & SPLICE_F_NONBLOCK))
-			return -EAGAIN;
+			goto out;
 
 		ret = wait_on_pipe(iter, true);
 		if (ret)
-			return ret;
+			goto out;
 
 		goto again;
 	}
 
 	ret = splice_to_pipe(pipe, &spd);
+out:
 	splice_shrink_spd(&spd);
 
 	return ret;
--- zfcpdump-kernel-4.4.orig/kernel/trace/trace_events.c
+++ zfcpdump-kernel-4.4/kernel/trace/trace_events.c
@@ -97,16 +97,16 @@ trace_find_event_field(struct trace_even
 	struct ftrace_event_field *field;
 	struct list_head *head;
 
-	field = __find_event_field(&ftrace_generic_fields, name);
+	head = trace_get_fields(call);
+	field = __find_event_field(head, name);
 	if (field)
 		return field;
 
-	field = __find_event_field(&ftrace_common_fields, name);
+	field = __find_event_field(&ftrace_generic_fields, name);
 	if (field)
 		return field;
 
-	head = trace_get_fields(call);
-	return __find_event_field(head, name);
+	return __find_event_field(&ftrace_common_fields, name);
 }
 
 static int __trace_define_field(struct list_head *head, const char *type,
@@ -171,8 +171,10 @@ static int trace_define_generic_fields(v
 {
 	int ret;
 
-	__generic_field(int, cpu, FILTER_OTHER);
-	__generic_field(char *, comm, FILTER_PTR_STRING);
+	__generic_field(int, CPU, FILTER_CPU);
+	__generic_field(int, cpu, FILTER_CPU);
+	__generic_field(char *, COMM, FILTER_COMM);
+	__generic_field(char *, comm, FILTER_COMM);
 
 	return ret;
 }
@@ -869,7 +871,8 @@ t_next(struct seq_file *m, void *v, loff
 		 * The ftrace subsystem is for showing formats only.
 		 * They can not be enabled or disabled via the event files.
 		 */
-		if (call->class && call->class->reg)
+		if (call->class && call->class->reg &&
+		    !(call->flags & TRACE_EVENT_FL_IGNORE_ENABLE))
 			return file;
 	}
 
@@ -2104,8 +2107,13 @@ event_create_dir(struct dentry *parent,
 	trace_create_file("filter", 0644, file->dir, file,
 			  &ftrace_event_filter_fops);
 
-	trace_create_file("trigger", 0644, file->dir, file,
-			  &event_trigger_fops);
+	/*
+	 * Only event directories that can be enabled should have
+	 * triggers.
+	 */
+	if (!(call->flags & TRACE_EVENT_FL_IGNORE_ENABLE))
+		trace_create_file("trigger", 0644, file->dir, file,
+				  &event_trigger_fops);
 
 	trace_create_file("format", 0444, file->dir, call,
 			  &ftrace_event_format_fops);
--- zfcpdump-kernel-4.4.orig/kernel/trace/trace_events_filter.c
+++ zfcpdump-kernel-4.4/kernel/trace/trace_events_filter.c
@@ -1043,13 +1043,14 @@ static int init_pred(struct filter_parse
 		return -EINVAL;
 	}
 
-	if (is_string_field(field)) {
+	if (field->filter_type == FILTER_COMM) {
+		filter_build_regex(pred);
+		fn = filter_pred_comm;
+		pred->regex.field_len = TASK_COMM_LEN;
+	} else if (is_string_field(field)) {
 		filter_build_regex(pred);
 
-		if (!strcmp(field->name, "comm")) {
-			fn = filter_pred_comm;
-			pred->regex.field_len = TASK_COMM_LEN;
-		} else if (field->filter_type == FILTER_STATIC_STRING) {
+		if (field->filter_type == FILTER_STATIC_STRING) {
 			fn = filter_pred_string;
 			pred->regex.field_len = field->size;
 		} else if (field->filter_type == FILTER_DYN_STRING)
@@ -1072,7 +1073,7 @@ static int init_pred(struct filter_parse
 		}
 		pred->val = val;
 
-		if (!strcmp(field->name, "cpu"))
+		if (field->filter_type == FILTER_CPU)
 			fn = filter_pred_cpu;
 		else
 			fn = select_comparison_fn(pred->op, field->size,
--- zfcpdump-kernel-4.4.orig/kernel/trace/trace_irqsoff.c
+++ zfcpdump-kernel-4.4/kernel/trace/trace_irqsoff.c
@@ -109,8 +109,12 @@ static int func_prolog_dec(struct trace_
 		return 0;
 
 	local_save_flags(*flags);
-	/* slight chance to get a false positive on tracing_cpu */
-	if (!irqs_disabled_flags(*flags))
+	/*
+	 * Slight chance to get a false positive on tracing_cpu,
+	 * although I'm starting to think there isn't a chance.
+	 * Leave this for now just to be paranoid.
+	 */
+	if (!irqs_disabled_flags(*flags) && !preempt_count())
 		return 0;
 
 	*data = per_cpu_ptr(tr->trace_buffer.data, cpu);
--- zfcpdump-kernel-4.4.orig/kernel/trace/trace_printk.c
+++ zfcpdump-kernel-4.4/kernel/trace/trace_printk.c
@@ -36,6 +36,10 @@ struct trace_bprintk_fmt {
 static inline struct trace_bprintk_fmt *lookup_format(const char *fmt)
 {
 	struct trace_bprintk_fmt *pos;
+
+	if (!fmt)
+		return ERR_PTR(-EINVAL);
+
 	list_for_each_entry(pos, &trace_bprintk_fmt_list, list) {
 		if (!strcmp(pos->fmt, fmt))
 			return pos;
@@ -57,7 +61,8 @@ void hold_module_trace_bprintk_format(co
 	for (iter = start; iter < end; iter++) {
 		struct trace_bprintk_fmt *tb_fmt = lookup_format(*iter);
 		if (tb_fmt) {
-			*iter = tb_fmt->fmt;
+			if (!IS_ERR(tb_fmt))
+				*iter = tb_fmt->fmt;
 			continue;
 		}
 
@@ -296,6 +301,9 @@ static int t_show(struct seq_file *m, vo
 	const char *str = *fmt;
 	int i;
 
+	if (!*fmt)
+		return 0;
+
 	seq_printf(m, "0x%lx : \"", *(unsigned long *)fmt);
 
 	/*
--- zfcpdump-kernel-4.4.orig/kernel/trace/trace_stack.c
+++ zfcpdump-kernel-4.4/kernel/trace/trace_stack.c
@@ -126,6 +126,13 @@ check_stack(unsigned long ip, unsigned l
 	}
 
 	/*
+	 * Some archs may not have the passed in ip in the dump.
+	 * If that happens, we need to show everything.
+	 */
+	if (i == stack_trace_max.nr_entries)
+		i = 0;
+
+	/*
 	 * Now find where in the stack these are.
 	 */
 	x = 0;
--- zfcpdump-kernel-4.4.orig/kernel/user_namespace.c
+++ zfcpdump-kernel-4.4/kernel/user_namespace.c
@@ -23,6 +23,12 @@
 #include <linux/projid.h>
 #include <linux/fs_struct.h>
 
+/*
+ * sysctl determining whether unprivileged users may unshare a new
+ * userns.  Allowed by default
+ */
+int unprivileged_userns_clone = 1;
+
 static struct kmem_cache *user_ns_cachep __read_mostly;
 static DEFINE_MUTEX(userns_state_mutex);
 
@@ -945,6 +951,21 @@ bool userns_may_setgroups(const struct u
 	return allowed;
 }
 
+/*
+ * Returns true if @ns is the same namespace as or a descendant of
+ * @target_ns.
+ */
+bool current_in_userns(const struct user_namespace *target_ns)
+{
+	struct user_namespace *ns;
+	for (ns = current_user_ns(); ns; ns = ns->parent) {
+		if (ns == target_ns)
+			return true;
+	}
+	return false;
+}
+EXPORT_SYMBOL(current_in_userns);
+
 static inline struct user_namespace *to_user_ns(struct ns_common *ns)
 {
 	return container_of(ns, struct user_namespace, ns);
--- zfcpdump-kernel-4.4.orig/kernel/watchdog.c
+++ zfcpdump-kernel-4.4/kernel/watchdog.c
@@ -907,6 +907,9 @@ static int proc_watchdog_common(int whic
 		 * both lockup detectors are disabled if proc_watchdog_update()
 		 * returns an error.
 		 */
+		if (old == new)
+			goto out;
+
 		err = proc_watchdog_update();
 	}
 out:
@@ -951,7 +954,7 @@ int proc_soft_watchdog(struct ctl_table
 int proc_watchdog_thresh(struct ctl_table *table, int write,
 			 void __user *buffer, size_t *lenp, loff_t *ppos)
 {
-	int err, old;
+	int err, old, new;
 
 	get_online_cpus();
 	mutex_lock(&watchdog_proc_mutex);
@@ -971,6 +974,10 @@ int proc_watchdog_thresh(struct ctl_tabl
 	/*
 	 * Update the sample period. Restore on failure.
 	 */
+	new = ACCESS_ONCE(watchdog_thresh);
+	if (old == new)
+		goto out;
+
 	set_sample_period();
 	err = proc_watchdog_update();
 	if (err) {
--- zfcpdump-kernel-4.4.orig/kernel/workqueue.c
+++ zfcpdump-kernel-4.4/kernel/workqueue.c
@@ -568,6 +568,16 @@ static struct pool_workqueue *unbound_pw
 						  int node)
 {
 	assert_rcu_or_wq_mutex_or_pool_mutex(wq);
+
+	/*
+	 * XXX: @node can be NUMA_NO_NODE if CPU goes offline while a
+	 * delayed item is pending.  The plan is to keep CPU -> NODE
+	 * mapping valid and stable across CPU on/offlines.  Once that
+	 * happens, this workaround can be removed.
+	 */
+	if (unlikely(node == NUMA_NO_NODE))
+		return wq->dfl_pwq;
+
 	return rcu_dereference_raw(wq->numa_pwq_tbl[node]);
 }
 
@@ -639,6 +649,35 @@ static void set_work_pool_and_clear_pend
 	 */
 	smp_wmb();
 	set_work_data(work, (unsigned long)pool_id << WORK_OFFQ_POOL_SHIFT, 0);
+	/*
+	 * The following mb guarantees that previous clear of a PENDING bit
+	 * will not be reordered with any speculative LOADS or STORES from
+	 * work->current_func, which is executed afterwards.  This possible
+	 * reordering can lead to a missed execution on attempt to qeueue
+	 * the same @work.  E.g. consider this case:
+	 *
+	 *   CPU#0                         CPU#1
+	 *   ----------------------------  --------------------------------
+	 *
+	 * 1  STORE event_indicated
+	 * 2  queue_work_on() {
+	 * 3    test_and_set_bit(PENDING)
+	 * 4 }                             set_..._and_clear_pending() {
+	 * 5                                 set_work_data() # clear bit
+	 * 6                                 smp_mb()
+	 * 7                               work->current_func() {
+	 * 8				      LOAD event_indicated
+	 *				   }
+	 *
+	 * Without an explicit full barrier speculative LOAD on line 8 can
+	 * be executed before CPU#0 does STORE on line 1.  If that happens,
+	 * CPU#0 observes the PENDING bit is still set and new execution of
+	 * a @work is not queued in a hope, that CPU#1 will eventually
+	 * finish the queued @work.  Meanwhile CPU#1 does not see
+	 * event_indicated is set, because speculative LOAD was executed
+	 * before actual STORE.
+	 */
+	smp_mb();
 }
 
 static void clear_work_data(struct work_struct *work)
@@ -1458,13 +1497,13 @@ static void __queue_delayed_work(int cpu
 	timer_stats_timer_set_start_info(&dwork->timer);
 
 	dwork->wq = wq;
-	/* timer isn't guaranteed to run in this cpu, record earlier */
-	if (cpu == WORK_CPU_UNBOUND)
-		cpu = raw_smp_processor_id();
 	dwork->cpu = cpu;
 	timer->expires = jiffies + delay;
 
-	add_timer_on(timer, cpu);
+	if (unlikely(cpu != WORK_CPU_UNBOUND))
+		add_timer_on(timer, cpu);
+	else
+		add_timer(timer);
 }
 
 /**
@@ -4418,6 +4457,17 @@ static void rebind_workers(struct worker
 						  pool->attrs->cpumask) < 0);
 
 	spin_lock_irq(&pool->lock);
+
+	/*
+	 * XXX: CPU hotplug notifiers are weird and can call DOWN_FAILED
+	 * w/o preceding DOWN_PREPARE.  Work around it.  CPU hotplug is
+	 * being reworked and this can go away in time.
+	 */
+	if (!(pool->flags & POOL_DISASSOCIATED)) {
+		spin_unlock_irq(&pool->lock);
+		return;
+	}
+
 	pool->flags &= ~POOL_DISASSOCIATED;
 
 	for_each_pool_worker(worker, pool) {
--- zfcpdump-kernel-4.4.orig/lib/842/842.h
+++ zfcpdump-kernel-4.4/lib/842/842.h
@@ -76,7 +76,6 @@
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/bitops.h>
-#include <linux/crc32.h>
 #include <asm/unaligned.h>
 
 #include <linux/sw842.h>
@@ -99,7 +98,6 @@
 #define I2_BITS		(8)
 #define I4_BITS		(9)
 #define I8_BITS		(8)
-#define CRC_BITS	(32)
 
 #define REPEAT_BITS_MAX		(0x3f)
 #define SHORT_DATA_BITS_MAX	(0x7)
--- zfcpdump-kernel-4.4.orig/lib/842/842_compress.c
+++ zfcpdump-kernel-4.4/lib/842/842_compress.c
@@ -490,7 +490,6 @@ int sw842_compress(const u8 *in, unsigne
 	int ret;
 	u64 last, next, pad, total;
 	u8 repeat_count = 0;
-	u32 crc;
 
 	BUILD_BUG_ON(sizeof(*p) > SW842_MEM_COMPRESS);
 
@@ -581,18 +580,6 @@ skip_comp:
 	if (ret)
 		return ret;
 
-	/*
-	 * crc(0:31) is appended to target data starting with the next
-	 * bit after End of stream template.
-	 * nx842 calculates CRC for data in big-endian format. So doing
-	 * same here so that sw842 decompression can be used for both
-	 * compressed data.
-	 */
-	crc = crc32_be(0, in, ilen);
-	ret = add_bits(p, crc, CRC_BITS);
-	if (ret)
-		return ret;
-
 	if (p->bit) {
 		p->out++;
 		p->olen--;
--- zfcpdump-kernel-4.4.orig/lib/842/842_decompress.c
+++ zfcpdump-kernel-4.4/lib/842/842_decompress.c
@@ -285,7 +285,6 @@ int sw842_decompress(const u8 *in, unsig
 	struct sw842_param p;
 	int ret;
 	u64 op, rep, tmp, bytes, total;
-	u64 crc;
 
 	p.in = (u8 *)in;
 	p.bit = 0;
@@ -376,22 +375,6 @@ int sw842_decompress(const u8 *in, unsig
 		}
 	} while (op != OP_END);
 
-	/*
-	 * crc(0:31) is saved in compressed data starting with the
-	 * next bit after End of stream template.
-	 */
-	ret = next_bits(&p, &crc, CRC_BITS);
-	if (ret)
-		return ret;
-
-	/*
-	 * Validate CRC saved in compressed data.
-	 */
-	if (crc != (u64)crc32_be(0, out, total - p.olen)) {
-		pr_debug("CRC mismatch for decompression\n");
-		return -EINVAL;
-	}
-
 	if (unlikely((total - p.olen) > UINT_MAX))
 		return -ENOSPC;
 
--- zfcpdump-kernel-4.4.orig/lib/Kconfig
+++ zfcpdump-kernel-4.4/lib/Kconfig
@@ -210,9 +210,11 @@ config RANDOM32_SELFTEST
 # compression support is select'ed if needed
 #
 config 842_COMPRESS
+	select CRC32
 	tristate
 
 config 842_DECOMPRESS
+	select CRC32
 	tristate
 
 config ZLIB_INFLATE
--- zfcpdump-kernel-4.4.orig/lib/asn1_decoder.c
+++ zfcpdump-kernel-4.4/lib/asn1_decoder.c
@@ -74,7 +74,7 @@ next_tag:
 
 	/* Extract a tag from the data */
 	tag = data[dp++];
-	if (tag == 0) {
+	if (tag == ASN1_EOC) {
 		/* It appears to be an EOC. */
 		if (data[dp++] != 0)
 			goto invalid_eoc;
@@ -96,10 +96,8 @@ next_tag:
 
 	/* Extract the length */
 	len = data[dp++];
-	if (len <= 0x7f) {
-		dp += len;
-		goto next_tag;
-	}
+	if (len <= 0x7f)
+		goto check_length;
 
 	if (unlikely(len == ASN1_INDEFINITE_LENGTH)) {
 		/* Indefinite length */
@@ -110,14 +108,18 @@ next_tag:
 	}
 
 	n = len - 0x80;
-	if (unlikely(n > sizeof(size_t) - 1))
+	if (unlikely(n > sizeof(len) - 1))
 		goto length_too_long;
 	if (unlikely(n > datalen - dp))
 		goto data_overrun_error;
-	for (len = 0; n > 0; n--) {
+	len = 0;
+	for (; n > 0; n--) {
 		len <<= 8;
 		len |= data[dp++];
 	}
+check_length:
+	if (len > datalen - dp)
+		goto data_overrun_error;
 	dp += len;
 	goto next_tag;
 
--- zfcpdump-kernel-4.4.orig/lib/assoc_array.c
+++ zfcpdump-kernel-4.4/lib/assoc_array.c
@@ -524,7 +524,9 @@ static bool assoc_array_insert_into_term
 			free_slot = i;
 			continue;
 		}
-		if (ops->compare_object(assoc_array_ptr_to_leaf(ptr), index_key)) {
+		if (assoc_array_ptr_is_leaf(ptr) &&
+		    ops->compare_object(assoc_array_ptr_to_leaf(ptr),
+					index_key)) {
 			pr_devel("replace in slot %d\n", i);
 			edit->leaf_p = &node->slots[i];
 			edit->dead_leaf = node->slots[i];
--- zfcpdump-kernel-4.4.orig/lib/atomic64_test.c
+++ zfcpdump-kernel-4.4/lib/atomic64_test.c
@@ -16,6 +16,10 @@
 #include <linux/kernel.h>
 #include <linux/atomic.h>
 
+#ifdef CONFIG_X86
+#include <asm/cpufeature.h>	/* for boot_cpu_has below */
+#endif
+
 #define TEST(bit, op, c_op, val)				\
 do {								\
 	atomic##bit##_set(&v, v0);				\
--- zfcpdump-kernel-4.4.orig/lib/bitmap.c
+++ zfcpdump-kernel-4.4/lib/bitmap.c
@@ -12,6 +12,8 @@
 #include <linux/bitmap.h>
 #include <linux/bitops.h>
 #include <linux/bug.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
 
 #include <asm/page.h>
 #include <asm/uaccess.h>
@@ -1060,6 +1062,93 @@ int bitmap_allocate_region(unsigned long
 EXPORT_SYMBOL(bitmap_allocate_region);
 
 /**
+ * bitmap_from_u32array - copy the contents of a u32 array of bits to bitmap
+ *	@bitmap: array of unsigned longs, the destination bitmap, non NULL
+ *	@nbits: number of bits in @bitmap
+ *	@buf: array of u32 (in host byte order), the source bitmap, non NULL
+ *	@nwords: number of u32 words in @buf
+ *
+ * copy min(nbits, 32*nwords) bits from @buf to @bitmap, remaining
+ * bits between nword and nbits in @bitmap (if any) are cleared. In
+ * last word of @bitmap, the bits beyond nbits (if any) are kept
+ * unchanged.
+ *
+ * Return the number of bits effectively copied.
+ */
+unsigned int
+bitmap_from_u32array(unsigned long *bitmap, unsigned int nbits,
+		     const u32 *buf, unsigned int nwords)
+{
+	unsigned int dst_idx, src_idx;
+
+	for (src_idx = dst_idx = 0; dst_idx < BITS_TO_LONGS(nbits); ++dst_idx) {
+		unsigned long part = 0;
+
+		if (src_idx < nwords)
+			part = buf[src_idx++];
+
+#if BITS_PER_LONG == 64
+		if (src_idx < nwords)
+			part |= ((unsigned long) buf[src_idx++]) << 32;
+#endif
+
+		if (dst_idx < nbits/BITS_PER_LONG)
+			bitmap[dst_idx] = part;
+		else {
+			unsigned long mask = BITMAP_LAST_WORD_MASK(nbits);
+
+			bitmap[dst_idx] = (bitmap[dst_idx] & ~mask)
+				| (part & mask);
+		}
+	}
+
+	return min_t(unsigned int, nbits, 32*nwords);
+}
+EXPORT_SYMBOL(bitmap_from_u32array);
+
+/**
+ * bitmap_to_u32array - copy the contents of bitmap to a u32 array of bits
+ *	@buf: array of u32 (in host byte order), the dest bitmap, non NULL
+ *	@nwords: number of u32 words in @buf
+ *	@bitmap: array of unsigned longs, the source bitmap, non NULL
+ *	@nbits: number of bits in @bitmap
+ *
+ * copy min(nbits, 32*nwords) bits from @bitmap to @buf. Remaining
+ * bits after nbits in @buf (if any) are cleared.
+ *
+ * Return the number of bits effectively copied.
+ */
+unsigned int
+bitmap_to_u32array(u32 *buf, unsigned int nwords,
+		   const unsigned long *bitmap, unsigned int nbits)
+{
+	unsigned int dst_idx = 0, src_idx = 0;
+
+	while (dst_idx < nwords) {
+		unsigned long part = 0;
+
+		if (src_idx < BITS_TO_LONGS(nbits)) {
+			part = bitmap[src_idx];
+			if (src_idx >= nbits/BITS_PER_LONG)
+				part &= BITMAP_LAST_WORD_MASK(nbits);
+			src_idx++;
+		}
+
+		buf[dst_idx++] = part & 0xffffffffUL;
+
+#if BITS_PER_LONG == 64
+		if (dst_idx < nwords) {
+			part >>= 32;
+			buf[dst_idx++] = part & 0xffffffffUL;
+		}
+#endif
+	}
+
+	return min_t(unsigned int, nbits, 32*nwords);
+}
+EXPORT_SYMBOL(bitmap_to_u32array);
+
+/**
  * bitmap_copy_le - copy a bitmap, putting the bits into little-endian order.
  * @dst:   destination buffer
  * @src:   bitmap to copy
--- zfcpdump-kernel-4.4.orig/lib/dma-debug.c
+++ zfcpdump-kernel-4.4/lib/dma-debug.c
@@ -657,9 +657,9 @@ static struct dma_debug_entry *dma_entry
 	spin_lock_irqsave(&free_entries_lock, flags);
 
 	if (list_empty(&free_entries)) {
-		pr_err("DMA-API: debugging out of memory - disabling\n");
 		global_disable = true;
 		spin_unlock_irqrestore(&free_entries_lock, flags);
+		pr_err("DMA-API: debugging out of memory - disabling\n");
 		return NULL;
 	}
 
@@ -1181,7 +1181,7 @@ static inline bool overlap(void *addr, u
 
 static void check_for_illegal_area(struct device *dev, void *addr, unsigned long len)
 {
-	if (overlap(addr, len, _text, _etext) ||
+	if (overlap(addr, len, _stext, _etext) ||
 	    overlap(addr, len, __start_rodata, __end_rodata))
 		err_printk(dev, NULL, "DMA-API: device driver maps memory from kernel text or rodata [addr=%p] [len=%lu]\n", addr, len);
 }
--- zfcpdump-kernel-4.4.orig/lib/dump_stack.c
+++ zfcpdump-kernel-4.4/lib/dump_stack.c
@@ -25,6 +25,7 @@ static atomic_t dump_lock = ATOMIC_INIT(
 
 asmlinkage __visible void dump_stack(void)
 {
+	unsigned long flags;
 	int was_locked;
 	int old;
 	int cpu;
@@ -33,9 +34,8 @@ asmlinkage __visible void dump_stack(voi
 	 * Permit this cpu to perform nested stack dumps while serialising
 	 * against other CPUs
 	 */
-	preempt_disable();
-
 retry:
+	local_irq_save(flags);
 	cpu = smp_processor_id();
 	old = atomic_cmpxchg(&dump_lock, -1, cpu);
 	if (old == -1) {
@@ -43,6 +43,7 @@ retry:
 	} else if (old == cpu) {
 		was_locked = 1;
 	} else {
+		local_irq_restore(flags);
 		cpu_relax();
 		goto retry;
 	}
@@ -52,7 +53,7 @@ retry:
 	if (!was_locked)
 		atomic_set(&dump_lock, -1);
 
-	preempt_enable();
+	local_irq_restore(flags);
 }
 #else
 asmlinkage __visible void dump_stack(void)
--- zfcpdump-kernel-4.4.orig/lib/iov_iter.c
+++ zfcpdump-kernel-4.4/lib/iov_iter.c
@@ -298,33 +298,13 @@ done:
 }
 
 /*
- * Fault in the first iovec of the given iov_iter, to a maximum length
- * of bytes. Returns 0 on success, or non-zero if the memory could not be
- * accessed (ie. because it is an invalid address).
- *
- * writev-intensive code may want this to prefault several iovecs -- that
- * would be possible (callers must not rely on the fact that _only_ the
- * first iovec will be faulted with the current implementation).
- */
-int iov_iter_fault_in_readable(struct iov_iter *i, size_t bytes)
-{
-	if (!(i->type & (ITER_BVEC|ITER_KVEC))) {
-		char __user *buf = i->iov->iov_base + i->iov_offset;
-		bytes = min(bytes, i->iov->iov_len - i->iov_offset);
-		return fault_in_pages_readable(buf, bytes);
-	}
-	return 0;
-}
-EXPORT_SYMBOL(iov_iter_fault_in_readable);
-
-/*
  * Fault in one or more iovecs of the given iov_iter, to a maximum length of
  * bytes.  For each iovec, fault in each page that constitutes the iovec.
  *
  * Return 0 on success, or non-zero if the memory could not be accessed (i.e.
  * because it is an invalid address).
  */
-int iov_iter_fault_in_multipages_readable(struct iov_iter *i, size_t bytes)
+int iov_iter_fault_in_readable(struct iov_iter *i, size_t bytes)
 {
 	size_t skip = i->iov_offset;
 	const struct iovec *iov;
@@ -341,7 +321,7 @@ int iov_iter_fault_in_multipages_readabl
 	}
 	return 0;
 }
-EXPORT_SYMBOL(iov_iter_fault_in_multipages_readable);
+EXPORT_SYMBOL(iov_iter_fault_in_readable);
 
 void iov_iter_init(struct iov_iter *i, int direction,
 			const struct iovec *iov, unsigned long nr_segs,
--- zfcpdump-kernel-4.4.orig/lib/klist.c
+++ zfcpdump-kernel-4.4/lib/klist.c
@@ -282,9 +282,9 @@ void klist_iter_init_node(struct klist *
 			  struct klist_node *n)
 {
 	i->i_klist = k;
-	i->i_cur = n;
-	if (n)
-		kref_get(&n->n_ref);
+	i->i_cur = NULL;
+	if (n && kref_get_unless_zero(&n->n_ref))
+		i->i_cur = n;
 }
 EXPORT_SYMBOL_GPL(klist_iter_init_node);
 
--- zfcpdump-kernel-4.4.orig/lib/libcrc32c.c
+++ zfcpdump-kernel-4.4/lib/libcrc32c.c
@@ -74,3 +74,4 @@ module_exit(libcrc32c_mod_fini);
 MODULE_AUTHOR("Clay Haapala <chaapala@cisco.com>");
 MODULE_DESCRIPTION("CRC32c (Castagnoli) calculations");
 MODULE_LICENSE("GPL");
+MODULE_SOFTDEP("pre: crc32c");
--- zfcpdump-kernel-4.4.orig/lib/lz4/lz4defs.h
+++ zfcpdump-kernel-4.4/lib/lz4/lz4defs.h
@@ -11,8 +11,7 @@
 /*
  * Detects 64 bits mode
  */
-#if (defined(__x86_64__) || defined(__x86_64) || defined(__amd64__) \
-	|| defined(__ppc64__) || defined(__LP64__))
+#if defined(CONFIG_64BIT)
 #define LZ4_ARCH64 1
 #else
 #define LZ4_ARCH64 0
@@ -35,6 +34,10 @@ typedef struct _U64_S { u64 v; } U64_S;
 
 #define PUT4(s, d) (A32(d) = A32(s))
 #define PUT8(s, d) (A64(d) = A64(s))
+
+#define LZ4_READ_LITTLEENDIAN_16(d, s, p)	\
+	(d = s - A16(p))
+
 #define LZ4_WRITE_LITTLEENDIAN_16(p, v)	\
 	do {	\
 		A16(p) = v; \
@@ -51,10 +54,13 @@ typedef struct _U64_S { u64 v; } U64_S;
 #define PUT8(s, d) \
 	put_unaligned(get_unaligned((const u64 *) s), (u64 *) d)
 
-#define LZ4_WRITE_LITTLEENDIAN_16(p, v)	\
-	do {	\
-		put_unaligned(v, (u16 *)(p)); \
-		p += 2; \
+#define LZ4_READ_LITTLEENDIAN_16(d, s, p)	\
+	(d = s - get_unaligned_le16(p))
+
+#define LZ4_WRITE_LITTLEENDIAN_16(p, v)			\
+	do {						\
+		put_unaligned_le16(v, (u16 *)(p));	\
+		p += 2;					\
 	} while (0)
 #endif
 
@@ -140,9 +146,6 @@ typedef struct _U64_S { u64 v; } U64_S;
 
 #endif
 
-#define LZ4_READ_LITTLEENDIAN_16(d, s, p) \
-	(d = s - get_unaligned_le16(p))
-
 #define LZ4_WILDCOPY(s, d, e)		\
 	do {				\
 		LZ4_COPYPACKET(s, d);	\
--- zfcpdump-kernel-4.4.orig/lib/mpi/mpicoder.c
+++ zfcpdump-kernel-4.4/lib/mpi/mpicoder.c
@@ -128,6 +128,23 @@ leave:
 }
 EXPORT_SYMBOL_GPL(mpi_read_from_buffer);
 
+static int count_lzeros(MPI a)
+{
+	mpi_limb_t alimb;
+	int i, lzeros = 0;
+
+	for (i = a->nlimbs - 1; i >= 0; i--) {
+		alimb = a->d[i];
+		if (alimb == 0) {
+			lzeros += sizeof(mpi_limb_t);
+		} else {
+			lzeros += count_leading_zeros(alimb) / 8;
+			break;
+		}
+	}
+	return lzeros;
+}
+
 /**
  * mpi_read_buffer() - read MPI to a bufer provided by user (msb first)
  *
@@ -146,7 +163,7 @@ int mpi_read_buffer(MPI a, uint8_t *buf,
 	uint8_t *p;
 	mpi_limb_t alimb;
 	unsigned int n = mpi_get_size(a);
-	int i, lzeros = 0;
+	int i, lzeros;
 
 	if (buf_len < n || !buf || !nbytes)
 		return -EINVAL;
@@ -154,14 +171,7 @@ int mpi_read_buffer(MPI a, uint8_t *buf,
 	if (sign)
 		*sign = a->sign;
 
-	p = (void *)&a->d[a->nlimbs] - 1;
-
-	for (i = a->nlimbs * sizeof(alimb) - 1; i >= 0; i--, p--) {
-		if (!*p)
-			lzeros++;
-		else
-			break;
-	}
+	lzeros = count_lzeros(a);
 
 	p = buf;
 	*nbytes = n - lzeros;
@@ -343,7 +353,7 @@ int mpi_write_to_sgl(MPI a, struct scatt
 	u8 *p, *p2;
 	mpi_limb_t alimb, alimb2;
 	unsigned int n = mpi_get_size(a);
-	int i, x, y = 0, lzeros = 0, buf_len;
+	int i, x, y = 0, lzeros, buf_len;
 
 	if (!nbytes || *nbytes < n)
 		return -EINVAL;
@@ -351,20 +361,15 @@ int mpi_write_to_sgl(MPI a, struct scatt
 	if (sign)
 		*sign = a->sign;
 
-	p = (void *)&a->d[a->nlimbs] - 1;
-
-	for (i = a->nlimbs * sizeof(alimb) - 1; i >= 0; i--, p--) {
-		if (!*p)
-			lzeros++;
-		else
-			break;
-	}
+	lzeros = count_lzeros(a);
 
 	*nbytes = n - lzeros;
 	buf_len = sgl->length;
 	p2 = sg_virt(sgl);
 
-	for (i = a->nlimbs - 1; i >= 0; i--) {
+	for (i = a->nlimbs - 1 - lzeros / BYTES_PER_MPI_LIMB,
+			lzeros %= BYTES_PER_MPI_LIMB;
+		i >= 0; i--) {
 		alimb = a->d[i];
 		p = (u8 *)&alimb2;
 #if BYTES_PER_MPI_LIMB == 4
@@ -385,17 +390,12 @@ int mpi_write_to_sgl(MPI a, struct scatt
 #error please implement for this limb size.
 #endif
 		if (lzeros > 0) {
-			if (lzeros >= sizeof(alimb)) {
-				p -= sizeof(alimb);
-				continue;
-			} else {
-				mpi_limb_t *limb1 = (void *)p - sizeof(alimb);
-				mpi_limb_t *limb2 = (void *)p - sizeof(alimb)
-							+ lzeros;
-				*limb1 = *limb2;
-				p -= lzeros;
-				y = lzeros;
-			}
+			mpi_limb_t *limb1 = (void *)p - sizeof(alimb);
+			mpi_limb_t *limb2 = (void *)p - sizeof(alimb)
+				+ lzeros;
+			*limb1 = *limb2;
+			p -= lzeros;
+			y = lzeros;
 			lzeros -= sizeof(alimb);
 		}
 
--- zfcpdump-kernel-4.4.orig/lib/radix-tree.c
+++ zfcpdump-kernel-4.4/lib/radix-tree.c
@@ -1019,9 +1019,13 @@ radix_tree_gang_lookup(struct radix_tree
 		return 0;
 
 	radix_tree_for_each_slot(slot, root, &iter, first_index) {
-		results[ret] = indirect_to_ptr(rcu_dereference_raw(*slot));
+		results[ret] = rcu_dereference_raw(*slot);
 		if (!results[ret])
 			continue;
+		if (radix_tree_is_indirect_ptr(results[ret])) {
+			slot = radix_tree_iter_retry(&iter);
+			continue;
+		}
 		if (++ret == max_items)
 			break;
 	}
@@ -1098,9 +1102,13 @@ radix_tree_gang_lookup_tag(struct radix_
 		return 0;
 
 	radix_tree_for_each_tagged(slot, root, &iter, first_index, tag) {
-		results[ret] = indirect_to_ptr(rcu_dereference_raw(*slot));
+		results[ret] = rcu_dereference_raw(*slot);
 		if (!results[ret])
 			continue;
+		if (radix_tree_is_indirect_ptr(results[ret])) {
+			slot = radix_tree_iter_retry(&iter);
+			continue;
+		}
 		if (++ret == max_items)
 			break;
 	}
--- zfcpdump-kernel-4.4.orig/lib/raid6/altivec.uc
+++ zfcpdump-kernel-4.4/lib/raid6/altivec.uc
@@ -101,6 +101,7 @@ static void raid6_altivec$#_gen_syndrome
 
 	raid6_altivec$#_gen_syndrome_real(disks, bytes, ptrs);
 
+	disable_kernel_altivec();
 	preempt_enable();
 }
 
--- zfcpdump-kernel-4.4.orig/lib/string_helpers.c
+++ zfcpdump-kernel-4.4/lib/string_helpers.c
@@ -43,50 +43,73 @@ void string_get_size(u64 size, u64 blk_s
 		[STRING_UNITS_10] = 1000,
 		[STRING_UNITS_2] = 1024,
 	};
-	int i, j;
-	u32 remainder = 0, sf_cap, exp;
+	static const unsigned int rounding[] = { 500, 50, 5 };
+	int i = 0, j;
+	u32 remainder = 0, sf_cap;
 	char tmp[8];
 	const char *unit;
 
 	tmp[0] = '\0';
-	i = 0;
-	if (!size)
+
+	if (blk_size == 0)
+		size = 0;
+	if (size == 0)
 		goto out;
 
-	while (blk_size >= divisor[units]) {
-		remainder = do_div(blk_size, divisor[units]);
+	/* This is Napier's algorithm.  Reduce the original block size to
+	 *
+	 * coefficient * divisor[units]^i
+	 *
+	 * we do the reduction so both coefficients are just under 32 bits so
+	 * that multiplying them together won't overflow 64 bits and we keep
+	 * as much precision as possible in the numbers.
+	 *
+	 * Note: it's safe to throw away the remainders here because all the
+	 * precision is in the coefficients.
+	 */
+	while (blk_size >> 32) {
+		do_div(blk_size, divisor[units]);
 		i++;
 	}
 
-	exp = divisor[units] / (u32)blk_size;
-	/*
-	 * size must be strictly greater than exp here to ensure that remainder
-	 * is greater than divisor[units] coming out of the if below.
-	 */
-	if (size > exp) {
-		remainder = do_div(size, divisor[units]);
-		remainder *= blk_size;
+	while (size >> 32) {
+		do_div(size, divisor[units]);
 		i++;
-	} else {
-		remainder *= size;
 	}
 
+	/* now perform the actual multiplication keeping i as the sum of the
+	 * two logarithms */
 	size *= blk_size;
-	size += remainder / divisor[units];
-	remainder %= divisor[units];
 
+	/* and logarithmically reduce it until it's just under the divisor */
 	while (size >= divisor[units]) {
 		remainder = do_div(size, divisor[units]);
 		i++;
 	}
 
+	/* work out in j how many digits of precision we need from the
+	 * remainder */
 	sf_cap = size;
 	for (j = 0; sf_cap*10 < 1000; j++)
 		sf_cap *= 10;
 
-	if (j) {
+	if (units == STRING_UNITS_2) {
+		/* express the remainder as a decimal.  It's currently the
+		 * numerator of a fraction whose denominator is
+		 * divisor[units], which is 1 << 10 for STRING_UNITS_2 */
 		remainder *= 1000;
-		remainder /= divisor[units];
+		remainder >>= 10;
+	}
+
+	/* add a 5 to the digit below what will be printed to ensure
+	 * an arithmetical round up and carry it through to size */
+	remainder += rounding[j];
+	if (remainder >= 1000) {
+		remainder -= 1000;
+		size += 1;
+	}
+
+	if (j) {
 		snprintf(tmp, sizeof(tmp), ".%03u", remainder);
 		tmp[j+1] = '\0';
 	}
--- zfcpdump-kernel-4.4.orig/lib/test-string_helpers.c
+++ zfcpdump-kernel-4.4/lib/test-string_helpers.c
@@ -327,36 +327,67 @@ out:
 }
 
 #define string_get_size_maxbuf 16
-#define test_string_get_size_one(size, blk_size, units, exp_result)            \
+#define test_string_get_size_one(size, blk_size, exp_result10, exp_result2)    \
 	do {                                                                   \
-		BUILD_BUG_ON(sizeof(exp_result) >= string_get_size_maxbuf);    \
-		__test_string_get_size((size), (blk_size), (units),            \
-				       (exp_result));                          \
+		BUILD_BUG_ON(sizeof(exp_result10) >= string_get_size_maxbuf);  \
+		BUILD_BUG_ON(sizeof(exp_result2) >= string_get_size_maxbuf);   \
+		__test_string_get_size((size), (blk_size), (exp_result10),     \
+				       (exp_result2));                         \
 	} while (0)
 
 
-static __init void __test_string_get_size(const u64 size, const u64 blk_size,
-					  const enum string_size_units units,
-					  const char *exp_result)
+static __init void test_string_get_size_check(const char *units,
+					      const char *exp,
+					      char *res,
+					      const u64 size,
+					      const u64 blk_size)
 {
-	char buf[string_get_size_maxbuf];
-
-	string_get_size(size, blk_size, units, buf, sizeof(buf));
-	if (!memcmp(buf, exp_result, strlen(exp_result) + 1))
+	if (!memcmp(res, exp, strlen(exp) + 1))
 		return;
 
-	buf[sizeof(buf) - 1] = '\0';
-	pr_warn("Test 'test_string_get_size_one' failed!\n");
-	pr_warn("string_get_size(size = %llu, blk_size = %llu, units = %d\n",
+	res[string_get_size_maxbuf - 1] = '\0';
+
+	pr_warn("Test 'test_string_get_size' failed!\n");
+	pr_warn("string_get_size(size = %llu, blk_size = %llu, units = %s)\n",
 		size, blk_size, units);
-	pr_warn("expected: '%s', got '%s'\n", exp_result, buf);
+	pr_warn("expected: '%s', got '%s'\n", exp, res);
+}
+
+static __init void __test_string_get_size(const u64 size, const u64 blk_size,
+					  const char *exp_result10,
+					  const char *exp_result2)
+{
+	char buf10[string_get_size_maxbuf];
+	char buf2[string_get_size_maxbuf];
+
+	string_get_size(size, blk_size, STRING_UNITS_10, buf10, sizeof(buf10));
+	string_get_size(size, blk_size, STRING_UNITS_2, buf2, sizeof(buf2));
+
+	test_string_get_size_check("STRING_UNITS_10", exp_result10, buf10,
+				   size, blk_size);
+
+	test_string_get_size_check("STRING_UNITS_2", exp_result2, buf2,
+				   size, blk_size);
 }
 
 static __init void test_string_get_size(void)
 {
-	test_string_get_size_one(16384, 512, STRING_UNITS_2, "8.00 MiB");
-	test_string_get_size_one(8192, 4096, STRING_UNITS_10, "32.7 MB");
-	test_string_get_size_one(1, 512, STRING_UNITS_10, "512 B");
+	/* small values */
+	test_string_get_size_one(0, 512, "0 B", "0 B");
+	test_string_get_size_one(1, 512, "512 B", "512 B");
+	test_string_get_size_one(1100, 1, "1.10 kB", "1.07 KiB");
+
+	/* normal values */
+	test_string_get_size_one(16384, 512, "8.39 MB", "8.00 MiB");
+	test_string_get_size_one(500118192, 512, "256 GB", "238 GiB");
+	test_string_get_size_one(8192, 4096, "33.6 MB", "32.0 MiB");
+
+	/* weird block sizes */
+	test_string_get_size_one(3000, 1900, "5.70 MB", "5.44 MiB");
+
+	/* huge values */
+	test_string_get_size_one(U64_MAX, 4096, "75.6 ZB", "64.0 ZiB");
+	test_string_get_size_one(4096, U64_MAX, "75.6 ZB", "64.0 ZiB");
 }
 
 static int __init test_string_helpers_init(void)
--- zfcpdump-kernel-4.4.orig/lib/ucs2_string.c
+++ zfcpdump-kernel-4.4/lib/ucs2_string.c
@@ -49,3 +49,65 @@ ucs2_strncmp(const ucs2_char_t *a, const
         }
 }
 EXPORT_SYMBOL(ucs2_strncmp);
+
+unsigned long
+ucs2_utf8size(const ucs2_char_t *src)
+{
+	unsigned long i;
+	unsigned long j = 0;
+
+	for (i = 0; i < ucs2_strlen(src); i++) {
+		u16 c = src[i];
+
+		if (c >= 0x800)
+			j += 3;
+		else if (c >= 0x80)
+			j += 2;
+		else
+			j += 1;
+	}
+
+	return j;
+}
+EXPORT_SYMBOL(ucs2_utf8size);
+
+/*
+ * copy at most maxlength bytes of whole utf8 characters to dest from the
+ * ucs2 string src.
+ *
+ * The return value is the number of characters copied, not including the
+ * final NUL character.
+ */
+unsigned long
+ucs2_as_utf8(u8 *dest, const ucs2_char_t *src, unsigned long maxlength)
+{
+	unsigned int i;
+	unsigned long j = 0;
+	unsigned long limit = ucs2_strnlen(src, maxlength);
+
+	for (i = 0; maxlength && i < limit; i++) {
+		u16 c = src[i];
+
+		if (c >= 0x800) {
+			if (maxlength < 3)
+				break;
+			maxlength -= 3;
+			dest[j++] = 0xe0 | (c & 0xf000) >> 12;
+			dest[j++] = 0x80 | (c & 0x0fc0) >> 6;
+			dest[j++] = 0x80 | (c & 0x003f);
+		} else if (c >= 0x80) {
+			if (maxlength < 2)
+				break;
+			maxlength -= 2;
+			dest[j++] = 0xc0 | (c & 0x7c0) >> 6;
+			dest[j++] = 0x80 | (c & 0x03f);
+		} else {
+			maxlength -= 1;
+			dest[j++] = c & 0x7f;
+		}
+	}
+	if (maxlength)
+		dest[j] = '\0';
+	return j;
+}
+EXPORT_SYMBOL(ucs2_as_utf8);
--- zfcpdump-kernel-4.4.orig/mm/Kconfig
+++ zfcpdump-kernel-4.4/mm/Kconfig
@@ -651,8 +651,6 @@ config IDLE_PAGE_TRACKING
 
 config ZONE_DEVICE
 	bool "Device memory (pmem, etc...) hotplug support" if EXPERT
-	default !ZONE_DMA
-	depends on !ZONE_DMA
 	depends on MEMORY_HOTPLUG
 	depends on MEMORY_HOTREMOVE
 	depends on X86_64 #arch_add_memory() comprehends device memory
--- zfcpdump-kernel-4.4.orig/mm/Makefile
+++ zfcpdump-kernel-4.4/mm/Makefile
@@ -21,7 +21,7 @@ obj-y			:= filemap.o mempool.o oom_kill.
 			   mm_init.o mmu_context.o percpu.o slab_common.o \
 			   compaction.o vmacache.o \
 			   interval_tree.o list_lru.o workingset.o \
-			   debug.o $(mmu-y)
+			   prfile.o debug.o $(mmu-y)
 
 obj-y += init-mm.o
 
--- zfcpdump-kernel-4.4.orig/mm/backing-dev.c
+++ zfcpdump-kernel-4.4/mm/backing-dev.c
@@ -825,6 +825,20 @@ int bdi_register_dev(struct backing_dev_
 }
 EXPORT_SYMBOL(bdi_register_dev);
 
+int bdi_register_owner(struct backing_dev_info *bdi, struct device *owner)
+{
+	int rc;
+
+	rc = bdi_register(bdi, NULL, "%u:%u", MAJOR(owner->devt),
+			MINOR(owner->devt));
+	if (rc)
+		return rc;
+	bdi->owner = owner;
+	get_device(owner);
+	return 0;
+}
+EXPORT_SYMBOL(bdi_register_owner);
+
 /*
  * Remove bdi from bdi_list, and ensure that it is no longer visible
  */
@@ -849,6 +863,11 @@ void bdi_unregister(struct backing_dev_i
 		device_unregister(bdi->dev);
 		bdi->dev = NULL;
 	}
+
+	if (bdi->owner) {
+		put_device(bdi->owner);
+		bdi->owner = NULL;
+	}
 }
 
 void bdi_exit(struct backing_dev_info *bdi)
@@ -989,7 +1008,7 @@ long wait_iff_congested(struct zone *zon
 		 * here rather than calling cond_resched().
 		 */
 		if (current->flags & PF_WQ_WORKER)
-			schedule_timeout(1);
+			schedule_timeout_uninterruptible(1);
 		else
 			cond_resched();
 
--- zfcpdump-kernel-4.4.orig/mm/balloon_compaction.c
+++ zfcpdump-kernel-4.4/mm/balloon_compaction.c
@@ -61,6 +61,7 @@ struct page *balloon_page_dequeue(struct
 	bool dequeued_page;
 
 	dequeued_page = false;
+	spin_lock_irqsave(&b_dev_info->pages_lock, flags);
 	list_for_each_entry_safe(page, tmp, &b_dev_info->pages, lru) {
 		/*
 		 * Block others from accessing the 'page' while we get around
@@ -75,15 +76,14 @@ struct page *balloon_page_dequeue(struct
 				continue;
 			}
 #endif
-			spin_lock_irqsave(&b_dev_info->pages_lock, flags);
 			balloon_page_delete(page);
 			__count_vm_event(BALLOON_DEFLATE);
-			spin_unlock_irqrestore(&b_dev_info->pages_lock, flags);
 			unlock_page(page);
 			dequeued_page = true;
 			break;
 		}
 	}
+	spin_unlock_irqrestore(&b_dev_info->pages_lock, flags);
 
 	if (!dequeued_page) {
 		/*
--- zfcpdump-kernel-4.4.orig/mm/compaction.c
+++ zfcpdump-kernel-4.4/mm/compaction.c
@@ -475,25 +475,23 @@ static unsigned long isolate_freepages_b
 
 		/* Found a free page, break it into order-0 pages */
 		isolated = split_free_page(page);
+		if (!isolated)
+			break;
+
 		total_isolated += isolated;
+		cc->nr_freepages += isolated;
 		for (i = 0; i < isolated; i++) {
 			list_add(&page->lru, freelist);
 			page++;
 		}
-
-		/* If a page was split, advance to the end of it */
-		if (isolated) {
-			cc->nr_freepages += isolated;
-			if (!strict &&
-				cc->nr_migratepages <= cc->nr_freepages) {
-				blockpfn += isolated;
-				break;
-			}
-
-			blockpfn += isolated - 1;
-			cursor += isolated - 1;
-			continue;
+		if (!strict && cc->nr_migratepages <= cc->nr_freepages) {
+			blockpfn += isolated;
+			break;
 		}
+		/* Advance to the end of split page */
+		blockpfn += isolated - 1;
+		cursor += isolated - 1;
+		continue;
 
 isolate_fail:
 		if (strict)
@@ -503,6 +501,9 @@ isolate_fail:
 
 	}
 
+	if (locked)
+		spin_unlock_irqrestore(&cc->zone->lock, flags);
+
 	/*
 	 * There is a tiny chance that we have read bogus compound_order(),
 	 * so be careful to not go outside of the pageblock.
@@ -524,9 +525,6 @@ isolate_fail:
 	if (strict && blockpfn < end_pfn)
 		total_isolated = 0;
 
-	if (locked)
-		spin_unlock_irqrestore(&cc->zone->lock, flags);
-
 	/* Update the pageblock-skip if the whole pageblock was scanned */
 	if (blockpfn == end_pfn)
 		update_pageblock_skip(cc, valid_page, total_isolated, false);
@@ -880,16 +878,8 @@ isolate_migratepages_range(struct compac
 		pfn = isolate_migratepages_block(cc, pfn, block_end_pfn,
 							ISOLATE_UNEVICTABLE);
 
-		/*
-		 * In case of fatal failure, release everything that might
-		 * have been isolated in the previous iteration, and signal
-		 * the failure back to caller.
-		 */
-		if (!pfn) {
-			putback_movable_pages(&cc->migratepages);
-			cc->nr_migratepages = 0;
+		if (!pfn)
 			break;
-		}
 
 		if (cc->nr_migratepages == COMPACT_CLUSTER_MAX)
 			break;
@@ -974,7 +964,6 @@ static void isolate_freepages(struct com
 				block_end_pfn = block_start_pfn,
 				block_start_pfn -= pageblock_nr_pages,
 				isolate_start_pfn = block_start_pfn) {
-
 		/*
 		 * This can iterate a massively long zone without finding any
 		 * suitable migration targets, so periodically check if we need
@@ -998,32 +987,30 @@ static void isolate_freepages(struct com
 			continue;
 
 		/* Found a block suitable for isolating free pages from. */
-		isolate_freepages_block(cc, &isolate_start_pfn,
-					block_end_pfn, freelist, false);
+		isolate_freepages_block(cc, &isolate_start_pfn, block_end_pfn,
+					freelist, false);
 
 		/*
-		 * If we isolated enough freepages, or aborted due to async
-		 * compaction being contended, terminate the loop.
-		 * Remember where the free scanner should restart next time,
-		 * which is where isolate_freepages_block() left off.
-		 * But if it scanned the whole pageblock, isolate_start_pfn
-		 * now points at block_end_pfn, which is the start of the next
-		 * pageblock.
-		 * In that case we will however want to restart at the start
-		 * of the previous pageblock.
+		 * If we isolated enough freepages, or aborted due to lock
+		 * contention, terminate.
 		 */
 		if ((cc->nr_freepages >= cc->nr_migratepages)
 							|| cc->contended) {
-			if (isolate_start_pfn >= block_end_pfn)
+			if (isolate_start_pfn >= block_end_pfn) {
+				/*
+				 * Restart at previous pageblock if more
+				 * freepages can be isolated next time.
+				 */
 				isolate_start_pfn =
 					block_start_pfn - pageblock_nr_pages;
+			}
 			break;
-		} else {
+		} else if (isolate_start_pfn < block_end_pfn) {
 			/*
-			 * isolate_freepages_block() should not terminate
-			 * prematurely unless contended, or isolated enough
+			 * If isolation failed early, do not continue
+			 * needlessly.
 			 */
-			VM_BUG_ON(isolate_start_pfn < block_end_pfn);
+			break;
 		}
 	}
 
--- zfcpdump-kernel-4.4.orig/mm/filemap.c
+++ zfcpdump-kernel-4.4/mm/filemap.c
@@ -2128,7 +2128,7 @@ int filemap_page_mkwrite(struct vm_area_
 	int ret = VM_FAULT_LOCKED;
 
 	sb_start_pagefault(inode->i_sb);
-	file_update_time(vma->vm_file);
+	vma_file_update_time(vma);
 	lock_page(page);
 	if (page->mapping != inode->i_mapping) {
 		unlock_page(page);
--- zfcpdump-kernel-4.4.orig/mm/gup.c
+++ zfcpdump-kernel-4.4/mm/gup.c
@@ -58,6 +58,16 @@ static int follow_pfn_pte(struct vm_area
 	return -EEXIST;
 }
 
+/*
+ * FOLL_FORCE can write to even unwritable pte's, but only
+ * after we've gone through a COW cycle and they are dirty.
+ */
+static inline bool can_follow_write_pte(pte_t pte, unsigned int flags)
+{
+	return pte_write(pte) ||
+		((flags & FOLL_FORCE) && (flags & FOLL_COW) && pte_dirty(pte));
+}
+
 static struct page *follow_page_pte(struct vm_area_struct *vma,
 		unsigned long address, pmd_t *pmd, unsigned int flags)
 {
@@ -92,7 +102,7 @@ retry:
 	}
 	if ((flags & FOLL_NUMA) && pte_protnone(pte))
 		goto no_page;
-	if ((flags & FOLL_WRITE) && !pte_write(pte)) {
+	if ((flags & FOLL_WRITE) && !can_follow_write_pte(pte, flags)) {
 		pte_unmap_unlock(ptep, ptl);
 		return NULL;
 	}
@@ -352,7 +362,7 @@ static int faultin_page(struct task_stru
 	 * reCOWed by userspace write).
 	 */
 	if ((ret & VM_FAULT_WRITE) && !(vma->vm_flags & VM_WRITE))
-		*flags &= ~FOLL_WRITE;
+	        *flags |= FOLL_COW;
 	return 0;
 }
 
--- zfcpdump-kernel-4.4.orig/mm/huge_memory.c
+++ zfcpdump-kernel-4.4/mm/huge_memory.c
@@ -2134,10 +2134,9 @@ int khugepaged_enter_vma_merge(struct vm
 		 * page fault if needed.
 		 */
 		return 0;
-	if (vma->vm_ops)
+	if (vma->vm_ops || (vm_flags & VM_NO_THP))
 		/* khugepaged not yet working on file or special mappings */
 		return 0;
-	VM_BUG_ON_VMA(vm_flags & VM_NO_THP, vma);
 	hstart = (vma->vm_start + ~HPAGE_PMD_MASK) & HPAGE_PMD_MASK;
 	hend = vma->vm_end & HPAGE_PMD_MASK;
 	if (hstart < hend)
@@ -2498,8 +2497,7 @@ static bool hugepage_vma_check(struct vm
 		return false;
 	if (is_vma_temporary_stack(vma))
 		return false;
-	VM_BUG_ON_VMA(vma->vm_flags & VM_NO_THP, vma);
-	return true;
+	return !(vma->vm_flags & VM_NO_THP);
 }
 
 static void collapse_huge_page(struct mm_struct *mm,
--- zfcpdump-kernel-4.4.orig/mm/hugetlb.c
+++ zfcpdump-kernel-4.4/mm/hugetlb.c
@@ -2170,6 +2170,10 @@ static unsigned long set_max_huge_pages(
 		 * and reducing the surplus.
 		 */
 		spin_unlock(&hugetlb_lock);
+
+		/* yield cpu to avoid soft lockup */
+		cond_resched();
+
 		if (hstate_is_gigantic(h))
 			ret = alloc_fresh_gigantic_page(h, nodes_allowed);
 		else
@@ -4209,7 +4213,6 @@ pte_t *huge_pmd_share(struct mm_struct *
 		if (saddr) {
 			spte = huge_pte_offset(svma->vm_mm, saddr);
 			if (spte) {
-				mm_inc_nr_pmds(mm);
 				get_page(virt_to_page(spte));
 				break;
 			}
@@ -4224,9 +4227,9 @@ pte_t *huge_pmd_share(struct mm_struct *
 	if (pud_none(*pud)) {
 		pud_populate(mm, pud,
 				(pmd_t *)((unsigned long)spte & PAGE_MASK));
+		mm_inc_nr_pmds(mm);
 	} else {
 		put_page(virt_to_page(spte));
-		mm_inc_nr_pmds(mm);
 	}
 	spin_unlock(ptl);
 out:
--- zfcpdump-kernel-4.4.orig/mm/internal.h
+++ zfcpdump-kernel-4.4/mm/internal.h
@@ -22,7 +22,8 @@
  */
 #define GFP_RECLAIM_MASK (__GFP_RECLAIM|__GFP_HIGH|__GFP_IO|__GFP_FS|\
 			__GFP_NOWARN|__GFP_REPEAT|__GFP_NOFAIL|\
-			__GFP_NORETRY|__GFP_MEMALLOC|__GFP_NOMEMALLOC)
+			__GFP_NORETRY|__GFP_MEMALLOC|__GFP_NOMEMALLOC|\
+			__GFP_ATOMIC)
 
 /* The GFP flags allowed during early boot */
 #define GFP_BOOT_MASK (__GFP_BITS_MASK & ~(__GFP_RECLAIM|__GFP_IO|__GFP_FS))
--- zfcpdump-kernel-4.4.orig/mm/ksm.c
+++ zfcpdump-kernel-4.4/mm/ksm.c
@@ -283,7 +283,8 @@ static inline struct rmap_item *alloc_rm
 {
 	struct rmap_item *rmap_item;
 
-	rmap_item = kmem_cache_zalloc(rmap_item_cache, GFP_KERNEL);
+	rmap_item = kmem_cache_zalloc(rmap_item_cache, GFP_KERNEL |
+						__GFP_NORETRY | __GFP_NOWARN);
 	if (rmap_item)
 		ksm_rmap_items++;
 	return rmap_item;
--- zfcpdump-kernel-4.4.orig/mm/memcontrol.c
+++ zfcpdump-kernel-4.4/mm/memcontrol.c
@@ -196,6 +196,7 @@ static void mem_cgroup_oom_notify(struct
 /* "mc" and its members are protected by cgroup_mutex */
 static struct move_charge_struct {
 	spinlock_t	  lock; /* for from, to */
+	struct mm_struct  *mm;
 	struct mem_cgroup *from;
 	struct mem_cgroup *to;
 	unsigned long flags;
@@ -271,21 +272,7 @@ static inline bool mem_cgroup_is_root(st
 
 static inline unsigned short mem_cgroup_id(struct mem_cgroup *memcg)
 {
-	return memcg->css.id;
-}
-
-/*
- * A helper function to get mem_cgroup from ID. must be called under
- * rcu_read_lock().  The caller is responsible for calling
- * css_tryget_online() if the mem_cgroup is used for charging. (dropping
- * refcnt from swap can be called against removed memcg.)
- */
-static inline struct mem_cgroup *mem_cgroup_from_id(unsigned short id)
-{
-	struct cgroup_subsys_state *css;
-
-	css = css_from_id(id, &memory_cgrp_subsys);
-	return mem_cgroup_from_css(css);
+	return memcg->id.id;
 }
 
 /* Writing them here to avoid exposing memcg's inner layout */
@@ -1332,7 +1319,7 @@ static unsigned long mem_cgroup_get_limi
 	return limit;
 }
 
-static void mem_cgroup_out_of_memory(struct mem_cgroup *memcg, gfp_t gfp_mask,
+static bool mem_cgroup_out_of_memory(struct mem_cgroup *memcg, gfp_t gfp_mask,
 				     int order)
 {
 	struct oom_control oc = {
@@ -1410,6 +1397,7 @@ static void mem_cgroup_out_of_memory(str
 	}
 unlock:
 	mutex_unlock(&oom_lock);
+	return chosen;
 }
 
 #if MAX_NUMNODES > 1
@@ -3522,16 +3510,17 @@ static void __mem_cgroup_usage_unregiste
 swap_buffers:
 	/* Swap primary and spare array */
 	thresholds->spare = thresholds->primary;
-	/* If all events are unregistered, free the spare array */
-	if (!new) {
-		kfree(thresholds->spare);
-		thresholds->spare = NULL;
-	}
 
 	rcu_assign_pointer(thresholds->primary, new);
 
 	/* To be sure that nobody uses thresholds */
 	synchronize_rcu();
+
+	/* If all events are unregistered, free the spare array */
+	if (!new) {
+		kfree(thresholds->spare);
+		thresholds->spare = NULL;
+	}
 unlock:
 	mutex_unlock(&memcg->thresholds_lock);
 }
@@ -3658,6 +3647,7 @@ static void memcg_deactivate_kmem(struct
 	 * ordering is imposed by list_lru_node->lock taken by
 	 * memcg_drain_all_list_lrus().
 	 */
+	rcu_read_lock(); /* can be called from css_free w/o cgroup_mutex */
 	css_for_each_descendant_pre(css, &memcg->css) {
 		child = mem_cgroup_from_css(css);
 		BUG_ON(child->kmemcg_id != kmemcg_id);
@@ -3665,6 +3655,8 @@ static void memcg_deactivate_kmem(struct
 		if (!memcg->use_hierarchy)
 			break;
 	}
+	rcu_read_unlock();
+
 	memcg_drain_all_list_lrus(kmemcg_id, parent->kmemcg_id);
 
 	memcg_free_cache_id(kmemcg_id);
@@ -4118,6 +4110,88 @@ static struct cftype mem_cgroup_legacy_f
 	{ },	/* terminate */
 };
 
+/*
+ * Private memory cgroup IDR
+ *
+ * Swap-out records and page cache shadow entries need to store memcg
+ * references in constrained space, so we maintain an ID space that is
+ * limited to 16 bit (MEM_CGROUP_ID_MAX), limiting the total number of
+ * memory-controlled cgroups to 64k.
+ *
+ * However, there usually are many references to the oflline CSS after
+ * the cgroup has been destroyed, such as page cache or reclaimable
+ * slab objects, that don't need to hang on to the ID. We want to keep
+ * those dead CSS from occupying IDs, or we might quickly exhaust the
+ * relatively small ID space and prevent the creation of new cgroups
+ * even when there are much fewer than 64k cgroups - possibly none.
+ *
+ * Maintain a private 16-bit ID space for memcg, and allow the ID to
+ * be freed and recycled when it's no longer needed, which is usually
+ * when the CSS is offlined.
+ *
+ * The only exception to that are records of swapped out tmpfs/shmem
+ * pages that need to be attributed to live ancestors on swapin. But
+ * those references are manageable from userspace.
+ */
+
+static DEFINE_IDR(mem_cgroup_idr);
+
+static void mem_cgroup_id_get_many(struct mem_cgroup *memcg, unsigned int n)
+{
+	atomic_add(n, &memcg->id.ref);
+}
+
+static struct mem_cgroup *mem_cgroup_id_get_online(struct mem_cgroup *memcg)
+{
+	while (!atomic_inc_not_zero(&memcg->id.ref)) {
+		/*
+		 * The root cgroup cannot be destroyed, so it's refcount must
+		 * always be >= 1.
+		 */
+		if (WARN_ON_ONCE(memcg == root_mem_cgroup)) {
+			VM_BUG_ON(1);
+			break;
+		}
+		memcg = parent_mem_cgroup(memcg);
+		if (!memcg)
+			memcg = root_mem_cgroup;
+	}
+	return memcg;
+}
+
+static void mem_cgroup_id_put_many(struct mem_cgroup *memcg, unsigned int n)
+{
+	if (atomic_sub_and_test(n, &memcg->id.ref)) {
+		idr_remove(&mem_cgroup_idr, memcg->id.id);
+		memcg->id.id = 0;
+
+		/* Memcg ID pins CSS */
+		css_put(&memcg->css);
+	}
+}
+
+static inline void mem_cgroup_id_get(struct mem_cgroup *memcg)
+{
+	mem_cgroup_id_get_many(memcg, 1);
+}
+
+static inline void mem_cgroup_id_put(struct mem_cgroup *memcg)
+{
+	mem_cgroup_id_put_many(memcg, 1);
+}
+
+/**
+ * mem_cgroup_from_id - look up a memcg from a memcg id
+ * @id: the memcg id to look up
+ *
+ * Caller must hold rcu_read_lock().
+ */
+struct mem_cgroup *mem_cgroup_from_id(unsigned short id)
+{
+	WARN_ON_ONCE(!rcu_read_lock_held());
+	return idr_find(&mem_cgroup_idr, id);
+}
+
 static int alloc_mem_cgroup_per_zone_info(struct mem_cgroup *memcg, int node)
 {
 	struct mem_cgroup_per_node *pn;
@@ -4172,6 +4246,12 @@ static struct mem_cgroup *mem_cgroup_all
 	if (memcg_wb_domain_init(memcg, GFP_KERNEL))
 		goto out_free_stat;
 
+	memcg->id.id = idr_alloc(&mem_cgroup_idr, NULL,
+				 1, MEM_CGROUP_ID_MAX,
+				 GFP_KERNEL);
+	if (memcg->id.id < 0)
+		goto out_free_stat;
+
 	return memcg;
 
 out_free_stat:
@@ -4257,9 +4337,11 @@ mem_cgroup_css_alloc(struct cgroup_subsy
 #ifdef CONFIG_CGROUP_WRITEBACK
 	INIT_LIST_HEAD(&memcg->cgwb_list);
 #endif
+	idr_replace(&mem_cgroup_idr, memcg, memcg->id.id);
 	return &memcg->css;
 
 free_out:
+	idr_remove(&mem_cgroup_idr, memcg->id.id);
 	__mem_cgroup_free(memcg);
 	return ERR_PTR(error);
 }
@@ -4271,8 +4353,9 @@ mem_cgroup_css_online(struct cgroup_subs
 	struct mem_cgroup *parent = mem_cgroup_from_css(css->parent);
 	int ret;
 
-	if (css->id > MEM_CGROUP_ID_MAX)
-		return -ENOSPC;
+	/* Online state pins memcg ID, memcg ID pins CSS */
+	mem_cgroup_id_get(mem_cgroup_from_css(css));
+	css_get(css);
 
 	if (!parent)
 		return 0;
@@ -4346,6 +4429,8 @@ static void mem_cgroup_css_offline(struc
 	memcg_deactivate_kmem(memcg);
 
 	wb_memcg_offline(memcg);
+
+	mem_cgroup_id_put(memcg);
 }
 
 static void mem_cgroup_css_released(struct cgroup_subsys_state *css)
@@ -4779,6 +4864,8 @@ static void __mem_cgroup_clear_mc(void)
 		if (!mem_cgroup_is_root(mc.from))
 			page_counter_uncharge(&mc.from->memsw, mc.moved_swap);
 
+		mem_cgroup_id_put_many(mc.from, mc.moved_swap);
+
 		/*
 		 * we charged both to->memory and to->memsw, so we
 		 * should uncharge to->memory.
@@ -4786,9 +4873,9 @@ static void __mem_cgroup_clear_mc(void)
 		if (!mem_cgroup_is_root(mc.to))
 			page_counter_uncharge(&mc.to->memory, mc.moved_swap);
 
-		css_put_many(&mc.from->css, mc.moved_swap);
+		mem_cgroup_id_get_many(mc.to, mc.moved_swap);
+		css_put_many(&mc.to->css, mc.moved_swap);
 
-		/* we've already done css_get(mc.to) */
 		mc.moved_swap = 0;
 	}
 	memcg_oom_recover(from);
@@ -4798,6 +4885,8 @@ static void __mem_cgroup_clear_mc(void)
 
 static void mem_cgroup_clear_mc(void)
 {
+	struct mm_struct *mm = mc.mm;
+
 	/*
 	 * we must clear moving_task before waking up waiters at the end of
 	 * task migration.
@@ -4807,7 +4896,10 @@ static void mem_cgroup_clear_mc(void)
 	spin_lock(&mc.lock);
 	mc.from = NULL;
 	mc.to = NULL;
+	mc.mm = NULL;
 	spin_unlock(&mc.lock);
+
+	mmput(mm);
 }
 
 static int mem_cgroup_can_attach(struct cgroup_taskset *tset)
@@ -4864,6 +4956,7 @@ static int mem_cgroup_can_attach(struct
 		VM_BUG_ON(mc.moved_swap);
 
 		spin_lock(&mc.lock);
+		mc.mm = mm;
 		mc.from = from;
 		mc.to = memcg;
 		mc.flags = move_flags;
@@ -4873,8 +4966,9 @@ static int mem_cgroup_can_attach(struct
 		ret = mem_cgroup_precharge_mc(mm);
 		if (ret)
 			mem_cgroup_clear_mc();
+	} else {
+		mmput(mm);
 	}
-	mmput(mm);
 	return ret;
 }
 
@@ -4983,11 +5077,11 @@ put:			/* get_mctgt_type() gets the page
 	return ret;
 }
 
-static void mem_cgroup_move_charge(struct mm_struct *mm)
+static void mem_cgroup_move_charge(void)
 {
 	struct mm_walk mem_cgroup_move_charge_walk = {
 		.pmd_entry = mem_cgroup_move_charge_pte_range,
-		.mm = mm,
+		.mm = mc.mm,
 	};
 
 	lru_add_drain_all();
@@ -4999,7 +5093,7 @@ static void mem_cgroup_move_charge(struc
 	atomic_inc(&mc.from->moving_account);
 	synchronize_rcu();
 retry:
-	if (unlikely(!down_read_trylock(&mm->mmap_sem))) {
+	if (unlikely(!down_read_trylock(&mc.mm->mmap_sem))) {
 		/*
 		 * Someone who are holding the mmap_sem might be waiting in
 		 * waitq. So we cancel all extra charges, wake up all waiters,
@@ -5016,23 +5110,16 @@ retry:
 	 * additional charge, the page walk just aborts.
 	 */
 	walk_page_range(0, ~0UL, &mem_cgroup_move_charge_walk);
-	up_read(&mm->mmap_sem);
+	up_read(&mc.mm->mmap_sem);
 	atomic_dec(&mc.from->moving_account);
 }
 
-static void mem_cgroup_move_task(struct cgroup_taskset *tset)
+static void mem_cgroup_move_task(void)
 {
-	struct cgroup_subsys_state *css;
-	struct task_struct *p = cgroup_taskset_first(tset, &css);
-	struct mm_struct *mm = get_task_mm(p);
-
-	if (mm) {
-		if (mc.to)
-			mem_cgroup_move_charge(mm);
-		mmput(mm);
-	}
-	if (mc.to)
+	if (mc.to) {
+		mem_cgroup_move_charge();
 		mem_cgroup_clear_mc();
+	}
 }
 #else	/* !CONFIG_MMU */
 static int mem_cgroup_can_attach(struct cgroup_taskset *tset)
@@ -5042,7 +5129,7 @@ static int mem_cgroup_can_attach(struct
 static void mem_cgroup_cancel_attach(struct cgroup_taskset *tset)
 {
 }
-static void mem_cgroup_move_task(struct cgroup_taskset *tset)
+static void mem_cgroup_move_task(void)
 {
 }
 #endif
@@ -5120,6 +5207,7 @@ static ssize_t memory_high_write(struct
 				 char *buf, size_t nbytes, loff_t off)
 {
 	struct mem_cgroup *memcg = mem_cgroup_from_css(of_css(of));
+	unsigned long nr_pages;
 	unsigned long high;
 	int err;
 
@@ -5130,6 +5218,11 @@ static ssize_t memory_high_write(struct
 
 	memcg->high = high;
 
+	nr_pages = page_counter_read(&memcg->memory);
+	if (nr_pages > high)
+		try_to_free_mem_cgroup_pages(memcg, nr_pages - high,
+					     GFP_KERNEL, true);
+
 	memcg_wb_domain_size_changed(memcg);
 	return nbytes;
 }
@@ -5151,6 +5244,8 @@ static ssize_t memory_max_write(struct k
 				char *buf, size_t nbytes, loff_t off)
 {
 	struct mem_cgroup *memcg = mem_cgroup_from_css(of_css(of));
+	unsigned int nr_reclaims = MEM_CGROUP_RECLAIM_RETRIES;
+	bool drained = false;
 	unsigned long max;
 	int err;
 
@@ -5159,9 +5254,36 @@ static ssize_t memory_max_write(struct k
 	if (err)
 		return err;
 
-	err = mem_cgroup_resize_limit(memcg, max);
-	if (err)
-		return err;
+	xchg(&memcg->memory.limit, max);
+
+	for (;;) {
+		unsigned long nr_pages = page_counter_read(&memcg->memory);
+
+		if (nr_pages <= max)
+			break;
+
+		if (signal_pending(current)) {
+			err = -EINTR;
+			break;
+		}
+
+		if (!drained) {
+			drain_all_stock(memcg);
+			drained = true;
+			continue;
+		}
+
+		if (nr_reclaims) {
+			if (!try_to_free_mem_cgroup_pages(memcg, nr_pages - max,
+							  GFP_KERNEL, true))
+				nr_reclaims--;
+			continue;
+		}
+
+		mem_cgroup_events(memcg, MEMCG_OOM, 1);
+		if (!mem_cgroup_out_of_memory(memcg, GFP_KERNEL, 0))
+			break;
+	}
 
 	memcg_wb_domain_size_changed(memcg);
 	return nbytes;
@@ -5221,7 +5343,7 @@ struct cgroup_subsys memory_cgrp_subsys
 	.css_reset = mem_cgroup_css_reset,
 	.can_attach = mem_cgroup_can_attach,
 	.cancel_attach = mem_cgroup_cancel_attach,
-	.attach = mem_cgroup_move_task,
+	.post_attach = mem_cgroup_move_task,
 	.bind = mem_cgroup_bind,
 	.dfl_cftypes = memory_files,
 	.legacy_cftypes = mem_cgroup_legacy_files,
@@ -5629,7 +5751,7 @@ subsys_initcall(mem_cgroup_init);
  */
 void mem_cgroup_swapout(struct page *page, swp_entry_t entry)
 {
-	struct mem_cgroup *memcg;
+	struct mem_cgroup *memcg, *swap_memcg;
 	unsigned short oldid;
 
 	VM_BUG_ON_PAGE(PageLRU(page), page);
@@ -5644,15 +5766,27 @@ void mem_cgroup_swapout(struct page *pag
 	if (!memcg)
 		return;
 
-	oldid = swap_cgroup_record(entry, mem_cgroup_id(memcg));
+	/*
+	 * In case the memcg owning these pages has been offlined and doesn't
+	 * have an ID allocated to it anymore, charge the closest online
+	 * ancestor for the swap instead and transfer the memory+swap charge.
+	 */
+	swap_memcg = mem_cgroup_id_get_online(memcg);
+	oldid = swap_cgroup_record(entry, mem_cgroup_id(swap_memcg));
 	VM_BUG_ON_PAGE(oldid, page);
-	mem_cgroup_swap_statistics(memcg, true);
+	mem_cgroup_swap_statistics(swap_memcg, true);
 
 	page->mem_cgroup = NULL;
 
 	if (!mem_cgroup_is_root(memcg))
 		page_counter_uncharge(&memcg->memory, 1);
 
+	if (memcg != swap_memcg) {
+		if (!mem_cgroup_is_root(swap_memcg))
+			page_counter_charge(&swap_memcg->memsw, 1);
+		page_counter_uncharge(&memcg->memsw, 1);
+	}
+
 	/*
 	 * Interrupts should be disabled here because the caller holds the
 	 * mapping->tree_lock lock which is taken with interrupts-off. It is
@@ -5662,6 +5796,9 @@ void mem_cgroup_swapout(struct page *pag
 	VM_BUG_ON(!irqs_disabled());
 	mem_cgroup_charge_statistics(memcg, page, -1);
 	memcg_check_events(memcg, page);
+
+	if (!mem_cgroup_is_root(memcg))
+		css_put(&memcg->css);
 }
 
 /**
@@ -5685,7 +5822,7 @@ void mem_cgroup_uncharge_swap(swp_entry_
 		if (!mem_cgroup_is_root(memcg))
 			page_counter_uncharge(&memcg->memsw, 1);
 		mem_cgroup_swap_statistics(memcg, false);
-		css_put(&memcg->css);
+		mem_cgroup_id_put(memcg);
 	}
 	rcu_read_unlock();
 }
--- zfcpdump-kernel-4.4.orig/mm/memory-failure.c
+++ zfcpdump-kernel-4.4/mm/memory-failure.c
@@ -1572,7 +1572,7 @@ static int get_any_page(struct page *pag
 		 * Did it turn free?
 		 */
 		ret = __get_any_page(page, pfn, 0);
-		if (!PageLRU(page)) {
+		if (ret == 1 && !PageLRU(page)) {
 			/* Drop page reference which is from __get_any_page() */
 			put_hwpoison_page(page);
 			pr_info("soft_offline: %#lx: unknown non LRU page type %lx\n",
--- zfcpdump-kernel-4.4.orig/mm/memory.c
+++ zfcpdump-kernel-4.4/mm/memory.c
@@ -797,6 +797,46 @@ out:
 	return pfn_to_page(pfn);
 }
 
+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
+struct page *vm_normal_page_pmd(struct vm_area_struct *vma, unsigned long addr,
+				pmd_t pmd)
+{
+	unsigned long pfn = pmd_pfn(pmd);
+
+	/*
+	 * There is no pmd_special() but there may be special pmds, e.g.
+	 * in a direct-access (dax) mapping, so let's just replicate the
+	 * !HAVE_PTE_SPECIAL case from vm_normal_page() here.
+	 */
+	if (unlikely(vma->vm_flags & (VM_PFNMAP|VM_MIXEDMAP))) {
+		if (vma->vm_flags & VM_MIXEDMAP) {
+			if (!pfn_valid(pfn))
+				return NULL;
+			goto out;
+		} else {
+			unsigned long off;
+			off = (addr - vma->vm_start) >> PAGE_SHIFT;
+			if (pfn == vma->vm_pgoff + off)
+				return NULL;
+			if (!is_cow_mapping(vma->vm_flags))
+				return NULL;
+		}
+	}
+
+	if (is_zero_pfn(pfn))
+		return NULL;
+	if (unlikely(pfn > highest_memmap_pfn))
+		return NULL;
+
+	/*
+	 * NOTE! We still have PageReserved() pages in the page tables.
+	 * eg. VDSO mappings can cause them to exist.
+	 */
+out:
+	return pfn_to_page(pfn);
+}
+#endif
+
 /*
  * copy one vm_area from one task to the other. Assumes the page tables
  * already present in the new task to be cleared in the whole range
@@ -2035,7 +2075,7 @@ static inline int wp_page_reuse(struct m
 		}
 
 		if (!page_mkwrite)
-			file_update_time(vma->vm_file);
+			vma_file_update_time(vma);
 	}
 
 	return VM_FAULT_WRITE;
@@ -3399,8 +3439,18 @@ static int __handle_mm_fault(struct mm_s
 	if (unlikely(pmd_none(*pmd)) &&
 	    unlikely(__pte_alloc(mm, vma, pmd, address)))
 		return VM_FAULT_OOM;
-	/* if an huge pmd materialized from under us just retry later */
-	if (unlikely(pmd_trans_huge(*pmd)))
+	/*
+	 * If a huge pmd materialized under us just retry later.  Use
+	 * pmd_trans_unstable() instead of pmd_trans_huge() to ensure the pmd
+	 * didn't become pmd_trans_huge under us and then back to pmd_none, as
+	 * a result of MADV_DONTNEED running immediately after a huge pmd fault
+	 * in a different thread of this mm, in turn leading to a misleading
+	 * pmd_trans_huge() retval.  All we have to ensure is that it is a
+	 * regular pmd that we can walk with pte_offset_map() and we can do that
+	 * through an atomic read in C, which is what pmd_trans_unstable()
+	 * provides.
+	 */
+	if (unlikely(pmd_trans_unstable(pmd)))
 		return 0;
 	/*
 	 * A regular pmd is established and it can't morph into a huge pmd
--- zfcpdump-kernel-4.4.orig/mm/migrate.c
+++ zfcpdump-kernel-4.4/mm/migrate.c
@@ -429,6 +429,7 @@ int migrate_page_move_mapping(struct add
 
 	return MIGRATEPAGE_SUCCESS;
 }
+EXPORT_SYMBOL(migrate_page_move_mapping);
 
 /*
  * The expected number of remaining references is the same as that
@@ -579,6 +580,7 @@ void migrate_page_copy(struct page *newp
 	if (PageWriteback(newpage))
 		end_page_writeback(newpage);
 }
+EXPORT_SYMBOL(migrate_page_copy);
 
 /************************************************************
  *                    Migration functions
@@ -963,7 +965,13 @@ out:
 		dec_zone_page_state(page, NR_ISOLATED_ANON +
 				page_is_file_cache(page));
 		/* Soft-offlined page shouldn't go through lru cache list */
-		if (reason == MR_MEMORY_FAILURE) {
+		if (reason == MR_MEMORY_FAILURE && rc == MIGRATEPAGE_SUCCESS) {
+			/*
+			 * With this release, we free successfully migrated
+			 * page and set PG_HWPoison on just freed page
+			 * intentionally. Although it's rather weird, it's how
+			 * HWPoison flag works at the moment.
+			 */
 			put_page(page);
 			if (!test_set_page_hwpoison(page))
 				num_poisoned_pages_inc();
@@ -1578,7 +1586,7 @@ static struct page *alloc_misplaced_dst_
 					 (GFP_HIGHUSER_MOVABLE |
 					  __GFP_THISNODE | __GFP_NOMEMALLOC |
 					  __GFP_NORETRY | __GFP_NOWARN) &
-					 ~(__GFP_IO | __GFP_FS), 0);
+					 ~__GFP_RECLAIM, 0);
 
 	return newpage;
 }
--- zfcpdump-kernel-4.4.orig/mm/mlock.c
+++ zfcpdump-kernel-4.4/mm/mlock.c
@@ -172,7 +172,7 @@ static void __munlock_isolation_failed(s
  */
 unsigned int munlock_vma_page(struct page *page)
 {
-	unsigned int nr_pages;
+	int nr_pages;
 	struct zone *zone = page_zone(page);
 
 	/* For try_to_munlock() and to serialize with page migration */
--- zfcpdump-kernel-4.4.orig/mm/mmap.c
+++ zfcpdump-kernel-4.4/mm/mmap.c
@@ -275,7 +275,7 @@ static struct vm_area_struct *remove_vma
 	if (vma->vm_ops && vma->vm_ops->close)
 		vma->vm_ops->close(vma);
 	if (vma->vm_file)
-		fput(vma->vm_file);
+		vma_fput(vma);
 	mpol_put(vma_policy(vma));
 	kmem_cache_free(vm_area_cachep, vma);
 	return next;
@@ -441,12 +441,16 @@ static void validate_mm(struct mm_struct
 	struct vm_area_struct *vma = mm->mmap;
 
 	while (vma) {
+		struct anon_vma *anon_vma = vma->anon_vma;
 		struct anon_vma_chain *avc;
 
-		vma_lock_anon_vma(vma);
-		list_for_each_entry(avc, &vma->anon_vma_chain, same_vma)
-			anon_vma_interval_tree_verify(avc);
-		vma_unlock_anon_vma(vma);
+		if (anon_vma) {
+			anon_vma_lock_read(anon_vma);
+			list_for_each_entry(avc, &vma->anon_vma_chain, same_vma)
+				anon_vma_interval_tree_verify(avc);
+			anon_vma_unlock_read(anon_vma);
+		}
+
 		highest_address = vma->vm_end;
 		vma = vma->vm_next;
 		i++;
@@ -887,7 +891,7 @@ again:			remove_next = 1 + (end > next->
 	if (remove_next) {
 		if (file) {
 			uprobe_munmap(next, next->vm_start, next->vm_end);
-			fput(file);
+			vma_fput(vma);
 		}
 		if (next->anon_vma)
 			anon_vma_merge(vma, next);
@@ -1681,8 +1685,8 @@ out:
 	return addr;
 
 unmap_and_free_vma:
+	vma_fput(vma);
 	vma->vm_file = NULL;
-	fput(file);
 
 	/* Undo any partial mapping done by a device driver. */
 	unmap_region(mm, vma, prev, vma->vm_start, vma->vm_end);
@@ -2147,32 +2151,27 @@ static int acct_stack_growth(struct vm_a
 int expand_upwards(struct vm_area_struct *vma, unsigned long address)
 {
 	struct mm_struct *mm = vma->vm_mm;
-	int error;
+	int error = 0;
 
 	if (!(vma->vm_flags & VM_GROWSUP))
 		return -EFAULT;
 
-	/*
-	 * We must make sure the anon_vma is allocated
-	 * so that the anon_vma locking is not a noop.
-	 */
+	/* Guard against wrapping around to address 0. */
+	if (address < PAGE_ALIGN(address+4))
+		address = PAGE_ALIGN(address+4);
+	else
+		return -ENOMEM;
+
+	/* We must make sure the anon_vma is allocated. */
 	if (unlikely(anon_vma_prepare(vma)))
 		return -ENOMEM;
-	vma_lock_anon_vma(vma);
 
 	/*
 	 * vma->vm_start/vm_end cannot change under us because the caller
 	 * is required to hold the mmap_sem in read mode.  We need the
 	 * anon_vma lock to serialize against concurrent expand_stacks.
-	 * Also guard against wrapping around to address 0.
 	 */
-	if (address < PAGE_ALIGN(address+4))
-		address = PAGE_ALIGN(address+4);
-	else {
-		vma_unlock_anon_vma(vma);
-		return -ENOMEM;
-	}
-	error = 0;
+	anon_vma_lock_write(vma->anon_vma);
 
 	/* Somebody else might have raced and expanded it already */
 	if (address > vma->vm_end) {
@@ -2190,7 +2189,7 @@ int expand_upwards(struct vm_area_struct
 				 * updates, but we only hold a shared mmap_sem
 				 * lock here, so we need to protect against
 				 * concurrent vma expansions.
-				 * vma_lock_anon_vma() doesn't help here, as
+				 * anon_vma_lock_write() doesn't help here, as
 				 * we don't guarantee that all growable vmas
 				 * in a mm share the same root anon vma.
 				 * So, we reuse mm->page_table_lock to guard
@@ -2214,7 +2213,7 @@ int expand_upwards(struct vm_area_struct
 			}
 		}
 	}
-	vma_unlock_anon_vma(vma);
+	anon_vma_unlock_write(vma->anon_vma);
 	khugepaged_enter_vma_merge(vma, vma->vm_flags);
 	validate_mm(mm);
 	return error;
@@ -2230,25 +2229,21 @@ int expand_downwards(struct vm_area_stru
 	struct mm_struct *mm = vma->vm_mm;
 	int error;
 
-	/*
-	 * We must make sure the anon_vma is allocated
-	 * so that the anon_vma locking is not a noop.
-	 */
-	if (unlikely(anon_vma_prepare(vma)))
-		return -ENOMEM;
-
 	address &= PAGE_MASK;
 	error = security_mmap_addr(address);
 	if (error)
 		return error;
 
-	vma_lock_anon_vma(vma);
+	/* We must make sure the anon_vma is allocated. */
+	if (unlikely(anon_vma_prepare(vma)))
+		return -ENOMEM;
 
 	/*
 	 * vma->vm_start/vm_end cannot change under us because the caller
 	 * is required to hold the mmap_sem in read mode.  We need the
 	 * anon_vma lock to serialize against concurrent expand_stacks.
 	 */
+	anon_vma_lock_write(vma->anon_vma);
 
 	/* Somebody else might have raced and expanded it already */
 	if (address < vma->vm_start) {
@@ -2266,7 +2261,7 @@ int expand_downwards(struct vm_area_stru
 				 * updates, but we only hold a shared mmap_sem
 				 * lock here, so we need to protect against
 				 * concurrent vma expansions.
-				 * vma_lock_anon_vma() doesn't help here, as
+				 * anon_vma_lock_write() doesn't help here, as
 				 * we don't guarantee that all growable vmas
 				 * in a mm share the same root anon vma.
 				 * So, we reuse mm->page_table_lock to guard
@@ -2288,7 +2283,7 @@ int expand_downwards(struct vm_area_stru
 			}
 		}
 	}
-	vma_unlock_anon_vma(vma);
+	anon_vma_unlock_write(vma->anon_vma);
 	khugepaged_enter_vma_merge(vma, vma->vm_flags);
 	validate_mm(mm);
 	return error;
@@ -2488,7 +2483,7 @@ static int __split_vma(struct mm_struct
 		goto out_free_mpol;
 
 	if (new->vm_file)
-		get_file(new->vm_file);
+		vma_get_file(new);
 
 	if (new->vm_ops && new->vm_ops->open)
 		new->vm_ops->open(new);
@@ -2507,7 +2502,7 @@ static int __split_vma(struct mm_struct
 	if (new->vm_ops && new->vm_ops->close)
 		new->vm_ops->close(new);
 	if (new->vm_file)
-		fput(new->vm_file);
+		vma_fput(new);
 	unlink_anon_vmas(new);
  out_free_mpol:
 	mpol_put(vma_policy(new));
@@ -2649,7 +2644,7 @@ SYSCALL_DEFINE5(remap_file_pages, unsign
 	struct vm_area_struct *vma;
 	unsigned long populate = 0;
 	unsigned long ret = -EINVAL;
-	struct file *file;
+	struct file *file, *prfile;
 
 	pr_warn_once("%s (%d) uses deprecated remap_file_pages() syscall. "
 			"See Documentation/vm/remap_file_pages.txt.\n",
@@ -2673,12 +2668,29 @@ SYSCALL_DEFINE5(remap_file_pages, unsign
 	if (!vma || !(vma->vm_flags & VM_SHARED))
 		goto out;
 
-	if (start < vma->vm_start || start + size > vma->vm_end)
+	if (start < vma->vm_start)
 		goto out;
 
-	if (pgoff == linear_page_index(vma, start)) {
-		ret = 0;
-		goto out;
+	if (start + size > vma->vm_end) {
+		struct vm_area_struct *next;
+
+		for (next = vma->vm_next; next; next = next->vm_next) {
+			/* hole between vmas ? */
+			if (next->vm_start != next->vm_prev->vm_end)
+				goto out;
+
+			if (next->vm_file != vma->vm_file)
+				goto out;
+
+			if (next->vm_flags != vma->vm_flags)
+				goto out;
+
+			if (start + size <= next->vm_end)
+				break;
+		}
+
+		if (!next)
+			goto out;
 	}
 
 	prot |= vma->vm_flags & VM_READ ? PROT_READ : 0;
@@ -2688,15 +2700,39 @@ SYSCALL_DEFINE5(remap_file_pages, unsign
 	flags &= MAP_NONBLOCK;
 	flags |= MAP_SHARED | MAP_FIXED | MAP_POPULATE;
 	if (vma->vm_flags & VM_LOCKED) {
+		struct vm_area_struct *tmp;
 		flags |= MAP_LOCKED;
+
 		/* drop PG_Mlocked flag for over-mapped range */
-		munlock_vma_pages_range(vma, start, start + size);
+		for (tmp = vma; tmp->vm_start >= start + size;
+				tmp = tmp->vm_next) {
+			munlock_vma_pages_range(tmp,
+					max(tmp->vm_start, start),
+					min(tmp->vm_end, start + size));
+		}
 	}
 
-	file = get_file(vma->vm_file);
+	vma_get_file(vma);
+	file = vma->vm_file;
+	prfile = vma->vm_prfile;
 	ret = do_mmap_pgoff(vma->vm_file, start, size,
 			prot, flags, pgoff, &populate);
+	if (!IS_ERR_VALUE(ret) && file && prfile) {
+		struct vm_area_struct *new_vma;
+
+		new_vma = find_vma(mm, ret);
+		if (!new_vma->vm_prfile)
+			new_vma->vm_prfile = prfile;
+		if (new_vma != vma)
+			get_file(prfile);
+	}
+	/*
+	 * two fput()s instead of vma_fput(vma),
+	 * coz vma may not be available anymore.
+	 */
 	fput(file);
+	if (prfile)
+		fput(prfile);
 out:
 	up_write(&mm->mmap_sem);
 	if (populate)
@@ -2966,7 +3002,7 @@ struct vm_area_struct *copy_vma(struct v
 		if (anon_vma_clone(new_vma, vma))
 			goto out_free_mempol;
 		if (new_vma->vm_file)
-			get_file(new_vma->vm_file);
+			vma_get_file(new_vma);
 		if (new_vma->vm_ops && new_vma->vm_ops->open)
 			new_vma->vm_ops->open(new_vma);
 		vma_link(mm, new_vma, prev, rb_link, rb_parent);
--- zfcpdump-kernel-4.4.orig/mm/nommu.c
+++ zfcpdump-kernel-4.4/mm/nommu.c
@@ -671,7 +671,7 @@ static void __put_nommu_region(struct vm
 		up_write(&nommu_region_sem);
 
 		if (region->vm_file)
-			fput(region->vm_file);
+			vmr_fput(region);
 
 		/* IO memory and memory shared directly out of the pagecache
 		 * from ramfs/tmpfs mustn't be released here */
@@ -829,7 +829,7 @@ static void delete_vma(struct mm_struct
 	if (vma->vm_ops && vma->vm_ops->close)
 		vma->vm_ops->close(vma);
 	if (vma->vm_file)
-		fput(vma->vm_file);
+		vma_fput(vma);
 	put_nommu_region(vma->vm_region);
 	kmem_cache_free(vm_area_cachep, vma);
 }
@@ -1355,7 +1355,7 @@ unsigned long do_mmap(struct file *file,
 					goto error_just_free;
 				}
 			}
-			fput(region->vm_file);
+			vmr_fput(region);
 			kmem_cache_free(vm_region_jar, region);
 			region = pregion;
 			result = start;
@@ -1430,10 +1430,10 @@ error_just_free:
 	up_write(&nommu_region_sem);
 error:
 	if (region->vm_file)
-		fput(region->vm_file);
+		vmr_fput(region);
 	kmem_cache_free(vm_region_jar, region);
 	if (vma->vm_file)
-		fput(vma->vm_file);
+		vma_fput(vma);
 	kmem_cache_free(vm_area_cachep, vma);
 	return ret;
 
--- zfcpdump-kernel-4.4.orig/mm/page-writeback.c
+++ zfcpdump-kernel-4.4/mm/page-writeback.c
@@ -359,8 +359,9 @@ static void domain_dirty_limits(struct d
 	struct dirty_throttle_control *gdtc = mdtc_gdtc(dtc);
 	unsigned long bytes = vm_dirty_bytes;
 	unsigned long bg_bytes = dirty_background_bytes;
-	unsigned long ratio = vm_dirty_ratio;
-	unsigned long bg_ratio = dirty_background_ratio;
+	/* convert ratios to per-PAGE_SIZE for higher precision */
+	unsigned long ratio = (vm_dirty_ratio * PAGE_SIZE) / 100;
+	unsigned long bg_ratio = (dirty_background_ratio * PAGE_SIZE) / 100;
 	unsigned long thresh;
 	unsigned long bg_thresh;
 	struct task_struct *tsk;
@@ -372,26 +373,28 @@ static void domain_dirty_limits(struct d
 		/*
 		 * The byte settings can't be applied directly to memcg
 		 * domains.  Convert them to ratios by scaling against
-		 * globally available memory.
+		 * globally available memory.  As the ratios are in
+		 * per-PAGE_SIZE, they can be obtained by dividing bytes by
+		 * number of pages.
 		 */
 		if (bytes)
-			ratio = min(DIV_ROUND_UP(bytes, PAGE_SIZE) * 100 /
-				    global_avail, 100UL);
+			ratio = min(DIV_ROUND_UP(bytes, global_avail),
+				    PAGE_SIZE);
 		if (bg_bytes)
-			bg_ratio = min(DIV_ROUND_UP(bg_bytes, PAGE_SIZE) * 100 /
-				       global_avail, 100UL);
+			bg_ratio = min(DIV_ROUND_UP(bg_bytes, global_avail),
+				       PAGE_SIZE);
 		bytes = bg_bytes = 0;
 	}
 
 	if (bytes)
 		thresh = DIV_ROUND_UP(bytes, PAGE_SIZE);
 	else
-		thresh = (ratio * available_memory) / 100;
+		thresh = (ratio * available_memory) / PAGE_SIZE;
 
 	if (bg_bytes)
 		bg_thresh = DIV_ROUND_UP(bg_bytes, PAGE_SIZE);
 	else
-		bg_thresh = (bg_ratio * available_memory) / 100;
+		bg_thresh = (bg_ratio * available_memory) / PAGE_SIZE;
 
 	if (bg_thresh >= thresh)
 		bg_thresh = thresh / 2;
@@ -1899,7 +1902,8 @@ bool wb_over_bg_thresh(struct bdi_writeb
 	if (gdtc->dirty > gdtc->bg_thresh)
 		return true;
 
-	if (wb_stat(wb, WB_RECLAIMABLE) > __wb_calc_thresh(gdtc))
+	if (wb_stat(wb, WB_RECLAIMABLE) >
+	    wb_calc_thresh(gdtc->wb, gdtc->bg_thresh))
 		return true;
 
 	if (mdtc) {
@@ -1913,7 +1917,8 @@ bool wb_over_bg_thresh(struct bdi_writeb
 		if (mdtc->dirty > mdtc->bg_thresh)
 			return true;
 
-		if (wb_stat(wb, WB_RECLAIMABLE) > __wb_calc_thresh(mdtc))
+		if (wb_stat(wb, WB_RECLAIMABLE) >
+		    wb_calc_thresh(mdtc->wb, mdtc->bg_thresh))
 			return true;
 	}
 
--- zfcpdump-kernel-4.4.orig/mm/page_alloc.c
+++ zfcpdump-kernel-4.4/mm/page_alloc.c
@@ -275,7 +275,9 @@ static inline void reset_deferred_memini
 /* Returns true if the struct page for the pfn is uninitialised */
 static inline bool __meminit early_page_uninitialised(unsigned long pfn)
 {
-	if (pfn >= NODE_DATA(early_pfn_to_nid(pfn))->first_deferred_pfn)
+	int nid = early_pfn_to_nid(pfn);
+
+	if (node_online(nid) && pfn >= NODE_DATA(nid)->first_deferred_pfn)
 		return true;
 
 	return false;
@@ -662,34 +664,28 @@ static inline void __free_one_page(struc
 	unsigned long combined_idx;
 	unsigned long uninitialized_var(buddy_idx);
 	struct page *buddy;
-	unsigned int max_order = MAX_ORDER;
+	unsigned int max_order;
+
+	max_order = min_t(unsigned int, MAX_ORDER, pageblock_order + 1);
 
 	VM_BUG_ON(!zone_is_initialized(zone));
 	VM_BUG_ON_PAGE(page->flags & PAGE_FLAGS_CHECK_AT_PREP, page);
 
 	VM_BUG_ON(migratetype == -1);
-	if (is_migrate_isolate(migratetype)) {
-		/*
-		 * We restrict max order of merging to prevent merge
-		 * between freepages on isolate pageblock and normal
-		 * pageblock. Without this, pageblock isolation
-		 * could cause incorrect freepage accounting.
-		 */
-		max_order = min_t(unsigned int, MAX_ORDER, pageblock_order + 1);
-	} else {
+	if (likely(!is_migrate_isolate(migratetype)))
 		__mod_zone_freepage_state(zone, 1 << order, migratetype);
-	}
 
-	page_idx = pfn & ((1 << max_order) - 1);
+	page_idx = pfn & ((1 << MAX_ORDER) - 1);
 
 	VM_BUG_ON_PAGE(page_idx & ((1 << order) - 1), page);
 	VM_BUG_ON_PAGE(bad_range(zone, page), page);
 
+continue_merging:
 	while (order < max_order - 1) {
 		buddy_idx = __find_buddy_index(page_idx, order);
 		buddy = page + (buddy_idx - page_idx);
 		if (!page_is_buddy(page, buddy, order))
-			break;
+			goto done_merging;
 		/*
 		 * Our buddy is free or it is CONFIG_DEBUG_PAGEALLOC guard page,
 		 * merge with it and move up one order.
@@ -706,6 +702,32 @@ static inline void __free_one_page(struc
 		page_idx = combined_idx;
 		order++;
 	}
+	if (max_order < MAX_ORDER) {
+		/* If we are here, it means order is >= pageblock_order.
+		 * We want to prevent merge between freepages on isolate
+		 * pageblock and normal pageblock. Without this, pageblock
+		 * isolation could cause incorrect freepage or CMA accounting.
+		 *
+		 * We don't want to hit this code for the more frequent
+		 * low-order merging.
+		 */
+		if (unlikely(has_isolate_pageblock(zone))) {
+			int buddy_mt;
+
+			buddy_idx = __find_buddy_index(page_idx, order);
+			buddy = page + (buddy_idx - page_idx);
+			buddy_mt = get_pageblock_migratetype(buddy);
+
+			if (migratetype != buddy_mt
+					&& (is_migrate_isolate(migratetype) ||
+						is_migrate_isolate(buddy_mt)))
+				goto done_merging;
+		}
+		max_order++;
+		goto continue_merging;
+	}
+
+done_merging:
 	set_page_order(page, order);
 
 	/*
@@ -931,7 +953,7 @@ static inline void init_reserved_page(un
  * marks the pages PageReserved. The remaining valid pages are later
  * sent to the buddy page allocator.
  */
-void __meminit reserve_bootmem_region(unsigned long start, unsigned long end)
+void __meminit reserve_bootmem_region(phys_addr_t start, phys_addr_t end)
 {
 	unsigned long start_pfn = PFN_DOWN(start);
 	unsigned long end_pfn = PFN_UP(end);
@@ -1037,7 +1059,7 @@ int __meminit early_pfn_to_nid(unsigned
 	spin_lock(&early_pfn_lock);
 	nid = __early_pfn_to_nid(pfn, &early_pfnnid_cache);
 	if (nid < 0)
-		nid = 0;
+		nid = first_online_node;
 	spin_unlock(&early_pfn_lock);
 
 	return nid;
@@ -3584,6 +3606,49 @@ static inline void show_node(struct zone
 		printk("Node %d ", zone_to_nid(zone));
 }
 
+long si_mem_available(void)
+{
+	long available;
+	unsigned long pagecache;
+	unsigned long wmark_low = 0;
+	unsigned long pages[NR_LRU_LISTS];
+	struct zone *zone;
+	int lru;
+
+	for (lru = LRU_BASE; lru < NR_LRU_LISTS; lru++)
+		pages[lru] = global_page_state(NR_LRU_BASE + lru);
+
+	for_each_zone(zone)
+		wmark_low += zone->watermark[WMARK_LOW];
+
+	/*
+	 * Estimate the amount of memory available for userspace allocations,
+	 * without causing swapping.
+	 */
+	available = global_page_state(NR_FREE_PAGES) - totalreserve_pages;
+
+	/*
+	 * Not all the page cache can be freed, otherwise the system will
+	 * start swapping. Assume at least half of the page cache, or the
+	 * low watermark worth of cache, needs to stay.
+	 */
+	pagecache = pages[LRU_ACTIVE_FILE] + pages[LRU_INACTIVE_FILE];
+	pagecache -= min(pagecache / 2, wmark_low);
+	available += pagecache;
+
+	/*
+	 * Part of the reclaimable slab consists of items that are in use,
+	 * and cannot be freed. Cap this estimate at the low watermark.
+	 */
+	available += global_page_state(NR_SLAB_RECLAIMABLE) -
+		     min(global_page_state(NR_SLAB_RECLAIMABLE) / 2, wmark_low);
+
+	if (available < 0)
+		available = 0;
+	return available;
+}
+EXPORT_SYMBOL_GPL(si_mem_available);
+
 void si_meminfo(struct sysinfo *val)
 {
 	val->totalram = totalram_pages;
@@ -6173,7 +6238,7 @@ int __meminit init_per_zone_wmark_min(vo
 	setup_per_zone_inactive_ratio();
 	return 0;
 }
-module_init(init_per_zone_wmark_min)
+core_initcall(init_per_zone_wmark_min)
 
 /*
  * min_free_kbytes_sysctl_handler - just a wrapper around proc_dointvec() so
--- zfcpdump-kernel-4.4.orig/mm/page_isolation.c
+++ zfcpdump-kernel-4.4/mm/page_isolation.c
@@ -283,11 +283,11 @@ struct page *alloc_migrate_target(struct
 	 * now as a simple work-around, we use the next node for destination.
 	 */
 	if (PageHuge(page)) {
-		nodemask_t src = nodemask_of_node(page_to_nid(page));
-		nodemask_t dst;
-		nodes_complement(dst, src);
+		int node = next_online_node(page_to_nid(page));
+		if (node == MAX_NUMNODES)
+			node = first_online_node;
 		return alloc_huge_page_node(page_hstate(compound_head(page)),
-					    next_node(page_to_nid(page), dst));
+					    node);
 	}
 
 	if (PageHighMem(page))
--- zfcpdump-kernel-4.4.orig/mm/percpu.c
+++ zfcpdump-kernel-4.4/mm/percpu.c
@@ -110,7 +110,7 @@ struct pcpu_chunk {
 	int			map_used;	/* # of map entries used before the sentry */
 	int			map_alloc;	/* # of map entries allocated */
 	int			*map;		/* allocation map */
-	struct work_struct	map_extend_work;/* async ->map[] extension */
+	struct list_head	map_extend_list;/* on pcpu_map_extend_chunks */
 
 	void			*data;		/* chunk data */
 	int			first_free;	/* no free below this */
@@ -160,10 +160,13 @@ static struct pcpu_chunk *pcpu_reserved_
 static int pcpu_reserved_chunk_limit;
 
 static DEFINE_SPINLOCK(pcpu_lock);	/* all internal data structures */
-static DEFINE_MUTEX(pcpu_alloc_mutex);	/* chunk create/destroy, [de]pop */
+static DEFINE_MUTEX(pcpu_alloc_mutex);	/* chunk create/destroy, [de]pop, map ext */
 
 static struct list_head *pcpu_slot __read_mostly; /* chunk list slots */
 
+/* chunks which need their map areas extended, protected by pcpu_lock */
+static LIST_HEAD(pcpu_map_extend_chunks);
+
 /*
  * The number of empty populated pages, protected by pcpu_lock.  The
  * reserved chunk doesn't contribute to the count.
@@ -397,13 +400,19 @@ static int pcpu_need_to_extend(struct pc
 {
 	int margin, new_alloc;
 
+	lockdep_assert_held(&pcpu_lock);
+
 	if (is_atomic) {
 		margin = 3;
 
 		if (chunk->map_alloc <
-		    chunk->map_used + PCPU_ATOMIC_MAP_MARGIN_LOW &&
-		    pcpu_async_enabled)
-			schedule_work(&chunk->map_extend_work);
+		    chunk->map_used + PCPU_ATOMIC_MAP_MARGIN_LOW) {
+			if (list_empty(&chunk->map_extend_list)) {
+				list_add_tail(&chunk->map_extend_list,
+					      &pcpu_map_extend_chunks);
+				pcpu_schedule_balance_work();
+			}
+		}
 	} else {
 		margin = PCPU_ATOMIC_MAP_MARGIN_HIGH;
 	}
@@ -437,6 +446,8 @@ static int pcpu_extend_area_map(struct p
 	size_t old_size = 0, new_size = new_alloc * sizeof(new[0]);
 	unsigned long flags;
 
+	lockdep_assert_held(&pcpu_alloc_mutex);
+
 	new = pcpu_mem_zalloc(new_size);
 	if (!new)
 		return -ENOMEM;
@@ -469,20 +480,6 @@ out_unlock:
 	return 0;
 }
 
-static void pcpu_map_extend_workfn(struct work_struct *work)
-{
-	struct pcpu_chunk *chunk = container_of(work, struct pcpu_chunk,
-						map_extend_work);
-	int new_alloc;
-
-	spin_lock_irq(&pcpu_lock);
-	new_alloc = pcpu_need_to_extend(chunk, false);
-	spin_unlock_irq(&pcpu_lock);
-
-	if (new_alloc)
-		pcpu_extend_area_map(chunk, new_alloc);
-}
-
 /**
  * pcpu_fit_in_area - try to fit the requested allocation in a candidate area
  * @chunk: chunk the candidate area belongs to
@@ -742,7 +739,7 @@ static struct pcpu_chunk *pcpu_alloc_chu
 	chunk->map_used = 1;
 
 	INIT_LIST_HEAD(&chunk->list);
-	INIT_WORK(&chunk->map_extend_work, pcpu_map_extend_workfn);
+	INIT_LIST_HEAD(&chunk->map_extend_list);
 	chunk->free_size = pcpu_unit_size;
 	chunk->contig_hint = pcpu_unit_size;
 
@@ -897,6 +894,9 @@ static void __percpu *pcpu_alloc(size_t
 		return NULL;
 	}
 
+	if (!is_atomic)
+		mutex_lock(&pcpu_alloc_mutex);
+
 	spin_lock_irqsave(&pcpu_lock, flags);
 
 	/* serve reserved allocations from the reserved chunk if available */
@@ -969,12 +969,9 @@ restart:
 	if (is_atomic)
 		goto fail;
 
-	mutex_lock(&pcpu_alloc_mutex);
-
 	if (list_empty(&pcpu_slot[pcpu_nr_slots - 1])) {
 		chunk = pcpu_create_chunk();
 		if (!chunk) {
-			mutex_unlock(&pcpu_alloc_mutex);
 			err = "failed to allocate new chunk";
 			goto fail;
 		}
@@ -985,7 +982,6 @@ restart:
 		spin_lock_irqsave(&pcpu_lock, flags);
 	}
 
-	mutex_unlock(&pcpu_alloc_mutex);
 	goto restart;
 
 area_found:
@@ -995,8 +991,6 @@ area_found:
 	if (!is_atomic) {
 		int page_start, page_end, rs, re;
 
-		mutex_lock(&pcpu_alloc_mutex);
-
 		page_start = PFN_DOWN(off);
 		page_end = PFN_UP(off + size);
 
@@ -1007,7 +1001,6 @@ area_found:
 
 			spin_lock_irqsave(&pcpu_lock, flags);
 			if (ret) {
-				mutex_unlock(&pcpu_alloc_mutex);
 				pcpu_free_area(chunk, off, &occ_pages);
 				err = "failed to populate";
 				goto fail_unlock;
@@ -1047,6 +1040,8 @@ fail:
 		/* see the flag handling in pcpu_blance_workfn() */
 		pcpu_atomic_alloc_failed = true;
 		pcpu_schedule_balance_work();
+	} else {
+		mutex_unlock(&pcpu_alloc_mutex);
 	}
 	return NULL;
 }
@@ -1131,6 +1126,7 @@ static void pcpu_balance_workfn(struct w
 		if (chunk == list_first_entry(free_head, struct pcpu_chunk, list))
 			continue;
 
+		list_del_init(&chunk->map_extend_list);
 		list_move(&chunk->list, &to_free);
 	}
 
@@ -1148,6 +1144,25 @@ static void pcpu_balance_workfn(struct w
 		pcpu_destroy_chunk(chunk);
 	}
 
+	/* service chunks which requested async area map extension */
+	do {
+		int new_alloc = 0;
+
+		spin_lock_irq(&pcpu_lock);
+
+		chunk = list_first_entry_or_null(&pcpu_map_extend_chunks,
+					struct pcpu_chunk, map_extend_list);
+		if (chunk) {
+			list_del_init(&chunk->map_extend_list);
+			new_alloc = pcpu_need_to_extend(chunk, false);
+		}
+
+		spin_unlock_irq(&pcpu_lock);
+
+		if (new_alloc)
+			pcpu_extend_area_map(chunk, new_alloc);
+	} while (chunk);
+
 	/*
 	 * Ensure there are certain number of free populated pages for
 	 * atomic allocs.  Fill up from the most packed so that atomic
@@ -1646,7 +1661,7 @@ int __init pcpu_setup_first_chunk(const
 	 */
 	schunk = memblock_virt_alloc(pcpu_chunk_struct_size, 0);
 	INIT_LIST_HEAD(&schunk->list);
-	INIT_WORK(&schunk->map_extend_work, pcpu_map_extend_workfn);
+	INIT_LIST_HEAD(&schunk->map_extend_list);
 	schunk->base_addr = base_addr;
 	schunk->map = smap;
 	schunk->map_alloc = ARRAY_SIZE(smap);
@@ -1675,7 +1690,7 @@ int __init pcpu_setup_first_chunk(const
 	if (dyn_size) {
 		dchunk = memblock_virt_alloc(pcpu_chunk_struct_size, 0);
 		INIT_LIST_HEAD(&dchunk->list);
-		INIT_WORK(&dchunk->map_extend_work, pcpu_map_extend_workfn);
+		INIT_LIST_HEAD(&dchunk->map_extend_list);
 		dchunk->base_addr = base_addr;
 		dchunk->map = dmap;
 		dchunk->map_alloc = ARRAY_SIZE(dmap);
--- zfcpdump-kernel-4.4.orig/mm/pgtable-generic.c
+++ zfcpdump-kernel-4.4/mm/pgtable-generic.c
@@ -210,7 +210,9 @@ pmd_t pmdp_collapse_flush(struct vm_area
 	VM_BUG_ON(address & ~HPAGE_PMD_MASK);
 	VM_BUG_ON(pmd_trans_huge(*pmdp));
 	pmd = pmdp_huge_get_and_clear(vma->vm_mm, address, pmdp);
-	flush_pmd_tlb_range(vma, address, address + HPAGE_PMD_SIZE);
+
+	/* collapse entails shooting down ptes not pmd */
+	flush_tlb_range(vma, address, address + HPAGE_PMD_SIZE);
 	return pmd;
 }
 #endif
--- /dev/null
+++ zfcpdump-kernel-4.4/mm/prfile.c
@@ -0,0 +1,86 @@
+/*
+ * Mainly for aufs which mmap(2) diffrent file and wants to print different path
+ * in /proc/PID/maps.
+ * Call these functions via macros defined in linux/mm.h.
+ *
+ * See Documentation/filesystems/aufs/design/06mmap.txt
+ *
+ * Copyright (c) 2014 Junjro R. Okajima
+ * Copyright (c) 2014 Ian Campbell
+ */
+
+#include <linux/mm.h>
+#include <linux/file.h>
+#include <linux/fs.h>
+
+/* #define PRFILE_TRACE */
+static inline void prfile_trace(struct file *f, struct file *pr,
+			      const char func[], int line, const char func2[])
+{
+#ifdef PRFILE_TRACE
+	if (pr)
+		pr_info("%s:%d: %s, %s\n", func, line, func2,
+			f ? (char *)f->f_path.dentry->d_name.name : "(null)");
+#endif
+}
+
+void vma_do_file_update_time(struct vm_area_struct *vma, const char func[],
+			     int line)
+{
+	struct file *f = vma->vm_file, *pr = vma->vm_prfile;
+
+	prfile_trace(f, pr, func, line, __func__);
+	file_update_time(f);
+	if (f && pr)
+		file_update_time(pr);
+}
+
+struct file *vma_do_pr_or_file(struct vm_area_struct *vma, const char func[],
+			       int line)
+{
+	struct file *f = vma->vm_file, *pr = vma->vm_prfile;
+
+	prfile_trace(f, pr, func, line, __func__);
+	return (f && pr) ? pr : f;
+}
+
+void vma_do_get_file(struct vm_area_struct *vma, const char func[], int line)
+{
+	struct file *f = vma->vm_file, *pr = vma->vm_prfile;
+
+	prfile_trace(f, pr, func, line, __func__);
+	get_file(f);
+	if (f && pr)
+		get_file(pr);
+}
+
+void vma_do_fput(struct vm_area_struct *vma, const char func[], int line)
+{
+	struct file *f = vma->vm_file, *pr = vma->vm_prfile;
+
+	prfile_trace(f, pr, func, line, __func__);
+	fput(f);
+	if (f && pr)
+		fput(pr);
+}
+
+#ifndef CONFIG_MMU
+struct file *vmr_do_pr_or_file(struct vm_region *region, const char func[],
+			       int line)
+{
+	struct file *f = region->vm_file, *pr = region->vm_prfile;
+
+	prfile_trace(f, pr, func, line, __func__);
+	return (f && pr) ? pr : f;
+}
+
+void vmr_do_fput(struct vm_region *region, const char func[], int line)
+{
+	struct file *f = region->vm_file, *pr = region->vm_prfile;
+
+	prfile_trace(f, pr, func, line, __func__);
+	fput(f);
+	if (f && pr)
+		fput(pr);
+}
+#endif /* !CONFIG_MMU */
--- zfcpdump-kernel-4.4.orig/mm/process_vm_access.c
+++ zfcpdump-kernel-4.4/mm/process_vm_access.c
@@ -194,7 +194,7 @@ static ssize_t process_vm_rw_core(pid_t
 		goto free_proc_pages;
 	}
 
-	mm = mm_access(task, PTRACE_MODE_ATTACH);
+	mm = mm_access(task, PTRACE_MODE_ATTACH_REALCREDS);
 	if (!mm || IS_ERR(mm)) {
 		rc = IS_ERR(mm) ? PTR_ERR(mm) : -ESRCH;
 		/*
--- zfcpdump-kernel-4.4.orig/mm/shmem.c
+++ zfcpdump-kernel-4.4/mm/shmem.c
@@ -112,9 +112,13 @@ static unsigned long shmem_default_max_b
 	return totalram_pages / 2;
 }
 
-static unsigned long shmem_default_max_inodes(void)
+static int shmem_default_max_inodes(void)
 {
-	return min(totalram_pages - totalhigh_pages, totalram_pages / 2);
+	unsigned long ul;
+
+	ul = INT_MAX;
+	ul = min3(ul, totalram_pages - totalhigh_pages, totalram_pages / 2);
+	return ul;
 }
 #endif
 
@@ -610,6 +614,7 @@ static int shmem_setattr(struct dentry *
 static void shmem_evict_inode(struct inode *inode)
 {
 	struct shmem_inode_info *info = SHMEM_I(inode);
+	struct shmem_sb_info *sbinfo = SHMEM_SB(inode->i_sb);
 
 	if (inode->i_mapping->a_ops == &shmem_aops) {
 		shmem_unacct_size(info->flags, inode->i_size);
@@ -620,11 +625,15 @@ static void shmem_evict_inode(struct ino
 			list_del_init(&info->swaplist);
 			mutex_unlock(&shmem_swaplist_mutex);
 		}
-	} else
-		kfree(info->symlink);
+	}
 
 	simple_xattrs_free(&info->xattrs);
 	WARN_ON(inode->i_blocks);
+	if (!sbinfo->idr_nouse && inode->i_ino) {
+		mutex_lock(&sbinfo->idr_lock);
+		idr_remove(&sbinfo->idr, inode->i_ino);
+		mutex_unlock(&sbinfo->idr_lock);
+	}
 	shmem_free_inode(inode->i_sb);
 	clear_inode(inode);
 }
@@ -1418,13 +1427,13 @@ static struct inode *shmem_get_inode(str
 	struct inode *inode;
 	struct shmem_inode_info *info;
 	struct shmem_sb_info *sbinfo = SHMEM_SB(sb);
+	int ino;
 
 	if (shmem_reserve_inode(sb))
 		return NULL;
 
 	inode = new_inode(sb);
 	if (inode) {
-		inode->i_ino = get_next_ino();
 		inode_init_owner(inode, dir, mode);
 		inode->i_blocks = 0;
 		inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
@@ -1465,6 +1474,25 @@ static struct inode *shmem_get_inode(str
 			mpol_shared_policy_init(&info->policy, NULL);
 			break;
 		}
+
+		if (!sbinfo->idr_nouse) {
+			/* inum 0 and 1 are unused */
+			mutex_lock(&sbinfo->idr_lock);
+			ino = idr_alloc(&sbinfo->idr, inode, 2, INT_MAX,
+					GFP_NOFS);
+			if (ino > 0) {
+				inode->i_ino = ino;
+				mutex_unlock(&sbinfo->idr_lock);
+				__insert_inode_hash(inode, inode->i_ino);
+			} else {
+				inode->i_ino = 0;
+				mutex_unlock(&sbinfo->idr_lock);
+				iput(inode);
+				/* shmem_free_inode() will be called */
+				inode = NULL;
+			}
+		} else
+			inode->i_ino = get_next_ino();
 	} else
 		shmem_free_inode(sb);
 	return inode;
@@ -2154,9 +2182,11 @@ static long shmem_fallocate(struct file
 									NULL);
 		if (error) {
 			/* Remove the !PageUptodate pages we added */
-			shmem_undo_range(inode,
-				(loff_t)start << PAGE_CACHE_SHIFT,
-				(loff_t)index << PAGE_CACHE_SHIFT, true);
+			if (index > start) {
+				shmem_undo_range(inode,
+				 (loff_t)start << PAGE_CACHE_SHIFT,
+				 ((loff_t)index << PAGE_CACHE_SHIFT) - 1, true);
+			}
 			goto undone;
 		}
 
@@ -2462,13 +2492,12 @@ static int shmem_symlink(struct inode *d
 	info = SHMEM_I(inode);
 	inode->i_size = len-1;
 	if (len <= SHORT_SYMLINK_LEN) {
-		info->symlink = kmemdup(symname, len, GFP_KERNEL);
-		if (!info->symlink) {
+		inode->i_link = kmemdup(symname, len, GFP_KERNEL);
+		if (!inode->i_link) {
 			iput(inode);
 			return -ENOMEM;
 		}
 		inode->i_op = &shmem_short_symlink_operations;
-		inode->i_link = info->symlink;
 	} else {
 		error = shmem_getpage(inode, 0, &page, SGP_WRITE, NULL);
 		if (error) {
@@ -2682,8 +2711,7 @@ static struct dentry *shmem_get_parent(s
 static int shmem_match(struct inode *ino, void *vfh)
 {
 	__u32 *fh = vfh;
-	__u64 inum = fh[2];
-	inum = (inum << 32) | fh[1];
+	__u64 inum = fh[1];
 	return ino->i_ino == inum && fh[0] == ino->i_generation;
 }
 
@@ -2694,14 +2722,11 @@ static struct dentry *shmem_fh_to_dentry
 	struct dentry *dentry = NULL;
 	u64 inum;
 
-	if (fh_len < 3)
+	if (fh_len < 2)
 		return NULL;
 
-	inum = fid->raw[2];
-	inum = (inum << 32) | fid->raw[1];
-
-	inode = ilookup5(sb, (unsigned long)(inum + fid->raw[0]),
-			shmem_match, fid->raw);
+	inum = fid->raw[1];
+	inode = ilookup5(sb, inum, shmem_match, fid->raw);
 	if (inode) {
 		dentry = d_find_alias(inode);
 		iput(inode);
@@ -2713,30 +2738,15 @@ static struct dentry *shmem_fh_to_dentry
 static int shmem_encode_fh(struct inode *inode, __u32 *fh, int *len,
 				struct inode *parent)
 {
-	if (*len < 3) {
-		*len = 3;
+	if (*len < 2) {
+		*len = 2;
 		return FILEID_INVALID;
 	}
 
-	if (inode_unhashed(inode)) {
-		/* Unfortunately insert_inode_hash is not idempotent,
-		 * so as we hash inodes here rather than at creation
-		 * time, we need a lock to ensure we only try
-		 * to do it once
-		 */
-		static DEFINE_SPINLOCK(lock);
-		spin_lock(&lock);
-		if (inode_unhashed(inode))
-			__insert_inode_hash(inode,
-					    inode->i_ino + inode->i_generation);
-		spin_unlock(&lock);
-	}
-
 	fh[0] = inode->i_generation;
 	fh[1] = inode->i_ino;
-	fh[2] = ((__u64)inode->i_ino) >> 32;
 
-	*len = 3;
+	*len = 2;
 	return 1;
 }
 
@@ -2801,7 +2811,7 @@ static int shmem_parse_options(char *opt
 				goto bad_val;
 		} else if (!strcmp(this_char,"nr_inodes")) {
 			sbinfo->max_inodes = memparse(value, &rest);
-			if (*rest)
+			if (*rest || sbinfo->max_inodes < 2)
 				goto bad_val;
 		} else if (!strcmp(this_char,"mode")) {
 			if (remount)
@@ -2854,7 +2864,7 @@ static int shmem_remount_fs(struct super
 {
 	struct shmem_sb_info *sbinfo = SHMEM_SB(sb);
 	struct shmem_sb_info config = *sbinfo;
-	unsigned long inodes;
+	int inodes;
 	int error = -EINVAL;
 
 	config.mpol = NULL;
@@ -2902,7 +2912,7 @@ static int shmem_show_options(struct seq
 		seq_printf(seq, ",size=%luk",
 			sbinfo->max_blocks << (PAGE_CACHE_SHIFT - 10));
 	if (sbinfo->max_inodes != shmem_default_max_inodes())
-		seq_printf(seq, ",nr_inodes=%lu", sbinfo->max_inodes);
+		seq_printf(seq, ",nr_inodes=%d", sbinfo->max_inodes);
 	if (sbinfo->mode != (S_IRWXUGO | S_ISVTX))
 		seq_printf(seq, ",mode=%03ho", sbinfo->mode);
 	if (!uid_eq(sbinfo->uid, GLOBAL_ROOT_UID))
@@ -2991,6 +3001,8 @@ static void shmem_put_super(struct super
 {
 	struct shmem_sb_info *sbinfo = SHMEM_SB(sb);
 
+	if (!sbinfo->idr_nouse)
+		idr_destroy(&sbinfo->idr);
 	percpu_counter_destroy(&sbinfo->used_blocks);
 	mpol_put(sbinfo->mpol);
 	kfree(sbinfo);
@@ -3009,6 +3021,8 @@ int shmem_fill_super(struct super_block
 	if (!sbinfo)
 		return -ENOMEM;
 
+	mutex_init(&sbinfo->idr_lock);
+	idr_init(&sbinfo->idr);
 	sbinfo->mode = S_IRWXUGO | S_ISVTX;
 	sbinfo->uid = current_fsuid();
 	sbinfo->gid = current_fsgid();
@@ -3083,6 +3097,7 @@ static struct inode *shmem_alloc_inode(s
 static void shmem_destroy_callback(struct rcu_head *head)
 {
 	struct inode *inode = container_of(head, struct inode, i_rcu);
+	kfree(inode->i_link);
 	kmem_cache_free(shmem_inode_cachep, SHMEM_I(inode));
 }
 
@@ -3112,6 +3127,15 @@ static void shmem_destroy_inodecache(voi
 	kmem_cache_destroy(shmem_inode_cachep);
 }
 
+static __init void shmem_no_idr(struct super_block *sb)
+{
+	struct shmem_sb_info *sbinfo;
+
+	sbinfo = SHMEM_SB(sb);
+	sbinfo->idr_nouse = true;
+	idr_destroy(&sbinfo->idr);
+}
+
 static const struct address_space_operations shmem_aops = {
 	.writepage	= shmem_writepage,
 	.set_page_dirty	= __set_page_dirty_no_writeback,
@@ -3248,6 +3272,7 @@ int __init shmem_init(void)
 		printk(KERN_ERR "Could not kern_mount tmpfs\n");
 		goto out1;
 	}
+	shmem_no_idr(shm_mnt->mnt_sb);
 	return 0;
 
 out1:
--- zfcpdump-kernel-4.4.orig/mm/slab_common.c
+++ zfcpdump-kernel-4.4/mm/slab_common.c
@@ -521,8 +521,8 @@ void memcg_create_kmem_cache(struct mem_
 		goto out_unlock;
 
 	cgroup_name(css->cgroup, memcg_name_buf, sizeof(memcg_name_buf));
-	cache_name = kasprintf(GFP_KERNEL, "%s(%d:%s)", root_cache->name,
-			       css->id, memcg_name_buf);
+	cache_name = kasprintf(GFP_KERNEL, "%s(%llu:%s)", root_cache->name,
+			       css->serial_nr, memcg_name_buf);
 	if (!cache_name)
 		goto out_unlock;
 
--- zfcpdump-kernel-4.4.orig/mm/slub.c
+++ zfcpdump-kernel-4.4/mm/slub.c
@@ -2819,6 +2819,7 @@ struct detached_freelist {
 	void *tail;
 	void *freelist;
 	int cnt;
+	struct kmem_cache *s;
 };
 
 /*
@@ -2833,8 +2834,9 @@ struct detached_freelist {
  * synchronization primitive.  Look ahead in the array is limited due
  * to performance reasons.
  */
-static int build_detached_freelist(struct kmem_cache *s, size_t size,
-				   void **p, struct detached_freelist *df)
+static inline
+int build_detached_freelist(struct kmem_cache *s, size_t size,
+			    void **p, struct detached_freelist *df)
 {
 	size_t first_skipped_index = 0;
 	int lookahead = 3;
@@ -2850,8 +2852,11 @@ static int build_detached_freelist(struc
 	if (!object)
 		return 0;
 
+	/* Support for memcg, compiler can optimize this out */
+	df->s = cache_from_obj(s, object);
+
 	/* Start new detached freelist */
-	set_freepointer(s, object, NULL);
+	set_freepointer(df->s, object, NULL);
 	df->page = virt_to_head_page(object);
 	df->tail = object;
 	df->freelist = object;
@@ -2866,7 +2871,7 @@ static int build_detached_freelist(struc
 		/* df->page is always set at this point */
 		if (df->page == virt_to_head_page(object)) {
 			/* Opportunity build freelist */
-			set_freepointer(s, object, df->freelist);
+			set_freepointer(df->s, object, df->freelist);
 			df->freelist = object;
 			df->cnt++;
 			p[size] = NULL; /* mark object processed */
@@ -2885,25 +2890,20 @@ static int build_detached_freelist(struc
 	return first_skipped_index;
 }
 
-
 /* Note that interrupts must be enabled when calling this function. */
-void kmem_cache_free_bulk(struct kmem_cache *orig_s, size_t size, void **p)
+void kmem_cache_free_bulk(struct kmem_cache *s, size_t size, void **p)
 {
 	if (WARN_ON(!size))
 		return;
 
 	do {
 		struct detached_freelist df;
-		struct kmem_cache *s;
-
-		/* Support for memcg */
-		s = cache_from_obj(orig_s, p[size - 1]);
 
 		size = build_detached_freelist(s, size, p, &df);
 		if (unlikely(!df.page))
 			continue;
 
-		slab_free(s, df.page, df.freelist, df.tail, df.cnt, _RET_IP_);
+		slab_free(df.s, df.page, df.freelist, df.tail, df.cnt,_RET_IP_);
 	} while (likely(size));
 }
 EXPORT_SYMBOL(kmem_cache_free_bulk);
--- zfcpdump-kernel-4.4.orig/mm/swapfile.c
+++ zfcpdump-kernel-4.4/mm/swapfile.c
@@ -48,6 +48,12 @@ static sector_t map_swap_entry(swp_entry
 DEFINE_SPINLOCK(swap_lock);
 static unsigned int nr_swapfiles;
 atomic_long_t nr_swap_pages;
+/*
+ * Some modules use swappable objects and may try to swap them out under
+ * memory pressure (via the shrinker). Before doing so, they may wish to
+ * check to see if any swap space is available.
+ */
+EXPORT_SYMBOL_GPL(nr_swap_pages);
 /* protected with swap_lock. reading in vm_swap_full() doesn't need lock */
 long total_swap_pages;
 static int least_priority;
--- zfcpdump-kernel-4.4.orig/mm/util.c
+++ zfcpdump-kernel-4.4/mm/util.c
@@ -199,36 +199,11 @@ void __vma_link_list(struct mm_struct *m
 }
 
 /* Check if the vma is being used as a stack by this task */
-static int vm_is_stack_for_task(struct task_struct *t,
-				struct vm_area_struct *vma)
+int vma_is_stack_for_task(struct vm_area_struct *vma, struct task_struct *t)
 {
 	return (vma->vm_start <= KSTK_ESP(t) && vma->vm_end >= KSTK_ESP(t));
 }
 
-/*
- * Check if the vma is being used as a stack.
- * If is_group is non-zero, check in the entire thread group or else
- * just check in the current task. Returns the task_struct of the task
- * that the vma is stack for. Must be called under rcu_read_lock().
- */
-struct task_struct *task_of_stack(struct task_struct *task,
-				struct vm_area_struct *vma, bool in_group)
-{
-	if (vm_is_stack_for_task(task, vma))
-		return task;
-
-	if (in_group) {
-		struct task_struct *t;
-
-		for_each_thread(task, t) {
-			if (vm_is_stack_for_task(t, vma))
-				return t;
-		}
-	}
-
-	return NULL;
-}
-
 #if defined(CONFIG_MMU) && !defined(HAVE_ARCH_PICK_MMAP_LAYOUT)
 void arch_pick_mmap_layout(struct mm_struct *mm)
 {
--- zfcpdump-kernel-4.4.orig/mm/vmscan.c
+++ zfcpdump-kernel-4.4/mm/vmscan.c
@@ -2159,23 +2159,6 @@ out:
 	}
 }
 
-#ifdef CONFIG_ARCH_WANT_BATCHED_UNMAP_TLB_FLUSH
-static void init_tlb_ubc(void)
-{
-	/*
-	 * This deliberately does not clear the cpumask as it's expensive
-	 * and unnecessary. If there happens to be data in there then the
-	 * first SWAP_CLUSTER_MAX pages will send an unnecessary IPI and
-	 * then will be cleared.
-	 */
-	current->tlb_ubc.flush_required = false;
-}
-#else
-static inline void init_tlb_ubc(void)
-{
-}
-#endif /* CONFIG_ARCH_WANT_BATCHED_UNMAP_TLB_FLUSH */
-
 /*
  * This is a basic per-zone page freer.  Used by both kswapd and direct reclaim.
  */
@@ -2210,8 +2193,6 @@ static void shrink_lruvec(struct lruvec
 	scan_adjusted = (global_reclaim(sc) && !current_is_kswapd() &&
 			 sc->priority == DEF_PRIORITY);
 
-	init_tlb_ubc();
-
 	blk_start_plug(&plug);
 	while (nr[LRU_INACTIVE_ANON] || nr[LRU_ACTIVE_FILE] ||
 					nr[LRU_INACTIVE_FILE]) {
@@ -2534,7 +2515,7 @@ static bool shrink_zones(struct zonelist
 		sc->gfp_mask |= __GFP_HIGHMEM;
 
 	for_each_zone_zonelist_nodemask(zone, z, zonelist,
-					requested_highidx, sc->nodemask) {
+					gfp_zone(sc->gfp_mask), sc->nodemask) {
 		enum zone_type classzone_idx;
 
 		if (!populated_zone(zone))
@@ -2959,6 +2940,13 @@ static void age_active_anon(struct zone
 static bool zone_balanced(struct zone *zone, int order,
 			  unsigned long balance_gap, int classzone_idx)
 {
+	/*
+	 * if zone is so small that watermarks are the same, don't bother trying
+	 * to balance; kswapd would just spin continuously trying to balance it.
+	 */
+	if (low_wmark_pages(zone) == high_wmark_pages(zone))
+		return true;
+
 	if (!zone_watermark_ok_safe(zone, order, high_wmark_pages(zone) +
 				    balance_gap, classzone_idx))
 		return false;
--- zfcpdump-kernel-4.4.orig/mm/zsmalloc.c
+++ zfcpdump-kernel-4.4/mm/zsmalloc.c
@@ -309,7 +309,12 @@ static void free_handle(struct zs_pool *
 
 static void record_obj(unsigned long handle, unsigned long obj)
 {
-	*(unsigned long *)handle = obj;
+	/*
+	 * lsb of @obj represents handle lock while other bits
+	 * represent object value the handle is pointing so
+	 * updating shouldn't do store tearing.
+	 */
+	WRITE_ONCE(*(unsigned long *)handle, obj);
 }
 
 /* zpool driver */
@@ -1635,6 +1640,13 @@ static int migrate_zspage(struct zs_pool
 		free_obj = obj_malloc(d_page, class, handle);
 		zs_object_copy(free_obj, used_obj, class);
 		index++;
+		/*
+		 * record_obj updates handle's value to free_obj and it will
+		 * invalidate lock bit(ie, HANDLE_PIN_BIT) of handle, which
+		 * breaks synchronization using pin_tag(e,g, zs_free) so
+		 * let's keep the lock bit.
+		 */
+		free_obj |= BIT(HANDLE_PIN_BIT);
 		record_obj(handle, free_obj);
 		unpin_tag(handle);
 		obj_free(pool, class, used_obj);
@@ -1720,10 +1732,13 @@ static struct page *isolate_source_page(
 static unsigned long zs_can_compact(struct size_class *class)
 {
 	unsigned long obj_wasted;
+	unsigned long obj_allocated = zs_stat_get(class, OBJ_ALLOCATED);
+	unsigned long obj_used = zs_stat_get(class, OBJ_USED);
 
-	obj_wasted = zs_stat_get(class, OBJ_ALLOCATED) -
-		zs_stat_get(class, OBJ_USED);
+	if (obj_allocated <= obj_used)
+		return 0;
 
+	obj_wasted = obj_allocated - obj_used;
 	obj_wasted /= get_maxobj_per_zspage(class->size,
 			class->pages_per_zspage);
 
--- zfcpdump-kernel-4.4.orig/mm/zswap.c
+++ zfcpdump-kernel-4.4/mm/zswap.c
@@ -170,6 +170,8 @@ static struct zswap_tree *zswap_trees[MA
 static LIST_HEAD(zswap_pools);
 /* protects zswap_pools list modification */
 static DEFINE_SPINLOCK(zswap_pools_lock);
+/* pool counter to provide unique names to zpool */
+static atomic_t zswap_pools_count = ATOMIC_INIT(0);
 
 /* used by param callback function */
 static bool zswap_init_started;
@@ -565,6 +567,7 @@ static struct zswap_pool *zswap_pool_fin
 static struct zswap_pool *zswap_pool_create(char *type, char *compressor)
 {
 	struct zswap_pool *pool;
+	char name[38]; /* 'zswap' + 32 char (max) num + \0 */
 	gfp_t gfp = __GFP_NORETRY | __GFP_NOWARN | __GFP_KSWAPD_RECLAIM;
 
 	pool = kzalloc(sizeof(*pool), GFP_KERNEL);
@@ -573,7 +576,10 @@ static struct zswap_pool *zswap_pool_cre
 		return NULL;
 	}
 
-	pool->zpool = zpool_create_pool(type, "zswap", gfp, &zswap_zpool_ops);
+	/* unique name for each pool specifically required by zsmalloc */
+	snprintf(name, 38, "zswap%x", atomic_inc_return(&zswap_pools_count));
+
+	pool->zpool = zpool_create_pool(type, name, gfp, &zswap_zpool_ops);
 	if (!pool->zpool) {
 		pr_err("%s zpool not available\n", type);
 		goto error;
--- zfcpdump-kernel-4.4.orig/net/8021q/vlan.c
+++ zfcpdump-kernel-4.4/net/8021q/vlan.c
@@ -659,7 +659,7 @@ static struct sk_buff **vlan_gro_receive
 
 	skb_gro_pull(skb, sizeof(*vhdr));
 	skb_gro_postpull_rcsum(skb, vhdr, sizeof(*vhdr));
-	pp = ptype->callbacks.gro_receive(head, skb);
+	pp = call_gro_receive(ptype->callbacks.gro_receive, head, skb);
 
 out_unlock:
 	rcu_read_unlock();
--- zfcpdump-kernel-4.4.orig/net/8021q/vlan_dev.c
+++ zfcpdump-kernel-4.4/net/8021q/vlan_dev.c
@@ -544,7 +544,7 @@ static int vlan_dev_init(struct net_devi
 
 	dev->hw_features = NETIF_F_ALL_CSUM | NETIF_F_SG |
 			   NETIF_F_FRAGLIST | NETIF_F_GSO_SOFTWARE |
-			   NETIF_F_HIGHDMA | NETIF_F_SCTP_CSUM |
+			   NETIF_F_HIGHDMA | NETIF_F_SCTP_CRC |
 			   NETIF_F_ALL_FCOE;
 
 	dev->features |= real_dev->vlan_features | NETIF_F_LLTX |
--- zfcpdump-kernel-4.4.orig/net/ax25/af_ax25.c
+++ zfcpdump-kernel-4.4/net/ax25/af_ax25.c
@@ -976,7 +976,8 @@ static int ax25_release(struct socket *s
 			release_sock(sk);
 			ax25_disconnect(ax25, 0);
 			lock_sock(sk);
-			ax25_destroy_socket(ax25);
+			if (!sock_flag(ax25->sk, SOCK_DESTROY))
+				ax25_destroy_socket(ax25);
 			break;
 
 		case AX25_STATE_3:
--- zfcpdump-kernel-4.4.orig/net/ax25/ax25_ds_timer.c
+++ zfcpdump-kernel-4.4/net/ax25/ax25_ds_timer.c
@@ -102,6 +102,7 @@ void ax25_ds_heartbeat_expiry(ax25_cb *a
 	switch (ax25->state) {
 
 	case AX25_STATE_0:
+	case AX25_STATE_2:
 		/* Magic here: If we listen() and a new link dies before it
 		   is accepted() it isn't 'dead' so doesn't get removed. */
 		if (!sk || sock_flag(sk, SOCK_DESTROY) ||
@@ -111,6 +112,7 @@ void ax25_ds_heartbeat_expiry(ax25_cb *a
 				sock_hold(sk);
 				ax25_destroy_socket(ax25);
 				bh_unlock_sock(sk);
+				/* Ungrab socket and destroy it */
 				sock_put(sk);
 			} else
 				ax25_destroy_socket(ax25);
@@ -213,7 +215,8 @@ void ax25_ds_t1_timeout(ax25_cb *ax25)
 	case AX25_STATE_2:
 		if (ax25->n2count == ax25->n2) {
 			ax25_send_control(ax25, AX25_DISC, AX25_POLLON, AX25_COMMAND);
-			ax25_disconnect(ax25, ETIMEDOUT);
+			if (!sock_flag(ax25->sk, SOCK_DESTROY))
+				ax25_disconnect(ax25, ETIMEDOUT);
 			return;
 		} else {
 			ax25->n2count++;
--- zfcpdump-kernel-4.4.orig/net/ax25/ax25_ip.c
+++ zfcpdump-kernel-4.4/net/ax25/ax25_ip.c
@@ -228,8 +228,23 @@ netdev_tx_t ax25_ip_xmit(struct sk_buff
 }
 #endif
 
+static bool ax25_validate_header(const char *header, unsigned int len)
+{
+	ax25_digi digi;
+
+	if (!len)
+		return false;
+
+	if (header[0])
+		return true;
+
+	return ax25_addr_parse(header + 1, len - 1, NULL, NULL, &digi, NULL,
+			       NULL);
+}
+
 const struct header_ops ax25_header_ops = {
 	.create = ax25_hard_header,
+	.validate = ax25_validate_header,
 };
 
 EXPORT_SYMBOL(ax25_header_ops);
--- zfcpdump-kernel-4.4.orig/net/ax25/ax25_std_timer.c
+++ zfcpdump-kernel-4.4/net/ax25/ax25_std_timer.c
@@ -38,6 +38,7 @@ void ax25_std_heartbeat_expiry(ax25_cb *
 
 	switch (ax25->state) {
 	case AX25_STATE_0:
+	case AX25_STATE_2:
 		/* Magic here: If we listen() and a new link dies before it
 		   is accepted() it isn't 'dead' so doesn't get removed. */
 		if (!sk || sock_flag(sk, SOCK_DESTROY) ||
@@ -47,6 +48,7 @@ void ax25_std_heartbeat_expiry(ax25_cb *
 				sock_hold(sk);
 				ax25_destroy_socket(ax25);
 				bh_unlock_sock(sk);
+				/* Ungrab socket and destroy it */
 				sock_put(sk);
 			} else
 				ax25_destroy_socket(ax25);
@@ -144,7 +146,8 @@ void ax25_std_t1timer_expiry(ax25_cb *ax
 	case AX25_STATE_2:
 		if (ax25->n2count == ax25->n2) {
 			ax25_send_control(ax25, AX25_DISC, AX25_POLLON, AX25_COMMAND);
-			ax25_disconnect(ax25, ETIMEDOUT);
+			if (!sock_flag(ax25->sk, SOCK_DESTROY))
+				ax25_disconnect(ax25, ETIMEDOUT);
 			return;
 		} else {
 			ax25->n2count++;
--- zfcpdump-kernel-4.4.orig/net/ax25/ax25_subr.c
+++ zfcpdump-kernel-4.4/net/ax25/ax25_subr.c
@@ -264,7 +264,8 @@ void ax25_disconnect(ax25_cb *ax25, int
 {
 	ax25_clear_queues(ax25);
 
-	ax25_stop_heartbeat(ax25);
+	if (!sock_flag(ax25->sk, SOCK_DESTROY))
+		ax25_stop_heartbeat(ax25);
 	ax25_stop_t1timer(ax25);
 	ax25_stop_t2timer(ax25);
 	ax25_stop_t3timer(ax25);
--- zfcpdump-kernel-4.4.orig/net/batman-adv/bridge_loop_avoidance.c
+++ zfcpdump-kernel-4.4/net/batman-adv/bridge_loop_avoidance.c
@@ -127,21 +127,17 @@ batadv_backbone_gw_free_ref(struct batad
 }
 
 /* finally deinitialize the claim */
-static void batadv_claim_free_rcu(struct rcu_head *rcu)
+static void batadv_claim_release(struct batadv_bla_claim *claim)
 {
-	struct batadv_bla_claim *claim;
-
-	claim = container_of(rcu, struct batadv_bla_claim, rcu);
-
 	batadv_backbone_gw_free_ref(claim->backbone_gw);
-	kfree(claim);
+	kfree_rcu(claim, rcu);
 }
 
 /* free a claim, call claim_free_rcu if its the last reference */
 static void batadv_claim_free_ref(struct batadv_bla_claim *claim)
 {
 	if (atomic_dec_and_test(&claim->refcount))
-		call_rcu(&claim->rcu, batadv_claim_free_rcu);
+		batadv_claim_release(claim);
 }
 
 /**
--- zfcpdump-kernel-4.4.orig/net/batman-adv/distributed-arp-table.c
+++ zfcpdump-kernel-4.4/net/batman-adv/distributed-arp-table.c
@@ -553,6 +553,7 @@ static void batadv_choose_next_candidate
  * be sent to
  * @bat_priv: the bat priv with all the soft interface information
  * @ip_dst: ipv4 to look up in the DHT
+ * @vid: VLAN identifier
  *
  * An originator O is selected if and only if its DHT_ID value is one of three
  * closest values (from the LEFT, with wrap around if needed) then the hash
@@ -561,7 +562,8 @@ static void batadv_choose_next_candidate
  * Returns the candidate array of size BATADV_DAT_CANDIDATE_NUM.
  */
 static struct batadv_dat_candidate *
-batadv_dat_select_candidates(struct batadv_priv *bat_priv, __be32 ip_dst)
+batadv_dat_select_candidates(struct batadv_priv *bat_priv, __be32 ip_dst,
+			     unsigned short vid)
 {
 	int select;
 	batadv_dat_addr_t last_max = BATADV_DAT_ADDR_MAX, ip_key;
@@ -577,7 +579,7 @@ batadv_dat_select_candidates(struct bata
 		return NULL;
 
 	dat.ip = ip_dst;
-	dat.vid = 0;
+	dat.vid = vid;
 	ip_key = (batadv_dat_addr_t)batadv_hash_dat(&dat,
 						    BATADV_DAT_ADDR_MAX);
 
@@ -597,6 +599,7 @@ batadv_dat_select_candidates(struct bata
  * @bat_priv: the bat priv with all the soft interface information
  * @skb: payload to send
  * @ip: the DHT key
+ * @vid: VLAN identifier
  * @packet_subtype: unicast4addr packet subtype to use
  *
  * This function copies the skb with pskb_copy() and is sent as unicast packet
@@ -607,7 +610,7 @@ batadv_dat_select_candidates(struct bata
  */
 static bool batadv_dat_send_data(struct batadv_priv *bat_priv,
 				 struct sk_buff *skb, __be32 ip,
-				 int packet_subtype)
+				 unsigned short vid, int packet_subtype)
 {
 	int i;
 	bool ret = false;
@@ -616,7 +619,7 @@ static bool batadv_dat_send_data(struct
 	struct sk_buff *tmp_skb;
 	struct batadv_dat_candidate *cand;
 
-	cand = batadv_dat_select_candidates(bat_priv, ip);
+	cand = batadv_dat_select_candidates(bat_priv, ip, vid);
 	if (!cand)
 		goto out;
 
@@ -1004,7 +1007,7 @@ bool batadv_dat_snoop_outgoing_arp_reque
 		ret = true;
 	} else {
 		/* Send the request to the DHT */
-		ret = batadv_dat_send_data(bat_priv, skb, ip_dst,
+		ret = batadv_dat_send_data(bat_priv, skb, ip_dst, vid,
 					   BATADV_P_DAT_DHT_GET);
 	}
 out:
@@ -1132,8 +1135,8 @@ void batadv_dat_snoop_outgoing_arp_reply
 	/* Send the ARP reply to the candidates for both the IP addresses that
 	 * the node obtained from the ARP reply
 	 */
-	batadv_dat_send_data(bat_priv, skb, ip_src, BATADV_P_DAT_DHT_PUT);
-	batadv_dat_send_data(bat_priv, skb, ip_dst, BATADV_P_DAT_DHT_PUT);
+	batadv_dat_send_data(bat_priv, skb, ip_src, vid, BATADV_P_DAT_DHT_PUT);
+	batadv_dat_send_data(bat_priv, skb, ip_dst, vid, BATADV_P_DAT_DHT_PUT);
 }
 
 /**
--- zfcpdump-kernel-4.4.orig/net/batman-adv/hard-interface.h
+++ zfcpdump-kernel-4.4/net/batman-adv/hard-interface.h
@@ -75,18 +75,6 @@ batadv_hardif_free_ref(struct batadv_har
 		call_rcu(&hard_iface->rcu, batadv_hardif_free_rcu);
 }
 
-/**
- * batadv_hardif_free_ref_now - decrement the hard interface refcounter and
- *  possibly free it (without rcu callback)
- * @hard_iface: the hard interface to free
- */
-static inline void
-batadv_hardif_free_ref_now(struct batadv_hard_iface *hard_iface)
-{
-	if (atomic_dec_and_test(&hard_iface->refcount))
-		batadv_hardif_free_rcu(&hard_iface->rcu);
-}
-
 static inline struct batadv_hard_iface *
 batadv_primary_if_get_selected(struct batadv_priv *bat_priv)
 {
--- zfcpdump-kernel-4.4.orig/net/batman-adv/network-coding.c
+++ zfcpdump-kernel-4.4/net/batman-adv/network-coding.c
@@ -203,28 +203,25 @@ void batadv_nc_init_orig(struct batadv_o
 }
 
 /**
- * batadv_nc_node_free_rcu - rcu callback to free an nc node and remove
- *  its refcount on the orig_node
- * @rcu: rcu pointer of the nc node
+ * batadv_nc_node_release - release nc_node from lists and queue for free after
+ *  rcu grace period
+ * @nc_node: the nc node to free
  */
-static void batadv_nc_node_free_rcu(struct rcu_head *rcu)
+static void batadv_nc_node_release(struct batadv_nc_node *nc_node)
 {
-	struct batadv_nc_node *nc_node;
-
-	nc_node = container_of(rcu, struct batadv_nc_node, rcu);
 	batadv_orig_node_free_ref(nc_node->orig_node);
-	kfree(nc_node);
+	kfree_rcu(nc_node, rcu);
 }
 
 /**
- * batadv_nc_node_free_ref - decrements the nc node refcounter and possibly
- * frees it
+ * batadv_nc_node_free_ref - decrement the nc node refcounter and possibly
+ *  release it
  * @nc_node: the nc node to free
  */
 static void batadv_nc_node_free_ref(struct batadv_nc_node *nc_node)
 {
 	if (atomic_dec_and_test(&nc_node->refcount))
-		call_rcu(&nc_node->rcu, batadv_nc_node_free_rcu);
+		batadv_nc_node_release(nc_node);
 }
 
 /**
--- zfcpdump-kernel-4.4.orig/net/batman-adv/originator.c
+++ zfcpdump-kernel-4.4/net/batman-adv/originator.c
@@ -163,92 +163,60 @@ err:
 }
 
 /**
- * batadv_neigh_ifinfo_free_rcu - free the neigh_ifinfo object
- * @rcu: rcu pointer of the neigh_ifinfo object
- */
-static void batadv_neigh_ifinfo_free_rcu(struct rcu_head *rcu)
-{
-	struct batadv_neigh_ifinfo *neigh_ifinfo;
-
-	neigh_ifinfo = container_of(rcu, struct batadv_neigh_ifinfo, rcu);
-
-	if (neigh_ifinfo->if_outgoing != BATADV_IF_DEFAULT)
-		batadv_hardif_free_ref_now(neigh_ifinfo->if_outgoing);
-
-	kfree(neigh_ifinfo);
-}
-
-/**
- * batadv_neigh_ifinfo_free_now - decrement the refcounter and possibly free
- *  the neigh_ifinfo (without rcu callback)
+ * batadv_neigh_ifinfo_release - release neigh_ifinfo from lists and queue for
+ *  free after rcu grace period
  * @neigh_ifinfo: the neigh_ifinfo object to release
  */
 static void
-batadv_neigh_ifinfo_free_ref_now(struct batadv_neigh_ifinfo *neigh_ifinfo)
+batadv_neigh_ifinfo_release(struct batadv_neigh_ifinfo *neigh_ifinfo)
 {
-	if (atomic_dec_and_test(&neigh_ifinfo->refcount))
-		batadv_neigh_ifinfo_free_rcu(&neigh_ifinfo->rcu);
+	if (neigh_ifinfo->if_outgoing != BATADV_IF_DEFAULT)
+		batadv_hardif_free_ref(neigh_ifinfo->if_outgoing);
+
+	kfree_rcu(neigh_ifinfo, rcu);
 }
 
 /**
- * batadv_neigh_ifinfo_free_ref - decrement the refcounter and possibly free
+ * batadv_neigh_ifinfo_free_ref - decrement the refcounter and possibly release
  *  the neigh_ifinfo
  * @neigh_ifinfo: the neigh_ifinfo object to release
  */
 void batadv_neigh_ifinfo_free_ref(struct batadv_neigh_ifinfo *neigh_ifinfo)
 {
 	if (atomic_dec_and_test(&neigh_ifinfo->refcount))
-		call_rcu(&neigh_ifinfo->rcu, batadv_neigh_ifinfo_free_rcu);
+		batadv_neigh_ifinfo_release(neigh_ifinfo);
 }
 
 /**
  * batadv_neigh_node_free_rcu - free the neigh_node
- * @rcu: rcu pointer of the neigh_node
+ * batadv_neigh_node_release - release neigh_node from lists and queue for
+ *  free after rcu grace period
+ * @neigh_node: neigh neighbor to free
  */
-static void batadv_neigh_node_free_rcu(struct rcu_head *rcu)
+static void batadv_neigh_node_release(struct batadv_neigh_node *neigh_node)
 {
 	struct hlist_node *node_tmp;
-	struct batadv_neigh_node *neigh_node;
 	struct batadv_neigh_ifinfo *neigh_ifinfo;
-	struct batadv_algo_ops *bao;
-
-	neigh_node = container_of(rcu, struct batadv_neigh_node, rcu);
-	bao = neigh_node->orig_node->bat_priv->bat_algo_ops;
 
 	hlist_for_each_entry_safe(neigh_ifinfo, node_tmp,
 				  &neigh_node->ifinfo_list, list) {
-		batadv_neigh_ifinfo_free_ref_now(neigh_ifinfo);
+		batadv_neigh_ifinfo_free_ref(neigh_ifinfo);
 	}
 
-	if (bao->bat_neigh_free)
-		bao->bat_neigh_free(neigh_node);
-
-	batadv_hardif_free_ref_now(neigh_node->if_incoming);
+	batadv_hardif_free_ref(neigh_node->if_incoming);
 
-	kfree(neigh_node);
-}
-
-/**
- * batadv_neigh_node_free_ref_now - decrement the neighbors refcounter
- *  and possibly free it (without rcu callback)
- * @neigh_node: neigh neighbor to free
- */
-static void
-batadv_neigh_node_free_ref_now(struct batadv_neigh_node *neigh_node)
-{
-	if (atomic_dec_and_test(&neigh_node->refcount))
-		batadv_neigh_node_free_rcu(&neigh_node->rcu);
+	kfree_rcu(neigh_node, rcu);
 }
 
 /**
  * batadv_neigh_node_free_ref - decrement the neighbors refcounter
- *  and possibly free it
+ *  and possibly release it
  * @neigh_node: neigh neighbor to free
  */
 void batadv_neigh_node_free_ref(struct batadv_neigh_node *neigh_node)
 {
 	if (atomic_dec_and_test(&neigh_node->refcount))
-		call_rcu(&neigh_node->rcu, batadv_neigh_node_free_rcu);
+		batadv_neigh_node_release(neigh_node);
 }
 
 /**
@@ -532,108 +500,99 @@ out:
 }
 
 /**
- * batadv_orig_ifinfo_free_rcu - free the orig_ifinfo object
- * @rcu: rcu pointer of the orig_ifinfo object
+ * batadv_orig_ifinfo_release - release orig_ifinfo from lists and queue for
+ *  free after rcu grace period
+ * @orig_ifinfo: the orig_ifinfo object to release
  */
-static void batadv_orig_ifinfo_free_rcu(struct rcu_head *rcu)
+static void batadv_orig_ifinfo_release(struct batadv_orig_ifinfo *orig_ifinfo)
 {
-	struct batadv_orig_ifinfo *orig_ifinfo;
 	struct batadv_neigh_node *router;
 
-	orig_ifinfo = container_of(rcu, struct batadv_orig_ifinfo, rcu);
-
 	if (orig_ifinfo->if_outgoing != BATADV_IF_DEFAULT)
-		batadv_hardif_free_ref_now(orig_ifinfo->if_outgoing);
+		batadv_hardif_free_ref(orig_ifinfo->if_outgoing);
 
 	/* this is the last reference to this object */
 	router = rcu_dereference_protected(orig_ifinfo->router, true);
 	if (router)
-		batadv_neigh_node_free_ref_now(router);
-	kfree(orig_ifinfo);
+		batadv_neigh_node_free_ref(router);
+
+	kfree_rcu(orig_ifinfo, rcu);
 }
 
 /**
- * batadv_orig_ifinfo_free_ref - decrement the refcounter and possibly free
- *  the orig_ifinfo (without rcu callback)
+ * batadv_orig_ifinfo_free_ref - decrement the refcounter and possibly release
+ *  the orig_ifinfo
  * @orig_ifinfo: the orig_ifinfo object to release
  */
-static void
-batadv_orig_ifinfo_free_ref_now(struct batadv_orig_ifinfo *orig_ifinfo)
+void batadv_orig_ifinfo_free_ref(struct batadv_orig_ifinfo *orig_ifinfo)
 {
 	if (atomic_dec_and_test(&orig_ifinfo->refcount))
-		batadv_orig_ifinfo_free_rcu(&orig_ifinfo->rcu);
+		batadv_orig_ifinfo_release(orig_ifinfo);
 }
 
 /**
- * batadv_orig_ifinfo_free_ref - decrement the refcounter and possibly free
- *  the orig_ifinfo
- * @orig_ifinfo: the orig_ifinfo object to release
+ * batadv_orig_node_free_rcu - free the orig_node
+ * @rcu: rcu pointer of the orig_node
  */
-void batadv_orig_ifinfo_free_ref(struct batadv_orig_ifinfo *orig_ifinfo)
+static void batadv_orig_node_free_rcu(struct rcu_head *rcu)
 {
-	if (atomic_dec_and_test(&orig_ifinfo->refcount))
-		call_rcu(&orig_ifinfo->rcu, batadv_orig_ifinfo_free_rcu);
+	struct batadv_orig_node *orig_node;
+
+	orig_node = container_of(rcu, struct batadv_orig_node, rcu);
+
+	batadv_mcast_purge_orig(orig_node);
+
+	batadv_frag_purge_orig(orig_node, NULL);
+
+	if (orig_node->bat_priv->bat_algo_ops->bat_orig_free)
+		orig_node->bat_priv->bat_algo_ops->bat_orig_free(orig_node);
+
+	kfree(orig_node->tt_buff);
+	kfree(orig_node);
 }
 
-static void batadv_orig_node_free_rcu(struct rcu_head *rcu)
+/**
+ * batadv_orig_node_release - release orig_node from lists and queue for
+ *  free after rcu grace period
+ * @orig_node: the orig node to free
+ */
+static void batadv_orig_node_release(struct batadv_orig_node *orig_node)
 {
 	struct hlist_node *node_tmp;
 	struct batadv_neigh_node *neigh_node;
-	struct batadv_orig_node *orig_node;
 	struct batadv_orig_ifinfo *orig_ifinfo;
 
-	orig_node = container_of(rcu, struct batadv_orig_node, rcu);
-
 	spin_lock_bh(&orig_node->neigh_list_lock);
 
 	/* for all neighbors towards this originator ... */
 	hlist_for_each_entry_safe(neigh_node, node_tmp,
 				  &orig_node->neigh_list, list) {
 		hlist_del_rcu(&neigh_node->list);
-		batadv_neigh_node_free_ref_now(neigh_node);
+		batadv_neigh_node_free_ref(neigh_node);
 	}
 
 	hlist_for_each_entry_safe(orig_ifinfo, node_tmp,
 				  &orig_node->ifinfo_list, list) {
 		hlist_del_rcu(&orig_ifinfo->list);
-		batadv_orig_ifinfo_free_ref_now(orig_ifinfo);
+		batadv_orig_ifinfo_free_ref(orig_ifinfo);
 	}
 	spin_unlock_bh(&orig_node->neigh_list_lock);
 
-	batadv_mcast_purge_orig(orig_node);
-
 	/* Free nc_nodes */
 	batadv_nc_purge_orig(orig_node->bat_priv, orig_node, NULL);
 
-	batadv_frag_purge_orig(orig_node, NULL);
-
-	if (orig_node->bat_priv->bat_algo_ops->bat_orig_free)
-		orig_node->bat_priv->bat_algo_ops->bat_orig_free(orig_node);
-
-	kfree(orig_node->tt_buff);
-	kfree(orig_node);
+	call_rcu(&orig_node->rcu, batadv_orig_node_free_rcu);
 }
 
 /**
  * batadv_orig_node_free_ref - decrement the orig node refcounter and possibly
- * schedule an rcu callback for freeing it
+ *  release it
  * @orig_node: the orig node to free
  */
 void batadv_orig_node_free_ref(struct batadv_orig_node *orig_node)
 {
 	if (atomic_dec_and_test(&orig_node->refcount))
-		call_rcu(&orig_node->rcu, batadv_orig_node_free_rcu);
-}
-
-/**
- * batadv_orig_node_free_ref_now - decrement the orig node refcounter and
- * possibly free it (without rcu callback)
- * @orig_node: the orig node to free
- */
-void batadv_orig_node_free_ref_now(struct batadv_orig_node *orig_node)
-{
-	if (atomic_dec_and_test(&orig_node->refcount))
-		batadv_orig_node_free_rcu(&orig_node->rcu);
+		batadv_orig_node_release(orig_node);
 }
 
 void batadv_originator_free(struct batadv_priv *bat_priv)
--- zfcpdump-kernel-4.4.orig/net/batman-adv/originator.h
+++ zfcpdump-kernel-4.4/net/batman-adv/originator.h
@@ -38,7 +38,6 @@ int batadv_originator_init(struct batadv
 void batadv_originator_free(struct batadv_priv *bat_priv);
 void batadv_purge_orig_ref(struct batadv_priv *bat_priv);
 void batadv_orig_node_free_ref(struct batadv_orig_node *orig_node);
-void batadv_orig_node_free_ref_now(struct batadv_orig_node *orig_node);
 struct batadv_orig_node *batadv_orig_node_new(struct batadv_priv *bat_priv,
 					      const u8 *addr);
 struct batadv_neigh_node *
--- zfcpdump-kernel-4.4.orig/net/batman-adv/routing.c
+++ zfcpdump-kernel-4.4/net/batman-adv/routing.c
@@ -104,6 +104,15 @@ static void _batadv_update_route(struct
 		neigh_node = NULL;
 
 	spin_lock_bh(&orig_node->neigh_list_lock);
+	/* curr_router used earlier may not be the current orig_ifinfo->router
+	 * anymore because it was dereferenced outside of the neigh_list_lock
+	 * protected region. After the new best neighbor has replace the current
+	 * best neighbor the reference counter needs to decrease. Consequently,
+	 * the code needs to ensure the curr_router variable contains a pointer
+	 * to the replaced best neighbor.
+	 */
+	curr_router = rcu_dereference_protected(orig_ifinfo->router, true);
+
 	rcu_assign_pointer(orig_ifinfo->router, neigh_node);
 	spin_unlock_bh(&orig_node->neigh_list_lock);
 	batadv_orig_ifinfo_free_ref(orig_ifinfo);
--- zfcpdump-kernel-4.4.orig/net/batman-adv/send.c
+++ zfcpdump-kernel-4.4/net/batman-adv/send.c
@@ -630,6 +630,9 @@ batadv_purge_outstanding_packets(struct
 
 		if (pending) {
 			hlist_del(&forw_packet->list);
+			if (!forw_packet->own)
+				atomic_inc(&bat_priv->bcast_queue_left);
+
 			batadv_forw_packet_free(forw_packet);
 		}
 	}
@@ -657,6 +660,9 @@ batadv_purge_outstanding_packets(struct
 
 		if (pending) {
 			hlist_del(&forw_packet->list);
+			if (!forw_packet->own)
+				atomic_inc(&bat_priv->batman_queue_left);
+
 			batadv_forw_packet_free(forw_packet);
 		}
 	}
--- zfcpdump-kernel-4.4.orig/net/batman-adv/soft-interface.c
+++ zfcpdump-kernel-4.4/net/batman-adv/soft-interface.c
@@ -407,11 +407,17 @@ void batadv_interface_rx(struct net_devi
 	 */
 	nf_reset(skb);
 
+	if (unlikely(!pskb_may_pull(skb, ETH_HLEN)))
+		goto dropped;
+
 	vid = batadv_get_vid(skb, 0);
 	ethhdr = eth_hdr(skb);
 
 	switch (ntohs(ethhdr->h_proto)) {
 	case ETH_P_8021Q:
+		if (!pskb_may_pull(skb, VLAN_ETH_HLEN))
+			goto dropped;
+
 		vhdr = (struct vlan_ethhdr *)skb->data;
 
 		if (vhdr->h_vlan_encapsulated_proto != ethertype)
@@ -423,8 +429,6 @@ void batadv_interface_rx(struct net_devi
 	}
 
 	/* skb->dev & skb->pkt_type are set here */
-	if (unlikely(!pskb_may_pull(skb, ETH_HLEN)))
-		goto dropped;
 	skb->protocol = eth_type_trans(skb, soft_iface);
 
 	/* should not be necessary anymore as we use skb_pull_rcsum()
--- zfcpdump-kernel-4.4.orig/net/batman-adv/translation-table.c
+++ zfcpdump-kernel-4.4/net/batman-adv/translation-table.c
@@ -240,20 +240,6 @@ int batadv_tt_global_hash_count(struct b
 	return count;
 }
 
-static void batadv_tt_orig_list_entry_free_rcu(struct rcu_head *rcu)
-{
-	struct batadv_tt_orig_list_entry *orig_entry;
-
-	orig_entry = container_of(rcu, struct batadv_tt_orig_list_entry, rcu);
-
-	/* We are in an rcu callback here, therefore we cannot use
-	 * batadv_orig_node_free_ref() and its call_rcu():
-	 * An rcu_barrier() wouldn't wait for that to finish
-	 */
-	batadv_orig_node_free_ref_now(orig_entry->orig_node);
-	kfree(orig_entry);
-}
-
 /**
  * batadv_tt_local_size_mod - change the size by v of the local table identified
  *  by vid
@@ -349,13 +335,25 @@ static void batadv_tt_global_size_dec(st
 	batadv_tt_global_size_mod(orig_node, vid, -1);
 }
 
+/**
+ * batadv_tt_orig_list_entry_release - release tt orig entry from lists and
+ *  queue for free after rcu grace period
+ * @orig_entry: tt orig entry to be free'd
+ */
+static void
+batadv_tt_orig_list_entry_release(struct batadv_tt_orig_list_entry *orig_entry)
+{
+	batadv_orig_node_free_ref(orig_entry->orig_node);
+	kfree_rcu(orig_entry, rcu);
+}
+
 static void
 batadv_tt_orig_list_entry_free_ref(struct batadv_tt_orig_list_entry *orig_entry)
 {
 	if (!atomic_dec_and_test(&orig_entry->refcount))
 		return;
 
-	call_rcu(&orig_entry->rcu, batadv_tt_orig_list_entry_free_rcu);
+	batadv_tt_orig_list_entry_release(orig_entry);
 }
 
 /**
--- zfcpdump-kernel-4.4.orig/net/batman-adv/types.h
+++ zfcpdump-kernel-4.4/net/batman-adv/types.h
@@ -1136,8 +1136,6 @@ struct batadv_forw_packet {
  * @bat_neigh_is_equiv_or_better: check if neigh1 is equally good or better
  *  than neigh2 for their respective outgoing interface from the metric
  *  prospective
- * @bat_neigh_free: free the resources allocated by the routing algorithm for a
- *  neigh_node object
  * @bat_orig_print: print the originator table (optional)
  * @bat_orig_free: free the resources allocated by the routing algorithm for an
  *  orig_node object
@@ -1165,7 +1163,6 @@ struct batadv_algo_ops {
 		 struct batadv_hard_iface *if_outgoing1,
 		 struct batadv_neigh_node *neigh2,
 		 struct batadv_hard_iface *if_outgoing2);
-	void (*bat_neigh_free)(struct batadv_neigh_node *neigh);
 	/* orig_node handling API */
 	void (*bat_orig_print)(struct batadv_priv *priv, struct seq_file *seq,
 			       struct batadv_hard_iface *hard_iface);
--- zfcpdump-kernel-4.4.orig/net/bluetooth/6lowpan.c
+++ zfcpdump-kernel-4.4/net/bluetooth/6lowpan.c
@@ -307,6 +307,9 @@ static int recv_pkt(struct sk_buff *skb,
 
 	/* check that it's our buffer */
 	if (lowpan_is_ipv6(*skb_network_header(skb))) {
+		/* Pull off the 1-byte of 6lowpan header. */
+		skb_pull(skb, 1);
+
 		/* Copy the packet so that the IPv6 header is
 		 * properly aligned.
 		 */
@@ -317,6 +320,7 @@ static int recv_pkt(struct sk_buff *skb,
 
 		local_skb->protocol = htons(ETH_P_IPV6);
 		local_skb->pkt_type = PACKET_HOST;
+		local_skb->dev = dev;
 
 		skb_set_transport_header(local_skb, sizeof(struct ipv6hdr));
 
@@ -335,6 +339,8 @@ static int recv_pkt(struct sk_buff *skb,
 		if (!local_skb)
 			goto drop;
 
+		local_skb->dev = dev;
+
 		ret = iphc_decompress(local_skb, dev, chan);
 		if (ret < 0) {
 			kfree_skb(local_skb);
@@ -343,7 +349,6 @@ static int recv_pkt(struct sk_buff *skb,
 
 		local_skb->protocol = htons(ETH_P_IPV6);
 		local_skb->pkt_type = PACKET_HOST;
-		local_skb->dev = dev;
 
 		if (give_skb_to_upper(local_skb, dev)
 				!= NET_RX_SUCCESS) {
--- zfcpdump-kernel-4.4.orig/net/bluetooth/hci_conn.c
+++ zfcpdump-kernel-4.4/net/bluetooth/hci_conn.c
@@ -722,8 +722,12 @@ static void hci_req_add_le_create_conn(s
 	if (hci_update_random_address(req, false, &own_addr_type))
 		return;
 
+	/* Set window to be the same value as the interval to enable
+	 * continuous scanning.
+	 */
 	cp.scan_interval = cpu_to_le16(hdev->le_scan_interval);
-	cp.scan_window = cpu_to_le16(hdev->le_scan_window);
+	cp.scan_window = cp.scan_interval;
+
 	bacpy(&cp.peer_addr, &conn->dst);
 	cp.peer_addr_type = conn->dst_type;
 	cp.own_address_type = own_addr_type;
--- zfcpdump-kernel-4.4.orig/net/bluetooth/hci_core.c
+++ zfcpdump-kernel-4.4/net/bluetooth/hci_core.c
@@ -1532,6 +1532,8 @@ static int hci_dev_do_open(struct hci_de
 			mgmt_powered(hdev, 1);
 			hci_dev_unlock(hdev);
 		}
+		if (hdev->post_open)
+			hdev->post_open(hdev);
 	} else {
 		/* Init failed, cleanup */
 		flush_work(&hdev->tx_work);
--- zfcpdump-kernel-4.4.orig/net/bluetooth/hci_request.c
+++ zfcpdump-kernel-4.4/net/bluetooth/hci_request.c
@@ -175,21 +175,29 @@ static u8 update_white_list(struct hci_r
 	 * command to remove it from the controller.
 	 */
 	list_for_each_entry(b, &hdev->le_white_list, list) {
-		struct hci_cp_le_del_from_white_list cp;
+		/* If the device is neither in pend_le_conns nor
+		 * pend_le_reports then remove it from the whitelist.
+		 */
+		if (!hci_pend_le_action_lookup(&hdev->pend_le_conns,
+					       &b->bdaddr, b->bdaddr_type) &&
+		    !hci_pend_le_action_lookup(&hdev->pend_le_reports,
+					       &b->bdaddr, b->bdaddr_type)) {
+			struct hci_cp_le_del_from_white_list cp;
 
-		if (hci_pend_le_action_lookup(&hdev->pend_le_conns,
-					      &b->bdaddr, b->bdaddr_type) ||
-		    hci_pend_le_action_lookup(&hdev->pend_le_reports,
-					      &b->bdaddr, b->bdaddr_type)) {
-			white_list_entries++;
+			cp.bdaddr_type = b->bdaddr_type;
+			bacpy(&cp.bdaddr, &b->bdaddr);
+
+			hci_req_add(req, HCI_OP_LE_DEL_FROM_WHITE_LIST,
+				    sizeof(cp), &cp);
 			continue;
 		}
 
-		cp.bdaddr_type = b->bdaddr_type;
-		bacpy(&cp.bdaddr, &b->bdaddr);
+		if (hci_find_irk_by_addr(hdev, &b->bdaddr, b->bdaddr_type)) {
+			/* White list can not be used with RPAs */
+			return 0x00;
+		}
 
-		hci_req_add(req, HCI_OP_LE_DEL_FROM_WHITE_LIST,
-			    sizeof(cp), &cp);
+		white_list_entries++;
 	}
 
 	/* Since all no longer valid white list entries have been
--- zfcpdump-kernel-4.4.orig/net/bluetooth/l2cap_sock.c
+++ zfcpdump-kernel-4.4/net/bluetooth/l2cap_sock.c
@@ -927,7 +927,7 @@ static int l2cap_sock_setsockopt(struct
 			break;
 		}
 
-		if (get_user(opt, (u32 __user *) optval)) {
+		if (get_user(opt, (u16 __user *) optval)) {
 			err = -EFAULT;
 			break;
 		}
--- zfcpdump-kernel-4.4.orig/net/bluetooth/mgmt.c
+++ zfcpdump-kernel-4.4/net/bluetooth/mgmt.c
@@ -7155,6 +7155,10 @@ static int add_advertising(struct sock *
 		return mgmt_cmd_status(sk, hdev->id, MGMT_OP_ADD_ADVERTISING,
 				       status);
 
+	if (data_len != sizeof(*cp) + cp->adv_data_len + cp->scan_rsp_len)
+		return mgmt_cmd_status(sk, hdev->id, MGMT_OP_ADD_ADVERTISING,
+				       MGMT_STATUS_INVALID_PARAMS);
+
 	flags = __le32_to_cpu(cp->flags);
 	timeout = __le16_to_cpu(cp->timeout);
 	duration = __le16_to_cpu(cp->duration);
--- zfcpdump-kernel-4.4.orig/net/bluetooth/smp.c
+++ zfcpdump-kernel-4.4/net/bluetooth/smp.c
@@ -1072,22 +1072,6 @@ static void smp_notify_keys(struct l2cap
 			hcon->dst_type = smp->remote_irk->addr_type;
 			queue_work(hdev->workqueue, &conn->id_addr_update_work);
 		}
-
-		/* When receiving an indentity resolving key for
-		 * a remote device that does not use a resolvable
-		 * private address, just remove the key so that
-		 * it is possible to use the controller white
-		 * list for scanning.
-		 *
-		 * Userspace will have been told to not store
-		 * this key at this point. So it is safe to
-		 * just remove it.
-		 */
-		if (!bacmp(&smp->remote_irk->rpa, BDADDR_ANY)) {
-			list_del_rcu(&smp->remote_irk->list);
-			kfree_rcu(smp->remote_irk, rcu);
-			smp->remote_irk = NULL;
-		}
 	}
 
 	if (smp->csrk) {
--- zfcpdump-kernel-4.4.orig/net/bridge/br.c
+++ zfcpdump-kernel-4.4/net/bridge/br.c
@@ -121,6 +121,7 @@ static struct notifier_block br_device_n
 	.notifier_call = br_device_event
 };
 
+/* called with RTNL */
 static int br_switchdev_event(struct notifier_block *unused,
 			      unsigned long event, void *ptr)
 {
@@ -130,7 +131,6 @@ static int br_switchdev_event(struct not
 	struct switchdev_notifier_fdb_info *fdb_info;
 	int err = NOTIFY_DONE;
 
-	rtnl_lock();
 	p = br_port_get_rtnl(dev);
 	if (!p)
 		goto out;
@@ -155,7 +155,6 @@ static int br_switchdev_event(struct not
 	}
 
 out:
-	rtnl_unlock();
 	return err;
 }
 
--- zfcpdump-kernel-4.4.orig/net/bridge/br_device.c
+++ zfcpdump-kernel-4.4/net/bridge/br_device.c
@@ -28,6 +28,8 @@
 const struct nf_br_ops __rcu *nf_br_ops __read_mostly;
 EXPORT_SYMBOL_GPL(nf_br_ops);
 
+static struct lock_class_key bridge_netdev_addr_lock_key;
+
 /* net device transmit always called with BH disabled */
 netdev_tx_t br_dev_xmit(struct sk_buff *skb, struct net_device *dev)
 {
@@ -87,6 +89,11 @@ out:
 	return NETDEV_TX_OK;
 }
 
+static void br_set_lockdep_class(struct net_device *dev)
+{
+	lockdep_set_class(&dev->addr_list_lock, &bridge_netdev_addr_lock_key);
+}
+
 static int br_dev_init(struct net_device *dev)
 {
 	struct net_bridge *br = netdev_priv(dev);
@@ -99,6 +106,7 @@ static int br_dev_init(struct net_device
 	err = br_vlan_init(br);
 	if (err)
 		free_percpu(br->stats);
+	br_set_lockdep_class(dev);
 
 	return err;
 }
--- zfcpdump-kernel-4.4.orig/net/bridge/br_fdb.c
+++ zfcpdump-kernel-4.4/net/bridge/br_fdb.c
@@ -278,6 +278,8 @@ void br_fdb_change_mac_address(struct ne
 	 * change from under us.
 	 */
 	list_for_each_entry(v, &vg->vlan_list, vlist) {
+		if (!br_vlan_should_use(v))
+			continue;
 		f = __br_fdb_get(br, br->dev->dev_addr, v->vid);
 		if (f && f->is_local && !f->dst)
 			fdb_delete_local(br, NULL, f);
--- zfcpdump-kernel-4.4.orig/net/bridge/br_ioctl.c
+++ zfcpdump-kernel-4.4/net/bridge/br_ioctl.c
@@ -21,18 +21,19 @@
 #include <asm/uaccess.h>
 #include "br_private.h"
 
-/* called with RTNL */
 static int get_bridge_ifindices(struct net *net, int *indices, int num)
 {
 	struct net_device *dev;
 	int i = 0;
 
-	for_each_netdev(net, dev) {
+	rcu_read_lock();
+	for_each_netdev_rcu(net, dev) {
 		if (i >= num)
 			break;
 		if (dev->priv_flags & IFF_EBRIDGE)
 			indices[i++] = dev->ifindex;
 	}
+	rcu_read_unlock();
 
 	return i;
 }
--- zfcpdump-kernel-4.4.orig/net/bridge/br_multicast.c
+++ zfcpdump-kernel-4.4/net/bridge/br_multicast.c
@@ -464,8 +464,11 @@ static struct sk_buff *br_ip6_multicast_
 	if (ipv6_dev_get_saddr(dev_net(br->dev), br->dev, &ip6h->daddr, 0,
 			       &ip6h->saddr)) {
 		kfree_skb(skb);
+		br->has_ipv6_addr = 0;
 		return NULL;
 	}
+
+	br->has_ipv6_addr = 1;
 	ipv6_eth_mc_map(&ip6h->daddr, eth->h_dest);
 
 	hopopt = (u8 *)(ip6h + 1);
@@ -1110,7 +1113,7 @@ static int br_ip6_multicast_mld2_report(
 		} else {
 			err = br_ip6_multicast_add_group(br, port,
 							 &grec->grec_mca, vid);
-			if (!err)
+			if (err)
 				break;
 		}
 	}
@@ -1270,6 +1273,7 @@ static int br_ip4_multicast_query(struct
 	struct br_ip saddr;
 	unsigned long max_delay;
 	unsigned long now = jiffies;
+	unsigned int offset = skb_transport_offset(skb);
 	__be32 group;
 	int err = 0;
 
@@ -1280,14 +1284,14 @@ static int br_ip4_multicast_query(struct
 
 	group = ih->group;
 
-	if (skb->len == sizeof(*ih)) {
+	if (skb->len == offset + sizeof(*ih)) {
 		max_delay = ih->code * (HZ / IGMP_TIMER_SCALE);
 
 		if (!max_delay) {
 			max_delay = 10 * HZ;
 			group = 0;
 		}
-	} else if (skb->len >= sizeof(*ih3)) {
+	} else if (skb->len >= offset + sizeof(*ih3)) {
 		ih3 = igmpv3_query_hdr(skb);
 		if (ih3->nsrcs)
 			goto out;
@@ -1348,6 +1352,7 @@ static int br_ip6_multicast_query(struct
 	struct br_ip saddr;
 	unsigned long max_delay;
 	unsigned long now = jiffies;
+	unsigned int offset = skb_transport_offset(skb);
 	const struct in6_addr *group = NULL;
 	bool is_general_query;
 	int err = 0;
@@ -1357,8 +1362,8 @@ static int br_ip6_multicast_query(struct
 	    (port && port->state == BR_STATE_DISABLED))
 		goto out;
 
-	if (skb->len == sizeof(*mld)) {
-		if (!pskb_may_pull(skb, sizeof(*mld))) {
+	if (skb->len == offset + sizeof(*mld)) {
+		if (!pskb_may_pull(skb, offset + sizeof(*mld))) {
 			err = -EINVAL;
 			goto out;
 		}
@@ -1367,7 +1372,7 @@ static int br_ip6_multicast_query(struct
 		if (max_delay)
 			group = &mld->mld_mca;
 	} else {
-		if (!pskb_may_pull(skb, sizeof(*mld2q))) {
+		if (!pskb_may_pull(skb, offset + sizeof(*mld2q))) {
 			err = -EINVAL;
 			goto out;
 		}
@@ -1734,6 +1739,7 @@ void br_multicast_init(struct net_bridge
 	br->ip6_other_query.delay_time = 0;
 	br->ip6_querier.port = NULL;
 #endif
+	br->has_ipv6_addr = 1;
 
 	spin_lock_init(&br->multicast_lock);
 	setup_timer(&br->multicast_router_timer,
--- zfcpdump-kernel-4.4.orig/net/bridge/br_private.h
+++ zfcpdump-kernel-4.4/net/bridge/br_private.h
@@ -301,6 +301,7 @@ struct net_bridge
 	u8				multicast_disabled:1;
 	u8				multicast_querier:1;
 	u8				multicast_query_use_ifaddr:1;
+	u8				has_ipv6_addr:1;
 
 	u32				hash_elasticity;
 	u32				hash_max;
@@ -574,10 +575,22 @@ static inline bool br_multicast_is_route
 
 static inline bool
 __br_multicast_querier_exists(struct net_bridge *br,
-			      struct bridge_mcast_other_query *querier)
+				struct bridge_mcast_other_query *querier,
+				const bool is_ipv6)
 {
+	bool own_querier_enabled;
+
+	if (br->multicast_querier) {
+		if (is_ipv6 && !br->has_ipv6_addr)
+			own_querier_enabled = false;
+		else
+			own_querier_enabled = true;
+	} else {
+		own_querier_enabled = false;
+	}
+
 	return time_is_before_jiffies(querier->delay_time) &&
-	       (br->multicast_querier || timer_pending(&querier->timer));
+	       (own_querier_enabled || timer_pending(&querier->timer));
 }
 
 static inline bool br_multicast_querier_exists(struct net_bridge *br,
@@ -585,10 +598,12 @@ static inline bool br_multicast_querier_
 {
 	switch (eth->h_proto) {
 	case (htons(ETH_P_IP)):
-		return __br_multicast_querier_exists(br, &br->ip4_other_query);
+		return __br_multicast_querier_exists(br,
+			&br->ip4_other_query, false);
 #if IS_ENABLED(CONFIG_IPV6)
 	case (htons(ETH_P_IPV6)):
-		return __br_multicast_querier_exists(br, &br->ip6_other_query);
+		return __br_multicast_querier_exists(br,
+			&br->ip6_other_query, true);
 #endif
 	default:
 		return false;
--- zfcpdump-kernel-4.4.orig/net/bridge/br_stp.c
+++ zfcpdump-kernel-4.4/net/bridge/br_stp.c
@@ -567,6 +567,14 @@ int br_set_max_age(struct net_bridge *br
 
 }
 
+/* Set time interval that dynamic forwarding entries live
+ * For pure software bridge, allow values outside the 802.1
+ * standard specification for special cases:
+ *  0 - entry never ages (all permanant)
+ *  1 - entry disappears (no persistance)
+ *
+ * Offloaded switch entries maybe more restrictive
+ */
 int br_set_ageing_time(struct net_bridge *br, u32 ageing_time)
 {
 	struct switchdev_attr attr = {
@@ -577,11 +585,8 @@ int br_set_ageing_time(struct net_bridge
 	unsigned long t = clock_t_to_jiffies(ageing_time);
 	int err;
 
-	if (t < BR_MIN_AGEING_TIME || t > BR_MAX_AGEING_TIME)
-		return -ERANGE;
-
 	err = switchdev_port_attr_set(br->dev, &attr);
-	if (err)
+	if (err && err != -EOPNOTSUPP)
 		return err;
 
 	br->ageing_time = t;
--- zfcpdump-kernel-4.4.orig/net/caif/cfpkt_skbuff.c
+++ zfcpdump-kernel-4.4/net/caif/cfpkt_skbuff.c
@@ -286,7 +286,7 @@ int cfpkt_setlen(struct cfpkt *pkt, u16
 		else
 			skb_trim(skb, len);
 
-			return cfpkt_getlen(pkt);
+		return cfpkt_getlen(pkt);
 	}
 
 	/* Need to expand SKB */
--- zfcpdump-kernel-4.4.orig/net/ceph/messenger.c
+++ zfcpdump-kernel-4.4/net/ceph/messenger.c
@@ -672,6 +672,8 @@ static void reset_connection(struct ceph
 	}
 	con->in_seq = 0;
 	con->in_seq_acked = 0;
+
+	con->out_skip = 0;
 }
 
 /*
@@ -771,6 +773,8 @@ static u32 get_global_seq(struct ceph_me
 
 static void con_out_kvec_reset(struct ceph_connection *con)
 {
+	BUG_ON(con->out_skip);
+
 	con->out_kvec_left = 0;
 	con->out_kvec_bytes = 0;
 	con->out_kvec_cur = &con->out_kvec[0];
@@ -779,9 +783,9 @@ static void con_out_kvec_reset(struct ce
 static void con_out_kvec_add(struct ceph_connection *con,
 				size_t size, void *data)
 {
-	int index;
+	int index = con->out_kvec_left;
 
-	index = con->out_kvec_left;
+	BUG_ON(con->out_skip);
 	BUG_ON(index >= ARRAY_SIZE(con->out_kvec));
 
 	con->out_kvec[index].iov_len = size;
@@ -790,6 +794,27 @@ static void con_out_kvec_add(struct ceph
 	con->out_kvec_bytes += size;
 }
 
+/*
+ * Chop off a kvec from the end.  Return residual number of bytes for
+ * that kvec, i.e. how many bytes would have been written if the kvec
+ * hadn't been nuked.
+ */
+static int con_out_kvec_skip(struct ceph_connection *con)
+{
+	int off = con->out_kvec_cur - con->out_kvec;
+	int skip = 0;
+
+	if (con->out_kvec_bytes > 0) {
+		skip = con->out_kvec[off + con->out_kvec_left - 1].iov_len;
+		BUG_ON(con->out_kvec_bytes < skip);
+		BUG_ON(!con->out_kvec_left);
+		con->out_kvec_bytes -= skip;
+		con->out_kvec_left--;
+	}
+
+	return skip;
+}
+
 #ifdef CONFIG_BLOCK
 
 /*
@@ -1175,6 +1200,13 @@ static bool ceph_msg_data_advance(struct
 	return new_piece;
 }
 
+static size_t sizeof_footer(struct ceph_connection *con)
+{
+	return (con->peer_features & CEPH_FEATURE_MSG_AUTH) ?
+	    sizeof(struct ceph_msg_footer) :
+	    sizeof(struct ceph_msg_footer_old);
+}
+
 static void prepare_message_data(struct ceph_msg *msg, u32 data_len)
 {
 	BUG_ON(!msg);
@@ -1197,7 +1229,6 @@ static void prepare_write_message_footer
 	m->footer.flags |= CEPH_MSG_FOOTER_COMPLETE;
 
 	dout("prepare_write_message_footer %p\n", con);
-	con->out_kvec_is_msg = true;
 	con->out_kvec[v].iov_base = &m->footer;
 	if (con->peer_features & CEPH_FEATURE_MSG_AUTH) {
 		if (con->ops->sign_message)
@@ -1225,7 +1256,6 @@ static void prepare_write_message(struct
 	u32 crc;
 
 	con_out_kvec_reset(con);
-	con->out_kvec_is_msg = true;
 	con->out_msg_done = false;
 
 	/* Sneak an ack in there first?  If we can get it into the same
@@ -1265,18 +1295,19 @@ static void prepare_write_message(struct
 
 	/* tag + hdr + front + middle */
 	con_out_kvec_add(con, sizeof (tag_msg), &tag_msg);
-	con_out_kvec_add(con, sizeof (m->hdr), &m->hdr);
+	con_out_kvec_add(con, sizeof(con->out_hdr), &con->out_hdr);
 	con_out_kvec_add(con, m->front.iov_len, m->front.iov_base);
 
 	if (m->middle)
 		con_out_kvec_add(con, m->middle->vec.iov_len,
 			m->middle->vec.iov_base);
 
-	/* fill in crc (except data pages), footer */
+	/* fill in hdr crc and finalize hdr */
 	crc = crc32c(0, &m->hdr, offsetof(struct ceph_msg_header, crc));
 	con->out_msg->hdr.crc = cpu_to_le32(crc);
-	con->out_msg->footer.flags = 0;
+	memcpy(&con->out_hdr, &con->out_msg->hdr, sizeof(con->out_hdr));
 
+	/* fill in front and middle crc, footer */
 	crc = crc32c(0, m->front.iov_base, m->front.iov_len);
 	con->out_msg->footer.front_crc = cpu_to_le32(crc);
 	if (m->middle) {
@@ -1288,6 +1319,7 @@ static void prepare_write_message(struct
 	dout("%s front_crc %u middle_crc %u\n", __func__,
 	     le32_to_cpu(con->out_msg->footer.front_crc),
 	     le32_to_cpu(con->out_msg->footer.middle_crc));
+	con->out_msg->footer.flags = 0;
 
 	/* is there a data payload? */
 	con->out_msg->footer.data_crc = 0;
@@ -1492,7 +1524,6 @@ static int write_partial_kvec(struct cep
 		}
 	}
 	con->out_kvec_left = 0;
-	con->out_kvec_is_msg = false;
 	ret = 1;
 out:
 	dout("write_partial_kvec %p %d left in %d kvecs ret = %d\n", con,
@@ -1584,6 +1615,7 @@ static int write_partial_skip(struct cep
 {
 	int ret;
 
+	dout("%s %p %d left\n", __func__, con, con->out_skip);
 	while (con->out_skip > 0) {
 		size_t size = min(con->out_skip, (int) PAGE_CACHE_SIZE);
 
@@ -2313,9 +2345,9 @@ static int read_partial_message(struct c
 			ceph_pr_addr(&con->peer_addr.in_addr),
 			seq, con->in_seq + 1);
 		con->in_base_pos = -front_len - middle_len - data_len -
-			sizeof(m->footer);
+			sizeof_footer(con);
 		con->in_tag = CEPH_MSGR_TAG_READY;
-		return 0;
+		return 1;
 	} else if ((s64)seq - (s64)con->in_seq > 1) {
 		pr_err("read_partial_message bad seq %lld expected %lld\n",
 		       seq, con->in_seq + 1);
@@ -2338,10 +2370,10 @@ static int read_partial_message(struct c
 			/* skip this message */
 			dout("alloc_msg said skip message\n");
 			con->in_base_pos = -front_len - middle_len - data_len -
-				sizeof(m->footer);
+				sizeof_footer(con);
 			con->in_tag = CEPH_MSGR_TAG_READY;
 			con->in_seq++;
-			return 0;
+			return 1;
 		}
 
 		BUG_ON(!con->in_msg);
@@ -2506,13 +2538,13 @@ more:
 
 more_kvec:
 	/* kvec data queued? */
-	if (con->out_skip) {
-		ret = write_partial_skip(con);
+	if (con->out_kvec_left) {
+		ret = write_partial_kvec(con);
 		if (ret <= 0)
 			goto out;
 	}
-	if (con->out_kvec_left) {
-		ret = write_partial_kvec(con);
+	if (con->out_skip) {
+		ret = write_partial_skip(con);
 		if (ret <= 0)
 			goto out;
 	}
@@ -3050,16 +3082,31 @@ void ceph_msg_revoke(struct ceph_msg *ms
 		ceph_msg_put(msg);
 	}
 	if (con->out_msg == msg) {
-		dout("%s %p msg %p - was sending\n", __func__, con, msg);
-		con->out_msg = NULL;
-		if (con->out_kvec_is_msg) {
-			con->out_skip = con->out_kvec_bytes;
-			con->out_kvec_is_msg = false;
-		}
-		msg->hdr.seq = 0;
+		BUG_ON(con->out_skip);
+		/* footer */
+		if (con->out_msg_done) {
+			con->out_skip += con_out_kvec_skip(con);
+		} else {
+			BUG_ON(!msg->data_length);
+			if (con->peer_features & CEPH_FEATURE_MSG_AUTH)
+				con->out_skip += sizeof(msg->footer);
+			else
+				con->out_skip += sizeof(msg->old_footer);
+		}
+		/* data, middle, front */
+		if (msg->data_length)
+			con->out_skip += msg->cursor.total_resid;
+		if (msg->middle)
+			con->out_skip += con_out_kvec_skip(con);
+		con->out_skip += con_out_kvec_skip(con);
 
+		dout("%s %p msg %p - was sending, will write %d skip %d\n",
+		     __func__, con, msg, con->out_kvec_bytes, con->out_skip);
+		msg->hdr.seq = 0;
+		con->out_msg = NULL;
 		ceph_msg_put(msg);
 	}
+
 	mutex_unlock(&con->mutex);
 }
 
--- zfcpdump-kernel-4.4.orig/net/ceph/osd_client.c
+++ zfcpdump-kernel-4.4/net/ceph/osd_client.c
@@ -2843,8 +2843,8 @@ static struct ceph_msg *get_reply(struct
 	mutex_lock(&osdc->request_mutex);
 	req = __lookup_request(osdc, tid);
 	if (!req) {
-		pr_warn("%s osd%d tid %llu unknown, skipping\n",
-			__func__, osd->o_osd, tid);
+		dout("%s osd%d tid %llu unknown, skipping\n", __func__,
+		     osd->o_osd, tid);
 		m = NULL;
 		*skip = 1;
 		goto out;
--- zfcpdump-kernel-4.4.orig/net/ceph/osdmap.c
+++ zfcpdump-kernel-4.4/net/ceph/osdmap.c
@@ -1192,6 +1192,115 @@ struct ceph_osdmap *ceph_osdmap_decode(v
 }
 
 /*
+ * Encoding order is (new_up_client, new_state, new_weight).  Need to
+ * apply in the (new_weight, new_state, new_up_client) order, because
+ * an incremental map may look like e.g.
+ *
+ *     new_up_client: { osd=6, addr=... } # set osd_state and addr
+ *     new_state: { osd=6, xorstate=EXISTS } # clear osd_state
+ */
+static int decode_new_up_state_weight(void **p, void *end,
+				      struct ceph_osdmap *map)
+{
+	void *new_up_client;
+	void *new_state;
+	void *new_weight_end;
+	u32 len;
+
+	new_up_client = *p;
+	ceph_decode_32_safe(p, end, len, e_inval);
+	len *= sizeof(u32) + sizeof(struct ceph_entity_addr);
+	ceph_decode_need(p, end, len, e_inval);
+	*p += len;
+
+	new_state = *p;
+	ceph_decode_32_safe(p, end, len, e_inval);
+	len *= sizeof(u32) + sizeof(u8);
+	ceph_decode_need(p, end, len, e_inval);
+	*p += len;
+
+	/* new_weight */
+	ceph_decode_32_safe(p, end, len, e_inval);
+	while (len--) {
+		s32 osd;
+		u32 w;
+
+		ceph_decode_need(p, end, 2*sizeof(u32), e_inval);
+		osd = ceph_decode_32(p);
+		w = ceph_decode_32(p);
+		BUG_ON(osd >= map->max_osd);
+		pr_info("osd%d weight 0x%x %s\n", osd, w,
+		     w == CEPH_OSD_IN ? "(in)" :
+		     (w == CEPH_OSD_OUT ? "(out)" : ""));
+		map->osd_weight[osd] = w;
+
+		/*
+		 * If we are marking in, set the EXISTS, and clear the
+		 * AUTOOUT and NEW bits.
+		 */
+		if (w) {
+			map->osd_state[osd] |= CEPH_OSD_EXISTS;
+			map->osd_state[osd] &= ~(CEPH_OSD_AUTOOUT |
+						 CEPH_OSD_NEW);
+		}
+	}
+	new_weight_end = *p;
+
+	/* new_state (up/down) */
+	*p = new_state;
+	len = ceph_decode_32(p);
+	while (len--) {
+		s32 osd;
+		u8 xorstate;
+		int ret;
+
+		osd = ceph_decode_32(p);
+		xorstate = ceph_decode_8(p);
+		if (xorstate == 0)
+			xorstate = CEPH_OSD_UP;
+		BUG_ON(osd >= map->max_osd);
+		if ((map->osd_state[osd] & CEPH_OSD_UP) &&
+		    (xorstate & CEPH_OSD_UP))
+			pr_info("osd%d down\n", osd);
+		if ((map->osd_state[osd] & CEPH_OSD_EXISTS) &&
+		    (xorstate & CEPH_OSD_EXISTS)) {
+			pr_info("osd%d does not exist\n", osd);
+			map->osd_weight[osd] = CEPH_OSD_IN;
+			ret = set_primary_affinity(map, osd,
+						   CEPH_OSD_DEFAULT_PRIMARY_AFFINITY);
+			if (ret)
+				return ret;
+			memset(map->osd_addr + osd, 0, sizeof(*map->osd_addr));
+			map->osd_state[osd] = 0;
+		} else {
+			map->osd_state[osd] ^= xorstate;
+		}
+	}
+
+	/* new_up_client */
+	*p = new_up_client;
+	len = ceph_decode_32(p);
+	while (len--) {
+		s32 osd;
+		struct ceph_entity_addr addr;
+
+		osd = ceph_decode_32(p);
+		ceph_decode_copy(p, &addr, sizeof(addr));
+		ceph_decode_addr(&addr);
+		BUG_ON(osd >= map->max_osd);
+		pr_info("osd%d up\n", osd);
+		map->osd_state[osd] |= CEPH_OSD_EXISTS | CEPH_OSD_UP;
+		map->osd_addr[osd] = addr;
+	}
+
+	*p = new_weight_end;
+	return 0;
+
+e_inval:
+	return -EINVAL;
+}
+
+/*
  * decode and apply an incremental map update.
  */
 struct ceph_osdmap *osdmap_apply_incremental(void **p, void *end,
@@ -1290,49 +1399,10 @@ struct ceph_osdmap *osdmap_apply_increme
 			__remove_pg_pool(&map->pg_pools, pi);
 	}
 
-	/* new_up */
-	ceph_decode_32_safe(p, end, len, e_inval);
-	while (len--) {
-		u32 osd;
-		struct ceph_entity_addr addr;
-		ceph_decode_32_safe(p, end, osd, e_inval);
-		ceph_decode_copy_safe(p, end, &addr, sizeof(addr), e_inval);
-		ceph_decode_addr(&addr);
-		pr_info("osd%d up\n", osd);
-		BUG_ON(osd >= map->max_osd);
-		map->osd_state[osd] |= CEPH_OSD_UP | CEPH_OSD_EXISTS;
-		map->osd_addr[osd] = addr;
-	}
-
-	/* new_state */
-	ceph_decode_32_safe(p, end, len, e_inval);
-	while (len--) {
-		u32 osd;
-		u8 xorstate;
-		ceph_decode_32_safe(p, end, osd, e_inval);
-		xorstate = **(u8 **)p;
-		(*p)++;  /* clean flag */
-		if (xorstate == 0)
-			xorstate = CEPH_OSD_UP;
-		if (xorstate & CEPH_OSD_UP)
-			pr_info("osd%d down\n", osd);
-		if (osd < map->max_osd)
-			map->osd_state[osd] ^= xorstate;
-	}
-
-	/* new_weight */
-	ceph_decode_32_safe(p, end, len, e_inval);
-	while (len--) {
-		u32 osd, off;
-		ceph_decode_need(p, end, sizeof(u32)*2, e_inval);
-		osd = ceph_decode_32(p);
-		off = ceph_decode_32(p);
-		pr_info("osd%d weight 0x%x %s\n", osd, off,
-		     off == CEPH_OSD_IN ? "(in)" :
-		     (off == CEPH_OSD_OUT ? "(out)" : ""));
-		if (osd < map->max_osd)
-			map->osd_weight[osd] = off;
-	}
+	/* new_up_client, new_state, new_weight */
+	err = decode_new_up_state_weight(p, end, map);
+	if (err)
+		goto bad;
 
 	/* new_pg_temp */
 	err = decode_new_pg_temp(p, end, map);
--- zfcpdump-kernel-4.4.orig/net/core/dev.c
+++ zfcpdump-kernel-4.4/net/core/dev.c
@@ -2542,6 +2542,8 @@ static inline bool skb_needs_check(struc
  *
  *	It may return NULL if the skb requires no segmentation.  This is
  *	only possible when GSO is used for verifying header integrity.
+ *
+ *	Segmentation preserves SKB_SGO_CB_OFFSET bytes of previous skb cb.
  */
 struct sk_buff *__skb_gso_segment(struct sk_buff *skb,
 				  netdev_features_t features, bool tx_path)
@@ -2556,6 +2558,9 @@ struct sk_buff *__skb_gso_segment(struct
 			return ERR_PTR(err);
 	}
 
+	BUILD_BUG_ON(SKB_SGO_CB_OFFSET +
+		     sizeof(*SKB_GSO_CB(skb)) > sizeof(skb->cb));
+
 	SKB_GSO_CB(skb)->mac_offset = skb_headroom(skb);
 	SKB_GSO_CB(skb)->encap_level = 0;
 
@@ -3717,6 +3722,22 @@ static inline struct sk_buff *handle_ing
 }
 
 /**
+ *	netdev_is_rx_handler_busy - check if receive handler is registered
+ *	@dev: device to check
+ *
+ *	Check if a receive handler is already registered for a given device.
+ *	Return true if there one.
+ *
+ *	The caller must hold the rtnl_mutex.
+ */
+bool netdev_is_rx_handler_busy(struct net_device *dev)
+{
+	ASSERT_RTNL();
+	return dev && rtnl_dereference(dev->rx_handler);
+}
+EXPORT_SYMBOL_GPL(netdev_is_rx_handler_busy);
+
+/**
  *	netdev_rx_handler_register - register receive handler
  *	@dev: device to register a handler for
  *	@rx_handler: receive handler to register
@@ -4140,6 +4161,7 @@ static void gro_list_prepare(struct napi
 
 		diffs = (unsigned long)p->dev ^ (unsigned long)skb->dev;
 		diffs |= p->vlan_tci ^ skb->vlan_tci;
+		diffs |= skb_metadata_dst_cmp(p, skb);
 		if (maclen == ETH_HLEN)
 			diffs |= compare_ether_header(skb_mac_header(p),
 						      skb_mac_header(skb));
@@ -4217,7 +4239,8 @@ static enum gro_result dev_gro_receive(s
 		NAPI_GRO_CB(skb)->same_flow = 0;
 		NAPI_GRO_CB(skb)->flush = 0;
 		NAPI_GRO_CB(skb)->free = 0;
-		NAPI_GRO_CB(skb)->udp_mark = 0;
+		NAPI_GRO_CB(skb)->encap_mark = 0;
+		NAPI_GRO_CB(skb)->recursion_counter = 0;
 		NAPI_GRO_CB(skb)->gro_remcsum_start = 0;
 
 		/* Setup for GRO checksum validation */
@@ -4337,10 +4360,12 @@ static gro_result_t napi_skb_finish(gro_
 		break;
 
 	case GRO_MERGED_FREE:
-		if (NAPI_GRO_CB(skb)->free == NAPI_GRO_FREE_STOLEN_HEAD)
+		if (NAPI_GRO_CB(skb)->free == NAPI_GRO_FREE_STOLEN_HEAD) {
+			skb_dst_drop(skb);
 			kmem_cache_free(skbuff_head_cache, skb);
-		else
+		} else {
 			__kfree_skb(skb);
+		}
 		break;
 
 	case GRO_HELD:
@@ -4871,6 +4896,7 @@ static void net_rx_action(struct softirq
 		}
 	}
 
+	__kfree_skb_flush();
 	local_irq_disable();
 
 	list_splice_tail_init(&sd->poll_list, &list);
@@ -7120,8 +7146,10 @@ struct net_device *alloc_netdev_mqs(int
 	dev->priv_flags = IFF_XMIT_DST_RELEASE | IFF_XMIT_DST_RELEASE_PERM;
 	setup(dev);
 
-	if (!dev->tx_queue_len)
+	if (!dev->tx_queue_len) {
 		dev->priv_flags |= IFF_NO_QUEUE;
+		dev->tx_queue_len = 1;
+	}
 
 	dev->num_tx_queues = txqs;
 	dev->real_num_tx_queues = txqs;
--- zfcpdump-kernel-4.4.orig/net/core/ethtool.c
+++ zfcpdump-kernel-4.4/net/core/ethtool.c
@@ -87,7 +87,7 @@ static const char netdev_features_string
 	[NETIF_F_GSO_UDP_TUNNEL_BIT] =	 "tx-udp_tnl-segmentation",
 
 	[NETIF_F_FCOE_CRC_BIT] =         "tx-checksum-fcoe-crc",
-	[NETIF_F_SCTP_CSUM_BIT] =        "tx-checksum-sctp",
+	[NETIF_F_SCTP_CRC_BIT] =        "tx-checksum-sctp",
 	[NETIF_F_FCOE_MTU_BIT] =         "fcoe-mtu",
 	[NETIF_F_NTUPLE_BIT] =           "rx-ntuple-filter",
 	[NETIF_F_RXHASH_BIT] =           "rx-hashing",
@@ -98,6 +98,7 @@ static const char netdev_features_string
 	[NETIF_F_RXALL_BIT] =            "rx-all",
 	[NETIF_F_HW_L2FW_DOFFLOAD_BIT] = "l2-fwd-offload",
 	[NETIF_F_BUSY_POLL_BIT] =        "busy-poll",
+	[NETIF_F_HW_TC_BIT] =		 "hw-tc-offload",
 };
 
 static const char
@@ -235,7 +236,7 @@ static netdev_features_t ethtool_get_fea
 	switch (eth_cmd) {
 	case ETHTOOL_GTXCSUM:
 	case ETHTOOL_STXCSUM:
-		return NETIF_F_ALL_CSUM | NETIF_F_SCTP_CSUM;
+		return NETIF_F_ALL_CSUM | NETIF_F_SCTP_CRC;
 	case ETHTOOL_GRXCSUM:
 	case ETHTOOL_SRXCSUM:
 		return NETIF_F_RXCSUM;
@@ -352,6 +353,359 @@ static int __ethtool_set_flags(struct ne
 	return 0;
 }
 
+static void convert_legacy_u32_to_link_mode(unsigned long *dst, u32 legacy_u32)
+{
+	bitmap_zero(dst, __ETHTOOL_LINK_MODE_MASK_NBITS);
+	dst[0] = legacy_u32;
+}
+
+/* return false if src had higher bits set. lower bits always updated. */
+static bool convert_link_mode_to_legacy_u32(u32 *legacy_u32,
+					    const unsigned long *src)
+{
+	bool retval = true;
+
+	/* TODO: following test will soon always be true */
+	if (__ETHTOOL_LINK_MODE_MASK_NBITS > 32) {
+		__ETHTOOL_DECLARE_LINK_MODE_MASK(ext);
+
+		bitmap_zero(ext, __ETHTOOL_LINK_MODE_MASK_NBITS);
+		bitmap_fill(ext, 32);
+		bitmap_complement(ext, ext, __ETHTOOL_LINK_MODE_MASK_NBITS);
+		if (bitmap_intersects(ext, src,
+				      __ETHTOOL_LINK_MODE_MASK_NBITS)) {
+			/* src mask goes beyond bit 31 */
+			retval = false;
+		}
+	}
+	*legacy_u32 = src[0];
+	return retval;
+}
+
+/* return false if legacy contained non-0 deprecated fields
+ * transceiver/maxtxpkt/maxrxpkt. rest of ksettings always updated
+ */
+static bool
+convert_legacy_settings_to_link_ksettings(
+	struct ethtool_link_ksettings *link_ksettings,
+	const struct ethtool_cmd *legacy_settings)
+{
+	bool retval = true;
+
+	memset(link_ksettings, 0, sizeof(*link_ksettings));
+
+	/* This is used to tell users that driver is still using these
+	 * deprecated legacy fields, and they should not use
+	 * %ETHTOOL_GLINKSETTINGS/%ETHTOOL_SLINKSETTINGS
+	 */
+	if (legacy_settings->transceiver ||
+	    legacy_settings->maxtxpkt ||
+	    legacy_settings->maxrxpkt)
+		retval = false;
+
+	convert_legacy_u32_to_link_mode(
+		link_ksettings->link_modes.supported,
+		legacy_settings->supported);
+	convert_legacy_u32_to_link_mode(
+		link_ksettings->link_modes.advertising,
+		legacy_settings->advertising);
+	convert_legacy_u32_to_link_mode(
+		link_ksettings->link_modes.lp_advertising,
+		legacy_settings->lp_advertising);
+	link_ksettings->base.speed
+		= ethtool_cmd_speed(legacy_settings);
+	link_ksettings->base.duplex
+		= legacy_settings->duplex;
+	link_ksettings->base.port
+		= legacy_settings->port;
+	link_ksettings->base.phy_address
+		= legacy_settings->phy_address;
+	link_ksettings->base.autoneg
+		= legacy_settings->autoneg;
+	link_ksettings->base.mdio_support
+		= legacy_settings->mdio_support;
+	link_ksettings->base.eth_tp_mdix
+		= legacy_settings->eth_tp_mdix;
+	link_ksettings->base.eth_tp_mdix_ctrl
+		= legacy_settings->eth_tp_mdix_ctrl;
+	return retval;
+}
+
+/* return false if ksettings link modes had higher bits
+ * set. legacy_settings always updated (best effort)
+ */
+static bool
+convert_link_ksettings_to_legacy_settings(
+	struct ethtool_cmd *legacy_settings,
+	const struct ethtool_link_ksettings *link_ksettings)
+{
+	bool retval = true;
+
+	memset(legacy_settings, 0, sizeof(*legacy_settings));
+	/* this also clears the deprecated fields in legacy structure:
+	 * __u8		transceiver;
+	 * __u32	maxtxpkt;
+	 * __u32	maxrxpkt;
+	 */
+
+	retval &= convert_link_mode_to_legacy_u32(
+		&legacy_settings->supported,
+		link_ksettings->link_modes.supported);
+	retval &= convert_link_mode_to_legacy_u32(
+		&legacy_settings->advertising,
+		link_ksettings->link_modes.advertising);
+	retval &= convert_link_mode_to_legacy_u32(
+		&legacy_settings->lp_advertising,
+		link_ksettings->link_modes.lp_advertising);
+	ethtool_cmd_speed_set(legacy_settings, link_ksettings->base.speed);
+	legacy_settings->duplex
+		= link_ksettings->base.duplex;
+	legacy_settings->port
+		= link_ksettings->base.port;
+	legacy_settings->phy_address
+		= link_ksettings->base.phy_address;
+	legacy_settings->autoneg
+		= link_ksettings->base.autoneg;
+	legacy_settings->mdio_support
+		= link_ksettings->base.mdio_support;
+	legacy_settings->eth_tp_mdix
+		= link_ksettings->base.eth_tp_mdix;
+	legacy_settings->eth_tp_mdix_ctrl
+		= link_ksettings->base.eth_tp_mdix_ctrl;
+	return retval;
+}
+
+/* number of 32-bit words to store the user's link mode bitmaps */
+#define __ETHTOOL_LINK_MODE_MASK_NU32			\
+	DIV_ROUND_UP(__ETHTOOL_LINK_MODE_MASK_NBITS, 32)
+
+/* layout of the struct passed from/to userland */
+struct ethtool_link_usettings {
+	struct ethtool_link_settings base;
+	struct {
+		__u32 supported[__ETHTOOL_LINK_MODE_MASK_NU32];
+		__u32 advertising[__ETHTOOL_LINK_MODE_MASK_NU32];
+		__u32 lp_advertising[__ETHTOOL_LINK_MODE_MASK_NU32];
+	} link_modes;
+};
+
+/* Internal kernel helper to query a device ethtool_link_settings.
+ *
+ * Backward compatibility note: for compatibility with legacy drivers
+ * that implement only the ethtool_cmd API, this has to work with both
+ * drivers implementing get_link_ksettings API and drivers
+ * implementing get_settings API. When drivers implement get_settings
+ * and report ethtool_cmd deprecated fields
+ * (transceiver/maxrxpkt/maxtxpkt), these fields are silently ignored
+ * because the resulting struct ethtool_link_settings does not report them.
+ */
+int __ethtool_get_link_ksettings(struct net_device *dev,
+				 struct ethtool_link_ksettings *link_ksettings)
+{
+	int err;
+	struct ethtool_cmd cmd;
+
+	ASSERT_RTNL();
+
+	if (dev->ethtool_ops->get_link_ksettings) {
+		memset(link_ksettings, 0, sizeof(*link_ksettings));
+		return dev->ethtool_ops->get_link_ksettings(dev,
+							    link_ksettings);
+	}
+
+	/* driver doesn't support %ethtool_link_ksettings API. revert to
+	 * legacy %ethtool_cmd API, unless it's not supported either.
+	 * TODO: remove when ethtool_ops::get_settings disappears internally
+	 */
+	err = __ethtool_get_settings(dev, &cmd);
+	if (err < 0)
+		return err;
+
+	/* we ignore deprecated fields transceiver/maxrxpkt/maxtxpkt
+	 */
+	convert_legacy_settings_to_link_ksettings(link_ksettings, &cmd);
+	return err;
+}
+EXPORT_SYMBOL(__ethtool_get_link_ksettings);
+
+/* convert ethtool_link_usettings in user space to a kernel internal
+ * ethtool_link_ksettings. return 0 on success, errno on error.
+ */
+static int load_link_ksettings_from_user(struct ethtool_link_ksettings *to,
+					 const void __user *from)
+{
+	struct ethtool_link_usettings link_usettings;
+
+	if (copy_from_user(&link_usettings, from, sizeof(link_usettings)))
+		return -EFAULT;
+
+	memcpy(&to->base, &link_usettings.base, sizeof(to->base));
+	bitmap_from_u32array(to->link_modes.supported,
+			     __ETHTOOL_LINK_MODE_MASK_NBITS,
+			     link_usettings.link_modes.supported,
+			     __ETHTOOL_LINK_MODE_MASK_NU32);
+	bitmap_from_u32array(to->link_modes.advertising,
+			     __ETHTOOL_LINK_MODE_MASK_NBITS,
+			     link_usettings.link_modes.advertising,
+			     __ETHTOOL_LINK_MODE_MASK_NU32);
+	bitmap_from_u32array(to->link_modes.lp_advertising,
+			     __ETHTOOL_LINK_MODE_MASK_NBITS,
+			     link_usettings.link_modes.lp_advertising,
+			     __ETHTOOL_LINK_MODE_MASK_NU32);
+
+	return 0;
+}
+
+/* convert a kernel internal ethtool_link_ksettings to
+ * ethtool_link_usettings in user space. return 0 on success, errno on
+ * error.
+ */
+static int
+store_link_ksettings_for_user(void __user *to,
+			      const struct ethtool_link_ksettings *from)
+{
+	struct ethtool_link_usettings link_usettings;
+
+	memcpy(&link_usettings.base, &from->base, sizeof(link_usettings));
+	bitmap_to_u32array(link_usettings.link_modes.supported,
+			   __ETHTOOL_LINK_MODE_MASK_NU32,
+			   from->link_modes.supported,
+			   __ETHTOOL_LINK_MODE_MASK_NBITS);
+	bitmap_to_u32array(link_usettings.link_modes.advertising,
+			   __ETHTOOL_LINK_MODE_MASK_NU32,
+			   from->link_modes.advertising,
+			   __ETHTOOL_LINK_MODE_MASK_NBITS);
+	bitmap_to_u32array(link_usettings.link_modes.lp_advertising,
+			   __ETHTOOL_LINK_MODE_MASK_NU32,
+			   from->link_modes.lp_advertising,
+			   __ETHTOOL_LINK_MODE_MASK_NBITS);
+
+	if (copy_to_user(to, &link_usettings, sizeof(link_usettings)))
+		return -EFAULT;
+
+	return 0;
+}
+
+/* Query device for its ethtool_link_settings.
+ *
+ * Backward compatibility note: this function must fail when driver
+ * does not implement ethtool::get_link_ksettings, even if legacy
+ * ethtool_ops::get_settings is implemented. This tells new versions
+ * of ethtool that they should use the legacy API %ETHTOOL_GSET for
+ * this driver, so that they can correctly access the ethtool_cmd
+ * deprecated fields (transceiver/maxrxpkt/maxtxpkt), until no driver
+ * implements ethtool_ops::get_settings anymore.
+ */
+static int ethtool_get_link_ksettings(struct net_device *dev,
+				      void __user *useraddr)
+{
+	int err = 0;
+	struct ethtool_link_ksettings link_ksettings;
+
+	ASSERT_RTNL();
+
+	if (!dev->ethtool_ops->get_link_ksettings)
+		return -EOPNOTSUPP;
+
+	/* handle bitmap nbits handshake */
+	if (copy_from_user(&link_ksettings.base, useraddr,
+			   sizeof(link_ksettings.base)))
+		return -EFAULT;
+
+	if (__ETHTOOL_LINK_MODE_MASK_NU32
+	    != link_ksettings.base.link_mode_masks_nwords) {
+		/* wrong link mode nbits requested */
+		memset(&link_ksettings, 0, sizeof(link_ksettings));
+		/* keep cmd field reset to 0 */
+		/* send back number of words required as negative val */
+		compiletime_assert(__ETHTOOL_LINK_MODE_MASK_NU32 <= S8_MAX,
+				   "need too many bits for link modes!");
+		link_ksettings.base.link_mode_masks_nwords
+			= -((s8)__ETHTOOL_LINK_MODE_MASK_NU32);
+
+		/* copy the base fields back to user, not the link
+		 * mode bitmaps
+		 */
+		if (copy_to_user(useraddr, &link_ksettings.base,
+				 sizeof(link_ksettings.base)))
+			return -EFAULT;
+
+		return 0;
+	}
+
+	/* handshake successful: user/kernel agree on
+	 * link_mode_masks_nwords
+	 */
+
+	memset(&link_ksettings, 0, sizeof(link_ksettings));
+	err = dev->ethtool_ops->get_link_ksettings(dev, &link_ksettings);
+	if (err < 0)
+		return err;
+
+	/* make sure we tell the right values to user */
+	link_ksettings.base.cmd = ETHTOOL_GLINKSETTINGS;
+	link_ksettings.base.link_mode_masks_nwords
+		= __ETHTOOL_LINK_MODE_MASK_NU32;
+
+	return store_link_ksettings_for_user(useraddr, &link_ksettings);
+}
+
+/* Update device ethtool_link_settings.
+ *
+ * Backward compatibility note: this function must fail when driver
+ * does not implement ethtool::set_link_ksettings, even if legacy
+ * ethtool_ops::set_settings is implemented. This tells new versions
+ * of ethtool that they should use the legacy API %ETHTOOL_SSET for
+ * this driver, so that they can correctly update the ethtool_cmd
+ * deprecated fields (transceiver/maxrxpkt/maxtxpkt), until no driver
+ * implements ethtool_ops::get_settings anymore.
+ */
+static int ethtool_set_link_ksettings(struct net_device *dev,
+				      void __user *useraddr)
+{
+	int err;
+	struct ethtool_link_ksettings link_ksettings;
+
+	ASSERT_RTNL();
+
+	if (!dev->ethtool_ops->set_link_ksettings)
+		return -EOPNOTSUPP;
+
+	/* make sure nbits field has expected value */
+	if (copy_from_user(&link_ksettings.base, useraddr,
+			   sizeof(link_ksettings.base)))
+		return -EFAULT;
+
+	if (__ETHTOOL_LINK_MODE_MASK_NU32
+	    != link_ksettings.base.link_mode_masks_nwords)
+		return -EINVAL;
+
+	/* copy the whole structure, now that we know it has expected
+	 * format
+	 */
+	err = load_link_ksettings_from_user(&link_ksettings, useraddr);
+	if (err)
+		return err;
+
+	/* re-check nwords field, just in case */
+	if (__ETHTOOL_LINK_MODE_MASK_NU32
+	    != link_ksettings.base.link_mode_masks_nwords)
+		return -EINVAL;
+
+	return dev->ethtool_ops->set_link_ksettings(dev, &link_ksettings);
+}
+
+/* Internal kernel helper to query a device ethtool_cmd settings.
+ *
+ * Note about transition to ethtool_link_settings API: We do not need
+ * (or want) this function to support "dev" instances that implement
+ * the ethtool_link_settings API as we will update the drivers calling
+ * this function to call __ethtool_get_link_ksettings instead, before
+ * the first drivers implement ethtool_ops::get_link_ksettings.
+ *
+ * TODO 1: at least make this function static when no driver is using it
+ * TODO 2: remove when ethtool_ops::get_settings disappears internally
+ */
 int __ethtool_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 {
 	ASSERT_RTNL();
@@ -365,30 +719,112 @@ int __ethtool_get_settings(struct net_de
 }
 EXPORT_SYMBOL(__ethtool_get_settings);
 
+static void
+warn_incomplete_ethtool_legacy_settings_conversion(const char *details)
+{
+	char name[sizeof(current->comm)];
+
+	pr_info_once("warning: `%s' uses legacy ethtool link settings API, %s\n",
+		     get_task_comm(name, current), details);
+}
+
+/* Query device for its ethtool_cmd settings.
+ *
+ * Backward compatibility note: for compatibility with legacy ethtool,
+ * this has to work with both drivers implementing get_link_ksettings
+ * API and drivers implementing get_settings API. When drivers
+ * implement get_link_ksettings and report higher link mode bits, a
+ * kernel warning is logged once (with name of 1st driver/device) to
+ * recommend user to upgrade ethtool, but the command is successful
+ * (only the lower link mode bits reported back to user).
+ */
 static int ethtool_get_settings(struct net_device *dev, void __user *useraddr)
 {
-	int err;
 	struct ethtool_cmd cmd;
 
-	err = __ethtool_get_settings(dev, &cmd);
-	if (err < 0)
-		return err;
+	ASSERT_RTNL();
+
+	if (dev->ethtool_ops->get_link_ksettings) {
+		/* First, use link_ksettings API if it is supported */
+		int err;
+		struct ethtool_link_ksettings link_ksettings;
+
+		memset(&link_ksettings, 0, sizeof(link_ksettings));
+		err = dev->ethtool_ops->get_link_ksettings(dev,
+							   &link_ksettings);
+		if (err < 0)
+			return err;
+		if (!convert_link_ksettings_to_legacy_settings(&cmd,
+							       &link_ksettings))
+			warn_incomplete_ethtool_legacy_settings_conversion(
+				"link modes are only partially reported");
+
+		/* send a sensible cmd tag back to user */
+		cmd.cmd = ETHTOOL_GSET;
+	} else {
+		int err;
+		/* TODO: return -EOPNOTSUPP when
+		 * ethtool_ops::get_settings disappears internally
+		 */
+
+		/* driver doesn't support %ethtool_link_ksettings
+		 * API. revert to legacy %ethtool_cmd API, unless it's
+		 * not supported either.
+		 */
+		err = __ethtool_get_settings(dev, &cmd);
+		if (err < 0)
+			return err;
+	}
 
 	if (copy_to_user(useraddr, &cmd, sizeof(cmd)))
 		return -EFAULT;
+
 	return 0;
 }
 
+/* Update device link settings with given ethtool_cmd.
+ *
+ * Backward compatibility note: for compatibility with legacy ethtool,
+ * this has to work with both drivers implementing set_link_ksettings
+ * API and drivers implementing set_settings API. When drivers
+ * implement set_link_ksettings and user's request updates deprecated
+ * ethtool_cmd fields (transceiver/maxrxpkt/maxtxpkt), a kernel
+ * warning is logged once (with name of 1st driver/device) to
+ * recommend user to upgrade ethtool, and the request is rejected.
+ */
 static int ethtool_set_settings(struct net_device *dev, void __user *useraddr)
 {
 	struct ethtool_cmd cmd;
 
-	if (!dev->ethtool_ops->set_settings)
-		return -EOPNOTSUPP;
+	ASSERT_RTNL();
 
 	if (copy_from_user(&cmd, useraddr, sizeof(cmd)))
 		return -EFAULT;
 
+	/* first, try new %ethtool_link_ksettings API. */
+	if (dev->ethtool_ops->set_link_ksettings) {
+		struct ethtool_link_ksettings link_ksettings;
+
+		if (!convert_legacy_settings_to_link_ksettings(&link_ksettings,
+							       &cmd))
+			return -EINVAL;
+
+		link_ksettings.base.cmd = ETHTOOL_SLINKSETTINGS;
+		link_ksettings.base.link_mode_masks_nwords
+			= __ETHTOOL_LINK_MODE_MASK_NU32;
+		return dev->ethtool_ops->set_link_ksettings(dev,
+							    &link_ksettings);
+	}
+
+	/* legacy %ethtool_cmd API */
+
+	/* TODO: return -EOPNOTSUPP when ethtool_ops::get_settings
+	 * disappears internally
+	 */
+
+	if (!dev->ethtool_ops->set_settings)
+		return -EOPNOTSUPP;
+
 	return dev->ethtool_ops->set_settings(dev, &cmd);
 }
 
@@ -608,6 +1044,37 @@ void netdev_rss_key_fill(void *buffer, s
 }
 EXPORT_SYMBOL(netdev_rss_key_fill);
 
+static int ethtool_get_max_rxfh_channel(struct net_device *dev, u32 *max)
+{
+	u32 dev_size, current_max = 0;
+	u32 *indir;
+	int ret;
+
+	if (!dev->ethtool_ops->get_rxfh_indir_size ||
+	    !dev->ethtool_ops->get_rxfh)
+		return -EOPNOTSUPP;
+	dev_size = dev->ethtool_ops->get_rxfh_indir_size(dev);
+	if (dev_size == 0)
+		return -EOPNOTSUPP;
+
+	indir = kcalloc(dev_size, sizeof(indir[0]), GFP_USER);
+	if (!indir)
+		return -ENOMEM;
+
+	ret = dev->ethtool_ops->get_rxfh(dev, indir, NULL, NULL);
+	if (ret)
+		goto out;
+
+	while (dev_size--)
+		current_max = max(current_max, indir[dev_size]);
+
+	*max = current_max;
+
+out:
+	kfree(indir);
+	return ret;
+}
+
 static noinline_for_stack int ethtool_get_rxfh_indir(struct net_device *dev,
 						     void __user *useraddr)
 {
@@ -704,6 +1171,14 @@ static noinline_for_stack int ethtool_se
 	}
 
 	ret = ops->set_rxfh(dev, indir, NULL, ETH_RSS_HASH_NO_CHANGE);
+	if (ret)
+		goto out;
+
+	/* indicate whether rxfh was set to default */
+	if (user_size == 0)
+		dev->priv_flags &= ~IFF_RXFH_CONFIGURED;
+	else
+		dev->priv_flags |= IFF_RXFH_CONFIGURED;
 
 out:
 	kfree(indir);
@@ -863,6 +1338,14 @@ static noinline_for_stack int ethtool_se
 	}
 
 	ret = ops->set_rxfh(dev, indir, hkey, rxfh.hfunc);
+	if (ret)
+		goto out;
+
+	/* indicate whether rxfh was set to default */
+	if (rxfh.indir_size == 0)
+		dev->priv_flags &= ~IFF_RXFH_CONFIGURED;
+	else if (rxfh.indir_size != ETH_RXFH_INDIR_NO_CHANGE)
+		dev->priv_flags |= IFF_RXFH_CONFIGURED;
 
 out:
 	kfree(rss_config);
@@ -1194,6 +1677,7 @@ static noinline_for_stack int ethtool_se
 						   void __user *useraddr)
 {
 	struct ethtool_channels channels;
+	u32 max_rx_in_use = 0;
 
 	if (!dev->ethtool_ops->set_channels)
 		return -EOPNOTSUPP;
@@ -1201,6 +1685,13 @@ static noinline_for_stack int ethtool_se
 	if (copy_from_user(&channels, useraddr, sizeof(channels)))
 		return -EFAULT;
 
+	/* ensure the new Rx count fits within the configured Rx flow
+	 * indirection table settings */
+	if (netif_is_rxfh_configured(dev) &&
+	    !ethtool_get_max_rxfh_channel(dev, &max_rx_in_use) &&
+	    (channels.combined_count + channels.rx_count) <= max_rx_in_use)
+	    return -EINVAL;
+
 	return dev->ethtool_ops->set_channels(dev, &channels);
 }
 
@@ -1991,6 +2482,12 @@ int dev_ethtool(struct net *net, struct
 	case ETHTOOL_STUNABLE:
 		rc = ethtool_set_tunable(dev, useraddr);
 		break;
+	case ETHTOOL_GLINKSETTINGS:
+		rc = ethtool_get_link_ksettings(dev, useraddr);
+		break;
+	case ETHTOOL_SLINKSETTINGS:
+		rc = ethtool_set_link_ksettings(dev, useraddr);
+		break;
 	default:
 		rc = -EOPNOTSUPP;
 	}
--- zfcpdump-kernel-4.4.orig/net/core/filter.c
+++ zfcpdump-kernel-4.4/net/core/filter.c
@@ -777,6 +777,11 @@ static int bpf_check_classic(const struc
 			if (ftest->k == 0)
 				return -EINVAL;
 			break;
+		case BPF_ALU | BPF_LSH | BPF_K:
+		case BPF_ALU | BPF_RSH | BPF_K:
+			if (ftest->k >= 32)
+				return -EINVAL;
+			break;
 		case BPF_LD | BPF_MEM:
 		case BPF_LDX | BPF_MEM:
 		case BPF_ST:
@@ -1134,7 +1139,8 @@ void bpf_prog_destroy(struct bpf_prog *f
 }
 EXPORT_SYMBOL_GPL(bpf_prog_destroy);
 
-static int __sk_attach_prog(struct bpf_prog *prog, struct sock *sk)
+static int __sk_attach_prog(struct bpf_prog *prog, struct sock *sk,
+			    bool locked)
 {
 	struct sk_filter *fp, *old_fp;
 
@@ -1150,10 +1156,8 @@ static int __sk_attach_prog(struct bpf_p
 		return -ENOMEM;
 	}
 
-	old_fp = rcu_dereference_protected(sk->sk_filter,
-					   sock_owned_by_user(sk));
+	old_fp = rcu_dereference_protected(sk->sk_filter, locked);
 	rcu_assign_pointer(sk->sk_filter, fp);
-
 	if (old_fp)
 		sk_filter_uncharge(sk, old_fp);
 
@@ -1170,7 +1174,8 @@ static int __sk_attach_prog(struct bpf_p
  * occurs or there is insufficient memory for the filter a negative
  * errno code is returned. On success the return is zero.
  */
-int sk_attach_filter(struct sock_fprog *fprog, struct sock *sk)
+int __sk_attach_filter(struct sock_fprog *fprog, struct sock *sk,
+		       bool locked)
 {
 	unsigned int fsize = bpf_classic_proglen(fprog);
 	unsigned int bpf_fsize = bpf_prog_size(fprog->len);
@@ -1208,7 +1213,7 @@ int sk_attach_filter(struct sock_fprog *
 	if (IS_ERR(prog))
 		return PTR_ERR(prog);
 
-	err = __sk_attach_prog(prog, sk);
+	err = __sk_attach_prog(prog, sk, locked);
 	if (err < 0) {
 		__bpf_prog_release(prog);
 		return err;
@@ -1216,7 +1221,12 @@ int sk_attach_filter(struct sock_fprog *
 
 	return 0;
 }
-EXPORT_SYMBOL_GPL(sk_attach_filter);
+EXPORT_SYMBOL_GPL(__sk_attach_filter);
+
+int sk_attach_filter(struct sock_fprog *fprog, struct sock *sk)
+{
+	return __sk_attach_filter(fprog, sk, sock_owned_by_user(sk));
+}
 
 int sk_attach_bpf(u32 ufd, struct sock *sk)
 {
@@ -1235,7 +1245,7 @@ int sk_attach_bpf(u32 ufd, struct sock *
 		return -EINVAL;
 	}
 
-	err = __sk_attach_prog(prog, sk);
+	err = __sk_attach_prog(prog, sk, sock_owned_by_user(sk));
 	if (err < 0) {
 		bpf_prog_put(prog);
 		return err;
@@ -1265,9 +1275,7 @@ static u64 bpf_skb_store_bytes(u64 r1, u
 	 */
 	if (unlikely((u32) offset > 0xffff || len > sizeof(buf)))
 		return -EFAULT;
-
-	if (unlikely(skb_cloned(skb) &&
-		     !skb_clone_writable(skb, offset + len)))
+	if (unlikely(skb_try_make_writable(skb, offset + len)))
 		return -EFAULT;
 
 	ptr = skb_header_pointer(skb, offset, len, buf);
@@ -1311,8 +1319,7 @@ static u64 bpf_l3_csum_replace(u64 r1, u
 	if (unlikely((u32) offset > 0xffff))
 		return -EFAULT;
 
-	if (unlikely(skb_cloned(skb) &&
-		     !skb_clone_writable(skb, offset + sizeof(sum))))
+	if (unlikely(skb_try_make_writable(skb, offset + sizeof(sum))))
 		return -EFAULT;
 
 	ptr = skb_header_pointer(skb, offset, sizeof(sum), &sum);
@@ -1357,9 +1364,7 @@ static u64 bpf_l4_csum_replace(u64 r1, u
 
 	if (unlikely((u32) offset > 0xffff))
 		return -EFAULT;
-
-	if (unlikely(skb_cloned(skb) &&
-		     !skb_clone_writable(skb, offset + sizeof(sum))))
+	if (unlikely(skb_try_make_writable(skb, offset + sizeof(sum))))
 		return -EFAULT;
 
 	ptr = skb_header_pointer(skb, offset, sizeof(sum), &sum);
@@ -1544,6 +1549,13 @@ bool bpf_helper_changes_skb_data(void *f
 		return true;
 	if (func == bpf_skb_vlan_pop)
 		return true;
+	if (func == bpf_skb_store_bytes)
+		return true;
+	if (func == bpf_l3_csum_replace)
+		return true;
+	if (func == bpf_l4_csum_replace)
+		return true;
+
 	return false;
 }
 
@@ -1908,7 +1920,7 @@ static int __init register_sk_filter_ops
 }
 late_initcall(register_sk_filter_ops);
 
-int sk_detach_filter(struct sock *sk)
+int __sk_detach_filter(struct sock *sk, bool locked)
 {
 	int ret = -ENOENT;
 	struct sk_filter *filter;
@@ -1916,8 +1928,7 @@ int sk_detach_filter(struct sock *sk)
 	if (sock_flag(sk, SOCK_FILTER_LOCKED))
 		return -EPERM;
 
-	filter = rcu_dereference_protected(sk->sk_filter,
-					   sock_owned_by_user(sk));
+	filter = rcu_dereference_protected(sk->sk_filter, locked);
 	if (filter) {
 		RCU_INIT_POINTER(sk->sk_filter, NULL);
 		sk_filter_uncharge(sk, filter);
@@ -1926,7 +1937,12 @@ int sk_detach_filter(struct sock *sk)
 
 	return ret;
 }
-EXPORT_SYMBOL_GPL(sk_detach_filter);
+EXPORT_SYMBOL_GPL(__sk_detach_filter);
+
+int sk_detach_filter(struct sock *sk)
+{
+	return __sk_detach_filter(sk, sock_owned_by_user(sk));
+}
 
 int sk_get_filter(struct sock *sk, struct sock_filter __user *ubuf,
 		  unsigned int len)
--- zfcpdump-kernel-4.4.orig/net/core/flow_dissector.c
+++ zfcpdump-kernel-4.4/net/core/flow_dissector.c
@@ -208,7 +208,6 @@ ip:
 	case htons(ETH_P_IPV6): {
 		const struct ipv6hdr *iph;
 		struct ipv6hdr _iph;
-		__be32 flow_label;
 
 ipv6:
 		iph = __skb_header_pointer(skb, nhoff, sizeof(_iph), data, hlen, &_iph);
@@ -230,8 +229,12 @@ ipv6:
 			key_control->addr_type = FLOW_DISSECTOR_KEY_IPV6_ADDRS;
 		}
 
-		flow_label = ip6_flowlabel(iph);
-		if (flow_label) {
+		if ((dissector_uses_key(flow_dissector,
+					FLOW_DISSECTOR_KEY_FLOW_LABEL) ||
+		     (flags & FLOW_DISSECTOR_F_STOP_AT_FLOW_LABEL)) &&
+		    ip6_flowlabel(iph)) {
+			__be32 flow_label = ip6_flowlabel(iph);
+
 			if (dissector_uses_key(flow_dissector,
 					       FLOW_DISSECTOR_KEY_FLOW_LABEL)) {
 				key_tags = skb_flow_dissector_target(flow_dissector,
@@ -396,6 +399,13 @@ ip_proto_again:
 				goto out_bad;
 			proto = eth->h_proto;
 			nhoff += sizeof(*eth);
+
+			/* Cap headers that we access via pointers at the
+			 * end of the Ethernet header as our maximum alignment
+			 * at that point is only 2 bytes.
+			 */
+			if (NET_IP_ALIGN)
+				hlen = nhoff;
 		}
 
 		key_control->flags |= FLOW_DIS_ENCAPSULATION;
@@ -652,6 +662,23 @@ void make_flow_keys_digest(struct flow_k
 }
 EXPORT_SYMBOL(make_flow_keys_digest);
 
+static struct flow_dissector flow_keys_dissector_symmetric __read_mostly;
+
+u32 __skb_get_hash_symmetric(struct sk_buff *skb)
+{
+	struct flow_keys keys;
+
+	__flow_hash_secret_init();
+
+	memset(&keys, 0, sizeof(keys));
+	__skb_flow_dissect(skb, &flow_keys_dissector_symmetric, &keys,
+			   NULL, 0, 0, 0,
+			   FLOW_DISSECTOR_F_STOP_AT_FLOW_LABEL);
+
+	return __flow_hash_from_keys(&keys, hashrnd);
+}
+EXPORT_SYMBOL_GPL(__skb_get_hash_symmetric);
+
 /**
  * __skb_get_hash: calculate a flow hash
  * @skb: sk_buff to calculate flow hash from
@@ -864,6 +891,29 @@ static const struct flow_dissector_key f
 	},
 };
 
+static const struct flow_dissector_key flow_keys_dissector_symmetric_keys[] = {
+	{
+		.key_id = FLOW_DISSECTOR_KEY_CONTROL,
+		.offset = offsetof(struct flow_keys, control),
+	},
+	{
+		.key_id = FLOW_DISSECTOR_KEY_BASIC,
+		.offset = offsetof(struct flow_keys, basic),
+	},
+	{
+		.key_id = FLOW_DISSECTOR_KEY_IPV4_ADDRS,
+		.offset = offsetof(struct flow_keys, addrs.v4addrs),
+	},
+	{
+		.key_id = FLOW_DISSECTOR_KEY_IPV6_ADDRS,
+		.offset = offsetof(struct flow_keys, addrs.v6addrs),
+	},
+	{
+		.key_id = FLOW_DISSECTOR_KEY_PORTS,
+		.offset = offsetof(struct flow_keys, ports),
+	},
+};
+
 static const struct flow_dissector_key flow_keys_buf_dissector_keys[] = {
 	{
 		.key_id = FLOW_DISSECTOR_KEY_CONTROL,
@@ -885,6 +935,9 @@ static int __init init_default_flow_diss
 	skb_flow_dissector_init(&flow_keys_dissector,
 				flow_keys_dissector_keys,
 				ARRAY_SIZE(flow_keys_dissector_keys));
+	skb_flow_dissector_init(&flow_keys_dissector_symmetric,
+				flow_keys_dissector_symmetric_keys,
+				ARRAY_SIZE(flow_keys_dissector_symmetric_keys));
 	skb_flow_dissector_init(&flow_keys_buf_dissector,
 				flow_keys_buf_dissector_keys,
 				ARRAY_SIZE(flow_keys_buf_dissector_keys));
--- zfcpdump-kernel-4.4.orig/net/core/neighbour.c
+++ zfcpdump-kernel-4.4/net/core/neighbour.c
@@ -2467,13 +2467,17 @@ int neigh_xmit(int index, struct net_dev
 		tbl = neigh_tables[index];
 		if (!tbl)
 			goto out;
+		rcu_read_lock_bh();
 		neigh = __neigh_lookup_noref(tbl, addr, dev);
 		if (!neigh)
 			neigh = __neigh_create(tbl, addr, dev, false);
 		err = PTR_ERR(neigh);
-		if (IS_ERR(neigh))
+		if (IS_ERR(neigh)) {
+			rcu_read_unlock_bh();
 			goto out_kfree_skb;
+		}
 		err = neigh->output(neigh, skb);
+		rcu_read_unlock_bh();
 	}
 	else if (index == NEIGH_LINK_TABLE) {
 		err = dev_hard_header(skb, dev, ntohs(skb->protocol),
--- zfcpdump-kernel-4.4.orig/net/core/pktgen.c
+++ zfcpdump-kernel-4.4/net/core/pktgen.c
@@ -2787,7 +2787,9 @@ static struct sk_buff *pktgen_alloc_skb(
 	} else {
 		 skb = __netdev_alloc_skb(dev, size, GFP_NOWAIT);
 	}
-	skb_reserve(skb, LL_RESERVED_SPACE(dev));
+
+	if (likely(skb))
+		skb_reserve(skb, LL_RESERVED_SPACE(dev));
 
 	return skb;
 }
--- zfcpdump-kernel-4.4.orig/net/core/rtnetlink.c
+++ zfcpdump-kernel-4.4/net/core/rtnetlink.c
@@ -905,6 +905,7 @@ static noinline size_t if_nlmsg_size(con
 	       + rtnl_link_get_af_size(dev, ext_filter_mask) /* IFLA_AF_SPEC */
 	       + nla_total_size(MAX_PHYS_ITEM_ID_LEN) /* IFLA_PHYS_PORT_ID */
 	       + nla_total_size(MAX_PHYS_ITEM_ID_LEN) /* IFLA_PHYS_SWITCH_ID */
+	       + nla_total_size(IFNAMSIZ) /* IFLA_PHYS_PORT_NAME */
 	       + nla_total_size(1); /* IFLA_PROTO_DOWN */
 
 }
@@ -1174,14 +1175,16 @@ static noinline_for_stack int rtnl_fill_
 
 static int rtnl_fill_link_ifmap(struct sk_buff *skb, struct net_device *dev)
 {
-	struct rtnl_link_ifmap map = {
-		.mem_start   = dev->mem_start,
-		.mem_end     = dev->mem_end,
-		.base_addr   = dev->base_addr,
-		.irq         = dev->irq,
-		.dma         = dev->dma,
-		.port        = dev->if_port,
-	};
+	struct rtnl_link_ifmap map;
+
+	memset(&map, 0, sizeof(map));
+	map.mem_start   = dev->mem_start;
+	map.mem_end     = dev->mem_end;
+	map.base_addr   = dev->base_addr;
+	map.irq         = dev->irq;
+	map.dma         = dev->dma;
+	map.port        = dev->if_port;
+
 	if (nla_put(skb, IFLA_MAP, sizeof(map), &map))
 		return -EMSGSIZE;
 
--- zfcpdump-kernel-4.4.orig/net/core/scm.c
+++ zfcpdump-kernel-4.4/net/core/scm.c
@@ -87,6 +87,7 @@ static int scm_fp_copy(struct cmsghdr *c
 		*fplp = fpl;
 		fpl->count = 0;
 		fpl->max = SCM_MAX_FD;
+		fpl->user = NULL;
 	}
 	fpp = &fpl->fp[fpl->count];
 
@@ -107,6 +108,10 @@ static int scm_fp_copy(struct cmsghdr *c
 		*fpp++ = file;
 		fpl->count++;
 	}
+
+	if (!fpl->user)
+		fpl->user = get_uid(current_user());
+
 	return num;
 }
 
@@ -119,6 +124,7 @@ void __scm_destroy(struct scm_cookie *sc
 		scm->fp = NULL;
 		for (i=fpl->count-1; i>=0; i--)
 			fput(fpl->fp[i]);
+		free_uid(fpl->user);
 		kfree(fpl);
 	}
 }
@@ -336,6 +342,7 @@ struct scm_fp_list *scm_fp_dup(struct sc
 		for (i = 0; i < fpl->count; i++)
 			get_file(fpl->fp[i]);
 		new_fpl->max = new_fpl->count;
+		new_fpl->user = get_uid(fpl->user);
 	}
 	return new_fpl;
 }
--- zfcpdump-kernel-4.4.orig/net/core/skbuff.c
+++ zfcpdump-kernel-4.4/net/core/skbuff.c
@@ -79,6 +79,8 @@
 
 struct kmem_cache *skbuff_head_cache __read_mostly;
 static struct kmem_cache *skbuff_fclone_cache __read_mostly;
+int sysctl_max_skb_frags __read_mostly = MAX_SKB_FRAGS;
+EXPORT_SYMBOL(sysctl_max_skb_frags);
 
 /**
  *	skb_panic - private function for out-of-line support
@@ -347,8 +349,16 @@ struct sk_buff *build_skb(void *data, un
 }
 EXPORT_SYMBOL(build_skb);
 
+#define NAPI_SKB_CACHE_SIZE	64
+
+struct napi_alloc_cache {
+	struct page_frag_cache page;
+	size_t skb_count;
+	void *skb_cache[NAPI_SKB_CACHE_SIZE];
+};
+
 static DEFINE_PER_CPU(struct page_frag_cache, netdev_alloc_cache);
-static DEFINE_PER_CPU(struct page_frag_cache, napi_alloc_cache);
+static DEFINE_PER_CPU(struct napi_alloc_cache, napi_alloc_cache);
 
 static void *__netdev_alloc_frag(unsigned int fragsz, gfp_t gfp_mask)
 {
@@ -378,9 +388,9 @@ EXPORT_SYMBOL(netdev_alloc_frag);
 
 static void *__napi_alloc_frag(unsigned int fragsz, gfp_t gfp_mask)
 {
-	struct page_frag_cache *nc = this_cpu_ptr(&napi_alloc_cache);
+	struct napi_alloc_cache *nc = this_cpu_ptr(&napi_alloc_cache);
 
-	return __alloc_page_frag(nc, fragsz, gfp_mask);
+	return __alloc_page_frag(&nc->page, fragsz, gfp_mask);
 }
 
 void *napi_alloc_frag(unsigned int fragsz)
@@ -474,7 +484,7 @@ EXPORT_SYMBOL(__netdev_alloc_skb);
 struct sk_buff *__napi_alloc_skb(struct napi_struct *napi, unsigned int len,
 				 gfp_t gfp_mask)
 {
-	struct page_frag_cache *nc = this_cpu_ptr(&napi_alloc_cache);
+	struct napi_alloc_cache *nc = this_cpu_ptr(&napi_alloc_cache);
 	struct sk_buff *skb;
 	void *data;
 
@@ -494,7 +504,7 @@ struct sk_buff *__napi_alloc_skb(struct
 	if (sk_memalloc_socks())
 		gfp_mask |= __GFP_MEMALLOC;
 
-	data = __alloc_page_frag(nc, len, gfp_mask);
+	data = __alloc_page_frag(&nc->page, len, gfp_mask);
 	if (unlikely(!data))
 		return NULL;
 
@@ -505,7 +515,7 @@ struct sk_buff *__napi_alloc_skb(struct
 	}
 
 	/* use OR instead of assignment to avoid clearing of bits in mask */
-	if (nc->pfmemalloc)
+	if (nc->page.pfmemalloc)
 		skb->pfmemalloc = 1;
 	skb->head_frag = 1;
 
@@ -747,6 +757,69 @@ void consume_skb(struct sk_buff *skb)
 }
 EXPORT_SYMBOL(consume_skb);
 
+void __kfree_skb_flush(void)
+{
+	struct napi_alloc_cache *nc = this_cpu_ptr(&napi_alloc_cache);
+
+	/* flush skb_cache if containing objects */
+	if (nc->skb_count) {
+		kmem_cache_free_bulk(skbuff_head_cache, nc->skb_count,
+				     nc->skb_cache);
+		nc->skb_count = 0;
+	}
+}
+
+static void __kfree_skb_defer(struct sk_buff *skb)
+{
+	struct napi_alloc_cache *nc = this_cpu_ptr(&napi_alloc_cache);
+
+	/* drop skb->head and call any destructors for packet */
+	skb_release_all(skb);
+
+	/* record skb to CPU local list */
+	nc->skb_cache[nc->skb_count++] = skb;
+
+#ifdef CONFIG_SLUB
+	/* SLUB writes into objects when freeing */
+	prefetchw(skb);
+#endif
+
+	/* flush skb_cache if it is filled */
+	if (unlikely(nc->skb_count == NAPI_SKB_CACHE_SIZE)) {
+		kmem_cache_free_bulk(skbuff_head_cache, NAPI_SKB_CACHE_SIZE,
+				     nc->skb_cache);
+		nc->skb_count = 0;
+	}
+}
+
+void napi_consume_skb(struct sk_buff *skb, int budget)
+{
+	if (unlikely(!skb))
+		return;
+
+	/* if budget is 0 assume netpoll w/ IRQs disabled */
+	if (unlikely(!budget)) {
+		dev_consume_skb_irq(skb);
+		return;
+	}
+
+	if (likely(atomic_read(&skb->users) == 1))
+		smp_rmb();
+	else if (likely(!atomic_dec_and_test(&skb->users)))
+		return;
+	/* if reaching here SKB is ready to free */
+	trace_consume_skb(skb);
+
+	/* if SKB is a clone, don't handle this case */
+	if (unlikely(skb->fclone != SKB_FCLONE_UNAVAILABLE)) {
+		__kfree_skb(skb);
+		return;
+	}
+
+	__kfree_skb_defer(skb);
+}
+EXPORT_SYMBOL(napi_consume_skb);
+
 /* Make sure a field is enclosed inside headers_start/headers_end section */
 #define CHECK_SKB_FIELD(field) \
 	BUILD_BUG_ON(offsetof(struct sk_buff, field) <		\
@@ -4082,9 +4155,9 @@ struct sk_buff *skb_checksum_trimmed(str
 	if (!pskb_may_pull(skb_chk, offset))
 		goto err;
 
-	__skb_pull(skb_chk, offset);
+	skb_pull_rcsum(skb_chk, offset);
 	ret = skb_chkf(skb_chk);
-	__skb_push(skb_chk, offset);
+	skb_push_rcsum(skb_chk, offset);
 
 	if (ret)
 		goto err;
@@ -4407,15 +4480,16 @@ int skb_vlan_push(struct sk_buff *skb, _
 		__skb_push(skb, offset);
 		err = __vlan_insert_tag(skb, skb->vlan_proto,
 					skb_vlan_tag_get(skb));
-		if (err)
+		if (err) {
+			__skb_pull(skb, offset);
 			return err;
+		}
+
 		skb->protocol = skb->vlan_proto;
 		skb->mac_len += VLAN_HLEN;
-		__skb_pull(skb, offset);
 
-		if (skb->ip_summed == CHECKSUM_COMPLETE)
-			skb->csum = csum_add(skb->csum, csum_partial(skb->data
-					+ (2 * ETH_ALEN), VLAN_HLEN, 0));
+		skb_postpush_rcsum(skb, skb->data + (2 * ETH_ALEN), VLAN_HLEN);
+		__skb_pull(skb, offset);
 	}
 	__vlan_hwaccel_put_tag(skb, vlan_proto, vlan_tci);
 	return 0;
--- zfcpdump-kernel-4.4.orig/net/core/sysctl_net_core.c
+++ zfcpdump-kernel-4.4/net/core/sysctl_net_core.c
@@ -26,6 +26,7 @@ static int zero = 0;
 static int one = 1;
 static int min_sndbuf = SOCK_MIN_SNDBUF;
 static int min_rcvbuf = SOCK_MIN_RCVBUF;
+static int max_skb_frags = MAX_SKB_FRAGS;
 
 static int net_msg_warn;	/* Unused, but still a sysctl */
 
@@ -392,6 +393,15 @@ static struct ctl_table net_core_table[]
 		.mode		= 0644,
 		.proc_handler	= proc_dointvec
 	},
+	{
+		.procname	= "max_skb_frags",
+		.data		= &sysctl_max_skb_frags,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= proc_dointvec_minmax,
+		.extra1		= &one,
+		.extra2		= &max_skb_frags,
+	},
 	{ }
 };
 
--- zfcpdump-kernel-4.4.orig/net/dccp/ipv4.c
+++ zfcpdump-kernel-4.4/net/dccp/ipv4.c
@@ -204,8 +204,6 @@ void dccp_req_err(struct sock *sk, u64 s
 	 * ICMPs are not backlogged, hence we cannot get an established
 	 * socket here.
 	 */
-	WARN_ON(req->sk);
-
 	if (!between48(seq, dccp_rsk(req)->dreq_iss, dccp_rsk(req)->dreq_gss)) {
 		NET_INC_STATS_BH(net, LINUX_MIB_OUTOFWINDOWICMPS);
 	} else {
@@ -824,26 +822,26 @@ lookup:
 
 	if (sk->sk_state == DCCP_NEW_SYN_RECV) {
 		struct request_sock *req = inet_reqsk(sk);
-		struct sock *nsk = NULL;
+		struct sock *nsk;
 
 		sk = req->rsk_listener;
-		if (likely(sk->sk_state == DCCP_LISTEN)) {
-			nsk = dccp_check_req(sk, skb, req);
-		} else {
+		if (unlikely(sk->sk_state != DCCP_LISTEN)) {
 			inet_csk_reqsk_queue_drop_and_put(sk, req);
 			goto lookup;
 		}
+		sock_hold(sk);
+		nsk = dccp_check_req(sk, skb, req);
 		if (!nsk) {
 			reqsk_put(req);
-			goto discard_it;
+			goto discard_and_relse;
 		}
 		if (nsk == sk) {
-			sock_hold(sk);
 			reqsk_put(req);
 		} else if (dccp_child_process(sk, nsk, skb)) {
 			dccp_v4_ctl_send_reset(sk, skb);
-			goto discard_it;
+			goto discard_and_relse;
 		} else {
+			sock_put(sk);
 			return 0;
 		}
 	}
--- zfcpdump-kernel-4.4.orig/net/dccp/ipv6.c
+++ zfcpdump-kernel-4.4/net/dccp/ipv6.c
@@ -691,26 +691,26 @@ lookup:
 
 	if (sk->sk_state == DCCP_NEW_SYN_RECV) {
 		struct request_sock *req = inet_reqsk(sk);
-		struct sock *nsk = NULL;
+		struct sock *nsk;
 
 		sk = req->rsk_listener;
-		if (likely(sk->sk_state == DCCP_LISTEN)) {
-			nsk = dccp_check_req(sk, skb, req);
-		} else {
+		if (unlikely(sk->sk_state != DCCP_LISTEN)) {
 			inet_csk_reqsk_queue_drop_and_put(sk, req);
 			goto lookup;
 		}
+		sock_hold(sk);
+		nsk = dccp_check_req(sk, skb, req);
 		if (!nsk) {
 			reqsk_put(req);
-			goto discard_it;
+			goto discard_and_relse;
 		}
 		if (nsk == sk) {
-			sock_hold(sk);
 			reqsk_put(req);
 		} else if (dccp_child_process(sk, nsk, skb)) {
 			dccp_v6_ctl_send_reset(sk, skb);
-			goto discard_it;
+			goto discard_and_relse;
 		} else {
+			sock_put(sk);
 			return 0;
 		}
 	}
--- zfcpdump-kernel-4.4.orig/net/decnet/dn_route.c
+++ zfcpdump-kernel-4.4/net/decnet/dn_route.c
@@ -1034,10 +1034,13 @@ source_ok:
 	if (!fld.daddr) {
 		fld.daddr = fld.saddr;
 
-		err = -EADDRNOTAVAIL;
 		if (dev_out)
 			dev_put(dev_out);
+		err = -EINVAL;
 		dev_out = init_net.loopback_dev;
+		if (!dev_out->dn_ptr)
+			goto out;
+		err = -EADDRNOTAVAIL;
 		dev_hold(dev_out);
 		if (!fld.daddr) {
 			fld.daddr =
@@ -1110,6 +1113,8 @@ source_ok:
 		if (dev_out == NULL)
 			goto out;
 		dn_db = rcu_dereference_raw(dev_out->dn_ptr);
+		if (!dn_db)
+			goto e_inval;
 		/* Possible improvement - check all devices for local addr */
 		if (dn_dev_islocal(dev_out, fld.daddr)) {
 			dev_put(dev_out);
@@ -1151,6 +1156,8 @@ select_source:
 			dev_put(dev_out);
 		dev_out = init_net.loopback_dev;
 		dev_hold(dev_out);
+		if (!dev_out->dn_ptr)
+			goto e_inval;
 		fld.flowidn_oif = dev_out->ifindex;
 		if (res.fi)
 			dn_fib_info_put(res.fi);
--- zfcpdump-kernel-4.4.orig/net/ethernet/eth.c
+++ zfcpdump-kernel-4.4/net/ethernet/eth.c
@@ -52,6 +52,8 @@
 #include <linux/errno.h>
 #include <linux/init.h>
 #include <linux/if_ether.h>
+#include <linux/of_net.h>
+#include <linux/pci.h>
 #include <net/dst.h>
 #include <net/arp.h>
 #include <net/sock.h>
@@ -436,7 +438,7 @@ struct sk_buff **eth_gro_receive(struct
 
 	skb_gro_pull(skb, sizeof(*eh));
 	skb_gro_postpull_rcsum(skb, eh, sizeof(*eh));
-	pp = ptype->callbacks.gro_receive(head, skb);
+	pp = call_gro_receive(ptype->callbacks.gro_receive, head, skb);
 
 out_unlock:
 	rcu_read_unlock();
@@ -485,3 +487,32 @@ static int __init eth_offload_init(void)
 }
 
 fs_initcall(eth_offload_init);
+
+unsigned char * __weak arch_get_platform_mac_address(void)
+{
+	return NULL;
+}
+
+int eth_platform_get_mac_address(struct device *dev, u8 *mac_addr)
+{
+	const unsigned char *addr;
+	struct device_node *dp;
+
+	if (dev_is_pci(dev))
+		dp = pci_device_to_OF_node(to_pci_dev(dev));
+	else
+		dp = dev->of_node;
+
+	addr = NULL;
+	if (dp)
+		addr = of_get_mac_address(dp);
+	if (!addr)
+		addr = arch_get_platform_mac_address();
+
+	if (!addr)
+		return -ENODEV;
+
+	ether_addr_copy(mac_addr, addr);
+	return 0;
+}
+EXPORT_SYMBOL(eth_platform_get_mac_address);
--- zfcpdump-kernel-4.4.orig/net/ipv4/af_inet.c
+++ zfcpdump-kernel-4.4/net/ipv4/af_inet.c
@@ -1372,7 +1372,7 @@ static struct sk_buff **inet_gro_receive
 	skb_gro_pull(skb, sizeof(*iph));
 	skb_set_transport_header(skb, skb_gro_offset(skb));
 
-	pp = ops->callbacks.gro_receive(head, skb);
+	pp = call_gro_receive(ops->callbacks.gro_receive, head, skb);
 
 out_unlock:
 	rcu_read_unlock();
@@ -1383,6 +1383,19 @@ out:
 	return pp;
 }
 
+static struct sk_buff **ipip_gro_receive(struct sk_buff **head,
+					 struct sk_buff *skb)
+{
+	if (NAPI_GRO_CB(skb)->encap_mark) {
+		NAPI_GRO_CB(skb)->flush = 1;
+		return NULL;
+	}
+
+	NAPI_GRO_CB(skb)->encap_mark = 1;
+
+	return inet_gro_receive(head, skb);
+}
+
 int inet_recv_error(struct sock *sk, struct msghdr *msg, int len, int *addr_len)
 {
 	if (sk->sk_family == AF_INET)
@@ -1652,7 +1665,7 @@ static struct packet_offload ip_packet_o
 static const struct net_offload ipip_offload = {
 	.callbacks = {
 		.gso_segment	= inet_gso_segment,
-		.gro_receive	= inet_gro_receive,
+		.gro_receive	= ipip_gro_receive,
 		.gro_complete	= inet_gro_complete,
 	},
 };
--- zfcpdump-kernel-4.4.orig/net/ipv4/devinet.c
+++ zfcpdump-kernel-4.4/net/ipv4/devinet.c
@@ -334,6 +334,9 @@ static void __inet_del_ifa(struct in_dev
 
 	ASSERT_RTNL();
 
+	if (in_dev->dead)
+		goto no_promotions;
+
 	/* 1. Deleting primary ifaddr forces deletion all secondaries
 	 * unless alias promotion is set
 	 **/
@@ -380,6 +383,7 @@ static void __inet_del_ifa(struct in_dev
 			fib_del_ifaddr(ifa, ifa1);
 	}
 
+no_promotions:
 	/* 2. Unlink it */
 
 	*ifap = ifa1->ifa_next;
@@ -1847,7 +1851,7 @@ static int inet_netconf_get_devconf(stru
 	if (err < 0)
 		goto errout;
 
-	err = EINVAL;
+	err = -EINVAL;
 	if (!tb[NETCONFA_IFINDEX])
 		goto errout;
 
--- zfcpdump-kernel-4.4.orig/net/ipv4/esp4.c
+++ zfcpdump-kernel-4.4/net/ipv4/esp4.c
@@ -23,6 +23,11 @@ struct esp_skb_cb {
 	void *tmp;
 };
 
+struct esp_output_extra {
+	__be32 seqhi;
+	u32 esphoff;
+};
+
 #define ESP_SKB_CB(__skb) ((struct esp_skb_cb *)&((__skb)->cb[0]))
 
 static u32 esp4_get_mtu(struct xfrm_state *x, int mtu);
@@ -35,11 +40,11 @@ static u32 esp4_get_mtu(struct xfrm_stat
  *
  * TODO: Use spare space in skb for this where possible.
  */
-static void *esp_alloc_tmp(struct crypto_aead *aead, int nfrags, int seqhilen)
+static void *esp_alloc_tmp(struct crypto_aead *aead, int nfrags, int extralen)
 {
 	unsigned int len;
 
-	len = seqhilen;
+	len = extralen;
 
 	len += crypto_aead_ivsize(aead);
 
@@ -57,15 +62,16 @@ static void *esp_alloc_tmp(struct crypto
 	return kmalloc(len, GFP_ATOMIC);
 }
 
-static inline __be32 *esp_tmp_seqhi(void *tmp)
+static inline void *esp_tmp_extra(void *tmp)
 {
-	return PTR_ALIGN((__be32 *)tmp, __alignof__(__be32));
+	return PTR_ALIGN(tmp, __alignof__(struct esp_output_extra));
 }
-static inline u8 *esp_tmp_iv(struct crypto_aead *aead, void *tmp, int seqhilen)
+
+static inline u8 *esp_tmp_iv(struct crypto_aead *aead, void *tmp, int extralen)
 {
 	return crypto_aead_ivsize(aead) ?
-	       PTR_ALIGN((u8 *)tmp + seqhilen,
-			 crypto_aead_alignmask(aead) + 1) : tmp + seqhilen;
+	       PTR_ALIGN((u8 *)tmp + extralen,
+			 crypto_aead_alignmask(aead) + 1) : tmp + extralen;
 }
 
 static inline struct aead_request *esp_tmp_req(struct crypto_aead *aead, u8 *iv)
@@ -99,7 +105,7 @@ static void esp_restore_header(struct sk
 {
 	struct ip_esp_hdr *esph = (void *)(skb->data + offset);
 	void *tmp = ESP_SKB_CB(skb)->tmp;
-	__be32 *seqhi = esp_tmp_seqhi(tmp);
+	__be32 *seqhi = esp_tmp_extra(tmp);
 
 	esph->seq_no = esph->spi;
 	esph->spi = *seqhi;
@@ -107,7 +113,11 @@ static void esp_restore_header(struct sk
 
 static void esp_output_restore_header(struct sk_buff *skb)
 {
-	esp_restore_header(skb, skb_transport_offset(skb) - sizeof(__be32));
+	void *tmp = ESP_SKB_CB(skb)->tmp;
+	struct esp_output_extra *extra = esp_tmp_extra(tmp);
+
+	esp_restore_header(skb, skb_transport_offset(skb) + extra->esphoff -
+				sizeof(__be32));
 }
 
 static void esp_output_done_esn(struct crypto_async_request *base, int err)
@@ -121,6 +131,7 @@ static void esp_output_done_esn(struct c
 static int esp_output(struct xfrm_state *x, struct sk_buff *skb)
 {
 	int err;
+	struct esp_output_extra *extra;
 	struct ip_esp_hdr *esph;
 	struct crypto_aead *aead;
 	struct aead_request *req;
@@ -137,8 +148,7 @@ static int esp_output(struct xfrm_state
 	int tfclen;
 	int nfrags;
 	int assoclen;
-	int seqhilen;
-	__be32 *seqhi;
+	int extralen;
 	__be64 seqno;
 
 	/* skb is pure payload to encrypt */
@@ -166,21 +176,21 @@ static int esp_output(struct xfrm_state
 	nfrags = err;
 
 	assoclen = sizeof(*esph);
-	seqhilen = 0;
+	extralen = 0;
 
 	if (x->props.flags & XFRM_STATE_ESN) {
-		seqhilen += sizeof(__be32);
-		assoclen += seqhilen;
+		extralen += sizeof(*extra);
+		assoclen += sizeof(__be32);
 	}
 
-	tmp = esp_alloc_tmp(aead, nfrags, seqhilen);
+	tmp = esp_alloc_tmp(aead, nfrags, extralen);
 	if (!tmp) {
 		err = -ENOMEM;
 		goto error;
 	}
 
-	seqhi = esp_tmp_seqhi(tmp);
-	iv = esp_tmp_iv(aead, tmp, seqhilen);
+	extra = esp_tmp_extra(tmp);
+	iv = esp_tmp_iv(aead, tmp, extralen);
 	req = esp_tmp_req(aead, iv);
 	sg = esp_req_sg(aead, req);
 
@@ -247,8 +257,10 @@ static int esp_output(struct xfrm_state
 	 * encryption.
 	 */
 	if ((x->props.flags & XFRM_STATE_ESN)) {
-		esph = (void *)(skb_transport_header(skb) - sizeof(__be32));
-		*seqhi = esph->spi;
+		extra->esphoff = (unsigned char *)esph -
+				 skb_transport_header(skb);
+		esph = (struct ip_esp_hdr *)((unsigned char *)esph - 4);
+		extra->seqhi = esph->spi;
 		esph->seq_no = htonl(XFRM_SKB_CB(skb)->seq.output.hi);
 		aead_request_set_callback(req, 0, esp_output_done_esn, skb);
 	}
@@ -445,7 +457,7 @@ static int esp_input(struct xfrm_state *
 		goto out;
 
 	ESP_SKB_CB(skb)->tmp = tmp;
-	seqhi = esp_tmp_seqhi(tmp);
+	seqhi = esp_tmp_extra(tmp);
 	iv = esp_tmp_iv(aead, tmp, seqhilen);
 	req = esp_tmp_req(aead, iv);
 	sg = esp_req_sg(aead, req);
--- zfcpdump-kernel-4.4.orig/net/ipv4/fib_frontend.c
+++ zfcpdump-kernel-4.4/net/ipv4/fib_frontend.c
@@ -280,7 +280,6 @@ __be32 fib_compute_spec_dst(struct sk_bu
 	struct in_device *in_dev;
 	struct fib_result res;
 	struct rtable *rt;
-	struct flowi4 fl4;
 	struct net *net;
 	int scope;
 
@@ -296,14 +295,13 @@ __be32 fib_compute_spec_dst(struct sk_bu
 
 	scope = RT_SCOPE_UNIVERSE;
 	if (!ipv4_is_zeronet(ip_hdr(skb)->saddr)) {
-		fl4.flowi4_oif = 0;
-		fl4.flowi4_iif = LOOPBACK_IFINDEX;
-		fl4.daddr = ip_hdr(skb)->saddr;
-		fl4.saddr = 0;
-		fl4.flowi4_tos = RT_TOS(ip_hdr(skb)->tos);
-		fl4.flowi4_scope = scope;
-		fl4.flowi4_mark = IN_DEV_SRC_VMARK(in_dev) ? skb->mark : 0;
-		fl4.flowi4_tun_key.tun_id = 0;
+		struct flowi4 fl4 = {
+			.flowi4_iif = LOOPBACK_IFINDEX,
+			.daddr = ip_hdr(skb)->saddr,
+			.flowi4_tos = RT_TOS(ip_hdr(skb)->tos),
+			.flowi4_scope = scope,
+			.flowi4_mark = IN_DEV_SRC_VMARK(in_dev) ? skb->mark : 0,
+		};
 		if (!fib_lookup(net, &fl4, &res, 0))
 			return FIB_RES_PREFSRC(net, res);
 	} else {
@@ -906,7 +904,11 @@ void fib_del_ifaddr(struct in_ifaddr *if
 	if (ifa->ifa_flags & IFA_F_SECONDARY) {
 		prim = inet_ifa_byprefix(in_dev, any, ifa->ifa_mask);
 		if (!prim) {
-			pr_warn("%s: bug: prim == NULL\n", __func__);
+			/* if the device has been deleted, we don't perform
+			 * address promotion
+			 */
+			if (!in_dev->dead)
+				pr_warn("%s: bug: prim == NULL\n", __func__);
 			return;
 		}
 		if (iprim && iprim != prim) {
@@ -922,6 +924,9 @@ void fib_del_ifaddr(struct in_ifaddr *if
 		subnet = 1;
 	}
 
+	if (in_dev->dead)
+		goto no_promotions;
+
 	/* Deletion is more complicated than add.
 	 * We should take care of not to delete too much :-)
 	 *
@@ -997,6 +1002,7 @@ void fib_del_ifaddr(struct in_ifaddr *if
 		}
 	}
 
+no_promotions:
 	if (!(ok & BRD_OK))
 		fib_magic(RTM_DELROUTE, RTN_BROADCAST, ifa->ifa_broadcast, 32, prim);
 	if (subnet && ifa->ifa_prefixlen < 31) {
--- zfcpdump-kernel-4.4.orig/net/ipv4/fib_semantics.c
+++ zfcpdump-kernel-4.4/net/ipv4/fib_semantics.c
@@ -479,6 +479,9 @@ static int fib_get_nhs(struct fib_info *
 		if (!rtnh_ok(rtnh, remaining))
 			return -EINVAL;
 
+		if (rtnh->rtnh_flags & (RTNH_F_DEAD | RTNH_F_LINKDOWN))
+			return -EINVAL;
+
 		nexthop_nh->nh_flags =
 			(cfg->fc_flags & ~0xFF) | rtnh->rtnh_flags;
 		nexthop_nh->nh_oif = rtnh->rtnh_ifindex;
@@ -975,6 +978,8 @@ fib_convert_metrics(struct fib_info *fi,
 			val = 65535 - 40;
 		if (type == RTAX_MTU && val > 65535 - 15)
 			val = 65535 - 15;
+		if (type == RTAX_HOPLIMIT && val > 255)
+			val = 255;
 		if (type == RTAX_FEATURES && (val & ~RTAX_FEATURE_MASK))
 			return -EINVAL;
 		fi->fib_metrics[type - 1] = val;
@@ -1001,6 +1006,9 @@ struct fib_info *fib_create_info(struct
 	if (fib_props[cfg->fc_type].scope > cfg->fc_scope)
 		goto err_inval;
 
+	if (cfg->fc_flags & (RTNH_F_DEAD | RTNH_F_LINKDOWN))
+		goto err_inval;
+
 #ifdef CONFIG_IP_ROUTE_MULTIPATH
 	if (cfg->fc_mp) {
 		nhs = fib_count_nexthops(cfg->fc_mp, cfg->fc_mp_len);
--- zfcpdump-kernel-4.4.orig/net/ipv4/fib_trie.c
+++ zfcpdump-kernel-4.4/net/ipv4/fib_trie.c
@@ -2453,9 +2453,7 @@ struct fib_route_iter {
 static struct key_vector *fib_route_get_idx(struct fib_route_iter *iter,
 					    loff_t pos)
 {
-	struct fib_table *tb = iter->main_tb;
 	struct key_vector *l, **tp = &iter->tnode;
-	struct trie *t;
 	t_key key;
 
 	/* use cache location of next-to-find key */
@@ -2463,8 +2461,6 @@ static struct key_vector *fib_route_get_
 		pos -= iter->pos;
 		key = iter->key;
 	} else {
-		t = (struct trie *)tb->tb_data;
-		iter->tnode = t->kv;
 		iter->pos = 0;
 		key = 0;
 	}
@@ -2505,12 +2501,12 @@ static void *fib_route_seq_start(struct
 		return NULL;
 
 	iter->main_tb = tb;
+	t = (struct trie *)tb->tb_data;
+	iter->tnode = t->kv;
 
 	if (*pos != 0)
 		return fib_route_get_idx(iter, *pos);
 
-	t = (struct trie *)tb->tb_data;
-	iter->tnode = t->kv;
 	iter->pos = 0;
 	iter->key = 0;
 
--- zfcpdump-kernel-4.4.orig/net/ipv4/fou.c
+++ zfcpdump-kernel-4.4/net/ipv4/fou.c
@@ -48,7 +48,7 @@ static inline struct fou *fou_from_sock(
 	return sk->sk_user_data;
 }
 
-static void fou_recv_pull(struct sk_buff *skb, size_t len)
+static int fou_recv_pull(struct sk_buff *skb, size_t len)
 {
 	struct iphdr *iph = ip_hdr(skb);
 
@@ -59,6 +59,7 @@ static void fou_recv_pull(struct sk_buff
 	__skb_pull(skb, len);
 	skb_postpull_rcsum(skb, udp_hdr(skb), len);
 	skb_reset_transport_header(skb);
+	return iptunnel_pull_offloads(skb);
 }
 
 static int fou_udp_recv(struct sock *sk, struct sk_buff *skb)
@@ -68,9 +69,14 @@ static int fou_udp_recv(struct sock *sk,
 	if (!fou)
 		return 1;
 
-	fou_recv_pull(skb, sizeof(struct udphdr));
+	if (fou_recv_pull(skb, sizeof(struct udphdr)))
+		goto drop;
 
 	return -fou->protocol;
+
+drop:
+	kfree_skb(skb);
+	return 0;
 }
 
 static struct guehdr *gue_remcsum(struct sk_buff *skb, struct guehdr *guehdr,
@@ -170,6 +176,9 @@ static int gue_udp_recv(struct sock *sk,
 	__skb_pull(skb, sizeof(struct udphdr) + hdrlen);
 	skb_reset_transport_header(skb);
 
+	if (iptunnel_pull_offloads(skb))
+		goto drop;
+
 	return -guehdr->proto_ctype;
 
 drop:
@@ -186,13 +195,21 @@ static struct sk_buff **fou_gro_receive(
 	u8 proto = NAPI_GRO_CB(skb)->proto;
 	const struct net_offload **offloads;
 
+	/* We can clear the encap_mark for FOU as we are essentially doing
+	 * one of two possible things.  We are either adding an L4 tunnel
+	 * header to the outer L3 tunnel header, or we are are simply
+	 * treating the GRE tunnel header as though it is a UDP protocol
+	 * specific header such as VXLAN or GENEVE.
+	 */
+	NAPI_GRO_CB(skb)->encap_mark = 0;
+
 	rcu_read_lock();
 	offloads = NAPI_GRO_CB(skb)->is_ipv6 ? inet6_offloads : inet_offloads;
 	ops = rcu_dereference(offloads[proto]);
 	if (!ops || !ops->callbacks.gro_receive)
 		goto out_unlock;
 
-	pp = ops->callbacks.gro_receive(head, skb);
+	pp = call_gro_receive(ops->callbacks.gro_receive, head, skb);
 
 out_unlock:
 	rcu_read_unlock();
@@ -345,13 +362,21 @@ static struct sk_buff **gue_gro_receive(
 		}
 	}
 
+	/* We can clear the encap_mark for GUE as we are essentially doing
+	 * one of two possible things.  We are either adding an L4 tunnel
+	 * header to the outer L3 tunnel header, or we are are simply
+	 * treating the GRE tunnel header as though it is a UDP protocol
+	 * specific header such as VXLAN or GENEVE.
+	 */
+	NAPI_GRO_CB(skb)->encap_mark = 0;
+
 	rcu_read_lock();
 	offloads = NAPI_GRO_CB(skb)->is_ipv6 ? inet6_offloads : inet_offloads;
 	ops = rcu_dereference(offloads[guehdr->proto_ctype]);
 	if (WARN_ON_ONCE(!ops || !ops->callbacks.gro_receive))
 		goto out_unlock;
 
-	pp = ops->callbacks.gro_receive(head, skb);
+	pp = call_gro_receive(ops->callbacks.gro_receive, head, skb);
 
 out_unlock:
 	rcu_read_unlock();
--- zfcpdump-kernel-4.4.orig/net/ipv4/gre_offload.c
+++ zfcpdump-kernel-4.4/net/ipv4/gre_offload.c
@@ -128,6 +128,11 @@ static struct sk_buff **gre_gro_receive(
 	struct packet_offload *ptype;
 	__be16 type;
 
+	if (NAPI_GRO_CB(skb)->encap_mark)
+		goto out;
+
+	NAPI_GRO_CB(skb)->encap_mark = 1;
+
 	off = skb_gro_offset(skb);
 	hlen = off + sizeof(*greh);
 	greh = skb_gro_header_fast(skb, off);
@@ -214,7 +219,7 @@ static struct sk_buff **gre_gro_receive(
 	/* Adjusted NAPI_GRO_CB(skb)->csum after skb_gro_pull()*/
 	skb_gro_postpull_rcsum(skb, greh, grehlen);
 
-	pp = ptype->callbacks.gro_receive(head, skb);
+	pp = call_gro_receive(ptype->callbacks.gro_receive, head, skb);
 
 out_unlock:
 	rcu_read_unlock();
--- zfcpdump-kernel-4.4.orig/net/ipv4/igmp.c
+++ zfcpdump-kernel-4.4/net/ipv4/igmp.c
@@ -356,9 +356,8 @@ static struct sk_buff *igmpv3_newpack(st
 	skb_dst_set(skb, &rt->dst);
 	skb->dev = dev;
 
-	skb->reserved_tailroom = skb_end_offset(skb) -
-				 min(mtu, skb_end_offset(skb));
 	skb_reserve(skb, hlen);
+	skb_tailroom_reserve(skb, mtu, tlen);
 
 	skb_reset_network_header(skb);
 	pip = ip_hdr(skb);
--- zfcpdump-kernel-4.4.orig/net/ipv4/inet_connection_sock.c
+++ zfcpdump-kernel-4.4/net/ipv4/inet_connection_sock.c
@@ -789,14 +789,16 @@ static void inet_child_forget(struct soc
 	reqsk_put(req);
 }
 
-void inet_csk_reqsk_queue_add(struct sock *sk, struct request_sock *req,
-			      struct sock *child)
+struct sock *inet_csk_reqsk_queue_add(struct sock *sk,
+				      struct request_sock *req,
+				      struct sock *child)
 {
 	struct request_sock_queue *queue = &inet_csk(sk)->icsk_accept_queue;
 
 	spin_lock(&queue->rskq_lock);
 	if (unlikely(sk->sk_state != TCP_LISTEN)) {
 		inet_child_forget(sk, req, child);
+		child = NULL;
 	} else {
 		req->sk = child;
 		req->dl_next = NULL;
@@ -808,6 +810,7 @@ void inet_csk_reqsk_queue_add(struct soc
 		sk_acceptq_added(sk);
 	}
 	spin_unlock(&queue->rskq_lock);
+	return child;
 }
 EXPORT_SYMBOL(inet_csk_reqsk_queue_add);
 
@@ -817,11 +820,8 @@ struct sock *inet_csk_complete_hashdance
 	if (own_req) {
 		inet_csk_reqsk_queue_drop(sk, req);
 		reqsk_queue_removed(&inet_csk(sk)->icsk_accept_queue, req);
-		inet_csk_reqsk_queue_add(sk, req, child);
-		/* Warning: caller must not call reqsk_put(req);
-		 * child stole last reference on it.
-		 */
-		return child;
+		if (inet_csk_reqsk_queue_add(sk, req, child))
+			return child;
 	}
 	/* Too bad, another child took ownership of the request, undo. */
 	bh_unlock_sock(child);
--- zfcpdump-kernel-4.4.orig/net/ipv4/ip_fragment.c
+++ zfcpdump-kernel-4.4/net/ipv4/ip_fragment.c
@@ -661,6 +661,7 @@ int ip_defrag(struct net *net, struct sk
 	struct ipq *qp;
 
 	IP_INC_STATS_BH(net, IPSTATS_MIB_REASMREQDS);
+	skb_orphan(skb);
 
 	/* Lookup (or create) queue header */
 	qp = ip_find(net, ip_hdr(skb), user, vif);
--- zfcpdump-kernel-4.4.orig/net/ipv4/ip_gre.c
+++ zfcpdump-kernel-4.4/net/ipv4/ip_gre.c
@@ -180,6 +180,7 @@ static __be16 tnl_flags_to_gre_flags(__b
 	return flags;
 }
 
+/* Fills in tpi and returns header length to be pulled. */
 static int parse_gre_header(struct sk_buff *skb, struct tnl_ptk_info *tpi,
 			    bool *csum_err)
 {
@@ -239,7 +240,7 @@ static int parse_gre_header(struct sk_bu
 				return -EINVAL;
 		}
 	}
-	return iptunnel_pull_header(skb, hdr_len, tpi->proto);
+	return hdr_len;
 }
 
 static void ipgre_err(struct sk_buff *skb, u32 info,
@@ -342,7 +343,7 @@ static void gre_err(struct sk_buff *skb,
 	struct tnl_ptk_info tpi;
 	bool csum_err = false;
 
-	if (parse_gre_header(skb, &tpi, &csum_err)) {
+	if (parse_gre_header(skb, &tpi, &csum_err) < 0) {
 		if (!csum_err)		/* ignore csum errors. */
 			return;
 	}
@@ -420,6 +421,7 @@ static int gre_rcv(struct sk_buff *skb)
 {
 	struct tnl_ptk_info tpi;
 	bool csum_err = false;
+	int hdr_len;
 
 #ifdef CONFIG_NET_IPGRE_BROADCAST
 	if (ipv4_is_multicast(ip_hdr(skb)->daddr)) {
@@ -429,7 +431,10 @@ static int gre_rcv(struct sk_buff *skb)
 	}
 #endif
 
-	if (parse_gre_header(skb, &tpi, &csum_err) < 0)
+	hdr_len = parse_gre_header(skb, &tpi, &csum_err);
+	if (hdr_len < 0)
+		goto drop;
+	if (iptunnel_pull_header(skb, hdr_len, tpi.proto) < 0)
 		goto drop;
 
 	if (ipgre_rcv(skb, &tpi) == PACKET_RCVD)
@@ -1242,6 +1247,14 @@ struct net_device *gretap_fb_dev_create(
 	err = ipgre_newlink(net, dev, tb, NULL);
 	if (err < 0)
 		goto out;
+
+	/* openvswitch users expect packet sizes to be unrestricted,
+	 * so set the largest MTU we can.
+	 */
+	err = __ip_tunnel_change_mtu(dev, IP_MAX_MTU, false);
+	if (err)
+		goto out;
+
 	return dev;
 out:
 	free_netdev(dev);
--- zfcpdump-kernel-4.4.orig/net/ipv4/ip_output.c
+++ zfcpdump-kernel-4.4/net/ipv4/ip_output.c
@@ -240,6 +240,7 @@ static int ip_finish_output_gso(struct n
 	 * from host network stack.
 	 */
 	features = netif_skb_features(skb);
+	BUILD_BUG_ON(sizeof(*IPCB(skb)) > SKB_SGO_CB_OFFSET);
 	segs = skb_gso_segment(skb, features & ~NETIF_F_GSO_MASK);
 	if (IS_ERR_OR_NULL(segs)) {
 		kfree_skb(skb);
@@ -921,7 +922,7 @@ static int __ip_append_data(struct sock
 	if (((length > mtu) || (skb && skb_is_gso(skb))) &&
 	    (sk->sk_protocol == IPPROTO_UDP) &&
 	    (rt->dst.dev->features & NETIF_F_UFO) && !rt->dst.header_len &&
-	    (sk->sk_type == SOCK_DGRAM)) {
+	    (sk->sk_type == SOCK_DGRAM) && !sk->sk_no_check_tx) {
 		err = ip_ufo_append_data(sk, queue, getfrag, from, length,
 					 hh_len, fragheaderlen, transhdrlen,
 					 maxfraglen, flags);
@@ -1236,13 +1237,16 @@ ssize_t	ip_append_page(struct sock *sk,
 	if (!skb)
 		return -EINVAL;
 
-	cork->length += size;
 	if ((size + skb->len > mtu) &&
 	    (sk->sk_protocol == IPPROTO_UDP) &&
 	    (rt->dst.dev->features & NETIF_F_UFO)) {
+		if (skb->ip_summed != CHECKSUM_PARTIAL)
+			return -EOPNOTSUPP;
+
 		skb_shinfo(skb)->gso_size = mtu - fragheaderlen;
 		skb_shinfo(skb)->gso_type = SKB_GSO_UDP;
 	}
+	cork->length += size;
 
 	while (size > 0) {
 		if (skb_is_gso(skb)) {
--- zfcpdump-kernel-4.4.orig/net/ipv4/ip_sockglue.c
+++ zfcpdump-kernel-4.4/net/ipv4/ip_sockglue.c
@@ -249,6 +249,8 @@ int ip_cmsg_send(struct net *net, struct
 		switch (cmsg->cmsg_type) {
 		case IP_RETOPTS:
 			err = cmsg->cmsg_len - CMSG_ALIGN(sizeof(struct cmsghdr));
+
+			/* Our caller is responsible for freeing ipc->opt */
 			err = ip_options_get(net, &ipc->opt, CMSG_DATA(cmsg),
 					     err < 40 ? err : 40);
 			if (err)
--- zfcpdump-kernel-4.4.orig/net/ipv4/ip_tunnel.c
+++ zfcpdump-kernel-4.4/net/ipv4/ip_tunnel.c
@@ -663,6 +663,8 @@ void ip_tunnel_xmit(struct sk_buff *skb,
 	inner_iph = (const struct iphdr *)skb_inner_network_header(skb);
 	connected = (tunnel->parms.iph.daddr != 0);
 
+	memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt));
+
 	dst = tnl_params->daddr;
 	if (dst == 0) {
 		/* NBMA tunnel */
@@ -760,7 +762,6 @@ void ip_tunnel_xmit(struct sk_buff *skb,
 				tunnel->err_time + IPTUNNEL_ERR_TIMEO)) {
 			tunnel->err_count--;
 
-			memset(IPCB(skb), 0, sizeof(*IPCB(skb)));
 			dst_link_failure(skb);
 		} else
 			tunnel->err_count = 0;
@@ -947,17 +948,31 @@ done:
 }
 EXPORT_SYMBOL_GPL(ip_tunnel_ioctl);
 
-int ip_tunnel_change_mtu(struct net_device *dev, int new_mtu)
+int __ip_tunnel_change_mtu(struct net_device *dev, int new_mtu, bool strict)
 {
 	struct ip_tunnel *tunnel = netdev_priv(dev);
 	int t_hlen = tunnel->hlen + sizeof(struct iphdr);
+	int max_mtu = 0xFFF8 - dev->hard_header_len - t_hlen;
 
-	if (new_mtu < 68 ||
-	    new_mtu > 0xFFF8 - dev->hard_header_len - t_hlen)
+	if (new_mtu < 68)
 		return -EINVAL;
+
+	if (new_mtu > max_mtu) {
+		if (strict)
+			return -EINVAL;
+
+		new_mtu = max_mtu;
+	}
+
 	dev->mtu = new_mtu;
 	return 0;
 }
+EXPORT_SYMBOL_GPL(__ip_tunnel_change_mtu);
+
+int ip_tunnel_change_mtu(struct net_device *dev, int new_mtu)
+{
+	return __ip_tunnel_change_mtu(dev, new_mtu, true);
+}
 EXPORT_SYMBOL_GPL(ip_tunnel_change_mtu);
 
 static void ip_tunnel_dev_free(struct net_device *dev)
@@ -1119,7 +1134,7 @@ int ip_tunnel_changelink(struct net_devi
 	struct ip_tunnel_net *itn = net_generic(net, tunnel->ip_tnl_net_id);
 
 	if (dev == itn->fb_tunnel_dev)
-		return -EINVAL;
+		return fan_has_map(&tunnel->fan) ? 0 : -EINVAL;
 
 	t = ip_tunnel_find(itn, p, dev->type);
 
--- zfcpdump-kernel-4.4.orig/net/ipv4/ip_tunnel_core.c
+++ zfcpdump-kernel-4.4/net/ipv4/ip_tunnel_core.c
@@ -116,7 +116,8 @@ int iptunnel_pull_header(struct sk_buff
 	skb->vlan_tci = 0;
 	skb_set_queue_mapping(skb, 0);
 	skb->pkt_type = PACKET_HOST;
-	return 0;
+
+	return iptunnel_pull_offloads(skb);
 }
 EXPORT_SYMBOL_GPL(iptunnel_pull_header);
 
--- zfcpdump-kernel-4.4.orig/net/ipv4/ip_vti.c
+++ zfcpdump-kernel-4.4/net/ipv4/ip_vti.c
@@ -540,6 +540,33 @@ static struct rtnl_link_ops vti_link_ops
 	.get_link_net	= ip_tunnel_get_link_net,
 };
 
+static bool is_vti_tunnel(const struct net_device *dev)
+{
+	return dev->netdev_ops == &vti_netdev_ops;
+}
+
+static int vti_device_event(struct notifier_block *unused,
+			    unsigned long event, void *ptr)
+{
+	struct net_device *dev = netdev_notifier_info_to_dev(ptr);
+	struct ip_tunnel *tunnel = netdev_priv(dev);
+
+	if (!is_vti_tunnel(dev))
+		return NOTIFY_DONE;
+
+	switch (event) {
+	case NETDEV_DOWN:
+		if (!net_eq(tunnel->net, dev_net(dev)))
+			xfrm_garbage_collect(tunnel->net);
+		break;
+	}
+	return NOTIFY_DONE;
+}
+
+static struct notifier_block vti_notifier_block __read_mostly = {
+	.notifier_call = vti_device_event,
+};
+
 static int __init vti_init(void)
 {
 	const char *msg;
@@ -547,6 +574,8 @@ static int __init vti_init(void)
 
 	pr_info("IPv4 over IPsec tunneling driver\n");
 
+	register_netdevice_notifier(&vti_notifier_block);
+
 	msg = "tunnel device";
 	err = register_pernet_device(&vti_net_ops);
 	if (err < 0)
@@ -579,6 +608,7 @@ xfrm_proto_ah_failed:
 xfrm_proto_esp_failed:
 	unregister_pernet_device(&vti_net_ops);
 pernet_dev_failed:
+	unregister_netdevice_notifier(&vti_notifier_block);
 	pr_err("vti init: failed to register %s\n", msg);
 	return err;
 }
@@ -590,6 +620,7 @@ static void __exit vti_fini(void)
 	xfrm4_protocol_deregister(&vti_ah4_protocol, IPPROTO_AH);
 	xfrm4_protocol_deregister(&vti_esp4_protocol, IPPROTO_ESP);
 	unregister_pernet_device(&vti_net_ops);
+	unregister_netdevice_notifier(&vti_notifier_block);
 }
 
 module_init(vti_init);
--- zfcpdump-kernel-4.4.orig/net/ipv4/ipip.c
+++ zfcpdump-kernel-4.4/net/ipv4/ipip.c
@@ -107,6 +107,8 @@
 #include <linux/init.h>
 #include <linux/netfilter_ipv4.h>
 #include <linux/if_ether.h>
+#include <linux/inetdevice.h>
+#include <linux/rculist.h>
 
 #include <net/sock.h>
 #include <net/ip.h>
@@ -208,6 +210,147 @@ drop:
 	return 0;
 }
 
+static struct ip_fan_map *ipip_fan_find_map(struct ip_tunnel *t, __be32 daddr)
+{
+	struct ip_fan_map *fan_map;
+
+	rcu_read_lock();
+	list_for_each_entry_rcu(fan_map, &t->fan.fan_maps, list) {
+		if (fan_map->overlay ==
+		    (daddr & inet_make_mask(fan_map->overlay_prefix))) {
+			rcu_read_unlock();
+			return fan_map;
+		}
+	}
+	rcu_read_unlock();
+
+	return NULL;
+}
+
+/* Determine fan tunnel endpoint to send packet to, based on the inner IP
+ * address.  
+ *
+ * Given a /8 overlay and /16 underlay, for an overlay (inner) address
+ * Y.A.B.C, the transformation is F.G.A.B, where "F" and "G" are the first
+ * two octets of the underlay network (the network portion of a /16), "A"
+ * and "B" are the low order two octets of the underlay network host (the
+ * host portion of a /16), and "Y" is a configured first octet of the
+ * overlay network.
+ *
+ * E.g., underlay host 10.88.3.4/16 with an overlay of 99.0.0.0/8 would
+ * host overlay subnet 99.3.4.0/24.  An overlay network datagram from
+ * 99.3.4.5 to 99.6.7.8, would be directed to underlay host 10.88.6.7,
+ * which hosts overlay network subnet 99.6.7.0/24.  This transformation is
+ * described in detail further below.
+ *
+ * Using netmasks for the overlay and underlay other than /8 and /16, as
+ * shown above, can yield larger (or smaller) overlay subnets, with the
+ * trade-off of allowing fewer (or more) underlay hosts to participate.
+ *
+ * The size of each overlay network subnet is defined by the total of the
+ * network mask of the overlay plus the size of host portion of the
+ * underlay network. In the above example, /8 + /16 = /24.
+ *
+ * E.g., consider underlay host 10.99.238.5/20 and overlay 99.0.0.0/8. In
+ * this case, the network portion of the underlay is 10.99.224.0/20, and
+ * the host portion is 0.0.14.5 (12 bits).  To determine the overlay
+ * network subnet, the 12 bits of host portion are left shifted 12 bits
+ * (/20 - /8) and ORed with the overlay subnet prefix.  This yields an
+ * overlay subnet of 99.224.80/20, composed of 8 bits overlay, followed by
+ * 12 bits underlay.  This yields 12 bits in the overlay network portion,
+ * allowing for 4094 addresses in each overlay network subnet.  The
+ * trade-off is that fewer hosts may participate in the underlay network,
+ * as its host address size has shrunk from 16 bits (65534 addresses) in
+ * the first example to 12 bits (4094 addresses) here.
+ *
+ * For fewer hosts per overlay subnet (permitting a larger number of
+ * underlay hosts to participate), the underlay netmask may be made
+ * smaller.
+ *
+ * E.g., underlay host 10.111.1.2/12 (network 10.96.0.0/12, host portion
+ * is 0.15.1.2, 20 bits) with an overlay of 33.0.0.0/8 would left shift
+ * the 20 bits of host by 4 (so that it's highest order bit is adjacent to
+ * the lowest order bit of the /8 overlay).  This yields an overlay subnet
+ * of 33.240.16.32/28 (8 bits overlay, 20 bits from the host portion of
+ * the underlay).  This provides more addresses for the underlay network
+ * (approximately 2^20), but each host's segment of the overlay provides
+ * only 4 bits of addresses (14 usable).
+ *
+ * It is also possible to adjust the overlay subnet.
+ *
+ * For an overlay of 240.0.0.0/5 and underlay of 10.88.0.0/20, consider
+ * underlay host 10.88.129.2; the 12 bits of host, 0.0.1.2, are left
+ * shifted 15 bits (/20 - /5), yielding an overlay network of
+ * 240.129.0.0/17.  An underlay host of 10.88.244.215 would yield an
+ * overlay network of 242.107.128.0/17.
+ *
+ * For an overlay of 100.64.0.0/10 and underlay of 10.224.220.0/24, for
+ * underlay host 10.224.220.10, the underlay host portion (.10) is left
+ * shifted 14 bits, yielding an overlay network subnet of 100.66.128.0/18.
+ * This would permit 254 addresses on the underlay, with each overlay
+ * segment providing approximately 2^14 - 2 addresses (16382).
+ *
+ * For packets being encapsulated, the overlay network destination IP
+ * address is deconstructed into its overlay and underlay-derived
+ * portions.  The underlay portion (determined by the overlay mask and
+ * overlay subnet mask) is right shifted according to the size of the
+ * underlay network mask.  This value is then ORed with the network
+ * portion of the underlay network to produce the underlay network
+ * destination for the encapsulated datagram.
+ *
+ * For example, using the initial example of underlay 10.88.3.4/16 and
+ * overlay 99.0.0.0/8, with underlay host 10.88.3.4/16 providing overlay
+ * subnet 99.3.4.0/24 with specfic host 99.3.4.5.  A datagram from
+ * 99.3.4.5 to 99.6.7.8 would first have the underlay host derived portion
+ * of the address extracted.  This is a number of bits equal to underlay
+ * network host portion.  In the destination address, the highest order of
+ * these bits is one bit lower than the lowest order bit from the overlay
+ * network mask.
+ *
+ * Using the sample value, 99.6.7.8, the overlay mask is /8, and the
+ * underlay mask is /16 (leaving 16 bits for the host portion).  The bits
+ * to be shifted are the middle two octets, 0.6.7.0, as this is 99.6.7.8
+ * ANDed with the mask 0x00ffff00 (which is 16 bits, the highest order of
+ * which is 1 bit lower than the lowest order overlay address bit).
+ *
+ * These octets, 0.6.7.0, are then right shifted 8 bits, yielding 0.0.6.7.
+ * This value is then ORed with the underlay network portion,
+ * 10.88.0.0/16, providing 10.88.6.7 as the final underlay destination for
+ * the encapuslated datagram.
+ *
+ * Another transform using the final example: overlay 100.64.0.0/10 and
+ * underlay 10.224.220.0/24.  Consider overlay address 100.66.128.1
+ * sending a datagram to 100.66.200.5.  In this case, 8 bits (the host
+ * portion size of 10.224.220.0/24) beginning after the 100.64/10 overlay
+ * prefix are masked off, yielding 0.2.192.0.  This is right shifted 14
+ * (32 - 10 - (32 - 24), i.e., the number of bits between the overlay
+ * network portion and the underlay host portion) bits, yielding 0.0.0.11.
+ * This is ORed with the underlay network portion, 10.224.220.0/24, giving
+ * the underlay destination of 10.224.220.11 for overlay destination
+ * 100.66.200.5.
+ */
+static int ipip_build_fan_iphdr(struct ip_tunnel *tunnel, struct sk_buff *skb, struct iphdr *iph)
+{
+	struct ip_fan_map *f_map;
+	u32 daddr, underlay;
+
+	f_map = ipip_fan_find_map(tunnel, ip_hdr(skb)->daddr);
+	if (!f_map)
+		return -ENOENT;
+
+	daddr = ntohl(ip_hdr(skb)->daddr);
+	underlay = ntohl(f_map->underlay);
+	if (!underlay)
+		return -EINVAL;
+
+	*iph = tunnel->parms.iph;
+	iph->daddr = htonl(underlay |
+			   ((daddr & ~f_map->overlay_mask) >>
+			    (32 - f_map->overlay_prefix -
+			     (32 - f_map->underlay_prefix))));
+	return 0;
+}
+
 /*
  *	This function assumes it is being called from dev_queue_xmit()
  *	and that skb is filled properly by that function.
@@ -215,7 +358,8 @@ drop:
 static netdev_tx_t ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	struct ip_tunnel *tunnel = netdev_priv(dev);
-	const struct iphdr  *tiph = &tunnel->parms.iph;
+	const struct iphdr *tiph;
+	struct iphdr fiph;
 
 	if (unlikely(skb->protocol != htons(ETH_P_IP)))
 		goto tx_error;
@@ -224,6 +368,14 @@ static netdev_tx_t ipip_tunnel_xmit(stru
 	if (IS_ERR(skb))
 		goto out;
 
+	if (fan_has_map(&tunnel->fan)) {
+		if (ipip_build_fan_iphdr(tunnel, skb, &fiph))
+			goto tx_error;
+		tiph = &fiph;
+	} else {
+		tiph = &tunnel->parms.iph;
+	}
+
 	skb_set_inner_ipproto(skb, IPPROTO_IPIP);
 
 	ip_tunnel_xmit(skb, dev, tiph, tiph->protocol);
@@ -281,6 +433,8 @@ static const struct net_device_ops ipip_
 
 static void ipip_tunnel_setup(struct net_device *dev)
 {
+	struct ip_tunnel *t = netdev_priv(dev);
+
 	dev->netdev_ops		= &ipip_netdev_ops;
 
 	dev->type		= ARPHRD_TUNNEL;
@@ -292,6 +446,7 @@ static void ipip_tunnel_setup(struct net
 	dev->features		|= IPIP_FEATURES;
 	dev->hw_features	|= IPIP_FEATURES;
 	ip_tunnel_setup(dev, ipip_net_id);
+	INIT_LIST_HEAD(&t->fan.fan_maps);
 }
 
 static int ipip_tunnel_init(struct net_device *dev)
@@ -375,21 +530,112 @@ static bool ipip_netlink_encap_parms(str
 	return ret;
 }
 
+static void ipip_fan_flush_map(struct ip_tunnel *t)
+{
+	struct ip_fan_map *fan_map;
+
+	list_for_each_entry_rcu(fan_map, &t->fan.fan_maps, list) {
+		list_del_rcu(&fan_map->list);
+		kfree_rcu(fan_map, rcu);
+	}
+}
+
+static int ipip_fan_del_map(struct ip_tunnel *t, __be32 overlay)
+{
+	struct ip_fan_map *fan_map;
+
+	fan_map = ipip_fan_find_map(t, overlay);
+	if (!fan_map)
+		return -ENOENT;
+
+	list_del_rcu(&fan_map->list);
+	kfree_rcu(fan_map, rcu);
+
+	return 0;
+}
+
+static int ipip_fan_add_map(struct ip_tunnel *t, struct ifla_fan_map *map)
+{
+	__be32 overlay_mask, underlay_mask;
+	struct ip_fan_map *fan_map;
+
+	overlay_mask = inet_make_mask(map->overlay_prefix);
+	underlay_mask = inet_make_mask(map->underlay_prefix);
+
+	if ((map->overlay & ~overlay_mask) || (map->underlay & ~underlay_mask))
+		return -EINVAL;
+
+	if (!(map->overlay & overlay_mask) && (map->underlay & underlay_mask))
+		return -EINVAL;
+
+	/* Special case: overlay 0 and underlay 0: flush all mappings */
+	if (!map->overlay && !map->underlay) {
+		ipip_fan_flush_map(t);
+		return 0;
+	}
+	
+	/* Special case: overlay set and underlay 0: clear map for overlay */
+	if (!map->underlay)
+		return ipip_fan_del_map(t, map->overlay);
+
+	if (ipip_fan_find_map(t, map->overlay))
+		return -EEXIST;
+
+	fan_map = kmalloc(sizeof(*fan_map), GFP_KERNEL);
+	fan_map->underlay = map->underlay;
+	fan_map->overlay = map->overlay;
+	fan_map->underlay_prefix = map->underlay_prefix;
+	fan_map->overlay_mask = ntohl(overlay_mask);
+	fan_map->overlay_prefix = map->overlay_prefix;
+
+	list_add_tail_rcu(&fan_map->list, &t->fan.fan_maps);
+
+	return 0;
+}
+	
+
+static int ipip_netlink_fan(struct nlattr *data[], struct ip_tunnel *t,
+			    struct ip_tunnel_parm *parms)
+{
+	struct ifla_fan_map *map;
+	struct nlattr *attr;
+	int rem, rv;
+
+	if (!data[IFLA_IPTUN_FAN_MAP])
+		return 0;
+
+	if (parms->iph.daddr)
+		return -EINVAL;
+
+	nla_for_each_nested(attr, data[IFLA_IPTUN_FAN_MAP], rem) {
+		map = nla_data(attr);
+		rv = ipip_fan_add_map(t, map);
+		if (rv)
+			return rv;
+	}
+
+	return 0;
+}
+
 static int ipip_newlink(struct net *src_net, struct net_device *dev,
 			struct nlattr *tb[], struct nlattr *data[])
 {
 	struct ip_tunnel_parm p;
 	struct ip_tunnel_encap ipencap;
+	struct ip_tunnel *t = netdev_priv(dev);
+	int err;
 
 	if (ipip_netlink_encap_parms(data, &ipencap)) {
-		struct ip_tunnel *t = netdev_priv(dev);
-		int err = ip_tunnel_encap_setup(t, &ipencap);
+		err = ip_tunnel_encap_setup(t, &ipencap);
 
 		if (err < 0)
 			return err;
 	}
 
 	ipip_netlink_parms(data, &p);
+	err = ipip_netlink_fan(data, t, &p);
+	if (err < 0)
+		return err;
 	return ip_tunnel_newlink(dev, tb, &p);
 }
 
@@ -398,16 +644,20 @@ static int ipip_changelink(struct net_de
 {
 	struct ip_tunnel_parm p;
 	struct ip_tunnel_encap ipencap;
+	struct ip_tunnel *t = netdev_priv(dev);
+	int err;
 
 	if (ipip_netlink_encap_parms(data, &ipencap)) {
-		struct ip_tunnel *t = netdev_priv(dev);
-		int err = ip_tunnel_encap_setup(t, &ipencap);
+		err = ip_tunnel_encap_setup(t, &ipencap);
 
 		if (err < 0)
 			return err;
 	}
 
 	ipip_netlink_parms(data, &p);
+	err = ipip_netlink_fan(data, t, &p);
+	if (err < 0)
+		return err;
 
 	if (((dev->flags & IFF_POINTOPOINT) && !p.iph.daddr) ||
 	    (!(dev->flags & IFF_POINTOPOINT) && p.iph.daddr))
@@ -439,6 +689,8 @@ static size_t ipip_get_size(const struct
 		nla_total_size(2) +
 		/* IFLA_IPTUN_ENCAP_DPORT */
 		nla_total_size(2) +
+		/* IFLA_IPTUN_FAN_MAP */
+		nla_total_size(sizeof(struct ifla_fan_map)) * 256 +
 		0;
 }
 
@@ -466,6 +718,26 @@ static int ipip_fill_info(struct sk_buff
 			tunnel->encap.flags))
 		goto nla_put_failure;
 
+	if (fan_has_map(&tunnel->fan)) {
+		struct nlattr *fan_nest;
+		struct ip_fan_map *fan_map;
+
+		fan_nest = nla_nest_start(skb, IFLA_IPTUN_FAN_MAP);
+		if (!fan_nest)
+			goto nla_put_failure;
+		list_for_each_entry_rcu(fan_map, &tunnel->fan.fan_maps, list) {
+			struct ifla_fan_map map;
+
+			map.underlay = fan_map->underlay;
+			map.underlay_prefix = fan_map->underlay_prefix;
+			map.overlay = fan_map->overlay;
+			map.overlay_prefix = fan_map->overlay_prefix;
+			if (nla_put(skb, IFLA_FAN_MAPPING, sizeof(map), &map))
+				goto nla_put_failure;
+		}
+		nla_nest_end(skb, fan_nest);
+	}
+
 	return 0;
 
 nla_put_failure:
@@ -483,6 +755,9 @@ static const struct nla_policy ipip_poli
 	[IFLA_IPTUN_ENCAP_FLAGS]	= { .type = NLA_U16 },
 	[IFLA_IPTUN_ENCAP_SPORT]	= { .type = NLA_U16 },
 	[IFLA_IPTUN_ENCAP_DPORT]	= { .type = NLA_U16 },
+
+	[__IFLA_IPTUN_VENDOR_BREAK ... IFLA_IPTUN_MAX]	= { .type = NLA_BINARY },
+	[IFLA_IPTUN_FAN_MAP]		= { .type = NLA_NESTED },
 };
 
 static struct rtnl_link_ops ipip_link_ops __read_mostly = {
@@ -523,6 +798,23 @@ static struct pernet_operations ipip_net
 	.size = sizeof(struct ip_tunnel_net),
 };
 
+#ifdef CONFIG_SYSCTL
+static struct ctl_table_header *ipip_fan_header;
+static unsigned int ipip_fan_version = 3;
+
+static struct ctl_table ipip_fan_sysctls[] = {
+	{
+		.procname	= "version",
+		.data		= &ipip_fan_version,
+		.maxlen		= sizeof(ipip_fan_version),
+		.mode		= 0444,
+		.proc_handler	= proc_dointvec,
+	},
+	{},
+};
+
+#endif /* CONFIG_SYSCTL */
+
 static int __init ipip_init(void)
 {
 	int err;
@@ -541,9 +833,22 @@ static int __init ipip_init(void)
 	if (err < 0)
 		goto rtnl_link_failed;
 
+#ifdef CONFIG_SYSCTL
+	ipip_fan_header = register_net_sysctl(&init_net, "net/fan",
+					      ipip_fan_sysctls);
+	if (!ipip_fan_header) {
+		err = -ENOMEM;
+		goto sysctl_failed;
+	}
+#endif /* CONFIG_SYSCTL */
+
 out:
 	return err;
 
+#ifdef CONFIG_SYSCTL
+sysctl_failed:
+	rtnl_link_unregister(&ipip_link_ops);
+#endif /* CONFIG_SYSCTL */
 rtnl_link_failed:
 	xfrm4_tunnel_deregister(&ipip_handler, AF_INET);
 xfrm_tunnel_failed:
@@ -553,6 +858,9 @@ xfrm_tunnel_failed:
 
 static void __exit ipip_fini(void)
 {
+#ifdef CONFIG_SYSCTL
+	unregister_net_sysctl_table(ipip_fan_header);
+#endif /* CONFIG_SYSCTL */
 	rtnl_link_unregister(&ipip_link_ops);
 	if (xfrm4_tunnel_deregister(&ipip_handler, AF_INET))
 		pr_info("%s: can't deregister tunnel\n", __func__);
--- zfcpdump-kernel-4.4.orig/net/ipv4/ipmr.c
+++ zfcpdump-kernel-4.4/net/ipv4/ipmr.c
@@ -882,8 +882,10 @@ static struct mfc_cache *ipmr_cache_allo
 {
 	struct mfc_cache *c = kmem_cache_zalloc(mrt_cachep, GFP_KERNEL);
 
-	if (c)
+	if (c) {
+		c->mfc_un.res.last_assert = jiffies - MFC_ASSERT_THRESH - 1;
 		c->mfc_un.res.minvif = MAXVIFS;
+	}
 	return c;
 }
 
--- zfcpdump-kernel-4.4.orig/net/ipv4/netfilter/arp_tables.c
+++ zfcpdump-kernel-4.4/net/ipv4/netfilter/arp_tables.c
@@ -359,11 +359,35 @@ unsigned int arpt_do_table(struct sk_buf
 }
 
 /* All zeroes == unconditional rule. */
-static inline bool unconditional(const struct arpt_arp *arp)
+static inline bool unconditional(const struct arpt_entry *e)
 {
 	static const struct arpt_arp uncond;
 
-	return memcmp(arp, &uncond, sizeof(uncond)) == 0;
+	return e->target_offset == sizeof(struct arpt_entry) &&
+	       memcmp(&e->arp, &uncond, sizeof(uncond)) == 0;
+}
+
+static bool next_offset_ok(const struct xt_table_info *t, unsigned int newpos)
+{
+	if (newpos > t->size - sizeof(struct arpt_entry))
+		return false;
+
+	if (newpos % __alignof__(struct arpt_entry) != 0)
+		return false;
+
+	return true;
+}
+
+static bool find_jump_target(const struct xt_table_info *t,
+			     const struct arpt_entry *target)
+{
+	struct arpt_entry *iter;
+
+	xt_entry_foreach(iter, t->entries, t->size) {
+		 if (iter == target)
+			return true;
+	}
+	return false;
 }
 
 /* Figures out from what hook each rule can be called: returns 0 if
@@ -402,11 +426,10 @@ static int mark_source_chains(const stru
 				|= ((1 << hook) | (1 << NF_ARP_NUMHOOKS));
 
 			/* Unconditional return/END. */
-			if ((e->target_offset == sizeof(struct arpt_entry) &&
+			if ((unconditional(e) &&
 			     (strcmp(t->target.u.user.name,
 				     XT_STANDARD_TARGET) == 0) &&
-			     t->verdict < 0 && unconditional(&e->arp)) ||
-			    visited) {
+			     t->verdict < 0) || visited) {
 				unsigned int oldpos, size;
 
 				if ((strcmp(t->target.u.user.name,
@@ -437,8 +460,12 @@ static int mark_source_chains(const stru
 
 				/* Move along one */
 				size = e->next_offset;
+				if (!next_offset_ok(newinfo, pos + size))
+					return 0;
 				e = (struct arpt_entry *)
 					(entry0 + pos + size);
+				if (pos + size >= newinfo->size)
+					return 0;
 				e->counters.pcnt = pos;
 				pos += size;
 			} else {
@@ -447,21 +474,23 @@ static int mark_source_chains(const stru
 				if (strcmp(t->target.u.user.name,
 					   XT_STANDARD_TARGET) == 0 &&
 				    newpos >= 0) {
-					if (newpos > newinfo->size -
-						sizeof(struct arpt_entry)) {
-						duprintf("mark_source_chains: "
-							"bad verdict (%i)\n",
-								newpos);
-						return 0;
-					}
-
 					/* This a jump; chase it. */
 					duprintf("Jump rule %u -> %u\n",
 						 pos, newpos);
+					e = (struct arpt_entry *)
+						(entry0 + newpos);
+					if (!find_jump_target(newinfo, e))
+						return 0;
 				} else {
 					/* ... this is a fallthru */
 					newpos = pos + e->next_offset;
+					if (newpos >= newinfo->size)
+						return 0;
 				}
+
+				if (!next_offset_ok(newinfo, newpos))
+					return 0;
+
 				e = (struct arpt_entry *)
 					(entry0 + newpos);
 				e->counters.pcnt = pos;
@@ -474,25 +503,6 @@ next:
 	return 1;
 }
 
-static inline int check_entry(const struct arpt_entry *e, const char *name)
-{
-	const struct xt_entry_target *t;
-
-	if (!arp_checkentry(&e->arp)) {
-		duprintf("arp_tables: arp check failed %p %s.\n", e, name);
-		return -EINVAL;
-	}
-
-	if (e->target_offset + sizeof(struct xt_entry_target) > e->next_offset)
-		return -EINVAL;
-
-	t = arpt_get_target_c(e);
-	if (e->target_offset + t->u.target_size > e->next_offset)
-		return -EINVAL;
-
-	return 0;
-}
-
 static inline int check_target(struct arpt_entry *e, const char *name)
 {
 	struct xt_entry_target *t = arpt_get_target(e);
@@ -522,10 +532,6 @@ find_check_entry(struct arpt_entry *e, c
 	struct xt_target *target;
 	int ret;
 
-	ret = check_entry(e, name);
-	if (ret)
-		return ret;
-
 	e->counters.pcnt = xt_percpu_counter_alloc();
 	if (IS_ERR_VALUE(e->counters.pcnt))
 		return -ENOMEM;
@@ -557,7 +563,7 @@ static bool check_underflow(const struct
 	const struct xt_entry_target *t;
 	unsigned int verdict;
 
-	if (!unconditional(&e->arp))
+	if (!unconditional(e))
 		return false;
 	t = arpt_get_target_c(e);
 	if (strcmp(t->u.user.name, XT_STANDARD_TARGET) != 0)
@@ -576,9 +582,11 @@ static inline int check_entry_size_and_h
 					     unsigned int valid_hooks)
 {
 	unsigned int h;
+	int err;
 
 	if ((unsigned long)e % __alignof__(struct arpt_entry) != 0 ||
-	    (unsigned char *)e + sizeof(struct arpt_entry) >= limit) {
+	    (unsigned char *)e + sizeof(struct arpt_entry) >= limit ||
+	    (unsigned char *)e + e->next_offset > limit) {
 		duprintf("Bad offset %p\n", e);
 		return -EINVAL;
 	}
@@ -590,6 +598,14 @@ static inline int check_entry_size_and_h
 		return -EINVAL;
 	}
 
+	if (!arp_checkentry(&e->arp))
+		return -EINVAL;
+
+	err = xt_check_entry_offsets(e, e->elems, e->target_offset,
+				     e->next_offset);
+	if (err)
+		return err;
+
 	/* Check hooks & underflows */
 	for (h = 0; h < NF_ARP_NUMHOOKS; h++) {
 		if (!(valid_hooks & (1 << h)))
@@ -598,9 +614,9 @@ static inline int check_entry_size_and_h
 			newinfo->hook_entry[h] = hook_entries[h];
 		if ((unsigned char *)e - base == underflows[h]) {
 			if (!check_underflow(e)) {
-				pr_err("Underflows must be unconditional and "
-				       "use the STANDARD target with "
-				       "ACCEPT/DROP\n");
+				pr_debug("Underflows must be unconditional and "
+					 "use the STANDARD target with "
+					 "ACCEPT/DROP\n");
 				return -EINVAL;
 			}
 			newinfo->underflow[h] = underflows[h];
@@ -691,10 +707,8 @@ static int translate_table(struct xt_tab
 		}
 	}
 
-	if (!mark_source_chains(newinfo, repl->valid_hooks, entry0)) {
-		duprintf("Looping hook\n");
+	if (!mark_source_chains(newinfo, repl->valid_hooks, entry0))
 		return -ELOOP;
-	}
 
 	/* Finally, each sanity check must pass */
 	i = 0;
@@ -1125,55 +1139,17 @@ static int do_add_counters(struct net *n
 	unsigned int i;
 	struct xt_counters_info tmp;
 	struct xt_counters *paddc;
-	unsigned int num_counters;
-	const char *name;
-	int size;
-	void *ptmp;
 	struct xt_table *t;
 	const struct xt_table_info *private;
 	int ret = 0;
 	struct arpt_entry *iter;
 	unsigned int addend;
-#ifdef CONFIG_COMPAT
-	struct compat_xt_counters_info compat_tmp;
-
-	if (compat) {
-		ptmp = &compat_tmp;
-		size = sizeof(struct compat_xt_counters_info);
-	} else
-#endif
-	{
-		ptmp = &tmp;
-		size = sizeof(struct xt_counters_info);
-	}
 
-	if (copy_from_user(ptmp, user, size) != 0)
-		return -EFAULT;
-
-#ifdef CONFIG_COMPAT
-	if (compat) {
-		num_counters = compat_tmp.num_counters;
-		name = compat_tmp.name;
-	} else
-#endif
-	{
-		num_counters = tmp.num_counters;
-		name = tmp.name;
-	}
-
-	if (len != size + num_counters * sizeof(struct xt_counters))
-		return -EINVAL;
-
-	paddc = vmalloc(len - size);
-	if (!paddc)
-		return -ENOMEM;
+	paddc = xt_copy_counters_from_user(user, len, &tmp, compat);
+	if (IS_ERR(paddc))
+		return PTR_ERR(paddc);
 
-	if (copy_from_user(paddc, user + size, len - size) != 0) {
-		ret = -EFAULT;
-		goto free;
-	}
-
-	t = xt_find_table_lock(net, NFPROTO_ARP, name);
+	t = xt_find_table_lock(net, NFPROTO_ARP, tmp.name);
 	if (IS_ERR_OR_NULL(t)) {
 		ret = t ? PTR_ERR(t) : -ENOENT;
 		goto free;
@@ -1181,7 +1157,7 @@ static int do_add_counters(struct net *n
 
 	local_bh_disable();
 	private = t->private;
-	if (private->number != num_counters) {
+	if (private->number != tmp.num_counters) {
 		ret = -EINVAL;
 		goto unlock_up_free;
 	}
@@ -1208,6 +1184,18 @@ static int do_add_counters(struct net *n
 }
 
 #ifdef CONFIG_COMPAT
+struct compat_arpt_replace {
+	char				name[XT_TABLE_MAXNAMELEN];
+	u32				valid_hooks;
+	u32				num_entries;
+	u32				size;
+	u32				hook_entry[NF_ARP_NUMHOOKS];
+	u32				underflow[NF_ARP_NUMHOOKS];
+	u32				num_counters;
+	compat_uptr_t			counters;
+	struct compat_arpt_entry	entries[0];
+};
+
 static inline void compat_release_entry(struct compat_arpt_entry *e)
 {
 	struct xt_entry_target *t;
@@ -1216,24 +1204,22 @@ static inline void compat_release_entry(
 	module_put(t->u.kernel.target->me);
 }
 
-static inline int
+static int
 check_compat_entry_size_and_hooks(struct compat_arpt_entry *e,
 				  struct xt_table_info *newinfo,
 				  unsigned int *size,
 				  const unsigned char *base,
-				  const unsigned char *limit,
-				  const unsigned int *hook_entries,
-				  const unsigned int *underflows,
-				  const char *name)
+				  const unsigned char *limit)
 {
 	struct xt_entry_target *t;
 	struct xt_target *target;
 	unsigned int entry_offset;
-	int ret, off, h;
+	int ret, off;
 
 	duprintf("check_compat_entry_size_and_hooks %p\n", e);
 	if ((unsigned long)e % __alignof__(struct compat_arpt_entry) != 0 ||
-	    (unsigned char *)e + sizeof(struct compat_arpt_entry) >= limit) {
+	    (unsigned char *)e + sizeof(struct compat_arpt_entry) >= limit ||
+	    (unsigned char *)e + e->next_offset > limit) {
 		duprintf("Bad offset %p, limit = %p\n", e, limit);
 		return -EINVAL;
 	}
@@ -1245,8 +1231,11 @@ check_compat_entry_size_and_hooks(struct
 		return -EINVAL;
 	}
 
-	/* For purposes of check_entry casting the compat entry is fine */
-	ret = check_entry((struct arpt_entry *)e, name);
+	if (!arp_checkentry(&e->arp))
+		return -EINVAL;
+
+	ret = xt_compat_check_entry_offsets(e, e->elems, e->target_offset,
+					    e->next_offset);
 	if (ret)
 		return ret;
 
@@ -1270,17 +1259,6 @@ check_compat_entry_size_and_hooks(struct
 	if (ret)
 		goto release_target;
 
-	/* Check hooks & underflows */
-	for (h = 0; h < NF_ARP_NUMHOOKS; h++) {
-		if ((unsigned char *)e - base == hook_entries[h])
-			newinfo->hook_entry[h] = hook_entries[h];
-		if ((unsigned char *)e - base == underflows[h])
-			newinfo->underflow[h] = underflows[h];
-	}
-
-	/* Clear counters and comefrom */
-	memset(&e->counters, 0, sizeof(e->counters));
-	e->comefrom = 0;
 	return 0;
 
 release_target:
@@ -1289,18 +1267,17 @@ out:
 	return ret;
 }
 
-static int
+static void
 compat_copy_entry_from_user(struct compat_arpt_entry *e, void **dstptr,
-			    unsigned int *size, const char *name,
+			    unsigned int *size,
 			    struct xt_table_info *newinfo, unsigned char *base)
 {
 	struct xt_entry_target *t;
 	struct xt_target *target;
 	struct arpt_entry *de;
 	unsigned int origsize;
-	int ret, h;
+	int h;
 
-	ret = 0;
 	origsize = *size;
 	de = (struct arpt_entry *)*dstptr;
 	memcpy(de, e, sizeof(struct arpt_entry));
@@ -1321,148 +1298,82 @@ compat_copy_entry_from_user(struct compa
 		if ((unsigned char *)de - base < newinfo->underflow[h])
 			newinfo->underflow[h] -= origsize - *size;
 	}
-	return ret;
 }
 
-static int translate_compat_table(const char *name,
-				  unsigned int valid_hooks,
-				  struct xt_table_info **pinfo,
+static int translate_compat_table(struct xt_table_info **pinfo,
 				  void **pentry0,
-				  unsigned int total_size,
-				  unsigned int number,
-				  unsigned int *hook_entries,
-				  unsigned int *underflows)
+				  const struct compat_arpt_replace *compatr)
 {
 	unsigned int i, j;
 	struct xt_table_info *newinfo, *info;
 	void *pos, *entry0, *entry1;
 	struct compat_arpt_entry *iter0;
-	struct arpt_entry *iter1;
+	struct arpt_replace repl;
 	unsigned int size;
 	int ret = 0;
 
 	info = *pinfo;
 	entry0 = *pentry0;
-	size = total_size;
-	info->number = number;
-
-	/* Init all hooks to impossible value. */
-	for (i = 0; i < NF_ARP_NUMHOOKS; i++) {
-		info->hook_entry[i] = 0xFFFFFFFF;
-		info->underflow[i] = 0xFFFFFFFF;
-	}
+	size = compatr->size;
+	info->number = compatr->num_entries;
 
 	duprintf("translate_compat_table: size %u\n", info->size);
 	j = 0;
 	xt_compat_lock(NFPROTO_ARP);
-	xt_compat_init_offsets(NFPROTO_ARP, number);
+	xt_compat_init_offsets(NFPROTO_ARP, compatr->num_entries);
 	/* Walk through entries, checking offsets. */
-	xt_entry_foreach(iter0, entry0, total_size) {
+	xt_entry_foreach(iter0, entry0, compatr->size) {
 		ret = check_compat_entry_size_and_hooks(iter0, info, &size,
 							entry0,
-							entry0 + total_size,
-							hook_entries,
-							underflows,
-							name);
+							entry0 + compatr->size);
 		if (ret != 0)
 			goto out_unlock;
 		++j;
 	}
 
 	ret = -EINVAL;
-	if (j != number) {
+	if (j != compatr->num_entries) {
 		duprintf("translate_compat_table: %u not %u entries\n",
-			 j, number);
+			 j, compatr->num_entries);
 		goto out_unlock;
 	}
 
-	/* Check hooks all assigned */
-	for (i = 0; i < NF_ARP_NUMHOOKS; i++) {
-		/* Only hooks which are valid */
-		if (!(valid_hooks & (1 << i)))
-			continue;
-		if (info->hook_entry[i] == 0xFFFFFFFF) {
-			duprintf("Invalid hook entry %u %u\n",
-				 i, hook_entries[i]);
-			goto out_unlock;
-		}
-		if (info->underflow[i] == 0xFFFFFFFF) {
-			duprintf("Invalid underflow %u %u\n",
-				 i, underflows[i]);
-			goto out_unlock;
-		}
-	}
-
 	ret = -ENOMEM;
 	newinfo = xt_alloc_table_info(size);
 	if (!newinfo)
 		goto out_unlock;
 
-	newinfo->number = number;
+	newinfo->number = compatr->num_entries;
 	for (i = 0; i < NF_ARP_NUMHOOKS; i++) {
 		newinfo->hook_entry[i] = info->hook_entry[i];
 		newinfo->underflow[i] = info->underflow[i];
 	}
 	entry1 = newinfo->entries;
 	pos = entry1;
-	size = total_size;
-	xt_entry_foreach(iter0, entry0, total_size) {
-		ret = compat_copy_entry_from_user(iter0, &pos, &size,
-						  name, newinfo, entry1);
-		if (ret != 0)
-			break;
-	}
+	size = compatr->size;
+	xt_entry_foreach(iter0, entry0, compatr->size)
+		compat_copy_entry_from_user(iter0, &pos, &size,
+					    newinfo, entry1);
+
+	/* all module references in entry0 are now gone */
+
 	xt_compat_flush_offsets(NFPROTO_ARP);
 	xt_compat_unlock(NFPROTO_ARP);
-	if (ret)
-		goto free_newinfo;
 
-	ret = -ELOOP;
-	if (!mark_source_chains(newinfo, valid_hooks, entry1))
-		goto free_newinfo;
+	memcpy(&repl, compatr, sizeof(*compatr));
 
-	i = 0;
-	xt_entry_foreach(iter1, entry1, newinfo->size) {
-		iter1->counters.pcnt = xt_percpu_counter_alloc();
-		if (IS_ERR_VALUE(iter1->counters.pcnt)) {
-			ret = -ENOMEM;
-			break;
-		}
-
-		ret = check_target(iter1, name);
-		if (ret != 0) {
-			xt_percpu_counter_free(iter1->counters.pcnt);
-			break;
-		}
-		++i;
-		if (strcmp(arpt_get_target(iter1)->u.user.name,
-		    XT_ERROR_TARGET) == 0)
-			++newinfo->stacksize;
-	}
-	if (ret) {
-		/*
-		 * The first i matches need cleanup_entry (calls ->destroy)
-		 * because they had called ->check already. The other j-i
-		 * entries need only release.
-		 */
-		int skip = i;
-		j -= i;
-		xt_entry_foreach(iter0, entry0, newinfo->size) {
-			if (skip-- > 0)
-				continue;
-			if (j-- == 0)
-				break;
-			compat_release_entry(iter0);
-		}
-		xt_entry_foreach(iter1, entry1, newinfo->size) {
-			if (i-- == 0)
-				break;
-			cleanup_entry(iter1);
-		}
-		xt_free_table_info(newinfo);
-		return ret;
+	for (i = 0; i < NF_ARP_NUMHOOKS; i++) {
+		repl.hook_entry[i] = newinfo->hook_entry[i];
+		repl.underflow[i] = newinfo->underflow[i];
 	}
 
+	repl.num_counters = 0;
+	repl.counters = NULL;
+	repl.size = newinfo->size;
+	ret = translate_table(newinfo, entry1, &repl);
+	if (ret)
+		goto free_newinfo;
+
 	*pinfo = newinfo;
 	*pentry0 = entry1;
 	xt_free_table_info(info);
@@ -1470,31 +1381,18 @@ static int translate_compat_table(const
 
 free_newinfo:
 	xt_free_table_info(newinfo);
-out:
-	xt_entry_foreach(iter0, entry0, total_size) {
+	return ret;
+out_unlock:
+	xt_compat_flush_offsets(NFPROTO_ARP);
+	xt_compat_unlock(NFPROTO_ARP);
+	xt_entry_foreach(iter0, entry0, compatr->size) {
 		if (j-- == 0)
 			break;
 		compat_release_entry(iter0);
 	}
 	return ret;
-out_unlock:
-	xt_compat_flush_offsets(NFPROTO_ARP);
-	xt_compat_unlock(NFPROTO_ARP);
-	goto out;
 }
 
-struct compat_arpt_replace {
-	char				name[XT_TABLE_MAXNAMELEN];
-	u32				valid_hooks;
-	u32				num_entries;
-	u32				size;
-	u32				hook_entry[NF_ARP_NUMHOOKS];
-	u32				underflow[NF_ARP_NUMHOOKS];
-	u32				num_counters;
-	compat_uptr_t			counters;
-	struct compat_arpt_entry	entries[0];
-};
-
 static int compat_do_replace(struct net *net, void __user *user,
 			     unsigned int len)
 {
@@ -1527,10 +1425,7 @@ static int compat_do_replace(struct net
 		goto free_newinfo;
 	}
 
-	ret = translate_compat_table(tmp.name, tmp.valid_hooks,
-				     &newinfo, &loc_cpu_entry, tmp.size,
-				     tmp.num_entries, tmp.hook_entry,
-				     tmp.underflow);
+	ret = translate_compat_table(&newinfo, &loc_cpu_entry, &tmp);
 	if (ret != 0)
 		goto free_newinfo;
 
--- zfcpdump-kernel-4.4.orig/net/ipv4/netfilter/ip_tables.c
+++ zfcpdump-kernel-4.4/net/ipv4/netfilter/ip_tables.c
@@ -168,11 +168,12 @@ get_entry(const void *base, unsigned int
 
 /* All zeroes == unconditional rule. */
 /* Mildly perf critical (only if packet tracing is on) */
-static inline bool unconditional(const struct ipt_ip *ip)
+static inline bool unconditional(const struct ipt_entry *e)
 {
 	static const struct ipt_ip uncond;
 
-	return memcmp(ip, &uncond, sizeof(uncond)) == 0;
+	return e->target_offset == sizeof(struct ipt_entry) &&
+	       memcmp(&e->ip, &uncond, sizeof(uncond)) == 0;
 #undef FWINV
 }
 
@@ -229,11 +230,10 @@ get_chainname_rulenum(const struct ipt_e
 	} else if (s == e) {
 		(*rulenum)++;
 
-		if (s->target_offset == sizeof(struct ipt_entry) &&
+		if (unconditional(s) &&
 		    strcmp(t->target.u.kernel.target->name,
 			   XT_STANDARD_TARGET) == 0 &&
-		   t->verdict < 0 &&
-		   unconditional(&s->ip)) {
+		   t->verdict < 0) {
 			/* Tail of chains: STANDARD target (return/policy) */
 			*comment = *chainname == hookname
 				? comments[NF_IP_TRACE_COMMENT_POLICY]
@@ -443,6 +443,29 @@ ipt_do_table(struct sk_buff *skb,
 #endif
 }
 
+static bool next_offset_ok(const struct xt_table_info *t, unsigned int newpos)
+{
+	if (newpos > t->size - sizeof(struct ipt_entry))
+		return false;
+
+	if (newpos % __alignof__(struct ipt_entry) != 0)
+		return false;
+
+	return true;
+}
+
+static bool find_jump_target(const struct xt_table_info *t,
+			     const struct ipt_entry *target)
+{
+	struct ipt_entry *iter;
+
+	xt_entry_foreach(iter, t->entries, t->size) {
+		 if (iter == target)
+			return true;
+	}
+	return false;
+}
+
 /* Figures out from what hook each rule can be called: returns 0 if
    there are loops.  Puts hook bitmask in comefrom. */
 static int
@@ -476,11 +499,10 @@ mark_source_chains(const struct xt_table
 			e->comefrom |= ((1 << hook) | (1 << NF_INET_NUMHOOKS));
 
 			/* Unconditional return/END. */
-			if ((e->target_offset == sizeof(struct ipt_entry) &&
+			if ((unconditional(e) &&
 			     (strcmp(t->target.u.user.name,
 				     XT_STANDARD_TARGET) == 0) &&
-			     t->verdict < 0 && unconditional(&e->ip)) ||
-			    visited) {
+			     t->verdict < 0) || visited) {
 				unsigned int oldpos, size;
 
 				if ((strcmp(t->target.u.user.name,
@@ -519,8 +541,12 @@ mark_source_chains(const struct xt_table
 
 				/* Move along one */
 				size = e->next_offset;
+				if (!next_offset_ok(newinfo, pos + size))
+					return 0;
 				e = (struct ipt_entry *)
 					(entry0 + pos + size);
+				if (pos + size >= newinfo->size)
+					return 0;
 				e->counters.pcnt = pos;
 				pos += size;
 			} else {
@@ -529,20 +555,23 @@ mark_source_chains(const struct xt_table
 				if (strcmp(t->target.u.user.name,
 					   XT_STANDARD_TARGET) == 0 &&
 				    newpos >= 0) {
-					if (newpos > newinfo->size -
-						sizeof(struct ipt_entry)) {
-						duprintf("mark_source_chains: "
-							"bad verdict (%i)\n",
-								newpos);
-						return 0;
-					}
 					/* This a jump; chase it. */
 					duprintf("Jump rule %u -> %u\n",
 						 pos, newpos);
+					e = (struct ipt_entry *)
+						(entry0 + newpos);
+					if (!find_jump_target(newinfo, e))
+						return 0;
 				} else {
 					/* ... this is a fallthru */
 					newpos = pos + e->next_offset;
+					if (newpos >= newinfo->size)
+						return 0;
 				}
+
+				if (!next_offset_ok(newinfo, newpos))
+					return 0;
+
 				e = (struct ipt_entry *)
 					(entry0 + newpos);
 				e->counters.pcnt = pos;
@@ -569,27 +598,6 @@ static void cleanup_match(struct xt_entr
 }
 
 static int
-check_entry(const struct ipt_entry *e, const char *name)
-{
-	const struct xt_entry_target *t;
-
-	if (!ip_checkentry(&e->ip)) {
-		duprintf("ip check failed %p %s.\n", e, name);
-		return -EINVAL;
-	}
-
-	if (e->target_offset + sizeof(struct xt_entry_target) >
-	    e->next_offset)
-		return -EINVAL;
-
-	t = ipt_get_target_c(e);
-	if (e->target_offset + t->u.target_size > e->next_offset)
-		return -EINVAL;
-
-	return 0;
-}
-
-static int
 check_match(struct xt_entry_match *m, struct xt_mtchk_param *par)
 {
 	const struct ipt_ip *ip = par->entryinfo;
@@ -666,10 +674,6 @@ find_check_entry(struct ipt_entry *e, st
 	struct xt_mtchk_param mtpar;
 	struct xt_entry_match *ematch;
 
-	ret = check_entry(e, name);
-	if (ret)
-		return ret;
-
 	e->counters.pcnt = xt_percpu_counter_alloc();
 	if (IS_ERR_VALUE(e->counters.pcnt))
 		return -ENOMEM;
@@ -721,7 +725,7 @@ static bool check_underflow(const struct
 	const struct xt_entry_target *t;
 	unsigned int verdict;
 
-	if (!unconditional(&e->ip))
+	if (!unconditional(e))
 		return false;
 	t = ipt_get_target_c(e);
 	if (strcmp(t->u.user.name, XT_STANDARD_TARGET) != 0)
@@ -741,9 +745,11 @@ check_entry_size_and_hooks(struct ipt_en
 			   unsigned int valid_hooks)
 {
 	unsigned int h;
+	int err;
 
 	if ((unsigned long)e % __alignof__(struct ipt_entry) != 0 ||
-	    (unsigned char *)e + sizeof(struct ipt_entry) >= limit) {
+	    (unsigned char *)e + sizeof(struct ipt_entry) >= limit ||
+	    (unsigned char *)e + e->next_offset > limit) {
 		duprintf("Bad offset %p\n", e);
 		return -EINVAL;
 	}
@@ -755,6 +761,14 @@ check_entry_size_and_hooks(struct ipt_en
 		return -EINVAL;
 	}
 
+	if (!ip_checkentry(&e->ip))
+		return -EINVAL;
+
+	err = xt_check_entry_offsets(e, e->elems, e->target_offset,
+				     e->next_offset);
+	if (err)
+		return err;
+
 	/* Check hooks & underflows */
 	for (h = 0; h < NF_INET_NUMHOOKS; h++) {
 		if (!(valid_hooks & (1 << h)))
@@ -763,9 +777,9 @@ check_entry_size_and_hooks(struct ipt_en
 			newinfo->hook_entry[h] = hook_entries[h];
 		if ((unsigned char *)e - base == underflows[h]) {
 			if (!check_underflow(e)) {
-				pr_err("Underflows must be unconditional and "
-				       "use the STANDARD target with "
-				       "ACCEPT/DROP\n");
+				pr_debug("Underflows must be unconditional and "
+					 "use the STANDARD target with "
+					 "ACCEPT/DROP\n");
 				return -EINVAL;
 			}
 			newinfo->underflow[h] = underflows[h];
@@ -1309,55 +1323,17 @@ do_add_counters(struct net *net, const v
 	unsigned int i;
 	struct xt_counters_info tmp;
 	struct xt_counters *paddc;
-	unsigned int num_counters;
-	const char *name;
-	int size;
-	void *ptmp;
 	struct xt_table *t;
 	const struct xt_table_info *private;
 	int ret = 0;
 	struct ipt_entry *iter;
 	unsigned int addend;
-#ifdef CONFIG_COMPAT
-	struct compat_xt_counters_info compat_tmp;
-
-	if (compat) {
-		ptmp = &compat_tmp;
-		size = sizeof(struct compat_xt_counters_info);
-	} else
-#endif
-	{
-		ptmp = &tmp;
-		size = sizeof(struct xt_counters_info);
-	}
-
-	if (copy_from_user(ptmp, user, size) != 0)
-		return -EFAULT;
-
-#ifdef CONFIG_COMPAT
-	if (compat) {
-		num_counters = compat_tmp.num_counters;
-		name = compat_tmp.name;
-	} else
-#endif
-	{
-		num_counters = tmp.num_counters;
-		name = tmp.name;
-	}
-
-	if (len != size + num_counters * sizeof(struct xt_counters))
-		return -EINVAL;
 
-	paddc = vmalloc(len - size);
-	if (!paddc)
-		return -ENOMEM;
+	paddc = xt_copy_counters_from_user(user, len, &tmp, compat);
+	if (IS_ERR(paddc))
+		return PTR_ERR(paddc);
 
-	if (copy_from_user(paddc, user + size, len - size) != 0) {
-		ret = -EFAULT;
-		goto free;
-	}
-
-	t = xt_find_table_lock(net, AF_INET, name);
+	t = xt_find_table_lock(net, AF_INET, tmp.name);
 	if (IS_ERR_OR_NULL(t)) {
 		ret = t ? PTR_ERR(t) : -ENOENT;
 		goto free;
@@ -1365,7 +1341,7 @@ do_add_counters(struct net *net, const v
 
 	local_bh_disable();
 	private = t->private;
-	if (private->number != num_counters) {
+	if (private->number != tmp.num_counters) {
 		ret = -EINVAL;
 		goto unlock_up_free;
 	}
@@ -1444,7 +1420,6 @@ compat_copy_entry_to_user(struct ipt_ent
 
 static int
 compat_find_calc_match(struct xt_entry_match *m,
-		       const char *name,
 		       const struct ipt_ip *ip,
 		       int *size)
 {
@@ -1479,21 +1454,19 @@ check_compat_entry_size_and_hooks(struct
 				  struct xt_table_info *newinfo,
 				  unsigned int *size,
 				  const unsigned char *base,
-				  const unsigned char *limit,
-				  const unsigned int *hook_entries,
-				  const unsigned int *underflows,
-				  const char *name)
+				  const unsigned char *limit)
 {
 	struct xt_entry_match *ematch;
 	struct xt_entry_target *t;
 	struct xt_target *target;
 	unsigned int entry_offset;
 	unsigned int j;
-	int ret, off, h;
+	int ret, off;
 
 	duprintf("check_compat_entry_size_and_hooks %p\n", e);
 	if ((unsigned long)e % __alignof__(struct compat_ipt_entry) != 0 ||
-	    (unsigned char *)e + sizeof(struct compat_ipt_entry) >= limit) {
+	    (unsigned char *)e + sizeof(struct compat_ipt_entry) >= limit ||
+	    (unsigned char *)e + e->next_offset > limit) {
 		duprintf("Bad offset %p, limit = %p\n", e, limit);
 		return -EINVAL;
 	}
@@ -1505,8 +1478,11 @@ check_compat_entry_size_and_hooks(struct
 		return -EINVAL;
 	}
 
-	/* For purposes of check_entry casting the compat entry is fine */
-	ret = check_entry((struct ipt_entry *)e, name);
+	if (!ip_checkentry(&e->ip))
+		return -EINVAL;
+
+	ret = xt_compat_check_entry_offsets(e, e->elems,
+					    e->target_offset, e->next_offset);
 	if (ret)
 		return ret;
 
@@ -1514,7 +1490,7 @@ check_compat_entry_size_and_hooks(struct
 	entry_offset = (void *)e - (void *)base;
 	j = 0;
 	xt_ematch_foreach(ematch, e) {
-		ret = compat_find_calc_match(ematch, name, &e->ip, &off);
+		ret = compat_find_calc_match(ematch, &e->ip, &off);
 		if (ret != 0)
 			goto release_matches;
 		++j;
@@ -1537,17 +1513,6 @@ check_compat_entry_size_and_hooks(struct
 	if (ret)
 		goto out;
 
-	/* Check hooks & underflows */
-	for (h = 0; h < NF_INET_NUMHOOKS; h++) {
-		if ((unsigned char *)e - base == hook_entries[h])
-			newinfo->hook_entry[h] = hook_entries[h];
-		if ((unsigned char *)e - base == underflows[h])
-			newinfo->underflow[h] = underflows[h];
-	}
-
-	/* Clear counters and comefrom */
-	memset(&e->counters, 0, sizeof(e->counters));
-	e->comefrom = 0;
 	return 0;
 
 out:
@@ -1561,19 +1526,18 @@ release_matches:
 	return ret;
 }
 
-static int
+static void
 compat_copy_entry_from_user(struct compat_ipt_entry *e, void **dstptr,
-			    unsigned int *size, const char *name,
+			    unsigned int *size,
 			    struct xt_table_info *newinfo, unsigned char *base)
 {
 	struct xt_entry_target *t;
 	struct xt_target *target;
 	struct ipt_entry *de;
 	unsigned int origsize;
-	int ret, h;
+	int h;
 	struct xt_entry_match *ematch;
 
-	ret = 0;
 	origsize = *size;
 	de = (struct ipt_entry *)*dstptr;
 	memcpy(de, e, sizeof(struct ipt_entry));
@@ -1582,201 +1546,105 @@ compat_copy_entry_from_user(struct compa
 	*dstptr += sizeof(struct ipt_entry);
 	*size += sizeof(struct ipt_entry) - sizeof(struct compat_ipt_entry);
 
-	xt_ematch_foreach(ematch, e) {
-		ret = xt_compat_match_from_user(ematch, dstptr, size);
-		if (ret != 0)
-			return ret;
-	}
+	xt_ematch_foreach(ematch, e)
+		xt_compat_match_from_user(ematch, dstptr, size);
+
 	de->target_offset = e->target_offset - (origsize - *size);
 	t = compat_ipt_get_target(e);
 	target = t->u.kernel.target;
 	xt_compat_target_from_user(t, dstptr, size);
 
 	de->next_offset = e->next_offset - (origsize - *size);
+
 	for (h = 0; h < NF_INET_NUMHOOKS; h++) {
 		if ((unsigned char *)de - base < newinfo->hook_entry[h])
 			newinfo->hook_entry[h] -= origsize - *size;
 		if ((unsigned char *)de - base < newinfo->underflow[h])
 			newinfo->underflow[h] -= origsize - *size;
 	}
-	return ret;
-}
-
-static int
-compat_check_entry(struct ipt_entry *e, struct net *net, const char *name)
-{
-	struct xt_entry_match *ematch;
-	struct xt_mtchk_param mtpar;
-	unsigned int j;
-	int ret = 0;
-
-	e->counters.pcnt = xt_percpu_counter_alloc();
-	if (IS_ERR_VALUE(e->counters.pcnt))
-		return -ENOMEM;
-
-	j = 0;
-	mtpar.net	= net;
-	mtpar.table     = name;
-	mtpar.entryinfo = &e->ip;
-	mtpar.hook_mask = e->comefrom;
-	mtpar.family    = NFPROTO_IPV4;
-	xt_ematch_foreach(ematch, e) {
-		ret = check_match(ematch, &mtpar);
-		if (ret != 0)
-			goto cleanup_matches;
-		++j;
-	}
-
-	ret = check_target(e, net, name);
-	if (ret)
-		goto cleanup_matches;
-	return 0;
-
- cleanup_matches:
-	xt_ematch_foreach(ematch, e) {
-		if (j-- == 0)
-			break;
-		cleanup_match(ematch, net);
-	}
-
-	xt_percpu_counter_free(e->counters.pcnt);
-
-	return ret;
 }
 
 static int
 translate_compat_table(struct net *net,
-		       const char *name,
-		       unsigned int valid_hooks,
 		       struct xt_table_info **pinfo,
 		       void **pentry0,
-		       unsigned int total_size,
-		       unsigned int number,
-		       unsigned int *hook_entries,
-		       unsigned int *underflows)
+		       const struct compat_ipt_replace *compatr)
 {
 	unsigned int i, j;
 	struct xt_table_info *newinfo, *info;
 	void *pos, *entry0, *entry1;
 	struct compat_ipt_entry *iter0;
-	struct ipt_entry *iter1;
+	struct ipt_replace repl;
 	unsigned int size;
 	int ret;
 
 	info = *pinfo;
 	entry0 = *pentry0;
-	size = total_size;
-	info->number = number;
-
-	/* Init all hooks to impossible value. */
-	for (i = 0; i < NF_INET_NUMHOOKS; i++) {
-		info->hook_entry[i] = 0xFFFFFFFF;
-		info->underflow[i] = 0xFFFFFFFF;
-	}
+	size = compatr->size;
+	info->number = compatr->num_entries;
 
 	duprintf("translate_compat_table: size %u\n", info->size);
 	j = 0;
 	xt_compat_lock(AF_INET);
-	xt_compat_init_offsets(AF_INET, number);
+	xt_compat_init_offsets(AF_INET, compatr->num_entries);
 	/* Walk through entries, checking offsets. */
-	xt_entry_foreach(iter0, entry0, total_size) {
+	xt_entry_foreach(iter0, entry0, compatr->size) {
 		ret = check_compat_entry_size_and_hooks(iter0, info, &size,
 							entry0,
-							entry0 + total_size,
-							hook_entries,
-							underflows,
-							name);
+							entry0 + compatr->size);
 		if (ret != 0)
 			goto out_unlock;
 		++j;
 	}
 
 	ret = -EINVAL;
-	if (j != number) {
+	if (j != compatr->num_entries) {
 		duprintf("translate_compat_table: %u not %u entries\n",
-			 j, number);
+			 j, compatr->num_entries);
 		goto out_unlock;
 	}
 
-	/* Check hooks all assigned */
-	for (i = 0; i < NF_INET_NUMHOOKS; i++) {
-		/* Only hooks which are valid */
-		if (!(valid_hooks & (1 << i)))
-			continue;
-		if (info->hook_entry[i] == 0xFFFFFFFF) {
-			duprintf("Invalid hook entry %u %u\n",
-				 i, hook_entries[i]);
-			goto out_unlock;
-		}
-		if (info->underflow[i] == 0xFFFFFFFF) {
-			duprintf("Invalid underflow %u %u\n",
-				 i, underflows[i]);
-			goto out_unlock;
-		}
-	}
-
 	ret = -ENOMEM;
 	newinfo = xt_alloc_table_info(size);
 	if (!newinfo)
 		goto out_unlock;
 
-	newinfo->number = number;
+	newinfo->number = compatr->num_entries;
 	for (i = 0; i < NF_INET_NUMHOOKS; i++) {
-		newinfo->hook_entry[i] = info->hook_entry[i];
-		newinfo->underflow[i] = info->underflow[i];
+		newinfo->hook_entry[i] = compatr->hook_entry[i];
+		newinfo->underflow[i] = compatr->underflow[i];
 	}
 	entry1 = newinfo->entries;
 	pos = entry1;
-	size = total_size;
-	xt_entry_foreach(iter0, entry0, total_size) {
-		ret = compat_copy_entry_from_user(iter0, &pos, &size,
-						  name, newinfo, entry1);
-		if (ret != 0)
-			break;
-	}
+	size = compatr->size;
+	xt_entry_foreach(iter0, entry0, compatr->size)
+		compat_copy_entry_from_user(iter0, &pos, &size,
+					    newinfo, entry1);
+
+	/* all module references in entry0 are now gone.
+	 * entry1/newinfo contains a 64bit ruleset that looks exactly as
+	 * generated by 64bit userspace.
+	 *
+	 * Call standard translate_table() to validate all hook_entrys,
+	 * underflows, check for loops, etc.
+	 */
 	xt_compat_flush_offsets(AF_INET);
 	xt_compat_unlock(AF_INET);
-	if (ret)
-		goto free_newinfo;
 
-	ret = -ELOOP;
-	if (!mark_source_chains(newinfo, valid_hooks, entry1))
-		goto free_newinfo;
+	memcpy(&repl, compatr, sizeof(*compatr));
 
-	i = 0;
-	xt_entry_foreach(iter1, entry1, newinfo->size) {
-		ret = compat_check_entry(iter1, net, name);
-		if (ret != 0)
-			break;
-		++i;
-		if (strcmp(ipt_get_target(iter1)->u.user.name,
-		    XT_ERROR_TARGET) == 0)
-			++newinfo->stacksize;
-	}
-	if (ret) {
-		/*
-		 * The first i matches need cleanup_entry (calls ->destroy)
-		 * because they had called ->check already. The other j-i
-		 * entries need only release.
-		 */
-		int skip = i;
-		j -= i;
-		xt_entry_foreach(iter0, entry0, newinfo->size) {
-			if (skip-- > 0)
-				continue;
-			if (j-- == 0)
-				break;
-			compat_release_entry(iter0);
-		}
-		xt_entry_foreach(iter1, entry1, newinfo->size) {
-			if (i-- == 0)
-				break;
-			cleanup_entry(iter1, net);
-		}
-		xt_free_table_info(newinfo);
-		return ret;
+	for (i = 0; i < NF_INET_NUMHOOKS; i++) {
+		repl.hook_entry[i] = newinfo->hook_entry[i];
+		repl.underflow[i] = newinfo->underflow[i];
 	}
 
+	repl.num_counters = 0;
+	repl.counters = NULL;
+	repl.size = newinfo->size;
+	ret = translate_table(net, newinfo, entry1, &repl);
+	if (ret)
+		goto free_newinfo;
+
 	*pinfo = newinfo;
 	*pentry0 = entry1;
 	xt_free_table_info(info);
@@ -1784,17 +1652,16 @@ translate_compat_table(struct net *net,
 
 free_newinfo:
 	xt_free_table_info(newinfo);
-out:
-	xt_entry_foreach(iter0, entry0, total_size) {
+	return ret;
+out_unlock:
+	xt_compat_flush_offsets(AF_INET);
+	xt_compat_unlock(AF_INET);
+	xt_entry_foreach(iter0, entry0, compatr->size) {
 		if (j-- == 0)
 			break;
 		compat_release_entry(iter0);
 	}
 	return ret;
-out_unlock:
-	xt_compat_flush_offsets(AF_INET);
-	xt_compat_unlock(AF_INET);
-	goto out;
 }
 
 static int
@@ -1830,10 +1697,7 @@ compat_do_replace(struct net *net, void
 		goto free_newinfo;
 	}
 
-	ret = translate_compat_table(net, tmp.name, tmp.valid_hooks,
-				     &newinfo, &loc_cpu_entry, tmp.size,
-				     tmp.num_entries, tmp.hook_entry,
-				     tmp.underflow);
+	ret = translate_compat_table(net, &newinfo, &loc_cpu_entry, &tmp);
 	if (ret != 0)
 		goto free_newinfo;
 
--- zfcpdump-kernel-4.4.orig/net/ipv4/netfilter/nf_defrag_ipv4.c
+++ zfcpdump-kernel-4.4/net/ipv4/netfilter/nf_defrag_ipv4.c
@@ -27,8 +27,6 @@ static int nf_ct_ipv4_gather_frags(struc
 {
 	int err;
 
-	skb_orphan(skb);
-
 	local_bh_disable();
 	err = ip_defrag(net, skb, user);
 	local_bh_enable();
--- zfcpdump-kernel-4.4.orig/net/ipv4/netfilter/nf_nat_masquerade_ipv4.c
+++ zfcpdump-kernel-4.4/net/ipv4/netfilter/nf_nat_masquerade_ipv4.c
@@ -108,10 +108,18 @@ static int masq_inet_event(struct notifi
 			   unsigned long event,
 			   void *ptr)
 {
-	struct net_device *dev = ((struct in_ifaddr *)ptr)->ifa_dev->dev;
+	struct in_device *idev = ((struct in_ifaddr *)ptr)->ifa_dev;
 	struct netdev_notifier_info info;
 
-	netdev_notifier_info_init(&info, dev);
+	/* The masq_dev_notifier will catch the case of the device going
+	 * down.  So if the inetdev is dead and being destroyed we have
+	 * no work to do.  Otherwise this is an individual address removal
+	 * and we have to perform the flush.
+	 */
+	if (idev->dead)
+		return NOTIFY_DONE;
+
+	netdev_notifier_info_init(&info, idev->dev);
 	return masq_device_event(this, event, &info);
 }
 
--- zfcpdump-kernel-4.4.orig/net/ipv4/ping.c
+++ zfcpdump-kernel-4.4/net/ipv4/ping.c
@@ -746,8 +746,10 @@ static int ping_v4_sendmsg(struct sock *
 
 	if (msg->msg_controllen) {
 		err = ip_cmsg_send(sock_net(sk), msg, &ipc, false);
-		if (err)
+		if (unlikely(err)) {
+			kfree(ipc.opt);
 			return err;
+		}
 		if (ipc.opt)
 			free = 1;
 	}
--- zfcpdump-kernel-4.4.orig/net/ipv4/raw.c
+++ zfcpdump-kernel-4.4/net/ipv4/raw.c
@@ -547,8 +547,10 @@ static int raw_sendmsg(struct sock *sk,
 
 	if (msg->msg_controllen) {
 		err = ip_cmsg_send(net, msg, &ipc, false);
-		if (err)
+		if (unlikely(err)) {
+			kfree(ipc.opt);
 			goto out;
+		}
 		if (ipc.opt)
 			free = 1;
 	}
--- zfcpdump-kernel-4.4.orig/net/ipv4/route.c
+++ zfcpdump-kernel-4.4/net/ipv4/route.c
@@ -129,6 +129,7 @@ static int ip_rt_mtu_expires __read_most
 static int ip_rt_min_pmtu __read_mostly		= 512 + 20 + 20;
 static int ip_rt_min_advmss __read_mostly	= 256;
 
+static int ip_rt_gc_timeout __read_mostly	= RT_GC_TIMEOUT;
 /*
  *	Interface to generic destination cache.
  */
@@ -755,7 +756,7 @@ static void __ip_do_redirect(struct rtab
 				struct fib_nh *nh = &FIB_RES_NH(res);
 
 				update_or_create_fnhe(nh, fl4->daddr, new_gw,
-						      0, 0);
+						0, jiffies + ip_rt_gc_timeout);
 			}
 			if (kill_route)
 				rt->dst.obsolete = DST_OBSOLETE_KILL;
@@ -1556,6 +1557,36 @@ static void ip_handle_martian_source(str
 #endif
 }
 
+static void ip_del_fnhe(struct fib_nh *nh, __be32 daddr)
+{
+	struct fnhe_hash_bucket *hash;
+	struct fib_nh_exception *fnhe, __rcu **fnhe_p;
+	u32 hval = fnhe_hashfun(daddr);
+
+	spin_lock_bh(&fnhe_lock);
+
+	hash = rcu_dereference_protected(nh->nh_exceptions,
+					 lockdep_is_held(&fnhe_lock));
+	hash += hval;
+
+	fnhe_p = &hash->chain;
+	fnhe = rcu_dereference_protected(*fnhe_p, lockdep_is_held(&fnhe_lock));
+	while (fnhe) {
+		if (fnhe->fnhe_daddr == daddr) {
+			rcu_assign_pointer(*fnhe_p, rcu_dereference_protected(
+				fnhe->fnhe_next, lockdep_is_held(&fnhe_lock)));
+			fnhe_flush_routes(fnhe);
+			kfree_rcu(fnhe, rcu);
+			break;
+		}
+		fnhe_p = &fnhe->fnhe_next;
+		fnhe = rcu_dereference_protected(fnhe->fnhe_next,
+						 lockdep_is_held(&fnhe_lock));
+	}
+
+	spin_unlock_bh(&fnhe_lock);
+}
+
 /* called in rcu_read_lock() section */
 static int __mkroute_input(struct sk_buff *skb,
 			   const struct fib_result *res,
@@ -1609,11 +1640,20 @@ static int __mkroute_input(struct sk_buf
 
 	fnhe = find_exception(&FIB_RES_NH(*res), daddr);
 	if (do_cache) {
-		if (fnhe)
+		if (fnhe) {
 			rth = rcu_dereference(fnhe->fnhe_rth_input);
-		else
-			rth = rcu_dereference(FIB_RES_NH(*res).nh_rth_input);
+			if (rth && rth->dst.expires &&
+			    time_after(jiffies, rth->dst.expires)) {
+				ip_del_fnhe(&FIB_RES_NH(*res), daddr);
+				fnhe = NULL;
+			} else {
+				goto rt_cache;
+			}
+		}
+
+		rth = rcu_dereference(FIB_RES_NH(*res).nh_rth_input);
 
+rt_cache:
 		if (rt_cache_valid(rth)) {
 			skb_dst_set_noref(skb, &rth->dst);
 			goto out;
@@ -2005,6 +2045,18 @@ static struct rtable *__mkroute_output(c
 		 */
 		if (fi && res->prefixlen < 4)
 			fi = NULL;
+	} else if ((type == RTN_LOCAL) && (orig_oif != 0) &&
+		   (orig_oif != dev_out->ifindex)) {
+		/* For local routes that require a particular output interface
+		 * we do not want to cache the result.  Caching the result
+		 * causes incorrect behaviour when there are multiple source
+		 * addresses on the interface, the end result being that if the
+		 * intended recipient is waiting on that interface for the
+		 * packet he won't receive it because it will be delivered on
+		 * the loopback interface and the IP_PKTINFO ipi_ifindex will
+		 * be set to the loopback interface as well.
+		 */
+		fi = NULL;
 	}
 
 	fnhe = NULL;
@@ -2014,19 +2066,29 @@ static struct rtable *__mkroute_output(c
 		struct fib_nh *nh = &FIB_RES_NH(*res);
 
 		fnhe = find_exception(nh, fl4->daddr);
-		if (fnhe)
+		if (fnhe) {
 			prth = &fnhe->fnhe_rth_output;
-		else {
-			if (unlikely(fl4->flowi4_flags &
-				     FLOWI_FLAG_KNOWN_NH &&
-				     !(nh->nh_gw &&
-				       nh->nh_scope == RT_SCOPE_LINK))) {
-				do_cache = false;
-				goto add;
+			rth = rcu_dereference(*prth);
+			if (rth && rth->dst.expires &&
+			    time_after(jiffies, rth->dst.expires)) {
+				ip_del_fnhe(nh, fl4->daddr);
+				fnhe = NULL;
+			} else {
+				goto rt_cache;
 			}
-			prth = raw_cpu_ptr(nh->nh_pcpu_rth_output);
 		}
+
+		if (unlikely(fl4->flowi4_flags &
+			     FLOWI_FLAG_KNOWN_NH &&
+			     !(nh->nh_gw &&
+			       nh->nh_scope == RT_SCOPE_LINK))) {
+			do_cache = false;
+			goto add;
+		}
+		prth = raw_cpu_ptr(nh->nh_pcpu_rth_output);
 		rth = rcu_dereference(*prth);
+
+rt_cache:
 		if (rt_cache_valid(rth)) {
 			dst_hold(&rth->dst);
 			return rth;
@@ -2569,7 +2631,6 @@ void ip_rt_multicast_event(struct in_dev
 }
 
 #ifdef CONFIG_SYSCTL
-static int ip_rt_gc_timeout __read_mostly	= RT_GC_TIMEOUT;
 static int ip_rt_gc_interval __read_mostly  = 60 * HZ;
 static int ip_rt_gc_min_interval __read_mostly	= HZ / 2;
 static int ip_rt_gc_elasticity __read_mostly	= 8;
--- zfcpdump-kernel-4.4.orig/net/ipv4/tcp.c
+++ zfcpdump-kernel-4.4/net/ipv4/tcp.c
@@ -279,6 +279,7 @@
 
 #include <asm/uaccess.h>
 #include <asm/ioctls.h>
+#include <asm/unaligned.h>
 #include <net/busy_poll.h>
 
 int sysctl_tcp_fin_timeout __read_mostly = TCP_FIN_TIMEOUT;
@@ -938,7 +939,7 @@ new_segment:
 
 		i = skb_shinfo(skb)->nr_frags;
 		can_coalesce = skb_can_coalesce(skb, i, page, offset);
-		if (!can_coalesce && i >= MAX_SKB_FRAGS) {
+		if (!can_coalesce && i >= sysctl_max_skb_frags) {
 			tcp_mark_push(tp, skb);
 			goto new_segment;
 		}
@@ -1211,7 +1212,7 @@ new_segment:
 
 			if (!skb_can_coalesce(skb, i, pfrag->page,
 					      pfrag->offset)) {
-				if (i == MAX_SKB_FRAGS || !sg) {
+				if (i == sysctl_max_skb_frags || !sg) {
 					tcp_mark_push(tp, skb);
 					goto new_segment;
 				}
@@ -2637,6 +2638,7 @@ void tcp_get_info(struct sock *sk, struc
 	const struct inet_connection_sock *icsk = inet_csk(sk);
 	u32 now = tcp_time_stamp;
 	unsigned int start;
+	u64 rate64;
 	u32 rate;
 
 	memset(info, 0, sizeof(*info));
@@ -2702,15 +2704,17 @@ void tcp_get_info(struct sock *sk, struc
 	info->tcpi_total_retrans = tp->total_retrans;
 
 	rate = READ_ONCE(sk->sk_pacing_rate);
-	info->tcpi_pacing_rate = rate != ~0U ? rate : ~0ULL;
+	rate64 = rate != ~0U ? rate : ~0ULL;
+	put_unaligned(rate64, &info->tcpi_pacing_rate);
 
 	rate = READ_ONCE(sk->sk_max_pacing_rate);
-	info->tcpi_max_pacing_rate = rate != ~0U ? rate : ~0ULL;
+	rate64 = rate != ~0U ? rate : ~0ULL;
+	put_unaligned(rate64, &info->tcpi_max_pacing_rate);
 
 	do {
 		start = u64_stats_fetch_begin_irq(&tp->syncp);
-		info->tcpi_bytes_acked = tp->bytes_acked;
-		info->tcpi_bytes_received = tp->bytes_received;
+		put_unaligned(tp->bytes_acked, &info->tcpi_bytes_acked);
+		put_unaligned(tp->bytes_received, &info->tcpi_bytes_received);
 	} while (u64_stats_fetch_retry_irq(&tp->syncp, start));
 	info->tcpi_segs_out = tp->segs_out;
 	info->tcpi_segs_in = tp->segs_in;
--- zfcpdump-kernel-4.4.orig/net/ipv4/tcp_input.c
+++ zfcpdump-kernel-4.4/net/ipv4/tcp_input.c
@@ -89,7 +89,7 @@ int sysctl_tcp_adv_win_scale __read_most
 EXPORT_SYMBOL(sysctl_tcp_adv_win_scale);
 
 /* rfc5961 challenge ack rate limiting */
-int sysctl_tcp_challenge_ack_limit = 100;
+int sysctl_tcp_challenge_ack_limit = 1000;
 
 int sysctl_tcp_stdurg __read_mostly;
 int sysctl_tcp_rfc1337 __read_mostly;
@@ -3390,6 +3390,23 @@ static int tcp_ack_update_window(struct
 	return flag;
 }
 
+static bool __tcp_oow_rate_limited(struct net *net, int mib_idx,
+				   u32 *last_oow_ack_time)
+{
+	if (*last_oow_ack_time) {
+		s32 elapsed = (s32)(tcp_time_stamp - *last_oow_ack_time);
+
+		if (0 <= elapsed && elapsed < sysctl_tcp_invalid_ratelimit) {
+			NET_INC_STATS_BH(net, mib_idx);
+			return true;	/* rate-limited: don't send yet! */
+		}
+	}
+
+	*last_oow_ack_time = tcp_time_stamp;
+
+	return false;	/* not rate-limited: go ahead, send dupack now! */
+}
+
 /* Return true if we're currently rate-limiting out-of-window ACKs and
  * thus shouldn't send a dupack right now. We rate-limit dupacks in
  * response to out-of-window SYNs or ACKs to mitigate ACK loops or DoS
@@ -3403,21 +3420,9 @@ bool tcp_oow_rate_limited(struct net *ne
 	/* Data packets without SYNs are not likely part of an ACK loop. */
 	if ((TCP_SKB_CB(skb)->seq != TCP_SKB_CB(skb)->end_seq) &&
 	    !tcp_hdr(skb)->syn)
-		goto not_rate_limited;
-
-	if (*last_oow_ack_time) {
-		s32 elapsed = (s32)(tcp_time_stamp - *last_oow_ack_time);
-
-		if (0 <= elapsed && elapsed < sysctl_tcp_invalid_ratelimit) {
-			NET_INC_STATS_BH(net, mib_idx);
-			return true;	/* rate-limited: don't send yet! */
-		}
-	}
-
-	*last_oow_ack_time = tcp_time_stamp;
+		return false;
 
-not_rate_limited:
-	return false;	/* not rate-limited: go ahead, send dupack now! */
+	return __tcp_oow_rate_limited(net, mib_idx, last_oow_ack_time);
 }
 
 /* RFC 5961 7 [ACK Throttling] */
@@ -3427,21 +3432,26 @@ static void tcp_send_challenge_ack(struc
 	static u32 challenge_timestamp;
 	static unsigned int challenge_count;
 	struct tcp_sock *tp = tcp_sk(sk);
-	u32 now;
+	u32 count, now;
 
 	/* First check our per-socket dupack rate limit. */
-	if (tcp_oow_rate_limited(sock_net(sk), skb,
-				 LINUX_MIB_TCPACKSKIPPEDCHALLENGE,
-				 &tp->last_oow_ack_time))
+	if (__tcp_oow_rate_limited(sock_net(sk),
+				   LINUX_MIB_TCPACKSKIPPEDCHALLENGE,
+				   &tp->last_oow_ack_time))
 		return;
 
-	/* Then check the check host-wide RFC 5961 rate limit. */
+	/* Then check host-wide RFC 5961 rate limit. */
 	now = jiffies / HZ;
 	if (now != challenge_timestamp) {
+		u32 half = (sysctl_tcp_challenge_ack_limit + 1) >> 1;
+
 		challenge_timestamp = now;
-		challenge_count = 0;
+		WRITE_ONCE(challenge_count, half +
+			   prandom_u32_max(sysctl_tcp_challenge_ack_limit));
 	}
-	if (++challenge_count <= sysctl_tcp_challenge_ack_limit) {
+	count = READ_ONCE(challenge_count);
+	if (count > 0) {
+		WRITE_ONCE(challenge_count, count - 1);
 		NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPCHALLENGEACK);
 		tcp_send_ack(sk);
 	}
--- zfcpdump-kernel-4.4.orig/net/ipv4/tcp_ipv4.c
+++ zfcpdump-kernel-4.4/net/ipv4/tcp_ipv4.c
@@ -312,7 +312,7 @@ static void do_redirect(struct sk_buff *
 
 
 /* handle ICMP messages on TCP_NEW_SYN_RECV request sockets */
-void tcp_req_err(struct sock *sk, u32 seq)
+void tcp_req_err(struct sock *sk, u32 seq, bool abort)
 {
 	struct request_sock *req = inet_reqsk(sk);
 	struct net *net = sock_net(sk);
@@ -320,11 +320,9 @@ void tcp_req_err(struct sock *sk, u32 se
 	/* ICMPs are not backlogged, hence we cannot get
 	 * an established socket here.
 	 */
-	WARN_ON(req->sk);
-
 	if (seq != tcp_rsk(req)->snt_isn) {
 		NET_INC_STATS_BH(net, LINUX_MIB_OUTOFWINDOWICMPS);
-	} else {
+	} else if (abort) {
 		/*
 		 * Still in SYN_RECV, just remove it silently.
 		 * There is no good way to pass the error to the newly
@@ -384,7 +382,12 @@ void tcp_v4_err(struct sk_buff *icmp_skb
 	}
 	seq = ntohl(th->seq);
 	if (sk->sk_state == TCP_NEW_SYN_RECV)
-		return tcp_req_err(sk, seq);
+		return tcp_req_err(sk, seq,
+				  type == ICMP_PARAMETERPROB ||
+				  type == ICMP_TIME_EXCEEDED ||
+				  (type == ICMP_DEST_UNREACH &&
+				   (code == ICMP_NET_UNREACH ||
+				    code == ICMP_HOST_UNREACH)));
 
 	bh_lock_sock(sk);
 	/* If too many ICMPs get dropped on busy
@@ -705,7 +708,8 @@ release_sk1:
    outside socket context is ugly, certainly. What can I do?
  */
 
-static void tcp_v4_send_ack(struct sk_buff *skb, u32 seq, u32 ack,
+static void tcp_v4_send_ack(struct net *net,
+			    struct sk_buff *skb, u32 seq, u32 ack,
 			    u32 win, u32 tsval, u32 tsecr, int oif,
 			    struct tcp_md5sig_key *key,
 			    int reply_flags, u8 tos)
@@ -720,7 +724,6 @@ static void tcp_v4_send_ack(struct sk_bu
 			];
 	} rep;
 	struct ip_reply_arg arg;
-	struct net *net = dev_net(skb_dst(skb)->dev);
 
 	memset(&rep.th, 0, sizeof(struct tcphdr));
 	memset(&arg, 0, sizeof(arg));
@@ -782,7 +785,8 @@ static void tcp_v4_timewait_ack(struct s
 	struct inet_timewait_sock *tw = inet_twsk(sk);
 	struct tcp_timewait_sock *tcptw = tcp_twsk(sk);
 
-	tcp_v4_send_ack(skb, tcptw->tw_snd_nxt, tcptw->tw_rcv_nxt,
+	tcp_v4_send_ack(sock_net(sk), skb,
+			tcptw->tw_snd_nxt, tcptw->tw_rcv_nxt,
 			tcptw->tw_rcv_wnd >> tw->tw_rcv_wscale,
 			tcp_time_stamp + tcptw->tw_ts_offset,
 			tcptw->tw_ts_recent,
@@ -801,9 +805,17 @@ static void tcp_v4_reqsk_send_ack(const
 	/* sk->sk_state == TCP_LISTEN -> for regular TCP_SYN_RECV
 	 * sk->sk_state == TCP_SYN_RECV -> for Fast Open.
 	 */
-	tcp_v4_send_ack(skb, (sk->sk_state == TCP_LISTEN) ?
-			tcp_rsk(req)->snt_isn + 1 : tcp_sk(sk)->snd_nxt,
-			tcp_rsk(req)->rcv_nxt, req->rsk_rcv_wnd,
+	u32 seq = (sk->sk_state == TCP_LISTEN) ? tcp_rsk(req)->snt_isn + 1 :
+					     tcp_sk(sk)->snd_nxt;
+
+	/* RFC 7323 2.3
+	 * The window field (SEG.WND) of every outgoing segment, with the
+	 * exception of <SYN> segments, MUST be right-shifted by
+	 * Rcv.Wind.Shift bits:
+	 */
+	tcp_v4_send_ack(sock_net(sk), skb, seq,
+			tcp_rsk(req)->rcv_nxt,
+			req->rsk_rcv_wnd >> inet_rsk(req)->rcv_wscale,
 			tcp_time_stamp,
 			req->ts_recent,
 			0,
@@ -1586,28 +1598,30 @@ process:
 
 	if (sk->sk_state == TCP_NEW_SYN_RECV) {
 		struct request_sock *req = inet_reqsk(sk);
-		struct sock *nsk = NULL;
+		struct sock *nsk;
 
 		sk = req->rsk_listener;
-		if (tcp_v4_inbound_md5_hash(sk, skb))
-			goto discard_and_relse;
-		if (likely(sk->sk_state == TCP_LISTEN)) {
-			nsk = tcp_check_req(sk, skb, req, false);
-		} else {
+		if (unlikely(tcp_v4_inbound_md5_hash(sk, skb))) {
+			reqsk_put(req);
+			goto discard_it;
+		}
+		if (unlikely(sk->sk_state != TCP_LISTEN)) {
 			inet_csk_reqsk_queue_drop_and_put(sk, req);
 			goto lookup;
 		}
+		sock_hold(sk);
+		nsk = tcp_check_req(sk, skb, req, false);
 		if (!nsk) {
 			reqsk_put(req);
-			goto discard_it;
+			goto discard_and_relse;
 		}
 		if (nsk == sk) {
-			sock_hold(sk);
 			reqsk_put(req);
 		} else if (tcp_child_process(sk, nsk, skb)) {
 			tcp_v4_send_reset(nsk, skb);
-			goto discard_it;
+			goto discard_and_relse;
 		} else {
+			sock_put(sk);
 			return 0;
 		}
 	}
--- zfcpdump-kernel-4.4.orig/net/ipv4/tcp_metrics.c
+++ zfcpdump-kernel-4.4/net/ipv4/tcp_metrics.c
@@ -550,7 +550,7 @@ reset:
 	 */
 	if (crtt > tp->srtt_us) {
 		/* Set RTO like tcp_rtt_estimator(), but from cached RTT. */
-		crtt /= 8 * USEC_PER_MSEC;
+		crtt /= 8 * USEC_PER_SEC / HZ;
 		inet_csk(sk)->icsk_rto = crtt + max(2 * crtt, tcp_rto_min(sk));
 	} else if (tp->srtt_us == 0) {
 		/* RFC6298: 5.7 We've failed to get a valid RTT sample from
--- zfcpdump-kernel-4.4.orig/net/ipv4/tcp_minisocks.c
+++ zfcpdump-kernel-4.4/net/ipv4/tcp_minisocks.c
@@ -458,7 +458,7 @@ struct sock *tcp_create_openreq_child(co
 
 		newtp->rcv_wup = newtp->copied_seq =
 		newtp->rcv_nxt = treq->rcv_isn + 1;
-		newtp->segs_in = 0;
+		newtp->segs_in = 1;
 
 		newtp->snd_sml = newtp->snd_una =
 		newtp->snd_nxt = newtp->snd_up = treq->snt_isn + 1;
@@ -818,6 +818,7 @@ int tcp_child_process(struct sock *paren
 	int ret = 0;
 	int state = child->sk_state;
 
+	tcp_sk(child)->segs_in += max_t(u16, 1, skb_shinfo(skb)->gso_segs);
 	if (!sock_owned_by_user(child)) {
 		ret = tcp_rcv_state_process(child, skb);
 		/* Wakeup parent, send SIGIO */
--- zfcpdump-kernel-4.4.orig/net/ipv4/tcp_output.c
+++ zfcpdump-kernel-4.4/net/ipv4/tcp_output.c
@@ -239,7 +239,8 @@ void tcp_select_initial_window(int __spa
 		/* Set window scaling on max possible window
 		 * See RFC1323 for an explanation of the limit to 14
 		 */
-		space = max_t(u32, sysctl_tcp_rmem[2], sysctl_rmem_max);
+		space = max_t(u32, space, sysctl_tcp_rmem[2]);
+		space = max_t(u32, space, sysctl_rmem_max);
 		space = min_t(u32, space, *window_clamp);
 		while (space > 65535 && (*rcv_wscale) < 14) {
 			space >>= 1;
@@ -2625,8 +2626,10 @@ int __tcp_retransmit_skb(struct sock *sk
 	 */
 	if (unlikely((NET_IP_ALIGN && ((unsigned long)skb->data & 3)) ||
 		     skb_headroom(skb) >= 0xFFFF)) {
-		struct sk_buff *nskb = __pskb_copy(skb, MAX_TCP_HEADER,
-						   GFP_ATOMIC);
+		struct sk_buff *nskb;
+
+		skb_mstamp_get(&skb->skb_mstamp);
+		nskb = __pskb_copy(skb, MAX_TCP_HEADER, GFP_ATOMIC);
 		err = nskb ? tcp_transmit_skb(sk, nskb, 0, GFP_ATOMIC) :
 			     -ENOBUFS;
 	} else {
--- zfcpdump-kernel-4.4.orig/net/ipv4/tcp_yeah.c
+++ zfcpdump-kernel-4.4/net/ipv4/tcp_yeah.c
@@ -75,7 +75,7 @@ static void tcp_yeah_cong_avoid(struct s
 	if (!tcp_is_cwnd_limited(sk))
 		return;
 
-	if (tp->snd_cwnd <= tp->snd_ssthresh)
+	if (tcp_in_slow_start(tp))
 		tcp_slow_start(tp, acked);
 
 	else if (!yeah->doing_reno_now) {
@@ -219,7 +219,7 @@ static u32 tcp_yeah_ssthresh(struct sock
 	yeah->fast_count = 0;
 	yeah->reno_count = max(yeah->reno_count>>1, 2U);
 
-	return tp->snd_cwnd - reduction;
+	return max_t(int, tp->snd_cwnd - reduction, 2);
 }
 
 static struct tcp_congestion_ops tcp_yeah __read_mostly = {
--- zfcpdump-kernel-4.4.orig/net/ipv4/udp.c
+++ zfcpdump-kernel-4.4/net/ipv4/udp.c
@@ -966,8 +966,10 @@ int udp_sendmsg(struct sock *sk, struct
 	if (msg->msg_controllen) {
 		err = ip_cmsg_send(sock_net(sk), msg, &ipc,
 				   sk->sk_family == AF_INET6);
-		if (err)
+		if (unlikely(err)) {
+			kfree(ipc.opt);
 			return err;
+		}
 		if (ipc.opt)
 			free = 1;
 		connected = 0;
@@ -1273,6 +1275,7 @@ int udp_recvmsg(struct sock *sk, struct
 	int peeked, off = 0;
 	int err;
 	int is_udplite = IS_UDPLITE(sk);
+	bool checksum_valid = false;
 	bool slow;
 
 	if (flags & MSG_ERRQUEUE)
@@ -1298,11 +1301,12 @@ try_again:
 	 */
 
 	if (copied < ulen || UDP_SKB_CB(skb)->partial_cov) {
-		if (udp_lib_checksum_complete(skb))
+		checksum_valid = !udp_lib_checksum_complete(skb);
+		if (!checksum_valid)
 			goto csum_copy_err;
 	}
 
-	if (skb_csum_unnecessary(skb))
+	if (checksum_valid || skb_csum_unnecessary(skb))
 		err = skb_copy_datagram_msg(skb, sizeof(struct udphdr),
 					    msg, copied);
 	else {
@@ -1529,7 +1533,7 @@ int udp_queue_rcv_skb(struct sock *sk, s
 
 		/* if we're overly short, let UDP handle it */
 		encap_rcv = ACCESS_ONCE(up->encap_rcv);
-		if (skb->len > sizeof(struct udphdr) && encap_rcv) {
+		if (encap_rcv) {
 			int ret;
 
 			/* Verify checksum before giving to encap */
@@ -1988,10 +1992,14 @@ void udp_v4_early_demux(struct sk_buff *
 		if (!in_dev)
 			return;
 
-		ours = ip_check_mc_rcu(in_dev, iph->daddr, iph->saddr,
-				       iph->protocol);
-		if (!ours)
-			return;
+		/* we are supposed to accept bcast packets */
+		if (skb->pkt_type == PACKET_MULTICAST) {
+			ours = ip_check_mc_rcu(in_dev, iph->daddr, iph->saddr,
+					       iph->protocol);
+			if (!ours)
+				return;
+		}
+
 		sk = __udp4_lib_mcast_demux_lookup(net, uh->dest, iph->daddr,
 						   uh->source, iph->saddr, dif);
 	} else if (skb->pkt_type == PACKET_HOST) {
--- zfcpdump-kernel-4.4.orig/net/ipv4/udp_offload.c
+++ zfcpdump-kernel-4.4/net/ipv4/udp_offload.c
@@ -299,14 +299,14 @@ struct sk_buff **udp_gro_receive(struct
 	unsigned int off = skb_gro_offset(skb);
 	int flush = 1;
 
-	if (NAPI_GRO_CB(skb)->udp_mark ||
+	if (NAPI_GRO_CB(skb)->encap_mark ||
 	    (skb->ip_summed != CHECKSUM_PARTIAL &&
 	     NAPI_GRO_CB(skb)->csum_cnt == 0 &&
 	     !NAPI_GRO_CB(skb)->csum_valid))
 		goto out;
 
-	/* mark that this skb passed once through the udp gro layer */
-	NAPI_GRO_CB(skb)->udp_mark = 1;
+	/* mark that this skb passed once through the tunnel gro layer */
+	NAPI_GRO_CB(skb)->encap_mark = 1;
 
 	rcu_read_lock();
 	uo_priv = rcu_dereference(udp_offload_base);
@@ -339,8 +339,14 @@ unflush:
 	skb_gro_pull(skb, sizeof(struct udphdr)); /* pull encapsulating udp header */
 	skb_gro_postpull_rcsum(skb, uh, sizeof(struct udphdr));
 	NAPI_GRO_CB(skb)->proto = uo_priv->offload->ipproto;
-	pp = uo_priv->offload->callbacks.gro_receive(head, skb,
-						     uo_priv->offload);
+
+	if (gro_recursion_inc_test(skb)) {
+		flush = 1;
+		pp = NULL;
+	} else {
+		pp = uo_priv->offload->callbacks.gro_receive(head, skb,
+							     uo_priv->offload);
+	}
 
 out_unlock:
 	rcu_read_unlock();
--- zfcpdump-kernel-4.4.orig/net/ipv4/udp_tunnel.c
+++ zfcpdump-kernel-4.4/net/ipv4/udp_tunnel.c
@@ -89,6 +89,8 @@ int udp_tunnel_xmit_skb(struct rtable *r
 	uh->source = src_port;
 	uh->len = htons(skb->len);
 
+	memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt));
+
 	udp_set_csum(nocheck, skb, src, dst, skb->len);
 
 	return iptunnel_xmit(sk, rt, skb, src, dst, IPPROTO_UDP,
--- zfcpdump-kernel-4.4.orig/net/ipv6/addrconf.c
+++ zfcpdump-kernel-4.4/net/ipv6/addrconf.c
@@ -583,7 +583,7 @@ static int inet6_netconf_get_devconf(str
 	if (err < 0)
 		goto errout;
 
-	err = EINVAL;
+	err = -EINVAL;
 	if (!tb[NETCONFA_IFINDEX])
 		goto errout;
 
@@ -1898,6 +1898,7 @@ errdad:
 	spin_unlock_bh(&ifp->lock);
 
 	addrconf_mod_dad_work(ifp, 0);
+	in6_ifa_put(ifp);
 }
 
 /* Join to solicited addr multicast group.
@@ -3506,6 +3507,7 @@ static void addrconf_dad_begin(struct in
 {
 	struct inet6_dev *idev = ifp->idev;
 	struct net_device *dev = idev->dev;
+	bool notify = false;
 
 	addrconf_join_solict(dev, &ifp->addr);
 
@@ -3551,7 +3553,7 @@ static void addrconf_dad_begin(struct in
 			/* Because optimistic nodes can use this address,
 			 * notify listeners. If DAD fails, RTM_DELADDR is sent.
 			 */
-			ipv6_ifa_notify(RTM_NEWADDR, ifp);
+			notify = true;
 		}
 	}
 
@@ -3559,6 +3561,8 @@ static void addrconf_dad_begin(struct in
 out:
 	spin_unlock(&ifp->lock);
 	read_unlock_bh(&idev->lock);
+	if (notify)
+		ipv6_ifa_notify(RTM_NEWADDR, ifp);
 }
 
 static void addrconf_dad_start(struct inet6_ifaddr *ifp)
@@ -3606,6 +3610,7 @@ static void addrconf_dad_work(struct wor
 		addrconf_dad_begin(ifp);
 		goto out;
 	} else if (action == DAD_ABORT) {
+		in6_ifa_hold(ifp);
 		addrconf_dad_stop(ifp, 1);
 		goto out;
 	}
--- zfcpdump-kernel-4.4.orig/net/ipv6/datagram.c
+++ zfcpdump-kernel-4.4/net/ipv6/datagram.c
@@ -162,6 +162,9 @@ ipv4_connected:
 	fl6.fl6_dport = inet->inet_dport;
 	fl6.fl6_sport = inet->inet_sport;
 
+	if (!fl6.flowi6_oif)
+		fl6.flowi6_oif = np->sticky_pktinfo.ipi6_ifindex;
+
 	if (!fl6.flowi6_oif && (addr_type&IPV6_ADDR_MULTICAST))
 		fl6.flowi6_oif = np->mcast_oif;
 
--- zfcpdump-kernel-4.4.orig/net/ipv6/exthdrs_core.c
+++ zfcpdump-kernel-4.4/net/ipv6/exthdrs_core.c
@@ -257,7 +257,11 @@ int ipv6_find_hdr(const struct sk_buff *
 						*fragoff = _frag_off;
 					return hp->nexthdr;
 				}
-				return -ENOENT;
+				if (!found)
+					return -ENOENT;
+				if (fragoff)
+					*fragoff = _frag_off;
+				break;
 			}
 			hdrlen = 8;
 		} else if (nexthdr == NEXTHDR_AUTH) {
--- zfcpdump-kernel-4.4.orig/net/ipv6/ip6_fib.c
+++ zfcpdump-kernel-4.4/net/ipv6/ip6_fib.c
@@ -179,6 +179,7 @@ static void rt6_free_pcpu(struct rt6_inf
 		}
 	}
 
+	free_percpu(non_pcpu_rt->rt6i_pcpu);
 	non_pcpu_rt->rt6i_pcpu = NULL;
 }
 
--- zfcpdump-kernel-4.4.orig/net/ipv6/ip6_flowlabel.c
+++ zfcpdump-kernel-4.4/net/ipv6/ip6_flowlabel.c
@@ -540,12 +540,13 @@ int ipv6_flowlabel_opt(struct sock *sk,
 		}
 		spin_lock_bh(&ip6_sk_fl_lock);
 		for (sflp = &np->ipv6_fl_list;
-		     (sfl = rcu_dereference(*sflp)) != NULL;
+		     (sfl = rcu_dereference_protected(*sflp,
+						      lockdep_is_held(&ip6_sk_fl_lock))) != NULL;
 		     sflp = &sfl->next) {
 			if (sfl->fl->label == freq.flr_label) {
 				if (freq.flr_label == (np->flow_label&IPV6_FLOWLABEL_MASK))
 					np->flow_label &= ~IPV6_FLOWLABEL_MASK;
-				*sflp = rcu_dereference(sfl->next);
+				*sflp = sfl->next;
 				spin_unlock_bh(&ip6_sk_fl_lock);
 				fl_release(sfl->fl);
 				kfree_rcu(sfl, rcu);
--- zfcpdump-kernel-4.4.orig/net/ipv6/ip6_gre.c
+++ zfcpdump-kernel-4.4/net/ipv6/ip6_gre.c
@@ -778,6 +778,8 @@ static inline int ip6gre_xmit_ipv4(struc
 	__u32 mtu;
 	int err;
 
+	memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt));
+
 	if (!(t->parms.flags & IP6_TNL_F_IGN_ENCAP_LIMIT))
 		encap_limit = t->parms.encap_limit;
 
--- zfcpdump-kernel-4.4.orig/net/ipv6/ip6_offload.c
+++ zfcpdump-kernel-4.4/net/ipv6/ip6_offload.c
@@ -247,7 +247,7 @@ static struct sk_buff **ipv6_gro_receive
 
 	skb_gro_postpull_rcsum(skb, iph, nlen);
 
-	pp = ops->callbacks.gro_receive(head, skb);
+	pp = call_gro_receive(ops->callbacks.gro_receive, head, skb);
 
 out_unlock:
 	rcu_read_unlock();
@@ -258,6 +258,19 @@ out:
 	return pp;
 }
 
+static struct sk_buff **sit_gro_receive(struct sk_buff **head,
+					struct sk_buff *skb)
+{
+	if (NAPI_GRO_CB(skb)->encap_mark) {
+		NAPI_GRO_CB(skb)->flush = 1;
+		return NULL;
+	}
+
+	NAPI_GRO_CB(skb)->encap_mark = 1;
+
+	return ipv6_gro_receive(head, skb);
+}
+
 static int ipv6_gro_complete(struct sk_buff *skb, int nhoff)
 {
 	const struct net_offload *ops;
@@ -302,7 +315,7 @@ static struct packet_offload ipv6_packet
 static const struct net_offload sit_offload = {
 	.callbacks = {
 		.gso_segment	= ipv6_gso_segment,
-		.gro_receive    = ipv6_gro_receive,
+		.gro_receive    = sit_gro_receive,
 		.gro_complete   = sit_gro_complete,
 	},
 };
--- zfcpdump-kernel-4.4.orig/net/ipv6/ip6_output.c
+++ zfcpdump-kernel-4.4/net/ipv6/ip6_output.c
@@ -909,6 +909,7 @@ static int ip6_dst_lookup_tail(struct ne
 	struct rt6_info *rt;
 #endif
 	int err;
+	int flags = 0;
 
 	/* The correct way to handle this would be to do
 	 * ip6_route_get_saddr, and then ip6_route_output; however,
@@ -940,10 +941,13 @@ static int ip6_dst_lookup_tail(struct ne
 			dst_release(*dst);
 			*dst = NULL;
 		}
+
+		if (fl6->flowi6_oif)
+			flags |= RT6_LOOKUP_F_IFACE;
 	}
 
 	if (!*dst)
-		*dst = ip6_route_output(net, sk, fl6);
+		*dst = ip6_route_output_flags(net, sk, fl6, flags);
 
 	err = (*dst)->error;
 	if (err)
@@ -1068,17 +1072,12 @@ struct dst_entry *ip6_sk_dst_lookup_flow
 					 const struct in6_addr *final_dst)
 {
 	struct dst_entry *dst = sk_dst_check(sk, inet6_sk(sk)->dst_cookie);
-	int err;
 
 	dst = ip6_sk_dst_check(sk, dst, fl6);
+	if (!dst)
+		dst = ip6_dst_lookup_flow(sk, fl6, final_dst);
 
-	err = ip6_dst_lookup_tail(sock_net(sk), sk, &dst, fl6);
-	if (err)
-		return ERR_PTR(err);
-	if (final_dst)
-		fl6->daddr = *final_dst;
-
-	return xfrm_lookup_route(sock_net(sk), dst, flowi6_to_flowi(fl6), sk, 0);
+	return dst;
 }
 EXPORT_SYMBOL_GPL(ip6_sk_dst_lookup_flow);
 
@@ -1087,8 +1086,8 @@ static inline int ip6_ufo_append_data(st
 			int getfrag(void *from, char *to, int offset, int len,
 			int odd, struct sk_buff *skb),
 			void *from, int length, int hh_len, int fragheaderlen,
-			int transhdrlen, int mtu, unsigned int flags,
-			const struct flowi6 *fl6)
+			int exthdrlen, int transhdrlen, int mtu,
+			unsigned int flags, const struct flowi6 *fl6)
 
 {
 	struct sk_buff *skb;
@@ -1113,7 +1112,7 @@ static inline int ip6_ufo_append_data(st
 		skb_put(skb, fragheaderlen + transhdrlen);
 
 		/* initialize network header pointer */
-		skb_reset_network_header(skb);
+		skb_set_network_header(skb, exthdrlen);
 
 		/* initialize protocol header pointer */
 		skb->transport_header = skb->network_header + fragheaderlen;
@@ -1353,9 +1352,9 @@ emsgsize:
 	     (skb && skb_is_gso(skb))) &&
 	    (sk->sk_protocol == IPPROTO_UDP) &&
 	    (rt->dst.dev->features & NETIF_F_UFO) &&
-	    (sk->sk_type == SOCK_DGRAM)) {
+	    (sk->sk_type == SOCK_DGRAM) && !udp_get_no_check6_tx(sk)) {
 		err = ip6_ufo_append_data(sk, queue, getfrag, from, length,
-					  hh_len, fragheaderlen,
+					  hh_len, fragheaderlen, exthdrlen,
 					  transhdrlen, mtu, flags, fl6);
 		if (err)
 			goto error;
--- zfcpdump-kernel-4.4.orig/net/ipv6/ip6_tunnel.c
+++ zfcpdump-kernel-4.4/net/ipv6/ip6_tunnel.c
@@ -343,12 +343,12 @@ static int ip6_tnl_create2(struct net_de
 
 	t = netdev_priv(dev);
 
+	dev->rtnl_link_ops = &ip6_link_ops;
 	err = register_netdevice(dev);
 	if (err < 0)
 		goto out;
 
 	strcpy(t->parms.name, dev->name);
-	dev->rtnl_link_ops = &ip6_link_ops;
 
 	dev_hold(dev);
 	ip6_tnl_link(ip6n, t);
@@ -1180,6 +1180,8 @@ ip4ip6_tnl_xmit(struct sk_buff *skb, str
 	u8 tproto;
 	int err;
 
+	memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt));
+
 	tproto = ACCESS_ONCE(t->parms.proto);
 	if (tproto != IPPROTO_IPIP && tproto != 0)
 		return -1;
--- zfcpdump-kernel-4.4.orig/net/ipv6/ip6mr.c
+++ zfcpdump-kernel-4.4/net/ipv6/ip6mr.c
@@ -1074,6 +1074,7 @@ static struct mfc6_cache *ip6mr_cache_al
 	struct mfc6_cache *c = kmem_cache_zalloc(mrt_cachep, GFP_KERNEL);
 	if (!c)
 		return NULL;
+	c->mfc_un.res.last_assert = jiffies - MFC_ASSERT_THRESH - 1;
 	c->mfc_un.res.minvif = MAXMIFS;
 	return c;
 }
--- zfcpdump-kernel-4.4.orig/net/ipv6/mcast.c
+++ zfcpdump-kernel-4.4/net/ipv6/mcast.c
@@ -1574,9 +1574,8 @@ static struct sk_buff *mld_newpack(struc
 		return NULL;
 
 	skb->priority = TC_PRIO_CONTROL;
-	skb->reserved_tailroom = skb_end_offset(skb) -
-				 min(mtu, skb_end_offset(skb));
 	skb_reserve(skb, hlen);
+	skb_tailroom_reserve(skb, mtu, tlen);
 
 	if (__ipv6_get_lladdr(idev, &addr_buf, IFA_F_TENTATIVE)) {
 		/* <draft-ietf-magma-mld-source-05.txt>:
--- zfcpdump-kernel-4.4.orig/net/ipv6/netfilter/ip6_tables.c
+++ zfcpdump-kernel-4.4/net/ipv6/netfilter/ip6_tables.c
@@ -198,11 +198,12 @@ get_entry(const void *base, unsigned int
 
 /* All zeroes == unconditional rule. */
 /* Mildly perf critical (only if packet tracing is on) */
-static inline bool unconditional(const struct ip6t_ip6 *ipv6)
+static inline bool unconditional(const struct ip6t_entry *e)
 {
 	static const struct ip6t_ip6 uncond;
 
-	return memcmp(ipv6, &uncond, sizeof(uncond)) == 0;
+	return e->target_offset == sizeof(struct ip6t_entry) &&
+	       memcmp(&e->ipv6, &uncond, sizeof(uncond)) == 0;
 }
 
 static inline const struct xt_entry_target *
@@ -258,11 +259,10 @@ get_chainname_rulenum(const struct ip6t_
 	} else if (s == e) {
 		(*rulenum)++;
 
-		if (s->target_offset == sizeof(struct ip6t_entry) &&
+		if (unconditional(s) &&
 		    strcmp(t->target.u.kernel.target->name,
 			   XT_STANDARD_TARGET) == 0 &&
-		    t->verdict < 0 &&
-		    unconditional(&s->ipv6)) {
+		    t->verdict < 0) {
 			/* Tail of chains: STANDARD target (return/policy) */
 			*comment = *chainname == hookname
 				? comments[NF_IP6_TRACE_COMMENT_POLICY]
@@ -455,6 +455,29 @@ ip6t_do_table(struct sk_buff *skb,
 #endif
 }
 
+static bool next_offset_ok(const struct xt_table_info *t, unsigned int newpos)
+{
+	if (newpos > t->size - sizeof(struct ip6t_entry))
+		return false;
+
+	if (newpos % __alignof__(struct ip6t_entry) != 0)
+		return false;
+
+	return true;
+}
+
+static bool find_jump_target(const struct xt_table_info *t,
+			     const struct ip6t_entry *target)
+{
+	struct ip6t_entry *iter;
+
+	xt_entry_foreach(iter, t->entries, t->size) {
+		 if (iter == target)
+			return true;
+	}
+	return false;
+}
+
 /* Figures out from what hook each rule can be called: returns 0 if
    there are loops.  Puts hook bitmask in comefrom. */
 static int
@@ -488,11 +511,10 @@ mark_source_chains(const struct xt_table
 			e->comefrom |= ((1 << hook) | (1 << NF_INET_NUMHOOKS));
 
 			/* Unconditional return/END. */
-			if ((e->target_offset == sizeof(struct ip6t_entry) &&
+			if ((unconditional(e) &&
 			     (strcmp(t->target.u.user.name,
 				     XT_STANDARD_TARGET) == 0) &&
-			     t->verdict < 0 &&
-			     unconditional(&e->ipv6)) || visited) {
+			     t->verdict < 0) || visited) {
 				unsigned int oldpos, size;
 
 				if ((strcmp(t->target.u.user.name,
@@ -531,8 +553,12 @@ mark_source_chains(const struct xt_table
 
 				/* Move along one */
 				size = e->next_offset;
+				if (!next_offset_ok(newinfo, pos + size))
+					return 0;
 				e = (struct ip6t_entry *)
 					(entry0 + pos + size);
+				if (pos + size >= newinfo->size)
+					return 0;
 				e->counters.pcnt = pos;
 				pos += size;
 			} else {
@@ -541,20 +567,23 @@ mark_source_chains(const struct xt_table
 				if (strcmp(t->target.u.user.name,
 					   XT_STANDARD_TARGET) == 0 &&
 				    newpos >= 0) {
-					if (newpos > newinfo->size -
-						sizeof(struct ip6t_entry)) {
-						duprintf("mark_source_chains: "
-							"bad verdict (%i)\n",
-								newpos);
-						return 0;
-					}
 					/* This a jump; chase it. */
 					duprintf("Jump rule %u -> %u\n",
 						 pos, newpos);
+					e = (struct ip6t_entry *)
+						(entry0 + newpos);
+					if (!find_jump_target(newinfo, e))
+						return 0;
 				} else {
 					/* ... this is a fallthru */
 					newpos = pos + e->next_offset;
+					if (newpos >= newinfo->size)
+						return 0;
 				}
+
+				if (!next_offset_ok(newinfo, newpos))
+					return 0;
+
 				e = (struct ip6t_entry *)
 					(entry0 + newpos);
 				e->counters.pcnt = pos;
@@ -580,27 +609,6 @@ static void cleanup_match(struct xt_entr
 	module_put(par.match->me);
 }
 
-static int
-check_entry(const struct ip6t_entry *e, const char *name)
-{
-	const struct xt_entry_target *t;
-
-	if (!ip6_checkentry(&e->ipv6)) {
-		duprintf("ip_tables: ip check failed %p %s.\n", e, name);
-		return -EINVAL;
-	}
-
-	if (e->target_offset + sizeof(struct xt_entry_target) >
-	    e->next_offset)
-		return -EINVAL;
-
-	t = ip6t_get_target_c(e);
-	if (e->target_offset + t->u.target_size > e->next_offset)
-		return -EINVAL;
-
-	return 0;
-}
-
 static int check_match(struct xt_entry_match *m, struct xt_mtchk_param *par)
 {
 	const struct ip6t_ip6 *ipv6 = par->entryinfo;
@@ -679,10 +687,6 @@ find_check_entry(struct ip6t_entry *e, s
 	struct xt_mtchk_param mtpar;
 	struct xt_entry_match *ematch;
 
-	ret = check_entry(e, name);
-	if (ret)
-		return ret;
-
 	e->counters.pcnt = xt_percpu_counter_alloc();
 	if (IS_ERR_VALUE(e->counters.pcnt))
 		return -ENOMEM;
@@ -733,7 +737,7 @@ static bool check_underflow(const struct
 	const struct xt_entry_target *t;
 	unsigned int verdict;
 
-	if (!unconditional(&e->ipv6))
+	if (!unconditional(e))
 		return false;
 	t = ip6t_get_target_c(e);
 	if (strcmp(t->u.user.name, XT_STANDARD_TARGET) != 0)
@@ -753,9 +757,11 @@ check_entry_size_and_hooks(struct ip6t_e
 			   unsigned int valid_hooks)
 {
 	unsigned int h;
+	int err;
 
 	if ((unsigned long)e % __alignof__(struct ip6t_entry) != 0 ||
-	    (unsigned char *)e + sizeof(struct ip6t_entry) >= limit) {
+	    (unsigned char *)e + sizeof(struct ip6t_entry) >= limit ||
+	    (unsigned char *)e + e->next_offset > limit) {
 		duprintf("Bad offset %p\n", e);
 		return -EINVAL;
 	}
@@ -767,6 +773,14 @@ check_entry_size_and_hooks(struct ip6t_e
 		return -EINVAL;
 	}
 
+	if (!ip6_checkentry(&e->ipv6))
+		return -EINVAL;
+
+	err = xt_check_entry_offsets(e, e->elems, e->target_offset,
+				     e->next_offset);
+	if (err)
+		return err;
+
 	/* Check hooks & underflows */
 	for (h = 0; h < NF_INET_NUMHOOKS; h++) {
 		if (!(valid_hooks & (1 << h)))
@@ -775,9 +789,9 @@ check_entry_size_and_hooks(struct ip6t_e
 			newinfo->hook_entry[h] = hook_entries[h];
 		if ((unsigned char *)e - base == underflows[h]) {
 			if (!check_underflow(e)) {
-				pr_err("Underflows must be unconditional and "
-				       "use the STANDARD target with "
-				       "ACCEPT/DROP\n");
+				pr_debug("Underflows must be unconditional and "
+					 "use the STANDARD target with "
+					 "ACCEPT/DROP\n");
 				return -EINVAL;
 			}
 			newinfo->underflow[h] = underflows[h];
@@ -1321,55 +1335,16 @@ do_add_counters(struct net *net, const v
 	unsigned int i;
 	struct xt_counters_info tmp;
 	struct xt_counters *paddc;
-	unsigned int num_counters;
-	char *name;
-	int size;
-	void *ptmp;
 	struct xt_table *t;
 	const struct xt_table_info *private;
 	int ret = 0;
 	struct ip6t_entry *iter;
 	unsigned int addend;
-#ifdef CONFIG_COMPAT
-	struct compat_xt_counters_info compat_tmp;
-
-	if (compat) {
-		ptmp = &compat_tmp;
-		size = sizeof(struct compat_xt_counters_info);
-	} else
-#endif
-	{
-		ptmp = &tmp;
-		size = sizeof(struct xt_counters_info);
-	}
-
-	if (copy_from_user(ptmp, user, size) != 0)
-		return -EFAULT;
-
-#ifdef CONFIG_COMPAT
-	if (compat) {
-		num_counters = compat_tmp.num_counters;
-		name = compat_tmp.name;
-	} else
-#endif
-	{
-		num_counters = tmp.num_counters;
-		name = tmp.name;
-	}
-
-	if (len != size + num_counters * sizeof(struct xt_counters))
-		return -EINVAL;
-
-	paddc = vmalloc(len - size);
-	if (!paddc)
-		return -ENOMEM;
 
-	if (copy_from_user(paddc, user + size, len - size) != 0) {
-		ret = -EFAULT;
-		goto free;
-	}
-
-	t = xt_find_table_lock(net, AF_INET6, name);
+	paddc = xt_copy_counters_from_user(user, len, &tmp, compat);
+	if (IS_ERR(paddc))
+		return PTR_ERR(paddc);
+	t = xt_find_table_lock(net, AF_INET6, tmp.name);
 	if (IS_ERR_OR_NULL(t)) {
 		ret = t ? PTR_ERR(t) : -ENOENT;
 		goto free;
@@ -1377,7 +1352,7 @@ do_add_counters(struct net *net, const v
 
 	local_bh_disable();
 	private = t->private;
-	if (private->number != num_counters) {
+	if (private->number != tmp.num_counters) {
 		ret = -EINVAL;
 		goto unlock_up_free;
 	}
@@ -1456,7 +1431,6 @@ compat_copy_entry_to_user(struct ip6t_en
 
 static int
 compat_find_calc_match(struct xt_entry_match *m,
-		       const char *name,
 		       const struct ip6t_ip6 *ipv6,
 		       int *size)
 {
@@ -1491,21 +1465,19 @@ check_compat_entry_size_and_hooks(struct
 				  struct xt_table_info *newinfo,
 				  unsigned int *size,
 				  const unsigned char *base,
-				  const unsigned char *limit,
-				  const unsigned int *hook_entries,
-				  const unsigned int *underflows,
-				  const char *name)
+				  const unsigned char *limit)
 {
 	struct xt_entry_match *ematch;
 	struct xt_entry_target *t;
 	struct xt_target *target;
 	unsigned int entry_offset;
 	unsigned int j;
-	int ret, off, h;
+	int ret, off;
 
 	duprintf("check_compat_entry_size_and_hooks %p\n", e);
 	if ((unsigned long)e % __alignof__(struct compat_ip6t_entry) != 0 ||
-	    (unsigned char *)e + sizeof(struct compat_ip6t_entry) >= limit) {
+	    (unsigned char *)e + sizeof(struct compat_ip6t_entry) >= limit ||
+	    (unsigned char *)e + e->next_offset > limit) {
 		duprintf("Bad offset %p, limit = %p\n", e, limit);
 		return -EINVAL;
 	}
@@ -1517,8 +1489,11 @@ check_compat_entry_size_and_hooks(struct
 		return -EINVAL;
 	}
 
-	/* For purposes of check_entry casting the compat entry is fine */
-	ret = check_entry((struct ip6t_entry *)e, name);
+	if (!ip6_checkentry(&e->ipv6))
+		return -EINVAL;
+
+	ret = xt_compat_check_entry_offsets(e, e->elems,
+					    e->target_offset, e->next_offset);
 	if (ret)
 		return ret;
 
@@ -1526,7 +1501,7 @@ check_compat_entry_size_and_hooks(struct
 	entry_offset = (void *)e - (void *)base;
 	j = 0;
 	xt_ematch_foreach(ematch, e) {
-		ret = compat_find_calc_match(ematch, name, &e->ipv6, &off);
+		ret = compat_find_calc_match(ematch, &e->ipv6, &off);
 		if (ret != 0)
 			goto release_matches;
 		++j;
@@ -1549,17 +1524,6 @@ check_compat_entry_size_and_hooks(struct
 	if (ret)
 		goto out;
 
-	/* Check hooks & underflows */
-	for (h = 0; h < NF_INET_NUMHOOKS; h++) {
-		if ((unsigned char *)e - base == hook_entries[h])
-			newinfo->hook_entry[h] = hook_entries[h];
-		if ((unsigned char *)e - base == underflows[h])
-			newinfo->underflow[h] = underflows[h];
-	}
-
-	/* Clear counters and comefrom */
-	memset(&e->counters, 0, sizeof(e->counters));
-	e->comefrom = 0;
 	return 0;
 
 out:
@@ -1573,18 +1537,17 @@ release_matches:
 	return ret;
 }
 
-static int
+static void
 compat_copy_entry_from_user(struct compat_ip6t_entry *e, void **dstptr,
-			    unsigned int *size, const char *name,
+			    unsigned int *size,
 			    struct xt_table_info *newinfo, unsigned char *base)
 {
 	struct xt_entry_target *t;
 	struct ip6t_entry *de;
 	unsigned int origsize;
-	int ret, h;
+	int h;
 	struct xt_entry_match *ematch;
 
-	ret = 0;
 	origsize = *size;
 	de = (struct ip6t_entry *)*dstptr;
 	memcpy(de, e, sizeof(struct ip6t_entry));
@@ -1593,11 +1556,9 @@ compat_copy_entry_from_user(struct compa
 	*dstptr += sizeof(struct ip6t_entry);
 	*size += sizeof(struct ip6t_entry) - sizeof(struct compat_ip6t_entry);
 
-	xt_ematch_foreach(ematch, e) {
-		ret = xt_compat_match_from_user(ematch, dstptr, size);
-		if (ret != 0)
-			return ret;
-	}
+	xt_ematch_foreach(ematch, e)
+		xt_compat_match_from_user(ematch, dstptr, size);
+
 	de->target_offset = e->target_offset - (origsize - *size);
 	t = compat_ip6t_get_target(e);
 	xt_compat_target_from_user(t, dstptr, size);
@@ -1609,183 +1570,83 @@ compat_copy_entry_from_user(struct compa
 		if ((unsigned char *)de - base < newinfo->underflow[h])
 			newinfo->underflow[h] -= origsize - *size;
 	}
-	return ret;
-}
-
-static int compat_check_entry(struct ip6t_entry *e, struct net *net,
-			      const char *name)
-{
-	unsigned int j;
-	int ret = 0;
-	struct xt_mtchk_param mtpar;
-	struct xt_entry_match *ematch;
-
-	e->counters.pcnt = xt_percpu_counter_alloc();
-	if (IS_ERR_VALUE(e->counters.pcnt))
-		return -ENOMEM;
-	j = 0;
-	mtpar.net	= net;
-	mtpar.table     = name;
-	mtpar.entryinfo = &e->ipv6;
-	mtpar.hook_mask = e->comefrom;
-	mtpar.family    = NFPROTO_IPV6;
-	xt_ematch_foreach(ematch, e) {
-		ret = check_match(ematch, &mtpar);
-		if (ret != 0)
-			goto cleanup_matches;
-		++j;
-	}
-
-	ret = check_target(e, net, name);
-	if (ret)
-		goto cleanup_matches;
-	return 0;
-
- cleanup_matches:
-	xt_ematch_foreach(ematch, e) {
-		if (j-- == 0)
-			break;
-		cleanup_match(ematch, net);
-	}
-
-	xt_percpu_counter_free(e->counters.pcnt);
-
-	return ret;
 }
 
 static int
 translate_compat_table(struct net *net,
-		       const char *name,
-		       unsigned int valid_hooks,
 		       struct xt_table_info **pinfo,
 		       void **pentry0,
-		       unsigned int total_size,
-		       unsigned int number,
-		       unsigned int *hook_entries,
-		       unsigned int *underflows)
+		       const struct compat_ip6t_replace *compatr)
 {
 	unsigned int i, j;
 	struct xt_table_info *newinfo, *info;
 	void *pos, *entry0, *entry1;
 	struct compat_ip6t_entry *iter0;
-	struct ip6t_entry *iter1;
+	struct ip6t_replace repl;
 	unsigned int size;
 	int ret = 0;
 
 	info = *pinfo;
 	entry0 = *pentry0;
-	size = total_size;
-	info->number = number;
-
-	/* Init all hooks to impossible value. */
-	for (i = 0; i < NF_INET_NUMHOOKS; i++) {
-		info->hook_entry[i] = 0xFFFFFFFF;
-		info->underflow[i] = 0xFFFFFFFF;
-	}
+	size = compatr->size;
+	info->number = compatr->num_entries;
 
 	duprintf("translate_compat_table: size %u\n", info->size);
 	j = 0;
 	xt_compat_lock(AF_INET6);
-	xt_compat_init_offsets(AF_INET6, number);
+	xt_compat_init_offsets(AF_INET6, compatr->num_entries);
 	/* Walk through entries, checking offsets. */
-	xt_entry_foreach(iter0, entry0, total_size) {
+	xt_entry_foreach(iter0, entry0, compatr->size) {
 		ret = check_compat_entry_size_and_hooks(iter0, info, &size,
 							entry0,
-							entry0 + total_size,
-							hook_entries,
-							underflows,
-							name);
+							entry0 + compatr->size);
 		if (ret != 0)
 			goto out_unlock;
 		++j;
 	}
 
 	ret = -EINVAL;
-	if (j != number) {
+	if (j != compatr->num_entries) {
 		duprintf("translate_compat_table: %u not %u entries\n",
-			 j, number);
+			 j, compatr->num_entries);
 		goto out_unlock;
 	}
 
-	/* Check hooks all assigned */
-	for (i = 0; i < NF_INET_NUMHOOKS; i++) {
-		/* Only hooks which are valid */
-		if (!(valid_hooks & (1 << i)))
-			continue;
-		if (info->hook_entry[i] == 0xFFFFFFFF) {
-			duprintf("Invalid hook entry %u %u\n",
-				 i, hook_entries[i]);
-			goto out_unlock;
-		}
-		if (info->underflow[i] == 0xFFFFFFFF) {
-			duprintf("Invalid underflow %u %u\n",
-				 i, underflows[i]);
-			goto out_unlock;
-		}
-	}
-
 	ret = -ENOMEM;
 	newinfo = xt_alloc_table_info(size);
 	if (!newinfo)
 		goto out_unlock;
 
-	newinfo->number = number;
+	newinfo->number = compatr->num_entries;
 	for (i = 0; i < NF_INET_NUMHOOKS; i++) {
-		newinfo->hook_entry[i] = info->hook_entry[i];
-		newinfo->underflow[i] = info->underflow[i];
+		newinfo->hook_entry[i] = compatr->hook_entry[i];
+		newinfo->underflow[i] = compatr->underflow[i];
 	}
 	entry1 = newinfo->entries;
 	pos = entry1;
-	size = total_size;
-	xt_entry_foreach(iter0, entry0, total_size) {
-		ret = compat_copy_entry_from_user(iter0, &pos, &size,
-						  name, newinfo, entry1);
-		if (ret != 0)
-			break;
-	}
+	size = compatr->size;
+	xt_entry_foreach(iter0, entry0, compatr->size)
+		compat_copy_entry_from_user(iter0, &pos, &size,
+					    newinfo, entry1);
+
+	/* all module references in entry0 are now gone. */
 	xt_compat_flush_offsets(AF_INET6);
 	xt_compat_unlock(AF_INET6);
-	if (ret)
-		goto free_newinfo;
 
-	ret = -ELOOP;
-	if (!mark_source_chains(newinfo, valid_hooks, entry1))
-		goto free_newinfo;
+	memcpy(&repl, compatr, sizeof(*compatr));
 
-	i = 0;
-	xt_entry_foreach(iter1, entry1, newinfo->size) {
-		ret = compat_check_entry(iter1, net, name);
-		if (ret != 0)
-			break;
-		++i;
-		if (strcmp(ip6t_get_target(iter1)->u.user.name,
-		    XT_ERROR_TARGET) == 0)
-			++newinfo->stacksize;
-	}
-	if (ret) {
-		/*
-		 * The first i matches need cleanup_entry (calls ->destroy)
-		 * because they had called ->check already. The other j-i
-		 * entries need only release.
-		 */
-		int skip = i;
-		j -= i;
-		xt_entry_foreach(iter0, entry0, newinfo->size) {
-			if (skip-- > 0)
-				continue;
-			if (j-- == 0)
-				break;
-			compat_release_entry(iter0);
-		}
-		xt_entry_foreach(iter1, entry1, newinfo->size) {
-			if (i-- == 0)
-				break;
-			cleanup_entry(iter1, net);
-		}
-		xt_free_table_info(newinfo);
-		return ret;
+	for (i = 0; i < NF_INET_NUMHOOKS; i++) {
+		repl.hook_entry[i] = newinfo->hook_entry[i];
+		repl.underflow[i] = newinfo->underflow[i];
 	}
 
+	repl.num_counters = 0;
+	repl.counters = NULL;
+	repl.size = newinfo->size;
+	ret = translate_table(net, newinfo, entry1, &repl);
+	if (ret)
+		goto free_newinfo;
+
 	*pinfo = newinfo;
 	*pentry0 = entry1;
 	xt_free_table_info(info);
@@ -1793,17 +1654,16 @@ translate_compat_table(struct net *net,
 
 free_newinfo:
 	xt_free_table_info(newinfo);
-out:
-	xt_entry_foreach(iter0, entry0, total_size) {
+	return ret;
+out_unlock:
+	xt_compat_flush_offsets(AF_INET6);
+	xt_compat_unlock(AF_INET6);
+	xt_entry_foreach(iter0, entry0, compatr->size) {
 		if (j-- == 0)
 			break;
 		compat_release_entry(iter0);
 	}
 	return ret;
-out_unlock:
-	xt_compat_flush_offsets(AF_INET6);
-	xt_compat_unlock(AF_INET6);
-	goto out;
 }
 
 static int
@@ -1839,10 +1699,7 @@ compat_do_replace(struct net *net, void
 		goto free_newinfo;
 	}
 
-	ret = translate_compat_table(net, tmp.name, tmp.valid_hooks,
-				     &newinfo, &loc_cpu_entry, tmp.size,
-				     tmp.num_entries, tmp.hook_entry,
-				     tmp.underflow);
+	ret = translate_compat_table(net, &newinfo, &loc_cpu_entry, &tmp);
 	if (ret != 0)
 		goto free_newinfo;
 
--- zfcpdump-kernel-4.4.orig/net/ipv6/ping.c
+++ zfcpdump-kernel-4.4/net/ipv6/ping.c
@@ -150,8 +150,10 @@ int ping_v6_sendmsg(struct sock *sk, str
 	rt = (struct rt6_info *) dst;
 
 	np = inet6_sk(sk);
-	if (!np)
-		return -EBADF;
+	if (!np) {
+		err = -EBADF;
+		goto dst_err_out;
+	}
 
 	if (!fl6.flowi6_oif && ipv6_addr_is_multicast(&fl6.daddr))
 		fl6.flowi6_oif = np->mcast_oif;
@@ -186,6 +188,9 @@ int ping_v6_sendmsg(struct sock *sk, str
 	}
 	release_sock(sk);
 
+dst_err_out:
+	dst_release(dst);
+
 	if (err)
 		return err;
 
--- zfcpdump-kernel-4.4.orig/net/ipv6/reassembly.c
+++ zfcpdump-kernel-4.4/net/ipv6/reassembly.c
@@ -496,10 +496,8 @@ static int ip6_frag_reasm(struct frag_qu
 	IP6CB(head)->flags |= IP6SKB_FRAGMENTED;
 
 	/* Yes, and fold redundant checksum back. 8) */
-	if (head->ip_summed == CHECKSUM_COMPLETE)
-		head->csum = csum_partial(skb_network_header(head),
-					  skb_network_header_len(head),
-					  head->csum);
+	skb_postpush_rcsum(head, skb_network_header(head),
+			   skb_network_header_len(head));
 
 	rcu_read_lock();
 	IP6_INC_STATS_BH(net, __in6_dev_get(dev), IPSTATS_MIB_REASMOKS);
--- zfcpdump-kernel-4.4.orig/net/ipv6/route.c
+++ zfcpdump-kernel-4.4/net/ipv6/route.c
@@ -1174,11 +1174,10 @@ static struct rt6_info *ip6_pol_route_ou
 	return ip6_pol_route(net, table, fl6->flowi6_oif, fl6, flags);
 }
 
-struct dst_entry *ip6_route_output(struct net *net, const struct sock *sk,
-				    struct flowi6 *fl6)
+struct dst_entry *ip6_route_output_flags(struct net *net, const struct sock *sk,
+					 struct flowi6 *fl6, int flags)
 {
 	struct dst_entry *dst;
-	int flags = 0;
 	bool any_src;
 
 	dst = l3mdev_rt6_dst_by_oif(net, fl6);
@@ -1199,7 +1198,7 @@ struct dst_entry *ip6_route_output(struc
 
 	return fib6_rule_lookup(net, fl6, flags, ip6_pol_route_output);
 }
-EXPORT_SYMBOL(ip6_route_output);
+EXPORT_SYMBOL_GPL(ip6_route_output_flags);
 
 struct dst_entry *ip6_blackhole_route(struct net *net, struct dst_entry *dst_orig)
 {
@@ -1728,6 +1727,8 @@ static int ip6_convert_metrics(struct mx
 		} else {
 			val = nla_get_u32(nla);
 		}
+		if (type == RTAX_HOPLIMIT && val > 255)
+			val = 255;
 		if (type == RTAX_FEATURES && (val & ~RTAX_FEATURE_MASK))
 			goto err;
 
--- zfcpdump-kernel-4.4.orig/net/ipv6/sit.c
+++ zfcpdump-kernel-4.4/net/ipv6/sit.c
@@ -560,13 +560,13 @@ static int ipip6_err(struct sk_buff *skb
 
 	if (type == ICMP_DEST_UNREACH && code == ICMP_FRAG_NEEDED) {
 		ipv4_update_pmtu(skb, dev_net(skb->dev), info,
-				 t->parms.link, 0, IPPROTO_IPV6, 0);
+				 t->parms.link, 0, iph->protocol, 0);
 		err = 0;
 		goto out;
 	}
 	if (type == ICMP_REDIRECT) {
 		ipv4_redirect(skb, dev_net(skb->dev), t->parms.link, 0,
-			      IPPROTO_IPV6, 0);
+			      iph->protocol, 0);
 		err = 0;
 		goto out;
 	}
@@ -681,14 +681,15 @@ static int ipip6_rcv(struct sk_buff *skb
 		skb->mac_header = skb->network_header;
 		skb_reset_network_header(skb);
 		IPCB(skb)->flags = 0;
-		skb->protocol = htons(ETH_P_IPV6);
+		skb->dev = tunnel->dev;
 
 		if (packet_is_spoofed(skb, iph, tunnel)) {
 			tunnel->dev->stats.rx_errors++;
 			goto out;
 		}
 
-		__skb_tunnel_rx(skb, tunnel->dev, tunnel->net);
+		if (iptunnel_pull_header(skb, 0, htons(ETH_P_IPV6)))
+			goto out;
 
 		err = IP_ECN_decapsulate(iph, skb);
 		if (unlikely(err)) {
--- zfcpdump-kernel-4.4.orig/net/ipv6/tcp_ipv6.c
+++ zfcpdump-kernel-4.4/net/ipv6/tcp_ipv6.c
@@ -328,6 +328,7 @@ static void tcp_v6_err(struct sk_buff *s
 	struct tcp_sock *tp;
 	__u32 seq, snd_una;
 	struct sock *sk;
+	bool fatal;
 	int err;
 
 	sk = __inet6_lookup_established(net, &tcp_hashinfo,
@@ -346,8 +347,9 @@ static void tcp_v6_err(struct sk_buff *s
 		return;
 	}
 	seq = ntohl(th->seq);
+	fatal = icmpv6_err_convert(type, code, &err);
 	if (sk->sk_state == TCP_NEW_SYN_RECV)
-		return tcp_req_err(sk, seq);
+		return tcp_req_err(sk, seq, fatal);
 
 	bh_lock_sock(sk);
 	if (sock_owned_by_user(sk) && type != ICMPV6_PKT_TOOBIG)
@@ -401,7 +403,6 @@ static void tcp_v6_err(struct sk_buff *s
 		goto out;
 	}
 
-	icmpv6_err_convert(type, code, &err);
 
 	/* Might be for an request_sock */
 	switch (sk->sk_state) {
@@ -462,8 +463,10 @@ static int tcp_v6_send_synack(const stru
 		if (np->repflow && ireq->pktopts)
 			fl6->flowlabel = ip6_flowlabel(ipv6_hdr(ireq->pktopts));
 
+		rcu_read_lock();
 		err = ip6_xmit(sk, skb, fl6, rcu_dereference(np->opt),
 			       np->tclass);
+		rcu_read_unlock();
 		err = net_xmit_eval(err);
 	}
 
@@ -929,9 +932,15 @@ static void tcp_v6_reqsk_send_ack(const
 	/* sk->sk_state == TCP_LISTEN -> for regular TCP_SYN_RECV
 	 * sk->sk_state == TCP_SYN_RECV -> for Fast Open.
 	 */
+	/* RFC 7323 2.3
+	 * The window field (SEG.WND) of every outgoing segment, with the
+	 * exception of <SYN> segments, MUST be right-shifted by
+	 * Rcv.Wind.Shift bits:
+	 */
 	tcp_v6_send_ack(sk, skb, (sk->sk_state == TCP_LISTEN) ?
 			tcp_rsk(req)->snt_isn + 1 : tcp_sk(sk)->snd_nxt,
-			tcp_rsk(req)->rcv_nxt, req->rsk_rcv_wnd,
+			tcp_rsk(req)->rcv_nxt,
+			req->rsk_rcv_wnd >> inet_rsk(req)->rcv_wscale,
 			tcp_time_stamp, req->ts_recent, sk->sk_bound_dev_if,
 			tcp_v6_md5_do_lookup(sk, &ipv6_hdr(skb)->daddr),
 			0, 0);
@@ -1385,7 +1394,7 @@ process:
 
 	if (sk->sk_state == TCP_NEW_SYN_RECV) {
 		struct request_sock *req = inet_reqsk(sk);
-		struct sock *nsk = NULL;
+		struct sock *nsk;
 
 		sk = req->rsk_listener;
 		tcp_v6_fill_cb(skb, hdr, th);
@@ -1393,24 +1402,24 @@ process:
 			reqsk_put(req);
 			goto discard_it;
 		}
-		if (likely(sk->sk_state == TCP_LISTEN)) {
-			nsk = tcp_check_req(sk, skb, req, false);
-		} else {
+		if (unlikely(sk->sk_state != TCP_LISTEN)) {
 			inet_csk_reqsk_queue_drop_and_put(sk, req);
 			goto lookup;
 		}
+		sock_hold(sk);
+		nsk = tcp_check_req(sk, skb, req, false);
 		if (!nsk) {
 			reqsk_put(req);
-			goto discard_it;
+			goto discard_and_relse;
 		}
 		if (nsk == sk) {
-			sock_hold(sk);
 			reqsk_put(req);
 			tcp_v6_restore_cb(skb);
 		} else if (tcp_child_process(sk, nsk, skb)) {
 			tcp_v6_send_reset(nsk, skb);
-			goto discard_it;
+			goto discard_and_relse;
 		} else {
+			sock_put(sk);
 			return 0;
 		}
 	}
@@ -1703,7 +1712,9 @@ static void get_tcp6_sock(struct seq_fil
 	destp = ntohs(inet->inet_dport);
 	srcp  = ntohs(inet->inet_sport);
 
-	if (icsk->icsk_pending == ICSK_TIME_RETRANS) {
+	if (icsk->icsk_pending == ICSK_TIME_RETRANS ||
+	    icsk->icsk_pending == ICSK_TIME_EARLY_RETRANS ||
+	    icsk->icsk_pending == ICSK_TIME_LOSS_PROBE) {
 		timer_active	= 1;
 		timer_expires	= icsk->icsk_timeout;
 	} else if (icsk->icsk_pending == ICSK_TIME_PROBE0) {
--- zfcpdump-kernel-4.4.orig/net/ipv6/udp.c
+++ zfcpdump-kernel-4.4/net/ipv6/udp.c
@@ -402,6 +402,7 @@ int udpv6_recvmsg(struct sock *sk, struc
 	int peeked, off = 0;
 	int err;
 	int is_udplite = IS_UDPLITE(sk);
+	bool checksum_valid = false;
 	int is_udp4;
 	bool slow;
 
@@ -433,11 +434,12 @@ try_again:
 	 */
 
 	if (copied < ulen || UDP_SKB_CB(skb)->partial_cov) {
-		if (udp_lib_checksum_complete(skb))
+		checksum_valid = !udp_lib_checksum_complete(skb);
+		if (!checksum_valid)
 			goto csum_copy_err;
 	}
 
-	if (skb_csum_unnecessary(skb))
+	if (checksum_valid || skb_csum_unnecessary(skb))
 		err = skb_copy_datagram_msg(skb, sizeof(struct udphdr),
 					    msg, copied);
 	else {
@@ -647,7 +649,7 @@ int udpv6_queue_rcv_skb(struct sock *sk,
 
 		/* if we're overly short, let UDP handle it */
 		encap_rcv = ACCESS_ONCE(up->encap_rcv);
-		if (skb->len > sizeof(struct udphdr) && encap_rcv) {
+		if (encap_rcv) {
 			int ret;
 
 			/* Verify checksum before giving to encap */
@@ -837,8 +839,8 @@ start_lookup:
 		flush_stack(stack, count, skb, count - 1);
 	} else {
 		if (!inner_flushed)
-			UDP_INC_STATS_BH(net, UDP_MIB_IGNOREDMULTI,
-					 proto == IPPROTO_UDPLITE);
+			UDP6_INC_STATS_BH(net, UDP_MIB_IGNOREDMULTI,
+					  proto == IPPROTO_UDPLITE);
 		consume_skb(skb);
 	}
 	return 0;
@@ -916,11 +918,9 @@ int __udp6_lib_rcv(struct sk_buff *skb,
 		ret = udpv6_queue_rcv_skb(sk, skb);
 		sock_put(sk);
 
-		/* a return value > 0 means to resubmit the input, but
-		 * it wants the return to be -protocol, or 0
-		 */
+		/* a return value > 0 means to resubmit the input */
 		if (ret > 0)
-			return -ret;
+			return ret;
 
 		return 0;
 	}
--- zfcpdump-kernel-4.4.orig/net/ipv6/xfrm6_mode_tunnel.c
+++ zfcpdump-kernel-4.4/net/ipv6/xfrm6_mode_tunnel.c
@@ -23,7 +23,7 @@ static inline void ipip6_ecn_decapsulate
 	struct ipv6hdr *inner_iph = ipipv6_hdr(skb);
 
 	if (INET_ECN_is_ce(XFRM_MODE_SKB_CB(skb)->tos))
-		IP6_ECN_set_ce(inner_iph);
+		IP6_ECN_set_ce(skb, inner_iph);
 }
 
 /* Add encapsulation header.
--- zfcpdump-kernel-4.4.orig/net/irda/af_irda.c
+++ zfcpdump-kernel-4.4/net/irda/af_irda.c
@@ -1024,8 +1024,11 @@ static int irda_connect(struct socket *s
 	}
 
 	/* Check if we have opened a local TSAP */
-	if (!self->tsap)
-		irda_open_tsap(self, LSAP_ANY, addr->sir_name);
+	if (!self->tsap) {
+		err = irda_open_tsap(self, LSAP_ANY, addr->sir_name);
+		if (err)
+			goto out;
+	}
 
 	/* Move to connecting socket, start sending Connect Requests */
 	sock->state = SS_CONNECTING;
--- zfcpdump-kernel-4.4.orig/net/irda/iriap.c
+++ zfcpdump-kernel-4.4/net/irda/iriap.c
@@ -185,8 +185,12 @@ struct iriap_cb *iriap_open(__u8 slsap_s
 
 	self->magic = IAS_MAGIC;
 	self->mode = mode;
-	if (mode == IAS_CLIENT)
-		iriap_register_lsap(self, slsap_sel, mode);
+	if (mode == IAS_CLIENT) {
+		if (iriap_register_lsap(self, slsap_sel, mode)) {
+			kfree(self);
+			return NULL;
+		}
+	}
 
 	self->confirm = callback;
 	self->priv = priv;
--- zfcpdump-kernel-4.4.orig/net/iucv/af_iucv.c
+++ zfcpdump-kernel-4.4/net/iucv/af_iucv.c
@@ -708,6 +708,9 @@ static int iucv_sock_bind(struct socket
 	if (!addr || addr->sa_family != AF_IUCV)
 		return -EINVAL;
 
+	if (addr_len < sizeof(struct sockaddr_iucv))
+		return -EINVAL;
+
 	lock_sock(sk);
 	if (sk->sk_state != IUCV_OPEN) {
 		err = -EBADFD;
--- zfcpdump-kernel-4.4.orig/net/l2tp/l2tp_core.c
+++ zfcpdump-kernel-4.4/net/l2tp/l2tp_core.c
@@ -1581,7 +1581,7 @@ int l2tp_tunnel_create(struct net *net,
 	/* Mark socket as an encapsulation socket. See net/ipv4/udp.c */
 	tunnel->encap = encap;
 	if (encap == L2TP_ENCAPTYPE_UDP) {
-		struct udp_tunnel_sock_cfg udp_cfg;
+		struct udp_tunnel_sock_cfg udp_cfg = { };
 
 		udp_cfg.sk_user_data = tunnel;
 		udp_cfg.encap_type = UDP_ENCAP_L2TPINUDP;
--- zfcpdump-kernel-4.4.orig/net/l2tp/l2tp_ip.c
+++ zfcpdump-kernel-4.4/net/l2tp/l2tp_ip.c
@@ -123,12 +123,11 @@ static int l2tp_ip_recv(struct sk_buff *
 	struct l2tp_tunnel *tunnel = NULL;
 	int length;
 
-	/* Point to L2TP header */
-	optr = ptr = skb->data;
-
 	if (!pskb_may_pull(skb, 4))
 		goto discard;
 
+	/* Point to L2TP header */
+	optr = ptr = skb->data;
 	session_id = ntohl(*((__be32 *) ptr));
 	ptr += 4;
 
@@ -156,6 +155,9 @@ static int l2tp_ip_recv(struct sk_buff *
 		if (!pskb_may_pull(skb, length))
 			goto discard;
 
+		/* Point to L2TP header */
+		optr = ptr = skb->data;
+		ptr += 4;
 		pr_debug("%s: ip recv\n", tunnel->name);
 		print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, ptr, length);
 	}
--- zfcpdump-kernel-4.4.orig/net/l2tp/l2tp_ip6.c
+++ zfcpdump-kernel-4.4/net/l2tp/l2tp_ip6.c
@@ -135,12 +135,11 @@ static int l2tp_ip6_recv(struct sk_buff
 	struct l2tp_tunnel *tunnel = NULL;
 	int length;
 
-	/* Point to L2TP header */
-	optr = ptr = skb->data;
-
 	if (!pskb_may_pull(skb, 4))
 		goto discard;
 
+	/* Point to L2TP header */
+	optr = ptr = skb->data;
 	session_id = ntohl(*((__be32 *) ptr));
 	ptr += 4;
 
@@ -168,6 +167,9 @@ static int l2tp_ip6_recv(struct sk_buff
 		if (!pskb_may_pull(skb, length))
 			goto discard;
 
+		/* Point to L2TP header */
+		optr = ptr = skb->data;
+		ptr += 4;
 		pr_debug("%s: ip recv\n", tunnel->name);
 		print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, ptr, length);
 	}
--- zfcpdump-kernel-4.4.orig/net/l2tp/l2tp_netlink.c
+++ zfcpdump-kernel-4.4/net/l2tp/l2tp_netlink.c
@@ -124,8 +124,13 @@ static int l2tp_tunnel_notify(struct gen
 	ret = l2tp_nl_tunnel_send(msg, info->snd_portid, info->snd_seq,
 				  NLM_F_ACK, tunnel, cmd);
 
-	if (ret >= 0)
-		return genlmsg_multicast_allns(family, msg, 0,	0, GFP_ATOMIC);
+	if (ret >= 0) {
+		ret = genlmsg_multicast_allns(family, msg, 0, 0, GFP_ATOMIC);
+		/* We don't care if no one is listening */
+		if (ret == -ESRCH)
+			ret = 0;
+		return ret;
+	}
 
 	nlmsg_free(msg);
 
@@ -147,8 +152,13 @@ static int l2tp_session_notify(struct ge
 	ret = l2tp_nl_session_send(msg, info->snd_portid, info->snd_seq,
 				   NLM_F_ACK, session, cmd);
 
-	if (ret >= 0)
-		return genlmsg_multicast_allns(family, msg, 0,	0, GFP_ATOMIC);
+	if (ret >= 0) {
+		ret = genlmsg_multicast_allns(family, msg, 0, 0, GFP_ATOMIC);
+		/* We don't care if no one is listening */
+		if (ret == -ESRCH)
+			ret = 0;
+		return ret;
+	}
 
 	nlmsg_free(msg);
 
--- zfcpdump-kernel-4.4.orig/net/llc/af_llc.c
+++ zfcpdump-kernel-4.4/net/llc/af_llc.c
@@ -626,6 +626,7 @@ static void llc_cmsg_rcv(struct msghdr *
 	if (llc->cmsg_flags & LLC_CMSG_PKTINFO) {
 		struct llc_pktinfo info;
 
+		memset(&info, 0, sizeof(info));
 		info.lpi_ifindex = llc_sk(skb->sk)->dev->ifindex;
 		llc_pdu_decode_dsap(skb, &info.lpi_sap);
 		llc_pdu_decode_da(skb, info.lpi_mac);
--- zfcpdump-kernel-4.4.orig/net/mac80211/agg-rx.c
+++ zfcpdump-kernel-4.4/net/mac80211/agg-rx.c
@@ -291,7 +291,7 @@ void __ieee80211_start_rx_ba_session(str
 	}
 
 	/* prepare A-MPDU MLME for Rx aggregation */
-	tid_agg_rx = kmalloc(sizeof(struct tid_ampdu_rx), GFP_KERNEL);
+	tid_agg_rx = kzalloc(sizeof(*tid_agg_rx), GFP_KERNEL);
 	if (!tid_agg_rx)
 		goto end;
 
--- zfcpdump-kernel-4.4.orig/net/mac80211/cfg.c
+++ zfcpdump-kernel-4.4/net/mac80211/cfg.c
@@ -865,7 +865,7 @@ static int ieee80211_stop_ap(struct wiph
 
 	/* free all potentially still buffered bcast frames */
 	local->total_ps_buffered -= skb_queue_len(&sdata->u.ap.ps.bc_buf);
-	skb_queue_purge(&sdata->u.ap.ps.bc_buf);
+	ieee80211_purge_tx_queue(&local->hw, &sdata->u.ap.ps.bc_buf);
 
 	mutex_lock(&local->mtx);
 	ieee80211_vif_copy_chanctx_to_vlans(sdata, true);
--- zfcpdump-kernel-4.4.orig/net/mac80211/ibss.c
+++ zfcpdump-kernel-4.4/net/mac80211/ibss.c
@@ -7,6 +7,7 @@
  * Copyright 2007, Michael Wu <flamingice@sourmilk.net>
  * Copyright 2009, Johannes Berg <johannes@sipsolutions.net>
  * Copyright 2013-2014  Intel Mobile Communications GmbH
+ * Copyright(c) 2016 Intel Deutschland GmbH
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -1484,14 +1485,21 @@ static void ieee80211_sta_find_ibss(stru
 
 		sdata_info(sdata, "Trigger new scan to find an IBSS to join\n");
 
-		num = ieee80211_ibss_setup_scan_channels(local->hw.wiphy,
-							 &ifibss->chandef,
-							 channels,
-							 ARRAY_SIZE(channels));
 		scan_width = cfg80211_chandef_to_scan_width(&ifibss->chandef);
-		ieee80211_request_ibss_scan(sdata, ifibss->ssid,
-					    ifibss->ssid_len, channels, num,
-					    scan_width);
+
+		if (ifibss->fixed_channel) {
+			num = ieee80211_ibss_setup_scan_channels(local->hw.wiphy,
+								 &ifibss->chandef,
+								 channels,
+								 ARRAY_SIZE(channels));
+			ieee80211_request_ibss_scan(sdata, ifibss->ssid,
+						    ifibss->ssid_len, channels,
+						    num, scan_width);
+		} else {
+			ieee80211_request_ibss_scan(sdata, ifibss->ssid,
+						    ifibss->ssid_len, NULL,
+						    0, scan_width);
+		}
 	} else {
 		int interval = IEEE80211_SCAN_INTERVAL;
 
@@ -1732,7 +1740,6 @@ void ieee80211_ibss_notify_scan_complete
 		if (sdata->vif.type != NL80211_IFTYPE_ADHOC)
 			continue;
 		sdata->u.ibss.last_scan_completed = jiffies;
-		ieee80211_queue_work(&local->hw, &sdata->work);
 	}
 	mutex_unlock(&local->iflist_mtx);
 }
--- zfcpdump-kernel-4.4.orig/net/mac80211/ieee80211_i.h
+++ zfcpdump-kernel-4.4/net/mac80211/ieee80211_i.h
@@ -92,7 +92,7 @@ struct ieee80211_fragment_entry {
 	u16 extra_len;
 	u16 last_frag;
 	u8 rx_queue;
-	bool ccmp; /* Whether fragments were encrypted with CCMP */
+	bool check_sequential_pn; /* needed for CCMP/GCMP */
 	u8 last_pn[6]; /* PN of the last fragment if CCMP was used */
 };
 
--- zfcpdump-kernel-4.4.orig/net/mac80211/iface.c
+++ zfcpdump-kernel-4.4/net/mac80211/iface.c
@@ -977,7 +977,10 @@ static void ieee80211_do_stop(struct iee
 	if (sdata->vif.txq) {
 		struct txq_info *txqi = to_txq_info(sdata->vif.txq);
 
+		spin_lock_bh(&txqi->queue.lock);
 		ieee80211_purge_tx_queue(&local->hw, &txqi->queue);
+		spin_unlock_bh(&txqi->queue.lock);
+
 		atomic_set(&sdata->txqs_len[txqi->txq.ac], 0);
 	}
 
@@ -1747,7 +1750,7 @@ int ieee80211_if_add(struct ieee80211_lo
 
 		ret = dev_alloc_name(ndev, ndev->name);
 		if (ret < 0) {
-			free_netdev(ndev);
+			ieee80211_if_free(ndev);
 			return ret;
 		}
 
@@ -1833,7 +1836,7 @@ int ieee80211_if_add(struct ieee80211_lo
 
 		ret = register_netdevice(ndev);
 		if (ret) {
-			free_netdev(ndev);
+			ieee80211_if_free(ndev);
 			return ret;
 		}
 	}
--- zfcpdump-kernel-4.4.orig/net/mac80211/mesh.c
+++ zfcpdump-kernel-4.4/net/mac80211/mesh.c
@@ -151,19 +151,26 @@ u32 mesh_accept_plinks_update(struct iee
 void mesh_sta_cleanup(struct sta_info *sta)
 {
 	struct ieee80211_sub_if_data *sdata = sta->sdata;
-	u32 changed;
+	u32 changed = 0;
 
 	/*
 	 * maybe userspace handles peer allocation and peering, but in either
 	 * case the beacon is still generated by the kernel and we might need
 	 * an update.
 	 */
-	changed = mesh_accept_plinks_update(sdata);
+	if (sdata->u.mesh.user_mpm &&
+	    sta->mesh->plink_state == NL80211_PLINK_ESTAB)
+		changed |= mesh_plink_dec_estab_count(sdata);
+	changed |= mesh_accept_plinks_update(sdata);
 	if (!sdata->u.mesh.user_mpm) {
 		changed |= mesh_plink_deactivate(sta);
 		del_timer_sync(&sta->mesh->plink_timer);
 	}
 
+	/* make sure no readers can access nexthop sta from here on */
+	mesh_path_flush_by_nexthop(sta);
+	synchronize_net();
+
 	if (changed)
 		ieee80211_mbss_info_change_notify(sdata, changed);
 }
@@ -1370,17 +1377,6 @@ out:
 	sdata_unlock(sdata);
 }
 
-void ieee80211_mesh_notify_scan_completed(struct ieee80211_local *local)
-{
-	struct ieee80211_sub_if_data *sdata;
-
-	rcu_read_lock();
-	list_for_each_entry_rcu(sdata, &local->interfaces, list)
-		if (ieee80211_vif_is_mesh(&sdata->vif) &&
-		    ieee80211_sdata_running(sdata))
-			ieee80211_queue_work(&local->hw, &sdata->work);
-	rcu_read_unlock();
-}
 
 void ieee80211_mesh_init_sdata(struct ieee80211_sub_if_data *sdata)
 {
--- zfcpdump-kernel-4.4.orig/net/mac80211/mesh.h
+++ zfcpdump-kernel-4.4/net/mac80211/mesh.h
@@ -362,14 +362,10 @@ static inline bool mesh_path_sel_is_hwmp
 	return sdata->u.mesh.mesh_pp_id == IEEE80211_PATH_PROTOCOL_HWMP;
 }
 
-void ieee80211_mesh_notify_scan_completed(struct ieee80211_local *local);
-
 void mesh_path_flush_by_iface(struct ieee80211_sub_if_data *sdata);
 void mesh_sync_adjust_tbtt(struct ieee80211_sub_if_data *sdata);
 void ieee80211s_stop(void);
 #else
-static inline void
-ieee80211_mesh_notify_scan_completed(struct ieee80211_local *local) {}
 static inline bool mesh_path_sel_is_hwmp(struct ieee80211_sub_if_data *sdata)
 { return false; }
 static inline void mesh_path_flush_by_iface(struct ieee80211_sub_if_data *sdata)
--- zfcpdump-kernel-4.4.orig/net/mac80211/mlme.c
+++ zfcpdump-kernel-4.4/net/mac80211/mlme.c
@@ -4003,8 +4003,6 @@ static void ieee80211_restart_sta_timer(
 		if (!ieee80211_hw_check(&sdata->local->hw, CONNECTION_MONITOR))
 			ieee80211_queue_work(&sdata->local->hw,
 					     &sdata->u.mgd.monitor_work);
-		/* and do all the other regular work too */
-		ieee80211_queue_work(&sdata->local->hw, &sdata->work);
 	}
 }
 
--- zfcpdump-kernel-4.4.orig/net/mac80211/rc80211_minstrel.c
+++ zfcpdump-kernel-4.4/net/mac80211/rc80211_minstrel.c
@@ -711,7 +711,7 @@ static u32 minstrel_get_expected_through
 	 * computing cur_tp
 	 */
 	tmp_mrs = &mi->r[idx].stats;
-	tmp_cur_tp = minstrel_get_tp_avg(&mi->r[idx], tmp_mrs->prob_ewma);
+	tmp_cur_tp = minstrel_get_tp_avg(&mi->r[idx], tmp_mrs->prob_ewma) * 10;
 	tmp_cur_tp = tmp_cur_tp * 1200 * 8 / 1024;
 
 	return tmp_cur_tp;
--- zfcpdump-kernel-4.4.orig/net/mac80211/rc80211_minstrel_ht.c
+++ zfcpdump-kernel-4.4/net/mac80211/rc80211_minstrel_ht.c
@@ -691,7 +691,7 @@ minstrel_aggr_check(struct ieee80211_sta
 	if (likely(sta->ampdu_mlme.tid_tx[tid]))
 		return;
 
-	ieee80211_start_tx_ba_session(pubsta, tid, 5000);
+	ieee80211_start_tx_ba_session(pubsta, tid, 0);
 }
 
 static void
@@ -871,7 +871,7 @@ minstrel_ht_set_rate(struct minstrel_pri
 	 *  - if station is in dynamic SMPS (and streams > 1)
 	 *  - for fallback rates, to increase chances of getting through
 	 */
-	if (offset > 0 &&
+	if (offset > 0 ||
 	    (mi->sta->smps_mode == IEEE80211_SMPS_DYNAMIC &&
 	     group->streams > 1)) {
 		ratetbl->rate[offset].count = ratetbl->rate[offset].count_rts;
@@ -1334,7 +1334,8 @@ static u32 minstrel_ht_get_expected_thro
 	prob = mi->groups[i].rates[j].prob_ewma;
 
 	/* convert tp_avg from pkt per second in kbps */
-	tp_avg = minstrel_ht_get_tp_avg(mi, i, j, prob) * AVG_PKT_SIZE * 8 / 1024;
+	tp_avg = minstrel_ht_get_tp_avg(mi, i, j, prob) * 10;
+	tp_avg = tp_avg * AVG_PKT_SIZE * 8 / 1024;
 
 	return tp_avg;
 }
--- zfcpdump-kernel-4.4.orig/net/mac80211/rx.c
+++ zfcpdump-kernel-4.4/net/mac80211/rx.c
@@ -1754,7 +1754,7 @@ ieee80211_reassemble_add(struct ieee8021
 	entry->seq = seq;
 	entry->rx_queue = rx_queue;
 	entry->last_frag = frag;
-	entry->ccmp = 0;
+	entry->check_sequential_pn = false;
 	entry->extra_len = 0;
 
 	return entry;
@@ -1850,15 +1850,27 @@ ieee80211_rx_h_defragment(struct ieee802
 						 rx->seqno_idx, &(rx->skb));
 		if (rx->key &&
 		    (rx->key->conf.cipher == WLAN_CIPHER_SUITE_CCMP ||
-		     rx->key->conf.cipher == WLAN_CIPHER_SUITE_CCMP_256) &&
+		     rx->key->conf.cipher == WLAN_CIPHER_SUITE_CCMP_256 ||
+		     rx->key->conf.cipher == WLAN_CIPHER_SUITE_GCMP ||
+		     rx->key->conf.cipher == WLAN_CIPHER_SUITE_GCMP_256) &&
 		    ieee80211_has_protected(fc)) {
 			int queue = rx->security_idx;
-			/* Store CCMP PN so that we can verify that the next
-			 * fragment has a sequential PN value. */
-			entry->ccmp = 1;
+
+			/* Store CCMP/GCMP PN so that we can verify that the
+			 * next fragment has a sequential PN value.
+			 */
+			entry->check_sequential_pn = true;
 			memcpy(entry->last_pn,
 			       rx->key->u.ccmp.rx_pn[queue],
 			       IEEE80211_CCMP_PN_LEN);
+			BUILD_BUG_ON(offsetof(struct ieee80211_key,
+					      u.ccmp.rx_pn) !=
+				     offsetof(struct ieee80211_key,
+					      u.gcmp.rx_pn));
+			BUILD_BUG_ON(sizeof(rx->key->u.ccmp.rx_pn[queue]) !=
+				     sizeof(rx->key->u.gcmp.rx_pn[queue]));
+			BUILD_BUG_ON(IEEE80211_CCMP_PN_LEN !=
+				     IEEE80211_GCMP_PN_LEN);
 		}
 		return RX_QUEUED;
 	}
@@ -1873,15 +1885,21 @@ ieee80211_rx_h_defragment(struct ieee802
 		return RX_DROP_MONITOR;
 	}
 
-	/* Verify that MPDUs within one MSDU have sequential PN values.
-	 * (IEEE 802.11i, 8.3.3.4.5) */
-	if (entry->ccmp) {
+	/* "The receiver shall discard MSDUs and MMPDUs whose constituent
+	 *  MPDU PN values are not incrementing in steps of 1."
+	 * see IEEE P802.11-REVmc/D5.0, 12.5.3.4.4, item d (for CCMP)
+	 * and IEEE P802.11-REVmc/D5.0, 12.5.5.4.4, item d (for GCMP)
+	 */
+	if (entry->check_sequential_pn) {
 		int i;
 		u8 pn[IEEE80211_CCMP_PN_LEN], *rpn;
 		int queue;
+
 		if (!rx->key ||
 		    (rx->key->conf.cipher != WLAN_CIPHER_SUITE_CCMP &&
-		     rx->key->conf.cipher != WLAN_CIPHER_SUITE_CCMP_256))
+		     rx->key->conf.cipher != WLAN_CIPHER_SUITE_CCMP_256 &&
+		     rx->key->conf.cipher != WLAN_CIPHER_SUITE_GCMP &&
+		     rx->key->conf.cipher != WLAN_CIPHER_SUITE_GCMP_256))
 			return RX_DROP_UNUSABLE;
 		memcpy(pn, entry->last_pn, IEEE80211_CCMP_PN_LEN);
 		for (i = IEEE80211_CCMP_PN_LEN - 1; i >= 0; i--) {
@@ -2232,7 +2250,7 @@ ieee80211_rx_h_mesh_fwding(struct ieee80
 	struct ieee80211_local *local = rx->local;
 	struct ieee80211_sub_if_data *sdata = rx->sdata;
 	struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
-	u16 q, hdrlen;
+	u16 ac, q, hdrlen;
 
 	hdr = (struct ieee80211_hdr *) skb->data;
 	hdrlen = ieee80211_hdrlen(hdr->frame_control);
@@ -2301,7 +2319,8 @@ ieee80211_rx_h_mesh_fwding(struct ieee80
 	    ether_addr_equal(sdata->vif.addr, hdr->addr3))
 		return RX_CONTINUE;
 
-	q = ieee80211_select_queue_80211(sdata, skb, hdr);
+	ac = ieee80211_select_queue_80211(sdata, skb, hdr);
+	q = sdata->vif.hw_queue[ac];
 	if (ieee80211_queue_stopped(&local->hw, q)) {
 		IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, dropped_frames_congestion);
 		return RX_DROP_MONITOR;
@@ -3367,6 +3386,7 @@ static bool ieee80211_accept_frame(struc
 				return false;
 			/* ignore action frames to TDLS-peers */
 			if (ieee80211_is_action(hdr->frame_control) &&
+			    !is_broadcast_ether_addr(bssid) &&
 			    !ether_addr_equal(bssid, hdr->addr1))
 				return false;
 		}
--- zfcpdump-kernel-4.4.orig/net/mac80211/scan.c
+++ zfcpdump-kernel-4.4/net/mac80211/scan.c
@@ -314,6 +314,7 @@ static void __ieee80211_scan_completed(s
 	bool was_scanning = local->scanning;
 	struct cfg80211_scan_request *scan_req;
 	struct ieee80211_sub_if_data *scan_sdata;
+	struct ieee80211_sub_if_data *sdata;
 
 	lockdep_assert_held(&local->mtx);
 
@@ -373,7 +374,16 @@ static void __ieee80211_scan_completed(s
 
 	ieee80211_mlme_notify_scan_completed(local);
 	ieee80211_ibss_notify_scan_completed(local);
-	ieee80211_mesh_notify_scan_completed(local);
+
+	/* Requeue all the work that might have been ignored while
+	 * the scan was in progress; if there was none this will
+	 * just be a no-op for the particular interface.
+	 */
+	list_for_each_entry_rcu(sdata, &local->interfaces, list) {
+		if (ieee80211_sdata_running(sdata))
+			ieee80211_queue_work(&sdata->local->hw, &sdata->work);
+	}
+
 	if (was_scanning)
 		ieee80211_start_next_roc(local);
 }
--- zfcpdump-kernel-4.4.orig/net/mac80211/sta_info.c
+++ zfcpdump-kernel-4.4/net/mac80211/sta_info.c
@@ -256,11 +256,11 @@ void sta_info_free(struct ieee80211_loca
 }
 
 /* Caller must hold local->sta_mtx */
-static void sta_info_hash_add(struct ieee80211_local *local,
-			      struct sta_info *sta)
+static int sta_info_hash_add(struct ieee80211_local *local,
+			     struct sta_info *sta)
 {
-	rhashtable_insert_fast(&local->sta_hash, &sta->hash_node,
-			       sta_rht_params);
+	return rhashtable_insert_fast(&local->sta_hash, &sta->hash_node,
+				      sta_rht_params);
 }
 
 static void sta_deliver_ps_frames(struct work_struct *wk)
@@ -484,11 +484,17 @@ static int sta_info_insert_finish(struct
 {
 	struct ieee80211_local *local = sta->local;
 	struct ieee80211_sub_if_data *sdata = sta->sdata;
-	struct station_info sinfo;
+	struct station_info *sinfo;
 	int err = 0;
 
 	lockdep_assert_held(&local->sta_mtx);
 
+	sinfo = kzalloc(sizeof(struct station_info), GFP_KERNEL);
+	if (!sinfo) {
+		err = -ENOMEM;
+		goto out_err;
+	}
+
 	/* check if STA exists already */
 	if (sta_info_get_bss(sdata, sta->sta.addr)) {
 		err = -EEXIST;
@@ -503,7 +509,9 @@ static int sta_info_insert_finish(struct
 	set_sta_flag(sta, WLAN_STA_BLOCK_BA);
 
 	/* make the station visible */
-	sta_info_hash_add(local, sta);
+	err = sta_info_hash_add(local, sta);
+	if (err)
+		goto out_drop_sta;
 
 	list_add_tail_rcu(&sta->list, &local->sta_list);
 
@@ -520,10 +528,9 @@ static int sta_info_insert_finish(struct
 	ieee80211_sta_debugfs_add(sta);
 	rate_control_add_sta_debugfs(sta);
 
-	memset(&sinfo, 0, sizeof(sinfo));
-	sinfo.filled = 0;
-	sinfo.generation = local->sta_generation;
-	cfg80211_new_sta(sdata->dev, sta->sta.addr, &sinfo, GFP_KERNEL);
+	sinfo->generation = local->sta_generation;
+	cfg80211_new_sta(sdata->dev, sta->sta.addr, sinfo, GFP_KERNEL);
+	kfree(sinfo);
 
 	sta_dbg(sdata, "Inserted STA %pM\n", sta->sta.addr);
 
@@ -538,6 +545,7 @@ static int sta_info_insert_finish(struct
  out_remove:
 	sta_info_hash_del(local, sta);
 	list_del_rcu(&sta->list);
+ out_drop_sta:
 	local->num_sta--;
 	synchronize_net();
 	__cleanup_single_sta(sta);
@@ -882,7 +890,7 @@ static void __sta_info_destroy_part2(str
 {
 	struct ieee80211_local *local = sta->local;
 	struct ieee80211_sub_if_data *sdata = sta->sdata;
-	struct station_info sinfo = {};
+	struct station_info *sinfo;
 	int ret;
 
 	/*
@@ -920,8 +928,11 @@ static void __sta_info_destroy_part2(str
 
 	sta_dbg(sdata, "Removed STA %pM\n", sta->sta.addr);
 
-	sta_set_sinfo(sta, &sinfo);
-	cfg80211_del_sta_sinfo(sdata->dev, sta->sta.addr, &sinfo, GFP_KERNEL);
+	sinfo = kzalloc(sizeof(*sinfo), GFP_KERNEL);
+	if (sinfo)
+		sta_set_sinfo(sta, sinfo);
+	cfg80211_del_sta_sinfo(sdata->dev, sta->sta.addr, sinfo, GFP_KERNEL);
+	kfree(sinfo);
 
 	rate_control_remove_sta_debugfs(sta);
 	ieee80211_sta_debugfs_remove(sta);
--- zfcpdump-kernel-4.4.orig/net/mac80211/sta_info.h
+++ zfcpdump-kernel-4.4/net/mac80211/sta_info.h
@@ -269,7 +269,7 @@ struct ieee80211_fast_tx {
 	u8 sa_offs, da_offs, pn_offs;
 	u8 band;
 	u8 hdr[30 + 2 + IEEE80211_FAST_XMIT_MAX_IV +
-	       sizeof(rfc1042_header)];
+	       sizeof(rfc1042_header)] __aligned(2);
 
 	struct rcu_head rcu_head;
 };
--- zfcpdump-kernel-4.4.orig/net/mac80211/tx.c
+++ zfcpdump-kernel-4.4/net/mac80211/tx.c
@@ -365,7 +365,7 @@ static void purge_old_ps_buffers(struct
 		skb = skb_dequeue(&ps->bc_buf);
 		if (skb) {
 			purged++;
-			dev_kfree_skb(skb);
+			ieee80211_free_txskb(&local->hw, skb);
 		}
 		total += skb_queue_len(&ps->bc_buf);
 	}
@@ -448,7 +448,7 @@ ieee80211_tx_h_multicast_ps_buf(struct i
 	if (skb_queue_len(&ps->bc_buf) >= AP_MAX_BC_BUFFER) {
 		ps_dbg(tx->sdata,
 		       "BC TX buffer full - dropping the oldest frame\n");
-		dev_kfree_skb(skb_dequeue(&ps->bc_buf));
+		ieee80211_free_txskb(&tx->local->hw, skb_dequeue(&ps->bc_buf));
 	} else
 		tx->local->total_ps_buffered++;
 
@@ -3781,7 +3781,7 @@ ieee80211_get_buffered_bc(struct ieee802
 			sdata = IEEE80211_DEV_TO_SUB_IF(skb->dev);
 		if (!ieee80211_tx_prepare(sdata, &tx, NULL, skb))
 			break;
-		dev_kfree_skb_any(skb);
+		ieee80211_free_txskb(hw, skb);
 	}
 
 	info = IEEE80211_SKB_CB(skb);
--- zfcpdump-kernel-4.4.orig/net/mpls/af_mpls.c
+++ zfcpdump-kernel-4.4/net/mpls/af_mpls.c
@@ -518,6 +518,9 @@ static struct net_device *find_outdev(st
 	if (!dev)
 		return ERR_PTR(-ENODEV);
 
+	if (IS_ERR(dev))
+		return dev;
+
 	/* The caller is holding rtnl anyways, so release the dev reference */
 	dev_put(dev);
 
--- zfcpdump-kernel-4.4.orig/net/netfilter/ipvs/ip_vs_core.c
+++ zfcpdump-kernel-4.4/net/netfilter/ipvs/ip_vs_core.c
@@ -1757,15 +1757,34 @@ ip_vs_in(struct netns_ipvs *ipvs, unsign
 	cp = pp->conn_in_get(ipvs, af, skb, &iph);
 
 	conn_reuse_mode = sysctl_conn_reuse_mode(ipvs);
-	if (conn_reuse_mode && !iph.fragoffs &&
-	    is_new_conn(skb, &iph) && cp &&
-	    ((unlikely(sysctl_expire_nodest_conn(ipvs)) && cp->dest &&
-	      unlikely(!atomic_read(&cp->dest->weight))) ||
-	     unlikely(is_new_conn_expected(cp, conn_reuse_mode)))) {
-		if (!atomic_read(&cp->n_control))
-			ip_vs_conn_expire_now(cp);
-		__ip_vs_conn_put(cp);
-		cp = NULL;
+	if (conn_reuse_mode && !iph.fragoffs && is_new_conn(skb, &iph) && cp) {
+		bool uses_ct = false, resched = false;
+
+		if (unlikely(sysctl_expire_nodest_conn(ipvs)) && cp->dest &&
+		    unlikely(!atomic_read(&cp->dest->weight))) {
+			resched = true;
+			uses_ct = ip_vs_conn_uses_conntrack(cp, skb);
+		} else if (is_new_conn_expected(cp, conn_reuse_mode)) {
+			uses_ct = ip_vs_conn_uses_conntrack(cp, skb);
+			if (!atomic_read(&cp->n_control)) {
+				resched = true;
+			} else {
+				/* Do not reschedule controlling connection
+				 * that uses conntrack while it is still
+				 * referenced by controlled connection(s).
+				 */
+				resched = !uses_ct;
+			}
+		}
+
+		if (resched) {
+			if (!atomic_read(&cp->n_control))
+				ip_vs_conn_expire_now(cp);
+			__ip_vs_conn_put(cp);
+			if (uses_ct)
+				return NF_DROP;
+			cp = NULL;
+		}
 	}
 
 	if (unlikely(!cp)) {
--- zfcpdump-kernel-4.4.orig/net/netfilter/ipvs/ip_vs_pe_sip.c
+++ zfcpdump-kernel-4.4/net/netfilter/ipvs/ip_vs_pe_sip.c
@@ -70,10 +70,10 @@ ip_vs_sip_fill_param(struct ip_vs_conn_p
 	const char *dptr;
 	int retc;
 
-	ip_vs_fill_iph_skb(p->af, skb, false, &iph);
+	retc = ip_vs_fill_iph_skb(p->af, skb, false, &iph);
 
 	/* Only useful with UDP */
-	if (iph.protocol != IPPROTO_UDP)
+	if (!retc || iph.protocol != IPPROTO_UDP)
 		return -EINVAL;
 	/* todo: IPv6 fragments:
 	 *       I think this only should be done for the first fragment. /HS
@@ -88,7 +88,7 @@ ip_vs_sip_fill_param(struct ip_vs_conn_p
 	dptr = skb->data + dataoff;
 	datalen = skb->len - dataoff;
 
-	if (get_callid(dptr, dataoff, datalen, &matchoff, &matchlen))
+	if (get_callid(dptr, 0, datalen, &matchoff, &matchlen))
 		return -EINVAL;
 
 	/* N.B: pe_data is only set on success,
--- zfcpdump-kernel-4.4.orig/net/netfilter/ipvs/ip_vs_proto_sctp.c
+++ zfcpdump-kernel-4.4/net/netfilter/ipvs/ip_vs_proto_sctp.c
@@ -169,7 +169,7 @@ sctp_dnat_handler(struct sk_buff *skb, s
 	/* Only update csum if we really have to */
 	if (sctph->dest != cp->dport || payload_csum ||
 	    (skb->ip_summed == CHECKSUM_PARTIAL &&
-	     !(skb_dst(skb)->dev->features & NETIF_F_SCTP_CSUM))) {
+	     !(skb_dst(skb)->dev->features & NETIF_F_SCTP_CRC))) {
 		sctph->dest = cp->dport;
 		sctp_nat_csum(skb, sctph, sctphoff);
 	} else if (skb->ip_summed != CHECKSUM_PARTIAL) {
--- zfcpdump-kernel-4.4.orig/net/netfilter/ipvs/ip_vs_sync.c
+++ zfcpdump-kernel-4.4/net/netfilter/ipvs/ip_vs_sync.c
@@ -1545,7 +1545,8 @@ error:
 /*
  *      Set up receiving multicast socket over UDP
  */
-static struct socket *make_receive_sock(struct netns_ipvs *ipvs, int id)
+static struct socket *make_receive_sock(struct netns_ipvs *ipvs, int id,
+					int ifindex)
 {
 	/* multicast addr */
 	union ipvs_sockaddr mcast_addr;
@@ -1566,6 +1567,7 @@ static struct socket *make_receive_sock(
 		set_sock_size(sock->sk, 0, result);
 
 	get_mcast_sockaddr(&mcast_addr, &salen, &ipvs->bcfg, id);
+	sock->sk->sk_bound_dev_if = ifindex;
 	result = sock->ops->bind(sock, (struct sockaddr *)&mcast_addr, salen);
 	if (result < 0) {
 		pr_err("Error binding to the multicast addr\n");
@@ -1868,7 +1870,7 @@ int start_sync_thread(struct netns_ipvs
 		if (state == IP_VS_STATE_MASTER)
 			sock = make_send_sock(ipvs, id);
 		else
-			sock = make_receive_sock(ipvs, id);
+			sock = make_receive_sock(ipvs, id, dev->ifindex);
 		if (IS_ERR(sock)) {
 			result = PTR_ERR(sock);
 			goto outtinfo;
--- zfcpdump-kernel-4.4.orig/net/netfilter/nf_conntrack_core.c
+++ zfcpdump-kernel-4.4/net/netfilter/nf_conntrack_core.c
@@ -1757,6 +1757,7 @@ void nf_conntrack_init_end(void)
 
 int nf_conntrack_init_net(struct net *net)
 {
+	static atomic64_t unique_id;
 	int ret = -ENOMEM;
 	int cpu;
 
@@ -1779,7 +1780,8 @@ int nf_conntrack_init_net(struct net *ne
 	if (!net->ct.stat)
 		goto err_pcpu_lists;
 
-	net->ct.slabname = kasprintf(GFP_KERNEL, "nf_conntrack_%p", net);
+	net->ct.slabname = kasprintf(GFP_KERNEL, "nf_conntrack_%llu",
+				(u64)atomic64_inc_return(&unique_id));
 	if (!net->ct.slabname)
 		goto err_slabname;
 
--- zfcpdump-kernel-4.4.orig/net/netfilter/nf_conntrack_expect.c
+++ zfcpdump-kernel-4.4/net/netfilter/nf_conntrack_expect.c
@@ -596,11 +596,18 @@ static int exp_proc_init(struct net *net
 {
 #ifdef CONFIG_NF_CONNTRACK_PROCFS
 	struct proc_dir_entry *proc;
+	kuid_t root_uid;
+	kgid_t root_gid;
 
 	proc = proc_create("nf_conntrack_expect", 0440, net->proc_net,
 			   &exp_file_ops);
 	if (!proc)
 		return -ENOMEM;
+
+	root_uid = make_kuid(net->user_ns, 0);
+	root_gid = make_kgid(net->user_ns, 0);
+	if (uid_valid(root_uid) && gid_valid(root_gid))
+		proc_set_user(proc, root_uid, root_gid);
 #endif /* CONFIG_NF_CONNTRACK_PROCFS */
 	return 0;
 }
--- zfcpdump-kernel-4.4.orig/net/netfilter/nf_conntrack_standalone.c
+++ zfcpdump-kernel-4.4/net/netfilter/nf_conntrack_standalone.c
@@ -392,11 +392,18 @@ static const struct file_operations ct_c
 static int nf_conntrack_standalone_init_proc(struct net *net)
 {
 	struct proc_dir_entry *pde;
+	kuid_t root_uid;
+	kgid_t root_gid;
 
 	pde = proc_create("nf_conntrack", 0440, net->proc_net, &ct_file_ops);
 	if (!pde)
 		goto out_nf_conntrack;
 
+	root_uid = make_kuid(net->user_ns, 0);
+	root_gid = make_kgid(net->user_ns, 0);
+	if (uid_valid(root_uid) && gid_valid(root_gid))
+		proc_set_user(pde, root_uid, root_gid);
+
 	pde = proc_create("nf_conntrack", S_IRUGO, net->proc_net_stat,
 			  &ct_cpu_seq_fops);
 	if (!pde)
--- zfcpdump-kernel-4.4.orig/net/netfilter/nfnetlink_log.c
+++ zfcpdump-kernel-4.4/net/netfilter/nfnetlink_log.c
@@ -1064,15 +1064,26 @@ static int __net_init nfnl_log_net_init(
 {
 	unsigned int i;
 	struct nfnl_log_net *log = nfnl_log_pernet(net);
+#ifdef CONFIG_PROC_FS
+	struct proc_dir_entry *proc;
+	kuid_t root_uid;
+	kgid_t root_gid;
+#endif
 
 	for (i = 0; i < INSTANCE_BUCKETS; i++)
 		INIT_HLIST_HEAD(&log->instance_table[i]);
 	spin_lock_init(&log->instances_lock);
 
 #ifdef CONFIG_PROC_FS
-	if (!proc_create("nfnetlink_log", 0440,
-			 net->nf.proc_netfilter, &nful_file_ops))
+	proc = proc_create("nfnetlink_log", 0440,
+			   net->nf.proc_netfilter, &nful_file_ops);
+	if (!proc)
 		return -ENOMEM;
+
+	root_uid = make_kuid(net->user_ns, 0);
+	root_gid = make_kgid(net->user_ns, 0);
+	if (uid_valid(root_uid) && gid_valid(root_gid))
+		proc_set_user(proc, root_uid, root_gid);
 #endif
 	return 0;
 }
--- zfcpdump-kernel-4.4.orig/net/netfilter/x_tables.c
+++ zfcpdump-kernel-4.4/net/netfilter/x_tables.c
@@ -26,6 +26,7 @@
 #include <linux/mm.h>
 #include <linux/slab.h>
 #include <linux/audit.h>
+#include <linux/user_namespace.h>
 #include <net/net_namespace.h>
 
 #include <linux/netfilter/x_tables.h>
@@ -415,6 +416,47 @@ int xt_check_match(struct xt_mtchk_param
 }
 EXPORT_SYMBOL_GPL(xt_check_match);
 
+/** xt_check_entry_match - check that matches end before start of target
+ *
+ * @match: beginning of xt_entry_match
+ * @target: beginning of this rules target (alleged end of matches)
+ * @alignment: alignment requirement of match structures
+ *
+ * Validates that all matches add up to the beginning of the target,
+ * and that each match covers at least the base structure size.
+ *
+ * Return: 0 on success, negative errno on failure.
+ */
+static int xt_check_entry_match(const char *match, const char *target,
+				const size_t alignment)
+{
+	const struct xt_entry_match *pos;
+	int length = target - match;
+
+	if (length == 0) /* no matches */
+		return 0;
+
+	pos = (struct xt_entry_match *)match;
+	do {
+		if ((unsigned long)pos % alignment)
+			return -EINVAL;
+
+		if (length < (int)sizeof(struct xt_entry_match))
+			return -EINVAL;
+
+		if (pos->u.match_size < sizeof(struct xt_entry_match))
+			return -EINVAL;
+
+		if (pos->u.match_size > length)
+			return -EINVAL;
+
+		length -= pos->u.match_size;
+		pos = ((void *)((char *)(pos) + (pos)->u.match_size));
+	} while (length > 0);
+
+	return 0;
+}
+
 #ifdef CONFIG_COMPAT
 int xt_compat_add_offset(u_int8_t af, unsigned int offset, int delta)
 {
@@ -484,13 +526,14 @@ int xt_compat_match_offset(const struct
 }
 EXPORT_SYMBOL_GPL(xt_compat_match_offset);
 
-int xt_compat_match_from_user(struct xt_entry_match *m, void **dstptr,
-			      unsigned int *size)
+void xt_compat_match_from_user(struct xt_entry_match *m, void **dstptr,
+			       unsigned int *size)
 {
 	const struct xt_match *match = m->u.kernel.match;
 	struct compat_xt_entry_match *cm = (struct compat_xt_entry_match *)m;
 	int pad, off = xt_compat_match_offset(match);
 	u_int16_t msize = cm->u.user.match_size;
+	char name[sizeof(m->u.user.name)];
 
 	m = *dstptr;
 	memcpy(m, cm, sizeof(*cm));
@@ -504,10 +547,12 @@ int xt_compat_match_from_user(struct xt_
 
 	msize += off;
 	m->u.user.match_size = msize;
+	strlcpy(name, match->name, sizeof(name));
+	module_put(match->me);
+	strncpy(m->u.user.name, name, sizeof(m->u.user.name));
 
 	*size += off;
 	*dstptr += msize;
-	return 0;
 }
 EXPORT_SYMBOL_GPL(xt_compat_match_from_user);
 
@@ -538,8 +583,125 @@ int xt_compat_match_to_user(const struct
 	return 0;
 }
 EXPORT_SYMBOL_GPL(xt_compat_match_to_user);
+
+/* non-compat version may have padding after verdict */
+struct compat_xt_standard_target {
+	struct compat_xt_entry_target t;
+	compat_uint_t verdict;
+};
+
+int xt_compat_check_entry_offsets(const void *base, const char *elems,
+				  unsigned int target_offset,
+				  unsigned int next_offset)
+{
+	long size_of_base_struct = elems - (const char *)base;
+	const struct compat_xt_entry_target *t;
+	const char *e = base;
+
+	if (target_offset < size_of_base_struct)
+		return -EINVAL;
+
+	if (target_offset + sizeof(*t) > next_offset)
+		return -EINVAL;
+
+	t = (void *)(e + target_offset);
+	if (t->u.target_size < sizeof(*t))
+		return -EINVAL;
+
+	if (target_offset + t->u.target_size > next_offset)
+		return -EINVAL;
+
+	if (strcmp(t->u.user.name, XT_STANDARD_TARGET) == 0 &&
+	    COMPAT_XT_ALIGN(target_offset + sizeof(struct compat_xt_standard_target)) != next_offset)
+		return -EINVAL;
+
+	/* compat_xt_entry match has less strict aligment requirements,
+	 * otherwise they are identical.  In case of padding differences
+	 * we need to add compat version of xt_check_entry_match.
+	 */
+	BUILD_BUG_ON(sizeof(struct compat_xt_entry_match) != sizeof(struct xt_entry_match));
+
+	return xt_check_entry_match(elems, base + target_offset,
+				    __alignof__(struct compat_xt_entry_match));
+}
+EXPORT_SYMBOL(xt_compat_check_entry_offsets);
 #endif /* CONFIG_COMPAT */
 
+/**
+ * xt_check_entry_offsets - validate arp/ip/ip6t_entry
+ *
+ * @base: pointer to arp/ip/ip6t_entry
+ * @elems: pointer to first xt_entry_match, i.e. ip(6)t_entry->elems
+ * @target_offset: the arp/ip/ip6_t->target_offset
+ * @next_offset: the arp/ip/ip6_t->next_offset
+ *
+ * validates that target_offset and next_offset are sane and that all
+ * match sizes (if any) align with the target offset.
+ *
+ * This function does not validate the targets or matches themselves, it
+ * only tests that all the offsets and sizes are correct, that all
+ * match structures are aligned, and that the last structure ends where
+ * the target structure begins.
+ *
+ * Also see xt_compat_check_entry_offsets for CONFIG_COMPAT version.
+ *
+ * The arp/ip/ip6t_entry structure @base must have passed following tests:
+ * - it must point to a valid memory location
+ * - base to base + next_offset must be accessible, i.e. not exceed allocated
+ *   length.
+ *
+ * A well-formed entry looks like this:
+ *
+ * ip(6)t_entry   match [mtdata]  match [mtdata] target [tgdata] ip(6)t_entry
+ * e->elems[]-----'                              |               |
+ *                matchsize                      |               |
+ *                                matchsize      |               |
+ *                                               |               |
+ * target_offset---------------------------------'               |
+ * next_offset---------------------------------------------------'
+ *
+ * elems[]: flexible array member at end of ip(6)/arpt_entry struct.
+ *          This is where matches (if any) and the target reside.
+ * target_offset: beginning of target.
+ * next_offset: start of the next rule; also: size of this rule.
+ * Since targets have a minimum size, target_offset + minlen <= next_offset.
+ *
+ * Every match stores its size, sum of sizes must not exceed target_offset.
+ *
+ * Return: 0 on success, negative errno on failure.
+ */
+int xt_check_entry_offsets(const void *base,
+			   const char *elems,
+			   unsigned int target_offset,
+			   unsigned int next_offset)
+{
+	long size_of_base_struct = elems - (const char *)base;
+	const struct xt_entry_target *t;
+	const char *e = base;
+
+	/* target start is within the ip/ip6/arpt_entry struct */
+	if (target_offset < size_of_base_struct)
+		return -EINVAL;
+
+	if (target_offset + sizeof(*t) > next_offset)
+		return -EINVAL;
+
+	t = (void *)(e + target_offset);
+	if (t->u.target_size < sizeof(*t))
+		return -EINVAL;
+
+	if (target_offset + t->u.target_size > next_offset)
+		return -EINVAL;
+
+	if (strcmp(t->u.user.name, XT_STANDARD_TARGET) == 0 &&
+	    XT_ALIGN(target_offset + sizeof(struct xt_standard_target)) != next_offset)
+		return -EINVAL;
+
+	return xt_check_entry_match(elems, base + target_offset,
+				    __alignof__(struct xt_entry_match));
+}
+EXPORT_SYMBOL(xt_check_entry_offsets);
+
 int xt_check_target(struct xt_tgchk_param *par,
 		    unsigned int size, u_int8_t proto, bool inv_proto)
 {
@@ -590,6 +752,80 @@ int xt_check_target(struct xt_tgchk_para
 }
 EXPORT_SYMBOL_GPL(xt_check_target);
 
+/**
+ * xt_copy_counters_from_user - copy counters and metadata from userspace
+ *
+ * @user: src pointer to userspace memory
+ * @len: alleged size of userspace memory
+ * @info: where to store the xt_counters_info metadata
+ * @compat: true if we setsockopt call is done by 32bit task on 64bit kernel
+ *
+ * Copies counter meta data from @user and stores it in @info.
+ *
+ * vmallocs memory to hold the counters, then copies the counter data
+ * from @user to the new memory and returns a pointer to it.
+ *
+ * If @compat is true, @info gets converted automatically to the 64bit
+ * representation.
+ *
+ * The metadata associated with the counters is stored in @info.
+ *
+ * Return: returns pointer that caller has to test via IS_ERR().
+ * If IS_ERR is false, caller has to vfree the pointer.
+ */
+void *xt_copy_counters_from_user(const void __user *user, unsigned int len,
+				 struct xt_counters_info *info, bool compat)
+{
+	void *mem;
+	u64 size;
+
+#ifdef CONFIG_COMPAT
+	if (compat) {
+		/* structures only differ in size due to alignment */
+		struct compat_xt_counters_info compat_tmp;
+
+		if (len <= sizeof(compat_tmp))
+			return ERR_PTR(-EINVAL);
+
+		len -= sizeof(compat_tmp);
+		if (copy_from_user(&compat_tmp, user, sizeof(compat_tmp)) != 0)
+			return ERR_PTR(-EFAULT);
+
+		strlcpy(info->name, compat_tmp.name, sizeof(info->name));
+		info->num_counters = compat_tmp.num_counters;
+		user += sizeof(compat_tmp);
+	} else
+#endif
+	{
+		if (len <= sizeof(*info))
+			return ERR_PTR(-EINVAL);
+
+		len -= sizeof(*info);
+		if (copy_from_user(info, user, sizeof(*info)) != 0)
+			return ERR_PTR(-EFAULT);
+
+		info->name[sizeof(info->name) - 1] = '\0';
+		user += sizeof(*info);
+	}
+
+	size = sizeof(struct xt_counters);
+	size *= info->num_counters;
+
+	if (size != (u64)len)
+		return ERR_PTR(-EINVAL);
+
+	mem = vmalloc(len);
+	if (!mem)
+		return ERR_PTR(-ENOMEM);
+
+	if (copy_from_user(mem, user, len) == 0)
+		return mem;
+
+	vfree(mem);
+	return ERR_PTR(-EFAULT);
+}
+EXPORT_SYMBOL_GPL(xt_copy_counters_from_user);
+
 #ifdef CONFIG_COMPAT
 int xt_compat_target_offset(const struct xt_target *target)
 {
@@ -605,6 +841,7 @@ void xt_compat_target_from_user(struct x
 	struct compat_xt_entry_target *ct = (struct compat_xt_entry_target *)t;
 	int pad, off = xt_compat_target_offset(target);
 	u_int16_t tsize = ct->u.user.target_size;
+	char name[sizeof(t->u.user.name)];
 
 	t = *dstptr;
 	memcpy(t, ct, sizeof(*ct));
@@ -618,6 +855,9 @@ void xt_compat_target_from_user(struct x
 
 	tsize += off;
 	t->u.user.target_size = tsize;
+	strlcpy(name, target->name, sizeof(name));
+	module_put(target->me);
+	strncpy(t->u.user.name, name, sizeof(t->u.user.name));
 
 	*size += off;
 	*dstptr += tsize;
@@ -658,6 +898,12 @@ struct xt_table_info *xt_alloc_table_inf
 	struct xt_table_info *info = NULL;
 	size_t sz = sizeof(*info) + size;
 
+	if (sz < sizeof(*info))
+		return NULL;
+
+	if (sz < sizeof(*info))
+		return NULL;
+
 	/* Pedantry: prevent them from hitting BUG() in vmalloc.c --RR */
 	if ((SMP_ALIGN(size) >> PAGE_SHIFT) + 2 > totalram_pages)
 		return NULL;
@@ -1226,6 +1472,8 @@ int xt_proto_init(struct net *net, u_int
 #ifdef CONFIG_PROC_FS
 	char buf[XT_FUNCTION_MAXNAMELEN];
 	struct proc_dir_entry *proc;
+	kuid_t root_uid;
+	kgid_t root_gid;
 #endif
 
 	if (af >= ARRAY_SIZE(xt_prefix))
@@ -1233,12 +1481,17 @@ int xt_proto_init(struct net *net, u_int
 
 
 #ifdef CONFIG_PROC_FS
+	root_uid = make_kuid(net->user_ns, 0);
+	root_gid = make_kgid(net->user_ns, 0);
+
 	strlcpy(buf, xt_prefix[af], sizeof(buf));
 	strlcat(buf, FORMAT_TABLES, sizeof(buf));
 	proc = proc_create_data(buf, 0440, net->proc_net, &xt_table_ops,
 				(void *)(unsigned long)af);
 	if (!proc)
 		goto out;
+	if (uid_valid(root_uid) && gid_valid(root_gid))
+		proc_set_user(proc, root_uid, root_gid);
 
 	strlcpy(buf, xt_prefix[af], sizeof(buf));
 	strlcat(buf, FORMAT_MATCHES, sizeof(buf));
@@ -1246,6 +1499,8 @@ int xt_proto_init(struct net *net, u_int
 				(void *)(unsigned long)af);
 	if (!proc)
 		goto out_remove_tables;
+	if (uid_valid(root_uid) && gid_valid(root_gid))
+		proc_set_user(proc, root_uid, root_gid);
 
 	strlcpy(buf, xt_prefix[af], sizeof(buf));
 	strlcat(buf, FORMAT_TARGETS, sizeof(buf));
@@ -1253,6 +1508,8 @@ int xt_proto_init(struct net *net, u_int
 				(void *)(unsigned long)af);
 	if (!proc)
 		goto out_remove_matches;
+	if (uid_valid(root_uid) && gid_valid(root_gid))
+		proc_set_user(proc, root_uid, root_gid);
 #endif
 
 	return 0;
--- zfcpdump-kernel-4.4.orig/net/netlabel/netlabel_kapi.c
+++ zfcpdump-kernel-4.4/net/netlabel/netlabel_kapi.c
@@ -824,7 +824,11 @@ socket_setattr_return:
  */
 void netlbl_sock_delattr(struct sock *sk)
 {
-	cipso_v4_sock_delattr(sk);
+	switch (sk->sk_family) {
+	case AF_INET:
+		cipso_v4_sock_delattr(sk);
+		break;
+	}
 }
 
 /**
@@ -987,7 +991,11 @@ req_setattr_return:
 */
 void netlbl_req_delattr(struct request_sock *req)
 {
-	cipso_v4_req_delattr(req);
+	switch (req->rsk_ops->family) {
+	case AF_INET:
+		cipso_v4_req_delattr(req);
+		break;
+	}
 }
 
 /**
--- zfcpdump-kernel-4.4.orig/net/netlink/af_netlink.c
+++ zfcpdump-kernel-4.4/net/netlink/af_netlink.c
@@ -1305,7 +1305,7 @@ static int netlink_release(struct socket
 
 	skb_queue_purge(&sk->sk_write_queue);
 
-	if (nlk->portid) {
+	if (nlk->portid && nlk->bound) {
 		struct netlink_notify n = {
 						.net = sock_net(sk),
 						.protocol = sk->sk_protocol,
@@ -2784,6 +2784,7 @@ static int netlink_dump(struct sock *sk)
 	struct netlink_callback *cb;
 	struct sk_buff *skb = NULL;
 	struct nlmsghdr *nlh;
+	struct module *module;
 	int len, err = -ENOBUFS;
 	int alloc_min_size;
 	int alloc_size;
@@ -2863,9 +2864,11 @@ static int netlink_dump(struct sock *sk)
 		cb->done(cb);
 
 	nlk->cb_running = false;
+	module = cb->module;
+	skb = cb->skb;
 	mutex_unlock(nlk->cb_mutex);
-	module_put(cb->module);
-	consume_skb(cb->skb);
+	module_put(module);
+	consume_skb(skb);
 	return 0;
 
 errout_skb:
--- zfcpdump-kernel-4.4.orig/net/netlink/genetlink.c
+++ zfcpdump-kernel-4.4/net/netlink/genetlink.c
@@ -566,6 +566,10 @@ static int genl_family_rcv_msg(struct ge
 	    !netlink_capable(skb, CAP_NET_ADMIN))
 		return -EPERM;
 
+	if ((ops->flags & GENL_UNS_ADMIN_PERM) &&
+	    !netlink_ns_capable(skb, net->user_ns, CAP_NET_ADMIN))
+		return -EPERM;
+
 	if ((nlh->nlmsg_flags & NLM_F_DUMP) == NLM_F_DUMP) {
 		int rc;
 
--- zfcpdump-kernel-4.4.orig/net/openvswitch/actions.c
+++ zfcpdump-kernel-4.4/net/openvswitch/actions.c
@@ -158,9 +158,7 @@ static int push_mpls(struct sk_buff *skb
 	new_mpls_lse = (__be32 *)skb_mpls_header(skb);
 	*new_mpls_lse = mpls->mpls_lse;
 
-	if (skb->ip_summed == CHECKSUM_COMPLETE)
-		skb->csum = csum_add(skb->csum, csum_partial(new_mpls_lse,
-							     MPLS_HLEN, 0));
+	skb_postpush_rcsum(skb, new_mpls_lse, MPLS_HLEN);
 
 	hdr = eth_hdr(skb);
 	hdr->h_proto = mpls->mpls_ethertype;
@@ -280,7 +278,7 @@ static int set_eth_addr(struct sk_buff *
 	ether_addr_copy_masked(eth_hdr(skb)->h_dest, key->eth_dst,
 			       mask->eth_dst);
 
-	ovs_skb_postpush_rcsum(skb, eth_hdr(skb), ETH_ALEN * 2);
+	skb_postpush_rcsum(skb, eth_hdr(skb), ETH_ALEN * 2);
 
 	ether_addr_copy(flow_key->eth.src, eth_hdr(skb)->h_source);
 	ether_addr_copy(flow_key->eth.dst, eth_hdr(skb)->h_dest);
@@ -463,7 +461,7 @@ static int set_ipv6(struct sk_buff *skb,
 		mask_ipv6_addr(saddr, key->ipv6_src, mask->ipv6_src, masked);
 
 		if (unlikely(memcmp(saddr, masked, sizeof(masked)))) {
-			set_ipv6_addr(skb, key->ipv6_proto, saddr, masked,
+			set_ipv6_addr(skb, flow_key->ip.proto, saddr, masked,
 				      true);
 			memcpy(&flow_key->ipv6.addr.src, masked,
 			       sizeof(flow_key->ipv6.addr.src));
@@ -485,7 +483,7 @@ static int set_ipv6(struct sk_buff *skb,
 							     NULL, &flags)
 					       != NEXTHDR_ROUTING);
 
-			set_ipv6_addr(skb, key->ipv6_proto, daddr, masked,
+			set_ipv6_addr(skb, flow_key->ip.proto, daddr, masked,
 				      recalc_csum);
 			memcpy(&flow_key->ipv6.addr.dst, masked,
 			       sizeof(flow_key->ipv6.addr.dst));
@@ -639,7 +637,7 @@ static int ovs_vport_output(struct net *
 	/* Reconstruct the MAC header.  */
 	skb_push(skb, data->l2_len);
 	memcpy(skb->data, &data->l2_data, data->l2_len);
-	ovs_skb_postpush_rcsum(skb, skb->data, data->l2_len);
+	skb_postpush_rcsum(skb, skb->data, data->l2_len);
 	skb_reset_mac_header(skb);
 
 	ovs_vport_send(vport, skb);
--- zfcpdump-kernel-4.4.orig/net/openvswitch/conntrack.c
+++ zfcpdump-kernel-4.4/net/openvswitch/conntrack.c
@@ -442,11 +442,16 @@ static int ovs_ct_lookup(struct net *net
 		state = OVS_CS_F_TRACKED | OVS_CS_F_NEW | OVS_CS_F_RELATED;
 		__ovs_ct_update_key(key, state, &info->zone, exp->master);
 	} else {
+		struct nf_conn *ct;
 		int err;
 
 		err = __ovs_ct_lookup(net, key, info, skb);
 		if (err)
 			return err;
+
+		ct = (struct nf_conn *)skb->nfct;
+		if (ct)
+			nf_ct_deliver_cached_events(ct);
 	}
 
 	return 0;
--- zfcpdump-kernel-4.4.orig/net/openvswitch/datapath.c
+++ zfcpdump-kernel-4.4/net/openvswitch/datapath.c
@@ -336,12 +336,10 @@ static int queue_gso_packets(struct data
 	unsigned short gso_type = skb_shinfo(skb)->gso_type;
 	struct sw_flow_key later_key;
 	struct sk_buff *segs, *nskb;
-	struct ovs_skb_cb ovs_cb;
 	int err;
 
-	ovs_cb = *OVS_CB(skb);
+	BUILD_BUG_ON(sizeof(*OVS_CB(skb)) > SKB_SGO_CB_OFFSET);
 	segs = __skb_gso_segment(skb, NETIF_F_SG, false);
-	*OVS_CB(skb) = ovs_cb;
 	if (IS_ERR(segs))
 		return PTR_ERR(segs);
 	if (segs == NULL)
@@ -359,7 +357,6 @@ static int queue_gso_packets(struct data
 	/* Queue all of the segments. */
 	skb = segs;
 	do {
-		*OVS_CB(skb) = ovs_cb;
 		if (gso_type & SKB_GSO_UDP && skb != segs)
 			key = &later_key;
 
@@ -657,7 +654,7 @@ static const struct nla_policy packet_po
 
 static const struct genl_ops dp_packet_genl_ops[] = {
 	{ .cmd = OVS_PACKET_CMD_EXECUTE,
-	  .flags = GENL_ADMIN_PERM, /* Requires CAP_NET_ADMIN privilege. */
+	  .flags = GENL_UNS_ADMIN_PERM, /* Requires CAP_NET_ADMIN privilege. */
 	  .policy = packet_policy,
 	  .doit = ovs_packet_cmd_execute
 	}
@@ -1394,12 +1391,12 @@ static const struct nla_policy flow_poli
 
 static const struct genl_ops dp_flow_genl_ops[] = {
 	{ .cmd = OVS_FLOW_CMD_NEW,
-	  .flags = GENL_ADMIN_PERM, /* Requires CAP_NET_ADMIN privilege. */
+	  .flags = GENL_UNS_ADMIN_PERM, /* Requires CAP_NET_ADMIN privilege. */
 	  .policy = flow_policy,
 	  .doit = ovs_flow_cmd_new
 	},
 	{ .cmd = OVS_FLOW_CMD_DEL,
-	  .flags = GENL_ADMIN_PERM, /* Requires CAP_NET_ADMIN privilege. */
+	  .flags = GENL_UNS_ADMIN_PERM, /* Requires CAP_NET_ADMIN privilege. */
 	  .policy = flow_policy,
 	  .doit = ovs_flow_cmd_del
 	},
@@ -1410,7 +1407,7 @@ static const struct genl_ops dp_flow_gen
 	  .dumpit = ovs_flow_cmd_dump
 	},
 	{ .cmd = OVS_FLOW_CMD_SET,
-	  .flags = GENL_ADMIN_PERM, /* Requires CAP_NET_ADMIN privilege. */
+	  .flags = GENL_UNS_ADMIN_PERM, /* Requires CAP_NET_ADMIN privilege. */
 	  .policy = flow_policy,
 	  .doit = ovs_flow_cmd_set,
 	},
@@ -1780,12 +1777,12 @@ static const struct nla_policy datapath_
 
 static const struct genl_ops dp_datapath_genl_ops[] = {
 	{ .cmd = OVS_DP_CMD_NEW,
-	  .flags = GENL_ADMIN_PERM, /* Requires CAP_NET_ADMIN privilege. */
+	  .flags = GENL_UNS_ADMIN_PERM, /* Requires CAP_NET_ADMIN privilege. */
 	  .policy = datapath_policy,
 	  .doit = ovs_dp_cmd_new
 	},
 	{ .cmd = OVS_DP_CMD_DEL,
-	  .flags = GENL_ADMIN_PERM, /* Requires CAP_NET_ADMIN privilege. */
+	  .flags = GENL_UNS_ADMIN_PERM, /* Requires CAP_NET_ADMIN privilege. */
 	  .policy = datapath_policy,
 	  .doit = ovs_dp_cmd_del
 	},
@@ -1796,7 +1793,7 @@ static const struct genl_ops dp_datapath
 	  .dumpit = ovs_dp_cmd_dump
 	},
 	{ .cmd = OVS_DP_CMD_SET,
-	  .flags = GENL_ADMIN_PERM, /* Requires CAP_NET_ADMIN privilege. */
+	  .flags = GENL_UNS_ADMIN_PERM, /* Requires CAP_NET_ADMIN privilege. */
 	  .policy = datapath_policy,
 	  .doit = ovs_dp_cmd_set,
 	},
@@ -2161,12 +2158,12 @@ static const struct nla_policy vport_pol
 
 static const struct genl_ops dp_vport_genl_ops[] = {
 	{ .cmd = OVS_VPORT_CMD_NEW,
-	  .flags = GENL_ADMIN_PERM, /* Requires CAP_NET_ADMIN privilege. */
+	  .flags = GENL_UNS_ADMIN_PERM, /* Requires CAP_NET_ADMIN privilege. */
 	  .policy = vport_policy,
 	  .doit = ovs_vport_cmd_new
 	},
 	{ .cmd = OVS_VPORT_CMD_DEL,
-	  .flags = GENL_ADMIN_PERM, /* Requires CAP_NET_ADMIN privilege. */
+	  .flags = GENL_UNS_ADMIN_PERM, /* Requires CAP_NET_ADMIN privilege. */
 	  .policy = vport_policy,
 	  .doit = ovs_vport_cmd_del
 	},
@@ -2177,7 +2174,7 @@ static const struct genl_ops dp_vport_ge
 	  .dumpit = ovs_vport_cmd_dump
 	},
 	{ .cmd = OVS_VPORT_CMD_SET,
-	  .flags = GENL_ADMIN_PERM, /* Requires CAP_NET_ADMIN privilege. */
+	  .flags = GENL_UNS_ADMIN_PERM, /* Requires CAP_NET_ADMIN privilege. */
 	  .policy = vport_policy,
 	  .doit = ovs_vport_cmd_set,
 	},
--- zfcpdump-kernel-4.4.orig/net/openvswitch/vport-netdev.c
+++ zfcpdump-kernel-4.4/net/openvswitch/vport-netdev.c
@@ -58,7 +58,7 @@ static void netdev_port_receive(struct s
 		return;
 
 	skb_push(skb, ETH_HLEN);
-	ovs_skb_postpush_rcsum(skb, skb->data, ETH_HLEN);
+	skb_postpush_rcsum(skb, skb->data, ETH_HLEN);
 	ovs_vport_receive(vport, skb, skb_tunnel_info(skb));
 	return;
 error:
--- zfcpdump-kernel-4.4.orig/net/openvswitch/vport-vxlan.c
+++ zfcpdump-kernel-4.4/net/openvswitch/vport-vxlan.c
@@ -90,7 +90,9 @@ static struct vport *vxlan_tnl_create(co
 	int err;
 	struct vxlan_config conf = {
 		.no_share = true,
-		.flags = VXLAN_F_COLLECT_METADATA,
+		.flags = VXLAN_F_COLLECT_METADATA | VXLAN_F_UDP_ZERO_CSUM6_RX,
+		/* Don't restrict the packets that can be sent by MTU */
+		.mtu = IP_MAX_MTU,
 	};
 
 	if (!options) {
--- zfcpdump-kernel-4.4.orig/net/openvswitch/vport.h
+++ zfcpdump-kernel-4.4/net/openvswitch/vport.h
@@ -184,13 +184,6 @@ static inline struct vport *vport_from_p
 int ovs_vport_receive(struct vport *, struct sk_buff *,
 		      const struct ip_tunnel_info *);
 
-static inline void ovs_skb_postpush_rcsum(struct sk_buff *skb,
-				      const void *start, unsigned int len)
-{
-	if (skb->ip_summed == CHECKSUM_COMPLETE)
-		skb->csum = csum_add(skb->csum, csum_partial(start, len, 0));
-}
-
 static inline const char *ovs_vport_name(struct vport *vport)
 {
 	return vport->dev->name;
--- zfcpdump-kernel-4.4.orig/net/packet/af_packet.c
+++ zfcpdump-kernel-4.4/net/packet/af_packet.c
@@ -1341,7 +1341,7 @@ static unsigned int fanout_demux_hash(st
 				      struct sk_buff *skb,
 				      unsigned int num)
 {
-	return reciprocal_scale(skb_get_hash(skb), num);
+	return reciprocal_scale(__skb_get_hash_symmetric(skb), num);
 }
 
 static unsigned int fanout_demux_lb(struct packet_fanout *f,
@@ -1916,6 +1916,10 @@ retry:
 		goto retry;
 	}
 
+	if (!dev_validate_header(dev, skb->data, len)) {
+		err = -EINVAL;
+		goto out_unlock;
+	}
 	if (len > (dev->mtu + dev->hard_header_len + extra_len) &&
 	    !packet_extra_vlan_len_allowed(dev, skb)) {
 		err = -EMSGSIZE;
@@ -2326,18 +2330,6 @@ static void tpacket_destruct_skb(struct
 	sock_wfree(skb);
 }
 
-static bool ll_header_truncated(const struct net_device *dev, int len)
-{
-	/* net device doesn't like empty head */
-	if (unlikely(len < dev->hard_header_len)) {
-		net_warn_ratelimited("%s: packet size is too short (%d < %d)\n",
-				     current->comm, len, dev->hard_header_len);
-		return true;
-	}
-
-	return false;
-}
-
 static void tpacket_set_protocol(const struct net_device *dev,
 				 struct sk_buff *skb)
 {
@@ -2420,19 +2412,19 @@ static int tpacket_fill_skb(struct packe
 		if (unlikely(err < 0))
 			return -EINVAL;
 	} else if (dev->hard_header_len) {
-		if (ll_header_truncated(dev, tp_len))
-			return -EINVAL;
+		int hdrlen = min_t(int, dev->hard_header_len, tp_len);
 
 		skb_push(skb, dev->hard_header_len);
-		err = skb_store_bits(skb, 0, data,
-				dev->hard_header_len);
+		err = skb_store_bits(skb, 0, data, hdrlen);
 		if (unlikely(err))
 			return err;
+		if (!dev_validate_header(dev, skb->data, hdrlen))
+			return -EINVAL;
 		if (!skb->protocol)
 			tpacket_set_protocol(dev, skb);
 
-		data += dev->hard_header_len;
-		to_write -= dev->hard_header_len;
+		data += hdrlen;
+		to_write -= hdrlen;
 	}
 
 	offset = offset_in_page(data);
@@ -2763,9 +2755,6 @@ static int packet_snd(struct socket *soc
 		offset = dev_hard_header(skb, dev, ntohs(proto), addr, NULL, len);
 		if (unlikely(offset < 0))
 			goto out_free;
-	} else {
-		if (ll_header_truncated(dev, len))
-			goto out_free;
 	}
 
 	/* Returns -EFAULT on error */
@@ -2773,6 +2762,12 @@ static int packet_snd(struct socket *soc
 	if (err)
 		goto out_free;
 
+	if (sock->type == SOCK_RAW &&
+	    !dev_validate_header(dev, skb->data, len)) {
+		err = -EINVAL;
+		goto out_free;
+	}
+
 	sock_tx_timestamp(sk, &skb_shinfo(skb)->tx_flags);
 
 	if (!gso_type && (len > dev->mtu + reserve + extra_len) &&
@@ -3441,6 +3436,7 @@ static int packet_mc_add(struct sock *sk
 	i->ifindex = mreq->mr_ifindex;
 	i->alen = mreq->mr_alen;
 	memcpy(i->addr, mreq->mr_address, i->alen);
+	memset(i->addr + i->alen, 0, sizeof(i->addr) - i->alen);
 	i->count = 1;
 	i->next = po->mclist;
 	po->mclist = i;
--- zfcpdump-kernel-4.4.orig/net/phonet/af_phonet.c
+++ zfcpdump-kernel-4.4/net/phonet/af_phonet.c
@@ -377,6 +377,10 @@ static int phonet_rcv(struct sk_buff *sk
 	struct sockaddr_pn sa;
 	u16 len;
 
+	skb = skb_share_check(skb, GFP_ATOMIC);
+	if (!skb)
+		return NET_RX_DROP;
+
 	/* check we have at least a full Phonet header */
 	if (!pskb_pull(skb, sizeof(struct phonethdr)))
 		goto out;
--- zfcpdump-kernel-4.4.orig/net/rds/ib_send.c
+++ zfcpdump-kernel-4.4/net/rds/ib_send.c
@@ -502,7 +502,7 @@ int rds_ib_xmit(struct rds_connection *c
 	int flow_controlled = 0;
 	int nr_sig = 0;
 
-	BUG_ON(off % RDS_FRAG_SIZE);
+	BUG_ON(!conn->c_loopback && off % RDS_FRAG_SIZE);
 	BUG_ON(hdr_off != 0 && hdr_off != sizeof(struct rds_header));
 
 	/* Do not send cong updates to IB loopback */
--- zfcpdump-kernel-4.4.orig/net/rds/recv.c
+++ zfcpdump-kernel-4.4/net/rds/recv.c
@@ -545,5 +545,7 @@ void rds_inc_info_copy(struct rds_incomi
 		minfo.fport = inc->i_hdr.h_dport;
 	}
 
+	minfo.flags = 0;
+
 	rds_info_copy(iter, &minfo, sizeof(minfo));
 }
--- zfcpdump-kernel-4.4.orig/net/rds/tcp.c
+++ zfcpdump-kernel-4.4/net/rds/tcp.c
@@ -421,7 +421,7 @@ static int rds_tcp_init(void)
 
 	ret = rds_tcp_recv_init();
 	if (ret)
-		goto out_slab;
+		goto out_pernet;
 
 	ret = rds_trans_register(&rds_tcp_transport);
 	if (ret)
@@ -433,8 +433,9 @@ static int rds_tcp_init(void)
 
 out_recv:
 	rds_tcp_recv_exit();
-out_slab:
+out_pernet:
 	unregister_pernet_subsys(&rds_tcp_net_ops);
+out_slab:
 	kmem_cache_destroy(rds_tcp_conn_slab);
 out:
 	return ret;
--- zfcpdump-kernel-4.4.orig/net/rfkill/core.c
+++ zfcpdump-kernel-4.4/net/rfkill/core.c
@@ -1095,17 +1095,6 @@ static unsigned int rfkill_fop_poll(stru
 	return res;
 }
 
-static bool rfkill_readable(struct rfkill_data *data)
-{
-	bool r;
-
-	mutex_lock(&data->mtx);
-	r = !list_empty(&data->events);
-	mutex_unlock(&data->mtx);
-
-	return r;
-}
-
 static ssize_t rfkill_fop_read(struct file *file, char __user *buf,
 			       size_t count, loff_t *pos)
 {
@@ -1122,8 +1111,11 @@ static ssize_t rfkill_fop_read(struct fi
 			goto out;
 		}
 		mutex_unlock(&data->mtx);
+		/* since we re-check and it just compares pointers,
+		 * using !list_empty() without locking isn't a problem
+		 */
 		ret = wait_event_interruptible(data->read_wait,
-					       rfkill_readable(data));
+					       !list_empty(&data->events));
 		mutex_lock(&data->mtx);
 
 		if (ret)
--- zfcpdump-kernel-4.4.orig/net/sched/act_csum.c
+++ zfcpdump-kernel-4.4/net/sched/act_csum.c
@@ -105,9 +105,7 @@ static void *tcf_csum_skb_nextlayer(stru
 	int hl = ihl + jhl;
 
 	if (!pskb_may_pull(skb, ipl + ntkoff) || (ipl < hl) ||
-	    (skb_cloned(skb) &&
-	     !skb_clone_writable(skb, hl + ntkoff) &&
-	     pskb_expand_head(skb, 0, 0, GFP_ATOMIC)))
+	    skb_try_make_writable(skb, hl + ntkoff))
 		return NULL;
 	else
 		return (void *)(skb_network_header(skb) + ihl);
@@ -365,9 +363,7 @@ static int tcf_csum_ipv4(struct sk_buff
 	}
 
 	if (update_flags & TCA_CSUM_UPDATE_FLAG_IPV4HDR) {
-		if (skb_cloned(skb) &&
-		    !skb_clone_writable(skb, sizeof(*iph) + ntkoff) &&
-		    pskb_expand_head(skb, 0, 0, GFP_ATOMIC))
+		if (skb_try_make_writable(skb, sizeof(*iph) + ntkoff))
 			goto fail;
 
 		ip_send_check(ip_hdr(skb));
--- zfcpdump-kernel-4.4.orig/net/sched/act_mirred.c
+++ zfcpdump-kernel-4.4/net/sched/act_mirred.c
@@ -170,7 +170,7 @@ static int tcf_mirred(struct sk_buff *sk
 
 	if (!(at & AT_EGRESS)) {
 		if (m->tcfm_ok_push)
-			skb_push(skb2, skb->mac_len);
+			skb_push_rcsum(skb2, skb->mac_len);
 	}
 
 	/* mirror is always swallowed */
--- zfcpdump-kernel-4.4.orig/net/sched/act_nat.c
+++ zfcpdump-kernel-4.4/net/sched/act_nat.c
@@ -126,9 +126,7 @@ static int tcf_nat(struct sk_buff *skb,
 		addr = iph->daddr;
 
 	if (!((old_addr ^ addr) & mask)) {
-		if (skb_cloned(skb) &&
-		    !skb_clone_writable(skb, sizeof(*iph) + noff) &&
-		    pskb_expand_head(skb, 0, 0, GFP_ATOMIC))
+		if (skb_try_make_writable(skb, sizeof(*iph) + noff))
 			goto drop;
 
 		new_addr &= mask;
@@ -156,9 +154,7 @@ static int tcf_nat(struct sk_buff *skb,
 		struct tcphdr *tcph;
 
 		if (!pskb_may_pull(skb, ihl + sizeof(*tcph) + noff) ||
-		    (skb_cloned(skb) &&
-		     !skb_clone_writable(skb, ihl + sizeof(*tcph) + noff) &&
-		     pskb_expand_head(skb, 0, 0, GFP_ATOMIC)))
+		    skb_try_make_writable(skb, ihl + sizeof(*tcph) + noff))
 			goto drop;
 
 		tcph = (void *)(skb_network_header(skb) + ihl);
@@ -171,9 +167,7 @@ static int tcf_nat(struct sk_buff *skb,
 		struct udphdr *udph;
 
 		if (!pskb_may_pull(skb, ihl + sizeof(*udph) + noff) ||
-		    (skb_cloned(skb) &&
-		     !skb_clone_writable(skb, ihl + sizeof(*udph) + noff) &&
-		     pskb_expand_head(skb, 0, 0, GFP_ATOMIC)))
+		    skb_try_make_writable(skb, ihl + sizeof(*udph) + noff))
 			goto drop;
 
 		udph = (void *)(skb_network_header(skb) + ihl);
@@ -213,10 +207,8 @@ static int tcf_nat(struct sk_buff *skb,
 		if ((old_addr ^ addr) & mask)
 			break;
 
-		if (skb_cloned(skb) &&
-		    !skb_clone_writable(skb, ihl + sizeof(*icmph) +
-					     sizeof(*iph) + noff) &&
-		    pskb_expand_head(skb, 0, 0, GFP_ATOMIC))
+		if (skb_try_make_writable(skb, ihl + sizeof(*icmph) +
+					  sizeof(*iph) + noff))
 			goto drop;
 
 		icmph = (void *)(skb_network_header(skb) + ihl);
--- zfcpdump-kernel-4.4.orig/net/sched/cls_flower.c
+++ zfcpdump-kernel-4.4/net/sched/cls_flower.c
@@ -252,23 +252,28 @@ static int fl_set_key(struct net *net, s
 	fl_set_key_val(tb, key->eth.src, TCA_FLOWER_KEY_ETH_SRC,
 		       mask->eth.src, TCA_FLOWER_KEY_ETH_SRC_MASK,
 		       sizeof(key->eth.src));
+
 	fl_set_key_val(tb, &key->basic.n_proto, TCA_FLOWER_KEY_ETH_TYPE,
 		       &mask->basic.n_proto, TCA_FLOWER_UNSPEC,
 		       sizeof(key->basic.n_proto));
+
 	if (key->basic.n_proto == htons(ETH_P_IP) ||
 	    key->basic.n_proto == htons(ETH_P_IPV6)) {
 		fl_set_key_val(tb, &key->basic.ip_proto, TCA_FLOWER_KEY_IP_PROTO,
 			       &mask->basic.ip_proto, TCA_FLOWER_UNSPEC,
 			       sizeof(key->basic.ip_proto));
 	}
-	if (key->control.addr_type == FLOW_DISSECTOR_KEY_IPV4_ADDRS) {
+
+	if (tb[TCA_FLOWER_KEY_IPV4_SRC] || tb[TCA_FLOWER_KEY_IPV4_DST]) {
+		key->control.addr_type = FLOW_DISSECTOR_KEY_IPV4_ADDRS;
 		fl_set_key_val(tb, &key->ipv4.src, TCA_FLOWER_KEY_IPV4_SRC,
 			       &mask->ipv4.src, TCA_FLOWER_KEY_IPV4_SRC_MASK,
 			       sizeof(key->ipv4.src));
 		fl_set_key_val(tb, &key->ipv4.dst, TCA_FLOWER_KEY_IPV4_DST,
 			       &mask->ipv4.dst, TCA_FLOWER_KEY_IPV4_DST_MASK,
 			       sizeof(key->ipv4.dst));
-	} else if (key->control.addr_type == FLOW_DISSECTOR_KEY_IPV6_ADDRS) {
+	} else if (tb[TCA_FLOWER_KEY_IPV6_SRC] || tb[TCA_FLOWER_KEY_IPV6_DST]) {
+		key->control.addr_type = FLOW_DISSECTOR_KEY_IPV6_ADDRS;
 		fl_set_key_val(tb, &key->ipv6.src, TCA_FLOWER_KEY_IPV6_SRC,
 			       &mask->ipv6.src, TCA_FLOWER_KEY_IPV6_SRC_MASK,
 			       sizeof(key->ipv6.src));
@@ -276,6 +281,7 @@ static int fl_set_key(struct net *net, s
 			       &mask->ipv6.dst, TCA_FLOWER_KEY_IPV6_DST_MASK,
 			       sizeof(key->ipv6.dst));
 	}
+
 	if (key->basic.ip_proto == IPPROTO_TCP) {
 		fl_set_key_val(tb, &key->tp.src, TCA_FLOWER_KEY_TCP_SRC,
 			       &mask->tp.src, TCA_FLOWER_UNSPEC,
--- zfcpdump-kernel-4.4.orig/net/sched/cls_u32.c
+++ zfcpdump-kernel-4.4/net/sched/cls_u32.c
@@ -43,6 +43,7 @@
 #include <net/netlink.h>
 #include <net/act_api.h>
 #include <net/pkt_cls.h>
+#include <linux/netdevice.h>
 
 struct tc_u_knode {
 	struct tc_u_knode __rcu	*next;
@@ -424,6 +425,93 @@ static int u32_delete_key(struct tcf_pro
 	return 0;
 }
 
+static void u32_remove_hw_knode(struct tcf_proto *tp, u32 handle)
+{
+	struct net_device *dev = tp->q->dev_queue->dev;
+	struct tc_cls_u32_offload u32_offload = {0};
+	struct tc_to_netdev offload;
+
+	offload.type = TC_SETUP_CLSU32;
+	offload.cls_u32 = &u32_offload;
+
+	if (dev->netdev_ops->ndo_setup_tc) {
+		offload.cls_u32->command = TC_CLSU32_DELETE_KNODE;
+		offload.cls_u32->knode.handle = handle;
+		dev->netdev_ops->ndo_setup_tc(dev, tp->q->handle,
+					      tp->protocol, &offload);
+	}
+}
+
+static void u32_replace_hw_hnode(struct tcf_proto *tp, struct tc_u_hnode *h)
+{
+	struct net_device *dev = tp->q->dev_queue->dev;
+	struct tc_cls_u32_offload u32_offload = {0};
+	struct tc_to_netdev offload;
+
+	offload.type = TC_SETUP_CLSU32;
+	offload.cls_u32 = &u32_offload;
+
+	if (dev->netdev_ops->ndo_setup_tc) {
+		offload.cls_u32->command = TC_CLSU32_NEW_HNODE;
+		offload.cls_u32->hnode.divisor = h->divisor;
+		offload.cls_u32->hnode.handle = h->handle;
+		offload.cls_u32->hnode.prio = h->prio;
+
+		dev->netdev_ops->ndo_setup_tc(dev, tp->q->handle,
+					      tp->protocol, &offload);
+	}
+}
+
+static void u32_clear_hw_hnode(struct tcf_proto *tp, struct tc_u_hnode *h)
+{
+	struct net_device *dev = tp->q->dev_queue->dev;
+	struct tc_cls_u32_offload u32_offload = {0};
+	struct tc_to_netdev offload;
+
+	offload.type = TC_SETUP_CLSU32;
+	offload.cls_u32 = &u32_offload;
+
+	if (dev->netdev_ops->ndo_setup_tc) {
+		offload.cls_u32->command = TC_CLSU32_DELETE_HNODE;
+		offload.cls_u32->hnode.divisor = h->divisor;
+		offload.cls_u32->hnode.handle = h->handle;
+		offload.cls_u32->hnode.prio = h->prio;
+
+		dev->netdev_ops->ndo_setup_tc(dev, tp->q->handle,
+					      tp->protocol, &offload);
+	}
+}
+
+static void u32_replace_hw_knode(struct tcf_proto *tp, struct tc_u_knode *n)
+{
+	struct net_device *dev = tp->q->dev_queue->dev;
+	struct tc_cls_u32_offload u32_offload = {0};
+	struct tc_to_netdev offload;
+
+	offload.type = TC_SETUP_CLSU32;
+	offload.cls_u32 = &u32_offload;
+
+	if (dev->netdev_ops->ndo_setup_tc) {
+		offload.cls_u32->command = TC_CLSU32_REPLACE_KNODE;
+		offload.cls_u32->knode.handle = n->handle;
+		offload.cls_u32->knode.fshift = n->fshift;
+#ifdef CONFIG_CLS_U32_MARK
+		offload.cls_u32->knode.val = n->val;
+		offload.cls_u32->knode.mask = n->mask;
+#else
+		offload.cls_u32->knode.val = 0;
+		offload.cls_u32->knode.mask = 0;
+#endif
+		offload.cls_u32->knode.sel = &n->sel;
+		offload.cls_u32->knode.exts = &n->exts;
+		if (n->ht_down)
+			offload.cls_u32->knode.link_handle = n->ht_down->handle;
+
+		dev->netdev_ops->ndo_setup_tc(dev, tp->q->handle,
+					      tp->protocol, &offload);
+	}
+}
+
 static void u32_clear_hnode(struct tcf_proto *tp, struct tc_u_hnode *ht)
 {
 	struct tc_u_knode *n;
@@ -434,6 +522,7 @@ static void u32_clear_hnode(struct tcf_p
 			RCU_INIT_POINTER(ht->ht[h],
 					 rtnl_dereference(n->next));
 			tcf_unbind_filter(tp, &n->res);
+			u32_remove_hw_knode(tp, n->handle);
 			call_rcu(&n->rcu, u32_delete_key_freepf_rcu);
 		}
 	}
@@ -454,6 +543,7 @@ static int u32_destroy_hnode(struct tcf_
 	     phn;
 	     hn = &phn->next, phn = rtnl_dereference(*hn)) {
 		if (phn == ht) {
+			u32_clear_hw_hnode(tp, ht);
 			RCU_INIT_POINTER(*hn, ht->next);
 			kfree_rcu(ht, rcu);
 			return 0;
@@ -540,8 +630,10 @@ static int u32_delete(struct tcf_proto *
 	if (ht == NULL)
 		return 0;
 
-	if (TC_U32_KEY(ht->handle))
+	if (TC_U32_KEY(ht->handle)) {
+		u32_remove_hw_knode(tp, ht->handle);
 		return u32_delete_key(tp, (struct tc_u_knode *)ht);
+	}
 
 	if (root_ht == ht)
 		return -EINVAL;
@@ -769,6 +861,7 @@ static int u32_change(struct net *net, s
 		u32_replace_knode(tp, tp_c, new);
 		tcf_unbind_filter(tp, &n->res);
 		call_rcu(&n->rcu, u32_delete_key_rcu);
+		u32_replace_hw_knode(tp, new);
 		return 0;
 	}
 
@@ -795,6 +888,8 @@ static int u32_change(struct net *net, s
 		RCU_INIT_POINTER(ht->next, tp_c->hlist);
 		rcu_assign_pointer(tp_c->hlist, ht);
 		*arg = (unsigned long)ht;
+
+		u32_replace_hw_hnode(tp, ht);
 		return 0;
 	}
 
@@ -877,7 +972,7 @@ static int u32_change(struct net *net, s
 
 		RCU_INIT_POINTER(n->next, pins);
 		rcu_assign_pointer(*ins, n);
-
+		u32_replace_hw_knode(tp, n);
 		*arg = (unsigned long)n;
 		return 0;
 	}
--- zfcpdump-kernel-4.4.orig/net/sched/sch_api.c
+++ zfcpdump-kernel-4.4/net/sched/sch_api.c
@@ -744,14 +744,15 @@ static u32 qdisc_alloc_handle(struct net
 	return 0;
 }
 
-void qdisc_tree_decrease_qlen(struct Qdisc *sch, unsigned int n)
+void qdisc_tree_reduce_backlog(struct Qdisc *sch, unsigned int n,
+			       unsigned int len)
 {
 	const struct Qdisc_class_ops *cops;
 	unsigned long cl;
 	u32 parentid;
 	int drops;
 
-	if (n == 0)
+	if (n == 0 && len == 0)
 		return;
 	drops = max_t(int, n, 0);
 	rcu_read_lock();
@@ -774,11 +775,12 @@ void qdisc_tree_decrease_qlen(struct Qdi
 			cops->put(sch, cl);
 		}
 		sch->q.qlen -= n;
+		sch->qstats.backlog -= len;
 		__qdisc_qstats_drop(sch, drops);
 	}
 	rcu_read_unlock();
 }
-EXPORT_SYMBOL(qdisc_tree_decrease_qlen);
+EXPORT_SYMBOL(qdisc_tree_reduce_backlog);
 
 static void notify_and_destroy(struct net *net, struct sk_buff *skb,
 			       struct nlmsghdr *n, u32 clid,
@@ -1852,6 +1854,7 @@ reset:
 	}
 
 	tp = old_tp;
+	protocol = tc_skb_protocol(skb);
 	goto reclassify;
 #endif
 }
--- zfcpdump-kernel-4.4.orig/net/sched/sch_cbq.c
+++ zfcpdump-kernel-4.4/net/sched/sch_cbq.c
@@ -1624,13 +1624,8 @@ static int cbq_graft(struct Qdisc *sch,
 			new->reshape_fail = cbq_reshape_fail;
 #endif
 	}
-	sch_tree_lock(sch);
-	*old = cl->q;
-	cl->q = new;
-	qdisc_tree_decrease_qlen(*old, (*old)->q.qlen);
-	qdisc_reset(*old);
-	sch_tree_unlock(sch);
 
+	*old = qdisc_replace(sch, new, &cl->q);
 	return 0;
 }
 
@@ -1914,7 +1909,7 @@ static int cbq_delete(struct Qdisc *sch,
 {
 	struct cbq_sched_data *q = qdisc_priv(sch);
 	struct cbq_class *cl = (struct cbq_class *)arg;
-	unsigned int qlen;
+	unsigned int qlen, backlog;
 
 	if (cl->filters || cl->children || cl == &q->link)
 		return -EBUSY;
@@ -1922,8 +1917,9 @@ static int cbq_delete(struct Qdisc *sch,
 	sch_tree_lock(sch);
 
 	qlen = cl->q->q.qlen;
+	backlog = cl->q->qstats.backlog;
 	qdisc_reset(cl->q);
-	qdisc_tree_decrease_qlen(cl->q, qlen);
+	qdisc_tree_reduce_backlog(cl->q, qlen, backlog);
 
 	if (cl->next_alive)
 		cbq_deactivate_class(cl);
--- zfcpdump-kernel-4.4.orig/net/sched/sch_choke.c
+++ zfcpdump-kernel-4.4/net/sched/sch_choke.c
@@ -128,8 +128,8 @@ static void choke_drop_by_idx(struct Qdi
 		choke_zap_tail_holes(q);
 
 	qdisc_qstats_backlog_dec(sch, skb);
+	qdisc_tree_reduce_backlog(sch, 1, qdisc_pkt_len(skb));
 	qdisc_drop(skb, sch);
-	qdisc_tree_decrease_qlen(sch, 1);
 	--sch->q.qlen;
 }
 
@@ -456,6 +456,7 @@ static int choke_change(struct Qdisc *sc
 		old = q->tab;
 		if (old) {
 			unsigned int oqlen = sch->q.qlen, tail = 0;
+			unsigned dropped = 0;
 
 			while (q->head != q->tail) {
 				struct sk_buff *skb = q->tab[q->head];
@@ -467,11 +468,12 @@ static int choke_change(struct Qdisc *sc
 					ntab[tail++] = skb;
 					continue;
 				}
+				dropped += qdisc_pkt_len(skb);
 				qdisc_qstats_backlog_dec(sch, skb);
 				--sch->q.qlen;
 				qdisc_drop(skb, sch);
 			}
-			qdisc_tree_decrease_qlen(sch, oqlen - sch->q.qlen);
+			qdisc_tree_reduce_backlog(sch, oqlen - sch->q.qlen, dropped);
 			q->head = 0;
 			q->tail = tail;
 		}
--- zfcpdump-kernel-4.4.orig/net/sched/sch_codel.c
+++ zfcpdump-kernel-4.4/net/sched/sch_codel.c
@@ -79,12 +79,13 @@ static struct sk_buff *codel_qdisc_deque
 
 	skb = codel_dequeue(sch, &q->params, &q->vars, &q->stats, dequeue);
 
-	/* We cant call qdisc_tree_decrease_qlen() if our qlen is 0,
+	/* We cant call qdisc_tree_reduce_backlog() if our qlen is 0,
 	 * or HTB crashes. Defer it for next round.
 	 */
 	if (q->stats.drop_count && sch->q.qlen) {
-		qdisc_tree_decrease_qlen(sch, q->stats.drop_count);
+		qdisc_tree_reduce_backlog(sch, q->stats.drop_count, q->stats.drop_len);
 		q->stats.drop_count = 0;
+		q->stats.drop_len = 0;
 	}
 	if (skb)
 		qdisc_bstats_update(sch, skb);
@@ -116,7 +117,7 @@ static int codel_change(struct Qdisc *sc
 {
 	struct codel_sched_data *q = qdisc_priv(sch);
 	struct nlattr *tb[TCA_CODEL_MAX + 1];
-	unsigned int qlen;
+	unsigned int qlen, dropped = 0;
 	int err;
 
 	if (!opt)
@@ -156,10 +157,11 @@ static int codel_change(struct Qdisc *sc
 	while (sch->q.qlen > sch->limit) {
 		struct sk_buff *skb = __skb_dequeue(&sch->q);
 
+		dropped += qdisc_pkt_len(skb);
 		qdisc_qstats_backlog_dec(sch, skb);
 		qdisc_drop(skb, sch);
 	}
-	qdisc_tree_decrease_qlen(sch, qlen - sch->q.qlen);
+	qdisc_tree_reduce_backlog(sch, qlen - sch->q.qlen, dropped);
 
 	sch_tree_unlock(sch);
 	return 0;
--- zfcpdump-kernel-4.4.orig/net/sched/sch_drr.c
+++ zfcpdump-kernel-4.4/net/sched/sch_drr.c
@@ -53,9 +53,10 @@ static struct drr_class *drr_find_class(
 static void drr_purge_queue(struct drr_class *cl)
 {
 	unsigned int len = cl->qdisc->q.qlen;
+	unsigned int backlog = cl->qdisc->qstats.backlog;
 
 	qdisc_reset(cl->qdisc);
-	qdisc_tree_decrease_qlen(cl->qdisc, len);
+	qdisc_tree_reduce_backlog(cl->qdisc, len, backlog);
 }
 
 static const struct nla_policy drr_policy[TCA_DRR_MAX + 1] = {
@@ -226,11 +227,7 @@ static int drr_graft_class(struct Qdisc
 			new = &noop_qdisc;
 	}
 
-	sch_tree_lock(sch);
-	drr_purge_queue(cl);
-	*old = cl->qdisc;
-	cl->qdisc = new;
-	sch_tree_unlock(sch);
+	*old = qdisc_replace(sch, new, &cl->qdisc);
 	return 0;
 }
 
--- zfcpdump-kernel-4.4.orig/net/sched/sch_dsmark.c
+++ zfcpdump-kernel-4.4/net/sched/sch_dsmark.c
@@ -73,13 +73,7 @@ static int dsmark_graft(struct Qdisc *sc
 			new = &noop_qdisc;
 	}
 
-	sch_tree_lock(sch);
-	*old = p->q;
-	p->q = new;
-	qdisc_tree_decrease_qlen(*old, (*old)->q.qlen);
-	qdisc_reset(*old);
-	sch_tree_unlock(sch);
-
+	*old = qdisc_replace(sch, new, &p->q);
 	return 0;
 }
 
@@ -264,6 +258,7 @@ static int dsmark_enqueue(struct sk_buff
 		return err;
 	}
 
+	qdisc_qstats_backlog_inc(sch, skb);
 	sch->q.qlen++;
 
 	return NET_XMIT_SUCCESS;
@@ -286,6 +281,7 @@ static struct sk_buff *dsmark_dequeue(st
 		return NULL;
 
 	qdisc_bstats_update(sch, skb);
+	qdisc_qstats_backlog_dec(sch, skb);
 	sch->q.qlen--;
 
 	index = skb->tc_index & (p->indices - 1);
@@ -401,6 +397,7 @@ static void dsmark_reset(struct Qdisc *s
 
 	pr_debug("%s(sch %p,[qdisc %p])\n", __func__, sch, p);
 	qdisc_reset(p->q);
+	sch->qstats.backlog = 0;
 	sch->q.qlen = 0;
 }
 
--- zfcpdump-kernel-4.4.orig/net/sched/sch_fifo.c
+++ zfcpdump-kernel-4.4/net/sched/sch_fifo.c
@@ -37,14 +37,18 @@ static int pfifo_enqueue(struct sk_buff
 
 static int pfifo_tail_enqueue(struct sk_buff *skb, struct Qdisc *sch)
 {
+	unsigned int prev_backlog;
+
 	if (likely(skb_queue_len(&sch->q) < sch->limit))
 		return qdisc_enqueue_tail(skb, sch);
 
+	prev_backlog = sch->qstats.backlog;
 	/* queue full, remove one skb to fulfill the limit */
 	__qdisc_queue_drop_head(sch, &sch->q);
 	qdisc_qstats_drop(sch);
 	qdisc_enqueue_tail(skb, sch);
 
+	qdisc_tree_reduce_backlog(sch, 0, prev_backlog - sch->qstats.backlog);
 	return NET_XMIT_CN;
 }
 
--- zfcpdump-kernel-4.4.orig/net/sched/sch_fq.c
+++ zfcpdump-kernel-4.4/net/sched/sch_fq.c
@@ -662,6 +662,7 @@ static int fq_change(struct Qdisc *sch,
 	struct fq_sched_data *q = qdisc_priv(sch);
 	struct nlattr *tb[TCA_FQ_MAX + 1];
 	int err, drop_count = 0;
+	unsigned drop_len = 0;
 	u32 fq_log;
 
 	if (!opt)
@@ -736,10 +737,11 @@ static int fq_change(struct Qdisc *sch,
 
 		if (!skb)
 			break;
+		drop_len += qdisc_pkt_len(skb);
 		kfree_skb(skb);
 		drop_count++;
 	}
-	qdisc_tree_decrease_qlen(sch, drop_count);
+	qdisc_tree_reduce_backlog(sch, drop_count, drop_len);
 
 	sch_tree_unlock(sch);
 	return err;
--- zfcpdump-kernel-4.4.orig/net/sched/sch_fq_codel.c
+++ zfcpdump-kernel-4.4/net/sched/sch_fq_codel.c
@@ -175,7 +175,7 @@ static unsigned int fq_codel_qdisc_drop(
 static int fq_codel_enqueue(struct sk_buff *skb, struct Qdisc *sch)
 {
 	struct fq_codel_sched_data *q = qdisc_priv(sch);
-	unsigned int idx;
+	unsigned int idx, prev_backlog;
 	struct fq_codel_flow *flow;
 	int uninitialized_var(ret);
 
@@ -203,6 +203,7 @@ static int fq_codel_enqueue(struct sk_bu
 	if (++sch->q.qlen <= sch->limit)
 		return NET_XMIT_SUCCESS;
 
+	prev_backlog = sch->qstats.backlog;
 	q->drop_overlimit++;
 	/* Return Congestion Notification only if we dropped a packet
 	 * from this flow.
@@ -211,7 +212,7 @@ static int fq_codel_enqueue(struct sk_bu
 		return NET_XMIT_CN;
 
 	/* As we dropped a packet, better let upper stack know this */
-	qdisc_tree_decrease_qlen(sch, 1);
+	qdisc_tree_reduce_backlog(sch, 1, prev_backlog - sch->qstats.backlog);
 	return NET_XMIT_SUCCESS;
 }
 
@@ -241,6 +242,7 @@ static struct sk_buff *fq_codel_dequeue(
 	struct fq_codel_flow *flow;
 	struct list_head *head;
 	u32 prev_drop_count, prev_ecn_mark;
+	unsigned int prev_backlog;
 
 begin:
 	head = &q->new_flows;
@@ -259,6 +261,7 @@ begin:
 
 	prev_drop_count = q->cstats.drop_count;
 	prev_ecn_mark = q->cstats.ecn_mark;
+	prev_backlog = sch->qstats.backlog;
 
 	skb = codel_dequeue(sch, &q->cparams, &flow->cvars, &q->cstats,
 			    dequeue);
@@ -276,12 +279,14 @@ begin:
 	}
 	qdisc_bstats_update(sch, skb);
 	flow->deficit -= qdisc_pkt_len(skb);
-	/* We cant call qdisc_tree_decrease_qlen() if our qlen is 0,
+	/* We cant call qdisc_tree_reduce_backlog() if our qlen is 0,
 	 * or HTB crashes. Defer it for next round.
 	 */
 	if (q->cstats.drop_count && sch->q.qlen) {
-		qdisc_tree_decrease_qlen(sch, q->cstats.drop_count);
+		qdisc_tree_reduce_backlog(sch, q->cstats.drop_count,
+					  q->cstats.drop_len);
 		q->cstats.drop_count = 0;
+		q->cstats.drop_len = 0;
 	}
 	return skb;
 }
@@ -372,11 +377,13 @@ static int fq_codel_change(struct Qdisc
 	while (sch->q.qlen > sch->limit) {
 		struct sk_buff *skb = fq_codel_dequeue(sch);
 
+		q->cstats.drop_len += qdisc_pkt_len(skb);
 		kfree_skb(skb);
 		q->cstats.drop_count++;
 	}
-	qdisc_tree_decrease_qlen(sch, q->cstats.drop_count);
+	qdisc_tree_reduce_backlog(sch, q->cstats.drop_count, q->cstats.drop_len);
 	q->cstats.drop_count = 0;
+	q->cstats.drop_len = 0;
 
 	sch_tree_unlock(sch);
 	return 0;
--- zfcpdump-kernel-4.4.orig/net/sched/sch_generic.c
+++ zfcpdump-kernel-4.4/net/sched/sch_generic.c
@@ -159,12 +159,15 @@ int sch_direct_xmit(struct sk_buff *skb,
 	if (validate)
 		skb = validate_xmit_skb_list(skb, dev);
 
-	if (skb) {
+	if (likely(skb)) {
 		HARD_TX_LOCK(dev, txq, smp_processor_id());
 		if (!netif_xmit_frozen_or_stopped(txq))
 			skb = dev_hard_start_xmit(skb, dev, txq, &ret);
 
 		HARD_TX_UNLOCK(dev, txq);
+	} else {
+		spin_lock(root_lock);
+		return qdisc_qlen(q);
 	}
 	spin_lock(root_lock);
 
--- zfcpdump-kernel-4.4.orig/net/sched/sch_hfsc.c
+++ zfcpdump-kernel-4.4/net/sched/sch_hfsc.c
@@ -895,9 +895,10 @@ static void
 hfsc_purge_queue(struct Qdisc *sch, struct hfsc_class *cl)
 {
 	unsigned int len = cl->qdisc->q.qlen;
+	unsigned int backlog = cl->qdisc->qstats.backlog;
 
 	qdisc_reset(cl->qdisc);
-	qdisc_tree_decrease_qlen(cl->qdisc, len);
+	qdisc_tree_reduce_backlog(cl->qdisc, len, backlog);
 }
 
 static void
@@ -1215,11 +1216,7 @@ hfsc_graft_class(struct Qdisc *sch, unsi
 			new = &noop_qdisc;
 	}
 
-	sch_tree_lock(sch);
-	hfsc_purge_queue(sch, cl);
-	*old = cl->qdisc;
-	cl->qdisc = new;
-	sch_tree_unlock(sch);
+	*old = qdisc_replace(sch, new, &cl->qdisc);
 	return 0;
 }
 
--- zfcpdump-kernel-4.4.orig/net/sched/sch_hhf.c
+++ zfcpdump-kernel-4.4/net/sched/sch_hhf.c
@@ -382,6 +382,7 @@ static int hhf_enqueue(struct sk_buff *s
 	struct hhf_sched_data *q = qdisc_priv(sch);
 	enum wdrr_bucket_idx idx;
 	struct wdrr_bucket *bucket;
+	unsigned int prev_backlog;
 
 	idx = hhf_classify(skb, sch);
 
@@ -409,6 +410,7 @@ static int hhf_enqueue(struct sk_buff *s
 	if (++sch->q.qlen <= sch->limit)
 		return NET_XMIT_SUCCESS;
 
+	prev_backlog = sch->qstats.backlog;
 	q->drop_overlimit++;
 	/* Return Congestion Notification only if we dropped a packet from this
 	 * bucket.
@@ -417,7 +419,7 @@ static int hhf_enqueue(struct sk_buff *s
 		return NET_XMIT_CN;
 
 	/* As we dropped a packet, better let upper stack know this. */
-	qdisc_tree_decrease_qlen(sch, 1);
+	qdisc_tree_reduce_backlog(sch, 1, prev_backlog - sch->qstats.backlog);
 	return NET_XMIT_SUCCESS;
 }
 
@@ -527,7 +529,7 @@ static int hhf_change(struct Qdisc *sch,
 {
 	struct hhf_sched_data *q = qdisc_priv(sch);
 	struct nlattr *tb[TCA_HHF_MAX + 1];
-	unsigned int qlen;
+	unsigned int qlen, prev_backlog;
 	int err;
 	u64 non_hh_quantum;
 	u32 new_quantum = q->quantum;
@@ -577,12 +579,14 @@ static int hhf_change(struct Qdisc *sch,
 	}
 
 	qlen = sch->q.qlen;
+	prev_backlog = sch->qstats.backlog;
 	while (sch->q.qlen > sch->limit) {
 		struct sk_buff *skb = hhf_dequeue(sch);
 
 		kfree_skb(skb);
 	}
-	qdisc_tree_decrease_qlen(sch, qlen - sch->q.qlen);
+	qdisc_tree_reduce_backlog(sch, qlen - sch->q.qlen,
+				  prev_backlog - sch->qstats.backlog);
 
 	sch_tree_unlock(sch);
 	return 0;
--- zfcpdump-kernel-4.4.orig/net/sched/sch_htb.c
+++ zfcpdump-kernel-4.4/net/sched/sch_htb.c
@@ -600,6 +600,7 @@ static int htb_enqueue(struct sk_buff *s
 		htb_activate(q, cl);
 	}
 
+	qdisc_qstats_backlog_inc(sch, skb);
 	sch->q.qlen++;
 	return NET_XMIT_SUCCESS;
 }
@@ -889,6 +890,7 @@ static struct sk_buff *htb_dequeue(struc
 ok:
 		qdisc_bstats_update(sch, skb);
 		qdisc_unthrottled(sch);
+		qdisc_qstats_backlog_dec(sch, skb);
 		sch->q.qlen--;
 		return skb;
 	}
@@ -955,6 +957,7 @@ static unsigned int htb_drop(struct Qdis
 			unsigned int len;
 			if (cl->un.leaf.q->ops->drop &&
 			    (len = cl->un.leaf.q->ops->drop(cl->un.leaf.q))) {
+				sch->qstats.backlog -= len;
 				sch->q.qlen--;
 				if (!cl->un.leaf.q->q.qlen)
 					htb_deactivate(q, cl);
@@ -984,12 +987,12 @@ static void htb_reset(struct Qdisc *sch)
 			}
 			cl->prio_activity = 0;
 			cl->cmode = HTB_CAN_SEND;
-
 		}
 	}
 	qdisc_watchdog_cancel(&q->watchdog);
 	__skb_queue_purge(&q->direct_queue);
 	sch->q.qlen = 0;
+	sch->qstats.backlog = 0;
 	memset(q->hlevel, 0, sizeof(q->hlevel));
 	memset(q->row_mask, 0, sizeof(q->row_mask));
 	for (i = 0; i < TC_HTB_NUMPRIO; i++)
@@ -1163,14 +1166,7 @@ static int htb_graft(struct Qdisc *sch,
 				     cl->common.classid)) == NULL)
 		return -ENOBUFS;
 
-	sch_tree_lock(sch);
-	*old = cl->un.leaf.q;
-	cl->un.leaf.q = new;
-	if (*old != NULL) {
-		qdisc_tree_decrease_qlen(*old, (*old)->q.qlen);
-		qdisc_reset(*old);
-	}
-	sch_tree_unlock(sch);
+	*old = qdisc_replace(sch, new, &cl->un.leaf.q);
 	return 0;
 }
 
@@ -1272,7 +1268,6 @@ static int htb_delete(struct Qdisc *sch,
 {
 	struct htb_sched *q = qdisc_priv(sch);
 	struct htb_class *cl = (struct htb_class *)arg;
-	unsigned int qlen;
 	struct Qdisc *new_q = NULL;
 	int last_child = 0;
 
@@ -1292,9 +1287,11 @@ static int htb_delete(struct Qdisc *sch,
 	sch_tree_lock(sch);
 
 	if (!cl->level) {
-		qlen = cl->un.leaf.q->q.qlen;
+		unsigned int qlen = cl->un.leaf.q->q.qlen;
+		unsigned int backlog = cl->un.leaf.q->qstats.backlog;
+
 		qdisc_reset(cl->un.leaf.q);
-		qdisc_tree_decrease_qlen(cl->un.leaf.q, qlen);
+		qdisc_tree_reduce_backlog(cl->un.leaf.q, qlen, backlog);
 	}
 
 	/* delete from hash and active; remainder in destroy_class */
@@ -1428,10 +1425,11 @@ static int htb_change_class(struct Qdisc
 		sch_tree_lock(sch);
 		if (parent && !parent->level) {
 			unsigned int qlen = parent->un.leaf.q->q.qlen;
+			unsigned int backlog = parent->un.leaf.q->qstats.backlog;
 
 			/* turn parent into inner node */
 			qdisc_reset(parent->un.leaf.q);
-			qdisc_tree_decrease_qlen(parent->un.leaf.q, qlen);
+			qdisc_tree_reduce_backlog(parent->un.leaf.q, qlen, backlog);
 			qdisc_destroy(parent->un.leaf.q);
 			if (parent->prio_activity)
 				htb_deactivate(q, parent);
--- zfcpdump-kernel-4.4.orig/net/sched/sch_mqprio.c
+++ zfcpdump-kernel-4.4/net/sched/sch_mqprio.c
@@ -28,6 +28,7 @@ static void mqprio_destroy(struct Qdisc
 {
 	struct net_device *dev = qdisc_dev(sch);
 	struct mqprio_sched *priv = qdisc_priv(sch);
+	struct tc_to_netdev tc = {.type = TC_SETUP_MQPRIO};
 	unsigned int ntx;
 
 	if (priv->qdiscs) {
@@ -39,7 +40,7 @@ static void mqprio_destroy(struct Qdisc
 	}
 
 	if (priv->hw_owned && dev->netdev_ops->ndo_setup_tc)
-		dev->netdev_ops->ndo_setup_tc(dev, 0);
+		dev->netdev_ops->ndo_setup_tc(dev, sch->handle, 0, &tc);
 	else
 		netdev_set_num_tc(dev, 0);
 }
@@ -140,8 +141,11 @@ static int mqprio_init(struct Qdisc *sch
 	 * supplied and verified mapping
 	 */
 	if (qopt->hw) {
+		struct tc_to_netdev tc = {.type = TC_SETUP_MQPRIO,
+					  .tc = qopt->num_tc};
+
 		priv->hw_owned = 1;
-		err = dev->netdev_ops->ndo_setup_tc(dev, qopt->num_tc);
+		err = dev->netdev_ops->ndo_setup_tc(dev, sch->handle, 0, &tc);
 		if (err)
 			goto err;
 	} else {
--- zfcpdump-kernel-4.4.orig/net/sched/sch_multiq.c
+++ zfcpdump-kernel-4.4/net/sched/sch_multiq.c
@@ -218,7 +218,8 @@ static int multiq_tune(struct Qdisc *sch
 		if (q->queues[i] != &noop_qdisc) {
 			struct Qdisc *child = q->queues[i];
 			q->queues[i] = &noop_qdisc;
-			qdisc_tree_decrease_qlen(child, child->q.qlen);
+			qdisc_tree_reduce_backlog(child, child->q.qlen,
+						  child->qstats.backlog);
 			qdisc_destroy(child);
 		}
 	}
@@ -238,8 +239,9 @@ static int multiq_tune(struct Qdisc *sch
 				q->queues[i] = child;
 
 				if (old != &noop_qdisc) {
-					qdisc_tree_decrease_qlen(old,
-								 old->q.qlen);
+					qdisc_tree_reduce_backlog(old,
+								  old->q.qlen,
+								  old->qstats.backlog);
 					qdisc_destroy(old);
 				}
 				sch_tree_unlock(sch);
@@ -303,13 +305,7 @@ static int multiq_graft(struct Qdisc *sc
 	if (new == NULL)
 		new = &noop_qdisc;
 
-	sch_tree_lock(sch);
-	*old = q->queues[band];
-	q->queues[band] = new;
-	qdisc_tree_decrease_qlen(*old, (*old)->q.qlen);
-	qdisc_reset(*old);
-	sch_tree_unlock(sch);
-
+	*old = qdisc_replace(sch, new, &q->queues[band]);
 	return 0;
 }
 
--- zfcpdump-kernel-4.4.orig/net/sched/sch_netem.c
+++ zfcpdump-kernel-4.4/net/sched/sch_netem.c
@@ -395,6 +395,25 @@ static void tfifo_enqueue(struct sk_buff
 	sch->q.qlen++;
 }
 
+/* netem can't properly corrupt a megapacket (like we get from GSO), so instead
+ * when we statistically choose to corrupt one, we instead segment it, returning
+ * the first packet to be corrupted, and re-enqueue the remaining frames
+ */
+static struct sk_buff *netem_segment(struct sk_buff *skb, struct Qdisc *sch)
+{
+	struct sk_buff *segs;
+	netdev_features_t features = netif_skb_features(skb);
+
+	segs = skb_gso_segment(skb, features & ~NETIF_F_GSO_MASK);
+
+	if (IS_ERR_OR_NULL(segs)) {
+		qdisc_reshape_fail(skb, sch);
+		return NULL;
+	}
+	consume_skb(skb);
+	return segs;
+}
+
 /*
  * Insert one skb into qdisc.
  * Note: parent depends on return value to account for queue length.
@@ -407,7 +426,11 @@ static int netem_enqueue(struct sk_buff
 	/* We don't fill cb now as skb_unshare() may invalidate it */
 	struct netem_skb_cb *cb;
 	struct sk_buff *skb2;
+	struct sk_buff *segs = NULL;
+	unsigned int len = 0, last_len, prev_len = qdisc_pkt_len(skb);
+	int nb = 0;
 	int count = 1;
+	int rc = NET_XMIT_SUCCESS;
 
 	/* Random duplication */
 	if (q->duplicate && q->duplicate >= get_crandom(&q->dup_cor))
@@ -453,10 +476,23 @@ static int netem_enqueue(struct sk_buff
 	 * do it now in software before we mangle it.
 	 */
 	if (q->corrupt && q->corrupt >= get_crandom(&q->corrupt_cor)) {
+		if (skb_is_gso(skb)) {
+			segs = netem_segment(skb, sch);
+			if (!segs)
+				return NET_XMIT_DROP;
+		} else {
+			segs = skb;
+		}
+
+		skb = segs;
+		segs = segs->next;
+
 		if (!(skb = skb_unshare(skb, GFP_ATOMIC)) ||
 		    (skb->ip_summed == CHECKSUM_PARTIAL &&
-		     skb_checksum_help(skb)))
-			return qdisc_drop(skb, sch);
+		     skb_checksum_help(skb))) {
+			rc = qdisc_drop(skb, sch);
+			goto finish_segs;
+		}
 
 		skb->data[prandom_u32() % skb_headlen(skb)] ^=
 			1<<(prandom_u32() % 8);
@@ -516,6 +552,27 @@ static int netem_enqueue(struct sk_buff
 		sch->qstats.requeues++;
 	}
 
+finish_segs:
+	if (segs) {
+		while (segs) {
+			skb2 = segs->next;
+			segs->next = NULL;
+			qdisc_skb_cb(segs)->pkt_len = segs->len;
+			last_len = segs->len;
+			rc = qdisc_enqueue(segs, sch);
+			if (rc != NET_XMIT_SUCCESS) {
+				if (net_xmit_drop_count(rc))
+					qdisc_qstats_drop(sch);
+			} else {
+				nb++;
+				len += last_len;
+			}
+			segs = skb2;
+		}
+		sch->q.qlen += nb;
+		if (nb > 1)
+			qdisc_tree_reduce_backlog(sch, 1 - nb, prev_len - len);
+	}
 	return NET_XMIT_SUCCESS;
 }
 
@@ -593,13 +650,14 @@ deliver:
 #endif
 
 			if (q->qdisc) {
+				unsigned int pkt_len = qdisc_pkt_len(skb);
 				int err = qdisc_enqueue(skb, q->qdisc);
 
-				if (unlikely(err != NET_XMIT_SUCCESS)) {
-					if (net_xmit_drop_count(err)) {
-						qdisc_qstats_drop(sch);
-						qdisc_tree_decrease_qlen(sch, 1);
-					}
+				if (err != NET_XMIT_SUCCESS &&
+				    net_xmit_drop_count(err)) {
+					qdisc_qstats_drop(sch);
+					qdisc_tree_reduce_backlog(sch, 1,
+								  pkt_len);
 				}
 				goto tfifo_dequeue;
 			}
@@ -1037,15 +1095,7 @@ static int netem_graft(struct Qdisc *sch
 {
 	struct netem_sched_data *q = qdisc_priv(sch);
 
-	sch_tree_lock(sch);
-	*old = q->qdisc;
-	q->qdisc = new;
-	if (*old) {
-		qdisc_tree_decrease_qlen(*old, (*old)->q.qlen);
-		qdisc_reset(*old);
-	}
-	sch_tree_unlock(sch);
-
+	*old = qdisc_replace(sch, new, &q->qdisc);
 	return 0;
 }
 
--- zfcpdump-kernel-4.4.orig/net/sched/sch_pie.c
+++ zfcpdump-kernel-4.4/net/sched/sch_pie.c
@@ -183,7 +183,7 @@ static int pie_change(struct Qdisc *sch,
 {
 	struct pie_sched_data *q = qdisc_priv(sch);
 	struct nlattr *tb[TCA_PIE_MAX + 1];
-	unsigned int qlen;
+	unsigned int qlen, dropped = 0;
 	int err;
 
 	if (!opt)
@@ -232,10 +232,11 @@ static int pie_change(struct Qdisc *sch,
 	while (sch->q.qlen > sch->limit) {
 		struct sk_buff *skb = __skb_dequeue(&sch->q);
 
+		dropped += qdisc_pkt_len(skb);
 		qdisc_qstats_backlog_dec(sch, skb);
 		qdisc_drop(skb, sch);
 	}
-	qdisc_tree_decrease_qlen(sch, qlen - sch->q.qlen);
+	qdisc_tree_reduce_backlog(sch, qlen - sch->q.qlen, dropped);
 
 	sch_tree_unlock(sch);
 	return 0;
--- zfcpdump-kernel-4.4.orig/net/sched/sch_prio.c
+++ zfcpdump-kernel-4.4/net/sched/sch_prio.c
@@ -191,7 +191,7 @@ static int prio_tune(struct Qdisc *sch,
 		struct Qdisc *child = q->queues[i];
 		q->queues[i] = &noop_qdisc;
 		if (child != &noop_qdisc) {
-			qdisc_tree_decrease_qlen(child, child->q.qlen);
+			qdisc_tree_reduce_backlog(child, child->q.qlen, child->qstats.backlog);
 			qdisc_destroy(child);
 		}
 	}
@@ -210,8 +210,9 @@ static int prio_tune(struct Qdisc *sch,
 				q->queues[i] = child;
 
 				if (old != &noop_qdisc) {
-					qdisc_tree_decrease_qlen(old,
-								 old->q.qlen);
+					qdisc_tree_reduce_backlog(old,
+								  old->q.qlen,
+								  old->qstats.backlog);
 					qdisc_destroy(old);
 				}
 				sch_tree_unlock(sch);
@@ -268,13 +269,7 @@ static int prio_graft(struct Qdisc *sch,
 	if (new == NULL)
 		new = &noop_qdisc;
 
-	sch_tree_lock(sch);
-	*old = q->queues[band];
-	q->queues[band] = new;
-	qdisc_tree_decrease_qlen(*old, (*old)->q.qlen);
-	qdisc_reset(*old);
-	sch_tree_unlock(sch);
-
+	*old = qdisc_replace(sch, new, &q->queues[band]);
 	return 0;
 }
 
--- zfcpdump-kernel-4.4.orig/net/sched/sch_qfq.c
+++ zfcpdump-kernel-4.4/net/sched/sch_qfq.c
@@ -220,9 +220,10 @@ static struct qfq_class *qfq_find_class(
 static void qfq_purge_queue(struct qfq_class *cl)
 {
 	unsigned int len = cl->qdisc->q.qlen;
+	unsigned int backlog = cl->qdisc->qstats.backlog;
 
 	qdisc_reset(cl->qdisc);
-	qdisc_tree_decrease_qlen(cl->qdisc, len);
+	qdisc_tree_reduce_backlog(cl->qdisc, len, backlog);
 }
 
 static const struct nla_policy qfq_policy[TCA_QFQ_MAX + 1] = {
@@ -617,11 +618,7 @@ static int qfq_graft_class(struct Qdisc
 			new = &noop_qdisc;
 	}
 
-	sch_tree_lock(sch);
-	qfq_purge_queue(cl);
-	*old = cl->qdisc;
-	cl->qdisc = new;
-	sch_tree_unlock(sch);
+	*old = qdisc_replace(sch, new, &cl->qdisc);
 	return 0;
 }
 
--- zfcpdump-kernel-4.4.orig/net/sched/sch_red.c
+++ zfcpdump-kernel-4.4/net/sched/sch_red.c
@@ -210,7 +210,8 @@ static int red_change(struct Qdisc *sch,
 	q->flags = ctl->flags;
 	q->limit = ctl->limit;
 	if (child) {
-		qdisc_tree_decrease_qlen(q->qdisc, q->qdisc->q.qlen);
+		qdisc_tree_reduce_backlog(q->qdisc, q->qdisc->q.qlen,
+					  q->qdisc->qstats.backlog);
 		qdisc_destroy(q->qdisc);
 		q->qdisc = child;
 	}
@@ -313,12 +314,7 @@ static int red_graft(struct Qdisc *sch,
 	if (new == NULL)
 		new = &noop_qdisc;
 
-	sch_tree_lock(sch);
-	*old = q->qdisc;
-	q->qdisc = new;
-	qdisc_tree_decrease_qlen(*old, (*old)->q.qlen);
-	qdisc_reset(*old);
-	sch_tree_unlock(sch);
+	*old = qdisc_replace(sch, new, &q->qdisc);
 	return 0;
 }
 
--- zfcpdump-kernel-4.4.orig/net/sched/sch_sfb.c
+++ zfcpdump-kernel-4.4/net/sched/sch_sfb.c
@@ -510,7 +510,8 @@ static int sfb_change(struct Qdisc *sch,
 
 	sch_tree_lock(sch);
 
-	qdisc_tree_decrease_qlen(q->qdisc, q->qdisc->q.qlen);
+	qdisc_tree_reduce_backlog(q->qdisc, q->qdisc->q.qlen,
+				  q->qdisc->qstats.backlog);
 	qdisc_destroy(q->qdisc);
 	q->qdisc = child;
 
@@ -606,12 +607,7 @@ static int sfb_graft(struct Qdisc *sch,
 	if (new == NULL)
 		new = &noop_qdisc;
 
-	sch_tree_lock(sch);
-	*old = q->qdisc;
-	q->qdisc = new;
-	qdisc_tree_decrease_qlen(*old, (*old)->q.qlen);
-	qdisc_reset(*old);
-	sch_tree_unlock(sch);
+	*old = qdisc_replace(sch, new, &q->qdisc);
 	return 0;
 }
 
--- zfcpdump-kernel-4.4.orig/net/sched/sch_sfq.c
+++ zfcpdump-kernel-4.4/net/sched/sch_sfq.c
@@ -346,7 +346,7 @@ static int
 sfq_enqueue(struct sk_buff *skb, struct Qdisc *sch)
 {
 	struct sfq_sched_data *q = qdisc_priv(sch);
-	unsigned int hash;
+	unsigned int hash, dropped;
 	sfq_index x, qlen;
 	struct sfq_slot *slot;
 	int uninitialized_var(ret);
@@ -461,7 +461,7 @@ enqueue:
 		return NET_XMIT_SUCCESS;
 
 	qlen = slot->qlen;
-	sfq_drop(sch);
+	dropped = sfq_drop(sch);
 	/* Return Congestion Notification only if we dropped a packet
 	 * from this flow.
 	 */
@@ -469,7 +469,7 @@ enqueue:
 		return NET_XMIT_CN;
 
 	/* As we dropped a packet, better let upper stack know this */
-	qdisc_tree_decrease_qlen(sch, 1);
+	qdisc_tree_reduce_backlog(sch, 1, dropped);
 	return NET_XMIT_SUCCESS;
 }
 
@@ -537,6 +537,7 @@ static void sfq_rehash(struct Qdisc *sch
 	struct sfq_slot *slot;
 	struct sk_buff_head list;
 	int dropped = 0;
+	unsigned int drop_len = 0;
 
 	__skb_queue_head_init(&list);
 
@@ -565,6 +566,7 @@ static void sfq_rehash(struct Qdisc *sch
 			if (x >= SFQ_MAX_FLOWS) {
 drop:
 				qdisc_qstats_backlog_dec(sch, skb);
+				drop_len += qdisc_pkt_len(skb);
 				kfree_skb(skb);
 				dropped++;
 				continue;
@@ -594,7 +596,7 @@ drop:
 		}
 	}
 	sch->q.qlen -= dropped;
-	qdisc_tree_decrease_qlen(sch, dropped);
+	qdisc_tree_reduce_backlog(sch, dropped, drop_len);
 }
 
 static void sfq_perturbation(unsigned long arg)
@@ -618,7 +620,7 @@ static int sfq_change(struct Qdisc *sch,
 	struct sfq_sched_data *q = qdisc_priv(sch);
 	struct tc_sfq_qopt *ctl = nla_data(opt);
 	struct tc_sfq_qopt_v1 *ctl_v1 = NULL;
-	unsigned int qlen;
+	unsigned int qlen, dropped = 0;
 	struct red_parms *p = NULL;
 
 	if (opt->nla_len < nla_attr_size(sizeof(*ctl)))
@@ -667,8 +669,8 @@ static int sfq_change(struct Qdisc *sch,
 
 	qlen = sch->q.qlen;
 	while (sch->q.qlen > q->limit)
-		sfq_drop(sch);
-	qdisc_tree_decrease_qlen(sch, qlen - sch->q.qlen);
+		dropped += sfq_drop(sch);
+	qdisc_tree_reduce_backlog(sch, qlen - sch->q.qlen, dropped);
 
 	del_timer(&q->perturb_timer);
 	if (q->perturb_period) {
--- zfcpdump-kernel-4.4.orig/net/sched/sch_tbf.c
+++ zfcpdump-kernel-4.4/net/sched/sch_tbf.c
@@ -160,6 +160,7 @@ static int tbf_segment(struct sk_buff *s
 	struct tbf_sched_data *q = qdisc_priv(sch);
 	struct sk_buff *segs, *nskb;
 	netdev_features_t features = netif_skb_features(skb);
+	unsigned int len = 0, prev_len = qdisc_pkt_len(skb);
 	int ret, nb;
 
 	segs = skb_gso_segment(skb, features & ~NETIF_F_GSO_MASK);
@@ -172,6 +173,7 @@ static int tbf_segment(struct sk_buff *s
 		nskb = segs->next;
 		segs->next = NULL;
 		qdisc_skb_cb(segs)->pkt_len = segs->len;
+		len += segs->len;
 		ret = qdisc_enqueue(segs, q->qdisc);
 		if (ret != NET_XMIT_SUCCESS) {
 			if (net_xmit_drop_count(ret))
@@ -183,7 +185,7 @@ static int tbf_segment(struct sk_buff *s
 	}
 	sch->q.qlen += nb;
 	if (nb > 1)
-		qdisc_tree_decrease_qlen(sch, 1 - nb);
+		qdisc_tree_reduce_backlog(sch, 1 - nb, prev_len - len);
 	consume_skb(skb);
 	return nb > 0 ? NET_XMIT_SUCCESS : NET_XMIT_DROP;
 }
@@ -399,7 +401,8 @@ static int tbf_change(struct Qdisc *sch,
 
 	sch_tree_lock(sch);
 	if (child) {
-		qdisc_tree_decrease_qlen(q->qdisc, q->qdisc->q.qlen);
+		qdisc_tree_reduce_backlog(q->qdisc, q->qdisc->q.qlen,
+					  q->qdisc->qstats.backlog);
 		qdisc_destroy(q->qdisc);
 		q->qdisc = child;
 	}
@@ -502,13 +505,7 @@ static int tbf_graft(struct Qdisc *sch,
 	if (new == NULL)
 		new = &noop_qdisc;
 
-	sch_tree_lock(sch);
-	*old = q->qdisc;
-	q->qdisc = new;
-	qdisc_tree_decrease_qlen(*old, (*old)->q.qlen);
-	qdisc_reset(*old);
-	sch_tree_unlock(sch);
-
+	*old = qdisc_replace(sch, new, &q->qdisc);
 	return 0;
 }
 
--- zfcpdump-kernel-4.4.orig/net/sctp/ipv6.c
+++ zfcpdump-kernel-4.4/net/sctp/ipv6.c
@@ -526,6 +526,8 @@ static int sctp_v6_cmp_addr(const union
 		}
 		return 0;
 	}
+	if (addr1->v6.sin6_port != addr2->v6.sin6_port)
+		return 0;
 	if (!ipv6_addr_equal(&addr1->v6.sin6_addr, &addr2->v6.sin6_addr))
 		return 0;
 	/* If this is a linklocal address, compare the scope_id. */
--- zfcpdump-kernel-4.4.orig/net/sctp/output.c
+++ zfcpdump-kernel-4.4/net/sctp/output.c
@@ -534,7 +534,7 @@ int sctp_packet_transmit(struct sctp_pac
 	 * by CRC32-C as described in <draft-ietf-tsvwg-sctpcsum-02.txt>.
 	 */
 	if (!sctp_checksum_disable) {
-		if (!(dst->dev->features & NETIF_F_SCTP_CSUM) ||
+		if (!(dst->dev->features & NETIF_F_SCTP_CRC) ||
 		    (dst_xfrm(dst) != NULL) || packet->ipfragok) {
 			sh->checksum = sctp_compute_cksum(nskb, 0);
 		} else {
--- zfcpdump-kernel-4.4.orig/net/sctp/protocol.c
+++ zfcpdump-kernel-4.4/net/sctp/protocol.c
@@ -60,6 +60,8 @@
 #include <net/inet_common.h>
 #include <net/inet_ecn.h>
 
+#define MAX_SCTP_PORT_HASH_ENTRIES (64 * 1024)
+
 /* Global data structures. */
 struct sctp_globals sctp_globals __read_mostly;
 
@@ -1352,6 +1354,8 @@ static __init int sctp_init(void)
 	unsigned long limit;
 	int max_share;
 	int order;
+	int num_entries;
+	int max_entry_order;
 
 	sock_skb_cb_check_size(sizeof(struct sctp_ulpevent));
 
@@ -1404,14 +1408,24 @@ static __init int sctp_init(void)
 
 	/* Size and allocate the association hash table.
 	 * The methodology is similar to that of the tcp hash tables.
+	 * Though not identical.  Start by getting a goal size
 	 */
 	if (totalram_pages >= (128 * 1024))
 		goal = totalram_pages >> (22 - PAGE_SHIFT);
 	else
 		goal = totalram_pages >> (24 - PAGE_SHIFT);
 
-	for (order = 0; (1UL << order) < goal; order++)
-		;
+	/* Then compute the page order for said goal */
+	order = get_order(goal);
+
+	/* Now compute the required page order for the maximum sized table we
+	 * want to create
+	 */
+	max_entry_order = get_order(MAX_SCTP_PORT_HASH_ENTRIES *
+				    sizeof(struct sctp_bind_hashbucket));
+
+	/* Limit the page order by that maximum hash table size */
+	order = min(order, max_entry_order);
 
 	do {
 		sctp_assoc_hashsize = (1UL << order) * PAGE_SIZE /
@@ -1445,20 +1459,35 @@ static __init int sctp_init(void)
 		INIT_HLIST_HEAD(&sctp_ep_hashtable[i].chain);
 	}
 
-	/* Allocate and initialize the SCTP port hash table.  */
+	/* Allocate and initialize the SCTP port hash table.
+	 * Note that order is initalized to start at the max sized
+	 * table we want to support.  If we can't get that many pages
+	 * reduce the order and try again
+	 */
 	do {
-		sctp_port_hashsize = (1UL << order) * PAGE_SIZE /
-					sizeof(struct sctp_bind_hashbucket);
-		if ((sctp_port_hashsize > (64 * 1024)) && order > 0)
-			continue;
 		sctp_port_hashtable = (struct sctp_bind_hashbucket *)
 			__get_free_pages(GFP_ATOMIC|__GFP_NOWARN, order);
 	} while (!sctp_port_hashtable && --order > 0);
+
 	if (!sctp_port_hashtable) {
 		pr_err("Failed bind hash alloc\n");
 		status = -ENOMEM;
 		goto err_bhash_alloc;
 	}
+
+	/* Now compute the number of entries that will fit in the
+	 * port hash space we allocated
+	 */
+	num_entries = (1UL << order) * PAGE_SIZE /
+		      sizeof(struct sctp_bind_hashbucket);
+
+	/* And finish by rounding it down to the nearest power of two
+	 * this wastes some memory of course, but its needed because
+	 * the hash function operates based on the assumption that
+	 * that the number of entries is a power of two
+	 */
+	sctp_port_hashsize = rounddown_pow_of_two(num_entries);
+
 	for (i = 0; i < sctp_port_hashsize; i++) {
 		spin_lock_init(&sctp_port_hashtable[i].lock);
 		INIT_HLIST_HEAD(&sctp_port_hashtable[i].chain);
--- zfcpdump-kernel-4.4.orig/net/sctp/socket.c
+++ zfcpdump-kernel-4.4/net/sctp/socket.c
@@ -5542,6 +5542,7 @@ static int sctp_getsockopt_hmac_ident(st
 	struct sctp_hmac_algo_param *hmacs;
 	__u16 data_len = 0;
 	u32 num_idents;
+	int i;
 
 	if (!ep->auth_enable)
 		return -EACCES;
@@ -5559,8 +5560,12 @@ static int sctp_getsockopt_hmac_ident(st
 		return -EFAULT;
 	if (put_user(num_idents, &p->shmac_num_idents))
 		return -EFAULT;
-	if (copy_to_user(p->shmac_idents, hmacs->hmac_ids, data_len))
-		return -EFAULT;
+	for (i = 0; i < num_idents; i++) {
+		__u16 hmacid = ntohs(hmacs->hmac_ids[i]);
+
+		if (copy_to_user(&p->shmac_idents[i], &hmacid, sizeof(__u16)))
+			return -EFAULT;
+	}
 	return 0;
 }
 
@@ -6640,6 +6645,7 @@ static int sctp_msghdr_parse(const struc
 
 			if (cmsgs->srinfo->sinfo_flags &
 			    ~(SCTP_UNORDERED | SCTP_ADDR_OVER |
+			      SCTP_SACK_IMMEDIATELY |
 			      SCTP_ABORT | SCTP_EOF))
 				return -EINVAL;
 			break;
@@ -6663,6 +6669,7 @@ static int sctp_msghdr_parse(const struc
 
 			if (cmsgs->sinfo->snd_flags &
 			    ~(SCTP_UNORDERED | SCTP_ADDR_OVER |
+			      SCTP_SACK_IMMEDIATELY |
 			      SCTP_ABORT | SCTP_EOF))
 				return -EINVAL;
 			break;
--- zfcpdump-kernel-4.4.orig/net/sctp/sysctl.c
+++ zfcpdump-kernel-4.4/net/sctp/sysctl.c
@@ -320,7 +320,7 @@ static int proc_sctp_do_hmac_alg(struct
 	struct ctl_table tbl;
 	bool changed = false;
 	char *none = "none";
-	char tmp[8];
+	char tmp[8] = {0};
 	int ret;
 
 	memset(&tbl, 0, sizeof(struct ctl_table));
--- zfcpdump-kernel-4.4.orig/net/socket.c
+++ zfcpdump-kernel-4.4/net/socket.c
@@ -2238,31 +2238,31 @@ int __sys_recvmmsg(int fd, struct mmsghd
 			break;
 	}
 
-out_put:
-	fput_light(sock->file, fput_needed);
-
 	if (err == 0)
-		return datagrams;
+		goto out_put;
+
+	if (datagrams == 0) {
+		datagrams = err;
+		goto out_put;
+	}
 
-	if (datagrams != 0) {
+	/*
+	 * We may return less entries than requested (vlen) if the
+	 * sock is non block and there aren't enough datagrams...
+	 */
+	if (err != -EAGAIN) {
 		/*
-		 * We may return less entries than requested (vlen) if the
-		 * sock is non block and there aren't enough datagrams...
+		 * ... or  if recvmsg returns an error after we
+		 * received some datagrams, where we record the
+		 * error to return on the next call or if the
+		 * app asks about it using getsockopt(SO_ERROR).
 		 */
-		if (err != -EAGAIN) {
-			/*
-			 * ... or  if recvmsg returns an error after we
-			 * received some datagrams, where we record the
-			 * error to return on the next call or if the
-			 * app asks about it using getsockopt(SO_ERROR).
-			 */
-			sock->sk->sk_err = -err;
-		}
-
-		return datagrams;
+		sock->sk->sk_err = -err;
 	}
+out_put:
+	fput_light(sock->file, fput_needed);
 
-	return err;
+	return datagrams;
 }
 
 SYSCALL_DEFINE5(recvmmsg, int, fd, struct mmsghdr __user *, mmsg,
--- zfcpdump-kernel-4.4.orig/net/sunrpc/auth_gss/auth_gss.c
+++ zfcpdump-kernel-4.4/net/sunrpc/auth_gss/auth_gss.c
@@ -340,12 +340,14 @@ gss_release_msg(struct gss_upcall_msg *g
 }
 
 static struct gss_upcall_msg *
-__gss_find_upcall(struct rpc_pipe *pipe, kuid_t uid)
+__gss_find_upcall(struct rpc_pipe *pipe, kuid_t uid, const struct gss_auth *auth)
 {
 	struct gss_upcall_msg *pos;
 	list_for_each_entry(pos, &pipe->in_downcall, list) {
 		if (!uid_eq(pos->uid, uid))
 			continue;
+		if (auth && pos->auth->service != auth->service)
+			continue;
 		atomic_inc(&pos->count);
 		dprintk("RPC:       %s found msg %p\n", __func__, pos);
 		return pos;
@@ -365,7 +367,7 @@ gss_add_msg(struct gss_upcall_msg *gss_m
 	struct gss_upcall_msg *old;
 
 	spin_lock(&pipe->lock);
-	old = __gss_find_upcall(pipe, gss_msg->uid);
+	old = __gss_find_upcall(pipe, gss_msg->uid, gss_msg->auth);
 	if (old == NULL) {
 		atomic_inc(&gss_msg->count);
 		list_add(&gss_msg->list, &pipe->in_downcall);
@@ -714,7 +716,7 @@ gss_pipe_downcall(struct file *filp, con
 	err = -ENOENT;
 	/* Find a matching upcall */
 	spin_lock(&pipe->lock);
-	gss_msg = __gss_find_upcall(pipe, uid);
+	gss_msg = __gss_find_upcall(pipe, uid, NULL);
 	if (gss_msg == NULL) {
 		spin_unlock(&pipe->lock);
 		goto err_put_ctx;
--- zfcpdump-kernel-4.4.orig/net/sunrpc/auth_gss/svcauth_gss.c
+++ zfcpdump-kernel-4.4/net/sunrpc/auth_gss/svcauth_gss.c
@@ -857,8 +857,8 @@ unwrap_integ_data(struct svc_rqst *rqstp
 		goto out;
 	if (svc_getnl(&buf->head[0]) != seq)
 		goto out;
-	/* trim off the mic at the end before returning */
-	xdr_buf_trim(buf, mic.len + 4);
+	/* trim off the mic and padding at the end before returning */
+	xdr_buf_trim(buf, round_up_to_quad(mic.len) + 4);
 	stat = 0;
 out:
 	kfree(mic.data);
--- zfcpdump-kernel-4.4.orig/net/sunrpc/cache.c
+++ zfcpdump-kernel-4.4/net/sunrpc/cache.c
@@ -1182,14 +1182,14 @@ int sunrpc_cache_pipe_upcall(struct cach
 	}
 
 	crq->q.reader = 0;
-	crq->item = cache_get(h);
 	crq->buf = buf;
 	crq->len = 0;
 	crq->readers = 0;
 	spin_lock(&queue_lock);
-	if (test_bit(CACHE_PENDING, &h->flags))
+	if (test_bit(CACHE_PENDING, &h->flags)) {
+		crq->item = cache_get(h);
 		list_add_tail(&crq->q.list, &detail->queue);
-	else
+	} else
 		/* Lost a race, no longer PENDING, so don't enqueue */
 		ret = -EAGAIN;
 	spin_unlock(&queue_lock);
@@ -1225,7 +1225,7 @@ int qword_get(char **bpp, char *dest, in
 	if (bp[0] == '\\' && bp[1] == 'x') {
 		/* HEX STRING */
 		bp += 2;
-		while (len < bufsize) {
+		while (len < bufsize - 1) {
 			int h, l;
 
 			h = hex_to_bin(bp[0]);
--- zfcpdump-kernel-4.4.orig/net/sunrpc/clnt.c
+++ zfcpdump-kernel-4.4/net/sunrpc/clnt.c
@@ -442,7 +442,7 @@ out_no_rpciod:
 	return ERR_PTR(err);
 }
 
-struct rpc_clnt *rpc_create_xprt(struct rpc_create_args *args,
+static struct rpc_clnt *rpc_create_xprt(struct rpc_create_args *args,
 					struct rpc_xprt *xprt)
 {
 	struct rpc_clnt *clnt = NULL;
@@ -474,7 +474,6 @@ struct rpc_clnt *rpc_create_xprt(struct
 
 	return clnt;
 }
-EXPORT_SYMBOL_GPL(rpc_create_xprt);
 
 /**
  * rpc_create - create an RPC client and transport with one call
@@ -500,6 +499,15 @@ struct rpc_clnt *rpc_create(struct rpc_c
 	};
 	char servername[48];
 
+	if (args->bc_xprt) {
+		WARN_ON(args->protocol != XPRT_TRANSPORT_BC_TCP);
+		xprt = args->bc_xprt->xpt_bc_xprt;
+		if (xprt) {
+			xprt_get(xprt);
+			return rpc_create_xprt(args, xprt);
+		}
+	}
+
 	if (args->flags & RPC_CLNT_CREATE_INFINITE_SLOTS)
 		xprtargs.flags |= XPRT_CREATE_INFINITE_SLOTS;
 	if (args->flags & RPC_CLNT_CREATE_NO_IDLE_TIMEOUT)
--- zfcpdump-kernel-4.4.orig/net/sunrpc/rpc_pipe.c
+++ zfcpdump-kernel-4.4/net/sunrpc/rpc_pipe.c
@@ -1386,7 +1386,7 @@ rpc_fill_super(struct super_block *sb, v
 {
 	struct inode *inode;
 	struct dentry *root, *gssd_dentry;
-	struct net *net = data;
+	struct net *net = get_net(sb->s_fs_info);
 	struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
 	int err;
 
@@ -1419,7 +1419,6 @@ rpc_fill_super(struct super_block *sb, v
 					   sb);
 	if (err)
 		goto err_depopulate;
-	sb->s_fs_info = get_net(net);
 	mutex_unlock(&sn->pipefs_sb_lock);
 	return 0;
 
@@ -1448,7 +1447,8 @@ static struct dentry *
 rpc_mount(struct file_system_type *fs_type,
 		int flags, const char *dev_name, void *data)
 {
-	return mount_ns(fs_type, flags, current->nsproxy->net_ns, rpc_fill_super);
+	struct net *net = current->nsproxy->net_ns;
+	return mount_ns(fs_type, flags, data, net, net->user_ns, rpc_fill_super);
 }
 
 static void rpc_kill_sb(struct super_block *sb)
@@ -1468,9 +1468,9 @@ static void rpc_kill_sb(struct super_blo
 					   RPC_PIPEFS_UMOUNT,
 					   sb);
 	mutex_unlock(&sn->pipefs_sb_lock);
-	put_net(net);
 out:
 	kill_litter_super(sb);
+	put_net(net);
 }
 
 static struct file_system_type rpc_pipe_fs_type = {
--- zfcpdump-kernel-4.4.orig/net/sunrpc/svc.c
+++ zfcpdump-kernel-4.4/net/sunrpc/svc.c
@@ -1188,11 +1188,17 @@ svc_process_common(struct svc_rqst *rqst
 		*statp = procp->pc_func(rqstp, rqstp->rq_argp, rqstp->rq_resp);
 
 		/* Encode reply */
-		if (test_bit(RQ_DROPME, &rqstp->rq_flags)) {
+		if (*statp == rpc_drop_reply ||
+		    test_bit(RQ_DROPME, &rqstp->rq_flags)) {
 			if (procp->pc_release)
 				procp->pc_release(rqstp, NULL, rqstp->rq_resp);
 			goto dropit;
 		}
+		if (*statp == rpc_autherr_badcred) {
+			if (procp->pc_release)
+				procp->pc_release(rqstp, NULL, rqstp->rq_resp);
+			goto err_bad_auth;
+		}
 		if (*statp == rpc_success &&
 		    (xdr = procp->pc_encode) &&
 		    !xdr(rqstp, resv->iov_base+resv->iov_len, rqstp->rq_resp)) {
--- zfcpdump-kernel-4.4.orig/net/sunrpc/xprtsock.c
+++ zfcpdump-kernel-4.4/net/sunrpc/xprtsock.c
@@ -398,7 +398,6 @@ static int xs_sendpages(struct socket *s
 	if (unlikely(!sock))
 		return -ENOTSOCK;
 
-	clear_bit(SOCKWQ_ASYNC_NOSPACE, &sock->flags);
 	if (base != 0) {
 		addr = NULL;
 		addrlen = 0;
@@ -442,7 +441,6 @@ static void xs_nospace_callback(struct r
 	struct sock_xprt *transport = container_of(task->tk_rqstp->rq_xprt, struct sock_xprt, xprt);
 
 	transport->inet->sk_write_pending--;
-	clear_bit(SOCKWQ_ASYNC_NOSPACE, &transport->sock->flags);
 }
 
 /**
@@ -467,20 +465,11 @@ static int xs_nospace(struct rpc_task *t
 
 	/* Don't race with disconnect */
 	if (xprt_connected(xprt)) {
-		if (test_bit(SOCKWQ_ASYNC_NOSPACE, &transport->sock->flags)) {
-			/*
-			 * Notify TCP that we're limited by the application
-			 * window size
-			 */
-			set_bit(SOCK_NOSPACE, &transport->sock->flags);
-			sk->sk_write_pending++;
-			/* ...and wait for more buffer space */
-			xprt_wait_for_buffer_space(task, xs_nospace_callback);
-		}
-	} else {
-		clear_bit(SOCKWQ_ASYNC_NOSPACE, &transport->sock->flags);
+		/* wait for more buffer space */
+		sk->sk_write_pending++;
+		xprt_wait_for_buffer_space(task, xs_nospace_callback);
+	} else
 		ret = -ENOTCONN;
-	}
 
 	spin_unlock_bh(&xprt->transport_lock);
 
@@ -616,9 +605,6 @@ process_status:
 	case -EAGAIN:
 		status = xs_nospace(task);
 		break;
-	default:
-		dprintk("RPC:       sendmsg returned unrecognized error %d\n",
-			-status);
 	case -ENETUNREACH:
 	case -ENOBUFS:
 	case -EPIPE:
@@ -626,7 +612,10 @@ process_status:
 	case -EPERM:
 		/* When the server has died, an ICMP port unreachable message
 		 * prompts ECONNREFUSED. */
-		clear_bit(SOCKWQ_ASYNC_NOSPACE, &transport->sock->flags);
+		break;
+	default:
+		dprintk("RPC:       sendmsg returned unrecognized error %d\n",
+			-status);
 	}
 
 	return status;
@@ -706,16 +695,16 @@ static int xs_tcp_send_request(struct rp
 	case -EAGAIN:
 		status = xs_nospace(task);
 		break;
-	default:
-		dprintk("RPC:       sendmsg returned unrecognized error %d\n",
-			-status);
 	case -ECONNRESET:
 	case -ECONNREFUSED:
 	case -ENOTCONN:
 	case -EADDRINUSE:
 	case -ENOBUFS:
 	case -EPIPE:
-		clear_bit(SOCKWQ_ASYNC_NOSPACE, &transport->sock->flags);
+		break;
+	default:
+		dprintk("RPC:       sendmsg returned unrecognized error %d\n",
+			-status);
 	}
 
 	return status;
@@ -1609,19 +1598,23 @@ static void xs_tcp_state_change(struct s
 
 static void xs_write_space(struct sock *sk)
 {
-	struct socket *sock;
+	struct socket_wq *wq;
 	struct rpc_xprt *xprt;
 
-	if (unlikely(!(sock = sk->sk_socket)))
+	if (!sk->sk_socket)
 		return;
-	clear_bit(SOCK_NOSPACE, &sock->flags);
+	clear_bit(SOCK_NOSPACE, &sk->sk_socket->flags);
 
 	if (unlikely(!(xprt = xprt_from_sock(sk))))
 		return;
-	if (test_and_clear_bit(SOCKWQ_ASYNC_NOSPACE, &sock->flags) == 0)
-		return;
+	rcu_read_lock();
+	wq = rcu_dereference(sk->sk_wq);
+	if (!wq || test_and_clear_bit(SOCKWQ_ASYNC_NOSPACE, &wq->flags) == 0)
+		goto out;
 
 	xprt_write_space(xprt);
+out:
+	rcu_read_unlock();
 }
 
 /**
@@ -2293,6 +2286,10 @@ static int xs_tcp_finish_connecting(stru
 		/* SYN_SENT! */
 		if (xprt->reestablish_timeout < XS_TCP_INIT_REEST_TO)
 			xprt->reestablish_timeout = XS_TCP_INIT_REEST_TO;
+		break;
+	case -EADDRNOTAVAIL:
+		/* Source port number is unavailable. Try a new one! */
+		transport->srcport = 0;
 	}
 out:
 	return ret;
--- zfcpdump-kernel-4.4.orig/net/switchdev/switchdev.c
+++ zfcpdump-kernel-4.4/net/switchdev/switchdev.c
@@ -20,6 +20,7 @@
 #include <linux/list.h>
 #include <linux/workqueue.h>
 #include <linux/if_vlan.h>
+#include <linux/rtnetlink.h>
 #include <net/ip_fib.h>
 #include <net/switchdev.h>
 
@@ -565,7 +566,6 @@ int switchdev_port_obj_dump(struct net_d
 }
 EXPORT_SYMBOL_GPL(switchdev_port_obj_dump);
 
-static DEFINE_MUTEX(switchdev_mutex);
 static RAW_NOTIFIER_HEAD(switchdev_notif_chain);
 
 /**
@@ -580,9 +580,9 @@ int register_switchdev_notifier(struct n
 {
 	int err;
 
-	mutex_lock(&switchdev_mutex);
+	rtnl_lock();
 	err = raw_notifier_chain_register(&switchdev_notif_chain, nb);
-	mutex_unlock(&switchdev_mutex);
+	rtnl_unlock();
 	return err;
 }
 EXPORT_SYMBOL_GPL(register_switchdev_notifier);
@@ -598,9 +598,9 @@ int unregister_switchdev_notifier(struct
 {
 	int err;
 
-	mutex_lock(&switchdev_mutex);
+	rtnl_lock();
 	err = raw_notifier_chain_unregister(&switchdev_notif_chain, nb);
-	mutex_unlock(&switchdev_mutex);
+	rtnl_unlock();
 	return err;
 }
 EXPORT_SYMBOL_GPL(unregister_switchdev_notifier);
@@ -614,16 +614,17 @@ EXPORT_SYMBOL_GPL(unregister_switchdev_n
  *	Call all network notifier blocks. This should be called by driver
  *	when it needs to propagate hardware event.
  *	Return values are same as for atomic_notifier_call_chain().
+ *	rtnl_lock must be held.
  */
 int call_switchdev_notifiers(unsigned long val, struct net_device *dev,
 			     struct switchdev_notifier_info *info)
 {
 	int err;
 
+	ASSERT_RTNL();
+
 	info->dev = dev;
-	mutex_lock(&switchdev_mutex);
 	err = raw_notifier_call_chain(&switchdev_notif_chain, val, info);
-	mutex_unlock(&switchdev_mutex);
 	return err;
 }
 EXPORT_SYMBOL_GPL(call_switchdev_notifiers);
@@ -1168,6 +1169,7 @@ int switchdev_fib_ipv4_add(u32 dst, int
 		.obj.id = SWITCHDEV_OBJ_ID_IPV4_FIB,
 		.dst = dst,
 		.dst_len = dst_len,
+		.fi = fi,
 		.tos = tos,
 		.type = type,
 		.nlflags = nlflags,
@@ -1176,8 +1178,6 @@ int switchdev_fib_ipv4_add(u32 dst, int
 	struct net_device *dev;
 	int err = 0;
 
-	memcpy(&ipv4_fib.fi, fi, sizeof(ipv4_fib.fi));
-
 	/* Don't offload route if using custom ip rules or if
 	 * IPv4 FIB offloading has been disabled completely.
 	 */
@@ -1221,6 +1221,7 @@ int switchdev_fib_ipv4_del(u32 dst, int
 		.obj.id = SWITCHDEV_OBJ_ID_IPV4_FIB,
 		.dst = dst,
 		.dst_len = dst_len,
+		.fi = fi,
 		.tos = tos,
 		.type = type,
 		.nlflags = 0,
@@ -1229,8 +1230,6 @@ int switchdev_fib_ipv4_del(u32 dst, int
 	struct net_device *dev;
 	int err = 0;
 
-	memcpy(&ipv4_fib.fi, fi, sizeof(ipv4_fib.fi));
-
 	if (!(fi->fib_flags & RTNH_F_OFFLOAD))
 		return 0;
 
--- zfcpdump-kernel-4.4.orig/net/sysctl_net.c
+++ zfcpdump-kernel-4.4/net/sysctl_net.c
@@ -46,7 +46,7 @@ static int net_ctl_permissions(struct ct
 	kgid_t root_gid = make_kgid(net->user_ns, 0);
 
 	/* Allow network administrator to have same access as root. */
-	if (ns_capable(net->user_ns, CAP_NET_ADMIN) ||
+	if (ns_capable_noaudit(net->user_ns, CAP_NET_ADMIN) ||
 	    uid_eq(root_uid, current_euid())) {
 		int mode = (table->mode >> 6) & 7;
 		return (mode << 6) | (mode << 3) | mode;
--- zfcpdump-kernel-4.4.orig/net/tipc/bcast.c
+++ zfcpdump-kernel-4.4/net/tipc/bcast.c
@@ -399,8 +399,10 @@ int tipc_nl_add_bc_link(struct net *net,
 
 	hdr = genlmsg_put(msg->skb, msg->portid, msg->seq, &tipc_genl_family,
 			  NLM_F_MULTI, TIPC_NL_LINK_GET);
-	if (!hdr)
+	if (!hdr) {
+		tipc_bcast_unlock(net);
 		return -EMSGSIZE;
+	}
 
 	attrs = nla_nest_start(msg->skb, TIPC_NLA_LINK);
 	if (!attrs)
--- zfcpdump-kernel-4.4.orig/net/tipc/link.c
+++ zfcpdump-kernel-4.4/net/tipc/link.c
@@ -1262,6 +1262,8 @@ static int tipc_link_proto_rcv(struct ti
 		/* fall thru' */
 
 	case ACTIVATE_MSG:
+		skb_linearize(skb);
+		hdr = buf_msg(skb);
 
 		/* Complete own link name with peer's interface name */
 		if_name =  strrchr(l->name, ':') + 1;
--- zfcpdump-kernel-4.4.orig/net/tipc/name_distr.c
+++ zfcpdump-kernel-4.4/net/tipc/name_distr.c
@@ -397,6 +397,7 @@ void tipc_named_rcv(struct net *net, str
 
 	spin_lock_bh(&tn->nametbl_lock);
 	for (skb = skb_dequeue(inputq); skb; skb = skb_dequeue(inputq)) {
+		skb_linearize(skb);
 		msg = buf_msg(skb);
 		mtype = msg_type(msg);
 		item = (struct distr_item *)msg_data(msg);
--- zfcpdump-kernel-4.4.orig/net/tipc/netlink_compat.c
+++ zfcpdump-kernel-4.4/net/tipc/netlink_compat.c
@@ -574,7 +574,8 @@ static int tipc_nl_compat_link_dump(stru
 
 	link_info.dest = nla_get_flag(link[TIPC_NLA_LINK_DEST]);
 	link_info.up = htonl(nla_get_flag(link[TIPC_NLA_LINK_UP]));
-	strcpy(link_info.str, nla_data(link[TIPC_NLA_LINK_NAME]));
+	nla_strlcpy(link_info.str, link[TIPC_NLA_LINK_NAME],
+		    TIPC_MAX_LINK_NAME);
 
 	return tipc_add_tlv(msg->rep, TIPC_TLV_LINK_INFO,
 			    &link_info, sizeof(link_info));
@@ -802,7 +803,7 @@ static int tipc_nl_compat_name_table_dum
 		goto out;
 
 	tipc_tlv_sprintf(msg->rep, "%-10u %s",
-			 nla_get_u32(publ[TIPC_NLA_PUBL_REF]),
+			 nla_get_u32(publ[TIPC_NLA_PUBL_KEY]),
 			 scope_str[nla_get_u32(publ[TIPC_NLA_PUBL_SCOPE])]);
 out:
 	tipc_tlv_sprintf(msg->rep, "\n");
--- zfcpdump-kernel-4.4.orig/net/tipc/node.c
+++ zfcpdump-kernel-4.4/net/tipc/node.c
@@ -168,12 +168,6 @@ struct tipc_node *tipc_node_create(struc
 	skb_queue_head_init(&n_ptr->bc_entry.inputq1);
 	__skb_queue_head_init(&n_ptr->bc_entry.arrvq);
 	skb_queue_head_init(&n_ptr->bc_entry.inputq2);
-	hlist_add_head_rcu(&n_ptr->hash, &tn->node_htable[tipc_hashfn(addr)]);
-	list_for_each_entry_rcu(temp_node, &tn->node_list, list) {
-		if (n_ptr->addr < temp_node->addr)
-			break;
-	}
-	list_add_tail_rcu(&n_ptr->list, &temp_node->list);
 	n_ptr->state = SELF_DOWN_PEER_LEAVING;
 	n_ptr->signature = INVALID_NODE_SIG;
 	n_ptr->active_links[0] = INVALID_BEARER_ID;
@@ -193,6 +187,12 @@ struct tipc_node *tipc_node_create(struc
 	tipc_node_get(n_ptr);
 	setup_timer(&n_ptr->timer, tipc_node_timeout, (unsigned long)n_ptr);
 	n_ptr->keepalive_intv = U32_MAX;
+	hlist_add_head_rcu(&n_ptr->hash, &tn->node_htable[tipc_hashfn(addr)]);
+	list_for_each_entry_rcu(temp_node, &tn->node_list, list) {
+		if (n_ptr->addr < temp_node->addr)
+			break;
+	}
+	list_add_tail_rcu(&n_ptr->list, &temp_node->list);
 exit:
 	spin_unlock_bh(&tn->node_list_lock);
 	return n_ptr;
--- zfcpdump-kernel-4.4.orig/net/tipc/socket.c
+++ zfcpdump-kernel-4.4/net/tipc/socket.c
@@ -673,7 +673,7 @@ static int tipc_sendmcast(struct  socket
 	struct tipc_sock *tsk = tipc_sk(sk);
 	struct net *net = sock_net(sk);
 	struct tipc_msg *mhdr = &tsk->phdr;
-	struct sk_buff_head *pktchain = &sk->sk_write_queue;
+	struct sk_buff_head pktchain;
 	struct iov_iter save = msg->msg_iter;
 	uint mtu;
 	int rc;
@@ -687,14 +687,16 @@ static int tipc_sendmcast(struct  socket
 	msg_set_nameupper(mhdr, seq->upper);
 	msg_set_hdr_sz(mhdr, MCAST_H_SIZE);
 
+	skb_queue_head_init(&pktchain);
+
 new_mtu:
 	mtu = tipc_bcast_get_mtu(net);
-	rc = tipc_msg_build(mhdr, msg, 0, dsz, mtu, pktchain);
+	rc = tipc_msg_build(mhdr, msg, 0, dsz, mtu, &pktchain);
 	if (unlikely(rc < 0))
 		return rc;
 
 	do {
-		rc = tipc_bcast_xmit(net, pktchain);
+		rc = tipc_bcast_xmit(net, &pktchain);
 		if (likely(!rc))
 			return dsz;
 
@@ -704,7 +706,7 @@ new_mtu:
 			if (!rc)
 				continue;
 		}
-		__skb_queue_purge(pktchain);
+		__skb_queue_purge(&pktchain);
 		if (rc == -EMSGSIZE) {
 			msg->msg_iter = save;
 			goto new_mtu;
@@ -863,7 +865,7 @@ static int __tipc_sendmsg(struct socket
 	struct net *net = sock_net(sk);
 	struct tipc_msg *mhdr = &tsk->phdr;
 	u32 dnode, dport;
-	struct sk_buff_head *pktchain = &sk->sk_write_queue;
+	struct sk_buff_head pktchain;
 	struct sk_buff *skb;
 	struct tipc_name_seq *seq;
 	struct iov_iter save;
@@ -924,17 +926,18 @@ static int __tipc_sendmsg(struct socket
 		msg_set_hdr_sz(mhdr, BASIC_H_SIZE);
 	}
 
+	skb_queue_head_init(&pktchain);
 	save = m->msg_iter;
 new_mtu:
 	mtu = tipc_node_get_mtu(net, dnode, tsk->portid);
-	rc = tipc_msg_build(mhdr, m, 0, dsz, mtu, pktchain);
+	rc = tipc_msg_build(mhdr, m, 0, dsz, mtu, &pktchain);
 	if (rc < 0)
 		return rc;
 
 	do {
-		skb = skb_peek(pktchain);
+		skb = skb_peek(&pktchain);
 		TIPC_SKB_CB(skb)->wakeup_pending = tsk->link_cong;
-		rc = tipc_node_xmit(net, pktchain, dnode, tsk->portid);
+		rc = tipc_node_xmit(net, &pktchain, dnode, tsk->portid);
 		if (likely(!rc)) {
 			if (sock->state != SS_READY)
 				sock->state = SS_CONNECTING;
@@ -946,7 +949,7 @@ new_mtu:
 			if (!rc)
 				continue;
 		}
-		__skb_queue_purge(pktchain);
+		__skb_queue_purge(&pktchain);
 		if (rc == -EMSGSIZE) {
 			m->msg_iter = save;
 			goto new_mtu;
@@ -1016,7 +1019,7 @@ static int __tipc_send_stream(struct soc
 	struct net *net = sock_net(sk);
 	struct tipc_sock *tsk = tipc_sk(sk);
 	struct tipc_msg *mhdr = &tsk->phdr;
-	struct sk_buff_head *pktchain = &sk->sk_write_queue;
+	struct sk_buff_head pktchain;
 	DECLARE_SOCKADDR(struct sockaddr_tipc *, dest, m->msg_name);
 	u32 portid = tsk->portid;
 	int rc = -EINVAL;
@@ -1044,17 +1047,19 @@ static int __tipc_send_stream(struct soc
 
 	timeo = sock_sndtimeo(sk, m->msg_flags & MSG_DONTWAIT);
 	dnode = tsk_peer_node(tsk);
+	skb_queue_head_init(&pktchain);
 
 next:
 	save = m->msg_iter;
 	mtu = tsk->max_pkt;
 	send = min_t(uint, dsz - sent, TIPC_MAX_USER_MSG_SIZE);
-	rc = tipc_msg_build(mhdr, m, sent, send, mtu, pktchain);
+	rc = tipc_msg_build(mhdr, m, sent, send, mtu, &pktchain);
 	if (unlikely(rc < 0))
 		return rc;
+
 	do {
 		if (likely(!tsk_conn_cong(tsk))) {
-			rc = tipc_node_xmit(net, pktchain, dnode, portid);
+			rc = tipc_node_xmit(net, &pktchain, dnode, portid);
 			if (likely(!rc)) {
 				tsk->sent_unacked++;
 				sent += send;
@@ -1063,7 +1068,7 @@ next:
 				goto next;
 			}
 			if (rc == -EMSGSIZE) {
-				__skb_queue_purge(pktchain);
+				__skb_queue_purge(&pktchain);
 				tsk->max_pkt = tipc_node_get_mtu(net, dnode,
 								 portid);
 				m->msg_iter = save;
@@ -1077,7 +1082,7 @@ next:
 		rc = tipc_wait_for_sndpkt(sock, &timeo);
 	} while (!rc);
 
-	__skb_queue_purge(pktchain);
+	__skb_queue_purge(&pktchain);
 	return sent ? sent : rc;
 }
 
@@ -2106,7 +2111,8 @@ restart:
 					      TIPC_CONN_MSG, SHORT_H_SIZE,
 					      0, dnode, onode, dport, oport,
 					      TIPC_CONN_SHUTDOWN);
-			tipc_node_xmit_skb(net, skb, dnode, tsk->portid);
+			if (skb)
+				tipc_node_xmit_skb(net, skb, dnode, tsk->portid);
 		}
 		tsk->connected = 0;
 		sock->state = SS_DISCONNECTING;
@@ -2809,6 +2815,9 @@ int tipc_nl_publ_dump(struct sk_buff *sk
 		if (err)
 			return err;
 
+		if (!attrs[TIPC_NLA_SOCK])
+			return -EINVAL;
+
 		err = nla_parse_nested(sock, TIPC_NLA_SOCK_MAX,
 				       attrs[TIPC_NLA_SOCK],
 				       tipc_nl_sock_policy);
--- zfcpdump-kernel-4.4.orig/net/tipc/subscr.c
+++ zfcpdump-kernel-4.4/net/tipc/subscr.c
@@ -289,15 +289,15 @@ static void tipc_subscrb_rcv_cb(struct n
 				struct sockaddr_tipc *addr, void *usr_data,
 				void *buf, size_t len)
 {
-	struct tipc_subscriber *subscriber = usr_data;
+	struct tipc_subscriber *subscrb = usr_data;
 	struct tipc_subscription *sub = NULL;
 	struct tipc_net *tn = net_generic(net, tipc_net_id);
 
-	tipc_subscrp_create(net, (struct tipc_subscr *)buf, subscriber, &sub);
+	if (tipc_subscrp_create(net, (struct tipc_subscr *)buf, subscrb, &sub))
+		return tipc_conn_terminate(tn->topsrv, subscrb->conid);
+
 	if (sub)
 		tipc_nametbl_subscribe(sub);
-	else
-		tipc_conn_terminate(tn->topsrv, subscriber->conid);
 }
 
 /* Handle one request to establish a new subscriber */
--- zfcpdump-kernel-4.4.orig/net/tipc/udp_media.c
+++ zfcpdump-kernel-4.4/net/tipc/udp_media.c
@@ -48,7 +48,6 @@
 #include <linux/tipc_netlink.h>
 #include "core.h"
 #include "bearer.h"
-#include "msg.h"
 
 /* IANA assigned UDP port */
 #define UDP_PORT_DEFAULT	6118
@@ -224,10 +223,6 @@ static int tipc_udp_recv(struct sock *sk
 {
 	struct udp_bearer *ub;
 	struct tipc_bearer *b;
-	int usr = msg_user(buf_msg(skb));
-
-	if ((usr == LINK_PROTOCOL) || (usr == NAME_DISTRIBUTOR))
-		skb_linearize(skb);
 
 	ub = rcu_dereference_sk_user_data(sk);
 	if (!ub) {
--- zfcpdump-kernel-4.4.orig/net/unix/af_unix.c
+++ zfcpdump-kernel-4.4/net/unix/af_unix.c
@@ -315,7 +315,7 @@ static struct sock *unix_find_socket_byi
 		    &unix_socket_table[i->i_ino & (UNIX_HASH_SIZE - 1)]) {
 		struct dentry *dentry = unix_sk(s)->path.dentry;
 
-		if (dentry && d_backing_inode(dentry) == i) {
+		if (dentry && d_real_inode(dentry) == i) {
 			sock_hold(s);
 			goto found;
 		}
@@ -661,11 +661,11 @@ static int unix_set_peek_off(struct sock
 {
 	struct unix_sock *u = unix_sk(sk);
 
-	if (mutex_lock_interruptible(&u->readlock))
+	if (mutex_lock_interruptible(&u->iolock))
 		return -EINTR;
 
 	sk->sk_peek_off = val;
-	mutex_unlock(&u->readlock);
+	mutex_unlock(&u->iolock);
 
 	return 0;
 }
@@ -778,7 +778,8 @@ static struct sock *unix_create1(struct
 	spin_lock_init(&u->lock);
 	atomic_long_set(&u->inflight, 0);
 	INIT_LIST_HEAD(&u->link);
-	mutex_init(&u->readlock); /* single task reading lock */
+	mutex_init(&u->iolock); /* single task reading lock */
+	mutex_init(&u->bindlock); /* single task binding lock */
 	init_waitqueue_head(&u->peer_wait);
 	init_waitqueue_func_entry(&u->peer_wake, unix_dgram_peer_wake_relay);
 	unix_insert_socket(unix_sockets_unbound(sk), sk);
@@ -847,7 +848,7 @@ static int unix_autobind(struct socket *
 	int err;
 	unsigned int retries = 0;
 
-	err = mutex_lock_interruptible(&u->readlock);
+	err = mutex_lock_interruptible(&u->bindlock);
 	if (err)
 		return err;
 
@@ -894,7 +895,7 @@ retry:
 	spin_unlock(&unix_table_lock);
 	err = 0;
 
-out:	mutex_unlock(&u->readlock);
+out:	mutex_unlock(&u->bindlock);
 	return err;
 }
 
@@ -911,7 +912,7 @@ static struct sock *unix_find_other(stru
 		err = kern_path(sunname->sun_path, LOOKUP_FOLLOW, &path);
 		if (err)
 			goto fail;
-		inode = d_backing_inode(path.dentry);
+		inode = d_real_inode(path.dentry);
 		err = inode_permission(inode, MAY_WRITE);
 		if (err)
 			goto put_fail;
@@ -953,20 +954,32 @@ fail:
 	return NULL;
 }
 
-static int unix_mknod(struct dentry *dentry, struct path *path, umode_t mode,
-		      struct path *res)
+static int unix_mknod(const char *sun_path, umode_t mode, struct path *res)
 {
-	int err;
+	struct dentry *dentry;
+	struct path path;
+	int err = 0;
+	/*
+	 * Get the parent directory, calculate the hash for last
+	 * component.
+	 */
+	dentry = kern_path_create(AT_FDCWD, sun_path, &path, 0);
+	err = PTR_ERR(dentry);
+	if (IS_ERR(dentry))
+		return err;
 
-	err = security_path_mknod(path, dentry, mode, 0);
+	/*
+	 * All right, let's create it.
+	 */
+	err = security_path_mknod(&path, dentry, mode, 0);
 	if (!err) {
-		err = vfs_mknod(d_inode(path->dentry), dentry, mode, 0);
+		err = vfs_mknod(d_inode(path.dentry), dentry, mode, 0);
 		if (!err) {
-			res->mnt = mntget(path->mnt);
+			res->mnt = mntget(path.mnt);
 			res->dentry = dget(dentry);
 		}
 	}
-
+	done_path_create(&path, dentry);
 	return err;
 }
 
@@ -977,12 +990,10 @@ static int unix_bind(struct socket *sock
 	struct unix_sock *u = unix_sk(sk);
 	struct sockaddr_un *sunaddr = (struct sockaddr_un *)uaddr;
 	char *sun_path = sunaddr->sun_path;
-	int err, name_err;
+	int err;
 	unsigned int hash;
 	struct unix_address *addr;
 	struct hlist_head *list;
-	struct path path;
-	struct dentry *dentry;
 
 	err = -EINVAL;
 	if (sunaddr->sun_family != AF_UNIX)
@@ -998,34 +1009,14 @@ static int unix_bind(struct socket *sock
 		goto out;
 	addr_len = err;
 
-	name_err = 0;
-	dentry = NULL;
-	if (sun_path[0]) {
-		/* Get the parent directory, calculate the hash for last
-		 * component.
-		 */
-		dentry = kern_path_create(AT_FDCWD, sun_path, &path, 0);
-
-		if (IS_ERR(dentry)) {
-			/* delay report until after 'already bound' check */
-			name_err = PTR_ERR(dentry);
-			dentry = NULL;
-		}
-	}
-
-	err = mutex_lock_interruptible(&u->readlock);
+	err = mutex_lock_interruptible(&u->bindlock);
 	if (err)
-		goto out_path;
+		goto out;
 
 	err = -EINVAL;
 	if (u->addr)
 		goto out_up;
 
-	if (name_err) {
-		err = name_err == -EEXIST ? -EADDRINUSE : name_err;
-		goto out_up;
-	}
-
 	err = -ENOMEM;
 	addr = kmalloc(sizeof(*addr)+addr_len, GFP_KERNEL);
 	if (!addr)
@@ -1036,11 +1027,11 @@ static int unix_bind(struct socket *sock
 	addr->hash = hash ^ sk->sk_type;
 	atomic_set(&addr->refcnt, 1);
 
-	if (dentry) {
-		struct path u_path;
+	if (sun_path[0]) {
+		struct path path;
 		umode_t mode = S_IFSOCK |
 		       (SOCK_INODE(sock)->i_mode & ~current_umask());
-		err = unix_mknod(dentry, &path, mode, &u_path);
+		err = unix_mknod(sun_path, mode, &path);
 		if (err) {
 			if (err == -EEXIST)
 				err = -EADDRINUSE;
@@ -1048,9 +1039,9 @@ static int unix_bind(struct socket *sock
 			goto out_up;
 		}
 		addr->hash = UNIX_HASH_SIZE;
-		hash = d_backing_inode(dentry)->i_ino & (UNIX_HASH_SIZE - 1);
+		hash = d_real_inode(path.dentry)->i_ino & (UNIX_HASH_SIZE - 1);
 		spin_lock(&unix_table_lock);
-		u->path = u_path;
+		u->path = path;
 		list = &unix_socket_table[hash];
 	} else {
 		spin_lock(&unix_table_lock);
@@ -1072,11 +1063,7 @@ static int unix_bind(struct socket *sock
 out_unlock:
 	spin_unlock(&unix_table_lock);
 out_up:
-	mutex_unlock(&u->readlock);
-out_path:
-	if (dentry)
-		done_path_create(&path, dentry);
-
+	mutex_unlock(&u->bindlock);
 out:
 	return err;
 }
@@ -1496,7 +1483,7 @@ static void unix_detach_fds(struct scm_c
 	UNIXCB(skb).fp = NULL;
 
 	for (i = scm->fp->count-1; i >= 0; i--)
-		unix_notinflight(scm->fp->fp[i]);
+		unix_notinflight(scm->fp->user, scm->fp->fp[i]);
 }
 
 static void unix_destruct_scm(struct sk_buff *skb)
@@ -1513,6 +1500,21 @@ static void unix_destruct_scm(struct sk_
 	sock_wfree(skb);
 }
 
+/*
+ * The "user->unix_inflight" variable is protected by the garbage
+ * collection lock, and we just read it locklessly here. If you go
+ * over the limit, there might be a tiny race in actually noticing
+ * it across threads. Tough.
+ */
+static inline bool too_many_unix_fds(struct task_struct *p)
+{
+	struct user_struct *user = current_user();
+
+	if (unlikely(user->unix_inflight > task_rlimit(p, RLIMIT_NOFILE)))
+		return !capable(CAP_SYS_RESOURCE) && !capable(CAP_SYS_ADMIN);
+	return false;
+}
+
 #define MAX_RECURSION_LEVEL 4
 
 static int unix_attach_fds(struct scm_cookie *scm, struct sk_buff *skb)
@@ -1521,6 +1523,9 @@ static int unix_attach_fds(struct scm_co
 	unsigned char max_level = 0;
 	int unix_sock_count = 0;
 
+	if (too_many_unix_fds(current))
+		return -ETOOMANYREFS;
+
 	for (i = scm->fp->count - 1; i >= 0; i--) {
 		struct sock *sk = unix_get_socket(scm->fp->fp[i]);
 
@@ -1542,10 +1547,8 @@ static int unix_attach_fds(struct scm_co
 	if (!UNIXCB(skb).fp)
 		return -ENOMEM;
 
-	if (unix_sock_count) {
-		for (i = scm->fp->count - 1; i >= 0; i--)
-			unix_inflight(scm->fp->fp[i]);
-	}
+	for (i = scm->fp->count - 1; i >= 0; i--)
+		unix_inflight(scm->fp->user, scm->fp->fp[i]);
 	return max_level;
 }
 
@@ -1765,7 +1768,12 @@ restart_locked:
 			goto out_unlock;
 	}
 
-	if (unlikely(unix_peer(other) != sk && unix_recvq_full(other))) {
+	/* other == sk && unix_peer(other) != sk if
+	 * - unix_peer(sk) == NULL, destination address bound to sk
+	 * - unix_peer(sk) == sk by time of get but disconnected before lock
+	 */
+	if (other != sk &&
+	    unlikely(unix_peer(other) != sk && unix_recvq_full(other))) {
 		if (timeo) {
 			timeo = unix_wait_for_peer(other, timeo);
 
@@ -1950,17 +1958,17 @@ static ssize_t unix_stream_sendpage(stru
 	if (false) {
 alloc_skb:
 		unix_state_unlock(other);
-		mutex_unlock(&unix_sk(other)->readlock);
+		mutex_unlock(&unix_sk(other)->iolock);
 		newskb = sock_alloc_send_pskb(sk, 0, 0, flags & MSG_DONTWAIT,
 					      &err, 0);
 		if (!newskb)
 			goto err;
 	}
 
-	/* we must acquire readlock as we modify already present
+	/* we must acquire iolock as we modify already present
 	 * skbs in the sk_receive_queue and mess with skb->len
 	 */
-	err = mutex_lock_interruptible(&unix_sk(other)->readlock);
+	err = mutex_lock_interruptible(&unix_sk(other)->iolock);
 	if (err) {
 		err = flags & MSG_DONTWAIT ? -EAGAIN : -ERESTARTSYS;
 		goto err;
@@ -2027,7 +2035,7 @@ alloc_skb:
 	}
 
 	unix_state_unlock(other);
-	mutex_unlock(&unix_sk(other)->readlock);
+	mutex_unlock(&unix_sk(other)->iolock);
 
 	other->sk_data_ready(other);
 	scm_destroy(&scm);
@@ -2036,7 +2044,7 @@ alloc_skb:
 err_state_unlock:
 	unix_state_unlock(other);
 err_unlock:
-	mutex_unlock(&unix_sk(other)->readlock);
+	mutex_unlock(&unix_sk(other)->iolock);
 err:
 	kfree_skb(newskb);
 	if (send_sigpipe && !(flags & MSG_NOSIGNAL))
@@ -2101,7 +2109,7 @@ static int unix_dgram_recvmsg(struct soc
 	if (flags&MSG_OOB)
 		goto out;
 
-	err = mutex_lock_interruptible(&u->readlock);
+	err = mutex_lock_interruptible(&u->iolock);
 	if (unlikely(err)) {
 		/* recvmsg() in non blocking mode is supposed to return -EAGAIN
 		 * sk_rcvtimeo is not honored by mutex_lock_interruptible()
@@ -2177,7 +2185,7 @@ static int unix_dgram_recvmsg(struct soc
 out_free:
 	skb_free_datagram(sk, skb);
 out_unlock:
-	mutex_unlock(&u->readlock);
+	mutex_unlock(&u->iolock);
 out:
 	return err;
 }
@@ -2254,13 +2262,15 @@ static int unix_stream_read_generic(stru
 	size_t size = state->size;
 	unsigned int last_len;
 
-	err = -EINVAL;
-	if (sk->sk_state != TCP_ESTABLISHED)
+	if (unlikely(sk->sk_state != TCP_ESTABLISHED)) {
+		err = -EINVAL;
 		goto out;
+	}
 
-	err = -EOPNOTSUPP;
-	if (flags & MSG_OOB)
+	if (unlikely(flags & MSG_OOB)) {
+		err = -EOPNOTSUPP;
 		goto out;
+	}
 
 	target = sock_rcvlowat(sk, flags & MSG_WAITALL, size);
 	timeo = sock_rcvtimeo(sk, noblock);
@@ -2270,7 +2280,7 @@ static int unix_stream_read_generic(stru
 	/* Lock the socket to prevent queue disordering
 	 * while sleeps in memcpy_tomsg
 	 */
-	mutex_lock(&u->readlock);
+	mutex_lock(&u->iolock);
 
 	if (flags & MSG_PEEK)
 		skip = sk_peek_offset(sk, flags);
@@ -2306,20 +2316,23 @@ again:
 				goto unlock;
 
 			unix_state_unlock(sk);
-			err = -EAGAIN;
-			if (!timeo)
+			if (!timeo) {
+				err = -EAGAIN;
 				break;
-			mutex_unlock(&u->readlock);
+			}
+
+			mutex_unlock(&u->iolock);
 
 			timeo = unix_stream_data_wait(sk, timeo, last,
 						      last_len);
 
 			if (signal_pending(current)) {
 				err = sock_intr_errno(timeo);
+				scm_destroy(&scm);
 				goto out;
 			}
 
-			mutex_lock(&u->readlock);
+			mutex_lock(&u->iolock);
 			continue;
 unlock:
 			unix_state_unlock(sk);
@@ -2422,7 +2435,7 @@ unlock:
 		}
 	} while (size);
 
-	mutex_unlock(&u->readlock);
+	mutex_unlock(&u->iolock);
 	if (state->msg)
 		scm_recv(sock, state->msg, &scm, flags);
 	else
@@ -2463,9 +2476,9 @@ static ssize_t skb_unix_socket_splice(st
 	int ret;
 	struct unix_sock *u = unix_sk(sk);
 
-	mutex_unlock(&u->readlock);
+	mutex_unlock(&u->iolock);
 	ret = splice_to_pipe(pipe, spd);
-	mutex_lock(&u->readlock);
+	mutex_lock(&u->iolock);
 
 	return ret;
 }
--- zfcpdump-kernel-4.4.orig/net/unix/diag.c
+++ zfcpdump-kernel-4.4/net/unix/diag.c
@@ -220,7 +220,7 @@ done:
 	return skb->len;
 }
 
-static struct sock *unix_lookup_by_ino(int ino)
+static struct sock *unix_lookup_by_ino(unsigned int ino)
 {
 	int i;
 	struct sock *sk;
--- zfcpdump-kernel-4.4.orig/net/unix/garbage.c
+++ zfcpdump-kernel-4.4/net/unix/garbage.c
@@ -116,15 +116,15 @@ struct sock *unix_get_socket(struct file
  * descriptor if it is for an AF_UNIX socket.
  */
 
-void unix_inflight(struct file *fp)
+void unix_inflight(struct user_struct *user, struct file *fp)
 {
 	struct sock *s = unix_get_socket(fp);
 
+	spin_lock(&unix_gc_lock);
+
 	if (s) {
 		struct unix_sock *u = unix_sk(s);
 
-		spin_lock(&unix_gc_lock);
-
 		if (atomic_long_inc_return(&u->inflight) == 1) {
 			BUG_ON(!list_empty(&u->link));
 			list_add_tail(&u->link, &gc_inflight_list);
@@ -132,25 +132,28 @@ void unix_inflight(struct file *fp)
 			BUG_ON(list_empty(&u->link));
 		}
 		unix_tot_inflight++;
-		spin_unlock(&unix_gc_lock);
 	}
+	user->unix_inflight++;
+	spin_unlock(&unix_gc_lock);
 }
 
-void unix_notinflight(struct file *fp)
+void unix_notinflight(struct user_struct *user, struct file *fp)
 {
 	struct sock *s = unix_get_socket(fp);
 
+	spin_lock(&unix_gc_lock);
+
 	if (s) {
 		struct unix_sock *u = unix_sk(s);
 
-		spin_lock(&unix_gc_lock);
 		BUG_ON(list_empty(&u->link));
 
 		if (atomic_long_dec_and_test(&u->inflight))
 			list_del_init(&u->link);
 		unix_tot_inflight--;
-		spin_unlock(&unix_gc_lock);
 	}
+	user->unix_inflight--;
+	spin_unlock(&unix_gc_lock);
 }
 
 static void scan_inflight(struct sock *x, void (*func)(struct unix_sock *),
--- zfcpdump-kernel-4.4.orig/net/vmw_vsock/af_vsock.c
+++ zfcpdump-kernel-4.4/net/vmw_vsock/af_vsock.c
@@ -1794,27 +1794,8 @@ vsock_stream_recvmsg(struct socket *sock
 	else if (sk->sk_shutdown & RCV_SHUTDOWN)
 		err = 0;
 
-	if (copied > 0) {
-		/* We only do these additional bookkeeping/notification steps
-		 * if we actually copied something out of the queue pair
-		 * instead of just peeking ahead.
-		 */
-
-		if (!(flags & MSG_PEEK)) {
-			/* If the other side has shutdown for sending and there
-			 * is nothing more to read, then modify the socket
-			 * state.
-			 */
-			if (vsk->peer_shutdown & SEND_SHUTDOWN) {
-				if (vsock_stream_has_data(vsk) <= 0) {
-					sk->sk_state = SS_UNCONNECTED;
-					sock_set_flag(sk, SOCK_DONE);
-					sk->sk_state_change(sk);
-				}
-			}
-		}
+	if (copied > 0)
 		err = copied;
-	}
 
 out_wait:
 	finish_wait(sk_sleep(sk), &wait);
--- zfcpdump-kernel-4.4.orig/net/wireless/core.c
+++ zfcpdump-kernel-4.4/net/wireless/core.c
@@ -1147,6 +1147,8 @@ static int cfg80211_netdev_notifier_call
 		return NOTIFY_DONE;
 	}
 
+	wireless_nlevent_flush();
+
 	return NOTIFY_OK;
 }
 
--- zfcpdump-kernel-4.4.orig/net/wireless/nl80211.c
+++ zfcpdump-kernel-4.4/net/wireless/nl80211.c
@@ -6628,7 +6628,7 @@ static int nl80211_channel_switch(struct
 
 		params.n_counter_offsets_presp = len / sizeof(u16);
 		if (rdev->wiphy.max_num_csa_counters &&
-		    (params.n_counter_offsets_beacon >
+		    (params.n_counter_offsets_presp >
 		     rdev->wiphy.max_num_csa_counters))
 			return -EINVAL;
 
@@ -13161,7 +13161,7 @@ static int nl80211_netlink_notify(struct
 	struct wireless_dev *wdev;
 	struct cfg80211_beacon_registration *reg, *tmp;
 
-	if (state != NETLINK_URELEASE)
+	if (state != NETLINK_URELEASE || notify->protocol != NETLINK_GENERIC)
 		return NOTIFY_DONE;
 
 	rcu_read_lock();
--- zfcpdump-kernel-4.4.orig/net/wireless/wext-core.c
+++ zfcpdump-kernel-4.4/net/wireless/wext-core.c
@@ -342,6 +342,40 @@ static const int compat_event_type_size[
 
 /* IW event code */
 
+void wireless_nlevent_flush(void)
+{
+	struct sk_buff *skb;
+	struct net *net;
+
+	ASSERT_RTNL();
+
+	for_each_net(net) {
+		while ((skb = skb_dequeue(&net->wext_nlevents)))
+			rtnl_notify(skb, net, 0, RTNLGRP_LINK, NULL,
+				    GFP_KERNEL);
+	}
+}
+EXPORT_SYMBOL_GPL(wireless_nlevent_flush);
+
+static int wext_netdev_notifier_call(struct notifier_block *nb,
+				     unsigned long state, void *ptr)
+{
+	/*
+	 * When a netdev changes state in any way, flush all pending messages
+	 * to avoid them going out in a strange order, e.g. RTM_NEWLINK after
+	 * RTM_DELLINK, or with IFF_UP after without IFF_UP during dev_close()
+	 * or similar - all of which could otherwise happen due to delays from
+	 * schedule_work().
+	 */
+	wireless_nlevent_flush();
+
+	return NOTIFY_OK;
+}
+
+static struct notifier_block wext_netdev_notifier = {
+	.notifier_call = wext_netdev_notifier_call,
+};
+
 static int __net_init wext_pernet_init(struct net *net)
 {
 	skb_queue_head_init(&net->wext_nlevents);
@@ -360,7 +394,12 @@ static struct pernet_operations wext_per
 
 static int __init wireless_nlevent_init(void)
 {
-	return register_pernet_subsys(&wext_pernet_ops);
+	int err = register_pernet_subsys(&wext_pernet_ops);
+
+	if (err)
+		return err;
+
+	return register_netdevice_notifier(&wext_netdev_notifier);
 }
 
 subsys_initcall(wireless_nlevent_init);
@@ -368,17 +407,8 @@ subsys_initcall(wireless_nlevent_init);
 /* Process events generated by the wireless layer or the driver. */
 static void wireless_nlevent_process(struct work_struct *work)
 {
-	struct sk_buff *skb;
-	struct net *net;
-
 	rtnl_lock();
-
-	for_each_net(net) {
-		while ((skb = skb_dequeue(&net->wext_nlevents)))
-			rtnl_notify(skb, net, 0, RTNLGRP_LINK, NULL,
-				    GFP_KERNEL);
-	}
-
+	wireless_nlevent_flush();
 	rtnl_unlock();
 }
 
--- zfcpdump-kernel-4.4.orig/net/x25/x25_facilities.c
+++ zfcpdump-kernel-4.4/net/x25/x25_facilities.c
@@ -277,6 +277,7 @@ int x25_negotiate_facilities(struct sk_b
 
 	memset(&theirs, 0, sizeof(theirs));
 	memcpy(new, ours, sizeof(*new));
+	memset(dte, 0, sizeof(*dte));
 
 	len = x25_parse_facilities(skb, &theirs, dte, &x25->vc_facil_mask);
 	if (len < 0)
--- zfcpdump-kernel-4.4.orig/net/xfrm/xfrm_input.c
+++ zfcpdump-kernel-4.4/net/xfrm/xfrm_input.c
@@ -292,12 +292,15 @@ int xfrm_input(struct sk_buff *skb, int
 		XFRM_SKB_CB(skb)->seq.input.hi = seq_hi;
 
 		skb_dst_force(skb);
+		dev_hold(skb->dev);
 
 		nexthdr = x->type->input(x, skb);
 
 		if (nexthdr == -EINPROGRESS)
 			return 0;
 resume:
+		dev_put(skb->dev);
+
 		spin_lock(&x->lock);
 		if (nexthdr <= 0) {
 			if (nexthdr == -EBADMSG) {
--- zfcpdump-kernel-4.4.orig/net/xfrm/xfrm_output.c
+++ zfcpdump-kernel-4.4/net/xfrm/xfrm_output.c
@@ -167,6 +167,8 @@ static int xfrm_output_gso(struct net *n
 {
 	struct sk_buff *segs;
 
+	BUILD_BUG_ON(sizeof(*IPCB(skb)) > SKB_SGO_CB_OFFSET);
+	BUILD_BUG_ON(sizeof(*IP6CB(skb)) > SKB_SGO_CB_OFFSET);
 	segs = skb_gso_segment(skb, 0);
 	kfree_skb(skb);
 	if (IS_ERR(segs))
--- zfcpdump-kernel-4.4.orig/net/xfrm/xfrm_policy.c
+++ zfcpdump-kernel-4.4/net/xfrm/xfrm_policy.c
@@ -626,6 +626,10 @@ static void xfrm_hash_rebuild(struct wor
 
 	/* re-insert all policies by order of creation */
 	list_for_each_entry_reverse(policy, &net->xfrm.policy_all, walk.all) {
+		if (xfrm_policy_id2dir(policy->index) >= XFRM_POLICY_MAX) {
+			/* skip socket policies */
+			continue;
+		}
 		newpos = NULL;
 		chain = policy_hash_bysel(net, &policy->selector,
 					  policy->family,
--- zfcpdump-kernel-4.4.orig/samples/bpf/trace_output_kern.c
+++ zfcpdump-kernel-4.4/samples/bpf/trace_output_kern.c
@@ -18,7 +18,6 @@ int bpf_prog1(struct pt_regs *ctx)
 		u64 cookie;
 	} data;
 
-	memset(&data, 0, sizeof(data));
 	data.pid = bpf_get_current_pid_tgid();
 	data.cookie = 0x12345678;
 
--- zfcpdump-kernel-4.4.orig/scripts/Makefile
+++ zfcpdump-kernel-4.4/scripts/Makefile
@@ -19,6 +19,7 @@ hostprogs-$(CONFIG_BUILDTIME_EXTABLE_SOR
 hostprogs-$(CONFIG_ASN1)	 += asn1_compiler
 hostprogs-$(CONFIG_MODULE_SIG)	 += sign-file
 hostprogs-$(CONFIG_SYSTEM_TRUSTED_KEYRING) += extract-cert
+hostprogs-$(CONFIG_SYSTEM_EXTRA_CERTIFICATE) += insert-sys-cert
 
 HOSTCFLAGS_sortextable.o = -I$(srctree)/tools/include
 HOSTCFLAGS_asn1_compiler.o = -I$(srctree)/include
--- zfcpdump-kernel-4.4.orig/scripts/Makefile.extrawarn
+++ zfcpdump-kernel-4.4/scripts/Makefile.extrawarn
@@ -24,6 +24,7 @@ warning-1 += $(call cc-option, -Wmissing
 warning-1 += -Wold-style-definition
 warning-1 += $(call cc-option, -Wmissing-include-dirs)
 warning-1 += $(call cc-option, -Wunused-but-set-variable)
+warning-1 += $(call cc-option, -Wunused-const-variable)
 warning-1 += $(call cc-disable-warning, missing-field-initializers)
 
 warning-2 := -Waggregate-return
--- zfcpdump-kernel-4.4.orig/scripts/bloat-o-meter
+++ zfcpdump-kernel-4.4/scripts/bloat-o-meter
@@ -58,8 +58,8 @@ for name in common:
 delta.sort()
 delta.reverse()
 
-print "add/remove: %s/%s grow/shrink: %s/%s up/down: %s/%s (%s)" % \
-      (add, remove, grow, shrink, up, -down, up-down)
-print "%-40s %7s %7s %+7s" % ("function", "old", "new", "delta")
+print("add/remove: %s/%s grow/shrink: %s/%s up/down: %s/%s (%s)" % \
+      (add, remove, grow, shrink, up, -down, up-down))
+print("%-40s %7s %7s %+7s" % ("function", "old", "new", "delta"))
 for d, n in delta:
-    if d: print "%-40s %7s %7s %+7d" % (n, old.get(n,"-"), new.get(n,"-"), d)
+    if d: print("%-40s %7s %7s %+7d" % (n, old.get(n,"-"), new.get(n,"-"), d))
--- zfcpdump-kernel-4.4.orig/scripts/coccinelle/iterators/use_after_iter.cocci
+++ zfcpdump-kernel-4.4/scripts/coccinelle/iterators/use_after_iter.cocci
@@ -123,7 +123,7 @@ list_remove_head(x,c,...)
 |
 sizeof(<+...c...+>)
 |
-&c->member
+ &c->member
 |
 c = E
 |
--- zfcpdump-kernel-4.4.orig/scripts/extract-sys-certs.pl
+++ zfcpdump-kernel-4.4/scripts/extract-sys-certs.pl
@@ -91,13 +91,15 @@ print "Have $nr_symbols symbols\n";
 
 die "Can't find system certificate list"
     unless (exists($symbols{"__cert_list_start"}) &&
-	    exists($symbols{"__cert_list_end"}));
+	    exists($symbols{"system_certificate_list_size"}));
 
 my $start = Math::BigInt->new($symbols{"__cert_list_start"});
-my $end = Math::BigInt->new($symbols{"__cert_list_end"});
-my $size = $end - $start;
+my $end;
+my $size;
+my $size_sym = Math::BigInt->new($symbols{"system_certificate_list_size"});
 
-printf "Have %u bytes of certs at VMA 0x%x\n", $size, $start;
+open FD, "<$vmlinux" || die $vmlinux;
+binmode(FD);
 
 my $s = undef;
 foreach my $sec (@sections) {
@@ -110,11 +112,24 @@ foreach my $sec (@sections) {
     next unless ($start >= $s_vma);
     next if ($start >= $s_vend);
 
-    die "Cert object partially overflows section $s_name\n"
-	if ($end > $s_vend);
+    die "Certificate list size was not found on the same section\n"
+	if ($size_sym < $s_vma || $size_sym > $s_vend);
 
     die "Cert object in multiple sections: ", $s_name, " and ", $s->{name}, "\n"
 	if ($s);
+
+    my $size_off = $size_sym -$s_vma + $s_foff;
+    my $packed;
+    die $vmlinux if (!defined(sysseek(FD, $size_off, SEEK_SET)));
+    sysread(FD, $packed, 8);
+    $size = unpack 'L!', $packed;
+    $end = $start + $size;
+
+    printf "Have %u bytes of certs at VMA 0x%x\n", $size, $start;
+
+    die "Cert object partially overflows section $s_name\n"
+	if ($end > $s_vend);
+
     $s = $sec;
 }
 
@@ -127,8 +142,6 @@ my $foff = $start - $s->{vma} + $s->{fof
 
 printf "Certificate list at file offset 0x%x\n", $foff;
 
-open FD, "<$vmlinux" || die $vmlinux;
-binmode(FD);
 die $vmlinux if (!defined(sysseek(FD, $foff, SEEK_SET)));
 my $buf = "";
 my $len = sysread(FD, $buf, $size);
--- /dev/null
+++ zfcpdump-kernel-4.4/scripts/insert-sys-cert.c
@@ -0,0 +1,606 @@
+/* Write the contents of the <certfile> into kernel symbol system_extra_cert
+ *
+ * Copyright (C) IBM Corporation, 2015
+ *
+ * Author: Mehmet Kayaalp <mkayaalp@linux.vnet.ibm.com>
+ *
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
+ *
+ * Usage: insert-sys-cert [-s <System.map>] -b <vmlinux> -c <certfile>
+ *                        [-s <System.map>] -z <bzImage> -c <certfile>
+ */
+
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <ctype.h>
+#include <string.h>
+#include <limits.h>
+#include <stdbool.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <elf.h>
+
+#define CERT_SYM  "system_extra_cert"
+#define USED_SYM  "system_extra_cert_used"
+#define LSIZE_SYM "system_certificate_list_size"
+
+#define info(format, args...) fprintf(stderr, "INFO:    " format, ## args)
+#define warn(format, args...) fprintf(stdout, "WARNING: " format, ## args)
+#define  err(format, args...) fprintf(stderr, "ERROR:   " format, ## args)
+
+#if UINTPTR_MAX == 0xffffffff
+#define CURRENT_ELFCLASS ELFCLASS32
+#define Elf_Ehdr	Elf32_Ehdr
+#define Elf_Shdr	Elf32_Shdr
+#define Elf_Sym		Elf32_Sym
+#else
+#define CURRENT_ELFCLASS ELFCLASS64
+#define Elf_Ehdr	Elf64_Ehdr
+#define Elf_Shdr	Elf64_Shdr
+#define Elf_Sym		Elf64_Sym
+#endif
+
+static unsigned char endianness(void)
+{
+	uint16_t two_byte = 0x00FF;
+	uint8_t low_address = *((uint8_t *)&two_byte);
+
+	if (low_address == 0)
+		return ELFDATA2MSB;
+	else
+		return ELFDATA2LSB;
+}
+
+struct sym {
+	char *name;
+	unsigned long address;
+	unsigned long offset;
+	void *content;
+	int size;
+};
+
+static unsigned long get_offset_from_address(Elf_Ehdr *hdr, unsigned long addr)
+{
+	Elf_Shdr *x;
+	unsigned int i, num_sections;
+
+	x = (void *)hdr + hdr->e_shoff;
+	if (hdr->e_shnum == SHN_UNDEF)
+		num_sections = x[0].sh_size;
+	else
+		num_sections = hdr->e_shnum;
+
+	for (i = 1; i < num_sections; i++) {
+		unsigned long start = x[i].sh_addr;
+		unsigned long end = start + x[i].sh_size;
+		unsigned long offset = x[i].sh_offset;
+
+		if (addr >= start && addr <= end)
+			return addr - start + offset;
+	}
+	return 0;
+}
+
+
+#define LINE_SIZE 100
+
+static void get_symbol_from_map(Elf_Ehdr *hdr, FILE *f, char *name,
+				struct sym *s)
+{
+	char l[LINE_SIZE];
+	char *w, *p, *n;
+
+	s->size = 0;
+	s->address = 0;
+	s->offset = 0;
+	if (fseek(f, 0, SEEK_SET) != 0) {
+		perror("File seek failed");
+		exit(EXIT_FAILURE);
+	}
+	while (fgets(l, LINE_SIZE, f)) {
+		p = strchr(l, '\n');
+		if (!p) {
+			err("Missing line ending.\n");
+			return;
+		}
+		n = strstr(l, name);
+		if (n)
+			break;
+	}
+	if (!n) {
+		err("Unable to find symbol: %s\n", name);
+		return;
+	}
+	w = strchr(l, ' ');
+	if (!w)
+		return;
+
+	*w = '\0';
+	s->address = strtoul(l, NULL, 16);
+	if (s->address == 0)
+		return;
+	s->offset = get_offset_from_address(hdr, s->address);
+	s->name = name;
+	s->content = (void *)hdr + s->offset;
+}
+
+static Elf_Sym *find_elf_symbol(Elf_Ehdr *hdr, Elf_Shdr *symtab, char *name)
+{
+	Elf_Sym *sym, *symtab_start;
+	char *strtab, *symname;
+	unsigned int link;
+	Elf_Shdr *x;
+	int i, n;
+
+	x = (void *)hdr + hdr->e_shoff;
+	link = symtab->sh_link;
+	symtab_start = (void *)hdr + symtab->sh_offset;
+	n = symtab->sh_size / symtab->sh_entsize;
+	strtab = (void *)hdr + x[link].sh_offset;
+
+	for (i = 0; i < n; i++) {
+		sym = &symtab_start[i];
+		symname = strtab + sym->st_name;
+		if (strcmp(symname, name) == 0)
+			return sym;
+	}
+	err("Unable to find symbol: %s\n", name);
+	return NULL;
+}
+
+static void get_symbol_from_table(Elf_Ehdr *hdr, Elf_Shdr *symtab,
+				  char *name, struct sym *s)
+{
+	Elf_Shdr *sec;
+	int secndx;
+	Elf_Sym *elf_sym;
+	Elf_Shdr *x;
+
+	x = (void *)hdr + hdr->e_shoff;
+	s->size = 0;
+	s->address = 0;
+	s->offset = 0;
+	elf_sym = find_elf_symbol(hdr, symtab, name);
+	if (!elf_sym)
+		return;
+	secndx = elf_sym->st_shndx;
+	if (!secndx)
+		return;
+	sec = &x[secndx];
+	s->size = elf_sym->st_size;
+	s->address = elf_sym->st_value;
+	s->offset = s->address - sec->sh_addr
+			       + sec->sh_offset;
+	s->name = name;
+	s->content = (void *)hdr + s->offset;
+}
+
+static Elf_Shdr *get_symbol_table(Elf_Ehdr *hdr)
+{
+	Elf_Shdr *x;
+	unsigned int i, num_sections;
+
+	x = (void *)hdr + hdr->e_shoff;
+	if (hdr->e_shnum == SHN_UNDEF)
+		num_sections = x[0].sh_size;
+	else
+		num_sections = hdr->e_shnum;
+
+	for (i = 1; i < num_sections; i++)
+		if (x[i].sh_type == SHT_SYMTAB)
+			return &x[i];
+	return NULL;
+}
+
+static void *map_file(char *file_name, int *size)
+{
+	struct stat st;
+	void *map;
+	int fd;
+
+	fd = open(file_name, O_RDWR);
+	if (fd < 0) {
+		perror(file_name);
+		return NULL;
+	}
+	if (fstat(fd, &st)) {
+		perror("Could not determine file size");
+		close(fd);
+		return NULL;
+	}
+	*size = st.st_size;
+	map = mmap(NULL, *size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
+	if (map == MAP_FAILED) {
+		perror("Mapping to memory failed");
+		close(fd);
+		return NULL;
+	}
+	close(fd);
+	return map;
+}
+
+static char *read_file(char *file_name, int *size)
+{
+	struct stat st;
+	char *buf;
+	int fd;
+
+	fd = open(file_name, O_RDONLY);
+	if (fd < 0) {
+		perror(file_name);
+		return NULL;
+	}
+	if (fstat(fd, &st)) {
+		perror("Could not determine file size");
+		close(fd);
+		return NULL;
+	}
+	*size = st.st_size;
+	buf = malloc(*size);
+	if (!buf) {
+		perror("Allocating memory failed");
+		close(fd);
+		return NULL;
+	}
+	if (read(fd, buf, *size) != *size) {
+		perror("File read failed");
+		close(fd);
+		return NULL;
+	}
+	close(fd);
+	return buf;
+}
+
+static void get_payload_info(char *bzimage, int *offset, int *size)
+{
+	unsigned int system_offset;
+	unsigned char setup_sectors;
+
+	setup_sectors = bzimage[0x1f1] + 1;
+	system_offset = setup_sectors * 512;
+	*offset = system_offset + *((int*)&bzimage[0x248]);
+	*size = *((int*)&bzimage[0x24c]);
+}
+
+static void update_payload_info(char* bzimage, int new_size)
+{
+	int offset, size;
+	get_payload_info(bzimage, &offset, &size);
+	*((int*)&bzimage[0x24c]) = new_size;
+	if (new_size < size)
+		memset(bzimage + offset + new_size, 0, size - new_size);
+}
+
+struct zipper {
+	unsigned char pattern[10];
+	int length;
+	char *command;
+	char *compress;
+};
+
+struct zipper zippers[] = {
+	{{0x7F,'E','L','F'}, 4, "cat", "cat"},
+	{{0x1F,0x8B}, 2, "gunzip", "gzip -n -f -9"},
+	{{0xFD,'7','z','X','Z',0}, 6, "unxz", "xz"},
+	{{'B','Z','h'},3, "bunzip2", "bzip2 -9"},
+	{{0xFF,'L','Z','M','A',0}, 6, "unlzma", "lzma -9"},
+	{{0xD3,'L','Z','O',0,'\r','\n',0x20,'\n'}, 9, "lzop -d", "lzop -9"}
+};
+
+static struct zipper* get_zipper(char *p) {
+	int i;
+	for (i = 0; i < sizeof(zippers)/sizeof(struct zipper); i++) {
+		if (memcmp(p, zippers[i].pattern, zippers[i].length) == 0)
+			return &zippers[i];
+	}
+	return NULL;
+}
+
+/*
+ * This only works for x86 bzImage
+ */
+static void extract_vmlinux(char *bzimage, int bzimage_size,
+			char **file, struct zipper **zipper)
+{
+	int r;
+	char src[15] = "vmlinux-XXXXXX";
+	char dest[15] = "vmlinux-XXXXXX";
+	char cmd[100];
+	int src_fd, dest_fd;
+	int offset, size;
+	struct zipper *z;
+
+	/* TODO: verify that bzImage is supported */
+
+	get_payload_info(bzimage, &offset, &size);
+	z = get_zipper(bzimage + offset);
+	if (z == NULL) {
+		err("Unable to determine the compression of vmlinux\n");
+		return;
+	}
+
+	src_fd = mkstemp(src);
+	if (src_fd == -1) {
+		perror("Could not create temp file");
+		return;
+	}
+
+	r = write(src_fd, bzimage + offset, size);
+	if (r != size) {
+		perror("Could not write vmlinux");
+		return;
+	}
+	dest_fd = mkstemp(dest);
+	if (dest_fd == -1) {
+		perror("Could not create temp file");
+		return;
+	}
+
+	snprintf(cmd, sizeof(cmd), "%s <%s >%s", z->command, src, dest);
+	info("Executing: %s\n", cmd);
+	r = system(cmd);
+	if (r!=0)
+		warn("Possible errors when extracting\n");
+
+	r = remove(src);
+	if (r!=0)
+		perror(src);
+
+	*file = strdup(dest);
+	*zipper = z;
+}
+
+static void repack_image(char *bzimage, int bzimage_size,
+			char* vmlinux_file, struct zipper *z)
+{
+	char tmp[15] = "vmlinux-XXXXXX";
+	char cmd[100];
+	int fd;
+	struct stat st;
+	int new_size;
+	int r;
+	int offset, size;
+
+	get_payload_info(bzimage, &offset, &size);
+
+	fd = mkstemp(tmp);
+	if (fd == -1) {
+		perror("Could not create temp file");
+		return;
+	}
+	snprintf(cmd, sizeof(cmd), "%s <%s >%s",
+			z->compress, vmlinux_file, tmp);
+
+	info("Executing: %s\n", cmd);
+	r = system(cmd);
+	if (r!=0)
+		warn("Possible errors when compressing\n");
+
+	r = remove(vmlinux_file);
+	if (r!=0)
+		perror(vmlinux_file);
+
+	if (fstat(fd, &st)) {
+		perror("Could not determine file size");
+		close(fd);
+
+	}
+	new_size = st.st_size;
+	if (new_size > size) {
+		err("Increase in compressed size is not supported.\n");
+		err("Old size was %d, new size is %d\n", size, new_size);
+		exit(EXIT_FAILURE);
+	}
+
+	r = read(fd, bzimage + offset, new_size);
+	if (r != new_size)
+		perror(tmp);
+
+	r = remove(tmp);
+	if (r!=0)
+		perror(tmp);
+
+	/* x86 specific patching of bzimage */
+	update_payload_info(bzimage, new_size);
+
+	/* TODO: update CRC */
+
+}
+
+static void fill_random(unsigned char *p, int n) {
+	srand(0);
+	int i;
+	for (i = 0; i < n; i++)
+		p[i] = rand();
+}
+
+static void print_sym(Elf_Ehdr *hdr, struct sym *s)
+{
+	info("sym:    %s\n", s->name);
+	info("addr:   0x%lx\n", s->address);
+	info("size:   %d\n", s->size);
+	info("offset: 0x%lx\n", (unsigned long)s->offset);
+}
+
+static void print_usage(char *e)
+{
+	printf("Usage: %s [-s <System.map>] -b <vmlinux> -c <certfile>\n", e);
+	printf("       %s [-s <System.map>] -z <bzImage> -c <certfile>\n", e);
+}
+
+int main(int argc, char **argv)
+{
+	char *system_map_file = NULL;
+	char *vmlinux_file = NULL;
+	char *bzimage_file = NULL;
+	char *cert_file = NULL;
+	int vmlinux_size;
+	int bzimage_size;
+	int cert_size;
+	Elf_Ehdr *hdr;
+	char *cert;
+	char *bzimage = NULL;
+	struct zipper *z = NULL;
+	FILE *system_map;
+	unsigned long *lsize;
+	int *used;
+	int opt;
+	Elf_Shdr *symtab = NULL;
+	struct sym cert_sym, lsize_sym, used_sym;
+
+	while ((opt = getopt(argc, argv, "b:z:c:s:")) != -1) {
+		switch (opt) {
+		case 's':
+			system_map_file = optarg;
+			break;
+		case 'b':
+			vmlinux_file = optarg;
+			break;
+		case 'z':
+			bzimage_file = optarg;
+			break;
+		case 'c':
+			cert_file = optarg;
+			break;
+		default:
+			break;
+		}
+	}
+
+	if (!cert_file ||
+	(!vmlinux_file && !bzimage_file) ||
+	(vmlinux_file && bzimage_file)) {
+		print_usage(argv[0]);
+		exit(EXIT_FAILURE);
+	}
+
+	cert = read_file(cert_file, &cert_size);
+	if (!cert)
+		exit(EXIT_FAILURE);
+
+	if (bzimage_file) {
+		bzimage = map_file(bzimage_file, &bzimage_size);
+		if (!bzimage)
+			exit(EXIT_FAILURE);
+
+		extract_vmlinux(bzimage, bzimage_size, &vmlinux_file, &z);
+		if (!vmlinux_file)
+			exit(EXIT_FAILURE);
+	}
+
+	hdr = map_file(vmlinux_file, &vmlinux_size);
+	if (!hdr)
+		exit(EXIT_FAILURE);
+
+	if (vmlinux_size < sizeof(*hdr)) {
+		err("Invalid ELF file.\n");
+		exit(EXIT_FAILURE);
+	}
+
+	if ((hdr->e_ident[EI_MAG0] != ELFMAG0) ||
+	    (hdr->e_ident[EI_MAG1] != ELFMAG1) ||
+	    (hdr->e_ident[EI_MAG2] != ELFMAG2) ||
+	    (hdr->e_ident[EI_MAG3] != ELFMAG3)) {
+		err("Invalid ELF magic.\n");
+		exit(EXIT_FAILURE);
+	}
+
+	if (hdr->e_ident[EI_CLASS] != CURRENT_ELFCLASS) {
+		err("ELF class mismatch.\n");
+		exit(EXIT_FAILURE);
+	}
+
+	if (hdr->e_ident[EI_DATA] != endianness()) {
+		err("ELF endian mismatch.\n");
+		exit(EXIT_FAILURE);
+	}
+
+	if (hdr->e_shoff > vmlinux_size) {
+		err("Could not find section header.\n");
+		exit(EXIT_FAILURE);
+	}
+
+	symtab = get_symbol_table(hdr);
+	if (!symtab) {
+		warn("Could not find the symbol table.\n");
+		if (!system_map_file) {
+			err("Please provide a System.map file.\n");
+			print_usage(argv[0]);
+			exit(EXIT_FAILURE);
+		}
+
+		system_map = fopen(system_map_file, "r");
+		if (!system_map) {
+			perror(system_map_file);
+			exit(EXIT_FAILURE);
+		}
+		get_symbol_from_map(hdr, system_map, CERT_SYM, &cert_sym);
+		get_symbol_from_map(hdr, system_map, USED_SYM, &used_sym);
+		get_symbol_from_map(hdr, system_map, LSIZE_SYM, &lsize_sym);
+		cert_sym.size = used_sym.address - cert_sym.address;
+	} else {
+		info("Symbol table found.\n");
+		if (system_map_file)
+			warn("System.map is ignored.\n");
+		get_symbol_from_table(hdr, symtab, CERT_SYM, &cert_sym);
+		get_symbol_from_table(hdr, symtab, USED_SYM, &used_sym);
+		get_symbol_from_table(hdr, symtab, LSIZE_SYM, &lsize_sym);
+	}
+
+	if (!cert_sym.offset || !lsize_sym.offset || !used_sym.offset)
+		exit(EXIT_FAILURE);
+
+	print_sym(hdr, &cert_sym);
+	print_sym(hdr, &used_sym);
+	print_sym(hdr, &lsize_sym);
+
+	lsize = (unsigned long *)lsize_sym.content;
+	used = (int *)used_sym.content;
+
+	if (cert_sym.size < cert_size) {
+		err("Certificate is larger than the reserved area!\n");
+		exit(EXIT_FAILURE);
+	}
+
+	/* If the existing cert is the same, don't overwrite */
+	if (cert_size > 0 && cert_size == *used &&
+	    strncmp(cert_sym.content, cert, cert_size) == 0) {
+		warn("Certificate was already inserted.\n");
+		exit(EXIT_SUCCESS);
+	}
+
+	if (*used > 0)
+		warn("Replacing previously inserted certificate.\n");
+
+	memcpy(cert_sym.content, cert, cert_size);
+
+	if (cert_size < cert_sym.size)
+		/* This makes the reserved space incompressable */
+		fill_random(cert_sym.content + cert_size,
+				cert_sym.size - cert_size);
+
+	*lsize = *lsize + cert_size - *used;
+	*used = cert_size;
+	info("Inserted the contents of %s into %lx.\n", cert_file,
+						cert_sym.address);
+	info("Used %d bytes out of %d bytes reserved.\n", *used,
+						 cert_sym.size);
+
+	if (munmap(hdr, vmlinux_size) == -1) {
+		perror(vmlinux_file);
+		exit(EXIT_FAILURE);
+	}
+
+	if (bzimage) {
+		repack_image(bzimage, bzimage_size, vmlinux_file, z);
+	}
+
+	exit(EXIT_SUCCESS);
+}
--- zfcpdump-kernel-4.4.orig/scripts/kconfig/Makefile
+++ zfcpdump-kernel-4.4/scripts/kconfig/Makefile
@@ -96,13 +96,15 @@ savedefconfig: $(obj)/conf
 defconfig: $(obj)/conf
 ifeq ($(KBUILD_DEFCONFIG),)
 	$< $(silent) --defconfig $(Kconfig)
-else ifneq ($(wildcard $(srctree)/arch/$(SRCARCH)/configs/$(KBUILD_DEFCONFIG)),)
+else
+ifneq ($(wildcard $(srctree)/arch/$(SRCARCH)/configs/$(KBUILD_DEFCONFIG)),)
 	@$(kecho) "*** Default configuration is based on '$(KBUILD_DEFCONFIG)'"
 	$(Q)$< $(silent) --defconfig=arch/$(SRCARCH)/configs/$(KBUILD_DEFCONFIG) $(Kconfig)
 else
 	@$(kecho) "*** Default configuration is based on target '$(KBUILD_DEFCONFIG)'"
 	$(Q)$(MAKE) -f $(srctree)/Makefile $(KBUILD_DEFCONFIG)
 endif
+endif
 
 %_defconfig: $(obj)/conf
 	$(Q)$< $(silent) --defconfig=arch/$(SRCARCH)/configs/$@ $(Kconfig)
--- zfcpdump-kernel-4.4.orig/scripts/kconfig/confdata.c
+++ zfcpdump-kernel-4.4/scripts/kconfig/confdata.c
@@ -267,10 +267,8 @@ int conf_read_simple(const char *name, i
 		if (in)
 			goto load;
 		sym_add_change_count(1);
-		if (!sym_defconfig_list) {
-			sym_calc_value(modules_sym);
+		if (!sym_defconfig_list)
 			return 1;
-		}
 
 		for_all_defaults(sym_defconfig_list, prop) {
 			if (expr_calc_value(prop->visible.expr) == no ||
@@ -403,7 +401,6 @@ setsym:
 	}
 	free(line);
 	fclose(in);
-	sym_calc_value(modules_sym);
 	return 0;
 }
 
@@ -414,8 +411,12 @@ int conf_read(const char *name)
 
 	sym_set_change_count(0);
 
-	if (conf_read_simple(name, S_DEF_USER))
+	if (conf_read_simple(name, S_DEF_USER)) {
+		sym_calc_value(modules_sym);
 		return 1;
+	}
+
+	sym_calc_value(modules_sym);
 
 	for_all_symbols(i, sym) {
 		sym_calc_value(sym);
@@ -846,6 +847,7 @@ static int conf_split_config(void)
 
 	name = conf_get_autoconfig_name();
 	conf_read_simple(name, S_DEF_AUTO);
+	sym_calc_value(modules_sym);
 
 	if (chdir("include/config"))
 		return 1;
--- zfcpdump-kernel-4.4.orig/scripts/kconfig/lkc.h
+++ zfcpdump-kernel-4.4/scripts/kconfig/lkc.h
@@ -88,7 +88,9 @@ void set_all_choice_values(struct symbol
 /* confdata.c and expr.c */
 static inline void xfwrite(const void *str, size_t len, size_t count, FILE *out)
 {
-	assert(len != 0);
+	//assert(len != 0);
+	if (len == 0)
+		return;
 
 	if (fwrite(str, len, count, out) != count)
 		fprintf(stderr, "Error in writing or end of file.\n");
--- zfcpdump-kernel-4.4.orig/scripts/ld-version.sh
+++ zfcpdump-kernel-4.4/scripts/ld-version.sh
@@ -1,7 +1,7 @@
 #!/usr/bin/awk -f
 # extract linker version number from stdin and turn into single number
 	{
-	gsub(".*)", "");
+	gsub(".*\\)", "");
 	split($1,a, ".");
 	print a[1]*10000000 + a[2]*100000 + a[3]*10000 + a[4]*100 + a[5];
 	exit
--- zfcpdump-kernel-4.4.orig/scripts/link-vmlinux.sh
+++ zfcpdump-kernel-4.4/scripts/link-vmlinux.sh
@@ -62,7 +62,7 @@ vmlinux_link()
 			-Wl,--start-group                                    \
 				 ${KBUILD_VMLINUX_MAIN}                      \
 			-Wl,--end-group                                      \
-			-lutil -lrt ${1}
+			-lutil -lrt -lpthread ${1}
 		rm -f linux
 	fi
 }
--- zfcpdump-kernel-4.4.orig/scripts/mod/file2alias.c
+++ zfcpdump-kernel-4.4/scripts/mod/file2alias.c
@@ -695,7 +695,7 @@ static int do_of_entry (const char *file
 	len = sprintf(alias, "of:N%sT%s", (*name)[0] ? *name : "*",
 		      (*type)[0] ? *type : "*");
 
-	if (compatible[0])
+	if ((*compatible)[0])
 		sprintf(&alias[len], "%sC%s", (*type)[0] ? "*" : "",
 			*compatible);
 
@@ -917,7 +917,7 @@ static int do_vmbus_entry(const char *fi
 	char guid_name[(sizeof(*guid) + 1) * 2];
 
 	for (i = 0; i < (sizeof(*guid) * 2); i += 2)
-		sprintf(&guid_name[i], "%02x", TO_NATIVE((*guid)[i/2]));
+		sprintf(&guid_name[i], "%02x", TO_NATIVE((guid->b)[i/2]));
 
 	strcpy(alias, "vmbus:");
 	strcat(alias, guid_name);
--- zfcpdump-kernel-4.4.orig/scripts/package/Makefile
+++ zfcpdump-kernel-4.4/scripts/package/Makefile
@@ -52,7 +52,7 @@ rpm-pkg rpm: FORCE
 	$(call cmd,src_tar,$(KERNELPATH),kernel.spec)
 	$(CONFIG_SHELL) $(srctree)/scripts/mkversion > $(objtree)/.tmp_version
 	mv -f $(objtree)/.tmp_version $(objtree)/.version
-	rpmbuild --target $(UTS_MACHINE) -ta $(KERNELPATH).tar.gz
+	rpmbuild $(RPMOPTS) --target $(UTS_MACHINE) -ta $(KERNELPATH).tar.gz
 	rm $(KERNELPATH).tar.gz kernel.spec
 
 # binrpm-pkg
@@ -63,7 +63,7 @@ binrpm-pkg: FORCE
 	$(CONFIG_SHELL) $(srctree)/scripts/mkversion > $(objtree)/.tmp_version
 	mv -f $(objtree)/.tmp_version $(objtree)/.version
 
-	rpmbuild --define "_builddir $(objtree)" --target \
+	rpmbuild $(RPMOPTS) --define "_builddir $(objtree)" --target \
 		$(UTS_MACHINE) -bb $(objtree)/binkernel.spec
 	rm binkernel.spec
 
--- zfcpdump-kernel-4.4.orig/scripts/package/mkspec
+++ zfcpdump-kernel-4.4/scripts/package/mkspec
@@ -131,11 +131,11 @@ echo 'rm -rf $RPM_BUILD_ROOT'
 echo ""
 echo "%post"
 echo "if [ -x /sbin/installkernel -a -r /boot/vmlinuz-$KERNELRELEASE -a -r /boot/System.map-$KERNELRELEASE ]; then"
-echo "cp /boot/vmlinuz-$KERNELRELEASE /boot/vmlinuz-$KERNELRELEASE-rpm"
-echo "cp /boot/System.map-$KERNELRELEASE /boot/System.map-$KERNELRELEASE-rpm"
+echo "cp /boot/vmlinuz-$KERNELRELEASE /boot/.vmlinuz-$KERNELRELEASE-rpm"
+echo "cp /boot/System.map-$KERNELRELEASE /boot/.System.map-$KERNELRELEASE-rpm"
 echo "rm -f /boot/vmlinuz-$KERNELRELEASE /boot/System.map-$KERNELRELEASE"
-echo "/sbin/installkernel $KERNELRELEASE /boot/vmlinuz-$KERNELRELEASE-rpm /boot/System.map-$KERNELRELEASE-rpm"
-echo "rm -f /boot/vmlinuz-$KERNELRELEASE-rpm /boot/System.map-$KERNELRELEASE-rpm"
+echo "/sbin/installkernel $KERNELRELEASE /boot/.vmlinuz-$KERNELRELEASE-rpm /boot/.System.map-$KERNELRELEASE-rpm"
+echo "rm -f /boot/.vmlinuz-$KERNELRELEASE-rpm /boot/.System.map-$KERNELRELEASE-rpm"
 echo "fi"
 echo ""
 echo "%files"
--- zfcpdump-kernel-4.4.orig/scripts/recordmcount.c
+++ zfcpdump-kernel-4.4/scripts/recordmcount.c
@@ -33,10 +33,17 @@
 #include <string.h>
 #include <unistd.h>
 
+/*
+ * glibc synced up and added the metag number but didn't add the relocations.
+ * Work around this in a crude manner for now.
+ */
 #ifndef EM_METAG
-/* Remove this when these make it to the standard system elf.h. */
 #define EM_METAG      174
+#endif
+#ifndef R_METAG_ADDR32
 #define R_METAG_ADDR32                   2
+#endif
+#ifndef R_METAG_NONE
 #define R_METAG_NONE                     3
 #endif
 
--- zfcpdump-kernel-4.4.orig/scripts/recordmcount.pl
+++ zfcpdump-kernel-4.4/scripts/recordmcount.pl
@@ -263,7 +263,8 @@ if ($arch eq "x86_64") {
 
 } elsif ($arch eq "powerpc") {
     $local_regex = "^[0-9a-fA-F]+\\s+t\\s+(\\.?\\S+)";
-    $function_regex = "^([0-9a-fA-F]+)\\s+<(\\.?.*?)>:";
+    # See comment in the sparc64 section for why we use '\w'.
+    $function_regex = "^([0-9a-fA-F]+)\\s+<(\\.?\\w*?)>:";
     $mcount_regex = "^\\s*([0-9a-fA-F]+):.*\\s\\.?_mcount\$";
 
     if ($bits == 64) {
--- zfcpdump-kernel-4.4.orig/security/apparmor/Kconfig
+++ zfcpdump-kernel-4.4/security/apparmor/Kconfig
@@ -30,14 +30,62 @@ config SECURITY_APPARMOR_BOOTPARAM_VALUE
 
 	  If you are unsure how to answer this question, answer 1.
 
+config SECURITY_APPARMOR_STATS
+	bool "enable debug statistics"
+	depends on SECURITY_APPARMOR
+	select APPARMOR_LABEL_STATS
+	default n
+	help
+	  This enables keeping statistics on various internal structures
+	  and functions in apparmor.
+
+	  If you are unsure how to answer this question, answer N.
+
+config SECURITY_APPARMOR_UNCONFINED_INIT
+	bool "Set init to unconfined on boot"
+	depends on SECURITY_APPARMOR
+	default y
+	help
+	  This option determines policy behavior during early boot by
+	  placing the init process in the unconfined state, or the
+	  'default' profile.
+
+	  This option determines policy behavior during early boot by
+	  placing the init process in the unconfined state, or the
+	  'default' profile.
+
+	  'Y' means init and its children are not confined, unless the
+	  init process is re-execed after a policy load; loaded policy
+	  will only apply to processes started after the load.
+
+	  'N' means init and its children are confined in a profile
+	  named 'default', which can be replaced later and thus
+	  provide for confinement for processes started early at boot,
+	  though not confined during early boot.
+
+	  If you are unsure how to answer this question, answer Y.
+
 config SECURITY_APPARMOR_HASH
-	bool "SHA1 hash of loaded profiles"
+	bool "Enable introspection of sha1 hashes for loaded profiles"
 	depends on SECURITY_APPARMOR
 	select CRYPTO
 	select CRYPTO_SHA1
 	default y
 
 	help
-	  This option selects whether sha1 hashing is done against loaded
-          profiles and exported for inspection to user space via the apparmor
-          filesystem.
+	  This option selects whether introspection of loaded policy
+	  is available to userspace via the apparmor filesystem.
+
+config SECURITY_APPARMOR_HASH_DEFAULT
+	bool "Enable policy hash introspection by default"
+	depends on SECURITY_APPARMOR_HASH
+	default y
+
+	help
+	  This option selects whether sha1 hashing of loaded policy
+	  is enabled by default. The generation of sha1 hashes for
+	  loaded policy provide system administrators a quick way
+	  to verify that policy in the kernel matches what is expected,
+	  however it can slow down policy load on some devices. In
+	  these cases policy hashing can be disabled by default and
+	  enabled only if needed.
--- zfcpdump-kernel-4.4.orig/security/apparmor/Makefile
+++ zfcpdump-kernel-4.4/security/apparmor/Makefile
@@ -4,11 +4,45 @@ obj-$(CONFIG_SECURITY_APPARMOR) += appar
 
 apparmor-y := apparmorfs.o audit.o capability.o context.o ipc.o lib.o match.o \
               path.o domain.o policy.o policy_unpack.o procattr.o lsm.o \
-              resource.o sid.o file.o
+              resource.o sid.o file.o label.o mount.o net.o af_unix.o \
+              policy_ns.o backport.o
 apparmor-$(CONFIG_SECURITY_APPARMOR_HASH) += crypto.o
 
-clean-files := capability_names.h rlim_names.h
+clean-files := capability_names.h rlim_names.h net_names.h
 
+# Build a lower case string table of address family names
+# Transform lines from
+#    define AF_LOCAL	1	/* POSIX name for AF_UNIX	*/
+#    #define AF_INET		2	/* Internet IP Protocol 	*/
+# to
+#    [1] = "local",
+#    [2] = "inet",
+#
+# and build the securityfs entries for the mapping.
+# Transforms lines from
+#    #define AF_INET		2	/* Internet IP Protocol 	*/
+# to
+#    #define AA_FS_AF_MASK "local inet"
+quiet_cmd_make-af = GEN     $@
+cmd_make-af = echo "static const char *address_family_names[] = {" > $@ ;\
+	sed $< >>$@ -r -n -e "/AF_MAX/d" -e "/AF_LOCAL/d" -e "/AF_ROUTE/d" -e \
+	 's/^\#define[ \t]+AF_([A-Z0-9_]+)[ \t]+([0-9]+)(.*)/[\2] = "\L\1",/p';\
+	echo "};" >> $@ ;\
+	echo -n '\#define AA_FS_AF_MASK "' >> $@ ;\
+	sed -r -n -e "/AF_MAX/d" -e "/AF_LOCAL/d" -e "/AF_ROUTE/d" -e \
+	 's/^\#define[ \t]+AF_([A-Z0-9_]+)[ \t]+([0-9]+)(.*)/\L\1/p'\
+	 $< | tr '\n' ' ' | sed -e 's/ $$/"\n/' >> $@
+
+# Build a lower case string table of sock type names
+# Transform lines from
+#    SOCK_STREAM	= 1,
+# to
+#    [1] = "stream",
+quiet_cmd_make-sock = GEN     $@
+cmd_make-sock = echo "static const char *sock_type_names[] = {" >> $@ ;\
+	sed $^ >>$@ -r -n \
+	-e 's/^\tSOCK_([A-Z0-9_]+)[\t]+=[ \t]+([0-9]+)(.*)/[\2] = "\L\1",/p';\
+	echo "};" >> $@
 
 # Build a lower case string table of capability names
 # Transforms lines from
@@ -61,6 +95,7 @@ cmd_make-rlim = echo "static const char
 	    tr '\n' ' ' | sed -e 's/ $$/"\n/' >> $@
 
 $(obj)/capability.o : $(obj)/capability_names.h
+$(obj)/net.o : $(obj)/net_names.h
 $(obj)/resource.o : $(obj)/rlim_names.h
 $(obj)/capability_names.h : $(srctree)/include/uapi/linux/capability.h \
 			    $(src)/Makefile
@@ -68,3 +103,8 @@ $(obj)/capability_names.h : $(srctree)/i
 $(obj)/rlim_names.h : $(srctree)/include/uapi/asm-generic/resource.h \
 		      $(src)/Makefile
 	$(call cmd,make-rlim)
+$(obj)/net_names.h : $(srctree)/include/linux/socket.h \
+		     $(srctree)/include/linux/net.h \
+		     $(src)/Makefile
+	$(call cmd,make-af)
+	$(call cmd,make-sock)
--- /dev/null
+++ zfcpdump-kernel-4.4/security/apparmor/af_unix.c
@@ -0,0 +1,643 @@
+/*
+ * AppArmor security module
+ *
+ * This file contains AppArmor af_unix fine grained mediation
+ *
+ * Copyright 2014 Canonical Ltd.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2 of the
+ * License.
+ */
+
+#include <net/tcp_states.h>
+
+#include "include/af_unix.h"
+#include "include/apparmor.h"
+#include "include/context.h"
+#include "include/file.h"
+#include "include/label.h"
+#include "include/path.h"
+#include "include/policy.h"
+
+static inline struct sock *aa_sock(struct unix_sock *u)
+{
+	return &u->sk;
+}
+
+static inline int unix_fs_perm(const char *op, u32 mask, struct aa_label *label,
+			       struct unix_sock *u, int flags)
+{
+	AA_BUG(!label);
+	AA_BUG(!u);
+	AA_BUG(!UNIX_FS(aa_sock(u)));
+
+	if (unconfined(label) || !LABEL_MEDIATES(label, AA_CLASS_FILE))
+		return 0;
+
+	mask &= NET_FS_PERMS;
+	if (!u->path.dentry) {
+		struct path_cond cond = { };
+		struct aa_perms perms = { };
+		struct aa_profile *profile;
+
+		/* socket path has been cleared because it is being shutdown
+		 * can only fall back to original sun_path request
+		 */
+		struct aa_sk_ctx *ctx = SK_CTX(&u->sk);
+		if (ctx->path.dentry)
+			return aa_path_perm(op, label, &ctx->path, flags, mask,
+					    &cond);
+		return fn_for_each_confined(label, profile,
+			((flags | profile->path_flags) & PATH_MEDIATE_DELETED) ?
+				__aa_path_perm(op, profile,
+					       u->addr->name->sun_path, mask,
+					       &cond, flags, &perms) :
+				aa_audit_file(profile, &nullperms, op, mask,
+					      u->addr->name->sun_path, NULL,
+					      NULL, cond.uid,
+					      "Failed name lookup - "
+					      "deleted entry", -EACCES));
+	} else {
+		/* the sunpath may not be valid for this ns so use the path */
+		struct path_cond cond = { u->path.dentry->d_inode->i_uid,
+					  u->path.dentry->d_inode->i_mode
+		};
+
+		return aa_path_perm(op, label, &u->path, flags, mask, &cond);
+	}
+
+	return 0;
+}
+
+/* passing in state returned by PROFILE_MEDIATES_AF */
+static unsigned int match_to_prot(struct aa_profile *profile,
+				  unsigned int state, int type, int protocol,
+				  const char **info)
+{
+	u16 buffer[2];
+	buffer[0] = cpu_to_be16(type);
+	buffer[1] = cpu_to_be16(protocol);
+	state = aa_dfa_match_len(profile->policy.dfa, state, (char *) &buffer,
+				 4);
+	if (!state)
+		*info = "failed type and protocol match";
+	return state;
+}
+
+static unsigned int match_addr(struct aa_profile *profile, unsigned int state,
+			       struct sockaddr_un *addr, int addrlen)
+{
+	if (addr)
+		/* include leading \0 */
+		state = aa_dfa_match_len(profile->policy.dfa, state,
+					 addr->sun_path,
+					 unix_addr_len(addrlen));
+	else
+		/* anonymous end point */
+		state = aa_dfa_match_len(profile->policy.dfa, state, "\x01",
+					 1);
+	/* todo change to out of band */
+	state = aa_dfa_null_transition(profile->policy.dfa, state);
+	return state;
+}
+
+static unsigned int match_to_local(struct aa_profile *profile,
+				   unsigned int state, int type, int protocol,
+				   struct sockaddr_un *addr, int addrlen,
+				   const char **info)
+{
+	state = match_to_prot(profile, state, type, protocol, info);
+	if (state) {
+		state = match_addr(profile, state, addr, addrlen);
+		if (state) {
+			/* todo: local label matching */
+			state = aa_dfa_null_transition(profile->policy.dfa,
+						       state);
+			if (!state)
+				*info = "failed local label match";
+		} else
+			*info = "failed local address match";
+	}
+
+	return state;
+}
+
+static unsigned int match_to_sk(struct aa_profile *profile,
+				unsigned int state, struct unix_sock *u,
+				const char **info)
+{
+	struct sockaddr_un *addr = NULL;
+	int addrlen = 0;
+
+	if (u->addr) {
+		addr = u->addr->name;
+		addrlen = u->addr->len;
+	}
+
+	return match_to_local(profile, state, u->sk.sk_type, u->sk.sk_protocol,
+			      addr, addrlen, info);
+}
+
+#define CMD_ADDR	1
+#define CMD_LISTEN	2
+#define CMD_OPT		4
+
+static inline unsigned int match_to_cmd(struct aa_profile *profile,
+					unsigned int state, struct unix_sock *u,
+					char cmd, const char **info)
+{
+	state = match_to_sk(profile, state, u, info);
+	if (state) {
+		state = aa_dfa_match_len(profile->policy.dfa, state, &cmd, 1);
+		if (!state)
+			*info = "failed cmd selection match";
+	}
+
+	return state;
+}
+
+static inline unsigned int match_to_peer(struct aa_profile *profile,
+					 unsigned int state,
+					 struct unix_sock *u,
+					 struct sockaddr_un *peer_addr,
+					 int peer_addrlen,
+					 const char **info)
+{
+	state = match_to_cmd(profile, state, u, CMD_ADDR, info);
+	if (state) {
+		state = match_addr(profile, state, peer_addr, peer_addrlen);
+		if (!state)
+			*info = "failed peer address match";
+	}
+	return state;
+}
+
+static int do_perms(struct aa_profile *profile, unsigned int state, u32 request,
+		    struct common_audit_data *sa)
+{
+	struct aa_perms perms;
+
+	AA_BUG(!profile);
+
+	aa_compute_perms(profile->policy.dfa, state, &perms);
+	aa_apply_modes_to_perms(profile, &perms);
+	return aa_check_perms(profile, &perms, request, sa,
+			      audit_net_cb);
+}
+
+static int match_label(struct aa_profile *profile, struct aa_profile *peer,
+			      unsigned int state, u32 request,
+			      struct common_audit_data *sa)
+{
+	AA_BUG(!profile);
+	AA_BUG(!peer);
+
+	aad(sa)->peer = &peer->label;
+
+	if (state) {
+		state = aa_dfa_match(profile->policy.dfa, state, aa_peer_name(peer));
+		if (!state)
+			aad(sa)->info = "failed peer label match";
+	}
+	return do_perms(profile, state, request, sa);
+}
+
+
+/* unix sock creation comes before we know if the socket will be an fs
+ * socket
+ * v6 - semantics are handled by mapping in profile load
+ * v7 - semantics require sock create for tasks creating an fs socket.
+ */
+static int profile_create_perm(struct aa_profile *profile, int family,
+			       int type, int protocol)
+{
+	unsigned int state;
+	DEFINE_AUDIT_NET(sa, OP_CREATE, NULL, family, type, protocol);
+
+	AA_BUG(!profile);
+	AA_BUG(profile_unconfined(profile));
+
+	if ((state = PROFILE_MEDIATES_AF(profile, AF_UNIX))) {
+		state = match_to_prot(profile, state, type, protocol,
+				      &aad(&sa)->info);
+		return do_perms(profile, state, AA_MAY_CREATE, &sa);
+	}
+
+	return aa_profile_af_perm(profile, &sa, AA_MAY_CREATE, family, type);
+}
+
+int aa_unix_create_perm(struct aa_label *label, int family, int type,
+			int protocol)
+{
+	struct aa_profile *profile;
+
+	if (unconfined(label))
+		return 0;
+
+	return fn_for_each_confined(label, profile,
+			profile_create_perm(profile, family, type, protocol));
+}
+
+
+static inline int profile_sk_perm(struct aa_profile *profile, const char *op,
+				  u32 request, struct sock *sk)
+{
+	unsigned int state;
+	DEFINE_AUDIT_SK(sa, op, sk);
+
+	AA_BUG(!profile);
+	AA_BUG(!sk);
+	AA_BUG(UNIX_FS(sk));
+	AA_BUG(profile_unconfined(profile));
+
+	state = PROFILE_MEDIATES_AF(profile, AF_UNIX);
+	if (state) {
+		state = match_to_sk(profile, state, unix_sk(sk),
+				    &aad(&sa)->info);
+		return do_perms(profile, state, request, &sa);
+	}
+
+	return aa_profile_af_sk_perm(profile, &sa, request, sk);
+}
+
+int aa_unix_label_sk_perm(struct aa_label *label, const char *op, u32 request,
+			  struct sock *sk)
+{
+	struct aa_profile *profile;
+
+	return fn_for_each_confined(label, profile,
+			profile_sk_perm(profile, op, request, sk));
+}
+
+static int unix_label_sock_perm(struct aa_label *label, const char *op, u32 request,
+				struct socket *sock)
+{
+	if (unconfined(label))
+		return 0;
+	if (UNIX_FS(sock->sk))
+		return unix_fs_perm(op, request, label, unix_sk(sock->sk), 0);
+
+	return aa_unix_label_sk_perm(label, op, request, sock->sk);
+}
+
+/* revaliation, get/set attr */
+int aa_unix_sock_perm(const char *op, u32 request, struct socket *sock)
+{
+	struct aa_label *label = aa_begin_current_label(DO_UPDATE);
+	int error = unix_label_sock_perm(label, op, request, sock);
+	aa_end_current_label(label);
+
+	return error;
+}
+
+static int profile_bind_perm(struct aa_profile *profile, struct sock *sk,
+			     struct sockaddr *addr, int addrlen)
+{
+	unsigned int state;
+	DEFINE_AUDIT_SK(sa, OP_BIND, sk);
+
+	AA_BUG(!profile);
+	AA_BUG(!sk);
+	AA_BUG(addr->sa_family != AF_UNIX);
+	AA_BUG(profile_unconfined(profile));
+	AA_BUG(unix_addr_fs(addr, addrlen));
+
+	state = PROFILE_MEDIATES_AF(profile, AF_UNIX);
+	if (state) {
+		/* bind for abstract socket */
+		aad(&sa)->net.addr = unix_addr(addr);
+		aad(&sa)->net.addrlen = addrlen;
+
+		state = match_to_local(profile, state,
+				       sk->sk_type, sk->sk_protocol,
+				       unix_addr(addr), addrlen,
+				       &aad(&sa)->info);
+		return do_perms(profile, state, AA_MAY_BIND, &sa);
+	}
+
+	return aa_profile_af_sk_perm(profile, &sa, AA_MAY_BIND, sk);
+}
+
+int aa_unix_bind_perm(struct socket *sock, struct sockaddr *address,
+		      int addrlen)
+{
+	struct aa_profile *profile;
+	struct aa_label *label = aa_begin_current_label(DO_UPDATE);
+	int error = 0;
+
+	 /* fs bind is handled by mknod */
+	if (!(unconfined(label) || unix_addr_fs(address, addrlen)))
+		error = fn_for_each_confined(label, profile,
+				profile_bind_perm(profile, sock->sk, address,
+						  addrlen));
+	aa_end_current_label(label);
+
+	return error;
+}
+
+int aa_unix_connect_perm(struct socket *sock, struct sockaddr *address,
+			 int addrlen)
+{
+	/* unix connections are covered by the
+	 * - unix_stream_connect (stream) and unix_may_send hooks (dgram)
+	 * - fs connect is handled by open
+	 */
+	return 0;
+}
+
+static int profile_listen_perm(struct aa_profile *profile, struct sock *sk,
+			       int backlog)
+{
+	unsigned int state;
+	DEFINE_AUDIT_SK(sa, OP_LISTEN, sk);
+
+	AA_BUG(!profile);
+	AA_BUG(!sk);
+	AA_BUG(UNIX_FS(sk));
+	AA_BUG(profile_unconfined(profile));
+
+	state = PROFILE_MEDIATES_AF(profile, AF_UNIX);
+	if (state) {
+		u16 b = cpu_to_be16(backlog);
+
+		state = match_to_cmd(profile, state, unix_sk(sk), CMD_LISTEN,
+				     &aad(&sa)->info);
+		if (state) {
+			state = aa_dfa_match_len(profile->policy.dfa, state,
+						 (char *) &b, 2);
+			if (!state)
+				aad(&sa)->info = "failed listen backlog match";
+		}
+		return do_perms(profile, state, AA_MAY_LISTEN, &sa);
+	}
+
+	return aa_profile_af_sk_perm(profile, &sa, AA_MAY_LISTEN, sk);
+}
+
+int aa_unix_listen_perm(struct socket *sock, int backlog)
+{
+	struct aa_profile *profile;
+	struct aa_label *label = aa_begin_current_label(DO_UPDATE);
+	int error = 0;
+
+	if (!(unconfined(label) || UNIX_FS(sock->sk)))
+		error = fn_for_each_confined(label, profile,
+				profile_listen_perm(profile, sock->sk,
+						    backlog));
+	aa_end_current_label(label);
+
+	return error;
+}
+
+
+static inline int profile_accept_perm(struct aa_profile *profile,
+				      struct sock *sk,
+				      struct sock *newsk)
+{
+	unsigned int state;
+	DEFINE_AUDIT_SK(sa, OP_ACCEPT, sk);
+
+	AA_BUG(!profile);
+	AA_BUG(!sk);
+	AA_BUG(UNIX_FS(sk));
+	AA_BUG(profile_unconfined(profile));
+
+	state = PROFILE_MEDIATES_AF(profile, AF_UNIX);
+	if (state) {
+		state = match_to_sk(profile, state, unix_sk(sk),
+				    &aad(&sa)->info);
+		return do_perms(profile, state, AA_MAY_ACCEPT, &sa);
+	}
+
+	return aa_profile_af_sk_perm(profile, &sa, AA_MAY_ACCEPT, sk);
+}
+
+/* ability of sock to connect, not peer address binding */
+int aa_unix_accept_perm(struct socket *sock, struct socket *newsock)
+{
+	struct aa_profile *profile;
+	struct aa_label *label = aa_begin_current_label(DO_UPDATE);
+	int error = 0;
+
+	if (!(unconfined(label) || UNIX_FS(sock->sk)))
+		error = fn_for_each_confined(label, profile,
+				profile_accept_perm(profile, sock->sk,
+						    newsock->sk));
+	aa_end_current_label(label);
+
+	return error;
+}
+
+
+/* dgram handled by unix_may_sendmsg, right to send on stream done at connect
+ * could do per msg unix_stream here
+ */
+/* sendmsg, recvmsg */
+int aa_unix_msg_perm(const char *op, u32 request, struct socket *sock,
+		     struct msghdr *msg, int size)
+{
+	return 0;
+}
+
+
+static int profile_opt_perm(struct aa_profile *profile, const char *op, u32 request,
+			    struct sock *sk, int level, int optname)
+{
+	unsigned int state;
+	DEFINE_AUDIT_SK(sa, op, sk);
+
+	AA_BUG(!profile);
+	AA_BUG(!sk);
+	AA_BUG(UNIX_FS(sk));
+	AA_BUG(profile_unconfined(profile));
+
+	state = PROFILE_MEDIATES_AF(profile, AF_UNIX);
+	if (state) {
+		u16 b = cpu_to_be16(optname);
+
+		state = match_to_cmd(profile, state, unix_sk(sk), CMD_OPT,
+				     &aad(&sa)->info);
+		if (state) {
+			state = aa_dfa_match_len(profile->policy.dfa, state,
+						 (char *) &b, 2);
+			if (!state)
+				aad(&sa)->info = "failed sockopt match";
+		}
+		return do_perms(profile, state, request, &sa);
+	}
+
+	return aa_profile_af_sk_perm(profile, &sa, request, sk);
+}
+
+int aa_unix_opt_perm(const char *op, u32 request, struct socket *sock, int level,
+		     int optname)
+{
+	struct aa_profile *profile;
+	struct aa_label *label = aa_begin_current_label(DO_UPDATE);
+	int error = 0;
+
+	if (!(unconfined(label) || UNIX_FS(sock->sk)))
+		error = fn_for_each_confined(label, profile,
+				profile_opt_perm(profile, op, request,
+						 sock->sk, level, optname));
+	aa_end_current_label(label);
+
+	return error;
+}
+
+/* null peer_label is allowed, in which case the peer_sk label is used */
+static int profile_peer_perm(struct aa_profile *profile, const char *op, u32 request,
+			     struct sock *sk, struct sock *peer_sk,
+			     struct aa_label *peer_label,
+			     struct common_audit_data *sa)
+{
+	unsigned int state;
+
+	AA_BUG(!profile);
+	AA_BUG(profile_unconfined(profile));
+	AA_BUG(!sk);
+	AA_BUG(!peer_sk);
+	AA_BUG(UNIX_FS(peer_sk));
+
+	state = PROFILE_MEDIATES_AF(profile, AF_UNIX);
+	if (state) {
+		struct aa_sk_ctx *peer_ctx = SK_CTX(peer_sk);
+		struct aa_profile *peerp;
+		struct sockaddr_un *addr = NULL;
+		int len = 0;
+		if (unix_sk(peer_sk)->addr) {
+			addr = unix_sk(peer_sk)->addr->name;
+			len = unix_sk(peer_sk)->addr->len;
+		}
+		state = match_to_peer(profile, state, unix_sk(sk),
+				      addr, len, &aad(sa)->info);
+		if (!peer_label)
+			peer_label = peer_ctx->label;
+		return fn_for_each(peer_label, peerp,
+				   match_label(profile, peerp, state, request,
+					       sa));
+	}
+
+	return aa_profile_af_sk_perm(profile, sa, request, sk);
+}
+
+/**
+ *
+ * Requires: lock held on both @sk and @peer_sk
+ */
+int aa_unix_peer_perm(struct aa_label *label, const char *op, u32 request,
+		      struct sock *sk, struct sock *peer_sk,
+		      struct aa_label *peer_label)
+{
+	struct unix_sock *peeru = unix_sk(peer_sk);
+	struct unix_sock *u = unix_sk(sk);
+
+	AA_BUG(!label);
+	AA_BUG(!sk);
+	AA_BUG(!peer_sk);
+
+	if (UNIX_FS(aa_sock(peeru)))
+		return unix_fs_perm(op, request, label, peeru, 0);
+	else if (UNIX_FS(aa_sock(u)))
+		return unix_fs_perm(op, request, label, u, 0);
+	else {
+		struct aa_profile *profile;
+		DEFINE_AUDIT_SK(sa, op, sk);
+		aad(&sa)->net.peer_sk = peer_sk;
+
+		/* TODO: ns!!! */
+		if (!net_eq(sock_net(sk), sock_net(peer_sk))) {
+			;
+		}
+
+		if (unconfined(label))
+			return 0;
+
+		return fn_for_each_confined(label, profile,
+				profile_peer_perm(profile, op, request, sk,
+						  peer_sk, peer_label, &sa));
+	}
+}
+
+
+/* from net/unix/af_unix.c */
+static void unix_state_double_lock(struct sock *sk1, struct sock *sk2)
+{
+	if (unlikely(sk1 == sk2) || !sk2) {
+		unix_state_lock(sk1);
+		return;
+	}
+	if (sk1 < sk2) {
+		unix_state_lock(sk1);
+		unix_state_lock_nested(sk2);
+	} else {
+		unix_state_lock(sk2);
+		unix_state_lock_nested(sk1);
+	}
+}
+
+static void unix_state_double_unlock(struct sock *sk1, struct sock *sk2)
+{
+	if (unlikely(sk1 == sk2) || !sk2) {
+		unix_state_unlock(sk1);
+		return;
+	}
+	unix_state_unlock(sk1);
+	unix_state_unlock(sk2);
+}
+
+int aa_unix_file_perm(struct aa_label *label, const char *op, u32 request,
+		      struct socket *sock)
+{
+	struct sock *peer_sk = NULL;
+	u32 sk_req = request & ~NET_PEER_MASK;
+	int error = 0;
+
+	AA_BUG(!label);
+	AA_BUG(!sock);
+	AA_BUG(!sock->sk);
+	AA_BUG(sock->sk->sk_family != AF_UNIX);
+
+	/* TODO: update sock label with new task label */
+	unix_state_lock(sock->sk);
+	peer_sk = unix_peer(sock->sk);
+	if (peer_sk)
+		sock_hold(peer_sk);
+	if (!unix_connected(sock) && sk_req) {
+		error = unix_label_sock_perm(label, op, sk_req, sock);
+		if (!error) {
+			// update label
+		}
+	}
+	unix_state_unlock(sock->sk);
+	if (!peer_sk)
+		return error;
+
+	unix_state_double_lock(sock->sk, peer_sk);
+	if (UNIX_FS(sock->sk)) {
+		error = unix_fs_perm(op, request, label, unix_sk(sock->sk),
+				     PATH_SOCK_COND);
+	} else if (UNIX_FS(peer_sk)) {
+		error = unix_fs_perm(op, request, label, unix_sk(peer_sk),
+				     PATH_SOCK_COND);
+	} else {
+		struct aa_sk_ctx *pctx = SK_CTX(peer_sk);
+		if (sk_req)
+			error = aa_unix_label_sk_perm(label, op, sk_req,
+						      sock->sk);
+		last_error(error,
+			xcheck(aa_unix_peer_perm(label, op,
+						 MAY_READ | MAY_WRITE,
+						 sock->sk, peer_sk, NULL),
+			       aa_unix_peer_perm(pctx->label, op,
+						 MAY_READ | MAY_WRITE,
+						 peer_sk, sock->sk, label)));
+	}
+
+	unix_state_double_unlock(sock->sk, peer_sk);
+	sock_put(peer_sk);
+
+	return error;
+}
--- zfcpdump-kernel-4.4.orig/security/apparmor/apparmorfs.c
+++ zfcpdump-kernel-4.4/security/apparmor/apparmorfs.c
@@ -18,17 +18,26 @@
 #include <linux/module.h>
 #include <linux/seq_file.h>
 #include <linux/uaccess.h>
+#include <linux/mount.h>
 #include <linux/namei.h>
 #include <linux/capability.h>
 #include <linux/rcupdate.h>
+#include <uapi/linux/major.h>
+#include <linux/fs.h>
 
 #include "include/apparmor.h"
 #include "include/apparmorfs.h"
 #include "include/audit.h"
 #include "include/context.h"
 #include "include/crypto.h"
+#include "include/ipc.h"
+#include "include/policy_ns.h"
+#include "include/label.h"
 #include "include/policy.h"
 #include "include/resource.h"
+#include "include/label.h"
+#include "include/lib.h"
+#include "include/policy_unpack.h"
 
 /**
  * aa_mangle_name - mangle a profile name to std profile layout form
@@ -37,7 +46,7 @@
  *
  * Returns: length of mangled name
  */
-static int mangle_name(char *name, char *target)
+static int mangle_name(const char *name, char *target)
 {
 	char *t = target;
 
@@ -71,7 +80,6 @@ static int mangle_name(char *name, char
 
 /**
  * aa_simple_write_to_buffer - common routine for getting policy from user
- * @op: operation doing the user buffer copy
  * @userbuf: user buffer to copy data from  (NOT NULL)
  * @alloc_size: size of user buffer (REQUIRES: @alloc_size >= @copy_size)
  * @copy_size: size of data to copy from user buffer
@@ -80,11 +88,12 @@ static int mangle_name(char *name, char
  * Returns: kernel buffer containing copy of user buffer data or an
  *          ERR_PTR on failure.
  */
-static char *aa_simple_write_to_buffer(int op, const char __user *userbuf,
-				       size_t alloc_size, size_t copy_size,
-				       loff_t *pos)
+static struct aa_loaddata *aa_simple_write_to_buffer(const char __user *userbuf,
+						     size_t alloc_size,
+						     size_t copy_size,
+						     loff_t *pos)
 {
-	char *data;
+	struct aa_loaddata *data;
 
 	BUG_ON(copy_size > alloc_size);
 
@@ -92,19 +101,16 @@ static char *aa_simple_write_to_buffer(i
 		/* only writes from pos 0, that is complete writes */
 		return ERR_PTR(-ESPIPE);
 
-	/*
-	 * Don't allow profile load/replace/remove from profiles that don't
-	 * have CAP_MAC_ADMIN
-	 */
-	if (!aa_may_manage_policy(op))
-		return ERR_PTR(-EACCES);
-
 	/* freed by caller to simple_write_to_buffer */
-	data = kvmalloc(alloc_size);
+	data = kvmalloc(sizeof(*data) + alloc_size);
 	if (data == NULL)
 		return ERR_PTR(-ENOMEM);
+	kref_init(&data->count);
+	data->size = copy_size;
+	data->hash = NULL;
+	data->abi = 0;
 
-	if (copy_from_user(data, userbuf, copy_size)) {
+	if (copy_from_user(data->data, userbuf, copy_size)) {
 		kvfree(data);
 		return ERR_PTR(-EFAULT);
 	}
@@ -112,21 +118,41 @@ static char *aa_simple_write_to_buffer(i
 	return data;
 }
 
-
-/* .load file hook fn to load policy */
-static ssize_t profile_load(struct file *f, const char __user *buf, size_t size,
-			    loff_t *pos)
+static ssize_t policy_update(u32 mask, const char __user *buf, size_t size,
+			     loff_t *pos, struct aa_ns *ns)
 {
-	char *data;
+	struct aa_label *label;
 	ssize_t error;
+	struct aa_loaddata *data;
 
-	data = aa_simple_write_to_buffer(OP_PROF_LOAD, buf, size, size, pos);
+	label = aa_begin_current_label(DO_UPDATE);
 
+	/* high level check about policy management - fine grained in
+	 * below after unpack
+	 */
+	error = aa_may_manage_policy(label, ns, mask);
+	if (error)
+		return error;
+
+	data = aa_simple_write_to_buffer(buf, size, size, pos);
 	error = PTR_ERR(data);
 	if (!IS_ERR(data)) {
-		error = aa_replace_profiles(data, size, PROF_ADD);
-		kvfree(data);
+		error = aa_replace_profiles(ns ? ns : labels_ns(label), label,
+					    mask, data);
+		aa_put_loaddata(data);
 	}
+	aa_end_current_label(label);
+
+	return error;
+}
+
+/* .load file hook fn to load policy */
+static ssize_t profile_load(struct file *f, const char __user *buf, size_t size,
+			    loff_t *pos)
+{
+	struct aa_ns *ns = aa_get_ns(f->f_inode->i_private);
+	int error = policy_update(AA_MAY_LOAD_POLICY, buf, size, pos, ns);
+	aa_put_ns(ns);
 
 	return error;
 }
@@ -140,15 +166,10 @@ static const struct file_operations aa_f
 static ssize_t profile_replace(struct file *f, const char __user *buf,
 			       size_t size, loff_t *pos)
 {
-	char *data;
-	ssize_t error;
-
-	data = aa_simple_write_to_buffer(OP_PROF_REPL, buf, size, size, pos);
-	error = PTR_ERR(data);
-	if (!IS_ERR(data)) {
-		error = aa_replace_profiles(data, size, PROF_REPLACE);
-		kvfree(data);
-	}
+	struct aa_ns *ns = aa_get_ns(f->f_inode->i_private);
+	int error = policy_update(AA_MAY_LOAD_POLICY | AA_MAY_REPLACE_POLICY,
+				  buf, size, pos, ns);
+	aa_put_ns(ns);
 
 	return error;
 }
@@ -162,22 +183,35 @@ static const struct file_operations aa_f
 static ssize_t profile_remove(struct file *f, const char __user *buf,
 			      size_t size, loff_t *pos)
 {
-	char *data;
+	struct aa_loaddata *data;
+	struct aa_label *label;
 	ssize_t error;
+	struct aa_ns *ns = aa_get_ns(f->f_inode->i_private);
+
+	label = aa_begin_current_label(DO_UPDATE);
+	/* high level check about policy management - fine grained in
+	 * below after unpack
+	 */
+	error = aa_may_manage_policy(label, ns, AA_MAY_REMOVE_POLICY);
+	if (error)
+		goto out;
 
 	/*
 	 * aa_remove_profile needs a null terminated string so 1 extra
 	 * byte is allocated and the copied data is null terminated.
 	 */
-	data = aa_simple_write_to_buffer(OP_PROF_RM, buf, size + 1, size, pos);
+	data = aa_simple_write_to_buffer(buf, size + 1, size, pos);
 
 	error = PTR_ERR(data);
 	if (!IS_ERR(data)) {
-		data[size] = 0;
-		error = aa_remove_profiles(data, size);
-		kvfree(data);
-	}
-
+		data->data[size] = 0;
+		error = aa_remove_profiles(ns ? ns : labels_ns(label), label,
+					   data->data, size);
+		aa_put_loaddata(data);
+	}
+ out:
+	aa_end_current_label(label);
+	aa_put_ns(ns);
 	return error;
 }
 
@@ -186,6 +220,282 @@ static const struct file_operations aa_f
 	.llseek = default_llseek,
 };
 
+
+static void profile_query_cb(struct aa_profile *profile, struct aa_perms *perms,
+			     const char *match_str, size_t match_len)
+{
+	struct aa_perms tmp;
+	struct aa_dfa *dfa;
+	unsigned int state = 0;
+
+	if (profile_unconfined(profile))
+		return;
+	if (profile->file.dfa && *match_str == AA_CLASS_FILE) {
+		dfa = profile->file.dfa;
+		state = aa_dfa_match_len(dfa, profile->file.start,
+					 match_str + 1, match_len - 1);
+		tmp = nullperms;
+		if (state) {
+			struct path_cond cond = { };
+			tmp = aa_compute_fperms(dfa, state, &cond);
+		}
+	} else if (profile->policy.dfa) {
+		if (!PROFILE_MEDIATES_SAFE(profile, *match_str))
+			return;	/* no change to current perms */
+		dfa = profile->policy.dfa;
+		state = aa_dfa_match_len(dfa, profile->policy.start[0],
+					 match_str, match_len);
+		if (state)
+			aa_compute_perms(dfa, state, &tmp);
+		else
+			tmp = nullperms;
+	}
+	aa_apply_modes_to_perms(profile, &tmp);
+	aa_perms_accum_raw(perms, &tmp);
+}
+
+/**
+ * query_data - queries a policy and writes its data to buf
+ * @buf: the resulting data is stored here (NOT NULL)
+ * @buf_len: size of buf
+ * @query: query string used to retrieve data
+ * @query_len: size of query including second NUL byte
+ *
+ * The buffers pointed to by buf and query may overlap. The query buffer is
+ * parsed before buf is written to.
+ *
+ * The query should look like "<LABEL>\0<KEY>\0", where <LABEL> is the name of
+ * the security confinement context and <KEY> is the name of the data to
+ * retrieve. <LABEL> and <KEY> must not be NUL-terminated.
+ *
+ * Don't expect the contents of buf to be preserved on failure.
+ *
+ * Returns: number of characters written to buf or -errno on failure
+ */
+static ssize_t query_data(char *buf, size_t buf_len,
+			  char *query, size_t query_len)
+{
+	char *out;
+	const char *key;
+	struct label_it i;
+	struct aa_label *label, *curr;
+	struct aa_profile *profile;
+	struct aa_data *data;
+	u32 bytes;
+	u32 blocks;
+	u32 size;
+
+	if (!query_len)
+		return -EINVAL; /* need a query */
+
+	key = query + strnlen(query, query_len) + 1;
+	if (key + 1 >= query + query_len)
+		return -EINVAL; /* not enough space for a non-empty key */
+	if (key + strnlen(key, query + query_len - key) >= query + query_len)
+		return -EINVAL; /* must end with NUL */
+
+	if (buf_len < sizeof(bytes) + sizeof(blocks))
+		return -EINVAL; /* not enough space */
+
+	curr = aa_begin_current_label(DO_UPDATE);
+	label = aa_label_parse(curr, query, GFP_KERNEL, false, false);
+	aa_end_current_label(curr);
+	if (IS_ERR(label))
+		return PTR_ERR(label);
+
+	/* We are going to leave space for two numbers. The first is the total
+	 * number of bytes we are writing after the first number. This is so
+	 * users can read the full output without reallocation.
+	 *
+	 * The second number is the number of data blocks we're writing. An
+	 * application might be confined by multiple policies having data in
+	 * the same key.
+	 */
+	memset(buf, 0, sizeof(bytes) + sizeof(blocks));
+	out = buf + sizeof(bytes) + sizeof(blocks);
+
+	blocks = 0;
+	label_for_each_confined(i, label, profile) {
+		if (!profile->data)
+			continue;
+
+		data = rhashtable_lookup_fast(profile->data, &key,
+					      profile->data->p);
+
+		if (data) {
+			if (out + sizeof(size) + data->size > buf + buf_len) {
+				aa_put_label(label);
+				return -EINVAL; /* not enough space */
+			}
+			size = __cpu_to_le32(data->size);
+			memcpy(out, &size, sizeof(size));
+			out += sizeof(size);
+			memcpy(out, data->data, data->size);
+			out += data->size;
+			blocks++;
+		}
+	}
+	aa_put_label(label);
+
+	bytes = out - buf - sizeof(bytes);
+	bytes = __cpu_to_le32(bytes);
+	blocks = __cpu_to_le32(blocks);
+	memcpy(buf, &bytes, sizeof(bytes));
+	memcpy(buf + sizeof(bytes), &blocks, sizeof(blocks));
+
+	return out - buf;
+}
+
+/**
+ * query_label - queries a label and writes permissions to buf
+ * @buf: the resulting permissions string is stored here (NOT NULL)
+ * @buf_len: size of buf
+ * @query: binary query string to match against the dfa
+ * @query_len: size of query
+ *
+ * The buffers pointed to by buf and query may overlap. The query buffer is
+ * parsed before buf is written to.
+ *
+ * The query should look like "LABEL_NAME\0DFA_STRING" where LABEL_NAME is
+ * the name of the label, in the current namespace, that is to be queried and
+ * DFA_STRING is a binary string to match against the label(s)'s DFA.
+ *
+ * LABEL_NAME must be NUL terminated. DFA_STRING may contain NUL characters
+ * but must *not* be NUL terminated.
+ *
+ * Returns: number of characters written to buf or -errno on failure
+ */
+static ssize_t query_label(char *buf, size_t buf_len,
+			   char *query, size_t query_len, bool ns_only)
+{
+	struct aa_profile *profile;
+	struct aa_label *label, *curr;
+	char *label_name, *match_str;
+	size_t label_name_len, match_len;
+	struct aa_perms perms;
+	struct label_it i;
+
+	if (!query_len)
+		return -EINVAL;
+
+	label_name = query;
+	label_name_len = strnlen(query, query_len);
+	if (!label_name_len || label_name_len == query_len)
+		return -EINVAL;
+
+	/**
+	 * The extra byte is to account for the null byte between the
+	 * profile name and dfa string. profile_name_len is greater
+	 * than zero and less than query_len, so a byte can be safely
+	 * added or subtracted.
+	 */
+	match_str = label_name + label_name_len + 1;
+	match_len = query_len - label_name_len - 1;
+
+	curr = aa_begin_current_label(DO_UPDATE);
+	label = aa_label_parse(curr, label_name, GFP_KERNEL, false, false);
+	aa_end_current_label(curr);
+	if (IS_ERR(label))
+		return PTR_ERR(label);
+
+	perms = allperms;
+	if (ns_only) {
+		label_for_each_in_ns(i, labels_ns(label), label, profile) {
+			profile_query_cb(profile, &perms, match_str, match_len);
+		}
+	} else {
+		label_for_each(i, label, profile) {
+			profile_query_cb(profile, &perms, match_str, match_len);
+		}
+	}
+	aa_put_label(label);
+
+	return scnprintf(buf, buf_len,
+		      "allow 0x%08x\ndeny 0x%08x\naudit 0x%08x\nquiet 0x%08x\n",
+		      perms.allow, perms.deny, perms.audit, perms.quiet);
+}
+
+#define QUERY_CMD_LABEL		"label\0"
+#define QUERY_CMD_LABEL_LEN	6
+#define QUERY_CMD_PROFILE	"profile\0"
+#define QUERY_CMD_PROFILE_LEN	8
+#define QUERY_CMD_LABELALL	"labelall\0"
+#define QUERY_CMD_LABELALL_LEN	9
+#define QUERY_CMD_DATA		"data\0"
+#define QUERY_CMD_DATA_LEN	5
+
+/**
+ * aa_write_access - generic permissions and data query
+ * @file: pointer to open apparmorfs/access file
+ * @ubuf: user buffer containing the complete query string (NOT NULL)
+ * @count: size of ubuf
+ * @ppos: position in the file (MUST BE ZERO)
+ *
+ * Allows for one permissions or data query per open(), write(), and read()
+ * sequence. The only queries currently supported are label-based queries for
+ * permissions or data.
+ *
+ * For permissions queries, ubuf must begin with "label\0", followed by the
+ * profile query specific format described in the query_label() function
+ * documentation.
+ *
+ * For data queries, ubuf must have the form "data\0<LABEL>\0<KEY>\0", where
+ * <LABEL> is the name of the security confinement context and <KEY> is the
+ * name of the data to retrieve.
+ *
+ * Returns: number of bytes written or -errno on failure
+ */
+static ssize_t aa_write_access(struct file *file, const char __user *ubuf,
+			       size_t count, loff_t *ppos)
+{
+	char *buf;
+	ssize_t len;
+
+	if (*ppos)
+		return -ESPIPE;
+
+	buf = simple_transaction_get(file, ubuf, count);
+	if (IS_ERR(buf))
+		return PTR_ERR(buf);
+
+	if (count > QUERY_CMD_PROFILE_LEN &&
+	    !memcmp(buf, QUERY_CMD_PROFILE, QUERY_CMD_PROFILE_LEN)) {
+		len = query_label(buf, SIMPLE_TRANSACTION_LIMIT,
+				  buf + QUERY_CMD_PROFILE_LEN,
+				  count - QUERY_CMD_PROFILE_LEN, true);
+	} else if (count > QUERY_CMD_LABEL_LEN &&
+		   !memcmp(buf, QUERY_CMD_LABEL, QUERY_CMD_LABEL_LEN)) {
+		len = query_label(buf, SIMPLE_TRANSACTION_LIMIT,
+				  buf + QUERY_CMD_LABEL_LEN,
+				  count - QUERY_CMD_LABEL_LEN, true);
+	} else if (count > QUERY_CMD_LABELALL_LEN &&
+		   !memcmp(buf, QUERY_CMD_LABELALL, QUERY_CMD_LABELALL_LEN)) {
+		len = query_label(buf, SIMPLE_TRANSACTION_LIMIT,
+				  buf + QUERY_CMD_LABELALL_LEN,
+				  count - QUERY_CMD_LABELALL_LEN, false);
+	} else if (count > QUERY_CMD_DATA_LEN &&
+		   !memcmp(buf, QUERY_CMD_DATA, QUERY_CMD_DATA_LEN)) {
+		len = query_data(buf, SIMPLE_TRANSACTION_LIMIT,
+				 buf + QUERY_CMD_DATA_LEN,
+				 count - QUERY_CMD_DATA_LEN);
+	} else
+		len = -EINVAL;
+
+	if (len < 0)
+		return len;
+
+	simple_transaction_set(file, len);
+
+	return count;
+}
+
+static const struct file_operations aa_fs_access = {
+	.write		= aa_write_access,
+	.read		= simple_transaction_read,
+	.release	= simple_transaction_release,
+	.llseek		= generic_file_llseek,
+};
+
 static int aa_fs_seq_show(struct seq_file *seq, void *v)
 {
 	struct aa_fs_entry *fs_file = seq->private;
@@ -227,12 +537,12 @@ const struct file_operations aa_fs_seq_f
 static int aa_fs_seq_profile_open(struct inode *inode, struct file *file,
 				  int (*show)(struct seq_file *, void *))
 {
-	struct aa_replacedby *r = aa_get_replacedby(inode->i_private);
-	int error = single_open(file, show, r);
+	struct aa_proxy *proxy = aa_get_proxy(inode->i_private);
+	int error = single_open(file, show, proxy);
 
 	if (error) {
 		file->private_data = NULL;
-		aa_put_replacedby(r);
+		aa_put_proxy(proxy);
 	}
 
 	return error;
@@ -242,16 +552,17 @@ static int aa_fs_seq_profile_release(str
 {
 	struct seq_file *seq = (struct seq_file *) file->private_data;
 	if (seq)
-		aa_put_replacedby(seq->private);
+		aa_put_proxy(seq->private);
 	return single_release(inode, file);
 }
 
 static int aa_fs_seq_profname_show(struct seq_file *seq, void *v)
 {
-	struct aa_replacedby *r = seq->private;
-	struct aa_profile *profile = aa_get_profile_rcu(&r->profile);
+	struct aa_proxy *proxy = seq->private;
+	struct aa_label *label = aa_get_label_rcu(&proxy->label);
+	struct aa_profile *profile = labels_profile(label);
 	seq_printf(seq, "%s\n", profile->base.name);
-	aa_put_profile(profile);
+	aa_put_label(label);
 
 	return 0;
 }
@@ -271,10 +582,11 @@ static const struct file_operations aa_f
 
 static int aa_fs_seq_profmode_show(struct seq_file *seq, void *v)
 {
-	struct aa_replacedby *r = seq->private;
-	struct aa_profile *profile = aa_get_profile_rcu(&r->profile);
+	struct aa_proxy *proxy = seq->private;
+	struct aa_label *label = aa_get_label_rcu(&proxy->label);
+	struct aa_profile *profile = labels_profile(label);
 	seq_printf(seq, "%s\n", aa_profile_mode_names[profile->mode]);
-	aa_put_profile(profile);
+	aa_put_label(label);
 
 	return 0;
 }
@@ -294,15 +606,16 @@ static const struct file_operations aa_f
 
 static int aa_fs_seq_profattach_show(struct seq_file *seq, void *v)
 {
-	struct aa_replacedby *r = seq->private;
-	struct aa_profile *profile = aa_get_profile_rcu(&r->profile);
+	struct aa_proxy *proxy = seq->private;
+	struct aa_label *label = aa_get_label_rcu(&proxy->label);
+	struct aa_profile *profile = labels_profile(label);
 	if (profile->attach)
 		seq_printf(seq, "%s\n", profile->attach);
 	else if (profile->xmatch)
 		seq_puts(seq, "<unknown>\n");
 	else
 		seq_printf(seq, "%s\n", profile->base.name);
-	aa_put_profile(profile);
+	aa_put_label(label);
 
 	return 0;
 }
@@ -322,8 +635,9 @@ static const struct file_operations aa_f
 
 static int aa_fs_seq_hash_show(struct seq_file *seq, void *v)
 {
-	struct aa_replacedby *r = seq->private;
-	struct aa_profile *profile = aa_get_profile_rcu(&r->profile);
+	struct aa_proxy *proxy = seq->private;
+	struct aa_label *label = aa_get_label_rcu(&proxy->label);
+	struct aa_profile *profile = labels_profile(label);
 	unsigned int i, size = aa_hash_size();
 
 	if (profile->hash) {
@@ -331,6 +645,7 @@ static int aa_fs_seq_hash_show(struct se
 			seq_printf(seq, "%.2x", profile->hash[i]);
 		seq_puts(seq, "\n");
 	}
+	aa_put_label(label);
 
 	return 0;
 }
@@ -348,7 +663,208 @@ static const struct file_operations aa_f
 	.release	= single_release,
 };
 
+static int aa_fs_seq_show_stacked(struct seq_file *seq, void *v)
+{
+	struct aa_label *label = aa_begin_current_label(DO_UPDATE);
+	seq_printf(seq, "%s\n", label->size > 1 ? "yes" : "no");
+	aa_end_current_label(label);
+
+	return 0;
+}
+
+static int aa_fs_seq_open_stacked(struct inode *inode, struct file *file)
+{
+	return single_open(file, aa_fs_seq_show_stacked, inode->i_private);
+}
+
+static const struct file_operations aa_fs_stacked = {
+	.owner		= THIS_MODULE,
+	.open		= aa_fs_seq_open_stacked,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
+static int aa_fs_seq_show_ns_stacked(struct seq_file *seq, void *v)
+{
+	struct aa_label *label = aa_begin_current_label(DO_UPDATE);
+	struct aa_profile *profile;
+	struct label_it it;
+	int count = 1;
+
+	if (label->size > 1) {
+		label_for_each(it, label, profile)
+			if (profile->ns != labels_ns(label)) {
+				count++;
+				break;
+			}
+	}
+
+	seq_printf(seq, "%s\n", count > 1 ? "yes" : "no");
+	aa_end_current_label(label);
+
+	return 0;
+}
+
+static int aa_fs_seq_open_ns_stacked(struct inode *inode, struct file *file)
+{
+	return single_open(file, aa_fs_seq_show_ns_stacked, inode->i_private);
+}
+
+static const struct file_operations aa_fs_ns_stacked = {
+	.owner		= THIS_MODULE,
+	.open		= aa_fs_seq_open_ns_stacked,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
+static int aa_fs_seq_show_ns_level(struct seq_file *seq, void *v)
+{
+	struct aa_label *label = aa_begin_current_label(DO_UPDATE);
+	seq_printf(seq, "%d\n", labels_ns(label)->level);
+	aa_end_current_label(label);
+
+	return 0;
+}
+
+static int aa_fs_seq_open_ns_level(struct inode *inode, struct file *file)
+{
+	return single_open(file, aa_fs_seq_show_ns_level, inode->i_private);
+}
+
+static const struct file_operations aa_fs_ns_level = {
+	.owner		= THIS_MODULE,
+	.open		= aa_fs_seq_open_ns_level,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
+static int aa_fs_seq_show_ns_name(struct seq_file *seq, void *v)
+{
+	struct aa_label *label = aa_begin_current_label(DO_UPDATE);
+	seq_printf(seq, "%s\n", labels_ns(label)->base.name);
+	aa_end_current_label(label);
+
+	return 0;
+}
+
+static int aa_fs_seq_open_ns_name(struct inode *inode, struct file *file)
+{
+	return single_open(file, aa_fs_seq_show_ns_name, inode->i_private);
+}
+
+static const struct file_operations aa_fs_ns_name = {
+	.owner		= THIS_MODULE,
+	.open		= aa_fs_seq_open_ns_name,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
+static int rawdata_release(struct inode *inode, struct file *file)
+{
+	/* TODO: switch to loaddata when profile switched to symlink */
+	aa_put_proxy(file->private_data);
+
+	return 0;
+}
+
+static int aa_fs_seq_raw_abi_show(struct seq_file *seq, void *v)
+{
+	struct aa_proxy *proxy = seq->private;
+	struct aa_label *label = aa_get_label_rcu(&proxy->label);
+	struct aa_profile *profile = labels_profile(label);
+
+	if (profile->rawdata->abi) {
+		seq_printf(seq, "v%d", profile->rawdata->abi);
+		seq_puts(seq, "\n");
+	}
+	aa_put_label(label);
+
+	return 0;
+}
+
+static int aa_fs_seq_raw_abi_open(struct inode *inode, struct file *file)
+{
+	return aa_fs_seq_profile_open(inode, file, aa_fs_seq_raw_abi_show);
+}
+
+static const struct file_operations aa_fs_seq_raw_abi_fops = {
+	.owner		= THIS_MODULE,
+	.open		= aa_fs_seq_raw_abi_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= aa_fs_seq_profile_release,
+};
+
+static int aa_fs_seq_raw_hash_show(struct seq_file *seq, void *v)
+{
+	struct aa_proxy *proxy = seq->private;
+	struct aa_label *label = aa_get_label_rcu(&proxy->label);
+	struct aa_profile *profile = labels_profile(label);
+	unsigned int i, size = aa_hash_size();
+
+	if (profile->rawdata->hash) {
+		for (i = 0; i < size; i++)
+			seq_printf(seq, "%.2x", profile->rawdata->hash[i]);
+		seq_puts(seq, "\n");
+	}
+	aa_put_label(label);
+
+	return 0;
+}
+
+static int aa_fs_seq_raw_hash_open(struct inode *inode, struct file *file)
+{
+	return aa_fs_seq_profile_open(inode, file, aa_fs_seq_raw_hash_show);
+}
+
+static const struct file_operations aa_fs_seq_raw_hash_fops = {
+	.owner		= THIS_MODULE,
+	.open		= aa_fs_seq_raw_hash_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= aa_fs_seq_profile_release,
+};
+
+static ssize_t rawdata_read(struct file *file, char __user *buf, size_t size,
+			    loff_t *ppos)
+{
+	struct aa_proxy *proxy = file->private_data;
+	struct aa_label *label = aa_get_label_rcu(&proxy->label);
+	struct aa_profile *profile = labels_profile(label);
+
+	ssize_t ret = simple_read_from_buffer(buf, size, ppos, profile->rawdata->data, profile->rawdata->size);
+	aa_put_label(label);
+
+	return ret;
+}
+
+static int rawdata_open(struct inode *inode, struct file *file)
+{
+	if (!policy_view_capable(NULL))
+		return -EACCES;
+
+	file->private_data = aa_get_proxy(inode->i_private);
+
+	return 0;
+}
+
+static const struct file_operations aa_fs_rawdata_fops = {
+	.open = rawdata_open,
+	.read = rawdata_read,
+	.llseek = generic_file_llseek,
+	.release = rawdata_release,
+};
+
 /** fns to setup dynamic per profile/namespace files **/
+
+/**
+ *
+ * Requires: @profile->ns->lock held
+ */
 void __aa_fs_profile_rmdir(struct aa_profile *profile)
 {
 	struct aa_profile *child;
@@ -356,29 +872,40 @@ void __aa_fs_profile_rmdir(struct aa_pro
 
 	if (!profile)
 		return;
+	AA_BUG(!mutex_is_locked(&profiles_ns(profile)->lock));
 
 	list_for_each_entry(child, &profile->base.profiles, base.list)
 		__aa_fs_profile_rmdir(child);
 
 	for (i = AAFS_PROF_SIZEOF - 1; i >= 0; --i) {
-		struct aa_replacedby *r;
+		struct aa_proxy *proxy;
 		if (!profile->dents[i])
 			continue;
 
-		r = d_inode(profile->dents[i])->i_private;
+		proxy = d_inode(profile->dents[i])->i_private;
 		securityfs_remove(profile->dents[i]);
-		aa_put_replacedby(r);
+		aa_put_proxy(proxy);
 		profile->dents[i] = NULL;
 	}
 }
 
+/**
+ *
+ * Requires: @old->ns->lock held
+ */
 void __aa_fs_profile_migrate_dents(struct aa_profile *old,
 				   struct aa_profile *new)
 {
 	int i;
 
+	AA_BUG(!old);
+	AA_BUG(!new);
+	AA_BUG(!mutex_is_locked(&profiles_ns(old)->lock));
+
 	for (i = 0; i < AAFS_PROF_SIZEOF; i++) {
 		new->dents[i] = old->dents[i];
+		if (new->dents[i])
+			new->dents[i]->d_inode->i_mtime = CURRENT_TIME;
 		old->dents[i] = NULL;
 	}
 }
@@ -387,23 +914,29 @@ static struct dentry *create_profile_fil
 					  struct aa_profile *profile,
 					  const struct file_operations *fops)
 {
-	struct aa_replacedby *r = aa_get_replacedby(profile->replacedby);
+	struct aa_proxy *proxy = aa_get_proxy(profile->label.proxy);
 	struct dentry *dent;
 
-	dent = securityfs_create_file(name, S_IFREG | 0444, dir, r, fops);
+	dent = securityfs_create_file(name, S_IFREG | 0444, dir, proxy, fops);
 	if (IS_ERR(dent))
-		aa_put_replacedby(r);
+		aa_put_proxy(proxy);
 
 	return dent;
 }
 
-/* requires lock be held */
+/**
+ *
+ * Requires: @profile->ns->lock held
+ */
 int __aa_fs_profile_mkdir(struct aa_profile *profile, struct dentry *parent)
 {
 	struct aa_profile *child;
 	struct dentry *dent = NULL, *dir;
 	int error;
 
+	AA_BUG(!profile);
+	AA_BUG(!mutex_is_locked(&profiles_ns(profile)->lock));
+
 	if (!parent) {
 		struct aa_profile *p;
 		p = aa_deref_parent(profile);
@@ -457,6 +990,29 @@ int __aa_fs_profile_mkdir(struct aa_prof
 		profile->dents[AAFS_PROF_HASH] = dent;
 	}
 
+	if (profile->rawdata) {
+		dent = create_profile_file(dir, "raw_hash", profile,
+					   &aa_fs_seq_raw_hash_fops);
+		if (IS_ERR(dent))
+			goto fail;
+		profile->dents[AAFS_PROF_RAW_HASH] = dent;
+
+		dent = create_profile_file(dir, "raw_abi", profile,
+					   &aa_fs_seq_raw_abi_fops);
+		if (IS_ERR(dent))
+			goto fail;
+		profile->dents[AAFS_PROF_RAW_ABI] = dent;
+
+		dent = securityfs_create_file("raw_data", S_IFREG | 0444, dir,
+					      profile->label.proxy,
+					      &aa_fs_rawdata_fops);
+		if (IS_ERR(dent))
+			goto fail;
+		profile->dents[AAFS_PROF_RAW_DATA] = dent;
+		d_inode(dent)->i_size = profile->rawdata->size;
+		aa_get_proxy(profile->label.proxy);
+	}
+
 	list_for_each_entry(child, &profile->base.profiles, base.list) {
 		error = __aa_fs_profile_mkdir(child, prof_child_dir(profile));
 		if (error)
@@ -474,65 +1030,228 @@ fail2:
 	return error;
 }
 
-void __aa_fs_namespace_rmdir(struct aa_namespace *ns)
+static int ns_mkdir_op(struct inode *dir, struct dentry *dentry, umode_t mode)
 {
-	struct aa_namespace *sub;
+	struct aa_ns *ns, *parent;
+	/* TODO: improve permission check */
+	struct aa_label *label = aa_begin_current_label(DO_UPDATE);
+	int error = aa_may_manage_policy(label, NULL, AA_MAY_LOAD_POLICY);
+	aa_end_current_label(label);
+	if (error)
+		return error;
+
+	parent = aa_get_ns(dir->i_private);
+	AA_BUG(d_inode(ns_subns_dir(parent)) != dir);
+
+	/* we have to unlock and then relock to get locking order right
+	 * for pin_fs
+	 */
+	inode_unlock(dir);
+	securityfs_pin_fs();
+	inode_lock_nested(dir, I_MUTEX_PARENT);
+
+	error = __securityfs_setup_d_inode(dir, dentry, mode | S_IFDIR,  NULL,
+					   NULL, NULL);
+	if (error)
+		return error;
+
+	ns = aa_create_ns(parent, ACCESS_ONCE(dentry->d_name.name), dentry);
+	if (IS_ERR(ns)) {
+		error = PTR_ERR(ns);
+		ns = NULL;
+	}
+
+	aa_put_ns(ns);		/* list ref remains */
+	aa_put_ns(parent);
+
+	return error;
+}
+
+static int ns_rmdir_op(struct inode *dir, struct dentry *dentry)
+{
+	struct aa_ns *ns, *parent;
+	/* TODO: improve permission check */
+	struct aa_label *label = aa_begin_current_label(DO_UPDATE);
+	int error = aa_may_manage_policy(label, NULL, AA_MAY_LOAD_POLICY);
+	aa_end_current_label(label);
+	if (error)
+		return error;
+
+	 parent = aa_get_ns(dir->i_private);
+	/* rmdir calls the generic securityfs functions to remove files
+	 * from the apparmor dir. It is up to the apparmor ns locking
+	 * to avoid races.
+	 */
+	inode_unlock(dir);
+	inode_unlock(dentry->d_inode);
+
+	mutex_lock(&parent->lock);
+	ns = aa_get_ns(__aa_findn_ns(&parent->sub_ns, dentry->d_name.name,
+				     dentry->d_name.len));
+	if (!ns) {
+		error = -ENOENT;
+		goto out;
+	}
+	AA_BUG(ns_dir(ns) != dentry);
+
+	__aa_remove_ns(ns);
+	aa_put_ns(ns);
+
+out:
+	mutex_unlock(&parent->lock);
+	inode_lock_nested(dir, I_MUTEX_PARENT);
+	inode_lock(dentry->d_inode);
+	aa_put_ns(parent);
+
+	return error;
+}
+
+static const struct inode_operations ns_dir_inode_operations = {
+	.lookup		= simple_lookup,
+	.mkdir		= ns_mkdir_op,
+	.rmdir		= ns_rmdir_op,
+};
+
+/**
+ *
+ * Requires: @ns->lock held
+ */
+void __aa_fs_ns_rmdir(struct aa_ns *ns)
+{
+	struct aa_ns *sub;
 	struct aa_profile *child;
 	int i;
 
 	if (!ns)
 		return;
+	AA_BUG(!mutex_is_locked(&ns->lock));
 
 	list_for_each_entry(child, &ns->base.profiles, base.list)
 		__aa_fs_profile_rmdir(child);
 
 	list_for_each_entry(sub, &ns->sub_ns, base.list) {
 		mutex_lock(&sub->lock);
-		__aa_fs_namespace_rmdir(sub);
+		__aa_fs_ns_rmdir(sub);
 		mutex_unlock(&sub->lock);
 	}
 
+	if (ns_subns_dir(ns)) {
+		sub = d_inode(ns_subns_dir(ns))->i_private;
+		aa_put_ns(sub);
+	}
+	if (ns_subload(ns)) {
+		sub = d_inode(ns_subload(ns))->i_private;
+		aa_put_ns(sub);
+	}
+	if (ns_subreplace(ns)) {
+		sub = d_inode(ns_subreplace(ns))->i_private;
+		aa_put_ns(sub);
+	}
+	if (ns_subremove(ns)) {
+		sub = d_inode(ns_subremove(ns))->i_private;
+		aa_put_ns(sub);
+	}
+
 	for (i = AAFS_NS_SIZEOF - 1; i >= 0; --i) {
 		securityfs_remove(ns->dents[i]);
 		ns->dents[i] = NULL;
 	}
 }
 
-int __aa_fs_namespace_mkdir(struct aa_namespace *ns, struct dentry *parent,
-			    const char *name)
+/* assumes cleanup in caller */
+static int __aa_fs_ns_mkdir_entries(struct aa_ns *ns, struct dentry *dir)
 {
-	struct aa_namespace *sub;
-	struct aa_profile *child;
-	struct dentry *dent, *dir;
-	int error;
+	struct dentry *dent;
 
-	if (!name)
-		name = ns->base.name;
-
-	dent = securityfs_create_dir(name, parent);
-	if (IS_ERR(dent))
-		goto fail;
-	ns_dir(ns) = dir = dent;
+	AA_BUG(!ns);
+	AA_BUG(!dir);
 
 	dent = securityfs_create_dir("profiles", dir);
 	if (IS_ERR(dent))
-		goto fail;
+		return PTR_ERR(dent);
 	ns_subprofs_dir(ns) = dent;
 
-	dent = securityfs_create_dir("namespaces", dir);
+	dent = securityfs_create_dir("raw_data", dir);
 	if (IS_ERR(dent))
-		goto fail;
+		return PTR_ERR(dent);
+	ns_subdata_dir(ns) = dent;
+
+	dent = securityfs_create_file(".load", 0666, dir, ns,
+				      &aa_fs_profile_load);
+	if (IS_ERR(dent))
+		return PTR_ERR(dent);
+	aa_get_ns(ns);
+	ns_subload(ns) = dent;
+
+	dent = securityfs_create_file(".replace", 0666, dir, ns,
+				      &aa_fs_profile_replace);
+	if (IS_ERR(dent))
+		return PTR_ERR(dent);
+	aa_get_ns(ns);
+	ns_subreplace(ns) = dent;
+
+	dent = securityfs_create_file(".remove", 0666, dir, ns,
+				      &aa_fs_profile_remove);
+	if (IS_ERR(dent))
+		return PTR_ERR(dent);
+	aa_get_ns(ns);
+	ns_subremove(ns) = dent;
+
+	  /* use create_dentry so we can supply private data */
+	dent = securityfs_create_dentry("namespaces",
+					S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO,
+					dir, ns, NULL,
+					&ns_dir_inode_operations);
+	if (IS_ERR(dent))
+		return PTR_ERR(dent);
+	aa_get_ns(ns);
 	ns_subns_dir(ns) = dent;
 
+	return 0;
+}
+
+/**
+ *
+ * Requires: @ns->lock held
+ */
+int __aa_fs_ns_mkdir(struct aa_ns *ns, struct dentry *parent, const char *name,
+		     struct dentry *dent)
+{
+	struct aa_ns *sub;
+	struct aa_profile *child;
+	struct dentry *dir;
+	int error;
+
+	AA_BUG(!ns);
+	AA_BUG(!parent);
+	AA_BUG(!mutex_is_locked(&ns->lock));
+
+	if (!name)
+		name = ns->base.name;
+
+	if (!dent) {
+		/* create ns dir if it doesn't already exist */
+		dent = securityfs_create_dir(name, parent);
+		if (IS_ERR(dent))
+			goto fail;
+	} else
+		dget(dent);
+	ns_dir(ns) = dir = dent;
+	error = __aa_fs_ns_mkdir_entries(ns, dir);
+	if (error)
+		goto fail2;
+
+	/* profiles */
 	list_for_each_entry(child, &ns->base.profiles, base.list) {
 		error = __aa_fs_profile_mkdir(child, ns_subprofs_dir(ns));
 		if (error)
 			goto fail2;
 	}
 
+	/* subnamespaces */
 	list_for_each_entry(sub, &ns->sub_ns, base.list) {
 		mutex_lock(&sub->lock);
-		error = __aa_fs_namespace_mkdir(sub, ns_subns_dir(ns), NULL);
+		error = __aa_fs_ns_mkdir(sub, ns_subns_dir(ns), NULL, NULL);
 		mutex_unlock(&sub->lock);
 		if (error)
 			goto fail2;
@@ -544,18 +1263,16 @@ fail:
 	error = PTR_ERR(dent);
 
 fail2:
-	__aa_fs_namespace_rmdir(ns);
+	__aa_fs_ns_rmdir(ns);
 
 	return error;
 }
 
 
-#define list_entry_next(pos, member) \
-	list_entry(pos->member.next, typeof(*pos), member)
 #define list_entry_is_head(pos, head, member) (&pos->member == (head))
 
 /**
- * __next_namespace - find the next namespace to list
+ * __next_ns - find the next namespace to list
  * @root: root namespace to stop search at (NOT NULL)
  * @ns: current ns position (NOT NULL)
  *
@@ -566,10 +1283,13 @@ fail2:
  * Requires: ns->parent->lock to be held
  * NOTE: will not unlock root->lock
  */
-static struct aa_namespace *__next_namespace(struct aa_namespace *root,
-					     struct aa_namespace *ns)
+static struct aa_ns *__next_ns(struct aa_ns *root, struct aa_ns *ns)
 {
-	struct aa_namespace *parent, *next;
+	struct aa_ns *parent, *next;
+
+	AA_BUG(!root);
+	AA_BUG(!ns);
+	AA_BUG(ns != root && !mutex_is_locked(&ns->parent->lock));
 
 	/* is next namespace a child */
 	if (!list_empty(&ns->sub_ns)) {
@@ -582,7 +1302,7 @@ static struct aa_namespace *__next_names
 	parent = ns->parent;
 	while (ns != root) {
 		mutex_unlock(&ns->lock);
-		next = list_entry_next(ns, base.list);
+		next = list_next_entry(ns, base.list);
 		if (!list_entry_is_head(next, &parent->sub_ns, base.list)) {
 			mutex_lock(&next->lock);
 			return next;
@@ -597,15 +1317,17 @@ static struct aa_namespace *__next_names
 /**
  * __first_profile - find the first profile in a namespace
  * @root: namespace that is root of profiles being displayed (NOT NULL)
- * @ns: namespace to start in   (NOT NULL)
+ * @ns: namespace to start in   (MAY BE NULL)
  *
  * Returns: unrefcounted profile or NULL if no profile
- * Requires: profile->ns.lock to be held
+ * Requires: ns.lock to be held
  */
-static struct aa_profile *__first_profile(struct aa_namespace *root,
-					  struct aa_namespace *ns)
+static struct aa_profile *__first_profile(struct aa_ns *root, struct aa_ns *ns)
 {
-	for (; ns; ns = __next_namespace(root, ns)) {
+	AA_BUG(!root);
+	AA_BUG(ns && !mutex_is_locked(&ns->lock));
+
+	for (; ns; ns = __next_ns(root, ns)) {
 		if (!list_empty(&ns->base.profiles))
 			return list_first_entry(&ns->base.profiles,
 						struct aa_profile, base.list);
@@ -625,7 +1347,9 @@ static struct aa_profile *__first_profil
 static struct aa_profile *__next_profile(struct aa_profile *p)
 {
 	struct aa_profile *parent;
-	struct aa_namespace *ns = p->ns;
+	struct aa_ns *ns = p->ns;
+
+	AA_BUG(!mutex_is_locked(&profiles_ns(p)->lock));
 
 	/* is next profile a child */
 	if (!list_empty(&p->base.profiles))
@@ -636,7 +1360,7 @@ static struct aa_profile *__next_profile
 	parent = rcu_dereference_protected(p->parent,
 					   mutex_is_locked(&p->ns->lock));
 	while (parent) {
-		p = list_entry_next(p, base.list);
+		p = list_next_entry(p, base.list);
 		if (!list_entry_is_head(p, &parent->base.profiles, base.list))
 			return p;
 		p = parent;
@@ -645,7 +1369,7 @@ static struct aa_profile *__next_profile
 	}
 
 	/* is next another profile in the namespace */
-	p = list_entry_next(p, base.list);
+	p = list_next_entry(p, base.list);
 	if (!list_entry_is_head(p, &ns->base.profiles, base.list))
 		return p;
 
@@ -659,7 +1383,7 @@ static struct aa_profile *__next_profile
  *
  * Returns: next profile or NULL if there isn't one
  */
-static struct aa_profile *next_profile(struct aa_namespace *root,
+static struct aa_profile *next_profile(struct aa_ns *root,
 				       struct aa_profile *profile)
 {
 	struct aa_profile *next = __next_profile(profile);
@@ -667,7 +1391,7 @@ static struct aa_profile *next_profile(s
 		return next;
 
 	/* finished all profiles in namespace move to next namespace */
-	return __first_profile(root, __next_namespace(root, profile->ns));
+	return __first_profile(root, __next_ns(root, profile->ns));
 }
 
 /**
@@ -682,10 +1406,9 @@ static struct aa_profile *next_profile(s
 static void *p_start(struct seq_file *f, loff_t *pos)
 {
 	struct aa_profile *profile = NULL;
-	struct aa_namespace *root = aa_current_profile()->ns;
+	struct aa_ns *root = aa_get_current_ns();
 	loff_t l = *pos;
-	f->private = aa_get_namespace(root);
-
+	f->private = root;
 
 	/* find the first profile */
 	mutex_lock(&root->lock);
@@ -711,7 +1434,7 @@ static void *p_start(struct seq_file *f,
 static void *p_next(struct seq_file *f, void *p, loff_t *pos)
 {
 	struct aa_profile *profile = p;
-	struct aa_namespace *ns = f->private;
+	struct aa_ns *ns = f->private;
 	(*pos)++;
 
 	return next_profile(ns, profile);
@@ -727,14 +1450,14 @@ static void *p_next(struct seq_file *f,
 static void p_stop(struct seq_file *f, void *p)
 {
 	struct aa_profile *profile = p;
-	struct aa_namespace *root = f->private, *ns;
+	struct aa_ns *root = f->private, *ns;
 
 	if (profile) {
 		for (ns = profile->ns; ns && ns != root; ns = ns->parent)
 			mutex_unlock(&ns->lock);
 	}
 	mutex_unlock(&root->lock);
-	aa_put_namespace(root);
+	aa_put_ns(root);
 }
 
 /**
@@ -747,12 +1470,11 @@ static void p_stop(struct seq_file *f, v
 static int seq_show_profile(struct seq_file *f, void *p)
 {
 	struct aa_profile *profile = (struct aa_profile *)p;
-	struct aa_namespace *root = f->private;
+	struct aa_ns *root = f->private;
 
-	if (profile->ns != root)
-		seq_printf(f, ":%s://", aa_ns_name(root, profile->ns));
-	seq_printf(f, "%s (%s)\n", profile->base.hname,
-		   aa_profile_mode_names[profile->mode]);
+	aa_label_seq_xprint(f, root, &profile->label,
+			    FLAG_SHOW_MODE | FLAG_VIEW_SUBNS, GFP_KERNEL);
+	seq_printf(f, "\n");
 
 	return 0;
 }
@@ -766,6 +1488,9 @@ static const struct seq_operations aa_fs
 
 static int profiles_open(struct inode *inode, struct file *file)
 {
+	if (!policy_view_capable(NULL))
+		return -EACCES;
+
 	return seq_open(file, &aa_fs_profiles_op);
 }
 
@@ -789,34 +1514,78 @@ static struct aa_fs_entry aa_fs_entry_fi
 	{ }
 };
 
+static struct aa_fs_entry aa_fs_entry_ptrace[] = {
+	AA_FS_FILE_STRING("mask", "read trace"),
+	{ }
+};
+
+static struct aa_fs_entry aa_fs_entry_signal[] = {
+	AA_FS_FILE_STRING("mask", AA_FS_SIG_MASK),
+	{ }
+};
+
 static struct aa_fs_entry aa_fs_entry_domain[] = {
 	AA_FS_FILE_BOOLEAN("change_hat",	1),
 	AA_FS_FILE_BOOLEAN("change_hatv",	1),
 	AA_FS_FILE_BOOLEAN("change_onexec",	1),
 	AA_FS_FILE_BOOLEAN("change_profile",	1),
+	AA_FS_FILE_BOOLEAN("stack",		1),
+	AA_FS_FILE_STRING("version", "1.2"),
+	{ }
+};
+
+static struct aa_fs_entry aa_fs_entry_versions[] = {
+	AA_FS_FILE_BOOLEAN("v5",	1),
+	AA_FS_FILE_BOOLEAN("v6",	1),
+	AA_FS_FILE_BOOLEAN("v7",	1),
 	{ }
 };
 
 static struct aa_fs_entry aa_fs_entry_policy[] = {
-	AA_FS_FILE_BOOLEAN("set_load",          1),
-	{}
+	AA_FS_DIR("versions",                   aa_fs_entry_versions),
+	AA_FS_FILE_BOOLEAN("set_load",		1),
+	{ }
+};
+
+static struct aa_fs_entry aa_fs_entry_mount[] = {
+	AA_FS_FILE_STRING("mask", "mount umount"),
+	{ }
+};
+
+static struct aa_fs_entry aa_fs_entry_ns[] = {
+	AA_FS_FILE_BOOLEAN("profile",		1),
+	AA_FS_FILE_BOOLEAN("pivot_root",	1),
+	{ }
+};
+
+static struct aa_fs_entry aa_fs_entry_dbus[] = {
+	AA_FS_FILE_STRING("mask", "acquire send receive"),
+	{ }
 };
 
 static struct aa_fs_entry aa_fs_entry_features[] = {
 	AA_FS_DIR("policy",			aa_fs_entry_policy),
 	AA_FS_DIR("domain",			aa_fs_entry_domain),
 	AA_FS_DIR("file",			aa_fs_entry_file),
+	AA_FS_DIR("network",			aa_fs_entry_network),
+	AA_FS_DIR("mount",			aa_fs_entry_mount),
+	AA_FS_DIR("namespaces",			aa_fs_entry_ns),
 	AA_FS_FILE_U64("capability",		VFS_CAP_FLAGS_MASK),
 	AA_FS_DIR("rlimit",			aa_fs_entry_rlimit),
 	AA_FS_DIR("caps",			aa_fs_entry_caps),
+	AA_FS_DIR("ptrace",			aa_fs_entry_ptrace),
+	AA_FS_DIR("signal",			aa_fs_entry_signal),
+	AA_FS_DIR("dbus",			aa_fs_entry_dbus),
 	{ }
 };
 
 static struct aa_fs_entry aa_fs_entry_apparmor[] = {
-	AA_FS_FILE_FOPS(".load", 0640, &aa_fs_profile_load),
-	AA_FS_FILE_FOPS(".replace", 0640, &aa_fs_profile_replace),
-	AA_FS_FILE_FOPS(".remove", 0640, &aa_fs_profile_remove),
-	AA_FS_FILE_FOPS("profiles", 0640, &aa_fs_profiles_fops),
+	AA_FS_FILE_FOPS(".access", 0666, &aa_fs_access),
+	AA_FS_FILE_FOPS(".stacked", 0666, &aa_fs_stacked),
+	AA_FS_FILE_FOPS(".ns_stacked", 0666, &aa_fs_ns_stacked),
+	AA_FS_FILE_FOPS(".ns_level", 0666, &aa_fs_ns_level),
+	AA_FS_FILE_FOPS(".ns_name", 0666, &aa_fs_ns_name),
+	AA_FS_FILE_FOPS("profiles", 0444, &aa_fs_profiles_fops),
 	AA_FS_DIR("features", aa_fs_entry_features),
 	{ }
 };
@@ -925,6 +1694,51 @@ void __init aa_destroy_aafs(void)
 	aafs_remove_dir(&aa_fs_entry);
 }
 
+
+#define NULL_FILE_NAME ".null"
+struct path aa_null;
+
+static int aa_mk_null_file(struct dentry *parent)
+{
+	struct vfsmount *mount = NULL;
+	struct dentry *dentry;
+	struct inode *inode;
+	int count = 0;
+	int error = simple_pin_fs(parent->d_sb->s_type, &mount, &count);
+	if (error)
+		return error;
+
+	inode_lock(d_inode(parent));
+	dentry = lookup_one_len(NULL_FILE_NAME, parent, strlen(NULL_FILE_NAME));
+	if (IS_ERR(dentry)) {
+		error = PTR_ERR(dentry);
+		goto out;
+	}
+	inode = new_inode(parent->d_inode->i_sb);
+	if (!inode) {
+		error = -ENOMEM;
+		goto out1;
+	}
+
+	inode->i_ino = get_next_ino();
+	inode->i_mode = S_IFCHR | S_IRUGO | S_IWUGO;
+	inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
+	init_special_inode(inode, S_IFCHR | S_IRUGO | S_IWUGO,
+			   MKDEV(MEM_MAJOR, 3));
+	d_instantiate(dentry, inode);
+	aa_null.dentry = dget(dentry);
+	aa_null.mnt = mntget(mount);
+
+	error = 0;
+
+out1:
+	dput(dentry);
+out:
+	inode_unlock(d_inode(parent));
+	simple_release_fs(&mount, &count);
+	return error;
+}
+
 /**
  * aa_create_aafs - create the apparmor security filesystem
  *
@@ -934,6 +1748,7 @@ void __init aa_destroy_aafs(void)
  */
 static int __init aa_create_aafs(void)
 {
+	struct dentry *dent;
 	int error;
 
 	if (!apparmor_initialized)
@@ -949,12 +1764,44 @@ static int __init aa_create_aafs(void)
 	if (error)
 		goto error;
 
-	error = __aa_fs_namespace_mkdir(root_ns, aa_fs_entry.dentry,
-					"policy");
+	dent = securityfs_create_file(".load", 0666, aa_fs_entry.dentry,
+				      NULL, &aa_fs_profile_load);
+	if (IS_ERR(dent)) {
+		error = PTR_ERR(dent);
+		goto error;
+	}
+	ns_subload(root_ns) = dent;
+
+	dent = securityfs_create_file(".replace", 0666, aa_fs_entry.dentry,
+				      NULL, &aa_fs_profile_replace);
+	if (IS_ERR(dent)) {
+		error = PTR_ERR(dent);
+		goto error;
+	}
+	ns_subreplace(root_ns) = dent;
+
+	dent = securityfs_create_file(".remove", 0666, aa_fs_entry.dentry,
+				      NULL, &aa_fs_profile_remove);
+	if (IS_ERR(dent)) {
+		error = PTR_ERR(dent);
+		goto error;
+	}
+	ns_subremove(root_ns) = dent;
+
+	mutex_lock(&root_ns->lock);
+	error = __aa_fs_ns_mkdir(root_ns, aa_fs_entry.dentry, "policy", NULL);
+	mutex_unlock(&root_ns->lock);
+
 	if (error)
 		goto error;
 
-	/* TODO: add support for apparmorfs_null and apparmorfs_mnt */
+	error = aa_mk_null_file(aa_fs_entry.dentry);
+	if (error)
+		goto error;
+
+	if (!aa_g_unconfined_init) {
+		/* TODO: add default profile to apparmorfs */
+	}
 
 	/* Report that AppArmor fs is enabled */
 	aa_info_message("AppArmor Filesystem Enabled");
--- zfcpdump-kernel-4.4.orig/security/apparmor/audit.c
+++ zfcpdump-kernel-4.4/security/apparmor/audit.c
@@ -18,60 +18,8 @@
 #include "include/apparmor.h"
 #include "include/audit.h"
 #include "include/policy.h"
+#include "include/policy_ns.h"
 
-const char *const op_table[] = {
-	"null",
-
-	"sysctl",
-	"capable",
-
-	"unlink",
-	"mkdir",
-	"rmdir",
-	"mknod",
-	"truncate",
-	"link",
-	"symlink",
-	"rename_src",
-	"rename_dest",
-	"chmod",
-	"chown",
-	"getattr",
-	"open",
-
-	"file_perm",
-	"file_lock",
-	"file_mmap",
-	"file_mprotect",
-
-	"create",
-	"post_create",
-	"bind",
-	"connect",
-	"listen",
-	"accept",
-	"sendmsg",
-	"recvmsg",
-	"getsockname",
-	"getpeername",
-	"getsockopt",
-	"setsockopt",
-	"socket_shutdown",
-
-	"ptrace",
-
-	"exec",
-	"change_hat",
-	"change_profile",
-	"change_onexec",
-
-	"setprocattr",
-	"setrlimit",
-
-	"profile_replace",
-	"profile_load",
-	"profile_remove"
-};
 
 const char *const audit_mode_names[] = {
 	"normal",
@@ -114,34 +62,42 @@ static void audit_pre(struct audit_buffe
 
 	if (aa_g_audit_header) {
 		audit_log_format(ab, "apparmor=");
-		audit_log_string(ab, aa_audit_type[sa->aad->type]);
+		audit_log_string(ab, aa_audit_type[aad(sa)->type]);
 	}
 
-	if (sa->aad->op) {
+	if (aad(sa)->op) {
 		audit_log_format(ab, " operation=");
-		audit_log_string(ab, op_table[sa->aad->op]);
+		audit_log_string(ab, aad(sa)->op);
 	}
 
-	if (sa->aad->info) {
+	if (aad(sa)->info) {
 		audit_log_format(ab, " info=");
-		audit_log_string(ab, sa->aad->info);
-		if (sa->aad->error)
-			audit_log_format(ab, " error=%d", sa->aad->error);
-	}
-
-	if (sa->aad->profile) {
-		struct aa_profile *profile = sa->aad->profile;
-		if (profile->ns != root_ns) {
-			audit_log_format(ab, " namespace=");
-			audit_log_untrustedstring(ab, profile->ns->base.hname);
+		audit_log_string(ab, aad(sa)->info);
+		if (aad(sa)->error)
+			audit_log_format(ab, " error=%d", aad(sa)->error);
+	}
+
+	if (aad(sa)->label) {
+		struct aa_label *label = aad(sa)->label;
+		if (label_isprofile(label)) {
+			struct aa_profile *profile = labels_profile(label);
+			if (profile->ns != root_ns) {
+				audit_log_format(ab, " namespace=");
+				audit_log_untrustedstring(ab,
+						       profile->ns->base.hname);
+			}
+			audit_log_format(ab, " profile=");
+			audit_log_untrustedstring(ab, profile->base.hname);
+		} else {
+			audit_log_format(ab, " label=");
+			aa_label_xaudit(ab, root_ns, label, FLAG_VIEW_SUBNS,
+					GFP_ATOMIC);
 		}
-		audit_log_format(ab, " profile=");
-		audit_log_untrustedstring(ab, profile->base.hname);
 	}
 
-	if (sa->aad->name) {
+	if (aad(sa)->name) {
 		audit_log_format(ab, " name=");
-		audit_log_untrustedstring(ab, sa->aad->name);
+		audit_log_untrustedstring(ab, aad(sa)->name);
 	}
 }
 
@@ -153,7 +109,12 @@ static void audit_pre(struct audit_buffe
 void aa_audit_msg(int type, struct common_audit_data *sa,
 		  void (*cb) (struct audit_buffer *, void *))
 {
-	sa->aad->type = type;
+	/* TODO: redirect messages for profile to the correct ns
+	 *       rejects from subns should goto the audit associated
+	 *       with it, and audits from parent ns should got ns
+	 *       associated with it
+	 */
+	aad(sa)->type = type;
 	common_lsm_audit(sa, audit_pre, cb);
 }
 
@@ -161,7 +122,6 @@ void aa_audit_msg(int type, struct commo
  * aa_audit - Log a profile based audit event to the audit subsystem
  * @type: audit type for the message
  * @profile: profile to check against (NOT NULL)
- * @gfp: allocation flags to use
  * @sa: audit event (NOT NULL)
  * @cb: optional callback fn for type specific fields (MAYBE NULL)
  *
@@ -169,14 +129,13 @@ void aa_audit_msg(int type, struct commo
  *
  * Returns: error on failure
  */
-int aa_audit(int type, struct aa_profile *profile, gfp_t gfp,
-	     struct common_audit_data *sa,
+int aa_audit(int type, struct aa_profile *profile, struct common_audit_data *sa,
 	     void (*cb) (struct audit_buffer *, void *))
 {
 	BUG_ON(!profile);
 
 	if (type == AUDIT_APPARMOR_AUTO) {
-		if (likely(!sa->aad->error)) {
+		if (likely(!aad(sa)->error)) {
 			if (AUDIT_MODE(profile) != AUDIT_ALL)
 				return 0;
 			type = AUDIT_APPARMOR_AUDIT;
@@ -188,22 +147,22 @@ int aa_audit(int type, struct aa_profile
 	if (AUDIT_MODE(profile) == AUDIT_QUIET ||
 	    (type == AUDIT_APPARMOR_DENIED &&
 	     AUDIT_MODE(profile) == AUDIT_QUIET))
-		return sa->aad->error;
+	  return aad(sa)->error;
 
 	if (KILL_MODE(profile) && type == AUDIT_APPARMOR_DENIED)
 		type = AUDIT_APPARMOR_KILL;
 
-	if (!unconfined(profile))
-		sa->aad->profile = profile;
+	aad(sa)->label = &profile->label;
 
 	aa_audit_msg(type, sa, cb);
 
-	if (sa->aad->type == AUDIT_APPARMOR_KILL)
+	if (aad(sa)->type == AUDIT_APPARMOR_KILL)
 		(void)send_sig_info(SIGKILL, NULL,
-				    sa->u.tsk ?  sa->u.tsk : current);
+			sa->type == LSM_AUDIT_DATA_TASK && sa->u.tsk ?
+				    sa->u.tsk : current);
 
-	if (sa->aad->type == AUDIT_APPARMOR_ALLOWED)
-		return complain_error(sa->aad->error);
+	if (aad(sa)->type == AUDIT_APPARMOR_ALLOWED)
+	  return complain_error(aad(sa)->error);
 
-	return sa->aad->error;
+	return aad(sa)->error;
 }
--- /dev/null
+++ zfcpdump-kernel-4.4/security/apparmor/backport.c
@@ -0,0 +1,19 @@
+/*
+ * AppArmor security module
+ *
+ * This file contains AppArmor file mediation function definitions.
+ *
+ * Copyright 2014 Canonical Ltd.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2 of the
+ * License.
+ *
+ *
+ * This is a file of helper fns backported from newer kernels to support
+ * backporting of apparmor to older kernels. Fns prefixed with code they
+ * are copied of modified from
+ */
+
+#include "include/backport.h"
--- zfcpdump-kernel-4.4.orig/security/apparmor/capability.c
+++ zfcpdump-kernel-4.4/security/apparmor/capability.c
@@ -53,6 +53,7 @@ static void audit_cb(struct audit_buffer
 
 /**
  * audit_caps - audit a capability
+ * @sa: audit data
  * @profile: profile being tested for confinement (NOT NULL)
  * @cap: capability tested
  * @error: error code returned by test
@@ -62,17 +63,12 @@ static void audit_cb(struct audit_buffer
  *
  * Returns: 0 or sa->error on success,  error code on failure
  */
-static int audit_caps(struct aa_profile *profile, int cap, int error)
+static int audit_caps(struct common_audit_data *sa, struct aa_profile *profile,
+		      int cap, int error)
 {
 	struct audit_cache *ent;
 	int type = AUDIT_APPARMOR_AUTO;
-	struct common_audit_data sa;
-	struct apparmor_audit_data aad = {0,};
-	sa.type = LSM_AUDIT_DATA_CAP;
-	sa.aad = &aad;
-	sa.u.cap = cap;
-	sa.aad->op = OP_CAPABLE;
-	sa.aad->error = error;
+	aad(sa)->error = error;
 
 	if (likely(!error)) {
 		/* test if auditing is being forced */
@@ -104,24 +100,44 @@ static int audit_caps(struct aa_profile
 	}
 	put_cpu_var(audit_cache);
 
-	return aa_audit(type, profile, GFP_ATOMIC, &sa, audit_cb);
+	return aa_audit(type, profile, sa, audit_cb);
 }
 
 /**
  * profile_capable - test if profile allows use of capability @cap
  * @profile: profile being enforced    (NOT NULL, NOT unconfined)
  * @cap: capability to test if allowed
+ * @audit: whether an audit record should be generated
+ * @sa: audit data (MAY BE NULL indicating no auditing)
  *
  * Returns: 0 if allowed else -EPERM
  */
-static int profile_capable(struct aa_profile *profile, int cap)
+static int profile_capable(struct aa_profile *profile, int cap, int audit,
+			   struct common_audit_data *sa)
 {
-	return cap_raised(profile->caps.allow, cap) ? 0 : -EPERM;
+       int error;
+
+       if (cap_raised(profile->caps.allow, cap) &&
+           !cap_raised(profile->caps.denied, cap))
+               error = 0;
+       else
+               error = -EPERM;
+
+       if (audit == SECURITY_CAP_NOAUDIT) {
+               if (!COMPLAIN_MODE(profile))
+		       return error;
+	       /* audit the cap request in complain mode but note that it
+		* should be optional.
+		*/
+	       aad(sa)->info = "optional: no audit";
+       }
+
+       return audit_caps(sa, profile, cap, error);
 }
 
 /**
  * aa_capable - test permission to use capability
- * @profile: profile being tested against (NOT NULL)
+ * @label: label being tested for capability (NOT NULL)
  * @cap: capability to be tested
  * @audit: whether an audit record should be generated
  *
@@ -129,15 +145,15 @@ static int profile_capable(struct aa_pro
  *
  * Returns: 0 on success, or else an error code.
  */
-int aa_capable(struct aa_profile *profile, int cap, int audit)
+int aa_capable(struct aa_label *label, int cap, int audit)
 {
-	int error = profile_capable(profile, cap);
+	struct aa_profile *profile;
+	int error = 0;
+	DEFINE_AUDIT_DATA(sa, LSM_AUDIT_DATA_CAP, OP_CAPABLE);
+	sa.u.cap = cap;
 
-	if (!audit) {
-		if (COMPLAIN_MODE(profile))
-			return complain_error(error);
-		return error;
-	}
+	error = fn_for_each_confined(label, profile,
+			profile_capable(profile, cap, audit, &sa));
 
-	return audit_caps(profile, cap, error);
+	return error;
 }
--- zfcpdump-kernel-4.4.orig/security/apparmor/context.c
+++ zfcpdump-kernel-4.4/security/apparmor/context.c
@@ -13,11 +13,11 @@
  * License.
  *
  *
- * AppArmor sets confinement on every task, via the the aa_task_cxt and
- * the aa_task_cxt.profile, both of which are required and are not allowed
- * to be NULL.  The aa_task_cxt is not reference counted and is unique
- * to each cred (which is reference count).  The profile pointed to by
- * the task_cxt is reference counted.
+ * AppArmor sets confinement on every task, via the the aa_task_ctx and
+ * the aa_task_ctx.label, both of which are required and are not allowed
+ * to be NULL.  The aa_task_ctx is not reference counted and is unique
+ * to each cred (which is reference count).  The label pointed to by
+ * the task_ctx is reference counted.
  *
  * TODO
  * If a task uses change_hat it currently does not return to the old
@@ -30,28 +30,28 @@
 #include "include/policy.h"
 
 /**
- * aa_alloc_task_context - allocate a new task_cxt
+ * aa_alloc_task_context - allocate a new task_ctx
  * @flags: gfp flags for allocation
  *
  * Returns: allocated buffer or NULL on failure
  */
-struct aa_task_cxt *aa_alloc_task_context(gfp_t flags)
+struct aa_task_ctx *aa_alloc_task_context(gfp_t flags)
 {
-	return kzalloc(sizeof(struct aa_task_cxt), flags);
+	return kzalloc(sizeof(struct aa_task_ctx), flags);
 }
 
 /**
- * aa_free_task_context - free a task_cxt
- * @cxt: task_cxt to free (MAYBE NULL)
+ * aa_free_task_context - free a task_ctx
+ * @ctx: task_ctx to free (MAYBE NULL)
  */
-void aa_free_task_context(struct aa_task_cxt *cxt)
+void aa_free_task_context(struct aa_task_ctx *ctx)
 {
-	if (cxt) {
-		aa_put_profile(cxt->profile);
-		aa_put_profile(cxt->previous);
-		aa_put_profile(cxt->onexec);
+	if (ctx) {
+		aa_put_label(ctx->label);
+		aa_put_label(ctx->previous);
+		aa_put_label(ctx->onexec);
 
-		kzfree(cxt);
+		kzfree(ctx);
 	}
 }
 
@@ -60,64 +60,63 @@ void aa_free_task_context(struct aa_task
  * @new: a blank task context      (NOT NULL)
  * @old: the task context to copy  (NOT NULL)
  */
-void aa_dup_task_context(struct aa_task_cxt *new, const struct aa_task_cxt *old)
+void aa_dup_task_context(struct aa_task_ctx *new, const struct aa_task_ctx *old)
 {
 	*new = *old;
-	aa_get_profile(new->profile);
-	aa_get_profile(new->previous);
-	aa_get_profile(new->onexec);
+	aa_get_label(new->label);
+	aa_get_label(new->previous);
+	aa_get_label(new->onexec);
 }
 
 /**
- * aa_get_task_profile - Get another task's profile
+ * aa_get_task_label - Get another task's label
  * @task: task to query  (NOT NULL)
  *
- * Returns: counted reference to @task's profile
+ * Returns: counted reference to @task's label
  */
-struct aa_profile *aa_get_task_profile(struct task_struct *task)
+struct aa_label *aa_get_task_label(struct task_struct *task)
 {
-	struct aa_profile *p;
+	struct aa_label *p;
 
 	rcu_read_lock();
-	p = aa_get_profile(__aa_task_profile(task));
+	p = aa_get_newest_label(__aa_task_raw_label(task));
 	rcu_read_unlock();
 
 	return p;
 }
 
 /**
- * aa_replace_current_profile - replace the current tasks profiles
- * @profile: new profile  (NOT NULL)
+ * aa_replace_current_label - replace the current tasks label
+ * @label: new label  (NOT NULL)
  *
  * Returns: 0 or error on failure
  */
-int aa_replace_current_profile(struct aa_profile *profile)
+int aa_replace_current_label(struct aa_label *label)
 {
-	struct aa_task_cxt *cxt = current_cxt();
+	struct aa_task_ctx *ctx = current_ctx();
 	struct cred *new;
-	BUG_ON(!profile);
+	BUG_ON(!label);
 
-	if (cxt->profile == profile)
+	if (ctx->label == label)
 		return 0;
 
+	if (current_cred() != current_real_cred())
+		return -EBUSY;
+
 	new  = prepare_creds();
 	if (!new)
 		return -ENOMEM;
 
-	cxt = cred_cxt(new);
-	if (unconfined(profile) || (cxt->profile->ns != profile->ns))
-		/* if switching to unconfined or a different profile namespace
+	ctx = cred_ctx(new);
+	if (unconfined(label) || (labels_ns(ctx->label) != labels_ns(label)))
+		/* if switching to unconfined or a different label namespace
 		 * clear out context state
 		 */
-		aa_clear_task_cxt_trans(cxt);
+		aa_clear_task_ctx_trans(ctx);
 
-	/* be careful switching cxt->profile, when racing replacement it
-	 * is possible that cxt->profile->replacedby->profile is the reference
-	 * keeping @profile valid, so make sure to get its reference before
-	 * dropping the reference on cxt->profile */
-	aa_get_profile(profile);
-	aa_put_profile(cxt->profile);
-	cxt->profile = profile;
+	aa_get_label(label);
+	aa_put_label(ctx->label);
+	ctx->label = label;
 
 	commit_creds(new);
 	return 0;
@@ -125,21 +124,22 @@ int aa_replace_current_profile(struct aa
 
 /**
  * aa_set_current_onexec - set the tasks change_profile to happen onexec
- * @profile: system profile to set at exec  (MAYBE NULL to clear value)
- *
+ * @label: system label to set at exec  (MAYBE NULL to clear value)
+ * @stack: whether stacking should be done
  * Returns: 0 or error on failure
  */
-int aa_set_current_onexec(struct aa_profile *profile)
+int aa_set_current_onexec(struct aa_label *label, bool stack)
 {
-	struct aa_task_cxt *cxt;
+	struct aa_task_ctx *ctx;
 	struct cred *new = prepare_creds();
 	if (!new)
 		return -ENOMEM;
 
-	cxt = cred_cxt(new);
-	aa_get_profile(profile);
-	aa_put_profile(cxt->onexec);
-	cxt->onexec = profile;
+	ctx = cred_ctx(new);
+	aa_get_label(label);
+	aa_clear_task_ctx_trans(ctx);
+	ctx->onexec = label;
+	ctx->token = stack;
 
 	commit_creds(new);
 	return 0;
@@ -147,7 +147,7 @@ int aa_set_current_onexec(struct aa_prof
 
 /**
  * aa_set_current_hat - set the current tasks hat
- * @profile: profile to set as the current hat  (NOT NULL)
+ * @label: label to set as the current hat  (NOT NULL)
  * @token: token value that must be specified to change from the hat
  *
  * Do switch of tasks hat.  If the task is currently in a hat
@@ -155,67 +155,67 @@ int aa_set_current_onexec(struct aa_prof
  *
  * Returns: 0 or error on failure
  */
-int aa_set_current_hat(struct aa_profile *profile, u64 token)
+int aa_set_current_hat(struct aa_label *label, u64 token)
 {
-	struct aa_task_cxt *cxt;
+	struct aa_task_ctx *ctx;
 	struct cred *new = prepare_creds();
 	if (!new)
 		return -ENOMEM;
-	BUG_ON(!profile);
+	BUG_ON(!label);
 
-	cxt = cred_cxt(new);
-	if (!cxt->previous) {
+	ctx = cred_ctx(new);
+	if (!ctx->previous) {
 		/* transfer refcount */
-		cxt->previous = cxt->profile;
-		cxt->token = token;
-	} else if (cxt->token == token) {
-		aa_put_profile(cxt->profile);
+		ctx->previous = ctx->label;
+		ctx->token = token;
+	} else if (ctx->token == token) {
+		aa_put_label(ctx->label);
 	} else {
-		/* previous_profile && cxt->token != token */
+		/* previous_profile && ctx->token != token */
 		abort_creds(new);
 		return -EACCES;
 	}
-	cxt->profile = aa_get_newest_profile(profile);
+	ctx->label = aa_get_newest_label(label);
 	/* clear exec on switching context */
-	aa_put_profile(cxt->onexec);
-	cxt->onexec = NULL;
+	aa_put_label(ctx->onexec);
+	ctx->onexec = NULL;
 
 	commit_creds(new);
 	return 0;
 }
 
 /**
- * aa_restore_previous_profile - exit from hat context restoring the profile
+ * aa_restore_previous_label - exit from hat context restoring previous label
  * @token: the token that must be matched to exit hat context
  *
- * Attempt to return out of a hat to the previous profile.  The token
+ * Attempt to return out of a hat to the previous label.  The token
  * must match the stored token value.
  *
  * Returns: 0 or error of failure
  */
-int aa_restore_previous_profile(u64 token)
+int aa_restore_previous_label(u64 token)
 {
-	struct aa_task_cxt *cxt;
+	struct aa_task_ctx *ctx;
 	struct cred *new = prepare_creds();
 	if (!new)
 		return -ENOMEM;
 
-	cxt = cred_cxt(new);
-	if (cxt->token != token) {
+	ctx = cred_ctx(new);
+	if (ctx->token != token) {
 		abort_creds(new);
 		return -EACCES;
 	}
-	/* ignore restores when there is no saved profile */
-	if (!cxt->previous) {
+	/* ignore restores when there is no saved label */
+	if (!ctx->previous) {
 		abort_creds(new);
 		return 0;
 	}
 
-	aa_put_profile(cxt->profile);
-	cxt->profile = aa_get_newest_profile(cxt->previous);
-	BUG_ON(!cxt->profile);
+	aa_put_label(ctx->label);
+	ctx->label = aa_get_newest_label(ctx->previous);
+	BUG_ON(!ctx->label);
 	/* clear exec && prev information when restoring to previous context */
-	aa_clear_task_cxt_trans(cxt);
+	aa_clear_task_ctx_trans(ctx);
 
 	commit_creds(new);
 	return 0;
--- zfcpdump-kernel-4.4.orig/security/apparmor/crypto.c
+++ zfcpdump-kernel-4.4/security/apparmor/crypto.c
@@ -29,6 +29,43 @@ unsigned int aa_hash_size(void)
 	return apparmor_hash_size;
 }
 
+char *aa_calc_hash(void *data, size_t len)
+{
+	struct {
+		struct shash_desc shash;
+		char ctx[crypto_shash_descsize(apparmor_tfm)];
+	} desc;
+	char *hash = NULL;
+	int error = -ENOMEM;
+
+	if (!apparmor_tfm)
+		return NULL;
+
+	hash = kzalloc(apparmor_hash_size, GFP_KERNEL);
+	if (!hash)
+		goto fail;
+
+	desc.shash.tfm = apparmor_tfm;
+	desc.shash.flags = 0;
+
+	error = crypto_shash_init(&desc.shash);
+	if (error)
+		goto fail;
+	error = crypto_shash_update(&desc.shash, (u8 *) data, len);
+	if (error)
+		goto fail;
+	error = crypto_shash_final(&desc.shash, hash);
+	if (error)
+		goto fail;
+
+	return hash;
+
+fail:
+	kfree(hash);
+
+	return ERR_PTR(error);
+}
+
 int aa_calc_profile_hash(struct aa_profile *profile, u32 version, void *start,
 			 size_t len)
 {
@@ -39,6 +76,9 @@ int aa_calc_profile_hash(struct aa_profi
 	int error = -ENOMEM;
 	u32 le32_version = cpu_to_le32(version);
 
+	if (!aa_g_hash_policy)
+		return 0;
+
 	if (!apparmor_tfm)
 		return 0;
 
--- zfcpdump-kernel-4.4.orig/security/apparmor/domain.c
+++ zfcpdump-kernel-4.4/security/apparmor/domain.c
@@ -50,76 +50,259 @@ void aa_free_domain_entries(struct aa_do
 
 /**
  * may_change_ptraced_domain - check if can change profile on ptraced task
- * @to_profile: profile to change to  (NOT NULL)
+ * @to_label: profile to change to  (NOT NULL)
+ * @info: message if there is an error
  *
  * Check if current is ptraced and if so if the tracing task is allowed
  * to trace the new domain
  *
  * Returns: %0 or error if change not allowed
  */
-static int may_change_ptraced_domain(struct aa_profile *to_profile)
+static int may_change_ptraced_domain(struct aa_label *to_label,
+				     const char **info)
 {
 	struct task_struct *tracer;
-	struct aa_profile *tracerp = NULL;
+	struct aa_label *tracerl = NULL;
 	int error = 0;
 
 	rcu_read_lock();
 	tracer = ptrace_parent(current);
 	if (tracer)
 		/* released below */
-		tracerp = aa_get_task_profile(tracer);
+		tracerl = aa_get_task_label(tracer);
 
 	/* not ptraced */
-	if (!tracer || unconfined(tracerp))
+	if (!tracer || unconfined(tracerl))
 		goto out;
 
-	error = aa_may_ptrace(tracerp, to_profile, PTRACE_MODE_ATTACH);
+	error = aa_may_ptrace(tracerl, to_label, PTRACE_MODE_ATTACH);
 
 out:
 	rcu_read_unlock();
-	aa_put_profile(tracerp);
+	aa_put_label(tracerl);
 
+	if (error)
+		*info = "ptrace prevents transition";
 	return error;
 }
 
+/**** TODO: dedup to aa_label_match - needs perm and dfa, merging
+ * specifically this is an exact copy of aa_label_match except
+ * aa_compute_perms is replaced with aa_compute_fperms
+ * and policy.dfa with file.dfa
+ ****/
+/* match a profile and its associated ns component if needed
+ * Assumes visibility test has already been done.
+ * If a subns profile is not to be matched should be prescreened with
+ * visibility test.
+ */
+/* match a profile and its associated ns component if needed
+ * Assumes visibility test has already been done.
+ * If a subns profile is not to be matched should be prescreened with
+ * visibility test.
+ */
+static inline unsigned int match_component(struct aa_profile *profile,
+					   struct aa_profile *tp,
+					   bool stack, unsigned int state)
+{
+	const char *ns_name;
+
+	if (stack)
+		state = aa_dfa_match(profile->file.dfa, state, "&");
+	if (profile->ns == tp->ns)
+		return aa_dfa_match(profile->file.dfa, state, tp->base.hname);
+
+	/* try matching with namespace name and then profile */
+	ns_name = aa_ns_name(profile->ns, tp->ns, true);
+	state = aa_dfa_match_len(profile->file.dfa, state, ":", 1);
+	state = aa_dfa_match(profile->file.dfa, state, ns_name);
+	state = aa_dfa_match_len(profile->file.dfa, state, ":", 1);
+	return aa_dfa_match(profile->file.dfa, state, tp->base.hname);
+}
+
+/**
+ * label_component_match - find perms for full compound label
+ * @profile: profile to find perms for
+ * @label: label to check access permissions for
+ * @stack: whether this is a stacking request
+ * @start: state to start match in
+ * @subns: whether to do permission checks on components in a subns
+ * @request: permissions to request
+ * @perms: perms struct to set
+ *
+ * Returns: 0 on success else ERROR
+ *
+ * For the label A//&B//&C this does the perm match for A//&B//&C
+ * @perms should be preinitialized with allperms OR a previous permission
+ *        check to be stacked.
+ */
+static int label_compound_match(struct aa_profile *profile,
+				struct aa_label *label, bool stack,
+				unsigned int state, bool subns, u32 request,
+				struct aa_perms *perms)
+{
+	struct aa_profile *tp;
+	struct label_it i;
+	struct path_cond cond = { };
+
+	/* find first subcomponent that is visible */
+	label_for_each(i, label, tp) {
+		if (!aa_ns_visible(profile->ns, tp->ns, subns))
+			continue;
+		state = match_component(profile, tp, stack, state);
+		if (!state)
+			goto fail;
+		goto next;
+	}
+
+	/* no component visible */
+	*perms = allperms;
+	return 0;
+
+next:
+	label_for_each_cont(i, label, tp) {
+		if (!aa_ns_visible(profile->ns, tp->ns, subns))
+			continue;
+		state = aa_dfa_match(profile->file.dfa, state, "//&");
+		state = match_component(profile, tp, false, state);
+		if (!state)
+			goto fail;
+	}
+	*perms = aa_compute_fperms(profile->file.dfa, state, &cond);
+	aa_apply_modes_to_perms(profile, perms);
+	if ((perms->allow & request) != request)
+		return -EACCES;
+
+	return 0;
+
+fail:
+	*perms = nullperms;
+	return -EACCES;
+}
+
+/**
+ * label_component_match - find perms for all subcomponents of a label
+ * @profile: profile to find perms for
+ * @label: label to check access permissions for
+ * @stack: whether this is a stacking request
+ * @start: state to start match in
+ * @subns: whether to do permission checks on components in a subns
+ * @request: permissions to request
+ * @perms: an initialized perms struct to add accumulation to
+ *
+ * Returns: 0 on success else ERROR
+ *
+ * For the label A//&B//&C this does the perm match for each of A and B and C
+ * @perms should be preinitialized with allperms OR a previous permission
+ *        check to be stacked.
+ */
+static int label_components_match(struct aa_profile *profile,
+				  struct aa_label *label, bool stack,
+				  unsigned int start, bool subns, u32 request,
+				  struct aa_perms *perms)
+{
+	struct aa_profile *tp;
+	struct label_it i;
+	struct aa_perms tmp;
+	struct path_cond cond = { };
+	unsigned int state = 0;
+
+	/* find first subcomponent to test */
+	label_for_each(i, label, tp) {
+		if (!aa_ns_visible(profile->ns, tp->ns, subns))
+			continue;
+		state = match_component(profile, tp, stack, start);
+		if (!state)
+			goto fail;
+		goto next;
+	}
+
+	/* no subcomponents visible - no change in perms */
+	return 0;
+
+next:
+	tmp = aa_compute_fperms(profile->file.dfa, state, &cond);
+	aa_apply_modes_to_perms(profile, &tmp);
+	aa_perms_accum(perms, &tmp);
+	label_for_each_cont(i, label, tp) {
+		if (!aa_ns_visible(profile->ns, tp->ns, subns))
+			continue;
+		state = match_component(profile, tp, stack, start);
+		if (!state)
+			goto fail;
+		tmp = aa_compute_fperms(profile->file.dfa, state, &cond);
+		aa_apply_modes_to_perms(profile, &tmp);
+		aa_perms_accum(perms, &tmp);
+	}
+
+	if ((perms->allow & request) != request)
+		return -EACCES;
+
+	return 0;
+
+fail:
+	*perms = nullperms;
+	return -EACCES;
+}
+
+/**
+ * aa_label_match - do a multi-component label match
+ * @profile: profile to match against (NOT NULL)
+ * @label: label to match (NOT NULL)
+ * @stack: whether this is a stacking request
+ * @state: state to start in
+ * @subns: whether to match subns components
+ * @request: permission request
+ * @perms: Returns computed perms (NOT NULL)
+ *
+ * Returns: the state the match finished in, may be the none matching state
+ */
+static int label_match(struct aa_profile *profile, struct aa_label *label,
+		       bool stack, unsigned int state, bool subns, u32 request,
+		       struct aa_perms *perms)
+{
+	int error;
+
+	*perms = nullperms;
+	error = label_compound_match(profile, label, stack, state, subns,
+				     request, perms);
+	if (!error)
+		return error;
+
+	*perms = allperms;
+	return label_components_match(profile, label, stack, state, subns,
+				      request, perms);
+}
+
+/******* end TODO: dedup *****/
+
 /**
  * change_profile_perms - find permissions for change_profile
  * @profile: the current profile  (NOT NULL)
- * @ns: the namespace being switched to  (NOT NULL)
- * @name: the name of the profile to change to  (NOT NULL)
+ * @target: label to transition to (NOT NULL)
+ * @stack: whether this is a stacking request
  * @request: requested perms
  * @start: state to start matching in
  *
+ *
  * Returns: permission set
+ *
+ * currently only matches full label A//&B//&C or individual components A, B, C
+ * not arbitrary combinations. Eg. A//&B, C
  */
-static struct file_perms change_profile_perms(struct aa_profile *profile,
-					      struct aa_namespace *ns,
-					      const char *name, u32 request,
-					      unsigned int start)
+static int change_profile_perms(struct aa_profile *profile,
+				struct aa_label *target, bool stack,
+				u32 request, unsigned int start,
+				struct aa_perms *perms)
 {
-	struct file_perms perms;
-	struct path_cond cond = { };
-	unsigned int state;
-
-	if (unconfined(profile)) {
-		perms.allow = AA_MAY_CHANGE_PROFILE | AA_MAY_ONEXEC;
-		perms.audit = perms.quiet = perms.kill = 0;
-		return perms;
-	} else if (!profile->file.dfa) {
-		return nullperms;
-	} else if ((ns == profile->ns)) {
-		/* try matching against rules with out namespace prepended */
-		aa_str_perms(profile->file.dfa, start, name, &cond, &perms);
-		if (COMBINED_PERM_MASK(perms) & request)
-			return perms;
+	if (profile_unconfined(profile)) {
+		perms->allow = AA_MAY_CHANGE_PROFILE | AA_MAY_ONEXEC;
+		perms->audit = perms->quiet = perms->kill = 0;
+		return 0;
 	}
 
-	/* try matching with namespace name and then profile */
-	state = aa_dfa_match(profile->file.dfa, start, ns->base.name);
-	state = aa_dfa_match_len(profile->file.dfa, state, ":", 1);
-	aa_str_perms(profile->file.dfa, state, name, &cond, &perms);
-
-	return perms;
+	/* TODO: add profile in ns screening */
+	return label_match(profile, target, stack, start, true, request, perms);
 }
 
 /**
@@ -143,7 +326,7 @@ static struct aa_profile *__attach_match
 	struct aa_profile *profile, *candidate = NULL;
 
 	list_for_each_entry_rcu(profile, head, base.list) {
-		if (profile->flags & PFLAG_NULL)
+		if (profile->label.flags & FLAG_NULL)
 			continue;
 		if (profile->xmatch && profile->xmatch_len > len) {
 			unsigned int state = aa_dfa_match(profile->xmatch,
@@ -168,10 +351,10 @@ static struct aa_profile *__attach_match
  * @list: list to search  (NOT NULL)
  * @name: the executable name to match against  (NOT NULL)
  *
- * Returns: profile or NULL if no match found
+ * Returns: label or NULL if no match found
  */
-static struct aa_profile *find_attach(struct aa_namespace *ns,
-				      struct list_head *list, const char *name)
+static struct aa_label *find_attach(struct aa_ns *ns, struct list_head *list,
+				    const char *name)
 {
 	struct aa_profile *profile;
 
@@ -179,49 +362,7 @@ static struct aa_profile *find_attach(st
 	profile = aa_get_profile(__attach_match(name, list));
 	rcu_read_unlock();
 
-	return profile;
-}
-
-/**
- * separate_fqname - separate the namespace and profile names
- * @fqname: the fqname name to split  (NOT NULL)
- * @ns_name: the namespace name if it exists  (NOT NULL)
- *
- * This is the xtable equivalent routine of aa_split_fqname.  It finds the
- * split in an xtable fqname which contains an embedded \0 instead of a :
- * if a namespace is specified.  This is done so the xtable is constant and
- * isn't re-split on every lookup.
- *
- * Either the profile or namespace name may be optional but if the namespace
- * is specified the profile name termination must be present.  This results
- * in the following possible encodings:
- * profile_name\0
- * :ns_name\0profile_name\0
- * :ns_name\0\0
- *
- * NOTE: the xtable fqname is pre-validated at load time in unpack_trans_table
- *
- * Returns: profile name if it is specified else NULL
- */
-static const char *separate_fqname(const char *fqname, const char **ns_name)
-{
-	const char *name;
-
-	if (fqname[0] == ':') {
-		/* In this case there is guaranteed to be two \0 terminators
-		 * in the string.  They are verified at load time by
-		 * by unpack_trans_table
-		 */
-		*ns_name = fqname + 1;		/* skip : */
-		name = *ns_name + strlen(*ns_name) + 1;
-		if (!*name)
-			name = NULL;
-	} else {
-		*ns_name = NULL;
-		name = fqname;
-	}
-
-	return name;
+	return profile ? &profile->label : NULL;
 }
 
 static const char *next_name(int xtype, const char *name)
@@ -233,239 +374,395 @@ static const char *next_name(int xtype,
  * x_table_lookup - lookup an x transition name via transition table
  * @profile: current profile (NOT NULL)
  * @xindex: index into x transition table
+ * @name: returns: name tested to find label (NOT NULL)
  *
- * Returns: refcounted profile, or NULL on failure (MAYBE NULL)
+ * Returns: refcounted label, or NULL on failure (MAYBE NULL)
  */
-static struct aa_profile *x_table_lookup(struct aa_profile *profile, u32 xindex)
+struct aa_label *x_table_lookup(struct aa_profile *profile, u32 xindex,
+				const char **name)
 {
-	struct aa_profile *new_profile = NULL;
-	struct aa_namespace *ns = profile->ns;
+	struct aa_label *label = NULL;
 	u32 xtype = xindex & AA_X_TYPE_MASK;
 	int index = xindex & AA_X_INDEX_MASK;
-	const char *name;
 
-	/* index is guaranteed to be in range, validated at load time */
-	for (name = profile->file.trans.table[index]; !new_profile && name;
-	     name = next_name(xtype, name)) {
-		struct aa_namespace *new_ns;
-		const char *xname = NULL;
+	AA_BUG(!name);
 
-		new_ns = NULL;
+	/* index is guaranteed to be in range, validated at load time */
+	/* TODO: move lookup parsing to unpack time so this is a straight
+	 *       index into the resultant label
+	 */
+	for (*name = profile->file.trans.table[index]; !label && *name;
+	     *name = next_name(xtype, *name)) {
 		if (xindex & AA_X_CHILD) {
+			struct aa_profile *new_profile;
 			/* release by caller */
-			new_profile = aa_find_child(profile, name);
-			continue;
-		} else if (*name == ':') {
-			/* switching namespace */
-			const char *ns_name;
-			xname = name = separate_fqname(name, &ns_name);
-			if (!xname)
-				/* no name so use profile name */
-				xname = profile->base.hname;
-			if (*ns_name == '@') {
-				/* TODO: variable support */
-				;
-			}
-			/* released below */
-			new_ns = aa_find_namespace(ns, ns_name);
-			if (!new_ns)
-				continue;
-		} else if (*name == '@') {
-			/* TODO: variable support */
+			new_profile = aa_find_child(profile, *name);
+			if (new_profile)
+				label = &new_profile->label;
 			continue;
-		} else {
-			/* basic namespace lookup */
-			xname = name;
 		}
-
-		/* released by caller */
-		new_profile = aa_lookup_profile(new_ns ? new_ns : ns, xname);
-		aa_put_namespace(new_ns);
+		label = aa_label_parse(&profile->label, *name, GFP_ATOMIC,
+				       true, false);
+		if (IS_ERR(label))
+			label = NULL;
 	}
 
 	/* released by caller */
-	return new_profile;
+	return label;
 }
 
 /**
- * x_to_profile - get target profile for a given xindex
+ * x_to_label - get target label for a given xindex
  * @profile: current profile  (NOT NULL)
  * @name: name to lookup (NOT NULL)
  * @xindex: index into x transition table
+ * @lookupname: returns: name used in lookup if one was specified (NOT NULL)
  *
- * find profile for a transition index
+ * find label for a transition index
  *
- * Returns: refcounted profile or NULL if not found available
+ * Returns: refcounted label or NULL if not found available
  */
-static struct aa_profile *x_to_profile(struct aa_profile *profile,
-				       const char *name, u32 xindex)
+static struct aa_label *x_to_label(struct aa_profile *profile,
+				   const char *name, u32 xindex,
+				   const char **lookupname,
+				   const char **info)
 {
-	struct aa_profile *new_profile = NULL;
-	struct aa_namespace *ns = profile->ns;
+	struct aa_label *new = NULL;
+	struct aa_ns *ns = profile->ns;
 	u32 xtype = xindex & AA_X_TYPE_MASK;
+	const char *stack = NULL;
 
 	switch (xtype) {
 	case AA_X_NONE:
 		/* fail exec unless ix || ux fallback - handled by caller */
-		return NULL;
+		*lookupname = NULL;
+		break;
+	case AA_X_TABLE:
+		/* TODO: fix when perm mapping done at unload */
+		stack = profile->file.trans.table[xindex & AA_X_INDEX_MASK];
+		if (*stack != '&') {
+			/* released by caller */
+			new = x_table_lookup(profile, xindex, lookupname);
+			stack = NULL;
+			break;
+		}
+		/* fall through to X_NAME */
 	case AA_X_NAME:
 		if (xindex & AA_X_CHILD)
 			/* released by caller */
-			new_profile = find_attach(ns, &profile->base.profiles,
-						  name);
+			new = find_attach(ns, &profile->base.profiles,
+						name);
 		else
 			/* released by caller */
-			new_profile = find_attach(ns, &ns->base.profiles,
-						  name);
-		break;
-	case AA_X_TABLE:
-		/* released by caller */
-		new_profile = x_table_lookup(profile, xindex);
+			new = find_attach(ns, &ns->base.profiles,
+						name);
+		*lookupname = name;
 		break;
 	}
 
+	if (!new) {
+		if (xindex & AA_X_INHERIT) {
+			/* (p|c|n)ix - don't change profile but do
+			 * use the newest version
+			 */
+			*info = "ix fallback";
+			/* no profile && no error */
+			new = aa_get_newest_label(&profile->label);
+		} else if (xindex & AA_X_UNCONFINED) {
+			new = aa_get_newest_label(ns_unconfined(profile->ns));
+			*info = "ux fallback";
+		}
+	}
+
+	if (new && stack) {
+		/* base the stack on post domain transition */
+		struct aa_label *base = new;
+		new = aa_label_parse(base, stack, GFP_ATOMIC, true, false);
+		if (IS_ERR(new))
+			new = NULL;
+		aa_put_label(base);
+	}
+
 	/* released by caller */
-	return new_profile;
+	return new;
 }
 
-/**
- * apparmor_bprm_set_creds - set the new creds on the bprm struct
- * @bprm: binprm for the exec  (NOT NULL)
- *
- * Returns: %0 or error on failure
- */
-int apparmor_bprm_set_creds(struct linux_binprm *bprm)
+static struct aa_label *profile_transition(struct aa_profile *profile,
+					   const struct linux_binprm *bprm,
+					   char *buffer, struct path_cond *cond,
+					   bool *secure_exec)
 {
-	struct aa_task_cxt *cxt;
-	struct aa_profile *profile, *new_profile = NULL;
-	struct aa_namespace *ns;
-	char *buffer = NULL;
-	unsigned int state;
-	struct file_perms perms = {};
-	struct path_cond cond = {
-		file_inode(bprm->file)->i_uid,
-		file_inode(bprm->file)->i_mode
-	};
-	const char *name = NULL, *target = NULL, *info = NULL;
+	struct aa_label *new = NULL;
+	const char *info = NULL, *name = NULL, *target = NULL;
+	unsigned int state = profile->file.start;
+	struct aa_perms perms = {};
 	int error = 0;
 
-	if (bprm->cred_prepared)
-		return 0;
-
-	cxt = cred_cxt(bprm->cred);
-	BUG_ON(!cxt);
+	AA_BUG(!profile);
+	AA_BUG(!bprm);
+	AA_BUG(!buffer);
 
-	profile = aa_get_newest_profile(cxt->profile);
-	/*
-	 * get the namespace from the replacement profile as replacement
-	 * can change the namespace
-	 */
-	ns = profile->ns;
-	state = profile->file.start;
-
-	/* buffer freed below, name is pointer into buffer */
-	error = aa_path_name(&bprm->file->f_path, profile->path_flags, &buffer,
-			     &name, &info);
+	error = aa_path_name(&bprm->file->f_path, profile->path_flags, buffer,
+			     &name, &info, profile->disconnected);
 	if (error) {
-		if (unconfined(profile) ||
-		    (profile->flags & PFLAG_IX_ON_NAME_ERROR))
+		if (profile_unconfined(profile) ||
+		    (profile->label.flags & FLAG_IX_ON_NAME_ERROR)) {
+			AA_DEBUG("name lookup ix on error");
 			error = 0;
+			new = aa_get_newest_label(&profile->label);
+		}
 		name = bprm->filename;
 		goto audit;
 	}
 
-	/* Test for onexec first as onexec directives override other
-	 * x transitions.
-	 */
-	if (unconfined(profile)) {
-		/* unconfined task */
-		if (cxt->onexec)
-			/* change_profile on exec already been granted */
-			new_profile = aa_get_profile(cxt->onexec);
-		else
-			new_profile = find_attach(ns, &ns->base.profiles, name);
-		if (!new_profile)
-			goto cleanup;
-		/*
-		 * NOTE: Domain transitions from unconfined are allowed
-		 * even when no_new_privs is set because this aways results
-		 * in a further reduction of permissions.
-		 */
-		goto apply;
+	if (profile_unconfined(profile)) {
+		new = find_attach(profile->ns, &profile->ns->base.profiles,
+				  name);
+		if (new) {
+			AA_DEBUG("unconfined attached to new label");
+			return new;
+		}
+		AA_DEBUG("unconfined exec no attachment");
+		return aa_get_newest_label(&profile->label);
 	}
 
 	/* find exec permissions for name */
-	state = aa_str_perms(profile->file.dfa, state, name, &cond, &perms);
-	if (cxt->onexec) {
-		struct file_perms cp;
-		info = "change_profile onexec";
-		if (!(perms.allow & AA_MAY_ONEXEC))
-			goto audit;
-
-		/* test if this exec can be paired with change_profile onexec.
-		 * onexec permission is linked to exec with a standard pairing
-		 * exec\0change_profile
-		 */
-		state = aa_dfa_null_transition(profile->file.dfa, state);
-		cp = change_profile_perms(profile, cxt->onexec->ns,
-					  cxt->onexec->base.name,
-					  AA_MAY_ONEXEC, state);
-
-		if (!(cp.allow & AA_MAY_ONEXEC))
-			goto audit;
-		new_profile = aa_get_newest_profile(cxt->onexec);
-		goto apply;
-	}
-
+	state = aa_str_perms(profile->file.dfa, state, name, cond, &perms);
 	if (perms.allow & MAY_EXEC) {
 		/* exec permission determine how to transition */
-		new_profile = x_to_profile(profile, name, perms.xindex);
-		if (!new_profile) {
-			if (perms.xindex & AA_X_INHERIT) {
-				/* (p|c|n)ix - don't change profile but do
-				 * use the newest version, which was picked
-				 * up above when getting profile
-				 */
-				info = "ix fallback";
-				new_profile = aa_get_profile(profile);
-				goto x_clear;
-			} else if (perms.xindex & AA_X_UNCONFINED) {
-				new_profile = aa_get_newest_profile(ns->unconfined);
-				info = "ux fallback";
-			} else {
-				error = -ENOENT;
-				info = "profile not found";
-				/* remove MAY_EXEC to audit as failure */
-				perms.allow &= ~MAY_EXEC;
-			}
+		new = x_to_label(profile, name, perms.xindex, &target, &info);
+		if (new && new->proxy == profile->label.proxy && info) {
+			/* hack ix fallback - improve how this is detected */
+			goto audit;
+		} else if (!new) {
+			error = -EACCES;
+			info = "profile transition not found";
+			/* remove MAY_EXEC to audit as failure */
+			perms.allow &= ~MAY_EXEC;
 		}
 	} else if (COMPLAIN_MODE(profile)) {
-		/* no exec permission - are we in learning mode */
-		new_profile = aa_new_null_profile(profile, 0);
+		/* no exec permission - learning mode */
+		struct aa_profile *new_profile = aa_null_profile(profile, false,
+							      name, GFP_ATOMIC);
 		if (!new_profile) {
 			error = -ENOMEM;
 			info = "could not create null profile";
 		} else {
 			error = -EACCES;
-			target = new_profile->base.hname;
+			new = &new_profile->label;
 		}
 		perms.xindex |= AA_X_UNSAFE;
 	} else
 		/* fail exec */
 		error = -EACCES;
 
-	/*
-	 * Policy has specified a domain transition, if no_new_privs then
-	 * fail the exec.
+	if (!new)
+		goto audit;
+
+	if (!(perms.xindex & AA_X_UNSAFE)) {
+		if (DEBUG_ON) {
+			dbg_printk("apparmor: scrubbing environment variables "
+				   "for %s profile=", name);
+			aa_label_printk(new, GFP_ATOMIC);
+			dbg_printk("\n");
+		}
+		*secure_exec = true;
+	}
+
+audit:
+	aa_audit_file(profile, &perms, OP_EXEC, MAY_EXEC, name, target, new,
+		      cond->uid, info, error);
+	if (!new)
+		return ERR_PTR(error);
+
+	return new;
+}
+
+static int profile_onexec(struct aa_profile *profile, struct aa_label *onexec,
+			  bool stack, const struct linux_binprm *bprm,
+			  char *buffer, struct path_cond *cond,
+			  bool *secure_exec)
+{
+	unsigned int state = profile->file.start;
+	struct aa_perms perms = {};
+	const char *xname = NULL, *info = "change_profile onexec";
+	int error = -EACCES;
+
+	AA_BUG(!profile);
+	AA_BUG(!onexec);
+	AA_BUG(!bprm);
+	AA_BUG(!buffer);
+
+	if (profile_unconfined(profile)) {
+		/* change_profile on exec already granted */
+		/*
+		 * NOTE: Domain transitions from unconfined are allowed
+		 * even when no_new_privs is set because this aways results
+		 * in a further reduction of permissions.
+		 */
+		return 0;
+	}
+
+	error = aa_path_name(&bprm->file->f_path, profile->path_flags, buffer,
+			     &xname, &info, profile->disconnected);
+	if (error) {
+		if (profile_unconfined(profile) ||
+		    (profile->label.flags & FLAG_IX_ON_NAME_ERROR)) {
+			AA_DEBUG("name lookup ix on error");
+			error = 0;
+		}
+		xname = bprm->filename;
+		goto audit;
+	}
+
+	/* find exec permissions for name */
+	state = aa_str_perms(profile->file.dfa, state, xname, cond, &perms);
+	if (!(perms.allow & AA_MAY_ONEXEC)) {
+		info = "no change_onexec valid for executable";
+		goto audit;
+	}
+	/* test if this exec can be paired with change_profile onexec.
+	 * onexec permission is linked to exec with a standard pairing
+	 * exec\0change_profile
 	 */
-	if (bprm->unsafe & LSM_UNSAFE_NO_NEW_PRIVS) {
-		aa_put_profile(new_profile);
-		error = -EPERM;
-		goto cleanup;
+	state = aa_dfa_null_transition(profile->file.dfa, state);
+	error = change_profile_perms(profile, onexec, stack, AA_MAY_ONEXEC,
+				     state, &perms);
+	if (error)
+		goto audit;
+
+	if (!(perms.xindex & AA_X_UNSAFE)) {
+		if (DEBUG_ON) {
+			dbg_printk("appaarmor: scrubbing environment "
+				   "variables for %s label=", xname);
+			aa_label_printk(onexec, GFP_ATOMIC);
+			dbg_printk("\n");
+		}
+		*secure_exec = true;
+	}
+
+audit:
+	return aa_audit_file(profile, &perms, OP_EXEC, AA_MAY_ONEXEC, xname,
+			     NULL, onexec, cond->uid, info, error);
+}
+
+/* ensure none ns domain transitions are correctly applied with onexec */
+
+static struct aa_label *handle_onexec(struct aa_label *label,
+				      struct aa_label *onexec, bool stack,
+				      const struct linux_binprm *bprm,
+				      char *buffer, struct path_cond *cond,
+				      bool *unsafe)
+{
+	struct aa_profile *profile;
+	struct aa_label *new;
+	int error;
+
+	AA_BUG(!label);
+	AA_BUG(!onexec);
+	AA_BUG(!bprm);
+	AA_BUG(!buffer);
+
+	if (!stack) {
+		error = fn_for_each_in_ns(label, profile,
+				profile_onexec(profile, onexec, stack,
+					       bprm, buffer, cond, unsafe));
+		if (error)
+			return ERR_PTR(error);
+		new = fn_label_build_in_ns(label, profile, GFP_ATOMIC,
+				aa_get_newest_label(onexec),
+				profile_transition(profile, bprm, buffer,
+						   cond, unsafe));
+
+	} else {
+		/* TODO: determine how much we want to losen this */
+		error = fn_for_each_in_ns(label, profile,
+				profile_onexec(profile, onexec, stack, bprm,
+					       buffer, cond, unsafe));
+		if (error)
+			return ERR_PTR(error);
+		new = fn_label_build_in_ns(label, profile, GFP_ATOMIC,
+				aa_label_merge(&profile->label, onexec,
+					       GFP_ATOMIC),
+				profile_transition(profile, bprm, buffer,
+						   cond, unsafe));
+	}
+
+	if (new)
+		return new;
+
+	/* TODO: get rid of GLOBAL_ROOT_UID */
+	error = fn_for_each_in_ns(label, profile,
+			aa_audit_file(profile, &nullperms, OP_CHANGE_ONEXEC,
+				      AA_MAY_ONEXEC, bprm->filename, NULL,
+				      onexec, GLOBAL_ROOT_UID,
+				      "failed to build target label", -ENOMEM));
+	return ERR_PTR(error);
+}
+
+/**
+ * apparmor_bprm_set_creds - set the new creds on the bprm struct
+ * @bprm: binprm for the exec  (NOT NULL)
+ *
+ * Returns: %0 or error on failure
+ *
+ * TODO: once the other paths are done see if we can't refactor into a fn
+ */
+int apparmor_bprm_set_creds(struct linux_binprm *bprm)
+{
+	struct aa_task_ctx *ctx;
+	struct aa_label *label, *new = NULL;
+	struct aa_profile *profile;
+	char *buffer = NULL;
+	const char *info = NULL;
+	int error = 0;
+	bool unsafe = false;
+	struct path_cond cond = {
+		file_inode(bprm->file)->i_uid,
+		file_inode(bprm->file)->i_mode
+	};
+
+	if (bprm->cred_prepared)
+		return 0;
+
+	ctx = cred_ctx(bprm->cred);
+	AA_BUG(!ctx);
+
+	label = aa_get_newest_label(ctx->label);
+
+	/* buffer freed below, name is pointer into buffer */
+	get_buffers(buffer);
+	/* Test for onexec first as onexec override other x transitions. */
+	if (ctx->onexec)
+		new = handle_onexec(label, ctx->onexec, ctx->token,
+				    bprm, buffer, &cond, &unsafe);
+	else
+		new = fn_label_build(label, profile, GFP_ATOMIC,
+				profile_transition(profile, bprm, buffer,
+						   &cond, &unsafe));
+
+	AA_BUG(!new);
+	if (IS_ERR(new)) {
+		error = PTR_ERR(new);
+		goto done;
+	} else if (!new) {
+		error = -ENOMEM;
+		goto done;
 	}
 
-	if (!new_profile)
+	/* Policy has specified a domain transitions. if no_new_privs and
+	 * confined and not transitioning to the current domain fail.
+	 *
+	 * NOTE: Domain transitions from unconfined and to stritly stacked
+	 * subsets are allowed even when no_new_privs is set because this
+	 * aways results in a further reduction of permissions.
+	 */
+	if ((bprm->unsafe & LSM_UNSAFE_NO_NEW_PRIVS) &&
+	    !unconfined(label) && !aa_label_is_subset(new, label)) {
+		error = -EPERM;
+		info = "no new privs";
 		goto audit;
+	}
 
 	if (bprm->unsafe & LSM_UNSAFE_SHARE) {
 		/* FIXME: currently don't mediate shared state */
@@ -473,52 +770,53 @@ int apparmor_bprm_set_creds(struct linux
 	}
 
 	if (bprm->unsafe & (LSM_UNSAFE_PTRACE | LSM_UNSAFE_PTRACE_CAP)) {
-		error = may_change_ptraced_domain(new_profile);
-		if (error) {
-			aa_put_profile(new_profile);
+		/* TODO: test needs to be profile of label to new */
+		error = may_change_ptraced_domain(new, &info);
+		if (error)
 			goto audit;
-		}
 	}
 
-	/* Determine if secure exec is needed.
-	 * Can be at this point for the following reasons:
-	 * 1. unconfined switching to confined
-	 * 2. confined switching to different confinement
-	 * 3. confined switching to unconfined
-	 *
-	 * Cases 2 and 3 are marked as requiring secure exec
-	 * (unless policy specified "unsafe exec")
-	 *
-	 * bprm->unsafe is used to cache the AA_X_UNSAFE permission
-	 * to avoid having to recompute in secureexec
-	 */
-	if (!(perms.xindex & AA_X_UNSAFE)) {
-		AA_DEBUG("scrubbing environment variables for %s profile=%s\n",
-			 name, new_profile->base.hname);
+	if (unsafe) {
+		if (DEBUG_ON) {
+			dbg_printk("scrubbing environment variables for %s "
+				   "label=", bprm->filename);
+			aa_label_printk(new, GFP_ATOMIC);
+			dbg_printk("\n");
+		}
 		bprm->unsafe |= AA_SECURE_X_NEEDED;
 	}
-apply:
-	target = new_profile->base.hname;
-	/* when transitioning profiles clear unsafe personality bits */
-	bprm->per_clear |= PER_CLEAR_ON_SETID;
-
-x_clear:
-	aa_put_profile(cxt->profile);
-	/* transfer new profile reference will be released when cxt is freed */
-	cxt->profile = new_profile;
-
-	/* clear out all temporary/transitional state from the context */
-	aa_clear_task_cxt_trans(cxt);
 
-audit:
-	error = aa_audit_file(profile, &perms, GFP_KERNEL, OP_EXEC, MAY_EXEC,
-			      name, target, cond.uid, info, error);
+	if (label->proxy != new->proxy) {
+		/* when transitioning clear unsafe personality bits */
+		if (DEBUG_ON) {
+			dbg_printk("apparmor: clearing unsafe personality "
+				   "bits. %s label=", bprm->filename);
+			aa_label_printk(new, GFP_ATOMIC);
+			dbg_printk("\n");
+		}
+		bprm->per_clear |= PER_CLEAR_ON_SETID;
+	}
+	aa_put_label(ctx->label);
+	/* transfer reference, released when ctx is freed */
+	ctx->label = new;
+
+done:
+	/* clear out temporary/transitional state from the context */
+	aa_clear_task_ctx_trans(ctx);
 
-cleanup:
-	aa_put_profile(profile);
-	kfree(buffer);
+	aa_put_label(label);
+	put_buffers(buffer);
 
 	return error;
+
+audit:
+	error = fn_for_each(label, profile,
+			aa_audit_file(profile, &nullperms, OP_EXEC, MAY_EXEC,
+				      bprm->filename, NULL, new,
+				      file_inode(bprm->file)->i_uid, info,
+				      error));
+	aa_put_label(new);
+	goto done;
 }
 
 /**
@@ -538,53 +836,154 @@ int apparmor_bprm_secureexec(struct linu
 	return 0;
 }
 
-/**
- * apparmor_bprm_committing_creds - do task cleanup on committing new creds
- * @bprm: binprm for the exec  (NOT NULL)
+/*
+ * Functions for self directed profile change
+ */
+
+
+/* helper fn for change_hat
+ *
+ * Returns: label for hat transition OR ERR_PTR.  Does NOT return NULL
  */
-void apparmor_bprm_committing_creds(struct linux_binprm *bprm)
+static struct aa_label *build_change_hat(struct aa_profile *profile,
+					 const char *name, bool sibling)
 {
-	struct aa_profile *profile = __aa_current_profile();
-	struct aa_task_cxt *new_cxt = cred_cxt(bprm->cred);
+	struct aa_profile *root, *hat = NULL;
+	const char *info = NULL;
+	int error = 0;
 
-	/* bail out if unconfined or not changing profile */
-	if ((new_cxt->profile == profile) ||
-	    (unconfined(new_cxt->profile)))
-		return;
+	if (sibling && PROFILE_IS_HAT(profile)) {
+		root = aa_get_profile_rcu(&profile->parent);
+	} else if (!sibling && !PROFILE_IS_HAT(profile)) {
+		root = aa_get_profile(profile);
+	} else {
+		info = "conflicting target types";
+		error = -EPERM;
+		goto audit;
+	}
 
-	current->pdeath_signal = 0;
+	hat = aa_find_child(root, name);
+	if (!hat) {
+		error = -ENOENT;
+		if (COMPLAIN_MODE(profile)) {
+			hat = aa_null_profile(profile, true, name, GFP_KERNEL);
+			if (!hat) {
+				info = "failed null profile create";
+				error = -ENOMEM;
+			}
+		}
+	}
+	aa_put_profile(root);
 
-	/* reset soft limits and set hard limits for the new profile */
-	__aa_transition_rlimits(profile, new_cxt->profile);
+audit:
+	aa_audit_file(profile, &nullperms, OP_CHANGE_HAT, AA_MAY_CHANGEHAT,
+		      name, hat ? hat->base.hname : NULL, hat ? &hat->label : NULL, GLOBAL_ROOT_UID,
+		      NULL, error);
+	if (!hat || (error && error != -ENOENT))
+		return ERR_PTR(error);
+	/* if hat && error - complain mode, already audited and we adjust for
+	 * complain mode allow by returning hat->label
+	 */
+	return &hat->label;
 }
 
-/**
- * apparmor_bprm_commited_cred - do cleanup after new creds committed
- * @bprm: binprm for the exec  (NOT NULL)
+/* helper fn for changing into a hat
+ *
+ * Returns: label for hat transition or ERR_PTR. Does not return NULL
  */
-void apparmor_bprm_committed_creds(struct linux_binprm *bprm)
+static struct aa_label *change_hat(struct aa_label *label, const char *hats[],
+				   int count, bool permtest)
 {
-	/* TODO: cleanup signals - ipc mediation */
-	return;
-}
+	struct aa_profile *profile, *root, *hat = NULL;
+	struct aa_label *new;
+	struct label_it it;
+	bool sibling = false;
+	const char *name, *info = NULL;
+	int i, error;
+
+	AA_BUG(!label);
+	AA_BUG(!hats);
+	AA_BUG(count < 1);
+
+	if (PROFILE_IS_HAT(labels_profile(label)))
+		sibling = true;
+
+	/*find first matching hat */
+	for (i = 0; i < count && !hat; i++) {
+		name = hats[i];
+		label_for_each_in_ns(it, labels_ns(label), label, profile) {
+			if (sibling && PROFILE_IS_HAT(profile)) {
+				root = aa_get_profile_rcu(&profile->parent);
+			} else if (!sibling && !PROFILE_IS_HAT(profile)) {
+				root = aa_get_profile(profile);
+			} else {	/* conflicting change type */
+				info = "conflicting targets types";
+				error = -EPERM;
+				goto fail;
+			}
+			hat = aa_find_child(root, name);
+			aa_put_profile(root);
+			if (!hat) {
+				if (!COMPLAIN_MODE(profile))
+					goto outer_continue;
+				/* complain mode succeed as if hat */
+			} else if (!PROFILE_IS_HAT(hat)) {
+				info = "target not hat";
+				error = -EPERM;
+				aa_put_profile(hat);
+				goto fail;
+			}
+			aa_put_profile(hat);
+		}
+		/* found a hat for all profiles in ns */
+		goto build;
+	outer_continue: ;
+	}
+	/* no hats that match, find appropriate error
+	 *
+	 * In complain mode audit of the failure is based off of the first
+	 * hat supplied.  This is done due how userspace interacts with
+	 * change_hat.
+	 */
+	name = NULL;
+	label_for_each_in_ns(it, labels_ns(label), label, profile) {
+		if (!list_empty(&profile->base.profiles)) {
+			info = "hat not found";
+			error = -ENOENT;
+			goto fail;
+		}
+	}
+	info = "no hats defined";
+	error = -ECHILD;
 
-/*
- * Functions for self directed profile change
- */
+fail:
+	label_for_each_in_ns(it, labels_ns(label), label, profile) {
+		/*
+		 * no target as it has failed to be found or built
+		 *
+		 * change_hat uses probing and should not log failures
+		 * related to missing hats
+		 */
+		/* TODO: get rid of GLOBAL_ROOT_UID */
+		if (count > 1 || COMPLAIN_MODE(profile)) {
+			aa_audit_file(profile, &nullperms, OP_CHANGE_HAT,
+				      AA_MAY_CHANGEHAT, name, NULL, NULL,
+				      GLOBAL_ROOT_UID, info, error);
+		}
+	}
+	return (ERR_PTR(error));
 
-/**
- * new_compound_name - create an hname with @n2 appended to @n1
- * @n1: base of hname  (NOT NULL)
- * @n2: name to append (NOT NULL)
- *
- * Returns: new name or NULL on error
- */
-static char *new_compound_name(const char *n1, const char *n2)
-{
-	char *name = kmalloc(strlen(n1) + strlen(n2) + 3, GFP_KERNEL);
-	if (name)
-		sprintf(name, "%s//%s", n1, n2);
-	return name;
+build:
+	new = fn_label_build_in_ns(label, profile, GFP_KERNEL,
+				   build_change_hat(profile, name, sibling),
+				   aa_get_label(&profile->label));
+	if (!new) {
+		info = "label build failed";
+		error = -ENOMEM;
+		goto fail;
+	} /* else if (IS_ERR) build_change_hat has logged error so return new */
+
+	return new;
 }
 
 /**
@@ -594,22 +993,24 @@ static char *new_compound_name(const cha
  * @token: magic value to validate the hat change
  * @permtest: true if this is just a permission test
  *
+ * Returns %0 on success, error otherwise.
+ *
  * Change to the first profile specified in @hats that exists, and store
  * the @hat_magic in the current task context.  If the count == 0 and the
  * @token matches that stored in the current task context, return to the
  * top level profile.
  *
- * Returns %0 on success, error otherwise.
+ * change_hat only applies to profiles in the current ns, and each profile
+ * in the ns must make the same transition otherwise change_hat will fail.
  */
 int aa_change_hat(const char *hats[], int count, u64 token, bool permtest)
 {
 	const struct cred *cred;
-	struct aa_task_cxt *cxt;
-	struct aa_profile *profile, *previous_profile, *hat = NULL;
-	char *name = NULL;
-	int i;
-	struct file_perms perms = {};
-	const char *target = NULL, *info = NULL;
+	struct aa_task_ctx *ctx;
+	struct aa_label *label, *previous, *new = NULL, *target = NULL;
+	struct aa_profile *profile;
+	struct aa_perms perms = {};
+	const char *info = NULL;
 	int error = 0;
 
 	/*
@@ -617,121 +1018,102 @@ int aa_change_hat(const char *hats[], in
 	 * There is no exception for unconfined as change_hat is not
 	 * available.
 	 */
-	if (task_no_new_privs(current))
+	if (task_no_new_privs(current)) {
+		/* not an apparmor denial per se, so don't log it */
+		AA_DEBUG("no_new_privs - chanage_hat denied");
 		return -EPERM;
+	}
 
 	/* released below */
 	cred = get_current_cred();
-	cxt = cred_cxt(cred);
-	profile = aa_cred_profile(cred);
-	previous_profile = cxt->previous;
+	ctx = cred_ctx(cred);
+	label = aa_get_newest_cred_label(cred);
+	previous = aa_get_newest_label(ctx->previous);
 
-	if (unconfined(profile)) {
-		info = "unconfined";
+	if (unconfined(label)) {
+		info = "unconfined can not change_hat";
 		error = -EPERM;
-		goto audit;
+		goto fail;
 	}
 
 	if (count) {
-		/* attempting to change into a new hat or switch to a sibling */
-		struct aa_profile *root;
-		if (PROFILE_IS_HAT(profile))
-			root = aa_get_profile_rcu(&profile->parent);
-		else
-			root = aa_get_profile(profile);
-
-		/* find first matching hat */
-		for (i = 0; i < count && !hat; i++)
-			/* released below */
-			hat = aa_find_child(root, hats[i]);
-		if (!hat) {
-			if (!COMPLAIN_MODE(root) || permtest) {
-				if (list_empty(&root->base.profiles))
-					error = -ECHILD;
-				else
-					error = -ENOENT;
-				aa_put_profile(root);
-				goto out;
-			}
-
-			/*
-			 * In complain mode and failed to match any hats.
-			 * Audit the failure is based off of the first hat
-			 * supplied.  This is done due how userspace
-			 * interacts with change_hat.
-			 *
-			 * TODO: Add logging of all failed hats
-			 */
-
-			/* freed below */
-			name = new_compound_name(root->base.hname, hats[0]);
-			aa_put_profile(root);
-			target = name;
-			/* released below */
-			hat = aa_new_null_profile(profile, 1);
-			if (!hat) {
-				info = "failed null profile create";
-				error = -ENOMEM;
-				goto audit;
-			}
-		} else {
-			aa_put_profile(root);
-			target = hat->base.hname;
-			if (!PROFILE_IS_HAT(hat)) {
-				info = "target not hat";
-				error = -EPERM;
-				goto audit;
-			}
+		new = change_hat(label, hats, count, permtest);
+		AA_BUG(!new);
+		if (IS_ERR(new)) {
+			error = PTR_ERR(new);
+			new = NULL;
+			/* already audited */
+			goto out;
 		}
 
-		error = may_change_ptraced_domain(hat);
+		error = may_change_ptraced_domain(new, &info);
+		if (error)
+			goto fail;
+
+		if (permtest)
+			goto out;
+
+		target = new;
+		error = aa_set_current_hat(new, token);
+		if (error == -EACCES)
+			/* kill task in case of brute force attacks */
+			goto kill;
+	} else if (previous && !permtest) {
+		/* Return to saved label.  Kill task if restore fails
+		 * to avoid brute force attacks
+		 */
+		target = previous;
+		error = aa_restore_previous_label(token);
 		if (error) {
-			info = "ptraced";
-			error = -EPERM;
-			goto audit;
-		}
-
-		if (!permtest) {
-			error = aa_set_current_hat(hat, token);
 			if (error == -EACCES)
-				/* kill task in case of brute force attacks */
-				perms.kill = AA_MAY_CHANGEHAT;
-			else if (name && !error)
-				/* reset error for learning of new hats */
-				error = -ENOENT;
+				goto kill;
+			goto fail;
 		}
-	} else if (previous_profile) {
-		/* Return to saved profile.  Kill task if restore fails
-		 * to avoid brute force attacks
-		 */
-		target = previous_profile->base.hname;
-		error = aa_restore_previous_profile(token);
-		perms.kill = AA_MAY_CHANGEHAT;
-	} else
-		/* ignore restores when there is no saved profile */
-		goto out;
-
-audit:
-	if (!permtest)
-		error = aa_audit_file(profile, &perms, GFP_KERNEL,
-				      OP_CHANGE_HAT, AA_MAY_CHANGEHAT, NULL,
-				      target, GLOBAL_ROOT_UID, info, error);
+	} /* else ignore permtest && restores when there is no saved profile */
 
 out:
-	aa_put_profile(hat);
-	kfree(name);
+	aa_put_label(new);
+	aa_put_label(previous);
+	aa_put_label(label);
 	put_cred(cred);
 
 	return error;
+
+kill:
+	info = "failed token match";
+	perms.kill = AA_MAY_CHANGEHAT;
+
+fail:
+	fn_for_each_in_ns(label, profile,
+		aa_audit_file(profile, &perms, OP_CHANGE_HAT, AA_MAY_CHANGEHAT,
+			      NULL, NULL, target, GLOBAL_ROOT_UID, info, error));
+
+	goto out;
+}
+
+
+static int change_profile_perms_wrapper(const char *op, const char *name,
+					struct aa_profile *profile,
+					struct aa_label *target, bool stack,
+					u32 request, struct aa_perms *perms)
+{
+	int error = change_profile_perms(profile, target,
+					 stack, request,
+					 profile->file.start, perms);
+	if (error)
+		error = aa_audit_file(profile, perms, op, request, name,
+				      NULL, target, GLOBAL_ROOT_UID, NULL,
+				      error);
+
+	return error;
 }
 
 /**
  * aa_change_profile - perform a one-way profile transition
- * @ns_name: name of the profile namespace to change to (MAYBE NULL)
- * @hname: name of profile to change to (MAYBE NULL)
+ * @fqname: name of profile may include namespace (NOT NULL)
  * @onexec: whether this transition is to take place immediately or at exec
  * @permtest: true if this is just a permission test
- *
+ * @stack: true if this call is to stack on top of current domain
  * Change to new profile @name.  Unlike with hats, there is no way
  * to change back.  If @name isn't specified the current profile name is
  * used.
@@ -740,111 +1122,144 @@ out:
  *
  * Returns %0 on success, error otherwise.
  */
-int aa_change_profile(const char *ns_name, const char *hname, bool onexec,
-		      bool permtest)
+int aa_change_profile(const char *fqname, bool onexec,
+		      bool permtest, bool stack)
 {
-	const struct cred *cred;
-	struct aa_profile *profile, *target = NULL;
-	struct aa_namespace *ns = NULL;
-	struct file_perms perms = {};
-	const char *name = NULL, *info = NULL;
-	int op, error = 0;
+	struct aa_label *label, *new = NULL, *target = NULL;
+	struct aa_profile *profile;
+	struct aa_perms perms = {};
+	const char *info = NULL;
+	const char *auditname = fqname;		/* retain leading & if stack */
+	int error = 0;
+	char *op;
 	u32 request;
 
-	if (!hname && !ns_name)
+	if (!fqname || !*fqname) {
+		AA_DEBUG("no profile name");
 		return -EINVAL;
+	}
 
 	if (onexec) {
 		request = AA_MAY_ONEXEC;
-		op = OP_CHANGE_ONEXEC;
+		if (stack)
+			op = OP_STACK_ONEXEC;
+		else
+			op = OP_CHANGE_ONEXEC;
 	} else {
 		request = AA_MAY_CHANGE_PROFILE;
-		op = OP_CHANGE_PROFILE;
+		if (stack)
+			op = OP_STACK;
+		else
+			op = OP_CHANGE_PROFILE;
 	}
 
-	cred = get_current_cred();
-	profile = aa_cred_profile(cred);
+	label = aa_get_current_label();
 
-	/*
-	 * Fail explicitly requested domain transitions if no_new_privs
-	 * and not unconfined.
-	 * Domain transitions from unconfined are allowed even when
-	 * no_new_privs is set because this aways results in a reduction
-	 * of permissions.
-	 */
-	if (task_no_new_privs(current) && !unconfined(profile)) {
-		put_cred(cred);
-		return -EPERM;
+	if (*fqname == '&') {
+		stack = true;
+		/* don't have label_parse() do stacking */
+		fqname++;
 	}
-
-	if (ns_name) {
+	target = aa_label_parse(label, fqname, GFP_KERNEL, true, false);
+	if (IS_ERR(target)) {
+		struct aa_profile *tprofile;
+
+		info = "label not found";
+		error = PTR_ERR(target);
+		target = NULL;
+		/* TODO: fixme using labels_profile is not right - do profile
+		   per complain profile ??? */
+		if (permtest || !COMPLAIN_MODE(labels_profile(label)))
+			goto audit;
 		/* released below */
-		ns = aa_find_namespace(profile->ns, ns_name);
-		if (!ns) {
-			/* we don't create new namespace in complain mode */
-			name = ns_name;
-			info = "namespace not found";
-			error = -ENOENT;
+		tprofile = aa_null_profile(labels_profile(label), false, fqname, GFP_KERNEL);
+		if (!tprofile) {
+			info = "failed null profile create";
+			error = -ENOMEM;
 			goto audit;
 		}
-	} else
-		/* released below */
-		ns = aa_get_namespace(profile->ns);
-
-	/* if the name was not specified, use the name of the current profile */
-	if (!hname) {
-		if (unconfined(profile))
-			hname = ns->unconfined->base.hname;
-		else
-			hname = profile->base.hname;
+		target = &tprofile->label;
+		goto check;
 	}
 
-	perms = change_profile_perms(profile, ns, hname, request,
-				     profile->file.start);
-	if (!(perms.allow & request)) {
-		error = -EACCES;
+	/*
+	 * Fail explicitly requested domain transitions when no_new_privs
+	 * and not unconfined OR the transition results in a stack on
+	 * the current label.
+	 * Stacking domain transitions and transitions from unconfined are
+	 * allowed even when no_new_privs is set because this aways results
+	 * in a reduction of permissions.
+	 */
+	if (task_no_new_privs(current) && !stack && !unconfined(label) &&
+	    !aa_label_is_subset(target, label)) {
+		info = "no new privs";
+		error = -EPERM;
 		goto audit;
 	}
 
-	/* released below */
-	target = aa_lookup_profile(ns, hname);
-	if (!target) {
-		info = "profile not found";
-		error = -ENOENT;
-		if (permtest || !COMPLAIN_MODE(profile))
-			goto audit;
-		/* released below */
-		target = aa_new_null_profile(profile, 0);
-		if (!target) {
-			info = "failed null profile create";
-			error = -ENOMEM;
-			goto audit;
-		}
-	}
+	/* self directed transitions only apply to current policy ns */
+	/* TODO: currently requiring perms for stacking and straight change
+	 *       stacking doesn't strictly need this. Determine how much
+	 *       we want to loosen this restriction for stacking
+	 */
+	/* if (!stack) { */
+	error = fn_for_each_in_ns(label, profile,
+			change_profile_perms_wrapper(op, auditname,
+						     profile, target, stack,
+						     request, &perms));
+	if (error)
+		/* auditing done in change_profile_perms_wrapper */
+		goto out;
+
+	/* } */
 
+check:
 	/* check if tracing task is allowed to trace target domain */
-	error = may_change_ptraced_domain(target);
-	if (error) {
-		info = "ptrace prevents transition";
+	error = may_change_ptraced_domain(target, &info);
+	if (error && !fn_for_each_in_ns(label, profile,
+					COMPLAIN_MODE(profile)))
 		goto audit;
-	}
 
-	if (permtest)
+	/* TODO: add permission check to allow this
+	if (onexec && !current_is_single_threaded()) {
+		info = "not a single threaded task";
+		error = -EACCES;
 		goto audit;
+	}
+	*/
+	if (permtest)
+		goto out;
 
-	if (onexec)
-		error = aa_set_current_onexec(target);
-	else
-		error = aa_replace_current_profile(target);
+	if (!onexec) {
+		/* only transition profiles in the current ns */
+		if (stack)
+			new = aa_label_merge(label, target, GFP_KERNEL);
+		else
+			new = fn_label_build_in_ns(label, profile, GFP_KERNEL,
+					aa_get_label(target),
+					aa_get_label(&profile->label));
+		if (IS_ERR_OR_NULL(new)) {
+			info = "failed to build target label";
+			error = PTR_ERR(new);
+			new = NULL;
+			perms.allow = 0;
+			goto audit;
+		}
+		error = aa_replace_current_label(new);
+	} else
+		/* full transition will be built in exec path */
+		error = aa_set_current_onexec(target, stack);
 
 audit:
-	if (!permtest)
-		error = aa_audit_file(profile, &perms, GFP_KERNEL, op, request,
-				      name, hname, GLOBAL_ROOT_UID, info, error);
+	error = fn_for_each_in_ns(label, profile,
+			aa_audit_file(profile, &perms, op, request, auditname,
+				      NULL, new ? new : target,
+				      GLOBAL_ROOT_UID, info, error));
 
-	aa_put_namespace(ns);
-	aa_put_profile(target);
-	put_cred(cred);
+out:
+	aa_put_label(new);
+	aa_put_label(target);
+	aa_put_label(label);
 
 	return error;
 }
--- zfcpdump-kernel-4.4.orig/security/apparmor/file.c
+++ zfcpdump-kernel-4.4/security/apparmor/file.c
@@ -12,15 +12,30 @@
  * License.
  */
 
+#include <linux/tty.h>
+#include <linux/fdtable.h>
+#include <linux/file.h>
+
+#include "include/af_unix.h"
 #include "include/apparmor.h"
 #include "include/audit.h"
+#include "include/context.h"
 #include "include/file.h"
 #include "include/match.h"
 #include "include/path.h"
 #include "include/policy.h"
+#include "include/label.h"
 
-struct file_perms nullperms;
+static u32 map_mask_to_chr_mask(u32 mask)
+{
+	u32 m = mask & PERMS_CHRS_MASK;
+	if (mask & AA_MAY_GETATTR)
+		m |= MAY_READ;
+	if (mask & (AA_MAY_SETATTR | AA_MAY_CHMOD | AA_MAY_CHOWN))
+		m |= MAY_WRITE;
 
+	return m;
+}
 
 /**
  * audit_file_mask - convert mask to permission string
@@ -31,29 +46,7 @@ static void audit_file_mask(struct audit
 {
 	char str[10];
 
-	char *m = str;
-
-	if (mask & AA_EXEC_MMAP)
-		*m++ = 'm';
-	if (mask & (MAY_READ | AA_MAY_META_READ))
-		*m++ = 'r';
-	if (mask & (MAY_WRITE | AA_MAY_META_WRITE | AA_MAY_CHMOD |
-		    AA_MAY_CHOWN))
-		*m++ = 'w';
-	else if (mask & MAY_APPEND)
-		*m++ = 'a';
-	if (mask & AA_MAY_CREATE)
-		*m++ = 'c';
-	if (mask & AA_MAY_DELETE)
-		*m++ = 'd';
-	if (mask & AA_MAY_LINK)
-		*m++ = 'l';
-	if (mask & AA_MAY_LOCK)
-		*m++ = 'k';
-	if (mask & MAY_EXEC)
-		*m++ = 'x';
-	*m = '\0';
-
+	aa_perm_mask_to_str(str, aa_file_perm_chrs, map_mask_to_chr_mask(mask));
 	audit_log_string(ab, str);
 }
 
@@ -67,24 +60,28 @@ static void file_audit_cb(struct audit_b
 	struct common_audit_data *sa = va;
 	kuid_t fsuid = current_fsuid();
 
-	if (sa->aad->fs.request & AA_AUDIT_FILE_MASK) {
+	if (aad(sa)->request & AA_AUDIT_FILE_MASK) {
 		audit_log_format(ab, " requested_mask=");
-		audit_file_mask(ab, sa->aad->fs.request);
+		audit_file_mask(ab, aad(sa)->request);
 	}
-	if (sa->aad->fs.denied & AA_AUDIT_FILE_MASK) {
+	if (aad(sa)->denied & AA_AUDIT_FILE_MASK) {
 		audit_log_format(ab, " denied_mask=");
-		audit_file_mask(ab, sa->aad->fs.denied);
+		audit_file_mask(ab, aad(sa)->denied);
 	}
-	if (sa->aad->fs.request & AA_AUDIT_FILE_MASK) {
+	if (aad(sa)->request & AA_AUDIT_FILE_MASK) {
 		audit_log_format(ab, " fsuid=%d",
 				 from_kuid(&init_user_ns, fsuid));
 		audit_log_format(ab, " ouid=%d",
-				 from_kuid(&init_user_ns, sa->aad->fs.ouid));
+				 from_kuid(&init_user_ns, aad(sa)->fs.ouid));
 	}
 
-	if (sa->aad->fs.target) {
+	if (aad(sa)->peer) {
+		audit_log_format(ab, " target=");
+		aa_label_xaudit(ab, labels_ns(aad(sa)->label), aad(sa)->peer,
+				FLAG_VIEW_SUBNS, GFP_ATOMIC);
+	} else if (aad(sa)->fs.target) {
 		audit_log_format(ab, " target=");
-		audit_log_untrustedstring(ab, sa->aad->fs.target);
+		audit_log_untrustedstring(ab, aad(sa)->fs.target);
 	}
 }
 
@@ -92,65 +89,98 @@ static void file_audit_cb(struct audit_b
  * aa_audit_file - handle the auditing of file operations
  * @profile: the profile being enforced  (NOT NULL)
  * @perms: the permissions computed for the request (NOT NULL)
- * @gfp: allocation flags
  * @op: operation being mediated
  * @request: permissions requested
  * @name: name of object being mediated (MAYBE NULL)
  * @target: name of target (MAYBE NULL)
+ * @tlabel: target label (MAY BE NULL)
  * @ouid: object uid
  * @info: extra information message (MAYBE NULL)
  * @error: 0 if operation allowed else failure error code
  *
  * Returns: %0 or error on failure
  */
-int aa_audit_file(struct aa_profile *profile, struct file_perms *perms,
-		  gfp_t gfp, int op, u32 request, const char *name,
-		  const char *target, kuid_t ouid, const char *info, int error)
+int aa_audit_file(struct aa_profile *profile, struct aa_perms *perms,
+		  const char *op, u32 request, const char *name,
+		  const char *target, struct aa_label *tlabel,
+		  kuid_t ouid, const char *info, int error)
 {
 	int type = AUDIT_APPARMOR_AUTO;
-	struct common_audit_data sa;
-	struct apparmor_audit_data aad = {0,};
-	sa.type = LSM_AUDIT_DATA_NONE;
-	sa.aad = &aad;
-	aad.op = op,
-	aad.fs.request = request;
-	aad.name = name;
-	aad.fs.target = target;
-	aad.fs.ouid = ouid;
-	aad.info = info;
-	aad.error = error;
 
-	if (likely(!sa.aad->error)) {
+	DEFINE_AUDIT_DATA(sa, LSM_AUDIT_DATA_TASK, op);
+	sa.u.tsk = NULL;
+	aad(&sa)->request = request;
+	aad(&sa)->name = name;
+	aad(&sa)->fs.target = target;
+	aad(&sa)->peer = tlabel;
+	aad(&sa)->fs.ouid = ouid;
+	aad(&sa)->info = info;
+	aad(&sa)->error = error;
+	sa.u.tsk = NULL;
+
+	if (likely(!aad(&sa)->error)) {
 		u32 mask = perms->audit;
 
 		if (unlikely(AUDIT_MODE(profile) == AUDIT_ALL))
 			mask = 0xffff;
 
 		/* mask off perms that are not being force audited */
-		sa.aad->fs.request &= mask;
+		aad(&sa)->request &= mask;
 
-		if (likely(!sa.aad->fs.request))
+		if (likely(!aad(&sa)->request))
 			return 0;
 		type = AUDIT_APPARMOR_AUDIT;
 	} else {
 		/* only report permissions that were denied */
-		sa.aad->fs.request = sa.aad->fs.request & ~perms->allow;
+		aad(&sa)->request = aad(&sa)->request & ~perms->allow;
+		AA_BUG(!aad(&sa)->request);
 
-		if (sa.aad->fs.request & perms->kill)
+		if (aad(&sa)->request & perms->kill)
 			type = AUDIT_APPARMOR_KILL;
 
 		/* quiet known rejects, assumes quiet and kill do not overlap */
-		if ((sa.aad->fs.request & perms->quiet) &&
+		if ((aad(&sa)->request & perms->quiet) &&
 		    AUDIT_MODE(profile) != AUDIT_NOQUIET &&
 		    AUDIT_MODE(profile) != AUDIT_ALL)
-			sa.aad->fs.request &= ~perms->quiet;
+			aad(&sa)->request &= ~perms->quiet;
 
-		if (!sa.aad->fs.request)
-			return COMPLAIN_MODE(profile) ? 0 : sa.aad->error;
+		if (!aad(&sa)->request)
+			return aad(&sa)->error;
 	}
 
-	sa.aad->fs.denied = sa.aad->fs.request & ~perms->allow;
-	return aa_audit(type, profile, gfp, &sa, file_audit_cb);
+	aad(&sa)->denied = aad(&sa)->request & ~perms->allow;
+	return aa_audit(type, profile, &sa, file_audit_cb);
+}
+
+/**
+ * is_deleted - test if a file has been completely unlinked
+ * @dentry: dentry of file to test for deletion  (NOT NULL)
+ *
+ * Returns: %1 if deleted else %0
+ */
+static inline bool is_deleted(struct dentry *dentry)
+{
+	if (d_unlinked(dentry) && d_backing_inode(dentry)->i_nlink == 0)
+		return 1;
+	return 0;
+}
+
+static int path_name(const char *op, struct aa_label *label,
+		     const struct path *path, int flags, char *buffer,
+		     const char**name, struct path_cond *cond, u32 request)
+{
+	struct aa_profile *profile;
+	const char *info = NULL;
+	int error = aa_path_name(path, flags, buffer, name, &info,
+				 labels_profile(label)->disconnected);
+	if (error) {
+		fn_for_each_confined(label, profile,
+			aa_audit_file(profile, &nullperms, op, request, *name,
+				      NULL, NULL, cond->uid, info, error));
+		return error;
+	}
+
+	return 0;
 }
 
 /**
@@ -163,10 +193,11 @@ static u32 map_old_perms(u32 old)
 {
 	u32 new = old & 0xf;
 	if (old & MAY_READ)
-		new |= AA_MAY_META_READ;
+		new |= AA_MAY_GETATTR | AA_MAY_OPEN;
 	if (old & MAY_WRITE)
-		new |= AA_MAY_META_WRITE | AA_MAY_CREATE | AA_MAY_DELETE |
-			AA_MAY_CHMOD | AA_MAY_CHOWN;
+		new |= AA_MAY_SETATTR | AA_MAY_CREATE | AA_MAY_DELETE |
+			AA_MAY_CHMOD | AA_MAY_CHOWN | AA_MAY_OPEN |
+		        AA_MAY_DELETE;
 	if (old & 0x10)
 		new |= AA_MAY_LINK;
 	/* the old mapping lock and link_subset flags where overlaid
@@ -181,7 +212,7 @@ static u32 map_old_perms(u32 old)
 }
 
 /**
- * compute_perms - convert dfa compressed perms to internal perms
+ * aa_compute_fperms - convert dfa compressed perms to internal perms
  * @dfa: dfa to compute perms for   (NOT NULL)
  * @state: state in dfa
  * @cond:  conditions to consider  (NOT NULL)
@@ -191,17 +222,21 @@ static u32 map_old_perms(u32 old)
  *
  * Returns: computed permission set
  */
-static struct file_perms compute_perms(struct aa_dfa *dfa, unsigned int state,
-				       struct path_cond *cond)
+struct aa_perms aa_compute_fperms(struct aa_dfa *dfa, unsigned int state,
+				  struct path_cond *cond)
 {
-	struct file_perms perms;
+	struct aa_perms perms;
 
 	/* FIXME: change over to new dfa format
 	 * currently file perms are encoded in the dfa, new format
 	 * splits the permissions from the dfa.  This mapping can be
 	 * done at profile load
 	 */
-	perms.kill = 0;
+	perms.deny = 0;
+	perms.kill = perms.stop = 0;
+	perms.complain = perms.cond = 0;
+	perms.hide = 0;
+	perms.prompt = 0;
 
 	if (uid_eq(current_fsuid(), cond->uid)) {
 		perms.allow = map_old_perms(dfa_user_allow(dfa, state));
@@ -214,7 +249,7 @@ static struct file_perms compute_perms(s
 		perms.quiet = map_old_perms(dfa_other_quiet(dfa, state));
 		perms.xindex = dfa_other_xindex(dfa, state);
 	}
-	perms.allow |= AA_MAY_META_READ;
+	perms.allow |= AA_MAY_GETATTR;
 
 	/* change_profile wasn't determined by ownership in old mapping */
 	if (ACCEPT_TABLE(dfa)[state] & 0x80000000)
@@ -237,37 +272,56 @@ static struct file_perms compute_perms(s
  */
 unsigned int aa_str_perms(struct aa_dfa *dfa, unsigned int start,
 			  const char *name, struct path_cond *cond,
-			  struct file_perms *perms)
+			  struct aa_perms *perms)
 {
 	unsigned int state;
-	if (!dfa) {
-		*perms = nullperms;
-		return DFA_NOMATCH;
-	}
-
 	state = aa_dfa_match(dfa, start, name);
-	*perms = compute_perms(dfa, state, cond);
+	*perms = aa_compute_fperms(dfa, state, cond);
 
 	return state;
 }
 
-/**
- * is_deleted - test if a file has been completely unlinked
- * @dentry: dentry of file to test for deletion  (NOT NULL)
- *
- * Returns: %1 if deleted else %0
- */
-static inline bool is_deleted(struct dentry *dentry)
+int __aa_path_perm(const char *op, struct aa_profile *profile, const char *name,
+		   u32 request, struct path_cond *cond, int flags,
+		   struct aa_perms *perms)
 {
-	if (d_unlinked(dentry) && d_backing_inode(dentry)->i_nlink == 0)
-		return 1;
-	return 0;
+	int e = 0;
+
+	if (profile_unconfined(profile) ||
+	    ((flags & PATH_SOCK_COND) && !PROFILE_MEDIATES_AF(profile, AF_UNIX)))
+		return 0;
+	aa_str_perms(profile->file.dfa, profile->file.start, name, cond, perms);
+	if (request & ~perms->allow)
+		e = -EACCES;
+	return aa_audit_file(profile, perms, op, request, name, NULL, NULL,
+			     cond->uid, NULL, e);
+}
+
+
+static int profile_path_perm(const char *op, struct aa_profile *profile,
+			     const struct path *path, char *buffer, u32 request,
+			     struct path_cond *cond, int flags,
+			     struct aa_perms *perms)
+{
+	const char *name;
+	int error;
+
+	if (profile_unconfined(profile))
+		return 0;
+
+	error = path_name(op, &profile->label, path,
+			  flags | profile->path_flags, buffer, &name, cond,
+			  request);
+	if (error)
+		return error;
+	return __aa_path_perm(op, profile, name, request, cond, flags,
+			      perms);
 }
 
 /**
  * aa_path_perm - do permissions check & audit for @path
  * @op: operation being checked
- * @profile: profile being enforced  (NOT NULL)
+ * @label: profile being enforced  (NOT NULL)
  * @path: path to check permissions of  (NOT NULL)
  * @flags: any additional path flags beyond what the profile specifies
  * @request: requested permissions
@@ -275,35 +329,22 @@ static inline bool is_deleted(struct den
  *
  * Returns: %0 else error if access denied or other error
  */
-int aa_path_perm(int op, struct aa_profile *profile, struct path *path,
-		 int flags, u32 request, struct path_cond *cond)
+int aa_path_perm(const char *op, struct aa_label *label,
+		 const struct path *path, int flags, u32 request,
+		 struct path_cond *cond)
 {
+	struct aa_perms perms = {};
+	struct aa_profile *profile;
 	char *buffer = NULL;
-	struct file_perms perms = {};
-	const char *name, *info = NULL;
 	int error;
 
-	flags |= profile->path_flags | (S_ISDIR(cond->mode) ? PATH_IS_DIR : 0);
-	error = aa_path_name(path, flags, &buffer, &name, &info);
-	if (error) {
-		if (error == -ENOENT && is_deleted(path->dentry)) {
-			/* Access to open files that are deleted are
-			 * give a pass (implicit delegation)
-			 */
-			error = 0;
-			info = NULL;
-			perms.allow = request;
-		}
-	} else {
-		aa_str_perms(profile->file.dfa, profile->file.start, name, cond,
-			     &perms);
-		if (request & ~perms.allow)
-			error = -EACCES;
-	}
-	error = aa_audit_file(profile, &perms, GFP_KERNEL, op, request, name,
-			      NULL, cond->uid, info, error);
-	kfree(buffer);
+	flags |= PATH_DELEGATE_DELETED | (S_ISDIR(cond->mode) ? PATH_IS_DIR : 0);
+	get_buffers(buffer);
+	error = fn_for_each_confined(label, profile,
+			profile_path_perm(op, profile, path, buffer, request,
+					  cond, flags, &perms));
 
+	put_buffers(buffer);
 	return error;
 }
 
@@ -327,65 +368,40 @@ static inline bool xindex_is_subset(u32
 	return 1;
 }
 
-/**
- * aa_path_link - Handle hard link permission check
- * @profile: the profile being enforced  (NOT NULL)
- * @old_dentry: the target dentry  (NOT NULL)
- * @new_dir: directory the new link will be created in  (NOT NULL)
- * @new_dentry: the link being created  (NOT NULL)
- *
- * Handle the permission test for a link & target pair.  Permission
- * is encoded as a pair where the link permission is determined
- * first, and if allowed, the target is tested.  The target test
- * is done from the point of the link match (not start of DFA)
- * making the target permission dependent on the link permission match.
- *
- * The subset test if required forces that permissions granted
- * on link are a subset of the permission granted to target.
- *
- * Returns: %0 if allowed else error
- */
-int aa_path_link(struct aa_profile *profile, struct dentry *old_dentry,
-		 struct path *new_dir, struct dentry *new_dentry)
-{
-	struct path link = { new_dir->mnt, new_dentry };
-	struct path target = { new_dir->mnt, old_dentry };
-	struct path_cond cond = {
-		d_backing_inode(old_dentry)->i_uid,
-		d_backing_inode(old_dentry)->i_mode
-	};
-	char *buffer = NULL, *buffer2 = NULL;
-	const char *lname, *tname = NULL, *info = NULL;
-	struct file_perms lperms, perms;
+static int profile_path_link(struct aa_profile *profile,
+			     const struct path *link, char *buffer,
+			     const struct path *target, char *buffer2,
+			     struct path_cond *cond)
+{
+	const char *lname, *tname = NULL;
+	struct aa_perms lperms, perms;
+	const char *info = NULL;
 	u32 request = AA_MAY_LINK;
 	unsigned int state;
 	int error;
 
-	lperms = nullperms;
-
-	/* buffer freed below, lname is pointer in buffer */
-	error = aa_path_name(&link, profile->path_flags, &buffer, &lname,
-			     &info);
+	error = path_name(OP_LINK, &profile->label, link, profile->path_flags,
+			  buffer, &lname, cond, AA_MAY_LINK);
 	if (error)
 		goto audit;
 
 	/* buffer2 freed below, tname is pointer in buffer2 */
-	error = aa_path_name(&target, profile->path_flags, &buffer2, &tname,
-			     &info);
+	error = path_name(OP_LINK, &profile->label, target, profile->path_flags,
+			  buffer2, &tname, cond, AA_MAY_LINK);
 	if (error)
 		goto audit;
 
 	error = -EACCES;
 	/* aa_str_perms - handles the case of the dfa being NULL */
 	state = aa_str_perms(profile->file.dfa, profile->file.start, lname,
-			     &cond, &lperms);
+			     cond, &lperms);
 
 	if (!(lperms.allow & AA_MAY_LINK))
 		goto audit;
 
 	/* test to see if target can be paired with link */
 	state = aa_dfa_null_transition(profile->file.dfa, state);
-	aa_str_perms(profile->file.dfa, state, tname, &cond, &perms);
+	aa_str_perms(profile->file.dfa, state, tname, cond, &perms);
 
 	/* force audit/quiet masks for link are stored in the second entry
 	 * in the link pair.
@@ -396,6 +412,7 @@ int aa_path_link(struct aa_profile *prof
 
 	if (!(perms.allow & AA_MAY_LINK)) {
 		info = "target restricted";
+		lperms = perms;
 		goto audit;
 	}
 
@@ -403,10 +420,10 @@ int aa_path_link(struct aa_profile *prof
 	if (!(perms.allow & AA_LINK_SUBSET))
 		goto done_tests;
 
-	/* Do link perm subset test requiring allowed permission on link are a
-	 * subset of the allowed permissions on target.
+	/* Do link perm subset test requiring allowed permission on link are
+	 * a subset of the allowed permissions on target.
 	 */
-	aa_str_perms(profile->file.dfa, profile->file.start, tname, &cond,
+	aa_str_perms(profile->file.dfa, profile->file.start, tname, cond,
 		     &perms);
 
 	/* AA_MAY_LINK is not considered in the subset test */
@@ -428,10 +445,140 @@ done_tests:
 	error = 0;
 
 audit:
-	error = aa_audit_file(profile, &lperms, GFP_KERNEL, OP_LINK, request,
-			      lname, tname, cond.uid, info, error);
-	kfree(buffer);
-	kfree(buffer2);
+	return aa_audit_file(profile, &lperms, OP_LINK, request, lname, tname,
+			     NULL, cond->uid, info, error);
+}
+
+/**
+ * aa_path_link - Handle hard link permission check
+ * @label: the label being enforced  (NOT NULL)
+ * @old_dentry: the target dentry  (NOT NULL)
+ * @new_dir: directory the new link will be created in  (NOT NULL)
+ * @new_dentry: the link being created  (NOT NULL)
+ *
+ * Handle the permission test for a link & target pair.  Permission
+ * is encoded as a pair where the link permission is determined
+ * first, and if allowed, the target is tested.  The target test
+ * is done from the point of the link match (not start of DFA)
+ * making the target permission dependent on the link permission match.
+ *
+ * The subset test if required forces that permissions granted
+ * on link are a subset of the permission granted to target.
+ *
+ * Returns: %0 if allowed else error
+ */
+int aa_path_link(struct aa_label *label, struct dentry *old_dentry,
+		 const struct path *new_dir, struct dentry *new_dentry)
+{
+	struct path link = { new_dir->mnt, new_dentry };
+	struct path target = { new_dir->mnt, old_dentry };
+	struct path_cond cond = {
+		d_backing_inode(old_dentry)->i_uid,
+		d_backing_inode(old_dentry)->i_mode
+	};
+	char *buffer = NULL, *buffer2 = NULL;
+	struct aa_profile *profile;
+	int error;
+
+	/* buffer freed below, lname is pointer in buffer */
+	get_buffers(buffer, buffer2);
+	error = fn_for_each_confined(label, profile,
+			profile_path_link(profile, &link, buffer, &target,
+					  buffer2, &cond));
+	put_buffers(buffer, buffer2);
+
+	return error;
+}
+
+static void update_file_ctx(struct aa_file_ctx *fctx, struct aa_label *label,
+			    u32 request)
+{
+	struct aa_label *l, *old;
+
+	/* update caching of label on file_ctx */
+	spin_lock(&fctx->lock);
+	old = rcu_dereference_protected(fctx->label,
+					spin_is_locked(&fctx->lock));
+	l = aa_label_merge(old, label, GFP_ATOMIC);
+	if (l) {
+		if (l != old) {
+			rcu_assign_pointer(fctx->label, l);
+			aa_put_label(old);
+		} else
+			aa_put_label(l);
+		fctx->allow |= request;
+	}
+	spin_unlock(&fctx->lock);
+}
+
+static int __file_path_perm(const char *op, struct aa_label *label,
+			    struct aa_label *flabel, struct file *file,
+			    u32 request, u32 denied)
+{
+	struct aa_profile *profile;
+	struct aa_perms perms = {};
+	struct path_cond cond = {
+		.uid = file_inode(file)->i_uid,
+		.mode = file_inode(file)->i_mode
+	};
+	char *buffer;
+	int flags, error;
+
+	/* revalidation due to label out of date. No revocation at this time */
+	if (!denied && aa_label_is_subset(flabel, label))
+		/* TODO: check for revocation on stale profiles */
+		return 0;
+
+	flags = PATH_DELEGATE_DELETED | (S_ISDIR(cond.mode) ? PATH_IS_DIR : 0);
+	get_buffers(buffer);
+
+	/* check every profile in task label not in current cache */
+	error = fn_for_each_not_in_set(flabel, label, profile,
+			profile_path_perm(op, profile, &file->f_path, buffer,
+					  request, &cond, flags, &perms));
+	if (denied) {
+		/* check every profile in file label that was not tested
+		 * in the initial check above.
+		 */
+		/* TODO: cache full perms so this only happens because of
+		 * conditionals */
+		/* TODO: don't audit here */
+		last_error(error,
+			fn_for_each_not_in_set(label, flabel, profile,
+				profile_path_perm(op, profile, &file->f_path,
+						  buffer, request, &cond, flags,
+						  &perms)));
+	}
+	if (!error)
+		update_file_ctx(file_ctx(file), label, request);
+
+	put_buffers(buffer);
+
+	return error;
+}
+
+static int __file_sock_perm(const char *op, struct aa_label *label,
+			    struct aa_label *flabel, struct file *file,
+			    u32 request, u32 denied)
+{
+	struct socket *sock = (struct socket *) file->private_data;
+	int error;
+
+	AA_BUG(!sock);
+
+	/* revalidation due to label out of date. No revocation at this time */
+	if (!denied && aa_label_is_subset(flabel, label))
+		return 0;
+
+	/* TODO: improve to skip profiles cached in flabel */
+	error = aa_sock_file_perm(label, op, request, sock);
+	if (denied) {
+		/* TODO: improve to skip profiles checked above */
+		/* check every profile in file label to is cached */
+		last_error(error, aa_sock_file_perm(flabel, op, request, sock));
+	}
+	if (!error)
+		update_file_ctx(file_ctx(file), label, request);
 
 	return error;
 }
@@ -439,20 +586,117 @@ audit:
 /**
  * aa_file_perm - do permission revalidation check & audit for @file
  * @op: operation being checked
- * @profile: profile being enforced   (NOT NULL)
+ * @label: label being enforced   (NOT NULL)
  * @file: file to revalidate access permissions on  (NOT NULL)
  * @request: requested permissions
  *
  * Returns: %0 if access allowed else error
  */
-int aa_file_perm(int op, struct aa_profile *profile, struct file *file,
+int aa_file_perm(const char *op, struct aa_label *label, struct file *file,
 		 u32 request)
 {
-	struct path_cond cond = {
-		.uid = file_inode(file)->i_uid,
-		.mode = file_inode(file)->i_mode
-	};
+	struct aa_file_ctx *fctx;
+	struct aa_label *flabel;
+	u32 denied;
+	int error = 0;
+
+	AA_BUG(!label);
+	AA_BUG(!file);
+
+	fctx = file_ctx(file);
+
+	rcu_read_lock();
+	flabel  = rcu_dereference(fctx->label);
+	AA_BUG(!flabel);
+
+	/* revalidate access, if task is unconfined, or the cached cred
+	 * doesn't match or if the request is for more permissions than
+	 * was granted.
+	 *
+	 * Note: the test for !unconfined(flabel) is to handle file
+	 *       delegation from unconfined tasks
+	 */
+	denied = request & ~fctx->allow;
+	if (unconfined(label) || unconfined(flabel) ||
+	    (!denied && aa_label_is_subset(flabel, label)))
+		goto done;
+
+	/* TODO: label cross check */
+
+	if (file->f_path.mnt && path_mediated_fs(file->f_path.dentry)) {
+		error = __file_path_perm(op, label, flabel, file, request,
+					 denied);
+
+	} else if (S_ISSOCK(file_inode(file)->i_mode)) {
+		error = __file_sock_perm(op, label, flabel, file, request,
+					 denied);
+	}
+done:
+	rcu_read_unlock();
+
+	return error;
+}
+
+static void revalidate_tty(struct aa_label *label)
+{
+	struct tty_struct *tty;
+	int drop_tty = 0;
+
+	tty = get_current_tty();
+	if (!tty)
+		return;
+
+	spin_lock(&tty_files_lock);
+	if (!list_empty(&tty->tty_files)) {
+		struct tty_file_private *file_priv;
+		struct file *file;
+		/* TODO: Revalidate access to controlling tty. */
+		file_priv = list_first_entry(&tty->tty_files,
+					     struct tty_file_private, list);
+		file = file_priv->file;
 
-	return aa_path_perm(op, profile, &file->f_path, PATH_DELEGATE_DELETED,
-			    request, &cond);
+		if (aa_file_perm(OP_INHERIT, label, file, MAY_READ | MAY_WRITE))
+			drop_tty = 1;
+	}
+	spin_unlock(&tty_files_lock);
+	tty_kref_put(tty);
+
+	if (drop_tty)
+		no_tty();
+}
+
+static int match_file(const void *p, struct file *file, unsigned fd)
+{
+	struct aa_label *label = (struct aa_label *)p;
+	if (aa_file_perm(OP_INHERIT, label, file, aa_map_file_to_perms(file)))
+		return fd + 1;
+	return 0;
+}
+
+
+/* based on selinux's flush_unauthorized_files */
+void aa_inherit_files(const struct cred *cred, struct files_struct *files)
+{
+	struct aa_label *label = aa_get_newest_cred_label(cred);
+	struct file *devnull = NULL;
+	unsigned n;
+
+	revalidate_tty(label);
+
+	/* Revalidate access to inherited open files. */
+	n = iterate_fd(files, 0, match_file, label);
+	if (!n) /* none found? */
+		goto out;
+
+	devnull = dentry_open(&aa_null, O_RDWR, cred);
+	if (IS_ERR(devnull))
+		devnull = NULL;
+	/* replace all the matching ones with this */
+	do {
+		replace_fd(n - 1, devnull, 0);
+	} while ((n = iterate_fd(files, n, match_file, label)) != 0);
+	if (devnull)
+		fput(devnull);
+out:
+	aa_put_label(label);
 }
--- /dev/null
+++ zfcpdump-kernel-4.4/security/apparmor/include/af_unix.h
@@ -0,0 +1,114 @@
+/*
+ * AppArmor security module
+ *
+ * This file contains AppArmor af_unix fine grained mediation
+ *
+ * Copyright 2014 Canonical Ltd.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2 of the
+ * License.
+ */
+#ifndef __AA_AF_UNIX_H
+
+#include <net/af_unix.h>
+
+#include "label.h"
+//#include "include/net.h"
+
+#define unix_addr_len(L) ((L) - sizeof(sa_family_t))
+#define unix_abstract_name_len(L) (unix_addr_len(L) - 1)
+#define unix_abstract_len(U) (unix_abstract_name_len((U)->addr->len))
+#define addr_unix_abstract_name(B) ((B)[0] == 0)
+#define addr_unix_anonymous(U) (addr_unix_len(U) <= 0)
+#define addr_unix_abstract(U) (!addr_unix_anonymous(U) && addr_unix_abstract_name((U)->addr))
+//#define unix_addr_fs(U) (!unix_addr_anonymous(U) && !unix_addr_abstract_name((U)->addr))
+
+#define unix_addr(A) ((struct sockaddr_un *)(A))
+#define unix_addr_anon(A, L) ((A) && unix_addr_len(L) <= 0)
+#define unix_addr_fs(A, L) (!unix_addr_anon(A, L) && !addr_unix_abstract_name(unix_addr(A)->sun_path))
+
+#define UNIX_ANONYMOUS(U) (!unix_sk(U)->addr)
+/* from net/unix/af_unix.c */
+#define UNIX_ABSTRACT(U) (!UNIX_ANONYMOUS(U) &&				\
+			  unix_sk(U)->addr->hash < UNIX_HASH_SIZE)
+#define UNIX_FS(U) (!UNIX_ANONYMOUS(U) && unix_sk(U)->addr->name->sun_path[0])
+#define unix_peer(sk) (unix_sk(sk)->peer)
+#define unix_connected(S) ((S)->state == SS_CONNECTED)
+
+static inline void print_unix_addr(struct sockaddr_un *A, int L)
+{
+	char *buf = (A) ? (char *) &(A)->sun_path : NULL;
+	int len = unix_addr_len(L);
+	if (!buf || len <= 0)
+		printk(" <anonymous>");
+	else if (buf[0])
+		printk(" %s", buf);
+	else
+		/* abstract name len includes leading \0 */
+		printk(" %d @%.*s", len - 1, len - 1, buf+1);
+};
+
+/*
+	printk("%s: %s: f %d, t %d, p %d", __FUNCTION__,		\
+	       #SK ,							\
+*/
+#define print_unix_sk(SK)						\
+do {									\
+	struct unix_sock *u = unix_sk(SK);				\
+	printk("%s: f %d, t %d, p %d",	#SK ,				\
+	       (SK)->sk_family, (SK)->sk_type, (SK)->sk_protocol);	\
+	if (u->addr)							\
+		print_unix_addr(u->addr->name, u->addr->len);		\
+	else								\
+		print_unix_addr(NULL, sizeof(sa_family_t));		\
+	/* printk("\n");*/						\
+} while (0)
+
+#define print_sk(SK)							\
+do {									\
+	if (!(SK)) {							\
+		printk("%s: %s is null\n", __FUNCTION__, #SK);		\
+	} else if ((SK)->sk_family == PF_UNIX) {			\
+		print_unix_sk(SK);					\
+		printk("\n");						\
+	} else {							\
+		printk("%s: %s: family %d\n", __FUNCTION__, #SK ,	\
+		       (SK)->sk_family);				\
+	}								\
+} while (0)
+
+#define print_sock_addr(U) \
+do {			       \
+	printk("%s:\n", __FUNCTION__);					\
+	printk("    sock %s:", sock_ctx && sock_ctx->label ? aa_label_printk(sock_ctx->label, GFP_ATOMIC); : "<null>"); print_sk(sock); \
+	printk("    other %s:", other_ctx && other_ctx->label ? aa_label_printk(other_ctx->label, GFP_ATOMIC); : "<null>"); print_sk(other); \
+	printk("    new %s", new_ctx && new_ctx->label ? aa_label_printk(new_ctx->label, GFP_ATOMIC); : "<null>"); print_sk(newsk); \
+} while (0)
+
+
+
+
+int aa_unix_peer_perm(struct aa_label *label, const char *op, u32 request,
+		      struct sock *sk, struct sock *peer_sk,
+		      struct aa_label *peer_label);
+int aa_unix_label_sk_perm(struct aa_label *label, const char *op, u32 request,
+			  struct sock *sk);
+int aa_unix_sock_perm(const char *op, u32 request, struct socket *sock);
+int aa_unix_create_perm(struct aa_label *label, int family, int type,
+			int protocol);
+int aa_unix_bind_perm(struct socket *sock, struct sockaddr *address,
+		      int addrlen);
+int aa_unix_connect_perm(struct socket *sock, struct sockaddr *address,
+			 int addrlen);
+int aa_unix_listen_perm(struct socket *sock, int backlog);
+int aa_unix_accept_perm(struct socket *sock, struct socket *newsock);
+int aa_unix_msg_perm(const char *op, u32 request, struct socket *sock,
+		     struct msghdr *msg, int size);
+int aa_unix_opt_perm(const char *op, u32 request, struct socket *sock, int level,
+		     int optname);
+int aa_unix_file_perm(struct aa_label *label, const char *op, u32 request,
+		      struct socket *sock);
+
+#endif /* __AA_AF_UNIX_H */
--- zfcpdump-kernel-4.4.orig/security/apparmor/include/apparmor.h
+++ zfcpdump-kernel-4.4/security/apparmor/include/apparmor.h
@@ -1,10 +1,10 @@
 /*
  * AppArmor security module
  *
- * This file contains AppArmor basic global and lib definitions
+ * This file contains AppArmor basic global
  *
  * Copyright (C) 1998-2008 Novell/SUSE
- * Copyright 2009-2010 Canonical Ltd.
+ * Copyright 2009-2016 Canonical Ltd.
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -15,10 +15,9 @@
 #ifndef __APPARMOR_H
 #define __APPARMOR_H
 
-#include <linux/slab.h>
-#include <linux/fs.h>
+#include <linux/types.h>
 
-#include "match.h"
+#include "backport.h"
 
 /*
  * Class of mediation types in the AppArmor policy db
@@ -30,91 +29,22 @@
 #define AA_CLASS_NET		4
 #define AA_CLASS_RLIMITS	5
 #define AA_CLASS_DOMAIN		6
+#define AA_CLASS_MOUNT		7
+#define AA_CLASS_PTRACE		9
+#define AA_CLASS_SIGNAL		10
+#define AA_CLASS_LABEL		16
 
-#define AA_CLASS_LAST		AA_CLASS_DOMAIN
+#define AA_CLASS_LAST		AA_CLASS_LABEL
 
 /* Control parameters settable through module/boot flags */
 extern enum audit_mode aa_g_audit;
 extern bool aa_g_audit_header;
 extern bool aa_g_debug;
+extern bool aa_g_hash_policy;
 extern bool aa_g_lock_policy;
 extern bool aa_g_logsyscall;
 extern bool aa_g_paranoid_load;
 extern unsigned int aa_g_path_max;
-
-/*
- * DEBUG remains global (no per profile flag) since it is mostly used in sysctl
- * which is not related to profile accesses.
- */
-
-#define AA_DEBUG(fmt, args...)						\
-	do {								\
-		if (aa_g_debug && printk_ratelimit())			\
-			printk(KERN_DEBUG "AppArmor: " fmt, ##args);	\
-	} while (0)
-
-#define AA_ERROR(fmt, args...)						\
-	do {								\
-		if (printk_ratelimit())					\
-			printk(KERN_ERR "AppArmor: " fmt, ##args);	\
-	} while (0)
-
-/* Flag indicating whether initialization completed */
-extern int apparmor_initialized __initdata;
-
-/* fn's in lib */
-char *aa_split_fqname(char *args, char **ns_name);
-void aa_info_message(const char *str);
-void *__aa_kvmalloc(size_t size, gfp_t flags);
-
-static inline void *kvmalloc(size_t size)
-{
-	return __aa_kvmalloc(size, 0);
-}
-
-static inline void *kvzalloc(size_t size)
-{
-	return __aa_kvmalloc(size, __GFP_ZERO);
-}
-
-/* returns 0 if kref not incremented */
-static inline int kref_get_not0(struct kref *kref)
-{
-	return atomic_inc_not_zero(&kref->refcount);
-}
-
-/**
- * aa_strneq - compare null terminated @str to a non null terminated substring
- * @str: a null terminated string
- * @sub: a substring, not necessarily null terminated
- * @len: length of @sub to compare
- *
- * The @str string must be full consumed for this to be considered a match
- */
-static inline bool aa_strneq(const char *str, const char *sub, int len)
-{
-	return !strncmp(str, sub, len) && !str[len];
-}
-
-/**
- * aa_dfa_null_transition - step to next state after null character
- * @dfa: the dfa to match against
- * @start: the state of the dfa to start matching in
- *
- * aa_dfa_null_transition transitions to the next state after a null
- * character which is not used in standard matching and is only
- * used to separate pairs.
- */
-static inline unsigned int aa_dfa_null_transition(struct aa_dfa *dfa,
-						  unsigned int start)
-{
-	/* the null transition only needs the string's null terminator byte */
-	return aa_dfa_next(dfa, start, 0);
-}
-
-static inline bool mediated_filesystem(struct dentry *dentry)
-{
-	return !(dentry->d_sb->s_flags & MS_NOUSER);
-}
+extern bool aa_g_unconfined_init;
 
 #endif /* __APPARMOR_H */
--- zfcpdump-kernel-4.4.orig/security/apparmor/include/apparmorfs.h
+++ zfcpdump-kernel-4.4/security/apparmor/include/apparmorfs.h
@@ -15,6 +15,8 @@
 #ifndef __AA_APPARMORFS_H
 #define __AA_APPARMORFS_H
 
+extern struct path aa_null;
+
 enum aa_fs_type {
 	AA_FS_TYPE_BOOLEAN,
 	AA_FS_TYPE_STRING,
@@ -62,12 +64,16 @@ extern const struct file_operations aa_f
 extern void __init aa_destroy_aafs(void);
 
 struct aa_profile;
-struct aa_namespace;
+struct aa_ns;
 
 enum aafs_ns_type {
 	AAFS_NS_DIR,
 	AAFS_NS_PROFS,
 	AAFS_NS_NS,
+	AAFS_NS_RAW_DATA,
+	AAFS_NS_LOAD,
+	AAFS_NS_REPLACE,
+	AAFS_NS_REMOVE,
 	AAFS_NS_COUNT,
 	AAFS_NS_MAX_COUNT,
 	AAFS_NS_SIZE,
@@ -83,12 +89,19 @@ enum aafs_prof_type {
 	AAFS_PROF_MODE,
 	AAFS_PROF_ATTACH,
 	AAFS_PROF_HASH,
+	AAFS_PROF_RAW_DATA,
+	AAFS_PROF_RAW_HASH,
+	AAFS_PROF_RAW_ABI,
 	AAFS_PROF_SIZEOF,
 };
 
 #define ns_dir(X) ((X)->dents[AAFS_NS_DIR])
 #define ns_subns_dir(X) ((X)->dents[AAFS_NS_NS])
 #define ns_subprofs_dir(X) ((X)->dents[AAFS_NS_PROFS])
+#define ns_subdata_dir(X) ((X)->dents[AAFS_NS_RAW_DATA])
+#define ns_subload(X) ((X)->dents[AAFS_NS_LOAD])
+#define ns_subreplace(X) ((X)->dents[AAFS_NS_REPLACE])
+#define ns_subremove(X) ((X)->dents[AAFS_NS_REMOVE])
 
 #define prof_dir(X) ((X)->dents[AAFS_PROF_DIR])
 #define prof_child_dir(X) ((X)->dents[AAFS_PROF_PROFS])
@@ -97,8 +110,8 @@ void __aa_fs_profile_rmdir(struct aa_pro
 void __aa_fs_profile_migrate_dents(struct aa_profile *old,
 				   struct aa_profile *new);
 int __aa_fs_profile_mkdir(struct aa_profile *profile, struct dentry *parent);
-void __aa_fs_namespace_rmdir(struct aa_namespace *ns);
-int __aa_fs_namespace_mkdir(struct aa_namespace *ns, struct dentry *parent,
-			    const char *name);
+void __aa_fs_ns_rmdir(struct aa_ns *ns);
+int __aa_fs_ns_mkdir(struct aa_ns *ns, struct dentry *parent, const char *name,
+		     struct dentry *dent);
 
 #endif /* __AA_APPARMORFS_H */
--- zfcpdump-kernel-4.4.orig/security/apparmor/include/audit.h
+++ zfcpdump-kernel-4.4/security/apparmor/include/audit.h
@@ -22,8 +22,7 @@
 #include <linux/slab.h>
 
 #include "file.h"
-
-struct aa_profile;
+#include "label.h"
 
 extern const char *const audit_mode_names[];
 #define AUDIT_MAX_INDEX 5
@@ -46,97 +45,140 @@ enum audit_type {
 	AUDIT_APPARMOR_AUTO
 };
 
-extern const char *const op_table[];
-enum aa_ops {
-	OP_NULL,
-
-	OP_SYSCTL,
-	OP_CAPABLE,
-
-	OP_UNLINK,
-	OP_MKDIR,
-	OP_RMDIR,
-	OP_MKNOD,
-	OP_TRUNC,
-	OP_LINK,
-	OP_SYMLINK,
-	OP_RENAME_SRC,
-	OP_RENAME_DEST,
-	OP_CHMOD,
-	OP_CHOWN,
-	OP_GETATTR,
-	OP_OPEN,
-
-	OP_FPERM,
-	OP_FLOCK,
-	OP_FMMAP,
-	OP_FMPROT,
-
-	OP_CREATE,
-	OP_POST_CREATE,
-	OP_BIND,
-	OP_CONNECT,
-	OP_LISTEN,
-	OP_ACCEPT,
-	OP_SENDMSG,
-	OP_RECVMSG,
-	OP_GETSOCKNAME,
-	OP_GETPEERNAME,
-	OP_GETSOCKOPT,
-	OP_SETSOCKOPT,
-	OP_SOCK_SHUTDOWN,
-
-	OP_PTRACE,
-
-	OP_EXEC,
-	OP_CHANGE_HAT,
-	OP_CHANGE_PROFILE,
-	OP_CHANGE_ONEXEC,
-
-	OP_SETPROCATTR,
-	OP_SETRLIMIT,
-
-	OP_PROF_REPL,
-	OP_PROF_LOAD,
-	OP_PROF_RM,
-};
+#define OP_NULL NULL
+
+#define OP_SYSCTL "sysctl"
+#define OP_CAPABLE "capable"
+
+#define OP_UNLINK "unlink"
+#define OP_MKDIR "mkdir"
+#define OP_RMDIR "rmdir"
+#define OP_MKNOD "mknod"
+#define OP_TRUNC "truncate"
+#define OP_LINK "link"
+#define OP_SYMLINK "symlink"
+#define OP_RENAME_SRC "rename_src"
+#define OP_RENAME_DEST "rename_dest"
+#define OP_CHMOD "chmod"
+#define OP_CHOWN "chown"
+#define OP_GETATTR "getattr"
+#define OP_OPEN "open"
+
+#define OP_FRECEIVE "file_receive"
+#define OP_FPERM "file_perm"
+#define OP_FLOCK "file_lock"
+#define OP_FMMAP "file_mmap"
+#define OP_FMPROT "file_mprotect"
+#define OP_INHERIT "file_inherit"
+
+#define OP_PIVOTROOT "pivotroot"
+#define OP_MOUNT "mount"
+#define OP_UMOUNT "umount"
+
+#define OP_CREATE "create"
+#define OP_POST_CREATE "post_create"
+#define OP_BIND "bind"
+#define OP_CONNECT "connect"
+#define OP_LISTEN "listen"
+#define OP_ACCEPT "accept"
+#define OP_SENDMSG "sendmsg"
+#define OP_RECVMSG "recvmsg"
+#define OP_GETSOCKNAME "getsockname"
+#define OP_GETPEERNAME "getpeername"
+#define OP_GETSOCKOPT "getsockopt"
+#define OP_SETSOCKOPT "setsockopt"
+#define OP_SHUTDOWN "socket_shutdown"
+
+#define OP_PTRACE "ptrace"
+#define OP_SIGNAL "signal"
+
+#define OP_EXEC "exec"
+
+#define OP_CHANGE_HAT "change_hat"
+#define OP_CHANGE_PROFILE "change_profile"
+#define OP_CHANGE_ONEXEC "change_onexec"
+#define OP_STACK "stack"
+#define OP_STACK_ONEXEC "stack_onexec"
+
+#define OP_SETPROCATTR "setprocattr"
+#define OP_SETRLIMIT "setrlimit"
+
+#define OP_PROF_REPL "profile_replace"
+#define OP_PROF_LOAD "profile_load"
+#define OP_PROF_RM "profile_remove"
 
 
 struct apparmor_audit_data {
 	int error;
-	int op;
 	int type;
-	void *profile;
+	const char *op;
+	struct aa_label *label;
 	const char *name;
 	const char *info;
+	u32 request;
+	u32 denied;
 	union {
-		void *target;
+		/* these entries require a custom callback fn */
 		struct {
+			struct aa_label *peer;
+			union {
+				struct {
+					kuid_t ouid;
+					const char *target;
+				} fs;
+				struct {
+					int type, protocol;
+					struct sock *peer_sk;
+					void *addr;
+					int addrlen;
+				} net;
+				int signal;
+			};
+		};
+		struct {
+			struct aa_profile *profile;
+			const char *ns;
 			long pos;
-			void *target;
 		} iface;
 		struct {
 			int rlim;
 			unsigned long max;
 		} rlim;
 		struct {
-			const char *target;
-			u32 request;
-			u32 denied;
-			kuid_t ouid;
-		} fs;
+			const char *src_name;
+			const char *type;
+			const char *trans;
+			const char *data;
+			unsigned long flags;
+		} mnt;
 	};
 };
 
-/* define a short hand for apparmor_audit_data structure */
-#define aad apparmor_audit_data
+/* macros for dealing with  apparmor_audit_data structure */
+#define aad(SA) (SA)->apparmor_audit_data
+#define DEFINE_AUDIT_DATA(NAME, T, X)					\
+	/* TODO: cleanup audit init so we don't need _aad = {0,} */	\
+	struct apparmor_audit_data NAME ## _aad = { .op = (X), };	\
+	struct common_audit_data NAME =					\
+	{								\
+	.type = (T),							\
+	.u.tsk = NULL,							\
+	};								\
+	NAME.apparmor_audit_data = &(NAME ## _aad)
 
 void aa_audit_msg(int type, struct common_audit_data *sa,
 		  void (*cb) (struct audit_buffer *, void *));
-int aa_audit(int type, struct aa_profile *profile, gfp_t gfp,
-	     struct common_audit_data *sa,
+int aa_audit(int type, struct aa_profile *profile, struct common_audit_data *sa,
 	     void (*cb) (struct audit_buffer *, void *));
 
+#define aa_audit_error(ERROR, SA, CB)				\
+({								\
+	aad((SA))->error = (ERROR);				\
+	aa_audit_msg(AUDIT_APPARMOR_ERROR, (SA), (CB));		\
+	aad((SA))->error;					\
+})
+
+
 static inline int complain_error(int error)
 {
 	if (error == -EPERM || error == -EACCES)
--- /dev/null
+++ zfcpdump-kernel-4.4/security/apparmor/include/backport.h
@@ -0,0 +1,20 @@
+/*
+ * AppArmor security module
+ *
+ * This file contains AppArmor file mediation function definitions.
+ *
+ * Copyright 2014 Canonical Ltd.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2 of the
+ * License.
+ *
+ *
+ * This is a file of helper macros, defines for backporting newer versions
+ * of apparmor to older kernels
+ */
+#ifndef __AA_BACKPORT_H
+#define __AA_BACKPORT_H
+
+#endif /* __AA_BACKPORT_H */
--- zfcpdump-kernel-4.4.orig/security/apparmor/include/capability.h
+++ zfcpdump-kernel-4.4/security/apparmor/include/capability.h
@@ -19,11 +19,12 @@
 
 #include "apparmorfs.h"
 
-struct aa_profile;
+struct aa_label;
 
 /* aa_caps - confinement data for capabilities
  * @allowed: capabilities mask
  * @audit: caps that are to be audited
+ * @denied: caps that are explicitly denied
  * @quiet: caps that should not be audited
  * @kill: caps that when requested will result in the task being killed
  * @extended: caps that are subject finer grained mediation
@@ -31,6 +32,7 @@ struct aa_profile;
 struct aa_caps {
 	kernel_cap_t allow;
 	kernel_cap_t audit;
+	kernel_cap_t denied;
 	kernel_cap_t quiet;
 	kernel_cap_t kill;
 	kernel_cap_t extended;
@@ -38,7 +40,7 @@ struct aa_caps {
 
 extern struct aa_fs_entry aa_fs_entry_caps[];
 
-int aa_capable(struct aa_profile *profile, int cap, int audit);
+int aa_capable(struct aa_label *label, int cap, int audit);
 
 static inline void aa_free_cap_rules(struct aa_caps *caps)
 {
--- zfcpdump-kernel-4.4.orig/security/apparmor/include/context.h
+++ zfcpdump-kernel-4.4/security/apparmor/include/context.h
@@ -19,99 +19,79 @@
 #include <linux/slab.h>
 #include <linux/sched.h>
 
-#include "policy.h"
+#include "label.h"
+#include "policy_ns.h"
 
-#define cred_cxt(X) (X)->security
-#define current_cxt() cred_cxt(current_cred())
-
-/* struct aa_file_cxt - the AppArmor context the file was opened in
- * @perms: the permission the file was opened with
- *
- * The file_cxt could currently be directly stored in file->f_security
- * as the profile reference is now stored in the f_cred.  However the
- * cxt struct will expand in the future so we keep the struct.
- */
-struct aa_file_cxt {
-	u16 allow;
-};
+#define cred_ctx(X) (X)->security
+#define current_ctx() cred_ctx(current_cred())
 
 /**
- * aa_alloc_file_context - allocate file_cxt
- * @gfp: gfp flags for allocation
+ * struct aa_task_ctx - primary label for confined tasks
+ * @label: the current label   (NOT NULL)
+ * @exec: label to transition to on next exec  (MAYBE NULL)
+ * @previous: label the task may return to     (MAYBE NULL)
+ * @token: magic value the task must know for returning to @previous
  *
- * Returns: file_cxt or NULL on failure
- */
-static inline struct aa_file_cxt *aa_alloc_file_context(gfp_t gfp)
-{
-	return kzalloc(sizeof(struct aa_file_cxt), gfp);
-}
-
-/**
- * aa_free_file_context - free a file_cxt
- * @cxt: file_cxt to free  (MAYBE_NULL)
- */
-static inline void aa_free_file_context(struct aa_file_cxt *cxt)
-{
-	if (cxt)
-		kzfree(cxt);
-}
-
-/**
- * struct aa_task_cxt - primary label for confined tasks
- * @profile: the current profile   (NOT NULL)
- * @exec: profile to transition to on next exec  (MAYBE NULL)
- * @previous: profile the task may return to     (MAYBE NULL)
- * @token: magic value the task must know for returning to @previous_profile
- *
- * Contains the task's current profile (which could change due to
+ * Contains the task's current label (which could change due to
  * change_hat).  Plus the hat_magic needed during change_hat.
  *
  * TODO: make so a task can be confined by a stack of contexts
  */
-struct aa_task_cxt {
-	struct aa_profile *profile;
-	struct aa_profile *onexec;
-	struct aa_profile *previous;
+struct aa_task_ctx {
+	struct aa_label *label;
+	struct aa_label *onexec;
+	struct aa_label *previous;
 	u64 token;
 };
 
-struct aa_task_cxt *aa_alloc_task_context(gfp_t flags);
-void aa_free_task_context(struct aa_task_cxt *cxt);
-void aa_dup_task_context(struct aa_task_cxt *new,
-			 const struct aa_task_cxt *old);
-int aa_replace_current_profile(struct aa_profile *profile);
-int aa_set_current_onexec(struct aa_profile *profile);
-int aa_set_current_hat(struct aa_profile *profile, u64 token);
-int aa_restore_previous_profile(u64 cookie);
-struct aa_profile *aa_get_task_profile(struct task_struct *task);
+struct aa_task_ctx *aa_alloc_task_context(gfp_t flags);
+void aa_free_task_context(struct aa_task_ctx *ctx);
+void aa_dup_task_context(struct aa_task_ctx *new,
+			 const struct aa_task_ctx *old);
+int aa_replace_current_label(struct aa_label *label);
+int aa_set_current_onexec(struct aa_label *label, bool stack);
+int aa_set_current_hat(struct aa_label *label, u64 token);
+int aa_restore_previous_label(u64 cookie);
+struct aa_label *aa_get_task_label(struct task_struct *task);
 
 
 /**
- * aa_cred_profile - obtain cred's profiles
- * @cred: cred to obtain profiles from  (NOT NULL)
+ * aa_cred_raw_label - obtain cred's label
+ * @cred: cred to obtain label from  (NOT NULL)
  *
- * Returns: confining profile
+ * Returns: confining label
  *
  * does NOT increment reference count
  */
-static inline struct aa_profile *aa_cred_profile(const struct cred *cred)
+static inline struct aa_label *aa_cred_raw_label(const struct cred *cred)
+{
+	struct aa_task_ctx *ctx = cred_ctx(cred);
+	BUG_ON(!ctx || !ctx->label);
+	return ctx->label;
+}
+
+/**
+ * aa_get_newest_cred_label - obtain the newest version of the label on a cred
+ * @cred: cred to obtain label from (NOT NULL)
+ *
+ * Returns: newest version of confining label
+ */
+static inline struct aa_label *aa_get_newest_cred_label(const struct cred *cred)
 {
-	struct aa_task_cxt *cxt = cred_cxt(cred);
-	BUG_ON(!cxt || !cxt->profile);
-	return cxt->profile;
+	return aa_get_newest_label(aa_cred_raw_label(cred));
 }
 
 /**
- * __aa_task_profile - retrieve another task's profile
+ * __aa_task_raw_label - retrieve another task's label
  * @task: task to query  (NOT NULL)
  *
- * Returns: @task's profile without incrementing its ref count
+ * Returns: @task's label without incrementing its ref count
  *
  * If @task != current needs to be called in RCU safe critical section
  */
-static inline struct aa_profile *__aa_task_profile(struct task_struct *task)
+static inline struct aa_label *__aa_task_raw_label(struct task_struct *task)
 {
-	return aa_cred_profile(__task_cred(task));
+	return aa_cred_raw_label(__task_cred(task));
 }
 
 /**
@@ -122,57 +102,105 @@ static inline struct aa_profile *__aa_ta
  */
 static inline bool __aa_task_is_confined(struct task_struct *task)
 {
-	return !unconfined(__aa_task_profile(task));
+	return !unconfined(__aa_task_raw_label(task));
 }
 
 /**
- * __aa_current_profile - find the current tasks confining profile
+ * aa_current_raw_label - find the current tasks confining label
  *
- * Returns: up to date confining profile or the ns unconfined profile (NOT NULL)
+ * Returns: up to date confining label or the ns unconfined label (NOT NULL)
  *
  * This fn will not update the tasks cred to the most up to date version
- * of the profile so it is safe to call when inside of locks.
+ * of the label so it is safe to call when inside of locks.
  */
-static inline struct aa_profile *__aa_current_profile(void)
+static inline struct aa_label *aa_current_raw_label(void)
 {
-	return aa_cred_profile(current_cred());
+	return aa_cred_raw_label(current_cred());
 }
 
 /**
- * aa_current_profile - find the current tasks confining profile and do updates
+ * aa_get_current_label - get the newest version of the current tasks label
  *
- * Returns: up to date confining profile or the ns unconfined profile (NOT NULL)
+ * Returns: newest version of confining label (NOT NULL)
  *
- * This fn will update the tasks cred structure if the profile has been
- * replaced.  Not safe to call inside locks
+ * This fn will not update the tasks cred, so it is safe inside of locks
+ *
+ * The returned reference must be put with aa_put_label()
  */
-static inline struct aa_profile *aa_current_profile(void)
+static inline struct aa_label *aa_get_current_label(void)
 {
-	const struct aa_task_cxt *cxt = current_cxt();
-	struct aa_profile *profile;
-	BUG_ON(!cxt || !cxt->profile);
+	struct aa_label *l = aa_current_raw_label();
+
+	if (label_is_stale(l))
+		return aa_get_newest_label(l);
+	return aa_get_label(l);
+}
 
-	if (PROFILE_INVALID(cxt->profile)) {
-		profile = aa_get_newest_profile(cxt->profile);
-		aa_replace_current_profile(profile);
-		aa_put_profile(profile);
-		cxt = current_cxt();
+/**
+ * aa_end_current_label - put a reference found with aa_begin_current_label
+ * @label: label reference to put
+ *
+ * Should only be used with a reference obtained with aa_begin_current_label
+ * and never used in situations where the task cred may be updated
+ */
+static inline void aa_end_current_label(struct aa_label *label)
+{
+	if (label != aa_current_raw_label())
+		aa_put_label(label);
+}
+
+/**
+ * aa_begin_current_label - find the current tasks confining label and update it
+ * @update: whether the current label can be updated
+ *
+ * Returns: up to date confining label or the ns unconfined label (NOT NULL)
+ *
+ * If @update is true this fn will update the tasks cred structure if the
+ *   label has been replaced.  Not safe to call inside locks
+ * else
+ *   just return the up to date label
+ *
+ * The returned reference must be put with aa_end_current_label()
+ * This must NOT be used if the task cred could be updated within the
+ * critical section between aa_begin_current_label() .. aa_end_current_label()
+ */
+static inline struct aa_label *aa_begin_current_label(bool update)
+{
+	struct aa_label *label = aa_current_raw_label();
+
+	if (label_is_stale(label)) {
+		label = aa_get_newest_label(label);
+		if (update && aa_replace_current_label(label) == 0)
+			/* task cred will keep the reference */
+			aa_put_label(label);
 	}
 
-	return cxt->profile;
+	return label;
+}
+
+#define NO_UPDATE false
+#define DO_UPDATE true
+
+static inline struct aa_ns *aa_get_current_ns(void)
+{
+	struct aa_label *label = aa_begin_current_label(NO_UPDATE);
+	struct aa_ns *ns = aa_get_ns(labels_ns(label));
+	aa_end_current_label(label);
+
+	return ns;
 }
 
 /**
- * aa_clear_task_cxt_trans - clear transition tracking info from the cxt
- * @cxt: task context to clear (NOT NULL)
+ * aa_clear_task_ctx_trans - clear transition tracking info from the ctx
+ * @ctx: task context to clear (NOT NULL)
  */
-static inline void aa_clear_task_cxt_trans(struct aa_task_cxt *cxt)
+static inline void aa_clear_task_ctx_trans(struct aa_task_ctx *ctx)
 {
-	aa_put_profile(cxt->previous);
-	aa_put_profile(cxt->onexec);
-	cxt->previous = NULL;
-	cxt->onexec = NULL;
-	cxt->token = 0;
+	aa_put_label(ctx->previous);
+	aa_put_label(ctx->onexec);
+	ctx->previous = NULL;
+	ctx->onexec = NULL;
+	ctx->token = 0;
 }
 
 #endif /* __AA_CONTEXT_H */
--- zfcpdump-kernel-4.4.orig/security/apparmor/include/crypto.h
+++ zfcpdump-kernel-4.4/security/apparmor/include/crypto.h
@@ -18,9 +18,14 @@
 
 #ifdef CONFIG_SECURITY_APPARMOR_HASH
 unsigned int aa_hash_size(void);
+char *aa_calc_hash(void *data, size_t len);
 int aa_calc_profile_hash(struct aa_profile *profile, u32 version, void *start,
 			 size_t len);
 #else
+static inline char *aa_calc_hash(void *data, size_t len)
+{
+	return NULL;
+}
 static inline int aa_calc_profile_hash(struct aa_profile *profile, u32 version,
 				       void *start, size_t len)
 {
--- zfcpdump-kernel-4.4.orig/security/apparmor/include/domain.h
+++ zfcpdump-kernel-4.4/security/apparmor/include/domain.h
@@ -15,6 +15,8 @@
 #include <linux/binfmts.h>
 #include <linux/types.h>
 
+#include "label.h"
+
 #ifndef __AA_DOMAIN_H
 #define __AA_DOMAIN_H
 
@@ -23,6 +25,9 @@ struct aa_domain {
 	char **table;
 };
 
+struct aa_label *x_table_lookup(struct aa_profile *profile, u32 xindex,
+				const char **name);
+
 int apparmor_bprm_set_creds(struct linux_binprm *bprm);
 int apparmor_bprm_secureexec(struct linux_binprm *bprm);
 void apparmor_bprm_committing_creds(struct linux_binprm *bprm);
@@ -30,7 +35,7 @@ void apparmor_bprm_committed_creds(struc
 
 void aa_free_domain_entries(struct aa_domain *domain);
 int aa_change_hat(const char *hats[], int count, u64 token, bool permtest);
-int aa_change_profile(const char *ns_name, const char *name, bool onexec,
-		      bool permtest);
+int aa_change_profile(const char *fqname, bool onexec, bool permtest,
+		      bool stack);
 
 #endif /* __AA_DOMAIN_H */
--- zfcpdump-kernel-4.4.orig/security/apparmor/include/file.h
+++ zfcpdump-kernel-4.4/security/apparmor/include/file.h
@@ -15,38 +15,75 @@
 #ifndef __AA_FILE_H
 #define __AA_FILE_H
 
+#include <linux/spinlock.h>
+
 #include "domain.h"
 #include "match.h"
+#include "label.h"
+#include "perms.h"
 
 struct aa_profile;
 struct path;
 
-/*
- * We use MAY_EXEC, MAY_WRITE, MAY_READ, MAY_APPEND and the following flags
- * for profile permissions
- */
-#define AA_MAY_CREATE                  0x0010
-#define AA_MAY_DELETE                  0x0020
-#define AA_MAY_META_WRITE              0x0040
-#define AA_MAY_META_READ               0x0080
-
-#define AA_MAY_CHMOD                   0x0100
-#define AA_MAY_CHOWN                   0x0200
-#define AA_MAY_LOCK                    0x0400
-#define AA_EXEC_MMAP                   0x0800
-
-#define AA_MAY_LINK			0x1000
-#define AA_LINK_SUBSET			AA_MAY_LOCK	/* overlaid */
-#define AA_MAY_ONEXEC			0x40000000	/* exec allows onexec */
-#define AA_MAY_CHANGE_PROFILE		0x80000000
-#define AA_MAY_CHANGEHAT		0x80000000	/* ctrl auditing only */
+#define mask_mode_t(X) (X & (MAY_EXEC | MAY_WRITE | MAY_READ | MAY_APPEND))
 
 #define AA_AUDIT_FILE_MASK	(MAY_READ | MAY_WRITE | MAY_EXEC | MAY_APPEND |\
 				 AA_MAY_CREATE | AA_MAY_DELETE |	\
-				 AA_MAY_META_READ | AA_MAY_META_WRITE | \
+				 AA_MAY_GETATTR | AA_MAY_SETATTR | \
 				 AA_MAY_CHMOD | AA_MAY_CHOWN | AA_MAY_LOCK | \
 				 AA_EXEC_MMAP | AA_MAY_LINK)
 
+#define file_ctx(X) ((struct aa_file_ctx *)(X)->f_security)
+
+/* struct aa_file_ctx - the AppArmor context the file was opened in
+ * @lock: lock to update the ctx
+ * @label: label currently cached on the ctx
+ * @perms: the permission the file was opened with
+ */
+struct aa_file_ctx {
+	spinlock_t lock;
+	struct aa_label __rcu *label;
+	u32 allow;
+};
+
+/**
+ * aa_alloc_file_ctx - allocate file_ctx
+ * @label: initial label of task creating the file
+ * @gfp: gfp flags for allocation
+ *
+ * Returns: file_ctx or NULL on failure
+ */
+static inline struct aa_file_ctx *aa_alloc_file_ctx(struct aa_label *label, gfp_t gfp)
+{
+	struct aa_file_ctx *ctx;
+
+	ctx = kzalloc(sizeof(struct aa_file_ctx), gfp);
+	if (ctx) {
+		spin_lock_init(&ctx->lock);
+		rcu_assign_pointer(ctx->label, aa_get_label(label));
+	}
+	return ctx;
+}
+
+/**
+ * aa_free_file_ctx - free a file_ctx
+ * @ctx: file_ctx to free  (MAYBE_NULL)
+ */
+static inline void aa_free_file_ctx(struct aa_file_ctx *ctx)
+{
+	if (ctx) {
+		aa_put_label(rcu_access_pointer(ctx->label));
+		kzfree(ctx);
+	}
+}
+
+static inline struct aa_label *aa_get_file_label(struct aa_file_ctx *ctx)
+{
+	return aa_get_label_rcu(&ctx->label);
+}
+
+#define inode_ctx(X) (X)->i_security
+
 /*
  * The xindex is broken into 3 parts
  * - index - an index into either the exec name table or the variable table
@@ -75,25 +112,6 @@ struct path_cond {
 	umode_t mode;
 };
 
-/* struct file_perms - file permission
- * @allow: mask of permissions that are allowed
- * @audit: mask of permissions to force an audit message for
- * @quiet: mask of permissions to quiet audit messages for
- * @kill: mask of permissions that when matched will kill the task
- * @xindex: exec transition index if @allow contains MAY_EXEC
- *
- * The @audit and @queit mask should be mutually exclusive.
- */
-struct file_perms {
-	u32 allow;
-	u32 audit;
-	u32 quiet;
-	u32 kill;
-	u16 xindex;
-};
-
-extern struct file_perms nullperms;
-
 #define COMBINED_PERM_MASK(X) ((X).allow | (X).audit | (X).quiet | (X).kill)
 
 /* FIXME: split perms from dfa and match this to description
@@ -144,9 +162,9 @@ static inline u16 dfa_map_xindex(u16 mas
 #define dfa_other_xindex(dfa, state) \
 	dfa_map_xindex((ACCEPT_TABLE(dfa)[state] >> 14) & 0x3fff)
 
-int aa_audit_file(struct aa_profile *profile, struct file_perms *perms,
-		  gfp_t gfp, int op, u32 request, const char *name,
-		  const char *target, kuid_t ouid, const char *info, int error);
+int aa_audit_file(struct aa_profile *profile, struct aa_perms *perms,
+		  const char *op, u32 request, const char *name, const char *target, struct aa_label *tlabel,
+		  kuid_t ouid, const char *info, int error);
 
 /**
  * struct aa_file_rules - components used for file rule permissions
@@ -167,19 +185,27 @@ struct aa_file_rules {
 	/* TODO: add delegate table */
 };
 
+struct aa_perms aa_compute_fperms(struct aa_dfa *dfa, unsigned int state,
+				    struct path_cond *cond);
 unsigned int aa_str_perms(struct aa_dfa *dfa, unsigned int start,
 			  const char *name, struct path_cond *cond,
-			  struct file_perms *perms);
+			  struct aa_perms *perms);
 
-int aa_path_perm(int op, struct aa_profile *profile, struct path *path,
-		 int flags, u32 request, struct path_cond *cond);
+int __aa_path_perm(const char *op, struct aa_profile *profile,
+		   const char *name, u32 request, struct path_cond *cond,
+		   int flags, struct aa_perms *perms);
+int aa_path_perm(const char *op, struct aa_label *label,
+		 const struct path *path, int flags, u32 request,
+		 struct path_cond *cond);
 
-int aa_path_link(struct aa_profile *profile, struct dentry *old_dentry,
-		 struct path *new_dir, struct dentry *new_dentry);
+int aa_path_link(struct aa_label *label, struct dentry *old_dentry,
+		 const struct path *new_dir, struct dentry *new_dentry);
 
-int aa_file_perm(int op, struct aa_profile *profile, struct file *file,
+int aa_file_perm(const char *op, struct aa_label *label, struct file *file,
 		 u32 request);
 
+void aa_inherit_files(const struct cred *cred, struct files_struct *files);
+
 static inline void aa_free_file_rules(struct aa_file_rules *rules)
 {
 	aa_put_dfa(rules->dfa);
--- zfcpdump-kernel-4.4.orig/security/apparmor/include/ipc.h
+++ zfcpdump-kernel-4.4/security/apparmor/include/ipc.h
@@ -4,7 +4,7 @@
  * This file contains AppArmor ipc mediation function definitions.
  *
  * Copyright (C) 1998-2008 Novell/SUSE
- * Copyright 2009-2010 Canonical Ltd.
+ * Copyright 2009-2013 Canonical Ltd.
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -19,10 +19,22 @@
 
 struct aa_profile;
 
-int aa_may_ptrace(struct aa_profile *tracer, struct aa_profile *tracee,
-		  unsigned int mode);
-
-int aa_ptrace(struct task_struct *tracer, struct task_struct *tracee,
-	      unsigned int mode);
+#define AA_PTRACE_TRACE		MAY_WRITE
+#define AA_PTRACE_READ		MAY_READ
+#define AA_MAY_BE_TRACED	AA_MAY_APPEND
+#define AA_MAY_BE_READ		AA_MAY_CREATE
+#define PTRACE_PERM_SHIFT	2
+
+#define AA_PTRACE_PERM_MASK (AA_PTRACE_READ | AA_PTRACE_TRACE | \
+			     AA_MAY_BE_READ | AA_MAY_BE_TRACED)
+#define AA_SIGNAL_PERM_MASK (MAY_READ | MAY_WRITE)
+
+#define AA_FS_SIG_MASK "hup int quit ill trap abrt bus fpe kill usr1 " \
+	"segv usr2 pipe alrm term stkflt chld cont stop stp ttin ttou urg " \
+	"xcpu xfsz vtalrm prof winch io pwr sys emt lost"
+
+int aa_may_ptrace(struct aa_label *tracer, struct aa_label *tracee,
+		  u32 request);
+int aa_may_signal(struct aa_label *sender, struct aa_label *target, int sig);
 
 #endif /* __AA_IPC_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/security/apparmor/include/label.h
@@ -0,0 +1,502 @@
+/*
+ * AppArmor security module
+ *
+ * This file contains AppArmor label definitions
+ *
+ * Copyright 2013 Canonical Ltd.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2 of the
+ * License.
+ */
+
+#ifndef __AA_LABEL_H
+#define __AA_LABEL_H
+
+#include <linux/atomic.h>
+#include <linux/audit.h>
+#include <linux/rbtree.h>
+#include <linux/rcupdate.h>
+
+#include "apparmor.h"
+#include "lib.h"
+
+struct aa_ns;
+
+#define LOCAL_VEC_ENTRIES 8
+#define DEFINE_VEC(T, V)						\
+	struct aa_ ## T *(_ ## V ## _localtmp)[LOCAL_VEC_ENTRIES];	\
+	struct aa_ ## T **(V)
+
+#define vec_setup(T, V, N, GFP)						\
+({									\
+	if ((N) <= LOCAL_VEC_ENTRIES) {					\
+		typeof(N) i;						\
+		(V) = (_ ## V ## _localtmp);				\
+		for (i = 0; i < (N); i++)				\
+			(V)[i] = NULL;					\
+	} else								\
+		(V) = kzalloc(sizeof(struct aa_ ## T *) * (N), (GFP));	\
+	(V) ? 0 : -ENOMEM;						\
+})
+
+#define vec_cleanup(T, V, N)						\
+do {									\
+	int i;								\
+	for (i = 0; i < (N); i++) {					\
+		if (!IS_ERR_OR_NULL((V)[i]))				\
+			aa_put_ ## T ((V)[i]);				\
+	}								\
+	if ((V) != _ ## V ## _localtmp)					\
+		kfree(V);						\
+} while (0)
+
+#define vec_last(VEC, SIZE) ((VEC)[(SIZE) - 1])
+#define vec_ns(VEC, SIZE) (vec_last((VEC), (SIZE))->ns)
+#define vec_labelset(VEC, SIZE) (&vec_ns((VEC), (SIZE))->labels)
+#define cleanup_domain_vec(V, L) cleanup_label_vec((V), (L)->size)
+
+struct aa_profile;
+#define VEC_FLAG_TERMINATE 1
+int aa_vec_unique(struct aa_profile **vec, int n, int flags);
+struct aa_label *aa_vec_find_or_create_label(struct aa_profile **vec, int len,
+					     gfp_t gfp);
+#define aa_sort_and_merge_vec(N, V) \
+	aa_sort_and_merge_profiles((N), (struct aa_profile **)(V))
+
+struct labelset_stats {
+	atomic_t sread;
+	atomic_t fread;
+	atomic_t msread;
+	atomic_t mfread;
+
+	atomic_t insert;
+	atomic_t existing;
+	atomic_t minsert;
+	atomic_t mexisting;
+
+	atomic_t stale;			/* outstanding stale */
+};
+
+struct label_stats {
+	struct labelset_stats set_stats;
+
+	atomic_t allocated;
+	atomic_t failed;
+	atomic_t freed;
+
+	atomic_t printk_name_alloc;
+	atomic_t printk_name_fail;
+	atomic_t seq_print_name_alloc;
+	atomic_t seq_print_name_fail;
+	atomic_t audit_name_alloc;
+	atomic_t audit_name_fail;
+};
+
+
+#ifdef AA_LABEL_STATS
+#define labelstats_inc(X) atomic_inc(stats.(X))
+#define labelstats_dec(X) atomic_dec(stats.(X))
+#define labelsetstats_inc(LS, X)		\
+	do {					\
+		labelstats_inc(set_stats.##X);	\
+		atomic_inc((LS)->stats.(X));	\
+	} while (0)
+#define labelsetstats_dec(LS, X)		\
+	do {					\
+		labelstats_dec(set_stats.##X);	\
+		atomic_dec((LS)->stats.(X));	\
+	} while (0)
+#else
+#define labelstats_inc(X)
+#define labelstats_dec(X)
+#define labelsetstats_inc(LS, X)
+#define labelsetstats_dec(LS, X)
+#endif
+#define labelstats_init(X)
+
+/* struct aa_labelset - set of labels for a namespace
+ *
+ * Labels are reference counted; aa_labelset does not contribute to label
+ * reference counts. Once a label's last refcount is put it is removed from
+ * the set.
+ */
+struct aa_labelset {
+	rwlock_t lock;
+
+	struct rb_root root;
+
+	/* stats */
+#ifdef APPARMOR_LABEL_STATS
+	struct labelset_stats stats;
+#endif
+
+};
+
+#define __labelset_for_each(LS, N) \
+	for((N) = rb_first(&(LS)->root); (N); (N) = rb_next(N))
+
+void aa_labelset_destroy(struct aa_labelset *ls);
+void aa_labelset_init(struct aa_labelset *ls);
+
+
+enum label_flags {
+	FLAG_HAT = 1,			/* profile is a hat */
+	FLAG_UNCONFINED = 2,		/* label unconfined only if all
+					 * constituant profiles unconfined */
+	FLAG_NULL = 4,			/* profile is null learning profile */
+	FLAG_IX_ON_NAME_ERROR = 8,	/* fallback to ix on name lookup fail */
+	FLAG_IMMUTIBLE = 0x10,		/* don't allow changes/replacement */
+	FLAG_USER_DEFINED = 0x20,	/* user based profile - lower privs */
+	FLAG_NO_LIST_REF = 0x40,	/* list doesn't keep profile ref */
+	FLAG_NS_COUNT = 0x80,		/* carries NS ref count */
+	FLAG_IN_TREE = 0x100,		/* label is in tree */
+	FLAG_PROFILE = 0x200,		/* label is a profile */
+	FLAG_EXPLICIT = 0x400,		/* explict static label */
+	FLAG_STALE = 0x800,		/* replaced/removed */
+	FLAG_RENAMED = 0x1000,		/* label has renaming in it */
+	FLAG_REVOKED = 0x2000,		/* label has revocation in it */
+
+	/* These flags must correspond with PATH_flags */
+	/* TODO: add new path flags */
+};
+
+struct aa_label;
+struct aa_proxy {
+	struct kref count;
+	struct aa_label __rcu *label;
+};
+
+struct label_it {
+	int i, j;
+};
+
+/* struct aa_label - lazy labeling struct
+ * @count: ref count of active users
+ * @node: rbtree position
+ * @rcu: rcu callback struct
+ * @proxy: is set to the label that replaced this label
+ * @hname: text representation of the label (MAYBE_NULL)
+ * @flags: stale and other flags - values may change under label set lock
+ * @sid: sid that references this label
+ * @size: number of entries in @ent[]
+ * @ent: set of profiles for label, actual size determined by @size
+ */
+struct aa_label {
+	struct kref count;
+	struct rb_node node;
+	struct rcu_head rcu;
+	struct aa_proxy *proxy;
+	__counted char *hname;
+	long flags;
+	u32 sid;
+	int size;
+	struct aa_profile *vec[];
+};
+
+#define last_error(E, FN)				\
+do {							\
+	int __subE = (FN);				\
+	if (__subE)					\
+		(E) = __subE;				\
+} while (0)
+
+#define label_isprofile(X) ((X)->flags & FLAG_PROFILE)
+#define label_unconfined(X) ((X)->flags & FLAG_UNCONFINED)
+#define unconfined(X) label_unconfined(X)
+#define label_is_stale(X) ((X)->flags & FLAG_STALE)
+#define __label_make_stale(X) do {	   \
+	labelsetstats_inc(labels_set(X), stale); \
+	((X)->flags |= FLAG_STALE);	   \
+} while (0)
+#define labels_ns(X) (vec_ns(&((X)->vec[0]), (X)->size))
+#define labels_set(X) (&labels_ns(X)->labels)
+#define labels_profile(X) ((X)->vec[(X)->size - 1])
+
+
+int aa_label_next_confined(struct aa_label *l, int i);
+
+/* for each profile in a label */
+#define label_for_each_init(I) ((I).i = 0);
+#define label_for_each_next(I) (++((I).i))
+#define label_for_each_curr(I, L) ({ (L)->vec[(I).i] ; })
+#define label_for_each(I, L, P)						\
+	for ((I).i = 0; ((P) = (L)->vec[(I).i]); ++((I).i))
+
+/* assumes break/goto ended label_for_each */
+#define label_for_each_cont(I, L, P)					\
+  for (++((I).i); ((P) = (L)->vec[(I).i]);	++((I).i))
+
+#define next_comb(I, L1, L2)						\
+do {									\
+	(I).j++;							\
+	if ((I).j >= (L2)->size) {					\
+		(I).i++;						\
+		(I).j = 0;						\
+	}								\
+} while (0)
+
+/* TODO: label_for_each_ns_comb */
+
+/* for each combination of P1 in L1, and P2 in L2 */
+#define label_for_each_comb(I, L1, L2, P1, P2)				\
+for ((I).i = (I).j = 0;							\
+     ((P1) = (L1)->vec[(I).i]) && ((P2) = (L2)->vec[(I).j]);		\
+     (I) = next_comb(I, L1, L2))
+
+#define fn_for_each_comb(L1, L2, P1, P2, FN)				\
+({									\
+	struct label_it i;						\
+	int __E = 0;							\
+	label_for_each_comb(i, (L1), (L2), (P1), (P2)) {		\
+		last_error(__E, (FN));					\
+	}								\
+	__E;								\
+})
+
+/* internal cross check */
+//fn_for_each_comb(L1, L2, P1, P2, xcheck(...));
+
+/* external cross check */
+// xcheck(fn_for_each_comb(L1, L2, ...),
+//        fn_for_each_comb(L2, L1, ...));
+
+/* for each profile that is enforcing confinement in a label */
+#define label_for_each_confined(I, L, P)				\
+	for ((I).i = aa_label_next_confined((L), 0);			\
+	     ((P) = (L)->vec[(I).i]);					\
+	     (I).i = aa_label_next_confined((L), (I).i + 1))
+
+#define label_for_each_in_merge(I, A, B, P)				\
+	for ((I).i = (I).j = 0;						\
+	     ((P) = aa_label_next_in_merge(&(I), (A), (B)));		\
+	     )
+
+#define label_for_each_not_in_set(I, SET, SUB, P)			\
+	for ((I).i = (I).j = 0;						\
+	     ((P) = __aa_label_next_not_in_set(&(I), (SET), (SUB)));	\
+	     )
+
+#define next_in_ns(i, NS, L)						\
+({									\
+	typeof(i) ___i = (i);						\
+	while ((L)->vec[___i] && (L)->vec[___i]->ns != (NS))		\
+		(___i)++;						\
+	(___i);								\
+})
+
+#define label_for_each_in_ns(I, NS, L, P)				\
+	for ((I).i = next_in_ns(0, (NS), (L));				\
+	     ((P) = (L)->vec[(I).i]);					\
+	     (I).i = next_in_ns((I).i + 1, (NS), (L)))
+
+#define fn_for_each_in_ns(L, P, FN)					\
+({									\
+	struct label_it __i;						\
+	struct aa_ns *__ns = labels_ns(L);				\
+	int __E = 0;							\
+	label_for_each_in_ns(__i, __ns, (L), (P)) {			\
+		last_error(__E, (FN));					\
+	}								\
+	__E;								\
+})
+
+
+#define fn_for_each_XXX(L, P, FN, ...)					\
+({									\
+	struct label_it i;						\
+	int __E = 0;							\
+	label_for_each ## __VA_ARGS__ (i, (L), (P)) {			\
+		last_error(__E, (FN));					\
+	}								\
+	__E;								\
+})
+
+#define fn_for_each(L, P, FN) fn_for_each_XXX(L, P, FN)
+#define fn_for_each_confined(L, P, FN) fn_for_each_XXX(L, P, FN, _confined)
+
+#define fn_for_each2_XXX(L1, L2, P, FN, ...)				\
+({									\
+	struct label_it i;						\
+	int __E = 0;							\
+	label_for_each ## __VA_ARGS__(i, (L1), (L2), (P)) {		\
+		last_error(__E, (FN));					\
+	}								\
+	__E;								\
+})
+
+#define fn_for_each_in_merge(L1, L2, P, FN)				\
+	fn_for_each2_XXX((L1), (L2), P, FN, _in_merge)
+#define fn_for_each_not_in_set(L1, L2, P, FN)				\
+	fn_for_each2_XXX((L1), (L2), P, FN, _not_in_set)
+
+#define LABEL_MEDIATES(L, C)						\
+({									\
+	struct aa_profile *profile;					\
+	struct label_it i;						\
+	int ret = 0;							\
+	label_for_each(i, (L), profile) {				\
+		if (PROFILE_MEDIATES(profile, (C))) {			\
+			ret = 1;					\
+			break;						\
+		}							\
+	}								\
+	ret;								\
+})
+
+
+void aa_labelset_destroy(struct aa_labelset *ls);
+void aa_labelset_init(struct aa_labelset *ls);
+void __aa_labelset_update_subtree(struct aa_ns *ns);
+
+void aa_label_free(struct aa_label *label);
+void aa_label_kref(struct kref *kref);
+bool aa_label_init(struct aa_label *label, int size);
+struct aa_label *aa_label_alloc(int size, struct aa_proxy *proxy, gfp_t gfp);
+
+bool aa_label_is_subset(struct aa_label *set, struct aa_label *sub);
+struct aa_profile *__aa_label_next_not_in_set(struct label_it *I,
+					     struct aa_label *set,
+					     struct aa_label *sub);
+bool aa_label_remove(struct aa_label *label);
+struct aa_label *aa_label_insert(struct aa_labelset *ls, struct aa_label *l);
+bool aa_label_replace(struct aa_label *old, struct aa_label *new);
+bool aa_label_make_newest(struct aa_labelset *ls, struct aa_label *old,
+			  struct aa_label *new);
+
+struct aa_label *aa_label_find(struct aa_label *l);
+
+struct aa_profile *aa_label_next_in_merge(struct label_it *I,
+					  struct aa_label *a,
+					  struct aa_label *b);
+struct aa_label *aa_label_find_merge(struct aa_label *a, struct aa_label *b);
+struct aa_label *aa_label_merge(struct aa_label *a, struct aa_label *b,
+				gfp_t gfp);
+
+
+bool aa_update_label_name(struct aa_ns *ns, struct aa_label *label, gfp_t gfp);
+
+#define FLAGS_NONE 0
+#define FLAG_SHOW_MODE 1
+#define FLAG_VIEW_SUBNS 2
+#define FLAG_HIDDEN_UNCONFINED 4
+int aa_profile_snxprint(char *str, size_t size, struct aa_ns *ns,
+			struct aa_profile *profile, int flags);
+int aa_label_snxprint(char *str, size_t size, struct aa_ns *ns,
+		      struct aa_label *label, int flags);
+int aa_label_asxprint(char **strp, struct aa_ns *ns, struct aa_label *label,
+		      int flags, gfp_t gfp);
+int aa_label_acntsxprint(char __counted **strp, struct aa_ns *ns,
+			 struct aa_label *label, int flags, gfp_t gfp);
+void aa_label_xaudit(struct audit_buffer *ab, struct aa_ns *ns,
+		     struct aa_label *label, int flags, gfp_t gfp);
+void aa_label_seq_xprint(struct seq_file *f, struct aa_ns *ns,
+			 struct aa_label *label, int flags, gfp_t gfp);
+void aa_label_xprintk(struct aa_ns *ns, struct aa_label *label, int flags,
+		      gfp_t gfp);
+void aa_label_audit(struct audit_buffer *ab, struct aa_label *label, gfp_t gfp);
+void aa_label_seq_print(struct seq_file *f, struct aa_label *label, gfp_t gfp);
+void aa_label_printk(struct aa_label *label, gfp_t gfp);
+
+struct aa_label *aa_label_parse(struct aa_label *base, const char *str,
+				gfp_t gfp, bool create, bool force_stack);
+
+
+struct aa_perms;
+int aa_label_match(struct aa_profile *profile, struct aa_label *label,
+		   unsigned int state, bool subns, u32 request,
+		   struct aa_perms *perms);
+
+
+static inline struct aa_label *aa_get_label(struct aa_label *l)
+{
+	if (l)
+		kref_get(&(l->count));
+
+	return l;
+}
+
+static inline struct aa_label *aa_get_label_not0(struct aa_label *l)
+{
+	if (l && kref_get_not0(&l->count))
+		return l;
+
+	return NULL;
+}
+
+/**
+ * aa_get_label_rcu - increment refcount on a label that can be replaced
+ * @l: pointer to label that can be replaced (NOT NULL)
+ *
+ * Returns: pointer to a refcounted label.
+ *     else NULL if no label
+ */
+static inline struct aa_label *aa_get_label_rcu(struct aa_label __rcu **l)
+{
+	struct aa_label *c;
+
+	rcu_read_lock();
+	do {
+		c = rcu_dereference(*l);
+	} while (c && !kref_get_not0(&c->count));
+	rcu_read_unlock();
+
+	return c;
+}
+
+/**
+ * aa_get_newest_label - find the newest version of @l
+ * @l: the label to check for newer versions of
+ *
+ * Returns: refcounted newest version of @l taking into account
+ *          replacement, renames and removals
+ *          return @l.
+ */
+static inline struct aa_label *aa_get_newest_label(struct aa_label *l)
+{
+	if (!l)
+		return NULL;
+
+	if (label_is_stale(l)) {
+		struct aa_label *tmp;
+		AA_BUG(!l->proxy);
+		AA_BUG(!l->proxy->label);
+		/* BUG: only way this can happen is @l ref count and its
+		 * replacement count have gone to 0 and are on their way
+		 * to destruction. ie. we have a refcounting error
+		 */
+		AA_BUG(!(tmp = aa_get_label_rcu(&l->proxy->label)));
+		return tmp;
+	}
+
+	return aa_get_label(l);
+}
+
+static inline void aa_put_label(struct aa_label *l)
+{
+	if (l)
+		kref_put(&l->count, aa_label_kref);
+}
+
+
+struct aa_proxy *aa_alloc_proxy(struct aa_label *l, gfp_t gfp);
+void aa_proxy_kref(struct kref *kref);
+
+static inline struct aa_proxy *aa_get_proxy(struct aa_proxy *proxy)
+{
+	if (proxy)
+		kref_get(&(proxy->count));
+
+	return proxy;
+}
+
+static inline void aa_put_proxy(struct aa_proxy *proxy)
+{
+	if (proxy)
+		kref_put(&proxy->count, aa_proxy_kref);
+}
+
+void __aa_proxy_redirect(struct aa_label *orig, struct aa_label *new);
+
+#endif /* __AA_LABEL_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/security/apparmor/include/lib.h
@@ -0,0 +1,317 @@
+/*
+ * AppArmor security module
+ *
+ * This file contains AppArmor lib definitions
+ *
+ * 2016 Canonical Ltd.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2 of the
+ * License.
+ */
+
+#ifndef __AA_LIB_H
+#define __AA_LIB_H
+
+#include <linux/slab.h>
+#include <linux/fs.h>
+
+#include "match.h"
+
+/* Provide our own test for whether a write lock is held for asserts
+ * this is because on none SMP systems write_can_lock will always
+ * resolve to true, which is what you want for code making decisions
+ * based on it, but wrong for asserts checking that the lock is held
+ */
+#ifdef CONFIG_SMP
+#define write_is_locked(X) !write_can_lock(X)
+#else
+#define write_is_locked(X) (1)
+#endif /* CONFIG_SMP */
+
+/*
+ * DEBUG remains global (no per profile flag) since it is mostly used in sysctl
+ * which is not related to profile accesses.
+ */
+
+#define DEBUG_ON (aa_g_debug && printk_ratelimit())
+#define dbg_printk(__fmt, __args...) printk(KERN_DEBUG __fmt, ##__args)
+#define AA_DEBUG(fmt, args...)						\
+	do {								\
+		if (DEBUG_ON)						\
+			dbg_printk("AppArmor: " fmt, ##args);		\
+	} while (0)
+
+#define AA_WARN(X) WARN((X), "APPARMOR WARN %s: %s\n", __FUNCTION__, #X)
+
+#define AA_BUG(X, args...) AA_BUG_FMT((X), "" args )
+#define AA_BUG_FMT(X, fmt, args...)					\
+	WARN((X), "AppArmor WARN %s: (" #X "): " fmt, __FUNCTION__ , ##args )
+
+#define AA_ERROR(fmt, args...)						\
+	do {								\
+		if (printk_ratelimit())					\
+			printk(KERN_ERR "AppArmor: " fmt, ##args);	\
+	} while (0)
+
+/* Flag indicating whether initialization completed */
+extern int apparmor_initialized __initdata;
+
+/* fn's in lib */
+char *aa_split_fqname(char *args, char **ns_name);
+const char *aa_splitn_fqname(const char *fqname, size_t n, const char **ns_name,
+			     size_t *ns_len);
+void aa_info_message(const char *str);
+void *__aa_kvmalloc(size_t size, gfp_t flags);
+
+static inline void *kvmalloc(size_t size)
+{
+	return __aa_kvmalloc(size, 0);
+}
+
+static inline void *kvzalloc(size_t size)
+{
+	return __aa_kvmalloc(size, __GFP_ZERO);
+}
+
+/* returns 0 if kref not incremented */
+static inline int kref_get_not0(struct kref *kref)
+{
+	return atomic_inc_not_zero(&kref->refcount);
+}
+
+/**
+ * aa_strneq - compare null terminated @str to a non null terminated substring
+ * @str: a null terminated string
+ * @sub: a substring, not necessarily null terminated
+ * @len: length of @sub to compare
+ *
+ * The @str string must be full consumed for this to be considered a match
+ */
+static inline bool aa_strneq(const char *str, const char *sub, int len)
+{
+	return !strncmp(str, sub, len) && !str[len];
+}
+
+/**
+ * aa_dfa_null_transition - step to next state after null character
+ * @dfa: the dfa to match against
+ * @start: the state of the dfa to start matching in
+ *
+ * aa_dfa_null_transition transitions to the next state after a null
+ * character which is not used in standard matching and is only
+ * used to separate pairs.
+ */
+static inline unsigned int aa_dfa_null_transition(struct aa_dfa *dfa,
+						  unsigned int start)
+{
+	/* the null transition only needs the string's null terminator byte */
+	return aa_dfa_next(dfa, start, 0);
+}
+
+static inline bool path_mediated_fs(struct dentry *dentry)
+{
+	return !(dentry->d_sb->s_flags & MS_NOUSER);
+}
+
+
+struct counted_str {
+	struct kref count;
+	char name[];
+};
+
+#define str_to_counted(str) \
+	((struct counted_str *)(str - offsetof(struct counted_str,name)))
+
+#define __counted	/* atm just a notation */
+
+void aa_str_kref(struct kref *kref);
+char *aa_str_alloc(int size, gfp_t gfp);
+
+
+static inline __counted char *aa_get_str(__counted char *str)
+{
+	if (str)
+		kref_get(&(str_to_counted(str)->count));
+
+	return str;
+}
+
+static inline void aa_put_str(__counted char *str)
+{
+	if (str)
+		kref_put(&str_to_counted(str)->count, aa_str_kref);
+}
+
+const char *aa_imode_name(umode_t mode);
+
+
+/* struct aa_policy - common part of both namespaces and profiles
+ * @name: name of the object
+ * @hname - The hierarchical name, NOTE: is .name of struct counted_str
+ * @list: list policy object is on
+ * @profiles: head of the profiles list contained in the object
+ */
+struct aa_policy {
+	const char *name;
+	__counted char *hname;
+	struct list_head list;
+	struct list_head profiles;
+};
+
+#define aa_peer_name(peer) (peer)->base.hname
+
+/**
+ * basename - find the last component of an hname
+ * @name: hname to find the base profile name component of  (NOT NULL)
+ *
+ * Returns: the tail (base profile name) name component of an hname
+ */
+static inline const char *basename(const char *hname)
+{
+	char *split;
+	hname = strim((char *)hname);
+	for (split = strstr(hname, "//"); split; split = strstr(hname, "//"))
+		hname = split + 2;
+
+	return hname;
+}
+
+/**
+ * __policy_find - find a policy by @name on a policy list
+ * @head: list to search  (NOT NULL)
+ * @name: name to search for  (NOT NULL)
+ *
+ * Requires: rcu_read_lock be held
+ *
+ * Returns: unrefcounted policy that match @name or NULL if not found
+ */
+static inline struct aa_policy *__policy_find(struct list_head *head,
+					      const char *name)
+{
+	struct aa_policy *policy;
+
+	list_for_each_entry_rcu(policy, head, list) {
+		if (!strcmp(policy->name, name))
+			return policy;
+	}
+	return NULL;
+}
+
+/**
+ * __policy_strn_find - find a policy that's name matches @len chars of @str
+ * @head: list to search  (NOT NULL)
+ * @str: string to search for  (NOT NULL)
+ * @len: length of match required
+ *
+ * Requires: rcu_read_lock be held
+ *
+ * Returns: unrefcounted policy that match @str or NULL if not found
+ *
+ * if @len == strlen(@strlen) then this is equiv to __policy_find
+ * other wise it allows searching for policy by a partial match of name
+ */
+static inline struct aa_policy *__policy_strn_find(struct list_head *head,
+						   const char *str, int len)
+{
+	struct aa_policy *policy;
+
+	list_for_each_entry_rcu(policy, head, list) {
+		if (aa_strneq(policy->name, str, len))
+			return policy;
+	}
+
+	return NULL;
+}
+
+bool aa_policy_init(struct aa_policy *policy, const char *prefix,
+		    const char *name, gfp_t gfp);
+void aa_policy_destroy(struct aa_policy *policy);
+
+
+/*
+ * fn_label_build - abstract out the build of a label transition
+ * @L: label the transition is being computed for
+ * @P: profile parameter derived from L by this macro, can be passed to FN
+ * @GFP: memory allocation type to use
+ * @FN: fn to call for each profile transition. @P is set to the profile
+ *
+ * Returns: new label on success
+ *          ERR_PTR if build @FN fails
+ *          NULL if label_build fails due to low memory conditions
+ *
+ * @FN must return a label or ERR_PTR on failure. NULL is not allowed
+ */
+#define fn_label_build(L, P, GFP, FN)					\
+({									\
+	__label__ __cleanup, __done;					\
+	struct aa_label *__new_;					\
+									\
+	if ((L)->size > 1) {						\
+		/* TODO: add cache of transitions already done */	\
+		struct label_it __i;					\
+		int __j, __k, __count;					\
+		DEFINE_VEC(label, __lvec);				\
+		DEFINE_VEC(profile, __pvec);				\
+		if (vec_setup(label, __lvec, (L)->size, (GFP)))	{	\
+			__new_ = NULL;					\
+			goto __done;					\
+		}							\
+		__j = 0;						\
+		label_for_each(__i, (L), (P)) {				\
+			__new_ = (FN);					\
+			AA_BUG(!__new_);				\
+			if (IS_ERR(__new_))				\
+				goto __cleanup;				\
+			__lvec[__j++] = __new_;				\
+		}							\
+		for (__j = __count = 0; __j < (L)->size; __j++)		\
+			__count += __lvec[__j]->size;			\
+		if (!vec_setup(profile, __pvec, __count, (GFP))) {	\
+			for (__j = __k = 0; __j < (L)->size; __j++) {	\
+				label_for_each(__i, __lvec[__j], (P))	\
+					__pvec[__k++] = aa_get_profile(P); \
+			}						\
+			__count -= aa_vec_unique(__pvec, __count, 0);	\
+			if (__count > 1) {				\
+				__new_ = aa_vec_find_or_create_label(__pvec,\
+						     __count, (GFP));	\
+				/* only fails if out of Mem */		\
+				if (!__new_)				\
+					__new_ = NULL;			\
+			} else						\
+				__new_ = aa_get_label(&__pvec[0]->label); \
+			vec_cleanup(profile, __pvec, __count);		\
+		} else							\
+			__new_ = NULL;					\
+	__cleanup:							\
+		vec_cleanup(label, __lvec, (L)->size);			\
+	} else {							\
+		(P) = labels_profile(L);				\
+		__new_ = (FN);						\
+	}								\
+__done:									\
+	if (!__new_)							\
+		AA_DEBUG("label build failed\n");			\
+	(__new_);							\
+})
+
+
+#define __fn_build_in_ns(NS, P, NS_FN, OTHER_FN)			\
+({									\
+	struct aa_label *__new;						\
+	if ((P)->ns != (NS))						\
+		__new = (OTHER_FN);					\
+	else								\
+		__new = (NS_FN);					\
+	(__new);							\
+})
+
+#define fn_label_build_in_ns(L, P, GFP, NS_FN, OTHER_FN)		\
+({									\
+	fn_label_build((L), (P), (GFP),					\
+		__fn_build_in_ns(labels_ns(L), (P), (NS_FN), (OTHER_FN))); \
+})
+
+#endif /* __AA_LIB_H */
--- zfcpdump-kernel-4.4.orig/security/apparmor/include/match.h
+++ zfcpdump-kernel-4.4/security/apparmor/include/match.h
@@ -62,6 +62,7 @@ struct table_set_header {
 #define YYTD_ID_ACCEPT2 6
 #define YYTD_ID_NXT	7
 #define YYTD_ID_TSIZE	8
+#define YYTD_ID_MAX	8
 
 #define YYTD_DATA8	1
 #define YYTD_DATA16	2
@@ -99,6 +100,8 @@ struct aa_dfa {
 	struct table_header *tables[YYTD_ID_TSIZE];
 };
 
+extern struct aa_dfa *nulldfa;
+
 #define byte_to_byte(X) (X)
 
 #define UNPACK_ARRAY(TABLE, BLOB, LEN, TYPE, NTOHX) \
@@ -116,6 +119,9 @@ static inline size_t table_size(size_t l
 	return ALIGN(sizeof(struct table_header) + len * el_size, 8);
 }
 
+int aa_setup_dfa_engine(void);
+void aa_teardown_dfa_engine(void);
+
 struct aa_dfa *aa_dfa_unpack(void *blob, size_t size, int flags);
 unsigned int aa_dfa_match_len(struct aa_dfa *dfa, unsigned int start,
 			      const char *str, int len);
@@ -127,6 +133,21 @@ unsigned int aa_dfa_next(struct aa_dfa *
 void aa_dfa_free_kref(struct kref *kref);
 
 /**
+ * aa_get_dfa - increment refcount on dfa @p
+ * @dfa: dfa  (MAYBE NULL)
+ *
+ * Returns: pointer to @dfa if @dfa is NULL will return NULL
+ * Requires: @dfa must be held with valid refcount when called
+ */
+static inline struct aa_dfa *aa_get_dfa(struct aa_dfa *dfa)
+{
+	if (dfa)
+		kref_get(&(dfa->count));
+
+	return dfa;
+}
+
+/**
  * aa_put_dfa - put a dfa refcount
  * @dfa: dfa to put refcount   (MAYBE NULL)
  *
--- /dev/null
+++ zfcpdump-kernel-4.4/security/apparmor/include/mount.h
@@ -0,0 +1,54 @@
+/*
+ * AppArmor security module
+ *
+ * This file contains AppArmor file mediation function definitions.
+ *
+ * Copyright 2012 Canonical Ltd.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2 of the
+ * License.
+ */
+
+#ifndef __AA_MOUNT_H
+#define __AA_MOUNT_H
+
+#include <linux/fs.h>
+#include <linux/path.h>
+
+#include "domain.h"
+#include "policy.h"
+
+/* mount perms */
+#define AA_MAY_PIVOTROOT	0x01
+#define AA_MAY_MOUNT		0x02
+#define AA_MAY_UMOUNT		0x04
+#define AA_AUDIT_DATA		0x40
+#define AA_MNT_CONT_MATCH	0x40
+
+#define AA_MS_IGNORE_MASK (MS_KERNMOUNT | MS_NOSEC | MS_ACTIVE | MS_BORN)
+
+int aa_remount(struct aa_label *label, const struct path *path,
+	       unsigned long flags, void *data);
+
+int aa_bind_mount(struct aa_label *label, const struct path *path,
+		  const char *old_name, unsigned long flags);
+
+
+int aa_mount_change_type(struct aa_label *label, const struct path *path,
+			 unsigned long flags);
+
+int aa_move_mount(struct aa_label *label, const struct path *path,
+		  const char *old_name);
+
+int aa_new_mount(struct aa_label *label, const char *dev_name,
+		 const struct path *path, const char *type, unsigned long flags,
+		 void *data);
+
+int aa_umount(struct aa_label *label, struct vfsmount *mnt, int flags);
+
+int aa_pivotroot(struct aa_label *label, const struct path *old_path,
+		 const struct path *new_path);
+
+#endif /* __AA_MOUNT_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/security/apparmor/include/net.h
@@ -0,0 +1,124 @@
+/*
+ * AppArmor security module
+ *
+ * This file contains AppArmor network mediation definitions.
+ *
+ * Copyright (C) 1998-2008 Novell/SUSE
+ * Copyright 2009-2014 Canonical Ltd.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2 of the
+ * License.
+ */
+
+#ifndef __AA_NET_H
+#define __AA_NET_H
+
+#include <net/sock.h>
+#include <linux/path.h>
+
+#include "apparmorfs.h"
+#include "label.h"
+#include "perms.h"
+#include "policy.h"
+
+#define AA_MAY_SEND		AA_MAY_WRITE
+#define AA_MAY_RECEIVE		AA_MAY_READ
+
+#define AA_MAY_SHUTDOWN		AA_MAY_DELETE
+
+#define AA_MAY_CONNECT		AA_MAY_OPEN
+#define AA_MAY_ACCEPT		0x00100000
+
+#define AA_MAY_BIND		0x00200000
+#define AA_MAY_LISTEN		0x00400000
+
+#define AA_MAY_SETOPT		0x01000000
+#define AA_MAY_GETOPT		0x02000000
+
+#define NET_PERMS_MASK (AA_MAY_SEND | AA_MAY_RECEIVE | AA_MAY_CREATE |    \
+			AA_MAY_SHUTDOWN | AA_MAY_BIND | AA_MAY_LISTEN |	  \
+			AA_MAY_CONNECT | AA_MAY_ACCEPT | AA_MAY_SETATTR | \
+			AA_MAY_GETATTR | AA_MAY_SETOPT | AA_MAY_GETOPT)
+
+#define NET_FS_PERMS (AA_MAY_SEND | AA_MAY_RECEIVE | AA_MAY_CREATE |	\
+		      AA_MAY_SHUTDOWN | AA_MAY_CONNECT | AA_MAY_RENAME |\
+		      AA_MAY_SETATTR | AA_MAY_GETATTR | AA_MAY_CHMOD |	\
+		      AA_MAY_CHOWN | AA_MAY_CHGRP | AA_MAY_LOCK |	\
+		      AA_MAY_MPROT)
+
+#define NET_PEER_MASK (AA_MAY_SEND | AA_MAY_RECEIVE | AA_MAY_CONNECT |	\
+		       AA_MAY_ACCEPT)
+struct aa_sk_ctx {
+	struct aa_label *label;
+	struct aa_label *peer;
+	struct path path;
+};
+
+#define SK_CTX(X) (X)->sk_security
+#define SOCK_ctx(X) SOCK_INODE(X)->i_security
+#define DEFINE_AUDIT_NET(NAME, OP, SK, F, T, P)				  \
+	struct lsm_network_audit NAME ## _net = { .sk = (SK),		  \
+						  .family = (F)};	  \
+	DEFINE_AUDIT_DATA(NAME,						  \
+			  ((SK) && (F) != AF_UNIX) ? LSM_AUDIT_DATA_NET : \
+						     LSM_AUDIT_DATA_NONE, \
+			  OP);						  \
+	NAME.u.net = &(NAME ## _net);					  \
+	aad(&NAME)->net.type = (T);					  \
+	aad(&NAME)->net.protocol = (P)
+
+#define DEFINE_AUDIT_SK(NAME, OP, SK)					\
+	DEFINE_AUDIT_NET(NAME, OP, SK, (SK)->sk_family, (SK)->sk_type,	\
+			 (SK)->sk_protocol)
+
+/* struct aa_net - network confinement data
+ * @allowed: basic network families permissions
+ * @audit_network: which network permissions to force audit
+ * @quiet_network: which network permissions to quiet rejects
+ */
+struct aa_net {
+	u16 allow[AF_MAX];
+	u16 audit[AF_MAX];
+	u16 quiet[AF_MAX];
+};
+
+
+extern struct aa_fs_entry aa_fs_entry_network[];
+
+void audit_net_cb(struct audit_buffer *ab, void *va);
+int aa_profile_af_perm(struct aa_profile *profile, struct common_audit_data *sa,
+		       u32 request, u16 family, int type);
+static inline int aa_profile_af_sk_perm(struct aa_profile *profile,
+					struct common_audit_data *sa,
+					u32 request,
+					struct sock *sk)
+{
+	return aa_profile_af_perm(profile, sa, request, sk->sk_family,
+				  sk->sk_type);
+}
+
+int aa_sock_perm(const char *op, u32 request, struct socket *sock);
+int aa_sock_create_perm(struct aa_label *label, int family, int type,
+			int protocol);
+int aa_sock_bind_perm(struct socket *sock, struct sockaddr *address,
+		      int addrlen);
+int aa_sock_connect_perm(struct socket *sock, struct sockaddr *address,
+			 int addrlen);
+int aa_sock_listen_perm(struct socket *sock, int backlog);
+int aa_sock_accept_perm(struct socket *sock, struct socket *newsock);
+int aa_sock_msg_perm(const char *op, u32 request, struct socket *sock,
+		     struct msghdr *msg, int size);
+int aa_sock_opt_perm(const char *op, u32 request, struct socket *sock, int level,
+		     int optname);
+int aa_sock_file_perm(struct aa_label *label, const char *op, u32 request,
+		      struct socket *sock);
+
+
+static inline void aa_free_net_rules(struct aa_net *new)
+{
+	/* NOP */
+}
+
+#endif /* __AA_NET_H */
--- zfcpdump-kernel-4.4.orig/security/apparmor/include/path.h
+++ zfcpdump-kernel-4.4/security/apparmor/include/path.h
@@ -18,15 +18,72 @@
 
 enum path_flags {
 	PATH_IS_DIR = 0x1,		/* path is a directory */
+	PATH_SOCK_COND = 0x2,
 	PATH_CONNECT_PATH = 0x4,	/* connect disconnected paths to / */
 	PATH_CHROOT_REL = 0x8,		/* do path lookup relative to chroot */
 	PATH_CHROOT_NSCONNECT = 0x10,	/* connect paths that are at ns root */
 
 	PATH_DELEGATE_DELETED = 0x08000, /* delegate deleted files */
-	PATH_MEDIATE_DELETED = 0x10000,	/* mediate deleted paths */
+	PATH_MEDIATE_DELETED = 0x10000,	 /* mediate deleted paths */
 };
 
-int aa_path_name(struct path *path, int flags, char **buffer,
-		 const char **name, const char **info);
+int aa_path_name(const struct path *path, int flags, char *buffer,
+		 const char **name, const char **info, const char *disconnect);
+
+#define MAX_PATH_BUFFERS 2
+
+/* Per cpu buffers used during mediation */
+/* preallocated buffers to use during path lookups */
+struct aa_buffers {
+	char *buf[MAX_PATH_BUFFERS];
+};
+
+#include <linux/percpu.h>
+#include <linux/preempt.h>
+
+DECLARE_PER_CPU(struct aa_buffers, aa_buffers);
+
+#define COUNT_ARGS(X...) COUNT_ARGS_HELPER ( , ##X ,9,8,7,6,5,4,3,2,1,0)
+#define COUNT_ARGS_HELPER(_0,_1,_2,_3,_4,_5,_6,_7,_8,_9,n,X...) n
+#define CONCAT(X, Y) X ## Y
+#define CONCAT_AFTER(X, Y) CONCAT(X, Y)
+
+#define ASSIGN(FN, X, N) do { (X) = FN(N); } while (0)
+#define EVAL1(FN, X) ASSIGN(FN, X, 0) /*X = FN(0)*/
+#define EVAL2(FN, X, Y...) ASSIGN(FN, X, 1); /*X = FN(1);*/ EVAL1(FN, Y)
+#define EVAL(FN, X...) CONCAT_AFTER(EVAL, COUNT_ARGS(X))(FN, X)
+
+#define for_each_cpu_buffer(I) for ((I) = 0; (I) < MAX_PATH_BUFFERS; (I)++)
+
+#ifdef CONFIG_DEBUG_PREEMPT
+#define AA_BUG_PREEMPT_ENABLED(X) AA_BUG(preempt_count() <= 0, X)
+#else
+#define AA_BUG_PREEMPT_ENABLED(X) /* nop */
+#endif
+
+#define __get_buffer(N) ({					\
+	struct aa_buffers *__cpu_var; \
+	AA_BUG_PREEMPT_ENABLED("__get_buffer without preempt disabled");  \
+	__cpu_var = this_cpu_ptr(&aa_buffers);			\
+        __cpu_var->buf[(N)]; })
+
+#define __get_buffers(X...)		\
+do {					\
+	EVAL(__get_buffer, X);		\
+} while (0)
+
+#define __put_buffers(X, Y...) (void)&(X)
+
+#define get_buffers(X...)	\
+do {				\
+	preempt_disable();	\
+	__get_buffers(X);	\
+} while (0)
+
+#define put_buffers(X, Y...)	\
+do {				\
+	__put_buffers(X, Y);	\
+	preempt_enable();	\
+} while (0)
 
 #endif /* __AA_PATH_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/security/apparmor/include/perms.h
@@ -0,0 +1,173 @@
+/*
+ * AppArmor security module
+ *
+ * This file contains AppArmor basic permission sets definitions.
+ *
+ * Copyright 2013 Canonical Ltd.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2 of the
+ * License.
+ */
+
+#ifndef __AA_PERM_H
+#define __AA_PERM_H
+
+#include <linux/fs.h>
+#include "label.h"
+
+#define AA_MAY_EXEC		MAY_EXEC
+#define AA_MAY_WRITE		MAY_WRITE
+#define AA_MAY_READ		MAY_READ
+#define AA_MAY_APPEND		MAY_APPEND
+
+#define AA_MAY_CREATE		0x0010
+#define AA_MAY_DELETE		0x0020
+#define AA_MAY_OPEN		0x0040
+#define AA_MAY_RENAME		0x0080		/* pair */
+
+#define AA_MAY_SETATTR		0x0100		/* meta write */
+#define AA_MAY_GETATTR		0x0200		/* meta read */
+#define AA_MAY_SETCRED		0x0400		/* security cred/attr */
+#define AA_MAY_GETCRED		0x0800
+
+#define AA_MAY_CHMOD		0x1000		/* pair */
+#define AA_MAY_CHOWN		0x2000		/* pair */
+#define AA_MAY_CHGRP		0x4000		/* pair */
+#define AA_MAY_LOCK		0x8000		/* LINK_SUBSET overlaid */
+
+#define AA_EXEC_MMAP		0x00010000
+#define AA_MAY_MPROT		0x00020000	/* extend conditions */
+#define AA_MAY_LINK		0x00040000	/* pair */
+#define AA_MAY_SNAPSHOT		0x00080000	/* pair */
+
+#define AA_MAY_DELEGATE
+#define AA_CONT_MATCH		0x08000000
+
+#define AA_MAY_STACK		0x10000000
+#define AA_MAY_ONEXEC		0x20000000 /* either stack or change_profile */
+#define AA_MAY_CHANGE_PROFILE	0x40000000
+#define AA_MAY_CHANGEHAT	0x80000000
+
+#define AA_LINK_SUBSET		AA_MAY_LOCK	/* overlaid */
+
+
+#define PERMS_CHRS_MASK (MAY_READ | MAY_WRITE | AA_MAY_CREATE |		\
+			 AA_MAY_DELETE | AA_MAY_LINK | AA_MAY_LOCK |	\
+			 AA_MAY_EXEC | AA_EXEC_MMAP | AA_MAY_APPEND)
+
+#define PERMS_NAMES_MASK (PERMS_CHRS_MASK | AA_MAY_OPEN | AA_MAY_RENAME |     \
+			  AA_MAY_SETATTR | AA_MAY_GETATTR | AA_MAY_SETCRED | \
+			  AA_MAY_GETCRED | AA_MAY_CHMOD | AA_MAY_CHOWN | \
+			  AA_MAY_CHGRP | AA_MAY_MPROT | AA_MAY_SNAPSHOT | \
+			  AA_MAY_STACK | AA_MAY_ONEXEC |		\
+			  AA_MAY_CHANGE_PROFILE | AA_MAY_CHANGEHAT)
+
+extern const char aa_file_perm_chrs[];
+extern const char *aa_file_perm_names[];
+
+
+struct aa_perms {
+	u32 allow;
+	u32 audit;	/* set only when allow is set */
+
+	u32 deny;	/* explicit deny, or conflict if allow also set */
+	u32 quiet;	/* set only when ~allow | deny */
+	u32 kill;	/* set only when ~allow | deny */
+	u32 stop;	/* set only when ~allow | deny */
+
+	u32 complain;	/* accumulates only used when ~allow & ~deny */
+	u32 cond;	/* set only when ~allow and ~deny */
+
+	u32 hide;	/* set only when  ~allow | deny */
+	u32 prompt;	/* accumulates only used when ~allow & ~deny */
+
+	/* Reserved:
+	 * u32 subtree;	/ * set only when allow is set * /
+	 */
+	u16 xindex;
+};
+
+#define ALL_PERMS_MASK 0xffffffff
+extern struct aa_perms nullperms;
+extern struct aa_perms allperms;
+
+
+#define xcheck(FN1, FN2)	\
+({				\
+	int e, error = FN1;	\
+	e = FN2;		\
+	if (e)			\
+		error = e;	\
+	error;			\
+})
+
+
+/*
+ * TODO: update for labels pointing to labels instead of profiles
+ * TODO: optimize the walk, currently does subwalk of L2 for each P in L1
+ * gah this doesn't allow for label compound check!!!!
+ */
+#define xcheck_ns_profile_profile(P1, P2, FN, args...)		\
+({								\
+	int ____e = 0;						\
+	if (P1->ns == P2->ns)					\
+		____e = FN((P1), (P2), args);			\
+	(____e);						\
+})
+
+#define xcheck_ns_profile_label(P, L, FN, args...)		\
+({								\
+	struct aa_profile *__p2;				\
+	fn_for_each((L), __p2,					\
+		    xcheck_ns_profile_profile((P), __p2, (FN), args));	\
+})
+
+#define xcheck_ns_labels(L1, L2, FN, args...)			\
+({								\
+	struct aa_profile *__p1;				\
+	fn_for_each((L1), __p1, FN(__p1, (L2), args));		\
+})
+
+/* Do the cross check but applying FN at the profiles level */
+#define xcheck_labels_profiles(L1, L2, FN, args...)		\
+	xcheck_ns_labels((L1), (L2), xcheck_ns_profile_label, (FN), args)
+
+
+#define FINAL_CHECK true
+
+void aa_perm_mask_to_str(char *str, const char *chrs, u32 mask);
+void aa_audit_perm_names(struct audit_buffer *ab, const char **names, u32 mask);
+void aa_audit_perm_mask(struct audit_buffer *ab, u32 mask, const char *chrs,
+			u32 chrsmask, const char **names, u32 namesmask);
+void aa_apply_modes_to_perms(struct aa_profile *profile,
+			     struct aa_perms *perms);
+void aa_compute_perms(struct aa_dfa *dfa, unsigned int state,
+		      struct aa_perms *perms);
+void aa_perms_accum(struct aa_perms *accum, struct aa_perms *addend);
+void aa_perms_accum_raw(struct aa_perms *accum, struct aa_perms *addend);
+void aa_profile_match_label(struct aa_profile *profile, struct aa_label *label,
+			    int type, u32 request, struct aa_perms *perms);
+int aa_profile_label_perm(struct aa_profile *profile, struct aa_profile *target,
+			  u32 request, int type, u32 *deny,
+			  struct common_audit_data *sa);
+int aa_check_perms(struct aa_profile *profile, struct aa_perms *perms,
+		   u32 request, struct common_audit_data *sa,
+		   void (*cb) (struct audit_buffer *, void *));
+
+
+static inline int aa_xlabel_perm(struct aa_profile *profile,
+				 struct aa_profile *target,
+				 int type, u32 request, u32 reverse,
+				 u32 * deny, struct common_audit_data *sa)
+{
+  /* TODO: ??? 2nd aa_profile_label_perm needs to reverse perms */
+	return xcheck(aa_profile_label_perm(profile, target, request, type,
+					    deny, sa),
+		      aa_profile_label_perm(target, profile, request /*??*/, type,
+					    deny, sa));
+}
+
+
+#endif /* __AA_PERM_H */
--- zfcpdump-kernel-4.4.orig/security/apparmor/include/policy.h
+++ zfcpdump-kernel-4.4/security/apparmor/include/policy.h
@@ -18,6 +18,7 @@
 #include <linux/capability.h>
 #include <linux/cred.h>
 #include <linux/kref.h>
+#include <linux/rhashtable.h>
 #include <linux/sched.h>
 #include <linux/slab.h>
 #include <linux/socket.h>
@@ -27,8 +28,15 @@
 #include "capability.h"
 #include "domain.h"
 #include "file.h"
+#include "label.h"
+#include "net.h"
+#include "perms.h"
 #include "resource.h"
 
+struct aa_ns;
+
+extern int unprivileged_userns_apparmor_policy;
+
 extern const char *const aa_profile_mode_names[];
 #define APPARMOR_MODE_NAMES_MAX_INDEX 4
 
@@ -40,9 +48,9 @@ extern const char *const aa_profile_mode
 
 #define KILL_MODE(_profile) PROFILE_MODE((_profile), APPARMOR_KILL)
 
-#define PROFILE_IS_HAT(_profile) ((_profile)->flags & PFLAG_HAT)
+#define PROFILE_IS_HAT(_profile) ((_profile)->label.flags & FLAG_HAT)
 
-#define PROFILE_INVALID(_profile) ((_profile)->flags & PFLAG_INVALID)
+#define profile_is_stale(_profile) (label_is_stale(&(_profile)->label))
 
 #define on_list_rcu(X) (!list_empty(X) && (X)->prev != LIST_POISON2)
 
@@ -59,86 +67,6 @@ enum profile_mode {
 	APPARMOR_UNCONFINED,	/* profile set to unconfined */
 };
 
-enum profile_flags {
-	PFLAG_HAT = 1,			/* profile is a hat */
-	PFLAG_NULL = 4,			/* profile is null learning profile */
-	PFLAG_IX_ON_NAME_ERROR = 8,	/* fallback to ix on name lookup fail */
-	PFLAG_IMMUTABLE = 0x10,		/* don't allow changes/replacement */
-	PFLAG_USER_DEFINED = 0x20,	/* user based profile - lower privs */
-	PFLAG_NO_LIST_REF = 0x40,	/* list doesn't keep profile ref */
-	PFLAG_OLD_NULL_TRANS = 0x100,	/* use // as the null transition */
-	PFLAG_INVALID = 0x200,		/* profile replaced/removed */
-	PFLAG_NS_COUNT = 0x400,		/* carries NS ref count */
-
-	/* These flags must correspond with PATH_flags */
-	PFLAG_MEDIATE_DELETED = 0x10000, /* mediate instead delegate deleted */
-};
-
-struct aa_profile;
-
-/* struct aa_policy - common part of both namespaces and profiles
- * @name: name of the object
- * @hname - The hierarchical name
- * @list: list policy object is on
- * @profiles: head of the profiles list contained in the object
- */
-struct aa_policy {
-	char *name;
-	char *hname;
-	struct list_head list;
-	struct list_head profiles;
-};
-
-/* struct aa_ns_acct - accounting of profiles in namespace
- * @max_size: maximum space allowed for all profiles in namespace
- * @max_count: maximum number of profiles that can be in this namespace
- * @size: current size of profiles
- * @count: current count of profiles (includes null profiles)
- */
-struct aa_ns_acct {
-	int max_size;
-	int max_count;
-	int size;
-	int count;
-};
-
-/* struct aa_namespace - namespace for a set of profiles
- * @base: common policy
- * @parent: parent of namespace
- * @lock: lock for modifying the object
- * @acct: accounting for the namespace
- * @unconfined: special unconfined profile for the namespace
- * @sub_ns: list of namespaces under the current namespace.
- * @uniq_null: uniq value used for null learning profiles
- * @uniq_id: a unique id count for the profiles in the namespace
- * @dents: dentries for the namespaces file entries in apparmorfs
- *
- * An aa_namespace defines the set profiles that are searched to determine
- * which profile to attach to a task.  Profiles can not be shared between
- * aa_namespaces and profile names within a namespace are guaranteed to be
- * unique.  When profiles in separate namespaces have the same name they
- * are NOT considered to be equivalent.
- *
- * Namespaces are hierarchical and only namespaces and profiles below the
- * current namespace are visible.
- *
- * Namespace names must be unique and can not contain the characters :/\0
- *
- * FIXME TODO: add vserver support of namespaces (can it all be done in
- *             userspace?)
- */
-struct aa_namespace {
-	struct aa_policy base;
-	struct aa_namespace *parent;
-	struct mutex lock;
-	struct aa_ns_acct acct;
-	struct aa_profile *unconfined;
-	struct list_head sub_ns;
-	atomic_t uniq_null;
-	long uniq_id;
-
-	struct dentry *dents[AAFS_NS_SIZEOF];
-};
 
 /* struct aa_policydb - match engine for a policy
  * dfa: dfa pattern match
@@ -151,43 +79,47 @@ struct aa_policydb {
 
 };
 
-struct aa_replacedby {
-	struct kref count;
-	struct aa_profile __rcu *profile;
+/* struct aa_data - generic data structure
+ * key: name for retrieving this data
+ * size: size of data in bytes
+ * data: binary data
+ * head: reserved for rhashtable
+ */
+struct aa_data {
+	char *key;
+	size_t size;
+	char *data;
+	struct rhash_head head;
 };
 
-
 /* struct aa_profile - basic confinement data
  * @base - base components of the profile (name, refcount, lists, lock ...)
- * @count: reference count of the obj
- * @rcu: rcu head used when removing from @list
+ * @label - label this profile is an extension of
  * @parent: parent of profile
  * @ns: namespace the profile is in
- * @replacedby: is set to the profile that replaced this profile
  * @rename: optional profile name that this profile renamed
  * @attach: human readable attachment string
  * @xmatch: optional extended matching for unconfined executables names
  * @xmatch_len: xmatch prefix len, used to determine xmatch priority
  * @audit: the auditing mode of the profile
  * @mode: the enforcement mode of the profile
- * @flags: flags controlling profile behavior
  * @path_flags: flags controlling path generation behavior
+ * @disconnected: what to prepend if attach_disconnected is specified
  * @size: the memory consumed by this profiles rules
  * @policy: general match rules governing policy
  * @file: The set of rules governing basic file access and domain transitions
  * @caps: capabilities for the profile
+ * @net: network controls for the profile
  * @rlimits: rlimits for the profile
- *
  * @dents: dentries for the profiles file entries in apparmorfs
  * @dirname: name of the profile dir in apparmorfs
+ * @data: hashtable for free-form policy aa_data
  *
  * The AppArmor profile contains the basic confinement data.  Each profile
  * has a name, and exists in a namespace.  The @name and @exec_match are
  * used to determine profile attachment against unconfined tasks.  All other
  * attachments are determined by profile X transition rules.
  *
- * The @replacedby struct is write protected by the profile lock.
- *
  * Profiles have a hierarchy where hats and children profiles keep
  * a reference to their parent.
  *
@@ -197,12 +129,9 @@ struct aa_replacedby {
  */
 struct aa_profile {
 	struct aa_policy base;
-	struct kref count;
-	struct rcu_head rcu;
 	struct aa_profile __rcu *parent;
 
-	struct aa_namespace *ns;
-	struct aa_replacedby *replacedby;
+	struct aa_ns *ns;
 	const char *rename;
 
 	const char *attach;
@@ -210,57 +139,94 @@ struct aa_profile {
 	int xmatch_len;
 	enum audit_mode audit;
 	long mode;
-	long flags;
 	u32 path_flags;
+	const char *disconnected;
 	int size;
 
 	struct aa_policydb policy;
 	struct aa_file_rules file;
 	struct aa_caps caps;
+	struct aa_net net;
 	struct aa_rlimit rlimits;
 
+	struct aa_loaddata *rawdata;
 	unsigned char *hash;
 	char *dirname;
 	struct dentry *dents[AAFS_PROF_SIZEOF];
+	struct rhashtable *data;
+	struct aa_label label;
 };
 
-extern struct aa_namespace *root_ns;
 extern enum profile_mode aa_g_profile_mode;
 
+#define AA_MAY_LOAD_POLICY	AA_MAY_APPEND
+#define AA_MAY_REPLACE_POLICY	AA_MAY_WRITE
+#define AA_MAY_REMOVE_POLICY	AA_MAY_DELETE
+
+#define profiles_ns(P) ((P)->ns)
+#define name_is_shared(A, B) ((A)->hname && (A)->hname == (B)->hname)
+
 void aa_add_profile(struct aa_policy *common, struct aa_profile *profile);
 
-bool aa_ns_visible(struct aa_namespace *curr, struct aa_namespace *view);
-const char *aa_ns_name(struct aa_namespace *parent, struct aa_namespace *child);
-int aa_alloc_root_ns(void);
-void aa_free_root_ns(void);
-void aa_free_namespace_kref(struct kref *kref);
-
-struct aa_namespace *aa_find_namespace(struct aa_namespace *root,
-				       const char *name);
 
+struct aa_label *aa_setup_default_label(void);
 
-void aa_free_replacedby_kref(struct kref *kref);
-struct aa_profile *aa_alloc_profile(const char *name);
-struct aa_profile *aa_new_null_profile(struct aa_profile *parent, int hat);
+struct aa_profile *aa_alloc_profile(const char *name, struct aa_proxy *proxy,
+				    gfp_t gfp);
+struct aa_profile *aa_null_profile(struct aa_profile *parent, bool hat,
+				   const char *base, gfp_t gfp);
 void aa_free_profile(struct aa_profile *profile);
 void aa_free_profile_kref(struct kref *kref);
 struct aa_profile *aa_find_child(struct aa_profile *parent, const char *name);
-struct aa_profile *aa_lookup_profile(struct aa_namespace *ns, const char *name);
-struct aa_profile *aa_match_profile(struct aa_namespace *ns, const char *name);
-
-ssize_t aa_replace_profiles(void *udata, size_t size, bool noreplace);
-ssize_t aa_remove_profiles(char *name, size_t size);
+struct aa_profile *aa_lookupn_profile(struct aa_ns *ns, const char *hname,
+				      size_t n);
+struct aa_profile *aa_lookup_profile(struct aa_ns *ns, const char *name);
+struct aa_profile *aa_fqlookupn_profile(struct aa_label *base,
+					const char *fqname, size_t n);
+struct aa_profile *aa_match_profile(struct aa_ns *ns, const char *name);
+
+ssize_t aa_replace_profiles(struct aa_ns *view, struct aa_label *label,
+			    u32 mask, struct aa_loaddata *udata);
+ssize_t aa_remove_profiles(struct aa_ns *view, struct aa_label *label,
+			   char *name, size_t size);
+void __aa_profile_list_release(struct list_head *head);
 
 #define PROF_ADD 1
 #define PROF_REPLACE 0
 
-#define unconfined(X) ((X)->mode == APPARMOR_UNCONFINED)
+#define profile_unconfined(X) ((X)->mode == APPARMOR_UNCONFINED)
 
-
-static inline struct aa_profile *aa_deref_parent(struct aa_profile *p)
+/**
+ * aa_get_newest_profile - simple wrapper fn to wrap the label version
+ * @p: profile (NOT NULL)
+ *
+ * Returns refcount to newest version of the profile (maybe @p)
+ *
+ * Requires: @p must be held with a valid refcount
+ */
+static inline struct aa_profile *aa_get_newest_profile(struct aa_profile *p)
 {
-	return rcu_dereference_protected(p->parent,
-					 mutex_is_locked(&p->ns->lock));
+	return labels_profile(aa_get_newest_label(&p->label));
+}
+
+#define PROFILE_MEDIATES(P, T)  ((P)->policy.start[(T)])
+/* safe version of POLICY_MEDIATES for full range input */
+static inline unsigned int PROFILE_MEDIATES_SAFE(struct aa_profile *profile,
+						 unsigned char class)
+{
+	if (profile->policy.dfa)
+		return aa_dfa_match_len(profile->policy.dfa,
+					profile->policy.start[0], &class, 1);
+	return 0;
+}
+
+static inline unsigned int PROFILE_MEDIATES_AF(struct aa_profile *profile,
+					       u16 AF) {
+	unsigned int state = PROFILE_MEDIATES(profile, AA_CLASS_NET);
+	u16 be_af = cpu_to_be16(AF);
+	if (!state)
+		return 0;
+	return aa_dfa_match_len(profile->policy.dfa, state, (char *) &be_af, 2);
 }
 
 /**
@@ -273,7 +239,7 @@ static inline struct aa_profile *aa_dere
 static inline struct aa_profile *aa_get_profile(struct aa_profile *p)
 {
 	if (p)
-		kref_get(&(p->count));
+		kref_get(&(p->label.count));
 
 	return p;
 }
@@ -287,7 +253,7 @@ static inline struct aa_profile *aa_get_
  */
 static inline struct aa_profile *aa_get_profile_not0(struct aa_profile *p)
 {
-	if (p && kref_get_not0(&p->count))
+	if (p && kref_get_not0(&p->label.count))
 		return p;
 
 	return NULL;
@@ -307,92 +273,20 @@ static inline struct aa_profile *aa_get_
 	rcu_read_lock();
 	do {
 		c = rcu_dereference(*p);
-	} while (c && !kref_get_not0(&c->count));
+	} while (c && !kref_get_not0(&c->label.count));
 	rcu_read_unlock();
 
 	return c;
 }
 
 /**
- * aa_get_newest_profile - find the newest version of @profile
- * @profile: the profile to check for newer versions of
- *
- * Returns: refcounted newest version of @profile taking into account
- *          replacement, renames and removals
- *          return @profile.
- */
-static inline struct aa_profile *aa_get_newest_profile(struct aa_profile *p)
-{
-	if (!p)
-		return NULL;
-
-	if (PROFILE_INVALID(p))
-		return aa_get_profile_rcu(&p->replacedby->profile);
-
-	return aa_get_profile(p);
-}
-
-/**
  * aa_put_profile - decrement refcount on profile @p
  * @p: profile  (MAYBE NULL)
  */
 static inline void aa_put_profile(struct aa_profile *p)
 {
 	if (p)
-		kref_put(&p->count, aa_free_profile_kref);
-}
-
-static inline struct aa_replacedby *aa_get_replacedby(struct aa_replacedby *p)
-{
-	if (p)
-		kref_get(&(p->count));
-
-	return p;
-}
-
-static inline void aa_put_replacedby(struct aa_replacedby *p)
-{
-	if (p)
-		kref_put(&p->count, aa_free_replacedby_kref);
-}
-
-/* requires profile list write lock held */
-static inline void __aa_update_replacedby(struct aa_profile *orig,
-					  struct aa_profile *new)
-{
-	struct aa_profile *tmp;
-	tmp = rcu_dereference_protected(orig->replacedby->profile,
-					mutex_is_locked(&orig->ns->lock));
-	rcu_assign_pointer(orig->replacedby->profile, aa_get_profile(new));
-	orig->flags |= PFLAG_INVALID;
-	aa_put_profile(tmp);
-}
-
-/**
- * aa_get_namespace - increment references count on @ns
- * @ns: namespace to increment reference count of (MAYBE NULL)
- *
- * Returns: pointer to @ns, if @ns is NULL returns NULL
- * Requires: @ns must be held with valid refcount when called
- */
-static inline struct aa_namespace *aa_get_namespace(struct aa_namespace *ns)
-{
-	if (ns)
-		aa_get_profile(ns->unconfined);
-
-	return ns;
-}
-
-/**
- * aa_put_namespace - decrement refcount on @ns
- * @ns: namespace to put reference of
- *
- * Decrement reference count of @ns and if no longer in use free it
- */
-static inline void aa_put_namespace(struct aa_namespace *ns)
-{
-	if (ns)
-		aa_put_profile(ns->unconfined);
+		kref_put(&p->label.count, aa_label_kref);
 }
 
 static inline int AUDIT_MODE(struct aa_profile *profile)
@@ -403,6 +297,9 @@ static inline int AUDIT_MODE(struct aa_p
 	return profile->audit;
 }
 
-bool aa_may_manage_policy(int op);
+bool policy_view_capable(struct aa_ns *ns);
+bool policy_admin_capable(struct aa_ns *ns);
+bool aa_may_open_profiles(void);
+int aa_may_manage_policy(struct aa_label *label, struct aa_ns *ns, u32 mask);
 
 #endif /* __AA_POLICY_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/security/apparmor/include/policy_ns.h
@@ -0,0 +1,150 @@
+/*
+ * AppArmor security module
+ *
+ * This file contains AppArmor policy definitions.
+ *
+ * Copyright (C) 1998-2008 Novell/SUSE
+ * Copyright 2009-2015 Canonical Ltd.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2 of the
+ * License.
+ */
+
+#ifndef __AA_NAMESPACE_H
+#define __AA_NAMESPACE_H
+
+#include <linux/kref.h>
+
+#include "apparmor.h"
+#include "apparmorfs.h"
+#include "label.h"
+#include "policy.h"
+
+
+/* struct aa_ns_acct - accounting of profiles in namespace
+ * @max_size: maximum space allowed for all profiles in namespace
+ * @max_count: maximum number of profiles that can be in this namespace
+ * @size: current size of profiles
+ * @count: current count of profiles (includes null profiles)
+ */
+struct aa_ns_acct {
+	int max_size;
+	int max_count;
+	int size;
+	int count;
+};
+
+/* struct aa_ns - namespace for a set of profiles
+ * @base: common policy
+ * @parent: parent of namespace
+ * @lock: lock for modifying the object
+ * @acct: accounting for the namespace
+ * @unconfined: special unconfined profile for the namespace
+ * @sub_ns: list of namespaces under the current namespace.
+ * @uniq_null: uniq value used for null learning profiles
+ * @uniq_id: a unique id count for the profiles in the namespace
+ * @dents: dentries for the namespaces file entries in apparmorfs
+ *
+ * An aa_ns defines the set profiles that are searched to determine which
+ * profile to attach to a task.  Profiles can not be shared between aa_ns
+ * and profile names within a namespace are guaranteed to be unique.  When
+ * profiles in separate namespaces have the same name they are NOT considered
+ * to be equivalent.
+ *
+ * Namespaces are hierarchical and only namespaces and profiles below the
+ * current namespace are visible.
+ *
+ * Namespace names must be unique and can not contain the characters :/\0
+ */
+struct aa_ns {
+	struct aa_policy base;
+	struct aa_ns *parent;
+	struct mutex lock;
+	struct aa_ns_acct acct;
+	struct aa_profile *unconfined;
+	struct list_head sub_ns;
+	atomic_t uniq_null;
+	long uniq_id;
+	int level;
+	struct aa_labelset labels;
+
+	struct dentry *dents[AAFS_NS_SIZEOF];
+};
+
+extern struct aa_ns *root_ns;
+
+extern const char *aa_hidden_ns_name;
+
+#define ns_unconfined(NS) (&(NS)->unconfined->label)
+
+bool aa_ns_visible(struct aa_ns *curr, struct aa_ns *view, bool subns);
+const char *aa_ns_name(struct aa_ns *parent, struct aa_ns *child, bool subns);
+void aa_free_ns(struct aa_ns *ns);
+int aa_alloc_root_ns(void);
+void aa_free_root_ns(void);
+void aa_free_ns_kref(struct kref *kref);
+
+struct aa_ns *aa_find_ns(struct aa_ns *root, const char *name);
+struct aa_ns *aa_findn_ns(struct aa_ns *root, const char *name, size_t n);
+struct aa_ns *aa_create_ns(struct aa_ns *parent, const char *name,
+			   struct dentry *dir);
+struct aa_ns *aa_prepare_ns(struct aa_ns *root, const char *name);
+void __aa_remove_ns(struct aa_ns *ns);
+
+static inline struct aa_profile *aa_deref_parent(struct aa_profile *p)
+{
+	return rcu_dereference_protected(p->parent,
+					 mutex_is_locked(&p->ns->lock));
+}
+
+/**
+ * aa_get_ns - increment references count on @ns
+ * @ns: namespace to increment reference count of (MAYBE NULL)
+ *
+ * Returns: pointer to @ns, if @ns is NULL returns NULL
+ * Requires: @ns must be held with valid refcount when called
+ */
+static inline struct aa_ns *aa_get_ns(struct aa_ns *ns)
+{
+	if (ns)
+		aa_get_profile(ns->unconfined);
+
+	return ns;
+}
+
+/**
+ * aa_put_ns - decrement refcount on @ns
+ * @ns: ns to put reference of
+ *
+ * Decrement reference count of @ns and if no longer in use free it
+ */
+static inline void aa_put_ns(struct aa_ns *ns)
+{
+	if (ns)
+		aa_put_profile(ns->unconfined);
+}
+
+/**
+ * __aa_findn_ns - find a namespace on a list by @name
+ * @head: list to search for namespace on  (NOT NULL)
+ * @name: name of namespace to look for  (NOT NULL)
+ * @n: length of @name
+ * Returns: unrefcounted namespace
+ *
+ * Requires: rcu_read_lock be held
+ */
+static inline struct aa_ns *__aa_findn_ns(struct list_head *head,
+					  const char *name, size_t n)
+{
+	return (struct aa_ns *)__policy_strn_find(head, name, n);
+}
+
+static inline struct aa_ns *__aa_find_ns(struct list_head *head,
+					 const char *name)
+{
+	return __aa_findn_ns(head, name, strlen(name));
+}
+
+#endif /* AA_NAMESPACE_H */
--- zfcpdump-kernel-4.4.orig/security/apparmor/include/policy_unpack.h
+++ zfcpdump-kernel-4.4/security/apparmor/include/policy_unpack.h
@@ -16,12 +16,14 @@
 #define __POLICY_INTERFACE_H
 
 #include <linux/list.h>
+#include <linux/kref.h>
 
 struct aa_load_ent {
 	struct list_head list;
 	struct aa_profile *new;
 	struct aa_profile *old;
 	struct aa_profile *rename;
+	const char *ns_name;
 };
 
 void aa_load_ent_free(struct aa_load_ent *ent);
@@ -34,6 +36,30 @@ struct aa_load_ent *aa_load_ent_alloc(vo
 #define PACKED_MODE_KILL	2
 #define PACKED_MODE_UNCONFINED	3
 
-int aa_unpack(void *udata, size_t size, struct list_head *lh, const char **ns);
+/* struct aa_loaddata - buffer of policy load data set */
+struct aa_loaddata {
+	struct kref count;
+	size_t size;
+	int abi;
+	unsigned char *hash;
+	char data[];
+};
+
+int aa_unpack(struct aa_loaddata *udata, struct list_head *lh, const char **ns);
+
+static inline struct aa_loaddata *
+aa_get_loaddata(struct aa_loaddata *data)
+{
+	if (data)
+		kref_get(&(data->count));
+	return data;
+}
+
+void aa_loaddata_kref(struct kref *kref);
+static inline void aa_put_loaddata(struct aa_loaddata *data)
+{
+	if (data)
+		kref_put(&data->count, aa_loaddata_kref);
+}
 
 #endif /* __POLICY_INTERFACE_H */
--- zfcpdump-kernel-4.4.orig/security/apparmor/include/procattr.h
+++ zfcpdump-kernel-4.4/security/apparmor/include/procattr.h
@@ -18,8 +18,7 @@
 #define AA_DO_TEST 1
 #define AA_ONEXEC  1
 
-int aa_getprocattr(struct aa_profile *profile, char **string);
+int aa_getprocattr(struct aa_label *label, char **string);
 int aa_setprocattr_changehat(char *args, size_t size, int test);
-int aa_setprocattr_changeprofile(char *fqname, bool onexec, int test);
 
 #endif /* __AA_PROCATTR_H */
--- zfcpdump-kernel-4.4.orig/security/apparmor/include/resource.h
+++ zfcpdump-kernel-4.4/security/apparmor/include/resource.h
@@ -37,10 +37,10 @@ struct aa_rlimit {
 extern struct aa_fs_entry aa_fs_entry_rlimit[];
 
 int aa_map_resource(int resource);
-int aa_task_setrlimit(struct aa_profile *profile, struct task_struct *,
+int aa_task_setrlimit(struct aa_label *label, struct task_struct *,
 		      unsigned int resource, struct rlimit *new_rlim);
 
-void __aa_transition_rlimits(struct aa_profile *old, struct aa_profile *new);
+void __aa_transition_rlimits(struct aa_label *old, struct aa_label *new);
 
 static inline void aa_free_rlimit_rules(struct aa_rlimit *rlims)
 {
--- /dev/null
+++ zfcpdump-kernel-4.4/security/apparmor/include/sig_names.h
@@ -0,0 +1,95 @@
+#include <linux/signal.h>
+
+#define SIGUNKNOWN 0
+#define MAXMAPPED_SIG 35
+/* provide a mapping of arch signal to internal signal # for mediation
+ * those that are always an alias SIGCLD for SIGCLHD and SIGPOLL for SIGIO
+ * map to the same entry those that may/or may not get a separate entry
+ */
+static const int sig_map[MAXMAPPED_SIG] = {
+	[0] = MAXMAPPED_SIG,	/* existance test */
+	[SIGHUP] = 1,
+	[SIGINT] = 2,
+	[SIGQUIT] = 3,
+	[SIGILL] = 4,
+	[SIGTRAP] = 5,		/* -, 5, - */
+	[SIGABRT] = 6,		/*  SIGIOT: -, 6, - */
+	[SIGBUS] = 7,		/* 10, 7, 10 */
+	[SIGFPE] = 8,
+	[SIGKILL] = 9,
+	[SIGUSR1] = 10,		/* 30, 10, 16 */
+	[SIGSEGV] = 11,
+	[SIGUSR2] = 12,		/* 31, 12, 17 */
+	[SIGPIPE] = 13,
+	[SIGALRM] = 14,
+	[SIGTERM] = 15,
+	[SIGSTKFLT] = 16,	/* -, 16, - */
+	[SIGCHLD] = 17,		/* 20, 17, 18.  SIGCHLD -, -, 18 */
+	[SIGCONT] = 18,		/* 19, 18, 25 */
+	[SIGSTOP] = 19,		/* 17, 19, 23 */
+	[SIGTSTP] = 20,		/* 18, 20, 24 */
+	[SIGTTIN] = 21,		/* 21, 21, 26 */
+	[SIGTTOU] = 22,		/* 22, 22, 27 */
+	[SIGURG] = 23,		/* 16, 23, 21 */
+	[SIGXCPU] = 24,		/* 24, 24, 30 */
+	[SIGXFSZ] = 25,		/* 25, 25, 31 */
+	[SIGVTALRM] = 26,	/* 26, 26, 28 */
+	[SIGPROF] = 27,		/* 27, 27, 29 */
+	[SIGWINCH] = 28,	/* 28, 28, 20 */
+	[SIGIO] = 29,		/* SIGPOLL: 23, 29, 22 */
+	[SIGPWR] = 30,		/* 29, 30, 19.  SIGINFO 29, -, - */
+#ifdef SIGSYS
+	[SIGSYS] = 31,		/* 12, 31, 12. often SIG LOST/UNUSED */
+#endif
+#ifdef SIGEMT
+	[SIGEMT] = 32,		/* 7, - , 7 */
+#endif
+#if defined(SIGLOST) && SIGPWR != SIGLOST		/* sparc */
+	[SIGLOST] = 33,		/* unused on Linux */
+#endif
+#if defined(SIGLOST) && defined(SIGSYS) && SIGLOST != SIGSYS
+	[SIGUNUSED] = 34,	/* -, 31, - */
+#endif
+};
+
+/* this table is ordered post sig_map[sig] mapping */
+static const char *const sig_names[MAXMAPPED_SIG + 1] = {
+	"unknown",
+	"hup",
+	"int",
+	"quit",
+	"ill",
+	"trap",
+	"abrt",
+	"bus",
+	"fpe",
+	"kill",
+	"usr1",
+	"segv",
+	"usr2",
+	"pipe",
+	"alrm",
+	"term",
+	"stkflt",
+	"chld",
+	"cont",
+	"stop",
+	"stp",
+	"ttin",
+	"ttou",
+	"urg",
+	"xcpu",
+	"xfsz",
+	"vtalrm",
+	"prof",
+	"winch",
+	"io",
+	"pwr",
+	"sys",
+	"emt",
+	"lost",
+	"unused",
+
+	"exists",	/* always last existance test mapped to MAXMAPPED_SIG */
+};
+
--- zfcpdump-kernel-4.4.orig/security/apparmor/ipc.c
+++ zfcpdump-kernel-4.4/security/apparmor/ipc.c
@@ -4,7 +4,7 @@
  * This file contains AppArmor ipc mediation
  *
  * Copyright (C) 1998-2008 Novell/SUSE
- * Copyright 2009-2010 Canonical Ltd.
+ * Copyright 2009-2013 Canonical Ltd.
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -20,92 +20,200 @@
 #include "include/context.h"
 #include "include/policy.h"
 #include "include/ipc.h"
+#include "include/sig_names.h"
+
+/**
+ * audit_ptrace_mask - convert mask to permission string
+ * @buffer: buffer to write string to (NOT NULL)
+ * @mask: permission mask to convert
+ */
+static void audit_ptrace_mask(struct audit_buffer *ab, u32 mask)
+{
+	switch (mask) {
+	case MAY_READ:
+		audit_log_string(ab, "read");
+		break;
+	case MAY_WRITE:
+		audit_log_string(ab, "trace");
+		break;
+	case AA_MAY_BE_READ:
+		audit_log_string(ab, "readby");
+		break;
+	case AA_MAY_BE_TRACED:
+		audit_log_string(ab, "tracedby");
+		break;
+	}
+}
 
 /* call back to audit ptrace fields */
-static void audit_cb(struct audit_buffer *ab, void *va)
+static void audit_ptrace_cb(struct audit_buffer *ab, void *va)
 {
 	struct common_audit_data *sa = va;
-	audit_log_format(ab, " target=");
-	audit_log_untrustedstring(ab, sa->aad->target);
+
+	if (aad(sa)->request & AA_PTRACE_PERM_MASK) {
+		audit_log_format(ab, " requested_mask=");
+		audit_ptrace_mask(ab, aad(sa)->request);
+
+		if (aad(sa)->denied & AA_PTRACE_PERM_MASK) {
+			audit_log_format(ab, " denied_mask=");
+			audit_ptrace_mask(ab, aad(sa)->denied);
+		}
+	}
+	audit_log_format(ab, " peer=");
+	aa_label_xaudit(ab, labels_ns(aad(sa)->label), aad(sa)->peer,
+			FLAGS_NONE, GFP_ATOMIC);
 }
 
-/**
- * aa_audit_ptrace - do auditing for ptrace
- * @profile: profile being enforced  (NOT NULL)
- * @target: profile being traced (NOT NULL)
- * @error: error condition
- *
- * Returns: %0 or error code
- */
-static int aa_audit_ptrace(struct aa_profile *profile,
-			   struct aa_profile *target, int error)
+/* TODO: conditionals */
+static int profile_ptrace_perm(struct aa_profile *profile,
+			       struct aa_profile *peer, u32 request,
+			       struct common_audit_data *sa)
 {
-	struct common_audit_data sa;
-	struct apparmor_audit_data aad = {0,};
-	sa.type = LSM_AUDIT_DATA_NONE;
-	sa.aad = &aad;
-	aad.op = OP_PTRACE;
-	aad.target = target;
-	aad.error = error;
+  struct aa_perms perms = { };
 
-	return aa_audit(AUDIT_APPARMOR_AUTO, profile, GFP_ATOMIC, &sa,
-			audit_cb);
+	/* need because of peer in cross check */
+	if (profile_unconfined(profile) ||
+	    !PROFILE_MEDIATES(profile, AA_CLASS_PTRACE))
+                return 0;
+
+	aad(sa)->peer = &peer->label;
+	aa_profile_match_label(profile, &peer->label, AA_CLASS_PTRACE, request,
+			       &perms);
+	aa_apply_modes_to_perms(profile, &perms);
+	return aa_check_perms(profile, &perms, request, sa, audit_ptrace_cb);
+}
+
+static int cross_ptrace_perm(struct aa_profile *tracer,
+			     struct aa_profile *tracee, u32 request,
+			     struct common_audit_data *sa)
+{
+	if (PROFILE_MEDIATES(tracer, AA_CLASS_PTRACE))
+		return xcheck(profile_ptrace_perm(tracer, tracee, request, sa),
+			      profile_ptrace_perm(tracee, tracer,
+						  request << PTRACE_PERM_SHIFT,
+						  sa));
+	/* policy uses the old style capability check for ptrace */
+	if (profile_unconfined(tracer) || tracer == tracee)
+		return 0;
+
+	aad(sa)->label = &tracer->label;
+	aad(sa)->peer = &tracee->label;
+	aad(sa)->request = 0;
+	aad(sa)->error = aa_capable(&tracer->label, CAP_SYS_PTRACE, 1);
+	return aa_audit(AUDIT_APPARMOR_AUTO, tracer, sa, audit_ptrace_cb);
 }
 
 /**
  * aa_may_ptrace - test if tracer task can trace the tracee
- * @tracer: profile of the task doing the tracing  (NOT NULL)
- * @tracee: task to be traced
- * @mode: whether PTRACE_MODE_READ || PTRACE_MODE_ATTACH
+ * @tracer: label of the task doing the tracing  (NOT NULL)
+ * @tracee: task label to be traced
+ * @request: permission request
  *
  * Returns: %0 else error code if permission denied or error
  */
-int aa_may_ptrace(struct aa_profile *tracer, struct aa_profile *tracee,
-		  unsigned int mode)
+int aa_may_ptrace(struct aa_label *tracer, struct aa_label *tracee,
+		  u32 request)
 {
-	/* TODO: currently only based on capability, not extended ptrace
-	 *       rules,
-	 *       Test mode for PTRACE_MODE_READ || PTRACE_MODE_ATTACH
-	 */
+	DEFINE_AUDIT_DATA(sa, LSM_AUDIT_DATA_NONE, OP_PTRACE);
 
-	if (unconfined(tracer) || tracer == tracee)
-		return 0;
-	/* log this capability request */
-	return aa_capable(tracer, CAP_SYS_PTRACE, 1);
+	return xcheck_labels_profiles(tracer, tracee, cross_ptrace_perm,
+				      request, &sa);
+}
+
+
+static inline int map_signal_num(int sig)
+{
+	if (sig > SIGRTMAX)
+		return SIGUNKNOWN;
+	else if (sig >= SIGRTMIN)
+		return sig - SIGRTMIN + 128;	/* rt sigs mapped to 128 */
+	else if (sig <= MAXMAPPED_SIG)
+		return sig_map[sig];
+	return SIGUNKNOWN;
 }
 
 /**
- * aa_ptrace - do ptrace permission check and auditing
- * @tracer: task doing the tracing (NOT NULL)
- * @tracee: task being traced (NOT NULL)
- * @mode: ptrace mode either PTRACE_MODE_READ || PTRACE_MODE_ATTACH
- *
- * Returns: %0 else error code if permission denied or error
+ * audit_file_mask - convert mask to permission string
+ * @buffer: buffer to write string to (NOT NULL)
+ * @mask: permission mask to convert
  */
-int aa_ptrace(struct task_struct *tracer, struct task_struct *tracee,
-	      unsigned int mode)
+static void audit_signal_mask(struct audit_buffer *ab, u32 mask)
 {
-	/*
-	 * tracer can ptrace tracee when
-	 * - tracer is unconfined ||
-	 *   - tracer is in complain mode
-	 *   - tracer has rules allowing it to trace tracee currently this is:
-	 *       - confined by the same profile ||
-	 *       - tracer profile has CAP_SYS_PTRACE
-	 */
-
-	struct aa_profile *tracer_p = aa_get_task_profile(tracer);
-	int error = 0;
-
-	if (!unconfined(tracer_p)) {
-		struct aa_profile *tracee_p = aa_get_task_profile(tracee);
+	if (mask & MAY_READ)
+		audit_log_string(ab, "receive");
+	if (mask & MAY_WRITE)
+		audit_log_string(ab, "send");
+}
 
-		error = aa_may_ptrace(tracer_p, tracee_p, mode);
-		error = aa_audit_ptrace(tracer_p, tracee_p, error);
+/**
+ * audit_cb - call back for signal specific audit fields
+ * @ab: audit_buffer  (NOT NULL)
+ * @va: audit struct to audit values of  (NOT NULL)
+ */
+static void audit_signal_cb(struct audit_buffer *ab, void *va)
+{
+	struct common_audit_data *sa = va;
 
-		aa_put_profile(tracee_p);
+	if (aad(sa)->request & AA_SIGNAL_PERM_MASK) {
+		audit_log_format(ab, " requested_mask=");
+		audit_signal_mask(ab, aad(sa)->request);
+		if (aad(sa)->denied & AA_SIGNAL_PERM_MASK) {
+			audit_log_format(ab, " denied_mask=");
+			audit_signal_mask(ab, aad(sa)->denied);
+		}
 	}
-	aa_put_profile(tracer_p);
+	if (aad(sa)->signal <= MAXMAPPED_SIG)
+		audit_log_format(ab, " signal=%s", sig_names[aad(sa)->signal]);
+	else
+		audit_log_format(ab, " signal=rtmin+%d",
+				 aad(sa)->signal - 128);
+	audit_log_format(ab, " peer=");
+	aa_label_xaudit(ab, labels_ns(aad(sa)->label), aad(sa)->peer,
+			FLAGS_NONE, GFP_ATOMIC);
+}
+
+/* TODO: update to handle compound name&name2, conditionals */
+static void profile_match_signal(struct aa_profile *profile, const char *label,
+				 int signal, struct aa_perms *perms)
+{
+	unsigned int state;
+	/* TODO: secondary cache check <profile, profile, perm> */
+	state = aa_dfa_next(profile->policy.dfa,
+			    profile->policy.start[AA_CLASS_SIGNAL],
+			    signal);
+	state = aa_dfa_match(profile->policy.dfa, state, label);
+	aa_compute_perms(profile->policy.dfa, state, perms);
+}
 
-	return error;
+static int profile_signal_perm(struct aa_profile *profile,
+			       struct aa_profile *peer, u32 request,
+			       struct common_audit_data *sa)
+{
+	struct aa_perms perms;
+
+	if (profile_unconfined(profile) ||
+	    !PROFILE_MEDIATES(profile, AA_CLASS_SIGNAL))
+		return 0;
+
+	aad(sa)->peer = &peer->label;
+	profile_match_signal(profile, aa_peer_name(peer), aad(sa)->signal,
+			     &perms);
+	aa_apply_modes_to_perms(profile, &perms);
+	return aa_check_perms(profile, &perms, request, sa, audit_signal_cb);
+}
+
+static int aa_signal_cross_perm(struct aa_profile *sender,
+				struct aa_profile *target,
+				struct common_audit_data *sa)
+{
+	return xcheck(profile_signal_perm(sender, target, MAY_WRITE, sa),
+		      profile_signal_perm(target, sender, MAY_READ, sa));
+}
+
+int aa_may_signal(struct aa_label *sender, struct aa_label *target, int sig)
+{
+	DEFINE_AUDIT_DATA(sa, LSM_AUDIT_DATA_NONE, OP_SIGNAL);
+	aad(&sa)->signal = map_signal_num(sig);
+	return xcheck_labels_profiles(sender, target, aa_signal_cross_perm,
+				      &sa);
 }
--- /dev/null
+++ zfcpdump-kernel-4.4/security/apparmor/label.c
@@ -0,0 +1,2105 @@
+/*
+ * AppArmor security module
+ *
+ * This file contains AppArmor label definitions
+ *
+ * Copyright 2013 Canonical Ltd.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2 of the
+ * License.
+ */
+
+#include <linux/audit.h>
+#include <linux/seq_file.h>
+#include <linux/sort.h>
+
+#include "include/apparmor.h"
+#include "include/context.h"
+#include "include/label.h"
+#include "include/policy.h"
+#include "include/sid.h"
+
+
+/*
+ * the aa_label represents the set of profiles confining an object
+ *
+ * Labels maintain a reference count to the set of pointers they reference
+ * Labels are ref counted by
+ *   tasks and object via the security field/security context off the field
+ *   code - will take a ref count on a label if it needs the label
+ *          beyond what is possible with an rcu_read_lock.
+ *   profiles - each profile is a label
+ *   sids - a pinned sid will keep a refcount of the label it is
+ *          referencing
+ *   objects - inode, files, sockets, ...
+ *
+ * Labels are not ref counted by the label set, so they maybe removed and
+ * freed when no longer in use.
+ *
+ */
+
+#define PROXY_POISON 97
+#define LABEL_POISON 100
+
+static void free_proxy(struct aa_proxy *proxy)
+{
+	if (proxy) {
+		/* p->label will not updated any more as p is dead */
+		aa_put_label(rcu_dereference_protected(proxy->label, true));
+		memset(proxy, 0, sizeof(*proxy));
+		proxy->label = (struct aa_label *) PROXY_POISON;
+		kfree(proxy);
+	}
+}
+
+void aa_proxy_kref(struct kref *kref)
+{
+	struct aa_proxy *proxy = container_of(kref, struct aa_proxy, count);
+	free_proxy(proxy);
+}
+
+struct aa_proxy *aa_alloc_proxy(struct aa_label *label, gfp_t gfp)
+{
+	struct aa_proxy *new;
+
+	new = kzalloc(sizeof(struct aa_proxy), gfp);
+	if (new) {
+		kref_init(&new->count);
+		rcu_assign_pointer(new->label, aa_get_label(label));
+	}
+	return new;
+}
+
+/* requires profile list write lock held */
+void __aa_proxy_redirect(struct aa_label *orig, struct aa_label *new)
+{
+	struct aa_label *tmp;
+
+	AA_BUG(!orig);
+	AA_BUG(!new);
+	AA_BUG(!write_is_locked(&labels_set(orig)->lock));
+
+	tmp = rcu_dereference_protected(orig->proxy->label,
+					&labels_ns(orig)->lock);
+	rcu_assign_pointer(orig->proxy->label, aa_get_label(new));
+	orig->flags |= FLAG_STALE;
+	aa_put_label(tmp);
+}
+
+static void __proxy_share(struct aa_label *old, struct aa_label *new)
+{
+	struct aa_proxy *proxy = new->proxy;
+	new->proxy = aa_get_proxy(old->proxy);
+	__aa_proxy_redirect(old, new);
+	aa_put_proxy(proxy);
+}
+
+
+/**
+ * ns_cmp - compare ns for label set ordering
+ * @a: ns to compare (NOT NULL)
+ * @b: ns to compare (NOT NULL)
+ *
+ * Returns: <0 if a < b
+ *          ==0 if a == b
+ *          >0  if a > b
+ */
+static int ns_cmp(struct aa_ns *a, struct aa_ns *b)
+{
+	int res;
+
+	AA_BUG(!a);
+	AA_BUG(!b);
+	AA_BUG(!a->base.hname);
+	AA_BUG(!b->base.hname);
+
+	if (a == b)
+		return 0;
+
+	res = a->level - b->level;
+	if (res)
+		return res;
+
+	return strcmp(a->base.hname, b->base.hname);
+}
+
+/**
+ * profile_cmp - profile comparision for set ordering
+ * @a: profile to compare (NOT NULL)
+ * @b: profile to compare (NOT NULL)
+ *
+ * Returns: <0  if a < b
+ *          ==0 if a == b
+ *          >0  if a > b
+ */
+static int profile_cmp(struct aa_profile *a, struct aa_profile *b)
+{
+	int res;
+
+	AA_BUG(!a);
+	AA_BUG(!b);
+	AA_BUG(!a->ns);
+	AA_BUG(!b->ns);
+	AA_BUG(!a->base.hname);
+	AA_BUG(!b->base.hname);
+
+	if (a == b || a->base.hname == b->base.hname)
+		return 0;
+	res = ns_cmp(a->ns, b->ns);
+	if (res)
+		return res;
+
+	return strcmp(a->base.hname, b->base.hname);
+}
+
+/**
+ * vec_cmp - label comparision for set ordering
+ * @a: label to compare (NOT NULL)
+ * @vec: vector of profiles to compare (NOT NULL)
+ * @n: length of @vec
+ *
+ * Returns: <0  if a < vec
+ *          ==0 if a == vec
+ *          >0  if a > vec
+ */
+static int vec_cmp(struct aa_profile **a, int an, struct aa_profile **b, int bn)
+{
+	int i;
+
+	AA_BUG(!a);
+	AA_BUG(!*a);
+	AA_BUG(!b);
+	AA_BUG(!*b);
+	AA_BUG(an <= 0);
+	AA_BUG(bn <= 0);
+
+	for (i = 0; i < an && i < bn; i++) {
+		int res = profile_cmp(a[i], b[i]);
+		if (res != 0)
+			return res;
+	}
+
+	return an - bn;
+}
+
+static bool vec_is_stale(struct aa_profile **vec, int n)
+{
+	int i;
+
+	AA_BUG(!vec);
+
+	for (i = 0; i < n; i++) {
+		if (profile_is_stale(vec[i]))
+			return true;
+	}
+
+	return false;
+}
+
+static bool vec_unconfined(struct aa_profile **vec, int n)
+{
+	int i;
+
+	AA_BUG(!vec);
+
+	for (i = 0; i < n; i++) {
+		if (!profile_unconfined(vec[i]))
+			return false;
+	}
+
+	return true;
+}
+
+static int sort_cmp(const void *a, const void *b)
+{
+	return profile_cmp(*(struct aa_profile **)a, *(struct aa_profile **)b);
+}
+
+/* assumes vec is sorted
+ * Assumes @vec has null terminator at vec[n], and will null terminate
+ * vec[n - dups]
+*/
+static inline int unique(struct aa_profile **vec, int n)
+{
+	int i, pos, dups = 0;
+
+	AA_BUG(n < 1);
+	AA_BUG(!vec);
+
+	pos = 0;
+	for (i = 1; i < n; i++) {
+		int res = profile_cmp(vec[pos], vec[i]);
+		AA_BUG(res > 0, "vec not sorted");
+		if (res == 0) {
+			/* drop duplicate */
+			aa_put_profile(vec[i]);
+			dups++;
+			continue;
+		}
+		pos++;
+		if (dups)
+			vec[pos] = vec[i];
+	}
+
+	AA_BUG(dups < 0);
+
+	return dups;
+}
+
+/**
+ * vec_unique - canonical sort and unique a list of profiles
+ * @n: number of refcounted profiles in the list (@n > 0)
+ * @vec: list of profiles to sort and merge
+ *
+ * Returns: the number of duplicates eliminated == references put
+ *
+ * If @flags & VEC_FLAG_TERMINATE @vec has null terminator at vec[n], and will
+ * null terminate vec[n - dups]
+ */
+int aa_vec_unique(struct aa_profile **vec, int n, int flags)
+{
+	int i, dups = 0;
+
+	AA_BUG(n < 1);
+	AA_BUG(!vec);
+
+	/* vecs are usually small and inorder, have a fallback for larger */
+	if (n > 8) {
+		sort(vec, n, sizeof(struct aa_profile *), sort_cmp, NULL);
+		dups = unique(vec, n);
+		goto out;
+	}
+
+	/* insertion sort + unique in one */
+	for (i = 1; i < n; i++) {
+		struct aa_profile *tmp = vec[i];
+		int pos, j;
+
+		for (pos = i - 1 - dups; pos >= 0; pos--) {
+			int res = profile_cmp(vec[pos], tmp);
+			if (res == 0) {
+				/* drop duplicate entry */
+				aa_put_profile(tmp);
+				dups++;
+				goto continue_outer;
+			} else if (res < 0)
+				break;
+		}
+		/* pos is at entry < tmp, or index -1. Set to insert pos */
+		pos++;
+
+		for (j = i - dups; j > pos; j--)
+			vec[j] = vec[j - 1];
+		vec[pos] = tmp;
+	continue_outer: ;
+	}
+
+	AA_BUG(dups < 0);
+
+out:
+	if (flags & VEC_FLAG_TERMINATE)
+		vec[n - dups] = NULL;
+
+	return dups;
+}
+
+
+static void label_destroy(struct aa_label *label)
+{
+	AA_BUG(!label);
+
+	if (label_is_stale(label))
+		labelsetstats_dec(labels_set(label), stale);
+
+	if (!label_isprofile(label)) {
+		struct aa_profile *profile;
+		struct label_it i;
+
+		aa_put_str(label->hname);
+
+		label_for_each(i, label, profile) {
+			aa_put_profile(profile);
+			label->vec[i.i] = (struct aa_profile *) (LABEL_POISON + (long) i.i);
+		}
+	}
+
+	if (rcu_dereference_protected(label->proxy->label, true) == label)
+		rcu_assign_pointer(label->proxy->label, NULL);
+
+	aa_free_sid(label->sid);
+	aa_put_proxy(label->proxy);
+	label->proxy = (struct aa_proxy *) PROXY_POISON + 1;
+}
+
+void aa_label_free(struct aa_label *label)
+{
+	if (!label)
+		return;
+
+	label_destroy(label);
+	labelstats_inc(freed);
+	kfree(label);
+}
+
+static void label_free_switch(struct aa_label *label)
+{
+	if (label->flags & FLAG_NS_COUNT)
+		aa_free_ns(labels_ns(label));
+	else if (label_isprofile(label))
+		aa_free_profile(labels_profile(label));
+	else
+		aa_label_free(label);
+}
+
+static void label_free_rcu(struct rcu_head *head)
+{
+	struct aa_label *label = container_of(head, struct aa_label, rcu);
+
+	if (label->flags & FLAG_IN_TREE)
+		(void) aa_label_remove(label);
+	label_free_switch(label);
+}
+
+void aa_label_kref(struct kref *kref)
+{
+	struct aa_label *label = container_of(kref, struct aa_label, count);
+	struct aa_ns *ns = labels_ns(label);
+
+	if (!ns) {
+		/* never live, no rcu callback needed, just using the fn */
+		label_free_switch(label);
+		return;
+	}
+	/* TODO: update labels_profile macro so it works here */
+	AA_BUG(label_isprofile(label) && on_list_rcu(&label->vec[0]->base.profiles));
+	AA_BUG(label_isprofile(label) && on_list_rcu(&label->vec[0]->base.list));
+
+	/* TODO: if compound label and not stale add to reclaim cache */
+	call_rcu(&label->rcu, label_free_rcu);
+}
+
+bool aa_label_init(struct aa_label *label, int size)
+{
+	AA_BUG(!label);
+	AA_BUG(size < 1);
+
+	label->sid = aa_alloc_sid();
+	if (label->sid == AA_SID_INVALID)
+		return false;
+
+	label->size = size;			/* doesn't include null */
+	label->vec[size] = NULL;		/* null terminate */
+	kref_init(&label->count);
+	RB_CLEAR_NODE(&label->node);
+
+	return true;
+}
+
+/**
+ * aa_label_alloc - allocate a label with a profile vector of @size length
+ * @size: size of profile vector in the label
+ * @proxy: proxy to use OR null if to allocate a new one
+ * @gfp: memory allocation type
+ *
+ * Returns: new label
+ *     else NULL if failed
+ */
+struct aa_label *aa_label_alloc(int size, struct aa_proxy *proxy, gfp_t gfp)
+{
+	struct aa_label *new;
+
+	AA_BUG(size < 1);
+
+	/*  + 1 for null terminator entry on vec */
+	new = kzalloc(sizeof(*new) + sizeof(struct aa_profile *) * (size + 1),
+			gfp);
+	AA_DEBUG("%s (%p)\n", __func__, new);
+	if (!new)
+		goto fail;
+
+	if (!aa_label_init(new, size))
+		goto fail;
+
+	if (!proxy) {
+		proxy = aa_alloc_proxy(new, gfp);
+		if (!proxy)
+			goto fail;
+	} else
+		aa_get_proxy(proxy);
+	/* just set new's proxy, don't redirect proxy here if it was passed in*/
+	new->proxy = proxy;
+
+	labelstats_inc(allocated);
+
+	return new;
+
+fail:
+	kfree(new);
+	labelstats_inc(failed);
+
+	return NULL;
+}
+
+
+/**
+ * label_cmp - label comparision for set ordering
+ * @a: label to compare (NOT NULL)
+ * @b: label to compare (NOT NULL)
+ *
+ * Returns: <0  if a < b
+ *          ==0 if a == b
+ *          >0  if a > b
+ */
+static int label_cmp(struct aa_label *a, struct aa_label *b)
+{
+	AA_BUG(!b);
+
+	if (a == b)
+		return 0;
+
+	return vec_cmp(a->vec, a->size, b->vec, b->size);
+}
+
+/* helper fn for label_for_each_confined */
+int aa_label_next_confined(struct aa_label *label, int i)
+{
+	AA_BUG(!label);
+	AA_BUG(i < 0);
+
+	for (; i < label->size; i++) {
+		if (!profile_unconfined(label->vec[i]))
+			return i;
+	}
+
+	return i;
+}
+
+/**
+ * aa_label_next_not_in_set - return the next profile of @sub not in @set
+ * @I: label iterator
+ * @set: label to test against
+ * @sub: label to if is subset of @set
+ *
+ * Returns: profile in @sub that is not in @set, with iterator set pos after
+ *     else NULL if @sub is a subset of @set
+ */
+struct aa_profile *__aa_label_next_not_in_set(struct label_it *I,
+					      struct aa_label *set,
+					      struct aa_label *sub)
+{
+	AA_BUG(!set);
+	AA_BUG(!I);
+	AA_BUG(I->i < 0);
+	AA_BUG(I->i > set->size);
+	AA_BUG(!sub);
+	AA_BUG(I->j < 0);
+	AA_BUG(I->j > sub->size);
+
+	while (I->j < sub->size && I->i < set->size) {
+		int res = profile_cmp(sub->vec[I->j], set->vec[I->i]);
+		if (res == 0) {
+			(I->j)++;
+			(I->i)++;
+		} else if (res > 0)
+			(I->i)++;
+		else
+			return sub->vec[(I->j)++];
+	}
+
+	if (I->j < sub->size)
+		return sub->vec[(I->j)++];
+
+	return NULL;
+}
+
+/**
+ * aa_label_is_subset - test if @sub is a subset of @set
+ * @set: label to test against
+ * @sub: label to test if is subset of @set
+ *
+ * Returns: true if @sub is subset of @set
+ *     else false
+ */
+bool aa_label_is_subset(struct aa_label *set, struct aa_label *sub)
+{
+	struct label_it i = { };
+
+	AA_BUG(!set);
+	AA_BUG(!sub);
+
+	if (sub == set)
+		return true;
+
+	return __aa_label_next_not_in_set(&i, set, sub) == NULL;
+}
+
+
+
+/**
+ * __label_remove - remove @label from the label set
+ * @l: label to remove
+ * @new: label to redirect to
+ *
+ * Requires: labels_set(@label)->lock write_lock
+ * Returns:  true if the label was in the tree and removed
+ */
+static bool __label_remove(struct aa_label *label, struct aa_label *new)
+{
+	struct aa_labelset *ls = labels_set(label);
+	AA_BUG(!ls);
+	AA_BUG(!label);
+	AA_BUG(!write_is_locked(&ls->lock));
+
+	if (new)
+		__aa_proxy_redirect(label, new);
+
+	if (label_is_stale(label))
+		labelstats_dec(stale_intree);
+	else
+		__label_make_stale(label);
+
+	if (label->flags & FLAG_IN_TREE) {
+		labelsetstats_dec(ls, intree);
+		rb_erase(&label->node, &ls->root);
+		label->flags &= ~FLAG_IN_TREE;
+		return true;
+	}
+
+	return false;
+}
+
+/**
+ * __label_replace - replace @old with @new in label set
+ * @old: label to remove from label set
+ * @new: label to replace @old with
+ *
+ * Requires: labels_set(@old)->lock write_lock
+ *           valid ref count be held on @new
+ * Returns: true if @old was in set and replaced by @new
+ *
+ * Note: current implementation requires label set be order in such a way
+ *       that @new directly replaces @old position in the set (ie.
+ *       using pointer comparison of the label address would not work)
+ */
+static bool __label_replace(struct aa_label *old, struct aa_label *new)
+{
+	struct aa_labelset *ls = labels_set(old);
+	AA_BUG(!ls);
+	AA_BUG(!old);
+	AA_BUG(!new);
+	AA_BUG(!write_is_locked(&ls->lock));
+	AA_BUG(new->flags & FLAG_IN_TREE);
+
+	if (label_is_stale(old))
+		labelstats_dec(stale_intree);
+	else
+		__label_make_stale(old);
+
+	if (old->flags & FLAG_IN_TREE) {
+		rb_replace_node(&old->node, &new->node, &ls->root);
+		old->flags &= ~FLAG_IN_TREE;
+		new->flags |= FLAG_IN_TREE;
+		return true;
+	}
+
+	return false;
+}
+
+/**
+ * __label_insert - attempt to insert @l into a label set
+ * @ls: set of labels to insert @l into (NOT NULL)
+ * @label: new label to insert (NOT NULL)
+ * @replace: whether insertion should replace existing entry that is not stale
+ *
+ * Requires: @ls->lock
+ *           caller to hold a valid ref on l
+ *           if @replace is true l has a preallocated proxy associated
+ * Returns: @l if successful in inserting @l - with additional refcount
+ *          else ref counted equivalent label that is already in the set,
+            the else condition only happens if @replace is false
+ */
+static struct aa_label *__label_insert(struct aa_labelset *ls,
+				       struct aa_label *label, bool replace)
+{
+	struct rb_node **new, *parent = NULL;
+
+	AA_BUG(!ls);
+	AA_BUG(!label);
+	AA_BUG(labels_set(label) != ls);
+	AA_BUG(!write_is_locked(&ls->lock));
+	AA_BUG(label->flags & FLAG_IN_TREE);
+
+	/* Figure out where to put new node */
+	new = &ls->root.rb_node;
+	while (*new) {
+		struct aa_label *this = rb_entry(*new, struct aa_label, node);
+		int result = label_cmp(label, this);
+
+		parent = *new;
+		if (result == 0) {
+			labelsetstats_inc(ls, existing);
+			/* !aa_get_label_not0 means queued for destruction,
+			 * so replace in place, however the label has
+			 * died before the replacement so do not share
+			 * the proxy
+			 */
+			if (!replace && !label_is_stale(this)) {
+				if (aa_get_label_not0(this))
+					return this;
+			} else
+				__proxy_share(this, label);
+			AA_BUG(!__label_replace(this, label));
+			return aa_get_label(label);
+		} else if (result < 0)
+			new = &((*new)->rb_left);
+		else /* (result > 0) */
+			new = &((*new)->rb_right);
+	}
+
+	/* Add new node and rebalance tree. */
+	rb_link_node(&label->node, parent, new);
+	rb_insert_color(&label->node, &ls->root);
+	label->flags |= FLAG_IN_TREE;
+	labelsetstats_inc(ls, insert);
+	labelsetstats_inc(ls, intree);
+
+	return aa_get_label(label);
+}
+
+/**
+ * __vec_find - find label that matches @vec in label set
+ * @vec: vec of profiles to find matching label for (NOT NULL)
+ * @n: length of @vec
+ *
+ * Requires: @vec_labelset(vec) lock held
+ *           caller to hold a valid ref on l
+ *
+ * Returns: ref counted @label if matching label is in tree
+ *          ref counted label that is equiv to @l in tree
+ *     else NULL if @vec equiv is not in tree
+ */
+static struct aa_label *__vec_find(struct aa_profile **vec, int n)
+{
+	struct rb_node *node;
+
+	AA_BUG(!vec);
+	AA_BUG(!*vec);
+	AA_BUG(n <= 0);
+
+	node = vec_labelset(vec, n)->root.rb_node;
+	while (node) {
+		struct aa_label *this = rb_entry(node, struct aa_label, node);
+		int result = vec_cmp(this->vec, this->size, vec, n);
+
+		if (result > 0)
+			node = node->rb_left;
+		else if (result < 0)
+			node = node->rb_right;
+		else
+			return aa_get_label_not0(this);
+	}
+
+	return NULL;
+}
+
+/**
+ * __label_find - find label @label in label set
+ * @label: label to find (NOT NULL)
+ *
+ * Requires: labels_set(@label)->lock held
+ *           caller to hold a valid ref on l
+ *
+ * Returns: ref counted @label if @label is in tree OR
+ *          ref counted label that is equiv to @label in tree
+ *     else NULL if @label or equiv is not in tree
+ */
+static struct aa_label *__label_find(struct aa_label *label)
+{
+	AA_BUG(!label);
+
+	return __vec_find(label->vec, label->size);
+}
+
+
+/**
+ * aa_label_remove - remove a label from the labelset
+ * @label: label to remove
+ *
+ * Returns: true if @label was removed from the tree
+ *     else @label was not in tree so it could not be removed
+ */
+bool aa_label_remove(struct aa_label *label)
+{
+	struct aa_labelset *ls = labels_set(label);
+	unsigned long flags;
+	bool res;
+
+	AA_BUG(!ls);
+
+	write_lock_irqsave(&ls->lock, flags);
+	res = __label_remove(label, ns_unconfined(labels_ns(label)));
+	write_unlock_irqrestore(&ls->lock, flags);
+
+	return res;
+}
+
+/**
+ * aa_label_replace - replace a label @old with a new version @new
+ * @old: label to replace
+ * @new: label replacing @old
+ *
+ * Returns: true if @old was in tree and replaced
+ *     else @old was not in tree, and @new was not inserted
+ */
+bool aa_label_replace(struct aa_label *old, struct aa_label *new)
+{
+	unsigned long flags;
+	bool res;
+
+	if (name_is_shared(old, new) && labels_ns(old) == labels_ns(new)) {
+		write_lock_irqsave(&labels_set(old)->lock, flags);
+		if (old->proxy != new->proxy) {
+			__proxy_share(old, new);
+		} else
+			__aa_proxy_redirect(old, new);
+		res = __label_replace(old, new);
+		write_unlock_irqrestore(&labels_set(old)->lock, flags);
+	} else {
+		struct aa_label *l;
+		struct aa_labelset *ls = labels_set(old);
+		write_lock_irqsave(&ls->lock, flags);
+		res = __label_remove(old, new);
+		if (labels_ns(old) != labels_ns(new)) {
+			write_unlock_irqrestore(&ls->lock, flags);
+			ls = labels_set(new);
+			write_lock_irqsave(&ls->lock, flags);
+		}
+		l = __label_insert(ls, new, true);
+		res = (l == new);
+		write_unlock_irqrestore(&ls->lock, flags);
+		aa_put_label(l);
+	}
+
+	return res;
+}
+
+/**
+ * vec_find - find label @l in label set
+ * @vec: array of profiles to find equiv label for (NOT NULL)
+ * @n: length of @vec
+ *
+ * Returns: refcounted label if @vec equiv is in tree
+ *     else NULL if @vec equiv is not in tree
+ */
+static struct aa_label *vec_find(struct aa_profile **vec, int n)
+{
+	struct aa_labelset *ls;
+	struct aa_label *label;
+	unsigned long flags;
+
+	AA_BUG(!vec);
+	AA_BUG(!*vec);
+	AA_BUG(n <= 0);
+
+	ls = vec_labelset(vec, n);
+	read_lock_irqsave(&ls->lock, flags);
+	label = __vec_find(vec, n);
+	labelstats_inc(sread);
+	read_unlock_irqrestore(&ls->lock, flags);
+
+	return label;
+}
+
+/* requires sort and merge done first */
+static struct aa_label *vec_create_and_insert_label(struct aa_profile **vec,
+						    int len, gfp_t gfp)
+{
+	struct aa_label *label = NULL;
+	struct aa_labelset *ls;
+	unsigned long flags;
+	struct aa_label *new;
+	int i;
+
+	AA_BUG(!vec);
+
+	if (len == 1)
+		return aa_get_label(&vec[0]->label);
+
+	ls = labels_set(&vec[len - 1]->label);
+
+	/* TODO: enable when read side is lockless
+	 * check if label exists before taking locks
+	 */
+	new = aa_label_alloc(len, NULL, gfp);
+	if (!new)
+		return NULL;
+
+	for (i = 0; i < len; i++) {
+		new->vec[i] = aa_get_profile(vec[i]);
+	}
+	write_lock_irqsave(&ls->lock, flags);
+	label = __label_insert(ls, new, false);
+	write_unlock_irqrestore(&ls->lock, flags);
+	aa_put_label(new);
+
+	return label;
+}
+
+struct aa_label *aa_vec_find_or_create_label(struct aa_profile **vec, int len,
+					     gfp_t gfp)
+{
+	struct aa_label *label = vec_find(vec, len);
+	if (label)
+		return label;
+
+	return vec_create_and_insert_label(vec, len, gfp);
+}
+
+/**
+ * aa_label_find - find label @label in label set
+ * @label: label to find (NOT NULL)
+ *
+ * Requires: caller to hold a valid ref on l
+ *
+ * Returns: refcounted @label if @label is in tree
+ *          refcounted label that is equiv to @label in tree
+ *     else NULL if @label or equiv is not in tree
+ */
+struct aa_label *aa_label_find(struct aa_label *label)
+{
+	AA_BUG(!label);
+
+	return vec_find(label->vec, label->size);
+}
+
+
+/**
+ * aa_label_insert - insert label @label into @ls or return existing label
+ * @ls - labelset to insert @label into
+ * @label - label to insert
+ *
+ * Requires: caller to hold a valid ref on @label
+ *
+ * Returns: ref counted @label if successful in inserting @label
+ *     else ref counted equivalent label that is already in the set
+ */
+struct aa_label *aa_label_insert(struct aa_labelset *ls, struct aa_label *label)
+{
+	struct aa_label *l;
+	unsigned long flags;
+
+	AA_BUG(!ls);
+	AA_BUG(!label);
+
+	/* check if label exists before taking lock */
+	if (!label_is_stale(label)) {
+		read_lock_irqsave(&ls->lock, flags);
+		l = __label_find(label);
+		read_unlock_irqrestore(&ls->lock, flags);
+		labelstats_inc(fread);
+		if (l)
+			return l;
+	}
+
+	write_lock_irqsave(&ls->lock, flags);
+	l = __label_insert(ls, label, false);
+	write_unlock_irqrestore(&ls->lock, flags);
+
+	return l;
+}
+
+
+/**
+ * aa_label_next_in_merge - find the next profile when merging @a and @b
+ * @I: label iterator
+ * @a: label to merge
+ * @b: label to merge
+ *
+ * Returns: next profile
+ *     else null if no more profiles
+ */
+struct aa_profile *aa_label_next_in_merge(struct label_it *I,
+					  struct aa_label *a,
+					  struct aa_label *b)
+{
+	AA_BUG(!a);
+	AA_BUG(!b);
+	AA_BUG(!I);
+	AA_BUG(I->i < 0);
+	AA_BUG(I->i > a->size);
+	AA_BUG(I->j < 0);
+	AA_BUG(I->j > b->size);
+
+	if (I->i < a->size) {
+		if (I->j < b->size) {
+			int res = profile_cmp(a->vec[I->i], b->vec[I->j]);
+			if (res > 0)
+				return b->vec[(I->j)++];
+			if (res == 0)
+				(I->j)++;
+		}
+
+		return a->vec[(I->i)++];
+	}
+
+	if (I->j < b->size)
+		return b->vec[(I->j)++];
+
+	return NULL;
+}
+
+/**
+ * label_merge_cmp - cmp of @a merging with @b against @z for set ordering
+ * @a: label to merge then compare (NOT NULL)
+ * @b: label to merge then compare (NOT NULL)
+ * @z: label to compare merge against (NOT NULL)
+ *
+ * Assumes: using the most recent versions of @a, @b, and @z
+ *
+ * Returns: <0  if a < b
+ *          ==0 if a == b
+ *          >0  if a > b
+ */
+static int label_merge_cmp(struct aa_label *a, struct aa_label *b,
+                           struct aa_label *z)
+{
+	struct aa_profile *p = NULL;
+	struct label_it i = { };
+	int k;
+
+	AA_BUG(!a);
+	AA_BUG(!b);
+	AA_BUG(!z);
+
+	for (k = 0;
+	     k < z->size && (p = aa_label_next_in_merge(&i, a, b));
+	     k++) {
+		int res = profile_cmp(p, z->vec[k]);
+
+		if (res != 0)
+			return res;
+	}
+
+	if (p)
+		return 1;
+	else if (k < z->size)
+		return -1;
+	return 0;
+}
+
+#if 0
+/**
+ * label_merge_len - find the length of the merge of @a and @b
+ * @a: label to merge (NOT NULL)
+ * @b: label to merge (NOT NULL)
+ *
+ * Assumes: using newest versions of labels @a and @b
+ *
+ * Returns: length of a label vector for merge of @a and @b
+ */
+static int label_merge_len(struct aa_label *a, struct aa_label *b)
+{
+	int len = a->size + b->size;
+	int i, j;
+
+	AA_BUG(!a);
+	AA_BUG(!b);
+
+	/* find entries in common and remove from count */
+	for (i = j = 0; i < a->size && j < b->size; ) {
+		int res = profile_cmp(a->vec[i], b->vec[j]);
+		if (res == 0) {
+			len--;
+			i++;
+			j++;
+		} else if (res < 0)
+			i++;
+		else
+			j++;
+	}
+
+	return len;
+}
+#endif
+
+/**
+ * label_merge_insert - create a new label by merging @a and @b
+ * @new: preallocated label to merge into (NOT NULL)
+ * @a: label to merge with @b  (NOT NULL)
+ * @b: label to merge with @a  (NOT NULL)
+ *
+ * Requires: preallocated proxy
+ *
+ * Returns: ref counted label either @new if merge is unique
+ *          @a if @b is a subset of @a
+ *          @b if @a is a subset of @b
+ *
+ * NOTE: will not use @new if the merge results in @new == @a or @b
+ *
+ *       Must be used within labelset write lock to avoid racing with
+ *       setting labels stale.
+ */
+static struct aa_label *label_merge_insert(struct aa_label *new,
+					   struct aa_label *a,
+					   struct aa_label *b)
+{
+	struct aa_label *label;
+	struct aa_labelset *ls;
+	struct aa_profile *next;
+	struct label_it i;
+	unsigned long flags;
+	int k = 0, invcount = 0;
+	bool stale = false;
+
+	AA_BUG(!a);
+	AA_BUG(a->size < 0);
+	AA_BUG(!b);
+	AA_BUG(b->size < 0);
+	AA_BUG(!new);
+	AA_BUG(new->size < a->size + b->size);
+
+	label_for_each_in_merge(i, a, b, next) {
+		AA_BUG(!next);
+		if (profile_is_stale(next)) {
+			new->vec[k] = aa_get_newest_profile(next);
+			AA_BUG(!new->vec[k]->label.proxy);
+			AA_BUG(!new->vec[k]->label.proxy->label);
+			if (next->label.proxy != new->vec[k]->label.proxy)
+				invcount++;
+			k++;
+			stale = true;
+		} else
+			new->vec[k++] = aa_get_profile(next);
+	}
+	/* set to actual size which is <= allocated len */
+	new->size = k;
+	new->vec[k] = NULL;
+
+	if (invcount) {
+		new->size -= aa_vec_unique(&new->vec[0], new->size,
+					   VEC_FLAG_TERMINATE);
+		/* TODO: deal with reference labels */
+		if (new->size == 1) {
+			label = aa_get_label(&new->vec[0]->label);
+			aa_put_label(new);
+			return label;
+		}
+	} else if (!stale) {
+		/* merge could be same as a || b, note: it is not possible
+		 * for new->size == a->size == b->size unless a == b */
+		if (k == a->size)
+			return aa_get_label(a);
+		else if (k == b->size)
+			return aa_get_label(b);
+	}
+	if (vec_unconfined(new->vec, new->size))
+		new->flags |= FLAG_UNCONFINED;
+	ls = labels_set(new);
+	write_lock_irqsave(&ls->lock, flags);
+	label = __label_insert(labels_set(new), new, false);
+	write_unlock_irqrestore(&ls->lock, flags);
+
+	return label;
+}
+
+/**
+ * labelset_of_merge - find into which labelset a merged label should be inserted
+ * @a: label to merge and insert
+ * @b: label to merge and insert
+ *
+ * Returns: labelset that the merged label should be inserted into
+ */
+static struct aa_labelset *labelset_of_merge(struct aa_label *a, struct aa_label *b)
+{
+	struct aa_ns *nsa = labels_ns(a);
+	struct aa_ns *nsb = labels_ns(b);
+
+	if (ns_cmp(nsa, nsb) <= 0)
+		return &nsa->labels;
+	return &nsb->labels;
+}
+
+/**
+ * __label_find_merge - find label that is equiv to merge of @a and @b
+ * @ls: set of labels to search (NOT NULL)
+ * @a: label to merge with @b  (NOT NULL)
+ * @b: label to merge with @a  (NOT NULL)
+ *
+ * Requires: ls->lock read_lock held
+ *
+ * Returns: ref counted label that is equiv to merge of @a and @b
+ *     else NULL if merge of @a and @b is not in set
+ */
+static struct aa_label *__label_find_merge(struct aa_labelset *ls,
+					   struct aa_label *a,
+					   struct aa_label *b)
+{
+	struct rb_node *node;
+
+	AA_BUG(!ls);
+	AA_BUG(!a);
+	AA_BUG(!b);
+
+	if (a == b)
+		return __label_find(a);
+
+	node  = ls->root.rb_node;
+	while (node) {
+		struct aa_label *this = container_of(node, struct aa_label,
+						     node);
+		int result = label_merge_cmp(a, b, this);
+
+		if (result < 0)
+			node = node->rb_left;
+		else if (result > 0)
+			node = node->rb_right;
+		else
+			return aa_get_label_not0(this);
+	}
+
+	return NULL;
+}
+
+
+/**
+ * aa_label_find_merge - find label that is equiv to merge of @a and @b
+ * @a: label to merge with @b  (NOT NULL)
+ * @b: label to merge with @a  (NOT NULL)
+ *
+ * Requires: labels be fully constructed with a valid ns
+ *
+ * Returns: ref counted label that is equiv to merge of @a and @b
+ *     else NULL if merge of @a and @b is not in set
+ */
+struct aa_label *aa_label_find_merge(struct aa_label *a, struct aa_label *b)
+{
+	struct aa_labelset *ls;
+	struct aa_label *label, *ar = NULL, *br = NULL;
+	unsigned long flags;
+
+	AA_BUG(!a);
+	AA_BUG(!b);
+
+	if (label_is_stale(a))
+		a = ar = aa_get_newest_label(a);
+	if (label_is_stale(b))
+		b = br = aa_get_newest_label(b);
+	ls = labelset_of_merge(a, b);
+	read_lock_irqsave(&ls->lock, flags);
+	label = __label_find_merge(ls, a, b);
+	read_unlock_irqrestore(&ls->lock, flags);
+	aa_put_label(ar);
+	aa_put_label(br);
+	labelsetstats_inc(ls, msread);
+
+	return label;
+}
+
+/**
+ * aa_label_merge - attempt to insert new merged label of @a and @b
+ * @ls: set of labels to insert label into (NOT NULL)
+ * @a: label to merge with @b  (NOT NULL)
+ * @b: label to merge with @a  (NOT NULL)
+ * @gfp: memory allocation type
+ *
+ * Requires: caller to hold valid refs on @a and @b
+ *           labels be fully constructed with a valid ns
+ *
+ * Returns: ref counted new label if successful in inserting merge of a & b
+ *     else ref counted equivalent label that is already in the set.
+ *     else NULL if could not create label (-ENOMEM)
+ */
+struct aa_label *aa_label_merge(struct aa_label *a, struct aa_label *b,
+				gfp_t gfp)
+{
+	struct aa_label *label = NULL;
+
+	AA_BUG(!a);
+	AA_BUG(!b);
+
+	if (a == b)
+		return aa_get_newest_label(a);
+
+	/* TODO: enable when read side is lockless
+	 * check if label exists before taking locks
+	if (!label_is_stale(a) && !label_is_stale(b))
+		label = aa_label_find_merge(a, b);
+	*/
+
+	if (!label) {
+		struct aa_label *new;
+
+		a = aa_get_newest_label(a);
+		b = aa_get_newest_label(b);
+
+		/* could use label_merge_len(a, b), but requires double
+		 * comparison for small savings
+		 */
+		new = aa_label_alloc(a->size + b->size, NULL, gfp);
+		if (!new)
+			goto out;
+
+		label = label_merge_insert(new, a, b);
+		aa_put_label(new);
+	out:
+		aa_put_label(a);
+		aa_put_label(b);
+	}
+
+	return label;
+}
+
+static inline bool label_is_visible(struct aa_profile *profile,
+				    struct aa_label *label)
+{
+	return aa_ns_visible(profile->ns, labels_ns(label), true);
+}
+
+/* match a profile and its associated ns component if needed
+ * Assumes visibility test has already been done.
+ * If a subns profile is not to be matched should be prescreened with
+ * visibility test.
+ */
+static inline unsigned int match_component(struct aa_profile *profile,
+					   struct aa_profile *tp,
+					   unsigned int state)
+{
+	const char *ns_name;
+
+	if (profile->ns == tp->ns)
+		return aa_dfa_match(profile->policy.dfa, state, tp->base.hname);
+
+	/* try matching with namespace name and then profile */
+	ns_name = aa_ns_name(profile->ns, tp->ns, true);
+	state = aa_dfa_match_len(profile->policy.dfa, state, ":", 1);
+	state = aa_dfa_match(profile->policy.dfa, state, ns_name);
+	state = aa_dfa_match_len(profile->policy.dfa, state, ":", 1);
+	return aa_dfa_match(profile->policy.dfa, state, tp->base.hname);
+}
+
+/**
+ * label_component_match - find perms for full compound label
+ * @profile: profile to find perms for
+ * @label: label to check access permissions for
+ * @start: state to start match in
+ * @subns: whether to do permission checks on components in a subns
+ * @request: permissions to request
+ * @perms: perms struct to set
+ *
+ * Returns: 0 on success else ERROR
+ *
+ * For the label A//&B//&C this does the perm match for A//&B//&C
+ * @perms should be preinitialized with allperms OR a previous permission
+ *        check to be stacked.
+ */
+static int label_compound_match(struct aa_profile *profile,
+				struct aa_label *label,
+				unsigned int state, bool subns, u32 request,
+				struct aa_perms *perms)
+{
+	struct aa_profile *tp;
+	struct label_it i;
+
+	/* find first subcomponent that is visible */
+	label_for_each(i, label, tp) {
+		if (!aa_ns_visible(profile->ns, tp->ns, subns))
+			continue;
+		state = match_component(profile, tp, state);
+		if (!state)
+			goto fail;
+		goto next;
+	}
+
+	/* no component visible */
+	*perms = allperms;
+	return 0;
+
+next:
+	label_for_each_cont(i, label, tp) {
+		if (!aa_ns_visible(profile->ns, tp->ns, subns))
+			continue;
+		state = aa_dfa_match(profile->policy.dfa, state, "//&");
+		state = match_component(profile, tp, state);
+		if (!state)
+			goto fail;
+	}
+	aa_compute_perms(profile->policy.dfa, state, perms);
+	aa_apply_modes_to_perms(profile, perms);
+	if ((perms->allow & request) != request)
+		return -EACCES;
+
+	return 0;
+
+fail:
+	*perms = nullperms;
+	return state;
+}
+
+/**
+ * label_component_match - find perms for all subcomponents of a label
+ * @profile: profile to find perms for
+ * @label: label to check access permissions for
+ * @start: state to start match in
+ * @subns: whether to do permission checks on components in a subns
+ * @request: permissions to request
+ * @perms: an initialized perms struct to add accumulation to
+ *
+ * Returns: 0 on success else ERROR
+ *
+ * For the label A//&B//&C this does the perm match for each of A and B and C
+ * @perms should be preinitialized with allperms OR a previous permission
+ *        check to be stacked.
+ */
+static int label_components_match(struct aa_profile *profile,
+				  struct aa_label *label, unsigned int start,
+				  bool subns, u32 request,
+				  struct aa_perms *perms)
+{
+	struct aa_profile *tp;
+	struct label_it i;
+	struct aa_perms tmp;
+	unsigned int state = 0;
+
+	/* find first subcomponent to test */
+	label_for_each(i, label, tp) {
+		if (!aa_ns_visible(profile->ns, tp->ns, subns))
+			continue;
+		state = match_component(profile, tp, start);
+		if (!state)
+			goto fail;
+		goto next;
+	}
+
+	/* no subcomponents visible - no change in perms */
+	return 0;
+
+next:
+	aa_compute_perms(profile->policy.dfa, state, &tmp);
+	aa_apply_modes_to_perms(profile, &tmp);
+	aa_perms_accum(perms, &tmp);
+	label_for_each_cont(i, label, tp) {
+		if (!aa_ns_visible(profile->ns, tp->ns, subns))
+			continue;
+		state = match_component(profile, tp, start);
+		if (!state)
+			goto fail;
+		aa_compute_perms(profile->policy.dfa, state, &tmp);
+		aa_apply_modes_to_perms(profile, &tmp);
+		aa_perms_accum(perms, &tmp);
+	}
+
+	if ((perms->allow & request) != request)
+		return -EACCES;
+
+	return 0;
+
+fail:
+	*perms = nullperms;
+	return -EACCES;
+}
+
+/**
+ * aa_label_match - do a multi-component label match
+ * @profile: profile to match against (NOT NULL)
+ * @label: label to match (NOT NULL)
+ * @state: state to start in
+ * @subns: whether to match subns components
+ * @request: permission request
+ * @perms: Returns computed perms (NOT NULL)
+ *
+ * Returns: the state the match finished in, may be the none matching state
+ */
+int aa_label_match(struct aa_profile *profile, struct aa_label *label,
+		   unsigned int state, bool subns, u32 request,
+		   struct aa_perms *perms)
+{
+	int error = label_compound_match(profile, label, state, subns, request,
+					 perms);
+	if (!error)
+		return error;
+
+	*perms = allperms;
+	return label_components_match(profile, label, state, subns, request,
+				      perms);
+}
+
+
+/**
+ * aa_update_label_name - update a label to have a stored name
+ * @ns: ns being viewed from (NOT NULL)
+ * @label: label to update (NOT NULL)
+ * @gfp: type of memory allocation
+ *
+ * Requires: labels_set(label) not locked in caller
+ *
+ * note: only updates the label name if it does not have a name already
+ *       and if it is in the labelset
+ */
+bool aa_update_label_name(struct aa_ns *ns, struct aa_label *label, gfp_t gfp)
+{
+	struct aa_labelset *ls;
+	unsigned long flags;
+	char __counted *name;
+	bool res = false;
+
+	AA_BUG(!ns);
+	AA_BUG(!label);
+
+	if (label->hname || labels_ns(label) != ns)
+		return res;
+
+	if (aa_label_acntsxprint(&name, ns, label, FLAGS_NONE, gfp) == -1)
+		return res;
+
+	ls = labels_set(label);
+	write_lock_irqsave(&ls->lock, flags);
+	if (!label->hname && label->flags & FLAG_IN_TREE) {
+		label->hname = name;
+		res = true;
+	} else
+		aa_put_str(name);
+	write_unlock_irqrestore(&ls->lock, flags);
+
+	return res;
+}
+
+/* cached label name is present and visible
+ * @label->hname only exists if label is namespace hierachical */
+static inline bool use_label_hname(struct aa_ns *ns, struct aa_label *label)
+{
+	if (label->hname && labels_ns(label) == ns)
+		return true;
+
+	return false;
+}
+
+/* helper macro for snprint routines */
+#define update_for_len(total, len, size, str)	\
+do {					\
+	AA_BUG(len < 0);		\
+	total += len;			\
+	len = min(len, size);		\
+	size -= len;			\
+	str += len;			\
+} while (0)
+
+/**
+ * aa_profile_snxprint_profile - print a profile name to a buffer
+ * @str: buffer to write to. (MAY BE NULL if @size == 0)
+ * @size: size of buffer
+ * @ns: namespace profile is being viewed from
+ * @profile: profile to view (NOT NULL)
+ * @flags: whether to include the mode string
+ *
+ * Returns: size of name written or would be written if larger than
+ *          available buffer
+ *
+ * Note: will not print anything if the profile is not visible
+ */
+int aa_profile_snxprint(char *str, size_t size, struct aa_ns *ns,
+			struct aa_profile *profile, int flags)
+{
+	const char *ns_name = "";
+
+	AA_BUG(!str && size != 0);
+	AA_BUG(!profile);
+
+	if (!ns)
+		ns = profiles_ns(profile);
+
+	if (ns != profile->ns) {
+		ns_name = aa_ns_name(ns, profile->ns, flags & FLAG_VIEW_SUBNS);
+		if (ns_name == aa_hidden_ns_name) {
+			if (flags & FLAG_HIDDEN_UNCONFINED)
+				return snprintf(str, size, "%s", "unconfined");
+			return snprintf(str, size, "%s", ns_name);
+		}
+	}
+
+	if ((flags & FLAG_SHOW_MODE) && profile != profile->ns->unconfined) {
+		const char *modestr = aa_profile_mode_names[profile->mode];
+		if (strlen(ns_name))
+			return snprintf(str, size, ":%s://%s (%s)", ns_name,
+					profile->base.hname, modestr);
+		return snprintf(str, size, "%s (%s)", profile->base.hname,
+				modestr);
+	}
+
+	if (strlen(ns_name))
+		return snprintf(str, size, ":%s://%s", ns_name,
+				profile->base.hname);
+	return snprintf(str, size, "%s", profile->base.hname);
+}
+
+static const char *label_modename(struct aa_ns *ns, struct aa_label *label,
+				  int flags)
+{
+	struct aa_profile *profile;
+	struct label_it i;
+	int mode = -1, count = 0;
+
+	label_for_each(i, label, profile) {
+		if (aa_ns_visible(ns, profile->ns, flags & FLAG_VIEW_SUBNS)) {
+			if (profile->mode == APPARMOR_UNCONFINED)
+				/* special case unconfined so stacks with
+				 * unconfined don't report as mixed. ie.
+				 * profile_foo//&:ns1://unconfined (mixed)
+				 */
+				continue;
+			count++;
+			if (mode == -1)
+				mode = profile->mode;
+			else if (mode != profile->mode)
+				return "mixed";
+		}
+	}
+
+	if (count == 0)
+		return "-";
+	if (mode == -1)
+		/* everything was unconfined */
+		mode = APPARMOR_UNCONFINED;
+
+	return aa_profile_mode_names[mode];
+}
+
+/* if any visible label is not unconfined the display_mode returns true */
+static inline bool display_mode(struct aa_ns *ns, struct aa_label *label,
+				int flags)
+{
+	if ((flags & FLAG_SHOW_MODE)) {
+		struct aa_profile *profile;
+		struct label_it i;
+
+		label_for_each(i, label, profile) {
+			if (aa_ns_visible(ns, profile->ns,
+					  flags & FLAG_VIEW_SUBNS) &&
+			    profile != profile->ns->unconfined)
+				return true;
+		}
+		/* only ns->unconfined in set of profiles in ns */
+		return false;
+	}
+
+	return false;
+}
+
+/**
+ * aa_label_snxprint - print a label name to a string buffer
+ * @str: buffer to write to. (MAY BE NULL if @size == 0)
+ * @size: size of buffer
+ * @ns: namespace profile is being viewed from
+ * @label: label to view (NOT NULL)
+ * @flags: whether to include the mode string
+ *
+ * Returns: size of name written or would be written if larger than
+ *          available buffer
+ *
+ * Note: labels do not have to be strictly hierarchical to the ns as
+ *       objects may be shared across different namespaces and thus
+ *       pickup labeling from each ns.  If a particular part of the
+ *       label is not visible it will just be excluded.  And if none
+ *       of the label is visible "---" will be used.
+ */
+int aa_label_snxprint(char *str, size_t size, struct aa_ns *ns,
+		      struct aa_label *label, int flags)
+{
+	struct aa_profile *profile;
+	struct label_it i;
+	int count = 0, total = 0;
+	size_t len;
+
+	AA_BUG(!str && size != 0);
+	AA_BUG(!label);
+
+	if (!ns)
+		ns = labels_ns(label);
+
+	label_for_each(i, label, profile) {
+		if (aa_ns_visible(ns, profile->ns, flags & FLAG_VIEW_SUBNS)) {
+			if (count > 0) {
+				len = snprintf(str, size, "//&");
+				update_for_len(total, len, size, str);
+			}
+			len = aa_profile_snxprint(str, size, ns, profile,
+						  flags & FLAG_VIEW_SUBNS);
+			update_for_len(total, len, size, str);
+			count++;
+		}
+	}
+
+	if (count == 0) {
+		if (flags & FLAG_HIDDEN_UNCONFINED)
+			return snprintf(str, size, "%s", "unconfined");
+		return snprintf(str, size, "%s", aa_hidden_ns_name);
+	}
+
+	/* count == 1 && ... is for backwards compat where the mode
+	 * is not displayed for 'unconfined' in the current ns
+	 */
+	if (display_mode(ns, label, flags)) {
+		len = snprintf(str, size, " (%s)",
+			       label_modename(ns, label, flags));
+		update_for_len(total, len, size, str);
+	}
+
+	return total;
+}
+#undef update_for_len
+
+/**
+ * aa_label_asxprint - allocate a string buffer and print label into it
+ * @strp: Returns - the allocated buffer with the label name. (NOT NULL)
+ * @ns: namespace profile is being viewed from
+ * @label: label to view (NOT NULL)
+ * @flags: flags controlling what label info is printed
+ * @gfp: kernel memory allocation type
+ *
+ * Returns: size of name written or would be written if larger than
+ *          available buffer
+ */
+int aa_label_asxprint(char **strp, struct aa_ns *ns, struct aa_label *label,
+		      int flags, gfp_t gfp)
+{
+	int size;
+
+	AA_BUG(!strp);
+	AA_BUG(!label);
+
+	size = aa_label_snxprint(NULL, 0, ns, label, flags);
+	if (size < 0)
+		return size;
+
+	*strp = kmalloc(size + 1, gfp);
+	if (!*strp)
+		return -ENOMEM;
+	return aa_label_snxprint(*strp, size + 1, ns, label, flags);
+}
+
+/**
+ * aa_label_acntsxprint - allocate a __counted string buffer and print label
+ * @strp: buffer to write to. (MAY BE NULL if @size == 0)
+ * @ns: namespace profile is being viewed from
+ * @label: label to view (NOT NULL)
+ * @flags: flags controlling what label info is printed
+ * @gfp: kernel memory allocation type
+ *
+ * Returns: size of name written or would be written if larger than
+ *          available buffer
+ */
+int aa_label_acntsxprint(char __counted **strp, struct aa_ns *ns,
+			 struct aa_label *label, int flags, gfp_t gfp)
+{
+	int size;
+
+	AA_BUG(!strp);
+	AA_BUG(!label);
+
+	size = aa_label_snxprint(NULL, 0, ns, label, flags);
+	if (size < 0)
+		return size;
+
+	*strp = aa_str_alloc(size + 1, gfp);
+	if (!*strp)
+		return -ENOMEM;
+	return aa_label_snxprint(*strp, size + 1, ns, label, flags);
+}
+
+
+void aa_label_xaudit(struct audit_buffer *ab, struct aa_ns *ns,
+		     struct aa_label *label, int flags, gfp_t gfp)
+{
+	const char *str;
+	char *name = NULL;
+	int len;
+
+	AA_BUG(!ab);
+	AA_BUG(!label);
+
+	if (!ns)
+		ns = labels_ns(label);
+
+	if (!use_label_hname(ns, label) || display_mode(ns, label, flags)) {
+		labelstats_inc(audit_name_alloc);
+		len  = aa_label_asxprint(&name, ns, label, flags, gfp);
+		if (len == -1) {
+			labelstats_inc(audit_name_fail);
+			AA_DEBUG("label print error");
+			return;
+		}
+		str = name;
+	} else {
+		str = (char *) label->hname;
+		len = strlen(str);
+	}
+	if (audit_string_contains_control(str, len))
+		audit_log_n_hex(ab, str, len);
+	else
+		audit_log_n_string(ab, str, len);
+
+	kfree(name);
+}
+
+void aa_label_seq_xprint(struct seq_file *f, struct aa_ns *ns,
+			 struct aa_label *label, int flags, gfp_t gfp)
+{
+	AA_BUG(!f);
+	AA_BUG(!label);
+
+	if (!ns)
+		ns = labels_ns(label);
+
+	if (!use_label_hname(ns, label)) {
+		char *str;
+		int len;
+
+		labelstats_inc(seq_print_name_alloc);
+		len = aa_label_asxprint(&str, ns, label, flags, gfp);
+		if (len == -1) {
+			labelstats_inc(seq_print_name_fail);
+			AA_DEBUG("label print error");
+			return;
+		}
+		seq_printf(f, "%s", str);
+		kfree(str);
+	} else if (display_mode(ns, label, flags))
+		seq_printf(f, "%s (%s)", label->hname,
+			   label_modename(ns, label, flags));
+	else
+		seq_printf(f, "%s", label->hname);
+}
+
+void aa_label_xprintk(struct aa_ns *ns, struct aa_label *label, int flags,
+		      gfp_t gfp)
+{
+	AA_BUG(!label);
+
+	if (!ns)
+		ns = labels_ns(label);
+
+	if (!use_label_hname(ns, label)) {
+		char *str;
+		int len;
+
+		labelstats_inc(printk_name_alloc);
+		len = aa_label_asxprint(&str, ns, label, flags, gfp);
+		if (len == -1) {
+			labelstats_inc(printk_name_fail);
+			AA_DEBUG("label print error");
+			return;
+		}
+		printk("%s", str);
+		kfree(str);
+	} else if (display_mode(ns, label, flags))
+		printk("%s (%s)", label->hname,
+		       label_modename(ns, label, flags));
+	else
+		printk("%s", label->hname);
+}
+
+void aa_label_audit(struct audit_buffer *ab, struct aa_label *label, gfp_t gfp)
+{
+	struct aa_ns *ns = aa_get_current_ns();
+	aa_label_xaudit(ab, ns, label, FLAG_VIEW_SUBNS, gfp);
+	aa_put_ns(ns);
+}
+
+void aa_label_seq_print(struct seq_file *f, struct aa_label *label, gfp_t gfp)
+{
+	struct aa_ns *ns = aa_get_current_ns();
+	aa_label_seq_xprint(f, ns, label, FLAG_VIEW_SUBNS, gfp);
+	aa_put_ns(ns);
+}
+
+void aa_label_printk(struct aa_label *label, gfp_t gfp)
+{
+	struct aa_ns *ns = aa_get_current_ns();
+	aa_label_xprintk(ns, label, FLAG_VIEW_SUBNS, gfp);
+	aa_put_ns(ns);
+}
+
+static int label_count_str_entries(const char *str)
+{
+	const char *split;
+	int count = 1;
+
+	AA_BUG(!str);
+
+	for (split = strstr(str, "//&"); split; split = strstr(str, "//&")) {
+		count++;
+		str = split + 3;
+	}
+
+	return count;
+}
+
+/**
+ * aa_label_parse - parse, validate and convert a text string to a label
+ * @base: base label to use for lookups (NOT NULL)
+ * @str: null terminated text string (NOT NULL)
+ * @gfp: allocation type
+ * @create: true if should create compound labels if they don't exist
+ * @force_stack: true if should stack even if no leading &
+ *
+ * Returns: the matching refcounted label if present
+ *     else ERRPTR
+ */
+struct aa_label *aa_label_parse(struct aa_label *base, const char *str,
+				gfp_t gfp, bool create, bool force_stack)
+{
+	DEFINE_VEC(profile, vec);
+	struct aa_label *label;
+	int i, len, stack = 0, error;
+	char *split;
+
+	AA_BUG(!base);
+	AA_BUG(!str);
+
+	str = skip_spaces(str);
+	len = label_count_str_entries(str);
+	if (*str == '&' || force_stack) {
+		/* stack on top of base */
+		stack = base->size;
+		len += stack;
+		if (*str == '&')
+			str++;
+	}
+	error = vec_setup(profile, vec, len, gfp);
+	if (error)
+		return ERR_PTR(error);
+
+	for (i = 0; i < stack; i++)
+		vec[i] = aa_get_profile(base->vec[i]);
+
+	for (split = strstr(str, "//&"), i = stack; split && i < len; i++) {
+		vec[i] = aa_fqlookupn_profile(base, str, split - str);
+		if (!vec[i])
+			goto fail;
+		str = split + 3;
+		split = strstr(str, "//&");
+	}
+	/* last element doesn't have a split so this should be the case but just to be safe */
+	if (i < len) {
+		vec[i] = aa_fqlookupn_profile(base, str, strlen(str));
+		if (!vec[i])
+			goto fail;
+	}
+	if (len == 1)
+		/* no need to free vec as len < LOCAL_VEC_ENTRIES */
+		return &vec[0]->label;
+
+	len -= aa_vec_unique(vec, len, VEC_FLAG_TERMINATE);
+	/* TODO: deal with reference labels */
+	if (len == 1) {
+		label = aa_get_label(&vec[0]->label);
+		goto out;
+	}
+
+	if (create)
+		label = aa_vec_find_or_create_label(vec, len, gfp);
+	else
+		label = vec_find(vec, len);
+	if (!label)
+		goto fail;
+
+out:
+	/* use adjusted len from after vec_unique, not original */
+	vec_cleanup(profile, vec, len);
+	return label;
+
+fail:
+	label = ERR_PTR(-ENOENT);
+	goto out;
+}
+
+
+/**
+ * aa_labelset_destroy - remove all labels from the label set
+ * @ls: label set to cleanup (NOT NULL)
+ *
+ * Labels that are removed from the set may still exist beyond the set
+ * being destroyed depending on their reference counting
+ */
+void aa_labelset_destroy(struct aa_labelset *ls)
+{
+	struct rb_node *node;
+	unsigned long flags;
+
+	AA_BUG(!ls);
+
+	write_lock_irqsave(&ls->lock, flags);
+	for (node = rb_first(&ls->root); node; node = rb_first(&ls->root)) {
+		struct aa_label *this = rb_entry(node, struct aa_label, node);
+		if (labels_ns(this) != root_ns)
+			__label_remove(this,
+				       ns_unconfined(labels_ns(this)->parent));
+		else
+			__label_remove(this, NULL);
+	}
+	write_unlock_irqrestore(&ls->lock, flags);
+}
+
+/*
+ * @ls: labelset to init (NOT NULL)
+ */
+void aa_labelset_init(struct aa_labelset *ls)
+{
+	AA_BUG(!ls);
+
+	rwlock_init(&ls->lock);
+	ls->root = RB_ROOT;
+	labelstats_init(&ls);
+}
+
+static struct aa_label *labelset_next_stale(struct aa_labelset *ls)
+{
+	struct aa_label *label;
+	struct rb_node *node;
+	unsigned long flags;
+
+	AA_BUG(!ls);
+
+	read_lock_irqsave(&ls->lock, flags);
+
+	__labelset_for_each(ls, node) {
+		label = rb_entry(node, struct aa_label, node);
+		if ((label_is_stale(label) || vec_is_stale(label->vec, label->size)) &&
+		    aa_get_label_not0(label))
+			goto out;
+
+	}
+	label = NULL;
+
+out:
+	read_unlock_irqrestore(&ls->lock, flags);
+
+	return label;
+}
+
+/**
+ * __label_update - insert updated version of @label into labelset
+ * @label - the label to update/repace
+ *
+ * Returns: new label that is up to date
+ *     else NULL on failure
+ *
+ * Requires: @ns lock be held
+ *
+ * Note: worst case is the stale @label does not get updated and has
+ *       to be updated at a later time.
+ */
+static struct aa_label *__label_update(struct aa_label *label)
+{
+	struct aa_label *new, *tmp;
+	struct aa_labelset *ls;
+	unsigned long flags;
+	int i, invcount = 0;
+
+	AA_BUG(!label);
+	AA_BUG(!mutex_is_locked(&labels_ns(label)->lock));
+
+	new = aa_label_alloc(label->size, label->proxy, GFP_KERNEL);
+	if (!new)
+		return NULL;
+
+	/* while holding the ns_lock will stop profile replacement, removal,
+	 * and label updates, label merging and removal can be occuring
+	 */
+	ls = labels_set(label);
+	write_lock_irqsave(&ls->lock, flags);
+	for (i = 0; i < label->size; i++) {
+		AA_BUG(!label->vec[i]);
+		new->vec[i] = aa_get_newest_profile(label->vec[i]);
+		AA_BUG(!new->vec[i]);
+		AA_BUG(!new->vec[i]->label.proxy);
+		AA_BUG(!new->vec[i]->label.proxy->label);
+		if (new->vec[i]->label.proxy != label->vec[i]->label.proxy)
+			invcount++;
+	}
+
+	/* updated stale label by being removed/renamed from labelset */
+	if (invcount) {
+		new->size -= aa_vec_unique(&new->vec[0], new->size,
+					   VEC_FLAG_TERMINATE);
+		/* TODO: deal with reference labels */
+		if (new->size == 1) {
+			tmp = aa_get_label(&new->vec[0]->label);
+			AA_BUG(tmp == label);
+			goto remove;
+		}
+		if (labels_set(label) != labels_set(new)) {
+			write_unlock_irqrestore(&ls->lock, flags);
+			tmp = aa_label_insert(labels_set(new), new);
+			write_lock_irqsave(&ls->lock, flags);
+			goto remove;
+		}
+	} else
+		AA_BUG(labels_ns(label) != labels_ns(new));
+
+	tmp = __label_insert(labels_set(label), new, true);
+remove:
+	/* ensure label is removed, and redirected correctly */
+	__label_remove(label, tmp);
+	write_unlock_irqrestore(&ls->lock, flags);
+
+	aa_put_label(new);
+
+	return tmp;
+}
+
+/**
+ * __labelset_update - update labels in @ns
+ * @ns: namespace to update labels in  (NOT NULL)
+ *
+ * Requires: @ns lock be held
+ *
+ * Walk the labelset ensuring that all labels are up to date and valid
+ * Any label that has a stale component is marked stale and replaced and
+ * by an updated version.
+ *
+ * If failures happen due to memory pressures then stale labels will
+ * be left in place until the next pass.
+ */
+static void __labelset_update(struct aa_ns *ns)
+{
+	struct aa_label *label;
+
+	AA_BUG(!ns);
+	AA_BUG(!mutex_is_locked(&ns->lock));
+
+	do {
+		label = labelset_next_stale(&ns->labels);
+		if (label) {
+			struct aa_label *l;
+			l = __label_update(label);
+			aa_put_label(l);
+			aa_put_label(label);
+		}
+	} while (label);
+}
+
+/**
+ * __aa_labelset_udate_subtree - update all labels with a stale component
+ * @ns: ns to start update at (NOT NULL)
+ *
+ * Requires: @ns lock be held
+ *
+ * Invalidates labels based on @p in @ns and any children namespaces.
+*/
+void __aa_labelset_update_subtree(struct aa_ns *ns)
+{
+	struct aa_ns *child;
+
+	AA_BUG(!ns);
+	AA_BUG(!mutex_is_locked(&ns->lock));
+
+	__labelset_update(ns);
+
+	list_for_each_entry(child, &ns->sub_ns, base.list) {
+		mutex_lock(&child->lock);
+		__aa_labelset_update_subtree(child);
+		mutex_unlock(&child->lock);
+	}
+}
--- zfcpdump-kernel-4.4.orig/security/apparmor/lib.c
+++ zfcpdump-kernel-4.4/security/apparmor/lib.c
@@ -4,7 +4,7 @@
  * This file contains basic common functions used in AppArmor
  *
  * Copyright (C) 1998-2008 Novell/SUSE
- * Copyright 2009-2010 Canonical Ltd.
+ * Copyright 2009-2013 Canonical Ltd.
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -12,14 +12,23 @@
  * License.
  */
 
+#include <linux/ctype.h>
 #include <linux/mm.h>
 #include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/vmalloc.h>
 
-#include "include/audit.h"
 #include "include/apparmor.h"
+#include "include/audit.h"
+#include "include/label.h"
+#include "include/lib.h"
+#include "include/perms.h"
+#include "include/policy.h"
 
+struct aa_perms nullperms;
+struct aa_perms allperms = { .allow = ALL_PERMS_MASK,
+			     .quiet = ALL_PERMS_MASK,
+			     .hide = ALL_PERMS_MASK };
 
 /**
  * aa_split_fqname - split a fqname into a profile and namespace name
@@ -60,17 +69,65 @@ char *aa_split_fqname(char *fqname, char
 }
 
 /**
+ * skipn_spaces - Removes leading whitespace from @str.
+ * @str: The string to be stripped.
+ *
+ * Returns a pointer to the first non-whitespace character in @str.
+ * if all whitespace will return NULL
+ */
+
+static const char *skipn_spaces(const char *str, size_t n)
+{
+	for (;n && isspace(*str); --n)
+		++str;
+	if (n)
+		return (char *)str;
+	return NULL;
+}
+
+const char *aa_splitn_fqname(const char *fqname, size_t n, const char **ns_name,
+			     size_t *ns_len)
+{
+	const char *end = fqname + n;
+	const char *name = skipn_spaces(fqname, n);
+	if (!name)
+		return NULL;
+	*ns_name = NULL;
+	*ns_len = 0;
+	if (name[0] == ':') {
+		char *split = strnchr(&name[1], end - &name[1], ':');
+		*ns_name = skipn_spaces(&name[1], end - &name[1]);
+		if (!*ns_name)
+			return NULL;
+		if (split) {
+			*ns_len = split - *ns_name;
+			if (*ns_len == 0)
+				*ns_name = NULL;
+			split++;
+			if (end - split > 1 && strncmp(split, "//", 2) == 0)
+				split += 2;
+			name = skipn_spaces(split, end - split);
+		} else {
+			/* a ns name without a following profile is allowed */
+			name = NULL;
+			*ns_len = end - *ns_name;
+		}
+	}
+	if (name && *name == 0)
+		name = NULL;
+
+	return name;
+}
+
+/**
  * aa_info_message - log a none profile related status message
  * @str: message to log
  */
 void aa_info_message(const char *str)
 {
 	if (audit_enabled) {
-		struct common_audit_data sa;
-		struct apparmor_audit_data aad = {0,};
-		sa.type = LSM_AUDIT_DATA_NONE;
-		sa.aad = &aad;
-		aad.info = str;
+		DEFINE_AUDIT_DATA(sa, LSM_AUDIT_DATA_NONE, NULL);
+		aad(&sa)->info = str;
 		aa_audit_msg(AUDIT_APPARMOR_STATUS, &sa, NULL);
 	}
 	printk(KERN_INFO "AppArmor: %s\n", str);
@@ -104,3 +161,405 @@ void *__aa_kvmalloc(size_t size, gfp_t f
 	}
 	return buffer;
 }
+
+
+__counted char *aa_str_alloc(int size, gfp_t gfp)
+{
+	struct counted_str *str;
+	str = kmalloc(sizeof(struct counted_str) + size, gfp);
+	if (!str)
+		return NULL;
+
+	kref_init(&str->count);
+	return str->name;
+}
+
+void aa_str_kref(struct kref *kref)
+{
+	kfree(container_of(kref, struct counted_str, count));
+}
+
+
+const char aa_file_perm_chrs[] = "xwracd         km l     ";
+const char *aa_file_perm_names[] = {
+	"exec",
+	"write",
+	"read",
+	"append",
+
+	"create",
+	"delete",
+	"open",
+	"rename",
+
+	"setattr",
+	"getattr",
+	"setcred",
+	"getcred",
+
+	"chmod",
+	"chown",
+	"chgrp",
+	"lock",
+
+	"mmap",
+	"mprot",
+	"link",
+	"snapshot",
+
+	"unknown",
+	"unknown",
+	"unknown",
+	"unknown",
+
+	"unknown",
+	"unknown",
+	"unknown",
+	"unknown",
+
+	"stack",
+	"change_onexec",
+	"change_profile",
+	"change_hat",
+};
+
+/**
+ * aa_perm_mask_to_str - convert a perm mask to its short string
+ * @str: character buffer to store string in (at least 10 characters)
+ * @mask: permission mask to convert
+ */
+void aa_perm_mask_to_str(char *str, const char *chrs, u32 mask)
+{
+	unsigned int i, perm = 1;
+	for (i = 0; i < 32; perm <<= 1, i++) {
+		if (mask & perm)
+			*str++ = chrs[i];
+	}
+	*str = '\0';
+}
+
+void aa_audit_perm_names(struct audit_buffer *ab, const char **names, u32 mask)
+{
+	const char *fmt = "%s";
+	unsigned int i, perm = 1;
+	bool prev = false;
+	for (i = 0; i < 32; perm <<= 1, i++) {
+		if (mask & perm) {
+			audit_log_format(ab, fmt, names[i]);
+			if (!prev) {
+				prev = true;
+				fmt = " %s";
+			}
+		}
+	}
+}
+
+void aa_audit_perm_mask(struct audit_buffer *ab, u32 mask, const char *chrs,
+			u32 chrsmask, const char **names, u32 namesmask)
+{
+	char str[33];
+
+	audit_log_format(ab, "\"");
+	if ((mask & chrsmask) && chrs) {
+		aa_perm_mask_to_str(str, chrs, mask & chrsmask);
+		mask &= ~chrsmask;
+		audit_log_format(ab, "%s", str);
+		if (mask & namesmask)
+			audit_log_format(ab, " ");
+	}
+	if ((mask & namesmask) && names)
+		aa_audit_perm_names(ab, names, mask & namesmask);
+	audit_log_format(ab, "\"");
+}
+
+/**
+ * aa_audit_perms_cb - generic callback fn for auditing perms
+ * @ab: audit buffer (NOT NULL)
+ * @va: audit struct to audit values of (NOT NULL)
+ */
+static void aa_audit_perms_cb(struct audit_buffer *ab, void *va)
+{
+	struct common_audit_data *sa = va;
+
+	if (aad(sa)->request) {
+		audit_log_format(ab, " requested_mask=");
+		aa_audit_perm_mask(ab, aad(sa)->request, aa_file_perm_chrs,
+				   PERMS_CHRS_MASK, aa_file_perm_names,
+				   PERMS_NAMES_MASK);
+	}
+	if (aad(sa)->denied) {
+		audit_log_format(ab, "denied_mask=");
+		aa_audit_perm_mask(ab, aad(sa)->denied, aa_file_perm_chrs,
+				   PERMS_CHRS_MASK, aa_file_perm_names,
+				   PERMS_NAMES_MASK);
+	}
+	audit_log_format(ab, " peer=");
+	aa_label_xaudit(ab, labels_ns(aad(sa)->label), aad(sa)->peer,
+				      FLAGS_NONE, GFP_ATOMIC);
+}
+
+/**
+ * aa_apply_modes_to_perms - apply namespace and profile flags to perms
+ * @profile: that perms where computed from
+ * @perms: perms to apply mode modifiers to
+ *
+ * TODO: split into profile and ns based flags for when accumulating perms
+ */
+void aa_apply_modes_to_perms(struct aa_profile *profile, struct aa_perms *perms)
+{
+	switch (AUDIT_MODE(profile)) {
+	case AUDIT_ALL:
+		perms->audit = ALL_PERMS_MASK;
+		/* fall through */
+	case AUDIT_NOQUIET:
+		perms->quiet = 0;
+		break;
+	case AUDIT_QUIET:
+		perms->audit = 0;
+		/* fall through */
+	case AUDIT_QUIET_DENIED:
+		perms->quiet = ALL_PERMS_MASK;
+		break;
+	}
+
+	if (KILL_MODE(profile))
+		perms->kill = ALL_PERMS_MASK;
+	else if (COMPLAIN_MODE(profile))
+		perms->complain = ALL_PERMS_MASK;
+/* TODO:
+	else if (PROMPT_MODE(profile))
+		perms->prompt = ALL_PERMS_MASK;
+*/
+}
+
+static u32 map_other(u32 x)
+{
+	return ((x & 0x3) << 8) |	/* SETATTR/GETATTR */
+		((x & 0x1c) << 18) |	/* ACCEPT/BIND/LISTEN */
+		((x & 0x60) << 19);	/* SETOPT/GETOPT */
+}
+
+void aa_compute_perms(struct aa_dfa *dfa, unsigned int state,
+		      struct aa_perms *perms)
+{
+	perms->deny = 0;
+	perms->kill = perms->stop = 0;
+	perms->complain = perms->cond = 0;
+	perms->hide = 0;
+	perms->prompt = 0;
+	perms->allow = dfa_user_allow(dfa, state);
+	perms->audit = dfa_user_audit(dfa, state);
+	perms->quiet = dfa_user_quiet(dfa, state);
+
+	/* for v5 perm mapping in the policydb, the other set is used
+	 * to extend the general perm set
+	 */
+	perms->allow |= map_other(dfa_other_allow(dfa, state));
+	perms->audit |= map_other(dfa_other_audit(dfa, state));
+	perms->quiet |= map_other(dfa_other_quiet(dfa, state));
+//	perms->xindex = dfa_user_xindex(dfa, state);
+}
+
+/**
+ * aa_perms_accum_raw - accumulate perms with out masking off overlapping perms
+ * @accum - perms struct to accumulate into
+ * @addend - perms struct to add to @accum
+ */
+void aa_perms_accum_raw(struct aa_perms *accum, struct aa_perms *addend)
+{
+	accum->deny |= addend->deny;
+	accum->allow &= addend->allow & ~addend->deny;
+	accum->audit |= addend->audit & addend->allow;
+	accum->quiet &= addend->quiet & ~addend->allow;
+	accum->kill |= addend->kill & ~addend->allow;
+	accum->stop |= addend->stop & ~addend->allow;
+	accum->complain |= addend->complain & ~addend->allow & ~addend->deny;
+	accum->cond |= addend->cond & ~addend->allow & ~addend->deny;
+	accum->hide &= addend->hide & ~addend->allow;
+	accum->prompt |= addend->prompt & ~addend->allow & ~addend->deny;
+}
+
+/**
+ * aa_perms_accum - accumulate perms, masking off overlapping perms
+ * @accum - perms struct to accumulate into
+ * @addend - perms struct to add to @accum
+ */
+void aa_perms_accum(struct aa_perms *accum, struct aa_perms *addend)
+{
+	accum->deny |= addend->deny;
+	accum->allow &= addend->allow & ~accum->deny;
+	accum->audit |= addend->audit & accum->allow;
+	accum->quiet &= addend->quiet & ~accum->allow;
+	accum->kill |= addend->kill & ~accum->allow;
+	accum->stop |= addend->stop & ~accum->allow;
+	accum->complain |= addend->complain & ~accum->allow & ~accum->deny;
+	accum->cond |= addend->cond & ~accum->allow & ~accum->deny;
+	accum->hide &= addend->hide & ~accum->allow;
+	accum->prompt |= addend->prompt & ~accum->allow & ~accum->deny;
+}
+
+void aa_profile_match_label(struct aa_profile *profile, struct aa_label *label,
+			    int type, u32 request, struct aa_perms *perms)
+{
+	/* TODO: doesn't yet handle extended types */
+	unsigned int state;
+	state = aa_dfa_next(profile->policy.dfa,
+			    profile->policy.start[AA_CLASS_LABEL],
+			    type);
+	aa_label_match(profile, label, state, false, request, perms);
+}
+
+
+/* currently unused */
+int aa_profile_label_perm(struct aa_profile *profile, struct aa_profile *target,
+			  u32 request, int type, u32 *deny,
+			  struct common_audit_data *sa)
+{
+	struct aa_perms perms;
+	aad(sa)->label = &profile->label;
+	aad(sa)->peer = &target->label;
+	aad(sa)->request = request;
+
+	aa_profile_match_label(profile, &target->label, type, request, &perms);
+	aa_apply_modes_to_perms(profile, &perms);
+	*deny |= request & perms.deny;
+	return aa_check_perms(profile, &perms, request, sa, aa_audit_perms_cb);
+}
+
+/**
+ * aa_check_perms - do audit mode selection based on perms set
+ * @profile: profile being checked
+ * @perms: perms computed for the request
+ * @request: requested perms
+ * @deny: Returns: explicit deny set
+ * @sa: initialized audit structure (MAY BE NULL if not auditing)
+ * @cb: callback fn for tpye specific fields (MAY BE NULL)
+ *
+ * Returns: 0 if permission else error code
+ *
+ * Note: profile audit modes need to be set before calling by setting the
+ *       perm masks appropriately.
+ *
+ *       If not auditing then complain mode is not enabled and the
+ *       error code will indicate whether there was an explicit deny
+ *	 with a positive value.
+ */
+int aa_check_perms(struct aa_profile *profile, struct aa_perms *perms,
+		   u32 request, struct common_audit_data *sa,
+		   void (*cb) (struct audit_buffer *, void *))
+{
+	int type, error;
+	bool stop = false;
+	u32 denied = request & (~perms->allow | perms->deny);
+	if (likely(!denied)) {
+		/* mask off perms that are not being force audited */
+		request &= perms->audit;
+		if (!request || !sa)
+			return 0;
+
+		type = AUDIT_APPARMOR_AUDIT;
+		error = 0;
+	} else {
+		error = -EACCES;
+
+		if (denied & perms->kill)
+			type = AUDIT_APPARMOR_KILL;
+		else if (denied == (denied & perms->complain))
+			type = AUDIT_APPARMOR_ALLOWED;
+		else
+			type = AUDIT_APPARMOR_DENIED;
+
+		if (denied & perms->stop)
+			stop = true;
+		if (denied == (denied & perms->hide))
+			error = -ENOENT;
+
+		denied &= ~perms->quiet;
+		if (!sa || !denied)
+			return error;
+	}
+
+	if (sa) {
+		aad(sa)->label = &profile->label;
+		aad(sa)->request = request;
+		aad(sa)->denied = denied;
+		aad(sa)->error = error;
+		aa_audit_msg(type, sa, cb);
+	}
+
+	if (type == AUDIT_APPARMOR_ALLOWED)
+		error = 0;
+
+	return error;
+}
+
+const char *aa_imode_name(umode_t mode)
+{
+	switch(mode & S_IFMT) {
+	case S_IFSOCK:
+		return "sock";
+	case S_IFLNK:
+		return "link";
+	case S_IFREG:
+		return "reg";
+	case S_IFBLK:
+		return "blkdev";
+	case S_IFDIR:
+		return "dir";
+	case S_IFCHR:
+		return "chrdev";
+	case S_IFIFO:
+		return "fifo";
+	}
+	return "unknown";
+}
+
+/**
+ * aa_policy_init - initialize a policy structure
+ * @policy: policy to initialize  (NOT NULL)
+ * @prefix: prefix name if any is required.  (MAYBE NULL)
+ * @name: name of the policy, init will make a copy of it  (NOT NULL)
+ * @gfp: allocation mode
+ *
+ * Note: this fn creates a copy of strings passed in
+ *
+ * Returns: true if policy init successful
+ */
+bool aa_policy_init(struct aa_policy *policy, const char *prefix,
+		    const char *name, gfp_t gfp)
+{
+	char *hname;
+
+	/* freed by policy_free */
+	if (prefix) {
+		hname = aa_str_alloc(strlen(prefix) + strlen(name) + 3, gfp);
+		if (hname)
+			sprintf(hname, "%s//%s", prefix, name);
+	} else {
+		hname = aa_str_alloc(strlen(name) + 1, gfp);
+		if (hname)
+			strcpy(hname, name);
+	}
+	if (!hname)
+		return 0;
+	policy->hname = hname;
+	/* base.name is a substring of fqname */
+	policy->name = (char *) basename(policy->hname);
+	INIT_LIST_HEAD(&policy->list);
+	INIT_LIST_HEAD(&policy->profiles);
+
+	return 1;
+}
+
+/**
+ * aa_policy_destroy - free the elements referenced by @policy
+ * @policy: policy that is to have its elements freed  (NOT NULL)
+ */
+void aa_policy_destroy(struct aa_policy *policy)
+{
+	AA_BUG(on_list_rcu(&policy->profiles));
+	AA_BUG(on_list_rcu(&policy->list));
+
+	/* don't free name as its a subset of hname */
+	aa_put_str(policy->hname);
+}
--- zfcpdump-kernel-4.4.orig/security/apparmor/lsm.c
+++ zfcpdump-kernel-4.4/security/apparmor/lsm.c
@@ -23,8 +23,10 @@
 #include <linux/sysctl.h>
 #include <linux/audit.h>
 #include <linux/user_namespace.h>
+#include <linux/kmemleak.h>
 #include <net/sock.h>
 
+#include "include/af_unix.h"
 #include "include/apparmor.h"
 #include "include/apparmorfs.h"
 #include "include/audit.h"
@@ -32,24 +34,29 @@
 #include "include/context.h"
 #include "include/file.h"
 #include "include/ipc.h"
+#include "include/net.h"
 #include "include/path.h"
 #include "include/policy.h"
 #include "include/procattr.h"
+#include "include/mount.h"
 
 /* Flag indicating whether initialization completed */
 int apparmor_initialized __initdata;
 
+DEFINE_PER_CPU(struct aa_buffers, aa_buffers);
+
+
 /*
  * LSM hook functions
  */
 
 /*
- * free the associated aa_task_cxt and put its profiles
+ * free the associated aa_task_ctx and put its labels
  */
 static void apparmor_cred_free(struct cred *cred)
 {
-	aa_free_task_context(cred_cxt(cred));
-	cred_cxt(cred) = NULL;
+	aa_free_task_context(cred_ctx(cred));
+	cred_ctx(cred) = NULL;
 }
 
 /*
@@ -58,27 +65,27 @@ static void apparmor_cred_free(struct cr
 static int apparmor_cred_alloc_blank(struct cred *cred, gfp_t gfp)
 {
 	/* freed by apparmor_cred_free */
-	struct aa_task_cxt *cxt = aa_alloc_task_context(gfp);
-	if (!cxt)
+	struct aa_task_ctx *ctx = aa_alloc_task_context(gfp);
+	if (!ctx)
 		return -ENOMEM;
 
-	cred_cxt(cred) = cxt;
+	cred_ctx(cred) = ctx;
 	return 0;
 }
 
 /*
- * prepare new aa_task_cxt for modification by prepare_cred block
+ * prepare new aa_task_ctx for modification by prepare_cred block
  */
 static int apparmor_cred_prepare(struct cred *new, const struct cred *old,
 				 gfp_t gfp)
 {
 	/* freed by apparmor_cred_free */
-	struct aa_task_cxt *cxt = aa_alloc_task_context(gfp);
-	if (!cxt)
+	struct aa_task_ctx *ctx = aa_alloc_task_context(gfp);
+	if (!ctx)
 		return -ENOMEM;
 
-	aa_dup_task_context(cxt, cred_cxt(old));
-	cred_cxt(new) = cxt;
+	aa_dup_task_context(ctx, cred_ctx(old));
+	cred_ctx(new) = ctx;
 	return 0;
 }
 
@@ -87,43 +94,71 @@ static int apparmor_cred_prepare(struct
  */
 static void apparmor_cred_transfer(struct cred *new, const struct cred *old)
 {
-	const struct aa_task_cxt *old_cxt = cred_cxt(old);
-	struct aa_task_cxt *new_cxt = cred_cxt(new);
+	const struct aa_task_ctx *old_ctx = cred_ctx(old);
+	struct aa_task_ctx *new_ctx = cred_ctx(new);
 
-	aa_dup_task_context(new_cxt, old_cxt);
+	aa_dup_task_context(new_ctx, old_ctx);
 }
 
 static int apparmor_ptrace_access_check(struct task_struct *child,
 					unsigned int mode)
 {
-	return aa_ptrace(current, child, mode);
+	struct aa_label *tracer, *tracee;
+	int error;
+
+	tracer = aa_begin_current_label(DO_UPDATE);
+	tracee = aa_get_task_label(child);
+	error = aa_may_ptrace(tracer, tracee,
+		  mode == PTRACE_MODE_READ ? AA_PTRACE_READ : AA_PTRACE_TRACE);
+	aa_put_label(tracee);
+	aa_end_current_label(tracer);
+
+	return error;
 }
 
 static int apparmor_ptrace_traceme(struct task_struct *parent)
 {
-	return aa_ptrace(parent, current, PTRACE_MODE_ATTACH);
+	struct aa_label *tracer, *tracee;
+	int error;
+
+	tracee = aa_begin_current_label(DO_UPDATE);
+	tracer = aa_get_task_label(parent);
+	error = aa_may_ptrace(tracer, tracee, AA_PTRACE_TRACE);
+	aa_put_label(tracer);
+	aa_end_current_label(tracee);
+
+	return error;
 }
 
 /* Derived from security/commoncap.c:cap_capget */
 static int apparmor_capget(struct task_struct *target, kernel_cap_t *effective,
 			   kernel_cap_t *inheritable, kernel_cap_t *permitted)
 {
-	struct aa_profile *profile;
+	struct aa_label *label;
 	const struct cred *cred;
 
 	rcu_read_lock();
 	cred = __task_cred(target);
-	profile = aa_cred_profile(cred);
+	label = aa_get_newest_cred_label(cred);
 
 	/*
 	 * cap_capget is stacked ahead of this and will
 	 * initialize effective and permitted.
 	 */
-	if (!unconfined(profile) && !COMPLAIN_MODE(profile)) {
-		*effective = cap_intersect(*effective, profile->caps.allow);
-		*permitted = cap_intersect(*permitted, profile->caps.allow);
+	if (!unconfined(label)) {
+		struct aa_profile *profile;
+		struct label_it i;
+		label_for_each_confined(i, label, profile) {
+			if (COMPLAIN_MODE(profile))
+				continue;
+			*effective = cap_intersect(*effective,
+						   profile->caps.allow);
+			*permitted = cap_intersect(*permitted,
+						   profile->caps.allow);
+		}
 	}
 	rcu_read_unlock();
+	aa_put_label(label);
 
 	return 0;
 }
@@ -131,12 +166,14 @@ static int apparmor_capget(struct task_s
 static int apparmor_capable(const struct cred *cred, struct user_namespace *ns,
 			    int cap, int audit)
 {
-	struct aa_profile *profile;
+	struct aa_label *label;
 	int error = 0;
 
-	profile = aa_cred_profile(cred);
-	if (!unconfined(profile))
-		error = aa_capable(profile, cap, audit);
+	label = aa_get_newest_cred_label(cred);
+	if (!unconfined(label))
+		error = aa_capable(label, cap, audit);
+	aa_put_label(label);
+
 	return error;
 }
 
@@ -149,19 +186,42 @@ static int apparmor_capable(const struct
  *
  * Returns: %0 else error code if error or permission denied
  */
-static int common_perm(int op, struct path *path, u32 mask,
+static int common_perm(const char *op, const struct path *path, u32 mask,
 		       struct path_cond *cond)
 {
-	struct aa_profile *profile;
+	struct aa_label *label;
 	int error = 0;
 
-	profile = __aa_current_profile();
-	if (!unconfined(profile))
-		error = aa_path_perm(op, profile, path, 0, mask, cond);
+	label = aa_begin_current_label(NO_UPDATE);
+	if (!unconfined(label))
+		error = aa_path_perm(op, label, path, 0, mask, cond);
+	aa_end_current_label(label);
 
 	return error;
 }
 
+static int common_perm_cond(const char *op, const struct path *path, u32 mask)
+{
+	struct path_cond cond = { d_backing_inode(path->dentry)->i_uid,
+				  d_backing_inode(path->dentry)->i_mode
+	};
+
+	if (!path_mediated_fs(path->dentry))
+		return 0;
+
+	return common_perm(op, path, mask, &cond);
+}
+
+static void apparmor_inode_free_security(struct inode *inode)
+{
+	struct aa_label *ctx = inode_ctx(inode);
+
+	if (ctx) {
+		inode_ctx(inode) = NULL;
+		aa_put_label(ctx);
+	}
+}
+
 /**
  * common_perm_dir_dentry - common permission wrapper when path is dir, dentry
  * @op: operation being checked
@@ -172,7 +232,7 @@ static int common_perm(int op, struct pa
  *
  * Returns: %0 else error code if error or permission denied
  */
-static int common_perm_dir_dentry(int op, struct path *dir,
+static int common_perm_dir_dentry(const char *op, const struct path *dir,
 				  struct dentry *dentry, u32 mask,
 				  struct path_cond *cond)
 {
@@ -182,26 +242,6 @@ static int common_perm_dir_dentry(int op
 }
 
 /**
- * common_perm_mnt_dentry - common permission wrapper when mnt, dentry
- * @op: operation being checked
- * @mnt: mount point of dentry (NOT NULL)
- * @dentry: dentry to check  (NOT NULL)
- * @mask: requested permissions mask
- *
- * Returns: %0 else error code if error or permission denied
- */
-static int common_perm_mnt_dentry(int op, struct vfsmount *mnt,
-				  struct dentry *dentry, u32 mask)
-{
-	struct path path = { mnt, dentry };
-	struct path_cond cond = { d_backing_inode(dentry)->i_uid,
-				  d_backing_inode(dentry)->i_mode
-	};
-
-	return common_perm(op, &path, mask, &cond);
-}
-
-/**
  * common_perm_rm - common permission wrapper for operations doing rm
  * @op: operation being checked
  * @dir: directory that the dentry is in  (NOT NULL)
@@ -210,13 +250,13 @@ static int common_perm_mnt_dentry(int op
  *
  * Returns: %0 else error code if error or permission denied
  */
-static int common_perm_rm(int op, struct path *dir,
+static int common_perm_rm(const char *op, const struct path *dir,
 			  struct dentry *dentry, u32 mask)
 {
 	struct inode *inode = d_backing_inode(dentry);
 	struct path_cond cond = { };
 
-	if (!inode || !dir->mnt || !mediated_filesystem(dentry))
+	if (!inode || !path_mediated_fs(dentry))
 		return 0;
 
 	cond.uid = inode->i_uid;
@@ -235,141 +275,123 @@ static int common_perm_rm(int op, struct
  *
  * Returns: %0 else error code if error or permission denied
  */
-static int common_perm_create(int op, struct path *dir, struct dentry *dentry,
-			      u32 mask, umode_t mode)
+static int common_perm_create(const char *op, const struct path *dir,
+			      struct dentry *dentry, u32 mask, umode_t mode)
 {
 	struct path_cond cond = { current_fsuid(), mode };
 
-	if (!dir->mnt || !mediated_filesystem(dir->dentry))
+	if (!path_mediated_fs(dir->dentry))
 		return 0;
 
 	return common_perm_dir_dentry(op, dir, dentry, mask, &cond);
 }
 
-static int apparmor_path_unlink(struct path *dir, struct dentry *dentry)
+static int apparmor_path_unlink(const struct path *dir, struct dentry *dentry)
 {
 	return common_perm_rm(OP_UNLINK, dir, dentry, AA_MAY_DELETE);
 }
 
-static int apparmor_path_mkdir(struct path *dir, struct dentry *dentry,
+static int apparmor_path_mkdir(const struct path *dir, struct dentry *dentry,
 			       umode_t mode)
 {
 	return common_perm_create(OP_MKDIR, dir, dentry, AA_MAY_CREATE,
 				  S_IFDIR);
 }
 
-static int apparmor_path_rmdir(struct path *dir, struct dentry *dentry)
+static int apparmor_path_rmdir(const struct path *dir, struct dentry *dentry)
 {
 	return common_perm_rm(OP_RMDIR, dir, dentry, AA_MAY_DELETE);
 }
 
-static int apparmor_path_mknod(struct path *dir, struct dentry *dentry,
+static int apparmor_path_mknod(const struct path *dir, struct dentry *dentry,
 			       umode_t mode, unsigned int dev)
 {
 	return common_perm_create(OP_MKNOD, dir, dentry, AA_MAY_CREATE, mode);
 }
 
-static int apparmor_path_truncate(struct path *path)
+static int apparmor_path_truncate(const struct path *path)
 {
-	struct path_cond cond = { d_backing_inode(path->dentry)->i_uid,
-				  d_backing_inode(path->dentry)->i_mode
-	};
-
-	if (!path->mnt || !mediated_filesystem(path->dentry))
-		return 0;
-
-	return common_perm(OP_TRUNC, path, MAY_WRITE | AA_MAY_META_WRITE,
-			   &cond);
+	return common_perm_cond(OP_TRUNC, path, MAY_WRITE | AA_MAY_SETATTR);
 }
 
-static int apparmor_path_symlink(struct path *dir, struct dentry *dentry,
+static int apparmor_path_symlink(const struct path *dir, struct dentry *dentry,
 				 const char *old_name)
 {
 	return common_perm_create(OP_SYMLINK, dir, dentry, AA_MAY_CREATE,
 				  S_IFLNK);
 }
 
-static int apparmor_path_link(struct dentry *old_dentry, struct path *new_dir,
+static int apparmor_path_link(struct dentry *old_dentry, const struct path *new_dir,
 			      struct dentry *new_dentry)
 {
-	struct aa_profile *profile;
+	struct aa_label *label;
 	int error = 0;
 
-	if (!mediated_filesystem(old_dentry))
+	if (!path_mediated_fs(old_dentry))
 		return 0;
 
-	profile = aa_current_profile();
-	if (!unconfined(profile))
-		error = aa_path_link(profile, old_dentry, new_dir, new_dentry);
+	label = aa_begin_current_label(DO_UPDATE);
+	if (!unconfined(label))
+		error = aa_path_link(label, old_dentry, new_dir, new_dentry);
+	aa_end_current_label(label);
+
 	return error;
 }
 
-static int apparmor_path_rename(struct path *old_dir, struct dentry *old_dentry,
-				struct path *new_dir, struct dentry *new_dentry)
+static int apparmor_path_rename(const struct path *old_dir, struct dentry *old_dentry,
+				const struct path *new_dir, struct dentry *new_dentry)
 {
-	struct aa_profile *profile;
+	struct aa_label *label;
 	int error = 0;
 
-	if (!mediated_filesystem(old_dentry))
+	if (!path_mediated_fs(old_dentry))
 		return 0;
 
-	profile = aa_current_profile();
-	if (!unconfined(profile)) {
+	label = aa_begin_current_label(DO_UPDATE);
+	if (!unconfined(label)) {
 		struct path old_path = { old_dir->mnt, old_dentry };
 		struct path new_path = { new_dir->mnt, new_dentry };
 		struct path_cond cond = { d_backing_inode(old_dentry)->i_uid,
 					  d_backing_inode(old_dentry)->i_mode
 		};
 
-		error = aa_path_perm(OP_RENAME_SRC, profile, &old_path, 0,
-				     MAY_READ | AA_MAY_META_READ | MAY_WRITE |
-				     AA_MAY_META_WRITE | AA_MAY_DELETE,
+		error = aa_path_perm(OP_RENAME_SRC, label, &old_path, 0,
+				     MAY_READ | AA_MAY_GETATTR | MAY_WRITE |
+				     AA_MAY_SETATTR | AA_MAY_DELETE,
 				     &cond);
 		if (!error)
-			error = aa_path_perm(OP_RENAME_DEST, profile, &new_path,
-					     0, MAY_WRITE | AA_MAY_META_WRITE |
+			error = aa_path_perm(OP_RENAME_DEST, label, &new_path,
+					     0, MAY_WRITE | AA_MAY_SETATTR |
 					     AA_MAY_CREATE, &cond);
 
 	}
+	aa_end_current_label(label);
+
 	return error;
 }
 
-static int apparmor_path_chmod(struct path *path, umode_t mode)
+static int apparmor_path_chmod(const struct path *path, umode_t mode)
 {
-	if (!mediated_filesystem(path->dentry))
-		return 0;
-
-	return common_perm_mnt_dentry(OP_CHMOD, path->mnt, path->dentry, AA_MAY_CHMOD);
+	return common_perm_cond(OP_CHMOD, path, AA_MAY_CHMOD);
 }
 
-static int apparmor_path_chown(struct path *path, kuid_t uid, kgid_t gid)
+static int apparmor_path_chown(const struct path *path, kuid_t uid, kgid_t gid)
 {
-	struct path_cond cond =  { d_backing_inode(path->dentry)->i_uid,
-				   d_backing_inode(path->dentry)->i_mode
-	};
-
-	if (!mediated_filesystem(path->dentry))
-		return 0;
-
-	return common_perm(OP_CHOWN, path, AA_MAY_CHOWN, &cond);
+	return common_perm_cond(OP_CHOWN, path, AA_MAY_CHOWN);
 }
 
 static int apparmor_inode_getattr(const struct path *path)
 {
-	if (!mediated_filesystem(path->dentry))
-		return 0;
-
-	return common_perm_mnt_dentry(OP_GETATTR, path->mnt, path->dentry,
-				      AA_MAY_META_READ);
+	return common_perm_cond(OP_GETATTR, path, AA_MAY_GETATTR);
 }
 
 static int apparmor_file_open(struct file *file, const struct cred *cred)
 {
-	struct aa_file_cxt *fcxt = file->f_security;
-	struct aa_profile *profile;
+	struct aa_file_ctx *fctx = file_ctx(file);
+	struct aa_label *label;
 	int error = 0;
 
-	if (!mediated_filesystem(file->f_path.dentry))
+	if (!path_mediated_fs(file->f_path.dentry))
 		return 0;
 
 	/* If in exec, permission is handled by bprm hooks.
@@ -378,69 +400,61 @@ static int apparmor_file_open(struct fil
 	 * actually execute the image.
 	 */
 	if (current->in_execve) {
-		fcxt->allow = MAY_EXEC | MAY_READ | AA_EXEC_MMAP;
+		fctx->allow = MAY_EXEC | MAY_READ | AA_EXEC_MMAP;
 		return 0;
 	}
 
-	profile = aa_cred_profile(cred);
-	if (!unconfined(profile)) {
+	label = aa_get_newest_cred_label(cred);
+	if (!unconfined(label)) {
 		struct inode *inode = file_inode(file);
 		struct path_cond cond = { inode->i_uid, inode->i_mode };
 
-		error = aa_path_perm(OP_OPEN, profile, &file->f_path, 0,
+		error = aa_path_perm(OP_OPEN, label, &file->f_path, 0,
 				     aa_map_file_to_perms(file), &cond);
 		/* todo cache full allowed permissions set and state */
-		fcxt->allow = aa_map_file_to_perms(file);
+		fctx->allow = aa_map_file_to_perms(file);
 	}
+	aa_put_label(label);
 
 	return error;
 }
 
 static int apparmor_file_alloc_security(struct file *file)
 {
+	int error = 0;
+
 	/* freed by apparmor_file_free_security */
-	file->f_security = aa_alloc_file_context(GFP_KERNEL);
-	if (!file->f_security)
-		return -ENOMEM;
-	return 0;
+	struct aa_label *label = aa_begin_current_label(DO_UPDATE);
+	file->f_security = aa_alloc_file_ctx(label, GFP_KERNEL);
+	if (!file_ctx(file))
+		error = -ENOMEM;
+	aa_end_current_label(label);
 
+	return error;
 }
 
 static void apparmor_file_free_security(struct file *file)
 {
-	struct aa_file_cxt *cxt = file->f_security;
-
-	aa_free_file_context(cxt);
+	aa_free_file_ctx(file_ctx(file));
 }
 
-static int common_file_perm(int op, struct file *file, u32 mask)
+static int common_file_perm(const char *op, struct file *file, u32 mask)
 {
-	struct aa_file_cxt *fcxt = file->f_security;
-	struct aa_profile *profile, *fprofile = aa_cred_profile(file->f_cred);
+	struct aa_label *label;
 	int error = 0;
 
-	BUG_ON(!fprofile);
-
-	if (!file->f_path.mnt ||
-	    !mediated_filesystem(file->f_path.dentry))
-		return 0;
-
-	profile = __aa_current_profile();
-
-	/* revalidate access, if task is unconfined, or the cached cred
-	 * doesn't match or if the request is for more permissions than
-	 * was granted.
-	 *
-	 * Note: the test for !unconfined(fprofile) is to handle file
-	 *       delegation from unconfined tasks
-	 */
-	if (!unconfined(profile) && !unconfined(fprofile) &&
-	    ((fprofile != profile) || (mask & ~fcxt->allow)))
-		error = aa_file_perm(op, profile, file, mask);
+	label = aa_begin_current_label(NO_UPDATE);
+	error = aa_file_perm(op, label, file, mask);
+	aa_end_current_label(label);
 
 	return error;
 }
 
+static int apparmor_file_receive(struct file *file)
+{
+	return common_file_perm(OP_FRECEIVE, file, aa_map_file_to_perms(file));
+}
+
 static int apparmor_file_permission(struct file *file, int mask)
 {
 	return common_file_perm(OP_FPERM, file, mask);
@@ -456,12 +470,12 @@ static int apparmor_file_lock(struct fil
 	return common_file_perm(OP_FLOCK, file, mask);
 }
 
-static int common_mmap(int op, struct file *file, unsigned long prot,
+static int common_mmap(const char *op, struct file *file, unsigned long prot,
 		       unsigned long flags)
 {
 	int mask = 0;
 
-	if (!file || !file->f_security)
+	if (!file || !file_ctx(file))
 		return 0;
 
 	if (prot & PROT_READ)
@@ -491,28 +505,87 @@ static int apparmor_file_mprotect(struct
 			   !(vma->vm_flags & VM_SHARED) ? MAP_PRIVATE : 0);
 }
 
+static int apparmor_sb_mount(const char *dev_name, const struct path *path,
+			     const char *type, unsigned long flags, void *data)
+{
+	struct aa_label *label;
+	int error = 0;
+
+	/* Discard magic */
+	if ((flags & MS_MGC_MSK) == MS_MGC_VAL)
+		flags &= ~MS_MGC_MSK;
+
+	flags &= ~AA_MS_IGNORE_MASK;
+
+	label = aa_begin_current_label(NO_UPDATE);
+	if (!unconfined(label)) {
+		if (flags & MS_REMOUNT)
+			error = aa_remount(label, path, flags, data);
+		else if (flags & MS_BIND)
+			error = aa_bind_mount(label, path, dev_name, flags);
+		else if (flags & (MS_SHARED | MS_PRIVATE | MS_SLAVE |
+				  MS_UNBINDABLE))
+			error = aa_mount_change_type(label, path, flags);
+		else if (flags & MS_MOVE)
+			error = aa_move_mount(label, path, dev_name);
+		else
+			error = aa_new_mount(label, dev_name, path, type,
+					     flags, data);
+	}
+	aa_end_current_label(label);
+
+	return error;
+}
+
+static int apparmor_sb_umount(struct vfsmount *mnt, int flags)
+{
+	struct aa_label *label;
+	int error = 0;
+
+	label = aa_begin_current_label(NO_UPDATE);
+	if (!unconfined(label))
+		error = aa_umount(label, mnt, flags);
+	aa_end_current_label(label);
+
+	return error;
+}
+
+static int apparmor_sb_pivotroot(const struct path *old_path,
+				 const struct path *new_path)
+{
+	struct aa_label *label;
+	int error = 0;
+
+	label = aa_get_current_label();
+	if (!unconfined(label))
+		error = aa_pivotroot(label, old_path, new_path);
+	aa_put_label(label);
+
+	return error;
+}
+
 static int apparmor_getprocattr(struct task_struct *task, char *name,
 				char **value)
 {
 	int error = -ENOENT;
 	/* released below */
 	const struct cred *cred = get_task_cred(task);
-	struct aa_task_cxt *cxt = cred_cxt(cred);
-	struct aa_profile *profile = NULL;
+	struct aa_task_ctx *ctx = cred_ctx(cred);
+	struct aa_label *label = NULL;
 
 	if (strcmp(name, "current") == 0)
-		profile = aa_get_newest_profile(cxt->profile);
-	else if (strcmp(name, "prev") == 0  && cxt->previous)
-		profile = aa_get_newest_profile(cxt->previous);
-	else if (strcmp(name, "exec") == 0 && cxt->onexec)
-		profile = aa_get_newest_profile(cxt->onexec);
+		label = aa_get_newest_label(ctx->label);
+	else if (strcmp(name, "prev") == 0  && ctx->previous)
+		label = aa_get_newest_label(ctx->previous);
+	else if (strcmp(name, "exec") == 0 && ctx->onexec)
+		label = aa_get_newest_label(ctx->onexec);
 	else
 		error = -EINVAL;
 
-	if (profile)
-		error = aa_getprocattr(profile, value);
+	if (label)
+		error = aa_getprocattr(label, value);
 
-	aa_put_profile(profile);
+	aa_put_label(label);
 	put_cred(cred);
 
 	return error;
@@ -521,38 +594,37 @@ static int apparmor_getprocattr(struct t
 static int apparmor_setprocattr(struct task_struct *task, char *name,
 				void *value, size_t size)
 {
-	struct common_audit_data sa;
-	struct apparmor_audit_data aad = {0,};
-	char *command, *args = value;
+	char *command, *largs = NULL, *args = value;
 	size_t arg_size;
 	int error;
+	DEFINE_AUDIT_DATA(sa, LSM_AUDIT_DATA_NONE, OP_SETPROCATTR);
 
 	if (size == 0)
 		return -EINVAL;
-	/* args points to a PAGE_SIZE buffer, AppArmor requires that
-	 * the buffer must be null terminated or have size <= PAGE_SIZE -1
-	 * so that AppArmor can null terminate them
-	 */
-	if (args[size - 1] != '\0') {
-		if (size == PAGE_SIZE)
-			return -EINVAL;
-		args[size] = '\0';
-	}
-
 	/* task can only write its own attributes */
 	if (current != task)
 		return -EACCES;
 
-	args = value;
+	/* AppArmor requires that the buffer must be null terminated atm */
+	if (args[size - 1] != '\0') {
+		/* null terminate */
+		largs = args = kmalloc(size + 1, GFP_KERNEL);
+		if (!args)
+			return -ENOMEM;
+		memcpy(args, value, size);
+		args[size] = '\0';
+	}
+
+	error = -EINVAL;
 	args = strim(args);
 	command = strsep(&args, " ");
 	if (!args)
-		return -EINVAL;
+		goto out;
 	args = skip_spaces(args);
 	if (!*args)
-		return -EINVAL;
+		goto out;
 
-	arg_size = size - (args - (char *) value);
+	arg_size = size - (args - (largs ? largs : (char *) value));
 	if (strcmp(name, "current") == 0) {
 		if (strcmp(command, "changehat") == 0) {
 			error = aa_setprocattr_changehat(args, arg_size,
@@ -561,79 +633,652 @@ static int apparmor_setprocattr(struct t
 			error = aa_setprocattr_changehat(args, arg_size,
 							 AA_DO_TEST);
 		} else if (strcmp(command, "changeprofile") == 0) {
-			error = aa_setprocattr_changeprofile(args, !AA_ONEXEC,
-							     !AA_DO_TEST);
+			error = aa_change_profile(args, !AA_ONEXEC,
+						  !AA_DO_TEST, false);
 		} else if (strcmp(command, "permprofile") == 0) {
-			error = aa_setprocattr_changeprofile(args, !AA_ONEXEC,
-							     AA_DO_TEST);
+			error = aa_change_profile(args, !AA_ONEXEC, AA_DO_TEST,
+						  false);
+		} else if (strcmp(command, "stack") == 0) {
+			error = aa_change_profile(args, !AA_ONEXEC, !AA_DO_TEST,
+						  true);
 		} else
 			goto fail;
 	} else if (strcmp(name, "exec") == 0) {
 		if (strcmp(command, "exec") == 0)
-			error = aa_setprocattr_changeprofile(args, AA_ONEXEC,
-							     !AA_DO_TEST);
+			error = aa_change_profile(args, AA_ONEXEC, !AA_DO_TEST,
+						  false);
+		else if (strcmp(command, "stack") == 0)
+			error = aa_change_profile(args, AA_ONEXEC, !AA_DO_TEST,
+						  true);
 		else
 			goto fail;
 	} else
 		/* only support the "current" and "exec" process attributes */
-		return -EINVAL;
+		goto fail;
 
 	if (!error)
 		error = size;
+out:
+	kfree(largs);
 	return error;
 
 fail:
-	sa.type = LSM_AUDIT_DATA_NONE;
-	sa.aad = &aad;
-	aad.profile = aa_current_profile();
-	aad.op = OP_SETPROCATTR;
-	aad.info = name;
-	aad.error = -EINVAL;
+	aad(&sa)->label = aa_begin_current_label(DO_UPDATE);
+	aad(&sa)->info = name;
+	aad(&sa)->error = error = -EINVAL;
 	aa_audit_msg(AUDIT_APPARMOR_DENIED, &sa, NULL);
-	return -EINVAL;
+	aa_end_current_label(aad(&sa)->label);
+	goto out;
+}
+
+/**
+ * apparmor_bprm_committing_creds - do task cleanup on committing new creds
+ * @bprm: binprm for the exec  (NOT NULL)
+ */
+void apparmor_bprm_committing_creds(struct linux_binprm *bprm)
+{
+	struct aa_label *label = aa_current_raw_label();
+	struct aa_task_ctx *new_ctx = cred_ctx(bprm->cred);
+
+	/* bail out if unconfined or not changing profile */
+	if ((new_ctx->label->proxy == label->proxy) ||
+	    (unconfined(new_ctx->label)))
+		return;
+
+	aa_inherit_files(bprm->cred, current->files);
+
+	current->pdeath_signal = 0;
+
+	/* reset soft limits and set hard limits for the new label */
+	__aa_transition_rlimits(label, new_ctx->label);
+}
+
+/**
+ * apparmor_bprm_commited_cred - do cleanup after new creds committed
+ * @bprm: binprm for the exec  (NOT NULL)
+ */
+void apparmor_bprm_committed_creds(struct linux_binprm *bprm)
+{
+	/* TODO: cleanup signals - ipc mediation */
+	return;
 }
 
 static int apparmor_task_setrlimit(struct task_struct *task,
 		unsigned int resource, struct rlimit *new_rlim)
 {
-	struct aa_profile *profile = __aa_current_profile();
+	struct aa_label *label = aa_begin_current_label(NO_UPDATE);
+	int error = 0;
+
+	if (!unconfined(label))
+		error = aa_task_setrlimit(label, task, resource, new_rlim);
+	aa_end_current_label(label);
+
+	return error;
+}
+
+/**
+ * apparmor_sk_alloc_security - allocate and attach the sk_security field
+ */
+static int apparmor_sk_alloc_security(struct sock *sk, int family, gfp_t flags)
+{
+	struct aa_sk_ctx *ctx;
+
+	ctx = kzalloc(sizeof(*ctx), flags);
+	if (!ctx)
+		return -ENOMEM;
+
+	SK_CTX(sk) = ctx;
+	//??? set local too current???
+
+	return 0;
+}
+
+/**
+ * apparmor_sk_free_security - free the sk_security field
+ */
+static void apparmor_sk_free_security(struct sock *sk)
+{
+	struct aa_sk_ctx *ctx = SK_CTX(sk);
+
+	SK_CTX(sk) = NULL;
+	aa_put_label(ctx->label);
+	aa_put_label(ctx->peer);
+	path_put(&ctx->path);
+	kfree(ctx);
+}
+
+/**
+ * apparmor_clone_security - clone the sk_security field
+ */
+static void apparmor_sk_clone_security(const struct sock *sk,
+				       struct sock *newsk)
+{
+	struct aa_sk_ctx *ctx = SK_CTX(sk);
+	struct aa_sk_ctx *new = SK_CTX(newsk);
+
+	new->label = aa_get_label(ctx->label);
+	new->peer = aa_get_label(ctx->peer);
+	new->path = ctx->path;
+	path_get(&new->path);
+}
+
+static struct path *UNIX_FS_CONN_PATH(struct sock *sk, struct sock *newsk)
+{
+	if (sk->sk_family == PF_UNIX && UNIX_FS(sk))
+		return &unix_sk(sk)->path;
+	else if (newsk->sk_family == PF_UNIX && UNIX_FS(newsk))
+		return &unix_sk(newsk)->path;
+	return NULL;
+}
+
+/**
+ * apparmor_unix_stream_connect - check perms before making unix domain conn
+ *
+ * peer is locked when this hook is called
+ */
+static int apparmor_unix_stream_connect(struct sock *sk, struct sock *peer_sk,
+					struct sock *newsk)
+{
+	struct aa_sk_ctx *sk_ctx = SK_CTX(sk);
+	struct aa_sk_ctx *peer_ctx = SK_CTX(peer_sk);
+	struct aa_sk_ctx *new_ctx = SK_CTX(newsk);
+	struct aa_label *label;
+	struct path *path;
+	int error;
+
+	label = aa_begin_current_label(NO_UPDATE);
+	error = aa_unix_peer_perm(label, OP_CONNECT,
+				(AA_MAY_CONNECT | AA_MAY_SEND | AA_MAY_RECEIVE),
+				  sk, peer_sk, NULL);
+	if (!UNIX_FS(peer_sk)) {
+		last_error(error,
+			aa_unix_peer_perm(peer_ctx->label, OP_CONNECT,
+				(AA_MAY_ACCEPT | AA_MAY_SEND | AA_MAY_RECEIVE),
+				peer_sk, sk, label));
+	}
+	aa_end_current_label(label);
+
+	if (error)
+		return error;
+
+	/* label newsk if it wasn't labeled in post_create. Normally this
+	 * would be done in sock_graft, but because we are directly looking
+	 * at the peer_sk to obtain peer_labeling for unix socks this
+	 * does not work
+	 */
+	if (!new_ctx->label)
+		new_ctx->label = aa_get_label(peer_ctx->label);
+
+	/* Cross reference the peer labels for SO_PEERSEC */
+	if (new_ctx->peer)
+		aa_put_label(new_ctx->peer);
+
+	if (sk_ctx->peer)
+		aa_put_label(sk_ctx->peer);
+
+	new_ctx->peer = aa_get_label(sk_ctx->label);
+	sk_ctx->peer = aa_get_label(peer_ctx->label);
+
+	path = UNIX_FS_CONN_PATH(sk, peer_sk);
+	if (path) {
+		new_ctx->path = *path;
+		sk_ctx->path = *path;
+		path_get(path);
+		path_get(path);
+	}
+	return 0;
+}
+
+/**
+ * apparmor_unix_may_send - check perms before conn or sending unix dgrams
+ *
+ * other is locked when this hook is called
+ *
+ * dgram connect calls may_send, peer setup but path not copied?????
+ */
+static int apparmor_unix_may_send(struct socket *sock, struct socket *peer)
+{
+	struct aa_sk_ctx *peer_ctx = SK_CTX(peer->sk);
+	struct aa_label *label = aa_begin_current_label(NO_UPDATE);
+	int error;
+
+	error = xcheck(aa_unix_peer_perm(label, OP_SENDMSG, AA_MAY_SEND,
+					 sock->sk, peer->sk, NULL),
+		       aa_unix_peer_perm(peer_ctx->label, OP_SENDMSG, AA_MAY_RECEIVE,
+					 peer->sk, sock->sk, label));
+	aa_end_current_label(label);
+
+	return error;
+}
+
+/**
+ * apparmor_socket_create - check perms before creating a new socket
+ */
+static int apparmor_socket_create(int family, int type, int protocol, int kern)
+{
+	struct aa_label *label;
 	int error = 0;
 
-	if (!unconfined(profile))
-		error = aa_task_setrlimit(profile, task, resource, new_rlim);
+	label = aa_begin_current_label(DO_UPDATE);
+	if (!(kern || unconfined(label)))
+		error = aa_sock_create_perm(label, family, type, protocol);
+	aa_end_current_label(label);
 
 	return error;
 }
 
+/**
+ * apparmor_socket_post_create - setup the per-socket security struct
+ *
+ * Note:
+ * -   kernel sockets currently labeled unconfined but we may want to
+ *     move to a special kernel label
+ * -   socket may not have sk here if created with sock_create_lite or
+ *     sock_alloc. These should be accept cases which will be handled in
+ *     sock_graft.
+ */
+static int apparmor_socket_post_create(struct socket *sock, int family,
+				       int type, int protocol, int kern)
+{
+	struct aa_label *label;
+
+	if (kern) {
+		struct aa_ns *ns = aa_get_current_ns();
+		label = aa_get_label(ns_unconfined(ns));
+		aa_put_ns(ns);
+	} else
+		label = aa_get_current_label();
+
+	if (sock->sk) {
+		struct aa_sk_ctx *ctx = SK_CTX(sock->sk);
+		aa_put_label(ctx->label);
+		ctx->label = aa_get_label(label);
+	}
+	aa_put_label(label);
+
+	return 0;
+}
+
+/**
+ * apparmor_socket_bind - check perms before bind addr to socket
+ */
+static int apparmor_socket_bind(struct socket *sock,
+				struct sockaddr *address, int addrlen)
+{
+	return aa_sock_bind_perm(sock, address, addrlen);
+}
+
+/**
+ * apparmor_socket_connect - check perms before connecting @sock to @address
+ */
+static int apparmor_socket_connect(struct socket *sock,
+				   struct sockaddr *address, int addrlen)
+{
+	return aa_sock_connect_perm(sock, address, addrlen);
+}
+
+/**
+ * apparmor_socket_list - check perms before allowing listen
+ */
+static int apparmor_socket_listen(struct socket *sock, int backlog)
+{
+	return aa_sock_listen_perm(sock, backlog);
+}
+
+/**
+ * apparmor_socket_accept - check perms before accepting a new connection.
+ *
+ * Note: while @newsock is created and has some information, the accept
+ *       has not been done.
+ */
+static int apparmor_socket_accept(struct socket *sock, struct socket *newsock)
+{
+	return aa_sock_accept_perm(sock, newsock);
+}
+
+/**
+ * apparmor_socket_sendmsg - check perms before sending msg to another socket
+ */
+static int apparmor_socket_sendmsg(struct socket *sock,
+				   struct msghdr *msg, int size)
+{
+	int error = aa_sock_msg_perm(OP_SENDMSG, AA_MAY_SEND, sock, msg, size);
+	if (!error) {
+		/* TODO: setup delegation on scm rights
+		   see smack for AF_INET, AF_INET6 */
+		;
+	}
+
+	return error;
+}
+
+/**
+ * apparmor_socket_recvmsg - check perms before receiving a message
+ */
+static int apparmor_socket_recvmsg(struct socket *sock,
+				   struct msghdr *msg, int size, int flags)
+{
+	return aa_sock_msg_perm(OP_RECVMSG, AA_MAY_RECEIVE, sock, msg, size);
+}
+
+/**
+ * apparmor_socket_getsockname - check perms before getting the local address
+ */
+static int apparmor_socket_getsockname(struct socket *sock)
+{
+	return aa_sock_perm(OP_GETSOCKNAME, AA_MAY_GETATTR, sock);
+}
+
+/**
+ * apparmor_socket_getpeername - check perms before getting remote address
+ */
+static int apparmor_socket_getpeername(struct socket *sock)
+{
+	return aa_sock_perm(OP_GETPEERNAME, AA_MAY_GETATTR, sock);
+}
+
+/**
+ * apparmor_getsockopt - check perms before getting socket options
+ */
+static int apparmor_socket_getsockopt(struct socket *sock, int level,
+				      int optname)
+{
+	return aa_sock_opt_perm(OP_GETSOCKOPT, AA_MAY_GETOPT, sock,
+				level, optname);
+}
+
+/**
+ * apparmor_setsockopt - check perms before setting socket options
+ */
+static int apparmor_socket_setsockopt(struct socket *sock, int level,
+				      int optname)
+{
+	return aa_sock_opt_perm(OP_SETSOCKOPT, AA_MAY_SETOPT, sock,
+				level, optname);
+}
+
+/**
+ * apparmor_socket_shutdown - check perms before shutting down @sock conn
+ */
+static int apparmor_socket_shutdown(struct socket *sock, int how)
+{
+	return aa_sock_perm(OP_SHUTDOWN, AA_MAY_SHUTDOWN, sock);
+}
+
+/**
+ * apparmor_socket_sock_recv_skb - check perms before associating skb to sk
+ *
+ * Note: can not sleep maybe called with locks held
+
+dont want protocol specific in __skb_recv_datagram()
+to deny an incoming connection  socket_sock_rcv_skb()
+
+ */
+static int apparmor_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
+{
+	/* TODO: */
+	return 0;
+}
+
+
+static struct aa_label *sk_peer_label(struct sock *sk)
+{
+	struct sock *peer_sk;
+	struct aa_sk_ctx *ctx = SK_CTX(sk);
+
+	if (ctx->peer)
+		return ctx->peer;
+
+	if (sk->sk_family != PF_UNIX)
+		return ERR_PTR(-ENOPROTOOPT);
+
+	/* check for sockpair peering which does not go through
+	 * security_unix_stream_connect
+	 */
+	peer_sk = unix_peer(sk);
+	if (peer_sk) {
+		ctx = SK_CTX(peer_sk);
+		if (ctx->label)
+			return ctx->label;
+	}
+
+	return ERR_PTR(-ENOPROTOOPT);
+}
+
+/**
+ * apparmor_socket_getpeersec_stream - get security context of peer
+ *
+ * Note: for tcp only valid if using ipsec or cipso on lan
+ */
+static int apparmor_socket_getpeersec_stream(struct socket *sock,
+					     char __user *optval,
+					     int __user *optlen, unsigned len)
+{
+	char *name;
+	int slen, error = 0;
+	struct aa_label *label = aa_begin_current_label(DO_UPDATE);
+	struct aa_label *peer = sk_peer_label(sock->sk);
+
+	if (IS_ERR(peer))
+		return PTR_ERR(peer);
+
+	slen = aa_label_asxprint(&name, labels_ns(label), peer,
+				 FLAG_SHOW_MODE | FLAG_VIEW_SUBNS |
+				 FLAG_HIDDEN_UNCONFINED, GFP_KERNEL);
+	/* don't include terminating \0 in slen, it breaks some apps */
+	if (slen < 0) {
+		error = -ENOMEM;
+	} else {
+		if (slen > len) {
+			error = -ERANGE;
+		} else if (copy_to_user(optval, name, slen)) {
+			error = -EFAULT;
+			goto out;
+		}
+		if (put_user(slen, optlen))
+			error = -EFAULT;
+	out:
+		kfree(name);
+
+	}
+	aa_end_current_label(label);
+
+	return error;
+}
+
+/**
+ * apparmor_socket_getpeersec_dgram - get security label of packet
+ * @sock: the peer socket
+ * @skb: packet data
+ * @secid: pointer to where to put the secid of the packet
+ *
+ * Sets the netlabel socket state on sk from parent
+ */
+static int apparmor_socket_getpeersec_dgram(struct socket *sock,
+					    struct sk_buff *skb, u32 *secid)
+
+{
+	/* TODO: requires secid support, and netlabel */
+	return -ENOPROTOOPT;
+}
+
+/**
+ * apparmor_sock_graft - Initialize newly created socket
+ * @sk: child sock
+ * @parent: parent socket
+ *
+ * Note: could set off of SOCK_CTX(parent) but need to track inode and we can
+ *       just set sk security information off of current creating process label
+ *       Labeling of sk for accept case - probably should be sock based
+ *       instead of task, because of the case where an implicitly labeled
+ *       socket is shared by different tasks.
+ */
+static void apparmor_sock_graft(struct sock *sk, struct socket *parent)
+{
+	struct aa_sk_ctx *ctx = SK_CTX(sk);
+	if (!ctx->label)
+		ctx->label = aa_get_current_label();
+}
+
+static int apparmor_task_kill(struct task_struct *target, struct siginfo *info,
+			      int sig, u32 secid)
+{
+	struct aa_label *cl, *tl;
+	int error;
+
+	if (secid)
+		/* TODO: after secid to label mapping is done.
+		 *  Dealing with USB IO specific behavior
+		 */
+		return 0;
+	cl = aa_begin_current_label(NO_UPDATE);
+	tl = aa_get_task_label(target);
+	error = aa_may_signal(cl, tl, sig);
+	aa_put_label(tl);
+	aa_end_current_label(cl);
+
+	return error;
+}
+
+/* 4.6 backport wrappers to keep constification of struct path */
+static int wrap_apparmor_sb_mount(const char *dev_name, struct path *path,
+				  const char *type, unsigned long flags,
+				  void *data)
+{
+	return apparmor_sb_mount(dev_name, path, type, flags, data);
+}
+
+static int wrap_apparmor_sb_pivotroot(struct path *old_path,
+				      struct path *new_path)
+{
+	return apparmor_sb_pivotroot(old_path, new_path);
+}
+
+static int wrap_apparmor_path_link(struct dentry *old_dentry,
+				   struct path *new_dir,
+				   struct dentry *new_dentry)
+{
+	return apparmor_path_link(old_dentry, new_dir, new_dentry);
+}
+
+static int wrap_apparmor_path_unlink(struct path *dir, struct dentry *dentry)
+{
+	return apparmor_path_unlink(dir, dentry);
+}
+
+static int wrap_apparmor_path_symlink(struct path *dir, struct dentry *dentry,
+				      const char *old_name)
+{
+	return apparmor_path_symlink(dir, dentry, old_name);
+}
+
+static int wrap_apparmor_path_mkdir(struct path *dir, struct dentry *dentry,
+				    umode_t mode)
+{
+	return apparmor_path_mkdir(dir, dentry, mode);
+}
+
+static int wrap_apparmor_path_rmdir(struct path *dir, struct dentry *dentry)
+{
+	return apparmor_path_rmdir(dir, dentry);
+}
+
+static int wrap_apparmor_path_mknod(struct path *dir, struct dentry *dentry,
+				    umode_t mode, unsigned int dev)
+{
+	return apparmor_path_mknod(dir, dentry, mode, dev);
+}
+
+static int wrap_apparmor_path_rename(struct path *old_dir,
+				     struct dentry *old_dentry,
+				     struct path *new_dir,
+				     struct dentry *new_dentry)
+{
+	return apparmor_path_rename(old_dir, old_dentry, new_dir, new_dentry);
+}
+
+static int wrap_apparmor_path_chmod(struct path *path, umode_t mode)
+{
+	return apparmor_path_chmod(path, mode);
+}
+
+static int wrap_apparmor_path_chown(struct path *path, kuid_t uid, kgid_t gid)
+{
+	return apparmor_path_chown(path, uid, gid);
+}
+
+static int wrap_apparmor_path_truncate(struct path *path)
+{
+	return apparmor_path_truncate(path);
+}
+
+#ifndef LSM_HOOKS_NAME
+#define LSM_HOOKS_NAME(X) //.name =	(X),
+#endif
 static struct security_hook_list apparmor_hooks[] = {
+	LSM_HOOKS_NAME("apparmor")
+
 	LSM_HOOK_INIT(ptrace_access_check, apparmor_ptrace_access_check),
 	LSM_HOOK_INIT(ptrace_traceme, apparmor_ptrace_traceme),
 	LSM_HOOK_INIT(capget, apparmor_capget),
 	LSM_HOOK_INIT(capable, apparmor_capable),
 
-	LSM_HOOK_INIT(path_link, apparmor_path_link),
-	LSM_HOOK_INIT(path_unlink, apparmor_path_unlink),
-	LSM_HOOK_INIT(path_symlink, apparmor_path_symlink),
-	LSM_HOOK_INIT(path_mkdir, apparmor_path_mkdir),
-	LSM_HOOK_INIT(path_rmdir, apparmor_path_rmdir),
-	LSM_HOOK_INIT(path_mknod, apparmor_path_mknod),
-	LSM_HOOK_INIT(path_rename, apparmor_path_rename),
-	LSM_HOOK_INIT(path_chmod, apparmor_path_chmod),
-	LSM_HOOK_INIT(path_chown, apparmor_path_chown),
-	LSM_HOOK_INIT(path_truncate, apparmor_path_truncate),
+	LSM_HOOK_INIT(inode_free_security, apparmor_inode_free_security),
+
+	LSM_HOOK_INIT(sb_mount, wrap_apparmor_sb_mount),
+	LSM_HOOK_INIT(sb_umount, apparmor_sb_umount),
+	LSM_HOOK_INIT(sb_pivotroot, wrap_apparmor_sb_pivotroot),
+
+	LSM_HOOK_INIT(path_link, wrap_apparmor_path_link),
+	LSM_HOOK_INIT(path_unlink, wrap_apparmor_path_unlink),
+	LSM_HOOK_INIT(path_symlink, wrap_apparmor_path_symlink),
+	LSM_HOOK_INIT(path_mkdir, wrap_apparmor_path_mkdir),
+	LSM_HOOK_INIT(path_rmdir, wrap_apparmor_path_rmdir),
+	LSM_HOOK_INIT(path_mknod, wrap_apparmor_path_mknod),
+	LSM_HOOK_INIT(path_rename, wrap_apparmor_path_rename),
+	LSM_HOOK_INIT(path_chmod, wrap_apparmor_path_chmod),
+	LSM_HOOK_INIT(path_chown, wrap_apparmor_path_chown),
+	LSM_HOOK_INIT(path_truncate, wrap_apparmor_path_truncate),
 	LSM_HOOK_INIT(inode_getattr, apparmor_inode_getattr),
 
 	LSM_HOOK_INIT(file_open, apparmor_file_open),
+	LSM_HOOK_INIT(file_receive, apparmor_file_receive),
 	LSM_HOOK_INIT(file_permission, apparmor_file_permission),
 	LSM_HOOK_INIT(file_alloc_security, apparmor_file_alloc_security),
 	LSM_HOOK_INIT(file_free_security, apparmor_file_free_security),
 	LSM_HOOK_INIT(mmap_file, apparmor_mmap_file),
+	LSM_HOOK_INIT(mmap_addr, cap_mmap_addr),
 	LSM_HOOK_INIT(file_mprotect, apparmor_file_mprotect),
 	LSM_HOOK_INIT(file_lock, apparmor_file_lock),
 
 	LSM_HOOK_INIT(getprocattr, apparmor_getprocattr),
 	LSM_HOOK_INIT(setprocattr, apparmor_setprocattr),
 
+	LSM_HOOK_INIT(sk_alloc_security, apparmor_sk_alloc_security),
+	LSM_HOOK_INIT(sk_free_security, apparmor_sk_free_security),
+	LSM_HOOK_INIT(sk_clone_security, apparmor_sk_clone_security),
+
+	LSM_HOOK_INIT(unix_stream_connect, apparmor_unix_stream_connect),
+	LSM_HOOK_INIT(unix_may_send, apparmor_unix_may_send),
+
+	LSM_HOOK_INIT(socket_create, apparmor_socket_create),
+	LSM_HOOK_INIT(socket_post_create, apparmor_socket_post_create),
+	LSM_HOOK_INIT(socket_bind, apparmor_socket_bind),
+	LSM_HOOK_INIT(socket_connect, apparmor_socket_connect),
+	LSM_HOOK_INIT(socket_listen, apparmor_socket_listen),
+	LSM_HOOK_INIT(socket_accept, apparmor_socket_accept),
+	LSM_HOOK_INIT(socket_sendmsg, apparmor_socket_sendmsg),
+	LSM_HOOK_INIT(socket_recvmsg, apparmor_socket_recvmsg),
+	LSM_HOOK_INIT(socket_getsockname, apparmor_socket_getsockname),
+	LSM_HOOK_INIT(socket_getpeername, apparmor_socket_getpeername),
+	LSM_HOOK_INIT(socket_getsockopt, apparmor_socket_getsockopt),
+	LSM_HOOK_INIT(socket_setsockopt, apparmor_socket_setsockopt),
+	LSM_HOOK_INIT(socket_shutdown, apparmor_socket_shutdown),
+	LSM_HOOK_INIT(socket_sock_rcv_skb, apparmor_socket_sock_rcv_skb),
+	LSM_HOOK_INIT(socket_getpeersec_stream,	apparmor_socket_getpeersec_stream),
+	LSM_HOOK_INIT(socket_getpeersec_dgram, apparmor_socket_getpeersec_dgram),
+	LSM_HOOK_INIT(sock_graft, apparmor_sock_graft),
+
 	LSM_HOOK_INIT(cred_alloc_blank, apparmor_cred_alloc_blank),
 	LSM_HOOK_INIT(cred_free, apparmor_cred_free),
 	LSM_HOOK_INIT(cred_prepare, apparmor_cred_prepare),
@@ -645,6 +1290,7 @@ static struct security_hook_list apparmo
 	LSM_HOOK_INIT(bprm_secureexec, apparmor_bprm_secureexec),
 
 	LSM_HOOK_INIT(task_setrlimit, apparmor_task_setrlimit),
+	LSM_HOOK_INIT(task_kill, apparmor_task_kill),
 };
 
 /*
@@ -690,23 +1336,28 @@ static int param_get_mode(char *buffer,
 /* AppArmor global enforcement switch - complain, enforce, kill */
 enum profile_mode aa_g_profile_mode = APPARMOR_ENFORCE;
 module_param_call(mode, param_set_mode, param_get_mode,
-		  &aa_g_profile_mode, S_IRUSR | S_IWUSR);
+		  &aa_g_profile_mode, S_IRUGO | S_IWUSR);
+
+#ifdef CONFIG_SECURITY_APPARMOR_HASH
+/* whether policy verification hashing is enabled */
+bool aa_g_hash_policy = IS_ENABLED(CONFIG_SECURITY_APPARMOR_HASH_DEFAULT);
+module_param_named(hash_policy, aa_g_hash_policy, aabool, S_IRUSR | S_IWUSR);
+#endif
 
 /* Debug mode */
 bool aa_g_debug;
-module_param_named(debug, aa_g_debug, aabool, S_IRUSR | S_IWUSR);
+module_param_named(debug, aa_g_debug, aabool, S_IRUGO | S_IWUSR);
 
 /* Audit mode */
 enum audit_mode aa_g_audit;
-module_param_call(audit, param_set_audit, param_get_audit,
-		  &aa_g_audit, S_IRUSR | S_IWUSR);
+module_param_call(audit, param_set_audit, param_get_audit, &aa_g_audit,
+		  S_IRUGO | S_IWUSR);
 
 /* Determines if audit header is included in audited messages.  This
  * provides more context if the audit daemon is not running
  */
 bool aa_g_audit_header = 1;
-module_param_named(audit_header, aa_g_audit_header, aabool,
-		   S_IRUSR | S_IWUSR);
+module_param_named(audit_header, aa_g_audit_header, aabool, S_IRUGO | S_IWUSR);
 
 /* lock out loading/removal of policy
  * TODO: add in at boot loading of policy, which is the only way to
@@ -714,27 +1365,33 @@ module_param_named(audit_header, aa_g_au
  */
 bool aa_g_lock_policy;
 module_param_named(lock_policy, aa_g_lock_policy, aalockpolicy,
-		   S_IRUSR | S_IWUSR);
+		   S_IRUGO | S_IWUSR);
 
 /* Syscall logging mode */
 bool aa_g_logsyscall;
-module_param_named(logsyscall, aa_g_logsyscall, aabool, S_IRUSR | S_IWUSR);
+module_param_named(logsyscall, aa_g_logsyscall, aabool, S_IRUGO | S_IWUSR);
 
 /* Maximum pathname length before accesses will start getting rejected */
 unsigned int aa_g_path_max = 2 * PATH_MAX;
-module_param_named(path_max, aa_g_path_max, aauint, S_IRUSR | S_IWUSR);
+module_param_named(path_max, aa_g_path_max, aauint, S_IRUGO | S_IWUSR);
 
 /* Determines how paranoid loading of policy is and how much verification
  * on the loaded policy is done.
+ * DEPRECATED: read only as strict checking of load is always done now
+ * that none root users (user namespaces) can load policy.
  */
 bool aa_g_paranoid_load = 1;
-module_param_named(paranoid_load, aa_g_paranoid_load, aabool,
-		   S_IRUSR | S_IWUSR);
+module_param_named(paranoid_load, aa_g_paranoid_load, aabool, S_IRUGO);
 
 /* Boot time disable flag */
 static bool apparmor_enabled = CONFIG_SECURITY_APPARMOR_BOOTPARAM_VALUE;
 module_param_named(enabled, apparmor_enabled, bool, S_IRUGO);
 
+/* Boot time to set use of default or unconfined as initial profile */
+bool aa_g_unconfined_init = CONFIG_SECURITY_APPARMOR_UNCONFINED_INIT;
+module_param_named(unconfined, aa_g_unconfined_init, aabool, S_IRUGO);
+
+
 static int __init apparmor_enabled_setup(char *str)
 {
 	unsigned long enabled;
@@ -749,68 +1406,72 @@ __setup("apparmor=", apparmor_enabled_se
 /* set global flag turning off the ability to load policy */
 static int param_set_aalockpolicy(const char *val, const struct kernel_param *kp)
 {
-	if (!capable(CAP_MAC_ADMIN))
+	if (!policy_admin_capable(NULL))
 		return -EPERM;
-	if (aa_g_lock_policy)
-		return -EACCES;
 	return param_set_bool(val, kp);
 }
 
 static int param_get_aalockpolicy(char *buffer, const struct kernel_param *kp)
 {
-	if (!capable(CAP_MAC_ADMIN))
+	if (!policy_view_capable(NULL))
 		return -EPERM;
+	if (!apparmor_enabled)
+		return -EINVAL;
 	return param_get_bool(buffer, kp);
 }
 
 static int param_set_aabool(const char *val, const struct kernel_param *kp)
 {
-	if (!capable(CAP_MAC_ADMIN))
+	if (!policy_admin_capable(NULL))
 		return -EPERM;
+	if (!apparmor_enabled)
+		return -EINVAL;
 	return param_set_bool(val, kp);
 }
 
 static int param_get_aabool(char *buffer, const struct kernel_param *kp)
 {
-	if (!capable(CAP_MAC_ADMIN))
+	if (!policy_view_capable(NULL))
 		return -EPERM;
+	if (!apparmor_enabled)
+		return -EINVAL;
 	return param_get_bool(buffer, kp);
 }
 
 static int param_set_aauint(const char *val, const struct kernel_param *kp)
 {
-	if (!capable(CAP_MAC_ADMIN))
+	if (!policy_admin_capable(NULL))
 		return -EPERM;
+	if (!apparmor_enabled)
+		return -EINVAL;
 	return param_set_uint(val, kp);
 }
 
 static int param_get_aauint(char *buffer, const struct kernel_param *kp)
 {
-	if (!capable(CAP_MAC_ADMIN))
+	if (!policy_view_capable(NULL))
 		return -EPERM;
+	if (!apparmor_enabled)
+		return -EINVAL;
 	return param_get_uint(buffer, kp);
 }
 
 static int param_get_audit(char *buffer, struct kernel_param *kp)
 {
-	if (!capable(CAP_MAC_ADMIN))
+	if (!policy_view_capable(NULL))
 		return -EPERM;
-
 	if (!apparmor_enabled)
 		return -EINVAL;
-
 	return sprintf(buffer, "%s", audit_mode_names[aa_g_audit]);
 }
 
 static int param_set_audit(const char *val, struct kernel_param *kp)
 {
 	int i;
-	if (!capable(CAP_MAC_ADMIN))
+	if (!policy_admin_capable(NULL))
 		return -EPERM;
-
 	if (!apparmor_enabled)
 		return -EINVAL;
-
 	if (!val)
 		return -EINVAL;
 
@@ -826,9 +1487,8 @@ static int param_set_audit(const char *v
 
 static int param_get_mode(char *buffer, struct kernel_param *kp)
 {
-	if (!capable(CAP_MAC_ADMIN))
+	if (!policy_view_capable(NULL))
 		return -EPERM;
-
 	if (!apparmor_enabled)
 		return -EINVAL;
 
@@ -838,12 +1498,10 @@ static int param_get_mode(char *buffer,
 static int param_set_mode(const char *val, struct kernel_param *kp)
 {
 	int i;
-	if (!capable(CAP_MAC_ADMIN))
+	if (!policy_admin_capable(NULL))
 		return -EPERM;
-
 	if (!apparmor_enabled)
 		return -EINVAL;
-
 	if (!val)
 		return -EINVAL;
 
@@ -862,24 +1520,106 @@ static int param_set_mode(const char *va
  */
 
 /**
- * set_init_cxt - set a task context and profile on the first task.
- *
- * TODO: allow setting an alternate profile than unconfined
+ * set_init_ctx - set a task context and profile on the first task.
  */
-static int __init set_init_cxt(void)
+static int __init set_init_ctx(void)
 {
 	struct cred *cred = (struct cred *)current->real_cred;
-	struct aa_task_cxt *cxt;
+	struct aa_task_ctx *ctx;
 
-	cxt = aa_alloc_task_context(GFP_KERNEL);
-	if (!cxt)
+	ctx = aa_alloc_task_context(GFP_KERNEL);
+	if (!ctx)
 		return -ENOMEM;
 
-	cxt->profile = aa_get_profile(root_ns->unconfined);
-	cred_cxt(cred) = cxt;
+	if (!aa_g_unconfined_init) {
+		ctx->label = aa_setup_default_label();
+		if (!ctx->label) {
+			aa_free_task_context(ctx);
+			return -ENOMEM;
+		}
+		/* fs setup of default is done in aa_create_aafs() */
+	} else
+		ctx->label = aa_get_label(ns_unconfined(root_ns));
+	cred_ctx(cred) = ctx;
+
+	return 0;
+}
+
+static void destroy_buffers(void)
+{
+	u32 i, j;
+
+	for_each_possible_cpu(i) {
+		for_each_cpu_buffer(j) {
+			kfree(per_cpu(aa_buffers, i).buf[j]);
+			per_cpu(aa_buffers, i).buf[j] = NULL;
+		}
+	}
+}
+
+static int __init alloc_buffers(void)
+{
+	u32 i, j;
+
+	for_each_possible_cpu(i) {
+		for_each_cpu_buffer(j) {
+			char *buffer;
+			if (cpu_to_node(i) > num_online_nodes())
+				/* fallback to kmalloc for offline nodes */
+				buffer = kmalloc(aa_g_path_max, GFP_KERNEL);
+			else
+				buffer = kmalloc_node(aa_g_path_max, GFP_KERNEL,
+						      cpu_to_node(i));
+			if (!buffer) {
+				destroy_buffers();
+				return -ENOMEM;
+			}
+			per_cpu(aa_buffers, i).buf[j] = buffer;
+		}
+	}
+
+	return 0;
+}
+
+#ifdef CONFIG_SYSCTL
+static int apparmor_dointvec(struct ctl_table *table, int write,
+			     void __user *buffer, size_t *lenp, loff_t *ppos)
+{
+	if (!policy_admin_capable(NULL))
+		return -EPERM;
+	if (!apparmor_enabled)
+		return -EINVAL;
+
+	return proc_dointvec(table, write, buffer, lenp, ppos);
+}
 
+static struct ctl_path apparmor_sysctl_path[] = {
+	{ .procname = "kernel", },
+	{ }
+};
+
+static struct ctl_table apparmor_sysctl_table[] = {
+	{
+		.procname	= "unprivileged_userns_apparmor_policy",
+		.data		= &unprivileged_userns_apparmor_policy,
+		.maxlen		= sizeof(int),
+		.mode		= 0600,
+		.proc_handler	= apparmor_dointvec,
+	},
+	{ }
+};
+
+static int __init apparmor_init_sysctl(void)
+{
+	return register_sysctl_paths(apparmor_sysctl_path,
+				     apparmor_sysctl_table) ? 0 : -ENOMEM;
+}
+#else
+static inline int apparmor_init_sysctl(void)
+{
 	return 0;
 }
+#endif /* CONFIG_SYSCTL */
 
 static int __init apparmor_init(void)
 {
@@ -891,17 +1631,36 @@ static int __init apparmor_init(void)
 		return 0;
 	}
 
+	error = aa_setup_dfa_engine();
+	if (error) {
+		AA_ERROR("Unable to setup dfa engine\n");
+		goto alloc_out;
+	}
+
 	error = aa_alloc_root_ns();
 	if (error) {
 		AA_ERROR("Unable to allocate default profile namespace\n");
 		goto alloc_out;
 	}
 
-	error = set_init_cxt();
+	error = apparmor_init_sysctl();
+	if (error) {
+		AA_ERROR("Unable to register sysctls\n");
+		goto alloc_out;
+
+	}
+
+	error = alloc_buffers();
+	if (error) {
+		AA_ERROR("Unable to allocate work buffers\n");
+		goto buffers_out;
+	}
+
+	error = set_init_ctx();
 	if (error) {
 		AA_ERROR("Failed to set context on init task\n");
 		aa_free_root_ns();
-		goto alloc_out;
+		goto buffers_out;
 	}
 	security_add_hooks(apparmor_hooks, ARRAY_SIZE(apparmor_hooks));
 
@@ -916,8 +1675,12 @@ static int __init apparmor_init(void)
 
 	return error;
 
+buffers_out:
+	destroy_buffers();
+
 alloc_out:
 	aa_destroy_aafs();
+	aa_teardown_dfa_engine();
 
 	apparmor_enabled = 0;
 	return error;
--- zfcpdump-kernel-4.4.orig/security/apparmor/match.c
+++ zfcpdump-kernel-4.4/security/apparmor/match.c
@@ -20,11 +20,38 @@
 #include <linux/err.h>
 #include <linux/kref.h>
 
-#include "include/apparmor.h"
+#include "include/lib.h"
 #include "include/match.h"
 
 #define base_idx(X) ((X) & 0xffffff)
 
+static char nulldfa_src[] = {
+	#include "nulldfa.in"
+};
+struct aa_dfa *nulldfa;
+
+int aa_setup_dfa_engine(void)
+{
+	int error;
+
+	nulldfa = aa_dfa_unpack(nulldfa_src, sizeof(nulldfa_src),
+				TO_ACCEPT1_FLAG(YYTD_DATA32) |
+				TO_ACCEPT2_FLAG(YYTD_DATA32));
+	if (!IS_ERR(nulldfa))
+		return 0;
+
+	error = PTR_ERR(nulldfa);
+	nulldfa = NULL;
+
+	return error;
+}
+
+void aa_teardown_dfa_engine(void)
+{
+	aa_put_dfa(nulldfa);
+	nulldfa = NULL;
+}
+
 /**
  * unpack_table - unpack a dfa table (one of accept, default, base, next check)
  * @blob: data to unpack (NOT NULL)
@@ -47,6 +74,8 @@ static struct table_header *unpack_table
 	 * it every time we use td_id as an index
 	 */
 	th.td_id = be16_to_cpu(*(u16 *) (blob)) - 1;
+	if (th.td_id > YYTD_ID_MAX)
+		goto out;
 	th.td_flags = be16_to_cpu(*(u16 *) (blob + 2));
 	th.td_lolen = be32_to_cpu(*(u32 *) (blob + 8));
 	blob += sizeof(struct table_header);
@@ -61,7 +90,9 @@ static struct table_header *unpack_table
 
 	table = kvzalloc(tsize);
 	if (table) {
-		*table = th;
+		table->td_id = th.td_id;
+		table->td_flags = th.td_flags;
+		table->td_lolen = th.td_lolen;
 		if (th.td_flags == YYTD_DATA8)
 			UNPACK_ARRAY(table->td_data, blob, th.td_lolen,
 				     u8, byte_to_byte);
@@ -73,14 +104,14 @@ static struct table_header *unpack_table
 				     u32, be32_to_cpu);
 		else
 			goto fail;
+		/* if table was vmalloced make sure the page tables are synced
+		 * before it is used, as it goes live to all cpus.
+		 */
+		if (is_vmalloc_addr(table))
+			vm_unmap_aliases();
 	}
 
 out:
-	/* if table was vmalloced make sure the page tables are synced
-	 * before it is used, as it goes live to all cpus.
-	 */
-	if (is_vmalloc_addr(table))
-		vm_unmap_aliases();
 	return table;
 fail:
 	kvfree(table);
--- /dev/null
+++ zfcpdump-kernel-4.4/security/apparmor/mount.c
@@ -0,0 +1,704 @@
+/*
+ * AppArmor security module
+ *
+ * This file contains AppArmor mediation of files
+ *
+ * Copyright (C) 1998-2008 Novell/SUSE
+ * Copyright 2009-2012 Canonical Ltd.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2 of the
+ * License.
+ */
+
+#include <linux/fs.h>
+#include <linux/mount.h>
+#include <linux/namei.h>
+
+#include "include/apparmor.h"
+#include "include/audit.h"
+#include "include/context.h"
+#include "include/domain.h"
+#include "include/file.h"
+#include "include/match.h"
+#include "include/mount.h"
+#include "include/path.h"
+#include "include/policy.h"
+
+
+static void audit_mnt_flags(struct audit_buffer *ab, unsigned long flags)
+{
+	if (flags & MS_RDONLY)
+		audit_log_format(ab, "ro");
+	else
+		audit_log_format(ab, "rw");
+	if (flags & MS_NOSUID)
+		audit_log_format(ab, ", nosuid");
+	if (flags & MS_NODEV)
+		audit_log_format(ab, ", nodev");
+	if (flags & MS_NOEXEC)
+		audit_log_format(ab, ", noexec");
+	if (flags & MS_SYNCHRONOUS)
+		audit_log_format(ab, ", sync");
+	if (flags & MS_REMOUNT)
+		audit_log_format(ab, ", remount");
+	if (flags & MS_MANDLOCK)
+		audit_log_format(ab, ", mand");
+	if (flags & MS_DIRSYNC)
+		audit_log_format(ab, ", dirsync");
+	if (flags & MS_NOATIME)
+		audit_log_format(ab, ", noatime");
+	if (flags & MS_NODIRATIME)
+		audit_log_format(ab, ", nodiratime");
+	if (flags & MS_BIND)
+		audit_log_format(ab, flags & MS_REC ? ", rbind" : ", bind");
+	if (flags & MS_MOVE)
+		audit_log_format(ab, ", move");
+	if (flags & MS_SILENT)
+		audit_log_format(ab, ", silent");
+	if (flags & MS_POSIXACL)
+		audit_log_format(ab, ", acl");
+	if (flags & MS_UNBINDABLE)
+		audit_log_format(ab, flags & MS_REC ? ", runbindable" :
+				 ", unbindable");
+	if (flags & MS_PRIVATE)
+		audit_log_format(ab, flags & MS_REC ? ", rprivate" :
+				 ", private");
+	if (flags & MS_SLAVE)
+		audit_log_format(ab, flags & MS_REC ? ", rslave" :
+				 ", slave");
+	if (flags & MS_SHARED)
+		audit_log_format(ab, flags & MS_REC ? ", rshared" :
+				 ", shared");
+	if (flags & MS_RELATIME)
+		audit_log_format(ab, ", relatime");
+	if (flags & MS_I_VERSION)
+		audit_log_format(ab, ", iversion");
+	if (flags & MS_STRICTATIME)
+		audit_log_format(ab, ", strictatime");
+	if (flags & MS_NOUSER)
+		audit_log_format(ab, ", nouser");
+}
+
+/**
+ * audit_cb - call back for mount specific audit fields
+ * @ab: audit_buffer  (NOT NULL)
+ * @va: audit struct to audit values of  (NOT NULL)
+ */
+static void audit_cb(struct audit_buffer *ab, void *va)
+{
+	struct common_audit_data *sa = va;
+
+	if (aad(sa)->mnt.type) {
+		audit_log_format(ab, " fstype=");
+		audit_log_untrustedstring(ab, aad(sa)->mnt.type);
+	}
+	if (aad(sa)->mnt.src_name) {
+		audit_log_format(ab, " srcname=");
+		audit_log_untrustedstring(ab, aad(sa)->mnt.src_name);
+	}
+	if (aad(sa)->mnt.trans) {
+		audit_log_format(ab, " trans=");
+		audit_log_untrustedstring(ab, aad(sa)->mnt.trans);
+	}
+	if (aad(sa)->mnt.flags) {
+		audit_log_format(ab, " flags=\"");
+		audit_mnt_flags(ab, aad(sa)->mnt.flags);
+		audit_log_format(ab, "\"");
+	}
+	if (aad(sa)->mnt.data) {
+		audit_log_format(ab, " options=");
+		audit_log_untrustedstring(ab, aad(sa)->mnt.data);
+	}
+}
+
+/**
+ * audit_mount - handle the auditing of mount operations
+ * @profile: the profile being enforced  (NOT NULL)
+ * @op: operation being mediated (NOT NULL)
+ * @name: name of object being mediated (MAYBE NULL)
+ * @src_name: src_name of object being mediated (MAYBE_NULL)
+ * @type: type of filesystem (MAYBE_NULL)
+ * @trans: name of trans (MAYBE NULL)
+ * @flags: filesystem idependent mount flags
+ * @data: filesystem mount flags
+ * @request: permissions requested
+ * @perms: the permissions computed for the request (NOT NULL)
+ * @info: extra information message (MAYBE NULL)
+ * @error: 0 if operation allowed else failure error code
+ *
+ * Returns: %0 or error on failure
+ */
+static int audit_mount(struct aa_profile *profile, const char *op, const char *name,
+		       const char *src_name, const char *type,
+		       const char *trans, unsigned long flags,
+		       const void *data, u32 request, struct aa_perms *perms,
+		       const char *info, int error)
+{
+	int audit_type = AUDIT_APPARMOR_AUTO;
+	DEFINE_AUDIT_DATA(sa, LSM_AUDIT_DATA_NONE, op);
+
+	if (likely(!error)) {
+		u32 mask = perms->audit;
+
+		if (unlikely(AUDIT_MODE(profile) == AUDIT_ALL))
+			mask = 0xffff;
+
+		/* mask off perms that are not being force audited */
+		request &= mask;
+
+		if (likely(!request))
+			return 0;
+		audit_type = AUDIT_APPARMOR_AUDIT;
+	} else {
+		/* only report permissions that were denied */
+		request = request & ~perms->allow;
+
+		if (request & perms->kill)
+			audit_type = AUDIT_APPARMOR_KILL;
+
+		/* quiet known rejects, assumes quiet and kill do not overlap */
+		if ((request & perms->quiet) &&
+		    AUDIT_MODE(profile) != AUDIT_NOQUIET &&
+		    AUDIT_MODE(profile) != AUDIT_ALL)
+			request &= ~perms->quiet;
+
+		if (!request)
+			return error;
+	}
+
+	aad(&sa)->name = name;
+	aad(&sa)->mnt.src_name = src_name;
+	aad(&sa)->mnt.type = type;
+	aad(&sa)->mnt.trans = trans;
+	aad(&sa)->mnt.flags = flags;
+	if (data && (perms->audit & AA_AUDIT_DATA))
+		aad(&sa)->mnt.data = data;
+	aad(&sa)->info = info;
+	aad(&sa)->error = error;
+
+	return aa_audit(audit_type, profile, &sa, audit_cb);
+}
+
+/**
+ * match_mnt_flags - Do an ordered match on mount flags
+ * @dfa: dfa to match against
+ * @state: state to start in
+ * @flags: mount flags to match against
+ *
+ * Mount flags are encoded as an ordered match. This is done instead of
+ * checking against a simple bitmask, to allow for logical operations
+ * on the flags.
+ *
+ * Returns: next state after flags match
+ */
+static unsigned int match_mnt_flags(struct aa_dfa *dfa, unsigned int state,
+				    unsigned long flags)
+{
+	unsigned int i;
+
+	for (i = 0; i <= 31 ; ++i) {
+		if ((1 << i) & flags)
+			state = aa_dfa_next(dfa, state, i + 1);
+	}
+
+	return state;
+}
+
+/**
+ * compute_mnt_perms - compute mount permission associated with @state
+ * @dfa: dfa to match against (NOT NULL)
+ * @state: state match finished in
+ *
+ * Returns: mount permissions
+ */
+static struct aa_perms compute_mnt_perms(struct aa_dfa *dfa,
+					   unsigned int state)
+{
+	struct aa_perms perms;
+
+	perms.kill = 0;
+	perms.allow = dfa_user_allow(dfa, state);
+	perms.audit = dfa_user_audit(dfa, state);
+	perms.quiet = dfa_user_quiet(dfa, state);
+	perms.xindex = dfa_user_xindex(dfa, state);
+
+	return perms;
+}
+
+static const char *mnt_info_table[] = {
+	"match succeeded",
+	"failed mntpnt match",
+	"failed srcname match",
+	"failed type match",
+	"failed flags match",
+	"failed data match"
+};
+
+/*
+ * Returns 0 on success else element that match failed in, this is the
+ * index into the mnt_info_table above
+ */
+static int do_match_mnt(struct aa_dfa *dfa, unsigned int start,
+			const char *mntpnt, const char *devname,
+			const char *type, unsigned long flags,
+			void *data, bool binary, struct aa_perms *perms)
+{
+	unsigned int state;
+
+	AA_BUG(!dfa);
+	AA_BUG(!perms);
+
+	state = aa_dfa_match(dfa, start, mntpnt);
+	state = aa_dfa_null_transition(dfa, state);
+	if (!state)
+		return 1;
+
+	if (devname)
+		state = aa_dfa_match(dfa, state, devname);
+	state = aa_dfa_null_transition(dfa, state);
+	if (!state)
+		return 2;
+
+	if (type)
+		state = aa_dfa_match(dfa, state, type);
+	state = aa_dfa_null_transition(dfa, state);
+	if (!state)
+		return 3;
+
+	state = match_mnt_flags(dfa, state, flags);
+	if (!state)
+		return 4;
+	*perms = compute_mnt_perms(dfa, state);
+	if (perms->allow & AA_MAY_MOUNT)
+		return 0;
+
+	/* only match data if not binary and the DFA flags data is expected */
+	if (data && !binary && (perms->allow & AA_MNT_CONT_MATCH)) {
+		state = aa_dfa_null_transition(dfa, state);
+		if (!state)
+			return 4;
+
+		state = aa_dfa_match(dfa, state, data);
+		if (!state)
+			return 5;
+		*perms = compute_mnt_perms(dfa, state);
+		if (perms->allow & AA_MAY_MOUNT)
+			return 0;
+	}
+
+	/* failed at end of flags match */
+	return 4;
+}
+
+
+static int path_flags(struct aa_profile *profile, const struct path *path)
+{
+	AA_BUG(!profile);
+	AA_BUG(!path);
+
+	return profile->path_flags |
+		(S_ISDIR(path->dentry->d_inode->i_mode) ? PATH_IS_DIR : 0);
+}
+
+/**
+ * match_mnt_path_str - handle path matching for mount
+ * @profile: the confining profile
+ * @mntpath: for the mntpnt (NOT NULL)
+ * @buffer: buffer to be used to lookup mntpath
+ * @devnme: string for the devname/src_name (MAY BE NULL OR ERRPTR)
+ * @type: string for the dev type (MAYBE NULL)
+ * @flags: mount flags to match
+ * @data: fs mount data (MAYBE NULL)
+ * @binary: whether @data is binary
+ * @devinfo: error str if (IS_ERR(@devname))
+ *
+ * Returns: 0 on success else error
+ */
+static int match_mnt_path_str(struct aa_profile *profile, const struct path *mntpath,
+			      char *buffer, const char *devname,
+			      const char *type, unsigned long flags,
+			      void *data, bool binary, const char *devinfo)
+{
+	struct aa_perms perms = { };
+	const char *mntpnt = NULL, *info = NULL;
+	int pos, error;
+
+	AA_BUG(!profile);
+	AA_BUG(!mntpath);
+	AA_BUG(!buffer);
+
+	error = aa_path_name(mntpath, path_flags(profile, mntpath), buffer,
+			     &mntpnt, &info, profile->disconnected);
+	if (error)
+		goto audit;
+	if (IS_ERR(devname)) {
+		error = PTR_ERR(devname);
+		info = devinfo;
+		goto audit;
+	}
+
+	error = -EACCES;
+	pos = do_match_mnt(profile->policy.dfa,
+			   profile->policy.start[AA_CLASS_MOUNT],
+			   mntpnt, devname, type, flags, data, binary, &perms);
+	if (pos) {
+		info = mnt_info_table[pos];
+		goto audit;
+	}
+	error = 0;
+
+audit:
+	return audit_mount(profile, OP_MOUNT, mntpnt, devname, type, NULL,
+			   flags, data, AA_MAY_MOUNT, &perms, info, error);
+}
+
+/**
+ * match_mnt - handle path matching for mount
+ * @profile: the confining profile
+ * @mntpath: for the mntpnt (NOT NULL)
+ * @buffer: buffer to be used to lookup mntpath
+ * @devpath: path devname/src_name (MAYBE NULL)
+ * @devbuffer: buffer to be used to lookup devname/src_name
+ * @type: string for the dev type (MAYBE NULL)
+ * @flags: mount flags to match
+ * @data: fs mount data (MAYBE NULL)
+ * @binary: whether @data is binary
+ *
+ * Returns: 0 on success else error
+ */
+static int match_mnt(struct aa_profile *profile, const struct path *path,
+		     char *buffer, struct path *devpath, char *devbuffer,
+		     const char *type, unsigned long flags, void *data,
+		     bool binary)
+{
+	const char *devname = NULL, *info = NULL;
+	int error = -EACCES;
+
+	AA_BUG(!profile);
+	AA_BUG(devpath && !devbuffer);
+
+	if (devpath) {
+		error = aa_path_name(devpath, path_flags(profile, devpath),
+				     devbuffer, &devname, &info,
+				     profile->disconnected);
+		if (error)
+			devname = ERR_PTR(error);
+	}
+
+	return match_mnt_path_str(profile, path, buffer, devname, type, flags,
+				  data, binary, info);
+}
+
+int aa_remount(struct aa_label *label, const struct path *path,
+	       unsigned long flags, void *data)
+{
+	struct aa_profile *profile;
+	char *buffer = NULL;
+	bool binary;
+	int error;
+
+	AA_BUG(!label);
+	AA_BUG(!path);
+
+	binary = path->dentry->d_sb->s_type->fs_flags & FS_BINARY_MOUNTDATA;
+
+	get_buffers(buffer);
+	error = fn_for_each_confined(label, profile,
+			match_mnt(profile, path, buffer, NULL, NULL, NULL,
+				  flags, data, binary));
+	put_buffers(buffer);
+
+	return error;
+}
+
+int aa_bind_mount(struct aa_label *label, const struct path *path,
+		  const char *dev_name, unsigned long flags)
+{
+	struct aa_profile *profile;
+	char *buffer = NULL, *old_buffer = NULL;
+	struct path old_path;
+	int error;
+
+	AA_BUG(!label);
+	AA_BUG(!path);
+
+	if (!dev_name || !*dev_name)
+		return -EINVAL;
+
+	flags &= MS_REC | MS_BIND;
+
+	error = kern_path(dev_name, LOOKUP_FOLLOW|LOOKUP_AUTOMOUNT, &old_path);
+	if (error)
+		return error;
+
+	get_buffers(buffer, old_buffer);
+	error = fn_for_each_confined(label, profile,
+			match_mnt(profile, path, buffer, &old_path, old_buffer,
+				  NULL, flags, NULL, false));
+	put_buffers(buffer, old_buffer);
+	path_put(&old_path);
+
+	return error;
+}
+
+int aa_mount_change_type(struct aa_label *label, const struct path *path,
+			 unsigned long flags)
+{
+	struct aa_profile *profile;
+	char *buffer = NULL;
+	int error;
+
+	AA_BUG(!label);
+	AA_BUG(!path);
+
+	/* These are the flags allowed by do_change_type() */
+	flags &= (MS_REC | MS_SILENT | MS_SHARED | MS_PRIVATE | MS_SLAVE |
+		  MS_UNBINDABLE);
+
+	get_buffers(buffer);
+	error = fn_for_each_confined(label, profile,
+			match_mnt(profile, path, buffer, NULL, NULL, NULL,
+				  flags, NULL, false));
+	put_buffers(buffer);
+
+	return error;
+}
+
+int aa_move_mount(struct aa_label *label, const struct path *path,
+		  const char *orig_name)
+{
+	struct aa_profile *profile;
+	char *buffer = NULL, *old_buffer = NULL;
+	struct path old_path;
+	int error;
+
+	AA_BUG(!label);
+	AA_BUG(!path);
+
+	if (!orig_name || !*orig_name)
+		return -EINVAL;
+
+	error = kern_path(orig_name, LOOKUP_FOLLOW, &old_path);
+	if (error)
+		return error;
+
+	get_buffers(buffer, old_buffer);
+	error = fn_for_each_confined(label, profile,
+			match_mnt(profile, path, buffer, &old_path, old_buffer,
+				  NULL, MS_MOVE, NULL, false));
+	put_buffers(buffer, old_buffer);
+	path_put(&old_path);
+
+	return error;
+}
+
+int aa_new_mount(struct aa_label *label, const char *dev_name,
+		 const struct path *path, const char *type, unsigned long flags,
+		 void *data)
+{
+	struct aa_profile *profile;
+	char *buffer = NULL, *dev_buffer = NULL;
+	bool binary = true;
+	int error;
+	int requires_dev = 0;
+	struct path tmp_path, *dev_path = NULL;
+
+	AA_BUG(!label);
+	AA_BUG(!path);
+
+	if (type) {
+		struct file_system_type *fstype;
+		fstype = get_fs_type(type);
+		if (!fstype)
+			return -ENODEV;
+		binary = fstype->fs_flags & FS_BINARY_MOUNTDATA;
+		requires_dev = fstype->fs_flags & FS_REQUIRES_DEV;
+		put_filesystem(fstype);
+
+		if (requires_dev) {
+			if (!dev_name || !*dev_name)
+				return -ENOENT;
+
+			error = kern_path(dev_name, LOOKUP_FOLLOW, &tmp_path);
+			if (error)
+				return error;
+			dev_path = &tmp_path;
+		}
+	}
+
+	get_buffers(buffer, dev_buffer);
+	if (dev_path) {
+		error = fn_for_each_confined(label, profile,
+			match_mnt(profile, path, buffer, dev_path, dev_buffer,
+				  type, flags, data, binary));
+	} else {
+		error = fn_for_each_confined(label, profile,
+			match_mnt_path_str(profile, path, buffer, dev_name,
+					   type, flags, data, binary, NULL));
+	}
+	put_buffers(buffer, dev_buffer);
+	if (dev_path)
+		path_put(dev_path);
+
+	return error;
+}
+
+static int profile_umount(struct aa_profile *profile, struct path *path,
+			  char *buffer)
+{
+	struct aa_perms perms = { };
+	const char *name = NULL, *info = NULL;
+	unsigned int state;
+	int error;
+
+	AA_BUG(!profile);
+	AA_BUG(!path);
+
+	error = aa_path_name(path, path_flags(profile, path), buffer, &name,
+			     &info, profile->disconnected);
+	if (error)
+		goto audit;
+
+	state = aa_dfa_match(profile->policy.dfa,
+			     profile->policy.start[AA_CLASS_MOUNT],
+			     name);
+	perms = compute_mnt_perms(profile->policy.dfa, state);
+	if (AA_MAY_UMOUNT & ~perms.allow)
+		error = -EACCES;
+
+audit:
+	return audit_mount(profile, OP_UMOUNT, name, NULL, NULL, NULL, 0, NULL,
+			   AA_MAY_UMOUNT, &perms, info, error);
+}
+
+int aa_umount(struct aa_label *label, struct vfsmount *mnt, int flags)
+{
+	struct aa_profile *profile;
+	char *buffer = NULL;
+	int error;
+	struct path path = { mnt, mnt->mnt_root };
+
+	AA_BUG(!label);
+	AA_BUG(!mnt);
+
+	get_buffers(buffer);
+	error = fn_for_each_confined(label, profile,
+			profile_umount(profile, &path, buffer));
+	put_buffers(buffer);
+
+	return error;
+}
+
+/* helper fn for transition on pivotroot
+ *
+ * Returns: label for transition or ERR_PTR. Does not return NULL
+ */
+static struct aa_label *build_pivotroot(struct aa_profile *profile,
+					const struct path *new_path,
+					char *new_buffer,
+					const struct path *old_path,
+					char *old_buffer)
+{
+	const char *old_name, *new_name = NULL, *info = NULL;
+	const char *trans_name = NULL;
+	struct aa_label *target = NULL;
+	struct aa_perms perms = { };
+	unsigned int state;
+	int error;
+
+	AA_BUG(!profile);
+	AA_BUG(!new_path);
+	AA_BUG(!old_path);
+
+	if (profile_unconfined(profile))
+		return aa_get_newest_label(&profile->label);
+
+	error = aa_path_name(old_path, path_flags(profile, old_path),
+			     old_buffer, &old_name, &info,
+			     profile->disconnected);
+	if (error)
+		goto audit;
+	error = aa_path_name(new_path, path_flags(profile, new_path),
+			     new_buffer, &new_name, &info,
+			     profile->disconnected);
+	if (error)
+		goto audit;
+
+	error = -EACCES;
+	state = aa_dfa_match(profile->policy.dfa,
+			     profile->policy.start[AA_CLASS_MOUNT],
+			     new_name);
+	state = aa_dfa_null_transition(profile->policy.dfa, state);
+	state = aa_dfa_match(profile->policy.dfa, state, old_name);
+	perms = compute_mnt_perms(profile->policy.dfa, state);
+
+	if (AA_MAY_PIVOTROOT & perms.allow) {
+		error = 0;
+		if ((perms.xindex & AA_X_TYPE_MASK) == AA_X_TABLE) {
+			target = x_table_lookup(profile, perms.xindex,
+						&trans_name);
+			if (!target)
+				error = -ENOENT;
+		}
+	}
+
+audit:
+	error = audit_mount(profile, OP_PIVOTROOT, new_name, old_name,
+			    NULL, trans_name, 0, NULL, AA_MAY_PIVOTROOT,
+			    &perms, info, error);
+	if (error) {
+		aa_put_label(target);
+		return ERR_PTR(error);
+	} else if (target)
+		return target;
+
+	return aa_get_newest_label(&profile->label);
+}
+
+int aa_pivotroot(struct aa_label *label, const struct path *old_path,
+		 const struct path *new_path)
+{
+	struct aa_profile *profile;
+	struct aa_label *target = NULL;
+	char *old_buffer = NULL, *new_buffer = NULL, *info = NULL;
+	int error;
+
+	AA_BUG(!label);
+	AA_BUG(!old_path);
+	AA_BUG(!new_path);
+
+	get_buffers(old_buffer, new_buffer);
+	target = fn_label_build(label, profile, GFP_ATOMIC,
+			build_pivotroot(profile, new_path, new_buffer,
+					old_path, old_buffer));
+	if (!target) {
+		info = "label build failed";
+		error = -ENOMEM;
+		goto fail;
+	} else if (!IS_ERR(target)) {
+		error = aa_replace_current_label(target);
+		if (error) {
+			/* TODO: audit target */
+			aa_put_label(target);
+			goto out;
+		}
+	} else
+		/* already audited error */
+		error = PTR_ERR(target);
+out:
+	put_buffers(old_buffer, new_buffer);
+
+	return error;
+
+fail:
+	/* TODO: add back in auditing of new_name and old_name */
+	error = fn_for_each(label, profile,
+			audit_mount(profile, OP_PIVOTROOT, NULL /*new_name */,
+				    NULL /* old_name */,
+				    NULL, NULL,
+				    0, NULL, AA_MAY_PIVOTROOT, &nullperms, info,
+				    error));
+	goto out;
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/security/apparmor/net.c
@@ -0,0 +1,357 @@
+/*
+ * AppArmor security module
+ *
+ * This file contains AppArmor network mediation
+ *
+ * Copyright (C) 1998-2008 Novell/SUSE
+ * Copyright 2009-2014 Canonical Ltd.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2 of the
+ * License.
+ */
+
+#include "include/af_unix.h"
+#include "include/apparmor.h"
+#include "include/audit.h"
+#include "include/context.h"
+#include "include/label.h"
+#include "include/net.h"
+#include "include/policy.h"
+
+#include "net_names.h"
+
+
+struct aa_fs_entry aa_fs_entry_network[] = {
+	AA_FS_FILE_STRING("af_mask",	AA_FS_AF_MASK),
+	AA_FS_FILE_BOOLEAN("af_unix",	1),
+	{ }
+};
+
+static const char *net_mask_names[] = {
+	"unknown",
+	"send",
+	"receive",
+	"unknown",
+
+	"create",
+	"shutdown",
+	"connect",
+	"unknown",
+
+	"setattr",
+	"getattr",
+	"setcred",
+	"getcred",
+
+	"chmod",
+	"chown",
+	"chgrp",
+	"lock",
+
+	"mmap",
+	"mprot",
+	"unknown",
+	"unknown",
+
+	"accept",
+	"bind",
+	"listen",
+	"unknown",
+
+	"setopt",
+	"getopt",
+	"unknown",
+	"unknown",
+
+	"unknown",
+	"unknown",
+	"unknown",
+	"unknown",
+};
+
+static void audit_unix_addr(struct audit_buffer *ab, const char *str,
+			    struct sockaddr_un *addr, int addrlen)
+{
+	int len = unix_addr_len(addrlen);
+
+	if (!addr || len <= 0) {
+		audit_log_format(ab, " %s=none", str);
+	} else if (addr->sun_path[0]) {
+		audit_log_format(ab, " %s=", str);
+		audit_log_untrustedstring(ab, addr->sun_path);
+	} else {
+		audit_log_format(ab, " %s=\"@", str);
+		if (audit_string_contains_control(&addr->sun_path[1], len - 1))
+			audit_log_n_hex(ab, &addr->sun_path[1], len - 1);
+		else
+			audit_log_format(ab, "%.*s", len - 1,
+					 &addr->sun_path[1]);
+		audit_log_format(ab, "\"");
+	}
+}
+
+static void audit_unix_sk_addr(struct audit_buffer *ab, const char *str,
+			       struct sock *sk)
+{
+	struct unix_sock *u = unix_sk(sk);
+	if (u && u->addr)
+		audit_unix_addr(ab, str, u->addr->name, u->addr->len);
+	else
+		audit_unix_addr(ab, str, NULL, 0);
+}
+
+/* audit callback for net specific fields */
+void audit_net_cb(struct audit_buffer *ab, void *va)
+{
+	struct common_audit_data *sa = va;
+
+	audit_log_format(ab, " family=");
+	if (address_family_names[sa->u.net->family]) {
+		audit_log_string(ab, address_family_names[sa->u.net->family]);
+	} else {
+		audit_log_format(ab, "\"unknown(%d)\"", sa->u.net->family);
+	}
+	audit_log_format(ab, " sock_type=");
+	if (sock_type_names[aad(sa)->net.type]) {
+		audit_log_string(ab, sock_type_names[aad(sa)->net.type]);
+	} else {
+		audit_log_format(ab, "\"unknown(%d)\"", aad(sa)->net.type);
+	}
+	audit_log_format(ab, " protocol=%d", aad(sa)->net.protocol);
+
+	if (aad(sa)->request & NET_PERMS_MASK) {
+		audit_log_format(ab, " requested_mask=");
+		aa_audit_perm_mask(ab, aad(sa)->request, NULL, 0,
+				   net_mask_names, NET_PERMS_MASK);
+
+		if (aad(sa)->denied & NET_PERMS_MASK) {
+			audit_log_format(ab, " denied_mask=");
+			aa_audit_perm_mask(ab, aad(sa)->denied, NULL, 0,
+					   net_mask_names, NET_PERMS_MASK);
+		}
+	}
+	if (sa->u.net->family == AF_UNIX) {
+		if ((aad(sa)->request & ~NET_PEER_MASK) && aad(sa)->net.addr)
+			audit_unix_addr(ab, "addr",
+					unix_addr(aad(sa)->net.addr),
+					aad(sa)->net.addrlen);
+		else
+			audit_unix_sk_addr(ab, "addr", sa->u.net->sk);
+		if (aad(sa)->request & NET_PEER_MASK) {
+			if (aad(sa)->net.addr)
+				audit_unix_addr(ab, "peer_addr",
+						unix_addr(aad(sa)->net.addr),
+						aad(sa)->net.addrlen);
+			else
+				audit_unix_sk_addr(ab, "peer_addr",
+						   aad(sa)->net.peer_sk);
+		}
+	}
+	if (aad(sa)->peer) {
+		audit_log_format(ab, " peer=");
+		aa_label_xaudit(ab, labels_ns(aad(sa)->label), aad(sa)->peer,
+				FLAGS_NONE, GFP_ATOMIC);
+	}
+}
+
+
+/* Generic af perm */
+int aa_profile_af_perm(struct aa_profile *profile, struct common_audit_data *sa,
+		       u32 request, u16 family, int type)
+{
+	struct aa_perms perms = { };
+
+	AA_BUG(family >= AF_MAX);
+	AA_BUG(type < 0 && type >= SOCK_MAX);
+
+	if (profile_unconfined(profile))
+		return 0;
+
+	perms.allow = (profile->net.allow[family] & (1 << type)) ?
+		ALL_PERMS_MASK : 0;
+	perms.audit = (profile->net.audit[family] & (1 << type)) ?
+		ALL_PERMS_MASK : 0;
+	perms.quiet = (profile->net.quiet[family] & (1 << type)) ?
+		ALL_PERMS_MASK : 0;
+	aa_apply_modes_to_perms(profile, &perms);
+
+	return aa_check_perms(profile, &perms, request, sa, audit_net_cb);
+}
+
+static int aa_af_perm(struct aa_label *label, const char *op, u32 request,
+		      u16 family, int type, int protocol)
+{
+	struct aa_profile *profile;
+	DEFINE_AUDIT_NET(sa, op, NULL, family, type, protocol);
+
+	return fn_for_each_confined(label, profile,
+			aa_profile_af_perm(profile, &sa, request, family, type));
+}
+
+static int aa_label_sk_perm(struct aa_label *label, const char *op, u32 request,
+			    struct sock *sk)
+{
+	struct aa_profile *profile;
+	DEFINE_AUDIT_SK(sa, op, sk);
+
+	AA_BUG(!label);
+	AA_BUG(!sk);
+
+	if (unconfined(label))
+		return 0;
+
+	return fn_for_each_confined(label, profile,
+			aa_profile_af_sk_perm(profile, &sa, request, sk));
+}
+
+static int aa_sk_perm(const char *op, u32 request, struct sock *sk)
+{
+	struct aa_label *label;
+	int error;
+
+	AA_BUG(!sk);
+	AA_BUG(in_interrupt());
+
+	/* TODO: switch to begin_current_label ???? */
+	label = aa_begin_current_label(DO_UPDATE);
+	error = aa_label_sk_perm(label, op, request, sk);
+	aa_end_current_label(label);
+
+	return error;
+}
+
+#define af_select(FAMILY, FN, DEF_FN)		\
+({						\
+	int __e;				\
+	switch ((FAMILY)) {			\
+	case AF_UNIX:				\
+		__e = aa_unix_ ## FN;		\
+		break;				\
+	default:				\
+		__e = DEF_FN;			\
+	}					\
+	__e;					\
+})
+
+/* TODO: push into lsm.c ???? */
+
+/* revaliation, get/set attr, shutdown */
+int aa_sock_perm(const char *op, u32 request, struct socket *sock)
+{
+	AA_BUG(!sock);
+	AA_BUG(!sock->sk);
+	AA_BUG(in_interrupt());
+
+	return af_select(sock->sk->sk_family,
+			 sock_perm(op, request, sock),
+			 aa_sk_perm(op, request, sock->sk));
+}
+
+int aa_sock_create_perm(struct aa_label *label, int family, int type,
+			int protocol)
+{
+	AA_BUG(!label);
+	/* TODO: .... */
+	AA_BUG(in_interrupt());
+
+	return af_select(family,
+			 create_perm(label, family, type, protocol),
+			 aa_af_perm(label, OP_CREATE, AA_MAY_CREATE, family,
+				    type, protocol));
+}
+
+int aa_sock_bind_perm(struct socket *sock, struct sockaddr *address,
+		      int addrlen)
+{
+	AA_BUG(!sock);
+	AA_BUG(!sock->sk);
+	AA_BUG(!address);
+	/* TODO: .... */
+	AA_BUG(in_interrupt());
+
+	return af_select(sock->sk->sk_family,
+			 bind_perm(sock, address, addrlen),
+			 aa_sk_perm(OP_BIND, AA_MAY_BIND, sock->sk));
+}
+
+int aa_sock_connect_perm(struct socket *sock, struct sockaddr *address,
+			 int addrlen)
+{
+	AA_BUG(!sock);
+	AA_BUG(!sock->sk);
+	AA_BUG(!address);
+	/* TODO: .... */
+	AA_BUG(in_interrupt());
+
+	return af_select(sock->sk->sk_family,
+			 connect_perm(sock, address, addrlen),
+			 aa_sk_perm(OP_CONNECT, AA_MAY_CONNECT, sock->sk));
+}
+
+int aa_sock_listen_perm(struct socket *sock, int backlog)
+{
+	AA_BUG(!sock);
+	AA_BUG(!sock->sk);
+	/* TODO: .... */
+	AA_BUG(in_interrupt());
+
+	return af_select(sock->sk->sk_family,
+			 listen_perm(sock, backlog),
+			 aa_sk_perm(OP_LISTEN, AA_MAY_LISTEN, sock->sk));
+}
+
+/* ability of sock to connect, not peer address binding */
+int aa_sock_accept_perm(struct socket *sock, struct socket *newsock)
+{
+	AA_BUG(!sock);
+	AA_BUG(!sock->sk);
+	AA_BUG(!newsock);
+	/* TODO: .... */
+	AA_BUG(in_interrupt());
+
+	return af_select(sock->sk->sk_family,
+			 accept_perm(sock, newsock),
+			 aa_sk_perm(OP_ACCEPT, AA_MAY_ACCEPT, sock->sk));
+}
+
+/* sendmsg, recvmsg */
+int aa_sock_msg_perm(const char *op, u32 request, struct socket *sock,
+		     struct msghdr *msg, int size)
+{
+	AA_BUG(!sock);
+	AA_BUG(!sock->sk);
+	AA_BUG(!msg);
+	/* TODO: .... */
+	AA_BUG(in_interrupt());
+
+	return af_select(sock->sk->sk_family,
+			 msg_perm(op, request, sock, msg, size),
+			 aa_sk_perm(op, request, sock->sk));
+}
+
+/* revaliation, get/set attr, opt */
+int aa_sock_opt_perm(const char *op, u32 request, struct socket *sock, int level,
+		     int optname)
+{
+	AA_BUG(!sock);
+	AA_BUG(!sock->sk);
+	AA_BUG(in_interrupt());
+
+	return af_select(sock->sk->sk_family,
+			 opt_perm(op, request, sock, level, optname),
+			 aa_sk_perm(op, request, sock->sk));
+}
+
+int aa_sock_file_perm(struct aa_label *label, const char *op, u32 request,
+		      struct socket *sock)
+{
+	AA_BUG(!label);
+	AA_BUG(!sock);
+	AA_BUG(!sock->sk);
+
+	return af_select(sock->sk->sk_family,
+			 file_perm(label, op, request, sock),
+			 aa_label_sk_perm(label, op, request, sock->sk));
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/security/apparmor/nulldfa.in
@@ -0,0 +1 @@
+0x1B, 0x5E, 0x78, 0x3D, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x04, 0x90, 0x00, 0x00, 0x6E, 0x6F, 0x74, 0x66, 0x6C, 0x65, 0x78, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
--- zfcpdump-kernel-4.4.orig/security/apparmor/path.c
+++ zfcpdump-kernel-4.4/security/apparmor/path.c
@@ -25,7 +25,6 @@
 #include "include/path.h"
 #include "include/policy.h"
 
-
 /* modified from dcache.c */
 static int prepend(char **buffer, int buflen, const char *str, int namelen)
 {
@@ -39,13 +38,50 @@ static int prepend(char **buffer, int bu
 
 #define CHROOT_NSCONNECT (PATH_CHROOT_REL | PATH_CHROOT_NSCONNECT)
 
+/* If the path is not connected to the expected root,
+ * check if it is a sysctl and handle specially else remove any
+ * leading / that __d_path may have returned.
+ * Unless
+ *     specifically directed to connect the path,
+ * OR
+ *     if in a chroot and doing chroot relative paths and the path
+ *     resolves to the namespace root (would be connected outside
+ *     of chroot) and specifically directed to connect paths to
+ *     namespace root.
+ */
+static int disconnect(const struct path *path, char *buf, char **name,
+		      int flags, const char *disconnected)
+{
+	int error = 0;
+
+	if (!(flags & PATH_CONNECT_PATH) &&
+	    !(((flags & CHROOT_NSCONNECT) == CHROOT_NSCONNECT) &&
+	      our_mnt(path->mnt))) {
+		/* disconnected path, don't return pathname starting
+		 * with '/'
+		 */
+		error = -EACCES;
+		if (**name == '/')
+			*name = *name + 1;
+	} else {
+		if (**name != '/')
+			/* CONNECT_PATH with missing root */
+			error = prepend(name, *name - buf, "/", 1);
+		if (!error && disconnected)
+			error = prepend(name, *name - buf, disconnected,
+					strlen(disconnected));
+	}
+
+	return error;
+}
+
 /**
  * d_namespace_path - lookup a name associated with a given path
  * @path: path to lookup  (NOT NULL)
  * @buf:  buffer to store path to  (NOT NULL)
- * @buflen: length of @buf
  * @name: Returns - pointer for start of path name with in @buf (NOT NULL)
  * @flags: flags controlling path lookup
+ * @disconnected: string to prefix to disconnected paths
  *
  * Handle path name lookup.
  *
@@ -53,12 +89,14 @@ static int prepend(char **buffer, int bu
  *          When no error the path name is returned in @name which points to
  *          to a position in @buf
  */
-static int d_namespace_path(struct path *path, char *buf, int buflen,
-			    char **name, int flags)
+static int d_namespace_path(const struct path *path, char *buf, char **name,
+			    int flags, const char *disconnected)
 {
 	char *res;
 	int error = 0;
 	int connected = 1;
+	int isdir = (flags & PATH_IS_DIR) ? 1 : 0;
+	int buflen = aa_g_path_max - isdir;
 
 	if (path->mnt->mnt_flags & MNT_INTERNAL) {
 		/* it's not mounted anywhere */
@@ -73,9 +111,12 @@ static int d_namespace_path(struct path
 			/* TODO: convert over to using a per namespace
 			 * control instead of hard coded /proc
 			 */
-			return prepend(name, *name - buf, "/proc", 5);
-		}
-		return 0;
+			error = prepend(name, *name - buf, "/proc", 5);
+			goto out;
+		} else
+			error = disconnect(path, buf, name, flags,
+					   disconnected);
+		goto out;
 	}
 
 	/* resolve paths relative to chroot?*/
@@ -94,8 +135,11 @@ static int d_namespace_path(struct path
 	 * be returned.
 	 */
 	if (!res || IS_ERR(res)) {
-		if (PTR_ERR(res) == -ENAMETOOLONG)
-			return -ENAMETOOLONG;
+		if (PTR_ERR(res) == -ENAMETOOLONG) {
+			error = -ENAMETOOLONG;
+			*name = buf;
+			goto out;
+		}
 		connected = 0;
 		res = dentry_path_raw(path->dentry, buf, buflen);
 		if (IS_ERR(res)) {
@@ -108,6 +152,9 @@ static int d_namespace_path(struct path
 
 	*name = res;
 
+	if (!connected)
+		error = disconnect(path, buf, name, flags, disconnected);
+
 	/* Handle two cases:
 	 * 1. A deleted dentry && profile is not allowing mediation of deleted
 	 * 2. On some filesystems, newly allocated dentries appear to the
@@ -115,83 +162,30 @@ static int d_namespace_path(struct path
 	 *    allocated.
 	 */
 	if (d_unlinked(path->dentry) && d_is_positive(path->dentry) &&
-	    !(flags & PATH_MEDIATE_DELETED)) {
+	    !(flags & (PATH_MEDIATE_DELETED | PATH_DELEGATE_DELETED))) {
 			error = -ENOENT;
 			goto out;
 	}
 
-	/* If the path is not connected to the expected root,
-	 * check if it is a sysctl and handle specially else remove any
-	 * leading / that __d_path may have returned.
-	 * Unless
-	 *     specifically directed to connect the path,
-	 * OR
-	 *     if in a chroot and doing chroot relative paths and the path
-	 *     resolves to the namespace root (would be connected outside
-	 *     of chroot) and specifically directed to connect paths to
-	 *     namespace root.
-	 */
-	if (!connected) {
-		if (!(flags & PATH_CONNECT_PATH) &&
-			   !(((flags & CHROOT_NSCONNECT) == CHROOT_NSCONNECT) &&
-			     our_mnt(path->mnt))) {
-			/* disconnected path, don't return pathname starting
-			 * with '/'
-			 */
-			error = -EACCES;
-			if (*res == '/')
-				*name = res + 1;
-		}
-	}
-
 out:
-	return error;
-}
-
-/**
- * get_name_to_buffer - get the pathname to a buffer ensure dir / is appended
- * @path: path to get name for  (NOT NULL)
- * @flags: flags controlling path lookup
- * @buffer: buffer to put name in  (NOT NULL)
- * @size: size of buffer
- * @name: Returns - contains position of path name in @buffer (NOT NULL)
- *
- * Returns: %0 else error on failure
- */
-static int get_name_to_buffer(struct path *path, int flags, char *buffer,
-			      int size, char **name, const char **info)
-{
-	int adjust = (flags & PATH_IS_DIR) ? 1 : 0;
-	int error = d_namespace_path(path, buffer, size - adjust, name, flags);
-
-	if (!error && (flags & PATH_IS_DIR) && (*name)[1] != '\0')
-		/*
-		 * Append "/" to the pathname.  The root directory is a special
-		 * case; it already ends in slash.
-		 */
-		strcpy(&buffer[size - 2], "/");
-
-	if (info && error) {
-		if (error == -ENOENT)
-			*info = "Failed name lookup - deleted entry";
-		else if (error == -EACCES)
-			*info = "Failed name lookup - disconnected path";
-		else if (error == -ENAMETOOLONG)
-			*info = "Failed name lookup - name too long";
-		else
-			*info = "Failed name lookup";
-	}
+	/*
+	 * Append "/" to the pathname.  The root directory is a special
+	 * case; it already ends in slash.
+	 */
+	if (!error && isdir && ((*name)[1] != '\0' || (*name)[0] != '/'))
+		strcpy(&buf[aa_g_path_max - 2], "/");
 
 	return error;
 }
 
 /**
- * aa_path_name - compute the pathname of a file
+ * aa_path_name - get the pathname to a buffer ensure dir / is appended
  * @path: path the file  (NOT NULL)
  * @flags: flags controlling path name generation
- * @buffer: buffer that aa_get_name() allocated  (NOT NULL)
+ * @buffer: buffer to put name in (NOT NULL)
  * @name: Returns - the generated path name if !error (NOT NULL)
  * @info: Returns - information on why the path lookup failed (MAYBE NULL)
+ * @disconnected: string to prepend to disconnected paths
  *
  * @name is a pointer to the beginning of the pathname (which usually differs
  * from the beginning of the buffer), or NULL.  If there is an error @name
@@ -204,33 +198,24 @@ static int get_name_to_buffer(struct pat
  *
  * Returns: %0 else error code if could retrieve name
  */
-int aa_path_name(struct path *path, int flags, char **buffer, const char **name,
-		 const char **info)
+int aa_path_name(const struct path *path, int flags, char *buffer,
+		 const char **name, const char **info, const char *disconnected)
 {
-	char *buf, *str = NULL;
-	int size = 256;
-	int error;
-
-	*name = NULL;
-	*buffer = NULL;
-	for (;;) {
-		/* freed by caller */
-		buf = kmalloc(size, GFP_KERNEL);
-		if (!buf)
-			return -ENOMEM;
-
-		error = get_name_to_buffer(path, flags, buf, size, &str, info);
-		if (error != -ENAMETOOLONG)
-			break;
-
-		kfree(buf);
-		size <<= 1;
-		if (size > aa_g_path_max)
-			return -ENAMETOOLONG;
-		*info = NULL;
+	char *str = NULL;
+	int error = d_namespace_path(path, buffer, &str, flags, disconnected);
+
+
+	if (info && error) {
+		if (error == -ENOENT)
+			*info = "Failed name lookup - deleted entry";
+		else if (error == -EACCES)
+			*info = "Failed name lookup - disconnected path";
+		else if (error == -ENAMETOOLONG)
+			*info = "Failed name lookup - name too long";
+		else
+			*info = "Failed name lookup";
 	}
-	*buffer = buf;
-	*name = str;
 
+	*name = str;
 	return error;
 }
--- zfcpdump-kernel-4.4.orig/security/apparmor/policy.c
+++ zfcpdump-kernel-4.4/security/apparmor/policy.c
@@ -76,22 +76,26 @@
 #include <linux/slab.h>
 #include <linux/spinlock.h>
 #include <linux/string.h>
+#include <linux/user_namespace.h>
 
 #include "include/apparmor.h"
 #include "include/capability.h"
 #include "include/context.h"
 #include "include/file.h"
 #include "include/ipc.h"
+#include "include/label.h"
 #include "include/match.h"
 #include "include/path.h"
 #include "include/policy.h"
+#include "include/policy_ns.h"
 #include "include/policy_unpack.h"
 #include "include/resource.h"
 
+int unprivileged_userns_apparmor_policy = 1;
 
-/* root profile namespace */
-struct aa_namespace *root_ns;
-
+/* Note: mode names must be unique in the first character because of
+ *       modechrs used to print modes on compound labels on some interfaces
+ */
 const char *const aa_profile_mode_names[] = {
 	"enforce",
 	"complain",
@@ -100,321 +104,21 @@ const char *const aa_profile_mode_names[
 };
 
 /**
- * hname_tail - find the last component of an hname
- * @name: hname to find the base profile name component of  (NOT NULL)
- *
- * Returns: the tail (base profile name) name component of an hname
- */
-static const char *hname_tail(const char *hname)
-{
-	char *split;
-	hname = strim((char *)hname);
-	for (split = strstr(hname, "//"); split; split = strstr(hname, "//"))
-		hname = split + 2;
-
-	return hname;
-}
-
-/**
- * policy_init - initialize a policy structure
- * @policy: policy to initialize  (NOT NULL)
- * @prefix: prefix name if any is required.  (MAYBE NULL)
- * @name: name of the policy, init will make a copy of it  (NOT NULL)
- *
- * Note: this fn creates a copy of strings passed in
- *
- * Returns: true if policy init successful
- */
-static bool policy_init(struct aa_policy *policy, const char *prefix,
-			const char *name)
-{
-	/* freed by policy_free */
-	if (prefix) {
-		policy->hname = kmalloc(strlen(prefix) + strlen(name) + 3,
-					GFP_KERNEL);
-		if (policy->hname)
-			sprintf(policy->hname, "%s//%s", prefix, name);
-	} else
-		policy->hname = kstrdup(name, GFP_KERNEL);
-	if (!policy->hname)
-		return 0;
-	/* base.name is a substring of fqname */
-	policy->name = (char *)hname_tail(policy->hname);
-	INIT_LIST_HEAD(&policy->list);
-	INIT_LIST_HEAD(&policy->profiles);
-
-	return 1;
-}
-
-/**
- * policy_destroy - free the elements referenced by @policy
- * @policy: policy that is to have its elements freed  (NOT NULL)
+ * aa_free_data - free a data blob
+ * @ptr: data to free
+ * @arg: unused
  */
-static void policy_destroy(struct aa_policy *policy)
+static void aa_free_data(void *ptr, void *arg)
 {
-	/* still contains profiles -- invalid */
-	if (on_list_rcu(&policy->profiles)) {
-		AA_ERROR("%s: internal error, "
-			 "policy '%s' still contains profiles\n",
-			 __func__, policy->name);
-		BUG();
-	}
-	if (on_list_rcu(&policy->list)) {
-		AA_ERROR("%s: internal error, policy '%s' still on list\n",
-			 __func__, policy->name);
-		BUG();
-	}
-
-	/* don't free name as its a subset of hname */
-	kzfree(policy->hname);
-}
-
-/**
- * __policy_find - find a policy by @name on a policy list
- * @head: list to search  (NOT NULL)
- * @name: name to search for  (NOT NULL)
- *
- * Requires: rcu_read_lock be held
- *
- * Returns: unrefcounted policy that match @name or NULL if not found
- */
-static struct aa_policy *__policy_find(struct list_head *head, const char *name)
-{
-	struct aa_policy *policy;
+	struct aa_data *data = ptr;
 
-	list_for_each_entry_rcu(policy, head, list) {
-		if (!strcmp(policy->name, name))
-			return policy;
-	}
-	return NULL;
+	kzfree(data->data);
+	kzfree(data->key);
+	kzfree(data);
 }
 
 /**
- * __policy_strn_find - find a policy that's name matches @len chars of @str
- * @head: list to search  (NOT NULL)
- * @str: string to search for  (NOT NULL)
- * @len: length of match required
- *
- * Requires: rcu_read_lock be held
- *
- * Returns: unrefcounted policy that match @str or NULL if not found
- *
- * if @len == strlen(@strlen) then this is equiv to __policy_find
- * other wise it allows searching for policy by a partial match of name
- */
-static struct aa_policy *__policy_strn_find(struct list_head *head,
-					    const char *str, int len)
-{
-	struct aa_policy *policy;
-
-	list_for_each_entry_rcu(policy, head, list) {
-		if (aa_strneq(policy->name, str, len))
-			return policy;
-	}
-
-	return NULL;
-}
-
-/*
- * Routines for AppArmor namespaces
- */
-
-static const char *hidden_ns_name = "---";
-/**
- * aa_ns_visible - test if @view is visible from @curr
- * @curr: namespace to treat as the parent (NOT NULL)
- * @view:  namespace to test if visible from @curr (NOT NULL)
- *
- * Returns: true if @view is visible from @curr else false
- */
-bool aa_ns_visible(struct aa_namespace *curr, struct aa_namespace *view)
-{
-	if (curr == view)
-		return true;
-
-	for ( ; view; view = view->parent) {
-		if (view->parent == curr)
-			return true;
-	}
-	return false;
-}
-
-/**
- * aa_na_name - Find the ns name to display for @view from @curr
- * @curr - current namespace (NOT NULL)
- * @view - namespace attempting to view (NOT NULL)
- *
- * Returns: name of @view visible from @curr
- */
-const char *aa_ns_name(struct aa_namespace *curr, struct aa_namespace *view)
-{
-	/* if view == curr then the namespace name isn't displayed */
-	if (curr == view)
-		return "";
-
-	if (aa_ns_visible(curr, view)) {
-		/* at this point if a ns is visible it is in a view ns
-		 * thus the curr ns.hname is a prefix of its name.
-		 * Only output the virtualized portion of the name
-		 * Add + 2 to skip over // separating curr hname prefix
-		 * from the visible tail of the views hname
-		 */
-		return view->base.hname + strlen(curr->base.hname) + 2;
-	} else
-		return hidden_ns_name;
-}
-
-/**
- * alloc_namespace - allocate, initialize and return a new namespace
- * @prefix: parent namespace name (MAYBE NULL)
- * @name: a preallocated name  (NOT NULL)
- *
- * Returns: refcounted namespace or NULL on failure.
- */
-static struct aa_namespace *alloc_namespace(const char *prefix,
-					    const char *name)
-{
-	struct aa_namespace *ns;
-
-	ns = kzalloc(sizeof(*ns), GFP_KERNEL);
-	AA_DEBUG("%s(%p)\n", __func__, ns);
-	if (!ns)
-		return NULL;
-	if (!policy_init(&ns->base, prefix, name))
-		goto fail_ns;
-
-	INIT_LIST_HEAD(&ns->sub_ns);
-	mutex_init(&ns->lock);
-
-	/* released by free_namespace */
-	ns->unconfined = aa_alloc_profile("unconfined");
-	if (!ns->unconfined)
-		goto fail_unconfined;
-
-	ns->unconfined->flags = PFLAG_IX_ON_NAME_ERROR |
-		PFLAG_IMMUTABLE | PFLAG_NS_COUNT;
-	ns->unconfined->mode = APPARMOR_UNCONFINED;
-
-	/* ns and ns->unconfined share ns->unconfined refcount */
-	ns->unconfined->ns = ns;
-
-	atomic_set(&ns->uniq_null, 0);
-
-	return ns;
-
-fail_unconfined:
-	kzfree(ns->base.hname);
-fail_ns:
-	kzfree(ns);
-	return NULL;
-}
-
-/**
- * free_namespace - free a profile namespace
- * @ns: the namespace to free  (MAYBE NULL)
- *
- * Requires: All references to the namespace must have been put, if the
- *           namespace was referenced by a profile confining a task,
- */
-static void free_namespace(struct aa_namespace *ns)
-{
-	if (!ns)
-		return;
-
-	policy_destroy(&ns->base);
-	aa_put_namespace(ns->parent);
-
-	ns->unconfined->ns = NULL;
-	aa_free_profile(ns->unconfined);
-	kzfree(ns);
-}
-
-/**
- * __aa_find_namespace - find a namespace on a list by @name
- * @head: list to search for namespace on  (NOT NULL)
- * @name: name of namespace to look for  (NOT NULL)
- *
- * Returns: unrefcounted namespace
- *
- * Requires: rcu_read_lock be held
- */
-static struct aa_namespace *__aa_find_namespace(struct list_head *head,
-						const char *name)
-{
-	return (struct aa_namespace *)__policy_find(head, name);
-}
-
-/**
- * aa_find_namespace  -  look up a profile namespace on the namespace list
- * @root: namespace to search in  (NOT NULL)
- * @name: name of namespace to find  (NOT NULL)
- *
- * Returns: a refcounted namespace on the list, or NULL if no namespace
- *          called @name exists.
- *
- * refcount released by caller
- */
-struct aa_namespace *aa_find_namespace(struct aa_namespace *root,
-				       const char *name)
-{
-	struct aa_namespace *ns = NULL;
-
-	rcu_read_lock();
-	ns = aa_get_namespace(__aa_find_namespace(&root->sub_ns, name));
-	rcu_read_unlock();
-
-	return ns;
-}
-
-/**
- * aa_prepare_namespace - find an existing or create a new namespace of @name
- * @name: the namespace to find or add  (MAYBE NULL)
- *
- * Returns: refcounted namespace or NULL if failed to create one
- */
-static struct aa_namespace *aa_prepare_namespace(const char *name)
-{
-	struct aa_namespace *ns, *root;
-
-	root = aa_current_profile()->ns;
-
-	mutex_lock(&root->lock);
-
-	/* if name isn't specified the profile is loaded to the current ns */
-	if (!name) {
-		/* released by caller */
-		ns = aa_get_namespace(root);
-		goto out;
-	}
-
-	/* try and find the specified ns and if it doesn't exist create it */
-	/* released by caller */
-	ns = aa_get_namespace(__aa_find_namespace(&root->sub_ns, name));
-	if (!ns) {
-		ns = alloc_namespace(root->base.hname, name);
-		if (!ns)
-			goto out;
-		if (__aa_fs_namespace_mkdir(ns, ns_subns_dir(root), name)) {
-			AA_ERROR("Failed to create interface for ns %s\n",
-				 ns->base.name);
-			free_namespace(ns);
-			ns = NULL;
-			goto out;
-		}
-		ns->parent = aa_get_namespace(root);
-		list_add_rcu(&ns->base.list, &root->sub_ns);
-		/* add list ref */
-		aa_get_namespace(ns);
-	}
-out:
-	mutex_unlock(&root->lock);
-
-	/* return ref */
-	return ns;
-}
-
-/**
- * __list_add_profile - add a profile to a list
+ * __add_profile - add a profiles to list and label tree
  * @list: list to add it to  (NOT NULL)
  * @profile: the profile to add  (NOT NULL)
  *
@@ -422,12 +126,21 @@ out:
  *
  * Requires: namespace lock be held, or list not be shared
  */
-static void __list_add_profile(struct list_head *list,
-			       struct aa_profile *profile)
+static void __add_profile(struct list_head *list, struct aa_profile *profile)
 {
+	struct aa_label *l;
+
+	AA_BUG(!list);
+	AA_BUG(!profile);
+	AA_BUG(!profile->ns);
+	AA_BUG(!mutex_is_locked(&profile->ns->lock));
+
 	list_add_rcu(&profile->base.list, list);
 	/* get list reference */
 	aa_get_profile(profile);
+	l = aa_label_insert(&profile->ns->labels, &profile->label);
+	AA_BUG(l != &profile->label);
+	aa_put_label(l);
 }
 
 /**
@@ -444,11 +157,15 @@ static void __list_add_profile(struct li
  */
 static void __list_remove_profile(struct aa_profile *profile)
 {
+	AA_BUG(!profile);
+	AA_BUG(!profile->ns);
+	AA_BUG(!mutex_is_locked(&profile->ns->lock));
+
 	list_del_rcu(&profile->base.list);
 	aa_put_profile(profile);
 }
 
-static void __profile_list_release(struct list_head *head);
+void __aa_profile_list_release(struct list_head *head);
 
 /**
  * __remove_profile - remove old profile, and children
@@ -458,124 +175,31 @@ static void __profile_list_release(struc
  */
 static void __remove_profile(struct aa_profile *profile)
 {
+	AA_BUG(!profile);
+	AA_BUG(!profile->ns);
+	AA_BUG(!mutex_is_locked(&profile->ns->lock));
+
 	/* release any children lists first */
-	__profile_list_release(&profile->base.profiles);
+	__aa_profile_list_release(&profile->base.profiles);
 	/* released by free_profile */
-	__aa_update_replacedby(profile, profile->ns->unconfined);
+	aa_label_remove(&profile->label);
 	__aa_fs_profile_rmdir(profile);
 	__list_remove_profile(profile);
 }
 
 /**
- * __profile_list_release - remove all profiles on the list and put refs
+ * __aa_profile_list_release - remove all profiles on the list and put refs
  * @head: list of profiles  (NOT NULL)
  *
  * Requires: namespace lock be held
  */
-static void __profile_list_release(struct list_head *head)
+void __aa_profile_list_release(struct list_head *head)
 {
 	struct aa_profile *profile, *tmp;
 	list_for_each_entry_safe(profile, tmp, head, base.list)
 		__remove_profile(profile);
 }
 
-static void __ns_list_release(struct list_head *head);
-
-/**
- * destroy_namespace - remove everything contained by @ns
- * @ns: namespace to have it contents removed  (NOT NULL)
- */
-static void destroy_namespace(struct aa_namespace *ns)
-{
-	if (!ns)
-		return;
-
-	mutex_lock(&ns->lock);
-	/* release all profiles in this namespace */
-	__profile_list_release(&ns->base.profiles);
-
-	/* release all sub namespaces */
-	__ns_list_release(&ns->sub_ns);
-
-	if (ns->parent)
-		__aa_update_replacedby(ns->unconfined, ns->parent->unconfined);
-	__aa_fs_namespace_rmdir(ns);
-	mutex_unlock(&ns->lock);
-}
-
-/**
- * __remove_namespace - remove a namespace and all its children
- * @ns: namespace to be removed  (NOT NULL)
- *
- * Requires: ns->parent->lock be held and ns removed from parent.
- */
-static void __remove_namespace(struct aa_namespace *ns)
-{
-	/* remove ns from namespace list */
-	list_del_rcu(&ns->base.list);
-	destroy_namespace(ns);
-	aa_put_namespace(ns);
-}
-
-/**
- * __ns_list_release - remove all profile namespaces on the list put refs
- * @head: list of profile namespaces  (NOT NULL)
- *
- * Requires: namespace lock be held
- */
-static void __ns_list_release(struct list_head *head)
-{
-	struct aa_namespace *ns, *tmp;
-	list_for_each_entry_safe(ns, tmp, head, base.list)
-		__remove_namespace(ns);
-
-}
-
-/**
- * aa_alloc_root_ns - allocate the root profile namespace
- *
- * Returns: %0 on success else error
- *
- */
-int __init aa_alloc_root_ns(void)
-{
-	/* released by aa_free_root_ns - used as list ref*/
-	root_ns = alloc_namespace(NULL, "root");
-	if (!root_ns)
-		return -ENOMEM;
-
-	return 0;
-}
-
- /**
-  * aa_free_root_ns - free the root profile namespace
-  */
-void __init aa_free_root_ns(void)
- {
-	 struct aa_namespace *ns = root_ns;
-	 root_ns = NULL;
-
-	 destroy_namespace(ns);
-	 aa_put_namespace(ns);
-}
-
-
-static void free_replacedby(struct aa_replacedby *r)
-{
-	if (r) {
-		/* r->profile will not be updated any more as r is dead */
-		aa_put_profile(rcu_dereference_protected(r->profile, true));
-		kzfree(r);
-	}
-}
-
-
-void aa_free_replacedby_kref(struct kref *kref)
-{
-	struct aa_replacedby *r = container_of(kref, struct aa_replacedby,
-					       count);
-	free_replacedby(r);
-}
 
 /**
  * aa_free_profile - free a profile
@@ -589,95 +213,98 @@ void aa_free_replacedby_kref(struct kref
  */
 void aa_free_profile(struct aa_profile *profile)
 {
+	struct rhashtable *rht;
+
 	AA_DEBUG("%s(%p)\n", __func__, profile);
 
 	if (!profile)
 		return;
 
 	/* free children profiles */
-	policy_destroy(&profile->base);
+	aa_policy_destroy(&profile->base);
 	aa_put_profile(rcu_access_pointer(profile->parent));
 
-	aa_put_namespace(profile->ns);
+	aa_put_ns(profile->ns);
 	kzfree(profile->rename);
 
 	aa_free_file_rules(&profile->file);
 	aa_free_cap_rules(&profile->caps);
+	aa_free_net_rules(&profile->net);
 	aa_free_rlimit_rules(&profile->rlimits);
 
 	kzfree(profile->dirname);
 	aa_put_dfa(profile->xmatch);
 	aa_put_dfa(profile->policy.dfa);
-	aa_put_replacedby(profile->replacedby);
 
-	kzfree(profile->hash);
-	kzfree(profile);
-}
+	if (profile->data) {
+		rht = profile->data;
+		profile->data = NULL;
+		rhashtable_free_and_destroy(rht, aa_free_data, NULL);
+		kzfree(rht);
+	}
 
-/**
- * aa_free_profile_rcu - free aa_profile by rcu (called by aa_free_profile_kref)
- * @head: rcu_head callback for freeing of a profile  (NOT NULL)
- */
-static void aa_free_profile_rcu(struct rcu_head *head)
-{
-	struct aa_profile *p = container_of(head, struct aa_profile, rcu);
-	if (p->flags & PFLAG_NS_COUNT)
-		free_namespace(p->ns);
-	else
-		aa_free_profile(p);
-}
+	kzfree(profile->hash);
+	aa_put_loaddata(profile->rawdata);
 
-/**
- * aa_free_profile_kref - free aa_profile by kref (called by aa_put_profile)
- * @kr: kref callback for freeing of a profile  (NOT NULL)
- */
-void aa_free_profile_kref(struct kref *kref)
-{
-	struct aa_profile *p = container_of(kref, struct aa_profile, count);
-	call_rcu(&p->rcu, aa_free_profile_rcu);
+	kzfree(profile);
 }
 
 /**
  * aa_alloc_profile - allocate, initialize and return a new profile
  * @hname: name of the profile  (NOT NULL)
+ * @gfp: allocation type
  *
  * Returns: refcount profile or NULL on failure
  */
-struct aa_profile *aa_alloc_profile(const char *hname)
+struct aa_profile *aa_alloc_profile(const char *hname, struct aa_proxy *proxy,
+				    gfp_t gfp)
 {
 	struct aa_profile *profile;
 
 	/* freed by free_profile - usually through aa_put_profile */
-	profile = kzalloc(sizeof(*profile), GFP_KERNEL);
+	profile = kzalloc(sizeof(*profile) + sizeof (struct aa_profile *) * 2,
+			  gfp);
 	if (!profile)
 		return NULL;
 
-	profile->replacedby = kzalloc(sizeof(struct aa_replacedby), GFP_KERNEL);
-	if (!profile->replacedby)
+	if (!aa_policy_init(&profile->base, NULL, hname, gfp))
 		goto fail;
-	kref_init(&profile->replacedby->count);
-
-	if (!policy_init(&profile->base, NULL, hname))
+	if (!aa_label_init(&profile->label, 1))
 		goto fail;
-	kref_init(&profile->count);
+
+	/* update being set needed by fs interface */
+	if (!proxy) {
+		proxy = aa_alloc_proxy(&profile->label, gfp);
+		if (!proxy)
+			goto fail;
+	} else
+		aa_get_proxy(proxy);
+	profile->label.proxy = proxy;
+
+	profile->label.hname = profile->base.hname;
+	profile->label.flags |= FLAG_PROFILE;
+	profile->label.vec[0] = profile;
 
 	/* refcount released by caller */
 	return profile;
 
 fail:
-	kzfree(profile->replacedby);
-	kzfree(profile);
+	aa_free_profile(profile);
 
 	return NULL;
 }
 
 /**
- * aa_new_null_profile - create a new null-X learning profile
+ * aa_null_profile - create or find a null-X learning profile
  * @parent: profile that caused this profile to be created (NOT NULL)
  * @hat: true if the null- learning profile is a hat
+ * @base: name to base the null profile off of
+ * @gfp: type of allocation
  *
- * Create a null- complain mode profile used in learning mode.  The name of
- * the profile is unique and follows the format of parent//null-<uniq>.
+ * Find/Create a null- complain mode profile used in learning mode.  The
+ * name of the profile is unique and follows the format of parent//null-XXX.
+ * where XXX is based on the @name or if that fails or is not supplied
+ * a unique number
  *
  * null profiles are added to the profile list but the list does not
  * hold a count on them so that they are automatically released when
@@ -685,43 +312,86 @@ fail:
  *
  * Returns: new refcounted profile else NULL on failure
  */
-struct aa_profile *aa_new_null_profile(struct aa_profile *parent, int hat)
+struct aa_profile *aa_null_profile(struct aa_profile *parent, bool hat,
+				   const char *base, gfp_t gfp)
 {
-	struct aa_profile *profile = NULL;
+	struct aa_profile *profile;
 	char *name;
-	int uniq = atomic_inc_return(&parent->ns->uniq_null);
 
-	/* freed below */
-	name = kmalloc(strlen(parent->base.hname) + 2 + 7 + 8, GFP_KERNEL);
+	AA_BUG(!parent);
+
+	if (base) {
+		name = kmalloc(strlen(parent->base.hname) + 8 + strlen(base),
+			       gfp);
+		if (name) {
+			sprintf(name, "%s//null-%s", parent->base.hname, base);
+			goto name;
+		}
+		/* fall through to try shorter uniq */
+	}
+
+	name = kmalloc(strlen(parent->base.hname) + 2 + 7 + 8, gfp);
 	if (!name)
-		goto fail;
-	sprintf(name, "%s//null-%x", parent->base.hname, uniq);
+		return NULL;
+	sprintf(name, "%s//null-%x", parent->base.hname,
+		atomic_inc_return(&parent->ns->uniq_null));
 
-	profile = aa_alloc_profile(name);
-	kfree(name);
+name:
+	/* lookup to see if this is a dup creation */
+	profile = aa_find_child(parent, basename(name));
+	if (profile)
+		goto out;
+
+	profile = aa_alloc_profile(name, NULL, gfp);
 	if (!profile)
 		goto fail;
 
 	profile->mode = APPARMOR_COMPLAIN;
-	profile->flags = PFLAG_NULL;
+	profile->label.flags |= FLAG_NULL;
 	if (hat)
-		profile->flags |= PFLAG_HAT;
+		profile->label.flags |= FLAG_HAT;
 
 	/* released on free_profile */
 	rcu_assign_pointer(profile->parent, aa_get_profile(parent));
-	profile->ns = aa_get_namespace(parent->ns);
+	profile->ns = aa_get_ns(parent->ns);
+	profile->file.dfa = aa_get_dfa(nulldfa);
+	profile->policy.dfa = aa_get_dfa(nulldfa);
 
 	mutex_lock(&profile->ns->lock);
-	__list_add_profile(&parent->base.profiles, profile);
+	__add_profile(&parent->base.profiles, profile);
 	mutex_unlock(&profile->ns->lock);
 
 	/* refcount released by caller */
+out:
+	kfree(name);
 	return profile;
 
 fail:
+	aa_free_profile(profile);
 	return NULL;
 }
 
+/**
+ * aa_setup_default_label - create the initial default label
+ */
+struct aa_label *aa_setup_default_label(void)
+{
+	struct aa_profile *profile = aa_alloc_profile("default", NULL,
+						      GFP_KERNEL);
+	if (!profile)
+		return NULL;
+
+	/* the default profile pretends to be unconfined until it is replaced */
+	profile->label.flags |= FLAG_IX_ON_NAME_ERROR | FLAG_UNCONFINED;
+	profile->mode = APPARMOR_UNCONFINED;
+
+	profile->ns = aa_get_ns(root_ns);
+
+	__add_profile(&root_ns->base.profiles, profile);
+
+	return &profile->label;
+}
+
 /* TODO: profile accounting - setup in remove */
 
 /**
@@ -766,7 +436,9 @@ struct aa_profile *aa_find_child(struct
 	struct aa_profile *profile;
 
 	rcu_read_lock();
-	profile = aa_get_profile(__find_child(&parent->base.profiles, name));
+	do {
+		profile = __find_child(&parent->base.profiles, name);
+	} while (profile && !aa_get_profile_not0(profile));
 	rcu_read_unlock();
 
 	/* refcount released by caller */
@@ -786,8 +458,7 @@ struct aa_profile *aa_find_child(struct
  *
  * Returns: unrefcounted policy or NULL if not found
  */
-static struct aa_policy *__lookup_parent(struct aa_namespace *ns,
-					 const char *hname)
+static struct aa_policy *__lookup_parent(struct aa_ns *ns, const char *hname)
 {
 	struct aa_policy *policy;
 	struct aa_profile *profile = NULL;
@@ -810,9 +481,10 @@ static struct aa_policy *__lookup_parent
 }
 
 /**
- * __lookup_profile - lookup the profile matching @hname
+ * __lookupn_profile - lookup the profile matching @hname
  * @base: base list to start looking up profile name from  (NOT NULL)
  * @hname: hierarchical profile name  (NOT NULL)
+ * @n: length of @hname
  *
  * Requires: rcu_read_lock be held
  *
@@ -820,53 +492,95 @@ static struct aa_policy *__lookup_parent
  *
  * Do a relative name lookup, recursing through profile tree.
  */
-static struct aa_profile *__lookup_profile(struct aa_policy *base,
-					   const char *hname)
+static struct aa_profile *__lookupn_profile(struct aa_policy *base,
+					    const char *hname, size_t n)
 {
 	struct aa_profile *profile = NULL;
-	char *split;
+	const char *split;
 
-	for (split = strstr(hname, "//"); split;) {
+	for (split = strnstr(hname, "//", n); split;
+	     split = strnstr(hname, "//", n)) {
 		profile = __strn_find_child(&base->profiles, hname,
 					    split - hname);
 		if (!profile)
 			return NULL;
 
 		base = &profile->base;
+		n -= split + 2 - hname;
 		hname = split + 2;
-		split = strstr(hname, "//");
 	}
 
-	profile = __find_child(&base->profiles, hname);
+	if (n)
+		return __strn_find_child(&base->profiles, hname, n);
+	return NULL;
+}
 
-	return profile;
+static struct aa_profile *__lookup_profile(struct aa_policy *base,
+					   const char *hname)
+{
+	return __lookupn_profile(base, hname, strlen(hname));
 }
 
 /**
  * aa_lookup_profile - find a profile by its full or partial name
  * @ns: the namespace to start from (NOT NULL)
  * @hname: name to do lookup on.  Does not contain namespace prefix (NOT NULL)
+ * @n: size of @hname
  *
  * Returns: refcounted profile or NULL if not found
  */
-struct aa_profile *aa_lookup_profile(struct aa_namespace *ns, const char *hname)
+struct aa_profile *aa_lookupn_profile(struct aa_ns *ns, const char *hname,
+				      size_t n)
 {
 	struct aa_profile *profile;
 
 	rcu_read_lock();
 	do {
-		profile = __lookup_profile(&ns->base, hname);
+		profile = __lookupn_profile(&ns->base, hname, n);
 	} while (profile && !aa_get_profile_not0(profile));
 	rcu_read_unlock();
 
 	/* the unconfined profile is not in the regular profile list */
-	if (!profile && strcmp(hname, "unconfined") == 0)
+	if (!profile && strncmp(hname, "unconfined", n) == 0)
 		profile = aa_get_newest_profile(ns->unconfined);
 
 	/* refcount released by caller */
 	return profile;
 }
 
+struct aa_profile *aa_lookup_profile(struct aa_ns *ns, const char *hname)
+{
+	return aa_lookupn_profile(ns, hname, strlen(hname));
+}
+
+struct aa_profile *aa_fqlookupn_profile(struct aa_label *base,
+					const char *fqname, size_t n)
+{
+	struct aa_profile *profile;
+	struct aa_ns *ns;
+	const char *name, *ns_name;
+	size_t ns_len;
+
+	name = aa_splitn_fqname(fqname, n, &ns_name, &ns_len);
+	if (ns_name) {
+		ns = aa_findn_ns(labels_ns(base), ns_name, ns_len);
+		if (!ns)
+			return NULL;
+	} else
+		ns = aa_get_ns(labels_ns(base));
+
+	if (name)
+		profile = aa_lookupn_profile(ns, name, n - (name - fqname));
+	else if (ns)
+		/* default profile for ns, currently unconfined */
+		profile = aa_get_newest_profile(ns->unconfined);
+	else
+		profile = NULL;
+	aa_put_ns(ns);
+
+       return profile;
+}
+
 /**
  * replacement_allowed - test to see if replacement is allowed
  * @profile: profile to test if it can be replaced  (MAYBE NULL)
@@ -879,7 +593,7 @@ static int replacement_allowed(struct aa
 			       const char **info)
 {
 	if (profile) {
-		if (profile->flags & PFLAG_IMMUTABLE) {
+		if (profile->label.flags & FLAG_IMMUTIBLE) {
 			*info = "cannot replace immutible profile";
 			return -EPERM;
 		} else if (noreplace) {
@@ -890,58 +604,118 @@ static int replacement_allowed(struct aa
 	return 0;
 }
 
+/* audit callback for net specific fields */
+static void audit_cb(struct audit_buffer *ab, void *va)
+{
+	struct common_audit_data *sa = va;
+
+	if (aad(sa)->iface.ns) {
+		audit_log_format(ab, " ns=");
+		audit_log_untrustedstring(ab, aad(sa)->iface.ns);
+	}
+}
+
 /**
- * aa_audit_policy - Do auditing of policy changes
+ * audit_policy - Do auditing of policy changes
+ * @label: label to check if it can manage policy
  * @op: policy operation being performed
- * @gfp: memory allocation flags
- * @name: name of profile being manipulated (NOT NULL)
+ * @profile: name of profile being manipulated (NOT NULL)
  * @info: any extra information to be audited (MAYBE NULL)
  * @error: error code
  *
  * Returns: the error to be returned after audit is done
  */
-static int audit_policy(int op, gfp_t gfp, const char *name, const char *info,
-			int error)
+static int audit_policy(struct aa_label *label, const char *op,
+			const char *ns_name, const char *name,
+			const char *info, int error)
+{
+	DEFINE_AUDIT_DATA(sa, LSM_AUDIT_DATA_NONE, op);
+	//	aad(&sa)->op = op;
+	aad(&sa)->iface.ns = ns_name;
+	aad(&sa)->name = name;
+	aad(&sa)->info = info;
+	aad(&sa)->error = error;
+	aad(&sa)->label = label;
+
+	aa_audit_msg(AUDIT_APPARMOR_STATUS, &sa, audit_cb);
+
+	return error;
+}
+
+/**
+ * policy_view_capable - check if viewing policy in at @ns is allowed
+ * ns: namespace being viewed by current task (may be NULL)
+ * Returns: true if viewing policy is allowed
+ *
+ * If @ns is NULL then the namespace being viewed is assumed to be the
+ * tasks current namespace.
+ */
+bool policy_view_capable(struct aa_ns *ns)
+{
+	struct user_namespace *user_ns = current_user_ns();
+	struct aa_ns *view_ns = aa_get_current_ns();
+	bool root_in_user_ns = uid_eq(current_euid(), make_kuid(user_ns, 0)) ||
+			       in_egroup_p(make_kgid(user_ns, 0));
+	bool response = false;
+	if (!ns)
+		ns = view_ns;
+
+	if (root_in_user_ns && aa_ns_visible(view_ns, ns, true) &&
+	    (user_ns == &init_user_ns ||
+	     (unprivileged_userns_apparmor_policy != 0 &&
+	      user_ns->level == view_ns->level)))
+		response = true;
+	aa_put_ns(view_ns);
+
+	return response;
+}
+
+bool policy_admin_capable(struct aa_ns *ns)
 {
-	struct common_audit_data sa;
-	struct apparmor_audit_data aad = {0,};
-	sa.type = LSM_AUDIT_DATA_NONE;
-	sa.aad = &aad;
-	aad.op = op;
-	aad.name = name;
-	aad.info = info;
-	aad.error = error;
+	struct user_namespace *user_ns = current_user_ns();
+	bool capable = ns_capable(user_ns, CAP_MAC_ADMIN);
+
+	AA_DEBUG("cap_mac_admin? %d\n", capable);
+	AA_DEBUG("policy locked? %d\n", aa_g_lock_policy);
 
-	return aa_audit(AUDIT_APPARMOR_STATUS, __aa_current_profile(), gfp,
-			&sa, NULL);
+	return policy_view_capable(ns) && capable && !aa_g_lock_policy;
 }
 
 /**
  * aa_may_manage_policy - can the current task manage policy
+ * @label: label to check if it can manage policy
  * @op: the policy manipulation operation being done
  *
- * Returns: true if the task is allowed to manipulate policy
+ * Returns: 0 if the task is allowed to manipulate policy else error
  */
-bool aa_may_manage_policy(int op)
+int aa_may_manage_policy(struct aa_label *label, struct aa_ns *ns, u32 mask)
 {
-	/* check if loading policy is locked out */
-	if (aa_g_lock_policy) {
-		audit_policy(op, GFP_KERNEL, NULL, "policy_locked", -EACCES);
-		return 0;
-	}
+	const char *op;
 
-	if (!capable(CAP_MAC_ADMIN)) {
-		audit_policy(op, GFP_KERNEL, NULL, "not policy admin", -EACCES);
-		return 0;
-	}
+	if (mask & AA_MAY_REMOVE_POLICY)
+		op = OP_PROF_RM;
+	else if (mask & AA_MAY_REPLACE_POLICY)
+		op = OP_PROF_REPL;
+	else
+		op = OP_PROF_LOAD;
 
-	return 1;
+	/* check if loading policy is locked out */
+	if (aa_g_lock_policy)
+		return audit_policy(label, op, NULL, NULL, "policy_locked",
+				    -EACCES);
+
+	if (!policy_admin_capable(ns))
+		return audit_policy(label, op, NULL, NULL, "not policy admin",
+				    -EACCES);
+
+	/* TODO: add fine grained mediation of policy loads */
+	return 0;
 }
 
 static struct aa_profile *__list_lookup_parent(struct list_head *lh,
 					       struct aa_profile *profile)
 {
-	const char *base = hname_tail(profile->base.hname);
+	const char *base = basename(profile->base.hname);
 	long len = base - profile->base.hname;
 	struct aa_load_ent *ent;
 
@@ -965,7 +739,6 @@ static struct aa_profile *__list_lookup_
  * __replace_profile - replace @old with @new on a list
  * @old: profile to be replaced  (NOT NULL)
  * @new: profile to replace @old with  (NOT NULL)
- * @share_replacedby: transfer @old->replacedby to @new
  *
  * Will duplicate and refcount elements that @new inherits from @old
  * and will inherit @old children.
@@ -974,8 +747,7 @@ static struct aa_profile *__list_lookup_
  *
  * Requires: namespace list lock be held, or list not be shared
  */
-static void __replace_profile(struct aa_profile *old, struct aa_profile *new,
-			      bool share_replacedby)
+static void __replace_profile(struct aa_profile *old, struct aa_profile *new)
 {
 	struct aa_profile *child, *tmp;
 
@@ -990,7 +762,7 @@ static void __replace_profile(struct aa_
 			p = __find_child(&new->base.profiles, child->base.name);
 			if (p) {
 				/* @p replaces @child  */
-				__replace_profile(child, p, share_replacedby);
+				__replace_profile(child, p);
 				continue;
 			}
 
@@ -1008,14 +780,8 @@ static void __replace_profile(struct aa_
 		struct aa_profile *parent = aa_deref_parent(old);
 		rcu_assign_pointer(new->parent, aa_get_profile(parent));
 	}
-	__aa_update_replacedby(old, new);
-	if (share_replacedby) {
-		aa_put_replacedby(new->replacedby);
-		new->replacedby = aa_get_replacedby(old->replacedby);
-	} else if (!rcu_access_pointer(new->replacedby->profile))
-		/* aafs interface uses replacedby */
-		rcu_assign_pointer(new->replacedby->profile,
-				   aa_get_profile(new));
+	aa_label_replace(&old->label, &new->label);
+	/* migrate dents must come after label replacement b/c update */
 	__aa_fs_profile_migrate_dents(old, new);
 
 	if (list_empty(&new->base.list)) {
@@ -1037,7 +803,7 @@ static void __replace_profile(struct aa_
  *
  * Returns: profile to replace (no ref) on success else ptr error
  */
-static int __lookup_replace(struct aa_namespace *ns, const char *hname,
+static int __lookup_replace(struct aa_ns *ns, const char *hname,
 			    bool noreplace, struct aa_profile **p,
 			    const char **info)
 {
@@ -1053,62 +819,121 @@ static int __lookup_replace(struct aa_na
 	return 0;
 }
 
+static void share_name(struct aa_profile *old, struct aa_profile *new)
+{
+	aa_put_str(new->base.hname);
+	aa_get_str(old->base.hname);
+	new->base.hname = old->base.hname;
+	new->base.name = old->base.name;
+	new->label.hname = old->label.hname;
+}
+
+/* Update to newest version of parent after previous replacements
+ * Returns: unrefcount newest version of parent
+ */
+static struct aa_profile *update_to_newest_parent(struct aa_profile *new)
+{
+	struct aa_profile *parent, *newest;
+	parent = rcu_dereference_protected(new->parent,
+					   mutex_is_locked(&new->ns->lock));
+	newest = aa_get_newest_profile(parent);
+
+	/* parent replaced in this atomic set? */
+	if (newest != parent) {
+		aa_put_profile(parent);
+		rcu_assign_pointer(new->parent, newest);
+	} else
+		aa_put_profile(newest);
+
+	return newest;
+}
+
 /**
  * aa_replace_profiles - replace profile(s) on the profile list
+ * @view: namespace load is viewed from
+ * @label: label that is attempting to load/replace policy
+ * @mask: permission mask
  * @udata: serialized data stream  (NOT NULL)
- * @size: size of the serialized data stream
- * @noreplace: true if only doing addition, no replacement allowed
  *
  * unpack and replace a profile on the profile list and uses of that profile
- * by any aa_task_cxt.  If the profile does not exist on the profile list
+ * by any aa_task_ctx.  If the profile does not exist on the profile list
  * it is added.
  *
  * Returns: size of data consumed else error code on failure.
  */
-ssize_t aa_replace_profiles(void *udata, size_t size, bool noreplace)
+ssize_t aa_replace_profiles(struct aa_ns *view, struct aa_label *label,
+			    u32 mask, struct aa_loaddata *udata)
 {
-	const char *ns_name, *name = NULL, *info = NULL;
-	struct aa_namespace *ns = NULL;
+	const char *ns_name, *info = NULL;
+	struct aa_ns *ns = NULL;
 	struct aa_load_ent *ent, *tmp;
-	int op = OP_PROF_REPL;
-	ssize_t error;
+	const char *op = mask & AA_MAY_REPLACE_POLICY ? OP_PROF_REPL : OP_PROF_LOAD;
+	ssize_t count, error;
+
 	LIST_HEAD(lh);
 
 	/* released below */
-	error = aa_unpack(udata, size, &lh, &ns_name);
+	error = aa_unpack(udata, &lh, &ns_name);
 	if (error)
 		goto out;
 
-	/* released below */
-	ns = aa_prepare_namespace(ns_name);
-	if (!ns) {
-		info = "failed to prepare namespace";
-		error = -ENOMEM;
-		name = ns_name;
-		goto fail;
-	}
+	/* ensure that profiles are all for the same ns
+	 * TODO: update locking to remove this constaint. All profiles in
+	 *       the load set must succeed as a set or the load will
+	 *       fail. Sort ent list and take ns locks in hierarchy order
+	 */
+	count = 0;
+	list_for_each_entry(ent, &lh, list) {
+		if (ns_name) {
+			if (ent->ns_name &&
+			    strcmp(ent->ns_name, ns_name) != 0) {
+				info = "policy load has mixed namespaces";
+				error = -EACCES;
+				goto fail;
+			}
+		} else if (ent->ns_name) {
+			if (count) {
+				info = "policy load has mixed namespaces";
+				error = -EACCES;
+				goto fail;
+			}
+			ns_name = ent->ns_name;
+		} else
+			count++;
+	}
+	if (ns_name) {
+		ns = aa_prepare_ns(view, ns_name);
+		if (IS_ERR(ns)) {
+			info = "failed to prepare namespace";
+			error = PTR_ERR(ns);
+			ns = NULL;
+			goto fail;
+		}
+	} else
+		ns = aa_get_ns(view);
 
 	mutex_lock(&ns->lock);
 	/* setup parent and ns info */
 	list_for_each_entry(ent, &lh, list) {
 		struct aa_policy *policy;
 
-		name = ent->new->base.hname;
-		error = __lookup_replace(ns, ent->new->base.hname, noreplace,
+		ent->new->rawdata = aa_get_loaddata(udata);
+		error = __lookup_replace(ns, ent->new->base.hname,
+					 !(mask & AA_MAY_REPLACE_POLICY),
 					 &ent->old, &info);
 		if (error)
 			goto fail_lock;
 
 		if (ent->new->rename) {
 			error = __lookup_replace(ns, ent->new->rename,
-						 noreplace, &ent->rename,
-						 &info);
+						!(mask & AA_MAY_REPLACE_POLICY),
+						&ent->rename, &info);
 			if (error)
 				goto fail_lock;
 		}
 
 		/* released when @new is freed */
-		ent->new->ns = aa_get_namespace(ns);
+		ent->new->ns = aa_get_ns(ns);
 
 		if (ent->old || ent->rename)
 			continue;
@@ -1121,7 +946,6 @@ ssize_t aa_replace_profiles(void *udata,
 			if (!p) {
 				error = -ENOENT;
 				info = "parent does not exist";
-				name = ent->new->base.hname;
 				goto fail_lock;
 			}
 			rcu_assign_pointer(ent->new->parent, aa_get_profile(p));
@@ -1134,14 +958,7 @@ ssize_t aa_replace_profiles(void *udata,
 
 	/* create new fs entries for introspection if needed */
 	list_for_each_entry(ent, &lh, list) {
-		if (ent->old) {
-			/* inherit old interface files */
-
-			/* if (ent->rename)
-				TODO: support rename */
-		/* } else if (ent->rename) {
-			TODO: support rename */
-		} else {
+		if (!ent->old) {
 			struct dentry *parent;
 			if (rcu_access_pointer(ent->new->parent)) {
 				struct aa_profile *p;
@@ -1153,7 +970,7 @@ ssize_t aa_replace_profiles(void *udata,
 		}
 
 		if (error) {
-			info = "failed to create ";
+			info = "failed to create";
 			goto fail_lock;
 		}
 	}
@@ -1163,60 +980,56 @@ ssize_t aa_replace_profiles(void *udata,
 		list_del_init(&ent->list);
 		op = (!ent->old && !ent->rename) ? OP_PROF_LOAD : OP_PROF_REPL;
 
-		audit_policy(op, GFP_ATOMIC, ent->new->base.name, NULL, error);
+		audit_policy(label, op, ns_name, ent->new->base.hname, NULL, error);
 
 		if (ent->old) {
-			__replace_profile(ent->old, ent->new, 1);
-			if (ent->rename) {
-				/* aafs interface uses replacedby */
-				struct aa_replacedby *r = ent->new->replacedby;
-				rcu_assign_pointer(r->profile,
-						   aa_get_profile(ent->new));
-				__replace_profile(ent->rename, ent->new, 0);
-			}
+			share_name(ent->old, ent->new);
+			__replace_profile(ent->old, ent->new);
+			if (ent->rename)
+				__replace_profile(ent->rename, ent->new);
 		} else if (ent->rename) {
-			/* aafs interface uses replacedby */
-			rcu_assign_pointer(ent->new->replacedby->profile,
-					   aa_get_profile(ent->new));
-			__replace_profile(ent->rename, ent->new, 0);
-		} else if (ent->new->parent) {
-			struct aa_profile *parent, *newest;
-			parent = aa_deref_parent(ent->new);
-			newest = aa_get_newest_profile(parent);
-
-			/* parent replaced in this atomic set? */
-			if (newest != parent) {
-				aa_get_profile(newest);
-				aa_put_profile(parent);
-				rcu_assign_pointer(ent->new->parent, newest);
-			} else
-				aa_put_profile(newest);
-			/* aafs interface uses replacedby */
-			rcu_assign_pointer(ent->new->replacedby->profile,
-					   aa_get_profile(ent->new));
-			__list_add_profile(&parent->base.profiles, ent->new);
+			/* TODO: case not actually supported yet */
+			;
 		} else {
-			/* aafs interface uses replacedby */
-			rcu_assign_pointer(ent->new->replacedby->profile,
-					   aa_get_profile(ent->new));
-			__list_add_profile(&ns->base.profiles, ent->new);
+			struct list_head *lh;
+			if (rcu_access_pointer(ent->new->parent)) {
+                               struct aa_profile *parent;
+                               parent = update_to_newest_parent(ent->new);
+                               lh = &parent->base.profiles;
+			} else
+				lh = &ns->base.profiles;
+			__add_profile(lh, ent->new);
 		}
 		aa_load_ent_free(ent);
 	}
+	__aa_labelset_update_subtree(ns);
 	mutex_unlock(&ns->lock);
 
 out:
-	aa_put_namespace(ns);
+	aa_put_ns(ns);
 
 	if (error)
 		return error;
-	return size;
+	return udata->size;
 
 fail_lock:
 	mutex_unlock(&ns->lock);
-fail:
-	error = audit_policy(op, GFP_KERNEL, name, info, error);
 
+	/* audit cause of failure */
+	op = (!ent->old) ? OP_PROF_LOAD : OP_PROF_REPL;
+fail:
+	audit_policy(label, op, ns_name, ent->new->base.hname, info, error);
+	/* audit status that rest of profiles in the atomic set failed too */
+	info = "valid profile in failed atomic policy load";
+	list_for_each_entry(tmp, &lh, list) {
+		if (tmp == ent) {
+			info = "unchecked profile in failed atomic policy load";
+			/* skip entry that caused failure */
+			continue;
+		}
+		op = (!ent->old) ? OP_PROF_LOAD : OP_PROF_REPL;
+		audit_policy(label, op, ns_name, tmp->new->base.hname, info, error);
+	}
 	list_for_each_entry_safe(ent, tmp, &lh, list) {
 		list_del_init(&ent->list);
 		aa_load_ent_free(ent);
@@ -1227,6 +1040,8 @@ fail:
 
 /**
  * aa_remove_profiles - remove profile(s) from the system
+ * @view: namespace the remove is being done from
+ * @label: label attempting to remove policy
  * @fqname: name of the profile or namespace to remove  (NOT NULL)
  * @size: size of the name
  *
@@ -1237,11 +1052,13 @@ fail:
  *
  * Returns: size of data consume else error code if fails
  */
-ssize_t aa_remove_profiles(char *fqname, size_t size)
+ssize_t aa_remove_profiles(struct aa_ns *view, struct aa_label *label,
+			   char *fqname, size_t size)
 {
-	struct aa_namespace *root, *ns = NULL;
+	struct aa_ns *root = NULL, *ns = NULL;
 	struct aa_profile *profile = NULL;
 	const char *name = fqname, *info = NULL;
+	char *ns_name = NULL;
 	ssize_t error = 0;
 
 	if (*fqname == 0) {
@@ -1250,13 +1067,12 @@ ssize_t aa_remove_profiles(char *fqname,
 		goto fail;
 	}
 
-	root = aa_current_profile()->ns;
+	root = view;
 
 	if (fqname[0] == ':') {
-		char *ns_name;
 		name = aa_split_fqname(fqname, &ns_name);
 		/* released below */
-		ns = aa_find_namespace(root, ns_name);
+		ns = aa_find_ns(root, ns_name);
 		if (!ns) {
 			info = "namespace does not exist";
 			error = -ENOENT;
@@ -1264,12 +1080,12 @@ ssize_t aa_remove_profiles(char *fqname,
 		}
 	} else
 		/* released below */
-		ns = aa_get_namespace(root);
+		ns = aa_get_ns(root);
 
 	if (!name) {
 		/* remove namespace - can only happen if fqname[0] == ':' */
 		mutex_lock(&ns->parent->lock);
-		__remove_namespace(ns);
+		__aa_remove_ns(ns);
 		mutex_unlock(&ns->parent->lock);
 	} else {
 		/* remove profile */
@@ -1282,20 +1098,19 @@ ssize_t aa_remove_profiles(char *fqname,
 		}
 		name = profile->base.hname;
 		__remove_profile(profile);
+		__aa_labelset_update_subtree(ns);
 		mutex_unlock(&ns->lock);
 	}
 
 	/* don't fail removal if audit fails */
-	(void) audit_policy(OP_PROF_RM, GFP_KERNEL, name, info, error);
-	aa_put_namespace(ns);
+	(void) audit_policy(label, OP_PROF_RM, ns_name, name, info, error);
 	aa_put_profile(profile);
 	return size;
 
 fail_ns_lock:
 	mutex_unlock(&ns->lock);
-	aa_put_namespace(ns);
 
 fail:
-	(void) audit_policy(OP_PROF_RM, GFP_KERNEL, name, info, error);
+	(void) audit_policy(label, OP_PROF_RM, ns_name, name, info, error);
 	return error;
 }
--- /dev/null
+++ zfcpdump-kernel-4.4/security/apparmor/policy_ns.c
@@ -0,0 +1,353 @@
+/*
+ * AppArmor security module
+ *
+ * This file contains AppArmor policy manipulation functions
+ *
+ * Copyright (C) 1998-2008 Novell/SUSE
+ * Copyright 2009-2015 Canonical Ltd.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2 of the
+ * License.
+ *
+ * AppArmor policy namespaces, allow for different sets of policies
+ * to be loaded for tasks within the namespace.
+ */
+
+#include <linux/list.h>
+#include <linux/mutex.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+
+#include "include/apparmor.h"
+#include "include/context.h"
+#include "include/policy_ns.h"
+#include "include/label.h"
+#include "include/policy.h"
+
+/* root profile namespace */
+struct aa_ns *root_ns;
+const char *aa_hidden_ns_name = "---";
+
+/**
+ * aa_ns_visible - test if @view is visible from @curr
+ * @curr: namespace to treat as the parent (NOT NULL)
+ * @view: namespace to test if visible from @curr (NOT NULL)
+ * @subns: whether view of a subns is allowed
+ *
+ * Returns: true if @view is visible from @curr else false
+ */
+bool aa_ns_visible(struct aa_ns *curr, struct aa_ns *view, bool subns)
+{
+	if (curr == view)
+		return true;
+
+	if (!subns)
+		return false;
+
+	for ( ; view; view = view->parent) {
+		if (view->parent == curr)
+			return true;
+	}
+
+	return false;
+}
+
+/**
+ * aa_na_name - Find the ns name to display for @view from @curr
+ * @curr - current namespace (NOT NULL)
+ * @view - namespace attempting to view (NOT NULL)
+ * @subns - are subns visible
+ *
+ * Returns: name of @view visible from @curr
+ */
+const char *aa_ns_name(struct aa_ns *curr, struct aa_ns *view, bool subns)
+{
+	/* if view == curr then the namespace name isn't displayed */
+	if (curr == view)
+		return "";
+
+	if (aa_ns_visible(curr, view, subns)) {
+		/* at this point if a ns is visible it is in a view ns
+		 * thus the curr ns.hname is a prefix of its name.
+		 * Only output the virtualized portion of the name
+		 * Add + 2 to skip over // separating curr hname prefix
+		 * from the visible tail of the views hname
+		 */
+		return view->base.hname + strlen(curr->base.hname) + 2;
+	} else
+		return aa_hidden_ns_name;
+}
+
+/**
+ * alloc_ns - allocate, initialize and return a new namespace
+ * @prefix: parent namespace name (MAYBE NULL)
+ * @name: a preallocated name  (NOT NULL)
+ *
+ * Returns: refcounted namespace or NULL on failure.
+ */
+static struct aa_ns *alloc_ns(const char *prefix, const char *name)
+{
+	struct aa_ns *ns;
+
+	ns = kzalloc(sizeof(*ns), GFP_KERNEL);
+	AA_DEBUG("%s(%p)\n", __func__, ns);
+	if (!ns)
+		return NULL;
+	if (!aa_policy_init(&ns->base, prefix, name, GFP_KERNEL))
+		goto fail_ns;
+
+	INIT_LIST_HEAD(&ns->sub_ns);
+	mutex_init(&ns->lock);
+
+	/* released by free_namespace */
+	ns->unconfined = aa_alloc_profile("unconfined", NULL, GFP_KERNEL);
+	if (!ns->unconfined)
+		goto fail_unconfined;
+
+	ns->unconfined->label.flags |= FLAG_IX_ON_NAME_ERROR |
+		FLAG_IMMUTIBLE | FLAG_NS_COUNT | FLAG_UNCONFINED;
+	ns->unconfined->mode = APPARMOR_UNCONFINED;
+
+	/* ns and ns->unconfined share ns->unconfined refcount */
+	ns->unconfined->ns = ns;
+
+	atomic_set(&ns->uniq_null, 0);
+
+	aa_labelset_init(&ns->labels);
+
+	return ns;
+
+fail_unconfined:
+	kzfree(ns->base.hname);
+fail_ns:
+	kzfree(ns);
+	return NULL;
+}
+
+/**
+ * aa_free_ns - free a profile namespace
+ * @ns: the namespace to free  (MAYBE NULL)
+ *
+ * Requires: All references to the namespace must have been put, if the
+ *           namespace was referenced by a profile confining a task,
+ */
+void aa_free_ns(struct aa_ns *ns)
+{
+	if (!ns)
+		return;
+
+	aa_policy_destroy(&ns->base);
+	aa_labelset_destroy(&ns->labels);
+	aa_put_ns(ns->parent);
+
+	ns->unconfined->ns = NULL;
+	aa_free_profile(ns->unconfined);
+	kzfree(ns);
+}
+
+/**
+ * aa_find_ns  -  look up a profile namespace on the namespace list
+ * @root: namespace to search in  (NOT NULL)
+ * @name: name of namespace to find  (NOT NULL)
+ * @n: length of @name
+ *
+ * Returns: a refcounted namespace on the list, or NULL if no namespace
+ *          called @name exists.
+ *
+ * refcount released by caller
+ */
+struct aa_ns *aa_findn_ns(struct aa_ns *root, const char *name, size_t n)
+{
+	struct aa_ns *ns = NULL;
+
+	rcu_read_lock();
+	ns = aa_get_ns(__aa_findn_ns(&root->sub_ns, name, n));
+	rcu_read_unlock();
+
+	return ns;
+}
+
+/**
+ * aa_find_ns  -  look up a profile namespace on the namespace list
+ * @root: namespace to search in  (NOT NULL)
+ * @name: name of namespace to find  (NOT NULL)
+ *
+ * Returns: a refcounted namespace on the list, or NULL if no namespace
+ *          called @name exists.
+ *
+ * refcount released by caller
+ */
+struct aa_ns *aa_find_ns(struct aa_ns *root, const char *name)
+{
+	return aa_findn_ns(root, name, strlen(name));
+}
+
+static struct aa_ns *__aa_create_ns(struct aa_ns *parent, const char *name,
+				    struct dentry *dir)
+{
+	struct aa_ns *ns;
+	int error;
+
+	AA_BUG(!parent);
+	AA_BUG(!name);
+	AA_BUG(!mutex_is_locked(&parent->lock));
+
+	ns = alloc_ns(parent->base.hname, name);
+	if (!ns)
+		return NULL;
+	mutex_lock(&ns->lock);
+	error = __aa_fs_ns_mkdir(ns, ns_subns_dir(parent), name, dir);
+	if (error) {
+		AA_ERROR("Failed to create interface for ns %s\n",
+			 ns->base.name);
+		mutex_unlock(&ns->lock);
+		aa_free_ns(ns);
+		return ERR_PTR(error);
+	} else {
+		ns->parent = aa_get_ns(parent);
+		ns->level = parent->level + 1;
+		list_add_rcu(&ns->base.list, &parent->sub_ns);
+		/* add list ref */
+		aa_get_ns(ns);
+	}
+	mutex_unlock(&ns->lock);
+
+	return ns;
+}
+
+/**
+ * aa_create_ns - create an ns, fail if it already exists
+ * @parent: the parent of the namespace being created
+ * @name: the name of the namespace
+ * @dir: if not null the dir to put the ns entries in
+ *
+ * Returns: the a refcounted ns that has been add or an ERR_PTR
+ */
+struct aa_ns *aa_create_ns(struct aa_ns *parent, const char *name,
+			   struct dentry *dir)
+{
+	struct aa_ns *ns;
+
+	mutex_lock(&parent->lock);
+	/* try and find the specified ns */
+	/* released by caller */
+	ns = aa_get_ns(__aa_find_ns(&parent->sub_ns, name));
+	if (!ns)
+		ns = __aa_create_ns(parent, name, dir);
+	else
+		ns = ERR_PTR(-EEXIST);
+	mutex_unlock(&parent->lock);
+
+	/* return ref */
+	return ns;
+}
+
+/**
+ * aa_prepare_ns - find an existing or create a new namespace of @name
+ * @parent: ns to treat as parent
+ * @name: the namespace to find or add  (NOT NULL)
+ *
+ * Returns: refcounted namespace or PTR_ERR if failed to create one
+ */
+struct aa_ns *aa_prepare_ns(struct aa_ns *parent, const char *name)
+{
+	struct aa_ns *ns;
+
+	mutex_lock(&parent->lock);
+	/* try and find the specified ns and if it doesn't exist create it */
+	/* released by caller */
+	ns = aa_get_ns(__aa_find_ns(&parent->sub_ns, name));
+	if (!ns)
+		ns = __aa_create_ns(parent, name, NULL);
+	mutex_unlock(&parent->lock);
+
+	/* return ref */
+	return ns;
+}
+
+static void __ns_list_release(struct list_head *head);
+
+/**
+ * destroy_namespace - remove everything contained by @ns
+ * @ns: namespace to have it contents removed  (NOT NULL)
+ */
+static void destroy_ns(struct aa_ns *ns)
+{
+	if (!ns)
+		return;
+
+	mutex_lock(&ns->lock);
+	/* release all profiles in this namespace */
+	__aa_profile_list_release(&ns->base.profiles);
+
+	/* release all sub namespaces */
+	__ns_list_release(&ns->sub_ns);
+
+	if (ns->parent) {
+		unsigned long flags;
+		write_lock_irqsave(&ns->labels.lock, flags);
+		__aa_proxy_redirect(ns_unconfined(ns),
+				    ns_unconfined(ns->parent));
+		write_unlock_irqrestore(&ns->labels.lock, flags);
+	}
+	__aa_fs_ns_rmdir(ns);
+	mutex_unlock(&ns->lock);
+}
+
+/**
+ * __aa_remove_ns - remove a namespace and all its children
+ * @ns: namespace to be removed  (NOT NULL)
+ *
+ * Requires: ns->parent->lock be held and ns removed from parent.
+ */
+void __aa_remove_ns(struct aa_ns *ns)
+{
+	/* remove ns from namespace list */
+	list_del_rcu(&ns->base.list);
+	destroy_ns(ns);
+	aa_put_ns(ns);
+}
+
+/**
+ * __ns_list_release - remove all profile namespaces on the list put refs
+ * @head: list of profile namespaces  (NOT NULL)
+ *
+ * Requires: namespace lock be held
+ */
+static void __ns_list_release(struct list_head *head)
+{
+	struct aa_ns *ns, *tmp;
+	list_for_each_entry_safe(ns, tmp, head, base.list)
+		__aa_remove_ns(ns);
+
+}
+
+/**
+ * aa_alloc_root_ns - allocate the root profile namespace
+ *
+ * Returns: %0 on success else error
+ *
+ */
+int __init aa_alloc_root_ns(void)
+{
+	/* released by aa_free_root_ns - used as list ref*/
+	root_ns = alloc_ns(NULL, "root");
+	if (!root_ns)
+		return -ENOMEM;
+
+	return 0;
+}
+
+ /**
+  * aa_free_root_ns - free the root profile namespace
+  */
+void __init aa_free_root_ns(void)
+ {
+	 struct aa_ns *ns = root_ns;
+	 root_ns = NULL;
+
+	 destroy_ns(ns);
+	 aa_put_ns(ns);
+}
--- zfcpdump-kernel-4.4.orig/security/apparmor/policy_unpack.c
+++ zfcpdump-kernel-4.4/security/apparmor/policy_unpack.c
@@ -20,15 +20,26 @@
 #include <asm/unaligned.h>
 #include <linux/ctype.h>
 #include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/jhash.h>
 
 #include "include/apparmor.h"
 #include "include/audit.h"
 #include "include/context.h"
 #include "include/crypto.h"
 #include "include/match.h"
+#include "include/path.h"
 #include "include/policy.h"
 #include "include/policy_unpack.h"
 
+#define K_ABI_MASK 0x3ff
+#define FORCE_COMPLAIN_FLAG 0x800
+#define VERSION_CMP(OP, X, Y) (((X) & K_ABI_MASK) OP ((Y) & K_ABI_MASK))
+
+#define v5	5	/* base version */
+#define v6	6	/* per entry policydb mediation check */
+#define v7	7	/* full network masking */
+
 /*
  * The AppArmor interface treats data as a type byte followed by the
  * actual data.  The interface has the notion of a a named entry
@@ -70,18 +81,23 @@ struct aa_ext {
 static void audit_cb(struct audit_buffer *ab, void *va)
 {
 	struct common_audit_data *sa = va;
-	if (sa->aad->iface.target) {
-		struct aa_profile *name = sa->aad->iface.target;
+
+	if (aad(sa)->iface.ns) {
+		audit_log_format(ab, " ns=");
+		audit_log_untrustedstring(ab, aad(sa)->iface.ns);
+	}
+	if (aad(sa)->name) {
 		audit_log_format(ab, " name=");
-		audit_log_untrustedstring(ab, name->base.hname);
+		audit_log_untrustedstring(ab, aad(sa)->name);
 	}
-	if (sa->aad->iface.pos)
-		audit_log_format(ab, " offset=%ld", sa->aad->iface.pos);
+	if (aad(sa)->iface.pos)
+		audit_log_format(ab, " offset=%ld", aad(sa)->iface.pos);
 }
 
 /**
  * audit_iface - do audit message for policy unpacking/load/replace/remove
  * @new: profile if it has been allocated (MAYBE NULL)
+ * @ns_name: name of the ns the profile is to be loaded to (MAY BE NULL)
  * @name: name of the profile being manipulated (MAYBE NULL)
  * @info: any extra info about the failure (MAYBE NULL)
  * @e: buffer position info
@@ -89,23 +105,33 @@ static void audit_cb(struct audit_buffer
  *
  * Returns: %0 or error
  */
-static int audit_iface(struct aa_profile *new, const char *name,
-		       const char *info, struct aa_ext *e, int error)
+static int audit_iface(struct aa_profile *new, const char *ns_name,
+		       const char *name, const char *info, struct aa_ext *e,
+		       int error)
 {
-	struct aa_profile *profile = __aa_current_profile();
-	struct common_audit_data sa;
-	struct apparmor_audit_data aad = {0,};
-	sa.type = LSM_AUDIT_DATA_NONE;
-	sa.aad = &aad;
+	struct aa_profile *profile = labels_profile(aa_current_raw_label());
+	DEFINE_AUDIT_DATA(sa, LSM_AUDIT_DATA_NONE, NULL);
 	if (e)
-		aad.iface.pos = e->pos - e->start;
-	aad.iface.target = new;
-	aad.name = name;
-	aad.info = info;
-	aad.error = error;
+		aad(&sa)->iface.pos = e->pos - e->start;
 
-	return aa_audit(AUDIT_APPARMOR_STATUS, profile, GFP_KERNEL, &sa,
-			audit_cb);
+	aad(&sa)->iface.ns = ns_name;
+	if (new)
+		aad(&sa)->name = new->base.hname;
+	else
+		aad(&sa)->name = name;
+	aad(&sa)->info = info;
+	aad(&sa)->error = error;
+
+	return aa_audit(AUDIT_APPARMOR_STATUS, profile, &sa, audit_cb);
+}
+
+void aa_loaddata_kref(struct kref *kref)
+{
+	struct aa_loaddata *d = container_of(kref, struct aa_loaddata, count);
+	if (d) {
+		kzfree(d->hash);
+		kvfree(d);
+	}
 }
 
 /* test if read will be in packed data bounds */
@@ -193,6 +219,19 @@ fail:
 	return 0;
 }
 
+static bool unpack_u16(struct aa_ext *e, u16 *data, const char *name)
+{
+	if (unpack_nameX(e, AA_U16, name)) {
+		if (!inbounds(e, sizeof(u16)))
+			return 0;
+		if (data)
+			*data = le16_to_cpu(get_unaligned((u16 *) e->pos));
+		e->pos += sizeof(u16);
+		return 1;
+	}
+	return 0;
+}
+
 static bool unpack_u32(struct aa_ext *e, u32 *data, const char *name)
 {
 	if (unpack_nameX(e, AA_U32, name)) {
@@ -340,12 +379,7 @@ static struct aa_dfa *unpack_dfa(struct
 			((e->pos - e->start) & 7);
 		size_t pad = ALIGN(sz, 8) - sz;
 		int flags = TO_ACCEPT1_FLAG(YYTD_DATA32) |
-			TO_ACCEPT2_FLAG(YYTD_DATA32);
-
-
-		if (aa_g_paranoid_load)
-			flags |= DFA_FLAG_VERIFY_STATES;
-
+			TO_ACCEPT2_FLAG(YYTD_DATA32) | DFA_FLAG_VERIFY_STATES;
 		dfa = aa_dfa_unpack(blob + pad, size - pad, flags);
 
 		if (IS_ERR(dfa))
@@ -389,7 +423,7 @@ static bool unpack_trans_table(struct aa
 		profile->file.trans.size = size;
 		for (i = 0; i < size; i++) {
 			char *str;
-			int c, j, size2 = unpack_strdup(e, &str, NULL);
+			int c, j, pos, size2 = unpack_strdup(e, &str, NULL);
 			/* unpack_strdup verifies that the last character is
 			 * null termination byte.
 			 */
@@ -401,19 +435,24 @@ static bool unpack_trans_table(struct aa
 				goto fail;
 
 			/* count internal #  of internal \0 */
-			for (c = j = 0; j < size2 - 2; j++) {
-				if (!str[j])
+			for (c = j = 0; j < size2 - 1; j++) {
+				if (!str[j]) {
+					pos = j;
 					c++;
+				}
 			}
 			if (*str == ':') {
+				/* first character after : must be valid */
+				if (!str[1])
+					goto fail;
 				/* beginning with : requires an embedded \0,
 				 * verify that exactly 1 internal \0 exists
 				 * trailing \0 already verified by unpack_strdup
 				 */
-				if (c != 1)
-					goto fail;
-				/* first character after : must be valid */
-				if (!str[1])
+				if (c == 1)
+					/* convert \0 back to : for label_parse */
+					str[pos] = ':';
+				else if (c > 1)
 					goto fail;
 			} else if (c)
 				/* fail - all other cases with embedded \0 */
@@ -466,27 +505,68 @@ fail:
 	return 0;
 }
 
+static void *kvmemdup(const void *src, size_t len)
+{
+	void *p = kvmalloc(len);
+
+	if (p)
+		memcpy(p, src, len);
+	return p;
+}
+
+static u32 strhash(const void *data, u32 len, u32 seed)
+{
+	const char * const *key = data;
+
+	return jhash(*key, strlen(*key), seed);
+}
+
+static int datacmp(struct rhashtable_compare_arg *arg, const void *obj)
+{
+	const struct aa_data *data = obj;
+	const char * const *key = arg->key;
+
+	return strcmp(data->key, *key);
+}
+
 /**
  * unpack_profile - unpack a serialized profile
  * @e: serialized data extent information (NOT NULL)
  *
  * NOTE: unpack profile sets audit struct if there is a failure
  */
-static struct aa_profile *unpack_profile(struct aa_ext *e)
+static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name)
 {
 	struct aa_profile *profile = NULL;
-	const char *name = NULL;
+	const char *tmpname, *tmpns = NULL, *name = NULL;
+	const char *info = "failed to unpack profile";
+	size_t size = 0, ns_len;
+	struct rhashtable_params params = { 0 };
+	char *key = NULL;
+	struct aa_data *data;
 	int i, error = -EPROTO;
 	kernel_cap_t tmpcap;
 	u32 tmp;
 
+	*ns_name = NULL;
+
 	/* check that we have the right struct being passed */
 	if (!unpack_nameX(e, AA_STRUCT, "profile"))
 		goto fail;
 	if (!unpack_str(e, &name, NULL))
 		goto fail;
+	if (*name == '\0')
+		goto fail;
+
+	tmpname = aa_splitn_fqname(name, strlen(name), &tmpns, &ns_len);
+	if (tmpns) {
+	  *ns_name = kstrndup(tmpns, ns_len, GFP_KERNEL);
+		if (!*ns_name)
+			goto fail;
+		name = tmpname;
+	}
 
-	profile = aa_alloc_profile(name);
+	profile = aa_alloc_profile(name, NULL, GFP_KERNEL);
 	if (!profile)
 		return ERR_PTR(-ENOMEM);
 
@@ -510,16 +590,19 @@ static struct aa_profile *unpack_profile
 		profile->xmatch_len = tmp;
 	}
 
+	/* disconnected attachment string is optional */
+	(void) unpack_str(e, &profile->disconnected, "disconnected");
+
 	/* per profile debug flags (complain, audit) */
 	if (!unpack_nameX(e, AA_STRUCT, "flags"))
 		goto fail;
 	if (!unpack_u32(e, &tmp, NULL))
 		goto fail;
 	if (tmp & PACKED_FLAG_HAT)
-		profile->flags |= PFLAG_HAT;
+		profile->label.flags |= FLAG_HAT;
 	if (!unpack_u32(e, &tmp, NULL))
 		goto fail;
-	if (tmp == PACKED_MODE_COMPLAIN)
+	if (tmp == PACKED_MODE_COMPLAIN || (e->version & FORCE_COMPLAIN_FLAG))
 		profile->mode = APPARMOR_COMPLAIN;
 	else if (tmp == PACKED_MODE_KILL)
 		profile->mode = APPARMOR_KILL;
@@ -534,11 +617,9 @@ static struct aa_profile *unpack_profile
 		goto fail;
 
 	/* path_flags is optional */
-	if (unpack_u32(e, &profile->path_flags, "path_flags"))
-		profile->path_flags |= profile->flags & PFLAG_MEDIATE_DELETED;
-	else
+	if (!unpack_u32(e, &profile->path_flags, "path_flags"))
 		/* set a default value if path_flags field is not present */
-		profile->path_flags = PFLAG_MEDIATE_DELETED;
+		profile->path_flags = PATH_MEDIATE_DELETED;
 
 	if (!unpack_u32(e, &(profile->caps.allow.cap[0]), NULL))
 		goto fail;
@@ -576,6 +657,37 @@ static struct aa_profile *unpack_profile
 	if (!unpack_rlimits(e, profile))
 		goto fail;
 
+	size = unpack_array(e, "net_allowed_af");
+	if (size) {
+
+		for (i = 0; i < size; i++) {
+			/* discard extraneous rules that this kernel will
+			 * never request
+			 */
+			if (i >= AF_MAX) {
+				u16 tmp;
+				if (!unpack_u16(e, &tmp, NULL) ||
+				    !unpack_u16(e, &tmp, NULL) ||
+				    !unpack_u16(e, &tmp, NULL))
+					goto fail;
+				continue;
+			}
+			if (!unpack_u16(e, &profile->net.allow[i], NULL))
+				goto fail;
+			if (!unpack_u16(e, &profile->net.audit[i], NULL))
+				goto fail;
+			if (!unpack_u16(e, &profile->net.quiet[i], NULL))
+				goto fail;
+		}
+		if (!unpack_nameX(e, AA_ARRAYEND, NULL))
+			goto fail;
+	}
+	if (VERSION_CMP(<, e->version, v7)) {
+		/* old policy always allowed these too */
+		profile->net.allow[AF_UNIX] = 0xffff;
+		profile->net.allow[AF_NETLINK] = 0xffff;
+	}
+
 	if (unpack_nameX(e, AA_STRUCT, "policydb")) {
 		/* generic policy dfa - optional and may be NULL */
 		profile->policy.dfa = unpack_dfa(e);
@@ -583,6 +695,9 @@ static struct aa_profile *unpack_profile
 			error = PTR_ERR(profile->policy.dfa);
 			profile->policy.dfa = NULL;
 			goto fail;
+		} else if (!profile->policy.dfa) {
+			error = -EPROTO;
+			goto fail;
 		}
 		if (!unpack_u32(e, &profile->policy.start[0], "start"))
 			/* default start state */
@@ -596,7 +711,8 @@ static struct aa_profile *unpack_profile
 		}
 		if (!unpack_nameX(e, AA_STRUCTEND, NULL))
 			goto fail;
-	}
+	} else
+		profile->policy.dfa = aa_get_dfa(nulldfa);
 
 	/* get file rules */
 	profile->file.dfa = unpack_dfa(e);
@@ -604,15 +720,59 @@ static struct aa_profile *unpack_profile
 		error = PTR_ERR(profile->file.dfa);
 		profile->file.dfa = NULL;
 		goto fail;
-	}
-
-	if (!unpack_u32(e, &profile->file.start, "dfa_start"))
-		/* default start state */
-		profile->file.start = DFA_START;
+	} else if (profile->file.dfa) {
+		if (!unpack_u32(e, &profile->file.start, "dfa_start"))
+			/* default start state */
+			profile->file.start = DFA_START;
+	} else if (profile->policy.dfa &&
+		   profile->policy.start[AA_CLASS_FILE]) {
+		profile->file.dfa = aa_get_dfa(profile->policy.dfa);
+		profile->file.start = profile->policy.start[AA_CLASS_FILE];
+	} else
+		profile->file.dfa = aa_get_dfa(nulldfa);
 
 	if (!unpack_trans_table(e, profile))
 		goto fail;
 
+	if (unpack_nameX(e, AA_STRUCT, "data")) {
+		profile->data = kzalloc(sizeof(*profile->data), GFP_KERNEL);
+		if (!profile->data)
+			goto fail;
+
+		params.nelem_hint = 3;
+		params.key_len = sizeof(void *);
+		params.key_offset = offsetof(struct aa_data, key);
+		params.head_offset = offsetof(struct aa_data, head);
+		params.hashfn = strhash;
+		params.obj_cmpfn = datacmp;
+
+		if (rhashtable_init(profile->data, &params))
+			goto fail;
+
+		while (unpack_strdup(e, &key, NULL)) {
+			data = kzalloc(sizeof(*data), GFP_KERNEL);
+			if (!data) {
+				kzfree(key);
+				goto fail;
+			}
+
+			data->key = key;
+			data->size = unpack_blob(e, &data->data, NULL);
+			data->data = kvmemdup(data->data, data->size);
+			if (data->size && !data->data) {
+				kzfree(data->key);
+				kzfree(data);
+				goto fail;
+			}
+
+			rhashtable_insert_fast(profile->data, &data->head,
+					       profile->data->p);
+		}
+
+		if (!unpack_nameX(e, AA_STRUCTEND, NULL))
+			goto fail;
+	}
+
 	if (!unpack_nameX(e, AA_STRUCTEND, NULL))
 		goto fail;
 
@@ -623,7 +783,7 @@ fail:
 		name = NULL;
 	else if (!name)
 		name = "unknown";
-	audit_iface(profile, name, "failed to unpack profile", e, error);
+	audit_iface(profile, NULL, name, info, e, error);
 	aa_free_profile(profile);
 
 	return ERR_PTR(error);
@@ -646,24 +806,32 @@ static int verify_header(struct aa_ext *
 	/* get the interface version */
 	if (!unpack_u32(e, &e->version, "version")) {
 		if (required) {
-			audit_iface(NULL, NULL, "invalid profile format", e,
-				    error);
-			return error;
-		}
-
-		/* check that the interface version is currently supported */
-		if (e->version != 5) {
-			audit_iface(NULL, NULL, "unsupported interface version",
+			audit_iface(NULL, NULL, NULL, "invalid profile format",
 				    e, error);
 			return error;
 		}
 	}
 
+	/* Check that the interface version is currently supported.
+	 * if not specified use previous version
+	 * Mask off everything that is not kernel abi version
+	 */
+	if (VERSION_CMP(<, e->version, v5) && VERSION_CMP(>, e->version, v7)) {
+		audit_iface(NULL, NULL, NULL, "unsupported interface version",
+			    e, error);
+		return error;
+	}
 
 	/* read the namespace if present */
 	if (unpack_str(e, &name, "namespace")) {
+		if (*name == '\0') {
+			audit_iface(NULL, NULL, NULL, "invalid namespace name",
+				    e, error);
+			return error;
+		}
 		if (*ns && strcmp(*ns, name))
-			audit_iface(NULL, NULL, "invalid ns change", e, error);
+			audit_iface(NULL, NULL, NULL, "invalid ns change", e,
+				    error);
 		else if (!*ns)
 			*ns = name;
 	}
@@ -676,7 +844,7 @@ static bool verify_xindex(int xindex, in
 	int index, xtype;
 	xtype = xindex & AA_X_TYPE_MASK;
 	index = xindex & AA_X_INDEX_MASK;
-	if (xtype == AA_X_TABLE && index > table_size)
+	if (xtype == AA_X_TABLE && index >= table_size)
 		return 0;
 	return 1;
 }
@@ -702,14 +870,12 @@ static bool verify_dfa_xindex(struct aa_
  */
 static int verify_profile(struct aa_profile *profile)
 {
-	if (aa_g_paranoid_load) {
-		if (profile->file.dfa &&
-		    !verify_dfa_xindex(profile->file.dfa,
-				       profile->file.trans.size)) {
-			audit_iface(profile, NULL, "Invalid named transition",
-				    NULL, -EPROTO);
-			return -EPROTO;
-		}
+	if (profile->file.dfa &&
+	    !verify_dfa_xindex(profile->file.dfa,
+			       profile->file.trans.size)) {
+		audit_iface(profile, NULL, NULL,
+			    "Invalid named transition", NULL, -EPROTO);
+		return -EPROTO;
 	}
 
 	return 0;
@@ -721,6 +887,7 @@ void aa_load_ent_free(struct aa_load_ent
 		aa_put_profile(ent->rename);
 		aa_put_profile(ent->old);
 		aa_put_profile(ent->new);
+		kfree(ent->ns_name);
 		kzfree(ent);
 	}
 }
@@ -736,7 +903,6 @@ struct aa_load_ent *aa_load_ent_alloc(vo
 /**
  * aa_unpack - unpack packed binary profile(s) data loaded from user space
  * @udata: user data copied to kmem  (NOT NULL)
- * @size: the size of the user data
  * @lh: list to place unpacked profiles in a aa_repl_ws
  * @ns: Returns namespace profile is in if specified else NULL (NOT NULL)
  *
@@ -746,26 +912,26 @@ struct aa_load_ent *aa_load_ent_alloc(vo
  *
  * Returns: profile(s) on @lh else error pointer if fails to unpack
  */
-int aa_unpack(void *udata, size_t size, struct list_head *lh, const char **ns)
+int aa_unpack(struct aa_loaddata *udata, struct list_head *lh, const char **ns)
 {
 	struct aa_load_ent *tmp, *ent;
 	struct aa_profile *profile = NULL;
 	int error;
 	struct aa_ext e = {
-		.start = udata,
-		.end = udata + size,
-		.pos = udata,
+		.start = udata->data,
+		.end = udata->data + udata->size,
+		.pos = udata->data,
 	};
 
 	*ns = NULL;
 	while (e.pos < e.end) {
+		char *ns_name = NULL;
 		void *start;
 		error = verify_header(&e, e.pos == e.start, ns);
 		if (error)
 			goto fail;
-
 		start = e.pos;
-		profile = unpack_profile(&e);
+		profile = unpack_profile(&e, &ns_name);
 		if (IS_ERR(profile)) {
 			error = PTR_ERR(profile);
 			goto fail;
@@ -775,8 +941,9 @@ int aa_unpack(void *udata, size_t size,
 		if (error)
 			goto fail_profile;
 
-		error = aa_calc_profile_hash(profile, e.version, start,
-					     e.pos - start);
+		if (aa_g_hash_policy)
+			error = aa_calc_profile_hash(profile, e.version, start,
+						     e.pos - start);
 		if (error)
 			goto fail_profile;
 
@@ -787,9 +954,18 @@ int aa_unpack(void *udata, size_t size,
 		}
 
 		ent->new = profile;
+		ent->ns_name = ns_name;
 		list_add_tail(&ent->list, lh);
 	}
-
+	udata->abi = e.version & K_ABI_MASK;
+	if (aa_g_hash_policy) {
+		udata->hash = aa_calc_hash(udata->data, udata->size);
+		if (IS_ERR(udata->hash)) {
+			error = PTR_ERR(udata->hash);
+			udata->hash = NULL;
+			goto fail;
+		}
+	}
 	return 0;
 
 fail_profile:
--- zfcpdump-kernel-4.4.orig/security/apparmor/procattr.c
+++ zfcpdump-kernel-4.4/security/apparmor/procattr.c
@@ -33,50 +33,41 @@
  *
  * Returns: size of string placed in @string else error code on failure
  */
-int aa_getprocattr(struct aa_profile *profile, char **string)
+int aa_getprocattr(struct aa_label *label, char **string)
 {
-	char *str;
-	int len = 0, mode_len = 0, ns_len = 0, name_len;
-	const char *mode_str = aa_profile_mode_names[profile->mode];
-	const char *ns_name = NULL;
-	struct aa_namespace *ns = profile->ns;
-	struct aa_namespace *current_ns = __aa_current_profile()->ns;
-	char *s;
+	struct aa_ns *ns = labels_ns(label);
+	struct aa_ns *current_ns = aa_get_current_ns();
+	int len;
 
-	if (!aa_ns_visible(current_ns, ns))
+	if (!aa_ns_visible(current_ns, ns, true)) {
+		aa_put_ns(current_ns);
 		return -EACCES;
+	}
 
-	ns_name = aa_ns_name(current_ns, ns);
-	ns_len = strlen(ns_name);
-
-	/* if the visible ns_name is > 0 increase size for : :// seperator */
-	if (ns_len)
-		ns_len += 4;
-
-	/* unconfined profiles don't have a mode string appended */
-	if (!unconfined(profile))
-		mode_len = strlen(mode_str) + 3;	/* + 3 for _() */
-
-	name_len = strlen(profile->base.hname);
-	len = mode_len + ns_len + name_len + 1;	    /* + 1 for \n */
-	s = str = kmalloc(len + 1, GFP_KERNEL);	    /* + 1 \0 */
-	if (!str)
+	len = aa_label_snxprint(NULL, 0, current_ns, label,
+				FLAG_SHOW_MODE | FLAG_VIEW_SUBNS |
+				FLAG_HIDDEN_UNCONFINED);
+	AA_BUG(len < 0);
+
+	*string = kmalloc(len + 2, GFP_KERNEL);
+	if (!*string) {
+		aa_put_ns(current_ns);
 		return -ENOMEM;
+	}
 
-	if (ns_len) {
-		/* skip over prefix current_ns->base.hname and separating // */
-		sprintf(s, ":%s://", ns_name);
-		s += ns_len;
+	len = aa_label_snxprint(*string, len + 2, current_ns, label,
+				FLAG_SHOW_MODE | FLAG_VIEW_SUBNS |
+				FLAG_HIDDEN_UNCONFINED);
+	if (len < 0) {
+		aa_put_ns(current_ns);
+		return len;
 	}
-	if (unconfined(profile))
-		/* mode string not being appended */
-		sprintf(s, "%s\n", profile->base.hname);
-	else
-		sprintf(s, "%s (%s)\n", profile->base.hname, mode_str);
-	*string = str;
 
-	/* NOTE: len does not include \0 of string, not saved as part of file */
-	return len;
+	(*string)[len] = '\n';
+	(*string)[len + 1] = 0;
+
+	aa_put_ns(current_ns);
+	return len + 1;
 }
 
 /**
@@ -87,13 +78,13 @@ int aa_getprocattr(struct aa_profile *pr
  *
  * Returns: start position of name after token else NULL on failure
  */
-static char *split_token_from_name(int op, char *args, u64 * token)
+static char *split_token_from_name(const char *op, char *args, u64 * token)
 {
 	char *name;
 
 	*token = simple_strtoull(args, &name, 16);
 	if ((name == args) || *name != '^') {
-		AA_ERROR("%s: Invalid input '%s'", op_table[op], args);
+		AA_ERROR("%s: Invalid input '%s'", op, args);
 		return ERR_PTR(-EINVAL);
 	}
 
@@ -138,28 +129,13 @@ int aa_setprocattr_changehat(char *args,
 		for (count = 0; (hat < end) && count < 16; ++count) {
 			char *next = hat + strlen(hat) + 1;
 			hats[count] = hat;
+			AA_DEBUG("%s: (pid %d) Magic 0x%llx count %d hat '%s'\n"
+				 , __func__, current->pid, token, count, hat);
 			hat = next;
 		}
-	}
-
-	AA_DEBUG("%s: Magic 0x%llx Hat '%s'\n",
-		 __func__, token, hat ? hat : NULL);
+	} else
+		AA_DEBUG("%s: (pid %d) Magic 0x%llx count %d Hat '%s'\n",
+			 __func__, current->pid, token, count, "<NULL>");
 
 	return aa_change_hat(hats, count, token, test);
 }
-
-/**
- * aa_setprocattr_changeprofile - handle procattr interface to changeprofile
- * @fqname: args received from writting to /proc/<pid>/attr/current (NOT NULL)
- * @onexec: true if change_profile should be delayed until exec
- * @test: true if this is a test of change_profile permissions
- *
- * Returns: %0 or error code if change_profile fails
- */
-int aa_setprocattr_changeprofile(char *fqname, bool onexec, int test)
-{
-	char *name, *ns_name;
-
-	name = aa_split_fqname(fqname, &ns_name);
-	return aa_change_profile(ns_name, name, onexec, test);
-}
--- zfcpdump-kernel-4.4.orig/security/apparmor/resource.c
+++ zfcpdump-kernel-4.4/security/apparmor/resource.c
@@ -35,7 +35,7 @@ static void audit_cb(struct audit_buffer
 	struct common_audit_data *sa = va;
 
 	audit_log_format(ab, " rlimit=%s value=%lu",
-			 rlim_names[sa->aad->rlim.rlim], sa->aad->rlim.max);
+			 rlim_names[aad(sa)->rlim.rlim], aad(sa)->rlim.max);
 }
 
 /**
@@ -50,17 +50,11 @@ static void audit_cb(struct audit_buffer
 static int audit_resource(struct aa_profile *profile, unsigned int resource,
 			  unsigned long value, int error)
 {
-	struct common_audit_data sa;
-	struct apparmor_audit_data aad = {0,};
-
-	sa.type = LSM_AUDIT_DATA_NONE;
-	sa.aad = &aad;
-	aad.op = OP_SETRLIMIT,
-	aad.rlim.rlim = resource;
-	aad.rlim.max = value;
-	aad.error = error;
-	return aa_audit(AUDIT_APPARMOR_AUTO, profile, GFP_KERNEL, &sa,
-			audit_cb);
+	DEFINE_AUDIT_DATA(sa, LSM_AUDIT_DATA_NONE, OP_SETRLIMIT);
+	aad(&sa)->rlim.rlim = resource;
+	aad(&sa)->rlim.max = value;
+	aad(&sa)->error = error;
+	return aa_audit(AUDIT_APPARMOR_AUTO, profile, &sa, audit_cb);
 }
 
 /**
@@ -77,9 +71,20 @@ int aa_map_resource(int resource)
 	return rlim_map[resource];
 }
 
+static int profile_setrlimit(struct aa_profile *profile, unsigned int resource,
+			     struct rlimit *new_rlim)
+{
+	int e = 0;
+
+	if (profile->rlimits.mask & (1 << resource) && new_rlim->rlim_max >
+	    profile->rlimits.limits[resource].rlim_max)
+		e = -EACCES;
+	return audit_resource(profile, resource, new_rlim->rlim_max, e);
+}
+
 /**
  * aa_task_setrlimit - test permission to set an rlimit
- * @profile - profile confining the task  (NOT NULL)
+ * @label - label confining the task  (NOT NULL)
  * @task - task the resource is being set on
  * @resource - the resource being set
  * @new_rlim - the new resource limit  (NOT NULL)
@@ -88,67 +93,84 @@ int aa_map_resource(int resource)
  *
  * Returns: 0 or error code if setting resource failed
  */
-int aa_task_setrlimit(struct aa_profile *profile, struct task_struct *task,
+int aa_task_setrlimit(struct aa_label *label, struct task_struct *task,
 		      unsigned int resource, struct rlimit *new_rlim)
 {
-	struct aa_profile *task_profile;
+	struct aa_profile *profile;
+	struct aa_label *peer;
 	int error = 0;
 
 	rcu_read_lock();
-	task_profile = aa_get_profile(aa_cred_profile(__task_cred(task)));
+	peer = aa_get_newest_cred_label(__task_cred(task));
 	rcu_read_unlock();
 
 	/* TODO: extend resource control to handle other (non current)
 	 * profiles.  AppArmor rules currently have the implicit assumption
 	 * that the task is setting the resource of a task confined with
-	 * the same profile.
+	 * the same profile or that the task setting the resource of another
+	 * task has CAP_SYS_RESOURCE.
 	 */
-	if (profile != task_profile ||
-	    (profile->rlimits.mask & (1 << resource) &&
-	     new_rlim->rlim_max > profile->rlimits.limits[resource].rlim_max))
-		error = -EACCES;
 
-	aa_put_profile(task_profile);
+	if (label != peer &&
+	    !aa_capable(label, CAP_SYS_RESOURCE, SECURITY_CAP_NOAUDIT))
+		error = fn_for_each(label, profile,
+				audit_resource(profile, resource,
+					       new_rlim->rlim_max, EACCES));
+	else
+		error = fn_for_each_confined(label, profile,
+				profile_setrlimit(profile, resource, new_rlim));
+	aa_put_label(peer);
 
-	return audit_resource(profile, resource, new_rlim->rlim_max, error);
+	return error;
 }
 
 /**
  * __aa_transition_rlimits - apply new profile rlimits
- * @old: old profile on task  (NOT NULL)
- * @new: new profile with rlimits to apply  (NOT NULL)
+ * @old_l: old label on task  (NOT NULL)
+ * @new_l: new label with rlimits to apply  (NOT NULL)
  */
-void __aa_transition_rlimits(struct aa_profile *old, struct aa_profile *new)
+void __aa_transition_rlimits(struct aa_label *old_l, struct aa_label *new_l)
 {
 	unsigned int mask = 0;
 	struct rlimit *rlim, *initrlim;
-	int i;
+	struct aa_profile *old, *new;
+	struct label_it i;
+
+	old = labels_profile(old_l);
+	new = labels_profile(new_l);
 
-	/* for any rlimits the profile controlled reset the soft limit
-	 * to the less of the tasks hard limit and the init tasks soft limit
+	/* for any rlimits the profile controlled, reset the soft limit
+	 * to the lesser of the tasks hard limit and the init tasks soft limit
 	 */
-	if (old->rlimits.mask) {
-		for (i = 0, mask = 1; i < RLIM_NLIMITS; i++, mask <<= 1) {
-			if (old->rlimits.mask & mask) {
-				rlim = current->signal->rlim + i;
-				initrlim = init_task.signal->rlim + i;
-				rlim->rlim_cur = min(rlim->rlim_max,
-						     initrlim->rlim_cur);
+	label_for_each_confined(i, old_l, old) {
+		if (old->rlimits.mask) {
+			int j;
+			for (j = 0, mask = 1; j < RLIM_NLIMITS; j++,
+				     mask <<= 1) {
+				if (old->rlimits.mask & mask) {
+					rlim = current->signal->rlim + j;
+					initrlim = init_task.signal->rlim + j;
+					rlim->rlim_cur = min(rlim->rlim_max,
+							    initrlim->rlim_cur);
+				}
 			}
 		}
 	}
 
 	/* set any new hard limits as dictated by the new profile */
-	if (!new->rlimits.mask)
-		return;
-	for (i = 0, mask = 1; i < RLIM_NLIMITS; i++, mask <<= 1) {
-		if (!(new->rlimits.mask & mask))
+	label_for_each_confined(i, new_l, new) {
+		int j;
+		if (!new->rlimits.mask)
 			continue;
-
-		rlim = current->signal->rlim + i;
-		rlim->rlim_max = min(rlim->rlim_max,
-				     new->rlimits.limits[i].rlim_max);
-		/* soft limit should not exceed hard limit */
-		rlim->rlim_cur = min(rlim->rlim_cur, rlim->rlim_max);
+		for (j = 0, mask = 1; j < RLIM_NLIMITS; j++, mask <<= 1) {
+			if (!(new->rlimits.mask & mask))
+				continue;
+
+			rlim = current->signal->rlim + j;
+			rlim->rlim_max = min(rlim->rlim_max,
+					     new->rlimits.limits[j].rlim_max);
+			/* soft limit should not exceed hard limit */
+			rlim->rlim_cur = min(rlim->rlim_cur, rlim->rlim_max);
+		}
 	}
 }
--- zfcpdump-kernel-4.4.orig/security/commoncap.c
+++ zfcpdump-kernel-4.4/security/commoncap.c
@@ -137,12 +137,17 @@ int cap_ptrace_access_check(struct task_
 {
 	int ret = 0;
 	const struct cred *cred, *child_cred;
+	const kernel_cap_t *caller_caps;
 
 	rcu_read_lock();
 	cred = current_cred();
 	child_cred = __task_cred(child);
+	if (mode & PTRACE_MODE_FSCREDS)
+		caller_caps = &cred->cap_effective;
+	else
+		caller_caps = &cred->cap_permitted;
 	if (cred->user_ns == child_cred->user_ns &&
-	    cap_issubset(child_cred->cap_permitted, cred->cap_permitted))
+	    cap_issubset(child_cred->cap_permitted, *caller_caps))
 		goto out;
 	if (ns_capable(child_cred->user_ns, CAP_SYS_PTRACE))
 		goto out;
@@ -448,7 +453,9 @@ static int get_file_caps(struct linux_bi
 	if (!file_caps_enabled)
 		return 0;
 
-	if (bprm->file->f_path.mnt->mnt_flags & MNT_NOSUID)
+	if (path_nosuid(&bprm->file->f_path))
+		return 0;
+	if (!current_in_userns(bprm->file->f_path.mnt->mnt_sb->s_user_ns))
 		return 0;
 
 	rc = get_vfs_caps_from_disk(bprm->file->f_path.dentry, &vcaps);
@@ -651,15 +658,17 @@ int cap_bprm_secureexec(struct linux_bin
 int cap_inode_setxattr(struct dentry *dentry, const char *name,
 		       const void *value, size_t size, int flags)
 {
+	struct user_namespace *user_ns = dentry->d_sb->s_user_ns;
+
 	if (!strcmp(name, XATTR_NAME_CAPS)) {
-		if (!capable(CAP_SETFCAP))
+		if (!ns_capable(user_ns, CAP_SETFCAP))
 			return -EPERM;
 		return 0;
 	}
 
 	if (!strncmp(name, XATTR_SECURITY_PREFIX,
 		     sizeof(XATTR_SECURITY_PREFIX) - 1) &&
-	    !capable(CAP_SYS_ADMIN))
+	    !ns_capable(user_ns, CAP_SYS_ADMIN))
 		return -EPERM;
 	return 0;
 }
@@ -677,15 +686,17 @@ int cap_inode_setxattr(struct dentry *de
  */
 int cap_inode_removexattr(struct dentry *dentry, const char *name)
 {
+	struct user_namespace *user_ns = dentry->d_sb->s_user_ns;
+
 	if (!strcmp(name, XATTR_NAME_CAPS)) {
-		if (!capable(CAP_SETFCAP))
+		if (!ns_capable(user_ns, CAP_SETFCAP))
 			return -EPERM;
 		return 0;
 	}
 
 	if (!strncmp(name, XATTR_SECURITY_PREFIX,
 		     sizeof(XATTR_SECURITY_PREFIX) - 1) &&
-	    !capable(CAP_SYS_ADMIN))
+	    !ns_capable(user_ns, CAP_SYS_ADMIN))
 		return -EPERM;
 	return 0;
 }
@@ -1053,12 +1064,14 @@ int cap_mmap_addr(unsigned long addr)
 	}
 	return ret;
 }
+EXPORT_SYMBOL(cap_mmap_addr);
 
 int cap_mmap_file(struct file *file, unsigned long reqprot,
 		  unsigned long prot, unsigned long flags)
 {
 	return 0;
 }
+EXPORT_SYMBOL(cap_mmap_file);
 
 #ifdef CONFIG_SECURITY
 
--- zfcpdump-kernel-4.4.orig/security/device_cgroup.c
+++ zfcpdump-kernel-4.4/security/device_cgroup.c
@@ -7,6 +7,7 @@
 #include <linux/device_cgroup.h>
 #include <linux/cgroup.h>
 #include <linux/ctype.h>
+#include <linux/export.h>
 #include <linux/list.h>
 #include <linux/uaccess.h>
 #include <linux/seq_file.h>
@@ -849,6 +850,7 @@ int __devcgroup_inode_permission(struct
 	return __devcgroup_check_permission(type, imajor(inode), iminor(inode),
 			access);
 }
+EXPORT_SYMBOL(__devcgroup_inode_permission);
 
 int devcgroup_inode_mknod(int mode, dev_t dev)
 {
--- zfcpdump-kernel-4.4.orig/security/inode.c
+++ zfcpdump-kernel-4.4/security/inode.c
@@ -46,8 +46,42 @@ static struct file_system_type fs_type =
 	.kill_sb =	kill_litter_super,
 };
 
+int securityfs_pin_fs(void)
+{
+	return simple_pin_fs(&fs_type, &mount, &mount_count);
+}
+
+int __securityfs_setup_d_inode(struct inode *dir, struct dentry *dentry,
+			       umode_t mode, void *data,
+			       const struct file_operations *fops,
+			       const struct inode_operations *iops)
+{
+	bool is_dir = S_ISDIR(mode);
+	struct inode *inode = new_inode(dir->i_sb);
+	if (!inode)
+		return -ENOMEM;
+
+	inode->i_ino = get_next_ino();
+	inode->i_mode = mode;
+	inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
+	inode->i_private = data;
+	if (is_dir) {
+		inode->i_op = iops ? iops : &simple_dir_inode_operations;
+		inode->i_fop = &simple_dir_operations;
+		inc_nlink(inode);
+		inc_nlink(dir);
+	} else {
+		inode->i_fop = fops;
+	}
+	d_instantiate(dentry, inode);
+	dget(dentry);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(__securityfs_setup_d_inode);
+
 /**
- * securityfs_create_file - create a file in the securityfs filesystem
+ * securityfs_create_dentry - create a file/dir in the securityfs filesystem
  *
  * @name: a pointer to a string containing the name of the file to create.
  * @mode: the permission that the file should have
@@ -59,8 +93,10 @@ static struct file_system_type fs_type =
  *        the open() call.
  * @fops: a pointer to a struct file_operations that should be used for
  *        this file.
+ * @iops: a point to a struct of inode_operations that should be used for
+ *        this file/dir
  *
- * This is the basic "create a file" function for securityfs.  It allows for a
+ * This is the basic "create a xxx" function for securityfs.  It allows for a
  * wide range of flexibility in creating a file, or a directory (if you
  * want to create a directory, the securityfs_create_dir() function is
  * recommended to be used instead).
@@ -74,13 +110,14 @@ static struct file_system_type fs_type =
  * If securityfs is not enabled in the kernel, the value %-ENODEV is
  * returned.
  */
-struct dentry *securityfs_create_file(const char *name, umode_t mode,
-				   struct dentry *parent, void *data,
-				   const struct file_operations *fops)
+struct dentry *securityfs_create_dentry(const char *name, umode_t mode,
+					struct dentry *parent, void *data,
+					const struct file_operations *fops,
+					const struct inode_operations *iops)
 {
 	struct dentry *dentry;
 	int is_dir = S_ISDIR(mode);
-	struct inode *dir, *inode;
+	struct inode *dir;
 	int error;
 
 	if (!is_dir) {
@@ -109,26 +146,9 @@ struct dentry *securityfs_create_file(co
 		goto out1;
 	}
 
-	inode = new_inode(dir->i_sb);
-	if (!inode) {
-		error = -ENOMEM;
+	error = __securityfs_setup_d_inode(dir, dentry, mode, data, fops, iops);
+	if (error)
 		goto out1;
-	}
-
-	inode->i_ino = get_next_ino();
-	inode->i_mode = mode;
-	inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
-	inode->i_private = data;
-	if (is_dir) {
-		inode->i_op = &simple_dir_inode_operations;
-		inode->i_fop = &simple_dir_operations;
-		inc_nlink(inode);
-		inc_nlink(dir);
-	} else {
-		inode->i_fop = fops;
-	}
-	d_instantiate(dentry, inode);
-	dget(dentry);
 	mutex_unlock(&dir->i_mutex);
 	return dentry;
 
@@ -140,6 +160,39 @@ out:
 	simple_release_fs(&mount, &mount_count);
 	return dentry;
 }
+EXPORT_SYMBOL_GPL(securityfs_create_dentry);
+
+/**
+ * securityfs_create_file - create a file in the securityfs filesystem
+ *
+ * @name: a pointer to a string containing the name of the file to create.
+ * @mode: the permission that the file should have
+ * @parent: a pointer to the parent dentry for this file.  This should be a
+ *          directory dentry if set.  If this parameter is %NULL, then the
+ *          file will be created in the root of the securityfs filesystem.
+ * @data: a pointer to something that the caller will want to get to later
+ *        on.  The inode.i_private pointer will point to this value on
+ *        the open() call.
+ * @fops: a pointer to a struct file_operations that should be used for
+ *        this file.
+ *
+ * This function creates a file in securityfs with the given @name.
+ *
+ * This function returns a pointer to a dentry if it succeeds.  This
+ * pointer must be passed to the securityfs_remove() function when the file is
+ * to be removed (no automatic cleanup happens if your module is unloaded,
+ * you are responsible here).  If an error occurs, the function will return
+ * the error value (via ERR_PTR).
+ *
+ * If securityfs is not enabled in the kernel, the value %-ENODEV is
+ * returned.
+ */
+struct dentry *securityfs_create_file(const char *name, umode_t mode,
+                                     struct dentry *parent, void *data,
+                                     const struct file_operations *fops)
+{
+	return securityfs_create_dentry(name, mode, parent, data, fops, NULL);
+}
 EXPORT_SYMBOL_GPL(securityfs_create_file);
 
 /**
--- zfcpdump-kernel-4.4.orig/security/integrity/digsig_asymmetric.c
+++ zfcpdump-kernel-4.4/security/integrity/digsig_asymmetric.c
@@ -17,6 +17,7 @@
 #include <linux/key-type.h>
 #include <crypto/public_key.h>
 #include <keys/asymmetric-type.h>
+#include <keys/system_keyring.h>
 
 #include "integrity.h"
 
@@ -32,9 +33,22 @@ static struct key *request_asymmetric_ke
 
 	pr_debug("key search: \"%s\"\n", name);
 
+	key = get_ima_blacklist_keyring();
+	if (key) {
+		key_ref_t kref;
+
+		kref = keyring_search(make_key_ref(key, 1),
+				     &key_type_asymmetric, name);
+		if (!IS_ERR(kref)) {
+			pr_err("Key '%s' is in ima_blacklist_keyring\n", name);
+			return ERR_PTR(-EKEYREJECTED);
+		}
+	}
+
 	if (keyring) {
 		/* search in specific keyring */
 		key_ref_t kref;
+
 		kref = keyring_search(make_key_ref(keyring, 1),
 				      &key_type_asymmetric, name);
 		if (IS_ERR(kref))
--- zfcpdump-kernel-4.4.orig/security/integrity/evm/evm_crypto.c
+++ zfcpdump-kernel-4.4/security/integrity/evm/evm_crypto.c
@@ -108,8 +108,8 @@ static void hmac_add_misc(struct shash_d
 	memset(&hmac_misc, 0, sizeof(hmac_misc));
 	hmac_misc.ino = inode->i_ino;
 	hmac_misc.generation = inode->i_generation;
-	hmac_misc.uid = from_kuid(&init_user_ns, inode->i_uid);
-	hmac_misc.gid = from_kgid(&init_user_ns, inode->i_gid);
+	hmac_misc.uid = from_kuid(inode->i_sb->s_user_ns, inode->i_uid);
+	hmac_misc.gid = from_kgid(inode->i_sb->s_user_ns, inode->i_gid);
 	hmac_misc.mode = inode->i_mode;
 	crypto_shash_update(desc, (const u8 *)&hmac_misc, sizeof(hmac_misc));
 	if (evm_hmac_attrs & EVM_ATTR_FSUUID)
--- zfcpdump-kernel-4.4.orig/security/integrity/evm/evm_main.c
+++ zfcpdump-kernel-4.4/security/integrity/evm/evm_main.c
@@ -23,6 +23,7 @@
 #include <linux/integrity.h>
 #include <linux/evm.h>
 #include <crypto/hash.h>
+#include <crypto/algapi.h>
 #include "evm.h"
 
 int evm_initialized;
@@ -148,7 +149,7 @@ static enum integrity_status evm_verify_
 				   xattr_value_len, calc.digest);
 		if (rc)
 			break;
-		rc = memcmp(xattr_data->digest, calc.digest,
+		rc = crypto_memneq(xattr_data->digest, calc.digest,
 			    sizeof(calc.digest));
 		if (rc)
 			rc = -EINVAL;
@@ -278,7 +279,7 @@ static int evm_protect_xattr(struct dent
 	enum integrity_status evm_status;
 
 	if (strcmp(xattr_name, XATTR_NAME_EVM) == 0) {
-		if (!capable(CAP_SYS_ADMIN))
+		if (!ns_capable(dentry->d_sb->s_user_ns, CAP_SYS_ADMIN))
 			return -EPERM;
 	} else if (!evm_protected_xattr(xattr_name)) {
 		if (!posix_xattr_acl(xattr_name))
--- zfcpdump-kernel-4.4.orig/security/integrity/ima/Kconfig
+++ zfcpdump-kernel-4.4/security/integrity/ima/Kconfig
@@ -131,6 +131,26 @@ config IMA_TRUSTED_KEYRING
 	   This option requires that all keys added to the .ima
 	   keyring be signed by a key on the system trusted keyring.
 
+	   This option is deprecated in favor of INTEGRITY_TRUSTED_KEYRING
+
+config IMA_MOK_KEYRING
+	bool "Create IMA machine owner keys (MOK) and blacklist keyrings"
+	depends on SYSTEM_TRUSTED_KEYRING
+	depends on IMA_TRUSTED_KEYRING
+	default n
+	help
+	   This option creates IMA MOK and blacklist keyrings.  IMA MOK is an
+	   intermediate keyring that sits between .system and .ima keyrings,
+	   effectively forming a simple CA hierarchy.  To successfully import a
+	   key into .ima_mok it must be signed by a key which CA is in .system
+	   keyring.  On turn any key that needs to go in .ima keyring must be
+	   signed by CA in either .system or .ima_mok keyrings. IMA MOK is empty
+	   at kernel boot.
+
+	   IMA blacklist keyring contains all revoked IMA keys.  It is consulted
+	   before any other keyring.  If the search is successful the requested
+	   operation is rejected and error is returned to the caller.
+
 config IMA_LOAD_X509
 	bool "Load X509 certificate onto the '.ima' trusted keyring"
 	depends on IMA_TRUSTED_KEYRING
--- zfcpdump-kernel-4.4.orig/security/integrity/ima/Makefile
+++ zfcpdump-kernel-4.4/security/integrity/ima/Makefile
@@ -8,3 +8,4 @@ obj-$(CONFIG_IMA) += ima.o
 ima-y := ima_fs.o ima_queue.o ima_init.o ima_main.o ima_crypto.o ima_api.o \
 	 ima_policy.o ima_template.o ima_template_lib.o
 ima-$(CONFIG_IMA_APPRAISE) += ima_appraise.o
+obj-$(CONFIG_IMA_MOK_KEYRING) += ima_mok.o
--- zfcpdump-kernel-4.4.orig/security/integrity/ima/ima_appraise.c
+++ zfcpdump-kernel-4.4/security/integrity/ima/ima_appraise.c
@@ -345,7 +345,7 @@ static int ima_protect_xattr(struct dent
 			     const void *xattr_value, size_t xattr_value_len)
 {
 	if (strcmp(xattr_name, XATTR_NAME_IMA) == 0) {
-		if (!capable(CAP_SYS_ADMIN))
+		if (!ns_capable(dentry->d_sb->s_user_ns, CAP_SYS_ADMIN))
 			return -EPERM;
 		return 1;
 	}
--- /dev/null
+++ zfcpdump-kernel-4.4/security/integrity/ima/ima_mok.c
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2015 Juniper Networks, Inc.
+ *
+ * Author:
+ * Petko Manolov <petko.manolov@konsulko.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2 of the
+ * License.
+ *
+ */
+
+#include <linux/export.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/cred.h>
+#include <linux/err.h>
+#include <linux/module.h>
+#include <keys/asymmetric-type.h>
+
+
+struct key *ima_mok_keyring;
+struct key *ima_blacklist_keyring;
+
+/*
+ * Allocate the IMA MOK and blacklist keyrings
+ */
+__init int ima_mok_init(void)
+{
+	pr_notice("Allocating IMA MOK and blacklist keyrings.\n");
+
+	ima_mok_keyring = keyring_alloc(".ima_mok",
+			      KUIDT_INIT(0), KGIDT_INIT(0), current_cred(),
+			      (KEY_POS_ALL & ~KEY_POS_SETATTR) |
+			      KEY_USR_VIEW | KEY_USR_READ |
+			      KEY_USR_WRITE | KEY_USR_SEARCH,
+			      KEY_ALLOC_NOT_IN_QUOTA, NULL);
+
+	ima_blacklist_keyring = keyring_alloc(".ima_blacklist",
+				KUIDT_INIT(0), KGIDT_INIT(0), current_cred(),
+				(KEY_POS_ALL & ~KEY_POS_SETATTR) |
+				KEY_USR_VIEW | KEY_USR_READ |
+				KEY_USR_WRITE | KEY_USR_SEARCH,
+				KEY_ALLOC_NOT_IN_QUOTA, NULL);
+
+	if (IS_ERR(ima_mok_keyring) || IS_ERR(ima_blacklist_keyring))
+		panic("Can't allocate IMA MOK or blacklist keyrings.");
+	set_bit(KEY_FLAG_TRUSTED_ONLY, &ima_mok_keyring->flags);
+	set_bit(KEY_FLAG_TRUSTED_ONLY, &ima_blacklist_keyring->flags);
+	return 0;
+}
+
+module_init(ima_mok_init);
--- zfcpdump-kernel-4.4.orig/security/keys/Kconfig
+++ zfcpdump-kernel-4.4/security/keys/Kconfig
@@ -54,6 +54,7 @@ config TRUSTED_KEYS
 	select CRYPTO
 	select CRYPTO_HMAC
 	select CRYPTO_SHA1
+	select CRYPTO_HASH_INFO
 	help
 	  This option provides support for creating, sealing, and unsealing
 	  keys in the kernel. Trusted keys are random number symmetric keys,
--- zfcpdump-kernel-4.4.orig/security/keys/key.c
+++ zfcpdump-kernel-4.4/security/keys/key.c
@@ -296,6 +296,8 @@ struct key *key_alloc(struct key_type *t
 		key->flags |= 1 << KEY_FLAG_IN_QUOTA;
 	if (flags & KEY_ALLOC_TRUSTED)
 		key->flags |= 1 << KEY_FLAG_TRUSTED;
+	if (flags & KEY_ALLOC_BUILT_IN)
+		key->flags |= 1 << KEY_FLAG_BUILTIN;
 
 #ifdef KEY_DEBUGGING
 	key->magic = KEY_DEBUG_MAGIC;
@@ -578,7 +580,7 @@ int key_reject_and_link(struct key *key,
 
 	mutex_unlock(&key_construction_mutex);
 
-	if (keyring)
+	if (keyring && link_ret == 0)
 		__key_link_end(keyring, &key->index_key, edit);
 
 	/* wake up anyone waiting for a key to be constructed */
--- zfcpdump-kernel-4.4.orig/security/keys/proc.c
+++ zfcpdump-kernel-4.4/security/keys/proc.c
@@ -181,7 +181,7 @@ static int proc_keys_show(struct seq_fil
 	struct timespec now;
 	unsigned long timo;
 	key_ref_t key_ref, skey_ref;
-	char xbuf[12];
+	char xbuf[16];
 	int rc;
 
 	struct keyring_search_context ctx = {
--- zfcpdump-kernel-4.4.orig/security/keys/process_keys.c
+++ zfcpdump-kernel-4.4/security/keys/process_keys.c
@@ -794,6 +794,7 @@ long join_session_keyring(const char *na
 		ret = PTR_ERR(keyring);
 		goto error2;
 	} else if (keyring == new->session_keyring) {
+		key_put(keyring);
 		ret = 0;
 		goto error2;
 	}
--- zfcpdump-kernel-4.4.orig/security/keys/trusted.c
+++ zfcpdump-kernel-4.4/security/keys/trusted.c
@@ -11,6 +11,7 @@
  * See Documentation/security/keys-trusted-encrypted.txt
  */
 
+#include <crypto/hash_info.h>
 #include <linux/uaccess.h>
 #include <linux/module.h>
 #include <linux/init.h>
@@ -710,7 +711,10 @@ enum {
 	Opt_err = -1,
 	Opt_new, Opt_load, Opt_update,
 	Opt_keyhandle, Opt_keyauth, Opt_blobauth,
-	Opt_pcrinfo, Opt_pcrlock, Opt_migratable
+	Opt_pcrinfo, Opt_pcrlock, Opt_migratable,
+	Opt_hash,
+	Opt_policydigest,
+	Opt_policyhandle,
 };
 
 static const match_table_t key_tokens = {
@@ -723,6 +727,9 @@ static const match_table_t key_tokens =
 	{Opt_pcrinfo, "pcrinfo=%s"},
 	{Opt_pcrlock, "pcrlock=%s"},
 	{Opt_migratable, "migratable=%s"},
+	{Opt_hash, "hash=%s"},
+	{Opt_policydigest, "policydigest=%s"},
+	{Opt_policyhandle, "policyhandle=%s"},
 	{Opt_err, NULL}
 };
 
@@ -736,11 +743,23 @@ static int getoptions(char *c, struct tr
 	int res;
 	unsigned long handle;
 	unsigned long lock;
+	unsigned long token_mask = 0;
+	unsigned int digest_len;
+	int i;
+	int tpm2;
+
+	tpm2 = tpm_is_tpm2(TPM_ANY_NUM);
+	if (tpm2 < 0)
+		return tpm2;
+
+	opt->hash = tpm2 ? HASH_ALGO_SHA256 : HASH_ALGO_SHA1;
 
 	while ((p = strsep(&c, " \t"))) {
 		if (*p == '\0' || *p == ' ' || *p == '\t')
 			continue;
 		token = match_token(p, key_tokens, args);
+		if (test_and_set_bit(token, &token_mask))
+			return -EINVAL;
 
 		switch (token) {
 		case Opt_pcrinfo:
@@ -787,6 +806,40 @@ static int getoptions(char *c, struct tr
 				return -EINVAL;
 			opt->pcrlock = lock;
 			break;
+		case Opt_hash:
+			if (test_bit(Opt_policydigest, &token_mask))
+				return -EINVAL;
+			for (i = 0; i < HASH_ALGO__LAST; i++) {
+				if (!strcmp(args[0].from, hash_algo_name[i])) {
+					opt->hash = i;
+					break;
+				}
+			}
+			if (i == HASH_ALGO__LAST)
+				return -EINVAL;
+			if  (!tpm2 && i != HASH_ALGO_SHA1) {
+				pr_info("trusted_key: TPM 1.x only supports SHA-1.\n");
+				return -EINVAL;
+			}
+			break;
+		case Opt_policydigest:
+			digest_len = hash_digest_size[opt->hash];
+			if (!tpm2 || strlen(args[0].from) != (2 * digest_len))
+				return -EINVAL;
+			res = hex2bin(opt->policydigest, args[0].from,
+				      digest_len);
+			if (res < 0)
+				return -EINVAL;
+			opt->policydigest_len = digest_len;
+			break;
+		case Opt_policyhandle:
+			if (!tpm2)
+				return -EINVAL;
+			res = kstrtoul(args[0].from, 16, &handle);
+			if (res < 0)
+				return -EINVAL;
+			opt->policyhandle = handle;
+			break;
 		default:
 			return -EINVAL;
 		}
--- zfcpdump-kernel-4.4.orig/security/security.c
+++ zfcpdump-kernel-4.4/security/security.c
@@ -433,6 +433,7 @@ int security_path_rmdir(struct path *dir
 		return 0;
 	return call_int_hook(path_rmdir, 0, dir, dentry);
 }
+EXPORT_SYMBOL(security_path_rmdir);
 
 int security_path_unlink(struct path *dir, struct dentry *dentry)
 {
@@ -449,6 +450,7 @@ int security_path_symlink(struct path *d
 		return 0;
 	return call_int_hook(path_symlink, 0, dir, dentry, old_name);
 }
+EXPORT_SYMBOL(security_path_symlink);
 
 int security_path_link(struct dentry *old_dentry, struct path *new_dir,
 		       struct dentry *new_dentry)
@@ -457,6 +459,7 @@ int security_path_link(struct dentry *ol
 		return 0;
 	return call_int_hook(path_link, 0, old_dentry, new_dir, new_dentry);
 }
+EXPORT_SYMBOL(security_path_link);
 
 int security_path_rename(struct path *old_dir, struct dentry *old_dentry,
 			 struct path *new_dir, struct dentry *new_dentry,
@@ -484,6 +487,7 @@ int security_path_truncate(struct path *
 		return 0;
 	return call_int_hook(path_truncate, 0, path);
 }
+EXPORT_SYMBOL(security_path_truncate);
 
 int security_path_chmod(struct path *path, umode_t mode)
 {
@@ -491,6 +495,7 @@ int security_path_chmod(struct path *pat
 		return 0;
 	return call_int_hook(path_chmod, 0, path, mode);
 }
+EXPORT_SYMBOL(security_path_chmod);
 
 int security_path_chown(struct path *path, kuid_t uid, kgid_t gid)
 {
@@ -498,6 +503,7 @@ int security_path_chown(struct path *pat
 		return 0;
 	return call_int_hook(path_chown, 0, path, uid, gid);
 }
+EXPORT_SYMBOL(security_path_chown);
 
 int security_path_chroot(struct path *path)
 {
@@ -583,6 +589,7 @@ int security_inode_readlink(struct dentr
 		return 0;
 	return call_int_hook(inode_readlink, 0, dentry);
 }
+EXPORT_SYMBOL(security_inode_readlink);
 
 int security_inode_follow_link(struct dentry *dentry, struct inode *inode,
 			       bool rcu)
@@ -598,6 +605,7 @@ int security_inode_permission(struct ino
 		return 0;
 	return call_int_hook(inode_permission, 0, inode, mask);
 }
+EXPORT_SYMBOL(security_inode_permission);
 
 int security_inode_setattr(struct dentry *dentry, struct iattr *attr)
 {
@@ -736,6 +744,7 @@ int security_file_permission(struct file
 
 	return fsnotify_perm(file, mask);
 }
+EXPORT_SYMBOL(security_file_permission);
 
 int security_file_alloc(struct file *file)
 {
@@ -795,6 +804,7 @@ int security_mmap_file(struct file *file
 		return ret;
 	return ima_file_mmap(file, prot);
 }
+EXPORT_SYMBOL(security_mmap_file);
 
 int security_mmap_addr(unsigned long addr)
 {
--- zfcpdump-kernel-4.4.orig/security/selinux/hooks.c
+++ zfcpdump-kernel-4.4/security/selinux/hooks.c
@@ -756,6 +756,28 @@ static int selinux_set_mnt_opts(struct s
 			goto out;
 		}
 	}
+
+	/*
+	 * If this is a user namespace mount, no contexts are allowed
+	 * on the command line and security labels must be ignored.
+	 */
+	if (sb->s_user_ns != &init_user_ns) {
+		if (context_sid || fscontext_sid || rootcontext_sid ||
+		    defcontext_sid) {
+			rc = -EACCES;
+			goto out;
+		}
+		if (sbsec->behavior == SECURITY_FS_USE_XATTR) {
+			sbsec->behavior = SECURITY_FS_USE_MNTPOINT;
+			rc = security_transition_sid(current_sid(), current_sid(),
+						     SECCLASS_FILE, NULL,
+						     &sbsec->mntpoint_sid);
+			if (rc)
+				goto out;
+		}
+		goto out_set_opts;
+	}
+
 	/* sets the context of the superblock for the fs being mounted. */
 	if (fscontext_sid) {
 		rc = may_context_mount_sb_relabel(fscontext_sid, sbsec, cred);
@@ -824,6 +846,7 @@ static int selinux_set_mnt_opts(struct s
 		sbsec->def_sid = defcontext_sid;
 	}
 
+out_set_opts:
 	rc = sb_finish_set_opts(sb);
 out:
 	mutex_unlock(&sbsec->lock);
@@ -2171,7 +2194,7 @@ static int check_nnp_nosuid(const struct
 			    const struct task_security_struct *new_tsec)
 {
 	int nnp = (bprm->unsafe & LSM_UNSAFE_NO_NEW_PRIVS);
-	int nosuid = (bprm->file->f_path.mnt->mnt_flags & MNT_NOSUID);
+	int nosuid = path_nosuid(&bprm->file->f_path);
 	int rc;
 
 	if (!nnp && !nosuid)
--- zfcpdump-kernel-4.4.orig/security/smack/smack.h
+++ zfcpdump-kernel-4.4/security/smack/smack.h
@@ -90,9 +90,15 @@ struct superblock_smack {
 	struct smack_known	*smk_floor;
 	struct smack_known	*smk_hat;
 	struct smack_known	*smk_default;
-	int			smk_initialized;
+	int			smk_flags;
 };
 
+/*
+ * Superblock flags
+ */
+#define SMK_SB_INITIALIZED	0x01
+#define SMK_SB_UNTRUSTED	0x02
+
 struct socket_smack {
 	struct smack_known	*smk_out;	/* outbound label */
 	struct smack_known	*smk_in;	/* inbound label */
--- zfcpdump-kernel-4.4.orig/security/smack/smack_lsm.c
+++ zfcpdump-kernel-4.4/security/smack/smack_lsm.c
@@ -398,12 +398,10 @@ static int smk_copy_relabel(struct list_
  */
 static inline unsigned int smk_ptrace_mode(unsigned int mode)
 {
-	switch (mode) {
-	case PTRACE_MODE_READ:
-		return MAY_READ;
-	case PTRACE_MODE_ATTACH:
+	if (mode & PTRACE_MODE_ATTACH)
 		return MAY_READWRITE;
-	}
+	if (mode & PTRACE_MODE_READ)
+		return MAY_READ;
 
 	return 0;
 }
@@ -551,7 +549,7 @@ static int smack_sb_alloc_security(struc
 	sbsp->smk_floor = &smack_known_floor;
 	sbsp->smk_hat = &smack_known_hat;
 	/*
-	 * smk_initialized will be zero from kzalloc.
+	 * SMK_SB_INITIALIZED will be zero from kzalloc.
 	 */
 	sb->s_security = sbsp;
 
@@ -768,10 +766,10 @@ static int smack_set_mnt_opts(struct sup
 	int num_opts = opts->num_mnt_opts;
 	int transmute = 0;
 
-	if (sp->smk_initialized)
+	if (sp->smk_flags & SMK_SB_INITIALIZED)
 		return 0;
 
-	sp->smk_initialized = 1;
+	sp->smk_flags |= SMK_SB_INITIALIZED;
 
 	for (i = 0; i < num_opts; i++) {
 		switch (opts->mnt_opts_flags[i]) {
@@ -823,6 +821,17 @@ static int smack_set_mnt_opts(struct sup
 		skp = smk_of_current();
 		sp->smk_root = skp;
 		sp->smk_default = skp;
+		/*
+		 * For a handful of fs types with no user-controlled
+		 * backing store it's okay to trust security labels
+		 * in the filesystem. The rest are untrusted.
+		 */
+		if (sb->s_user_ns != &init_user_ns &&
+		    sb->s_magic != SYSFS_MAGIC && sb->s_magic != TMPFS_MAGIC &&
+		    sb->s_magic != RAMFS_MAGIC) {
+			transmute = 1;
+			sp->smk_flags |= SMK_SB_UNTRUSTED;
+		}
 	}
 
 	/*
@@ -910,6 +919,7 @@ static int smack_bprm_set_creds(struct l
 	struct inode *inode = file_inode(bprm->file);
 	struct task_smack *bsp = bprm->cred->security;
 	struct inode_smack *isp;
+	struct superblock_smack *sbsp;
 	int rc;
 
 	if (bprm->cred_prepared)
@@ -919,6 +929,11 @@ static int smack_bprm_set_creds(struct l
 	if (isp->smk_task == NULL || isp->smk_task == bsp->smk_task)
 		return 0;
 
+	sbsp = inode->i_sb->s_security;
+	if ((sbsp->smk_flags & SMK_SB_UNTRUSTED) &&
+	    isp->smk_task != sbsp->smk_root)
+		return 0;
+
 	if (bprm->unsafe & (LSM_UNSAFE_PTRACE | LSM_UNSAFE_PTRACE_CAP)) {
 		struct task_struct *tracer;
 		rc = 0;
@@ -1205,6 +1220,7 @@ static int smack_inode_rename(struct ino
  */
 static int smack_inode_permission(struct inode *inode, int mask)
 {
+	struct superblock_smack *sbsp = inode->i_sb->s_security;
 	struct smk_audit_info ad;
 	int no_block = mask & MAY_NOT_BLOCK;
 	int rc;
@@ -1216,6 +1232,11 @@ static int smack_inode_permission(struct
 	if (mask == 0)
 		return 0;
 
+	if (sbsp->smk_flags & SMK_SB_UNTRUSTED) {
+		if (smk_of_inode(inode) != sbsp->smk_root)
+			return -EACCES;
+	}
+
 	/* May be droppable after audit */
 	if (no_block)
 		return -ECHILD;
@@ -1716,6 +1737,7 @@ static int smack_mmap_file(struct file *
 	struct task_smack *tsp;
 	struct smack_known *okp;
 	struct inode_smack *isp;
+	struct superblock_smack *sbsp;
 	int may;
 	int mmay;
 	int tmay;
@@ -1727,6 +1749,10 @@ static int smack_mmap_file(struct file *
 	isp = file_inode(file)->i_security;
 	if (isp->smk_mmap == NULL)
 		return 0;
+	sbsp = file_inode(file)->i_sb->s_security;
+	if (sbsp->smk_flags & SMK_SB_UNTRUSTED &&
+	    isp->smk_mmap != sbsp->smk_root)
+		return -EACCES;
 	mkp = isp->smk_mmap;
 
 	tsp = current_security();
--- zfcpdump-kernel-4.4.orig/security/yama/yama_lsm.c
+++ zfcpdump-kernel-4.4/security/yama/yama_lsm.c
@@ -281,7 +281,7 @@ static int yama_ptrace_access_check(stru
 	int rc = 0;
 
 	/* require ptrace target be a child of ptracer on attach */
-	if (mode == PTRACE_MODE_ATTACH) {
+	if (mode & PTRACE_MODE_ATTACH) {
 		switch (ptrace_scope) {
 		case YAMA_SCOPE_DISABLED:
 			/* No additional restrictions. */
@@ -307,7 +307,7 @@ static int yama_ptrace_access_check(stru
 		}
 	}
 
-	if (rc) {
+	if (rc && (mode & PTRACE_MODE_NOAUDIT) == 0) {
 		printk_ratelimited(KERN_NOTICE
 			"ptrace of pid %d was attempted by: %s (pid %d)\n",
 			child->pid, current->comm, current->pid);
--- /dev/null
+++ zfcpdump-kernel-4.4/snapcraft.yaml
@@ -0,0 +1,16 @@
+name: ubuntu-generic-kernel
+version: 4.4.0
+summary: The generic kernel for snappy
+description: This is a generic snapped kernel, based off the xenial src and config
+type: kernel
+
+parts:
+  kernel:
+    plugin: kernel
+    source: .
+    source-type: git
+    kdefconfig: ['--makefile=debian/snapcraft.mk', 'branch=master','flavour=generic', 'config']
+    kconfigs:
+      - CONFIG_LOCALVERSION="-xenial_generic"
+      - CONFIG_DEBUG_INFO=n
+    kernel-image-target: bzImage
--- zfcpdump-kernel-4.4.orig/sound/core/compress_offload.c
+++ zfcpdump-kernel-4.4/sound/core/compress_offload.c
@@ -44,6 +44,13 @@
 #include <sound/compress_offload.h>
 #include <sound/compress_driver.h>
 
+/* struct snd_compr_codec_caps overflows the ioctl bit size for some
+ * architectures, so we need to disable the relevant ioctls.
+ */
+#if _IOC_SIZEBITS < 14
+#define COMPR_CODEC_CAPS_OVERFLOW
+#endif
+
 /* TODO:
  * - add substream support for multiple devices in case of
  *	SND_DYNAMIC_MINORS is not used
@@ -438,6 +445,7 @@ out:
 	return retval;
 }
 
+#ifndef COMPR_CODEC_CAPS_OVERFLOW
 static int
 snd_compr_get_codec_caps(struct snd_compr_stream *stream, unsigned long arg)
 {
@@ -461,6 +469,7 @@ out:
 	kfree(caps);
 	return retval;
 }
+#endif /* !COMPR_CODEC_CAPS_OVERFLOW */
 
 /* revisit this with snd_pcm_preallocate_xxx */
 static int snd_compr_allocate_buffer(struct snd_compr_stream *stream,
@@ -799,9 +808,11 @@ static long snd_compr_ioctl(struct file
 	case _IOC_NR(SNDRV_COMPRESS_GET_CAPS):
 		retval = snd_compr_get_caps(stream, arg);
 		break;
+#ifndef COMPR_CODEC_CAPS_OVERFLOW
 	case _IOC_NR(SNDRV_COMPRESS_GET_CODEC_CAPS):
 		retval = snd_compr_get_codec_caps(stream, arg);
 		break;
+#endif
 	case _IOC_NR(SNDRV_COMPRESS_SET_PARAMS):
 		retval = snd_compr_set_params(stream, arg);
 		break;
--- zfcpdump-kernel-4.4.orig/sound/core/control.c
+++ zfcpdump-kernel-4.4/sound/core/control.c
@@ -160,6 +160,8 @@ void snd_ctl_notify(struct snd_card *car
 	
 	if (snd_BUG_ON(!card || !id))
 		return;
+	if (card->shutdown)
+		return;
 	read_lock(&card->ctl_files_rwlock);
 #if IS_ENABLED(CONFIG_SND_MIXER_OSS)
 	card->mixer_oss_change_count++;
@@ -1405,6 +1407,8 @@ static int snd_ctl_tlv_ioctl(struct snd_
 		return -EFAULT;
 	if (tlv.length < sizeof(unsigned int) * 2)
 		return -EINVAL;
+	if (!tlv.numid)
+		return -EINVAL;
 	down_read(&card->controls_rwsem);
 	kctl = snd_ctl_find_numid(card, tlv.numid);
 	if (kctl == NULL) {
--- zfcpdump-kernel-4.4.orig/sound/core/control_compat.c
+++ zfcpdump-kernel-4.4/sound/core/control_compat.c
@@ -170,6 +170,19 @@ struct snd_ctl_elem_value32 {
         unsigned char reserved[128];
 };
 
+#ifdef CONFIG_X86_X32
+/* x32 has a different alignment for 64bit values from ia32 */
+struct snd_ctl_elem_value_x32 {
+	struct snd_ctl_elem_id id;
+	unsigned int indirect;	/* bit-field causes misalignment */
+	union {
+		s32 integer[128];
+		unsigned char data[512];
+		s64 integer64[64];
+	} value;
+	unsigned char reserved[128];
+};
+#endif /* CONFIG_X86_X32 */
 
 /* get the value type and count of the control */
 static int get_ctl_type(struct snd_card *card, struct snd_ctl_elem_id *id,
@@ -219,9 +232,11 @@ static int get_elem_size(int type, int c
 
 static int copy_ctl_value_from_user(struct snd_card *card,
 				    struct snd_ctl_elem_value *data,
-				    struct snd_ctl_elem_value32 __user *data32,
+				    void __user *userdata,
+				    void __user *valuep,
 				    int *typep, int *countp)
 {
+	struct snd_ctl_elem_value32 __user *data32 = userdata;
 	int i, type, size;
 	int uninitialized_var(count);
 	unsigned int indirect;
@@ -239,8 +254,9 @@ static int copy_ctl_value_from_user(stru
 	if (type == SNDRV_CTL_ELEM_TYPE_BOOLEAN ||
 	    type == SNDRV_CTL_ELEM_TYPE_INTEGER) {
 		for (i = 0; i < count; i++) {
+			s32 __user *intp = valuep;
 			int val;
-			if (get_user(val, &data32->value.integer[i]))
+			if (get_user(val, &intp[i]))
 				return -EFAULT;
 			data->value.integer.value[i] = val;
 		}
@@ -250,8 +266,7 @@ static int copy_ctl_value_from_user(stru
 			dev_err(card->dev, "snd_ioctl32_ctl_elem_value: unknown type %d\n", type);
 			return -EINVAL;
 		}
-		if (copy_from_user(data->value.bytes.data,
-				   data32->value.data, size))
+		if (copy_from_user(data->value.bytes.data, valuep, size))
 			return -EFAULT;
 	}
 
@@ -261,7 +276,8 @@ static int copy_ctl_value_from_user(stru
 }
 
 /* restore the value to 32bit */
-static int copy_ctl_value_to_user(struct snd_ctl_elem_value32 __user *data32,
+static int copy_ctl_value_to_user(void __user *userdata,
+				  void __user *valuep,
 				  struct snd_ctl_elem_value *data,
 				  int type, int count)
 {
@@ -270,22 +286,22 @@ static int copy_ctl_value_to_user(struct
 	if (type == SNDRV_CTL_ELEM_TYPE_BOOLEAN ||
 	    type == SNDRV_CTL_ELEM_TYPE_INTEGER) {
 		for (i = 0; i < count; i++) {
+			s32 __user *intp = valuep;
 			int val;
 			val = data->value.integer.value[i];
-			if (put_user(val, &data32->value.integer[i]))
+			if (put_user(val, &intp[i]))
 				return -EFAULT;
 		}
 	} else {
 		size = get_elem_size(type, count);
-		if (copy_to_user(data32->value.data,
-				 data->value.bytes.data, size))
+		if (copy_to_user(valuep, data->value.bytes.data, size))
 			return -EFAULT;
 	}
 	return 0;
 }
 
-static int snd_ctl_elem_read_user_compat(struct snd_card *card, 
-					 struct snd_ctl_elem_value32 __user *data32)
+static int ctl_elem_read_user(struct snd_card *card,
+			      void __user *userdata, void __user *valuep)
 {
 	struct snd_ctl_elem_value *data;
 	int err, type, count;
@@ -294,7 +310,9 @@ static int snd_ctl_elem_read_user_compat
 	if (data == NULL)
 		return -ENOMEM;
 
-	if ((err = copy_ctl_value_from_user(card, data, data32, &type, &count)) < 0)
+	err = copy_ctl_value_from_user(card, data, userdata, valuep,
+				       &type, &count);
+	if (err < 0)
 		goto error;
 
 	snd_power_lock(card);
@@ -303,14 +321,15 @@ static int snd_ctl_elem_read_user_compat
 		err = snd_ctl_elem_read(card, data);
 	snd_power_unlock(card);
 	if (err >= 0)
-		err = copy_ctl_value_to_user(data32, data, type, count);
+		err = copy_ctl_value_to_user(userdata, valuep, data,
+					     type, count);
  error:
 	kfree(data);
 	return err;
 }
 
-static int snd_ctl_elem_write_user_compat(struct snd_ctl_file *file,
-					  struct snd_ctl_elem_value32 __user *data32)
+static int ctl_elem_write_user(struct snd_ctl_file *file,
+			       void __user *userdata, void __user *valuep)
 {
 	struct snd_ctl_elem_value *data;
 	struct snd_card *card = file->card;
@@ -320,7 +339,9 @@ static int snd_ctl_elem_write_user_compa
 	if (data == NULL)
 		return -ENOMEM;
 
-	if ((err = copy_ctl_value_from_user(card, data, data32, &type, &count)) < 0)
+	err = copy_ctl_value_from_user(card, data, userdata, valuep,
+				       &type, &count);
+	if (err < 0)
 		goto error;
 
 	snd_power_lock(card);
@@ -329,12 +350,39 @@ static int snd_ctl_elem_write_user_compa
 		err = snd_ctl_elem_write(card, file, data);
 	snd_power_unlock(card);
 	if (err >= 0)
-		err = copy_ctl_value_to_user(data32, data, type, count);
+		err = copy_ctl_value_to_user(userdata, valuep, data,
+					     type, count);
  error:
 	kfree(data);
 	return err;
 }
 
+static int snd_ctl_elem_read_user_compat(struct snd_card *card,
+					 struct snd_ctl_elem_value32 __user *data32)
+{
+	return ctl_elem_read_user(card, data32, &data32->value);
+}
+
+static int snd_ctl_elem_write_user_compat(struct snd_ctl_file *file,
+					  struct snd_ctl_elem_value32 __user *data32)
+{
+	return ctl_elem_write_user(file, data32, &data32->value);
+}
+
+#ifdef CONFIG_X86_X32
+static int snd_ctl_elem_read_user_x32(struct snd_card *card,
+				      struct snd_ctl_elem_value_x32 __user *data32)
+{
+	return ctl_elem_read_user(card, data32, &data32->value);
+}
+
+static int snd_ctl_elem_write_user_x32(struct snd_ctl_file *file,
+				       struct snd_ctl_elem_value_x32 __user *data32)
+{
+	return ctl_elem_write_user(file, data32, &data32->value);
+}
+#endif /* CONFIG_X86_X32 */
+
 /* add or replace a user control */
 static int snd_ctl_elem_add_compat(struct snd_ctl_file *file,
 				   struct snd_ctl_elem_info32 __user *data32,
@@ -393,6 +441,10 @@ enum {
 	SNDRV_CTL_IOCTL_ELEM_WRITE32 = _IOWR('U', 0x13, struct snd_ctl_elem_value32),
 	SNDRV_CTL_IOCTL_ELEM_ADD32 = _IOWR('U', 0x17, struct snd_ctl_elem_info32),
 	SNDRV_CTL_IOCTL_ELEM_REPLACE32 = _IOWR('U', 0x18, struct snd_ctl_elem_info32),
+#ifdef CONFIG_X86_X32
+	SNDRV_CTL_IOCTL_ELEM_READ_X32 = _IOWR('U', 0x12, struct snd_ctl_elem_value_x32),
+	SNDRV_CTL_IOCTL_ELEM_WRITE_X32 = _IOWR('U', 0x13, struct snd_ctl_elem_value_x32),
+#endif /* CONFIG_X86_X32 */
 };
 
 static inline long snd_ctl_ioctl_compat(struct file *file, unsigned int cmd, unsigned long arg)
@@ -431,6 +483,12 @@ static inline long snd_ctl_ioctl_compat(
 		return snd_ctl_elem_add_compat(ctl, argp, 0);
 	case SNDRV_CTL_IOCTL_ELEM_REPLACE32:
 		return snd_ctl_elem_add_compat(ctl, argp, 1);
+#ifdef CONFIG_X86_X32
+	case SNDRV_CTL_IOCTL_ELEM_READ_X32:
+		return snd_ctl_elem_read_user_x32(ctl->card, argp);
+	case SNDRV_CTL_IOCTL_ELEM_WRITE_X32:
+		return snd_ctl_elem_write_user_x32(ctl, argp);
+#endif /* CONFIG_X86_X32 */
 	}
 
 	down_read(&snd_ioctl_rwsem);
--- zfcpdump-kernel-4.4.orig/sound/core/hrtimer.c
+++ zfcpdump-kernel-4.4/sound/core/hrtimer.c
@@ -90,7 +90,7 @@ static int snd_hrtimer_start(struct snd_
 	struct snd_hrtimer *stime = t->private_data;
 
 	atomic_set(&stime->running, 0);
-	hrtimer_cancel(&stime->hrt);
+	hrtimer_try_to_cancel(&stime->hrt);
 	hrtimer_start(&stime->hrt, ns_to_ktime(t->sticks * resolution),
 		      HRTIMER_MODE_REL);
 	atomic_set(&stime->running, 1);
@@ -101,6 +101,7 @@ static int snd_hrtimer_stop(struct snd_t
 {
 	struct snd_hrtimer *stime = t->private_data;
 	atomic_set(&stime->running, 0);
+	hrtimer_try_to_cancel(&stime->hrt);
 	return 0;
 }
 
--- zfcpdump-kernel-4.4.orig/sound/core/oss/pcm_oss.c
+++ zfcpdump-kernel-4.4/sound/core/oss/pcm_oss.c
@@ -834,7 +834,8 @@ static int choose_rate(struct snd_pcm_su
 	return snd_pcm_hw_param_near(substream, params, SNDRV_PCM_HW_PARAM_RATE, best_rate, NULL);
 }
 
-static int snd_pcm_oss_change_params(struct snd_pcm_substream *substream)
+static int snd_pcm_oss_change_params(struct snd_pcm_substream *substream,
+				     bool trylock)
 {
 	struct snd_pcm_runtime *runtime = substream->runtime;
 	struct snd_pcm_hw_params *params, *sparams;
@@ -848,7 +849,10 @@ static int snd_pcm_oss_change_params(str
 	struct snd_mask sformat_mask;
 	struct snd_mask mask;
 
-	if (mutex_lock_interruptible(&runtime->oss.params_lock))
+	if (trylock) {
+		if (!(mutex_trylock(&runtime->oss.params_lock)))
+			return -EAGAIN;
+	} else if (mutex_lock_interruptible(&runtime->oss.params_lock))
 		return -EINTR;
 	sw_params = kmalloc(sizeof(*sw_params), GFP_KERNEL);
 	params = kmalloc(sizeof(*params), GFP_KERNEL);
@@ -1092,7 +1096,7 @@ static int snd_pcm_oss_get_active_substr
 		if (asubstream == NULL)
 			asubstream = substream;
 		if (substream->runtime->oss.params) {
-			err = snd_pcm_oss_change_params(substream);
+			err = snd_pcm_oss_change_params(substream, false);
 			if (err < 0)
 				return err;
 		}
@@ -1132,7 +1136,7 @@ static int snd_pcm_oss_make_ready(struct
 		return 0;
 	runtime = substream->runtime;
 	if (runtime->oss.params) {
-		err = snd_pcm_oss_change_params(substream);
+		err = snd_pcm_oss_change_params(substream, false);
 		if (err < 0)
 			return err;
 	}
@@ -2163,7 +2167,7 @@ static int snd_pcm_oss_get_space(struct
 	runtime = substream->runtime;
 
 	if (runtime->oss.params &&
-	    (err = snd_pcm_oss_change_params(substream)) < 0)
+	    (err = snd_pcm_oss_change_params(substream, false)) < 0)
 		return err;
 
 	info.fragsize = runtime->oss.period_bytes;
@@ -2800,7 +2804,12 @@ static int snd_pcm_oss_mmap(struct file
 		return -EIO;
 	
 	if (runtime->oss.params) {
-		if ((err = snd_pcm_oss_change_params(substream)) < 0)
+		/* use mutex_trylock() for params_lock for avoiding a deadlock
+		 * between mmap_sem and params_lock taken by
+		 * copy_from/to_user() in snd_pcm_oss_write/read()
+		 */
+		err = snd_pcm_oss_change_params(substream, true);
+		if (err < 0)
 			return err;
 	}
 #ifdef CONFIG_SND_PCM_OSS_PLUGINS
--- zfcpdump-kernel-4.4.orig/sound/core/pcm.c
+++ zfcpdump-kernel-4.4/sound/core/pcm.c
@@ -849,6 +849,14 @@ int snd_pcm_new_internal(struct snd_card
 }
 EXPORT_SYMBOL(snd_pcm_new_internal);
 
+static void free_chmap(struct snd_pcm_str *pstr)
+{
+	if (pstr->chmap_kctl) {
+		snd_ctl_remove(pstr->pcm->card, pstr->chmap_kctl);
+		pstr->chmap_kctl = NULL;
+	}
+}
+
 static void snd_pcm_free_stream(struct snd_pcm_str * pstr)
 {
 	struct snd_pcm_substream *substream, *substream_next;
@@ -871,6 +879,7 @@ static void snd_pcm_free_stream(struct s
 		kfree(setup);
 	}
 #endif
+	free_chmap(pstr);
 	if (pstr->substream_count)
 		put_device(&pstr->dev);
 }
@@ -1135,10 +1144,7 @@ static int snd_pcm_dev_disconnect(struct
 	for (cidx = 0; cidx < 2; cidx++) {
 		if (!pcm->internal)
 			snd_unregister_device(&pcm->streams[cidx].dev);
-		if (pcm->streams[cidx].chmap_kctl) {
-			snd_ctl_remove(pcm->card, pcm->streams[cidx].chmap_kctl);
-			pcm->streams[cidx].chmap_kctl = NULL;
-		}
+		free_chmap(&pcm->streams[cidx]);
 	}
 	mutex_unlock(&pcm->open_mutex);
 	mutex_unlock(&register_mutex);
--- zfcpdump-kernel-4.4.orig/sound/core/pcm_compat.c
+++ zfcpdump-kernel-4.4/sound/core/pcm_compat.c
@@ -183,6 +183,14 @@ static int snd_pcm_ioctl_channel_info_co
 	return err;
 }
 
+#ifdef CONFIG_X86_X32
+/* X32 ABI has the same struct as x86-64 for snd_pcm_channel_info */
+static int snd_pcm_channel_info_user(struct snd_pcm_substream *substream,
+				     struct snd_pcm_channel_info __user *src);
+#define snd_pcm_ioctl_channel_info_x32(s, p)	\
+	snd_pcm_channel_info_user(s, p)
+#endif /* CONFIG_X86_X32 */
+
 struct snd_pcm_status32 {
 	s32 state;
 	struct compat_timespec trigger_tstamp;
@@ -243,6 +251,71 @@ static int snd_pcm_status_user_compat(st
 	return err;
 }
 
+#ifdef CONFIG_X86_X32
+/* X32 ABI has 64bit timespec and 64bit alignment */
+struct snd_pcm_status_x32 {
+	s32 state;
+	u32 rsvd; /* alignment */
+	struct timespec trigger_tstamp;
+	struct timespec tstamp;
+	u32 appl_ptr;
+	u32 hw_ptr;
+	s32 delay;
+	u32 avail;
+	u32 avail_max;
+	u32 overrange;
+	s32 suspended_state;
+	u32 audio_tstamp_data;
+	struct timespec audio_tstamp;
+	struct timespec driver_tstamp;
+	u32 audio_tstamp_accuracy;
+	unsigned char reserved[52-2*sizeof(struct timespec)];
+} __packed;
+
+#define put_timespec(src, dst) copy_to_user(dst, src, sizeof(*dst))
+
+static int snd_pcm_status_user_x32(struct snd_pcm_substream *substream,
+				   struct snd_pcm_status_x32 __user *src,
+				   bool ext)
+{
+	struct snd_pcm_status status;
+	int err;
+
+	memset(&status, 0, sizeof(status));
+	/*
+	 * with extension, parameters are read/write,
+	 * get audio_tstamp_data from user,
+	 * ignore rest of status structure
+	 */
+	if (ext && get_user(status.audio_tstamp_data,
+				(u32 __user *)(&src->audio_tstamp_data)))
+		return -EFAULT;
+	err = snd_pcm_status(substream, &status);
+	if (err < 0)
+		return err;
+
+	if (clear_user(src, sizeof(*src)))
+		return -EFAULT;
+	if (put_user(status.state, &src->state) ||
+	    put_timespec(&status.trigger_tstamp, &src->trigger_tstamp) ||
+	    put_timespec(&status.tstamp, &src->tstamp) ||
+	    put_user(status.appl_ptr, &src->appl_ptr) ||
+	    put_user(status.hw_ptr, &src->hw_ptr) ||
+	    put_user(status.delay, &src->delay) ||
+	    put_user(status.avail, &src->avail) ||
+	    put_user(status.avail_max, &src->avail_max) ||
+	    put_user(status.overrange, &src->overrange) ||
+	    put_user(status.suspended_state, &src->suspended_state) ||
+	    put_user(status.audio_tstamp_data, &src->audio_tstamp_data) ||
+	    put_timespec(&status.audio_tstamp, &src->audio_tstamp) ||
+	    put_timespec(&status.driver_tstamp, &src->driver_tstamp) ||
+	    put_user(status.audio_tstamp_accuracy, &src->audio_tstamp_accuracy))
+		return -EFAULT;
+
+	return err;
+}
+#endif /* CONFIG_X86_X32 */
+
 /* both for HW_PARAMS and HW_REFINE */
 static int snd_pcm_ioctl_hw_params_compat(struct snd_pcm_substream *substream,
 					  int refine, 
@@ -255,10 +328,15 @@ static int snd_pcm_ioctl_hw_params_compa
 	if (! (runtime = substream->runtime))
 		return -ENOTTY;
 
-	/* only fifo_size is different, so just copy all */
-	data = memdup_user(data32, sizeof(*data32));
-	if (IS_ERR(data))
-		return PTR_ERR(data);
+	data = kmalloc(sizeof(*data), GFP_KERNEL);
+	if (!data)
+		return -ENOMEM;
+
+	/* only fifo_size (RO from userspace) is different, so just copy all */
+	if (copy_from_user(data, data32, sizeof(*data32))) {
+		err = -EFAULT;
+		goto error;
+	}
 
 	if (refine)
 		err = snd_pcm_hw_refine(substream, data);
@@ -464,6 +542,93 @@ static int snd_pcm_ioctl_sync_ptr_compat
 	return 0;
 }
 
+#ifdef CONFIG_X86_X32
+/* X32 ABI has 64bit timespec and 64bit alignment */
+struct snd_pcm_mmap_status_x32 {
+	s32 state;
+	s32 pad1;
+	u32 hw_ptr;
+	u32 pad2; /* alignment */
+	struct timespec tstamp;
+	s32 suspended_state;
+	struct timespec audio_tstamp;
+} __packed;
+
+struct snd_pcm_mmap_control_x32 {
+	u32 appl_ptr;
+	u32 avail_min;
+};
+
+struct snd_pcm_sync_ptr_x32 {
+	u32 flags;
+	u32 rsvd; /* alignment */
+	union {
+		struct snd_pcm_mmap_status_x32 status;
+		unsigned char reserved[64];
+	} s;
+	union {
+		struct snd_pcm_mmap_control_x32 control;
+		unsigned char reserved[64];
+	} c;
+} __packed;
+
+static int snd_pcm_ioctl_sync_ptr_x32(struct snd_pcm_substream *substream,
+				      struct snd_pcm_sync_ptr_x32 __user *src)
+{
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	volatile struct snd_pcm_mmap_status *status;
+	volatile struct snd_pcm_mmap_control *control;
+	u32 sflags;
+	struct snd_pcm_mmap_control scontrol;
+	struct snd_pcm_mmap_status sstatus;
+	snd_pcm_uframes_t boundary;
+	int err;
+
+	if (snd_BUG_ON(!runtime))
+		return -EINVAL;
+
+	if (get_user(sflags, &src->flags) ||
+	    get_user(scontrol.appl_ptr, &src->c.control.appl_ptr) ||
+	    get_user(scontrol.avail_min, &src->c.control.avail_min))
+		return -EFAULT;
+	if (sflags & SNDRV_PCM_SYNC_PTR_HWSYNC) {
+		err = snd_pcm_hwsync(substream);
+		if (err < 0)
+			return err;
+	}
+	status = runtime->status;
+	control = runtime->control;
+	boundary = recalculate_boundary(runtime);
+	if (!boundary)
+		boundary = 0x7fffffff;
+	snd_pcm_stream_lock_irq(substream);
+	/* FIXME: we should consider the boundary for the sync from app */
+	if (!(sflags & SNDRV_PCM_SYNC_PTR_APPL))
+		control->appl_ptr = scontrol.appl_ptr;
+	else
+		scontrol.appl_ptr = control->appl_ptr % boundary;
+	if (!(sflags & SNDRV_PCM_SYNC_PTR_AVAIL_MIN))
+		control->avail_min = scontrol.avail_min;
+	else
+		scontrol.avail_min = control->avail_min;
+	sstatus.state = status->state;
+	sstatus.hw_ptr = status->hw_ptr % boundary;
+	sstatus.tstamp = status->tstamp;
+	sstatus.suspended_state = status->suspended_state;
+	sstatus.audio_tstamp = status->audio_tstamp;
+	snd_pcm_stream_unlock_irq(substream);
+	if (put_user(sstatus.state, &src->s.status.state) ||
+	    put_user(sstatus.hw_ptr, &src->s.status.hw_ptr) ||
+	    put_timespec(&sstatus.tstamp, &src->s.status.tstamp) ||
+	    put_user(sstatus.suspended_state, &src->s.status.suspended_state) ||
+	    put_timespec(&sstatus.audio_tstamp, &src->s.status.audio_tstamp) ||
+	    put_user(scontrol.appl_ptr, &src->c.control.appl_ptr) ||
+	    put_user(scontrol.avail_min, &src->c.control.avail_min))
+		return -EFAULT;
+
+	return 0;
+}
+#endif /* CONFIG_X86_X32 */
 
 /*
  */
@@ -482,7 +647,12 @@ enum {
 	SNDRV_PCM_IOCTL_WRITEN_FRAMES32 = _IOW('A', 0x52, struct snd_xfern32),
 	SNDRV_PCM_IOCTL_READN_FRAMES32 = _IOR('A', 0x53, struct snd_xfern32),
 	SNDRV_PCM_IOCTL_SYNC_PTR32 = _IOWR('A', 0x23, struct snd_pcm_sync_ptr32),
-
+#ifdef CONFIG_X86_X32
+	SNDRV_PCM_IOCTL_CHANNEL_INFO_X32 = _IOR('A', 0x32, struct snd_pcm_channel_info),
+	SNDRV_PCM_IOCTL_STATUS_X32 = _IOR('A', 0x20, struct snd_pcm_status_x32),
+	SNDRV_PCM_IOCTL_STATUS_EXT_X32 = _IOWR('A', 0x24, struct snd_pcm_status_x32),
+	SNDRV_PCM_IOCTL_SYNC_PTR_X32 = _IOWR('A', 0x23, struct snd_pcm_sync_ptr_x32),
+#endif /* CONFIG_X86_X32 */
 };
 
 static long snd_pcm_ioctl_compat(struct file *file, unsigned int cmd, unsigned long arg)
@@ -554,6 +724,16 @@ static long snd_pcm_ioctl_compat(struct
 		return snd_pcm_ioctl_rewind_compat(substream, argp);
 	case SNDRV_PCM_IOCTL_FORWARD32:
 		return snd_pcm_ioctl_forward_compat(substream, argp);
+#ifdef CONFIG_X86_X32
+	case SNDRV_PCM_IOCTL_STATUS_X32:
+		return snd_pcm_status_user_x32(substream, argp, false);
+	case SNDRV_PCM_IOCTL_STATUS_EXT_X32:
+		return snd_pcm_status_user_x32(substream, argp, true);
+	case SNDRV_PCM_IOCTL_SYNC_PTR_X32:
+		return snd_pcm_ioctl_sync_ptr_x32(substream, argp);
+	case SNDRV_PCM_IOCTL_CHANNEL_INFO_X32:
+		return snd_pcm_ioctl_channel_info_x32(substream, argp);
+#endif /* CONFIG_X86_X32 */
 	}
 
 	return -ENOIOCTLCMD;
--- zfcpdump-kernel-4.4.orig/sound/core/pcm_lib.c
+++ zfcpdump-kernel-4.4/sound/core/pcm_lib.c
@@ -322,7 +322,7 @@ static int snd_pcm_update_hw_ptr0(struct
 			char name[16];
 			snd_pcm_debug_name(substream, name, sizeof(name));
 			pcm_err(substream->pcm,
-				"BUG: %s, pos = %ld, buffer size = %ld, period size = %ld\n",
+				"invalid position: %s, pos = %ld, buffer size = %ld, period size = %ld\n",
 				name, pos, runtime->buffer_size,
 				runtime->period_size);
 		}
--- zfcpdump-kernel-4.4.orig/sound/core/pcm_native.c
+++ zfcpdump-kernel-4.4/sound/core/pcm_native.c
@@ -74,6 +74,18 @@ static int snd_pcm_open(struct file *fil
 static DEFINE_RWLOCK(snd_pcm_link_rwlock);
 static DECLARE_RWSEM(snd_pcm_link_rwsem);
 
+/* Writer in rwsem may block readers even during its waiting in queue,
+ * and this may lead to a deadlock when the code path takes read sem
+ * twice (e.g. one in snd_pcm_action_nonatomic() and another in
+ * snd_pcm_stream_lock()).  As a (suboptimal) workaround, let writer to
+ * spin until it gets the lock.
+ */
+static inline void down_write_nonblock(struct rw_semaphore *lock)
+{
+	while (!down_write_trylock(lock))
+		cond_resched();
+}
+
 /**
  * snd_pcm_stream_lock - Lock the PCM stream
  * @substream: PCM substream
@@ -1813,7 +1825,7 @@ static int snd_pcm_link(struct snd_pcm_s
 		res = -ENOMEM;
 		goto _nolock;
 	}
-	down_write(&snd_pcm_link_rwsem);
+	down_write_nonblock(&snd_pcm_link_rwsem);
 	write_lock_irq(&snd_pcm_link_rwlock);
 	if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN ||
 	    substream->runtime->status->state != substream1->runtime->status->state ||
@@ -1860,7 +1872,7 @@ static int snd_pcm_unlink(struct snd_pcm
 	struct snd_pcm_substream *s;
 	int res = 0;
 
-	down_write(&snd_pcm_link_rwsem);
+	down_write_nonblock(&snd_pcm_link_rwsem);
 	write_lock_irq(&snd_pcm_link_rwlock);
 	if (!snd_pcm_stream_linked(substream)) {
 		res = -EALREADY;
--- zfcpdump-kernel-4.4.orig/sound/core/rawmidi.c
+++ zfcpdump-kernel-4.4/sound/core/rawmidi.c
@@ -942,31 +942,36 @@ static long snd_rawmidi_kernel_read1(str
 	unsigned long flags;
 	long result = 0, count1;
 	struct snd_rawmidi_runtime *runtime = substream->runtime;
+	unsigned long appl_ptr;
 
+	spin_lock_irqsave(&runtime->lock, flags);
 	while (count > 0 && runtime->avail) {
 		count1 = runtime->buffer_size - runtime->appl_ptr;
 		if (count1 > count)
 			count1 = count;
-		spin_lock_irqsave(&runtime->lock, flags);
 		if (count1 > (int)runtime->avail)
 			count1 = runtime->avail;
+
+		/* update runtime->appl_ptr before unlocking for userbuf */
+		appl_ptr = runtime->appl_ptr;
+		runtime->appl_ptr += count1;
+		runtime->appl_ptr %= runtime->buffer_size;
+		runtime->avail -= count1;
+
 		if (kernelbuf)
-			memcpy(kernelbuf + result, runtime->buffer + runtime->appl_ptr, count1);
+			memcpy(kernelbuf + result, runtime->buffer + appl_ptr, count1);
 		if (userbuf) {
 			spin_unlock_irqrestore(&runtime->lock, flags);
 			if (copy_to_user(userbuf + result,
-					 runtime->buffer + runtime->appl_ptr, count1)) {
+					 runtime->buffer + appl_ptr, count1)) {
 				return result > 0 ? result : -EFAULT;
 			}
 			spin_lock_irqsave(&runtime->lock, flags);
 		}
-		runtime->appl_ptr += count1;
-		runtime->appl_ptr %= runtime->buffer_size;
-		runtime->avail -= count1;
-		spin_unlock_irqrestore(&runtime->lock, flags);
 		result += count1;
 		count -= count1;
 	}
+	spin_unlock_irqrestore(&runtime->lock, flags);
 	return result;
 }
 
@@ -1055,23 +1060,16 @@ int snd_rawmidi_transmit_empty(struct sn
 EXPORT_SYMBOL(snd_rawmidi_transmit_empty);
 
 /**
- * snd_rawmidi_transmit_peek - copy data from the internal buffer
+ * __snd_rawmidi_transmit_peek - copy data from the internal buffer
  * @substream: the rawmidi substream
  * @buffer: the buffer pointer
  * @count: data size to transfer
  *
- * Copies data from the internal output buffer to the given buffer.
- *
- * Call this in the interrupt handler when the midi output is ready,
- * and call snd_rawmidi_transmit_ack() after the transmission is
- * finished.
- *
- * Return: The size of copied data, or a negative error code on failure.
+ * This is a variant of snd_rawmidi_transmit_peek() without spinlock.
  */
-int snd_rawmidi_transmit_peek(struct snd_rawmidi_substream *substream,
+int __snd_rawmidi_transmit_peek(struct snd_rawmidi_substream *substream,
 			      unsigned char *buffer, int count)
 {
-	unsigned long flags;
 	int result, count1;
 	struct snd_rawmidi_runtime *runtime = substream->runtime;
 
@@ -1081,7 +1079,6 @@ int snd_rawmidi_transmit_peek(struct snd
 		return -EINVAL;
 	}
 	result = 0;
-	spin_lock_irqsave(&runtime->lock, flags);
 	if (runtime->avail >= runtime->buffer_size) {
 		/* warning: lowlevel layer MUST trigger down the hardware */
 		goto __skip;
@@ -1106,25 +1103,47 @@ int snd_rawmidi_transmit_peek(struct snd
 		}
 	}
       __skip:
+	return result;
+}
+EXPORT_SYMBOL(__snd_rawmidi_transmit_peek);
+
+/**
+ * snd_rawmidi_transmit_peek - copy data from the internal buffer
+ * @substream: the rawmidi substream
+ * @buffer: the buffer pointer
+ * @count: data size to transfer
+ *
+ * Copies data from the internal output buffer to the given buffer.
+ *
+ * Call this in the interrupt handler when the midi output is ready,
+ * and call snd_rawmidi_transmit_ack() after the transmission is
+ * finished.
+ *
+ * Return: The size of copied data, or a negative error code on failure.
+ */
+int snd_rawmidi_transmit_peek(struct snd_rawmidi_substream *substream,
+			      unsigned char *buffer, int count)
+{
+	struct snd_rawmidi_runtime *runtime = substream->runtime;
+	int result;
+	unsigned long flags;
+
+	spin_lock_irqsave(&runtime->lock, flags);
+	result = __snd_rawmidi_transmit_peek(substream, buffer, count);
 	spin_unlock_irqrestore(&runtime->lock, flags);
 	return result;
 }
 EXPORT_SYMBOL(snd_rawmidi_transmit_peek);
 
 /**
- * snd_rawmidi_transmit_ack - acknowledge the transmission
+ * __snd_rawmidi_transmit_ack - acknowledge the transmission
  * @substream: the rawmidi substream
  * @count: the transferred count
  *
- * Advances the hardware pointer for the internal output buffer with
- * the given size and updates the condition.
- * Call after the transmission is finished.
- *
- * Return: The advanced size if successful, or a negative error code on failure.
+ * This is a variant of __snd_rawmidi_transmit_ack() without spinlock.
  */
-int snd_rawmidi_transmit_ack(struct snd_rawmidi_substream *substream, int count)
+int __snd_rawmidi_transmit_ack(struct snd_rawmidi_substream *substream, int count)
 {
-	unsigned long flags;
 	struct snd_rawmidi_runtime *runtime = substream->runtime;
 
 	if (runtime->buffer == NULL) {
@@ -1132,7 +1151,6 @@ int snd_rawmidi_transmit_ack(struct snd_
 			  "snd_rawmidi_transmit_ack: output is not active!!!\n");
 		return -EINVAL;
 	}
-	spin_lock_irqsave(&runtime->lock, flags);
 	snd_BUG_ON(runtime->avail + count > runtime->buffer_size);
 	runtime->hw_ptr += count;
 	runtime->hw_ptr %= runtime->buffer_size;
@@ -1142,9 +1160,32 @@ int snd_rawmidi_transmit_ack(struct snd_
 		if (runtime->drain || snd_rawmidi_ready(substream))
 			wake_up(&runtime->sleep);
 	}
-	spin_unlock_irqrestore(&runtime->lock, flags);
 	return count;
 }
+EXPORT_SYMBOL(__snd_rawmidi_transmit_ack);
+
+/**
+ * snd_rawmidi_transmit_ack - acknowledge the transmission
+ * @substream: the rawmidi substream
+ * @count: the transferred count
+ *
+ * Advances the hardware pointer for the internal output buffer with
+ * the given size and updates the condition.
+ * Call after the transmission is finished.
+ *
+ * Return: The advanced size if successful, or a negative error code on failure.
+ */
+int snd_rawmidi_transmit_ack(struct snd_rawmidi_substream *substream, int count)
+{
+	struct snd_rawmidi_runtime *runtime = substream->runtime;
+	int result;
+	unsigned long flags;
+
+	spin_lock_irqsave(&runtime->lock, flags);
+	result = __snd_rawmidi_transmit_ack(substream, count);
+	spin_unlock_irqrestore(&runtime->lock, flags);
+	return result;
+}
 EXPORT_SYMBOL(snd_rawmidi_transmit_ack);
 
 /**
@@ -1160,12 +1201,22 @@ EXPORT_SYMBOL(snd_rawmidi_transmit_ack);
 int snd_rawmidi_transmit(struct snd_rawmidi_substream *substream,
 			 unsigned char *buffer, int count)
 {
+	struct snd_rawmidi_runtime *runtime = substream->runtime;
+	int result;
+	unsigned long flags;
+
+	spin_lock_irqsave(&runtime->lock, flags);
 	if (!substream->opened)
-		return -EBADFD;
-	count = snd_rawmidi_transmit_peek(substream, buffer, count);
-	if (count < 0)
-		return count;
-	return snd_rawmidi_transmit_ack(substream, count);
+		result = -EBADFD;
+	else {
+		count = __snd_rawmidi_transmit_peek(substream, buffer, count);
+		if (count <= 0)
+			result = count;
+		else
+			result = __snd_rawmidi_transmit_ack(substream, count);
+	}
+	spin_unlock_irqrestore(&runtime->lock, flags);
+	return result;
 }
 EXPORT_SYMBOL(snd_rawmidi_transmit);
 
@@ -1177,8 +1228,9 @@ static long snd_rawmidi_kernel_write1(st
 	unsigned long flags;
 	long count1, result;
 	struct snd_rawmidi_runtime *runtime = substream->runtime;
+	unsigned long appl_ptr;
 
-	if (snd_BUG_ON(!kernelbuf && !userbuf))
+	if (!kernelbuf && !userbuf)
 		return -EINVAL;
 	if (snd_BUG_ON(!runtime->buffer))
 		return -EINVAL;
@@ -1197,12 +1249,19 @@ static long snd_rawmidi_kernel_write1(st
 			count1 = count;
 		if (count1 > (long)runtime->avail)
 			count1 = runtime->avail;
+
+		/* update runtime->appl_ptr before unlocking for userbuf */
+		appl_ptr = runtime->appl_ptr;
+		runtime->appl_ptr += count1;
+		runtime->appl_ptr %= runtime->buffer_size;
+		runtime->avail -= count1;
+
 		if (kernelbuf)
-			memcpy(runtime->buffer + runtime->appl_ptr,
+			memcpy(runtime->buffer + appl_ptr,
 			       kernelbuf + result, count1);
 		else if (userbuf) {
 			spin_unlock_irqrestore(&runtime->lock, flags);
-			if (copy_from_user(runtime->buffer + runtime->appl_ptr,
+			if (copy_from_user(runtime->buffer + appl_ptr,
 					   userbuf + result, count1)) {
 				spin_lock_irqsave(&runtime->lock, flags);
 				result = result > 0 ? result : -EFAULT;
@@ -1210,9 +1269,6 @@ static long snd_rawmidi_kernel_write1(st
 			}
 			spin_lock_irqsave(&runtime->lock, flags);
 		}
-		runtime->appl_ptr += count1;
-		runtime->appl_ptr %= runtime->buffer_size;
-		runtime->avail -= count1;
 		result += count1;
 		count -= count1;
 	}
@@ -1577,11 +1633,13 @@ static int snd_rawmidi_dev_register(stru
 		return -EBUSY;
 	}
 	list_add_tail(&rmidi->list, &snd_rawmidi_devices);
+	mutex_unlock(&register_mutex);
 	err = snd_register_device(SNDRV_DEVICE_TYPE_RAWMIDI,
 				  rmidi->card, rmidi->device,
 				  &snd_rawmidi_f_ops, rmidi, &rmidi->dev);
 	if (err < 0) {
 		rmidi_err(rmidi, "unable to register\n");
+		mutex_lock(&register_mutex);
 		list_del(&rmidi->list);
 		mutex_unlock(&register_mutex);
 		return err;
@@ -1589,6 +1647,7 @@ static int snd_rawmidi_dev_register(stru
 	if (rmidi->ops && rmidi->ops->dev_register &&
 	    (err = rmidi->ops->dev_register(rmidi)) < 0) {
 		snd_unregister_device(&rmidi->dev);
+		mutex_lock(&register_mutex);
 		list_del(&rmidi->list);
 		mutex_unlock(&register_mutex);
 		return err;
@@ -1621,7 +1680,6 @@ static int snd_rawmidi_dev_register(stru
 		}
 	}
 #endif /* CONFIG_SND_OSSEMUL */
-	mutex_unlock(&register_mutex);
 	sprintf(name, "midi%d", rmidi->device);
 	entry = snd_info_create_card_entry(rmidi->card, name, rmidi->card->proc_root);
 	if (entry) {
--- zfcpdump-kernel-4.4.orig/sound/core/rawmidi_compat.c
+++ zfcpdump-kernel-4.4/sound/core/rawmidi_compat.c
@@ -94,9 +94,58 @@ static int snd_rawmidi_ioctl_status_comp
 	return 0;
 }
 
+#ifdef CONFIG_X86_X32
+/* X32 ABI has 64bit timespec and 64bit alignment */
+struct snd_rawmidi_status_x32 {
+	s32 stream;
+	u32 rsvd; /* alignment */
+	struct timespec tstamp;
+	u32 avail;
+	u32 xruns;
+	unsigned char reserved[16];
+} __attribute__((packed));
+
+#define put_timespec(src, dst) copy_to_user(dst, src, sizeof(*dst))
+
+static int snd_rawmidi_ioctl_status_x32(struct snd_rawmidi_file *rfile,
+					struct snd_rawmidi_status_x32 __user *src)
+{
+	int err;
+	struct snd_rawmidi_status status;
+
+	if (rfile->output == NULL)
+		return -EINVAL;
+	if (get_user(status.stream, &src->stream))
+		return -EFAULT;
+
+	switch (status.stream) {
+	case SNDRV_RAWMIDI_STREAM_OUTPUT:
+		err = snd_rawmidi_output_status(rfile->output, &status);
+		break;
+	case SNDRV_RAWMIDI_STREAM_INPUT:
+		err = snd_rawmidi_input_status(rfile->input, &status);
+		break;
+	default:
+		return -EINVAL;
+	}
+	if (err < 0)
+		return err;
+
+	if (put_timespec(&status.tstamp, &src->tstamp) ||
+	    put_user(status.avail, &src->avail) ||
+	    put_user(status.xruns, &src->xruns))
+		return -EFAULT;
+
+	return 0;
+}
+#endif /* CONFIG_X86_X32 */
+
 enum {
 	SNDRV_RAWMIDI_IOCTL_PARAMS32 = _IOWR('W', 0x10, struct snd_rawmidi_params32),
 	SNDRV_RAWMIDI_IOCTL_STATUS32 = _IOWR('W', 0x20, struct snd_rawmidi_status32),
+#ifdef CONFIG_X86_X32
+	SNDRV_RAWMIDI_IOCTL_STATUS_X32 = _IOWR('W', 0x20, struct snd_rawmidi_status_x32),
+#endif /* CONFIG_X86_X32 */
 };
 
 static long snd_rawmidi_ioctl_compat(struct file *file, unsigned int cmd, unsigned long arg)
@@ -115,6 +164,10 @@ static long snd_rawmidi_ioctl_compat(str
 		return snd_rawmidi_ioctl_params_compat(rfile, argp);
 	case SNDRV_RAWMIDI_IOCTL_STATUS32:
 		return snd_rawmidi_ioctl_status_compat(rfile, argp);
+#ifdef CONFIG_X86_X32
+	case SNDRV_RAWMIDI_IOCTL_STATUS_X32:
+		return snd_rawmidi_ioctl_status_x32(rfile, argp);
+#endif /* CONFIG_X86_X32 */
 	}
 	return -ENOIOCTLCMD;
 }
--- zfcpdump-kernel-4.4.orig/sound/core/seq/oss/seq_oss.c
+++ zfcpdump-kernel-4.4/sound/core/seq/oss/seq_oss.c
@@ -148,8 +148,6 @@ odev_release(struct inode *inode, struct
 	if ((dp = file->private_data) == NULL)
 		return 0;
 
-	snd_seq_oss_drain_write(dp);
-
 	mutex_lock(&register_mutex);
 	snd_seq_oss_release(dp);
 	mutex_unlock(&register_mutex);
--- zfcpdump-kernel-4.4.orig/sound/core/seq/oss/seq_oss_device.h
+++ zfcpdump-kernel-4.4/sound/core/seq/oss/seq_oss_device.h
@@ -127,7 +127,6 @@ int snd_seq_oss_write(struct seq_oss_dev
 unsigned int snd_seq_oss_poll(struct seq_oss_devinfo *dp, struct file *file, poll_table * wait);
 
 void snd_seq_oss_reset(struct seq_oss_devinfo *dp);
-void snd_seq_oss_drain_write(struct seq_oss_devinfo *dp);
 
 /* */
 void snd_seq_oss_process_queue(struct seq_oss_devinfo *dp, abstime_t time);
--- zfcpdump-kernel-4.4.orig/sound/core/seq/oss/seq_oss_init.c
+++ zfcpdump-kernel-4.4/sound/core/seq/oss/seq_oss_init.c
@@ -202,7 +202,7 @@ snd_seq_oss_open(struct file *file, int
 
 	dp->index = i;
 	if (i >= SNDRV_SEQ_OSS_MAX_CLIENTS) {
-		pr_err("ALSA: seq_oss: too many applications\n");
+		pr_debug("ALSA: seq_oss: too many applications\n");
 		rc = -ENOMEM;
 		goto _error;
 	}
@@ -435,22 +435,6 @@ snd_seq_oss_release(struct seq_oss_devin
 }
 
 
-/*
- * Wait until the queue is empty (if we don't have nonblock)
- */
-void
-snd_seq_oss_drain_write(struct seq_oss_devinfo *dp)
-{
-	if (! dp->timer->running)
-		return;
-	if (is_write_mode(dp->file_mode) && !is_nonblock_mode(dp->file_mode) &&
-	    dp->writeq) {
-		while (snd_seq_oss_writeq_sync(dp->writeq))
-			;
-	}
-}
-
-
 /*
  * reset sequencer devices
  */
--- zfcpdump-kernel-4.4.orig/sound/core/seq/oss/seq_oss_synth.c
+++ zfcpdump-kernel-4.4/sound/core/seq/oss/seq_oss_synth.c
@@ -308,7 +308,7 @@ snd_seq_oss_synth_cleanup(struct seq_oss
 	struct seq_oss_synth *rec;
 	struct seq_oss_synthinfo *info;
 
-	if (snd_BUG_ON(dp->max_synthdev >= SNDRV_SEQ_OSS_MAX_SYNTH_DEVS))
+	if (snd_BUG_ON(dp->max_synthdev > SNDRV_SEQ_OSS_MAX_SYNTH_DEVS))
 		return;
 	for (i = 0; i < dp->max_synthdev; i++) {
 		info = &dp->synths[i];
--- zfcpdump-kernel-4.4.orig/sound/core/seq/seq_clientmgr.c
+++ zfcpdump-kernel-4.4/sound/core/seq/seq_clientmgr.c
@@ -678,6 +678,9 @@ static int deliver_to_subscribers(struct
 	else
 		down_read(&grp->list_mutex);
 	list_for_each_entry(subs, &grp->list_head, src_list) {
+		/* both ports ready? */
+		if (atomic_read(&subs->ref_count) != 2)
+			continue;
 		event->dest = subs->info.dest;
 		if (subs->info.flags & SNDRV_SEQ_PORT_SUBS_TIMESTAMP)
 			/* convert time according to flag with subscription */
@@ -1962,7 +1965,7 @@ static int snd_seq_ioctl_remove_events(s
 		 * No restrictions so for a user client we can clear
 		 * the whole fifo
 		 */
-		if (client->type == USER_CLIENT)
+		if (client->type == USER_CLIENT && client->data.user.fifo)
 			snd_seq_fifo_clear(client->data.user.fifo);
 	}
 
--- zfcpdump-kernel-4.4.orig/sound/core/seq/seq_compat.c
+++ zfcpdump-kernel-4.4/sound/core/seq/seq_compat.c
@@ -49,11 +49,12 @@ static int snd_seq_call_port_info_ioctl(
 	struct snd_seq_port_info *data;
 	mm_segment_t fs;
 
-	data = memdup_user(data32, sizeof(*data32));
-	if (IS_ERR(data))
-		return PTR_ERR(data);
+	data = kmalloc(sizeof(*data), GFP_KERNEL);
+	if (!data)
+		return -ENOMEM;
 
-	if (get_user(data->flags, &data32->flags) ||
+	if (copy_from_user(data, data32, sizeof(*data32)) ||
+	    get_user(data->flags, &data32->flags) ||
 	    get_user(data->time_queue, &data32->time_queue))
 		goto error;
 	data->kernel = NULL;
--- zfcpdump-kernel-4.4.orig/sound/core/seq/seq_memory.c
+++ zfcpdump-kernel-4.4/sound/core/seq/seq_memory.c
@@ -383,15 +383,20 @@ int snd_seq_pool_init(struct snd_seq_poo
 
 	if (snd_BUG_ON(!pool))
 		return -EINVAL;
-	if (pool->ptr)			/* should be atomic? */
-		return 0;
 
-	pool->ptr = vmalloc(sizeof(struct snd_seq_event_cell) * pool->size);
-	if (!pool->ptr)
+	cellptr = vmalloc(sizeof(struct snd_seq_event_cell) * pool->size);
+	if (!cellptr)
 		return -ENOMEM;
 
 	/* add new cells to the free cell list */
 	spin_lock_irqsave(&pool->lock, flags);
+	if (pool->ptr) {
+		spin_unlock_irqrestore(&pool->lock, flags);
+		vfree(cellptr);
+		return 0;
+	}
+
+	pool->ptr = cellptr;
 	pool->free = NULL;
 
 	for (cell = 0; cell < pool->size; cell++) {
--- zfcpdump-kernel-4.4.orig/sound/core/seq/seq_ports.c
+++ zfcpdump-kernel-4.4/sound/core/seq/seq_ports.c
@@ -173,10 +173,6 @@ struct snd_seq_client_port *snd_seq_crea
 }
 
 /* */
-enum group_type {
-	SRC_LIST, DEST_LIST
-};
-
 static int subscribe_port(struct snd_seq_client *client,
 			  struct snd_seq_client_port *port,
 			  struct snd_seq_port_subs_info *grp,
@@ -203,6 +199,20 @@ static struct snd_seq_client_port *get_c
 	return NULL;
 }
 
+static void delete_and_unsubscribe_port(struct snd_seq_client *client,
+					struct snd_seq_client_port *port,
+					struct snd_seq_subscribers *subs,
+					bool is_src, bool ack);
+
+static inline struct snd_seq_subscribers *
+get_subscriber(struct list_head *p, bool is_src)
+{
+	if (is_src)
+		return list_entry(p, struct snd_seq_subscribers, src_list);
+	else
+		return list_entry(p, struct snd_seq_subscribers, dest_list);
+}
+
 /*
  * remove all subscribers on the list
  * this is called from port_delete, for each src and dest list.
@@ -210,7 +220,7 @@ static struct snd_seq_client_port *get_c
 static void clear_subscriber_list(struct snd_seq_client *client,
 				  struct snd_seq_client_port *port,
 				  struct snd_seq_port_subs_info *grp,
-				  int grptype)
+				  int is_src)
 {
 	struct list_head *p, *n;
 
@@ -219,15 +229,13 @@ static void clear_subscriber_list(struct
 		struct snd_seq_client *c;
 		struct snd_seq_client_port *aport;
 
-		if (grptype == SRC_LIST) {
-			subs = list_entry(p, struct snd_seq_subscribers, src_list);
+		subs = get_subscriber(p, is_src);
+		if (is_src)
 			aport = get_client_port(&subs->info.dest, &c);
-		} else {
-			subs = list_entry(p, struct snd_seq_subscribers, dest_list);
+		else
 			aport = get_client_port(&subs->info.sender, &c);
-		}
-		list_del(p);
-		unsubscribe_port(client, port, grp, &subs->info, 0);
+		delete_and_unsubscribe_port(client, port, subs, is_src, false);
+
 		if (!aport) {
 			/* looks like the connected port is being deleted.
 			 * we decrease the counter, and when both ports are deleted
@@ -235,21 +243,14 @@ static void clear_subscriber_list(struct
 			 */
 			if (atomic_dec_and_test(&subs->ref_count))
 				kfree(subs);
-		} else {
-			/* ok we got the connected port */
-			struct snd_seq_port_subs_info *agrp;
-			agrp = (grptype == SRC_LIST) ? &aport->c_dest : &aport->c_src;
-			down_write(&agrp->list_mutex);
-			if (grptype == SRC_LIST)
-				list_del(&subs->dest_list);
-			else
-				list_del(&subs->src_list);
-			up_write(&agrp->list_mutex);
-			unsubscribe_port(c, aport, agrp, &subs->info, 1);
-			kfree(subs);
-			snd_seq_port_unlock(aport);
-			snd_seq_client_unlock(c);
+			continue;
 		}
+
+		/* ok we got the connected port */
+		delete_and_unsubscribe_port(c, aport, subs, !is_src, true);
+		kfree(subs);
+		snd_seq_port_unlock(aport);
+		snd_seq_client_unlock(c);
 	}
 }
 
@@ -262,8 +263,8 @@ static int port_delete(struct snd_seq_cl
 	snd_use_lock_sync(&port->use_lock); 
 
 	/* clear subscribers info */
-	clear_subscriber_list(client, port, &port->c_src, SRC_LIST);
-	clear_subscriber_list(client, port, &port->c_dest, DEST_LIST);
+	clear_subscriber_list(client, port, &port->c_src, true);
+	clear_subscriber_list(client, port, &port->c_dest, false);
 
 	if (port->private_free)
 		port->private_free(port->private_data);
@@ -479,85 +480,123 @@ static int match_subs_info(struct snd_se
 	return 0;
 }
 
+static int check_and_subscribe_port(struct snd_seq_client *client,
+				    struct snd_seq_client_port *port,
+				    struct snd_seq_subscribers *subs,
+				    bool is_src, bool exclusive, bool ack)
+{
+	struct snd_seq_port_subs_info *grp;
+	struct list_head *p;
+	struct snd_seq_subscribers *s;
+	int err;
 
-/* connect two ports */
-int snd_seq_port_connect(struct snd_seq_client *connector,
-			 struct snd_seq_client *src_client,
-			 struct snd_seq_client_port *src_port,
-			 struct snd_seq_client *dest_client,
-			 struct snd_seq_client_port *dest_port,
-			 struct snd_seq_port_subscribe *info)
-{
-	struct snd_seq_port_subs_info *src = &src_port->c_src;
-	struct snd_seq_port_subs_info *dest = &dest_port->c_dest;
-	struct snd_seq_subscribers *subs, *s;
-	int err, src_called = 0;
-	unsigned long flags;
-	int exclusive;
-
-	subs = kzalloc(sizeof(*subs), GFP_KERNEL);
-	if (! subs)
-		return -ENOMEM;
-
-	subs->info = *info;
-	atomic_set(&subs->ref_count, 2);
-
-	down_write(&src->list_mutex);
-	down_write_nested(&dest->list_mutex, SINGLE_DEPTH_NESTING);
-
-	exclusive = info->flags & SNDRV_SEQ_PORT_SUBS_EXCLUSIVE ? 1 : 0;
+	grp = is_src ? &port->c_src : &port->c_dest;
 	err = -EBUSY;
+	down_write(&grp->list_mutex);
 	if (exclusive) {
-		if (! list_empty(&src->list_head) || ! list_empty(&dest->list_head))
+		if (!list_empty(&grp->list_head))
 			goto __error;
 	} else {
-		if (src->exclusive || dest->exclusive)
+		if (grp->exclusive)
 			goto __error;
 		/* check whether already exists */
-		list_for_each_entry(s, &src->list_head, src_list) {
-			if (match_subs_info(info, &s->info))
-				goto __error;
-		}
-		list_for_each_entry(s, &dest->list_head, dest_list) {
-			if (match_subs_info(info, &s->info))
+		list_for_each(p, &grp->list_head) {
+			s = get_subscriber(p, is_src);
+			if (match_subs_info(&subs->info, &s->info))
 				goto __error;
 		}
 	}
 
-	if ((err = subscribe_port(src_client, src_port, src, info,
-				  connector->number != src_client->number)) < 0)
-		goto __error;
-	src_called = 1;
-
-	if ((err = subscribe_port(dest_client, dest_port, dest, info,
-				  connector->number != dest_client->number)) < 0)
+	err = subscribe_port(client, port, grp, &subs->info, ack);
+	if (err < 0) {
+		grp->exclusive = 0;
 		goto __error;
+	}
 
 	/* add to list */
-	write_lock_irqsave(&src->list_lock, flags);
-	// write_lock(&dest->list_lock); // no other lock yet
-	list_add_tail(&subs->src_list, &src->list_head);
-	list_add_tail(&subs->dest_list, &dest->list_head);
-	// write_unlock(&dest->list_lock); // no other lock yet
-	write_unlock_irqrestore(&src->list_lock, flags);
+	write_lock_irq(&grp->list_lock);
+	if (is_src)
+		list_add_tail(&subs->src_list, &grp->list_head);
+	else
+		list_add_tail(&subs->dest_list, &grp->list_head);
+	grp->exclusive = exclusive;
+	atomic_inc(&subs->ref_count);
+	write_unlock_irq(&grp->list_lock);
+	err = 0;
 
-	src->exclusive = dest->exclusive = exclusive;
+ __error:
+	up_write(&grp->list_mutex);
+	return err;
+}
+
+static void delete_and_unsubscribe_port(struct snd_seq_client *client,
+					struct snd_seq_client_port *port,
+					struct snd_seq_subscribers *subs,
+					bool is_src, bool ack)
+{
+	struct snd_seq_port_subs_info *grp;
+	struct list_head *list;
+	bool empty;
+
+	grp = is_src ? &port->c_src : &port->c_dest;
+	list = is_src ? &subs->src_list : &subs->dest_list;
+	down_write(&grp->list_mutex);
+	write_lock_irq(&grp->list_lock);
+	empty = list_empty(list);
+	if (!empty)
+		list_del_init(list);
+	grp->exclusive = 0;
+	write_unlock_irq(&grp->list_lock);
+	up_write(&grp->list_mutex);
+
+	if (!empty)
+		unsubscribe_port(client, port, grp, &subs->info, ack);
+}
+
+/* connect two ports */
+int snd_seq_port_connect(struct snd_seq_client *connector,
+			 struct snd_seq_client *src_client,
+			 struct snd_seq_client_port *src_port,
+			 struct snd_seq_client *dest_client,
+			 struct snd_seq_client_port *dest_port,
+			 struct snd_seq_port_subscribe *info)
+{
+	struct snd_seq_subscribers *subs;
+	bool exclusive;
+	int err;
+
+	subs = kzalloc(sizeof(*subs), GFP_KERNEL);
+	if (!subs)
+		return -ENOMEM;
+
+	subs->info = *info;
+	atomic_set(&subs->ref_count, 0);
+	INIT_LIST_HEAD(&subs->src_list);
+	INIT_LIST_HEAD(&subs->dest_list);
+
+	exclusive = !!(info->flags & SNDRV_SEQ_PORT_SUBS_EXCLUSIVE);
+
+	err = check_and_subscribe_port(src_client, src_port, subs, true,
+				       exclusive,
+				       connector->number != src_client->number);
+	if (err < 0)
+		goto error;
+	err = check_and_subscribe_port(dest_client, dest_port, subs, false,
+				       exclusive,
+				       connector->number != dest_client->number);
+	if (err < 0)
+		goto error_dest;
 
-	up_write(&dest->list_mutex);
-	up_write(&src->list_mutex);
 	return 0;
 
- __error:
-	if (src_called)
-		unsubscribe_port(src_client, src_port, src, info,
-				 connector->number != src_client->number);
+ error_dest:
+	delete_and_unsubscribe_port(src_client, src_port, subs, true,
+				    connector->number != src_client->number);
+ error:
 	kfree(subs);
-	up_write(&dest->list_mutex);
-	up_write(&src->list_mutex);
 	return err;
 }
 
-
 /* remove the connection */
 int snd_seq_port_disconnect(struct snd_seq_client *connector,
 			    struct snd_seq_client *src_client,
@@ -567,37 +606,28 @@ int snd_seq_port_disconnect(struct snd_s
 			    struct snd_seq_port_subscribe *info)
 {
 	struct snd_seq_port_subs_info *src = &src_port->c_src;
-	struct snd_seq_port_subs_info *dest = &dest_port->c_dest;
 	struct snd_seq_subscribers *subs;
 	int err = -ENOENT;
-	unsigned long flags;
 
 	down_write(&src->list_mutex);
-	down_write_nested(&dest->list_mutex, SINGLE_DEPTH_NESTING);
-
 	/* look for the connection */
 	list_for_each_entry(subs, &src->list_head, src_list) {
 		if (match_subs_info(info, &subs->info)) {
-			write_lock_irqsave(&src->list_lock, flags);
-			// write_lock(&dest->list_lock);  // no lock yet
-			list_del(&subs->src_list);
-			list_del(&subs->dest_list);
-			// write_unlock(&dest->list_lock);
-			write_unlock_irqrestore(&src->list_lock, flags);
-			src->exclusive = dest->exclusive = 0;
-			unsubscribe_port(src_client, src_port, src, info,
-					 connector->number != src_client->number);
-			unsubscribe_port(dest_client, dest_port, dest, info,
-					 connector->number != dest_client->number);
-			kfree(subs);
+			atomic_dec(&subs->ref_count); /* mark as not ready */
 			err = 0;
 			break;
 		}
 	}
-
-	up_write(&dest->list_mutex);
 	up_write(&src->list_mutex);
-	return err;
+	if (err < 0)
+		return err;
+
+	delete_and_unsubscribe_port(src_client, src_port, subs, true,
+				    connector->number != src_client->number);
+	delete_and_unsubscribe_port(dest_client, dest_port, subs, false,
+				    connector->number != dest_client->number);
+	kfree(subs);
+	return 0;
 }
 
 
--- zfcpdump-kernel-4.4.orig/sound/core/seq/seq_queue.c
+++ zfcpdump-kernel-4.4/sound/core/seq/seq_queue.c
@@ -142,8 +142,10 @@ static struct snd_seq_queue *queue_new(i
 static void queue_delete(struct snd_seq_queue *q)
 {
 	/* stop and release the timer */
+	mutex_lock(&q->timer_mutex);
 	snd_seq_timer_stop(q->timer);
 	snd_seq_timer_close(q);
+	mutex_unlock(&q->timer_mutex);
 	/* wait until access free */
 	snd_use_lock_sync(&q->use_lock);
 	/* release resources... */
--- zfcpdump-kernel-4.4.orig/sound/core/seq/seq_timer.c
+++ zfcpdump-kernel-4.4/sound/core/seq/seq_timer.c
@@ -90,6 +90,9 @@ void snd_seq_timer_delete(struct snd_seq
 
 void snd_seq_timer_defaults(struct snd_seq_timer * tmr)
 {
+	unsigned long flags;
+
+	spin_lock_irqsave(&tmr->lock, flags);
 	/* setup defaults */
 	tmr->ppq = 96;		/* 96 PPQ */
 	tmr->tempo = 500000;	/* 120 BPM */
@@ -105,21 +108,25 @@ void snd_seq_timer_defaults(struct snd_s
 	tmr->preferred_resolution = seq_default_timer_resolution;
 
 	tmr->skew = tmr->skew_base = SKEW_BASE;
+	spin_unlock_irqrestore(&tmr->lock, flags);
 }
 
-void snd_seq_timer_reset(struct snd_seq_timer * tmr)
+static void seq_timer_reset(struct snd_seq_timer *tmr)
 {
-	unsigned long flags;
-
-	spin_lock_irqsave(&tmr->lock, flags);
-
 	/* reset time & songposition */
 	tmr->cur_time.tv_sec = 0;
 	tmr->cur_time.tv_nsec = 0;
 
 	tmr->tick.cur_tick = 0;
 	tmr->tick.fraction = 0;
+}
+
+void snd_seq_timer_reset(struct snd_seq_timer *tmr)
+{
+	unsigned long flags;
 
+	spin_lock_irqsave(&tmr->lock, flags);
+	seq_timer_reset(tmr);
 	spin_unlock_irqrestore(&tmr->lock, flags);
 }
 
@@ -138,8 +145,11 @@ static void snd_seq_timer_interrupt(stru
 	tmr = q->timer;
 	if (tmr == NULL)
 		return;
-	if (!tmr->running)
+	spin_lock_irqsave(&tmr->lock, flags);
+	if (!tmr->running) {
+		spin_unlock_irqrestore(&tmr->lock, flags);
 		return;
+	}
 
 	resolution *= ticks;
 	if (tmr->skew != tmr->skew_base) {
@@ -148,8 +158,6 @@ static void snd_seq_timer_interrupt(stru
 			(((resolution & 0xffff) * tmr->skew) >> 16);
 	}
 
-	spin_lock_irqsave(&tmr->lock, flags);
-
 	/* update timer */
 	snd_seq_inc_time_nsec(&tmr->cur_time, resolution);
 
@@ -296,26 +304,30 @@ int snd_seq_timer_open(struct snd_seq_qu
 	t->callback = snd_seq_timer_interrupt;
 	t->callback_data = q;
 	t->flags |= SNDRV_TIMER_IFLG_AUTO;
+	spin_lock_irq(&tmr->lock);
 	tmr->timeri = t;
+	spin_unlock_irq(&tmr->lock);
 	return 0;
 }
 
 int snd_seq_timer_close(struct snd_seq_queue *q)
 {
 	struct snd_seq_timer *tmr;
+	struct snd_timer_instance *t;
 	
 	tmr = q->timer;
 	if (snd_BUG_ON(!tmr))
 		return -EINVAL;
-	if (tmr->timeri) {
-		snd_timer_stop(tmr->timeri);
-		snd_timer_close(tmr->timeri);
-		tmr->timeri = NULL;
-	}
+	spin_lock_irq(&tmr->lock);
+	t = tmr->timeri;
+	tmr->timeri = NULL;
+	spin_unlock_irq(&tmr->lock);
+	if (t)
+		snd_timer_close(t);
 	return 0;
 }
 
-int snd_seq_timer_stop(struct snd_seq_timer * tmr)
+static int seq_timer_stop(struct snd_seq_timer *tmr)
 {
 	if (! tmr->timeri)
 		return -EINVAL;
@@ -326,6 +338,17 @@ int snd_seq_timer_stop(struct snd_seq_ti
 	return 0;
 }
 
+int snd_seq_timer_stop(struct snd_seq_timer *tmr)
+{
+	unsigned long flags;
+	int err;
+
+	spin_lock_irqsave(&tmr->lock, flags);
+	err = seq_timer_stop(tmr);
+	spin_unlock_irqrestore(&tmr->lock, flags);
+	return err;
+}
+
 static int initialize_timer(struct snd_seq_timer *tmr)
 {
 	struct snd_timer *t;
@@ -358,13 +381,13 @@ static int initialize_timer(struct snd_s
 	return 0;
 }
 
-int snd_seq_timer_start(struct snd_seq_timer * tmr)
+static int seq_timer_start(struct snd_seq_timer *tmr)
 {
 	if (! tmr->timeri)
 		return -EINVAL;
 	if (tmr->running)
-		snd_seq_timer_stop(tmr);
-	snd_seq_timer_reset(tmr);
+		seq_timer_stop(tmr);
+	seq_timer_reset(tmr);
 	if (initialize_timer(tmr) < 0)
 		return -EINVAL;
 	snd_timer_start(tmr->timeri, tmr->ticks);
@@ -373,14 +396,25 @@ int snd_seq_timer_start(struct snd_seq_t
 	return 0;
 }
 
-int snd_seq_timer_continue(struct snd_seq_timer * tmr)
+int snd_seq_timer_start(struct snd_seq_timer *tmr)
+{
+	unsigned long flags;
+	int err;
+
+	spin_lock_irqsave(&tmr->lock, flags);
+	err = seq_timer_start(tmr);
+	spin_unlock_irqrestore(&tmr->lock, flags);
+	return err;
+}
+
+static int seq_timer_continue(struct snd_seq_timer *tmr)
 {
 	if (! tmr->timeri)
 		return -EINVAL;
 	if (tmr->running)
 		return -EBUSY;
 	if (! tmr->initialized) {
-		snd_seq_timer_reset(tmr);
+		seq_timer_reset(tmr);
 		if (initialize_timer(tmr) < 0)
 			return -EINVAL;
 	}
@@ -390,11 +424,24 @@ int snd_seq_timer_continue(struct snd_se
 	return 0;
 }
 
+int snd_seq_timer_continue(struct snd_seq_timer *tmr)
+{
+	unsigned long flags;
+	int err;
+
+	spin_lock_irqsave(&tmr->lock, flags);
+	err = seq_timer_continue(tmr);
+	spin_unlock_irqrestore(&tmr->lock, flags);
+	return err;
+}
+
 /* return current 'real' time. use timeofday() to get better granularity. */
 snd_seq_real_time_t snd_seq_timer_get_cur_time(struct snd_seq_timer *tmr)
 {
 	snd_seq_real_time_t cur_time;
+	unsigned long flags;
 
+	spin_lock_irqsave(&tmr->lock, flags);
 	cur_time = tmr->cur_time;
 	if (tmr->running) { 
 		struct timeval tm;
@@ -410,7 +457,7 @@ snd_seq_real_time_t snd_seq_timer_get_cu
 		}
 		snd_seq_sanity_real_time(&cur_time);
 	}
-                
+	spin_unlock_irqrestore(&tmr->lock, flags);
 	return cur_time;	
 }
 
--- zfcpdump-kernel-4.4.orig/sound/core/seq/seq_virmidi.c
+++ zfcpdump-kernel-4.4/sound/core/seq/seq_virmidi.c
@@ -155,21 +155,26 @@ static void snd_virmidi_output_trigger(s
 	struct snd_virmidi *vmidi = substream->runtime->private_data;
 	int count, res;
 	unsigned char buf[32], *pbuf;
+	unsigned long flags;
 
 	if (up) {
 		vmidi->trigger = 1;
 		if (vmidi->seq_mode == SNDRV_VIRMIDI_SEQ_DISPATCH &&
 		    !(vmidi->rdev->flags & SNDRV_VIRMIDI_SUBSCRIBE)) {
-			snd_rawmidi_transmit_ack(substream, substream->runtime->buffer_size - substream->runtime->avail);
-			return;		/* ignored */
+			while (snd_rawmidi_transmit(substream, buf,
+						    sizeof(buf)) > 0) {
+				/* ignored */
+			}
+			return;
 		}
 		if (vmidi->event.type != SNDRV_SEQ_EVENT_NONE) {
 			if (snd_seq_kernel_client_dispatch(vmidi->client, &vmidi->event, in_atomic(), 0) < 0)
 				return;
 			vmidi->event.type = SNDRV_SEQ_EVENT_NONE;
 		}
+		spin_lock_irqsave(&substream->runtime->lock, flags);
 		while (1) {
-			count = snd_rawmidi_transmit_peek(substream, buf, sizeof(buf));
+			count = __snd_rawmidi_transmit_peek(substream, buf, sizeof(buf));
 			if (count <= 0)
 				break;
 			pbuf = buf;
@@ -179,16 +184,18 @@ static void snd_virmidi_output_trigger(s
 					snd_midi_event_reset_encode(vmidi->parser);
 					continue;
 				}
-				snd_rawmidi_transmit_ack(substream, res);
+				__snd_rawmidi_transmit_ack(substream, res);
 				pbuf += res;
 				count -= res;
 				if (vmidi->event.type != SNDRV_SEQ_EVENT_NONE) {
 					if (snd_seq_kernel_client_dispatch(vmidi->client, &vmidi->event, in_atomic(), 0) < 0)
-						return;
+						goto out;
 					vmidi->event.type = SNDRV_SEQ_EVENT_NONE;
 				}
 			}
 		}
+	out:
+		spin_unlock_irqrestore(&substream->runtime->lock, flags);
 	} else {
 		vmidi->trigger = 0;
 	}
@@ -254,9 +261,13 @@ static int snd_virmidi_output_open(struc
  */
 static int snd_virmidi_input_close(struct snd_rawmidi_substream *substream)
 {
+	struct snd_virmidi_dev *rdev = substream->rmidi->private_data;
 	struct snd_virmidi *vmidi = substream->runtime->private_data;
-	snd_midi_event_free(vmidi->parser);
+
+	write_lock_irq(&rdev->filelist_lock);
 	list_del(&vmidi->list);
+	write_unlock_irq(&rdev->filelist_lock);
+	snd_midi_event_free(vmidi->parser);
 	substream->runtime->private_data = NULL;
 	kfree(vmidi);
 	return 0;
--- zfcpdump-kernel-4.4.orig/sound/core/timer.c
+++ zfcpdump-kernel-4.4/sound/core/timer.c
@@ -65,6 +65,7 @@ struct snd_timer_user {
 	int qtail;
 	int qused;
 	int queue_size;
+	bool disconnected;
 	struct snd_timer_read *queue;
 	struct snd_timer_tread *tqueue;
 	spinlock_t qlock;
@@ -73,7 +74,7 @@ struct snd_timer_user {
 	struct timespec tstamp;		/* trigger tstamp */
 	wait_queue_head_t qchange_sleep;
 	struct fasync_struct *fasync;
-	struct mutex tread_sem;
+	struct mutex ioctl_lock;
 };
 
 /* list of timers */
@@ -215,11 +216,13 @@ static void snd_timer_check_master(struc
 		    slave->slave_id == master->slave_id) {
 			list_move_tail(&slave->open_list, &master->slave_list_head);
 			spin_lock_irq(&slave_active_lock);
+			spin_lock(&master->timer->lock);
 			slave->master = master;
 			slave->timer = master->timer;
 			if (slave->flags & SNDRV_TIMER_IFLG_RUNNING)
 				list_add_tail(&slave->active_list,
 					      &master->slave_active_head);
+			spin_unlock(&master->timer->lock);
 			spin_unlock_irq(&slave_active_lock);
 		}
 	}
@@ -288,10 +291,26 @@ int snd_timer_open(struct snd_timer_inst
 		mutex_unlock(&register_mutex);
 		return -ENOMEM;
 	}
+	/* take a card refcount for safe disconnection */
+	if (timer->card)
+		get_device(&timer->card->card_dev);
 	timeri->slave_class = tid->dev_sclass;
 	timeri->slave_id = slave_id;
-	if (list_empty(&timer->open_list_head) && timer->hw.open)
-		timer->hw.open(timer);
+
+	if (list_empty(&timer->open_list_head) && timer->hw.open) {
+		int err = timer->hw.open(timer);
+		if (err) {
+			kfree(timeri->owner);
+			kfree(timeri);
+
+			if (timer->card)
+				put_device(&timer->card->card_dev);
+			module_put(timer->module);
+			mutex_unlock(&register_mutex);
+			return err;
+		}
+	}
+
 	list_add_tail(&timeri->open_list, &timer->open_list_head);
 	snd_timer_check_master(timeri);
 	mutex_unlock(&register_mutex);
@@ -299,8 +318,7 @@ int snd_timer_open(struct snd_timer_inst
 	return 0;
 }
 
-static int _snd_timer_stop(struct snd_timer_instance *timeri,
-			   int keep_flag, int event);
+static int _snd_timer_stop(struct snd_timer_instance *timeri, int event);
 
 /*
  * close a timer instance
@@ -342,19 +360,25 @@ int snd_timer_close(struct snd_timer_ins
 		spin_unlock_irq(&timer->lock);
 		mutex_lock(&register_mutex);
 		list_del(&timeri->open_list);
-		if (timer && list_empty(&timer->open_list_head) &&
+		if (list_empty(&timer->open_list_head) &&
 		    timer->hw.close)
 			timer->hw.close(timer);
 		/* remove slave links */
+		spin_lock_irq(&slave_active_lock);
+		spin_lock(&timer->lock);
 		list_for_each_entry_safe(slave, tmp, &timeri->slave_list_head,
 					 open_list) {
-			spin_lock_irq(&slave_active_lock);
-			_snd_timer_stop(slave, 1, SNDRV_TIMER_EVENT_RESOLUTION);
 			list_move_tail(&slave->open_list, &snd_timer_slave_list);
 			slave->master = NULL;
 			slave->timer = NULL;
-			spin_unlock_irq(&slave_active_lock);
+			list_del_init(&slave->ack_list);
+			list_del_init(&slave->active_list);
 		}
+		spin_unlock(&timer->lock);
+		spin_unlock_irq(&slave_active_lock);
+		/* release a card refcount for safe disconnection */
+		if (timer->card)
+			put_device(&timer->card->card_dev);
 		mutex_unlock(&register_mutex);
 	}
  out:
@@ -411,7 +435,7 @@ static void snd_timer_notify1(struct snd
 	spin_lock_irqsave(&timer->lock, flags);
 	list_for_each_entry(ts, &ti->slave_active_head, active_list)
 		if (ts->ccallback)
-			ts->ccallback(ti, event + 100, &tstamp, resolution);
+			ts->ccallback(ts, event + 100, &tstamp, resolution);
 	spin_unlock_irqrestore(&timer->lock, flags);
 }
 
@@ -440,10 +464,17 @@ static int snd_timer_start_slave(struct
 	unsigned long flags;
 
 	spin_lock_irqsave(&slave_active_lock, flags);
+	if (timeri->flags & SNDRV_TIMER_IFLG_RUNNING) {
+		spin_unlock_irqrestore(&slave_active_lock, flags);
+		return -EBUSY;
+	}
 	timeri->flags |= SNDRV_TIMER_IFLG_RUNNING;
-	if (timeri->master)
+	if (timeri->master && timeri->timer) {
+		spin_lock(&timeri->timer->lock);
 		list_add_tail(&timeri->active_list,
 			      &timeri->master->slave_active_head);
+		spin_unlock(&timeri->timer->lock);
+	}
 	spin_unlock_irqrestore(&slave_active_lock, flags);
 	return 1; /* delayed start */
 }
@@ -461,23 +492,32 @@ int snd_timer_start(struct snd_timer_ins
 		return -EINVAL;
 	if (timeri->flags & SNDRV_TIMER_IFLG_SLAVE) {
 		result = snd_timer_start_slave(timeri);
-		snd_timer_notify1(timeri, SNDRV_TIMER_EVENT_START);
+		if (result >= 0)
+			snd_timer_notify1(timeri, SNDRV_TIMER_EVENT_START);
 		return result;
 	}
 	timer = timeri->timer;
 	if (timer == NULL)
 		return -EINVAL;
+	if (timer->card && timer->card->shutdown)
+		return -ENODEV;
 	spin_lock_irqsave(&timer->lock, flags);
+	if (timeri->flags & (SNDRV_TIMER_IFLG_RUNNING |
+			     SNDRV_TIMER_IFLG_START)) {
+		result = -EBUSY;
+		goto unlock;
+	}
 	timeri->ticks = timeri->cticks = ticks;
 	timeri->pticks = 0;
 	result = snd_timer_start1(timer, timeri, ticks);
+ unlock:
 	spin_unlock_irqrestore(&timer->lock, flags);
-	snd_timer_notify1(timeri, SNDRV_TIMER_EVENT_START);
+	if (result >= 0)
+		snd_timer_notify1(timeri, SNDRV_TIMER_EVENT_START);
 	return result;
 }
 
-static int _snd_timer_stop(struct snd_timer_instance * timeri,
-			   int keep_flag, int event)
+static int _snd_timer_stop(struct snd_timer_instance *timeri, int event)
 {
 	struct snd_timer *timer;
 	unsigned long flags;
@@ -486,19 +526,36 @@ static int _snd_timer_stop(struct snd_ti
 		return -ENXIO;
 
 	if (timeri->flags & SNDRV_TIMER_IFLG_SLAVE) {
-		if (!keep_flag) {
-			spin_lock_irqsave(&slave_active_lock, flags);
-			timeri->flags &= ~SNDRV_TIMER_IFLG_RUNNING;
+		spin_lock_irqsave(&slave_active_lock, flags);
+		if (!(timeri->flags & SNDRV_TIMER_IFLG_RUNNING)) {
 			spin_unlock_irqrestore(&slave_active_lock, flags);
+			return -EBUSY;
 		}
+		if (timeri->timer)
+			spin_lock(&timeri->timer->lock);
+		timeri->flags &= ~SNDRV_TIMER_IFLG_RUNNING;
+		list_del_init(&timeri->ack_list);
+		list_del_init(&timeri->active_list);
+		if (timeri->timer)
+			spin_unlock(&timeri->timer->lock);
+		spin_unlock_irqrestore(&slave_active_lock, flags);
 		goto __end;
 	}
 	timer = timeri->timer;
 	if (!timer)
 		return -EINVAL;
 	spin_lock_irqsave(&timer->lock, flags);
+	if (!(timeri->flags & (SNDRV_TIMER_IFLG_RUNNING |
+			       SNDRV_TIMER_IFLG_START))) {
+		spin_unlock_irqrestore(&timer->lock, flags);
+		return -EBUSY;
+	}
 	list_del_init(&timeri->ack_list);
 	list_del_init(&timeri->active_list);
+	if (timer->card && timer->card->shutdown) {
+		spin_unlock_irqrestore(&timer->lock, flags);
+		return 0;
+	}
 	if ((timeri->flags & SNDRV_TIMER_IFLG_RUNNING) &&
 	    !(--timer->running)) {
 		timer->hw.stop(timer);
@@ -511,9 +568,7 @@ static int _snd_timer_stop(struct snd_ti
 			}
 		}
 	}
-	if (!keep_flag)
-		timeri->flags &=
-			~(SNDRV_TIMER_IFLG_RUNNING | SNDRV_TIMER_IFLG_START);
+	timeri->flags &= ~(SNDRV_TIMER_IFLG_RUNNING | SNDRV_TIMER_IFLG_START);
 	spin_unlock_irqrestore(&timer->lock, flags);
       __end:
 	if (event != SNDRV_TIMER_EVENT_RESOLUTION)
@@ -532,7 +587,7 @@ int snd_timer_stop(struct snd_timer_inst
 	unsigned long flags;
 	int err;
 
-	err = _snd_timer_stop(timeri, 0, SNDRV_TIMER_EVENT_STOP);
+	err = _snd_timer_stop(timeri, SNDRV_TIMER_EVENT_STOP);
 	if (err < 0)
 		return err;
 	timer = timeri->timer;
@@ -561,11 +616,18 @@ int snd_timer_continue(struct snd_timer_
 	timer = timeri->timer;
 	if (! timer)
 		return -EINVAL;
+	if (timer->card && timer->card->shutdown)
+		return -ENODEV;
 	spin_lock_irqsave(&timer->lock, flags);
+	if (timeri->flags & SNDRV_TIMER_IFLG_RUNNING) {
+		result = -EBUSY;
+		goto unlock;
+	}
 	if (!timeri->cticks)
 		timeri->cticks = 1;
 	timeri->pticks = 0;
 	result = snd_timer_start1(timer, timeri, timer->sticks);
+ unlock:
 	spin_unlock_irqrestore(&timer->lock, flags);
 	snd_timer_notify1(timeri, SNDRV_TIMER_EVENT_CONTINUE);
 	return result;
@@ -576,7 +638,7 @@ int snd_timer_continue(struct snd_timer_
  */
 int snd_timer_pause(struct snd_timer_instance * timeri)
 {
-	return _snd_timer_stop(timeri, 0, SNDRV_TIMER_EVENT_PAUSE);
+	return _snd_timer_stop(timeri, SNDRV_TIMER_EVENT_PAUSE);
 }
 
 /*
@@ -624,6 +686,9 @@ static void snd_timer_tasklet(unsigned l
 	unsigned long resolution, ticks;
 	unsigned long flags;
 
+	if (timer->card && timer->card->shutdown)
+		return;
+
 	spin_lock_irqsave(&timer->lock, flags);
 	/* now process all callbacks */
 	while (!list_empty(&timer->sack_list_head)) {
@@ -664,6 +729,9 @@ void snd_timer_interrupt(struct snd_time
 	if (timer == NULL)
 		return;
 
+	if (timer->card && timer->card->shutdown)
+		return;
+
 	spin_lock_irqsave(&timer->lock, flags);
 
 	/* remember the current resolution */
@@ -693,8 +761,8 @@ void snd_timer_interrupt(struct snd_time
 			ti->cticks = ti->ticks;
 		} else {
 			ti->flags &= ~SNDRV_TIMER_IFLG_RUNNING;
-			if (--timer->running)
-				list_del(&ti->active_list);
+			--timer->running;
+			list_del_init(&ti->active_list);
 		}
 		if ((timer->hw.flags & SNDRV_TIMER_HW_TASKLET) ||
 		    (ti->flags & SNDRV_TIMER_IFLG_FAST))
@@ -782,6 +850,7 @@ int snd_timer_new(struct snd_card *card,
 	timer->tmr_subdevice = tid->subdevice;
 	if (id)
 		strlcpy(timer->id, id, sizeof(timer->id));
+	timer->sticks = 1;
 	INIT_LIST_HEAD(&timer->device_list);
 	INIT_LIST_HEAD(&timer->open_list_head);
 	INIT_LIST_HEAD(&timer->active_list_head);
@@ -874,11 +943,28 @@ static int snd_timer_dev_register(struct
 	return 0;
 }
 
+/* just for reference in snd_timer_dev_disconnect() below */
+static void snd_timer_user_ccallback(struct snd_timer_instance *timeri,
+				     int event, struct timespec *tstamp,
+				     unsigned long resolution);
+
 static int snd_timer_dev_disconnect(struct snd_device *device)
 {
 	struct snd_timer *timer = device->device_data;
+	struct snd_timer_instance *ti;
+
 	mutex_lock(&register_mutex);
 	list_del_init(&timer->device_list);
+	/* wake up pending sleepers */
+	list_for_each_entry(ti, &timer->open_list_head, open_list) {
+		/* FIXME: better to have a ti.disconnect() op */
+		if (ti->ccallback == snd_timer_user_ccallback) {
+			struct snd_timer_user *tu = ti->callback_data;
+
+			tu->disconnected = true;
+			wake_up(&tu->qchange_sleep);
+		}
+	}
 	mutex_unlock(&register_mutex);
 	return 0;
 }
@@ -889,6 +975,8 @@ void snd_timer_notify(struct snd_timer *
 	unsigned long resolution = 0;
 	struct snd_timer_instance *ti, *ts;
 
+	if (timer->card && timer->card->shutdown)
+		return;
 	if (! (timer->hw.flags & SNDRV_TIMER_HW_SLAVE))
 		return;
 	if (snd_BUG_ON(event < SNDRV_TIMER_EVENT_MSTART ||
@@ -977,8 +1065,8 @@ static int snd_timer_s_start(struct snd_
 		njiff += timer->sticks - priv->correction;
 		priv->correction = 0;
 	}
-	priv->last_expires = priv->tlist.expires = njiff;
-	add_timer(&priv->tlist);
+	priv->last_expires = njiff;
+	mod_timer(&priv->tlist, njiff);
 	return 0;
 }
 
@@ -1047,6 +1135,8 @@ static void snd_timer_proc_read(struct s
 
 	mutex_lock(&register_mutex);
 	list_for_each_entry(timer, &snd_timer_list, device_list) {
+		if (timer->card && timer->card->shutdown)
+			continue;
 		switch (timer->tmr_class) {
 		case SNDRV_TIMER_CLASS_GLOBAL:
 			snd_iprintf(buffer, "G%i: ", timer->tmr_device);
@@ -1171,6 +1261,7 @@ static void snd_timer_user_ccallback(str
 		tu->tstamp = *tstamp;
 	if ((tu->filter & (1 << event)) == 0 || !tu->tread)
 		return;
+	memset(&r1, 0, sizeof(r1));
 	r1.event = event;
 	r1.tstamp = *tstamp;
 	r1.val = resolution;
@@ -1205,6 +1296,7 @@ static void snd_timer_user_tinterrupt(st
 	}
 	if ((tu->filter & (1 << SNDRV_TIMER_EVENT_RESOLUTION)) &&
 	    tu->last_resolution != resolution) {
+		memset(&r1, 0, sizeof(r1));
 		r1.event = SNDRV_TIMER_EVENT_RESOLUTION;
 		r1.tstamp = tstamp;
 		r1.val = resolution;
@@ -1253,7 +1345,7 @@ static int snd_timer_user_open(struct in
 		return -ENOMEM;
 	spin_lock_init(&tu->qlock);
 	init_waitqueue_head(&tu->qchange_sleep);
-	mutex_init(&tu->tread_sem);
+	mutex_init(&tu->ioctl_lock);
 	tu->ticks = 1;
 	tu->queue_size = 128;
 	tu->queue = kmalloc(tu->queue_size * sizeof(struct snd_timer_read),
@@ -1273,8 +1365,10 @@ static int snd_timer_user_release(struct
 	if (file->private_data) {
 		tu = file->private_data;
 		file->private_data = NULL;
+		mutex_lock(&tu->ioctl_lock);
 		if (tu->timeri)
 			snd_timer_close(tu->timeri);
+		mutex_unlock(&tu->ioctl_lock);
 		kfree(tu->queue);
 		kfree(tu->tqueue);
 		kfree(tu);
@@ -1512,7 +1606,6 @@ static int snd_timer_user_tselect(struct
 	int err = 0;
 
 	tu = file->private_data;
-	mutex_lock(&tu->tread_sem);
 	if (tu->timeri) {
 		snd_timer_close(tu->timeri);
 		tu->timeri = NULL;
@@ -1556,7 +1649,6 @@ static int snd_timer_user_tselect(struct
 	}
 
       __err:
-      	mutex_unlock(&tu->tread_sem);
 	return err;
 }
 
@@ -1670,6 +1762,7 @@ static int snd_timer_user_params(struct
 	if (tu->timeri->flags & SNDRV_TIMER_IFLG_EARLY_EVENT) {
 		if (tu->tread) {
 			struct snd_timer_tread tread;
+			memset(&tread, 0, sizeof(tread));
 			tread.event = SNDRV_TIMER_EVENT_EARLY;
 			tread.tstamp.tv_sec = 0;
 			tread.tstamp.tv_nsec = 0;
@@ -1769,7 +1862,7 @@ enum {
 	SNDRV_TIMER_IOCTL_PAUSE_OLD = _IO('T', 0x23),
 };
 
-static long snd_timer_user_ioctl(struct file *file, unsigned int cmd,
+static long __snd_timer_user_ioctl(struct file *file, unsigned int cmd,
 				 unsigned long arg)
 {
 	struct snd_timer_user *tu;
@@ -1786,17 +1879,11 @@ static long snd_timer_user_ioctl(struct
 	{
 		int xarg;
 
-		mutex_lock(&tu->tread_sem);
-		if (tu->timeri)	{	/* too late */
-			mutex_unlock(&tu->tread_sem);
+		if (tu->timeri)	/* too late */
 			return -EBUSY;
-		}
-		if (get_user(xarg, p)) {
-			mutex_unlock(&tu->tread_sem);
+		if (get_user(xarg, p))
 			return -EFAULT;
-		}
 		tu->tread = xarg ? 1 : 0;
-		mutex_unlock(&tu->tread_sem);
 		return 0;
 	}
 	case SNDRV_TIMER_IOCTL_GINFO:
@@ -1829,6 +1916,18 @@ static long snd_timer_user_ioctl(struct
 	return -ENOTTY;
 }
 
+static long snd_timer_user_ioctl(struct file *file, unsigned int cmd,
+				 unsigned long arg)
+{
+	struct snd_timer_user *tu = file->private_data;
+	long ret;
+
+	mutex_lock(&tu->ioctl_lock);
+	ret = __snd_timer_user_ioctl(file, cmd, arg);
+	mutex_unlock(&tu->ioctl_lock);
+	return ret;
+}
+
 static int snd_timer_user_fasync(int fd, struct file * file, int on)
 {
 	struct snd_timer_user *tu;
@@ -1842,6 +1941,7 @@ static ssize_t snd_timer_user_read(struc
 {
 	struct snd_timer_user *tu;
 	long result = 0, unit;
+	int qhead;
 	int err = 0;
 
 	tu = file->private_data;
@@ -1853,7 +1953,7 @@ static ssize_t snd_timer_user_read(struc
 
 			if ((file->f_flags & O_NONBLOCK) != 0 || result > 0) {
 				err = -EAGAIN;
-				break;
+				goto _error;
 			}
 
 			set_current_state(TASK_INTERRUPTIBLE);
@@ -1866,40 +1966,41 @@ static ssize_t snd_timer_user_read(struc
 
 			remove_wait_queue(&tu->qchange_sleep, &wait);
 
+			if (tu->disconnected) {
+				err = -ENODEV;
+				goto _error;
+			}
 			if (signal_pending(current)) {
 				err = -ERESTARTSYS;
-				break;
+				goto _error;
 			}
 		}
 
+		qhead = tu->qhead++;
+		tu->qhead %= tu->queue_size;
+		tu->qused--;
 		spin_unlock_irq(&tu->qlock);
-		if (err < 0)
-			goto _error;
 
+		mutex_lock(&tu->ioctl_lock);
 		if (tu->tread) {
-			if (copy_to_user(buffer, &tu->tqueue[tu->qhead++],
-					 sizeof(struct snd_timer_tread))) {
+			if (copy_to_user(buffer, &tu->tqueue[qhead],
+					 sizeof(struct snd_timer_tread)))
 				err = -EFAULT;
-				goto _error;
-			}
 		} else {
-			if (copy_to_user(buffer, &tu->queue[tu->qhead++],
-					 sizeof(struct snd_timer_read))) {
+			if (copy_to_user(buffer, &tu->queue[qhead],
+					 sizeof(struct snd_timer_read)))
 				err = -EFAULT;
-				goto _error;
-			}
 		}
+		mutex_unlock(&tu->ioctl_lock);
 
-		tu->qhead %= tu->queue_size;
-
+		spin_lock_irq(&tu->qlock);
+		if (err < 0)
+			goto _error;
 		result += unit;
 		buffer += unit;
-
-		spin_lock_irq(&tu->qlock);
-		tu->qused--;
 	}
-	spin_unlock_irq(&tu->qlock);
  _error:
+	spin_unlock_irq(&tu->qlock);
 	return result > 0 ? result : err;
 }
 
@@ -1915,6 +2016,8 @@ static unsigned int snd_timer_user_poll(
 	mask = 0;
 	if (tu->qused)
 		mask |= POLLIN | POLLRDNORM;
+	if (tu->disconnected)
+		mask |= POLLERR;
 
 	return mask;
 }
--- zfcpdump-kernel-4.4.orig/sound/core/timer_compat.c
+++ zfcpdump-kernel-4.4/sound/core/timer_compat.c
@@ -70,13 +70,14 @@ static int snd_timer_user_status_compat(
 					struct snd_timer_status32 __user *_status)
 {
 	struct snd_timer_user *tu;
-	struct snd_timer_status status;
+	struct snd_timer_status32 status;
 	
 	tu = file->private_data;
 	if (snd_BUG_ON(!tu->timeri))
 		return -ENXIO;
 	memset(&status, 0, sizeof(status));
-	status.tstamp = tu->tstamp;
+	status.tstamp.tv_sec = tu->tstamp.tv_sec;
+	status.tstamp.tv_nsec = tu->tstamp.tv_nsec;
 	status.resolution = snd_timer_resolution(tu->timeri);
 	status.lost = tu->timeri->lost;
 	status.overrun = tu->overrun;
@@ -88,12 +89,21 @@ static int snd_timer_user_status_compat(
 	return 0;
 }
 
+#ifdef CONFIG_X86_X32
+/* X32 ABI has the same struct as x86-64 */
+#define snd_timer_user_status_x32(file, s) \
+	snd_timer_user_status(file, s)
+#endif /* CONFIG_X86_X32 */
+
 /*
  */
 
 enum {
 	SNDRV_TIMER_IOCTL_INFO32 = _IOR('T', 0x11, struct snd_timer_info32),
 	SNDRV_TIMER_IOCTL_STATUS32 = _IOW('T', 0x14, struct snd_timer_status32),
+#ifdef CONFIG_X86_X32
+	SNDRV_TIMER_IOCTL_STATUS_X32 = _IOW('T', 0x14, struct snd_timer_status),
+#endif /* CONFIG_X86_X32 */
 };
 
 static long snd_timer_user_ioctl_compat(struct file *file, unsigned int cmd, unsigned long arg)
@@ -122,6 +132,10 @@ static long snd_timer_user_ioctl_compat(
 		return snd_timer_user_info_compat(file, argp);
 	case SNDRV_TIMER_IOCTL_STATUS32:
 		return snd_timer_user_status_compat(file, argp);
+#ifdef CONFIG_X86_X32
+	case SNDRV_TIMER_IOCTL_STATUS_X32:
+		return snd_timer_user_status_x32(file, argp);
+#endif /* CONFIG_X86_X32 */
 	}
 	return -ENOIOCTLCMD;
 }
--- zfcpdump-kernel-4.4.orig/sound/drivers/dummy.c
+++ zfcpdump-kernel-4.4/sound/drivers/dummy.c
@@ -109,6 +109,9 @@ struct dummy_timer_ops {
 	snd_pcm_uframes_t (*pointer)(struct snd_pcm_substream *);
 };
 
+#define get_dummy_ops(substream) \
+	(*(const struct dummy_timer_ops **)(substream)->runtime->private_data)
+
 struct dummy_model {
 	const char *name;
 	int (*playback_constraints)(struct snd_pcm_runtime *runtime);
@@ -137,7 +140,6 @@ struct snd_dummy {
 	int iobox;
 	struct snd_kcontrol *cd_volume_ctl;
 	struct snd_kcontrol *cd_switch_ctl;
-	const struct dummy_timer_ops *timer_ops;
 };
 
 /*
@@ -231,6 +233,8 @@ static struct dummy_model *dummy_models[
  */
 
 struct dummy_systimer_pcm {
+	/* ops must be the first item */
+	const struct dummy_timer_ops *timer_ops;
 	spinlock_t lock;
 	struct timer_list timer;
 	unsigned long base_time;
@@ -366,6 +370,8 @@ static struct dummy_timer_ops dummy_syst
  */
 
 struct dummy_hrtimer_pcm {
+	/* ops must be the first item */
+	const struct dummy_timer_ops *timer_ops;
 	ktime_t base_time;
 	ktime_t period_time;
 	atomic_t running;
@@ -414,6 +420,7 @@ static int dummy_hrtimer_stop(struct snd
 
 static inline void dummy_hrtimer_sync(struct dummy_hrtimer_pcm *dpcm)
 {
+	hrtimer_cancel(&dpcm->timer);
 	tasklet_kill(&dpcm->tasklet);
 }
 
@@ -492,31 +499,25 @@ static struct dummy_timer_ops dummy_hrti
 
 static int dummy_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
 {
-	struct snd_dummy *dummy = snd_pcm_substream_chip(substream);
-
 	switch (cmd) {
 	case SNDRV_PCM_TRIGGER_START:
 	case SNDRV_PCM_TRIGGER_RESUME:
-		return dummy->timer_ops->start(substream);
+		return get_dummy_ops(substream)->start(substream);
 	case SNDRV_PCM_TRIGGER_STOP:
 	case SNDRV_PCM_TRIGGER_SUSPEND:
-		return dummy->timer_ops->stop(substream);
+		return get_dummy_ops(substream)->stop(substream);
 	}
 	return -EINVAL;
 }
 
 static int dummy_pcm_prepare(struct snd_pcm_substream *substream)
 {
-	struct snd_dummy *dummy = snd_pcm_substream_chip(substream);
-
-	return dummy->timer_ops->prepare(substream);
+	return get_dummy_ops(substream)->prepare(substream);
 }
 
 static snd_pcm_uframes_t dummy_pcm_pointer(struct snd_pcm_substream *substream)
 {
-	struct snd_dummy *dummy = snd_pcm_substream_chip(substream);
-
-	return dummy->timer_ops->pointer(substream);
+	return get_dummy_ops(substream)->pointer(substream);
 }
 
 static struct snd_pcm_hardware dummy_pcm_hardware = {
@@ -562,17 +563,19 @@ static int dummy_pcm_open(struct snd_pcm
 	struct snd_dummy *dummy = snd_pcm_substream_chip(substream);
 	struct dummy_model *model = dummy->model;
 	struct snd_pcm_runtime *runtime = substream->runtime;
+	const struct dummy_timer_ops *ops;
 	int err;
 
-	dummy->timer_ops = &dummy_systimer_ops;
+	ops = &dummy_systimer_ops;
 #ifdef CONFIG_HIGH_RES_TIMERS
 	if (hrtimer)
-		dummy->timer_ops = &dummy_hrtimer_ops;
+		ops = &dummy_hrtimer_ops;
 #endif
 
-	err = dummy->timer_ops->create(substream);
+	err = ops->create(substream);
 	if (err < 0)
 		return err;
+	get_dummy_ops(substream) = ops;
 
 	runtime->hw = dummy->pcm_hw;
 	if (substream->pcm->device & 1) {
@@ -594,7 +597,7 @@ static int dummy_pcm_open(struct snd_pcm
 			err = model->capture_constraints(substream->runtime);
 	}
 	if (err < 0) {
-		dummy->timer_ops->free(substream);
+		get_dummy_ops(substream)->free(substream);
 		return err;
 	}
 	return 0;
@@ -602,8 +605,7 @@ static int dummy_pcm_open(struct snd_pcm
 
 static int dummy_pcm_close(struct snd_pcm_substream *substream)
 {
-	struct snd_dummy *dummy = snd_pcm_substream_chip(substream);
-	dummy->timer_ops->free(substream);
+	get_dummy_ops(substream)->free(substream);
 	return 0;
 }
 
--- zfcpdump-kernel-4.4.orig/sound/firewire/bebob/bebob_stream.c
+++ zfcpdump-kernel-4.4/sound/firewire/bebob/bebob_stream.c
@@ -47,14 +47,16 @@ static const unsigned int bridgeco_freq_
 	[6] = 0x07,
 };
 
-static unsigned int
-get_formation_index(unsigned int rate)
+static int
+get_formation_index(unsigned int rate, unsigned int *index)
 {
 	unsigned int i;
 
 	for (i = 0; i < ARRAY_SIZE(snd_bebob_rate_table); i++) {
-		if (snd_bebob_rate_table[i] == rate)
-			return i;
+		if (snd_bebob_rate_table[i] == rate) {
+			*index = i;
+			return 0;
+		}
 	}
 	return -EINVAL;
 }
@@ -425,7 +427,9 @@ make_both_connections(struct snd_bebob *
 		goto end;
 
 	/* confirm params for both streams */
-	index = get_formation_index(rate);
+	err = get_formation_index(rate, &index);
+	if (err < 0)
+		goto end;
 	pcm_channels = bebob->tx_stream_formations[index].pcm;
 	midi_channels = bebob->tx_stream_formations[index].midi;
 	err = amdtp_am824_set_parameters(&bebob->tx_stream, rate,
--- zfcpdump-kernel-4.4.orig/sound/firewire/fireworks/fireworks.h
+++ zfcpdump-kernel-4.4/sound/firewire/fireworks/fireworks.h
@@ -106,7 +106,6 @@ struct snd_efw {
 	u8 *resp_buf;
 	u8 *pull_ptr;
 	u8 *push_ptr;
-	unsigned int resp_queues;
 };
 
 int snd_efw_transaction_cmd(struct fw_unit *unit,
--- zfcpdump-kernel-4.4.orig/sound/firewire/fireworks/fireworks_hwdep.c
+++ zfcpdump-kernel-4.4/sound/firewire/fireworks/fireworks_hwdep.c
@@ -25,6 +25,7 @@ hwdep_read_resp_buf(struct snd_efw *efw,
 {
 	unsigned int length, till_end, type;
 	struct snd_efw_transaction *t;
+	u8 *pull_ptr;
 	long count = 0;
 
 	if (remained < sizeof(type) + sizeof(struct snd_efw_transaction))
@@ -38,8 +39,17 @@ hwdep_read_resp_buf(struct snd_efw *efw,
 	buf += sizeof(type);
 
 	/* write into buffer as many responses as possible */
-	while (efw->resp_queues > 0) {
-		t = (struct snd_efw_transaction *)(efw->pull_ptr);
+	spin_lock_irq(&efw->lock);
+
+	/*
+	 * When another task reaches here during this task's access to user
+	 * space, it picks up current position in buffer and can read the same
+	 * series of responses.
+	 */
+	pull_ptr = efw->pull_ptr;
+
+	while (efw->push_ptr != pull_ptr) {
+		t = (struct snd_efw_transaction *)(pull_ptr);
 		length = be32_to_cpu(t->length) * sizeof(__be32);
 
 		/* confirm enough space for this response */
@@ -49,26 +59,39 @@ hwdep_read_resp_buf(struct snd_efw *efw,
 		/* copy from ring buffer to user buffer */
 		while (length > 0) {
 			till_end = snd_efw_resp_buf_size -
-				(unsigned int)(efw->pull_ptr - efw->resp_buf);
+				(unsigned int)(pull_ptr - efw->resp_buf);
 			till_end = min_t(unsigned int, length, till_end);
 
-			if (copy_to_user(buf, efw->pull_ptr, till_end))
+			spin_unlock_irq(&efw->lock);
+
+			if (copy_to_user(buf, pull_ptr, till_end))
 				return -EFAULT;
 
-			efw->pull_ptr += till_end;
-			if (efw->pull_ptr >= efw->resp_buf +
-					     snd_efw_resp_buf_size)
-				efw->pull_ptr -= snd_efw_resp_buf_size;
+			spin_lock_irq(&efw->lock);
+
+			pull_ptr += till_end;
+			if (pull_ptr >= efw->resp_buf + snd_efw_resp_buf_size)
+				pull_ptr -= snd_efw_resp_buf_size;
 
 			length -= till_end;
 			buf += till_end;
 			count += till_end;
 			remained -= till_end;
 		}
-
-		efw->resp_queues--;
 	}
 
+	/*
+	 * All of tasks can read from the buffer nearly simultaneously, but the
+	 * last position for each task is different depending on the length of
+	 * given buffer. Here, for simplicity, a position of buffer is set by
+	 * the latest task. It's better for a listening application to allow one
+	 * thread to read from the buffer. Unless, each task can read different
+	 * sequence of responses depending on variation of buffer length.
+	 */
+	efw->pull_ptr = pull_ptr;
+
+	spin_unlock_irq(&efw->lock);
+
 	return count;
 }
 
@@ -76,14 +99,17 @@ static long
 hwdep_read_locked(struct snd_efw *efw, char __user *buf, long count,
 		  loff_t *offset)
 {
-	union snd_firewire_event event;
+	union snd_firewire_event event = {
+		.lock_status.type = SNDRV_FIREWIRE_EVENT_LOCK_STATUS,
+	};
 
-	memset(&event, 0, sizeof(event));
+	spin_lock_irq(&efw->lock);
 
-	event.lock_status.type = SNDRV_FIREWIRE_EVENT_LOCK_STATUS;
 	event.lock_status.status = (efw->dev_lock_count > 0);
 	efw->dev_lock_changed = false;
 
+	spin_unlock_irq(&efw->lock);
+
 	count = min_t(long, count, sizeof(event.lock_status));
 
 	if (copy_to_user(buf, &event, count))
@@ -98,10 +124,15 @@ hwdep_read(struct snd_hwdep *hwdep, char
 {
 	struct snd_efw *efw = hwdep->private_data;
 	DEFINE_WAIT(wait);
+	bool dev_lock_changed;
+	bool queued;
 
 	spin_lock_irq(&efw->lock);
 
-	while ((!efw->dev_lock_changed) && (efw->resp_queues == 0)) {
+	dev_lock_changed = efw->dev_lock_changed;
+	queued = efw->push_ptr != efw->pull_ptr;
+
+	while (!dev_lock_changed && !queued) {
 		prepare_to_wait(&efw->hwdep_wait, &wait, TASK_INTERRUPTIBLE);
 		spin_unlock_irq(&efw->lock);
 		schedule();
@@ -109,15 +140,17 @@ hwdep_read(struct snd_hwdep *hwdep, char
 		if (signal_pending(current))
 			return -ERESTARTSYS;
 		spin_lock_irq(&efw->lock);
+		dev_lock_changed = efw->dev_lock_changed;
+		queued = efw->push_ptr != efw->pull_ptr;
 	}
 
-	if (efw->dev_lock_changed)
+	spin_unlock_irq(&efw->lock);
+
+	if (dev_lock_changed)
 		count = hwdep_read_locked(efw, buf, count, offset);
-	else if (efw->resp_queues > 0)
+	else if (queued)
 		count = hwdep_read_resp_buf(efw, buf, count, offset);
 
-	spin_unlock_irq(&efw->lock);
-
 	return count;
 }
 
@@ -160,7 +193,7 @@ hwdep_poll(struct snd_hwdep *hwdep, stru
 	poll_wait(file, &efw->hwdep_wait, wait);
 
 	spin_lock_irq(&efw->lock);
-	if (efw->dev_lock_changed || (efw->resp_queues > 0))
+	if (efw->dev_lock_changed || efw->pull_ptr != efw->push_ptr)
 		events = POLLIN | POLLRDNORM;
 	else
 		events = 0;
--- zfcpdump-kernel-4.4.orig/sound/firewire/fireworks/fireworks_proc.c
+++ zfcpdump-kernel-4.4/sound/firewire/fireworks/fireworks_proc.c
@@ -188,8 +188,8 @@ proc_read_queues_state(struct snd_info_e
 	else
 		consumed = (unsigned int)(efw->push_ptr - efw->pull_ptr);
 
-	snd_iprintf(buffer, "%d %d/%d\n",
-		    efw->resp_queues, consumed, snd_efw_resp_buf_size);
+	snd_iprintf(buffer, "%d/%d\n",
+		    consumed, snd_efw_resp_buf_size);
 }
 
 static void
--- zfcpdump-kernel-4.4.orig/sound/firewire/fireworks/fireworks_transaction.c
+++ zfcpdump-kernel-4.4/sound/firewire/fireworks/fireworks_transaction.c
@@ -121,11 +121,11 @@ copy_resp_to_buf(struct snd_efw *efw, vo
 	size_t capacity, till_end;
 	struct snd_efw_transaction *t;
 
-	spin_lock_irq(&efw->lock);
-
 	t = (struct snd_efw_transaction *)data;
 	length = min_t(size_t, be32_to_cpu(t->length) * sizeof(u32), length);
 
+	spin_lock_irq(&efw->lock);
+
 	if (efw->push_ptr < efw->pull_ptr)
 		capacity = (unsigned int)(efw->pull_ptr - efw->push_ptr);
 	else
@@ -155,7 +155,6 @@ copy_resp_to_buf(struct snd_efw *efw, vo
 	}
 
 	/* for hwdep */
-	efw->resp_queues++;
 	wake_up(&efw->hwdep_wait);
 
 	*rcode = RCODE_COMPLETE;
--- zfcpdump-kernel-4.4.orig/sound/firewire/tascam/tascam-hwdep.c
+++ zfcpdump-kernel-4.4/sound/firewire/tascam/tascam-hwdep.c
@@ -16,31 +16,14 @@
 
 #include "tascam.h"
 
-static long hwdep_read_locked(struct snd_tscm *tscm, char __user *buf,
-			      long count)
-{
-	union snd_firewire_event event;
-
-	memset(&event, 0, sizeof(event));
-
-	event.lock_status.type = SNDRV_FIREWIRE_EVENT_LOCK_STATUS;
-	event.lock_status.status = (tscm->dev_lock_count > 0);
-	tscm->dev_lock_changed = false;
-
-	count = min_t(long, count, sizeof(event.lock_status));
-
-	if (copy_to_user(buf, &event, count))
-		return -EFAULT;
-
-	return count;
-}
-
 static long hwdep_read(struct snd_hwdep *hwdep, char __user *buf, long count,
 		       loff_t *offset)
 {
 	struct snd_tscm *tscm = hwdep->private_data;
 	DEFINE_WAIT(wait);
-	union snd_firewire_event event;
+	union snd_firewire_event event = {
+		.lock_status.type = SNDRV_FIREWIRE_EVENT_LOCK_STATUS,
+	};
 
 	spin_lock_irq(&tscm->lock);
 
@@ -54,10 +37,16 @@ static long hwdep_read(struct snd_hwdep
 		spin_lock_irq(&tscm->lock);
 	}
 
-	memset(&event, 0, sizeof(event));
-	count = hwdep_read_locked(tscm, buf, count);
+	event.lock_status.status = (tscm->dev_lock_count > 0);
+	tscm->dev_lock_changed = false;
+
 	spin_unlock_irq(&tscm->lock);
 
+	count = min_t(long, count, sizeof(event.lock_status));
+
+	if (copy_to_user(buf, &event, count))
+		return -EFAULT;
+
 	return count;
 }
 
--- zfcpdump-kernel-4.4.orig/sound/hda/array.c
+++ zfcpdump-kernel-4.4/sound/hda/array.c
@@ -21,13 +21,15 @@ void *snd_array_new(struct snd_array *ar
 		return NULL;
 	if (array->used >= array->alloced) {
 		int num = array->alloced + array->alloc_align;
+		int oldsize = array->alloced * array->elem_size;
 		int size = (num + 1) * array->elem_size;
 		void *nlist;
 		if (snd_BUG_ON(num >= 4096))
 			return NULL;
-		nlist = krealloc(array->list, size, GFP_KERNEL | __GFP_ZERO);
+		nlist = krealloc(array->list, size, GFP_KERNEL);
 		if (!nlist)
 			return NULL;
+		memset(nlist + oldsize, 0, size - oldsize);
 		array->list = nlist;
 		array->alloced = num;
 	}
--- zfcpdump-kernel-4.4.orig/sound/hda/hdac_i915.c
+++ zfcpdump-kernel-4.4/sound/hda/hdac_i915.c
@@ -170,6 +170,11 @@ static int hdac_component_master_match(s
 	return !strcmp(dev->driver->name, "i915");
 }
 
+static int hdac_component_master_match_bpo(struct device *dev, void *data)
+{
+	return !strcmp(dev->driver->name, "i915_bpo");
+}
+
 /**
  * snd_hdac_i915_register_notifier - Register i915 audio component ops
  * @aops: i915 audio component ops
@@ -246,6 +251,49 @@ out_err:
 }
 EXPORT_SYMBOL_GPL(snd_hdac_i915_init);
 
+int snd_hdac_i915_init_bpo(struct hdac_bus *bus)
+{
+	struct component_match *match = NULL;
+	struct device *dev = bus->dev;
+	struct i915_audio_component *acomp;
+	int ret;
+
+	acomp = kzalloc(sizeof(*acomp), GFP_KERNEL);
+	if (!acomp)
+		return -ENOMEM;
+	bus->audio_component = acomp;
+	hdac_acomp = acomp;
+
+	component_match_add(dev, &match, hdac_component_master_match_bpo, bus);
+	ret = component_master_add_with_match(dev, &hdac_component_master_ops,
+					      match);
+	if (ret < 0)
+		goto out_err;
+
+	/*
+	 * Atm, we don't support deferring the component binding, so make sure
+	 * i915_bpo is loaded and that the binding successfully completes.
+	 */
+	request_module("i915_bpo");
+
+	if (!acomp->ops) {
+		ret = -ENODEV;
+		goto out_master_del;
+	}
+	dev_dbg(dev, "bound to i915_bpo component master\n");
+
+	return 0;
+out_master_del:
+	component_master_del(dev, &hdac_component_master_ops);
+out_err:
+	kfree(acomp);
+	bus->audio_component = NULL;
+	dev_err(dev, "failed to add i915_bpo component master (%d)\n", ret);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(snd_hdac_i915_init_bpo);
+
 /**
  * snd_hdac_i915_exit - Finalize i915 audio component
  * @bus: HDA core bus
--- zfcpdump-kernel-4.4.orig/sound/isa/Kconfig
+++ zfcpdump-kernel-4.4/sound/isa/Kconfig
@@ -3,6 +3,7 @@
 config SND_WSS_LIB
         tristate
         select SND_PCM
+	select SND_TIMER
 
 config SND_SB_COMMON
         tristate
@@ -42,6 +43,7 @@ config SND_AD1816A
 	select SND_OPL3_LIB
 	select SND_MPU401_UART
 	select SND_PCM
+	select SND_TIMER
 	help
 	  Say Y here to include support for Analog Devices SoundPort
 	  AD1816A or compatible sound chips.
@@ -209,6 +211,7 @@ config SND_GUSCLASSIC
 	tristate "Gravis UltraSound Classic"
 	select SND_RAWMIDI
 	select SND_PCM
+	select SND_TIMER
 	help
 	  Say Y here to include support for Gravis UltraSound Classic
 	  soundcards.
@@ -221,6 +224,7 @@ config SND_GUSEXTREME
 	select SND_OPL3_LIB
 	select SND_MPU401_UART
 	select SND_PCM
+	select SND_TIMER
 	help
 	  Say Y here to include support for Gravis UltraSound Extreme
 	  soundcards.
--- zfcpdump-kernel-4.4.orig/sound/pci/Kconfig
+++ zfcpdump-kernel-4.4/sound/pci/Kconfig
@@ -155,6 +155,7 @@ config SND_AZT3328
 	select SND_PCM
 	select SND_RAWMIDI
 	select SND_AC97_CODEC
+	select SND_TIMER
 	depends on ZONE_DMA
 	help
 	  Say Y here to include support for Aztech AZF3328 (PCI168)
@@ -463,6 +464,7 @@ config SND_EMU10K1
 	select SND_HWDEP
 	select SND_RAWMIDI
 	select SND_AC97_CODEC
+	select SND_TIMER
 	depends on ZONE_DMA
 	help
 	  Say Y to include support for Sound Blaster PCI 512, Live!,
@@ -889,6 +891,7 @@ config SND_YMFPCI
 	select SND_OPL3_LIB
 	select SND_MPU401_UART
 	select SND_AC97_CODEC
+	select SND_TIMER
 	help
 	  Say Y here to include support for Yamaha PCI audio chips -
 	  YMF724, YMF724F, YMF740, YMF740C, YMF744, YMF754.
--- zfcpdump-kernel-4.4.orig/sound/pci/au88x0/au88x0_core.c
+++ zfcpdump-kernel-4.4/sound/pci/au88x0/au88x0_core.c
@@ -1444,9 +1444,8 @@ static int vortex_wtdma_bufshift(vortex_
 	int page, p, pp, delta, i;
 
 	page =
-	    (hwread(vortex->mmio, VORTEX_WTDMA_STAT + (wtdma << 2)) &
-	     WT_SUBBUF_MASK)
-	    >> WT_SUBBUF_SHIFT;
+	    (hwread(vortex->mmio, VORTEX_WTDMA_STAT + (wtdma << 2))
+	     >> WT_SUBBUF_SHIFT) & WT_SUBBUF_MASK;
 	if (dma->nr_periods >= 4)
 		delta = (page - dma->period_real) & 3;
 	else {
--- zfcpdump-kernel-4.4.orig/sound/pci/echoaudio/echoaudio.c
+++ zfcpdump-kernel-4.4/sound/pci/echoaudio/echoaudio.c
@@ -2200,11 +2200,11 @@ static int snd_echo_resume(struct device
 	u32 pipe_alloc_mask;
 	int err;
 
-	commpage_bak = kmalloc(sizeof(struct echoaudio), GFP_KERNEL);
+	commpage_bak = kmalloc(sizeof(*commpage), GFP_KERNEL);
 	if (commpage_bak == NULL)
 		return -ENOMEM;
 	commpage = chip->comm_page;
-	memcpy(commpage_bak, commpage, sizeof(struct comm_page));
+	memcpy(commpage_bak, commpage, sizeof(*commpage));
 
 	err = init_hw(chip, chip->pci->device, chip->pci->subsystem_device);
 	if (err < 0) {
--- zfcpdump-kernel-4.4.orig/sound/pci/hda/hda_bind.c
+++ zfcpdump-kernel-4.4/sound/pci/hda/hda_bind.c
@@ -174,14 +174,40 @@ static inline bool codec_probed(struct h
 	return device_attach(hda_codec_dev(codec)) > 0 && codec->preset;
 }
 
-/* try to auto-load and bind the codec module */
-static void codec_bind_module(struct hda_codec *codec)
+/* try to auto-load codec module */
+static void request_codec_module(struct hda_codec *codec)
 {
 #ifdef MODULE
 	char modalias[32];
+	const char *mod = NULL;
+
+	switch (codec->probe_id) {
+	case HDA_CODEC_ID_GENERIC_HDMI:
+#if IS_MODULE(CONFIG_SND_HDA_CODEC_HDMI)
+		mod = "snd-hda-codec-hdmi";
+#endif
+		break;
+	case HDA_CODEC_ID_GENERIC:
+#if IS_MODULE(CONFIG_SND_HDA_GENERIC)
+		mod = "snd-hda-codec-generic";
+#endif
+		break;
+	default:
+		snd_hdac_codec_modalias(&codec->core, modalias, sizeof(modalias));
+		mod = modalias;
+		break;
+	}
+
+	if (mod)
+		request_module(mod);
+#endif /* MODULE */
+}
 
-	snd_hdac_codec_modalias(&codec->core, modalias, sizeof(modalias));
-	request_module(modalias);
+/* try to auto-load and bind the codec module */
+static void codec_bind_module(struct hda_codec *codec)
+{
+#ifdef MODULE
+	request_codec_module(codec);
 	if (codec_probed(codec))
 		return;
 #endif
@@ -218,17 +244,13 @@ static int codec_bind_generic(struct hda
 
 	if (is_likely_hdmi_codec(codec)) {
 		codec->probe_id = HDA_CODEC_ID_GENERIC_HDMI;
-#if IS_MODULE(CONFIG_SND_HDA_CODEC_HDMI)
-		request_module("snd-hda-codec-hdmi");
-#endif
+		request_codec_module(codec);
 		if (codec_probed(codec))
 			return 0;
 	}
 
 	codec->probe_id = HDA_CODEC_ID_GENERIC;
-#if IS_MODULE(CONFIG_SND_HDA_GENERIC)
-	request_module("snd-hda-codec-generic");
-#endif
+	request_codec_module(codec);
 	if (codec_probed(codec))
 		return 0;
 	return -ENODEV;
--- zfcpdump-kernel-4.4.orig/sound/pci/hda/hda_generic.c
+++ zfcpdump-kernel-4.4/sound/pci/hda/hda_generic.c
@@ -771,9 +771,6 @@ static void activate_amp(struct hda_code
 	unsigned int caps;
 	unsigned int mask, val;
 
-	if (!enable && is_active_nid(codec, nid, dir, idx_to_check))
-		return;
-
 	caps = query_amp_caps(codec, nid, dir);
 	val = get_amp_val_to_activate(codec, nid, dir, caps, enable);
 	mask = get_amp_mask_to_modify(codec, nid, dir, idx_to_check, caps);
@@ -784,12 +781,22 @@ static void activate_amp(struct hda_code
 	update_amp(codec, nid, dir, idx, mask, val);
 }
 
+static void check_and_activate_amp(struct hda_codec *codec, hda_nid_t nid,
+				   int dir, int idx, int idx_to_check,
+				   bool enable)
+{
+	/* check whether the given amp is still used by others */
+	if (!enable && is_active_nid(codec, nid, dir, idx_to_check))
+		return;
+	activate_amp(codec, nid, dir, idx, idx_to_check, enable);
+}
+
 static void activate_amp_out(struct hda_codec *codec, struct nid_path *path,
 			     int i, bool enable)
 {
 	hda_nid_t nid = path->path[i];
 	init_amp(codec, nid, HDA_OUTPUT, 0);
-	activate_amp(codec, nid, HDA_OUTPUT, 0, 0, enable);
+	check_and_activate_amp(codec, nid, HDA_OUTPUT, 0, 0, enable);
 }
 
 static void activate_amp_in(struct hda_codec *codec, struct nid_path *path,
@@ -817,9 +824,16 @@ static void activate_amp_in(struct hda_c
 	 * when aa-mixer is available, we need to enable the path as well
 	 */
 	for (n = 0; n < nums; n++) {
-		if (n != idx && (!add_aamix || conn[n] != spec->mixer_merge_nid))
-			continue;
-		activate_amp(codec, nid, HDA_INPUT, n, idx, enable);
+		if (n != idx) {
+			if (conn[n] != spec->mixer_merge_nid)
+				continue;
+			/* when aamix is disabled, force to off */
+			if (!add_aamix) {
+				activate_amp(codec, nid, HDA_INPUT, n, n, false);
+				continue;
+			}
+		}
+		check_and_activate_amp(codec, nid, HDA_INPUT, n, idx, enable);
 	}
 }
 
@@ -829,7 +843,7 @@ static hda_nid_t path_power_update(struc
 				   bool allow_powerdown)
 {
 	hda_nid_t nid, changed = 0;
-	int i, state;
+	int i, state, power;
 
 	for (i = 0; i < path->depth; i++) {
 		nid = path->path[i];
@@ -841,7 +855,9 @@ static hda_nid_t path_power_update(struc
 			state = AC_PWRST_D0;
 		else
 			state = AC_PWRST_D3;
-		if (!snd_hda_check_power_state(codec, nid, state)) {
+		power = snd_hda_codec_read(codec, nid, 0,
+					   AC_VERB_GET_POWER_STATE, 0);
+		if (power != (state | (state << 4))) {
 			snd_hda_codec_write(codec, nid, 0,
 					    AC_VERB_SET_POWER_STATE, state);
 			changed = nid;
@@ -1580,6 +1596,12 @@ static bool map_singles(struct hda_codec
 	return found;
 }
 
+static inline bool has_aamix_out_paths(struct hda_gen_spec *spec)
+{
+	return spec->aamix_out_paths[0] || spec->aamix_out_paths[1] ||
+		spec->aamix_out_paths[2];
+}
+
 /* create a new path including aamix if available, and return its index */
 static int check_aamix_out_path(struct hda_codec *codec, int path_idx)
 {
@@ -2422,25 +2444,51 @@ static void update_aamix_paths(struct hd
 	}
 }
 
+/* re-initialize the output paths; only called from loopback_mixing_put() */
+static void update_output_paths(struct hda_codec *codec, int num_outs,
+				const int *paths)
+{
+	struct hda_gen_spec *spec = codec->spec;
+	struct nid_path *path;
+	int i;
+
+	for (i = 0; i < num_outs; i++) {
+		path = snd_hda_get_path_from_idx(codec, paths[i]);
+		if (path)
+			snd_hda_activate_path(codec, path, path->active,
+					      spec->aamix_mode);
+	}
+}
+
 static int loopback_mixing_put(struct snd_kcontrol *kcontrol,
 			       struct snd_ctl_elem_value *ucontrol)
 {
 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 	struct hda_gen_spec *spec = codec->spec;
+	const struct auto_pin_cfg *cfg = &spec->autocfg;
 	unsigned int val = ucontrol->value.enumerated.item[0];
 
 	if (val == spec->aamix_mode)
 		return 0;
 	spec->aamix_mode = val;
-	update_aamix_paths(codec, val, spec->out_paths[0],
-			   spec->aamix_out_paths[0],
-			   spec->autocfg.line_out_type);
-	update_aamix_paths(codec, val, spec->hp_paths[0],
-			   spec->aamix_out_paths[1],
-			   AUTO_PIN_HP_OUT);
-	update_aamix_paths(codec, val, spec->speaker_paths[0],
-			   spec->aamix_out_paths[2],
-			   AUTO_PIN_SPEAKER_OUT);
+	if (has_aamix_out_paths(spec)) {
+		update_aamix_paths(codec, val, spec->out_paths[0],
+				   spec->aamix_out_paths[0],
+				   cfg->line_out_type);
+		update_aamix_paths(codec, val, spec->hp_paths[0],
+				   spec->aamix_out_paths[1],
+				   AUTO_PIN_HP_OUT);
+		update_aamix_paths(codec, val, spec->speaker_paths[0],
+				   spec->aamix_out_paths[2],
+				   AUTO_PIN_SPEAKER_OUT);
+	} else {
+		update_output_paths(codec, cfg->line_outs, spec->out_paths);
+		if (cfg->line_out_type != AUTO_PIN_HP_OUT)
+			update_output_paths(codec, cfg->hp_outs, spec->hp_paths);
+		if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT)
+			update_output_paths(codec, cfg->speaker_outs,
+					    spec->speaker_paths);
+	}
 	return 1;
 }
 
@@ -2458,12 +2506,13 @@ static int create_loopback_mixing_ctl(st
 
 	if (!spec->mixer_nid)
 		return 0;
-	if (!(spec->aamix_out_paths[0] || spec->aamix_out_paths[1] ||
-	      spec->aamix_out_paths[2]))
-		return 0;
 	if (!snd_hda_gen_add_kctl(spec, NULL, &loopback_mixing_enum))
 		return -ENOMEM;
 	spec->have_aamix_ctl = 1;
+	/* if no explicit aamix path is present (e.g. for Realtek codecs),
+	 * enable aamix as default -- just for compatibility
+	 */
+	spec->aamix_mode = !has_aamix_out_paths(spec);
 	return 0;
 }
 
@@ -3945,6 +3994,8 @@ static hda_nid_t set_path_power(struct h
 
 	for (n = 0; n < spec->paths.used; n++) {
 		path = snd_array_elem(&spec->paths, n);
+		if (!path->depth)
+			continue;
 		if (path->path[0] == nid ||
 		    path->path[path->depth - 1] == nid) {
 			bool pin_old = path->pin_enabled;
@@ -3998,9 +4049,9 @@ static void pin_power_callback(struct hd
 			       struct hda_jack_callback *jack,
 			       bool on)
 {
-	if (jack && jack->tbl->nid)
+	if (jack && jack->nid)
 		sync_power_state_change(codec,
-					set_pin_power_jack(codec, jack->tbl->nid, on));
+					set_pin_power_jack(codec, jack->nid, on));
 }
 
 /* callback only doing power up -- called at first */
@@ -5664,6 +5715,8 @@ static void init_aamix_paths(struct hda_
 
 	if (!spec->have_aamix_ctl)
 		return;
+	if (!has_aamix_out_paths(spec))
+		return;
 	update_aamix_paths(codec, spec->aamix_mode, spec->out_paths[0],
 			   spec->aamix_out_paths[0],
 			   spec->autocfg.line_out_type);
--- zfcpdump-kernel-4.4.orig/sound/pci/hda/hda_intel.c
+++ zfcpdump-kernel-4.4/sound/pci/hda/hda_intel.c
@@ -90,6 +90,8 @@ enum {
 #define NVIDIA_HDA_ENABLE_COHBIT      0x01
 
 /* Defines for Intel SCH HDA snoop control */
+#define INTEL_HDA_CGCTL	 0x48
+#define INTEL_HDA_CGCTL_MISCBDCGE        (0x1 << 6)
 #define INTEL_SCH_HDA_DEVC      0x78
 #define INTEL_SCH_HDA_DEVC_NOSNOOP       (0x1<<11)
 
@@ -355,7 +357,14 @@ enum {
 					((pci)->device == 0x0d0c) || \
 					((pci)->device == 0x160c))
 
-#define IS_BROXTON(pci)	((pci)->device == 0x5a98)
+#define IS_SKL(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0xa170)
+#define IS_SKL_LP(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0x9d70)
+#define IS_KBL(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0xa171)
+#define IS_KBL_LP(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0x9d71)
+#define IS_KBL_H(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0xa2f0)
+#define IS_BXT(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0x5a98)
+#define IS_SKL_PLUS(pci) (IS_SKL(pci) || IS_SKL_LP(pci) || IS_BXT(pci)) || \
+			IS_KBL(pci) || IS_KBL_LP(pci) || IS_KBL_H(pci)
 
 static char *driver_short_names[] = {
 	[AZX_DRIVER_ICH] = "HDA Intel",
@@ -528,15 +537,26 @@ static void hda_intel_init_chip(struct a
 {
 	struct hdac_bus *bus = azx_bus(chip);
 	struct pci_dev *pci = chip->pci;
+	u32 val;
 
 	if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL)
 		snd_hdac_set_codec_wakeup(bus, true);
+	if (IS_SKL_PLUS(pci)) {
+		pci_read_config_dword(pci, INTEL_HDA_CGCTL, &val);
+		val = val & ~INTEL_HDA_CGCTL_MISCBDCGE;
+		pci_write_config_dword(pci, INTEL_HDA_CGCTL, val);
+	}
 	azx_init_chip(chip, full_reset);
+	if (IS_SKL_PLUS(pci)) {
+		pci_read_config_dword(pci, INTEL_HDA_CGCTL, &val);
+		val = val | INTEL_HDA_CGCTL_MISCBDCGE;
+		pci_write_config_dword(pci, INTEL_HDA_CGCTL, val);
+	}
 	if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL)
 		snd_hdac_set_codec_wakeup(bus, false);
 
 	/* reduce dma latency to avoid noise */
-	if (IS_BROXTON(pci))
+	if (IS_BXT(pci))
 		bxt_reduce_dma_latency(chip);
 }
 
@@ -924,20 +944,23 @@ static int azx_resume(struct device *dev
 	struct snd_card *card = dev_get_drvdata(dev);
 	struct azx *chip;
 	struct hda_intel *hda;
+	struct hdac_bus *bus;
 
 	if (!card)
 		return 0;
 
 	chip = card->private_data;
 	hda = container_of(chip, struct hda_intel, chip);
+	bus = azx_bus(chip);
 	if (chip->disabled || hda->init_failed || !chip->running)
 		return 0;
 
-	if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL
-		&& hda->need_i915_power) {
-		snd_hdac_display_power(azx_bus(chip), true);
-		haswell_set_bclk(hda);
+	if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL) {
+		snd_hdac_display_power(bus, true);
+		if (hda->need_i915_power)
+			haswell_set_bclk(hda);
 	}
+
 	if (chip->msi)
 		if (pci_enable_msi(pci) < 0)
 			chip->msi = 0;
@@ -947,6 +970,11 @@ static int azx_resume(struct device *dev
 
 	hda_intel_init_chip(chip, true);
 
+	/* power down again for link-controlled chips */
+	if ((chip->driver_caps & AZX_DCAPS_I915_POWERWELL) &&
+	    !hda->need_i915_power)
+		snd_hdac_display_power(bus, false);
+
 	snd_power_change_state(card, SNDRV_CTL_POWER_D0);
 
 	trace_azx_resume(chip);
@@ -958,11 +986,6 @@ static int azx_resume(struct device *dev
 /* put codec down to D3 at hibernation for Intel SKL+;
  * otherwise BIOS may still access the codec and screw up the driver
  */
-#define IS_SKL(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0xa170)
-#define IS_SKL_LP(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0x9d70)
-#define IS_BXT(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0x5a98)
-#define IS_SKL_PLUS(pci) (IS_SKL(pci) || IS_SKL_LP(pci) || IS_BXT(pci))
-
 static int azx_freeze_noirq(struct device *dev)
 {
 	struct pci_dev *pci = to_pci_dev(dev);
@@ -1031,6 +1054,7 @@ static int azx_runtime_resume(struct dev
 
 	chip = card->private_data;
 	hda = container_of(chip, struct hda_intel, chip);
+	bus = azx_bus(chip);
 	if (chip->disabled || hda->init_failed)
 		return 0;
 
@@ -1038,15 +1062,9 @@ static int azx_runtime_resume(struct dev
 		return 0;
 
 	if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL) {
-		bus = azx_bus(chip);
-		if (hda->need_i915_power) {
-			snd_hdac_display_power(bus, true);
+		snd_hdac_display_power(bus, true);
+		if (hda->need_i915_power)
 			haswell_set_bclk(hda);
-		} else {
-			/* toggle codec wakeup bit for STATESTS read */
-			snd_hdac_set_codec_wakeup(bus, true);
-			snd_hdac_set_codec_wakeup(bus, false);
-		}
 	}
 
 	/* Read STATESTS before controller reset */
@@ -1066,6 +1084,11 @@ static int azx_runtime_resume(struct dev
 	azx_writew(chip, WAKEEN, azx_readw(chip, WAKEEN) &
 			~STATESTS_INT_MASK);
 
+	/* power down again for link-controlled chips */
+	if ((chip->driver_caps & AZX_DCAPS_I915_POWERWELL) &&
+	    !hda->need_i915_power)
+		snd_hdac_display_power(bus, false);
+
 	trace_azx_runtime_resume(chip);
 	return 0;
 }
@@ -1241,8 +1264,10 @@ static int azx_free(struct azx *chip)
 	if (use_vga_switcheroo(hda)) {
 		if (chip->disabled && hda->probe_continued)
 			snd_hda_unlock_devices(&chip->bus);
-		if (hda->vga_switcheroo_registered)
+		if (hda->vga_switcheroo_registered) {
 			vga_switcheroo_unregister_client(chip->pci);
+			vga_switcheroo_fini_domain_pm_ops(chip->card->dev);
+		}
 	}
 
 	if (bus->chip_init) {
@@ -2048,7 +2073,12 @@ static int azx_probe_continue(struct azx
 		if (CONTROLLER_IN_GPU(pci))
 			hda->need_i915_power = 1;
 
-		err = snd_hdac_i915_init(bus);
+		if (((chip->driver_caps & AZX_DCAPS_INTEL_SKYLAKE) == AZX_DCAPS_INTEL_SKYLAKE) || \
+			((chip->driver_caps & AZX_DCAPS_INTEL_BROXTON) == AZX_DCAPS_INTEL_BROXTON))
+			err = snd_hdac_i915_init_bpo(bus);
+		else
+			err = snd_hdac_i915_init(bus);
+
 		if (err < 0) {
 			/* if the controller is bound only with HDMI/DP
 			 * (for HSW and BDW), we need to abort the probe;
@@ -2126,9 +2156,17 @@ i915_power_fail:
 static void azx_remove(struct pci_dev *pci)
 {
 	struct snd_card *card = pci_get_drvdata(pci);
+	struct azx *chip;
+	struct hda_intel *hda;
+
+	if (card) {
+		/* cancel the pending probing work */
+		chip = card->private_data;
+		hda = container_of(chip, struct hda_intel, chip);
+		cancel_work_sync(&hda->probe_work);
 
-	if (card)
 		snd_card_free(card);
+	}
 }
 
 static void azx_shutdown(struct pci_dev *pci)
@@ -2185,9 +2223,21 @@ static const struct pci_device_id azx_id
 	/* Sunrise Point-LP */
 	{ PCI_DEVICE(0x8086, 0x9d70),
 	  .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_SKYLAKE },
+	/* Kabylake */
+	{ PCI_DEVICE(0x8086, 0xa171),
+	  .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_SKYLAKE },
+	/* Kabylake-LP */
+	{ PCI_DEVICE(0x8086, 0x9d71),
+	  .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_SKYLAKE },
+	/* Kabylake-H */
+	{ PCI_DEVICE(0x8086, 0xa2f0),
+	  .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_SKYLAKE },
 	/* Broxton-P(Apollolake) */
 	{ PCI_DEVICE(0x8086, 0x5a98),
 	  .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_BROXTON },
+	/* Broxton-T */
+	{ PCI_DEVICE(0x8086, 0x1a98),
+	  .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_BROXTON },
 	/* Haswell */
 	{ PCI_DEVICE(0x8086, 0x0a0c),
 	  .driver_data = AZX_DRIVER_HDMI | AZX_DCAPS_INTEL_HASWELL },
@@ -2251,10 +2301,14 @@ static const struct pci_device_id azx_id
 	{ PCI_DEVICE(0x1022, 0x780d),
 	  .driver_data = AZX_DRIVER_GENERIC | AZX_DCAPS_PRESET_ATI_SB },
 	/* ATI HDMI */
+	{ PCI_DEVICE(0x1002, 0x0002),
+	  .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS },
 	{ PCI_DEVICE(0x1002, 0x1308),
 	  .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS },
 	{ PCI_DEVICE(0x1002, 0x157a),
 	  .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS },
+	{ PCI_DEVICE(0x1002, 0x15b3),
+	  .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS },
 	{ PCI_DEVICE(0x1002, 0x793b),
 	  .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
 	{ PCI_DEVICE(0x1002, 0x7919),
@@ -2317,6 +2371,10 @@ static const struct pci_device_id azx_id
 	  .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS },
 	{ PCI_DEVICE(0x1002, 0xaae8),
 	  .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS },
+	{ PCI_DEVICE(0x1002, 0xaae0),
+	  .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS },
+	{ PCI_DEVICE(0x1002, 0xaaf0),
+	  .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS },
 	/* VIA VT8251/VT8237A */
 	{ PCI_DEVICE(0x1106, 0x3288),
 	  .driver_data = AZX_DRIVER_VIA | AZX_DCAPS_POSFIX_VIA },
--- zfcpdump-kernel-4.4.orig/sound/pci/hda/hda_jack.c
+++ zfcpdump-kernel-4.4/sound/pci/hda/hda_jack.c
@@ -259,7 +259,7 @@ snd_hda_jack_detect_enable_callback(stru
 		if (!callback)
 			return ERR_PTR(-ENOMEM);
 		callback->func = func;
-		callback->tbl = jack;
+		callback->nid = jack->nid;
 		callback->next = jack->callback;
 		jack->callback = callback;
 	}
--- zfcpdump-kernel-4.4.orig/sound/pci/hda/hda_jack.h
+++ zfcpdump-kernel-4.4/sound/pci/hda/hda_jack.h
@@ -21,7 +21,7 @@ struct hda_jack_callback;
 typedef void (*hda_jack_callback_fn) (struct hda_codec *, struct hda_jack_callback *);
 
 struct hda_jack_callback {
-	struct hda_jack_tbl *tbl;
+	hda_nid_t nid;
 	hda_jack_callback_fn func;
 	unsigned int private_data;	/* arbitrary data */
 	struct hda_jack_callback *next;
--- zfcpdump-kernel-4.4.orig/sound/pci/hda/hda_sysfs.c
+++ zfcpdump-kernel-4.4/sound/pci/hda/hda_sysfs.c
@@ -141,14 +141,6 @@ static int reconfig_codec(struct hda_cod
 	err = snd_hda_codec_configure(codec);
 	if (err < 0)
 		goto error;
-	/* rebuild PCMs */
-	err = snd_hda_codec_build_pcms(codec);
-	if (err < 0)
-		goto error;
-	/* rebuild mixers */
-	err = snd_hda_codec_build_controls(codec);
-	if (err < 0)
-		goto error;
 	err = snd_card_register(codec->card);
  error:
 	snd_hda_power_down(codec);
--- zfcpdump-kernel-4.4.orig/sound/pci/hda/patch_ca0132.c
+++ zfcpdump-kernel-4.4/sound/pci/hda/patch_ca0132.c
@@ -4427,13 +4427,16 @@ static void ca0132_process_dsp_response(
 static void hp_callback(struct hda_codec *codec, struct hda_jack_callback *cb)
 {
 	struct ca0132_spec *spec = codec->spec;
+	struct hda_jack_tbl *tbl;
 
 	/* Delay enabling the HP amp, to let the mic-detection
 	 * state machine run.
 	 */
 	cancel_delayed_work_sync(&spec->unsol_hp_work);
 	schedule_delayed_work(&spec->unsol_hp_work, msecs_to_jiffies(500));
-	cb->tbl->block_report = 1;
+	tbl = snd_hda_jack_tbl_get(codec, cb->nid);
+	if (tbl)
+		tbl->block_report = 1;
 }
 
 static void amic_callback(struct hda_codec *codec, struct hda_jack_callback *cb)
--- zfcpdump-kernel-4.4.orig/sound/pci/hda/patch_cirrus.c
+++ zfcpdump-kernel-4.4/sound/pci/hda/patch_cirrus.c
@@ -174,8 +174,12 @@ static void cs_automute(struct hda_codec
 	snd_hda_gen_update_outputs(codec);
 
 	if (spec->gpio_eapd_hp || spec->gpio_eapd_speaker) {
-		spec->gpio_data = spec->gen.hp_jack_present ?
-			spec->gpio_eapd_hp : spec->gpio_eapd_speaker;
+		if (spec->gen.automute_speaker)
+			spec->gpio_data = spec->gen.hp_jack_present ?
+				spec->gpio_eapd_hp : spec->gpio_eapd_speaker;
+		else
+			spec->gpio_data =
+				spec->gpio_eapd_hp | spec->gpio_eapd_speaker;
 		snd_hda_codec_write(codec, 0x01, 0,
 				    AC_VERB_SET_GPIO_DATA, spec->gpio_data);
 	}
@@ -357,6 +361,7 @@ static int cs_parse_auto_config(struct h
 {
 	struct cs_spec *spec = codec->spec;
 	int err;
+	int i;
 
 	err = snd_hda_parse_pin_defcfg(codec, &spec->gen.autocfg, NULL, 0);
 	if (err < 0)
@@ -366,6 +371,19 @@ static int cs_parse_auto_config(struct h
 	if (err < 0)
 		return err;
 
+	/* keep the ADCs powered up when it's dynamically switchable */
+	if (spec->gen.dyn_adc_switch) {
+		unsigned int done = 0;
+		for (i = 0; i < spec->gen.input_mux.num_items; i++) {
+			int idx = spec->gen.dyn_adc_idx[i];
+			if (done & (1 << idx))
+				continue;
+			snd_hda_gen_fix_pin_power(codec,
+						  spec->gen.adc_nids[idx]);
+			done |= 1 << idx;
+		}
+	}
+
 	return 0;
 }
 
@@ -614,6 +632,7 @@ enum {
 	CS4208_MAC_AUTO,
 	CS4208_MBA6,
 	CS4208_MBP11,
+	CS4208_MACMINI,
 	CS4208_GPIO0,
 };
 
@@ -621,6 +640,7 @@ static const struct hda_model_fixup cs42
 	{ .id = CS4208_GPIO0, .name = "gpio0" },
 	{ .id = CS4208_MBA6, .name = "mba6" },
 	{ .id = CS4208_MBP11, .name = "mbp11" },
+	{ .id = CS4208_MACMINI, .name = "macmini" },
 	{}
 };
 
@@ -632,6 +652,7 @@ static const struct snd_pci_quirk cs4208
 /* codec SSID matching */
 static const struct snd_pci_quirk cs4208_mac_fixup_tbl[] = {
 	SND_PCI_QUIRK(0x106b, 0x5e00, "MacBookPro 11,2", CS4208_MBP11),
+	SND_PCI_QUIRK(0x106b, 0x6c00, "MacMini 7,1", CS4208_MACMINI),
 	SND_PCI_QUIRK(0x106b, 0x7100, "MacBookAir 6,1", CS4208_MBA6),
 	SND_PCI_QUIRK(0x106b, 0x7200, "MacBookAir 6,2", CS4208_MBA6),
 	SND_PCI_QUIRK(0x106b, 0x7b00, "MacBookPro 12,1", CS4208_MBP11),
@@ -666,6 +687,24 @@ static void cs4208_fixup_mac(struct hda_
 	snd_hda_apply_fixup(codec, action);
 }
 
+/* MacMini 7,1 has the inverted jack detection */
+static void cs4208_fixup_macmini(struct hda_codec *codec,
+				 const struct hda_fixup *fix, int action)
+{
+	static const struct hda_pintbl pincfgs[] = {
+		{ 0x18, 0x00ab9150 }, /* mic (audio-in) jack: disable detect */
+		{ 0x21, 0x004be140 }, /* SPDIF: disable detect */
+		{ }
+	};
+
+	if (action == HDA_FIXUP_ACT_PRE_PROBE) {
+		/* HP pin (0x10) has an inverted detection */
+		codec->inv_jack_detect = 1;
+		/* disable the bogus Mic and SPDIF jack detections */
+		snd_hda_apply_pincfgs(codec, pincfgs);
+	}
+}
+
 static int cs4208_spdif_sw_put(struct snd_kcontrol *kcontrol,
 			       struct snd_ctl_elem_value *ucontrol)
 {
@@ -709,6 +748,12 @@ static const struct hda_fixup cs4208_fix
 		.chained = true,
 		.chain_id = CS4208_GPIO0,
 	},
+	[CS4208_MACMINI] = {
+		.type = HDA_FIXUP_FUNC,
+		.v.func = cs4208_fixup_macmini,
+		.chained = true,
+		.chain_id = CS4208_GPIO0,
+	},
 	[CS4208_GPIO0] = {
 		.type = HDA_FIXUP_FUNC,
 		.v.func = cs4208_fixup_gpio0,
--- zfcpdump-kernel-4.4.orig/sound/pci/hda/patch_conexant.c
+++ zfcpdump-kernel-4.4/sound/pci/hda/patch_conexant.c
@@ -204,8 +204,13 @@ static void cx_auto_reboot_notify(struct
 {
 	struct conexant_spec *spec = codec->spec;
 
-	if (codec->core.vendor_id != 0x14f150f2)
+	switch (codec->core.vendor_id) {
+	case 0x14f150f2: /* CX20722 */
+	case 0x14f150f4: /* CX20724 */
+		break;
+	default:
 		return;
+	}
 
 	/* Turn the CX20722 codec into D3 to avoid spurious noises
 	   from the internal speaker during (and after) reboot */
@@ -256,6 +261,7 @@ enum {
 	CXT_FIXUP_HP_530,
 	CXT_FIXUP_CAP_MIX_AMP_5047,
 	CXT_FIXUP_MUTE_LED_EAPD,
+	CXT_FIXUP_HP_SPECTRE,
 };
 
 /* for hda_fixup_thinkpad_acpi() */
@@ -760,6 +766,14 @@ static const struct hda_fixup cxt_fixups
 		.type = HDA_FIXUP_FUNC,
 		.v.func = cxt_fixup_mute_led_eapd,
 	},
+	[CXT_FIXUP_HP_SPECTRE] = {
+		.type = HDA_FIXUP_PINS,
+		.v.pins = (const struct hda_pintbl[]) {
+			/* enable NID 0x1d for the speaker on top */
+			{ 0x1d, 0x91170111 },
+			{ }
+		}
+	},
 };
 
 static const struct snd_pci_quirk cxt5045_fixups[] = {
@@ -809,6 +823,7 @@ static const struct snd_pci_quirk cxt506
 	SND_PCI_QUIRK(0x1025, 0x0543, "Acer Aspire One 522", CXT_FIXUP_STEREO_DMIC),
 	SND_PCI_QUIRK(0x1025, 0x054c, "Acer Aspire 3830TG", CXT_FIXUP_ASPIRE_DMIC),
 	SND_PCI_QUIRK(0x1025, 0x054f, "Acer Aspire 4830T", CXT_FIXUP_ASPIRE_DMIC),
+	SND_PCI_QUIRK(0x103c, 0x8174, "HP Spectre x360", CXT_FIXUP_HP_SPECTRE),
 	SND_PCI_QUIRK(0x1043, 0x138d, "Asus", CXT_FIXUP_HEADPHONE_MIC_PIN),
 	SND_PCI_QUIRK(0x152d, 0x0833, "OLPC XO-1.5", CXT_FIXUP_OLPC_XO),
 	SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo T400", CXT_PINCFG_LENOVO_TP410),
--- zfcpdump-kernel-4.4.orig/sound/pci/hda/patch_hdmi.c
+++ zfcpdump-kernel-4.4/sound/pci/hda/patch_hdmi.c
@@ -51,8 +51,10 @@ MODULE_PARM_DESC(static_hdmi_pcm, "Don't
 #define is_broadwell(codec)    ((codec)->core.vendor_id == 0x80862808)
 #define is_skylake(codec) ((codec)->core.vendor_id == 0x80862809)
 #define is_broxton(codec) ((codec)->core.vendor_id == 0x8086280a)
+#define is_kabylake(codec) ((codec)->core.vendor_id == 0x8086280b)
 #define is_haswell_plus(codec) (is_haswell(codec) || is_broadwell(codec) \
-				|| is_skylake(codec) || is_broxton(codec))
+				|| is_skylake(codec) || is_broxton(codec) \
+				|| is_kabylake(codec))
 
 #define is_valleyview(codec) ((codec)->core.vendor_id == 0x80862882)
 #define is_cherryview(codec) ((codec)->core.vendor_id == 0x80862883)
@@ -438,7 +440,8 @@ static int hdmi_eld_ctl_get(struct snd_k
 	eld = &per_pin->sink_eld;
 
 	mutex_lock(&per_pin->lock);
-	if (eld->eld_size > ARRAY_SIZE(ucontrol->value.bytes.data)) {
+	if (eld->eld_size > ARRAY_SIZE(ucontrol->value.bytes.data) ||
+	    eld->eld_size > ELD_MAX_SIZE) {
 		mutex_unlock(&per_pin->lock);
 		snd_BUG();
 		return -EINVAL;
@@ -1183,7 +1186,7 @@ static void check_presence_and_report(st
 static void jack_callback(struct hda_codec *codec,
 			  struct hda_jack_callback *jack)
 {
-	check_presence_and_report(codec, jack->tbl->nid);
+	check_presence_and_report(codec, jack->nid);
 }
 
 static void hdmi_intrinsic_event(struct hda_codec *codec, unsigned int res)
@@ -2352,11 +2355,18 @@ static void intel_pin_eld_notify(void *a
 	struct hda_codec *codec = audio_ptr;
 	int pin_nid = port + 0x04;
 
+	/* we assume only from port-B to port-D */
+	if (port < 1 || port > 3)
+		return;
+
 	/* skip notification during system suspend (but not in runtime PM);
 	 * the state will be updated at resume
 	 */
 	if (snd_power_get_state(codec->card) != SNDRV_CTL_POWER_D0)
 		return;
+	/* ditto during suspend/resume process itself */
+	if (atomic_read(&(codec)->core.in_pm))
+		return;
 
 	check_presence_and_report(codec, pin_nid);
 }
@@ -2388,13 +2398,6 @@ static int patch_generic_hdmi(struct hda
 			is_broxton(codec))
 		codec->core.link_power_control = 1;
 
-	if (is_haswell_plus(codec) || is_valleyview_plus(codec)) {
-		codec->depop_delay = 0;
-		spec->i915_audio_ops.audio_ptr = codec;
-		spec->i915_audio_ops.pin_eld_notify = intel_pin_eld_notify;
-		snd_hdac_i915_register_notifier(&spec->i915_audio_ops);
-	}
-
 	if (hdmi_parse_codec(codec) < 0) {
 		codec->spec = NULL;
 		kfree(spec);
@@ -2414,6 +2417,18 @@ static int patch_generic_hdmi(struct hda
 
 	init_channel_allocations();
 
+	if (is_haswell_plus(codec) || is_valleyview_plus(codec)) {
+		codec->depop_delay = 0;
+		spec->i915_audio_ops.audio_ptr = codec;
+		/* intel_audio_codec_enable() or intel_audio_codec_disable()
+		 * will call pin_eld_notify with using audio_ptr pointer
+		 * We need make sure audio_ptr is really setup
+		 */
+		wmb();
+		spec->i915_audio_ops.pin_eld_notify = intel_pin_eld_notify;
+		snd_hdac_i915_register_notifier(&spec->i915_audio_ops);
+	}
+
 	return 0;
 }
 
@@ -3579,6 +3594,7 @@ HDA_CODEC_ENTRY(0x80862807, "Haswell HDM
 HDA_CODEC_ENTRY(0x80862808, "Broadwell HDMI",	patch_generic_hdmi),
 HDA_CODEC_ENTRY(0x80862809, "Skylake HDMI",	patch_generic_hdmi),
 HDA_CODEC_ENTRY(0x8086280a, "Broxton HDMI",	patch_generic_hdmi),
+HDA_CODEC_ENTRY(0x8086280b, "Kabylake HDMI",	patch_generic_hdmi),
 HDA_CODEC_ENTRY(0x80862880, "CedarTrail HDMI",	patch_generic_hdmi),
 HDA_CODEC_ENTRY(0x80862882, "Valleyview2 HDMI",	patch_generic_hdmi),
 HDA_CODEC_ENTRY(0x80862883, "Braswell HDMI",	patch_generic_hdmi),
--- zfcpdump-kernel-4.4.orig/sound/pci/hda/patch_realtek.c
+++ zfcpdump-kernel-4.4/sound/pci/hda/patch_realtek.c
@@ -282,7 +282,7 @@ static void alc_update_knob_master(struc
 	uctl = kzalloc(sizeof(*uctl), GFP_KERNEL);
 	if (!uctl)
 		return;
-	val = snd_hda_codec_read(codec, jack->tbl->nid, 0,
+	val = snd_hda_codec_read(codec, jack->nid, 0,
 				 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
 	val &= HDA_AMP_VOLMASK;
 	uctl->value.integer.value[0] = val;
@@ -327,6 +327,7 @@ static void alc_fill_eapd_coef(struct hd
 	case 0x10ec0292:
 		alc_update_coef_idx(codec, 0x4, 1<<15, 0);
 		break;
+	case 0x10ec0225:
 	case 0x10ec0233:
 	case 0x10ec0255:
 	case 0x10ec0256:
@@ -334,6 +335,7 @@ static void alc_fill_eapd_coef(struct hd
 	case 0x10ec0283:
 	case 0x10ec0286:
 	case 0x10ec0288:
+	case 0x10ec0295:
 	case 0x10ec0298:
 		alc_update_coef_idx(codec, 0x10, 1<<9, 0);
 		break;
@@ -341,6 +343,14 @@ static void alc_fill_eapd_coef(struct hd
 	case 0x10ec0293:
 		alc_update_coef_idx(codec, 0xa, 1<<13, 0);
 		break;
+	case 0x10ec0234:
+	case 0x10ec0274:
+	case 0x10ec0294:
+	case 0x10ec0700:
+	case 0x10ec0701:
+	case 0x10ec0703:
+		alc_update_coef_idx(codec, 0x10, 1<<15, 0);
+		break;
 	case 0x10ec0662:
 		if ((coef & 0x00f0) == 0x0030)
 			alc_update_coef_idx(codec, 0x4, 1<<10, 0); /* EAPD Ctrl */
@@ -900,6 +910,8 @@ static struct alc_codec_rename_pci_table
 	{ 0x10ec0899, 0x1028, 0, "ALC3861" },
 	{ 0x10ec0298, 0x1028, 0, "ALC3266" },
 	{ 0x10ec0256, 0x1028, 0, "ALC3246" },
+	{ 0x10ec0225, 0x1028, 0, "ALC3253" },
+	{ 0x10ec0295, 0x1028, 0, "ALC3254" },
 	{ 0x10ec0670, 0x1025, 0, "ALC669X" },
 	{ 0x10ec0676, 0x1025, 0, "ALC679X" },
 	{ 0x10ec0282, 0x1043, 0, "ALC3229" },
@@ -1785,7 +1797,6 @@ enum {
 	ALC882_FIXUP_NO_PRIMARY_HP,
 	ALC887_FIXUP_ASUS_BASS,
 	ALC887_FIXUP_BASS_CHMAP,
-	ALC882_FIXUP_DISABLE_AAMIX,
 };
 
 static void alc889_fixup_coef(struct hda_codec *codec,
@@ -1947,8 +1958,6 @@ static void alc882_fixup_no_primary_hp(s
 
 static void alc_fixup_bass_chmap(struct hda_codec *codec,
 				 const struct hda_fixup *fix, int action);
-static void alc_fixup_disable_aamix(struct hda_codec *codec,
-				    const struct hda_fixup *fix, int action);
 
 static const struct hda_fixup alc882_fixups[] = {
 	[ALC882_FIXUP_ABIT_AW9D_MAX] = {
@@ -2186,10 +2195,6 @@ static const struct hda_fixup alc882_fix
 		.type = HDA_FIXUP_FUNC,
 		.v.func = alc_fixup_bass_chmap,
 	},
-	[ALC882_FIXUP_DISABLE_AAMIX] = {
-		.type = HDA_FIXUP_FUNC,
-		.v.func = alc_fixup_disable_aamix,
-	},
 };
 
 static const struct snd_pci_quirk alc882_fixup_tbl[] = {
@@ -2228,6 +2233,7 @@ static const struct snd_pci_quirk alc882
 	SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC889_FIXUP_VAIO_TT),
 	SND_PCI_QUIRK(0x104d, 0x905a, "Sony Vaio Z", ALC882_FIXUP_NO_PRIMARY_HP),
 	SND_PCI_QUIRK(0x104d, 0x9043, "Sony Vaio VGC-LN51JGB", ALC882_FIXUP_NO_PRIMARY_HP),
+	SND_PCI_QUIRK(0x104d, 0x9044, "Sony VAIO AiO", ALC882_FIXUP_NO_PRIMARY_HP),
 
 	/* All Apple entries are in codec SSIDs */
 	SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC889_FIXUP_MBP_VREF),
@@ -2257,7 +2263,6 @@ static const struct snd_pci_quirk alc882
 	SND_PCI_QUIRK(0x1462, 0x7350, "MSI-7350", ALC889_FIXUP_CD),
 	SND_PCI_QUIRK_VENDOR(0x1462, "MSI", ALC882_FIXUP_GPIO3),
 	SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte EP45-DS3/Z87X-UD3H", ALC889_FIXUP_FRONT_HP_NO_PRESENCE),
-	SND_PCI_QUIRK(0x1458, 0xa182, "Gigabyte Z170X-UD3", ALC882_FIXUP_DISABLE_AAMIX),
 	SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", ALC882_FIXUP_ABIT_AW9D_MAX),
 	SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC882_FIXUP_EAPD),
 	SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_FIXUP_EAPD),
@@ -2651,6 +2656,9 @@ enum {
 	ALC269_TYPE_ALC298,
 	ALC269_TYPE_ALC255,
 	ALC269_TYPE_ALC256,
+	ALC269_TYPE_ALC225,
+	ALC269_TYPE_ALC294,
+	ALC269_TYPE_ALC700,
 };
 
 /*
@@ -2680,6 +2688,9 @@ static int alc269_parse_auto_config(stru
 	case ALC269_TYPE_ALC298:
 	case ALC269_TYPE_ALC255:
 	case ALC269_TYPE_ALC256:
+	case ALC269_TYPE_ALC225:
+	case ALC269_TYPE_ALC294:
+	case ALC269_TYPE_ALC700:
 		ssids = alc269_ssids;
 		break;
 	default:
@@ -3612,13 +3623,20 @@ static void alc269_fixup_hp_line1_mic1_l
 static void alc_headset_mode_unplugged(struct hda_codec *codec)
 {
 	static struct coef_fw coef0255[] = {
-		WRITE_COEF(0x1b, 0x0c0b), /* LDO and MISC control */
 		WRITE_COEF(0x45, 0xd089), /* UAJ function set to menual mode */
 		UPDATE_COEFEX(0x57, 0x05, 1<<14, 0), /* Direct Drive HP Amp control(Set to verb control)*/
 		WRITE_COEF(0x06, 0x6104), /* Set MIC2 Vref gate with HP */
 		WRITE_COEFEX(0x57, 0x03, 0x8aa6), /* Direct Drive HP Amp control */
 		{}
 	};
+	static struct coef_fw coef0255_1[] = {
+		WRITE_COEF(0x1b, 0x0c0b), /* LDO and MISC control */
+		{}
+	};
+	static struct coef_fw coef0256[] = {
+		WRITE_COEF(0x1b, 0x0c4b), /* LDO and MISC control */
+		{}
+	};
 	static struct coef_fw coef0233[] = {
 		WRITE_COEF(0x1b, 0x0c0b),
 		WRITE_COEF(0x45, 0xc429),
@@ -3658,10 +3676,24 @@ static void alc_headset_mode_unplugged(s
 		WRITE_COEF(0xb7, 0x802b),
 		{}
 	};
+	static struct coef_fw coef0225[] = {
+		UPDATE_COEF(0x4a, 1<<8, 0),
+		UPDATE_COEFEX(0x57, 0x05, 1<<14, 0),
+		UPDATE_COEF(0x63, 3<<14, 3<<14),
+		UPDATE_COEF(0x4a, 3<<4, 2<<4),
+		UPDATE_COEF(0x4a, 3<<10, 3<<10),
+		UPDATE_COEF(0x45, 0x3f<<10, 0x34<<10),
+		UPDATE_COEF(0x4a, 3<<10, 0),
+		{}
+	};
 
 	switch (codec->core.vendor_id) {
 	case 0x10ec0255:
+		alc_process_coef_fw(codec, coef0255_1);
+		alc_process_coef_fw(codec, coef0255);
+		break;
 	case 0x10ec0256:
+		alc_process_coef_fw(codec, coef0256);
 		alc_process_coef_fw(codec, coef0255);
 		break;
 	case 0x10ec0233:
@@ -3682,6 +3714,10 @@ static void alc_headset_mode_unplugged(s
 	case 0x10ec0668:
 		alc_process_coef_fw(codec, coef0668);
 		break;
+	case 0x10ec0225:
+	case 0x10ec0295:
+		alc_process_coef_fw(codec, coef0225);
+		break;
 	}
 	codec_dbg(codec, "Headset jack set to unplugged mode.\n");
 }
@@ -3727,6 +3763,13 @@ static void alc_headset_mode_mic_in(stru
 		UPDATE_COEF(0xc3, 0, 1<<12),
 		{}
 	};
+	static struct coef_fw coef0225[] = {
+		UPDATE_COEFEX(0x57, 0x05, 1<<14, 1<<14),
+		UPDATE_COEF(0x4a, 3<<4, 2<<4),
+		UPDATE_COEF(0x63, 3<<14, 0),
+		{}
+	};
+
 
 	switch (codec->core.vendor_id) {
 	case 0x10ec0255:
@@ -3772,12 +3815,23 @@ static void alc_headset_mode_mic_in(stru
 		alc_process_coef_fw(codec, coef0688);
 		snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
 		break;
+	case 0x10ec0225:
+	case 0x10ec0295:
+		alc_update_coef_idx(codec, 0x45, 0x3f<<10, 0x31<<10);
+		snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
+		alc_process_coef_fw(codec, coef0225);
+		snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
+		break;
 	}
 	codec_dbg(codec, "Headset jack set to mic-in mode.\n");
 }
 
 static void alc_headset_mode_default(struct hda_codec *codec)
 {
+	static struct coef_fw coef0225[] = {
+		UPDATE_COEF(0x45, 0x3f<<10, 0x34<<10),
+		{}
+	};
 	static struct coef_fw coef0255[] = {
 		WRITE_COEF(0x45, 0xc089),
 		WRITE_COEF(0x45, 0xc489),
@@ -3819,6 +3873,10 @@ static void alc_headset_mode_default(str
 	};
 
 	switch (codec->core.vendor_id) {
+	case 0x10ec0225:
+	case 0x10ec0295:
+		alc_process_coef_fw(codec, coef0225);
+		break;
 	case 0x10ec0255:
 	case 0x10ec0256:
 		alc_process_coef_fw(codec, coef0255);
@@ -3854,6 +3912,12 @@ static void alc_headset_mode_ctia(struct
 		WRITE_COEFEX(0x57, 0x03, 0x8ea6),
 		{}
 	};
+	static struct coef_fw coef0256[] = {
+		WRITE_COEF(0x45, 0xd489), /* Set to CTIA type */
+		WRITE_COEF(0x1b, 0x0c6b),
+		WRITE_COEFEX(0x57, 0x03, 0x8ea6),
+		{}
+	};
 	static struct coef_fw coef0233[] = {
 		WRITE_COEF(0x45, 0xd429),
 		WRITE_COEF(0x1b, 0x0c2b),
@@ -3884,12 +3948,21 @@ static void alc_headset_mode_ctia(struct
 		WRITE_COEF(0xc3, 0x0000),
 		{}
 	};
+	static struct coef_fw coef0225[] = {
+		UPDATE_COEF(0x45, 0x3f<<10, 0x35<<10),
+		UPDATE_COEF(0x49, 1<<8, 1<<8),
+		UPDATE_COEF(0x4a, 7<<6, 7<<6),
+		UPDATE_COEF(0x4a, 3<<4, 3<<4),
+		{}
+	};
 
 	switch (codec->core.vendor_id) {
 	case 0x10ec0255:
-	case 0x10ec0256:
 		alc_process_coef_fw(codec, coef0255);
 		break;
+	case 0x10ec0256:
+		alc_process_coef_fw(codec, coef0256);
+		break;
 	case 0x10ec0233:
 	case 0x10ec0283:
 		alc_process_coef_fw(codec, coef0233);
@@ -3912,6 +3985,10 @@ static void alc_headset_mode_ctia(struct
 	case 0x10ec0668:
 		alc_process_coef_fw(codec, coef0688);
 		break;
+	case 0x10ec0225:
+	case 0x10ec0295:
+		alc_process_coef_fw(codec, coef0225);
+		break;
 	}
 	codec_dbg(codec, "Headset jack set to iPhone-style headset mode.\n");
 }
@@ -3925,6 +4002,12 @@ static void alc_headset_mode_omtp(struct
 		WRITE_COEFEX(0x57, 0x03, 0x8ea6),
 		{}
 	};
+	static struct coef_fw coef0256[] = {
+		WRITE_COEF(0x45, 0xe489), /* Set to OMTP Type */
+		WRITE_COEF(0x1b, 0x0c6b),
+		WRITE_COEFEX(0x57, 0x03, 0x8ea6),
+		{}
+	};
 	static struct coef_fw coef0233[] = {
 		WRITE_COEF(0x45, 0xe429),
 		WRITE_COEF(0x1b, 0x0c2b),
@@ -3955,12 +4038,21 @@ static void alc_headset_mode_omtp(struct
 		WRITE_COEF(0xc3, 0x0000),
 		{}
 	};
+	static struct coef_fw coef0225[] = {
+		UPDATE_COEF(0x45, 0x3f<<10, 0x39<<10),
+		UPDATE_COEF(0x49, 1<<8, 1<<8),
+		UPDATE_COEF(0x4a, 7<<6, 7<<6),
+		UPDATE_COEF(0x4a, 3<<4, 3<<4),
+		{}
+	};
 
 	switch (codec->core.vendor_id) {
 	case 0x10ec0255:
-	case 0x10ec0256:
 		alc_process_coef_fw(codec, coef0255);
 		break;
+	case 0x10ec0256:
+		alc_process_coef_fw(codec, coef0256);
+		break;
 	case 0x10ec0233:
 	case 0x10ec0283:
 		alc_process_coef_fw(codec, coef0233);
@@ -3983,6 +4075,10 @@ static void alc_headset_mode_omtp(struct
 	case 0x10ec0668:
 		alc_process_coef_fw(codec, coef0688);
 		break;
+	case 0x10ec0225:
+	case 0x10ec0295:
+		alc_process_coef_fw(codec, coef0225);
+		break;
 	}
 	codec_dbg(codec, "Headset jack set to Nokia-style headset mode.\n");
 }
@@ -4014,6 +4110,11 @@ static void alc_determine_headset_type(s
 		WRITE_COEF(0xc3, 0x0c00),
 		{}
 	};
+	static struct coef_fw coef0225[] = {
+		UPDATE_COEF(0x45, 0x3f<<10, 0x34<<10),
+		UPDATE_COEF(0x49, 1<<8, 1<<8),
+		{}
+	};
 
 	switch (codec->core.vendor_id) {
 	case 0x10ec0255:
@@ -4058,6 +4159,13 @@ static void alc_determine_headset_type(s
 		val = alc_read_coef_idx(codec, 0xbe);
 		is_ctia = (val & 0x1c02) == 0x1c02;
 		break;
+	case 0x10ec0225:
+	case 0x10ec0295:
+		alc_process_coef_fw(codec, coef0225);
+		msleep(800);
+		val = alc_read_coef_idx(codec, 0x46);
+		is_ctia = (val & 0x00f0) == 0x00f0;
+		break;
 	}
 
 	codec_dbg(codec, "Headset jack detected iPhone-style headset: %s\n",
@@ -4190,7 +4298,7 @@ static void alc_fixup_headset_mode_no_hp
 static void alc255_set_default_jack_type(struct hda_codec *codec)
 {
 	/* Set to iphone type */
-	static struct coef_fw fw[] = {
+	static struct coef_fw alc255fw[] = {
 		WRITE_COEF(0x1b, 0x880b),
 		WRITE_COEF(0x45, 0xd089),
 		WRITE_COEF(0x1b, 0x080b),
@@ -4198,7 +4306,22 @@ static void alc255_set_default_jack_type
 		WRITE_COEF(0x1b, 0x0c0b),
 		{}
 	};
-	alc_process_coef_fw(codec, fw);
+	static struct coef_fw alc256fw[] = {
+		WRITE_COEF(0x1b, 0x884b),
+		WRITE_COEF(0x45, 0xd089),
+		WRITE_COEF(0x1b, 0x084b),
+		WRITE_COEF(0x46, 0x0004),
+		WRITE_COEF(0x1b, 0x0c4b),
+		{}
+	};
+	switch (codec->core.vendor_id) {
+	case 0x10ec0255:
+		alc_process_coef_fw(codec, alc255fw);
+		break;
+	case 0x10ec0256:
+		alc_process_coef_fw(codec, alc256fw);
+		break;
+	}
 	msleep(30);
 }
 
@@ -4551,6 +4674,22 @@ static void alc290_fixup_mono_speakers(s
 	}
 }
 
+static void alc298_fixup_speaker_volume(struct hda_codec *codec,
+					const struct hda_fixup *fix, int action)
+{
+	if (action == HDA_FIXUP_ACT_PRE_PROBE) {
+		/* The speaker is routed to the Node 0x06 by a mistake, as a result
+		   we can't adjust the speaker's volume since this node does not has
+		   Amp-out capability. we change the speaker's route to:
+		   Node 0x02 (Audio Output) -> Node 0x0c (Audio Mixer) -> Node 0x17 (
+		   Pin Complex), since Node 0x02 has Amp-out caps, we can adjust
+		   speaker's volume now. */
+
+		hda_nid_t conn1[1] = { 0x0c };
+		snd_hda_override_conn_list(codec, 0x17, 1, conn1);
+	}
+}
+
 /* Hook to update amp GPIO4 for automute */
 static void alc280_hp_gpio4_automute_hook(struct hda_codec *codec,
 					  struct hda_jack_callback *jack)
@@ -4666,6 +4805,7 @@ enum {
 	ALC290_FIXUP_SUBWOOFER,
 	ALC290_FIXUP_SUBWOOFER_HSJACK,
 	ALC269_FIXUP_THINKPAD_ACPI,
+	ALC269_FIXUP_DMIC_THINKPAD_ACPI,
 	ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
 	ALC255_FIXUP_DELL2_MIC_NO_PRESENCE,
 	ALC255_FIXUP_HEADSET_MODE,
@@ -4694,6 +4834,13 @@ enum {
 	ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE,
 	ALC293_FIXUP_LENOVO_SPK_NOISE,
 	ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY,
+	ALC255_FIXUP_DELL_SPK_NOISE,
+	ALC221_FIXUP_HP_FRONT_MIC,
+	ALC225_FIXUP_DELL1_MIC_NO_PRESENCE,
+	ALC280_FIXUP_HP_HEADSET_MIC,
+	ALC292_FIXUP_TPT460,
+	ALC298_FIXUP_SPK_VOLUME,
+	ALC256_FIXUP_DELL_INSPIRON_7559_SUBWOOFER,
 };
 
 static const struct hda_fixup alc269_fixups[] = {
@@ -5103,6 +5250,12 @@ static const struct hda_fixup alc269_fix
 		.type = HDA_FIXUP_FUNC,
 		.v.func = hda_fixup_thinkpad_acpi,
 	},
+	[ALC269_FIXUP_DMIC_THINKPAD_ACPI] = {
+		.type = HDA_FIXUP_FUNC,
+		.v.func = alc_fixup_inv_dmic,
+		.chained = true,
+		.chain_id = ALC269_FIXUP_THINKPAD_ACPI,
+	},
 	[ALC255_FIXUP_DELL1_MIC_NO_PRESENCE] = {
 		.type = HDA_FIXUP_PINS,
 		.v.pins = (const struct hda_pintbl[]) {
@@ -5307,6 +5460,57 @@ static const struct hda_fixup alc269_fix
 		.type = HDA_FIXUP_FUNC,
 		.v.func = alc233_fixup_lenovo_line2_mic_hotkey,
 	},
+	[ALC255_FIXUP_DELL_SPK_NOISE] = {
+		.type = HDA_FIXUP_FUNC,
+		.v.func = alc_fixup_disable_aamix,
+		.chained = true,
+		.chain_id = ALC255_FIXUP_DELL1_MIC_NO_PRESENCE
+	},
+	[ALC221_FIXUP_HP_FRONT_MIC] = {
+		.type = HDA_FIXUP_PINS,
+		.v.pins = (const struct hda_pintbl[]) {
+			{ 0x19, 0x02a19020 }, /* Front Mic */
+			{ }
+		},
+	},
+	[ALC225_FIXUP_DELL1_MIC_NO_PRESENCE] = {
+		.type = HDA_FIXUP_VERBS,
+		.v.verbs = (const struct hda_verb[]) {
+			/* Disable pass-through path for FRONT 14h */
+			{ 0x20, AC_VERB_SET_COEF_INDEX, 0x36 },
+			{ 0x20, AC_VERB_SET_PROC_COEF, 0x57d7 },
+			{}
+		},
+		.chained = true,
+		.chain_id = ALC269_FIXUP_DELL1_MIC_NO_PRESENCE
+	},
+	[ALC280_FIXUP_HP_HEADSET_MIC] = {
+		.type = HDA_FIXUP_FUNC,
+		.v.func = alc_fixup_disable_aamix,
+		.chained = true,
+		.chain_id = ALC269_FIXUP_HEADSET_MIC,
+	},
+	[ALC292_FIXUP_TPT460] = {
+		.type = HDA_FIXUP_FUNC,
+		.v.func = alc_fixup_tpt440_dock,
+		.chained = true,
+		.chain_id = ALC293_FIXUP_LENOVO_SPK_NOISE,
+	},
+	[ALC298_FIXUP_SPK_VOLUME] = {
+		.type = HDA_FIXUP_FUNC,
+		.v.func = alc298_fixup_speaker_volume,
+		.chained = true,
+		.chain_id = ALC298_FIXUP_DELL1_MIC_NO_PRESENCE,
+	},
+	[ALC256_FIXUP_DELL_INSPIRON_7559_SUBWOOFER] = {
+		.type = HDA_FIXUP_PINS,
+		.v.pins = (const struct hda_pintbl[]) {
+			{ 0x1b, 0x90170151 },
+			{ }
+		},
+		.chained = true,
+		.chain_id = ALC255_FIXUP_DELL1_MIC_NO_PRESENCE
+	},
 };
 
 static const struct snd_pci_quirk alc269_fixup_tbl[] = {
@@ -5318,12 +5522,14 @@ static const struct snd_pci_quirk alc269
 	SND_PCI_QUIRK(0x1025, 0x080d, "Acer Aspire V5-122P", ALC269_FIXUP_ASPIRE_HEADSET_MIC),
 	SND_PCI_QUIRK(0x1025, 0x0740, "Acer AO725", ALC271_FIXUP_HP_GATE_MIC_JACK),
 	SND_PCI_QUIRK(0x1025, 0x0742, "Acer AO756", ALC271_FIXUP_HP_GATE_MIC_JACK),
+	SND_PCI_QUIRK(0x1025, 0x0762, "Acer Aspire E1-472", ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572),
 	SND_PCI_QUIRK(0x1025, 0x0775, "Acer Aspire E1-572", ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572),
 	SND_PCI_QUIRK(0x1025, 0x079b, "Acer Aspire V5-573G", ALC282_FIXUP_ASPIRE_V5_PINS),
 	SND_PCI_QUIRK(0x1025, 0x106d, "Acer Cloudbook 14", ALC283_FIXUP_CHROME_BOOK),
 	SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z),
 	SND_PCI_QUIRK(0x1028, 0x054b, "Dell XPS one 2710", ALC275_FIXUP_DELL_XPS),
 	SND_PCI_QUIRK(0x1028, 0x05bd, "Dell Latitude E6440", ALC292_FIXUP_DELL_E7X),
+	SND_PCI_QUIRK(0x1028, 0x05be, "Dell Latitude E6540", ALC292_FIXUP_DELL_E7X),
 	SND_PCI_QUIRK(0x1028, 0x05ca, "Dell Latitude E7240", ALC292_FIXUP_DELL_E7X),
 	SND_PCI_QUIRK(0x1028, 0x05cb, "Dell Latitude E7440", ALC292_FIXUP_DELL_E7X),
 	SND_PCI_QUIRK(0x1028, 0x05da, "Dell Vostro 5460", ALC290_FIXUP_SUBWOOFER),
@@ -5332,11 +5538,13 @@ static const struct snd_pci_quirk alc269
 	SND_PCI_QUIRK(0x1028, 0x05f6, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
 	SND_PCI_QUIRK(0x1028, 0x0615, "Dell Vostro 5470", ALC290_FIXUP_SUBWOOFER_HSJACK),
 	SND_PCI_QUIRK(0x1028, 0x0616, "Dell Vostro 5470", ALC290_FIXUP_SUBWOOFER_HSJACK),
+	SND_PCI_QUIRK(0x1028, 0x062c, "Dell Latitude E5550", ALC292_FIXUP_DELL_E7X),
 	SND_PCI_QUIRK(0x1028, 0x062e, "Dell Latitude E7450", ALC292_FIXUP_DELL_E7X),
 	SND_PCI_QUIRK(0x1028, 0x0638, "Dell Inspiron 5439", ALC290_FIXUP_MONO_SPEAKERS_HSJACK),
 	SND_PCI_QUIRK(0x1028, 0x064a, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
 	SND_PCI_QUIRK(0x1028, 0x064b, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
 	SND_PCI_QUIRK(0x1028, 0x0665, "Dell XPS 13", ALC288_FIXUP_DELL_XPS_13),
+	SND_PCI_QUIRK(0x1028, 0x0669, "Dell Optiplex 9020m", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE),
 	SND_PCI_QUIRK(0x1028, 0x069a, "Dell Vostro 5480", ALC290_FIXUP_SUBWOOFER_HSJACK),
 	SND_PCI_QUIRK(0x1028, 0x06c7, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE),
 	SND_PCI_QUIRK(0x1028, 0x06d9, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
@@ -5346,7 +5554,11 @@ static const struct snd_pci_quirk alc269
 	SND_PCI_QUIRK(0x1028, 0x06de, "Dell", ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK),
 	SND_PCI_QUIRK(0x1028, 0x06df, "Dell", ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK),
 	SND_PCI_QUIRK(0x1028, 0x06e0, "Dell", ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK),
-	SND_PCI_QUIRK(0x1028, 0x0704, "Dell XPS 13", ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE),
+	SND_PCI_QUIRK(0x1028, 0x0704, "Dell XPS 13 9350", ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE),
+	SND_PCI_QUIRK(0x1028, 0x0706, "Dell Inspiron 7559", ALC256_FIXUP_DELL_INSPIRON_7559_SUBWOOFER),
+	SND_PCI_QUIRK(0x1028, 0x0725, "Dell Inspiron 3162", ALC255_FIXUP_DELL_SPK_NOISE),
+	SND_PCI_QUIRK(0x1028, 0x075b, "Dell XPS 13 9360", ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE),
+	SND_PCI_QUIRK(0x1028, 0x075d, "Dell AIO", ALC298_FIXUP_SPK_VOLUME),
 	SND_PCI_QUIRK(0x1028, 0x164a, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
 	SND_PCI_QUIRK(0x1028, 0x164b, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
 	SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC2),
@@ -5407,6 +5619,8 @@ static const struct snd_pci_quirk alc269
 	SND_PCI_QUIRK(0x103c, 0x2335, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
 	SND_PCI_QUIRK(0x103c, 0x2336, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
 	SND_PCI_QUIRK(0x103c, 0x2337, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
+	SND_PCI_QUIRK(0x103c, 0x8256, "HP", ALC221_FIXUP_HP_FRONT_MIC),
+	SND_PCI_QUIRK(0x103c, 0x221c, "HP EliteBook 755 G2", ALC280_FIXUP_HP_HEADSET_MIC),
 	SND_PCI_QUIRK(0x1043, 0x103f, "ASUS TX300", ALC282_FIXUP_ASUS_TX300),
 	SND_PCI_QUIRK(0x1043, 0x106d, "Asus K53BE", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
 	SND_PCI_QUIRK(0x1043, 0x115d, "Asus 1015E", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
@@ -5455,8 +5669,11 @@ static const struct snd_pci_quirk alc269
 	SND_PCI_QUIRK(0x17aa, 0x2218, "Thinkpad X1 Carbon 2nd", ALC292_FIXUP_TPT440_DOCK),
 	SND_PCI_QUIRK(0x17aa, 0x2223, "ThinkPad T550", ALC292_FIXUP_TPT440_DOCK),
 	SND_PCI_QUIRK(0x17aa, 0x2226, "ThinkPad X250", ALC292_FIXUP_TPT440_DOCK),
-	SND_PCI_QUIRK(0x17aa, 0x2233, "Thinkpad", ALC293_FIXUP_LENOVO_SPK_NOISE),
+	SND_PCI_QUIRK(0x17aa, 0x2231, "Thinkpad T560", ALC292_FIXUP_TPT460),
+	SND_PCI_QUIRK(0x17aa, 0x2233, "Thinkpad", ALC292_FIXUP_TPT460),
 	SND_PCI_QUIRK(0x17aa, 0x30bb, "ThinkCentre AIO", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY),
+	SND_PCI_QUIRK(0x17aa, 0x30e2, "ThinkCentre AIO", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY),
+	SND_PCI_QUIRK(0x17aa, 0x3902, "Lenovo E50-80", ALC269_FIXUP_DMIC_THINKPAD_ACPI),
 	SND_PCI_QUIRK(0x17aa, 0x3977, "IdeaPad S210", ALC283_FIXUP_INT_MIC),
 	SND_PCI_QUIRK(0x17aa, 0x3978, "IdeaPad Y410P", ALC269_FIXUP_NO_SHUTUP),
 	SND_PCI_QUIRK(0x17aa, 0x5013, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
@@ -5466,7 +5683,11 @@ static const struct snd_pci_quirk alc269
 	SND_PCI_QUIRK(0x17aa, 0x5034, "Thinkpad T450", ALC292_FIXUP_TPT440_DOCK),
 	SND_PCI_QUIRK(0x17aa, 0x5036, "Thinkpad T450s", ALC292_FIXUP_TPT440_DOCK),
 	SND_PCI_QUIRK(0x17aa, 0x503c, "Thinkpad L450", ALC292_FIXUP_TPT440_DOCK),
+	SND_PCI_QUIRK(0x17aa, 0x504a, "ThinkPad X260", ALC292_FIXUP_TPT440_DOCK),
 	SND_PCI_QUIRK(0x17aa, 0x504b, "Thinkpad", ALC293_FIXUP_LENOVO_SPK_NOISE),
+	SND_PCI_QUIRK(0x17aa, 0x5050, "Thinkpad T560p", ALC292_FIXUP_TPT460),
+	SND_PCI_QUIRK(0x17aa, 0x5051, "Thinkpad L460", ALC292_FIXUP_TPT460),
+	SND_PCI_QUIRK(0x17aa, 0x5053, "Thinkpad T460", ALC292_FIXUP_TPT460),
 	SND_PCI_QUIRK(0x17aa, 0x5109, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
 	SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_FIXUP_PCM_44K),
 	SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD),
@@ -5548,8 +5769,11 @@ static const struct hda_model_fixup alc2
 	{.id = ALC283_FIXUP_SENSE_COMBO_JACK, .name = "alc283-sense-combo"},
 	{.id = ALC292_FIXUP_TPT440_DOCK, .name = "tpt440-dock"},
 	{.id = ALC292_FIXUP_TPT440, .name = "tpt440"},
+	{.id = ALC292_FIXUP_TPT460, .name = "tpt460"},
 	{}
 };
+#define ALC225_STANDARD_PINS \
+	{0x21, 0x04211020}
 
 #define ALC256_STANDARD_PINS \
 	{0x12, 0x90a60140}, \
@@ -5566,15 +5790,45 @@ static const struct hda_model_fixup alc2
 	{0x14, 0x90170110}, \
 	{0x15, 0x0221401f}
 
+#define ALC295_STANDARD_PINS \
+	{0x12, 0xb7a60130}, \
+	{0x14, 0x90170110}, \
+	{0x17, 0x21014020}, \
+	{0x18, 0x21a19030}, \
+	{0x21, 0x04211020}
+
 #define ALC298_STANDARD_PINS \
 	{0x12, 0x90a60130}, \
 	{0x21, 0x03211020}
 
 static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = {
+	SND_HDA_PIN_QUIRK(0x10ec0225, 0x1028, "Dell", ALC225_FIXUP_DELL1_MIC_NO_PRESENCE,
+		ALC225_STANDARD_PINS,
+		{0x12, 0xb7a60130},
+		{0x14, 0x901701a0}),
+	SND_HDA_PIN_QUIRK(0x10ec0225, 0x1028, "Dell", ALC225_FIXUP_DELL1_MIC_NO_PRESENCE,
+		ALC225_STANDARD_PINS,
+		{0x12, 0xb7a60130},
+		{0x14, 0x901701b0}),
+	SND_HDA_PIN_QUIRK(0x10ec0225, 0x1028, "Dell", ALC225_FIXUP_DELL1_MIC_NO_PRESENCE,
+		ALC225_STANDARD_PINS,
+		{0x12, 0xb7a60150},
+		{0x14, 0x901701a0}),
+	SND_HDA_PIN_QUIRK(0x10ec0225, 0x1028, "Dell", ALC225_FIXUP_DELL1_MIC_NO_PRESENCE,
+		ALC225_STANDARD_PINS,
+		{0x12, 0xb7a60150},
+		{0x14, 0x901701b0}),
+	SND_HDA_PIN_QUIRK(0x10ec0225, 0x1028, "Dell", ALC225_FIXUP_DELL1_MIC_NO_PRESENCE,
+		ALC225_STANDARD_PINS,
+		{0x12, 0xb7a60130},
+		{0x1b, 0x90170110}),
 	SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL2_MIC_NO_PRESENCE,
 		{0x14, 0x90170110},
 		{0x21, 0x02211020}),
 	SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
+		{0x14, 0x90170130},
+		{0x21, 0x02211040}),
+	SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
 		{0x12, 0x90a60140},
 		{0x14, 0x90170110},
 		{0x21, 0x02211020}),
@@ -5583,10 +5837,18 @@ static const struct snd_hda_pin_quirk al
 		{0x14, 0x90170120},
 		{0x21, 0x02211030}),
 	SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
+		{0x14, 0x90170110},
+		{0x1b, 0x02011020},
+		{0x21, 0x0221101f}),
+	SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
 		{0x14, 0x90170130},
 		{0x1b, 0x01014020},
 		{0x21, 0x0221103f}),
 	SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
+		{0x14, 0x90170130},
+		{0x1b, 0x02011020},
+		{0x21, 0x0221103f}),
+	SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
 		{0x14, 0x90170150},
 		{0x1b, 0x02011020},
 		{0x21, 0x0221105f}),
@@ -5617,17 +5879,37 @@ static const struct snd_hda_pin_quirk al
 		{0x21, 0x02211040}),
 	SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
 		{0x12, 0x90a60170},
+		{0x14, 0x90171130},
+		{0x21, 0x02211040}),
+	SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
+		{0x12, 0x90a60170},
 		{0x14, 0x90170140},
 		{0x21, 0x02211050}),
 	SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell Inspiron 5548", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
 		{0x12, 0x90a60180},
 		{0x14, 0x90170130},
 		{0x21, 0x02211040}),
+	SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell Inspiron 5565", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
+		{0x12, 0x90a60180},
+		{0x14, 0x90170120},
+		{0x21, 0x02211030}),
 	SND_HDA_PIN_QUIRK(0x10ec0256, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
 		{0x12, 0x90a60160},
 		{0x14, 0x90170120},
 		{0x21, 0x02211030}),
 	SND_HDA_PIN_QUIRK(0x10ec0256, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
+		{0x12, 0x90a60170},
+		{0x14, 0x90170120},
+		{0x21, 0x02211030}),
+	SND_HDA_PIN_QUIRK(0x10ec0256, 0x1028, "Dell Inspiron 5468", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
+		{0x12, 0x90a60180},
+		{0x14, 0x90170120},
+		{0x21, 0x02211030}),
+	SND_HDA_PIN_QUIRK(0x10ec0256, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
+		{0x12, 0xb7a60130},
+		{0x14, 0x90170110},
+		{0x21, 0x02211020}),
+	SND_HDA_PIN_QUIRK(0x10ec0256, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
 		ALC256_STANDARD_PINS),
 	SND_HDA_PIN_QUIRK(0x10ec0280, 0x103c, "HP", ALC280_FIXUP_HP_GPIO4,
 		{0x12, 0x90a60130},
@@ -5738,6 +6020,8 @@ static const struct snd_hda_pin_quirk al
 	SND_HDA_PIN_QUIRK(0x10ec0293, 0x1028, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE,
 		ALC292_STANDARD_PINS,
 		{0x13, 0x90a60140}),
+	SND_HDA_PIN_QUIRK(0x10ec0295, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
+		ALC295_STANDARD_PINS),
 	SND_HDA_PIN_QUIRK(0x10ec0298, 0x1028, "Dell", ALC298_FIXUP_DELL1_MIC_NO_PRESENCE,
 		ALC298_STANDARD_PINS,
 		{0x17, 0x90170110}),
@@ -5892,6 +6176,23 @@ static int patch_alc269(struct hda_codec
 		spec->gen.mixer_nid = 0; /* ALC256 does not have any loopback mixer path */
 		alc_update_coef_idx(codec, 0x36, 1 << 13, 1 << 5); /* Switch pcbeep path to Line in path*/
 		break;
+	case 0x10ec0225:
+	case 0x10ec0295:
+		spec->codec_variant = ALC269_TYPE_ALC225;
+		break;
+	case 0x10ec0234:
+	case 0x10ec0274:
+	case 0x10ec0294:
+		spec->codec_variant = ALC269_TYPE_ALC294;
+		break;
+	case 0x10ec0700:
+	case 0x10ec0701:
+	case 0x10ec0703:
+		spec->codec_variant = ALC269_TYPE_ALC700;
+		spec->gen.mixer_nid = 0; /* ALC700 does not have any loopback mixer path */
+		alc_update_coef_idx(codec, 0x4a, 0, 1 << 15); /* Combo jack auto trigger control */
+		break;
+
 	}
 
 	if (snd_hda_codec_read(codec, 0x51, 0, AC_VERB_PARAMETERS, 0) == 0x10ec5505) {
@@ -6289,6 +6590,8 @@ enum {
 	ALC668_FIXUP_AUTO_MUTE,
 	ALC668_FIXUP_DELL_DISABLE_AAMIX,
 	ALC668_FIXUP_DELL_XPS13,
+	ALC662_FIXUP_ASUS_Nx50,
+	ALC668_FIXUP_ASUS_Nx51,
 };
 
 static const struct hda_fixup alc662_fixups[] = {
@@ -6529,6 +6832,21 @@ static const struct hda_fixup alc662_fix
 		.type = HDA_FIXUP_FUNC,
 		.v.func = alc_fixup_bass_chmap,
 	},
+	[ALC662_FIXUP_ASUS_Nx50] = {
+		.type = HDA_FIXUP_FUNC,
+		.v.func = alc_fixup_auto_mute_via_amp,
+		.chained = true,
+		.chain_id = ALC662_FIXUP_BASS_1A
+	},
+	[ALC668_FIXUP_ASUS_Nx51] = {
+		.type = HDA_FIXUP_PINS,
+		.v.pins = (const struct hda_pintbl[]) {
+			{0x1a, 0x90170151}, /* bass speaker */
+			{}
+		},
+		.chained = true,
+		.chain_id = ALC662_FIXUP_BASS_CHMAP,
+	},
 };
 
 static const struct snd_pci_quirk alc662_fixup_tbl[] = {
@@ -6551,9 +6869,14 @@ static const struct snd_pci_quirk alc662
 	SND_PCI_QUIRK(0x1028, 0x0698, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
 	SND_PCI_QUIRK(0x1028, 0x069f, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
 	SND_PCI_QUIRK(0x103c, 0x1632, "HP RP5800", ALC662_FIXUP_HP_RP5800),
-	SND_PCI_QUIRK(0x1043, 0x11cd, "Asus N550", ALC662_FIXUP_BASS_1A),
+	SND_PCI_QUIRK(0x1043, 0x1080, "Asus UX501VW", ALC668_FIXUP_HEADSET_MODE),
+	SND_PCI_QUIRK(0x1043, 0x11cd, "Asus N550", ALC662_FIXUP_ASUS_Nx50),
+	SND_PCI_QUIRK(0x1043, 0x13df, "Asus N550JX", ALC662_FIXUP_BASS_1A),
+	SND_PCI_QUIRK(0x1043, 0x129d, "Asus N750", ALC662_FIXUP_ASUS_Nx50),
 	SND_PCI_QUIRK(0x1043, 0x1477, "ASUS N56VZ", ALC662_FIXUP_BASS_MODE4_CHMAP),
 	SND_PCI_QUIRK(0x1043, 0x15a7, "ASUS UX51VZH", ALC662_FIXUP_BASS_16),
+	SND_PCI_QUIRK(0x1043, 0x177d, "ASUS N551", ALC668_FIXUP_ASUS_Nx51),
+	SND_PCI_QUIRK(0x1043, 0x17bd, "ASUS N751", ALC668_FIXUP_ASUS_Nx51),
 	SND_PCI_QUIRK(0x1043, 0x1b73, "ASUS N55SF", ALC662_FIXUP_BASS_16),
 	SND_PCI_QUIRK(0x1043, 0x1bf3, "ASUS N76VZ", ALC662_FIXUP_BASS_MODE4_CHMAP),
 	SND_PCI_QUIRK(0x1043, 0x8469, "ASUS mobo", ALC662_FIXUP_NO_JACK_DETECT),
@@ -6781,8 +7104,10 @@ static int patch_alc680(struct hda_codec
  */
 static const struct hda_device_id snd_hda_id_realtek[] = {
 	HDA_CODEC_ENTRY(0x10ec0221, "ALC221", patch_alc269),
+	HDA_CODEC_ENTRY(0x10ec0225, "ALC225", patch_alc269),
 	HDA_CODEC_ENTRY(0x10ec0231, "ALC231", patch_alc269),
 	HDA_CODEC_ENTRY(0x10ec0233, "ALC233", patch_alc269),
+	HDA_CODEC_ENTRY(0x10ec0234, "ALC234", patch_alc269),
 	HDA_CODEC_ENTRY(0x10ec0235, "ALC233", patch_alc269),
 	HDA_CODEC_ENTRY(0x10ec0255, "ALC255", patch_alc269),
 	HDA_CODEC_ENTRY(0x10ec0256, "ALC256", patch_alc269),
@@ -6793,6 +7118,7 @@ static const struct hda_device_id snd_hd
 	HDA_CODEC_ENTRY(0x10ec0269, "ALC269", patch_alc269),
 	HDA_CODEC_ENTRY(0x10ec0270, "ALC270", patch_alc269),
 	HDA_CODEC_ENTRY(0x10ec0272, "ALC272", patch_alc662),
+	HDA_CODEC_ENTRY(0x10ec0274, "ALC274", patch_alc269),
 	HDA_CODEC_ENTRY(0x10ec0275, "ALC275", patch_alc269),
 	HDA_CODEC_ENTRY(0x10ec0276, "ALC276", patch_alc269),
 	HDA_CODEC_ENTRY(0x10ec0280, "ALC280", patch_alc269),
@@ -6805,6 +7131,8 @@ static const struct hda_device_id snd_hd
 	HDA_CODEC_ENTRY(0x10ec0290, "ALC290", patch_alc269),
 	HDA_CODEC_ENTRY(0x10ec0292, "ALC292", patch_alc269),
 	HDA_CODEC_ENTRY(0x10ec0293, "ALC293", patch_alc269),
+	HDA_CODEC_ENTRY(0x10ec0294, "ALC294", patch_alc269),
+	HDA_CODEC_ENTRY(0x10ec0295, "ALC295", patch_alc269),
 	HDA_CODEC_ENTRY(0x10ec0298, "ALC298", patch_alc269),
 	HDA_CODEC_REV_ENTRY(0x10ec0861, 0x100340, "ALC660", patch_alc861),
 	HDA_CODEC_ENTRY(0x10ec0660, "ALC660-VD", patch_alc861vd),
@@ -6820,6 +7148,9 @@ static const struct hda_device_id snd_hd
 	HDA_CODEC_ENTRY(0x10ec0670, "ALC670", patch_alc662),
 	HDA_CODEC_ENTRY(0x10ec0671, "ALC671", patch_alc662),
 	HDA_CODEC_ENTRY(0x10ec0680, "ALC680", patch_alc680),
+	HDA_CODEC_ENTRY(0x10ec0700, "ALC700", patch_alc269),
+	HDA_CODEC_ENTRY(0x10ec0701, "ALC701", patch_alc269),
+	HDA_CODEC_ENTRY(0x10ec0703, "ALC703", patch_alc269),
 	HDA_CODEC_ENTRY(0x10ec0867, "ALC891", patch_alc882),
 	HDA_CODEC_ENTRY(0x10ec0880, "ALC880", patch_alc880),
 	HDA_CODEC_ENTRY(0x10ec0882, "ALC882", patch_alc882),
--- zfcpdump-kernel-4.4.orig/sound/pci/hda/patch_sigmatel.c
+++ zfcpdump-kernel-4.4/sound/pci/hda/patch_sigmatel.c
@@ -493,9 +493,9 @@ static void jack_update_power(struct hda
 	if (!spec->num_pwrs)
 		return;
 
-	if (jack && jack->tbl->nid) {
-		stac_toggle_power_map(codec, jack->tbl->nid,
-				      snd_hda_jack_detect(codec, jack->tbl->nid),
+	if (jack && jack->nid) {
+		stac_toggle_power_map(codec, jack->nid,
+				      snd_hda_jack_detect(codec, jack->nid),
 				      true);
 		return;
 	}
--- zfcpdump-kernel-4.4.orig/sound/pci/intel8x0.c
+++ zfcpdump-kernel-4.4/sound/pci/intel8x0.c
@@ -2879,6 +2879,7 @@ static void intel8x0_measure_ac97_clock(
 
 static struct snd_pci_quirk intel8x0_clock_list[] = {
 	SND_PCI_QUIRK(0x0e11, 0x008a, "AD1885", 41000),
+	SND_PCI_QUIRK(0x1014, 0x0581, "AD1981B", 48000),
 	SND_PCI_QUIRK(0x1028, 0x00be, "AD1885", 44100),
 	SND_PCI_QUIRK(0x1028, 0x0177, "AD1980", 48000),
 	SND_PCI_QUIRK(0x1028, 0x01ad, "AD1981B", 48000),
--- zfcpdump-kernel-4.4.orig/sound/pci/pcxhr/pcxhr_core.c
+++ zfcpdump-kernel-4.4/sound/pci/pcxhr/pcxhr_core.c
@@ -1341,5 +1341,6 @@ irqreturn_t pcxhr_threaded_irq(int irq,
 	}
 
 	pcxhr_msg_thread(mgr);
+	mutex_unlock(&mgr->lock);
 	return IRQ_HANDLED;
 }
--- zfcpdump-kernel-4.4.orig/sound/pci/rme9652/hdsp.c
+++ zfcpdump-kernel-4.4/sound/pci/rme9652/hdsp.c
@@ -2879,7 +2879,7 @@ static int snd_hdsp_get_dds_offset(struc
 {
 	struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
 
-	ucontrol->value.enumerated.item[0] = hdsp_dds_offset(hdsp);
+	ucontrol->value.integer.value[0] = hdsp_dds_offset(hdsp);
 	return 0;
 }
 
@@ -2891,7 +2891,7 @@ static int snd_hdsp_put_dds_offset(struc
 
 	if (!snd_hdsp_use_is_exclusive(hdsp))
 		return -EBUSY;
-	val = ucontrol->value.enumerated.item[0];
+	val = ucontrol->value.integer.value[0];
 	spin_lock_irq(&hdsp->lock);
 	if (val != hdsp_dds_offset(hdsp))
 		change = (hdsp_set_dds_offset(hdsp, val) == 0) ? 1 : 0;
--- zfcpdump-kernel-4.4.orig/sound/pci/rme9652/hdspm.c
+++ zfcpdump-kernel-4.4/sound/pci/rme9652/hdspm.c
@@ -1601,6 +1601,9 @@ static void hdspm_set_dds_value(struct h
 {
 	u64 n;
 
+	if (snd_BUG_ON(rate <= 0))
+		return;
+
 	if (rate >= 112000)
 		rate /= 4;
 	else if (rate >= 56000)
@@ -2215,6 +2218,8 @@ static int hdspm_get_system_sample_rate(
 		} else {
 			/* slave mode, return external sample rate */
 			rate = hdspm_external_sample_rate(hdspm);
+			if (!rate)
+				rate = hdspm->system_sample_rate;
 		}
 	}
 
@@ -2260,8 +2265,11 @@ static int snd_hdspm_put_system_sample_r
 					    ucontrol)
 {
 	struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
+	int rate = ucontrol->value.integer.value[0];
 
-	hdspm_set_dds_value(hdspm, ucontrol->value.enumerated.item[0]);
+	if (rate < 27000 || rate > 207000)
+		return -EINVAL;
+	hdspm_set_dds_value(hdspm, ucontrol->value.integer.value[0]);
 	return 0;
 }
 
@@ -4449,7 +4457,7 @@ static int snd_hdspm_get_tco_word_term(s
 {
 	struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
 
-	ucontrol->value.enumerated.item[0] = hdspm->tco->term;
+	ucontrol->value.integer.value[0] = hdspm->tco->term;
 
 	return 0;
 }
@@ -4460,8 +4468,8 @@ static int snd_hdspm_put_tco_word_term(s
 {
 	struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
 
-	if (hdspm->tco->term != ucontrol->value.enumerated.item[0]) {
-		hdspm->tco->term = ucontrol->value.enumerated.item[0];
+	if (hdspm->tco->term != ucontrol->value.integer.value[0]) {
+		hdspm->tco->term = ucontrol->value.integer.value[0];
 
 		hdspm_tco_write(hdspm);
 
--- zfcpdump-kernel-4.4.orig/sound/soc/atmel/atmel_ssc_dai.c
+++ zfcpdump-kernel-4.4/sound/soc/atmel/atmel_ssc_dai.c
@@ -298,8 +298,9 @@ static int atmel_ssc_startup(struct snd_
 	clk_enable(ssc_p->ssc->clk);
 	ssc_p->mck_rate = clk_get_rate(ssc_p->ssc->clk);
 
-	/* Reset the SSC to keep it at a clean status */
-	ssc_writel(ssc_p->ssc->regs, CR, SSC_BIT(CR_SWRST));
+	/* Reset the SSC unless initialized to keep it in a clean state */
+	if (!ssc_p->initialized)
+		ssc_writel(ssc_p->ssc->regs, CR, SSC_BIT(CR_SWRST));
 
 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
 		dir = 0;
--- zfcpdump-kernel-4.4.orig/sound/soc/codecs/ak4642.c
+++ zfcpdump-kernel-4.4/sound/soc/codecs/ak4642.c
@@ -560,6 +560,7 @@ static const struct regmap_config ak4642
 	.max_register		= FIL1_3,
 	.reg_defaults		= ak4642_reg,
 	.num_reg_defaults	= NUM_AK4642_REG_DEFAULTS,
+	.cache_type		= REGCACHE_RBTREE,
 };
 
 static const struct regmap_config ak4643_regmap = {
@@ -568,6 +569,7 @@ static const struct regmap_config ak4643
 	.max_register		= SPK_MS,
 	.reg_defaults		= ak4643_reg,
 	.num_reg_defaults	= ARRAY_SIZE(ak4643_reg),
+	.cache_type		= REGCACHE_RBTREE,
 };
 
 static const struct regmap_config ak4648_regmap = {
@@ -576,6 +578,7 @@ static const struct regmap_config ak4648
 	.max_register		= EQ_FBEQE,
 	.reg_defaults		= ak4648_reg,
 	.num_reg_defaults	= ARRAY_SIZE(ak4648_reg),
+	.cache_type		= REGCACHE_RBTREE,
 };
 
 static const struct ak4642_drvdata ak4642_drvdata = {
--- zfcpdump-kernel-4.4.orig/sound/soc/codecs/rt5640.c
+++ zfcpdump-kernel-4.4/sound/soc/codecs/rt5640.c
@@ -359,7 +359,7 @@ static const DECLARE_TLV_DB_RANGE(bst_tl
 
 /* Interface data select */
 static const char * const rt5640_data_select[] = {
-	"Normal", "left copy to right", "right copy to left", "Swap"};
+	"Normal", "Swap", "left copy to right", "right copy to left"};
 
 static SOC_ENUM_SINGLE_DECL(rt5640_if1_dac_enum, RT5640_DIG_INF_DATA,
 			    RT5640_IF1_DAC_SEL_SFT, rt5640_data_select);
--- zfcpdump-kernel-4.4.orig/sound/soc/codecs/rt5640.h
+++ zfcpdump-kernel-4.4/sound/soc/codecs/rt5640.h
@@ -442,39 +442,39 @@
 #define RT5640_IF1_DAC_SEL_MASK			(0x3 << 14)
 #define RT5640_IF1_DAC_SEL_SFT			14
 #define RT5640_IF1_DAC_SEL_NOR			(0x0 << 14)
-#define RT5640_IF1_DAC_SEL_L2R			(0x1 << 14)
-#define RT5640_IF1_DAC_SEL_R2L			(0x2 << 14)
-#define RT5640_IF1_DAC_SEL_SWAP			(0x3 << 14)
+#define RT5640_IF1_DAC_SEL_SWAP			(0x1 << 14)
+#define RT5640_IF1_DAC_SEL_L2R			(0x2 << 14)
+#define RT5640_IF1_DAC_SEL_R2L			(0x3 << 14)
 #define RT5640_IF1_ADC_SEL_MASK			(0x3 << 12)
 #define RT5640_IF1_ADC_SEL_SFT			12
 #define RT5640_IF1_ADC_SEL_NOR			(0x0 << 12)
-#define RT5640_IF1_ADC_SEL_L2R			(0x1 << 12)
-#define RT5640_IF1_ADC_SEL_R2L			(0x2 << 12)
-#define RT5640_IF1_ADC_SEL_SWAP			(0x3 << 12)
+#define RT5640_IF1_ADC_SEL_SWAP			(0x1 << 12)
+#define RT5640_IF1_ADC_SEL_L2R			(0x2 << 12)
+#define RT5640_IF1_ADC_SEL_R2L			(0x3 << 12)
 #define RT5640_IF2_DAC_SEL_MASK			(0x3 << 10)
 #define RT5640_IF2_DAC_SEL_SFT			10
 #define RT5640_IF2_DAC_SEL_NOR			(0x0 << 10)
-#define RT5640_IF2_DAC_SEL_L2R			(0x1 << 10)
-#define RT5640_IF2_DAC_SEL_R2L			(0x2 << 10)
-#define RT5640_IF2_DAC_SEL_SWAP			(0x3 << 10)
+#define RT5640_IF2_DAC_SEL_SWAP			(0x1 << 10)
+#define RT5640_IF2_DAC_SEL_L2R			(0x2 << 10)
+#define RT5640_IF2_DAC_SEL_R2L			(0x3 << 10)
 #define RT5640_IF2_ADC_SEL_MASK			(0x3 << 8)
 #define RT5640_IF2_ADC_SEL_SFT			8
 #define RT5640_IF2_ADC_SEL_NOR			(0x0 << 8)
-#define RT5640_IF2_ADC_SEL_L2R			(0x1 << 8)
-#define RT5640_IF2_ADC_SEL_R2L			(0x2 << 8)
-#define RT5640_IF2_ADC_SEL_SWAP			(0x3 << 8)
+#define RT5640_IF2_ADC_SEL_SWAP			(0x1 << 8)
+#define RT5640_IF2_ADC_SEL_L2R			(0x2 << 8)
+#define RT5640_IF2_ADC_SEL_R2L			(0x3 << 8)
 #define RT5640_IF3_DAC_SEL_MASK			(0x3 << 6)
 #define RT5640_IF3_DAC_SEL_SFT			6
 #define RT5640_IF3_DAC_SEL_NOR			(0x0 << 6)
-#define RT5640_IF3_DAC_SEL_L2R			(0x1 << 6)
-#define RT5640_IF3_DAC_SEL_R2L			(0x2 << 6)
-#define RT5640_IF3_DAC_SEL_SWAP			(0x3 << 6)
+#define RT5640_IF3_DAC_SEL_SWAP			(0x1 << 6)
+#define RT5640_IF3_DAC_SEL_L2R			(0x2 << 6)
+#define RT5640_IF3_DAC_SEL_R2L			(0x3 << 6)
 #define RT5640_IF3_ADC_SEL_MASK			(0x3 << 4)
 #define RT5640_IF3_ADC_SEL_SFT			4
 #define RT5640_IF3_ADC_SEL_NOR			(0x0 << 4)
-#define RT5640_IF3_ADC_SEL_L2R			(0x1 << 4)
-#define RT5640_IF3_ADC_SEL_R2L			(0x2 << 4)
-#define RT5640_IF3_ADC_SEL_SWAP			(0x3 << 4)
+#define RT5640_IF3_ADC_SEL_SWAP			(0x1 << 4)
+#define RT5640_IF3_ADC_SEL_L2R			(0x2 << 4)
+#define RT5640_IF3_ADC_SEL_R2L			(0x3 << 4)
 
 /* REC Left Mixer Control 1 (0x3b) */
 #define RT5640_G_HP_L_RM_L_MASK			(0x7 << 13)
--- zfcpdump-kernel-4.4.orig/sound/soc/codecs/rt5645.c
+++ zfcpdump-kernel-4.4/sound/soc/codecs/rt5645.c
@@ -621,7 +621,7 @@ static const struct snd_kcontrol_new rt5
 
 	/* IN1/IN2 Control */
 	SOC_SINGLE_TLV("IN1 Boost", RT5645_IN1_CTRL1,
-		RT5645_BST_SFT1, 8, 0, bst_tlv),
+		RT5645_BST_SFT1, 12, 0, bst_tlv),
 	SOC_SINGLE_TLV("IN2 Boost", RT5645_IN2_CTRL,
 		RT5645_BST_SFT2, 8, 0, bst_tlv),
 
--- zfcpdump-kernel-4.4.orig/sound/soc/codecs/ssm4567.c
+++ zfcpdump-kernel-4.4/sound/soc/codecs/ssm4567.c
@@ -352,6 +352,11 @@ static int ssm4567_set_power(struct ssm4
 	regcache_cache_only(ssm4567->regmap, !enable);
 
 	if (enable) {
+		ret = regmap_write(ssm4567->regmap, SSM4567_REG_SOFT_RESET,
+			0x00);
+		if (ret)
+			return ret;
+
 		ret = regmap_update_bits(ssm4567->regmap,
 			SSM4567_REG_POWER_CTRL,
 			SSM4567_POWER_SPWDN, 0x00);
--- zfcpdump-kernel-4.4.orig/sound/soc/codecs/wm5110.c
+++ zfcpdump-kernel-4.4/sound/soc/codecs/wm5110.c
@@ -360,15 +360,13 @@ static int wm5110_hp_ev(struct snd_soc_d
 
 static int wm5110_clear_pga_volume(struct arizona *arizona, int output)
 {
-	struct reg_sequence clear_pga = {
-		ARIZONA_OUTPUT_PATH_CONFIG_1L + output * 4, 0x80
-	};
+	unsigned int reg = ARIZONA_OUTPUT_PATH_CONFIG_1L + output * 4;
 	int ret;
 
-	ret = regmap_multi_reg_write_bypassed(arizona->regmap, &clear_pga, 1);
+	ret = regmap_write(arizona->regmap, reg, 0x80);
 	if (ret)
 		dev_err(arizona->dev, "Failed to clear PGA (0x%x): %d\n",
-			clear_pga.reg, ret);
+			reg, ret);
 
 	return ret;
 }
--- zfcpdump-kernel-4.4.orig/sound/soc/codecs/wm8958-dsp2.c
+++ zfcpdump-kernel-4.4/sound/soc/codecs/wm8958-dsp2.c
@@ -459,7 +459,7 @@ static int wm8958_put_mbc_enum(struct sn
 	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
 	struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
 	struct wm8994 *control = wm8994->wm8994;
-	int value = ucontrol->value.integer.value[0];
+	int value = ucontrol->value.enumerated.item[0];
 	int reg;
 
 	/* Don't allow on the fly reconfiguration */
@@ -549,7 +549,7 @@ static int wm8958_put_vss_enum(struct sn
 	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
 	struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
 	struct wm8994 *control = wm8994->wm8994;
-	int value = ucontrol->value.integer.value[0];
+	int value = ucontrol->value.enumerated.item[0];
 	int reg;
 
 	/* Don't allow on the fly reconfiguration */
@@ -582,7 +582,7 @@ static int wm8958_put_vss_hpf_enum(struc
 	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
 	struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
 	struct wm8994 *control = wm8994->wm8994;
-	int value = ucontrol->value.integer.value[0];
+	int value = ucontrol->value.enumerated.item[0];
 	int reg;
 
 	/* Don't allow on the fly reconfiguration */
@@ -749,7 +749,7 @@ static int wm8958_put_enh_eq_enum(struct
 	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
 	struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
 	struct wm8994 *control = wm8994->wm8994;
-	int value = ucontrol->value.integer.value[0];
+	int value = ucontrol->value.enumerated.item[0];
 	int reg;
 
 	/* Don't allow on the fly reconfiguration */
--- zfcpdump-kernel-4.4.orig/sound/soc/codecs/wm8994.c
+++ zfcpdump-kernel-4.4/sound/soc/codecs/wm8994.c
@@ -362,7 +362,7 @@ static int wm8994_put_drc_enum(struct sn
 	struct wm8994 *control = wm8994->wm8994;
 	struct wm8994_pdata *pdata = &control->pdata;
 	int drc = wm8994_get_drc(kcontrol->id.name);
-	int value = ucontrol->value.integer.value[0];
+	int value = ucontrol->value.enumerated.item[0];
 
 	if (drc < 0)
 		return drc;
@@ -469,7 +469,7 @@ static int wm8994_put_retune_mobile_enum
 	struct wm8994 *control = wm8994->wm8994;
 	struct wm8994_pdata *pdata = &control->pdata;
 	int block = wm8994_get_retune_mobile_block(kcontrol->id.name);
-	int value = ucontrol->value.integer.value[0];
+	int value = ucontrol->value.enumerated.item[0];
 
 	if (block < 0)
 		return block;
--- zfcpdump-kernel-4.4.orig/sound/soc/intel/skylake/skl.c
+++ zfcpdump-kernel-4.4/sound/soc/intel/skylake/skl.c
@@ -464,8 +464,10 @@ static int skl_probe(struct pci_dev *pci
 
 	skl->nhlt = skl_nhlt_init(bus->dev);
 
-	if (skl->nhlt == NULL)
+	if (skl->nhlt == NULL) {
+		err = -ENODEV;
 		goto out_free;
+	}
 
 	pci_set_drvdata(skl->pci, ebus);
 
--- zfcpdump-kernel-4.4.orig/sound/soc/omap/omap-mcpdm.c
+++ zfcpdump-kernel-4.4/sound/soc/omap/omap-mcpdm.c
@@ -390,8 +390,8 @@ static int omap_mcpdm_probe(struct snd_s
 	pm_runtime_get_sync(mcpdm->dev);
 	omap_mcpdm_write(mcpdm, MCPDM_REG_CTRL, 0x00);
 
-	ret = devm_request_irq(mcpdm->dev, mcpdm->irq, omap_mcpdm_irq_handler,
-				0, "McPDM", (void *)mcpdm);
+	ret = request_irq(mcpdm->irq, omap_mcpdm_irq_handler, 0, "McPDM",
+			  (void *)mcpdm);
 
 	pm_runtime_put_sync(mcpdm->dev);
 
@@ -416,6 +416,7 @@ static int omap_mcpdm_remove(struct snd_
 {
 	struct omap_mcpdm *mcpdm = snd_soc_dai_get_drvdata(dai);
 
+	free_irq(mcpdm->irq, (void *)mcpdm);
 	pm_runtime_disable(mcpdm->dev);
 
 	return 0;
--- zfcpdump-kernel-4.4.orig/sound/soc/samsung/ac97.c
+++ zfcpdump-kernel-4.4/sound/soc/samsung/ac97.c
@@ -324,7 +324,7 @@ static const struct snd_soc_component_dr
 
 static int s3c_ac97_probe(struct platform_device *pdev)
 {
-	struct resource *mem_res, *dmatx_res, *dmarx_res, *dmamic_res, *irq_res;
+	struct resource *mem_res, *irq_res;
 	struct s3c_audio_pdata *ac97_pdata;
 	int ret;
 
@@ -335,24 +335,6 @@ static int s3c_ac97_probe(struct platfor
 	}
 
 	/* Check for availability of necessary resource */
-	dmatx_res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
-	if (!dmatx_res) {
-		dev_err(&pdev->dev, "Unable to get AC97-TX dma resource\n");
-		return -ENXIO;
-	}
-
-	dmarx_res = platform_get_resource(pdev, IORESOURCE_DMA, 1);
-	if (!dmarx_res) {
-		dev_err(&pdev->dev, "Unable to get AC97-RX dma resource\n");
-		return -ENXIO;
-	}
-
-	dmamic_res = platform_get_resource(pdev, IORESOURCE_DMA, 2);
-	if (!dmamic_res) {
-		dev_err(&pdev->dev, "Unable to get AC97-MIC dma resource\n");
-		return -ENXIO;
-	}
-
 	irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
 	if (!irq_res) {
 		dev_err(&pdev->dev, "AC97 IRQ not provided!\n");
@@ -364,11 +346,11 @@ static int s3c_ac97_probe(struct platfor
 	if (IS_ERR(s3c_ac97.regs))
 		return PTR_ERR(s3c_ac97.regs);
 
-	s3c_ac97_pcm_out.channel = dmatx_res->start;
+	s3c_ac97_pcm_out.slave = ac97_pdata->dma_playback;
 	s3c_ac97_pcm_out.dma_addr = mem_res->start + S3C_AC97_PCM_DATA;
-	s3c_ac97_pcm_in.channel = dmarx_res->start;
+	s3c_ac97_pcm_in.slave = ac97_pdata->dma_capture;
 	s3c_ac97_pcm_in.dma_addr = mem_res->start + S3C_AC97_PCM_DATA;
-	s3c_ac97_mic_in.channel = dmamic_res->start;
+	s3c_ac97_mic_in.slave = ac97_pdata->dma_capture_mic;
 	s3c_ac97_mic_in.dma_addr = mem_res->start + S3C_AC97_MIC_DATA;
 
 	init_completion(&s3c_ac97.done);
--- zfcpdump-kernel-4.4.orig/sound/soc/samsung/dma.h
+++ zfcpdump-kernel-4.4/sound/soc/samsung/dma.h
@@ -15,7 +15,7 @@
 #include <sound/dmaengine_pcm.h>
 
 struct s3c_dma_params {
-	int channel;				/* Channel ID */
+	void *slave;				/* Channel ID */
 	dma_addr_t dma_addr;
 	int dma_size;			/* Size of the DMA transfer */
 	char *ch_name;
--- zfcpdump-kernel-4.4.orig/sound/soc/samsung/dmaengine.c
+++ zfcpdump-kernel-4.4/sound/soc/samsung/dmaengine.c
@@ -50,14 +50,14 @@ void samsung_asoc_init_dma_data(struct s
 
 	if (playback) {
 		playback_data = &playback->dma_data;
-		playback_data->filter_data = (void *)playback->channel;
+		playback_data->filter_data = playback->slave;
 		playback_data->chan_name = playback->ch_name;
 		playback_data->addr = playback->dma_addr;
 		playback_data->addr_width = playback->dma_size;
 	}
 	if (capture) {
 		capture_data = &capture->dma_data;
-		capture_data->filter_data = (void *)capture->channel;
+		capture_data->filter_data = capture->slave;
 		capture_data->chan_name = capture->ch_name;
 		capture_data->addr = capture->dma_addr;
 		capture_data->addr_width = capture->dma_size;
--- zfcpdump-kernel-4.4.orig/sound/soc/samsung/i2s.c
+++ zfcpdump-kernel-4.4/sound/soc/samsung/i2s.c
@@ -480,10 +480,11 @@ static int i2s_set_sysclk(struct snd_soc
 	unsigned int cdcon_mask = 1 << i2s_regs->cdclkcon_off;
 	unsigned int rsrc_mask = 1 << i2s_regs->rclksrc_off;
 	u32 mod, mask, val = 0;
+	unsigned long flags;
 
-	spin_lock(i2s->lock);
+	spin_lock_irqsave(i2s->lock, flags);
 	mod = readl(i2s->addr + I2SMOD);
-	spin_unlock(i2s->lock);
+	spin_unlock_irqrestore(i2s->lock, flags);
 
 	switch (clk_id) {
 	case SAMSUNG_I2S_OPCLK:
@@ -574,11 +575,11 @@ static int i2s_set_sysclk(struct snd_soc
 		return -EINVAL;
 	}
 
-	spin_lock(i2s->lock);
+	spin_lock_irqsave(i2s->lock, flags);
 	mod = readl(i2s->addr + I2SMOD);
 	mod = (mod & ~mask) | val;
 	writel(mod, i2s->addr + I2SMOD);
-	spin_unlock(i2s->lock);
+	spin_unlock_irqrestore(i2s->lock, flags);
 
 	return 0;
 }
@@ -589,6 +590,7 @@ static int i2s_set_fmt(struct snd_soc_da
 	struct i2s_dai *i2s = to_info(dai);
 	int lrp_shift, sdf_shift, sdf_mask, lrp_rlow, mod_slave;
 	u32 mod, tmp = 0;
+	unsigned long flags;
 
 	lrp_shift = i2s->variant_regs->lrp_off;
 	sdf_shift = i2s->variant_regs->sdf_off;
@@ -648,7 +650,7 @@ static int i2s_set_fmt(struct snd_soc_da
 		return -EINVAL;
 	}
 
-	spin_lock(i2s->lock);
+	spin_lock_irqsave(i2s->lock, flags);
 	mod = readl(i2s->addr + I2SMOD);
 	/*
 	 * Don't change the I2S mode if any controller is active on this
@@ -656,7 +658,7 @@ static int i2s_set_fmt(struct snd_soc_da
 	 */
 	if (any_active(i2s) &&
 		((mod & (sdf_mask | lrp_rlow | mod_slave)) != tmp)) {
-		spin_unlock(i2s->lock);
+		spin_unlock_irqrestore(i2s->lock, flags);
 		dev_err(&i2s->pdev->dev,
 				"%s:%d Other DAI busy\n", __func__, __LINE__);
 		return -EAGAIN;
@@ -665,7 +667,7 @@ static int i2s_set_fmt(struct snd_soc_da
 	mod &= ~(sdf_mask | lrp_rlow | mod_slave);
 	mod |= tmp;
 	writel(mod, i2s->addr + I2SMOD);
-	spin_unlock(i2s->lock);
+	spin_unlock_irqrestore(i2s->lock, flags);
 
 	return 0;
 }
@@ -675,6 +677,7 @@ static int i2s_hw_params(struct snd_pcm_
 {
 	struct i2s_dai *i2s = to_info(dai);
 	u32 mod, mask = 0, val = 0;
+	unsigned long flags;
 
 	if (!is_secondary(i2s))
 		mask |= (MOD_DC2_EN | MOD_DC1_EN);
@@ -743,11 +746,11 @@ static int i2s_hw_params(struct snd_pcm_
 		return -EINVAL;
 	}
 
-	spin_lock(i2s->lock);
+	spin_lock_irqsave(i2s->lock, flags);
 	mod = readl(i2s->addr + I2SMOD);
 	mod = (mod & ~mask) | val;
 	writel(mod, i2s->addr + I2SMOD);
-	spin_unlock(i2s->lock);
+	spin_unlock_irqrestore(i2s->lock, flags);
 
 	samsung_asoc_init_dma_data(dai, &i2s->dma_playback, &i2s->dma_capture);
 
@@ -1257,27 +1260,14 @@ static int samsung_i2s_probe(struct plat
 	pri_dai->lock = &pri_dai->spinlock;
 
 	if (!np) {
-		res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
-		if (!res) {
-			dev_err(&pdev->dev,
-				"Unable to get I2S-TX dma resource\n");
-			return -ENXIO;
-		}
-		pri_dai->dma_playback.channel = res->start;
-
-		res = platform_get_resource(pdev, IORESOURCE_DMA, 1);
-		if (!res) {
-			dev_err(&pdev->dev,
-				"Unable to get I2S-RX dma resource\n");
-			return -ENXIO;
-		}
-		pri_dai->dma_capture.channel = res->start;
-
 		if (i2s_pdata == NULL) {
 			dev_err(&pdev->dev, "Can't work without s3c_audio_pdata\n");
 			return -EINVAL;
 		}
 
+		pri_dai->dma_playback.slave = i2s_pdata->dma_playback;
+		pri_dai->dma_capture.slave = i2s_pdata->dma_capture;
+
 		if (&i2s_pdata->type)
 			i2s_cfg = &i2s_pdata->type.i2s;
 
@@ -1338,11 +1328,8 @@ static int samsung_i2s_probe(struct plat
 		sec_dai->dma_playback.dma_addr = regs_base + I2STXDS;
 		sec_dai->dma_playback.ch_name = "tx-sec";
 
-		if (!np) {
-			res = platform_get_resource(pdev, IORESOURCE_DMA, 2);
-			if (res)
-				sec_dai->dma_playback.channel = res->start;
-		}
+		if (!np)
+			sec_dai->dma_playback.slave = i2s_pdata->dma_play_sec;
 
 		sec_dai->dma_playback.dma_size = 4;
 		sec_dai->addr = pri_dai->addr;
--- zfcpdump-kernel-4.4.orig/sound/soc/samsung/pcm.c
+++ zfcpdump-kernel-4.4/sound/soc/samsung/pcm.c
@@ -486,7 +486,7 @@ static const struct snd_soc_component_dr
 static int s3c_pcm_dev_probe(struct platform_device *pdev)
 {
 	struct s3c_pcm_info *pcm;
-	struct resource *mem_res, *dmatx_res, *dmarx_res;
+	struct resource *mem_res;
 	struct s3c_audio_pdata *pcm_pdata;
 	int ret;
 
@@ -499,18 +499,6 @@ static int s3c_pcm_dev_probe(struct plat
 	pcm_pdata = pdev->dev.platform_data;
 
 	/* Check for availability of necessary resource */
-	dmatx_res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
-	if (!dmatx_res) {
-		dev_err(&pdev->dev, "Unable to get PCM-TX dma resource\n");
-		return -ENXIO;
-	}
-
-	dmarx_res = platform_get_resource(pdev, IORESOURCE_DMA, 1);
-	if (!dmarx_res) {
-		dev_err(&pdev->dev, "Unable to get PCM-RX dma resource\n");
-		return -ENXIO;
-	}
-
 	mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	if (!mem_res) {
 		dev_err(&pdev->dev, "Unable to get register resource\n");
@@ -568,8 +556,10 @@ static int s3c_pcm_dev_probe(struct plat
 	s3c_pcm_stereo_out[pdev->id].dma_addr = mem_res->start
 							+ S3C_PCM_TXFIFO;
 
-	s3c_pcm_stereo_in[pdev->id].channel = dmarx_res->start;
-	s3c_pcm_stereo_out[pdev->id].channel = dmatx_res->start;
+	if (pcm_pdata) {
+		s3c_pcm_stereo_in[pdev->id].slave = pcm_pdata->dma_capture;
+		s3c_pcm_stereo_out[pdev->id].slave = pcm_pdata->dma_playback;
+	}
 
 	pcm->dma_capture = &s3c_pcm_stereo_in[pdev->id];
 	pcm->dma_playback = &s3c_pcm_stereo_out[pdev->id];
--- zfcpdump-kernel-4.4.orig/sound/soc/samsung/s3c-i2s-v2.c
+++ zfcpdump-kernel-4.4/sound/soc/samsung/s3c-i2s-v2.c
@@ -709,7 +709,7 @@ static int s3c2412_i2s_resume(struct snd
 #endif
 
 int s3c_i2sv2_register_component(struct device *dev, int id,
-			   struct snd_soc_component_driver *cmp_drv,
+			   const struct snd_soc_component_driver *cmp_drv,
 			   struct snd_soc_dai_driver *dai_drv)
 {
 	struct snd_soc_dai_ops *ops = (struct snd_soc_dai_ops *)dai_drv->ops;
--- zfcpdump-kernel-4.4.orig/sound/soc/samsung/s3c-i2s-v2.h
+++ zfcpdump-kernel-4.4/sound/soc/samsung/s3c-i2s-v2.h
@@ -101,7 +101,7 @@ extern int s3c_i2sv2_probe(struct snd_so
  * soc core.
  */
 extern int s3c_i2sv2_register_component(struct device *dev, int id,
-					struct snd_soc_component_driver *cmp_drv,
+					const struct snd_soc_component_driver *cmp_drv,
 					struct snd_soc_dai_driver *dai_drv);
 
 #endif /* __SND_SOC_S3C24XX_S3C_I2SV2_I2S_H */
--- zfcpdump-kernel-4.4.orig/sound/soc/samsung/s3c2412-i2s.c
+++ zfcpdump-kernel-4.4/sound/soc/samsung/s3c2412-i2s.c
@@ -34,13 +34,13 @@
 #include "s3c2412-i2s.h"
 
 static struct s3c_dma_params s3c2412_i2s_pcm_stereo_out = {
-	.channel	= DMACH_I2S_OUT,
+	.slave		= (void *)(uintptr_t)DMACH_I2S_OUT,
 	.ch_name	= "tx",
 	.dma_size	= 4,
 };
 
 static struct s3c_dma_params s3c2412_i2s_pcm_stereo_in = {
-	.channel	= DMACH_I2S_IN,
+	.slave		= (void *)(uintptr_t)DMACH_I2S_IN,
 	.ch_name	= "rx",
 	.dma_size	= 4,
 };
--- zfcpdump-kernel-4.4.orig/sound/soc/samsung/s3c24xx-i2s.c
+++ zfcpdump-kernel-4.4/sound/soc/samsung/s3c24xx-i2s.c
@@ -32,13 +32,13 @@
 #include "s3c24xx-i2s.h"
 
 static struct s3c_dma_params s3c24xx_i2s_pcm_stereo_out = {
-	.channel	= DMACH_I2S_OUT,
+	.slave		= (void *)(uintptr_t)DMACH_I2S_OUT,
 	.ch_name	= "tx",
 	.dma_size	= 2,
 };
 
 static struct s3c_dma_params s3c24xx_i2s_pcm_stereo_in = {
-	.channel	= DMACH_I2S_IN,
+	.slave		= (void *)(uintptr_t)DMACH_I2S_IN,
 	.ch_name	= "rx",
 	.dma_size	= 2,
 };
--- zfcpdump-kernel-4.4.orig/sound/soc/samsung/spdif.c
+++ zfcpdump-kernel-4.4/sound/soc/samsung/spdif.c
@@ -359,7 +359,7 @@ static const struct snd_soc_component_dr
 static int spdif_probe(struct platform_device *pdev)
 {
 	struct s3c_audio_pdata *spdif_pdata;
-	struct resource *mem_res, *dma_res;
+	struct resource *mem_res;
 	struct samsung_spdif_info *spdif;
 	int ret;
 
@@ -367,12 +367,6 @@ static int spdif_probe(struct platform_d
 
 	dev_dbg(&pdev->dev, "Entered %s\n", __func__);
 
-	dma_res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
-	if (!dma_res) {
-		dev_err(&pdev->dev, "Unable to get dma resource.\n");
-		return -ENXIO;
-	}
-
 	mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	if (!mem_res) {
 		dev_err(&pdev->dev, "Unable to get register resource.\n");
@@ -432,7 +426,7 @@ static int spdif_probe(struct platform_d
 
 	spdif_stereo_out.dma_size = 2;
 	spdif_stereo_out.dma_addr = mem_res->start + DATA_OUTBUF;
-	spdif_stereo_out.channel = dma_res->start;
+	spdif_stereo_out.slave = spdif_pdata ? spdif_pdata->dma_playback : NULL;
 
 	spdif->dma_playback = &spdif_stereo_out;
 
--- zfcpdump-kernel-4.4.orig/sound/soc/soc-compress.c
+++ zfcpdump-kernel-4.4/sound/soc/soc-compress.c
@@ -630,6 +630,7 @@ int snd_soc_new_compress(struct snd_soc_
 	struct snd_pcm *be_pcm;
 	char new_name[64];
 	int ret = 0, direction = 0;
+	int playback = 0, capture = 0;
 
 	if (rtd->num_codecs > 1) {
 		dev_err(rtd->card->dev, "Multicodec not supported for compressed stream\n");
@@ -641,11 +642,27 @@ int snd_soc_new_compress(struct snd_soc_
 			rtd->dai_link->stream_name, codec_dai->name, num);
 
 	if (codec_dai->driver->playback.channels_min)
+		playback = 1;
+	if (codec_dai->driver->capture.channels_min)
+		capture = 1;
+
+	capture = capture && cpu_dai->driver->capture.channels_min;
+	playback = playback && cpu_dai->driver->playback.channels_min;
+
+	/*
+	 * Compress devices are unidirectional so only one of the directions
+	 * should be set, check for that (xor)
+	 */
+	if (playback + capture != 1) {
+		dev_err(rtd->card->dev, "Invalid direction for compress P %d, C %d\n",
+				playback, capture);
+		return -EINVAL;
+	}
+
+	if(playback)
 		direction = SND_COMPRESS_PLAYBACK;
-	else if (codec_dai->driver->capture.channels_min)
-		direction = SND_COMPRESS_CAPTURE;
 	else
-		return -EINVAL;
+		direction = SND_COMPRESS_CAPTURE;
 
 	compr = kzalloc(sizeof(*compr), GFP_KERNEL);
 	if (compr == NULL) {
--- zfcpdump-kernel-4.4.orig/sound/soc/soc-dapm.c
+++ zfcpdump-kernel-4.4/sound/soc/soc-dapm.c
@@ -2188,6 +2188,13 @@ static ssize_t dapm_widget_show_componen
 	int count = 0;
 	char *state = "not set";
 
+	/* card won't be set for the dummy component, as a spot fix
+	 * we're checking for that case specifically here but in future
+	 * we will ensure that the dummy component looks like others.
+	 */
+	if (!cmpnt->card)
+		return 0;
+
 	list_for_each_entry(w, &cmpnt->card->widgets, list) {
 		if (w->dapm != dapm)
 			continue;
@@ -3568,7 +3575,7 @@ static int snd_soc_dapm_dai_link_get(str
 {
 	struct snd_soc_dapm_widget *w = snd_kcontrol_chip(kcontrol);
 
-	ucontrol->value.integer.value[0] = w->params_select;
+	ucontrol->value.enumerated.item[0] = w->params_select;
 
 	return 0;
 }
@@ -3582,13 +3589,13 @@ static int snd_soc_dapm_dai_link_put(str
 	if (w->power)
 		return -EBUSY;
 
-	if (ucontrol->value.integer.value[0] == w->params_select)
+	if (ucontrol->value.enumerated.item[0] == w->params_select)
 		return 0;
 
-	if (ucontrol->value.integer.value[0] >= w->num_params)
+	if (ucontrol->value.enumerated.item[0] >= w->num_params)
 		return -EINVAL;
 
-	w->params_select = ucontrol->value.integer.value[0];
+	w->params_select = ucontrol->value.enumerated.item[0];
 
 	return 0;
 }
--- zfcpdump-kernel-4.4.orig/sound/soc/soc-pcm.c
+++ zfcpdump-kernel-4.4/sound/soc/soc-pcm.c
@@ -1743,7 +1743,8 @@ int dpcm_be_dai_hw_free(struct snd_soc_p
 		    (be->dpcm[stream].state != SND_SOC_DPCM_STATE_PREPARE) &&
 		    (be->dpcm[stream].state != SND_SOC_DPCM_STATE_HW_FREE) &&
 		    (be->dpcm[stream].state != SND_SOC_DPCM_STATE_PAUSED) &&
-		    (be->dpcm[stream].state != SND_SOC_DPCM_STATE_STOP))
+		    (be->dpcm[stream].state != SND_SOC_DPCM_STATE_STOP) &&
+		    (be->dpcm[stream].state != SND_SOC_DPCM_STATE_SUSPEND))
 			continue;
 
 		dev_dbg(be->dev, "ASoC: hw_free BE %s\n",
--- zfcpdump-kernel-4.4.orig/sound/sparc/Kconfig
+++ zfcpdump-kernel-4.4/sound/sparc/Kconfig
@@ -22,6 +22,7 @@ config SND_SUN_AMD7930
 config SND_SUN_CS4231
 	tristate "Sun CS4231"
 	select SND_PCM
+	select SND_TIMER
 	help
 	  Say Y here to include support for CS4231 sound device on Sun.
 
--- zfcpdump-kernel-4.4.orig/sound/usb/card.c
+++ zfcpdump-kernel-4.4/sound/usb/card.c
@@ -675,6 +675,8 @@ int snd_usb_autoresume(struct snd_usb_au
 
 void snd_usb_autosuspend(struct snd_usb_audio *chip)
 {
+	if (atomic_read(&chip->shutdown))
+		return;
 	if (atomic_dec_and_test(&chip->active))
 		usb_autopm_put_interface(chip->pm_intf);
 }
--- zfcpdump-kernel-4.4.orig/sound/usb/clock.c
+++ zfcpdump-kernel-4.4/sound/usb/clock.c
@@ -285,6 +285,8 @@ static int set_sample_rate_v1(struct snd
 	unsigned char data[3];
 	int err, crate;
 
+	if (get_iface_desc(alts)->bNumEndpoints < 1)
+		return -EINVAL;
 	ep = get_endpoint(alts, 0)->bEndpointAddress;
 
 	/* if endpoint doesn't have sampling rate control, bail out */
--- zfcpdump-kernel-4.4.orig/sound/usb/endpoint.c
+++ zfcpdump-kernel-4.4/sound/usb/endpoint.c
@@ -438,6 +438,9 @@ exit_clear:
  *
  * New endpoints will be added to chip->ep_list and must be freed by
  * calling snd_usb_endpoint_free().
+ *
+ * For SND_USB_ENDPOINT_TYPE_SYNC, the caller needs to guarantee that
+ * bNumEndpoints > 1 beforehand.
  */
 struct snd_usb_endpoint *snd_usb_add_endpoint(struct snd_usb_audio *chip,
 					      struct usb_host_interface *alts,
--- zfcpdump-kernel-4.4.orig/sound/usb/line6/pcm.c
+++ zfcpdump-kernel-4.4/sound/usb/line6/pcm.c
@@ -55,7 +55,6 @@ static int snd_line6_impulse_volume_put(
 		err = line6_pcm_acquire(line6pcm, LINE6_STREAM_IMPULSE);
 		if (err < 0) {
 			line6pcm->impulse_volume = 0;
-			line6_pcm_release(line6pcm, LINE6_STREAM_IMPULSE);
 			return err;
 		}
 	} else {
@@ -211,7 +210,9 @@ static void line6_stream_stop(struct snd
 	spin_lock_irqsave(&pstr->lock, flags);
 	clear_bit(type, &pstr->running);
 	if (!pstr->running) {
+		spin_unlock_irqrestore(&pstr->lock, flags);
 		line6_unlink_audio_urbs(line6pcm, pstr);
+		spin_lock_irqsave(&pstr->lock, flags);
 		if (direction == SNDRV_PCM_STREAM_CAPTURE) {
 			line6pcm->prev_fbuf = NULL;
 			line6pcm->prev_fsize = 0;
--- zfcpdump-kernel-4.4.orig/sound/usb/line6/pod.c
+++ zfcpdump-kernel-4.4/sound/usb/line6/pod.c
@@ -244,8 +244,8 @@ static int pod_set_system_param_int(stru
 static ssize_t serial_number_show(struct device *dev,
 				  struct device_attribute *attr, char *buf)
 {
-	struct usb_interface *interface = to_usb_interface(dev);
-	struct usb_line6_pod *pod = usb_get_intfdata(interface);
+	struct snd_card *card = dev_to_snd_card(dev);
+	struct usb_line6_pod *pod = card->private_data;
 
 	return sprintf(buf, "%u\n", pod->serial_number);
 }
@@ -256,8 +256,8 @@ static ssize_t serial_number_show(struct
 static ssize_t firmware_version_show(struct device *dev,
 				     struct device_attribute *attr, char *buf)
 {
-	struct usb_interface *interface = to_usb_interface(dev);
-	struct usb_line6_pod *pod = usb_get_intfdata(interface);
+	struct snd_card *card = dev_to_snd_card(dev);
+	struct usb_line6_pod *pod = card->private_data;
 
 	return sprintf(buf, "%d.%02d\n", pod->firmware_version / 100,
 		       pod->firmware_version % 100);
@@ -269,8 +269,8 @@ static ssize_t firmware_version_show(str
 static ssize_t device_id_show(struct device *dev,
 			      struct device_attribute *attr, char *buf)
 {
-	struct usb_interface *interface = to_usb_interface(dev);
-	struct usb_line6_pod *pod = usb_get_intfdata(interface);
+	struct snd_card *card = dev_to_snd_card(dev);
+	struct usb_line6_pod *pod = card->private_data;
 
 	return sprintf(buf, "%d\n", pod->device_id);
 }
--- zfcpdump-kernel-4.4.orig/sound/usb/midi.c
+++ zfcpdump-kernel-4.4/sound/usb/midi.c
@@ -2454,7 +2454,6 @@ int snd_usbmidi_create(struct snd_card *
 	else
 		err = snd_usbmidi_create_endpoints(umidi, endpoints);
 	if (err < 0) {
-		snd_usbmidi_free(umidi);
 		return err;
 	}
 
--- zfcpdump-kernel-4.4.orig/sound/usb/mixer_maps.c
+++ zfcpdump-kernel-4.4/sound/usb/mixer_maps.c
@@ -349,6 +349,16 @@ static struct usbmix_name_map bose_compa
 };
 
 /*
+ * Dell usb dock with ALC4020 codec had a firmware problem where it got
+ * screwed up when zero volume is passed; just skip it as a workaround
+ */
+static const struct usbmix_name_map dell_alc4020_map[] = {
+	{ 16, NULL },
+	{ 19, NULL },
+	{ 0 }
+};
+
+/*
  * Control map entries
  */
 
@@ -431,6 +441,10 @@ static struct usbmix_ctl_map usbmix_ctl_
 		.map = aureon_51_2_map,
 	},
 	{
+		.id = USB_ID(0x0bda, 0x4014),
+		.map = dell_alc4020_map,
+	},
+	{
 		.id = USB_ID(0x0dba, 0x1000),
 		.map = mbox1_map,
 	},
--- zfcpdump-kernel-4.4.orig/sound/usb/mixer_quirks.c
+++ zfcpdump-kernel-4.4/sound/usb/mixer_quirks.c
@@ -793,7 +793,7 @@ static int snd_nativeinstruments_control
 		return 0;
 
 	kcontrol->private_value &= ~(0xff << 24);
-	kcontrol->private_value |= newval;
+	kcontrol->private_value |= (unsigned int)newval << 24;
 	err = snd_ni_update_cur_val(list);
 	return err < 0 ? err : 1;
 }
@@ -1519,7 +1519,11 @@ static int snd_microii_spdif_default_get
 
 	/* use known values for that card: interface#1 altsetting#1 */
 	iface = usb_ifnum_to_if(chip->dev, 1);
+	if (!iface || iface->num_altsetting < 2)
+		return -EINVAL;
 	alts = &iface->altsetting[1];
+	if (get_iface_desc(alts)->bNumEndpoints < 1)
+		return -EINVAL;
 	ep = get_endpoint(alts, 0)->bEndpointAddress;
 
 	err = snd_usb_ctl_msg(chip->dev,
--- zfcpdump-kernel-4.4.orig/sound/usb/pcm.c
+++ zfcpdump-kernel-4.4/sound/usb/pcm.c
@@ -159,6 +159,8 @@ static int init_pitch_v1(struct snd_usb_
 	unsigned char data[1];
 	int err;
 
+	if (get_iface_desc(alts)->bNumEndpoints < 1)
+		return -EINVAL;
 	ep = get_endpoint(alts, 0)->bEndpointAddress;
 
 	data[0] = 1;
--- zfcpdump-kernel-4.4.orig/sound/usb/quirks.c
+++ zfcpdump-kernel-4.4/sound/usb/quirks.c
@@ -150,6 +150,7 @@ static int create_fixed_stream_quirk(str
 		usb_audio_err(chip, "cannot memdup\n");
 		return -ENOMEM;
 	}
+	INIT_LIST_HEAD(&fp->list);
 	if (fp->nr_rates > MAX_NR_RATES) {
 		kfree(fp);
 		return -EINVAL;
@@ -167,19 +168,20 @@ static int create_fixed_stream_quirk(str
 	stream = (fp->endpoint & USB_DIR_IN)
 		? SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK;
 	err = snd_usb_add_audio_stream(chip, stream, fp);
-	if (err < 0) {
-		kfree(fp);
-		kfree(rate_table);
-		return err;
-	}
+	if (err < 0)
+		goto error;
 	if (fp->iface != get_iface_desc(&iface->altsetting[0])->bInterfaceNumber ||
 	    fp->altset_idx >= iface->num_altsetting) {
-		kfree(fp);
-		kfree(rate_table);
-		return -EINVAL;
+		err = -EINVAL;
+		goto error;
 	}
 	alts = &iface->altsetting[fp->altset_idx];
 	altsd = get_iface_desc(alts);
+	if (altsd->bNumEndpoints < 1) {
+		err = -EINVAL;
+		goto error;
+	}
+
 	fp->protocol = altsd->bInterfaceProtocol;
 
 	if (fp->datainterval == 0)
@@ -190,6 +192,12 @@ static int create_fixed_stream_quirk(str
 	snd_usb_init_pitch(chip, fp->iface, alts, fp);
 	snd_usb_init_sample_rate(chip, fp->iface, alts, fp, fp->rate_max);
 	return 0;
+
+ error:
+	list_del(&fp->list); /* unlink for avoiding double-free */
+	kfree(fp);
+	kfree(rate_table);
+	return err;
 }
 
 static int create_auto_pcm_quirk(struct snd_usb_audio *chip,
@@ -462,6 +470,7 @@ static int create_uaxx_quirk(struct snd_
 	fp->ep_attr = get_endpoint(alts, 0)->bmAttributes;
 	fp->datainterval = 0;
 	fp->maxpacksize = le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize);
+	INIT_LIST_HEAD(&fp->list);
 
 	switch (fp->maxpacksize) {
 	case 0x120:
@@ -485,6 +494,7 @@ static int create_uaxx_quirk(struct snd_
 		? SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK;
 	err = snd_usb_add_audio_stream(chip, stream, fp);
 	if (err < 0) {
+		list_del(&fp->list); /* unlink for avoiding double-free */
 		kfree(fp);
 		return err;
 	}
@@ -1119,13 +1129,25 @@ bool snd_usb_get_sample_rate_quirk(struc
 {
 	/* devices which do not support reading the sample rate. */
 	switch (chip->usb_id) {
+	case USB_ID(0x041E, 0x4080): /* Creative Live Cam VF0610 */
 	case USB_ID(0x045E, 0x075D): /* MS Lifecam Cinema  */
 	case USB_ID(0x045E, 0x076D): /* MS Lifecam HD-5000 */
+	case USB_ID(0x045E, 0x076E): /* MS Lifecam HD-5001 */
+	case USB_ID(0x045E, 0x076F): /* MS Lifecam HD-6000 */
 	case USB_ID(0x045E, 0x0772): /* MS Lifecam Studio */
 	case USB_ID(0x045E, 0x0779): /* MS Lifecam HD-3000 */
+	case USB_ID(0x047F, 0x0415): /* Plantronics BT-300 */
+	case USB_ID(0x047F, 0xAA05): /* Plantronics DA45 */
 	case USB_ID(0x04D8, 0xFEEA): /* Benchmark DAC1 Pre */
+	case USB_ID(0x0556, 0x0014): /* Phoenix Audio TMX320VC */
+	case USB_ID(0x05A3, 0x9420): /* ELP HD USB Camera */
 	case USB_ID(0x074D, 0x3553): /* Outlaw RR2150 (Micronas UAC3553B) */
+	case USB_ID(0x1901, 0x0191): /* GE B850V3 CP2114 audio interface */
+	case USB_ID(0x1de7, 0x0013): /* Phoenix Audio MT202exe */
+	case USB_ID(0x1de7, 0x0014): /* Phoenix Audio TMX320 */
+	case USB_ID(0x1de7, 0x0114): /* Phoenix Audio MT202pcs */
 	case USB_ID(0x21B4, 0x0081): /* AudioQuest DragonFly */
+	case USB_ID(0x1395, 0x740a): /* Sennheiser Officerunner */
 		return true;
 	}
 	return false;
@@ -1205,8 +1227,12 @@ void snd_usb_set_interface_quirk(struct
 	 * "Playback Design" products need a 50ms delay after setting the
 	 * USB interface.
 	 */
-	if (le16_to_cpu(dev->descriptor.idVendor) == 0x23ba)
+	switch (le16_to_cpu(dev->descriptor.idVendor)) {
+	case 0x23ba: /* Playback Design */
+	case 0x0644: /* TEAC Corp. */
 		mdelay(50);
+		break;
+	}
 }
 
 void snd_usb_ctl_msg_quirk(struct usb_device *dev, unsigned int pipe,
@@ -1221,6 +1247,14 @@ void snd_usb_ctl_msg_quirk(struct usb_de
 	    (requesttype & USB_TYPE_MASK) == USB_TYPE_CLASS)
 		mdelay(20);
 
+	/*
+	 * "TEAC Corp." products need a 20ms delay after each
+	 * class compliant request
+	 */
+	if ((le16_to_cpu(dev->descriptor.idVendor) == 0x0644) &&
+	    (requesttype & USB_TYPE_MASK) == USB_TYPE_CLASS)
+		mdelay(20);
+
 	/* Marantz/Denon devices with USB DAC functionality need a delay
 	 * after each class compliant request
 	 */
@@ -1269,6 +1303,7 @@ u64 snd_usb_interface_dsd_format_quirks(
 	case USB_ID(0x20b1, 0x3008): /* iFi Audio micro/nano iDSD */
 	case USB_ID(0x20b1, 0x2008): /* Matrix Audio X-Sabre */
 	case USB_ID(0x20b1, 0x300a): /* Matrix Audio Mini-i Pro */
+	case USB_ID(0x22d9, 0x0416): /* OPPO HA-1 */
 		if (fp->altsetting == 2)
 			return SNDRV_PCM_FMTBIT_DSD_U32_BE;
 		break;
@@ -1277,6 +1312,7 @@ u64 snd_usb_interface_dsd_format_quirks(
 	case USB_ID(0x20b1, 0x2009): /* DIYINHK DSD DXD 384kHz USB to I2S/DSD */
 	case USB_ID(0x20b1, 0x2023): /* JLsounds I2SoverUSB */
 	case USB_ID(0x20b1, 0x3023): /* Aune X1S 32BIT/384 DSD DAC */
+	case USB_ID(0x2616, 0x0106): /* PS Audio NuWave DAC */
 		if (fp->altsetting == 3)
 			return SNDRV_PCM_FMTBIT_DSD_U32_BE;
 		break;
--- zfcpdump-kernel-4.4.orig/sound/usb/stream.c
+++ zfcpdump-kernel-4.4/sound/usb/stream.c
@@ -316,7 +316,9 @@ static struct snd_pcm_chmap_elem *conver
 /*
  * add this endpoint to the chip instance.
  * if a stream with the same endpoint already exists, append to it.
- * if not, create a new pcm stream.
+ * if not, create a new pcm stream. note, fp is added to the substream
+ * fmt_list and will be freed on the chip instance release. do not free
+ * fp or do remove it from the substream fmt_list to avoid double-free.
  */
 int snd_usb_add_audio_stream(struct snd_usb_audio *chip,
 			     int stream,
@@ -677,6 +679,7 @@ int snd_usb_parse_audio_interface(struct
 					* (fp->maxpacksize & 0x7ff);
 		fp->attributes = parse_uac_endpoint_attributes(chip, alts, protocol, iface_no);
 		fp->clock = clock;
+		INIT_LIST_HEAD(&fp->list);
 
 		/* some quirks for attributes here */
 
@@ -725,6 +728,7 @@ int snd_usb_parse_audio_interface(struct
 		dev_dbg(&dev->dev, "%u:%d: add audio endpoint %#x\n", iface_no, altno, fp->endpoint);
 		err = snd_usb_add_audio_stream(chip, stream, fp);
 		if (err < 0) {
+			list_del(&fp->list); /* unlink for avoiding double-free */
 			kfree(fp->rate_table);
 			kfree(fp->chmap);
 			kfree(fp);
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/AUTHORS
@@ -0,0 +1,25 @@
+Original author and maintainer.
+
+  Brian Behlendorf <behlendorf1@llnl.gov>
+
+Additionally the following individuals have all made contributions
+to the project and deserve to be acknowledged.
+
+  Alex Zhuravlev <Alex.Zhuravlev@Sun.COM>
+  Brian J. Murrell <brian@sun.com>
+  Chris Dunlap <cdunlap@llnl.gov>
+  Chris Dunlop <chris@onthe.net.au>
+  Darik Horn <dajhorn@vanadac.com>
+  Etienne Dechamps <etienne.dechamps@ovh.net>
+  Gunnar Beutner <gunnar@beutner.name>
+  Jorgen Lundman <lundman@lundman.net>
+  Lars Johannsen <laj@it.dk>
+  Li Wei <W.Li@Sun.COM>
+  Massimo Maggi <massimo@mmmm.it>
+  Ned Bass <bass6@llnl.gov>
+  Neependra Khare <neependra@kqinfotech.com>
+  Prakash Surya <surya1@llnl.gov>
+  Ricardo Correia <Ricardo.M.Correia@Sun.COM>
+  Richard Yao <ryao@cs.stonybrook.edu>
+  Steven Johnson <sjohnson@sakuraindustries.com>
+  Yuxuan Shui <yshuiv7@gmail.com>
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/COPYING
@@ -0,0 +1,339 @@
+                    GNU GENERAL PUBLIC LICENSE
+                       Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                            Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Lesser General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+                    GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+                            NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+                     END OF TERMS AND CONDITIONS
+
+            How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License along
+    with this program; if not, write to the Free Software Foundation, Inc.,
+    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) year name of author
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+  <signature of Ty Coon>, 1 April 1989
+  Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs.  If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library.  If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/DISCLAIMER
@@ -0,0 +1,24 @@
+This work was produced at the Lawrence Livermore National Laboratory
+(LLNL) under Contract No. DE-AC52-07NA27344 (Contract 44) between
+the U.S. Department of Energy (DOE) and Lawrence Livermore National
+Security, LLC (LLNS) for the operation of LLNL.
+
+This work was prepared as an account of work sponsored by an agency of
+the United States Government.  Neither the United States Government nor
+Lawrence Livermore National Security, LLC nor any of their employees,
+makes any warranty, express or implied, or assumes any liability or
+responsibility for the accuracy, completeness, or usefulness of any
+information, apparatus, product, or process disclosed, or represents
+that its use would not infringe privately-owned rights.
+
+Reference herein to any specific commercial products, process, or
+services by trade name, trademark, manufacturer or otherwise does
+not necessarily constitute or imply its endorsement, recommendation,
+or favoring by the United States Government or Lawrence Livermore
+National Security, LLC.  The views and opinions of authors expressed
+herein do not necessarily state or reflect those of the Untied States
+Government or Lawrence Livermore National Security, LLC, and shall
+not be used for advertising or product endorsement purposes.
+
+The precise terms and conditions for copying, distribution, and
+modification are specified in the file "COPYING".
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/META
@@ -0,0 +1,8 @@
+Meta:         1
+Name:         spl
+Branch:       1.0
+Version:      0.6.5.6
+Release:      0ubuntu4
+Release-Tags: relext
+License:      GPL
+Author:       OpenZFS on Linux
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/Makefile.am
@@ -0,0 +1,54 @@
+
+ACLOCAL_AMFLAGS = -I config
+
+include config/rpm.am
+include config/deb.am
+include config/tgz.am
+
+SUBDIRS = include rpm
+if CONFIG_USER
+SUBDIRS += lib cmd man scripts
+endif
+if CONFIG_KERNEL
+SUBDIRS += module
+
+extradir = @prefix@/src/spl-$(VERSION)
+extra_HEADERS = spl.release.in spl_config.h.in
+
+kerneldir = @prefix@/src/spl-$(VERSION)/$(LINUX_VERSION)
+nodist_kernel_HEADERS = spl.release spl_config.h module/$(LINUX_SYMBOLS)
+endif
+
+AUTOMAKE_OPTIONS = foreign
+EXTRA_DIST  = autogen.sh META DISCLAIMER copy-builtin COPYING
+EXTRA_DIST += config/config.awk config/rpm.am config/deb.am config/tgz.am
+
+distclean-local::
+	-$(RM) -R autom4te*.cache
+	-find . \( -name SCCS -o -name BitKeeper -o -name .svn -o -name CVS \
+		-o -name .pc -o -name .hg -o -name .git \) -prune -o \
+		\( -name '*.orig' -o -name '*.rej' -o -name '*~' \
+		-o -name '*.bak' -o -name '#*#' -o -name '.*.orig' \
+		-o -name '.*.rej' -o -name 'aclocal.m4' -o -size 0 \
+		-o -name '*%' -o -name '.*.cmd' -o -name 'core' \
+		-o -name 'Makefile' -o -name '$(LINUX_SYMBOLS)' \
+		-o -name '*.order' -o -name '*.markers' \) \
+		-type f -print | xargs $(RM)
+
+dist-hook:
+	sed -i 's/Release:[[:print:]]*/Release:      $(RELEASE)/' \
+		$(distdir)/META
+
+ctags:
+	$(RM) tags
+	find $(top_srcdir) -name .git -prune -o -name '*.[hc]' | xargs ctags
+
+etags:
+	$(RM) TAGS
+	find $(top_srcdir) -name .pc -prune -o -name '*.[hc]' | xargs etags -a
+
+tags: ctags etags
+
+pkg: @DEFAULT_PACKAGE@
+pkg-kmod: @DEFAULT_PACKAGE@-kmod
+pkg-utils: @DEFAULT_PACKAGE@-utils
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/Makefile.in
@@ -0,0 +1,1182 @@
+# Makefile.in generated by automake 1.15 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2014 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+###############################################################################
+# Copyright (C) 2007-2013 Lawrence Livermore National Security, LLC.
+# Copyright (C) 2007 The Regents of the University of California.
+# Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+###############################################################################
+# Build targets for RPM packages.
+###############################################################################
+
+###############################################################################
+# Copyright (C) 2010 Lawrence Livermore National Security, LLC.
+# Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+###############################################################################
+# Build targets for DEB packages.
+#
+# Long term native distro specific Debian style packaging should be added.
+# In the short term RPM packages are built and converted to DEB packages
+# using alien.  If someone familiar with Debian style packaging were to
+# update the build system to correctly build Debian style packages I would
+# happily take it.  Until then we will have to make due with alien.
+#
+###############################################################################
+
+###############################################################################
+# Copyright (C) 2010 Lawrence Livermore National Security, LLC.
+# Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+###############################################################################
+# Build targets for TGZ packages.
+#
+# Long term native distro specific Slackware style packaging should be added.
+# In the short term RPM packages are built and converted to TGZ packages
+# using alien.  If someone familiar with Slackware style packaging were to
+# update the build system to correctly build Slackware style packages I would
+# happily take it.  Until then we will have to make due with alien.
+#
+###############################################################################
+
+VPATH = @srcdir@
+am__is_gnu_make = { \
+  if test -z '$(MAKELEVEL)'; then \
+    false; \
+  elif test -n '$(MAKE_HOST)'; then \
+    true; \
+  elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+    true; \
+  else \
+    false; \
+  fi; \
+}
+am__make_running_with_option = \
+  case $${target_option-} in \
+      ?) ;; \
+      *) echo "am__make_running_with_option: internal error: invalid" \
+              "target option '$${target_option-}' specified" >&2; \
+         exit 1;; \
+  esac; \
+  has_opt=no; \
+  sane_makeflags=$$MAKEFLAGS; \
+  if $(am__is_gnu_make); then \
+    sane_makeflags=$$MFLAGS; \
+  else \
+    case $$MAKEFLAGS in \
+      *\\[\ \	]*) \
+        bs=\\; \
+        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
+    esac; \
+  fi; \
+  skip_next=no; \
+  strip_trailopt () \
+  { \
+    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+  }; \
+  for flg in $$sane_makeflags; do \
+    test $$skip_next = yes && { skip_next=no; continue; }; \
+    case $$flg in \
+      *=*|--*) continue;; \
+        -*I) strip_trailopt 'I'; skip_next=yes;; \
+      -*I?*) strip_trailopt 'I';; \
+        -*O) strip_trailopt 'O'; skip_next=yes;; \
+      -*O?*) strip_trailopt 'O';; \
+        -*l) strip_trailopt 'l'; skip_next=yes;; \
+      -*l?*) strip_trailopt 'l';; \
+      -[dEDm]) skip_next=yes;; \
+      -[JT]) skip_next=yes;; \
+    esac; \
+    case $$flg in \
+      *$$target_option*) has_opt=yes; break;; \
+    esac; \
+  done; \
+  test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+target_triplet = @target@
+@CONFIG_USER_TRUE@am__append_1 = lib cmd man scripts
+@CONFIG_KERNEL_TRUE@am__append_2 = module
+subdir = .
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/config/libtool.m4 \
+	$(top_srcdir)/config/ltoptions.m4 \
+	$(top_srcdir)/config/ltsugar.m4 \
+	$(top_srcdir)/config/ltversion.m4 \
+	$(top_srcdir)/config/lt~obsolete.m4 \
+	$(top_srcdir)/config/spl-build.m4 \
+	$(top_srcdir)/config/spl-meta.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(top_srcdir)/configure \
+	$(am__configure_deps) $(am__extra_HEADERS_DIST) \
+	$(am__DIST_COMMON)
+am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
+ configure.lineno config.status.lineno
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = spl_config.h
+CONFIG_CLEAN_FILES = module/Makefile module/spl/Makefile \
+	module/splat/Makefile spl.release
+CONFIG_CLEAN_VPATH_FILES =
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo "  GEN     " $@;
+am__v_GEN_1 = 
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 = 
+SOURCES =
+DIST_SOURCES =
+RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \
+	ctags-recursive dvi-recursive html-recursive info-recursive \
+	install-data-recursive install-dvi-recursive \
+	install-exec-recursive install-html-recursive \
+	install-info-recursive install-pdf-recursive \
+	install-ps-recursive install-recursive installcheck-recursive \
+	installdirs-recursive pdf-recursive ps-recursive \
+	tags-recursive uninstall-recursive
+am__can_run_installinfo = \
+  case $$AM_UPDATE_INFO_DIR in \
+    n|no|NO) false;; \
+    *) (install-info --version) >/dev/null 2>&1;; \
+  esac
+am__extra_HEADERS_DIST = spl.release.in spl_config.h.in
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+    $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+    *) f=$$p;; \
+  esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+  srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+  for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+  for p in $$list; do echo "$$p $$p"; done | \
+  sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+  $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+    if (++n[$$2] == $(am__install_max)) \
+      { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+    END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+  sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+  sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+  test -z "$$files" \
+    || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+    || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+         $(am__cd) "$$dir" && rm -f $$files; }; \
+  }
+am__installdirs = "$(DESTDIR)$(extradir)" "$(DESTDIR)$(kerneldir)"
+HEADERS = $(extra_HEADERS) $(nodist_kernel_HEADERS)
+RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive	\
+  distclean-recursive maintainer-clean-recursive
+am__recursive_targets = \
+  $(RECURSIVE_TARGETS) \
+  $(RECURSIVE_CLEAN_TARGETS) \
+  $(am__extra_recursive_targets)
+AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \
+	cscope distdir dist dist-all distcheck
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) \
+	$(LISP)spl_config.h.in
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates.  Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+  BEGIN { nonempty = 0; } \
+  { items[$$0] = 1; nonempty = 1; } \
+  END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique.  This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+  list='$(am__tagged_files)'; \
+  unique=`for i in $$list; do \
+    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+  done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+CSCOPE = cscope
+DIST_SUBDIRS = include rpm lib cmd man scripts module
+am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/config/deb.am \
+	$(srcdir)/config/rpm.am $(srcdir)/config/tgz.am \
+	$(srcdir)/spl.release.in $(srcdir)/spl_config.h.in \
+	$(top_srcdir)/config/compile $(top_srcdir)/config/config.guess \
+	$(top_srcdir)/config/config.sub \
+	$(top_srcdir)/config/install-sh $(top_srcdir)/config/ltmain.sh \
+	$(top_srcdir)/config/missing $(top_srcdir)/module/Makefile.in \
+	$(top_srcdir)/module/spl/Makefile.in \
+	$(top_srcdir)/module/splat/Makefile.in AUTHORS COPYING \
+	config/compile config/config.guess config/config.sub \
+	config/install-sh config/ltmain.sh config/missing
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+distdir = $(PACKAGE)-$(VERSION)
+top_distdir = $(distdir)
+am__remove_distdir = \
+  if test -d "$(distdir)"; then \
+    find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \
+      && rm -rf "$(distdir)" \
+      || { sleep 5 && rm -rf "$(distdir)"; }; \
+  else :; fi
+am__post_remove_distdir = $(am__remove_distdir)
+am__relativize = \
+  dir0=`pwd`; \
+  sed_first='s,^\([^/]*\)/.*$$,\1,'; \
+  sed_rest='s,^[^/]*/*,,'; \
+  sed_last='s,^.*/\([^/]*\)$$,\1,'; \
+  sed_butlast='s,/*[^/]*$$,,'; \
+  while test -n "$$dir1"; do \
+    first=`echo "$$dir1" | sed -e "$$sed_first"`; \
+    if test "$$first" != "."; then \
+      if test "$$first" = ".."; then \
+        dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \
+        dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \
+      else \
+        first2=`echo "$$dir2" | sed -e "$$sed_first"`; \
+        if test "$$first2" = "$$first"; then \
+          dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \
+        else \
+          dir2="../$$dir2"; \
+        fi; \
+        dir0="$$dir0"/"$$first"; \
+      fi; \
+    fi; \
+    dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \
+  done; \
+  reldir="$$dir2"
+DIST_ARCHIVES = $(distdir).tar.gz
+GZIP_ENV = --best
+DIST_TARGETS = dist-gzip
+distuninstallcheck_listfiles = find . -type f -print
+am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \
+  | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$'
+distcleancheck_listfiles = find . -type f -print
+ACLOCAL = @ACLOCAL@
+ALIEN = @ALIEN@
+ALIEN_VERSION = @ALIEN_VERSION@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEBUG_CFLAGS = @DEBUG_CFLAGS@
+DEBUG_KMEM = @DEBUG_KMEM@
+DEBUG_KMEM_TRACKING = @DEBUG_KMEM_TRACKING@
+DEBUG_SPL = @DEBUG_SPL@
+DEFAULT_PACKAGE = @DEFAULT_PACKAGE@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DPKG = @DPKG@
+DPKGBUILD = @DPKGBUILD@
+DPKGBUILD_VERSION = @DPKGBUILD_VERSION@
+DPKG_VERSION = @DPKG_VERSION@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GREP = @GREP@
+HAVE_ALIEN = @HAVE_ALIEN@
+HAVE_DPKG = @HAVE_DPKG@
+HAVE_DPKGBUILD = @HAVE_DPKGBUILD@
+HAVE_RPM = @HAVE_RPM@
+HAVE_RPMBUILD = @HAVE_RPMBUILD@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+KERNELCPPFLAGS = @KERNELCPPFLAGS@
+KERNELMAKE_PARAMS = @KERNELMAKE_PARAMS@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LINUX = @LINUX@
+LINUX_OBJ = @LINUX_OBJ@
+LINUX_SYMBOLS = @LINUX_SYMBOLS@
+LINUX_VERSION = @LINUX_VERSION@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+RANLIB = @RANLIB@
+RELEASE = @RELEASE@
+RPM = @RPM@
+RPMBUILD = @RPMBUILD@
+RPMBUILD_VERSION = @RPMBUILD_VERSION@
+RPM_DEFINE_COMMON = @RPM_DEFINE_COMMON@
+RPM_DEFINE_DKMS = @RPM_DEFINE_DKMS@
+RPM_DEFINE_KMOD = @RPM_DEFINE_KMOD@
+RPM_DEFINE_UTIL = @RPM_DEFINE_UTIL@
+RPM_SPEC_DIR = @RPM_SPEC_DIR@
+RPM_VERSION = @RPM_VERSION@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SPL_CONFIG = @SPL_CONFIG@
+SPL_META_ALIAS = @SPL_META_ALIAS@
+SPL_META_AUTHOR = @SPL_META_AUTHOR@
+SPL_META_DATA = @SPL_META_DATA@
+SPL_META_LICENSE = @SPL_META_LICENSE@
+SPL_META_LT_AGE = @SPL_META_LT_AGE@
+SPL_META_LT_CURRENT = @SPL_META_LT_CURRENT@
+SPL_META_LT_REVISION = @SPL_META_LT_REVISION@
+SPL_META_NAME = @SPL_META_NAME@
+SPL_META_RELEASE = @SPL_META_RELEASE@
+SPL_META_VERSION = @SPL_META_VERSION@
+SRPM_DEFINE_COMMON = @SRPM_DEFINE_COMMON@
+SRPM_DEFINE_DKMS = @SRPM_DEFINE_DKMS@
+SRPM_DEFINE_KMOD = @SRPM_DEFINE_KMOD@
+SRPM_DEFINE_UTIL = @SRPM_DEFINE_UTIL@
+STRIP = @STRIP@
+VENDOR = @VENDOR@
+VERSION = @VERSION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+runstatedir = @runstatedir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+ACLOCAL_AMFLAGS = -I config
+SUBDIRS = include rpm $(am__append_1) $(am__append_2)
+@CONFIG_KERNEL_TRUE@extradir = @prefix@/src/spl-$(VERSION)
+@CONFIG_KERNEL_TRUE@extra_HEADERS = spl.release.in spl_config.h.in
+@CONFIG_KERNEL_TRUE@kerneldir = @prefix@/src/spl-$(VERSION)/$(LINUX_VERSION)
+@CONFIG_KERNEL_TRUE@nodist_kernel_HEADERS = spl.release spl_config.h module/$(LINUX_SYMBOLS)
+AUTOMAKE_OPTIONS = foreign
+EXTRA_DIST = autogen.sh META DISCLAIMER copy-builtin COPYING \
+	config/config.awk config/rpm.am config/deb.am config/tgz.am
+all: spl_config.h
+	$(MAKE) $(AM_MAKEFLAGS) all-recursive
+
+.SUFFIXES:
+am--refresh: Makefile
+	@:
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(srcdir)/config/rpm.am $(srcdir)/config/deb.am $(srcdir)/config/tgz.am $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      echo ' cd $(srcdir) && $(AUTOMAKE) --foreign'; \
+	      $(am__cd) $(srcdir) && $(AUTOMAKE) --foreign \
+		&& exit 0; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --foreign Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    echo ' $(SHELL) ./config.status'; \
+	    $(SHELL) ./config.status;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \
+	esac;
+$(srcdir)/config/rpm.am $(srcdir)/config/deb.am $(srcdir)/config/tgz.am $(am__empty):
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	$(SHELL) ./config.status --recheck
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+	$(am__cd) $(srcdir) && $(AUTOCONF)
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+	$(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS)
+$(am__aclocal_m4_deps):
+
+spl_config.h: stamp-h1
+	@test -f $@ || rm -f stamp-h1
+	@test -f $@ || $(MAKE) $(AM_MAKEFLAGS) stamp-h1
+
+stamp-h1: $(srcdir)/spl_config.h.in $(top_builddir)/config.status
+	@rm -f stamp-h1
+	cd $(top_builddir) && $(SHELL) ./config.status spl_config.h
+$(srcdir)/spl_config.h.in: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) 
+	($(am__cd) $(top_srcdir) && $(AUTOHEADER))
+	rm -f stamp-h1
+	touch $@
+
+distclean-hdr:
+	-rm -f spl_config.h stamp-h1
+module/Makefile: $(top_builddir)/config.status $(top_srcdir)/module/Makefile.in
+	cd $(top_builddir) && $(SHELL) ./config.status $@
+module/spl/Makefile: $(top_builddir)/config.status $(top_srcdir)/module/spl/Makefile.in
+	cd $(top_builddir) && $(SHELL) ./config.status $@
+module/splat/Makefile: $(top_builddir)/config.status $(top_srcdir)/module/splat/Makefile.in
+	cd $(top_builddir) && $(SHELL) ./config.status $@
+spl.release: $(top_builddir)/config.status $(srcdir)/spl.release.in
+	cd $(top_builddir) && $(SHELL) ./config.status $@
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
+
+distclean-libtool:
+	-rm -f libtool config.lt
+install-extraHEADERS: $(extra_HEADERS)
+	@$(NORMAL_INSTALL)
+	@list='$(extra_HEADERS)'; test -n "$(extradir)" || list=; \
+	if test -n "$$list"; then \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(extradir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(extradir)" || exit 1; \
+	fi; \
+	for p in $$list; do \
+	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+	  echo "$$d$$p"; \
+	done | $(am__base_list) | \
+	while read files; do \
+	  echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(extradir)'"; \
+	  $(INSTALL_HEADER) $$files "$(DESTDIR)$(extradir)" || exit $$?; \
+	done
+
+uninstall-extraHEADERS:
+	@$(NORMAL_UNINSTALL)
+	@list='$(extra_HEADERS)'; test -n "$(extradir)" || list=; \
+	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+	dir='$(DESTDIR)$(extradir)'; $(am__uninstall_files_from_dir)
+install-nodist_kernelHEADERS: $(nodist_kernel_HEADERS)
+	@$(NORMAL_INSTALL)
+	@list='$(nodist_kernel_HEADERS)'; test -n "$(kerneldir)" || list=; \
+	if test -n "$$list"; then \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(kerneldir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(kerneldir)" || exit 1; \
+	fi; \
+	for p in $$list; do \
+	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+	  echo "$$d$$p"; \
+	done | $(am__base_list) | \
+	while read files; do \
+	  echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(kerneldir)'"; \
+	  $(INSTALL_HEADER) $$files "$(DESTDIR)$(kerneldir)" || exit $$?; \
+	done
+
+uninstall-nodist_kernelHEADERS:
+	@$(NORMAL_UNINSTALL)
+	@list='$(nodist_kernel_HEADERS)'; test -n "$(kerneldir)" || list=; \
+	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+	dir='$(DESTDIR)$(kerneldir)'; $(am__uninstall_files_from_dir)
+
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run 'make' without going through this Makefile.
+# To change the values of 'make' variables: instead of editing Makefiles,
+# (1) if the variable is set in 'config.status', edit 'config.status'
+#     (which will cause the Makefiles to be regenerated when you run 'make');
+# (2) otherwise, pass the desired values on the 'make' command line.
+$(am__recursive_targets):
+	@fail=; \
+	if $(am__make_keepgoing); then \
+	  failcom='fail=yes'; \
+	else \
+	  failcom='exit 1'; \
+	fi; \
+	dot_seen=no; \
+	target=`echo $@ | sed s/-recursive//`; \
+	case "$@" in \
+	  distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
+	  *) list='$(SUBDIRS)' ;; \
+	esac; \
+	for subdir in $$list; do \
+	  echo "Making $$target in $$subdir"; \
+	  if test "$$subdir" = "."; then \
+	    dot_seen=yes; \
+	    local_target="$$target-am"; \
+	  else \
+	    local_target="$$target"; \
+	  fi; \
+	  ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+	  || eval $$failcom; \
+	done; \
+	if test "$$dot_seen" = "no"; then \
+	  $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+	fi; test -z "$$fail"
+
+ID: $(am__tagged_files)
+	$(am__define_uniq_tagged_files); mkid -fID $$unique
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	set x; \
+	here=`pwd`; \
+	if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
+	  include_option=--etags-include; \
+	  empty_fix=.; \
+	else \
+	  include_option=--include; \
+	  empty_fix=; \
+	fi; \
+	list='$(SUBDIRS)'; for subdir in $$list; do \
+	  if test "$$subdir" = .; then :; else \
+	    test ! -f $$subdir/TAGS || \
+	      set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \
+	  fi; \
+	done; \
+	$(am__define_uniq_tagged_files); \
+	shift; \
+	if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+	  test -n "$$unique" || unique=$$empty_fix; \
+	  if test $$# -gt 0; then \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      "$$@" $$unique; \
+	  else \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      $$unique; \
+	  fi; \
+	fi
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	$(am__define_uniq_tagged_files); \
+	test -z "$(CTAGS_ARGS)$$unique" \
+	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+	     $$unique
+
+GTAGS:
+	here=`$(am__cd) $(top_builddir) && pwd` \
+	  && $(am__cd) $(top_srcdir) \
+	  && gtags -i $(GTAGS_ARGS) "$$here"
+cscope: cscope.files
+	test ! -s cscope.files \
+	  || $(CSCOPE) -b -q $(AM_CSCOPEFLAGS) $(CSCOPEFLAGS) -i cscope.files $(CSCOPE_ARGS)
+clean-cscope:
+	-rm -f cscope.files
+cscope.files: clean-cscope cscopelist
+cscopelist: cscopelist-recursive
+
+cscopelist-am: $(am__tagged_files)
+	list='$(am__tagged_files)'; \
+	case "$(srcdir)" in \
+	  [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+	  *) sdir=$(subdir)/$(srcdir) ;; \
+	esac; \
+	for i in $$list; do \
+	  if test -f "$$i"; then \
+	    echo "$(subdir)/$$i"; \
+	  else \
+	    echo "$$sdir/$$i"; \
+	  fi; \
+	done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+	-rm -f cscope.out cscope.in.out cscope.po.out cscope.files
+
+distdir: $(DISTFILES)
+	$(am__remove_distdir)
+	test -d "$(distdir)" || mkdir "$(distdir)"
+	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	list='$(DISTFILES)'; \
+	  dist_files=`for file in $$list; do echo $$file; done | \
+	  sed -e "s|^$$srcdirstrip/||;t" \
+	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+	case $$dist_files in \
+	  */*) $(MKDIR_P) `echo "$$dist_files" | \
+			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+			   sort -u` ;; \
+	esac; \
+	for file in $$dist_files; do \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  if test -d $$d/$$file; then \
+	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+	    if test -d "$(distdir)/$$file"; then \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+	  else \
+	    test -f "$(distdir)/$$file" \
+	    || cp -p $$d/$$file "$(distdir)/$$file" \
+	    || exit 1; \
+	  fi; \
+	done
+	@list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
+	  if test "$$subdir" = .; then :; else \
+	    $(am__make_dryrun) \
+	      || test -d "$(distdir)/$$subdir" \
+	      || $(MKDIR_P) "$(distdir)/$$subdir" \
+	      || exit 1; \
+	    dir1=$$subdir; dir2="$(distdir)/$$subdir"; \
+	    $(am__relativize); \
+	    new_distdir=$$reldir; \
+	    dir1=$$subdir; dir2="$(top_distdir)"; \
+	    $(am__relativize); \
+	    new_top_distdir=$$reldir; \
+	    echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \
+	    echo "     am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \
+	    ($(am__cd) $$subdir && \
+	      $(MAKE) $(AM_MAKEFLAGS) \
+	        top_distdir="$$new_top_distdir" \
+	        distdir="$$new_distdir" \
+		am__remove_distdir=: \
+		am__skip_length_check=: \
+		am__skip_mode_fix=: \
+	        distdir) \
+	      || exit 1; \
+	  fi; \
+	done
+	$(MAKE) $(AM_MAKEFLAGS) \
+	  top_distdir="$(top_distdir)" distdir="$(distdir)" \
+	  dist-hook
+	-test -n "$(am__skip_mode_fix)" \
+	|| find "$(distdir)" -type d ! -perm -755 \
+		-exec chmod u+rwx,go+rx {} \; -o \
+	  ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \
+	  ! -type d ! -perm -400 -exec chmod a+r {} \; -o \
+	  ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \
+	|| chmod -R a+r "$(distdir)"
+dist-gzip: distdir
+	tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
+	$(am__post_remove_distdir)
+
+dist-bzip2: distdir
+	tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2
+	$(am__post_remove_distdir)
+
+dist-lzip: distdir
+	tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz
+	$(am__post_remove_distdir)
+
+dist-xz: distdir
+	tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz
+	$(am__post_remove_distdir)
+
+dist-tarZ: distdir
+	@echo WARNING: "Support for distribution archives compressed with" \
+		       "legacy program 'compress' is deprecated." >&2
+	@echo WARNING: "It will be removed altogether in Automake 2.0" >&2
+	tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z
+	$(am__post_remove_distdir)
+
+dist-shar: distdir
+	@echo WARNING: "Support for shar distribution archives is" \
+	               "deprecated." >&2
+	@echo WARNING: "It will be removed altogether in Automake 2.0" >&2
+	shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz
+	$(am__post_remove_distdir)
+
+dist-zip: distdir
+	-rm -f $(distdir).zip
+	zip -rq $(distdir).zip $(distdir)
+	$(am__post_remove_distdir)
+
+dist dist-all:
+	$(MAKE) $(AM_MAKEFLAGS) $(DIST_TARGETS) am__post_remove_distdir='@:'
+	$(am__post_remove_distdir)
+
+# This target untars the dist file and tries a VPATH configuration.  Then
+# it guarantees that the distribution is self-contained by making another
+# tarfile.
+distcheck: dist
+	case '$(DIST_ARCHIVES)' in \
+	*.tar.gz*) \
+	  GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\
+	*.tar.bz2*) \
+	  bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\
+	*.tar.lz*) \
+	  lzip -dc $(distdir).tar.lz | $(am__untar) ;;\
+	*.tar.xz*) \
+	  xz -dc $(distdir).tar.xz | $(am__untar) ;;\
+	*.tar.Z*) \
+	  uncompress -c $(distdir).tar.Z | $(am__untar) ;;\
+	*.shar.gz*) \
+	  GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\
+	*.zip*) \
+	  unzip $(distdir).zip ;;\
+	esac
+	chmod -R a-w $(distdir)
+	chmod u+w $(distdir)
+	mkdir $(distdir)/_build $(distdir)/_build/sub $(distdir)/_inst
+	chmod a-w $(distdir)
+	test -d $(distdir)/_build || exit 0; \
+	dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \
+	  && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \
+	  && am__cwd=`pwd` \
+	  && $(am__cd) $(distdir)/_build/sub \
+	  && ../../configure \
+	    $(AM_DISTCHECK_CONFIGURE_FLAGS) \
+	    $(DISTCHECK_CONFIGURE_FLAGS) \
+	    --srcdir=../.. --prefix="$$dc_install_base" \
+	  && $(MAKE) $(AM_MAKEFLAGS) \
+	  && $(MAKE) $(AM_MAKEFLAGS) dvi \
+	  && $(MAKE) $(AM_MAKEFLAGS) check \
+	  && $(MAKE) $(AM_MAKEFLAGS) install \
+	  && $(MAKE) $(AM_MAKEFLAGS) installcheck \
+	  && $(MAKE) $(AM_MAKEFLAGS) uninstall \
+	  && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \
+	        distuninstallcheck \
+	  && chmod -R a-w "$$dc_install_base" \
+	  && ({ \
+	       (cd ../.. && umask 077 && mkdir "$$dc_destdir") \
+	       && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \
+	       && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \
+	       && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \
+	            distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \
+	      } || { rm -rf "$$dc_destdir"; exit 1; }) \
+	  && rm -rf "$$dc_destdir" \
+	  && $(MAKE) $(AM_MAKEFLAGS) dist \
+	  && rm -rf $(DIST_ARCHIVES) \
+	  && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \
+	  && cd "$$am__cwd" \
+	  || exit 1
+	$(am__post_remove_distdir)
+	@(echo "$(distdir) archives ready for distribution: "; \
+	  list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \
+	  sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x'
+distuninstallcheck:
+	@test -n '$(distuninstallcheck_dir)' || { \
+	  echo 'ERROR: trying to run $@ with an empty' \
+	       '$$(distuninstallcheck_dir)' >&2; \
+	  exit 1; \
+	}; \
+	$(am__cd) '$(distuninstallcheck_dir)' || { \
+	  echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \
+	  exit 1; \
+	}; \
+	test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \
+	   || { echo "ERROR: files left after uninstall:" ; \
+	        if test -n "$(DESTDIR)"; then \
+	          echo "  (check DESTDIR support)"; \
+	        fi ; \
+	        $(distuninstallcheck_listfiles) ; \
+	        exit 1; } >&2
+distcleancheck: distclean
+	@if test '$(srcdir)' = . ; then \
+	  echo "ERROR: distcleancheck can only run from a VPATH build" ; \
+	  exit 1 ; \
+	fi
+	@test `$(distcleancheck_listfiles) | wc -l` -eq 0 \
+	  || { echo "ERROR: files left in build directory after distclean:" ; \
+	       $(distcleancheck_listfiles) ; \
+	       exit 1; } >&2
+check-am: all-am
+check: check-recursive
+all-am: Makefile $(HEADERS) spl_config.h
+installdirs: installdirs-recursive
+installdirs-am:
+	for dir in "$(DESTDIR)$(extradir)" "$(DESTDIR)$(kerneldir)"; do \
+	  test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+	done
+install: install-recursive
+install-exec: install-exec-recursive
+install-data: install-data-recursive
+uninstall: uninstall-recursive
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-recursive
+install-strip:
+	if test -z '$(STRIP)'; then \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	      install; \
+	else \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+	fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+clean: clean-recursive
+
+clean-am: clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-recursive
+	-rm -f $(am__CONFIG_DISTCLEAN_FILES)
+	-rm -f Makefile
+distclean-am: clean-am distclean-generic distclean-hdr \
+	distclean-libtool distclean-local distclean-tags
+
+dvi: dvi-recursive
+
+dvi-am:
+
+html: html-recursive
+
+html-am:
+
+info: info-recursive
+
+info-am:
+
+install-data-am: install-extraHEADERS install-nodist_kernelHEADERS
+
+install-dvi: install-dvi-recursive
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-recursive
+
+install-html-am:
+
+install-info: install-info-recursive
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-recursive
+
+install-pdf-am:
+
+install-ps: install-ps-recursive
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-recursive
+	-rm -f $(am__CONFIG_DISTCLEAN_FILES)
+	-rm -rf $(top_srcdir)/autom4te.cache
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-recursive
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-recursive
+
+pdf-am:
+
+ps: ps-recursive
+
+ps-am:
+
+uninstall-am: uninstall-extraHEADERS uninstall-nodist_kernelHEADERS
+
+.MAKE: $(am__recursive_targets) all install-am install-strip
+
+.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \
+	am--refresh check check-am clean clean-cscope clean-generic \
+	clean-libtool cscope cscopelist-am ctags ctags-am dist \
+	dist-all dist-bzip2 dist-gzip dist-hook dist-lzip dist-shar \
+	dist-tarZ dist-xz dist-zip distcheck distclean \
+	distclean-generic distclean-hdr distclean-libtool \
+	distclean-local distclean-tags distcleancheck distdir \
+	distuninstallcheck dvi dvi-am html html-am info info-am \
+	install install-am install-data install-data-am install-dvi \
+	install-dvi-am install-exec install-exec-am \
+	install-extraHEADERS install-html install-html-am install-info \
+	install-info-am install-man install-nodist_kernelHEADERS \
+	install-pdf install-pdf-am install-ps install-ps-am \
+	install-strip installcheck installcheck-am installdirs \
+	installdirs-am maintainer-clean maintainer-clean-generic \
+	mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \
+	ps ps-am tags tags-am uninstall uninstall-am \
+	uninstall-extraHEADERS uninstall-nodist_kernelHEADERS
+
+.PRECIOUS: Makefile
+
+
+srpm-kmod:
+	$(MAKE) $(AM_MAKEFLAGS) pkg="${PACKAGE}-kmod" \
+		def='${SRPM_DEFINE_COMMON} ${SRPM_DEFINE_KMOD}' srpm-common
+
+srpm-dkms:
+	$(MAKE) $(AM_MAKEFLAGS) pkg="${PACKAGE}-dkms" \
+		def='${SRPM_DEFINE_COMMON} ${SRPM_DEFINE_DKMS}' srpm-common
+
+srpm-utils:
+	$(MAKE) $(AM_MAKEFLAGS) pkg="${PACKAGE}" \
+		def='${SRPM_DEFINE_COMMON} ${SRPM_DEFINE_UTIL}' srpm-common
+
+srpm: srpm-kmod srpm-dkms srpm-utils
+srpms: srpm-kmod srpm-dkms srpm-utils
+
+rpm-kmod: srpm-kmod
+	$(MAKE) $(AM_MAKEFLAGS) pkg="${PACKAGE}-kmod" \
+		def='${RPM_DEFINE_COMMON} ${RPM_DEFINE_KMOD}' rpm-common
+
+rpm-dkms: srpm-dkms
+	$(MAKE) $(AM_MAKEFLAGS) pkg="${PACKAGE}-dkms" \
+		def='${RPM_DEFINE_COMMON} ${RPM_DEFINE_DKMS}' rpm-common
+
+rpm-utils: srpm-utils
+	$(MAKE) $(AM_MAKEFLAGS) pkg="${PACKAGE}" \
+		def='${RPM_DEFINE_COMMON} ${RPM_DEFINE_UTIL}' rpm-common
+
+rpm: rpm-kmod rpm-dkms rpm-utils
+rpms: rpm-kmod rpm-dkms rpm-utils
+
+rpm-local:
+	@(if test "${HAVE_RPMBUILD}" = "no"; then \
+		echo -e "\n" \
+	"*** Required util ${RPMBUILD} missing.  Please install the\n" \
+	"*** package for your distribution which provides ${RPMBUILD},\n" \
+	"*** re-run configure, and try again.\n"; \
+		exit 1; \
+	fi; \
+	mkdir -p $(rpmbuild)/TMP && \
+	mkdir -p $(rpmbuild)/BUILD && \
+	mkdir -p $(rpmbuild)/RPMS && \
+	mkdir -p $(rpmbuild)/SRPMS && \
+	mkdir -p $(rpmbuild)/SPECS && \
+	cp ${RPM_SPEC_DIR}/$(rpmspec) $(rpmbuild)/SPECS && \
+	mkdir -p $(rpmbuild)/SOURCES && \
+	cp $(top_srcdir)/scripts/kmodtool $(rpmbuild)/SOURCES && \
+	cp $(distdir).tar.gz $(rpmbuild)/SOURCES)
+
+srpm-common: dist
+	@(dist=`$(RPM) --eval %{?dist}`; \
+	rpmpkg=$(pkg)-$(VERSION)-$(RELEASE)$$dist*src.rpm; \
+	rpmspec=$(pkg).spec; \
+	rpmbuild=`mktemp -t -d $(PACKAGE)-build-$$USER-XXXXXXXX`; \
+	$(MAKE) $(AM_MAKEFLAGS) \
+		rpmbuild="$$rpmbuild" \
+		rpmspec="$$rpmspec" \
+		rpm-local || exit 1; \
+	LANG=C $(RPMBUILD) \
+		--define "_tmppath $$rpmbuild/TMP" \
+		--define "_topdir $$rpmbuild" \
+		$(def) -bs $$rpmbuild/SPECS/$$rpmspec || exit 1; \
+	cp $$rpmbuild/SRPMS/$$rpmpkg . || exit 1; \
+	rm -R $$rpmbuild)
+
+rpm-common: 
+	@(dist=`$(RPM) --eval %{?dist}`; \
+	rpmpkg=$(pkg)-$(VERSION)-$(RELEASE)$$dist*src.rpm; \
+	rpmspec=$(pkg).spec; \
+	rpmbuild=`mktemp -t -d $(PACKAGE)-build-$$USER-XXXXXXXX`; \
+	$(MAKE) $(AM_MAKEFLAGS) \
+		rpmbuild="$$rpmbuild" \
+		rpmspec="$$rpmspec" \
+		rpm-local || exit 1; \
+	LANG=C ${RPMBUILD} \
+		--define "_tmppath $$rpmbuild/TMP" \
+		--define "_topdir $$rpmbuild" \
+		$(def) --rebuild $$rpmpkg || exit 1; \
+	cp $$rpmbuild/RPMS/*/* . || exit 1; \
+	rm -R $$rpmbuild)
+
+deb-local:
+	@(if test "${HAVE_DPKGBUILD}" = "no"; then \
+		echo -e "\n" \
+	"*** Required util ${DPKGBUILD} missing.  Please install the\n" \
+        "*** package for your distribution which provides ${DPKGBUILD},\n" \
+	"*** re-run configure, and try again.\n"; \
+                exit 1; \
+	fi; \
+	if test "${HAVE_ALIEN}" = "no"; then \
+		echo -e "\n" \
+	"*** Required util ${ALIEN} missing.  Please install the\n" \
+        "*** package for your distribution which provides ${ALIEN},\n" \
+	"*** re-run configure, and try again.\n"; \
+                exit 1; \
+	fi)
+
+deb-kmod: deb-local rpm-kmod
+@CONFIG_KERNEL_TRUE@	name=${PACKAGE}; \
+@CONFIG_KERNEL_TRUE@	version=${VERSION}-${RELEASE}; \
+@CONFIG_KERNEL_TRUE@	arch=`$(RPM) -qp $${name}-kmod-$${version}.src.rpm --qf %{arch} | tail -1`; \
+@CONFIG_KERNEL_TRUE@	pkg1=kmod-$${name}*$${version}.$${arch}.rpm; \
+@CONFIG_KERNEL_TRUE@	fakeroot $(ALIEN) --bump=0 --scripts --to-deb $$pkg1; \
+@CONFIG_KERNEL_TRUE@	$(RM) $$pkg1
+
+deb-utils: deb-local rpm-utils
+@CONFIG_USER_TRUE@	name=${PACKAGE}; \
+@CONFIG_USER_TRUE@	version=${VERSION}-${RELEASE}; \
+@CONFIG_USER_TRUE@	arch=`$(RPM) -qp $${name}-$${version}.src.rpm --qf %{arch} | tail -1`; \
+@CONFIG_USER_TRUE@	pkg1=$${name}-$${version}.$${arch}.rpm; \
+@CONFIG_USER_TRUE@	fakeroot $(ALIEN) --bump=0 --scripts --to-deb $$pkg1; \
+@CONFIG_USER_TRUE@	$(RM) $$pkg1
+
+deb: deb-kmod deb-utils
+
+tgz-local:
+	@(if test "${HAVE_ALIEN}" = "no"; then \
+		echo -e "\n" \
+	"*** Required util ${ALIEN} missing.  Please install the\n" \
+        "*** package for your distribution which provides ${ALIEN},\n" \
+	"*** re-run configure, and try again.\n"; \
+                exit 1; \
+	fi)
+
+tgz-kmod: tgz-local rpm-kmod
+@CONFIG_KERNEL_TRUE@	name=${PACKAGE}; \
+@CONFIG_KERNEL_TRUE@	version=${VERSION}-${RELEASE}; \
+@CONFIG_KERNEL_TRUE@	arch=`$(RPM) -qp $${name}-kmod-$${version}.src.rpm --qf %{arch} | tail -1`; \
+@CONFIG_KERNEL_TRUE@	pkg1=kmod-$${name}*$${version}.$${arch}.rpm; \
+@CONFIG_KERNEL_TRUE@	fakeroot $(ALIEN) --scripts --to-tgz $$pkg1; \
+@CONFIG_KERNEL_TRUE@	$(RM) $$pkg1
+
+tgz-utils: tgz-local rpm-utils
+@CONFIG_USER_TRUE@	name=${PACKAGE}; \
+@CONFIG_USER_TRUE@	version=${VERSION}-${RELEASE}; \
+@CONFIG_USER_TRUE@	arch=`$(RPM) -qp $${name}-$${version}.src.rpm --qf %{arch} | tail -1`; \
+@CONFIG_USER_TRUE@	pkg1=$${name}-$${version}.$${arch}.rpm; \
+@CONFIG_USER_TRUE@	fakeroot $(ALIEN) --scripts --to-tgz $$pkg1; \
+@CONFIG_USER_TRUE@	$(RM) $$pkg1
+
+tgz: tgz-kmod tgz-utils
+
+distclean-local::
+	-$(RM) -R autom4te*.cache
+	-find . \( -name SCCS -o -name BitKeeper -o -name .svn -o -name CVS \
+		-o -name .pc -o -name .hg -o -name .git \) -prune -o \
+		\( -name '*.orig' -o -name '*.rej' -o -name '*~' \
+		-o -name '*.bak' -o -name '#*#' -o -name '.*.orig' \
+		-o -name '.*.rej' -o -name 'aclocal.m4' -o -size 0 \
+		-o -name '*%' -o -name '.*.cmd' -o -name 'core' \
+		-o -name 'Makefile' -o -name '$(LINUX_SYMBOLS)' \
+		-o -name '*.order' -o -name '*.markers' \) \
+		-type f -print | xargs $(RM)
+
+dist-hook:
+	sed -i 's/Release:[[:print:]]*/Release:      $(RELEASE)/' \
+		$(distdir)/META
+
+ctags:
+	$(RM) tags
+	find $(top_srcdir) -name .git -prune -o -name '*.[hc]' | xargs ctags
+
+etags:
+	$(RM) TAGS
+	find $(top_srcdir) -name .pc -prune -o -name '*.[hc]' | xargs etags -a
+
+tags: ctags etags
+
+pkg: @DEFAULT_PACKAGE@
+pkg-kmod: @DEFAULT_PACKAGE@-kmod
+pkg-utils: @DEFAULT_PACKAGE@-utils
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/aclocal.m4
@@ -0,0 +1,1195 @@
+# generated automatically by aclocal 1.15 -*- Autoconf -*-
+
+# Copyright (C) 1996-2014 Free Software Foundation, Inc.
+
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])])
+m4_ifndef([AC_AUTOCONF_VERSION],
+  [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
+m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.69],,
+[m4_warning([this file was generated for autoconf 2.69.
+You have another version of autoconf.  It may work, but is not guaranteed to.
+If you have problems, you may need to regenerate the build system entirely.
+To do so, use the procedure documented by the package, typically 'autoreconf'.])])
+
+# Copyright (C) 2002-2014 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_AUTOMAKE_VERSION(VERSION)
+# ----------------------------
+# Automake X.Y traces this macro to ensure aclocal.m4 has been
+# generated from the m4 files accompanying Automake X.Y.
+# (This private macro should not be called outside this file.)
+AC_DEFUN([AM_AUTOMAKE_VERSION],
+[am__api_version='1.15'
+dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to
+dnl require some minimum version.  Point them to the right macro.
+m4_if([$1], [1.15], [],
+      [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl
+])
+
+# _AM_AUTOCONF_VERSION(VERSION)
+# -----------------------------
+# aclocal traces this macro to find the Autoconf version.
+# This is a private macro too.  Using m4_define simplifies
+# the logic in aclocal, which can simply ignore this definition.
+m4_define([_AM_AUTOCONF_VERSION], [])
+
+# AM_SET_CURRENT_AUTOMAKE_VERSION
+# -------------------------------
+# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced.
+# This function is AC_REQUIREd by AM_INIT_AUTOMAKE.
+AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
+[AM_AUTOMAKE_VERSION([1.15])dnl
+m4_ifndef([AC_AUTOCONF_VERSION],
+  [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
+_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
+
+# AM_AUX_DIR_EXPAND                                         -*- Autoconf -*-
+
+# Copyright (C) 2001-2014 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets
+# $ac_aux_dir to '$srcdir/foo'.  In other projects, it is set to
+# '$srcdir', '$srcdir/..', or '$srcdir/../..'.
+#
+# Of course, Automake must honor this variable whenever it calls a
+# tool from the auxiliary directory.  The problem is that $srcdir (and
+# therefore $ac_aux_dir as well) can be either absolute or relative,
+# depending on how configure is run.  This is pretty annoying, since
+# it makes $ac_aux_dir quite unusable in subdirectories: in the top
+# source directory, any form will work fine, but in subdirectories a
+# relative path needs to be adjusted first.
+#
+# $ac_aux_dir/missing
+#    fails when called from a subdirectory if $ac_aux_dir is relative
+# $top_srcdir/$ac_aux_dir/missing
+#    fails if $ac_aux_dir is absolute,
+#    fails when called from a subdirectory in a VPATH build with
+#          a relative $ac_aux_dir
+#
+# The reason of the latter failure is that $top_srcdir and $ac_aux_dir
+# are both prefixed by $srcdir.  In an in-source build this is usually
+# harmless because $srcdir is '.', but things will broke when you
+# start a VPATH build or use an absolute $srcdir.
+#
+# So we could use something similar to $top_srcdir/$ac_aux_dir/missing,
+# iff we strip the leading $srcdir from $ac_aux_dir.  That would be:
+#   am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"`
+# and then we would define $MISSING as
+#   MISSING="\${SHELL} $am_aux_dir/missing"
+# This will work as long as MISSING is not called from configure, because
+# unfortunately $(top_srcdir) has no meaning in configure.
+# However there are other variables, like CC, which are often used in
+# configure, and could therefore not use this "fixed" $ac_aux_dir.
+#
+# Another solution, used here, is to always expand $ac_aux_dir to an
+# absolute PATH.  The drawback is that using absolute paths prevent a
+# configured tree to be moved without reconfiguration.
+
+AC_DEFUN([AM_AUX_DIR_EXPAND],
+[AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl
+# Expand $ac_aux_dir to an absolute path.
+am_aux_dir=`cd "$ac_aux_dir" && pwd`
+])
+
+# AM_CONDITIONAL                                            -*- Autoconf -*-
+
+# Copyright (C) 1997-2014 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_CONDITIONAL(NAME, SHELL-CONDITION)
+# -------------------------------------
+# Define a conditional.
+AC_DEFUN([AM_CONDITIONAL],
+[AC_PREREQ([2.52])dnl
+ m4_if([$1], [TRUE],  [AC_FATAL([$0: invalid condition: $1])],
+       [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl
+AC_SUBST([$1_TRUE])dnl
+AC_SUBST([$1_FALSE])dnl
+_AM_SUBST_NOTMAKE([$1_TRUE])dnl
+_AM_SUBST_NOTMAKE([$1_FALSE])dnl
+m4_define([_AM_COND_VALUE_$1], [$2])dnl
+if $2; then
+  $1_TRUE=
+  $1_FALSE='#'
+else
+  $1_TRUE='#'
+  $1_FALSE=
+fi
+AC_CONFIG_COMMANDS_PRE(
+[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then
+  AC_MSG_ERROR([[conditional "$1" was never defined.
+Usually this means the macro was only invoked conditionally.]])
+fi])])
+
+# Copyright (C) 1999-2014 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+
+# There are a few dirty hacks below to avoid letting 'AC_PROG_CC' be
+# written in clear, in which case automake, when reading aclocal.m4,
+# will think it sees a *use*, and therefore will trigger all it's
+# C support machinery.  Also note that it means that autoscan, seeing
+# CC etc. in the Makefile, will ask for an AC_PROG_CC use...
+
+
+# _AM_DEPENDENCIES(NAME)
+# ----------------------
+# See how the compiler implements dependency checking.
+# NAME is "CC", "CXX", "OBJC", "OBJCXX", "UPC", or "GJC".
+# We try a few techniques and use that to set a single cache variable.
+#
+# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was
+# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular
+# dependency, and given that the user is not expected to run this macro,
+# just rely on AC_PROG_CC.
+AC_DEFUN([_AM_DEPENDENCIES],
+[AC_REQUIRE([AM_SET_DEPDIR])dnl
+AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl
+AC_REQUIRE([AM_MAKE_INCLUDE])dnl
+AC_REQUIRE([AM_DEP_TRACK])dnl
+
+m4_if([$1], [CC],   [depcc="$CC"   am_compiler_list=],
+      [$1], [CXX],  [depcc="$CXX"  am_compiler_list=],
+      [$1], [OBJC], [depcc="$OBJC" am_compiler_list='gcc3 gcc'],
+      [$1], [OBJCXX], [depcc="$OBJCXX" am_compiler_list='gcc3 gcc'],
+      [$1], [UPC],  [depcc="$UPC"  am_compiler_list=],
+      [$1], [GCJ],  [depcc="$GCJ"  am_compiler_list='gcc3 gcc'],
+                    [depcc="$$1"   am_compiler_list=])
+
+AC_CACHE_CHECK([dependency style of $depcc],
+               [am_cv_$1_dependencies_compiler_type],
+[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
+  # We make a subdir and do the tests there.  Otherwise we can end up
+  # making bogus files that we don't know about and never remove.  For
+  # instance it was reported that on HP-UX the gcc test will end up
+  # making a dummy file named 'D' -- because '-MD' means "put the output
+  # in D".
+  rm -rf conftest.dir
+  mkdir conftest.dir
+  # Copy depcomp to subdir because otherwise we won't find it if we're
+  # using a relative directory.
+  cp "$am_depcomp" conftest.dir
+  cd conftest.dir
+  # We will build objects and dependencies in a subdirectory because
+  # it helps to detect inapplicable dependency modes.  For instance
+  # both Tru64's cc and ICC support -MD to output dependencies as a
+  # side effect of compilation, but ICC will put the dependencies in
+  # the current directory while Tru64 will put them in the object
+  # directory.
+  mkdir sub
+
+  am_cv_$1_dependencies_compiler_type=none
+  if test "$am_compiler_list" = ""; then
+     am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp`
+  fi
+  am__universal=false
+  m4_case([$1], [CC],
+    [case " $depcc " in #(
+     *\ -arch\ *\ -arch\ *) am__universal=true ;;
+     esac],
+    [CXX],
+    [case " $depcc " in #(
+     *\ -arch\ *\ -arch\ *) am__universal=true ;;
+     esac])
+
+  for depmode in $am_compiler_list; do
+    # Setup a source with many dependencies, because some compilers
+    # like to wrap large dependency lists on column 80 (with \), and
+    # we should not choose a depcomp mode which is confused by this.
+    #
+    # We need to recreate these files for each test, as the compiler may
+    # overwrite some of them when testing with obscure command lines.
+    # This happens at least with the AIX C compiler.
+    : > sub/conftest.c
+    for i in 1 2 3 4 5 6; do
+      echo '#include "conftst'$i'.h"' >> sub/conftest.c
+      # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with
+      # Solaris 10 /bin/sh.
+      echo '/* dummy */' > sub/conftst$i.h
+    done
+    echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
+
+    # We check with '-c' and '-o' for the sake of the "dashmstdout"
+    # mode.  It turns out that the SunPro C++ compiler does not properly
+    # handle '-M -o', and we need to detect this.  Also, some Intel
+    # versions had trouble with output in subdirs.
+    am__obj=sub/conftest.${OBJEXT-o}
+    am__minus_obj="-o $am__obj"
+    case $depmode in
+    gcc)
+      # This depmode causes a compiler race in universal mode.
+      test "$am__universal" = false || continue
+      ;;
+    nosideeffect)
+      # After this tag, mechanisms are not by side-effect, so they'll
+      # only be used when explicitly requested.
+      if test "x$enable_dependency_tracking" = xyes; then
+	continue
+      else
+	break
+      fi
+      ;;
+    msvc7 | msvc7msys | msvisualcpp | msvcmsys)
+      # This compiler won't grok '-c -o', but also, the minuso test has
+      # not run yet.  These depmodes are late enough in the game, and
+      # so weak that their functioning should not be impacted.
+      am__obj=conftest.${OBJEXT-o}
+      am__minus_obj=
+      ;;
+    none) break ;;
+    esac
+    if depmode=$depmode \
+       source=sub/conftest.c object=$am__obj \
+       depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
+       $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \
+         >/dev/null 2>conftest.err &&
+       grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 &&
+       grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
+       grep $am__obj sub/conftest.Po > /dev/null 2>&1 &&
+       ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
+      # icc doesn't choke on unknown options, it will just issue warnings
+      # or remarks (even with -Werror).  So we grep stderr for any message
+      # that says an option was ignored or not supported.
+      # When given -MP, icc 7.0 and 7.1 complain thusly:
+      #   icc: Command line warning: ignoring option '-M'; no argument required
+      # The diagnosis changed in icc 8.0:
+      #   icc: Command line remark: option '-MP' not supported
+      if (grep 'ignoring option' conftest.err ||
+          grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
+        am_cv_$1_dependencies_compiler_type=$depmode
+        break
+      fi
+    fi
+  done
+
+  cd ..
+  rm -rf conftest.dir
+else
+  am_cv_$1_dependencies_compiler_type=none
+fi
+])
+AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type])
+AM_CONDITIONAL([am__fastdep$1], [
+  test "x$enable_dependency_tracking" != xno \
+  && test "$am_cv_$1_dependencies_compiler_type" = gcc3])
+])
+
+
+# AM_SET_DEPDIR
+# -------------
+# Choose a directory name for dependency files.
+# This macro is AC_REQUIREd in _AM_DEPENDENCIES.
+AC_DEFUN([AM_SET_DEPDIR],
+[AC_REQUIRE([AM_SET_LEADING_DOT])dnl
+AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl
+])
+
+
+# AM_DEP_TRACK
+# ------------
+AC_DEFUN([AM_DEP_TRACK],
+[AC_ARG_ENABLE([dependency-tracking], [dnl
+AS_HELP_STRING(
+  [--enable-dependency-tracking],
+  [do not reject slow dependency extractors])
+AS_HELP_STRING(
+  [--disable-dependency-tracking],
+  [speeds up one-time build])])
+if test "x$enable_dependency_tracking" != xno; then
+  am_depcomp="$ac_aux_dir/depcomp"
+  AMDEPBACKSLASH='\'
+  am__nodep='_no'
+fi
+AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno])
+AC_SUBST([AMDEPBACKSLASH])dnl
+_AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl
+AC_SUBST([am__nodep])dnl
+_AM_SUBST_NOTMAKE([am__nodep])dnl
+])
+
+# Generate code to set up dependency tracking.              -*- Autoconf -*-
+
+# Copyright (C) 1999-2014 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+
+# _AM_OUTPUT_DEPENDENCY_COMMANDS
+# ------------------------------
+AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
+[{
+  # Older Autoconf quotes --file arguments for eval, but not when files
+  # are listed without --file.  Let's play safe and only enable the eval
+  # if we detect the quoting.
+  case $CONFIG_FILES in
+  *\'*) eval set x "$CONFIG_FILES" ;;
+  *)   set x $CONFIG_FILES ;;
+  esac
+  shift
+  for mf
+  do
+    # Strip MF so we end up with the name of the file.
+    mf=`echo "$mf" | sed -e 's/:.*$//'`
+    # Check whether this is an Automake generated Makefile or not.
+    # We used to match only the files named 'Makefile.in', but
+    # some people rename them; so instead we look at the file content.
+    # Grep'ing the first line is not enough: some people post-process
+    # each Makefile.in and add a new line on top of each file to say so.
+    # Grep'ing the whole file is not good either: AIX grep has a line
+    # limit of 2048, but all sed's we know have understand at least 4000.
+    if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then
+      dirpart=`AS_DIRNAME("$mf")`
+    else
+      continue
+    fi
+    # Extract the definition of DEPDIR, am__include, and am__quote
+    # from the Makefile without running 'make'.
+    DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"`
+    test -z "$DEPDIR" && continue
+    am__include=`sed -n 's/^am__include = //p' < "$mf"`
+    test -z "$am__include" && continue
+    am__quote=`sed -n 's/^am__quote = //p' < "$mf"`
+    # Find all dependency output files, they are included files with
+    # $(DEPDIR) in their names.  We invoke sed twice because it is the
+    # simplest approach to changing $(DEPDIR) to its actual value in the
+    # expansion.
+    for file in `sed -n "
+      s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \
+	 sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do
+      # Make sure the directory exists.
+      test -f "$dirpart/$file" && continue
+      fdir=`AS_DIRNAME(["$file"])`
+      AS_MKDIR_P([$dirpart/$fdir])
+      # echo "creating $dirpart/$file"
+      echo '# dummy' > "$dirpart/$file"
+    done
+  done
+}
+])# _AM_OUTPUT_DEPENDENCY_COMMANDS
+
+
+# AM_OUTPUT_DEPENDENCY_COMMANDS
+# -----------------------------
+# This macro should only be invoked once -- use via AC_REQUIRE.
+#
+# This code is only required when automatic dependency tracking
+# is enabled.  FIXME.  This creates each '.P' file that we will
+# need in order to bootstrap the dependency handling code.
+AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],
+[AC_CONFIG_COMMANDS([depfiles],
+     [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS],
+     [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"])
+])
+
+# Do all the work for Automake.                             -*- Autoconf -*-
+
+# Copyright (C) 1996-2014 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This macro actually does too much.  Some checks are only needed if
+# your package does certain things.  But this isn't really a big deal.
+
+dnl Redefine AC_PROG_CC to automatically invoke _AM_PROG_CC_C_O.
+m4_define([AC_PROG_CC],
+m4_defn([AC_PROG_CC])
+[_AM_PROG_CC_C_O
+])
+
+# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE])
+# AM_INIT_AUTOMAKE([OPTIONS])
+# -----------------------------------------------
+# The call with PACKAGE and VERSION arguments is the old style
+# call (pre autoconf-2.50), which is being phased out.  PACKAGE
+# and VERSION should now be passed to AC_INIT and removed from
+# the call to AM_INIT_AUTOMAKE.
+# We support both call styles for the transition.  After
+# the next Automake release, Autoconf can make the AC_INIT
+# arguments mandatory, and then we can depend on a new Autoconf
+# release and drop the old call support.
+AC_DEFUN([AM_INIT_AUTOMAKE],
+[AC_PREREQ([2.65])dnl
+dnl Autoconf wants to disallow AM_ names.  We explicitly allow
+dnl the ones we care about.
+m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl
+AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl
+AC_REQUIRE([AC_PROG_INSTALL])dnl
+if test "`cd $srcdir && pwd`" != "`pwd`"; then
+  # Use -I$(srcdir) only when $(srcdir) != ., so that make's output
+  # is not polluted with repeated "-I."
+  AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl
+  # test to see if srcdir already configured
+  if test -f $srcdir/config.status; then
+    AC_MSG_ERROR([source directory already configured; run "make distclean" there first])
+  fi
+fi
+
+# test whether we have cygpath
+if test -z "$CYGPATH_W"; then
+  if (cygpath --version) >/dev/null 2>/dev/null; then
+    CYGPATH_W='cygpath -w'
+  else
+    CYGPATH_W=echo
+  fi
+fi
+AC_SUBST([CYGPATH_W])
+
+# Define the identity of the package.
+dnl Distinguish between old-style and new-style calls.
+m4_ifval([$2],
+[AC_DIAGNOSE([obsolete],
+             [$0: two- and three-arguments forms are deprecated.])
+m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl
+ AC_SUBST([PACKAGE], [$1])dnl
+ AC_SUBST([VERSION], [$2])],
+[_AM_SET_OPTIONS([$1])dnl
+dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT.
+m4_if(
+  m4_ifdef([AC_PACKAGE_NAME], [ok]):m4_ifdef([AC_PACKAGE_VERSION], [ok]),
+  [ok:ok],,
+  [m4_fatal([AC_INIT should be called with package and version arguments])])dnl
+ AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl
+ AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl
+
+_AM_IF_OPTION([no-define],,
+[AC_DEFINE_UNQUOTED([PACKAGE], ["$PACKAGE"], [Name of package])
+ AC_DEFINE_UNQUOTED([VERSION], ["$VERSION"], [Version number of package])])dnl
+
+# Some tools Automake needs.
+AC_REQUIRE([AM_SANITY_CHECK])dnl
+AC_REQUIRE([AC_ARG_PROGRAM])dnl
+AM_MISSING_PROG([ACLOCAL], [aclocal-${am__api_version}])
+AM_MISSING_PROG([AUTOCONF], [autoconf])
+AM_MISSING_PROG([AUTOMAKE], [automake-${am__api_version}])
+AM_MISSING_PROG([AUTOHEADER], [autoheader])
+AM_MISSING_PROG([MAKEINFO], [makeinfo])
+AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
+AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl
+AC_REQUIRE([AC_PROG_MKDIR_P])dnl
+# For better backward compatibility.  To be removed once Automake 1.9.x
+# dies out for good.  For more background, see:
+# <http://lists.gnu.org/archive/html/automake/2012-07/msg00001.html>
+# <http://lists.gnu.org/archive/html/automake/2012-07/msg00014.html>
+AC_SUBST([mkdir_p], ['$(MKDIR_P)'])
+# We need awk for the "check" target (and possibly the TAP driver).  The
+# system "awk" is bad on some platforms.
+AC_REQUIRE([AC_PROG_AWK])dnl
+AC_REQUIRE([AC_PROG_MAKE_SET])dnl
+AC_REQUIRE([AM_SET_LEADING_DOT])dnl
+_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])],
+	      [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])],
+			     [_AM_PROG_TAR([v7])])])
+_AM_IF_OPTION([no-dependencies],,
+[AC_PROVIDE_IFELSE([AC_PROG_CC],
+		  [_AM_DEPENDENCIES([CC])],
+		  [m4_define([AC_PROG_CC],
+			     m4_defn([AC_PROG_CC])[_AM_DEPENDENCIES([CC])])])dnl
+AC_PROVIDE_IFELSE([AC_PROG_CXX],
+		  [_AM_DEPENDENCIES([CXX])],
+		  [m4_define([AC_PROG_CXX],
+			     m4_defn([AC_PROG_CXX])[_AM_DEPENDENCIES([CXX])])])dnl
+AC_PROVIDE_IFELSE([AC_PROG_OBJC],
+		  [_AM_DEPENDENCIES([OBJC])],
+		  [m4_define([AC_PROG_OBJC],
+			     m4_defn([AC_PROG_OBJC])[_AM_DEPENDENCIES([OBJC])])])dnl
+AC_PROVIDE_IFELSE([AC_PROG_OBJCXX],
+		  [_AM_DEPENDENCIES([OBJCXX])],
+		  [m4_define([AC_PROG_OBJCXX],
+			     m4_defn([AC_PROG_OBJCXX])[_AM_DEPENDENCIES([OBJCXX])])])dnl
+])
+AC_REQUIRE([AM_SILENT_RULES])dnl
+dnl The testsuite driver may need to know about EXEEXT, so add the
+dnl 'am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen.  This
+dnl macro is hooked onto _AC_COMPILER_EXEEXT early, see below.
+AC_CONFIG_COMMANDS_PRE(dnl
+[m4_provide_if([_AM_COMPILER_EXEEXT],
+  [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl
+
+# POSIX will say in a future version that running "rm -f" with no argument
+# is OK; and we want to be able to make that assumption in our Makefile
+# recipes.  So use an aggressive probe to check that the usage we want is
+# actually supported "in the wild" to an acceptable degree.
+# See automake bug#10828.
+# To make any issue more visible, cause the running configure to be aborted
+# by default if the 'rm' program in use doesn't match our expectations; the
+# user can still override this though.
+if rm -f && rm -fr && rm -rf; then : OK; else
+  cat >&2 <<'END'
+Oops!
+
+Your 'rm' program seems unable to run without file operands specified
+on the command line, even when the '-f' option is present.  This is contrary
+to the behaviour of most rm programs out there, and not conforming with
+the upcoming POSIX standard: <http://austingroupbugs.net/view.php?id=542>
+
+Please tell bug-automake@gnu.org about your system, including the value
+of your $PATH and any error possibly output before this message.  This
+can help us improve future automake versions.
+
+END
+  if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then
+    echo 'Configuration will proceed anyway, since you have set the' >&2
+    echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2
+    echo >&2
+  else
+    cat >&2 <<'END'
+Aborting the configuration process, to ensure you take notice of the issue.
+
+You can download and install GNU coreutils to get an 'rm' implementation
+that behaves properly: <http://www.gnu.org/software/coreutils/>.
+
+If you want to complete the configuration process using your problematic
+'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM
+to "yes", and re-run configure.
+
+END
+    AC_MSG_ERROR([Your 'rm' program is bad, sorry.])
+  fi
+fi
+dnl The trailing newline in this macro's definition is deliberate, for
+dnl backward compatibility and to allow trailing 'dnl'-style comments
+dnl after the AM_INIT_AUTOMAKE invocation. See automake bug#16841.
+])
+
+dnl Hook into '_AC_COMPILER_EXEEXT' early to learn its expansion.  Do not
+dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further
+dnl mangled by Autoconf and run in a shell conditional statement.
+m4_define([_AC_COMPILER_EXEEXT],
+m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])])
+
+# When config.status generates a header, we must update the stamp-h file.
+# This file resides in the same directory as the config header
+# that is generated.  The stamp files are numbered to have different names.
+
+# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the
+# loop where config.status creates the headers, so we can generate
+# our stamp files there.
+AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK],
+[# Compute $1's index in $config_headers.
+_am_arg=$1
+_am_stamp_count=1
+for _am_header in $config_headers :; do
+  case $_am_header in
+    $_am_arg | $_am_arg:* )
+      break ;;
+    * )
+      _am_stamp_count=`expr $_am_stamp_count + 1` ;;
+  esac
+done
+echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count])
+
+# Copyright (C) 2001-2014 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_PROG_INSTALL_SH
+# ------------------
+# Define $install_sh.
+AC_DEFUN([AM_PROG_INSTALL_SH],
+[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+if test x"${install_sh+set}" != xset; then
+  case $am_aux_dir in
+  *\ * | *\	*)
+    install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;;
+  *)
+    install_sh="\${SHELL} $am_aux_dir/install-sh"
+  esac
+fi
+AC_SUBST([install_sh])])
+
+# Copyright (C) 2003-2014 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# Check whether the underlying file-system supports filenames
+# with a leading dot.  For instance MS-DOS doesn't.
+AC_DEFUN([AM_SET_LEADING_DOT],
+[rm -rf .tst 2>/dev/null
+mkdir .tst 2>/dev/null
+if test -d .tst; then
+  am__leading_dot=.
+else
+  am__leading_dot=_
+fi
+rmdir .tst 2>/dev/null
+AC_SUBST([am__leading_dot])])
+
+# Add --enable-maintainer-mode option to configure.         -*- Autoconf -*-
+# From Jim Meyering
+
+# Copyright (C) 1996-2014 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_MAINTAINER_MODE([DEFAULT-MODE])
+# ----------------------------------
+# Control maintainer-specific portions of Makefiles.
+# Default is to disable them, unless 'enable' is passed literally.
+# For symmetry, 'disable' may be passed as well.  Anyway, the user
+# can override the default with the --enable/--disable switch.
+AC_DEFUN([AM_MAINTAINER_MODE],
+[m4_case(m4_default([$1], [disable]),
+       [enable], [m4_define([am_maintainer_other], [disable])],
+       [disable], [m4_define([am_maintainer_other], [enable])],
+       [m4_define([am_maintainer_other], [enable])
+        m4_warn([syntax], [unexpected argument to AM@&t@_MAINTAINER_MODE: $1])])
+AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles])
+  dnl maintainer-mode's default is 'disable' unless 'enable' is passed
+  AC_ARG_ENABLE([maintainer-mode],
+    [AS_HELP_STRING([--]am_maintainer_other[-maintainer-mode],
+      am_maintainer_other[ make rules and dependencies not useful
+      (and sometimes confusing) to the casual installer])],
+    [USE_MAINTAINER_MODE=$enableval],
+    [USE_MAINTAINER_MODE=]m4_if(am_maintainer_other, [enable], [no], [yes]))
+  AC_MSG_RESULT([$USE_MAINTAINER_MODE])
+  AM_CONDITIONAL([MAINTAINER_MODE], [test $USE_MAINTAINER_MODE = yes])
+  MAINT=$MAINTAINER_MODE_TRUE
+  AC_SUBST([MAINT])dnl
+]
+)
+
+# Check to see how 'make' treats includes.	            -*- Autoconf -*-
+
+# Copyright (C) 2001-2014 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_MAKE_INCLUDE()
+# -----------------
+# Check to see how make treats includes.
+AC_DEFUN([AM_MAKE_INCLUDE],
+[am_make=${MAKE-make}
+cat > confinc << 'END'
+am__doit:
+	@echo this is the am__doit target
+.PHONY: am__doit
+END
+# If we don't find an include directive, just comment out the code.
+AC_MSG_CHECKING([for style of include used by $am_make])
+am__include="#"
+am__quote=
+_am_result=none
+# First try GNU make style include.
+echo "include confinc" > confmf
+# Ignore all kinds of additional output from 'make'.
+case `$am_make -s -f confmf 2> /dev/null` in #(
+*the\ am__doit\ target*)
+  am__include=include
+  am__quote=
+  _am_result=GNU
+  ;;
+esac
+# Now try BSD make style include.
+if test "$am__include" = "#"; then
+   echo '.include "confinc"' > confmf
+   case `$am_make -s -f confmf 2> /dev/null` in #(
+   *the\ am__doit\ target*)
+     am__include=.include
+     am__quote="\""
+     _am_result=BSD
+     ;;
+   esac
+fi
+AC_SUBST([am__include])
+AC_SUBST([am__quote])
+AC_MSG_RESULT([$_am_result])
+rm -f confinc confmf
+])
+
+# Fake the existence of programs that GNU maintainers use.  -*- Autoconf -*-
+
+# Copyright (C) 1997-2014 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_MISSING_PROG(NAME, PROGRAM)
+# ------------------------------
+AC_DEFUN([AM_MISSING_PROG],
+[AC_REQUIRE([AM_MISSING_HAS_RUN])
+$1=${$1-"${am_missing_run}$2"}
+AC_SUBST($1)])
+
+# AM_MISSING_HAS_RUN
+# ------------------
+# Define MISSING if not defined so far and test if it is modern enough.
+# If it is, set am_missing_run to use it, otherwise, to nothing.
+AC_DEFUN([AM_MISSING_HAS_RUN],
+[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+AC_REQUIRE_AUX_FILE([missing])dnl
+if test x"${MISSING+set}" != xset; then
+  case $am_aux_dir in
+  *\ * | *\	*)
+    MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;;
+  *)
+    MISSING="\${SHELL} $am_aux_dir/missing" ;;
+  esac
+fi
+# Use eval to expand $SHELL
+if eval "$MISSING --is-lightweight"; then
+  am_missing_run="$MISSING "
+else
+  am_missing_run=
+  AC_MSG_WARN(['missing' script is too old or missing])
+fi
+])
+
+# Helper functions for option handling.                     -*- Autoconf -*-
+
+# Copyright (C) 2001-2014 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# _AM_MANGLE_OPTION(NAME)
+# -----------------------
+AC_DEFUN([_AM_MANGLE_OPTION],
+[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])])
+
+# _AM_SET_OPTION(NAME)
+# --------------------
+# Set option NAME.  Presently that only means defining a flag for this option.
+AC_DEFUN([_AM_SET_OPTION],
+[m4_define(_AM_MANGLE_OPTION([$1]), [1])])
+
+# _AM_SET_OPTIONS(OPTIONS)
+# ------------------------
+# OPTIONS is a space-separated list of Automake options.
+AC_DEFUN([_AM_SET_OPTIONS],
+[m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])])
+
+# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET])
+# -------------------------------------------
+# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise.
+AC_DEFUN([_AM_IF_OPTION],
+[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])
+
+# Copyright (C) 1999-2014 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# _AM_PROG_CC_C_O
+# ---------------
+# Like AC_PROG_CC_C_O, but changed for automake.  We rewrite AC_PROG_CC
+# to automatically call this.
+AC_DEFUN([_AM_PROG_CC_C_O],
+[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+AC_REQUIRE_AUX_FILE([compile])dnl
+AC_LANG_PUSH([C])dnl
+AC_CACHE_CHECK(
+  [whether $CC understands -c and -o together],
+  [am_cv_prog_cc_c_o],
+  [AC_LANG_CONFTEST([AC_LANG_PROGRAM([])])
+  # Make sure it works both with $CC and with simple cc.
+  # Following AC_PROG_CC_C_O, we do the test twice because some
+  # compilers refuse to overwrite an existing .o file with -o,
+  # though they will create one.
+  am_cv_prog_cc_c_o=yes
+  for am_i in 1 2; do
+    if AM_RUN_LOG([$CC -c conftest.$ac_ext -o conftest2.$ac_objext]) \
+         && test -f conftest2.$ac_objext; then
+      : OK
+    else
+      am_cv_prog_cc_c_o=no
+      break
+    fi
+  done
+  rm -f core conftest*
+  unset am_i])
+if test "$am_cv_prog_cc_c_o" != yes; then
+   # Losing compiler, so override with the script.
+   # FIXME: It is wrong to rewrite CC.
+   # But if we don't then we get into trouble of one sort or another.
+   # A longer-term fix would be to have automake use am__CC in this case,
+   # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)"
+   CC="$am_aux_dir/compile $CC"
+fi
+AC_LANG_POP([C])])
+
+# For backward compatibility.
+AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])])
+
+# Copyright (C) 2001-2014 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_RUN_LOG(COMMAND)
+# -------------------
+# Run COMMAND, save the exit status in ac_status, and log it.
+# (This has been adapted from Autoconf's _AC_RUN_LOG macro.)
+AC_DEFUN([AM_RUN_LOG],
+[{ echo "$as_me:$LINENO: $1" >&AS_MESSAGE_LOG_FD
+   ($1) >&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD
+   ac_status=$?
+   echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD
+   (exit $ac_status); }])
+
+# Check to make sure that the build environment is sane.    -*- Autoconf -*-
+
+# Copyright (C) 1996-2014 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_SANITY_CHECK
+# ---------------
+AC_DEFUN([AM_SANITY_CHECK],
+[AC_MSG_CHECKING([whether build environment is sane])
+# Reject unsafe characters in $srcdir or the absolute working directory
+# name.  Accept space and tab only in the latter.
+am_lf='
+'
+case `pwd` in
+  *[[\\\"\#\$\&\'\`$am_lf]]*)
+    AC_MSG_ERROR([unsafe absolute working directory name]);;
+esac
+case $srcdir in
+  *[[\\\"\#\$\&\'\`$am_lf\ \	]]*)
+    AC_MSG_ERROR([unsafe srcdir value: '$srcdir']);;
+esac
+
+# Do 'set' in a subshell so we don't clobber the current shell's
+# arguments.  Must try -L first in case configure is actually a
+# symlink; some systems play weird games with the mod time of symlinks
+# (eg FreeBSD returns the mod time of the symlink's containing
+# directory).
+if (
+   am_has_slept=no
+   for am_try in 1 2; do
+     echo "timestamp, slept: $am_has_slept" > conftest.file
+     set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null`
+     if test "$[*]" = "X"; then
+	# -L didn't work.
+	set X `ls -t "$srcdir/configure" conftest.file`
+     fi
+     if test "$[*]" != "X $srcdir/configure conftest.file" \
+	&& test "$[*]" != "X conftest.file $srcdir/configure"; then
+
+	# If neither matched, then we have a broken ls.  This can happen
+	# if, for instance, CONFIG_SHELL is bash and it inherits a
+	# broken ls alias from the environment.  This has actually
+	# happened.  Such a system could not be considered "sane".
+	AC_MSG_ERROR([ls -t appears to fail.  Make sure there is not a broken
+  alias in your environment])
+     fi
+     if test "$[2]" = conftest.file || test $am_try -eq 2; then
+       break
+     fi
+     # Just in case.
+     sleep 1
+     am_has_slept=yes
+   done
+   test "$[2]" = conftest.file
+   )
+then
+   # Ok.
+   :
+else
+   AC_MSG_ERROR([newly created file is older than distributed files!
+Check your system clock])
+fi
+AC_MSG_RESULT([yes])
+# If we didn't sleep, we still need to ensure time stamps of config.status and
+# generated files are strictly newer.
+am_sleep_pid=
+if grep 'slept: no' conftest.file >/dev/null 2>&1; then
+  ( sleep 1 ) &
+  am_sleep_pid=$!
+fi
+AC_CONFIG_COMMANDS_PRE(
+  [AC_MSG_CHECKING([that generated files are newer than configure])
+   if test -n "$am_sleep_pid"; then
+     # Hide warnings about reused PIDs.
+     wait $am_sleep_pid 2>/dev/null
+   fi
+   AC_MSG_RESULT([done])])
+rm -f conftest.file
+])
+
+# Copyright (C) 2009-2014 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_SILENT_RULES([DEFAULT])
+# --------------------------
+# Enable less verbose build rules; with the default set to DEFAULT
+# ("yes" being less verbose, "no" or empty being verbose).
+AC_DEFUN([AM_SILENT_RULES],
+[AC_ARG_ENABLE([silent-rules], [dnl
+AS_HELP_STRING(
+  [--enable-silent-rules],
+  [less verbose build output (undo: "make V=1")])
+AS_HELP_STRING(
+  [--disable-silent-rules],
+  [verbose build output (undo: "make V=0")])dnl
+])
+case $enable_silent_rules in @%:@ (((
+  yes) AM_DEFAULT_VERBOSITY=0;;
+   no) AM_DEFAULT_VERBOSITY=1;;
+    *) AM_DEFAULT_VERBOSITY=m4_if([$1], [yes], [0], [1]);;
+esac
+dnl
+dnl A few 'make' implementations (e.g., NonStop OS and NextStep)
+dnl do not support nested variable expansions.
+dnl See automake bug#9928 and bug#10237.
+am_make=${MAKE-make}
+AC_CACHE_CHECK([whether $am_make supports nested variables],
+   [am_cv_make_support_nested_variables],
+   [if AS_ECHO([['TRUE=$(BAR$(V))
+BAR0=false
+BAR1=true
+V=1
+am__doit:
+	@$(TRUE)
+.PHONY: am__doit']]) | $am_make -f - >/dev/null 2>&1; then
+  am_cv_make_support_nested_variables=yes
+else
+  am_cv_make_support_nested_variables=no
+fi])
+if test $am_cv_make_support_nested_variables = yes; then
+  dnl Using '$V' instead of '$(V)' breaks IRIX make.
+  AM_V='$(V)'
+  AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)'
+else
+  AM_V=$AM_DEFAULT_VERBOSITY
+  AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY
+fi
+AC_SUBST([AM_V])dnl
+AM_SUBST_NOTMAKE([AM_V])dnl
+AC_SUBST([AM_DEFAULT_V])dnl
+AM_SUBST_NOTMAKE([AM_DEFAULT_V])dnl
+AC_SUBST([AM_DEFAULT_VERBOSITY])dnl
+AM_BACKSLASH='\'
+AC_SUBST([AM_BACKSLASH])dnl
+_AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl
+])
+
+# Copyright (C) 2001-2014 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_PROG_INSTALL_STRIP
+# ---------------------
+# One issue with vendor 'install' (even GNU) is that you can't
+# specify the program used to strip binaries.  This is especially
+# annoying in cross-compiling environments, where the build's strip
+# is unlikely to handle the host's binaries.
+# Fortunately install-sh will honor a STRIPPROG variable, so we
+# always use install-sh in "make install-strip", and initialize
+# STRIPPROG with the value of the STRIP variable (set by the user).
+AC_DEFUN([AM_PROG_INSTALL_STRIP],
+[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
+# Installed binaries are usually stripped using 'strip' when the user
+# run "make install-strip".  However 'strip' might not be the right
+# tool to use in cross-compilation environments, therefore Automake
+# will honor the 'STRIP' environment variable to overrule this program.
+dnl Don't test for $cross_compiling = yes, because it might be 'maybe'.
+if test "$cross_compiling" != no; then
+  AC_CHECK_TOOL([STRIP], [strip], :)
+fi
+INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
+AC_SUBST([INSTALL_STRIP_PROGRAM])])
+
+# Copyright (C) 2006-2014 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# _AM_SUBST_NOTMAKE(VARIABLE)
+# ---------------------------
+# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in.
+# This macro is traced by Automake.
+AC_DEFUN([_AM_SUBST_NOTMAKE])
+
+# AM_SUBST_NOTMAKE(VARIABLE)
+# --------------------------
+# Public sister of _AM_SUBST_NOTMAKE.
+AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)])
+
+# Check how to create a tarball.                            -*- Autoconf -*-
+
+# Copyright (C) 2004-2014 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# _AM_PROG_TAR(FORMAT)
+# --------------------
+# Check how to create a tarball in format FORMAT.
+# FORMAT should be one of 'v7', 'ustar', or 'pax'.
+#
+# Substitute a variable $(am__tar) that is a command
+# writing to stdout a FORMAT-tarball containing the directory
+# $tardir.
+#     tardir=directory && $(am__tar) > result.tar
+#
+# Substitute a variable $(am__untar) that extract such
+# a tarball read from stdin.
+#     $(am__untar) < result.tar
+#
+AC_DEFUN([_AM_PROG_TAR],
+[# Always define AMTAR for backward compatibility.  Yes, it's still used
+# in the wild :-(  We should find a proper way to deprecate it ...
+AC_SUBST([AMTAR], ['$${TAR-tar}'])
+
+# We'll loop over all known methods to create a tar archive until one works.
+_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none'
+
+m4_if([$1], [v7],
+  [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'],
+
+  [m4_case([$1],
+    [ustar],
+     [# The POSIX 1988 'ustar' format is defined with fixed-size fields.
+      # There is notably a 21 bits limit for the UID and the GID.  In fact,
+      # the 'pax' utility can hang on bigger UID/GID (see automake bug#8343
+      # and bug#13588).
+      am_max_uid=2097151 # 2^21 - 1
+      am_max_gid=$am_max_uid
+      # The $UID and $GID variables are not portable, so we need to resort
+      # to the POSIX-mandated id(1) utility.  Errors in the 'id' calls
+      # below are definitely unexpected, so allow the users to see them
+      # (that is, avoid stderr redirection).
+      am_uid=`id -u || echo unknown`
+      am_gid=`id -g || echo unknown`
+      AC_MSG_CHECKING([whether UID '$am_uid' is supported by ustar format])
+      if test $am_uid -le $am_max_uid; then
+         AC_MSG_RESULT([yes])
+      else
+         AC_MSG_RESULT([no])
+         _am_tools=none
+      fi
+      AC_MSG_CHECKING([whether GID '$am_gid' is supported by ustar format])
+      if test $am_gid -le $am_max_gid; then
+         AC_MSG_RESULT([yes])
+      else
+        AC_MSG_RESULT([no])
+        _am_tools=none
+      fi],
+
+  [pax],
+    [],
+
+  [m4_fatal([Unknown tar format])])
+
+  AC_MSG_CHECKING([how to create a $1 tar archive])
+
+  # Go ahead even if we have the value already cached.  We do so because we
+  # need to set the values for the 'am__tar' and 'am__untar' variables.
+  _am_tools=${am_cv_prog_tar_$1-$_am_tools}
+
+  for _am_tool in $_am_tools; do
+    case $_am_tool in
+    gnutar)
+      for _am_tar in tar gnutar gtar; do
+        AM_RUN_LOG([$_am_tar --version]) && break
+      done
+      am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"'
+      am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"'
+      am__untar="$_am_tar -xf -"
+      ;;
+    plaintar)
+      # Must skip GNU tar: if it does not support --format= it doesn't create
+      # ustar tarball either.
+      (tar --version) >/dev/null 2>&1 && continue
+      am__tar='tar chf - "$$tardir"'
+      am__tar_='tar chf - "$tardir"'
+      am__untar='tar xf -'
+      ;;
+    pax)
+      am__tar='pax -L -x $1 -w "$$tardir"'
+      am__tar_='pax -L -x $1 -w "$tardir"'
+      am__untar='pax -r'
+      ;;
+    cpio)
+      am__tar='find "$$tardir" -print | cpio -o -H $1 -L'
+      am__tar_='find "$tardir" -print | cpio -o -H $1 -L'
+      am__untar='cpio -i -H $1 -d'
+      ;;
+    none)
+      am__tar=false
+      am__tar_=false
+      am__untar=false
+      ;;
+    esac
+
+    # If the value was cached, stop now.  We just wanted to have am__tar
+    # and am__untar set.
+    test -n "${am_cv_prog_tar_$1}" && break
+
+    # tar/untar a dummy directory, and stop if the command works.
+    rm -rf conftest.dir
+    mkdir conftest.dir
+    echo GrepMe > conftest.dir/file
+    AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar])
+    rm -rf conftest.dir
+    if test -s conftest.tar; then
+      AM_RUN_LOG([$am__untar <conftest.tar])
+      AM_RUN_LOG([cat conftest.dir/file])
+      grep GrepMe conftest.dir/file >/dev/null 2>&1 && break
+    fi
+  done
+  rm -rf conftest.dir
+
+  AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool])
+  AC_MSG_RESULT([$am_cv_prog_tar_$1])])
+
+AC_SUBST([am__tar])
+AC_SUBST([am__untar])
+]) # _AM_PROG_TAR
+
+m4_include([config/libtool.m4])
+m4_include([config/ltoptions.m4])
+m4_include([config/ltsugar.m4])
+m4_include([config/ltversion.m4])
+m4_include([config/lt~obsolete.m4])
+m4_include([config/spl-build.m4])
+m4_include([config/spl-meta.m4])
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/autogen.sh
@@ -0,0 +1,4 @@
+#!/bin/sh
+
+autoreconf -fiv
+rm -Rf autom4te.cache
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/cmd/Makefile.am
@@ -0,0 +1,11 @@
+include $(top_srcdir)/config/Rules.am
+
+DEFAULT_INCLUDES += \
+	-I$(top_srcdir)/lib
+
+sbin_PROGRAMS = splat
+
+splat_SOURCES = splat.c
+splat_LDFLAGS = $(top_builddir)/lib/libcommon.la
+
+EXTRA_DIST = splat.h
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/cmd/Makefile.in
@@ -0,0 +1,703 @@
+# Makefile.in generated by automake 1.15 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2014 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+###############################################################################
+# Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+# Copyright (C) 2007 The Regents of the University of California.
+# Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+###############################################################################
+# Common rules for user space components.
+###############################################################################
+
+VPATH = @srcdir@
+am__is_gnu_make = { \
+  if test -z '$(MAKELEVEL)'; then \
+    false; \
+  elif test -n '$(MAKE_HOST)'; then \
+    true; \
+  elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+    true; \
+  else \
+    false; \
+  fi; \
+}
+am__make_running_with_option = \
+  case $${target_option-} in \
+      ?) ;; \
+      *) echo "am__make_running_with_option: internal error: invalid" \
+              "target option '$${target_option-}' specified" >&2; \
+         exit 1;; \
+  esac; \
+  has_opt=no; \
+  sane_makeflags=$$MAKEFLAGS; \
+  if $(am__is_gnu_make); then \
+    sane_makeflags=$$MFLAGS; \
+  else \
+    case $$MAKEFLAGS in \
+      *\\[\ \	]*) \
+        bs=\\; \
+        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
+    esac; \
+  fi; \
+  skip_next=no; \
+  strip_trailopt () \
+  { \
+    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+  }; \
+  for flg in $$sane_makeflags; do \
+    test $$skip_next = yes && { skip_next=no; continue; }; \
+    case $$flg in \
+      *=*|--*) continue;; \
+        -*I) strip_trailopt 'I'; skip_next=yes;; \
+      -*I?*) strip_trailopt 'I';; \
+        -*O) strip_trailopt 'O'; skip_next=yes;; \
+      -*O?*) strip_trailopt 'O';; \
+        -*l) strip_trailopt 'l'; skip_next=yes;; \
+      -*l?*) strip_trailopt 'l';; \
+      -[dEDm]) skip_next=yes;; \
+      -[JT]) skip_next=yes;; \
+    esac; \
+    case $$flg in \
+      *$$target_option*) has_opt=yes; break;; \
+    esac; \
+  done; \
+  test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+target_triplet = @target@
+sbin_PROGRAMS = splat$(EXEEXT)
+subdir = cmd
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/config/libtool.m4 \
+	$(top_srcdir)/config/ltoptions.m4 \
+	$(top_srcdir)/config/ltsugar.m4 \
+	$(top_srcdir)/config/ltversion.m4 \
+	$(top_srcdir)/config/lt~obsolete.m4 \
+	$(top_srcdir)/config/spl-build.m4 \
+	$(top_srcdir)/config/spl-meta.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/spl_config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am__installdirs = "$(DESTDIR)$(sbindir)"
+PROGRAMS = $(sbin_PROGRAMS)
+am_splat_OBJECTS = splat.$(OBJEXT)
+splat_OBJECTS = $(am_splat_OBJECTS)
+splat_LDADD = $(LDADD)
+AM_V_lt = $(am__v_lt_@AM_V@)
+am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 = 
+splat_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+	$(splat_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo "  GEN     " $@;
+am__v_GEN_1 = 
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 = 
+depcomp = $(SHELL) $(top_srcdir)/config/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+	$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+	$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+	$(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_@AM_V@)
+am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
+am__v_CC_0 = @echo "  CC      " $@;
+am__v_CC_1 = 
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+	$(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_@AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo "  CCLD    " $@;
+am__v_CCLD_1 = 
+SOURCES = $(splat_SOURCES)
+DIST_SOURCES = $(splat_SOURCES)
+am__can_run_installinfo = \
+  case $$AM_UPDATE_INFO_DIR in \
+    n|no|NO) false;; \
+    *) (install-info --version) >/dev/null 2>&1;; \
+  esac
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates.  Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+  BEGIN { nonempty = 0; } \
+  { items[$$0] = 1; nonempty = 1; } \
+  END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique.  This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+  list='$(am__tagged_files)'; \
+  unique=`for i in $$list; do \
+    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+  done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/config/Rules.am \
+	$(top_srcdir)/config/depcomp
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ALIEN = @ALIEN@
+ALIEN_VERSION = @ALIEN_VERSION@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEBUG_CFLAGS = @DEBUG_CFLAGS@
+DEBUG_KMEM = @DEBUG_KMEM@
+DEBUG_KMEM_TRACKING = @DEBUG_KMEM_TRACKING@
+DEBUG_SPL = @DEBUG_SPL@
+DEFAULT_PACKAGE = @DEFAULT_PACKAGE@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DPKG = @DPKG@
+DPKGBUILD = @DPKGBUILD@
+DPKGBUILD_VERSION = @DPKGBUILD_VERSION@
+DPKG_VERSION = @DPKG_VERSION@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GREP = @GREP@
+HAVE_ALIEN = @HAVE_ALIEN@
+HAVE_DPKG = @HAVE_DPKG@
+HAVE_DPKGBUILD = @HAVE_DPKGBUILD@
+HAVE_RPM = @HAVE_RPM@
+HAVE_RPMBUILD = @HAVE_RPMBUILD@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+KERNELCPPFLAGS = @KERNELCPPFLAGS@
+KERNELMAKE_PARAMS = @KERNELMAKE_PARAMS@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LINUX = @LINUX@
+LINUX_OBJ = @LINUX_OBJ@
+LINUX_SYMBOLS = @LINUX_SYMBOLS@
+LINUX_VERSION = @LINUX_VERSION@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+RANLIB = @RANLIB@
+RELEASE = @RELEASE@
+RPM = @RPM@
+RPMBUILD = @RPMBUILD@
+RPMBUILD_VERSION = @RPMBUILD_VERSION@
+RPM_DEFINE_COMMON = @RPM_DEFINE_COMMON@
+RPM_DEFINE_DKMS = @RPM_DEFINE_DKMS@
+RPM_DEFINE_KMOD = @RPM_DEFINE_KMOD@
+RPM_DEFINE_UTIL = @RPM_DEFINE_UTIL@
+RPM_SPEC_DIR = @RPM_SPEC_DIR@
+RPM_VERSION = @RPM_VERSION@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SPL_CONFIG = @SPL_CONFIG@
+SPL_META_ALIAS = @SPL_META_ALIAS@
+SPL_META_AUTHOR = @SPL_META_AUTHOR@
+SPL_META_DATA = @SPL_META_DATA@
+SPL_META_LICENSE = @SPL_META_LICENSE@
+SPL_META_LT_AGE = @SPL_META_LT_AGE@
+SPL_META_LT_CURRENT = @SPL_META_LT_CURRENT@
+SPL_META_LT_REVISION = @SPL_META_LT_REVISION@
+SPL_META_NAME = @SPL_META_NAME@
+SPL_META_RELEASE = @SPL_META_RELEASE@
+SPL_META_VERSION = @SPL_META_VERSION@
+SRPM_DEFINE_COMMON = @SRPM_DEFINE_COMMON@
+SRPM_DEFINE_DKMS = @SRPM_DEFINE_DKMS@
+SRPM_DEFINE_KMOD = @SRPM_DEFINE_KMOD@
+SRPM_DEFINE_UTIL = @SRPM_DEFINE_UTIL@
+STRIP = @STRIP@
+VENDOR = @VENDOR@
+VERSION = @VERSION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+runstatedir = @runstatedir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+DEFAULT_INCLUDES = -include ${top_builddir}/spl_config.h \
+	-I$(top_srcdir)/lib
+AM_LIBTOOLFLAGS = --silent
+AM_CPPFLAGS = -D__USE_LARGEFILE64
+AM_CFLAGS = -Wall -Wshadow -Wstrict-prototypes -fno-strict-aliasing \
+	${DEBUG_CFLAGS}
+splat_SOURCES = splat.c
+splat_LDFLAGS = $(top_builddir)/lib/libcommon.la
+EXTRA_DIST = splat.h
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(top_srcdir)/config/Rules.am $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+	        && { if test -f $@; then exit 0; else break; fi; }; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu cmd/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --gnu cmd/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+	esac;
+$(top_srcdir)/config/Rules.am $(am__empty):
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+install-sbinPROGRAMS: $(sbin_PROGRAMS)
+	@$(NORMAL_INSTALL)
+	@list='$(sbin_PROGRAMS)'; test -n "$(sbindir)" || list=; \
+	if test -n "$$list"; then \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(sbindir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(sbindir)" || exit 1; \
+	fi; \
+	for p in $$list; do echo "$$p $$p"; done | \
+	sed 's/$(EXEEXT)$$//' | \
+	while read p p1; do if test -f $$p \
+	 || test -f $$p1 \
+	  ; then echo "$$p"; echo "$$p"; else :; fi; \
+	done | \
+	sed -e 'p;s,.*/,,;n;h' \
+	    -e 's|.*|.|' \
+	    -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \
+	sed 'N;N;N;s,\n, ,g' | \
+	$(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \
+	  { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
+	    if ($$2 == $$4) files[d] = files[d] " " $$1; \
+	    else { print "f", $$3 "/" $$4, $$1; } } \
+	  END { for (d in files) print "f", d, files[d] }' | \
+	while read type dir files; do \
+	    if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
+	    test -z "$$files" || { \
+	    echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(sbindir)$$dir'"; \
+	    $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(sbindir)$$dir" || exit $$?; \
+	    } \
+	; done
+
+uninstall-sbinPROGRAMS:
+	@$(NORMAL_UNINSTALL)
+	@list='$(sbin_PROGRAMS)'; test -n "$(sbindir)" || list=; \
+	files=`for p in $$list; do echo "$$p"; done | \
+	  sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \
+	      -e 's/$$/$(EXEEXT)/' \
+	`; \
+	test -n "$$list" || exit 0; \
+	echo " ( cd '$(DESTDIR)$(sbindir)' && rm -f" $$files ")"; \
+	cd "$(DESTDIR)$(sbindir)" && rm -f $$files
+
+clean-sbinPROGRAMS:
+	@list='$(sbin_PROGRAMS)'; test -n "$$list" || exit 0; \
+	echo " rm -f" $$list; \
+	rm -f $$list || exit $$?; \
+	test -n "$(EXEEXT)" || exit 0; \
+	list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+	echo " rm -f" $$list; \
+	rm -f $$list
+
+splat$(EXEEXT): $(splat_OBJECTS) $(splat_DEPENDENCIES) $(EXTRA_splat_DEPENDENCIES) 
+	@rm -f splat$(EXEEXT)
+	$(AM_V_CCLD)$(splat_LINK) $(splat_OBJECTS) $(splat_LDADD) $(LIBS)
+
+mostlyclean-compile:
+	-rm -f *.$(OBJEXT)
+
+distclean-compile:
+	-rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/splat.Po@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
+
+.c.obj:
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
+
+ID: $(am__tagged_files)
+	$(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	set x; \
+	here=`pwd`; \
+	$(am__define_uniq_tagged_files); \
+	shift; \
+	if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+	  test -n "$$unique" || unique=$$empty_fix; \
+	  if test $$# -gt 0; then \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      "$$@" $$unique; \
+	  else \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      $$unique; \
+	  fi; \
+	fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	$(am__define_uniq_tagged_files); \
+	test -z "$(CTAGS_ARGS)$$unique" \
+	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+	     $$unique
+
+GTAGS:
+	here=`$(am__cd) $(top_builddir) && pwd` \
+	  && $(am__cd) $(top_srcdir) \
+	  && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+	list='$(am__tagged_files)'; \
+	case "$(srcdir)" in \
+	  [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+	  *) sdir=$(subdir)/$(srcdir) ;; \
+	esac; \
+	for i in $$list; do \
+	  if test -f "$$i"; then \
+	    echo "$(subdir)/$$i"; \
+	  else \
+	    echo "$$sdir/$$i"; \
+	  fi; \
+	done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	list='$(DISTFILES)'; \
+	  dist_files=`for file in $$list; do echo $$file; done | \
+	  sed -e "s|^$$srcdirstrip/||;t" \
+	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+	case $$dist_files in \
+	  */*) $(MKDIR_P) `echo "$$dist_files" | \
+			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+			   sort -u` ;; \
+	esac; \
+	for file in $$dist_files; do \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  if test -d $$d/$$file; then \
+	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+	    if test -d "$(distdir)/$$file"; then \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+	  else \
+	    test -f "$(distdir)/$$file" \
+	    || cp -p $$d/$$file "$(distdir)/$$file" \
+	    || exit 1; \
+	  fi; \
+	done
+check-am: all-am
+check: check-am
+all-am: Makefile $(PROGRAMS)
+installdirs:
+	for dir in "$(DESTDIR)$(sbindir)"; do \
+	  test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+	done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+	if test -z '$(STRIP)'; then \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	      install; \
+	else \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+	fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-sbinPROGRAMS \
+	mostlyclean-am
+
+distclean: distclean-am
+	-rm -rf ./$(DEPDIR)
+	-rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+	distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am: install-sbinPROGRAMS
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+	-rm -rf ./$(DEPDIR)
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+	mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-sbinPROGRAMS
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \
+	clean-libtool clean-sbinPROGRAMS cscopelist-am ctags ctags-am \
+	distclean distclean-compile distclean-generic \
+	distclean-libtool distclean-tags distdir dvi dvi-am html \
+	html-am info info-am install install-am install-data \
+	install-data-am install-dvi install-dvi-am install-exec \
+	install-exec-am install-html install-html-am install-info \
+	install-info-am install-man install-pdf install-pdf-am \
+	install-ps install-ps-am install-sbinPROGRAMS install-strip \
+	installcheck installcheck-am installdirs maintainer-clean \
+	maintainer-clean-generic mostlyclean mostlyclean-compile \
+	mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+	tags tags-am uninstall uninstall-am uninstall-sbinPROGRAMS
+
+.PRECIOUS: Makefile
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/cmd/splat.c
@@ -0,0 +1,836 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+ *****************************************************************************
+ *  Solaris Porting LAyer Tests (SPLAT) User Space Interface.
+\*****************************************************************************/
+
+#include <stdlib.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <getopt.h>
+#include <assert.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include "splat.h"
+
+#undef ioctl
+
+static const char shortOpts[] = "hvlat:xc";
+static const struct option longOpts[] = {
+	{ "help",            no_argument,       0, 'h' },
+	{ "verbose",         no_argument,       0, 'v' },
+	{ "list",            no_argument,       0, 'l' },
+	{ "all",             no_argument,       0, 'a' },
+	{ "test",            required_argument, 0, 't' },
+	{ "exit",            no_argument,       0, 'x' },
+	{ "nocolor",         no_argument,       0, 'c' },
+	{ 0,                 0,                 0, 0   }
+};
+
+#define VERSION_SIZE	64
+
+static List subsystems;				/* Subsystem/tests */
+static int splatctl_fd;				/* Control file descriptor */
+static char splat_version[VERSION_SIZE];	/* Kernel version string */
+static char *splat_buffer = NULL;		/* Scratch space area */
+static int splat_buffer_size = 0;		/* Scratch space size */
+
+
+static void test_list(List, int);
+static int dev_clear(void);
+static void subsystem_fini(subsystem_t *);
+static void test_fini(test_t *);
+
+
+static int usage(void) {
+	fprintf(stderr, "usage: splat [hvla] [-t <subsystem:<tests>>]\n");
+	fprintf(stderr,
+	"  --help      -h               This help\n"
+	"  --verbose   -v               Increase verbosity\n"
+	"  --list      -l               List all tests in all subsystems\n"
+	"  --all       -a               Run all tests in all subsystems\n"
+	"  --test      -t <sub:test>    Run 'test' in subsystem 'sub'\n"
+	"  --exit      -x               Exit on first test error\n"
+	"  --nocolor   -c               Do not colorize output\n");
+	fprintf(stderr, "\n"
+	"Examples:\n"
+	"  splat -t kmem:all     # Runs all kmem tests\n"
+	"  splat -t taskq:0x201  # Run taskq test 0x201\n");
+
+	return 0;
+}
+
+static subsystem_t *subsystem_init(splat_user_t *desc)
+{
+	subsystem_t *sub;
+
+	sub = (subsystem_t *)malloc(sizeof(*sub));
+	if (sub == NULL)
+		return NULL;
+
+	memcpy(&sub->sub_desc, desc, sizeof(*desc));
+
+	sub->sub_tests = list_create((ListDelF)test_fini);
+	if (sub->sub_tests == NULL) {
+		free(sub);
+		return NULL;
+	}
+
+	return sub;
+}
+
+static void subsystem_fini(subsystem_t *sub)
+{
+	assert(sub != NULL);
+	free(sub);
+}
+
+static int subsystem_setup(void)
+{
+	splat_cfg_t *cfg;
+	int i, rc, size, cfg_size;
+	subsystem_t *sub;
+	splat_user_t *desc;
+
+	/* Aquire the number of registered subsystems */
+	cfg_size = sizeof(*cfg);
+	cfg = (splat_cfg_t *)malloc(cfg_size);
+	if (cfg == NULL)
+		return -ENOMEM;
+
+	memset(cfg, 0, cfg_size);
+	cfg->cfg_magic = SPLAT_CFG_MAGIC;
+        cfg->cfg_cmd   = SPLAT_CFG_SUBSYSTEM_COUNT;
+
+	rc = ioctl(splatctl_fd, SPLAT_CFG, cfg);
+	if (rc) {
+		fprintf(stderr, "Ioctl() error 0x%lx / %d: %d\n",
+		        (unsigned long)SPLAT_CFG, cfg->cfg_cmd, errno);
+		free(cfg);
+		return rc;
+	}
+
+	size = cfg->cfg_rc1;
+	free(cfg);
+
+	/* Based on the newly acquired number of subsystems allocate
+	 * memory to get the descriptive information for them all. */
+	cfg_size = sizeof(*cfg) + size * sizeof(splat_user_t);
+	cfg = (splat_cfg_t *)malloc(cfg_size);
+	if (cfg == NULL)
+		return -ENOMEM;
+
+	memset(cfg, 0, cfg_size);
+	cfg->cfg_magic = SPLAT_CFG_MAGIC;
+	cfg->cfg_cmd   = SPLAT_CFG_SUBSYSTEM_LIST;
+	cfg->cfg_data.splat_subsystems.size = size;
+
+	rc = ioctl(splatctl_fd, SPLAT_CFG, cfg);
+	if (rc) {
+		fprintf(stderr, "Ioctl() error %lu / %d: %d\n",
+		        (unsigned long) SPLAT_CFG, cfg->cfg_cmd, errno);
+		free(cfg);
+		return rc;
+	}
+
+	/* Add the new subsystems in to the global list */
+	size = cfg->cfg_rc1;
+	for (i = 0; i < size; i++) {
+		desc = &(cfg->cfg_data.splat_subsystems.descs[i]);
+
+		sub = subsystem_init(desc);
+		if (sub == NULL) {
+			fprintf(stderr, "Error initializing subsystem: %s\n",
+			        desc->name);
+			free(cfg);
+			return -ENOMEM;
+		}
+
+		list_append(subsystems, sub);
+	}
+
+	free(cfg);
+	return 0;
+}
+
+static void subsystem_list(List l, int indent)
+{
+	ListIterator i;
+	subsystem_t *sub;
+
+	fprintf(stdout,
+	        "------------------------------ "
+	        "Available SPLAT Tests "
+	        "------------------------------\n");
+
+	i = list_iterator_create(l);
+
+	while ((sub = list_next(i))) {
+		fprintf(stdout, "%*s0x%0*x %-*s ---- %s ----\n",
+		        indent, "",
+		        4, sub->sub_desc.id,
+		        SPLAT_NAME_SIZE + 7, sub->sub_desc.name,
+		        sub->sub_desc.desc);
+		test_list(sub->sub_tests, indent + 7);
+	}
+
+	list_iterator_destroy(i);
+}
+
+static test_t *test_init(subsystem_t *sub, splat_user_t *desc)
+{
+	test_t *test;
+
+	test = (test_t *)malloc(sizeof(*test));
+	if (test == NULL)
+		return NULL;
+
+	test->test_sub = sub;
+	memcpy(&test->test_desc, desc, sizeof(*desc));
+
+	return test;
+}
+
+static void test_fini(test_t *test)
+{
+	assert(test != NULL);
+	free(test);
+}
+
+static int test_setup(subsystem_t *sub)
+{
+	splat_cfg_t *cfg;
+	int i, rc, size;
+	test_t *test;
+	splat_user_t *desc;
+
+	/* Aquire the number of registered tests for the give subsystem */
+	cfg = (splat_cfg_t *)malloc(sizeof(*cfg));
+	if (cfg == NULL)
+		return -ENOMEM;
+
+	memset(cfg, 0, sizeof(*cfg));
+	cfg->cfg_magic = SPLAT_CFG_MAGIC;
+        cfg->cfg_cmd   = SPLAT_CFG_TEST_COUNT;
+	cfg->cfg_arg1  = sub->sub_desc.id; /* Subsystem of interest */
+
+	rc = ioctl(splatctl_fd, SPLAT_CFG, cfg);
+	if (rc) {
+		fprintf(stderr, "Ioctl() error %lu / %d: %d\n",
+		        (unsigned long) SPLAT_CFG, cfg->cfg_cmd, errno);
+		free(cfg);
+		return rc;
+	}
+
+	size = cfg->cfg_rc1;
+	free(cfg);
+
+	/* Based on the newly aquired number of tests allocate enough
+	 * memory to get the descriptive information for them all. */
+	cfg = (splat_cfg_t *)malloc(sizeof(*cfg) + size*sizeof(splat_user_t));
+	if (cfg == NULL)
+		return -ENOMEM;
+
+	memset(cfg, 0, sizeof(*cfg) + size * sizeof(splat_user_t));
+	cfg->cfg_magic = SPLAT_CFG_MAGIC;
+	cfg->cfg_cmd   = SPLAT_CFG_TEST_LIST;
+	cfg->cfg_arg1  = sub->sub_desc.id; /* Subsystem of interest */
+	cfg->cfg_data.splat_tests.size = size;
+
+	rc = ioctl(splatctl_fd, SPLAT_CFG, cfg);
+	if (rc) {
+		fprintf(stderr, "Ioctl() error %lu / %d: %d\n",
+		        (unsigned long) SPLAT_CFG, cfg->cfg_cmd, errno);
+		free(cfg);
+		return rc;
+	}
+
+	/* Add the new tests in to the relevant subsystems */
+	size = cfg->cfg_rc1;
+	for (i = 0; i < size; i++) {
+		desc = &(cfg->cfg_data.splat_tests.descs[i]);
+
+		test = test_init(sub, desc);
+		if (test == NULL) {
+			fprintf(stderr, "Error initializing test: %s\n",
+			        desc->name);
+			free(cfg);
+			return -ENOMEM;
+		}
+
+		list_append(sub->sub_tests, test);
+	}
+
+	free(cfg);
+	return 0;
+}
+
+static test_t *test_copy(test_t *test)
+{
+	return test_init(test->test_sub, &test->test_desc);
+}
+
+static void test_list(List l, int indent)
+{
+	ListIterator i;
+	test_t *test;
+
+	i = list_iterator_create(l);
+
+	while ((test = list_next(i)))
+		fprintf(stdout, "%*s0x%0*x %-*s %s\n",
+		        indent, "", 04, test->test_desc.id,
+		        SPLAT_NAME_SIZE, test->test_desc.name,
+		        test->test_desc.desc);
+
+	list_iterator_destroy(i);
+}
+
+static test_t *test_find(char *sub_str, char *test_str)
+{
+	ListIterator si, ti;
+	subsystem_t *sub;
+	test_t *test;
+	__u32 sub_num, test_num;
+
+	/*
+	 * No error checking here because it may not be a number, it's
+	 * perfectly OK for it to be a string.  Since we're just using
+	 * it for comparison purposes this is all very safe.
+	 */
+	sub_num = strtoul(sub_str, NULL, 0);
+	test_num = strtoul(test_str, NULL, 0);
+
+        si = list_iterator_create(subsystems);
+
+        while ((sub = list_next(si))) {
+
+		if (strncmp(sub->sub_desc.name, sub_str, SPLAT_NAME_SIZE) &&
+		    sub->sub_desc.id != sub_num)
+			continue;
+
+		ti = list_iterator_create(sub->sub_tests);
+
+		while ((test = list_next(ti))) {
+
+			if (!strncmp(test->test_desc.name, test_str,
+		            SPLAT_NAME_SIZE) || test->test_desc.id==test_num) {
+				list_iterator_destroy(ti);
+			        list_iterator_destroy(si);
+				return test;
+			}
+		}
+
+	        list_iterator_destroy(ti);
+        }
+
+        list_iterator_destroy(si);
+
+	return NULL;
+}
+
+static int test_add(cmd_args_t *args, test_t *test)
+{
+	test_t *tmp;
+
+	tmp = test_copy(test);
+	if (tmp == NULL)
+		return -ENOMEM;
+
+	list_append(args->args_tests, tmp);
+	return 0;
+}
+
+static int test_add_all(cmd_args_t *args)
+{
+	ListIterator si, ti;
+	subsystem_t *sub;
+	test_t *test;
+	int rc;
+
+        si = list_iterator_create(subsystems);
+
+        while ((sub = list_next(si))) {
+		ti = list_iterator_create(sub->sub_tests);
+
+		while ((test = list_next(ti))) {
+			if ((rc = test_add(args, test))) {
+			        list_iterator_destroy(ti);
+			        list_iterator_destroy(si);
+				return rc;
+			}
+		}
+
+	        list_iterator_destroy(ti);
+        }
+
+        list_iterator_destroy(si);
+
+	return 0;
+}
+
+static int test_run(cmd_args_t *args, test_t *test)
+{
+	subsystem_t *sub = test->test_sub;
+	splat_cmd_t *cmd;
+	int rc, cmd_size;
+
+	dev_clear();
+
+	cmd_size = sizeof(*cmd);
+	cmd = (splat_cmd_t *)malloc(cmd_size);
+	if (cmd == NULL)
+		return -ENOMEM;
+
+	memset(cmd, 0, cmd_size);
+	cmd->cmd_magic = SPLAT_CMD_MAGIC;
+        cmd->cmd_subsystem = sub->sub_desc.id;
+	cmd->cmd_test = test->test_desc.id;
+	cmd->cmd_data_size = 0; /* Unused feature */
+
+	fprintf(stdout, "%*s:%-*s ",
+	        SPLAT_NAME_SIZE, sub->sub_desc.name,
+	        SPLAT_NAME_SIZE, test->test_desc.name);
+	fflush(stdout);
+	rc = ioctl(splatctl_fd, SPLAT_CMD, cmd);
+	if (args->args_do_color) {
+		fprintf(stdout, "%s  %s\n", rc ?
+		        COLOR_RED "Fail" COLOR_RESET :
+		        COLOR_GREEN "Pass" COLOR_RESET,
+			rc ? strerror(errno) : "");
+	} else {
+		fprintf(stdout, "%s  %s\n", rc ?
+		        "Fail" : "Pass",
+			rc ? strerror(errno) : "");
+	}
+	fflush(stdout);
+	free(cmd);
+
+	if ((args->args_verbose == 1 && rc) ||
+	    (args->args_verbose >= 2)) {
+		if ((rc = read(splatctl_fd, splat_buffer,
+			       splat_buffer_size - 1)) < 0) {
+			fprintf(stdout, "Error reading results: %d\n", rc);
+		} else {
+			fprintf(stdout, "\n%s\n", splat_buffer);
+			fflush(stdout);
+		}
+	}
+
+	return rc;
+}
+
+static int tests_run(cmd_args_t *args)
+{
+        ListIterator i;
+	test_t *test;
+	int rc;
+
+	fprintf(stdout,
+	        "------------------------------ "
+	        "Running SPLAT Tests "
+	        "------------------------------\n");
+
+	i = list_iterator_create(args->args_tests);
+
+	while ((test = list_next(i))) {
+		rc = test_run(args, test);
+		if (rc && args->args_exit_on_error) {
+			list_iterator_destroy(i);
+			return rc;
+		}
+	}
+
+	list_iterator_destroy(i);
+	return 0;
+}
+
+static int args_parse_test(cmd_args_t *args, char *str)
+{
+        ListIterator si, ti;
+	subsystem_t *s;
+	test_t *t;
+	char *sub_str, *test_str;
+	int sub_num, test_num;
+	int sub_all = 0, test_all = 0;
+	int rc, flag = 0;
+
+	test_str = strchr(str, ':');
+	if (test_str == NULL) {
+		fprintf(stderr, "Test must be of the "
+		        "form <subsystem:test>\n");
+		return -EINVAL;
+	}
+
+	sub_str = str;
+	test_str[0] = '\0';
+	test_str = test_str + 1;
+
+	sub_num = strtol(sub_str, NULL, 0);
+	test_num = strtol(test_str, NULL, 0);
+
+	if (!strncasecmp(sub_str, "all", strlen(sub_str)) || (sub_num == -1))
+		sub_all = 1;
+
+	if (!strncasecmp(test_str,"all",strlen(test_str)) || (test_num == -1))
+		test_all = 1;
+
+	si = list_iterator_create(subsystems);
+
+	if (sub_all) {
+		if (test_all) {
+			/* Add all tests from all subsystems */
+			while ((s = list_next(si))) {
+				ti = list_iterator_create(s->sub_tests);
+				while ((t = list_next(ti))) {
+					if ((rc = test_add(args, t))) {
+						list_iterator_destroy(ti);
+						goto error_run;
+					}
+				}
+				list_iterator_destroy(ti);
+			}
+		} else {
+			/* Add a specific test from all subsystems */
+			while ((s = list_next(si))) {
+				if ((t=test_find(s->sub_desc.name,test_str))) {
+					if ((rc = test_add(args, t)))
+						goto error_run;
+
+					flag = 1;
+				}
+			}
+
+			if (!flag)
+				fprintf(stderr, "No tests '%s:%s' could be "
+				        "found\n", sub_str, test_str);
+		}
+	} else {
+		if (test_all) {
+			/* Add all tests from a specific subsystem */
+			while ((s = list_next(si))) {
+				if (strncasecmp(sub_str, s->sub_desc.name,
+				    strlen(sub_str)))
+					continue;
+
+				ti = list_iterator_create(s->sub_tests);
+				while ((t = list_next(ti))) {
+					if ((rc = test_add(args, t))) {
+						list_iterator_destroy(ti);
+						goto error_run;
+					}
+				}
+				list_iterator_destroy(ti);
+			}
+		} else {
+			/* Add a specific test from a specific subsystem */
+			if ((t = test_find(sub_str, test_str))) {
+				if ((rc = test_add(args, t)))
+					goto error_run;
+			} else {
+				fprintf(stderr, "Test '%s:%s' could not be "
+				        "found\n", sub_str, test_str);
+				return -EINVAL;
+			}
+		}
+	}
+
+	list_iterator_destroy(si);
+
+	return 0;
+
+error_run:
+	list_iterator_destroy(si);
+
+	fprintf(stderr, "Test '%s:%s' not added to run list: %d\n",
+	        sub_str, test_str, rc);
+
+	return rc;
+}
+
+static void args_fini(cmd_args_t *args)
+{
+	assert(args != NULL);
+
+	if (args->args_tests != NULL)
+		list_destroy(args->args_tests);
+
+	free(args);
+}
+
+static cmd_args_t *
+args_init(int argc, char **argv)
+{
+	cmd_args_t *args;
+	int c, rc;
+
+	if (argc == 1) {
+		usage();
+		return (cmd_args_t *) NULL;
+	}
+
+	/* Configure and populate the args structures */
+	args = malloc(sizeof(*args));
+	if (args == NULL)
+		return NULL;
+
+	memset(args, 0, sizeof(*args));
+	args->args_verbose = 0;
+	args->args_do_list = 0;
+	args->args_do_all  = 0;
+	args->args_do_color = 1;
+	args->args_exit_on_error = 0;
+	args->args_tests = list_create((ListDelF)test_fini);
+	if (args->args_tests == NULL) {
+		args_fini(args);
+		return NULL;
+	}
+
+	while ((c = getopt_long(argc, argv, shortOpts, longOpts, NULL)) != -1){
+		switch (c) {
+		case 'v':  args->args_verbose++;			break;
+		case 'l':  args->args_do_list = 1;			break;
+		case 'a':  args->args_do_all = 1;			break;
+		case 'c':  args->args_do_color = 0;			break;
+		case 'x':  args->args_exit_on_error = 1;		break;
+		case 't':
+			if (args->args_do_all) {
+				fprintf(stderr, "Option -t <subsystem:test> is "
+				        "useless when used with -a\n");
+				args_fini(args);
+				return NULL;
+			}
+
+			rc = args_parse_test(args, argv[optind - 1]);
+			if (rc) {
+				args_fini(args);
+				return NULL;
+			}
+			break;
+		case 'h':
+		case '?':
+			usage();
+			args_fini(args);
+			return NULL;
+		default:
+			fprintf(stderr, "Unknown option '%s'\n",
+			        argv[optind - 1]);
+			break;
+		}
+	}
+
+	return args;
+}
+
+static int
+dev_clear(void)
+{
+	splat_cfg_t cfg;
+	int rc;
+
+	memset(&cfg, 0, sizeof(cfg));
+	cfg.cfg_magic = SPLAT_CFG_MAGIC;
+        cfg.cfg_cmd   = SPLAT_CFG_BUFFER_CLEAR;
+	cfg.cfg_arg1  = 0;
+
+	rc = ioctl(splatctl_fd, SPLAT_CFG, &cfg);
+	if (rc)
+		fprintf(stderr, "Ioctl() error %lu / %d: %d\n",
+		        (unsigned long) SPLAT_CFG, cfg.cfg_cmd, errno);
+
+	lseek(splatctl_fd, 0, SEEK_SET);
+
+	return rc;
+}
+
+static int
+dev_size(int size)
+{
+	splat_cfg_t cfg;
+	int rc;
+
+	memset(&cfg, 0, sizeof(cfg));
+	cfg.cfg_magic = SPLAT_CFG_MAGIC;
+        cfg.cfg_cmd   = SPLAT_CFG_BUFFER_SIZE;
+	cfg.cfg_arg1  = size;
+
+	rc = ioctl(splatctl_fd, SPLAT_CFG, &cfg);
+	if (rc) {
+		fprintf(stderr, "Ioctl() error %lu / %d: %d\n",
+		        (unsigned long) SPLAT_CFG, cfg.cfg_cmd, errno);
+		return rc;
+	}
+
+	return cfg.cfg_rc1;
+}
+
+static void
+dev_fini(void)
+{
+	if (splat_buffer)
+		free(splat_buffer);
+
+	if (splatctl_fd != -1) {
+		if (close(splatctl_fd) == -1) {
+			fprintf(stderr, "Unable to close %s: %d\n",
+		                SPLAT_DEV, errno);
+		}
+	}
+}
+
+static int
+dev_init(void)
+{
+	ListIterator i;
+	subsystem_t *sub;
+	int rc;
+
+	splatctl_fd = open(SPLAT_DEV, O_RDONLY);
+	if (splatctl_fd == -1) {
+		fprintf(stderr, "Unable to open %s: %d\n"
+		        "Is the splat module loaded?\n", SPLAT_DEV, errno);
+		rc = errno;
+		goto error;
+	}
+
+	/* Determine kernel module version string */
+	memset(splat_version, 0, VERSION_SIZE);
+	if ((rc = read(splatctl_fd, splat_version, VERSION_SIZE - 1)) == -1)
+		goto error;
+
+	if ((rc = dev_clear()))
+		goto error;
+
+	if ((rc = dev_size(0)) < 0)
+		goto error;
+
+	splat_buffer_size = rc;
+	splat_buffer = (char *)malloc(splat_buffer_size);
+	if (splat_buffer == NULL) {
+		rc = -ENOMEM;
+		goto error;
+	}
+
+	memset(splat_buffer, 0, splat_buffer_size);
+
+	/* Determine available subsystems */
+	if ((rc = subsystem_setup()) != 0)
+		goto error;
+
+	/* Determine available tests for all subsystems */
+	i = list_iterator_create(subsystems);
+
+	while ((sub = list_next(i))) {
+		if ((rc = test_setup(sub)) != 0) {
+			list_iterator_destroy(i);
+			goto error;
+		}
+	}
+
+	list_iterator_destroy(i);
+	return 0;
+
+error:
+	if (splatctl_fd != -1) {
+		if (close(splatctl_fd) == -1) {
+			fprintf(stderr, "Unable to close %s: %d\n",
+		                SPLAT_DEV, errno);
+		}
+	}
+
+	return rc;
+}
+
+int
+init(void)
+{
+	int rc = 0;
+
+	/* Allocate the subsystem list */
+	subsystems = list_create((ListDelF)subsystem_fini);
+	if (subsystems == NULL)
+		rc = ENOMEM;
+
+	return rc;
+}
+
+void
+fini(void)
+{
+	list_destroy(subsystems);
+}
+
+
+int
+main(int argc, char **argv)
+{
+	cmd_args_t *args = NULL;
+	int rc = 0;
+
+	/* General init */
+	if ((rc = init()))
+		return rc;
+
+	/* Device specific init */
+	if ((rc = dev_init()))
+		goto out;
+
+	/* Argument init and parsing */
+	if ((args = args_init(argc, argv)) == NULL) {
+		rc = -1;
+		goto out;
+	}
+
+	/* Generic kernel version string */
+	if (args->args_verbose)
+		fprintf(stdout, "%s", splat_version);
+
+	/* Print the available test list and exit */
+	if (args->args_do_list) {
+		subsystem_list(subsystems, 0);
+		goto out;
+	}
+
+	/* Add all available test to the list of tests to run */
+	if (args->args_do_all) {
+		if ((rc = test_add_all(args)))
+			goto out;
+	}
+
+	/* Run all the requested tests */
+	if ((rc = tests_run(args)))
+		goto out;
+
+out:
+	if (args != NULL)
+		args_fini(args);
+
+	dev_fini();
+	fini();
+	return rc;
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/cmd/splat.h
@@ -0,0 +1,70 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+\*****************************************************************************/
+
+#ifndef _SPLAT_H
+#define _SPLAT_H
+
+#include "list.h"
+#include "../include/splat-ctl.h"
+
+#define DEV_NAME			"/dev/splatctl"
+#define COLOR_BLACK			"\033[0;30m"
+#define COLOR_DK_GRAY			"\033[1;30m"
+#define COLOR_BLUE			"\033[0;34m"
+#define COLOR_LT_BLUE			"\033[1;34m"
+#define COLOR_GREEN			"\033[0;32m"
+#define COLOR_LT_GREEN			"\033[1;32m"
+#define COLOR_CYAN			"\033[0;36m"
+#define COLOR_LT_CYAN			"\033[1;36m"
+#define COLOR_RED			"\033[0;31m"
+#define COLOR_LT_RED			"\033[1;31m"
+#define COLOR_PURPLE			"\033[0;35m"
+#define COLOR_LT_PURPLE			"\033[1;35m"
+#define COLOR_BROWN			"\033[0;33m"
+#define COLOR_YELLOW			"\033[1;33m"
+#define COLOR_LT_GRAY			"\033[0;37m"
+#define COLOR_WHITE			"\033[1;37m"
+#define COLOR_RESET			"\033[0m"
+
+typedef struct subsystem {
+	splat_user_t sub_desc;		/* Subsystem description */
+	List sub_tests;			/* Assocated subsystem tests list */
+} subsystem_t;
+
+typedef struct test {
+	splat_user_t test_desc;		/* Test description */
+	subsystem_t *test_sub;		/* Parent subsystem */
+} test_t;
+
+typedef struct cmd_args {
+	int args_verbose;		/* Verbose flag */
+	int args_do_list;		/* Display all tests flag */
+	int args_do_all;		/* Run all tests flag */
+	int args_do_color;		/* Colorize output */
+	int args_exit_on_error;		/* Exit on first error flag */
+	List args_tests;		/* Requested subsystems/tests */
+} cmd_args_t;
+
+#endif /* _SPLAT_H */
+
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/config/Rules.am
@@ -0,0 +1,14 @@
+###############################################################################
+# Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+# Copyright (C) 2007 The Regents of the University of California.
+# Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+###############################################################################
+# Common rules for user space components.
+###############################################################################
+
+DEFAULT_INCLUDES = -include ${top_builddir}/spl_config.h
+
+AM_LIBTOOLFLAGS = --silent
+AM_CPPFLAGS = -D__USE_LARGEFILE64
+AM_CFLAGS  = -Wall -Wshadow -Wstrict-prototypes -fno-strict-aliasing
+AM_CFLAGS += ${DEBUG_CFLAGS}
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/config/compile
@@ -0,0 +1,347 @@
+#! /bin/sh
+# Wrapper for compilers which do not understand '-c -o'.
+
+scriptversion=2012-10-14.11; # UTC
+
+# Copyright (C) 1999-2014 Free Software Foundation, Inc.
+# Written by Tom Tromey <tromey@cygnus.com>.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# This file is maintained in Automake, please report
+# bugs to <bug-automake@gnu.org> or send patches to
+# <automake-patches@gnu.org>.
+
+nl='
+'
+
+# We need space, tab and new line, in precisely that order.  Quoting is
+# there to prevent tools from complaining about whitespace usage.
+IFS=" ""	$nl"
+
+file_conv=
+
+# func_file_conv build_file lazy
+# Convert a $build file to $host form and store it in $file
+# Currently only supports Windows hosts. If the determined conversion
+# type is listed in (the comma separated) LAZY, no conversion will
+# take place.
+func_file_conv ()
+{
+  file=$1
+  case $file in
+    / | /[!/]*) # absolute file, and not a UNC file
+      if test -z "$file_conv"; then
+	# lazily determine how to convert abs files
+	case `uname -s` in
+	  MINGW*)
+	    file_conv=mingw
+	    ;;
+	  CYGWIN*)
+	    file_conv=cygwin
+	    ;;
+	  *)
+	    file_conv=wine
+	    ;;
+	esac
+      fi
+      case $file_conv/,$2, in
+	*,$file_conv,*)
+	  ;;
+	mingw/*)
+	  file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'`
+	  ;;
+	cygwin/*)
+	  file=`cygpath -m "$file" || echo "$file"`
+	  ;;
+	wine/*)
+	  file=`winepath -w "$file" || echo "$file"`
+	  ;;
+      esac
+      ;;
+  esac
+}
+
+# func_cl_dashL linkdir
+# Make cl look for libraries in LINKDIR
+func_cl_dashL ()
+{
+  func_file_conv "$1"
+  if test -z "$lib_path"; then
+    lib_path=$file
+  else
+    lib_path="$lib_path;$file"
+  fi
+  linker_opts="$linker_opts -LIBPATH:$file"
+}
+
+# func_cl_dashl library
+# Do a library search-path lookup for cl
+func_cl_dashl ()
+{
+  lib=$1
+  found=no
+  save_IFS=$IFS
+  IFS=';'
+  for dir in $lib_path $LIB
+  do
+    IFS=$save_IFS
+    if $shared && test -f "$dir/$lib.dll.lib"; then
+      found=yes
+      lib=$dir/$lib.dll.lib
+      break
+    fi
+    if test -f "$dir/$lib.lib"; then
+      found=yes
+      lib=$dir/$lib.lib
+      break
+    fi
+    if test -f "$dir/lib$lib.a"; then
+      found=yes
+      lib=$dir/lib$lib.a
+      break
+    fi
+  done
+  IFS=$save_IFS
+
+  if test "$found" != yes; then
+    lib=$lib.lib
+  fi
+}
+
+# func_cl_wrapper cl arg...
+# Adjust compile command to suit cl
+func_cl_wrapper ()
+{
+  # Assume a capable shell
+  lib_path=
+  shared=:
+  linker_opts=
+  for arg
+  do
+    if test -n "$eat"; then
+      eat=
+    else
+      case $1 in
+	-o)
+	  # configure might choose to run compile as 'compile cc -o foo foo.c'.
+	  eat=1
+	  case $2 in
+	    *.o | *.[oO][bB][jJ])
+	      func_file_conv "$2"
+	      set x "$@" -Fo"$file"
+	      shift
+	      ;;
+	    *)
+	      func_file_conv "$2"
+	      set x "$@" -Fe"$file"
+	      shift
+	      ;;
+	  esac
+	  ;;
+	-I)
+	  eat=1
+	  func_file_conv "$2" mingw
+	  set x "$@" -I"$file"
+	  shift
+	  ;;
+	-I*)
+	  func_file_conv "${1#-I}" mingw
+	  set x "$@" -I"$file"
+	  shift
+	  ;;
+	-l)
+	  eat=1
+	  func_cl_dashl "$2"
+	  set x "$@" "$lib"
+	  shift
+	  ;;
+	-l*)
+	  func_cl_dashl "${1#-l}"
+	  set x "$@" "$lib"
+	  shift
+	  ;;
+	-L)
+	  eat=1
+	  func_cl_dashL "$2"
+	  ;;
+	-L*)
+	  func_cl_dashL "${1#-L}"
+	  ;;
+	-static)
+	  shared=false
+	  ;;
+	-Wl,*)
+	  arg=${1#-Wl,}
+	  save_ifs="$IFS"; IFS=','
+	  for flag in $arg; do
+	    IFS="$save_ifs"
+	    linker_opts="$linker_opts $flag"
+	  done
+	  IFS="$save_ifs"
+	  ;;
+	-Xlinker)
+	  eat=1
+	  linker_opts="$linker_opts $2"
+	  ;;
+	-*)
+	  set x "$@" "$1"
+	  shift
+	  ;;
+	*.cc | *.CC | *.cxx | *.CXX | *.[cC]++)
+	  func_file_conv "$1"
+	  set x "$@" -Tp"$file"
+	  shift
+	  ;;
+	*.c | *.cpp | *.CPP | *.lib | *.LIB | *.Lib | *.OBJ | *.obj | *.[oO])
+	  func_file_conv "$1" mingw
+	  set x "$@" "$file"
+	  shift
+	  ;;
+	*)
+	  set x "$@" "$1"
+	  shift
+	  ;;
+      esac
+    fi
+    shift
+  done
+  if test -n "$linker_opts"; then
+    linker_opts="-link$linker_opts"
+  fi
+  exec "$@" $linker_opts
+  exit 1
+}
+
+eat=
+
+case $1 in
+  '')
+     echo "$0: No command.  Try '$0 --help' for more information." 1>&2
+     exit 1;
+     ;;
+  -h | --h*)
+    cat <<\EOF
+Usage: compile [--help] [--version] PROGRAM [ARGS]
+
+Wrapper for compilers which do not understand '-c -o'.
+Remove '-o dest.o' from ARGS, run PROGRAM with the remaining
+arguments, and rename the output as expected.
+
+If you are trying to build a whole package this is not the
+right script to run: please start by reading the file 'INSTALL'.
+
+Report bugs to <bug-automake@gnu.org>.
+EOF
+    exit $?
+    ;;
+  -v | --v*)
+    echo "compile $scriptversion"
+    exit $?
+    ;;
+  cl | *[/\\]cl | cl.exe | *[/\\]cl.exe )
+    func_cl_wrapper "$@"      # Doesn't return...
+    ;;
+esac
+
+ofile=
+cfile=
+
+for arg
+do
+  if test -n "$eat"; then
+    eat=
+  else
+    case $1 in
+      -o)
+	# configure might choose to run compile as 'compile cc -o foo foo.c'.
+	# So we strip '-o arg' only if arg is an object.
+	eat=1
+	case $2 in
+	  *.o | *.obj)
+	    ofile=$2
+	    ;;
+	  *)
+	    set x "$@" -o "$2"
+	    shift
+	    ;;
+	esac
+	;;
+      *.c)
+	cfile=$1
+	set x "$@" "$1"
+	shift
+	;;
+      *)
+	set x "$@" "$1"
+	shift
+	;;
+    esac
+  fi
+  shift
+done
+
+if test -z "$ofile" || test -z "$cfile"; then
+  # If no '-o' option was seen then we might have been invoked from a
+  # pattern rule where we don't need one.  That is ok -- this is a
+  # normal compilation that the losing compiler can handle.  If no
+  # '.c' file was seen then we are probably linking.  That is also
+  # ok.
+  exec "$@"
+fi
+
+# Name of file we expect compiler to create.
+cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'`
+
+# Create the lock directory.
+# Note: use '[/\\:.-]' here to ensure that we don't use the same name
+# that we are using for the .o file.  Also, base the name on the expected
+# object file name, since that is what matters with a parallel build.
+lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d
+while true; do
+  if mkdir "$lockdir" >/dev/null 2>&1; then
+    break
+  fi
+  sleep 1
+done
+# FIXME: race condition here if user kills between mkdir and trap.
+trap "rmdir '$lockdir'; exit 1" 1 2 15
+
+# Run the compile.
+"$@"
+ret=$?
+
+if test -f "$cofile"; then
+  test "$cofile" = "$ofile" || mv "$cofile" "$ofile"
+elif test -f "${cofile}bj"; then
+  test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile"
+fi
+
+rmdir "$lockdir"
+exit $ret
+
+# Local Variables:
+# mode: shell-script
+# sh-indentation: 2
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
+# End:
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/config/config.awk
@@ -0,0 +1,15 @@
+# Remove default preprocessor define's from config.h
+#   PACKAGE
+#   PACKAGE_BUGREPORT
+#   PACKAGE_NAME
+#   PACKAGE_STRING
+#   PACKAGE_TARNAME
+#   PACKAGE_VERSION
+#   STDC_HEADERS
+#   VERSION
+
+BEGIN { RS = "" ; FS = "\n" }     \
+	!/.#define PACKAGE./ &&   \
+	!/.#define VERSION./ &&   \
+	!/.#define STDC_HEADERS./ \
+	{ print $0"\n" }
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/config/config.guess
@@ -0,0 +1,1441 @@
+#! /bin/sh
+# Attempt to guess a canonical system name.
+#   Copyright 1992-2015 Free Software Foundation, Inc.
+
+timestamp='2015-08-20'
+
+# This file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, see <http://www.gnu.org/licenses/>.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that
+# program.  This Exception is an additional permission under section 7
+# of the GNU General Public License, version 3 ("GPLv3").
+#
+# Originally written by Per Bothner; maintained since 2000 by Ben Elliston.
+#
+# You can get the latest version of this script from:
+# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
+#
+# Please send patches to <config-patches@gnu.org>.
+
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION]
+
+Output the configuration name of the system \`$me' is run on.
+
+Operation modes:
+  -h, --help         print this help, then exit
+  -t, --time-stamp   print date of last modification, then exit
+  -v, --version      print version number, then exit
+
+Report bugs and patches to <config-patches@gnu.org>."
+
+version="\
+GNU config.guess ($timestamp)
+
+Originally written by Per Bothner.
+Copyright 1992-2015 Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions.  There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+  case $1 in
+    --time-stamp | --time* | -t )
+       echo "$timestamp" ; exit ;;
+    --version | -v )
+       echo "$version" ; exit ;;
+    --help | --h* | -h )
+       echo "$usage"; exit ;;
+    -- )     # Stop option processing
+       shift; break ;;
+    - )	# Use stdin as input.
+       break ;;
+    -* )
+       echo "$me: invalid option $1$help" >&2
+       exit 1 ;;
+    * )
+       break ;;
+  esac
+done
+
+if test $# != 0; then
+  echo "$me: too many arguments$help" >&2
+  exit 1
+fi
+
+trap 'exit 1' 1 2 15
+
+# CC_FOR_BUILD -- compiler used by this script. Note that the use of a
+# compiler to aid in system detection is discouraged as it requires
+# temporary files to be created and, as you can see below, it is a
+# headache to deal with in a portable fashion.
+
+# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still
+# use `HOST_CC' if defined, but it is deprecated.
+
+# Portable tmp directory creation inspired by the Autoconf team.
+
+set_cc_for_build='
+trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ;
+trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ;
+: ${TMPDIR=/tmp} ;
+ { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
+ { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } ||
+ { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } ||
+ { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ;
+dummy=$tmp/dummy ;
+tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ;
+case $CC_FOR_BUILD,$HOST_CC,$CC in
+ ,,)    echo "int x;" > $dummy.c ;
+	for c in cc gcc c89 c99 ; do
+	  if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then
+	     CC_FOR_BUILD="$c"; break ;
+	  fi ;
+	done ;
+	if test x"$CC_FOR_BUILD" = x ; then
+	  CC_FOR_BUILD=no_compiler_found ;
+	fi
+	;;
+ ,,*)   CC_FOR_BUILD=$CC ;;
+ ,*,*)  CC_FOR_BUILD=$HOST_CC ;;
+esac ; set_cc_for_build= ;'
+
+# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
+# (ghazi@noc.rutgers.edu 1994-08-24)
+if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
+	PATH=$PATH:/.attbin ; export PATH
+fi
+
+UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
+UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
+UNAME_SYSTEM=`(uname -s) 2>/dev/null`  || UNAME_SYSTEM=unknown
+UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
+
+case "${UNAME_SYSTEM}" in
+Linux|GNU|GNU/*)
+	# If the system lacks a compiler, then just pick glibc.
+	# We could probably try harder.
+	LIBC=gnu
+
+	eval $set_cc_for_build
+	cat <<-EOF > $dummy.c
+	#include <features.h>
+	#if defined(__UCLIBC__)
+	LIBC=uclibc
+	#elif defined(__dietlibc__)
+	LIBC=dietlibc
+	#else
+	LIBC=gnu
+	#endif
+	EOF
+	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC' | sed 's, ,,g'`
+	;;
+esac
+
+# Note: order is significant - the case branches are not exclusive.
+
+case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
+    *:NetBSD:*:*)
+	# NetBSD (nbsd) targets should (where applicable) match one or
+	# more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*,
+	# *-*-netbsdecoff* and *-*-netbsd*.  For targets that recently
+	# switched to ELF, *-*-netbsd* would select the old
+	# object file format.  This provides both forward
+	# compatibility and a consistent mechanism for selecting the
+	# object file format.
+	#
+	# Note: NetBSD doesn't particularly care about the vendor
+	# portion of the name.  We always set it to "unknown".
+	sysctl="sysctl -n hw.machine_arch"
+	UNAME_MACHINE_ARCH=`(uname -p 2>/dev/null || \
+	    /sbin/$sysctl 2>/dev/null || \
+	    /usr/sbin/$sysctl 2>/dev/null || \
+	    echo unknown)`
+	case "${UNAME_MACHINE_ARCH}" in
+	    armeb) machine=armeb-unknown ;;
+	    arm*) machine=arm-unknown ;;
+	    sh3el) machine=shl-unknown ;;
+	    sh3eb) machine=sh-unknown ;;
+	    sh5el) machine=sh5le-unknown ;;
+	    earmv*)
+		arch=`echo ${UNAME_MACHINE_ARCH} | sed -e 's,^e\(armv[0-9]\).*$,\1,'`
+		endian=`echo ${UNAME_MACHINE_ARCH} | sed -ne 's,^.*\(eb\)$,\1,p'`
+		machine=${arch}${endian}-unknown
+		;;
+	    *) machine=${UNAME_MACHINE_ARCH}-unknown ;;
+	esac
+	# The Operating System including object format, if it has switched
+	# to ELF recently, or will in the future.
+	case "${UNAME_MACHINE_ARCH}" in
+	    arm*|earm*|i386|m68k|ns32k|sh3*|sparc|vax)
+		eval $set_cc_for_build
+		if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
+			| grep -q __ELF__
+		then
+		    # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
+		    # Return netbsd for either.  FIX?
+		    os=netbsd
+		else
+		    os=netbsdelf
+		fi
+		;;
+	    *)
+		os=netbsd
+		;;
+	esac
+	# Determine ABI tags.
+	case "${UNAME_MACHINE_ARCH}" in
+	    earm*)
+		expr='s/^earmv[0-9]/-eabi/;s/eb$//'
+		abi=`echo ${UNAME_MACHINE_ARCH} | sed -e "$expr"`
+		;;
+	esac
+	# The OS release
+	# Debian GNU/NetBSD machines have a different userland, and
+	# thus, need a distinct triplet. However, they do not need
+	# kernel version information, so it can be replaced with a
+	# suitable tag, in the style of linux-gnu.
+	case "${UNAME_VERSION}" in
+	    Debian*)
+		release='-gnu'
+		;;
+	    *)
+		release=`echo ${UNAME_RELEASE} | sed -e 's/[-_].*//' | cut -d. -f1,2`
+		;;
+	esac
+	# Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
+	# contains redundant information, the shorter form:
+	# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
+	echo "${machine}-${os}${release}${abi}"
+	exit ;;
+    *:Bitrig:*:*)
+	UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'`
+	echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_RELEASE}
+	exit ;;
+    *:OpenBSD:*:*)
+	UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`
+	echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE}
+	exit ;;
+    *:ekkoBSD:*:*)
+	echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE}
+	exit ;;
+    *:SolidBSD:*:*)
+	echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE}
+	exit ;;
+    macppc:MirBSD:*:*)
+	echo powerpc-unknown-mirbsd${UNAME_RELEASE}
+	exit ;;
+    *:MirBSD:*:*)
+	echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE}
+	exit ;;
+    *:Sortix:*:*)
+	echo ${UNAME_MACHINE}-unknown-sortix
+	exit ;;
+    alpha:OSF1:*:*)
+	case $UNAME_RELEASE in
+	*4.0)
+		UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
+		;;
+	*5.*)
+		UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
+		;;
+	esac
+	# According to Compaq, /usr/sbin/psrinfo has been available on
+	# OSF/1 and Tru64 systems produced since 1995.  I hope that
+	# covers most systems running today.  This code pipes the CPU
+	# types through head -n 1, so we only detect the type of CPU 0.
+	ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^  The alpha \(.*\) processor.*$/\1/p' | head -n 1`
+	case "$ALPHA_CPU_TYPE" in
+	    "EV4 (21064)")
+		UNAME_MACHINE="alpha" ;;
+	    "EV4.5 (21064)")
+		UNAME_MACHINE="alpha" ;;
+	    "LCA4 (21066/21068)")
+		UNAME_MACHINE="alpha" ;;
+	    "EV5 (21164)")
+		UNAME_MACHINE="alphaev5" ;;
+	    "EV5.6 (21164A)")
+		UNAME_MACHINE="alphaev56" ;;
+	    "EV5.6 (21164PC)")
+		UNAME_MACHINE="alphapca56" ;;
+	    "EV5.7 (21164PC)")
+		UNAME_MACHINE="alphapca57" ;;
+	    "EV6 (21264)")
+		UNAME_MACHINE="alphaev6" ;;
+	    "EV6.7 (21264A)")
+		UNAME_MACHINE="alphaev67" ;;
+	    "EV6.8CB (21264C)")
+		UNAME_MACHINE="alphaev68" ;;
+	    "EV6.8AL (21264B)")
+		UNAME_MACHINE="alphaev68" ;;
+	    "EV6.8CX (21264D)")
+		UNAME_MACHINE="alphaev68" ;;
+	    "EV6.9A (21264/EV69A)")
+		UNAME_MACHINE="alphaev69" ;;
+	    "EV7 (21364)")
+		UNAME_MACHINE="alphaev7" ;;
+	    "EV7.9 (21364A)")
+		UNAME_MACHINE="alphaev79" ;;
+	esac
+	# A Pn.n version is a patched version.
+	# A Vn.n version is a released version.
+	# A Tn.n version is a released field test version.
+	# A Xn.n version is an unreleased experimental baselevel.
+	# 1.2 uses "1.2" for uname -r.
+	echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+	# Reset EXIT trap before exiting to avoid spurious non-zero exit code.
+	exitcode=$?
+	trap '' 0
+	exit $exitcode ;;
+    Alpha\ *:Windows_NT*:*)
+	# How do we know it's Interix rather than the generic POSIX subsystem?
+	# Should we change UNAME_MACHINE based on the output of uname instead
+	# of the specific Alpha model?
+	echo alpha-pc-interix
+	exit ;;
+    21064:Windows_NT:50:3)
+	echo alpha-dec-winnt3.5
+	exit ;;
+    Amiga*:UNIX_System_V:4.0:*)
+	echo m68k-unknown-sysv4
+	exit ;;
+    *:[Aa]miga[Oo][Ss]:*:*)
+	echo ${UNAME_MACHINE}-unknown-amigaos
+	exit ;;
+    *:[Mm]orph[Oo][Ss]:*:*)
+	echo ${UNAME_MACHINE}-unknown-morphos
+	exit ;;
+    *:OS/390:*:*)
+	echo i370-ibm-openedition
+	exit ;;
+    *:z/VM:*:*)
+	echo s390-ibm-zvmoe
+	exit ;;
+    *:OS400:*:*)
+	echo powerpc-ibm-os400
+	exit ;;
+    arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
+	echo arm-acorn-riscix${UNAME_RELEASE}
+	exit ;;
+    arm*:riscos:*:*|arm*:RISCOS:*:*)
+	echo arm-unknown-riscos
+	exit ;;
+    SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
+	echo hppa1.1-hitachi-hiuxmpp
+	exit ;;
+    Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
+	# akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
+	if test "`(/bin/universe) 2>/dev/null`" = att ; then
+		echo pyramid-pyramid-sysv3
+	else
+		echo pyramid-pyramid-bsd
+	fi
+	exit ;;
+    NILE*:*:*:dcosx)
+	echo pyramid-pyramid-svr4
+	exit ;;
+    DRS?6000:unix:4.0:6*)
+	echo sparc-icl-nx6
+	exit ;;
+    DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*)
+	case `/usr/bin/uname -p` in
+	    sparc) echo sparc-icl-nx7; exit ;;
+	esac ;;
+    s390x:SunOS:*:*)
+	echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit ;;
+    sun4H:SunOS:5.*:*)
+	echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit ;;
+    sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
+	echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit ;;
+    i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*)
+	echo i386-pc-auroraux${UNAME_RELEASE}
+	exit ;;
+    i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*)
+	eval $set_cc_for_build
+	SUN_ARCH="i386"
+	# If there is a compiler, see if it is configured for 64-bit objects.
+	# Note that the Sun cc does not turn __LP64__ into 1 like gcc does.
+	# This test works for both compilers.
+	if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
+	    if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \
+		(CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
+		grep IS_64BIT_ARCH >/dev/null
+	    then
+		SUN_ARCH="x86_64"
+	    fi
+	fi
+	echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit ;;
+    sun4*:SunOS:6*:*)
+	# According to config.sub, this is the proper way to canonicalize
+	# SunOS6.  Hard to guess exactly what SunOS6 will be like, but
+	# it's likely to be more like Solaris than SunOS4.
+	echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit ;;
+    sun4*:SunOS:*:*)
+	case "`/usr/bin/arch -k`" in
+	    Series*|S4*)
+		UNAME_RELEASE=`uname -v`
+		;;
+	esac
+	# Japanese Language versions have a version number like `4.1.3-JL'.
+	echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
+	exit ;;
+    sun3*:SunOS:*:*)
+	echo m68k-sun-sunos${UNAME_RELEASE}
+	exit ;;
+    sun*:*:4.2BSD:*)
+	UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
+	test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
+	case "`/bin/arch`" in
+	    sun3)
+		echo m68k-sun-sunos${UNAME_RELEASE}
+		;;
+	    sun4)
+		echo sparc-sun-sunos${UNAME_RELEASE}
+		;;
+	esac
+	exit ;;
+    aushp:SunOS:*:*)
+	echo sparc-auspex-sunos${UNAME_RELEASE}
+	exit ;;
+    # The situation for MiNT is a little confusing.  The machine name
+    # can be virtually everything (everything which is not
+    # "atarist" or "atariste" at least should have a processor
+    # > m68000).  The system name ranges from "MiNT" over "FreeMiNT"
+    # to the lowercase version "mint" (or "freemint").  Finally
+    # the system name "TOS" denotes a system which is actually not
+    # MiNT.  But MiNT is downward compatible to TOS, so this should
+    # be no problem.
+    atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
+	echo m68k-atari-mint${UNAME_RELEASE}
+	exit ;;
+    atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
+	echo m68k-atari-mint${UNAME_RELEASE}
+	exit ;;
+    *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
+	echo m68k-atari-mint${UNAME_RELEASE}
+	exit ;;
+    milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
+	echo m68k-milan-mint${UNAME_RELEASE}
+	exit ;;
+    hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
+	echo m68k-hades-mint${UNAME_RELEASE}
+	exit ;;
+    *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
+	echo m68k-unknown-mint${UNAME_RELEASE}
+	exit ;;
+    m68k:machten:*:*)
+	echo m68k-apple-machten${UNAME_RELEASE}
+	exit ;;
+    powerpc:machten:*:*)
+	echo powerpc-apple-machten${UNAME_RELEASE}
+	exit ;;
+    RISC*:Mach:*:*)
+	echo mips-dec-mach_bsd4.3
+	exit ;;
+    RISC*:ULTRIX:*:*)
+	echo mips-dec-ultrix${UNAME_RELEASE}
+	exit ;;
+    VAX*:ULTRIX*:*:*)
+	echo vax-dec-ultrix${UNAME_RELEASE}
+	exit ;;
+    2020:CLIX:*:* | 2430:CLIX:*:*)
+	echo clipper-intergraph-clix${UNAME_RELEASE}
+	exit ;;
+    mips:*:*:UMIPS | mips:*:*:RISCos)
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+#ifdef __cplusplus
+#include <stdio.h>  /* for printf() prototype */
+	int main (int argc, char *argv[]) {
+#else
+	int main (argc, argv) int argc; char *argv[]; {
+#endif
+	#if defined (host_mips) && defined (MIPSEB)
+	#if defined (SYSTYPE_SYSV)
+	  printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
+	#endif
+	#if defined (SYSTYPE_SVR4)
+	  printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
+	#endif
+	#if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
+	  printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
+	#endif
+	#endif
+	  exit (-1);
+	}
+EOF
+	$CC_FOR_BUILD -o $dummy $dummy.c &&
+	  dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` &&
+	  SYSTEM_NAME=`$dummy $dummyarg` &&
+	    { echo "$SYSTEM_NAME"; exit; }
+	echo mips-mips-riscos${UNAME_RELEASE}
+	exit ;;
+    Motorola:PowerMAX_OS:*:*)
+	echo powerpc-motorola-powermax
+	exit ;;
+    Motorola:*:4.3:PL8-*)
+	echo powerpc-harris-powermax
+	exit ;;
+    Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*)
+	echo powerpc-harris-powermax
+	exit ;;
+    Night_Hawk:Power_UNIX:*:*)
+	echo powerpc-harris-powerunix
+	exit ;;
+    m88k:CX/UX:7*:*)
+	echo m88k-harris-cxux7
+	exit ;;
+    m88k:*:4*:R4*)
+	echo m88k-motorola-sysv4
+	exit ;;
+    m88k:*:3*:R3*)
+	echo m88k-motorola-sysv3
+	exit ;;
+    AViiON:dgux:*:*)
+	# DG/UX returns AViiON for all architectures
+	UNAME_PROCESSOR=`/usr/bin/uname -p`
+	if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
+	then
+	    if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
+	       [ ${TARGET_BINARY_INTERFACE}x = x ]
+	    then
+		echo m88k-dg-dgux${UNAME_RELEASE}
+	    else
+		echo m88k-dg-dguxbcs${UNAME_RELEASE}
+	    fi
+	else
+	    echo i586-dg-dgux${UNAME_RELEASE}
+	fi
+	exit ;;
+    M88*:DolphinOS:*:*)	# DolphinOS (SVR3)
+	echo m88k-dolphin-sysv3
+	exit ;;
+    M88*:*:R3*:*)
+	# Delta 88k system running SVR3
+	echo m88k-motorola-sysv3
+	exit ;;
+    XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
+	echo m88k-tektronix-sysv3
+	exit ;;
+    Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
+	echo m68k-tektronix-bsd
+	exit ;;
+    *:IRIX*:*:*)
+	echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
+	exit ;;
+    ????????:AIX?:[12].1:2)   # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
+	echo romp-ibm-aix     # uname -m gives an 8 hex-code CPU id
+	exit ;;               # Note that: echo "'`uname -s`'" gives 'AIX '
+    i*86:AIX:*:*)
+	echo i386-ibm-aix
+	exit ;;
+    ia64:AIX:*:*)
+	if [ -x /usr/bin/oslevel ] ; then
+		IBM_REV=`/usr/bin/oslevel`
+	else
+		IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+	fi
+	echo ${UNAME_MACHINE}-ibm-aix${IBM_REV}
+	exit ;;
+    *:AIX:2:3)
+	if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
+		eval $set_cc_for_build
+		sed 's/^		//' << EOF >$dummy.c
+		#include <sys/systemcfg.h>
+
+		main()
+			{
+			if (!__power_pc())
+				exit(1);
+			puts("powerpc-ibm-aix3.2.5");
+			exit(0);
+			}
+EOF
+		if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy`
+		then
+			echo "$SYSTEM_NAME"
+		else
+			echo rs6000-ibm-aix3.2.5
+		fi
+	elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
+		echo rs6000-ibm-aix3.2.4
+	else
+		echo rs6000-ibm-aix3.2
+	fi
+	exit ;;
+    *:AIX:*:[4567])
+	IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
+	if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
+		IBM_ARCH=rs6000
+	else
+		IBM_ARCH=powerpc
+	fi
+	if [ -x /usr/bin/lslpp ] ; then
+		IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc |
+			   awk -F: '{ print $3 }' | sed s/[0-9]*$/0/`
+	else
+		IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+	fi
+	echo ${IBM_ARCH}-ibm-aix${IBM_REV}
+	exit ;;
+    *:AIX:*:*)
+	echo rs6000-ibm-aix
+	exit ;;
+    ibmrt:4.4BSD:*|romp-ibm:BSD:*)
+	echo romp-ibm-bsd4.4
+	exit ;;
+    ibmrt:*BSD:*|romp-ibm:BSD:*)            # covers RT/PC BSD and
+	echo romp-ibm-bsd${UNAME_RELEASE}   # 4.3 with uname added to
+	exit ;;                             # report: romp-ibm BSD 4.3
+    *:BOSX:*:*)
+	echo rs6000-bull-bosx
+	exit ;;
+    DPX/2?00:B.O.S.:*:*)
+	echo m68k-bull-sysv3
+	exit ;;
+    9000/[34]??:4.3bsd:1.*:*)
+	echo m68k-hp-bsd
+	exit ;;
+    hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
+	echo m68k-hp-bsd4.4
+	exit ;;
+    9000/[34678]??:HP-UX:*:*)
+	HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+	case "${UNAME_MACHINE}" in
+	    9000/31? )            HP_ARCH=m68000 ;;
+	    9000/[34]?? )         HP_ARCH=m68k ;;
+	    9000/[678][0-9][0-9])
+		if [ -x /usr/bin/getconf ]; then
+		    sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
+		    sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
+		    case "${sc_cpu_version}" in
+		      523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
+		      528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
+		      532)                      # CPU_PA_RISC2_0
+			case "${sc_kernel_bits}" in
+			  32) HP_ARCH="hppa2.0n" ;;
+			  64) HP_ARCH="hppa2.0w" ;;
+			  '') HP_ARCH="hppa2.0" ;;   # HP-UX 10.20
+			esac ;;
+		    esac
+		fi
+		if [ "${HP_ARCH}" = "" ]; then
+		    eval $set_cc_for_build
+		    sed 's/^		//' << EOF >$dummy.c
+
+		#define _HPUX_SOURCE
+		#include <stdlib.h>
+		#include <unistd.h>
+
+		int main ()
+		{
+		#if defined(_SC_KERNEL_BITS)
+		    long bits = sysconf(_SC_KERNEL_BITS);
+		#endif
+		    long cpu  = sysconf (_SC_CPU_VERSION);
+
+		    switch (cpu)
+			{
+			case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
+			case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
+			case CPU_PA_RISC2_0:
+		#if defined(_SC_KERNEL_BITS)
+			    switch (bits)
+				{
+				case 64: puts ("hppa2.0w"); break;
+				case 32: puts ("hppa2.0n"); break;
+				default: puts ("hppa2.0"); break;
+				} break;
+		#else  /* !defined(_SC_KERNEL_BITS) */
+			    puts ("hppa2.0"); break;
+		#endif
+			default: puts ("hppa1.0"); break;
+			}
+		    exit (0);
+		}
+EOF
+		    (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
+		    test -z "$HP_ARCH" && HP_ARCH=hppa
+		fi ;;
+	esac
+	if [ ${HP_ARCH} = "hppa2.0w" ]
+	then
+	    eval $set_cc_for_build
+
+	    # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating
+	    # 32-bit code.  hppa64-hp-hpux* has the same kernel and a compiler
+	    # generating 64-bit code.  GNU and HP use different nomenclature:
+	    #
+	    # $ CC_FOR_BUILD=cc ./config.guess
+	    # => hppa2.0w-hp-hpux11.23
+	    # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess
+	    # => hppa64-hp-hpux11.23
+
+	    if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) |
+		grep -q __LP64__
+	    then
+		HP_ARCH="hppa2.0w"
+	    else
+		HP_ARCH="hppa64"
+	    fi
+	fi
+	echo ${HP_ARCH}-hp-hpux${HPUX_REV}
+	exit ;;
+    ia64:HP-UX:*:*)
+	HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+	echo ia64-hp-hpux${HPUX_REV}
+	exit ;;
+    3050*:HI-UX:*:*)
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+	#include <unistd.h>
+	int
+	main ()
+	{
+	  long cpu = sysconf (_SC_CPU_VERSION);
+	  /* The order matters, because CPU_IS_HP_MC68K erroneously returns
+	     true for CPU_PA_RISC1_0.  CPU_IS_PA_RISC returns correct
+	     results, however.  */
+	  if (CPU_IS_PA_RISC (cpu))
+	    {
+	      switch (cpu)
+		{
+		  case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break;
+		  case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break;
+		  case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break;
+		  default: puts ("hppa-hitachi-hiuxwe2"); break;
+		}
+	    }
+	  else if (CPU_IS_HP_MC68K (cpu))
+	    puts ("m68k-hitachi-hiuxwe2");
+	  else puts ("unknown-hitachi-hiuxwe2");
+	  exit (0);
+	}
+EOF
+	$CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` &&
+		{ echo "$SYSTEM_NAME"; exit; }
+	echo unknown-hitachi-hiuxwe2
+	exit ;;
+    9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
+	echo hppa1.1-hp-bsd
+	exit ;;
+    9000/8??:4.3bsd:*:*)
+	echo hppa1.0-hp-bsd
+	exit ;;
+    *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)
+	echo hppa1.0-hp-mpeix
+	exit ;;
+    hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
+	echo hppa1.1-hp-osf
+	exit ;;
+    hp8??:OSF1:*:*)
+	echo hppa1.0-hp-osf
+	exit ;;
+    i*86:OSF1:*:*)
+	if [ -x /usr/sbin/sysversion ] ; then
+	    echo ${UNAME_MACHINE}-unknown-osf1mk
+	else
+	    echo ${UNAME_MACHINE}-unknown-osf1
+	fi
+	exit ;;
+    parisc*:Lites*:*:*)
+	echo hppa1.1-hp-lites
+	exit ;;
+    C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
+	echo c1-convex-bsd
+	exit ;;
+    C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
+	if getsysinfo -f scalar_acc
+	then echo c32-convex-bsd
+	else echo c2-convex-bsd
+	fi
+	exit ;;
+    C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
+	echo c34-convex-bsd
+	exit ;;
+    C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
+	echo c38-convex-bsd
+	exit ;;
+    C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
+	echo c4-convex-bsd
+	exit ;;
+    CRAY*Y-MP:*:*:*)
+	echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit ;;
+    CRAY*[A-Z]90:*:*:*)
+	echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
+	| sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
+	      -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \
+	      -e 's/\.[^.]*$/.X/'
+	exit ;;
+    CRAY*TS:*:*:*)
+	echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit ;;
+    CRAY*T3E:*:*:*)
+	echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit ;;
+    CRAY*SV1:*:*:*)
+	echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit ;;
+    *:UNICOS/mp:*:*)
+	echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit ;;
+    F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
+	FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+	FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+	FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
+	echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+	exit ;;
+    5000:UNIX_System_V:4.*:*)
+	FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+	FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
+	echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+	exit ;;
+    i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
+	echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
+	exit ;;
+    sparc*:BSD/OS:*:*)
+	echo sparc-unknown-bsdi${UNAME_RELEASE}
+	exit ;;
+    *:BSD/OS:*:*)
+	echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
+	exit ;;
+    *:FreeBSD:*:*)
+	UNAME_PROCESSOR=`/usr/bin/uname -p`
+	case ${UNAME_PROCESSOR} in
+	    amd64)
+		echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+	    *)
+		echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+	esac
+	exit ;;
+    i*:CYGWIN*:*)
+	echo ${UNAME_MACHINE}-pc-cygwin
+	exit ;;
+    *:MINGW64*:*)
+	echo ${UNAME_MACHINE}-pc-mingw64
+	exit ;;
+    *:MINGW*:*)
+	echo ${UNAME_MACHINE}-pc-mingw32
+	exit ;;
+    *:MSYS*:*)
+	echo ${UNAME_MACHINE}-pc-msys
+	exit ;;
+    i*:windows32*:*)
+	# uname -m includes "-pc" on this system.
+	echo ${UNAME_MACHINE}-mingw32
+	exit ;;
+    i*:PW*:*)
+	echo ${UNAME_MACHINE}-pc-pw32
+	exit ;;
+    *:Interix*:*)
+	case ${UNAME_MACHINE} in
+	    x86)
+		echo i586-pc-interix${UNAME_RELEASE}
+		exit ;;
+	    authenticamd | genuineintel | EM64T)
+		echo x86_64-unknown-interix${UNAME_RELEASE}
+		exit ;;
+	    IA64)
+		echo ia64-unknown-interix${UNAME_RELEASE}
+		exit ;;
+	esac ;;
+    [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
+	echo i${UNAME_MACHINE}-pc-mks
+	exit ;;
+    8664:Windows_NT:*)
+	echo x86_64-pc-mks
+	exit ;;
+    i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
+	# How do we know it's Interix rather than the generic POSIX subsystem?
+	# It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
+	# UNAME_MACHINE based on the output of uname instead of i386?
+	echo i586-pc-interix
+	exit ;;
+    i*:UWIN*:*)
+	echo ${UNAME_MACHINE}-pc-uwin
+	exit ;;
+    amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*)
+	echo x86_64-unknown-cygwin
+	exit ;;
+    p*:CYGWIN*:*)
+	echo powerpcle-unknown-cygwin
+	exit ;;
+    prep*:SunOS:5.*:*)
+	echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit ;;
+    *:GNU:*:*)
+	# the GNU system
+	echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-${LIBC}`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
+	exit ;;
+    *:GNU/*:*:*)
+	# other systems with GNU libc and userland
+	echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC}
+	exit ;;
+    i*86:Minix:*:*)
+	echo ${UNAME_MACHINE}-pc-minix
+	exit ;;
+    aarch64:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
+    aarch64_be:Linux:*:*)
+	UNAME_MACHINE=aarch64_be
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
+    alpha:Linux:*:*)
+	case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
+	  EV5)   UNAME_MACHINE=alphaev5 ;;
+	  EV56)  UNAME_MACHINE=alphaev56 ;;
+	  PCA56) UNAME_MACHINE=alphapca56 ;;
+	  PCA57) UNAME_MACHINE=alphapca56 ;;
+	  EV6)   UNAME_MACHINE=alphaev6 ;;
+	  EV67)  UNAME_MACHINE=alphaev67 ;;
+	  EV68*) UNAME_MACHINE=alphaev68 ;;
+	esac
+	objdump --private-headers /bin/sh | grep -q ld.so.1
+	if test "$?" = 0 ; then LIBC="gnulibc1" ; fi
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
+    arc:Linux:*:* | arceb:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
+    arm*:Linux:*:*)
+	eval $set_cc_for_build
+	if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
+	    | grep -q __ARM_EABI__
+	then
+	    echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	else
+	    if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \
+		| grep -q __ARM_PCS_VFP
+	    then
+		echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabi
+	    else
+		echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabihf
+	    fi
+	fi
+	exit ;;
+    avr32*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
+    cris:Linux:*:*)
+	echo ${UNAME_MACHINE}-axis-linux-${LIBC}
+	exit ;;
+    crisv32:Linux:*:*)
+	echo ${UNAME_MACHINE}-axis-linux-${LIBC}
+	exit ;;
+    e2k:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
+    frv:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
+    hexagon:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
+    i*86:Linux:*:*)
+	echo ${UNAME_MACHINE}-pc-linux-${LIBC}
+	exit ;;
+    ia64:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
+    m32r*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
+    m68*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
+    mips:Linux:*:* | mips64:Linux:*:*)
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+	#undef CPU
+	#undef ${UNAME_MACHINE}
+	#undef ${UNAME_MACHINE}el
+	#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
+	CPU=${UNAME_MACHINE}el
+	#else
+	#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
+	CPU=${UNAME_MACHINE}
+	#else
+	CPU=
+	#endif
+	#endif
+EOF
+	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'`
+	test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; }
+	;;
+    openrisc*:Linux:*:*)
+	echo or1k-unknown-linux-${LIBC}
+	exit ;;
+    or32:Linux:*:* | or1k*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
+    padre:Linux:*:*)
+	echo sparc-unknown-linux-${LIBC}
+	exit ;;
+    parisc64:Linux:*:* | hppa64:Linux:*:*)
+	echo hppa64-unknown-linux-${LIBC}
+	exit ;;
+    parisc:Linux:*:* | hppa:Linux:*:*)
+	# Look for CPU level
+	case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
+	  PA7*) echo hppa1.1-unknown-linux-${LIBC} ;;
+	  PA8*) echo hppa2.0-unknown-linux-${LIBC} ;;
+	  *)    echo hppa-unknown-linux-${LIBC} ;;
+	esac
+	exit ;;
+    ppc64:Linux:*:*)
+	echo powerpc64-unknown-linux-${LIBC}
+	exit ;;
+    ppc:Linux:*:*)
+	echo powerpc-unknown-linux-${LIBC}
+	exit ;;
+    ppc64le:Linux:*:*)
+	echo powerpc64le-unknown-linux-${LIBC}
+	exit ;;
+    ppcle:Linux:*:*)
+	echo powerpcle-unknown-linux-${LIBC}
+	exit ;;
+    s390:Linux:*:* | s390x:Linux:*:*)
+	echo ${UNAME_MACHINE}-ibm-linux-${LIBC}
+	exit ;;
+    sh64*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
+    sh*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
+    sparc:Linux:*:* | sparc64:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
+    tile*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
+    vax:Linux:*:*)
+	echo ${UNAME_MACHINE}-dec-linux-${LIBC}
+	exit ;;
+    x86_64:Linux:*:*)
+	echo ${UNAME_MACHINE}-pc-linux-${LIBC}
+	exit ;;
+    xtensa*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
+    i*86:DYNIX/ptx:4*:*)
+	# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
+	# earlier versions are messed up and put the nodename in both
+	# sysname and nodename.
+	echo i386-sequent-sysv4
+	exit ;;
+    i*86:UNIX_SV:4.2MP:2.*)
+	# Unixware is an offshoot of SVR4, but it has its own version
+	# number series starting with 2...
+	# I am not positive that other SVR4 systems won't match this,
+	# I just have to hope.  -- rms.
+	# Use sysv4.2uw... so that sysv4* matches it.
+	echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
+	exit ;;
+    i*86:OS/2:*:*)
+	# If we were able to find `uname', then EMX Unix compatibility
+	# is probably installed.
+	echo ${UNAME_MACHINE}-pc-os2-emx
+	exit ;;
+    i*86:XTS-300:*:STOP)
+	echo ${UNAME_MACHINE}-unknown-stop
+	exit ;;
+    i*86:atheos:*:*)
+	echo ${UNAME_MACHINE}-unknown-atheos
+	exit ;;
+    i*86:syllable:*:*)
+	echo ${UNAME_MACHINE}-pc-syllable
+	exit ;;
+    i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*)
+	echo i386-unknown-lynxos${UNAME_RELEASE}
+	exit ;;
+    i*86:*DOS:*:*)
+	echo ${UNAME_MACHINE}-pc-msdosdjgpp
+	exit ;;
+    i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*)
+	UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'`
+	if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
+		echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL}
+	else
+		echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL}
+	fi
+	exit ;;
+    i*86:*:5:[678]*)
+	# UnixWare 7.x, OpenUNIX and OpenServer 6.
+	case `/bin/uname -X | grep "^Machine"` in
+	    *486*)	     UNAME_MACHINE=i486 ;;
+	    *Pentium)	     UNAME_MACHINE=i586 ;;
+	    *Pent*|*Celeron) UNAME_MACHINE=i686 ;;
+	esac
+	echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}
+	exit ;;
+    i*86:*:3.2:*)
+	if test -f /usr/options/cb.name; then
+		UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
+		echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
+	elif /bin/uname -X 2>/dev/null >/dev/null ; then
+		UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')`
+		(/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486
+		(/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \
+			&& UNAME_MACHINE=i586
+		(/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \
+			&& UNAME_MACHINE=i686
+		(/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \
+			&& UNAME_MACHINE=i686
+		echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
+	else
+		echo ${UNAME_MACHINE}-pc-sysv32
+	fi
+	exit ;;
+    pc:*:*:*)
+	# Left here for compatibility:
+	# uname -m prints for DJGPP always 'pc', but it prints nothing about
+	# the processor, so we play safe by assuming i586.
+	# Note: whatever this is, it MUST be the same as what config.sub
+	# prints for the "djgpp" host, or else GDB configury will decide that
+	# this is a cross-build.
+	echo i586-pc-msdosdjgpp
+	exit ;;
+    Intel:Mach:3*:*)
+	echo i386-pc-mach3
+	exit ;;
+    paragon:*:*:*)
+	echo i860-intel-osf1
+	exit ;;
+    i860:*:4.*:*) # i860-SVR4
+	if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
+	  echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
+	else # Add other i860-SVR4 vendors below as they are discovered.
+	  echo i860-unknown-sysv${UNAME_RELEASE}  # Unknown i860-SVR4
+	fi
+	exit ;;
+    mini*:CTIX:SYS*5:*)
+	# "miniframe"
+	echo m68010-convergent-sysv
+	exit ;;
+    mc68k:UNIX:SYSTEM5:3.51m)
+	echo m68k-convergent-sysv
+	exit ;;
+    M680?0:D-NIX:5.3:*)
+	echo m68k-diab-dnix
+	exit ;;
+    M68*:*:R3V[5678]*:*)
+	test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;;
+    3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0)
+	OS_REL=''
+	test -r /etc/.relid \
+	&& OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+	/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+	  && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
+	/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+	  && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
+    3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
+	/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+	  && { echo i486-ncr-sysv4; exit; } ;;
+    NCR*:*:4.2:* | MPRAS*:*:4.2:*)
+	OS_REL='.3'
+	test -r /etc/.relid \
+	    && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+	/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+	    && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
+	/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+	    && { echo i586-ncr-sysv4.3${OS_REL}; exit; }
+	/bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \
+	    && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
+    m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
+	echo m68k-unknown-lynxos${UNAME_RELEASE}
+	exit ;;
+    mc68030:UNIX_System_V:4.*:*)
+	echo m68k-atari-sysv4
+	exit ;;
+    TSUNAMI:LynxOS:2.*:*)
+	echo sparc-unknown-lynxos${UNAME_RELEASE}
+	exit ;;
+    rs6000:LynxOS:2.*:*)
+	echo rs6000-unknown-lynxos${UNAME_RELEASE}
+	exit ;;
+    PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*)
+	echo powerpc-unknown-lynxos${UNAME_RELEASE}
+	exit ;;
+    SM[BE]S:UNIX_SV:*:*)
+	echo mips-dde-sysv${UNAME_RELEASE}
+	exit ;;
+    RM*:ReliantUNIX-*:*:*)
+	echo mips-sni-sysv4
+	exit ;;
+    RM*:SINIX-*:*:*)
+	echo mips-sni-sysv4
+	exit ;;
+    *:SINIX-*:*:*)
+	if uname -p 2>/dev/null >/dev/null ; then
+		UNAME_MACHINE=`(uname -p) 2>/dev/null`
+		echo ${UNAME_MACHINE}-sni-sysv4
+	else
+		echo ns32k-sni-sysv
+	fi
+	exit ;;
+    PENTIUM:*:4.0*:*)	# Unisys `ClearPath HMP IX 4000' SVR4/MP effort
+			# says <Richard.M.Bartel@ccMail.Census.GOV>
+	echo i586-unisys-sysv4
+	exit ;;
+    *:UNIX_System_V:4*:FTX*)
+	# From Gerald Hewes <hewes@openmarket.com>.
+	# How about differentiating between stratus architectures? -djm
+	echo hppa1.1-stratus-sysv4
+	exit ;;
+    *:*:*:FTX*)
+	# From seanf@swdc.stratus.com.
+	echo i860-stratus-sysv4
+	exit ;;
+    i*86:VOS:*:*)
+	# From Paul.Green@stratus.com.
+	echo ${UNAME_MACHINE}-stratus-vos
+	exit ;;
+    *:VOS:*:*)
+	# From Paul.Green@stratus.com.
+	echo hppa1.1-stratus-vos
+	exit ;;
+    mc68*:A/UX:*:*)
+	echo m68k-apple-aux${UNAME_RELEASE}
+	exit ;;
+    news*:NEWS-OS:6*:*)
+	echo mips-sony-newsos6
+	exit ;;
+    R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
+	if [ -d /usr/nec ]; then
+		echo mips-nec-sysv${UNAME_RELEASE}
+	else
+		echo mips-unknown-sysv${UNAME_RELEASE}
+	fi
+	exit ;;
+    BeBox:BeOS:*:*)	# BeOS running on hardware made by Be, PPC only.
+	echo powerpc-be-beos
+	exit ;;
+    BeMac:BeOS:*:*)	# BeOS running on Mac or Mac clone, PPC only.
+	echo powerpc-apple-beos
+	exit ;;
+    BePC:BeOS:*:*)	# BeOS running on Intel PC compatible.
+	echo i586-pc-beos
+	exit ;;
+    BePC:Haiku:*:*)	# Haiku running on Intel PC compatible.
+	echo i586-pc-haiku
+	exit ;;
+    x86_64:Haiku:*:*)
+	echo x86_64-unknown-haiku
+	exit ;;
+    SX-4:SUPER-UX:*:*)
+	echo sx4-nec-superux${UNAME_RELEASE}
+	exit ;;
+    SX-5:SUPER-UX:*:*)
+	echo sx5-nec-superux${UNAME_RELEASE}
+	exit ;;
+    SX-6:SUPER-UX:*:*)
+	echo sx6-nec-superux${UNAME_RELEASE}
+	exit ;;
+    SX-7:SUPER-UX:*:*)
+	echo sx7-nec-superux${UNAME_RELEASE}
+	exit ;;
+    SX-8:SUPER-UX:*:*)
+	echo sx8-nec-superux${UNAME_RELEASE}
+	exit ;;
+    SX-8R:SUPER-UX:*:*)
+	echo sx8r-nec-superux${UNAME_RELEASE}
+	exit ;;
+    Power*:Rhapsody:*:*)
+	echo powerpc-apple-rhapsody${UNAME_RELEASE}
+	exit ;;
+    *:Rhapsody:*:*)
+	echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
+	exit ;;
+    *:Darwin:*:*)
+	UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
+	eval $set_cc_for_build
+	if test "$UNAME_PROCESSOR" = unknown ; then
+	    UNAME_PROCESSOR=powerpc
+	fi
+	if test `echo "$UNAME_RELEASE" | sed -e 's/\..*//'` -le 10 ; then
+	    if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
+		if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
+		    (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
+		    grep IS_64BIT_ARCH >/dev/null
+		then
+		    case $UNAME_PROCESSOR in
+			i386) UNAME_PROCESSOR=x86_64 ;;
+			powerpc) UNAME_PROCESSOR=powerpc64 ;;
+		    esac
+		fi
+	    fi
+	elif test "$UNAME_PROCESSOR" = i386 ; then
+	    # Avoid executing cc on OS X 10.9, as it ships with a stub
+	    # that puts up a graphical alert prompting to install
+	    # developer tools.  Any system running Mac OS X 10.7 or
+	    # later (Darwin 11 and later) is required to have a 64-bit
+	    # processor. This is not true of the ARM version of Darwin
+	    # that Apple uses in portable devices.
+	    UNAME_PROCESSOR=x86_64
+	fi
+	echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
+	exit ;;
+    *:procnto*:*:* | *:QNX:[0123456789]*:*)
+	UNAME_PROCESSOR=`uname -p`
+	if test "$UNAME_PROCESSOR" = "x86"; then
+		UNAME_PROCESSOR=i386
+		UNAME_MACHINE=pc
+	fi
+	echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE}
+	exit ;;
+    *:QNX:*:4*)
+	echo i386-pc-qnx
+	exit ;;
+    NEO-?:NONSTOP_KERNEL:*:*)
+	echo neo-tandem-nsk${UNAME_RELEASE}
+	exit ;;
+    NSE-*:NONSTOP_KERNEL:*:*)
+	echo nse-tandem-nsk${UNAME_RELEASE}
+	exit ;;
+    NSR-?:NONSTOP_KERNEL:*:*)
+	echo nsr-tandem-nsk${UNAME_RELEASE}
+	exit ;;
+    *:NonStop-UX:*:*)
+	echo mips-compaq-nonstopux
+	exit ;;
+    BS2000:POSIX*:*:*)
+	echo bs2000-siemens-sysv
+	exit ;;
+    DS/*:UNIX_System_V:*:*)
+	echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE}
+	exit ;;
+    *:Plan9:*:*)
+	# "uname -m" is not consistent, so use $cputype instead. 386
+	# is converted to i386 for consistency with other x86
+	# operating systems.
+	if test "$cputype" = "386"; then
+	    UNAME_MACHINE=i386
+	else
+	    UNAME_MACHINE="$cputype"
+	fi
+	echo ${UNAME_MACHINE}-unknown-plan9
+	exit ;;
+    *:TOPS-10:*:*)
+	echo pdp10-unknown-tops10
+	exit ;;
+    *:TENEX:*:*)
+	echo pdp10-unknown-tenex
+	exit ;;
+    KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*)
+	echo pdp10-dec-tops20
+	exit ;;
+    XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*)
+	echo pdp10-xkl-tops20
+	exit ;;
+    *:TOPS-20:*:*)
+	echo pdp10-unknown-tops20
+	exit ;;
+    *:ITS:*:*)
+	echo pdp10-unknown-its
+	exit ;;
+    SEI:*:*:SEIUX)
+	echo mips-sei-seiux${UNAME_RELEASE}
+	exit ;;
+    *:DragonFly:*:*)
+	echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
+	exit ;;
+    *:*VMS:*:*)
+	UNAME_MACHINE=`(uname -p) 2>/dev/null`
+	case "${UNAME_MACHINE}" in
+	    A*) echo alpha-dec-vms ; exit ;;
+	    I*) echo ia64-dec-vms ; exit ;;
+	    V*) echo vax-dec-vms ; exit ;;
+	esac ;;
+    *:XENIX:*:SysV)
+	echo i386-pc-xenix
+	exit ;;
+    i*86:skyos:*:*)
+	echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//'
+	exit ;;
+    i*86:rdos:*:*)
+	echo ${UNAME_MACHINE}-pc-rdos
+	exit ;;
+    i*86:AROS:*:*)
+	echo ${UNAME_MACHINE}-pc-aros
+	exit ;;
+    x86_64:VMkernel:*:*)
+	echo ${UNAME_MACHINE}-unknown-esx
+	exit ;;
+esac
+
+cat >&2 <<EOF
+$0: unable to guess system type
+
+This script, last modified $timestamp, has failed to recognize
+the operating system you are using. It is advised that you
+download the most up to date version of the config scripts from
+
+  http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
+and
+  http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
+
+If the version you run ($0) is already up to date, please
+send the following data and any information you think might be
+pertinent to <config-patches@gnu.org> in order to provide the needed
+information to handle your system.
+
+config.guess timestamp = $timestamp
+
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null`
+/bin/uname -X     = `(/bin/uname -X) 2>/dev/null`
+
+hostinfo               = `(hostinfo) 2>/dev/null`
+/bin/universe          = `(/bin/universe) 2>/dev/null`
+/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null`
+/bin/arch              = `(/bin/arch) 2>/dev/null`
+/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null`
+
+UNAME_MACHINE = ${UNAME_MACHINE}
+UNAME_RELEASE = ${UNAME_RELEASE}
+UNAME_SYSTEM  = ${UNAME_SYSTEM}
+UNAME_VERSION = ${UNAME_VERSION}
+EOF
+
+exit 1
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/config/config.sub
@@ -0,0 +1,1813 @@
+#! /bin/sh
+# Configuration validation subroutine script.
+#   Copyright 1992-2015 Free Software Foundation, Inc.
+
+timestamp='2015-08-20'
+
+# This file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, see <http://www.gnu.org/licenses/>.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that
+# program.  This Exception is an additional permission under section 7
+# of the GNU General Public License, version 3 ("GPLv3").
+
+
+# Please send patches to <config-patches@gnu.org>.
+#
+# Configuration subroutine to validate and canonicalize a configuration type.
+# Supply the specified configuration type as an argument.
+# If it is invalid, we print an error message on stderr and exit with code 1.
+# Otherwise, we print the canonical config type on stdout and succeed.
+
+# You can get the latest version of this script from:
+# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
+
+# This file is supposed to be the same for all GNU packages
+# and recognize all the CPU types, system types and aliases
+# that are meaningful with *any* GNU software.
+# Each package is responsible for reporting which valid configurations
+# it does not support.  The user should be able to distinguish
+# a failure to support a valid configuration from a meaningless
+# configuration.
+
+# The goal of this file is to map all the various variations of a given
+# machine specification into a single specification in the form:
+#	CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
+# or in some cases, the newer four-part form:
+#	CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
+# It is wrong to echo any other type of specification.
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION] CPU-MFR-OPSYS
+       $0 [OPTION] ALIAS
+
+Canonicalize a configuration name.
+
+Operation modes:
+  -h, --help         print this help, then exit
+  -t, --time-stamp   print date of last modification, then exit
+  -v, --version      print version number, then exit
+
+Report bugs and patches to <config-patches@gnu.org>."
+
+version="\
+GNU config.sub ($timestamp)
+
+Copyright 1992-2015 Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions.  There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+  case $1 in
+    --time-stamp | --time* | -t )
+       echo "$timestamp" ; exit ;;
+    --version | -v )
+       echo "$version" ; exit ;;
+    --help | --h* | -h )
+       echo "$usage"; exit ;;
+    -- )     # Stop option processing
+       shift; break ;;
+    - )	# Use stdin as input.
+       break ;;
+    -* )
+       echo "$me: invalid option $1$help"
+       exit 1 ;;
+
+    *local*)
+       # First pass through any local machine types.
+       echo $1
+       exit ;;
+
+    * )
+       break ;;
+  esac
+done
+
+case $# in
+ 0) echo "$me: missing argument$help" >&2
+    exit 1;;
+ 1) ;;
+ *) echo "$me: too many arguments$help" >&2
+    exit 1;;
+esac
+
+# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
+# Here we must recognize all the valid KERNEL-OS combinations.
+maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
+case $maybe_os in
+  nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \
+  linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
+  knetbsd*-gnu* | netbsd*-gnu* | netbsd*-eabi* | \
+  kopensolaris*-gnu* | \
+  storm-chaos* | os2-emx* | rtmk-nova*)
+    os=-$maybe_os
+    basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
+    ;;
+  android-linux)
+    os=-linux-android
+    basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown
+    ;;
+  *)
+    basic_machine=`echo $1 | sed 's/-[^-]*$//'`
+    if [ $basic_machine != $1 ]
+    then os=`echo $1 | sed 's/.*-/-/'`
+    else os=; fi
+    ;;
+esac
+
+### Let's recognize common machines as not being operating systems so
+### that things like config.sub decstation-3100 work.  We also
+### recognize some manufacturers as not being operating systems, so we
+### can provide default operating systems below.
+case $os in
+	-sun*os*)
+		# Prevent following clause from handling this invalid input.
+		;;
+	-dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
+	-att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
+	-unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
+	-convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
+	-c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
+	-harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
+	-apple | -axis | -knuth | -cray | -microblaze*)
+		os=
+		basic_machine=$1
+		;;
+	-bluegene*)
+		os=-cnk
+		;;
+	-sim | -cisco | -oki | -wec | -winbond)
+		os=
+		basic_machine=$1
+		;;
+	-scout)
+		;;
+	-wrs)
+		os=-vxworks
+		basic_machine=$1
+		;;
+	-chorusos*)
+		os=-chorusos
+		basic_machine=$1
+		;;
+	-chorusrdb)
+		os=-chorusrdb
+		basic_machine=$1
+		;;
+	-hiux*)
+		os=-hiuxwe2
+		;;
+	-sco6)
+		os=-sco5v6
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco5)
+		os=-sco3.2v5
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco4)
+		os=-sco3.2v4
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco3.2.[4-9]*)
+		os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco3.2v[4-9]*)
+		# Don't forget version if it is 3.2v4 or newer.
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco5v6*)
+		# Don't forget version if it is 3.2v4 or newer.
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco*)
+		os=-sco3.2v2
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-udk*)
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-isc)
+		os=-isc2.2
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-clix*)
+		basic_machine=clipper-intergraph
+		;;
+	-isc*)
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-lynx*178)
+		os=-lynxos178
+		;;
+	-lynx*5)
+		os=-lynxos5
+		;;
+	-lynx*)
+		os=-lynxos
+		;;
+	-ptx*)
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
+		;;
+	-windowsnt*)
+		os=`echo $os | sed -e 's/windowsnt/winnt/'`
+		;;
+	-psos*)
+		os=-psos
+		;;
+	-mint | -mint[0-9]*)
+		basic_machine=m68k-atari
+		os=-mint
+		;;
+esac
+
+# Decode aliases for certain CPU-COMPANY combinations.
+case $basic_machine in
+	# Recognize the basic CPU types without company name.
+	# Some are omitted here because they have special meanings below.
+	1750a | 580 \
+	| a29k \
+	| aarch64 | aarch64_be \
+	| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
+	| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
+	| am33_2.0 \
+	| arc | arceb \
+	| arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \
+	| avr | avr32 \
+	| ba \
+	| be32 | be64 \
+	| bfin \
+	| c4x | c8051 | clipper \
+	| d10v | d30v | dlx | dsp16xx \
+	| e2k | epiphany \
+	| fido | fr30 | frv | ft32 \
+	| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
+	| hexagon \
+	| i370 | i860 | i960 | ia64 \
+	| ip2k | iq2000 \
+	| k1om \
+	| le32 | le64 \
+	| lm32 \
+	| m32c | m32r | m32rle | m68000 | m68k | m88k \
+	| maxq | mb | microblaze | microblazeel | mcore | mep | metag \
+	| mips | mipsbe | mipseb | mipsel | mipsle \
+	| mips16 \
+	| mips64 | mips64el \
+	| mips64octeon | mips64octeonel \
+	| mips64orion | mips64orionel \
+	| mips64r5900 | mips64r5900el \
+	| mips64vr | mips64vrel \
+	| mips64vr4100 | mips64vr4100el \
+	| mips64vr4300 | mips64vr4300el \
+	| mips64vr5000 | mips64vr5000el \
+	| mips64vr5900 | mips64vr5900el \
+	| mipsisa32 | mipsisa32el \
+	| mipsisa32r2 | mipsisa32r2el \
+	| mipsisa32r6 | mipsisa32r6el \
+	| mipsisa64 | mipsisa64el \
+	| mipsisa64r2 | mipsisa64r2el \
+	| mipsisa64r6 | mipsisa64r6el \
+	| mipsisa64sb1 | mipsisa64sb1el \
+	| mipsisa64sr71k | mipsisa64sr71kel \
+	| mipsr5900 | mipsr5900el \
+	| mipstx39 | mipstx39el \
+	| mn10200 | mn10300 \
+	| moxie \
+	| mt \
+	| msp430 \
+	| nds32 | nds32le | nds32be \
+	| nios | nios2 | nios2eb | nios2el \
+	| ns16k | ns32k \
+	| open8 | or1k | or1knd | or32 \
+	| pdp10 | pdp11 | pj | pjl \
+	| powerpc | powerpc64 | powerpc64le | powerpcle \
+	| pyramid \
+	| riscv32 | riscv64 \
+	| rl78 | rx \
+	| score \
+	| sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[234]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
+	| sh64 | sh64le \
+	| sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
+	| sparcv8 | sparcv9 | sparcv9b | sparcv9v \
+	| spu \
+	| tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \
+	| ubicom32 \
+	| v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \
+	| visium \
+	| we32k \
+	| x86 | xc16x | xstormy16 | xtensa \
+	| z8k | z80)
+		basic_machine=$basic_machine-unknown
+		;;
+	c54x)
+		basic_machine=tic54x-unknown
+		;;
+	c55x)
+		basic_machine=tic55x-unknown
+		;;
+	c6x)
+		basic_machine=tic6x-unknown
+		;;
+	leon|leon[3-9])
+		basic_machine=sparc-$basic_machine
+		;;
+	m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip)
+		basic_machine=$basic_machine-unknown
+		os=-none
+		;;
+	m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
+		;;
+	ms1)
+		basic_machine=mt-unknown
+		;;
+
+	strongarm | thumb | xscale)
+		basic_machine=arm-unknown
+		;;
+	xgate)
+		basic_machine=$basic_machine-unknown
+		os=-none
+		;;
+	xscaleeb)
+		basic_machine=armeb-unknown
+		;;
+
+	xscaleel)
+		basic_machine=armel-unknown
+		;;
+
+	# We use `pc' rather than `unknown'
+	# because (1) that's what they normally are, and
+	# (2) the word "unknown" tends to confuse beginning users.
+	i*86 | x86_64)
+	  basic_machine=$basic_machine-pc
+	  ;;
+	# Object if more than one company name word.
+	*-*-*)
+		echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+		exit 1
+		;;
+	# Recognize the basic CPU types with company name.
+	580-* \
+	| a29k-* \
+	| aarch64-* | aarch64_be-* \
+	| alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
+	| alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
+	| alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \
+	| arm-*  | armbe-* | armle-* | armeb-* | armv*-* \
+	| avr-* | avr32-* \
+	| ba-* \
+	| be32-* | be64-* \
+	| bfin-* | bs2000-* \
+	| c[123]* | c30-* | [cjt]90-* | c4x-* \
+	| c8051-* | clipper-* | craynv-* | cydra-* \
+	| d10v-* | d30v-* | dlx-* \
+	| e2k-* | elxsi-* \
+	| f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
+	| h8300-* | h8500-* \
+	| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
+	| hexagon-* \
+	| i*86-* | i860-* | i960-* | ia64-* \
+	| ip2k-* | iq2000-* \
+	| k1om-* \
+	| le32-* | le64-* \
+	| lm32-* \
+	| m32c-* | m32r-* | m32rle-* \
+	| m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
+	| m88110-* | m88k-* | maxq-* | mcore-* | metag-* \
+	| microblaze-* | microblazeel-* \
+	| mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
+	| mips16-* \
+	| mips64-* | mips64el-* \
+	| mips64octeon-* | mips64octeonel-* \
+	| mips64orion-* | mips64orionel-* \
+	| mips64r5900-* | mips64r5900el-* \
+	| mips64vr-* | mips64vrel-* \
+	| mips64vr4100-* | mips64vr4100el-* \
+	| mips64vr4300-* | mips64vr4300el-* \
+	| mips64vr5000-* | mips64vr5000el-* \
+	| mips64vr5900-* | mips64vr5900el-* \
+	| mipsisa32-* | mipsisa32el-* \
+	| mipsisa32r2-* | mipsisa32r2el-* \
+	| mipsisa32r6-* | mipsisa32r6el-* \
+	| mipsisa64-* | mipsisa64el-* \
+	| mipsisa64r2-* | mipsisa64r2el-* \
+	| mipsisa64r6-* | mipsisa64r6el-* \
+	| mipsisa64sb1-* | mipsisa64sb1el-* \
+	| mipsisa64sr71k-* | mipsisa64sr71kel-* \
+	| mipsr5900-* | mipsr5900el-* \
+	| mipstx39-* | mipstx39el-* \
+	| mmix-* \
+	| mt-* \
+	| msp430-* \
+	| nds32-* | nds32le-* | nds32be-* \
+	| nios-* | nios2-* | nios2eb-* | nios2el-* \
+	| none-* | np1-* | ns16k-* | ns32k-* \
+	| open8-* \
+	| or1k*-* \
+	| orion-* \
+	| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
+	| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \
+	| pyramid-* \
+	| riscv32-* | riscv64-* \
+	| rl78-* | romp-* | rs6000-* | rx-* \
+	| sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
+	| shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
+	| sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
+	| sparclite-* \
+	| sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx*-* \
+	| tahoe-* \
+	| tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
+	| tile*-* \
+	| tron-* \
+	| ubicom32-* \
+	| v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \
+	| vax-* \
+	| visium-* \
+	| we32k-* \
+	| x86-* | x86_64-* | xc16x-* | xps100-* \
+	| xstormy16-* | xtensa*-* \
+	| ymp-* \
+	| z8k-* | z80-*)
+		;;
+	# Recognize the basic CPU types without company name, with glob match.
+	xtensa*)
+		basic_machine=$basic_machine-unknown
+		;;
+	# Recognize the various machine names and aliases which stand
+	# for a CPU type and a company and sometimes even an OS.
+	386bsd)
+		basic_machine=i386-unknown
+		os=-bsd
+		;;
+	3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
+		basic_machine=m68000-att
+		;;
+	3b*)
+		basic_machine=we32k-att
+		;;
+	a29khif)
+		basic_machine=a29k-amd
+		os=-udi
+		;;
+	abacus)
+		basic_machine=abacus-unknown
+		;;
+	adobe68k)
+		basic_machine=m68010-adobe
+		os=-scout
+		;;
+	alliant | fx80)
+		basic_machine=fx80-alliant
+		;;
+	altos | altos3068)
+		basic_machine=m68k-altos
+		;;
+	am29k)
+		basic_machine=a29k-none
+		os=-bsd
+		;;
+	amd64)
+		basic_machine=x86_64-pc
+		;;
+	amd64-*)
+		basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	amdahl)
+		basic_machine=580-amdahl
+		os=-sysv
+		;;
+	amiga | amiga-*)
+		basic_machine=m68k-unknown
+		;;
+	amigaos | amigados)
+		basic_machine=m68k-unknown
+		os=-amigaos
+		;;
+	amigaunix | amix)
+		basic_machine=m68k-unknown
+		os=-sysv4
+		;;
+	apollo68)
+		basic_machine=m68k-apollo
+		os=-sysv
+		;;
+	apollo68bsd)
+		basic_machine=m68k-apollo
+		os=-bsd
+		;;
+	aros)
+		basic_machine=i386-pc
+		os=-aros
+		;;
+        asmjs)
+		basic_machine=asmjs-unknown
+		;;
+	aux)
+		basic_machine=m68k-apple
+		os=-aux
+		;;
+	balance)
+		basic_machine=ns32k-sequent
+		os=-dynix
+		;;
+	blackfin)
+		basic_machine=bfin-unknown
+		os=-linux
+		;;
+	blackfin-*)
+		basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'`
+		os=-linux
+		;;
+	bluegene*)
+		basic_machine=powerpc-ibm
+		os=-cnk
+		;;
+	c54x-*)
+		basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	c55x-*)
+		basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	c6x-*)
+		basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	c90)
+		basic_machine=c90-cray
+		os=-unicos
+		;;
+	cegcc)
+		basic_machine=arm-unknown
+		os=-cegcc
+		;;
+	convex-c1)
+		basic_machine=c1-convex
+		os=-bsd
+		;;
+	convex-c2)
+		basic_machine=c2-convex
+		os=-bsd
+		;;
+	convex-c32)
+		basic_machine=c32-convex
+		os=-bsd
+		;;
+	convex-c34)
+		basic_machine=c34-convex
+		os=-bsd
+		;;
+	convex-c38)
+		basic_machine=c38-convex
+		os=-bsd
+		;;
+	cray | j90)
+		basic_machine=j90-cray
+		os=-unicos
+		;;
+	craynv)
+		basic_machine=craynv-cray
+		os=-unicosmp
+		;;
+	cr16 | cr16-*)
+		basic_machine=cr16-unknown
+		os=-elf
+		;;
+	crds | unos)
+		basic_machine=m68k-crds
+		;;
+	crisv32 | crisv32-* | etraxfs*)
+		basic_machine=crisv32-axis
+		;;
+	cris | cris-* | etrax*)
+		basic_machine=cris-axis
+		;;
+	crx)
+		basic_machine=crx-unknown
+		os=-elf
+		;;
+	da30 | da30-*)
+		basic_machine=m68k-da30
+		;;
+	decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
+		basic_machine=mips-dec
+		;;
+	decsystem10* | dec10*)
+		basic_machine=pdp10-dec
+		os=-tops10
+		;;
+	decsystem20* | dec20*)
+		basic_machine=pdp10-dec
+		os=-tops20
+		;;
+	delta | 3300 | motorola-3300 | motorola-delta \
+	      | 3300-motorola | delta-motorola)
+		basic_machine=m68k-motorola
+		;;
+	delta88)
+		basic_machine=m88k-motorola
+		os=-sysv3
+		;;
+	dicos)
+		basic_machine=i686-pc
+		os=-dicos
+		;;
+	djgpp)
+		basic_machine=i586-pc
+		os=-msdosdjgpp
+		;;
+	dpx20 | dpx20-*)
+		basic_machine=rs6000-bull
+		os=-bosx
+		;;
+	dpx2* | dpx2*-bull)
+		basic_machine=m68k-bull
+		os=-sysv3
+		;;
+	ebmon29k)
+		basic_machine=a29k-amd
+		os=-ebmon
+		;;
+	elxsi)
+		basic_machine=elxsi-elxsi
+		os=-bsd
+		;;
+	encore | umax | mmax)
+		basic_machine=ns32k-encore
+		;;
+	es1800 | OSE68k | ose68k | ose | OSE)
+		basic_machine=m68k-ericsson
+		os=-ose
+		;;
+	fx2800)
+		basic_machine=i860-alliant
+		;;
+	genix)
+		basic_machine=ns32k-ns
+		;;
+	gmicro)
+		basic_machine=tron-gmicro
+		os=-sysv
+		;;
+	go32)
+		basic_machine=i386-pc
+		os=-go32
+		;;
+	h3050r* | hiux*)
+		basic_machine=hppa1.1-hitachi
+		os=-hiuxwe2
+		;;
+	h8300hms)
+		basic_machine=h8300-hitachi
+		os=-hms
+		;;
+	h8300xray)
+		basic_machine=h8300-hitachi
+		os=-xray
+		;;
+	h8500hms)
+		basic_machine=h8500-hitachi
+		os=-hms
+		;;
+	harris)
+		basic_machine=m88k-harris
+		os=-sysv3
+		;;
+	hp300-*)
+		basic_machine=m68k-hp
+		;;
+	hp300bsd)
+		basic_machine=m68k-hp
+		os=-bsd
+		;;
+	hp300hpux)
+		basic_machine=m68k-hp
+		os=-hpux
+		;;
+	hp3k9[0-9][0-9] | hp9[0-9][0-9])
+		basic_machine=hppa1.0-hp
+		;;
+	hp9k2[0-9][0-9] | hp9k31[0-9])
+		basic_machine=m68000-hp
+		;;
+	hp9k3[2-9][0-9])
+		basic_machine=m68k-hp
+		;;
+	hp9k6[0-9][0-9] | hp6[0-9][0-9])
+		basic_machine=hppa1.0-hp
+		;;
+	hp9k7[0-79][0-9] | hp7[0-79][0-9])
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k78[0-9] | hp78[0-9])
+		# FIXME: really hppa2.0-hp
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)
+		# FIXME: really hppa2.0-hp
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k8[0-9][13679] | hp8[0-9][13679])
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k8[0-9][0-9] | hp8[0-9][0-9])
+		basic_machine=hppa1.0-hp
+		;;
+	hppa-next)
+		os=-nextstep3
+		;;
+	hppaosf)
+		basic_machine=hppa1.1-hp
+		os=-osf
+		;;
+	hppro)
+		basic_machine=hppa1.1-hp
+		os=-proelf
+		;;
+	i370-ibm* | ibm*)
+		basic_machine=i370-ibm
+		;;
+	i*86v32)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-sysv32
+		;;
+	i*86v4*)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-sysv4
+		;;
+	i*86v)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-sysv
+		;;
+	i*86sol2)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-solaris2
+		;;
+	i386mach)
+		basic_machine=i386-mach
+		os=-mach
+		;;
+	i386-vsta | vsta)
+		basic_machine=i386-unknown
+		os=-vsta
+		;;
+	iris | iris4d)
+		basic_machine=mips-sgi
+		case $os in
+		    -irix*)
+			;;
+		    *)
+			os=-irix4
+			;;
+		esac
+		;;
+	isi68 | isi)
+		basic_machine=m68k-isi
+		os=-sysv
+		;;
+	leon-*|leon[3-9]-*)
+		basic_machine=sparc-`echo $basic_machine | sed 's/-.*//'`
+		;;
+	m68knommu)
+		basic_machine=m68k-unknown
+		os=-linux
+		;;
+	m68knommu-*)
+		basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'`
+		os=-linux
+		;;
+	m88k-omron*)
+		basic_machine=m88k-omron
+		;;
+	magnum | m3230)
+		basic_machine=mips-mips
+		os=-sysv
+		;;
+	merlin)
+		basic_machine=ns32k-utek
+		os=-sysv
+		;;
+	microblaze*)
+		basic_machine=microblaze-xilinx
+		;;
+	mingw64)
+		basic_machine=x86_64-pc
+		os=-mingw64
+		;;
+	mingw32)
+		basic_machine=i686-pc
+		os=-mingw32
+		;;
+	mingw32ce)
+		basic_machine=arm-unknown
+		os=-mingw32ce
+		;;
+	miniframe)
+		basic_machine=m68000-convergent
+		;;
+	*mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*)
+		basic_machine=m68k-atari
+		os=-mint
+		;;
+	mips3*-*)
+		basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
+		;;
+	mips3*)
+		basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
+		;;
+	monitor)
+		basic_machine=m68k-rom68k
+		os=-coff
+		;;
+	morphos)
+		basic_machine=powerpc-unknown
+		os=-morphos
+		;;
+	moxiebox)
+		basic_machine=moxie-unknown
+		os=-moxiebox
+		;;
+	msdos)
+		basic_machine=i386-pc
+		os=-msdos
+		;;
+	ms1-*)
+		basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`
+		;;
+	msys)
+		basic_machine=i686-pc
+		os=-msys
+		;;
+	mvs)
+		basic_machine=i370-ibm
+		os=-mvs
+		;;
+	nacl)
+		basic_machine=le32-unknown
+		os=-nacl
+		;;
+	ncr3000)
+		basic_machine=i486-ncr
+		os=-sysv4
+		;;
+	netbsd386)
+		basic_machine=i386-unknown
+		os=-netbsd
+		;;
+	netwinder)
+		basic_machine=armv4l-rebel
+		os=-linux
+		;;
+	news | news700 | news800 | news900)
+		basic_machine=m68k-sony
+		os=-newsos
+		;;
+	news1000)
+		basic_machine=m68030-sony
+		os=-newsos
+		;;
+	news-3600 | risc-news)
+		basic_machine=mips-sony
+		os=-newsos
+		;;
+	necv70)
+		basic_machine=v70-nec
+		os=-sysv
+		;;
+	next | m*-next )
+		basic_machine=m68k-next
+		case $os in
+		    -nextstep* )
+			;;
+		    -ns2*)
+		      os=-nextstep2
+			;;
+		    *)
+		      os=-nextstep3
+			;;
+		esac
+		;;
+	nh3000)
+		basic_machine=m68k-harris
+		os=-cxux
+		;;
+	nh[45]000)
+		basic_machine=m88k-harris
+		os=-cxux
+		;;
+	nindy960)
+		basic_machine=i960-intel
+		os=-nindy
+		;;
+	mon960)
+		basic_machine=i960-intel
+		os=-mon960
+		;;
+	nonstopux)
+		basic_machine=mips-compaq
+		os=-nonstopux
+		;;
+	np1)
+		basic_machine=np1-gould
+		;;
+	neo-tandem)
+		basic_machine=neo-tandem
+		;;
+	nse-tandem)
+		basic_machine=nse-tandem
+		;;
+	nsr-tandem)
+		basic_machine=nsr-tandem
+		;;
+	op50n-* | op60c-*)
+		basic_machine=hppa1.1-oki
+		os=-proelf
+		;;
+	openrisc | openrisc-*)
+		basic_machine=or32-unknown
+		;;
+	os400)
+		basic_machine=powerpc-ibm
+		os=-os400
+		;;
+	OSE68000 | ose68000)
+		basic_machine=m68000-ericsson
+		os=-ose
+		;;
+	os68k)
+		basic_machine=m68k-none
+		os=-os68k
+		;;
+	pa-hitachi)
+		basic_machine=hppa1.1-hitachi
+		os=-hiuxwe2
+		;;
+	paragon)
+		basic_machine=i860-intel
+		os=-osf
+		;;
+	parisc)
+		basic_machine=hppa-unknown
+		os=-linux
+		;;
+	parisc-*)
+		basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'`
+		os=-linux
+		;;
+	pbd)
+		basic_machine=sparc-tti
+		;;
+	pbb)
+		basic_machine=m68k-tti
+		;;
+	pc532 | pc532-*)
+		basic_machine=ns32k-pc532
+		;;
+	pc98)
+		basic_machine=i386-pc
+		;;
+	pc98-*)
+		basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentium | p5 | k5 | k6 | nexgen | viac3)
+		basic_machine=i586-pc
+		;;
+	pentiumpro | p6 | 6x86 | athlon | athlon_*)
+		basic_machine=i686-pc
+		;;
+	pentiumii | pentium2 | pentiumiii | pentium3)
+		basic_machine=i686-pc
+		;;
+	pentium4)
+		basic_machine=i786-pc
+		;;
+	pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
+		basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentiumpro-* | p6-* | 6x86-* | athlon-*)
+		basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
+		basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentium4-*)
+		basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pn)
+		basic_machine=pn-gould
+		;;
+	power)	basic_machine=power-ibm
+		;;
+	ppc | ppcbe)	basic_machine=powerpc-unknown
+		;;
+	ppc-* | ppcbe-*)
+		basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ppcle | powerpclittle | ppc-le | powerpc-little)
+		basic_machine=powerpcle-unknown
+		;;
+	ppcle-* | powerpclittle-*)
+		basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ppc64)	basic_machine=powerpc64-unknown
+		;;
+	ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ppc64le | powerpc64little | ppc64-le | powerpc64-little)
+		basic_machine=powerpc64le-unknown
+		;;
+	ppc64le-* | powerpc64little-*)
+		basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ps2)
+		basic_machine=i386-ibm
+		;;
+	pw32)
+		basic_machine=i586-unknown
+		os=-pw32
+		;;
+	rdos | rdos64)
+		basic_machine=x86_64-pc
+		os=-rdos
+		;;
+	rdos32)
+		basic_machine=i386-pc
+		os=-rdos
+		;;
+	rom68k)
+		basic_machine=m68k-rom68k
+		os=-coff
+		;;
+	rm[46]00)
+		basic_machine=mips-siemens
+		;;
+	rtpc | rtpc-*)
+		basic_machine=romp-ibm
+		;;
+	s390 | s390-*)
+		basic_machine=s390-ibm
+		;;
+	s390x | s390x-*)
+		basic_machine=s390x-ibm
+		;;
+	sa29200)
+		basic_machine=a29k-amd
+		os=-udi
+		;;
+	sb1)
+		basic_machine=mipsisa64sb1-unknown
+		;;
+	sb1el)
+		basic_machine=mipsisa64sb1el-unknown
+		;;
+	sde)
+		basic_machine=mipsisa32-sde
+		os=-elf
+		;;
+	sei)
+		basic_machine=mips-sei
+		os=-seiux
+		;;
+	sequent)
+		basic_machine=i386-sequent
+		;;
+	sh)
+		basic_machine=sh-hitachi
+		os=-hms
+		;;
+	sh5el)
+		basic_machine=sh5le-unknown
+		;;
+	sh64)
+		basic_machine=sh64-unknown
+		;;
+	sparclite-wrs | simso-wrs)
+		basic_machine=sparclite-wrs
+		os=-vxworks
+		;;
+	sps7)
+		basic_machine=m68k-bull
+		os=-sysv2
+		;;
+	spur)
+		basic_machine=spur-unknown
+		;;
+	st2000)
+		basic_machine=m68k-tandem
+		;;
+	stratus)
+		basic_machine=i860-stratus
+		os=-sysv4
+		;;
+	strongarm-* | thumb-*)
+		basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	sun2)
+		basic_machine=m68000-sun
+		;;
+	sun2os3)
+		basic_machine=m68000-sun
+		os=-sunos3
+		;;
+	sun2os4)
+		basic_machine=m68000-sun
+		os=-sunos4
+		;;
+	sun3os3)
+		basic_machine=m68k-sun
+		os=-sunos3
+		;;
+	sun3os4)
+		basic_machine=m68k-sun
+		os=-sunos4
+		;;
+	sun4os3)
+		basic_machine=sparc-sun
+		os=-sunos3
+		;;
+	sun4os4)
+		basic_machine=sparc-sun
+		os=-sunos4
+		;;
+	sun4sol2)
+		basic_machine=sparc-sun
+		os=-solaris2
+		;;
+	sun3 | sun3-*)
+		basic_machine=m68k-sun
+		;;
+	sun4)
+		basic_machine=sparc-sun
+		;;
+	sun386 | sun386i | roadrunner)
+		basic_machine=i386-sun
+		;;
+	sv1)
+		basic_machine=sv1-cray
+		os=-unicos
+		;;
+	symmetry)
+		basic_machine=i386-sequent
+		os=-dynix
+		;;
+	t3e)
+		basic_machine=alphaev5-cray
+		os=-unicos
+		;;
+	t90)
+		basic_machine=t90-cray
+		os=-unicos
+		;;
+	tile*)
+		basic_machine=$basic_machine-unknown
+		os=-linux-gnu
+		;;
+	tx39)
+		basic_machine=mipstx39-unknown
+		;;
+	tx39el)
+		basic_machine=mipstx39el-unknown
+		;;
+	toad1)
+		basic_machine=pdp10-xkl
+		os=-tops20
+		;;
+	tower | tower-32)
+		basic_machine=m68k-ncr
+		;;
+	tpf)
+		basic_machine=s390x-ibm
+		os=-tpf
+		;;
+	udi29k)
+		basic_machine=a29k-amd
+		os=-udi
+		;;
+	ultra3)
+		basic_machine=a29k-nyu
+		os=-sym1
+		;;
+	v810 | necv810)
+		basic_machine=v810-nec
+		os=-none
+		;;
+	vaxv)
+		basic_machine=vax-dec
+		os=-sysv
+		;;
+	vms)
+		basic_machine=vax-dec
+		os=-vms
+		;;
+	vpp*|vx|vx-*)
+		basic_machine=f301-fujitsu
+		;;
+	vxworks960)
+		basic_machine=i960-wrs
+		os=-vxworks
+		;;
+	vxworks68)
+		basic_machine=m68k-wrs
+		os=-vxworks
+		;;
+	vxworks29k)
+		basic_machine=a29k-wrs
+		os=-vxworks
+		;;
+	w65*)
+		basic_machine=w65-wdc
+		os=-none
+		;;
+	w89k-*)
+		basic_machine=hppa1.1-winbond
+		os=-proelf
+		;;
+	xbox)
+		basic_machine=i686-pc
+		os=-mingw32
+		;;
+	xps | xps100)
+		basic_machine=xps100-honeywell
+		;;
+	xscale-* | xscalee[bl]-*)
+		basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'`
+		;;
+	ymp)
+		basic_machine=ymp-cray
+		os=-unicos
+		;;
+	z8k-*-coff)
+		basic_machine=z8k-unknown
+		os=-sim
+		;;
+	z80-*-coff)
+		basic_machine=z80-unknown
+		os=-sim
+		;;
+	none)
+		basic_machine=none-none
+		os=-none
+		;;
+
+# Here we handle the default manufacturer of certain CPU types.  It is in
+# some cases the only manufacturer, in others, it is the most popular.
+	w89k)
+		basic_machine=hppa1.1-winbond
+		;;
+	op50n)
+		basic_machine=hppa1.1-oki
+		;;
+	op60c)
+		basic_machine=hppa1.1-oki
+		;;
+	romp)
+		basic_machine=romp-ibm
+		;;
+	mmix)
+		basic_machine=mmix-knuth
+		;;
+	rs6000)
+		basic_machine=rs6000-ibm
+		;;
+	vax)
+		basic_machine=vax-dec
+		;;
+	pdp10)
+		# there are many clones, so DEC is not a safe bet
+		basic_machine=pdp10-unknown
+		;;
+	pdp11)
+		basic_machine=pdp11-dec
+		;;
+	we32k)
+		basic_machine=we32k-att
+		;;
+	sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele)
+		basic_machine=sh-unknown
+		;;
+	sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v)
+		basic_machine=sparc-sun
+		;;
+	cydra)
+		basic_machine=cydra-cydrome
+		;;
+	orion)
+		basic_machine=orion-highlevel
+		;;
+	orion105)
+		basic_machine=clipper-highlevel
+		;;
+	mac | mpw | mac-mpw)
+		basic_machine=m68k-apple
+		;;
+	pmac | pmac-mpw)
+		basic_machine=powerpc-apple
+		;;
+	*-unknown)
+		# Make sure to match an already-canonicalized machine name.
+		;;
+	*)
+		echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+		exit 1
+		;;
+esac
+
+# Here we canonicalize certain aliases for manufacturers.
+case $basic_machine in
+	*-digital*)
+		basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
+		;;
+	*-commodore*)
+		basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
+		;;
+	*)
+		;;
+esac
+
+# Decode manufacturer-specific aliases for certain operating systems.
+
+if [ x"$os" != x"" ]
+then
+case $os in
+	# First match some system type aliases
+	# that might get confused with valid system types.
+	# -solaris* is a basic system type, with this one exception.
+	-auroraux)
+		os=-auroraux
+		;;
+	-solaris1 | -solaris1.*)
+		os=`echo $os | sed -e 's|solaris1|sunos4|'`
+		;;
+	-solaris)
+		os=-solaris2
+		;;
+	-svr4*)
+		os=-sysv4
+		;;
+	-unixware*)
+		os=-sysv4.2uw
+		;;
+	-gnu/linux*)
+		os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
+		;;
+	# First accept the basic system types.
+	# The portable systems comes first.
+	# Each alternative MUST END IN A *, to match a version number.
+	# -sysv* is not here because it comes later, after sysvr4.
+	-gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
+	      | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\
+	      | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \
+	      | -sym* | -kopensolaris* | -plan9* \
+	      | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
+	      | -aos* | -aros* | -cloudabi* | -sortix* \
+	      | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
+	      | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
+	      | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
+	      | -bitrig* | -openbsd* | -solidbsd* \
+	      | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
+	      | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
+	      | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
+	      | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
+	      | -chorusos* | -chorusrdb* | -cegcc* \
+	      | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
+	      | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \
+	      | -linux-newlib* | -linux-musl* | -linux-uclibc* \
+	      | -uxpv* | -beos* | -mpeix* | -udk* | -moxiebox* \
+	      | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
+	      | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
+	      | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
+	      | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
+	      | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
+	      | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
+	      | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* | -tirtos*)
+	# Remember, each alternative MUST END IN *, to match a version number.
+		;;
+	-qnx*)
+		case $basic_machine in
+		    x86-* | i*86-*)
+			;;
+		    *)
+			os=-nto$os
+			;;
+		esac
+		;;
+	-nto-qnx*)
+		;;
+	-nto*)
+		os=`echo $os | sed -e 's|nto|nto-qnx|'`
+		;;
+	-sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
+	      | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \
+	      | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
+		;;
+	-mac*)
+		os=`echo $os | sed -e 's|mac|macos|'`
+		;;
+	-linux-dietlibc)
+		os=-linux-dietlibc
+		;;
+	-linux*)
+		os=`echo $os | sed -e 's|linux|linux-gnu|'`
+		;;
+	-sunos5*)
+		os=`echo $os | sed -e 's|sunos5|solaris2|'`
+		;;
+	-sunos6*)
+		os=`echo $os | sed -e 's|sunos6|solaris3|'`
+		;;
+	-opened*)
+		os=-openedition
+		;;
+	-os400*)
+		os=-os400
+		;;
+	-wince*)
+		os=-wince
+		;;
+	-osfrose*)
+		os=-osfrose
+		;;
+	-osf*)
+		os=-osf
+		;;
+	-utek*)
+		os=-bsd
+		;;
+	-dynix*)
+		os=-bsd
+		;;
+	-acis*)
+		os=-aos
+		;;
+	-atheos*)
+		os=-atheos
+		;;
+	-syllable*)
+		os=-syllable
+		;;
+	-386bsd)
+		os=-bsd
+		;;
+	-ctix* | -uts*)
+		os=-sysv
+		;;
+	-nova*)
+		os=-rtmk-nova
+		;;
+	-ns2 )
+		os=-nextstep2
+		;;
+	-nsk*)
+		os=-nsk
+		;;
+	# Preserve the version number of sinix5.
+	-sinix5.*)
+		os=`echo $os | sed -e 's|sinix|sysv|'`
+		;;
+	-sinix*)
+		os=-sysv4
+		;;
+	-tpf*)
+		os=-tpf
+		;;
+	-triton*)
+		os=-sysv3
+		;;
+	-oss*)
+		os=-sysv3
+		;;
+	-svr4)
+		os=-sysv4
+		;;
+	-svr3)
+		os=-sysv3
+		;;
+	-sysvr4)
+		os=-sysv4
+		;;
+	# This must come after -sysvr4.
+	-sysv*)
+		;;
+	-ose*)
+		os=-ose
+		;;
+	-es1800*)
+		os=-ose
+		;;
+	-xenix)
+		os=-xenix
+		;;
+	-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+		os=-mint
+		;;
+	-aros*)
+		os=-aros
+		;;
+	-zvmoe)
+		os=-zvmoe
+		;;
+	-dicos*)
+		os=-dicos
+		;;
+	-nacl*)
+		;;
+	-none)
+		;;
+	*)
+		# Get rid of the `-' at the beginning of $os.
+		os=`echo $os | sed 's/[^-]*-//'`
+		echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
+		exit 1
+		;;
+esac
+else
+
+# Here we handle the default operating systems that come with various machines.
+# The value should be what the vendor currently ships out the door with their
+# machine or put another way, the most popular os provided with the machine.
+
+# Note that if you're going to try to match "-MANUFACTURER" here (say,
+# "-sun"), then you have to tell the case statement up towards the top
+# that MANUFACTURER isn't an operating system.  Otherwise, code above
+# will signal an error saying that MANUFACTURER isn't an operating
+# system, and we'll never get to this point.
+
+case $basic_machine in
+	score-*)
+		os=-elf
+		;;
+	spu-*)
+		os=-elf
+		;;
+	*-acorn)
+		os=-riscix1.2
+		;;
+	arm*-rebel)
+		os=-linux
+		;;
+	arm*-semi)
+		os=-aout
+		;;
+	c4x-* | tic4x-*)
+		os=-coff
+		;;
+	c8051-*)
+		os=-elf
+		;;
+	hexagon-*)
+		os=-elf
+		;;
+	tic54x-*)
+		os=-coff
+		;;
+	tic55x-*)
+		os=-coff
+		;;
+	tic6x-*)
+		os=-coff
+		;;
+	# This must come before the *-dec entry.
+	pdp10-*)
+		os=-tops20
+		;;
+	pdp11-*)
+		os=-none
+		;;
+	*-dec | vax-*)
+		os=-ultrix4.2
+		;;
+	m68*-apollo)
+		os=-domain
+		;;
+	i386-sun)
+		os=-sunos4.0.2
+		;;
+	m68000-sun)
+		os=-sunos3
+		;;
+	m68*-cisco)
+		os=-aout
+		;;
+	mep-*)
+		os=-elf
+		;;
+	mips*-cisco)
+		os=-elf
+		;;
+	mips*-*)
+		os=-elf
+		;;
+	or32-*)
+		os=-coff
+		;;
+	*-tti)	# must be before sparc entry or we get the wrong os.
+		os=-sysv3
+		;;
+	sparc-* | *-sun)
+		os=-sunos4.1.1
+		;;
+	*-be)
+		os=-beos
+		;;
+	*-haiku)
+		os=-haiku
+		;;
+	*-ibm)
+		os=-aix
+		;;
+	*-knuth)
+		os=-mmixware
+		;;
+	*-wec)
+		os=-proelf
+		;;
+	*-winbond)
+		os=-proelf
+		;;
+	*-oki)
+		os=-proelf
+		;;
+	*-hp)
+		os=-hpux
+		;;
+	*-hitachi)
+		os=-hiux
+		;;
+	i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
+		os=-sysv
+		;;
+	*-cbm)
+		os=-amigaos
+		;;
+	*-dg)
+		os=-dgux
+		;;
+	*-dolphin)
+		os=-sysv3
+		;;
+	m68k-ccur)
+		os=-rtu
+		;;
+	m88k-omron*)
+		os=-luna
+		;;
+	*-next )
+		os=-nextstep
+		;;
+	*-sequent)
+		os=-ptx
+		;;
+	*-crds)
+		os=-unos
+		;;
+	*-ns)
+		os=-genix
+		;;
+	i370-*)
+		os=-mvs
+		;;
+	*-next)
+		os=-nextstep3
+		;;
+	*-gould)
+		os=-sysv
+		;;
+	*-highlevel)
+		os=-bsd
+		;;
+	*-encore)
+		os=-bsd
+		;;
+	*-sgi)
+		os=-irix
+		;;
+	*-siemens)
+		os=-sysv4
+		;;
+	*-masscomp)
+		os=-rtu
+		;;
+	f30[01]-fujitsu | f700-fujitsu)
+		os=-uxpv
+		;;
+	*-rom68k)
+		os=-coff
+		;;
+	*-*bug)
+		os=-coff
+		;;
+	*-apple)
+		os=-macos
+		;;
+	*-atari*)
+		os=-mint
+		;;
+	*)
+		os=-none
+		;;
+esac
+fi
+
+# Here we handle the case where we know the os, and the CPU type, but not the
+# manufacturer.  We pick the logical manufacturer.
+vendor=unknown
+case $basic_machine in
+	*-unknown)
+		case $os in
+			-riscix*)
+				vendor=acorn
+				;;
+			-sunos*)
+				vendor=sun
+				;;
+			-cnk*|-aix*)
+				vendor=ibm
+				;;
+			-beos*)
+				vendor=be
+				;;
+			-hpux*)
+				vendor=hp
+				;;
+			-mpeix*)
+				vendor=hp
+				;;
+			-hiux*)
+				vendor=hitachi
+				;;
+			-unos*)
+				vendor=crds
+				;;
+			-dgux*)
+				vendor=dg
+				;;
+			-luna*)
+				vendor=omron
+				;;
+			-genix*)
+				vendor=ns
+				;;
+			-mvs* | -opened*)
+				vendor=ibm
+				;;
+			-os400*)
+				vendor=ibm
+				;;
+			-ptx*)
+				vendor=sequent
+				;;
+			-tpf*)
+				vendor=ibm
+				;;
+			-vxsim* | -vxworks* | -windiss*)
+				vendor=wrs
+				;;
+			-aux*)
+				vendor=apple
+				;;
+			-hms*)
+				vendor=hitachi
+				;;
+			-mpw* | -macos*)
+				vendor=apple
+				;;
+			-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+				vendor=atari
+				;;
+			-vos*)
+				vendor=stratus
+				;;
+		esac
+		basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
+		;;
+esac
+
+echo $basic_machine$os
+exit
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/config/deb.am
@@ -0,0 +1,51 @@
+###############################################################################
+# Copyright (C) 2010 Lawrence Livermore National Security, LLC.
+# Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+###############################################################################
+# Build targets for DEB packages.
+#
+# Long term native distro specific Debian style packaging should be added.
+# In the short term RPM packages are built and converted to DEB packages
+# using alien.  If someone familiar with Debian style packaging were to
+# update the build system to correctly build Debian style packages I would
+# happily take it.  Until then we will have to make due with alien.
+#
+###############################################################################
+
+deb-local:
+	@(if test "${HAVE_DPKGBUILD}" = "no"; then \
+		echo -e "\n" \
+	"*** Required util ${DPKGBUILD} missing.  Please install the\n" \
+        "*** package for your distribution which provides ${DPKGBUILD},\n" \
+	"*** re-run configure, and try again.\n"; \
+                exit 1; \
+	fi; \
+	if test "${HAVE_ALIEN}" = "no"; then \
+		echo -e "\n" \
+	"*** Required util ${ALIEN} missing.  Please install the\n" \
+        "*** package for your distribution which provides ${ALIEN},\n" \
+	"*** re-run configure, and try again.\n"; \
+                exit 1; \
+	fi)
+
+deb-kmod: deb-local rpm-kmod
+if CONFIG_KERNEL
+	name=${PACKAGE}; \
+	version=${VERSION}-${RELEASE}; \
+	arch=`$(RPM) -qp $${name}-kmod-$${version}.src.rpm --qf %{arch} | tail -1`; \
+	pkg1=kmod-$${name}*$${version}.$${arch}.rpm; \
+	fakeroot $(ALIEN) --bump=0 --scripts --to-deb $$pkg1; \
+	$(RM) $$pkg1
+endif
+
+deb-utils: deb-local rpm-utils
+if CONFIG_USER
+	name=${PACKAGE}; \
+	version=${VERSION}-${RELEASE}; \
+	arch=`$(RPM) -qp $${name}-$${version}.src.rpm --qf %{arch} | tail -1`; \
+	pkg1=$${name}-$${version}.$${arch}.rpm; \
+	fakeroot $(ALIEN) --bump=0 --scripts --to-deb $$pkg1; \
+	$(RM) $$pkg1
+endif
+
+deb: deb-kmod deb-utils
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/config/depcomp
@@ -0,0 +1,791 @@
+#! /bin/sh
+# depcomp - compile a program generating dependencies as side-effects
+
+scriptversion=2013-05-30.07; # UTC
+
+# Copyright (C) 1999-2014 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Originally written by Alexandre Oliva <oliva@dcc.unicamp.br>.
+
+case $1 in
+  '')
+    echo "$0: No command.  Try '$0 --help' for more information." 1>&2
+    exit 1;
+    ;;
+  -h | --h*)
+    cat <<\EOF
+Usage: depcomp [--help] [--version] PROGRAM [ARGS]
+
+Run PROGRAMS ARGS to compile a file, generating dependencies
+as side-effects.
+
+Environment variables:
+  depmode     Dependency tracking mode.
+  source      Source file read by 'PROGRAMS ARGS'.
+  object      Object file output by 'PROGRAMS ARGS'.
+  DEPDIR      directory where to store dependencies.
+  depfile     Dependency file to output.
+  tmpdepfile  Temporary file to use when outputting dependencies.
+  libtool     Whether libtool is used (yes/no).
+
+Report bugs to <bug-automake@gnu.org>.
+EOF
+    exit $?
+    ;;
+  -v | --v*)
+    echo "depcomp $scriptversion"
+    exit $?
+    ;;
+esac
+
+# Get the directory component of the given path, and save it in the
+# global variables '$dir'.  Note that this directory component will
+# be either empty or ending with a '/' character.  This is deliberate.
+set_dir_from ()
+{
+  case $1 in
+    */*) dir=`echo "$1" | sed -e 's|/[^/]*$|/|'`;;
+      *) dir=;;
+  esac
+}
+
+# Get the suffix-stripped basename of the given path, and save it the
+# global variable '$base'.
+set_base_from ()
+{
+  base=`echo "$1" | sed -e 's|^.*/||' -e 's/\.[^.]*$//'`
+}
+
+# If no dependency file was actually created by the compiler invocation,
+# we still have to create a dummy depfile, to avoid errors with the
+# Makefile "include basename.Plo" scheme.
+make_dummy_depfile ()
+{
+  echo "#dummy" > "$depfile"
+}
+
+# Factor out some common post-processing of the generated depfile.
+# Requires the auxiliary global variable '$tmpdepfile' to be set.
+aix_post_process_depfile ()
+{
+  # If the compiler actually managed to produce a dependency file,
+  # post-process it.
+  if test -f "$tmpdepfile"; then
+    # Each line is of the form 'foo.o: dependency.h'.
+    # Do two passes, one to just change these to
+    #   $object: dependency.h
+    # and one to simply output
+    #   dependency.h:
+    # which is needed to avoid the deleted-header problem.
+    { sed -e "s,^.*\.[$lower]*:,$object:," < "$tmpdepfile"
+      sed -e "s,^.*\.[$lower]*:[$tab ]*,," -e 's,$,:,' < "$tmpdepfile"
+    } > "$depfile"
+    rm -f "$tmpdepfile"
+  else
+    make_dummy_depfile
+  fi
+}
+
+# A tabulation character.
+tab='	'
+# A newline character.
+nl='
+'
+# Character ranges might be problematic outside the C locale.
+# These definitions help.
+upper=ABCDEFGHIJKLMNOPQRSTUVWXYZ
+lower=abcdefghijklmnopqrstuvwxyz
+digits=0123456789
+alpha=${upper}${lower}
+
+if test -z "$depmode" || test -z "$source" || test -z "$object"; then
+  echo "depcomp: Variables source, object and depmode must be set" 1>&2
+  exit 1
+fi
+
+# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po.
+depfile=${depfile-`echo "$object" |
+  sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`}
+tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`}
+
+rm -f "$tmpdepfile"
+
+# Avoid interferences from the environment.
+gccflag= dashmflag=
+
+# Some modes work just like other modes, but use different flags.  We
+# parameterize here, but still list the modes in the big case below,
+# to make depend.m4 easier to write.  Note that we *cannot* use a case
+# here, because this file can only contain one case statement.
+if test "$depmode" = hp; then
+  # HP compiler uses -M and no extra arg.
+  gccflag=-M
+  depmode=gcc
+fi
+
+if test "$depmode" = dashXmstdout; then
+  # This is just like dashmstdout with a different argument.
+  dashmflag=-xM
+  depmode=dashmstdout
+fi
+
+cygpath_u="cygpath -u -f -"
+if test "$depmode" = msvcmsys; then
+  # This is just like msvisualcpp but w/o cygpath translation.
+  # Just convert the backslash-escaped backslashes to single forward
+  # slashes to satisfy depend.m4
+  cygpath_u='sed s,\\\\,/,g'
+  depmode=msvisualcpp
+fi
+
+if test "$depmode" = msvc7msys; then
+  # This is just like msvc7 but w/o cygpath translation.
+  # Just convert the backslash-escaped backslashes to single forward
+  # slashes to satisfy depend.m4
+  cygpath_u='sed s,\\\\,/,g'
+  depmode=msvc7
+fi
+
+if test "$depmode" = xlc; then
+  # IBM C/C++ Compilers xlc/xlC can output gcc-like dependency information.
+  gccflag=-qmakedep=gcc,-MF
+  depmode=gcc
+fi
+
+case "$depmode" in
+gcc3)
+## gcc 3 implements dependency tracking that does exactly what
+## we want.  Yay!  Note: for some reason libtool 1.4 doesn't like
+## it if -MD -MP comes after the -MF stuff.  Hmm.
+## Unfortunately, FreeBSD c89 acceptance of flags depends upon
+## the command line argument order; so add the flags where they
+## appear in depend2.am.  Note that the slowdown incurred here
+## affects only configure: in makefiles, %FASTDEP% shortcuts this.
+  for arg
+  do
+    case $arg in
+    -c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;;
+    *)  set fnord "$@" "$arg" ;;
+    esac
+    shift # fnord
+    shift # $arg
+  done
+  "$@"
+  stat=$?
+  if test $stat -ne 0; then
+    rm -f "$tmpdepfile"
+    exit $stat
+  fi
+  mv "$tmpdepfile" "$depfile"
+  ;;
+
+gcc)
+## Note that this doesn't just cater to obsosete pre-3.x GCC compilers.
+## but also to in-use compilers like IMB xlc/xlC and the HP C compiler.
+## (see the conditional assignment to $gccflag above).
+## There are various ways to get dependency output from gcc.  Here's
+## why we pick this rather obscure method:
+## - Don't want to use -MD because we'd like the dependencies to end
+##   up in a subdir.  Having to rename by hand is ugly.
+##   (We might end up doing this anyway to support other compilers.)
+## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like
+##   -MM, not -M (despite what the docs say).  Also, it might not be
+##   supported by the other compilers which use the 'gcc' depmode.
+## - Using -M directly means running the compiler twice (even worse
+##   than renaming).
+  if test -z "$gccflag"; then
+    gccflag=-MD,
+  fi
+  "$@" -Wp,"$gccflag$tmpdepfile"
+  stat=$?
+  if test $stat -ne 0; then
+    rm -f "$tmpdepfile"
+    exit $stat
+  fi
+  rm -f "$depfile"
+  echo "$object : \\" > "$depfile"
+  # The second -e expression handles DOS-style file names with drive
+  # letters.
+  sed -e 's/^[^:]*: / /' \
+      -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile"
+## This next piece of magic avoids the "deleted header file" problem.
+## The problem is that when a header file which appears in a .P file
+## is deleted, the dependency causes make to die (because there is
+## typically no way to rebuild the header).  We avoid this by adding
+## dummy dependencies for each header file.  Too bad gcc doesn't do
+## this for us directly.
+## Some versions of gcc put a space before the ':'.  On the theory
+## that the space means something, we add a space to the output as
+## well.  hp depmode also adds that space, but also prefixes the VPATH
+## to the object.  Take care to not repeat it in the output.
+## Some versions of the HPUX 10.20 sed can't process this invocation
+## correctly.  Breaking it into two sed invocations is a workaround.
+  tr ' ' "$nl" < "$tmpdepfile" \
+    | sed -e 's/^\\$//' -e '/^$/d' -e "s|.*$object$||" -e '/:$/d' \
+    | sed -e 's/$/ :/' >> "$depfile"
+  rm -f "$tmpdepfile"
+  ;;
+
+hp)
+  # This case exists only to let depend.m4 do its work.  It works by
+  # looking at the text of this script.  This case will never be run,
+  # since it is checked for above.
+  exit 1
+  ;;
+
+sgi)
+  if test "$libtool" = yes; then
+    "$@" "-Wp,-MDupdate,$tmpdepfile"
+  else
+    "$@" -MDupdate "$tmpdepfile"
+  fi
+  stat=$?
+  if test $stat -ne 0; then
+    rm -f "$tmpdepfile"
+    exit $stat
+  fi
+  rm -f "$depfile"
+
+  if test -f "$tmpdepfile"; then  # yes, the sourcefile depend on other files
+    echo "$object : \\" > "$depfile"
+    # Clip off the initial element (the dependent).  Don't try to be
+    # clever and replace this with sed code, as IRIX sed won't handle
+    # lines with more than a fixed number of characters (4096 in
+    # IRIX 6.2 sed, 8192 in IRIX 6.5).  We also remove comment lines;
+    # the IRIX cc adds comments like '#:fec' to the end of the
+    # dependency line.
+    tr ' ' "$nl" < "$tmpdepfile" \
+      | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' \
+      | tr "$nl" ' ' >> "$depfile"
+    echo >> "$depfile"
+    # The second pass generates a dummy entry for each header file.
+    tr ' ' "$nl" < "$tmpdepfile" \
+      | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \
+      >> "$depfile"
+  else
+    make_dummy_depfile
+  fi
+  rm -f "$tmpdepfile"
+  ;;
+
+xlc)
+  # This case exists only to let depend.m4 do its work.  It works by
+  # looking at the text of this script.  This case will never be run,
+  # since it is checked for above.
+  exit 1
+  ;;
+
+aix)
+  # The C for AIX Compiler uses -M and outputs the dependencies
+  # in a .u file.  In older versions, this file always lives in the
+  # current directory.  Also, the AIX compiler puts '$object:' at the
+  # start of each line; $object doesn't have directory information.
+  # Version 6 uses the directory in both cases.
+  set_dir_from "$object"
+  set_base_from "$object"
+  if test "$libtool" = yes; then
+    tmpdepfile1=$dir$base.u
+    tmpdepfile2=$base.u
+    tmpdepfile3=$dir.libs/$base.u
+    "$@" -Wc,-M
+  else
+    tmpdepfile1=$dir$base.u
+    tmpdepfile2=$dir$base.u
+    tmpdepfile3=$dir$base.u
+    "$@" -M
+  fi
+  stat=$?
+  if test $stat -ne 0; then
+    rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
+    exit $stat
+  fi
+
+  for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
+  do
+    test -f "$tmpdepfile" && break
+  done
+  aix_post_process_depfile
+  ;;
+
+tcc)
+  # tcc (Tiny C Compiler) understand '-MD -MF file' since version 0.9.26
+  # FIXME: That version still under development at the moment of writing.
+  #        Make that this statement remains true also for stable, released
+  #        versions.
+  # It will wrap lines (doesn't matter whether long or short) with a
+  # trailing '\', as in:
+  #
+  #   foo.o : \
+  #    foo.c \
+  #    foo.h \
+  #
+  # It will put a trailing '\' even on the last line, and will use leading
+  # spaces rather than leading tabs (at least since its commit 0394caf7
+  # "Emit spaces for -MD").
+  "$@" -MD -MF "$tmpdepfile"
+  stat=$?
+  if test $stat -ne 0; then
+    rm -f "$tmpdepfile"
+    exit $stat
+  fi
+  rm -f "$depfile"
+  # Each non-empty line is of the form 'foo.o : \' or ' dep.h \'.
+  # We have to change lines of the first kind to '$object: \'.
+  sed -e "s|.*:|$object :|" < "$tmpdepfile" > "$depfile"
+  # And for each line of the second kind, we have to emit a 'dep.h:'
+  # dummy dependency, to avoid the deleted-header problem.
+  sed -n -e 's|^  *\(.*\) *\\$|\1:|p' < "$tmpdepfile" >> "$depfile"
+  rm -f "$tmpdepfile"
+  ;;
+
+## The order of this option in the case statement is important, since the
+## shell code in configure will try each of these formats in the order
+## listed in this file.  A plain '-MD' option would be understood by many
+## compilers, so we must ensure this comes after the gcc and icc options.
+pgcc)
+  # Portland's C compiler understands '-MD'.
+  # Will always output deps to 'file.d' where file is the root name of the
+  # source file under compilation, even if file resides in a subdirectory.
+  # The object file name does not affect the name of the '.d' file.
+  # pgcc 10.2 will output
+  #    foo.o: sub/foo.c sub/foo.h
+  # and will wrap long lines using '\' :
+  #    foo.o: sub/foo.c ... \
+  #     sub/foo.h ... \
+  #     ...
+  set_dir_from "$object"
+  # Use the source, not the object, to determine the base name, since
+  # that's sadly what pgcc will do too.
+  set_base_from "$source"
+  tmpdepfile=$base.d
+
+  # For projects that build the same source file twice into different object
+  # files, the pgcc approach of using the *source* file root name can cause
+  # problems in parallel builds.  Use a locking strategy to avoid stomping on
+  # the same $tmpdepfile.
+  lockdir=$base.d-lock
+  trap "
+    echo '$0: caught signal, cleaning up...' >&2
+    rmdir '$lockdir'
+    exit 1
+  " 1 2 13 15
+  numtries=100
+  i=$numtries
+  while test $i -gt 0; do
+    # mkdir is a portable test-and-set.
+    if mkdir "$lockdir" 2>/dev/null; then
+      # This process acquired the lock.
+      "$@" -MD
+      stat=$?
+      # Release the lock.
+      rmdir "$lockdir"
+      break
+    else
+      # If the lock is being held by a different process, wait
+      # until the winning process is done or we timeout.
+      while test -d "$lockdir" && test $i -gt 0; do
+        sleep 1
+        i=`expr $i - 1`
+      done
+    fi
+    i=`expr $i - 1`
+  done
+  trap - 1 2 13 15
+  if test $i -le 0; then
+    echo "$0: failed to acquire lock after $numtries attempts" >&2
+    echo "$0: check lockdir '$lockdir'" >&2
+    exit 1
+  fi
+
+  if test $stat -ne 0; then
+    rm -f "$tmpdepfile"
+    exit $stat
+  fi
+  rm -f "$depfile"
+  # Each line is of the form `foo.o: dependent.h',
+  # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'.
+  # Do two passes, one to just change these to
+  # `$object: dependent.h' and one to simply `dependent.h:'.
+  sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile"
+  # Some versions of the HPUX 10.20 sed can't process this invocation
+  # correctly.  Breaking it into two sed invocations is a workaround.
+  sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" \
+    | sed -e 's/$/ :/' >> "$depfile"
+  rm -f "$tmpdepfile"
+  ;;
+
+hp2)
+  # The "hp" stanza above does not work with aCC (C++) and HP's ia64
+  # compilers, which have integrated preprocessors.  The correct option
+  # to use with these is +Maked; it writes dependencies to a file named
+  # 'foo.d', which lands next to the object file, wherever that
+  # happens to be.
+  # Much of this is similar to the tru64 case; see comments there.
+  set_dir_from  "$object"
+  set_base_from "$object"
+  if test "$libtool" = yes; then
+    tmpdepfile1=$dir$base.d
+    tmpdepfile2=$dir.libs/$base.d
+    "$@" -Wc,+Maked
+  else
+    tmpdepfile1=$dir$base.d
+    tmpdepfile2=$dir$base.d
+    "$@" +Maked
+  fi
+  stat=$?
+  if test $stat -ne 0; then
+     rm -f "$tmpdepfile1" "$tmpdepfile2"
+     exit $stat
+  fi
+
+  for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2"
+  do
+    test -f "$tmpdepfile" && break
+  done
+  if test -f "$tmpdepfile"; then
+    sed -e "s,^.*\.[$lower]*:,$object:," "$tmpdepfile" > "$depfile"
+    # Add 'dependent.h:' lines.
+    sed -ne '2,${
+               s/^ *//
+               s/ \\*$//
+               s/$/:/
+               p
+             }' "$tmpdepfile" >> "$depfile"
+  else
+    make_dummy_depfile
+  fi
+  rm -f "$tmpdepfile" "$tmpdepfile2"
+  ;;
+
+tru64)
+  # The Tru64 compiler uses -MD to generate dependencies as a side
+  # effect.  'cc -MD -o foo.o ...' puts the dependencies into 'foo.o.d'.
+  # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put
+  # dependencies in 'foo.d' instead, so we check for that too.
+  # Subdirectories are respected.
+  set_dir_from  "$object"
+  set_base_from "$object"
+
+  if test "$libtool" = yes; then
+    # Libtool generates 2 separate objects for the 2 libraries.  These
+    # two compilations output dependencies in $dir.libs/$base.o.d and
+    # in $dir$base.o.d.  We have to check for both files, because
+    # one of the two compilations can be disabled.  We should prefer
+    # $dir$base.o.d over $dir.libs/$base.o.d because the latter is
+    # automatically cleaned when .libs/ is deleted, while ignoring
+    # the former would cause a distcleancheck panic.
+    tmpdepfile1=$dir$base.o.d          # libtool 1.5
+    tmpdepfile2=$dir.libs/$base.o.d    # Likewise.
+    tmpdepfile3=$dir.libs/$base.d      # Compaq CCC V6.2-504
+    "$@" -Wc,-MD
+  else
+    tmpdepfile1=$dir$base.d
+    tmpdepfile2=$dir$base.d
+    tmpdepfile3=$dir$base.d
+    "$@" -MD
+  fi
+
+  stat=$?
+  if test $stat -ne 0; then
+    rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
+    exit $stat
+  fi
+
+  for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
+  do
+    test -f "$tmpdepfile" && break
+  done
+  # Same post-processing that is required for AIX mode.
+  aix_post_process_depfile
+  ;;
+
+msvc7)
+  if test "$libtool" = yes; then
+    showIncludes=-Wc,-showIncludes
+  else
+    showIncludes=-showIncludes
+  fi
+  "$@" $showIncludes > "$tmpdepfile"
+  stat=$?
+  grep -v '^Note: including file: ' "$tmpdepfile"
+  if test $stat -ne 0; then
+    rm -f "$tmpdepfile"
+    exit $stat
+  fi
+  rm -f "$depfile"
+  echo "$object : \\" > "$depfile"
+  # The first sed program below extracts the file names and escapes
+  # backslashes for cygpath.  The second sed program outputs the file
+  # name when reading, but also accumulates all include files in the
+  # hold buffer in order to output them again at the end.  This only
+  # works with sed implementations that can handle large buffers.
+  sed < "$tmpdepfile" -n '
+/^Note: including file:  *\(.*\)/ {
+  s//\1/
+  s/\\/\\\\/g
+  p
+}' | $cygpath_u | sort -u | sed -n '
+s/ /\\ /g
+s/\(.*\)/'"$tab"'\1 \\/p
+s/.\(.*\) \\/\1:/
+H
+$ {
+  s/.*/'"$tab"'/
+  G
+  p
+}' >> "$depfile"
+  echo >> "$depfile" # make sure the fragment doesn't end with a backslash
+  rm -f "$tmpdepfile"
+  ;;
+
+msvc7msys)
+  # This case exists only to let depend.m4 do its work.  It works by
+  # looking at the text of this script.  This case will never be run,
+  # since it is checked for above.
+  exit 1
+  ;;
+
+#nosideeffect)
+  # This comment above is used by automake to tell side-effect
+  # dependency tracking mechanisms from slower ones.
+
+dashmstdout)
+  # Important note: in order to support this mode, a compiler *must*
+  # always write the preprocessed file to stdout, regardless of -o.
+  "$@" || exit $?
+
+  # Remove the call to Libtool.
+  if test "$libtool" = yes; then
+    while test "X$1" != 'X--mode=compile'; do
+      shift
+    done
+    shift
+  fi
+
+  # Remove '-o $object'.
+  IFS=" "
+  for arg
+  do
+    case $arg in
+    -o)
+      shift
+      ;;
+    $object)
+      shift
+      ;;
+    *)
+      set fnord "$@" "$arg"
+      shift # fnord
+      shift # $arg
+      ;;
+    esac
+  done
+
+  test -z "$dashmflag" && dashmflag=-M
+  # Require at least two characters before searching for ':'
+  # in the target name.  This is to cope with DOS-style filenames:
+  # a dependency such as 'c:/foo/bar' could be seen as target 'c' otherwise.
+  "$@" $dashmflag |
+    sed "s|^[$tab ]*[^:$tab ][^:][^:]*:[$tab ]*|$object: |" > "$tmpdepfile"
+  rm -f "$depfile"
+  cat < "$tmpdepfile" > "$depfile"
+  # Some versions of the HPUX 10.20 sed can't process this sed invocation
+  # correctly.  Breaking it into two sed invocations is a workaround.
+  tr ' ' "$nl" < "$tmpdepfile" \
+    | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \
+    | sed -e 's/$/ :/' >> "$depfile"
+  rm -f "$tmpdepfile"
+  ;;
+
+dashXmstdout)
+  # This case only exists to satisfy depend.m4.  It is never actually
+  # run, as this mode is specially recognized in the preamble.
+  exit 1
+  ;;
+
+makedepend)
+  "$@" || exit $?
+  # Remove any Libtool call
+  if test "$libtool" = yes; then
+    while test "X$1" != 'X--mode=compile'; do
+      shift
+    done
+    shift
+  fi
+  # X makedepend
+  shift
+  cleared=no eat=no
+  for arg
+  do
+    case $cleared in
+    no)
+      set ""; shift
+      cleared=yes ;;
+    esac
+    if test $eat = yes; then
+      eat=no
+      continue
+    fi
+    case "$arg" in
+    -D*|-I*)
+      set fnord "$@" "$arg"; shift ;;
+    # Strip any option that makedepend may not understand.  Remove
+    # the object too, otherwise makedepend will parse it as a source file.
+    -arch)
+      eat=yes ;;
+    -*|$object)
+      ;;
+    *)
+      set fnord "$@" "$arg"; shift ;;
+    esac
+  done
+  obj_suffix=`echo "$object" | sed 's/^.*\././'`
+  touch "$tmpdepfile"
+  ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@"
+  rm -f "$depfile"
+  # makedepend may prepend the VPATH from the source file name to the object.
+  # No need to regex-escape $object, excess matching of '.' is harmless.
+  sed "s|^.*\($object *:\)|\1|" "$tmpdepfile" > "$depfile"
+  # Some versions of the HPUX 10.20 sed can't process the last invocation
+  # correctly.  Breaking it into two sed invocations is a workaround.
+  sed '1,2d' "$tmpdepfile" \
+    | tr ' ' "$nl" \
+    | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \
+    | sed -e 's/$/ :/' >> "$depfile"
+  rm -f "$tmpdepfile" "$tmpdepfile".bak
+  ;;
+
+cpp)
+  # Important note: in order to support this mode, a compiler *must*
+  # always write the preprocessed file to stdout.
+  "$@" || exit $?
+
+  # Remove the call to Libtool.
+  if test "$libtool" = yes; then
+    while test "X$1" != 'X--mode=compile'; do
+      shift
+    done
+    shift
+  fi
+
+  # Remove '-o $object'.
+  IFS=" "
+  for arg
+  do
+    case $arg in
+    -o)
+      shift
+      ;;
+    $object)
+      shift
+      ;;
+    *)
+      set fnord "$@" "$arg"
+      shift # fnord
+      shift # $arg
+      ;;
+    esac
+  done
+
+  "$@" -E \
+    | sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \
+             -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \
+    | sed '$ s: \\$::' > "$tmpdepfile"
+  rm -f "$depfile"
+  echo "$object : \\" > "$depfile"
+  cat < "$tmpdepfile" >> "$depfile"
+  sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile"
+  rm -f "$tmpdepfile"
+  ;;
+
+msvisualcpp)
+  # Important note: in order to support this mode, a compiler *must*
+  # always write the preprocessed file to stdout.
+  "$@" || exit $?
+
+  # Remove the call to Libtool.
+  if test "$libtool" = yes; then
+    while test "X$1" != 'X--mode=compile'; do
+      shift
+    done
+    shift
+  fi
+
+  IFS=" "
+  for arg
+  do
+    case "$arg" in
+    -o)
+      shift
+      ;;
+    $object)
+      shift
+      ;;
+    "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI")
+        set fnord "$@"
+        shift
+        shift
+        ;;
+    *)
+        set fnord "$@" "$arg"
+        shift
+        shift
+        ;;
+    esac
+  done
+  "$@" -E 2>/dev/null |
+  sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile"
+  rm -f "$depfile"
+  echo "$object : \\" > "$depfile"
+  sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::'"$tab"'\1 \\:p' >> "$depfile"
+  echo "$tab" >> "$depfile"
+  sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile"
+  rm -f "$tmpdepfile"
+  ;;
+
+msvcmsys)
+  # This case exists only to let depend.m4 do its work.  It works by
+  # looking at the text of this script.  This case will never be run,
+  # since it is checked for above.
+  exit 1
+  ;;
+
+none)
+  exec "$@"
+  ;;
+
+*)
+  echo "Unknown depmode $depmode" 1>&2
+  exit 1
+  ;;
+esac
+
+exit 0
+
+# Local Variables:
+# mode: shell-script
+# sh-indentation: 2
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
+# End:
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/config/install-sh
@@ -0,0 +1,508 @@
+#!/bin/sh
+# install - install a program, script, or datafile
+
+scriptversion=2014-09-12.12; # UTC
+
+# This originates from X11R5 (mit/util/scripts/install.sh), which was
+# later released in X11R6 (xc/config/util/install.sh) with the
+# following copyright and license.
+#
+# Copyright (C) 1994 X Consortium
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to
+# deal in the Software without restriction, including without limitation the
+# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+# sell copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
+# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+# Except as contained in this notice, the name of the X Consortium shall not
+# be used in advertising or otherwise to promote the sale, use or other deal-
+# ings in this Software without prior written authorization from the X Consor-
+# tium.
+#
+#
+# FSF changes to this file are in the public domain.
+#
+# Calling this script install-sh is preferred over install.sh, to prevent
+# 'make' implicit rules from creating a file called install from it
+# when there is no Makefile.
+#
+# This script is compatible with the BSD install script, but was written
+# from scratch.
+
+tab='	'
+nl='
+'
+IFS=" $tab$nl"
+
+# Set DOITPROG to "echo" to test this script.
+
+doit=${DOITPROG-}
+doit_exec=${doit:-exec}
+
+# Put in absolute file names if you don't have them in your path;
+# or use environment vars.
+
+chgrpprog=${CHGRPPROG-chgrp}
+chmodprog=${CHMODPROG-chmod}
+chownprog=${CHOWNPROG-chown}
+cmpprog=${CMPPROG-cmp}
+cpprog=${CPPROG-cp}
+mkdirprog=${MKDIRPROG-mkdir}
+mvprog=${MVPROG-mv}
+rmprog=${RMPROG-rm}
+stripprog=${STRIPPROG-strip}
+
+posix_mkdir=
+
+# Desired mode of installed file.
+mode=0755
+
+chgrpcmd=
+chmodcmd=$chmodprog
+chowncmd=
+mvcmd=$mvprog
+rmcmd="$rmprog -f"
+stripcmd=
+
+src=
+dst=
+dir_arg=
+dst_arg=
+
+copy_on_change=false
+is_target_a_directory=possibly
+
+usage="\
+Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
+   or: $0 [OPTION]... SRCFILES... DIRECTORY
+   or: $0 [OPTION]... -t DIRECTORY SRCFILES...
+   or: $0 [OPTION]... -d DIRECTORIES...
+
+In the 1st form, copy SRCFILE to DSTFILE.
+In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
+In the 4th, create DIRECTORIES.
+
+Options:
+     --help     display this help and exit.
+     --version  display version info and exit.
+
+  -c            (ignored)
+  -C            install only if different (preserve the last data modification time)
+  -d            create directories instead of installing files.
+  -g GROUP      $chgrpprog installed files to GROUP.
+  -m MODE       $chmodprog installed files to MODE.
+  -o USER       $chownprog installed files to USER.
+  -s            $stripprog installed files.
+  -t DIRECTORY  install into DIRECTORY.
+  -T            report an error if DSTFILE is a directory.
+
+Environment variables override the default commands:
+  CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
+  RMPROG STRIPPROG
+"
+
+while test $# -ne 0; do
+  case $1 in
+    -c) ;;
+
+    -C) copy_on_change=true;;
+
+    -d) dir_arg=true;;
+
+    -g) chgrpcmd="$chgrpprog $2"
+        shift;;
+
+    --help) echo "$usage"; exit $?;;
+
+    -m) mode=$2
+        case $mode in
+          *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*)
+            echo "$0: invalid mode: $mode" >&2
+            exit 1;;
+        esac
+        shift;;
+
+    -o) chowncmd="$chownprog $2"
+        shift;;
+
+    -s) stripcmd=$stripprog;;
+
+    -t)
+        is_target_a_directory=always
+        dst_arg=$2
+        # Protect names problematic for 'test' and other utilities.
+        case $dst_arg in
+          -* | [=\(\)!]) dst_arg=./$dst_arg;;
+        esac
+        shift;;
+
+    -T) is_target_a_directory=never;;
+
+    --version) echo "$0 $scriptversion"; exit $?;;
+
+    --) shift
+        break;;
+
+    -*) echo "$0: invalid option: $1" >&2
+        exit 1;;
+
+    *)  break;;
+  esac
+  shift
+done
+
+# We allow the use of options -d and -T together, by making -d
+# take the precedence; this is for compatibility with GNU install.
+
+if test -n "$dir_arg"; then
+  if test -n "$dst_arg"; then
+    echo "$0: target directory not allowed when installing a directory." >&2
+    exit 1
+  fi
+fi
+
+if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
+  # When -d is used, all remaining arguments are directories to create.
+  # When -t is used, the destination is already specified.
+  # Otherwise, the last argument is the destination.  Remove it from $@.
+  for arg
+  do
+    if test -n "$dst_arg"; then
+      # $@ is not empty: it contains at least $arg.
+      set fnord "$@" "$dst_arg"
+      shift # fnord
+    fi
+    shift # arg
+    dst_arg=$arg
+    # Protect names problematic for 'test' and other utilities.
+    case $dst_arg in
+      -* | [=\(\)!]) dst_arg=./$dst_arg;;
+    esac
+  done
+fi
+
+if test $# -eq 0; then
+  if test -z "$dir_arg"; then
+    echo "$0: no input file specified." >&2
+    exit 1
+  fi
+  # It's OK to call 'install-sh -d' without argument.
+  # This can happen when creating conditional directories.
+  exit 0
+fi
+
+if test -z "$dir_arg"; then
+  if test $# -gt 1 || test "$is_target_a_directory" = always; then
+    if test ! -d "$dst_arg"; then
+      echo "$0: $dst_arg: Is not a directory." >&2
+      exit 1
+    fi
+  fi
+fi
+
+if test -z "$dir_arg"; then
+  do_exit='(exit $ret); exit $ret'
+  trap "ret=129; $do_exit" 1
+  trap "ret=130; $do_exit" 2
+  trap "ret=141; $do_exit" 13
+  trap "ret=143; $do_exit" 15
+
+  # Set umask so as not to create temps with too-generous modes.
+  # However, 'strip' requires both read and write access to temps.
+  case $mode in
+    # Optimize common cases.
+    *644) cp_umask=133;;
+    *755) cp_umask=22;;
+
+    *[0-7])
+      if test -z "$stripcmd"; then
+        u_plus_rw=
+      else
+        u_plus_rw='% 200'
+      fi
+      cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
+    *)
+      if test -z "$stripcmd"; then
+        u_plus_rw=
+      else
+        u_plus_rw=,u+rw
+      fi
+      cp_umask=$mode$u_plus_rw;;
+  esac
+fi
+
+for src
+do
+  # Protect names problematic for 'test' and other utilities.
+  case $src in
+    -* | [=\(\)!]) src=./$src;;
+  esac
+
+  if test -n "$dir_arg"; then
+    dst=$src
+    dstdir=$dst
+    test -d "$dstdir"
+    dstdir_status=$?
+  else
+
+    # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
+    # might cause directories to be created, which would be especially bad
+    # if $src (and thus $dsttmp) contains '*'.
+    if test ! -f "$src" && test ! -d "$src"; then
+      echo "$0: $src does not exist." >&2
+      exit 1
+    fi
+
+    if test -z "$dst_arg"; then
+      echo "$0: no destination specified." >&2
+      exit 1
+    fi
+    dst=$dst_arg
+
+    # If destination is a directory, append the input filename; won't work
+    # if double slashes aren't ignored.
+    if test -d "$dst"; then
+      if test "$is_target_a_directory" = never; then
+        echo "$0: $dst_arg: Is a directory" >&2
+        exit 1
+      fi
+      dstdir=$dst
+      dst=$dstdir/`basename "$src"`
+      dstdir_status=0
+    else
+      dstdir=`dirname "$dst"`
+      test -d "$dstdir"
+      dstdir_status=$?
+    fi
+  fi
+
+  obsolete_mkdir_used=false
+
+  if test $dstdir_status != 0; then
+    case $posix_mkdir in
+      '')
+        # Create intermediate dirs using mode 755 as modified by the umask.
+        # This is like FreeBSD 'install' as of 1997-10-28.
+        umask=`umask`
+        case $stripcmd.$umask in
+          # Optimize common cases.
+          *[2367][2367]) mkdir_umask=$umask;;
+          .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
+
+          *[0-7])
+            mkdir_umask=`expr $umask + 22 \
+              - $umask % 100 % 40 + $umask % 20 \
+              - $umask % 10 % 4 + $umask % 2
+            `;;
+          *) mkdir_umask=$umask,go-w;;
+        esac
+
+        # With -d, create the new directory with the user-specified mode.
+        # Otherwise, rely on $mkdir_umask.
+        if test -n "$dir_arg"; then
+          mkdir_mode=-m$mode
+        else
+          mkdir_mode=
+        fi
+
+        posix_mkdir=false
+        case $umask in
+          *[123567][0-7][0-7])
+            # POSIX mkdir -p sets u+wx bits regardless of umask, which
+            # is incompatible with FreeBSD 'install' when (umask & 300) != 0.
+            ;;
+          *)
+            # $RANDOM is not portable (e.g. dash);  use it when possible to
+            # lower collision chance
+            tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
+            trap 'ret=$?; rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null; exit $ret' 0
+
+            # As "mkdir -p" follows symlinks and we work in /tmp possibly;  so
+            # create the $tmpdir first (and fail if unsuccessful) to make sure
+            # that nobody tries to guess the $tmpdir name.
+            if (umask $mkdir_umask &&
+                $mkdirprog $mkdir_mode "$tmpdir" &&
+                exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1
+            then
+              if test -z "$dir_arg" || {
+                   # Check for POSIX incompatibilities with -m.
+                   # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
+                   # other-writable bit of parent directory when it shouldn't.
+                   # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
+                   test_tmpdir="$tmpdir/a"
+                   ls_ld_tmpdir=`ls -ld "$test_tmpdir"`
+                   case $ls_ld_tmpdir in
+                     d????-?r-*) different_mode=700;;
+                     d????-?--*) different_mode=755;;
+                     *) false;;
+                   esac &&
+                   $mkdirprog -m$different_mode -p -- "$test_tmpdir" && {
+                     ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"`
+                     test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
+                   }
+                 }
+              then posix_mkdir=:
+              fi
+              rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir"
+            else
+              # Remove any dirs left behind by ancient mkdir implementations.
+              rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null
+            fi
+            trap '' 0;;
+        esac;;
+    esac
+
+    if
+      $posix_mkdir && (
+        umask $mkdir_umask &&
+        $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
+      )
+    then :
+    else
+
+      # The umask is ridiculous, or mkdir does not conform to POSIX,
+      # or it failed possibly due to a race condition.  Create the
+      # directory the slow way, step by step, checking for races as we go.
+
+      case $dstdir in
+        /*) prefix='/';;
+        [-=\(\)!]*) prefix='./';;
+        *)  prefix='';;
+      esac
+
+      oIFS=$IFS
+      IFS=/
+      set -f
+      set fnord $dstdir
+      shift
+      set +f
+      IFS=$oIFS
+
+      prefixes=
+
+      for d
+      do
+        test X"$d" = X && continue
+
+        prefix=$prefix$d
+        if test -d "$prefix"; then
+          prefixes=
+        else
+          if $posix_mkdir; then
+            (umask=$mkdir_umask &&
+             $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
+            # Don't fail if two instances are running concurrently.
+            test -d "$prefix" || exit 1
+          else
+            case $prefix in
+              *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
+              *) qprefix=$prefix;;
+            esac
+            prefixes="$prefixes '$qprefix'"
+          fi
+        fi
+        prefix=$prefix/
+      done
+
+      if test -n "$prefixes"; then
+        # Don't fail if two instances are running concurrently.
+        (umask $mkdir_umask &&
+         eval "\$doit_exec \$mkdirprog $prefixes") ||
+          test -d "$dstdir" || exit 1
+        obsolete_mkdir_used=true
+      fi
+    fi
+  fi
+
+  if test -n "$dir_arg"; then
+    { test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
+    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
+    { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
+      test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
+  else
+
+    # Make a couple of temp file names in the proper directory.
+    dsttmp=$dstdir/_inst.$$_
+    rmtmp=$dstdir/_rm.$$_
+
+    # Trap to clean up those temp files at exit.
+    trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
+
+    # Copy the file name to the temp name.
+    (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
+
+    # and set any options; do chmod last to preserve setuid bits.
+    #
+    # If any of these fail, we abort the whole thing.  If we want to
+    # ignore errors from any of these, just make sure not to ignore
+    # errors from the above "$doit $cpprog $src $dsttmp" command.
+    #
+    { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
+    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
+    { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
+    { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
+
+    # If -C, don't bother to copy if it wouldn't change the file.
+    if $copy_on_change &&
+       old=`LC_ALL=C ls -dlL "$dst"     2>/dev/null` &&
+       new=`LC_ALL=C ls -dlL "$dsttmp"  2>/dev/null` &&
+       set -f &&
+       set X $old && old=:$2:$4:$5:$6 &&
+       set X $new && new=:$2:$4:$5:$6 &&
+       set +f &&
+       test "$old" = "$new" &&
+       $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
+    then
+      rm -f "$dsttmp"
+    else
+      # Rename the file to the real destination.
+      $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
+
+      # The rename failed, perhaps because mv can't rename something else
+      # to itself, or perhaps because mv is so ancient that it does not
+      # support -f.
+      {
+        # Now remove or move aside any old file at destination location.
+        # We try this two ways since rm can't unlink itself on some
+        # systems and the destination file might be busy for other
+        # reasons.  In this case, the final cleanup might fail but the new
+        # file should still install successfully.
+        {
+          test ! -f "$dst" ||
+          $doit $rmcmd -f "$dst" 2>/dev/null ||
+          { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
+            { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
+          } ||
+          { echo "$0: cannot unlink or rename $dst" >&2
+            (exit 1); exit 1
+          }
+        } &&
+
+        # Now rename the file to the real destination.
+        $doit $mvcmd "$dsttmp" "$dst"
+      }
+    fi || exit 1
+
+    trap '' 0
+  fi
+done
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
+# End:
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/config/libtool.m4
@@ -0,0 +1,8388 @@
+# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*-
+#
+#   Copyright (C) 1996-2001, 2003-2015 Free Software Foundation, Inc.
+#   Written by Gordon Matzigkeit, 1996
+#
+# This file is free software; the Free Software Foundation gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+
+m4_define([_LT_COPYING], [dnl
+# Copyright (C) 2014 Free Software Foundation, Inc.
+# This is free software; see the source for copying conditions.  There is NO
+# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+# GNU Libtool is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of of the License, or
+# (at your option) any later version.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program or library that is built
+# using GNU Libtool, you may include this file under the  same
+# distribution terms that you use for the rest of that program.
+#
+# GNU Libtool is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+])
+
+# serial 58 LT_INIT
+
+
+# LT_PREREQ(VERSION)
+# ------------------
+# Complain and exit if this libtool version is less that VERSION.
+m4_defun([LT_PREREQ],
+[m4_if(m4_version_compare(m4_defn([LT_PACKAGE_VERSION]), [$1]), -1,
+       [m4_default([$3],
+		   [m4_fatal([Libtool version $1 or higher is required],
+		             63)])],
+       [$2])])
+
+
+# _LT_CHECK_BUILDDIR
+# ------------------
+# Complain if the absolute build directory name contains unusual characters
+m4_defun([_LT_CHECK_BUILDDIR],
+[case `pwd` in
+  *\ * | *\	*)
+    AC_MSG_WARN([Libtool does not cope well with whitespace in `pwd`]) ;;
+esac
+])
+
+
+# LT_INIT([OPTIONS])
+# ------------------
+AC_DEFUN([LT_INIT],
+[AC_PREREQ([2.62])dnl We use AC_PATH_PROGS_FEATURE_CHECK
+AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl
+AC_BEFORE([$0], [LT_LANG])dnl
+AC_BEFORE([$0], [LT_OUTPUT])dnl
+AC_BEFORE([$0], [LTDL_INIT])dnl
+m4_require([_LT_CHECK_BUILDDIR])dnl
+
+dnl Autoconf doesn't catch unexpanded LT_ macros by default:
+m4_pattern_forbid([^_?LT_[A-Z_]+$])dnl
+m4_pattern_allow([^(_LT_EOF|LT_DLGLOBAL|LT_DLLAZY_OR_NOW|LT_MULTI_MODULE)$])dnl
+dnl aclocal doesn't pull ltoptions.m4, ltsugar.m4, or ltversion.m4
+dnl unless we require an AC_DEFUNed macro:
+AC_REQUIRE([LTOPTIONS_VERSION])dnl
+AC_REQUIRE([LTSUGAR_VERSION])dnl
+AC_REQUIRE([LTVERSION_VERSION])dnl
+AC_REQUIRE([LTOBSOLETE_VERSION])dnl
+m4_require([_LT_PROG_LTMAIN])dnl
+
+_LT_SHELL_INIT([SHELL=${CONFIG_SHELL-/bin/sh}])
+
+dnl Parse OPTIONS
+_LT_SET_OPTIONS([$0], [$1])
+
+# This can be used to rebuild libtool when needed
+LIBTOOL_DEPS=$ltmain
+
+# Always use our own libtool.
+LIBTOOL='$(SHELL) $(top_builddir)/libtool'
+AC_SUBST(LIBTOOL)dnl
+
+_LT_SETUP
+
+# Only expand once:
+m4_define([LT_INIT])
+])# LT_INIT
+
+# Old names:
+AU_ALIAS([AC_PROG_LIBTOOL], [LT_INIT])
+AU_ALIAS([AM_PROG_LIBTOOL], [LT_INIT])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_PROG_LIBTOOL], [])
+dnl AC_DEFUN([AM_PROG_LIBTOOL], [])
+
+
+# _LT_PREPARE_CC_BASENAME
+# -----------------------
+m4_defun([_LT_PREPARE_CC_BASENAME], [
+# Calculate cc_basename.  Skip known compiler wrappers and cross-prefix.
+func_cc_basename ()
+{
+    for cc_temp in @S|@*""; do
+      case $cc_temp in
+        compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;;
+        distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;;
+        \-*) ;;
+        *) break;;
+      esac
+    done
+    func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"`
+}
+])# _LT_PREPARE_CC_BASENAME
+
+
+# _LT_CC_BASENAME(CC)
+# -------------------
+# It would be clearer to call AC_REQUIREs from _LT_PREPARE_CC_BASENAME,
+# but that macro is also expanded into generated libtool script, which
+# arranges for $SED and $ECHO to be set by different means.
+m4_defun([_LT_CC_BASENAME],
+[m4_require([_LT_PREPARE_CC_BASENAME])dnl
+AC_REQUIRE([_LT_DECL_SED])dnl
+AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl
+func_cc_basename $1
+cc_basename=$func_cc_basename_result
+])
+
+
+# _LT_FILEUTILS_DEFAULTS
+# ----------------------
+# It is okay to use these file commands and assume they have been set
+# sensibly after 'm4_require([_LT_FILEUTILS_DEFAULTS])'.
+m4_defun([_LT_FILEUTILS_DEFAULTS],
+[: ${CP="cp -f"}
+: ${MV="mv -f"}
+: ${RM="rm -f"}
+])# _LT_FILEUTILS_DEFAULTS
+
+
+# _LT_SETUP
+# ---------
+m4_defun([_LT_SETUP],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+AC_REQUIRE([_LT_PREPARE_SED_QUOTE_VARS])dnl
+AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl
+
+_LT_DECL([], [PATH_SEPARATOR], [1], [The PATH separator for the build system])dnl
+dnl
+_LT_DECL([], [host_alias], [0], [The host system])dnl
+_LT_DECL([], [host], [0])dnl
+_LT_DECL([], [host_os], [0])dnl
+dnl
+_LT_DECL([], [build_alias], [0], [The build system])dnl
+_LT_DECL([], [build], [0])dnl
+_LT_DECL([], [build_os], [0])dnl
+dnl
+AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([LT_PATH_LD])dnl
+AC_REQUIRE([LT_PATH_NM])dnl
+dnl
+AC_REQUIRE([AC_PROG_LN_S])dnl
+test -z "$LN_S" && LN_S="ln -s"
+_LT_DECL([], [LN_S], [1], [Whether we need soft or hard links])dnl
+dnl
+AC_REQUIRE([LT_CMD_MAX_LEN])dnl
+_LT_DECL([objext], [ac_objext], [0], [Object file suffix (normally "o")])dnl
+_LT_DECL([], [exeext], [0], [Executable file suffix (normally "")])dnl
+dnl
+m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_CHECK_SHELL_FEATURES])dnl
+m4_require([_LT_PATH_CONVERSION_FUNCTIONS])dnl
+m4_require([_LT_CMD_RELOAD])dnl
+m4_require([_LT_CHECK_MAGIC_METHOD])dnl
+m4_require([_LT_CHECK_SHAREDLIB_FROM_LINKLIB])dnl
+m4_require([_LT_CMD_OLD_ARCHIVE])dnl
+m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl
+m4_require([_LT_WITH_SYSROOT])dnl
+m4_require([_LT_CMD_TRUNCATE])dnl
+
+_LT_CONFIG_LIBTOOL_INIT([
+# See if we are running on zsh, and set the options that allow our
+# commands through without removal of \ escapes INIT.
+if test -n "\${ZSH_VERSION+set}"; then
+   setopt NO_GLOB_SUBST
+fi
+])
+if test -n "${ZSH_VERSION+set}"; then
+   setopt NO_GLOB_SUBST
+fi
+
+_LT_CHECK_OBJDIR
+
+m4_require([_LT_TAG_COMPILER])dnl
+
+case $host_os in
+aix3*)
+  # AIX sometimes has problems with the GCC collect2 program.  For some
+  # reason, if we set the COLLECT_NAMES environment variable, the problems
+  # vanish in a puff of smoke.
+  if test set != "${COLLECT_NAMES+set}"; then
+    COLLECT_NAMES=
+    export COLLECT_NAMES
+  fi
+  ;;
+esac
+
+# Global variables:
+ofile=libtool
+can_build_shared=yes
+
+# All known linkers require a '.a' archive for static linking (except MSVC,
+# which needs '.lib').
+libext=a
+
+with_gnu_ld=$lt_cv_prog_gnu_ld
+
+old_CC=$CC
+old_CFLAGS=$CFLAGS
+
+# Set sane defaults for various variables
+test -z "$CC" && CC=cc
+test -z "$LTCC" && LTCC=$CC
+test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS
+test -z "$LD" && LD=ld
+test -z "$ac_objext" && ac_objext=o
+
+_LT_CC_BASENAME([$compiler])
+
+# Only perform the check for file, if the check method requires it
+test -z "$MAGIC_CMD" && MAGIC_CMD=file
+case $deplibs_check_method in
+file_magic*)
+  if test "$file_magic_cmd" = '$MAGIC_CMD'; then
+    _LT_PATH_MAGIC
+  fi
+  ;;
+esac
+
+# Use C for the default configuration in the libtool script
+LT_SUPPORTED_TAG([CC])
+_LT_LANG_C_CONFIG
+_LT_LANG_DEFAULT_CONFIG
+_LT_CONFIG_COMMANDS
+])# _LT_SETUP
+
+
+# _LT_PREPARE_SED_QUOTE_VARS
+# --------------------------
+# Define a few sed substitution that help us do robust quoting.
+m4_defun([_LT_PREPARE_SED_QUOTE_VARS],
+[# Backslashify metacharacters that are still active within
+# double-quoted strings.
+sed_quote_subst='s/\([["`$\\]]\)/\\\1/g'
+
+# Same as above, but do not quote variable references.
+double_quote_subst='s/\([["`\\]]\)/\\\1/g'
+
+# Sed substitution to delay expansion of an escaped shell variable in a
+# double_quote_subst'ed string.
+delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g'
+
+# Sed substitution to delay expansion of an escaped single quote.
+delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g'
+
+# Sed substitution to avoid accidental globbing in evaled expressions
+no_glob_subst='s/\*/\\\*/g'
+])
+
+# _LT_PROG_LTMAIN
+# ---------------
+# Note that this code is called both from 'configure', and 'config.status'
+# now that we use AC_CONFIG_COMMANDS to generate libtool.  Notably,
+# 'config.status' has no value for ac_aux_dir unless we are using Automake,
+# so we pass a copy along to make sure it has a sensible value anyway.
+m4_defun([_LT_PROG_LTMAIN],
+[m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([ltmain.sh])])dnl
+_LT_CONFIG_LIBTOOL_INIT([ac_aux_dir='$ac_aux_dir'])
+ltmain=$ac_aux_dir/ltmain.sh
+])# _LT_PROG_LTMAIN
+
+
+## ------------------------------------- ##
+## Accumulate code for creating libtool. ##
+## ------------------------------------- ##
+
+# So that we can recreate a full libtool script including additional
+# tags, we accumulate the chunks of code to send to AC_CONFIG_COMMANDS
+# in macros and then make a single call at the end using the 'libtool'
+# label.
+
+
+# _LT_CONFIG_LIBTOOL_INIT([INIT-COMMANDS])
+# ----------------------------------------
+# Register INIT-COMMANDS to be passed to AC_CONFIG_COMMANDS later.
+m4_define([_LT_CONFIG_LIBTOOL_INIT],
+[m4_ifval([$1],
+          [m4_append([_LT_OUTPUT_LIBTOOL_INIT],
+                     [$1
+])])])
+
+# Initialize.
+m4_define([_LT_OUTPUT_LIBTOOL_INIT])
+
+
+# _LT_CONFIG_LIBTOOL([COMMANDS])
+# ------------------------------
+# Register COMMANDS to be passed to AC_CONFIG_COMMANDS later.
+m4_define([_LT_CONFIG_LIBTOOL],
+[m4_ifval([$1],
+          [m4_append([_LT_OUTPUT_LIBTOOL_COMMANDS],
+                     [$1
+])])])
+
+# Initialize.
+m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS])
+
+
+# _LT_CONFIG_SAVE_COMMANDS([COMMANDS], [INIT_COMMANDS])
+# -----------------------------------------------------
+m4_defun([_LT_CONFIG_SAVE_COMMANDS],
+[_LT_CONFIG_LIBTOOL([$1])
+_LT_CONFIG_LIBTOOL_INIT([$2])
+])
+
+
+# _LT_FORMAT_COMMENT([COMMENT])
+# -----------------------------
+# Add leading comment marks to the start of each line, and a trailing
+# full-stop to the whole comment if one is not present already.
+m4_define([_LT_FORMAT_COMMENT],
+[m4_ifval([$1], [
+m4_bpatsubst([m4_bpatsubst([$1], [^ *], [# ])],
+              [['`$\]], [\\\&])]m4_bmatch([$1], [[!?.]$], [], [.])
+)])
+
+
+
+## ------------------------ ##
+## FIXME: Eliminate VARNAME ##
+## ------------------------ ##
+
+
+# _LT_DECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION], [IS-TAGGED?])
+# -------------------------------------------------------------------
+# CONFIGNAME is the name given to the value in the libtool script.
+# VARNAME is the (base) name used in the configure script.
+# VALUE may be 0, 1 or 2 for a computed quote escaped value based on
+# VARNAME.  Any other value will be used directly.
+m4_define([_LT_DECL],
+[lt_if_append_uniq([lt_decl_varnames], [$2], [, ],
+    [lt_dict_add_subkey([lt_decl_dict], [$2], [libtool_name],
+	[m4_ifval([$1], [$1], [$2])])
+    lt_dict_add_subkey([lt_decl_dict], [$2], [value], [$3])
+    m4_ifval([$4],
+	[lt_dict_add_subkey([lt_decl_dict], [$2], [description], [$4])])
+    lt_dict_add_subkey([lt_decl_dict], [$2],
+	[tagged?], [m4_ifval([$5], [yes], [no])])])
+])
+
+
+# _LT_TAGDECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION])
+# --------------------------------------------------------
+m4_define([_LT_TAGDECL], [_LT_DECL([$1], [$2], [$3], [$4], [yes])])
+
+
+# lt_decl_tag_varnames([SEPARATOR], [VARNAME1...])
+# ------------------------------------------------
+m4_define([lt_decl_tag_varnames],
+[_lt_decl_filter([tagged?], [yes], $@)])
+
+
+# _lt_decl_filter(SUBKEY, VALUE, [SEPARATOR], [VARNAME1..])
+# ---------------------------------------------------------
+m4_define([_lt_decl_filter],
+[m4_case([$#],
+  [0], [m4_fatal([$0: too few arguments: $#])],
+  [1], [m4_fatal([$0: too few arguments: $#: $1])],
+  [2], [lt_dict_filter([lt_decl_dict], [$1], [$2], [], lt_decl_varnames)],
+  [3], [lt_dict_filter([lt_decl_dict], [$1], [$2], [$3], lt_decl_varnames)],
+  [lt_dict_filter([lt_decl_dict], $@)])[]dnl
+])
+
+
+# lt_decl_quote_varnames([SEPARATOR], [VARNAME1...])
+# --------------------------------------------------
+m4_define([lt_decl_quote_varnames],
+[_lt_decl_filter([value], [1], $@)])
+
+
+# lt_decl_dquote_varnames([SEPARATOR], [VARNAME1...])
+# ---------------------------------------------------
+m4_define([lt_decl_dquote_varnames],
+[_lt_decl_filter([value], [2], $@)])
+
+
+# lt_decl_varnames_tagged([SEPARATOR], [VARNAME1...])
+# ---------------------------------------------------
+m4_define([lt_decl_varnames_tagged],
+[m4_assert([$# <= 2])dnl
+_$0(m4_quote(m4_default([$1], [[, ]])),
+    m4_ifval([$2], [[$2]], [m4_dquote(lt_decl_tag_varnames)]),
+    m4_split(m4_normalize(m4_quote(_LT_TAGS)), [ ]))])
+m4_define([_lt_decl_varnames_tagged],
+[m4_ifval([$3], [lt_combine([$1], [$2], [_], $3)])])
+
+
+# lt_decl_all_varnames([SEPARATOR], [VARNAME1...])
+# ------------------------------------------------
+m4_define([lt_decl_all_varnames],
+[_$0(m4_quote(m4_default([$1], [[, ]])),
+     m4_if([$2], [],
+	   m4_quote(lt_decl_varnames),
+	m4_quote(m4_shift($@))))[]dnl
+])
+m4_define([_lt_decl_all_varnames],
+[lt_join($@, lt_decl_varnames_tagged([$1],
+			lt_decl_tag_varnames([[, ]], m4_shift($@))))dnl
+])
+
+
+# _LT_CONFIG_STATUS_DECLARE([VARNAME])
+# ------------------------------------
+# Quote a variable value, and forward it to 'config.status' so that its
+# declaration there will have the same value as in 'configure'.  VARNAME
+# must have a single quote delimited value for this to work.
+m4_define([_LT_CONFIG_STATUS_DECLARE],
+[$1='`$ECHO "$][$1" | $SED "$delay_single_quote_subst"`'])
+
+
+# _LT_CONFIG_STATUS_DECLARATIONS
+# ------------------------------
+# We delimit libtool config variables with single quotes, so when
+# we write them to config.status, we have to be sure to quote all
+# embedded single quotes properly.  In configure, this macro expands
+# each variable declared with _LT_DECL (and _LT_TAGDECL) into:
+#
+#    <var>='`$ECHO "$<var>" | $SED "$delay_single_quote_subst"`'
+m4_defun([_LT_CONFIG_STATUS_DECLARATIONS],
+[m4_foreach([_lt_var], m4_quote(lt_decl_all_varnames),
+    [m4_n([_LT_CONFIG_STATUS_DECLARE(_lt_var)])])])
+
+
+# _LT_LIBTOOL_TAGS
+# ----------------
+# Output comment and list of tags supported by the script
+m4_defun([_LT_LIBTOOL_TAGS],
+[_LT_FORMAT_COMMENT([The names of the tagged configurations supported by this script])dnl
+available_tags='_LT_TAGS'dnl
+])
+
+
+# _LT_LIBTOOL_DECLARE(VARNAME, [TAG])
+# -----------------------------------
+# Extract the dictionary values for VARNAME (optionally with TAG) and
+# expand to a commented shell variable setting:
+#
+#    # Some comment about what VAR is for.
+#    visible_name=$lt_internal_name
+m4_define([_LT_LIBTOOL_DECLARE],
+[_LT_FORMAT_COMMENT(m4_quote(lt_dict_fetch([lt_decl_dict], [$1],
+					   [description])))[]dnl
+m4_pushdef([_libtool_name],
+    m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [libtool_name])))[]dnl
+m4_case(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [value])),
+    [0], [_libtool_name=[$]$1],
+    [1], [_libtool_name=$lt_[]$1],
+    [2], [_libtool_name=$lt_[]$1],
+    [_libtool_name=lt_dict_fetch([lt_decl_dict], [$1], [value])])[]dnl
+m4_ifval([$2], [_$2])[]m4_popdef([_libtool_name])[]dnl
+])
+
+
+# _LT_LIBTOOL_CONFIG_VARS
+# -----------------------
+# Produce commented declarations of non-tagged libtool config variables
+# suitable for insertion in the LIBTOOL CONFIG section of the 'libtool'
+# script.  Tagged libtool config variables (even for the LIBTOOL CONFIG
+# section) are produced by _LT_LIBTOOL_TAG_VARS.
+m4_defun([_LT_LIBTOOL_CONFIG_VARS],
+[m4_foreach([_lt_var],
+    m4_quote(_lt_decl_filter([tagged?], [no], [], lt_decl_varnames)),
+    [m4_n([_LT_LIBTOOL_DECLARE(_lt_var)])])])
+
+
+# _LT_LIBTOOL_TAG_VARS(TAG)
+# -------------------------
+m4_define([_LT_LIBTOOL_TAG_VARS],
+[m4_foreach([_lt_var], m4_quote(lt_decl_tag_varnames),
+    [m4_n([_LT_LIBTOOL_DECLARE(_lt_var, [$1])])])])
+
+
+# _LT_TAGVAR(VARNAME, [TAGNAME])
+# ------------------------------
+m4_define([_LT_TAGVAR], [m4_ifval([$2], [$1_$2], [$1])])
+
+
+# _LT_CONFIG_COMMANDS
+# -------------------
+# Send accumulated output to $CONFIG_STATUS.  Thanks to the lists of
+# variables for single and double quote escaping we saved from calls
+# to _LT_DECL, we can put quote escaped variables declarations
+# into 'config.status', and then the shell code to quote escape them in
+# for loops in 'config.status'.  Finally, any additional code accumulated
+# from calls to _LT_CONFIG_LIBTOOL_INIT is expanded.
+m4_defun([_LT_CONFIG_COMMANDS],
+[AC_PROVIDE_IFELSE([LT_OUTPUT],
+	dnl If the libtool generation code has been placed in $CONFIG_LT,
+	dnl instead of duplicating it all over again into config.status,
+	dnl then we will have config.status run $CONFIG_LT later, so it
+	dnl needs to know what name is stored there:
+        [AC_CONFIG_COMMANDS([libtool],
+            [$SHELL $CONFIG_LT || AS_EXIT(1)], [CONFIG_LT='$CONFIG_LT'])],
+    dnl If the libtool generation code is destined for config.status,
+    dnl expand the accumulated commands and init code now:
+    [AC_CONFIG_COMMANDS([libtool],
+        [_LT_OUTPUT_LIBTOOL_COMMANDS], [_LT_OUTPUT_LIBTOOL_COMMANDS_INIT])])
+])#_LT_CONFIG_COMMANDS
+
+
+# Initialize.
+m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS_INIT],
+[
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+sed_quote_subst='$sed_quote_subst'
+double_quote_subst='$double_quote_subst'
+delay_variable_subst='$delay_variable_subst'
+_LT_CONFIG_STATUS_DECLARATIONS
+LTCC='$LTCC'
+LTCFLAGS='$LTCFLAGS'
+compiler='$compiler_DEFAULT'
+
+# A function that is used when there is no print builtin or printf.
+func_fallback_echo ()
+{
+  eval 'cat <<_LTECHO_EOF
+\$[]1
+_LTECHO_EOF'
+}
+
+# Quote evaled strings.
+for var in lt_decl_all_varnames([[ \
+]], lt_decl_quote_varnames); do
+    case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in
+    *[[\\\\\\\`\\"\\\$]]*)
+      eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes
+      ;;
+    *)
+      eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
+      ;;
+    esac
+done
+
+# Double-quote double-evaled strings.
+for var in lt_decl_all_varnames([[ \
+]], lt_decl_dquote_varnames); do
+    case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in
+    *[[\\\\\\\`\\"\\\$]]*)
+      eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes
+      ;;
+    *)
+      eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
+      ;;
+    esac
+done
+
+_LT_OUTPUT_LIBTOOL_INIT
+])
+
+# _LT_GENERATED_FILE_INIT(FILE, [COMMENT])
+# ------------------------------------
+# Generate a child script FILE with all initialization necessary to
+# reuse the environment learned by the parent script, and make the
+# file executable.  If COMMENT is supplied, it is inserted after the
+# '#!' sequence but before initialization text begins.  After this
+# macro, additional text can be appended to FILE to form the body of
+# the child script.  The macro ends with non-zero status if the
+# file could not be fully written (such as if the disk is full).
+m4_ifdef([AS_INIT_GENERATED],
+[m4_defun([_LT_GENERATED_FILE_INIT],[AS_INIT_GENERATED($@)])],
+[m4_defun([_LT_GENERATED_FILE_INIT],
+[m4_require([AS_PREPARE])]dnl
+[m4_pushdef([AS_MESSAGE_LOG_FD])]dnl
+[lt_write_fail=0
+cat >$1 <<_ASEOF || lt_write_fail=1
+#! $SHELL
+# Generated by $as_me.
+$2
+SHELL=\${CONFIG_SHELL-$SHELL}
+export SHELL
+_ASEOF
+cat >>$1 <<\_ASEOF || lt_write_fail=1
+AS_SHELL_SANITIZE
+_AS_PREPARE
+exec AS_MESSAGE_FD>&1
+_ASEOF
+test 0 = "$lt_write_fail" && chmod +x $1[]dnl
+m4_popdef([AS_MESSAGE_LOG_FD])])])# _LT_GENERATED_FILE_INIT
+
+# LT_OUTPUT
+# ---------
+# This macro allows early generation of the libtool script (before
+# AC_OUTPUT is called), incase it is used in configure for compilation
+# tests.
+AC_DEFUN([LT_OUTPUT],
+[: ${CONFIG_LT=./config.lt}
+AC_MSG_NOTICE([creating $CONFIG_LT])
+_LT_GENERATED_FILE_INIT(["$CONFIG_LT"],
+[# Run this file to recreate a libtool stub with the current configuration.])
+
+cat >>"$CONFIG_LT" <<\_LTEOF
+lt_cl_silent=false
+exec AS_MESSAGE_LOG_FD>>config.log
+{
+  echo
+  AS_BOX([Running $as_me.])
+} >&AS_MESSAGE_LOG_FD
+
+lt_cl_help="\
+'$as_me' creates a local libtool stub from the current configuration,
+for use in further configure time tests before the real libtool is
+generated.
+
+Usage: $[0] [[OPTIONS]]
+
+  -h, --help      print this help, then exit
+  -V, --version   print version number, then exit
+  -q, --quiet     do not print progress messages
+  -d, --debug     don't remove temporary files
+
+Report bugs to <bug-libtool@gnu.org>."
+
+lt_cl_version="\
+m4_ifset([AC_PACKAGE_NAME], [AC_PACKAGE_NAME ])config.lt[]dnl
+m4_ifset([AC_PACKAGE_VERSION], [ AC_PACKAGE_VERSION])
+configured by $[0], generated by m4_PACKAGE_STRING.
+
+Copyright (C) 2011 Free Software Foundation, Inc.
+This config.lt script is free software; the Free Software Foundation
+gives unlimited permision to copy, distribute and modify it."
+
+while test 0 != $[#]
+do
+  case $[1] in
+    --version | --v* | -V )
+      echo "$lt_cl_version"; exit 0 ;;
+    --help | --h* | -h )
+      echo "$lt_cl_help"; exit 0 ;;
+    --debug | --d* | -d )
+      debug=: ;;
+    --quiet | --q* | --silent | --s* | -q )
+      lt_cl_silent=: ;;
+
+    -*) AC_MSG_ERROR([unrecognized option: $[1]
+Try '$[0] --help' for more information.]) ;;
+
+    *) AC_MSG_ERROR([unrecognized argument: $[1]
+Try '$[0] --help' for more information.]) ;;
+  esac
+  shift
+done
+
+if $lt_cl_silent; then
+  exec AS_MESSAGE_FD>/dev/null
+fi
+_LTEOF
+
+cat >>"$CONFIG_LT" <<_LTEOF
+_LT_OUTPUT_LIBTOOL_COMMANDS_INIT
+_LTEOF
+
+cat >>"$CONFIG_LT" <<\_LTEOF
+AC_MSG_NOTICE([creating $ofile])
+_LT_OUTPUT_LIBTOOL_COMMANDS
+AS_EXIT(0)
+_LTEOF
+chmod +x "$CONFIG_LT"
+
+# configure is writing to config.log, but config.lt does its own redirection,
+# appending to config.log, which fails on DOS, as config.log is still kept
+# open by configure.  Here we exec the FD to /dev/null, effectively closing
+# config.log, so it can be properly (re)opened and appended to by config.lt.
+lt_cl_success=:
+test yes = "$silent" &&
+  lt_config_lt_args="$lt_config_lt_args --quiet"
+exec AS_MESSAGE_LOG_FD>/dev/null
+$SHELL "$CONFIG_LT" $lt_config_lt_args || lt_cl_success=false
+exec AS_MESSAGE_LOG_FD>>config.log
+$lt_cl_success || AS_EXIT(1)
+])# LT_OUTPUT
+
+
+# _LT_CONFIG(TAG)
+# ---------------
+# If TAG is the built-in tag, create an initial libtool script with a
+# default configuration from the untagged config vars.  Otherwise add code
+# to config.status for appending the configuration named by TAG from the
+# matching tagged config vars.
+m4_defun([_LT_CONFIG],
+[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+_LT_CONFIG_SAVE_COMMANDS([
+  m4_define([_LT_TAG], m4_if([$1], [], [C], [$1]))dnl
+  m4_if(_LT_TAG, [C], [
+    # See if we are running on zsh, and set the options that allow our
+    # commands through without removal of \ escapes.
+    if test -n "${ZSH_VERSION+set}"; then
+      setopt NO_GLOB_SUBST
+    fi
+
+    cfgfile=${ofile}T
+    trap "$RM \"$cfgfile\"; exit 1" 1 2 15
+    $RM "$cfgfile"
+
+    cat <<_LT_EOF >> "$cfgfile"
+#! $SHELL
+# Generated automatically by $as_me ($PACKAGE) $VERSION
+# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+# NOTE: Changes made to this file will be lost: look at ltmain.sh.
+
+# Provide generalized library-building support services.
+# Written by Gordon Matzigkeit, 1996
+
+_LT_COPYING
+_LT_LIBTOOL_TAGS
+
+# Configured defaults for sys_lib_dlsearch_path munging.
+: \${LT_SYS_LIBRARY_PATH="$configure_time_lt_sys_library_path"}
+
+# ### BEGIN LIBTOOL CONFIG
+_LT_LIBTOOL_CONFIG_VARS
+_LT_LIBTOOL_TAG_VARS
+# ### END LIBTOOL CONFIG
+
+_LT_EOF
+
+    cat <<'_LT_EOF' >> "$cfgfile"
+
+# ### BEGIN FUNCTIONS SHARED WITH CONFIGURE
+
+_LT_PREPARE_MUNGE_PATH_LIST
+_LT_PREPARE_CC_BASENAME
+
+# ### END FUNCTIONS SHARED WITH CONFIGURE
+
+_LT_EOF
+
+  case $host_os in
+  aix3*)
+    cat <<\_LT_EOF >> "$cfgfile"
+# AIX sometimes has problems with the GCC collect2 program.  For some
+# reason, if we set the COLLECT_NAMES environment variable, the problems
+# vanish in a puff of smoke.
+if test set != "${COLLECT_NAMES+set}"; then
+  COLLECT_NAMES=
+  export COLLECT_NAMES
+fi
+_LT_EOF
+    ;;
+  esac
+
+  _LT_PROG_LTMAIN
+
+  # We use sed instead of cat because bash on DJGPP gets confused if
+  # if finds mixed CR/LF and LF-only lines.  Since sed operates in
+  # text mode, it properly converts lines to CR/LF.  This bash problem
+  # is reportedly fixed, but why not run on old versions too?
+  sed '$q' "$ltmain" >> "$cfgfile" \
+     || (rm -f "$cfgfile"; exit 1)
+
+   mv -f "$cfgfile" "$ofile" ||
+    (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile")
+  chmod +x "$ofile"
+],
+[cat <<_LT_EOF >> "$ofile"
+
+dnl Unfortunately we have to use $1 here, since _LT_TAG is not expanded
+dnl in a comment (ie after a #).
+# ### BEGIN LIBTOOL TAG CONFIG: $1
+_LT_LIBTOOL_TAG_VARS(_LT_TAG)
+# ### END LIBTOOL TAG CONFIG: $1
+_LT_EOF
+])dnl /m4_if
+],
+[m4_if([$1], [], [
+    PACKAGE='$PACKAGE'
+    VERSION='$VERSION'
+    RM='$RM'
+    ofile='$ofile'], [])
+])dnl /_LT_CONFIG_SAVE_COMMANDS
+])# _LT_CONFIG
+
+
+# LT_SUPPORTED_TAG(TAG)
+# ---------------------
+# Trace this macro to discover what tags are supported by the libtool
+# --tag option, using:
+#    autoconf --trace 'LT_SUPPORTED_TAG:$1'
+AC_DEFUN([LT_SUPPORTED_TAG], [])
+
+
+# C support is built-in for now
+m4_define([_LT_LANG_C_enabled], [])
+m4_define([_LT_TAGS], [])
+
+
+# LT_LANG(LANG)
+# -------------
+# Enable libtool support for the given language if not already enabled.
+AC_DEFUN([LT_LANG],
+[AC_BEFORE([$0], [LT_OUTPUT])dnl
+m4_case([$1],
+  [C],			[_LT_LANG(C)],
+  [C++],		[_LT_LANG(CXX)],
+  [Go],			[_LT_LANG(GO)],
+  [Java],		[_LT_LANG(GCJ)],
+  [Fortran 77],		[_LT_LANG(F77)],
+  [Fortran],		[_LT_LANG(FC)],
+  [Windows Resource],	[_LT_LANG(RC)],
+  [m4_ifdef([_LT_LANG_]$1[_CONFIG],
+    [_LT_LANG($1)],
+    [m4_fatal([$0: unsupported language: "$1"])])])dnl
+])# LT_LANG
+
+
+# _LT_LANG(LANGNAME)
+# ------------------
+m4_defun([_LT_LANG],
+[m4_ifdef([_LT_LANG_]$1[_enabled], [],
+  [LT_SUPPORTED_TAG([$1])dnl
+  m4_append([_LT_TAGS], [$1 ])dnl
+  m4_define([_LT_LANG_]$1[_enabled], [])dnl
+  _LT_LANG_$1_CONFIG($1)])dnl
+])# _LT_LANG
+
+
+m4_ifndef([AC_PROG_GO], [
+############################################################
+# NOTE: This macro has been submitted for inclusion into   #
+#  GNU Autoconf as AC_PROG_GO.  When it is available in    #
+#  a released version of Autoconf we should remove this    #
+#  macro and use it instead.                               #
+############################################################
+m4_defun([AC_PROG_GO],
+[AC_LANG_PUSH(Go)dnl
+AC_ARG_VAR([GOC],     [Go compiler command])dnl
+AC_ARG_VAR([GOFLAGS], [Go compiler flags])dnl
+_AC_ARG_VAR_LDFLAGS()dnl
+AC_CHECK_TOOL(GOC, gccgo)
+if test -z "$GOC"; then
+  if test -n "$ac_tool_prefix"; then
+    AC_CHECK_PROG(GOC, [${ac_tool_prefix}gccgo], [${ac_tool_prefix}gccgo])
+  fi
+fi
+if test -z "$GOC"; then
+  AC_CHECK_PROG(GOC, gccgo, gccgo, false)
+fi
+])#m4_defun
+])#m4_ifndef
+
+
+# _LT_LANG_DEFAULT_CONFIG
+# -----------------------
+m4_defun([_LT_LANG_DEFAULT_CONFIG],
+[AC_PROVIDE_IFELSE([AC_PROG_CXX],
+  [LT_LANG(CXX)],
+  [m4_define([AC_PROG_CXX], defn([AC_PROG_CXX])[LT_LANG(CXX)])])
+
+AC_PROVIDE_IFELSE([AC_PROG_F77],
+  [LT_LANG(F77)],
+  [m4_define([AC_PROG_F77], defn([AC_PROG_F77])[LT_LANG(F77)])])
+
+AC_PROVIDE_IFELSE([AC_PROG_FC],
+  [LT_LANG(FC)],
+  [m4_define([AC_PROG_FC], defn([AC_PROG_FC])[LT_LANG(FC)])])
+
+dnl The call to [A][M_PROG_GCJ] is quoted like that to stop aclocal
+dnl pulling things in needlessly.
+AC_PROVIDE_IFELSE([AC_PROG_GCJ],
+  [LT_LANG(GCJ)],
+  [AC_PROVIDE_IFELSE([A][M_PROG_GCJ],
+    [LT_LANG(GCJ)],
+    [AC_PROVIDE_IFELSE([LT_PROG_GCJ],
+      [LT_LANG(GCJ)],
+      [m4_ifdef([AC_PROG_GCJ],
+	[m4_define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[LT_LANG(GCJ)])])
+       m4_ifdef([A][M_PROG_GCJ],
+	[m4_define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[LT_LANG(GCJ)])])
+       m4_ifdef([LT_PROG_GCJ],
+	[m4_define([LT_PROG_GCJ], defn([LT_PROG_GCJ])[LT_LANG(GCJ)])])])])])
+
+AC_PROVIDE_IFELSE([AC_PROG_GO],
+  [LT_LANG(GO)],
+  [m4_define([AC_PROG_GO], defn([AC_PROG_GO])[LT_LANG(GO)])])
+
+AC_PROVIDE_IFELSE([LT_PROG_RC],
+  [LT_LANG(RC)],
+  [m4_define([LT_PROG_RC], defn([LT_PROG_RC])[LT_LANG(RC)])])
+])# _LT_LANG_DEFAULT_CONFIG
+
+# Obsolete macros:
+AU_DEFUN([AC_LIBTOOL_CXX], [LT_LANG(C++)])
+AU_DEFUN([AC_LIBTOOL_F77], [LT_LANG(Fortran 77)])
+AU_DEFUN([AC_LIBTOOL_FC], [LT_LANG(Fortran)])
+AU_DEFUN([AC_LIBTOOL_GCJ], [LT_LANG(Java)])
+AU_DEFUN([AC_LIBTOOL_RC], [LT_LANG(Windows Resource)])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_CXX], [])
+dnl AC_DEFUN([AC_LIBTOOL_F77], [])
+dnl AC_DEFUN([AC_LIBTOOL_FC], [])
+dnl AC_DEFUN([AC_LIBTOOL_GCJ], [])
+dnl AC_DEFUN([AC_LIBTOOL_RC], [])
+
+
+# _LT_TAG_COMPILER
+# ----------------
+m4_defun([_LT_TAG_COMPILER],
+[AC_REQUIRE([AC_PROG_CC])dnl
+
+_LT_DECL([LTCC], [CC], [1], [A C compiler])dnl
+_LT_DECL([LTCFLAGS], [CFLAGS], [1], [LTCC compiler flags])dnl
+_LT_TAGDECL([CC], [compiler], [1], [A language specific compiler])dnl
+_LT_TAGDECL([with_gcc], [GCC], [0], [Is the compiler the GNU compiler?])dnl
+
+# If no C compiler was specified, use CC.
+LTCC=${LTCC-"$CC"}
+
+# If no C compiler flags were specified, use CFLAGS.
+LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
+
+# Allow CC to be a program name with arguments.
+compiler=$CC
+])# _LT_TAG_COMPILER
+
+
+# _LT_COMPILER_BOILERPLATE
+# ------------------------
+# Check for compiler boilerplate output or warnings with
+# the simple compiler test code.
+m4_defun([_LT_COMPILER_BOILERPLATE],
+[m4_require([_LT_DECL_SED])dnl
+ac_outfile=conftest.$ac_objext
+echo "$lt_simple_compile_test_code" >conftest.$ac_ext
+eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_compiler_boilerplate=`cat conftest.err`
+$RM conftest*
+])# _LT_COMPILER_BOILERPLATE
+
+
+# _LT_LINKER_BOILERPLATE
+# ----------------------
+# Check for linker boilerplate output or warnings with
+# the simple link test code.
+m4_defun([_LT_LINKER_BOILERPLATE],
+[m4_require([_LT_DECL_SED])dnl
+ac_outfile=conftest.$ac_objext
+echo "$lt_simple_link_test_code" >conftest.$ac_ext
+eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_linker_boilerplate=`cat conftest.err`
+$RM -r conftest*
+])# _LT_LINKER_BOILERPLATE
+
+# _LT_REQUIRED_DARWIN_CHECKS
+# -------------------------
+m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[
+  case $host_os in
+    rhapsody* | darwin*)
+    AC_CHECK_TOOL([DSYMUTIL], [dsymutil], [:])
+    AC_CHECK_TOOL([NMEDIT], [nmedit], [:])
+    AC_CHECK_TOOL([LIPO], [lipo], [:])
+    AC_CHECK_TOOL([OTOOL], [otool], [:])
+    AC_CHECK_TOOL([OTOOL64], [otool64], [:])
+    _LT_DECL([], [DSYMUTIL], [1],
+      [Tool to manipulate archived DWARF debug symbol files on Mac OS X])
+    _LT_DECL([], [NMEDIT], [1],
+      [Tool to change global to local symbols on Mac OS X])
+    _LT_DECL([], [LIPO], [1],
+      [Tool to manipulate fat objects and archives on Mac OS X])
+    _LT_DECL([], [OTOOL], [1],
+      [ldd/readelf like tool for Mach-O binaries on Mac OS X])
+    _LT_DECL([], [OTOOL64], [1],
+      [ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4])
+
+    AC_CACHE_CHECK([for -single_module linker flag],[lt_cv_apple_cc_single_mod],
+      [lt_cv_apple_cc_single_mod=no
+      if test -z "$LT_MULTI_MODULE"; then
+	# By default we will add the -single_module flag. You can override
+	# by either setting the environment variable LT_MULTI_MODULE
+	# non-empty at configure time, or by adding -multi_module to the
+	# link flags.
+	rm -rf libconftest.dylib*
+	echo "int foo(void){return 1;}" > conftest.c
+	echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \
+-dynamiclib -Wl,-single_module conftest.c" >&AS_MESSAGE_LOG_FD
+	$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \
+	  -dynamiclib -Wl,-single_module conftest.c 2>conftest.err
+        _lt_result=$?
+	# If there is a non-empty error log, and "single_module"
+	# appears in it, assume the flag caused a linker warning
+        if test -s conftest.err && $GREP single_module conftest.err; then
+	  cat conftest.err >&AS_MESSAGE_LOG_FD
+	# Otherwise, if the output was created with a 0 exit code from
+	# the compiler, it worked.
+	elif test -f libconftest.dylib && test 0 = "$_lt_result"; then
+	  lt_cv_apple_cc_single_mod=yes
+	else
+	  cat conftest.err >&AS_MESSAGE_LOG_FD
+	fi
+	rm -rf libconftest.dylib*
+	rm -f conftest.*
+      fi])
+
+    AC_CACHE_CHECK([for -exported_symbols_list linker flag],
+      [lt_cv_ld_exported_symbols_list],
+      [lt_cv_ld_exported_symbols_list=no
+      save_LDFLAGS=$LDFLAGS
+      echo "_main" > conftest.sym
+      LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym"
+      AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])],
+	[lt_cv_ld_exported_symbols_list=yes],
+	[lt_cv_ld_exported_symbols_list=no])
+	LDFLAGS=$save_LDFLAGS
+    ])
+
+    AC_CACHE_CHECK([for -force_load linker flag],[lt_cv_ld_force_load],
+      [lt_cv_ld_force_load=no
+      cat > conftest.c << _LT_EOF
+int forced_loaded() { return 2;}
+_LT_EOF
+      echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&AS_MESSAGE_LOG_FD
+      $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&AS_MESSAGE_LOG_FD
+      echo "$AR cru libconftest.a conftest.o" >&AS_MESSAGE_LOG_FD
+      $AR cru libconftest.a conftest.o 2>&AS_MESSAGE_LOG_FD
+      echo "$RANLIB libconftest.a" >&AS_MESSAGE_LOG_FD
+      $RANLIB libconftest.a 2>&AS_MESSAGE_LOG_FD
+      cat > conftest.c << _LT_EOF
+int main() { return 0;}
+_LT_EOF
+      echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&AS_MESSAGE_LOG_FD
+      $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err
+      _lt_result=$?
+      if test -s conftest.err && $GREP force_load conftest.err; then
+	cat conftest.err >&AS_MESSAGE_LOG_FD
+      elif test -f conftest && test 0 = "$_lt_result" && $GREP forced_load conftest >/dev/null 2>&1; then
+	lt_cv_ld_force_load=yes
+      else
+	cat conftest.err >&AS_MESSAGE_LOG_FD
+      fi
+        rm -f conftest.err libconftest.a conftest conftest.c
+        rm -rf conftest.dSYM
+    ])
+    case $host_os in
+    rhapsody* | darwin1.[[012]])
+      _lt_dar_allow_undefined='$wl-undefined ${wl}suppress' ;;
+    darwin1.*)
+      _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;;
+    darwin*) # darwin 5.x on
+      # if running on 10.5 or later, the deployment target defaults
+      # to the OS version, if on x86, and 10.4, the deployment
+      # target defaults to 10.4. Don't you love it?
+      case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in
+	10.0,*86*-darwin8*|10.0,*-darwin[[91]]*)
+	  _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;;
+	10.[[012]][[,.]]*)
+	  _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;;
+	10.*)
+	  _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;;
+      esac
+    ;;
+  esac
+    if test yes = "$lt_cv_apple_cc_single_mod"; then
+      _lt_dar_single_mod='$single_module'
+    fi
+    if test yes = "$lt_cv_ld_exported_symbols_list"; then
+      _lt_dar_export_syms=' $wl-exported_symbols_list,$output_objdir/$libname-symbols.expsym'
+    else
+      _lt_dar_export_syms='~$NMEDIT -s $output_objdir/$libname-symbols.expsym $lib'
+    fi
+    if test : != "$DSYMUTIL" && test no = "$lt_cv_ld_force_load"; then
+      _lt_dsymutil='~$DSYMUTIL $lib || :'
+    else
+      _lt_dsymutil=
+    fi
+    ;;
+  esac
+])
+
+
+# _LT_DARWIN_LINKER_FEATURES([TAG])
+# ---------------------------------
+# Checks for linker and compiler features on darwin
+m4_defun([_LT_DARWIN_LINKER_FEATURES],
+[
+  m4_require([_LT_REQUIRED_DARWIN_CHECKS])
+  _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+  _LT_TAGVAR(hardcode_direct, $1)=no
+  _LT_TAGVAR(hardcode_automatic, $1)=yes
+  _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
+  if test yes = "$lt_cv_ld_force_load"; then
+    _LT_TAGVAR(whole_archive_flag_spec, $1)='`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience $wl-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`'
+    m4_case([$1], [F77], [_LT_TAGVAR(compiler_needs_object, $1)=yes],
+                  [FC],  [_LT_TAGVAR(compiler_needs_object, $1)=yes])
+  else
+    _LT_TAGVAR(whole_archive_flag_spec, $1)=''
+  fi
+  _LT_TAGVAR(link_all_deplibs, $1)=yes
+  _LT_TAGVAR(allow_undefined_flag, $1)=$_lt_dar_allow_undefined
+  case $cc_basename in
+     ifort*|nagfor*) _lt_dar_can_shared=yes ;;
+     *) _lt_dar_can_shared=$GCC ;;
+  esac
+  if test yes = "$_lt_dar_can_shared"; then
+    output_verbose_link_cmd=func_echo_all
+    _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil"
+    _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil"
+    _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil"
+    _LT_TAGVAR(module_expsym_cmds, $1)="sed -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil"
+    m4_if([$1], [CXX],
+[   if test yes != "$lt_cv_apple_cc_single_mod"; then
+      _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dsymutil"
+      _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dar_export_syms$_lt_dsymutil"
+    fi
+],[])
+  else
+  _LT_TAGVAR(ld_shlibs, $1)=no
+  fi
+])
+
+# _LT_SYS_MODULE_PATH_AIX([TAGNAME])
+# ----------------------------------
+# Links a minimal program and checks the executable
+# for the system default hardcoded library path. In most cases,
+# this is /usr/lib:/lib, but when the MPI compilers are used
+# the location of the communication and MPI libs are included too.
+# If we don't find anything, use the default library path according
+# to the aix ld manual.
+# Store the results from the different compilers for each TAGNAME.
+# Allow to override them for all tags through lt_cv_aix_libpath.
+m4_defun([_LT_SYS_MODULE_PATH_AIX],
+[m4_require([_LT_DECL_SED])dnl
+if test set = "${lt_cv_aix_libpath+set}"; then
+  aix_libpath=$lt_cv_aix_libpath
+else
+  AC_CACHE_VAL([_LT_TAGVAR([lt_cv_aix_libpath_], [$1])],
+  [AC_LINK_IFELSE([AC_LANG_PROGRAM],[
+  lt_aix_libpath_sed='[
+      /Import File Strings/,/^$/ {
+	  /^0/ {
+	      s/^0  *\([^ ]*\) *$/\1/
+	      p
+	  }
+      }]'
+  _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+  # Check for a 64-bit object if we didn't find anything.
+  if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then
+    _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+  fi],[])
+  if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then
+    _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=/usr/lib:/lib
+  fi
+  ])
+  aix_libpath=$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])
+fi
+])# _LT_SYS_MODULE_PATH_AIX
+
+
+# _LT_SHELL_INIT(ARG)
+# -------------------
+m4_define([_LT_SHELL_INIT],
+[m4_divert_text([M4SH-INIT], [$1
+])])# _LT_SHELL_INIT
+
+
+
+# _LT_PROG_ECHO_BACKSLASH
+# -----------------------
+# Find how we can fake an echo command that does not interpret backslash.
+# In particular, with Autoconf 2.60 or later we add some code to the start
+# of the generated configure script that will find a shell with a builtin
+# printf (that we can use as an echo command).
+m4_defun([_LT_PROG_ECHO_BACKSLASH],
+[ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO
+ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO
+
+AC_MSG_CHECKING([how to print strings])
+# Test print first, because it will be a builtin if present.
+if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \
+   test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then
+  ECHO='print -r --'
+elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then
+  ECHO='printf %s\n'
+else
+  # Use this function as a fallback that always works.
+  func_fallback_echo ()
+  {
+    eval 'cat <<_LTECHO_EOF
+$[]1
+_LTECHO_EOF'
+  }
+  ECHO='func_fallback_echo'
+fi
+
+# func_echo_all arg...
+# Invoke $ECHO with all args, space-separated.
+func_echo_all ()
+{
+    $ECHO "$*"
+}
+
+case $ECHO in
+  printf*) AC_MSG_RESULT([printf]) ;;
+  print*) AC_MSG_RESULT([print -r]) ;;
+  *) AC_MSG_RESULT([cat]) ;;
+esac
+
+m4_ifdef([_AS_DETECT_SUGGESTED],
+[_AS_DETECT_SUGGESTED([
+  test -n "${ZSH_VERSION+set}${BASH_VERSION+set}" || (
+    ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+    ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO
+    ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO
+    PATH=/empty FPATH=/empty; export PATH FPATH
+    test "X`printf %s $ECHO`" = "X$ECHO" \
+      || test "X`print -r -- $ECHO`" = "X$ECHO" )])])
+
+_LT_DECL([], [SHELL], [1], [Shell to use when invoking shell scripts])
+_LT_DECL([], [ECHO], [1], [An echo program that protects backslashes])
+])# _LT_PROG_ECHO_BACKSLASH
+
+
+# _LT_WITH_SYSROOT
+# ----------------
+AC_DEFUN([_LT_WITH_SYSROOT],
+[AC_MSG_CHECKING([for sysroot])
+AC_ARG_WITH([sysroot],
+[AS_HELP_STRING([--with-sysroot@<:@=DIR@:>@],
+  [Search for dependent libraries within DIR (or the compiler's sysroot
+   if not specified).])],
+[], [with_sysroot=no])
+
+dnl lt_sysroot will always be passed unquoted.  We quote it here
+dnl in case the user passed a directory name.
+lt_sysroot=
+case $with_sysroot in #(
+ yes)
+   if test yes = "$GCC"; then
+     lt_sysroot=`$CC --print-sysroot 2>/dev/null`
+   fi
+   ;; #(
+ /*)
+   lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"`
+   ;; #(
+ no|'')
+   ;; #(
+ *)
+   AC_MSG_RESULT([$with_sysroot])
+   AC_MSG_ERROR([The sysroot must be an absolute path.])
+   ;;
+esac
+
+ AC_MSG_RESULT([${lt_sysroot:-no}])
+_LT_DECL([], [lt_sysroot], [0], [The root where to search for ]dnl
+[dependent libraries, and where our libraries should be installed.])])
+
+# _LT_ENABLE_LOCK
+# ---------------
+m4_defun([_LT_ENABLE_LOCK],
+[AC_ARG_ENABLE([libtool-lock],
+  [AS_HELP_STRING([--disable-libtool-lock],
+    [avoid locking (might break parallel builds)])])
+test no = "$enable_libtool_lock" || enable_libtool_lock=yes
+
+# Some flags need to be propagated to the compiler or linker for good
+# libtool support.
+case $host in
+ia64-*-hpux*)
+  # Find out what ABI is being produced by ac_compile, and set mode
+  # options accordingly.
+  echo 'int i;' > conftest.$ac_ext
+  if AC_TRY_EVAL(ac_compile); then
+    case `/usr/bin/file conftest.$ac_objext` in
+      *ELF-32*)
+	HPUX_IA64_MODE=32
+	;;
+      *ELF-64*)
+	HPUX_IA64_MODE=64
+	;;
+    esac
+  fi
+  rm -rf conftest*
+  ;;
+*-*-irix6*)
+  # Find out what ABI is being produced by ac_compile, and set linker
+  # options accordingly.
+  echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext
+  if AC_TRY_EVAL(ac_compile); then
+    if test yes = "$lt_cv_prog_gnu_ld"; then
+      case `/usr/bin/file conftest.$ac_objext` in
+	*32-bit*)
+	  LD="${LD-ld} -melf32bsmip"
+	  ;;
+	*N32*)
+	  LD="${LD-ld} -melf32bmipn32"
+	  ;;
+	*64-bit*)
+	  LD="${LD-ld} -melf64bmip"
+	;;
+      esac
+    else
+      case `/usr/bin/file conftest.$ac_objext` in
+	*32-bit*)
+	  LD="${LD-ld} -32"
+	  ;;
+	*N32*)
+	  LD="${LD-ld} -n32"
+	  ;;
+	*64-bit*)
+	  LD="${LD-ld} -64"
+	  ;;
+      esac
+    fi
+  fi
+  rm -rf conftest*
+  ;;
+
+mips64*-*linux*)
+  # Find out what ABI is being produced by ac_compile, and set linker
+  # options accordingly.
+  echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext
+  if AC_TRY_EVAL(ac_compile); then
+    emul=elf
+    case `/usr/bin/file conftest.$ac_objext` in
+      *32-bit*)
+	emul="${emul}32"
+	;;
+      *64-bit*)
+	emul="${emul}64"
+	;;
+    esac
+    case `/usr/bin/file conftest.$ac_objext` in
+      *MSB*)
+	emul="${emul}btsmip"
+	;;
+      *LSB*)
+	emul="${emul}ltsmip"
+	;;
+    esac
+    case `/usr/bin/file conftest.$ac_objext` in
+      *N32*)
+	emul="${emul}n32"
+	;;
+    esac
+    LD="${LD-ld} -m $emul"
+  fi
+  rm -rf conftest*
+  ;;
+
+x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \
+s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
+  # Find out what ABI is being produced by ac_compile, and set linker
+  # options accordingly.  Note that the listed cases only cover the
+  # situations where additional linker options are needed (such as when
+  # doing 32-bit compilation for a host where ld defaults to 64-bit, or
+  # vice versa); the common cases where no linker options are needed do
+  # not appear in the list.
+  echo 'int i;' > conftest.$ac_ext
+  if AC_TRY_EVAL(ac_compile); then
+    case `/usr/bin/file conftest.o` in
+      *32-bit*)
+	case $host in
+	  x86_64-*kfreebsd*-gnu)
+	    LD="${LD-ld} -m elf_i386_fbsd"
+	    ;;
+	  x86_64-*linux*)
+	    case `/usr/bin/file conftest.o` in
+	      *x86-64*)
+		LD="${LD-ld} -m elf32_x86_64"
+		;;
+	      *)
+		LD="${LD-ld} -m elf_i386"
+		;;
+	    esac
+	    ;;
+	  powerpc64le-*linux*)
+	    LD="${LD-ld} -m elf32lppclinux"
+	    ;;
+	  powerpc64-*linux*)
+	    LD="${LD-ld} -m elf32ppclinux"
+	    ;;
+	  s390x-*linux*)
+	    LD="${LD-ld} -m elf_s390"
+	    ;;
+	  sparc64-*linux*)
+	    LD="${LD-ld} -m elf32_sparc"
+	    ;;
+	esac
+	;;
+      *64-bit*)
+	case $host in
+	  x86_64-*kfreebsd*-gnu)
+	    LD="${LD-ld} -m elf_x86_64_fbsd"
+	    ;;
+	  x86_64-*linux*)
+	    LD="${LD-ld} -m elf_x86_64"
+	    ;;
+	  powerpcle-*linux*)
+	    LD="${LD-ld} -m elf64lppc"
+	    ;;
+	  powerpc-*linux*)
+	    LD="${LD-ld} -m elf64ppc"
+	    ;;
+	  s390*-*linux*|s390*-*tpf*)
+	    LD="${LD-ld} -m elf64_s390"
+	    ;;
+	  sparc*-*linux*)
+	    LD="${LD-ld} -m elf64_sparc"
+	    ;;
+	esac
+	;;
+    esac
+  fi
+  rm -rf conftest*
+  ;;
+
+*-*-sco3.2v5*)
+  # On SCO OpenServer 5, we need -belf to get full-featured binaries.
+  SAVE_CFLAGS=$CFLAGS
+  CFLAGS="$CFLAGS -belf"
+  AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf,
+    [AC_LANG_PUSH(C)
+     AC_LINK_IFELSE([AC_LANG_PROGRAM([[]],[[]])],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no])
+     AC_LANG_POP])
+  if test yes != "$lt_cv_cc_needs_belf"; then
+    # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf
+    CFLAGS=$SAVE_CFLAGS
+  fi
+  ;;
+*-*solaris*)
+  # Find out what ABI is being produced by ac_compile, and set linker
+  # options accordingly.
+  echo 'int i;' > conftest.$ac_ext
+  if AC_TRY_EVAL(ac_compile); then
+    case `/usr/bin/file conftest.o` in
+    *64-bit*)
+      case $lt_cv_prog_gnu_ld in
+      yes*)
+        case $host in
+        i?86-*-solaris*|x86_64-*-solaris*)
+          LD="${LD-ld} -m elf_x86_64"
+          ;;
+        sparc*-*-solaris*)
+          LD="${LD-ld} -m elf64_sparc"
+          ;;
+        esac
+        # GNU ld 2.21 introduced _sol2 emulations.  Use them if available.
+        if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then
+          LD=${LD-ld}_sol2
+        fi
+        ;;
+      *)
+	if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then
+	  LD="${LD-ld} -64"
+	fi
+	;;
+      esac
+      ;;
+    esac
+  fi
+  rm -rf conftest*
+  ;;
+esac
+
+need_locks=$enable_libtool_lock
+])# _LT_ENABLE_LOCK
+
+
+# _LT_PROG_AR
+# -----------
+m4_defun([_LT_PROG_AR],
+[AC_CHECK_TOOLS(AR, [ar], false)
+: ${AR=ar}
+: ${AR_FLAGS=cru}
+_LT_DECL([], [AR], [1], [The archiver])
+_LT_DECL([], [AR_FLAGS], [1], [Flags to create an archive])
+
+AC_CACHE_CHECK([for archiver @FILE support], [lt_cv_ar_at_file],
+  [lt_cv_ar_at_file=no
+   AC_COMPILE_IFELSE([AC_LANG_PROGRAM],
+     [echo conftest.$ac_objext > conftest.lst
+      lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&AS_MESSAGE_LOG_FD'
+      AC_TRY_EVAL([lt_ar_try])
+      if test 0 -eq "$ac_status"; then
+	# Ensure the archiver fails upon bogus file names.
+	rm -f conftest.$ac_objext libconftest.a
+	AC_TRY_EVAL([lt_ar_try])
+	if test 0 -ne "$ac_status"; then
+          lt_cv_ar_at_file=@
+        fi
+      fi
+      rm -f conftest.* libconftest.a
+     ])
+  ])
+
+if test no = "$lt_cv_ar_at_file"; then
+  archiver_list_spec=
+else
+  archiver_list_spec=$lt_cv_ar_at_file
+fi
+_LT_DECL([], [archiver_list_spec], [1],
+  [How to feed a file listing to the archiver])
+])# _LT_PROG_AR
+
+
+# _LT_CMD_OLD_ARCHIVE
+# -------------------
+m4_defun([_LT_CMD_OLD_ARCHIVE],
+[_LT_PROG_AR
+
+AC_CHECK_TOOL(STRIP, strip, :)
+test -z "$STRIP" && STRIP=:
+_LT_DECL([], [STRIP], [1], [A symbol stripping program])
+
+AC_CHECK_TOOL(RANLIB, ranlib, :)
+test -z "$RANLIB" && RANLIB=:
+_LT_DECL([], [RANLIB], [1],
+    [Commands used to install an old-style archive])
+
+# Determine commands to create old-style static archives.
+old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs'
+old_postinstall_cmds='chmod 644 $oldlib'
+old_postuninstall_cmds=
+
+if test -n "$RANLIB"; then
+  case $host_os in
+  bitrig* | openbsd*)
+    old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib"
+    ;;
+  *)
+    old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib"
+    ;;
+  esac
+  old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib"
+fi
+
+case $host_os in
+  darwin*)
+    lock_old_archive_extraction=yes ;;
+  *)
+    lock_old_archive_extraction=no ;;
+esac
+_LT_DECL([], [old_postinstall_cmds], [2])
+_LT_DECL([], [old_postuninstall_cmds], [2])
+_LT_TAGDECL([], [old_archive_cmds], [2],
+    [Commands used to build an old-style archive])
+_LT_DECL([], [lock_old_archive_extraction], [0],
+    [Whether to use a lock for old archive extraction])
+])# _LT_CMD_OLD_ARCHIVE
+
+
+# _LT_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS,
+#		[OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE])
+# ----------------------------------------------------------------
+# Check whether the given compiler option works
+AC_DEFUN([_LT_COMPILER_OPTION],
+[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_DECL_SED])dnl
+AC_CACHE_CHECK([$1], [$2],
+  [$2=no
+   m4_if([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4])
+   echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+   lt_compiler_flag="$3"  ## exclude from sc_useless_quotes_in_assignment
+   # Insert the option either (1) after the last *FLAGS variable, or
+   # (2) before a word containing "conftest.", or (3) at the end.
+   # Note that $ac_compile itself does not contain backslashes and begins
+   # with a dollar sign (not a hyphen), so the echo should work correctly.
+   # The option is referenced via a variable to avoid confusing sed.
+   lt_compile=`echo "$ac_compile" | $SED \
+   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+   -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \
+   -e 's:$: $lt_compiler_flag:'`
+   (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD)
+   (eval "$lt_compile" 2>conftest.err)
+   ac_status=$?
+   cat conftest.err >&AS_MESSAGE_LOG_FD
+   echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD
+   if (exit $ac_status) && test -s "$ac_outfile"; then
+     # The compiler can only warn and ignore the option if not recognized
+     # So say no if there are warnings other than the usual output.
+     $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp
+     $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+     if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
+       $2=yes
+     fi
+   fi
+   $RM conftest*
+])
+
+if test yes = "[$]$2"; then
+    m4_if([$5], , :, [$5])
+else
+    m4_if([$6], , :, [$6])
+fi
+])# _LT_COMPILER_OPTION
+
+# Old name:
+AU_ALIAS([AC_LIBTOOL_COMPILER_OPTION], [_LT_COMPILER_OPTION])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION], [])
+
+
+# _LT_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS,
+#                  [ACTION-SUCCESS], [ACTION-FAILURE])
+# ----------------------------------------------------
+# Check whether the given linker option works
+AC_DEFUN([_LT_LINKER_OPTION],
+[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_DECL_SED])dnl
+AC_CACHE_CHECK([$1], [$2],
+  [$2=no
+   save_LDFLAGS=$LDFLAGS
+   LDFLAGS="$LDFLAGS $3"
+   echo "$lt_simple_link_test_code" > conftest.$ac_ext
+   if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
+     # The linker can only warn and ignore the option if not recognized
+     # So say no if there are warnings
+     if test -s conftest.err; then
+       # Append any errors to the config.log.
+       cat conftest.err 1>&AS_MESSAGE_LOG_FD
+       $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp
+       $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+       if diff conftest.exp conftest.er2 >/dev/null; then
+         $2=yes
+       fi
+     else
+       $2=yes
+     fi
+   fi
+   $RM -r conftest*
+   LDFLAGS=$save_LDFLAGS
+])
+
+if test yes = "[$]$2"; then
+    m4_if([$4], , :, [$4])
+else
+    m4_if([$5], , :, [$5])
+fi
+])# _LT_LINKER_OPTION
+
+# Old name:
+AU_ALIAS([AC_LIBTOOL_LINKER_OPTION], [_LT_LINKER_OPTION])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_LINKER_OPTION], [])
+
+
+# LT_CMD_MAX_LEN
+#---------------
+AC_DEFUN([LT_CMD_MAX_LEN],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+# find the maximum length of command line arguments
+AC_MSG_CHECKING([the maximum length of command line arguments])
+AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl
+  i=0
+  teststring=ABCD
+
+  case $build_os in
+  msdosdjgpp*)
+    # On DJGPP, this test can blow up pretty badly due to problems in libc
+    # (any single argument exceeding 2000 bytes causes a buffer overrun
+    # during glob expansion).  Even if it were fixed, the result of this
+    # check would be larger than it should be.
+    lt_cv_sys_max_cmd_len=12288;    # 12K is about right
+    ;;
+
+  gnu*)
+    # Under GNU Hurd, this test is not required because there is
+    # no limit to the length of command line arguments.
+    # Libtool will interpret -1 as no limit whatsoever
+    lt_cv_sys_max_cmd_len=-1;
+    ;;
+
+  cygwin* | mingw* | cegcc*)
+    # On Win9x/ME, this test blows up -- it succeeds, but takes
+    # about 5 minutes as the teststring grows exponentially.
+    # Worse, since 9x/ME are not pre-emptively multitasking,
+    # you end up with a "frozen" computer, even though with patience
+    # the test eventually succeeds (with a max line length of 256k).
+    # Instead, let's just punt: use the minimum linelength reported by
+    # all of the supported platforms: 8192 (on NT/2K/XP).
+    lt_cv_sys_max_cmd_len=8192;
+    ;;
+
+  mint*)
+    # On MiNT this can take a long time and run out of memory.
+    lt_cv_sys_max_cmd_len=8192;
+    ;;
+
+  amigaos*)
+    # On AmigaOS with pdksh, this test takes hours, literally.
+    # So we just punt and use a minimum line length of 8192.
+    lt_cv_sys_max_cmd_len=8192;
+    ;;
+
+  bitrig* | darwin* | dragonfly* | freebsd* | netbsd* | openbsd*)
+    # This has been around since 386BSD, at least.  Likely further.
+    if test -x /sbin/sysctl; then
+      lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax`
+    elif test -x /usr/sbin/sysctl; then
+      lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax`
+    else
+      lt_cv_sys_max_cmd_len=65536	# usable default for all BSDs
+    fi
+    # And add a safety zone
+    lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
+    lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
+    ;;
+
+  interix*)
+    # We know the value 262144 and hardcode it with a safety zone (like BSD)
+    lt_cv_sys_max_cmd_len=196608
+    ;;
+
+  os2*)
+    # The test takes a long time on OS/2.
+    lt_cv_sys_max_cmd_len=8192
+    ;;
+
+  osf*)
+    # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure
+    # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not
+    # nice to cause kernel panics so lets avoid the loop below.
+    # First set a reasonable default.
+    lt_cv_sys_max_cmd_len=16384
+    #
+    if test -x /sbin/sysconfig; then
+      case `/sbin/sysconfig -q proc exec_disable_arg_limit` in
+        *1*) lt_cv_sys_max_cmd_len=-1 ;;
+      esac
+    fi
+    ;;
+  sco3.2v5*)
+    lt_cv_sys_max_cmd_len=102400
+    ;;
+  sysv5* | sco5v6* | sysv4.2uw2*)
+    kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null`
+    if test -n "$kargmax"; then
+      lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[[	 ]]//'`
+    else
+      lt_cv_sys_max_cmd_len=32768
+    fi
+    ;;
+  *)
+    lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null`
+    if test -n "$lt_cv_sys_max_cmd_len" && \
+       test undefined != "$lt_cv_sys_max_cmd_len"; then
+      lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
+      lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
+    else
+      # Make teststring a little bigger before we do anything with it.
+      # a 1K string should be a reasonable start.
+      for i in 1 2 3 4 5 6 7 8; do
+        teststring=$teststring$teststring
+      done
+      SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}}
+      # If test is not a shell built-in, we'll probably end up computing a
+      # maximum length that is only half of the actual maximum length, but
+      # we can't tell.
+      while { test X`env echo "$teststring$teststring" 2>/dev/null` \
+	         = "X$teststring$teststring"; } >/dev/null 2>&1 &&
+	      test 17 != "$i" # 1/2 MB should be enough
+      do
+        i=`expr $i + 1`
+        teststring=$teststring$teststring
+      done
+      # Only check the string length outside the loop.
+      lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1`
+      teststring=
+      # Add a significant safety factor because C++ compilers can tack on
+      # massive amounts of additional arguments before passing them to the
+      # linker.  It appears as though 1/2 is a usable value.
+      lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2`
+    fi
+    ;;
+  esac
+])
+if test -n "$lt_cv_sys_max_cmd_len"; then
+  AC_MSG_RESULT($lt_cv_sys_max_cmd_len)
+else
+  AC_MSG_RESULT(none)
+fi
+max_cmd_len=$lt_cv_sys_max_cmd_len
+_LT_DECL([], [max_cmd_len], [0],
+    [What is the maximum length of a command?])
+])# LT_CMD_MAX_LEN
+
+# Old name:
+AU_ALIAS([AC_LIBTOOL_SYS_MAX_CMD_LEN], [LT_CMD_MAX_LEN])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN], [])
+
+
+# _LT_HEADER_DLFCN
+# ----------------
+m4_defun([_LT_HEADER_DLFCN],
+[AC_CHECK_HEADERS([dlfcn.h], [], [], [AC_INCLUDES_DEFAULT])dnl
+])# _LT_HEADER_DLFCN
+
+
+# _LT_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE,
+#                      ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING)
+# ----------------------------------------------------------------
+m4_defun([_LT_TRY_DLOPEN_SELF],
+[m4_require([_LT_HEADER_DLFCN])dnl
+if test yes = "$cross_compiling"; then :
+  [$4]
+else
+  lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+  lt_status=$lt_dlunknown
+  cat > conftest.$ac_ext <<_LT_EOF
+[#line $LINENO "configure"
+#include "confdefs.h"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+#  define LT_DLGLOBAL		RTLD_GLOBAL
+#else
+#  ifdef DL_GLOBAL
+#    define LT_DLGLOBAL		DL_GLOBAL
+#  else
+#    define LT_DLGLOBAL		0
+#  endif
+#endif
+
+/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
+   find out it does not work in some platform. */
+#ifndef LT_DLLAZY_OR_NOW
+#  ifdef RTLD_LAZY
+#    define LT_DLLAZY_OR_NOW		RTLD_LAZY
+#  else
+#    ifdef DL_LAZY
+#      define LT_DLLAZY_OR_NOW		DL_LAZY
+#    else
+#      ifdef RTLD_NOW
+#        define LT_DLLAZY_OR_NOW	RTLD_NOW
+#      else
+#        ifdef DL_NOW
+#          define LT_DLLAZY_OR_NOW	DL_NOW
+#        else
+#          define LT_DLLAZY_OR_NOW	0
+#        endif
+#      endif
+#    endif
+#  endif
+#endif
+
+/* When -fvisibility=hidden is used, assume the code has been annotated
+   correspondingly for the symbols needed.  */
+#if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))
+int fnord () __attribute__((visibility("default")));
+#endif
+
+int fnord () { return 42; }
+int main ()
+{
+  void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
+  int status = $lt_dlunknown;
+
+  if (self)
+    {
+      if (dlsym (self,"fnord"))       status = $lt_dlno_uscore;
+      else
+        {
+	  if (dlsym( self,"_fnord"))  status = $lt_dlneed_uscore;
+          else puts (dlerror ());
+	}
+      /* dlclose (self); */
+    }
+  else
+    puts (dlerror ());
+
+  return status;
+}]
+_LT_EOF
+  if AC_TRY_EVAL(ac_link) && test -s "conftest$ac_exeext" 2>/dev/null; then
+    (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null
+    lt_status=$?
+    case x$lt_status in
+      x$lt_dlno_uscore) $1 ;;
+      x$lt_dlneed_uscore) $2 ;;
+      x$lt_dlunknown|x*) $3 ;;
+    esac
+  else :
+    # compilation failed
+    $3
+  fi
+fi
+rm -fr conftest*
+])# _LT_TRY_DLOPEN_SELF
+
+
+# LT_SYS_DLOPEN_SELF
+# ------------------
+AC_DEFUN([LT_SYS_DLOPEN_SELF],
+[m4_require([_LT_HEADER_DLFCN])dnl
+if test yes != "$enable_dlopen"; then
+  enable_dlopen=unknown
+  enable_dlopen_self=unknown
+  enable_dlopen_self_static=unknown
+else
+  lt_cv_dlopen=no
+  lt_cv_dlopen_libs=
+
+  case $host_os in
+  beos*)
+    lt_cv_dlopen=load_add_on
+    lt_cv_dlopen_libs=
+    lt_cv_dlopen_self=yes
+    ;;
+
+  mingw* | pw32* | cegcc*)
+    lt_cv_dlopen=LoadLibrary
+    lt_cv_dlopen_libs=
+    ;;
+
+  cygwin*)
+    lt_cv_dlopen=dlopen
+    lt_cv_dlopen_libs=
+    ;;
+
+  darwin*)
+    # if libdl is installed we need to link against it
+    AC_CHECK_LIB([dl], [dlopen],
+		[lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl],[
+    lt_cv_dlopen=dyld
+    lt_cv_dlopen_libs=
+    lt_cv_dlopen_self=yes
+    ])
+    ;;
+
+  tpf*)
+    # Don't try to run any link tests for TPF.  We know it's impossible
+    # because TPF is a cross-compiler, and we know how we open DSOs.
+    lt_cv_dlopen=dlopen
+    lt_cv_dlopen_libs=
+    lt_cv_dlopen_self=no
+    ;;
+
+  *)
+    AC_CHECK_FUNC([shl_load],
+	  [lt_cv_dlopen=shl_load],
+      [AC_CHECK_LIB([dld], [shl_load],
+	    [lt_cv_dlopen=shl_load lt_cv_dlopen_libs=-ldld],
+	[AC_CHECK_FUNC([dlopen],
+	      [lt_cv_dlopen=dlopen],
+	  [AC_CHECK_LIB([dl], [dlopen],
+		[lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl],
+	    [AC_CHECK_LIB([svld], [dlopen],
+		  [lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-lsvld],
+	      [AC_CHECK_LIB([dld], [dld_link],
+		    [lt_cv_dlopen=dld_link lt_cv_dlopen_libs=-ldld])
+	      ])
+	    ])
+	  ])
+	])
+      ])
+    ;;
+  esac
+
+  if test no = "$lt_cv_dlopen"; then
+    enable_dlopen=no
+  else
+    enable_dlopen=yes
+  fi
+
+  case $lt_cv_dlopen in
+  dlopen)
+    save_CPPFLAGS=$CPPFLAGS
+    test yes = "$ac_cv_header_dlfcn_h" && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H"
+
+    save_LDFLAGS=$LDFLAGS
+    wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\"
+
+    save_LIBS=$LIBS
+    LIBS="$lt_cv_dlopen_libs $LIBS"
+
+    AC_CACHE_CHECK([whether a program can dlopen itself],
+	  lt_cv_dlopen_self, [dnl
+	  _LT_TRY_DLOPEN_SELF(
+	    lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes,
+	    lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross)
+    ])
+
+    if test yes = "$lt_cv_dlopen_self"; then
+      wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\"
+      AC_CACHE_CHECK([whether a statically linked program can dlopen itself],
+	  lt_cv_dlopen_self_static, [dnl
+	  _LT_TRY_DLOPEN_SELF(
+	    lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes,
+	    lt_cv_dlopen_self_static=no,  lt_cv_dlopen_self_static=cross)
+      ])
+    fi
+
+    CPPFLAGS=$save_CPPFLAGS
+    LDFLAGS=$save_LDFLAGS
+    LIBS=$save_LIBS
+    ;;
+  esac
+
+  case $lt_cv_dlopen_self in
+  yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;;
+  *) enable_dlopen_self=unknown ;;
+  esac
+
+  case $lt_cv_dlopen_self_static in
+  yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;;
+  *) enable_dlopen_self_static=unknown ;;
+  esac
+fi
+_LT_DECL([dlopen_support], [enable_dlopen], [0],
+	 [Whether dlopen is supported])
+_LT_DECL([dlopen_self], [enable_dlopen_self], [0],
+	 [Whether dlopen of programs is supported])
+_LT_DECL([dlopen_self_static], [enable_dlopen_self_static], [0],
+	 [Whether dlopen of statically linked programs is supported])
+])# LT_SYS_DLOPEN_SELF
+
+# Old name:
+AU_ALIAS([AC_LIBTOOL_DLOPEN_SELF], [LT_SYS_DLOPEN_SELF])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], [])
+
+
+# _LT_COMPILER_C_O([TAGNAME])
+# ---------------------------
+# Check to see if options -c and -o are simultaneously supported by compiler.
+# This macro does not hard code the compiler like AC_PROG_CC_C_O.
+m4_defun([_LT_COMPILER_C_O],
+[m4_require([_LT_DECL_SED])dnl
+m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_TAG_COMPILER])dnl
+AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext],
+  [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)],
+  [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no
+   $RM -r conftest 2>/dev/null
+   mkdir conftest
+   cd conftest
+   mkdir out
+   echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+   lt_compiler_flag="-o out/conftest2.$ac_objext"
+   # Insert the option either (1) after the last *FLAGS variable, or
+   # (2) before a word containing "conftest.", or (3) at the end.
+   # Note that $ac_compile itself does not contain backslashes and begins
+   # with a dollar sign (not a hyphen), so the echo should work correctly.
+   lt_compile=`echo "$ac_compile" | $SED \
+   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+   -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \
+   -e 's:$: $lt_compiler_flag:'`
+   (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD)
+   (eval "$lt_compile" 2>out/conftest.err)
+   ac_status=$?
+   cat out/conftest.err >&AS_MESSAGE_LOG_FD
+   echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD
+   if (exit $ac_status) && test -s out/conftest2.$ac_objext
+   then
+     # The compiler can only warn and ignore the option if not recognized
+     # So say no if there are warnings
+     $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp
+     $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
+     if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
+       _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes
+     fi
+   fi
+   chmod u+w . 2>&AS_MESSAGE_LOG_FD
+   $RM conftest*
+   # SGI C++ compiler will create directory out/ii_files/ for
+   # template instantiation
+   test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files
+   $RM out/* && rmdir out
+   cd ..
+   $RM -r conftest
+   $RM conftest*
+])
+_LT_TAGDECL([compiler_c_o], [lt_cv_prog_compiler_c_o], [1],
+	[Does compiler simultaneously support -c and -o options?])
+])# _LT_COMPILER_C_O
+
+
+# _LT_COMPILER_FILE_LOCKS([TAGNAME])
+# ----------------------------------
+# Check to see if we can do hard links to lock some files if needed
+m4_defun([_LT_COMPILER_FILE_LOCKS],
+[m4_require([_LT_ENABLE_LOCK])dnl
+m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+_LT_COMPILER_C_O([$1])
+
+hard_links=nottested
+if test no = "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" && test no != "$need_locks"; then
+  # do not overwrite the value of need_locks provided by the user
+  AC_MSG_CHECKING([if we can lock with hard links])
+  hard_links=yes
+  $RM conftest*
+  ln conftest.a conftest.b 2>/dev/null && hard_links=no
+  touch conftest.a
+  ln conftest.a conftest.b 2>&5 || hard_links=no
+  ln conftest.a conftest.b 2>/dev/null && hard_links=no
+  AC_MSG_RESULT([$hard_links])
+  if test no = "$hard_links"; then
+    AC_MSG_WARN(['$CC' does not support '-c -o', so 'make -j' may be unsafe])
+    need_locks=warn
+  fi
+else
+  need_locks=no
+fi
+_LT_DECL([], [need_locks], [1], [Must we lock files when doing compilation?])
+])# _LT_COMPILER_FILE_LOCKS
+
+
+# _LT_CHECK_OBJDIR
+# ----------------
+m4_defun([_LT_CHECK_OBJDIR],
+[AC_CACHE_CHECK([for objdir], [lt_cv_objdir],
+[rm -f .libs 2>/dev/null
+mkdir .libs 2>/dev/null
+if test -d .libs; then
+  lt_cv_objdir=.libs
+else
+  # MS-DOS does not allow filenames that begin with a dot.
+  lt_cv_objdir=_libs
+fi
+rmdir .libs 2>/dev/null])
+objdir=$lt_cv_objdir
+_LT_DECL([], [objdir], [0],
+         [The name of the directory that contains temporary libtool files])dnl
+m4_pattern_allow([LT_OBJDIR])dnl
+AC_DEFINE_UNQUOTED([LT_OBJDIR], "$lt_cv_objdir/",
+  [Define to the sub-directory where libtool stores uninstalled libraries.])
+])# _LT_CHECK_OBJDIR
+
+
+# _LT_LINKER_HARDCODE_LIBPATH([TAGNAME])
+# --------------------------------------
+# Check hardcoding attributes.
+m4_defun([_LT_LINKER_HARDCODE_LIBPATH],
+[AC_MSG_CHECKING([how to hardcode library paths into programs])
+_LT_TAGVAR(hardcode_action, $1)=
+if test -n "$_LT_TAGVAR(hardcode_libdir_flag_spec, $1)" ||
+   test -n "$_LT_TAGVAR(runpath_var, $1)" ||
+   test yes = "$_LT_TAGVAR(hardcode_automatic, $1)"; then
+
+  # We can hardcode non-existent directories.
+  if test no != "$_LT_TAGVAR(hardcode_direct, $1)" &&
+     # If the only mechanism to avoid hardcoding is shlibpath_var, we
+     # have to relink, otherwise we might link with an installed library
+     # when we should be linking with a yet-to-be-installed one
+     ## test no != "$_LT_TAGVAR(hardcode_shlibpath_var, $1)" &&
+     test no != "$_LT_TAGVAR(hardcode_minus_L, $1)"; then
+    # Linking always hardcodes the temporary library directory.
+    _LT_TAGVAR(hardcode_action, $1)=relink
+  else
+    # We can link without hardcoding, and we can hardcode nonexisting dirs.
+    _LT_TAGVAR(hardcode_action, $1)=immediate
+  fi
+else
+  # We cannot hardcode anything, or else we can only hardcode existing
+  # directories.
+  _LT_TAGVAR(hardcode_action, $1)=unsupported
+fi
+AC_MSG_RESULT([$_LT_TAGVAR(hardcode_action, $1)])
+
+if test relink = "$_LT_TAGVAR(hardcode_action, $1)" ||
+   test yes = "$_LT_TAGVAR(inherit_rpath, $1)"; then
+  # Fast installation is not supported
+  enable_fast_install=no
+elif test yes = "$shlibpath_overrides_runpath" ||
+     test no = "$enable_shared"; then
+  # Fast installation is not necessary
+  enable_fast_install=needless
+fi
+_LT_TAGDECL([], [hardcode_action], [0],
+    [How to hardcode a shared library path into an executable])
+])# _LT_LINKER_HARDCODE_LIBPATH
+
+
+# _LT_CMD_STRIPLIB
+# ----------------
+m4_defun([_LT_CMD_STRIPLIB],
+[m4_require([_LT_DECL_EGREP])
+striplib=
+old_striplib=
+AC_MSG_CHECKING([whether stripping libraries is possible])
+if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then
+  test -z "$old_striplib" && old_striplib="$STRIP --strip-debug"
+  test -z "$striplib" && striplib="$STRIP --strip-unneeded"
+  AC_MSG_RESULT([yes])
+else
+# FIXME - insert some real tests, host_os isn't really good enough
+  case $host_os in
+  darwin*)
+    if test -n "$STRIP"; then
+      striplib="$STRIP -x"
+      old_striplib="$STRIP -S"
+      AC_MSG_RESULT([yes])
+    else
+      AC_MSG_RESULT([no])
+    fi
+    ;;
+  *)
+    AC_MSG_RESULT([no])
+    ;;
+  esac
+fi
+_LT_DECL([], [old_striplib], [1], [Commands to strip libraries])
+_LT_DECL([], [striplib], [1])
+])# _LT_CMD_STRIPLIB
+
+
+# _LT_PREPARE_MUNGE_PATH_LIST
+# ---------------------------
+# Make sure func_munge_path_list() is defined correctly.
+m4_defun([_LT_PREPARE_MUNGE_PATH_LIST],
+[[# func_munge_path_list VARIABLE PATH
+# -----------------------------------
+# VARIABLE is name of variable containing _space_ separated list of
+# directories to be munged by the contents of PATH, which is string
+# having a format:
+# "DIR[:DIR]:"
+#       string "DIR[ DIR]" will be prepended to VARIABLE
+# ":DIR[:DIR]"
+#       string "DIR[ DIR]" will be appended to VARIABLE
+# "DIRP[:DIRP]::[DIRA:]DIRA"
+#       string "DIRP[ DIRP]" will be prepended to VARIABLE and string
+#       "DIRA[ DIRA]" will be appended to VARIABLE
+# "DIR[:DIR]"
+#       VARIABLE will be replaced by "DIR[ DIR]"
+func_munge_path_list ()
+{
+    case x@S|@2 in
+    x)
+        ;;
+    *:)
+        eval @S|@1=\"`$ECHO @S|@2 | $SED 's/:/ /g'` \@S|@@S|@1\"
+        ;;
+    x:*)
+        eval @S|@1=\"\@S|@@S|@1 `$ECHO @S|@2 | $SED 's/:/ /g'`\"
+        ;;
+    *::*)
+        eval @S|@1=\"\@S|@@S|@1\ `$ECHO @S|@2 | $SED -e 's/.*:://' -e 's/:/ /g'`\"
+        eval @S|@1=\"`$ECHO @S|@2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \@S|@@S|@1\"
+        ;;
+    *)
+        eval @S|@1=\"`$ECHO @S|@2 | $SED 's/:/ /g'`\"
+        ;;
+    esac
+}
+]])# _LT_PREPARE_PATH_LIST
+
+
+# _LT_SYS_DYNAMIC_LINKER([TAG])
+# -----------------------------
+# PORTME Fill in your ld.so characteristics
+m4_defun([_LT_SYS_DYNAMIC_LINKER],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+m4_require([_LT_DECL_EGREP])dnl
+m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_DECL_OBJDUMP])dnl
+m4_require([_LT_DECL_SED])dnl
+m4_require([_LT_CHECK_SHELL_FEATURES])dnl
+m4_require([_LT_PREPARE_MUNGE_PATH_LIST])dnl
+AC_MSG_CHECKING([dynamic linker characteristics])
+m4_if([$1],
+	[], [
+if test yes = "$GCC"; then
+  case $host_os in
+    darwin*) lt_awk_arg='/^libraries:/,/LR/' ;;
+    *) lt_awk_arg='/^libraries:/' ;;
+  esac
+  case $host_os in
+    mingw* | cegcc*) lt_sed_strip_eq='s|=\([[A-Za-z]]:\)|\1|g' ;;
+    *) lt_sed_strip_eq='s|=/|/|g' ;;
+  esac
+  lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq`
+  case $lt_search_path_spec in
+  *\;*)
+    # if the path contains ";" then we assume it to be the separator
+    # otherwise default to the standard path separator (i.e. ":") - it is
+    # assumed that no part of a normal pathname contains ";" but that should
+    # okay in the real world where ";" in dirpaths is itself problematic.
+    lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'`
+    ;;
+  *)
+    lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"`
+    ;;
+  esac
+  # Ok, now we have the path, separated by spaces, we can step through it
+  # and add multilib dir if necessary...
+  lt_tmp_lt_search_path_spec=
+  lt_multi_os_dir=/`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null`
+  # ...but if some path component already ends with the multilib dir we assume
+  # that all is fine and trust -print-search-dirs as is (GCC 4.2? or newer).
+  case "$lt_multi_os_dir; $lt_search_path_spec " in
+  "/; "* | "/.; "* | "/./; "* | *"$lt_multi_os_dir "* | *"$lt_multi_os_dir/ "*)
+    lt_multi_os_dir=
+    ;;
+  esac
+  for lt_sys_path in $lt_search_path_spec; do
+    if test -d "$lt_sys_path$lt_multi_os_dir"; then
+      lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path$lt_multi_os_dir"
+    elif test -n "$lt_multi_os_dir"; then
+      test -d "$lt_sys_path" && \
+	lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path"
+    fi
+  done
+  lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk '
+BEGIN {RS = " "; FS = "/|\n";} {
+  lt_foo = "";
+  lt_count = 0;
+  for (lt_i = NF; lt_i > 0; lt_i--) {
+    if ($lt_i != "" && $lt_i != ".") {
+      if ($lt_i == "..") {
+        lt_count++;
+      } else {
+        if (lt_count == 0) {
+          lt_foo = "/" $lt_i lt_foo;
+        } else {
+          lt_count--;
+        }
+      }
+    }
+  }
+  if (lt_foo != "") { lt_freq[[lt_foo]]++; }
+  if (lt_freq[[lt_foo]] == 1) { print lt_foo; }
+}'`
+  # AWK program above erroneously prepends '/' to C:/dos/paths
+  # for these hosts.
+  case $host_os in
+    mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\
+      $SED 's|/\([[A-Za-z]]:\)|\1|g'` ;;
+  esac
+  sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP`
+else
+  sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
+fi])
+library_names_spec=
+libname_spec='lib$name'
+soname_spec=
+shrext_cmds=.so
+postinstall_cmds=
+postuninstall_cmds=
+finish_cmds=
+finish_eval=
+shlibpath_var=
+shlibpath_overrides_runpath=unknown
+version_type=none
+dynamic_linker="$host_os ld.so"
+sys_lib_dlsearch_path_spec="/lib /usr/lib"
+need_lib_prefix=unknown
+hardcode_into_libs=no
+
+# when you set need_version to no, make sure it does not cause -set_version
+# flags to be left without arguments
+need_version=unknown
+
+AC_ARG_VAR([LT_SYS_LIBRARY_PATH],
+[User-defined run-time library search path.])
+
+case $host_os in
+aix3*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  library_names_spec='$libname$release$shared_ext$versuffix $libname.a'
+  shlibpath_var=LIBPATH
+
+  # AIX 3 has no versioning support, so we append a major version to the name.
+  soname_spec='$libname$release$shared_ext$major'
+  ;;
+
+aix[[4-9]]*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  need_lib_prefix=no
+  need_version=no
+  hardcode_into_libs=yes
+  if test ia64 = "$host_cpu"; then
+    # AIX 5 supports IA64
+    library_names_spec='$libname$release$shared_ext$major $libname$release$shared_ext$versuffix $libname$shared_ext'
+    shlibpath_var=LD_LIBRARY_PATH
+  else
+    # With GCC up to 2.95.x, collect2 would create an import file
+    # for dependence libraries.  The import file would start with
+    # the line '#! .'.  This would cause the generated library to
+    # depend on '.', always an invalid library.  This was fixed in
+    # development snapshots of GCC prior to 3.0.
+    case $host_os in
+      aix4 | aix4.[[01]] | aix4.[[01]].*)
+      if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)'
+	   echo ' yes '
+	   echo '#endif'; } | $CC -E - | $GREP yes > /dev/null; then
+	:
+      else
+	can_build_shared=no
+      fi
+      ;;
+    esac
+    # Using Import Files as archive members, it is possible to support
+    # filename-based versioning of shared library archives on AIX. While
+    # this would work for both with and without runtime linking, it will
+    # prevent static linking of such archives. So we do filename-based
+    # shared library versioning with .so extension only, which is used
+    # when both runtime linking and shared linking is enabled.
+    # Unfortunately, runtime linking may impact performance, so we do
+    # not want this to be the default eventually. Also, we use the
+    # versioned .so libs for executables only if there is the -brtl
+    # linker flag in LDFLAGS as well, or --with-aix-soname=svr4 only.
+    # To allow for filename-based versioning support, we need to create
+    # libNAME.so.V as an archive file, containing:
+    # *) an Import File, referring to the versioned filename of the
+    #    archive as well as the shared archive member, telling the
+    #    bitwidth (32 or 64) of that shared object, and providing the
+    #    list of exported symbols of that shared object, eventually
+    #    decorated with the 'weak' keyword
+    # *) the shared object with the F_LOADONLY flag set, to really avoid
+    #    it being seen by the linker.
+    # At run time we better use the real file rather than another symlink,
+    # but for link time we create the symlink libNAME.so -> libNAME.so.V
+
+    case $with_aix_soname,$aix_use_runtimelinking in
+    # AIX (on Power*) has no versioning support, so currently we cannot hardcode correct
+    # soname into executable. Probably we can add versioning support to
+    # collect2, so additional links can be useful in future.
+    aix,yes) # traditional libtool
+      dynamic_linker='AIX unversionable lib.so'
+      # If using run time linking (on AIX 4.2 or later) use lib<name>.so
+      # instead of lib<name>.a to let people know that these are not
+      # typical AIX shared libraries.
+      library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+      ;;
+    aix,no) # traditional AIX only
+      dynamic_linker='AIX lib.a[(]lib.so.V[)]'
+      # We preserve .a as extension for shared libraries through AIX4.2
+      # and later when we are not doing run time linking.
+      library_names_spec='$libname$release.a $libname.a'
+      soname_spec='$libname$release$shared_ext$major'
+      ;;
+    svr4,*) # full svr4 only
+      dynamic_linker="AIX lib.so.V[(]$shared_archive_member_spec.o[)]"
+      library_names_spec='$libname$release$shared_ext$major $libname$shared_ext'
+      # We do not specify a path in Import Files, so LIBPATH fires.
+      shlibpath_overrides_runpath=yes
+      ;;
+    *,yes) # both, prefer svr4
+      dynamic_linker="AIX lib.so.V[(]$shared_archive_member_spec.o[)], lib.a[(]lib.so.V[)]"
+      library_names_spec='$libname$release$shared_ext$major $libname$shared_ext'
+      # unpreferred sharedlib libNAME.a needs extra handling
+      postinstall_cmds='test -n "$linkname" || linkname="$realname"~func_stripname "" ".so" "$linkname"~$install_shared_prog "$dir/$func_stripname_result.$libext" "$destdir/$func_stripname_result.$libext"~test -z "$tstripme" || test -z "$striplib" || $striplib "$destdir/$func_stripname_result.$libext"'
+      postuninstall_cmds='for n in $library_names $old_library; do :; done~func_stripname "" ".so" "$n"~test "$func_stripname_result" = "$n" || func_append rmfiles " $odir/$func_stripname_result.$libext"'
+      # We do not specify a path in Import Files, so LIBPATH fires.
+      shlibpath_overrides_runpath=yes
+      ;;
+    *,no) # both, prefer aix
+      dynamic_linker="AIX lib.a[(]lib.so.V[)], lib.so.V[(]$shared_archive_member_spec.o[)]"
+      library_names_spec='$libname$release.a $libname.a'
+      soname_spec='$libname$release$shared_ext$major'
+      # unpreferred sharedlib libNAME.so.V and symlink libNAME.so need extra handling
+      postinstall_cmds='test -z "$dlname" || $install_shared_prog $dir/$dlname $destdir/$dlname~test -z "$tstripme" || test -z "$striplib" || $striplib $destdir/$dlname~test -n "$linkname" || linkname=$realname~func_stripname "" ".a" "$linkname"~(cd "$destdir" && $LN_S -f $dlname $func_stripname_result.so)'
+      postuninstall_cmds='test -z "$dlname" || func_append rmfiles " $odir/$dlname"~for n in $old_library $library_names; do :; done~func_stripname "" ".a" "$n"~func_append rmfiles " $odir/$func_stripname_result.so"'
+      ;;
+    esac
+    shlibpath_var=LIBPATH
+  fi
+  ;;
+
+amigaos*)
+  case $host_cpu in
+  powerpc)
+    # Since July 2007 AmigaOS4 officially supports .so libraries.
+    # When compiling the executable, add -use-dynld -Lsobjs: to the compileline.
+    library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+    ;;
+  m68k)
+    library_names_spec='$libname.ixlibrary $libname.a'
+    # Create ${libname}_ixlibrary.a entries in /sys/libs.
+    finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
+    ;;
+  esac
+  ;;
+
+beos*)
+  library_names_spec='$libname$shared_ext'
+  dynamic_linker="$host_os ld.so"
+  shlibpath_var=LIBRARY_PATH
+  ;;
+
+bsdi[[45]]*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  need_version=no
+  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+  soname_spec='$libname$release$shared_ext$major'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
+  sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib"
+  # the default ld.so.conf also contains /usr/contrib/lib and
+  # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow
+  # libtool to hard-code these into programs
+  ;;
+
+cygwin* | mingw* | pw32* | cegcc*)
+  version_type=windows
+  shrext_cmds=.dll
+  need_version=no
+  need_lib_prefix=no
+
+  case $GCC,$cc_basename in
+  yes,*)
+    # gcc
+    library_names_spec='$libname.dll.a'
+    # DLL is installed to $(libdir)/../bin by postinstall_cmds
+    postinstall_cmds='base_file=`basename \$file`~
+      dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~
+      dldir=$destdir/`dirname \$dlpath`~
+      test -d \$dldir || mkdir -p \$dldir~
+      $install_prog $dir/$dlname \$dldir/$dlname~
+      chmod a+x \$dldir/$dlname~
+      if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then
+        eval '\''$striplib \$dldir/$dlname'\'' || exit \$?;
+      fi'
+    postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+      dlpath=$dir/\$dldll~
+       $RM \$dlpath'
+    shlibpath_overrides_runpath=yes
+
+    case $host_os in
+    cygwin*)
+      # Cygwin DLLs use 'cyg' prefix rather than 'lib'
+      soname_spec='`echo $libname | sed -e 's/^lib/cyg/'``echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext'
+m4_if([$1], [],[
+      sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"])
+      ;;
+    mingw* | cegcc*)
+      # MinGW DLLs use traditional 'lib' prefix
+      soname_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext'
+      ;;
+    pw32*)
+      # pw32 DLLs use 'pw' prefix rather than 'lib'
+      library_names_spec='`echo $libname | sed -e 's/^lib/pw/'``echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext'
+      ;;
+    esac
+    dynamic_linker='Win32 ld.exe'
+    ;;
+
+  *,cl*)
+    # Native MSVC
+    libname_spec='$name'
+    soname_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext'
+    library_names_spec='$libname.dll.lib'
+
+    case $build_os in
+    mingw*)
+      sys_lib_search_path_spec=
+      lt_save_ifs=$IFS
+      IFS=';'
+      for lt_path in $LIB
+      do
+        IFS=$lt_save_ifs
+        # Let DOS variable expansion print the short 8.3 style file name.
+        lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"`
+        sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path"
+      done
+      IFS=$lt_save_ifs
+      # Convert to MSYS style.
+      sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([[a-zA-Z]]\\):| /\\1|g' -e 's|^ ||'`
+      ;;
+    cygwin*)
+      # Convert to unix form, then to dos form, then back to unix form
+      # but this time dos style (no spaces!) so that the unix form looks
+      # like /cygdrive/c/PROGRA~1:/cygdr...
+      sys_lib_search_path_spec=`cygpath --path --unix "$LIB"`
+      sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null`
+      sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
+      ;;
+    *)
+      sys_lib_search_path_spec=$LIB
+      if $ECHO "$sys_lib_search_path_spec" | [$GREP ';[c-zC-Z]:/' >/dev/null]; then
+        # It is most probably a Windows format PATH.
+        sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
+      else
+        sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
+      fi
+      # FIXME: find the short name or the path components, as spaces are
+      # common. (e.g. "Program Files" -> "PROGRA~1")
+      ;;
+    esac
+
+    # DLL is installed to $(libdir)/../bin by postinstall_cmds
+    postinstall_cmds='base_file=`basename \$file`~
+      dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~
+      dldir=$destdir/`dirname \$dlpath`~
+      test -d \$dldir || mkdir -p \$dldir~
+      $install_prog $dir/$dlname \$dldir/$dlname'
+    postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+      dlpath=$dir/\$dldll~
+       $RM \$dlpath'
+    shlibpath_overrides_runpath=yes
+    dynamic_linker='Win32 link.exe'
+    ;;
+
+  *)
+    # Assume MSVC wrapper
+    library_names_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext $libname.lib'
+    dynamic_linker='Win32 ld.exe'
+    ;;
+  esac
+  # FIXME: first we should search . and the directory the executable is in
+  shlibpath_var=PATH
+  ;;
+
+darwin* | rhapsody*)
+  dynamic_linker="$host_os dyld"
+  version_type=darwin
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='$libname$release$major$shared_ext $libname$shared_ext'
+  soname_spec='$libname$release$major$shared_ext'
+  shlibpath_overrides_runpath=yes
+  shlibpath_var=DYLD_LIBRARY_PATH
+  shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`'
+m4_if([$1], [],[
+  sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"])
+  sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib'
+  ;;
+
+dgux*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+  soname_spec='$libname$release$shared_ext$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+freebsd* | dragonfly*)
+  # DragonFly does not have aout.  When/if they implement a new
+  # versioning mechanism, adjust this.
+  if test -x /usr/bin/objformat; then
+    objformat=`/usr/bin/objformat`
+  else
+    case $host_os in
+    freebsd[[23]].*) objformat=aout ;;
+    *) objformat=elf ;;
+    esac
+  fi
+  version_type=freebsd-$objformat
+  case $version_type in
+    freebsd-elf*)
+      library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+      soname_spec='$libname$release$shared_ext$major'
+      need_version=no
+      need_lib_prefix=no
+      ;;
+    freebsd-*)
+      library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'
+      need_version=yes
+      ;;
+  esac
+  shlibpath_var=LD_LIBRARY_PATH
+  case $host_os in
+  freebsd2.*)
+    shlibpath_overrides_runpath=yes
+    ;;
+  freebsd3.[[01]]* | freebsdelf3.[[01]]*)
+    shlibpath_overrides_runpath=yes
+    hardcode_into_libs=yes
+    ;;
+  freebsd3.[[2-9]]* | freebsdelf3.[[2-9]]* | \
+  freebsd4.[[0-5]] | freebsdelf4.[[0-5]] | freebsd4.1.1 | freebsdelf4.1.1)
+    shlibpath_overrides_runpath=no
+    hardcode_into_libs=yes
+    ;;
+  *) # from 4.6 on, and DragonFly
+    shlibpath_overrides_runpath=yes
+    hardcode_into_libs=yes
+    ;;
+  esac
+  ;;
+
+haiku*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  need_lib_prefix=no
+  need_version=no
+  dynamic_linker="$host_os runtime_loader"
+  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+  soname_spec='$libname$release$shared_ext$major'
+  shlibpath_var=LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib'
+  hardcode_into_libs=yes
+  ;;
+
+hpux9* | hpux10* | hpux11*)
+  # Give a soname corresponding to the major version so that dld.sl refuses to
+  # link against other versions.
+  version_type=sunos
+  need_lib_prefix=no
+  need_version=no
+  case $host_cpu in
+  ia64*)
+    shrext_cmds='.so'
+    hardcode_into_libs=yes
+    dynamic_linker="$host_os dld.so"
+    shlibpath_var=LD_LIBRARY_PATH
+    shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+    library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+    soname_spec='$libname$release$shared_ext$major'
+    if test 32 = "$HPUX_IA64_MODE"; then
+      sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib"
+      sys_lib_dlsearch_path_spec=/usr/lib/hpux32
+    else
+      sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64"
+      sys_lib_dlsearch_path_spec=/usr/lib/hpux64
+    fi
+    ;;
+  hppa*64*)
+    shrext_cmds='.sl'
+    hardcode_into_libs=yes
+    dynamic_linker="$host_os dld.sl"
+    shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH
+    shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+    library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+    soname_spec='$libname$release$shared_ext$major'
+    sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64"
+    sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+    ;;
+  *)
+    shrext_cmds='.sl'
+    dynamic_linker="$host_os dld.sl"
+    shlibpath_var=SHLIB_PATH
+    shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
+    library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+    soname_spec='$libname$release$shared_ext$major'
+    ;;
+  esac
+  # HP-UX runs *really* slowly unless shared libraries are mode 555, ...
+  postinstall_cmds='chmod 555 $lib'
+  # or fails outright, so override atomically:
+  install_override_mode=555
+  ;;
+
+interix[[3-9]]*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+  soname_spec='$libname$release$shared_ext$major'
+  dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  ;;
+
+irix5* | irix6* | nonstopux*)
+  case $host_os in
+    nonstopux*) version_type=nonstopux ;;
+    *)
+	if test yes = "$lt_cv_prog_gnu_ld"; then
+		version_type=linux # correct to gnu/linux during the next big refactor
+	else
+		version_type=irix
+	fi ;;
+  esac
+  need_lib_prefix=no
+  need_version=no
+  soname_spec='$libname$release$shared_ext$major'
+  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$release$shared_ext $libname$shared_ext'
+  case $host_os in
+  irix5* | nonstopux*)
+    libsuff= shlibsuff=
+    ;;
+  *)
+    case $LD in # libtool.m4 will add one of these switches to LD
+    *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ")
+      libsuff= shlibsuff= libmagic=32-bit;;
+    *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ")
+      libsuff=32 shlibsuff=N32 libmagic=N32;;
+    *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ")
+      libsuff=64 shlibsuff=64 libmagic=64-bit;;
+    *) libsuff= shlibsuff= libmagic=never-match;;
+    esac
+    ;;
+  esac
+  shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
+  shlibpath_overrides_runpath=no
+  sys_lib_search_path_spec="/usr/lib$libsuff /lib$libsuff /usr/local/lib$libsuff"
+  sys_lib_dlsearch_path_spec="/usr/lib$libsuff /lib$libsuff"
+  hardcode_into_libs=yes
+  ;;
+
+# No shared lib support for Linux oldld, aout, or coff.
+linux*oldld* | linux*aout* | linux*coff*)
+  dynamic_linker=no
+  ;;
+
+linux*android*)
+  version_type=none # Android doesn't support versioned libraries.
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='$libname$release$shared_ext'
+  soname_spec='$libname$release$shared_ext'
+  finish_cmds=
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+
+  # This implies no fast_install, which is unacceptable.
+  # Some rework will be needed to allow for fast_install
+  # before this can be enabled.
+  hardcode_into_libs=yes
+
+  dynamic_linker='Android linker'
+  # Don't embed -rpath directories since the linker doesn't support them.
+  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+  ;;
+
+# This must be glibc/ELF.
+linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+  soname_spec='$libname$release$shared_ext$major'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+
+  # Some binutils ld are patched to set DT_RUNPATH
+  AC_CACHE_VAL([lt_cv_shlibpath_overrides_runpath],
+    [lt_cv_shlibpath_overrides_runpath=no
+    save_LDFLAGS=$LDFLAGS
+    save_libdir=$libdir
+    eval "libdir=/foo; wl=\"$_LT_TAGVAR(lt_prog_compiler_wl, $1)\"; \
+	 LDFLAGS=\"\$LDFLAGS $_LT_TAGVAR(hardcode_libdir_flag_spec, $1)\""
+    AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])],
+      [AS_IF([ ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null],
+	 [lt_cv_shlibpath_overrides_runpath=yes])])
+    LDFLAGS=$save_LDFLAGS
+    libdir=$save_libdir
+    ])
+  shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath
+
+  # This implies no fast_install, which is unacceptable.
+  # Some rework will be needed to allow for fast_install
+  # before this can be enabled.
+  hardcode_into_libs=yes
+
+  # Ideally, we could use ldconfig to report *all* directores which are
+  # searched for libraries, however this is still not possible.  Aside from not
+  # being certain /sbin/ldconfig is available, command
+  # 'ldconfig -N -X -v | grep ^/' on 64bit Fedora does not report /usr/lib64,
+  # even though it is searched at run-time.  Try to do the best guess by
+  # appending ld.so.conf contents (and includes) to the search path.
+  if test -f /etc/ld.so.conf; then
+    lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[	 ]*hwcap[	 ]/d;s/[:,	]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '`
+    sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra"
+  fi
+
+  # We used to test for /lib/ld.so.1 and disable shared libraries on
+  # powerpc, because MkLinux only supported shared libraries with the
+  # GNU dynamic linker.  Since this was broken with cross compilers,
+  # most powerpc-linux boxes support dynamic linking these days and
+  # people can always --disable-shared, the test was removed, and we
+  # assume the GNU/Linux dynamic linker is in use.
+  dynamic_linker='GNU/Linux ld.so'
+  ;;
+
+netbsdelf*-gnu)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  dynamic_linker='NetBSD ld.elf_so'
+  ;;
+
+netbsd*)
+  version_type=sunos
+  need_lib_prefix=no
+  need_version=no
+  if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+    library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'
+    finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+    dynamic_linker='NetBSD (a.out) ld.so'
+  else
+    library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+    soname_spec='$libname$release$shared_ext$major'
+    dynamic_linker='NetBSD ld.elf_so'
+  fi
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  hardcode_into_libs=yes
+  ;;
+
+newsos6)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  ;;
+
+*nto* | *qnx*)
+  version_type=qnx
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+  soname_spec='$libname$release$shared_ext$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  dynamic_linker='ldqnx.so'
+  ;;
+
+openbsd* | bitrig*)
+  version_type=sunos
+  sys_lib_dlsearch_path_spec=/usr/lib
+  need_lib_prefix=no
+  if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then
+    need_version=no
+  else
+    need_version=yes
+  fi
+  library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  ;;
+
+os2*)
+  libname_spec='$name'
+  version_type=windows
+  shrext_cmds=.dll
+  need_version=no
+  need_lib_prefix=no
+  # OS/2 can only load a DLL with a base name of 8 characters or less.
+  soname_spec='`test -n "$os2dllname" && libname="$os2dllname";
+    v=$($ECHO $release$versuffix | tr -d .-);
+    n=$($ECHO $libname | cut -b -$((8 - ${#v})) | tr . _);
+    $ECHO $n$v`$shared_ext'
+  library_names_spec='${libname}_dll.$libext'
+  dynamic_linker='OS/2 ld.exe'
+  shlibpath_var=BEGINLIBPATH
+  sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
+  sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+  postinstall_cmds='base_file=`basename \$file`~
+    dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; $ECHO \$dlname'\''`~
+    dldir=$destdir/`dirname \$dlpath`~
+    test -d \$dldir || mkdir -p \$dldir~
+    $install_prog $dir/$dlname \$dldir/$dlname~
+    chmod a+x \$dldir/$dlname~
+    if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then
+      eval '\''$striplib \$dldir/$dlname'\'' || exit \$?;
+    fi'
+  postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; $ECHO \$dlname'\''`~
+    dlpath=$dir/\$dldll~
+    $RM \$dlpath'
+  ;;
+
+osf3* | osf4* | osf5*)
+  version_type=osf
+  need_lib_prefix=no
+  need_version=no
+  soname_spec='$libname$release$shared_ext$major'
+  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+  shlibpath_var=LD_LIBRARY_PATH
+  sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
+  sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+  ;;
+
+rdos*)
+  dynamic_linker=no
+  ;;
+
+solaris*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+  soname_spec='$libname$release$shared_ext$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  hardcode_into_libs=yes
+  # ldd complains unless libraries are executable
+  postinstall_cmds='chmod +x $lib'
+  ;;
+
+sunos4*)
+  version_type=sunos
+  library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'
+  finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  if test yes = "$with_gnu_ld"; then
+    need_lib_prefix=no
+  fi
+  need_version=yes
+  ;;
+
+sysv4 | sysv4.3*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+  soname_spec='$libname$release$shared_ext$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  case $host_vendor in
+    sni)
+      shlibpath_overrides_runpath=no
+      need_lib_prefix=no
+      runpath_var=LD_RUN_PATH
+      ;;
+    siemens)
+      need_lib_prefix=no
+      ;;
+    motorola)
+      need_lib_prefix=no
+      need_version=no
+      shlibpath_overrides_runpath=no
+      sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib'
+      ;;
+  esac
+  ;;
+
+sysv4*MP*)
+  if test -d /usr/nec; then
+    version_type=linux # correct to gnu/linux during the next big refactor
+    library_names_spec='$libname$shared_ext.$versuffix $libname$shared_ext.$major $libname$shared_ext'
+    soname_spec='$libname$shared_ext.$major'
+    shlibpath_var=LD_LIBRARY_PATH
+  fi
+  ;;
+
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+  version_type=sco
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext $libname$shared_ext'
+  soname_spec='$libname$release$shared_ext$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  hardcode_into_libs=yes
+  if test yes = "$with_gnu_ld"; then
+    sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib'
+  else
+    sys_lib_search_path_spec='/usr/ccs/lib /usr/lib'
+    case $host_os in
+      sco3.2v5*)
+        sys_lib_search_path_spec="$sys_lib_search_path_spec /lib"
+	;;
+    esac
+  fi
+  sys_lib_dlsearch_path_spec='/usr/lib'
+  ;;
+
+tpf*)
+  # TPF is a cross-target only.  Preferred cross-host = GNU/Linux.
+  version_type=linux # correct to gnu/linux during the next big refactor
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  ;;
+
+uts4*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+  soname_spec='$libname$release$shared_ext$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+*)
+  dynamic_linker=no
+  ;;
+esac
+AC_MSG_RESULT([$dynamic_linker])
+test no = "$dynamic_linker" && can_build_shared=no
+
+variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
+if test yes = "$GCC"; then
+  variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
+fi
+
+if test set = "${lt_cv_sys_lib_search_path_spec+set}"; then
+  sys_lib_search_path_spec=$lt_cv_sys_lib_search_path_spec
+fi
+
+if test set = "${lt_cv_sys_lib_dlsearch_path_spec+set}"; then
+  sys_lib_dlsearch_path_spec=$lt_cv_sys_lib_dlsearch_path_spec
+fi
+
+# remember unaugmented sys_lib_dlsearch_path content for libtool script decls...
+configure_time_dlsearch_path=$sys_lib_dlsearch_path_spec
+
+# ... but it needs LT_SYS_LIBRARY_PATH munging for other configure-time code
+func_munge_path_list sys_lib_dlsearch_path_spec "$LT_SYS_LIBRARY_PATH"
+
+# to be used as default LT_SYS_LIBRARY_PATH value in generated libtool
+configure_time_lt_sys_library_path=$LT_SYS_LIBRARY_PATH
+
+_LT_DECL([], [variables_saved_for_relink], [1],
+    [Variables whose values should be saved in libtool wrapper scripts and
+    restored at link time])
+_LT_DECL([], [need_lib_prefix], [0],
+    [Do we need the "lib" prefix for modules?])
+_LT_DECL([], [need_version], [0], [Do we need a version for libraries?])
+_LT_DECL([], [version_type], [0], [Library versioning type])
+_LT_DECL([], [runpath_var], [0],  [Shared library runtime path variable])
+_LT_DECL([], [shlibpath_var], [0],[Shared library path variable])
+_LT_DECL([], [shlibpath_overrides_runpath], [0],
+    [Is shlibpath searched before the hard-coded library search path?])
+_LT_DECL([], [libname_spec], [1], [Format of library name prefix])
+_LT_DECL([], [library_names_spec], [1],
+    [[List of archive names.  First name is the real one, the rest are links.
+    The last name is the one that the linker finds with -lNAME]])
+_LT_DECL([], [soname_spec], [1],
+    [[The coded name of the library, if different from the real name]])
+_LT_DECL([], [install_override_mode], [1],
+    [Permission mode override for installation of shared libraries])
+_LT_DECL([], [postinstall_cmds], [2],
+    [Command to use after installation of a shared archive])
+_LT_DECL([], [postuninstall_cmds], [2],
+    [Command to use after uninstallation of a shared archive])
+_LT_DECL([], [finish_cmds], [2],
+    [Commands used to finish a libtool library installation in a directory])
+_LT_DECL([], [finish_eval], [1],
+    [[As "finish_cmds", except a single script fragment to be evaled but
+    not shown]])
+_LT_DECL([], [hardcode_into_libs], [0],
+    [Whether we should hardcode library paths into libraries])
+_LT_DECL([], [sys_lib_search_path_spec], [2],
+    [Compile-time system search path for libraries])
+_LT_DECL([sys_lib_dlsearch_path_spec], [configure_time_dlsearch_path], [2],
+    [Detected run-time system search path for libraries])
+_LT_DECL([], [configure_time_lt_sys_library_path], [2],
+    [Explicit LT_SYS_LIBRARY_PATH set during ./configure time])
+])# _LT_SYS_DYNAMIC_LINKER
+
+
+# _LT_PATH_TOOL_PREFIX(TOOL)
+# --------------------------
+# find a file program that can recognize shared library
+AC_DEFUN([_LT_PATH_TOOL_PREFIX],
+[m4_require([_LT_DECL_EGREP])dnl
+AC_MSG_CHECKING([for $1])
+AC_CACHE_VAL(lt_cv_path_MAGIC_CMD,
+[case $MAGIC_CMD in
+[[\\/*] |  ?:[\\/]*])
+  lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path.
+  ;;
+*)
+  lt_save_MAGIC_CMD=$MAGIC_CMD
+  lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR
+dnl $ac_dummy forces splitting on constant user-supplied paths.
+dnl POSIX.2 word splitting is done only on the output of word expansions,
+dnl not every word.  This closes a longstanding sh security hole.
+  ac_dummy="m4_if([$2], , $PATH, [$2])"
+  for ac_dir in $ac_dummy; do
+    IFS=$lt_save_ifs
+    test -z "$ac_dir" && ac_dir=.
+    if test -f "$ac_dir/$1"; then
+      lt_cv_path_MAGIC_CMD=$ac_dir/"$1"
+      if test -n "$file_magic_test_file"; then
+	case $deplibs_check_method in
+	"file_magic "*)
+	  file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"`
+	  MAGIC_CMD=$lt_cv_path_MAGIC_CMD
+	  if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
+	    $EGREP "$file_magic_regex" > /dev/null; then
+	    :
+	  else
+	    cat <<_LT_EOF 1>&2
+
+*** Warning: the command libtool uses to detect shared libraries,
+*** $file_magic_cmd, produces output that libtool cannot recognize.
+*** The result is that libtool may fail to recognize shared libraries
+*** as such.  This will affect the creation of libtool libraries that
+*** depend on shared libraries, but programs linked with such libtool
+*** libraries will work regardless of this problem.  Nevertheless, you
+*** may want to report the problem to your system manager and/or to
+*** bug-libtool@gnu.org
+
+_LT_EOF
+	  fi ;;
+	esac
+      fi
+      break
+    fi
+  done
+  IFS=$lt_save_ifs
+  MAGIC_CMD=$lt_save_MAGIC_CMD
+  ;;
+esac])
+MAGIC_CMD=$lt_cv_path_MAGIC_CMD
+if test -n "$MAGIC_CMD"; then
+  AC_MSG_RESULT($MAGIC_CMD)
+else
+  AC_MSG_RESULT(no)
+fi
+_LT_DECL([], [MAGIC_CMD], [0],
+	 [Used to examine libraries when file_magic_cmd begins with "file"])dnl
+])# _LT_PATH_TOOL_PREFIX
+
+# Old name:
+AU_ALIAS([AC_PATH_TOOL_PREFIX], [_LT_PATH_TOOL_PREFIX])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_PATH_TOOL_PREFIX], [])
+
+
+# _LT_PATH_MAGIC
+# --------------
+# find a file program that can recognize a shared library
+m4_defun([_LT_PATH_MAGIC],
+[_LT_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH)
+if test -z "$lt_cv_path_MAGIC_CMD"; then
+  if test -n "$ac_tool_prefix"; then
+    _LT_PATH_TOOL_PREFIX(file, /usr/bin$PATH_SEPARATOR$PATH)
+  else
+    MAGIC_CMD=:
+  fi
+fi
+])# _LT_PATH_MAGIC
+
+
+# LT_PATH_LD
+# ----------
+# find the pathname to the GNU or non-GNU linker
+AC_DEFUN([LT_PATH_LD],
+[AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+m4_require([_LT_DECL_SED])dnl
+m4_require([_LT_DECL_EGREP])dnl
+m4_require([_LT_PROG_ECHO_BACKSLASH])dnl
+
+AC_ARG_WITH([gnu-ld],
+    [AS_HELP_STRING([--with-gnu-ld],
+	[assume the C compiler uses GNU ld @<:@default=no@:>@])],
+    [test no = "$withval" || with_gnu_ld=yes],
+    [with_gnu_ld=no])dnl
+
+ac_prog=ld
+if test yes = "$GCC"; then
+  # Check if gcc -print-prog-name=ld gives a path.
+  AC_MSG_CHECKING([for ld used by $CC])
+  case $host in
+  *-*-mingw*)
+    # gcc leaves a trailing carriage return, which upsets mingw
+    ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
+  *)
+    ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
+  esac
+  case $ac_prog in
+    # Accept absolute paths.
+    [[\\/]]* | ?:[[\\/]]*)
+      re_direlt='/[[^/]][[^/]]*/\.\./'
+      # Canonicalize the pathname of ld
+      ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'`
+      while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do
+	ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"`
+      done
+      test -z "$LD" && LD=$ac_prog
+      ;;
+  "")
+    # If it fails, then pretend we aren't using GCC.
+    ac_prog=ld
+    ;;
+  *)
+    # If it is relative, then search for the first ld in PATH.
+    with_gnu_ld=unknown
+    ;;
+  esac
+elif test yes = "$with_gnu_ld"; then
+  AC_MSG_CHECKING([for GNU ld])
+else
+  AC_MSG_CHECKING([for non-GNU ld])
+fi
+AC_CACHE_VAL(lt_cv_path_LD,
+[if test -z "$LD"; then
+  lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR
+  for ac_dir in $PATH; do
+    IFS=$lt_save_ifs
+    test -z "$ac_dir" && ac_dir=.
+    if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+      lt_cv_path_LD=$ac_dir/$ac_prog
+      # Check to see if the program is GNU ld.  I'd rather use --version,
+      # but apparently some variants of GNU ld only accept -v.
+      # Break only if it was the GNU/non-GNU ld that we prefer.
+      case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in
+      *GNU* | *'with BFD'*)
+	test no != "$with_gnu_ld" && break
+	;;
+      *)
+	test yes != "$with_gnu_ld" && break
+	;;
+      esac
+    fi
+  done
+  IFS=$lt_save_ifs
+else
+  lt_cv_path_LD=$LD # Let the user override the test with a path.
+fi])
+LD=$lt_cv_path_LD
+if test -n "$LD"; then
+  AC_MSG_RESULT($LD)
+else
+  AC_MSG_RESULT(no)
+fi
+test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH])
+_LT_PATH_LD_GNU
+AC_SUBST([LD])
+
+_LT_TAGDECL([], [LD], [1], [The linker used to build libraries])
+])# LT_PATH_LD
+
+# Old names:
+AU_ALIAS([AM_PROG_LD], [LT_PATH_LD])
+AU_ALIAS([AC_PROG_LD], [LT_PATH_LD])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AM_PROG_LD], [])
+dnl AC_DEFUN([AC_PROG_LD], [])
+
+
+# _LT_PATH_LD_GNU
+#- --------------
+m4_defun([_LT_PATH_LD_GNU],
+[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], lt_cv_prog_gnu_ld,
+[# I'd rather use --version here, but apparently some GNU lds only accept -v.
+case `$LD -v 2>&1 </dev/null` in
+*GNU* | *'with BFD'*)
+  lt_cv_prog_gnu_ld=yes
+  ;;
+*)
+  lt_cv_prog_gnu_ld=no
+  ;;
+esac])
+with_gnu_ld=$lt_cv_prog_gnu_ld
+])# _LT_PATH_LD_GNU
+
+
+# _LT_CMD_RELOAD
+# --------------
+# find reload flag for linker
+#   -- PORTME Some linkers may need a different reload flag.
+m4_defun([_LT_CMD_RELOAD],
+[AC_CACHE_CHECK([for $LD option to reload object files],
+  lt_cv_ld_reload_flag,
+  [lt_cv_ld_reload_flag='-r'])
+reload_flag=$lt_cv_ld_reload_flag
+case $reload_flag in
+"" | " "*) ;;
+*) reload_flag=" $reload_flag" ;;
+esac
+reload_cmds='$LD$reload_flag -o $output$reload_objs'
+case $host_os in
+  cygwin* | mingw* | pw32* | cegcc*)
+    if test yes != "$GCC"; then
+      reload_cmds=false
+    fi
+    ;;
+  darwin*)
+    if test yes = "$GCC"; then
+      reload_cmds='$LTCC $LTCFLAGS -nostdlib $wl-r -o $output$reload_objs'
+    else
+      reload_cmds='$LD$reload_flag -o $output$reload_objs'
+    fi
+    ;;
+esac
+_LT_TAGDECL([], [reload_flag], [1], [How to create reloadable object files])dnl
+_LT_TAGDECL([], [reload_cmds], [2])dnl
+])# _LT_CMD_RELOAD
+
+
+# _LT_PATH_DD
+# -----------
+# find a working dd
+m4_defun([_LT_PATH_DD],
+[AC_CACHE_CHECK([for a working dd], [ac_cv_path_lt_DD],
+[printf 0123456789abcdef0123456789abcdef >conftest.i
+cat conftest.i conftest.i >conftest2.i
+: ${lt_DD:=$DD}
+AC_PATH_PROGS_FEATURE_CHECK([lt_DD], [dd],
+[if "$ac_path_lt_DD" bs=32 count=1 <conftest2.i >conftest.out 2>/dev/null; then
+  cmp -s conftest.i conftest.out \
+  && ac_cv_path_lt_DD="$ac_path_lt_DD" ac_path_lt_DD_found=:
+fi])
+rm -f conftest.i conftest2.i conftest.out])
+])# _LT_PATH_DD
+
+
+# _LT_CMD_TRUNCATE
+# ----------------
+# find command to truncate a binary pipe
+m4_defun([_LT_CMD_TRUNCATE],
+[m4_require([_LT_PATH_DD])
+AC_CACHE_CHECK([how to truncate binary pipes], [lt_cv_truncate_bin],
+[printf 0123456789abcdef0123456789abcdef >conftest.i
+cat conftest.i conftest.i >conftest2.i
+lt_cv_truncate_bin=
+if "$ac_cv_path_lt_DD" bs=32 count=1 <conftest2.i >conftest.out 2>/dev/null; then
+  cmp -s conftest.i conftest.out \
+  && lt_cv_truncate_bin="$ac_cv_path_lt_DD bs=4096 count=1"
+fi
+rm -f conftest.i conftest2.i conftest.out
+test -z "$lt_cv_truncate_bin" && lt_cv_truncate_bin="$SED -e 4q"])
+_LT_DECL([lt_truncate_bin], [lt_cv_truncate_bin], [1],
+  [Command to truncate a binary pipe])
+])# _LT_CMD_TRUNCATE
+
+
+# _LT_CHECK_MAGIC_METHOD
+# ----------------------
+# how to check for library dependencies
+#  -- PORTME fill in with the dynamic library characteristics
+m4_defun([_LT_CHECK_MAGIC_METHOD],
+[m4_require([_LT_DECL_EGREP])
+m4_require([_LT_DECL_OBJDUMP])
+AC_CACHE_CHECK([how to recognize dependent libraries],
+lt_cv_deplibs_check_method,
+[lt_cv_file_magic_cmd='$MAGIC_CMD'
+lt_cv_file_magic_test_file=
+lt_cv_deplibs_check_method='unknown'
+# Need to set the preceding variable on all platforms that support
+# interlibrary dependencies.
+# 'none' -- dependencies not supported.
+# 'unknown' -- same as none, but documents that we really don't know.
+# 'pass_all' -- all dependencies passed with no checks.
+# 'test_compile' -- check by making test program.
+# 'file_magic [[regex]]' -- check by looking for files in library path
+# that responds to the $file_magic_cmd with a given extended regex.
+# If you have 'file' or equivalent on your system and you're not sure
+# whether 'pass_all' will *always* work, you probably want this one.
+
+case $host_os in
+aix[[4-9]]*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+beos*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+bsdi[[45]]*)
+  lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib)'
+  lt_cv_file_magic_cmd='/usr/bin/file -L'
+  lt_cv_file_magic_test_file=/shlib/libc.so
+  ;;
+
+cygwin*)
+  # func_win32_libid is a shell function defined in ltmain.sh
+  lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
+  lt_cv_file_magic_cmd='func_win32_libid'
+  ;;
+
+mingw* | pw32*)
+  # Base MSYS/MinGW do not provide the 'file' command needed by
+  # func_win32_libid shell function, so use a weaker test based on 'objdump',
+  # unless we find 'file', for example because we are cross-compiling.
+  if ( file / ) >/dev/null 2>&1; then
+    lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
+    lt_cv_file_magic_cmd='func_win32_libid'
+  else
+    # Keep this pattern in sync with the one in func_win32_libid.
+    lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)'
+    lt_cv_file_magic_cmd='$OBJDUMP -f'
+  fi
+  ;;
+
+cegcc*)
+  # use the weaker test based on 'objdump'. See mingw*.
+  lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?'
+  lt_cv_file_magic_cmd='$OBJDUMP -f'
+  ;;
+
+darwin* | rhapsody*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+freebsd* | dragonfly*)
+  if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
+    case $host_cpu in
+    i*86 )
+      # Not sure whether the presence of OpenBSD here was a mistake.
+      # Let's accept both of them until this is cleared up.
+      lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[[3-9]]86 (compact )?demand paged shared library'
+      lt_cv_file_magic_cmd=/usr/bin/file
+      lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*`
+      ;;
+    esac
+  else
+    lt_cv_deplibs_check_method=pass_all
+  fi
+  ;;
+
+haiku*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+hpux10.20* | hpux11*)
+  lt_cv_file_magic_cmd=/usr/bin/file
+  case $host_cpu in
+  ia64*)
+    lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64'
+    lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so
+    ;;
+  hppa*64*)
+    [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]']
+    lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl
+    ;;
+  *)
+    lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]]\.[[0-9]]) shared library'
+    lt_cv_file_magic_test_file=/usr/lib/libc.sl
+    ;;
+  esac
+  ;;
+
+interix[[3-9]]*)
+  # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here
+  lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|\.a)$'
+  ;;
+
+irix5* | irix6* | nonstopux*)
+  case $LD in
+  *-32|*"-32 ") libmagic=32-bit;;
+  *-n32|*"-n32 ") libmagic=N32;;
+  *-64|*"-64 ") libmagic=64-bit;;
+  *) libmagic=never-match;;
+  esac
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+# This must be glibc/ELF.
+linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+netbsd* | netbsdelf*-gnu)
+  if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
+    lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$'
+  else
+    lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|_pic\.a)$'
+  fi
+  ;;
+
+newos6*)
+  lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)'
+  lt_cv_file_magic_cmd=/usr/bin/file
+  lt_cv_file_magic_test_file=/usr/lib/libnls.so
+  ;;
+
+*nto* | *qnx*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+openbsd* | bitrig*)
+  if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then
+    lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|\.so|_pic\.a)$'
+  else
+    lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$'
+  fi
+  ;;
+
+osf3* | osf4* | osf5*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+rdos*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+solaris*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+sysv4 | sysv4.3*)
+  case $host_vendor in
+  motorola)
+    lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]'
+    lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*`
+    ;;
+  ncr)
+    lt_cv_deplibs_check_method=pass_all
+    ;;
+  sequent)
+    lt_cv_file_magic_cmd='/bin/file'
+    lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )'
+    ;;
+  sni)
+    lt_cv_file_magic_cmd='/bin/file'
+    lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib"
+    lt_cv_file_magic_test_file=/lib/libc.so
+    ;;
+  siemens)
+    lt_cv_deplibs_check_method=pass_all
+    ;;
+  pc)
+    lt_cv_deplibs_check_method=pass_all
+    ;;
+  esac
+  ;;
+
+tpf*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+os2*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+esac
+])
+
+file_magic_glob=
+want_nocaseglob=no
+if test "$build" = "$host"; then
+  case $host_os in
+  mingw* | pw32*)
+    if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then
+      want_nocaseglob=yes
+    else
+      file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[[\1]]\/[[\1]]\/g;/g"`
+    fi
+    ;;
+  esac
+fi
+
+file_magic_cmd=$lt_cv_file_magic_cmd
+deplibs_check_method=$lt_cv_deplibs_check_method
+test -z "$deplibs_check_method" && deplibs_check_method=unknown
+
+_LT_DECL([], [deplibs_check_method], [1],
+    [Method to check whether dependent libraries are shared objects])
+_LT_DECL([], [file_magic_cmd], [1],
+    [Command to use when deplibs_check_method = "file_magic"])
+_LT_DECL([], [file_magic_glob], [1],
+    [How to find potential files when deplibs_check_method = "file_magic"])
+_LT_DECL([], [want_nocaseglob], [1],
+    [Find potential files using nocaseglob when deplibs_check_method = "file_magic"])
+])# _LT_CHECK_MAGIC_METHOD
+
+
+# LT_PATH_NM
+# ----------
+# find the pathname to a BSD- or MS-compatible name lister
+AC_DEFUN([LT_PATH_NM],
+[AC_REQUIRE([AC_PROG_CC])dnl
+AC_CACHE_CHECK([for BSD- or MS-compatible name lister (nm)], lt_cv_path_NM,
+[if test -n "$NM"; then
+  # Let the user override the test.
+  lt_cv_path_NM=$NM
+else
+  lt_nm_to_check=${ac_tool_prefix}nm
+  if test -n "$ac_tool_prefix" && test "$build" = "$host"; then
+    lt_nm_to_check="$lt_nm_to_check nm"
+  fi
+  for lt_tmp_nm in $lt_nm_to_check; do
+    lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR
+    for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do
+      IFS=$lt_save_ifs
+      test -z "$ac_dir" && ac_dir=.
+      tmp_nm=$ac_dir/$lt_tmp_nm
+      if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext"; then
+	# Check to see if the nm accepts a BSD-compat flag.
+	# Adding the 'sed 1q' prevents false positives on HP-UX, which says:
+	#   nm: unknown option "B" ignored
+	# Tru64's nm complains that /dev/null is an invalid object file
+	# MSYS converts /dev/null to NUL, MinGW nm treats NUL as empty
+	case $build_os in
+	mingw*) lt_bad_file=conftest.nm/nofile ;;
+	*) lt_bad_file=/dev/null ;;
+	esac
+	case `"$tmp_nm" -B $lt_bad_file 2>&1 | sed '1q'` in
+	*$lt_bad_file* | *'Invalid file or object type'*)
+	  lt_cv_path_NM="$tmp_nm -B"
+	  break 2
+	  ;;
+	*)
+	  case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in
+	  */dev/null*)
+	    lt_cv_path_NM="$tmp_nm -p"
+	    break 2
+	    ;;
+	  *)
+	    lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but
+	    continue # so that we can try to find one that supports BSD flags
+	    ;;
+	  esac
+	  ;;
+	esac
+      fi
+    done
+    IFS=$lt_save_ifs
+  done
+  : ${lt_cv_path_NM=no}
+fi])
+if test no != "$lt_cv_path_NM"; then
+  NM=$lt_cv_path_NM
+else
+  # Didn't find any BSD compatible name lister, look for dumpbin.
+  if test -n "$DUMPBIN"; then :
+    # Let the user override the test.
+  else
+    AC_CHECK_TOOLS(DUMPBIN, [dumpbin "link -dump"], :)
+    case `$DUMPBIN -symbols -headers /dev/null 2>&1 | sed '1q'` in
+    *COFF*)
+      DUMPBIN="$DUMPBIN -symbols -headers"
+      ;;
+    *)
+      DUMPBIN=:
+      ;;
+    esac
+  fi
+  AC_SUBST([DUMPBIN])
+  if test : != "$DUMPBIN"; then
+    NM=$DUMPBIN
+  fi
+fi
+test -z "$NM" && NM=nm
+AC_SUBST([NM])
+_LT_DECL([], [NM], [1], [A BSD- or MS-compatible name lister])dnl
+
+AC_CACHE_CHECK([the name lister ($NM) interface], [lt_cv_nm_interface],
+  [lt_cv_nm_interface="BSD nm"
+  echo "int some_variable = 0;" > conftest.$ac_ext
+  (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&AS_MESSAGE_LOG_FD)
+  (eval "$ac_compile" 2>conftest.err)
+  cat conftest.err >&AS_MESSAGE_LOG_FD
+  (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&AS_MESSAGE_LOG_FD)
+  (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out)
+  cat conftest.err >&AS_MESSAGE_LOG_FD
+  (eval echo "\"\$as_me:$LINENO: output\"" >&AS_MESSAGE_LOG_FD)
+  cat conftest.out >&AS_MESSAGE_LOG_FD
+  if $GREP 'External.*some_variable' conftest.out > /dev/null; then
+    lt_cv_nm_interface="MS dumpbin"
+  fi
+  rm -f conftest*])
+])# LT_PATH_NM
+
+# Old names:
+AU_ALIAS([AM_PROG_NM], [LT_PATH_NM])
+AU_ALIAS([AC_PROG_NM], [LT_PATH_NM])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AM_PROG_NM], [])
+dnl AC_DEFUN([AC_PROG_NM], [])
+
+# _LT_CHECK_SHAREDLIB_FROM_LINKLIB
+# --------------------------------
+# how to determine the name of the shared library
+# associated with a specific link library.
+#  -- PORTME fill in with the dynamic library characteristics
+m4_defun([_LT_CHECK_SHAREDLIB_FROM_LINKLIB],
+[m4_require([_LT_DECL_EGREP])
+m4_require([_LT_DECL_OBJDUMP])
+m4_require([_LT_DECL_DLLTOOL])
+AC_CACHE_CHECK([how to associate runtime and link libraries],
+lt_cv_sharedlib_from_linklib_cmd,
+[lt_cv_sharedlib_from_linklib_cmd='unknown'
+
+case $host_os in
+cygwin* | mingw* | pw32* | cegcc*)
+  # two different shell functions defined in ltmain.sh;
+  # decide which one to use based on capabilities of $DLLTOOL
+  case `$DLLTOOL --help 2>&1` in
+  *--identify-strict*)
+    lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib
+    ;;
+  *)
+    lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback
+    ;;
+  esac
+  ;;
+*)
+  # fallback: assume linklib IS sharedlib
+  lt_cv_sharedlib_from_linklib_cmd=$ECHO
+  ;;
+esac
+])
+sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd
+test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO
+
+_LT_DECL([], [sharedlib_from_linklib_cmd], [1],
+    [Command to associate shared and link libraries])
+])# _LT_CHECK_SHAREDLIB_FROM_LINKLIB
+
+
+# _LT_PATH_MANIFEST_TOOL
+# ----------------------
+# locate the manifest tool
+m4_defun([_LT_PATH_MANIFEST_TOOL],
+[AC_CHECK_TOOL(MANIFEST_TOOL, mt, :)
+test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt
+AC_CACHE_CHECK([if $MANIFEST_TOOL is a manifest tool], [lt_cv_path_mainfest_tool],
+  [lt_cv_path_mainfest_tool=no
+  echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&AS_MESSAGE_LOG_FD
+  $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out
+  cat conftest.err >&AS_MESSAGE_LOG_FD
+  if $GREP 'Manifest Tool' conftest.out > /dev/null; then
+    lt_cv_path_mainfest_tool=yes
+  fi
+  rm -f conftest*])
+if test yes != "$lt_cv_path_mainfest_tool"; then
+  MANIFEST_TOOL=:
+fi
+_LT_DECL([], [MANIFEST_TOOL], [1], [Manifest tool])dnl
+])# _LT_PATH_MANIFEST_TOOL
+
+
+# _LT_DLL_DEF_P([FILE])
+# ---------------------
+# True iff FILE is a Windows DLL '.def' file.
+# Keep in sync with func_dll_def_p in the libtool script
+AC_DEFUN([_LT_DLL_DEF_P],
+[dnl
+  test DEF = "`$SED -n dnl
+    -e '\''s/^[[	 ]]*//'\'' dnl Strip leading whitespace
+    -e '\''/^\(;.*\)*$/d'\'' dnl      Delete empty lines and comments
+    -e '\''s/^\(EXPORTS\|LIBRARY\)\([[	 ]].*\)*$/DEF/p'\'' dnl
+    -e q dnl                          Only consider the first "real" line
+    $1`" dnl
+])# _LT_DLL_DEF_P
+
+
+# LT_LIB_M
+# --------
+# check for math library
+AC_DEFUN([LT_LIB_M],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+LIBM=
+case $host in
+*-*-beos* | *-*-cegcc* | *-*-cygwin* | *-*-haiku* | *-*-pw32* | *-*-darwin*)
+  # These system don't have libm, or don't need it
+  ;;
+*-ncr-sysv4.3*)
+  AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM=-lmw)
+  AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm")
+  ;;
+*)
+  AC_CHECK_LIB(m, cos, LIBM=-lm)
+  ;;
+esac
+AC_SUBST([LIBM])
+])# LT_LIB_M
+
+# Old name:
+AU_ALIAS([AC_CHECK_LIBM], [LT_LIB_M])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_CHECK_LIBM], [])
+
+
+# _LT_COMPILER_NO_RTTI([TAGNAME])
+# -------------------------------
+m4_defun([_LT_COMPILER_NO_RTTI],
+[m4_require([_LT_TAG_COMPILER])dnl
+
+_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=
+
+if test yes = "$GCC"; then
+  case $cc_basename in
+  nvcc*)
+    _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -Xcompiler -fno-builtin' ;;
+  *)
+    _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' ;;
+  esac
+
+  _LT_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions],
+    lt_cv_prog_compiler_rtti_exceptions,
+    [-fno-rtti -fno-exceptions], [],
+    [_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)="$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) -fno-rtti -fno-exceptions"])
+fi
+_LT_TAGDECL([no_builtin_flag], [lt_prog_compiler_no_builtin_flag], [1],
+	[Compiler flag to turn off builtin functions])
+])# _LT_COMPILER_NO_RTTI
+
+
+# _LT_CMD_GLOBAL_SYMBOLS
+# ----------------------
+m4_defun([_LT_CMD_GLOBAL_SYMBOLS],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([AC_PROG_AWK])dnl
+AC_REQUIRE([LT_PATH_NM])dnl
+AC_REQUIRE([LT_PATH_LD])dnl
+m4_require([_LT_DECL_SED])dnl
+m4_require([_LT_DECL_EGREP])dnl
+m4_require([_LT_TAG_COMPILER])dnl
+
+# Check for command to grab the raw symbol name followed by C symbol from nm.
+AC_MSG_CHECKING([command to parse $NM output from $compiler object])
+AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe],
+[
+# These are sane defaults that work on at least a few old systems.
+# [They come from Ultrix.  What could be older than Ultrix?!! ;)]
+
+# Character class describing NM global symbol codes.
+symcode='[[BCDEGRST]]'
+
+# Regexp to match symbols that can be accessed directly from C.
+sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)'
+
+# Define system-specific variables.
+case $host_os in
+aix*)
+  symcode='[[BCDT]]'
+  ;;
+cygwin* | mingw* | pw32* | cegcc*)
+  symcode='[[ABCDGISTW]]'
+  ;;
+hpux*)
+  if test ia64 = "$host_cpu"; then
+    symcode='[[ABCDEGRST]]'
+  fi
+  ;;
+irix* | nonstopux*)
+  symcode='[[BCDEGRST]]'
+  ;;
+osf*)
+  symcode='[[BCDEGQRST]]'
+  ;;
+solaris*)
+  symcode='[[BDRT]]'
+  ;;
+sco3.2v5*)
+  symcode='[[DT]]'
+  ;;
+sysv4.2uw2*)
+  symcode='[[DT]]'
+  ;;
+sysv5* | sco5v6* | unixware* | OpenUNIX*)
+  symcode='[[ABDT]]'
+  ;;
+sysv4)
+  symcode='[[DFNSTU]]'
+  ;;
+esac
+
+# If we're using GNU nm, then use its standard symbol codes.
+case `$NM -V 2>&1` in
+*GNU* | *'with BFD'*)
+  symcode='[[ABCDGIRSTW]]' ;;
+esac
+
+if test "$lt_cv_nm_interface" = "MS dumpbin"; then
+  # Gets list of data symbols to import.
+  lt_cv_sys_global_symbol_to_import="sed -n -e 's/^I .* \(.*\)$/\1/p'"
+  # Adjust the below global symbol transforms to fixup imported variables.
+  lt_cdecl_hook=" -e 's/^I .* \(.*\)$/extern __declspec(dllimport) char \1;/p'"
+  lt_c_name_hook=" -e 's/^I .* \(.*\)$/  {\"\1\", (void *) 0},/p'"
+  lt_c_name_lib_hook="\
+  -e 's/^I .* \(lib.*\)$/  {\"\1\", (void *) 0},/p'\
+  -e 's/^I .* \(.*\)$/  {\"lib\1\", (void *) 0},/p'"
+else
+  # Disable hooks by default.
+  lt_cv_sys_global_symbol_to_import=
+  lt_cdecl_hook=
+  lt_c_name_hook=
+  lt_c_name_lib_hook=
+fi
+
+# Transform an extracted symbol line into a proper C declaration.
+# Some systems (esp. on ia64) link data and code symbols differently,
+# so use this general approach.
+lt_cv_sys_global_symbol_to_cdecl="sed -n"\
+$lt_cdecl_hook\
+" -e 's/^T .* \(.*\)$/extern int \1();/p'"\
+" -e 's/^$symcode$symcode* .* \(.*\)$/extern char \1;/p'"
+
+# Transform an extracted symbol line into symbol name and symbol address
+lt_cv_sys_global_symbol_to_c_name_address="sed -n"\
+$lt_c_name_hook\
+" -e 's/^: \(.*\) .*$/  {\"\1\", (void *) 0},/p'"\
+" -e 's/^$symcode$symcode* .* \(.*\)$/  {\"\1\", (void *) \&\1},/p'"
+
+# Transform an extracted symbol line into symbol name with lib prefix and
+# symbol address.
+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n"\
+$lt_c_name_lib_hook\
+" -e 's/^: \(.*\) .*$/  {\"\1\", (void *) 0},/p'"\
+" -e 's/^$symcode$symcode* .* \(lib.*\)$/  {\"\1\", (void *) \&\1},/p'"\
+" -e 's/^$symcode$symcode* .* \(.*\)$/  {\"lib\1\", (void *) \&\1},/p'"
+
+# Handle CRLF in mingw tool chain
+opt_cr=
+case $build_os in
+mingw*)
+  opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp
+  ;;
+esac
+
+# Try without a prefix underscore, then with it.
+for ac_symprfx in "" "_"; do
+
+  # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol.
+  symxfrm="\\1 $ac_symprfx\\2 \\2"
+
+  # Write the raw and C identifiers.
+  if test "$lt_cv_nm_interface" = "MS dumpbin"; then
+    # Fake it for dumpbin and say T for any non-static function,
+    # D for any global variable and I for any imported variable.
+    # Also find C++ and __fastcall symbols from MSVC++,
+    # which start with @ or ?.
+    lt_cv_sys_global_symbol_pipe="$AWK ['"\
+"     {last_section=section; section=\$ 3};"\
+"     /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\
+"     /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\
+"     /^ *Symbol name *: /{split(\$ 0,sn,\":\"); si=substr(sn[2],2)};"\
+"     /^ *Type *: code/{print \"T\",si,substr(si,length(prfx))};"\
+"     /^ *Type *: data/{print \"I\",si,substr(si,length(prfx))};"\
+"     \$ 0!~/External *\|/{next};"\
+"     / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\
+"     {if(hide[section]) next};"\
+"     {f=\"D\"}; \$ 0~/\(\).*\|/{f=\"T\"};"\
+"     {split(\$ 0,a,/\||\r/); split(a[2],s)};"\
+"     s[1]~/^[@?]/{print f,s[1],s[1]; next};"\
+"     s[1]~prfx {split(s[1],t,\"@\"); print f,t[1],substr(t[1],length(prfx))}"\
+"     ' prfx=^$ac_symprfx]"
+  else
+    lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[	 ]]\($symcode$symcode*\)[[	 ]][[	 ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'"
+  fi
+  lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'"
+
+  # Check to see that the pipe works correctly.
+  pipe_works=no
+
+  rm -f conftest*
+  cat > conftest.$ac_ext <<_LT_EOF
+#ifdef __cplusplus
+extern "C" {
+#endif
+char nm_test_var;
+void nm_test_func(void);
+void nm_test_func(void){}
+#ifdef __cplusplus
+}
+#endif
+int main(){nm_test_var='a';nm_test_func();return(0);}
+_LT_EOF
+
+  if AC_TRY_EVAL(ac_compile); then
+    # Now try to grab the symbols.
+    nlist=conftest.nm
+    if AC_TRY_EVAL(NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) && test -s "$nlist"; then
+      # Try sorting and uniquifying the output.
+      if sort "$nlist" | uniq > "$nlist"T; then
+	mv -f "$nlist"T "$nlist"
+      else
+	rm -f "$nlist"T
+      fi
+
+      # Make sure that we snagged all the symbols we need.
+      if $GREP ' nm_test_var$' "$nlist" >/dev/null; then
+	if $GREP ' nm_test_func$' "$nlist" >/dev/null; then
+	  cat <<_LT_EOF > conftest.$ac_ext
+/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests.  */
+#if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE
+/* DATA imports from DLLs on WIN32 can't be const, because runtime
+   relocations are performed -- see ld's documentation on pseudo-relocs.  */
+# define LT@&t@_DLSYM_CONST
+#elif defined __osf__
+/* This system does not cope well with relocations in const data.  */
+# define LT@&t@_DLSYM_CONST
+#else
+# define LT@&t@_DLSYM_CONST const
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+_LT_EOF
+	  # Now generate the symbol file.
+	  eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext'
+
+	  cat <<_LT_EOF >> conftest.$ac_ext
+
+/* The mapping between symbol names and symbols.  */
+LT@&t@_DLSYM_CONST struct {
+  const char *name;
+  void       *address;
+}
+lt__PROGRAM__LTX_preloaded_symbols[[]] =
+{
+  { "@PROGRAM@", (void *) 0 },
+_LT_EOF
+	  $SED "s/^$symcode$symcode* .* \(.*\)$/  {\"\1\", (void *) \&\1},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext
+	  cat <<\_LT_EOF >> conftest.$ac_ext
+  {0, (void *) 0}
+};
+
+/* This works around a problem in FreeBSD linker */
+#ifdef FREEBSD_WORKAROUND
+static const void *lt_preloaded_setup() {
+  return lt__PROGRAM__LTX_preloaded_symbols;
+}
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+_LT_EOF
+	  # Now try linking the two files.
+	  mv conftest.$ac_objext conftstm.$ac_objext
+	  lt_globsym_save_LIBS=$LIBS
+	  lt_globsym_save_CFLAGS=$CFLAGS
+	  LIBS=conftstm.$ac_objext
+	  CFLAGS="$CFLAGS$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)"
+	  if AC_TRY_EVAL(ac_link) && test -s conftest$ac_exeext; then
+	    pipe_works=yes
+	  fi
+	  LIBS=$lt_globsym_save_LIBS
+	  CFLAGS=$lt_globsym_save_CFLAGS
+	else
+	  echo "cannot find nm_test_func in $nlist" >&AS_MESSAGE_LOG_FD
+	fi
+      else
+	echo "cannot find nm_test_var in $nlist" >&AS_MESSAGE_LOG_FD
+      fi
+    else
+      echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD
+    fi
+  else
+    echo "$progname: failed program was:" >&AS_MESSAGE_LOG_FD
+    cat conftest.$ac_ext >&5
+  fi
+  rm -rf conftest* conftst*
+
+  # Do not use the global_symbol_pipe unless it works.
+  if test yes = "$pipe_works"; then
+    break
+  else
+    lt_cv_sys_global_symbol_pipe=
+  fi
+done
+])
+if test -z "$lt_cv_sys_global_symbol_pipe"; then
+  lt_cv_sys_global_symbol_to_cdecl=
+fi
+if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then
+  AC_MSG_RESULT(failed)
+else
+  AC_MSG_RESULT(ok)
+fi
+
+# Response file support.
+if test "$lt_cv_nm_interface" = "MS dumpbin"; then
+  nm_file_list_spec='@'
+elif $NM --help 2>/dev/null | grep '[[@]]FILE' >/dev/null; then
+  nm_file_list_spec='@'
+fi
+
+_LT_DECL([global_symbol_pipe], [lt_cv_sys_global_symbol_pipe], [1],
+    [Take the output of nm and produce a listing of raw symbols and C names])
+_LT_DECL([global_symbol_to_cdecl], [lt_cv_sys_global_symbol_to_cdecl], [1],
+    [Transform the output of nm in a proper C declaration])
+_LT_DECL([global_symbol_to_import], [lt_cv_sys_global_symbol_to_import], [1],
+    [Transform the output of nm into a list of symbols to manually relocate])
+_LT_DECL([global_symbol_to_c_name_address],
+    [lt_cv_sys_global_symbol_to_c_name_address], [1],
+    [Transform the output of nm in a C name address pair])
+_LT_DECL([global_symbol_to_c_name_address_lib_prefix],
+    [lt_cv_sys_global_symbol_to_c_name_address_lib_prefix], [1],
+    [Transform the output of nm in a C name address pair when lib prefix is needed])
+_LT_DECL([nm_interface], [lt_cv_nm_interface], [1],
+    [The name lister interface])
+_LT_DECL([], [nm_file_list_spec], [1],
+    [Specify filename containing input files for $NM])
+]) # _LT_CMD_GLOBAL_SYMBOLS
+
+
+# _LT_COMPILER_PIC([TAGNAME])
+# ---------------------------
+m4_defun([_LT_COMPILER_PIC],
+[m4_require([_LT_TAG_COMPILER])dnl
+_LT_TAGVAR(lt_prog_compiler_wl, $1)=
+_LT_TAGVAR(lt_prog_compiler_pic, $1)=
+_LT_TAGVAR(lt_prog_compiler_static, $1)=
+
+m4_if([$1], [CXX], [
+  # C++ specific cases for pic, static, wl, etc.
+  if test yes = "$GXX"; then
+    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+    _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+
+    case $host_os in
+    aix*)
+      # All AIX code is PIC.
+      if test ia64 = "$host_cpu"; then
+	# AIX 5 now supports IA64 processor
+	_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      fi
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+      ;;
+
+    amigaos*)
+      case $host_cpu in
+      powerpc)
+            # see comment about AmigaOS4 .so support
+            _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+        ;;
+      m68k)
+            # FIXME: we need at least 68020 code to build shared libraries, but
+            # adding the '-m68020' flag to GCC prevents building anything better,
+            # like '-m68040'.
+            _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4'
+        ;;
+      esac
+      ;;
+
+    beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
+      # PIC is the default for these OSes.
+      ;;
+    mingw* | cygwin* | os2* | pw32* | cegcc*)
+      # This hack is so that the source file can tell whether it is being
+      # built for inclusion in a dll (and should export symbols for example).
+      # Although the cygwin gcc ignores -fPIC, still need this for old-style
+      # (--disable-auto-import) libraries
+      m4_if([$1], [GCJ], [],
+	[_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])
+      case $host_os in
+      os2*)
+	_LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static'
+	;;
+      esac
+      ;;
+    darwin* | rhapsody*)
+      # PIC is the default on this platform
+      # Common symbols not allowed in MH_DYLIB files
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common'
+      ;;
+    *djgpp*)
+      # DJGPP does not support shared libraries at all
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)=
+      ;;
+    haiku*)
+      # PIC is the default for Haiku.
+      # The "-static" flag exists, but is broken.
+      _LT_TAGVAR(lt_prog_compiler_static, $1)=
+      ;;
+    interix[[3-9]]*)
+      # Interix 3.x gcc -fpic/-fPIC options generate broken code.
+      # Instead, we relocate shared libraries at runtime.
+      ;;
+    sysv4*MP*)
+      if test -d /usr/nec; then
+	_LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic
+      fi
+      ;;
+    hpux*)
+      # PIC is the default for 64-bit PA HP-UX, but not for 32-bit
+      # PA HP-UX.  On IA64 HP-UX, PIC is the default but the pic flag
+      # sets the default TLS model and affects inlining.
+      case $host_cpu in
+      hppa*64*)
+	;;
+      *)
+	_LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+	;;
+      esac
+      ;;
+    *qnx* | *nto*)
+      # QNX uses GNU C++, but need to define -shared option too, otherwise
+      # it will coredump.
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared'
+      ;;
+    *)
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+      ;;
+    esac
+  else
+    case $host_os in
+      aix[[4-9]]*)
+	# All AIX code is PIC.
+	if test ia64 = "$host_cpu"; then
+	  # AIX 5 now supports IA64 processor
+	  _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+	else
+	  _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp'
+	fi
+	;;
+      chorus*)
+	case $cc_basename in
+	cxch68*)
+	  # Green Hills C++ Compiler
+	  # _LT_TAGVAR(lt_prog_compiler_static, $1)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a"
+	  ;;
+	esac
+	;;
+      mingw* | cygwin* | os2* | pw32* | cegcc*)
+	# This hack is so that the source file can tell whether it is being
+	# built for inclusion in a dll (and should export symbols for example).
+	m4_if([$1], [GCJ], [],
+	  [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])
+	;;
+      dgux*)
+	case $cc_basename in
+	  ec++*)
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+	    ;;
+	  ghcx*)
+	    # Green Hills C++ Compiler
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      freebsd* | dragonfly*)
+	# FreeBSD uses GNU C++
+	;;
+      hpux9* | hpux10* | hpux11*)
+	case $cc_basename in
+	  CC*)
+	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive'
+	    if test ia64 != "$host_cpu"; then
+	      _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z'
+	    fi
+	    ;;
+	  aCC*)
+	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive'
+	    case $host_cpu in
+	    hppa*64*|ia64*)
+	      # +Z the default
+	      ;;
+	    *)
+	      _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z'
+	      ;;
+	    esac
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      interix*)
+	# This is c89, which is MS Visual C++ (no shared libs)
+	# Anyone wants to do a port?
+	;;
+      irix5* | irix6* | nonstopux*)
+	case $cc_basename in
+	  CC*)
+	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+	    # CC pic flag -KPIC is the default.
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
+	case $cc_basename in
+	  KCC*)
+	    # KAI C++ Compiler
+	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,'
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+	    ;;
+	  ecpc* )
+	    # old Intel C++ for x86_64, which still supported -KPIC.
+	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+	    ;;
+	  icpc* )
+	    # Intel C++, used to be incompatible with GCC.
+	    # ICC 10 doesn't accept -KPIC any more.
+	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+	    ;;
+	  pgCC* | pgcpp*)
+	    # Portland Group C++ compiler
+	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic'
+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+	    ;;
+	  cxx*)
+	    # Compaq C++
+	    # Make sure the PIC flag is empty.  It appears that all Alpha
+	    # Linux and Compaq Tru64 Unix objects are PIC.
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)=
+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+	    ;;
+	  xlc* | xlC* | bgxl[[cC]]* | mpixl[[cC]]*)
+	    # IBM XL 8.0, 9.0 on PPC and BlueGene
+	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic'
+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink'
+	    ;;
+	  *)
+	    case `$CC -V 2>&1 | sed 5q` in
+	    *Sun\ C*)
+	      # Sun C++ 5.9
+	      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+	      _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+	      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '
+	      ;;
+	    esac
+	    ;;
+	esac
+	;;
+      lynxos*)
+	;;
+      m88k*)
+	;;
+      mvs*)
+	case $cc_basename in
+	  cxx*)
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      netbsd* | netbsdelf*-gnu)
+	;;
+      *qnx* | *nto*)
+        # QNX uses GNU C++, but need to define -shared option too, otherwise
+        # it will coredump.
+        _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared'
+        ;;
+      osf3* | osf4* | osf5*)
+	case $cc_basename in
+	  KCC*)
+	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,'
+	    ;;
+	  RCC*)
+	    # Rational C++ 2.4.1
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+	    ;;
+	  cxx*)
+	    # Digital/Compaq C++
+	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	    # Make sure the PIC flag is empty.  It appears that all Alpha
+	    # Linux and Compaq Tru64 Unix objects are PIC.
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)=
+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      psos*)
+	;;
+      solaris*)
+	case $cc_basename in
+	  CC* | sunCC*)
+	    # Sun C++ 4.2, 5.x and Centerline C++
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '
+	    ;;
+	  gcx*)
+	    # Green Hills C++ Compiler
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      sunos4*)
+	case $cc_basename in
+	  CC*)
+	    # Sun C++ 4.x
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+	    ;;
+	  lcc*)
+	    # Lucid
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
+	case $cc_basename in
+	  CC*)
+	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+	    ;;
+	esac
+	;;
+      tandem*)
+	case $cc_basename in
+	  NCC*)
+	    # NonStop-UX NCC 3.20
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      vxworks*)
+	;;
+      *)
+	_LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
+	;;
+    esac
+  fi
+],
+[
+  if test yes = "$GCC"; then
+    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+    _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+
+    case $host_os in
+      aix*)
+      # All AIX code is PIC.
+      if test ia64 = "$host_cpu"; then
+	# AIX 5 now supports IA64 processor
+	_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      fi
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+      ;;
+
+    amigaos*)
+      case $host_cpu in
+      powerpc)
+            # see comment about AmigaOS4 .so support
+            _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+        ;;
+      m68k)
+            # FIXME: we need at least 68020 code to build shared libraries, but
+            # adding the '-m68020' flag to GCC prevents building anything better,
+            # like '-m68040'.
+            _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4'
+        ;;
+      esac
+      ;;
+
+    beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
+      # PIC is the default for these OSes.
+      ;;
+
+    mingw* | cygwin* | pw32* | os2* | cegcc*)
+      # This hack is so that the source file can tell whether it is being
+      # built for inclusion in a dll (and should export symbols for example).
+      # Although the cygwin gcc ignores -fPIC, still need this for old-style
+      # (--disable-auto-import) libraries
+      m4_if([$1], [GCJ], [],
+	[_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])
+      case $host_os in
+      os2*)
+	_LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static'
+	;;
+      esac
+      ;;
+
+    darwin* | rhapsody*)
+      # PIC is the default on this platform
+      # Common symbols not allowed in MH_DYLIB files
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common'
+      ;;
+
+    haiku*)
+      # PIC is the default for Haiku.
+      # The "-static" flag exists, but is broken.
+      _LT_TAGVAR(lt_prog_compiler_static, $1)=
+      ;;
+
+    hpux*)
+      # PIC is the default for 64-bit PA HP-UX, but not for 32-bit
+      # PA HP-UX.  On IA64 HP-UX, PIC is the default but the pic flag
+      # sets the default TLS model and affects inlining.
+      case $host_cpu in
+      hppa*64*)
+	# +Z the default
+	;;
+      *)
+	_LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+	;;
+      esac
+      ;;
+
+    interix[[3-9]]*)
+      # Interix 3.x gcc -fpic/-fPIC options generate broken code.
+      # Instead, we relocate shared libraries at runtime.
+      ;;
+
+    msdosdjgpp*)
+      # Just because we use GCC doesn't mean we suddenly get shared libraries
+      # on systems that don't support them.
+      _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
+      enable_shared=no
+      ;;
+
+    *nto* | *qnx*)
+      # QNX uses GNU C++, but need to define -shared option too, otherwise
+      # it will coredump.
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared'
+      ;;
+
+    sysv4*MP*)
+      if test -d /usr/nec; then
+	_LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic
+      fi
+      ;;
+
+    *)
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+      ;;
+    esac
+
+    case $cc_basename in
+    nvcc*) # Cuda Compiler Driver 2.2
+      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Xlinker '
+      if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then
+        _LT_TAGVAR(lt_prog_compiler_pic, $1)="-Xcompiler $_LT_TAGVAR(lt_prog_compiler_pic, $1)"
+      fi
+      ;;
+    esac
+  else
+    # PORTME Check for flag to pass linker flags through the system compiler.
+    case $host_os in
+    aix*)
+      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+      if test ia64 = "$host_cpu"; then
+	# AIX 5 now supports IA64 processor
+	_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      else
+	_LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp'
+      fi
+      ;;
+
+    darwin* | rhapsody*)
+      # PIC is the default on this platform
+      # Common symbols not allowed in MH_DYLIB files
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common'
+      case $cc_basename in
+      nagfor*)
+        # NAG Fortran compiler
+        _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,'
+        _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC'
+        _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+        ;;
+      esac
+      ;;
+
+    mingw* | cygwin* | pw32* | os2* | cegcc*)
+      # This hack is so that the source file can tell whether it is being
+      # built for inclusion in a dll (and should export symbols for example).
+      m4_if([$1], [GCJ], [],
+	[_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])
+      case $host_os in
+      os2*)
+	_LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static'
+	;;
+      esac
+      ;;
+
+    hpux9* | hpux10* | hpux11*)
+      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+      # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
+      # not for PA HP-UX.
+      case $host_cpu in
+      hppa*64*|ia64*)
+	# +Z the default
+	;;
+      *)
+	_LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z'
+	;;
+      esac
+      # Is there a better lt_prog_compiler_static that works with the bundled CC?
+      _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive'
+      ;;
+
+    irix5* | irix6* | nonstopux*)
+      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+      # PIC (with -KPIC) is the default.
+      _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+      ;;
+
+    linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
+      case $cc_basename in
+      # old Intel for x86_64, which still supported -KPIC.
+      ecc*)
+	_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	_LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+	_LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+        ;;
+      # icc used to be incompatible with GCC.
+      # ICC 10 doesn't accept -KPIC any more.
+      icc* | ifort*)
+	_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	_LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+	_LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+        ;;
+      # Lahey Fortran 8.1.
+      lf95*)
+	_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	_LT_TAGVAR(lt_prog_compiler_pic, $1)='--shared'
+	_LT_TAGVAR(lt_prog_compiler_static, $1)='--static'
+	;;
+      nagfor*)
+	# NAG Fortran compiler
+	_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,'
+	_LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC'
+	_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+	;;
+      tcc*)
+	# Fabrice Bellard et al's Tiny C Compiler
+	_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	_LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+	_LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+	;;
+      pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*)
+        # Portland Group compilers (*not* the Pentium gcc compiler,
+	# which looks to be a dead project)
+	_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	_LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic'
+	_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+        ;;
+      ccc*)
+        _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+        # All Alpha code is PIC.
+        _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+        ;;
+      xl* | bgxl* | bgf* | mpixl*)
+	# IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene
+	_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	_LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic'
+	_LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink'
+	;;
+      *)
+	case `$CC -V 2>&1 | sed 5q` in
+	*Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [[1-7]].* | *Sun*Fortran*\ 8.[[0-3]]*)
+	  # Sun Fortran 8.3 passes all unrecognized flags to the linker
+	  _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+	  _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+	  _LT_TAGVAR(lt_prog_compiler_wl, $1)=''
+	  ;;
+	*Sun\ F* | *Sun*Fortran*)
+	  _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+	  _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+	  _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '
+	  ;;
+	*Sun\ C*)
+	  # Sun C 5.9
+	  _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+	  _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+	  _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	  ;;
+        *Intel*\ [[CF]]*Compiler*)
+	  _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	  _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+	  _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+	  ;;
+	*Portland\ Group*)
+	  _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	  _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic'
+	  _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+	  ;;
+	esac
+	;;
+      esac
+      ;;
+
+    newsos6)
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+      _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      ;;
+
+    *nto* | *qnx*)
+      # QNX uses GNU C++, but need to define -shared option too, otherwise
+      # it will coredump.
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared'
+      ;;
+
+    osf3* | osf4* | osf5*)
+      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+      # All OSF/1 code is PIC.
+      _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+      ;;
+
+    rdos*)
+      _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+      ;;
+
+    solaris*)
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+      _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      case $cc_basename in
+      f77* | f90* | f95* | sunf77* | sunf90* | sunf95*)
+	_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ';;
+      *)
+	_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,';;
+      esac
+      ;;
+
+    sunos4*)
+      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC'
+      _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      ;;
+
+    sysv4 | sysv4.2uw2* | sysv4.3*)
+      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+      _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      ;;
+
+    sysv4*MP*)
+      if test -d /usr/nec; then
+	_LT_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic'
+	_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      fi
+      ;;
+
+    sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
+      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+      _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      ;;
+
+    unicos*)
+      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+      _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
+      ;;
+
+    uts4*)
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+      _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      ;;
+
+    *)
+      _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
+      ;;
+    esac
+  fi
+])
+case $host_os in
+  # For platforms that do not support PIC, -DPIC is meaningless:
+  *djgpp*)
+    _LT_TAGVAR(lt_prog_compiler_pic, $1)=
+    ;;
+  *)
+    _LT_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])"
+    ;;
+esac
+
+AC_CACHE_CHECK([for $compiler option to produce PIC],
+  [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)],
+  [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_prog_compiler_pic, $1)])
+_LT_TAGVAR(lt_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)
+
+#
+# Check to make sure the PIC flag actually works.
+#
+if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then
+  _LT_COMPILER_OPTION([if $compiler PIC flag $_LT_TAGVAR(lt_prog_compiler_pic, $1) works],
+    [_LT_TAGVAR(lt_cv_prog_compiler_pic_works, $1)],
+    [$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])], [],
+    [case $_LT_TAGVAR(lt_prog_compiler_pic, $1) in
+     "" | " "*) ;;
+     *) _LT_TAGVAR(lt_prog_compiler_pic, $1)=" $_LT_TAGVAR(lt_prog_compiler_pic, $1)" ;;
+     esac],
+    [_LT_TAGVAR(lt_prog_compiler_pic, $1)=
+     _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no])
+fi
+_LT_TAGDECL([pic_flag], [lt_prog_compiler_pic], [1],
+	[Additional compiler flags for building library objects])
+
+_LT_TAGDECL([wl], [lt_prog_compiler_wl], [1],
+	[How to pass a linker flag through the compiler])
+#
+# Check to make sure the static flag actually works.
+#
+wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) eval lt_tmp_static_flag=\"$_LT_TAGVAR(lt_prog_compiler_static, $1)\"
+_LT_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works],
+  _LT_TAGVAR(lt_cv_prog_compiler_static_works, $1),
+  $lt_tmp_static_flag,
+  [],
+  [_LT_TAGVAR(lt_prog_compiler_static, $1)=])
+_LT_TAGDECL([link_static_flag], [lt_prog_compiler_static], [1],
+	[Compiler flag to prevent dynamic linking])
+])# _LT_COMPILER_PIC
+
+
+# _LT_LINKER_SHLIBS([TAGNAME])
+# ----------------------------
+# See if the linker supports building shared libraries.
+m4_defun([_LT_LINKER_SHLIBS],
+[AC_REQUIRE([LT_PATH_LD])dnl
+AC_REQUIRE([LT_PATH_NM])dnl
+m4_require([_LT_PATH_MANIFEST_TOOL])dnl
+m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_DECL_EGREP])dnl
+m4_require([_LT_DECL_SED])dnl
+m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl
+m4_require([_LT_TAG_COMPILER])dnl
+AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries])
+m4_if([$1], [CXX], [
+  _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+  _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*']
+  case $host_os in
+  aix[[4-9]]*)
+    # If we're using GNU nm, then we don't want the "-C" option.
+    # -C means demangle to GNU nm, but means don't demangle to AIX nm.
+    # Without the "-l" option, or with the "-B" option, AIX nm treats
+    # weak defined symbols like other global defined symbols, whereas
+    # GNU nm marks them as "W".
+    # While the 'weak' keyword is ignored in the Export File, we need
+    # it in the Import File for the 'aix-soname' feature, so we have
+    # to replace the "-B" option with "-P" for AIX nm.
+    if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
+      _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols'
+    else
+      _LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols'
+    fi
+    ;;
+  pw32*)
+    _LT_TAGVAR(export_symbols_cmds, $1)=$ltdll_cmds
+    ;;
+  cygwin* | mingw* | cegcc*)
+    case $cc_basename in
+    cl*)
+      _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*'
+      ;;
+    *)
+      _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols'
+      _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname']
+      ;;
+    esac
+    ;;
+  linux* | k*bsd*-gnu | gnu*)
+    _LT_TAGVAR(link_all_deplibs, $1)=no
+    ;;
+  *)
+    _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+    ;;
+  esac
+], [
+  runpath_var=
+  _LT_TAGVAR(allow_undefined_flag, $1)=
+  _LT_TAGVAR(always_export_symbols, $1)=no
+  _LT_TAGVAR(archive_cmds, $1)=
+  _LT_TAGVAR(archive_expsym_cmds, $1)=
+  _LT_TAGVAR(compiler_needs_object, $1)=no
+  _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no
+  _LT_TAGVAR(export_dynamic_flag_spec, $1)=
+  _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+  _LT_TAGVAR(hardcode_automatic, $1)=no
+  _LT_TAGVAR(hardcode_direct, $1)=no
+  _LT_TAGVAR(hardcode_direct_absolute, $1)=no
+  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+  _LT_TAGVAR(hardcode_libdir_separator, $1)=
+  _LT_TAGVAR(hardcode_minus_L, $1)=no
+  _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
+  _LT_TAGVAR(inherit_rpath, $1)=no
+  _LT_TAGVAR(link_all_deplibs, $1)=unknown
+  _LT_TAGVAR(module_cmds, $1)=
+  _LT_TAGVAR(module_expsym_cmds, $1)=
+  _LT_TAGVAR(old_archive_from_new_cmds, $1)=
+  _LT_TAGVAR(old_archive_from_expsyms_cmds, $1)=
+  _LT_TAGVAR(thread_safe_flag_spec, $1)=
+  _LT_TAGVAR(whole_archive_flag_spec, $1)=
+  # include_expsyms should be a list of space-separated symbols to be *always*
+  # included in the symbol list
+  _LT_TAGVAR(include_expsyms, $1)=
+  # exclude_expsyms can be an extended regexp of symbols to exclude
+  # it will be wrapped by ' (' and ')$', so one must not match beginning or
+  # end of line.  Example: 'a|bc|.*d.*' will exclude the symbols 'a' and 'bc',
+  # as well as any symbol that contains 'd'.
+  _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*']
+  # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out
+  # platforms (ab)use it in PIC code, but their linkers get confused if
+  # the symbol is explicitly referenced.  Since portable code cannot
+  # rely on this symbol name, it's probably fine to never include it in
+  # preloaded symbol tables.
+  # Exclude shared library initialization/finalization symbols.
+dnl Note also adjust exclude_expsyms for C++ above.
+  extract_expsyms_cmds=
+
+  case $host_os in
+  cygwin* | mingw* | pw32* | cegcc*)
+    # FIXME: the MSVC++ port hasn't been tested in a loooong time
+    # When not using gcc, we currently assume that we are using
+    # Microsoft Visual C++.
+    if test yes != "$GCC"; then
+      with_gnu_ld=no
+    fi
+    ;;
+  interix*)
+    # we just hope/assume this is gcc and not c89 (= MSVC++)
+    with_gnu_ld=yes
+    ;;
+  openbsd* | bitrig*)
+    with_gnu_ld=no
+    ;;
+  linux* | k*bsd*-gnu | gnu*)
+    _LT_TAGVAR(link_all_deplibs, $1)=no
+    ;;
+  esac
+
+  _LT_TAGVAR(ld_shlibs, $1)=yes
+
+  # On some targets, GNU ld is compatible enough with the native linker
+  # that we're better off using the native interface for both.
+  lt_use_gnu_ld_interface=no
+  if test yes = "$with_gnu_ld"; then
+    case $host_os in
+      aix*)
+	# The AIX port of GNU ld has always aspired to compatibility
+	# with the native linker.  However, as the warning in the GNU ld
+	# block says, versions before 2.19.5* couldn't really create working
+	# shared libraries, regardless of the interface used.
+	case `$LD -v 2>&1` in
+	  *\ \(GNU\ Binutils\)\ 2.19.5*) ;;
+	  *\ \(GNU\ Binutils\)\ 2.[[2-9]]*) ;;
+	  *\ \(GNU\ Binutils\)\ [[3-9]]*) ;;
+	  *)
+	    lt_use_gnu_ld_interface=yes
+	    ;;
+	esac
+	;;
+      *)
+	lt_use_gnu_ld_interface=yes
+	;;
+    esac
+  fi
+
+  if test yes = "$lt_use_gnu_ld_interface"; then
+    # If archive_cmds runs LD, not CC, wlarc should be empty
+    wlarc='$wl'
+
+    # Set some defaults for GNU ld with shared library support. These
+    # are reset later if shared libraries are not supported. Putting them
+    # here allows them to be overridden if necessary.
+    runpath_var=LD_RUN_PATH
+    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+    _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic'
+    # ancient GNU ld didn't support --whole-archive et. al.
+    if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then
+      _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive'
+    else
+      _LT_TAGVAR(whole_archive_flag_spec, $1)=
+    fi
+    supports_anon_versioning=no
+    case `$LD -v | $SED -e 's/([^)]\+)\s\+//' 2>&1` in
+      *GNU\ gold*) supports_anon_versioning=yes ;;
+      *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11
+      *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ...
+      *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ...
+      *\ 2.11.*) ;; # other 2.11 versions
+      *) supports_anon_versioning=yes ;;
+    esac
+
+    # See if GNU ld supports shared libraries.
+    case $host_os in
+    aix[[3-9]]*)
+      # On AIX/PPC, the GNU linker is very broken
+      if test ia64 != "$host_cpu"; then
+	_LT_TAGVAR(ld_shlibs, $1)=no
+	cat <<_LT_EOF 1>&2
+
+*** Warning: the GNU linker, at least up to release 2.19, is reported
+*** to be unable to reliably create shared libraries on AIX.
+*** Therefore, libtool is disabling shared libraries support.  If you
+*** really care for shared libraries, you may want to install binutils
+*** 2.20 or above, or modify your PATH so that a non-GNU linker is found.
+*** You will then need to restart the configuration process.
+
+_LT_EOF
+      fi
+      ;;
+
+    amigaos*)
+      case $host_cpu in
+      powerpc)
+            # see comment about AmigaOS4 .so support
+            _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+            _LT_TAGVAR(archive_expsym_cmds, $1)=''
+        ;;
+      m68k)
+            _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+            _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+            _LT_TAGVAR(hardcode_minus_L, $1)=yes
+        ;;
+      esac
+      ;;
+
+    beos*)
+      if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+	_LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+	# Joseph Beckenbach <jrb3@best.com> says some releases of gcc
+	# support --undefined.  This deserves some investigation.  FIXME
+	_LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+      else
+	_LT_TAGVAR(ld_shlibs, $1)=no
+      fi
+      ;;
+
+    cygwin* | mingw* | pw32* | cegcc*)
+      # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless,
+      # as there is no search path for DLLs.
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+      _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-all-symbols'
+      _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+      _LT_TAGVAR(always_export_symbols, $1)=no
+      _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+      _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols'
+      _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname']
+
+      if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
+        _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+	# If the export-symbols file already is a .def file, use it as
+	# is; otherwise, prepend EXPORTS...
+	_LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then
+          cp $export_symbols $output_objdir/$soname.def;
+        else
+          echo EXPORTS > $output_objdir/$soname.def;
+          cat $export_symbols >> $output_objdir/$soname.def;
+        fi~
+        $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+      else
+	_LT_TAGVAR(ld_shlibs, $1)=no
+      fi
+      ;;
+
+    haiku*)
+      _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+      _LT_TAGVAR(link_all_deplibs, $1)=yes
+      ;;
+
+    os2*)
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+      _LT_TAGVAR(hardcode_minus_L, $1)=yes
+      _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+      shrext_cmds=.dll
+      _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
+	$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
+	$ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
+	$ECHO EXPORTS >> $output_objdir/$libname.def~
+	emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~
+	$CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
+	emximp -o $lib $output_objdir/$libname.def'
+      _LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
+	$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
+	$ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
+	$ECHO EXPORTS >> $output_objdir/$libname.def~
+	prefix_cmds="$SED"~
+	if test EXPORTS = "`$SED 1q $export_symbols`"; then
+	  prefix_cmds="$prefix_cmds -e 1d";
+	fi~
+	prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~
+	cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~
+	$CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
+	emximp -o $lib $output_objdir/$libname.def'
+      _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def'
+      _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+      ;;
+
+    interix[[3-9]]*)
+      _LT_TAGVAR(hardcode_direct, $1)=no
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir'
+      _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
+      # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
+      # Instead, shared libraries are loaded at an image base (0x10000000 by
+      # default) and relocated if they conflict, which is a slow very memory
+      # consuming and fragmenting process.  To avoid this, we pick a random,
+      # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
+      # time.  Moving up from 0x10000000 also allows more sbrk(2) space.
+      _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+      _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+      ;;
+
+    gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu)
+      tmp_diet=no
+      if test linux-dietlibc = "$host_os"; then
+	case $cc_basename in
+	  diet\ *) tmp_diet=yes;;	# linux-dietlibc with static linking (!diet-dyn)
+	esac
+      fi
+      if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \
+	 && test no = "$tmp_diet"
+      then
+	tmp_addflag=' $pic_flag'
+	tmp_sharedflag='-shared'
+	case $cc_basename,$host_cpu in
+        pgcc*)				# Portland Group C compiler
+	  _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+	  tmp_addflag=' $pic_flag'
+	  ;;
+	pgf77* | pgf90* | pgf95* | pgfortran*)
+					# Portland Group f77 and f90 compilers
+	  _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+	  tmp_addflag=' $pic_flag -Mnomain' ;;
+	ecc*,ia64* | icc*,ia64*)	# Intel C compiler on ia64
+	  tmp_addflag=' -i_dynamic' ;;
+	efc*,ia64* | ifort*,ia64*)	# Intel Fortran compiler on ia64
+	  tmp_addflag=' -i_dynamic -nofor_main' ;;
+	ifc* | ifort*)			# Intel Fortran compiler
+	  tmp_addflag=' -nofor_main' ;;
+	lf95*)				# Lahey Fortran 8.1
+	  _LT_TAGVAR(whole_archive_flag_spec, $1)=
+	  tmp_sharedflag='--shared' ;;
+        nagfor*)                        # NAGFOR 5.3
+          tmp_sharedflag='-Wl,-shared' ;;
+	xl[[cC]]* | bgxl[[cC]]* | mpixl[[cC]]*) # IBM XL C 8.0 on PPC (deal with xlf below)
+	  tmp_sharedflag='-qmkshrobj'
+	  tmp_addflag= ;;
+	nvcc*)	# Cuda Compiler Driver 2.2
+	  _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+	  _LT_TAGVAR(compiler_needs_object, $1)=yes
+	  ;;
+	esac
+	case `$CC -V 2>&1 | sed 5q` in
+	*Sun\ C*)			# Sun C 5.9
+	  _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+	  _LT_TAGVAR(compiler_needs_object, $1)=yes
+	  tmp_sharedflag='-G' ;;
+	*Sun\ F*)			# Sun Fortran 8.3
+	  tmp_sharedflag='-G' ;;
+	esac
+	_LT_TAGVAR(archive_cmds, $1)='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+
+        if test yes = "$supports_anon_versioning"; then
+          _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~
+            cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+            echo "local: *; };" >> $output_objdir/$libname.ver~
+            $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib'
+        fi
+
+	case $cc_basename in
+	tcc*)
+	  _LT_TAGVAR(export_dynamic_flag_spec, $1)='-rdynamic'
+	  ;;
+	xlf* | bgf* | bgxlf* | mpixlf*)
+	  # IBM XL Fortran 10.1 on PPC cannot create shared libs itself
+	  _LT_TAGVAR(whole_archive_flag_spec, $1)='--whole-archive$convenience --no-whole-archive'
+	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+	  _LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib'
+	  if test yes = "$supports_anon_versioning"; then
+	    _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~
+              cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+              echo "local: *; };" >> $output_objdir/$libname.ver~
+              $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib'
+	  fi
+	  ;;
+	esac
+      else
+        _LT_TAGVAR(ld_shlibs, $1)=no
+      fi
+      ;;
+
+    netbsd* | netbsdelf*-gnu)
+      if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+	_LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
+	wlarc=
+      else
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+      fi
+      ;;
+
+    solaris*)
+      if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then
+	_LT_TAGVAR(ld_shlibs, $1)=no
+	cat <<_LT_EOF 1>&2
+
+*** Warning: The releases 2.8.* of the GNU linker cannot reliably
+*** create shared libraries on Solaris systems.  Therefore, libtool
+*** is disabling shared libraries support.  We urge you to upgrade GNU
+*** binutils to release 2.9.1 or newer.  Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+_LT_EOF
+      elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+      else
+	_LT_TAGVAR(ld_shlibs, $1)=no
+      fi
+      ;;
+
+    sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*)
+      case `$LD -v 2>&1` in
+        *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.1[[0-5]].*)
+	_LT_TAGVAR(ld_shlibs, $1)=no
+	cat <<_LT_EOF 1>&2
+
+*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 cannot
+*** reliably create shared libraries on SCO systems.  Therefore, libtool
+*** is disabling shared libraries support.  We urge you to upgrade GNU
+*** binutils to release 2.16.91.0.3 or newer.  Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+_LT_EOF
+	;;
+	*)
+	  # For security reasons, it is highly recommended that you always
+	  # use absolute paths for naming shared libraries, and exclude the
+	  # DT_RUNPATH tag from executables and libraries.  But doing so
+	  # requires that you compile everything twice, which is a pain.
+	  if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+	    _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+	    _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+	  else
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	  fi
+	;;
+      esac
+      ;;
+
+    sunos4*)
+      _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+      wlarc=
+      _LT_TAGVAR(hardcode_direct, $1)=yes
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    *)
+      if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+      else
+	_LT_TAGVAR(ld_shlibs, $1)=no
+      fi
+      ;;
+    esac
+
+    if test no = "$_LT_TAGVAR(ld_shlibs, $1)"; then
+      runpath_var=
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+      _LT_TAGVAR(export_dynamic_flag_spec, $1)=
+      _LT_TAGVAR(whole_archive_flag_spec, $1)=
+    fi
+  else
+    # PORTME fill in a description of your system's linker (not GNU ld)
+    case $host_os in
+    aix3*)
+      _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+      _LT_TAGVAR(always_export_symbols, $1)=yes
+      _LT_TAGVAR(archive_expsym_cmds, $1)='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname'
+      # Note: this linker hardcodes the directories in LIBPATH if there
+      # are no directories specified by -L.
+      _LT_TAGVAR(hardcode_minus_L, $1)=yes
+      if test yes = "$GCC" && test -z "$lt_prog_compiler_static"; then
+	# Neither direct hardcoding nor static linking is supported with a
+	# broken collect2.
+	_LT_TAGVAR(hardcode_direct, $1)=unsupported
+      fi
+      ;;
+
+    aix[[4-9]]*)
+      if test ia64 = "$host_cpu"; then
+	# On IA64, the linker does run time linking by default, so we don't
+	# have to do anything special.
+	aix_use_runtimelinking=no
+	exp_sym_flag='-Bexport'
+	no_entry_flag=
+      else
+	# If we're using GNU nm, then we don't want the "-C" option.
+	# -C means demangle to GNU nm, but means don't demangle to AIX nm.
+	# Without the "-l" option, or with the "-B" option, AIX nm treats
+	# weak defined symbols like other global defined symbols, whereas
+	# GNU nm marks them as "W".
+	# While the 'weak' keyword is ignored in the Export File, we need
+	# it in the Import File for the 'aix-soname' feature, so we have
+	# to replace the "-B" option with "-P" for AIX nm.
+	if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
+	  _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols'
+	else
+	  _LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols'
+	fi
+	aix_use_runtimelinking=no
+
+	# Test if we are trying to use run time linking or normal
+	# AIX style linking. If -brtl is somewhere in LDFLAGS, we
+	# have runtime linking enabled, and use it for executables.
+	# For shared libraries, we enable/disable runtime linking
+	# depending on the kind of the shared library created -
+	# when "with_aix_soname,aix_use_runtimelinking" is:
+	# "aix,no"   lib.a(lib.so.V) shared, rtl:no,  for executables
+	# "aix,yes"  lib.so          shared, rtl:yes, for executables
+	#            lib.a           static archive
+	# "both,no"  lib.so.V(shr.o) shared, rtl:yes
+	#            lib.a(lib.so.V) shared, rtl:no,  for executables
+	# "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables
+	#            lib.a(lib.so.V) shared, rtl:no
+	# "svr4,*"   lib.so.V(shr.o) shared, rtl:yes, for executables
+	#            lib.a           static archive
+	case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*)
+	  for ld_flag in $LDFLAGS; do
+	  if (test x-brtl = "x$ld_flag" || test x-Wl,-brtl = "x$ld_flag"); then
+	    aix_use_runtimelinking=yes
+	    break
+	  fi
+	  done
+	  if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then
+	    # With aix-soname=svr4, we create the lib.so.V shared archives only,
+	    # so we don't have lib.a shared libs to link our executables.
+	    # We have to force runtime linking in this case.
+	    aix_use_runtimelinking=yes
+	    LDFLAGS="$LDFLAGS -Wl,-brtl"
+	  fi
+	  ;;
+	esac
+
+	exp_sym_flag='-bexport'
+	no_entry_flag='-bnoentry'
+      fi
+
+      # When large executables or shared objects are built, AIX ld can
+      # have problems creating the table of contents.  If linking a library
+      # or program results in "error TOC overflow" add -mminimal-toc to
+      # CXXFLAGS/CFLAGS for g++/gcc.  In the cases where that is not
+      # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
+
+      _LT_TAGVAR(archive_cmds, $1)=''
+      _LT_TAGVAR(hardcode_direct, $1)=yes
+      _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+      _LT_TAGVAR(hardcode_libdir_separator, $1)=':'
+      _LT_TAGVAR(link_all_deplibs, $1)=yes
+      _LT_TAGVAR(file_list_spec, $1)='$wl-f,'
+      case $with_aix_soname,$aix_use_runtimelinking in
+      aix,*) ;; # traditional, no import file
+      svr4,* | *,yes) # use import file
+	# The Import File defines what to hardcode.
+	_LT_TAGVAR(hardcode_direct, $1)=no
+	_LT_TAGVAR(hardcode_direct_absolute, $1)=no
+	;;
+      esac
+
+      if test yes = "$GCC"; then
+	case $host_os in aix4.[[012]]|aix4.[[012]].*)
+	# We only want to do this on AIX 4.2 and lower, the check
+	# below for broken collect2 doesn't work under 4.3+
+	  collect2name=`$CC -print-prog-name=collect2`
+	  if test -f "$collect2name" &&
+	   strings "$collect2name" | $GREP resolve_lib_name >/dev/null
+	  then
+	  # We have reworked collect2
+	  :
+	  else
+	  # We have old collect2
+	  _LT_TAGVAR(hardcode_direct, $1)=unsupported
+	  # It fails to find uninstalled libraries when the uninstalled
+	  # path is not listed in the libpath.  Setting hardcode_minus_L
+	  # to unsupported forces relinking
+	  _LT_TAGVAR(hardcode_minus_L, $1)=yes
+	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+	  _LT_TAGVAR(hardcode_libdir_separator, $1)=
+	  fi
+	  ;;
+	esac
+	shared_flag='-shared'
+	if test yes = "$aix_use_runtimelinking"; then
+	  shared_flag="$shared_flag "'$wl-G'
+	fi
+	# Need to ensure runtime linking is disabled for the traditional
+	# shared library, or the linker may eventually find shared libraries
+	# /with/ Import File - we do not want to mix them.
+	shared_flag_aix='-shared'
+	shared_flag_svr4='-shared $wl-G'
+      else
+	# not using gcc
+	if test ia64 = "$host_cpu"; then
+	# VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
+	# chokes on -Wl,-G. The following line is correct:
+	  shared_flag='-G'
+	else
+	  if test yes = "$aix_use_runtimelinking"; then
+	    shared_flag='$wl-G'
+	  else
+	    shared_flag='$wl-bM:SRE'
+	  fi
+	  shared_flag_aix='$wl-bM:SRE'
+	  shared_flag_svr4='$wl-G'
+	fi
+      fi
+
+      _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-bexpall'
+      # It seems that -bexpall does not export symbols beginning with
+      # underscore (_), so it is better to generate a list of symbols to export.
+      _LT_TAGVAR(always_export_symbols, $1)=yes
+      if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then
+	# Warning - without using the other runtime loading flags (-brtl),
+	# -berok will link without error, but may produce a broken library.
+	_LT_TAGVAR(allow_undefined_flag, $1)='-berok'
+        # Determine the default libpath from the value encoded in an
+        # empty executable.
+        _LT_SYS_MODULE_PATH_AIX([$1])
+        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath"
+        _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag
+      else
+	if test ia64 = "$host_cpu"; then
+	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $libdir:/usr/lib:/lib'
+	  _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs"
+	  _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols"
+	else
+	 # Determine the default libpath from the value encoded in an
+	 # empty executable.
+	 _LT_SYS_MODULE_PATH_AIX([$1])
+	 _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath"
+	  # Warning - without using the other run time loading flags,
+	  # -berok will link without error, but may produce a broken library.
+	  _LT_TAGVAR(no_undefined_flag, $1)=' $wl-bernotok'
+	  _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-berok'
+	  if test yes = "$with_gnu_ld"; then
+	    # We only use this code for GNU lds that support --whole-archive.
+	    _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive'
+	  else
+	    # Exported symbols can be pulled into shared objects from archives
+	    _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience'
+	  fi
+	  _LT_TAGVAR(archive_cmds_need_lc, $1)=yes
+	  _LT_TAGVAR(archive_expsym_cmds, $1)='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d'
+	  # -brtl affects multiple linker settings, -berok does not and is overridden later
+	  compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([[, ]]\\)%-berok\\1%g"`'
+	  if test svr4 != "$with_aix_soname"; then
+	    # This is similar to how AIX traditionally builds its shared libraries.
+	    _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname'
+	  fi
+	  if test aix != "$with_aix_soname"; then
+	    _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp'
+	  else
+	    # used by -dlpreopen to get the symbols
+	    _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$MV  $output_objdir/$realname.d/$soname $output_objdir'
+	  fi
+	  _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$RM -r $output_objdir/$realname.d'
+	fi
+      fi
+      ;;
+
+    amigaos*)
+      case $host_cpu in
+      powerpc)
+            # see comment about AmigaOS4 .so support
+            _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+            _LT_TAGVAR(archive_expsym_cmds, $1)=''
+        ;;
+      m68k)
+            _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+            _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+            _LT_TAGVAR(hardcode_minus_L, $1)=yes
+        ;;
+      esac
+      ;;
+
+    bsdi[[45]]*)
+      _LT_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic
+      ;;
+
+    cygwin* | mingw* | pw32* | cegcc*)
+      # When not using gcc, we currently assume that we are using
+      # Microsoft Visual C++.
+      # hardcode_libdir_flag_spec is actually meaningless, as there is
+      # no search path for DLLs.
+      case $cc_basename in
+      cl*)
+	# Native MSVC
+	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' '
+	_LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+	_LT_TAGVAR(always_export_symbols, $1)=yes
+	_LT_TAGVAR(file_list_spec, $1)='@'
+	# Tell ltmain to make .lib files, not .a files.
+	libext=lib
+	# Tell ltmain to make .dll files, not .so files.
+	shrext_cmds=.dll
+	# FIXME: Setting linknames here is a bad hack.
+	_LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames='
+	_LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then
+            cp "$export_symbols" "$output_objdir/$soname.def";
+            echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp";
+          else
+            $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp;
+          fi~
+          $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
+          linknames='
+	# The linker will not automatically build a static lib if we build a DLL.
+	# _LT_TAGVAR(old_archive_from_new_cmds, $1)='true'
+	_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+	_LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*'
+	_LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1,DATA/'\'' | $SED -e '\''/^[[AITW]][[ ]]/s/.*[[ ]]//'\'' | sort | uniq > $export_symbols'
+	# Don't use ranlib
+	_LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib'
+	_LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~
+          lt_tool_outputfile="@TOOL_OUTPUT@"~
+          case $lt_outputfile in
+            *.exe|*.EXE) ;;
+            *)
+              lt_outputfile=$lt_outputfile.exe
+              lt_tool_outputfile=$lt_tool_outputfile.exe
+              ;;
+          esac~
+          if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then
+            $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1;
+            $RM "$lt_outputfile.manifest";
+          fi'
+	;;
+      *)
+	# Assume MSVC wrapper
+	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' '
+	_LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+	# Tell ltmain to make .lib files, not .a files.
+	libext=lib
+	# Tell ltmain to make .dll files, not .so files.
+	shrext_cmds=.dll
+	# FIXME: Setting linknames here is a bad hack.
+	_LT_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames='
+	# The linker will automatically build a .lib file if we build a DLL.
+	_LT_TAGVAR(old_archive_from_new_cmds, $1)='true'
+	# FIXME: Should let the user specify the lib program.
+	_LT_TAGVAR(old_archive_cmds, $1)='lib -OUT:$oldlib$oldobjs$old_deplibs'
+	_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+	;;
+      esac
+      ;;
+
+    darwin* | rhapsody*)
+      _LT_DARWIN_LINKER_FEATURES($1)
+      ;;
+
+    dgux*)
+      _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor
+    # support.  Future versions do this automatically, but an explicit c++rt0.o
+    # does not break anything, and helps significantly (at the cost of a little
+    # extra space).
+    freebsd2.2*)
+      _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o'
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+      _LT_TAGVAR(hardcode_direct, $1)=yes
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    # Unfortunately, older versions of FreeBSD 2 do not have this feature.
+    freebsd2.*)
+      _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+      _LT_TAGVAR(hardcode_direct, $1)=yes
+      _LT_TAGVAR(hardcode_minus_L, $1)=yes
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    # FreeBSD 3 and greater uses gcc -shared to do shared libraries.
+    freebsd* | dragonfly*)
+      _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+      _LT_TAGVAR(hardcode_direct, $1)=yes
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    hpux9*)
+      if test yes = "$GCC"; then
+	_LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib'
+      else
+	_LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib'
+      fi
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir'
+      _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+      _LT_TAGVAR(hardcode_direct, $1)=yes
+
+      # hardcode_minus_L: Not really in the search PATH,
+      # but as the default location of the library.
+      _LT_TAGVAR(hardcode_minus_L, $1)=yes
+      _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
+      ;;
+
+    hpux10*)
+      if test yes,no = "$GCC,$with_gnu_ld"; then
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+      else
+	_LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
+      fi
+      if test no = "$with_gnu_ld"; then
+	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir'
+	_LT_TAGVAR(hardcode_libdir_separator, $1)=:
+	_LT_TAGVAR(hardcode_direct, $1)=yes
+	_LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+	_LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
+	# hardcode_minus_L: Not really in the search PATH,
+	# but as the default location of the library.
+	_LT_TAGVAR(hardcode_minus_L, $1)=yes
+      fi
+      ;;
+
+    hpux11*)
+      if test yes,no = "$GCC,$with_gnu_ld"; then
+	case $host_cpu in
+	hppa*64*)
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	ia64*)
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	*)
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	esac
+      else
+	case $host_cpu in
+	hppa*64*)
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	ia64*)
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	*)
+	m4_if($1, [], [
+	  # Older versions of the 11.00 compiler do not understand -b yet
+	  # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does)
+	  _LT_LINKER_OPTION([if $CC understands -b],
+	    _LT_TAGVAR(lt_cv_prog_compiler__b, $1), [-b],
+	    [_LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags'],
+	    [_LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'])],
+	  [_LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags'])
+	  ;;
+	esac
+      fi
+      if test no = "$with_gnu_ld"; then
+	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir'
+	_LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+	case $host_cpu in
+	hppa*64*|ia64*)
+	  _LT_TAGVAR(hardcode_direct, $1)=no
+	  _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+	  ;;
+	*)
+	  _LT_TAGVAR(hardcode_direct, $1)=yes
+	  _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+	  _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
+
+	  # hardcode_minus_L: Not really in the search PATH,
+	  # but as the default location of the library.
+	  _LT_TAGVAR(hardcode_minus_L, $1)=yes
+	  ;;
+	esac
+      fi
+      ;;
+
+    irix5* | irix6* | nonstopux*)
+      if test yes = "$GCC"; then
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
+	# Try to use the -exported_symbol ld option, if it does not
+	# work, assume that -exports_file does not work either and
+	# implicitly export all symbols.
+	# This should be the same for all languages, so no per-tag cache variable.
+	AC_CACHE_CHECK([whether the $host_os linker accepts -exported_symbol],
+	  [lt_cv_irix_exported_symbol],
+	  [save_LDFLAGS=$LDFLAGS
+	   LDFLAGS="$LDFLAGS -shared $wl-exported_symbol ${wl}foo $wl-update_registry $wl/dev/null"
+	   AC_LINK_IFELSE(
+	     [AC_LANG_SOURCE(
+	        [AC_LANG_CASE([C], [[int foo (void) { return 0; }]],
+			      [C++], [[int foo (void) { return 0; }]],
+			      [Fortran 77], [[
+      subroutine foo
+      end]],
+			      [Fortran], [[
+      subroutine foo
+      end]])])],
+	      [lt_cv_irix_exported_symbol=yes],
+	      [lt_cv_irix_exported_symbol=no])
+           LDFLAGS=$save_LDFLAGS])
+	if test yes = "$lt_cv_irix_exported_symbol"; then
+          _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations $wl-exports_file $wl$export_symbols -o $lib'
+	fi
+	_LT_TAGVAR(link_all_deplibs, $1)=no
+      else
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -exports_file $export_symbols -o $lib'
+      fi
+      _LT_TAGVAR(archive_cmds_need_lc, $1)='no'
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+      _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+      _LT_TAGVAR(inherit_rpath, $1)=yes
+      _LT_TAGVAR(link_all_deplibs, $1)=yes
+      ;;
+
+    linux*)
+      case $cc_basename in
+      tcc*)
+	# Fabrice Bellard et al's Tiny C Compiler
+	_LT_TAGVAR(ld_shlibs, $1)=yes
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+	;;
+      esac
+      ;;
+
+    netbsd* | netbsdelf*-gnu)
+      if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+	_LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'  # a.out
+      else
+	_LT_TAGVAR(archive_cmds, $1)='$LD -shared -o $lib $libobjs $deplibs $linker_flags'      # ELF
+      fi
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+      _LT_TAGVAR(hardcode_direct, $1)=yes
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    newsos6)
+      _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      _LT_TAGVAR(hardcode_direct, $1)=yes
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+      _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    *nto* | *qnx*)
+      ;;
+
+    openbsd* | bitrig*)
+      if test -f /usr/libexec/ld.so; then
+	_LT_TAGVAR(hardcode_direct, $1)=yes
+	_LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+	_LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+	if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+	  _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags $wl-retain-symbols-file,$export_symbols'
+	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir'
+	  _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
+	else
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir'
+	fi
+      else
+	_LT_TAGVAR(ld_shlibs, $1)=no
+      fi
+      ;;
+
+    os2*)
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+      _LT_TAGVAR(hardcode_minus_L, $1)=yes
+      _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+      shrext_cmds=.dll
+      _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
+	$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
+	$ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
+	$ECHO EXPORTS >> $output_objdir/$libname.def~
+	emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~
+	$CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
+	emximp -o $lib $output_objdir/$libname.def'
+      _LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
+	$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
+	$ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
+	$ECHO EXPORTS >> $output_objdir/$libname.def~
+	prefix_cmds="$SED"~
+	if test EXPORTS = "`$SED 1q $export_symbols`"; then
+	  prefix_cmds="$prefix_cmds -e 1d";
+	fi~
+	prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~
+	cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~
+	$CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
+	emximp -o $lib $output_objdir/$libname.def'
+      _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def'
+      _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+      ;;
+
+    osf3*)
+      if test yes = "$GCC"; then
+	_LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*'
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
+      else
+	_LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
+      fi
+      _LT_TAGVAR(archive_cmds_need_lc, $1)='no'
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+      _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+      ;;
+
+    osf4* | osf5*)	# as osf3* with the addition of -msym flag
+      if test yes = "$GCC"; then
+	_LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*'
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $pic_flag $libobjs $deplibs $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
+	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+      else
+	_LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~
+          $CC -shared$allow_undefined_flag $wl-input $wl$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~$RM $lib.exp'
+
+	# Both c and cxx compiler support -rpath directly
+	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'
+      fi
+      _LT_TAGVAR(archive_cmds_need_lc, $1)='no'
+      _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+      ;;
+
+    solaris*)
+      _LT_TAGVAR(no_undefined_flag, $1)=' -z defs'
+      if test yes = "$GCC"; then
+	wlarc='$wl'
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl-z ${wl}text $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+          $CC -shared $pic_flag $wl-z ${wl}text $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+      else
+	case `$CC -V 2>&1` in
+	*"Compilers 5.0"*)
+	  wlarc=''
+	  _LT_TAGVAR(archive_cmds, $1)='$LD -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $linker_flags'
+	  _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+            $LD -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp'
+	  ;;
+	*)
+	  wlarc='$wl'
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $compiler_flags'
+	  _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+            $CC -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+	  ;;
+	esac
+      fi
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      case $host_os in
+      solaris2.[[0-5]] | solaris2.[[0-5]].*) ;;
+      *)
+	# The compiler driver will combine and reorder linker options,
+	# but understands '-z linker_flag'.  GCC discards it without '$wl',
+	# but is careful enough not to reorder.
+	# Supported since Solaris 2.6 (maybe 2.5.1?)
+	if test yes = "$GCC"; then
+	  _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract'
+	else
+	  _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract'
+	fi
+	;;
+      esac
+      _LT_TAGVAR(link_all_deplibs, $1)=yes
+      ;;
+
+    sunos4*)
+      if test sequent = "$host_vendor"; then
+	# Use $CC to link under sequent, because it throws in some extra .o
+	# files that make .init and .fini sections work.
+	_LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h $soname -o $lib $libobjs $deplibs $compiler_flags'
+      else
+	_LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags'
+      fi
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+      _LT_TAGVAR(hardcode_direct, $1)=yes
+      _LT_TAGVAR(hardcode_minus_L, $1)=yes
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    sysv4)
+      case $host_vendor in
+	sni)
+	  _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+	  _LT_TAGVAR(hardcode_direct, $1)=yes # is this really true???
+	;;
+	siemens)
+	  ## LD is ld it makes a PLAMLIB
+	  ## CC just makes a GrossModule.
+	  _LT_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags'
+	  _LT_TAGVAR(reload_cmds, $1)='$CC -r -o $output$reload_objs'
+	  _LT_TAGVAR(hardcode_direct, $1)=no
+        ;;
+	motorola)
+	  _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+	  _LT_TAGVAR(hardcode_direct, $1)=no #Motorola manual says yes, but my tests say they lie
+	;;
+      esac
+      runpath_var='LD_RUN_PATH'
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    sysv4.3*)
+      _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      _LT_TAGVAR(export_dynamic_flag_spec, $1)='-Bexport'
+      ;;
+
+    sysv4*MP*)
+      if test -d /usr/nec; then
+	_LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+	_LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+	runpath_var=LD_RUN_PATH
+	hardcode_runpath_var=yes
+	_LT_TAGVAR(ld_shlibs, $1)=yes
+      fi
+      ;;
+
+    sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*)
+      _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text'
+      _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      runpath_var='LD_RUN_PATH'
+
+      if test yes = "$GCC"; then
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+      else
+	_LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+      fi
+      ;;
+
+    sysv5* | sco3.2v5* | sco5v6*)
+      # Note: We CANNOT use -z defs as we might desire, because we do not
+      # link with -lc, and that would cause any symbols used from libc to
+      # always be unresolved, which means just about no library would
+      # ever link correctly.  If we're not using GNU ld we use -z text
+      # though, which does catch some bad symbols but isn't as heavy-handed
+      # as -z defs.
+      _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text'
+      _LT_TAGVAR(allow_undefined_flag, $1)='$wl-z,nodefs'
+      _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R,$libdir'
+      _LT_TAGVAR(hardcode_libdir_separator, $1)=':'
+      _LT_TAGVAR(link_all_deplibs, $1)=yes
+      _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Bexport'
+      runpath_var='LD_RUN_PATH'
+
+      if test yes = "$GCC"; then
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+      else
+	_LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+      fi
+      ;;
+
+    uts4*)
+      _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    *)
+      _LT_TAGVAR(ld_shlibs, $1)=no
+      ;;
+    esac
+
+    if test sni = "$host_vendor"; then
+      case $host in
+      sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+	_LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Blargedynsym'
+	;;
+      esac
+    fi
+  fi
+])
+AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)])
+test no = "$_LT_TAGVAR(ld_shlibs, $1)" && can_build_shared=no
+
+_LT_TAGVAR(with_gnu_ld, $1)=$with_gnu_ld
+
+_LT_DECL([], [libext], [0], [Old archive suffix (normally "a")])dnl
+_LT_DECL([], [shrext_cmds], [1], [Shared library suffix (normally ".so")])dnl
+_LT_DECL([], [extract_expsyms_cmds], [2],
+    [The commands to extract the exported symbol list from a shared archive])
+
+#
+# Do we need to explicitly link libc?
+#
+case "x$_LT_TAGVAR(archive_cmds_need_lc, $1)" in
+x|xyes)
+  # Assume -lc should be added
+  _LT_TAGVAR(archive_cmds_need_lc, $1)=yes
+
+  if test yes,yes = "$GCC,$enable_shared"; then
+    case $_LT_TAGVAR(archive_cmds, $1) in
+    *'~'*)
+      # FIXME: we may have to deal with multi-command sequences.
+      ;;
+    '$CC '*)
+      # Test whether the compiler implicitly links with -lc since on some
+      # systems, -lgcc has to come before -lc. If gcc already passes -lc
+      # to ld, don't add -lc before -lgcc.
+      AC_CACHE_CHECK([whether -lc should be explicitly linked in],
+	[lt_cv_]_LT_TAGVAR(archive_cmds_need_lc, $1),
+	[$RM conftest*
+	echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+	if AC_TRY_EVAL(ac_compile) 2>conftest.err; then
+	  soname=conftest
+	  lib=conftest
+	  libobjs=conftest.$ac_objext
+	  deplibs=
+	  wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1)
+	  pic_flag=$_LT_TAGVAR(lt_prog_compiler_pic, $1)
+	  compiler_flags=-v
+	  linker_flags=-v
+	  verstring=
+	  output_objdir=.
+	  libname=conftest
+	  lt_save_allow_undefined_flag=$_LT_TAGVAR(allow_undefined_flag, $1)
+	  _LT_TAGVAR(allow_undefined_flag, $1)=
+	  if AC_TRY_EVAL(_LT_TAGVAR(archive_cmds, $1) 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1)
+	  then
+	    lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+	  else
+	    lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=yes
+	  fi
+	  _LT_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag
+	else
+	  cat conftest.err 1>&5
+	fi
+	$RM conftest*
+	])
+      _LT_TAGVAR(archive_cmds_need_lc, $1)=$lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)
+      ;;
+    esac
+  fi
+  ;;
+esac
+
+_LT_TAGDECL([build_libtool_need_lc], [archive_cmds_need_lc], [0],
+    [Whether or not to add -lc for building shared libraries])
+_LT_TAGDECL([allow_libtool_libs_with_static_runtimes],
+    [enable_shared_with_static_runtimes], [0],
+    [Whether or not to disallow shared libs when runtime libs are static])
+_LT_TAGDECL([], [export_dynamic_flag_spec], [1],
+    [Compiler flag to allow reflexive dlopens])
+_LT_TAGDECL([], [whole_archive_flag_spec], [1],
+    [Compiler flag to generate shared objects directly from archives])
+_LT_TAGDECL([], [compiler_needs_object], [1],
+    [Whether the compiler copes with passing no objects directly])
+_LT_TAGDECL([], [old_archive_from_new_cmds], [2],
+    [Create an old-style archive from a shared archive])
+_LT_TAGDECL([], [old_archive_from_expsyms_cmds], [2],
+    [Create a temporary old-style archive to link instead of a shared archive])
+_LT_TAGDECL([], [archive_cmds], [2], [Commands used to build a shared archive])
+_LT_TAGDECL([], [archive_expsym_cmds], [2])
+_LT_TAGDECL([], [module_cmds], [2],
+    [Commands used to build a loadable module if different from building
+    a shared archive.])
+_LT_TAGDECL([], [module_expsym_cmds], [2])
+_LT_TAGDECL([], [with_gnu_ld], [1],
+    [Whether we are building with GNU ld or not])
+_LT_TAGDECL([], [allow_undefined_flag], [1],
+    [Flag that allows shared libraries with undefined symbols to be built])
+_LT_TAGDECL([], [no_undefined_flag], [1],
+    [Flag that enforces no undefined symbols])
+_LT_TAGDECL([], [hardcode_libdir_flag_spec], [1],
+    [Flag to hardcode $libdir into a binary during linking.
+    This must work even if $libdir does not exist])
+_LT_TAGDECL([], [hardcode_libdir_separator], [1],
+    [Whether we need a single "-rpath" flag with a separated argument])
+_LT_TAGDECL([], [hardcode_direct], [0],
+    [Set to "yes" if using DIR/libNAME$shared_ext during linking hardcodes
+    DIR into the resulting binary])
+_LT_TAGDECL([], [hardcode_direct_absolute], [0],
+    [Set to "yes" if using DIR/libNAME$shared_ext during linking hardcodes
+    DIR into the resulting binary and the resulting library dependency is
+    "absolute", i.e impossible to change by setting $shlibpath_var if the
+    library is relocated])
+_LT_TAGDECL([], [hardcode_minus_L], [0],
+    [Set to "yes" if using the -LDIR flag during linking hardcodes DIR
+    into the resulting binary])
+_LT_TAGDECL([], [hardcode_shlibpath_var], [0],
+    [Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR
+    into the resulting binary])
+_LT_TAGDECL([], [hardcode_automatic], [0],
+    [Set to "yes" if building a shared library automatically hardcodes DIR
+    into the library and all subsequent libraries and executables linked
+    against it])
+_LT_TAGDECL([], [inherit_rpath], [0],
+    [Set to yes if linker adds runtime paths of dependent libraries
+    to runtime path list])
+_LT_TAGDECL([], [link_all_deplibs], [0],
+    [Whether libtool must link a program against all its dependency libraries])
+_LT_TAGDECL([], [always_export_symbols], [0],
+    [Set to "yes" if exported symbols are required])
+_LT_TAGDECL([], [export_symbols_cmds], [2],
+    [The commands to list exported symbols])
+_LT_TAGDECL([], [exclude_expsyms], [1],
+    [Symbols that should not be listed in the preloaded symbols])
+_LT_TAGDECL([], [include_expsyms], [1],
+    [Symbols that must always be exported])
+_LT_TAGDECL([], [prelink_cmds], [2],
+    [Commands necessary for linking programs (against libraries) with templates])
+_LT_TAGDECL([], [postlink_cmds], [2],
+    [Commands necessary for finishing linking programs])
+_LT_TAGDECL([], [file_list_spec], [1],
+    [Specify filename containing input files])
+dnl FIXME: Not yet implemented
+dnl _LT_TAGDECL([], [thread_safe_flag_spec], [1],
+dnl    [Compiler flag to generate thread safe objects])
+])# _LT_LINKER_SHLIBS
+
+
+# _LT_LANG_C_CONFIG([TAG])
+# ------------------------
+# Ensure that the configuration variables for a C compiler are suitably
+# defined.  These variables are subsequently used by _LT_CONFIG to write
+# the compiler configuration to 'libtool'.
+m4_defun([_LT_LANG_C_CONFIG],
+[m4_require([_LT_DECL_EGREP])dnl
+lt_save_CC=$CC
+AC_LANG_PUSH(C)
+
+# Source file extension for C test sources.
+ac_ext=c
+
+# Object file extension for compiled C test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="int some_variable = 0;"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code='int main(){return(0);}'
+
+_LT_TAG_COMPILER
+# Save the default compiler, since it gets overwritten when the other
+# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP.
+compiler_DEFAULT=$CC
+
+# save warnings/boilerplate of simple test code
+_LT_COMPILER_BOILERPLATE
+_LT_LINKER_BOILERPLATE
+
+## CAVEAT EMPTOR:
+## There is no encapsulation within the following macros, do not change
+## the running order or otherwise move them around unless you know exactly
+## what you are doing...
+if test -n "$compiler"; then
+  _LT_COMPILER_NO_RTTI($1)
+  _LT_COMPILER_PIC($1)
+  _LT_COMPILER_C_O($1)
+  _LT_COMPILER_FILE_LOCKS($1)
+  _LT_LINKER_SHLIBS($1)
+  _LT_SYS_DYNAMIC_LINKER($1)
+  _LT_LINKER_HARDCODE_LIBPATH($1)
+  LT_SYS_DLOPEN_SELF
+  _LT_CMD_STRIPLIB
+
+  # Report what library types will actually be built
+  AC_MSG_CHECKING([if libtool supports shared libraries])
+  AC_MSG_RESULT([$can_build_shared])
+
+  AC_MSG_CHECKING([whether to build shared libraries])
+  test no = "$can_build_shared" && enable_shared=no
+
+  # On AIX, shared libraries and static libraries use the same namespace, and
+  # are all built from PIC.
+  case $host_os in
+  aix3*)
+    test yes = "$enable_shared" && enable_static=no
+    if test -n "$RANLIB"; then
+      archive_cmds="$archive_cmds~\$RANLIB \$lib"
+      postinstall_cmds='$RANLIB $lib'
+    fi
+    ;;
+
+  aix[[4-9]]*)
+    if test ia64 != "$host_cpu"; then
+      case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in
+      yes,aix,yes) ;;			# shared object as lib.so file only
+      yes,svr4,*) ;;			# shared object as lib.so archive member only
+      yes,*) enable_static=no ;;	# shared object in lib.a archive as well
+      esac
+    fi
+    ;;
+  esac
+  AC_MSG_RESULT([$enable_shared])
+
+  AC_MSG_CHECKING([whether to build static libraries])
+  # Make sure either enable_shared or enable_static is yes.
+  test yes = "$enable_shared" || enable_static=yes
+  AC_MSG_RESULT([$enable_static])
+
+  _LT_CONFIG($1)
+fi
+AC_LANG_POP
+CC=$lt_save_CC
+])# _LT_LANG_C_CONFIG
+
+
+# _LT_LANG_CXX_CONFIG([TAG])
+# --------------------------
+# Ensure that the configuration variables for a C++ compiler are suitably
+# defined.  These variables are subsequently used by _LT_CONFIG to write
+# the compiler configuration to 'libtool'.
+m4_defun([_LT_LANG_CXX_CONFIG],
+[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_DECL_EGREP])dnl
+m4_require([_LT_PATH_MANIFEST_TOOL])dnl
+if test -n "$CXX" && ( test no != "$CXX" &&
+    ( (test g++ = "$CXX" && `g++ -v >/dev/null 2>&1` ) ||
+    (test g++ != "$CXX"))); then
+  AC_PROG_CXXCPP
+else
+  _lt_caught_CXX_error=yes
+fi
+
+AC_LANG_PUSH(C++)
+_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+_LT_TAGVAR(allow_undefined_flag, $1)=
+_LT_TAGVAR(always_export_symbols, $1)=no
+_LT_TAGVAR(archive_expsym_cmds, $1)=
+_LT_TAGVAR(compiler_needs_object, $1)=no
+_LT_TAGVAR(export_dynamic_flag_spec, $1)=
+_LT_TAGVAR(hardcode_direct, $1)=no
+_LT_TAGVAR(hardcode_direct_absolute, $1)=no
+_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+_LT_TAGVAR(hardcode_libdir_separator, $1)=
+_LT_TAGVAR(hardcode_minus_L, $1)=no
+_LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
+_LT_TAGVAR(hardcode_automatic, $1)=no
+_LT_TAGVAR(inherit_rpath, $1)=no
+_LT_TAGVAR(module_cmds, $1)=
+_LT_TAGVAR(module_expsym_cmds, $1)=
+_LT_TAGVAR(link_all_deplibs, $1)=unknown
+_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+_LT_TAGVAR(reload_flag, $1)=$reload_flag
+_LT_TAGVAR(reload_cmds, $1)=$reload_cmds
+_LT_TAGVAR(no_undefined_flag, $1)=
+_LT_TAGVAR(whole_archive_flag_spec, $1)=
+_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no
+
+# Source file extension for C++ test sources.
+ac_ext=cpp
+
+# Object file extension for compiled C++ test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# No sense in running all these tests if we already determined that
+# the CXX compiler isn't working.  Some variables (like enable_shared)
+# are currently assumed to apply to all compilers on this platform,
+# and will be corrupted by setting them based on a non-working compiler.
+if test yes != "$_lt_caught_CXX_error"; then
+  # Code to be used in simple compile tests
+  lt_simple_compile_test_code="int some_variable = 0;"
+
+  # Code to be used in simple link tests
+  lt_simple_link_test_code='int main(int, char *[[]]) { return(0); }'
+
+  # ltmain only uses $CC for tagged configurations so make sure $CC is set.
+  _LT_TAG_COMPILER
+
+  # save warnings/boilerplate of simple test code
+  _LT_COMPILER_BOILERPLATE
+  _LT_LINKER_BOILERPLATE
+
+  # Allow CC to be a program name with arguments.
+  lt_save_CC=$CC
+  lt_save_CFLAGS=$CFLAGS
+  lt_save_LD=$LD
+  lt_save_GCC=$GCC
+  GCC=$GXX
+  lt_save_with_gnu_ld=$with_gnu_ld
+  lt_save_path_LD=$lt_cv_path_LD
+  if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then
+    lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx
+  else
+    $as_unset lt_cv_prog_gnu_ld
+  fi
+  if test -n "${lt_cv_path_LDCXX+set}"; then
+    lt_cv_path_LD=$lt_cv_path_LDCXX
+  else
+    $as_unset lt_cv_path_LD
+  fi
+  test -z "${LDCXX+set}" || LD=$LDCXX
+  CC=${CXX-"c++"}
+  CFLAGS=$CXXFLAGS
+  compiler=$CC
+  _LT_TAGVAR(compiler, $1)=$CC
+  _LT_CC_BASENAME([$compiler])
+
+  if test -n "$compiler"; then
+    # We don't want -fno-exception when compiling C++ code, so set the
+    # no_builtin_flag separately
+    if test yes = "$GXX"; then
+      _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin'
+    else
+      _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=
+    fi
+
+    if test yes = "$GXX"; then
+      # Set up default GNU C++ configuration
+
+      LT_PATH_LD
+
+      # Check if GNU C++ uses GNU ld as the underlying linker, since the
+      # archiving commands below assume that GNU ld is being used.
+      if test yes = "$with_gnu_ld"; then
+        _LT_TAGVAR(archive_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib'
+        _LT_TAGVAR(archive_expsym_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+
+        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+        _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic'
+
+        # If archive_cmds runs LD, not CC, wlarc should be empty
+        # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to
+        #     investigate it a little bit more. (MM)
+        wlarc='$wl'
+
+        # ancient GNU ld didn't support --whole-archive et. al.
+        if eval "`$CC -print-prog-name=ld` --help 2>&1" |
+	  $GREP 'no-whole-archive' > /dev/null; then
+          _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive'
+        else
+          _LT_TAGVAR(whole_archive_flag_spec, $1)=
+        fi
+      else
+        with_gnu_ld=no
+        wlarc=
+
+        # A generic and very simple default shared library creation
+        # command for GNU C++ for the case where it uses the native
+        # linker, instead of GNU ld.  If possible, this setting should
+        # overridden to take advantage of the native linker features on
+        # the platform it is being used on.
+        _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib'
+      fi
+
+      # Commands to make compiler produce verbose output that lists
+      # what "hidden" libraries, object files and flags are used when
+      # linking a shared library.
+      output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+
+    else
+      GXX=no
+      with_gnu_ld=no
+      wlarc=
+    fi
+
+    # PORTME: fill in a description of your system's C++ link characteristics
+    AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries])
+    _LT_TAGVAR(ld_shlibs, $1)=yes
+    case $host_os in
+      aix3*)
+        # FIXME: insert proper C++ library support
+        _LT_TAGVAR(ld_shlibs, $1)=no
+        ;;
+      aix[[4-9]]*)
+        if test ia64 = "$host_cpu"; then
+          # On IA64, the linker does run time linking by default, so we don't
+          # have to do anything special.
+          aix_use_runtimelinking=no
+          exp_sym_flag='-Bexport'
+          no_entry_flag=
+        else
+          aix_use_runtimelinking=no
+
+          # Test if we are trying to use run time linking or normal
+          # AIX style linking. If -brtl is somewhere in LDFLAGS, we
+          # have runtime linking enabled, and use it for executables.
+          # For shared libraries, we enable/disable runtime linking
+          # depending on the kind of the shared library created -
+          # when "with_aix_soname,aix_use_runtimelinking" is:
+          # "aix,no"   lib.a(lib.so.V) shared, rtl:no,  for executables
+          # "aix,yes"  lib.so          shared, rtl:yes, for executables
+          #            lib.a           static archive
+          # "both,no"  lib.so.V(shr.o) shared, rtl:yes
+          #            lib.a(lib.so.V) shared, rtl:no,  for executables
+          # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables
+          #            lib.a(lib.so.V) shared, rtl:no
+          # "svr4,*"   lib.so.V(shr.o) shared, rtl:yes, for executables
+          #            lib.a           static archive
+          case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*)
+	    for ld_flag in $LDFLAGS; do
+	      case $ld_flag in
+	      *-brtl*)
+	        aix_use_runtimelinking=yes
+	        break
+	        ;;
+	      esac
+	    done
+	    if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then
+	      # With aix-soname=svr4, we create the lib.so.V shared archives only,
+	      # so we don't have lib.a shared libs to link our executables.
+	      # We have to force runtime linking in this case.
+	      aix_use_runtimelinking=yes
+	      LDFLAGS="$LDFLAGS -Wl,-brtl"
+	    fi
+	    ;;
+          esac
+
+          exp_sym_flag='-bexport'
+          no_entry_flag='-bnoentry'
+        fi
+
+        # When large executables or shared objects are built, AIX ld can
+        # have problems creating the table of contents.  If linking a library
+        # or program results in "error TOC overflow" add -mminimal-toc to
+        # CXXFLAGS/CFLAGS for g++/gcc.  In the cases where that is not
+        # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
+
+        _LT_TAGVAR(archive_cmds, $1)=''
+        _LT_TAGVAR(hardcode_direct, $1)=yes
+        _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+        _LT_TAGVAR(hardcode_libdir_separator, $1)=':'
+        _LT_TAGVAR(link_all_deplibs, $1)=yes
+        _LT_TAGVAR(file_list_spec, $1)='$wl-f,'
+        case $with_aix_soname,$aix_use_runtimelinking in
+        aix,*) ;;	# no import file
+        svr4,* | *,yes) # use import file
+          # The Import File defines what to hardcode.
+          _LT_TAGVAR(hardcode_direct, $1)=no
+          _LT_TAGVAR(hardcode_direct_absolute, $1)=no
+          ;;
+        esac
+
+        if test yes = "$GXX"; then
+          case $host_os in aix4.[[012]]|aix4.[[012]].*)
+          # We only want to do this on AIX 4.2 and lower, the check
+          # below for broken collect2 doesn't work under 4.3+
+	  collect2name=`$CC -print-prog-name=collect2`
+	  if test -f "$collect2name" &&
+	     strings "$collect2name" | $GREP resolve_lib_name >/dev/null
+	  then
+	    # We have reworked collect2
+	    :
+	  else
+	    # We have old collect2
+	    _LT_TAGVAR(hardcode_direct, $1)=unsupported
+	    # It fails to find uninstalled libraries when the uninstalled
+	    # path is not listed in the libpath.  Setting hardcode_minus_L
+	    # to unsupported forces relinking
+	    _LT_TAGVAR(hardcode_minus_L, $1)=yes
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+	    _LT_TAGVAR(hardcode_libdir_separator, $1)=
+	  fi
+          esac
+          shared_flag='-shared'
+	  if test yes = "$aix_use_runtimelinking"; then
+	    shared_flag=$shared_flag' $wl-G'
+	  fi
+	  # Need to ensure runtime linking is disabled for the traditional
+	  # shared library, or the linker may eventually find shared libraries
+	  # /with/ Import File - we do not want to mix them.
+	  shared_flag_aix='-shared'
+	  shared_flag_svr4='-shared $wl-G'
+        else
+          # not using gcc
+          if test ia64 = "$host_cpu"; then
+	  # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
+	  # chokes on -Wl,-G. The following line is correct:
+	  shared_flag='-G'
+          else
+	    if test yes = "$aix_use_runtimelinking"; then
+	      shared_flag='$wl-G'
+	    else
+	      shared_flag='$wl-bM:SRE'
+	    fi
+	    shared_flag_aix='$wl-bM:SRE'
+	    shared_flag_svr4='$wl-G'
+          fi
+        fi
+
+        _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-bexpall'
+        # It seems that -bexpall does not export symbols beginning with
+        # underscore (_), so it is better to generate a list of symbols to
+	# export.
+        _LT_TAGVAR(always_export_symbols, $1)=yes
+	if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then
+          # Warning - without using the other runtime loading flags (-brtl),
+          # -berok will link without error, but may produce a broken library.
+          # The "-G" linker flag allows undefined symbols.
+          _LT_TAGVAR(no_undefined_flag, $1)='-bernotok'
+          # Determine the default libpath from the value encoded in an empty
+          # executable.
+          _LT_SYS_MODULE_PATH_AIX([$1])
+          _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath"
+
+          _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag
+        else
+          if test ia64 = "$host_cpu"; then
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $libdir:/usr/lib:/lib'
+	    _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs"
+	    _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols"
+          else
+	    # Determine the default libpath from the value encoded in an
+	    # empty executable.
+	    _LT_SYS_MODULE_PATH_AIX([$1])
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath"
+	    # Warning - without using the other run time loading flags,
+	    # -berok will link without error, but may produce a broken library.
+	    _LT_TAGVAR(no_undefined_flag, $1)=' $wl-bernotok'
+	    _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-berok'
+	    if test yes = "$with_gnu_ld"; then
+	      # We only use this code for GNU lds that support --whole-archive.
+	      _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive'
+	    else
+	      # Exported symbols can be pulled into shared objects from archives
+	      _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience'
+	    fi
+	    _LT_TAGVAR(archive_cmds_need_lc, $1)=yes
+	    _LT_TAGVAR(archive_expsym_cmds, $1)='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d'
+	    # -brtl affects multiple linker settings, -berok does not and is overridden later
+	    compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([[, ]]\\)%-berok\\1%g"`'
+	    if test svr4 != "$with_aix_soname"; then
+	      # This is similar to how AIX traditionally builds its shared
+	      # libraries. Need -bnortl late, we may have -brtl in LDFLAGS.
+	      _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname'
+	    fi
+	    if test aix != "$with_aix_soname"; then
+	      _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp'
+	    else
+	      # used by -dlpreopen to get the symbols
+	      _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$MV  $output_objdir/$realname.d/$soname $output_objdir'
+	    fi
+	    _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$RM -r $output_objdir/$realname.d'
+          fi
+        fi
+        ;;
+
+      beos*)
+	if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+	  _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+	  # Joseph Beckenbach <jrb3@best.com> says some releases of gcc
+	  # support --undefined.  This deserves some investigation.  FIXME
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+	else
+	  _LT_TAGVAR(ld_shlibs, $1)=no
+	fi
+	;;
+
+      chorus*)
+        case $cc_basename in
+          *)
+	  # FIXME: insert proper C++ library support
+	  _LT_TAGVAR(ld_shlibs, $1)=no
+	  ;;
+        esac
+        ;;
+
+      cygwin* | mingw* | pw32* | cegcc*)
+	case $GXX,$cc_basename in
+	,cl* | no,cl*)
+	  # Native MSVC
+	  # hardcode_libdir_flag_spec is actually meaningless, as there is
+	  # no search path for DLLs.
+	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' '
+	  _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+	  _LT_TAGVAR(always_export_symbols, $1)=yes
+	  _LT_TAGVAR(file_list_spec, $1)='@'
+	  # Tell ltmain to make .lib files, not .a files.
+	  libext=lib
+	  # Tell ltmain to make .dll files, not .so files.
+	  shrext_cmds=.dll
+	  # FIXME: Setting linknames here is a bad hack.
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames='
+	  _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then
+              cp "$export_symbols" "$output_objdir/$soname.def";
+              echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp";
+            else
+              $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp;
+            fi~
+            $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
+            linknames='
+	  # The linker will not automatically build a static lib if we build a DLL.
+	  # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true'
+	  _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+	  # Don't use ranlib
+	  _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib'
+	  _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~
+            lt_tool_outputfile="@TOOL_OUTPUT@"~
+            case $lt_outputfile in
+              *.exe|*.EXE) ;;
+              *)
+                lt_outputfile=$lt_outputfile.exe
+                lt_tool_outputfile=$lt_tool_outputfile.exe
+                ;;
+            esac~
+            func_to_tool_file "$lt_outputfile"~
+            if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then
+              $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1;
+              $RM "$lt_outputfile.manifest";
+            fi'
+	  ;;
+	*)
+	  # g++
+	  # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless,
+	  # as there is no search path for DLLs.
+	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+	  _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-all-symbols'
+	  _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+	  _LT_TAGVAR(always_export_symbols, $1)=no
+	  _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+
+	  if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
+	    _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+	    # If the export-symbols file already is a .def file, use it as
+	    # is; otherwise, prepend EXPORTS...
+	    _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then
+              cp $export_symbols $output_objdir/$soname.def;
+            else
+              echo EXPORTS > $output_objdir/$soname.def;
+              cat $export_symbols >> $output_objdir/$soname.def;
+            fi~
+            $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+	  else
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	  fi
+	  ;;
+	esac
+	;;
+      darwin* | rhapsody*)
+        _LT_DARWIN_LINKER_FEATURES($1)
+	;;
+
+      os2*)
+	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+	_LT_TAGVAR(hardcode_minus_L, $1)=yes
+	_LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+	shrext_cmds=.dll
+	_LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
+	  $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
+	  $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
+	  $ECHO EXPORTS >> $output_objdir/$libname.def~
+	  emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~
+	  $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
+	  emximp -o $lib $output_objdir/$libname.def'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
+	  $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
+	  $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
+	  $ECHO EXPORTS >> $output_objdir/$libname.def~
+	  prefix_cmds="$SED"~
+	  if test EXPORTS = "`$SED 1q $export_symbols`"; then
+	    prefix_cmds="$prefix_cmds -e 1d";
+	  fi~
+	  prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~
+	  cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~
+	  $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
+	  emximp -o $lib $output_objdir/$libname.def'
+	_LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def'
+	_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+	;;
+
+      dgux*)
+        case $cc_basename in
+          ec++*)
+	    # FIXME: insert proper C++ library support
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	    ;;
+          ghcx*)
+	    # Green Hills C++ Compiler
+	    # FIXME: insert proper C++ library support
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	    ;;
+          *)
+	    # FIXME: insert proper C++ library support
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	    ;;
+        esac
+        ;;
+
+      freebsd2.*)
+        # C++ shared libraries reported to be fairly broken before
+	# switch to ELF
+        _LT_TAGVAR(ld_shlibs, $1)=no
+        ;;
+
+      freebsd-elf*)
+        _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+        ;;
+
+      freebsd* | dragonfly*)
+        # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF
+        # conventions
+        _LT_TAGVAR(ld_shlibs, $1)=yes
+        ;;
+
+      haiku*)
+        _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+        _LT_TAGVAR(link_all_deplibs, $1)=yes
+        ;;
+
+      hpux9*)
+        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir'
+        _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+        _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
+        _LT_TAGVAR(hardcode_direct, $1)=yes
+        _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH,
+				             # but as the default
+				             # location of the library.
+
+        case $cc_basename in
+          CC*)
+            # FIXME: insert proper C++ library support
+            _LT_TAGVAR(ld_shlibs, $1)=no
+            ;;
+          aCC*)
+            _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -b $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib'
+            # Commands to make compiler produce verbose output that lists
+            # what "hidden" libraries, object files and flags are used when
+            # linking a shared library.
+            #
+            # There doesn't appear to be a way to prevent this compiler from
+            # explicitly linking system object files so we need to strip them
+            # from the output so that they don't get included in the library
+            # dependencies.
+            output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+            ;;
+          *)
+            if test yes = "$GXX"; then
+              _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib'
+            else
+              # FIXME: insert proper C++ library support
+              _LT_TAGVAR(ld_shlibs, $1)=no
+            fi
+            ;;
+        esac
+        ;;
+
+      hpux10*|hpux11*)
+        if test no = "$with_gnu_ld"; then
+	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir'
+	  _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+          case $host_cpu in
+            hppa*64*|ia64*)
+              ;;
+            *)
+	      _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
+              ;;
+          esac
+        fi
+        case $host_cpu in
+          hppa*64*|ia64*)
+            _LT_TAGVAR(hardcode_direct, $1)=no
+            _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+            ;;
+          *)
+            _LT_TAGVAR(hardcode_direct, $1)=yes
+            _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+            _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH,
+					         # but as the default
+					         # location of the library.
+            ;;
+        esac
+
+        case $cc_basename in
+          CC*)
+	    # FIXME: insert proper C++ library support
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	    ;;
+          aCC*)
+	    case $host_cpu in
+	      hppa*64*)
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	        ;;
+	      ia64*)
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	        ;;
+	      *)
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	        ;;
+	    esac
+	    # Commands to make compiler produce verbose output that lists
+	    # what "hidden" libraries, object files and flags are used when
+	    # linking a shared library.
+	    #
+	    # There doesn't appear to be a way to prevent this compiler from
+	    # explicitly linking system object files so we need to strip them
+	    # from the output so that they don't get included in the library
+	    # dependencies.
+	    output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+	    ;;
+          *)
+	    if test yes = "$GXX"; then
+	      if test no = "$with_gnu_ld"; then
+	        case $host_cpu in
+	          hppa*64*)
+	            _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	            ;;
+	          ia64*)
+	            _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	            ;;
+	          *)
+	            _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	            ;;
+	        esac
+	      fi
+	    else
+	      # FIXME: insert proper C++ library support
+	      _LT_TAGVAR(ld_shlibs, $1)=no
+	    fi
+	    ;;
+        esac
+        ;;
+
+      interix[[3-9]]*)
+	_LT_TAGVAR(hardcode_direct, $1)=no
+	_LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir'
+	_LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
+	# Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
+	# Instead, shared libraries are loaded at an image base (0x10000000 by
+	# default) and relocated if they conflict, which is a slow very memory
+	# consuming and fragmenting process.  To avoid this, we pick a random,
+	# 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
+	# time.  Moving up from 0x10000000 also allows more sbrk(2) space.
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+	;;
+      irix5* | irix6*)
+        case $cc_basename in
+          CC*)
+	    # SGI C++
+	    _LT_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
+
+	    # Archives containing C++ object files must be created using
+	    # "CC -ar", where "CC" is the IRIX C++ compiler.  This is
+	    # necessary to make sure instantiated templates are included
+	    # in the archive.
+	    _LT_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs'
+	    ;;
+          *)
+	    if test yes = "$GXX"; then
+	      if test no = "$with_gnu_ld"; then
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
+	      else
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` -o $lib'
+	      fi
+	    fi
+	    _LT_TAGVAR(link_all_deplibs, $1)=yes
+	    ;;
+        esac
+        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+        _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+        _LT_TAGVAR(inherit_rpath, $1)=yes
+        ;;
+
+      linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
+        case $cc_basename in
+          KCC*)
+	    # Kuck and Associates, Inc. (KAI) C++ Compiler
+
+	    # KCC will only create a shared library if the output file
+	    # ends with ".so" (or ".sl" for HP-UX), so rename the library
+	    # to its proper name (with version) after linking.
+	    _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
+	    _LT_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib $wl-retain-symbols-file,$export_symbols; mv \$templib $lib'
+	    # Commands to make compiler produce verbose output that lists
+	    # what "hidden" libraries, object files and flags are used when
+	    # linking a shared library.
+	    #
+	    # There doesn't appear to be a way to prevent this compiler from
+	    # explicitly linking system object files so we need to strip them
+	    # from the output so that they don't get included in the library
+	    # dependencies.
+	    output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir'
+	    _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic'
+
+	    # Archives containing C++ object files must be created using
+	    # "CC -Bstatic", where "CC" is the KAI C++ compiler.
+	    _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs'
+	    ;;
+	  icpc* | ecpc* )
+	    # Intel C++
+	    with_gnu_ld=yes
+	    # version 8.0 and above of icpc choke on multiply defined symbols
+	    # if we add $predep_objects and $postdep_objects, however 7.1 and
+	    # earlier do not add the objects themselves.
+	    case `$CC -V 2>&1` in
+	      *"Version 7."*)
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib'
+		_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+		;;
+	      *)  # Version 8.0 or newer
+	        tmp_idyn=
+	        case $host_cpu in
+		  ia64*) tmp_idyn=' -i_dynamic';;
+		esac
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+		_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+		;;
+	    esac
+	    _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir'
+	    _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic'
+	    _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive'
+	    ;;
+          pgCC* | pgcpp*)
+            # Portland Group C++ compiler
+	    case `$CC -V` in
+	    *pgCC\ [[1-5]].* | *pgcpp\ [[1-5]].*)
+	      _LT_TAGVAR(prelink_cmds, $1)='tpldir=Template.dir~
+               rm -rf $tpldir~
+               $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~
+               compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"'
+	      _LT_TAGVAR(old_archive_cmds, $1)='tpldir=Template.dir~
+                rm -rf $tpldir~
+                $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~
+                $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~
+                $RANLIB $oldlib'
+	      _LT_TAGVAR(archive_cmds, $1)='tpldir=Template.dir~
+                rm -rf $tpldir~
+                $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~
+                $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib'
+	      _LT_TAGVAR(archive_expsym_cmds, $1)='tpldir=Template.dir~
+                rm -rf $tpldir~
+                $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~
+                $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+	      ;;
+	    *) # Version 6 and above use weak symbols
+	      _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib'
+	      _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+	      ;;
+	    esac
+
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl--rpath $wl$libdir'
+	    _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic'
+	    _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+            ;;
+	  cxx*)
+	    # Compaq C++
+	    _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib'
+	    _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname  -o $lib $wl-retain-symbols-file $wl$export_symbols'
+
+	    runpath_var=LD_RUN_PATH
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'
+	    _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+	    # Commands to make compiler produce verbose output that lists
+	    # what "hidden" libraries, object files and flags are used when
+	    # linking a shared library.
+	    #
+	    # There doesn't appear to be a way to prevent this compiler from
+	    # explicitly linking system object files so we need to strip them
+	    # from the output so that they don't get included in the library
+	    # dependencies.
+	    output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed'
+	    ;;
+	  xl* | mpixl* | bgxl*)
+	    # IBM XL 8.0 on PPC, with GNU ld
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+	    _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic'
+	    _LT_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+	    if test yes = "$supports_anon_versioning"; then
+	      _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~
+                cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+                echo "local: *; };" >> $output_objdir/$libname.ver~
+                $CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib'
+	    fi
+	    ;;
+	  *)
+	    case `$CC -V 2>&1 | sed 5q` in
+	    *Sun\ C*)
+	      # Sun C++ 5.9
+	      _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs'
+	      _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	      _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file $wl$export_symbols'
+	      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+	      _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+	      _LT_TAGVAR(compiler_needs_object, $1)=yes
+
+	      # Not sure whether something based on
+	      # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1
+	      # would be better.
+	      output_verbose_link_cmd='func_echo_all'
+
+	      # Archives containing C++ object files must be created using
+	      # "CC -xar", where "CC" is the Sun C++ compiler.  This is
+	      # necessary to make sure instantiated templates are included
+	      # in the archive.
+	      _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs'
+	      ;;
+	    esac
+	    ;;
+	esac
+	;;
+
+      lynxos*)
+        # FIXME: insert proper C++ library support
+	_LT_TAGVAR(ld_shlibs, $1)=no
+	;;
+
+      m88k*)
+        # FIXME: insert proper C++ library support
+        _LT_TAGVAR(ld_shlibs, $1)=no
+	;;
+
+      mvs*)
+        case $cc_basename in
+          cxx*)
+	    # FIXME: insert proper C++ library support
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	    ;;
+	  *)
+	    # FIXME: insert proper C++ library support
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	    ;;
+	esac
+	;;
+
+      netbsd*)
+        if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+	  _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable  -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags'
+	  wlarc=
+	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+	  _LT_TAGVAR(hardcode_direct, $1)=yes
+	  _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+	fi
+	# Workaround some broken pre-1.5 toolchains
+	output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"'
+	;;
+
+      *nto* | *qnx*)
+        _LT_TAGVAR(ld_shlibs, $1)=yes
+	;;
+
+      openbsd* | bitrig*)
+	if test -f /usr/libexec/ld.so; then
+	  _LT_TAGVAR(hardcode_direct, $1)=yes
+	  _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+	  _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib'
+	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir'
+	  if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`"; then
+	    _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file,$export_symbols -o $lib'
+	    _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
+	    _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive'
+	  fi
+	  output_verbose_link_cmd=func_echo_all
+	else
+	  _LT_TAGVAR(ld_shlibs, $1)=no
+	fi
+	;;
+
+      osf3* | osf4* | osf5*)
+        case $cc_basename in
+          KCC*)
+	    # Kuck and Associates, Inc. (KAI) C++ Compiler
+
+	    # KCC will only create a shared library if the output file
+	    # ends with ".so" (or ".sl" for HP-UX), so rename the library
+	    # to its proper name (with version) after linking.
+	    _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
+
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir'
+	    _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+	    # Archives containing C++ object files must be created using
+	    # the KAI C++ compiler.
+	    case $host in
+	      osf3*) _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;;
+	      *) _LT_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs' ;;
+	    esac
+	    ;;
+          RCC*)
+	    # Rational C++ 2.4.1
+	    # FIXME: insert proper C++ library support
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	    ;;
+          cxx*)
+	    case $host in
+	      osf3*)
+	        _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*'
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $soname `test -n "$verstring" && func_echo_all "$wl-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
+	        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+		;;
+	      *)
+	        _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
+	        _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~
+                  echo "-hidden">> $lib.exp~
+                  $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname $wl-input $wl$lib.exp  `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~
+                  $RM $lib.exp'
+	        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'
+		;;
+	    esac
+
+	    _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+	    # Commands to make compiler produce verbose output that lists
+	    # what "hidden" libraries, object files and flags are used when
+	    # linking a shared library.
+	    #
+	    # There doesn't appear to be a way to prevent this compiler from
+	    # explicitly linking system object files so we need to strip them
+	    # from the output so that they don't get included in the library
+	    # dependencies.
+	    output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+	    ;;
+	  *)
+	    if test yes,no = "$GXX,$with_gnu_ld"; then
+	      _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*'
+	      case $host in
+	        osf3*)
+	          _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
+		  ;;
+	        *)
+	          _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
+		  ;;
+	      esac
+
+	      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+	      _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+	      # Commands to make compiler produce verbose output that lists
+	      # what "hidden" libraries, object files and flags are used when
+	      # linking a shared library.
+	      output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+
+	    else
+	      # FIXME: insert proper C++ library support
+	      _LT_TAGVAR(ld_shlibs, $1)=no
+	    fi
+	    ;;
+        esac
+        ;;
+
+      psos*)
+        # FIXME: insert proper C++ library support
+        _LT_TAGVAR(ld_shlibs, $1)=no
+        ;;
+
+      sunos4*)
+        case $cc_basename in
+          CC*)
+	    # Sun C++ 4.x
+	    # FIXME: insert proper C++ library support
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	    ;;
+          lcc*)
+	    # Lucid
+	    # FIXME: insert proper C++ library support
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	    ;;
+          *)
+	    # FIXME: insert proper C++ library support
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	    ;;
+        esac
+        ;;
+
+      solaris*)
+        case $cc_basename in
+          CC* | sunCC*)
+	    # Sun C++ 4.2, 5.x and Centerline C++
+            _LT_TAGVAR(archive_cmds_need_lc,$1)=yes
+	    _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs'
+	    _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	    _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+              $CC -G$allow_undefined_flag $wl-M $wl$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+	    _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+	    case $host_os in
+	      solaris2.[[0-5]] | solaris2.[[0-5]].*) ;;
+	      *)
+		# The compiler driver will combine and reorder linker options,
+		# but understands '-z linker_flag'.
+	        # Supported since Solaris 2.6 (maybe 2.5.1?)
+		_LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract'
+	        ;;
+	    esac
+	    _LT_TAGVAR(link_all_deplibs, $1)=yes
+
+	    output_verbose_link_cmd='func_echo_all'
+
+	    # Archives containing C++ object files must be created using
+	    # "CC -xar", where "CC" is the Sun C++ compiler.  This is
+	    # necessary to make sure instantiated templates are included
+	    # in the archive.
+	    _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs'
+	    ;;
+          gcx*)
+	    # Green Hills C++ Compiler
+	    _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib'
+
+	    # The C++ compiler must be used to create the archive.
+	    _LT_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs'
+	    ;;
+          *)
+	    # GNU C++ compiler with Solaris linker
+	    if test yes,no = "$GXX,$with_gnu_ld"; then
+	      _LT_TAGVAR(no_undefined_flag, $1)=' $wl-z ${wl}defs'
+	      if $CC --version | $GREP -v '^2\.7' > /dev/null; then
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib'
+	        _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+                  $CC -shared $pic_flag -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+
+	        # Commands to make compiler produce verbose output that lists
+	        # what "hidden" libraries, object files and flags are used when
+	        # linking a shared library.
+	        output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+	      else
+	        # g++ 2.7 appears to require '-G' NOT '-shared' on this
+	        # platform.
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib'
+	        _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+                  $CC -G -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+
+	        # Commands to make compiler produce verbose output that lists
+	        # what "hidden" libraries, object files and flags are used when
+	        # linking a shared library.
+	        output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+	      fi
+
+	      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $wl$libdir'
+	      case $host_os in
+		solaris2.[[0-5]] | solaris2.[[0-5]].*) ;;
+		*)
+		  _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract'
+		  ;;
+	      esac
+	    fi
+	    ;;
+        esac
+        ;;
+
+    sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*)
+      _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text'
+      _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      runpath_var='LD_RUN_PATH'
+
+      case $cc_basename in
+        CC*)
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	*)
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+      esac
+      ;;
+
+      sysv5* | sco3.2v5* | sco5v6*)
+	# Note: We CANNOT use -z defs as we might desire, because we do not
+	# link with -lc, and that would cause any symbols used from libc to
+	# always be unresolved, which means just about no library would
+	# ever link correctly.  If we're not using GNU ld we use -z text
+	# though, which does catch some bad symbols but isn't as heavy-handed
+	# as -z defs.
+	_LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text'
+	_LT_TAGVAR(allow_undefined_flag, $1)='$wl-z,nodefs'
+	_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+	_LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R,$libdir'
+	_LT_TAGVAR(hardcode_libdir_separator, $1)=':'
+	_LT_TAGVAR(link_all_deplibs, $1)=yes
+	_LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Bexport'
+	runpath_var='LD_RUN_PATH'
+
+	case $cc_basename in
+          CC*)
+	    _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	    _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	    _LT_TAGVAR(old_archive_cmds, $1)='$CC -Tprelink_objects $oldobjs~
+              '"$_LT_TAGVAR(old_archive_cmds, $1)"
+	    _LT_TAGVAR(reload_cmds, $1)='$CC -Tprelink_objects $reload_objs~
+              '"$_LT_TAGVAR(reload_cmds, $1)"
+	    ;;
+	  *)
+	    _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	    _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	    ;;
+	esac
+      ;;
+
+      tandem*)
+        case $cc_basename in
+          NCC*)
+	    # NonStop-UX NCC 3.20
+	    # FIXME: insert proper C++ library support
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	    ;;
+          *)
+	    # FIXME: insert proper C++ library support
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	    ;;
+        esac
+        ;;
+
+      vxworks*)
+        # FIXME: insert proper C++ library support
+        _LT_TAGVAR(ld_shlibs, $1)=no
+        ;;
+
+      *)
+        # FIXME: insert proper C++ library support
+        _LT_TAGVAR(ld_shlibs, $1)=no
+        ;;
+    esac
+
+    AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)])
+    test no = "$_LT_TAGVAR(ld_shlibs, $1)" && can_build_shared=no
+
+    _LT_TAGVAR(GCC, $1)=$GXX
+    _LT_TAGVAR(LD, $1)=$LD
+
+    ## CAVEAT EMPTOR:
+    ## There is no encapsulation within the following macros, do not change
+    ## the running order or otherwise move them around unless you know exactly
+    ## what you are doing...
+    _LT_SYS_HIDDEN_LIBDEPS($1)
+    _LT_COMPILER_PIC($1)
+    _LT_COMPILER_C_O($1)
+    _LT_COMPILER_FILE_LOCKS($1)
+    _LT_LINKER_SHLIBS($1)
+    _LT_SYS_DYNAMIC_LINKER($1)
+    _LT_LINKER_HARDCODE_LIBPATH($1)
+
+    _LT_CONFIG($1)
+  fi # test -n "$compiler"
+
+  CC=$lt_save_CC
+  CFLAGS=$lt_save_CFLAGS
+  LDCXX=$LD
+  LD=$lt_save_LD
+  GCC=$lt_save_GCC
+  with_gnu_ld=$lt_save_with_gnu_ld
+  lt_cv_path_LDCXX=$lt_cv_path_LD
+  lt_cv_path_LD=$lt_save_path_LD
+  lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld
+  lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld
+fi # test yes != "$_lt_caught_CXX_error"
+
+AC_LANG_POP
+])# _LT_LANG_CXX_CONFIG
+
+
+# _LT_FUNC_STRIPNAME_CNF
+# ----------------------
+# func_stripname_cnf prefix suffix name
+# strip PREFIX and SUFFIX off of NAME.
+# PREFIX and SUFFIX must not contain globbing or regex special
+# characters, hashes, percent signs, but SUFFIX may contain a leading
+# dot (in which case that matches only a dot).
+#
+# This function is identical to the (non-XSI) version of func_stripname,
+# except this one can be used by m4 code that may be executed by configure,
+# rather than the libtool script.
+m4_defun([_LT_FUNC_STRIPNAME_CNF],[dnl
+AC_REQUIRE([_LT_DECL_SED])
+AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])
+func_stripname_cnf ()
+{
+  case @S|@2 in
+  .*) func_stripname_result=`$ECHO "@S|@3" | $SED "s%^@S|@1%%; s%\\\\@S|@2\$%%"`;;
+  *)  func_stripname_result=`$ECHO "@S|@3" | $SED "s%^@S|@1%%; s%@S|@2\$%%"`;;
+  esac
+} # func_stripname_cnf
+])# _LT_FUNC_STRIPNAME_CNF
+
+
+# _LT_SYS_HIDDEN_LIBDEPS([TAGNAME])
+# ---------------------------------
+# Figure out "hidden" library dependencies from verbose
+# compiler output when linking a shared library.
+# Parse the compiler output and extract the necessary
+# objects, libraries and library flags.
+m4_defun([_LT_SYS_HIDDEN_LIBDEPS],
+[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+AC_REQUIRE([_LT_FUNC_STRIPNAME_CNF])dnl
+# Dependencies to place before and after the object being linked:
+_LT_TAGVAR(predep_objects, $1)=
+_LT_TAGVAR(postdep_objects, $1)=
+_LT_TAGVAR(predeps, $1)=
+_LT_TAGVAR(postdeps, $1)=
+_LT_TAGVAR(compiler_lib_search_path, $1)=
+
+dnl we can't use the lt_simple_compile_test_code here,
+dnl because it contains code intended for an executable,
+dnl not a library.  It's possible we should let each
+dnl tag define a new lt_????_link_test_code variable,
+dnl but it's only used here...
+m4_if([$1], [], [cat > conftest.$ac_ext <<_LT_EOF
+int a;
+void foo (void) { a = 0; }
+_LT_EOF
+], [$1], [CXX], [cat > conftest.$ac_ext <<_LT_EOF
+class Foo
+{
+public:
+  Foo (void) { a = 0; }
+private:
+  int a;
+};
+_LT_EOF
+], [$1], [F77], [cat > conftest.$ac_ext <<_LT_EOF
+      subroutine foo
+      implicit none
+      integer*4 a
+      a=0
+      return
+      end
+_LT_EOF
+], [$1], [FC], [cat > conftest.$ac_ext <<_LT_EOF
+      subroutine foo
+      implicit none
+      integer a
+      a=0
+      return
+      end
+_LT_EOF
+], [$1], [GCJ], [cat > conftest.$ac_ext <<_LT_EOF
+public class foo {
+  private int a;
+  public void bar (void) {
+    a = 0;
+  }
+};
+_LT_EOF
+], [$1], [GO], [cat > conftest.$ac_ext <<_LT_EOF
+package foo
+func foo() {
+}
+_LT_EOF
+])
+
+_lt_libdeps_save_CFLAGS=$CFLAGS
+case "$CC $CFLAGS " in #(
+*\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;;
+*\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;;
+*\ -fuse-linker-plugin*\ *) CFLAGS="$CFLAGS -fno-use-linker-plugin" ;;
+esac
+
+dnl Parse the compiler output and extract the necessary
+dnl objects, libraries and library flags.
+if AC_TRY_EVAL(ac_compile); then
+  # Parse the compiler output and extract the necessary
+  # objects, libraries and library flags.
+
+  # Sentinel used to keep track of whether or not we are before
+  # the conftest object file.
+  pre_test_object_deps_done=no
+
+  for p in `eval "$output_verbose_link_cmd"`; do
+    case $prev$p in
+
+    -L* | -R* | -l*)
+       # Some compilers place space between "-{L,R}" and the path.
+       # Remove the space.
+       if test x-L = "$p" ||
+          test x-R = "$p"; then
+	 prev=$p
+	 continue
+       fi
+
+       # Expand the sysroot to ease extracting the directories later.
+       if test -z "$prev"; then
+         case $p in
+         -L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;;
+         -R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;;
+         -l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;;
+         esac
+       fi
+       case $p in
+       =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;;
+       esac
+       if test no = "$pre_test_object_deps_done"; then
+	 case $prev in
+	 -L | -R)
+	   # Internal compiler library paths should come after those
+	   # provided the user.  The postdeps already come after the
+	   # user supplied libs so there is no need to process them.
+	   if test -z "$_LT_TAGVAR(compiler_lib_search_path, $1)"; then
+	     _LT_TAGVAR(compiler_lib_search_path, $1)=$prev$p
+	   else
+	     _LT_TAGVAR(compiler_lib_search_path, $1)="${_LT_TAGVAR(compiler_lib_search_path, $1)} $prev$p"
+	   fi
+	   ;;
+	 # The "-l" case would never come before the object being
+	 # linked, so don't bother handling this case.
+	 esac
+       else
+	 if test -z "$_LT_TAGVAR(postdeps, $1)"; then
+	   _LT_TAGVAR(postdeps, $1)=$prev$p
+	 else
+	   _LT_TAGVAR(postdeps, $1)="${_LT_TAGVAR(postdeps, $1)} $prev$p"
+	 fi
+       fi
+       prev=
+       ;;
+
+    *.lto.$objext) ;; # Ignore GCC LTO objects
+    *.$objext)
+       # This assumes that the test object file only shows up
+       # once in the compiler output.
+       if test "$p" = "conftest.$objext"; then
+	 pre_test_object_deps_done=yes
+	 continue
+       fi
+
+       if test no = "$pre_test_object_deps_done"; then
+	 if test -z "$_LT_TAGVAR(predep_objects, $1)"; then
+	   _LT_TAGVAR(predep_objects, $1)=$p
+	 else
+	   _LT_TAGVAR(predep_objects, $1)="$_LT_TAGVAR(predep_objects, $1) $p"
+	 fi
+       else
+	 if test -z "$_LT_TAGVAR(postdep_objects, $1)"; then
+	   _LT_TAGVAR(postdep_objects, $1)=$p
+	 else
+	   _LT_TAGVAR(postdep_objects, $1)="$_LT_TAGVAR(postdep_objects, $1) $p"
+	 fi
+       fi
+       ;;
+
+    *) ;; # Ignore the rest.
+
+    esac
+  done
+
+  # Clean up.
+  rm -f a.out a.exe
+else
+  echo "libtool.m4: error: problem compiling $1 test program"
+fi
+
+$RM -f confest.$objext
+CFLAGS=$_lt_libdeps_save_CFLAGS
+
+# PORTME: override above test on systems where it is broken
+m4_if([$1], [CXX],
+[case $host_os in
+interix[[3-9]]*)
+  # Interix 3.5 installs completely hosed .la files for C++, so rather than
+  # hack all around it, let's just trust "g++" to DTRT.
+  _LT_TAGVAR(predep_objects,$1)=
+  _LT_TAGVAR(postdep_objects,$1)=
+  _LT_TAGVAR(postdeps,$1)=
+  ;;
+esac
+])
+
+case " $_LT_TAGVAR(postdeps, $1) " in
+*" -lc "*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;;
+esac
+ _LT_TAGVAR(compiler_lib_search_dirs, $1)=
+if test -n "${_LT_TAGVAR(compiler_lib_search_path, $1)}"; then
+ _LT_TAGVAR(compiler_lib_search_dirs, $1)=`echo " ${_LT_TAGVAR(compiler_lib_search_path, $1)}" | $SED -e 's! -L! !g' -e 's!^ !!'`
+fi
+_LT_TAGDECL([], [compiler_lib_search_dirs], [1],
+    [The directories searched by this compiler when creating a shared library])
+_LT_TAGDECL([], [predep_objects], [1],
+    [Dependencies to place before and after the objects being linked to
+    create a shared library])
+_LT_TAGDECL([], [postdep_objects], [1])
+_LT_TAGDECL([], [predeps], [1])
+_LT_TAGDECL([], [postdeps], [1])
+_LT_TAGDECL([], [compiler_lib_search_path], [1],
+    [The library search path used internally by the compiler when linking
+    a shared library])
+])# _LT_SYS_HIDDEN_LIBDEPS
+
+
+# _LT_LANG_F77_CONFIG([TAG])
+# --------------------------
+# Ensure that the configuration variables for a Fortran 77 compiler are
+# suitably defined.  These variables are subsequently used by _LT_CONFIG
+# to write the compiler configuration to 'libtool'.
+m4_defun([_LT_LANG_F77_CONFIG],
+[AC_LANG_PUSH(Fortran 77)
+if test -z "$F77" || test no = "$F77"; then
+  _lt_disable_F77=yes
+fi
+
+_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+_LT_TAGVAR(allow_undefined_flag, $1)=
+_LT_TAGVAR(always_export_symbols, $1)=no
+_LT_TAGVAR(archive_expsym_cmds, $1)=
+_LT_TAGVAR(export_dynamic_flag_spec, $1)=
+_LT_TAGVAR(hardcode_direct, $1)=no
+_LT_TAGVAR(hardcode_direct_absolute, $1)=no
+_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+_LT_TAGVAR(hardcode_libdir_separator, $1)=
+_LT_TAGVAR(hardcode_minus_L, $1)=no
+_LT_TAGVAR(hardcode_automatic, $1)=no
+_LT_TAGVAR(inherit_rpath, $1)=no
+_LT_TAGVAR(module_cmds, $1)=
+_LT_TAGVAR(module_expsym_cmds, $1)=
+_LT_TAGVAR(link_all_deplibs, $1)=unknown
+_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+_LT_TAGVAR(reload_flag, $1)=$reload_flag
+_LT_TAGVAR(reload_cmds, $1)=$reload_cmds
+_LT_TAGVAR(no_undefined_flag, $1)=
+_LT_TAGVAR(whole_archive_flag_spec, $1)=
+_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no
+
+# Source file extension for f77 test sources.
+ac_ext=f
+
+# Object file extension for compiled f77 test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# No sense in running all these tests if we already determined that
+# the F77 compiler isn't working.  Some variables (like enable_shared)
+# are currently assumed to apply to all compilers on this platform,
+# and will be corrupted by setting them based on a non-working compiler.
+if test yes != "$_lt_disable_F77"; then
+  # Code to be used in simple compile tests
+  lt_simple_compile_test_code="\
+      subroutine t
+      return
+      end
+"
+
+  # Code to be used in simple link tests
+  lt_simple_link_test_code="\
+      program t
+      end
+"
+
+  # ltmain only uses $CC for tagged configurations so make sure $CC is set.
+  _LT_TAG_COMPILER
+
+  # save warnings/boilerplate of simple test code
+  _LT_COMPILER_BOILERPLATE
+  _LT_LINKER_BOILERPLATE
+
+  # Allow CC to be a program name with arguments.
+  lt_save_CC=$CC
+  lt_save_GCC=$GCC
+  lt_save_CFLAGS=$CFLAGS
+  CC=${F77-"f77"}
+  CFLAGS=$FFLAGS
+  compiler=$CC
+  _LT_TAGVAR(compiler, $1)=$CC
+  _LT_CC_BASENAME([$compiler])
+  GCC=$G77
+  if test -n "$compiler"; then
+    AC_MSG_CHECKING([if libtool supports shared libraries])
+    AC_MSG_RESULT([$can_build_shared])
+
+    AC_MSG_CHECKING([whether to build shared libraries])
+    test no = "$can_build_shared" && enable_shared=no
+
+    # On AIX, shared libraries and static libraries use the same namespace, and
+    # are all built from PIC.
+    case $host_os in
+      aix3*)
+        test yes = "$enable_shared" && enable_static=no
+        if test -n "$RANLIB"; then
+          archive_cmds="$archive_cmds~\$RANLIB \$lib"
+          postinstall_cmds='$RANLIB $lib'
+        fi
+        ;;
+      aix[[4-9]]*)
+	if test ia64 != "$host_cpu"; then
+	  case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in
+	  yes,aix,yes) ;;		# shared object as lib.so file only
+	  yes,svr4,*) ;;		# shared object as lib.so archive member only
+	  yes,*) enable_static=no ;;	# shared object in lib.a archive as well
+	  esac
+	fi
+        ;;
+    esac
+    AC_MSG_RESULT([$enable_shared])
+
+    AC_MSG_CHECKING([whether to build static libraries])
+    # Make sure either enable_shared or enable_static is yes.
+    test yes = "$enable_shared" || enable_static=yes
+    AC_MSG_RESULT([$enable_static])
+
+    _LT_TAGVAR(GCC, $1)=$G77
+    _LT_TAGVAR(LD, $1)=$LD
+
+    ## CAVEAT EMPTOR:
+    ## There is no encapsulation within the following macros, do not change
+    ## the running order or otherwise move them around unless you know exactly
+    ## what you are doing...
+    _LT_COMPILER_PIC($1)
+    _LT_COMPILER_C_O($1)
+    _LT_COMPILER_FILE_LOCKS($1)
+    _LT_LINKER_SHLIBS($1)
+    _LT_SYS_DYNAMIC_LINKER($1)
+    _LT_LINKER_HARDCODE_LIBPATH($1)
+
+    _LT_CONFIG($1)
+  fi # test -n "$compiler"
+
+  GCC=$lt_save_GCC
+  CC=$lt_save_CC
+  CFLAGS=$lt_save_CFLAGS
+fi # test yes != "$_lt_disable_F77"
+
+AC_LANG_POP
+])# _LT_LANG_F77_CONFIG
+
+
+# _LT_LANG_FC_CONFIG([TAG])
+# -------------------------
+# Ensure that the configuration variables for a Fortran compiler are
+# suitably defined.  These variables are subsequently used by _LT_CONFIG
+# to write the compiler configuration to 'libtool'.
+m4_defun([_LT_LANG_FC_CONFIG],
+[AC_LANG_PUSH(Fortran)
+
+if test -z "$FC" || test no = "$FC"; then
+  _lt_disable_FC=yes
+fi
+
+_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+_LT_TAGVAR(allow_undefined_flag, $1)=
+_LT_TAGVAR(always_export_symbols, $1)=no
+_LT_TAGVAR(archive_expsym_cmds, $1)=
+_LT_TAGVAR(export_dynamic_flag_spec, $1)=
+_LT_TAGVAR(hardcode_direct, $1)=no
+_LT_TAGVAR(hardcode_direct_absolute, $1)=no
+_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+_LT_TAGVAR(hardcode_libdir_separator, $1)=
+_LT_TAGVAR(hardcode_minus_L, $1)=no
+_LT_TAGVAR(hardcode_automatic, $1)=no
+_LT_TAGVAR(inherit_rpath, $1)=no
+_LT_TAGVAR(module_cmds, $1)=
+_LT_TAGVAR(module_expsym_cmds, $1)=
+_LT_TAGVAR(link_all_deplibs, $1)=unknown
+_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+_LT_TAGVAR(reload_flag, $1)=$reload_flag
+_LT_TAGVAR(reload_cmds, $1)=$reload_cmds
+_LT_TAGVAR(no_undefined_flag, $1)=
+_LT_TAGVAR(whole_archive_flag_spec, $1)=
+_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no
+
+# Source file extension for fc test sources.
+ac_ext=${ac_fc_srcext-f}
+
+# Object file extension for compiled fc test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# No sense in running all these tests if we already determined that
+# the FC compiler isn't working.  Some variables (like enable_shared)
+# are currently assumed to apply to all compilers on this platform,
+# and will be corrupted by setting them based on a non-working compiler.
+if test yes != "$_lt_disable_FC"; then
+  # Code to be used in simple compile tests
+  lt_simple_compile_test_code="\
+      subroutine t
+      return
+      end
+"
+
+  # Code to be used in simple link tests
+  lt_simple_link_test_code="\
+      program t
+      end
+"
+
+  # ltmain only uses $CC for tagged configurations so make sure $CC is set.
+  _LT_TAG_COMPILER
+
+  # save warnings/boilerplate of simple test code
+  _LT_COMPILER_BOILERPLATE
+  _LT_LINKER_BOILERPLATE
+
+  # Allow CC to be a program name with arguments.
+  lt_save_CC=$CC
+  lt_save_GCC=$GCC
+  lt_save_CFLAGS=$CFLAGS
+  CC=${FC-"f95"}
+  CFLAGS=$FCFLAGS
+  compiler=$CC
+  GCC=$ac_cv_fc_compiler_gnu
+
+  _LT_TAGVAR(compiler, $1)=$CC
+  _LT_CC_BASENAME([$compiler])
+
+  if test -n "$compiler"; then
+    AC_MSG_CHECKING([if libtool supports shared libraries])
+    AC_MSG_RESULT([$can_build_shared])
+
+    AC_MSG_CHECKING([whether to build shared libraries])
+    test no = "$can_build_shared" && enable_shared=no
+
+    # On AIX, shared libraries and static libraries use the same namespace, and
+    # are all built from PIC.
+    case $host_os in
+      aix3*)
+        test yes = "$enable_shared" && enable_static=no
+        if test -n "$RANLIB"; then
+          archive_cmds="$archive_cmds~\$RANLIB \$lib"
+          postinstall_cmds='$RANLIB $lib'
+        fi
+        ;;
+      aix[[4-9]]*)
+	if test ia64 != "$host_cpu"; then
+	  case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in
+	  yes,aix,yes) ;;		# shared object as lib.so file only
+	  yes,svr4,*) ;;		# shared object as lib.so archive member only
+	  yes,*) enable_static=no ;;	# shared object in lib.a archive as well
+	  esac
+	fi
+        ;;
+    esac
+    AC_MSG_RESULT([$enable_shared])
+
+    AC_MSG_CHECKING([whether to build static libraries])
+    # Make sure either enable_shared or enable_static is yes.
+    test yes = "$enable_shared" || enable_static=yes
+    AC_MSG_RESULT([$enable_static])
+
+    _LT_TAGVAR(GCC, $1)=$ac_cv_fc_compiler_gnu
+    _LT_TAGVAR(LD, $1)=$LD
+
+    ## CAVEAT EMPTOR:
+    ## There is no encapsulation within the following macros, do not change
+    ## the running order or otherwise move them around unless you know exactly
+    ## what you are doing...
+    _LT_SYS_HIDDEN_LIBDEPS($1)
+    _LT_COMPILER_PIC($1)
+    _LT_COMPILER_C_O($1)
+    _LT_COMPILER_FILE_LOCKS($1)
+    _LT_LINKER_SHLIBS($1)
+    _LT_SYS_DYNAMIC_LINKER($1)
+    _LT_LINKER_HARDCODE_LIBPATH($1)
+
+    _LT_CONFIG($1)
+  fi # test -n "$compiler"
+
+  GCC=$lt_save_GCC
+  CC=$lt_save_CC
+  CFLAGS=$lt_save_CFLAGS
+fi # test yes != "$_lt_disable_FC"
+
+AC_LANG_POP
+])# _LT_LANG_FC_CONFIG
+
+
+# _LT_LANG_GCJ_CONFIG([TAG])
+# --------------------------
+# Ensure that the configuration variables for the GNU Java Compiler compiler
+# are suitably defined.  These variables are subsequently used by _LT_CONFIG
+# to write the compiler configuration to 'libtool'.
+m4_defun([_LT_LANG_GCJ_CONFIG],
+[AC_REQUIRE([LT_PROG_GCJ])dnl
+AC_LANG_SAVE
+
+# Source file extension for Java test sources.
+ac_ext=java
+
+# Object file extension for compiled Java test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="class foo {}"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code='public class conftest { public static void main(String[[]] argv) {}; }'
+
+# ltmain only uses $CC for tagged configurations so make sure $CC is set.
+_LT_TAG_COMPILER
+
+# save warnings/boilerplate of simple test code
+_LT_COMPILER_BOILERPLATE
+_LT_LINKER_BOILERPLATE
+
+# Allow CC to be a program name with arguments.
+lt_save_CC=$CC
+lt_save_CFLAGS=$CFLAGS
+lt_save_GCC=$GCC
+GCC=yes
+CC=${GCJ-"gcj"}
+CFLAGS=$GCJFLAGS
+compiler=$CC
+_LT_TAGVAR(compiler, $1)=$CC
+_LT_TAGVAR(LD, $1)=$LD
+_LT_CC_BASENAME([$compiler])
+
+# GCJ did not exist at the time GCC didn't implicitly link libc in.
+_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+
+_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+_LT_TAGVAR(reload_flag, $1)=$reload_flag
+_LT_TAGVAR(reload_cmds, $1)=$reload_cmds
+
+## CAVEAT EMPTOR:
+## There is no encapsulation within the following macros, do not change
+## the running order or otherwise move them around unless you know exactly
+## what you are doing...
+if test -n "$compiler"; then
+  _LT_COMPILER_NO_RTTI($1)
+  _LT_COMPILER_PIC($1)
+  _LT_COMPILER_C_O($1)
+  _LT_COMPILER_FILE_LOCKS($1)
+  _LT_LINKER_SHLIBS($1)
+  _LT_LINKER_HARDCODE_LIBPATH($1)
+
+  _LT_CONFIG($1)
+fi
+
+AC_LANG_RESTORE
+
+GCC=$lt_save_GCC
+CC=$lt_save_CC
+CFLAGS=$lt_save_CFLAGS
+])# _LT_LANG_GCJ_CONFIG
+
+
+# _LT_LANG_GO_CONFIG([TAG])
+# --------------------------
+# Ensure that the configuration variables for the GNU Go compiler
+# are suitably defined.  These variables are subsequently used by _LT_CONFIG
+# to write the compiler configuration to 'libtool'.
+m4_defun([_LT_LANG_GO_CONFIG],
+[AC_REQUIRE([LT_PROG_GO])dnl
+AC_LANG_SAVE
+
+# Source file extension for Go test sources.
+ac_ext=go
+
+# Object file extension for compiled Go test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="package main; func main() { }"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code='package main; func main() { }'
+
+# ltmain only uses $CC for tagged configurations so make sure $CC is set.
+_LT_TAG_COMPILER
+
+# save warnings/boilerplate of simple test code
+_LT_COMPILER_BOILERPLATE
+_LT_LINKER_BOILERPLATE
+
+# Allow CC to be a program name with arguments.
+lt_save_CC=$CC
+lt_save_CFLAGS=$CFLAGS
+lt_save_GCC=$GCC
+GCC=yes
+CC=${GOC-"gccgo"}
+CFLAGS=$GOFLAGS
+compiler=$CC
+_LT_TAGVAR(compiler, $1)=$CC
+_LT_TAGVAR(LD, $1)=$LD
+_LT_CC_BASENAME([$compiler])
+
+# Go did not exist at the time GCC didn't implicitly link libc in.
+_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+
+_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+_LT_TAGVAR(reload_flag, $1)=$reload_flag
+_LT_TAGVAR(reload_cmds, $1)=$reload_cmds
+
+## CAVEAT EMPTOR:
+## There is no encapsulation within the following macros, do not change
+## the running order or otherwise move them around unless you know exactly
+## what you are doing...
+if test -n "$compiler"; then
+  _LT_COMPILER_NO_RTTI($1)
+  _LT_COMPILER_PIC($1)
+  _LT_COMPILER_C_O($1)
+  _LT_COMPILER_FILE_LOCKS($1)
+  _LT_LINKER_SHLIBS($1)
+  _LT_LINKER_HARDCODE_LIBPATH($1)
+
+  _LT_CONFIG($1)
+fi
+
+AC_LANG_RESTORE
+
+GCC=$lt_save_GCC
+CC=$lt_save_CC
+CFLAGS=$lt_save_CFLAGS
+])# _LT_LANG_GO_CONFIG
+
+
+# _LT_LANG_RC_CONFIG([TAG])
+# -------------------------
+# Ensure that the configuration variables for the Windows resource compiler
+# are suitably defined.  These variables are subsequently used by _LT_CONFIG
+# to write the compiler configuration to 'libtool'.
+m4_defun([_LT_LANG_RC_CONFIG],
+[AC_REQUIRE([LT_PROG_RC])dnl
+AC_LANG_SAVE
+
+# Source file extension for RC test sources.
+ac_ext=rc
+
+# Object file extension for compiled RC test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }'
+
+# Code to be used in simple link tests
+lt_simple_link_test_code=$lt_simple_compile_test_code
+
+# ltmain only uses $CC for tagged configurations so make sure $CC is set.
+_LT_TAG_COMPILER
+
+# save warnings/boilerplate of simple test code
+_LT_COMPILER_BOILERPLATE
+_LT_LINKER_BOILERPLATE
+
+# Allow CC to be a program name with arguments.
+lt_save_CC=$CC
+lt_save_CFLAGS=$CFLAGS
+lt_save_GCC=$GCC
+GCC=
+CC=${RC-"windres"}
+CFLAGS=
+compiler=$CC
+_LT_TAGVAR(compiler, $1)=$CC
+_LT_CC_BASENAME([$compiler])
+_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes
+
+if test -n "$compiler"; then
+  :
+  _LT_CONFIG($1)
+fi
+
+GCC=$lt_save_GCC
+AC_LANG_RESTORE
+CC=$lt_save_CC
+CFLAGS=$lt_save_CFLAGS
+])# _LT_LANG_RC_CONFIG
+
+
+# LT_PROG_GCJ
+# -----------
+AC_DEFUN([LT_PROG_GCJ],
+[m4_ifdef([AC_PROG_GCJ], [AC_PROG_GCJ],
+  [m4_ifdef([A][M_PROG_GCJ], [A][M_PROG_GCJ],
+    [AC_CHECK_TOOL(GCJ, gcj,)
+      test set = "${GCJFLAGS+set}" || GCJFLAGS="-g -O2"
+      AC_SUBST(GCJFLAGS)])])[]dnl
+])
+
+# Old name:
+AU_ALIAS([LT_AC_PROG_GCJ], [LT_PROG_GCJ])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([LT_AC_PROG_GCJ], [])
+
+
+# LT_PROG_GO
+# ----------
+AC_DEFUN([LT_PROG_GO],
+[AC_CHECK_TOOL(GOC, gccgo,)
+])
+
+
+# LT_PROG_RC
+# ----------
+AC_DEFUN([LT_PROG_RC],
+[AC_CHECK_TOOL(RC, windres,)
+])
+
+# Old name:
+AU_ALIAS([LT_AC_PROG_RC], [LT_PROG_RC])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([LT_AC_PROG_RC], [])
+
+
+# _LT_DECL_EGREP
+# --------------
+# If we don't have a new enough Autoconf to choose the best grep
+# available, choose the one first in the user's PATH.
+m4_defun([_LT_DECL_EGREP],
+[AC_REQUIRE([AC_PROG_EGREP])dnl
+AC_REQUIRE([AC_PROG_FGREP])dnl
+test -z "$GREP" && GREP=grep
+_LT_DECL([], [GREP], [1], [A grep program that handles long lines])
+_LT_DECL([], [EGREP], [1], [An ERE matcher])
+_LT_DECL([], [FGREP], [1], [A literal string matcher])
+dnl Non-bleeding-edge autoconf doesn't subst GREP, so do it here too
+AC_SUBST([GREP])
+])
+
+
+# _LT_DECL_OBJDUMP
+# --------------
+# If we don't have a new enough Autoconf to choose the best objdump
+# available, choose the one first in the user's PATH.
+m4_defun([_LT_DECL_OBJDUMP],
+[AC_CHECK_TOOL(OBJDUMP, objdump, false)
+test -z "$OBJDUMP" && OBJDUMP=objdump
+_LT_DECL([], [OBJDUMP], [1], [An object symbol dumper])
+AC_SUBST([OBJDUMP])
+])
+
+# _LT_DECL_DLLTOOL
+# ----------------
+# Ensure DLLTOOL variable is set.
+m4_defun([_LT_DECL_DLLTOOL],
+[AC_CHECK_TOOL(DLLTOOL, dlltool, false)
+test -z "$DLLTOOL" && DLLTOOL=dlltool
+_LT_DECL([], [DLLTOOL], [1], [DLL creation program])
+AC_SUBST([DLLTOOL])
+])
+
+# _LT_DECL_SED
+# ------------
+# Check for a fully-functional sed program, that truncates
+# as few characters as possible.  Prefer GNU sed if found.
+m4_defun([_LT_DECL_SED],
+[AC_PROG_SED
+test -z "$SED" && SED=sed
+Xsed="$SED -e 1s/^X//"
+_LT_DECL([], [SED], [1], [A sed program that does not truncate output])
+_LT_DECL([], [Xsed], ["\$SED -e 1s/^X//"],
+    [Sed that helps us avoid accidentally triggering echo(1) options like -n])
+])# _LT_DECL_SED
+
+m4_ifndef([AC_PROG_SED], [
+############################################################
+# NOTE: This macro has been submitted for inclusion into   #
+#  GNU Autoconf as AC_PROG_SED.  When it is available in   #
+#  a released version of Autoconf we should remove this    #
+#  macro and use it instead.                               #
+############################################################
+
+m4_defun([AC_PROG_SED],
+[AC_MSG_CHECKING([for a sed that does not truncate output])
+AC_CACHE_VAL(lt_cv_path_SED,
+[# Loop through the user's path and test for sed and gsed.
+# Then use that list of sed's as ones to test for truncation.
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for lt_ac_prog in sed gsed; do
+    for ac_exec_ext in '' $ac_executable_extensions; do
+      if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then
+        lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext"
+      fi
+    done
+  done
+done
+IFS=$as_save_IFS
+lt_ac_max=0
+lt_ac_count=0
+# Add /usr/xpg4/bin/sed as it is typically found on Solaris
+# along with /bin/sed that truncates output.
+for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do
+  test ! -f "$lt_ac_sed" && continue
+  cat /dev/null > conftest.in
+  lt_ac_count=0
+  echo $ECHO_N "0123456789$ECHO_C" >conftest.in
+  # Check for GNU sed and select it if it is found.
+  if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then
+    lt_cv_path_SED=$lt_ac_sed
+    break
+  fi
+  while true; do
+    cat conftest.in conftest.in >conftest.tmp
+    mv conftest.tmp conftest.in
+    cp conftest.in conftest.nl
+    echo >>conftest.nl
+    $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break
+    cmp -s conftest.out conftest.nl || break
+    # 10000 chars as input seems more than enough
+    test 10 -lt "$lt_ac_count" && break
+    lt_ac_count=`expr $lt_ac_count + 1`
+    if test "$lt_ac_count" -gt "$lt_ac_max"; then
+      lt_ac_max=$lt_ac_count
+      lt_cv_path_SED=$lt_ac_sed
+    fi
+  done
+done
+])
+SED=$lt_cv_path_SED
+AC_SUBST([SED])
+AC_MSG_RESULT([$SED])
+])#AC_PROG_SED
+])#m4_ifndef
+
+# Old name:
+AU_ALIAS([LT_AC_PROG_SED], [AC_PROG_SED])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([LT_AC_PROG_SED], [])
+
+
+# _LT_CHECK_SHELL_FEATURES
+# ------------------------
+# Find out whether the shell is Bourne or XSI compatible,
+# or has some other useful features.
+m4_defun([_LT_CHECK_SHELL_FEATURES],
+[if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+  lt_unset=unset
+else
+  lt_unset=false
+fi
+_LT_DECL([], [lt_unset], [0], [whether the shell understands "unset"])dnl
+
+# test EBCDIC or ASCII
+case `echo X|tr X '\101'` in
+ A) # ASCII based system
+    # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr
+  lt_SP2NL='tr \040 \012'
+  lt_NL2SP='tr \015\012 \040\040'
+  ;;
+ *) # EBCDIC based system
+  lt_SP2NL='tr \100 \n'
+  lt_NL2SP='tr \r\n \100\100'
+  ;;
+esac
+_LT_DECL([SP2NL], [lt_SP2NL], [1], [turn spaces into newlines])dnl
+_LT_DECL([NL2SP], [lt_NL2SP], [1], [turn newlines into spaces])dnl
+])# _LT_CHECK_SHELL_FEATURES
+
+
+# _LT_PATH_CONVERSION_FUNCTIONS
+# -----------------------------
+# Determine what file name conversion functions should be used by
+# func_to_host_file (and, implicitly, by func_to_host_path).  These are needed
+# for certain cross-compile configurations and native mingw.
+m4_defun([_LT_PATH_CONVERSION_FUNCTIONS],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+AC_MSG_CHECKING([how to convert $build file names to $host format])
+AC_CACHE_VAL(lt_cv_to_host_file_cmd,
+[case $host in
+  *-*-mingw* )
+    case $build in
+      *-*-mingw* ) # actually msys
+        lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32
+        ;;
+      *-*-cygwin* )
+        lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32
+        ;;
+      * ) # otherwise, assume *nix
+        lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32
+        ;;
+    esac
+    ;;
+  *-*-cygwin* )
+    case $build in
+      *-*-mingw* ) # actually msys
+        lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin
+        ;;
+      *-*-cygwin* )
+        lt_cv_to_host_file_cmd=func_convert_file_noop
+        ;;
+      * ) # otherwise, assume *nix
+        lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin
+        ;;
+    esac
+    ;;
+  * ) # unhandled hosts (and "normal" native builds)
+    lt_cv_to_host_file_cmd=func_convert_file_noop
+    ;;
+esac
+])
+to_host_file_cmd=$lt_cv_to_host_file_cmd
+AC_MSG_RESULT([$lt_cv_to_host_file_cmd])
+_LT_DECL([to_host_file_cmd], [lt_cv_to_host_file_cmd],
+         [0], [convert $build file names to $host format])dnl
+
+AC_MSG_CHECKING([how to convert $build file names to toolchain format])
+AC_CACHE_VAL(lt_cv_to_tool_file_cmd,
+[#assume ordinary cross tools, or native build.
+lt_cv_to_tool_file_cmd=func_convert_file_noop
+case $host in
+  *-*-mingw* )
+    case $build in
+      *-*-mingw* ) # actually msys
+        lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32
+        ;;
+    esac
+    ;;
+esac
+])
+to_tool_file_cmd=$lt_cv_to_tool_file_cmd
+AC_MSG_RESULT([$lt_cv_to_tool_file_cmd])
+_LT_DECL([to_tool_file_cmd], [lt_cv_to_tool_file_cmd],
+         [0], [convert $build files to toolchain format])dnl
+])# _LT_PATH_CONVERSION_FUNCTIONS
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/config/ltmain.sh
@@ -0,0 +1,11156 @@
+#! /bin/sh
+## DO NOT EDIT - This file generated from ./build-aux/ltmain.in
+##               by inline-source v2014-01-03.01
+
+# libtool (GNU libtool) 2.4.6
+# Provide generalized library-building support services.
+# Written by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
+
+# Copyright (C) 1996-2015 Free Software Foundation, Inc.
+# This is free software; see the source for copying conditions.  There is NO
+# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+# GNU Libtool is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# As a special exception to the GNU General Public License,
+# if you distribute this file as part of a program or library that
+# is built using GNU Libtool, you may include this file under the
+# same distribution terms that you use for the rest of that program.
+#
+# GNU Libtool is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+
+PROGRAM=libtool
+PACKAGE=libtool
+VERSION="2.4.6 Debian-2.4.6-0.1"
+package_revision=2.4.6
+
+
+## ------ ##
+## Usage. ##
+## ------ ##
+
+# Run './libtool --help' for help with using this script from the
+# command line.
+
+
+## ------------------------------- ##
+## User overridable command paths. ##
+## ------------------------------- ##
+
+# After configure completes, it has a better idea of some of the
+# shell tools we need than the defaults used by the functions shared
+# with bootstrap, so set those here where they can still be over-
+# ridden by the user, but otherwise take precedence.
+
+: ${AUTOCONF="autoconf"}
+: ${AUTOMAKE="automake"}
+
+
+## -------------------------- ##
+## Source external libraries. ##
+## -------------------------- ##
+
+# Much of our low-level functionality needs to be sourced from external
+# libraries, which are installed to $pkgauxdir.
+
+# Set a version string for this script.
+scriptversion=2015-01-20.17; # UTC
+
+# General shell script boiler plate, and helper functions.
+# Written by Gary V. Vaughan, 2004
+
+# Copyright (C) 2004-2015 Free Software Foundation, Inc.
+# This is free software; see the source for copying conditions.  There is NO
+# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+
+# As a special exception to the GNU General Public License, if you distribute
+# this file as part of a program or library that is built using GNU Libtool,
+# you may include this file under the same distribution terms that you use
+# for the rest of that program.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNES FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+# Please report bugs or propose patches to gary@gnu.org.
+
+
+## ------ ##
+## Usage. ##
+## ------ ##
+
+# Evaluate this file near the top of your script to gain access to
+# the functions and variables defined here:
+#
+#   . `echo "$0" | ${SED-sed} 's|[^/]*$||'`/build-aux/funclib.sh
+#
+# If you need to override any of the default environment variable
+# settings, do that before evaluating this file.
+
+
+## -------------------- ##
+## Shell normalisation. ##
+## -------------------- ##
+
+# Some shells need a little help to be as Bourne compatible as possible.
+# Before doing anything else, make sure all that help has been provided!
+
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
+  emulate sh
+  NULLCMD=:
+  # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+  setopt NO_GLOB_SUBST
+else
+  case `(set -o) 2>/dev/null` in *posix*) set -o posix ;; esac
+fi
+
+# NLS nuisances: We save the old values in case they are required later.
+_G_user_locale=
+_G_safe_locale=
+for _G_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES
+do
+  eval "if test set = \"\${$_G_var+set}\"; then
+          save_$_G_var=\$$_G_var
+          $_G_var=C
+	  export $_G_var
+	  _G_user_locale=\"$_G_var=\\\$save_\$_G_var; \$_G_user_locale\"
+	  _G_safe_locale=\"$_G_var=C; \$_G_safe_locale\"
+	fi"
+done
+
+# CDPATH.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+# Make sure IFS has a sensible default
+sp=' '
+nl='
+'
+IFS="$sp	$nl"
+
+# There are apparently some retarded systems that use ';' as a PATH separator!
+if test "${PATH_SEPARATOR+set}" != set; then
+  PATH_SEPARATOR=:
+  (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+    (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+      PATH_SEPARATOR=';'
+  }
+fi
+
+
+
+## ------------------------- ##
+## Locate command utilities. ##
+## ------------------------- ##
+
+
+# func_executable_p FILE
+# ----------------------
+# Check that FILE is an executable regular file.
+func_executable_p ()
+{
+    test -f "$1" && test -x "$1"
+}
+
+
+# func_path_progs PROGS_LIST CHECK_FUNC [PATH]
+# --------------------------------------------
+# Search for either a program that responds to --version with output
+# containing "GNU", or else returned by CHECK_FUNC otherwise, by
+# trying all the directories in PATH with each of the elements of
+# PROGS_LIST.
+#
+# CHECK_FUNC should accept the path to a candidate program, and
+# set $func_check_prog_result if it truncates its output less than
+# $_G_path_prog_max characters.
+func_path_progs ()
+{
+    _G_progs_list=$1
+    _G_check_func=$2
+    _G_PATH=${3-"$PATH"}
+
+    _G_path_prog_max=0
+    _G_path_prog_found=false
+    _G_save_IFS=$IFS; IFS=${PATH_SEPARATOR-:}
+    for _G_dir in $_G_PATH; do
+      IFS=$_G_save_IFS
+      test -z "$_G_dir" && _G_dir=.
+      for _G_prog_name in $_G_progs_list; do
+        for _exeext in '' .EXE; do
+          _G_path_prog=$_G_dir/$_G_prog_name$_exeext
+          func_executable_p "$_G_path_prog" || continue
+          case `"$_G_path_prog" --version 2>&1` in
+            *GNU*) func_path_progs_result=$_G_path_prog _G_path_prog_found=: ;;
+            *)     $_G_check_func $_G_path_prog
+		   func_path_progs_result=$func_check_prog_result
+		   ;;
+          esac
+          $_G_path_prog_found && break 3
+        done
+      done
+    done
+    IFS=$_G_save_IFS
+    test -z "$func_path_progs_result" && {
+      echo "no acceptable sed could be found in \$PATH" >&2
+      exit 1
+    }
+}
+
+
+# We want to be able to use the functions in this file before configure
+# has figured out where the best binaries are kept, which means we have
+# to search for them ourselves - except when the results are already set
+# where we skip the searches.
+
+# Unless the user overrides by setting SED, search the path for either GNU
+# sed, or the sed that truncates its output the least.
+test -z "$SED" && {
+  _G_sed_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/
+  for _G_i in 1 2 3 4 5 6 7; do
+    _G_sed_script=$_G_sed_script$nl$_G_sed_script
+  done
+  echo "$_G_sed_script" 2>/dev/null | sed 99q >conftest.sed
+  _G_sed_script=
+
+  func_check_prog_sed ()
+  {
+    _G_path_prog=$1
+
+    _G_count=0
+    printf 0123456789 >conftest.in
+    while :
+    do
+      cat conftest.in conftest.in >conftest.tmp
+      mv conftest.tmp conftest.in
+      cp conftest.in conftest.nl
+      echo '' >> conftest.nl
+      "$_G_path_prog" -f conftest.sed <conftest.nl >conftest.out 2>/dev/null || break
+      diff conftest.out conftest.nl >/dev/null 2>&1 || break
+      _G_count=`expr $_G_count + 1`
+      if test "$_G_count" -gt "$_G_path_prog_max"; then
+        # Best one so far, save it but keep looking for a better one
+        func_check_prog_result=$_G_path_prog
+        _G_path_prog_max=$_G_count
+      fi
+      # 10*(2^10) chars as input seems more than enough
+      test 10 -lt "$_G_count" && break
+    done
+    rm -f conftest.in conftest.tmp conftest.nl conftest.out
+  }
+
+  func_path_progs "sed gsed" func_check_prog_sed $PATH:/usr/xpg4/bin
+  rm -f conftest.sed
+  SED=$func_path_progs_result
+}
+
+
+# Unless the user overrides by setting GREP, search the path for either GNU
+# grep, or the grep that truncates its output the least.
+test -z "$GREP" && {
+  func_check_prog_grep ()
+  {
+    _G_path_prog=$1
+
+    _G_count=0
+    _G_path_prog_max=0
+    printf 0123456789 >conftest.in
+    while :
+    do
+      cat conftest.in conftest.in >conftest.tmp
+      mv conftest.tmp conftest.in
+      cp conftest.in conftest.nl
+      echo 'GREP' >> conftest.nl
+      "$_G_path_prog" -e 'GREP$' -e '-(cannot match)-' <conftest.nl >conftest.out 2>/dev/null || break
+      diff conftest.out conftest.nl >/dev/null 2>&1 || break
+      _G_count=`expr $_G_count + 1`
+      if test "$_G_count" -gt "$_G_path_prog_max"; then
+        # Best one so far, save it but keep looking for a better one
+        func_check_prog_result=$_G_path_prog
+        _G_path_prog_max=$_G_count
+      fi
+      # 10*(2^10) chars as input seems more than enough
+      test 10 -lt "$_G_count" && break
+    done
+    rm -f conftest.in conftest.tmp conftest.nl conftest.out
+  }
+
+  func_path_progs "grep ggrep" func_check_prog_grep $PATH:/usr/xpg4/bin
+  GREP=$func_path_progs_result
+}
+
+
+## ------------------------------- ##
+## User overridable command paths. ##
+## ------------------------------- ##
+
+# All uppercase variable names are used for environment variables.  These
+# variables can be overridden by the user before calling a script that
+# uses them if a suitable command of that name is not already available
+# in the command search PATH.
+
+: ${CP="cp -f"}
+: ${ECHO="printf %s\n"}
+: ${EGREP="$GREP -E"}
+: ${FGREP="$GREP -F"}
+: ${LN_S="ln -s"}
+: ${MAKE="make"}
+: ${MKDIR="mkdir"}
+: ${MV="mv -f"}
+: ${RM="rm -f"}
+: ${SHELL="${CONFIG_SHELL-/bin/sh}"}
+
+
+## -------------------- ##
+## Useful sed snippets. ##
+## -------------------- ##
+
+sed_dirname='s|/[^/]*$||'
+sed_basename='s|^.*/||'
+
+# Sed substitution that helps us do robust quoting.  It backslashifies
+# metacharacters that are still active within double-quoted strings.
+sed_quote_subst='s|\([`"$\\]\)|\\\1|g'
+
+# Same as above, but do not quote variable references.
+sed_double_quote_subst='s/\(["`\\]\)/\\\1/g'
+
+# Sed substitution that turns a string into a regex matching for the
+# string literally.
+sed_make_literal_regex='s|[].[^$\\*\/]|\\&|g'
+
+# Sed substitution that converts a w32 file name or path
+# that contains forward slashes, into one that contains
+# (escaped) backslashes.  A very naive implementation.
+sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g'
+
+# Re-'\' parameter expansions in output of sed_double_quote_subst that
+# were '\'-ed in input to the same.  If an odd number of '\' preceded a
+# '$' in input to sed_double_quote_subst, that '$' was protected from
+# expansion.  Since each input '\' is now two '\'s, look for any number
+# of runs of four '\'s followed by two '\'s and then a '$'.  '\' that '$'.
+_G_bs='\\'
+_G_bs2='\\\\'
+_G_bs4='\\\\\\\\'
+_G_dollar='\$'
+sed_double_backslash="\
+  s/$_G_bs4/&\\
+/g
+  s/^$_G_bs2$_G_dollar/$_G_bs&/
+  s/\\([^$_G_bs]\\)$_G_bs2$_G_dollar/\\1$_G_bs2$_G_bs$_G_dollar/g
+  s/\n//g"
+
+
+## ----------------- ##
+## Global variables. ##
+## ----------------- ##
+
+# Except for the global variables explicitly listed below, the following
+# functions in the '^func_' namespace, and the '^require_' namespace
+# variables initialised in the 'Resource management' section, sourcing
+# this file will not pollute your global namespace with anything
+# else. There's no portable way to scope variables in Bourne shell
+# though, so actually running these functions will sometimes place
+# results into a variable named after the function, and often use
+# temporary variables in the '^_G_' namespace. If you are careful to
+# avoid using those namespaces casually in your sourcing script, things
+# should continue to work as you expect. And, of course, you can freely
+# overwrite any of the functions or variables defined here before
+# calling anything to customize them.
+
+EXIT_SUCCESS=0
+EXIT_FAILURE=1
+EXIT_MISMATCH=63  # $? = 63 is used to indicate version mismatch to missing.
+EXIT_SKIP=77	  # $? = 77 is used to indicate a skipped test to automake.
+
+# Allow overriding, eg assuming that you follow the convention of
+# putting '$debug_cmd' at the start of all your functions, you can get
+# bash to show function call trace with:
+#
+#    debug_cmd='eval echo "${FUNCNAME[0]} $*" >&2' bash your-script-name
+debug_cmd=${debug_cmd-":"}
+exit_cmd=:
+
+# By convention, finish your script with:
+#
+#    exit $exit_status
+#
+# so that you can set exit_status to non-zero if you want to indicate
+# something went wrong during execution without actually bailing out at
+# the point of failure.
+exit_status=$EXIT_SUCCESS
+
+# Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh
+# is ksh but when the shell is invoked as "sh" and the current value of
+# the _XPG environment variable is not equal to 1 (one), the special
+# positional parameter $0, within a function call, is the name of the
+# function.
+progpath=$0
+
+# The name of this program.
+progname=`$ECHO "$progpath" |$SED "$sed_basename"`
+
+# Make sure we have an absolute progpath for reexecution:
+case $progpath in
+  [\\/]*|[A-Za-z]:\\*) ;;
+  *[\\/]*)
+     progdir=`$ECHO "$progpath" |$SED "$sed_dirname"`
+     progdir=`cd "$progdir" && pwd`
+     progpath=$progdir/$progname
+     ;;
+  *)
+     _G_IFS=$IFS
+     IFS=${PATH_SEPARATOR-:}
+     for progdir in $PATH; do
+       IFS=$_G_IFS
+       test -x "$progdir/$progname" && break
+     done
+     IFS=$_G_IFS
+     test -n "$progdir" || progdir=`pwd`
+     progpath=$progdir/$progname
+     ;;
+esac
+
+
+## ----------------- ##
+## Standard options. ##
+## ----------------- ##
+
+# The following options affect the operation of the functions defined
+# below, and should be set appropriately depending on run-time para-
+# meters passed on the command line.
+
+opt_dry_run=false
+opt_quiet=false
+opt_verbose=false
+
+# Categories 'all' and 'none' are always available.  Append any others
+# you will pass as the first argument to func_warning from your own
+# code.
+warning_categories=
+
+# By default, display warnings according to 'opt_warning_types'.  Set
+# 'warning_func'  to ':' to elide all warnings, or func_fatal_error to
+# treat the next displayed warning as a fatal error.
+warning_func=func_warn_and_continue
+
+# Set to 'all' to display all warnings, 'none' to suppress all
+# warnings, or a space delimited list of some subset of
+# 'warning_categories' to display only the listed warnings.
+opt_warning_types=all
+
+
+## -------------------- ##
+## Resource management. ##
+## -------------------- ##
+
+# This section contains definitions for functions that each ensure a
+# particular resource (a file, or a non-empty configuration variable for
+# example) is available, and if appropriate to extract default values
+# from pertinent package files. Call them using their associated
+# 'require_*' variable to ensure that they are executed, at most, once.
+#
+# It's entirely deliberate that calling these functions can set
+# variables that don't obey the namespace limitations obeyed by the rest
+# of this file, in order that that they be as useful as possible to
+# callers.
+
+
+# require_term_colors
+# -------------------
+# Allow display of bold text on terminals that support it.
+require_term_colors=func_require_term_colors
+func_require_term_colors ()
+{
+    $debug_cmd
+
+    test -t 1 && {
+      # COLORTERM and USE_ANSI_COLORS environment variables take
+      # precedence, because most terminfo databases neglect to describe
+      # whether color sequences are supported.
+      test -n "${COLORTERM+set}" && : ${USE_ANSI_COLORS="1"}
+
+      if test 1 = "$USE_ANSI_COLORS"; then
+        # Standard ANSI escape sequences
+        tc_reset='[0m'
+        tc_bold='[1m';   tc_standout='[7m'
+        tc_red='[31m';   tc_green='[32m'
+        tc_blue='[34m';  tc_cyan='[36m'
+      else
+        # Otherwise trust the terminfo database after all.
+        test -n "`tput sgr0 2>/dev/null`" && {
+          tc_reset=`tput sgr0`
+          test -n "`tput bold 2>/dev/null`" && tc_bold=`tput bold`
+          tc_standout=$tc_bold
+          test -n "`tput smso 2>/dev/null`" && tc_standout=`tput smso`
+          test -n "`tput setaf 1 2>/dev/null`" && tc_red=`tput setaf 1`
+          test -n "`tput setaf 2 2>/dev/null`" && tc_green=`tput setaf 2`
+          test -n "`tput setaf 4 2>/dev/null`" && tc_blue=`tput setaf 4`
+          test -n "`tput setaf 5 2>/dev/null`" && tc_cyan=`tput setaf 5`
+        }
+      fi
+    }
+
+    require_term_colors=:
+}
+
+
+## ----------------- ##
+## Function library. ##
+## ----------------- ##
+
+# This section contains a variety of useful functions to call in your
+# scripts. Take note of the portable wrappers for features provided by
+# some modern shells, which will fall back to slower equivalents on
+# less featureful shells.
+
+
+# func_append VAR VALUE
+# ---------------------
+# Append VALUE onto the existing contents of VAR.
+
+  # We should try to minimise forks, especially on Windows where they are
+  # unreasonably slow, so skip the feature probes when bash or zsh are
+  # being used:
+  if test set = "${BASH_VERSION+set}${ZSH_VERSION+set}"; then
+    : ${_G_HAVE_ARITH_OP="yes"}
+    : ${_G_HAVE_XSI_OPS="yes"}
+    # The += operator was introduced in bash 3.1
+    case $BASH_VERSION in
+      [12].* | 3.0 | 3.0*) ;;
+      *)
+        : ${_G_HAVE_PLUSEQ_OP="yes"}
+        ;;
+    esac
+  fi
+
+  # _G_HAVE_PLUSEQ_OP
+  # Can be empty, in which case the shell is probed, "yes" if += is
+  # useable or anything else if it does not work.
+  test -z "$_G_HAVE_PLUSEQ_OP" \
+    && (eval 'x=a; x+=" b"; test "a b" = "$x"') 2>/dev/null \
+    && _G_HAVE_PLUSEQ_OP=yes
+
+if test yes = "$_G_HAVE_PLUSEQ_OP"
+then
+  # This is an XSI compatible shell, allowing a faster implementation...
+  eval 'func_append ()
+  {
+    $debug_cmd
+
+    eval "$1+=\$2"
+  }'
+else
+  # ...otherwise fall back to using expr, which is often a shell builtin.
+  func_append ()
+  {
+    $debug_cmd
+
+    eval "$1=\$$1\$2"
+  }
+fi
+
+
+# func_append_quoted VAR VALUE
+# ----------------------------
+# Quote VALUE and append to the end of shell variable VAR, separated
+# by a space.
+if test yes = "$_G_HAVE_PLUSEQ_OP"; then
+  eval 'func_append_quoted ()
+  {
+    $debug_cmd
+
+    func_quote_for_eval "$2"
+    eval "$1+=\\ \$func_quote_for_eval_result"
+  }'
+else
+  func_append_quoted ()
+  {
+    $debug_cmd
+
+    func_quote_for_eval "$2"
+    eval "$1=\$$1\\ \$func_quote_for_eval_result"
+  }
+fi
+
+
+# func_append_uniq VAR VALUE
+# --------------------------
+# Append unique VALUE onto the existing contents of VAR, assuming
+# entries are delimited by the first character of VALUE.  For example:
+#
+#   func_append_uniq options " --another-option option-argument"
+#
+# will only append to $options if " --another-option option-argument "
+# is not already present somewhere in $options already (note spaces at
+# each end implied by leading space in second argument).
+func_append_uniq ()
+{
+    $debug_cmd
+
+    eval _G_current_value='`$ECHO $'$1'`'
+    _G_delim=`expr "$2" : '\(.\)'`
+
+    case $_G_delim$_G_current_value$_G_delim in
+      *"$2$_G_delim"*) ;;
+      *) func_append "$@" ;;
+    esac
+}
+
+
+# func_arith TERM...
+# ------------------
+# Set func_arith_result to the result of evaluating TERMs.
+  test -z "$_G_HAVE_ARITH_OP" \
+    && (eval 'test 2 = $(( 1 + 1 ))') 2>/dev/null \
+    && _G_HAVE_ARITH_OP=yes
+
+if test yes = "$_G_HAVE_ARITH_OP"; then
+  eval 'func_arith ()
+  {
+    $debug_cmd
+
+    func_arith_result=$(( $* ))
+  }'
+else
+  func_arith ()
+  {
+    $debug_cmd
+
+    func_arith_result=`expr "$@"`
+  }
+fi
+
+
+# func_basename FILE
+# ------------------
+# Set func_basename_result to FILE with everything up to and including
+# the last / stripped.
+if test yes = "$_G_HAVE_XSI_OPS"; then
+  # If this shell supports suffix pattern removal, then use it to avoid
+  # forking. Hide the definitions single quotes in case the shell chokes
+  # on unsupported syntax...
+  _b='func_basename_result=${1##*/}'
+  _d='case $1 in
+        */*) func_dirname_result=${1%/*}$2 ;;
+        *  ) func_dirname_result=$3        ;;
+      esac'
+
+else
+  # ...otherwise fall back to using sed.
+  _b='func_basename_result=`$ECHO "$1" |$SED "$sed_basename"`'
+  _d='func_dirname_result=`$ECHO "$1"  |$SED "$sed_dirname"`
+      if test "X$func_dirname_result" = "X$1"; then
+        func_dirname_result=$3
+      else
+        func_append func_dirname_result "$2"
+      fi'
+fi
+
+eval 'func_basename ()
+{
+    $debug_cmd
+
+    '"$_b"'
+}'
+
+
+# func_dirname FILE APPEND NONDIR_REPLACEMENT
+# -------------------------------------------
+# Compute the dirname of FILE.  If nonempty, add APPEND to the result,
+# otherwise set result to NONDIR_REPLACEMENT.
+eval 'func_dirname ()
+{
+    $debug_cmd
+
+    '"$_d"'
+}'
+
+
+# func_dirname_and_basename FILE APPEND NONDIR_REPLACEMENT
+# --------------------------------------------------------
+# Perform func_basename and func_dirname in a single function
+# call:
+#   dirname:  Compute the dirname of FILE.  If nonempty,
+#             add APPEND to the result, otherwise set result
+#             to NONDIR_REPLACEMENT.
+#             value returned in "$func_dirname_result"
+#   basename: Compute filename of FILE.
+#             value retuned in "$func_basename_result"
+# For efficiency, we do not delegate to the functions above but instead
+# duplicate the functionality here.
+eval 'func_dirname_and_basename ()
+{
+    $debug_cmd
+
+    '"$_b"'
+    '"$_d"'
+}'
+
+
+# func_echo ARG...
+# ----------------
+# Echo program name prefixed message.
+func_echo ()
+{
+    $debug_cmd
+
+    _G_message=$*
+
+    func_echo_IFS=$IFS
+    IFS=$nl
+    for _G_line in $_G_message; do
+      IFS=$func_echo_IFS
+      $ECHO "$progname: $_G_line"
+    done
+    IFS=$func_echo_IFS
+}
+
+
+# func_echo_all ARG...
+# --------------------
+# Invoke $ECHO with all args, space-separated.
+func_echo_all ()
+{
+    $ECHO "$*"
+}
+
+
+# func_echo_infix_1 INFIX ARG...
+# ------------------------------
+# Echo program name, followed by INFIX on the first line, with any
+# additional lines not showing INFIX.
+func_echo_infix_1 ()
+{
+    $debug_cmd
+
+    $require_term_colors
+
+    _G_infix=$1; shift
+    _G_indent=$_G_infix
+    _G_prefix="$progname: $_G_infix: "
+    _G_message=$*
+
+    # Strip color escape sequences before counting printable length
+    for _G_tc in "$tc_reset" "$tc_bold" "$tc_standout" "$tc_red" "$tc_green" "$tc_blue" "$tc_cyan"
+    do
+      test -n "$_G_tc" && {
+        _G_esc_tc=`$ECHO "$_G_tc" | $SED "$sed_make_literal_regex"`
+        _G_indent=`$ECHO "$_G_indent" | $SED "s|$_G_esc_tc||g"`
+      }
+    done
+    _G_indent="$progname: "`echo "$_G_indent" | $SED 's|.| |g'`"  " ## exclude from sc_prohibit_nested_quotes
+
+    func_echo_infix_1_IFS=$IFS
+    IFS=$nl
+    for _G_line in $_G_message; do
+      IFS=$func_echo_infix_1_IFS
+      $ECHO "$_G_prefix$tc_bold$_G_line$tc_reset" >&2
+      _G_prefix=$_G_indent
+    done
+    IFS=$func_echo_infix_1_IFS
+}
+
+
+# func_error ARG...
+# -----------------
+# Echo program name prefixed message to standard error.
+func_error ()
+{
+    $debug_cmd
+
+    $require_term_colors
+
+    func_echo_infix_1 "  $tc_standout${tc_red}error$tc_reset" "$*" >&2
+}
+
+
+# func_fatal_error ARG...
+# -----------------------
+# Echo program name prefixed message to standard error, and exit.
+func_fatal_error ()
+{
+    $debug_cmd
+
+    func_error "$*"
+    exit $EXIT_FAILURE
+}
+
+
+# func_grep EXPRESSION FILENAME
+# -----------------------------
+# Check whether EXPRESSION matches any line of FILENAME, without output.
+func_grep ()
+{
+    $debug_cmd
+
+    $GREP "$1" "$2" >/dev/null 2>&1
+}
+
+
+# func_len STRING
+# ---------------
+# Set func_len_result to the length of STRING. STRING may not
+# start with a hyphen.
+  test -z "$_G_HAVE_XSI_OPS" \
+    && (eval 'x=a/b/c;
+      test 5aa/bb/cc = "${#x}${x%%/*}${x%/*}${x#*/}${x##*/}"') 2>/dev/null \
+    && _G_HAVE_XSI_OPS=yes
+
+if test yes = "$_G_HAVE_XSI_OPS"; then
+  eval 'func_len ()
+  {
+    $debug_cmd
+
+    func_len_result=${#1}
+  }'
+else
+  func_len ()
+  {
+    $debug_cmd
+
+    func_len_result=`expr "$1" : ".*" 2>/dev/null || echo $max_cmd_len`
+  }
+fi
+
+
+# func_mkdir_p DIRECTORY-PATH
+# ---------------------------
+# Make sure the entire path to DIRECTORY-PATH is available.
+func_mkdir_p ()
+{
+    $debug_cmd
+
+    _G_directory_path=$1
+    _G_dir_list=
+
+    if test -n "$_G_directory_path" && test : != "$opt_dry_run"; then
+
+      # Protect directory names starting with '-'
+      case $_G_directory_path in
+        -*) _G_directory_path=./$_G_directory_path ;;
+      esac
+
+      # While some portion of DIR does not yet exist...
+      while test ! -d "$_G_directory_path"; do
+        # ...make a list in topmost first order.  Use a colon delimited
+	# list incase some portion of path contains whitespace.
+        _G_dir_list=$_G_directory_path:$_G_dir_list
+
+        # If the last portion added has no slash in it, the list is done
+        case $_G_directory_path in */*) ;; *) break ;; esac
+
+        # ...otherwise throw away the child directory and loop
+        _G_directory_path=`$ECHO "$_G_directory_path" | $SED -e "$sed_dirname"`
+      done
+      _G_dir_list=`$ECHO "$_G_dir_list" | $SED 's|:*$||'`
+
+      func_mkdir_p_IFS=$IFS; IFS=:
+      for _G_dir in $_G_dir_list; do
+	IFS=$func_mkdir_p_IFS
+        # mkdir can fail with a 'File exist' error if two processes
+        # try to create one of the directories concurrently.  Don't
+        # stop in that case!
+        $MKDIR "$_G_dir" 2>/dev/null || :
+      done
+      IFS=$func_mkdir_p_IFS
+
+      # Bail out if we (or some other process) failed to create a directory.
+      test -d "$_G_directory_path" || \
+        func_fatal_error "Failed to create '$1'"
+    fi
+}
+
+
+# func_mktempdir [BASENAME]
+# -------------------------
+# Make a temporary directory that won't clash with other running
+# libtool processes, and avoids race conditions if possible.  If
+# given, BASENAME is the basename for that directory.
+func_mktempdir ()
+{
+    $debug_cmd
+
+    _G_template=${TMPDIR-/tmp}/${1-$progname}
+
+    if test : = "$opt_dry_run"; then
+      # Return a directory name, but don't create it in dry-run mode
+      _G_tmpdir=$_G_template-$$
+    else
+
+      # If mktemp works, use that first and foremost
+      _G_tmpdir=`mktemp -d "$_G_template-XXXXXXXX" 2>/dev/null`
+
+      if test ! -d "$_G_tmpdir"; then
+        # Failing that, at least try and use $RANDOM to avoid a race
+        _G_tmpdir=$_G_template-${RANDOM-0}$$
+
+        func_mktempdir_umask=`umask`
+        umask 0077
+        $MKDIR "$_G_tmpdir"
+        umask $func_mktempdir_umask
+      fi
+
+      # If we're not in dry-run mode, bomb out on failure
+      test -d "$_G_tmpdir" || \
+        func_fatal_error "cannot create temporary directory '$_G_tmpdir'"
+    fi
+
+    $ECHO "$_G_tmpdir"
+}
+
+
+# func_normal_abspath PATH
+# ------------------------
+# Remove doubled-up and trailing slashes, "." path components,
+# and cancel out any ".." path components in PATH after making
+# it an absolute path.
+func_normal_abspath ()
+{
+    $debug_cmd
+
+    # These SED scripts presuppose an absolute path with a trailing slash.
+    _G_pathcar='s|^/\([^/]*\).*$|\1|'
+    _G_pathcdr='s|^/[^/]*||'
+    _G_removedotparts=':dotsl
+		s|/\./|/|g
+		t dotsl
+		s|/\.$|/|'
+    _G_collapseslashes='s|/\{1,\}|/|g'
+    _G_finalslash='s|/*$|/|'
+
+    # Start from root dir and reassemble the path.
+    func_normal_abspath_result=
+    func_normal_abspath_tpath=$1
+    func_normal_abspath_altnamespace=
+    case $func_normal_abspath_tpath in
+      "")
+        # Empty path, that just means $cwd.
+        func_stripname '' '/' "`pwd`"
+        func_normal_abspath_result=$func_stripname_result
+        return
+        ;;
+      # The next three entries are used to spot a run of precisely
+      # two leading slashes without using negated character classes;
+      # we take advantage of case's first-match behaviour.
+      ///*)
+        # Unusual form of absolute path, do nothing.
+        ;;
+      //*)
+        # Not necessarily an ordinary path; POSIX reserves leading '//'
+        # and for example Cygwin uses it to access remote file shares
+        # over CIFS/SMB, so we conserve a leading double slash if found.
+        func_normal_abspath_altnamespace=/
+        ;;
+      /*)
+        # Absolute path, do nothing.
+        ;;
+      *)
+        # Relative path, prepend $cwd.
+        func_normal_abspath_tpath=`pwd`/$func_normal_abspath_tpath
+        ;;
+    esac
+
+    # Cancel out all the simple stuff to save iterations.  We also want
+    # the path to end with a slash for ease of parsing, so make sure
+    # there is one (and only one) here.
+    func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \
+          -e "$_G_removedotparts" -e "$_G_collapseslashes" -e "$_G_finalslash"`
+    while :; do
+      # Processed it all yet?
+      if test / = "$func_normal_abspath_tpath"; then
+        # If we ascended to the root using ".." the result may be empty now.
+        if test -z "$func_normal_abspath_result"; then
+          func_normal_abspath_result=/
+        fi
+        break
+      fi
+      func_normal_abspath_tcomponent=`$ECHO "$func_normal_abspath_tpath" | $SED \
+          -e "$_G_pathcar"`
+      func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \
+          -e "$_G_pathcdr"`
+      # Figure out what to do with it
+      case $func_normal_abspath_tcomponent in
+        "")
+          # Trailing empty path component, ignore it.
+          ;;
+        ..)
+          # Parent dir; strip last assembled component from result.
+          func_dirname "$func_normal_abspath_result"
+          func_normal_abspath_result=$func_dirname_result
+          ;;
+        *)
+          # Actual path component, append it.
+          func_append func_normal_abspath_result "/$func_normal_abspath_tcomponent"
+          ;;
+      esac
+    done
+    # Restore leading double-slash if one was found on entry.
+    func_normal_abspath_result=$func_normal_abspath_altnamespace$func_normal_abspath_result
+}
+
+
+# func_notquiet ARG...
+# --------------------
+# Echo program name prefixed message only when not in quiet mode.
+func_notquiet ()
+{
+    $debug_cmd
+
+    $opt_quiet || func_echo ${1+"$@"}
+
+    # A bug in bash halts the script if the last line of a function
+    # fails when set -e is in force, so we need another command to
+    # work around that:
+    :
+}
+
+
+# func_relative_path SRCDIR DSTDIR
+# --------------------------------
+# Set func_relative_path_result to the relative path from SRCDIR to DSTDIR.
+func_relative_path ()
+{
+    $debug_cmd
+
+    func_relative_path_result=
+    func_normal_abspath "$1"
+    func_relative_path_tlibdir=$func_normal_abspath_result
+    func_normal_abspath "$2"
+    func_relative_path_tbindir=$func_normal_abspath_result
+
+    # Ascend the tree starting from libdir
+    while :; do
+      # check if we have found a prefix of bindir
+      case $func_relative_path_tbindir in
+        $func_relative_path_tlibdir)
+          # found an exact match
+          func_relative_path_tcancelled=
+          break
+          ;;
+        $func_relative_path_tlibdir*)
+          # found a matching prefix
+          func_stripname "$func_relative_path_tlibdir" '' "$func_relative_path_tbindir"
+          func_relative_path_tcancelled=$func_stripname_result
+          if test -z "$func_relative_path_result"; then
+            func_relative_path_result=.
+          fi
+          break
+          ;;
+        *)
+          func_dirname $func_relative_path_tlibdir
+          func_relative_path_tlibdir=$func_dirname_result
+          if test -z "$func_relative_path_tlibdir"; then
+            # Have to descend all the way to the root!
+            func_relative_path_result=../$func_relative_path_result
+            func_relative_path_tcancelled=$func_relative_path_tbindir
+            break
+          fi
+          func_relative_path_result=../$func_relative_path_result
+          ;;
+      esac
+    done
+
+    # Now calculate path; take care to avoid doubling-up slashes.
+    func_stripname '' '/' "$func_relative_path_result"
+    func_relative_path_result=$func_stripname_result
+    func_stripname '/' '/' "$func_relative_path_tcancelled"
+    if test -n "$func_stripname_result"; then
+      func_append func_relative_path_result "/$func_stripname_result"
+    fi
+
+    # Normalisation. If bindir is libdir, return '.' else relative path.
+    if test -n "$func_relative_path_result"; then
+      func_stripname './' '' "$func_relative_path_result"
+      func_relative_path_result=$func_stripname_result
+    fi
+
+    test -n "$func_relative_path_result" || func_relative_path_result=.
+
+    :
+}
+
+
+# func_quote_for_eval ARG...
+# --------------------------
+# Aesthetically quote ARGs to be evaled later.
+# This function returns two values:
+#   i) func_quote_for_eval_result
+#      double-quoted, suitable for a subsequent eval
+#  ii) func_quote_for_eval_unquoted_result
+#      has all characters that are still active within double
+#      quotes backslashified.
+func_quote_for_eval ()
+{
+    $debug_cmd
+
+    func_quote_for_eval_unquoted_result=
+    func_quote_for_eval_result=
+    while test 0 -lt $#; do
+      case $1 in
+        *[\\\`\"\$]*)
+	  _G_unquoted_arg=`printf '%s\n' "$1" |$SED "$sed_quote_subst"` ;;
+        *)
+          _G_unquoted_arg=$1 ;;
+      esac
+      if test -n "$func_quote_for_eval_unquoted_result"; then
+	func_append func_quote_for_eval_unquoted_result " $_G_unquoted_arg"
+      else
+        func_append func_quote_for_eval_unquoted_result "$_G_unquoted_arg"
+      fi
+
+      case $_G_unquoted_arg in
+        # Double-quote args containing shell metacharacters to delay
+        # word splitting, command substitution and variable expansion
+        # for a subsequent eval.
+        # Many Bourne shells cannot handle close brackets correctly
+        # in scan sets, so we specify it separately.
+        *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
+          _G_quoted_arg=\"$_G_unquoted_arg\"
+          ;;
+        *)
+          _G_quoted_arg=$_G_unquoted_arg
+	  ;;
+      esac
+
+      if test -n "$func_quote_for_eval_result"; then
+	func_append func_quote_for_eval_result " $_G_quoted_arg"
+      else
+        func_append func_quote_for_eval_result "$_G_quoted_arg"
+      fi
+      shift
+    done
+}
+
+
+# func_quote_for_expand ARG
+# -------------------------
+# Aesthetically quote ARG to be evaled later; same as above,
+# but do not quote variable references.
+func_quote_for_expand ()
+{
+    $debug_cmd
+
+    case $1 in
+      *[\\\`\"]*)
+	_G_arg=`$ECHO "$1" | $SED \
+	    -e "$sed_double_quote_subst" -e "$sed_double_backslash"` ;;
+      *)
+        _G_arg=$1 ;;
+    esac
+
+    case $_G_arg in
+      # Double-quote args containing shell metacharacters to delay
+      # word splitting and command substitution for a subsequent eval.
+      # Many Bourne shells cannot handle close brackets correctly
+      # in scan sets, so we specify it separately.
+      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
+        _G_arg=\"$_G_arg\"
+        ;;
+    esac
+
+    func_quote_for_expand_result=$_G_arg
+}
+
+
+# func_stripname PREFIX SUFFIX NAME
+# ---------------------------------
+# strip PREFIX and SUFFIX from NAME, and store in func_stripname_result.
+# PREFIX and SUFFIX must not contain globbing or regex special
+# characters, hashes, percent signs, but SUFFIX may contain a leading
+# dot (in which case that matches only a dot).
+if test yes = "$_G_HAVE_XSI_OPS"; then
+  eval 'func_stripname ()
+  {
+    $debug_cmd
+
+    # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are
+    # positional parameters, so assign one to ordinary variable first.
+    func_stripname_result=$3
+    func_stripname_result=${func_stripname_result#"$1"}
+    func_stripname_result=${func_stripname_result%"$2"}
+  }'
+else
+  func_stripname ()
+  {
+    $debug_cmd
+
+    case $2 in
+      .*) func_stripname_result=`$ECHO "$3" | $SED -e "s%^$1%%" -e "s%\\\\$2\$%%"`;;
+      *)  func_stripname_result=`$ECHO "$3" | $SED -e "s%^$1%%" -e "s%$2\$%%"`;;
+    esac
+  }
+fi
+
+
+# func_show_eval CMD [FAIL_EXP]
+# -----------------------------
+# Unless opt_quiet is true, then output CMD.  Then, if opt_dryrun is
+# not true, evaluate CMD.  If the evaluation of CMD fails, and FAIL_EXP
+# is given, then evaluate it.
+func_show_eval ()
+{
+    $debug_cmd
+
+    _G_cmd=$1
+    _G_fail_exp=${2-':'}
+
+    func_quote_for_expand "$_G_cmd"
+    eval "func_notquiet $func_quote_for_expand_result"
+
+    $opt_dry_run || {
+      eval "$_G_cmd"
+      _G_status=$?
+      if test 0 -ne "$_G_status"; then
+	eval "(exit $_G_status); $_G_fail_exp"
+      fi
+    }
+}
+
+
+# func_show_eval_locale CMD [FAIL_EXP]
+# ------------------------------------
+# Unless opt_quiet is true, then output CMD.  Then, if opt_dryrun is
+# not true, evaluate CMD.  If the evaluation of CMD fails, and FAIL_EXP
+# is given, then evaluate it.  Use the saved locale for evaluation.
+func_show_eval_locale ()
+{
+    $debug_cmd
+
+    _G_cmd=$1
+    _G_fail_exp=${2-':'}
+
+    $opt_quiet || {
+      func_quote_for_expand "$_G_cmd"
+      eval "func_echo $func_quote_for_expand_result"
+    }
+
+    $opt_dry_run || {
+      eval "$_G_user_locale
+	    $_G_cmd"
+      _G_status=$?
+      eval "$_G_safe_locale"
+      if test 0 -ne "$_G_status"; then
+	eval "(exit $_G_status); $_G_fail_exp"
+      fi
+    }
+}
+
+
+# func_tr_sh
+# ----------
+# Turn $1 into a string suitable for a shell variable name.
+# Result is stored in $func_tr_sh_result.  All characters
+# not in the set a-zA-Z0-9_ are replaced with '_'. Further,
+# if $1 begins with a digit, a '_' is prepended as well.
+func_tr_sh ()
+{
+    $debug_cmd
+
+    case $1 in
+    [0-9]* | *[!a-zA-Z0-9_]*)
+      func_tr_sh_result=`$ECHO "$1" | $SED -e 's/^\([0-9]\)/_\1/' -e 's/[^a-zA-Z0-9_]/_/g'`
+      ;;
+    * )
+      func_tr_sh_result=$1
+      ;;
+    esac
+}
+
+
+# func_verbose ARG...
+# -------------------
+# Echo program name prefixed message in verbose mode only.
+func_verbose ()
+{
+    $debug_cmd
+
+    $opt_verbose && func_echo "$*"
+
+    :
+}
+
+
+# func_warn_and_continue ARG...
+# -----------------------------
+# Echo program name prefixed warning message to standard error.
+func_warn_and_continue ()
+{
+    $debug_cmd
+
+    $require_term_colors
+
+    func_echo_infix_1 "${tc_red}warning$tc_reset" "$*" >&2
+}
+
+
+# func_warning CATEGORY ARG...
+# ----------------------------
+# Echo program name prefixed warning message to standard error. Warning
+# messages can be filtered according to CATEGORY, where this function
+# elides messages where CATEGORY is not listed in the global variable
+# 'opt_warning_types'.
+func_warning ()
+{
+    $debug_cmd
+
+    # CATEGORY must be in the warning_categories list!
+    case " $warning_categories " in
+      *" $1 "*) ;;
+      *) func_internal_error "invalid warning category '$1'" ;;
+    esac
+
+    _G_category=$1
+    shift
+
+    case " $opt_warning_types " in
+      *" $_G_category "*) $warning_func ${1+"$@"} ;;
+    esac
+}
+
+
+# func_sort_ver VER1 VER2
+# -----------------------
+# 'sort -V' is not generally available.
+# Note this deviates from the version comparison in automake
+# in that it treats 1.5 < 1.5.0, and treats 1.4.4a < 1.4-p3a
+# but this should suffice as we won't be specifying old
+# version formats or redundant trailing .0 in bootstrap.conf.
+# If we did want full compatibility then we should probably
+# use m4_version_compare from autoconf.
+func_sort_ver ()
+{
+    $debug_cmd
+
+    printf '%s\n%s\n' "$1" "$2" \
+      | sort -t. -k 1,1n -k 2,2n -k 3,3n -k 4,4n -k 5,5n -k 6,6n -k 7,7n -k 8,8n -k 9,9n
+}
+
+# func_lt_ver PREV CURR
+# ---------------------
+# Return true if PREV and CURR are in the correct order according to
+# func_sort_ver, otherwise false.  Use it like this:
+#
+#  func_lt_ver "$prev_ver" "$proposed_ver" || func_fatal_error "..."
+func_lt_ver ()
+{
+    $debug_cmd
+
+    test "x$1" = x`func_sort_ver "$1" "$2" | $SED 1q`
+}
+
+
+# Local variables:
+# mode: shell-script
+# sh-indentation: 2
+# eval: (add-hook 'before-save-hook 'time-stamp)
+# time-stamp-pattern: "10/scriptversion=%:y-%02m-%02d.%02H; # UTC"
+# time-stamp-time-zone: "UTC"
+# End:
+#! /bin/sh
+
+# Set a version string for this script.
+scriptversion=2014-01-07.03; # UTC
+
+# A portable, pluggable option parser for Bourne shell.
+# Written by Gary V. Vaughan, 2010
+
+# Copyright (C) 2010-2015 Free Software Foundation, Inc.
+# This is free software; see the source for copying conditions.  There is NO
+# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# Please report bugs or propose patches to gary@gnu.org.
+
+
+## ------ ##
+## Usage. ##
+## ------ ##
+
+# This file is a library for parsing options in your shell scripts along
+# with assorted other useful supporting features that you can make use
+# of too.
+#
+# For the simplest scripts you might need only:
+#
+#   #!/bin/sh
+#   . relative/path/to/funclib.sh
+#   . relative/path/to/options-parser
+#   scriptversion=1.0
+#   func_options ${1+"$@"}
+#   eval set dummy "$func_options_result"; shift
+#   ...rest of your script...
+#
+# In order for the '--version' option to work, you will need to have a
+# suitably formatted comment like the one at the top of this file
+# starting with '# Written by ' and ending with '# warranty; '.
+#
+# For '-h' and '--help' to work, you will also need a one line
+# description of your script's purpose in a comment directly above the
+# '# Written by ' line, like the one at the top of this file.
+#
+# The default options also support '--debug', which will turn on shell
+# execution tracing (see the comment above debug_cmd below for another
+# use), and '--verbose' and the func_verbose function to allow your script
+# to display verbose messages only when your user has specified
+# '--verbose'.
+#
+# After sourcing this file, you can plug processing for additional
+# options by amending the variables from the 'Configuration' section
+# below, and following the instructions in the 'Option parsing'
+# section further down.
+
+## -------------- ##
+## Configuration. ##
+## -------------- ##
+
+# You should override these variables in your script after sourcing this
+# file so that they reflect the customisations you have added to the
+# option parser.
+
+# The usage line for option parsing errors and the start of '-h' and
+# '--help' output messages. You can embed shell variables for delayed
+# expansion at the time the message is displayed, but you will need to
+# quote other shell meta-characters carefully to prevent them being
+# expanded when the contents are evaled.
+usage='$progpath [OPTION]...'
+
+# Short help message in response to '-h' and '--help'.  Add to this or
+# override it after sourcing this library to reflect the full set of
+# options your script accepts.
+usage_message="\
+       --debug        enable verbose shell tracing
+   -W, --warnings=CATEGORY
+                      report the warnings falling in CATEGORY [all]
+   -v, --verbose      verbosely report processing
+       --version      print version information and exit
+   -h, --help         print short or long help message and exit
+"
+
+# Additional text appended to 'usage_message' in response to '--help'.
+long_help_message="
+Warning categories include:
+       'all'          show all warnings
+       'none'         turn off all the warnings
+       'error'        warnings are treated as fatal errors"
+
+# Help message printed before fatal option parsing errors.
+fatal_help="Try '\$progname --help' for more information."
+
+
+
+## ------------------------- ##
+## Hook function management. ##
+## ------------------------- ##
+
+# This section contains functions for adding, removing, and running hooks
+# to the main code.  A hook is just a named list of of function, that can
+# be run in order later on.
+
+# func_hookable FUNC_NAME
+# -----------------------
+# Declare that FUNC_NAME will run hooks added with
+# 'func_add_hook FUNC_NAME ...'.
+func_hookable ()
+{
+    $debug_cmd
+
+    func_append hookable_fns " $1"
+}
+
+
+# func_add_hook FUNC_NAME HOOK_FUNC
+# ---------------------------------
+# Request that FUNC_NAME call HOOK_FUNC before it returns.  FUNC_NAME must
+# first have been declared "hookable" by a call to 'func_hookable'.
+func_add_hook ()
+{
+    $debug_cmd
+
+    case " $hookable_fns " in
+      *" $1 "*) ;;
+      *) func_fatal_error "'$1' does not accept hook functions." ;;
+    esac
+
+    eval func_append ${1}_hooks '" $2"'
+}
+
+
+# func_remove_hook FUNC_NAME HOOK_FUNC
+# ------------------------------------
+# Remove HOOK_FUNC from the list of functions called by FUNC_NAME.
+func_remove_hook ()
+{
+    $debug_cmd
+
+    eval ${1}_hooks='`$ECHO "\$'$1'_hooks" |$SED "s| '$2'||"`'
+}
+
+
+# func_run_hooks FUNC_NAME [ARG]...
+# ---------------------------------
+# Run all hook functions registered to FUNC_NAME.
+# It is assumed that the list of hook functions contains nothing more
+# than a whitespace-delimited list of legal shell function names, and
+# no effort is wasted trying to catch shell meta-characters or preserve
+# whitespace.
+func_run_hooks ()
+{
+    $debug_cmd
+
+    case " $hookable_fns " in
+      *" $1 "*) ;;
+      *) func_fatal_error "'$1' does not support hook funcions.n" ;;
+    esac
+
+    eval _G_hook_fns=\$$1_hooks; shift
+
+    for _G_hook in $_G_hook_fns; do
+      eval $_G_hook '"$@"'
+
+      # store returned options list back into positional
+      # parameters for next 'cmd' execution.
+      eval _G_hook_result=\$${_G_hook}_result
+      eval set dummy "$_G_hook_result"; shift
+    done
+
+    func_quote_for_eval ${1+"$@"}
+    func_run_hooks_result=$func_quote_for_eval_result
+}
+
+
+
+## --------------- ##
+## Option parsing. ##
+## --------------- ##
+
+# In order to add your own option parsing hooks, you must accept the
+# full positional parameter list in your hook function, remove any
+# options that you action, and then pass back the remaining unprocessed
+# options in '<hooked_function_name>_result', escaped suitably for
+# 'eval'.  Like this:
+#
+#    my_options_prep ()
+#    {
+#        $debug_cmd
+#
+#        # Extend the existing usage message.
+#        usage_message=$usage_message'
+#      -s, --silent       don'\''t print informational messages
+#    '
+#
+#        func_quote_for_eval ${1+"$@"}
+#        my_options_prep_result=$func_quote_for_eval_result
+#    }
+#    func_add_hook func_options_prep my_options_prep
+#
+#
+#    my_silent_option ()
+#    {
+#        $debug_cmd
+#
+#        # Note that for efficiency, we parse as many options as we can
+#        # recognise in a loop before passing the remainder back to the
+#        # caller on the first unrecognised argument we encounter.
+#        while test $# -gt 0; do
+#          opt=$1; shift
+#          case $opt in
+#            --silent|-s) opt_silent=: ;;
+#            # Separate non-argument short options:
+#            -s*)         func_split_short_opt "$_G_opt"
+#                         set dummy "$func_split_short_opt_name" \
+#                             "-$func_split_short_opt_arg" ${1+"$@"}
+#                         shift
+#                         ;;
+#            *)            set dummy "$_G_opt" "$*"; shift; break ;;
+#          esac
+#        done
+#
+#        func_quote_for_eval ${1+"$@"}
+#        my_silent_option_result=$func_quote_for_eval_result
+#    }
+#    func_add_hook func_parse_options my_silent_option
+#
+#
+#    my_option_validation ()
+#    {
+#        $debug_cmd
+#
+#        $opt_silent && $opt_verbose && func_fatal_help "\
+#    '--silent' and '--verbose' options are mutually exclusive."
+#
+#        func_quote_for_eval ${1+"$@"}
+#        my_option_validation_result=$func_quote_for_eval_result
+#    }
+#    func_add_hook func_validate_options my_option_validation
+#
+# You'll alse need to manually amend $usage_message to reflect the extra
+# options you parse.  It's preferable to append if you can, so that
+# multiple option parsing hooks can be added safely.
+
+
+# func_options [ARG]...
+# ---------------------
+# All the functions called inside func_options are hookable. See the
+# individual implementations for details.
+func_hookable func_options
+func_options ()
+{
+    $debug_cmd
+
+    func_options_prep ${1+"$@"}
+    eval func_parse_options \
+        ${func_options_prep_result+"$func_options_prep_result"}
+    eval func_validate_options \
+        ${func_parse_options_result+"$func_parse_options_result"}
+
+    eval func_run_hooks func_options \
+        ${func_validate_options_result+"$func_validate_options_result"}
+
+    # save modified positional parameters for caller
+    func_options_result=$func_run_hooks_result
+}
+
+
+# func_options_prep [ARG]...
+# --------------------------
+# All initialisations required before starting the option parse loop.
+# Note that when calling hook functions, we pass through the list of
+# positional parameters.  If a hook function modifies that list, and
+# needs to propogate that back to rest of this script, then the complete
+# modified list must be put in 'func_run_hooks_result' before
+# returning.
+func_hookable func_options_prep
+func_options_prep ()
+{
+    $debug_cmd
+
+    # Option defaults:
+    opt_verbose=false
+    opt_warning_types=
+
+    func_run_hooks func_options_prep ${1+"$@"}
+
+    # save modified positional parameters for caller
+    func_options_prep_result=$func_run_hooks_result
+}
+
+
+# func_parse_options [ARG]...
+# ---------------------------
+# The main option parsing loop.
+func_hookable func_parse_options
+func_parse_options ()
+{
+    $debug_cmd
+
+    func_parse_options_result=
+
+    # this just eases exit handling
+    while test $# -gt 0; do
+      # Defer to hook functions for initial option parsing, so they
+      # get priority in the event of reusing an option name.
+      func_run_hooks func_parse_options ${1+"$@"}
+
+      # Adjust func_parse_options positional parameters to match
+      eval set dummy "$func_run_hooks_result"; shift
+
+      # Break out of the loop if we already parsed every option.
+      test $# -gt 0 || break
+
+      _G_opt=$1
+      shift
+      case $_G_opt in
+        --debug|-x)   debug_cmd='set -x'
+                      func_echo "enabling shell trace mode"
+                      $debug_cmd
+                      ;;
+
+        --no-warnings|--no-warning|--no-warn)
+                      set dummy --warnings none ${1+"$@"}
+                      shift
+		      ;;
+
+        --warnings|--warning|-W)
+                      test $# = 0 && func_missing_arg $_G_opt && break
+                      case " $warning_categories $1" in
+                        *" $1 "*)
+                          # trailing space prevents matching last $1 above
+                          func_append_uniq opt_warning_types " $1"
+                          ;;
+                        *all)
+                          opt_warning_types=$warning_categories
+                          ;;
+                        *none)
+                          opt_warning_types=none
+                          warning_func=:
+                          ;;
+                        *error)
+                          opt_warning_types=$warning_categories
+                          warning_func=func_fatal_error
+                          ;;
+                        *)
+                          func_fatal_error \
+                             "unsupported warning category: '$1'"
+                          ;;
+                      esac
+                      shift
+                      ;;
+
+        --verbose|-v) opt_verbose=: ;;
+        --version)    func_version ;;
+        -\?|-h)       func_usage ;;
+        --help)       func_help ;;
+
+	# Separate optargs to long options (plugins may need this):
+	--*=*)        func_split_equals "$_G_opt"
+	              set dummy "$func_split_equals_lhs" \
+                          "$func_split_equals_rhs" ${1+"$@"}
+                      shift
+                      ;;
+
+       # Separate optargs to short options:
+        -W*)
+                      func_split_short_opt "$_G_opt"
+                      set dummy "$func_split_short_opt_name" \
+                          "$func_split_short_opt_arg" ${1+"$@"}
+                      shift
+                      ;;
+
+        # Separate non-argument short options:
+        -\?*|-h*|-v*|-x*)
+                      func_split_short_opt "$_G_opt"
+                      set dummy "$func_split_short_opt_name" \
+                          "-$func_split_short_opt_arg" ${1+"$@"}
+                      shift
+                      ;;
+
+        --)           break ;;
+        -*)           func_fatal_help "unrecognised option: '$_G_opt'" ;;
+        *)            set dummy "$_G_opt" ${1+"$@"}; shift; break ;;
+      esac
+    done
+
+    # save modified positional parameters for caller
+    func_quote_for_eval ${1+"$@"}
+    func_parse_options_result=$func_quote_for_eval_result
+}
+
+
+# func_validate_options [ARG]...
+# ------------------------------
+# Perform any sanity checks on option settings and/or unconsumed
+# arguments.
+func_hookable func_validate_options
+func_validate_options ()
+{
+    $debug_cmd
+
+    # Display all warnings if -W was not given.
+    test -n "$opt_warning_types" || opt_warning_types=" $warning_categories"
+
+    func_run_hooks func_validate_options ${1+"$@"}
+
+    # Bail if the options were screwed!
+    $exit_cmd $EXIT_FAILURE
+
+    # save modified positional parameters for caller
+    func_validate_options_result=$func_run_hooks_result
+}
+
+
+
+## ----------------- ##
+## Helper functions. ##
+## ----------------- ##
+
+# This section contains the helper functions used by the rest of the
+# hookable option parser framework in ascii-betical order.
+
+
+# func_fatal_help ARG...
+# ----------------------
+# Echo program name prefixed message to standard error, followed by
+# a help hint, and exit.
+func_fatal_help ()
+{
+    $debug_cmd
+
+    eval \$ECHO \""Usage: $usage"\"
+    eval \$ECHO \""$fatal_help"\"
+    func_error ${1+"$@"}
+    exit $EXIT_FAILURE
+}
+
+
+# func_help
+# ---------
+# Echo long help message to standard output and exit.
+func_help ()
+{
+    $debug_cmd
+
+    func_usage_message
+    $ECHO "$long_help_message"
+    exit 0
+}
+
+
+# func_missing_arg ARGNAME
+# ------------------------
+# Echo program name prefixed message to standard error and set global
+# exit_cmd.
+func_missing_arg ()
+{
+    $debug_cmd
+
+    func_error "Missing argument for '$1'."
+    exit_cmd=exit
+}
+
+
+# func_split_equals STRING
+# ------------------------
+# Set func_split_equals_lhs and func_split_equals_rhs shell variables after
+# splitting STRING at the '=' sign.
+test -z "$_G_HAVE_XSI_OPS" \
+    && (eval 'x=a/b/c;
+      test 5aa/bb/cc = "${#x}${x%%/*}${x%/*}${x#*/}${x##*/}"') 2>/dev/null \
+    && _G_HAVE_XSI_OPS=yes
+
+if test yes = "$_G_HAVE_XSI_OPS"
+then
+  # This is an XSI compatible shell, allowing a faster implementation...
+  eval 'func_split_equals ()
+  {
+      $debug_cmd
+
+      func_split_equals_lhs=${1%%=*}
+      func_split_equals_rhs=${1#*=}
+      test "x$func_split_equals_lhs" = "x$1" \
+        && func_split_equals_rhs=
+  }'
+else
+  # ...otherwise fall back to using expr, which is often a shell builtin.
+  func_split_equals ()
+  {
+      $debug_cmd
+
+      func_split_equals_lhs=`expr "x$1" : 'x\([^=]*\)'`
+      func_split_equals_rhs=
+      test "x$func_split_equals_lhs" = "x$1" \
+        || func_split_equals_rhs=`expr "x$1" : 'x[^=]*=\(.*\)$'`
+  }
+fi #func_split_equals
+
+
+# func_split_short_opt SHORTOPT
+# -----------------------------
+# Set func_split_short_opt_name and func_split_short_opt_arg shell
+# variables after splitting SHORTOPT after the 2nd character.
+if test yes = "$_G_HAVE_XSI_OPS"
+then
+  # This is an XSI compatible shell, allowing a faster implementation...
+  eval 'func_split_short_opt ()
+  {
+      $debug_cmd
+
+      func_split_short_opt_arg=${1#??}
+      func_split_short_opt_name=${1%"$func_split_short_opt_arg"}
+  }'
+else
+  # ...otherwise fall back to using expr, which is often a shell builtin.
+  func_split_short_opt ()
+  {
+      $debug_cmd
+
+      func_split_short_opt_name=`expr "x$1" : 'x-\(.\)'`
+      func_split_short_opt_arg=`expr "x$1" : 'x-.\(.*\)$'`
+  }
+fi #func_split_short_opt
+
+
+# func_usage
+# ----------
+# Echo short help message to standard output and exit.
+func_usage ()
+{
+    $debug_cmd
+
+    func_usage_message
+    $ECHO "Run '$progname --help |${PAGER-more}' for full usage"
+    exit 0
+}
+
+
+# func_usage_message
+# ------------------
+# Echo short help message to standard output.
+func_usage_message ()
+{
+    $debug_cmd
+
+    eval \$ECHO \""Usage: $usage"\"
+    echo
+    $SED -n 's|^# ||
+        /^Written by/{
+          x;p;x
+        }
+	h
+	/^Written by/q' < "$progpath"
+    echo
+    eval \$ECHO \""$usage_message"\"
+}
+
+
+# func_version
+# ------------
+# Echo version message to standard output and exit.
+func_version ()
+{
+    $debug_cmd
+
+    printf '%s\n' "$progname $scriptversion"
+    $SED -n '
+        /(C)/!b go
+        :more
+        /\./!{
+          N
+          s|\n# | |
+          b more
+        }
+        :go
+        /^# Written by /,/# warranty; / {
+          s|^# ||
+          s|^# *$||
+          s|\((C)\)[ 0-9,-]*[ ,-]\([1-9][0-9]* \)|\1 \2|
+          p
+        }
+        /^# Written by / {
+          s|^# ||
+          p
+        }
+        /^warranty; /q' < "$progpath"
+
+    exit $?
+}
+
+
+# Local variables:
+# mode: shell-script
+# sh-indentation: 2
+# eval: (add-hook 'before-save-hook 'time-stamp)
+# time-stamp-pattern: "10/scriptversion=%:y-%02m-%02d.%02H; # UTC"
+# time-stamp-time-zone: "UTC"
+# End:
+
+# Set a version string.
+scriptversion='(GNU libtool) 2.4.6'
+
+
+# func_echo ARG...
+# ----------------
+# Libtool also displays the current mode in messages, so override
+# funclib.sh func_echo with this custom definition.
+func_echo ()
+{
+    $debug_cmd
+
+    _G_message=$*
+
+    func_echo_IFS=$IFS
+    IFS=$nl
+    for _G_line in $_G_message; do
+      IFS=$func_echo_IFS
+      $ECHO "$progname${opt_mode+: $opt_mode}: $_G_line"
+    done
+    IFS=$func_echo_IFS
+}
+
+
+# func_warning ARG...
+# -------------------
+# Libtool warnings are not categorized, so override funclib.sh
+# func_warning with this simpler definition.
+func_warning ()
+{
+    $debug_cmd
+
+    $warning_func ${1+"$@"}
+}
+
+
+## ---------------- ##
+## Options parsing. ##
+## ---------------- ##
+
+# Hook in the functions to make sure our own options are parsed during
+# the option parsing loop.
+
+usage='$progpath [OPTION]... [MODE-ARG]...'
+
+# Short help message in response to '-h'.
+usage_message="Options:
+       --config             show all configuration variables
+       --debug              enable verbose shell tracing
+   -n, --dry-run            display commands without modifying any files
+       --features           display basic configuration information and exit
+       --mode=MODE          use operation mode MODE
+       --no-warnings        equivalent to '-Wnone'
+       --preserve-dup-deps  don't remove duplicate dependency libraries
+       --quiet, --silent    don't print informational messages
+       --tag=TAG            use configuration variables from tag TAG
+   -v, --verbose            print more informational messages than default
+       --version            print version information
+   -W, --warnings=CATEGORY  report the warnings falling in CATEGORY [all]
+   -h, --help, --help-all   print short, long, or detailed help message
+"
+
+# Additional text appended to 'usage_message' in response to '--help'.
+func_help ()
+{
+    $debug_cmd
+
+    func_usage_message
+    $ECHO "$long_help_message
+
+MODE must be one of the following:
+
+       clean           remove files from the build directory
+       compile         compile a source file into a libtool object
+       execute         automatically set library path, then run a program
+       finish          complete the installation of libtool libraries
+       install         install libraries or executables
+       link            create a library or an executable
+       uninstall       remove libraries from an installed directory
+
+MODE-ARGS vary depending on the MODE.  When passed as first option,
+'--mode=MODE' may be abbreviated as 'MODE' or a unique abbreviation of that.
+Try '$progname --help --mode=MODE' for a more detailed description of MODE.
+
+When reporting a bug, please describe a test case to reproduce it and
+include the following information:
+
+       host-triplet:   $host
+       shell:          $SHELL
+       compiler:       $LTCC
+       compiler flags: $LTCFLAGS
+       linker:         $LD (gnu? $with_gnu_ld)
+       version:        $progname (GNU libtool) 2.4.6
+       automake:       `($AUTOMAKE --version) 2>/dev/null |$SED 1q`
+       autoconf:       `($AUTOCONF --version) 2>/dev/null |$SED 1q`
+
+Report bugs to <bug-libtool@gnu.org>.
+GNU libtool home page: <http://www.gnu.org/s/libtool/>.
+General help using GNU software: <http://www.gnu.org/gethelp/>."
+    exit 0
+}
+
+
+# func_lo2o OBJECT-NAME
+# ---------------------
+# Transform OBJECT-NAME from a '.lo' suffix to the platform specific
+# object suffix.
+
+lo2o=s/\\.lo\$/.$objext/
+o2lo=s/\\.$objext\$/.lo/
+
+if test yes = "$_G_HAVE_XSI_OPS"; then
+  eval 'func_lo2o ()
+  {
+    case $1 in
+      *.lo) func_lo2o_result=${1%.lo}.$objext ;;
+      *   ) func_lo2o_result=$1               ;;
+    esac
+  }'
+
+  # func_xform LIBOBJ-OR-SOURCE
+  # ---------------------------
+  # Transform LIBOBJ-OR-SOURCE from a '.o' or '.c' (or otherwise)
+  # suffix to a '.lo' libtool-object suffix.
+  eval 'func_xform ()
+  {
+    func_xform_result=${1%.*}.lo
+  }'
+else
+  # ...otherwise fall back to using sed.
+  func_lo2o ()
+  {
+    func_lo2o_result=`$ECHO "$1" | $SED "$lo2o"`
+  }
+
+  func_xform ()
+  {
+    func_xform_result=`$ECHO "$1" | $SED 's|\.[^.]*$|.lo|'`
+  }
+fi
+
+
+# func_fatal_configuration ARG...
+# -------------------------------
+# Echo program name prefixed message to standard error, followed by
+# a configuration failure hint, and exit.
+func_fatal_configuration ()
+{
+    func__fatal_error ${1+"$@"} \
+      "See the $PACKAGE documentation for more information." \
+      "Fatal configuration error."
+}
+
+
+# func_config
+# -----------
+# Display the configuration for all the tags in this script.
+func_config ()
+{
+    re_begincf='^# ### BEGIN LIBTOOL'
+    re_endcf='^# ### END LIBTOOL'
+
+    # Default configuration.
+    $SED "1,/$re_begincf CONFIG/d;/$re_endcf CONFIG/,\$d" < "$progpath"
+
+    # Now print the configurations for the tags.
+    for tagname in $taglist; do
+      $SED -n "/$re_begincf TAG CONFIG: $tagname\$/,/$re_endcf TAG CONFIG: $tagname\$/p" < "$progpath"
+    done
+
+    exit $?
+}
+
+
+# func_features
+# -------------
+# Display the features supported by this script.
+func_features ()
+{
+    echo "host: $host"
+    if test yes = "$build_libtool_libs"; then
+      echo "enable shared libraries"
+    else
+      echo "disable shared libraries"
+    fi
+    if test yes = "$build_old_libs"; then
+      echo "enable static libraries"
+    else
+      echo "disable static libraries"
+    fi
+
+    exit $?
+}
+
+
+# func_enable_tag TAGNAME
+# -----------------------
+# Verify that TAGNAME is valid, and either flag an error and exit, or
+# enable the TAGNAME tag.  We also add TAGNAME to the global $taglist
+# variable here.
+func_enable_tag ()
+{
+    # Global variable:
+    tagname=$1
+
+    re_begincf="^# ### BEGIN LIBTOOL TAG CONFIG: $tagname\$"
+    re_endcf="^# ### END LIBTOOL TAG CONFIG: $tagname\$"
+    sed_extractcf=/$re_begincf/,/$re_endcf/p
+
+    # Validate tagname.
+    case $tagname in
+      *[!-_A-Za-z0-9,/]*)
+        func_fatal_error "invalid tag name: $tagname"
+        ;;
+    esac
+
+    # Don't test for the "default" C tag, as we know it's
+    # there but not specially marked.
+    case $tagname in
+        CC) ;;
+    *)
+        if $GREP "$re_begincf" "$progpath" >/dev/null 2>&1; then
+	  taglist="$taglist $tagname"
+
+	  # Evaluate the configuration.  Be careful to quote the path
+	  # and the sed script, to avoid splitting on whitespace, but
+	  # also don't use non-portable quotes within backquotes within
+	  # quotes we have to do it in 2 steps:
+	  extractedcf=`$SED -n -e "$sed_extractcf" < "$progpath"`
+	  eval "$extractedcf"
+        else
+	  func_error "ignoring unknown tag $tagname"
+        fi
+        ;;
+    esac
+}
+
+
+# func_check_version_match
+# ------------------------
+# Ensure that we are using m4 macros, and libtool script from the same
+# release of libtool.
+func_check_version_match ()
+{
+    if test "$package_revision" != "$macro_revision"; then
+      if test "$VERSION" != "$macro_version"; then
+        if test -z "$macro_version"; then
+          cat >&2 <<_LT_EOF
+$progname: Version mismatch error.  This is $PACKAGE $VERSION, but the
+$progname: definition of this LT_INIT comes from an older release.
+$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION
+$progname: and run autoconf again.
+_LT_EOF
+        else
+          cat >&2 <<_LT_EOF
+$progname: Version mismatch error.  This is $PACKAGE $VERSION, but the
+$progname: definition of this LT_INIT comes from $PACKAGE $macro_version.
+$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION
+$progname: and run autoconf again.
+_LT_EOF
+        fi
+      else
+        cat >&2 <<_LT_EOF
+$progname: Version mismatch error.  This is $PACKAGE $VERSION, revision $package_revision,
+$progname: but the definition of this LT_INIT comes from revision $macro_revision.
+$progname: You should recreate aclocal.m4 with macros from revision $package_revision
+$progname: of $PACKAGE $VERSION and run autoconf again.
+_LT_EOF
+      fi
+
+      exit $EXIT_MISMATCH
+    fi
+}
+
+
+# libtool_options_prep [ARG]...
+# -----------------------------
+# Preparation for options parsed by libtool.
+libtool_options_prep ()
+{
+    $debug_mode
+
+    # Option defaults:
+    opt_config=false
+    opt_dlopen=
+    opt_dry_run=false
+    opt_help=false
+    opt_mode=
+    opt_preserve_dup_deps=false
+    opt_quiet=false
+
+    nonopt=
+    preserve_args=
+
+    # Shorthand for --mode=foo, only valid as the first argument
+    case $1 in
+    clean|clea|cle|cl)
+      shift; set dummy --mode clean ${1+"$@"}; shift
+      ;;
+    compile|compil|compi|comp|com|co|c)
+      shift; set dummy --mode compile ${1+"$@"}; shift
+      ;;
+    execute|execut|execu|exec|exe|ex|e)
+      shift; set dummy --mode execute ${1+"$@"}; shift
+      ;;
+    finish|finis|fini|fin|fi|f)
+      shift; set dummy --mode finish ${1+"$@"}; shift
+      ;;
+    install|instal|insta|inst|ins|in|i)
+      shift; set dummy --mode install ${1+"$@"}; shift
+      ;;
+    link|lin|li|l)
+      shift; set dummy --mode link ${1+"$@"}; shift
+      ;;
+    uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u)
+      shift; set dummy --mode uninstall ${1+"$@"}; shift
+      ;;
+    esac
+
+    # Pass back the list of options.
+    func_quote_for_eval ${1+"$@"}
+    libtool_options_prep_result=$func_quote_for_eval_result
+}
+func_add_hook func_options_prep libtool_options_prep
+
+
+# libtool_parse_options [ARG]...
+# ---------------------------------
+# Provide handling for libtool specific options.
+libtool_parse_options ()
+{
+    $debug_cmd
+
+    # Perform our own loop to consume as many options as possible in
+    # each iteration.
+    while test $# -gt 0; do
+      _G_opt=$1
+      shift
+      case $_G_opt in
+        --dry-run|--dryrun|-n)
+                        opt_dry_run=:
+                        ;;
+
+        --config)       func_config ;;
+
+        --dlopen|-dlopen)
+                        opt_dlopen="${opt_dlopen+$opt_dlopen
+}$1"
+                        shift
+                        ;;
+
+        --preserve-dup-deps)
+                        opt_preserve_dup_deps=: ;;
+
+        --features)     func_features ;;
+
+        --finish)       set dummy --mode finish ${1+"$@"}; shift ;;
+
+        --help)         opt_help=: ;;
+
+        --help-all)     opt_help=': help-all' ;;
+
+        --mode)         test $# = 0 && func_missing_arg $_G_opt && break
+                        opt_mode=$1
+                        case $1 in
+                          # Valid mode arguments:
+                          clean|compile|execute|finish|install|link|relink|uninstall) ;;
+
+                          # Catch anything else as an error
+                          *) func_error "invalid argument for $_G_opt"
+                             exit_cmd=exit
+                             break
+                             ;;
+                        esac
+                        shift
+                        ;;
+
+        --no-silent|--no-quiet)
+                        opt_quiet=false
+                        func_append preserve_args " $_G_opt"
+                        ;;
+
+        --no-warnings|--no-warning|--no-warn)
+                        opt_warning=false
+                        func_append preserve_args " $_G_opt"
+                        ;;
+
+        --no-verbose)
+                        opt_verbose=false
+                        func_append preserve_args " $_G_opt"
+                        ;;
+
+        --silent|--quiet)
+                        opt_quiet=:
+                        opt_verbose=false
+                        func_append preserve_args " $_G_opt"
+                        ;;
+
+        --tag)          test $# = 0 && func_missing_arg $_G_opt && break
+                        opt_tag=$1
+                        func_append preserve_args " $_G_opt $1"
+                        func_enable_tag "$1"
+                        shift
+                        ;;
+
+        --verbose|-v)   opt_quiet=false
+                        opt_verbose=:
+                        func_append preserve_args " $_G_opt"
+                        ;;
+
+	# An option not handled by this hook function:
+        *)		set dummy "$_G_opt" ${1+"$@"};	shift; break  ;;
+      esac
+    done
+
+
+    # save modified positional parameters for caller
+    func_quote_for_eval ${1+"$@"}
+    libtool_parse_options_result=$func_quote_for_eval_result
+}
+func_add_hook func_parse_options libtool_parse_options
+
+
+
+# libtool_validate_options [ARG]...
+# ---------------------------------
+# Perform any sanity checks on option settings and/or unconsumed
+# arguments.
+libtool_validate_options ()
+{
+    # save first non-option argument
+    if test 0 -lt $#; then
+      nonopt=$1
+      shift
+    fi
+
+    # preserve --debug
+    test : = "$debug_cmd" || func_append preserve_args " --debug"
+
+    case $host in
+      # Solaris2 added to fix http://debbugs.gnu.org/cgi/bugreport.cgi?bug=16452
+      # see also: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59788
+      *cygwin* | *mingw* | *pw32* | *cegcc* | *solaris2* | *os2*)
+        # don't eliminate duplications in $postdeps and $predeps
+        opt_duplicate_compiler_generated_deps=:
+        ;;
+      *)
+        opt_duplicate_compiler_generated_deps=$opt_preserve_dup_deps
+        ;;
+    esac
+
+    $opt_help || {
+      # Sanity checks first:
+      func_check_version_match
+
+      test yes != "$build_libtool_libs" \
+        && test yes != "$build_old_libs" \
+        && func_fatal_configuration "not configured to build any kind of library"
+
+      # Darwin sucks
+      eval std_shrext=\"$shrext_cmds\"
+
+      # Only execute mode is allowed to have -dlopen flags.
+      if test -n "$opt_dlopen" && test execute != "$opt_mode"; then
+        func_error "unrecognized option '-dlopen'"
+        $ECHO "$help" 1>&2
+        exit $EXIT_FAILURE
+      fi
+
+      # Change the help message to a mode-specific one.
+      generic_help=$help
+      help="Try '$progname --help --mode=$opt_mode' for more information."
+    }
+
+    # Pass back the unparsed argument list
+    func_quote_for_eval ${1+"$@"}
+    libtool_validate_options_result=$func_quote_for_eval_result
+}
+func_add_hook func_validate_options libtool_validate_options
+
+
+# Process options as early as possible so that --help and --version
+# can return quickly.
+func_options ${1+"$@"}
+eval set dummy "$func_options_result"; shift
+
+
+
+## ----------- ##
+##    Main.    ##
+## ----------- ##
+
+magic='%%%MAGIC variable%%%'
+magic_exe='%%%MAGIC EXE variable%%%'
+
+# Global variables.
+extracted_archives=
+extracted_serial=0
+
+# If this variable is set in any of the actions, the command in it
+# will be execed at the end.  This prevents here-documents from being
+# left over by shells.
+exec_cmd=
+
+
+# A function that is used when there is no print builtin or printf.
+func_fallback_echo ()
+{
+  eval 'cat <<_LTECHO_EOF
+$1
+_LTECHO_EOF'
+}
+
+# func_generated_by_libtool
+# True iff stdin has been generated by Libtool. This function is only
+# a basic sanity check; it will hardly flush out determined imposters.
+func_generated_by_libtool_p ()
+{
+  $GREP "^# Generated by .*$PACKAGE" > /dev/null 2>&1
+}
+
+# func_lalib_p file
+# True iff FILE is a libtool '.la' library or '.lo' object file.
+# This function is only a basic sanity check; it will hardly flush out
+# determined imposters.
+func_lalib_p ()
+{
+    test -f "$1" &&
+      $SED -e 4q "$1" 2>/dev/null | func_generated_by_libtool_p
+}
+
+# func_lalib_unsafe_p file
+# True iff FILE is a libtool '.la' library or '.lo' object file.
+# This function implements the same check as func_lalib_p without
+# resorting to external programs.  To this end, it redirects stdin and
+# closes it afterwards, without saving the original file descriptor.
+# As a safety measure, use it only where a negative result would be
+# fatal anyway.  Works if 'file' does not exist.
+func_lalib_unsafe_p ()
+{
+    lalib_p=no
+    if test -f "$1" && test -r "$1" && exec 5<&0 <"$1"; then
+	for lalib_p_l in 1 2 3 4
+	do
+	    read lalib_p_line
+	    case $lalib_p_line in
+		\#\ Generated\ by\ *$PACKAGE* ) lalib_p=yes; break;;
+	    esac
+	done
+	exec 0<&5 5<&-
+    fi
+    test yes = "$lalib_p"
+}
+
+# func_ltwrapper_script_p file
+# True iff FILE is a libtool wrapper script
+# This function is only a basic sanity check; it will hardly flush out
+# determined imposters.
+func_ltwrapper_script_p ()
+{
+    test -f "$1" &&
+      $lt_truncate_bin < "$1" 2>/dev/null | func_generated_by_libtool_p
+}
+
+# func_ltwrapper_executable_p file
+# True iff FILE is a libtool wrapper executable
+# This function is only a basic sanity check; it will hardly flush out
+# determined imposters.
+func_ltwrapper_executable_p ()
+{
+    func_ltwrapper_exec_suffix=
+    case $1 in
+    *.exe) ;;
+    *) func_ltwrapper_exec_suffix=.exe ;;
+    esac
+    $GREP "$magic_exe" "$1$func_ltwrapper_exec_suffix" >/dev/null 2>&1
+}
+
+# func_ltwrapper_scriptname file
+# Assumes file is an ltwrapper_executable
+# uses $file to determine the appropriate filename for a
+# temporary ltwrapper_script.
+func_ltwrapper_scriptname ()
+{
+    func_dirname_and_basename "$1" "" "."
+    func_stripname '' '.exe' "$func_basename_result"
+    func_ltwrapper_scriptname_result=$func_dirname_result/$objdir/${func_stripname_result}_ltshwrapper
+}
+
+# func_ltwrapper_p file
+# True iff FILE is a libtool wrapper script or wrapper executable
+# This function is only a basic sanity check; it will hardly flush out
+# determined imposters.
+func_ltwrapper_p ()
+{
+    func_ltwrapper_script_p "$1" || func_ltwrapper_executable_p "$1"
+}
+
+
+# func_execute_cmds commands fail_cmd
+# Execute tilde-delimited COMMANDS.
+# If FAIL_CMD is given, eval that upon failure.
+# FAIL_CMD may read-access the current command in variable CMD!
+func_execute_cmds ()
+{
+    $debug_cmd
+
+    save_ifs=$IFS; IFS='~'
+    for cmd in $1; do
+      IFS=$sp$nl
+      eval cmd=\"$cmd\"
+      IFS=$save_ifs
+      func_show_eval "$cmd" "${2-:}"
+    done
+    IFS=$save_ifs
+}
+
+
+# func_source file
+# Source FILE, adding directory component if necessary.
+# Note that it is not necessary on cygwin/mingw to append a dot to
+# FILE even if both FILE and FILE.exe exist: automatic-append-.exe
+# behavior happens only for exec(3), not for open(2)!  Also, sourcing
+# 'FILE.' does not work on cygwin managed mounts.
+func_source ()
+{
+    $debug_cmd
+
+    case $1 in
+    */* | *\\*)	. "$1" ;;
+    *)		. "./$1" ;;
+    esac
+}
+
+
+# func_resolve_sysroot PATH
+# Replace a leading = in PATH with a sysroot.  Store the result into
+# func_resolve_sysroot_result
+func_resolve_sysroot ()
+{
+  func_resolve_sysroot_result=$1
+  case $func_resolve_sysroot_result in
+  =*)
+    func_stripname '=' '' "$func_resolve_sysroot_result"
+    func_resolve_sysroot_result=$lt_sysroot$func_stripname_result
+    ;;
+  esac
+}
+
+# func_replace_sysroot PATH
+# If PATH begins with the sysroot, replace it with = and
+# store the result into func_replace_sysroot_result.
+func_replace_sysroot ()
+{
+  case $lt_sysroot:$1 in
+  ?*:"$lt_sysroot"*)
+    func_stripname "$lt_sysroot" '' "$1"
+    func_replace_sysroot_result='='$func_stripname_result
+    ;;
+  *)
+    # Including no sysroot.
+    func_replace_sysroot_result=$1
+    ;;
+  esac
+}
+
+# func_infer_tag arg
+# Infer tagged configuration to use if any are available and
+# if one wasn't chosen via the "--tag" command line option.
+# Only attempt this if the compiler in the base compile
+# command doesn't match the default compiler.
+# arg is usually of the form 'gcc ...'
+func_infer_tag ()
+{
+    $debug_cmd
+
+    if test -n "$available_tags" && test -z "$tagname"; then
+      CC_quoted=
+      for arg in $CC; do
+	func_append_quoted CC_quoted "$arg"
+      done
+      CC_expanded=`func_echo_all $CC`
+      CC_quoted_expanded=`func_echo_all $CC_quoted`
+      case $@ in
+      # Blanks in the command may have been stripped by the calling shell,
+      # but not from the CC environment variable when configure was run.
+      " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \
+      " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) ;;
+      # Blanks at the start of $base_compile will cause this to fail
+      # if we don't check for them as well.
+      *)
+	for z in $available_tags; do
+	  if $GREP "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then
+	    # Evaluate the configuration.
+	    eval "`$SED -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`"
+	    CC_quoted=
+	    for arg in $CC; do
+	      # Double-quote args containing other shell metacharacters.
+	      func_append_quoted CC_quoted "$arg"
+	    done
+	    CC_expanded=`func_echo_all $CC`
+	    CC_quoted_expanded=`func_echo_all $CC_quoted`
+	    case "$@ " in
+	    " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \
+	    " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*)
+	      # The compiler in the base compile command matches
+	      # the one in the tagged configuration.
+	      # Assume this is the tagged configuration we want.
+	      tagname=$z
+	      break
+	      ;;
+	    esac
+	  fi
+	done
+	# If $tagname still isn't set, then no tagged configuration
+	# was found and let the user know that the "--tag" command
+	# line option must be used.
+	if test -z "$tagname"; then
+	  func_echo "unable to infer tagged configuration"
+	  func_fatal_error "specify a tag with '--tag'"
+#	else
+#	  func_verbose "using $tagname tagged configuration"
+	fi
+	;;
+      esac
+    fi
+}
+
+
+
+# func_write_libtool_object output_name pic_name nonpic_name
+# Create a libtool object file (analogous to a ".la" file),
+# but don't create it if we're doing a dry run.
+func_write_libtool_object ()
+{
+    write_libobj=$1
+    if test yes = "$build_libtool_libs"; then
+      write_lobj=\'$2\'
+    else
+      write_lobj=none
+    fi
+
+    if test yes = "$build_old_libs"; then
+      write_oldobj=\'$3\'
+    else
+      write_oldobj=none
+    fi
+
+    $opt_dry_run || {
+      cat >${write_libobj}T <<EOF
+# $write_libobj - a libtool object file
+# Generated by $PROGRAM (GNU $PACKAGE) $VERSION
+#
+# Please DO NOT delete this file!
+# It is necessary for linking the library.
+
+# Name of the PIC object.
+pic_object=$write_lobj
+
+# Name of the non-PIC object
+non_pic_object=$write_oldobj
+
+EOF
+      $MV "${write_libobj}T" "$write_libobj"
+    }
+}
+
+
+##################################################
+# FILE NAME AND PATH CONVERSION HELPER FUNCTIONS #
+##################################################
+
+# func_convert_core_file_wine_to_w32 ARG
+# Helper function used by file name conversion functions when $build is *nix,
+# and $host is mingw, cygwin, or some other w32 environment. Relies on a
+# correctly configured wine environment available, with the winepath program
+# in $build's $PATH.
+#
+# ARG is the $build file name to be converted to w32 format.
+# Result is available in $func_convert_core_file_wine_to_w32_result, and will
+# be empty on error (or when ARG is empty)
+func_convert_core_file_wine_to_w32 ()
+{
+  $debug_cmd
+
+  func_convert_core_file_wine_to_w32_result=$1
+  if test -n "$1"; then
+    # Unfortunately, winepath does not exit with a non-zero error code, so we
+    # are forced to check the contents of stdout. On the other hand, if the
+    # command is not found, the shell will set an exit code of 127 and print
+    # *an error message* to stdout. So we must check for both error code of
+    # zero AND non-empty stdout, which explains the odd construction:
+    func_convert_core_file_wine_to_w32_tmp=`winepath -w "$1" 2>/dev/null`
+    if test "$?" -eq 0 && test -n "$func_convert_core_file_wine_to_w32_tmp"; then
+      func_convert_core_file_wine_to_w32_result=`$ECHO "$func_convert_core_file_wine_to_w32_tmp" |
+        $SED -e "$sed_naive_backslashify"`
+    else
+      func_convert_core_file_wine_to_w32_result=
+    fi
+  fi
+}
+# end: func_convert_core_file_wine_to_w32
+
+
+# func_convert_core_path_wine_to_w32 ARG
+# Helper function used by path conversion functions when $build is *nix, and
+# $host is mingw, cygwin, or some other w32 environment. Relies on a correctly
+# configured wine environment available, with the winepath program in $build's
+# $PATH. Assumes ARG has no leading or trailing path separator characters.
+#
+# ARG is path to be converted from $build format to win32.
+# Result is available in $func_convert_core_path_wine_to_w32_result.
+# Unconvertible file (directory) names in ARG are skipped; if no directory names
+# are convertible, then the result may be empty.
+func_convert_core_path_wine_to_w32 ()
+{
+  $debug_cmd
+
+  # unfortunately, winepath doesn't convert paths, only file names
+  func_convert_core_path_wine_to_w32_result=
+  if test -n "$1"; then
+    oldIFS=$IFS
+    IFS=:
+    for func_convert_core_path_wine_to_w32_f in $1; do
+      IFS=$oldIFS
+      func_convert_core_file_wine_to_w32 "$func_convert_core_path_wine_to_w32_f"
+      if test -n "$func_convert_core_file_wine_to_w32_result"; then
+        if test -z "$func_convert_core_path_wine_to_w32_result"; then
+          func_convert_core_path_wine_to_w32_result=$func_convert_core_file_wine_to_w32_result
+        else
+          func_append func_convert_core_path_wine_to_w32_result ";$func_convert_core_file_wine_to_w32_result"
+        fi
+      fi
+    done
+    IFS=$oldIFS
+  fi
+}
+# end: func_convert_core_path_wine_to_w32
+
+
+# func_cygpath ARGS...
+# Wrapper around calling the cygpath program via LT_CYGPATH. This is used when
+# when (1) $build is *nix and Cygwin is hosted via a wine environment; or (2)
+# $build is MSYS and $host is Cygwin, or (3) $build is Cygwin. In case (1) or
+# (2), returns the Cygwin file name or path in func_cygpath_result (input
+# file name or path is assumed to be in w32 format, as previously converted
+# from $build's *nix or MSYS format). In case (3), returns the w32 file name
+# or path in func_cygpath_result (input file name or path is assumed to be in
+# Cygwin format). Returns an empty string on error.
+#
+# ARGS are passed to cygpath, with the last one being the file name or path to
+# be converted.
+#
+# Specify the absolute *nix (or w32) name to cygpath in the LT_CYGPATH
+# environment variable; do not put it in $PATH.
+func_cygpath ()
+{
+  $debug_cmd
+
+  if test -n "$LT_CYGPATH" && test -f "$LT_CYGPATH"; then
+    func_cygpath_result=`$LT_CYGPATH "$@" 2>/dev/null`
+    if test "$?" -ne 0; then
+      # on failure, ensure result is empty
+      func_cygpath_result=
+    fi
+  else
+    func_cygpath_result=
+    func_error "LT_CYGPATH is empty or specifies non-existent file: '$LT_CYGPATH'"
+  fi
+}
+#end: func_cygpath
+
+
+# func_convert_core_msys_to_w32 ARG
+# Convert file name or path ARG from MSYS format to w32 format.  Return
+# result in func_convert_core_msys_to_w32_result.
+func_convert_core_msys_to_w32 ()
+{
+  $debug_cmd
+
+  # awkward: cmd appends spaces to result
+  func_convert_core_msys_to_w32_result=`( cmd //c echo "$1" ) 2>/dev/null |
+    $SED -e 's/[ ]*$//' -e "$sed_naive_backslashify"`
+}
+#end: func_convert_core_msys_to_w32
+
+
+# func_convert_file_check ARG1 ARG2
+# Verify that ARG1 (a file name in $build format) was converted to $host
+# format in ARG2. Otherwise, emit an error message, but continue (resetting
+# func_to_host_file_result to ARG1).
+func_convert_file_check ()
+{
+  $debug_cmd
+
+  if test -z "$2" && test -n "$1"; then
+    func_error "Could not determine host file name corresponding to"
+    func_error "  '$1'"
+    func_error "Continuing, but uninstalled executables may not work."
+    # Fallback:
+    func_to_host_file_result=$1
+  fi
+}
+# end func_convert_file_check
+
+
+# func_convert_path_check FROM_PATHSEP TO_PATHSEP FROM_PATH TO_PATH
+# Verify that FROM_PATH (a path in $build format) was converted to $host
+# format in TO_PATH. Otherwise, emit an error message, but continue, resetting
+# func_to_host_file_result to a simplistic fallback value (see below).
+func_convert_path_check ()
+{
+  $debug_cmd
+
+  if test -z "$4" && test -n "$3"; then
+    func_error "Could not determine the host path corresponding to"
+    func_error "  '$3'"
+    func_error "Continuing, but uninstalled executables may not work."
+    # Fallback.  This is a deliberately simplistic "conversion" and
+    # should not be "improved".  See libtool.info.
+    if test "x$1" != "x$2"; then
+      lt_replace_pathsep_chars="s|$1|$2|g"
+      func_to_host_path_result=`echo "$3" |
+        $SED -e "$lt_replace_pathsep_chars"`
+    else
+      func_to_host_path_result=$3
+    fi
+  fi
+}
+# end func_convert_path_check
+
+
+# func_convert_path_front_back_pathsep FRONTPAT BACKPAT REPL ORIG
+# Modifies func_to_host_path_result by prepending REPL if ORIG matches FRONTPAT
+# and appending REPL if ORIG matches BACKPAT.
+func_convert_path_front_back_pathsep ()
+{
+  $debug_cmd
+
+  case $4 in
+  $1 ) func_to_host_path_result=$3$func_to_host_path_result
+    ;;
+  esac
+  case $4 in
+  $2 ) func_append func_to_host_path_result "$3"
+    ;;
+  esac
+}
+# end func_convert_path_front_back_pathsep
+
+
+##################################################
+# $build to $host FILE NAME CONVERSION FUNCTIONS #
+##################################################
+# invoked via '$to_host_file_cmd ARG'
+#
+# In each case, ARG is the path to be converted from $build to $host format.
+# Result will be available in $func_to_host_file_result.
+
+
+# func_to_host_file ARG
+# Converts the file name ARG from $build format to $host format. Return result
+# in func_to_host_file_result.
+func_to_host_file ()
+{
+  $debug_cmd
+
+  $to_host_file_cmd "$1"
+}
+# end func_to_host_file
+
+
+# func_to_tool_file ARG LAZY
+# converts the file name ARG from $build format to toolchain format. Return
+# result in func_to_tool_file_result.  If the conversion in use is listed
+# in (the comma separated) LAZY, no conversion takes place.
+func_to_tool_file ()
+{
+  $debug_cmd
+
+  case ,$2, in
+    *,"$to_tool_file_cmd",*)
+      func_to_tool_file_result=$1
+      ;;
+    *)
+      $to_tool_file_cmd "$1"
+      func_to_tool_file_result=$func_to_host_file_result
+      ;;
+  esac
+}
+# end func_to_tool_file
+
+
+# func_convert_file_noop ARG
+# Copy ARG to func_to_host_file_result.
+func_convert_file_noop ()
+{
+  func_to_host_file_result=$1
+}
+# end func_convert_file_noop
+
+
+# func_convert_file_msys_to_w32 ARG
+# Convert file name ARG from (mingw) MSYS to (mingw) w32 format; automatic
+# conversion to w32 is not available inside the cwrapper.  Returns result in
+# func_to_host_file_result.
+func_convert_file_msys_to_w32 ()
+{
+  $debug_cmd
+
+  func_to_host_file_result=$1
+  if test -n "$1"; then
+    func_convert_core_msys_to_w32 "$1"
+    func_to_host_file_result=$func_convert_core_msys_to_w32_result
+  fi
+  func_convert_file_check "$1" "$func_to_host_file_result"
+}
+# end func_convert_file_msys_to_w32
+
+
+# func_convert_file_cygwin_to_w32 ARG
+# Convert file name ARG from Cygwin to w32 format.  Returns result in
+# func_to_host_file_result.
+func_convert_file_cygwin_to_w32 ()
+{
+  $debug_cmd
+
+  func_to_host_file_result=$1
+  if test -n "$1"; then
+    # because $build is cygwin, we call "the" cygpath in $PATH; no need to use
+    # LT_CYGPATH in this case.
+    func_to_host_file_result=`cygpath -m "$1"`
+  fi
+  func_convert_file_check "$1" "$func_to_host_file_result"
+}
+# end func_convert_file_cygwin_to_w32
+
+
+# func_convert_file_nix_to_w32 ARG
+# Convert file name ARG from *nix to w32 format.  Requires a wine environment
+# and a working winepath. Returns result in func_to_host_file_result.
+func_convert_file_nix_to_w32 ()
+{
+  $debug_cmd
+
+  func_to_host_file_result=$1
+  if test -n "$1"; then
+    func_convert_core_file_wine_to_w32 "$1"
+    func_to_host_file_result=$func_convert_core_file_wine_to_w32_result
+  fi
+  func_convert_file_check "$1" "$func_to_host_file_result"
+}
+# end func_convert_file_nix_to_w32
+
+
+# func_convert_file_msys_to_cygwin ARG
+# Convert file name ARG from MSYS to Cygwin format.  Requires LT_CYGPATH set.
+# Returns result in func_to_host_file_result.
+func_convert_file_msys_to_cygwin ()
+{
+  $debug_cmd
+
+  func_to_host_file_result=$1
+  if test -n "$1"; then
+    func_convert_core_msys_to_w32 "$1"
+    func_cygpath -u "$func_convert_core_msys_to_w32_result"
+    func_to_host_file_result=$func_cygpath_result
+  fi
+  func_convert_file_check "$1" "$func_to_host_file_result"
+}
+# end func_convert_file_msys_to_cygwin
+
+
+# func_convert_file_nix_to_cygwin ARG
+# Convert file name ARG from *nix to Cygwin format.  Requires Cygwin installed
+# in a wine environment, working winepath, and LT_CYGPATH set.  Returns result
+# in func_to_host_file_result.
+func_convert_file_nix_to_cygwin ()
+{
+  $debug_cmd
+
+  func_to_host_file_result=$1
+  if test -n "$1"; then
+    # convert from *nix to w32, then use cygpath to convert from w32 to cygwin.
+    func_convert_core_file_wine_to_w32 "$1"
+    func_cygpath -u "$func_convert_core_file_wine_to_w32_result"
+    func_to_host_file_result=$func_cygpath_result
+  fi
+  func_convert_file_check "$1" "$func_to_host_file_result"
+}
+# end func_convert_file_nix_to_cygwin
+
+
+#############################################
+# $build to $host PATH CONVERSION FUNCTIONS #
+#############################################
+# invoked via '$to_host_path_cmd ARG'
+#
+# In each case, ARG is the path to be converted from $build to $host format.
+# The result will be available in $func_to_host_path_result.
+#
+# Path separators are also converted from $build format to $host format.  If
+# ARG begins or ends with a path separator character, it is preserved (but
+# converted to $host format) on output.
+#
+# All path conversion functions are named using the following convention:
+#   file name conversion function    : func_convert_file_X_to_Y ()
+#   path conversion function         : func_convert_path_X_to_Y ()
+# where, for any given $build/$host combination the 'X_to_Y' value is the
+# same.  If conversion functions are added for new $build/$host combinations,
+# the two new functions must follow this pattern, or func_init_to_host_path_cmd
+# will break.
+
+
+# func_init_to_host_path_cmd
+# Ensures that function "pointer" variable $to_host_path_cmd is set to the
+# appropriate value, based on the value of $to_host_file_cmd.
+to_host_path_cmd=
+func_init_to_host_path_cmd ()
+{
+  $debug_cmd
+
+  if test -z "$to_host_path_cmd"; then
+    func_stripname 'func_convert_file_' '' "$to_host_file_cmd"
+    to_host_path_cmd=func_convert_path_$func_stripname_result
+  fi
+}
+
+
+# func_to_host_path ARG
+# Converts the path ARG from $build format to $host format. Return result
+# in func_to_host_path_result.
+func_to_host_path ()
+{
+  $debug_cmd
+
+  func_init_to_host_path_cmd
+  $to_host_path_cmd "$1"
+}
+# end func_to_host_path
+
+
+# func_convert_path_noop ARG
+# Copy ARG to func_to_host_path_result.
+func_convert_path_noop ()
+{
+  func_to_host_path_result=$1
+}
+# end func_convert_path_noop
+
+
+# func_convert_path_msys_to_w32 ARG
+# Convert path ARG from (mingw) MSYS to (mingw) w32 format; automatic
+# conversion to w32 is not available inside the cwrapper.  Returns result in
+# func_to_host_path_result.
+func_convert_path_msys_to_w32 ()
+{
+  $debug_cmd
+
+  func_to_host_path_result=$1
+  if test -n "$1"; then
+    # Remove leading and trailing path separator characters from ARG.  MSYS
+    # behavior is inconsistent here; cygpath turns them into '.;' and ';.';
+    # and winepath ignores them completely.
+    func_stripname : : "$1"
+    func_to_host_path_tmp1=$func_stripname_result
+    func_convert_core_msys_to_w32 "$func_to_host_path_tmp1"
+    func_to_host_path_result=$func_convert_core_msys_to_w32_result
+    func_convert_path_check : ";" \
+      "$func_to_host_path_tmp1" "$func_to_host_path_result"
+    func_convert_path_front_back_pathsep ":*" "*:" ";" "$1"
+  fi
+}
+# end func_convert_path_msys_to_w32
+
+
+# func_convert_path_cygwin_to_w32 ARG
+# Convert path ARG from Cygwin to w32 format.  Returns result in
+# func_to_host_file_result.
+func_convert_path_cygwin_to_w32 ()
+{
+  $debug_cmd
+
+  func_to_host_path_result=$1
+  if test -n "$1"; then
+    # See func_convert_path_msys_to_w32:
+    func_stripname : : "$1"
+    func_to_host_path_tmp1=$func_stripname_result
+    func_to_host_path_result=`cygpath -m -p "$func_to_host_path_tmp1"`
+    func_convert_path_check : ";" \
+      "$func_to_host_path_tmp1" "$func_to_host_path_result"
+    func_convert_path_front_back_pathsep ":*" "*:" ";" "$1"
+  fi
+}
+# end func_convert_path_cygwin_to_w32
+
+
+# func_convert_path_nix_to_w32 ARG
+# Convert path ARG from *nix to w32 format.  Requires a wine environment and
+# a working winepath.  Returns result in func_to_host_file_result.
+func_convert_path_nix_to_w32 ()
+{
+  $debug_cmd
+
+  func_to_host_path_result=$1
+  if test -n "$1"; then
+    # See func_convert_path_msys_to_w32:
+    func_stripname : : "$1"
+    func_to_host_path_tmp1=$func_stripname_result
+    func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1"
+    func_to_host_path_result=$func_convert_core_path_wine_to_w32_result
+    func_convert_path_check : ";" \
+      "$func_to_host_path_tmp1" "$func_to_host_path_result"
+    func_convert_path_front_back_pathsep ":*" "*:" ";" "$1"
+  fi
+}
+# end func_convert_path_nix_to_w32
+
+
+# func_convert_path_msys_to_cygwin ARG
+# Convert path ARG from MSYS to Cygwin format.  Requires LT_CYGPATH set.
+# Returns result in func_to_host_file_result.
+func_convert_path_msys_to_cygwin ()
+{
+  $debug_cmd
+
+  func_to_host_path_result=$1
+  if test -n "$1"; then
+    # See func_convert_path_msys_to_w32:
+    func_stripname : : "$1"
+    func_to_host_path_tmp1=$func_stripname_result
+    func_convert_core_msys_to_w32 "$func_to_host_path_tmp1"
+    func_cygpath -u -p "$func_convert_core_msys_to_w32_result"
+    func_to_host_path_result=$func_cygpath_result
+    func_convert_path_check : : \
+      "$func_to_host_path_tmp1" "$func_to_host_path_result"
+    func_convert_path_front_back_pathsep ":*" "*:" : "$1"
+  fi
+}
+# end func_convert_path_msys_to_cygwin
+
+
+# func_convert_path_nix_to_cygwin ARG
+# Convert path ARG from *nix to Cygwin format.  Requires Cygwin installed in a
+# a wine environment, working winepath, and LT_CYGPATH set.  Returns result in
+# func_to_host_file_result.
+func_convert_path_nix_to_cygwin ()
+{
+  $debug_cmd
+
+  func_to_host_path_result=$1
+  if test -n "$1"; then
+    # Remove leading and trailing path separator characters from
+    # ARG. msys behavior is inconsistent here, cygpath turns them
+    # into '.;' and ';.', and winepath ignores them completely.
+    func_stripname : : "$1"
+    func_to_host_path_tmp1=$func_stripname_result
+    func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1"
+    func_cygpath -u -p "$func_convert_core_path_wine_to_w32_result"
+    func_to_host_path_result=$func_cygpath_result
+    func_convert_path_check : : \
+      "$func_to_host_path_tmp1" "$func_to_host_path_result"
+    func_convert_path_front_back_pathsep ":*" "*:" : "$1"
+  fi
+}
+# end func_convert_path_nix_to_cygwin
+
+
+# func_dll_def_p FILE
+# True iff FILE is a Windows DLL '.def' file.
+# Keep in sync with _LT_DLL_DEF_P in libtool.m4
+func_dll_def_p ()
+{
+  $debug_cmd
+
+  func_dll_def_p_tmp=`$SED -n \
+    -e 's/^[	 ]*//' \
+    -e '/^\(;.*\)*$/d' \
+    -e 's/^\(EXPORTS\|LIBRARY\)\([	 ].*\)*$/DEF/p' \
+    -e q \
+    "$1"`
+  test DEF = "$func_dll_def_p_tmp"
+}
+
+
+# func_mode_compile arg...
+func_mode_compile ()
+{
+    $debug_cmd
+
+    # Get the compilation command and the source file.
+    base_compile=
+    srcfile=$nonopt  #  always keep a non-empty value in "srcfile"
+    suppress_opt=yes
+    suppress_output=
+    arg_mode=normal
+    libobj=
+    later=
+    pie_flag=
+
+    for arg
+    do
+      case $arg_mode in
+      arg  )
+	# do not "continue".  Instead, add this to base_compile
+	lastarg=$arg
+	arg_mode=normal
+	;;
+
+      target )
+	libobj=$arg
+	arg_mode=normal
+	continue
+	;;
+
+      normal )
+	# Accept any command-line options.
+	case $arg in
+	-o)
+	  test -n "$libobj" && \
+	    func_fatal_error "you cannot specify '-o' more than once"
+	  arg_mode=target
+	  continue
+	  ;;
+
+	-pie | -fpie | -fPIE)
+          func_append pie_flag " $arg"
+	  continue
+	  ;;
+
+	-shared | -static | -prefer-pic | -prefer-non-pic)
+	  func_append later " $arg"
+	  continue
+	  ;;
+
+	-no-suppress)
+	  suppress_opt=no
+	  continue
+	  ;;
+
+	-Xcompiler)
+	  arg_mode=arg  #  the next one goes into the "base_compile" arg list
+	  continue      #  The current "srcfile" will either be retained or
+	  ;;            #  replaced later.  I would guess that would be a bug.
+
+	-Wc,*)
+	  func_stripname '-Wc,' '' "$arg"
+	  args=$func_stripname_result
+	  lastarg=
+	  save_ifs=$IFS; IFS=,
+	  for arg in $args; do
+	    IFS=$save_ifs
+	    func_append_quoted lastarg "$arg"
+	  done
+	  IFS=$save_ifs
+	  func_stripname ' ' '' "$lastarg"
+	  lastarg=$func_stripname_result
+
+	  # Add the arguments to base_compile.
+	  func_append base_compile " $lastarg"
+	  continue
+	  ;;
+
+	*)
+	  # Accept the current argument as the source file.
+	  # The previous "srcfile" becomes the current argument.
+	  #
+	  lastarg=$srcfile
+	  srcfile=$arg
+	  ;;
+	esac  #  case $arg
+	;;
+      esac    #  case $arg_mode
+
+      # Aesthetically quote the previous argument.
+      func_append_quoted base_compile "$lastarg"
+    done # for arg
+
+    case $arg_mode in
+    arg)
+      func_fatal_error "you must specify an argument for -Xcompile"
+      ;;
+    target)
+      func_fatal_error "you must specify a target with '-o'"
+      ;;
+    *)
+      # Get the name of the library object.
+      test -z "$libobj" && {
+	func_basename "$srcfile"
+	libobj=$func_basename_result
+      }
+      ;;
+    esac
+
+    # Recognize several different file suffixes.
+    # If the user specifies -o file.o, it is replaced with file.lo
+    case $libobj in
+    *.[cCFSifmso] | \
+    *.ada | *.adb | *.ads | *.asm | \
+    *.c++ | *.cc | *.ii | *.class | *.cpp | *.cxx | \
+    *.[fF][09]? | *.for | *.java | *.go | *.obj | *.sx | *.cu | *.cup)
+      func_xform "$libobj"
+      libobj=$func_xform_result
+      ;;
+    esac
+
+    case $libobj in
+    *.lo) func_lo2o "$libobj"; obj=$func_lo2o_result ;;
+    *)
+      func_fatal_error "cannot determine name of library object from '$libobj'"
+      ;;
+    esac
+
+    func_infer_tag $base_compile
+
+    for arg in $later; do
+      case $arg in
+      -shared)
+	test yes = "$build_libtool_libs" \
+	  || func_fatal_configuration "cannot build a shared library"
+	build_old_libs=no
+	continue
+	;;
+
+      -static)
+	build_libtool_libs=no
+	build_old_libs=yes
+	continue
+	;;
+
+      -prefer-pic)
+	pic_mode=yes
+	continue
+	;;
+
+      -prefer-non-pic)
+	pic_mode=no
+	continue
+	;;
+      esac
+    done
+
+    func_quote_for_eval "$libobj"
+    test "X$libobj" != "X$func_quote_for_eval_result" \
+      && $ECHO "X$libobj" | $GREP '[]~#^*{};<>?"'"'"'	 &()|`$[]' \
+      && func_warning "libobj name '$libobj' may not contain shell special characters."
+    func_dirname_and_basename "$obj" "/" ""
+    objname=$func_basename_result
+    xdir=$func_dirname_result
+    lobj=$xdir$objdir/$objname
+
+    test -z "$base_compile" && \
+      func_fatal_help "you must specify a compilation command"
+
+    # Delete any leftover library objects.
+    if test yes = "$build_old_libs"; then
+      removelist="$obj $lobj $libobj ${libobj}T"
+    else
+      removelist="$lobj $libobj ${libobj}T"
+    fi
+
+    # On Cygwin there's no "real" PIC flag so we must build both object types
+    case $host_os in
+    cygwin* | mingw* | pw32* | os2* | cegcc*)
+      pic_mode=default
+      ;;
+    esac
+    if test no = "$pic_mode" && test pass_all != "$deplibs_check_method"; then
+      # non-PIC code in shared libraries is not supported
+      pic_mode=default
+    fi
+
+    # Calculate the filename of the output object if compiler does
+    # not support -o with -c
+    if test no = "$compiler_c_o"; then
+      output_obj=`$ECHO "$srcfile" | $SED 's%^.*/%%; s%\.[^.]*$%%'`.$objext
+      lockfile=$output_obj.lock
+    else
+      output_obj=
+      need_locks=no
+      lockfile=
+    fi
+
+    # Lock this critical section if it is needed
+    # We use this script file to make the link, it avoids creating a new file
+    if test yes = "$need_locks"; then
+      until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do
+	func_echo "Waiting for $lockfile to be removed"
+	sleep 2
+      done
+    elif test warn = "$need_locks"; then
+      if test -f "$lockfile"; then
+	$ECHO "\
+*** ERROR, $lockfile exists and contains:
+`cat $lockfile 2>/dev/null`
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support '-c' and '-o' together.  If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+	$opt_dry_run || $RM $removelist
+	exit $EXIT_FAILURE
+      fi
+      func_append removelist " $output_obj"
+      $ECHO "$srcfile" > "$lockfile"
+    fi
+
+    $opt_dry_run || $RM $removelist
+    func_append removelist " $lockfile"
+    trap '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' 1 2 15
+
+    func_to_tool_file "$srcfile" func_convert_file_msys_to_w32
+    srcfile=$func_to_tool_file_result
+    func_quote_for_eval "$srcfile"
+    qsrcfile=$func_quote_for_eval_result
+
+    # Only build a PIC object if we are building libtool libraries.
+    if test yes = "$build_libtool_libs"; then
+      # Without this assignment, base_compile gets emptied.
+      fbsd_hideous_sh_bug=$base_compile
+
+      if test no != "$pic_mode"; then
+	command="$base_compile $qsrcfile $pic_flag"
+      else
+	# Don't build PIC code
+	command="$base_compile $qsrcfile"
+      fi
+
+      func_mkdir_p "$xdir$objdir"
+
+      if test -z "$output_obj"; then
+	# Place PIC objects in $objdir
+	func_append command " -o $lobj"
+      fi
+
+      func_show_eval_locale "$command"	\
+          'test -n "$output_obj" && $RM $removelist; exit $EXIT_FAILURE'
+
+      if test warn = "$need_locks" &&
+	 test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then
+	$ECHO "\
+*** ERROR, $lockfile contains:
+`cat $lockfile 2>/dev/null`
+
+but it should contain:
+$srcfile
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support '-c' and '-o' together.  If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+	$opt_dry_run || $RM $removelist
+	exit $EXIT_FAILURE
+      fi
+
+      # Just move the object if needed, then go on to compile the next one
+      if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then
+	func_show_eval '$MV "$output_obj" "$lobj"' \
+	  'error=$?; $opt_dry_run || $RM $removelist; exit $error'
+      fi
+
+      # Allow error messages only from the first compilation.
+      if test yes = "$suppress_opt"; then
+	suppress_output=' >/dev/null 2>&1'
+      fi
+    fi
+
+    # Only build a position-dependent object if we build old libraries.
+    if test yes = "$build_old_libs"; then
+      if test yes != "$pic_mode"; then
+	# Don't build PIC code
+	command="$base_compile $qsrcfile$pie_flag"
+      else
+	command="$base_compile $qsrcfile $pic_flag"
+      fi
+      if test yes = "$compiler_c_o"; then
+	func_append command " -o $obj"
+      fi
+
+      # Suppress compiler output if we already did a PIC compilation.
+      func_append command "$suppress_output"
+      func_show_eval_locale "$command" \
+        '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE'
+
+      if test warn = "$need_locks" &&
+	 test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then
+	$ECHO "\
+*** ERROR, $lockfile contains:
+`cat $lockfile 2>/dev/null`
+
+but it should contain:
+$srcfile
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support '-c' and '-o' together.  If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+	$opt_dry_run || $RM $removelist
+	exit $EXIT_FAILURE
+      fi
+
+      # Just move the object if needed
+      if test -n "$output_obj" && test "X$output_obj" != "X$obj"; then
+	func_show_eval '$MV "$output_obj" "$obj"' \
+	  'error=$?; $opt_dry_run || $RM $removelist; exit $error'
+      fi
+    fi
+
+    $opt_dry_run || {
+      func_write_libtool_object "$libobj" "$objdir/$objname" "$objname"
+
+      # Unlock the critical section if it was locked
+      if test no != "$need_locks"; then
+	removelist=$lockfile
+        $RM "$lockfile"
+      fi
+    }
+
+    exit $EXIT_SUCCESS
+}
+
+$opt_help || {
+  test compile = "$opt_mode" && func_mode_compile ${1+"$@"}
+}
+
+func_mode_help ()
+{
+    # We need to display help for each of the modes.
+    case $opt_mode in
+      "")
+        # Generic help is extracted from the usage comments
+        # at the start of this file.
+        func_help
+        ;;
+
+      clean)
+        $ECHO \
+"Usage: $progname [OPTION]... --mode=clean RM [RM-OPTION]... FILE...
+
+Remove files from the build directory.
+
+RM is the name of the program to use to delete files associated with each FILE
+(typically '/bin/rm').  RM-OPTIONS are options (such as '-f') to be passed
+to RM.
+
+If FILE is a libtool library, object or program, all the files associated
+with it are deleted. Otherwise, only FILE itself is deleted using RM."
+        ;;
+
+      compile)
+      $ECHO \
+"Usage: $progname [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE
+
+Compile a source file into a libtool library object.
+
+This mode accepts the following additional options:
+
+  -o OUTPUT-FILE    set the output file name to OUTPUT-FILE
+  -no-suppress      do not suppress compiler output for multiple passes
+  -prefer-pic       try to build PIC objects only
+  -prefer-non-pic   try to build non-PIC objects only
+  -shared           do not build a '.o' file suitable for static linking
+  -static           only build a '.o' file suitable for static linking
+  -Wc,FLAG          pass FLAG directly to the compiler
+
+COMPILE-COMMAND is a command to be used in creating a 'standard' object file
+from the given SOURCEFILE.
+
+The output file name is determined by removing the directory component from
+SOURCEFILE, then substituting the C source code suffix '.c' with the
+library object suffix, '.lo'."
+        ;;
+
+      execute)
+        $ECHO \
+"Usage: $progname [OPTION]... --mode=execute COMMAND [ARGS]...
+
+Automatically set library path, then run a program.
+
+This mode accepts the following additional options:
+
+  -dlopen FILE      add the directory containing FILE to the library path
+
+This mode sets the library path environment variable according to '-dlopen'
+flags.
+
+If any of the ARGS are libtool executable wrappers, then they are translated
+into their corresponding uninstalled binary, and any of their required library
+directories are added to the library path.
+
+Then, COMMAND is executed, with ARGS as arguments."
+        ;;
+
+      finish)
+        $ECHO \
+"Usage: $progname [OPTION]... --mode=finish [LIBDIR]...
+
+Complete the installation of libtool libraries.
+
+Each LIBDIR is a directory that contains libtool libraries.
+
+The commands that this mode executes may require superuser privileges.  Use
+the '--dry-run' option if you just want to see what would be executed."
+        ;;
+
+      install)
+        $ECHO \
+"Usage: $progname [OPTION]... --mode=install INSTALL-COMMAND...
+
+Install executables or libraries.
+
+INSTALL-COMMAND is the installation command.  The first component should be
+either the 'install' or 'cp' program.
+
+The following components of INSTALL-COMMAND are treated specially:
+
+  -inst-prefix-dir PREFIX-DIR  Use PREFIX-DIR as a staging area for installation
+
+The rest of the components are interpreted as arguments to that command (only
+BSD-compatible install options are recognized)."
+        ;;
+
+      link)
+        $ECHO \
+"Usage: $progname [OPTION]... --mode=link LINK-COMMAND...
+
+Link object files or libraries together to form another library, or to
+create an executable program.
+
+LINK-COMMAND is a command using the C compiler that you would use to create
+a program from several object files.
+
+The following components of LINK-COMMAND are treated specially:
+
+  -all-static       do not do any dynamic linking at all
+  -avoid-version    do not add a version suffix if possible
+  -bindir BINDIR    specify path to binaries directory (for systems where
+                    libraries must be found in the PATH setting at runtime)
+  -dlopen FILE      '-dlpreopen' FILE if it cannot be dlopened at runtime
+  -dlpreopen FILE   link in FILE and add its symbols to lt_preloaded_symbols
+  -export-dynamic   allow symbols from OUTPUT-FILE to be resolved with dlsym(3)
+  -export-symbols SYMFILE
+                    try to export only the symbols listed in SYMFILE
+  -export-symbols-regex REGEX
+                    try to export only the symbols matching REGEX
+  -LLIBDIR          search LIBDIR for required installed libraries
+  -lNAME            OUTPUT-FILE requires the installed library libNAME
+  -module           build a library that can dlopened
+  -no-fast-install  disable the fast-install mode
+  -no-install       link a not-installable executable
+  -no-undefined     declare that a library does not refer to external symbols
+  -o OUTPUT-FILE    create OUTPUT-FILE from the specified objects
+  -objectlist FILE  use a list of object files found in FILE to specify objects
+  -os2dllname NAME  force a short DLL name on OS/2 (no effect on other OSes)
+  -precious-files-regex REGEX
+                    don't remove output files matching REGEX
+  -release RELEASE  specify package release information
+  -rpath LIBDIR     the created library will eventually be installed in LIBDIR
+  -R[ ]LIBDIR       add LIBDIR to the runtime path of programs and libraries
+  -shared           only do dynamic linking of libtool libraries
+  -shrext SUFFIX    override the standard shared library file extension
+  -static           do not do any dynamic linking of uninstalled libtool libraries
+  -static-libtool-libs
+                    do not do any dynamic linking of libtool libraries
+  -version-info CURRENT[:REVISION[:AGE]]
+                    specify library version info [each variable defaults to 0]
+  -weak LIBNAME     declare that the target provides the LIBNAME interface
+  -Wc,FLAG
+  -Xcompiler FLAG   pass linker-specific FLAG directly to the compiler
+  -Wl,FLAG
+  -Xlinker FLAG     pass linker-specific FLAG directly to the linker
+  -XCClinker FLAG   pass link-specific FLAG to the compiler driver (CC)
+
+All other options (arguments beginning with '-') are ignored.
+
+Every other argument is treated as a filename.  Files ending in '.la' are
+treated as uninstalled libtool libraries, other files are standard or library
+object files.
+
+If the OUTPUT-FILE ends in '.la', then a libtool library is created,
+only library objects ('.lo' files) may be specified, and '-rpath' is
+required, except when creating a convenience library.
+
+If OUTPUT-FILE ends in '.a' or '.lib', then a standard library is created
+using 'ar' and 'ranlib', or on Windows using 'lib'.
+
+If OUTPUT-FILE ends in '.lo' or '.$objext', then a reloadable object file
+is created, otherwise an executable program is created."
+        ;;
+
+      uninstall)
+        $ECHO \
+"Usage: $progname [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE...
+
+Remove libraries from an installation directory.
+
+RM is the name of the program to use to delete files associated with each FILE
+(typically '/bin/rm').  RM-OPTIONS are options (such as '-f') to be passed
+to RM.
+
+If FILE is a libtool library, all the files associated with it are deleted.
+Otherwise, only FILE itself is deleted using RM."
+        ;;
+
+      *)
+        func_fatal_help "invalid operation mode '$opt_mode'"
+        ;;
+    esac
+
+    echo
+    $ECHO "Try '$progname --help' for more information about other modes."
+}
+
+# Now that we've collected a possible --mode arg, show help if necessary
+if $opt_help; then
+  if test : = "$opt_help"; then
+    func_mode_help
+  else
+    {
+      func_help noexit
+      for opt_mode in compile link execute install finish uninstall clean; do
+	func_mode_help
+      done
+    } | $SED -n '1p; 2,$s/^Usage:/  or: /p'
+    {
+      func_help noexit
+      for opt_mode in compile link execute install finish uninstall clean; do
+	echo
+	func_mode_help
+      done
+    } |
+    $SED '1d
+      /^When reporting/,/^Report/{
+	H
+	d
+      }
+      $x
+      /information about other modes/d
+      /more detailed .*MODE/d
+      s/^Usage:.*--mode=\([^ ]*\) .*/Description of \1 mode:/'
+  fi
+  exit $?
+fi
+
+
+# func_mode_execute arg...
+func_mode_execute ()
+{
+    $debug_cmd
+
+    # The first argument is the command name.
+    cmd=$nonopt
+    test -z "$cmd" && \
+      func_fatal_help "you must specify a COMMAND"
+
+    # Handle -dlopen flags immediately.
+    for file in $opt_dlopen; do
+      test -f "$file" \
+	|| func_fatal_help "'$file' is not a file"
+
+      dir=
+      case $file in
+      *.la)
+	func_resolve_sysroot "$file"
+	file=$func_resolve_sysroot_result
+
+	# Check to see that this really is a libtool archive.
+	func_lalib_unsafe_p "$file" \
+	  || func_fatal_help "'$lib' is not a valid libtool archive"
+
+	# Read the libtool library.
+	dlname=
+	library_names=
+	func_source "$file"
+
+	# Skip this library if it cannot be dlopened.
+	if test -z "$dlname"; then
+	  # Warn if it was a shared library.
+	  test -n "$library_names" && \
+	    func_warning "'$file' was not linked with '-export-dynamic'"
+	  continue
+	fi
+
+	func_dirname "$file" "" "."
+	dir=$func_dirname_result
+
+	if test -f "$dir/$objdir/$dlname"; then
+	  func_append dir "/$objdir"
+	else
+	  if test ! -f "$dir/$dlname"; then
+	    func_fatal_error "cannot find '$dlname' in '$dir' or '$dir/$objdir'"
+	  fi
+	fi
+	;;
+
+      *.lo)
+	# Just add the directory containing the .lo file.
+	func_dirname "$file" "" "."
+	dir=$func_dirname_result
+	;;
+
+      *)
+	func_warning "'-dlopen' is ignored for non-libtool libraries and objects"
+	continue
+	;;
+      esac
+
+      # Get the absolute pathname.
+      absdir=`cd "$dir" && pwd`
+      test -n "$absdir" && dir=$absdir
+
+      # Now add the directory to shlibpath_var.
+      if eval "test -z \"\$$shlibpath_var\""; then
+	eval "$shlibpath_var=\"\$dir\""
+      else
+	eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\""
+      fi
+    done
+
+    # This variable tells wrapper scripts just to set shlibpath_var
+    # rather than running their programs.
+    libtool_execute_magic=$magic
+
+    # Check if any of the arguments is a wrapper script.
+    args=
+    for file
+    do
+      case $file in
+      -* | *.la | *.lo ) ;;
+      *)
+	# Do a test to see if this is really a libtool program.
+	if func_ltwrapper_script_p "$file"; then
+	  func_source "$file"
+	  # Transform arg to wrapped name.
+	  file=$progdir/$program
+	elif func_ltwrapper_executable_p "$file"; then
+	  func_ltwrapper_scriptname "$file"
+	  func_source "$func_ltwrapper_scriptname_result"
+	  # Transform arg to wrapped name.
+	  file=$progdir/$program
+	fi
+	;;
+      esac
+      # Quote arguments (to preserve shell metacharacters).
+      func_append_quoted args "$file"
+    done
+
+    if $opt_dry_run; then
+      # Display what would be done.
+      if test -n "$shlibpath_var"; then
+	eval "\$ECHO \"\$shlibpath_var=\$$shlibpath_var\""
+	echo "export $shlibpath_var"
+      fi
+      $ECHO "$cmd$args"
+      exit $EXIT_SUCCESS
+    else
+      if test -n "$shlibpath_var"; then
+	# Export the shlibpath_var.
+	eval "export $shlibpath_var"
+      fi
+
+      # Restore saved environment variables
+      for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES
+      do
+	eval "if test \"\${save_$lt_var+set}\" = set; then
+                $lt_var=\$save_$lt_var; export $lt_var
+	      else
+		$lt_unset $lt_var
+	      fi"
+      done
+
+      # Now prepare to actually exec the command.
+      exec_cmd=\$cmd$args
+    fi
+}
+
+test execute = "$opt_mode" && func_mode_execute ${1+"$@"}
+
+
+# func_mode_finish arg...
+func_mode_finish ()
+{
+    $debug_cmd
+
+    libs=
+    libdirs=
+    admincmds=
+
+    for opt in "$nonopt" ${1+"$@"}
+    do
+      if test -d "$opt"; then
+	func_append libdirs " $opt"
+
+      elif test -f "$opt"; then
+	if func_lalib_unsafe_p "$opt"; then
+	  func_append libs " $opt"
+	else
+	  func_warning "'$opt' is not a valid libtool archive"
+	fi
+
+      else
+	func_fatal_error "invalid argument '$opt'"
+      fi
+    done
+
+    if test -n "$libs"; then
+      if test -n "$lt_sysroot"; then
+        sysroot_regex=`$ECHO "$lt_sysroot" | $SED "$sed_make_literal_regex"`
+        sysroot_cmd="s/\([ ']\)$sysroot_regex/\1/g;"
+      else
+        sysroot_cmd=
+      fi
+
+      # Remove sysroot references
+      if $opt_dry_run; then
+        for lib in $libs; do
+          echo "removing references to $lt_sysroot and '=' prefixes from $lib"
+        done
+      else
+        tmpdir=`func_mktempdir`
+        for lib in $libs; do
+	  $SED -e "$sysroot_cmd s/\([ ']-[LR]\)=/\1/g; s/\([ ']\)=/\1/g" $lib \
+	    > $tmpdir/tmp-la
+	  mv -f $tmpdir/tmp-la $lib
+	done
+        ${RM}r "$tmpdir"
+      fi
+    fi
+
+    if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then
+      for libdir in $libdirs; do
+	if test -n "$finish_cmds"; then
+	  # Do each command in the finish commands.
+	  func_execute_cmds "$finish_cmds" 'admincmds="$admincmds
+'"$cmd"'"'
+	fi
+	if test -n "$finish_eval"; then
+	  # Do the single finish_eval.
+	  eval cmds=\"$finish_eval\"
+	  $opt_dry_run || eval "$cmds" || func_append admincmds "
+       $cmds"
+	fi
+      done
+    fi
+
+    # Exit here if they wanted silent mode.
+    $opt_quiet && exit $EXIT_SUCCESS
+
+    if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then
+      echo "----------------------------------------------------------------------"
+      echo "Libraries have been installed in:"
+      for libdir in $libdirs; do
+	$ECHO "   $libdir"
+      done
+      echo
+      echo "If you ever happen to want to link against installed libraries"
+      echo "in a given directory, LIBDIR, you must either use libtool, and"
+      echo "specify the full pathname of the library, or use the '-LLIBDIR'"
+      echo "flag during linking and do at least one of the following:"
+      if test -n "$shlibpath_var"; then
+	echo "   - add LIBDIR to the '$shlibpath_var' environment variable"
+	echo "     during execution"
+      fi
+      if test -n "$runpath_var"; then
+	echo "   - add LIBDIR to the '$runpath_var' environment variable"
+	echo "     during linking"
+      fi
+      if test -n "$hardcode_libdir_flag_spec"; then
+	libdir=LIBDIR
+	eval flag=\"$hardcode_libdir_flag_spec\"
+
+	$ECHO "   - use the '$flag' linker flag"
+      fi
+      if test -n "$admincmds"; then
+	$ECHO "   - have your system administrator run these commands:$admincmds"
+      fi
+      if test -f /etc/ld.so.conf; then
+	echo "   - have your system administrator add LIBDIR to '/etc/ld.so.conf'"
+      fi
+      echo
+
+      echo "See any operating system documentation about shared libraries for"
+      case $host in
+	solaris2.[6789]|solaris2.1[0-9])
+	  echo "more information, such as the ld(1), crle(1) and ld.so(8) manual"
+	  echo "pages."
+	  ;;
+	*)
+	  echo "more information, such as the ld(1) and ld.so(8) manual pages."
+	  ;;
+      esac
+      echo "----------------------------------------------------------------------"
+    fi
+    exit $EXIT_SUCCESS
+}
+
+test finish = "$opt_mode" && func_mode_finish ${1+"$@"}
+
+
+# func_mode_install arg...
+func_mode_install ()
+{
+    $debug_cmd
+
+    # There may be an optional sh(1) argument at the beginning of
+    # install_prog (especially on Windows NT).
+    if test "$SHELL" = "$nonopt" || test /bin/sh = "$nonopt" ||
+       # Allow the use of GNU shtool's install command.
+       case $nonopt in *shtool*) :;; *) false;; esac
+    then
+      # Aesthetically quote it.
+      func_quote_for_eval "$nonopt"
+      install_prog="$func_quote_for_eval_result "
+      arg=$1
+      shift
+    else
+      install_prog=
+      arg=$nonopt
+    fi
+
+    # The real first argument should be the name of the installation program.
+    # Aesthetically quote it.
+    func_quote_for_eval "$arg"
+    func_append install_prog "$func_quote_for_eval_result"
+    install_shared_prog=$install_prog
+    case " $install_prog " in
+      *[\\\ /]cp\ *) install_cp=: ;;
+      *) install_cp=false ;;
+    esac
+
+    # We need to accept at least all the BSD install flags.
+    dest=
+    files=
+    opts=
+    prev=
+    install_type=
+    isdir=false
+    stripme=
+    no_mode=:
+    for arg
+    do
+      arg2=
+      if test -n "$dest"; then
+	func_append files " $dest"
+	dest=$arg
+	continue
+      fi
+
+      case $arg in
+      -d) isdir=: ;;
+      -f)
+	if $install_cp; then :; else
+	  prev=$arg
+	fi
+	;;
+      -g | -m | -o)
+	prev=$arg
+	;;
+      -s)
+	stripme=" -s"
+	continue
+	;;
+      -*)
+	;;
+      *)
+	# If the previous option needed an argument, then skip it.
+	if test -n "$prev"; then
+	  if test X-m = "X$prev" && test -n "$install_override_mode"; then
+	    arg2=$install_override_mode
+	    no_mode=false
+	  fi
+	  prev=
+	else
+	  dest=$arg
+	  continue
+	fi
+	;;
+      esac
+
+      # Aesthetically quote the argument.
+      func_quote_for_eval "$arg"
+      func_append install_prog " $func_quote_for_eval_result"
+      if test -n "$arg2"; then
+	func_quote_for_eval "$arg2"
+      fi
+      func_append install_shared_prog " $func_quote_for_eval_result"
+    done
+
+    test -z "$install_prog" && \
+      func_fatal_help "you must specify an install program"
+
+    test -n "$prev" && \
+      func_fatal_help "the '$prev' option requires an argument"
+
+    if test -n "$install_override_mode" && $no_mode; then
+      if $install_cp; then :; else
+	func_quote_for_eval "$install_override_mode"
+	func_append install_shared_prog " -m $func_quote_for_eval_result"
+      fi
+    fi
+
+    if test -z "$files"; then
+      if test -z "$dest"; then
+	func_fatal_help "no file or destination specified"
+      else
+	func_fatal_help "you must specify a destination"
+      fi
+    fi
+
+    # Strip any trailing slash from the destination.
+    func_stripname '' '/' "$dest"
+    dest=$func_stripname_result
+
+    # Check to see that the destination is a directory.
+    test -d "$dest" && isdir=:
+    if $isdir; then
+      destdir=$dest
+      destname=
+    else
+      func_dirname_and_basename "$dest" "" "."
+      destdir=$func_dirname_result
+      destname=$func_basename_result
+
+      # Not a directory, so check to see that there is only one file specified.
+      set dummy $files; shift
+      test "$#" -gt 1 && \
+	func_fatal_help "'$dest' is not a directory"
+    fi
+    case $destdir in
+    [\\/]* | [A-Za-z]:[\\/]*) ;;
+    *)
+      for file in $files; do
+	case $file in
+	*.lo) ;;
+	*)
+	  func_fatal_help "'$destdir' must be an absolute directory name"
+	  ;;
+	esac
+      done
+      ;;
+    esac
+
+    # This variable tells wrapper scripts just to set variables rather
+    # than running their programs.
+    libtool_install_magic=$magic
+
+    staticlibs=
+    future_libdirs=
+    current_libdirs=
+    for file in $files; do
+
+      # Do each installation.
+      case $file in
+      *.$libext)
+	# Do the static libraries later.
+	func_append staticlibs " $file"
+	;;
+
+      *.la)
+	func_resolve_sysroot "$file"
+	file=$func_resolve_sysroot_result
+
+	# Check to see that this really is a libtool archive.
+	func_lalib_unsafe_p "$file" \
+	  || func_fatal_help "'$file' is not a valid libtool archive"
+
+	library_names=
+	old_library=
+	relink_command=
+	func_source "$file"
+
+	# Add the libdir to current_libdirs if it is the destination.
+	if test "X$destdir" = "X$libdir"; then
+	  case "$current_libdirs " in
+	  *" $libdir "*) ;;
+	  *) func_append current_libdirs " $libdir" ;;
+	  esac
+	else
+	  # Note the libdir as a future libdir.
+	  case "$future_libdirs " in
+	  *" $libdir "*) ;;
+	  *) func_append future_libdirs " $libdir" ;;
+	  esac
+	fi
+
+	func_dirname "$file" "/" ""
+	dir=$func_dirname_result
+	func_append dir "$objdir"
+
+	if test -n "$relink_command"; then
+	  # Determine the prefix the user has applied to our future dir.
+	  inst_prefix_dir=`$ECHO "$destdir" | $SED -e "s%$libdir\$%%"`
+
+	  # Don't allow the user to place us outside of our expected
+	  # location b/c this prevents finding dependent libraries that
+	  # are installed to the same prefix.
+	  # At present, this check doesn't affect windows .dll's that
+	  # are installed into $libdir/../bin (currently, that works fine)
+	  # but it's something to keep an eye on.
+	  test "$inst_prefix_dir" = "$destdir" && \
+	    func_fatal_error "error: cannot install '$file' to a directory not ending in $libdir"
+
+	  if test -n "$inst_prefix_dir"; then
+	    # Stick the inst_prefix_dir data into the link command.
+	    relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%"`
+	  else
+	    relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%%"`
+	  fi
+
+	  func_warning "relinking '$file'"
+	  func_show_eval "$relink_command" \
+	    'func_fatal_error "error: relink '\''$file'\'' with the above command before installing it"'
+	fi
+
+	# See the names of the shared library.
+	set dummy $library_names; shift
+	if test -n "$1"; then
+	  realname=$1
+	  shift
+
+	  srcname=$realname
+	  test -n "$relink_command" && srcname=${realname}T
+
+	  # Install the shared library and build the symlinks.
+	  func_show_eval "$install_shared_prog $dir/$srcname $destdir/$realname" \
+	      'exit $?'
+	  tstripme=$stripme
+	  case $host_os in
+	  cygwin* | mingw* | pw32* | cegcc*)
+	    case $realname in
+	    *.dll.a)
+	      tstripme=
+	      ;;
+	    esac
+	    ;;
+	  os2*)
+	    case $realname in
+	    *_dll.a)
+	      tstripme=
+	      ;;
+	    esac
+	    ;;
+	  esac
+	  if test -n "$tstripme" && test -n "$striplib"; then
+	    func_show_eval "$striplib $destdir/$realname" 'exit $?'
+	  fi
+
+	  if test "$#" -gt 0; then
+	    # Delete the old symlinks, and create new ones.
+	    # Try 'ln -sf' first, because the 'ln' binary might depend on
+	    # the symlink we replace!  Solaris /bin/ln does not understand -f,
+	    # so we also need to try rm && ln -s.
+	    for linkname
+	    do
+	      test "$linkname" != "$realname" \
+		&& func_show_eval "(cd $destdir && { $LN_S -f $realname $linkname || { $RM $linkname && $LN_S $realname $linkname; }; })"
+	    done
+	  fi
+
+	  # Do each command in the postinstall commands.
+	  lib=$destdir/$realname
+	  func_execute_cmds "$postinstall_cmds" 'exit $?'
+	fi
+
+	# Install the pseudo-library for information purposes.
+	func_basename "$file"
+	name=$func_basename_result
+	instname=$dir/${name}i
+	func_show_eval "$install_prog $instname $destdir/$name" 'exit $?'
+
+	# Maybe install the static library, too.
+	test -n "$old_library" && func_append staticlibs " $dir/$old_library"
+	;;
+
+      *.lo)
+	# Install (i.e. copy) a libtool object.
+
+	# Figure out destination file name, if it wasn't already specified.
+	if test -n "$destname"; then
+	  destfile=$destdir/$destname
+	else
+	  func_basename "$file"
+	  destfile=$func_basename_result
+	  destfile=$destdir/$destfile
+	fi
+
+	# Deduce the name of the destination old-style object file.
+	case $destfile in
+	*.lo)
+	  func_lo2o "$destfile"
+	  staticdest=$func_lo2o_result
+	  ;;
+	*.$objext)
+	  staticdest=$destfile
+	  destfile=
+	  ;;
+	*)
+	  func_fatal_help "cannot copy a libtool object to '$destfile'"
+	  ;;
+	esac
+
+	# Install the libtool object if requested.
+	test -n "$destfile" && \
+	  func_show_eval "$install_prog $file $destfile" 'exit $?'
+
+	# Install the old object if enabled.
+	if test yes = "$build_old_libs"; then
+	  # Deduce the name of the old-style object file.
+	  func_lo2o "$file"
+	  staticobj=$func_lo2o_result
+	  func_show_eval "$install_prog \$staticobj \$staticdest" 'exit $?'
+	fi
+	exit $EXIT_SUCCESS
+	;;
+
+      *)
+	# Figure out destination file name, if it wasn't already specified.
+	if test -n "$destname"; then
+	  destfile=$destdir/$destname
+	else
+	  func_basename "$file"
+	  destfile=$func_basename_result
+	  destfile=$destdir/$destfile
+	fi
+
+	# If the file is missing, and there is a .exe on the end, strip it
+	# because it is most likely a libtool script we actually want to
+	# install
+	stripped_ext=
+	case $file in
+	  *.exe)
+	    if test ! -f "$file"; then
+	      func_stripname '' '.exe' "$file"
+	      file=$func_stripname_result
+	      stripped_ext=.exe
+	    fi
+	    ;;
+	esac
+
+	# Do a test to see if this is really a libtool program.
+	case $host in
+	*cygwin* | *mingw*)
+	    if func_ltwrapper_executable_p "$file"; then
+	      func_ltwrapper_scriptname "$file"
+	      wrapper=$func_ltwrapper_scriptname_result
+	    else
+	      func_stripname '' '.exe' "$file"
+	      wrapper=$func_stripname_result
+	    fi
+	    ;;
+	*)
+	    wrapper=$file
+	    ;;
+	esac
+	if func_ltwrapper_script_p "$wrapper"; then
+	  notinst_deplibs=
+	  relink_command=
+
+	  func_source "$wrapper"
+
+	  # Check the variables that should have been set.
+	  test -z "$generated_by_libtool_version" && \
+	    func_fatal_error "invalid libtool wrapper script '$wrapper'"
+
+	  finalize=:
+	  for lib in $notinst_deplibs; do
+	    # Check to see that each library is installed.
+	    libdir=
+	    if test -f "$lib"; then
+	      func_source "$lib"
+	    fi
+	    libfile=$libdir/`$ECHO "$lib" | $SED 's%^.*/%%g'`
+	    if test -n "$libdir" && test ! -f "$libfile"; then
+	      func_warning "'$lib' has not been installed in '$libdir'"
+	      finalize=false
+	    fi
+	  done
+
+	  relink_command=
+	  func_source "$wrapper"
+
+	  outputname=
+	  if test no = "$fast_install" && test -n "$relink_command"; then
+	    $opt_dry_run || {
+	      if $finalize; then
+	        tmpdir=`func_mktempdir`
+		func_basename "$file$stripped_ext"
+		file=$func_basename_result
+	        outputname=$tmpdir/$file
+	        # Replace the output file specification.
+	        relink_command=`$ECHO "$relink_command" | $SED 's%@OUTPUT@%'"$outputname"'%g'`
+
+	        $opt_quiet || {
+	          func_quote_for_expand "$relink_command"
+		  eval "func_echo $func_quote_for_expand_result"
+	        }
+	        if eval "$relink_command"; then :
+	          else
+		  func_error "error: relink '$file' with the above command before installing it"
+		  $opt_dry_run || ${RM}r "$tmpdir"
+		  continue
+	        fi
+	        file=$outputname
+	      else
+	        func_warning "cannot relink '$file'"
+	      fi
+	    }
+	  else
+	    # Install the binary that we compiled earlier.
+	    file=`$ECHO "$file$stripped_ext" | $SED "s%\([^/]*\)$%$objdir/\1%"`
+	  fi
+	fi
+
+	# remove .exe since cygwin /usr/bin/install will append another
+	# one anyway
+	case $install_prog,$host in
+	*/usr/bin/install*,*cygwin*)
+	  case $file:$destfile in
+	  *.exe:*.exe)
+	    # this is ok
+	    ;;
+	  *.exe:*)
+	    destfile=$destfile.exe
+	    ;;
+	  *:*.exe)
+	    func_stripname '' '.exe' "$destfile"
+	    destfile=$func_stripname_result
+	    ;;
+	  esac
+	  ;;
+	esac
+	func_show_eval "$install_prog\$stripme \$file \$destfile" 'exit $?'
+	$opt_dry_run || if test -n "$outputname"; then
+	  ${RM}r "$tmpdir"
+	fi
+	;;
+      esac
+    done
+
+    for file in $staticlibs; do
+      func_basename "$file"
+      name=$func_basename_result
+
+      # Set up the ranlib parameters.
+      oldlib=$destdir/$name
+      func_to_tool_file "$oldlib" func_convert_file_msys_to_w32
+      tool_oldlib=$func_to_tool_file_result
+
+      func_show_eval "$install_prog \$file \$oldlib" 'exit $?'
+
+      if test -n "$stripme" && test -n "$old_striplib"; then
+	func_show_eval "$old_striplib $tool_oldlib" 'exit $?'
+      fi
+
+      # Do each command in the postinstall commands.
+      func_execute_cmds "$old_postinstall_cmds" 'exit $?'
+    done
+
+    test -n "$future_libdirs" && \
+      func_warning "remember to run '$progname --finish$future_libdirs'"
+
+    if test -n "$current_libdirs"; then
+      # Maybe just do a dry run.
+      $opt_dry_run && current_libdirs=" -n$current_libdirs"
+      exec_cmd='$SHELL "$progpath" $preserve_args --finish$current_libdirs'
+    else
+      exit $EXIT_SUCCESS
+    fi
+}
+
+test install = "$opt_mode" && func_mode_install ${1+"$@"}
+
+
+# func_generate_dlsyms outputname originator pic_p
+# Extract symbols from dlprefiles and create ${outputname}S.o with
+# a dlpreopen symbol table.
+func_generate_dlsyms ()
+{
+    $debug_cmd
+
+    my_outputname=$1
+    my_originator=$2
+    my_pic_p=${3-false}
+    my_prefix=`$ECHO "$my_originator" | $SED 's%[^a-zA-Z0-9]%_%g'`
+    my_dlsyms=
+
+    if test -n "$dlfiles$dlprefiles" || test no != "$dlself"; then
+      if test -n "$NM" && test -n "$global_symbol_pipe"; then
+	my_dlsyms=${my_outputname}S.c
+      else
+	func_error "not configured to extract global symbols from dlpreopened files"
+      fi
+    fi
+
+    if test -n "$my_dlsyms"; then
+      case $my_dlsyms in
+      "") ;;
+      *.c)
+	# Discover the nlist of each of the dlfiles.
+	nlist=$output_objdir/$my_outputname.nm
+
+	func_show_eval "$RM $nlist ${nlist}S ${nlist}T"
+
+	# Parse the name list into a source file.
+	func_verbose "creating $output_objdir/$my_dlsyms"
+
+	$opt_dry_run || $ECHO > "$output_objdir/$my_dlsyms" "\
+/* $my_dlsyms - symbol resolution table for '$my_outputname' dlsym emulation. */
+/* Generated by $PROGRAM (GNU $PACKAGE) $VERSION */
+
+#ifdef __cplusplus
+extern \"C\" {
+#endif
+
+#if defined __GNUC__ && (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 4)) || (__GNUC__ > 4))
+#pragma GCC diagnostic ignored \"-Wstrict-prototypes\"
+#endif
+
+/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests.  */
+#if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE
+/* DATA imports from DLLs on WIN32 can't be const, because runtime
+   relocations are performed -- see ld's documentation on pseudo-relocs.  */
+# define LT_DLSYM_CONST
+#elif defined __osf__
+/* This system does not cope well with relocations in const data.  */
+# define LT_DLSYM_CONST
+#else
+# define LT_DLSYM_CONST const
+#endif
+
+#define STREQ(s1, s2) (strcmp ((s1), (s2)) == 0)
+
+/* External symbol declarations for the compiler. */\
+"
+
+	if test yes = "$dlself"; then
+	  func_verbose "generating symbol list for '$output'"
+
+	  $opt_dry_run || echo ': @PROGRAM@ ' > "$nlist"
+
+	  # Add our own program objects to the symbol list.
+	  progfiles=`$ECHO "$objs$old_deplibs" | $SP2NL | $SED "$lo2o" | $NL2SP`
+	  for progfile in $progfiles; do
+	    func_to_tool_file "$progfile" func_convert_file_msys_to_w32
+	    func_verbose "extracting global C symbols from '$func_to_tool_file_result'"
+	    $opt_dry_run || eval "$NM $func_to_tool_file_result | $global_symbol_pipe >> '$nlist'"
+	  done
+
+	  if test -n "$exclude_expsyms"; then
+	    $opt_dry_run || {
+	      eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T'
+	      eval '$MV "$nlist"T "$nlist"'
+	    }
+	  fi
+
+	  if test -n "$export_symbols_regex"; then
+	    $opt_dry_run || {
+	      eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T'
+	      eval '$MV "$nlist"T "$nlist"'
+	    }
+	  fi
+
+	  # Prepare the list of exported symbols
+	  if test -z "$export_symbols"; then
+	    export_symbols=$output_objdir/$outputname.exp
+	    $opt_dry_run || {
+	      $RM $export_symbols
+	      eval "$SED -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"'
+	      case $host in
+	      *cygwin* | *mingw* | *cegcc* )
+                eval "echo EXPORTS "'> "$output_objdir/$outputname.def"'
+                eval 'cat "$export_symbols" >> "$output_objdir/$outputname.def"'
+	        ;;
+	      esac
+	    }
+	  else
+	    $opt_dry_run || {
+	      eval "$SED -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"'
+	      eval '$GREP -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T'
+	      eval '$MV "$nlist"T "$nlist"'
+	      case $host in
+	        *cygwin* | *mingw* | *cegcc* )
+	          eval "echo EXPORTS "'> "$output_objdir/$outputname.def"'
+	          eval 'cat "$nlist" >> "$output_objdir/$outputname.def"'
+	          ;;
+	      esac
+	    }
+	  fi
+	fi
+
+	for dlprefile in $dlprefiles; do
+	  func_verbose "extracting global C symbols from '$dlprefile'"
+	  func_basename "$dlprefile"
+	  name=$func_basename_result
+          case $host in
+	    *cygwin* | *mingw* | *cegcc* )
+	      # if an import library, we need to obtain dlname
+	      if func_win32_import_lib_p "$dlprefile"; then
+	        func_tr_sh "$dlprefile"
+	        eval "curr_lafile=\$libfile_$func_tr_sh_result"
+	        dlprefile_dlbasename=
+	        if test -n "$curr_lafile" && func_lalib_p "$curr_lafile"; then
+	          # Use subshell, to avoid clobbering current variable values
+	          dlprefile_dlname=`source "$curr_lafile" && echo "$dlname"`
+	          if test -n "$dlprefile_dlname"; then
+	            func_basename "$dlprefile_dlname"
+	            dlprefile_dlbasename=$func_basename_result
+	          else
+	            # no lafile. user explicitly requested -dlpreopen <import library>.
+	            $sharedlib_from_linklib_cmd "$dlprefile"
+	            dlprefile_dlbasename=$sharedlib_from_linklib_result
+	          fi
+	        fi
+	        $opt_dry_run || {
+	          if test -n "$dlprefile_dlbasename"; then
+	            eval '$ECHO ": $dlprefile_dlbasename" >> "$nlist"'
+	          else
+	            func_warning "Could not compute DLL name from $name"
+	            eval '$ECHO ": $name " >> "$nlist"'
+	          fi
+	          func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32
+	          eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe |
+	            $SED -e '/I __imp/d' -e 's/I __nm_/D /;s/_nm__//' >> '$nlist'"
+	        }
+	      else # not an import lib
+	        $opt_dry_run || {
+	          eval '$ECHO ": $name " >> "$nlist"'
+	          func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32
+	          eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'"
+	        }
+	      fi
+	    ;;
+	    *)
+	      $opt_dry_run || {
+	        eval '$ECHO ": $name " >> "$nlist"'
+	        func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32
+	        eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'"
+	      }
+	    ;;
+          esac
+	done
+
+	$opt_dry_run || {
+	  # Make sure we have at least an empty file.
+	  test -f "$nlist" || : > "$nlist"
+
+	  if test -n "$exclude_expsyms"; then
+	    $EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T
+	    $MV "$nlist"T "$nlist"
+	  fi
+
+	  # Try sorting and uniquifying the output.
+	  if $GREP -v "^: " < "$nlist" |
+	      if sort -k 3 </dev/null >/dev/null 2>&1; then
+		sort -k 3
+	      else
+		sort +2
+	      fi |
+	      uniq > "$nlist"S; then
+	    :
+	  else
+	    $GREP -v "^: " < "$nlist" > "$nlist"S
+	  fi
+
+	  if test -f "$nlist"S; then
+	    eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$my_dlsyms"'
+	  else
+	    echo '/* NONE */' >> "$output_objdir/$my_dlsyms"
+	  fi
+
+	  func_show_eval '$RM "${nlist}I"'
+	  if test -n "$global_symbol_to_import"; then
+	    eval "$global_symbol_to_import"' < "$nlist"S > "$nlist"I'
+	  fi
+
+	  echo >> "$output_objdir/$my_dlsyms" "\
+
+/* The mapping between symbol names and symbols.  */
+typedef struct {
+  const char *name;
+  void *address;
+} lt_dlsymlist;
+extern LT_DLSYM_CONST lt_dlsymlist
+lt_${my_prefix}_LTX_preloaded_symbols[];\
+"
+
+	  if test -s "$nlist"I; then
+	    echo >> "$output_objdir/$my_dlsyms" "\
+static void lt_syminit(void)
+{
+  LT_DLSYM_CONST lt_dlsymlist *symbol = lt_${my_prefix}_LTX_preloaded_symbols;
+  for (; symbol->name; ++symbol)
+    {"
+	    $SED 's/.*/      if (STREQ (symbol->name, \"&\")) symbol->address = (void *) \&&;/' < "$nlist"I >> "$output_objdir/$my_dlsyms"
+	    echo >> "$output_objdir/$my_dlsyms" "\
+    }
+}"
+	  fi
+	  echo >> "$output_objdir/$my_dlsyms" "\
+LT_DLSYM_CONST lt_dlsymlist
+lt_${my_prefix}_LTX_preloaded_symbols[] =
+{ {\"$my_originator\", (void *) 0},"
+
+	  if test -s "$nlist"I; then
+	    echo >> "$output_objdir/$my_dlsyms" "\
+  {\"@INIT@\", (void *) &lt_syminit},"
+	  fi
+
+	  case $need_lib_prefix in
+	  no)
+	    eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$my_dlsyms"
+	    ;;
+	  *)
+	    eval "$global_symbol_to_c_name_address_lib_prefix" < "$nlist" >> "$output_objdir/$my_dlsyms"
+	    ;;
+	  esac
+	  echo >> "$output_objdir/$my_dlsyms" "\
+  {0, (void *) 0}
+};
+
+/* This works around a problem in FreeBSD linker */
+#ifdef FREEBSD_WORKAROUND
+static const void *lt_preloaded_setup() {
+  return lt_${my_prefix}_LTX_preloaded_symbols;
+}
+#endif
+
+#ifdef __cplusplus
+}
+#endif\
+"
+	} # !$opt_dry_run
+
+	pic_flag_for_symtable=
+	case "$compile_command " in
+	*" -static "*) ;;
+	*)
+	  case $host in
+	  # compiling the symbol table file with pic_flag works around
+	  # a FreeBSD bug that causes programs to crash when -lm is
+	  # linked before any other PIC object.  But we must not use
+	  # pic_flag when linking with -static.  The problem exists in
+	  # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1.
+	  *-*-freebsd2.*|*-*-freebsd3.0*|*-*-freebsdelf3.0*)
+	    pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND" ;;
+	  *-*-hpux*)
+	    pic_flag_for_symtable=" $pic_flag"  ;;
+	  *)
+	    $my_pic_p && pic_flag_for_symtable=" $pic_flag"
+	    ;;
+	  esac
+	  ;;
+	esac
+	symtab_cflags=
+	for arg in $LTCFLAGS; do
+	  case $arg in
+	  -pie | -fpie | -fPIE) ;;
+	  *) func_append symtab_cflags " $arg" ;;
+	  esac
+	done
+
+	# Now compile the dynamic symbol file.
+	func_show_eval '(cd $output_objdir && $LTCC$symtab_cflags -c$no_builtin_flag$pic_flag_for_symtable "$my_dlsyms")' 'exit $?'
+
+	# Clean up the generated files.
+	func_show_eval '$RM "$output_objdir/$my_dlsyms" "$nlist" "${nlist}S" "${nlist}T" "${nlist}I"'
+
+	# Transform the symbol file into the correct name.
+	symfileobj=$output_objdir/${my_outputname}S.$objext
+	case $host in
+	*cygwin* | *mingw* | *cegcc* )
+	  if test -f "$output_objdir/$my_outputname.def"; then
+	    compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"`
+	    finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"`
+	  else
+	    compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"`
+	    finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"`
+	  fi
+	  ;;
+	*)
+	  compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"`
+	  finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"`
+	  ;;
+	esac
+	;;
+      *)
+	func_fatal_error "unknown suffix for '$my_dlsyms'"
+	;;
+      esac
+    else
+      # We keep going just in case the user didn't refer to
+      # lt_preloaded_symbols.  The linker will fail if global_symbol_pipe
+      # really was required.
+
+      # Nullify the symbol file.
+      compile_command=`$ECHO "$compile_command" | $SED "s% @SYMFILE@%%"`
+      finalize_command=`$ECHO "$finalize_command" | $SED "s% @SYMFILE@%%"`
+    fi
+}
+
+# func_cygming_gnu_implib_p ARG
+# This predicate returns with zero status (TRUE) if
+# ARG is a GNU/binutils-style import library. Returns
+# with nonzero status (FALSE) otherwise.
+func_cygming_gnu_implib_p ()
+{
+  $debug_cmd
+
+  func_to_tool_file "$1" func_convert_file_msys_to_w32
+  func_cygming_gnu_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $EGREP ' (_head_[A-Za-z0-9_]+_[ad]l*|[A-Za-z0-9_]+_[ad]l*_iname)$'`
+  test -n "$func_cygming_gnu_implib_tmp"
+}
+
+# func_cygming_ms_implib_p ARG
+# This predicate returns with zero status (TRUE) if
+# ARG is an MS-style import library. Returns
+# with nonzero status (FALSE) otherwise.
+func_cygming_ms_implib_p ()
+{
+  $debug_cmd
+
+  func_to_tool_file "$1" func_convert_file_msys_to_w32
+  func_cygming_ms_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $GREP '_NULL_IMPORT_DESCRIPTOR'`
+  test -n "$func_cygming_ms_implib_tmp"
+}
+
+# func_win32_libid arg
+# return the library type of file 'arg'
+#
+# Need a lot of goo to handle *both* DLLs and import libs
+# Has to be a shell function in order to 'eat' the argument
+# that is supplied when $file_magic_command is called.
+# Despite the name, also deal with 64 bit binaries.
+func_win32_libid ()
+{
+  $debug_cmd
+
+  win32_libid_type=unknown
+  win32_fileres=`file -L $1 2>/dev/null`
+  case $win32_fileres in
+  *ar\ archive\ import\ library*) # definitely import
+    win32_libid_type="x86 archive import"
+    ;;
+  *ar\ archive*) # could be an import, or static
+    # Keep the egrep pattern in sync with the one in _LT_CHECK_MAGIC_METHOD.
+    if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null |
+       $EGREP 'file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' >/dev/null; then
+      case $nm_interface in
+      "MS dumpbin")
+	if func_cygming_ms_implib_p "$1" ||
+	   func_cygming_gnu_implib_p "$1"
+	then
+	  win32_nmres=import
+	else
+	  win32_nmres=
+	fi
+	;;
+      *)
+	func_to_tool_file "$1" func_convert_file_msys_to_w32
+	win32_nmres=`eval $NM -f posix -A \"$func_to_tool_file_result\" |
+	  $SED -n -e '
+	    1,100{
+		/ I /{
+		    s|.*|import|
+		    p
+		    q
+		}
+	    }'`
+	;;
+      esac
+      case $win32_nmres in
+      import*)  win32_libid_type="x86 archive import";;
+      *)        win32_libid_type="x86 archive static";;
+      esac
+    fi
+    ;;
+  *DLL*)
+    win32_libid_type="x86 DLL"
+    ;;
+  *executable*) # but shell scripts are "executable" too...
+    case $win32_fileres in
+    *MS\ Windows\ PE\ Intel*)
+      win32_libid_type="x86 DLL"
+      ;;
+    esac
+    ;;
+  esac
+  $ECHO "$win32_libid_type"
+}
+
+# func_cygming_dll_for_implib ARG
+#
+# Platform-specific function to extract the
+# name of the DLL associated with the specified
+# import library ARG.
+# Invoked by eval'ing the libtool variable
+#    $sharedlib_from_linklib_cmd
+# Result is available in the variable
+#    $sharedlib_from_linklib_result
+func_cygming_dll_for_implib ()
+{
+  $debug_cmd
+
+  sharedlib_from_linklib_result=`$DLLTOOL --identify-strict --identify "$1"`
+}
+
+# func_cygming_dll_for_implib_fallback_core SECTION_NAME LIBNAMEs
+#
+# The is the core of a fallback implementation of a
+# platform-specific function to extract the name of the
+# DLL associated with the specified import library LIBNAME.
+#
+# SECTION_NAME is either .idata$6 or .idata$7, depending
+# on the platform and compiler that created the implib.
+#
+# Echos the name of the DLL associated with the
+# specified import library.
+func_cygming_dll_for_implib_fallback_core ()
+{
+  $debug_cmd
+
+  match_literal=`$ECHO "$1" | $SED "$sed_make_literal_regex"`
+  $OBJDUMP -s --section "$1" "$2" 2>/dev/null |
+    $SED '/^Contents of section '"$match_literal"':/{
+      # Place marker at beginning of archive member dllname section
+      s/.*/====MARK====/
+      p
+      d
+    }
+    # These lines can sometimes be longer than 43 characters, but
+    # are always uninteresting
+    /:[	 ]*file format pe[i]\{,1\}-/d
+    /^In archive [^:]*:/d
+    # Ensure marker is printed
+    /^====MARK====/p
+    # Remove all lines with less than 43 characters
+    /^.\{43\}/!d
+    # From remaining lines, remove first 43 characters
+    s/^.\{43\}//' |
+    $SED -n '
+      # Join marker and all lines until next marker into a single line
+      /^====MARK====/ b para
+      H
+      $ b para
+      b
+      :para
+      x
+      s/\n//g
+      # Remove the marker
+      s/^====MARK====//
+      # Remove trailing dots and whitespace
+      s/[\. \t]*$//
+      # Print
+      /./p' |
+    # we now have a list, one entry per line, of the stringified
+    # contents of the appropriate section of all members of the
+    # archive that possess that section. Heuristic: eliminate
+    # all those that have a first or second character that is
+    # a '.' (that is, objdump's representation of an unprintable
+    # character.) This should work for all archives with less than
+    # 0x302f exports -- but will fail for DLLs whose name actually
+    # begins with a literal '.' or a single character followed by
+    # a '.'.
+    #
+    # Of those that remain, print the first one.
+    $SED -e '/^\./d;/^.\./d;q'
+}
+
+# func_cygming_dll_for_implib_fallback ARG
+# Platform-specific function to extract the
+# name of the DLL associated with the specified
+# import library ARG.
+#
+# This fallback implementation is for use when $DLLTOOL
+# does not support the --identify-strict option.
+# Invoked by eval'ing the libtool variable
+#    $sharedlib_from_linklib_cmd
+# Result is available in the variable
+#    $sharedlib_from_linklib_result
+func_cygming_dll_for_implib_fallback ()
+{
+  $debug_cmd
+
+  if func_cygming_gnu_implib_p "$1"; then
+    # binutils import library
+    sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$7' "$1"`
+  elif func_cygming_ms_implib_p "$1"; then
+    # ms-generated import library
+    sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$6' "$1"`
+  else
+    # unknown
+    sharedlib_from_linklib_result=
+  fi
+}
+
+
+# func_extract_an_archive dir oldlib
+func_extract_an_archive ()
+{
+    $debug_cmd
+
+    f_ex_an_ar_dir=$1; shift
+    f_ex_an_ar_oldlib=$1
+    if test yes = "$lock_old_archive_extraction"; then
+      lockfile=$f_ex_an_ar_oldlib.lock
+      until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do
+	func_echo "Waiting for $lockfile to be removed"
+	sleep 2
+      done
+    fi
+    func_show_eval "(cd \$f_ex_an_ar_dir && $AR x \"\$f_ex_an_ar_oldlib\")" \
+		   'stat=$?; rm -f "$lockfile"; exit $stat'
+    if test yes = "$lock_old_archive_extraction"; then
+      $opt_dry_run || rm -f "$lockfile"
+    fi
+    if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then
+     :
+    else
+      func_fatal_error "object name conflicts in archive: $f_ex_an_ar_dir/$f_ex_an_ar_oldlib"
+    fi
+}
+
+
+# func_extract_archives gentop oldlib ...
+func_extract_archives ()
+{
+    $debug_cmd
+
+    my_gentop=$1; shift
+    my_oldlibs=${1+"$@"}
+    my_oldobjs=
+    my_xlib=
+    my_xabs=
+    my_xdir=
+
+    for my_xlib in $my_oldlibs; do
+      # Extract the objects.
+      case $my_xlib in
+	[\\/]* | [A-Za-z]:[\\/]*) my_xabs=$my_xlib ;;
+	*) my_xabs=`pwd`"/$my_xlib" ;;
+      esac
+      func_basename "$my_xlib"
+      my_xlib=$func_basename_result
+      my_xlib_u=$my_xlib
+      while :; do
+        case " $extracted_archives " in
+	*" $my_xlib_u "*)
+	  func_arith $extracted_serial + 1
+	  extracted_serial=$func_arith_result
+	  my_xlib_u=lt$extracted_serial-$my_xlib ;;
+	*) break ;;
+	esac
+      done
+      extracted_archives="$extracted_archives $my_xlib_u"
+      my_xdir=$my_gentop/$my_xlib_u
+
+      func_mkdir_p "$my_xdir"
+
+      case $host in
+      *-darwin*)
+	func_verbose "Extracting $my_xabs"
+	# Do not bother doing anything if just a dry run
+	$opt_dry_run || {
+	  darwin_orig_dir=`pwd`
+	  cd $my_xdir || exit $?
+	  darwin_archive=$my_xabs
+	  darwin_curdir=`pwd`
+	  func_basename "$darwin_archive"
+	  darwin_base_archive=$func_basename_result
+	  darwin_arches=`$LIPO -info "$darwin_archive" 2>/dev/null | $GREP Architectures 2>/dev/null || true`
+	  if test -n "$darwin_arches"; then
+	    darwin_arches=`$ECHO "$darwin_arches" | $SED -e 's/.*are://'`
+	    darwin_arch=
+	    func_verbose "$darwin_base_archive has multiple architectures $darwin_arches"
+	    for darwin_arch in  $darwin_arches; do
+	      func_mkdir_p "unfat-$$/$darwin_base_archive-$darwin_arch"
+	      $LIPO -thin $darwin_arch -output "unfat-$$/$darwin_base_archive-$darwin_arch/$darwin_base_archive" "$darwin_archive"
+	      cd "unfat-$$/$darwin_base_archive-$darwin_arch"
+	      func_extract_an_archive "`pwd`" "$darwin_base_archive"
+	      cd "$darwin_curdir"
+	      $RM "unfat-$$/$darwin_base_archive-$darwin_arch/$darwin_base_archive"
+	    done # $darwin_arches
+            ## Okay now we've a bunch of thin objects, gotta fatten them up :)
+	    darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print | $SED -e "$sed_basename" | sort -u`
+	    darwin_file=
+	    darwin_files=
+	    for darwin_file in $darwin_filelist; do
+	      darwin_files=`find unfat-$$ -name $darwin_file -print | sort | $NL2SP`
+	      $LIPO -create -output "$darwin_file" $darwin_files
+	    done # $darwin_filelist
+	    $RM -rf unfat-$$
+	    cd "$darwin_orig_dir"
+	  else
+	    cd $darwin_orig_dir
+	    func_extract_an_archive "$my_xdir" "$my_xabs"
+	  fi # $darwin_arches
+	} # !$opt_dry_run
+	;;
+      *)
+        func_extract_an_archive "$my_xdir" "$my_xabs"
+	;;
+      esac
+      my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | sort | $NL2SP`
+    done
+
+    func_extract_archives_result=$my_oldobjs
+}
+
+
+# func_emit_wrapper [arg=no]
+#
+# Emit a libtool wrapper script on stdout.
+# Don't directly open a file because we may want to
+# incorporate the script contents within a cygwin/mingw
+# wrapper executable.  Must ONLY be called from within
+# func_mode_link because it depends on a number of variables
+# set therein.
+#
+# ARG is the value that the WRAPPER_SCRIPT_BELONGS_IN_OBJDIR
+# variable will take.  If 'yes', then the emitted script
+# will assume that the directory where it is stored is
+# the $objdir directory.  This is a cygwin/mingw-specific
+# behavior.
+func_emit_wrapper ()
+{
+	func_emit_wrapper_arg1=${1-no}
+
+	$ECHO "\
+#! $SHELL
+
+# $output - temporary wrapper script for $objdir/$outputname
+# Generated by $PROGRAM (GNU $PACKAGE) $VERSION
+#
+# The $output program cannot be directly executed until all the libtool
+# libraries that it depends on are installed.
+#
+# This wrapper script should never be moved out of the build directory.
+# If it is, it will not operate correctly.
+
+# Sed substitution that helps us do robust quoting.  It backslashifies
+# metacharacters that are still active within double-quoted strings.
+sed_quote_subst='$sed_quote_subst'
+
+# Be Bourne compatible
+if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then
+  emulate sh
+  NULLCMD=:
+  # Zsh 3.x and 4.x performs word splitting on \${1+\"\$@\"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '\${1+\"\$@\"}'='\"\$@\"'
+  setopt NO_GLOB_SUBST
+else
+  case \`(set -o) 2>/dev/null\` in *posix*) set -o posix;; esac
+fi
+BIN_SH=xpg4; export BIN_SH # for Tru64
+DUALCASE=1; export DUALCASE # for MKS sh
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+relink_command=\"$relink_command\"
+
+# This environment variable determines our operation mode.
+if test \"\$libtool_install_magic\" = \"$magic\"; then
+  # install mode needs the following variables:
+  generated_by_libtool_version='$macro_version'
+  notinst_deplibs='$notinst_deplibs'
+else
+  # When we are sourced in execute mode, \$file and \$ECHO are already set.
+  if test \"\$libtool_execute_magic\" != \"$magic\"; then
+    file=\"\$0\""
+
+    qECHO=`$ECHO "$ECHO" | $SED "$sed_quote_subst"`
+    $ECHO "\
+
+# A function that is used when there is no print builtin or printf.
+func_fallback_echo ()
+{
+  eval 'cat <<_LTECHO_EOF
+\$1
+_LTECHO_EOF'
+}
+    ECHO=\"$qECHO\"
+  fi
+
+# Very basic option parsing. These options are (a) specific to
+# the libtool wrapper, (b) are identical between the wrapper
+# /script/ and the wrapper /executable/ that is used only on
+# windows platforms, and (c) all begin with the string "--lt-"
+# (application programs are unlikely to have options that match
+# this pattern).
+#
+# There are only two supported options: --lt-debug and
+# --lt-dump-script. There is, deliberately, no --lt-help.
+#
+# The first argument to this parsing function should be the
+# script's $0 value, followed by "$@".
+lt_option_debug=
+func_parse_lt_options ()
+{
+  lt_script_arg0=\$0
+  shift
+  for lt_opt
+  do
+    case \"\$lt_opt\" in
+    --lt-debug) lt_option_debug=1 ;;
+    --lt-dump-script)
+        lt_dump_D=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%/[^/]*$%%'\`
+        test \"X\$lt_dump_D\" = \"X\$lt_script_arg0\" && lt_dump_D=.
+        lt_dump_F=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%^.*/%%'\`
+        cat \"\$lt_dump_D/\$lt_dump_F\"
+        exit 0
+      ;;
+    --lt-*)
+        \$ECHO \"Unrecognized --lt- option: '\$lt_opt'\" 1>&2
+        exit 1
+      ;;
+    esac
+  done
+
+  # Print the debug banner immediately:
+  if test -n \"\$lt_option_debug\"; then
+    echo \"$outputname:$output:\$LINENO: libtool wrapper (GNU $PACKAGE) $VERSION\" 1>&2
+  fi
+}
+
+# Used when --lt-debug. Prints its arguments to stdout
+# (redirection is the responsibility of the caller)
+func_lt_dump_args ()
+{
+  lt_dump_args_N=1;
+  for lt_arg
+  do
+    \$ECHO \"$outputname:$output:\$LINENO: newargv[\$lt_dump_args_N]: \$lt_arg\"
+    lt_dump_args_N=\`expr \$lt_dump_args_N + 1\`
+  done
+}
+
+# Core function for launching the target application
+func_exec_program_core ()
+{
+"
+  case $host in
+  # Backslashes separate directories on plain windows
+  *-*-mingw | *-*-os2* | *-cegcc*)
+    $ECHO "\
+      if test -n \"\$lt_option_debug\"; then
+        \$ECHO \"$outputname:$output:\$LINENO: newargv[0]: \$progdir\\\\\$program\" 1>&2
+        func_lt_dump_args \${1+\"\$@\"} 1>&2
+      fi
+      exec \"\$progdir\\\\\$program\" \${1+\"\$@\"}
+"
+    ;;
+
+  *)
+    $ECHO "\
+      if test -n \"\$lt_option_debug\"; then
+        \$ECHO \"$outputname:$output:\$LINENO: newargv[0]: \$progdir/\$program\" 1>&2
+        func_lt_dump_args \${1+\"\$@\"} 1>&2
+      fi
+      exec \"\$progdir/\$program\" \${1+\"\$@\"}
+"
+    ;;
+  esac
+  $ECHO "\
+      \$ECHO \"\$0: cannot exec \$program \$*\" 1>&2
+      exit 1
+}
+
+# A function to encapsulate launching the target application
+# Strips options in the --lt-* namespace from \$@ and
+# launches target application with the remaining arguments.
+func_exec_program ()
+{
+  case \" \$* \" in
+  *\\ --lt-*)
+    for lt_wr_arg
+    do
+      case \$lt_wr_arg in
+      --lt-*) ;;
+      *) set x \"\$@\" \"\$lt_wr_arg\"; shift;;
+      esac
+      shift
+    done ;;
+  esac
+  func_exec_program_core \${1+\"\$@\"}
+}
+
+  # Parse options
+  func_parse_lt_options \"\$0\" \${1+\"\$@\"}
+
+  # Find the directory that this script lives in.
+  thisdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*$%%'\`
+  test \"x\$thisdir\" = \"x\$file\" && thisdir=.
+
+  # Follow symbolic links until we get to the real thisdir.
+  file=\`ls -ld \"\$file\" | $SED -n 's/.*-> //p'\`
+  while test -n \"\$file\"; do
+    destdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*\$%%'\`
+
+    # If there was a directory component, then change thisdir.
+    if test \"x\$destdir\" != \"x\$file\"; then
+      case \"\$destdir\" in
+      [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;;
+      *) thisdir=\"\$thisdir/\$destdir\" ;;
+      esac
+    fi
+
+    file=\`\$ECHO \"\$file\" | $SED 's%^.*/%%'\`
+    file=\`ls -ld \"\$thisdir/\$file\" | $SED -n 's/.*-> //p'\`
+  done
+
+  # Usually 'no', except on cygwin/mingw when embedded into
+  # the cwrapper.
+  WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=$func_emit_wrapper_arg1
+  if test \"\$WRAPPER_SCRIPT_BELONGS_IN_OBJDIR\" = \"yes\"; then
+    # special case for '.'
+    if test \"\$thisdir\" = \".\"; then
+      thisdir=\`pwd\`
+    fi
+    # remove .libs from thisdir
+    case \"\$thisdir\" in
+    *[\\\\/]$objdir ) thisdir=\`\$ECHO \"\$thisdir\" | $SED 's%[\\\\/][^\\\\/]*$%%'\` ;;
+    $objdir )   thisdir=. ;;
+    esac
+  fi
+
+  # Try to get the absolute directory name.
+  absdir=\`cd \"\$thisdir\" && pwd\`
+  test -n \"\$absdir\" && thisdir=\"\$absdir\"
+"
+
+	if test yes = "$fast_install"; then
+	  $ECHO "\
+  program=lt-'$outputname'$exeext
+  progdir=\"\$thisdir/$objdir\"
+
+  if test ! -f \"\$progdir/\$program\" ||
+     { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | $SED 1q\`; \\
+       test \"X\$file\" != \"X\$progdir/\$program\"; }; then
+
+    file=\"\$\$-\$program\"
+
+    if test ! -d \"\$progdir\"; then
+      $MKDIR \"\$progdir\"
+    else
+      $RM \"\$progdir/\$file\"
+    fi"
+
+	  $ECHO "\
+
+    # relink executable if necessary
+    if test -n \"\$relink_command\"; then
+      if relink_command_output=\`eval \$relink_command 2>&1\`; then :
+      else
+	\$ECHO \"\$relink_command_output\" >&2
+	$RM \"\$progdir/\$file\"
+	exit 1
+      fi
+    fi
+
+    $MV \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null ||
+    { $RM \"\$progdir/\$program\";
+      $MV \"\$progdir/\$file\" \"\$progdir/\$program\"; }
+    $RM \"\$progdir/\$file\"
+  fi"
+	else
+	  $ECHO "\
+  program='$outputname'
+  progdir=\"\$thisdir/$objdir\"
+"
+	fi
+
+	$ECHO "\
+
+  if test -f \"\$progdir/\$program\"; then"
+
+	# fixup the dll searchpath if we need to.
+	#
+	# Fix the DLL searchpath if we need to.  Do this before prepending
+	# to shlibpath, because on Windows, both are PATH and uninstalled
+	# libraries must come first.
+	if test -n "$dllsearchpath"; then
+	  $ECHO "\
+    # Add the dll search path components to the executable PATH
+    PATH=$dllsearchpath:\$PATH
+"
+	fi
+
+	# Export our shlibpath_var if we have one.
+	if test yes = "$shlibpath_overrides_runpath" && test -n "$shlibpath_var" && test -n "$temp_rpath"; then
+	  $ECHO "\
+    # Add our own library path to $shlibpath_var
+    $shlibpath_var=\"$temp_rpath\$$shlibpath_var\"
+
+    # Some systems cannot cope with colon-terminated $shlibpath_var
+    # The second colon is a workaround for a bug in BeOS R4 sed
+    $shlibpath_var=\`\$ECHO \"\$$shlibpath_var\" | $SED 's/::*\$//'\`
+
+    export $shlibpath_var
+"
+	fi
+
+	$ECHO "\
+    if test \"\$libtool_execute_magic\" != \"$magic\"; then
+      # Run the actual program with our arguments.
+      func_exec_program \${1+\"\$@\"}
+    fi
+  else
+    # The program doesn't exist.
+    \$ECHO \"\$0: error: '\$progdir/\$program' does not exist\" 1>&2
+    \$ECHO \"This script is just a wrapper for \$program.\" 1>&2
+    \$ECHO \"See the $PACKAGE documentation for more information.\" 1>&2
+    exit 1
+  fi
+fi\
+"
+}
+
+
+# func_emit_cwrapperexe_src
+# emit the source code for a wrapper executable on stdout
+# Must ONLY be called from within func_mode_link because
+# it depends on a number of variable set therein.
+func_emit_cwrapperexe_src ()
+{
+	cat <<EOF
+
+/* $cwrappersource - temporary wrapper executable for $objdir/$outputname
+   Generated by $PROGRAM (GNU $PACKAGE) $VERSION
+
+   The $output program cannot be directly executed until all the libtool
+   libraries that it depends on are installed.
+
+   This wrapper executable should never be moved out of the build directory.
+   If it is, it will not operate correctly.
+*/
+EOF
+	    cat <<"EOF"
+#ifdef _MSC_VER
+# define _CRT_SECURE_NO_DEPRECATE 1
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef _MSC_VER
+# include <direct.h>
+# include <process.h>
+# include <io.h>
+#else
+# include <unistd.h>
+# include <stdint.h>
+# ifdef __CYGWIN__
+#  include <io.h>
+# endif
+#endif
+#include <malloc.h>
+#include <stdarg.h>
+#include <assert.h>
+#include <string.h>
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+
+#define STREQ(s1, s2) (strcmp ((s1), (s2)) == 0)
+
+/* declarations of non-ANSI functions */
+#if defined __MINGW32__
+# ifdef __STRICT_ANSI__
+int _putenv (const char *);
+# endif
+#elif defined __CYGWIN__
+# ifdef __STRICT_ANSI__
+char *realpath (const char *, char *);
+int putenv (char *);
+int setenv (const char *, const char *, int);
+# endif
+/* #elif defined other_platform || defined ... */
+#endif
+
+/* portability defines, excluding path handling macros */
+#if defined _MSC_VER
+# define setmode _setmode
+# define stat    _stat
+# define chmod   _chmod
+# define getcwd  _getcwd
+# define putenv  _putenv
+# define S_IXUSR _S_IEXEC
+#elif defined __MINGW32__
+# define setmode _setmode
+# define stat    _stat
+# define chmod   _chmod
+# define getcwd  _getcwd
+# define putenv  _putenv
+#elif defined __CYGWIN__
+# define HAVE_SETENV
+# define FOPEN_WB "wb"
+/* #elif defined other platforms ... */
+#endif
+
+#if defined PATH_MAX
+# define LT_PATHMAX PATH_MAX
+#elif defined MAXPATHLEN
+# define LT_PATHMAX MAXPATHLEN
+#else
+# define LT_PATHMAX 1024
+#endif
+
+#ifndef S_IXOTH
+# define S_IXOTH 0
+#endif
+#ifndef S_IXGRP
+# define S_IXGRP 0
+#endif
+
+/* path handling portability macros */
+#ifndef DIR_SEPARATOR
+# define DIR_SEPARATOR '/'
+# define PATH_SEPARATOR ':'
+#endif
+
+#if defined _WIN32 || defined __MSDOS__ || defined __DJGPP__ || \
+  defined __OS2__
+# define HAVE_DOS_BASED_FILE_SYSTEM
+# define FOPEN_WB "wb"
+# ifndef DIR_SEPARATOR_2
+#  define DIR_SEPARATOR_2 '\\'
+# endif
+# ifndef PATH_SEPARATOR_2
+#  define PATH_SEPARATOR_2 ';'
+# endif
+#endif
+
+#ifndef DIR_SEPARATOR_2
+# define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR)
+#else /* DIR_SEPARATOR_2 */
+# define IS_DIR_SEPARATOR(ch) \
+	(((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2))
+#endif /* DIR_SEPARATOR_2 */
+
+#ifndef PATH_SEPARATOR_2
+# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR)
+#else /* PATH_SEPARATOR_2 */
+# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR_2)
+#endif /* PATH_SEPARATOR_2 */
+
+#ifndef FOPEN_WB
+# define FOPEN_WB "w"
+#endif
+#ifndef _O_BINARY
+# define _O_BINARY 0
+#endif
+
+#define XMALLOC(type, num)      ((type *) xmalloc ((num) * sizeof(type)))
+#define XFREE(stale) do { \
+  if (stale) { free (stale); stale = 0; } \
+} while (0)
+
+#if defined LT_DEBUGWRAPPER
+static int lt_debug = 1;
+#else
+static int lt_debug = 0;
+#endif
+
+const char *program_name = "libtool-wrapper"; /* in case xstrdup fails */
+
+void *xmalloc (size_t num);
+char *xstrdup (const char *string);
+const char *base_name (const char *name);
+char *find_executable (const char *wrapper);
+char *chase_symlinks (const char *pathspec);
+int make_executable (const char *path);
+int check_executable (const char *path);
+char *strendzap (char *str, const char *pat);
+void lt_debugprintf (const char *file, int line, const char *fmt, ...);
+void lt_fatal (const char *file, int line, const char *message, ...);
+static const char *nonnull (const char *s);
+static const char *nonempty (const char *s);
+void lt_setenv (const char *name, const char *value);
+char *lt_extend_str (const char *orig_value, const char *add, int to_end);
+void lt_update_exe_path (const char *name, const char *value);
+void lt_update_lib_path (const char *name, const char *value);
+char **prepare_spawn (char **argv);
+void lt_dump_script (FILE *f);
+EOF
+
+	    cat <<EOF
+#if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 5)
+# define externally_visible volatile
+#else
+# define externally_visible __attribute__((externally_visible)) volatile
+#endif
+externally_visible const char * MAGIC_EXE = "$magic_exe";
+const char * LIB_PATH_VARNAME = "$shlibpath_var";
+EOF
+
+	    if test yes = "$shlibpath_overrides_runpath" && test -n "$shlibpath_var" && test -n "$temp_rpath"; then
+              func_to_host_path "$temp_rpath"
+	      cat <<EOF
+const char * LIB_PATH_VALUE   = "$func_to_host_path_result";
+EOF
+	    else
+	      cat <<"EOF"
+const char * LIB_PATH_VALUE   = "";
+EOF
+	    fi
+
+	    if test -n "$dllsearchpath"; then
+              func_to_host_path "$dllsearchpath:"
+	      cat <<EOF
+const char * EXE_PATH_VARNAME = "PATH";
+const char * EXE_PATH_VALUE   = "$func_to_host_path_result";
+EOF
+	    else
+	      cat <<"EOF"
+const char * EXE_PATH_VARNAME = "";
+const char * EXE_PATH_VALUE   = "";
+EOF
+	    fi
+
+	    if test yes = "$fast_install"; then
+	      cat <<EOF
+const char * TARGET_PROGRAM_NAME = "lt-$outputname"; /* hopefully, no .exe */
+EOF
+	    else
+	      cat <<EOF
+const char * TARGET_PROGRAM_NAME = "$outputname"; /* hopefully, no .exe */
+EOF
+	    fi
+
+
+	    cat <<"EOF"
+
+#define LTWRAPPER_OPTION_PREFIX         "--lt-"
+
+static const char *ltwrapper_option_prefix = LTWRAPPER_OPTION_PREFIX;
+static const char *dumpscript_opt       = LTWRAPPER_OPTION_PREFIX "dump-script";
+static const char *debug_opt            = LTWRAPPER_OPTION_PREFIX "debug";
+
+int
+main (int argc, char *argv[])
+{
+  char **newargz;
+  int  newargc;
+  char *tmp_pathspec;
+  char *actual_cwrapper_path;
+  char *actual_cwrapper_name;
+  char *target_name;
+  char *lt_argv_zero;
+  int rval = 127;
+
+  int i;
+
+  program_name = (char *) xstrdup (base_name (argv[0]));
+  newargz = XMALLOC (char *, (size_t) argc + 1);
+
+  /* very simple arg parsing; don't want to rely on getopt
+   * also, copy all non cwrapper options to newargz, except
+   * argz[0], which is handled differently
+   */
+  newargc=0;
+  for (i = 1; i < argc; i++)
+    {
+      if (STREQ (argv[i], dumpscript_opt))
+	{
+EOF
+	    case $host in
+	      *mingw* | *cygwin* )
+		# make stdout use "unix" line endings
+		echo "          setmode(1,_O_BINARY);"
+		;;
+	      esac
+
+	    cat <<"EOF"
+	  lt_dump_script (stdout);
+	  return 0;
+	}
+      if (STREQ (argv[i], debug_opt))
+	{
+          lt_debug = 1;
+          continue;
+	}
+      if (STREQ (argv[i], ltwrapper_option_prefix))
+        {
+          /* however, if there is an option in the LTWRAPPER_OPTION_PREFIX
+             namespace, but it is not one of the ones we know about and
+             have already dealt with, above (inluding dump-script), then
+             report an error. Otherwise, targets might begin to believe
+             they are allowed to use options in the LTWRAPPER_OPTION_PREFIX
+             namespace. The first time any user complains about this, we'll
+             need to make LTWRAPPER_OPTION_PREFIX a configure-time option
+             or a configure.ac-settable value.
+           */
+          lt_fatal (__FILE__, __LINE__,
+		    "unrecognized %s option: '%s'",
+                    ltwrapper_option_prefix, argv[i]);
+        }
+      /* otherwise ... */
+      newargz[++newargc] = xstrdup (argv[i]);
+    }
+  newargz[++newargc] = NULL;
+
+EOF
+	    cat <<EOF
+  /* The GNU banner must be the first non-error debug message */
+  lt_debugprintf (__FILE__, __LINE__, "libtool wrapper (GNU $PACKAGE) $VERSION\n");
+EOF
+	    cat <<"EOF"
+  lt_debugprintf (__FILE__, __LINE__, "(main) argv[0]: %s\n", argv[0]);
+  lt_debugprintf (__FILE__, __LINE__, "(main) program_name: %s\n", program_name);
+
+  tmp_pathspec = find_executable (argv[0]);
+  if (tmp_pathspec == NULL)
+    lt_fatal (__FILE__, __LINE__, "couldn't find %s", argv[0]);
+  lt_debugprintf (__FILE__, __LINE__,
+                  "(main) found exe (before symlink chase) at: %s\n",
+		  tmp_pathspec);
+
+  actual_cwrapper_path = chase_symlinks (tmp_pathspec);
+  lt_debugprintf (__FILE__, __LINE__,
+                  "(main) found exe (after symlink chase) at: %s\n",
+		  actual_cwrapper_path);
+  XFREE (tmp_pathspec);
+
+  actual_cwrapper_name = xstrdup (base_name (actual_cwrapper_path));
+  strendzap (actual_cwrapper_path, actual_cwrapper_name);
+
+  /* wrapper name transforms */
+  strendzap (actual_cwrapper_name, ".exe");
+  tmp_pathspec = lt_extend_str (actual_cwrapper_name, ".exe", 1);
+  XFREE (actual_cwrapper_name);
+  actual_cwrapper_name = tmp_pathspec;
+  tmp_pathspec = 0;
+
+  /* target_name transforms -- use actual target program name; might have lt- prefix */
+  target_name = xstrdup (base_name (TARGET_PROGRAM_NAME));
+  strendzap (target_name, ".exe");
+  tmp_pathspec = lt_extend_str (target_name, ".exe", 1);
+  XFREE (target_name);
+  target_name = tmp_pathspec;
+  tmp_pathspec = 0;
+
+  lt_debugprintf (__FILE__, __LINE__,
+		  "(main) libtool target name: %s\n",
+		  target_name);
+EOF
+
+	    cat <<EOF
+  newargz[0] =
+    XMALLOC (char, (strlen (actual_cwrapper_path) +
+		    strlen ("$objdir") + 1 + strlen (actual_cwrapper_name) + 1));
+  strcpy (newargz[0], actual_cwrapper_path);
+  strcat (newargz[0], "$objdir");
+  strcat (newargz[0], "/");
+EOF
+
+	    cat <<"EOF"
+  /* stop here, and copy so we don't have to do this twice */
+  tmp_pathspec = xstrdup (newargz[0]);
+
+  /* do NOT want the lt- prefix here, so use actual_cwrapper_name */
+  strcat (newargz[0], actual_cwrapper_name);
+
+  /* DO want the lt- prefix here if it exists, so use target_name */
+  lt_argv_zero = lt_extend_str (tmp_pathspec, target_name, 1);
+  XFREE (tmp_pathspec);
+  tmp_pathspec = NULL;
+EOF
+
+	    case $host_os in
+	      mingw*)
+	    cat <<"EOF"
+  {
+    char* p;
+    while ((p = strchr (newargz[0], '\\')) != NULL)
+      {
+	*p = '/';
+      }
+    while ((p = strchr (lt_argv_zero, '\\')) != NULL)
+      {
+	*p = '/';
+      }
+  }
+EOF
+	    ;;
+	    esac
+
+	    cat <<"EOF"
+  XFREE (target_name);
+  XFREE (actual_cwrapper_path);
+  XFREE (actual_cwrapper_name);
+
+  lt_setenv ("BIN_SH", "xpg4"); /* for Tru64 */
+  lt_setenv ("DUALCASE", "1");  /* for MSK sh */
+  /* Update the DLL searchpath.  EXE_PATH_VALUE ($dllsearchpath) must
+     be prepended before (that is, appear after) LIB_PATH_VALUE ($temp_rpath)
+     because on Windows, both *_VARNAMEs are PATH but uninstalled
+     libraries must come first. */
+  lt_update_exe_path (EXE_PATH_VARNAME, EXE_PATH_VALUE);
+  lt_update_lib_path (LIB_PATH_VARNAME, LIB_PATH_VALUE);
+
+  lt_debugprintf (__FILE__, __LINE__, "(main) lt_argv_zero: %s\n",
+		  nonnull (lt_argv_zero));
+  for (i = 0; i < newargc; i++)
+    {
+      lt_debugprintf (__FILE__, __LINE__, "(main) newargz[%d]: %s\n",
+		      i, nonnull (newargz[i]));
+    }
+
+EOF
+
+	    case $host_os in
+	      mingw*)
+		cat <<"EOF"
+  /* execv doesn't actually work on mingw as expected on unix */
+  newargz = prepare_spawn (newargz);
+  rval = (int) _spawnv (_P_WAIT, lt_argv_zero, (const char * const *) newargz);
+  if (rval == -1)
+    {
+      /* failed to start process */
+      lt_debugprintf (__FILE__, __LINE__,
+		      "(main) failed to launch target \"%s\": %s\n",
+		      lt_argv_zero, nonnull (strerror (errno)));
+      return 127;
+    }
+  return rval;
+EOF
+		;;
+	      *)
+		cat <<"EOF"
+  execv (lt_argv_zero, newargz);
+  return rval; /* =127, but avoids unused variable warning */
+EOF
+		;;
+	    esac
+
+	    cat <<"EOF"
+}
+
+void *
+xmalloc (size_t num)
+{
+  void *p = (void *) malloc (num);
+  if (!p)
+    lt_fatal (__FILE__, __LINE__, "memory exhausted");
+
+  return p;
+}
+
+char *
+xstrdup (const char *string)
+{
+  return string ? strcpy ((char *) xmalloc (strlen (string) + 1),
+			  string) : NULL;
+}
+
+const char *
+base_name (const char *name)
+{
+  const char *base;
+
+#if defined HAVE_DOS_BASED_FILE_SYSTEM
+  /* Skip over the disk name in MSDOS pathnames. */
+  if (isalpha ((unsigned char) name[0]) && name[1] == ':')
+    name += 2;
+#endif
+
+  for (base = name; *name; name++)
+    if (IS_DIR_SEPARATOR (*name))
+      base = name + 1;
+  return base;
+}
+
+int
+check_executable (const char *path)
+{
+  struct stat st;
+
+  lt_debugprintf (__FILE__, __LINE__, "(check_executable): %s\n",
+                  nonempty (path));
+  if ((!path) || (!*path))
+    return 0;
+
+  if ((stat (path, &st) >= 0)
+      && (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH)))
+    return 1;
+  else
+    return 0;
+}
+
+int
+make_executable (const char *path)
+{
+  int rval = 0;
+  struct stat st;
+
+  lt_debugprintf (__FILE__, __LINE__, "(make_executable): %s\n",
+                  nonempty (path));
+  if ((!path) || (!*path))
+    return 0;
+
+  if (stat (path, &st) >= 0)
+    {
+      rval = chmod (path, st.st_mode | S_IXOTH | S_IXGRP | S_IXUSR);
+    }
+  return rval;
+}
+
+/* Searches for the full path of the wrapper.  Returns
+   newly allocated full path name if found, NULL otherwise
+   Does not chase symlinks, even on platforms that support them.
+*/
+char *
+find_executable (const char *wrapper)
+{
+  int has_slash = 0;
+  const char *p;
+  const char *p_next;
+  /* static buffer for getcwd */
+  char tmp[LT_PATHMAX + 1];
+  size_t tmp_len;
+  char *concat_name;
+
+  lt_debugprintf (__FILE__, __LINE__, "(find_executable): %s\n",
+                  nonempty (wrapper));
+
+  if ((wrapper == NULL) || (*wrapper == '\0'))
+    return NULL;
+
+  /* Absolute path? */
+#if defined HAVE_DOS_BASED_FILE_SYSTEM
+  if (isalpha ((unsigned char) wrapper[0]) && wrapper[1] == ':')
+    {
+      concat_name = xstrdup (wrapper);
+      if (check_executable (concat_name))
+	return concat_name;
+      XFREE (concat_name);
+    }
+  else
+    {
+#endif
+      if (IS_DIR_SEPARATOR (wrapper[0]))
+	{
+	  concat_name = xstrdup (wrapper);
+	  if (check_executable (concat_name))
+	    return concat_name;
+	  XFREE (concat_name);
+	}
+#if defined HAVE_DOS_BASED_FILE_SYSTEM
+    }
+#endif
+
+  for (p = wrapper; *p; p++)
+    if (*p == '/')
+      {
+	has_slash = 1;
+	break;
+      }
+  if (!has_slash)
+    {
+      /* no slashes; search PATH */
+      const char *path = getenv ("PATH");
+      if (path != NULL)
+	{
+	  for (p = path; *p; p = p_next)
+	    {
+	      const char *q;
+	      size_t p_len;
+	      for (q = p; *q; q++)
+		if (IS_PATH_SEPARATOR (*q))
+		  break;
+	      p_len = (size_t) (q - p);
+	      p_next = (*q == '\0' ? q : q + 1);
+	      if (p_len == 0)
+		{
+		  /* empty path: current directory */
+		  if (getcwd (tmp, LT_PATHMAX) == NULL)
+		    lt_fatal (__FILE__, __LINE__, "getcwd failed: %s",
+                              nonnull (strerror (errno)));
+		  tmp_len = strlen (tmp);
+		  concat_name =
+		    XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1);
+		  memcpy (concat_name, tmp, tmp_len);
+		  concat_name[tmp_len] = '/';
+		  strcpy (concat_name + tmp_len + 1, wrapper);
+		}
+	      else
+		{
+		  concat_name =
+		    XMALLOC (char, p_len + 1 + strlen (wrapper) + 1);
+		  memcpy (concat_name, p, p_len);
+		  concat_name[p_len] = '/';
+		  strcpy (concat_name + p_len + 1, wrapper);
+		}
+	      if (check_executable (concat_name))
+		return concat_name;
+	      XFREE (concat_name);
+	    }
+	}
+      /* not found in PATH; assume curdir */
+    }
+  /* Relative path | not found in path: prepend cwd */
+  if (getcwd (tmp, LT_PATHMAX) == NULL)
+    lt_fatal (__FILE__, __LINE__, "getcwd failed: %s",
+              nonnull (strerror (errno)));
+  tmp_len = strlen (tmp);
+  concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1);
+  memcpy (concat_name, tmp, tmp_len);
+  concat_name[tmp_len] = '/';
+  strcpy (concat_name + tmp_len + 1, wrapper);
+
+  if (check_executable (concat_name))
+    return concat_name;
+  XFREE (concat_name);
+  return NULL;
+}
+
+char *
+chase_symlinks (const char *pathspec)
+{
+#ifndef S_ISLNK
+  return xstrdup (pathspec);
+#else
+  char buf[LT_PATHMAX];
+  struct stat s;
+  char *tmp_pathspec = xstrdup (pathspec);
+  char *p;
+  int has_symlinks = 0;
+  while (strlen (tmp_pathspec) && !has_symlinks)
+    {
+      lt_debugprintf (__FILE__, __LINE__,
+		      "checking path component for symlinks: %s\n",
+		      tmp_pathspec);
+      if (lstat (tmp_pathspec, &s) == 0)
+	{
+	  if (S_ISLNK (s.st_mode) != 0)
+	    {
+	      has_symlinks = 1;
+	      break;
+	    }
+
+	  /* search backwards for last DIR_SEPARATOR */
+	  p = tmp_pathspec + strlen (tmp_pathspec) - 1;
+	  while ((p > tmp_pathspec) && (!IS_DIR_SEPARATOR (*p)))
+	    p--;
+	  if ((p == tmp_pathspec) && (!IS_DIR_SEPARATOR (*p)))
+	    {
+	      /* no more DIR_SEPARATORS left */
+	      break;
+	    }
+	  *p = '\0';
+	}
+      else
+	{
+	  lt_fatal (__FILE__, __LINE__,
+		    "error accessing file \"%s\": %s",
+		    tmp_pathspec, nonnull (strerror (errno)));
+	}
+    }
+  XFREE (tmp_pathspec);
+
+  if (!has_symlinks)
+    {
+      return xstrdup (pathspec);
+    }
+
+  tmp_pathspec = realpath (pathspec, buf);
+  if (tmp_pathspec == 0)
+    {
+      lt_fatal (__FILE__, __LINE__,
+		"could not follow symlinks for %s", pathspec);
+    }
+  return xstrdup (tmp_pathspec);
+#endif
+}
+
+char *
+strendzap (char *str, const char *pat)
+{
+  size_t len, patlen;
+
+  assert (str != NULL);
+  assert (pat != NULL);
+
+  len = strlen (str);
+  patlen = strlen (pat);
+
+  if (patlen <= len)
+    {
+      str += len - patlen;
+      if (STREQ (str, pat))
+	*str = '\0';
+    }
+  return str;
+}
+
+void
+lt_debugprintf (const char *file, int line, const char *fmt, ...)
+{
+  va_list args;
+  if (lt_debug)
+    {
+      (void) fprintf (stderr, "%s:%s:%d: ", program_name, file, line);
+      va_start (args, fmt);
+      (void) vfprintf (stderr, fmt, args);
+      va_end (args);
+    }
+}
+
+static void
+lt_error_core (int exit_status, const char *file,
+	       int line, const char *mode,
+	       const char *message, va_list ap)
+{
+  fprintf (stderr, "%s:%s:%d: %s: ", program_name, file, line, mode);
+  vfprintf (stderr, message, ap);
+  fprintf (stderr, ".\n");
+
+  if (exit_status >= 0)
+    exit (exit_status);
+}
+
+void
+lt_fatal (const char *file, int line, const char *message, ...)
+{
+  va_list ap;
+  va_start (ap, message);
+  lt_error_core (EXIT_FAILURE, file, line, "FATAL", message, ap);
+  va_end (ap);
+}
+
+static const char *
+nonnull (const char *s)
+{
+  return s ? s : "(null)";
+}
+
+static const char *
+nonempty (const char *s)
+{
+  return (s && !*s) ? "(empty)" : nonnull (s);
+}
+
+void
+lt_setenv (const char *name, const char *value)
+{
+  lt_debugprintf (__FILE__, __LINE__,
+		  "(lt_setenv) setting '%s' to '%s'\n",
+                  nonnull (name), nonnull (value));
+  {
+#ifdef HAVE_SETENV
+    /* always make a copy, for consistency with !HAVE_SETENV */
+    char *str = xstrdup (value);
+    setenv (name, str, 1);
+#else
+    size_t len = strlen (name) + 1 + strlen (value) + 1;
+    char *str = XMALLOC (char, len);
+    sprintf (str, "%s=%s", name, value);
+    if (putenv (str) != EXIT_SUCCESS)
+      {
+        XFREE (str);
+      }
+#endif
+  }
+}
+
+char *
+lt_extend_str (const char *orig_value, const char *add, int to_end)
+{
+  char *new_value;
+  if (orig_value && *orig_value)
+    {
+      size_t orig_value_len = strlen (orig_value);
+      size_t add_len = strlen (add);
+      new_value = XMALLOC (char, add_len + orig_value_len + 1);
+      if (to_end)
+        {
+          strcpy (new_value, orig_value);
+          strcpy (new_value + orig_value_len, add);
+        }
+      else
+        {
+          strcpy (new_value, add);
+          strcpy (new_value + add_len, orig_value);
+        }
+    }
+  else
+    {
+      new_value = xstrdup (add);
+    }
+  return new_value;
+}
+
+void
+lt_update_exe_path (const char *name, const char *value)
+{
+  lt_debugprintf (__FILE__, __LINE__,
+		  "(lt_update_exe_path) modifying '%s' by prepending '%s'\n",
+                  nonnull (name), nonnull (value));
+
+  if (name && *name && value && *value)
+    {
+      char *new_value = lt_extend_str (getenv (name), value, 0);
+      /* some systems can't cope with a ':'-terminated path #' */
+      size_t len = strlen (new_value);
+      while ((len > 0) && IS_PATH_SEPARATOR (new_value[len-1]))
+        {
+          new_value[--len] = '\0';
+        }
+      lt_setenv (name, new_value);
+      XFREE (new_value);
+    }
+}
+
+void
+lt_update_lib_path (const char *name, const char *value)
+{
+  lt_debugprintf (__FILE__, __LINE__,
+		  "(lt_update_lib_path) modifying '%s' by prepending '%s'\n",
+                  nonnull (name), nonnull (value));
+
+  if (name && *name && value && *value)
+    {
+      char *new_value = lt_extend_str (getenv (name), value, 0);
+      lt_setenv (name, new_value);
+      XFREE (new_value);
+    }
+}
+
+EOF
+	    case $host_os in
+	      mingw*)
+		cat <<"EOF"
+
+/* Prepares an argument vector before calling spawn().
+   Note that spawn() does not by itself call the command interpreter
+     (getenv ("COMSPEC") != NULL ? getenv ("COMSPEC") :
+      ({ OSVERSIONINFO v; v.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+         GetVersionEx(&v);
+         v.dwPlatformId == VER_PLATFORM_WIN32_NT;
+      }) ? "cmd.exe" : "command.com").
+   Instead it simply concatenates the arguments, separated by ' ', and calls
+   CreateProcess().  We must quote the arguments since Win32 CreateProcess()
+   interprets characters like ' ', '\t', '\\', '"' (but not '<' and '>') in a
+   special way:
+   - Space and tab are interpreted as delimiters. They are not treated as
+     delimiters if they are surrounded by double quotes: "...".
+   - Unescaped double quotes are removed from the input. Their only effect is
+     that within double quotes, space and tab are treated like normal
+     characters.
+   - Backslashes not followed by double quotes are not special.
+   - But 2*n+1 backslashes followed by a double quote become
+     n backslashes followed by a double quote (n >= 0):
+       \" -> "
+       \\\" -> \"
+       \\\\\" -> \\"
+ */
+#define SHELL_SPECIAL_CHARS "\"\\ \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037"
+#define SHELL_SPACE_CHARS " \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037"
+char **
+prepare_spawn (char **argv)
+{
+  size_t argc;
+  char **new_argv;
+  size_t i;
+
+  /* Count number of arguments.  */
+  for (argc = 0; argv[argc] != NULL; argc++)
+    ;
+
+  /* Allocate new argument vector.  */
+  new_argv = XMALLOC (char *, argc + 1);
+
+  /* Put quoted arguments into the new argument vector.  */
+  for (i = 0; i < argc; i++)
+    {
+      const char *string = argv[i];
+
+      if (string[0] == '\0')
+	new_argv[i] = xstrdup ("\"\"");
+      else if (strpbrk (string, SHELL_SPECIAL_CHARS) != NULL)
+	{
+	  int quote_around = (strpbrk (string, SHELL_SPACE_CHARS) != NULL);
+	  size_t length;
+	  unsigned int backslashes;
+	  const char *s;
+	  char *quoted_string;
+	  char *p;
+
+	  length = 0;
+	  backslashes = 0;
+	  if (quote_around)
+	    length++;
+	  for (s = string; *s != '\0'; s++)
+	    {
+	      char c = *s;
+	      if (c == '"')
+		length += backslashes + 1;
+	      length++;
+	      if (c == '\\')
+		backslashes++;
+	      else
+		backslashes = 0;
+	    }
+	  if (quote_around)
+	    length += backslashes + 1;
+
+	  quoted_string = XMALLOC (char, length + 1);
+
+	  p = quoted_string;
+	  backslashes = 0;
+	  if (quote_around)
+	    *p++ = '"';
+	  for (s = string; *s != '\0'; s++)
+	    {
+	      char c = *s;
+	      if (c == '"')
+		{
+		  unsigned int j;
+		  for (j = backslashes + 1; j > 0; j--)
+		    *p++ = '\\';
+		}
+	      *p++ = c;
+	      if (c == '\\')
+		backslashes++;
+	      else
+		backslashes = 0;
+	    }
+	  if (quote_around)
+	    {
+	      unsigned int j;
+	      for (j = backslashes; j > 0; j--)
+		*p++ = '\\';
+	      *p++ = '"';
+	    }
+	  *p = '\0';
+
+	  new_argv[i] = quoted_string;
+	}
+      else
+	new_argv[i] = (char *) string;
+    }
+  new_argv[argc] = NULL;
+
+  return new_argv;
+}
+EOF
+		;;
+	    esac
+
+            cat <<"EOF"
+void lt_dump_script (FILE* f)
+{
+EOF
+	    func_emit_wrapper yes |
+	      $SED -n -e '
+s/^\(.\{79\}\)\(..*\)/\1\
+\2/
+h
+s/\([\\"]\)/\\\1/g
+s/$/\\n/
+s/\([^\n]*\).*/  fputs ("\1", f);/p
+g
+D'
+            cat <<"EOF"
+}
+EOF
+}
+# end: func_emit_cwrapperexe_src
+
+# func_win32_import_lib_p ARG
+# True if ARG is an import lib, as indicated by $file_magic_cmd
+func_win32_import_lib_p ()
+{
+    $debug_cmd
+
+    case `eval $file_magic_cmd \"\$1\" 2>/dev/null | $SED -e 10q` in
+    *import*) : ;;
+    *) false ;;
+    esac
+}
+
+# func_suncc_cstd_abi
+# !!ONLY CALL THIS FOR SUN CC AFTER $compile_command IS FULLY EXPANDED!!
+# Several compiler flags select an ABI that is incompatible with the
+# Cstd library. Avoid specifying it if any are in CXXFLAGS.
+func_suncc_cstd_abi ()
+{
+    $debug_cmd
+
+    case " $compile_command " in
+    *" -compat=g "*|*\ -std=c++[0-9][0-9]\ *|*" -library=stdcxx4 "*|*" -library=stlport4 "*)
+      suncc_use_cstd_abi=no
+      ;;
+    *)
+      suncc_use_cstd_abi=yes
+      ;;
+    esac
+}
+
+# func_mode_link arg...
+func_mode_link ()
+{
+    $debug_cmd
+
+    case $host in
+    *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*)
+      # It is impossible to link a dll without this setting, and
+      # we shouldn't force the makefile maintainer to figure out
+      # what system we are compiling for in order to pass an extra
+      # flag for every libtool invocation.
+      # allow_undefined=no
+
+      # FIXME: Unfortunately, there are problems with the above when trying
+      # to make a dll that has undefined symbols, in which case not
+      # even a static library is built.  For now, we need to specify
+      # -no-undefined on the libtool link line when we can be certain
+      # that all symbols are satisfied, otherwise we get a static library.
+      allow_undefined=yes
+      ;;
+    *)
+      allow_undefined=yes
+      ;;
+    esac
+    libtool_args=$nonopt
+    base_compile="$nonopt $@"
+    compile_command=$nonopt
+    finalize_command=$nonopt
+
+    compile_rpath=
+    finalize_rpath=
+    compile_shlibpath=
+    finalize_shlibpath=
+    convenience=
+    old_convenience=
+    deplibs=
+    old_deplibs=
+    compiler_flags=
+    linker_flags=
+    dllsearchpath=
+    lib_search_path=`pwd`
+    inst_prefix_dir=
+    new_inherited_linker_flags=
+
+    avoid_version=no
+    bindir=
+    dlfiles=
+    dlprefiles=
+    dlself=no
+    export_dynamic=no
+    export_symbols=
+    export_symbols_regex=
+    generated=
+    libobjs=
+    ltlibs=
+    module=no
+    no_install=no
+    objs=
+    os2dllname=
+    non_pic_objects=
+    precious_files_regex=
+    prefer_static_libs=no
+    preload=false
+    prev=
+    prevarg=
+    release=
+    rpath=
+    xrpath=
+    perm_rpath=
+    temp_rpath=
+    thread_safe=no
+    vinfo=
+    vinfo_number=no
+    weak_libs=
+    single_module=$wl-single_module
+    func_infer_tag $base_compile
+
+    # We need to know -static, to get the right output filenames.
+    for arg
+    do
+      case $arg in
+      -shared)
+	test yes != "$build_libtool_libs" \
+	  && func_fatal_configuration "cannot build a shared library"
+	build_old_libs=no
+	break
+	;;
+      -all-static | -static | -static-libtool-libs)
+	case $arg in
+	-all-static)
+	  if test yes = "$build_libtool_libs" && test -z "$link_static_flag"; then
+	    func_warning "complete static linking is impossible in this configuration"
+	  fi
+	  if test -n "$link_static_flag"; then
+	    dlopen_self=$dlopen_self_static
+	  fi
+	  prefer_static_libs=yes
+	  ;;
+	-static)
+	  if test -z "$pic_flag" && test -n "$link_static_flag"; then
+	    dlopen_self=$dlopen_self_static
+	  fi
+	  prefer_static_libs=built
+	  ;;
+	-static-libtool-libs)
+	  if test -z "$pic_flag" && test -n "$link_static_flag"; then
+	    dlopen_self=$dlopen_self_static
+	  fi
+	  prefer_static_libs=yes
+	  ;;
+	esac
+	build_libtool_libs=no
+	build_old_libs=yes
+	break
+	;;
+      esac
+    done
+
+    # See if our shared archives depend on static archives.
+    test -n "$old_archive_from_new_cmds" && build_old_libs=yes
+
+    # Go through the arguments, transforming them on the way.
+    while test "$#" -gt 0; do
+      arg=$1
+      shift
+      func_quote_for_eval "$arg"
+      qarg=$func_quote_for_eval_unquoted_result
+      func_append libtool_args " $func_quote_for_eval_result"
+
+      # If the previous option needs an argument, assign it.
+      if test -n "$prev"; then
+	case $prev in
+	output)
+	  func_append compile_command " @OUTPUT@"
+	  func_append finalize_command " @OUTPUT@"
+	  ;;
+	esac
+
+	case $prev in
+	bindir)
+	  bindir=$arg
+	  prev=
+	  continue
+	  ;;
+	dlfiles|dlprefiles)
+	  $preload || {
+	    # Add the symbol object into the linking commands.
+	    func_append compile_command " @SYMFILE@"
+	    func_append finalize_command " @SYMFILE@"
+	    preload=:
+	  }
+	  case $arg in
+	  *.la | *.lo) ;;  # We handle these cases below.
+	  force)
+	    if test no = "$dlself"; then
+	      dlself=needless
+	      export_dynamic=yes
+	    fi
+	    prev=
+	    continue
+	    ;;
+	  self)
+	    if test dlprefiles = "$prev"; then
+	      dlself=yes
+	    elif test dlfiles = "$prev" && test yes != "$dlopen_self"; then
+	      dlself=yes
+	    else
+	      dlself=needless
+	      export_dynamic=yes
+	    fi
+	    prev=
+	    continue
+	    ;;
+	  *)
+	    if test dlfiles = "$prev"; then
+	      func_append dlfiles " $arg"
+	    else
+	      func_append dlprefiles " $arg"
+	    fi
+	    prev=
+	    continue
+	    ;;
+	  esac
+	  ;;
+	expsyms)
+	  export_symbols=$arg
+	  test -f "$arg" \
+	    || func_fatal_error "symbol file '$arg' does not exist"
+	  prev=
+	  continue
+	  ;;
+	expsyms_regex)
+	  export_symbols_regex=$arg
+	  prev=
+	  continue
+	  ;;
+	framework)
+	  case $host in
+	    *-*-darwin*)
+	      case "$deplibs " in
+		*" $qarg.ltframework "*) ;;
+		*) func_append deplibs " $qarg.ltframework" # this is fixed later
+		   ;;
+	      esac
+	      ;;
+	  esac
+	  prev=
+	  continue
+	  ;;
+	inst_prefix)
+	  inst_prefix_dir=$arg
+	  prev=
+	  continue
+	  ;;
+	mllvm)
+	  # Clang does not use LLVM to link, so we can simply discard any
+	  # '-mllvm $arg' options when doing the link step.
+	  prev=
+	  continue
+	  ;;
+	objectlist)
+	  if test -f "$arg"; then
+	    save_arg=$arg
+	    moreargs=
+	    for fil in `cat "$save_arg"`
+	    do
+#	      func_append moreargs " $fil"
+	      arg=$fil
+	      # A libtool-controlled object.
+
+	      # Check to see that this really is a libtool object.
+	      if func_lalib_unsafe_p "$arg"; then
+		pic_object=
+		non_pic_object=
+
+		# Read the .lo file
+		func_source "$arg"
+
+		if test -z "$pic_object" ||
+		   test -z "$non_pic_object" ||
+		   test none = "$pic_object" &&
+		   test none = "$non_pic_object"; then
+		  func_fatal_error "cannot find name of object for '$arg'"
+		fi
+
+		# Extract subdirectory from the argument.
+		func_dirname "$arg" "/" ""
+		xdir=$func_dirname_result
+
+		if test none != "$pic_object"; then
+		  # Prepend the subdirectory the object is found in.
+		  pic_object=$xdir$pic_object
+
+		  if test dlfiles = "$prev"; then
+		    if test yes = "$build_libtool_libs" && test yes = "$dlopen_support"; then
+		      func_append dlfiles " $pic_object"
+		      prev=
+		      continue
+		    else
+		      # If libtool objects are unsupported, then we need to preload.
+		      prev=dlprefiles
+		    fi
+		  fi
+
+		  # CHECK ME:  I think I busted this.  -Ossama
+		  if test dlprefiles = "$prev"; then
+		    # Preload the old-style object.
+		    func_append dlprefiles " $pic_object"
+		    prev=
+		  fi
+
+		  # A PIC object.
+		  func_append libobjs " $pic_object"
+		  arg=$pic_object
+		fi
+
+		# Non-PIC object.
+		if test none != "$non_pic_object"; then
+		  # Prepend the subdirectory the object is found in.
+		  non_pic_object=$xdir$non_pic_object
+
+		  # A standard non-PIC object
+		  func_append non_pic_objects " $non_pic_object"
+		  if test -z "$pic_object" || test none = "$pic_object"; then
+		    arg=$non_pic_object
+		  fi
+		else
+		  # If the PIC object exists, use it instead.
+		  # $xdir was prepended to $pic_object above.
+		  non_pic_object=$pic_object
+		  func_append non_pic_objects " $non_pic_object"
+		fi
+	      else
+		# Only an error if not doing a dry-run.
+		if $opt_dry_run; then
+		  # Extract subdirectory from the argument.
+		  func_dirname "$arg" "/" ""
+		  xdir=$func_dirname_result
+
+		  func_lo2o "$arg"
+		  pic_object=$xdir$objdir/$func_lo2o_result
+		  non_pic_object=$xdir$func_lo2o_result
+		  func_append libobjs " $pic_object"
+		  func_append non_pic_objects " $non_pic_object"
+	        else
+		  func_fatal_error "'$arg' is not a valid libtool object"
+		fi
+	      fi
+	    done
+	  else
+	    func_fatal_error "link input file '$arg' does not exist"
+	  fi
+	  arg=$save_arg
+	  prev=
+	  continue
+	  ;;
+	os2dllname)
+	  os2dllname=$arg
+	  prev=
+	  continue
+	  ;;
+	precious_regex)
+	  precious_files_regex=$arg
+	  prev=
+	  continue
+	  ;;
+	release)
+	  release=-$arg
+	  prev=
+	  continue
+	  ;;
+	rpath | xrpath)
+	  # We need an absolute path.
+	  case $arg in
+	  [\\/]* | [A-Za-z]:[\\/]*) ;;
+	  *)
+	    func_fatal_error "only absolute run-paths are allowed"
+	    ;;
+	  esac
+	  if test rpath = "$prev"; then
+	    case "$rpath " in
+	    *" $arg "*) ;;
+	    *) func_append rpath " $arg" ;;
+	    esac
+	  else
+	    case "$xrpath " in
+	    *" $arg "*) ;;
+	    *) func_append xrpath " $arg" ;;
+	    esac
+	  fi
+	  prev=
+	  continue
+	  ;;
+	shrext)
+	  shrext_cmds=$arg
+	  prev=
+	  continue
+	  ;;
+	weak)
+	  func_append weak_libs " $arg"
+	  prev=
+	  continue
+	  ;;
+	xcclinker)
+	  func_append linker_flags " $qarg"
+	  func_append compiler_flags " $qarg"
+	  prev=
+	  func_append compile_command " $qarg"
+	  func_append finalize_command " $qarg"
+	  continue
+	  ;;
+	xcompiler)
+	  func_append compiler_flags " $qarg"
+	  prev=
+	  func_append compile_command " $qarg"
+	  func_append finalize_command " $qarg"
+	  continue
+	  ;;
+	xlinker)
+	  func_append linker_flags " $qarg"
+	  func_append compiler_flags " $wl$qarg"
+	  prev=
+	  func_append compile_command " $wl$qarg"
+	  func_append finalize_command " $wl$qarg"
+	  continue
+	  ;;
+	*)
+	  eval "$prev=\"\$arg\""
+	  prev=
+	  continue
+	  ;;
+	esac
+      fi # test -n "$prev"
+
+      prevarg=$arg
+
+      case $arg in
+      -all-static)
+	if test -n "$link_static_flag"; then
+	  # See comment for -static flag below, for more details.
+	  func_append compile_command " $link_static_flag"
+	  func_append finalize_command " $link_static_flag"
+	fi
+	continue
+	;;
+
+      -allow-undefined)
+	# FIXME: remove this flag sometime in the future.
+	func_fatal_error "'-allow-undefined' must not be used because it is the default"
+	;;
+
+      -avoid-version)
+	avoid_version=yes
+	continue
+	;;
+
+      -bindir)
+	prev=bindir
+	continue
+	;;
+
+      -dlopen)
+	prev=dlfiles
+	continue
+	;;
+
+      -dlpreopen)
+	prev=dlprefiles
+	continue
+	;;
+
+      -export-dynamic)
+	export_dynamic=yes
+	continue
+	;;
+
+      -export-symbols | -export-symbols-regex)
+	if test -n "$export_symbols" || test -n "$export_symbols_regex"; then
+	  func_fatal_error "more than one -exported-symbols argument is not allowed"
+	fi
+	if test X-export-symbols = "X$arg"; then
+	  prev=expsyms
+	else
+	  prev=expsyms_regex
+	fi
+	continue
+	;;
+
+      -framework)
+	prev=framework
+	continue
+	;;
+
+      -inst-prefix-dir)
+	prev=inst_prefix
+	continue
+	;;
+
+      # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:*
+      # so, if we see these flags be careful not to treat them like -L
+      -L[A-Z][A-Z]*:*)
+	case $with_gcc/$host in
+	no/*-*-irix* | /*-*-irix*)
+	  func_append compile_command " $arg"
+	  func_append finalize_command " $arg"
+	  ;;
+	esac
+	continue
+	;;
+
+      -L*)
+	func_stripname "-L" '' "$arg"
+	if test -z "$func_stripname_result"; then
+	  if test "$#" -gt 0; then
+	    func_fatal_error "require no space between '-L' and '$1'"
+	  else
+	    func_fatal_error "need path for '-L' option"
+	  fi
+	fi
+	func_resolve_sysroot "$func_stripname_result"
+	dir=$func_resolve_sysroot_result
+	# We need an absolute path.
+	case $dir in
+	[\\/]* | [A-Za-z]:[\\/]*) ;;
+	*)
+	  absdir=`cd "$dir" && pwd`
+	  test -z "$absdir" && \
+	    func_fatal_error "cannot determine absolute directory name of '$dir'"
+	  dir=$absdir
+	  ;;
+	esac
+	case "$deplibs " in
+	*" -L$dir "* | *" $arg "*)
+	  # Will only happen for absolute or sysroot arguments
+	  ;;
+	*)
+	  # Preserve sysroot, but never include relative directories
+	  case $dir in
+	    [\\/]* | [A-Za-z]:[\\/]* | =*) func_append deplibs " $arg" ;;
+	    *) func_append deplibs " -L$dir" ;;
+	  esac
+	  func_append lib_search_path " $dir"
+	  ;;
+	esac
+	case $host in
+	*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*)
+	  testbindir=`$ECHO "$dir" | $SED 's*/lib$*/bin*'`
+	  case :$dllsearchpath: in
+	  *":$dir:"*) ;;
+	  ::) dllsearchpath=$dir;;
+	  *) func_append dllsearchpath ":$dir";;
+	  esac
+	  case :$dllsearchpath: in
+	  *":$testbindir:"*) ;;
+	  ::) dllsearchpath=$testbindir;;
+	  *) func_append dllsearchpath ":$testbindir";;
+	  esac
+	  ;;
+	esac
+	continue
+	;;
+
+      -l*)
+	if test X-lc = "X$arg" || test X-lm = "X$arg"; then
+	  case $host in
+	  *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos* | *-cegcc* | *-*-haiku*)
+	    # These systems don't actually have a C or math library (as such)
+	    continue
+	    ;;
+	  *-*-os2*)
+	    # These systems don't actually have a C library (as such)
+	    test X-lc = "X$arg" && continue
+	    ;;
+	  *-*-openbsd* | *-*-freebsd* | *-*-dragonfly* | *-*-bitrig*)
+	    # Do not include libc due to us having libc/libc_r.
+	    test X-lc = "X$arg" && continue
+	    ;;
+	  *-*-rhapsody* | *-*-darwin1.[012])
+	    # Rhapsody C and math libraries are in the System framework
+	    func_append deplibs " System.ltframework"
+	    continue
+	    ;;
+	  *-*-sco3.2v5* | *-*-sco5v6*)
+	    # Causes problems with __ctype
+	    test X-lc = "X$arg" && continue
+	    ;;
+	  *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*)
+	    # Compiler inserts libc in the correct place for threads to work
+	    test X-lc = "X$arg" && continue
+	    ;;
+	  esac
+	elif test X-lc_r = "X$arg"; then
+	 case $host in
+	 *-*-openbsd* | *-*-freebsd* | *-*-dragonfly* | *-*-bitrig*)
+	   # Do not include libc_r directly, use -pthread flag.
+	   continue
+	   ;;
+	 esac
+	fi
+	func_append deplibs " $arg"
+	continue
+	;;
+
+      -mllvm)
+	prev=mllvm
+	continue
+	;;
+
+      -module)
+	module=yes
+	continue
+	;;
+
+      # Tru64 UNIX uses -model [arg] to determine the layout of C++
+      # classes, name mangling, and exception handling.
+      # Darwin uses the -arch flag to determine output architecture.
+      -model|-arch|-isysroot|--sysroot)
+	func_append compiler_flags " $arg"
+	func_append compile_command " $arg"
+	func_append finalize_command " $arg"
+	prev=xcompiler
+	continue
+	;;
+
+      -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \
+      |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*)
+	func_append compiler_flags " $arg"
+	func_append compile_command " $arg"
+	func_append finalize_command " $arg"
+	case "$new_inherited_linker_flags " in
+	    *" $arg "*) ;;
+	    * ) func_append new_inherited_linker_flags " $arg" ;;
+	esac
+	continue
+	;;
+
+      -multi_module)
+	single_module=$wl-multi_module
+	continue
+	;;
+
+      -no-fast-install)
+	fast_install=no
+	continue
+	;;
+
+      -no-install)
+	case $host in
+	*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-darwin* | *-cegcc*)
+	  # The PATH hackery in wrapper scripts is required on Windows
+	  # and Darwin in order for the loader to find any dlls it needs.
+	  func_warning "'-no-install' is ignored for $host"
+	  func_warning "assuming '-no-fast-install' instead"
+	  fast_install=no
+	  ;;
+	*) no_install=yes ;;
+	esac
+	continue
+	;;
+
+      -no-undefined)
+	allow_undefined=no
+	continue
+	;;
+
+      -objectlist)
+	prev=objectlist
+	continue
+	;;
+
+      -os2dllname)
+	prev=os2dllname
+	continue
+	;;
+
+      -o) prev=output ;;
+
+      -precious-files-regex)
+	prev=precious_regex
+	continue
+	;;
+
+      -release)
+	prev=release
+	continue
+	;;
+
+      -rpath)
+	prev=rpath
+	continue
+	;;
+
+      -R)
+	prev=xrpath
+	continue
+	;;
+
+      -R*)
+	func_stripname '-R' '' "$arg"
+	dir=$func_stripname_result
+	# We need an absolute path.
+	case $dir in
+	[\\/]* | [A-Za-z]:[\\/]*) ;;
+	=*)
+	  func_stripname '=' '' "$dir"
+	  dir=$lt_sysroot$func_stripname_result
+	  ;;
+	*)
+	  func_fatal_error "only absolute run-paths are allowed"
+	  ;;
+	esac
+	case "$xrpath " in
+	*" $dir "*) ;;
+	*) func_append xrpath " $dir" ;;
+	esac
+	continue
+	;;
+
+      -shared)
+	# The effects of -shared are defined in a previous loop.
+	continue
+	;;
+
+      -shrext)
+	prev=shrext
+	continue
+	;;
+
+      -static | -static-libtool-libs)
+	# The effects of -static are defined in a previous loop.
+	# We used to do the same as -all-static on platforms that
+	# didn't have a PIC flag, but the assumption that the effects
+	# would be equivalent was wrong.  It would break on at least
+	# Digital Unix and AIX.
+	continue
+	;;
+
+      -thread-safe)
+	thread_safe=yes
+	continue
+	;;
+
+      -version-info)
+	prev=vinfo
+	continue
+	;;
+
+      -version-number)
+	prev=vinfo
+	vinfo_number=yes
+	continue
+	;;
+
+      -weak)
+        prev=weak
+	continue
+	;;
+
+      -Wc,*)
+	func_stripname '-Wc,' '' "$arg"
+	args=$func_stripname_result
+	arg=
+	save_ifs=$IFS; IFS=,
+	for flag in $args; do
+	  IFS=$save_ifs
+          func_quote_for_eval "$flag"
+	  func_append arg " $func_quote_for_eval_result"
+	  func_append compiler_flags " $func_quote_for_eval_result"
+	done
+	IFS=$save_ifs
+	func_stripname ' ' '' "$arg"
+	arg=$func_stripname_result
+	;;
+
+      -Wl,*)
+	func_stripname '-Wl,' '' "$arg"
+	args=$func_stripname_result
+	arg=
+	save_ifs=$IFS; IFS=,
+	for flag in $args; do
+	  IFS=$save_ifs
+          func_quote_for_eval "$flag"
+	  func_append arg " $wl$func_quote_for_eval_result"
+	  func_append compiler_flags " $wl$func_quote_for_eval_result"
+	  func_append linker_flags " $func_quote_for_eval_result"
+	done
+	IFS=$save_ifs
+	func_stripname ' ' '' "$arg"
+	arg=$func_stripname_result
+	;;
+
+      -Xcompiler)
+	prev=xcompiler
+	continue
+	;;
+
+      -Xlinker)
+	prev=xlinker
+	continue
+	;;
+
+      -XCClinker)
+	prev=xcclinker
+	continue
+	;;
+
+      # -msg_* for osf cc
+      -msg_*)
+	func_quote_for_eval "$arg"
+	arg=$func_quote_for_eval_result
+	;;
+
+      # Flags to be passed through unchanged, with rationale:
+      # -64, -mips[0-9]      enable 64-bit mode for the SGI compiler
+      # -r[0-9][0-9]*        specify processor for the SGI compiler
+      # -xarch=*, -xtarget=* enable 64-bit mode for the Sun compiler
+      # +DA*, +DD*           enable 64-bit mode for the HP compiler
+      # -q*                  compiler args for the IBM compiler
+      # -m*, -t[45]*, -txscale* architecture-specific flags for GCC
+      # -F/path              path to uninstalled frameworks, gcc on darwin
+      # -p, -pg, --coverage, -fprofile-*  profiling flags for GCC
+      # -fstack-protector*   stack protector flags for GCC
+      # @file                GCC response files
+      # -tp=*                Portland pgcc target processor selection
+      # --sysroot=*          for sysroot support
+      # -O*, -g*, -flto*, -fwhopr*, -fuse-linker-plugin GCC link-time optimization
+      # -specs=*             GCC specs files
+      # -stdlib=*            select c++ std lib with clang
+      # -fsanitize=*         Clang/GCC memory and address sanitizer
+      -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \
+      -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*|-tp=*|--sysroot=*| \
+      -O*|-g*|-flto*|-fwhopr*|-fuse-linker-plugin|-fstack-protector*|-stdlib=*| \
+      -specs=*|-fsanitize=*)
+        func_quote_for_eval "$arg"
+	arg=$func_quote_for_eval_result
+        func_append compile_command " $arg"
+        func_append finalize_command " $arg"
+        func_append compiler_flags " $arg"
+        continue
+        ;;
+
+      -Z*)
+        if test os2 = "`expr $host : '.*\(os2\)'`"; then
+          # OS/2 uses -Zxxx to specify OS/2-specific options
+	  compiler_flags="$compiler_flags $arg"
+	  func_append compile_command " $arg"
+	  func_append finalize_command " $arg"
+	  case $arg in
+	  -Zlinker | -Zstack)
+	    prev=xcompiler
+	    ;;
+	  esac
+	  continue
+        else
+	  # Otherwise treat like 'Some other compiler flag' below
+	  func_quote_for_eval "$arg"
+	  arg=$func_quote_for_eval_result
+        fi
+	;;
+
+      # Some other compiler flag.
+      -* | +*)
+        func_quote_for_eval "$arg"
+	arg=$func_quote_for_eval_result
+	;;
+
+      *.$objext)
+	# A standard object.
+	func_append objs " $arg"
+	;;
+
+      *.lo)
+	# A libtool-controlled object.
+
+	# Check to see that this really is a libtool object.
+	if func_lalib_unsafe_p "$arg"; then
+	  pic_object=
+	  non_pic_object=
+
+	  # Read the .lo file
+	  func_source "$arg"
+
+	  if test -z "$pic_object" ||
+	     test -z "$non_pic_object" ||
+	     test none = "$pic_object" &&
+	     test none = "$non_pic_object"; then
+	    func_fatal_error "cannot find name of object for '$arg'"
+	  fi
+
+	  # Extract subdirectory from the argument.
+	  func_dirname "$arg" "/" ""
+	  xdir=$func_dirname_result
+
+	  test none = "$pic_object" || {
+	    # Prepend the subdirectory the object is found in.
+	    pic_object=$xdir$pic_object
+
+	    if test dlfiles = "$prev"; then
+	      if test yes = "$build_libtool_libs" && test yes = "$dlopen_support"; then
+		func_append dlfiles " $pic_object"
+		prev=
+		continue
+	      else
+		# If libtool objects are unsupported, then we need to preload.
+		prev=dlprefiles
+	      fi
+	    fi
+
+	    # CHECK ME:  I think I busted this.  -Ossama
+	    if test dlprefiles = "$prev"; then
+	      # Preload the old-style object.
+	      func_append dlprefiles " $pic_object"
+	      prev=
+	    fi
+
+	    # A PIC object.
+	    func_append libobjs " $pic_object"
+	    arg=$pic_object
+	  }
+
+	  # Non-PIC object.
+	  if test none != "$non_pic_object"; then
+	    # Prepend the subdirectory the object is found in.
+	    non_pic_object=$xdir$non_pic_object
+
+	    # A standard non-PIC object
+	    func_append non_pic_objects " $non_pic_object"
+	    if test -z "$pic_object" || test none = "$pic_object"; then
+	      arg=$non_pic_object
+	    fi
+	  else
+	    # If the PIC object exists, use it instead.
+	    # $xdir was prepended to $pic_object above.
+	    non_pic_object=$pic_object
+	    func_append non_pic_objects " $non_pic_object"
+	  fi
+	else
+	  # Only an error if not doing a dry-run.
+	  if $opt_dry_run; then
+	    # Extract subdirectory from the argument.
+	    func_dirname "$arg" "/" ""
+	    xdir=$func_dirname_result
+
+	    func_lo2o "$arg"
+	    pic_object=$xdir$objdir/$func_lo2o_result
+	    non_pic_object=$xdir$func_lo2o_result
+	    func_append libobjs " $pic_object"
+	    func_append non_pic_objects " $non_pic_object"
+	  else
+	    func_fatal_error "'$arg' is not a valid libtool object"
+	  fi
+	fi
+	;;
+
+      *.$libext)
+	# An archive.
+	func_append deplibs " $arg"
+	func_append old_deplibs " $arg"
+	continue
+	;;
+
+      *.la)
+	# A libtool-controlled library.
+
+	func_resolve_sysroot "$arg"
+	if test dlfiles = "$prev"; then
+	  # This library was specified with -dlopen.
+	  func_append dlfiles " $func_resolve_sysroot_result"
+	  prev=
+	elif test dlprefiles = "$prev"; then
+	  # The library was specified with -dlpreopen.
+	  func_append dlprefiles " $func_resolve_sysroot_result"
+	  prev=
+	else
+	  func_append deplibs " $func_resolve_sysroot_result"
+	fi
+	continue
+	;;
+
+      # Some other compiler argument.
+      *)
+	# Unknown arguments in both finalize_command and compile_command need
+	# to be aesthetically quoted because they are evaled later.
+	func_quote_for_eval "$arg"
+	arg=$func_quote_for_eval_result
+	;;
+      esac # arg
+
+      # Now actually substitute the argument into the commands.
+      if test -n "$arg"; then
+	func_append compile_command " $arg"
+	func_append finalize_command " $arg"
+      fi
+    done # argument parsing loop
+
+    test -n "$prev" && \
+      func_fatal_help "the '$prevarg' option requires an argument"
+
+    if test yes = "$export_dynamic" && test -n "$export_dynamic_flag_spec"; then
+      eval arg=\"$export_dynamic_flag_spec\"
+      func_append compile_command " $arg"
+      func_append finalize_command " $arg"
+    fi
+
+    oldlibs=
+    # calculate the name of the file, without its directory
+    func_basename "$output"
+    outputname=$func_basename_result
+    libobjs_save=$libobjs
+
+    if test -n "$shlibpath_var"; then
+      # get the directories listed in $shlibpath_var
+      eval shlib_search_path=\`\$ECHO \"\$$shlibpath_var\" \| \$SED \'s/:/ /g\'\`
+    else
+      shlib_search_path=
+    fi
+    eval sys_lib_search_path=\"$sys_lib_search_path_spec\"
+    eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\"
+
+    # Definition is injected by LT_CONFIG during libtool generation.
+    func_munge_path_list sys_lib_dlsearch_path "$LT_SYS_LIBRARY_PATH"
+
+    func_dirname "$output" "/" ""
+    output_objdir=$func_dirname_result$objdir
+    func_to_tool_file "$output_objdir/"
+    tool_output_objdir=$func_to_tool_file_result
+    # Create the object directory.
+    func_mkdir_p "$output_objdir"
+
+    # Determine the type of output
+    case $output in
+    "")
+      func_fatal_help "you must specify an output file"
+      ;;
+    *.$libext) linkmode=oldlib ;;
+    *.lo | *.$objext) linkmode=obj ;;
+    *.la) linkmode=lib ;;
+    *) linkmode=prog ;; # Anything else should be a program.
+    esac
+
+    specialdeplibs=
+
+    libs=
+    # Find all interdependent deplibs by searching for libraries
+    # that are linked more than once (e.g. -la -lb -la)
+    for deplib in $deplibs; do
+      if $opt_preserve_dup_deps; then
+	case "$libs " in
+	*" $deplib "*) func_append specialdeplibs " $deplib" ;;
+	esac
+      fi
+      func_append libs " $deplib"
+    done
+
+    if test lib = "$linkmode"; then
+      libs="$predeps $libs $compiler_lib_search_path $postdeps"
+
+      # Compute libraries that are listed more than once in $predeps
+      # $postdeps and mark them as special (i.e., whose duplicates are
+      # not to be eliminated).
+      pre_post_deps=
+      if $opt_duplicate_compiler_generated_deps; then
+	for pre_post_dep in $predeps $postdeps; do
+	  case "$pre_post_deps " in
+	  *" $pre_post_dep "*) func_append specialdeplibs " $pre_post_deps" ;;
+	  esac
+	  func_append pre_post_deps " $pre_post_dep"
+	done
+      fi
+      pre_post_deps=
+    fi
+
+    deplibs=
+    newdependency_libs=
+    newlib_search_path=
+    need_relink=no # whether we're linking any uninstalled libtool libraries
+    notinst_deplibs= # not-installed libtool libraries
+    notinst_path= # paths that contain not-installed libtool libraries
+
+    case $linkmode in
+    lib)
+	passes="conv dlpreopen link"
+	for file in $dlfiles $dlprefiles; do
+	  case $file in
+	  *.la) ;;
+	  *)
+	    func_fatal_help "libraries can '-dlopen' only libtool libraries: $file"
+	    ;;
+	  esac
+	done
+	;;
+    prog)
+	compile_deplibs=
+	finalize_deplibs=
+	alldeplibs=false
+	newdlfiles=
+	newdlprefiles=
+	passes="conv scan dlopen dlpreopen link"
+	;;
+    *)  passes="conv"
+	;;
+    esac
+
+    for pass in $passes; do
+      # The preopen pass in lib mode reverses $deplibs; put it back here
+      # so that -L comes before libs that need it for instance...
+      if test lib,link = "$linkmode,$pass"; then
+	## FIXME: Find the place where the list is rebuilt in the wrong
+	##        order, and fix it there properly
+        tmp_deplibs=
+	for deplib in $deplibs; do
+	  tmp_deplibs="$deplib $tmp_deplibs"
+	done
+	deplibs=$tmp_deplibs
+      fi
+
+      if test lib,link = "$linkmode,$pass" ||
+	 test prog,scan = "$linkmode,$pass"; then
+	libs=$deplibs
+	deplibs=
+      fi
+      if test prog = "$linkmode"; then
+	case $pass in
+	dlopen) libs=$dlfiles ;;
+	dlpreopen) libs=$dlprefiles ;;
+	link)
+	  libs="$deplibs %DEPLIBS%"
+	  test "X$link_all_deplibs" != Xno && libs="$libs $dependency_libs"
+	  ;;
+	esac
+      fi
+      if test lib,dlpreopen = "$linkmode,$pass"; then
+	# Collect and forward deplibs of preopened libtool libs
+	for lib in $dlprefiles; do
+	  # Ignore non-libtool-libs
+	  dependency_libs=
+	  func_resolve_sysroot "$lib"
+	  case $lib in
+	  *.la)	func_source "$func_resolve_sysroot_result" ;;
+	  esac
+
+	  # Collect preopened libtool deplibs, except any this library
+	  # has declared as weak libs
+	  for deplib in $dependency_libs; do
+	    func_basename "$deplib"
+            deplib_base=$func_basename_result
+	    case " $weak_libs " in
+	    *" $deplib_base "*) ;;
+	    *) func_append deplibs " $deplib" ;;
+	    esac
+	  done
+	done
+	libs=$dlprefiles
+      fi
+      if test dlopen = "$pass"; then
+	# Collect dlpreopened libraries
+	save_deplibs=$deplibs
+	deplibs=
+      fi
+
+      for deplib in $libs; do
+	lib=
+	found=false
+	case $deplib in
+	-mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \
+        |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*)
+	  if test prog,link = "$linkmode,$pass"; then
+	    compile_deplibs="$deplib $compile_deplibs"
+	    finalize_deplibs="$deplib $finalize_deplibs"
+	  else
+	    func_append compiler_flags " $deplib"
+	    if test lib = "$linkmode"; then
+		case "$new_inherited_linker_flags " in
+		    *" $deplib "*) ;;
+		    * ) func_append new_inherited_linker_flags " $deplib" ;;
+		esac
+	    fi
+	  fi
+	  continue
+	  ;;
+	-l*)
+	  if test lib != "$linkmode" && test prog != "$linkmode"; then
+	    func_warning "'-l' is ignored for archives/objects"
+	    continue
+	  fi
+	  func_stripname '-l' '' "$deplib"
+	  name=$func_stripname_result
+	  if test lib = "$linkmode"; then
+	    searchdirs="$newlib_search_path $lib_search_path $compiler_lib_search_dirs $sys_lib_search_path $shlib_search_path"
+	  else
+	    searchdirs="$newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path"
+	  fi
+	  for searchdir in $searchdirs; do
+	    for search_ext in .la $std_shrext .so .a; do
+	      # Search the libtool library
+	      lib=$searchdir/lib$name$search_ext
+	      if test -f "$lib"; then
+		if test .la = "$search_ext"; then
+		  found=:
+		else
+		  found=false
+		fi
+		break 2
+	      fi
+	    done
+	  done
+	  if $found; then
+	    # deplib is a libtool library
+	    # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib,
+	    # We need to do some special things here, and not later.
+	    if test yes = "$allow_libtool_libs_with_static_runtimes"; then
+	      case " $predeps $postdeps " in
+	      *" $deplib "*)
+		if func_lalib_p "$lib"; then
+		  library_names=
+		  old_library=
+		  func_source "$lib"
+		  for l in $old_library $library_names; do
+		    ll=$l
+		  done
+		  if test "X$ll" = "X$old_library"; then # only static version available
+		    found=false
+		    func_dirname "$lib" "" "."
+		    ladir=$func_dirname_result
+		    lib=$ladir/$old_library
+		    if test prog,link = "$linkmode,$pass"; then
+		      compile_deplibs="$deplib $compile_deplibs"
+		      finalize_deplibs="$deplib $finalize_deplibs"
+		    else
+		      deplibs="$deplib $deplibs"
+		      test lib = "$linkmode" && newdependency_libs="$deplib $newdependency_libs"
+		    fi
+		    continue
+		  fi
+		fi
+		;;
+	      *) ;;
+	      esac
+	    fi
+	  else
+	    # deplib doesn't seem to be a libtool library
+	    if test prog,link = "$linkmode,$pass"; then
+	      compile_deplibs="$deplib $compile_deplibs"
+	      finalize_deplibs="$deplib $finalize_deplibs"
+	    else
+	      deplibs="$deplib $deplibs"
+	      test lib = "$linkmode" && newdependency_libs="$deplib $newdependency_libs"
+	    fi
+	    continue
+	  fi
+	  ;; # -l
+	*.ltframework)
+	  if test prog,link = "$linkmode,$pass"; then
+	    compile_deplibs="$deplib $compile_deplibs"
+	    finalize_deplibs="$deplib $finalize_deplibs"
+	  else
+	    deplibs="$deplib $deplibs"
+	    if test lib = "$linkmode"; then
+		case "$new_inherited_linker_flags " in
+		    *" $deplib "*) ;;
+		    * ) func_append new_inherited_linker_flags " $deplib" ;;
+		esac
+	    fi
+	  fi
+	  continue
+	  ;;
+	-L*)
+	  case $linkmode in
+	  lib)
+	    deplibs="$deplib $deplibs"
+	    test conv = "$pass" && continue
+	    newdependency_libs="$deplib $newdependency_libs"
+	    func_stripname '-L' '' "$deplib"
+	    func_resolve_sysroot "$func_stripname_result"
+	    func_append newlib_search_path " $func_resolve_sysroot_result"
+	    ;;
+	  prog)
+	    if test conv = "$pass"; then
+	      deplibs="$deplib $deplibs"
+	      continue
+	    fi
+	    if test scan = "$pass"; then
+	      deplibs="$deplib $deplibs"
+	    else
+	      compile_deplibs="$deplib $compile_deplibs"
+	      finalize_deplibs="$deplib $finalize_deplibs"
+	    fi
+	    func_stripname '-L' '' "$deplib"
+	    func_resolve_sysroot "$func_stripname_result"
+	    func_append newlib_search_path " $func_resolve_sysroot_result"
+	    ;;
+	  *)
+	    func_warning "'-L' is ignored for archives/objects"
+	    ;;
+	  esac # linkmode
+	  continue
+	  ;; # -L
+	-R*)
+	  if test link = "$pass"; then
+	    func_stripname '-R' '' "$deplib"
+	    func_resolve_sysroot "$func_stripname_result"
+	    dir=$func_resolve_sysroot_result
+	    # Make sure the xrpath contains only unique directories.
+	    case "$xrpath " in
+	    *" $dir "*) ;;
+	    *) func_append xrpath " $dir" ;;
+	    esac
+	  fi
+	  deplibs="$deplib $deplibs"
+	  continue
+	  ;;
+	*.la)
+	  func_resolve_sysroot "$deplib"
+	  lib=$func_resolve_sysroot_result
+	  ;;
+	*.$libext)
+	  if test conv = "$pass"; then
+	    deplibs="$deplib $deplibs"
+	    continue
+	  fi
+	  case $linkmode in
+	  lib)
+	    # Linking convenience modules into shared libraries is allowed,
+	    # but linking other static libraries is non-portable.
+	    case " $dlpreconveniencelibs " in
+	    *" $deplib "*) ;;
+	    *)
+	      valid_a_lib=false
+	      case $deplibs_check_method in
+		match_pattern*)
+		  set dummy $deplibs_check_method; shift
+		  match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"`
+		  if eval "\$ECHO \"$deplib\"" 2>/dev/null | $SED 10q \
+		    | $EGREP "$match_pattern_regex" > /dev/null; then
+		    valid_a_lib=:
+		  fi
+		;;
+		pass_all)
+		  valid_a_lib=:
+		;;
+	      esac
+	      if $valid_a_lib; then
+		echo
+		$ECHO "*** Warning: Linking the shared library $output against the"
+		$ECHO "*** static library $deplib is not portable!"
+		deplibs="$deplib $deplibs"
+	      else
+		echo
+		$ECHO "*** Warning: Trying to link with static lib archive $deplib."
+		echo "*** I have the capability to make that library automatically link in when"
+		echo "*** you link to this library.  But I can only do this if you have a"
+		echo "*** shared version of the library, which you do not appear to have"
+		echo "*** because the file extensions .$libext of this argument makes me believe"
+		echo "*** that it is just a static archive that I should not use here."
+	      fi
+	      ;;
+	    esac
+	    continue
+	    ;;
+	  prog)
+	    if test link != "$pass"; then
+	      deplibs="$deplib $deplibs"
+	    else
+	      compile_deplibs="$deplib $compile_deplibs"
+	      finalize_deplibs="$deplib $finalize_deplibs"
+	    fi
+	    continue
+	    ;;
+	  esac # linkmode
+	  ;; # *.$libext
+	*.lo | *.$objext)
+	  if test conv = "$pass"; then
+	    deplibs="$deplib $deplibs"
+	  elif test prog = "$linkmode"; then
+	    if test dlpreopen = "$pass" || test yes != "$dlopen_support" || test no = "$build_libtool_libs"; then
+	      # If there is no dlopen support or we're linking statically,
+	      # we need to preload.
+	      func_append newdlprefiles " $deplib"
+	      compile_deplibs="$deplib $compile_deplibs"
+	      finalize_deplibs="$deplib $finalize_deplibs"
+	    else
+	      func_append newdlfiles " $deplib"
+	    fi
+	  fi
+	  continue
+	  ;;
+	%DEPLIBS%)
+	  alldeplibs=:
+	  continue
+	  ;;
+	esac # case $deplib
+
+	$found || test -f "$lib" \
+	  || func_fatal_error "cannot find the library '$lib' or unhandled argument '$deplib'"
+
+	# Check to see that this really is a libtool archive.
+	func_lalib_unsafe_p "$lib" \
+	  || func_fatal_error "'$lib' is not a valid libtool archive"
+
+	func_dirname "$lib" "" "."
+	ladir=$func_dirname_result
+
+	dlname=
+	dlopen=
+	dlpreopen=
+	libdir=
+	library_names=
+	old_library=
+	inherited_linker_flags=
+	# If the library was installed with an old release of libtool,
+	# it will not redefine variables installed, or shouldnotlink
+	installed=yes
+	shouldnotlink=no
+	avoidtemprpath=
+
+
+	# Read the .la file
+	func_source "$lib"
+
+	# Convert "-framework foo" to "foo.ltframework"
+	if test -n "$inherited_linker_flags"; then
+	  tmp_inherited_linker_flags=`$ECHO "$inherited_linker_flags" | $SED 's/-framework \([^ $]*\)/\1.ltframework/g'`
+	  for tmp_inherited_linker_flag in $tmp_inherited_linker_flags; do
+	    case " $new_inherited_linker_flags " in
+	      *" $tmp_inherited_linker_flag "*) ;;
+	      *) func_append new_inherited_linker_flags " $tmp_inherited_linker_flag";;
+	    esac
+	  done
+	fi
+	dependency_libs=`$ECHO " $dependency_libs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+	if test lib,link = "$linkmode,$pass" ||
+	   test prog,scan = "$linkmode,$pass" ||
+	   { test prog != "$linkmode" && test lib != "$linkmode"; }; then
+	  test -n "$dlopen" && func_append dlfiles " $dlopen"
+	  test -n "$dlpreopen" && func_append dlprefiles " $dlpreopen"
+	fi
+
+	if test conv = "$pass"; then
+	  # Only check for convenience libraries
+	  deplibs="$lib $deplibs"
+	  if test -z "$libdir"; then
+	    if test -z "$old_library"; then
+	      func_fatal_error "cannot find name of link library for '$lib'"
+	    fi
+	    # It is a libtool convenience library, so add in its objects.
+	    func_append convenience " $ladir/$objdir/$old_library"
+	    func_append old_convenience " $ladir/$objdir/$old_library"
+	    tmp_libs=
+	    for deplib in $dependency_libs; do
+	      deplibs="$deplib $deplibs"
+	      if $opt_preserve_dup_deps; then
+		case "$tmp_libs " in
+		*" $deplib "*) func_append specialdeplibs " $deplib" ;;
+		esac
+	      fi
+	      func_append tmp_libs " $deplib"
+	    done
+	  elif test prog != "$linkmode" && test lib != "$linkmode"; then
+	    func_fatal_error "'$lib' is not a convenience library"
+	  fi
+	  continue
+	fi # $pass = conv
+
+
+	# Get the name of the library we link against.
+	linklib=
+	if test -n "$old_library" &&
+	   { test yes = "$prefer_static_libs" ||
+	     test built,no = "$prefer_static_libs,$installed"; }; then
+	  linklib=$old_library
+	else
+	  for l in $old_library $library_names; do
+	    linklib=$l
+	  done
+	fi
+	if test -z "$linklib"; then
+	  func_fatal_error "cannot find name of link library for '$lib'"
+	fi
+
+	# This library was specified with -dlopen.
+	if test dlopen = "$pass"; then
+	  test -z "$libdir" \
+	    && func_fatal_error "cannot -dlopen a convenience library: '$lib'"
+	  if test -z "$dlname" ||
+	     test yes != "$dlopen_support" ||
+	     test no = "$build_libtool_libs"
+	  then
+	    # If there is no dlname, no dlopen support or we're linking
+	    # statically, we need to preload.  We also need to preload any
+	    # dependent libraries so libltdl's deplib preloader doesn't
+	    # bomb out in the load deplibs phase.
+	    func_append dlprefiles " $lib $dependency_libs"
+	  else
+	    func_append newdlfiles " $lib"
+	  fi
+	  continue
+	fi # $pass = dlopen
+
+	# We need an absolute path.
+	case $ladir in
+	[\\/]* | [A-Za-z]:[\\/]*) abs_ladir=$ladir ;;
+	*)
+	  abs_ladir=`cd "$ladir" && pwd`
+	  if test -z "$abs_ladir"; then
+	    func_warning "cannot determine absolute directory name of '$ladir'"
+	    func_warning "passing it literally to the linker, although it might fail"
+	    abs_ladir=$ladir
+	  fi
+	  ;;
+	esac
+	func_basename "$lib"
+	laname=$func_basename_result
+
+	# Find the relevant object directory and library name.
+	if test yes = "$installed"; then
+	  if test ! -f "$lt_sysroot$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then
+	    func_warning "library '$lib' was moved."
+	    dir=$ladir
+	    absdir=$abs_ladir
+	    libdir=$abs_ladir
+	  else
+	    dir=$lt_sysroot$libdir
+	    absdir=$lt_sysroot$libdir
+	  fi
+	  test yes = "$hardcode_automatic" && avoidtemprpath=yes
+	else
+	  if test ! -f "$ladir/$objdir/$linklib" && test -f "$abs_ladir/$linklib"; then
+	    dir=$ladir
+	    absdir=$abs_ladir
+	    # Remove this search path later
+	    func_append notinst_path " $abs_ladir"
+	  else
+	    dir=$ladir/$objdir
+	    absdir=$abs_ladir/$objdir
+	    # Remove this search path later
+	    func_append notinst_path " $abs_ladir"
+	  fi
+	fi # $installed = yes
+	func_stripname 'lib' '.la' "$laname"
+	name=$func_stripname_result
+
+	# This library was specified with -dlpreopen.
+	if test dlpreopen = "$pass"; then
+	  if test -z "$libdir" && test prog = "$linkmode"; then
+	    func_fatal_error "only libraries may -dlpreopen a convenience library: '$lib'"
+	  fi
+	  case $host in
+	    # special handling for platforms with PE-DLLs.
+	    *cygwin* | *mingw* | *cegcc* )
+	      # Linker will automatically link against shared library if both
+	      # static and shared are present.  Therefore, ensure we extract
+	      # symbols from the import library if a shared library is present
+	      # (otherwise, the dlopen module name will be incorrect).  We do
+	      # this by putting the import library name into $newdlprefiles.
+	      # We recover the dlopen module name by 'saving' the la file
+	      # name in a special purpose variable, and (later) extracting the
+	      # dlname from the la file.
+	      if test -n "$dlname"; then
+	        func_tr_sh "$dir/$linklib"
+	        eval "libfile_$func_tr_sh_result=\$abs_ladir/\$laname"
+	        func_append newdlprefiles " $dir/$linklib"
+	      else
+	        func_append newdlprefiles " $dir/$old_library"
+	        # Keep a list of preopened convenience libraries to check
+	        # that they are being used correctly in the link pass.
+	        test -z "$libdir" && \
+	          func_append dlpreconveniencelibs " $dir/$old_library"
+	      fi
+	    ;;
+	    * )
+	      # Prefer using a static library (so that no silly _DYNAMIC symbols
+	      # are required to link).
+	      if test -n "$old_library"; then
+	        func_append newdlprefiles " $dir/$old_library"
+	        # Keep a list of preopened convenience libraries to check
+	        # that they are being used correctly in the link pass.
+	        test -z "$libdir" && \
+	          func_append dlpreconveniencelibs " $dir/$old_library"
+	      # Otherwise, use the dlname, so that lt_dlopen finds it.
+	      elif test -n "$dlname"; then
+	        func_append newdlprefiles " $dir/$dlname"
+	      else
+	        func_append newdlprefiles " $dir/$linklib"
+	      fi
+	    ;;
+	  esac
+	fi # $pass = dlpreopen
+
+	if test -z "$libdir"; then
+	  # Link the convenience library
+	  if test lib = "$linkmode"; then
+	    deplibs="$dir/$old_library $deplibs"
+	  elif test prog,link = "$linkmode,$pass"; then
+	    compile_deplibs="$dir/$old_library $compile_deplibs"
+	    finalize_deplibs="$dir/$old_library $finalize_deplibs"
+	  else
+	    deplibs="$lib $deplibs" # used for prog,scan pass
+	  fi
+	  continue
+	fi
+
+
+	if test prog = "$linkmode" && test link != "$pass"; then
+	  func_append newlib_search_path " $ladir"
+	  deplibs="$lib $deplibs"
+
+	  linkalldeplibs=false
+	  if test no != "$link_all_deplibs" || test -z "$library_names" ||
+	     test no = "$build_libtool_libs"; then
+	    linkalldeplibs=:
+	  fi
+
+	  tmp_libs=
+	  for deplib in $dependency_libs; do
+	    case $deplib in
+	    -L*) func_stripname '-L' '' "$deplib"
+	         func_resolve_sysroot "$func_stripname_result"
+	         func_append newlib_search_path " $func_resolve_sysroot_result"
+		 ;;
+	    esac
+	    # Need to link against all dependency_libs?
+	    if $linkalldeplibs; then
+	      deplibs="$deplib $deplibs"
+	    else
+	      # Need to hardcode shared library paths
+	      # or/and link against static libraries
+	      newdependency_libs="$deplib $newdependency_libs"
+	    fi
+	    if $opt_preserve_dup_deps; then
+	      case "$tmp_libs " in
+	      *" $deplib "*) func_append specialdeplibs " $deplib" ;;
+	      esac
+	    fi
+	    func_append tmp_libs " $deplib"
+	  done # for deplib
+	  continue
+	fi # $linkmode = prog...
+
+	if test prog,link = "$linkmode,$pass"; then
+	  if test -n "$library_names" &&
+	     { { test no = "$prefer_static_libs" ||
+	         test built,yes = "$prefer_static_libs,$installed"; } ||
+	       test -z "$old_library"; }; then
+	    # We need to hardcode the library path
+	    if test -n "$shlibpath_var" && test -z "$avoidtemprpath"; then
+	      # Make sure the rpath contains only unique directories.
+	      case $temp_rpath: in
+	      *"$absdir:"*) ;;
+	      *) func_append temp_rpath "$absdir:" ;;
+	      esac
+	    fi
+
+	    # Hardcode the library path.
+	    # Skip directories that are in the system default run-time
+	    # search path.
+	    case " $sys_lib_dlsearch_path " in
+	    *" $absdir "*) ;;
+	    *)
+	      case "$compile_rpath " in
+	      *" $absdir "*) ;;
+	      *) func_append compile_rpath " $absdir" ;;
+	      esac
+	      ;;
+	    esac
+	    case " $sys_lib_dlsearch_path " in
+	    *" $libdir "*) ;;
+	    *)
+	      case "$finalize_rpath " in
+	      *" $libdir "*) ;;
+	      *) func_append finalize_rpath " $libdir" ;;
+	      esac
+	      ;;
+	    esac
+	  fi # $linkmode,$pass = prog,link...
+
+	  if $alldeplibs &&
+	     { test pass_all = "$deplibs_check_method" ||
+	       { test yes = "$build_libtool_libs" &&
+		 test -n "$library_names"; }; }; then
+	    # We only need to search for static libraries
+	    continue
+	  fi
+	fi
+
+	link_static=no # Whether the deplib will be linked statically
+	use_static_libs=$prefer_static_libs
+	if test built = "$use_static_libs" && test yes = "$installed"; then
+	  use_static_libs=no
+	fi
+	if test -n "$library_names" &&
+	   { test no = "$use_static_libs" || test -z "$old_library"; }; then
+	  case $host in
+	  *cygwin* | *mingw* | *cegcc* | *os2*)
+	      # No point in relinking DLLs because paths are not encoded
+	      func_append notinst_deplibs " $lib"
+	      need_relink=no
+	    ;;
+	  *)
+	    if test no = "$installed"; then
+	      func_append notinst_deplibs " $lib"
+	      need_relink=yes
+	    fi
+	    ;;
+	  esac
+	  # This is a shared library
+
+	  # Warn about portability, can't link against -module's on some
+	  # systems (darwin).  Don't bleat about dlopened modules though!
+	  dlopenmodule=
+	  for dlpremoduletest in $dlprefiles; do
+	    if test "X$dlpremoduletest" = "X$lib"; then
+	      dlopenmodule=$dlpremoduletest
+	      break
+	    fi
+	  done
+	  if test -z "$dlopenmodule" && test yes = "$shouldnotlink" && test link = "$pass"; then
+	    echo
+	    if test prog = "$linkmode"; then
+	      $ECHO "*** Warning: Linking the executable $output against the loadable module"
+	    else
+	      $ECHO "*** Warning: Linking the shared library $output against the loadable module"
+	    fi
+	    $ECHO "*** $linklib is not portable!"
+	  fi
+	  if test lib = "$linkmode" &&
+	     test yes = "$hardcode_into_libs"; then
+	    # Hardcode the library path.
+	    # Skip directories that are in the system default run-time
+	    # search path.
+	    case " $sys_lib_dlsearch_path " in
+	    *" $absdir "*) ;;
+	    *)
+	      case "$compile_rpath " in
+	      *" $absdir "*) ;;
+	      *) func_append compile_rpath " $absdir" ;;
+	      esac
+	      ;;
+	    esac
+	    case " $sys_lib_dlsearch_path " in
+	    *" $libdir "*) ;;
+	    *)
+	      case "$finalize_rpath " in
+	      *" $libdir "*) ;;
+	      *) func_append finalize_rpath " $libdir" ;;
+	      esac
+	      ;;
+	    esac
+	  fi
+
+	  if test -n "$old_archive_from_expsyms_cmds"; then
+	    # figure out the soname
+	    set dummy $library_names
+	    shift
+	    realname=$1
+	    shift
+	    libname=`eval "\\$ECHO \"$libname_spec\""`
+	    # use dlname if we got it. it's perfectly good, no?
+	    if test -n "$dlname"; then
+	      soname=$dlname
+	    elif test -n "$soname_spec"; then
+	      # bleh windows
+	      case $host in
+	      *cygwin* | mingw* | *cegcc* | *os2*)
+	        func_arith $current - $age
+		major=$func_arith_result
+		versuffix=-$major
+		;;
+	      esac
+	      eval soname=\"$soname_spec\"
+	    else
+	      soname=$realname
+	    fi
+
+	    # Make a new name for the extract_expsyms_cmds to use
+	    soroot=$soname
+	    func_basename "$soroot"
+	    soname=$func_basename_result
+	    func_stripname 'lib' '.dll' "$soname"
+	    newlib=libimp-$func_stripname_result.a
+
+	    # If the library has no export list, then create one now
+	    if test -f "$output_objdir/$soname-def"; then :
+	    else
+	      func_verbose "extracting exported symbol list from '$soname'"
+	      func_execute_cmds "$extract_expsyms_cmds" 'exit $?'
+	    fi
+
+	    # Create $newlib
+	    if test -f "$output_objdir/$newlib"; then :; else
+	      func_verbose "generating import library for '$soname'"
+	      func_execute_cmds "$old_archive_from_expsyms_cmds" 'exit $?'
+	    fi
+	    # make sure the library variables are pointing to the new library
+	    dir=$output_objdir
+	    linklib=$newlib
+	  fi # test -n "$old_archive_from_expsyms_cmds"
+
+	  if test prog = "$linkmode" || test relink != "$opt_mode"; then
+	    add_shlibpath=
+	    add_dir=
+	    add=
+	    lib_linked=yes
+	    case $hardcode_action in
+	    immediate | unsupported)
+	      if test no = "$hardcode_direct"; then
+		add=$dir/$linklib
+		case $host in
+		  *-*-sco3.2v5.0.[024]*) add_dir=-L$dir ;;
+		  *-*-sysv4*uw2*) add_dir=-L$dir ;;
+		  *-*-sysv5OpenUNIX* | *-*-sysv5UnixWare7.[01].[10]* | \
+		    *-*-unixware7*) add_dir=-L$dir ;;
+		  *-*-darwin* )
+		    # if the lib is a (non-dlopened) module then we cannot
+		    # link against it, someone is ignoring the earlier warnings
+		    if /usr/bin/file -L $add 2> /dev/null |
+			 $GREP ": [^:]* bundle" >/dev/null; then
+		      if test "X$dlopenmodule" != "X$lib"; then
+			$ECHO "*** Warning: lib $linklib is a module, not a shared library"
+			if test -z "$old_library"; then
+			  echo
+			  echo "*** And there doesn't seem to be a static archive available"
+			  echo "*** The link will probably fail, sorry"
+			else
+			  add=$dir/$old_library
+			fi
+		      elif test -n "$old_library"; then
+			add=$dir/$old_library
+		      fi
+		    fi
+		esac
+	      elif test no = "$hardcode_minus_L"; then
+		case $host in
+		*-*-sunos*) add_shlibpath=$dir ;;
+		esac
+		add_dir=-L$dir
+		add=-l$name
+	      elif test no = "$hardcode_shlibpath_var"; then
+		add_shlibpath=$dir
+		add=-l$name
+	      else
+		lib_linked=no
+	      fi
+	      ;;
+	    relink)
+	      if test yes = "$hardcode_direct" &&
+	         test no = "$hardcode_direct_absolute"; then
+		add=$dir/$linklib
+	      elif test yes = "$hardcode_minus_L"; then
+		add_dir=-L$absdir
+		# Try looking first in the location we're being installed to.
+		if test -n "$inst_prefix_dir"; then
+		  case $libdir in
+		    [\\/]*)
+		      func_append add_dir " -L$inst_prefix_dir$libdir"
+		      ;;
+		  esac
+		fi
+		add=-l$name
+	      elif test yes = "$hardcode_shlibpath_var"; then
+		add_shlibpath=$dir
+		add=-l$name
+	      else
+		lib_linked=no
+	      fi
+	      ;;
+	    *) lib_linked=no ;;
+	    esac
+
+	    if test yes != "$lib_linked"; then
+	      func_fatal_configuration "unsupported hardcode properties"
+	    fi
+
+	    if test -n "$add_shlibpath"; then
+	      case :$compile_shlibpath: in
+	      *":$add_shlibpath:"*) ;;
+	      *) func_append compile_shlibpath "$add_shlibpath:" ;;
+	      esac
+	    fi
+	    if test prog = "$linkmode"; then
+	      test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs"
+	      test -n "$add" && compile_deplibs="$add $compile_deplibs"
+	    else
+	      test -n "$add_dir" && deplibs="$add_dir $deplibs"
+	      test -n "$add" && deplibs="$add $deplibs"
+	      if test yes != "$hardcode_direct" &&
+		 test yes != "$hardcode_minus_L" &&
+		 test yes = "$hardcode_shlibpath_var"; then
+		case :$finalize_shlibpath: in
+		*":$libdir:"*) ;;
+		*) func_append finalize_shlibpath "$libdir:" ;;
+		esac
+	      fi
+	    fi
+	  fi
+
+	  if test prog = "$linkmode" || test relink = "$opt_mode"; then
+	    add_shlibpath=
+	    add_dir=
+	    add=
+	    # Finalize command for both is simple: just hardcode it.
+	    if test yes = "$hardcode_direct" &&
+	       test no = "$hardcode_direct_absolute"; then
+	      add=$libdir/$linklib
+	    elif test yes = "$hardcode_minus_L"; then
+	      add_dir=-L$libdir
+	      add=-l$name
+	    elif test yes = "$hardcode_shlibpath_var"; then
+	      case :$finalize_shlibpath: in
+	      *":$libdir:"*) ;;
+	      *) func_append finalize_shlibpath "$libdir:" ;;
+	      esac
+	      add=-l$name
+	    elif test yes = "$hardcode_automatic"; then
+	      if test -n "$inst_prefix_dir" &&
+		 test -f "$inst_prefix_dir$libdir/$linklib"; then
+		add=$inst_prefix_dir$libdir/$linklib
+	      else
+		add=$libdir/$linklib
+	      fi
+	    else
+	      # We cannot seem to hardcode it, guess we'll fake it.
+	      add_dir=-L$libdir
+	      # Try looking first in the location we're being installed to.
+	      if test -n "$inst_prefix_dir"; then
+		case $libdir in
+		  [\\/]*)
+		    func_append add_dir " -L$inst_prefix_dir$libdir"
+		    ;;
+		esac
+	      fi
+	      add=-l$name
+	    fi
+
+	    if test prog = "$linkmode"; then
+	      test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs"
+	      test -n "$add" && finalize_deplibs="$add $finalize_deplibs"
+	    else
+	      test -n "$add_dir" && deplibs="$add_dir $deplibs"
+	      test -n "$add" && deplibs="$add $deplibs"
+	    fi
+	  fi
+	elif test prog = "$linkmode"; then
+	  # Here we assume that one of hardcode_direct or hardcode_minus_L
+	  # is not unsupported.  This is valid on all known static and
+	  # shared platforms.
+	  if test unsupported != "$hardcode_direct"; then
+	    test -n "$old_library" && linklib=$old_library
+	    compile_deplibs="$dir/$linklib $compile_deplibs"
+	    finalize_deplibs="$dir/$linklib $finalize_deplibs"
+	  else
+	    compile_deplibs="-l$name -L$dir $compile_deplibs"
+	    finalize_deplibs="-l$name -L$dir $finalize_deplibs"
+	  fi
+	elif test yes = "$build_libtool_libs"; then
+	  # Not a shared library
+	  if test pass_all != "$deplibs_check_method"; then
+	    # We're trying link a shared library against a static one
+	    # but the system doesn't support it.
+
+	    # Just print a warning and add the library to dependency_libs so
+	    # that the program can be linked against the static library.
+	    echo
+	    $ECHO "*** Warning: This system cannot link to static lib archive $lib."
+	    echo "*** I have the capability to make that library automatically link in when"
+	    echo "*** you link to this library.  But I can only do this if you have a"
+	    echo "*** shared version of the library, which you do not appear to have."
+	    if test yes = "$module"; then
+	      echo "*** But as you try to build a module library, libtool will still create "
+	      echo "*** a static module, that should work as long as the dlopening application"
+	      echo "*** is linked with the -dlopen flag to resolve symbols at runtime."
+	      if test -z "$global_symbol_pipe"; then
+		echo
+		echo "*** However, this would only work if libtool was able to extract symbol"
+		echo "*** lists from a program, using 'nm' or equivalent, but libtool could"
+		echo "*** not find such a program.  So, this module is probably useless."
+		echo "*** 'nm' from GNU binutils and a full rebuild may help."
+	      fi
+	      if test no = "$build_old_libs"; then
+		build_libtool_libs=module
+		build_old_libs=yes
+	      else
+		build_libtool_libs=no
+	      fi
+	    fi
+	  else
+	    deplibs="$dir/$old_library $deplibs"
+	    link_static=yes
+	  fi
+	fi # link shared/static library?
+
+	if test lib = "$linkmode"; then
+	  if test -n "$dependency_libs" &&
+	     { test yes != "$hardcode_into_libs" ||
+	       test yes = "$build_old_libs" ||
+	       test yes = "$link_static"; }; then
+	    # Extract -R from dependency_libs
+	    temp_deplibs=
+	    for libdir in $dependency_libs; do
+	      case $libdir in
+	      -R*) func_stripname '-R' '' "$libdir"
+	           temp_xrpath=$func_stripname_result
+		   case " $xrpath " in
+		   *" $temp_xrpath "*) ;;
+		   *) func_append xrpath " $temp_xrpath";;
+		   esac;;
+	      *) func_append temp_deplibs " $libdir";;
+	      esac
+	    done
+	    dependency_libs=$temp_deplibs
+	  fi
+
+	  func_append newlib_search_path " $absdir"
+	  # Link against this library
+	  test no = "$link_static" && newdependency_libs="$abs_ladir/$laname $newdependency_libs"
+	  # ... and its dependency_libs
+	  tmp_libs=
+	  for deplib in $dependency_libs; do
+	    newdependency_libs="$deplib $newdependency_libs"
+	    case $deplib in
+              -L*) func_stripname '-L' '' "$deplib"
+                   func_resolve_sysroot "$func_stripname_result";;
+              *) func_resolve_sysroot "$deplib" ;;
+            esac
+	    if $opt_preserve_dup_deps; then
+	      case "$tmp_libs " in
+	      *" $func_resolve_sysroot_result "*)
+                func_append specialdeplibs " $func_resolve_sysroot_result" ;;
+	      esac
+	    fi
+	    func_append tmp_libs " $func_resolve_sysroot_result"
+	  done
+
+	  if test no != "$link_all_deplibs"; then
+	    # Add the search paths of all dependency libraries
+	    for deplib in $dependency_libs; do
+	      path=
+	      case $deplib in
+	      -L*) path=$deplib ;;
+	      *.la)
+	        func_resolve_sysroot "$deplib"
+	        deplib=$func_resolve_sysroot_result
+	        func_dirname "$deplib" "" "."
+		dir=$func_dirname_result
+		# We need an absolute path.
+		case $dir in
+		[\\/]* | [A-Za-z]:[\\/]*) absdir=$dir ;;
+		*)
+		  absdir=`cd "$dir" && pwd`
+		  if test -z "$absdir"; then
+		    func_warning "cannot determine absolute directory name of '$dir'"
+		    absdir=$dir
+		  fi
+		  ;;
+		esac
+		if $GREP "^installed=no" $deplib > /dev/null; then
+		case $host in
+		*-*-darwin*)
+		  depdepl=
+		  eval deplibrary_names=`$SED -n -e 's/^library_names=\(.*\)$/\1/p' $deplib`
+		  if test -n "$deplibrary_names"; then
+		    for tmp in $deplibrary_names; do
+		      depdepl=$tmp
+		    done
+		    if test -f "$absdir/$objdir/$depdepl"; then
+		      depdepl=$absdir/$objdir/$depdepl
+		      darwin_install_name=`$OTOOL -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'`
+                      if test -z "$darwin_install_name"; then
+                          darwin_install_name=`$OTOOL64 -L $depdepl  | awk '{if (NR == 2) {print $1;exit}}'`
+                      fi
+		      func_append compiler_flags " $wl-dylib_file $wl$darwin_install_name:$depdepl"
+		      func_append linker_flags " -dylib_file $darwin_install_name:$depdepl"
+		      path=
+		    fi
+		  fi
+		  ;;
+		*)
+		  path=-L$absdir/$objdir
+		  ;;
+		esac
+		else
+		  eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $deplib`
+		  test -z "$libdir" && \
+		    func_fatal_error "'$deplib' is not a valid libtool archive"
+		  test "$absdir" != "$libdir" && \
+		    func_warning "'$deplib' seems to be moved"
+
+		  path=-L$absdir
+		fi
+		;;
+	      esac
+	      case " $deplibs " in
+	      *" $path "*) ;;
+	      *) deplibs="$path $deplibs" ;;
+	      esac
+	    done
+	  fi # link_all_deplibs != no
+	fi # linkmode = lib
+      done # for deplib in $libs
+      if test link = "$pass"; then
+	if test prog = "$linkmode"; then
+	  compile_deplibs="$new_inherited_linker_flags $compile_deplibs"
+	  finalize_deplibs="$new_inherited_linker_flags $finalize_deplibs"
+	else
+	  compiler_flags="$compiler_flags "`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+	fi
+      fi
+      dependency_libs=$newdependency_libs
+      if test dlpreopen = "$pass"; then
+	# Link the dlpreopened libraries before other libraries
+	for deplib in $save_deplibs; do
+	  deplibs="$deplib $deplibs"
+	done
+      fi
+      if test dlopen != "$pass"; then
+	test conv = "$pass" || {
+	  # Make sure lib_search_path contains only unique directories.
+	  lib_search_path=
+	  for dir in $newlib_search_path; do
+	    case "$lib_search_path " in
+	    *" $dir "*) ;;
+	    *) func_append lib_search_path " $dir" ;;
+	    esac
+	  done
+	  newlib_search_path=
+	}
+
+	if test prog,link = "$linkmode,$pass"; then
+	  vars="compile_deplibs finalize_deplibs"
+	else
+	  vars=deplibs
+	fi
+	for var in $vars dependency_libs; do
+	  # Add libraries to $var in reverse order
+	  eval tmp_libs=\"\$$var\"
+	  new_libs=
+	  for deplib in $tmp_libs; do
+	    # FIXME: Pedantically, this is the right thing to do, so
+	    #        that some nasty dependency loop isn't accidentally
+	    #        broken:
+	    #new_libs="$deplib $new_libs"
+	    # Pragmatically, this seems to cause very few problems in
+	    # practice:
+	    case $deplib in
+	    -L*) new_libs="$deplib $new_libs" ;;
+	    -R*) ;;
+	    *)
+	      # And here is the reason: when a library appears more
+	      # than once as an explicit dependence of a library, or
+	      # is implicitly linked in more than once by the
+	      # compiler, it is considered special, and multiple
+	      # occurrences thereof are not removed.  Compare this
+	      # with having the same library being listed as a
+	      # dependency of multiple other libraries: in this case,
+	      # we know (pedantically, we assume) the library does not
+	      # need to be listed more than once, so we keep only the
+	      # last copy.  This is not always right, but it is rare
+	      # enough that we require users that really mean to play
+	      # such unportable linking tricks to link the library
+	      # using -Wl,-lname, so that libtool does not consider it
+	      # for duplicate removal.
+	      case " $specialdeplibs " in
+	      *" $deplib "*) new_libs="$deplib $new_libs" ;;
+	      *)
+		case " $new_libs " in
+		*" $deplib "*) ;;
+		*) new_libs="$deplib $new_libs" ;;
+		esac
+		;;
+	      esac
+	      ;;
+	    esac
+	  done
+	  tmp_libs=
+	  for deplib in $new_libs; do
+	    case $deplib in
+	    -L*)
+	      case " $tmp_libs " in
+	      *" $deplib "*) ;;
+	      *) func_append tmp_libs " $deplib" ;;
+	      esac
+	      ;;
+	    *) func_append tmp_libs " $deplib" ;;
+	    esac
+	  done
+	  eval $var=\"$tmp_libs\"
+	done # for var
+      fi
+
+      # Add Sun CC postdeps if required:
+      test CXX = "$tagname" && {
+        case $host_os in
+        linux*)
+          case `$CC -V 2>&1 | sed 5q` in
+          *Sun\ C*) # Sun C++ 5.9
+            func_suncc_cstd_abi
+
+            if test no != "$suncc_use_cstd_abi"; then
+              func_append postdeps ' -library=Cstd -library=Crun'
+            fi
+            ;;
+          esac
+          ;;
+
+        solaris*)
+          func_cc_basename "$CC"
+          case $func_cc_basename_result in
+          CC* | sunCC*)
+            func_suncc_cstd_abi
+
+            if test no != "$suncc_use_cstd_abi"; then
+              func_append postdeps ' -library=Cstd -library=Crun'
+            fi
+            ;;
+          esac
+          ;;
+        esac
+      }
+
+      # Last step: remove runtime libs from dependency_libs
+      # (they stay in deplibs)
+      tmp_libs=
+      for i in $dependency_libs; do
+	case " $predeps $postdeps $compiler_lib_search_path " in
+	*" $i "*)
+	  i=
+	  ;;
+	esac
+	if test -n "$i"; then
+	  func_append tmp_libs " $i"
+	fi
+      done
+      dependency_libs=$tmp_libs
+    done # for pass
+    if test prog = "$linkmode"; then
+      dlfiles=$newdlfiles
+    fi
+    if test prog = "$linkmode" || test lib = "$linkmode"; then
+      dlprefiles=$newdlprefiles
+    fi
+
+    case $linkmode in
+    oldlib)
+      if test -n "$dlfiles$dlprefiles" || test no != "$dlself"; then
+	func_warning "'-dlopen' is ignored for archives"
+      fi
+
+      case " $deplibs" in
+      *\ -l* | *\ -L*)
+	func_warning "'-l' and '-L' are ignored for archives" ;;
+      esac
+
+      test -n "$rpath" && \
+	func_warning "'-rpath' is ignored for archives"
+
+      test -n "$xrpath" && \
+	func_warning "'-R' is ignored for archives"
+
+      test -n "$vinfo" && \
+	func_warning "'-version-info/-version-number' is ignored for archives"
+
+      test -n "$release" && \
+	func_warning "'-release' is ignored for archives"
+
+      test -n "$export_symbols$export_symbols_regex" && \
+	func_warning "'-export-symbols' is ignored for archives"
+
+      # Now set the variables for building old libraries.
+      build_libtool_libs=no
+      oldlibs=$output
+      func_append objs "$old_deplibs"
+      ;;
+
+    lib)
+      # Make sure we only generate libraries of the form 'libNAME.la'.
+      case $outputname in
+      lib*)
+	func_stripname 'lib' '.la' "$outputname"
+	name=$func_stripname_result
+	eval shared_ext=\"$shrext_cmds\"
+	eval libname=\"$libname_spec\"
+	;;
+      *)
+	test no = "$module" \
+	  && func_fatal_help "libtool library '$output' must begin with 'lib'"
+
+	if test no != "$need_lib_prefix"; then
+	  # Add the "lib" prefix for modules if required
+	  func_stripname '' '.la' "$outputname"
+	  name=$func_stripname_result
+	  eval shared_ext=\"$shrext_cmds\"
+	  eval libname=\"$libname_spec\"
+	else
+	  func_stripname '' '.la' "$outputname"
+	  libname=$func_stripname_result
+	fi
+	;;
+      esac
+
+      if test -n "$objs"; then
+	if test pass_all != "$deplibs_check_method"; then
+	  func_fatal_error "cannot build libtool library '$output' from non-libtool objects on this host:$objs"
+	else
+	  echo
+	  $ECHO "*** Warning: Linking the shared library $output against the non-libtool"
+	  $ECHO "*** objects $objs is not portable!"
+	  func_append libobjs " $objs"
+	fi
+      fi
+
+      test no = "$dlself" \
+	|| func_warning "'-dlopen self' is ignored for libtool libraries"
+
+      set dummy $rpath
+      shift
+      test 1 -lt "$#" \
+	&& func_warning "ignoring multiple '-rpath's for a libtool library"
+
+      install_libdir=$1
+
+      oldlibs=
+      if test -z "$rpath"; then
+	if test yes = "$build_libtool_libs"; then
+	  # Building a libtool convenience library.
+	  # Some compilers have problems with a '.al' extension so
+	  # convenience libraries should have the same extension an
+	  # archive normally would.
+	  oldlibs="$output_objdir/$libname.$libext $oldlibs"
+	  build_libtool_libs=convenience
+	  build_old_libs=yes
+	fi
+
+	test -n "$vinfo" && \
+	  func_warning "'-version-info/-version-number' is ignored for convenience libraries"
+
+	test -n "$release" && \
+	  func_warning "'-release' is ignored for convenience libraries"
+      else
+
+	# Parse the version information argument.
+	save_ifs=$IFS; IFS=:
+	set dummy $vinfo 0 0 0
+	shift
+	IFS=$save_ifs
+
+	test -n "$7" && \
+	  func_fatal_help "too many parameters to '-version-info'"
+
+	# convert absolute version numbers to libtool ages
+	# this retains compatibility with .la files and attempts
+	# to make the code below a bit more comprehensible
+
+	case $vinfo_number in
+	yes)
+	  number_major=$1
+	  number_minor=$2
+	  number_revision=$3
+	  #
+	  # There are really only two kinds -- those that
+	  # use the current revision as the major version
+	  # and those that subtract age and use age as
+	  # a minor version.  But, then there is irix
+	  # that has an extra 1 added just for fun
+	  #
+	  case $version_type in
+	  # correct linux to gnu/linux during the next big refactor
+	  darwin|freebsd-elf|linux|osf|windows|none)
+	    func_arith $number_major + $number_minor
+	    current=$func_arith_result
+	    age=$number_minor
+	    revision=$number_revision
+	    ;;
+	  freebsd-aout|qnx|sunos)
+	    current=$number_major
+	    revision=$number_minor
+	    age=0
+	    ;;
+	  irix|nonstopux)
+	    func_arith $number_major + $number_minor
+	    current=$func_arith_result
+	    age=$number_minor
+	    revision=$number_minor
+	    lt_irix_increment=no
+	    ;;
+	  *)
+	    func_fatal_configuration "$modename: unknown library version type '$version_type'"
+	    ;;
+	  esac
+	  ;;
+	no)
+	  current=$1
+	  revision=$2
+	  age=$3
+	  ;;
+	esac
+
+	# Check that each of the things are valid numbers.
+	case $current in
+	0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;;
+	*)
+	  func_error "CURRENT '$current' must be a nonnegative integer"
+	  func_fatal_error "'$vinfo' is not valid version information"
+	  ;;
+	esac
+
+	case $revision in
+	0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;;
+	*)
+	  func_error "REVISION '$revision' must be a nonnegative integer"
+	  func_fatal_error "'$vinfo' is not valid version information"
+	  ;;
+	esac
+
+	case $age in
+	0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;;
+	*)
+	  func_error "AGE '$age' must be a nonnegative integer"
+	  func_fatal_error "'$vinfo' is not valid version information"
+	  ;;
+	esac
+
+	if test "$age" -gt "$current"; then
+	  func_error "AGE '$age' is greater than the current interface number '$current'"
+	  func_fatal_error "'$vinfo' is not valid version information"
+	fi
+
+	# Calculate the version variables.
+	major=
+	versuffix=
+	verstring=
+	case $version_type in
+	none) ;;
+
+	darwin)
+	  # Like Linux, but with the current version available in
+	  # verstring for coding it into the library header
+	  func_arith $current - $age
+	  major=.$func_arith_result
+	  versuffix=$major.$age.$revision
+	  # Darwin ld doesn't like 0 for these options...
+	  func_arith $current + 1
+	  minor_current=$func_arith_result
+	  xlcverstring="$wl-compatibility_version $wl$minor_current $wl-current_version $wl$minor_current.$revision"
+	  verstring="-compatibility_version $minor_current -current_version $minor_current.$revision"
+          # On Darwin other compilers
+          case $CC in
+              nagfor*)
+                  verstring="$wl-compatibility_version $wl$minor_current $wl-current_version $wl$minor_current.$revision"
+                  ;;
+              *)
+                  verstring="-compatibility_version $minor_current -current_version $minor_current.$revision"
+                  ;;
+          esac
+	  ;;
+
+	freebsd-aout)
+	  major=.$current
+	  versuffix=.$current.$revision
+	  ;;
+
+	freebsd-elf)
+	  func_arith $current - $age
+	  major=.$func_arith_result
+	  versuffix=$major.$age.$revision
+	  ;;
+
+	irix | nonstopux)
+	  if test no = "$lt_irix_increment"; then
+	    func_arith $current - $age
+	  else
+	    func_arith $current - $age + 1
+	  fi
+	  major=$func_arith_result
+
+	  case $version_type in
+	    nonstopux) verstring_prefix=nonstopux ;;
+	    *)         verstring_prefix=sgi ;;
+	  esac
+	  verstring=$verstring_prefix$major.$revision
+
+	  # Add in all the interfaces that we are compatible with.
+	  loop=$revision
+	  while test 0 -ne "$loop"; do
+	    func_arith $revision - $loop
+	    iface=$func_arith_result
+	    func_arith $loop - 1
+	    loop=$func_arith_result
+	    verstring=$verstring_prefix$major.$iface:$verstring
+	  done
+
+	  # Before this point, $major must not contain '.'.
+	  major=.$major
+	  versuffix=$major.$revision
+	  ;;
+
+	linux) # correct to gnu/linux during the next big refactor
+	  func_arith $current - $age
+	  major=.$func_arith_result
+	  versuffix=$major.$age.$revision
+	  ;;
+
+	osf)
+	  func_arith $current - $age
+	  major=.$func_arith_result
+	  versuffix=.$current.$age.$revision
+	  verstring=$current.$age.$revision
+
+	  # Add in all the interfaces that we are compatible with.
+	  loop=$age
+	  while test 0 -ne "$loop"; do
+	    func_arith $current - $loop
+	    iface=$func_arith_result
+	    func_arith $loop - 1
+	    loop=$func_arith_result
+	    verstring=$verstring:$iface.0
+	  done
+
+	  # Make executables depend on our current version.
+	  func_append verstring ":$current.0"
+	  ;;
+
+	qnx)
+	  major=.$current
+	  versuffix=.$current
+	  ;;
+
+	sco)
+	  major=.$current
+	  versuffix=.$current
+	  ;;
+
+	sunos)
+	  major=.$current
+	  versuffix=.$current.$revision
+	  ;;
+
+	windows)
+	  # Use '-' rather than '.', since we only want one
+	  # extension on DOS 8.3 file systems.
+	  func_arith $current - $age
+	  major=$func_arith_result
+	  versuffix=-$major
+	  ;;
+
+	*)
+	  func_fatal_configuration "unknown library version type '$version_type'"
+	  ;;
+	esac
+
+	# Clear the version info if we defaulted, and they specified a release.
+	if test -z "$vinfo" && test -n "$release"; then
+	  major=
+	  case $version_type in
+	  darwin)
+	    # we can't check for "0.0" in archive_cmds due to quoting
+	    # problems, so we reset it completely
+	    verstring=
+	    ;;
+	  *)
+	    verstring=0.0
+	    ;;
+	  esac
+	  if test no = "$need_version"; then
+	    versuffix=
+	  else
+	    versuffix=.0.0
+	  fi
+	fi
+
+	# Remove version info from name if versioning should be avoided
+	if test yes,no = "$avoid_version,$need_version"; then
+	  major=
+	  versuffix=
+	  verstring=
+	fi
+
+	# Check to see if the archive will have undefined symbols.
+	if test yes = "$allow_undefined"; then
+	  if test unsupported = "$allow_undefined_flag"; then
+	    if test yes = "$build_old_libs"; then
+	      func_warning "undefined symbols not allowed in $host shared libraries; building static only"
+	      build_libtool_libs=no
+	    else
+	      func_fatal_error "can't build $host shared library unless -no-undefined is specified"
+	    fi
+	  fi
+	else
+	  # Don't allow undefined symbols.
+	  allow_undefined_flag=$no_undefined_flag
+	fi
+
+      fi
+
+      func_generate_dlsyms "$libname" "$libname" :
+      func_append libobjs " $symfileobj"
+      test " " = "$libobjs" && libobjs=
+
+      if test relink != "$opt_mode"; then
+	# Remove our outputs, but don't remove object files since they
+	# may have been created when compiling PIC objects.
+	removelist=
+	tempremovelist=`$ECHO "$output_objdir/*"`
+	for p in $tempremovelist; do
+	  case $p in
+	    *.$objext | *.gcno)
+	       ;;
+	    $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/$libname$release.*)
+	       if test -n "$precious_files_regex"; then
+		 if $ECHO "$p" | $EGREP -e "$precious_files_regex" >/dev/null 2>&1
+		 then
+		   continue
+		 fi
+	       fi
+	       func_append removelist " $p"
+	       ;;
+	    *) ;;
+	  esac
+	done
+	test -n "$removelist" && \
+	  func_show_eval "${RM}r \$removelist"
+      fi
+
+      # Now set the variables for building old libraries.
+      if test yes = "$build_old_libs" && test convenience != "$build_libtool_libs"; then
+	func_append oldlibs " $output_objdir/$libname.$libext"
+
+	# Transform .lo files to .o files.
+	oldobjs="$objs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.$libext$/d; $lo2o" | $NL2SP`
+      fi
+
+      # Eliminate all temporary directories.
+      #for path in $notinst_path; do
+      #	lib_search_path=`$ECHO "$lib_search_path " | $SED "s% $path % %g"`
+      #	deplibs=`$ECHO "$deplibs " | $SED "s% -L$path % %g"`
+      #	dependency_libs=`$ECHO "$dependency_libs " | $SED "s% -L$path % %g"`
+      #done
+
+      if test -n "$xrpath"; then
+	# If the user specified any rpath flags, then add them.
+	temp_xrpath=
+	for libdir in $xrpath; do
+	  func_replace_sysroot "$libdir"
+	  func_append temp_xrpath " -R$func_replace_sysroot_result"
+	  case "$finalize_rpath " in
+	  *" $libdir "*) ;;
+	  *) func_append finalize_rpath " $libdir" ;;
+	  esac
+	done
+	if test yes != "$hardcode_into_libs" || test yes = "$build_old_libs"; then
+	  dependency_libs="$temp_xrpath $dependency_libs"
+	fi
+      fi
+
+      # Make sure dlfiles contains only unique files that won't be dlpreopened
+      old_dlfiles=$dlfiles
+      dlfiles=
+      for lib in $old_dlfiles; do
+	case " $dlprefiles $dlfiles " in
+	*" $lib "*) ;;
+	*) func_append dlfiles " $lib" ;;
+	esac
+      done
+
+      # Make sure dlprefiles contains only unique files
+      old_dlprefiles=$dlprefiles
+      dlprefiles=
+      for lib in $old_dlprefiles; do
+	case "$dlprefiles " in
+	*" $lib "*) ;;
+	*) func_append dlprefiles " $lib" ;;
+	esac
+      done
+
+      if test yes = "$build_libtool_libs"; then
+	if test -n "$rpath"; then
+	  case $host in
+	  *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos* | *-cegcc* | *-*-haiku*)
+	    # these systems don't actually have a c library (as such)!
+	    ;;
+	  *-*-rhapsody* | *-*-darwin1.[012])
+	    # Rhapsody C library is in the System framework
+	    func_append deplibs " System.ltframework"
+	    ;;
+	  *-*-netbsd*)
+	    # Don't link with libc until the a.out ld.so is fixed.
+	    ;;
+	  *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*)
+	    # Do not include libc due to us having libc/libc_r.
+	    ;;
+	  *-*-sco3.2v5* | *-*-sco5v6*)
+	    # Causes problems with __ctype
+	    ;;
+	  *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*)
+	    # Compiler inserts libc in the correct place for threads to work
+	    ;;
+	  *)
+	    # Add libc to deplibs on all other systems if necessary.
+	    if test yes = "$build_libtool_need_lc"; then
+	      func_append deplibs " -lc"
+	    fi
+	    ;;
+	  esac
+	fi
+
+	# Transform deplibs into only deplibs that can be linked in shared.
+	name_save=$name
+	libname_save=$libname
+	release_save=$release
+	versuffix_save=$versuffix
+	major_save=$major
+	# I'm not sure if I'm treating the release correctly.  I think
+	# release should show up in the -l (ie -lgmp5) so we don't want to
+	# add it in twice.  Is that correct?
+	release=
+	versuffix=
+	major=
+	newdeplibs=
+	droppeddeps=no
+	case $deplibs_check_method in
+	pass_all)
+	  # Don't check for shared/static.  Everything works.
+	  # This might be a little naive.  We might want to check
+	  # whether the library exists or not.  But this is on
+	  # osf3 & osf4 and I'm not really sure... Just
+	  # implementing what was already the behavior.
+	  newdeplibs=$deplibs
+	  ;;
+	test_compile)
+	  # This code stresses the "libraries are programs" paradigm to its
+	  # limits. Maybe even breaks it.  We compile a program, linking it
+	  # against the deplibs as a proxy for the library.  Then we can check
+	  # whether they linked in statically or dynamically with ldd.
+	  $opt_dry_run || $RM conftest.c
+	  cat > conftest.c <<EOF
+	  int main() { return 0; }
+EOF
+	  $opt_dry_run || $RM conftest
+	  if $LTCC $LTCFLAGS -o conftest conftest.c $deplibs; then
+	    ldd_output=`ldd conftest`
+	    for i in $deplibs; do
+	      case $i in
+	      -l*)
+		func_stripname -l '' "$i"
+		name=$func_stripname_result
+		if test yes = "$allow_libtool_libs_with_static_runtimes"; then
+		  case " $predeps $postdeps " in
+		  *" $i "*)
+		    func_append newdeplibs " $i"
+		    i=
+		    ;;
+		  esac
+		fi
+		if test -n "$i"; then
+		  libname=`eval "\\$ECHO \"$libname_spec\""`
+		  deplib_matches=`eval "\\$ECHO \"$library_names_spec\""`
+		  set dummy $deplib_matches; shift
+		  deplib_match=$1
+		  if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0; then
+		    func_append newdeplibs " $i"
+		  else
+		    droppeddeps=yes
+		    echo
+		    $ECHO "*** Warning: dynamic linker does not accept needed library $i."
+		    echo "*** I have the capability to make that library automatically link in when"
+		    echo "*** you link to this library.  But I can only do this if you have a"
+		    echo "*** shared version of the library, which I believe you do not have"
+		    echo "*** because a test_compile did reveal that the linker did not use it for"
+		    echo "*** its dynamic dependency list that programs get resolved with at runtime."
+		  fi
+		fi
+		;;
+	      *)
+		func_append newdeplibs " $i"
+		;;
+	      esac
+	    done
+	  else
+	    # Error occurred in the first compile.  Let's try to salvage
+	    # the situation: Compile a separate program for each library.
+	    for i in $deplibs; do
+	      case $i in
+	      -l*)
+		func_stripname -l '' "$i"
+		name=$func_stripname_result
+		$opt_dry_run || $RM conftest
+		if $LTCC $LTCFLAGS -o conftest conftest.c $i; then
+		  ldd_output=`ldd conftest`
+		  if test yes = "$allow_libtool_libs_with_static_runtimes"; then
+		    case " $predeps $postdeps " in
+		    *" $i "*)
+		      func_append newdeplibs " $i"
+		      i=
+		      ;;
+		    esac
+		  fi
+		  if test -n "$i"; then
+		    libname=`eval "\\$ECHO \"$libname_spec\""`
+		    deplib_matches=`eval "\\$ECHO \"$library_names_spec\""`
+		    set dummy $deplib_matches; shift
+		    deplib_match=$1
+		    if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0; then
+		      func_append newdeplibs " $i"
+		    else
+		      droppeddeps=yes
+		      echo
+		      $ECHO "*** Warning: dynamic linker does not accept needed library $i."
+		      echo "*** I have the capability to make that library automatically link in when"
+		      echo "*** you link to this library.  But I can only do this if you have a"
+		      echo "*** shared version of the library, which you do not appear to have"
+		      echo "*** because a test_compile did reveal that the linker did not use this one"
+		      echo "*** as a dynamic dependency that programs can get resolved with at runtime."
+		    fi
+		  fi
+		else
+		  droppeddeps=yes
+		  echo
+		  $ECHO "*** Warning!  Library $i is needed by this library but I was not able to"
+		  echo "*** make it link in!  You will probably need to install it or some"
+		  echo "*** library that it depends on before this library will be fully"
+		  echo "*** functional.  Installing it before continuing would be even better."
+		fi
+		;;
+	      *)
+		func_append newdeplibs " $i"
+		;;
+	      esac
+	    done
+	  fi
+	  ;;
+	file_magic*)
+	  set dummy $deplibs_check_method; shift
+	  file_magic_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"`
+	  for a_deplib in $deplibs; do
+	    case $a_deplib in
+	    -l*)
+	      func_stripname -l '' "$a_deplib"
+	      name=$func_stripname_result
+	      if test yes = "$allow_libtool_libs_with_static_runtimes"; then
+		case " $predeps $postdeps " in
+		*" $a_deplib "*)
+		  func_append newdeplibs " $a_deplib"
+		  a_deplib=
+		  ;;
+		esac
+	      fi
+	      if test -n "$a_deplib"; then
+		libname=`eval "\\$ECHO \"$libname_spec\""`
+		if test -n "$file_magic_glob"; then
+		  libnameglob=`func_echo_all "$libname" | $SED -e $file_magic_glob`
+		else
+		  libnameglob=$libname
+		fi
+		test yes = "$want_nocaseglob" && nocaseglob=`shopt -p nocaseglob`
+		for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do
+		  if test yes = "$want_nocaseglob"; then
+		    shopt -s nocaseglob
+		    potential_libs=`ls $i/$libnameglob[.-]* 2>/dev/null`
+		    $nocaseglob
+		  else
+		    potential_libs=`ls $i/$libnameglob[.-]* 2>/dev/null`
+		  fi
+		  for potent_lib in $potential_libs; do
+		      # Follow soft links.
+		      if ls -lLd "$potent_lib" 2>/dev/null |
+			 $GREP " -> " >/dev/null; then
+			continue
+		      fi
+		      # The statement above tries to avoid entering an
+		      # endless loop below, in case of cyclic links.
+		      # We might still enter an endless loop, since a link
+		      # loop can be closed while we follow links,
+		      # but so what?
+		      potlib=$potent_lib
+		      while test -h "$potlib" 2>/dev/null; do
+			potliblink=`ls -ld $potlib | $SED 's/.* -> //'`
+			case $potliblink in
+			[\\/]* | [A-Za-z]:[\\/]*) potlib=$potliblink;;
+			*) potlib=`$ECHO "$potlib" | $SED 's|[^/]*$||'`"$potliblink";;
+			esac
+		      done
+		      if eval $file_magic_cmd \"\$potlib\" 2>/dev/null |
+			 $SED -e 10q |
+			 $EGREP "$file_magic_regex" > /dev/null; then
+			func_append newdeplibs " $a_deplib"
+			a_deplib=
+			break 2
+		      fi
+		  done
+		done
+	      fi
+	      if test -n "$a_deplib"; then
+		droppeddeps=yes
+		echo
+		$ECHO "*** Warning: linker path does not have real file for library $a_deplib."
+		echo "*** I have the capability to make that library automatically link in when"
+		echo "*** you link to this library.  But I can only do this if you have a"
+		echo "*** shared version of the library, which you do not appear to have"
+		echo "*** because I did check the linker path looking for a file starting"
+		if test -z "$potlib"; then
+		  $ECHO "*** with $libname but no candidates were found. (...for file magic test)"
+		else
+		  $ECHO "*** with $libname and none of the candidates passed a file format test"
+		  $ECHO "*** using a file magic. Last file checked: $potlib"
+		fi
+	      fi
+	      ;;
+	    *)
+	      # Add a -L argument.
+	      func_append newdeplibs " $a_deplib"
+	      ;;
+	    esac
+	  done # Gone through all deplibs.
+	  ;;
+	match_pattern*)
+	  set dummy $deplibs_check_method; shift
+	  match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"`
+	  for a_deplib in $deplibs; do
+	    case $a_deplib in
+	    -l*)
+	      func_stripname -l '' "$a_deplib"
+	      name=$func_stripname_result
+	      if test yes = "$allow_libtool_libs_with_static_runtimes"; then
+		case " $predeps $postdeps " in
+		*" $a_deplib "*)
+		  func_append newdeplibs " $a_deplib"
+		  a_deplib=
+		  ;;
+		esac
+	      fi
+	      if test -n "$a_deplib"; then
+		libname=`eval "\\$ECHO \"$libname_spec\""`
+		for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do
+		  potential_libs=`ls $i/$libname[.-]* 2>/dev/null`
+		  for potent_lib in $potential_libs; do
+		    potlib=$potent_lib # see symlink-check above in file_magic test
+		    if eval "\$ECHO \"$potent_lib\"" 2>/dev/null | $SED 10q | \
+		       $EGREP "$match_pattern_regex" > /dev/null; then
+		      func_append newdeplibs " $a_deplib"
+		      a_deplib=
+		      break 2
+		    fi
+		  done
+		done
+	      fi
+	      if test -n "$a_deplib"; then
+		droppeddeps=yes
+		echo
+		$ECHO "*** Warning: linker path does not have real file for library $a_deplib."
+		echo "*** I have the capability to make that library automatically link in when"
+		echo "*** you link to this library.  But I can only do this if you have a"
+		echo "*** shared version of the library, which you do not appear to have"
+		echo "*** because I did check the linker path looking for a file starting"
+		if test -z "$potlib"; then
+		  $ECHO "*** with $libname but no candidates were found. (...for regex pattern test)"
+		else
+		  $ECHO "*** with $libname and none of the candidates passed a file format test"
+		  $ECHO "*** using a regex pattern. Last file checked: $potlib"
+		fi
+	      fi
+	      ;;
+	    *)
+	      # Add a -L argument.
+	      func_append newdeplibs " $a_deplib"
+	      ;;
+	    esac
+	  done # Gone through all deplibs.
+	  ;;
+	none | unknown | *)
+	  newdeplibs=
+	  tmp_deplibs=`$ECHO " $deplibs" | $SED 's/ -lc$//; s/ -[LR][^ ]*//g'`
+	  if test yes = "$allow_libtool_libs_with_static_runtimes"; then
+	    for i in $predeps $postdeps; do
+	      # can't use Xsed below, because $i might contain '/'
+	      tmp_deplibs=`$ECHO " $tmp_deplibs" | $SED "s|$i||"`
+	    done
+	  fi
+	  case $tmp_deplibs in
+	  *[!\	\ ]*)
+	    echo
+	    if test none = "$deplibs_check_method"; then
+	      echo "*** Warning: inter-library dependencies are not supported in this platform."
+	    else
+	      echo "*** Warning: inter-library dependencies are not known to be supported."
+	    fi
+	    echo "*** All declared inter-library dependencies are being dropped."
+	    droppeddeps=yes
+	    ;;
+	  esac
+	  ;;
+	esac
+	versuffix=$versuffix_save
+	major=$major_save
+	release=$release_save
+	libname=$libname_save
+	name=$name_save
+
+	case $host in
+	*-*-rhapsody* | *-*-darwin1.[012])
+	  # On Rhapsody replace the C library with the System framework
+	  newdeplibs=`$ECHO " $newdeplibs" | $SED 's/ -lc / System.ltframework /'`
+	  ;;
+	esac
+
+	if test yes = "$droppeddeps"; then
+	  if test yes = "$module"; then
+	    echo
+	    echo "*** Warning: libtool could not satisfy all declared inter-library"
+	    $ECHO "*** dependencies of module $libname.  Therefore, libtool will create"
+	    echo "*** a static module, that should work as long as the dlopening"
+	    echo "*** application is linked with the -dlopen flag."
+	    if test -z "$global_symbol_pipe"; then
+	      echo
+	      echo "*** However, this would only work if libtool was able to extract symbol"
+	      echo "*** lists from a program, using 'nm' or equivalent, but libtool could"
+	      echo "*** not find such a program.  So, this module is probably useless."
+	      echo "*** 'nm' from GNU binutils and a full rebuild may help."
+	    fi
+	    if test no = "$build_old_libs"; then
+	      oldlibs=$output_objdir/$libname.$libext
+	      build_libtool_libs=module
+	      build_old_libs=yes
+	    else
+	      build_libtool_libs=no
+	    fi
+	  else
+	    echo "*** The inter-library dependencies that have been dropped here will be"
+	    echo "*** automatically added whenever a program is linked with this library"
+	    echo "*** or is declared to -dlopen it."
+
+	    if test no = "$allow_undefined"; then
+	      echo
+	      echo "*** Since this library must not contain undefined symbols,"
+	      echo "*** because either the platform does not support them or"
+	      echo "*** it was explicitly requested with -no-undefined,"
+	      echo "*** libtool will only create a static version of it."
+	      if test no = "$build_old_libs"; then
+		oldlibs=$output_objdir/$libname.$libext
+		build_libtool_libs=module
+		build_old_libs=yes
+	      else
+		build_libtool_libs=no
+	      fi
+	    fi
+	  fi
+	fi
+	# Done checking deplibs!
+	deplibs=$newdeplibs
+      fi
+      # Time to change all our "foo.ltframework" stuff back to "-framework foo"
+      case $host in
+	*-*-darwin*)
+	  newdeplibs=`$ECHO " $newdeplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+	  new_inherited_linker_flags=`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+	  deplibs=`$ECHO " $deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+	  ;;
+      esac
+
+      # move library search paths that coincide with paths to not yet
+      # installed libraries to the beginning of the library search list
+      new_libs=
+      for path in $notinst_path; do
+	case " $new_libs " in
+	*" -L$path/$objdir "*) ;;
+	*)
+	  case " $deplibs " in
+	  *" -L$path/$objdir "*)
+	    func_append new_libs " -L$path/$objdir" ;;
+	  esac
+	  ;;
+	esac
+      done
+      for deplib in $deplibs; do
+	case $deplib in
+	-L*)
+	  case " $new_libs " in
+	  *" $deplib "*) ;;
+	  *) func_append new_libs " $deplib" ;;
+	  esac
+	  ;;
+	*) func_append new_libs " $deplib" ;;
+	esac
+      done
+      deplibs=$new_libs
+
+      # All the library-specific variables (install_libdir is set above).
+      library_names=
+      old_library=
+      dlname=
+
+      # Test again, we may have decided not to build it any more
+      if test yes = "$build_libtool_libs"; then
+	# Remove $wl instances when linking with ld.
+	# FIXME: should test the right _cmds variable.
+	case $archive_cmds in
+	  *\$LD\ *) wl= ;;
+        esac
+	if test yes = "$hardcode_into_libs"; then
+	  # Hardcode the library paths
+	  hardcode_libdirs=
+	  dep_rpath=
+	  rpath=$finalize_rpath
+	  test relink = "$opt_mode" || rpath=$compile_rpath$rpath
+	  for libdir in $rpath; do
+	    if test -n "$hardcode_libdir_flag_spec"; then
+	      if test -n "$hardcode_libdir_separator"; then
+		func_replace_sysroot "$libdir"
+		libdir=$func_replace_sysroot_result
+		if test -z "$hardcode_libdirs"; then
+		  hardcode_libdirs=$libdir
+		else
+		  # Just accumulate the unique libdirs.
+		  case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
+		  *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+		    ;;
+		  *)
+		    func_append hardcode_libdirs "$hardcode_libdir_separator$libdir"
+		    ;;
+		  esac
+		fi
+	      else
+		eval flag=\"$hardcode_libdir_flag_spec\"
+		func_append dep_rpath " $flag"
+	      fi
+	    elif test -n "$runpath_var"; then
+	      case "$perm_rpath " in
+	      *" $libdir "*) ;;
+	      *) func_append perm_rpath " $libdir" ;;
+	      esac
+	    fi
+	  done
+	  # Substitute the hardcoded libdirs into the rpath.
+	  if test -n "$hardcode_libdir_separator" &&
+	     test -n "$hardcode_libdirs"; then
+	    libdir=$hardcode_libdirs
+	    eval "dep_rpath=\"$hardcode_libdir_flag_spec\""
+	  fi
+	  if test -n "$runpath_var" && test -n "$perm_rpath"; then
+	    # We should set the runpath_var.
+	    rpath=
+	    for dir in $perm_rpath; do
+	      func_append rpath "$dir:"
+	    done
+	    eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var"
+	  fi
+	  test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs"
+	fi
+
+	shlibpath=$finalize_shlibpath
+	test relink = "$opt_mode" || shlibpath=$compile_shlibpath$shlibpath
+	if test -n "$shlibpath"; then
+	  eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var"
+	fi
+
+	# Get the real and link names of the library.
+	eval shared_ext=\"$shrext_cmds\"
+	eval library_names=\"$library_names_spec\"
+	set dummy $library_names
+	shift
+	realname=$1
+	shift
+
+	if test -n "$soname_spec"; then
+	  eval soname=\"$soname_spec\"
+	else
+	  soname=$realname
+	fi
+	if test -z "$dlname"; then
+	  dlname=$soname
+	fi
+
+	lib=$output_objdir/$realname
+	linknames=
+	for link
+	do
+	  func_append linknames " $link"
+	done
+
+	# Use standard objects if they are pic
+	test -z "$pic_flag" && libobjs=`$ECHO "$libobjs" | $SP2NL | $SED "$lo2o" | $NL2SP`
+	test "X$libobjs" = "X " && libobjs=
+
+	delfiles=
+	if test -n "$export_symbols" && test -n "$include_expsyms"; then
+	  $opt_dry_run || cp "$export_symbols" "$output_objdir/$libname.uexp"
+	  export_symbols=$output_objdir/$libname.uexp
+	  func_append delfiles " $export_symbols"
+	fi
+
+	orig_export_symbols=
+	case $host_os in
+	cygwin* | mingw* | cegcc*)
+	  if test -n "$export_symbols" && test -z "$export_symbols_regex"; then
+	    # exporting using user supplied symfile
+	    func_dll_def_p "$export_symbols" || {
+	      # and it's NOT already a .def file. Must figure out
+	      # which of the given symbols are data symbols and tag
+	      # them as such. So, trigger use of export_symbols_cmds.
+	      # export_symbols gets reassigned inside the "prepare
+	      # the list of exported symbols" if statement, so the
+	      # include_expsyms logic still works.
+	      orig_export_symbols=$export_symbols
+	      export_symbols=
+	      always_export_symbols=yes
+	    }
+	  fi
+	  ;;
+	esac
+
+	# Prepare the list of exported symbols
+	if test -z "$export_symbols"; then
+	  if test yes = "$always_export_symbols" || test -n "$export_symbols_regex"; then
+	    func_verbose "generating symbol list for '$libname.la'"
+	    export_symbols=$output_objdir/$libname.exp
+	    $opt_dry_run || $RM $export_symbols
+	    cmds=$export_symbols_cmds
+	    save_ifs=$IFS; IFS='~'
+	    for cmd1 in $cmds; do
+	      IFS=$save_ifs
+	      # Take the normal branch if the nm_file_list_spec branch
+	      # doesn't work or if tool conversion is not needed.
+	      case $nm_file_list_spec~$to_tool_file_cmd in
+		*~func_convert_file_noop | *~func_convert_file_msys_to_w32 | ~*)
+		  try_normal_branch=yes
+		  eval cmd=\"$cmd1\"
+		  func_len " $cmd"
+		  len=$func_len_result
+		  ;;
+		*)
+		  try_normal_branch=no
+		  ;;
+	      esac
+	      if test yes = "$try_normal_branch" \
+		 && { test "$len" -lt "$max_cmd_len" \
+		      || test "$max_cmd_len" -le -1; }
+	      then
+		func_show_eval "$cmd" 'exit $?'
+		skipped_export=false
+	      elif test -n "$nm_file_list_spec"; then
+		func_basename "$output"
+		output_la=$func_basename_result
+		save_libobjs=$libobjs
+		save_output=$output
+		output=$output_objdir/$output_la.nm
+		func_to_tool_file "$output"
+		libobjs=$nm_file_list_spec$func_to_tool_file_result
+		func_append delfiles " $output"
+		func_verbose "creating $NM input file list: $output"
+		for obj in $save_libobjs; do
+		  func_to_tool_file "$obj"
+		  $ECHO "$func_to_tool_file_result"
+		done > "$output"
+		eval cmd=\"$cmd1\"
+		func_show_eval "$cmd" 'exit $?'
+		output=$save_output
+		libobjs=$save_libobjs
+		skipped_export=false
+	      else
+		# The command line is too long to execute in one step.
+		func_verbose "using reloadable object file for export list..."
+		skipped_export=:
+		# Break out early, otherwise skipped_export may be
+		# set to false by a later but shorter cmd.
+		break
+	      fi
+	    done
+	    IFS=$save_ifs
+	    if test -n "$export_symbols_regex" && test : != "$skipped_export"; then
+	      func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"'
+	      func_show_eval '$MV "${export_symbols}T" "$export_symbols"'
+	    fi
+	  fi
+	fi
+
+	if test -n "$export_symbols" && test -n "$include_expsyms"; then
+	  tmp_export_symbols=$export_symbols
+	  test -n "$orig_export_symbols" && tmp_export_symbols=$orig_export_symbols
+	  $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"'
+	fi
+
+	if test : != "$skipped_export" && test -n "$orig_export_symbols"; then
+	  # The given exports_symbols file has to be filtered, so filter it.
+	  func_verbose "filter symbol list for '$libname.la' to tag DATA exports"
+	  # FIXME: $output_objdir/$libname.filter potentially contains lots of
+	  # 's' commands, which not all seds can handle. GNU sed should be fine
+	  # though. Also, the filter scales superlinearly with the number of
+	  # global variables. join(1) would be nice here, but unfortunately
+	  # isn't a blessed tool.
+	  $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter
+	  func_append delfiles " $export_symbols $output_objdir/$libname.filter"
+	  export_symbols=$output_objdir/$libname.def
+	  $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols
+	fi
+
+	tmp_deplibs=
+	for test_deplib in $deplibs; do
+	  case " $convenience " in
+	  *" $test_deplib "*) ;;
+	  *)
+	    func_append tmp_deplibs " $test_deplib"
+	    ;;
+	  esac
+	done
+	deplibs=$tmp_deplibs
+
+	if test -n "$convenience"; then
+	  if test -n "$whole_archive_flag_spec" &&
+	    test yes = "$compiler_needs_object" &&
+	    test -z "$libobjs"; then
+	    # extract the archives, so we have objects to list.
+	    # TODO: could optimize this to just extract one archive.
+	    whole_archive_flag_spec=
+	  fi
+	  if test -n "$whole_archive_flag_spec"; then
+	    save_libobjs=$libobjs
+	    eval libobjs=\"\$libobjs $whole_archive_flag_spec\"
+	    test "X$libobjs" = "X " && libobjs=
+	  else
+	    gentop=$output_objdir/${outputname}x
+	    func_append generated " $gentop"
+
+	    func_extract_archives $gentop $convenience
+	    func_append libobjs " $func_extract_archives_result"
+	    test "X$libobjs" = "X " && libobjs=
+	  fi
+	fi
+
+	if test yes = "$thread_safe" && test -n "$thread_safe_flag_spec"; then
+	  eval flag=\"$thread_safe_flag_spec\"
+	  func_append linker_flags " $flag"
+	fi
+
+	# Make a backup of the uninstalled library when relinking
+	if test relink = "$opt_mode"; then
+	  $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}U && $MV $realname ${realname}U)' || exit $?
+	fi
+
+	# Do each of the archive commands.
+	if test yes = "$module" && test -n "$module_cmds"; then
+	  if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then
+	    eval test_cmds=\"$module_expsym_cmds\"
+	    cmds=$module_expsym_cmds
+	  else
+	    eval test_cmds=\"$module_cmds\"
+	    cmds=$module_cmds
+	  fi
+	else
+	  if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then
+	    eval test_cmds=\"$archive_expsym_cmds\"
+	    cmds=$archive_expsym_cmds
+	  else
+	    eval test_cmds=\"$archive_cmds\"
+	    cmds=$archive_cmds
+	  fi
+	fi
+
+	if test : != "$skipped_export" &&
+	   func_len " $test_cmds" &&
+	   len=$func_len_result &&
+	   test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then
+	  :
+	else
+	  # The command line is too long to link in one step, link piecewise
+	  # or, if using GNU ld and skipped_export is not :, use a linker
+	  # script.
+
+	  # Save the value of $output and $libobjs because we want to
+	  # use them later.  If we have whole_archive_flag_spec, we
+	  # want to use save_libobjs as it was before
+	  # whole_archive_flag_spec was expanded, because we can't
+	  # assume the linker understands whole_archive_flag_spec.
+	  # This may have to be revisited, in case too many
+	  # convenience libraries get linked in and end up exceeding
+	  # the spec.
+	  if test -z "$convenience" || test -z "$whole_archive_flag_spec"; then
+	    save_libobjs=$libobjs
+	  fi
+	  save_output=$output
+	  func_basename "$output"
+	  output_la=$func_basename_result
+
+	  # Clear the reloadable object creation command queue and
+	  # initialize k to one.
+	  test_cmds=
+	  concat_cmds=
+	  objlist=
+	  last_robj=
+	  k=1
+
+	  if test -n "$save_libobjs" && test : != "$skipped_export" && test yes = "$with_gnu_ld"; then
+	    output=$output_objdir/$output_la.lnkscript
+	    func_verbose "creating GNU ld script: $output"
+	    echo 'INPUT (' > $output
+	    for obj in $save_libobjs
+	    do
+	      func_to_tool_file "$obj"
+	      $ECHO "$func_to_tool_file_result" >> $output
+	    done
+	    echo ')' >> $output
+	    func_append delfiles " $output"
+	    func_to_tool_file "$output"
+	    output=$func_to_tool_file_result
+	  elif test -n "$save_libobjs" && test : != "$skipped_export" && test -n "$file_list_spec"; then
+	    output=$output_objdir/$output_la.lnk
+	    func_verbose "creating linker input file list: $output"
+	    : > $output
+	    set x $save_libobjs
+	    shift
+	    firstobj=
+	    if test yes = "$compiler_needs_object"; then
+	      firstobj="$1 "
+	      shift
+	    fi
+	    for obj
+	    do
+	      func_to_tool_file "$obj"
+	      $ECHO "$func_to_tool_file_result" >> $output
+	    done
+	    func_append delfiles " $output"
+	    func_to_tool_file "$output"
+	    output=$firstobj\"$file_list_spec$func_to_tool_file_result\"
+	  else
+	    if test -n "$save_libobjs"; then
+	      func_verbose "creating reloadable object files..."
+	      output=$output_objdir/$output_la-$k.$objext
+	      eval test_cmds=\"$reload_cmds\"
+	      func_len " $test_cmds"
+	      len0=$func_len_result
+	      len=$len0
+
+	      # Loop over the list of objects to be linked.
+	      for obj in $save_libobjs
+	      do
+		func_len " $obj"
+		func_arith $len + $func_len_result
+		len=$func_arith_result
+		if test -z "$objlist" ||
+		   test "$len" -lt "$max_cmd_len"; then
+		  func_append objlist " $obj"
+		else
+		  # The command $test_cmds is almost too long, add a
+		  # command to the queue.
+		  if test 1 -eq "$k"; then
+		    # The first file doesn't have a previous command to add.
+		    reload_objs=$objlist
+		    eval concat_cmds=\"$reload_cmds\"
+		  else
+		    # All subsequent reloadable object files will link in
+		    # the last one created.
+		    reload_objs="$objlist $last_robj"
+		    eval concat_cmds=\"\$concat_cmds~$reload_cmds~\$RM $last_robj\"
+		  fi
+		  last_robj=$output_objdir/$output_la-$k.$objext
+		  func_arith $k + 1
+		  k=$func_arith_result
+		  output=$output_objdir/$output_la-$k.$objext
+		  objlist=" $obj"
+		  func_len " $last_robj"
+		  func_arith $len0 + $func_len_result
+		  len=$func_arith_result
+		fi
+	      done
+	      # Handle the remaining objects by creating one last
+	      # reloadable object file.  All subsequent reloadable object
+	      # files will link in the last one created.
+	      test -z "$concat_cmds" || concat_cmds=$concat_cmds~
+	      reload_objs="$objlist $last_robj"
+	      eval concat_cmds=\"\$concat_cmds$reload_cmds\"
+	      if test -n "$last_robj"; then
+	        eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\"
+	      fi
+	      func_append delfiles " $output"
+
+	    else
+	      output=
+	    fi
+
+	    ${skipped_export-false} && {
+	      func_verbose "generating symbol list for '$libname.la'"
+	      export_symbols=$output_objdir/$libname.exp
+	      $opt_dry_run || $RM $export_symbols
+	      libobjs=$output
+	      # Append the command to create the export file.
+	      test -z "$concat_cmds" || concat_cmds=$concat_cmds~
+	      eval concat_cmds=\"\$concat_cmds$export_symbols_cmds\"
+	      if test -n "$last_robj"; then
+		eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\"
+	      fi
+	    }
+
+	    test -n "$save_libobjs" &&
+	      func_verbose "creating a temporary reloadable object file: $output"
+
+	    # Loop through the commands generated above and execute them.
+	    save_ifs=$IFS; IFS='~'
+	    for cmd in $concat_cmds; do
+	      IFS=$save_ifs
+	      $opt_quiet || {
+		  func_quote_for_expand "$cmd"
+		  eval "func_echo $func_quote_for_expand_result"
+	      }
+	      $opt_dry_run || eval "$cmd" || {
+		lt_exit=$?
+
+		# Restore the uninstalled library and exit
+		if test relink = "$opt_mode"; then
+		  ( cd "$output_objdir" && \
+		    $RM "${realname}T" && \
+		    $MV "${realname}U" "$realname" )
+		fi
+
+		exit $lt_exit
+	      }
+	    done
+	    IFS=$save_ifs
+
+	    if test -n "$export_symbols_regex" && ${skipped_export-false}; then
+	      func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"'
+	      func_show_eval '$MV "${export_symbols}T" "$export_symbols"'
+	    fi
+	  fi
+
+          ${skipped_export-false} && {
+	    if test -n "$export_symbols" && test -n "$include_expsyms"; then
+	      tmp_export_symbols=$export_symbols
+	      test -n "$orig_export_symbols" && tmp_export_symbols=$orig_export_symbols
+	      $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"'
+	    fi
+
+	    if test -n "$orig_export_symbols"; then
+	      # The given exports_symbols file has to be filtered, so filter it.
+	      func_verbose "filter symbol list for '$libname.la' to tag DATA exports"
+	      # FIXME: $output_objdir/$libname.filter potentially contains lots of
+	      # 's' commands, which not all seds can handle. GNU sed should be fine
+	      # though. Also, the filter scales superlinearly with the number of
+	      # global variables. join(1) would be nice here, but unfortunately
+	      # isn't a blessed tool.
+	      $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter
+	      func_append delfiles " $export_symbols $output_objdir/$libname.filter"
+	      export_symbols=$output_objdir/$libname.def
+	      $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols
+	    fi
+	  }
+
+	  libobjs=$output
+	  # Restore the value of output.
+	  output=$save_output
+
+	  if test -n "$convenience" && test -n "$whole_archive_flag_spec"; then
+	    eval libobjs=\"\$libobjs $whole_archive_flag_spec\"
+	    test "X$libobjs" = "X " && libobjs=
+	  fi
+	  # Expand the library linking commands again to reset the
+	  # value of $libobjs for piecewise linking.
+
+	  # Do each of the archive commands.
+	  if test yes = "$module" && test -n "$module_cmds"; then
+	    if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then
+	      cmds=$module_expsym_cmds
+	    else
+	      cmds=$module_cmds
+	    fi
+	  else
+	    if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then
+	      cmds=$archive_expsym_cmds
+	    else
+	      cmds=$archive_cmds
+	    fi
+	  fi
+	fi
+
+	if test -n "$delfiles"; then
+	  # Append the command to remove temporary files to $cmds.
+	  eval cmds=\"\$cmds~\$RM $delfiles\"
+	fi
+
+	# Add any objects from preloaded convenience libraries
+	if test -n "$dlprefiles"; then
+	  gentop=$output_objdir/${outputname}x
+	  func_append generated " $gentop"
+
+	  func_extract_archives $gentop $dlprefiles
+	  func_append libobjs " $func_extract_archives_result"
+	  test "X$libobjs" = "X " && libobjs=
+	fi
+
+	save_ifs=$IFS; IFS='~'
+	for cmd in $cmds; do
+	  IFS=$sp$nl
+	  eval cmd=\"$cmd\"
+	  IFS=$save_ifs
+	  $opt_quiet || {
+	    func_quote_for_expand "$cmd"
+	    eval "func_echo $func_quote_for_expand_result"
+	  }
+	  $opt_dry_run || eval "$cmd" || {
+	    lt_exit=$?
+
+	    # Restore the uninstalled library and exit
+	    if test relink = "$opt_mode"; then
+	      ( cd "$output_objdir" && \
+	        $RM "${realname}T" && \
+		$MV "${realname}U" "$realname" )
+	    fi
+
+	    exit $lt_exit
+	  }
+	done
+	IFS=$save_ifs
+
+	# Restore the uninstalled library and exit
+	if test relink = "$opt_mode"; then
+	  $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}T && $MV $realname ${realname}T && $MV ${realname}U $realname)' || exit $?
+
+	  if test -n "$convenience"; then
+	    if test -z "$whole_archive_flag_spec"; then
+	      func_show_eval '${RM}r "$gentop"'
+	    fi
+	  fi
+
+	  exit $EXIT_SUCCESS
+	fi
+
+	# Create links to the real library.
+	for linkname in $linknames; do
+	  if test "$realname" != "$linkname"; then
+	    func_show_eval '(cd "$output_objdir" && $RM "$linkname" && $LN_S "$realname" "$linkname")' 'exit $?'
+	  fi
+	done
+
+	# If -module or -export-dynamic was specified, set the dlname.
+	if test yes = "$module" || test yes = "$export_dynamic"; then
+	  # On all known operating systems, these are identical.
+	  dlname=$soname
+	fi
+      fi
+      ;;
+
+    obj)
+      if test -n "$dlfiles$dlprefiles" || test no != "$dlself"; then
+	func_warning "'-dlopen' is ignored for objects"
+      fi
+
+      case " $deplibs" in
+      *\ -l* | *\ -L*)
+	func_warning "'-l' and '-L' are ignored for objects" ;;
+      esac
+
+      test -n "$rpath" && \
+	func_warning "'-rpath' is ignored for objects"
+
+      test -n "$xrpath" && \
+	func_warning "'-R' is ignored for objects"
+
+      test -n "$vinfo" && \
+	func_warning "'-version-info' is ignored for objects"
+
+      test -n "$release" && \
+	func_warning "'-release' is ignored for objects"
+
+      case $output in
+      *.lo)
+	test -n "$objs$old_deplibs" && \
+	  func_fatal_error "cannot build library object '$output' from non-libtool objects"
+
+	libobj=$output
+	func_lo2o "$libobj"
+	obj=$func_lo2o_result
+	;;
+      *)
+	libobj=
+	obj=$output
+	;;
+      esac
+
+      # Delete the old objects.
+      $opt_dry_run || $RM $obj $libobj
+
+      # Objects from convenience libraries.  This assumes
+      # single-version convenience libraries.  Whenever we create
+      # different ones for PIC/non-PIC, this we'll have to duplicate
+      # the extraction.
+      reload_conv_objs=
+      gentop=
+      # if reload_cmds runs $LD directly, get rid of -Wl from
+      # whole_archive_flag_spec and hope we can get by with turning comma
+      # into space.
+      case $reload_cmds in
+        *\$LD[\ \$]*) wl= ;;
+      esac
+      if test -n "$convenience"; then
+	if test -n "$whole_archive_flag_spec"; then
+	  eval tmp_whole_archive_flags=\"$whole_archive_flag_spec\"
+	  test -n "$wl" || tmp_whole_archive_flags=`$ECHO "$tmp_whole_archive_flags" | $SED 's|,| |g'`
+	  reload_conv_objs=$reload_objs\ $tmp_whole_archive_flags
+	else
+	  gentop=$output_objdir/${obj}x
+	  func_append generated " $gentop"
+
+	  func_extract_archives $gentop $convenience
+	  reload_conv_objs="$reload_objs $func_extract_archives_result"
+	fi
+      fi
+
+      # If we're not building shared, we need to use non_pic_objs
+      test yes = "$build_libtool_libs" || libobjs=$non_pic_objects
+
+      # Create the old-style object.
+      reload_objs=$objs$old_deplibs' '`$ECHO "$libobjs" | $SP2NL | $SED "/\.$libext$/d; /\.lib$/d; $lo2o" | $NL2SP`' '$reload_conv_objs
+
+      output=$obj
+      func_execute_cmds "$reload_cmds" 'exit $?'
+
+      # Exit if we aren't doing a library object file.
+      if test -z "$libobj"; then
+	if test -n "$gentop"; then
+	  func_show_eval '${RM}r "$gentop"'
+	fi
+
+	exit $EXIT_SUCCESS
+      fi
+
+      test yes = "$build_libtool_libs" || {
+	if test -n "$gentop"; then
+	  func_show_eval '${RM}r "$gentop"'
+	fi
+
+	# Create an invalid libtool object if no PIC, so that we don't
+	# accidentally link it into a program.
+	# $show "echo timestamp > $libobj"
+	# $opt_dry_run || eval "echo timestamp > $libobj" || exit $?
+	exit $EXIT_SUCCESS
+      }
+
+      if test -n "$pic_flag" || test default != "$pic_mode"; then
+	# Only do commands if we really have different PIC objects.
+	reload_objs="$libobjs $reload_conv_objs"
+	output=$libobj
+	func_execute_cmds "$reload_cmds" 'exit $?'
+      fi
+
+      if test -n "$gentop"; then
+	func_show_eval '${RM}r "$gentop"'
+      fi
+
+      exit $EXIT_SUCCESS
+      ;;
+
+    prog)
+      case $host in
+	*cygwin*) func_stripname '' '.exe' "$output"
+	          output=$func_stripname_result.exe;;
+      esac
+      test -n "$vinfo" && \
+	func_warning "'-version-info' is ignored for programs"
+
+      test -n "$release" && \
+	func_warning "'-release' is ignored for programs"
+
+      $preload \
+	&& test unknown,unknown,unknown = "$dlopen_support,$dlopen_self,$dlopen_self_static" \
+	&& func_warning "'LT_INIT([dlopen])' not used. Assuming no dlopen support."
+
+      case $host in
+      *-*-rhapsody* | *-*-darwin1.[012])
+	# On Rhapsody replace the C library is the System framework
+	compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's/ -lc / System.ltframework /'`
+	finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's/ -lc / System.ltframework /'`
+	;;
+      esac
+
+      case $host in
+      *-*-darwin*)
+	# Don't allow lazy linking, it breaks C++ global constructors
+	# But is supposedly fixed on 10.4 or later (yay!).
+	if test CXX = "$tagname"; then
+	  case ${MACOSX_DEPLOYMENT_TARGET-10.0} in
+	    10.[0123])
+	      func_append compile_command " $wl-bind_at_load"
+	      func_append finalize_command " $wl-bind_at_load"
+	    ;;
+	  esac
+	fi
+	# Time to change all our "foo.ltframework" stuff back to "-framework foo"
+	compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+	finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+	;;
+      esac
+
+
+      # move library search paths that coincide with paths to not yet
+      # installed libraries to the beginning of the library search list
+      new_libs=
+      for path in $notinst_path; do
+	case " $new_libs " in
+	*" -L$path/$objdir "*) ;;
+	*)
+	  case " $compile_deplibs " in
+	  *" -L$path/$objdir "*)
+	    func_append new_libs " -L$path/$objdir" ;;
+	  esac
+	  ;;
+	esac
+      done
+      for deplib in $compile_deplibs; do
+	case $deplib in
+	-L*)
+	  case " $new_libs " in
+	  *" $deplib "*) ;;
+	  *) func_append new_libs " $deplib" ;;
+	  esac
+	  ;;
+	*) func_append new_libs " $deplib" ;;
+	esac
+      done
+      compile_deplibs=$new_libs
+
+
+      func_append compile_command " $compile_deplibs"
+      func_append finalize_command " $finalize_deplibs"
+
+      if test -n "$rpath$xrpath"; then
+	# If the user specified any rpath flags, then add them.
+	for libdir in $rpath $xrpath; do
+	  # This is the magic to use -rpath.
+	  case "$finalize_rpath " in
+	  *" $libdir "*) ;;
+	  *) func_append finalize_rpath " $libdir" ;;
+	  esac
+	done
+      fi
+
+      # Now hardcode the library paths
+      rpath=
+      hardcode_libdirs=
+      for libdir in $compile_rpath $finalize_rpath; do
+	if test -n "$hardcode_libdir_flag_spec"; then
+	  if test -n "$hardcode_libdir_separator"; then
+	    if test -z "$hardcode_libdirs"; then
+	      hardcode_libdirs=$libdir
+	    else
+	      # Just accumulate the unique libdirs.
+	      case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
+	      *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+		;;
+	      *)
+		func_append hardcode_libdirs "$hardcode_libdir_separator$libdir"
+		;;
+	      esac
+	    fi
+	  else
+	    eval flag=\"$hardcode_libdir_flag_spec\"
+	    func_append rpath " $flag"
+	  fi
+	elif test -n "$runpath_var"; then
+	  case "$perm_rpath " in
+	  *" $libdir "*) ;;
+	  *) func_append perm_rpath " $libdir" ;;
+	  esac
+	fi
+	case $host in
+	*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*)
+	  testbindir=`$ECHO "$libdir" | $SED -e 's*/lib$*/bin*'`
+	  case :$dllsearchpath: in
+	  *":$libdir:"*) ;;
+	  ::) dllsearchpath=$libdir;;
+	  *) func_append dllsearchpath ":$libdir";;
+	  esac
+	  case :$dllsearchpath: in
+	  *":$testbindir:"*) ;;
+	  ::) dllsearchpath=$testbindir;;
+	  *) func_append dllsearchpath ":$testbindir";;
+	  esac
+	  ;;
+	esac
+      done
+      # Substitute the hardcoded libdirs into the rpath.
+      if test -n "$hardcode_libdir_separator" &&
+	 test -n "$hardcode_libdirs"; then
+	libdir=$hardcode_libdirs
+	eval rpath=\" $hardcode_libdir_flag_spec\"
+      fi
+      compile_rpath=$rpath
+
+      rpath=
+      hardcode_libdirs=
+      for libdir in $finalize_rpath; do
+	if test -n "$hardcode_libdir_flag_spec"; then
+	  if test -n "$hardcode_libdir_separator"; then
+	    if test -z "$hardcode_libdirs"; then
+	      hardcode_libdirs=$libdir
+	    else
+	      # Just accumulate the unique libdirs.
+	      case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
+	      *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+		;;
+	      *)
+		func_append hardcode_libdirs "$hardcode_libdir_separator$libdir"
+		;;
+	      esac
+	    fi
+	  else
+	    eval flag=\"$hardcode_libdir_flag_spec\"
+	    func_append rpath " $flag"
+	  fi
+	elif test -n "$runpath_var"; then
+	  case "$finalize_perm_rpath " in
+	  *" $libdir "*) ;;
+	  *) func_append finalize_perm_rpath " $libdir" ;;
+	  esac
+	fi
+      done
+      # Substitute the hardcoded libdirs into the rpath.
+      if test -n "$hardcode_libdir_separator" &&
+	 test -n "$hardcode_libdirs"; then
+	libdir=$hardcode_libdirs
+	eval rpath=\" $hardcode_libdir_flag_spec\"
+      fi
+      finalize_rpath=$rpath
+
+      if test -n "$libobjs" && test yes = "$build_old_libs"; then
+	# Transform all the library objects into standard objects.
+	compile_command=`$ECHO "$compile_command" | $SP2NL | $SED "$lo2o" | $NL2SP`
+	finalize_command=`$ECHO "$finalize_command" | $SP2NL | $SED "$lo2o" | $NL2SP`
+      fi
+
+      func_generate_dlsyms "$outputname" "@PROGRAM@" false
+
+      # template prelinking step
+      if test -n "$prelink_cmds"; then
+	func_execute_cmds "$prelink_cmds" 'exit $?'
+      fi
+
+      wrappers_required=:
+      case $host in
+      *cegcc* | *mingw32ce*)
+        # Disable wrappers for cegcc and mingw32ce hosts, we are cross compiling anyway.
+        wrappers_required=false
+        ;;
+      *cygwin* | *mingw* )
+        test yes = "$build_libtool_libs" || wrappers_required=false
+        ;;
+      *)
+        if test no = "$need_relink" || test yes != "$build_libtool_libs"; then
+          wrappers_required=false
+        fi
+        ;;
+      esac
+      $wrappers_required || {
+	# Replace the output file specification.
+	compile_command=`$ECHO "$compile_command" | $SED 's%@OUTPUT@%'"$output"'%g'`
+	link_command=$compile_command$compile_rpath
+
+	# We have no uninstalled library dependencies, so finalize right now.
+	exit_status=0
+	func_show_eval "$link_command" 'exit_status=$?'
+
+	if test -n "$postlink_cmds"; then
+	  func_to_tool_file "$output"
+	  postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'`
+	  func_execute_cmds "$postlink_cmds" 'exit $?'
+	fi
+
+	# Delete the generated files.
+	if test -f "$output_objdir/${outputname}S.$objext"; then
+	  func_show_eval '$RM "$output_objdir/${outputname}S.$objext"'
+	fi
+
+	exit $exit_status
+      }
+
+      if test -n "$compile_shlibpath$finalize_shlibpath"; then
+	compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command"
+      fi
+      if test -n "$finalize_shlibpath"; then
+	finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command"
+      fi
+
+      compile_var=
+      finalize_var=
+      if test -n "$runpath_var"; then
+	if test -n "$perm_rpath"; then
+	  # We should set the runpath_var.
+	  rpath=
+	  for dir in $perm_rpath; do
+	    func_append rpath "$dir:"
+	  done
+	  compile_var="$runpath_var=\"$rpath\$$runpath_var\" "
+	fi
+	if test -n "$finalize_perm_rpath"; then
+	  # We should set the runpath_var.
+	  rpath=
+	  for dir in $finalize_perm_rpath; do
+	    func_append rpath "$dir:"
+	  done
+	  finalize_var="$runpath_var=\"$rpath\$$runpath_var\" "
+	fi
+      fi
+
+      if test yes = "$no_install"; then
+	# We don't need to create a wrapper script.
+	link_command=$compile_var$compile_command$compile_rpath
+	# Replace the output file specification.
+	link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output"'%g'`
+	# Delete the old output file.
+	$opt_dry_run || $RM $output
+	# Link the executable and exit
+	func_show_eval "$link_command" 'exit $?'
+
+	if test -n "$postlink_cmds"; then
+	  func_to_tool_file "$output"
+	  postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'`
+	  func_execute_cmds "$postlink_cmds" 'exit $?'
+	fi
+
+	exit $EXIT_SUCCESS
+      fi
+
+      case $hardcode_action,$fast_install in
+        relink,*)
+	  # Fast installation is not supported
+	  link_command=$compile_var$compile_command$compile_rpath
+	  relink_command=$finalize_var$finalize_command$finalize_rpath
+
+	  func_warning "this platform does not like uninstalled shared libraries"
+	  func_warning "'$output' will be relinked during installation"
+	  ;;
+        *,yes)
+	  link_command=$finalize_var$compile_command$finalize_rpath
+	  relink_command=`$ECHO "$compile_var$compile_command$compile_rpath" | $SED 's%@OUTPUT@%\$progdir/\$file%g'`
+          ;;
+	*,no)
+	  link_command=$compile_var$compile_command$compile_rpath
+	  relink_command=$finalize_var$finalize_command$finalize_rpath
+          ;;
+	*,needless)
+	  link_command=$finalize_var$compile_command$finalize_rpath
+	  relink_command=
+          ;;
+      esac
+
+      # Replace the output file specification.
+      link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'`
+
+      # Delete the old output files.
+      $opt_dry_run || $RM $output $output_objdir/$outputname $output_objdir/lt-$outputname
+
+      func_show_eval "$link_command" 'exit $?'
+
+      if test -n "$postlink_cmds"; then
+	func_to_tool_file "$output_objdir/$outputname"
+	postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'`
+	func_execute_cmds "$postlink_cmds" 'exit $?'
+      fi
+
+      # Now create the wrapper script.
+      func_verbose "creating $output"
+
+      # Quote the relink command for shipping.
+      if test -n "$relink_command"; then
+	# Preserve any variables that may affect compiler behavior
+	for var in $variables_saved_for_relink; do
+	  if eval test -z \"\${$var+set}\"; then
+	    relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command"
+	  elif eval var_value=\$$var; test -z "$var_value"; then
+	    relink_command="$var=; export $var; $relink_command"
+	  else
+	    func_quote_for_eval "$var_value"
+	    relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command"
+	  fi
+	done
+	relink_command="(cd `pwd`; $relink_command)"
+	relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"`
+      fi
+
+      # Only actually do things if not in dry run mode.
+      $opt_dry_run || {
+	# win32 will think the script is a binary if it has
+	# a .exe suffix, so we strip it off here.
+	case $output in
+	  *.exe) func_stripname '' '.exe' "$output"
+	         output=$func_stripname_result ;;
+	esac
+	# test for cygwin because mv fails w/o .exe extensions
+	case $host in
+	  *cygwin*)
+	    exeext=.exe
+	    func_stripname '' '.exe' "$outputname"
+	    outputname=$func_stripname_result ;;
+	  *) exeext= ;;
+	esac
+	case $host in
+	  *cygwin* | *mingw* )
+	    func_dirname_and_basename "$output" "" "."
+	    output_name=$func_basename_result
+	    output_path=$func_dirname_result
+	    cwrappersource=$output_path/$objdir/lt-$output_name.c
+	    cwrapper=$output_path/$output_name.exe
+	    $RM $cwrappersource $cwrapper
+	    trap "$RM $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15
+
+	    func_emit_cwrapperexe_src > $cwrappersource
+
+	    # The wrapper executable is built using the $host compiler,
+	    # because it contains $host paths and files. If cross-
+	    # compiling, it, like the target executable, must be
+	    # executed on the $host or under an emulation environment.
+	    $opt_dry_run || {
+	      $LTCC $LTCFLAGS -o $cwrapper $cwrappersource
+	      $STRIP $cwrapper
+	    }
+
+	    # Now, create the wrapper script for func_source use:
+	    func_ltwrapper_scriptname $cwrapper
+	    $RM $func_ltwrapper_scriptname_result
+	    trap "$RM $func_ltwrapper_scriptname_result; exit $EXIT_FAILURE" 1 2 15
+	    $opt_dry_run || {
+	      # note: this script will not be executed, so do not chmod.
+	      if test "x$build" = "x$host"; then
+		$cwrapper --lt-dump-script > $func_ltwrapper_scriptname_result
+	      else
+		func_emit_wrapper no > $func_ltwrapper_scriptname_result
+	      fi
+	    }
+	  ;;
+	  * )
+	    $RM $output
+	    trap "$RM $output; exit $EXIT_FAILURE" 1 2 15
+
+	    func_emit_wrapper no > $output
+	    chmod +x $output
+	  ;;
+	esac
+      }
+      exit $EXIT_SUCCESS
+      ;;
+    esac
+
+    # See if we need to build an old-fashioned archive.
+    for oldlib in $oldlibs; do
+
+      case $build_libtool_libs in
+        convenience)
+	  oldobjs="$libobjs_save $symfileobj"
+	  addlibs=$convenience
+	  build_libtool_libs=no
+	  ;;
+	module)
+	  oldobjs=$libobjs_save
+	  addlibs=$old_convenience
+	  build_libtool_libs=no
+          ;;
+	*)
+	  oldobjs="$old_deplibs $non_pic_objects"
+	  $preload && test -f "$symfileobj" \
+	    && func_append oldobjs " $symfileobj"
+	  addlibs=$old_convenience
+	  ;;
+      esac
+
+      if test -n "$addlibs"; then
+	gentop=$output_objdir/${outputname}x
+	func_append generated " $gentop"
+
+	func_extract_archives $gentop $addlibs
+	func_append oldobjs " $func_extract_archives_result"
+      fi
+
+      # Do each command in the archive commands.
+      if test -n "$old_archive_from_new_cmds" && test yes = "$build_libtool_libs"; then
+	cmds=$old_archive_from_new_cmds
+      else
+
+	# Add any objects from preloaded convenience libraries
+	if test -n "$dlprefiles"; then
+	  gentop=$output_objdir/${outputname}x
+	  func_append generated " $gentop"
+
+	  func_extract_archives $gentop $dlprefiles
+	  func_append oldobjs " $func_extract_archives_result"
+	fi
+
+	# POSIX demands no paths to be encoded in archives.  We have
+	# to avoid creating archives with duplicate basenames if we
+	# might have to extract them afterwards, e.g., when creating a
+	# static archive out of a convenience library, or when linking
+	# the entirety of a libtool archive into another (currently
+	# not supported by libtool).
+	if (for obj in $oldobjs
+	    do
+	      func_basename "$obj"
+	      $ECHO "$func_basename_result"
+	    done | sort | sort -uc >/dev/null 2>&1); then
+	  :
+	else
+	  echo "copying selected object files to avoid basename conflicts..."
+	  gentop=$output_objdir/${outputname}x
+	  func_append generated " $gentop"
+	  func_mkdir_p "$gentop"
+	  save_oldobjs=$oldobjs
+	  oldobjs=
+	  counter=1
+	  for obj in $save_oldobjs
+	  do
+	    func_basename "$obj"
+	    objbase=$func_basename_result
+	    case " $oldobjs " in
+	    " ") oldobjs=$obj ;;
+	    *[\ /]"$objbase "*)
+	      while :; do
+		# Make sure we don't pick an alternate name that also
+		# overlaps.
+		newobj=lt$counter-$objbase
+		func_arith $counter + 1
+		counter=$func_arith_result
+		case " $oldobjs " in
+		*[\ /]"$newobj "*) ;;
+		*) if test ! -f "$gentop/$newobj"; then break; fi ;;
+		esac
+	      done
+	      func_show_eval "ln $obj $gentop/$newobj || cp $obj $gentop/$newobj"
+	      func_append oldobjs " $gentop/$newobj"
+	      ;;
+	    *) func_append oldobjs " $obj" ;;
+	    esac
+	  done
+	fi
+	func_to_tool_file "$oldlib" func_convert_file_msys_to_w32
+	tool_oldlib=$func_to_tool_file_result
+	eval cmds=\"$old_archive_cmds\"
+
+	func_len " $cmds"
+	len=$func_len_result
+	if test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then
+	  cmds=$old_archive_cmds
+	elif test -n "$archiver_list_spec"; then
+	  func_verbose "using command file archive linking..."
+	  for obj in $oldobjs
+	  do
+	    func_to_tool_file "$obj"
+	    $ECHO "$func_to_tool_file_result"
+	  done > $output_objdir/$libname.libcmd
+	  func_to_tool_file "$output_objdir/$libname.libcmd"
+	  oldobjs=" $archiver_list_spec$func_to_tool_file_result"
+	  cmds=$old_archive_cmds
+	else
+	  # the command line is too long to link in one step, link in parts
+	  func_verbose "using piecewise archive linking..."
+	  save_RANLIB=$RANLIB
+	  RANLIB=:
+	  objlist=
+	  concat_cmds=
+	  save_oldobjs=$oldobjs
+	  oldobjs=
+	  # Is there a better way of finding the last object in the list?
+	  for obj in $save_oldobjs
+	  do
+	    last_oldobj=$obj
+	  done
+	  eval test_cmds=\"$old_archive_cmds\"
+	  func_len " $test_cmds"
+	  len0=$func_len_result
+	  len=$len0
+	  for obj in $save_oldobjs
+	  do
+	    func_len " $obj"
+	    func_arith $len + $func_len_result
+	    len=$func_arith_result
+	    func_append objlist " $obj"
+	    if test "$len" -lt "$max_cmd_len"; then
+	      :
+	    else
+	      # the above command should be used before it gets too long
+	      oldobjs=$objlist
+	      if test "$obj" = "$last_oldobj"; then
+		RANLIB=$save_RANLIB
+	      fi
+	      test -z "$concat_cmds" || concat_cmds=$concat_cmds~
+	      eval concat_cmds=\"\$concat_cmds$old_archive_cmds\"
+	      objlist=
+	      len=$len0
+	    fi
+	  done
+	  RANLIB=$save_RANLIB
+	  oldobjs=$objlist
+	  if test -z "$oldobjs"; then
+	    eval cmds=\"\$concat_cmds\"
+	  else
+	    eval cmds=\"\$concat_cmds~\$old_archive_cmds\"
+	  fi
+	fi
+      fi
+      func_execute_cmds "$cmds" 'exit $?'
+    done
+
+    test -n "$generated" && \
+      func_show_eval "${RM}r$generated"
+
+    # Now create the libtool archive.
+    case $output in
+    *.la)
+      old_library=
+      test yes = "$build_old_libs" && old_library=$libname.$libext
+      func_verbose "creating $output"
+
+      # Preserve any variables that may affect compiler behavior
+      for var in $variables_saved_for_relink; do
+	if eval test -z \"\${$var+set}\"; then
+	  relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command"
+	elif eval var_value=\$$var; test -z "$var_value"; then
+	  relink_command="$var=; export $var; $relink_command"
+	else
+	  func_quote_for_eval "$var_value"
+	  relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command"
+	fi
+      done
+      # Quote the link command for shipping.
+      relink_command="(cd `pwd`; $SHELL \"$progpath\" $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)"
+      relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"`
+      if test yes = "$hardcode_automatic"; then
+	relink_command=
+      fi
+
+      # Only create the output if not a dry run.
+      $opt_dry_run || {
+	for installed in no yes; do
+	  if test yes = "$installed"; then
+	    if test -z "$install_libdir"; then
+	      break
+	    fi
+	    output=$output_objdir/${outputname}i
+	    # Replace all uninstalled libtool libraries with the installed ones
+	    newdependency_libs=
+	    for deplib in $dependency_libs; do
+	      case $deplib in
+	      *.la)
+		func_basename "$deplib"
+		name=$func_basename_result
+		func_resolve_sysroot "$deplib"
+		eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $func_resolve_sysroot_result`
+		test -z "$libdir" && \
+		  func_fatal_error "'$deplib' is not a valid libtool archive"
+		func_append newdependency_libs " ${lt_sysroot:+=}$libdir/$name"
+		;;
+	      -L*)
+		func_stripname -L '' "$deplib"
+		func_replace_sysroot "$func_stripname_result"
+		func_append newdependency_libs " -L$func_replace_sysroot_result"
+		;;
+	      -R*)
+		func_stripname -R '' "$deplib"
+		func_replace_sysroot "$func_stripname_result"
+		func_append newdependency_libs " -R$func_replace_sysroot_result"
+		;;
+	      *) func_append newdependency_libs " $deplib" ;;
+	      esac
+	    done
+	    dependency_libs=$newdependency_libs
+	    newdlfiles=
+
+	    for lib in $dlfiles; do
+	      case $lib in
+	      *.la)
+	        func_basename "$lib"
+		name=$func_basename_result
+		eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $lib`
+		test -z "$libdir" && \
+		  func_fatal_error "'$lib' is not a valid libtool archive"
+		func_append newdlfiles " ${lt_sysroot:+=}$libdir/$name"
+		;;
+	      *) func_append newdlfiles " $lib" ;;
+	      esac
+	    done
+	    dlfiles=$newdlfiles
+	    newdlprefiles=
+	    for lib in $dlprefiles; do
+	      case $lib in
+	      *.la)
+		# Only pass preopened files to the pseudo-archive (for
+		# eventual linking with the app. that links it) if we
+		# didn't already link the preopened objects directly into
+		# the library:
+		func_basename "$lib"
+		name=$func_basename_result
+		eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $lib`
+		test -z "$libdir" && \
+		  func_fatal_error "'$lib' is not a valid libtool archive"
+		func_append newdlprefiles " ${lt_sysroot:+=}$libdir/$name"
+		;;
+	      esac
+	    done
+	    dlprefiles=$newdlprefiles
+	  else
+	    newdlfiles=
+	    for lib in $dlfiles; do
+	      case $lib in
+		[\\/]* | [A-Za-z]:[\\/]*) abs=$lib ;;
+		*) abs=`pwd`"/$lib" ;;
+	      esac
+	      func_append newdlfiles " $abs"
+	    done
+	    dlfiles=$newdlfiles
+	    newdlprefiles=
+	    for lib in $dlprefiles; do
+	      case $lib in
+		[\\/]* | [A-Za-z]:[\\/]*) abs=$lib ;;
+		*) abs=`pwd`"/$lib" ;;
+	      esac
+	      func_append newdlprefiles " $abs"
+	    done
+	    dlprefiles=$newdlprefiles
+	  fi
+	  $RM $output
+	  # place dlname in correct position for cygwin
+	  # In fact, it would be nice if we could use this code for all target
+	  # systems that can't hard-code library paths into their executables
+	  # and that have no shared library path variable independent of PATH,
+	  # but it turns out we can't easily determine that from inspecting
+	  # libtool variables, so we have to hard-code the OSs to which it
+	  # applies here; at the moment, that means platforms that use the PE
+	  # object format with DLL files.  See the long comment at the top of
+	  # tests/bindir.at for full details.
+	  tdlname=$dlname
+	  case $host,$output,$installed,$module,$dlname in
+	    *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll | *cegcc*,*lai,yes,no,*.dll)
+	      # If a -bindir argument was supplied, place the dll there.
+	      if test -n "$bindir"; then
+		func_relative_path "$install_libdir" "$bindir"
+		tdlname=$func_relative_path_result/$dlname
+	      else
+		# Otherwise fall back on heuristic.
+		tdlname=../bin/$dlname
+	      fi
+	      ;;
+	  esac
+	  $ECHO > $output "\
+# $outputname - a libtool library file
+# Generated by $PROGRAM (GNU $PACKAGE) $VERSION
+#
+# Please DO NOT delete this file!
+# It is necessary for linking the library.
+
+# The name that we can dlopen(3).
+dlname='$tdlname'
+
+# Names of this library.
+library_names='$library_names'
+
+# The name of the static archive.
+old_library='$old_library'
+
+# Linker flags that cannot go in dependency_libs.
+inherited_linker_flags='$new_inherited_linker_flags'
+
+# Libraries that this one depends upon.
+dependency_libs='$dependency_libs'
+
+# Names of additional weak libraries provided by this library
+weak_library_names='$weak_libs'
+
+# Version information for $libname.
+current=$current
+age=$age
+revision=$revision
+
+# Is this an already installed library?
+installed=$installed
+
+# Should we warn about portability when linking against -modules?
+shouldnotlink=$module
+
+# Files to dlopen/dlpreopen
+dlopen='$dlfiles'
+dlpreopen='$dlprefiles'
+
+# Directory that this library needs to be installed in:
+libdir='$install_libdir'"
+	  if test no,yes = "$installed,$need_relink"; then
+	    $ECHO >> $output "\
+relink_command=\"$relink_command\""
+	  fi
+	done
+      }
+
+      # Do a symbolic link so that the libtool archive can be found in
+      # LD_LIBRARY_PATH before the program is installed.
+      func_show_eval '( cd "$output_objdir" && $RM "$outputname" && $LN_S "../$outputname" "$outputname" )' 'exit $?'
+      ;;
+    esac
+    exit $EXIT_SUCCESS
+}
+
+if test link = "$opt_mode" || test relink = "$opt_mode"; then
+  func_mode_link ${1+"$@"}
+fi
+
+
+# func_mode_uninstall arg...
+func_mode_uninstall ()
+{
+    $debug_cmd
+
+    RM=$nonopt
+    files=
+    rmforce=false
+    exit_status=0
+
+    # This variable tells wrapper scripts just to set variables rather
+    # than running their programs.
+    libtool_install_magic=$magic
+
+    for arg
+    do
+      case $arg in
+      -f) func_append RM " $arg"; rmforce=: ;;
+      -*) func_append RM " $arg" ;;
+      *) func_append files " $arg" ;;
+      esac
+    done
+
+    test -z "$RM" && \
+      func_fatal_help "you must specify an RM program"
+
+    rmdirs=
+
+    for file in $files; do
+      func_dirname "$file" "" "."
+      dir=$func_dirname_result
+      if test . = "$dir"; then
+	odir=$objdir
+      else
+	odir=$dir/$objdir
+      fi
+      func_basename "$file"
+      name=$func_basename_result
+      test uninstall = "$opt_mode" && odir=$dir
+
+      # Remember odir for removal later, being careful to avoid duplicates
+      if test clean = "$opt_mode"; then
+	case " $rmdirs " in
+	  *" $odir "*) ;;
+	  *) func_append rmdirs " $odir" ;;
+	esac
+      fi
+
+      # Don't error if the file doesn't exist and rm -f was used.
+      if { test -L "$file"; } >/dev/null 2>&1 ||
+	 { test -h "$file"; } >/dev/null 2>&1 ||
+	 test -f "$file"; then
+	:
+      elif test -d "$file"; then
+	exit_status=1
+	continue
+      elif $rmforce; then
+	continue
+      fi
+
+      rmfiles=$file
+
+      case $name in
+      *.la)
+	# Possibly a libtool archive, so verify it.
+	if func_lalib_p "$file"; then
+	  func_source $dir/$name
+
+	  # Delete the libtool libraries and symlinks.
+	  for n in $library_names; do
+	    func_append rmfiles " $odir/$n"
+	  done
+	  test -n "$old_library" && func_append rmfiles " $odir/$old_library"
+
+	  case $opt_mode in
+	  clean)
+	    case " $library_names " in
+	    *" $dlname "*) ;;
+	    *) test -n "$dlname" && func_append rmfiles " $odir/$dlname" ;;
+	    esac
+	    test -n "$libdir" && func_append rmfiles " $odir/$name $odir/${name}i"
+	    ;;
+	  uninstall)
+	    if test -n "$library_names"; then
+	      # Do each command in the postuninstall commands.
+	      func_execute_cmds "$postuninstall_cmds" '$rmforce || exit_status=1'
+	    fi
+
+	    if test -n "$old_library"; then
+	      # Do each command in the old_postuninstall commands.
+	      func_execute_cmds "$old_postuninstall_cmds" '$rmforce || exit_status=1'
+	    fi
+	    # FIXME: should reinstall the best remaining shared library.
+	    ;;
+	  esac
+	fi
+	;;
+
+      *.lo)
+	# Possibly a libtool object, so verify it.
+	if func_lalib_p "$file"; then
+
+	  # Read the .lo file
+	  func_source $dir/$name
+
+	  # Add PIC object to the list of files to remove.
+	  if test -n "$pic_object" && test none != "$pic_object"; then
+	    func_append rmfiles " $dir/$pic_object"
+	  fi
+
+	  # Add non-PIC object to the list of files to remove.
+	  if test -n "$non_pic_object" && test none != "$non_pic_object"; then
+	    func_append rmfiles " $dir/$non_pic_object"
+	  fi
+	fi
+	;;
+
+      *)
+	if test clean = "$opt_mode"; then
+	  noexename=$name
+	  case $file in
+	  *.exe)
+	    func_stripname '' '.exe' "$file"
+	    file=$func_stripname_result
+	    func_stripname '' '.exe' "$name"
+	    noexename=$func_stripname_result
+	    # $file with .exe has already been added to rmfiles,
+	    # add $file without .exe
+	    func_append rmfiles " $file"
+	    ;;
+	  esac
+	  # Do a test to see if this is a libtool program.
+	  if func_ltwrapper_p "$file"; then
+	    if func_ltwrapper_executable_p "$file"; then
+	      func_ltwrapper_scriptname "$file"
+	      relink_command=
+	      func_source $func_ltwrapper_scriptname_result
+	      func_append rmfiles " $func_ltwrapper_scriptname_result"
+	    else
+	      relink_command=
+	      func_source $dir/$noexename
+	    fi
+
+	    # note $name still contains .exe if it was in $file originally
+	    # as does the version of $file that was added into $rmfiles
+	    func_append rmfiles " $odir/$name $odir/${name}S.$objext"
+	    if test yes = "$fast_install" && test -n "$relink_command"; then
+	      func_append rmfiles " $odir/lt-$name"
+	    fi
+	    if test "X$noexename" != "X$name"; then
+	      func_append rmfiles " $odir/lt-$noexename.c"
+	    fi
+	  fi
+	fi
+	;;
+      esac
+      func_show_eval "$RM $rmfiles" 'exit_status=1'
+    done
+
+    # Try to remove the $objdir's in the directories where we deleted files
+    for dir in $rmdirs; do
+      if test -d "$dir"; then
+	func_show_eval "rmdir $dir >/dev/null 2>&1"
+      fi
+    done
+
+    exit $exit_status
+}
+
+if test uninstall = "$opt_mode" || test clean = "$opt_mode"; then
+  func_mode_uninstall ${1+"$@"}
+fi
+
+test -z "$opt_mode" && {
+  help=$generic_help
+  func_fatal_help "you must specify a MODE"
+}
+
+test -z "$exec_cmd" && \
+  func_fatal_help "invalid operation mode '$opt_mode'"
+
+if test -n "$exec_cmd"; then
+  eval exec "$exec_cmd"
+  exit $EXIT_FAILURE
+fi
+
+exit $exit_status
+
+
+# The TAGs below are defined such that we never get into a situation
+# where we disable both kinds of libraries.  Given conflicting
+# choices, we go for a static library, that is the most portable,
+# since we can't tell whether shared libraries were disabled because
+# the user asked for that or because the platform doesn't support
+# them.  This is particularly important on AIX, because we don't
+# support having both static and shared libraries enabled at the same
+# time on that platform, so we default to a shared-only configuration.
+# If a disable-shared tag is given, we'll fallback to a static-only
+# configuration.  But we'll never go from static-only to shared-only.
+
+# ### BEGIN LIBTOOL TAG CONFIG: disable-shared
+build_libtool_libs=no
+build_old_libs=yes
+# ### END LIBTOOL TAG CONFIG: disable-shared
+
+# ### BEGIN LIBTOOL TAG CONFIG: disable-static
+build_old_libs=`case $build_libtool_libs in yes) echo no;; *) echo yes;; esac`
+# ### END LIBTOOL TAG CONFIG: disable-static
+
+# Local Variables:
+# mode:shell-script
+# sh-indentation:2
+# End:
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/config/ltoptions.m4
@@ -0,0 +1,437 @@
+# Helper functions for option handling.                    -*- Autoconf -*-
+#
+#   Copyright (C) 2004-2005, 2007-2009, 2011-2015 Free Software
+#   Foundation, Inc.
+#   Written by Gary V. Vaughan, 2004
+#
+# This file is free software; the Free Software Foundation gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+
+# serial 8 ltoptions.m4
+
+# This is to help aclocal find these macros, as it can't see m4_define.
+AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])])
+
+
+# _LT_MANGLE_OPTION(MACRO-NAME, OPTION-NAME)
+# ------------------------------------------
+m4_define([_LT_MANGLE_OPTION],
+[[_LT_OPTION_]m4_bpatsubst($1__$2, [[^a-zA-Z0-9_]], [_])])
+
+
+# _LT_SET_OPTION(MACRO-NAME, OPTION-NAME)
+# ---------------------------------------
+# Set option OPTION-NAME for macro MACRO-NAME, and if there is a
+# matching handler defined, dispatch to it.  Other OPTION-NAMEs are
+# saved as a flag.
+m4_define([_LT_SET_OPTION],
+[m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl
+m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]),
+        _LT_MANGLE_DEFUN([$1], [$2]),
+    [m4_warning([Unknown $1 option '$2'])])[]dnl
+])
+
+
+# _LT_IF_OPTION(MACRO-NAME, OPTION-NAME, IF-SET, [IF-NOT-SET])
+# ------------------------------------------------------------
+# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise.
+m4_define([_LT_IF_OPTION],
+[m4_ifdef(_LT_MANGLE_OPTION([$1], [$2]), [$3], [$4])])
+
+
+# _LT_UNLESS_OPTIONS(MACRO-NAME, OPTION-LIST, IF-NOT-SET)
+# -------------------------------------------------------
+# Execute IF-NOT-SET unless all options in OPTION-LIST for MACRO-NAME
+# are set.
+m4_define([_LT_UNLESS_OPTIONS],
+[m4_foreach([_LT_Option], m4_split(m4_normalize([$2])),
+	    [m4_ifdef(_LT_MANGLE_OPTION([$1], _LT_Option),
+		      [m4_define([$0_found])])])[]dnl
+m4_ifdef([$0_found], [m4_undefine([$0_found])], [$3
+])[]dnl
+])
+
+
+# _LT_SET_OPTIONS(MACRO-NAME, OPTION-LIST)
+# ----------------------------------------
+# OPTION-LIST is a space-separated list of Libtool options associated
+# with MACRO-NAME.  If any OPTION has a matching handler declared with
+# LT_OPTION_DEFINE, dispatch to that macro; otherwise complain about
+# the unknown option and exit.
+m4_defun([_LT_SET_OPTIONS],
+[# Set options
+m4_foreach([_LT_Option], m4_split(m4_normalize([$2])),
+    [_LT_SET_OPTION([$1], _LT_Option)])
+
+m4_if([$1],[LT_INIT],[
+  dnl
+  dnl Simply set some default values (i.e off) if boolean options were not
+  dnl specified:
+  _LT_UNLESS_OPTIONS([LT_INIT], [dlopen], [enable_dlopen=no
+  ])
+  _LT_UNLESS_OPTIONS([LT_INIT], [win32-dll], [enable_win32_dll=no
+  ])
+  dnl
+  dnl If no reference was made to various pairs of opposing options, then
+  dnl we run the default mode handler for the pair.  For example, if neither
+  dnl 'shared' nor 'disable-shared' was passed, we enable building of shared
+  dnl archives by default:
+  _LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED])
+  _LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC])
+  _LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC])
+  _LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install],
+		   [_LT_ENABLE_FAST_INSTALL])
+  _LT_UNLESS_OPTIONS([LT_INIT], [aix-soname=aix aix-soname=both aix-soname=svr4],
+		   [_LT_WITH_AIX_SONAME([aix])])
+  ])
+])# _LT_SET_OPTIONS
+
+
+## --------------------------------- ##
+## Macros to handle LT_INIT options. ##
+## --------------------------------- ##
+
+# _LT_MANGLE_DEFUN(MACRO-NAME, OPTION-NAME)
+# -----------------------------------------
+m4_define([_LT_MANGLE_DEFUN],
+[[_LT_OPTION_DEFUN_]m4_bpatsubst(m4_toupper([$1__$2]), [[^A-Z0-9_]], [_])])
+
+
+# LT_OPTION_DEFINE(MACRO-NAME, OPTION-NAME, CODE)
+# -----------------------------------------------
+m4_define([LT_OPTION_DEFINE],
+[m4_define(_LT_MANGLE_DEFUN([$1], [$2]), [$3])[]dnl
+])# LT_OPTION_DEFINE
+
+
+# dlopen
+# ------
+LT_OPTION_DEFINE([LT_INIT], [dlopen], [enable_dlopen=yes
+])
+
+AU_DEFUN([AC_LIBTOOL_DLOPEN],
+[_LT_SET_OPTION([LT_INIT], [dlopen])
+AC_DIAGNOSE([obsolete],
+[$0: Remove this warning and the call to _LT_SET_OPTION when you
+put the 'dlopen' option into LT_INIT's first parameter.])
+])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_DLOPEN], [])
+
+
+# win32-dll
+# ---------
+# Declare package support for building win32 dll's.
+LT_OPTION_DEFINE([LT_INIT], [win32-dll],
+[enable_win32_dll=yes
+
+case $host in
+*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*)
+  AC_CHECK_TOOL(AS, as, false)
+  AC_CHECK_TOOL(DLLTOOL, dlltool, false)
+  AC_CHECK_TOOL(OBJDUMP, objdump, false)
+  ;;
+esac
+
+test -z "$AS" && AS=as
+_LT_DECL([], [AS],      [1], [Assembler program])dnl
+
+test -z "$DLLTOOL" && DLLTOOL=dlltool
+_LT_DECL([], [DLLTOOL], [1], [DLL creation program])dnl
+
+test -z "$OBJDUMP" && OBJDUMP=objdump
+_LT_DECL([], [OBJDUMP], [1], [Object dumper program])dnl
+])# win32-dll
+
+AU_DEFUN([AC_LIBTOOL_WIN32_DLL],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+_LT_SET_OPTION([LT_INIT], [win32-dll])
+AC_DIAGNOSE([obsolete],
+[$0: Remove this warning and the call to _LT_SET_OPTION when you
+put the 'win32-dll' option into LT_INIT's first parameter.])
+])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], [])
+
+
+# _LT_ENABLE_SHARED([DEFAULT])
+# ----------------------------
+# implement the --enable-shared flag, and supports the 'shared' and
+# 'disable-shared' LT_INIT options.
+# DEFAULT is either 'yes' or 'no'.  If omitted, it defaults to 'yes'.
+m4_define([_LT_ENABLE_SHARED],
+[m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl
+AC_ARG_ENABLE([shared],
+    [AS_HELP_STRING([--enable-shared@<:@=PKGS@:>@],
+	[build shared libraries @<:@default=]_LT_ENABLE_SHARED_DEFAULT[@:>@])],
+    [p=${PACKAGE-default}
+    case $enableval in
+    yes) enable_shared=yes ;;
+    no) enable_shared=no ;;
+    *)
+      enable_shared=no
+      # Look at the argument we got.  We use all the common list separators.
+      lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
+      for pkg in $enableval; do
+	IFS=$lt_save_ifs
+	if test "X$pkg" = "X$p"; then
+	  enable_shared=yes
+	fi
+      done
+      IFS=$lt_save_ifs
+      ;;
+    esac],
+    [enable_shared=]_LT_ENABLE_SHARED_DEFAULT)
+
+    _LT_DECL([build_libtool_libs], [enable_shared], [0],
+	[Whether or not to build shared libraries])
+])# _LT_ENABLE_SHARED
+
+LT_OPTION_DEFINE([LT_INIT], [shared], [_LT_ENABLE_SHARED([yes])])
+LT_OPTION_DEFINE([LT_INIT], [disable-shared], [_LT_ENABLE_SHARED([no])])
+
+# Old names:
+AC_DEFUN([AC_ENABLE_SHARED],
+[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[shared])
+])
+
+AC_DEFUN([AC_DISABLE_SHARED],
+[_LT_SET_OPTION([LT_INIT], [disable-shared])
+])
+
+AU_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)])
+AU_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AM_ENABLE_SHARED], [])
+dnl AC_DEFUN([AM_DISABLE_SHARED], [])
+
+
+
+# _LT_ENABLE_STATIC([DEFAULT])
+# ----------------------------
+# implement the --enable-static flag, and support the 'static' and
+# 'disable-static' LT_INIT options.
+# DEFAULT is either 'yes' or 'no'.  If omitted, it defaults to 'yes'.
+m4_define([_LT_ENABLE_STATIC],
+[m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl
+AC_ARG_ENABLE([static],
+    [AS_HELP_STRING([--enable-static@<:@=PKGS@:>@],
+	[build static libraries @<:@default=]_LT_ENABLE_STATIC_DEFAULT[@:>@])],
+    [p=${PACKAGE-default}
+    case $enableval in
+    yes) enable_static=yes ;;
+    no) enable_static=no ;;
+    *)
+     enable_static=no
+      # Look at the argument we got.  We use all the common list separators.
+      lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
+      for pkg in $enableval; do
+	IFS=$lt_save_ifs
+	if test "X$pkg" = "X$p"; then
+	  enable_static=yes
+	fi
+      done
+      IFS=$lt_save_ifs
+      ;;
+    esac],
+    [enable_static=]_LT_ENABLE_STATIC_DEFAULT)
+
+    _LT_DECL([build_old_libs], [enable_static], [0],
+	[Whether or not to build static libraries])
+])# _LT_ENABLE_STATIC
+
+LT_OPTION_DEFINE([LT_INIT], [static], [_LT_ENABLE_STATIC([yes])])
+LT_OPTION_DEFINE([LT_INIT], [disable-static], [_LT_ENABLE_STATIC([no])])
+
+# Old names:
+AC_DEFUN([AC_ENABLE_STATIC],
+[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[static])
+])
+
+AC_DEFUN([AC_DISABLE_STATIC],
+[_LT_SET_OPTION([LT_INIT], [disable-static])
+])
+
+AU_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)])
+AU_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AM_ENABLE_STATIC], [])
+dnl AC_DEFUN([AM_DISABLE_STATIC], [])
+
+
+
+# _LT_ENABLE_FAST_INSTALL([DEFAULT])
+# ----------------------------------
+# implement the --enable-fast-install flag, and support the 'fast-install'
+# and 'disable-fast-install' LT_INIT options.
+# DEFAULT is either 'yes' or 'no'.  If omitted, it defaults to 'yes'.
+m4_define([_LT_ENABLE_FAST_INSTALL],
+[m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl
+AC_ARG_ENABLE([fast-install],
+    [AS_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@],
+    [optimize for fast installation @<:@default=]_LT_ENABLE_FAST_INSTALL_DEFAULT[@:>@])],
+    [p=${PACKAGE-default}
+    case $enableval in
+    yes) enable_fast_install=yes ;;
+    no) enable_fast_install=no ;;
+    *)
+      enable_fast_install=no
+      # Look at the argument we got.  We use all the common list separators.
+      lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
+      for pkg in $enableval; do
+	IFS=$lt_save_ifs
+	if test "X$pkg" = "X$p"; then
+	  enable_fast_install=yes
+	fi
+      done
+      IFS=$lt_save_ifs
+      ;;
+    esac],
+    [enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT)
+
+_LT_DECL([fast_install], [enable_fast_install], [0],
+	 [Whether or not to optimize for fast installation])dnl
+])# _LT_ENABLE_FAST_INSTALL
+
+LT_OPTION_DEFINE([LT_INIT], [fast-install], [_LT_ENABLE_FAST_INSTALL([yes])])
+LT_OPTION_DEFINE([LT_INIT], [disable-fast-install], [_LT_ENABLE_FAST_INSTALL([no])])
+
+# Old names:
+AU_DEFUN([AC_ENABLE_FAST_INSTALL],
+[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install])
+AC_DIAGNOSE([obsolete],
+[$0: Remove this warning and the call to _LT_SET_OPTION when you put
+the 'fast-install' option into LT_INIT's first parameter.])
+])
+
+AU_DEFUN([AC_DISABLE_FAST_INSTALL],
+[_LT_SET_OPTION([LT_INIT], [disable-fast-install])
+AC_DIAGNOSE([obsolete],
+[$0: Remove this warning and the call to _LT_SET_OPTION when you put
+the 'disable-fast-install' option into LT_INIT's first parameter.])
+])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], [])
+dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], [])
+
+
+# _LT_WITH_AIX_SONAME([DEFAULT])
+# ----------------------------------
+# implement the --with-aix-soname flag, and support the `aix-soname=aix'
+# and `aix-soname=both' and `aix-soname=svr4' LT_INIT options. DEFAULT
+# is either `aix', `both' or `svr4'.  If omitted, it defaults to `aix'.
+m4_define([_LT_WITH_AIX_SONAME],
+[m4_define([_LT_WITH_AIX_SONAME_DEFAULT], [m4_if($1, svr4, svr4, m4_if($1, both, both, aix))])dnl
+shared_archive_member_spec=
+case $host,$enable_shared in
+power*-*-aix[[5-9]]*,yes)
+  AC_MSG_CHECKING([which variant of shared library versioning to provide])
+  AC_ARG_WITH([aix-soname],
+    [AS_HELP_STRING([--with-aix-soname=aix|svr4|both],
+      [shared library versioning (aka "SONAME") variant to provide on AIX, @<:@default=]_LT_WITH_AIX_SONAME_DEFAULT[@:>@.])],
+    [case $withval in
+    aix|svr4|both)
+      ;;
+    *)
+      AC_MSG_ERROR([Unknown argument to --with-aix-soname])
+      ;;
+    esac
+    lt_cv_with_aix_soname=$with_aix_soname],
+    [AC_CACHE_VAL([lt_cv_with_aix_soname],
+      [lt_cv_with_aix_soname=]_LT_WITH_AIX_SONAME_DEFAULT)
+    with_aix_soname=$lt_cv_with_aix_soname])
+  AC_MSG_RESULT([$with_aix_soname])
+  if test aix != "$with_aix_soname"; then
+    # For the AIX way of multilib, we name the shared archive member
+    # based on the bitwidth used, traditionally 'shr.o' or 'shr_64.o',
+    # and 'shr.imp' or 'shr_64.imp', respectively, for the Import File.
+    # Even when GNU compilers ignore OBJECT_MODE but need '-maix64' flag,
+    # the AIX toolchain works better with OBJECT_MODE set (default 32).
+    if test 64 = "${OBJECT_MODE-32}"; then
+      shared_archive_member_spec=shr_64
+    else
+      shared_archive_member_spec=shr
+    fi
+  fi
+  ;;
+*)
+  with_aix_soname=aix
+  ;;
+esac
+
+_LT_DECL([], [shared_archive_member_spec], [0],
+    [Shared archive member basename, for filename based shared library versioning on AIX])dnl
+])# _LT_WITH_AIX_SONAME
+
+LT_OPTION_DEFINE([LT_INIT], [aix-soname=aix], [_LT_WITH_AIX_SONAME([aix])])
+LT_OPTION_DEFINE([LT_INIT], [aix-soname=both], [_LT_WITH_AIX_SONAME([both])])
+LT_OPTION_DEFINE([LT_INIT], [aix-soname=svr4], [_LT_WITH_AIX_SONAME([svr4])])
+
+
+# _LT_WITH_PIC([MODE])
+# --------------------
+# implement the --with-pic flag, and support the 'pic-only' and 'no-pic'
+# LT_INIT options.
+# MODE is either 'yes' or 'no'.  If omitted, it defaults to 'both'.
+m4_define([_LT_WITH_PIC],
+[AC_ARG_WITH([pic],
+    [AS_HELP_STRING([--with-pic@<:@=PKGS@:>@],
+	[try to use only PIC/non-PIC objects @<:@default=use both@:>@])],
+    [lt_p=${PACKAGE-default}
+    case $withval in
+    yes|no) pic_mode=$withval ;;
+    *)
+      pic_mode=default
+      # Look at the argument we got.  We use all the common list separators.
+      lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
+      for lt_pkg in $withval; do
+	IFS=$lt_save_ifs
+	if test "X$lt_pkg" = "X$lt_p"; then
+	  pic_mode=yes
+	fi
+      done
+      IFS=$lt_save_ifs
+      ;;
+    esac],
+    [pic_mode=m4_default([$1], [default])])
+
+_LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl
+])# _LT_WITH_PIC
+
+LT_OPTION_DEFINE([LT_INIT], [pic-only], [_LT_WITH_PIC([yes])])
+LT_OPTION_DEFINE([LT_INIT], [no-pic], [_LT_WITH_PIC([no])])
+
+# Old name:
+AU_DEFUN([AC_LIBTOOL_PICMODE],
+[_LT_SET_OPTION([LT_INIT], [pic-only])
+AC_DIAGNOSE([obsolete],
+[$0: Remove this warning and the call to _LT_SET_OPTION when you
+put the 'pic-only' option into LT_INIT's first parameter.])
+])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_PICMODE], [])
+
+## ----------------- ##
+## LTDL_INIT Options ##
+## ----------------- ##
+
+m4_define([_LTDL_MODE], [])
+LT_OPTION_DEFINE([LTDL_INIT], [nonrecursive],
+		 [m4_define([_LTDL_MODE], [nonrecursive])])
+LT_OPTION_DEFINE([LTDL_INIT], [recursive],
+		 [m4_define([_LTDL_MODE], [recursive])])
+LT_OPTION_DEFINE([LTDL_INIT], [subproject],
+		 [m4_define([_LTDL_MODE], [subproject])])
+
+m4_define([_LTDL_TYPE], [])
+LT_OPTION_DEFINE([LTDL_INIT], [installable],
+		 [m4_define([_LTDL_TYPE], [installable])])
+LT_OPTION_DEFINE([LTDL_INIT], [convenience],
+		 [m4_define([_LTDL_TYPE], [convenience])])
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/config/ltsugar.m4
@@ -0,0 +1,124 @@
+# ltsugar.m4 -- libtool m4 base layer.                         -*-Autoconf-*-
+#
+# Copyright (C) 2004-2005, 2007-2008, 2011-2015 Free Software
+# Foundation, Inc.
+# Written by Gary V. Vaughan, 2004
+#
+# This file is free software; the Free Software Foundation gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+
+# serial 6 ltsugar.m4
+
+# This is to help aclocal find these macros, as it can't see m4_define.
+AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])])
+
+
+# lt_join(SEP, ARG1, [ARG2...])
+# -----------------------------
+# Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their
+# associated separator.
+# Needed until we can rely on m4_join from Autoconf 2.62, since all earlier
+# versions in m4sugar had bugs.
+m4_define([lt_join],
+[m4_if([$#], [1], [],
+       [$#], [2], [[$2]],
+       [m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])])
+m4_define([_lt_join],
+[m4_if([$#$2], [2], [],
+       [m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])])
+
+
+# lt_car(LIST)
+# lt_cdr(LIST)
+# ------------
+# Manipulate m4 lists.
+# These macros are necessary as long as will still need to support
+# Autoconf-2.59, which quotes differently.
+m4_define([lt_car], [[$1]])
+m4_define([lt_cdr],
+[m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])],
+       [$#], 1, [],
+       [m4_dquote(m4_shift($@))])])
+m4_define([lt_unquote], $1)
+
+
+# lt_append(MACRO-NAME, STRING, [SEPARATOR])
+# ------------------------------------------
+# Redefine MACRO-NAME to hold its former content plus 'SEPARATOR''STRING'.
+# Note that neither SEPARATOR nor STRING are expanded; they are appended
+# to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked).
+# No SEPARATOR is output if MACRO-NAME was previously undefined (different
+# than defined and empty).
+#
+# This macro is needed until we can rely on Autoconf 2.62, since earlier
+# versions of m4sugar mistakenly expanded SEPARATOR but not STRING.
+m4_define([lt_append],
+[m4_define([$1],
+	   m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])])
+
+
+
+# lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...])
+# ----------------------------------------------------------
+# Produce a SEP delimited list of all paired combinations of elements of
+# PREFIX-LIST with SUFFIX1 through SUFFIXn.  Each element of the list
+# has the form PREFIXmINFIXSUFFIXn.
+# Needed until we can rely on m4_combine added in Autoconf 2.62.
+m4_define([lt_combine],
+[m4_if(m4_eval([$# > 3]), [1],
+       [m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl
+[[m4_foreach([_Lt_prefix], [$2],
+	     [m4_foreach([_Lt_suffix],
+		]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[,
+	[_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])])
+
+
+# lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ])
+# -----------------------------------------------------------------------
+# Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited
+# by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ.
+m4_define([lt_if_append_uniq],
+[m4_ifdef([$1],
+	  [m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1],
+		 [lt_append([$1], [$2], [$3])$4],
+		 [$5])],
+	  [lt_append([$1], [$2], [$3])$4])])
+
+
+# lt_dict_add(DICT, KEY, VALUE)
+# -----------------------------
+m4_define([lt_dict_add],
+[m4_define([$1($2)], [$3])])
+
+
+# lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE)
+# --------------------------------------------
+m4_define([lt_dict_add_subkey],
+[m4_define([$1($2:$3)], [$4])])
+
+
+# lt_dict_fetch(DICT, KEY, [SUBKEY])
+# ----------------------------------
+m4_define([lt_dict_fetch],
+[m4_ifval([$3],
+	m4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]),
+    m4_ifdef([$1($2)], [m4_defn([$1($2)])]))])
+
+
+# lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE])
+# -----------------------------------------------------------------
+m4_define([lt_if_dict_fetch],
+[m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4],
+	[$5],
+    [$6])])
+
+
+# lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...])
+# --------------------------------------------------------------
+m4_define([lt_dict_filter],
+[m4_if([$5], [], [],
+  [lt_join(m4_quote(m4_default([$4], [[, ]])),
+           lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]),
+		      [lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl
+])
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/config/ltversion.m4
@@ -0,0 +1,23 @@
+# ltversion.m4 -- version numbers			-*- Autoconf -*-
+#
+#   Copyright (C) 2004, 2011-2015 Free Software Foundation, Inc.
+#   Written by Scott James Remnant, 2004
+#
+# This file is free software; the Free Software Foundation gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+
+# @configure_input@
+
+# serial 4179 ltversion.m4
+# This file is part of GNU Libtool
+
+m4_define([LT_PACKAGE_VERSION], [2.4.6])
+m4_define([LT_PACKAGE_REVISION], [2.4.6])
+
+AC_DEFUN([LTVERSION_VERSION],
+[macro_version='2.4.6'
+macro_revision='2.4.6'
+_LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?])
+_LT_DECL(, macro_revision, 0)
+])
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/config/lt~obsolete.m4
@@ -0,0 +1,99 @@
+# lt~obsolete.m4 -- aclocal satisfying obsolete definitions.    -*-Autoconf-*-
+#
+#   Copyright (C) 2004-2005, 2007, 2009, 2011-2015 Free Software
+#   Foundation, Inc.
+#   Written by Scott James Remnant, 2004.
+#
+# This file is free software; the Free Software Foundation gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+
+# serial 5 lt~obsolete.m4
+
+# These exist entirely to fool aclocal when bootstrapping libtool.
+#
+# In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN),
+# which have later been changed to m4_define as they aren't part of the
+# exported API, or moved to Autoconf or Automake where they belong.
+#
+# The trouble is, aclocal is a bit thick.  It'll see the old AC_DEFUN
+# in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us
+# using a macro with the same name in our local m4/libtool.m4 it'll
+# pull the old libtool.m4 in (it doesn't see our shiny new m4_define
+# and doesn't know about Autoconf macros at all.)
+#
+# So we provide this file, which has a silly filename so it's always
+# included after everything else.  This provides aclocal with the
+# AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything
+# because those macros already exist, or will be overwritten later.
+# We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6.
+#
+# Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here.
+# Yes, that means every name once taken will need to remain here until
+# we give up compatibility with versions before 1.7, at which point
+# we need to keep only those names which we still refer to.
+
+# This is to help aclocal find these macros, as it can't see m4_define.
+AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])])
+
+m4_ifndef([AC_LIBTOOL_LINKER_OPTION],	[AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])])
+m4_ifndef([AC_PROG_EGREP],		[AC_DEFUN([AC_PROG_EGREP])])
+m4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH],	[AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])])
+m4_ifndef([_LT_AC_SHELL_INIT],		[AC_DEFUN([_LT_AC_SHELL_INIT])])
+m4_ifndef([_LT_AC_SYS_LIBPATH_AIX],	[AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])])
+m4_ifndef([_LT_PROG_LTMAIN],		[AC_DEFUN([_LT_PROG_LTMAIN])])
+m4_ifndef([_LT_AC_TAGVAR],		[AC_DEFUN([_LT_AC_TAGVAR])])
+m4_ifndef([AC_LTDL_ENABLE_INSTALL],	[AC_DEFUN([AC_LTDL_ENABLE_INSTALL])])
+m4_ifndef([AC_LTDL_PREOPEN],		[AC_DEFUN([AC_LTDL_PREOPEN])])
+m4_ifndef([_LT_AC_SYS_COMPILER],	[AC_DEFUN([_LT_AC_SYS_COMPILER])])
+m4_ifndef([_LT_AC_LOCK],		[AC_DEFUN([_LT_AC_LOCK])])
+m4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE],	[AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])])
+m4_ifndef([_LT_AC_TRY_DLOPEN_SELF],	[AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])])
+m4_ifndef([AC_LIBTOOL_PROG_CC_C_O],	[AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])])
+m4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])])
+m4_ifndef([AC_LIBTOOL_OBJDIR],		[AC_DEFUN([AC_LIBTOOL_OBJDIR])])
+m4_ifndef([AC_LTDL_OBJDIR],		[AC_DEFUN([AC_LTDL_OBJDIR])])
+m4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])])
+m4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP],	[AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])])
+m4_ifndef([AC_PATH_MAGIC],		[AC_DEFUN([AC_PATH_MAGIC])])
+m4_ifndef([AC_PROG_LD_GNU],		[AC_DEFUN([AC_PROG_LD_GNU])])
+m4_ifndef([AC_PROG_LD_RELOAD_FLAG],	[AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])])
+m4_ifndef([AC_DEPLIBS_CHECK_METHOD],	[AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])])
+m4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])])
+m4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])])
+m4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])])
+m4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS],	[AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])])
+m4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP],	[AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])])
+m4_ifndef([LT_AC_PROG_EGREP],		[AC_DEFUN([LT_AC_PROG_EGREP])])
+m4_ifndef([LT_AC_PROG_SED],		[AC_DEFUN([LT_AC_PROG_SED])])
+m4_ifndef([_LT_CC_BASENAME],		[AC_DEFUN([_LT_CC_BASENAME])])
+m4_ifndef([_LT_COMPILER_BOILERPLATE],	[AC_DEFUN([_LT_COMPILER_BOILERPLATE])])
+m4_ifndef([_LT_LINKER_BOILERPLATE],	[AC_DEFUN([_LT_LINKER_BOILERPLATE])])
+m4_ifndef([_AC_PROG_LIBTOOL],		[AC_DEFUN([_AC_PROG_LIBTOOL])])
+m4_ifndef([AC_LIBTOOL_SETUP],		[AC_DEFUN([AC_LIBTOOL_SETUP])])
+m4_ifndef([_LT_AC_CHECK_DLFCN],		[AC_DEFUN([_LT_AC_CHECK_DLFCN])])
+m4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER],	[AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])])
+m4_ifndef([_LT_AC_TAGCONFIG],		[AC_DEFUN([_LT_AC_TAGCONFIG])])
+m4_ifndef([AC_DISABLE_FAST_INSTALL],	[AC_DEFUN([AC_DISABLE_FAST_INSTALL])])
+m4_ifndef([_LT_AC_LANG_CXX],		[AC_DEFUN([_LT_AC_LANG_CXX])])
+m4_ifndef([_LT_AC_LANG_F77],		[AC_DEFUN([_LT_AC_LANG_F77])])
+m4_ifndef([_LT_AC_LANG_GCJ],		[AC_DEFUN([_LT_AC_LANG_GCJ])])
+m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG],	[AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])])
+m4_ifndef([_LT_AC_LANG_C_CONFIG],	[AC_DEFUN([_LT_AC_LANG_C_CONFIG])])
+m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG],	[AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])])
+m4_ifndef([_LT_AC_LANG_CXX_CONFIG],	[AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])])
+m4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG],	[AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])])
+m4_ifndef([_LT_AC_LANG_F77_CONFIG],	[AC_DEFUN([_LT_AC_LANG_F77_CONFIG])])
+m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG],	[AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])])
+m4_ifndef([_LT_AC_LANG_GCJ_CONFIG],	[AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])])
+m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG],	[AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])])
+m4_ifndef([_LT_AC_LANG_RC_CONFIG],	[AC_DEFUN([_LT_AC_LANG_RC_CONFIG])])
+m4_ifndef([AC_LIBTOOL_CONFIG],		[AC_DEFUN([AC_LIBTOOL_CONFIG])])
+m4_ifndef([_LT_AC_FILE_LTDLL_C],	[AC_DEFUN([_LT_AC_FILE_LTDLL_C])])
+m4_ifndef([_LT_REQUIRED_DARWIN_CHECKS],	[AC_DEFUN([_LT_REQUIRED_DARWIN_CHECKS])])
+m4_ifndef([_LT_AC_PROG_CXXCPP],		[AC_DEFUN([_LT_AC_PROG_CXXCPP])])
+m4_ifndef([_LT_PREPARE_SED_QUOTE_VARS],	[AC_DEFUN([_LT_PREPARE_SED_QUOTE_VARS])])
+m4_ifndef([_LT_PROG_ECHO_BACKSLASH],	[AC_DEFUN([_LT_PROG_ECHO_BACKSLASH])])
+m4_ifndef([_LT_PROG_F77],		[AC_DEFUN([_LT_PROG_F77])])
+m4_ifndef([_LT_PROG_FC],		[AC_DEFUN([_LT_PROG_FC])])
+m4_ifndef([_LT_PROG_CXX],		[AC_DEFUN([_LT_PROG_CXX])])
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/config/missing
@@ -0,0 +1,215 @@
+#! /bin/sh
+# Common wrapper for a few potentially missing GNU programs.
+
+scriptversion=2013-10-28.13; # UTC
+
+# Copyright (C) 1996-2014 Free Software Foundation, Inc.
+# Originally written by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+if test $# -eq 0; then
+  echo 1>&2 "Try '$0 --help' for more information"
+  exit 1
+fi
+
+case $1 in
+
+  --is-lightweight)
+    # Used by our autoconf macros to check whether the available missing
+    # script is modern enough.
+    exit 0
+    ;;
+
+  --run)
+    # Back-compat with the calling convention used by older automake.
+    shift
+    ;;
+
+  -h|--h|--he|--hel|--help)
+    echo "\
+$0 [OPTION]... PROGRAM [ARGUMENT]...
+
+Run 'PROGRAM [ARGUMENT]...', returning a proper advice when this fails due
+to PROGRAM being missing or too old.
+
+Options:
+  -h, --help      display this help and exit
+  -v, --version   output version information and exit
+
+Supported PROGRAM values:
+  aclocal   autoconf  autoheader   autom4te  automake  makeinfo
+  bison     yacc      flex         lex       help2man
+
+Version suffixes to PROGRAM as well as the prefixes 'gnu-', 'gnu', and
+'g' are ignored when checking the name.
+
+Send bug reports to <bug-automake@gnu.org>."
+    exit $?
+    ;;
+
+  -v|--v|--ve|--ver|--vers|--versi|--versio|--version)
+    echo "missing $scriptversion (GNU Automake)"
+    exit $?
+    ;;
+
+  -*)
+    echo 1>&2 "$0: unknown '$1' option"
+    echo 1>&2 "Try '$0 --help' for more information"
+    exit 1
+    ;;
+
+esac
+
+# Run the given program, remember its exit status.
+"$@"; st=$?
+
+# If it succeeded, we are done.
+test $st -eq 0 && exit 0
+
+# Also exit now if we it failed (or wasn't found), and '--version' was
+# passed; such an option is passed most likely to detect whether the
+# program is present and works.
+case $2 in --version|--help) exit $st;; esac
+
+# Exit code 63 means version mismatch.  This often happens when the user
+# tries to use an ancient version of a tool on a file that requires a
+# minimum version.
+if test $st -eq 63; then
+  msg="probably too old"
+elif test $st -eq 127; then
+  # Program was missing.
+  msg="missing on your system"
+else
+  # Program was found and executed, but failed.  Give up.
+  exit $st
+fi
+
+perl_URL=http://www.perl.org/
+flex_URL=http://flex.sourceforge.net/
+gnu_software_URL=http://www.gnu.org/software
+
+program_details ()
+{
+  case $1 in
+    aclocal|automake)
+      echo "The '$1' program is part of the GNU Automake package:"
+      echo "<$gnu_software_URL/automake>"
+      echo "It also requires GNU Autoconf, GNU m4 and Perl in order to run:"
+      echo "<$gnu_software_URL/autoconf>"
+      echo "<$gnu_software_URL/m4/>"
+      echo "<$perl_URL>"
+      ;;
+    autoconf|autom4te|autoheader)
+      echo "The '$1' program is part of the GNU Autoconf package:"
+      echo "<$gnu_software_URL/autoconf/>"
+      echo "It also requires GNU m4 and Perl in order to run:"
+      echo "<$gnu_software_URL/m4/>"
+      echo "<$perl_URL>"
+      ;;
+  esac
+}
+
+give_advice ()
+{
+  # Normalize program name to check for.
+  normalized_program=`echo "$1" | sed '
+    s/^gnu-//; t
+    s/^gnu//; t
+    s/^g//; t'`
+
+  printf '%s\n' "'$1' is $msg."
+
+  configure_deps="'configure.ac' or m4 files included by 'configure.ac'"
+  case $normalized_program in
+    autoconf*)
+      echo "You should only need it if you modified 'configure.ac',"
+      echo "or m4 files included by it."
+      program_details 'autoconf'
+      ;;
+    autoheader*)
+      echo "You should only need it if you modified 'acconfig.h' or"
+      echo "$configure_deps."
+      program_details 'autoheader'
+      ;;
+    automake*)
+      echo "You should only need it if you modified 'Makefile.am' or"
+      echo "$configure_deps."
+      program_details 'automake'
+      ;;
+    aclocal*)
+      echo "You should only need it if you modified 'acinclude.m4' or"
+      echo "$configure_deps."
+      program_details 'aclocal'
+      ;;
+   autom4te*)
+      echo "You might have modified some maintainer files that require"
+      echo "the 'autom4te' program to be rebuilt."
+      program_details 'autom4te'
+      ;;
+    bison*|yacc*)
+      echo "You should only need it if you modified a '.y' file."
+      echo "You may want to install the GNU Bison package:"
+      echo "<$gnu_software_URL/bison/>"
+      ;;
+    lex*|flex*)
+      echo "You should only need it if you modified a '.l' file."
+      echo "You may want to install the Fast Lexical Analyzer package:"
+      echo "<$flex_URL>"
+      ;;
+    help2man*)
+      echo "You should only need it if you modified a dependency" \
+           "of a man page."
+      echo "You may want to install the GNU Help2man package:"
+      echo "<$gnu_software_URL/help2man/>"
+    ;;
+    makeinfo*)
+      echo "You should only need it if you modified a '.texi' file, or"
+      echo "any other file indirectly affecting the aspect of the manual."
+      echo "You might want to install the Texinfo package:"
+      echo "<$gnu_software_URL/texinfo/>"
+      echo "The spurious makeinfo call might also be the consequence of"
+      echo "using a buggy 'make' (AIX, DU, IRIX), in which case you might"
+      echo "want to install GNU make:"
+      echo "<$gnu_software_URL/make/>"
+      ;;
+    *)
+      echo "You might have modified some files without having the proper"
+      echo "tools for further handling them.  Check the 'README' file, it"
+      echo "often tells you about the needed prerequisites for installing"
+      echo "this package.  You may also peek at any GNU archive site, in"
+      echo "case some other package contains this missing '$1' program."
+      ;;
+  esac
+}
+
+give_advice "$1" | sed -e '1s/^/WARNING: /' \
+                       -e '2,$s/^/         /' >&2
+
+# Propagate the correct exit status (expected to be 127 for a program
+# not found, 63 for a program that failed due to version mismatch).
+exit $st
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
+# End:
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/config/rpm.am
@@ -0,0 +1,87 @@
+###############################################################################
+# Copyright (C) 2007-2013 Lawrence Livermore National Security, LLC.
+# Copyright (C) 2007 The Regents of the University of California.
+# Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+###############################################################################
+# Build targets for RPM packages.
+###############################################################################
+
+srpm-kmod:
+	$(MAKE) $(AM_MAKEFLAGS) pkg="${PACKAGE}-kmod" \
+		def='${SRPM_DEFINE_COMMON} ${SRPM_DEFINE_KMOD}' srpm-common
+
+srpm-dkms:
+	$(MAKE) $(AM_MAKEFLAGS) pkg="${PACKAGE}-dkms" \
+		def='${SRPM_DEFINE_COMMON} ${SRPM_DEFINE_DKMS}' srpm-common
+
+srpm-utils:
+	$(MAKE) $(AM_MAKEFLAGS) pkg="${PACKAGE}" \
+		def='${SRPM_DEFINE_COMMON} ${SRPM_DEFINE_UTIL}' srpm-common
+
+srpm: srpm-kmod srpm-dkms srpm-utils
+srpms: srpm-kmod srpm-dkms srpm-utils
+
+rpm-kmod: srpm-kmod
+	$(MAKE) $(AM_MAKEFLAGS) pkg="${PACKAGE}-kmod" \
+		def='${RPM_DEFINE_COMMON} ${RPM_DEFINE_KMOD}' rpm-common
+
+rpm-dkms: srpm-dkms
+	$(MAKE) $(AM_MAKEFLAGS) pkg="${PACKAGE}-dkms" \
+		def='${RPM_DEFINE_COMMON} ${RPM_DEFINE_DKMS}' rpm-common
+
+rpm-utils: srpm-utils
+	$(MAKE) $(AM_MAKEFLAGS) pkg="${PACKAGE}" \
+		def='${RPM_DEFINE_COMMON} ${RPM_DEFINE_UTIL}' rpm-common
+
+rpm: rpm-kmod rpm-dkms rpm-utils
+rpms: rpm-kmod rpm-dkms rpm-utils
+
+rpm-local:
+	@(if test "${HAVE_RPMBUILD}" = "no"; then \
+		echo -e "\n" \
+	"*** Required util ${RPMBUILD} missing.  Please install the\n" \
+	"*** package for your distribution which provides ${RPMBUILD},\n" \
+	"*** re-run configure, and try again.\n"; \
+		exit 1; \
+	fi; \
+	mkdir -p $(rpmbuild)/TMP && \
+	mkdir -p $(rpmbuild)/BUILD && \
+	mkdir -p $(rpmbuild)/RPMS && \
+	mkdir -p $(rpmbuild)/SRPMS && \
+	mkdir -p $(rpmbuild)/SPECS && \
+	cp ${RPM_SPEC_DIR}/$(rpmspec) $(rpmbuild)/SPECS && \
+	mkdir -p $(rpmbuild)/SOURCES && \
+	cp $(top_srcdir)/scripts/kmodtool $(rpmbuild)/SOURCES && \
+	cp $(distdir).tar.gz $(rpmbuild)/SOURCES)
+
+srpm-common: dist
+	@(dist=`$(RPM) --eval %{?dist}`; \
+	rpmpkg=$(pkg)-$(VERSION)-$(RELEASE)$$dist*src.rpm; \
+	rpmspec=$(pkg).spec; \
+	rpmbuild=`mktemp -t -d $(PACKAGE)-build-$$USER-XXXXXXXX`; \
+	$(MAKE) $(AM_MAKEFLAGS) \
+		rpmbuild="$$rpmbuild" \
+		rpmspec="$$rpmspec" \
+		rpm-local || exit 1; \
+	LANG=C $(RPMBUILD) \
+		--define "_tmppath $$rpmbuild/TMP" \
+		--define "_topdir $$rpmbuild" \
+		$(def) -bs $$rpmbuild/SPECS/$$rpmspec || exit 1; \
+	cp $$rpmbuild/SRPMS/$$rpmpkg . || exit 1; \
+	rm -R $$rpmbuild)
+
+rpm-common: 
+	@(dist=`$(RPM) --eval %{?dist}`; \
+	rpmpkg=$(pkg)-$(VERSION)-$(RELEASE)$$dist*src.rpm; \
+	rpmspec=$(pkg).spec; \
+	rpmbuild=`mktemp -t -d $(PACKAGE)-build-$$USER-XXXXXXXX`; \
+	$(MAKE) $(AM_MAKEFLAGS) \
+		rpmbuild="$$rpmbuild" \
+		rpmspec="$$rpmspec" \
+		rpm-local || exit 1; \
+	LANG=C ${RPMBUILD} \
+		--define "_tmppath $$rpmbuild/TMP" \
+		--define "_topdir $$rpmbuild" \
+		$(def) --rebuild $$rpmpkg || exit 1; \
+	cp $$rpmbuild/RPMS/*/* . || exit 1; \
+	rm -R $$rpmbuild)
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/config/spl-build.m4
@@ -0,0 +1,1449 @@
+###############################################################################
+# Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+# Copyright (C) 2007 The Regents of the University of California.
+# Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+###############################################################################
+# SPL_AC_CONFIG_KERNEL: Default SPL kernel configuration.
+###############################################################################
+
+AC_DEFUN([SPL_AC_CONFIG_KERNEL], [
+	SPL_AC_KERNEL
+
+	if test "${LINUX_OBJ}" != "${LINUX}"; then
+		KERNELMAKE_PARAMS="$KERNELMAKE_PARAMS O=$LINUX_OBJ"
+	fi
+	AC_SUBST(KERNELMAKE_PARAMS)
+
+	KERNELCPPFLAGS="$KERNELCPPFLAGS -Wstrict-prototypes"
+	AC_SUBST(KERNELCPPFLAGS)
+
+	SPL_AC_DEBUG
+	SPL_AC_DEBUG_KMEM
+	SPL_AC_DEBUG_KMEM_TRACKING
+	SPL_AC_TEST_MODULE
+	SPL_AC_ATOMIC_SPINLOCK
+	SPL_AC_SHRINKER_CALLBACK
+	SPL_AC_CTL_NAME
+	SPL_AC_PDE_DATA
+	SPL_AC_SET_FS_PWD_WITH_CONST
+	SPL_AC_2ARGS_VFS_UNLINK
+	SPL_AC_4ARGS_VFS_RENAME
+	SPL_AC_2ARGS_VFS_FSYNC
+	SPL_AC_INODE_TRUNCATE_RANGE
+	SPL_AC_FS_STRUCT_SPINLOCK
+	SPL_AC_KUIDGID_T
+	SPL_AC_PUT_TASK_STRUCT
+	SPL_AC_KERNEL_FALLOCATE
+	SPL_AC_CONFIG_ZLIB_INFLATE
+	SPL_AC_CONFIG_ZLIB_DEFLATE
+	SPL_AC_2ARGS_ZLIB_DEFLATE_WORKSPACESIZE
+	SPL_AC_SHRINK_CONTROL_STRUCT
+	SPL_AC_RWSEM_SPINLOCK_IS_RAW
+	SPL_AC_SCHED_RT_HEADER
+	SPL_AC_2ARGS_VFS_GETATTR
+	SPL_AC_USLEEP_RANGE
+	SPL_AC_KMEM_CACHE_ALLOCFLAGS
+	SPL_AC_WAIT_ON_BIT
+])
+
+AC_DEFUN([SPL_AC_MODULE_SYMVERS], [
+	modpost=$LINUX/scripts/Makefile.modpost
+	AC_MSG_CHECKING([kernel file name for module symbols])
+	if test "x$enable_linux_builtin" != xyes -a -f "$modpost"; then
+		if grep -q Modules.symvers $modpost; then
+			LINUX_SYMBOLS=Modules.symvers
+		else
+			LINUX_SYMBOLS=Module.symvers
+		fi
+
+		if ! test -f "$LINUX_OBJ/$LINUX_SYMBOLS"; then
+			AC_MSG_ERROR([
+	*** Please make sure the kernel devel package for your distribution
+	*** is installed.  If you are building with a custom kernel, make sure the
+	*** kernel is configured, built, and the '--with-linux=PATH' configure
+	*** option refers to the location of the kernel source.])
+		fi
+	else
+		LINUX_SYMBOLS=NONE
+	fi
+	AC_MSG_RESULT($LINUX_SYMBOLS)
+	AC_SUBST(LINUX_SYMBOLS)
+])
+
+AC_DEFUN([SPL_AC_KERNEL], [
+	AC_ARG_WITH([linux],
+		AS_HELP_STRING([--with-linux=PATH],
+		[Path to kernel source]),
+		[kernelsrc="$withval"])
+
+	AC_ARG_WITH([linux-obj],
+		AS_HELP_STRING([--with-linux-obj=PATH],
+		[Path to kernel build objects]),
+		[kernelbuild="$withval"])
+
+	AC_MSG_CHECKING([kernel source directory])
+	if test -z "$kernelsrc"; then
+		if test -e "/lib/modules/$(uname -r)/source"; then
+			headersdir="/lib/modules/$(uname -r)/source"
+			sourcelink=$(readlink -f "$headersdir")
+		elif test -e "/lib/modules/$(uname -r)/build"; then
+			headersdir="/lib/modules/$(uname -r)/build"
+			sourcelink=$(readlink -f "$headersdir")
+		else
+			sourcelink=$(ls -1d /usr/src/kernels/* \
+			             /usr/src/linux-* \
+			             2>/dev/null | grep -v obj | tail -1)
+		fi
+
+		if test -n "$sourcelink" && test -e ${sourcelink}; then
+			kernelsrc=`readlink -f ${sourcelink}`
+		else
+			kernelsrc="[Not found]"
+		fi
+	else
+		if test "$kernelsrc" = "NONE"; then
+			kernsrcver=NONE
+		fi
+	fi
+
+	AC_MSG_RESULT([$kernelsrc])
+	if test ! -d "$kernelsrc"; then
+		AC_MSG_ERROR([
+	*** Please make sure the kernel devel package for your distribution
+	*** is installed and then try again.  If that fails, you can specify the
+	*** location of the kernel source with the '--with-linux=PATH' option.])
+	fi
+
+	AC_MSG_CHECKING([kernel build directory])
+	if test -z "$kernelbuild"; then
+		if test -e "/lib/modules/$(uname -r)/build"; then
+			kernelbuild=`readlink -f /lib/modules/$(uname -r)/build`
+		elif test -d ${kernelsrc}-obj/${target_cpu}/${target_cpu}; then
+			kernelbuild=${kernelsrc}-obj/${target_cpu}/${target_cpu}
+		elif test -d ${kernelsrc}-obj/${target_cpu}/default; then
+			kernelbuild=${kernelsrc}-obj/${target_cpu}/default
+		elif test -d `dirname ${kernelsrc}`/build-${target_cpu}; then
+			kernelbuild=`dirname ${kernelsrc}`/build-${target_cpu}
+		else
+			kernelbuild=${kernelsrc}
+		fi
+	fi
+	AC_MSG_RESULT([$kernelbuild])
+
+	AC_MSG_CHECKING([kernel source version])
+	utsrelease1=$kernelbuild/include/linux/version.h
+	utsrelease2=$kernelbuild/include/linux/utsrelease.h
+	utsrelease3=$kernelbuild/include/generated/utsrelease.h
+	if test -r $utsrelease1 && fgrep -q UTS_RELEASE $utsrelease1; then
+		utsrelease=linux/version.h
+	elif test -r $utsrelease2 && fgrep -q UTS_RELEASE $utsrelease2; then
+		utsrelease=linux/utsrelease.h
+	elif test -r $utsrelease3 && fgrep -q UTS_RELEASE $utsrelease3; then
+		utsrelease=generated/utsrelease.h
+	fi
+
+	if test "$utsrelease"; then
+		kernsrcver=`(echo "#include <$utsrelease>";
+		             echo "kernsrcver=UTS_RELEASE") | 
+		             cpp -I $kernelbuild/include |
+		             grep "^kernsrcver=" | cut -d \" -f 2`
+
+		if test -z "$kernsrcver"; then
+			AC_MSG_RESULT([Not found])
+			AC_MSG_ERROR([*** Cannot determine kernel version.])
+		fi
+	else
+		AC_MSG_RESULT([Not found])
+		if test "x$enable_linux_builtin" != xyes; then
+			AC_MSG_ERROR([*** Cannot find UTS_RELEASE definition.])
+		else
+			AC_MSG_ERROR([
+	*** Cannot find UTS_RELEASE definition.
+	*** Please run 'make prepare' inside the kernel source tree.])
+		fi
+	fi
+
+	AC_MSG_RESULT([$kernsrcver])
+
+	LINUX=${kernelsrc}
+	LINUX_OBJ=${kernelbuild}
+	LINUX_VERSION=${kernsrcver}
+
+	AC_SUBST(LINUX)
+	AC_SUBST(LINUX_OBJ)
+	AC_SUBST(LINUX_VERSION)
+
+	SPL_AC_MODULE_SYMVERS
+])
+
+dnl #
+dnl # Default SPL user configuration
+dnl #
+AC_DEFUN([SPL_AC_CONFIG_USER], [])
+
+dnl #
+dnl # Check for rpm+rpmbuild to build RPM packages.  If these tools
+dnl # are missing, it is non-fatal, but you will not be able to build
+dnl # RPM packages and will be warned if you try too.
+dnl #
+dnl # By default, the generic spec file will be used because it requires
+dnl # minimal dependencies.  Distribution specific spec files can be
+dnl # placed under the 'rpm/<distribution>' directory and enabled using
+dnl # the --with-spec=<distribution> configure option.
+dnl #
+AC_DEFUN([SPL_AC_RPM], [
+	RPM=rpm
+	RPMBUILD=rpmbuild
+
+	AC_MSG_CHECKING([whether $RPM is available])
+	AS_IF([tmp=$($RPM --version 2>/dev/null)], [
+		RPM_VERSION=$(echo $tmp | $AWK '/RPM/ { print $[3] }')
+		HAVE_RPM=yes
+		AC_MSG_RESULT([$HAVE_RPM ($RPM_VERSION)])
+	],[
+		HAVE_RPM=no
+		AC_MSG_RESULT([$HAVE_RPM])
+	])
+
+	AC_MSG_CHECKING([whether $RPMBUILD is available])
+	AS_IF([tmp=$($RPMBUILD --version 2>/dev/null)], [
+		RPMBUILD_VERSION=$(echo $tmp | $AWK '/RPM/ { print $[3] }')
+		HAVE_RPMBUILD=yes
+		AC_MSG_RESULT([$HAVE_RPMBUILD ($RPMBUILD_VERSION)])
+	],[
+		HAVE_RPMBUILD=no
+		AC_MSG_RESULT([$HAVE_RPMBUILD])
+	])
+
+	RPM_DEFINE_COMMON='--define "$(DEBUG_SPL) 1" --define "$(DEBUG_KMEM) 1" --define "$(DEBUG_KMEM_TRACKING) 1"'
+	RPM_DEFINE_UTIL=
+	RPM_DEFINE_KMOD='--define "kernels $(LINUX_VERSION)"'
+	RPM_DEFINE_DKMS=
+
+	SRPM_DEFINE_COMMON='--define "build_src_rpm 1"'
+	SRPM_DEFINE_UTIL=
+	SRPM_DEFINE_KMOD=
+	SRPM_DEFINE_DKMS=
+
+	RPM_SPEC_DIR="rpm/generic"
+	AC_ARG_WITH([spec],
+		AS_HELP_STRING([--with-spec=SPEC],
+		[Spec files 'generic|redhat']),
+		[RPM_SPEC_DIR="rpm/$withval"])
+
+	AC_MSG_CHECKING([whether spec files are available])
+	AC_MSG_RESULT([yes ($RPM_SPEC_DIR/*.spec.in)])
+
+	AC_SUBST(HAVE_RPM)
+	AC_SUBST(RPM)
+	AC_SUBST(RPM_VERSION)
+
+	AC_SUBST(HAVE_RPMBUILD)
+	AC_SUBST(RPMBUILD)
+	AC_SUBST(RPMBUILD_VERSION)
+
+	AC_SUBST(RPM_SPEC_DIR)
+	AC_SUBST(RPM_DEFINE_UTIL)
+	AC_SUBST(RPM_DEFINE_KMOD)
+	AC_SUBST(RPM_DEFINE_DKMS)
+	AC_SUBST(RPM_DEFINE_COMMON)
+	AC_SUBST(SRPM_DEFINE_UTIL)
+	AC_SUBST(SRPM_DEFINE_KMOD)
+	AC_SUBST(SRPM_DEFINE_DKMS)
+	AC_SUBST(SRPM_DEFINE_COMMON)
+])
+
+dnl #
+dnl # Check for dpkg+dpkg-buildpackage to build DEB packages.  If these
+dnl # tools are missing it is non-fatal but you will not be able to build
+dnl # DEB packages and will be warned if you try too.
+dnl #
+AC_DEFUN([SPL_AC_DPKG], [
+	DPKG=dpkg
+	DPKGBUILD=dpkg-buildpackage
+
+	AC_MSG_CHECKING([whether $DPKG is available])
+	AS_IF([tmp=$($DPKG --version 2>/dev/null)], [
+		DPKG_VERSION=$(echo $tmp | $AWK '/Debian/ { print $[7] }')
+		HAVE_DPKG=yes
+		AC_MSG_RESULT([$HAVE_DPKG ($DPKG_VERSION)])
+	],[
+		HAVE_DPKG=no
+		AC_MSG_RESULT([$HAVE_DPKG])
+	])
+
+	AC_MSG_CHECKING([whether $DPKGBUILD is available])
+	AS_IF([tmp=$($DPKGBUILD --version 2>/dev/null)], [
+		DPKGBUILD_VERSION=$(echo $tmp | \
+		    $AWK '/Debian/ { print $[4] }' | cut -f-4 -d'.')
+		HAVE_DPKGBUILD=yes
+		AC_MSG_RESULT([$HAVE_DPKGBUILD ($DPKGBUILD_VERSION)])
+	],[
+		HAVE_DPKGBUILD=no
+		AC_MSG_RESULT([$HAVE_DPKGBUILD])
+	])
+
+	AC_SUBST(HAVE_DPKG)
+	AC_SUBST(DPKG)
+	AC_SUBST(DPKG_VERSION)
+
+	AC_SUBST(HAVE_DPKGBUILD)
+	AC_SUBST(DPKGBUILD)
+	AC_SUBST(DPKGBUILD_VERSION)
+])
+
+dnl #
+dnl # Until native packaging for various different packing systems
+dnl # can be added the least we can do is attempt to use alien to
+dnl # convert the RPM packages to the needed package type.  This is
+dnl # a hack but so far it has worked reasonable well.
+dnl #
+AC_DEFUN([SPL_AC_ALIEN], [
+	ALIEN=alien
+
+	AC_MSG_CHECKING([whether $ALIEN is available])
+	AS_IF([tmp=$($ALIEN --version 2>/dev/null)], [
+		ALIEN_VERSION=$(echo $tmp | $AWK '{ print $[3] }')
+		HAVE_ALIEN=yes
+		AC_MSG_RESULT([$HAVE_ALIEN ($ALIEN_VERSION)])
+	],[
+		HAVE_ALIEN=no
+		AC_MSG_RESULT([$HAVE_ALIEN])
+	])
+
+	AC_SUBST(HAVE_ALIEN)
+	AC_SUBST(ALIEN)
+	AC_SUBST(ALIEN_VERSION)
+])
+
+dnl #
+dnl # Using the VENDOR tag from config.guess set the default
+dnl # package type for 'make pkg': (rpm | deb | tgz)
+dnl #
+AC_DEFUN([SPL_AC_DEFAULT_PACKAGE], [
+	AC_MSG_CHECKING([linux distribution])
+	if test -f /etc/toss-release ; then
+		VENDOR=toss ;
+	elif test -f /etc/fedora-release ; then
+		VENDOR=fedora ;
+	elif test -f /etc/redhat-release ; then
+		VENDOR=redhat ;
+	elif test -f /etc/gentoo-release ; then
+		VENDOR=gentoo ;
+	elif test -f /etc/arch-release ; then
+		VENDOR=arch ;
+	elif test -f /etc/SuSE-release ; then
+		VENDOR=sles ;
+	elif test -f /etc/slackware-version ; then
+		VENDOR=slackware ;
+	elif test -f /etc/lunar.release ; then
+		VENDOR=lunar ;
+	elif test -f /etc/lsb-release ; then
+		VENDOR=ubuntu ;
+	elif test -f /etc/debian_version ; then
+		VENDOR=debian ;
+	else
+		VENDOR= ;
+	fi
+	AC_MSG_RESULT([$VENDOR])
+	AC_SUBST(VENDOR)
+
+	AC_MSG_CHECKING([default package type])
+	case "$VENDOR" in
+		toss)       DEFAULT_PACKAGE=rpm  ;;
+		redhat)     DEFAULT_PACKAGE=rpm  ;;
+		fedora)     DEFAULT_PACKAGE=rpm  ;;
+		gentoo)     DEFAULT_PACKAGE=tgz  ;;
+		arch)       DEFAULT_PACKAGE=tgz  ;;
+		sles)       DEFAULT_PACKAGE=rpm  ;;
+		slackware)  DEFAULT_PACKAGE=tgz  ;;
+		lunar)      DEFAULT_PACKAGE=tgz  ;;
+		ubuntu)     DEFAULT_PACKAGE=deb  ;;
+		debian)     DEFAULT_PACKAGE=deb  ;;
+		*)          DEFAULT_PACKAGE=rpm  ;;
+	esac
+
+	AC_MSG_RESULT([$DEFAULT_PACKAGE])
+	AC_SUBST(DEFAULT_PACKAGE)
+])
+
+dnl #
+dnl # Default SPL user configuration
+dnl #
+AC_DEFUN([SPL_AC_PACKAGE], [
+	SPL_AC_DEFAULT_PACKAGE
+	SPL_AC_RPM
+	SPL_AC_DPKG
+	SPL_AC_ALIEN
+])
+
+AC_DEFUN([SPL_AC_LICENSE], [
+	AC_MSG_CHECKING([spl author])
+	AC_MSG_RESULT([$SPL_META_AUTHOR])
+
+	AC_MSG_CHECKING([spl license])
+	AC_MSG_RESULT([$SPL_META_LICENSE])
+])
+
+AC_DEFUN([SPL_AC_CONFIG], [
+	SPL_CONFIG=all
+	AC_ARG_WITH([config],
+		AS_HELP_STRING([--with-config=CONFIG],
+		[Config file 'kernel|user|all|srpm']),
+		[SPL_CONFIG="$withval"])
+	AC_ARG_ENABLE([linux-builtin],
+		[AC_HELP_STRING([--enable-linux-builtin],
+		[Configure for builtin in-tree kernel modules @<:@default=no@:>@])],
+		[],
+		[enable_linux_builtin=no])
+
+	AC_MSG_CHECKING([spl config])
+	AC_MSG_RESULT([$SPL_CONFIG]);
+	AC_SUBST(SPL_CONFIG)
+
+	case "$SPL_CONFIG" in
+		kernel) SPL_AC_CONFIG_KERNEL ;;
+		user)   SPL_AC_CONFIG_USER   ;;
+		all)    SPL_AC_CONFIG_KERNEL
+		        SPL_AC_CONFIG_USER   ;;
+		srpm)                        ;;
+		*)
+		AC_MSG_RESULT([Error!])
+		AC_MSG_ERROR([Bad value "$SPL_CONFIG" for --with-config,
+		             user kernel|user|all|srpm]) ;;
+	esac
+
+	AM_CONDITIONAL([CONFIG_USER],
+	               [test "$SPL_CONFIG" = user -o "$SPL_CONFIG" = all])
+	AM_CONDITIONAL([CONFIG_KERNEL],
+	               [test "$SPL_CONFIG" = kernel -o "$SPL_CONFIG" = all] &&
+	               [test "x$enable_linux_builtin" != xyes ])
+])
+
+dnl #
+dnl # Enable if the SPL should be compiled with internal debugging enabled.
+dnl # By default this support is disabled.
+dnl #
+AC_DEFUN([SPL_AC_DEBUG], [
+	AC_MSG_CHECKING([whether debugging is enabled])
+	AC_ARG_ENABLE([debug],
+		[AS_HELP_STRING([--enable-debug],
+		[Enable generic debug support @<:@default=no@:>@])],
+		[],
+		[enable_debug=no])
+
+	AS_IF([test "x$enable_debug" = xyes],
+	[
+		KERNELCPPFLAGS="${KERNELCPPFLAGS} -DDEBUG -Werror"
+		DEBUG_CFLAGS="-DDEBUG -Werror"
+		DEBUG_SPL="_with_debug"
+	], [
+		KERNELCPPFLAGS="${KERNELCPPFLAGS} -DNDEBUG"
+		DEBUG_CFLAGS="-DNDEBUG"
+		DEBUG_SPL="_without_debug"
+	])
+
+	AC_SUBST(DEBUG_CFLAGS)
+	AC_SUBST(DEBUG_SPL)
+	AC_MSG_RESULT([$enable_debug])
+])
+
+dnl #
+dnl # Enabled by default it provides a minimal level of memory tracking.
+dnl # A total count of bytes allocated is kept for each alloc and free.
+dnl # Then at module unload time a report to the console will be printed
+dnl # if memory was leaked.
+dnl #
+AC_DEFUN([SPL_AC_DEBUG_KMEM], [
+	AC_ARG_ENABLE([debug-kmem],
+		[AS_HELP_STRING([--enable-debug-kmem],
+		[Enable basic kmem accounting @<:@default=no@:>@])],
+		[],
+		[enable_debug_kmem=no])
+
+	AS_IF([test "x$enable_debug_kmem" = xyes],
+	[
+		KERNELCPPFLAGS="${KERNELCPPFLAGS} -DDEBUG_KMEM"
+		DEBUG_KMEM="_with_debug_kmem"
+		AC_DEFINE([DEBUG_KMEM], [1],
+		[Define to 1 to enable basic kmem accounting])
+	], [
+		DEBUG_KMEM="_without_debug_kmem"
+	])
+
+	AC_SUBST(DEBUG_KMEM)
+	AC_MSG_CHECKING([whether basic kmem accounting is enabled])
+	AC_MSG_RESULT([$enable_debug_kmem])
+])
+
+dnl #
+dnl # Disabled by default it provides detailed memory tracking.  This
+dnl # feature also requires --enable-debug-kmem to be set.  When enabled
+dnl # not only will total bytes be tracked but also the location of every
+dnl # alloc and free.  When the SPL module is unloaded a list of all leaked
+dnl # addresses and where they were allocated will be dumped to the console.
+dnl # Enabling this feature has a significant impact on performance but it
+dnl # makes finding memory leaks pretty straight forward.
+dnl #
+AC_DEFUN([SPL_AC_DEBUG_KMEM_TRACKING], [
+	AC_ARG_ENABLE([debug-kmem-tracking],
+		[AS_HELP_STRING([--enable-debug-kmem-tracking],
+		[Enable detailed kmem tracking  @<:@default=no@:>@])],
+		[],
+		[enable_debug_kmem_tracking=no])
+
+	AS_IF([test "x$enable_debug_kmem_tracking" = xyes],
+	[
+		KERNELCPPFLAGS="${KERNELCPPFLAGS} -DDEBUG_KMEM_TRACKING"
+		DEBUG_KMEM_TRACKING="_with_debug_kmem_tracking"
+		AC_DEFINE([DEBUG_KMEM_TRACKING], [1],
+		[Define to 1 to enable detailed kmem tracking])
+	], [
+		DEBUG_KMEM_TRACKING="_without_debug_kmem_tracking"
+	])
+
+	AC_SUBST(DEBUG_KMEM_TRACKING)
+	AC_MSG_CHECKING([whether detailed kmem tracking is enabled])
+	AC_MSG_RESULT([$enable_debug_kmem_tracking])
+])
+
+dnl #
+dnl # SPL_LINUX_CONFTEST
+dnl #
+AC_DEFUN([SPL_LINUX_CONFTEST], [
+cat confdefs.h - <<_ACEOF >conftest.c
+$1
+_ACEOF
+])
+
+dnl #
+dnl # SPL_LANG_PROGRAM(C)([PROLOGUE], [BODY])
+dnl #
+m4_define([SPL_LANG_PROGRAM], [
+$1
+int
+main (void)
+{
+dnl Do *not* indent the following line: there may be CPP directives.
+dnl Don't move the `;' right after for the same reason.
+$2
+  ;
+  return 0;
+}
+])
+
+dnl #
+dnl # SPL_LINUX_COMPILE_IFELSE / like AC_COMPILE_IFELSE
+dnl #
+AC_DEFUN([SPL_LINUX_COMPILE_IFELSE], [
+	m4_ifvaln([$1], [SPL_LINUX_CONFTEST([$1])])
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	AS_IF(
+		[AC_TRY_COMMAND(cp conftest.c build && make [$2] -C $LINUX_OBJ EXTRA_CFLAGS="-Werror-implicit-function-declaration $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag) >/dev/null && AC_TRY_COMMAND([$3])],
+		[$4],
+		[_AC_MSG_LOG_CONFTEST m4_ifvaln([$5],[$5])]
+	)
+	rm -Rf build
+])
+
+dnl #
+dnl # SPL_LINUX_TRY_COMPILE like AC_TRY_COMPILE
+dnl #
+AC_DEFUN([SPL_LINUX_TRY_COMPILE],
+	[SPL_LINUX_COMPILE_IFELSE(
+	[AC_LANG_SOURCE([SPL_LANG_PROGRAM([[$1]], [[$2]])])],
+	[modules],
+	[test -s build/conftest.o],
+	[$3], [$4])
+])
+
+dnl #
+dnl # SPL_CHECK_SYMBOL_EXPORT
+dnl # check symbol exported or not
+dnl #
+AC_DEFUN([SPL_CHECK_SYMBOL_EXPORT], [
+	grep -q -E '[[[:space:]]]$1[[[:space:]]]' \
+		$LINUX_OBJ/Module*.symvers 2>/dev/null
+	rc=$?
+	if test $rc -ne 0; then
+		export=0
+		for file in $2; do
+			grep -q -E "EXPORT_SYMBOL.*($1)" \
+				"$LINUX_OBJ/$file" 2>/dev/null
+			rc=$?
+			if test $rc -eq 0; then
+				export=1
+				break;
+			fi
+		done
+		if test $export -eq 0; then :
+			$4
+		else :
+			$3
+		fi
+	else :
+		$3
+	fi
+])
+
+dnl #
+dnl # SPL_LINUX_TRY_COMPILE_SYMBOL
+dnl # like SPL_LINUX_TRY_COMPILE, except SPL_CHECK_SYMBOL_EXPORT
+dnl # is called if not compiling for builtin
+dnl #
+AC_DEFUN([SPL_LINUX_TRY_COMPILE_SYMBOL], [
+	SPL_LINUX_TRY_COMPILE([$1], [$2], [rc=0], [rc=1])
+	if test $rc -ne 0; then :
+		$6
+	else
+		if test "x$enable_linux_builtin" != xyes; then
+			SPL_CHECK_SYMBOL_EXPORT([$3], [$4], [rc=0], [rc=1])
+		fi
+		if test $rc -ne 0; then :
+			$6
+		else :
+			$5
+		fi
+	fi
+])
+
+dnl #
+dnl # SPL_CHECK_SYMBOL_HEADER
+dnl # check if a symbol prototype is defined in listed headers.
+dnl #
+AC_DEFUN([SPL_CHECK_SYMBOL_HEADER], [
+	AC_MSG_CHECKING([whether symbol $1 exists in header])
+	header=0
+	for file in $3; do
+		grep -q "$2" "$LINUX/$file" 2>/dev/null
+		rc=$?
+		if test $rc -eq 0; then
+			header=1
+			break;
+		fi
+	done
+	if test $header -eq 0; then
+		AC_MSG_RESULT([no])
+		$5
+	else
+		AC_MSG_RESULT([yes])
+		$4
+	fi
+])
+
+dnl #
+dnl # SPL_CHECK_HEADER
+dnl # check whether header exists and define HAVE_$2_HEADER
+dnl #
+AC_DEFUN([SPL_CHECK_HEADER],
+	[AC_MSG_CHECKING([whether header $1 exists])
+	SPL_LINUX_TRY_COMPILE([
+		#include <$1>
+	],[
+		return 0;
+	],[
+		AC_DEFINE(HAVE_$2_HEADER, 1, [$1 exists])
+		AC_MSG_RESULT(yes)
+		$3
+	],[
+		AC_MSG_RESULT(no)
+		$4
+	])
+])
+
+dnl #
+dnl # Basic toolchain sanity check.  Verify that kernel modules can
+dnl # be built and which symbols can be used.
+dnl #
+AC_DEFUN([SPL_AC_TEST_MODULE],
+	[AC_MSG_CHECKING([whether modules can be built])
+	SPL_LINUX_TRY_COMPILE([],[],[
+		AC_MSG_RESULT([yes])
+	],[
+		AC_MSG_RESULT([no])
+		if test "x$enable_linux_builtin" != xyes; then
+			AC_MSG_ERROR([*** Unable to build an empty module.])
+		else
+			AC_MSG_ERROR([
+	*** Unable to build an empty module.
+	*** Please run 'make scripts' inside the kernel source tree.])
+		fi
+	])
+
+	AS_IF([test "x$cross_compiling" != xyes], [
+		AC_RUN_IFELSE([
+			AC_LANG_PROGRAM([
+				#include "$LINUX/include/linux/license.h"
+			], [
+				return !license_is_gpl_compatible(
+				    "$SPL_META_LICENSE");
+			])
+		], [
+			AC_DEFINE([SPL_IS_GPL_COMPATIBLE], [1],
+			    [Define to 1 if GPL-only symbols can be used])
+		], [
+		])
+	])
+])
+
+dnl #
+dnl # Use the atomic implemenation based on global spinlocks.  This
+dnl # should only be needed by 32-bit kernels which do not provide
+dnl # the atomic64_* API.  It may be optionally enabled as a fallback
+dnl # if problems are observed with the direct mapping to the native
+dnl # Linux atomic operations.  You may not disable atomic spinlocks
+dnl # if you kernel does not an atomic64_* API.
+dnl #
+AC_DEFUN([SPL_AC_ATOMIC_SPINLOCK], [
+	AC_ARG_ENABLE([atomic-spinlocks],
+		[AS_HELP_STRING([--enable-atomic-spinlocks],
+		[Atomic types use spinlocks @<:@default=check@:>@])],
+		[],
+		[enable_atomic_spinlocks=check])
+
+	SPL_LINUX_TRY_COMPILE([
+		#include <linux/fs.h>
+	],[
+		atomic64_t *ptr __attribute__ ((unused));
+	],[
+		have_atomic64_t=yes
+		AC_DEFINE(HAVE_ATOMIC64_T, 1,
+			[kernel defines atomic64_t])
+	],[
+		have_atomic64_t=no
+	])
+
+	AS_IF([test "x$enable_atomic_spinlocks" = xcheck], [
+		AS_IF([test "x$have_atomic64_t" = xyes], [
+			enable_atomic_spinlocks=no
+		],[
+			enable_atomic_spinlocks=yes
+		])
+	])
+
+	AS_IF([test "x$enable_atomic_spinlocks" = xyes], [
+		AC_DEFINE([ATOMIC_SPINLOCK], [1],
+			[Atomic types use spinlocks])
+	],[
+		AS_IF([test "x$have_atomic64_t" = xno], [
+			AC_MSG_FAILURE(
+			[--disable-atomic-spinlocks given but required atomic64 support is unavailable])
+		])
+	])
+
+	AC_MSG_CHECKING([whether atomic types use spinlocks])
+	AC_MSG_RESULT([$enable_atomic_spinlocks])
+
+	AC_MSG_CHECKING([whether kernel defines atomic64_t])
+	AC_MSG_RESULT([$have_atomic64_t])
+])
+
+AC_DEFUN([SPL_AC_SHRINKER_CALLBACK],[
+	tmp_flags="$EXTRA_KCFLAGS"
+	EXTRA_KCFLAGS="-Werror"
+	dnl #
+	dnl # 2.6.23 to 2.6.34 API change
+	dnl # ->shrink(int nr_to_scan, gfp_t gfp_mask)
+	dnl #
+	AC_MSG_CHECKING([whether old 2-argument shrinker exists])
+	SPL_LINUX_TRY_COMPILE([
+		#include <linux/mm.h>
+
+		int shrinker_cb(int nr_to_scan, gfp_t gfp_mask);
+	],[
+		struct shrinker cache_shrinker = {
+			.shrink = shrinker_cb,
+			.seeks = DEFAULT_SEEKS,
+		};
+		register_shrinker(&cache_shrinker);
+	],[
+		AC_MSG_RESULT(yes)
+		AC_DEFINE(HAVE_2ARGS_OLD_SHRINKER_CALLBACK, 1,
+			[old shrinker callback wants 2 args])
+	],[
+		AC_MSG_RESULT(no)
+		dnl #
+		dnl # 2.6.35 - 2.6.39 API change
+		dnl # ->shrink(struct shrinker *,
+		dnl #          int nr_to_scan, gfp_t gfp_mask)
+		dnl #
+		AC_MSG_CHECKING([whether old 3-argument shrinker exists])
+		SPL_LINUX_TRY_COMPILE([
+			#include <linux/mm.h>
+
+			int shrinker_cb(struct shrinker *, int nr_to_scan,
+					gfp_t gfp_mask);
+		],[
+			struct shrinker cache_shrinker = {
+				.shrink = shrinker_cb,
+				.seeks = DEFAULT_SEEKS,
+			};
+			register_shrinker(&cache_shrinker);
+		],[
+			AC_MSG_RESULT(yes)
+			AC_DEFINE(HAVE_3ARGS_SHRINKER_CALLBACK, 1,
+				[old shrinker callback wants 3 args])
+		],[
+			AC_MSG_RESULT(no)
+			dnl #
+			dnl # 3.0 - 3.11 API change
+			dnl # ->shrink(struct shrinker *,
+			dnl #          struct shrink_control *sc)
+			dnl #
+			AC_MSG_CHECKING(
+				[whether new 2-argument shrinker exists])
+			SPL_LINUX_TRY_COMPILE([
+				#include <linux/mm.h>
+
+				int shrinker_cb(struct shrinker *,
+						struct shrink_control *sc);
+			],[
+				struct shrinker cache_shrinker = {
+					.shrink = shrinker_cb,
+					.seeks = DEFAULT_SEEKS,
+				};
+				register_shrinker(&cache_shrinker);
+			],[
+				AC_MSG_RESULT(yes)
+				AC_DEFINE(HAVE_2ARGS_NEW_SHRINKER_CALLBACK, 1,
+					[new shrinker callback wants 2 args])
+			],[
+				AC_MSG_RESULT(no)
+				dnl #
+				dnl # 3.12 API change,
+				dnl # ->shrink() is logically split in to
+				dnl # ->count_objects() and ->scan_objects()
+				dnl #
+				AC_MSG_CHECKING(
+				    [whether ->count_objects callback exists])
+				SPL_LINUX_TRY_COMPILE([
+					#include <linux/mm.h>
+
+					unsigned long shrinker_cb(
+						struct shrinker *,
+						struct shrink_control *sc);
+				],[
+					struct shrinker cache_shrinker = {
+						.count_objects = shrinker_cb,
+						.scan_objects = shrinker_cb,
+						.seeks = DEFAULT_SEEKS,
+					};
+					register_shrinker(&cache_shrinker);
+				],[
+					AC_MSG_RESULT(yes)
+					AC_DEFINE(HAVE_SPLIT_SHRINKER_CALLBACK,
+						1, [->count_objects exists])
+				],[
+					AC_MSG_ERROR(error)
+				])
+			])
+		])
+	])
+	EXTRA_KCFLAGS="$tmp_flags"
+])
+
+dnl #
+dnl # 2.6.33 API change,
+dnl # Removed .ctl_name from struct ctl_table.
+dnl #
+AC_DEFUN([SPL_AC_CTL_NAME], [
+	AC_MSG_CHECKING([whether struct ctl_table has ctl_name])
+	SPL_LINUX_TRY_COMPILE([
+		#include <linux/sysctl.h>
+	],[
+		struct ctl_table ctl __attribute__ ((unused));
+		ctl.ctl_name = 0;
+	],[
+		AC_MSG_RESULT(yes)
+		AC_DEFINE(HAVE_CTL_NAME, 1, [struct ctl_table has ctl_name])
+	],[
+		AC_MSG_RESULT(no)
+	])
+])
+
+dnl #
+dnl # 3.10 API change,
+dnl # PDE is replaced by PDE_DATA
+dnl #
+AC_DEFUN([SPL_AC_PDE_DATA], [
+	AC_MSG_CHECKING([whether PDE_DATA() is available])
+	SPL_LINUX_TRY_COMPILE_SYMBOL([
+		#include <linux/proc_fs.h>
+	], [
+		PDE_DATA(NULL);
+	], [PDE_DATA], [], [
+		AC_MSG_RESULT(yes)
+		AC_DEFINE(HAVE_PDE_DATA, 1, [yes])
+	],[
+		AC_MSG_RESULT(no)
+	])
+])
+
+dnl #
+dnl # 3.9 API change
+dnl # set_fs_pwd takes const struct path *
+dnl #
+AC_DEFUN([SPL_AC_SET_FS_PWD_WITH_CONST],
+	tmp_flags="$EXTRA_KCFLAGS"
+	EXTRA_KCFLAGS="-Werror"
+	[AC_MSG_CHECKING([whether set_fs_pwd() requires const struct path *])
+	SPL_LINUX_TRY_COMPILE([
+		#include <linux/spinlock.h>
+		#include <linux/fs_struct.h>
+		#include <linux/path.h>
+		void (*const set_fs_pwd_func)
+			(struct fs_struct *, const struct path *)
+			= set_fs_pwd;
+	],[
+		return 0;
+	],[
+		AC_MSG_RESULT(yes)
+		AC_DEFINE(HAVE_SET_FS_PWD_WITH_CONST, 1,
+			[set_fs_pwd() needs const path *])
+	],[
+		SPL_LINUX_TRY_COMPILE([
+			#include <linux/spinlock.h>
+			#include <linux/fs_struct.h>
+			#include <linux/path.h>
+			void (*const set_fs_pwd_func)
+				(struct fs_struct *, struct path *)
+				= set_fs_pwd;
+		],[
+			return 0;
+		],[
+			AC_MSG_RESULT(no)
+		],[
+			AC_MSG_ERROR(unknown)
+		])
+	])
+	EXTRA_KCFLAGS="$tmp_flags"
+])
+
+dnl #
+dnl # 3.13 API change
+dnl # vfs_unlink() updated to take a third delegated_inode argument.
+dnl #
+AC_DEFUN([SPL_AC_2ARGS_VFS_UNLINK],
+	[AC_MSG_CHECKING([whether vfs_unlink() wants 2 args])
+	SPL_LINUX_TRY_COMPILE([
+		#include <linux/fs.h>
+	],[
+		vfs_unlink((struct inode *) NULL, (struct dentry *) NULL);
+	],[
+		AC_MSG_RESULT(yes)
+		AC_DEFINE(HAVE_2ARGS_VFS_UNLINK, 1,
+		          [vfs_unlink() wants 2 args])
+	],[
+		AC_MSG_RESULT(no)
+		dnl #
+		dnl # Linux 3.13 API change
+		dnl # Added delegated inode
+		dnl #
+		AC_MSG_CHECKING([whether vfs_unlink() wants 3 args])
+		SPL_LINUX_TRY_COMPILE([
+			#include <linux/fs.h>
+		],[
+			vfs_unlink((struct inode *) NULL,
+				(struct dentry *) NULL,
+				(struct inode **) NULL);
+		],[
+			AC_MSG_RESULT(yes)
+			AC_DEFINE(HAVE_3ARGS_VFS_UNLINK, 1,
+				  [vfs_unlink() wants 3 args])
+		],[
+			AC_MSG_ERROR(no)
+		])
+
+	])
+])
+
+dnl #
+dnl # 3.13 and 3.15 API changes
+dnl # Added delegated inode and flags argument.
+dnl #
+AC_DEFUN([SPL_AC_4ARGS_VFS_RENAME],
+	[AC_MSG_CHECKING([whether vfs_rename() wants 4 args])
+	SPL_LINUX_TRY_COMPILE([
+		#include <linux/fs.h>
+	],[
+		vfs_rename((struct inode *) NULL, (struct dentry *) NULL,
+			(struct inode *) NULL, (struct dentry *) NULL);
+	],[
+		AC_MSG_RESULT(yes)
+		AC_DEFINE(HAVE_4ARGS_VFS_RENAME, 1,
+		          [vfs_rename() wants 4 args])
+	],[
+		AC_MSG_RESULT(no)
+		dnl #
+		dnl # Linux 3.13 API change
+		dnl # Added delegated inode
+		dnl #
+		AC_MSG_CHECKING([whether vfs_rename() wants 5 args])
+		SPL_LINUX_TRY_COMPILE([
+			#include <linux/fs.h>
+		],[
+			vfs_rename((struct inode *) NULL,
+				(struct dentry *) NULL,
+				(struct inode *) NULL,
+				(struct dentry *) NULL,
+				(struct inode **) NULL);
+		],[
+			AC_MSG_RESULT(yes)
+			AC_DEFINE(HAVE_5ARGS_VFS_RENAME, 1,
+				  [vfs_rename() wants 5 args])
+		],[
+			AC_MSG_RESULT(no)
+			dnl #
+			dnl # Linux 3.15 API change
+			dnl # Added flags
+			dnl #
+			AC_MSG_CHECKING([whether vfs_rename() wants 6 args])
+			SPL_LINUX_TRY_COMPILE([
+				#include <linux/fs.h>
+			],[
+				vfs_rename((struct inode *) NULL,
+					(struct dentry *) NULL,
+					(struct inode *) NULL,
+					(struct dentry *) NULL,
+					(struct inode **) NULL,
+					(unsigned int) 0);
+			],[
+				AC_MSG_RESULT(yes)
+				AC_DEFINE(HAVE_6ARGS_VFS_RENAME, 1,
+					  [vfs_rename() wants 6 args])
+			],[
+				AC_MSG_ERROR(no)
+			])
+		])
+	])
+])
+
+dnl #
+dnl # 2.6.36 API change,
+dnl # The 'struct fs_struct->lock' was changed from a rwlock_t to
+dnl # a spinlock_t to improve the fastpath performance.
+dnl #
+AC_DEFUN([SPL_AC_FS_STRUCT_SPINLOCK], [
+	AC_MSG_CHECKING([whether struct fs_struct uses spinlock_t])
+	tmp_flags="$EXTRA_KCFLAGS"
+	EXTRA_KCFLAGS="-Werror"
+	SPL_LINUX_TRY_COMPILE([
+		#include <linux/sched.h>
+		#include <linux/fs_struct.h>
+	],[
+		static struct fs_struct fs;
+		spin_lock_init(&fs.lock);
+	],[
+		AC_MSG_RESULT(yes)
+		AC_DEFINE(HAVE_FS_STRUCT_SPINLOCK, 1,
+		          [struct fs_struct uses spinlock_t])
+	],[
+		AC_MSG_RESULT(no)
+	])
+	EXTRA_KCFLAGS="$tmp_flags"
+])
+
+dnl #
+dnl # User namespaces, use kuid_t in place of uid_t
+dnl # where available. Not strictly a user namespaces thing
+dnl # but it should prevent surprises
+dnl #
+AC_DEFUN([SPL_AC_KUIDGID_T], [
+	AC_MSG_CHECKING([whether kuid_t/kgid_t is available])
+	SPL_LINUX_TRY_COMPILE([
+		#include <linux/uidgid.h>
+	], [
+		kuid_t userid = KUIDT_INIT(0);
+		kgid_t groupid = KGIDT_INIT(0);
+	],[
+		SPL_LINUX_TRY_COMPILE([
+			#include <linux/uidgid.h>
+		], [
+			kuid_t userid = 0;
+			kgid_t groupid = 0;
+		],[
+			AC_MSG_RESULT(yes; optional)
+		],[
+			AC_MSG_RESULT(yes; mandatory)
+			AC_DEFINE(HAVE_KUIDGID_T, 1, [kuid_t/kgid_t in use])
+		])
+	],[
+		AC_MSG_RESULT(no)
+	])
+])
+
+dnl #
+dnl # 2.6.39 API change,
+dnl # __put_task_struct() was exported by the mainline kernel.
+dnl #
+AC_DEFUN([SPL_AC_PUT_TASK_STRUCT],
+	[AC_MSG_CHECKING([whether __put_task_struct() is available])
+	SPL_LINUX_TRY_COMPILE_SYMBOL([
+		#include <linux/sched.h>
+	], [
+		__put_task_struct(NULL);
+	], [__put_task_struct], [], [
+		AC_MSG_RESULT(yes)
+		AC_DEFINE(HAVE_PUT_TASK_STRUCT, 1,
+		          [__put_task_struct() is available])
+	], [
+		AC_MSG_RESULT(no)
+	])
+])
+
+dnl #
+dnl # 2.6.35 API change,
+dnl # Unused 'struct dentry *' removed from vfs_fsync() prototype.
+dnl #
+AC_DEFUN([SPL_AC_2ARGS_VFS_FSYNC], [
+	AC_MSG_CHECKING([whether vfs_fsync() wants 2 args])
+	SPL_LINUX_TRY_COMPILE([
+		#include <linux/fs.h>
+	],[
+		vfs_fsync(NULL, 0);
+	],[
+		AC_MSG_RESULT(yes)
+		AC_DEFINE(HAVE_2ARGS_VFS_FSYNC, 1, [vfs_fsync() wants 2 args])
+	],[
+		AC_MSG_RESULT(no)
+	])
+])
+
+dnl #
+dnl # 3.5 API change,
+dnl # inode_operations.truncate_range removed
+dnl #
+AC_DEFUN([SPL_AC_INODE_TRUNCATE_RANGE], [
+	AC_MSG_CHECKING([whether truncate_range() inode operation is available])
+	SPL_LINUX_TRY_COMPILE([
+		#include <linux/fs.h>
+	],[
+		struct inode_operations ops;
+		ops.truncate_range = NULL;
+	],[
+		AC_MSG_RESULT(yes)
+		AC_DEFINE(HAVE_INODE_TRUNCATE_RANGE, 1,
+			[truncate_range() inode operation is available])
+	],[
+		AC_MSG_RESULT(no)
+	])
+])
+
+dnl #
+dnl # Linux 2.6.38 - 3.x API
+dnl #
+AC_DEFUN([SPL_AC_KERNEL_FILE_FALLOCATE], [
+	AC_MSG_CHECKING([whether fops->fallocate() exists])
+	SPL_LINUX_TRY_COMPILE([
+		#include <linux/fs.h>
+	],[
+		long (*fallocate) (struct file *, int, loff_t, loff_t) = NULL;
+		struct file_operations fops __attribute__ ((unused)) = {
+			.fallocate = fallocate,
+		};
+	],[
+		AC_MSG_RESULT(yes)
+		AC_DEFINE(HAVE_FILE_FALLOCATE, 1, [fops->fallocate() exists])
+	],[
+		AC_MSG_RESULT(no)
+	])
+])
+
+dnl #
+dnl # Linux 2.6.x - 2.6.37 API
+dnl #
+AC_DEFUN([SPL_AC_KERNEL_INODE_FALLOCATE], [
+	AC_MSG_CHECKING([whether iops->fallocate() exists])
+	SPL_LINUX_TRY_COMPILE([
+		#include <linux/fs.h>
+	],[
+		long (*fallocate) (struct inode *, int, loff_t, loff_t) = NULL;
+		struct inode_operations fops __attribute__ ((unused)) = {
+			.fallocate = fallocate,
+		};
+	],[
+		AC_MSG_RESULT(yes)
+		AC_DEFINE(HAVE_INODE_FALLOCATE, 1, [fops->fallocate() exists])
+	],[
+		AC_MSG_RESULT(no)
+	])
+])
+
+dnl #
+dnl # PaX Linux 2.6.38 - 3.x API
+dnl #
+AC_DEFUN([SPL_AC_PAX_KERNEL_FILE_FALLOCATE], [
+	AC_MSG_CHECKING([whether fops->fallocate() exists])
+	SPL_LINUX_TRY_COMPILE([
+		#include <linux/fs.h>
+	],[
+		long (*fallocate) (struct file *, int, loff_t, loff_t) = NULL;
+		struct file_operations_no_const fops __attribute__ ((unused)) = {
+			.fallocate = fallocate,
+		};
+	],[
+		AC_MSG_RESULT(yes)
+		AC_DEFINE(HAVE_FILE_FALLOCATE, 1, [fops->fallocate() exists])
+	],[
+		AC_MSG_RESULT(no)
+	])
+])
+
+dnl #
+dnl # The fallocate callback was moved from the inode_operations
+dnl # structure to the file_operations structure.
+dnl #
+AC_DEFUN([SPL_AC_KERNEL_FALLOCATE], [
+	SPL_AC_KERNEL_FILE_FALLOCATE
+	SPL_AC_KERNEL_INODE_FALLOCATE
+	SPL_AC_PAX_KERNEL_FILE_FALLOCATE
+])
+
+dnl #
+dnl # zlib inflate compat,
+dnl # Verify the kernel has CONFIG_ZLIB_INFLATE support enabled.
+dnl #
+AC_DEFUN([SPL_AC_CONFIG_ZLIB_INFLATE], [
+	AC_MSG_CHECKING([whether CONFIG_ZLIB_INFLATE is defined])
+	SPL_LINUX_TRY_COMPILE([
+		#if !defined(CONFIG_ZLIB_INFLATE) && \
+		    !defined(CONFIG_ZLIB_INFLATE_MODULE)
+		#error CONFIG_ZLIB_INFLATE not defined
+		#endif
+	],[ ],[
+		AC_MSG_RESULT([yes])
+	],[
+		AC_MSG_RESULT([no])
+		AC_MSG_ERROR([
+	*** This kernel does not include the required zlib inflate support.
+	*** Rebuild the kernel with CONFIG_ZLIB_INFLATE=y|m set.])
+	])
+])
+
+dnl #
+dnl # zlib deflate compat,
+dnl # Verify the kernel has CONFIG_ZLIB_DEFLATE support enabled.
+dnl #
+AC_DEFUN([SPL_AC_CONFIG_ZLIB_DEFLATE], [
+	AC_MSG_CHECKING([whether CONFIG_ZLIB_DEFLATE is defined])
+	SPL_LINUX_TRY_COMPILE([
+		#if !defined(CONFIG_ZLIB_DEFLATE) && \
+		    !defined(CONFIG_ZLIB_DEFLATE_MODULE)
+		#error CONFIG_ZLIB_DEFLATE not defined
+		#endif
+	],[ ],[
+		AC_MSG_RESULT([yes])
+	],[
+		AC_MSG_RESULT([no])
+		AC_MSG_ERROR([
+	*** This kernel does not include the required zlib deflate support.
+	*** Rebuild the kernel with CONFIG_ZLIB_DEFLATE=y|m set.])
+	])
+])
+
+dnl #
+dnl # 2.6.39 API compat,
+dnl # The function zlib_deflate_workspacesize() now take 2 arguments.
+dnl # This was done to avoid always having to allocate the maximum size
+dnl # workspace (268K).  The caller can now specific the windowBits and
+dnl # memLevel compression parameters to get a smaller workspace.
+dnl #
+AC_DEFUN([SPL_AC_2ARGS_ZLIB_DEFLATE_WORKSPACESIZE],
+	[AC_MSG_CHECKING([whether zlib_deflate_workspacesize() wants 2 args])
+	SPL_LINUX_TRY_COMPILE([
+		#include <linux/zlib.h>
+	],[
+		return zlib_deflate_workspacesize(MAX_WBITS, MAX_MEM_LEVEL);
+	],[
+		AC_MSG_RESULT(yes)
+		AC_DEFINE(HAVE_2ARGS_ZLIB_DEFLATE_WORKSPACESIZE, 1,
+		          [zlib_deflate_workspacesize() wants 2 args])
+	],[
+		AC_MSG_RESULT(no)
+	])
+])
+
+dnl #
+dnl # 2.6.39 API change,
+dnl # Shrinker adjust to use common shrink_control structure.
+dnl #
+AC_DEFUN([SPL_AC_SHRINK_CONTROL_STRUCT], [
+	AC_MSG_CHECKING([whether struct shrink_control exists])
+	SPL_LINUX_TRY_COMPILE([
+		#include <linux/mm.h>
+	],[
+		struct shrink_control sc __attribute__ ((unused));
+
+		sc.nr_to_scan = 0;
+		sc.gfp_mask = GFP_KERNEL;
+	],[
+		AC_MSG_RESULT(yes)
+		AC_DEFINE(HAVE_SHRINK_CONTROL_STRUCT, 1,
+			[struct shrink_control exists])
+	],[
+		AC_MSG_RESULT(no)
+	])
+])
+
+dnl #
+dnl # 3.1 API Change
+dnl #
+dnl # The rw_semaphore.wait_lock member was changed from spinlock_t to
+dnl # raw_spinlock_t at commit ddb6c9b58a19edcfac93ac670b066c836ff729f1.
+dnl #
+AC_DEFUN([SPL_AC_RWSEM_SPINLOCK_IS_RAW], [
+	AC_MSG_CHECKING([whether struct rw_semaphore member wait_lock is raw])
+	tmp_flags="$EXTRA_KCFLAGS"
+	EXTRA_KCFLAGS="-Werror"
+	SPL_LINUX_TRY_COMPILE([
+		#include <linux/rwsem.h>
+	],[
+		struct rw_semaphore dummy_semaphore __attribute__ ((unused));
+		raw_spinlock_t dummy_lock __attribute__ ((unused));
+		dummy_semaphore.wait_lock = dummy_lock;
+	],[
+		AC_MSG_RESULT(yes)
+		AC_DEFINE(RWSEM_SPINLOCK_IS_RAW, 1,
+		[struct rw_semaphore member wait_lock is raw_spinlock_t])
+	],[
+		AC_MSG_RESULT(no)
+	])
+	EXTRA_KCFLAGS="$tmp_flags"
+])
+
+dnl #
+dnl # 3.9 API change,
+dnl # Moved things from linux/sched.h to linux/sched/rt.h
+dnl #
+AC_DEFUN([SPL_AC_SCHED_RT_HEADER],
+	[AC_MSG_CHECKING([whether header linux/sched/rt.h exists])
+	SPL_LINUX_TRY_COMPILE([
+		#include <linux/sched.h>
+		#include <linux/sched/rt.h>
+	],[
+		return 0;
+	],[
+		AC_DEFINE(HAVE_SCHED_RT_HEADER, 1, [linux/sched/rt.h exists])
+		AC_MSG_RESULT(yes)
+	],[
+		AC_MSG_RESULT(no)
+	])
+])
+
+dnl #
+dnl # 3.9 API change,
+dnl # vfs_getattr() uses 2 args
+dnl # It takes struct path * instead of struct vfsmount * and struct dentry *
+dnl #
+AC_DEFUN([SPL_AC_2ARGS_VFS_GETATTR], [
+	AC_MSG_CHECKING([whether vfs_getattr() wants])
+	SPL_LINUX_TRY_COMPILE([
+		#include <linux/fs.h>
+	],[
+		vfs_getattr((struct path *) NULL,
+			(struct kstat *)NULL);
+	],[
+		AC_MSG_RESULT(2 args)
+		AC_DEFINE(HAVE_2ARGS_VFS_GETATTR, 1,
+		          [vfs_getattr wants 2 args])
+	],[
+		SPL_LINUX_TRY_COMPILE([
+			#include <linux/fs.h>
+		],[
+			vfs_getattr((struct vfsmount *)NULL,
+				(struct dentry *)NULL,
+				(struct kstat *)NULL);
+		],[
+			AC_MSG_RESULT(3 args)
+		],[
+			AC_MSG_ERROR(unknown)
+		])
+	])
+])
+
+dnl #
+dnl # 2.6.36 API compatibility.
+dnl # Added usleep_range timer.
+dnl # usleep_range is a finer precision implementation of msleep
+dnl # designed to be a drop-in replacement for udelay where a precise
+dnl # sleep / busy-wait is unnecessary.
+dnl #
+AC_DEFUN([SPL_AC_USLEEP_RANGE], [
+	AC_MSG_CHECKING([whether usleep_range() is available])
+	SPL_LINUX_TRY_COMPILE([
+		#include <linux/delay.h>
+	],[
+		usleep_range(0, 0);
+	],[
+		AC_MSG_RESULT(yes)
+		AC_DEFINE(HAVE_USLEEP_RANGE, 1,
+		          [usleep_range is available])
+	],[
+		AC_MSG_RESULT(no)
+	])
+])
+
+dnl #
+dnl # 2.6.35 API change,
+dnl # The cachep->gfpflags member was renamed cachep->allocflags.  These are
+dnl # private allocation flags which are applied when allocating a new slab
+dnl # in kmem_getpages().  Unfortunately there is no public API for setting
+dnl # non-default flags.
+dnl #
+AC_DEFUN([SPL_AC_KMEM_CACHE_ALLOCFLAGS], [
+	AC_MSG_CHECKING([whether struct kmem_cache has allocflags])
+	SPL_LINUX_TRY_COMPILE([
+		#include <linux/slab.h>
+	],[
+		struct kmem_cache cachep __attribute__ ((unused));
+		cachep.allocflags = GFP_KERNEL;
+	],[
+		AC_MSG_RESULT(yes)
+		AC_DEFINE(HAVE_KMEM_CACHE_ALLOCFLAGS, 1,
+			[struct kmem_cache has allocflags])
+	],[
+		AC_MSG_RESULT(no)
+
+		AC_MSG_CHECKING([whether struct kmem_cache has gfpflags])
+		SPL_LINUX_TRY_COMPILE([
+			#include <linux/slab.h>
+		],[
+			struct kmem_cache cachep __attribute__ ((unused));
+			cachep.gfpflags = GFP_KERNEL;
+		],[
+			AC_MSG_RESULT(yes)
+			AC_DEFINE(HAVE_KMEM_CACHE_GFPFLAGS, 1,
+				[struct kmem_cache has gfpflags])
+		],[
+			AC_MSG_RESULT(no)
+		])
+	])
+])
+
+dnl #
+dnl # 3.17 API change,
+dnl # wait_on_bit() no longer requires an action argument. The former
+dnl # "wait_on_bit" interface required an 'action' function to be provided
+dnl # which does the actual waiting. There were over 20 such functions in the
+dnl # kernel, many of them identical, though most cases can be satisfied by one
+dnl # of just two functions: one which uses io_schedule() and one which just
+dnl # uses schedule().  This API change was made to consolidate all of those
+dnl # redundant wait functions.
+dnl #
+AC_DEFUN([SPL_AC_WAIT_ON_BIT], [
+	AC_MSG_CHECKING([whether wait_on_bit() takes an action])
+	SPL_LINUX_TRY_COMPILE([
+		#include <linux/wait.h>
+	],[
+		int (*action)(void *) = NULL;
+		wait_on_bit(NULL, 0, action, 0);
+	],[
+		AC_MSG_RESULT(yes)
+		AC_DEFINE(HAVE_WAIT_ON_BIT_ACTION, 1, [yes])
+	],[
+		AC_MSG_RESULT(no)
+	])
+])
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/config/spl-meta.m4
@@ -0,0 +1,162 @@
+dnl #
+dnl # DESCRIPTION:
+dnl # Read meta data from the META file.  When building from a git repository
+dnl # the SPL_META_RELEASE field will be overwritten if there is an annotated
+dnl # tag matching the form SPL_META_NAME-SPL_META_VERSION-*.  This allows
+dnl # for working builds to be uniquely identified using the git commit hash.
+dnl #
+dnl #    The META file format is as follows:
+dnl #      ^[ ]*KEY:[ \t]+VALUE$
+dnl #
+dnl #    In other words:
+dnl #    - KEY is separated from VALUE by a colon and one or more spaces/tabs.
+dnl #    - KEY and VALUE are case sensitive.
+dnl #    - Leading spaces are ignored.
+dnl #    - First match wins for duplicate keys.
+dnl #
+dnl #    A line can be commented out by preceding it with a '#' (or technically
+dnl #    any non-space character since that will prevent the regex from
+dnl #    matching).
+dnl #
+dnl # WARNING:
+dnl #   Placing a colon followed by a space or tab (ie, ":[ \t]+") within the
+dnl #   VALUE will prematurely terminate the string since that sequence is
+dnl #   used as the awk field separator.
+dnl #
+dnl # KEYS:
+dnl #   The following META keys are recognized:
+dnl #     Name, Version, Release, Date, Author, LT_Current, LT_Revision, LT_Age
+dnl #
+dnl # Written by Chris Dunlap <cdunlap@llnl.gov>.
+dnl # Modified by Brian Behlendorf <behlendorf1@llnl.gov>.
+dnl #
+AC_DEFUN([SPL_AC_META], [
+	AC_PROG_AWK
+	AC_MSG_CHECKING([metadata])
+
+	META="$srcdir/META"
+	_spl_ac_meta_type="none"
+	if test -f "$META"; then
+		_spl_ac_meta_type="META file"
+
+		SPL_META_NAME=_SPL_AC_META_GETVAL([(Name|Project|Package)]);
+		if test -n "$SPL_META_NAME"; then
+			AC_DEFINE_UNQUOTED([SPL_META_NAME], ["$SPL_META_NAME"],
+				[Define the project name.]
+			)
+			AC_SUBST([SPL_META_NAME])
+		fi
+
+		SPL_META_VERSION=_SPL_AC_META_GETVAL([Version]);
+		if test -n "$SPL_META_VERSION"; then
+			AC_DEFINE_UNQUOTED([SPL_META_VERSION], ["$SPL_META_VERSION"],
+				[Define the project version.]
+			)
+			AC_SUBST([SPL_META_VERSION])
+		fi
+
+		SPL_META_RELEASE=_SPL_AC_META_GETVAL([Release]);
+		if test ! -f ".nogitrelease" && git rev-parse --git-dir > /dev/null 2>&1; then
+			_match="${SPL_META_NAME}-${SPL_META_VERSION}"
+			_alias=$(git describe --match=${_match} 2>/dev/null)
+			_release=$(echo ${_alias}|cut -f3- -d'-'|sed 's/-/_/g')
+			if test -n "${_release}"; then
+				SPL_META_RELEASE=${_release}
+				_spl_ac_meta_type="git describe"
+			fi
+		fi
+
+		if test -n "$SPL_META_RELEASE"; then
+			AC_DEFINE_UNQUOTED([SPL_META_RELEASE], ["$SPL_META_RELEASE"],
+				[Define the project release.]
+			)
+			AC_SUBST([SPL_META_RELEASE])
+
+			RELEASE="$SPL_META_RELEASE"
+			AC_SUBST([RELEASE])
+		fi
+
+		SPL_META_LICENSE=_SPL_AC_META_GETVAL([License]);
+		if test -n "$SPL_META_LICENSE"; then
+			AC_DEFINE_UNQUOTED([SPL_META_LICENSE], ["$SPL_META_LICENSE"],
+				[Define the project license.]
+			)
+			AC_SUBST([SPL_META_LICENSE])
+		fi
+
+		if test -n "$SPL_META_NAME" -a -n "$SPL_META_VERSION"; then
+				SPL_META_ALIAS="$SPL_META_NAME-$SPL_META_VERSION"
+				test -n "$SPL_META_RELEASE" && 
+				        SPL_META_ALIAS="$SPL_META_ALIAS-$SPL_META_RELEASE"
+				AC_DEFINE_UNQUOTED([SPL_META_ALIAS],
+					["$SPL_META_ALIAS"],
+					[Define the project alias string.] 
+				)
+				AC_SUBST([SPL_META_ALIAS])
+		fi
+
+		SPL_META_DATA=_SPL_AC_META_GETVAL([Date]);
+		if test -n "$SPL_META_DATA"; then
+			AC_DEFINE_UNQUOTED([SPL_META_DATA], ["$SPL_META_DATA"],
+				[Define the project release date.] 
+			)
+			AC_SUBST([SPL_META_DATA])
+		fi
+
+		SPL_META_AUTHOR=_SPL_AC_META_GETVAL([Author]);
+		if test -n "$SPL_META_AUTHOR"; then
+			AC_DEFINE_UNQUOTED([SPL_META_AUTHOR], ["$SPL_META_AUTHOR"],
+				[Define the project author.]
+			)
+			AC_SUBST([SPL_META_AUTHOR])
+		fi
+
+		m4_pattern_allow([^LT_(CURRENT|REVISION|AGE)$])
+		SPL_META_LT_CURRENT=_SPL_AC_META_GETVAL([LT_Current]);
+		SPL_META_LT_REVISION=_SPL_AC_META_GETVAL([LT_Revision]);
+		SPL_META_LT_AGE=_SPL_AC_META_GETVAL([LT_Age]);
+		if test -n "$SPL_META_LT_CURRENT" \
+				 -o -n "$SPL_META_LT_REVISION" \
+				 -o -n "$SPL_META_LT_AGE"; then
+			test -n "$SPL_META_LT_CURRENT" || SPL_META_LT_CURRENT="0"
+			test -n "$SPL_META_LT_REVISION" || SPL_META_LT_REVISION="0"
+			test -n "$SPL_META_LT_AGE" || SPL_META_LT_AGE="0"
+			AC_DEFINE_UNQUOTED([SPL_META_LT_CURRENT],
+				["$SPL_META_LT_CURRENT"],
+				[Define the libtool library 'current'
+				 version information.]
+			)
+			AC_DEFINE_UNQUOTED([SPL_META_LT_REVISION],
+				["$SPL_META_LT_REVISION"],
+				[Define the libtool library 'revision'
+				 version information.]
+			)
+			AC_DEFINE_UNQUOTED([SPL_META_LT_AGE], ["$SPL_META_LT_AGE"],
+				[Define the libtool library 'age' 
+				 version information.]
+			)
+			AC_SUBST([SPL_META_LT_CURRENT])
+			AC_SUBST([SPL_META_LT_REVISION])
+			AC_SUBST([SPL_META_LT_AGE])
+		fi
+	fi
+
+	AC_MSG_RESULT([$_spl_ac_meta_type])
+	]
+)
+
+dnl # _SPL_AC_META_GETVAL (KEY_NAME_OR_REGEX)
+dnl #
+dnl # Returns the META VALUE associated with the given KEY_NAME_OR_REGEX expr.
+dnl #
+dnl # Despite their resemblance to line noise,
+dnl #   the "@<:@" and "@:>@" constructs are quadrigraphs for "[" and "]".
+dnl #   <www.gnu.org/software/autoconf/manual/autoconf.html#Quadrigraphs>
+dnl #
+dnl # The "$[]1" and "$[]2" constructs prevent M4 parameter expansion
+dnl #   so a literal $1 and $2 will be passed to the resulting awk script,
+dnl #   whereas the "$1" will undergo M4 parameter expansion for the META key.
+dnl #
+AC_DEFUN([_SPL_AC_META_GETVAL],
+	[`$AWK -F ':@<:@ \t@:>@+' '$[]1 ~ /^ *$1$/ { print $[]2; exit }' $META`]dnl
+)
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/config/tgz.am
@@ -0,0 +1,44 @@
+###############################################################################
+# Copyright (C) 2010 Lawrence Livermore National Security, LLC.
+# Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+###############################################################################
+# Build targets for TGZ packages.
+#
+# Long term native distro specific Slackware style packaging should be added.
+# In the short term RPM packages are built and converted to TGZ packages
+# using alien.  If someone familiar with Slackware style packaging were to
+# update the build system to correctly build Slackware style packages I would
+# happily take it.  Until then we will have to make due with alien.
+#
+###############################################################################
+
+tgz-local:
+	@(if test "${HAVE_ALIEN}" = "no"; then \
+		echo -e "\n" \
+	"*** Required util ${ALIEN} missing.  Please install the\n" \
+        "*** package for your distribution which provides ${ALIEN},\n" \
+	"*** re-run configure, and try again.\n"; \
+                exit 1; \
+	fi)
+
+tgz-kmod: tgz-local rpm-kmod
+if CONFIG_KERNEL
+	name=${PACKAGE}; \
+	version=${VERSION}-${RELEASE}; \
+	arch=`$(RPM) -qp $${name}-kmod-$${version}.src.rpm --qf %{arch} | tail -1`; \
+	pkg1=kmod-$${name}*$${version}.$${arch}.rpm; \
+	fakeroot $(ALIEN) --scripts --to-tgz $$pkg1; \
+	$(RM) $$pkg1
+endif
+
+tgz-utils: tgz-local rpm-utils
+if CONFIG_USER
+	name=${PACKAGE}; \
+	version=${VERSION}-${RELEASE}; \
+	arch=`$(RPM) -qp $${name}-$${version}.src.rpm --qf %{arch} | tail -1`; \
+	pkg1=$${name}-$${version}.$${arch}.rpm; \
+	fakeroot $(ALIEN) --scripts --to-tgz $$pkg1; \
+	$(RM) $$pkg1
+endif
+
+tgz: tgz-kmod tgz-utils
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/configure
@@ -0,0 +1,19893 @@
+#! /bin/sh
+# Guess values for system-dependent variables and create Makefiles.
+# Generated by GNU Autoconf 2.69 for spl 0.6.5.6.
+#
+#
+# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
+#
+#
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+## -------------------- ##
+## M4sh Initialization. ##
+## -------------------- ##
+
+# Be more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
+  emulate sh
+  NULLCMD=:
+  # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+  setopt NO_GLOB_SUBST
+else
+  case `(set -o) 2>/dev/null` in #(
+  *posix*) :
+    set -o posix ;; #(
+  *) :
+     ;;
+esac
+fi
+
+
+as_nl='
+'
+export as_nl
+# Printing a long string crashes Solaris 7 /usr/bin/printf.
+as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
+# Prefer a ksh shell builtin over an external printf program on Solaris,
+# but without wasting forks for bash or zsh.
+if test -z "$BASH_VERSION$ZSH_VERSION" \
+    && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
+  as_echo='print -r --'
+  as_echo_n='print -rn --'
+elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
+  as_echo='printf %s\n'
+  as_echo_n='printf %s'
+else
+  if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
+    as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
+    as_echo_n='/usr/ucb/echo -n'
+  else
+    as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
+    as_echo_n_body='eval
+      arg=$1;
+      case $arg in #(
+      *"$as_nl"*)
+	expr "X$arg" : "X\\(.*\\)$as_nl";
+	arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
+      esac;
+      expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
+    '
+    export as_echo_n_body
+    as_echo_n='sh -c $as_echo_n_body as_echo'
+  fi
+  export as_echo_body
+  as_echo='sh -c $as_echo_body as_echo'
+fi
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  PATH_SEPARATOR=:
+  (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+    (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+      PATH_SEPARATOR=';'
+  }
+fi
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.  Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+IFS=" ""	$as_nl"
+
+# Find who we are.  Look in the path if we contain no directory separator.
+as_myself=
+case $0 in #((
+  *[\\/]* ) as_myself=$0 ;;
+  *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+  done
+IFS=$as_save_IFS
+
+     ;;
+esac
+# We did not find ourselves, most probably we were run as `sh COMMAND'
+# in which case we are not to be found in the path.
+if test "x$as_myself" = x; then
+  as_myself=$0
+fi
+if test ! -f "$as_myself"; then
+  $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+  exit 1
+fi
+
+# Unset variables that we do not need and which cause bugs (e.g. in
+# pre-3.0 UWIN ksh).  But do not cause bugs in bash 2.01; the "|| exit 1"
+# suppresses any "Segmentation fault" message there.  '((' could
+# trigger a bug in pdksh 5.2.14.
+for as_var in BASH_ENV ENV MAIL MAILPATH
+do eval test x\${$as_var+set} = xset \
+  && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
+done
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# CDPATH.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+# Use a proper internal environment variable to ensure we don't fall
+  # into an infinite loop, continuously re-executing ourselves.
+  if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then
+    _as_can_reexec=no; export _as_can_reexec;
+    # We cannot yet assume a decent shell, so we have to provide a
+# neutralization value for shells without unset; and this also
+# works around shells that cannot unset nonexistent variables.
+# Preserve -v and -x to the replacement shell.
+BASH_ENV=/dev/null
+ENV=/dev/null
+(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+case $- in # ((((
+  *v*x* | *x*v* ) as_opts=-vx ;;
+  *v* ) as_opts=-v ;;
+  *x* ) as_opts=-x ;;
+  * ) as_opts= ;;
+esac
+exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
+# Admittedly, this is quite paranoid, since all the known shells bail
+# out after a failed `exec'.
+$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
+as_fn_exit 255
+  fi
+  # We don't want this to propagate to other subprocesses.
+          { _as_can_reexec=; unset _as_can_reexec;}
+if test "x$CONFIG_SHELL" = x; then
+  as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then :
+  emulate sh
+  NULLCMD=:
+  # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '\${1+\"\$@\"}'='\"\$@\"'
+  setopt NO_GLOB_SUBST
+else
+  case \`(set -o) 2>/dev/null\` in #(
+  *posix*) :
+    set -o posix ;; #(
+  *) :
+     ;;
+esac
+fi
+"
+  as_required="as_fn_return () { (exit \$1); }
+as_fn_success () { as_fn_return 0; }
+as_fn_failure () { as_fn_return 1; }
+as_fn_ret_success () { return 0; }
+as_fn_ret_failure () { return 1; }
+
+exitcode=0
+as_fn_success || { exitcode=1; echo as_fn_success failed.; }
+as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; }
+as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; }
+as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; }
+if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then :
+
+else
+  exitcode=1; echo positional parameters were not saved.
+fi
+test x\$exitcode = x0 || exit 1
+test -x / || exit 1"
+  as_suggested="  as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO
+  as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO
+  eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" &&
+  test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1
+
+  test -n \"\${ZSH_VERSION+set}\${BASH_VERSION+set}\" || (
+    ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+    ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO
+    ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO
+    PATH=/empty FPATH=/empty; export PATH FPATH
+    test \"X\`printf %s \$ECHO\`\" = \"X\$ECHO\" \\
+      || test \"X\`print -r -- \$ECHO\`\" = \"X\$ECHO\" ) || exit 1
+test \$(( 1 + 1 )) = 2 || exit 1"
+  if (eval "$as_required") 2>/dev/null; then :
+  as_have_required=yes
+else
+  as_have_required=no
+fi
+  if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then :
+
+else
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+as_found=false
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  as_found=:
+  case $as_dir in #(
+	 /*)
+	   for as_base in sh bash ksh sh5; do
+	     # Try only shells that exist, to save several forks.
+	     as_shell=$as_dir/$as_base
+	     if { test -f "$as_shell" || test -f "$as_shell.exe"; } &&
+		    { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then :
+  CONFIG_SHELL=$as_shell as_have_required=yes
+		   if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then :
+  break 2
+fi
+fi
+	   done;;
+       esac
+  as_found=false
+done
+$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } &&
+	      { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then :
+  CONFIG_SHELL=$SHELL as_have_required=yes
+fi; }
+IFS=$as_save_IFS
+
+
+      if test "x$CONFIG_SHELL" != x; then :
+  export CONFIG_SHELL
+             # We cannot yet assume a decent shell, so we have to provide a
+# neutralization value for shells without unset; and this also
+# works around shells that cannot unset nonexistent variables.
+# Preserve -v and -x to the replacement shell.
+BASH_ENV=/dev/null
+ENV=/dev/null
+(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+case $- in # ((((
+  *v*x* | *x*v* ) as_opts=-vx ;;
+  *v* ) as_opts=-v ;;
+  *x* ) as_opts=-x ;;
+  * ) as_opts= ;;
+esac
+exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
+# Admittedly, this is quite paranoid, since all the known shells bail
+# out after a failed `exec'.
+$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
+exit 255
+fi
+
+    if test x$as_have_required = xno; then :
+  $as_echo "$0: This script requires a shell more modern than all"
+  $as_echo "$0: the shells that I found on your system."
+  if test x${ZSH_VERSION+set} = xset ; then
+    $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should"
+    $as_echo "$0: be upgraded to zsh 4.3.4 or later."
+  else
+    $as_echo "$0: Please tell bug-autoconf@gnu.org about your system,
+$0: including any error possibly output before this
+$0: message. Then install a modern shell, or manually run
+$0: the script under such a shell if you do have one."
+  fi
+  exit 1
+fi
+fi
+fi
+SHELL=${CONFIG_SHELL-/bin/sh}
+export SHELL
+# Unset more variables known to interfere with behavior of common tools.
+CLICOLOR_FORCE= GREP_OPTIONS=
+unset CLICOLOR_FORCE GREP_OPTIONS
+
+## --------------------- ##
+## M4sh Shell Functions. ##
+## --------------------- ##
+# as_fn_unset VAR
+# ---------------
+# Portably unset VAR.
+as_fn_unset ()
+{
+  { eval $1=; unset $1;}
+}
+as_unset=as_fn_unset
+
+# as_fn_set_status STATUS
+# -----------------------
+# Set $? to STATUS, without forking.
+as_fn_set_status ()
+{
+  return $1
+} # as_fn_set_status
+
+# as_fn_exit STATUS
+# -----------------
+# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
+as_fn_exit ()
+{
+  set +e
+  as_fn_set_status $1
+  exit $1
+} # as_fn_exit
+
+# as_fn_mkdir_p
+# -------------
+# Create "$as_dir" as a directory, including parents if necessary.
+as_fn_mkdir_p ()
+{
+
+  case $as_dir in #(
+  -*) as_dir=./$as_dir;;
+  esac
+  test -d "$as_dir" || eval $as_mkdir_p || {
+    as_dirs=
+    while :; do
+      case $as_dir in #(
+      *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+      *) as_qdir=$as_dir;;
+      esac
+      as_dirs="'$as_qdir' $as_dirs"
+      as_dir=`$as_dirname -- "$as_dir" ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$as_dir" : 'X\(//\)[^/]' \| \
+	 X"$as_dir" : 'X\(//\)$' \| \
+	 X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_dir" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+      test -d "$as_dir" && break
+    done
+    test -z "$as_dirs" || eval "mkdir $as_dirs"
+  } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"
+
+
+} # as_fn_mkdir_p
+
+# as_fn_executable_p FILE
+# -----------------------
+# Test if FILE is an executable regular file.
+as_fn_executable_p ()
+{
+  test -f "$1" && test -x "$1"
+} # as_fn_executable_p
+# as_fn_append VAR VALUE
+# ----------------------
+# Append the text in VALUE to the end of the definition contained in VAR. Take
+# advantage of any shell optimizations that allow amortized linear growth over
+# repeated appends, instead of the typical quadratic growth present in naive
+# implementations.
+if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
+  eval 'as_fn_append ()
+  {
+    eval $1+=\$2
+  }'
+else
+  as_fn_append ()
+  {
+    eval $1=\$$1\$2
+  }
+fi # as_fn_append
+
+# as_fn_arith ARG...
+# ------------------
+# Perform arithmetic evaluation on the ARGs, and store the result in the
+# global $as_val. Take advantage of shells that can avoid forks. The arguments
+# must be portable across $(()) and expr.
+if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
+  eval 'as_fn_arith ()
+  {
+    as_val=$(( $* ))
+  }'
+else
+  as_fn_arith ()
+  {
+    as_val=`expr "$@" || test $? -eq 1`
+  }
+fi # as_fn_arith
+
+
+# as_fn_error STATUS ERROR [LINENO LOG_FD]
+# ----------------------------------------
+# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
+# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
+# script with STATUS, using 1 if that was 0.
+as_fn_error ()
+{
+  as_status=$1; test $as_status -eq 0 && as_status=1
+  if test "$4"; then
+    as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+    $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
+  fi
+  $as_echo "$as_me: error: $2" >&2
+  as_fn_exit $as_status
+} # as_fn_error
+
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+   test "X`expr 00001 : '.*\(...\)'`" = X001; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
+  as_basename=basename
+else
+  as_basename=false
+fi
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+  as_dirname=dirname
+else
+  as_dirname=false
+fi
+
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+	 X"$0" : 'X\(//\)$' \| \
+	 X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X/"$0" |
+    sed '/^.*\/\([^/][^/]*\)\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\/\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\/\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+
+  as_lineno_1=$LINENO as_lineno_1a=$LINENO
+  as_lineno_2=$LINENO as_lineno_2a=$LINENO
+  eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" &&
+  test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || {
+  # Blame Lee E. McMahon (1931-1989) for sed's syntax.  :-)
+  sed -n '
+    p
+    /[$]LINENO/=
+  ' <$as_myself |
+    sed '
+      s/[$]LINENO.*/&-/
+      t lineno
+      b
+      :lineno
+      N
+      :loop
+      s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
+      t loop
+      s/-\n.*//
+    ' >$as_me.lineno &&
+  chmod +x "$as_me.lineno" ||
+    { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; }
+
+  # If we had to re-execute with $CONFIG_SHELL, we're ensured to have
+  # already done that, so ensure we don't try to do so again and fall
+  # in an infinite loop.  This has already happened in practice.
+  _as_can_reexec=no; export _as_can_reexec
+  # Don't try to exec as it changes $[0], causing all sort of problems
+  # (the dirname of $[0] is not the place where we might find the
+  # original and so on.  Autoconf is especially sensitive to this).
+  . "./$as_me.lineno"
+  # Exit status is that of the last command.
+  exit
+}
+
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in #(((((
+-n*)
+  case `echo 'xy\c'` in
+  *c*) ECHO_T='	';;	# ECHO_T is single tab character.
+  xy)  ECHO_C='\c';;
+  *)   echo `echo ksh88 bug on AIX 6.1` > /dev/null
+       ECHO_T='	';;
+  esac;;
+*)
+  ECHO_N='-n';;
+esac
+
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+  rm -f conf$$.dir/conf$$.file
+else
+  rm -f conf$$.dir
+  mkdir conf$$.dir 2>/dev/null
+fi
+if (echo >conf$$.file) 2>/dev/null; then
+  if ln -s conf$$.file conf$$ 2>/dev/null; then
+    as_ln_s='ln -s'
+    # ... but there are two gotchas:
+    # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+    # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+    # In both cases, we have to default to `cp -pR'.
+    ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+      as_ln_s='cp -pR'
+  elif ln conf$$.file conf$$ 2>/dev/null; then
+    as_ln_s=ln
+  else
+    as_ln_s='cp -pR'
+  fi
+else
+  as_ln_s='cp -pR'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+if mkdir -p . 2>/dev/null; then
+  as_mkdir_p='mkdir -p "$as_dir"'
+else
+  test -d ./-p && rmdir ./-p
+  as_mkdir_p=false
+fi
+
+as_test_x='test -x'
+as_executable_p=as_fn_executable_p
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+SHELL=${CONFIG_SHELL-/bin/sh}
+
+
+test -n "$DJDIR" || exec 7<&0 </dev/null
+exec 6>&1
+
+# Name of the host.
+# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status,
+# so uname gets run too.
+ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
+
+#
+# Initializations.
+#
+ac_default_prefix=/usr/local
+ac_clean_files=
+ac_config_libobj_dir=.
+LIBOBJS=
+cross_compiling=no
+subdirs=
+MFLAGS=
+MAKEFLAGS=
+
+# Identity of this package.
+PACKAGE_NAME='spl'
+PACKAGE_TARNAME='spl'
+PACKAGE_VERSION='0.6.5.6'
+PACKAGE_STRING='spl 0.6.5.6'
+PACKAGE_BUGREPORT=''
+PACKAGE_URL=''
+
+# Factoring default headers for most tests.
+ac_includes_default="\
+#include <stdio.h>
+#ifdef HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# ifdef HAVE_STDLIB_H
+#  include <stdlib.h>
+# endif
+#endif
+#ifdef HAVE_STRING_H
+# if !defined STDC_HEADERS && defined HAVE_MEMORY_H
+#  include <memory.h>
+# endif
+# include <string.h>
+#endif
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif
+#ifdef HAVE_INTTYPES_H
+# include <inttypes.h>
+#endif
+#ifdef HAVE_STDINT_H
+# include <stdint.h>
+#endif
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif"
+
+ac_subst_vars='am__EXEEXT_FALSE
+am__EXEEXT_TRUE
+LTLIBOBJS
+LIBOBJS
+CONFIG_KERNEL_FALSE
+CONFIG_KERNEL_TRUE
+CONFIG_USER_FALSE
+CONFIG_USER_TRUE
+DEBUG_KMEM_TRACKING
+DEBUG_KMEM
+DEBUG_SPL
+DEBUG_CFLAGS
+KERNELCPPFLAGS
+KERNELMAKE_PARAMS
+LINUX_SYMBOLS
+LINUX_VERSION
+LINUX_OBJ
+LINUX
+SPL_CONFIG
+ALIEN_VERSION
+ALIEN
+HAVE_ALIEN
+DPKGBUILD_VERSION
+DPKGBUILD
+HAVE_DPKGBUILD
+DPKG_VERSION
+DPKG
+HAVE_DPKG
+SRPM_DEFINE_COMMON
+SRPM_DEFINE_DKMS
+SRPM_DEFINE_KMOD
+SRPM_DEFINE_UTIL
+RPM_DEFINE_COMMON
+RPM_DEFINE_DKMS
+RPM_DEFINE_KMOD
+RPM_DEFINE_UTIL
+RPM_SPEC_DIR
+RPMBUILD_VERSION
+RPMBUILD
+HAVE_RPMBUILD
+RPM_VERSION
+RPM
+HAVE_RPM
+DEFAULT_PACKAGE
+VENDOR
+CPP
+LT_SYS_LIBRARY_PATH
+OTOOL64
+OTOOL
+LIPO
+NMEDIT
+DSYMUTIL
+MANIFEST_TOOL
+RANLIB
+ac_ct_AR
+AR
+DLLTOOL
+OBJDUMP
+LN_S
+NM
+ac_ct_DUMPBIN
+DUMPBIN
+LD
+FGREP
+EGREP
+GREP
+SED
+LIBTOOL
+am__fastdepCC_FALSE
+am__fastdepCC_TRUE
+CCDEPMODE
+am__nodep
+AMDEPBACKSLASH
+AMDEP_FALSE
+AMDEP_TRUE
+am__quote
+am__include
+DEPDIR
+OBJEXT
+EXEEXT
+ac_ct_CC
+CPPFLAGS
+LDFLAGS
+CFLAGS
+CC
+am__untar
+am__tar
+AMTAR
+am__leading_dot
+SET_MAKE
+mkdir_p
+MKDIR_P
+INSTALL_STRIP_PROGRAM
+STRIP
+install_sh
+MAKEINFO
+AUTOHEADER
+AUTOMAKE
+AUTOCONF
+ACLOCAL
+VERSION
+PACKAGE
+CYGPATH_W
+am__isrc
+INSTALL_DATA
+INSTALL_SCRIPT
+INSTALL_PROGRAM
+AM_BACKSLASH
+AM_DEFAULT_VERBOSITY
+AM_DEFAULT_V
+AM_V
+MAINT
+MAINTAINER_MODE_FALSE
+MAINTAINER_MODE_TRUE
+target_os
+target_vendor
+target_cpu
+target
+host_os
+host_vendor
+host_cpu
+host
+build_os
+build_vendor
+build_cpu
+build
+SPL_META_LT_AGE
+SPL_META_LT_REVISION
+SPL_META_LT_CURRENT
+SPL_META_AUTHOR
+SPL_META_DATA
+SPL_META_ALIAS
+SPL_META_LICENSE
+RELEASE
+SPL_META_RELEASE
+SPL_META_VERSION
+SPL_META_NAME
+AWK
+target_alias
+host_alias
+build_alias
+LIBS
+ECHO_T
+ECHO_N
+ECHO_C
+DEFS
+mandir
+localedir
+libdir
+psdir
+pdfdir
+dvidir
+htmldir
+infodir
+docdir
+oldincludedir
+includedir
+runstatedir
+localstatedir
+sharedstatedir
+sysconfdir
+datadir
+datarootdir
+libexecdir
+sbindir
+bindir
+program_transform_name
+prefix
+exec_prefix
+PACKAGE_URL
+PACKAGE_BUGREPORT
+PACKAGE_STRING
+PACKAGE_VERSION
+PACKAGE_TARNAME
+PACKAGE_NAME
+PATH_SEPARATOR
+SHELL'
+ac_subst_files=''
+ac_user_opts='
+enable_option_checking
+enable_maintainer_mode
+enable_silent_rules
+enable_dependency_tracking
+enable_shared
+enable_static
+with_pic
+enable_fast_install
+with_aix_soname
+with_gnu_ld
+with_sysroot
+enable_libtool_lock
+with_spec
+with_config
+enable_linux_builtin
+with_linux
+with_linux_obj
+enable_debug
+enable_debug_kmem
+enable_debug_kmem_tracking
+enable_atomic_spinlocks
+'
+      ac_precious_vars='build_alias
+host_alias
+target_alias
+CC
+CFLAGS
+LDFLAGS
+LIBS
+CPPFLAGS
+LT_SYS_LIBRARY_PATH
+CPP'
+
+
+# Initialize some variables set by options.
+ac_init_help=
+ac_init_version=false
+ac_unrecognized_opts=
+ac_unrecognized_sep=
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+cache_file=/dev/null
+exec_prefix=NONE
+no_create=
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+verbose=
+x_includes=NONE
+x_libraries=NONE
+
+# Installation directory options.
+# These are left unexpanded so users can "make install exec_prefix=/foo"
+# and all the variables that are supposed to be based on exec_prefix
+# by default will actually change.
+# Use braces instead of parens because sh, perl, etc. also accept them.
+# (The list follows the same order as the GNU Coding Standards.)
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datarootdir='${prefix}/share'
+datadir='${datarootdir}'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+runstatedir='${localstatedir}/run'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
+infodir='${datarootdir}/info'
+htmldir='${docdir}'
+dvidir='${docdir}'
+pdfdir='${docdir}'
+psdir='${docdir}'
+libdir='${exec_prefix}/lib'
+localedir='${datarootdir}/locale'
+mandir='${datarootdir}/man'
+
+ac_prev=
+ac_dashdash=
+for ac_option
+do
+  # If the previous option needs an argument, assign it.
+  if test -n "$ac_prev"; then
+    eval $ac_prev=\$ac_option
+    ac_prev=
+    continue
+  fi
+
+  case $ac_option in
+  *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;;
+  *=)   ac_optarg= ;;
+  *)    ac_optarg=yes ;;
+  esac
+
+  # Accept the important Cygnus configure options, so we can diagnose typos.
+
+  case $ac_dashdash$ac_option in
+  --)
+    ac_dashdash=yes ;;
+
+  -bindir | --bindir | --bindi | --bind | --bin | --bi)
+    ac_prev=bindir ;;
+  -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+    bindir=$ac_optarg ;;
+
+  -build | --build | --buil | --bui | --bu)
+    ac_prev=build_alias ;;
+  -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+    build_alias=$ac_optarg ;;
+
+  -cache-file | --cache-file | --cache-fil | --cache-fi \
+  | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+    ac_prev=cache_file ;;
+  -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+  | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+    cache_file=$ac_optarg ;;
+
+  --config-cache | -C)
+    cache_file=config.cache ;;
+
+  -datadir | --datadir | --datadi | --datad)
+    ac_prev=datadir ;;
+  -datadir=* | --datadir=* | --datadi=* | --datad=*)
+    datadir=$ac_optarg ;;
+
+  -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \
+  | --dataroo | --dataro | --datar)
+    ac_prev=datarootdir ;;
+  -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \
+  | --dataroot=* | --dataroo=* | --dataro=* | --datar=*)
+    datarootdir=$ac_optarg ;;
+
+  -disable-* | --disable-*)
+    ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+      as_fn_error $? "invalid feature name: $ac_useropt"
+    ac_useropt_orig=$ac_useropt
+    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+    case $ac_user_opts in
+      *"
+"enable_$ac_useropt"
+"*) ;;
+      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig"
+	 ac_unrecognized_sep=', ';;
+    esac
+    eval enable_$ac_useropt=no ;;
+
+  -docdir | --docdir | --docdi | --doc | --do)
+    ac_prev=docdir ;;
+  -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*)
+    docdir=$ac_optarg ;;
+
+  -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv)
+    ac_prev=dvidir ;;
+  -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*)
+    dvidir=$ac_optarg ;;
+
+  -enable-* | --enable-*)
+    ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+      as_fn_error $? "invalid feature name: $ac_useropt"
+    ac_useropt_orig=$ac_useropt
+    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+    case $ac_user_opts in
+      *"
+"enable_$ac_useropt"
+"*) ;;
+      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig"
+	 ac_unrecognized_sep=', ';;
+    esac
+    eval enable_$ac_useropt=\$ac_optarg ;;
+
+  -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+  | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+  | --exec | --exe | --ex)
+    ac_prev=exec_prefix ;;
+  -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+  | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+  | --exec=* | --exe=* | --ex=*)
+    exec_prefix=$ac_optarg ;;
+
+  -gas | --gas | --ga | --g)
+    # Obsolete; use --with-gas.
+    with_gas=yes ;;
+
+  -help | --help | --hel | --he | -h)
+    ac_init_help=long ;;
+  -help=r* | --help=r* | --hel=r* | --he=r* | -hr*)
+    ac_init_help=recursive ;;
+  -help=s* | --help=s* | --hel=s* | --he=s* | -hs*)
+    ac_init_help=short ;;
+
+  -host | --host | --hos | --ho)
+    ac_prev=host_alias ;;
+  -host=* | --host=* | --hos=* | --ho=*)
+    host_alias=$ac_optarg ;;
+
+  -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht)
+    ac_prev=htmldir ;;
+  -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \
+  | --ht=*)
+    htmldir=$ac_optarg ;;
+
+  -includedir | --includedir | --includedi | --included | --include \
+  | --includ | --inclu | --incl | --inc)
+    ac_prev=includedir ;;
+  -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+  | --includ=* | --inclu=* | --incl=* | --inc=*)
+    includedir=$ac_optarg ;;
+
+  -infodir | --infodir | --infodi | --infod | --info | --inf)
+    ac_prev=infodir ;;
+  -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+    infodir=$ac_optarg ;;
+
+  -libdir | --libdir | --libdi | --libd)
+    ac_prev=libdir ;;
+  -libdir=* | --libdir=* | --libdi=* | --libd=*)
+    libdir=$ac_optarg ;;
+
+  -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+  | --libexe | --libex | --libe)
+    ac_prev=libexecdir ;;
+  -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+  | --libexe=* | --libex=* | --libe=*)
+    libexecdir=$ac_optarg ;;
+
+  -localedir | --localedir | --localedi | --localed | --locale)
+    ac_prev=localedir ;;
+  -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*)
+    localedir=$ac_optarg ;;
+
+  -localstatedir | --localstatedir | --localstatedi | --localstated \
+  | --localstate | --localstat | --localsta | --localst | --locals)
+    ac_prev=localstatedir ;;
+  -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+  | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*)
+    localstatedir=$ac_optarg ;;
+
+  -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+    ac_prev=mandir ;;
+  -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+    mandir=$ac_optarg ;;
+
+  -nfp | --nfp | --nf)
+    # Obsolete; use --without-fp.
+    with_fp=no ;;
+
+  -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+  | --no-cr | --no-c | -n)
+    no_create=yes ;;
+
+  -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+  | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+    no_recursion=yes ;;
+
+  -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+  | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+  | --oldin | --oldi | --old | --ol | --o)
+    ac_prev=oldincludedir ;;
+  -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+  | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+  | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+    oldincludedir=$ac_optarg ;;
+
+  -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+    ac_prev=prefix ;;
+  -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+    prefix=$ac_optarg ;;
+
+  -program-prefix | --program-prefix | --program-prefi | --program-pref \
+  | --program-pre | --program-pr | --program-p)
+    ac_prev=program_prefix ;;
+  -program-prefix=* | --program-prefix=* | --program-prefi=* \
+  | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+    program_prefix=$ac_optarg ;;
+
+  -program-suffix | --program-suffix | --program-suffi | --program-suff \
+  | --program-suf | --program-su | --program-s)
+    ac_prev=program_suffix ;;
+  -program-suffix=* | --program-suffix=* | --program-suffi=* \
+  | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+    program_suffix=$ac_optarg ;;
+
+  -program-transform-name | --program-transform-name \
+  | --program-transform-nam | --program-transform-na \
+  | --program-transform-n | --program-transform- \
+  | --program-transform | --program-transfor \
+  | --program-transfo | --program-transf \
+  | --program-trans | --program-tran \
+  | --progr-tra | --program-tr | --program-t)
+    ac_prev=program_transform_name ;;
+  -program-transform-name=* | --program-transform-name=* \
+  | --program-transform-nam=* | --program-transform-na=* \
+  | --program-transform-n=* | --program-transform-=* \
+  | --program-transform=* | --program-transfor=* \
+  | --program-transfo=* | --program-transf=* \
+  | --program-trans=* | --program-tran=* \
+  | --progr-tra=* | --program-tr=* | --program-t=*)
+    program_transform_name=$ac_optarg ;;
+
+  -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd)
+    ac_prev=pdfdir ;;
+  -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*)
+    pdfdir=$ac_optarg ;;
+
+  -psdir | --psdir | --psdi | --psd | --ps)
+    ac_prev=psdir ;;
+  -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*)
+    psdir=$ac_optarg ;;
+
+  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+  | -silent | --silent | --silen | --sile | --sil)
+    silent=yes ;;
+
+  -runstatedir | --runstatedir | --runstatedi | --runstated \
+  | --runstate | --runstat | --runsta | --runst | --runs \
+  | --run | --ru | --r)
+    ac_prev=runstatedir ;;
+  -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \
+  | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \
+  | --run=* | --ru=* | --r=*)
+    runstatedir=$ac_optarg ;;
+
+  -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+    ac_prev=sbindir ;;
+  -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+  | --sbi=* | --sb=*)
+    sbindir=$ac_optarg ;;
+
+  -sharedstatedir | --sharedstatedir | --sharedstatedi \
+  | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+  | --sharedst | --shareds | --shared | --share | --shar \
+  | --sha | --sh)
+    ac_prev=sharedstatedir ;;
+  -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+  | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+  | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+  | --sha=* | --sh=*)
+    sharedstatedir=$ac_optarg ;;
+
+  -site | --site | --sit)
+    ac_prev=site ;;
+  -site=* | --site=* | --sit=*)
+    site=$ac_optarg ;;
+
+  -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+    ac_prev=srcdir ;;
+  -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+    srcdir=$ac_optarg ;;
+
+  -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+  | --syscon | --sysco | --sysc | --sys | --sy)
+    ac_prev=sysconfdir ;;
+  -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+  | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+    sysconfdir=$ac_optarg ;;
+
+  -target | --target | --targe | --targ | --tar | --ta | --t)
+    ac_prev=target_alias ;;
+  -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+    target_alias=$ac_optarg ;;
+
+  -v | -verbose | --verbose | --verbos | --verbo | --verb)
+    verbose=yes ;;
+
+  -version | --version | --versio | --versi | --vers | -V)
+    ac_init_version=: ;;
+
+  -with-* | --with-*)
+    ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+      as_fn_error $? "invalid package name: $ac_useropt"
+    ac_useropt_orig=$ac_useropt
+    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+    case $ac_user_opts in
+      *"
+"with_$ac_useropt"
+"*) ;;
+      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig"
+	 ac_unrecognized_sep=', ';;
+    esac
+    eval with_$ac_useropt=\$ac_optarg ;;
+
+  -without-* | --without-*)
+    ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+      as_fn_error $? "invalid package name: $ac_useropt"
+    ac_useropt_orig=$ac_useropt
+    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+    case $ac_user_opts in
+      *"
+"with_$ac_useropt"
+"*) ;;
+      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig"
+	 ac_unrecognized_sep=', ';;
+    esac
+    eval with_$ac_useropt=no ;;
+
+  --x)
+    # Obsolete; use --with-x.
+    with_x=yes ;;
+
+  -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+  | --x-incl | --x-inc | --x-in | --x-i)
+    ac_prev=x_includes ;;
+  -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+  | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+    x_includes=$ac_optarg ;;
+
+  -x-libraries | --x-libraries | --x-librarie | --x-librari \
+  | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+    ac_prev=x_libraries ;;
+  -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+  | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+    x_libraries=$ac_optarg ;;
+
+  -*) as_fn_error $? "unrecognized option: \`$ac_option'
+Try \`$0 --help' for more information"
+    ;;
+
+  *=*)
+    ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
+    # Reject names that are not valid shell variable names.
+    case $ac_envvar in #(
+      '' | [0-9]* | *[!_$as_cr_alnum]* )
+      as_fn_error $? "invalid variable name: \`$ac_envvar'" ;;
+    esac
+    eval $ac_envvar=\$ac_optarg
+    export $ac_envvar ;;
+
+  *)
+    # FIXME: should be removed in autoconf 3.0.
+    $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2
+    expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
+      $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2
+    : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}"
+    ;;
+
+  esac
+done
+
+if test -n "$ac_prev"; then
+  ac_option=--`echo $ac_prev | sed 's/_/-/g'`
+  as_fn_error $? "missing argument to $ac_option"
+fi
+
+if test -n "$ac_unrecognized_opts"; then
+  case $enable_option_checking in
+    no) ;;
+    fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;;
+    *)     $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;;
+  esac
+fi
+
+# Check all directory arguments for consistency.
+for ac_var in	exec_prefix prefix bindir sbindir libexecdir datarootdir \
+		datadir sysconfdir sharedstatedir localstatedir includedir \
+		oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
+		libdir localedir mandir runstatedir
+do
+  eval ac_val=\$$ac_var
+  # Remove trailing slashes.
+  case $ac_val in
+    */ )
+      ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'`
+      eval $ac_var=\$ac_val;;
+  esac
+  # Be sure to have absolute directory names.
+  case $ac_val in
+    [\\/$]* | ?:[\\/]* )  continue;;
+    NONE | '' ) case $ac_var in *prefix ) continue;; esac;;
+  esac
+  as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val"
+done
+
+# There might be people who depend on the old broken behavior: `$host'
+# used to hold the argument of --host etc.
+# FIXME: To remove some day.
+build=$build_alias
+host=$host_alias
+target=$target_alias
+
+# FIXME: To remove some day.
+if test "x$host_alias" != x; then
+  if test "x$build_alias" = x; then
+    cross_compiling=maybe
+  elif test "x$build_alias" != "x$host_alias"; then
+    cross_compiling=yes
+  fi
+fi
+
+ac_tool_prefix=
+test -n "$host_alias" && ac_tool_prefix=$host_alias-
+
+test "$silent" = yes && exec 6>/dev/null
+
+
+ac_pwd=`pwd` && test -n "$ac_pwd" &&
+ac_ls_di=`ls -di .` &&
+ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` ||
+  as_fn_error $? "working directory cannot be determined"
+test "X$ac_ls_di" = "X$ac_pwd_ls_di" ||
+  as_fn_error $? "pwd does not report name of working directory"
+
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+  ac_srcdir_defaulted=yes
+  # Try the directory containing this script, then the parent directory.
+  ac_confdir=`$as_dirname -- "$as_myself" ||
+$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$as_myself" : 'X\(//\)[^/]' \| \
+	 X"$as_myself" : 'X\(//\)$' \| \
+	 X"$as_myself" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_myself" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+  srcdir=$ac_confdir
+  if test ! -r "$srcdir/$ac_unique_file"; then
+    srcdir=..
+  fi
+else
+  ac_srcdir_defaulted=no
+fi
+if test ! -r "$srcdir/$ac_unique_file"; then
+  test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .."
+  as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir"
+fi
+ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work"
+ac_abs_confdir=`(
+	cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg"
+	pwd)`
+# When building in place, set srcdir=.
+if test "$ac_abs_confdir" = "$ac_pwd"; then
+  srcdir=.
+fi
+# Remove unnecessary trailing slashes from srcdir.
+# Double slashes in file names in object file debugging info
+# mess up M-x gdb in Emacs.
+case $srcdir in
+*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;;
+esac
+for ac_var in $ac_precious_vars; do
+  eval ac_env_${ac_var}_set=\${${ac_var}+set}
+  eval ac_env_${ac_var}_value=\$${ac_var}
+  eval ac_cv_env_${ac_var}_set=\${${ac_var}+set}
+  eval ac_cv_env_${ac_var}_value=\$${ac_var}
+done
+
+#
+# Report the --help message.
+#
+if test "$ac_init_help" = "long"; then
+  # Omit some internal or obsolete options to make the list less imposing.
+  # This message is too long to be a string in the A/UX 3.1 sh.
+  cat <<_ACEOF
+\`configure' configures spl 0.6.5.6 to adapt to many kinds of systems.
+
+Usage: $0 [OPTION]... [VAR=VALUE]...
+
+To assign environment variables (e.g., CC, CFLAGS...), specify them as
+VAR=VALUE.  See below for descriptions of some of the useful variables.
+
+Defaults for the options are specified in brackets.
+
+Configuration:
+  -h, --help              display this help and exit
+      --help=short        display options specific to this package
+      --help=recursive    display the short help of all the included packages
+  -V, --version           display version information and exit
+  -q, --quiet, --silent   do not print \`checking ...' messages
+      --cache-file=FILE   cache test results in FILE [disabled]
+  -C, --config-cache      alias for \`--cache-file=config.cache'
+  -n, --no-create         do not create output files
+      --srcdir=DIR        find the sources in DIR [configure dir or \`..']
+
+Installation directories:
+  --prefix=PREFIX         install architecture-independent files in PREFIX
+                          [$ac_default_prefix]
+  --exec-prefix=EPREFIX   install architecture-dependent files in EPREFIX
+                          [PREFIX]
+
+By default, \`make install' will install all the files in
+\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc.  You can specify
+an installation prefix other than \`$ac_default_prefix' using \`--prefix',
+for instance \`--prefix=\$HOME'.
+
+For better control, use the options below.
+
+Fine tuning of the installation directories:
+  --bindir=DIR            user executables [EPREFIX/bin]
+  --sbindir=DIR           system admin executables [EPREFIX/sbin]
+  --libexecdir=DIR        program executables [EPREFIX/libexec]
+  --sysconfdir=DIR        read-only single-machine data [PREFIX/etc]
+  --sharedstatedir=DIR    modifiable architecture-independent data [PREFIX/com]
+  --localstatedir=DIR     modifiable single-machine data [PREFIX/var]
+  --runstatedir=DIR       modifiable per-process data [LOCALSTATEDIR/run]
+  --libdir=DIR            object code libraries [EPREFIX/lib]
+  --includedir=DIR        C header files [PREFIX/include]
+  --oldincludedir=DIR     C header files for non-gcc [/usr/include]
+  --datarootdir=DIR       read-only arch.-independent data root [PREFIX/share]
+  --datadir=DIR           read-only architecture-independent data [DATAROOTDIR]
+  --infodir=DIR           info documentation [DATAROOTDIR/info]
+  --localedir=DIR         locale-dependent data [DATAROOTDIR/locale]
+  --mandir=DIR            man documentation [DATAROOTDIR/man]
+  --docdir=DIR            documentation root [DATAROOTDIR/doc/spl]
+  --htmldir=DIR           html documentation [DOCDIR]
+  --dvidir=DIR            dvi documentation [DOCDIR]
+  --pdfdir=DIR            pdf documentation [DOCDIR]
+  --psdir=DIR             ps documentation [DOCDIR]
+_ACEOF
+
+  cat <<\_ACEOF
+
+Program names:
+  --program-prefix=PREFIX            prepend PREFIX to installed program names
+  --program-suffix=SUFFIX            append SUFFIX to installed program names
+  --program-transform-name=PROGRAM   run sed PROGRAM on installed program names
+
+System types:
+  --build=BUILD     configure for building on BUILD [guessed]
+  --host=HOST       cross-compile to build programs to run on HOST [BUILD]
+  --target=TARGET   configure for building compilers for TARGET [HOST]
+_ACEOF
+fi
+
+if test -n "$ac_init_help"; then
+  case $ac_init_help in
+     short | recursive ) echo "Configuration of spl 0.6.5.6:";;
+   esac
+  cat <<\_ACEOF
+
+Optional Features:
+  --disable-option-checking  ignore unrecognized --enable/--with options
+  --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
+  --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
+  --enable-maintainer-mode
+                          enable make rules and dependencies not useful (and
+                          sometimes confusing) to the casual installer
+  --enable-silent-rules   less verbose build output (undo: "make V=1")
+  --disable-silent-rules  verbose build output (undo: "make V=0")
+  --enable-dependency-tracking
+                          do not reject slow dependency extractors
+  --disable-dependency-tracking
+                          speeds up one-time build
+  --enable-shared[=PKGS]  build shared libraries [default=yes]
+  --enable-static[=PKGS]  build static libraries [default=yes]
+  --enable-fast-install[=PKGS]
+                          optimize for fast installation [default=yes]
+  --disable-libtool-lock  avoid locking (might break parallel builds)
+  --enable-linux-builtin  Configure for builtin in-tree kernel modules
+                          [default=no]
+  --enable-debug          Enable generic debug support [default=no]
+  --enable-debug-kmem     Enable basic kmem accounting [default=no]
+  --enable-debug-kmem-tracking
+                          Enable detailed kmem tracking [default=no]
+  --enable-atomic-spinlocks
+                          Atomic types use spinlocks [default=check]
+
+Optional Packages:
+  --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
+  --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
+  --with-pic[=PKGS]       try to use only PIC/non-PIC objects [default=use
+                          both]
+  --with-aix-soname=aix|svr4|both
+                          shared library versioning (aka "SONAME") variant to
+                          provide on AIX, [default=aix].
+  --with-gnu-ld           assume the C compiler uses GNU ld [default=no]
+  --with-sysroot[=DIR]    Search for dependent libraries within DIR (or the
+                          compiler's sysroot if not specified).
+  --with-spec=SPEC        Spec files 'generic|redhat'
+  --with-config=CONFIG    Config file 'kernel|user|all|srpm'
+  --with-linux=PATH       Path to kernel source
+  --with-linux-obj=PATH   Path to kernel build objects
+
+Some influential environment variables:
+  CC          C compiler command
+  CFLAGS      C compiler flags
+  LDFLAGS     linker flags, e.g. -L<lib dir> if you have libraries in a
+              nonstandard directory <lib dir>
+  LIBS        libraries to pass to the linker, e.g. -l<library>
+  CPPFLAGS    (Objective) C/C++ preprocessor flags, e.g. -I<include dir> if
+              you have headers in a nonstandard directory <include dir>
+  LT_SYS_LIBRARY_PATH
+              User-defined run-time library search path.
+  CPP         C preprocessor
+
+Use these variables to override the choices made by `configure' or to help
+it to find libraries and programs with nonstandard names/locations.
+
+Report bugs to the package provider.
+_ACEOF
+ac_status=$?
+fi
+
+if test "$ac_init_help" = "recursive"; then
+  # If there are subdirs, report their specific --help.
+  for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
+    test -d "$ac_dir" ||
+      { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } ||
+      continue
+    ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+  ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
+  # A ".." for each directory in $ac_dir_suffix.
+  ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+  case $ac_top_builddir_sub in
+  "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+  *)  ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+  esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+  .)  # We are building in place.
+    ac_srcdir=.
+    ac_top_srcdir=$ac_top_builddir_sub
+    ac_abs_top_srcdir=$ac_pwd ;;
+  [\\/]* | ?:[\\/]* )  # Absolute name.
+    ac_srcdir=$srcdir$ac_dir_suffix;
+    ac_top_srcdir=$srcdir
+    ac_abs_top_srcdir=$srcdir ;;
+  *) # Relative name.
+    ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_build_prefix$srcdir
+    ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+    cd "$ac_dir" || { ac_status=$?; continue; }
+    # Check for guested configure.
+    if test -f "$ac_srcdir/configure.gnu"; then
+      echo &&
+      $SHELL "$ac_srcdir/configure.gnu" --help=recursive
+    elif test -f "$ac_srcdir/configure"; then
+      echo &&
+      $SHELL "$ac_srcdir/configure" --help=recursive
+    else
+      $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
+    fi || ac_status=$?
+    cd "$ac_pwd" || { ac_status=$?; break; }
+  done
+fi
+
+test -n "$ac_init_help" && exit $ac_status
+if $ac_init_version; then
+  cat <<\_ACEOF
+spl configure 0.6.5.6
+generated by GNU Autoconf 2.69
+
+Copyright (C) 2012 Free Software Foundation, Inc.
+This configure script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it.
+_ACEOF
+  exit
+fi
+
+## ------------------------ ##
+## Autoconf initialization. ##
+## ------------------------ ##
+
+# ac_fn_c_try_compile LINENO
+# --------------------------
+# Try to compile conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_compile ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  rm -f conftest.$ac_objext
+  if { { ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_compile") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    grep -v '^ *+' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+    mv -f conftest.er1 conftest.err
+  fi
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then :
+  ac_retval=0
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_retval=1
+fi
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_compile
+
+# ac_fn_c_try_link LINENO
+# -----------------------
+# Try to link conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_link ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  rm -f conftest.$ac_objext conftest$ac_exeext
+  if { { ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_link") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    grep -v '^ *+' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+    mv -f conftest.er1 conftest.err
+  fi
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest$ac_exeext && {
+	 test "$cross_compiling" = yes ||
+	 test -x conftest$ac_exeext
+       }; then :
+  ac_retval=0
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_retval=1
+fi
+  # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information
+  # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would
+  # interfere with the next link command; also delete a directory that is
+  # left behind by Apple's compiler.  We do this before executing the actions.
+  rm -rf conftest.dSYM conftest_ipa8_conftest.oo
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_link
+
+# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES
+# -------------------------------------------------------
+# Tests whether HEADER exists and can be compiled using the include files in
+# INCLUDES, setting the cache variable VAR accordingly.
+ac_fn_c_check_header_compile ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+#include <$2>
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  eval "$3=yes"
+else
+  eval "$3=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_header_compile
+
+# ac_fn_c_try_cpp LINENO
+# ----------------------
+# Try to preprocess conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_cpp ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  if { { ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    grep -v '^ *+' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+    mv -f conftest.er1 conftest.err
+  fi
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } > conftest.i && {
+	 test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       }; then :
+  ac_retval=0
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+    ac_retval=1
+fi
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_cpp
+
+# ac_fn_c_try_run LINENO
+# ----------------------
+# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes
+# that executables *can* be run.
+ac_fn_c_try_run ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  if { { ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_link") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && { ac_try='./conftest$ac_exeext'
+  { { case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+  ac_retval=0
+else
+  $as_echo "$as_me: program exited with status $ac_status" >&5
+       $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+       ac_retval=$ac_status
+fi
+  rm -rf conftest.dSYM conftest_ipa8_conftest.oo
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_run
+
+# ac_fn_c_check_func LINENO FUNC VAR
+# ----------------------------------
+# Tests whether FUNC exists, setting the cache variable VAR accordingly
+ac_fn_c_check_func ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+/* Define $2 to an innocuous variant, in case <limits.h> declares $2.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define $2 innocuous_$2
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $2 (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $2
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char $2 ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined __stub_$2 || defined __stub___$2
+choke me
+#endif
+
+int
+main ()
+{
+return $2 ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  eval "$3=yes"
+else
+  eval "$3=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_func
+cat >config.log <<_ACEOF
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+
+It was created by spl $as_me 0.6.5.6, which was
+generated by GNU Autoconf 2.69.  Invocation command line was
+
+  $ $0 $@
+
+_ACEOF
+exec 5>>config.log
+{
+cat <<_ASUNAME
+## --------- ##
+## Platform. ##
+## --------- ##
+
+hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`
+/bin/uname -X     = `(/bin/uname -X) 2>/dev/null     || echo unknown`
+
+/bin/arch              = `(/bin/arch) 2>/dev/null              || echo unknown`
+/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null       || echo unknown`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
+/usr/bin/hostinfo      = `(/usr/bin/hostinfo) 2>/dev/null      || echo unknown`
+/bin/machine           = `(/bin/machine) 2>/dev/null           || echo unknown`
+/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null       || echo unknown`
+/bin/universe          = `(/bin/universe) 2>/dev/null          || echo unknown`
+
+_ASUNAME
+
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    $as_echo "PATH: $as_dir"
+  done
+IFS=$as_save_IFS
+
+} >&5
+
+cat >&5 <<_ACEOF
+
+
+## ----------- ##
+## Core tests. ##
+## ----------- ##
+
+_ACEOF
+
+
+# Keep a trace of the command line.
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Strip out --silent because we don't want to record it for future runs.
+# Also quote any args containing shell meta-characters.
+# Make two passes to allow for proper duplicate-argument suppression.
+ac_configure_args=
+ac_configure_args0=
+ac_configure_args1=
+ac_must_keep_next=false
+for ac_pass in 1 2
+do
+  for ac_arg
+  do
+    case $ac_arg in
+    -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;
+    -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+    | -silent | --silent | --silen | --sile | --sil)
+      continue ;;
+    *\'*)
+      ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+    esac
+    case $ac_pass in
+    1) as_fn_append ac_configure_args0 " '$ac_arg'" ;;
+    2)
+      as_fn_append ac_configure_args1 " '$ac_arg'"
+      if test $ac_must_keep_next = true; then
+	ac_must_keep_next=false # Got value, back to normal.
+      else
+	case $ac_arg in
+	  *=* | --config-cache | -C | -disable-* | --disable-* \
+	  | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
+	  | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
+	  | -with-* | --with-* | -without-* | --without-* | --x)
+	    case "$ac_configure_args0 " in
+	      "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
+	    esac
+	    ;;
+	  -* ) ac_must_keep_next=true ;;
+	esac
+      fi
+      as_fn_append ac_configure_args " '$ac_arg'"
+      ;;
+    esac
+  done
+done
+{ ac_configure_args0=; unset ac_configure_args0;}
+{ ac_configure_args1=; unset ac_configure_args1;}
+
+# When interrupted or exit'd, cleanup temporary files, and complete
+# config.log.  We remove comments because anyway the quotes in there
+# would cause problems or look ugly.
+# WARNING: Use '\'' to represent an apostrophe within the trap.
+# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug.
+trap 'exit_status=$?
+  # Save into config.log some information that might help in debugging.
+  {
+    echo
+
+    $as_echo "## ---------------- ##
+## Cache variables. ##
+## ---------------- ##"
+    echo
+    # The following way of writing the cache mishandles newlines in values,
+(
+  for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do
+    eval ac_val=\$$ac_var
+    case $ac_val in #(
+    *${as_nl}*)
+      case $ac_var in #(
+      *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
+$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
+      esac
+      case $ac_var in #(
+      _ | IFS | as_nl) ;; #(
+      BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
+      *) { eval $ac_var=; unset $ac_var;} ;;
+      esac ;;
+    esac
+  done
+  (set) 2>&1 |
+    case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #(
+    *${as_nl}ac_space=\ *)
+      sed -n \
+	"s/'\''/'\''\\\\'\'''\''/g;
+	  s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p"
+      ;; #(
+    *)
+      sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
+      ;;
+    esac |
+    sort
+)
+    echo
+
+    $as_echo "## ----------------- ##
+## Output variables. ##
+## ----------------- ##"
+    echo
+    for ac_var in $ac_subst_vars
+    do
+      eval ac_val=\$$ac_var
+      case $ac_val in
+      *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+      esac
+      $as_echo "$ac_var='\''$ac_val'\''"
+    done | sort
+    echo
+
+    if test -n "$ac_subst_files"; then
+      $as_echo "## ------------------- ##
+## File substitutions. ##
+## ------------------- ##"
+      echo
+      for ac_var in $ac_subst_files
+      do
+	eval ac_val=\$$ac_var
+	case $ac_val in
+	*\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+	esac
+	$as_echo "$ac_var='\''$ac_val'\''"
+      done | sort
+      echo
+    fi
+
+    if test -s confdefs.h; then
+      $as_echo "## ----------- ##
+## confdefs.h. ##
+## ----------- ##"
+      echo
+      cat confdefs.h
+      echo
+    fi
+    test "$ac_signal" != 0 &&
+      $as_echo "$as_me: caught signal $ac_signal"
+    $as_echo "$as_me: exit $exit_status"
+  } >&5
+  rm -f core *.core core.conftest.* &&
+    rm -f -r conftest* confdefs* conf$$* $ac_clean_files &&
+    exit $exit_status
+' 0
+for ac_signal in 1 2 13 15; do
+  trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal
+done
+ac_signal=0
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -f -r conftest* confdefs.h
+
+$as_echo "/* confdefs.h */" > confdefs.h
+
+# Predefined preprocessor variables.
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_NAME "$PACKAGE_NAME"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_TARNAME "$PACKAGE_TARNAME"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_VERSION "$PACKAGE_VERSION"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_STRING "$PACKAGE_STRING"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_URL "$PACKAGE_URL"
+_ACEOF
+
+
+# Let the site file select an alternate cache file if it wants to.
+# Prefer an explicitly selected file to automatically selected ones.
+ac_site_file1=NONE
+ac_site_file2=NONE
+if test -n "$CONFIG_SITE"; then
+  # We do not want a PATH search for config.site.
+  case $CONFIG_SITE in #((
+    -*)  ac_site_file1=./$CONFIG_SITE;;
+    */*) ac_site_file1=$CONFIG_SITE;;
+    *)   ac_site_file1=./$CONFIG_SITE;;
+  esac
+elif test "x$prefix" != xNONE; then
+  ac_site_file1=$prefix/share/config.site
+  ac_site_file2=$prefix/etc/config.site
+else
+  ac_site_file1=$ac_default_prefix/share/config.site
+  ac_site_file2=$ac_default_prefix/etc/config.site
+fi
+for ac_site_file in "$ac_site_file1" "$ac_site_file2"
+do
+  test "x$ac_site_file" = xNONE && continue
+  if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5
+$as_echo "$as_me: loading site script $ac_site_file" >&6;}
+    sed 's/^/| /' "$ac_site_file" >&5
+    . "$ac_site_file" \
+      || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "failed to load site script $ac_site_file
+See \`config.log' for more details" "$LINENO" 5; }
+  fi
+done
+
+if test -r "$cache_file"; then
+  # Some versions of bash will fail to source /dev/null (special files
+  # actually), so we avoid doing that.  DJGPP emulates it as a regular file.
+  if test /dev/null != "$cache_file" && test -f "$cache_file"; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5
+$as_echo "$as_me: loading cache $cache_file" >&6;}
+    case $cache_file in
+      [\\/]* | ?:[\\/]* ) . "$cache_file";;
+      *)                      . "./$cache_file";;
+    esac
+  fi
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5
+$as_echo "$as_me: creating cache $cache_file" >&6;}
+  >$cache_file
+fi
+
+# Check that the precious variables saved in the cache have kept the same
+# value.
+ac_cache_corrupted=false
+for ac_var in $ac_precious_vars; do
+  eval ac_old_set=\$ac_cv_env_${ac_var}_set
+  eval ac_new_set=\$ac_env_${ac_var}_set
+  eval ac_old_val=\$ac_cv_env_${ac_var}_value
+  eval ac_new_val=\$ac_env_${ac_var}_value
+  case $ac_old_set,$ac_new_set in
+    set,)
+      { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
+$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
+      ac_cache_corrupted=: ;;
+    ,set)
+      { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5
+$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
+      ac_cache_corrupted=: ;;
+    ,);;
+    *)
+      if test "x$ac_old_val" != "x$ac_new_val"; then
+	# differences in whitespace do not lead to failure.
+	ac_old_val_w=`echo x $ac_old_val`
+	ac_new_val_w=`echo x $ac_new_val`
+	if test "$ac_old_val_w" != "$ac_new_val_w"; then
+	  { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5
+$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
+	  ac_cache_corrupted=:
+	else
+	  { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5
+$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;}
+	  eval $ac_var=\$ac_old_val
+	fi
+	{ $as_echo "$as_me:${as_lineno-$LINENO}:   former value:  \`$ac_old_val'" >&5
+$as_echo "$as_me:   former value:  \`$ac_old_val'" >&2;}
+	{ $as_echo "$as_me:${as_lineno-$LINENO}:   current value: \`$ac_new_val'" >&5
+$as_echo "$as_me:   current value: \`$ac_new_val'" >&2;}
+      fi;;
+  esac
+  # Pass precious variables to config.status.
+  if test "$ac_new_set" = set; then
+    case $ac_new_val in
+    *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
+    *) ac_arg=$ac_var=$ac_new_val ;;
+    esac
+    case " $ac_configure_args " in
+      *" '$ac_arg' "*) ;; # Avoid dups.  Use of quotes ensures accuracy.
+      *) as_fn_append ac_configure_args " '$ac_arg'" ;;
+    esac
+  fi
+done
+if $ac_cache_corrupted; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+  { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5
+$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;}
+  as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5
+fi
+## -------------------- ##
+## Main body of script. ##
+## -------------------- ##
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+	for ac_prog in gawk mawk nawk awk
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_AWK+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$AWK"; then
+  ac_cv_prog_AWK="$AWK" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_AWK="$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+AWK=$ac_cv_prog_AWK
+if test -n "$AWK"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5
+$as_echo "$AWK" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  test -n "$AWK" && break
+done
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking metadata" >&5
+$as_echo_n "checking metadata... " >&6; }
+
+	META="$srcdir/META"
+	_spl_ac_meta_type="none"
+	if test -f "$META"; then
+		_spl_ac_meta_type="META file"
+
+		SPL_META_NAME=`$AWK -F ':[ \t]+' '$1 ~ /^ *(Name|Project|Package)$/ { print $2; exit }' $META`;
+		if test -n "$SPL_META_NAME"; then
+
+cat >>confdefs.h <<_ACEOF
+#define SPL_META_NAME "$SPL_META_NAME"
+_ACEOF
+
+
+		fi
+
+		SPL_META_VERSION=`$AWK -F ':[ \t]+' '$1 ~ /^ *Version$/ { print $2; exit }' $META`;
+		if test -n "$SPL_META_VERSION"; then
+
+cat >>confdefs.h <<_ACEOF
+#define SPL_META_VERSION "$SPL_META_VERSION"
+_ACEOF
+
+
+		fi
+
+		SPL_META_RELEASE=`$AWK -F ':[ \t]+' '$1 ~ /^ *Release$/ { print $2; exit }' $META`;
+		if test ! -f ".nogitrelease" && git rev-parse --git-dir > /dev/null 2>&1; then
+			_match="${SPL_META_NAME}-${SPL_META_VERSION}"
+			_alias=$(git describe --match=${_match} 2>/dev/null)
+			_release=$(echo ${_alias}|cut -f3- -d'-'|sed 's/-/_/g')
+			if test -n "${_release}"; then
+				SPL_META_RELEASE=${_release}
+				_spl_ac_meta_type="git describe"
+			fi
+		fi
+
+		if test -n "$SPL_META_RELEASE"; then
+
+cat >>confdefs.h <<_ACEOF
+#define SPL_META_RELEASE "$SPL_META_RELEASE"
+_ACEOF
+
+
+
+			RELEASE="$SPL_META_RELEASE"
+
+		fi
+
+		SPL_META_LICENSE=`$AWK -F ':[ \t]+' '$1 ~ /^ *License$/ { print $2; exit }' $META`;
+		if test -n "$SPL_META_LICENSE"; then
+
+cat >>confdefs.h <<_ACEOF
+#define SPL_META_LICENSE "$SPL_META_LICENSE"
+_ACEOF
+
+
+		fi
+
+		if test -n "$SPL_META_NAME" -a -n "$SPL_META_VERSION"; then
+				SPL_META_ALIAS="$SPL_META_NAME-$SPL_META_VERSION"
+				test -n "$SPL_META_RELEASE" &&
+				        SPL_META_ALIAS="$SPL_META_ALIAS-$SPL_META_RELEASE"
+
+cat >>confdefs.h <<_ACEOF
+#define SPL_META_ALIAS "$SPL_META_ALIAS"
+_ACEOF
+
+
+		fi
+
+		SPL_META_DATA=`$AWK -F ':[ \t]+' '$1 ~ /^ *Date$/ { print $2; exit }' $META`;
+		if test -n "$SPL_META_DATA"; then
+
+cat >>confdefs.h <<_ACEOF
+#define SPL_META_DATA "$SPL_META_DATA"
+_ACEOF
+
+
+		fi
+
+		SPL_META_AUTHOR=`$AWK -F ':[ \t]+' '$1 ~ /^ *Author$/ { print $2; exit }' $META`;
+		if test -n "$SPL_META_AUTHOR"; then
+
+cat >>confdefs.h <<_ACEOF
+#define SPL_META_AUTHOR "$SPL_META_AUTHOR"
+_ACEOF
+
+
+		fi
+
+
+		SPL_META_LT_CURRENT=`$AWK -F ':[ \t]+' '$1 ~ /^ *LT_Current$/ { print $2; exit }' $META`;
+		SPL_META_LT_REVISION=`$AWK -F ':[ \t]+' '$1 ~ /^ *LT_Revision$/ { print $2; exit }' $META`;
+		SPL_META_LT_AGE=`$AWK -F ':[ \t]+' '$1 ~ /^ *LT_Age$/ { print $2; exit }' $META`;
+		if test -n "$SPL_META_LT_CURRENT" \
+				 -o -n "$SPL_META_LT_REVISION" \
+				 -o -n "$SPL_META_LT_AGE"; then
+			test -n "$SPL_META_LT_CURRENT" || SPL_META_LT_CURRENT="0"
+			test -n "$SPL_META_LT_REVISION" || SPL_META_LT_REVISION="0"
+			test -n "$SPL_META_LT_AGE" || SPL_META_LT_AGE="0"
+
+cat >>confdefs.h <<_ACEOF
+#define SPL_META_LT_CURRENT "$SPL_META_LT_CURRENT"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define SPL_META_LT_REVISION "$SPL_META_LT_REVISION"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define SPL_META_LT_AGE "$SPL_META_LT_AGE"
+_ACEOF
+
+
+
+
+		fi
+	fi
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $_spl_ac_meta_type" >&5
+$as_echo "$_spl_ac_meta_type" >&6; }
+
+
+ac_aux_dir=
+for ac_dir in config "$srcdir"/config; do
+  if test -f "$ac_dir/install-sh"; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install-sh -c"
+    break
+  elif test -f "$ac_dir/install.sh"; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install.sh -c"
+    break
+  elif test -f "$ac_dir/shtool"; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/shtool install -c"
+    break
+  fi
+done
+if test -z "$ac_aux_dir"; then
+  as_fn_error $? "cannot find install-sh, install.sh, or shtool in config \"$srcdir\"/config" "$LINENO" 5
+fi
+
+# These three variables are undocumented and unsupported,
+# and are intended to be withdrawn in a future Autoconf release.
+# They can cause serious problems if a builder's source tree is in a directory
+# whose full name contains unusual characters.
+ac_config_guess="$SHELL $ac_aux_dir/config.guess"  # Please don't use this var.
+ac_config_sub="$SHELL $ac_aux_dir/config.sub"  # Please don't use this var.
+ac_configure="$SHELL $ac_aux_dir/configure"  # Please don't use this var.
+
+
+
+# Make sure we can run config.sub.
+$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 ||
+  as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5
+$as_echo_n "checking build system type... " >&6; }
+if ${ac_cv_build+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_build_alias=$build_alias
+test "x$ac_build_alias" = x &&
+  ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"`
+test "x$ac_build_alias" = x &&
+  as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5
+ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` ||
+  as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5
+$as_echo "$ac_cv_build" >&6; }
+case $ac_cv_build in
+*-*-*) ;;
+*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;;
+esac
+build=$ac_cv_build
+ac_save_IFS=$IFS; IFS='-'
+set x $ac_cv_build
+shift
+build_cpu=$1
+build_vendor=$2
+shift; shift
+# Remember, the first character of IFS is used to create $*,
+# except with old shells:
+build_os=$*
+IFS=$ac_save_IFS
+case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5
+$as_echo_n "checking host system type... " >&6; }
+if ${ac_cv_host+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test "x$host_alias" = x; then
+  ac_cv_host=$ac_cv_build
+else
+  ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` ||
+    as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5
+$as_echo "$ac_cv_host" >&6; }
+case $ac_cv_host in
+*-*-*) ;;
+*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;;
+esac
+host=$ac_cv_host
+ac_save_IFS=$IFS; IFS='-'
+set x $ac_cv_host
+shift
+host_cpu=$1
+host_vendor=$2
+shift; shift
+# Remember, the first character of IFS is used to create $*,
+# except with old shells:
+host_os=$*
+IFS=$ac_save_IFS
+case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking target system type" >&5
+$as_echo_n "checking target system type... " >&6; }
+if ${ac_cv_target+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test "x$target_alias" = x; then
+  ac_cv_target=$ac_cv_host
+else
+  ac_cv_target=`$SHELL "$ac_aux_dir/config.sub" $target_alias` ||
+    as_fn_error $? "$SHELL $ac_aux_dir/config.sub $target_alias failed" "$LINENO" 5
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_target" >&5
+$as_echo "$ac_cv_target" >&6; }
+case $ac_cv_target in
+*-*-*) ;;
+*) as_fn_error $? "invalid value of canonical target" "$LINENO" 5;;
+esac
+target=$ac_cv_target
+ac_save_IFS=$IFS; IFS='-'
+set x $ac_cv_target
+shift
+target_cpu=$1
+target_vendor=$2
+shift; shift
+# Remember, the first character of IFS is used to create $*,
+# except with old shells:
+target_os=$*
+IFS=$ac_save_IFS
+case $target_os in *\ *) target_os=`echo "$target_os" | sed 's/ /-/g'`;; esac
+
+
+# The aliases save the names the user supplied, while $host etc.
+# will get canonicalized.
+test -n "$target_alias" &&
+  test "$program_prefix$program_suffix$program_transform_name" = \
+    NONENONEs,x,x, &&
+  program_prefix=${target_alias}-
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable maintainer-specific portions of Makefiles" >&5
+$as_echo_n "checking whether to enable maintainer-specific portions of Makefiles... " >&6; }
+    # Check whether --enable-maintainer-mode was given.
+if test "${enable_maintainer_mode+set}" = set; then :
+  enableval=$enable_maintainer_mode; USE_MAINTAINER_MODE=$enableval
+else
+  USE_MAINTAINER_MODE=no
+fi
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $USE_MAINTAINER_MODE" >&5
+$as_echo "$USE_MAINTAINER_MODE" >&6; }
+   if test $USE_MAINTAINER_MODE = yes; then
+  MAINTAINER_MODE_TRUE=
+  MAINTAINER_MODE_FALSE='#'
+else
+  MAINTAINER_MODE_TRUE='#'
+  MAINTAINER_MODE_FALSE=
+fi
+
+  MAINT=$MAINTAINER_MODE_TRUE
+
+
+# Check whether --enable-silent-rules was given.
+if test "${enable_silent_rules+set}" = set; then :
+  enableval=$enable_silent_rules;
+fi
+
+case $enable_silent_rules in # (((
+  yes) AM_DEFAULT_VERBOSITY=0;;
+   no) AM_DEFAULT_VERBOSITY=1;;
+    *) AM_DEFAULT_VERBOSITY=0;;
+esac
+am_make=${MAKE-make}
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5
+$as_echo_n "checking whether $am_make supports nested variables... " >&6; }
+if ${am_cv_make_support_nested_variables+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if $as_echo 'TRUE=$(BAR$(V))
+BAR0=false
+BAR1=true
+V=1
+am__doit:
+	@$(TRUE)
+.PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then
+  am_cv_make_support_nested_variables=yes
+else
+  am_cv_make_support_nested_variables=no
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5
+$as_echo "$am_cv_make_support_nested_variables" >&6; }
+if test $am_cv_make_support_nested_variables = yes; then
+    AM_V='$(V)'
+  AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)'
+else
+  AM_V=$AM_DEFAULT_VERBOSITY
+  AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY
+fi
+AM_BACKSLASH='\'
+
+am__api_version='1.15'
+
+# Find a good install program.  We prefer a C program (faster),
+# so one script is as good as another.  But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AmigaOS /C/install, which installs bootblocks on floppy discs
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# OS/2's system install, which has a completely different semantic
+# ./install, which can be erroneously created by make from ./install.sh.
+# Reject install programs that cannot install multiple files.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5
+$as_echo_n "checking for a BSD-compatible install... " >&6; }
+if test -z "$INSTALL"; then
+if ${ac_cv_path_install+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    # Account for people who put trailing slashes in PATH elements.
+case $as_dir/ in #((
+  ./ | .// | /[cC]/* | \
+  /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \
+  ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \
+  /usr/ucb/* ) ;;
+  *)
+    # OSF1 and SCO ODT 3.0 have their own names for install.
+    # Don't use installbsd from OSF since it installs stuff as root
+    # by default.
+    for ac_prog in ginstall scoinst install; do
+      for ac_exec_ext in '' $ac_executable_extensions; do
+	if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then
+	  if test $ac_prog = install &&
+	    grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+	    # AIX install.  It has an incompatible calling convention.
+	    :
+	  elif test $ac_prog = install &&
+	    grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+	    # program-specific install script used by HP pwplus--don't use.
+	    :
+	  else
+	    rm -rf conftest.one conftest.two conftest.dir
+	    echo one > conftest.one
+	    echo two > conftest.two
+	    mkdir conftest.dir
+	    if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" &&
+	      test -s conftest.one && test -s conftest.two &&
+	      test -s conftest.dir/conftest.one &&
+	      test -s conftest.dir/conftest.two
+	    then
+	      ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c"
+	      break 3
+	    fi
+	  fi
+	fi
+      done
+    done
+    ;;
+esac
+
+  done
+IFS=$as_save_IFS
+
+rm -rf conftest.one conftest.two conftest.dir
+
+fi
+  if test "${ac_cv_path_install+set}" = set; then
+    INSTALL=$ac_cv_path_install
+  else
+    # As a last resort, use the slow shell script.  Don't cache a
+    # value for INSTALL within a source directory, because that will
+    # break other packages using the cache if that directory is
+    # removed, or if the value is a relative name.
+    INSTALL=$ac_install_sh
+  fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5
+$as_echo "$INSTALL" >&6; }
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5
+$as_echo_n "checking whether build environment is sane... " >&6; }
+# Reject unsafe characters in $srcdir or the absolute working directory
+# name.  Accept space and tab only in the latter.
+am_lf='
+'
+case `pwd` in
+  *[\\\"\#\$\&\'\`$am_lf]*)
+    as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;;
+esac
+case $srcdir in
+  *[\\\"\#\$\&\'\`$am_lf\ \	]*)
+    as_fn_error $? "unsafe srcdir value: '$srcdir'" "$LINENO" 5;;
+esac
+
+# Do 'set' in a subshell so we don't clobber the current shell's
+# arguments.  Must try -L first in case configure is actually a
+# symlink; some systems play weird games with the mod time of symlinks
+# (eg FreeBSD returns the mod time of the symlink's containing
+# directory).
+if (
+   am_has_slept=no
+   for am_try in 1 2; do
+     echo "timestamp, slept: $am_has_slept" > conftest.file
+     set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null`
+     if test "$*" = "X"; then
+	# -L didn't work.
+	set X `ls -t "$srcdir/configure" conftest.file`
+     fi
+     if test "$*" != "X $srcdir/configure conftest.file" \
+	&& test "$*" != "X conftest.file $srcdir/configure"; then
+
+	# If neither matched, then we have a broken ls.  This can happen
+	# if, for instance, CONFIG_SHELL is bash and it inherits a
+	# broken ls alias from the environment.  This has actually
+	# happened.  Such a system could not be considered "sane".
+	as_fn_error $? "ls -t appears to fail.  Make sure there is not a broken
+  alias in your environment" "$LINENO" 5
+     fi
+     if test "$2" = conftest.file || test $am_try -eq 2; then
+       break
+     fi
+     # Just in case.
+     sleep 1
+     am_has_slept=yes
+   done
+   test "$2" = conftest.file
+   )
+then
+   # Ok.
+   :
+else
+   as_fn_error $? "newly created file is older than distributed files!
+Check your system clock" "$LINENO" 5
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+# If we didn't sleep, we still need to ensure time stamps of config.status and
+# generated files are strictly newer.
+am_sleep_pid=
+if grep 'slept: no' conftest.file >/dev/null 2>&1; then
+  ( sleep 1 ) &
+  am_sleep_pid=$!
+fi
+
+rm -f conftest.file
+
+test "$program_prefix" != NONE &&
+  program_transform_name="s&^&$program_prefix&;$program_transform_name"
+# Use a double $ so make ignores it.
+test "$program_suffix" != NONE &&
+  program_transform_name="s&\$&$program_suffix&;$program_transform_name"
+# Double any \ or $.
+# By default was `s,x,x', remove it if useless.
+ac_script='s/[\\$]/&&/g;s/;s,x,x,$//'
+program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"`
+
+# Expand $ac_aux_dir to an absolute path.
+am_aux_dir=`cd "$ac_aux_dir" && pwd`
+
+if test x"${MISSING+set}" != xset; then
+  case $am_aux_dir in
+  *\ * | *\	*)
+    MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;;
+  *)
+    MISSING="\${SHELL} $am_aux_dir/missing" ;;
+  esac
+fi
+# Use eval to expand $SHELL
+if eval "$MISSING --is-lightweight"; then
+  am_missing_run="$MISSING "
+else
+  am_missing_run=
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 'missing' script is too old or missing" >&5
+$as_echo "$as_me: WARNING: 'missing' script is too old or missing" >&2;}
+fi
+
+if test x"${install_sh+set}" != xset; then
+  case $am_aux_dir in
+  *\ * | *\	*)
+    install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;;
+  *)
+    install_sh="\${SHELL} $am_aux_dir/install-sh"
+  esac
+fi
+
+# Installed binaries are usually stripped using 'strip' when the user
+# run "make install-strip".  However 'strip' might not be the right
+# tool to use in cross-compilation environments, therefore Automake
+# will honor the 'STRIP' environment variable to overrule this program.
+if test "$cross_compiling" != no; then
+  if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args.
+set dummy ${ac_tool_prefix}strip; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_STRIP+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$STRIP"; then
+  ac_cv_prog_STRIP="$STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_STRIP="${ac_tool_prefix}strip"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+STRIP=$ac_cv_prog_STRIP
+if test -n "$STRIP"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5
+$as_echo "$STRIP" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_STRIP"; then
+  ac_ct_STRIP=$STRIP
+  # Extract the first word of "strip", so it can be a program name with args.
+set dummy strip; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_STRIP+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_STRIP"; then
+  ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_STRIP="strip"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP
+if test -n "$ac_ct_STRIP"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5
+$as_echo "$ac_ct_STRIP" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_STRIP" = x; then
+    STRIP=":"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    STRIP=$ac_ct_STRIP
+  fi
+else
+  STRIP="$ac_cv_prog_STRIP"
+fi
+
+fi
+INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5
+$as_echo_n "checking for a thread-safe mkdir -p... " >&6; }
+if test -z "$MKDIR_P"; then
+  if ${ac_cv_path_mkdir+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_prog in mkdir gmkdir; do
+	 for ac_exec_ext in '' $ac_executable_extensions; do
+	   as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext" || continue
+	   case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #(
+	     'mkdir (GNU coreutils) '* | \
+	     'mkdir (coreutils) '* | \
+	     'mkdir (fileutils) '4.1*)
+	       ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext
+	       break 3;;
+	   esac
+	 done
+       done
+  done
+IFS=$as_save_IFS
+
+fi
+
+  test -d ./--version && rmdir ./--version
+  if test "${ac_cv_path_mkdir+set}" = set; then
+    MKDIR_P="$ac_cv_path_mkdir -p"
+  else
+    # As a last resort, use the slow shell script.  Don't cache a
+    # value for MKDIR_P within a source directory, because that will
+    # break other packages using the cache if that directory is
+    # removed, or if the value is a relative name.
+    MKDIR_P="$ac_install_sh -d"
+  fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5
+$as_echo "$MKDIR_P" >&6; }
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5
+$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; }
+set x ${MAKE-make}
+ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'`
+if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat >conftest.make <<\_ACEOF
+SHELL = /bin/sh
+all:
+	@echo '@@@%%%=$(MAKE)=@@@%%%'
+_ACEOF
+# GNU make sometimes prints "make[1]: Entering ...", which would confuse us.
+case `${MAKE-make} -f conftest.make 2>/dev/null` in
+  *@@@%%%=?*=@@@%%%*)
+    eval ac_cv_prog_make_${ac_make}_set=yes;;
+  *)
+    eval ac_cv_prog_make_${ac_make}_set=no;;
+esac
+rm -f conftest.make
+fi
+if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+  SET_MAKE=
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+  SET_MAKE="MAKE=${MAKE-make}"
+fi
+
+rm -rf .tst 2>/dev/null
+mkdir .tst 2>/dev/null
+if test -d .tst; then
+  am__leading_dot=.
+else
+  am__leading_dot=_
+fi
+rmdir .tst 2>/dev/null
+
+if test "`cd $srcdir && pwd`" != "`pwd`"; then
+  # Use -I$(srcdir) only when $(srcdir) != ., so that make's output
+  # is not polluted with repeated "-I."
+  am__isrc=' -I$(srcdir)'
+  # test to see if srcdir already configured
+  if test -f $srcdir/config.status; then
+    as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5
+  fi
+fi
+
+# test whether we have cygpath
+if test -z "$CYGPATH_W"; then
+  if (cygpath --version) >/dev/null 2>/dev/null; then
+    CYGPATH_W='cygpath -w'
+  else
+    CYGPATH_W=echo
+  fi
+fi
+
+
+# Define the identity of the package.
+ PACKAGE='spl'
+ VERSION='0.6.5.6'
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE "$PACKAGE"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define VERSION "$VERSION"
+_ACEOF
+
+# Some tools Automake needs.
+
+ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"}
+
+
+AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"}
+
+
+AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"}
+
+
+AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"}
+
+
+MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"}
+
+# For better backward compatibility.  To be removed once Automake 1.9.x
+# dies out for good.  For more background, see:
+# <http://lists.gnu.org/archive/html/automake/2012-07/msg00001.html>
+# <http://lists.gnu.org/archive/html/automake/2012-07/msg00014.html>
+mkdir_p='$(MKDIR_P)'
+
+# We need awk for the "check" target (and possibly the TAP driver).  The
+# system "awk" is bad on some platforms.
+# Always define AMTAR for backward compatibility.  Yes, it's still used
+# in the wild :-(  We should find a proper way to deprecate it ...
+AMTAR='$${TAR-tar}'
+
+
+# We'll loop over all known methods to create a tar archive until one works.
+_am_tools='gnutar  pax cpio none'
+
+am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'
+
+
+
+
+
+
+# POSIX will say in a future version that running "rm -f" with no argument
+# is OK; and we want to be able to make that assumption in our Makefile
+# recipes.  So use an aggressive probe to check that the usage we want is
+# actually supported "in the wild" to an acceptable degree.
+# See automake bug#10828.
+# To make any issue more visible, cause the running configure to be aborted
+# by default if the 'rm' program in use doesn't match our expectations; the
+# user can still override this though.
+if rm -f && rm -fr && rm -rf; then : OK; else
+  cat >&2 <<'END'
+Oops!
+
+Your 'rm' program seems unable to run without file operands specified
+on the command line, even when the '-f' option is present.  This is contrary
+to the behaviour of most rm programs out there, and not conforming with
+the upcoming POSIX standard: <http://austingroupbugs.net/view.php?id=542>
+
+Please tell bug-automake@gnu.org about your system, including the value
+of your $PATH and any error possibly output before this message.  This
+can help us improve future automake versions.
+
+END
+  if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then
+    echo 'Configuration will proceed anyway, since you have set the' >&2
+    echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2
+    echo >&2
+  else
+    cat >&2 <<'END'
+Aborting the configuration process, to ensure you take notice of the issue.
+
+You can download and install GNU coreutils to get an 'rm' implementation
+that behaves properly: <http://www.gnu.org/software/coreutils/>.
+
+If you want to complete the configuration process using your problematic
+'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM
+to "yes", and re-run configure.
+
+END
+    as_fn_error $? "Your 'rm' program is bad, sorry." "$LINENO" 5
+  fi
+fi
+
+ac_config_headers="$ac_config_headers spl_config.h"
+
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}gcc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="${ac_tool_prefix}gcc"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+  ac_ct_CC=$CC
+  # Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_CC+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CC="gcc"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_CC" = x; then
+    CC=""
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    CC=$ac_ct_CC
+  fi
+else
+  CC="$ac_cv_prog_CC"
+fi
+
+if test -z "$CC"; then
+          if test -n "$ac_tool_prefix"; then
+    # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}cc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="${ac_tool_prefix}cc"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  fi
+fi
+if test -z "$CC"; then
+  # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+  ac_prog_rejected=no
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
+       ac_prog_rejected=yes
+       continue
+     fi
+    ac_cv_prog_CC="cc"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+if test $ac_prog_rejected = yes; then
+  # We found a bogon in the path, so make sure we never use it.
+  set dummy $ac_cv_prog_CC
+  shift
+  if test $# != 0; then
+    # We chose a different compiler from the bogus one.
+    # However, it has the same basename, so the bogon will be chosen
+    # first if we set CC to just the basename; use the full file name.
+    shift
+    ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
+  fi
+fi
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$CC"; then
+  if test -n "$ac_tool_prefix"; then
+  for ac_prog in cl.exe
+  do
+    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+    test -n "$CC" && break
+  done
+fi
+if test -z "$CC"; then
+  ac_ct_CC=$CC
+  for ac_prog in cl.exe
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_CC+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CC="$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  test -n "$ac_ct_CC" && break
+done
+
+  if test "x$ac_ct_CC" = x; then
+    CC=""
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    CC=$ac_ct_CC
+  fi
+fi
+
+fi
+
+
+test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "no acceptable C compiler found in \$PATH
+See \`config.log' for more details" "$LINENO" 5; }
+
+# Provide some information about the compiler.
+$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5
+set X $ac_compile
+ac_compiler=$2
+for ac_option in --version -v -V -qversion; do
+  { { ac_try="$ac_compiler $ac_option >&5"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_compiler $ac_option >&5") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    sed '10a\
+... rest of stderr output deleted ...
+         10q' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+  fi
+  rm -f conftest.er1 conftest.err
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+done
+
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out"
+# Try to create an executable without -o first, disregard a.out.
+# It will help us diagnose broken compilers, and finding out an intuition
+# of exeext.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5
+$as_echo_n "checking whether the C compiler works... " >&6; }
+ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
+
+# The possible output files:
+ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*"
+
+ac_rmfiles=
+for ac_file in $ac_files
+do
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
+    * ) ac_rmfiles="$ac_rmfiles $ac_file";;
+  esac
+done
+rm -f $ac_rmfiles
+
+if { { ac_try="$ac_link_default"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_link_default") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then :
+  # Autoconf-2.13 could set the ac_cv_exeext variable to `no'.
+# So ignore a value of `no', otherwise this would lead to `EXEEXT = no'
+# in a Makefile.  We should not override ac_cv_exeext if it was cached,
+# so that the user can short-circuit this test for compilers unknown to
+# Autoconf.
+for ac_file in $ac_files ''
+do
+  test -f "$ac_file" || continue
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj )
+	;;
+    [ab].out )
+	# We found the default executable, but exeext='' is most
+	# certainly right.
+	break;;
+    *.* )
+	if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no;
+	then :; else
+	   ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+	fi
+	# We set ac_cv_exeext here because the later test for it is not
+	# safe: cross compilers may not add the suffix if given an `-o'
+	# argument, so we may need to know it at that point already.
+	# Even if this section looks crufty: it has the advantage of
+	# actually working.
+	break;;
+    * )
+	break;;
+  esac
+done
+test "$ac_cv_exeext" = no && ac_cv_exeext=
+
+else
+  ac_file=''
+fi
+if test -z "$ac_file"; then :
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+$as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "C compiler cannot create executables
+See \`config.log' for more details" "$LINENO" 5; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5
+$as_echo_n "checking for C compiler default output file name... " >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5
+$as_echo "$ac_file" >&6; }
+ac_exeext=$ac_cv_exeext
+
+rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out
+ac_clean_files=$ac_clean_files_save
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5
+$as_echo_n "checking for suffix of executables... " >&6; }
+if { { ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_link") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then :
+  # If both `conftest.exe' and `conftest' are `present' (well, observable)
+# catch `conftest.exe'.  For instance with Cygwin, `ls conftest' will
+# work properly (i.e., refer to `conftest.exe'), while it won't with
+# `rm'.
+for ac_file in conftest.exe conftest conftest.*; do
+  test -f "$ac_file" || continue
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
+    *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+	  break;;
+    * ) break;;
+  esac
+done
+else
+  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+rm -f conftest conftest$ac_cv_exeext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5
+$as_echo "$ac_cv_exeext" >&6; }
+
+rm -f conftest.$ac_ext
+EXEEXT=$ac_cv_exeext
+ac_exeext=$EXEEXT
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdio.h>
+int
+main ()
+{
+FILE *f = fopen ("conftest.out", "w");
+ return ferror (f) || fclose (f) != 0;
+
+  ;
+  return 0;
+}
+_ACEOF
+ac_clean_files="$ac_clean_files conftest.out"
+# Check that the compiler produces executables we can run.  If not, either
+# the compiler is broken, or we cross compile.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5
+$as_echo_n "checking whether we are cross compiling... " >&6; }
+if test "$cross_compiling" != yes; then
+  { { ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_link") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+  if { ac_try='./conftest$ac_cv_exeext'
+  { { case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then
+    cross_compiling=no
+  else
+    if test "$cross_compiling" = maybe; then
+	cross_compiling=yes
+    else
+	{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details" "$LINENO" 5; }
+    fi
+  fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5
+$as_echo "$cross_compiling" >&6; }
+
+rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out
+ac_clean_files=$ac_clean_files_save
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5
+$as_echo_n "checking for suffix of object files... " >&6; }
+if ${ac_cv_objext+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.o conftest.obj
+if { { ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_compile") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then :
+  for ac_file in conftest.o conftest.obj conftest.*; do
+  test -f "$ac_file" || continue;
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;;
+    *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
+       break;;
+  esac
+done
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot compute suffix of object files: cannot compile
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+rm -f conftest.$ac_cv_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5
+$as_echo "$ac_cv_objext" >&6; }
+OBJEXT=$ac_cv_objext
+ac_objext=$OBJEXT
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5
+$as_echo_n "checking whether we are using the GNU C compiler... " >&6; }
+if ${ac_cv_c_compiler_gnu+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+#ifndef __GNUC__
+       choke me
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_compiler_gnu=yes
+else
+  ac_compiler_gnu=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_c_compiler_gnu=$ac_compiler_gnu
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5
+$as_echo "$ac_cv_c_compiler_gnu" >&6; }
+if test $ac_compiler_gnu = yes; then
+  GCC=yes
+else
+  GCC=
+fi
+ac_test_CFLAGS=${CFLAGS+set}
+ac_save_CFLAGS=$CFLAGS
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5
+$as_echo_n "checking whether $CC accepts -g... " >&6; }
+if ${ac_cv_prog_cc_g+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_save_c_werror_flag=$ac_c_werror_flag
+   ac_c_werror_flag=yes
+   ac_cv_prog_cc_g=no
+   CFLAGS="-g"
+   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_prog_cc_g=yes
+else
+  CFLAGS=""
+      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+else
+  ac_c_werror_flag=$ac_save_c_werror_flag
+	 CFLAGS="-g"
+	 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_prog_cc_g=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+   ac_c_werror_flag=$ac_save_c_werror_flag
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5
+$as_echo "$ac_cv_prog_cc_g" >&6; }
+if test "$ac_test_CFLAGS" = set; then
+  CFLAGS=$ac_save_CFLAGS
+elif test $ac_cv_prog_cc_g = yes; then
+  if test "$GCC" = yes; then
+    CFLAGS="-g -O2"
+  else
+    CFLAGS="-g"
+  fi
+else
+  if test "$GCC" = yes; then
+    CFLAGS="-O2"
+  else
+    CFLAGS=
+  fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5
+$as_echo_n "checking for $CC option to accept ISO C89... " >&6; }
+if ${ac_cv_prog_cc_c89+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_cv_prog_cc_c89=no
+ac_save_CC=$CC
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdarg.h>
+#include <stdio.h>
+struct stat;
+/* Most of the following tests are stolen from RCS 5.7's src/conf.sh.  */
+struct buf { int x; };
+FILE * (*rcsopen) (struct buf *, struct stat *, int);
+static char *e (p, i)
+     char **p;
+     int i;
+{
+  return p[i];
+}
+static char *f (char * (*g) (char **, int), char **p, ...)
+{
+  char *s;
+  va_list v;
+  va_start (v,p);
+  s = g (p, va_arg (v,int));
+  va_end (v);
+  return s;
+}
+
+/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default.  It has
+   function prototypes and stuff, but not '\xHH' hex character constants.
+   These don't provoke an error unfortunately, instead are silently treated
+   as 'x'.  The following induces an error, until -std is added to get
+   proper ANSI mode.  Curiously '\x00'!='x' always comes out true, for an
+   array size at least.  It's necessary to write '\x00'==0 to get something
+   that's true only with -std.  */
+int osf4_cc_array ['\x00' == 0 ? 1 : -1];
+
+/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters
+   inside strings and character constants.  */
+#define FOO(x) 'x'
+int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1];
+
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
+int argc;
+char **argv;
+int
+main ()
+{
+return f (e, argv, 0) != argv[0]  ||  f (e, argv, 1) != argv[1];
+  ;
+  return 0;
+}
+_ACEOF
+for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \
+	-Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+  CC="$ac_save_CC $ac_arg"
+  if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_prog_cc_c89=$ac_arg
+fi
+rm -f core conftest.err conftest.$ac_objext
+  test "x$ac_cv_prog_cc_c89" != "xno" && break
+done
+rm -f conftest.$ac_ext
+CC=$ac_save_CC
+
+fi
+# AC_CACHE_VAL
+case "x$ac_cv_prog_cc_c89" in
+  x)
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
+$as_echo "none needed" >&6; } ;;
+  xno)
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
+$as_echo "unsupported" >&6; } ;;
+  *)
+    CC="$CC $ac_cv_prog_cc_c89"
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5
+$as_echo "$ac_cv_prog_cc_c89" >&6; } ;;
+esac
+if test "x$ac_cv_prog_cc_c89" != xno; then :
+
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5
+$as_echo_n "checking whether $CC understands -c and -o together... " >&6; }
+if ${am_cv_prog_cc_c_o+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+  # Make sure it works both with $CC and with simple cc.
+  # Following AC_PROG_CC_C_O, we do the test twice because some
+  # compilers refuse to overwrite an existing .o file with -o,
+  # though they will create one.
+  am_cv_prog_cc_c_o=yes
+  for am_i in 1 2; do
+    if { echo "$as_me:$LINENO: $CC -c conftest.$ac_ext -o conftest2.$ac_objext" >&5
+   ($CC -c conftest.$ac_ext -o conftest2.$ac_objext) >&5 2>&5
+   ac_status=$?
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
+   (exit $ac_status); } \
+         && test -f conftest2.$ac_objext; then
+      : OK
+    else
+      am_cv_prog_cc_c_o=no
+      break
+    fi
+  done
+  rm -f core conftest*
+  unset am_i
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5
+$as_echo "$am_cv_prog_cc_c_o" >&6; }
+if test "$am_cv_prog_cc_c_o" != yes; then
+   # Losing compiler, so override with the script.
+   # FIXME: It is wrong to rewrite CC.
+   # But if we don't then we get into trouble of one sort or another.
+   # A longer-term fix would be to have automake use am__CC in this case,
+   # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)"
+   CC="$am_aux_dir/compile $CC"
+fi
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+DEPDIR="${am__leading_dot}deps"
+
+ac_config_commands="$ac_config_commands depfiles"
+
+
+am_make=${MAKE-make}
+cat > confinc << 'END'
+am__doit:
+	@echo this is the am__doit target
+.PHONY: am__doit
+END
+# If we don't find an include directive, just comment out the code.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5
+$as_echo_n "checking for style of include used by $am_make... " >&6; }
+am__include="#"
+am__quote=
+_am_result=none
+# First try GNU make style include.
+echo "include confinc" > confmf
+# Ignore all kinds of additional output from 'make'.
+case `$am_make -s -f confmf 2> /dev/null` in #(
+*the\ am__doit\ target*)
+  am__include=include
+  am__quote=
+  _am_result=GNU
+  ;;
+esac
+# Now try BSD make style include.
+if test "$am__include" = "#"; then
+   echo '.include "confinc"' > confmf
+   case `$am_make -s -f confmf 2> /dev/null` in #(
+   *the\ am__doit\ target*)
+     am__include=.include
+     am__quote="\""
+     _am_result=BSD
+     ;;
+   esac
+fi
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5
+$as_echo "$_am_result" >&6; }
+rm -f confinc confmf
+
+# Check whether --enable-dependency-tracking was given.
+if test "${enable_dependency_tracking+set}" = set; then :
+  enableval=$enable_dependency_tracking;
+fi
+
+if test "x$enable_dependency_tracking" != xno; then
+  am_depcomp="$ac_aux_dir/depcomp"
+  AMDEPBACKSLASH='\'
+  am__nodep='_no'
+fi
+ if test "x$enable_dependency_tracking" != xno; then
+  AMDEP_TRUE=
+  AMDEP_FALSE='#'
+else
+  AMDEP_TRUE='#'
+  AMDEP_FALSE=
+fi
+
+
+
+depcc="$CC"   am_compiler_list=
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5
+$as_echo_n "checking dependency style of $depcc... " >&6; }
+if ${am_cv_CC_dependencies_compiler_type+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
+  # We make a subdir and do the tests there.  Otherwise we can end up
+  # making bogus files that we don't know about and never remove.  For
+  # instance it was reported that on HP-UX the gcc test will end up
+  # making a dummy file named 'D' -- because '-MD' means "put the output
+  # in D".
+  rm -rf conftest.dir
+  mkdir conftest.dir
+  # Copy depcomp to subdir because otherwise we won't find it if we're
+  # using a relative directory.
+  cp "$am_depcomp" conftest.dir
+  cd conftest.dir
+  # We will build objects and dependencies in a subdirectory because
+  # it helps to detect inapplicable dependency modes.  For instance
+  # both Tru64's cc and ICC support -MD to output dependencies as a
+  # side effect of compilation, but ICC will put the dependencies in
+  # the current directory while Tru64 will put them in the object
+  # directory.
+  mkdir sub
+
+  am_cv_CC_dependencies_compiler_type=none
+  if test "$am_compiler_list" = ""; then
+     am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp`
+  fi
+  am__universal=false
+  case " $depcc " in #(
+     *\ -arch\ *\ -arch\ *) am__universal=true ;;
+     esac
+
+  for depmode in $am_compiler_list; do
+    # Setup a source with many dependencies, because some compilers
+    # like to wrap large dependency lists on column 80 (with \), and
+    # we should not choose a depcomp mode which is confused by this.
+    #
+    # We need to recreate these files for each test, as the compiler may
+    # overwrite some of them when testing with obscure command lines.
+    # This happens at least with the AIX C compiler.
+    : > sub/conftest.c
+    for i in 1 2 3 4 5 6; do
+      echo '#include "conftst'$i'.h"' >> sub/conftest.c
+      # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with
+      # Solaris 10 /bin/sh.
+      echo '/* dummy */' > sub/conftst$i.h
+    done
+    echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
+
+    # We check with '-c' and '-o' for the sake of the "dashmstdout"
+    # mode.  It turns out that the SunPro C++ compiler does not properly
+    # handle '-M -o', and we need to detect this.  Also, some Intel
+    # versions had trouble with output in subdirs.
+    am__obj=sub/conftest.${OBJEXT-o}
+    am__minus_obj="-o $am__obj"
+    case $depmode in
+    gcc)
+      # This depmode causes a compiler race in universal mode.
+      test "$am__universal" = false || continue
+      ;;
+    nosideeffect)
+      # After this tag, mechanisms are not by side-effect, so they'll
+      # only be used when explicitly requested.
+      if test "x$enable_dependency_tracking" = xyes; then
+	continue
+      else
+	break
+      fi
+      ;;
+    msvc7 | msvc7msys | msvisualcpp | msvcmsys)
+      # This compiler won't grok '-c -o', but also, the minuso test has
+      # not run yet.  These depmodes are late enough in the game, and
+      # so weak that their functioning should not be impacted.
+      am__obj=conftest.${OBJEXT-o}
+      am__minus_obj=
+      ;;
+    none) break ;;
+    esac
+    if depmode=$depmode \
+       source=sub/conftest.c object=$am__obj \
+       depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
+       $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \
+         >/dev/null 2>conftest.err &&
+       grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 &&
+       grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
+       grep $am__obj sub/conftest.Po > /dev/null 2>&1 &&
+       ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
+      # icc doesn't choke on unknown options, it will just issue warnings
+      # or remarks (even with -Werror).  So we grep stderr for any message
+      # that says an option was ignored or not supported.
+      # When given -MP, icc 7.0 and 7.1 complain thusly:
+      #   icc: Command line warning: ignoring option '-M'; no argument required
+      # The diagnosis changed in icc 8.0:
+      #   icc: Command line remark: option '-MP' not supported
+      if (grep 'ignoring option' conftest.err ||
+          grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
+        am_cv_CC_dependencies_compiler_type=$depmode
+        break
+      fi
+    fi
+  done
+
+  cd ..
+  rm -rf conftest.dir
+else
+  am_cv_CC_dependencies_compiler_type=none
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5
+$as_echo "$am_cv_CC_dependencies_compiler_type" >&6; }
+CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type
+
+ if
+  test "x$enable_dependency_tracking" != xno \
+  && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then
+  am__fastdepCC_TRUE=
+  am__fastdepCC_FALSE='#'
+else
+  am__fastdepCC_TRUE='#'
+  am__fastdepCC_FALSE=
+fi
+
+
+case `pwd` in
+  *\ * | *\	*)
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&5
+$as_echo "$as_me: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&2;} ;;
+esac
+
+
+
+macro_version='2.4.6'
+macro_revision='2.4.6'
+
+
+
+
+
+
+
+
+
+
+
+
+
+ltmain=$ac_aux_dir/ltmain.sh
+
+# Backslashify metacharacters that are still active within
+# double-quoted strings.
+sed_quote_subst='s/\(["`$\\]\)/\\\1/g'
+
+# Same as above, but do not quote variable references.
+double_quote_subst='s/\(["`\\]\)/\\\1/g'
+
+# Sed substitution to delay expansion of an escaped shell variable in a
+# double_quote_subst'ed string.
+delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g'
+
+# Sed substitution to delay expansion of an escaped single quote.
+delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g'
+
+# Sed substitution to avoid accidental globbing in evaled expressions
+no_glob_subst='s/\*/\\\*/g'
+
+ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO
+ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to print strings" >&5
+$as_echo_n "checking how to print strings... " >&6; }
+# Test print first, because it will be a builtin if present.
+if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \
+   test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then
+  ECHO='print -r --'
+elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then
+  ECHO='printf %s\n'
+else
+  # Use this function as a fallback that always works.
+  func_fallback_echo ()
+  {
+    eval 'cat <<_LTECHO_EOF
+$1
+_LTECHO_EOF'
+  }
+  ECHO='func_fallback_echo'
+fi
+
+# func_echo_all arg...
+# Invoke $ECHO with all args, space-separated.
+func_echo_all ()
+{
+    $ECHO ""
+}
+
+case $ECHO in
+  printf*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: printf" >&5
+$as_echo "printf" >&6; } ;;
+  print*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: print -r" >&5
+$as_echo "print -r" >&6; } ;;
+  *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: cat" >&5
+$as_echo "cat" >&6; } ;;
+esac
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5
+$as_echo_n "checking for a sed that does not truncate output... " >&6; }
+if ${ac_cv_path_SED+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+            ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/
+     for ac_i in 1 2 3 4 5 6 7; do
+       ac_script="$ac_script$as_nl$ac_script"
+     done
+     echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed
+     { ac_script=; unset ac_script;}
+     if test -z "$SED"; then
+  ac_path_SED_found=false
+  # Loop through the user's path and test for each of PROGNAME-LIST
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_prog in sed gsed; do
+    for ac_exec_ext in '' $ac_executable_extensions; do
+      ac_path_SED="$as_dir/$ac_prog$ac_exec_ext"
+      as_fn_executable_p "$ac_path_SED" || continue
+# Check for GNU ac_path_SED and select it if it is found.
+  # Check for GNU $ac_path_SED
+case `"$ac_path_SED" --version 2>&1` in
+*GNU*)
+  ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;;
+*)
+  ac_count=0
+  $as_echo_n 0123456789 >"conftest.in"
+  while :
+  do
+    cat "conftest.in" "conftest.in" >"conftest.tmp"
+    mv "conftest.tmp" "conftest.in"
+    cp "conftest.in" "conftest.nl"
+    $as_echo '' >> "conftest.nl"
+    "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break
+    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+    as_fn_arith $ac_count + 1 && ac_count=$as_val
+    if test $ac_count -gt ${ac_path_SED_max-0}; then
+      # Best one so far, save it but keep looking for a better one
+      ac_cv_path_SED="$ac_path_SED"
+      ac_path_SED_max=$ac_count
+    fi
+    # 10*(2^10) chars as input seems more than enough
+    test $ac_count -gt 10 && break
+  done
+  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+      $ac_path_SED_found && break 3
+    done
+  done
+  done
+IFS=$as_save_IFS
+  if test -z "$ac_cv_path_SED"; then
+    as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5
+  fi
+else
+  ac_cv_path_SED=$SED
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5
+$as_echo "$ac_cv_path_SED" >&6; }
+ SED="$ac_cv_path_SED"
+  rm -f conftest.sed
+
+test -z "$SED" && SED=sed
+Xsed="$SED -e 1s/^X//"
+
+
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5
+$as_echo_n "checking for grep that handles long lines and -e... " >&6; }
+if ${ac_cv_path_GREP+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -z "$GREP"; then
+  ac_path_GREP_found=false
+  # Loop through the user's path and test for each of PROGNAME-LIST
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_prog in grep ggrep; do
+    for ac_exec_ext in '' $ac_executable_extensions; do
+      ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext"
+      as_fn_executable_p "$ac_path_GREP" || continue
+# Check for GNU ac_path_GREP and select it if it is found.
+  # Check for GNU $ac_path_GREP
+case `"$ac_path_GREP" --version 2>&1` in
+*GNU*)
+  ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;;
+*)
+  ac_count=0
+  $as_echo_n 0123456789 >"conftest.in"
+  while :
+  do
+    cat "conftest.in" "conftest.in" >"conftest.tmp"
+    mv "conftest.tmp" "conftest.in"
+    cp "conftest.in" "conftest.nl"
+    $as_echo 'GREP' >> "conftest.nl"
+    "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+    as_fn_arith $ac_count + 1 && ac_count=$as_val
+    if test $ac_count -gt ${ac_path_GREP_max-0}; then
+      # Best one so far, save it but keep looking for a better one
+      ac_cv_path_GREP="$ac_path_GREP"
+      ac_path_GREP_max=$ac_count
+    fi
+    # 10*(2^10) chars as input seems more than enough
+    test $ac_count -gt 10 && break
+  done
+  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+      $ac_path_GREP_found && break 3
+    done
+  done
+  done
+IFS=$as_save_IFS
+  if test -z "$ac_cv_path_GREP"; then
+    as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+  fi
+else
+  ac_cv_path_GREP=$GREP
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5
+$as_echo "$ac_cv_path_GREP" >&6; }
+ GREP="$ac_cv_path_GREP"
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5
+$as_echo_n "checking for egrep... " >&6; }
+if ${ac_cv_path_EGREP+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if echo a | $GREP -E '(a|b)' >/dev/null 2>&1
+   then ac_cv_path_EGREP="$GREP -E"
+   else
+     if test -z "$EGREP"; then
+  ac_path_EGREP_found=false
+  # Loop through the user's path and test for each of PROGNAME-LIST
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_prog in egrep; do
+    for ac_exec_ext in '' $ac_executable_extensions; do
+      ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext"
+      as_fn_executable_p "$ac_path_EGREP" || continue
+# Check for GNU ac_path_EGREP and select it if it is found.
+  # Check for GNU $ac_path_EGREP
+case `"$ac_path_EGREP" --version 2>&1` in
+*GNU*)
+  ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;;
+*)
+  ac_count=0
+  $as_echo_n 0123456789 >"conftest.in"
+  while :
+  do
+    cat "conftest.in" "conftest.in" >"conftest.tmp"
+    mv "conftest.tmp" "conftest.in"
+    cp "conftest.in" "conftest.nl"
+    $as_echo 'EGREP' >> "conftest.nl"
+    "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+    as_fn_arith $ac_count + 1 && ac_count=$as_val
+    if test $ac_count -gt ${ac_path_EGREP_max-0}; then
+      # Best one so far, save it but keep looking for a better one
+      ac_cv_path_EGREP="$ac_path_EGREP"
+      ac_path_EGREP_max=$ac_count
+    fi
+    # 10*(2^10) chars as input seems more than enough
+    test $ac_count -gt 10 && break
+  done
+  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+      $ac_path_EGREP_found && break 3
+    done
+  done
+  done
+IFS=$as_save_IFS
+  if test -z "$ac_cv_path_EGREP"; then
+    as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+  fi
+else
+  ac_cv_path_EGREP=$EGREP
+fi
+
+   fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5
+$as_echo "$ac_cv_path_EGREP" >&6; }
+ EGREP="$ac_cv_path_EGREP"
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5
+$as_echo_n "checking for fgrep... " >&6; }
+if ${ac_cv_path_FGREP+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if echo 'ab*c' | $GREP -F 'ab*c' >/dev/null 2>&1
+   then ac_cv_path_FGREP="$GREP -F"
+   else
+     if test -z "$FGREP"; then
+  ac_path_FGREP_found=false
+  # Loop through the user's path and test for each of PROGNAME-LIST
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_prog in fgrep; do
+    for ac_exec_ext in '' $ac_executable_extensions; do
+      ac_path_FGREP="$as_dir/$ac_prog$ac_exec_ext"
+      as_fn_executable_p "$ac_path_FGREP" || continue
+# Check for GNU ac_path_FGREP and select it if it is found.
+  # Check for GNU $ac_path_FGREP
+case `"$ac_path_FGREP" --version 2>&1` in
+*GNU*)
+  ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_found=:;;
+*)
+  ac_count=0
+  $as_echo_n 0123456789 >"conftest.in"
+  while :
+  do
+    cat "conftest.in" "conftest.in" >"conftest.tmp"
+    mv "conftest.tmp" "conftest.in"
+    cp "conftest.in" "conftest.nl"
+    $as_echo 'FGREP' >> "conftest.nl"
+    "$ac_path_FGREP" FGREP < "conftest.nl" >"conftest.out" 2>/dev/null || break
+    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+    as_fn_arith $ac_count + 1 && ac_count=$as_val
+    if test $ac_count -gt ${ac_path_FGREP_max-0}; then
+      # Best one so far, save it but keep looking for a better one
+      ac_cv_path_FGREP="$ac_path_FGREP"
+      ac_path_FGREP_max=$ac_count
+    fi
+    # 10*(2^10) chars as input seems more than enough
+    test $ac_count -gt 10 && break
+  done
+  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+      $ac_path_FGREP_found && break 3
+    done
+  done
+  done
+IFS=$as_save_IFS
+  if test -z "$ac_cv_path_FGREP"; then
+    as_fn_error $? "no acceptable fgrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+  fi
+else
+  ac_cv_path_FGREP=$FGREP
+fi
+
+   fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_FGREP" >&5
+$as_echo "$ac_cv_path_FGREP" >&6; }
+ FGREP="$ac_cv_path_FGREP"
+
+
+test -z "$GREP" && GREP=grep
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# Check whether --with-gnu-ld was given.
+if test "${with_gnu_ld+set}" = set; then :
+  withval=$with_gnu_ld; test no = "$withval" || with_gnu_ld=yes
+else
+  with_gnu_ld=no
+fi
+
+ac_prog=ld
+if test yes = "$GCC"; then
+  # Check if gcc -print-prog-name=ld gives a path.
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5
+$as_echo_n "checking for ld used by $CC... " >&6; }
+  case $host in
+  *-*-mingw*)
+    # gcc leaves a trailing carriage return, which upsets mingw
+    ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
+  *)
+    ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
+  esac
+  case $ac_prog in
+    # Accept absolute paths.
+    [\\/]* | ?:[\\/]*)
+      re_direlt='/[^/][^/]*/\.\./'
+      # Canonicalize the pathname of ld
+      ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'`
+      while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do
+	ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"`
+      done
+      test -z "$LD" && LD=$ac_prog
+      ;;
+  "")
+    # If it fails, then pretend we aren't using GCC.
+    ac_prog=ld
+    ;;
+  *)
+    # If it is relative, then search for the first ld in PATH.
+    with_gnu_ld=unknown
+    ;;
+  esac
+elif test yes = "$with_gnu_ld"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5
+$as_echo_n "checking for GNU ld... " >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5
+$as_echo_n "checking for non-GNU ld... " >&6; }
+fi
+if ${lt_cv_path_LD+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -z "$LD"; then
+  lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR
+  for ac_dir in $PATH; do
+    IFS=$lt_save_ifs
+    test -z "$ac_dir" && ac_dir=.
+    if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+      lt_cv_path_LD=$ac_dir/$ac_prog
+      # Check to see if the program is GNU ld.  I'd rather use --version,
+      # but apparently some variants of GNU ld only accept -v.
+      # Break only if it was the GNU/non-GNU ld that we prefer.
+      case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in
+      *GNU* | *'with BFD'*)
+	test no != "$with_gnu_ld" && break
+	;;
+      *)
+	test yes != "$with_gnu_ld" && break
+	;;
+      esac
+    fi
+  done
+  IFS=$lt_save_ifs
+else
+  lt_cv_path_LD=$LD # Let the user override the test with a path.
+fi
+fi
+
+LD=$lt_cv_path_LD
+if test -n "$LD"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LD" >&5
+$as_echo "$LD" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5
+$as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; }
+if ${lt_cv_prog_gnu_ld+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  # I'd rather use --version here, but apparently some GNU lds only accept -v.
+case `$LD -v 2>&1 </dev/null` in
+*GNU* | *'with BFD'*)
+  lt_cv_prog_gnu_ld=yes
+  ;;
+*)
+  lt_cv_prog_gnu_ld=no
+  ;;
+esac
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_gnu_ld" >&5
+$as_echo "$lt_cv_prog_gnu_ld" >&6; }
+with_gnu_ld=$lt_cv_prog_gnu_ld
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for BSD- or MS-compatible name lister (nm)" >&5
+$as_echo_n "checking for BSD- or MS-compatible name lister (nm)... " >&6; }
+if ${lt_cv_path_NM+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$NM"; then
+  # Let the user override the test.
+  lt_cv_path_NM=$NM
+else
+  lt_nm_to_check=${ac_tool_prefix}nm
+  if test -n "$ac_tool_prefix" && test "$build" = "$host"; then
+    lt_nm_to_check="$lt_nm_to_check nm"
+  fi
+  for lt_tmp_nm in $lt_nm_to_check; do
+    lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR
+    for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do
+      IFS=$lt_save_ifs
+      test -z "$ac_dir" && ac_dir=.
+      tmp_nm=$ac_dir/$lt_tmp_nm
+      if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext"; then
+	# Check to see if the nm accepts a BSD-compat flag.
+	# Adding the 'sed 1q' prevents false positives on HP-UX, which says:
+	#   nm: unknown option "B" ignored
+	# Tru64's nm complains that /dev/null is an invalid object file
+	# MSYS converts /dev/null to NUL, MinGW nm treats NUL as empty
+	case $build_os in
+	mingw*) lt_bad_file=conftest.nm/nofile ;;
+	*) lt_bad_file=/dev/null ;;
+	esac
+	case `"$tmp_nm" -B $lt_bad_file 2>&1 | sed '1q'` in
+	*$lt_bad_file* | *'Invalid file or object type'*)
+	  lt_cv_path_NM="$tmp_nm -B"
+	  break 2
+	  ;;
+	*)
+	  case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in
+	  */dev/null*)
+	    lt_cv_path_NM="$tmp_nm -p"
+	    break 2
+	    ;;
+	  *)
+	    lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but
+	    continue # so that we can try to find one that supports BSD flags
+	    ;;
+	  esac
+	  ;;
+	esac
+      fi
+    done
+    IFS=$lt_save_ifs
+  done
+  : ${lt_cv_path_NM=no}
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_NM" >&5
+$as_echo "$lt_cv_path_NM" >&6; }
+if test no != "$lt_cv_path_NM"; then
+  NM=$lt_cv_path_NM
+else
+  # Didn't find any BSD compatible name lister, look for dumpbin.
+  if test -n "$DUMPBIN"; then :
+    # Let the user override the test.
+  else
+    if test -n "$ac_tool_prefix"; then
+  for ac_prog in dumpbin "link -dump"
+  do
+    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_DUMPBIN+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$DUMPBIN"; then
+  ac_cv_prog_DUMPBIN="$DUMPBIN" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_DUMPBIN="$ac_tool_prefix$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+DUMPBIN=$ac_cv_prog_DUMPBIN
+if test -n "$DUMPBIN"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DUMPBIN" >&5
+$as_echo "$DUMPBIN" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+    test -n "$DUMPBIN" && break
+  done
+fi
+if test -z "$DUMPBIN"; then
+  ac_ct_DUMPBIN=$DUMPBIN
+  for ac_prog in dumpbin "link -dump"
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_DUMPBIN+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_DUMPBIN"; then
+  ac_cv_prog_ac_ct_DUMPBIN="$ac_ct_DUMPBIN" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_DUMPBIN="$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_DUMPBIN=$ac_cv_prog_ac_ct_DUMPBIN
+if test -n "$ac_ct_DUMPBIN"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DUMPBIN" >&5
+$as_echo "$ac_ct_DUMPBIN" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  test -n "$ac_ct_DUMPBIN" && break
+done
+
+  if test "x$ac_ct_DUMPBIN" = x; then
+    DUMPBIN=":"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    DUMPBIN=$ac_ct_DUMPBIN
+  fi
+fi
+
+    case `$DUMPBIN -symbols -headers /dev/null 2>&1 | sed '1q'` in
+    *COFF*)
+      DUMPBIN="$DUMPBIN -symbols -headers"
+      ;;
+    *)
+      DUMPBIN=:
+      ;;
+    esac
+  fi
+
+  if test : != "$DUMPBIN"; then
+    NM=$DUMPBIN
+  fi
+fi
+test -z "$NM" && NM=nm
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the name lister ($NM) interface" >&5
+$as_echo_n "checking the name lister ($NM) interface... " >&6; }
+if ${lt_cv_nm_interface+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_nm_interface="BSD nm"
+  echo "int some_variable = 0;" > conftest.$ac_ext
+  (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&5)
+  (eval "$ac_compile" 2>conftest.err)
+  cat conftest.err >&5
+  (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
+  (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out)
+  cat conftest.err >&5
+  (eval echo "\"\$as_me:$LINENO: output\"" >&5)
+  cat conftest.out >&5
+  if $GREP 'External.*some_variable' conftest.out > /dev/null; then
+    lt_cv_nm_interface="MS dumpbin"
+  fi
+  rm -f conftest*
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_nm_interface" >&5
+$as_echo "$lt_cv_nm_interface" >&6; }
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5
+$as_echo_n "checking whether ln -s works... " >&6; }
+LN_S=$as_ln_s
+if test "$LN_S" = "ln -s"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5
+$as_echo "no, using $LN_S" >&6; }
+fi
+
+# find the maximum length of command line arguments
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the maximum length of command line arguments" >&5
+$as_echo_n "checking the maximum length of command line arguments... " >&6; }
+if ${lt_cv_sys_max_cmd_len+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+    i=0
+  teststring=ABCD
+
+  case $build_os in
+  msdosdjgpp*)
+    # On DJGPP, this test can blow up pretty badly due to problems in libc
+    # (any single argument exceeding 2000 bytes causes a buffer overrun
+    # during glob expansion).  Even if it were fixed, the result of this
+    # check would be larger than it should be.
+    lt_cv_sys_max_cmd_len=12288;    # 12K is about right
+    ;;
+
+  gnu*)
+    # Under GNU Hurd, this test is not required because there is
+    # no limit to the length of command line arguments.
+    # Libtool will interpret -1 as no limit whatsoever
+    lt_cv_sys_max_cmd_len=-1;
+    ;;
+
+  cygwin* | mingw* | cegcc*)
+    # On Win9x/ME, this test blows up -- it succeeds, but takes
+    # about 5 minutes as the teststring grows exponentially.
+    # Worse, since 9x/ME are not pre-emptively multitasking,
+    # you end up with a "frozen" computer, even though with patience
+    # the test eventually succeeds (with a max line length of 256k).
+    # Instead, let's just punt: use the minimum linelength reported by
+    # all of the supported platforms: 8192 (on NT/2K/XP).
+    lt_cv_sys_max_cmd_len=8192;
+    ;;
+
+  mint*)
+    # On MiNT this can take a long time and run out of memory.
+    lt_cv_sys_max_cmd_len=8192;
+    ;;
+
+  amigaos*)
+    # On AmigaOS with pdksh, this test takes hours, literally.
+    # So we just punt and use a minimum line length of 8192.
+    lt_cv_sys_max_cmd_len=8192;
+    ;;
+
+  bitrig* | darwin* | dragonfly* | freebsd* | netbsd* | openbsd*)
+    # This has been around since 386BSD, at least.  Likely further.
+    if test -x /sbin/sysctl; then
+      lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax`
+    elif test -x /usr/sbin/sysctl; then
+      lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax`
+    else
+      lt_cv_sys_max_cmd_len=65536	# usable default for all BSDs
+    fi
+    # And add a safety zone
+    lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
+    lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
+    ;;
+
+  interix*)
+    # We know the value 262144 and hardcode it with a safety zone (like BSD)
+    lt_cv_sys_max_cmd_len=196608
+    ;;
+
+  os2*)
+    # The test takes a long time on OS/2.
+    lt_cv_sys_max_cmd_len=8192
+    ;;
+
+  osf*)
+    # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure
+    # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not
+    # nice to cause kernel panics so lets avoid the loop below.
+    # First set a reasonable default.
+    lt_cv_sys_max_cmd_len=16384
+    #
+    if test -x /sbin/sysconfig; then
+      case `/sbin/sysconfig -q proc exec_disable_arg_limit` in
+        *1*) lt_cv_sys_max_cmd_len=-1 ;;
+      esac
+    fi
+    ;;
+  sco3.2v5*)
+    lt_cv_sys_max_cmd_len=102400
+    ;;
+  sysv5* | sco5v6* | sysv4.2uw2*)
+    kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null`
+    if test -n "$kargmax"; then
+      lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[	 ]//'`
+    else
+      lt_cv_sys_max_cmd_len=32768
+    fi
+    ;;
+  *)
+    lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null`
+    if test -n "$lt_cv_sys_max_cmd_len" && \
+       test undefined != "$lt_cv_sys_max_cmd_len"; then
+      lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
+      lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
+    else
+      # Make teststring a little bigger before we do anything with it.
+      # a 1K string should be a reasonable start.
+      for i in 1 2 3 4 5 6 7 8; do
+        teststring=$teststring$teststring
+      done
+      SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}}
+      # If test is not a shell built-in, we'll probably end up computing a
+      # maximum length that is only half of the actual maximum length, but
+      # we can't tell.
+      while { test X`env echo "$teststring$teststring" 2>/dev/null` \
+	         = "X$teststring$teststring"; } >/dev/null 2>&1 &&
+	      test 17 != "$i" # 1/2 MB should be enough
+      do
+        i=`expr $i + 1`
+        teststring=$teststring$teststring
+      done
+      # Only check the string length outside the loop.
+      lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1`
+      teststring=
+      # Add a significant safety factor because C++ compilers can tack on
+      # massive amounts of additional arguments before passing them to the
+      # linker.  It appears as though 1/2 is a usable value.
+      lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2`
+    fi
+    ;;
+  esac
+
+fi
+
+if test -n "$lt_cv_sys_max_cmd_len"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sys_max_cmd_len" >&5
+$as_echo "$lt_cv_sys_max_cmd_len" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: none" >&5
+$as_echo "none" >&6; }
+fi
+max_cmd_len=$lt_cv_sys_max_cmd_len
+
+
+
+
+
+
+: ${CP="cp -f"}
+: ${MV="mv -f"}
+: ${RM="rm -f"}
+
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+  lt_unset=unset
+else
+  lt_unset=false
+fi
+
+
+
+
+
+# test EBCDIC or ASCII
+case `echo X|tr X '\101'` in
+ A) # ASCII based system
+    # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr
+  lt_SP2NL='tr \040 \012'
+  lt_NL2SP='tr \015\012 \040\040'
+  ;;
+ *) # EBCDIC based system
+  lt_SP2NL='tr \100 \n'
+  lt_NL2SP='tr \r\n \100\100'
+  ;;
+esac
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to $host format" >&5
+$as_echo_n "checking how to convert $build file names to $host format... " >&6; }
+if ${lt_cv_to_host_file_cmd+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $host in
+  *-*-mingw* )
+    case $build in
+      *-*-mingw* ) # actually msys
+        lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32
+        ;;
+      *-*-cygwin* )
+        lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32
+        ;;
+      * ) # otherwise, assume *nix
+        lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32
+        ;;
+    esac
+    ;;
+  *-*-cygwin* )
+    case $build in
+      *-*-mingw* ) # actually msys
+        lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin
+        ;;
+      *-*-cygwin* )
+        lt_cv_to_host_file_cmd=func_convert_file_noop
+        ;;
+      * ) # otherwise, assume *nix
+        lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin
+        ;;
+    esac
+    ;;
+  * ) # unhandled hosts (and "normal" native builds)
+    lt_cv_to_host_file_cmd=func_convert_file_noop
+    ;;
+esac
+
+fi
+
+to_host_file_cmd=$lt_cv_to_host_file_cmd
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_host_file_cmd" >&5
+$as_echo "$lt_cv_to_host_file_cmd" >&6; }
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to toolchain format" >&5
+$as_echo_n "checking how to convert $build file names to toolchain format... " >&6; }
+if ${lt_cv_to_tool_file_cmd+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  #assume ordinary cross tools, or native build.
+lt_cv_to_tool_file_cmd=func_convert_file_noop
+case $host in
+  *-*-mingw* )
+    case $build in
+      *-*-mingw* ) # actually msys
+        lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32
+        ;;
+    esac
+    ;;
+esac
+
+fi
+
+to_tool_file_cmd=$lt_cv_to_tool_file_cmd
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_tool_file_cmd" >&5
+$as_echo "$lt_cv_to_tool_file_cmd" >&6; }
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $LD option to reload object files" >&5
+$as_echo_n "checking for $LD option to reload object files... " >&6; }
+if ${lt_cv_ld_reload_flag+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_ld_reload_flag='-r'
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_reload_flag" >&5
+$as_echo "$lt_cv_ld_reload_flag" >&6; }
+reload_flag=$lt_cv_ld_reload_flag
+case $reload_flag in
+"" | " "*) ;;
+*) reload_flag=" $reload_flag" ;;
+esac
+reload_cmds='$LD$reload_flag -o $output$reload_objs'
+case $host_os in
+  cygwin* | mingw* | pw32* | cegcc*)
+    if test yes != "$GCC"; then
+      reload_cmds=false
+    fi
+    ;;
+  darwin*)
+    if test yes = "$GCC"; then
+      reload_cmds='$LTCC $LTCFLAGS -nostdlib $wl-r -o $output$reload_objs'
+    else
+      reload_cmds='$LD$reload_flag -o $output$reload_objs'
+    fi
+    ;;
+esac
+
+
+
+
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args.
+set dummy ${ac_tool_prefix}objdump; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_OBJDUMP+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$OBJDUMP"; then
+  ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+OBJDUMP=$ac_cv_prog_OBJDUMP
+if test -n "$OBJDUMP"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5
+$as_echo "$OBJDUMP" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_OBJDUMP"; then
+  ac_ct_OBJDUMP=$OBJDUMP
+  # Extract the first word of "objdump", so it can be a program name with args.
+set dummy objdump; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_OBJDUMP+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_OBJDUMP"; then
+  ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_OBJDUMP="objdump"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP
+if test -n "$ac_ct_OBJDUMP"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5
+$as_echo "$ac_ct_OBJDUMP" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_OBJDUMP" = x; then
+    OBJDUMP="false"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    OBJDUMP=$ac_ct_OBJDUMP
+  fi
+else
+  OBJDUMP="$ac_cv_prog_OBJDUMP"
+fi
+
+test -z "$OBJDUMP" && OBJDUMP=objdump
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to recognize dependent libraries" >&5
+$as_echo_n "checking how to recognize dependent libraries... " >&6; }
+if ${lt_cv_deplibs_check_method+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_file_magic_cmd='$MAGIC_CMD'
+lt_cv_file_magic_test_file=
+lt_cv_deplibs_check_method='unknown'
+# Need to set the preceding variable on all platforms that support
+# interlibrary dependencies.
+# 'none' -- dependencies not supported.
+# 'unknown' -- same as none, but documents that we really don't know.
+# 'pass_all' -- all dependencies passed with no checks.
+# 'test_compile' -- check by making test program.
+# 'file_magic [[regex]]' -- check by looking for files in library path
+# that responds to the $file_magic_cmd with a given extended regex.
+# If you have 'file' or equivalent on your system and you're not sure
+# whether 'pass_all' will *always* work, you probably want this one.
+
+case $host_os in
+aix[4-9]*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+beos*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+bsdi[45]*)
+  lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)'
+  lt_cv_file_magic_cmd='/usr/bin/file -L'
+  lt_cv_file_magic_test_file=/shlib/libc.so
+  ;;
+
+cygwin*)
+  # func_win32_libid is a shell function defined in ltmain.sh
+  lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
+  lt_cv_file_magic_cmd='func_win32_libid'
+  ;;
+
+mingw* | pw32*)
+  # Base MSYS/MinGW do not provide the 'file' command needed by
+  # func_win32_libid shell function, so use a weaker test based on 'objdump',
+  # unless we find 'file', for example because we are cross-compiling.
+  if ( file / ) >/dev/null 2>&1; then
+    lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
+    lt_cv_file_magic_cmd='func_win32_libid'
+  else
+    # Keep this pattern in sync with the one in func_win32_libid.
+    lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)'
+    lt_cv_file_magic_cmd='$OBJDUMP -f'
+  fi
+  ;;
+
+cegcc*)
+  # use the weaker test based on 'objdump'. See mingw*.
+  lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?'
+  lt_cv_file_magic_cmd='$OBJDUMP -f'
+  ;;
+
+darwin* | rhapsody*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+freebsd* | dragonfly*)
+  if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
+    case $host_cpu in
+    i*86 )
+      # Not sure whether the presence of OpenBSD here was a mistake.
+      # Let's accept both of them until this is cleared up.
+      lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[3-9]86 (compact )?demand paged shared library'
+      lt_cv_file_magic_cmd=/usr/bin/file
+      lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*`
+      ;;
+    esac
+  else
+    lt_cv_deplibs_check_method=pass_all
+  fi
+  ;;
+
+haiku*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+hpux10.20* | hpux11*)
+  lt_cv_file_magic_cmd=/usr/bin/file
+  case $host_cpu in
+  ia64*)
+    lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64'
+    lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so
+    ;;
+  hppa*64*)
+    lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]'
+    lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl
+    ;;
+  *)
+    lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9]\.[0-9]) shared library'
+    lt_cv_file_magic_test_file=/usr/lib/libc.sl
+    ;;
+  esac
+  ;;
+
+interix[3-9]*)
+  # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here
+  lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|\.a)$'
+  ;;
+
+irix5* | irix6* | nonstopux*)
+  case $LD in
+  *-32|*"-32 ") libmagic=32-bit;;
+  *-n32|*"-n32 ") libmagic=N32;;
+  *-64|*"-64 ") libmagic=64-bit;;
+  *) libmagic=never-match;;
+  esac
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+# This must be glibc/ELF.
+linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+netbsd* | netbsdelf*-gnu)
+  if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
+    lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$'
+  else
+    lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|_pic\.a)$'
+  fi
+  ;;
+
+newos6*)
+  lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)'
+  lt_cv_file_magic_cmd=/usr/bin/file
+  lt_cv_file_magic_test_file=/usr/lib/libnls.so
+  ;;
+
+*nto* | *qnx*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+openbsd* | bitrig*)
+  if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then
+    lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$'
+  else
+    lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$'
+  fi
+  ;;
+
+osf3* | osf4* | osf5*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+rdos*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+solaris*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+sysv4 | sysv4.3*)
+  case $host_vendor in
+  motorola)
+    lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]'
+    lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*`
+    ;;
+  ncr)
+    lt_cv_deplibs_check_method=pass_all
+    ;;
+  sequent)
+    lt_cv_file_magic_cmd='/bin/file'
+    lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )'
+    ;;
+  sni)
+    lt_cv_file_magic_cmd='/bin/file'
+    lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib"
+    lt_cv_file_magic_test_file=/lib/libc.so
+    ;;
+  siemens)
+    lt_cv_deplibs_check_method=pass_all
+    ;;
+  pc)
+    lt_cv_deplibs_check_method=pass_all
+    ;;
+  esac
+  ;;
+
+tpf*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+os2*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+esac
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_deplibs_check_method" >&5
+$as_echo "$lt_cv_deplibs_check_method" >&6; }
+
+file_magic_glob=
+want_nocaseglob=no
+if test "$build" = "$host"; then
+  case $host_os in
+  mingw* | pw32*)
+    if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then
+      want_nocaseglob=yes
+    else
+      file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[\1]\/[\1]\/g;/g"`
+    fi
+    ;;
+  esac
+fi
+
+file_magic_cmd=$lt_cv_file_magic_cmd
+deplibs_check_method=$lt_cv_deplibs_check_method
+test -z "$deplibs_check_method" && deplibs_check_method=unknown
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args.
+set dummy ${ac_tool_prefix}dlltool; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_DLLTOOL+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$DLLTOOL"; then
+  ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+DLLTOOL=$ac_cv_prog_DLLTOOL
+if test -n "$DLLTOOL"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DLLTOOL" >&5
+$as_echo "$DLLTOOL" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_DLLTOOL"; then
+  ac_ct_DLLTOOL=$DLLTOOL
+  # Extract the first word of "dlltool", so it can be a program name with args.
+set dummy dlltool; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_DLLTOOL+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_DLLTOOL"; then
+  ac_cv_prog_ac_ct_DLLTOOL="$ac_ct_DLLTOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_DLLTOOL="dlltool"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_DLLTOOL=$ac_cv_prog_ac_ct_DLLTOOL
+if test -n "$ac_ct_DLLTOOL"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DLLTOOL" >&5
+$as_echo "$ac_ct_DLLTOOL" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_DLLTOOL" = x; then
+    DLLTOOL="false"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    DLLTOOL=$ac_ct_DLLTOOL
+  fi
+else
+  DLLTOOL="$ac_cv_prog_DLLTOOL"
+fi
+
+test -z "$DLLTOOL" && DLLTOOL=dlltool
+
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to associate runtime and link libraries" >&5
+$as_echo_n "checking how to associate runtime and link libraries... " >&6; }
+if ${lt_cv_sharedlib_from_linklib_cmd+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_sharedlib_from_linklib_cmd='unknown'
+
+case $host_os in
+cygwin* | mingw* | pw32* | cegcc*)
+  # two different shell functions defined in ltmain.sh;
+  # decide which one to use based on capabilities of $DLLTOOL
+  case `$DLLTOOL --help 2>&1` in
+  *--identify-strict*)
+    lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib
+    ;;
+  *)
+    lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback
+    ;;
+  esac
+  ;;
+*)
+  # fallback: assume linklib IS sharedlib
+  lt_cv_sharedlib_from_linklib_cmd=$ECHO
+  ;;
+esac
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sharedlib_from_linklib_cmd" >&5
+$as_echo "$lt_cv_sharedlib_from_linklib_cmd" >&6; }
+sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd
+test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO
+
+
+
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+  for ac_prog in ar
+  do
+    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_AR+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$AR"; then
+  ac_cv_prog_AR="$AR" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_AR="$ac_tool_prefix$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+AR=$ac_cv_prog_AR
+if test -n "$AR"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5
+$as_echo "$AR" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+    test -n "$AR" && break
+  done
+fi
+if test -z "$AR"; then
+  ac_ct_AR=$AR
+  for ac_prog in ar
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_AR+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_AR"; then
+  ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_AR="$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_AR=$ac_cv_prog_ac_ct_AR
+if test -n "$ac_ct_AR"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5
+$as_echo "$ac_ct_AR" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  test -n "$ac_ct_AR" && break
+done
+
+  if test "x$ac_ct_AR" = x; then
+    AR="false"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    AR=$ac_ct_AR
+  fi
+fi
+
+: ${AR=ar}
+: ${AR_FLAGS=cru}
+
+
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for archiver @FILE support" >&5
+$as_echo_n "checking for archiver @FILE support... " >&6; }
+if ${lt_cv_ar_at_file+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_ar_at_file=no
+   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  echo conftest.$ac_objext > conftest.lst
+      lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&5'
+      { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5
+  (eval $lt_ar_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      if test 0 -eq "$ac_status"; then
+	# Ensure the archiver fails upon bogus file names.
+	rm -f conftest.$ac_objext libconftest.a
+	{ { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5
+  (eval $lt_ar_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+	if test 0 -ne "$ac_status"; then
+          lt_cv_ar_at_file=@
+        fi
+      fi
+      rm -f conftest.* libconftest.a
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ar_at_file" >&5
+$as_echo "$lt_cv_ar_at_file" >&6; }
+
+if test no = "$lt_cv_ar_at_file"; then
+  archiver_list_spec=
+else
+  archiver_list_spec=$lt_cv_ar_at_file
+fi
+
+
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args.
+set dummy ${ac_tool_prefix}strip; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_STRIP+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$STRIP"; then
+  ac_cv_prog_STRIP="$STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_STRIP="${ac_tool_prefix}strip"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+STRIP=$ac_cv_prog_STRIP
+if test -n "$STRIP"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5
+$as_echo "$STRIP" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_STRIP"; then
+  ac_ct_STRIP=$STRIP
+  # Extract the first word of "strip", so it can be a program name with args.
+set dummy strip; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_STRIP+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_STRIP"; then
+  ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_STRIP="strip"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP
+if test -n "$ac_ct_STRIP"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5
+$as_echo "$ac_ct_STRIP" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_STRIP" = x; then
+    STRIP=":"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    STRIP=$ac_ct_STRIP
+  fi
+else
+  STRIP="$ac_cv_prog_STRIP"
+fi
+
+test -z "$STRIP" && STRIP=:
+
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
+set dummy ${ac_tool_prefix}ranlib; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_RANLIB+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$RANLIB"; then
+  ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+RANLIB=$ac_cv_prog_RANLIB
+if test -n "$RANLIB"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5
+$as_echo "$RANLIB" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_RANLIB"; then
+  ac_ct_RANLIB=$RANLIB
+  # Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_RANLIB+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_RANLIB"; then
+  ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_RANLIB="ranlib"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB
+if test -n "$ac_ct_RANLIB"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5
+$as_echo "$ac_ct_RANLIB" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_RANLIB" = x; then
+    RANLIB=":"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    RANLIB=$ac_ct_RANLIB
+  fi
+else
+  RANLIB="$ac_cv_prog_RANLIB"
+fi
+
+test -z "$RANLIB" && RANLIB=:
+
+
+
+
+
+
+# Determine commands to create old-style static archives.
+old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs'
+old_postinstall_cmds='chmod 644 $oldlib'
+old_postuninstall_cmds=
+
+if test -n "$RANLIB"; then
+  case $host_os in
+  bitrig* | openbsd*)
+    old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib"
+    ;;
+  *)
+    old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib"
+    ;;
+  esac
+  old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib"
+fi
+
+case $host_os in
+  darwin*)
+    lock_old_archive_extraction=yes ;;
+  *)
+    lock_old_archive_extraction=no ;;
+esac
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# If no C compiler was specified, use CC.
+LTCC=${LTCC-"$CC"}
+
+# If no C compiler flags were specified, use CFLAGS.
+LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
+
+# Allow CC to be a program name with arguments.
+compiler=$CC
+
+
+# Check for command to grab the raw symbol name followed by C symbol from nm.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking command to parse $NM output from $compiler object" >&5
+$as_echo_n "checking command to parse $NM output from $compiler object... " >&6; }
+if ${lt_cv_sys_global_symbol_pipe+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+# These are sane defaults that work on at least a few old systems.
+# [They come from Ultrix.  What could be older than Ultrix?!! ;)]
+
+# Character class describing NM global symbol codes.
+symcode='[BCDEGRST]'
+
+# Regexp to match symbols that can be accessed directly from C.
+sympat='\([_A-Za-z][_A-Za-z0-9]*\)'
+
+# Define system-specific variables.
+case $host_os in
+aix*)
+  symcode='[BCDT]'
+  ;;
+cygwin* | mingw* | pw32* | cegcc*)
+  symcode='[ABCDGISTW]'
+  ;;
+hpux*)
+  if test ia64 = "$host_cpu"; then
+    symcode='[ABCDEGRST]'
+  fi
+  ;;
+irix* | nonstopux*)
+  symcode='[BCDEGRST]'
+  ;;
+osf*)
+  symcode='[BCDEGQRST]'
+  ;;
+solaris*)
+  symcode='[BDRT]'
+  ;;
+sco3.2v5*)
+  symcode='[DT]'
+  ;;
+sysv4.2uw2*)
+  symcode='[DT]'
+  ;;
+sysv5* | sco5v6* | unixware* | OpenUNIX*)
+  symcode='[ABDT]'
+  ;;
+sysv4)
+  symcode='[DFNSTU]'
+  ;;
+esac
+
+# If we're using GNU nm, then use its standard symbol codes.
+case `$NM -V 2>&1` in
+*GNU* | *'with BFD'*)
+  symcode='[ABCDGIRSTW]' ;;
+esac
+
+if test "$lt_cv_nm_interface" = "MS dumpbin"; then
+  # Gets list of data symbols to import.
+  lt_cv_sys_global_symbol_to_import="sed -n -e 's/^I .* \(.*\)$/\1/p'"
+  # Adjust the below global symbol transforms to fixup imported variables.
+  lt_cdecl_hook=" -e 's/^I .* \(.*\)$/extern __declspec(dllimport) char \1;/p'"
+  lt_c_name_hook=" -e 's/^I .* \(.*\)$/  {\"\1\", (void *) 0},/p'"
+  lt_c_name_lib_hook="\
+  -e 's/^I .* \(lib.*\)$/  {\"\1\", (void *) 0},/p'\
+  -e 's/^I .* \(.*\)$/  {\"lib\1\", (void *) 0},/p'"
+else
+  # Disable hooks by default.
+  lt_cv_sys_global_symbol_to_import=
+  lt_cdecl_hook=
+  lt_c_name_hook=
+  lt_c_name_lib_hook=
+fi
+
+# Transform an extracted symbol line into a proper C declaration.
+# Some systems (esp. on ia64) link data and code symbols differently,
+# so use this general approach.
+lt_cv_sys_global_symbol_to_cdecl="sed -n"\
+$lt_cdecl_hook\
+" -e 's/^T .* \(.*\)$/extern int \1();/p'"\
+" -e 's/^$symcode$symcode* .* \(.*\)$/extern char \1;/p'"
+
+# Transform an extracted symbol line into symbol name and symbol address
+lt_cv_sys_global_symbol_to_c_name_address="sed -n"\
+$lt_c_name_hook\
+" -e 's/^: \(.*\) .*$/  {\"\1\", (void *) 0},/p'"\
+" -e 's/^$symcode$symcode* .* \(.*\)$/  {\"\1\", (void *) \&\1},/p'"
+
+# Transform an extracted symbol line into symbol name with lib prefix and
+# symbol address.
+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n"\
+$lt_c_name_lib_hook\
+" -e 's/^: \(.*\) .*$/  {\"\1\", (void *) 0},/p'"\
+" -e 's/^$symcode$symcode* .* \(lib.*\)$/  {\"\1\", (void *) \&\1},/p'"\
+" -e 's/^$symcode$symcode* .* \(.*\)$/  {\"lib\1\", (void *) \&\1},/p'"
+
+# Handle CRLF in mingw tool chain
+opt_cr=
+case $build_os in
+mingw*)
+  opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp
+  ;;
+esac
+
+# Try without a prefix underscore, then with it.
+for ac_symprfx in "" "_"; do
+
+  # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol.
+  symxfrm="\\1 $ac_symprfx\\2 \\2"
+
+  # Write the raw and C identifiers.
+  if test "$lt_cv_nm_interface" = "MS dumpbin"; then
+    # Fake it for dumpbin and say T for any non-static function,
+    # D for any global variable and I for any imported variable.
+    # Also find C++ and __fastcall symbols from MSVC++,
+    # which start with @ or ?.
+    lt_cv_sys_global_symbol_pipe="$AWK '"\
+"     {last_section=section; section=\$ 3};"\
+"     /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\
+"     /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\
+"     /^ *Symbol name *: /{split(\$ 0,sn,\":\"); si=substr(sn[2],2)};"\
+"     /^ *Type *: code/{print \"T\",si,substr(si,length(prfx))};"\
+"     /^ *Type *: data/{print \"I\",si,substr(si,length(prfx))};"\
+"     \$ 0!~/External *\|/{next};"\
+"     / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\
+"     {if(hide[section]) next};"\
+"     {f=\"D\"}; \$ 0~/\(\).*\|/{f=\"T\"};"\
+"     {split(\$ 0,a,/\||\r/); split(a[2],s)};"\
+"     s[1]~/^[@?]/{print f,s[1],s[1]; next};"\
+"     s[1]~prfx {split(s[1],t,\"@\"); print f,t[1],substr(t[1],length(prfx))}"\
+"     ' prfx=^$ac_symprfx"
+  else
+    lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[	 ]\($symcode$symcode*\)[	 ][	 ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'"
+  fi
+  lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'"
+
+  # Check to see that the pipe works correctly.
+  pipe_works=no
+
+  rm -f conftest*
+  cat > conftest.$ac_ext <<_LT_EOF
+#ifdef __cplusplus
+extern "C" {
+#endif
+char nm_test_var;
+void nm_test_func(void);
+void nm_test_func(void){}
+#ifdef __cplusplus
+}
+#endif
+int main(){nm_test_var='a';nm_test_func();return(0);}
+_LT_EOF
+
+  if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+    # Now try to grab the symbols.
+    nlist=conftest.nm
+    if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist\""; } >&5
+  (eval $NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && test -s "$nlist"; then
+      # Try sorting and uniquifying the output.
+      if sort "$nlist" | uniq > "$nlist"T; then
+	mv -f "$nlist"T "$nlist"
+      else
+	rm -f "$nlist"T
+      fi
+
+      # Make sure that we snagged all the symbols we need.
+      if $GREP ' nm_test_var$' "$nlist" >/dev/null; then
+	if $GREP ' nm_test_func$' "$nlist" >/dev/null; then
+	  cat <<_LT_EOF > conftest.$ac_ext
+/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests.  */
+#if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE
+/* DATA imports from DLLs on WIN32 can't be const, because runtime
+   relocations are performed -- see ld's documentation on pseudo-relocs.  */
+# define LT_DLSYM_CONST
+#elif defined __osf__
+/* This system does not cope well with relocations in const data.  */
+# define LT_DLSYM_CONST
+#else
+# define LT_DLSYM_CONST const
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+_LT_EOF
+	  # Now generate the symbol file.
+	  eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext'
+
+	  cat <<_LT_EOF >> conftest.$ac_ext
+
+/* The mapping between symbol names and symbols.  */
+LT_DLSYM_CONST struct {
+  const char *name;
+  void       *address;
+}
+lt__PROGRAM__LTX_preloaded_symbols[] =
+{
+  { "@PROGRAM@", (void *) 0 },
+_LT_EOF
+	  $SED "s/^$symcode$symcode* .* \(.*\)$/  {\"\1\", (void *) \&\1},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext
+	  cat <<\_LT_EOF >> conftest.$ac_ext
+  {0, (void *) 0}
+};
+
+/* This works around a problem in FreeBSD linker */
+#ifdef FREEBSD_WORKAROUND
+static const void *lt_preloaded_setup() {
+  return lt__PROGRAM__LTX_preloaded_symbols;
+}
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+_LT_EOF
+	  # Now try linking the two files.
+	  mv conftest.$ac_objext conftstm.$ac_objext
+	  lt_globsym_save_LIBS=$LIBS
+	  lt_globsym_save_CFLAGS=$CFLAGS
+	  LIBS=conftstm.$ac_objext
+	  CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag"
+	  if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && test -s conftest$ac_exeext; then
+	    pipe_works=yes
+	  fi
+	  LIBS=$lt_globsym_save_LIBS
+	  CFLAGS=$lt_globsym_save_CFLAGS
+	else
+	  echo "cannot find nm_test_func in $nlist" >&5
+	fi
+      else
+	echo "cannot find nm_test_var in $nlist" >&5
+      fi
+    else
+      echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5
+    fi
+  else
+    echo "$progname: failed program was:" >&5
+    cat conftest.$ac_ext >&5
+  fi
+  rm -rf conftest* conftst*
+
+  # Do not use the global_symbol_pipe unless it works.
+  if test yes = "$pipe_works"; then
+    break
+  else
+    lt_cv_sys_global_symbol_pipe=
+  fi
+done
+
+fi
+
+if test -z "$lt_cv_sys_global_symbol_pipe"; then
+  lt_cv_sys_global_symbol_to_cdecl=
+fi
+if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: failed" >&5
+$as_echo "failed" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5
+$as_echo "ok" >&6; }
+fi
+
+# Response file support.
+if test "$lt_cv_nm_interface" = "MS dumpbin"; then
+  nm_file_list_spec='@'
+elif $NM --help 2>/dev/null | grep '[@]FILE' >/dev/null; then
+  nm_file_list_spec='@'
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sysroot" >&5
+$as_echo_n "checking for sysroot... " >&6; }
+
+# Check whether --with-sysroot was given.
+if test "${with_sysroot+set}" = set; then :
+  withval=$with_sysroot;
+else
+  with_sysroot=no
+fi
+
+
+lt_sysroot=
+case $with_sysroot in #(
+ yes)
+   if test yes = "$GCC"; then
+     lt_sysroot=`$CC --print-sysroot 2>/dev/null`
+   fi
+   ;; #(
+ /*)
+   lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"`
+   ;; #(
+ no|'')
+   ;; #(
+ *)
+   { $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_sysroot" >&5
+$as_echo "$with_sysroot" >&6; }
+   as_fn_error $? "The sysroot must be an absolute path." "$LINENO" 5
+   ;;
+esac
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${lt_sysroot:-no}" >&5
+$as_echo "${lt_sysroot:-no}" >&6; }
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a working dd" >&5
+$as_echo_n "checking for a working dd... " >&6; }
+if ${ac_cv_path_lt_DD+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  printf 0123456789abcdef0123456789abcdef >conftest.i
+cat conftest.i conftest.i >conftest2.i
+: ${lt_DD:=$DD}
+if test -z "$lt_DD"; then
+  ac_path_lt_DD_found=false
+  # Loop through the user's path and test for each of PROGNAME-LIST
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_prog in dd; do
+    for ac_exec_ext in '' $ac_executable_extensions; do
+      ac_path_lt_DD="$as_dir/$ac_prog$ac_exec_ext"
+      as_fn_executable_p "$ac_path_lt_DD" || continue
+if "$ac_path_lt_DD" bs=32 count=1 <conftest2.i >conftest.out 2>/dev/null; then
+  cmp -s conftest.i conftest.out \
+  && ac_cv_path_lt_DD="$ac_path_lt_DD" ac_path_lt_DD_found=:
+fi
+      $ac_path_lt_DD_found && break 3
+    done
+  done
+  done
+IFS=$as_save_IFS
+  if test -z "$ac_cv_path_lt_DD"; then
+    :
+  fi
+else
+  ac_cv_path_lt_DD=$lt_DD
+fi
+
+rm -f conftest.i conftest2.i conftest.out
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_lt_DD" >&5
+$as_echo "$ac_cv_path_lt_DD" >&6; }
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to truncate binary pipes" >&5
+$as_echo_n "checking how to truncate binary pipes... " >&6; }
+if ${lt_cv_truncate_bin+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  printf 0123456789abcdef0123456789abcdef >conftest.i
+cat conftest.i conftest.i >conftest2.i
+lt_cv_truncate_bin=
+if "$ac_cv_path_lt_DD" bs=32 count=1 <conftest2.i >conftest.out 2>/dev/null; then
+  cmp -s conftest.i conftest.out \
+  && lt_cv_truncate_bin="$ac_cv_path_lt_DD bs=4096 count=1"
+fi
+rm -f conftest.i conftest2.i conftest.out
+test -z "$lt_cv_truncate_bin" && lt_cv_truncate_bin="$SED -e 4q"
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_truncate_bin" >&5
+$as_echo "$lt_cv_truncate_bin" >&6; }
+
+
+
+
+
+
+
+# Calculate cc_basename.  Skip known compiler wrappers and cross-prefix.
+func_cc_basename ()
+{
+    for cc_temp in $*""; do
+      case $cc_temp in
+        compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
+        distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
+        \-*) ;;
+        *) break;;
+      esac
+    done
+    func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"`
+}
+
+# Check whether --enable-libtool-lock was given.
+if test "${enable_libtool_lock+set}" = set; then :
+  enableval=$enable_libtool_lock;
+fi
+
+test no = "$enable_libtool_lock" || enable_libtool_lock=yes
+
+# Some flags need to be propagated to the compiler or linker for good
+# libtool support.
+case $host in
+ia64-*-hpux*)
+  # Find out what ABI is being produced by ac_compile, and set mode
+  # options accordingly.
+  echo 'int i;' > conftest.$ac_ext
+  if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+    case `/usr/bin/file conftest.$ac_objext` in
+      *ELF-32*)
+	HPUX_IA64_MODE=32
+	;;
+      *ELF-64*)
+	HPUX_IA64_MODE=64
+	;;
+    esac
+  fi
+  rm -rf conftest*
+  ;;
+*-*-irix6*)
+  # Find out what ABI is being produced by ac_compile, and set linker
+  # options accordingly.
+  echo '#line '$LINENO' "configure"' > conftest.$ac_ext
+  if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+    if test yes = "$lt_cv_prog_gnu_ld"; then
+      case `/usr/bin/file conftest.$ac_objext` in
+	*32-bit*)
+	  LD="${LD-ld} -melf32bsmip"
+	  ;;
+	*N32*)
+	  LD="${LD-ld} -melf32bmipn32"
+	  ;;
+	*64-bit*)
+	  LD="${LD-ld} -melf64bmip"
+	;;
+      esac
+    else
+      case `/usr/bin/file conftest.$ac_objext` in
+	*32-bit*)
+	  LD="${LD-ld} -32"
+	  ;;
+	*N32*)
+	  LD="${LD-ld} -n32"
+	  ;;
+	*64-bit*)
+	  LD="${LD-ld} -64"
+	  ;;
+      esac
+    fi
+  fi
+  rm -rf conftest*
+  ;;
+
+mips64*-*linux*)
+  # Find out what ABI is being produced by ac_compile, and set linker
+  # options accordingly.
+  echo '#line '$LINENO' "configure"' > conftest.$ac_ext
+  if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+    emul=elf
+    case `/usr/bin/file conftest.$ac_objext` in
+      *32-bit*)
+	emul="${emul}32"
+	;;
+      *64-bit*)
+	emul="${emul}64"
+	;;
+    esac
+    case `/usr/bin/file conftest.$ac_objext` in
+      *MSB*)
+	emul="${emul}btsmip"
+	;;
+      *LSB*)
+	emul="${emul}ltsmip"
+	;;
+    esac
+    case `/usr/bin/file conftest.$ac_objext` in
+      *N32*)
+	emul="${emul}n32"
+	;;
+    esac
+    LD="${LD-ld} -m $emul"
+  fi
+  rm -rf conftest*
+  ;;
+
+x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \
+s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
+  # Find out what ABI is being produced by ac_compile, and set linker
+  # options accordingly.  Note that the listed cases only cover the
+  # situations where additional linker options are needed (such as when
+  # doing 32-bit compilation for a host where ld defaults to 64-bit, or
+  # vice versa); the common cases where no linker options are needed do
+  # not appear in the list.
+  echo 'int i;' > conftest.$ac_ext
+  if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+    case `/usr/bin/file conftest.o` in
+      *32-bit*)
+	case $host in
+	  x86_64-*kfreebsd*-gnu)
+	    LD="${LD-ld} -m elf_i386_fbsd"
+	    ;;
+	  x86_64-*linux*)
+	    case `/usr/bin/file conftest.o` in
+	      *x86-64*)
+		LD="${LD-ld} -m elf32_x86_64"
+		;;
+	      *)
+		LD="${LD-ld} -m elf_i386"
+		;;
+	    esac
+	    ;;
+	  powerpc64le-*linux*)
+	    LD="${LD-ld} -m elf32lppclinux"
+	    ;;
+	  powerpc64-*linux*)
+	    LD="${LD-ld} -m elf32ppclinux"
+	    ;;
+	  s390x-*linux*)
+	    LD="${LD-ld} -m elf_s390"
+	    ;;
+	  sparc64-*linux*)
+	    LD="${LD-ld} -m elf32_sparc"
+	    ;;
+	esac
+	;;
+      *64-bit*)
+	case $host in
+	  x86_64-*kfreebsd*-gnu)
+	    LD="${LD-ld} -m elf_x86_64_fbsd"
+	    ;;
+	  x86_64-*linux*)
+	    LD="${LD-ld} -m elf_x86_64"
+	    ;;
+	  powerpcle-*linux*)
+	    LD="${LD-ld} -m elf64lppc"
+	    ;;
+	  powerpc-*linux*)
+	    LD="${LD-ld} -m elf64ppc"
+	    ;;
+	  s390*-*linux*|s390*-*tpf*)
+	    LD="${LD-ld} -m elf64_s390"
+	    ;;
+	  sparc*-*linux*)
+	    LD="${LD-ld} -m elf64_sparc"
+	    ;;
+	esac
+	;;
+    esac
+  fi
+  rm -rf conftest*
+  ;;
+
+*-*-sco3.2v5*)
+  # On SCO OpenServer 5, we need -belf to get full-featured binaries.
+  SAVE_CFLAGS=$CFLAGS
+  CFLAGS="$CFLAGS -belf"
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler needs -belf" >&5
+$as_echo_n "checking whether the C compiler needs -belf... " >&6; }
+if ${lt_cv_cc_needs_belf+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+     cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  lt_cv_cc_needs_belf=yes
+else
+  lt_cv_cc_needs_belf=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+     ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_cc_needs_belf" >&5
+$as_echo "$lt_cv_cc_needs_belf" >&6; }
+  if test yes != "$lt_cv_cc_needs_belf"; then
+    # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf
+    CFLAGS=$SAVE_CFLAGS
+  fi
+  ;;
+*-*solaris*)
+  # Find out what ABI is being produced by ac_compile, and set linker
+  # options accordingly.
+  echo 'int i;' > conftest.$ac_ext
+  if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+    case `/usr/bin/file conftest.o` in
+    *64-bit*)
+      case $lt_cv_prog_gnu_ld in
+      yes*)
+        case $host in
+        i?86-*-solaris*|x86_64-*-solaris*)
+          LD="${LD-ld} -m elf_x86_64"
+          ;;
+        sparc*-*-solaris*)
+          LD="${LD-ld} -m elf64_sparc"
+          ;;
+        esac
+        # GNU ld 2.21 introduced _sol2 emulations.  Use them if available.
+        if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then
+          LD=${LD-ld}_sol2
+        fi
+        ;;
+      *)
+	if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then
+	  LD="${LD-ld} -64"
+	fi
+	;;
+      esac
+      ;;
+    esac
+  fi
+  rm -rf conftest*
+  ;;
+esac
+
+need_locks=$enable_libtool_lock
+
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}mt", so it can be a program name with args.
+set dummy ${ac_tool_prefix}mt; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_MANIFEST_TOOL+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$MANIFEST_TOOL"; then
+  ac_cv_prog_MANIFEST_TOOL="$MANIFEST_TOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_MANIFEST_TOOL="${ac_tool_prefix}mt"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+MANIFEST_TOOL=$ac_cv_prog_MANIFEST_TOOL
+if test -n "$MANIFEST_TOOL"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MANIFEST_TOOL" >&5
+$as_echo "$MANIFEST_TOOL" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_MANIFEST_TOOL"; then
+  ac_ct_MANIFEST_TOOL=$MANIFEST_TOOL
+  # Extract the first word of "mt", so it can be a program name with args.
+set dummy mt; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_MANIFEST_TOOL+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_MANIFEST_TOOL"; then
+  ac_cv_prog_ac_ct_MANIFEST_TOOL="$ac_ct_MANIFEST_TOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_MANIFEST_TOOL="mt"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_MANIFEST_TOOL=$ac_cv_prog_ac_ct_MANIFEST_TOOL
+if test -n "$ac_ct_MANIFEST_TOOL"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_MANIFEST_TOOL" >&5
+$as_echo "$ac_ct_MANIFEST_TOOL" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_MANIFEST_TOOL" = x; then
+    MANIFEST_TOOL=":"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    MANIFEST_TOOL=$ac_ct_MANIFEST_TOOL
+  fi
+else
+  MANIFEST_TOOL="$ac_cv_prog_MANIFEST_TOOL"
+fi
+
+test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $MANIFEST_TOOL is a manifest tool" >&5
+$as_echo_n "checking if $MANIFEST_TOOL is a manifest tool... " >&6; }
+if ${lt_cv_path_mainfest_tool+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_path_mainfest_tool=no
+  echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&5
+  $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out
+  cat conftest.err >&5
+  if $GREP 'Manifest Tool' conftest.out > /dev/null; then
+    lt_cv_path_mainfest_tool=yes
+  fi
+  rm -f conftest*
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_mainfest_tool" >&5
+$as_echo "$lt_cv_path_mainfest_tool" >&6; }
+if test yes != "$lt_cv_path_mainfest_tool"; then
+  MANIFEST_TOOL=:
+fi
+
+
+
+
+
+
+  case $host_os in
+    rhapsody* | darwin*)
+    if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}dsymutil", so it can be a program name with args.
+set dummy ${ac_tool_prefix}dsymutil; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_DSYMUTIL+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$DSYMUTIL"; then
+  ac_cv_prog_DSYMUTIL="$DSYMUTIL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_DSYMUTIL="${ac_tool_prefix}dsymutil"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+DSYMUTIL=$ac_cv_prog_DSYMUTIL
+if test -n "$DSYMUTIL"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DSYMUTIL" >&5
+$as_echo "$DSYMUTIL" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_DSYMUTIL"; then
+  ac_ct_DSYMUTIL=$DSYMUTIL
+  # Extract the first word of "dsymutil", so it can be a program name with args.
+set dummy dsymutil; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_DSYMUTIL+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_DSYMUTIL"; then
+  ac_cv_prog_ac_ct_DSYMUTIL="$ac_ct_DSYMUTIL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_DSYMUTIL="dsymutil"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_DSYMUTIL=$ac_cv_prog_ac_ct_DSYMUTIL
+if test -n "$ac_ct_DSYMUTIL"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DSYMUTIL" >&5
+$as_echo "$ac_ct_DSYMUTIL" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_DSYMUTIL" = x; then
+    DSYMUTIL=":"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    DSYMUTIL=$ac_ct_DSYMUTIL
+  fi
+else
+  DSYMUTIL="$ac_cv_prog_DSYMUTIL"
+fi
+
+    if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}nmedit", so it can be a program name with args.
+set dummy ${ac_tool_prefix}nmedit; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_NMEDIT+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$NMEDIT"; then
+  ac_cv_prog_NMEDIT="$NMEDIT" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_NMEDIT="${ac_tool_prefix}nmedit"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+NMEDIT=$ac_cv_prog_NMEDIT
+if test -n "$NMEDIT"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NMEDIT" >&5
+$as_echo "$NMEDIT" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_NMEDIT"; then
+  ac_ct_NMEDIT=$NMEDIT
+  # Extract the first word of "nmedit", so it can be a program name with args.
+set dummy nmedit; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_NMEDIT+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_NMEDIT"; then
+  ac_cv_prog_ac_ct_NMEDIT="$ac_ct_NMEDIT" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_NMEDIT="nmedit"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_NMEDIT=$ac_cv_prog_ac_ct_NMEDIT
+if test -n "$ac_ct_NMEDIT"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_NMEDIT" >&5
+$as_echo "$ac_ct_NMEDIT" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_NMEDIT" = x; then
+    NMEDIT=":"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    NMEDIT=$ac_ct_NMEDIT
+  fi
+else
+  NMEDIT="$ac_cv_prog_NMEDIT"
+fi
+
+    if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}lipo", so it can be a program name with args.
+set dummy ${ac_tool_prefix}lipo; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_LIPO+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$LIPO"; then
+  ac_cv_prog_LIPO="$LIPO" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_LIPO="${ac_tool_prefix}lipo"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+LIPO=$ac_cv_prog_LIPO
+if test -n "$LIPO"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIPO" >&5
+$as_echo "$LIPO" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_LIPO"; then
+  ac_ct_LIPO=$LIPO
+  # Extract the first word of "lipo", so it can be a program name with args.
+set dummy lipo; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_LIPO+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_LIPO"; then
+  ac_cv_prog_ac_ct_LIPO="$ac_ct_LIPO" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_LIPO="lipo"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_LIPO=$ac_cv_prog_ac_ct_LIPO
+if test -n "$ac_ct_LIPO"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_LIPO" >&5
+$as_echo "$ac_ct_LIPO" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_LIPO" = x; then
+    LIPO=":"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    LIPO=$ac_ct_LIPO
+  fi
+else
+  LIPO="$ac_cv_prog_LIPO"
+fi
+
+    if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}otool", so it can be a program name with args.
+set dummy ${ac_tool_prefix}otool; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_OTOOL+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$OTOOL"; then
+  ac_cv_prog_OTOOL="$OTOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_OTOOL="${ac_tool_prefix}otool"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+OTOOL=$ac_cv_prog_OTOOL
+if test -n "$OTOOL"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL" >&5
+$as_echo "$OTOOL" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_OTOOL"; then
+  ac_ct_OTOOL=$OTOOL
+  # Extract the first word of "otool", so it can be a program name with args.
+set dummy otool; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_OTOOL+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_OTOOL"; then
+  ac_cv_prog_ac_ct_OTOOL="$ac_ct_OTOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_OTOOL="otool"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_OTOOL=$ac_cv_prog_ac_ct_OTOOL
+if test -n "$ac_ct_OTOOL"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL" >&5
+$as_echo "$ac_ct_OTOOL" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_OTOOL" = x; then
+    OTOOL=":"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    OTOOL=$ac_ct_OTOOL
+  fi
+else
+  OTOOL="$ac_cv_prog_OTOOL"
+fi
+
+    if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}otool64", so it can be a program name with args.
+set dummy ${ac_tool_prefix}otool64; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_OTOOL64+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$OTOOL64"; then
+  ac_cv_prog_OTOOL64="$OTOOL64" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_OTOOL64="${ac_tool_prefix}otool64"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+OTOOL64=$ac_cv_prog_OTOOL64
+if test -n "$OTOOL64"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL64" >&5
+$as_echo "$OTOOL64" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_OTOOL64"; then
+  ac_ct_OTOOL64=$OTOOL64
+  # Extract the first word of "otool64", so it can be a program name with args.
+set dummy otool64; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_OTOOL64+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_OTOOL64"; then
+  ac_cv_prog_ac_ct_OTOOL64="$ac_ct_OTOOL64" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_OTOOL64="otool64"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_OTOOL64=$ac_cv_prog_ac_ct_OTOOL64
+if test -n "$ac_ct_OTOOL64"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL64" >&5
+$as_echo "$ac_ct_OTOOL64" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_OTOOL64" = x; then
+    OTOOL64=":"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    OTOOL64=$ac_ct_OTOOL64
+  fi
+else
+  OTOOL64="$ac_cv_prog_OTOOL64"
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -single_module linker flag" >&5
+$as_echo_n "checking for -single_module linker flag... " >&6; }
+if ${lt_cv_apple_cc_single_mod+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_apple_cc_single_mod=no
+      if test -z "$LT_MULTI_MODULE"; then
+	# By default we will add the -single_module flag. You can override
+	# by either setting the environment variable LT_MULTI_MODULE
+	# non-empty at configure time, or by adding -multi_module to the
+	# link flags.
+	rm -rf libconftest.dylib*
+	echo "int foo(void){return 1;}" > conftest.c
+	echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \
+-dynamiclib -Wl,-single_module conftest.c" >&5
+	$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \
+	  -dynamiclib -Wl,-single_module conftest.c 2>conftest.err
+        _lt_result=$?
+	# If there is a non-empty error log, and "single_module"
+	# appears in it, assume the flag caused a linker warning
+        if test -s conftest.err && $GREP single_module conftest.err; then
+	  cat conftest.err >&5
+	# Otherwise, if the output was created with a 0 exit code from
+	# the compiler, it worked.
+	elif test -f libconftest.dylib && test 0 = "$_lt_result"; then
+	  lt_cv_apple_cc_single_mod=yes
+	else
+	  cat conftest.err >&5
+	fi
+	rm -rf libconftest.dylib*
+	rm -f conftest.*
+      fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_apple_cc_single_mod" >&5
+$as_echo "$lt_cv_apple_cc_single_mod" >&6; }
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -exported_symbols_list linker flag" >&5
+$as_echo_n "checking for -exported_symbols_list linker flag... " >&6; }
+if ${lt_cv_ld_exported_symbols_list+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_ld_exported_symbols_list=no
+      save_LDFLAGS=$LDFLAGS
+      echo "_main" > conftest.sym
+      LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym"
+      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  lt_cv_ld_exported_symbols_list=yes
+else
+  lt_cv_ld_exported_symbols_list=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+	LDFLAGS=$save_LDFLAGS
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list" >&5
+$as_echo "$lt_cv_ld_exported_symbols_list" >&6; }
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -force_load linker flag" >&5
+$as_echo_n "checking for -force_load linker flag... " >&6; }
+if ${lt_cv_ld_force_load+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_ld_force_load=no
+      cat > conftest.c << _LT_EOF
+int forced_loaded() { return 2;}
+_LT_EOF
+      echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&5
+      $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&5
+      echo "$AR cru libconftest.a conftest.o" >&5
+      $AR cru libconftest.a conftest.o 2>&5
+      echo "$RANLIB libconftest.a" >&5
+      $RANLIB libconftest.a 2>&5
+      cat > conftest.c << _LT_EOF
+int main() { return 0;}
+_LT_EOF
+      echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&5
+      $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err
+      _lt_result=$?
+      if test -s conftest.err && $GREP force_load conftest.err; then
+	cat conftest.err >&5
+      elif test -f conftest && test 0 = "$_lt_result" && $GREP forced_load conftest >/dev/null 2>&1; then
+	lt_cv_ld_force_load=yes
+      else
+	cat conftest.err >&5
+      fi
+        rm -f conftest.err libconftest.a conftest conftest.c
+        rm -rf conftest.dSYM
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_force_load" >&5
+$as_echo "$lt_cv_ld_force_load" >&6; }
+    case $host_os in
+    rhapsody* | darwin1.[012])
+      _lt_dar_allow_undefined='$wl-undefined ${wl}suppress' ;;
+    darwin1.*)
+      _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;;
+    darwin*) # darwin 5.x on
+      # if running on 10.5 or later, the deployment target defaults
+      # to the OS version, if on x86, and 10.4, the deployment
+      # target defaults to 10.4. Don't you love it?
+      case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in
+	10.0,*86*-darwin8*|10.0,*-darwin[91]*)
+	  _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;;
+	10.[012][,.]*)
+	  _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;;
+	10.*)
+	  _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;;
+      esac
+    ;;
+  esac
+    if test yes = "$lt_cv_apple_cc_single_mod"; then
+      _lt_dar_single_mod='$single_module'
+    fi
+    if test yes = "$lt_cv_ld_exported_symbols_list"; then
+      _lt_dar_export_syms=' $wl-exported_symbols_list,$output_objdir/$libname-symbols.expsym'
+    else
+      _lt_dar_export_syms='~$NMEDIT -s $output_objdir/$libname-symbols.expsym $lib'
+    fi
+    if test : != "$DSYMUTIL" && test no = "$lt_cv_ld_force_load"; then
+      _lt_dsymutil='~$DSYMUTIL $lib || :'
+    else
+      _lt_dsymutil=
+    fi
+    ;;
+  esac
+
+# func_munge_path_list VARIABLE PATH
+# -----------------------------------
+# VARIABLE is name of variable containing _space_ separated list of
+# directories to be munged by the contents of PATH, which is string
+# having a format:
+# "DIR[:DIR]:"
+#       string "DIR[ DIR]" will be prepended to VARIABLE
+# ":DIR[:DIR]"
+#       string "DIR[ DIR]" will be appended to VARIABLE
+# "DIRP[:DIRP]::[DIRA:]DIRA"
+#       string "DIRP[ DIRP]" will be prepended to VARIABLE and string
+#       "DIRA[ DIRA]" will be appended to VARIABLE
+# "DIR[:DIR]"
+#       VARIABLE will be replaced by "DIR[ DIR]"
+func_munge_path_list ()
+{
+    case x$2 in
+    x)
+        ;;
+    *:)
+        eval $1=\"`$ECHO $2 | $SED 's/:/ /g'` \$$1\"
+        ;;
+    x:*)
+        eval $1=\"\$$1 `$ECHO $2 | $SED 's/:/ /g'`\"
+        ;;
+    *::*)
+        eval $1=\"\$$1\ `$ECHO $2 | $SED -e 's/.*:://' -e 's/:/ /g'`\"
+        eval $1=\"`$ECHO $2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \$$1\"
+        ;;
+    *)
+        eval $1=\"`$ECHO $2 | $SED 's/:/ /g'`\"
+        ;;
+    esac
+}
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5
+$as_echo_n "checking how to run the C preprocessor... " >&6; }
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+  CPP=
+fi
+if test -z "$CPP"; then
+  if ${ac_cv_prog_CPP+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+      # Double quotes because CPP needs to be expanded
+    for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
+    do
+      ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+  # Use a header file that comes with gcc, so configuring glibc
+  # with a fresh cross-compiler works.
+  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+  # <limits.h> exists even on freestanding compilers.
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp. "Syntax error" is here to catch this case.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+		     Syntax error
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+
+else
+  # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+  # OK, works on sane cases.  Now check whether nonexistent headers
+  # can be detected and how.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+  # Broken: success on invalid input.
+continue
+else
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+  break
+fi
+
+    done
+    ac_cv_prog_CPP=$CPP
+
+fi
+  CPP=$ac_cv_prog_CPP
+else
+  ac_cv_prog_CPP=$CPP
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5
+$as_echo "$CPP" >&6; }
+ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+  # Use a header file that comes with gcc, so configuring glibc
+  # with a fresh cross-compiler works.
+  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+  # <limits.h> exists even on freestanding compilers.
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp. "Syntax error" is here to catch this case.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+		     Syntax error
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+
+else
+  # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+  # OK, works on sane cases.  Now check whether nonexistent headers
+  # can be detected and how.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+  # Broken: success on invalid input.
+continue
+else
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+
+else
+  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5
+$as_echo_n "checking for ANSI C header files... " >&6; }
+if ${ac_cv_header_stdc+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_header_stdc=yes
+else
+  ac_cv_header_stdc=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+if test $ac_cv_header_stdc = yes; then
+  # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "memchr" >/dev/null 2>&1; then :
+
+else
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "free" >/dev/null 2>&1; then :
+
+else
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+  if test "$cross_compiling" = yes; then :
+  :
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <ctype.h>
+#include <stdlib.h>
+#if ((' ' & 0x0FF) == 0x020)
+# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#else
+# define ISLOWER(c) \
+		   (('a' <= (c) && (c) <= 'i') \
+		     || ('j' <= (c) && (c) <= 'r') \
+		     || ('s' <= (c) && (c) <= 'z'))
+# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
+#endif
+
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int
+main ()
+{
+  int i;
+  for (i = 0; i < 256; i++)
+    if (XOR (islower (i), ISLOWER (i))
+	|| toupper (i) != TOUPPER (i))
+      return 2;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+
+else
+  ac_cv_header_stdc=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5
+$as_echo "$ac_cv_header_stdc" >&6; }
+if test $ac_cv_header_stdc = yes; then
+
+$as_echo "#define STDC_HEADERS 1" >>confdefs.h
+
+fi
+
+# On IRIX 5.3, sys/types and inttypes.h are conflicting.
+for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
+		  inttypes.h stdint.h unistd.h
+do :
+  as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default
+"
+if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+for ac_header in dlfcn.h
+do :
+  ac_fn_c_check_header_compile "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default
+"
+if test "x$ac_cv_header_dlfcn_h" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_DLFCN_H 1
+_ACEOF
+
+fi
+
+done
+
+
+
+
+
+# Set options
+
+
+
+        enable_dlopen=no
+
+
+  enable_win32_dll=no
+
+
+            # Check whether --enable-shared was given.
+if test "${enable_shared+set}" = set; then :
+  enableval=$enable_shared; p=${PACKAGE-default}
+    case $enableval in
+    yes) enable_shared=yes ;;
+    no) enable_shared=no ;;
+    *)
+      enable_shared=no
+      # Look at the argument we got.  We use all the common list separators.
+      lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
+      for pkg in $enableval; do
+	IFS=$lt_save_ifs
+	if test "X$pkg" = "X$p"; then
+	  enable_shared=yes
+	fi
+      done
+      IFS=$lt_save_ifs
+      ;;
+    esac
+else
+  enable_shared=yes
+fi
+
+
+
+
+
+
+
+
+
+  # Check whether --enable-static was given.
+if test "${enable_static+set}" = set; then :
+  enableval=$enable_static; p=${PACKAGE-default}
+    case $enableval in
+    yes) enable_static=yes ;;
+    no) enable_static=no ;;
+    *)
+     enable_static=no
+      # Look at the argument we got.  We use all the common list separators.
+      lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
+      for pkg in $enableval; do
+	IFS=$lt_save_ifs
+	if test "X$pkg" = "X$p"; then
+	  enable_static=yes
+	fi
+      done
+      IFS=$lt_save_ifs
+      ;;
+    esac
+else
+  enable_static=yes
+fi
+
+
+
+
+
+
+
+
+
+
+# Check whether --with-pic was given.
+if test "${with_pic+set}" = set; then :
+  withval=$with_pic; lt_p=${PACKAGE-default}
+    case $withval in
+    yes|no) pic_mode=$withval ;;
+    *)
+      pic_mode=default
+      # Look at the argument we got.  We use all the common list separators.
+      lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
+      for lt_pkg in $withval; do
+	IFS=$lt_save_ifs
+	if test "X$lt_pkg" = "X$lt_p"; then
+	  pic_mode=yes
+	fi
+      done
+      IFS=$lt_save_ifs
+      ;;
+    esac
+else
+  pic_mode=default
+fi
+
+
+
+
+
+
+
+
+  # Check whether --enable-fast-install was given.
+if test "${enable_fast_install+set}" = set; then :
+  enableval=$enable_fast_install; p=${PACKAGE-default}
+    case $enableval in
+    yes) enable_fast_install=yes ;;
+    no) enable_fast_install=no ;;
+    *)
+      enable_fast_install=no
+      # Look at the argument we got.  We use all the common list separators.
+      lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
+      for pkg in $enableval; do
+	IFS=$lt_save_ifs
+	if test "X$pkg" = "X$p"; then
+	  enable_fast_install=yes
+	fi
+      done
+      IFS=$lt_save_ifs
+      ;;
+    esac
+else
+  enable_fast_install=yes
+fi
+
+
+
+
+
+
+
+
+  shared_archive_member_spec=
+case $host,$enable_shared in
+power*-*-aix[5-9]*,yes)
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking which variant of shared library versioning to provide" >&5
+$as_echo_n "checking which variant of shared library versioning to provide... " >&6; }
+
+# Check whether --with-aix-soname was given.
+if test "${with_aix_soname+set}" = set; then :
+  withval=$with_aix_soname; case $withval in
+    aix|svr4|both)
+      ;;
+    *)
+      as_fn_error $? "Unknown argument to --with-aix-soname" "$LINENO" 5
+      ;;
+    esac
+    lt_cv_with_aix_soname=$with_aix_soname
+else
+  if ${lt_cv_with_aix_soname+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_with_aix_soname=aix
+fi
+
+    with_aix_soname=$lt_cv_with_aix_soname
+fi
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_aix_soname" >&5
+$as_echo "$with_aix_soname" >&6; }
+  if test aix != "$with_aix_soname"; then
+    # For the AIX way of multilib, we name the shared archive member
+    # based on the bitwidth used, traditionally 'shr.o' or 'shr_64.o',
+    # and 'shr.imp' or 'shr_64.imp', respectively, for the Import File.
+    # Even when GNU compilers ignore OBJECT_MODE but need '-maix64' flag,
+    # the AIX toolchain works better with OBJECT_MODE set (default 32).
+    if test 64 = "${OBJECT_MODE-32}"; then
+      shared_archive_member_spec=shr_64
+    else
+      shared_archive_member_spec=shr
+    fi
+  fi
+  ;;
+*)
+  with_aix_soname=aix
+  ;;
+esac
+
+
+
+
+
+
+
+
+
+
+# This can be used to rebuild libtool when needed
+LIBTOOL_DEPS=$ltmain
+
+# Always use our own libtool.
+LIBTOOL='$(SHELL) $(top_builddir)/libtool'
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+test -z "$LN_S" && LN_S="ln -s"
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+if test -n "${ZSH_VERSION+set}"; then
+   setopt NO_GLOB_SUBST
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for objdir" >&5
+$as_echo_n "checking for objdir... " >&6; }
+if ${lt_cv_objdir+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  rm -f .libs 2>/dev/null
+mkdir .libs 2>/dev/null
+if test -d .libs; then
+  lt_cv_objdir=.libs
+else
+  # MS-DOS does not allow filenames that begin with a dot.
+  lt_cv_objdir=_libs
+fi
+rmdir .libs 2>/dev/null
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_objdir" >&5
+$as_echo "$lt_cv_objdir" >&6; }
+objdir=$lt_cv_objdir
+
+
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define LT_OBJDIR "$lt_cv_objdir/"
+_ACEOF
+
+
+
+
+case $host_os in
+aix3*)
+  # AIX sometimes has problems with the GCC collect2 program.  For some
+  # reason, if we set the COLLECT_NAMES environment variable, the problems
+  # vanish in a puff of smoke.
+  if test set != "${COLLECT_NAMES+set}"; then
+    COLLECT_NAMES=
+    export COLLECT_NAMES
+  fi
+  ;;
+esac
+
+# Global variables:
+ofile=libtool
+can_build_shared=yes
+
+# All known linkers require a '.a' archive for static linking (except MSVC,
+# which needs '.lib').
+libext=a
+
+with_gnu_ld=$lt_cv_prog_gnu_ld
+
+old_CC=$CC
+old_CFLAGS=$CFLAGS
+
+# Set sane defaults for various variables
+test -z "$CC" && CC=cc
+test -z "$LTCC" && LTCC=$CC
+test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS
+test -z "$LD" && LD=ld
+test -z "$ac_objext" && ac_objext=o
+
+func_cc_basename $compiler
+cc_basename=$func_cc_basename_result
+
+
+# Only perform the check for file, if the check method requires it
+test -z "$MAGIC_CMD" && MAGIC_CMD=file
+case $deplibs_check_method in
+file_magic*)
+  if test "$file_magic_cmd" = '$MAGIC_CMD'; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${ac_tool_prefix}file" >&5
+$as_echo_n "checking for ${ac_tool_prefix}file... " >&6; }
+if ${lt_cv_path_MAGIC_CMD+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $MAGIC_CMD in
+[\\/*] |  ?:[\\/]*)
+  lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path.
+  ;;
+*)
+  lt_save_MAGIC_CMD=$MAGIC_CMD
+  lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR
+  ac_dummy="/usr/bin$PATH_SEPARATOR$PATH"
+  for ac_dir in $ac_dummy; do
+    IFS=$lt_save_ifs
+    test -z "$ac_dir" && ac_dir=.
+    if test -f "$ac_dir/${ac_tool_prefix}file"; then
+      lt_cv_path_MAGIC_CMD=$ac_dir/"${ac_tool_prefix}file"
+      if test -n "$file_magic_test_file"; then
+	case $deplibs_check_method in
+	"file_magic "*)
+	  file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"`
+	  MAGIC_CMD=$lt_cv_path_MAGIC_CMD
+	  if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
+	    $EGREP "$file_magic_regex" > /dev/null; then
+	    :
+	  else
+	    cat <<_LT_EOF 1>&2
+
+*** Warning: the command libtool uses to detect shared libraries,
+*** $file_magic_cmd, produces output that libtool cannot recognize.
+*** The result is that libtool may fail to recognize shared libraries
+*** as such.  This will affect the creation of libtool libraries that
+*** depend on shared libraries, but programs linked with such libtool
+*** libraries will work regardless of this problem.  Nevertheless, you
+*** may want to report the problem to your system manager and/or to
+*** bug-libtool@gnu.org
+
+_LT_EOF
+	  fi ;;
+	esac
+      fi
+      break
+    fi
+  done
+  IFS=$lt_save_ifs
+  MAGIC_CMD=$lt_save_MAGIC_CMD
+  ;;
+esac
+fi
+
+MAGIC_CMD=$lt_cv_path_MAGIC_CMD
+if test -n "$MAGIC_CMD"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5
+$as_echo "$MAGIC_CMD" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+
+
+
+if test -z "$lt_cv_path_MAGIC_CMD"; then
+  if test -n "$ac_tool_prefix"; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for file" >&5
+$as_echo_n "checking for file... " >&6; }
+if ${lt_cv_path_MAGIC_CMD+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $MAGIC_CMD in
+[\\/*] |  ?:[\\/]*)
+  lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path.
+  ;;
+*)
+  lt_save_MAGIC_CMD=$MAGIC_CMD
+  lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR
+  ac_dummy="/usr/bin$PATH_SEPARATOR$PATH"
+  for ac_dir in $ac_dummy; do
+    IFS=$lt_save_ifs
+    test -z "$ac_dir" && ac_dir=.
+    if test -f "$ac_dir/file"; then
+      lt_cv_path_MAGIC_CMD=$ac_dir/"file"
+      if test -n "$file_magic_test_file"; then
+	case $deplibs_check_method in
+	"file_magic "*)
+	  file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"`
+	  MAGIC_CMD=$lt_cv_path_MAGIC_CMD
+	  if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
+	    $EGREP "$file_magic_regex" > /dev/null; then
+	    :
+	  else
+	    cat <<_LT_EOF 1>&2
+
+*** Warning: the command libtool uses to detect shared libraries,
+*** $file_magic_cmd, produces output that libtool cannot recognize.
+*** The result is that libtool may fail to recognize shared libraries
+*** as such.  This will affect the creation of libtool libraries that
+*** depend on shared libraries, but programs linked with such libtool
+*** libraries will work regardless of this problem.  Nevertheless, you
+*** may want to report the problem to your system manager and/or to
+*** bug-libtool@gnu.org
+
+_LT_EOF
+	  fi ;;
+	esac
+      fi
+      break
+    fi
+  done
+  IFS=$lt_save_ifs
+  MAGIC_CMD=$lt_save_MAGIC_CMD
+  ;;
+esac
+fi
+
+MAGIC_CMD=$lt_cv_path_MAGIC_CMD
+if test -n "$MAGIC_CMD"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5
+$as_echo "$MAGIC_CMD" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  else
+    MAGIC_CMD=:
+  fi
+fi
+
+  fi
+  ;;
+esac
+
+# Use C for the default configuration in the libtool script
+
+lt_save_CC=$CC
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+# Source file extension for C test sources.
+ac_ext=c
+
+# Object file extension for compiled C test sources.
+objext=o
+objext=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="int some_variable = 0;"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code='int main(){return(0);}'
+
+
+
+
+
+
+
+# If no C compiler was specified, use CC.
+LTCC=${LTCC-"$CC"}
+
+# If no C compiler flags were specified, use CFLAGS.
+LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
+
+# Allow CC to be a program name with arguments.
+compiler=$CC
+
+# Save the default compiler, since it gets overwritten when the other
+# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP.
+compiler_DEFAULT=$CC
+
+# save warnings/boilerplate of simple test code
+ac_outfile=conftest.$ac_objext
+echo "$lt_simple_compile_test_code" >conftest.$ac_ext
+eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_compiler_boilerplate=`cat conftest.err`
+$RM conftest*
+
+ac_outfile=conftest.$ac_objext
+echo "$lt_simple_link_test_code" >conftest.$ac_ext
+eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_linker_boilerplate=`cat conftest.err`
+$RM -r conftest*
+
+
+## CAVEAT EMPTOR:
+## There is no encapsulation within the following macros, do not change
+## the running order or otherwise move them around unless you know exactly
+## what you are doing...
+if test -n "$compiler"; then
+
+lt_prog_compiler_no_builtin_flag=
+
+if test yes = "$GCC"; then
+  case $cc_basename in
+  nvcc*)
+    lt_prog_compiler_no_builtin_flag=' -Xcompiler -fno-builtin' ;;
+  *)
+    lt_prog_compiler_no_builtin_flag=' -fno-builtin' ;;
+  esac
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -fno-rtti -fno-exceptions" >&5
+$as_echo_n "checking if $compiler supports -fno-rtti -fno-exceptions... " >&6; }
+if ${lt_cv_prog_compiler_rtti_exceptions+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_prog_compiler_rtti_exceptions=no
+   ac_outfile=conftest.$ac_objext
+   echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+   lt_compiler_flag="-fno-rtti -fno-exceptions"  ## exclude from sc_useless_quotes_in_assignment
+   # Insert the option either (1) after the last *FLAGS variable, or
+   # (2) before a word containing "conftest.", or (3) at the end.
+   # Note that $ac_compile itself does not contain backslashes and begins
+   # with a dollar sign (not a hyphen), so the echo should work correctly.
+   # The option is referenced via a variable to avoid confusing sed.
+   lt_compile=`echo "$ac_compile" | $SED \
+   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+   -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+   -e 's:$: $lt_compiler_flag:'`
+   (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>conftest.err)
+   ac_status=$?
+   cat conftest.err >&5
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
+   if (exit $ac_status) && test -s "$ac_outfile"; then
+     # The compiler can only warn and ignore the option if not recognized
+     # So say no if there are warnings other than the usual output.
+     $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp
+     $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+     if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
+       lt_cv_prog_compiler_rtti_exceptions=yes
+     fi
+   fi
+   $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_rtti_exceptions" >&5
+$as_echo "$lt_cv_prog_compiler_rtti_exceptions" >&6; }
+
+if test yes = "$lt_cv_prog_compiler_rtti_exceptions"; then
+    lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions"
+else
+    :
+fi
+
+fi
+
+
+
+
+
+
+  lt_prog_compiler_wl=
+lt_prog_compiler_pic=
+lt_prog_compiler_static=
+
+
+  if test yes = "$GCC"; then
+    lt_prog_compiler_wl='-Wl,'
+    lt_prog_compiler_static='-static'
+
+    case $host_os in
+      aix*)
+      # All AIX code is PIC.
+      if test ia64 = "$host_cpu"; then
+	# AIX 5 now supports IA64 processor
+	lt_prog_compiler_static='-Bstatic'
+      fi
+      lt_prog_compiler_pic='-fPIC'
+      ;;
+
+    amigaos*)
+      case $host_cpu in
+      powerpc)
+            # see comment about AmigaOS4 .so support
+            lt_prog_compiler_pic='-fPIC'
+        ;;
+      m68k)
+            # FIXME: we need at least 68020 code to build shared libraries, but
+            # adding the '-m68020' flag to GCC prevents building anything better,
+            # like '-m68040'.
+            lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4'
+        ;;
+      esac
+      ;;
+
+    beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
+      # PIC is the default for these OSes.
+      ;;
+
+    mingw* | cygwin* | pw32* | os2* | cegcc*)
+      # This hack is so that the source file can tell whether it is being
+      # built for inclusion in a dll (and should export symbols for example).
+      # Although the cygwin gcc ignores -fPIC, still need this for old-style
+      # (--disable-auto-import) libraries
+      lt_prog_compiler_pic='-DDLL_EXPORT'
+      case $host_os in
+      os2*)
+	lt_prog_compiler_static='$wl-static'
+	;;
+      esac
+      ;;
+
+    darwin* | rhapsody*)
+      # PIC is the default on this platform
+      # Common symbols not allowed in MH_DYLIB files
+      lt_prog_compiler_pic='-fno-common'
+      ;;
+
+    haiku*)
+      # PIC is the default for Haiku.
+      # The "-static" flag exists, but is broken.
+      lt_prog_compiler_static=
+      ;;
+
+    hpux*)
+      # PIC is the default for 64-bit PA HP-UX, but not for 32-bit
+      # PA HP-UX.  On IA64 HP-UX, PIC is the default but the pic flag
+      # sets the default TLS model and affects inlining.
+      case $host_cpu in
+      hppa*64*)
+	# +Z the default
+	;;
+      *)
+	lt_prog_compiler_pic='-fPIC'
+	;;
+      esac
+      ;;
+
+    interix[3-9]*)
+      # Interix 3.x gcc -fpic/-fPIC options generate broken code.
+      # Instead, we relocate shared libraries at runtime.
+      ;;
+
+    msdosdjgpp*)
+      # Just because we use GCC doesn't mean we suddenly get shared libraries
+      # on systems that don't support them.
+      lt_prog_compiler_can_build_shared=no
+      enable_shared=no
+      ;;
+
+    *nto* | *qnx*)
+      # QNX uses GNU C++, but need to define -shared option too, otherwise
+      # it will coredump.
+      lt_prog_compiler_pic='-fPIC -shared'
+      ;;
+
+    sysv4*MP*)
+      if test -d /usr/nec; then
+	lt_prog_compiler_pic=-Kconform_pic
+      fi
+      ;;
+
+    *)
+      lt_prog_compiler_pic='-fPIC'
+      ;;
+    esac
+
+    case $cc_basename in
+    nvcc*) # Cuda Compiler Driver 2.2
+      lt_prog_compiler_wl='-Xlinker '
+      if test -n "$lt_prog_compiler_pic"; then
+        lt_prog_compiler_pic="-Xcompiler $lt_prog_compiler_pic"
+      fi
+      ;;
+    esac
+  else
+    # PORTME Check for flag to pass linker flags through the system compiler.
+    case $host_os in
+    aix*)
+      lt_prog_compiler_wl='-Wl,'
+      if test ia64 = "$host_cpu"; then
+	# AIX 5 now supports IA64 processor
+	lt_prog_compiler_static='-Bstatic'
+      else
+	lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp'
+      fi
+      ;;
+
+    darwin* | rhapsody*)
+      # PIC is the default on this platform
+      # Common symbols not allowed in MH_DYLIB files
+      lt_prog_compiler_pic='-fno-common'
+      case $cc_basename in
+      nagfor*)
+        # NAG Fortran compiler
+        lt_prog_compiler_wl='-Wl,-Wl,,'
+        lt_prog_compiler_pic='-PIC'
+        lt_prog_compiler_static='-Bstatic'
+        ;;
+      esac
+      ;;
+
+    mingw* | cygwin* | pw32* | os2* | cegcc*)
+      # This hack is so that the source file can tell whether it is being
+      # built for inclusion in a dll (and should export symbols for example).
+      lt_prog_compiler_pic='-DDLL_EXPORT'
+      case $host_os in
+      os2*)
+	lt_prog_compiler_static='$wl-static'
+	;;
+      esac
+      ;;
+
+    hpux9* | hpux10* | hpux11*)
+      lt_prog_compiler_wl='-Wl,'
+      # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
+      # not for PA HP-UX.
+      case $host_cpu in
+      hppa*64*|ia64*)
+	# +Z the default
+	;;
+      *)
+	lt_prog_compiler_pic='+Z'
+	;;
+      esac
+      # Is there a better lt_prog_compiler_static that works with the bundled CC?
+      lt_prog_compiler_static='$wl-a ${wl}archive'
+      ;;
+
+    irix5* | irix6* | nonstopux*)
+      lt_prog_compiler_wl='-Wl,'
+      # PIC (with -KPIC) is the default.
+      lt_prog_compiler_static='-non_shared'
+      ;;
+
+    linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
+      case $cc_basename in
+      # old Intel for x86_64, which still supported -KPIC.
+      ecc*)
+	lt_prog_compiler_wl='-Wl,'
+	lt_prog_compiler_pic='-KPIC'
+	lt_prog_compiler_static='-static'
+        ;;
+      # icc used to be incompatible with GCC.
+      # ICC 10 doesn't accept -KPIC any more.
+      icc* | ifort*)
+	lt_prog_compiler_wl='-Wl,'
+	lt_prog_compiler_pic='-fPIC'
+	lt_prog_compiler_static='-static'
+        ;;
+      # Lahey Fortran 8.1.
+      lf95*)
+	lt_prog_compiler_wl='-Wl,'
+	lt_prog_compiler_pic='--shared'
+	lt_prog_compiler_static='--static'
+	;;
+      nagfor*)
+	# NAG Fortran compiler
+	lt_prog_compiler_wl='-Wl,-Wl,,'
+	lt_prog_compiler_pic='-PIC'
+	lt_prog_compiler_static='-Bstatic'
+	;;
+      tcc*)
+	# Fabrice Bellard et al's Tiny C Compiler
+	lt_prog_compiler_wl='-Wl,'
+	lt_prog_compiler_pic='-fPIC'
+	lt_prog_compiler_static='-static'
+	;;
+      pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*)
+        # Portland Group compilers (*not* the Pentium gcc compiler,
+	# which looks to be a dead project)
+	lt_prog_compiler_wl='-Wl,'
+	lt_prog_compiler_pic='-fpic'
+	lt_prog_compiler_static='-Bstatic'
+        ;;
+      ccc*)
+        lt_prog_compiler_wl='-Wl,'
+        # All Alpha code is PIC.
+        lt_prog_compiler_static='-non_shared'
+        ;;
+      xl* | bgxl* | bgf* | mpixl*)
+	# IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene
+	lt_prog_compiler_wl='-Wl,'
+	lt_prog_compiler_pic='-qpic'
+	lt_prog_compiler_static='-qstaticlink'
+	;;
+      *)
+	case `$CC -V 2>&1 | sed 5q` in
+	*Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [1-7].* | *Sun*Fortran*\ 8.[0-3]*)
+	  # Sun Fortran 8.3 passes all unrecognized flags to the linker
+	  lt_prog_compiler_pic='-KPIC'
+	  lt_prog_compiler_static='-Bstatic'
+	  lt_prog_compiler_wl=''
+	  ;;
+	*Sun\ F* | *Sun*Fortran*)
+	  lt_prog_compiler_pic='-KPIC'
+	  lt_prog_compiler_static='-Bstatic'
+	  lt_prog_compiler_wl='-Qoption ld '
+	  ;;
+	*Sun\ C*)
+	  # Sun C 5.9
+	  lt_prog_compiler_pic='-KPIC'
+	  lt_prog_compiler_static='-Bstatic'
+	  lt_prog_compiler_wl='-Wl,'
+	  ;;
+        *Intel*\ [CF]*Compiler*)
+	  lt_prog_compiler_wl='-Wl,'
+	  lt_prog_compiler_pic='-fPIC'
+	  lt_prog_compiler_static='-static'
+	  ;;
+	*Portland\ Group*)
+	  lt_prog_compiler_wl='-Wl,'
+	  lt_prog_compiler_pic='-fpic'
+	  lt_prog_compiler_static='-Bstatic'
+	  ;;
+	esac
+	;;
+      esac
+      ;;
+
+    newsos6)
+      lt_prog_compiler_pic='-KPIC'
+      lt_prog_compiler_static='-Bstatic'
+      ;;
+
+    *nto* | *qnx*)
+      # QNX uses GNU C++, but need to define -shared option too, otherwise
+      # it will coredump.
+      lt_prog_compiler_pic='-fPIC -shared'
+      ;;
+
+    osf3* | osf4* | osf5*)
+      lt_prog_compiler_wl='-Wl,'
+      # All OSF/1 code is PIC.
+      lt_prog_compiler_static='-non_shared'
+      ;;
+
+    rdos*)
+      lt_prog_compiler_static='-non_shared'
+      ;;
+
+    solaris*)
+      lt_prog_compiler_pic='-KPIC'
+      lt_prog_compiler_static='-Bstatic'
+      case $cc_basename in
+      f77* | f90* | f95* | sunf77* | sunf90* | sunf95*)
+	lt_prog_compiler_wl='-Qoption ld ';;
+      *)
+	lt_prog_compiler_wl='-Wl,';;
+      esac
+      ;;
+
+    sunos4*)
+      lt_prog_compiler_wl='-Qoption ld '
+      lt_prog_compiler_pic='-PIC'
+      lt_prog_compiler_static='-Bstatic'
+      ;;
+
+    sysv4 | sysv4.2uw2* | sysv4.3*)
+      lt_prog_compiler_wl='-Wl,'
+      lt_prog_compiler_pic='-KPIC'
+      lt_prog_compiler_static='-Bstatic'
+      ;;
+
+    sysv4*MP*)
+      if test -d /usr/nec; then
+	lt_prog_compiler_pic='-Kconform_pic'
+	lt_prog_compiler_static='-Bstatic'
+      fi
+      ;;
+
+    sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
+      lt_prog_compiler_wl='-Wl,'
+      lt_prog_compiler_pic='-KPIC'
+      lt_prog_compiler_static='-Bstatic'
+      ;;
+
+    unicos*)
+      lt_prog_compiler_wl='-Wl,'
+      lt_prog_compiler_can_build_shared=no
+      ;;
+
+    uts4*)
+      lt_prog_compiler_pic='-pic'
+      lt_prog_compiler_static='-Bstatic'
+      ;;
+
+    *)
+      lt_prog_compiler_can_build_shared=no
+      ;;
+    esac
+  fi
+
+case $host_os in
+  # For platforms that do not support PIC, -DPIC is meaningless:
+  *djgpp*)
+    lt_prog_compiler_pic=
+    ;;
+  *)
+    lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC"
+    ;;
+esac
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5
+$as_echo_n "checking for $compiler option to produce PIC... " >&6; }
+if ${lt_cv_prog_compiler_pic+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_prog_compiler_pic=$lt_prog_compiler_pic
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic" >&5
+$as_echo "$lt_cv_prog_compiler_pic" >&6; }
+lt_prog_compiler_pic=$lt_cv_prog_compiler_pic
+
+#
+# Check to make sure the PIC flag actually works.
+#
+if test -n "$lt_prog_compiler_pic"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5
+$as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic works... " >&6; }
+if ${lt_cv_prog_compiler_pic_works+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_prog_compiler_pic_works=no
+   ac_outfile=conftest.$ac_objext
+   echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+   lt_compiler_flag="$lt_prog_compiler_pic -DPIC"  ## exclude from sc_useless_quotes_in_assignment
+   # Insert the option either (1) after the last *FLAGS variable, or
+   # (2) before a word containing "conftest.", or (3) at the end.
+   # Note that $ac_compile itself does not contain backslashes and begins
+   # with a dollar sign (not a hyphen), so the echo should work correctly.
+   # The option is referenced via a variable to avoid confusing sed.
+   lt_compile=`echo "$ac_compile" | $SED \
+   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+   -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+   -e 's:$: $lt_compiler_flag:'`
+   (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>conftest.err)
+   ac_status=$?
+   cat conftest.err >&5
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
+   if (exit $ac_status) && test -s "$ac_outfile"; then
+     # The compiler can only warn and ignore the option if not recognized
+     # So say no if there are warnings other than the usual output.
+     $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp
+     $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+     if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
+       lt_cv_prog_compiler_pic_works=yes
+     fi
+   fi
+   $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works" >&5
+$as_echo "$lt_cv_prog_compiler_pic_works" >&6; }
+
+if test yes = "$lt_cv_prog_compiler_pic_works"; then
+    case $lt_prog_compiler_pic in
+     "" | " "*) ;;
+     *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;;
+     esac
+else
+    lt_prog_compiler_pic=
+     lt_prog_compiler_can_build_shared=no
+fi
+
+fi
+
+
+
+
+
+
+
+
+
+
+
+#
+# Check to make sure the static flag actually works.
+#
+wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\"
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5
+$as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; }
+if ${lt_cv_prog_compiler_static_works+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_prog_compiler_static_works=no
+   save_LDFLAGS=$LDFLAGS
+   LDFLAGS="$LDFLAGS $lt_tmp_static_flag"
+   echo "$lt_simple_link_test_code" > conftest.$ac_ext
+   if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
+     # The linker can only warn and ignore the option if not recognized
+     # So say no if there are warnings
+     if test -s conftest.err; then
+       # Append any errors to the config.log.
+       cat conftest.err 1>&5
+       $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp
+       $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+       if diff conftest.exp conftest.er2 >/dev/null; then
+         lt_cv_prog_compiler_static_works=yes
+       fi
+     else
+       lt_cv_prog_compiler_static_works=yes
+     fi
+   fi
+   $RM -r conftest*
+   LDFLAGS=$save_LDFLAGS
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works" >&5
+$as_echo "$lt_cv_prog_compiler_static_works" >&6; }
+
+if test yes = "$lt_cv_prog_compiler_static_works"; then
+    :
+else
+    lt_prog_compiler_static=
+fi
+
+
+
+
+
+
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5
+$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; }
+if ${lt_cv_prog_compiler_c_o+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_prog_compiler_c_o=no
+   $RM -r conftest 2>/dev/null
+   mkdir conftest
+   cd conftest
+   mkdir out
+   echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+   lt_compiler_flag="-o out/conftest2.$ac_objext"
+   # Insert the option either (1) after the last *FLAGS variable, or
+   # (2) before a word containing "conftest.", or (3) at the end.
+   # Note that $ac_compile itself does not contain backslashes and begins
+   # with a dollar sign (not a hyphen), so the echo should work correctly.
+   lt_compile=`echo "$ac_compile" | $SED \
+   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+   -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+   -e 's:$: $lt_compiler_flag:'`
+   (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>out/conftest.err)
+   ac_status=$?
+   cat out/conftest.err >&5
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
+   if (exit $ac_status) && test -s out/conftest2.$ac_objext
+   then
+     # The compiler can only warn and ignore the option if not recognized
+     # So say no if there are warnings
+     $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp
+     $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
+     if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
+       lt_cv_prog_compiler_c_o=yes
+     fi
+   fi
+   chmod u+w . 2>&5
+   $RM conftest*
+   # SGI C++ compiler will create directory out/ii_files/ for
+   # template instantiation
+   test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files
+   $RM out/* && rmdir out
+   cd ..
+   $RM -r conftest
+   $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5
+$as_echo "$lt_cv_prog_compiler_c_o" >&6; }
+
+
+
+
+
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5
+$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; }
+if ${lt_cv_prog_compiler_c_o+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_prog_compiler_c_o=no
+   $RM -r conftest 2>/dev/null
+   mkdir conftest
+   cd conftest
+   mkdir out
+   echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+   lt_compiler_flag="-o out/conftest2.$ac_objext"
+   # Insert the option either (1) after the last *FLAGS variable, or
+   # (2) before a word containing "conftest.", or (3) at the end.
+   # Note that $ac_compile itself does not contain backslashes and begins
+   # with a dollar sign (not a hyphen), so the echo should work correctly.
+   lt_compile=`echo "$ac_compile" | $SED \
+   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+   -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+   -e 's:$: $lt_compiler_flag:'`
+   (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>out/conftest.err)
+   ac_status=$?
+   cat out/conftest.err >&5
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
+   if (exit $ac_status) && test -s out/conftest2.$ac_objext
+   then
+     # The compiler can only warn and ignore the option if not recognized
+     # So say no if there are warnings
+     $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp
+     $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
+     if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
+       lt_cv_prog_compiler_c_o=yes
+     fi
+   fi
+   chmod u+w . 2>&5
+   $RM conftest*
+   # SGI C++ compiler will create directory out/ii_files/ for
+   # template instantiation
+   test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files
+   $RM out/* && rmdir out
+   cd ..
+   $RM -r conftest
+   $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5
+$as_echo "$lt_cv_prog_compiler_c_o" >&6; }
+
+
+
+
+hard_links=nottested
+if test no = "$lt_cv_prog_compiler_c_o" && test no != "$need_locks"; then
+  # do not overwrite the value of need_locks provided by the user
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5
+$as_echo_n "checking if we can lock with hard links... " >&6; }
+  hard_links=yes
+  $RM conftest*
+  ln conftest.a conftest.b 2>/dev/null && hard_links=no
+  touch conftest.a
+  ln conftest.a conftest.b 2>&5 || hard_links=no
+  ln conftest.a conftest.b 2>/dev/null && hard_links=no
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5
+$as_echo "$hard_links" >&6; }
+  if test no = "$hard_links"; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&5
+$as_echo "$as_me: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&2;}
+    need_locks=warn
+  fi
+else
+  need_locks=no
+fi
+
+
+
+
+
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5
+$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; }
+
+  runpath_var=
+  allow_undefined_flag=
+  always_export_symbols=no
+  archive_cmds=
+  archive_expsym_cmds=
+  compiler_needs_object=no
+  enable_shared_with_static_runtimes=no
+  export_dynamic_flag_spec=
+  export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+  hardcode_automatic=no
+  hardcode_direct=no
+  hardcode_direct_absolute=no
+  hardcode_libdir_flag_spec=
+  hardcode_libdir_separator=
+  hardcode_minus_L=no
+  hardcode_shlibpath_var=unsupported
+  inherit_rpath=no
+  link_all_deplibs=unknown
+  module_cmds=
+  module_expsym_cmds=
+  old_archive_from_new_cmds=
+  old_archive_from_expsyms_cmds=
+  thread_safe_flag_spec=
+  whole_archive_flag_spec=
+  # include_expsyms should be a list of space-separated symbols to be *always*
+  # included in the symbol list
+  include_expsyms=
+  # exclude_expsyms can be an extended regexp of symbols to exclude
+  # it will be wrapped by ' (' and ')$', so one must not match beginning or
+  # end of line.  Example: 'a|bc|.*d.*' will exclude the symbols 'a' and 'bc',
+  # as well as any symbol that contains 'd'.
+  exclude_expsyms='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'
+  # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out
+  # platforms (ab)use it in PIC code, but their linkers get confused if
+  # the symbol is explicitly referenced.  Since portable code cannot
+  # rely on this symbol name, it's probably fine to never include it in
+  # preloaded symbol tables.
+  # Exclude shared library initialization/finalization symbols.
+  extract_expsyms_cmds=
+
+  case $host_os in
+  cygwin* | mingw* | pw32* | cegcc*)
+    # FIXME: the MSVC++ port hasn't been tested in a loooong time
+    # When not using gcc, we currently assume that we are using
+    # Microsoft Visual C++.
+    if test yes != "$GCC"; then
+      with_gnu_ld=no
+    fi
+    ;;
+  interix*)
+    # we just hope/assume this is gcc and not c89 (= MSVC++)
+    with_gnu_ld=yes
+    ;;
+  openbsd* | bitrig*)
+    with_gnu_ld=no
+    ;;
+  linux* | k*bsd*-gnu | gnu*)
+    link_all_deplibs=no
+    ;;
+  esac
+
+  ld_shlibs=yes
+
+  # On some targets, GNU ld is compatible enough with the native linker
+  # that we're better off using the native interface for both.
+  lt_use_gnu_ld_interface=no
+  if test yes = "$with_gnu_ld"; then
+    case $host_os in
+      aix*)
+	# The AIX port of GNU ld has always aspired to compatibility
+	# with the native linker.  However, as the warning in the GNU ld
+	# block says, versions before 2.19.5* couldn't really create working
+	# shared libraries, regardless of the interface used.
+	case `$LD -v 2>&1` in
+	  *\ \(GNU\ Binutils\)\ 2.19.5*) ;;
+	  *\ \(GNU\ Binutils\)\ 2.[2-9]*) ;;
+	  *\ \(GNU\ Binutils\)\ [3-9]*) ;;
+	  *)
+	    lt_use_gnu_ld_interface=yes
+	    ;;
+	esac
+	;;
+      *)
+	lt_use_gnu_ld_interface=yes
+	;;
+    esac
+  fi
+
+  if test yes = "$lt_use_gnu_ld_interface"; then
+    # If archive_cmds runs LD, not CC, wlarc should be empty
+    wlarc='$wl'
+
+    # Set some defaults for GNU ld with shared library support. These
+    # are reset later if shared libraries are not supported. Putting them
+    # here allows them to be overridden if necessary.
+    runpath_var=LD_RUN_PATH
+    hardcode_libdir_flag_spec='$wl-rpath $wl$libdir'
+    export_dynamic_flag_spec='$wl--export-dynamic'
+    # ancient GNU ld didn't support --whole-archive et. al.
+    if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then
+      whole_archive_flag_spec=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive'
+    else
+      whole_archive_flag_spec=
+    fi
+    supports_anon_versioning=no
+    case `$LD -v | $SED -e 's/(^)\+)\s\+//' 2>&1` in
+      *GNU\ gold*) supports_anon_versioning=yes ;;
+      *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11
+      *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ...
+      *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ...
+      *\ 2.11.*) ;; # other 2.11 versions
+      *) supports_anon_versioning=yes ;;
+    esac
+
+    # See if GNU ld supports shared libraries.
+    case $host_os in
+    aix[3-9]*)
+      # On AIX/PPC, the GNU linker is very broken
+      if test ia64 != "$host_cpu"; then
+	ld_shlibs=no
+	cat <<_LT_EOF 1>&2
+
+*** Warning: the GNU linker, at least up to release 2.19, is reported
+*** to be unable to reliably create shared libraries on AIX.
+*** Therefore, libtool is disabling shared libraries support.  If you
+*** really care for shared libraries, you may want to install binutils
+*** 2.20 or above, or modify your PATH so that a non-GNU linker is found.
+*** You will then need to restart the configuration process.
+
+_LT_EOF
+      fi
+      ;;
+
+    amigaos*)
+      case $host_cpu in
+      powerpc)
+            # see comment about AmigaOS4 .so support
+            archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+            archive_expsym_cmds=''
+        ;;
+      m68k)
+            archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+            hardcode_libdir_flag_spec='-L$libdir'
+            hardcode_minus_L=yes
+        ;;
+      esac
+      ;;
+
+    beos*)
+      if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+	allow_undefined_flag=unsupported
+	# Joseph Beckenbach <jrb3@best.com> says some releases of gcc
+	# support --undefined.  This deserves some investigation.  FIXME
+	archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+      else
+	ld_shlibs=no
+      fi
+      ;;
+
+    cygwin* | mingw* | pw32* | cegcc*)
+      # _LT_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless,
+      # as there is no search path for DLLs.
+      hardcode_libdir_flag_spec='-L$libdir'
+      export_dynamic_flag_spec='$wl--export-all-symbols'
+      allow_undefined_flag=unsupported
+      always_export_symbols=no
+      enable_shared_with_static_runtimes=yes
+      export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols'
+      exclude_expsyms='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'
+
+      if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
+        archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+	# If the export-symbols file already is a .def file, use it as
+	# is; otherwise, prepend EXPORTS...
+	archive_expsym_cmds='if   test DEF = "`$SED -n     -e '\''s/^[	 ]*//'\''     -e '\''/^\(;.*\)*$/d'\''     -e '\''s/^\(EXPORTS\|LIBRARY\)\([	 ].*\)*$/DEF/p'\''     -e q     $export_symbols`" ; then
+          cp $export_symbols $output_objdir/$soname.def;
+        else
+          echo EXPORTS > $output_objdir/$soname.def;
+          cat $export_symbols >> $output_objdir/$soname.def;
+        fi~
+        $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+      else
+	ld_shlibs=no
+      fi
+      ;;
+
+    haiku*)
+      archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+      link_all_deplibs=yes
+      ;;
+
+    os2*)
+      hardcode_libdir_flag_spec='-L$libdir'
+      hardcode_minus_L=yes
+      allow_undefined_flag=unsupported
+      shrext_cmds=.dll
+      archive_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
+	$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
+	$ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
+	$ECHO EXPORTS >> $output_objdir/$libname.def~
+	emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~
+	$CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
+	emximp -o $lib $output_objdir/$libname.def'
+      archive_expsym_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
+	$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
+	$ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
+	$ECHO EXPORTS >> $output_objdir/$libname.def~
+	prefix_cmds="$SED"~
+	if test EXPORTS = "`$SED 1q $export_symbols`"; then
+	  prefix_cmds="$prefix_cmds -e 1d";
+	fi~
+	prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~
+	cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~
+	$CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
+	emximp -o $lib $output_objdir/$libname.def'
+      old_archive_From_new_cmds='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def'
+      enable_shared_with_static_runtimes=yes
+      ;;
+
+    interix[3-9]*)
+      hardcode_direct=no
+      hardcode_shlibpath_var=no
+      hardcode_libdir_flag_spec='$wl-rpath,$libdir'
+      export_dynamic_flag_spec='$wl-E'
+      # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
+      # Instead, shared libraries are loaded at an image base (0x10000000 by
+      # default) and relocated if they conflict, which is a slow very memory
+      # consuming and fragmenting process.  To avoid this, we pick a random,
+      # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
+      # time.  Moving up from 0x10000000 also allows more sbrk(2) space.
+      archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+      archive_expsym_cmds='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+      ;;
+
+    gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu)
+      tmp_diet=no
+      if test linux-dietlibc = "$host_os"; then
+	case $cc_basename in
+	  diet\ *) tmp_diet=yes;;	# linux-dietlibc with static linking (!diet-dyn)
+	esac
+      fi
+      if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \
+	 && test no = "$tmp_diet"
+      then
+	tmp_addflag=' $pic_flag'
+	tmp_sharedflag='-shared'
+	case $cc_basename,$host_cpu in
+        pgcc*)				# Portland Group C compiler
+	  whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+	  tmp_addflag=' $pic_flag'
+	  ;;
+	pgf77* | pgf90* | pgf95* | pgfortran*)
+					# Portland Group f77 and f90 compilers
+	  whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+	  tmp_addflag=' $pic_flag -Mnomain' ;;
+	ecc*,ia64* | icc*,ia64*)	# Intel C compiler on ia64
+	  tmp_addflag=' -i_dynamic' ;;
+	efc*,ia64* | ifort*,ia64*)	# Intel Fortran compiler on ia64
+	  tmp_addflag=' -i_dynamic -nofor_main' ;;
+	ifc* | ifort*)			# Intel Fortran compiler
+	  tmp_addflag=' -nofor_main' ;;
+	lf95*)				# Lahey Fortran 8.1
+	  whole_archive_flag_spec=
+	  tmp_sharedflag='--shared' ;;
+        nagfor*)                        # NAGFOR 5.3
+          tmp_sharedflag='-Wl,-shared' ;;
+	xl[cC]* | bgxl[cC]* | mpixl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below)
+	  tmp_sharedflag='-qmkshrobj'
+	  tmp_addflag= ;;
+	nvcc*)	# Cuda Compiler Driver 2.2
+	  whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+	  compiler_needs_object=yes
+	  ;;
+	esac
+	case `$CC -V 2>&1 | sed 5q` in
+	*Sun\ C*)			# Sun C 5.9
+	  whole_archive_flag_spec='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+	  compiler_needs_object=yes
+	  tmp_sharedflag='-G' ;;
+	*Sun\ F*)			# Sun Fortran 8.3
+	  tmp_sharedflag='-G' ;;
+	esac
+	archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+
+        if test yes = "$supports_anon_versioning"; then
+          archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~
+            cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+            echo "local: *; };" >> $output_objdir/$libname.ver~
+            $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib'
+        fi
+
+	case $cc_basename in
+	tcc*)
+	  export_dynamic_flag_spec='-rdynamic'
+	  ;;
+	xlf* | bgf* | bgxlf* | mpixlf*)
+	  # IBM XL Fortran 10.1 on PPC cannot create shared libs itself
+	  whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive'
+	  hardcode_libdir_flag_spec='$wl-rpath $wl$libdir'
+	  archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib'
+	  if test yes = "$supports_anon_versioning"; then
+	    archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~
+              cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+              echo "local: *; };" >> $output_objdir/$libname.ver~
+              $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib'
+	  fi
+	  ;;
+	esac
+      else
+        ld_shlibs=no
+      fi
+      ;;
+
+    netbsd* | netbsdelf*-gnu)
+      if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+	archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
+	wlarc=
+      else
+	archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+	archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+      fi
+      ;;
+
+    solaris*)
+      if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then
+	ld_shlibs=no
+	cat <<_LT_EOF 1>&2
+
+*** Warning: The releases 2.8.* of the GNU linker cannot reliably
+*** create shared libraries on Solaris systems.  Therefore, libtool
+*** is disabling shared libraries support.  We urge you to upgrade GNU
+*** binutils to release 2.9.1 or newer.  Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+_LT_EOF
+      elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+	archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+	archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+      else
+	ld_shlibs=no
+      fi
+      ;;
+
+    sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*)
+      case `$LD -v 2>&1` in
+        *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*)
+	ld_shlibs=no
+	cat <<_LT_EOF 1>&2
+
+*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 cannot
+*** reliably create shared libraries on SCO systems.  Therefore, libtool
+*** is disabling shared libraries support.  We urge you to upgrade GNU
+*** binutils to release 2.16.91.0.3 or newer.  Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+_LT_EOF
+	;;
+	*)
+	  # For security reasons, it is highly recommended that you always
+	  # use absolute paths for naming shared libraries, and exclude the
+	  # DT_RUNPATH tag from executables and libraries.  But doing so
+	  # requires that you compile everything twice, which is a pain.
+	  if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+	    hardcode_libdir_flag_spec='$wl-rpath $wl$libdir'
+	    archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+	    archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+	  else
+	    ld_shlibs=no
+	  fi
+	;;
+      esac
+      ;;
+
+    sunos4*)
+      archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+      wlarc=
+      hardcode_direct=yes
+      hardcode_shlibpath_var=no
+      ;;
+
+    *)
+      if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+	archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+	archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+      else
+	ld_shlibs=no
+      fi
+      ;;
+    esac
+
+    if test no = "$ld_shlibs"; then
+      runpath_var=
+      hardcode_libdir_flag_spec=
+      export_dynamic_flag_spec=
+      whole_archive_flag_spec=
+    fi
+  else
+    # PORTME fill in a description of your system's linker (not GNU ld)
+    case $host_os in
+    aix3*)
+      allow_undefined_flag=unsupported
+      always_export_symbols=yes
+      archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname'
+      # Note: this linker hardcodes the directories in LIBPATH if there
+      # are no directories specified by -L.
+      hardcode_minus_L=yes
+      if test yes = "$GCC" && test -z "$lt_prog_compiler_static"; then
+	# Neither direct hardcoding nor static linking is supported with a
+	# broken collect2.
+	hardcode_direct=unsupported
+      fi
+      ;;
+
+    aix[4-9]*)
+      if test ia64 = "$host_cpu"; then
+	# On IA64, the linker does run time linking by default, so we don't
+	# have to do anything special.
+	aix_use_runtimelinking=no
+	exp_sym_flag='-Bexport'
+	no_entry_flag=
+      else
+	# If we're using GNU nm, then we don't want the "-C" option.
+	# -C means demangle to GNU nm, but means don't demangle to AIX nm.
+	# Without the "-l" option, or with the "-B" option, AIX nm treats
+	# weak defined symbols like other global defined symbols, whereas
+	# GNU nm marks them as "W".
+	# While the 'weak' keyword is ignored in the Export File, we need
+	# it in the Import File for the 'aix-soname' feature, so we have
+	# to replace the "-B" option with "-P" for AIX nm.
+	if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
+	  export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols'
+	else
+	  export_symbols_cmds='`func_echo_all $NM | $SED -e '\''s/B\([^B]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && (substr(\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols'
+	fi
+	aix_use_runtimelinking=no
+
+	# Test if we are trying to use run time linking or normal
+	# AIX style linking. If -brtl is somewhere in LDFLAGS, we
+	# have runtime linking enabled, and use it for executables.
+	# For shared libraries, we enable/disable runtime linking
+	# depending on the kind of the shared library created -
+	# when "with_aix_soname,aix_use_runtimelinking" is:
+	# "aix,no"   lib.a(lib.so.V) shared, rtl:no,  for executables
+	# "aix,yes"  lib.so          shared, rtl:yes, for executables
+	#            lib.a           static archive
+	# "both,no"  lib.so.V(shr.o) shared, rtl:yes
+	#            lib.a(lib.so.V) shared, rtl:no,  for executables
+	# "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables
+	#            lib.a(lib.so.V) shared, rtl:no
+	# "svr4,*"   lib.so.V(shr.o) shared, rtl:yes, for executables
+	#            lib.a           static archive
+	case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*)
+	  for ld_flag in $LDFLAGS; do
+	  if (test x-brtl = "x$ld_flag" || test x-Wl,-brtl = "x$ld_flag"); then
+	    aix_use_runtimelinking=yes
+	    break
+	  fi
+	  done
+	  if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then
+	    # With aix-soname=svr4, we create the lib.so.V shared archives only,
+	    # so we don't have lib.a shared libs to link our executables.
+	    # We have to force runtime linking in this case.
+	    aix_use_runtimelinking=yes
+	    LDFLAGS="$LDFLAGS -Wl,-brtl"
+	  fi
+	  ;;
+	esac
+
+	exp_sym_flag='-bexport'
+	no_entry_flag='-bnoentry'
+      fi
+
+      # When large executables or shared objects are built, AIX ld can
+      # have problems creating the table of contents.  If linking a library
+      # or program results in "error TOC overflow" add -mminimal-toc to
+      # CXXFLAGS/CFLAGS for g++/gcc.  In the cases where that is not
+      # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
+
+      archive_cmds=''
+      hardcode_direct=yes
+      hardcode_direct_absolute=yes
+      hardcode_libdir_separator=':'
+      link_all_deplibs=yes
+      file_list_spec='$wl-f,'
+      case $with_aix_soname,$aix_use_runtimelinking in
+      aix,*) ;; # traditional, no import file
+      svr4,* | *,yes) # use import file
+	# The Import File defines what to hardcode.
+	hardcode_direct=no
+	hardcode_direct_absolute=no
+	;;
+      esac
+
+      if test yes = "$GCC"; then
+	case $host_os in aix4.[012]|aix4.[012].*)
+	# We only want to do this on AIX 4.2 and lower, the check
+	# below for broken collect2 doesn't work under 4.3+
+	  collect2name=`$CC -print-prog-name=collect2`
+	  if test -f "$collect2name" &&
+	   strings "$collect2name" | $GREP resolve_lib_name >/dev/null
+	  then
+	  # We have reworked collect2
+	  :
+	  else
+	  # We have old collect2
+	  hardcode_direct=unsupported
+	  # It fails to find uninstalled libraries when the uninstalled
+	  # path is not listed in the libpath.  Setting hardcode_minus_L
+	  # to unsupported forces relinking
+	  hardcode_minus_L=yes
+	  hardcode_libdir_flag_spec='-L$libdir'
+	  hardcode_libdir_separator=
+	  fi
+	  ;;
+	esac
+	shared_flag='-shared'
+	if test yes = "$aix_use_runtimelinking"; then
+	  shared_flag="$shared_flag "'$wl-G'
+	fi
+	# Need to ensure runtime linking is disabled for the traditional
+	# shared library, or the linker may eventually find shared libraries
+	# /with/ Import File - we do not want to mix them.
+	shared_flag_aix='-shared'
+	shared_flag_svr4='-shared $wl-G'
+      else
+	# not using gcc
+	if test ia64 = "$host_cpu"; then
+	# VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
+	# chokes on -Wl,-G. The following line is correct:
+	  shared_flag='-G'
+	else
+	  if test yes = "$aix_use_runtimelinking"; then
+	    shared_flag='$wl-G'
+	  else
+	    shared_flag='$wl-bM:SRE'
+	  fi
+	  shared_flag_aix='$wl-bM:SRE'
+	  shared_flag_svr4='$wl-G'
+	fi
+      fi
+
+      export_dynamic_flag_spec='$wl-bexpall'
+      # It seems that -bexpall does not export symbols beginning with
+      # underscore (_), so it is better to generate a list of symbols to export.
+      always_export_symbols=yes
+      if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then
+	# Warning - without using the other runtime loading flags (-brtl),
+	# -berok will link without error, but may produce a broken library.
+	allow_undefined_flag='-berok'
+        # Determine the default libpath from the value encoded in an
+        # empty executable.
+        if test set = "${lt_cv_aix_libpath+set}"; then
+  aix_libpath=$lt_cv_aix_libpath
+else
+  if ${lt_cv_aix_libpath_+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+
+  lt_aix_libpath_sed='
+      /Import File Strings/,/^$/ {
+	  /^0/ {
+	      s/^0  *\([^ ]*\) *$/\1/
+	      p
+	  }
+      }'
+  lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+  # Check for a 64-bit object if we didn't find anything.
+  if test -z "$lt_cv_aix_libpath_"; then
+    lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+  fi
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+  if test -z "$lt_cv_aix_libpath_"; then
+    lt_cv_aix_libpath_=/usr/lib:/lib
+  fi
+
+fi
+
+  aix_libpath=$lt_cv_aix_libpath_
+fi
+
+        hardcode_libdir_flag_spec='$wl-blibpath:$libdir:'"$aix_libpath"
+        archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag
+      else
+	if test ia64 = "$host_cpu"; then
+	  hardcode_libdir_flag_spec='$wl-R $libdir:/usr/lib:/lib'
+	  allow_undefined_flag="-z nodefs"
+	  archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols"
+	else
+	 # Determine the default libpath from the value encoded in an
+	 # empty executable.
+	 if test set = "${lt_cv_aix_libpath+set}"; then
+  aix_libpath=$lt_cv_aix_libpath
+else
+  if ${lt_cv_aix_libpath_+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+
+  lt_aix_libpath_sed='
+      /Import File Strings/,/^$/ {
+	  /^0/ {
+	      s/^0  *\([^ ]*\) *$/\1/
+	      p
+	  }
+      }'
+  lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+  # Check for a 64-bit object if we didn't find anything.
+  if test -z "$lt_cv_aix_libpath_"; then
+    lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+  fi
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+  if test -z "$lt_cv_aix_libpath_"; then
+    lt_cv_aix_libpath_=/usr/lib:/lib
+  fi
+
+fi
+
+  aix_libpath=$lt_cv_aix_libpath_
+fi
+
+	 hardcode_libdir_flag_spec='$wl-blibpath:$libdir:'"$aix_libpath"
+	  # Warning - without using the other run time loading flags,
+	  # -berok will link without error, but may produce a broken library.
+	  no_undefined_flag=' $wl-bernotok'
+	  allow_undefined_flag=' $wl-berok'
+	  if test yes = "$with_gnu_ld"; then
+	    # We only use this code for GNU lds that support --whole-archive.
+	    whole_archive_flag_spec='$wl--whole-archive$convenience $wl--no-whole-archive'
+	  else
+	    # Exported symbols can be pulled into shared objects from archives
+	    whole_archive_flag_spec='$convenience'
+	  fi
+	  archive_cmds_need_lc=yes
+	  archive_expsym_cmds='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d'
+	  # -brtl affects multiple linker settings, -berok does not and is overridden later
+	  compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([, ]\\)%-berok\\1%g"`'
+	  if test svr4 != "$with_aix_soname"; then
+	    # This is similar to how AIX traditionally builds its shared libraries.
+	    archive_expsym_cmds="$archive_expsym_cmds"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname'
+	  fi
+	  if test aix != "$with_aix_soname"; then
+	    archive_expsym_cmds="$archive_expsym_cmds"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp'
+	  else
+	    # used by -dlpreopen to get the symbols
+	    archive_expsym_cmds="$archive_expsym_cmds"'~$MV  $output_objdir/$realname.d/$soname $output_objdir'
+	  fi
+	  archive_expsym_cmds="$archive_expsym_cmds"'~$RM -r $output_objdir/$realname.d'
+	fi
+      fi
+      ;;
+
+    amigaos*)
+      case $host_cpu in
+      powerpc)
+            # see comment about AmigaOS4 .so support
+            archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+            archive_expsym_cmds=''
+        ;;
+      m68k)
+            archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+            hardcode_libdir_flag_spec='-L$libdir'
+            hardcode_minus_L=yes
+        ;;
+      esac
+      ;;
+
+    bsdi[45]*)
+      export_dynamic_flag_spec=-rdynamic
+      ;;
+
+    cygwin* | mingw* | pw32* | cegcc*)
+      # When not using gcc, we currently assume that we are using
+      # Microsoft Visual C++.
+      # hardcode_libdir_flag_spec is actually meaningless, as there is
+      # no search path for DLLs.
+      case $cc_basename in
+      cl*)
+	# Native MSVC
+	hardcode_libdir_flag_spec=' '
+	allow_undefined_flag=unsupported
+	always_export_symbols=yes
+	file_list_spec='@'
+	# Tell ltmain to make .lib files, not .a files.
+	libext=lib
+	# Tell ltmain to make .dll files, not .so files.
+	shrext_cmds=.dll
+	# FIXME: Setting linknames here is a bad hack.
+	archive_cmds='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames='
+	archive_expsym_cmds='if   test DEF = "`$SED -n     -e '\''s/^[	 ]*//'\''     -e '\''/^\(;.*\)*$/d'\''     -e '\''s/^\(EXPORTS\|LIBRARY\)\([	 ].*\)*$/DEF/p'\''     -e q     $export_symbols`" ; then
+            cp "$export_symbols" "$output_objdir/$soname.def";
+            echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp";
+          else
+            $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp;
+          fi~
+          $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
+          linknames='
+	# The linker will not automatically build a static lib if we build a DLL.
+	# _LT_TAGVAR(old_archive_from_new_cmds, )='true'
+	enable_shared_with_static_runtimes=yes
+	exclude_expsyms='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*'
+	export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1,DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols'
+	# Don't use ranlib
+	old_postinstall_cmds='chmod 644 $oldlib'
+	postlink_cmds='lt_outputfile="@OUTPUT@"~
+          lt_tool_outputfile="@TOOL_OUTPUT@"~
+          case $lt_outputfile in
+            *.exe|*.EXE) ;;
+            *)
+              lt_outputfile=$lt_outputfile.exe
+              lt_tool_outputfile=$lt_tool_outputfile.exe
+              ;;
+          esac~
+          if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then
+            $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1;
+            $RM "$lt_outputfile.manifest";
+          fi'
+	;;
+      *)
+	# Assume MSVC wrapper
+	hardcode_libdir_flag_spec=' '
+	allow_undefined_flag=unsupported
+	# Tell ltmain to make .lib files, not .a files.
+	libext=lib
+	# Tell ltmain to make .dll files, not .so files.
+	shrext_cmds=.dll
+	# FIXME: Setting linknames here is a bad hack.
+	archive_cmds='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames='
+	# The linker will automatically build a .lib file if we build a DLL.
+	old_archive_from_new_cmds='true'
+	# FIXME: Should let the user specify the lib program.
+	old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs'
+	enable_shared_with_static_runtimes=yes
+	;;
+      esac
+      ;;
+
+    darwin* | rhapsody*)
+
+
+  archive_cmds_need_lc=no
+  hardcode_direct=no
+  hardcode_automatic=yes
+  hardcode_shlibpath_var=unsupported
+  if test yes = "$lt_cv_ld_force_load"; then
+    whole_archive_flag_spec='`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience $wl-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`'
+
+  else
+    whole_archive_flag_spec=''
+  fi
+  link_all_deplibs=yes
+  allow_undefined_flag=$_lt_dar_allow_undefined
+  case $cc_basename in
+     ifort*|nagfor*) _lt_dar_can_shared=yes ;;
+     *) _lt_dar_can_shared=$GCC ;;
+  esac
+  if test yes = "$_lt_dar_can_shared"; then
+    output_verbose_link_cmd=func_echo_all
+    archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil"
+    module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil"
+    archive_expsym_cmds="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil"
+    module_expsym_cmds="sed -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil"
+
+  else
+  ld_shlibs=no
+  fi
+
+      ;;
+
+    dgux*)
+      archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_libdir_flag_spec='-L$libdir'
+      hardcode_shlibpath_var=no
+      ;;
+
+    # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor
+    # support.  Future versions do this automatically, but an explicit c++rt0.o
+    # does not break anything, and helps significantly (at the cost of a little
+    # extra space).
+    freebsd2.2*)
+      archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o'
+      hardcode_libdir_flag_spec='-R$libdir'
+      hardcode_direct=yes
+      hardcode_shlibpath_var=no
+      ;;
+
+    # Unfortunately, older versions of FreeBSD 2 do not have this feature.
+    freebsd2.*)
+      archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_direct=yes
+      hardcode_minus_L=yes
+      hardcode_shlibpath_var=no
+      ;;
+
+    # FreeBSD 3 and greater uses gcc -shared to do shared libraries.
+    freebsd* | dragonfly*)
+      archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+      hardcode_libdir_flag_spec='-R$libdir'
+      hardcode_direct=yes
+      hardcode_shlibpath_var=no
+      ;;
+
+    hpux9*)
+      if test yes = "$GCC"; then
+	archive_cmds='$RM $output_objdir/$soname~$CC -shared $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib'
+      else
+	archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib'
+      fi
+      hardcode_libdir_flag_spec='$wl+b $wl$libdir'
+      hardcode_libdir_separator=:
+      hardcode_direct=yes
+
+      # hardcode_minus_L: Not really in the search PATH,
+      # but as the default location of the library.
+      hardcode_minus_L=yes
+      export_dynamic_flag_spec='$wl-E'
+      ;;
+
+    hpux10*)
+      if test yes,no = "$GCC,$with_gnu_ld"; then
+	archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+      else
+	archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
+      fi
+      if test no = "$with_gnu_ld"; then
+	hardcode_libdir_flag_spec='$wl+b $wl$libdir'
+	hardcode_libdir_separator=:
+	hardcode_direct=yes
+	hardcode_direct_absolute=yes
+	export_dynamic_flag_spec='$wl-E'
+	# hardcode_minus_L: Not really in the search PATH,
+	# but as the default location of the library.
+	hardcode_minus_L=yes
+      fi
+      ;;
+
+    hpux11*)
+      if test yes,no = "$GCC,$with_gnu_ld"; then
+	case $host_cpu in
+	hppa*64*)
+	  archive_cmds='$CC -shared $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	ia64*)
+	  archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	*)
+	  archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	esac
+      else
+	case $host_cpu in
+	hppa*64*)
+	  archive_cmds='$CC -b $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	ia64*)
+	  archive_cmds='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	*)
+
+	  # Older versions of the 11.00 compiler do not understand -b yet
+	  # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does)
+	  { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC understands -b" >&5
+$as_echo_n "checking if $CC understands -b... " >&6; }
+if ${lt_cv_prog_compiler__b+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_prog_compiler__b=no
+   save_LDFLAGS=$LDFLAGS
+   LDFLAGS="$LDFLAGS -b"
+   echo "$lt_simple_link_test_code" > conftest.$ac_ext
+   if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
+     # The linker can only warn and ignore the option if not recognized
+     # So say no if there are warnings
+     if test -s conftest.err; then
+       # Append any errors to the config.log.
+       cat conftest.err 1>&5
+       $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp
+       $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+       if diff conftest.exp conftest.er2 >/dev/null; then
+         lt_cv_prog_compiler__b=yes
+       fi
+     else
+       lt_cv_prog_compiler__b=yes
+     fi
+   fi
+   $RM -r conftest*
+   LDFLAGS=$save_LDFLAGS
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler__b" >&5
+$as_echo "$lt_cv_prog_compiler__b" >&6; }
+
+if test yes = "$lt_cv_prog_compiler__b"; then
+    archive_cmds='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+else
+    archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
+fi
+
+	  ;;
+	esac
+      fi
+      if test no = "$with_gnu_ld"; then
+	hardcode_libdir_flag_spec='$wl+b $wl$libdir'
+	hardcode_libdir_separator=:
+
+	case $host_cpu in
+	hppa*64*|ia64*)
+	  hardcode_direct=no
+	  hardcode_shlibpath_var=no
+	  ;;
+	*)
+	  hardcode_direct=yes
+	  hardcode_direct_absolute=yes
+	  export_dynamic_flag_spec='$wl-E'
+
+	  # hardcode_minus_L: Not really in the search PATH,
+	  # but as the default location of the library.
+	  hardcode_minus_L=yes
+	  ;;
+	esac
+      fi
+      ;;
+
+    irix5* | irix6* | nonstopux*)
+      if test yes = "$GCC"; then
+	archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
+	# Try to use the -exported_symbol ld option, if it does not
+	# work, assume that -exports_file does not work either and
+	# implicitly export all symbols.
+	# This should be the same for all languages, so no per-tag cache variable.
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $host_os linker accepts -exported_symbol" >&5
+$as_echo_n "checking whether the $host_os linker accepts -exported_symbol... " >&6; }
+if ${lt_cv_irix_exported_symbol+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  save_LDFLAGS=$LDFLAGS
+	   LDFLAGS="$LDFLAGS -shared $wl-exported_symbol ${wl}foo $wl-update_registry $wl/dev/null"
+	   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+int foo (void) { return 0; }
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  lt_cv_irix_exported_symbol=yes
+else
+  lt_cv_irix_exported_symbol=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+           LDFLAGS=$save_LDFLAGS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_irix_exported_symbol" >&5
+$as_echo "$lt_cv_irix_exported_symbol" >&6; }
+	if test yes = "$lt_cv_irix_exported_symbol"; then
+          archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations $wl-exports_file $wl$export_symbols -o $lib'
+	fi
+	link_all_deplibs=no
+      else
+	archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
+	archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -exports_file $export_symbols -o $lib'
+      fi
+      archive_cmds_need_lc='no'
+      hardcode_libdir_flag_spec='$wl-rpath $wl$libdir'
+      hardcode_libdir_separator=:
+      inherit_rpath=yes
+      link_all_deplibs=yes
+      ;;
+
+    linux*)
+      case $cc_basename in
+      tcc*)
+	# Fabrice Bellard et al's Tiny C Compiler
+	ld_shlibs=yes
+	archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+	;;
+      esac
+      ;;
+
+    netbsd* | netbsdelf*-gnu)
+      if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+	archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'  # a.out
+      else
+	archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags'      # ELF
+      fi
+      hardcode_libdir_flag_spec='-R$libdir'
+      hardcode_direct=yes
+      hardcode_shlibpath_var=no
+      ;;
+
+    newsos6)
+      archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_direct=yes
+      hardcode_libdir_flag_spec='$wl-rpath $wl$libdir'
+      hardcode_libdir_separator=:
+      hardcode_shlibpath_var=no
+      ;;
+
+    *nto* | *qnx*)
+      ;;
+
+    openbsd* | bitrig*)
+      if test -f /usr/libexec/ld.so; then
+	hardcode_direct=yes
+	hardcode_shlibpath_var=no
+	hardcode_direct_absolute=yes
+	if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then
+	  archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+	  archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags $wl-retain-symbols-file,$export_symbols'
+	  hardcode_libdir_flag_spec='$wl-rpath,$libdir'
+	  export_dynamic_flag_spec='$wl-E'
+	else
+	  archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+	  hardcode_libdir_flag_spec='$wl-rpath,$libdir'
+	fi
+      else
+	ld_shlibs=no
+      fi
+      ;;
+
+    os2*)
+      hardcode_libdir_flag_spec='-L$libdir'
+      hardcode_minus_L=yes
+      allow_undefined_flag=unsupported
+      shrext_cmds=.dll
+      archive_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
+	$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
+	$ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
+	$ECHO EXPORTS >> $output_objdir/$libname.def~
+	emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~
+	$CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
+	emximp -o $lib $output_objdir/$libname.def'
+      archive_expsym_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
+	$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
+	$ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
+	$ECHO EXPORTS >> $output_objdir/$libname.def~
+	prefix_cmds="$SED"~
+	if test EXPORTS = "`$SED 1q $export_symbols`"; then
+	  prefix_cmds="$prefix_cmds -e 1d";
+	fi~
+	prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~
+	cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~
+	$CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
+	emximp -o $lib $output_objdir/$libname.def'
+      old_archive_From_new_cmds='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def'
+      enable_shared_with_static_runtimes=yes
+      ;;
+
+    osf3*)
+      if test yes = "$GCC"; then
+	allow_undefined_flag=' $wl-expect_unresolved $wl\*'
+	archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
+      else
+	allow_undefined_flag=' -expect_unresolved \*'
+	archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
+      fi
+      archive_cmds_need_lc='no'
+      hardcode_libdir_flag_spec='$wl-rpath $wl$libdir'
+      hardcode_libdir_separator=:
+      ;;
+
+    osf4* | osf5*)	# as osf3* with the addition of -msym flag
+      if test yes = "$GCC"; then
+	allow_undefined_flag=' $wl-expect_unresolved $wl\*'
+	archive_cmds='$CC -shared$allow_undefined_flag $pic_flag $libobjs $deplibs $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
+	hardcode_libdir_flag_spec='$wl-rpath $wl$libdir'
+      else
+	allow_undefined_flag=' -expect_unresolved \*'
+	archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
+	archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~
+          $CC -shared$allow_undefined_flag $wl-input $wl$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~$RM $lib.exp'
+
+	# Both c and cxx compiler support -rpath directly
+	hardcode_libdir_flag_spec='-rpath $libdir'
+      fi
+      archive_cmds_need_lc='no'
+      hardcode_libdir_separator=:
+      ;;
+
+    solaris*)
+      no_undefined_flag=' -z defs'
+      if test yes = "$GCC"; then
+	wlarc='$wl'
+	archive_cmds='$CC -shared $pic_flag $wl-z ${wl}text $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags'
+	archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+          $CC -shared $pic_flag $wl-z ${wl}text $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+      else
+	case `$CC -V 2>&1` in
+	*"Compilers 5.0"*)
+	  wlarc=''
+	  archive_cmds='$LD -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $linker_flags'
+	  archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+            $LD -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp'
+	  ;;
+	*)
+	  wlarc='$wl'
+	  archive_cmds='$CC -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $compiler_flags'
+	  archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+            $CC -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+	  ;;
+	esac
+      fi
+      hardcode_libdir_flag_spec='-R$libdir'
+      hardcode_shlibpath_var=no
+      case $host_os in
+      solaris2.[0-5] | solaris2.[0-5].*) ;;
+      *)
+	# The compiler driver will combine and reorder linker options,
+	# but understands '-z linker_flag'.  GCC discards it without '$wl',
+	# but is careful enough not to reorder.
+	# Supported since Solaris 2.6 (maybe 2.5.1?)
+	if test yes = "$GCC"; then
+	  whole_archive_flag_spec='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract'
+	else
+	  whole_archive_flag_spec='-z allextract$convenience -z defaultextract'
+	fi
+	;;
+      esac
+      link_all_deplibs=yes
+      ;;
+
+    sunos4*)
+      if test sequent = "$host_vendor"; then
+	# Use $CC to link under sequent, because it throws in some extra .o
+	# files that make .init and .fini sections work.
+	archive_cmds='$CC -G $wl-h $soname -o $lib $libobjs $deplibs $compiler_flags'
+      else
+	archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags'
+      fi
+      hardcode_libdir_flag_spec='-L$libdir'
+      hardcode_direct=yes
+      hardcode_minus_L=yes
+      hardcode_shlibpath_var=no
+      ;;
+
+    sysv4)
+      case $host_vendor in
+	sni)
+	  archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+	  hardcode_direct=yes # is this really true???
+	;;
+	siemens)
+	  ## LD is ld it makes a PLAMLIB
+	  ## CC just makes a GrossModule.
+	  archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags'
+	  reload_cmds='$CC -r -o $output$reload_objs'
+	  hardcode_direct=no
+        ;;
+	motorola)
+	  archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+	  hardcode_direct=no #Motorola manual says yes, but my tests say they lie
+	;;
+      esac
+      runpath_var='LD_RUN_PATH'
+      hardcode_shlibpath_var=no
+      ;;
+
+    sysv4.3*)
+      archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_shlibpath_var=no
+      export_dynamic_flag_spec='-Bexport'
+      ;;
+
+    sysv4*MP*)
+      if test -d /usr/nec; then
+	archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+	hardcode_shlibpath_var=no
+	runpath_var=LD_RUN_PATH
+	hardcode_runpath_var=yes
+	ld_shlibs=yes
+      fi
+      ;;
+
+    sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*)
+      no_undefined_flag='$wl-z,text'
+      archive_cmds_need_lc=no
+      hardcode_shlibpath_var=no
+      runpath_var='LD_RUN_PATH'
+
+      if test yes = "$GCC"; then
+	archive_cmds='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	archive_expsym_cmds='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+      else
+	archive_cmds='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	archive_expsym_cmds='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+      fi
+      ;;
+
+    sysv5* | sco3.2v5* | sco5v6*)
+      # Note: We CANNOT use -z defs as we might desire, because we do not
+      # link with -lc, and that would cause any symbols used from libc to
+      # always be unresolved, which means just about no library would
+      # ever link correctly.  If we're not using GNU ld we use -z text
+      # though, which does catch some bad symbols but isn't as heavy-handed
+      # as -z defs.
+      no_undefined_flag='$wl-z,text'
+      allow_undefined_flag='$wl-z,nodefs'
+      archive_cmds_need_lc=no
+      hardcode_shlibpath_var=no
+      hardcode_libdir_flag_spec='$wl-R,$libdir'
+      hardcode_libdir_separator=':'
+      link_all_deplibs=yes
+      export_dynamic_flag_spec='$wl-Bexport'
+      runpath_var='LD_RUN_PATH'
+
+      if test yes = "$GCC"; then
+	archive_cmds='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	archive_expsym_cmds='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+      else
+	archive_cmds='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	archive_expsym_cmds='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+      fi
+      ;;
+
+    uts4*)
+      archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_libdir_flag_spec='-L$libdir'
+      hardcode_shlibpath_var=no
+      ;;
+
+    *)
+      ld_shlibs=no
+      ;;
+    esac
+
+    if test sni = "$host_vendor"; then
+      case $host in
+      sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+	export_dynamic_flag_spec='$wl-Blargedynsym'
+	;;
+      esac
+    fi
+  fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs" >&5
+$as_echo "$ld_shlibs" >&6; }
+test no = "$ld_shlibs" && can_build_shared=no
+
+with_gnu_ld=$with_gnu_ld
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+#
+# Do we need to explicitly link libc?
+#
+case "x$archive_cmds_need_lc" in
+x|xyes)
+  # Assume -lc should be added
+  archive_cmds_need_lc=yes
+
+  if test yes,yes = "$GCC,$enable_shared"; then
+    case $archive_cmds in
+    *'~'*)
+      # FIXME: we may have to deal with multi-command sequences.
+      ;;
+    '$CC '*)
+      # Test whether the compiler implicitly links with -lc since on some
+      # systems, -lgcc has to come before -lc. If gcc already passes -lc
+      # to ld, don't add -lc before -lgcc.
+      { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5
+$as_echo_n "checking whether -lc should be explicitly linked in... " >&6; }
+if ${lt_cv_archive_cmds_need_lc+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  $RM conftest*
+	echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+	if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } 2>conftest.err; then
+	  soname=conftest
+	  lib=conftest
+	  libobjs=conftest.$ac_objext
+	  deplibs=
+	  wl=$lt_prog_compiler_wl
+	  pic_flag=$lt_prog_compiler_pic
+	  compiler_flags=-v
+	  linker_flags=-v
+	  verstring=
+	  output_objdir=.
+	  libname=conftest
+	  lt_save_allow_undefined_flag=$allow_undefined_flag
+	  allow_undefined_flag=
+	  if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5
+  (eval $archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+	  then
+	    lt_cv_archive_cmds_need_lc=no
+	  else
+	    lt_cv_archive_cmds_need_lc=yes
+	  fi
+	  allow_undefined_flag=$lt_save_allow_undefined_flag
+	else
+	  cat conftest.err 1>&5
+	fi
+	$RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc" >&5
+$as_echo "$lt_cv_archive_cmds_need_lc" >&6; }
+      archive_cmds_need_lc=$lt_cv_archive_cmds_need_lc
+      ;;
+    esac
+  fi
+  ;;
+esac
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5
+$as_echo_n "checking dynamic linker characteristics... " >&6; }
+
+if test yes = "$GCC"; then
+  case $host_os in
+    darwin*) lt_awk_arg='/^libraries:/,/LR/' ;;
+    *) lt_awk_arg='/^libraries:/' ;;
+  esac
+  case $host_os in
+    mingw* | cegcc*) lt_sed_strip_eq='s|=\([A-Za-z]:\)|\1|g' ;;
+    *) lt_sed_strip_eq='s|=/|/|g' ;;
+  esac
+  lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq`
+  case $lt_search_path_spec in
+  *\;*)
+    # if the path contains ";" then we assume it to be the separator
+    # otherwise default to the standard path separator (i.e. ":") - it is
+    # assumed that no part of a normal pathname contains ";" but that should
+    # okay in the real world where ";" in dirpaths is itself problematic.
+    lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'`
+    ;;
+  *)
+    lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"`
+    ;;
+  esac
+  # Ok, now we have the path, separated by spaces, we can step through it
+  # and add multilib dir if necessary...
+  lt_tmp_lt_search_path_spec=
+  lt_multi_os_dir=/`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null`
+  # ...but if some path component already ends with the multilib dir we assume
+  # that all is fine and trust -print-search-dirs as is (GCC 4.2? or newer).
+  case "$lt_multi_os_dir; $lt_search_path_spec " in
+  "/; "* | "/.; "* | "/./; "* | *"$lt_multi_os_dir "* | *"$lt_multi_os_dir/ "*)
+    lt_multi_os_dir=
+    ;;
+  esac
+  for lt_sys_path in $lt_search_path_spec; do
+    if test -d "$lt_sys_path$lt_multi_os_dir"; then
+      lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path$lt_multi_os_dir"
+    elif test -n "$lt_multi_os_dir"; then
+      test -d "$lt_sys_path" && \
+	lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path"
+    fi
+  done
+  lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk '
+BEGIN {RS = " "; FS = "/|\n";} {
+  lt_foo = "";
+  lt_count = 0;
+  for (lt_i = NF; lt_i > 0; lt_i--) {
+    if ($lt_i != "" && $lt_i != ".") {
+      if ($lt_i == "..") {
+        lt_count++;
+      } else {
+        if (lt_count == 0) {
+          lt_foo = "/" $lt_i lt_foo;
+        } else {
+          lt_count--;
+        }
+      }
+    }
+  }
+  if (lt_foo != "") { lt_freq[lt_foo]++; }
+  if (lt_freq[lt_foo] == 1) { print lt_foo; }
+}'`
+  # AWK program above erroneously prepends '/' to C:/dos/paths
+  # for these hosts.
+  case $host_os in
+    mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\
+      $SED 's|/\([A-Za-z]:\)|\1|g'` ;;
+  esac
+  sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP`
+else
+  sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
+fi
+library_names_spec=
+libname_spec='lib$name'
+soname_spec=
+shrext_cmds=.so
+postinstall_cmds=
+postuninstall_cmds=
+finish_cmds=
+finish_eval=
+shlibpath_var=
+shlibpath_overrides_runpath=unknown
+version_type=none
+dynamic_linker="$host_os ld.so"
+sys_lib_dlsearch_path_spec="/lib /usr/lib"
+need_lib_prefix=unknown
+hardcode_into_libs=no
+
+# when you set need_version to no, make sure it does not cause -set_version
+# flags to be left without arguments
+need_version=unknown
+
+
+
+case $host_os in
+aix3*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  library_names_spec='$libname$release$shared_ext$versuffix $libname.a'
+  shlibpath_var=LIBPATH
+
+  # AIX 3 has no versioning support, so we append a major version to the name.
+  soname_spec='$libname$release$shared_ext$major'
+  ;;
+
+aix[4-9]*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  need_lib_prefix=no
+  need_version=no
+  hardcode_into_libs=yes
+  if test ia64 = "$host_cpu"; then
+    # AIX 5 supports IA64
+    library_names_spec='$libname$release$shared_ext$major $libname$release$shared_ext$versuffix $libname$shared_ext'
+    shlibpath_var=LD_LIBRARY_PATH
+  else
+    # With GCC up to 2.95.x, collect2 would create an import file
+    # for dependence libraries.  The import file would start with
+    # the line '#! .'.  This would cause the generated library to
+    # depend on '.', always an invalid library.  This was fixed in
+    # development snapshots of GCC prior to 3.0.
+    case $host_os in
+      aix4 | aix4.[01] | aix4.[01].*)
+      if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)'
+	   echo ' yes '
+	   echo '#endif'; } | $CC -E - | $GREP yes > /dev/null; then
+	:
+      else
+	can_build_shared=no
+      fi
+      ;;
+    esac
+    # Using Import Files as archive members, it is possible to support
+    # filename-based versioning of shared library archives on AIX. While
+    # this would work for both with and without runtime linking, it will
+    # prevent static linking of such archives. So we do filename-based
+    # shared library versioning with .so extension only, which is used
+    # when both runtime linking and shared linking is enabled.
+    # Unfortunately, runtime linking may impact performance, so we do
+    # not want this to be the default eventually. Also, we use the
+    # versioned .so libs for executables only if there is the -brtl
+    # linker flag in LDFLAGS as well, or --with-aix-soname=svr4 only.
+    # To allow for filename-based versioning support, we need to create
+    # libNAME.so.V as an archive file, containing:
+    # *) an Import File, referring to the versioned filename of the
+    #    archive as well as the shared archive member, telling the
+    #    bitwidth (32 or 64) of that shared object, and providing the
+    #    list of exported symbols of that shared object, eventually
+    #    decorated with the 'weak' keyword
+    # *) the shared object with the F_LOADONLY flag set, to really avoid
+    #    it being seen by the linker.
+    # At run time we better use the real file rather than another symlink,
+    # but for link time we create the symlink libNAME.so -> libNAME.so.V
+
+    case $with_aix_soname,$aix_use_runtimelinking in
+    # AIX (on Power*) has no versioning support, so currently we cannot hardcode correct
+    # soname into executable. Probably we can add versioning support to
+    # collect2, so additional links can be useful in future.
+    aix,yes) # traditional libtool
+      dynamic_linker='AIX unversionable lib.so'
+      # If using run time linking (on AIX 4.2 or later) use lib<name>.so
+      # instead of lib<name>.a to let people know that these are not
+      # typical AIX shared libraries.
+      library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+      ;;
+    aix,no) # traditional AIX only
+      dynamic_linker='AIX lib.a(lib.so.V)'
+      # We preserve .a as extension for shared libraries through AIX4.2
+      # and later when we are not doing run time linking.
+      library_names_spec='$libname$release.a $libname.a'
+      soname_spec='$libname$release$shared_ext$major'
+      ;;
+    svr4,*) # full svr4 only
+      dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o)"
+      library_names_spec='$libname$release$shared_ext$major $libname$shared_ext'
+      # We do not specify a path in Import Files, so LIBPATH fires.
+      shlibpath_overrides_runpath=yes
+      ;;
+    *,yes) # both, prefer svr4
+      dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o), lib.a(lib.so.V)"
+      library_names_spec='$libname$release$shared_ext$major $libname$shared_ext'
+      # unpreferred sharedlib libNAME.a needs extra handling
+      postinstall_cmds='test -n "$linkname" || linkname="$realname"~func_stripname "" ".so" "$linkname"~$install_shared_prog "$dir/$func_stripname_result.$libext" "$destdir/$func_stripname_result.$libext"~test -z "$tstripme" || test -z "$striplib" || $striplib "$destdir/$func_stripname_result.$libext"'
+      postuninstall_cmds='for n in $library_names $old_library; do :; done~func_stripname "" ".so" "$n"~test "$func_stripname_result" = "$n" || func_append rmfiles " $odir/$func_stripname_result.$libext"'
+      # We do not specify a path in Import Files, so LIBPATH fires.
+      shlibpath_overrides_runpath=yes
+      ;;
+    *,no) # both, prefer aix
+      dynamic_linker="AIX lib.a(lib.so.V), lib.so.V($shared_archive_member_spec.o)"
+      library_names_spec='$libname$release.a $libname.a'
+      soname_spec='$libname$release$shared_ext$major'
+      # unpreferred sharedlib libNAME.so.V and symlink libNAME.so need extra handling
+      postinstall_cmds='test -z "$dlname" || $install_shared_prog $dir/$dlname $destdir/$dlname~test -z "$tstripme" || test -z "$striplib" || $striplib $destdir/$dlname~test -n "$linkname" || linkname=$realname~func_stripname "" ".a" "$linkname"~(cd "$destdir" && $LN_S -f $dlname $func_stripname_result.so)'
+      postuninstall_cmds='test -z "$dlname" || func_append rmfiles " $odir/$dlname"~for n in $old_library $library_names; do :; done~func_stripname "" ".a" "$n"~func_append rmfiles " $odir/$func_stripname_result.so"'
+      ;;
+    esac
+    shlibpath_var=LIBPATH
+  fi
+  ;;
+
+amigaos*)
+  case $host_cpu in
+  powerpc)
+    # Since July 2007 AmigaOS4 officially supports .so libraries.
+    # When compiling the executable, add -use-dynld -Lsobjs: to the compileline.
+    library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+    ;;
+  m68k)
+    library_names_spec='$libname.ixlibrary $libname.a'
+    # Create ${libname}_ixlibrary.a entries in /sys/libs.
+    finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
+    ;;
+  esac
+  ;;
+
+beos*)
+  library_names_spec='$libname$shared_ext'
+  dynamic_linker="$host_os ld.so"
+  shlibpath_var=LIBRARY_PATH
+  ;;
+
+bsdi[45]*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  need_version=no
+  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+  soname_spec='$libname$release$shared_ext$major'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
+  sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib"
+  # the default ld.so.conf also contains /usr/contrib/lib and
+  # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow
+  # libtool to hard-code these into programs
+  ;;
+
+cygwin* | mingw* | pw32* | cegcc*)
+  version_type=windows
+  shrext_cmds=.dll
+  need_version=no
+  need_lib_prefix=no
+
+  case $GCC,$cc_basename in
+  yes,*)
+    # gcc
+    library_names_spec='$libname.dll.a'
+    # DLL is installed to $(libdir)/../bin by postinstall_cmds
+    postinstall_cmds='base_file=`basename \$file`~
+      dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~
+      dldir=$destdir/`dirname \$dlpath`~
+      test -d \$dldir || mkdir -p \$dldir~
+      $install_prog $dir/$dlname \$dldir/$dlname~
+      chmod a+x \$dldir/$dlname~
+      if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then
+        eval '\''$striplib \$dldir/$dlname'\'' || exit \$?;
+      fi'
+    postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+      dlpath=$dir/\$dldll~
+       $RM \$dlpath'
+    shlibpath_overrides_runpath=yes
+
+    case $host_os in
+    cygwin*)
+      # Cygwin DLLs use 'cyg' prefix rather than 'lib'
+      soname_spec='`echo $libname | sed -e 's/^lib/cyg/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext'
+
+      sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"
+      ;;
+    mingw* | cegcc*)
+      # MinGW DLLs use traditional 'lib' prefix
+      soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext'
+      ;;
+    pw32*)
+      # pw32 DLLs use 'pw' prefix rather than 'lib'
+      library_names_spec='`echo $libname | sed -e 's/^lib/pw/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext'
+      ;;
+    esac
+    dynamic_linker='Win32 ld.exe'
+    ;;
+
+  *,cl*)
+    # Native MSVC
+    libname_spec='$name'
+    soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext'
+    library_names_spec='$libname.dll.lib'
+
+    case $build_os in
+    mingw*)
+      sys_lib_search_path_spec=
+      lt_save_ifs=$IFS
+      IFS=';'
+      for lt_path in $LIB
+      do
+        IFS=$lt_save_ifs
+        # Let DOS variable expansion print the short 8.3 style file name.
+        lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"`
+        sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path"
+      done
+      IFS=$lt_save_ifs
+      # Convert to MSYS style.
+      sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'`
+      ;;
+    cygwin*)
+      # Convert to unix form, then to dos form, then back to unix form
+      # but this time dos style (no spaces!) so that the unix form looks
+      # like /cygdrive/c/PROGRA~1:/cygdr...
+      sys_lib_search_path_spec=`cygpath --path --unix "$LIB"`
+      sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null`
+      sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
+      ;;
+    *)
+      sys_lib_search_path_spec=$LIB
+      if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then
+        # It is most probably a Windows format PATH.
+        sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
+      else
+        sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
+      fi
+      # FIXME: find the short name or the path components, as spaces are
+      # common. (e.g. "Program Files" -> "PROGRA~1")
+      ;;
+    esac
+
+    # DLL is installed to $(libdir)/../bin by postinstall_cmds
+    postinstall_cmds='base_file=`basename \$file`~
+      dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~
+      dldir=$destdir/`dirname \$dlpath`~
+      test -d \$dldir || mkdir -p \$dldir~
+      $install_prog $dir/$dlname \$dldir/$dlname'
+    postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+      dlpath=$dir/\$dldll~
+       $RM \$dlpath'
+    shlibpath_overrides_runpath=yes
+    dynamic_linker='Win32 link.exe'
+    ;;
+
+  *)
+    # Assume MSVC wrapper
+    library_names_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext $libname.lib'
+    dynamic_linker='Win32 ld.exe'
+    ;;
+  esac
+  # FIXME: first we should search . and the directory the executable is in
+  shlibpath_var=PATH
+  ;;
+
+darwin* | rhapsody*)
+  dynamic_linker="$host_os dyld"
+  version_type=darwin
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='$libname$release$major$shared_ext $libname$shared_ext'
+  soname_spec='$libname$release$major$shared_ext'
+  shlibpath_overrides_runpath=yes
+  shlibpath_var=DYLD_LIBRARY_PATH
+  shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`'
+
+  sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"
+  sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib'
+  ;;
+
+dgux*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+  soname_spec='$libname$release$shared_ext$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+freebsd* | dragonfly*)
+  # DragonFly does not have aout.  When/if they implement a new
+  # versioning mechanism, adjust this.
+  if test -x /usr/bin/objformat; then
+    objformat=`/usr/bin/objformat`
+  else
+    case $host_os in
+    freebsd[23].*) objformat=aout ;;
+    *) objformat=elf ;;
+    esac
+  fi
+  version_type=freebsd-$objformat
+  case $version_type in
+    freebsd-elf*)
+      library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+      soname_spec='$libname$release$shared_ext$major'
+      need_version=no
+      need_lib_prefix=no
+      ;;
+    freebsd-*)
+      library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'
+      need_version=yes
+      ;;
+  esac
+  shlibpath_var=LD_LIBRARY_PATH
+  case $host_os in
+  freebsd2.*)
+    shlibpath_overrides_runpath=yes
+    ;;
+  freebsd3.[01]* | freebsdelf3.[01]*)
+    shlibpath_overrides_runpath=yes
+    hardcode_into_libs=yes
+    ;;
+  freebsd3.[2-9]* | freebsdelf3.[2-9]* | \
+  freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1)
+    shlibpath_overrides_runpath=no
+    hardcode_into_libs=yes
+    ;;
+  *) # from 4.6 on, and DragonFly
+    shlibpath_overrides_runpath=yes
+    hardcode_into_libs=yes
+    ;;
+  esac
+  ;;
+
+haiku*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  need_lib_prefix=no
+  need_version=no
+  dynamic_linker="$host_os runtime_loader"
+  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+  soname_spec='$libname$release$shared_ext$major'
+  shlibpath_var=LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib'
+  hardcode_into_libs=yes
+  ;;
+
+hpux9* | hpux10* | hpux11*)
+  # Give a soname corresponding to the major version so that dld.sl refuses to
+  # link against other versions.
+  version_type=sunos
+  need_lib_prefix=no
+  need_version=no
+  case $host_cpu in
+  ia64*)
+    shrext_cmds='.so'
+    hardcode_into_libs=yes
+    dynamic_linker="$host_os dld.so"
+    shlibpath_var=LD_LIBRARY_PATH
+    shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+    library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+    soname_spec='$libname$release$shared_ext$major'
+    if test 32 = "$HPUX_IA64_MODE"; then
+      sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib"
+      sys_lib_dlsearch_path_spec=/usr/lib/hpux32
+    else
+      sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64"
+      sys_lib_dlsearch_path_spec=/usr/lib/hpux64
+    fi
+    ;;
+  hppa*64*)
+    shrext_cmds='.sl'
+    hardcode_into_libs=yes
+    dynamic_linker="$host_os dld.sl"
+    shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH
+    shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+    library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+    soname_spec='$libname$release$shared_ext$major'
+    sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64"
+    sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+    ;;
+  *)
+    shrext_cmds='.sl'
+    dynamic_linker="$host_os dld.sl"
+    shlibpath_var=SHLIB_PATH
+    shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
+    library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+    soname_spec='$libname$release$shared_ext$major'
+    ;;
+  esac
+  # HP-UX runs *really* slowly unless shared libraries are mode 555, ...
+  postinstall_cmds='chmod 555 $lib'
+  # or fails outright, so override atomically:
+  install_override_mode=555
+  ;;
+
+interix[3-9]*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+  soname_spec='$libname$release$shared_ext$major'
+  dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  ;;
+
+irix5* | irix6* | nonstopux*)
+  case $host_os in
+    nonstopux*) version_type=nonstopux ;;
+    *)
+	if test yes = "$lt_cv_prog_gnu_ld"; then
+		version_type=linux # correct to gnu/linux during the next big refactor
+	else
+		version_type=irix
+	fi ;;
+  esac
+  need_lib_prefix=no
+  need_version=no
+  soname_spec='$libname$release$shared_ext$major'
+  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$release$shared_ext $libname$shared_ext'
+  case $host_os in
+  irix5* | nonstopux*)
+    libsuff= shlibsuff=
+    ;;
+  *)
+    case $LD in # libtool.m4 will add one of these switches to LD
+    *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ")
+      libsuff= shlibsuff= libmagic=32-bit;;
+    *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ")
+      libsuff=32 shlibsuff=N32 libmagic=N32;;
+    *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ")
+      libsuff=64 shlibsuff=64 libmagic=64-bit;;
+    *) libsuff= shlibsuff= libmagic=never-match;;
+    esac
+    ;;
+  esac
+  shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
+  shlibpath_overrides_runpath=no
+  sys_lib_search_path_spec="/usr/lib$libsuff /lib$libsuff /usr/local/lib$libsuff"
+  sys_lib_dlsearch_path_spec="/usr/lib$libsuff /lib$libsuff"
+  hardcode_into_libs=yes
+  ;;
+
+# No shared lib support for Linux oldld, aout, or coff.
+linux*oldld* | linux*aout* | linux*coff*)
+  dynamic_linker=no
+  ;;
+
+linux*android*)
+  version_type=none # Android doesn't support versioned libraries.
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='$libname$release$shared_ext'
+  soname_spec='$libname$release$shared_ext'
+  finish_cmds=
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+
+  # This implies no fast_install, which is unacceptable.
+  # Some rework will be needed to allow for fast_install
+  # before this can be enabled.
+  hardcode_into_libs=yes
+
+  dynamic_linker='Android linker'
+  # Don't embed -rpath directories since the linker doesn't support them.
+  hardcode_libdir_flag_spec='-L$libdir'
+  ;;
+
+# This must be glibc/ELF.
+linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+  soname_spec='$libname$release$shared_ext$major'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+
+  # Some binutils ld are patched to set DT_RUNPATH
+  if ${lt_cv_shlibpath_overrides_runpath+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_shlibpath_overrides_runpath=no
+    save_LDFLAGS=$LDFLAGS
+    save_libdir=$libdir
+    eval "libdir=/foo; wl=\"$lt_prog_compiler_wl\"; \
+	 LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec\""
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  if  ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then :
+  lt_cv_shlibpath_overrides_runpath=yes
+fi
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+    LDFLAGS=$save_LDFLAGS
+    libdir=$save_libdir
+
+fi
+
+  shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath
+
+  # This implies no fast_install, which is unacceptable.
+  # Some rework will be needed to allow for fast_install
+  # before this can be enabled.
+  hardcode_into_libs=yes
+
+  # Ideally, we could use ldconfig to report *all* directores which are
+  # searched for libraries, however this is still not possible.  Aside from not
+  # being certain /sbin/ldconfig is available, command
+  # 'ldconfig -N -X -v | grep ^/' on 64bit Fedora does not report /usr/lib64,
+  # even though it is searched at run-time.  Try to do the best guess by
+  # appending ld.so.conf contents (and includes) to the search path.
+  if test -f /etc/ld.so.conf; then
+    lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[	 ]*hwcap[	 ]/d;s/[:,	]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '`
+    sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra"
+  fi
+
+  # We used to test for /lib/ld.so.1 and disable shared libraries on
+  # powerpc, because MkLinux only supported shared libraries with the
+  # GNU dynamic linker.  Since this was broken with cross compilers,
+  # most powerpc-linux boxes support dynamic linking these days and
+  # people can always --disable-shared, the test was removed, and we
+  # assume the GNU/Linux dynamic linker is in use.
+  dynamic_linker='GNU/Linux ld.so'
+  ;;
+
+netbsdelf*-gnu)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  dynamic_linker='NetBSD ld.elf_so'
+  ;;
+
+netbsd*)
+  version_type=sunos
+  need_lib_prefix=no
+  need_version=no
+  if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+    library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'
+    finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+    dynamic_linker='NetBSD (a.out) ld.so'
+  else
+    library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+    soname_spec='$libname$release$shared_ext$major'
+    dynamic_linker='NetBSD ld.elf_so'
+  fi
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  hardcode_into_libs=yes
+  ;;
+
+newsos6)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  ;;
+
+*nto* | *qnx*)
+  version_type=qnx
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+  soname_spec='$libname$release$shared_ext$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  dynamic_linker='ldqnx.so'
+  ;;
+
+openbsd* | bitrig*)
+  version_type=sunos
+  sys_lib_dlsearch_path_spec=/usr/lib
+  need_lib_prefix=no
+  if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then
+    need_version=no
+  else
+    need_version=yes
+  fi
+  library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  ;;
+
+os2*)
+  libname_spec='$name'
+  version_type=windows
+  shrext_cmds=.dll
+  need_version=no
+  need_lib_prefix=no
+  # OS/2 can only load a DLL with a base name of 8 characters or less.
+  soname_spec='`test -n "$os2dllname" && libname="$os2dllname";
+    v=$($ECHO $release$versuffix | tr -d .-);
+    n=$($ECHO $libname | cut -b -$((8 - ${#v})) | tr . _);
+    $ECHO $n$v`$shared_ext'
+  library_names_spec='${libname}_dll.$libext'
+  dynamic_linker='OS/2 ld.exe'
+  shlibpath_var=BEGINLIBPATH
+  sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
+  sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+  postinstall_cmds='base_file=`basename \$file`~
+    dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; $ECHO \$dlname'\''`~
+    dldir=$destdir/`dirname \$dlpath`~
+    test -d \$dldir || mkdir -p \$dldir~
+    $install_prog $dir/$dlname \$dldir/$dlname~
+    chmod a+x \$dldir/$dlname~
+    if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then
+      eval '\''$striplib \$dldir/$dlname'\'' || exit \$?;
+    fi'
+  postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; $ECHO \$dlname'\''`~
+    dlpath=$dir/\$dldll~
+    $RM \$dlpath'
+  ;;
+
+osf3* | osf4* | osf5*)
+  version_type=osf
+  need_lib_prefix=no
+  need_version=no
+  soname_spec='$libname$release$shared_ext$major'
+  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+  shlibpath_var=LD_LIBRARY_PATH
+  sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
+  sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+  ;;
+
+rdos*)
+  dynamic_linker=no
+  ;;
+
+solaris*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+  soname_spec='$libname$release$shared_ext$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  hardcode_into_libs=yes
+  # ldd complains unless libraries are executable
+  postinstall_cmds='chmod +x $lib'
+  ;;
+
+sunos4*)
+  version_type=sunos
+  library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'
+  finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  if test yes = "$with_gnu_ld"; then
+    need_lib_prefix=no
+  fi
+  need_version=yes
+  ;;
+
+sysv4 | sysv4.3*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+  soname_spec='$libname$release$shared_ext$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  case $host_vendor in
+    sni)
+      shlibpath_overrides_runpath=no
+      need_lib_prefix=no
+      runpath_var=LD_RUN_PATH
+      ;;
+    siemens)
+      need_lib_prefix=no
+      ;;
+    motorola)
+      need_lib_prefix=no
+      need_version=no
+      shlibpath_overrides_runpath=no
+      sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib'
+      ;;
+  esac
+  ;;
+
+sysv4*MP*)
+  if test -d /usr/nec; then
+    version_type=linux # correct to gnu/linux during the next big refactor
+    library_names_spec='$libname$shared_ext.$versuffix $libname$shared_ext.$major $libname$shared_ext'
+    soname_spec='$libname$shared_ext.$major'
+    shlibpath_var=LD_LIBRARY_PATH
+  fi
+  ;;
+
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+  version_type=sco
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext $libname$shared_ext'
+  soname_spec='$libname$release$shared_ext$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  hardcode_into_libs=yes
+  if test yes = "$with_gnu_ld"; then
+    sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib'
+  else
+    sys_lib_search_path_spec='/usr/ccs/lib /usr/lib'
+    case $host_os in
+      sco3.2v5*)
+        sys_lib_search_path_spec="$sys_lib_search_path_spec /lib"
+	;;
+    esac
+  fi
+  sys_lib_dlsearch_path_spec='/usr/lib'
+  ;;
+
+tpf*)
+  # TPF is a cross-target only.  Preferred cross-host = GNU/Linux.
+  version_type=linux # correct to gnu/linux during the next big refactor
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  ;;
+
+uts4*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+  soname_spec='$libname$release$shared_ext$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+*)
+  dynamic_linker=no
+  ;;
+esac
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5
+$as_echo "$dynamic_linker" >&6; }
+test no = "$dynamic_linker" && can_build_shared=no
+
+variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
+if test yes = "$GCC"; then
+  variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
+fi
+
+if test set = "${lt_cv_sys_lib_search_path_spec+set}"; then
+  sys_lib_search_path_spec=$lt_cv_sys_lib_search_path_spec
+fi
+
+if test set = "${lt_cv_sys_lib_dlsearch_path_spec+set}"; then
+  sys_lib_dlsearch_path_spec=$lt_cv_sys_lib_dlsearch_path_spec
+fi
+
+# remember unaugmented sys_lib_dlsearch_path content for libtool script decls...
+configure_time_dlsearch_path=$sys_lib_dlsearch_path_spec
+
+# ... but it needs LT_SYS_LIBRARY_PATH munging for other configure-time code
+func_munge_path_list sys_lib_dlsearch_path_spec "$LT_SYS_LIBRARY_PATH"
+
+# to be used as default LT_SYS_LIBRARY_PATH value in generated libtool
+configure_time_lt_sys_library_path=$LT_SYS_LIBRARY_PATH
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5
+$as_echo_n "checking how to hardcode library paths into programs... " >&6; }
+hardcode_action=
+if test -n "$hardcode_libdir_flag_spec" ||
+   test -n "$runpath_var" ||
+   test yes = "$hardcode_automatic"; then
+
+  # We can hardcode non-existent directories.
+  if test no != "$hardcode_direct" &&
+     # If the only mechanism to avoid hardcoding is shlibpath_var, we
+     # have to relink, otherwise we might link with an installed library
+     # when we should be linking with a yet-to-be-installed one
+     ## test no != "$_LT_TAGVAR(hardcode_shlibpath_var, )" &&
+     test no != "$hardcode_minus_L"; then
+    # Linking always hardcodes the temporary library directory.
+    hardcode_action=relink
+  else
+    # We can link without hardcoding, and we can hardcode nonexisting dirs.
+    hardcode_action=immediate
+  fi
+else
+  # We cannot hardcode anything, or else we can only hardcode existing
+  # directories.
+  hardcode_action=unsupported
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action" >&5
+$as_echo "$hardcode_action" >&6; }
+
+if test relink = "$hardcode_action" ||
+   test yes = "$inherit_rpath"; then
+  # Fast installation is not supported
+  enable_fast_install=no
+elif test yes = "$shlibpath_overrides_runpath" ||
+     test no = "$enable_shared"; then
+  # Fast installation is not necessary
+  enable_fast_install=needless
+fi
+
+
+
+
+
+
+  if test yes != "$enable_dlopen"; then
+  enable_dlopen=unknown
+  enable_dlopen_self=unknown
+  enable_dlopen_self_static=unknown
+else
+  lt_cv_dlopen=no
+  lt_cv_dlopen_libs=
+
+  case $host_os in
+  beos*)
+    lt_cv_dlopen=load_add_on
+    lt_cv_dlopen_libs=
+    lt_cv_dlopen_self=yes
+    ;;
+
+  mingw* | pw32* | cegcc*)
+    lt_cv_dlopen=LoadLibrary
+    lt_cv_dlopen_libs=
+    ;;
+
+  cygwin*)
+    lt_cv_dlopen=dlopen
+    lt_cv_dlopen_libs=
+    ;;
+
+  darwin*)
+    # if libdl is installed we need to link against it
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5
+$as_echo_n "checking for dlopen in -ldl... " >&6; }
+if ${ac_cv_lib_dl_dlopen+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldl  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dlopen ();
+int
+main ()
+{
+return dlopen ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_dl_dlopen=yes
+else
+  ac_cv_lib_dl_dlopen=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5
+$as_echo "$ac_cv_lib_dl_dlopen" >&6; }
+if test "x$ac_cv_lib_dl_dlopen" = xyes; then :
+  lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl
+else
+
+    lt_cv_dlopen=dyld
+    lt_cv_dlopen_libs=
+    lt_cv_dlopen_self=yes
+
+fi
+
+    ;;
+
+  tpf*)
+    # Don't try to run any link tests for TPF.  We know it's impossible
+    # because TPF is a cross-compiler, and we know how we open DSOs.
+    lt_cv_dlopen=dlopen
+    lt_cv_dlopen_libs=
+    lt_cv_dlopen_self=no
+    ;;
+
+  *)
+    ac_fn_c_check_func "$LINENO" "shl_load" "ac_cv_func_shl_load"
+if test "x$ac_cv_func_shl_load" = xyes; then :
+  lt_cv_dlopen=shl_load
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5
+$as_echo_n "checking for shl_load in -ldld... " >&6; }
+if ${ac_cv_lib_dld_shl_load+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldld  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char shl_load ();
+int
+main ()
+{
+return shl_load ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_dld_shl_load=yes
+else
+  ac_cv_lib_dld_shl_load=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5
+$as_echo "$ac_cv_lib_dld_shl_load" >&6; }
+if test "x$ac_cv_lib_dld_shl_load" = xyes; then :
+  lt_cv_dlopen=shl_load lt_cv_dlopen_libs=-ldld
+else
+  ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen"
+if test "x$ac_cv_func_dlopen" = xyes; then :
+  lt_cv_dlopen=dlopen
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5
+$as_echo_n "checking for dlopen in -ldl... " >&6; }
+if ${ac_cv_lib_dl_dlopen+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldl  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dlopen ();
+int
+main ()
+{
+return dlopen ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_dl_dlopen=yes
+else
+  ac_cv_lib_dl_dlopen=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5
+$as_echo "$ac_cv_lib_dl_dlopen" >&6; }
+if test "x$ac_cv_lib_dl_dlopen" = xyes; then :
+  lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -lsvld" >&5
+$as_echo_n "checking for dlopen in -lsvld... " >&6; }
+if ${ac_cv_lib_svld_dlopen+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lsvld  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dlopen ();
+int
+main ()
+{
+return dlopen ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_svld_dlopen=yes
+else
+  ac_cv_lib_svld_dlopen=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_svld_dlopen" >&5
+$as_echo "$ac_cv_lib_svld_dlopen" >&6; }
+if test "x$ac_cv_lib_svld_dlopen" = xyes; then :
+  lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-lsvld
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dld_link in -ldld" >&5
+$as_echo_n "checking for dld_link in -ldld... " >&6; }
+if ${ac_cv_lib_dld_dld_link+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldld  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dld_link ();
+int
+main ()
+{
+return dld_link ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_dld_dld_link=yes
+else
+  ac_cv_lib_dld_dld_link=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_dld_link" >&5
+$as_echo "$ac_cv_lib_dld_dld_link" >&6; }
+if test "x$ac_cv_lib_dld_dld_link" = xyes; then :
+  lt_cv_dlopen=dld_link lt_cv_dlopen_libs=-ldld
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+    ;;
+  esac
+
+  if test no = "$lt_cv_dlopen"; then
+    enable_dlopen=no
+  else
+    enable_dlopen=yes
+  fi
+
+  case $lt_cv_dlopen in
+  dlopen)
+    save_CPPFLAGS=$CPPFLAGS
+    test yes = "$ac_cv_header_dlfcn_h" && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H"
+
+    save_LDFLAGS=$LDFLAGS
+    wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\"
+
+    save_LIBS=$LIBS
+    LIBS="$lt_cv_dlopen_libs $LIBS"
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a program can dlopen itself" >&5
+$as_echo_n "checking whether a program can dlopen itself... " >&6; }
+if ${lt_cv_dlopen_self+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  	  if test yes = "$cross_compiling"; then :
+  lt_cv_dlopen_self=cross
+else
+  lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+  lt_status=$lt_dlunknown
+  cat > conftest.$ac_ext <<_LT_EOF
+#line $LINENO "configure"
+#include "confdefs.h"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+#  define LT_DLGLOBAL		RTLD_GLOBAL
+#else
+#  ifdef DL_GLOBAL
+#    define LT_DLGLOBAL		DL_GLOBAL
+#  else
+#    define LT_DLGLOBAL		0
+#  endif
+#endif
+
+/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
+   find out it does not work in some platform. */
+#ifndef LT_DLLAZY_OR_NOW
+#  ifdef RTLD_LAZY
+#    define LT_DLLAZY_OR_NOW		RTLD_LAZY
+#  else
+#    ifdef DL_LAZY
+#      define LT_DLLAZY_OR_NOW		DL_LAZY
+#    else
+#      ifdef RTLD_NOW
+#        define LT_DLLAZY_OR_NOW	RTLD_NOW
+#      else
+#        ifdef DL_NOW
+#          define LT_DLLAZY_OR_NOW	DL_NOW
+#        else
+#          define LT_DLLAZY_OR_NOW	0
+#        endif
+#      endif
+#    endif
+#  endif
+#endif
+
+/* When -fvisibility=hidden is used, assume the code has been annotated
+   correspondingly for the symbols needed.  */
+#if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))
+int fnord () __attribute__((visibility("default")));
+#endif
+
+int fnord () { return 42; }
+int main ()
+{
+  void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
+  int status = $lt_dlunknown;
+
+  if (self)
+    {
+      if (dlsym (self,"fnord"))       status = $lt_dlno_uscore;
+      else
+        {
+	  if (dlsym( self,"_fnord"))  status = $lt_dlneed_uscore;
+          else puts (dlerror ());
+	}
+      /* dlclose (self); */
+    }
+  else
+    puts (dlerror ());
+
+  return status;
+}
+_LT_EOF
+  if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && test -s "conftest$ac_exeext" 2>/dev/null; then
+    (./conftest; exit; ) >&5 2>/dev/null
+    lt_status=$?
+    case x$lt_status in
+      x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;;
+      x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;;
+      x$lt_dlunknown|x*) lt_cv_dlopen_self=no ;;
+    esac
+  else :
+    # compilation failed
+    lt_cv_dlopen_self=no
+  fi
+fi
+rm -fr conftest*
+
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self" >&5
+$as_echo "$lt_cv_dlopen_self" >&6; }
+
+    if test yes = "$lt_cv_dlopen_self"; then
+      wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\"
+      { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a statically linked program can dlopen itself" >&5
+$as_echo_n "checking whether a statically linked program can dlopen itself... " >&6; }
+if ${lt_cv_dlopen_self_static+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  	  if test yes = "$cross_compiling"; then :
+  lt_cv_dlopen_self_static=cross
+else
+  lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+  lt_status=$lt_dlunknown
+  cat > conftest.$ac_ext <<_LT_EOF
+#line $LINENO "configure"
+#include "confdefs.h"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+#  define LT_DLGLOBAL		RTLD_GLOBAL
+#else
+#  ifdef DL_GLOBAL
+#    define LT_DLGLOBAL		DL_GLOBAL
+#  else
+#    define LT_DLGLOBAL		0
+#  endif
+#endif
+
+/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
+   find out it does not work in some platform. */
+#ifndef LT_DLLAZY_OR_NOW
+#  ifdef RTLD_LAZY
+#    define LT_DLLAZY_OR_NOW		RTLD_LAZY
+#  else
+#    ifdef DL_LAZY
+#      define LT_DLLAZY_OR_NOW		DL_LAZY
+#    else
+#      ifdef RTLD_NOW
+#        define LT_DLLAZY_OR_NOW	RTLD_NOW
+#      else
+#        ifdef DL_NOW
+#          define LT_DLLAZY_OR_NOW	DL_NOW
+#        else
+#          define LT_DLLAZY_OR_NOW	0
+#        endif
+#      endif
+#    endif
+#  endif
+#endif
+
+/* When -fvisibility=hidden is used, assume the code has been annotated
+   correspondingly for the symbols needed.  */
+#if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))
+int fnord () __attribute__((visibility("default")));
+#endif
+
+int fnord () { return 42; }
+int main ()
+{
+  void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
+  int status = $lt_dlunknown;
+
+  if (self)
+    {
+      if (dlsym (self,"fnord"))       status = $lt_dlno_uscore;
+      else
+        {
+	  if (dlsym( self,"_fnord"))  status = $lt_dlneed_uscore;
+          else puts (dlerror ());
+	}
+      /* dlclose (self); */
+    }
+  else
+    puts (dlerror ());
+
+  return status;
+}
+_LT_EOF
+  if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && test -s "conftest$ac_exeext" 2>/dev/null; then
+    (./conftest; exit; ) >&5 2>/dev/null
+    lt_status=$?
+    case x$lt_status in
+      x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;;
+      x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;;
+      x$lt_dlunknown|x*) lt_cv_dlopen_self_static=no ;;
+    esac
+  else :
+    # compilation failed
+    lt_cv_dlopen_self_static=no
+  fi
+fi
+rm -fr conftest*
+
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self_static" >&5
+$as_echo "$lt_cv_dlopen_self_static" >&6; }
+    fi
+
+    CPPFLAGS=$save_CPPFLAGS
+    LDFLAGS=$save_LDFLAGS
+    LIBS=$save_LIBS
+    ;;
+  esac
+
+  case $lt_cv_dlopen_self in
+  yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;;
+  *) enable_dlopen_self=unknown ;;
+  esac
+
+  case $lt_cv_dlopen_self_static in
+  yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;;
+  *) enable_dlopen_self_static=unknown ;;
+  esac
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+striplib=
+old_striplib=
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stripping libraries is possible" >&5
+$as_echo_n "checking whether stripping libraries is possible... " >&6; }
+if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then
+  test -z "$old_striplib" && old_striplib="$STRIP --strip-debug"
+  test -z "$striplib" && striplib="$STRIP --strip-unneeded"
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+else
+# FIXME - insert some real tests, host_os isn't really good enough
+  case $host_os in
+  darwin*)
+    if test -n "$STRIP"; then
+      striplib="$STRIP -x"
+      old_striplib="$STRIP -S"
+      { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+    else
+      { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+    fi
+    ;;
+  *)
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+    ;;
+  esac
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+  # Report what library types will actually be built
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking if libtool supports shared libraries" >&5
+$as_echo_n "checking if libtool supports shared libraries... " >&6; }
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $can_build_shared" >&5
+$as_echo "$can_build_shared" >&6; }
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build shared libraries" >&5
+$as_echo_n "checking whether to build shared libraries... " >&6; }
+  test no = "$can_build_shared" && enable_shared=no
+
+  # On AIX, shared libraries and static libraries use the same namespace, and
+  # are all built from PIC.
+  case $host_os in
+  aix3*)
+    test yes = "$enable_shared" && enable_static=no
+    if test -n "$RANLIB"; then
+      archive_cmds="$archive_cmds~\$RANLIB \$lib"
+      postinstall_cmds='$RANLIB $lib'
+    fi
+    ;;
+
+  aix[4-9]*)
+    if test ia64 != "$host_cpu"; then
+      case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in
+      yes,aix,yes) ;;			# shared object as lib.so file only
+      yes,svr4,*) ;;			# shared object as lib.so archive member only
+      yes,*) enable_static=no ;;	# shared object in lib.a archive as well
+      esac
+    fi
+    ;;
+  esac
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_shared" >&5
+$as_echo "$enable_shared" >&6; }
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build static libraries" >&5
+$as_echo_n "checking whether to build static libraries... " >&6; }
+  # Make sure either enable_shared or enable_static is yes.
+  test yes = "$enable_shared" || enable_static=yes
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_static" >&5
+$as_echo "$enable_static" >&6; }
+
+
+
+
+fi
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+CC=$lt_save_CC
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+        ac_config_commands="$ac_config_commands libtool"
+
+
+
+
+# Only expand once:
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking spl author" >&5
+$as_echo_n "checking spl author... " >&6; }
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $SPL_META_AUTHOR" >&5
+$as_echo "$SPL_META_AUTHOR" >&6; }
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking spl license" >&5
+$as_echo_n "checking spl license... " >&6; }
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $SPL_META_LICENSE" >&5
+$as_echo "$SPL_META_LICENSE" >&6; }
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking linux distribution" >&5
+$as_echo_n "checking linux distribution... " >&6; }
+	if test -f /etc/toss-release ; then
+		VENDOR=toss ;
+	elif test -f /etc/fedora-release ; then
+		VENDOR=fedora ;
+	elif test -f /etc/redhat-release ; then
+		VENDOR=redhat ;
+	elif test -f /etc/gentoo-release ; then
+		VENDOR=gentoo ;
+	elif test -f /etc/arch-release ; then
+		VENDOR=arch ;
+	elif test -f /etc/SuSE-release ; then
+		VENDOR=sles ;
+	elif test -f /etc/slackware-version ; then
+		VENDOR=slackware ;
+	elif test -f /etc/lunar.release ; then
+		VENDOR=lunar ;
+	elif test -f /etc/lsb-release ; then
+		VENDOR=ubuntu ;
+	elif test -f /etc/debian_version ; then
+		VENDOR=debian ;
+	else
+		VENDOR= ;
+	fi
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $VENDOR" >&5
+$as_echo "$VENDOR" >&6; }
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking default package type" >&5
+$as_echo_n "checking default package type... " >&6; }
+	case "$VENDOR" in
+		toss)       DEFAULT_PACKAGE=rpm  ;;
+		redhat)     DEFAULT_PACKAGE=rpm  ;;
+		fedora)     DEFAULT_PACKAGE=rpm  ;;
+		gentoo)     DEFAULT_PACKAGE=tgz  ;;
+		arch)       DEFAULT_PACKAGE=tgz  ;;
+		sles)       DEFAULT_PACKAGE=rpm  ;;
+		slackware)  DEFAULT_PACKAGE=tgz  ;;
+		lunar)      DEFAULT_PACKAGE=tgz  ;;
+		ubuntu)     DEFAULT_PACKAGE=deb  ;;
+		debian)     DEFAULT_PACKAGE=deb  ;;
+		*)          DEFAULT_PACKAGE=rpm  ;;
+	esac
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $DEFAULT_PACKAGE" >&5
+$as_echo "$DEFAULT_PACKAGE" >&6; }
+
+
+
+	RPM=rpm
+	RPMBUILD=rpmbuild
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $RPM is available" >&5
+$as_echo_n "checking whether $RPM is available... " >&6; }
+	if tmp=$($RPM --version 2>/dev/null); then :
+
+		RPM_VERSION=$(echo $tmp | $AWK '/RPM/ { print $3 }')
+		HAVE_RPM=yes
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $HAVE_RPM ($RPM_VERSION)" >&5
+$as_echo "$HAVE_RPM ($RPM_VERSION)" >&6; }
+
+else
+
+		HAVE_RPM=no
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $HAVE_RPM" >&5
+$as_echo "$HAVE_RPM" >&6; }
+
+fi
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $RPMBUILD is available" >&5
+$as_echo_n "checking whether $RPMBUILD is available... " >&6; }
+	if tmp=$($RPMBUILD --version 2>/dev/null); then :
+
+		RPMBUILD_VERSION=$(echo $tmp | $AWK '/RPM/ { print $3 }')
+		HAVE_RPMBUILD=yes
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $HAVE_RPMBUILD ($RPMBUILD_VERSION)" >&5
+$as_echo "$HAVE_RPMBUILD ($RPMBUILD_VERSION)" >&6; }
+
+else
+
+		HAVE_RPMBUILD=no
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $HAVE_RPMBUILD" >&5
+$as_echo "$HAVE_RPMBUILD" >&6; }
+
+fi
+
+	RPM_DEFINE_COMMON='--define "$(DEBUG_SPL) 1" --define "$(DEBUG_KMEM) 1" --define "$(DEBUG_KMEM_TRACKING) 1"'
+	RPM_DEFINE_UTIL=
+	RPM_DEFINE_KMOD='--define "kernels $(LINUX_VERSION)"'
+	RPM_DEFINE_DKMS=
+
+	SRPM_DEFINE_COMMON='--define "build_src_rpm 1"'
+	SRPM_DEFINE_UTIL=
+	SRPM_DEFINE_KMOD=
+	SRPM_DEFINE_DKMS=
+
+	RPM_SPEC_DIR="rpm/generic"
+
+# Check whether --with-spec was given.
+if test "${with_spec+set}" = set; then :
+  withval=$with_spec; RPM_SPEC_DIR="rpm/$withval"
+fi
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether spec files are available" >&5
+$as_echo_n "checking whether spec files are available... " >&6; }
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes ($RPM_SPEC_DIR/*.spec.in)" >&5
+$as_echo "yes ($RPM_SPEC_DIR/*.spec.in)" >&6; }
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+	DPKG=dpkg
+	DPKGBUILD=dpkg-buildpackage
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $DPKG is available" >&5
+$as_echo_n "checking whether $DPKG is available... " >&6; }
+	if tmp=$($DPKG --version 2>/dev/null); then :
+
+		DPKG_VERSION=$(echo $tmp | $AWK '/Debian/ { print $7 }')
+		HAVE_DPKG=yes
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $HAVE_DPKG ($DPKG_VERSION)" >&5
+$as_echo "$HAVE_DPKG ($DPKG_VERSION)" >&6; }
+
+else
+
+		HAVE_DPKG=no
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $HAVE_DPKG" >&5
+$as_echo "$HAVE_DPKG" >&6; }
+
+fi
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $DPKGBUILD is available" >&5
+$as_echo_n "checking whether $DPKGBUILD is available... " >&6; }
+	if tmp=$($DPKGBUILD --version 2>/dev/null); then :
+
+		DPKGBUILD_VERSION=$(echo $tmp | \
+		    $AWK '/Debian/ { print $4 }' | cut -f-4 -d'.')
+		HAVE_DPKGBUILD=yes
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $HAVE_DPKGBUILD ($DPKGBUILD_VERSION)" >&5
+$as_echo "$HAVE_DPKGBUILD ($DPKGBUILD_VERSION)" >&6; }
+
+else
+
+		HAVE_DPKGBUILD=no
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $HAVE_DPKGBUILD" >&5
+$as_echo "$HAVE_DPKGBUILD" >&6; }
+
+fi
+
+
+
+
+
+
+
+
+
+
+	ALIEN=alien
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $ALIEN is available" >&5
+$as_echo_n "checking whether $ALIEN is available... " >&6; }
+	if tmp=$($ALIEN --version 2>/dev/null); then :
+
+		ALIEN_VERSION=$(echo $tmp | $AWK '{ print $3 }')
+		HAVE_ALIEN=yes
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $HAVE_ALIEN ($ALIEN_VERSION)" >&5
+$as_echo "$HAVE_ALIEN ($ALIEN_VERSION)" >&6; }
+
+else
+
+		HAVE_ALIEN=no
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $HAVE_ALIEN" >&5
+$as_echo "$HAVE_ALIEN" >&6; }
+
+fi
+
+
+
+
+
+
+
+	SPL_CONFIG=all
+
+# Check whether --with-config was given.
+if test "${with_config+set}" = set; then :
+  withval=$with_config; SPL_CONFIG="$withval"
+fi
+
+	# Check whether --enable-linux-builtin was given.
+if test "${enable_linux_builtin+set}" = set; then :
+  enableval=$enable_linux_builtin;
+else
+  enable_linux_builtin=no
+fi
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking spl config" >&5
+$as_echo_n "checking spl config... " >&6; }
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $SPL_CONFIG" >&5
+$as_echo "$SPL_CONFIG" >&6; };
+
+
+	case "$SPL_CONFIG" in
+		kernel)
+
+
+# Check whether --with-linux was given.
+if test "${with_linux+set}" = set; then :
+  withval=$with_linux; kernelsrc="$withval"
+fi
+
+
+
+# Check whether --with-linux-obj was given.
+if test "${with_linux_obj+set}" = set; then :
+  withval=$with_linux_obj; kernelbuild="$withval"
+fi
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking kernel source directory" >&5
+$as_echo_n "checking kernel source directory... " >&6; }
+	if test -z "$kernelsrc"; then
+		if test -e "/lib/modules/$(uname -r)/source"; then
+			headersdir="/lib/modules/$(uname -r)/source"
+			sourcelink=$(readlink -f "$headersdir")
+		elif test -e "/lib/modules/$(uname -r)/build"; then
+			headersdir="/lib/modules/$(uname -r)/build"
+			sourcelink=$(readlink -f "$headersdir")
+		else
+			sourcelink=$(ls -1d /usr/src/kernels/* \
+			             /usr/src/linux-* \
+			             2>/dev/null | grep -v obj | tail -1)
+		fi
+
+		if test -n "$sourcelink" && test -e ${sourcelink}; then
+			kernelsrc=`readlink -f ${sourcelink}`
+		else
+			kernelsrc="Not found"
+		fi
+	else
+		if test "$kernelsrc" = "NONE"; then
+			kernsrcver=NONE
+		fi
+	fi
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $kernelsrc" >&5
+$as_echo "$kernelsrc" >&6; }
+	if test ! -d "$kernelsrc"; then
+		as_fn_error $? "
+	*** Please make sure the kernel devel package for your distribution
+	*** is installed and then try again.  If that fails, you can specify the
+	*** location of the kernel source with the '--with-linux=PATH' option." "$LINENO" 5
+	fi
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking kernel build directory" >&5
+$as_echo_n "checking kernel build directory... " >&6; }
+	if test -z "$kernelbuild"; then
+		if test -e "/lib/modules/$(uname -r)/build"; then
+			kernelbuild=`readlink -f /lib/modules/$(uname -r)/build`
+		elif test -d ${kernelsrc}-obj/${target_cpu}/${target_cpu}; then
+			kernelbuild=${kernelsrc}-obj/${target_cpu}/${target_cpu}
+		elif test -d ${kernelsrc}-obj/${target_cpu}/default; then
+			kernelbuild=${kernelsrc}-obj/${target_cpu}/default
+		elif test -d `dirname ${kernelsrc}`/build-${target_cpu}; then
+			kernelbuild=`dirname ${kernelsrc}`/build-${target_cpu}
+		else
+			kernelbuild=${kernelsrc}
+		fi
+	fi
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $kernelbuild" >&5
+$as_echo "$kernelbuild" >&6; }
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking kernel source version" >&5
+$as_echo_n "checking kernel source version... " >&6; }
+	utsrelease1=$kernelbuild/include/linux/version.h
+	utsrelease2=$kernelbuild/include/linux/utsrelease.h
+	utsrelease3=$kernelbuild/include/generated/utsrelease.h
+	if test -r $utsrelease1 && fgrep -q UTS_RELEASE $utsrelease1; then
+		utsrelease=linux/version.h
+	elif test -r $utsrelease2 && fgrep -q UTS_RELEASE $utsrelease2; then
+		utsrelease=linux/utsrelease.h
+	elif test -r $utsrelease3 && fgrep -q UTS_RELEASE $utsrelease3; then
+		utsrelease=generated/utsrelease.h
+	fi
+
+	if test "$utsrelease"; then
+		kernsrcver=`(echo "#include <$utsrelease>";
+		             echo "kernsrcver=UTS_RELEASE") |
+		             cpp -I $kernelbuild/include |
+		             grep "^kernsrcver=" | cut -d \" -f 2`
+
+		if test -z "$kernsrcver"; then
+			{ $as_echo "$as_me:${as_lineno-$LINENO}: result: Not found" >&5
+$as_echo "Not found" >&6; }
+			as_fn_error $? "*** Cannot determine kernel version." "$LINENO" 5
+		fi
+	else
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: Not found" >&5
+$as_echo "Not found" >&6; }
+		if test "x$enable_linux_builtin" != xyes; then
+			as_fn_error $? "*** Cannot find UTS_RELEASE definition." "$LINENO" 5
+		else
+			as_fn_error $? "
+	*** Cannot find UTS_RELEASE definition.
+	*** Please run 'make prepare' inside the kernel source tree." "$LINENO" 5
+		fi
+	fi
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $kernsrcver" >&5
+$as_echo "$kernsrcver" >&6; }
+
+	LINUX=${kernelsrc}
+	LINUX_OBJ=${kernelbuild}
+	LINUX_VERSION=${kernsrcver}
+
+
+
+
+
+
+	modpost=$LINUX/scripts/Makefile.modpost
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking kernel file name for module symbols" >&5
+$as_echo_n "checking kernel file name for module symbols... " >&6; }
+	if test "x$enable_linux_builtin" != xyes -a -f "$modpost"; then
+		if grep -q Modules.symvers $modpost; then
+			LINUX_SYMBOLS=Modules.symvers
+		else
+			LINUX_SYMBOLS=Module.symvers
+		fi
+
+		if ! test -f "$LINUX_OBJ/$LINUX_SYMBOLS"; then
+			as_fn_error $? "
+	*** Please make sure the kernel devel package for your distribution
+	*** is installed.  If you are building with a custom kernel, make sure the
+	*** kernel is configured, built, and the '--with-linux=PATH' configure
+	*** option refers to the location of the kernel source." "$LINENO" 5
+		fi
+	else
+		LINUX_SYMBOLS=NONE
+	fi
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $LINUX_SYMBOLS" >&5
+$as_echo "$LINUX_SYMBOLS" >&6; }
+
+
+
+
+	if test "${LINUX_OBJ}" != "${LINUX}"; then
+		KERNELMAKE_PARAMS="$KERNELMAKE_PARAMS O=$LINUX_OBJ"
+	fi
+
+
+	KERNELCPPFLAGS="$KERNELCPPFLAGS -Wstrict-prototypes"
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether debugging is enabled" >&5
+$as_echo_n "checking whether debugging is enabled... " >&6; }
+	# Check whether --enable-debug was given.
+if test "${enable_debug+set}" = set; then :
+  enableval=$enable_debug;
+else
+  enable_debug=no
+fi
+
+
+	if test "x$enable_debug" = xyes; then :
+
+		KERNELCPPFLAGS="${KERNELCPPFLAGS} -DDEBUG -Werror"
+		DEBUG_CFLAGS="-DDEBUG -Werror"
+		DEBUG_SPL="_with_debug"
+
+else
+
+		KERNELCPPFLAGS="${KERNELCPPFLAGS} -DNDEBUG"
+		DEBUG_CFLAGS="-DNDEBUG"
+		DEBUG_SPL="_without_debug"
+
+fi
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_debug" >&5
+$as_echo "$enable_debug" >&6; }
+
+
+	# Check whether --enable-debug-kmem was given.
+if test "${enable_debug_kmem+set}" = set; then :
+  enableval=$enable_debug_kmem;
+else
+  enable_debug_kmem=no
+fi
+
+
+	if test "x$enable_debug_kmem" = xyes; then :
+
+		KERNELCPPFLAGS="${KERNELCPPFLAGS} -DDEBUG_KMEM"
+		DEBUG_KMEM="_with_debug_kmem"
+
+$as_echo "#define DEBUG_KMEM 1" >>confdefs.h
+
+
+else
+
+		DEBUG_KMEM="_without_debug_kmem"
+
+fi
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether basic kmem accounting is enabled" >&5
+$as_echo_n "checking whether basic kmem accounting is enabled... " >&6; }
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_debug_kmem" >&5
+$as_echo "$enable_debug_kmem" >&6; }
+
+
+	# Check whether --enable-debug-kmem-tracking was given.
+if test "${enable_debug_kmem_tracking+set}" = set; then :
+  enableval=$enable_debug_kmem_tracking;
+else
+  enable_debug_kmem_tracking=no
+fi
+
+
+	if test "x$enable_debug_kmem_tracking" = xyes; then :
+
+		KERNELCPPFLAGS="${KERNELCPPFLAGS} -DDEBUG_KMEM_TRACKING"
+		DEBUG_KMEM_TRACKING="_with_debug_kmem_tracking"
+
+$as_echo "#define DEBUG_KMEM_TRACKING 1" >>confdefs.h
+
+
+else
+
+		DEBUG_KMEM_TRACKING="_without_debug_kmem_tracking"
+
+fi
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether detailed kmem tracking is enabled" >&5
+$as_echo_n "checking whether detailed kmem tracking is enabled... " >&6; }
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_debug_kmem_tracking" >&5
+$as_echo "$enable_debug_kmem_tracking" >&6; }
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether modules can be built" >&5
+$as_echo_n "checking whether modules can be built... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+int
+main (void)
+{
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror-implicit-function-declaration $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+		if test "x$enable_linux_builtin" != xyes; then
+			as_fn_error $? "*** Unable to build an empty module." "$LINENO" 5
+		else
+			as_fn_error $? "
+	*** Unable to build an empty module.
+	*** Please run 'make scripts' inside the kernel source tree." "$LINENO" 5
+		fi
+
+
+
+fi
+	rm -Rf build
+
+
+
+	if test "x$cross_compiling" != xyes; then :
+
+		if test "$cross_compiling" = yes; then :
+  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot run test program while cross compiling
+See \`config.log' for more details" "$LINENO" 5; }
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+
+				#include "$LINUX/include/linux/license.h"
+
+int
+main ()
+{
+
+				return !license_is_gpl_compatible(
+				    "$SPL_META_LICENSE");
+
+  ;
+  return 0;
+}
+
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+
+
+$as_echo "#define SPL_IS_GPL_COMPATIBLE 1" >>confdefs.h
+
+
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+
+fi
+
+
+	# Check whether --enable-atomic-spinlocks was given.
+if test "${enable_atomic_spinlocks+set}" = set; then :
+  enableval=$enable_atomic_spinlocks;
+else
+  enable_atomic_spinlocks=check
+fi
+
+
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/fs.h>
+
+int
+main (void)
+{
+
+		atomic64_t *ptr __attribute__ ((unused));
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror-implicit-function-declaration $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		have_atomic64_t=yes
+
+$as_echo "#define HAVE_ATOMIC64_T 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		have_atomic64_t=no
+
+
+
+fi
+	rm -Rf build
+
+
+
+	if test "x$enable_atomic_spinlocks" = xcheck; then :
+
+		if test "x$have_atomic64_t" = xyes; then :
+
+			enable_atomic_spinlocks=no
+
+else
+
+			enable_atomic_spinlocks=yes
+
+fi
+
+fi
+
+	if test "x$enable_atomic_spinlocks" = xyes; then :
+
+
+$as_echo "#define ATOMIC_SPINLOCK 1" >>confdefs.h
+
+
+else
+
+		if test "x$have_atomic64_t" = xno; then :
+
+			{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "--disable-atomic-spinlocks given but required atomic64 support is unavailable
+See \`config.log' for more details" "$LINENO" 5; }
+
+fi
+
+fi
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether atomic types use spinlocks" >&5
+$as_echo_n "checking whether atomic types use spinlocks... " >&6; }
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_atomic_spinlocks" >&5
+$as_echo "$enable_atomic_spinlocks" >&6; }
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether kernel defines atomic64_t" >&5
+$as_echo_n "checking whether kernel defines atomic64_t... " >&6; }
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_atomic64_t" >&5
+$as_echo "$have_atomic64_t" >&6; }
+
+
+	tmp_flags="$EXTRA_KCFLAGS"
+	EXTRA_KCFLAGS="-Werror"
+					{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether old 2-argument shrinker exists" >&5
+$as_echo_n "checking whether old 2-argument shrinker exists... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/mm.h>
+
+		int shrinker_cb(int nr_to_scan, gfp_t gfp_mask);
+
+int
+main (void)
+{
+
+		struct shrinker cache_shrinker = {
+			.shrink = shrinker_cb,
+			.seeks = DEFAULT_SEEKS,
+		};
+		register_shrinker(&cache_shrinker);
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror-implicit-function-declaration $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_2ARGS_OLD_SHRINKER_CALLBACK 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+												{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether old 3-argument shrinker exists" >&5
+$as_echo_n "checking whether old 3-argument shrinker exists... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+			#include <linux/mm.h>
+
+			int shrinker_cb(struct shrinker *, int nr_to_scan,
+					gfp_t gfp_mask);
+
+int
+main (void)
+{
+
+			struct shrinker cache_shrinker = {
+				.shrink = shrinker_cb,
+				.seeks = DEFAULT_SEEKS,
+			};
+			register_shrinker(&cache_shrinker);
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror-implicit-function-declaration $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+			{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_3ARGS_SHRINKER_CALLBACK 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+			{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+																		{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether new 2-argument shrinker exists" >&5
+$as_echo_n "checking whether new 2-argument shrinker exists... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+				#include <linux/mm.h>
+
+				int shrinker_cb(struct shrinker *,
+						struct shrink_control *sc);
+
+int
+main (void)
+{
+
+				struct shrinker cache_shrinker = {
+					.shrink = shrinker_cb,
+					.seeks = DEFAULT_SEEKS,
+				};
+				register_shrinker(&cache_shrinker);
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror-implicit-function-declaration $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+				{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_2ARGS_NEW_SHRINKER_CALLBACK 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+				{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+																								{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ->count_objects callback exists" >&5
+$as_echo_n "checking whether ->count_objects callback exists... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+					#include <linux/mm.h>
+
+					unsigned long shrinker_cb(
+						struct shrinker *,
+						struct shrink_control *sc);
+
+int
+main (void)
+{
+
+					struct shrinker cache_shrinker = {
+						.count_objects = shrinker_cb,
+						.scan_objects = shrinker_cb,
+						.seeks = DEFAULT_SEEKS,
+					};
+					register_shrinker(&cache_shrinker);
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror-implicit-function-declaration $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+					{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_SPLIT_SHRINKER_CALLBACK 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+					as_fn_error $? "error" "$LINENO" 5
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+
+fi
+	rm -Rf build
+
+
+	EXTRA_KCFLAGS="$tmp_flags"
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether struct ctl_table has ctl_name" >&5
+$as_echo_n "checking whether struct ctl_table has ctl_name... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/sysctl.h>
+
+int
+main (void)
+{
+
+		struct ctl_table ctl __attribute__ ((unused));
+		ctl.ctl_name = 0;
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror-implicit-function-declaration $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_CTL_NAME 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether PDE_DATA() is available" >&5
+$as_echo_n "checking whether PDE_DATA() is available... " >&6; }
+
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/proc_fs.h>
+
+int
+main (void)
+{
+
+		PDE_DATA(NULL);
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror-implicit-function-declaration $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+  rc=0
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+ rc=1
+
+
+fi
+	rm -Rf build
+
+
+	if test $rc -ne 0; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+	else
+		if test "x$enable_linux_builtin" != xyes; then
+
+	grep -q -E '[[:space:]]PDE_DATA[[:space:]]' \
+		$LINUX_OBJ/Module*.symvers 2>/dev/null
+	rc=$?
+	if test $rc -ne 0; then
+		export=0
+		for file in ; do
+			grep -q -E "EXPORT_SYMBOL.*(PDE_DATA)" \
+				"$LINUX_OBJ/$file" 2>/dev/null
+			rc=$?
+			if test $rc -eq 0; then
+				export=1
+				break;
+			fi
+		done
+		if test $export -eq 0; then :
+			rc=1
+		else :
+			rc=0
+		fi
+	else :
+		rc=0
+	fi
+
+		fi
+		if test $rc -ne 0; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+		else :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_PDE_DATA 1" >>confdefs.h
+
+
+		fi
+	fi
+
+
+	tmp_flags="$EXTRA_KCFLAGS"
+	EXTRA_KCFLAGS="-Werror"
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether set_fs_pwd() requires const struct path *" >&5
+$as_echo_n "checking whether set_fs_pwd() requires const struct path *... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/spinlock.h>
+		#include <linux/fs_struct.h>
+		#include <linux/path.h>
+		void (*const set_fs_pwd_func)
+			(struct fs_struct *, const struct path *)
+			= set_fs_pwd;
+
+int
+main (void)
+{
+
+		return 0;
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror-implicit-function-declaration $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_SET_FS_PWD_WITH_CONST 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+			#include <linux/spinlock.h>
+			#include <linux/fs_struct.h>
+			#include <linux/path.h>
+			void (*const set_fs_pwd_func)
+				(struct fs_struct *, struct path *)
+				= set_fs_pwd;
+
+int
+main (void)
+{
+
+			return 0;
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror-implicit-function-declaration $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+			{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+			as_fn_error $? "unknown" "$LINENO" 5
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+
+fi
+	rm -Rf build
+
+
+	EXTRA_KCFLAGS="$tmp_flags"
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether vfs_unlink() wants 2 args" >&5
+$as_echo_n "checking whether vfs_unlink() wants 2 args... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/fs.h>
+
+int
+main (void)
+{
+
+		vfs_unlink((struct inode *) NULL, (struct dentry *) NULL);
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror-implicit-function-declaration $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_2ARGS_VFS_UNLINK 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+										{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether vfs_unlink() wants 3 args" >&5
+$as_echo_n "checking whether vfs_unlink() wants 3 args... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+			#include <linux/fs.h>
+
+int
+main (void)
+{
+
+			vfs_unlink((struct inode *) NULL,
+				(struct dentry *) NULL,
+				(struct inode **) NULL);
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror-implicit-function-declaration $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+			{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_3ARGS_VFS_UNLINK 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+			as_fn_error $? "no" "$LINENO" 5
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+
+
+fi
+	rm -Rf build
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether vfs_rename() wants 4 args" >&5
+$as_echo_n "checking whether vfs_rename() wants 4 args... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/fs.h>
+
+int
+main (void)
+{
+
+		vfs_rename((struct inode *) NULL, (struct dentry *) NULL,
+			(struct inode *) NULL, (struct dentry *) NULL);
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror-implicit-function-declaration $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_4ARGS_VFS_RENAME 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+										{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether vfs_rename() wants 5 args" >&5
+$as_echo_n "checking whether vfs_rename() wants 5 args... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+			#include <linux/fs.h>
+
+int
+main (void)
+{
+
+			vfs_rename((struct inode *) NULL,
+				(struct dentry *) NULL,
+				(struct inode *) NULL,
+				(struct dentry *) NULL,
+				(struct inode **) NULL);
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror-implicit-function-declaration $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+			{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_5ARGS_VFS_RENAME 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+			{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+															{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether vfs_rename() wants 6 args" >&5
+$as_echo_n "checking whether vfs_rename() wants 6 args... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+				#include <linux/fs.h>
+
+int
+main (void)
+{
+
+				vfs_rename((struct inode *) NULL,
+					(struct dentry *) NULL,
+					(struct inode *) NULL,
+					(struct dentry *) NULL,
+					(struct inode **) NULL,
+					(unsigned int) 0);
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror-implicit-function-declaration $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+				{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_6ARGS_VFS_RENAME 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+				as_fn_error $? "no" "$LINENO" 5
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether vfs_fsync() wants 2 args" >&5
+$as_echo_n "checking whether vfs_fsync() wants 2 args... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/fs.h>
+
+int
+main (void)
+{
+
+		vfs_fsync(NULL, 0);
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror-implicit-function-declaration $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_2ARGS_VFS_FSYNC 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether truncate_range() inode operation is available" >&5
+$as_echo_n "checking whether truncate_range() inode operation is available... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/fs.h>
+
+int
+main (void)
+{
+
+		struct inode_operations ops;
+		ops.truncate_range = NULL;
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror-implicit-function-declaration $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_INODE_TRUNCATE_RANGE 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether struct fs_struct uses spinlock_t" >&5
+$as_echo_n "checking whether struct fs_struct uses spinlock_t... " >&6; }
+	tmp_flags="$EXTRA_KCFLAGS"
+	EXTRA_KCFLAGS="-Werror"
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/sched.h>
+		#include <linux/fs_struct.h>
+
+int
+main (void)
+{
+
+		static struct fs_struct fs;
+		spin_lock_init(&fs.lock);
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror-implicit-function-declaration $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_FS_STRUCT_SPINLOCK 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+	EXTRA_KCFLAGS="$tmp_flags"
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether kuid_t/kgid_t is available" >&5
+$as_echo_n "checking whether kuid_t/kgid_t is available... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/uidgid.h>
+
+int
+main (void)
+{
+
+		kuid_t userid = KUIDT_INIT(0);
+		kgid_t groupid = KGIDT_INIT(0);
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror-implicit-function-declaration $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+			#include <linux/uidgid.h>
+
+int
+main (void)
+{
+
+			kuid_t userid = 0;
+			kgid_t groupid = 0;
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror-implicit-function-declaration $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+			{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes; optional" >&5
+$as_echo "yes; optional" >&6; }
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+			{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes; mandatory" >&5
+$as_echo "yes; mandatory" >&6; }
+
+$as_echo "#define HAVE_KUIDGID_T 1" >>confdefs.h
+
+
+
+
+fi
+	rm -Rf build
+
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether __put_task_struct() is available" >&5
+$as_echo_n "checking whether __put_task_struct() is available... " >&6; }
+
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/sched.h>
+
+int
+main (void)
+{
+
+		__put_task_struct(NULL);
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror-implicit-function-declaration $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+  rc=0
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+ rc=1
+
+
+fi
+	rm -Rf build
+
+
+	if test $rc -ne 0; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+	else
+		if test "x$enable_linux_builtin" != xyes; then
+
+	grep -q -E '[[:space:]]__put_task_struct[[:space:]]' \
+		$LINUX_OBJ/Module*.symvers 2>/dev/null
+	rc=$?
+	if test $rc -ne 0; then
+		export=0
+		for file in ; do
+			grep -q -E "EXPORT_SYMBOL.*(__put_task_struct)" \
+				"$LINUX_OBJ/$file" 2>/dev/null
+			rc=$?
+			if test $rc -eq 0; then
+				export=1
+				break;
+			fi
+		done
+		if test $export -eq 0; then :
+			rc=1
+		else :
+			rc=0
+		fi
+	else :
+		rc=0
+	fi
+
+		fi
+		if test $rc -ne 0; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+		else :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_PUT_TASK_STRUCT 1" >>confdefs.h
+
+
+		fi
+	fi
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether fops->fallocate() exists" >&5
+$as_echo_n "checking whether fops->fallocate() exists... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/fs.h>
+
+int
+main (void)
+{
+
+		long (*fallocate) (struct file *, int, loff_t, loff_t) = NULL;
+		struct file_operations fops __attribute__ ((unused)) = {
+			.fallocate = fallocate,
+		};
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror-implicit-function-declaration $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_FILE_FALLOCATE 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether iops->fallocate() exists" >&5
+$as_echo_n "checking whether iops->fallocate() exists... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/fs.h>
+
+int
+main (void)
+{
+
+		long (*fallocate) (struct inode *, int, loff_t, loff_t) = NULL;
+		struct inode_operations fops __attribute__ ((unused)) = {
+			.fallocate = fallocate,
+		};
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror-implicit-function-declaration $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_INODE_FALLOCATE 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether fops->fallocate() exists" >&5
+$as_echo_n "checking whether fops->fallocate() exists... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/fs.h>
+
+int
+main (void)
+{
+
+		long (*fallocate) (struct file *, int, loff_t, loff_t) = NULL;
+		struct file_operations_no_const fops __attribute__ ((unused)) = {
+			.fallocate = fallocate,
+		};
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror-implicit-function-declaration $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_FILE_FALLOCATE 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether CONFIG_ZLIB_INFLATE is defined" >&5
+$as_echo_n "checking whether CONFIG_ZLIB_INFLATE is defined... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#if !defined(CONFIG_ZLIB_INFLATE) && \
+		    !defined(CONFIG_ZLIB_INFLATE_MODULE)
+		#error CONFIG_ZLIB_INFLATE not defined
+		#endif
+
+int
+main (void)
+{
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror-implicit-function-declaration $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+		as_fn_error $? "
+	*** This kernel does not include the required zlib inflate support.
+	*** Rebuild the kernel with CONFIG_ZLIB_INFLATE=y|m set." "$LINENO" 5
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether CONFIG_ZLIB_DEFLATE is defined" >&5
+$as_echo_n "checking whether CONFIG_ZLIB_DEFLATE is defined... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#if !defined(CONFIG_ZLIB_DEFLATE) && \
+		    !defined(CONFIG_ZLIB_DEFLATE_MODULE)
+		#error CONFIG_ZLIB_DEFLATE not defined
+		#endif
+
+int
+main (void)
+{
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror-implicit-function-declaration $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+		as_fn_error $? "
+	*** This kernel does not include the required zlib deflate support.
+	*** Rebuild the kernel with CONFIG_ZLIB_DEFLATE=y|m set." "$LINENO" 5
+
+
+
+fi
+	rm -Rf build
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether zlib_deflate_workspacesize() wants 2 args" >&5
+$as_echo_n "checking whether zlib_deflate_workspacesize() wants 2 args... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/zlib.h>
+
+int
+main (void)
+{
+
+		return zlib_deflate_workspacesize(MAX_WBITS, MAX_MEM_LEVEL);
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror-implicit-function-declaration $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_2ARGS_ZLIB_DEFLATE_WORKSPACESIZE 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether struct shrink_control exists" >&5
+$as_echo_n "checking whether struct shrink_control exists... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/mm.h>
+
+int
+main (void)
+{
+
+		struct shrink_control sc __attribute__ ((unused));
+
+		sc.nr_to_scan = 0;
+		sc.gfp_mask = GFP_KERNEL;
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror-implicit-function-declaration $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_SHRINK_CONTROL_STRUCT 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether struct rw_semaphore member wait_lock is raw" >&5
+$as_echo_n "checking whether struct rw_semaphore member wait_lock is raw... " >&6; }
+	tmp_flags="$EXTRA_KCFLAGS"
+	EXTRA_KCFLAGS="-Werror"
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/rwsem.h>
+
+int
+main (void)
+{
+
+		struct rw_semaphore dummy_semaphore __attribute__ ((unused));
+		raw_spinlock_t dummy_lock __attribute__ ((unused));
+		dummy_semaphore.wait_lock = dummy_lock;
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror-implicit-function-declaration $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define RWSEM_SPINLOCK_IS_RAW 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+	EXTRA_KCFLAGS="$tmp_flags"
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether header linux/sched/rt.h exists" >&5
+$as_echo_n "checking whether header linux/sched/rt.h exists... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/sched.h>
+		#include <linux/sched/rt.h>
+
+int
+main (void)
+{
+
+		return 0;
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror-implicit-function-declaration $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+
+$as_echo "#define HAVE_SCHED_RT_HEADER 1" >>confdefs.h
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether vfs_getattr() wants" >&5
+$as_echo_n "checking whether vfs_getattr() wants... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/fs.h>
+
+int
+main (void)
+{
+
+		vfs_getattr((struct path *) NULL,
+			(struct kstat *)NULL);
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror-implicit-function-declaration $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: 2 args" >&5
+$as_echo "2 args" >&6; }
+
+$as_echo "#define HAVE_2ARGS_VFS_GETATTR 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+			#include <linux/fs.h>
+
+int
+main (void)
+{
+
+			vfs_getattr((struct vfsmount *)NULL,
+				(struct dentry *)NULL,
+				(struct kstat *)NULL);
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror-implicit-function-declaration $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+			{ $as_echo "$as_me:${as_lineno-$LINENO}: result: 3 args" >&5
+$as_echo "3 args" >&6; }
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+			as_fn_error $? "unknown" "$LINENO" 5
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether usleep_range() is available" >&5
+$as_echo_n "checking whether usleep_range() is available... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/delay.h>
+
+int
+main (void)
+{
+
+		usleep_range(0, 0);
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror-implicit-function-declaration $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_USLEEP_RANGE 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether struct kmem_cache has allocflags" >&5
+$as_echo_n "checking whether struct kmem_cache has allocflags... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/slab.h>
+
+int
+main (void)
+{
+
+		struct kmem_cache cachep __attribute__ ((unused));
+		cachep.allocflags = GFP_KERNEL;
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror-implicit-function-declaration $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_KMEM_CACHE_ALLOCFLAGS 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether struct kmem_cache has gfpflags" >&5
+$as_echo_n "checking whether struct kmem_cache has gfpflags... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+			#include <linux/slab.h>
+
+int
+main (void)
+{
+
+			struct kmem_cache cachep __attribute__ ((unused));
+			cachep.gfpflags = GFP_KERNEL;
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror-implicit-function-declaration $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+			{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_KMEM_CACHE_GFPFLAGS 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+			{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether wait_on_bit() takes an action" >&5
+$as_echo_n "checking whether wait_on_bit() takes an action... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/wait.h>
+
+int
+main (void)
+{
+
+		int (*action)(void *) = NULL;
+		wait_on_bit(NULL, 0, action, 0);
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror-implicit-function-declaration $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_WAIT_ON_BIT_ACTION 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+
+ ;;
+		user)      ;;
+		all)
+
+
+# Check whether --with-linux was given.
+if test "${with_linux+set}" = set; then :
+  withval=$with_linux; kernelsrc="$withval"
+fi
+
+
+
+# Check whether --with-linux-obj was given.
+if test "${with_linux_obj+set}" = set; then :
+  withval=$with_linux_obj; kernelbuild="$withval"
+fi
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking kernel source directory" >&5
+$as_echo_n "checking kernel source directory... " >&6; }
+	if test -z "$kernelsrc"; then
+		if test -e "/lib/modules/$(uname -r)/source"; then
+			headersdir="/lib/modules/$(uname -r)/source"
+			sourcelink=$(readlink -f "$headersdir")
+		elif test -e "/lib/modules/$(uname -r)/build"; then
+			headersdir="/lib/modules/$(uname -r)/build"
+			sourcelink=$(readlink -f "$headersdir")
+		else
+			sourcelink=$(ls -1d /usr/src/kernels/* \
+			             /usr/src/linux-* \
+			             2>/dev/null | grep -v obj | tail -1)
+		fi
+
+		if test -n "$sourcelink" && test -e ${sourcelink}; then
+			kernelsrc=`readlink -f ${sourcelink}`
+		else
+			kernelsrc="Not found"
+		fi
+	else
+		if test "$kernelsrc" = "NONE"; then
+			kernsrcver=NONE
+		fi
+	fi
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $kernelsrc" >&5
+$as_echo "$kernelsrc" >&6; }
+	if test ! -d "$kernelsrc"; then
+		as_fn_error $? "
+	*** Please make sure the kernel devel package for your distribution
+	*** is installed and then try again.  If that fails, you can specify the
+	*** location of the kernel source with the '--with-linux=PATH' option." "$LINENO" 5
+	fi
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking kernel build directory" >&5
+$as_echo_n "checking kernel build directory... " >&6; }
+	if test -z "$kernelbuild"; then
+		if test -e "/lib/modules/$(uname -r)/build"; then
+			kernelbuild=`readlink -f /lib/modules/$(uname -r)/build`
+		elif test -d ${kernelsrc}-obj/${target_cpu}/${target_cpu}; then
+			kernelbuild=${kernelsrc}-obj/${target_cpu}/${target_cpu}
+		elif test -d ${kernelsrc}-obj/${target_cpu}/default; then
+			kernelbuild=${kernelsrc}-obj/${target_cpu}/default
+		elif test -d `dirname ${kernelsrc}`/build-${target_cpu}; then
+			kernelbuild=`dirname ${kernelsrc}`/build-${target_cpu}
+		else
+			kernelbuild=${kernelsrc}
+		fi
+	fi
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $kernelbuild" >&5
+$as_echo "$kernelbuild" >&6; }
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking kernel source version" >&5
+$as_echo_n "checking kernel source version... " >&6; }
+	utsrelease1=$kernelbuild/include/linux/version.h
+	utsrelease2=$kernelbuild/include/linux/utsrelease.h
+	utsrelease3=$kernelbuild/include/generated/utsrelease.h
+	if test -r $utsrelease1 && fgrep -q UTS_RELEASE $utsrelease1; then
+		utsrelease=linux/version.h
+	elif test -r $utsrelease2 && fgrep -q UTS_RELEASE $utsrelease2; then
+		utsrelease=linux/utsrelease.h
+	elif test -r $utsrelease3 && fgrep -q UTS_RELEASE $utsrelease3; then
+		utsrelease=generated/utsrelease.h
+	fi
+
+	if test "$utsrelease"; then
+		kernsrcver=`(echo "#include <$utsrelease>";
+		             echo "kernsrcver=UTS_RELEASE") |
+		             cpp -I $kernelbuild/include |
+		             grep "^kernsrcver=" | cut -d \" -f 2`
+
+		if test -z "$kernsrcver"; then
+			{ $as_echo "$as_me:${as_lineno-$LINENO}: result: Not found" >&5
+$as_echo "Not found" >&6; }
+			as_fn_error $? "*** Cannot determine kernel version." "$LINENO" 5
+		fi
+	else
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: Not found" >&5
+$as_echo "Not found" >&6; }
+		if test "x$enable_linux_builtin" != xyes; then
+			as_fn_error $? "*** Cannot find UTS_RELEASE definition." "$LINENO" 5
+		else
+			as_fn_error $? "
+	*** Cannot find UTS_RELEASE definition.
+	*** Please run 'make prepare' inside the kernel source tree." "$LINENO" 5
+		fi
+	fi
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $kernsrcver" >&5
+$as_echo "$kernsrcver" >&6; }
+
+	LINUX=${kernelsrc}
+	LINUX_OBJ=${kernelbuild}
+	LINUX_VERSION=${kernsrcver}
+
+
+
+
+
+
+	modpost=$LINUX/scripts/Makefile.modpost
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking kernel file name for module symbols" >&5
+$as_echo_n "checking kernel file name for module symbols... " >&6; }
+	if test "x$enable_linux_builtin" != xyes -a -f "$modpost"; then
+		if grep -q Modules.symvers $modpost; then
+			LINUX_SYMBOLS=Modules.symvers
+		else
+			LINUX_SYMBOLS=Module.symvers
+		fi
+
+		if ! test -f "$LINUX_OBJ/$LINUX_SYMBOLS"; then
+			as_fn_error $? "
+	*** Please make sure the kernel devel package for your distribution
+	*** is installed.  If you are building with a custom kernel, make sure the
+	*** kernel is configured, built, and the '--with-linux=PATH' configure
+	*** option refers to the location of the kernel source." "$LINENO" 5
+		fi
+	else
+		LINUX_SYMBOLS=NONE
+	fi
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $LINUX_SYMBOLS" >&5
+$as_echo "$LINUX_SYMBOLS" >&6; }
+
+
+
+
+	if test "${LINUX_OBJ}" != "${LINUX}"; then
+		KERNELMAKE_PARAMS="$KERNELMAKE_PARAMS O=$LINUX_OBJ"
+	fi
+
+
+	KERNELCPPFLAGS="$KERNELCPPFLAGS -Wstrict-prototypes"
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether debugging is enabled" >&5
+$as_echo_n "checking whether debugging is enabled... " >&6; }
+	# Check whether --enable-debug was given.
+if test "${enable_debug+set}" = set; then :
+  enableval=$enable_debug;
+else
+  enable_debug=no
+fi
+
+
+	if test "x$enable_debug" = xyes; then :
+
+		KERNELCPPFLAGS="${KERNELCPPFLAGS} -DDEBUG -Werror"
+		DEBUG_CFLAGS="-DDEBUG -Werror"
+		DEBUG_SPL="_with_debug"
+
+else
+
+		KERNELCPPFLAGS="${KERNELCPPFLAGS} -DNDEBUG"
+		DEBUG_CFLAGS="-DNDEBUG"
+		DEBUG_SPL="_without_debug"
+
+fi
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_debug" >&5
+$as_echo "$enable_debug" >&6; }
+
+
+	# Check whether --enable-debug-kmem was given.
+if test "${enable_debug_kmem+set}" = set; then :
+  enableval=$enable_debug_kmem;
+else
+  enable_debug_kmem=no
+fi
+
+
+	if test "x$enable_debug_kmem" = xyes; then :
+
+		KERNELCPPFLAGS="${KERNELCPPFLAGS} -DDEBUG_KMEM"
+		DEBUG_KMEM="_with_debug_kmem"
+
+$as_echo "#define DEBUG_KMEM 1" >>confdefs.h
+
+
+else
+
+		DEBUG_KMEM="_without_debug_kmem"
+
+fi
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether basic kmem accounting is enabled" >&5
+$as_echo_n "checking whether basic kmem accounting is enabled... " >&6; }
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_debug_kmem" >&5
+$as_echo "$enable_debug_kmem" >&6; }
+
+
+	# Check whether --enable-debug-kmem-tracking was given.
+if test "${enable_debug_kmem_tracking+set}" = set; then :
+  enableval=$enable_debug_kmem_tracking;
+else
+  enable_debug_kmem_tracking=no
+fi
+
+
+	if test "x$enable_debug_kmem_tracking" = xyes; then :
+
+		KERNELCPPFLAGS="${KERNELCPPFLAGS} -DDEBUG_KMEM_TRACKING"
+		DEBUG_KMEM_TRACKING="_with_debug_kmem_tracking"
+
+$as_echo "#define DEBUG_KMEM_TRACKING 1" >>confdefs.h
+
+
+else
+
+		DEBUG_KMEM_TRACKING="_without_debug_kmem_tracking"
+
+fi
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether detailed kmem tracking is enabled" >&5
+$as_echo_n "checking whether detailed kmem tracking is enabled... " >&6; }
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_debug_kmem_tracking" >&5
+$as_echo "$enable_debug_kmem_tracking" >&6; }
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether modules can be built" >&5
+$as_echo_n "checking whether modules can be built... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+int
+main (void)
+{
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror-implicit-function-declaration $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+		if test "x$enable_linux_builtin" != xyes; then
+			as_fn_error $? "*** Unable to build an empty module." "$LINENO" 5
+		else
+			as_fn_error $? "
+	*** Unable to build an empty module.
+	*** Please run 'make scripts' inside the kernel source tree." "$LINENO" 5
+		fi
+
+
+
+fi
+	rm -Rf build
+
+
+
+	if test "x$cross_compiling" != xyes; then :
+
+		if test "$cross_compiling" = yes; then :
+  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot run test program while cross compiling
+See \`config.log' for more details" "$LINENO" 5; }
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+
+				#include "$LINUX/include/linux/license.h"
+
+int
+main ()
+{
+
+				return !license_is_gpl_compatible(
+				    "$SPL_META_LICENSE");
+
+  ;
+  return 0;
+}
+
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+
+
+$as_echo "#define SPL_IS_GPL_COMPATIBLE 1" >>confdefs.h
+
+
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+
+fi
+
+
+	# Check whether --enable-atomic-spinlocks was given.
+if test "${enable_atomic_spinlocks+set}" = set; then :
+  enableval=$enable_atomic_spinlocks;
+else
+  enable_atomic_spinlocks=check
+fi
+
+
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/fs.h>
+
+int
+main (void)
+{
+
+		atomic64_t *ptr __attribute__ ((unused));
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror-implicit-function-declaration $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		have_atomic64_t=yes
+
+$as_echo "#define HAVE_ATOMIC64_T 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		have_atomic64_t=no
+
+
+
+fi
+	rm -Rf build
+
+
+
+	if test "x$enable_atomic_spinlocks" = xcheck; then :
+
+		if test "x$have_atomic64_t" = xyes; then :
+
+			enable_atomic_spinlocks=no
+
+else
+
+			enable_atomic_spinlocks=yes
+
+fi
+
+fi
+
+	if test "x$enable_atomic_spinlocks" = xyes; then :
+
+
+$as_echo "#define ATOMIC_SPINLOCK 1" >>confdefs.h
+
+
+else
+
+		if test "x$have_atomic64_t" = xno; then :
+
+			{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "--disable-atomic-spinlocks given but required atomic64 support is unavailable
+See \`config.log' for more details" "$LINENO" 5; }
+
+fi
+
+fi
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether atomic types use spinlocks" >&5
+$as_echo_n "checking whether atomic types use spinlocks... " >&6; }
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_atomic_spinlocks" >&5
+$as_echo "$enable_atomic_spinlocks" >&6; }
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether kernel defines atomic64_t" >&5
+$as_echo_n "checking whether kernel defines atomic64_t... " >&6; }
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_atomic64_t" >&5
+$as_echo "$have_atomic64_t" >&6; }
+
+
+	tmp_flags="$EXTRA_KCFLAGS"
+	EXTRA_KCFLAGS="-Werror"
+					{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether old 2-argument shrinker exists" >&5
+$as_echo_n "checking whether old 2-argument shrinker exists... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/mm.h>
+
+		int shrinker_cb(int nr_to_scan, gfp_t gfp_mask);
+
+int
+main (void)
+{
+
+		struct shrinker cache_shrinker = {
+			.shrink = shrinker_cb,
+			.seeks = DEFAULT_SEEKS,
+		};
+		register_shrinker(&cache_shrinker);
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror-implicit-function-declaration $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_2ARGS_OLD_SHRINKER_CALLBACK 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+												{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether old 3-argument shrinker exists" >&5
+$as_echo_n "checking whether old 3-argument shrinker exists... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+			#include <linux/mm.h>
+
+			int shrinker_cb(struct shrinker *, int nr_to_scan,
+					gfp_t gfp_mask);
+
+int
+main (void)
+{
+
+			struct shrinker cache_shrinker = {
+				.shrink = shrinker_cb,
+				.seeks = DEFAULT_SEEKS,
+			};
+			register_shrinker(&cache_shrinker);
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror-implicit-function-declaration $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+			{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_3ARGS_SHRINKER_CALLBACK 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+			{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+																		{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether new 2-argument shrinker exists" >&5
+$as_echo_n "checking whether new 2-argument shrinker exists... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+				#include <linux/mm.h>
+
+				int shrinker_cb(struct shrinker *,
+						struct shrink_control *sc);
+
+int
+main (void)
+{
+
+				struct shrinker cache_shrinker = {
+					.shrink = shrinker_cb,
+					.seeks = DEFAULT_SEEKS,
+				};
+				register_shrinker(&cache_shrinker);
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror-implicit-function-declaration $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+				{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_2ARGS_NEW_SHRINKER_CALLBACK 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+				{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+																								{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ->count_objects callback exists" >&5
+$as_echo_n "checking whether ->count_objects callback exists... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+					#include <linux/mm.h>
+
+					unsigned long shrinker_cb(
+						struct shrinker *,
+						struct shrink_control *sc);
+
+int
+main (void)
+{
+
+					struct shrinker cache_shrinker = {
+						.count_objects = shrinker_cb,
+						.scan_objects = shrinker_cb,
+						.seeks = DEFAULT_SEEKS,
+					};
+					register_shrinker(&cache_shrinker);
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror-implicit-function-declaration $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+					{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_SPLIT_SHRINKER_CALLBACK 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+					as_fn_error $? "error" "$LINENO" 5
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+
+fi
+	rm -Rf build
+
+
+	EXTRA_KCFLAGS="$tmp_flags"
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether struct ctl_table has ctl_name" >&5
+$as_echo_n "checking whether struct ctl_table has ctl_name... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/sysctl.h>
+
+int
+main (void)
+{
+
+		struct ctl_table ctl __attribute__ ((unused));
+		ctl.ctl_name = 0;
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror-implicit-function-declaration $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_CTL_NAME 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether PDE_DATA() is available" >&5
+$as_echo_n "checking whether PDE_DATA() is available... " >&6; }
+
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/proc_fs.h>
+
+int
+main (void)
+{
+
+		PDE_DATA(NULL);
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror-implicit-function-declaration $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+  rc=0
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+ rc=1
+
+
+fi
+	rm -Rf build
+
+
+	if test $rc -ne 0; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+	else
+		if test "x$enable_linux_builtin" != xyes; then
+
+	grep -q -E '[[:space:]]PDE_DATA[[:space:]]' \
+		$LINUX_OBJ/Module*.symvers 2>/dev/null
+	rc=$?
+	if test $rc -ne 0; then
+		export=0
+		for file in ; do
+			grep -q -E "EXPORT_SYMBOL.*(PDE_DATA)" \
+				"$LINUX_OBJ/$file" 2>/dev/null
+			rc=$?
+			if test $rc -eq 0; then
+				export=1
+				break;
+			fi
+		done
+		if test $export -eq 0; then :
+			rc=1
+		else :
+			rc=0
+		fi
+	else :
+		rc=0
+	fi
+
+		fi
+		if test $rc -ne 0; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+		else :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_PDE_DATA 1" >>confdefs.h
+
+
+		fi
+	fi
+
+
+	tmp_flags="$EXTRA_KCFLAGS"
+	EXTRA_KCFLAGS="-Werror"
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether set_fs_pwd() requires const struct path *" >&5
+$as_echo_n "checking whether set_fs_pwd() requires const struct path *... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/spinlock.h>
+		#include <linux/fs_struct.h>
+		#include <linux/path.h>
+		void (*const set_fs_pwd_func)
+			(struct fs_struct *, const struct path *)
+			= set_fs_pwd;
+
+int
+main (void)
+{
+
+		return 0;
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror-implicit-function-declaration $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_SET_FS_PWD_WITH_CONST 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+			#include <linux/spinlock.h>
+			#include <linux/fs_struct.h>
+			#include <linux/path.h>
+			void (*const set_fs_pwd_func)
+				(struct fs_struct *, struct path *)
+				= set_fs_pwd;
+
+int
+main (void)
+{
+
+			return 0;
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror-implicit-function-declaration $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+			{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+			as_fn_error $? "unknown" "$LINENO" 5
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+
+fi
+	rm -Rf build
+
+
+	EXTRA_KCFLAGS="$tmp_flags"
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether vfs_unlink() wants 2 args" >&5
+$as_echo_n "checking whether vfs_unlink() wants 2 args... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/fs.h>
+
+int
+main (void)
+{
+
+		vfs_unlink((struct inode *) NULL, (struct dentry *) NULL);
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror-implicit-function-declaration $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_2ARGS_VFS_UNLINK 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+										{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether vfs_unlink() wants 3 args" >&5
+$as_echo_n "checking whether vfs_unlink() wants 3 args... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+			#include <linux/fs.h>
+
+int
+main (void)
+{
+
+			vfs_unlink((struct inode *) NULL,
+				(struct dentry *) NULL,
+				(struct inode **) NULL);
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror-implicit-function-declaration $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+			{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_3ARGS_VFS_UNLINK 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+			as_fn_error $? "no" "$LINENO" 5
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+
+
+fi
+	rm -Rf build
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether vfs_rename() wants 4 args" >&5
+$as_echo_n "checking whether vfs_rename() wants 4 args... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/fs.h>
+
+int
+main (void)
+{
+
+		vfs_rename((struct inode *) NULL, (struct dentry *) NULL,
+			(struct inode *) NULL, (struct dentry *) NULL);
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror-implicit-function-declaration $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_4ARGS_VFS_RENAME 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+										{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether vfs_rename() wants 5 args" >&5
+$as_echo_n "checking whether vfs_rename() wants 5 args... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+			#include <linux/fs.h>
+
+int
+main (void)
+{
+
+			vfs_rename((struct inode *) NULL,
+				(struct dentry *) NULL,
+				(struct inode *) NULL,
+				(struct dentry *) NULL,
+				(struct inode **) NULL);
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror-implicit-function-declaration $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+			{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_5ARGS_VFS_RENAME 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+			{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+															{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether vfs_rename() wants 6 args" >&5
+$as_echo_n "checking whether vfs_rename() wants 6 args... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+				#include <linux/fs.h>
+
+int
+main (void)
+{
+
+				vfs_rename((struct inode *) NULL,
+					(struct dentry *) NULL,
+					(struct inode *) NULL,
+					(struct dentry *) NULL,
+					(struct inode **) NULL,
+					(unsigned int) 0);
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror-implicit-function-declaration $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+				{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_6ARGS_VFS_RENAME 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+				as_fn_error $? "no" "$LINENO" 5
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether vfs_fsync() wants 2 args" >&5
+$as_echo_n "checking whether vfs_fsync() wants 2 args... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/fs.h>
+
+int
+main (void)
+{
+
+		vfs_fsync(NULL, 0);
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror-implicit-function-declaration $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_2ARGS_VFS_FSYNC 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether truncate_range() inode operation is available" >&5
+$as_echo_n "checking whether truncate_range() inode operation is available... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/fs.h>
+
+int
+main (void)
+{
+
+		struct inode_operations ops;
+		ops.truncate_range = NULL;
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror-implicit-function-declaration $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_INODE_TRUNCATE_RANGE 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether struct fs_struct uses spinlock_t" >&5
+$as_echo_n "checking whether struct fs_struct uses spinlock_t... " >&6; }
+	tmp_flags="$EXTRA_KCFLAGS"
+	EXTRA_KCFLAGS="-Werror"
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/sched.h>
+		#include <linux/fs_struct.h>
+
+int
+main (void)
+{
+
+		static struct fs_struct fs;
+		spin_lock_init(&fs.lock);
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror-implicit-function-declaration $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_FS_STRUCT_SPINLOCK 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+	EXTRA_KCFLAGS="$tmp_flags"
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether kuid_t/kgid_t is available" >&5
+$as_echo_n "checking whether kuid_t/kgid_t is available... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/uidgid.h>
+
+int
+main (void)
+{
+
+		kuid_t userid = KUIDT_INIT(0);
+		kgid_t groupid = KGIDT_INIT(0);
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror-implicit-function-declaration $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+			#include <linux/uidgid.h>
+
+int
+main (void)
+{
+
+			kuid_t userid = 0;
+			kgid_t groupid = 0;
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror-implicit-function-declaration $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+			{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes; optional" >&5
+$as_echo "yes; optional" >&6; }
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+			{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes; mandatory" >&5
+$as_echo "yes; mandatory" >&6; }
+
+$as_echo "#define HAVE_KUIDGID_T 1" >>confdefs.h
+
+
+
+
+fi
+	rm -Rf build
+
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether __put_task_struct() is available" >&5
+$as_echo_n "checking whether __put_task_struct() is available... " >&6; }
+
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/sched.h>
+
+int
+main (void)
+{
+
+		__put_task_struct(NULL);
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror-implicit-function-declaration $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+  rc=0
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+ rc=1
+
+
+fi
+	rm -Rf build
+
+
+	if test $rc -ne 0; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+	else
+		if test "x$enable_linux_builtin" != xyes; then
+
+	grep -q -E '[[:space:]]__put_task_struct[[:space:]]' \
+		$LINUX_OBJ/Module*.symvers 2>/dev/null
+	rc=$?
+	if test $rc -ne 0; then
+		export=0
+		for file in ; do
+			grep -q -E "EXPORT_SYMBOL.*(__put_task_struct)" \
+				"$LINUX_OBJ/$file" 2>/dev/null
+			rc=$?
+			if test $rc -eq 0; then
+				export=1
+				break;
+			fi
+		done
+		if test $export -eq 0; then :
+			rc=1
+		else :
+			rc=0
+		fi
+	else :
+		rc=0
+	fi
+
+		fi
+		if test $rc -ne 0; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+		else :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_PUT_TASK_STRUCT 1" >>confdefs.h
+
+
+		fi
+	fi
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether fops->fallocate() exists" >&5
+$as_echo_n "checking whether fops->fallocate() exists... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/fs.h>
+
+int
+main (void)
+{
+
+		long (*fallocate) (struct file *, int, loff_t, loff_t) = NULL;
+		struct file_operations fops __attribute__ ((unused)) = {
+			.fallocate = fallocate,
+		};
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror-implicit-function-declaration $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_FILE_FALLOCATE 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether iops->fallocate() exists" >&5
+$as_echo_n "checking whether iops->fallocate() exists... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/fs.h>
+
+int
+main (void)
+{
+
+		long (*fallocate) (struct inode *, int, loff_t, loff_t) = NULL;
+		struct inode_operations fops __attribute__ ((unused)) = {
+			.fallocate = fallocate,
+		};
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror-implicit-function-declaration $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_INODE_FALLOCATE 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether fops->fallocate() exists" >&5
+$as_echo_n "checking whether fops->fallocate() exists... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/fs.h>
+
+int
+main (void)
+{
+
+		long (*fallocate) (struct file *, int, loff_t, loff_t) = NULL;
+		struct file_operations_no_const fops __attribute__ ((unused)) = {
+			.fallocate = fallocate,
+		};
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror-implicit-function-declaration $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_FILE_FALLOCATE 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether CONFIG_ZLIB_INFLATE is defined" >&5
+$as_echo_n "checking whether CONFIG_ZLIB_INFLATE is defined... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#if !defined(CONFIG_ZLIB_INFLATE) && \
+		    !defined(CONFIG_ZLIB_INFLATE_MODULE)
+		#error CONFIG_ZLIB_INFLATE not defined
+		#endif
+
+int
+main (void)
+{
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror-implicit-function-declaration $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+		as_fn_error $? "
+	*** This kernel does not include the required zlib inflate support.
+	*** Rebuild the kernel with CONFIG_ZLIB_INFLATE=y|m set." "$LINENO" 5
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether CONFIG_ZLIB_DEFLATE is defined" >&5
+$as_echo_n "checking whether CONFIG_ZLIB_DEFLATE is defined... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#if !defined(CONFIG_ZLIB_DEFLATE) && \
+		    !defined(CONFIG_ZLIB_DEFLATE_MODULE)
+		#error CONFIG_ZLIB_DEFLATE not defined
+		#endif
+
+int
+main (void)
+{
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror-implicit-function-declaration $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+		as_fn_error $? "
+	*** This kernel does not include the required zlib deflate support.
+	*** Rebuild the kernel with CONFIG_ZLIB_DEFLATE=y|m set." "$LINENO" 5
+
+
+
+fi
+	rm -Rf build
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether zlib_deflate_workspacesize() wants 2 args" >&5
+$as_echo_n "checking whether zlib_deflate_workspacesize() wants 2 args... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/zlib.h>
+
+int
+main (void)
+{
+
+		return zlib_deflate_workspacesize(MAX_WBITS, MAX_MEM_LEVEL);
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror-implicit-function-declaration $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_2ARGS_ZLIB_DEFLATE_WORKSPACESIZE 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether struct shrink_control exists" >&5
+$as_echo_n "checking whether struct shrink_control exists... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/mm.h>
+
+int
+main (void)
+{
+
+		struct shrink_control sc __attribute__ ((unused));
+
+		sc.nr_to_scan = 0;
+		sc.gfp_mask = GFP_KERNEL;
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror-implicit-function-declaration $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_SHRINK_CONTROL_STRUCT 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether struct rw_semaphore member wait_lock is raw" >&5
+$as_echo_n "checking whether struct rw_semaphore member wait_lock is raw... " >&6; }
+	tmp_flags="$EXTRA_KCFLAGS"
+	EXTRA_KCFLAGS="-Werror"
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/rwsem.h>
+
+int
+main (void)
+{
+
+		struct rw_semaphore dummy_semaphore __attribute__ ((unused));
+		raw_spinlock_t dummy_lock __attribute__ ((unused));
+		dummy_semaphore.wait_lock = dummy_lock;
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror-implicit-function-declaration $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define RWSEM_SPINLOCK_IS_RAW 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+	EXTRA_KCFLAGS="$tmp_flags"
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether header linux/sched/rt.h exists" >&5
+$as_echo_n "checking whether header linux/sched/rt.h exists... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/sched.h>
+		#include <linux/sched/rt.h>
+
+int
+main (void)
+{
+
+		return 0;
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror-implicit-function-declaration $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+
+$as_echo "#define HAVE_SCHED_RT_HEADER 1" >>confdefs.h
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether vfs_getattr() wants" >&5
+$as_echo_n "checking whether vfs_getattr() wants... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/fs.h>
+
+int
+main (void)
+{
+
+		vfs_getattr((struct path *) NULL,
+			(struct kstat *)NULL);
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror-implicit-function-declaration $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: 2 args" >&5
+$as_echo "2 args" >&6; }
+
+$as_echo "#define HAVE_2ARGS_VFS_GETATTR 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+			#include <linux/fs.h>
+
+int
+main (void)
+{
+
+			vfs_getattr((struct vfsmount *)NULL,
+				(struct dentry *)NULL,
+				(struct kstat *)NULL);
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror-implicit-function-declaration $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+			{ $as_echo "$as_me:${as_lineno-$LINENO}: result: 3 args" >&5
+$as_echo "3 args" >&6; }
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+			as_fn_error $? "unknown" "$LINENO" 5
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether usleep_range() is available" >&5
+$as_echo_n "checking whether usleep_range() is available... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/delay.h>
+
+int
+main (void)
+{
+
+		usleep_range(0, 0);
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror-implicit-function-declaration $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_USLEEP_RANGE 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether struct kmem_cache has allocflags" >&5
+$as_echo_n "checking whether struct kmem_cache has allocflags... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/slab.h>
+
+int
+main (void)
+{
+
+		struct kmem_cache cachep __attribute__ ((unused));
+		cachep.allocflags = GFP_KERNEL;
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror-implicit-function-declaration $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_KMEM_CACHE_ALLOCFLAGS 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether struct kmem_cache has gfpflags" >&5
+$as_echo_n "checking whether struct kmem_cache has gfpflags... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+			#include <linux/slab.h>
+
+int
+main (void)
+{
+
+			struct kmem_cache cachep __attribute__ ((unused));
+			cachep.gfpflags = GFP_KERNEL;
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror-implicit-function-declaration $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+			{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_KMEM_CACHE_GFPFLAGS 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+			{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether wait_on_bit() takes an action" >&5
+$as_echo_n "checking whether wait_on_bit() takes an action... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/wait.h>
+
+int
+main (void)
+{
+
+		int (*action)(void *) = NULL;
+		wait_on_bit(NULL, 0, action, 0);
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror-implicit-function-declaration $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_WAIT_ON_BIT_ACTION 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+		           ;;
+		srpm)                        ;;
+		*)
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: Error!" >&5
+$as_echo "Error!" >&6; }
+		as_fn_error $? "Bad value \"$SPL_CONFIG\" for --with-config,
+		             user kernel|user|all|srpm" "$LINENO" 5 ;;
+	esac
+
+	 if test "$SPL_CONFIG" = user -o "$SPL_CONFIG" = all; then
+  CONFIG_USER_TRUE=
+  CONFIG_USER_FALSE='#'
+else
+  CONFIG_USER_TRUE='#'
+  CONFIG_USER_FALSE=
+fi
+
+	 if test "$SPL_CONFIG" = kernel -o "$SPL_CONFIG" = all &&
+	               test "x$enable_linux_builtin" != xyes ; then
+  CONFIG_KERNEL_TRUE=
+  CONFIG_KERNEL_FALSE='#'
+else
+  CONFIG_KERNEL_TRUE='#'
+  CONFIG_KERNEL_FALSE=
+fi
+
+
+
+ac_config_files="$ac_config_files Makefile man/Makefile man/man1/Makefile man/man5/Makefile lib/Makefile cmd/Makefile module/Makefile module/spl/Makefile module/splat/Makefile include/Makefile include/fs/Makefile include/linux/Makefile include/rpc/Makefile include/sharefs/Makefile include/sys/Makefile include/sys/fm/Makefile include/sys/fs/Makefile include/sys/sysevent/Makefile include/util/Makefile include/vm/Makefile scripts/Makefile rpm/Makefile rpm/redhat/Makefile rpm/redhat/spl.spec rpm/redhat/spl-kmod.spec rpm/redhat/spl-dkms.spec rpm/generic/Makefile rpm/generic/spl.spec rpm/generic/spl-kmod.spec rpm/generic/spl-dkms.spec spl.release"
+
+
+cat >confcache <<\_ACEOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs, see configure's option --config-cache.
+# It is not useful on other systems.  If it contains results you don't
+# want to keep, you may remove or edit it.
+#
+# config.status only pays attention to the cache file if you give it
+# the --recheck option to rerun configure.
+#
+# `ac_cv_env_foo' variables (set or unset) will be overridden when
+# loading this file, other *unset* `ac_cv_foo' will be assigned the
+# following values.
+
+_ACEOF
+
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, we kill variables containing newlines.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(
+  for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do
+    eval ac_val=\$$ac_var
+    case $ac_val in #(
+    *${as_nl}*)
+      case $ac_var in #(
+      *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
+$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
+      esac
+      case $ac_var in #(
+      _ | IFS | as_nl) ;; #(
+      BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
+      *) { eval $ac_var=; unset $ac_var;} ;;
+      esac ;;
+    esac
+  done
+
+  (set) 2>&1 |
+    case $as_nl`(ac_space=' '; set) 2>&1` in #(
+    *${as_nl}ac_space=\ *)
+      # `set' does not quote correctly, so add quotes: double-quote
+      # substitution turns \\\\ into \\, and sed turns \\ into \.
+      sed -n \
+	"s/'/'\\\\''/g;
+	  s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
+      ;; #(
+    *)
+      # `set' quotes correctly as required by POSIX, so do not add quotes.
+      sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
+      ;;
+    esac |
+    sort
+) |
+  sed '
+     /^ac_cv_env_/b end
+     t clear
+     :clear
+     s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
+     t end
+     s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
+     :end' >>confcache
+if diff "$cache_file" confcache >/dev/null 2>&1; then :; else
+  if test -w "$cache_file"; then
+    if test "x$cache_file" != "x/dev/null"; then
+      { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5
+$as_echo "$as_me: updating cache $cache_file" >&6;}
+      if test ! -f "$cache_file" || test -h "$cache_file"; then
+	cat confcache >"$cache_file"
+      else
+        case $cache_file in #(
+        */* | ?:*)
+	  mv -f confcache "$cache_file"$$ &&
+	  mv -f "$cache_file"$$ "$cache_file" ;; #(
+        *)
+	  mv -f confcache "$cache_file" ;;
+	esac
+      fi
+    fi
+  else
+    { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5
+$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;}
+  fi
+fi
+rm -f confcache
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+DEFS=-DHAVE_CONFIG_H
+
+ac_libobjs=
+ac_ltlibobjs=
+U=
+for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
+  # 1. Remove the extension, and $U if already installed.
+  ac_script='s/\$U\././;s/\.o$//;s/\.obj$//'
+  ac_i=`$as_echo "$ac_i" | sed "$ac_script"`
+  # 2. Prepend LIBOBJDIR.  When used with automake>=1.10 LIBOBJDIR
+  #    will be set to the directory where LIBOBJS objects are built.
+  as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext"
+  as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo'
+done
+LIBOBJS=$ac_libobjs
+
+LTLIBOBJS=$ac_ltlibobjs
+
+
+if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then
+  as_fn_error $? "conditional \"MAINTAINER_MODE\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking that generated files are newer than configure" >&5
+$as_echo_n "checking that generated files are newer than configure... " >&6; }
+   if test -n "$am_sleep_pid"; then
+     # Hide warnings about reused PIDs.
+     wait $am_sleep_pid 2>/dev/null
+   fi
+   { $as_echo "$as_me:${as_lineno-$LINENO}: result: done" >&5
+$as_echo "done" >&6; }
+ if test -n "$EXEEXT"; then
+  am__EXEEXT_TRUE=
+  am__EXEEXT_FALSE='#'
+else
+  am__EXEEXT_TRUE='#'
+  am__EXEEXT_FALSE=
+fi
+
+if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then
+  as_fn_error $? "conditional \"AMDEP\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then
+  as_fn_error $? "conditional \"am__fastdepCC\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${CONFIG_USER_TRUE}" && test -z "${CONFIG_USER_FALSE}"; then
+  as_fn_error $? "conditional \"CONFIG_USER\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${CONFIG_KERNEL_TRUE}" && test -z "${CONFIG_KERNEL_FALSE}"; then
+  as_fn_error $? "conditional \"CONFIG_KERNEL\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+
+: "${CONFIG_STATUS=./config.status}"
+ac_write_fail=0
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files $CONFIG_STATUS"
+{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5
+$as_echo "$as_me: creating $CONFIG_STATUS" >&6;}
+as_write_fail=0
+cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1
+#! $SHELL
+# Generated by $as_me.
+# Run this file to recreate the current configuration.
+# Compiler output produced by configure, useful for debugging
+# configure, is in config.log if it exists.
+
+debug=false
+ac_cs_recheck=false
+ac_cs_silent=false
+
+SHELL=\${CONFIG_SHELL-$SHELL}
+export SHELL
+_ASEOF
+cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1
+## -------------------- ##
+## M4sh Initialization. ##
+## -------------------- ##
+
+# Be more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
+  emulate sh
+  NULLCMD=:
+  # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+  setopt NO_GLOB_SUBST
+else
+  case `(set -o) 2>/dev/null` in #(
+  *posix*) :
+    set -o posix ;; #(
+  *) :
+     ;;
+esac
+fi
+
+
+as_nl='
+'
+export as_nl
+# Printing a long string crashes Solaris 7 /usr/bin/printf.
+as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
+# Prefer a ksh shell builtin over an external printf program on Solaris,
+# but without wasting forks for bash or zsh.
+if test -z "$BASH_VERSION$ZSH_VERSION" \
+    && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
+  as_echo='print -r --'
+  as_echo_n='print -rn --'
+elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
+  as_echo='printf %s\n'
+  as_echo_n='printf %s'
+else
+  if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
+    as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
+    as_echo_n='/usr/ucb/echo -n'
+  else
+    as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
+    as_echo_n_body='eval
+      arg=$1;
+      case $arg in #(
+      *"$as_nl"*)
+	expr "X$arg" : "X\\(.*\\)$as_nl";
+	arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
+      esac;
+      expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
+    '
+    export as_echo_n_body
+    as_echo_n='sh -c $as_echo_n_body as_echo'
+  fi
+  export as_echo_body
+  as_echo='sh -c $as_echo_body as_echo'
+fi
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  PATH_SEPARATOR=:
+  (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+    (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+      PATH_SEPARATOR=';'
+  }
+fi
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.  Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+IFS=" ""	$as_nl"
+
+# Find who we are.  Look in the path if we contain no directory separator.
+as_myself=
+case $0 in #((
+  *[\\/]* ) as_myself=$0 ;;
+  *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+  done
+IFS=$as_save_IFS
+
+     ;;
+esac
+# We did not find ourselves, most probably we were run as `sh COMMAND'
+# in which case we are not to be found in the path.
+if test "x$as_myself" = x; then
+  as_myself=$0
+fi
+if test ! -f "$as_myself"; then
+  $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+  exit 1
+fi
+
+# Unset variables that we do not need and which cause bugs (e.g. in
+# pre-3.0 UWIN ksh).  But do not cause bugs in bash 2.01; the "|| exit 1"
+# suppresses any "Segmentation fault" message there.  '((' could
+# trigger a bug in pdksh 5.2.14.
+for as_var in BASH_ENV ENV MAIL MAILPATH
+do eval test x\${$as_var+set} = xset \
+  && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
+done
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# CDPATH.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+
+# as_fn_error STATUS ERROR [LINENO LOG_FD]
+# ----------------------------------------
+# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
+# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
+# script with STATUS, using 1 if that was 0.
+as_fn_error ()
+{
+  as_status=$1; test $as_status -eq 0 && as_status=1
+  if test "$4"; then
+    as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+    $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
+  fi
+  $as_echo "$as_me: error: $2" >&2
+  as_fn_exit $as_status
+} # as_fn_error
+
+
+# as_fn_set_status STATUS
+# -----------------------
+# Set $? to STATUS, without forking.
+as_fn_set_status ()
+{
+  return $1
+} # as_fn_set_status
+
+# as_fn_exit STATUS
+# -----------------
+# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
+as_fn_exit ()
+{
+  set +e
+  as_fn_set_status $1
+  exit $1
+} # as_fn_exit
+
+# as_fn_unset VAR
+# ---------------
+# Portably unset VAR.
+as_fn_unset ()
+{
+  { eval $1=; unset $1;}
+}
+as_unset=as_fn_unset
+# as_fn_append VAR VALUE
+# ----------------------
+# Append the text in VALUE to the end of the definition contained in VAR. Take
+# advantage of any shell optimizations that allow amortized linear growth over
+# repeated appends, instead of the typical quadratic growth present in naive
+# implementations.
+if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
+  eval 'as_fn_append ()
+  {
+    eval $1+=\$2
+  }'
+else
+  as_fn_append ()
+  {
+    eval $1=\$$1\$2
+  }
+fi # as_fn_append
+
+# as_fn_arith ARG...
+# ------------------
+# Perform arithmetic evaluation on the ARGs, and store the result in the
+# global $as_val. Take advantage of shells that can avoid forks. The arguments
+# must be portable across $(()) and expr.
+if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
+  eval 'as_fn_arith ()
+  {
+    as_val=$(( $* ))
+  }'
+else
+  as_fn_arith ()
+  {
+    as_val=`expr "$@" || test $? -eq 1`
+  }
+fi # as_fn_arith
+
+
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+   test "X`expr 00001 : '.*\(...\)'`" = X001; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
+  as_basename=basename
+else
+  as_basename=false
+fi
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+  as_dirname=dirname
+else
+  as_dirname=false
+fi
+
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+	 X"$0" : 'X\(//\)$' \| \
+	 X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X/"$0" |
+    sed '/^.*\/\([^/][^/]*\)\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\/\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\/\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in #(((((
+-n*)
+  case `echo 'xy\c'` in
+  *c*) ECHO_T='	';;	# ECHO_T is single tab character.
+  xy)  ECHO_C='\c';;
+  *)   echo `echo ksh88 bug on AIX 6.1` > /dev/null
+       ECHO_T='	';;
+  esac;;
+*)
+  ECHO_N='-n';;
+esac
+
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+  rm -f conf$$.dir/conf$$.file
+else
+  rm -f conf$$.dir
+  mkdir conf$$.dir 2>/dev/null
+fi
+if (echo >conf$$.file) 2>/dev/null; then
+  if ln -s conf$$.file conf$$ 2>/dev/null; then
+    as_ln_s='ln -s'
+    # ... but there are two gotchas:
+    # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+    # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+    # In both cases, we have to default to `cp -pR'.
+    ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+      as_ln_s='cp -pR'
+  elif ln conf$$.file conf$$ 2>/dev/null; then
+    as_ln_s=ln
+  else
+    as_ln_s='cp -pR'
+  fi
+else
+  as_ln_s='cp -pR'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+
+# as_fn_mkdir_p
+# -------------
+# Create "$as_dir" as a directory, including parents if necessary.
+as_fn_mkdir_p ()
+{
+
+  case $as_dir in #(
+  -*) as_dir=./$as_dir;;
+  esac
+  test -d "$as_dir" || eval $as_mkdir_p || {
+    as_dirs=
+    while :; do
+      case $as_dir in #(
+      *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+      *) as_qdir=$as_dir;;
+      esac
+      as_dirs="'$as_qdir' $as_dirs"
+      as_dir=`$as_dirname -- "$as_dir" ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$as_dir" : 'X\(//\)[^/]' \| \
+	 X"$as_dir" : 'X\(//\)$' \| \
+	 X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_dir" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+      test -d "$as_dir" && break
+    done
+    test -z "$as_dirs" || eval "mkdir $as_dirs"
+  } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"
+
+
+} # as_fn_mkdir_p
+if mkdir -p . 2>/dev/null; then
+  as_mkdir_p='mkdir -p "$as_dir"'
+else
+  test -d ./-p && rmdir ./-p
+  as_mkdir_p=false
+fi
+
+
+# as_fn_executable_p FILE
+# -----------------------
+# Test if FILE is an executable regular file.
+as_fn_executable_p ()
+{
+  test -f "$1" && test -x "$1"
+} # as_fn_executable_p
+as_test_x='test -x'
+as_executable_p=as_fn_executable_p
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+exec 6>&1
+## ----------------------------------- ##
+## Main body of $CONFIG_STATUS script. ##
+## ----------------------------------- ##
+_ASEOF
+test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# Save the log message, to keep $0 and so on meaningful, and to
+# report actual input values of CONFIG_FILES etc. instead of their
+# values after options handling.
+ac_log="
+This file was extended by spl $as_me 0.6.5.6, which was
+generated by GNU Autoconf 2.69.  Invocation command line was
+
+  CONFIG_FILES    = $CONFIG_FILES
+  CONFIG_HEADERS  = $CONFIG_HEADERS
+  CONFIG_LINKS    = $CONFIG_LINKS
+  CONFIG_COMMANDS = $CONFIG_COMMANDS
+  $ $0 $@
+
+on `(hostname || uname -n) 2>/dev/null | sed 1q`
+"
+
+_ACEOF
+
+case $ac_config_files in *"
+"*) set x $ac_config_files; shift; ac_config_files=$*;;
+esac
+
+case $ac_config_headers in *"
+"*) set x $ac_config_headers; shift; ac_config_headers=$*;;
+esac
+
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+# Files that config.status was made for.
+config_files="$ac_config_files"
+config_headers="$ac_config_headers"
+config_commands="$ac_config_commands"
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+ac_cs_usage="\
+\`$as_me' instantiates files and other configuration actions
+from templates according to the current configuration.  Unless the files
+and actions are specified as TAGs, all are instantiated by default.
+
+Usage: $0 [OPTION]... [TAG]...
+
+  -h, --help       print this help, then exit
+  -V, --version    print version number and configuration settings, then exit
+      --config     print configuration, then exit
+  -q, --quiet, --silent
+                   do not print progress messages
+  -d, --debug      don't remove temporary files
+      --recheck    update $as_me by reconfiguring in the same conditions
+      --file=FILE[:TEMPLATE]
+                   instantiate the configuration file FILE
+      --header=FILE[:TEMPLATE]
+                   instantiate the configuration header FILE
+
+Configuration files:
+$config_files
+
+Configuration headers:
+$config_headers
+
+Configuration commands:
+$config_commands
+
+Report bugs to the package provider."
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
+ac_cs_version="\\
+spl config.status 0.6.5.6
+configured by $0, generated by GNU Autoconf 2.69,
+  with options \\"\$ac_cs_config\\"
+
+Copyright (C) 2012 Free Software Foundation, Inc.
+This config.status script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it."
+
+ac_pwd='$ac_pwd'
+srcdir='$srcdir'
+INSTALL='$INSTALL'
+MKDIR_P='$MKDIR_P'
+AWK='$AWK'
+test -n "\$AWK" || AWK=awk
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# The default lists apply if the user does not specify any file.
+ac_need_defaults=:
+while test $# != 0
+do
+  case $1 in
+  --*=?*)
+    ac_option=`expr "X$1" : 'X\([^=]*\)='`
+    ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'`
+    ac_shift=:
+    ;;
+  --*=)
+    ac_option=`expr "X$1" : 'X\([^=]*\)='`
+    ac_optarg=
+    ac_shift=:
+    ;;
+  *)
+    ac_option=$1
+    ac_optarg=$2
+    ac_shift=shift
+    ;;
+  esac
+
+  case $ac_option in
+  # Handling of the options.
+  -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+    ac_cs_recheck=: ;;
+  --version | --versio | --versi | --vers | --ver | --ve | --v | -V )
+    $as_echo "$ac_cs_version"; exit ;;
+  --config | --confi | --conf | --con | --co | --c )
+    $as_echo "$ac_cs_config"; exit ;;
+  --debug | --debu | --deb | --de | --d | -d )
+    debug=: ;;
+  --file | --fil | --fi | --f )
+    $ac_shift
+    case $ac_optarg in
+    *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
+    '') as_fn_error $? "missing file argument" ;;
+    esac
+    as_fn_append CONFIG_FILES " '$ac_optarg'"
+    ac_need_defaults=false;;
+  --header | --heade | --head | --hea )
+    $ac_shift
+    case $ac_optarg in
+    *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
+    esac
+    as_fn_append CONFIG_HEADERS " '$ac_optarg'"
+    ac_need_defaults=false;;
+  --he | --h)
+    # Conflict between --help and --header
+    as_fn_error $? "ambiguous option: \`$1'
+Try \`$0 --help' for more information.";;
+  --help | --hel | -h )
+    $as_echo "$ac_cs_usage"; exit ;;
+  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+  | -silent | --silent | --silen | --sile | --sil | --si | --s)
+    ac_cs_silent=: ;;
+
+  # This is an error.
+  -*) as_fn_error $? "unrecognized option: \`$1'
+Try \`$0 --help' for more information." ;;
+
+  *) as_fn_append ac_config_targets " $1"
+     ac_need_defaults=false ;;
+
+  esac
+  shift
+done
+
+ac_configure_extra_args=
+
+if $ac_cs_silent; then
+  exec 6>/dev/null
+  ac_configure_extra_args="$ac_configure_extra_args --silent"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+if \$ac_cs_recheck; then
+  set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
+  shift
+  \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6
+  CONFIG_SHELL='$SHELL'
+  export CONFIG_SHELL
+  exec "\$@"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+exec 5>>config.log
+{
+  echo
+  sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
+## Running $as_me. ##
+_ASBOX
+  $as_echo "$ac_log"
+} >&5
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+#
+# INIT-COMMANDS
+#
+AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"
+
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+sed_quote_subst='$sed_quote_subst'
+double_quote_subst='$double_quote_subst'
+delay_variable_subst='$delay_variable_subst'
+macro_version='`$ECHO "$macro_version" | $SED "$delay_single_quote_subst"`'
+macro_revision='`$ECHO "$macro_revision" | $SED "$delay_single_quote_subst"`'
+enable_shared='`$ECHO "$enable_shared" | $SED "$delay_single_quote_subst"`'
+enable_static='`$ECHO "$enable_static" | $SED "$delay_single_quote_subst"`'
+pic_mode='`$ECHO "$pic_mode" | $SED "$delay_single_quote_subst"`'
+enable_fast_install='`$ECHO "$enable_fast_install" | $SED "$delay_single_quote_subst"`'
+shared_archive_member_spec='`$ECHO "$shared_archive_member_spec" | $SED "$delay_single_quote_subst"`'
+SHELL='`$ECHO "$SHELL" | $SED "$delay_single_quote_subst"`'
+ECHO='`$ECHO "$ECHO" | $SED "$delay_single_quote_subst"`'
+PATH_SEPARATOR='`$ECHO "$PATH_SEPARATOR" | $SED "$delay_single_quote_subst"`'
+host_alias='`$ECHO "$host_alias" | $SED "$delay_single_quote_subst"`'
+host='`$ECHO "$host" | $SED "$delay_single_quote_subst"`'
+host_os='`$ECHO "$host_os" | $SED "$delay_single_quote_subst"`'
+build_alias='`$ECHO "$build_alias" | $SED "$delay_single_quote_subst"`'
+build='`$ECHO "$build" | $SED "$delay_single_quote_subst"`'
+build_os='`$ECHO "$build_os" | $SED "$delay_single_quote_subst"`'
+SED='`$ECHO "$SED" | $SED "$delay_single_quote_subst"`'
+Xsed='`$ECHO "$Xsed" | $SED "$delay_single_quote_subst"`'
+GREP='`$ECHO "$GREP" | $SED "$delay_single_quote_subst"`'
+EGREP='`$ECHO "$EGREP" | $SED "$delay_single_quote_subst"`'
+FGREP='`$ECHO "$FGREP" | $SED "$delay_single_quote_subst"`'
+LD='`$ECHO "$LD" | $SED "$delay_single_quote_subst"`'
+NM='`$ECHO "$NM" | $SED "$delay_single_quote_subst"`'
+LN_S='`$ECHO "$LN_S" | $SED "$delay_single_quote_subst"`'
+max_cmd_len='`$ECHO "$max_cmd_len" | $SED "$delay_single_quote_subst"`'
+ac_objext='`$ECHO "$ac_objext" | $SED "$delay_single_quote_subst"`'
+exeext='`$ECHO "$exeext" | $SED "$delay_single_quote_subst"`'
+lt_unset='`$ECHO "$lt_unset" | $SED "$delay_single_quote_subst"`'
+lt_SP2NL='`$ECHO "$lt_SP2NL" | $SED "$delay_single_quote_subst"`'
+lt_NL2SP='`$ECHO "$lt_NL2SP" | $SED "$delay_single_quote_subst"`'
+lt_cv_to_host_file_cmd='`$ECHO "$lt_cv_to_host_file_cmd" | $SED "$delay_single_quote_subst"`'
+lt_cv_to_tool_file_cmd='`$ECHO "$lt_cv_to_tool_file_cmd" | $SED "$delay_single_quote_subst"`'
+reload_flag='`$ECHO "$reload_flag" | $SED "$delay_single_quote_subst"`'
+reload_cmds='`$ECHO "$reload_cmds" | $SED "$delay_single_quote_subst"`'
+OBJDUMP='`$ECHO "$OBJDUMP" | $SED "$delay_single_quote_subst"`'
+deplibs_check_method='`$ECHO "$deplibs_check_method" | $SED "$delay_single_quote_subst"`'
+file_magic_cmd='`$ECHO "$file_magic_cmd" | $SED "$delay_single_quote_subst"`'
+file_magic_glob='`$ECHO "$file_magic_glob" | $SED "$delay_single_quote_subst"`'
+want_nocaseglob='`$ECHO "$want_nocaseglob" | $SED "$delay_single_quote_subst"`'
+DLLTOOL='`$ECHO "$DLLTOOL" | $SED "$delay_single_quote_subst"`'
+sharedlib_from_linklib_cmd='`$ECHO "$sharedlib_from_linklib_cmd" | $SED "$delay_single_quote_subst"`'
+AR='`$ECHO "$AR" | $SED "$delay_single_quote_subst"`'
+AR_FLAGS='`$ECHO "$AR_FLAGS" | $SED "$delay_single_quote_subst"`'
+archiver_list_spec='`$ECHO "$archiver_list_spec" | $SED "$delay_single_quote_subst"`'
+STRIP='`$ECHO "$STRIP" | $SED "$delay_single_quote_subst"`'
+RANLIB='`$ECHO "$RANLIB" | $SED "$delay_single_quote_subst"`'
+old_postinstall_cmds='`$ECHO "$old_postinstall_cmds" | $SED "$delay_single_quote_subst"`'
+old_postuninstall_cmds='`$ECHO "$old_postuninstall_cmds" | $SED "$delay_single_quote_subst"`'
+old_archive_cmds='`$ECHO "$old_archive_cmds" | $SED "$delay_single_quote_subst"`'
+lock_old_archive_extraction='`$ECHO "$lock_old_archive_extraction" | $SED "$delay_single_quote_subst"`'
+CC='`$ECHO "$CC" | $SED "$delay_single_quote_subst"`'
+CFLAGS='`$ECHO "$CFLAGS" | $SED "$delay_single_quote_subst"`'
+compiler='`$ECHO "$compiler" | $SED "$delay_single_quote_subst"`'
+GCC='`$ECHO "$GCC" | $SED "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_pipe='`$ECHO "$lt_cv_sys_global_symbol_pipe" | $SED "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_to_cdecl='`$ECHO "$lt_cv_sys_global_symbol_to_cdecl" | $SED "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_to_import='`$ECHO "$lt_cv_sys_global_symbol_to_import" | $SED "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address" | $SED "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $SED "$delay_single_quote_subst"`'
+lt_cv_nm_interface='`$ECHO "$lt_cv_nm_interface" | $SED "$delay_single_quote_subst"`'
+nm_file_list_spec='`$ECHO "$nm_file_list_spec" | $SED "$delay_single_quote_subst"`'
+lt_sysroot='`$ECHO "$lt_sysroot" | $SED "$delay_single_quote_subst"`'
+lt_cv_truncate_bin='`$ECHO "$lt_cv_truncate_bin" | $SED "$delay_single_quote_subst"`'
+objdir='`$ECHO "$objdir" | $SED "$delay_single_quote_subst"`'
+MAGIC_CMD='`$ECHO "$MAGIC_CMD" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_no_builtin_flag='`$ECHO "$lt_prog_compiler_no_builtin_flag" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_pic='`$ECHO "$lt_prog_compiler_pic" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_wl='`$ECHO "$lt_prog_compiler_wl" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_static='`$ECHO "$lt_prog_compiler_static" | $SED "$delay_single_quote_subst"`'
+lt_cv_prog_compiler_c_o='`$ECHO "$lt_cv_prog_compiler_c_o" | $SED "$delay_single_quote_subst"`'
+need_locks='`$ECHO "$need_locks" | $SED "$delay_single_quote_subst"`'
+MANIFEST_TOOL='`$ECHO "$MANIFEST_TOOL" | $SED "$delay_single_quote_subst"`'
+DSYMUTIL='`$ECHO "$DSYMUTIL" | $SED "$delay_single_quote_subst"`'
+NMEDIT='`$ECHO "$NMEDIT" | $SED "$delay_single_quote_subst"`'
+LIPO='`$ECHO "$LIPO" | $SED "$delay_single_quote_subst"`'
+OTOOL='`$ECHO "$OTOOL" | $SED "$delay_single_quote_subst"`'
+OTOOL64='`$ECHO "$OTOOL64" | $SED "$delay_single_quote_subst"`'
+libext='`$ECHO "$libext" | $SED "$delay_single_quote_subst"`'
+shrext_cmds='`$ECHO "$shrext_cmds" | $SED "$delay_single_quote_subst"`'
+extract_expsyms_cmds='`$ECHO "$extract_expsyms_cmds" | $SED "$delay_single_quote_subst"`'
+archive_cmds_need_lc='`$ECHO "$archive_cmds_need_lc" | $SED "$delay_single_quote_subst"`'
+enable_shared_with_static_runtimes='`$ECHO "$enable_shared_with_static_runtimes" | $SED "$delay_single_quote_subst"`'
+export_dynamic_flag_spec='`$ECHO "$export_dynamic_flag_spec" | $SED "$delay_single_quote_subst"`'
+whole_archive_flag_spec='`$ECHO "$whole_archive_flag_spec" | $SED "$delay_single_quote_subst"`'
+compiler_needs_object='`$ECHO "$compiler_needs_object" | $SED "$delay_single_quote_subst"`'
+old_archive_from_new_cmds='`$ECHO "$old_archive_from_new_cmds" | $SED "$delay_single_quote_subst"`'
+old_archive_from_expsyms_cmds='`$ECHO "$old_archive_from_expsyms_cmds" | $SED "$delay_single_quote_subst"`'
+archive_cmds='`$ECHO "$archive_cmds" | $SED "$delay_single_quote_subst"`'
+archive_expsym_cmds='`$ECHO "$archive_expsym_cmds" | $SED "$delay_single_quote_subst"`'
+module_cmds='`$ECHO "$module_cmds" | $SED "$delay_single_quote_subst"`'
+module_expsym_cmds='`$ECHO "$module_expsym_cmds" | $SED "$delay_single_quote_subst"`'
+with_gnu_ld='`$ECHO "$with_gnu_ld" | $SED "$delay_single_quote_subst"`'
+allow_undefined_flag='`$ECHO "$allow_undefined_flag" | $SED "$delay_single_quote_subst"`'
+no_undefined_flag='`$ECHO "$no_undefined_flag" | $SED "$delay_single_quote_subst"`'
+hardcode_libdir_flag_spec='`$ECHO "$hardcode_libdir_flag_spec" | $SED "$delay_single_quote_subst"`'
+hardcode_libdir_separator='`$ECHO "$hardcode_libdir_separator" | $SED "$delay_single_quote_subst"`'
+hardcode_direct='`$ECHO "$hardcode_direct" | $SED "$delay_single_quote_subst"`'
+hardcode_direct_absolute='`$ECHO "$hardcode_direct_absolute" | $SED "$delay_single_quote_subst"`'
+hardcode_minus_L='`$ECHO "$hardcode_minus_L" | $SED "$delay_single_quote_subst"`'
+hardcode_shlibpath_var='`$ECHO "$hardcode_shlibpath_var" | $SED "$delay_single_quote_subst"`'
+hardcode_automatic='`$ECHO "$hardcode_automatic" | $SED "$delay_single_quote_subst"`'
+inherit_rpath='`$ECHO "$inherit_rpath" | $SED "$delay_single_quote_subst"`'
+link_all_deplibs='`$ECHO "$link_all_deplibs" | $SED "$delay_single_quote_subst"`'
+always_export_symbols='`$ECHO "$always_export_symbols" | $SED "$delay_single_quote_subst"`'
+export_symbols_cmds='`$ECHO "$export_symbols_cmds" | $SED "$delay_single_quote_subst"`'
+exclude_expsyms='`$ECHO "$exclude_expsyms" | $SED "$delay_single_quote_subst"`'
+include_expsyms='`$ECHO "$include_expsyms" | $SED "$delay_single_quote_subst"`'
+prelink_cmds='`$ECHO "$prelink_cmds" | $SED "$delay_single_quote_subst"`'
+postlink_cmds='`$ECHO "$postlink_cmds" | $SED "$delay_single_quote_subst"`'
+file_list_spec='`$ECHO "$file_list_spec" | $SED "$delay_single_quote_subst"`'
+variables_saved_for_relink='`$ECHO "$variables_saved_for_relink" | $SED "$delay_single_quote_subst"`'
+need_lib_prefix='`$ECHO "$need_lib_prefix" | $SED "$delay_single_quote_subst"`'
+need_version='`$ECHO "$need_version" | $SED "$delay_single_quote_subst"`'
+version_type='`$ECHO "$version_type" | $SED "$delay_single_quote_subst"`'
+runpath_var='`$ECHO "$runpath_var" | $SED "$delay_single_quote_subst"`'
+shlibpath_var='`$ECHO "$shlibpath_var" | $SED "$delay_single_quote_subst"`'
+shlibpath_overrides_runpath='`$ECHO "$shlibpath_overrides_runpath" | $SED "$delay_single_quote_subst"`'
+libname_spec='`$ECHO "$libname_spec" | $SED "$delay_single_quote_subst"`'
+library_names_spec='`$ECHO "$library_names_spec" | $SED "$delay_single_quote_subst"`'
+soname_spec='`$ECHO "$soname_spec" | $SED "$delay_single_quote_subst"`'
+install_override_mode='`$ECHO "$install_override_mode" | $SED "$delay_single_quote_subst"`'
+postinstall_cmds='`$ECHO "$postinstall_cmds" | $SED "$delay_single_quote_subst"`'
+postuninstall_cmds='`$ECHO "$postuninstall_cmds" | $SED "$delay_single_quote_subst"`'
+finish_cmds='`$ECHO "$finish_cmds" | $SED "$delay_single_quote_subst"`'
+finish_eval='`$ECHO "$finish_eval" | $SED "$delay_single_quote_subst"`'
+hardcode_into_libs='`$ECHO "$hardcode_into_libs" | $SED "$delay_single_quote_subst"`'
+sys_lib_search_path_spec='`$ECHO "$sys_lib_search_path_spec" | $SED "$delay_single_quote_subst"`'
+configure_time_dlsearch_path='`$ECHO "$configure_time_dlsearch_path" | $SED "$delay_single_quote_subst"`'
+configure_time_lt_sys_library_path='`$ECHO "$configure_time_lt_sys_library_path" | $SED "$delay_single_quote_subst"`'
+hardcode_action='`$ECHO "$hardcode_action" | $SED "$delay_single_quote_subst"`'
+enable_dlopen='`$ECHO "$enable_dlopen" | $SED "$delay_single_quote_subst"`'
+enable_dlopen_self='`$ECHO "$enable_dlopen_self" | $SED "$delay_single_quote_subst"`'
+enable_dlopen_self_static='`$ECHO "$enable_dlopen_self_static" | $SED "$delay_single_quote_subst"`'
+old_striplib='`$ECHO "$old_striplib" | $SED "$delay_single_quote_subst"`'
+striplib='`$ECHO "$striplib" | $SED "$delay_single_quote_subst"`'
+
+LTCC='$LTCC'
+LTCFLAGS='$LTCFLAGS'
+compiler='$compiler_DEFAULT'
+
+# A function that is used when there is no print builtin or printf.
+func_fallback_echo ()
+{
+  eval 'cat <<_LTECHO_EOF
+\$1
+_LTECHO_EOF'
+}
+
+# Quote evaled strings.
+for var in SHELL \
+ECHO \
+PATH_SEPARATOR \
+SED \
+GREP \
+EGREP \
+FGREP \
+LD \
+NM \
+LN_S \
+lt_SP2NL \
+lt_NL2SP \
+reload_flag \
+OBJDUMP \
+deplibs_check_method \
+file_magic_cmd \
+file_magic_glob \
+want_nocaseglob \
+DLLTOOL \
+sharedlib_from_linklib_cmd \
+AR \
+AR_FLAGS \
+archiver_list_spec \
+STRIP \
+RANLIB \
+CC \
+CFLAGS \
+compiler \
+lt_cv_sys_global_symbol_pipe \
+lt_cv_sys_global_symbol_to_cdecl \
+lt_cv_sys_global_symbol_to_import \
+lt_cv_sys_global_symbol_to_c_name_address \
+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix \
+lt_cv_nm_interface \
+nm_file_list_spec \
+lt_cv_truncate_bin \
+lt_prog_compiler_no_builtin_flag \
+lt_prog_compiler_pic \
+lt_prog_compiler_wl \
+lt_prog_compiler_static \
+lt_cv_prog_compiler_c_o \
+need_locks \
+MANIFEST_TOOL \
+DSYMUTIL \
+NMEDIT \
+LIPO \
+OTOOL \
+OTOOL64 \
+shrext_cmds \
+export_dynamic_flag_spec \
+whole_archive_flag_spec \
+compiler_needs_object \
+with_gnu_ld \
+allow_undefined_flag \
+no_undefined_flag \
+hardcode_libdir_flag_spec \
+hardcode_libdir_separator \
+exclude_expsyms \
+include_expsyms \
+file_list_spec \
+variables_saved_for_relink \
+libname_spec \
+library_names_spec \
+soname_spec \
+install_override_mode \
+finish_eval \
+old_striplib \
+striplib; do
+    case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in
+    *[\\\\\\\`\\"\\\$]*)
+      eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes
+      ;;
+    *)
+      eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
+      ;;
+    esac
+done
+
+# Double-quote double-evaled strings.
+for var in reload_cmds \
+old_postinstall_cmds \
+old_postuninstall_cmds \
+old_archive_cmds \
+extract_expsyms_cmds \
+old_archive_from_new_cmds \
+old_archive_from_expsyms_cmds \
+archive_cmds \
+archive_expsym_cmds \
+module_cmds \
+module_expsym_cmds \
+export_symbols_cmds \
+prelink_cmds \
+postlink_cmds \
+postinstall_cmds \
+postuninstall_cmds \
+finish_cmds \
+sys_lib_search_path_spec \
+configure_time_dlsearch_path \
+configure_time_lt_sys_library_path; do
+    case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in
+    *[\\\\\\\`\\"\\\$]*)
+      eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes
+      ;;
+    *)
+      eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
+      ;;
+    esac
+done
+
+ac_aux_dir='$ac_aux_dir'
+
+# See if we are running on zsh, and set the options that allow our
+# commands through without removal of \ escapes INIT.
+if test -n "\${ZSH_VERSION+set}"; then
+   setopt NO_GLOB_SUBST
+fi
+
+
+    PACKAGE='$PACKAGE'
+    VERSION='$VERSION'
+    RM='$RM'
+    ofile='$ofile'
+
+
+
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+
+# Handling of arguments.
+for ac_config_target in $ac_config_targets
+do
+  case $ac_config_target in
+    "spl_config.h") CONFIG_HEADERS="$CONFIG_HEADERS spl_config.h" ;;
+    "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;;
+    "libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;;
+    "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
+    "man/Makefile") CONFIG_FILES="$CONFIG_FILES man/Makefile" ;;
+    "man/man1/Makefile") CONFIG_FILES="$CONFIG_FILES man/man1/Makefile" ;;
+    "man/man5/Makefile") CONFIG_FILES="$CONFIG_FILES man/man5/Makefile" ;;
+    "lib/Makefile") CONFIG_FILES="$CONFIG_FILES lib/Makefile" ;;
+    "cmd/Makefile") CONFIG_FILES="$CONFIG_FILES cmd/Makefile" ;;
+    "module/Makefile") CONFIG_FILES="$CONFIG_FILES module/Makefile" ;;
+    "module/spl/Makefile") CONFIG_FILES="$CONFIG_FILES module/spl/Makefile" ;;
+    "module/splat/Makefile") CONFIG_FILES="$CONFIG_FILES module/splat/Makefile" ;;
+    "include/Makefile") CONFIG_FILES="$CONFIG_FILES include/Makefile" ;;
+    "include/fs/Makefile") CONFIG_FILES="$CONFIG_FILES include/fs/Makefile" ;;
+    "include/linux/Makefile") CONFIG_FILES="$CONFIG_FILES include/linux/Makefile" ;;
+    "include/rpc/Makefile") CONFIG_FILES="$CONFIG_FILES include/rpc/Makefile" ;;
+    "include/sharefs/Makefile") CONFIG_FILES="$CONFIG_FILES include/sharefs/Makefile" ;;
+    "include/sys/Makefile") CONFIG_FILES="$CONFIG_FILES include/sys/Makefile" ;;
+    "include/sys/fm/Makefile") CONFIG_FILES="$CONFIG_FILES include/sys/fm/Makefile" ;;
+    "include/sys/fs/Makefile") CONFIG_FILES="$CONFIG_FILES include/sys/fs/Makefile" ;;
+    "include/sys/sysevent/Makefile") CONFIG_FILES="$CONFIG_FILES include/sys/sysevent/Makefile" ;;
+    "include/util/Makefile") CONFIG_FILES="$CONFIG_FILES include/util/Makefile" ;;
+    "include/vm/Makefile") CONFIG_FILES="$CONFIG_FILES include/vm/Makefile" ;;
+    "scripts/Makefile") CONFIG_FILES="$CONFIG_FILES scripts/Makefile" ;;
+    "rpm/Makefile") CONFIG_FILES="$CONFIG_FILES rpm/Makefile" ;;
+    "rpm/redhat/Makefile") CONFIG_FILES="$CONFIG_FILES rpm/redhat/Makefile" ;;
+    "rpm/redhat/spl.spec") CONFIG_FILES="$CONFIG_FILES rpm/redhat/spl.spec" ;;
+    "rpm/redhat/spl-kmod.spec") CONFIG_FILES="$CONFIG_FILES rpm/redhat/spl-kmod.spec" ;;
+    "rpm/redhat/spl-dkms.spec") CONFIG_FILES="$CONFIG_FILES rpm/redhat/spl-dkms.spec" ;;
+    "rpm/generic/Makefile") CONFIG_FILES="$CONFIG_FILES rpm/generic/Makefile" ;;
+    "rpm/generic/spl.spec") CONFIG_FILES="$CONFIG_FILES rpm/generic/spl.spec" ;;
+    "rpm/generic/spl-kmod.spec") CONFIG_FILES="$CONFIG_FILES rpm/generic/spl-kmod.spec" ;;
+    "rpm/generic/spl-dkms.spec") CONFIG_FILES="$CONFIG_FILES rpm/generic/spl-dkms.spec" ;;
+    "spl.release") CONFIG_FILES="$CONFIG_FILES spl.release" ;;
+
+  *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
+  esac
+done
+
+
+# If the user did not use the arguments to specify the items to instantiate,
+# then the envvar interface is used.  Set only those that are not.
+# We use the long form for the default assignment because of an extremely
+# bizarre bug on SunOS 4.1.3.
+if $ac_need_defaults; then
+  test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
+  test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers
+  test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands
+fi
+
+# Have a temporary directory for convenience.  Make it in the build tree
+# simply because there is no reason against having it here, and in addition,
+# creating and moving files from /tmp can sometimes cause problems.
+# Hook for its removal unless debugging.
+# Note that there is a small window in which the directory will not be cleaned:
+# after its creation but before its name has been assigned to `$tmp'.
+$debug ||
+{
+  tmp= ac_tmp=
+  trap 'exit_status=$?
+  : "${ac_tmp:=$tmp}"
+  { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status
+' 0
+  trap 'as_fn_exit 1' 1 2 13 15
+}
+# Create a (secure) tmp directory for tmp files.
+
+{
+  tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` &&
+  test -d "$tmp"
+}  ||
+{
+  tmp=./conf$$-$RANDOM
+  (umask 077 && mkdir "$tmp")
+} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5
+ac_tmp=$tmp
+
+# Set up the scripts for CONFIG_FILES section.
+# No need to generate them if there are no CONFIG_FILES.
+# This happens for instance with `./config.status config.h'.
+if test -n "$CONFIG_FILES"; then
+
+
+ac_cr=`echo X | tr X '\015'`
+# On cygwin, bash can eat \r inside `` if the user requested igncr.
+# But we know of no other shell where ac_cr would be empty at this
+# point, so we can use a bashism as a fallback.
+if test "x$ac_cr" = x; then
+  eval ac_cr=\$\'\\r\'
+fi
+ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' </dev/null 2>/dev/null`
+if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then
+  ac_cs_awk_cr='\\r'
+else
+  ac_cs_awk_cr=$ac_cr
+fi
+
+echo 'BEGIN {' >"$ac_tmp/subs1.awk" &&
+_ACEOF
+
+
+{
+  echo "cat >conf$$subs.awk <<_ACEOF" &&
+  echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' &&
+  echo "_ACEOF"
+} >conf$$subs.sh ||
+  as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
+ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'`
+ac_delim='%!_!# '
+for ac_last_try in false false false false false :; do
+  . ./conf$$subs.sh ||
+    as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
+
+  ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X`
+  if test $ac_delim_n = $ac_delim_num; then
+    break
+  elif $ac_last_try; then
+    as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
+  else
+    ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
+  fi
+done
+rm -f conf$$subs.sh
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK &&
+_ACEOF
+sed -n '
+h
+s/^/S["/; s/!.*/"]=/
+p
+g
+s/^[^!]*!//
+:repl
+t repl
+s/'"$ac_delim"'$//
+t delim
+:nl
+h
+s/\(.\{148\}\)..*/\1/
+t more1
+s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/
+p
+n
+b repl
+:more1
+s/["\\]/\\&/g; s/^/"/; s/$/"\\/
+p
+g
+s/.\{148\}//
+t nl
+:delim
+h
+s/\(.\{148\}\)..*/\1/
+t more2
+s/["\\]/\\&/g; s/^/"/; s/$/"/
+p
+b
+:more2
+s/["\\]/\\&/g; s/^/"/; s/$/"\\/
+p
+g
+s/.\{148\}//
+t delim
+' <conf$$subs.awk | sed '
+/^[^""]/{
+  N
+  s/\n//
+}
+' >>$CONFIG_STATUS || ac_write_fail=1
+rm -f conf$$subs.awk
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+_ACAWK
+cat >>"\$ac_tmp/subs1.awk" <<_ACAWK &&
+  for (key in S) S_is_set[key] = 1
+  FS = ""
+
+}
+{
+  line = $ 0
+  nfields = split(line, field, "@")
+  substed = 0
+  len = length(field[1])
+  for (i = 2; i < nfields; i++) {
+    key = field[i]
+    keylen = length(key)
+    if (S_is_set[key]) {
+      value = S[key]
+      line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3)
+      len += length(value) + length(field[++i])
+      substed = 1
+    } else
+      len += 1 + keylen
+  }
+
+  print line
+}
+
+_ACAWK
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then
+  sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g"
+else
+  cat
+fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \
+  || as_fn_error $? "could not setup config files machinery" "$LINENO" 5
+_ACEOF
+
+# VPATH may cause trouble with some makes, so we remove sole $(srcdir),
+# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and
+# trailing colons and then remove the whole line if VPATH becomes empty
+# (actually we leave an empty line to preserve line numbers).
+if test "x$srcdir" = x.; then
+  ac_vpsub='/^[	 ]*VPATH[	 ]*=[	 ]*/{
+h
+s///
+s/^/:/
+s/[	 ]*$/:/
+s/:\$(srcdir):/:/g
+s/:\${srcdir}:/:/g
+s/:@srcdir@:/:/g
+s/^:*//
+s/:*$//
+x
+s/\(=[	 ]*\).*/\1/
+G
+s/\n//
+s/^[^=]*=[	 ]*$//
+}'
+fi
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+fi # test -n "$CONFIG_FILES"
+
+# Set up the scripts for CONFIG_HEADERS section.
+# No need to generate them if there are no CONFIG_HEADERS.
+# This happens for instance with `./config.status Makefile'.
+if test -n "$CONFIG_HEADERS"; then
+cat >"$ac_tmp/defines.awk" <<\_ACAWK ||
+BEGIN {
+_ACEOF
+
+# Transform confdefs.h into an awk script `defines.awk', embedded as
+# here-document in config.status, that substitutes the proper values into
+# config.h.in to produce config.h.
+
+# Create a delimiter string that does not exist in confdefs.h, to ease
+# handling of long lines.
+ac_delim='%!_!# '
+for ac_last_try in false false :; do
+  ac_tt=`sed -n "/$ac_delim/p" confdefs.h`
+  if test -z "$ac_tt"; then
+    break
+  elif $ac_last_try; then
+    as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5
+  else
+    ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
+  fi
+done
+
+# For the awk script, D is an array of macro values keyed by name,
+# likewise P contains macro parameters if any.  Preserve backslash
+# newline sequences.
+
+ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]*
+sed -n '
+s/.\{148\}/&'"$ac_delim"'/g
+t rset
+:rset
+s/^[	 ]*#[	 ]*define[	 ][	 ]*/ /
+t def
+d
+:def
+s/\\$//
+t bsnl
+s/["\\]/\\&/g
+s/^ \('"$ac_word_re"'\)\(([^()]*)\)[	 ]*\(.*\)/P["\1"]="\2"\
+D["\1"]=" \3"/p
+s/^ \('"$ac_word_re"'\)[	 ]*\(.*\)/D["\1"]=" \2"/p
+d
+:bsnl
+s/["\\]/\\&/g
+s/^ \('"$ac_word_re"'\)\(([^()]*)\)[	 ]*\(.*\)/P["\1"]="\2"\
+D["\1"]=" \3\\\\\\n"\\/p
+t cont
+s/^ \('"$ac_word_re"'\)[	 ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p
+t cont
+d
+:cont
+n
+s/.\{148\}/&'"$ac_delim"'/g
+t clear
+:clear
+s/\\$//
+t bsnlc
+s/["\\]/\\&/g; s/^/"/; s/$/"/p
+d
+:bsnlc
+s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p
+b cont
+' <confdefs.h | sed '
+s/'"$ac_delim"'/"\\\
+"/g' >>$CONFIG_STATUS || ac_write_fail=1
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+  for (key in D) D_is_set[key] = 1
+  FS = ""
+}
+/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ {
+  line = \$ 0
+  split(line, arg, " ")
+  if (arg[1] == "#") {
+    defundef = arg[2]
+    mac1 = arg[3]
+  } else {
+    defundef = substr(arg[1], 2)
+    mac1 = arg[2]
+  }
+  split(mac1, mac2, "(") #)
+  macro = mac2[1]
+  prefix = substr(line, 1, index(line, defundef) - 1)
+  if (D_is_set[macro]) {
+    # Preserve the white space surrounding the "#".
+    print prefix "define", macro P[macro] D[macro]
+    next
+  } else {
+    # Replace #undef with comments.  This is necessary, for example,
+    # in the case of _POSIX_SOURCE, which is predefined and required
+    # on some systems where configure will not decide to define it.
+    if (defundef == "undef") {
+      print "/*", prefix defundef, macro, "*/"
+      next
+    }
+  }
+}
+{ print }
+_ACAWK
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+  as_fn_error $? "could not setup config headers machinery" "$LINENO" 5
+fi # test -n "$CONFIG_HEADERS"
+
+
+eval set X "  :F $CONFIG_FILES  :H $CONFIG_HEADERS    :C $CONFIG_COMMANDS"
+shift
+for ac_tag
+do
+  case $ac_tag in
+  :[FHLC]) ac_mode=$ac_tag; continue;;
+  esac
+  case $ac_mode$ac_tag in
+  :[FHL]*:*);;
+  :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;;
+  :[FH]-) ac_tag=-:-;;
+  :[FH]*) ac_tag=$ac_tag:$ac_tag.in;;
+  esac
+  ac_save_IFS=$IFS
+  IFS=:
+  set x $ac_tag
+  IFS=$ac_save_IFS
+  shift
+  ac_file=$1
+  shift
+
+  case $ac_mode in
+  :L) ac_source=$1;;
+  :[FH])
+    ac_file_inputs=
+    for ac_f
+    do
+      case $ac_f in
+      -) ac_f="$ac_tmp/stdin";;
+      *) # Look for the file first in the build tree, then in the source tree
+	 # (if the path is not absolute).  The absolute path cannot be DOS-style,
+	 # because $ac_f cannot contain `:'.
+	 test -f "$ac_f" ||
+	   case $ac_f in
+	   [\\/$]*) false;;
+	   *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";;
+	   esac ||
+	   as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;;
+      esac
+      case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac
+      as_fn_append ac_file_inputs " '$ac_f'"
+    done
+
+    # Let's still pretend it is `configure' which instantiates (i.e., don't
+    # use $as_me), people would be surprised to read:
+    #    /* config.h.  Generated by config.status.  */
+    configure_input='Generated from '`
+	  $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g'
+	`' by configure.'
+    if test x"$ac_file" != x-; then
+      configure_input="$ac_file.  $configure_input"
+      { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5
+$as_echo "$as_me: creating $ac_file" >&6;}
+    fi
+    # Neutralize special characters interpreted by sed in replacement strings.
+    case $configure_input in #(
+    *\&* | *\|* | *\\* )
+       ac_sed_conf_input=`$as_echo "$configure_input" |
+       sed 's/[\\\\&|]/\\\\&/g'`;; #(
+    *) ac_sed_conf_input=$configure_input;;
+    esac
+
+    case $ac_tag in
+    *:-:* | *:-) cat >"$ac_tmp/stdin" \
+      || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;;
+    esac
+    ;;
+  esac
+
+  ac_dir=`$as_dirname -- "$ac_file" ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$ac_file" : 'X\(//\)[^/]' \| \
+	 X"$ac_file" : 'X\(//\)$' \| \
+	 X"$ac_file" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$ac_file" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+  as_dir="$ac_dir"; as_fn_mkdir_p
+  ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+  ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
+  # A ".." for each directory in $ac_dir_suffix.
+  ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+  case $ac_top_builddir_sub in
+  "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+  *)  ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+  esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+  .)  # We are building in place.
+    ac_srcdir=.
+    ac_top_srcdir=$ac_top_builddir_sub
+    ac_abs_top_srcdir=$ac_pwd ;;
+  [\\/]* | ?:[\\/]* )  # Absolute name.
+    ac_srcdir=$srcdir$ac_dir_suffix;
+    ac_top_srcdir=$srcdir
+    ac_abs_top_srcdir=$srcdir ;;
+  *) # Relative name.
+    ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_build_prefix$srcdir
+    ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+
+  case $ac_mode in
+  :F)
+  #
+  # CONFIG_FILE
+  #
+
+  case $INSTALL in
+  [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;;
+  *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;;
+  esac
+  ac_MKDIR_P=$MKDIR_P
+  case $MKDIR_P in
+  [\\/$]* | ?:[\\/]* ) ;;
+  */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;;
+  esac
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# If the template does not know about datarootdir, expand it.
+# FIXME: This hack should be removed a few years after 2.60.
+ac_datarootdir_hack=; ac_datarootdir_seen=
+ac_sed_dataroot='
+/datarootdir/ {
+  p
+  q
+}
+/@datadir@/p
+/@docdir@/p
+/@infodir@/p
+/@localedir@/p
+/@mandir@/p'
+case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in
+*datarootdir*) ac_datarootdir_seen=yes;;
+*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*)
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5
+$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;}
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+  ac_datarootdir_hack='
+  s&@datadir@&$datadir&g
+  s&@docdir@&$docdir&g
+  s&@infodir@&$infodir&g
+  s&@localedir@&$localedir&g
+  s&@mandir@&$mandir&g
+  s&\\\${datarootdir}&$datarootdir&g' ;;
+esac
+_ACEOF
+
+# Neutralize VPATH when `$srcdir' = `.'.
+# Shell code in configure.ac might set extrasub.
+# FIXME: do we really want to maintain this feature?
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ac_sed_extra="$ac_vpsub
+$extrasub
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+:t
+/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
+s|@configure_input@|$ac_sed_conf_input|;t t
+s&@top_builddir@&$ac_top_builddir_sub&;t t
+s&@top_build_prefix@&$ac_top_build_prefix&;t t
+s&@srcdir@&$ac_srcdir&;t t
+s&@abs_srcdir@&$ac_abs_srcdir&;t t
+s&@top_srcdir@&$ac_top_srcdir&;t t
+s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t
+s&@builddir@&$ac_builddir&;t t
+s&@abs_builddir@&$ac_abs_builddir&;t t
+s&@abs_top_builddir@&$ac_abs_top_builddir&;t t
+s&@INSTALL@&$ac_INSTALL&;t t
+s&@MKDIR_P@&$ac_MKDIR_P&;t t
+$ac_datarootdir_hack
+"
+eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \
+  >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+
+test -z "$ac_datarootdir_hack$ac_datarootdir_seen" &&
+  { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } &&
+  { ac_out=`sed -n '/^[	 ]*datarootdir[	 ]*:*=/p' \
+      "$ac_tmp/out"`; test -z "$ac_out"; } &&
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined.  Please make sure it is defined" >&5
+$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined.  Please make sure it is defined" >&2;}
+
+  rm -f "$ac_tmp/stdin"
+  case $ac_file in
+  -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";;
+  *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";;
+  esac \
+  || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+ ;;
+  :H)
+  #
+  # CONFIG_HEADER
+  #
+  if test x"$ac_file" != x-; then
+    {
+      $as_echo "/* $configure_input  */" \
+      && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs"
+    } >"$ac_tmp/config.h" \
+      || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+    if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then
+      { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5
+$as_echo "$as_me: $ac_file is unchanged" >&6;}
+    else
+      rm -f "$ac_file"
+      mv "$ac_tmp/config.h" "$ac_file" \
+	|| as_fn_error $? "could not create $ac_file" "$LINENO" 5
+    fi
+  else
+    $as_echo "/* $configure_input  */" \
+      && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \
+      || as_fn_error $? "could not create -" "$LINENO" 5
+  fi
+# Compute "$ac_file"'s index in $config_headers.
+_am_arg="$ac_file"
+_am_stamp_count=1
+for _am_header in $config_headers :; do
+  case $_am_header in
+    $_am_arg | $_am_arg:* )
+      break ;;
+    * )
+      _am_stamp_count=`expr $_am_stamp_count + 1` ;;
+  esac
+done
+echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" ||
+$as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$_am_arg" : 'X\(//\)[^/]' \| \
+	 X"$_am_arg" : 'X\(//\)$' \| \
+	 X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$_am_arg" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`/stamp-h$_am_stamp_count
+ ;;
+
+  :C)  { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5
+$as_echo "$as_me: executing $ac_file commands" >&6;}
+ ;;
+  esac
+
+
+  case $ac_file$ac_mode in
+    "spl_config.h":H)
+	(mv spl_config.h spl_config.h.tmp &&
+	awk -f ${ac_srcdir}/config/config.awk spl_config.h.tmp >spl_config.h &&
+	rm spl_config.h.tmp) || exit 1 ;;
+    "depfiles":C) test x"$AMDEP_TRUE" != x"" || {
+  # Older Autoconf quotes --file arguments for eval, but not when files
+  # are listed without --file.  Let's play safe and only enable the eval
+  # if we detect the quoting.
+  case $CONFIG_FILES in
+  *\'*) eval set x "$CONFIG_FILES" ;;
+  *)   set x $CONFIG_FILES ;;
+  esac
+  shift
+  for mf
+  do
+    # Strip MF so we end up with the name of the file.
+    mf=`echo "$mf" | sed -e 's/:.*$//'`
+    # Check whether this is an Automake generated Makefile or not.
+    # We used to match only the files named 'Makefile.in', but
+    # some people rename them; so instead we look at the file content.
+    # Grep'ing the first line is not enough: some people post-process
+    # each Makefile.in and add a new line on top of each file to say so.
+    # Grep'ing the whole file is not good either: AIX grep has a line
+    # limit of 2048, but all sed's we know have understand at least 4000.
+    if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then
+      dirpart=`$as_dirname -- "$mf" ||
+$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$mf" : 'X\(//\)[^/]' \| \
+	 X"$mf" : 'X\(//\)$' \| \
+	 X"$mf" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$mf" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+    else
+      continue
+    fi
+    # Extract the definition of DEPDIR, am__include, and am__quote
+    # from the Makefile without running 'make'.
+    DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"`
+    test -z "$DEPDIR" && continue
+    am__include=`sed -n 's/^am__include = //p' < "$mf"`
+    test -z "$am__include" && continue
+    am__quote=`sed -n 's/^am__quote = //p' < "$mf"`
+    # Find all dependency output files, they are included files with
+    # $(DEPDIR) in their names.  We invoke sed twice because it is the
+    # simplest approach to changing $(DEPDIR) to its actual value in the
+    # expansion.
+    for file in `sed -n "
+      s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \
+	 sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do
+      # Make sure the directory exists.
+      test -f "$dirpart/$file" && continue
+      fdir=`$as_dirname -- "$file" ||
+$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$file" : 'X\(//\)[^/]' \| \
+	 X"$file" : 'X\(//\)$' \| \
+	 X"$file" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$file" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+      as_dir=$dirpart/$fdir; as_fn_mkdir_p
+      # echo "creating $dirpart/$file"
+      echo '# dummy' > "$dirpart/$file"
+    done
+  done
+}
+ ;;
+    "libtool":C)
+
+    # See if we are running on zsh, and set the options that allow our
+    # commands through without removal of \ escapes.
+    if test -n "${ZSH_VERSION+set}"; then
+      setopt NO_GLOB_SUBST
+    fi
+
+    cfgfile=${ofile}T
+    trap "$RM \"$cfgfile\"; exit 1" 1 2 15
+    $RM "$cfgfile"
+
+    cat <<_LT_EOF >> "$cfgfile"
+#! $SHELL
+# Generated automatically by $as_me ($PACKAGE) $VERSION
+# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+# NOTE: Changes made to this file will be lost: look at ltmain.sh.
+
+# Provide generalized library-building support services.
+# Written by Gordon Matzigkeit, 1996
+
+# Copyright (C) 2014 Free Software Foundation, Inc.
+# This is free software; see the source for copying conditions.  There is NO
+# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+# GNU Libtool is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of of the License, or
+# (at your option) any later version.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program or library that is built
+# using GNU Libtool, you may include this file under the  same
+# distribution terms that you use for the rest of that program.
+#
+# GNU Libtool is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+
+# The names of the tagged configurations supported by this script.
+available_tags=''
+
+# Configured defaults for sys_lib_dlsearch_path munging.
+: \${LT_SYS_LIBRARY_PATH="$configure_time_lt_sys_library_path"}
+
+# ### BEGIN LIBTOOL CONFIG
+
+# Which release of libtool.m4 was used?
+macro_version=$macro_version
+macro_revision=$macro_revision
+
+# Whether or not to build shared libraries.
+build_libtool_libs=$enable_shared
+
+# Whether or not to build static libraries.
+build_old_libs=$enable_static
+
+# What type of objects to build.
+pic_mode=$pic_mode
+
+# Whether or not to optimize for fast installation.
+fast_install=$enable_fast_install
+
+# Shared archive member basename,for filename based shared library versioning on AIX.
+shared_archive_member_spec=$shared_archive_member_spec
+
+# Shell to use when invoking shell scripts.
+SHELL=$lt_SHELL
+
+# An echo program that protects backslashes.
+ECHO=$lt_ECHO
+
+# The PATH separator for the build system.
+PATH_SEPARATOR=$lt_PATH_SEPARATOR
+
+# The host system.
+host_alias=$host_alias
+host=$host
+host_os=$host_os
+
+# The build system.
+build_alias=$build_alias
+build=$build
+build_os=$build_os
+
+# A sed program that does not truncate output.
+SED=$lt_SED
+
+# Sed that helps us avoid accidentally triggering echo(1) options like -n.
+Xsed="\$SED -e 1s/^X//"
+
+# A grep program that handles long lines.
+GREP=$lt_GREP
+
+# An ERE matcher.
+EGREP=$lt_EGREP
+
+# A literal string matcher.
+FGREP=$lt_FGREP
+
+# A BSD- or MS-compatible name lister.
+NM=$lt_NM
+
+# Whether we need soft or hard links.
+LN_S=$lt_LN_S
+
+# What is the maximum length of a command?
+max_cmd_len=$max_cmd_len
+
+# Object file suffix (normally "o").
+objext=$ac_objext
+
+# Executable file suffix (normally "").
+exeext=$exeext
+
+# whether the shell understands "unset".
+lt_unset=$lt_unset
+
+# turn spaces into newlines.
+SP2NL=$lt_lt_SP2NL
+
+# turn newlines into spaces.
+NL2SP=$lt_lt_NL2SP
+
+# convert \$build file names to \$host format.
+to_host_file_cmd=$lt_cv_to_host_file_cmd
+
+# convert \$build files to toolchain format.
+to_tool_file_cmd=$lt_cv_to_tool_file_cmd
+
+# An object symbol dumper.
+OBJDUMP=$lt_OBJDUMP
+
+# Method to check whether dependent libraries are shared objects.
+deplibs_check_method=$lt_deplibs_check_method
+
+# Command to use when deplibs_check_method = "file_magic".
+file_magic_cmd=$lt_file_magic_cmd
+
+# How to find potential files when deplibs_check_method = "file_magic".
+file_magic_glob=$lt_file_magic_glob
+
+# Find potential files using nocaseglob when deplibs_check_method = "file_magic".
+want_nocaseglob=$lt_want_nocaseglob
+
+# DLL creation program.
+DLLTOOL=$lt_DLLTOOL
+
+# Command to associate shared and link libraries.
+sharedlib_from_linklib_cmd=$lt_sharedlib_from_linklib_cmd
+
+# The archiver.
+AR=$lt_AR
+
+# Flags to create an archive.
+AR_FLAGS=$lt_AR_FLAGS
+
+# How to feed a file listing to the archiver.
+archiver_list_spec=$lt_archiver_list_spec
+
+# A symbol stripping program.
+STRIP=$lt_STRIP
+
+# Commands used to install an old-style archive.
+RANLIB=$lt_RANLIB
+old_postinstall_cmds=$lt_old_postinstall_cmds
+old_postuninstall_cmds=$lt_old_postuninstall_cmds
+
+# Whether to use a lock for old archive extraction.
+lock_old_archive_extraction=$lock_old_archive_extraction
+
+# A C compiler.
+LTCC=$lt_CC
+
+# LTCC compiler flags.
+LTCFLAGS=$lt_CFLAGS
+
+# Take the output of nm and produce a listing of raw symbols and C names.
+global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe
+
+# Transform the output of nm in a proper C declaration.
+global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl
+
+# Transform the output of nm into a list of symbols to manually relocate.
+global_symbol_to_import=$lt_lt_cv_sys_global_symbol_to_import
+
+# Transform the output of nm in a C name address pair.
+global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address
+
+# Transform the output of nm in a C name address pair when lib prefix is needed.
+global_symbol_to_c_name_address_lib_prefix=$lt_lt_cv_sys_global_symbol_to_c_name_address_lib_prefix
+
+# The name lister interface.
+nm_interface=$lt_lt_cv_nm_interface
+
+# Specify filename containing input files for \$NM.
+nm_file_list_spec=$lt_nm_file_list_spec
+
+# The root where to search for dependent libraries,and where our libraries should be installed.
+lt_sysroot=$lt_sysroot
+
+# Command to truncate a binary pipe.
+lt_truncate_bin=$lt_lt_cv_truncate_bin
+
+# The name of the directory that contains temporary libtool files.
+objdir=$objdir
+
+# Used to examine libraries when file_magic_cmd begins with "file".
+MAGIC_CMD=$MAGIC_CMD
+
+# Must we lock files when doing compilation?
+need_locks=$lt_need_locks
+
+# Manifest tool.
+MANIFEST_TOOL=$lt_MANIFEST_TOOL
+
+# Tool to manipulate archived DWARF debug symbol files on Mac OS X.
+DSYMUTIL=$lt_DSYMUTIL
+
+# Tool to change global to local symbols on Mac OS X.
+NMEDIT=$lt_NMEDIT
+
+# Tool to manipulate fat objects and archives on Mac OS X.
+LIPO=$lt_LIPO
+
+# ldd/readelf like tool for Mach-O binaries on Mac OS X.
+OTOOL=$lt_OTOOL
+
+# ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4.
+OTOOL64=$lt_OTOOL64
+
+# Old archive suffix (normally "a").
+libext=$libext
+
+# Shared library suffix (normally ".so").
+shrext_cmds=$lt_shrext_cmds
+
+# The commands to extract the exported symbol list from a shared archive.
+extract_expsyms_cmds=$lt_extract_expsyms_cmds
+
+# Variables whose values should be saved in libtool wrapper scripts and
+# restored at link time.
+variables_saved_for_relink=$lt_variables_saved_for_relink
+
+# Do we need the "lib" prefix for modules?
+need_lib_prefix=$need_lib_prefix
+
+# Do we need a version for libraries?
+need_version=$need_version
+
+# Library versioning type.
+version_type=$version_type
+
+# Shared library runtime path variable.
+runpath_var=$runpath_var
+
+# Shared library path variable.
+shlibpath_var=$shlibpath_var
+
+# Is shlibpath searched before the hard-coded library search path?
+shlibpath_overrides_runpath=$shlibpath_overrides_runpath
+
+# Format of library name prefix.
+libname_spec=$lt_libname_spec
+
+# List of archive names.  First name is the real one, the rest are links.
+# The last name is the one that the linker finds with -lNAME
+library_names_spec=$lt_library_names_spec
+
+# The coded name of the library, if different from the real name.
+soname_spec=$lt_soname_spec
+
+# Permission mode override for installation of shared libraries.
+install_override_mode=$lt_install_override_mode
+
+# Command to use after installation of a shared archive.
+postinstall_cmds=$lt_postinstall_cmds
+
+# Command to use after uninstallation of a shared archive.
+postuninstall_cmds=$lt_postuninstall_cmds
+
+# Commands used to finish a libtool library installation in a directory.
+finish_cmds=$lt_finish_cmds
+
+# As "finish_cmds", except a single script fragment to be evaled but
+# not shown.
+finish_eval=$lt_finish_eval
+
+# Whether we should hardcode library paths into libraries.
+hardcode_into_libs=$hardcode_into_libs
+
+# Compile-time system search path for libraries.
+sys_lib_search_path_spec=$lt_sys_lib_search_path_spec
+
+# Detected run-time system search path for libraries.
+sys_lib_dlsearch_path_spec=$lt_configure_time_dlsearch_path
+
+# Explicit LT_SYS_LIBRARY_PATH set during ./configure time.
+configure_time_lt_sys_library_path=$lt_configure_time_lt_sys_library_path
+
+# Whether dlopen is supported.
+dlopen_support=$enable_dlopen
+
+# Whether dlopen of programs is supported.
+dlopen_self=$enable_dlopen_self
+
+# Whether dlopen of statically linked programs is supported.
+dlopen_self_static=$enable_dlopen_self_static
+
+# Commands to strip libraries.
+old_striplib=$lt_old_striplib
+striplib=$lt_striplib
+
+
+# The linker used to build libraries.
+LD=$lt_LD
+
+# How to create reloadable object files.
+reload_flag=$lt_reload_flag
+reload_cmds=$lt_reload_cmds
+
+# Commands used to build an old-style archive.
+old_archive_cmds=$lt_old_archive_cmds
+
+# A language specific compiler.
+CC=$lt_compiler
+
+# Is the compiler the GNU compiler?
+with_gcc=$GCC
+
+# Compiler flag to turn off builtin functions.
+no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag
+
+# Additional compiler flags for building library objects.
+pic_flag=$lt_lt_prog_compiler_pic
+
+# How to pass a linker flag through the compiler.
+wl=$lt_lt_prog_compiler_wl
+
+# Compiler flag to prevent dynamic linking.
+link_static_flag=$lt_lt_prog_compiler_static
+
+# Does compiler simultaneously support -c and -o options?
+compiler_c_o=$lt_lt_cv_prog_compiler_c_o
+
+# Whether or not to add -lc for building shared libraries.
+build_libtool_need_lc=$archive_cmds_need_lc
+
+# Whether or not to disallow shared libs when runtime libs are static.
+allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes
+
+# Compiler flag to allow reflexive dlopens.
+export_dynamic_flag_spec=$lt_export_dynamic_flag_spec
+
+# Compiler flag to generate shared objects directly from archives.
+whole_archive_flag_spec=$lt_whole_archive_flag_spec
+
+# Whether the compiler copes with passing no objects directly.
+compiler_needs_object=$lt_compiler_needs_object
+
+# Create an old-style archive from a shared archive.
+old_archive_from_new_cmds=$lt_old_archive_from_new_cmds
+
+# Create a temporary old-style archive to link instead of a shared archive.
+old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds
+
+# Commands used to build a shared archive.
+archive_cmds=$lt_archive_cmds
+archive_expsym_cmds=$lt_archive_expsym_cmds
+
+# Commands used to build a loadable module if different from building
+# a shared archive.
+module_cmds=$lt_module_cmds
+module_expsym_cmds=$lt_module_expsym_cmds
+
+# Whether we are building with GNU ld or not.
+with_gnu_ld=$lt_with_gnu_ld
+
+# Flag that allows shared libraries with undefined symbols to be built.
+allow_undefined_flag=$lt_allow_undefined_flag
+
+# Flag that enforces no undefined symbols.
+no_undefined_flag=$lt_no_undefined_flag
+
+# Flag to hardcode \$libdir into a binary during linking.
+# This must work even if \$libdir does not exist
+hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec
+
+# Whether we need a single "-rpath" flag with a separated argument.
+hardcode_libdir_separator=$lt_hardcode_libdir_separator
+
+# Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes
+# DIR into the resulting binary.
+hardcode_direct=$hardcode_direct
+
+# Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes
+# DIR into the resulting binary and the resulting library dependency is
+# "absolute",i.e impossible to change by setting \$shlibpath_var if the
+# library is relocated.
+hardcode_direct_absolute=$hardcode_direct_absolute
+
+# Set to "yes" if using the -LDIR flag during linking hardcodes DIR
+# into the resulting binary.
+hardcode_minus_L=$hardcode_minus_L
+
+# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR
+# into the resulting binary.
+hardcode_shlibpath_var=$hardcode_shlibpath_var
+
+# Set to "yes" if building a shared library automatically hardcodes DIR
+# into the library and all subsequent libraries and executables linked
+# against it.
+hardcode_automatic=$hardcode_automatic
+
+# Set to yes if linker adds runtime paths of dependent libraries
+# to runtime path list.
+inherit_rpath=$inherit_rpath
+
+# Whether libtool must link a program against all its dependency libraries.
+link_all_deplibs=$link_all_deplibs
+
+# Set to "yes" if exported symbols are required.
+always_export_symbols=$always_export_symbols
+
+# The commands to list exported symbols.
+export_symbols_cmds=$lt_export_symbols_cmds
+
+# Symbols that should not be listed in the preloaded symbols.
+exclude_expsyms=$lt_exclude_expsyms
+
+# Symbols that must always be exported.
+include_expsyms=$lt_include_expsyms
+
+# Commands necessary for linking programs (against libraries) with templates.
+prelink_cmds=$lt_prelink_cmds
+
+# Commands necessary for finishing linking programs.
+postlink_cmds=$lt_postlink_cmds
+
+# Specify filename containing input files.
+file_list_spec=$lt_file_list_spec
+
+# How to hardcode a shared library path into an executable.
+hardcode_action=$hardcode_action
+
+# ### END LIBTOOL CONFIG
+
+_LT_EOF
+
+    cat <<'_LT_EOF' >> "$cfgfile"
+
+# ### BEGIN FUNCTIONS SHARED WITH CONFIGURE
+
+# func_munge_path_list VARIABLE PATH
+# -----------------------------------
+# VARIABLE is name of variable containing _space_ separated list of
+# directories to be munged by the contents of PATH, which is string
+# having a format:
+# "DIR[:DIR]:"
+#       string "DIR[ DIR]" will be prepended to VARIABLE
+# ":DIR[:DIR]"
+#       string "DIR[ DIR]" will be appended to VARIABLE
+# "DIRP[:DIRP]::[DIRA:]DIRA"
+#       string "DIRP[ DIRP]" will be prepended to VARIABLE and string
+#       "DIRA[ DIRA]" will be appended to VARIABLE
+# "DIR[:DIR]"
+#       VARIABLE will be replaced by "DIR[ DIR]"
+func_munge_path_list ()
+{
+    case x$2 in
+    x)
+        ;;
+    *:)
+        eval $1=\"`$ECHO $2 | $SED 's/:/ /g'` \$$1\"
+        ;;
+    x:*)
+        eval $1=\"\$$1 `$ECHO $2 | $SED 's/:/ /g'`\"
+        ;;
+    *::*)
+        eval $1=\"\$$1\ `$ECHO $2 | $SED -e 's/.*:://' -e 's/:/ /g'`\"
+        eval $1=\"`$ECHO $2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \$$1\"
+        ;;
+    *)
+        eval $1=\"`$ECHO $2 | $SED 's/:/ /g'`\"
+        ;;
+    esac
+}
+
+
+# Calculate cc_basename.  Skip known compiler wrappers and cross-prefix.
+func_cc_basename ()
+{
+    for cc_temp in $*""; do
+      case $cc_temp in
+        compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
+        distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
+        \-*) ;;
+        *) break;;
+      esac
+    done
+    func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"`
+}
+
+
+# ### END FUNCTIONS SHARED WITH CONFIGURE
+
+_LT_EOF
+
+  case $host_os in
+  aix3*)
+    cat <<\_LT_EOF >> "$cfgfile"
+# AIX sometimes has problems with the GCC collect2 program.  For some
+# reason, if we set the COLLECT_NAMES environment variable, the problems
+# vanish in a puff of smoke.
+if test set != "${COLLECT_NAMES+set}"; then
+  COLLECT_NAMES=
+  export COLLECT_NAMES
+fi
+_LT_EOF
+    ;;
+  esac
+
+
+ltmain=$ac_aux_dir/ltmain.sh
+
+
+  # We use sed instead of cat because bash on DJGPP gets confused if
+  # if finds mixed CR/LF and LF-only lines.  Since sed operates in
+  # text mode, it properly converts lines to CR/LF.  This bash problem
+  # is reportedly fixed, but why not run on old versions too?
+  sed '$q' "$ltmain" >> "$cfgfile" \
+     || (rm -f "$cfgfile"; exit 1)
+
+   mv -f "$cfgfile" "$ofile" ||
+    (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile")
+  chmod +x "$ofile"
+
+ ;;
+
+  esac
+done # for ac_tag
+
+
+as_fn_exit 0
+_ACEOF
+ac_clean_files=$ac_clean_files_save
+
+test $ac_write_fail = 0 ||
+  as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5
+
+
+# configure is writing to config.log, and then calls config.status.
+# config.status does its own redirection, appending to config.log.
+# Unfortunately, on DOS this fails, as config.log is still kept open
+# by configure, so config.status won't be able to write to it; its
+# output is simply discarded.  So we exec the FD to /dev/null,
+# effectively closing config.log, so it can be properly (re)opened and
+# appended to by config.status.  When coming back to configure, we
+# need to make the FD available again.
+if test "$no_create" != yes; then
+  ac_cs_success=:
+  ac_config_status_args=
+  test "$silent" = yes &&
+    ac_config_status_args="$ac_config_status_args --quiet"
+  exec 5>/dev/null
+  $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
+  exec 5>>config.log
+  # Use ||, not &&, to avoid exiting from the if with $? = 1, which
+  # would make configure fail if this is the last instruction.
+  $ac_cs_success || as_fn_exit 1
+fi
+if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5
+$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;}
+fi
+
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/configure.ac
@@ -0,0 +1,84 @@
+###############################################################################
+# SPL AutoConf Configuration
+###############################################################################
+# Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+# Copyright (C) 2007 The Regents of the University of California.
+# Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+# Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+# UCRL-CODE-235197
+#
+# This file is part of the SPL, Solaris Porting Layer.
+# For details, see <http://zfsonlinux.org/>.
+#
+# The SPL is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 2 of the License, or (at your
+# option) any later version.
+#
+# The SPL is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+###############################################################################
+
+AC_INIT(m4_esyscmd(grep Name META | cut -d ':' -f 2 | tr -d ' \n'),
+	m4_esyscmd(grep Version META | cut -d ':' -f 2 | tr -d ' \n'))
+AC_LANG(C)
+SPL_AC_META
+AC_CONFIG_AUX_DIR([config])
+AC_CONFIG_MACRO_DIR([config])
+AC_CANONICAL_SYSTEM
+AM_MAINTAINER_MODE
+m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
+AM_INIT_AUTOMAKE
+AC_CONFIG_HEADERS([spl_config.h], [
+	(mv spl_config.h spl_config.h.tmp &&
+	awk -f ${ac_srcdir}/config/config.awk spl_config.h.tmp >spl_config.h &&
+	rm spl_config.h.tmp) || exit 1])
+
+AC_PROG_INSTALL
+AC_PROG_CC
+AC_PROG_LIBTOOL
+
+SPL_AC_LICENSE
+SPL_AC_PACKAGE
+SPL_AC_CONFIG
+
+AC_CONFIG_FILES([
+	Makefile
+	man/Makefile
+	man/man1/Makefile
+	man/man5/Makefile
+	lib/Makefile
+	cmd/Makefile
+	module/Makefile
+	module/spl/Makefile
+	module/splat/Makefile
+	include/Makefile
+	include/fs/Makefile
+	include/linux/Makefile
+	include/rpc/Makefile
+	include/sharefs/Makefile
+	include/sys/Makefile
+	include/sys/fm/Makefile
+	include/sys/fs/Makefile
+	include/sys/sysevent/Makefile
+	include/util/Makefile
+	include/vm/Makefile
+	scripts/Makefile
+	rpm/Makefile
+	rpm/redhat/Makefile
+	rpm/redhat/spl.spec
+	rpm/redhat/spl-kmod.spec
+	rpm/redhat/spl-dkms.spec
+	rpm/generic/Makefile
+	rpm/generic/spl.spec
+	rpm/generic/spl-kmod.spec
+	rpm/generic/spl-dkms.spec
+	spl.release
+])
+
+AC_OUTPUT
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/copy-builtin
@@ -0,0 +1,126 @@
+#!/bin/bash
+
+set -e
+
+usage()
+{
+	echo "usage: $0 <kernel source tree>" >&2
+	exit 1
+}
+
+[ "$#" -eq 1 ] || usage
+KERNEL_DIR="$(readlink --canonicalize-existing "$1")"
+
+MODULES=()
+for MODULE_DIR in module/*
+do
+	[ -d "$MODULE_DIR" ] || continue
+	MODULES+=("${MODULE_DIR##*/}")
+done
+
+if ! [ -e 'spl_config.h' ]
+then
+	echo >&2
+	echo "    $0: you did not run configure, or you're not in the SPL source directory." >&2
+	echo "    $0: run configure with --with-linux=$KERNEL_DIR and --enable-linux-builtin." >&2
+	echo >&2
+	exit 1
+fi
+
+make clean || true
+
+rm -rf "$KERNEL_DIR/include/spl" "$KERNEL_DIR/spl"
+cp --recursive include "$KERNEL_DIR/include/spl"
+cp --recursive module "$KERNEL_DIR/spl"
+cp spl_config.h "$KERNEL_DIR/"
+cp spl.release.in "$KERNEL_DIR/"
+
+adjust_obj_paths()
+{
+	local FILE="$1"
+	local LINE OBJPATH
+
+	while IFS='' read -r LINE
+	do
+		OBJPATH="${LINE#\$(MODULE)-objs += }"
+		if [ "$OBJPATH" = "$LINE" ]
+		then
+			echo "$LINE"
+		else
+			echo "\$(MODULE)-objs += ${OBJPATH##*/}"
+		fi
+	done < "$FILE" > "$FILE.new"
+	mv "$FILE.new" "$FILE"
+}
+
+for MODULE in "${MODULES[@]}"
+do
+	adjust_obj_paths "$KERNEL_DIR/spl/$MODULE/Makefile"
+	sed -i.bak '/obj =/d' "$KERNEL_DIR/spl/$MODULE/Makefile"
+	sed -i.bak '/src =/d' "$KERNEL_DIR/spl/$MODULE/Makefile"
+done
+
+cat > "$KERNEL_DIR/spl/Kconfig" <<"EOF"
+config SPL
+	tristate "Solaris Porting Layer (SPL)"
+	help
+	  This is the SPL library from the ZFS On Linux project.
+
+	  See http://zfsonlinux.org/
+
+	  To compile this library as a module, choose M here.
+
+	  If unsure, say N.
+EOF
+
+{
+	cat <<-"EOF"
+	SPL_MODULE_CFLAGS  = -I$(srctree)/include/spl
+	SPL_MODULE_CFLAGS += -include $(srctree)/spl_config.h
+	export SPL_MODULE_CFLAGS
+
+	obj-$(CONFIG_SPL) :=
+	EOF
+
+	for MODULE in "${MODULES[@]}"
+	do
+		echo 'obj-$(CONFIG_SPL) += ' "$MODULE/"
+	done
+} > "$KERNEL_DIR/spl/Kbuild"
+
+add_after()
+{
+	local FILE="$1"
+	local MARKER="$2"
+	local NEW="$3"
+	local LINE
+
+	while IFS='' read -r LINE
+	do
+		echo "$LINE"
+
+		if [ -n "$MARKER" -a "$LINE" = "$MARKER" ]
+		then
+			echo "$NEW"
+			MARKER=''
+			if IFS='' read -r LINE
+			then
+				[ "$LINE" != "$NEW" ] && echo "$LINE"
+			fi
+		fi
+	done < "$FILE" > "$FILE.new"
+
+	mv "$FILE.new" "$FILE"
+}
+
+add_after "$KERNEL_DIR/Kconfig" 'source "arch/$SRCARCH/Kconfig"' 'source "spl/Kconfig"'
+# We must take care to build SPL before ZFS, otherwise the symbols required
+# to link ZFS will not be available.
+sed -i 's~mm/ fs/~mm/ spl/ fs/~' "$KERNEL_DIR/Makefile"
+
+echo >&2
+echo "    $0: done." >&2
+echo "    $0: now you can build the kernel with SPL support." >&2
+echo "    $0: make sure you enable SPL support (CONFIG_SPL) before building." >&2
+echo >&2
+
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/cp
@@ -0,0 +1,2 @@
+#!/bin/sh
+cp "$@"
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/dkms.conf
@@ -0,0 +1,35 @@
+AUTOINSTALL="yes"
+PACKAGE_NAME="spl"
+PACKAGE_VERSION="0.6.5.6"
+PRE_BUILD="configure
+  --prefix=/usr
+  --with-config=kernel
+  --with-linux=$(case `lsb_release -is` in
+                   (Debian)
+                     if [ -e ${kernel_source_dir/%build/source} ]
+                     then
+                       echo ${kernel_source_dir/%build/source}
+                     else
+                       # This is a kpkg exception for Proxmox 2.0
+		       echo ${kernel_source_dir}
+                     fi
+                     ;;
+                   (*)
+                     echo ${kernel_source_dir}
+                     ;;
+                 esac)
+  --with-linux-obj=${kernel_source_dir}
+"
+POST_INSTALL="cp
+  ${dkms_tree}/${PACKAGE_NAME}/${PACKAGE_VERSION}/build/spl_config.h
+  ${dkms_tree}/${PACKAGE_NAME}/${PACKAGE_VERSION}/build/module/Module.symvers
+  ${dkms_tree}/${PACKAGE_NAME}/${PACKAGE_VERSION}/${kernelver}/${arch}/
+"
+REMAKE_INITRD="no"
+MAKE[0]="make"
+BUILT_MODULE_NAME[0]="spl"
+BUILT_MODULE_LOCATION[0]="module/spl/"
+DEST_MODULE_LOCATION[0]="/extra/spl/spl"
+BUILT_MODULE_NAME[1]="splat"
+BUILT_MODULE_LOCATION[1]="module/splat/"
+DEST_MODULE_LOCATION[1]="/extra/splat/splat"
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/Makefile.am
@@ -0,0 +1,18 @@
+SUBDIRS = fs linux rpc sharefs sys util vm
+
+COMMON_H =
+
+KERNEL_H = \
+	$(top_srcdir)/include/splat-ctl.h \
+	$(top_srcdir)/include/spl-ctl.h \
+	$(top_srcdir)/include/strings.h \
+	$(top_srcdir)/include/unistd.h
+
+USER_H =
+
+EXTRA_DIST = $(COMMON_H) $(KERNEL_H) $(USER_H)
+
+if CONFIG_KERNEL
+kerneldir = @prefix@/src/spl-$(VERSION)/include
+kernel_HEADERS = $(KERNEL_H)
+endif
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/Makefile.in
@@ -0,0 +1,743 @@
+# Makefile.in generated by automake 1.15 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2014 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+VPATH = @srcdir@
+am__is_gnu_make = { \
+  if test -z '$(MAKELEVEL)'; then \
+    false; \
+  elif test -n '$(MAKE_HOST)'; then \
+    true; \
+  elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+    true; \
+  else \
+    false; \
+  fi; \
+}
+am__make_running_with_option = \
+  case $${target_option-} in \
+      ?) ;; \
+      *) echo "am__make_running_with_option: internal error: invalid" \
+              "target option '$${target_option-}' specified" >&2; \
+         exit 1;; \
+  esac; \
+  has_opt=no; \
+  sane_makeflags=$$MAKEFLAGS; \
+  if $(am__is_gnu_make); then \
+    sane_makeflags=$$MFLAGS; \
+  else \
+    case $$MAKEFLAGS in \
+      *\\[\ \	]*) \
+        bs=\\; \
+        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
+    esac; \
+  fi; \
+  skip_next=no; \
+  strip_trailopt () \
+  { \
+    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+  }; \
+  for flg in $$sane_makeflags; do \
+    test $$skip_next = yes && { skip_next=no; continue; }; \
+    case $$flg in \
+      *=*|--*) continue;; \
+        -*I) strip_trailopt 'I'; skip_next=yes;; \
+      -*I?*) strip_trailopt 'I';; \
+        -*O) strip_trailopt 'O'; skip_next=yes;; \
+      -*O?*) strip_trailopt 'O';; \
+        -*l) strip_trailopt 'l'; skip_next=yes;; \
+      -*l?*) strip_trailopt 'l';; \
+      -[dEDm]) skip_next=yes;; \
+      -[JT]) skip_next=yes;; \
+    esac; \
+    case $$flg in \
+      *$$target_option*) has_opt=yes; break;; \
+    esac; \
+  done; \
+  test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+target_triplet = @target@
+subdir = include
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/config/libtool.m4 \
+	$(top_srcdir)/config/ltoptions.m4 \
+	$(top_srcdir)/config/ltsugar.m4 \
+	$(top_srcdir)/config/ltversion.m4 \
+	$(top_srcdir)/config/lt~obsolete.m4 \
+	$(top_srcdir)/config/spl-build.m4 \
+	$(top_srcdir)/config/spl-meta.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(am__kernel_HEADERS_DIST) \
+	$(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/spl_config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo "  GEN     " $@;
+am__v_GEN_1 = 
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 = 
+SOURCES =
+DIST_SOURCES =
+RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \
+	ctags-recursive dvi-recursive html-recursive info-recursive \
+	install-data-recursive install-dvi-recursive \
+	install-exec-recursive install-html-recursive \
+	install-info-recursive install-pdf-recursive \
+	install-ps-recursive install-recursive installcheck-recursive \
+	installdirs-recursive pdf-recursive ps-recursive \
+	tags-recursive uninstall-recursive
+am__can_run_installinfo = \
+  case $$AM_UPDATE_INFO_DIR in \
+    n|no|NO) false;; \
+    *) (install-info --version) >/dev/null 2>&1;; \
+  esac
+am__kernel_HEADERS_DIST = $(top_srcdir)/include/splat-ctl.h \
+	$(top_srcdir)/include/spl-ctl.h \
+	$(top_srcdir)/include/strings.h $(top_srcdir)/include/unistd.h
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+    $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+    *) f=$$p;; \
+  esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+  srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+  for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+  for p in $$list; do echo "$$p $$p"; done | \
+  sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+  $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+    if (++n[$$2] == $(am__install_max)) \
+      { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+    END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+  sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+  sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+  test -z "$$files" \
+    || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+    || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+         $(am__cd) "$$dir" && rm -f $$files; }; \
+  }
+am__installdirs = "$(DESTDIR)$(kerneldir)"
+HEADERS = $(kernel_HEADERS)
+RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive	\
+  distclean-recursive maintainer-clean-recursive
+am__recursive_targets = \
+  $(RECURSIVE_TARGETS) \
+  $(RECURSIVE_CLEAN_TARGETS) \
+  $(am__extra_recursive_targets)
+AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \
+	distdir
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates.  Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+  BEGIN { nonempty = 0; } \
+  { items[$$0] = 1; nonempty = 1; } \
+  END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique.  This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+  list='$(am__tagged_files)'; \
+  unique=`for i in $$list; do \
+    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+  done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+DIST_SUBDIRS = $(SUBDIRS)
+am__DIST_COMMON = $(srcdir)/Makefile.in
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+am__relativize = \
+  dir0=`pwd`; \
+  sed_first='s,^\([^/]*\)/.*$$,\1,'; \
+  sed_rest='s,^[^/]*/*,,'; \
+  sed_last='s,^.*/\([^/]*\)$$,\1,'; \
+  sed_butlast='s,/*[^/]*$$,,'; \
+  while test -n "$$dir1"; do \
+    first=`echo "$$dir1" | sed -e "$$sed_first"`; \
+    if test "$$first" != "."; then \
+      if test "$$first" = ".."; then \
+        dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \
+        dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \
+      else \
+        first2=`echo "$$dir2" | sed -e "$$sed_first"`; \
+        if test "$$first2" = "$$first"; then \
+          dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \
+        else \
+          dir2="../$$dir2"; \
+        fi; \
+        dir0="$$dir0"/"$$first"; \
+      fi; \
+    fi; \
+    dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \
+  done; \
+  reldir="$$dir2"
+ACLOCAL = @ACLOCAL@
+ALIEN = @ALIEN@
+ALIEN_VERSION = @ALIEN_VERSION@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEBUG_CFLAGS = @DEBUG_CFLAGS@
+DEBUG_KMEM = @DEBUG_KMEM@
+DEBUG_KMEM_TRACKING = @DEBUG_KMEM_TRACKING@
+DEBUG_SPL = @DEBUG_SPL@
+DEFAULT_PACKAGE = @DEFAULT_PACKAGE@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DPKG = @DPKG@
+DPKGBUILD = @DPKGBUILD@
+DPKGBUILD_VERSION = @DPKGBUILD_VERSION@
+DPKG_VERSION = @DPKG_VERSION@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GREP = @GREP@
+HAVE_ALIEN = @HAVE_ALIEN@
+HAVE_DPKG = @HAVE_DPKG@
+HAVE_DPKGBUILD = @HAVE_DPKGBUILD@
+HAVE_RPM = @HAVE_RPM@
+HAVE_RPMBUILD = @HAVE_RPMBUILD@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+KERNELCPPFLAGS = @KERNELCPPFLAGS@
+KERNELMAKE_PARAMS = @KERNELMAKE_PARAMS@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LINUX = @LINUX@
+LINUX_OBJ = @LINUX_OBJ@
+LINUX_SYMBOLS = @LINUX_SYMBOLS@
+LINUX_VERSION = @LINUX_VERSION@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+RANLIB = @RANLIB@
+RELEASE = @RELEASE@
+RPM = @RPM@
+RPMBUILD = @RPMBUILD@
+RPMBUILD_VERSION = @RPMBUILD_VERSION@
+RPM_DEFINE_COMMON = @RPM_DEFINE_COMMON@
+RPM_DEFINE_DKMS = @RPM_DEFINE_DKMS@
+RPM_DEFINE_KMOD = @RPM_DEFINE_KMOD@
+RPM_DEFINE_UTIL = @RPM_DEFINE_UTIL@
+RPM_SPEC_DIR = @RPM_SPEC_DIR@
+RPM_VERSION = @RPM_VERSION@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SPL_CONFIG = @SPL_CONFIG@
+SPL_META_ALIAS = @SPL_META_ALIAS@
+SPL_META_AUTHOR = @SPL_META_AUTHOR@
+SPL_META_DATA = @SPL_META_DATA@
+SPL_META_LICENSE = @SPL_META_LICENSE@
+SPL_META_LT_AGE = @SPL_META_LT_AGE@
+SPL_META_LT_CURRENT = @SPL_META_LT_CURRENT@
+SPL_META_LT_REVISION = @SPL_META_LT_REVISION@
+SPL_META_NAME = @SPL_META_NAME@
+SPL_META_RELEASE = @SPL_META_RELEASE@
+SPL_META_VERSION = @SPL_META_VERSION@
+SRPM_DEFINE_COMMON = @SRPM_DEFINE_COMMON@
+SRPM_DEFINE_DKMS = @SRPM_DEFINE_DKMS@
+SRPM_DEFINE_KMOD = @SRPM_DEFINE_KMOD@
+SRPM_DEFINE_UTIL = @SRPM_DEFINE_UTIL@
+STRIP = @STRIP@
+VENDOR = @VENDOR@
+VERSION = @VERSION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+runstatedir = @runstatedir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+SUBDIRS = fs linux rpc sharefs sys util vm
+COMMON_H = 
+KERNEL_H = \
+	$(top_srcdir)/include/splat-ctl.h \
+	$(top_srcdir)/include/spl-ctl.h \
+	$(top_srcdir)/include/strings.h \
+	$(top_srcdir)/include/unistd.h
+
+USER_H = 
+EXTRA_DIST = $(COMMON_H) $(KERNEL_H) $(USER_H)
+@CONFIG_KERNEL_TRUE@kerneldir = @prefix@/src/spl-$(VERSION)/include
+@CONFIG_KERNEL_TRUE@kernel_HEADERS = $(KERNEL_H)
+all: all-recursive
+
+.SUFFIXES:
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+	        && { if test -f $@; then exit 0; else break; fi; }; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu include/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --gnu include/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+	esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
+install-kernelHEADERS: $(kernel_HEADERS)
+	@$(NORMAL_INSTALL)
+	@list='$(kernel_HEADERS)'; test -n "$(kerneldir)" || list=; \
+	if test -n "$$list"; then \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(kerneldir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(kerneldir)" || exit 1; \
+	fi; \
+	for p in $$list; do \
+	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+	  echo "$$d$$p"; \
+	done | $(am__base_list) | \
+	while read files; do \
+	  echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(kerneldir)'"; \
+	  $(INSTALL_HEADER) $$files "$(DESTDIR)$(kerneldir)" || exit $$?; \
+	done
+
+uninstall-kernelHEADERS:
+	@$(NORMAL_UNINSTALL)
+	@list='$(kernel_HEADERS)'; test -n "$(kerneldir)" || list=; \
+	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+	dir='$(DESTDIR)$(kerneldir)'; $(am__uninstall_files_from_dir)
+
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run 'make' without going through this Makefile.
+# To change the values of 'make' variables: instead of editing Makefiles,
+# (1) if the variable is set in 'config.status', edit 'config.status'
+#     (which will cause the Makefiles to be regenerated when you run 'make');
+# (2) otherwise, pass the desired values on the 'make' command line.
+$(am__recursive_targets):
+	@fail=; \
+	if $(am__make_keepgoing); then \
+	  failcom='fail=yes'; \
+	else \
+	  failcom='exit 1'; \
+	fi; \
+	dot_seen=no; \
+	target=`echo $@ | sed s/-recursive//`; \
+	case "$@" in \
+	  distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
+	  *) list='$(SUBDIRS)' ;; \
+	esac; \
+	for subdir in $$list; do \
+	  echo "Making $$target in $$subdir"; \
+	  if test "$$subdir" = "."; then \
+	    dot_seen=yes; \
+	    local_target="$$target-am"; \
+	  else \
+	    local_target="$$target"; \
+	  fi; \
+	  ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+	  || eval $$failcom; \
+	done; \
+	if test "$$dot_seen" = "no"; then \
+	  $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+	fi; test -z "$$fail"
+
+ID: $(am__tagged_files)
+	$(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-recursive
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	set x; \
+	here=`pwd`; \
+	if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
+	  include_option=--etags-include; \
+	  empty_fix=.; \
+	else \
+	  include_option=--include; \
+	  empty_fix=; \
+	fi; \
+	list='$(SUBDIRS)'; for subdir in $$list; do \
+	  if test "$$subdir" = .; then :; else \
+	    test ! -f $$subdir/TAGS || \
+	      set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \
+	  fi; \
+	done; \
+	$(am__define_uniq_tagged_files); \
+	shift; \
+	if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+	  test -n "$$unique" || unique=$$empty_fix; \
+	  if test $$# -gt 0; then \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      "$$@" $$unique; \
+	  else \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      $$unique; \
+	  fi; \
+	fi
+ctags: ctags-recursive
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	$(am__define_uniq_tagged_files); \
+	test -z "$(CTAGS_ARGS)$$unique" \
+	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+	     $$unique
+
+GTAGS:
+	here=`$(am__cd) $(top_builddir) && pwd` \
+	  && $(am__cd) $(top_srcdir) \
+	  && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-recursive
+
+cscopelist-am: $(am__tagged_files)
+	list='$(am__tagged_files)'; \
+	case "$(srcdir)" in \
+	  [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+	  *) sdir=$(subdir)/$(srcdir) ;; \
+	esac; \
+	for i in $$list; do \
+	  if test -f "$$i"; then \
+	    echo "$(subdir)/$$i"; \
+	  else \
+	    echo "$$sdir/$$i"; \
+	  fi; \
+	done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	list='$(DISTFILES)'; \
+	  dist_files=`for file in $$list; do echo $$file; done | \
+	  sed -e "s|^$$srcdirstrip/||;t" \
+	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+	case $$dist_files in \
+	  */*) $(MKDIR_P) `echo "$$dist_files" | \
+			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+			   sort -u` ;; \
+	esac; \
+	for file in $$dist_files; do \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  if test -d $$d/$$file; then \
+	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+	    if test -d "$(distdir)/$$file"; then \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+	  else \
+	    test -f "$(distdir)/$$file" \
+	    || cp -p $$d/$$file "$(distdir)/$$file" \
+	    || exit 1; \
+	  fi; \
+	done
+	@list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
+	  if test "$$subdir" = .; then :; else \
+	    $(am__make_dryrun) \
+	      || test -d "$(distdir)/$$subdir" \
+	      || $(MKDIR_P) "$(distdir)/$$subdir" \
+	      || exit 1; \
+	    dir1=$$subdir; dir2="$(distdir)/$$subdir"; \
+	    $(am__relativize); \
+	    new_distdir=$$reldir; \
+	    dir1=$$subdir; dir2="$(top_distdir)"; \
+	    $(am__relativize); \
+	    new_top_distdir=$$reldir; \
+	    echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \
+	    echo "     am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \
+	    ($(am__cd) $$subdir && \
+	      $(MAKE) $(AM_MAKEFLAGS) \
+	        top_distdir="$$new_top_distdir" \
+	        distdir="$$new_distdir" \
+		am__remove_distdir=: \
+		am__skip_length_check=: \
+		am__skip_mode_fix=: \
+	        distdir) \
+	      || exit 1; \
+	  fi; \
+	done
+check-am: all-am
+check: check-recursive
+all-am: Makefile $(HEADERS)
+installdirs: installdirs-recursive
+installdirs-am:
+	for dir in "$(DESTDIR)$(kerneldir)"; do \
+	  test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+	done
+install: install-recursive
+install-exec: install-exec-recursive
+install-data: install-data-recursive
+uninstall: uninstall-recursive
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-recursive
+install-strip:
+	if test -z '$(STRIP)'; then \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	      install; \
+	else \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+	fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+clean: clean-recursive
+
+clean-am: clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-recursive
+	-rm -f Makefile
+distclean-am: clean-am distclean-generic distclean-tags
+
+dvi: dvi-recursive
+
+dvi-am:
+
+html: html-recursive
+
+html-am:
+
+info: info-recursive
+
+info-am:
+
+install-data-am: install-kernelHEADERS
+
+install-dvi: install-dvi-recursive
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-recursive
+
+install-html-am:
+
+install-info: install-info-recursive
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-recursive
+
+install-pdf-am:
+
+install-ps: install-ps-recursive
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-recursive
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-recursive
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-recursive
+
+pdf-am:
+
+ps: ps-recursive
+
+ps-am:
+
+uninstall-am: uninstall-kernelHEADERS
+
+.MAKE: $(am__recursive_targets) install-am install-strip
+
+.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \
+	check-am clean clean-generic clean-libtool cscopelist-am ctags \
+	ctags-am distclean distclean-generic distclean-libtool \
+	distclean-tags distdir dvi dvi-am html html-am info info-am \
+	install install-am install-data install-data-am install-dvi \
+	install-dvi-am install-exec install-exec-am install-html \
+	install-html-am install-info install-info-am \
+	install-kernelHEADERS install-man install-pdf install-pdf-am \
+	install-ps install-ps-am install-strip installcheck \
+	installcheck-am installdirs installdirs-am maintainer-clean \
+	maintainer-clean-generic mostlyclean mostlyclean-generic \
+	mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \
+	uninstall-am uninstall-kernelHEADERS
+
+.PRECIOUS: Makefile
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/fs/Makefile.am
@@ -0,0 +1,13 @@
+COMMON_H =
+
+KERNEL_H = \
+	$(top_srcdir)/include/fs/fs_subr.h
+
+USER_H =
+
+EXTRA_DIST = $(COMMON_H) $(KERNEL_H) $(USER_H)
+
+if CONFIG_KERNEL
+kerneldir = @prefix@/src/spl-$(VERSION)/include/fs
+kernel_HEADERS = $(KERNEL_H)
+endif
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/fs/Makefile.in
@@ -0,0 +1,621 @@
+# Makefile.in generated by automake 1.15 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2014 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+VPATH = @srcdir@
+am__is_gnu_make = { \
+  if test -z '$(MAKELEVEL)'; then \
+    false; \
+  elif test -n '$(MAKE_HOST)'; then \
+    true; \
+  elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+    true; \
+  else \
+    false; \
+  fi; \
+}
+am__make_running_with_option = \
+  case $${target_option-} in \
+      ?) ;; \
+      *) echo "am__make_running_with_option: internal error: invalid" \
+              "target option '$${target_option-}' specified" >&2; \
+         exit 1;; \
+  esac; \
+  has_opt=no; \
+  sane_makeflags=$$MAKEFLAGS; \
+  if $(am__is_gnu_make); then \
+    sane_makeflags=$$MFLAGS; \
+  else \
+    case $$MAKEFLAGS in \
+      *\\[\ \	]*) \
+        bs=\\; \
+        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
+    esac; \
+  fi; \
+  skip_next=no; \
+  strip_trailopt () \
+  { \
+    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+  }; \
+  for flg in $$sane_makeflags; do \
+    test $$skip_next = yes && { skip_next=no; continue; }; \
+    case $$flg in \
+      *=*|--*) continue;; \
+        -*I) strip_trailopt 'I'; skip_next=yes;; \
+      -*I?*) strip_trailopt 'I';; \
+        -*O) strip_trailopt 'O'; skip_next=yes;; \
+      -*O?*) strip_trailopt 'O';; \
+        -*l) strip_trailopt 'l'; skip_next=yes;; \
+      -*l?*) strip_trailopt 'l';; \
+      -[dEDm]) skip_next=yes;; \
+      -[JT]) skip_next=yes;; \
+    esac; \
+    case $$flg in \
+      *$$target_option*) has_opt=yes; break;; \
+    esac; \
+  done; \
+  test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+target_triplet = @target@
+subdir = include/fs
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/config/libtool.m4 \
+	$(top_srcdir)/config/ltoptions.m4 \
+	$(top_srcdir)/config/ltsugar.m4 \
+	$(top_srcdir)/config/ltversion.m4 \
+	$(top_srcdir)/config/lt~obsolete.m4 \
+	$(top_srcdir)/config/spl-build.m4 \
+	$(top_srcdir)/config/spl-meta.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(am__kernel_HEADERS_DIST) \
+	$(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/spl_config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo "  GEN     " $@;
+am__v_GEN_1 = 
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 = 
+SOURCES =
+DIST_SOURCES =
+am__can_run_installinfo = \
+  case $$AM_UPDATE_INFO_DIR in \
+    n|no|NO) false;; \
+    *) (install-info --version) >/dev/null 2>&1;; \
+  esac
+am__kernel_HEADERS_DIST = $(top_srcdir)/include/fs/fs_subr.h
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+    $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+    *) f=$$p;; \
+  esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+  srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+  for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+  for p in $$list; do echo "$$p $$p"; done | \
+  sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+  $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+    if (++n[$$2] == $(am__install_max)) \
+      { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+    END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+  sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+  sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+  test -z "$$files" \
+    || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+    || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+         $(am__cd) "$$dir" && rm -f $$files; }; \
+  }
+am__installdirs = "$(DESTDIR)$(kerneldir)"
+HEADERS = $(kernel_HEADERS)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates.  Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+  BEGIN { nonempty = 0; } \
+  { items[$$0] = 1; nonempty = 1; } \
+  END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique.  This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+  list='$(am__tagged_files)'; \
+  unique=`for i in $$list; do \
+    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+  done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+am__DIST_COMMON = $(srcdir)/Makefile.in
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ALIEN = @ALIEN@
+ALIEN_VERSION = @ALIEN_VERSION@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEBUG_CFLAGS = @DEBUG_CFLAGS@
+DEBUG_KMEM = @DEBUG_KMEM@
+DEBUG_KMEM_TRACKING = @DEBUG_KMEM_TRACKING@
+DEBUG_SPL = @DEBUG_SPL@
+DEFAULT_PACKAGE = @DEFAULT_PACKAGE@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DPKG = @DPKG@
+DPKGBUILD = @DPKGBUILD@
+DPKGBUILD_VERSION = @DPKGBUILD_VERSION@
+DPKG_VERSION = @DPKG_VERSION@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GREP = @GREP@
+HAVE_ALIEN = @HAVE_ALIEN@
+HAVE_DPKG = @HAVE_DPKG@
+HAVE_DPKGBUILD = @HAVE_DPKGBUILD@
+HAVE_RPM = @HAVE_RPM@
+HAVE_RPMBUILD = @HAVE_RPMBUILD@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+KERNELCPPFLAGS = @KERNELCPPFLAGS@
+KERNELMAKE_PARAMS = @KERNELMAKE_PARAMS@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LINUX = @LINUX@
+LINUX_OBJ = @LINUX_OBJ@
+LINUX_SYMBOLS = @LINUX_SYMBOLS@
+LINUX_VERSION = @LINUX_VERSION@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+RANLIB = @RANLIB@
+RELEASE = @RELEASE@
+RPM = @RPM@
+RPMBUILD = @RPMBUILD@
+RPMBUILD_VERSION = @RPMBUILD_VERSION@
+RPM_DEFINE_COMMON = @RPM_DEFINE_COMMON@
+RPM_DEFINE_DKMS = @RPM_DEFINE_DKMS@
+RPM_DEFINE_KMOD = @RPM_DEFINE_KMOD@
+RPM_DEFINE_UTIL = @RPM_DEFINE_UTIL@
+RPM_SPEC_DIR = @RPM_SPEC_DIR@
+RPM_VERSION = @RPM_VERSION@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SPL_CONFIG = @SPL_CONFIG@
+SPL_META_ALIAS = @SPL_META_ALIAS@
+SPL_META_AUTHOR = @SPL_META_AUTHOR@
+SPL_META_DATA = @SPL_META_DATA@
+SPL_META_LICENSE = @SPL_META_LICENSE@
+SPL_META_LT_AGE = @SPL_META_LT_AGE@
+SPL_META_LT_CURRENT = @SPL_META_LT_CURRENT@
+SPL_META_LT_REVISION = @SPL_META_LT_REVISION@
+SPL_META_NAME = @SPL_META_NAME@
+SPL_META_RELEASE = @SPL_META_RELEASE@
+SPL_META_VERSION = @SPL_META_VERSION@
+SRPM_DEFINE_COMMON = @SRPM_DEFINE_COMMON@
+SRPM_DEFINE_DKMS = @SRPM_DEFINE_DKMS@
+SRPM_DEFINE_KMOD = @SRPM_DEFINE_KMOD@
+SRPM_DEFINE_UTIL = @SRPM_DEFINE_UTIL@
+STRIP = @STRIP@
+VENDOR = @VENDOR@
+VERSION = @VERSION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+runstatedir = @runstatedir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+COMMON_H = 
+KERNEL_H = \
+	$(top_srcdir)/include/fs/fs_subr.h
+
+USER_H = 
+EXTRA_DIST = $(COMMON_H) $(KERNEL_H) $(USER_H)
+@CONFIG_KERNEL_TRUE@kerneldir = @prefix@/src/spl-$(VERSION)/include/fs
+@CONFIG_KERNEL_TRUE@kernel_HEADERS = $(KERNEL_H)
+all: all-am
+
+.SUFFIXES:
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+	        && { if test -f $@; then exit 0; else break; fi; }; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu include/fs/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --gnu include/fs/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+	esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
+install-kernelHEADERS: $(kernel_HEADERS)
+	@$(NORMAL_INSTALL)
+	@list='$(kernel_HEADERS)'; test -n "$(kerneldir)" || list=; \
+	if test -n "$$list"; then \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(kerneldir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(kerneldir)" || exit 1; \
+	fi; \
+	for p in $$list; do \
+	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+	  echo "$$d$$p"; \
+	done | $(am__base_list) | \
+	while read files; do \
+	  echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(kerneldir)'"; \
+	  $(INSTALL_HEADER) $$files "$(DESTDIR)$(kerneldir)" || exit $$?; \
+	done
+
+uninstall-kernelHEADERS:
+	@$(NORMAL_UNINSTALL)
+	@list='$(kernel_HEADERS)'; test -n "$(kerneldir)" || list=; \
+	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+	dir='$(DESTDIR)$(kerneldir)'; $(am__uninstall_files_from_dir)
+
+ID: $(am__tagged_files)
+	$(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	set x; \
+	here=`pwd`; \
+	$(am__define_uniq_tagged_files); \
+	shift; \
+	if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+	  test -n "$$unique" || unique=$$empty_fix; \
+	  if test $$# -gt 0; then \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      "$$@" $$unique; \
+	  else \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      $$unique; \
+	  fi; \
+	fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	$(am__define_uniq_tagged_files); \
+	test -z "$(CTAGS_ARGS)$$unique" \
+	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+	     $$unique
+
+GTAGS:
+	here=`$(am__cd) $(top_builddir) && pwd` \
+	  && $(am__cd) $(top_srcdir) \
+	  && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+	list='$(am__tagged_files)'; \
+	case "$(srcdir)" in \
+	  [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+	  *) sdir=$(subdir)/$(srcdir) ;; \
+	esac; \
+	for i in $$list; do \
+	  if test -f "$$i"; then \
+	    echo "$(subdir)/$$i"; \
+	  else \
+	    echo "$$sdir/$$i"; \
+	  fi; \
+	done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	list='$(DISTFILES)'; \
+	  dist_files=`for file in $$list; do echo $$file; done | \
+	  sed -e "s|^$$srcdirstrip/||;t" \
+	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+	case $$dist_files in \
+	  */*) $(MKDIR_P) `echo "$$dist_files" | \
+			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+			   sort -u` ;; \
+	esac; \
+	for file in $$dist_files; do \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  if test -d $$d/$$file; then \
+	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+	    if test -d "$(distdir)/$$file"; then \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+	  else \
+	    test -f "$(distdir)/$$file" \
+	    || cp -p $$d/$$file "$(distdir)/$$file" \
+	    || exit 1; \
+	  fi; \
+	done
+check-am: all-am
+check: check-am
+all-am: Makefile $(HEADERS)
+installdirs:
+	for dir in "$(DESTDIR)$(kerneldir)"; do \
+	  test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+	done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+	if test -z '$(STRIP)'; then \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	      install; \
+	else \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+	fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-am
+	-rm -f Makefile
+distclean-am: clean-am distclean-generic distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-kernelHEADERS
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-kernelHEADERS
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \
+	clean-libtool cscopelist-am ctags ctags-am distclean \
+	distclean-generic distclean-libtool distclean-tags distdir dvi \
+	dvi-am html html-am info info-am install install-am \
+	install-data install-data-am install-dvi install-dvi-am \
+	install-exec install-exec-am install-html install-html-am \
+	install-info install-info-am install-kernelHEADERS install-man \
+	install-pdf install-pdf-am install-ps install-ps-am \
+	install-strip installcheck installcheck-am installdirs \
+	maintainer-clean maintainer-clean-generic mostlyclean \
+	mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+	tags tags-am uninstall uninstall-am uninstall-kernelHEADERS
+
+.PRECIOUS: Makefile
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/fs/fs_subr.h
@@ -0,0 +1,28 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+\*****************************************************************************/
+
+#ifndef _SPL_FS_FS_SUBR_H
+#define _SPL_FS_FS_SUBR_H
+
+#endif /* SPL_FS_FS_SUBR_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/linux/Makefile.am
@@ -0,0 +1,23 @@
+COMMON_H =
+
+KERNEL_H = \
+	$(top_srcdir)/include/linux/bitops_compat.h \
+	$(top_srcdir)/include/linux/compiler_compat.h \
+	$(top_srcdir)/include/linux/delay_compat.h \
+	$(top_srcdir)/include/linux/file_compat.h \
+	$(top_srcdir)/include/linux/list_compat.h \
+	$(top_srcdir)/include/linux/math64_compat.h \
+	$(top_srcdir)/include/linux/mm_compat.h \
+	$(top_srcdir)/include/linux/proc_compat.h \
+	$(top_srcdir)/include/linux/rwsem_compat.h \
+	$(top_srcdir)/include/linux/wait_compat.h \
+	$(top_srcdir)/include/linux/zlib_compat.h
+
+USER_H =
+
+EXTRA_DIST = $(COMMON_H) $(KERNEL_H) $(USER_H)
+
+if CONFIG_KERNEL
+kerneldir = @prefix@/src/spl-$(VERSION)/include/linux
+kernel_HEADERS = $(KERNEL_H)
+endif
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/linux/Makefile.in
@@ -0,0 +1,641 @@
+# Makefile.in generated by automake 1.15 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2014 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+VPATH = @srcdir@
+am__is_gnu_make = { \
+  if test -z '$(MAKELEVEL)'; then \
+    false; \
+  elif test -n '$(MAKE_HOST)'; then \
+    true; \
+  elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+    true; \
+  else \
+    false; \
+  fi; \
+}
+am__make_running_with_option = \
+  case $${target_option-} in \
+      ?) ;; \
+      *) echo "am__make_running_with_option: internal error: invalid" \
+              "target option '$${target_option-}' specified" >&2; \
+         exit 1;; \
+  esac; \
+  has_opt=no; \
+  sane_makeflags=$$MAKEFLAGS; \
+  if $(am__is_gnu_make); then \
+    sane_makeflags=$$MFLAGS; \
+  else \
+    case $$MAKEFLAGS in \
+      *\\[\ \	]*) \
+        bs=\\; \
+        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
+    esac; \
+  fi; \
+  skip_next=no; \
+  strip_trailopt () \
+  { \
+    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+  }; \
+  for flg in $$sane_makeflags; do \
+    test $$skip_next = yes && { skip_next=no; continue; }; \
+    case $$flg in \
+      *=*|--*) continue;; \
+        -*I) strip_trailopt 'I'; skip_next=yes;; \
+      -*I?*) strip_trailopt 'I';; \
+        -*O) strip_trailopt 'O'; skip_next=yes;; \
+      -*O?*) strip_trailopt 'O';; \
+        -*l) strip_trailopt 'l'; skip_next=yes;; \
+      -*l?*) strip_trailopt 'l';; \
+      -[dEDm]) skip_next=yes;; \
+      -[JT]) skip_next=yes;; \
+    esac; \
+    case $$flg in \
+      *$$target_option*) has_opt=yes; break;; \
+    esac; \
+  done; \
+  test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+target_triplet = @target@
+subdir = include/linux
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/config/libtool.m4 \
+	$(top_srcdir)/config/ltoptions.m4 \
+	$(top_srcdir)/config/ltsugar.m4 \
+	$(top_srcdir)/config/ltversion.m4 \
+	$(top_srcdir)/config/lt~obsolete.m4 \
+	$(top_srcdir)/config/spl-build.m4 \
+	$(top_srcdir)/config/spl-meta.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(am__kernel_HEADERS_DIST) \
+	$(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/spl_config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo "  GEN     " $@;
+am__v_GEN_1 = 
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 = 
+SOURCES =
+DIST_SOURCES =
+am__can_run_installinfo = \
+  case $$AM_UPDATE_INFO_DIR in \
+    n|no|NO) false;; \
+    *) (install-info --version) >/dev/null 2>&1;; \
+  esac
+am__kernel_HEADERS_DIST = $(top_srcdir)/include/linux/bitops_compat.h \
+	$(top_srcdir)/include/linux/compiler_compat.h \
+	$(top_srcdir)/include/linux/delay_compat.h \
+	$(top_srcdir)/include/linux/file_compat.h \
+	$(top_srcdir)/include/linux/list_compat.h \
+	$(top_srcdir)/include/linux/math64_compat.h \
+	$(top_srcdir)/include/linux/mm_compat.h \
+	$(top_srcdir)/include/linux/proc_compat.h \
+	$(top_srcdir)/include/linux/rwsem_compat.h \
+	$(top_srcdir)/include/linux/wait_compat.h \
+	$(top_srcdir)/include/linux/zlib_compat.h
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+    $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+    *) f=$$p;; \
+  esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+  srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+  for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+  for p in $$list; do echo "$$p $$p"; done | \
+  sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+  $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+    if (++n[$$2] == $(am__install_max)) \
+      { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+    END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+  sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+  sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+  test -z "$$files" \
+    || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+    || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+         $(am__cd) "$$dir" && rm -f $$files; }; \
+  }
+am__installdirs = "$(DESTDIR)$(kerneldir)"
+HEADERS = $(kernel_HEADERS)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates.  Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+  BEGIN { nonempty = 0; } \
+  { items[$$0] = 1; nonempty = 1; } \
+  END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique.  This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+  list='$(am__tagged_files)'; \
+  unique=`for i in $$list; do \
+    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+  done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+am__DIST_COMMON = $(srcdir)/Makefile.in
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ALIEN = @ALIEN@
+ALIEN_VERSION = @ALIEN_VERSION@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEBUG_CFLAGS = @DEBUG_CFLAGS@
+DEBUG_KMEM = @DEBUG_KMEM@
+DEBUG_KMEM_TRACKING = @DEBUG_KMEM_TRACKING@
+DEBUG_SPL = @DEBUG_SPL@
+DEFAULT_PACKAGE = @DEFAULT_PACKAGE@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DPKG = @DPKG@
+DPKGBUILD = @DPKGBUILD@
+DPKGBUILD_VERSION = @DPKGBUILD_VERSION@
+DPKG_VERSION = @DPKG_VERSION@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GREP = @GREP@
+HAVE_ALIEN = @HAVE_ALIEN@
+HAVE_DPKG = @HAVE_DPKG@
+HAVE_DPKGBUILD = @HAVE_DPKGBUILD@
+HAVE_RPM = @HAVE_RPM@
+HAVE_RPMBUILD = @HAVE_RPMBUILD@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+KERNELCPPFLAGS = @KERNELCPPFLAGS@
+KERNELMAKE_PARAMS = @KERNELMAKE_PARAMS@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LINUX = @LINUX@
+LINUX_OBJ = @LINUX_OBJ@
+LINUX_SYMBOLS = @LINUX_SYMBOLS@
+LINUX_VERSION = @LINUX_VERSION@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+RANLIB = @RANLIB@
+RELEASE = @RELEASE@
+RPM = @RPM@
+RPMBUILD = @RPMBUILD@
+RPMBUILD_VERSION = @RPMBUILD_VERSION@
+RPM_DEFINE_COMMON = @RPM_DEFINE_COMMON@
+RPM_DEFINE_DKMS = @RPM_DEFINE_DKMS@
+RPM_DEFINE_KMOD = @RPM_DEFINE_KMOD@
+RPM_DEFINE_UTIL = @RPM_DEFINE_UTIL@
+RPM_SPEC_DIR = @RPM_SPEC_DIR@
+RPM_VERSION = @RPM_VERSION@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SPL_CONFIG = @SPL_CONFIG@
+SPL_META_ALIAS = @SPL_META_ALIAS@
+SPL_META_AUTHOR = @SPL_META_AUTHOR@
+SPL_META_DATA = @SPL_META_DATA@
+SPL_META_LICENSE = @SPL_META_LICENSE@
+SPL_META_LT_AGE = @SPL_META_LT_AGE@
+SPL_META_LT_CURRENT = @SPL_META_LT_CURRENT@
+SPL_META_LT_REVISION = @SPL_META_LT_REVISION@
+SPL_META_NAME = @SPL_META_NAME@
+SPL_META_RELEASE = @SPL_META_RELEASE@
+SPL_META_VERSION = @SPL_META_VERSION@
+SRPM_DEFINE_COMMON = @SRPM_DEFINE_COMMON@
+SRPM_DEFINE_DKMS = @SRPM_DEFINE_DKMS@
+SRPM_DEFINE_KMOD = @SRPM_DEFINE_KMOD@
+SRPM_DEFINE_UTIL = @SRPM_DEFINE_UTIL@
+STRIP = @STRIP@
+VENDOR = @VENDOR@
+VERSION = @VERSION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+runstatedir = @runstatedir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+COMMON_H = 
+KERNEL_H = \
+	$(top_srcdir)/include/linux/bitops_compat.h \
+	$(top_srcdir)/include/linux/compiler_compat.h \
+	$(top_srcdir)/include/linux/delay_compat.h \
+	$(top_srcdir)/include/linux/file_compat.h \
+	$(top_srcdir)/include/linux/list_compat.h \
+	$(top_srcdir)/include/linux/math64_compat.h \
+	$(top_srcdir)/include/linux/mm_compat.h \
+	$(top_srcdir)/include/linux/proc_compat.h \
+	$(top_srcdir)/include/linux/rwsem_compat.h \
+	$(top_srcdir)/include/linux/wait_compat.h \
+	$(top_srcdir)/include/linux/zlib_compat.h
+
+USER_H = 
+EXTRA_DIST = $(COMMON_H) $(KERNEL_H) $(USER_H)
+@CONFIG_KERNEL_TRUE@kerneldir = @prefix@/src/spl-$(VERSION)/include/linux
+@CONFIG_KERNEL_TRUE@kernel_HEADERS = $(KERNEL_H)
+all: all-am
+
+.SUFFIXES:
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+	        && { if test -f $@; then exit 0; else break; fi; }; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu include/linux/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --gnu include/linux/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+	esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
+install-kernelHEADERS: $(kernel_HEADERS)
+	@$(NORMAL_INSTALL)
+	@list='$(kernel_HEADERS)'; test -n "$(kerneldir)" || list=; \
+	if test -n "$$list"; then \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(kerneldir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(kerneldir)" || exit 1; \
+	fi; \
+	for p in $$list; do \
+	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+	  echo "$$d$$p"; \
+	done | $(am__base_list) | \
+	while read files; do \
+	  echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(kerneldir)'"; \
+	  $(INSTALL_HEADER) $$files "$(DESTDIR)$(kerneldir)" || exit $$?; \
+	done
+
+uninstall-kernelHEADERS:
+	@$(NORMAL_UNINSTALL)
+	@list='$(kernel_HEADERS)'; test -n "$(kerneldir)" || list=; \
+	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+	dir='$(DESTDIR)$(kerneldir)'; $(am__uninstall_files_from_dir)
+
+ID: $(am__tagged_files)
+	$(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	set x; \
+	here=`pwd`; \
+	$(am__define_uniq_tagged_files); \
+	shift; \
+	if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+	  test -n "$$unique" || unique=$$empty_fix; \
+	  if test $$# -gt 0; then \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      "$$@" $$unique; \
+	  else \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      $$unique; \
+	  fi; \
+	fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	$(am__define_uniq_tagged_files); \
+	test -z "$(CTAGS_ARGS)$$unique" \
+	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+	     $$unique
+
+GTAGS:
+	here=`$(am__cd) $(top_builddir) && pwd` \
+	  && $(am__cd) $(top_srcdir) \
+	  && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+	list='$(am__tagged_files)'; \
+	case "$(srcdir)" in \
+	  [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+	  *) sdir=$(subdir)/$(srcdir) ;; \
+	esac; \
+	for i in $$list; do \
+	  if test -f "$$i"; then \
+	    echo "$(subdir)/$$i"; \
+	  else \
+	    echo "$$sdir/$$i"; \
+	  fi; \
+	done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	list='$(DISTFILES)'; \
+	  dist_files=`for file in $$list; do echo $$file; done | \
+	  sed -e "s|^$$srcdirstrip/||;t" \
+	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+	case $$dist_files in \
+	  */*) $(MKDIR_P) `echo "$$dist_files" | \
+			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+			   sort -u` ;; \
+	esac; \
+	for file in $$dist_files; do \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  if test -d $$d/$$file; then \
+	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+	    if test -d "$(distdir)/$$file"; then \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+	  else \
+	    test -f "$(distdir)/$$file" \
+	    || cp -p $$d/$$file "$(distdir)/$$file" \
+	    || exit 1; \
+	  fi; \
+	done
+check-am: all-am
+check: check-am
+all-am: Makefile $(HEADERS)
+installdirs:
+	for dir in "$(DESTDIR)$(kerneldir)"; do \
+	  test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+	done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+	if test -z '$(STRIP)'; then \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	      install; \
+	else \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+	fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-am
+	-rm -f Makefile
+distclean-am: clean-am distclean-generic distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-kernelHEADERS
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-kernelHEADERS
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \
+	clean-libtool cscopelist-am ctags ctags-am distclean \
+	distclean-generic distclean-libtool distclean-tags distdir dvi \
+	dvi-am html html-am info info-am install install-am \
+	install-data install-data-am install-dvi install-dvi-am \
+	install-exec install-exec-am install-html install-html-am \
+	install-info install-info-am install-kernelHEADERS install-man \
+	install-pdf install-pdf-am install-ps install-ps-am \
+	install-strip installcheck installcheck-am installdirs \
+	maintainer-clean maintainer-clean-generic mostlyclean \
+	mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+	tags tags-am uninstall uninstall-am uninstall-kernelHEADERS
+
+.PRECIOUS: Makefile
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/linux/bitops_compat.h
@@ -0,0 +1,31 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+\*****************************************************************************/
+
+#ifndef _SPL_BITOPS_COMPAT_H
+#define _SPL_BITOPS_COMPAT_H
+
+#include <linux/bitops.h>
+
+#endif /* _SPL_BITOPS_COMPAT_H */
+
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/linux/compiler_compat.h
@@ -0,0 +1,47 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+\*****************************************************************************/
+
+#ifndef _SPL_COMPILER_COMPAT_H
+#define _SPL_COMPILER_COMPAT_H
+
+#include <linux/compiler.h>
+
+#ifndef ACCESS_ONCE
+/*
+ * Prevent the compiler from merging or refetching accesses.  The compiler
+ * is also forbidden from reordering successive instances of ACCESS_ONCE(),
+ * but only when the compiler is aware of some particular ordering.  One way
+ * to make the compiler aware of ordering is to put the two invocations of
+ * ACCESS_ONCE() in different C statements.
+ *
+ * This macro does absolutely -nothing- to prevent the CPU from reordering,
+ * merging, or refetching absolutely anything at any time.  Its main intended
+ * use is to mediate communication between process-level code and irq/NMI
+ * handlers, all running on the same CPU.
+ */
+/* Taken from 2.6.33.2 */
+# define ACCESS_ONCE(x) (*(volatile typeof(x) *)&(x))
+#endif
+
+#endif /* _SPL_COMPILER_COMPAT_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/linux/delay_compat.h
@@ -0,0 +1,47 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2013 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+\*****************************************************************************/
+
+#ifndef _SPL_DELAY_COMPAT_H
+#define _SPL_DELAY_COMPAT_H
+
+#include <linux/delay.h>
+#include <linux/time.h>
+
+/* usleep_range() introduced in 2.6.36 */
+#ifndef HAVE_USLEEP_RANGE
+
+static inline void
+usleep_range(unsigned long min, unsigned long max)
+{
+	unsigned int min_ms = min / USEC_PER_MSEC;
+
+	if (min >= MAX_UDELAY_MS)
+		msleep(min_ms);
+	else
+		udelay(min);
+}
+
+#endif /* HAVE_USLEEP_RANGE */
+
+#endif /* _SPL_DELAY_COMPAT_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/linux/file_compat.h
@@ -0,0 +1,83 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+\*****************************************************************************/
+
+#ifndef _SPL_FILE_COMPAT_H
+#define _SPL_FILE_COMPAT_H
+
+#include <linux/fs.h>
+#ifdef HAVE_FDTABLE_HEADER
+#include <linux/fdtable.h>
+#endif
+
+static inline struct file *
+spl_filp_open(const char *name, int flags, int mode, int *err)
+{
+        struct file *filp = NULL;
+        int rc;
+
+        filp = filp_open(name, flags, mode);
+        if (IS_ERR(filp)) {
+                rc = PTR_ERR(filp);
+                if (err)
+                        *err = rc;
+                filp = NULL;
+        }
+        return filp;
+}
+
+#define spl_filp_close(f)		filp_close(f, NULL)
+#define spl_filp_poff(f)		(&(f)->f_pos)
+#define spl_filp_write(fp, b, s, p)	(fp)->f_op->write((fp), (b), (s), p)
+
+static inline int
+spl_filp_fallocate(struct file *fp, int mode, loff_t offset, loff_t len)
+{
+	int error = -EOPNOTSUPP;
+
+#ifdef HAVE_FILE_FALLOCATE
+	if (fp->f_op->fallocate)
+		error = fp->f_op->fallocate(fp, mode, offset, len);
+#else
+#ifdef HAVE_INODE_FALLOCATE
+	if (fp->f_dentry && fp->f_dentry->d_inode &&
+	    fp->f_dentry->d_inode->i_op->fallocate)
+		error = fp->f_dentry->d_inode->i_op->fallocate(
+		    fp->f_dentry->d_inode, mode, offset, len);
+#endif /* HAVE_INODE_FALLOCATE */
+#endif /*HAVE_FILE_FALLOCATE */
+
+	return (error);
+}
+
+#ifdef HAVE_2ARGS_VFS_FSYNC
+#define	spl_filp_fsync(fp, sync)	vfs_fsync(fp, sync)
+#else
+#define	spl_filp_fsync(fp, sync)	vfs_fsync(fp, (fp)->f_dentry, sync)
+#endif /* HAVE_2ARGS_VFS_FSYNC */
+
+#define	spl_inode_lock(ip)		mutex_lock(&(ip)->i_mutex)
+#define	spl_inode_unlock(ip)		mutex_unlock(&(ip)->i_mutex)
+
+#endif /* SPL_FILE_COMPAT_H */
+
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/linux/list_compat.h
@@ -0,0 +1,51 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+\*****************************************************************************/
+
+#ifndef _SPL_LIST_COMPAT_H
+#define _SPL_LIST_COMPAT_H
+
+#include <linux/list.h>
+
+#ifndef list_for_each_entry_safe_reverse
+
+/**
+ * list_for_each_entry_safe_reverse
+ * @pos:        the type * to use as a loop cursor.
+ * @n:          another type * to use as temporary storage
+ * @head:       the head for your list.
+ * @member:     the name of the list_struct within the struct.
+ *
+ * Iterate backwards over list of given type, safe against removal
+ * of list entry.
+ */
+#define list_for_each_entry_safe_reverse(pos, n, head, member)          \
+        for (pos = list_entry((head)->prev, typeof(*pos), member),      \
+                n = list_entry(pos->member.prev, typeof(*pos), member); \
+             &pos->member != (head);                                    \
+             pos = n, n = list_entry(n->member.prev, typeof(*n), member))
+
+#endif /* list_for_each_entry_safe_reverse */
+
+#endif /* SPL_LIST_COMPAT_H */
+
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/linux/math64_compat.h
@@ -0,0 +1,32 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+\*****************************************************************************/
+
+#ifndef _SPL_MATH64_COMPAT_H
+#define _SPL_MATH64_COMPAT_H
+
+#ifndef abs64
+#define abs64(x)	({ uint64_t t = (x) >> 63; ((x) ^ t) - t; })
+#endif
+
+#endif /* _SPL_MATH64_COMPAT_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/linux/mm_compat.h
@@ -0,0 +1,209 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+\*****************************************************************************/
+
+#ifndef _SPL_MM_COMPAT_H
+#define _SPL_MM_COMPAT_H
+
+#include <linux/mm.h>
+#include <linux/fs.h>
+
+#if !defined(HAVE_SHRINK_CONTROL_STRUCT)
+struct shrink_control {
+	gfp_t gfp_mask;
+	unsigned long nr_to_scan;
+};
+#endif /* HAVE_SHRINK_CONTROL_STRUCT */
+
+/*
+ * Due to frequent changes in the shrinker API the following
+ * compatibility wrappers should be used.  They are as follows:
+ *
+ * SPL_SHRINKER_DECLARE is used to declare the shrinker which is
+ * passed to spl_register_shrinker()/spl_unregister_shrinker().  Use
+ * shrinker_name to set the shrinker variable name, shrinker_callback
+ * to set the callback function, and seek_cost to define the cost of
+ * reclaiming an object.
+ *
+ *   SPL_SHRINKER_DECLARE(shrinker_name, shrinker_callback, seek_cost);
+ *
+ * SPL_SHRINKER_CALLBACK_FWD_DECLARE is used when a forward declaration
+ * of the shrinker callback function is required.  Only the callback
+ * function needs to be passed.
+ *
+ *   SPL_SHRINKER_CALLBACK_FWD_DECLARE(shrinker_callback);
+ *
+ * SPL_SHRINKER_CALLBACK_WRAPPER is used to declare the callback function
+ * which is registered with the shrinker.  This function will call your
+ * custom shrinker which must use the following prototype.  Notice the
+ * leading __'s, these must be appended to the callback_function name.
+ *
+ *   int  __shrinker_callback(struct shrinker *, struct shrink_control *)
+ *   SPL_SHRINKER_CALLBACK_WRAPPER(shrinker_callback);a
+ *
+ *
+ * Example:
+ *
+ * SPL_SHRINKER_CALLBACK_FWD_DECLARE(my_shrinker_fn);
+ * SPL_SHRINKER_DECLARE(my_shrinker, my_shrinker_fn, 1);
+ *
+ * static int
+ * __my_shrinker_fn(struct shrinker *shrink, struct shrink_control *sc)
+ * {
+ *	if (sc->nr_to_scan) {
+ *		...scan objects in the cache and reclaim them...
+ *	}
+ *
+ *	...calculate number of objects in the cache...
+ *
+ *	return (number of objects in the cache);
+ * }
+ * SPL_SHRINKER_CALLBACK_WRAPPER(my_shrinker_fn);
+ */
+
+#define	spl_register_shrinker(x)	register_shrinker(x)
+#define	spl_unregister_shrinker(x)	unregister_shrinker(x)
+
+/*
+ * Linux 2.6.23 - 2.6.34 Shrinker API Compatibility.
+ */
+#if defined(HAVE_2ARGS_OLD_SHRINKER_CALLBACK)
+#define	SPL_SHRINKER_DECLARE(s, x, y)					\
+static struct shrinker s = {						\
+	.shrink = x,							\
+	.seeks = y							\
+}
+
+#define	SPL_SHRINKER_CALLBACK_FWD_DECLARE(fn)				\
+static int fn(int nr_to_scan, unsigned int gfp_mask)
+
+#define	SPL_SHRINKER_CALLBACK_WRAPPER(fn)				\
+static int								\
+fn(int nr_to_scan, unsigned int gfp_mask)				\
+{									\
+	struct shrink_control sc;					\
+									\
+	sc.nr_to_scan = nr_to_scan;					\
+	sc.gfp_mask = gfp_mask;						\
+									\
+	return (__ ## fn(NULL, &sc));					\
+}
+
+/*
+ * Linux 2.6.35 to 2.6.39 Shrinker API Compatibility.
+ */
+#elif defined(HAVE_3ARGS_SHRINKER_CALLBACK)
+#define	SPL_SHRINKER_DECLARE(s, x, y)					\
+static struct shrinker s = {						\
+	.shrink = x,							\
+	.seeks = y							\
+}
+
+#define	SPL_SHRINKER_CALLBACK_FWD_DECLARE(fn)				\
+static int fn(struct shrinker *, int, unsigned int)
+
+#define	SPL_SHRINKER_CALLBACK_WRAPPER(fn)				\
+static int								\
+fn(struct shrinker *shrink, int nr_to_scan, unsigned int gfp_mask)	\
+{									\
+	struct shrink_control sc;					\
+									\
+	sc.nr_to_scan = nr_to_scan;					\
+	sc.gfp_mask = gfp_mask;						\
+									\
+	return (__ ## fn(shrink, &sc));					\
+}
+
+/*
+ * Linux 3.0 to 3.11 Shrinker API Compatibility.
+ */
+#elif defined(HAVE_2ARGS_NEW_SHRINKER_CALLBACK)
+#define	SPL_SHRINKER_DECLARE(s, x, y)					\
+static struct shrinker s = {						\
+	.shrink = x,							\
+	.seeks = y							\
+}
+
+#define	SPL_SHRINKER_CALLBACK_FWD_DECLARE(fn)				\
+static int fn(struct shrinker *, struct shrink_control *)
+
+#define	SPL_SHRINKER_CALLBACK_WRAPPER(fn)				\
+static int								\
+fn(struct shrinker *shrink, struct shrink_control *sc)			\
+{									\
+	return (__ ## fn(shrink, sc));					\
+}
+
+/*
+ * Linux 3.12 and later Shrinker API Compatibility.
+ */
+#elif defined(HAVE_SPLIT_SHRINKER_CALLBACK)
+#define	SPL_SHRINKER_DECLARE(s, x, y)					\
+static struct shrinker s = {						\
+	.count_objects = x ## _count_objects,				\
+	.scan_objects = x ## _scan_objects,				\
+	.seeks = y							\
+}
+
+#define	SPL_SHRINKER_CALLBACK_FWD_DECLARE(fn)				\
+static unsigned long fn ## _count_objects(struct shrinker *,		\
+    struct shrink_control *);						\
+static unsigned long fn ## _scan_objects(struct shrinker *,		\
+    struct shrink_control *)
+
+#define	SPL_SHRINKER_CALLBACK_WRAPPER(fn)				\
+static unsigned long							\
+fn ## _count_objects(struct shrinker *shrink, struct shrink_control *sc)\
+{									\
+	int __ret__;							\
+									\
+	sc->nr_to_scan = 0;						\
+	__ret__ = __ ## fn(NULL, sc);					\
+									\
+	/* Errors may not be returned and must be converted to zeros */	\
+	return ((__ret__ < 0) ? 0 : __ret__);				\
+}									\
+									\
+static unsigned long							\
+fn ## _scan_objects(struct shrinker *shrink, struct shrink_control *sc)	\
+{									\
+	int __ret__;							\
+									\
+	__ret__ = __ ## fn(NULL, sc);					\
+	return ((__ret__ < 0) ? SHRINK_STOP : __ret__);			\
+}
+#else
+/*
+ * Linux 2.x to 2.6.22, or a newer shrinker API has been introduced.
+ */
+#error "Unknown shrinker callback"
+#endif
+
+#if defined(HAVE_SPLIT_SHRINKER_CALLBACK)
+typedef unsigned long	spl_shrinker_t;
+#else
+typedef int		spl_shrinker_t;
+#define	SHRINK_STOP	(-1)
+#endif
+
+#endif /* SPL_MM_COMPAT_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/linux/proc_compat.h
@@ -0,0 +1,35 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+\*****************************************************************************/
+
+#ifndef _SPL_PROC_COMPAT_H
+#define _SPL_PROC_COMPAT_H
+
+#include <linux/proc_fs.h>
+
+extern struct proc_dir_entry *proc_spl_kstat;
+
+int spl_proc_init(void);
+void spl_proc_fini(void);
+
+#endif /* SPL_PROC_COMPAT_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/linux/rwsem_compat.h
@@ -0,0 +1,42 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+\*****************************************************************************/
+
+#ifndef _SPL_RWSEM_COMPAT_H
+#define _SPL_RWSEM_COMPAT_H
+
+#include <linux/rwsem.h>
+
+#if defined(RWSEM_SPINLOCK_IS_RAW)
+#define spl_rwsem_lock_irqsave(lk, fl)       raw_spin_lock_irqsave(lk, fl)
+#define spl_rwsem_unlock_irqrestore(lk, fl)  raw_spin_unlock_irqrestore(lk, fl)
+#define spl_rwsem_trylock_irqsave(lk, fl)    raw_spin_trylock_irqsave(lk, fl)
+#else
+#define spl_rwsem_lock_irqsave(lk, fl)       spin_lock_irqsave(lk, fl)
+#define spl_rwsem_unlock_irqrestore(lk, fl)  spin_unlock_irqrestore(lk, fl)
+#define spl_rwsem_trylock_irqsave(lk, fl)    spin_trylock_irqsave(lk, fl)
+#endif /* RWSEM_SPINLOCK_IS_RAW */
+
+#define spl_rwsem_is_locked(rwsem)           rwsem_is_locked(rwsem)
+
+#endif /* _SPL_RWSEM_COMPAT_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/linux/wait_compat.h
@@ -0,0 +1,46 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2014 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+\*****************************************************************************/
+
+#ifndef _SPL_WAIT_COMPAT_H
+#define _SPL_WAIT_COMPAT_H
+
+#include <linux/sched.h>
+
+#ifndef HAVE_WAIT_ON_BIT_ACTION
+#  define spl_wait_on_bit(word, bit, mode) wait_on_bit(word, bit, mode)
+#else
+
+static inline int
+spl_bit_wait(void *word)
+{
+        schedule();
+        return 0;
+}
+
+#define spl_wait_on_bit(word, bit, mode)			\
+	wait_on_bit(word, bit, spl_bit_wait, mode)
+
+#endif /* HAVE_WAIT_ON_BIT_ACTION */
+
+#endif /* SPL_WAIT_COMPAT_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/linux/zlib_compat.h
@@ -0,0 +1,37 @@
+/*****************************************************************************\
+ *  Copyright (C) 2011 Lawrence Livermore National Security, LLC.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+\*****************************************************************************/
+
+#ifndef _SPL_ZLIB_COMPAT_H
+#define _SPL_ZLIB_COMPAT_H
+
+#include <linux/zlib.h>
+
+#ifdef HAVE_2ARGS_ZLIB_DEFLATE_WORKSPACESIZE
+#define spl_zlib_deflate_workspacesize(wb, ml) \
+	zlib_deflate_workspacesize(wb, ml)
+#else
+#define spl_zlib_deflate_workspacesize(wb, ml) \
+	zlib_deflate_workspacesize()
+#endif /* HAVE_2ARGS_ZLIB_DEFLATE_WORKSPACESIZE */
+
+#endif /* SPL_ZLIB_COMPAT_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/rpc/Makefile.am
@@ -0,0 +1,14 @@
+COMMON_H =
+
+KERNEL_H = \
+	$(top_srcdir)/include/rpc/types.h \
+	$(top_srcdir)/include/rpc/xdr.h
+
+USER_H =
+
+EXTRA_DIST = $(COMMON_H) $(KERNEL_H) $(USER_H)
+
+if CONFIG_KERNEL
+kerneldir = @prefix@/src/spl-$(VERSION)/include/rpc
+kernel_HEADERS = $(KERNEL_H)
+endif
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/rpc/Makefile.in
@@ -0,0 +1,623 @@
+# Makefile.in generated by automake 1.15 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2014 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+VPATH = @srcdir@
+am__is_gnu_make = { \
+  if test -z '$(MAKELEVEL)'; then \
+    false; \
+  elif test -n '$(MAKE_HOST)'; then \
+    true; \
+  elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+    true; \
+  else \
+    false; \
+  fi; \
+}
+am__make_running_with_option = \
+  case $${target_option-} in \
+      ?) ;; \
+      *) echo "am__make_running_with_option: internal error: invalid" \
+              "target option '$${target_option-}' specified" >&2; \
+         exit 1;; \
+  esac; \
+  has_opt=no; \
+  sane_makeflags=$$MAKEFLAGS; \
+  if $(am__is_gnu_make); then \
+    sane_makeflags=$$MFLAGS; \
+  else \
+    case $$MAKEFLAGS in \
+      *\\[\ \	]*) \
+        bs=\\; \
+        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
+    esac; \
+  fi; \
+  skip_next=no; \
+  strip_trailopt () \
+  { \
+    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+  }; \
+  for flg in $$sane_makeflags; do \
+    test $$skip_next = yes && { skip_next=no; continue; }; \
+    case $$flg in \
+      *=*|--*) continue;; \
+        -*I) strip_trailopt 'I'; skip_next=yes;; \
+      -*I?*) strip_trailopt 'I';; \
+        -*O) strip_trailopt 'O'; skip_next=yes;; \
+      -*O?*) strip_trailopt 'O';; \
+        -*l) strip_trailopt 'l'; skip_next=yes;; \
+      -*l?*) strip_trailopt 'l';; \
+      -[dEDm]) skip_next=yes;; \
+      -[JT]) skip_next=yes;; \
+    esac; \
+    case $$flg in \
+      *$$target_option*) has_opt=yes; break;; \
+    esac; \
+  done; \
+  test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+target_triplet = @target@
+subdir = include/rpc
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/config/libtool.m4 \
+	$(top_srcdir)/config/ltoptions.m4 \
+	$(top_srcdir)/config/ltsugar.m4 \
+	$(top_srcdir)/config/ltversion.m4 \
+	$(top_srcdir)/config/lt~obsolete.m4 \
+	$(top_srcdir)/config/spl-build.m4 \
+	$(top_srcdir)/config/spl-meta.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(am__kernel_HEADERS_DIST) \
+	$(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/spl_config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo "  GEN     " $@;
+am__v_GEN_1 = 
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 = 
+SOURCES =
+DIST_SOURCES =
+am__can_run_installinfo = \
+  case $$AM_UPDATE_INFO_DIR in \
+    n|no|NO) false;; \
+    *) (install-info --version) >/dev/null 2>&1;; \
+  esac
+am__kernel_HEADERS_DIST = $(top_srcdir)/include/rpc/types.h \
+	$(top_srcdir)/include/rpc/xdr.h
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+    $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+    *) f=$$p;; \
+  esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+  srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+  for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+  for p in $$list; do echo "$$p $$p"; done | \
+  sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+  $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+    if (++n[$$2] == $(am__install_max)) \
+      { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+    END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+  sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+  sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+  test -z "$$files" \
+    || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+    || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+         $(am__cd) "$$dir" && rm -f $$files; }; \
+  }
+am__installdirs = "$(DESTDIR)$(kerneldir)"
+HEADERS = $(kernel_HEADERS)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates.  Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+  BEGIN { nonempty = 0; } \
+  { items[$$0] = 1; nonempty = 1; } \
+  END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique.  This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+  list='$(am__tagged_files)'; \
+  unique=`for i in $$list; do \
+    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+  done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+am__DIST_COMMON = $(srcdir)/Makefile.in
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ALIEN = @ALIEN@
+ALIEN_VERSION = @ALIEN_VERSION@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEBUG_CFLAGS = @DEBUG_CFLAGS@
+DEBUG_KMEM = @DEBUG_KMEM@
+DEBUG_KMEM_TRACKING = @DEBUG_KMEM_TRACKING@
+DEBUG_SPL = @DEBUG_SPL@
+DEFAULT_PACKAGE = @DEFAULT_PACKAGE@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DPKG = @DPKG@
+DPKGBUILD = @DPKGBUILD@
+DPKGBUILD_VERSION = @DPKGBUILD_VERSION@
+DPKG_VERSION = @DPKG_VERSION@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GREP = @GREP@
+HAVE_ALIEN = @HAVE_ALIEN@
+HAVE_DPKG = @HAVE_DPKG@
+HAVE_DPKGBUILD = @HAVE_DPKGBUILD@
+HAVE_RPM = @HAVE_RPM@
+HAVE_RPMBUILD = @HAVE_RPMBUILD@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+KERNELCPPFLAGS = @KERNELCPPFLAGS@
+KERNELMAKE_PARAMS = @KERNELMAKE_PARAMS@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LINUX = @LINUX@
+LINUX_OBJ = @LINUX_OBJ@
+LINUX_SYMBOLS = @LINUX_SYMBOLS@
+LINUX_VERSION = @LINUX_VERSION@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+RANLIB = @RANLIB@
+RELEASE = @RELEASE@
+RPM = @RPM@
+RPMBUILD = @RPMBUILD@
+RPMBUILD_VERSION = @RPMBUILD_VERSION@
+RPM_DEFINE_COMMON = @RPM_DEFINE_COMMON@
+RPM_DEFINE_DKMS = @RPM_DEFINE_DKMS@
+RPM_DEFINE_KMOD = @RPM_DEFINE_KMOD@
+RPM_DEFINE_UTIL = @RPM_DEFINE_UTIL@
+RPM_SPEC_DIR = @RPM_SPEC_DIR@
+RPM_VERSION = @RPM_VERSION@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SPL_CONFIG = @SPL_CONFIG@
+SPL_META_ALIAS = @SPL_META_ALIAS@
+SPL_META_AUTHOR = @SPL_META_AUTHOR@
+SPL_META_DATA = @SPL_META_DATA@
+SPL_META_LICENSE = @SPL_META_LICENSE@
+SPL_META_LT_AGE = @SPL_META_LT_AGE@
+SPL_META_LT_CURRENT = @SPL_META_LT_CURRENT@
+SPL_META_LT_REVISION = @SPL_META_LT_REVISION@
+SPL_META_NAME = @SPL_META_NAME@
+SPL_META_RELEASE = @SPL_META_RELEASE@
+SPL_META_VERSION = @SPL_META_VERSION@
+SRPM_DEFINE_COMMON = @SRPM_DEFINE_COMMON@
+SRPM_DEFINE_DKMS = @SRPM_DEFINE_DKMS@
+SRPM_DEFINE_KMOD = @SRPM_DEFINE_KMOD@
+SRPM_DEFINE_UTIL = @SRPM_DEFINE_UTIL@
+STRIP = @STRIP@
+VENDOR = @VENDOR@
+VERSION = @VERSION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+runstatedir = @runstatedir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+COMMON_H = 
+KERNEL_H = \
+	$(top_srcdir)/include/rpc/types.h \
+	$(top_srcdir)/include/rpc/xdr.h
+
+USER_H = 
+EXTRA_DIST = $(COMMON_H) $(KERNEL_H) $(USER_H)
+@CONFIG_KERNEL_TRUE@kerneldir = @prefix@/src/spl-$(VERSION)/include/rpc
+@CONFIG_KERNEL_TRUE@kernel_HEADERS = $(KERNEL_H)
+all: all-am
+
+.SUFFIXES:
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+	        && { if test -f $@; then exit 0; else break; fi; }; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu include/rpc/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --gnu include/rpc/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+	esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
+install-kernelHEADERS: $(kernel_HEADERS)
+	@$(NORMAL_INSTALL)
+	@list='$(kernel_HEADERS)'; test -n "$(kerneldir)" || list=; \
+	if test -n "$$list"; then \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(kerneldir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(kerneldir)" || exit 1; \
+	fi; \
+	for p in $$list; do \
+	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+	  echo "$$d$$p"; \
+	done | $(am__base_list) | \
+	while read files; do \
+	  echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(kerneldir)'"; \
+	  $(INSTALL_HEADER) $$files "$(DESTDIR)$(kerneldir)" || exit $$?; \
+	done
+
+uninstall-kernelHEADERS:
+	@$(NORMAL_UNINSTALL)
+	@list='$(kernel_HEADERS)'; test -n "$(kerneldir)" || list=; \
+	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+	dir='$(DESTDIR)$(kerneldir)'; $(am__uninstall_files_from_dir)
+
+ID: $(am__tagged_files)
+	$(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	set x; \
+	here=`pwd`; \
+	$(am__define_uniq_tagged_files); \
+	shift; \
+	if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+	  test -n "$$unique" || unique=$$empty_fix; \
+	  if test $$# -gt 0; then \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      "$$@" $$unique; \
+	  else \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      $$unique; \
+	  fi; \
+	fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	$(am__define_uniq_tagged_files); \
+	test -z "$(CTAGS_ARGS)$$unique" \
+	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+	     $$unique
+
+GTAGS:
+	here=`$(am__cd) $(top_builddir) && pwd` \
+	  && $(am__cd) $(top_srcdir) \
+	  && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+	list='$(am__tagged_files)'; \
+	case "$(srcdir)" in \
+	  [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+	  *) sdir=$(subdir)/$(srcdir) ;; \
+	esac; \
+	for i in $$list; do \
+	  if test -f "$$i"; then \
+	    echo "$(subdir)/$$i"; \
+	  else \
+	    echo "$$sdir/$$i"; \
+	  fi; \
+	done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	list='$(DISTFILES)'; \
+	  dist_files=`for file in $$list; do echo $$file; done | \
+	  sed -e "s|^$$srcdirstrip/||;t" \
+	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+	case $$dist_files in \
+	  */*) $(MKDIR_P) `echo "$$dist_files" | \
+			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+			   sort -u` ;; \
+	esac; \
+	for file in $$dist_files; do \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  if test -d $$d/$$file; then \
+	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+	    if test -d "$(distdir)/$$file"; then \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+	  else \
+	    test -f "$(distdir)/$$file" \
+	    || cp -p $$d/$$file "$(distdir)/$$file" \
+	    || exit 1; \
+	  fi; \
+	done
+check-am: all-am
+check: check-am
+all-am: Makefile $(HEADERS)
+installdirs:
+	for dir in "$(DESTDIR)$(kerneldir)"; do \
+	  test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+	done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+	if test -z '$(STRIP)'; then \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	      install; \
+	else \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+	fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-am
+	-rm -f Makefile
+distclean-am: clean-am distclean-generic distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-kernelHEADERS
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-kernelHEADERS
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \
+	clean-libtool cscopelist-am ctags ctags-am distclean \
+	distclean-generic distclean-libtool distclean-tags distdir dvi \
+	dvi-am html html-am info info-am install install-am \
+	install-data install-data-am install-dvi install-dvi-am \
+	install-exec install-exec-am install-html install-html-am \
+	install-info install-info-am install-kernelHEADERS install-man \
+	install-pdf install-pdf-am install-ps install-ps-am \
+	install-strip installcheck installcheck-am installdirs \
+	maintainer-clean maintainer-clean-generic mostlyclean \
+	mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+	tags tags-am uninstall uninstall-am uninstall-kernelHEADERS
+
+.PRECIOUS: Makefile
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/rpc/types.h
@@ -0,0 +1,30 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+\*****************************************************************************/
+
+#ifndef _SPL_RPC_TYPES_H
+#define _SPL_RPC_TYPES_H
+
+typedef int bool_t;
+
+#endif /* SPL_RPC_TYPES_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/rpc/xdr.h
@@ -0,0 +1,155 @@
+/*****************************************************************************\
+ *  Copyright (c) 2008 Sun Microsystems, Inc.
+ *  Written by Ricardo Correia <Ricardo.M.Correia@Sun.COM>
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+\*****************************************************************************/
+
+#ifndef _SPL_RPC_XDR_H
+#define _SPL_RPC_XDR_H
+
+#include <sys/types.h>
+#include <rpc/types.h>
+
+/*
+ * XDR enums and types.
+ */
+enum xdr_op {
+	XDR_ENCODE,
+	XDR_DECODE
+};
+
+struct xdr_ops;
+
+typedef struct {
+	struct xdr_ops *x_ops;      /* Also used to let caller know if
+	                               xdrmem_create() succeeds (sigh..) */
+	caddr_t         x_addr;     /* Current buffer addr */
+	caddr_t         x_addr_end; /* End of the buffer */
+	enum xdr_op     x_op;       /* Stream direction */
+} XDR;
+
+typedef bool_t (*xdrproc_t)(XDR *xdrs, void *ptr);
+
+struct xdr_ops {
+	bool_t (*xdr_control)(XDR *, int, void *);
+
+	bool_t (*xdr_char)(XDR *, char *);
+	bool_t (*xdr_u_short)(XDR *, unsigned short *);
+	bool_t (*xdr_u_int)(XDR *, unsigned *);
+	bool_t (*xdr_u_longlong_t)(XDR *, u_longlong_t *);
+
+	bool_t (*xdr_opaque)(XDR *, caddr_t, const uint_t);
+	bool_t (*xdr_string)(XDR *, char **, const uint_t);
+	bool_t (*xdr_array)(XDR *, caddr_t *, uint_t *, const uint_t,
+	                    const uint_t, const xdrproc_t);
+};
+
+/*
+ * XDR control operator.
+ */
+#define XDR_GET_BYTES_AVAIL 1
+
+struct xdr_bytesrec {
+	bool_t xc_is_last_record;
+	size_t xc_num_avail;
+};
+
+/*
+ * XDR functions.
+ */
+void xdrmem_create(XDR *xdrs, const caddr_t addr, const uint_t size,
+    const enum xdr_op op);
+#define xdr_destroy(xdrs) ((void) 0) /* Currently not needed. If needed later,
+                                        we'll add it to struct xdr_ops */
+
+#define xdr_control(xdrs, req, info) (xdrs)->x_ops->xdr_control((xdrs),        \
+                                         (req), (info))
+
+/*
+ * For precaution, the following are defined as static inlines instead of macros
+ * to get some amount of type safety.
+ *
+ * Also, macros wouldn't work in the case where typecasting is done, because it
+ * must be possible to reference the functions' addresses by these names.
+ */
+static inline bool_t xdr_char(XDR *xdrs, char *cp)
+{
+	return xdrs->x_ops->xdr_char(xdrs, cp);
+}
+
+static inline bool_t xdr_u_short(XDR *xdrs, unsigned short *usp)
+{
+	return xdrs->x_ops->xdr_u_short(xdrs, usp);
+}
+
+static inline bool_t xdr_short(XDR *xdrs, short *sp)
+{
+	BUILD_BUG_ON(sizeof(short) != 2);
+	return xdrs->x_ops->xdr_u_short(xdrs, (unsigned short *) sp);
+}
+
+static inline bool_t xdr_u_int(XDR *xdrs, unsigned *up)
+{
+	return xdrs->x_ops->xdr_u_int(xdrs, up);
+}
+
+static inline bool_t xdr_int(XDR *xdrs, int *ip)
+{
+	BUILD_BUG_ON(sizeof(int) != 4);
+	return xdrs->x_ops->xdr_u_int(xdrs, (unsigned *) ip);
+}
+
+static inline bool_t xdr_u_longlong_t(XDR *xdrs, u_longlong_t *ullp)
+{
+	return xdrs->x_ops->xdr_u_longlong_t(xdrs, ullp);
+}
+
+static inline bool_t xdr_longlong_t(XDR *xdrs, longlong_t *llp)
+{
+	BUILD_BUG_ON(sizeof(longlong_t) != 8);
+	return xdrs->x_ops->xdr_u_longlong_t(xdrs, (u_longlong_t *) llp);
+}
+
+/*
+ * Fixed-length opaque data.
+ */
+static inline bool_t xdr_opaque(XDR *xdrs, caddr_t cp, const uint_t cnt)
+{
+	return xdrs->x_ops->xdr_opaque(xdrs, cp, cnt);
+}
+
+/*
+ * Variable-length string.
+ * The *sp buffer must have (maxsize + 1) bytes.
+ */
+static inline bool_t xdr_string(XDR *xdrs, char **sp, const uint_t maxsize)
+{
+	return xdrs->x_ops->xdr_string(xdrs, sp, maxsize);
+}
+
+/*
+ * Variable-length arrays.
+ */
+static inline bool_t xdr_array(XDR *xdrs, caddr_t *arrp, uint_t *sizep,
+    const uint_t maxsize, const uint_t elsize, const xdrproc_t elproc)
+{
+	return xdrs->x_ops->xdr_array(xdrs, arrp, sizep, maxsize, elsize,
+	    elproc);
+}
+
+#endif /* SPL_RPC_XDR_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/sharefs/Makefile.am
@@ -0,0 +1,13 @@
+COMMON_H =
+
+KERNEL_H = \
+	$(top_srcdir)/include/sharefs/share.h
+
+USER_H =
+
+EXTRA_DIST = $(COMMON_H) $(KERNEL_H) $(USER_H)
+
+if CONFIG_KERNEL
+kerneldir = @prefix@/src/spl-$(VERSION)/include/sharefs
+kernel_HEADERS = $(KERNEL_H)
+endif
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/sharefs/Makefile.in
@@ -0,0 +1,621 @@
+# Makefile.in generated by automake 1.15 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2014 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+VPATH = @srcdir@
+am__is_gnu_make = { \
+  if test -z '$(MAKELEVEL)'; then \
+    false; \
+  elif test -n '$(MAKE_HOST)'; then \
+    true; \
+  elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+    true; \
+  else \
+    false; \
+  fi; \
+}
+am__make_running_with_option = \
+  case $${target_option-} in \
+      ?) ;; \
+      *) echo "am__make_running_with_option: internal error: invalid" \
+              "target option '$${target_option-}' specified" >&2; \
+         exit 1;; \
+  esac; \
+  has_opt=no; \
+  sane_makeflags=$$MAKEFLAGS; \
+  if $(am__is_gnu_make); then \
+    sane_makeflags=$$MFLAGS; \
+  else \
+    case $$MAKEFLAGS in \
+      *\\[\ \	]*) \
+        bs=\\; \
+        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
+    esac; \
+  fi; \
+  skip_next=no; \
+  strip_trailopt () \
+  { \
+    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+  }; \
+  for flg in $$sane_makeflags; do \
+    test $$skip_next = yes && { skip_next=no; continue; }; \
+    case $$flg in \
+      *=*|--*) continue;; \
+        -*I) strip_trailopt 'I'; skip_next=yes;; \
+      -*I?*) strip_trailopt 'I';; \
+        -*O) strip_trailopt 'O'; skip_next=yes;; \
+      -*O?*) strip_trailopt 'O';; \
+        -*l) strip_trailopt 'l'; skip_next=yes;; \
+      -*l?*) strip_trailopt 'l';; \
+      -[dEDm]) skip_next=yes;; \
+      -[JT]) skip_next=yes;; \
+    esac; \
+    case $$flg in \
+      *$$target_option*) has_opt=yes; break;; \
+    esac; \
+  done; \
+  test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+target_triplet = @target@
+subdir = include/sharefs
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/config/libtool.m4 \
+	$(top_srcdir)/config/ltoptions.m4 \
+	$(top_srcdir)/config/ltsugar.m4 \
+	$(top_srcdir)/config/ltversion.m4 \
+	$(top_srcdir)/config/lt~obsolete.m4 \
+	$(top_srcdir)/config/spl-build.m4 \
+	$(top_srcdir)/config/spl-meta.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(am__kernel_HEADERS_DIST) \
+	$(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/spl_config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo "  GEN     " $@;
+am__v_GEN_1 = 
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 = 
+SOURCES =
+DIST_SOURCES =
+am__can_run_installinfo = \
+  case $$AM_UPDATE_INFO_DIR in \
+    n|no|NO) false;; \
+    *) (install-info --version) >/dev/null 2>&1;; \
+  esac
+am__kernel_HEADERS_DIST = $(top_srcdir)/include/sharefs/share.h
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+    $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+    *) f=$$p;; \
+  esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+  srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+  for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+  for p in $$list; do echo "$$p $$p"; done | \
+  sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+  $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+    if (++n[$$2] == $(am__install_max)) \
+      { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+    END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+  sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+  sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+  test -z "$$files" \
+    || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+    || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+         $(am__cd) "$$dir" && rm -f $$files; }; \
+  }
+am__installdirs = "$(DESTDIR)$(kerneldir)"
+HEADERS = $(kernel_HEADERS)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates.  Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+  BEGIN { nonempty = 0; } \
+  { items[$$0] = 1; nonempty = 1; } \
+  END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique.  This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+  list='$(am__tagged_files)'; \
+  unique=`for i in $$list; do \
+    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+  done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+am__DIST_COMMON = $(srcdir)/Makefile.in
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ALIEN = @ALIEN@
+ALIEN_VERSION = @ALIEN_VERSION@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEBUG_CFLAGS = @DEBUG_CFLAGS@
+DEBUG_KMEM = @DEBUG_KMEM@
+DEBUG_KMEM_TRACKING = @DEBUG_KMEM_TRACKING@
+DEBUG_SPL = @DEBUG_SPL@
+DEFAULT_PACKAGE = @DEFAULT_PACKAGE@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DPKG = @DPKG@
+DPKGBUILD = @DPKGBUILD@
+DPKGBUILD_VERSION = @DPKGBUILD_VERSION@
+DPKG_VERSION = @DPKG_VERSION@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GREP = @GREP@
+HAVE_ALIEN = @HAVE_ALIEN@
+HAVE_DPKG = @HAVE_DPKG@
+HAVE_DPKGBUILD = @HAVE_DPKGBUILD@
+HAVE_RPM = @HAVE_RPM@
+HAVE_RPMBUILD = @HAVE_RPMBUILD@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+KERNELCPPFLAGS = @KERNELCPPFLAGS@
+KERNELMAKE_PARAMS = @KERNELMAKE_PARAMS@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LINUX = @LINUX@
+LINUX_OBJ = @LINUX_OBJ@
+LINUX_SYMBOLS = @LINUX_SYMBOLS@
+LINUX_VERSION = @LINUX_VERSION@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+RANLIB = @RANLIB@
+RELEASE = @RELEASE@
+RPM = @RPM@
+RPMBUILD = @RPMBUILD@
+RPMBUILD_VERSION = @RPMBUILD_VERSION@
+RPM_DEFINE_COMMON = @RPM_DEFINE_COMMON@
+RPM_DEFINE_DKMS = @RPM_DEFINE_DKMS@
+RPM_DEFINE_KMOD = @RPM_DEFINE_KMOD@
+RPM_DEFINE_UTIL = @RPM_DEFINE_UTIL@
+RPM_SPEC_DIR = @RPM_SPEC_DIR@
+RPM_VERSION = @RPM_VERSION@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SPL_CONFIG = @SPL_CONFIG@
+SPL_META_ALIAS = @SPL_META_ALIAS@
+SPL_META_AUTHOR = @SPL_META_AUTHOR@
+SPL_META_DATA = @SPL_META_DATA@
+SPL_META_LICENSE = @SPL_META_LICENSE@
+SPL_META_LT_AGE = @SPL_META_LT_AGE@
+SPL_META_LT_CURRENT = @SPL_META_LT_CURRENT@
+SPL_META_LT_REVISION = @SPL_META_LT_REVISION@
+SPL_META_NAME = @SPL_META_NAME@
+SPL_META_RELEASE = @SPL_META_RELEASE@
+SPL_META_VERSION = @SPL_META_VERSION@
+SRPM_DEFINE_COMMON = @SRPM_DEFINE_COMMON@
+SRPM_DEFINE_DKMS = @SRPM_DEFINE_DKMS@
+SRPM_DEFINE_KMOD = @SRPM_DEFINE_KMOD@
+SRPM_DEFINE_UTIL = @SRPM_DEFINE_UTIL@
+STRIP = @STRIP@
+VENDOR = @VENDOR@
+VERSION = @VERSION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+runstatedir = @runstatedir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+COMMON_H = 
+KERNEL_H = \
+	$(top_srcdir)/include/sharefs/share.h
+
+USER_H = 
+EXTRA_DIST = $(COMMON_H) $(KERNEL_H) $(USER_H)
+@CONFIG_KERNEL_TRUE@kerneldir = @prefix@/src/spl-$(VERSION)/include/sharefs
+@CONFIG_KERNEL_TRUE@kernel_HEADERS = $(KERNEL_H)
+all: all-am
+
+.SUFFIXES:
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+	        && { if test -f $@; then exit 0; else break; fi; }; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu include/sharefs/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --gnu include/sharefs/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+	esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
+install-kernelHEADERS: $(kernel_HEADERS)
+	@$(NORMAL_INSTALL)
+	@list='$(kernel_HEADERS)'; test -n "$(kerneldir)" || list=; \
+	if test -n "$$list"; then \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(kerneldir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(kerneldir)" || exit 1; \
+	fi; \
+	for p in $$list; do \
+	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+	  echo "$$d$$p"; \
+	done | $(am__base_list) | \
+	while read files; do \
+	  echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(kerneldir)'"; \
+	  $(INSTALL_HEADER) $$files "$(DESTDIR)$(kerneldir)" || exit $$?; \
+	done
+
+uninstall-kernelHEADERS:
+	@$(NORMAL_UNINSTALL)
+	@list='$(kernel_HEADERS)'; test -n "$(kerneldir)" || list=; \
+	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+	dir='$(DESTDIR)$(kerneldir)'; $(am__uninstall_files_from_dir)
+
+ID: $(am__tagged_files)
+	$(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	set x; \
+	here=`pwd`; \
+	$(am__define_uniq_tagged_files); \
+	shift; \
+	if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+	  test -n "$$unique" || unique=$$empty_fix; \
+	  if test $$# -gt 0; then \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      "$$@" $$unique; \
+	  else \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      $$unique; \
+	  fi; \
+	fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	$(am__define_uniq_tagged_files); \
+	test -z "$(CTAGS_ARGS)$$unique" \
+	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+	     $$unique
+
+GTAGS:
+	here=`$(am__cd) $(top_builddir) && pwd` \
+	  && $(am__cd) $(top_srcdir) \
+	  && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+	list='$(am__tagged_files)'; \
+	case "$(srcdir)" in \
+	  [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+	  *) sdir=$(subdir)/$(srcdir) ;; \
+	esac; \
+	for i in $$list; do \
+	  if test -f "$$i"; then \
+	    echo "$(subdir)/$$i"; \
+	  else \
+	    echo "$$sdir/$$i"; \
+	  fi; \
+	done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	list='$(DISTFILES)'; \
+	  dist_files=`for file in $$list; do echo $$file; done | \
+	  sed -e "s|^$$srcdirstrip/||;t" \
+	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+	case $$dist_files in \
+	  */*) $(MKDIR_P) `echo "$$dist_files" | \
+			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+			   sort -u` ;; \
+	esac; \
+	for file in $$dist_files; do \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  if test -d $$d/$$file; then \
+	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+	    if test -d "$(distdir)/$$file"; then \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+	  else \
+	    test -f "$(distdir)/$$file" \
+	    || cp -p $$d/$$file "$(distdir)/$$file" \
+	    || exit 1; \
+	  fi; \
+	done
+check-am: all-am
+check: check-am
+all-am: Makefile $(HEADERS)
+installdirs:
+	for dir in "$(DESTDIR)$(kerneldir)"; do \
+	  test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+	done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+	if test -z '$(STRIP)'; then \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	      install; \
+	else \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+	fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-am
+	-rm -f Makefile
+distclean-am: clean-am distclean-generic distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-kernelHEADERS
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-kernelHEADERS
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \
+	clean-libtool cscopelist-am ctags ctags-am distclean \
+	distclean-generic distclean-libtool distclean-tags distdir dvi \
+	dvi-am html html-am info info-am install install-am \
+	install-data install-data-am install-dvi install-dvi-am \
+	install-exec install-exec-am install-html install-html-am \
+	install-info install-info-am install-kernelHEADERS install-man \
+	install-pdf install-pdf-am install-ps install-ps-am \
+	install-strip installcheck installcheck-am installdirs \
+	maintainer-clean maintainer-clean-generic mostlyclean \
+	mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+	tags tags-am uninstall uninstall-am uninstall-kernelHEADERS
+
+.PRECIOUS: Makefile
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/sharefs/share.h
@@ -0,0 +1,28 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+\*****************************************************************************/
+
+#ifndef _SPL_SHARE_H
+#define _SPL_SHARE_H
+
+#endif /* SPL_SHARE_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/spl-ctl.h
@@ -0,0 +1,45 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+\*****************************************************************************/
+
+#ifndef _DEBUG_CTL_H
+#define _DEBUG_CTL_H
+
+/*
+ * Contains shared definitions which both the user space
+ * and kernel space portions of splat must agree on.
+ */
+typedef struct spl_debug_header {
+        int ph_len;
+        int ph_flags;
+        int ph_subsys;
+        int ph_mask;
+        int ph_cpu_id;
+        int ph_sec;
+        long ph_usec;
+        int ph_stack;
+        int ph_pid;
+        int ph_line_num;
+} spl_debug_header_t;
+
+#endif /* _DEBUG_CTL_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/splat-ctl.h
@@ -0,0 +1,109 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+\*****************************************************************************/
+
+#ifndef _SPLAT_CTL_H
+#define _SPLAT_CTL_H
+
+#include <linux/types.h>
+
+/*
+ * Contains shared definitions for both user space and kernel space.  To
+ * ensure 32-bit/64-bit interoperability over ioctl()'s only types with
+ * fixed sizes can be used.
+ */
+#define SPLAT_NAME			"splatctl"
+#define SPLAT_DEV			"/dev/splatctl"
+
+#define SPLAT_NAME_SIZE			20
+#define SPLAT_DESC_SIZE			60
+
+typedef struct splat_user {
+	char name[SPLAT_NAME_SIZE];	/* Short name */
+	char desc[SPLAT_DESC_SIZE];	/* Short description */
+	__u32 id;			/* Unique numeric id */
+} splat_user_t;
+
+#define	SPLAT_CFG_MAGIC			0x15263748U
+typedef struct splat_cfg {
+	__u32 cfg_magic;		/* Unique magic */
+	__u32 cfg_cmd;			/* Configure command */
+	__s32 cfg_arg1;			/* Configure command arg 1 */
+	__s32 cfg_rc1;			/* Configure response 1 */
+	union {
+		struct {
+			__u32 size;
+			splat_user_t descs[0];
+		} splat_subsystems;
+		struct {
+			__u32 size;
+			splat_user_t descs[0];
+		} splat_tests;
+	} cfg_data;
+} splat_cfg_t;
+
+#define	SPLAT_CMD_MAGIC			0x9daebfc0U
+typedef struct splat_cmd {
+	__u32 cmd_magic;		/* Unique magic */
+	__u32 cmd_subsystem;		/* Target subsystem */
+	__u32 cmd_test;			/* Subsystem test */
+	__u32 cmd_data_size;		/* Opaque data size */
+	char cmd_data_str[0];		/* Opaque data region */
+} splat_cmd_t;
+
+/* Valid ioctls */
+#define SPLAT_CFG			_IOWR('f', 101, splat_cfg_t)
+#define SPLAT_CMD			_IOWR('f', 102, splat_cmd_t)
+
+/* Valid configuration commands */
+#define SPLAT_CFG_BUFFER_CLEAR		0x001	/* Clear text buffer */
+#define SPLAT_CFG_BUFFER_SIZE		0x002	/* Resize text buffer */
+#define SPLAT_CFG_SUBSYSTEM_COUNT	0x101	/* Number of subsystem */
+#define SPLAT_CFG_SUBSYSTEM_LIST	0x102	/* List of N subsystems */
+#define SPLAT_CFG_TEST_COUNT		0x201	/* Number of tests */
+#define SPLAT_CFG_TEST_LIST		0x202	/* List of N tests */
+
+/*
+ * Valid subsystem and test commands are defined in each subsystem as
+ * SPLAT_SUBSYSTEM_*.  We do need to be careful to avoid collisions, the
+ * currently defined subsystems are as follows:
+ */
+#define SPLAT_SUBSYSTEM_KMEM		0x0100
+#define SPLAT_SUBSYSTEM_TASKQ		0x0200
+#define SPLAT_SUBSYSTEM_KRNG		0x0300
+#define SPLAT_SUBSYSTEM_MUTEX		0x0400
+#define SPLAT_SUBSYSTEM_CONDVAR		0x0500
+#define SPLAT_SUBSYSTEM_THREAD		0x0600
+#define SPLAT_SUBSYSTEM_RWLOCK		0x0700
+#define SPLAT_SUBSYSTEM_TIME		0x0800
+#define SPLAT_SUBSYSTEM_VNODE		0x0900
+#define SPLAT_SUBSYSTEM_KOBJ		0x0a00
+#define SPLAT_SUBSYSTEM_ATOMIC		0x0b00
+#define SPLAT_SUBSYSTEM_LIST		0x0c00
+#define SPLAT_SUBSYSTEM_GENERIC		0x0d00
+#define SPLAT_SUBSYSTEM_CRED		0x0e00
+#define SPLAT_SUBSYSTEM_ZLIB		0x0f00
+#define SPLAT_SUBSYSTEM_LINUX		0x1000
+#define SPLAT_SUBSYSTEM_UNKNOWN		0xff00
+
+#endif /* _SPLAT_CTL_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/strings.h
@@ -0,0 +1,28 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+\*****************************************************************************/
+
+#ifndef _SPL_STRINGS_H
+#define _SPL_STRINGS_H
+
+#endif /* SPL_STRINGS_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/sys/Makefile.am
@@ -0,0 +1,113 @@
+SUBDIRS = fm fs sysevent
+
+COMMON_H =
+
+KERNEL_H = \
+	$(top_srcdir)/include/sys/acl.h \
+	$(top_srcdir)/include/sys/acl_impl.h \
+	$(top_srcdir)/include/sys/atomic.h \
+	$(top_srcdir)/include/sys/attr.h \
+	$(top_srcdir)/include/sys/bitmap.h \
+	$(top_srcdir)/include/sys/bootconf.h \
+	$(top_srcdir)/include/sys/bootprops.h \
+	$(top_srcdir)/include/sys/buf.h \
+	$(top_srcdir)/include/sys/byteorder.h \
+	$(top_srcdir)/include/sys/callb.h \
+	$(top_srcdir)/include/sys/callo.h \
+	$(top_srcdir)/include/sys/cmn_err.h \
+	$(top_srcdir)/include/sys/compress.h \
+	$(top_srcdir)/include/sys/condvar.h \
+	$(top_srcdir)/include/sys/conf.h \
+	$(top_srcdir)/include/sys/console.h \
+	$(top_srcdir)/include/sys/cpupart.h \
+	$(top_srcdir)/include/sys/cpuvar.h \
+	$(top_srcdir)/include/sys/crc32.h \
+	$(top_srcdir)/include/sys/cred.h \
+	$(top_srcdir)/include/sys/ctype.h \
+	$(top_srcdir)/include/sys/ddi.h \
+	$(top_srcdir)/include/sys/debug.h \
+	$(top_srcdir)/include/sys/dirent.h \
+	$(top_srcdir)/include/sys/disp.h \
+	$(top_srcdir)/include/sys/dkio.h \
+	$(top_srcdir)/include/sys/dklabel.h \
+	$(top_srcdir)/include/sys/dnlc.h \
+	$(top_srcdir)/include/sys/dumphdr.h \
+	$(top_srcdir)/include/sys/efi_partition.h \
+	$(top_srcdir)/include/sys/errno.h \
+	$(top_srcdir)/include/sys/extdirent.h \
+	$(top_srcdir)/include/sys/fcntl.h \
+	$(top_srcdir)/include/sys/file.h \
+	$(top_srcdir)/include/sys/idmap.h \
+	$(top_srcdir)/include/sys/int_limits.h \
+	$(top_srcdir)/include/sys/int_types.h \
+	$(top_srcdir)/include/sys/inttypes.h \
+	$(top_srcdir)/include/sys/isa_defs.h \
+	$(top_srcdir)/include/sys/kidmap.h \
+	$(top_srcdir)/include/sys/kmem.h \
+	$(top_srcdir)/include/sys/kmem_cache.h \
+	$(top_srcdir)/include/sys/kobj.h \
+	$(top_srcdir)/include/sys/kstat.h \
+	$(top_srcdir)/include/sys/list.h \
+	$(top_srcdir)/include/sys/mkdev.h \
+	$(top_srcdir)/include/sys/mntent.h \
+	$(top_srcdir)/include/sys/modctl.h \
+	$(top_srcdir)/include/sys/mode.h \
+	$(top_srcdir)/include/sys/mount.h \
+	$(top_srcdir)/include/sys/mutex.h \
+	$(top_srcdir)/include/sys/note.h \
+	$(top_srcdir)/include/sys/open.h \
+	$(top_srcdir)/include/sys/param.h \
+	$(top_srcdir)/include/sys/pathname.h \
+	$(top_srcdir)/include/sys/policy.h \
+	$(top_srcdir)/include/sys/pool.h \
+	$(top_srcdir)/include/sys/priv_impl.h \
+	$(top_srcdir)/include/sys/processor.h \
+	$(top_srcdir)/include/sys/proc.h \
+	$(top_srcdir)/include/sys/pset.h \
+	$(top_srcdir)/include/sys/random.h \
+	$(top_srcdir)/include/sys/refstr.h \
+	$(top_srcdir)/include/sys/resource.h \
+	$(top_srcdir)/include/sys/rwlock.h \
+	$(top_srcdir)/include/sys/sdt.h \
+	$(top_srcdir)/include/sys/sid.h \
+	$(top_srcdir)/include/sys/signal.h \
+	$(top_srcdir)/include/sys/stat.h \
+	$(top_srcdir)/include/sys/stropts.h \
+	$(top_srcdir)/include/sys/sunddi.h \
+	$(top_srcdir)/include/sys/sunldi.h \
+	$(top_srcdir)/include/sys/sysdc.h \
+	$(top_srcdir)/include/sys/sysevent.h \
+	$(top_srcdir)/include/sys/sysmacros.h \
+	$(top_srcdir)/include/sys/systeminfo.h \
+	$(top_srcdir)/include/sys/systm.h \
+	$(top_srcdir)/include/sys/taskq.h \
+	$(top_srcdir)/include/sys/thread.h \
+	$(top_srcdir)/include/sys/time.h \
+	$(top_srcdir)/include/sys/timer.h \
+	$(top_srcdir)/include/sys/t_lock.h \
+	$(top_srcdir)/include/sys/tsd.h \
+	$(top_srcdir)/include/sys/types32.h \
+	$(top_srcdir)/include/sys/types.h \
+	$(top_srcdir)/include/sys/u8_textprep.h \
+	$(top_srcdir)/include/sys/uio.h \
+	$(top_srcdir)/include/sys/unistd.h \
+	$(top_srcdir)/include/sys/user.h \
+	$(top_srcdir)/include/sys/va_list.h \
+	$(top_srcdir)/include/sys/varargs.h \
+	$(top_srcdir)/include/sys/vfs.h \
+	$(top_srcdir)/include/sys/vfs_opreg.h \
+	$(top_srcdir)/include/sys/vmem.h \
+	$(top_srcdir)/include/sys/vmsystm.h \
+	$(top_srcdir)/include/sys/vnode.h \
+	$(top_srcdir)/include/sys/zmod.h \
+	$(top_srcdir)/include/sys/zone.h
+
+USER_H =
+
+EXTRA_DIST = $(COMMON_H) $(KERNEL_H) $(USER_H)
+
+if CONFIG_KERNEL
+kerneldir = @prefix@/src/spl-$(VERSION)/include/sys
+kernel_HEADERS = $(KERNEL_H)
+endif
+
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/sys/Makefile.in
@@ -0,0 +1,932 @@
+# Makefile.in generated by automake 1.15 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2014 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+VPATH = @srcdir@
+am__is_gnu_make = { \
+  if test -z '$(MAKELEVEL)'; then \
+    false; \
+  elif test -n '$(MAKE_HOST)'; then \
+    true; \
+  elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+    true; \
+  else \
+    false; \
+  fi; \
+}
+am__make_running_with_option = \
+  case $${target_option-} in \
+      ?) ;; \
+      *) echo "am__make_running_with_option: internal error: invalid" \
+              "target option '$${target_option-}' specified" >&2; \
+         exit 1;; \
+  esac; \
+  has_opt=no; \
+  sane_makeflags=$$MAKEFLAGS; \
+  if $(am__is_gnu_make); then \
+    sane_makeflags=$$MFLAGS; \
+  else \
+    case $$MAKEFLAGS in \
+      *\\[\ \	]*) \
+        bs=\\; \
+        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
+    esac; \
+  fi; \
+  skip_next=no; \
+  strip_trailopt () \
+  { \
+    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+  }; \
+  for flg in $$sane_makeflags; do \
+    test $$skip_next = yes && { skip_next=no; continue; }; \
+    case $$flg in \
+      *=*|--*) continue;; \
+        -*I) strip_trailopt 'I'; skip_next=yes;; \
+      -*I?*) strip_trailopt 'I';; \
+        -*O) strip_trailopt 'O'; skip_next=yes;; \
+      -*O?*) strip_trailopt 'O';; \
+        -*l) strip_trailopt 'l'; skip_next=yes;; \
+      -*l?*) strip_trailopt 'l';; \
+      -[dEDm]) skip_next=yes;; \
+      -[JT]) skip_next=yes;; \
+    esac; \
+    case $$flg in \
+      *$$target_option*) has_opt=yes; break;; \
+    esac; \
+  done; \
+  test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+target_triplet = @target@
+subdir = include/sys
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/config/libtool.m4 \
+	$(top_srcdir)/config/ltoptions.m4 \
+	$(top_srcdir)/config/ltsugar.m4 \
+	$(top_srcdir)/config/ltversion.m4 \
+	$(top_srcdir)/config/lt~obsolete.m4 \
+	$(top_srcdir)/config/spl-build.m4 \
+	$(top_srcdir)/config/spl-meta.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(am__kernel_HEADERS_DIST) \
+	$(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/spl_config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo "  GEN     " $@;
+am__v_GEN_1 = 
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 = 
+SOURCES =
+DIST_SOURCES =
+RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \
+	ctags-recursive dvi-recursive html-recursive info-recursive \
+	install-data-recursive install-dvi-recursive \
+	install-exec-recursive install-html-recursive \
+	install-info-recursive install-pdf-recursive \
+	install-ps-recursive install-recursive installcheck-recursive \
+	installdirs-recursive pdf-recursive ps-recursive \
+	tags-recursive uninstall-recursive
+am__can_run_installinfo = \
+  case $$AM_UPDATE_INFO_DIR in \
+    n|no|NO) false;; \
+    *) (install-info --version) >/dev/null 2>&1;; \
+  esac
+am__kernel_HEADERS_DIST = $(top_srcdir)/include/sys/acl.h \
+	$(top_srcdir)/include/sys/acl_impl.h \
+	$(top_srcdir)/include/sys/atomic.h \
+	$(top_srcdir)/include/sys/attr.h \
+	$(top_srcdir)/include/sys/bitmap.h \
+	$(top_srcdir)/include/sys/bootconf.h \
+	$(top_srcdir)/include/sys/bootprops.h \
+	$(top_srcdir)/include/sys/buf.h \
+	$(top_srcdir)/include/sys/byteorder.h \
+	$(top_srcdir)/include/sys/callb.h \
+	$(top_srcdir)/include/sys/callo.h \
+	$(top_srcdir)/include/sys/cmn_err.h \
+	$(top_srcdir)/include/sys/compress.h \
+	$(top_srcdir)/include/sys/condvar.h \
+	$(top_srcdir)/include/sys/conf.h \
+	$(top_srcdir)/include/sys/console.h \
+	$(top_srcdir)/include/sys/cpupart.h \
+	$(top_srcdir)/include/sys/cpuvar.h \
+	$(top_srcdir)/include/sys/crc32.h \
+	$(top_srcdir)/include/sys/cred.h \
+	$(top_srcdir)/include/sys/ctype.h \
+	$(top_srcdir)/include/sys/ddi.h \
+	$(top_srcdir)/include/sys/debug.h \
+	$(top_srcdir)/include/sys/dirent.h \
+	$(top_srcdir)/include/sys/disp.h \
+	$(top_srcdir)/include/sys/dkio.h \
+	$(top_srcdir)/include/sys/dklabel.h \
+	$(top_srcdir)/include/sys/dnlc.h \
+	$(top_srcdir)/include/sys/dumphdr.h \
+	$(top_srcdir)/include/sys/efi_partition.h \
+	$(top_srcdir)/include/sys/errno.h \
+	$(top_srcdir)/include/sys/extdirent.h \
+	$(top_srcdir)/include/sys/fcntl.h \
+	$(top_srcdir)/include/sys/file.h \
+	$(top_srcdir)/include/sys/idmap.h \
+	$(top_srcdir)/include/sys/int_limits.h \
+	$(top_srcdir)/include/sys/int_types.h \
+	$(top_srcdir)/include/sys/inttypes.h \
+	$(top_srcdir)/include/sys/isa_defs.h \
+	$(top_srcdir)/include/sys/kidmap.h \
+	$(top_srcdir)/include/sys/kmem.h \
+	$(top_srcdir)/include/sys/kmem_cache.h \
+	$(top_srcdir)/include/sys/kobj.h \
+	$(top_srcdir)/include/sys/kstat.h \
+	$(top_srcdir)/include/sys/list.h \
+	$(top_srcdir)/include/sys/mkdev.h \
+	$(top_srcdir)/include/sys/mntent.h \
+	$(top_srcdir)/include/sys/modctl.h \
+	$(top_srcdir)/include/sys/mode.h \
+	$(top_srcdir)/include/sys/mount.h \
+	$(top_srcdir)/include/sys/mutex.h \
+	$(top_srcdir)/include/sys/note.h \
+	$(top_srcdir)/include/sys/open.h \
+	$(top_srcdir)/include/sys/param.h \
+	$(top_srcdir)/include/sys/pathname.h \
+	$(top_srcdir)/include/sys/policy.h \
+	$(top_srcdir)/include/sys/pool.h \
+	$(top_srcdir)/include/sys/priv_impl.h \
+	$(top_srcdir)/include/sys/processor.h \
+	$(top_srcdir)/include/sys/proc.h \
+	$(top_srcdir)/include/sys/pset.h \
+	$(top_srcdir)/include/sys/random.h \
+	$(top_srcdir)/include/sys/refstr.h \
+	$(top_srcdir)/include/sys/resource.h \
+	$(top_srcdir)/include/sys/rwlock.h \
+	$(top_srcdir)/include/sys/sdt.h \
+	$(top_srcdir)/include/sys/sid.h \
+	$(top_srcdir)/include/sys/signal.h \
+	$(top_srcdir)/include/sys/stat.h \
+	$(top_srcdir)/include/sys/stropts.h \
+	$(top_srcdir)/include/sys/sunddi.h \
+	$(top_srcdir)/include/sys/sunldi.h \
+	$(top_srcdir)/include/sys/sysdc.h \
+	$(top_srcdir)/include/sys/sysevent.h \
+	$(top_srcdir)/include/sys/sysmacros.h \
+	$(top_srcdir)/include/sys/systeminfo.h \
+	$(top_srcdir)/include/sys/systm.h \
+	$(top_srcdir)/include/sys/taskq.h \
+	$(top_srcdir)/include/sys/thread.h \
+	$(top_srcdir)/include/sys/time.h \
+	$(top_srcdir)/include/sys/timer.h \
+	$(top_srcdir)/include/sys/t_lock.h \
+	$(top_srcdir)/include/sys/tsd.h \
+	$(top_srcdir)/include/sys/types32.h \
+	$(top_srcdir)/include/sys/types.h \
+	$(top_srcdir)/include/sys/u8_textprep.h \
+	$(top_srcdir)/include/sys/uio.h \
+	$(top_srcdir)/include/sys/unistd.h \
+	$(top_srcdir)/include/sys/user.h \
+	$(top_srcdir)/include/sys/va_list.h \
+	$(top_srcdir)/include/sys/varargs.h \
+	$(top_srcdir)/include/sys/vfs.h \
+	$(top_srcdir)/include/sys/vfs_opreg.h \
+	$(top_srcdir)/include/sys/vmem.h \
+	$(top_srcdir)/include/sys/vmsystm.h \
+	$(top_srcdir)/include/sys/vnode.h \
+	$(top_srcdir)/include/sys/zmod.h \
+	$(top_srcdir)/include/sys/zone.h
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+    $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+    *) f=$$p;; \
+  esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+  srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+  for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+  for p in $$list; do echo "$$p $$p"; done | \
+  sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+  $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+    if (++n[$$2] == $(am__install_max)) \
+      { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+    END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+  sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+  sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+  test -z "$$files" \
+    || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+    || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+         $(am__cd) "$$dir" && rm -f $$files; }; \
+  }
+am__installdirs = "$(DESTDIR)$(kerneldir)"
+HEADERS = $(kernel_HEADERS)
+RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive	\
+  distclean-recursive maintainer-clean-recursive
+am__recursive_targets = \
+  $(RECURSIVE_TARGETS) \
+  $(RECURSIVE_CLEAN_TARGETS) \
+  $(am__extra_recursive_targets)
+AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \
+	distdir
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates.  Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+  BEGIN { nonempty = 0; } \
+  { items[$$0] = 1; nonempty = 1; } \
+  END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique.  This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+  list='$(am__tagged_files)'; \
+  unique=`for i in $$list; do \
+    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+  done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+DIST_SUBDIRS = $(SUBDIRS)
+am__DIST_COMMON = $(srcdir)/Makefile.in
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+am__relativize = \
+  dir0=`pwd`; \
+  sed_first='s,^\([^/]*\)/.*$$,\1,'; \
+  sed_rest='s,^[^/]*/*,,'; \
+  sed_last='s,^.*/\([^/]*\)$$,\1,'; \
+  sed_butlast='s,/*[^/]*$$,,'; \
+  while test -n "$$dir1"; do \
+    first=`echo "$$dir1" | sed -e "$$sed_first"`; \
+    if test "$$first" != "."; then \
+      if test "$$first" = ".."; then \
+        dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \
+        dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \
+      else \
+        first2=`echo "$$dir2" | sed -e "$$sed_first"`; \
+        if test "$$first2" = "$$first"; then \
+          dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \
+        else \
+          dir2="../$$dir2"; \
+        fi; \
+        dir0="$$dir0"/"$$first"; \
+      fi; \
+    fi; \
+    dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \
+  done; \
+  reldir="$$dir2"
+ACLOCAL = @ACLOCAL@
+ALIEN = @ALIEN@
+ALIEN_VERSION = @ALIEN_VERSION@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEBUG_CFLAGS = @DEBUG_CFLAGS@
+DEBUG_KMEM = @DEBUG_KMEM@
+DEBUG_KMEM_TRACKING = @DEBUG_KMEM_TRACKING@
+DEBUG_SPL = @DEBUG_SPL@
+DEFAULT_PACKAGE = @DEFAULT_PACKAGE@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DPKG = @DPKG@
+DPKGBUILD = @DPKGBUILD@
+DPKGBUILD_VERSION = @DPKGBUILD_VERSION@
+DPKG_VERSION = @DPKG_VERSION@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GREP = @GREP@
+HAVE_ALIEN = @HAVE_ALIEN@
+HAVE_DPKG = @HAVE_DPKG@
+HAVE_DPKGBUILD = @HAVE_DPKGBUILD@
+HAVE_RPM = @HAVE_RPM@
+HAVE_RPMBUILD = @HAVE_RPMBUILD@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+KERNELCPPFLAGS = @KERNELCPPFLAGS@
+KERNELMAKE_PARAMS = @KERNELMAKE_PARAMS@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LINUX = @LINUX@
+LINUX_OBJ = @LINUX_OBJ@
+LINUX_SYMBOLS = @LINUX_SYMBOLS@
+LINUX_VERSION = @LINUX_VERSION@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+RANLIB = @RANLIB@
+RELEASE = @RELEASE@
+RPM = @RPM@
+RPMBUILD = @RPMBUILD@
+RPMBUILD_VERSION = @RPMBUILD_VERSION@
+RPM_DEFINE_COMMON = @RPM_DEFINE_COMMON@
+RPM_DEFINE_DKMS = @RPM_DEFINE_DKMS@
+RPM_DEFINE_KMOD = @RPM_DEFINE_KMOD@
+RPM_DEFINE_UTIL = @RPM_DEFINE_UTIL@
+RPM_SPEC_DIR = @RPM_SPEC_DIR@
+RPM_VERSION = @RPM_VERSION@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SPL_CONFIG = @SPL_CONFIG@
+SPL_META_ALIAS = @SPL_META_ALIAS@
+SPL_META_AUTHOR = @SPL_META_AUTHOR@
+SPL_META_DATA = @SPL_META_DATA@
+SPL_META_LICENSE = @SPL_META_LICENSE@
+SPL_META_LT_AGE = @SPL_META_LT_AGE@
+SPL_META_LT_CURRENT = @SPL_META_LT_CURRENT@
+SPL_META_LT_REVISION = @SPL_META_LT_REVISION@
+SPL_META_NAME = @SPL_META_NAME@
+SPL_META_RELEASE = @SPL_META_RELEASE@
+SPL_META_VERSION = @SPL_META_VERSION@
+SRPM_DEFINE_COMMON = @SRPM_DEFINE_COMMON@
+SRPM_DEFINE_DKMS = @SRPM_DEFINE_DKMS@
+SRPM_DEFINE_KMOD = @SRPM_DEFINE_KMOD@
+SRPM_DEFINE_UTIL = @SRPM_DEFINE_UTIL@
+STRIP = @STRIP@
+VENDOR = @VENDOR@
+VERSION = @VERSION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+runstatedir = @runstatedir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+SUBDIRS = fm fs sysevent
+COMMON_H = 
+KERNEL_H = \
+	$(top_srcdir)/include/sys/acl.h \
+	$(top_srcdir)/include/sys/acl_impl.h \
+	$(top_srcdir)/include/sys/atomic.h \
+	$(top_srcdir)/include/sys/attr.h \
+	$(top_srcdir)/include/sys/bitmap.h \
+	$(top_srcdir)/include/sys/bootconf.h \
+	$(top_srcdir)/include/sys/bootprops.h \
+	$(top_srcdir)/include/sys/buf.h \
+	$(top_srcdir)/include/sys/byteorder.h \
+	$(top_srcdir)/include/sys/callb.h \
+	$(top_srcdir)/include/sys/callo.h \
+	$(top_srcdir)/include/sys/cmn_err.h \
+	$(top_srcdir)/include/sys/compress.h \
+	$(top_srcdir)/include/sys/condvar.h \
+	$(top_srcdir)/include/sys/conf.h \
+	$(top_srcdir)/include/sys/console.h \
+	$(top_srcdir)/include/sys/cpupart.h \
+	$(top_srcdir)/include/sys/cpuvar.h \
+	$(top_srcdir)/include/sys/crc32.h \
+	$(top_srcdir)/include/sys/cred.h \
+	$(top_srcdir)/include/sys/ctype.h \
+	$(top_srcdir)/include/sys/ddi.h \
+	$(top_srcdir)/include/sys/debug.h \
+	$(top_srcdir)/include/sys/dirent.h \
+	$(top_srcdir)/include/sys/disp.h \
+	$(top_srcdir)/include/sys/dkio.h \
+	$(top_srcdir)/include/sys/dklabel.h \
+	$(top_srcdir)/include/sys/dnlc.h \
+	$(top_srcdir)/include/sys/dumphdr.h \
+	$(top_srcdir)/include/sys/efi_partition.h \
+	$(top_srcdir)/include/sys/errno.h \
+	$(top_srcdir)/include/sys/extdirent.h \
+	$(top_srcdir)/include/sys/fcntl.h \
+	$(top_srcdir)/include/sys/file.h \
+	$(top_srcdir)/include/sys/idmap.h \
+	$(top_srcdir)/include/sys/int_limits.h \
+	$(top_srcdir)/include/sys/int_types.h \
+	$(top_srcdir)/include/sys/inttypes.h \
+	$(top_srcdir)/include/sys/isa_defs.h \
+	$(top_srcdir)/include/sys/kidmap.h \
+	$(top_srcdir)/include/sys/kmem.h \
+	$(top_srcdir)/include/sys/kmem_cache.h \
+	$(top_srcdir)/include/sys/kobj.h \
+	$(top_srcdir)/include/sys/kstat.h \
+	$(top_srcdir)/include/sys/list.h \
+	$(top_srcdir)/include/sys/mkdev.h \
+	$(top_srcdir)/include/sys/mntent.h \
+	$(top_srcdir)/include/sys/modctl.h \
+	$(top_srcdir)/include/sys/mode.h \
+	$(top_srcdir)/include/sys/mount.h \
+	$(top_srcdir)/include/sys/mutex.h \
+	$(top_srcdir)/include/sys/note.h \
+	$(top_srcdir)/include/sys/open.h \
+	$(top_srcdir)/include/sys/param.h \
+	$(top_srcdir)/include/sys/pathname.h \
+	$(top_srcdir)/include/sys/policy.h \
+	$(top_srcdir)/include/sys/pool.h \
+	$(top_srcdir)/include/sys/priv_impl.h \
+	$(top_srcdir)/include/sys/processor.h \
+	$(top_srcdir)/include/sys/proc.h \
+	$(top_srcdir)/include/sys/pset.h \
+	$(top_srcdir)/include/sys/random.h \
+	$(top_srcdir)/include/sys/refstr.h \
+	$(top_srcdir)/include/sys/resource.h \
+	$(top_srcdir)/include/sys/rwlock.h \
+	$(top_srcdir)/include/sys/sdt.h \
+	$(top_srcdir)/include/sys/sid.h \
+	$(top_srcdir)/include/sys/signal.h \
+	$(top_srcdir)/include/sys/stat.h \
+	$(top_srcdir)/include/sys/stropts.h \
+	$(top_srcdir)/include/sys/sunddi.h \
+	$(top_srcdir)/include/sys/sunldi.h \
+	$(top_srcdir)/include/sys/sysdc.h \
+	$(top_srcdir)/include/sys/sysevent.h \
+	$(top_srcdir)/include/sys/sysmacros.h \
+	$(top_srcdir)/include/sys/systeminfo.h \
+	$(top_srcdir)/include/sys/systm.h \
+	$(top_srcdir)/include/sys/taskq.h \
+	$(top_srcdir)/include/sys/thread.h \
+	$(top_srcdir)/include/sys/time.h \
+	$(top_srcdir)/include/sys/timer.h \
+	$(top_srcdir)/include/sys/t_lock.h \
+	$(top_srcdir)/include/sys/tsd.h \
+	$(top_srcdir)/include/sys/types32.h \
+	$(top_srcdir)/include/sys/types.h \
+	$(top_srcdir)/include/sys/u8_textprep.h \
+	$(top_srcdir)/include/sys/uio.h \
+	$(top_srcdir)/include/sys/unistd.h \
+	$(top_srcdir)/include/sys/user.h \
+	$(top_srcdir)/include/sys/va_list.h \
+	$(top_srcdir)/include/sys/varargs.h \
+	$(top_srcdir)/include/sys/vfs.h \
+	$(top_srcdir)/include/sys/vfs_opreg.h \
+	$(top_srcdir)/include/sys/vmem.h \
+	$(top_srcdir)/include/sys/vmsystm.h \
+	$(top_srcdir)/include/sys/vnode.h \
+	$(top_srcdir)/include/sys/zmod.h \
+	$(top_srcdir)/include/sys/zone.h
+
+USER_H = 
+EXTRA_DIST = $(COMMON_H) $(KERNEL_H) $(USER_H)
+@CONFIG_KERNEL_TRUE@kerneldir = @prefix@/src/spl-$(VERSION)/include/sys
+@CONFIG_KERNEL_TRUE@kernel_HEADERS = $(KERNEL_H)
+all: all-recursive
+
+.SUFFIXES:
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+	        && { if test -f $@; then exit 0; else break; fi; }; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu include/sys/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --gnu include/sys/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+	esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
+install-kernelHEADERS: $(kernel_HEADERS)
+	@$(NORMAL_INSTALL)
+	@list='$(kernel_HEADERS)'; test -n "$(kerneldir)" || list=; \
+	if test -n "$$list"; then \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(kerneldir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(kerneldir)" || exit 1; \
+	fi; \
+	for p in $$list; do \
+	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+	  echo "$$d$$p"; \
+	done | $(am__base_list) | \
+	while read files; do \
+	  echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(kerneldir)'"; \
+	  $(INSTALL_HEADER) $$files "$(DESTDIR)$(kerneldir)" || exit $$?; \
+	done
+
+uninstall-kernelHEADERS:
+	@$(NORMAL_UNINSTALL)
+	@list='$(kernel_HEADERS)'; test -n "$(kerneldir)" || list=; \
+	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+	dir='$(DESTDIR)$(kerneldir)'; $(am__uninstall_files_from_dir)
+
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run 'make' without going through this Makefile.
+# To change the values of 'make' variables: instead of editing Makefiles,
+# (1) if the variable is set in 'config.status', edit 'config.status'
+#     (which will cause the Makefiles to be regenerated when you run 'make');
+# (2) otherwise, pass the desired values on the 'make' command line.
+$(am__recursive_targets):
+	@fail=; \
+	if $(am__make_keepgoing); then \
+	  failcom='fail=yes'; \
+	else \
+	  failcom='exit 1'; \
+	fi; \
+	dot_seen=no; \
+	target=`echo $@ | sed s/-recursive//`; \
+	case "$@" in \
+	  distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
+	  *) list='$(SUBDIRS)' ;; \
+	esac; \
+	for subdir in $$list; do \
+	  echo "Making $$target in $$subdir"; \
+	  if test "$$subdir" = "."; then \
+	    dot_seen=yes; \
+	    local_target="$$target-am"; \
+	  else \
+	    local_target="$$target"; \
+	  fi; \
+	  ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+	  || eval $$failcom; \
+	done; \
+	if test "$$dot_seen" = "no"; then \
+	  $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+	fi; test -z "$$fail"
+
+ID: $(am__tagged_files)
+	$(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-recursive
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	set x; \
+	here=`pwd`; \
+	if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
+	  include_option=--etags-include; \
+	  empty_fix=.; \
+	else \
+	  include_option=--include; \
+	  empty_fix=; \
+	fi; \
+	list='$(SUBDIRS)'; for subdir in $$list; do \
+	  if test "$$subdir" = .; then :; else \
+	    test ! -f $$subdir/TAGS || \
+	      set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \
+	  fi; \
+	done; \
+	$(am__define_uniq_tagged_files); \
+	shift; \
+	if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+	  test -n "$$unique" || unique=$$empty_fix; \
+	  if test $$# -gt 0; then \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      "$$@" $$unique; \
+	  else \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      $$unique; \
+	  fi; \
+	fi
+ctags: ctags-recursive
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	$(am__define_uniq_tagged_files); \
+	test -z "$(CTAGS_ARGS)$$unique" \
+	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+	     $$unique
+
+GTAGS:
+	here=`$(am__cd) $(top_builddir) && pwd` \
+	  && $(am__cd) $(top_srcdir) \
+	  && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-recursive
+
+cscopelist-am: $(am__tagged_files)
+	list='$(am__tagged_files)'; \
+	case "$(srcdir)" in \
+	  [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+	  *) sdir=$(subdir)/$(srcdir) ;; \
+	esac; \
+	for i in $$list; do \
+	  if test -f "$$i"; then \
+	    echo "$(subdir)/$$i"; \
+	  else \
+	    echo "$$sdir/$$i"; \
+	  fi; \
+	done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	list='$(DISTFILES)'; \
+	  dist_files=`for file in $$list; do echo $$file; done | \
+	  sed -e "s|^$$srcdirstrip/||;t" \
+	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+	case $$dist_files in \
+	  */*) $(MKDIR_P) `echo "$$dist_files" | \
+			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+			   sort -u` ;; \
+	esac; \
+	for file in $$dist_files; do \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  if test -d $$d/$$file; then \
+	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+	    if test -d "$(distdir)/$$file"; then \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+	  else \
+	    test -f "$(distdir)/$$file" \
+	    || cp -p $$d/$$file "$(distdir)/$$file" \
+	    || exit 1; \
+	  fi; \
+	done
+	@list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
+	  if test "$$subdir" = .; then :; else \
+	    $(am__make_dryrun) \
+	      || test -d "$(distdir)/$$subdir" \
+	      || $(MKDIR_P) "$(distdir)/$$subdir" \
+	      || exit 1; \
+	    dir1=$$subdir; dir2="$(distdir)/$$subdir"; \
+	    $(am__relativize); \
+	    new_distdir=$$reldir; \
+	    dir1=$$subdir; dir2="$(top_distdir)"; \
+	    $(am__relativize); \
+	    new_top_distdir=$$reldir; \
+	    echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \
+	    echo "     am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \
+	    ($(am__cd) $$subdir && \
+	      $(MAKE) $(AM_MAKEFLAGS) \
+	        top_distdir="$$new_top_distdir" \
+	        distdir="$$new_distdir" \
+		am__remove_distdir=: \
+		am__skip_length_check=: \
+		am__skip_mode_fix=: \
+	        distdir) \
+	      || exit 1; \
+	  fi; \
+	done
+check-am: all-am
+check: check-recursive
+all-am: Makefile $(HEADERS)
+installdirs: installdirs-recursive
+installdirs-am:
+	for dir in "$(DESTDIR)$(kerneldir)"; do \
+	  test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+	done
+install: install-recursive
+install-exec: install-exec-recursive
+install-data: install-data-recursive
+uninstall: uninstall-recursive
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-recursive
+install-strip:
+	if test -z '$(STRIP)'; then \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	      install; \
+	else \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+	fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+clean: clean-recursive
+
+clean-am: clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-recursive
+	-rm -f Makefile
+distclean-am: clean-am distclean-generic distclean-tags
+
+dvi: dvi-recursive
+
+dvi-am:
+
+html: html-recursive
+
+html-am:
+
+info: info-recursive
+
+info-am:
+
+install-data-am: install-kernelHEADERS
+
+install-dvi: install-dvi-recursive
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-recursive
+
+install-html-am:
+
+install-info: install-info-recursive
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-recursive
+
+install-pdf-am:
+
+install-ps: install-ps-recursive
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-recursive
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-recursive
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-recursive
+
+pdf-am:
+
+ps: ps-recursive
+
+ps-am:
+
+uninstall-am: uninstall-kernelHEADERS
+
+.MAKE: $(am__recursive_targets) install-am install-strip
+
+.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \
+	check-am clean clean-generic clean-libtool cscopelist-am ctags \
+	ctags-am distclean distclean-generic distclean-libtool \
+	distclean-tags distdir dvi dvi-am html html-am info info-am \
+	install install-am install-data install-data-am install-dvi \
+	install-dvi-am install-exec install-exec-am install-html \
+	install-html-am install-info install-info-am \
+	install-kernelHEADERS install-man install-pdf install-pdf-am \
+	install-ps install-ps-am install-strip installcheck \
+	installcheck-am installdirs installdirs-am maintainer-clean \
+	maintainer-clean-generic mostlyclean mostlyclean-generic \
+	mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \
+	uninstall-am uninstall-kernelHEADERS
+
+.PRECIOUS: Makefile
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/sys/acl.h
@@ -0,0 +1,117 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+\*****************************************************************************/
+
+#ifndef _SPL_ACL_H
+#define _SPL_ACL_H
+
+#include <sys/types.h>
+
+typedef struct ace {
+        uid_t a_who;
+        uint32_t a_access_mask;
+        uint16_t a_flags;
+        uint16_t a_type;
+} ace_t;
+
+typedef struct ace_object {
+        uid_t           a_who;          /* uid or gid */
+        uint32_t        a_access_mask;  /* read,write,... */
+        uint16_t        a_flags;        /* see below */
+        uint16_t        a_type;         /* allow or deny */
+        uint8_t         a_obj_type[16]; /* obj type */
+        uint8_t         a_inherit_obj_type[16];  /* inherit obj */
+} ace_object_t;
+
+#define MAX_ACL_ENTRIES					1024
+
+#define ACE_READ_DATA                                   0x00000001
+#define ACE_LIST_DIRECTORY                              0x00000001
+#define ACE_WRITE_DATA                                  0x00000002
+#define ACE_ADD_FILE                                    0x00000002
+#define ACE_APPEND_DATA                                 0x00000004
+#define ACE_ADD_SUBDIRECTORY                            0x00000004
+#define ACE_READ_NAMED_ATTRS                            0x00000008
+#define ACE_WRITE_NAMED_ATTRS                           0x00000010
+#define ACE_EXECUTE                                     0x00000020
+#define ACE_DELETE_CHILD                                0x00000040
+#define ACE_READ_ATTRIBUTES                             0x00000080
+#define ACE_WRITE_ATTRIBUTES                            0x00000100
+#define ACE_DELETE                                      0x00010000
+#define ACE_READ_ACL                                    0x00020000
+#define ACE_WRITE_ACL                                   0x00040000
+#define ACE_WRITE_OWNER                                 0x00080000
+#define ACE_SYNCHRONIZE                                 0x00100000
+
+#define ACE_FILE_INHERIT_ACE                            0x0001
+#define ACE_DIRECTORY_INHERIT_ACE                       0x0002
+#define ACE_NO_PROPAGATE_INHERIT_ACE                    0x0004
+#define ACE_INHERIT_ONLY_ACE                            0x0008
+#define ACE_SUCCESSFUL_ACCESS_ACE_FLAG                  0x0010
+#define ACE_FAILED_ACCESS_ACE_FLAG                      0x0020
+#define ACE_IDENTIFIER_GROUP                            0x0040
+#define ACE_INHERITED_ACE                               0x0080
+#define ACE_OWNER                                       0x1000
+#define ACE_GROUP                                       0x2000
+#define ACE_EVERYONE                                    0x4000
+
+#define ACE_ACCESS_ALLOWED_ACE_TYPE                     0x0000
+#define ACE_ACCESS_DENIED_ACE_TYPE                      0x0001
+#define ACE_SYSTEM_AUDIT_ACE_TYPE                       0x0002
+#define ACE_SYSTEM_ALARM_ACE_TYPE                       0x0003
+
+#define ACL_AUTO_INHERIT                                0x0001
+#define ACL_PROTECTED                                   0x0002
+#define ACL_DEFAULTED                                   0x0004
+#define ACL_FLAGS_ALL (ACL_AUTO_INHERIT|ACL_PROTECTED|ACL_DEFAULTED)
+
+#define ACE_ACCESS_ALLOWED_COMPOUND_ACE_TYPE            0x04
+#define ACE_ACCESS_ALLOWED_OBJECT_ACE_TYPE              0x05
+#define ACE_ACCESS_DENIED_OBJECT_ACE_TYPE               0x06
+#define ACE_SYSTEM_AUDIT_OBJECT_ACE_TYPE                0x07
+#define ACE_SYSTEM_ALARM_OBJECT_ACE_TYPE                0x08
+#define ACE_ACCESS_ALLOWED_CALLBACK_ACE_TYPE            0x09
+#define ACE_ACCESS_DENIED_CALLBACK_ACE_TYPE             0x0A
+#define ACE_ACCESS_ALLOWED_CALLBACK_OBJECT_ACE_TYPE     0x0B
+#define ACE_ACCESS_DENIED_CALLBACK_OBJECT_ACE_TYPE      0x0C
+#define ACE_SYSTEM_AUDIT_CALLBACK_ACE_TYPE              0x0D
+#define ACE_SYSTEM_ALARM_CALLBACK_ACE_TYPE              0x0E
+#define ACE_SYSTEM_AUDIT_CALLBACK_OBJECT_ACE_TYPE       0x0F
+#define ACE_SYSTEM_ALARM_CALLBACK_OBJECT_ACE_TYPE       0x10
+
+#define ACE_ALL_TYPES   0x001F
+
+#define ACE_TYPE_FLAGS (ACE_OWNER|ACE_GROUP|ACE_EVERYONE|ACE_IDENTIFIER_GROUP)
+
+#define ACE_ALL_PERMS   (ACE_READ_DATA|ACE_LIST_DIRECTORY|ACE_WRITE_DATA| \
+     ACE_ADD_FILE|ACE_APPEND_DATA|ACE_ADD_SUBDIRECTORY|ACE_READ_NAMED_ATTRS| \
+     ACE_WRITE_NAMED_ATTRS|ACE_EXECUTE|ACE_DELETE_CHILD|ACE_READ_ATTRIBUTES| \
+     ACE_WRITE_ATTRIBUTES|ACE_DELETE|ACE_READ_ACL|ACE_WRITE_ACL| \
+     ACE_WRITE_OWNER|ACE_SYNCHRONIZE)
+
+#define VSA_ACE                                         0x0010
+#define VSA_ACECNT                                      0x0020
+#define VSA_ACE_ALLTYPES                                0x0040
+#define VSA_ACE_ACLFLAGS                                0x0080
+
+#endif /* _SPL_ACL_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/sys/acl_impl.h
@@ -0,0 +1,28 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+\*****************************************************************************/
+
+#ifndef _SPL_ACL_IMPL_H
+#define _SPL_ACL_IMPL_H
+
+#endif /* _SPL_ACL_IMPL_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/sys/atomic.h
@@ -0,0 +1,315 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+\*****************************************************************************/
+
+#ifndef _SPL_ATOMIC_H
+#define _SPL_ATOMIC_H
+
+#include <linux/module.h>
+#include <linux/spinlock.h>
+#include <sys/types.h>
+
+/*
+ * Two approaches to atomic operations are implemented each with its
+ * own benefits are drawbacks imposed by the Solaris API.  Neither
+ * approach handles the issue of word breaking when using a 64-bit
+ * atomic variable on a 32-bit arch.  The Solaris API would need to
+ * add an atomic read call to correctly support this.
+ *
+ * When ATOMIC_SPINLOCK is defined all atomic operations will be
+ * serialized through global spin locks.  This is bad for performance
+ * but it does allow a simple generic implementation.
+ *
+ * When ATOMIC_SPINLOCK is not defined the Linux atomic operations
+ * are used.  This is safe as long as the core Linux implementation
+ * doesn't change because we are relying on the fact that an atomic
+ * type is really just a uint32 or uint64.  If this changes at some
+ * point in the future we need to fall-back to the spin approach.
+ */
+#ifdef ATOMIC_SPINLOCK
+extern spinlock_t atomic32_lock;
+extern spinlock_t atomic64_lock;
+
+static __inline__ void
+atomic_inc_32(volatile uint32_t *target)
+{
+	spin_lock(&atomic32_lock);
+	(*target)++;
+	spin_unlock(&atomic32_lock);
+}
+
+static __inline__ void
+atomic_dec_32(volatile uint32_t *target)
+{
+	spin_lock(&atomic32_lock);
+	(*target)--;
+	spin_unlock(&atomic32_lock);
+}
+
+static __inline__ void
+atomic_add_32(volatile uint32_t *target, int32_t delta)
+{
+	spin_lock(&atomic32_lock);
+	*target += delta;
+	spin_unlock(&atomic32_lock);
+}
+
+static __inline__ void
+atomic_sub_32(volatile uint32_t *target, int32_t delta)
+{
+	spin_lock(&atomic32_lock);
+	*target -= delta;
+	spin_unlock(&atomic32_lock);
+}
+
+static __inline__ uint32_t
+atomic_inc_32_nv(volatile uint32_t *target)
+{
+	uint32_t nv;
+
+	spin_lock(&atomic32_lock);
+	nv = ++(*target);
+	spin_unlock(&atomic32_lock);
+
+	return nv;
+}
+
+static __inline__ uint32_t
+atomic_dec_32_nv(volatile uint32_t *target)
+{
+	uint32_t nv;
+
+	spin_lock(&atomic32_lock);
+	nv = --(*target);
+	spin_unlock(&atomic32_lock);
+
+	return nv;
+}
+
+static __inline__ uint32_t
+atomic_add_32_nv(volatile uint32_t *target, uint32_t delta)
+{
+	uint32_t nv;
+
+	spin_lock(&atomic32_lock);
+	*target += delta;
+	nv = *target;
+	spin_unlock(&atomic32_lock);
+
+	return nv;
+}
+
+static __inline__ uint32_t
+atomic_sub_32_nv(volatile uint32_t *target, uint32_t delta)
+{
+	uint32_t nv;
+
+	spin_lock(&atomic32_lock);
+	*target -= delta;
+	nv = *target;
+	spin_unlock(&atomic32_lock);
+
+	return nv;
+}
+
+static __inline__ uint32_t
+atomic_cas_32(volatile uint32_t *target,  uint32_t cmp,
+              uint32_t newval)
+{
+	uint32_t rc;
+
+	spin_lock(&atomic32_lock);
+	rc = *target;
+	if (*target == cmp)
+		*target = newval;
+
+	spin_unlock(&atomic32_lock);
+
+	return rc;
+}
+
+static __inline__ uint32_t
+atomic_swap_32(volatile uint32_t *target,  uint32_t newval)
+{
+	uint32_t rc;
+
+	spin_lock(&atomic32_lock);
+	rc = *target;
+	*target = newval;
+	spin_unlock(&atomic32_lock);
+
+	return rc;
+}
+
+static __inline__ void
+atomic_inc_64(volatile uint64_t *target)
+{
+	spin_lock(&atomic64_lock);
+	(*target)++;
+	spin_unlock(&atomic64_lock);
+}
+
+static __inline__ void
+atomic_dec_64(volatile uint64_t *target)
+{
+	spin_lock(&atomic64_lock);
+	(*target)--;
+	spin_unlock(&atomic64_lock);
+}
+
+static __inline__ void
+atomic_add_64(volatile uint64_t *target, uint64_t delta)
+{
+	spin_lock(&atomic64_lock);
+	*target += delta;
+	spin_unlock(&atomic64_lock);
+}
+
+static __inline__ void
+atomic_sub_64(volatile uint64_t *target, uint64_t delta)
+{
+	spin_lock(&atomic64_lock);
+	*target -= delta;
+	spin_unlock(&atomic64_lock);
+}
+
+static __inline__ uint64_t
+atomic_inc_64_nv(volatile uint64_t *target)
+{
+	uint64_t nv;
+
+	spin_lock(&atomic64_lock);
+	nv = ++(*target);
+	spin_unlock(&atomic64_lock);
+
+	return nv;
+}
+
+static __inline__ uint64_t
+atomic_dec_64_nv(volatile uint64_t *target)
+{
+	uint64_t nv;
+
+	spin_lock(&atomic64_lock);
+	nv = --(*target);
+	spin_unlock(&atomic64_lock);
+
+	return nv;
+}
+
+static __inline__ uint64_t
+atomic_add_64_nv(volatile uint64_t *target, uint64_t delta)
+{
+	uint64_t nv;
+
+	spin_lock(&atomic64_lock);
+	*target += delta;
+	nv = *target;
+	spin_unlock(&atomic64_lock);
+
+	return nv;
+}
+
+static __inline__ uint64_t
+atomic_sub_64_nv(volatile uint64_t *target, uint64_t delta)
+{
+	uint64_t nv;
+
+	spin_lock(&atomic64_lock);
+	*target -= delta;
+	nv = *target;
+	spin_unlock(&atomic64_lock);
+
+	return nv;
+}
+
+static __inline__ uint64_t
+atomic_cas_64(volatile uint64_t *target,  uint64_t cmp,
+              uint64_t newval)
+{
+	uint64_t rc;
+
+	spin_lock(&atomic64_lock);
+	rc = *target;
+	if (*target == cmp)
+		*target = newval;
+	spin_unlock(&atomic64_lock);
+
+	return rc;
+}
+
+static __inline__ uint64_t
+atomic_swap_64(volatile uint64_t *target,  uint64_t newval)
+{
+	uint64_t rc;
+
+	spin_lock(&atomic64_lock);
+	rc = *target;
+	*target = newval;
+	spin_unlock(&atomic64_lock);
+
+	return rc;
+}
+
+#else /* ATOMIC_SPINLOCK */
+
+#define atomic_inc_32(v)	atomic_inc((atomic_t *)(v))
+#define atomic_dec_32(v)	atomic_dec((atomic_t *)(v))
+#define atomic_add_32(v, i)	atomic_add((i), (atomic_t *)(v))
+#define atomic_sub_32(v, i)	atomic_sub((i), (atomic_t *)(v))
+#define atomic_inc_32_nv(v)	atomic_inc_return((atomic_t *)(v))
+#define atomic_dec_32_nv(v)	atomic_dec_return((atomic_t *)(v))
+#define atomic_add_32_nv(v, i)	atomic_add_return((i), (atomic_t *)(v))
+#define atomic_sub_32_nv(v, i)	atomic_sub_return((i), (atomic_t *)(v))
+#define atomic_cas_32(v, x, y)	atomic_cmpxchg((atomic_t *)(v), x, y)
+#define atomic_swap_32(v, x)	atomic_xchg((atomic_t *)(v), x)
+#define atomic_inc_64(v)	atomic64_inc((atomic64_t *)(v))
+#define atomic_dec_64(v)	atomic64_dec((atomic64_t *)(v))
+#define atomic_add_64(v, i)	atomic64_add((i), (atomic64_t *)(v))
+#define atomic_sub_64(v, i)	atomic64_sub((i), (atomic64_t *)(v))
+#define atomic_inc_64_nv(v)	atomic64_inc_return((atomic64_t *)(v))
+#define atomic_dec_64_nv(v)	atomic64_dec_return((atomic64_t *)(v))
+#define atomic_add_64_nv(v, i)	atomic64_add_return((i), (atomic64_t *)(v))
+#define atomic_sub_64_nv(v, i)	atomic64_sub_return((i), (atomic64_t *)(v))
+#define atomic_cas_64(v, x, y)	atomic64_cmpxchg((atomic64_t *)(v), x, y)
+#define atomic_swap_64(v, x)	atomic64_xchg((atomic64_t *)(v), x)
+
+#endif /* ATOMIC_SPINLOCK */
+
+#ifdef _LP64
+static __inline__ void *
+atomic_cas_ptr(volatile void *target,  void *cmp, void *newval)
+{
+	return (void *)atomic_cas_64((volatile uint64_t *)target,
+	                             (uint64_t)cmp, (uint64_t)newval);
+}
+#else /* _LP64 */
+static __inline__ void *
+atomic_cas_ptr(volatile void *target,  void *cmp, void *newval)
+{
+	return (void *)atomic_cas_32((volatile uint32_t *)target,
+	                             (uint32_t)cmp, (uint32_t)newval);
+}
+#endif /* _LP64 */
+
+#endif  /* _SPL_ATOMIC_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/sys/attr.h
@@ -0,0 +1,28 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+\*****************************************************************************/
+
+#ifndef _SPL_ATTR_H
+#define _SPL_ATTR_H
+
+#endif /* SPL_ATTR_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/sys/bitmap.h
@@ -0,0 +1,28 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+\*****************************************************************************/
+
+#ifndef _SPL_BITMAP_H
+#define _SPL_BITMAP_H
+
+#endif /* SPL_BITMAP_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/sys/bootconf.h
@@ -0,0 +1,28 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+\*****************************************************************************/
+
+#ifndef _SPL_BOOTCONF_H
+#define _SPL_BOOTCONF_H
+
+#endif /* SPL_BOOTCONF_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/sys/bootprops.h
@@ -0,0 +1,28 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+\*****************************************************************************/
+
+#ifndef _SPL_BOOTPROPS_H
+#define _SPL_BOOTPROPS_H
+
+#endif /* SPL_BOOTPROPS_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/sys/buf.h
@@ -0,0 +1,28 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+\*****************************************************************************/
+
+#ifndef _SPL_BUF_H
+#define _SPL_BUF_H
+
+#endif /* SPL_BUF_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/sys/byteorder.h
@@ -0,0 +1,46 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+\*****************************************************************************/
+
+#ifndef _SPL_BYTEORDER_H
+#define _SPL_BYTEORDER_H
+
+#include <asm/byteorder.h>
+
+#define LE_16(x)	cpu_to_le16(x)
+#define LE_32(x)	cpu_to_le32(x)
+#define LE_64(x)	cpu_to_le64(x)
+#define BE_16(x)	cpu_to_be16(x)
+#define BE_32(x)	cpu_to_be32(x)
+#define BE_64(x)	cpu_to_be64(x)
+
+#define BE_IN8(xa) \
+	*((uint8_t *)(xa))
+
+#define BE_IN16(xa) \
+	(((uint16_t)BE_IN8(xa) << 8) | BE_IN8((uint8_t *)(xa)+1))
+
+#define BE_IN32(xa) \
+	(((uint32_t)BE_IN16(xa) << 16) | BE_IN16((uint8_t *)(xa)+2))
+
+#endif /* SPL_BYTEORDER_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/sys/callb.h
@@ -0,0 +1,55 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+\*****************************************************************************/
+
+#ifndef _SPL_CALLB_H
+#define _SPL_CALLB_H
+
+#include <linux/module.h>
+#include <sys/mutex.h>
+
+#define CALLB_CPR_ASSERT(cp)		ASSERT(MUTEX_HELD((cp)->cc_lockp));
+
+typedef struct callb_cpr {
+        kmutex_t        *cc_lockp;
+} callb_cpr_t;
+
+#define CALLB_CPR_INIT(cp, lockp, func, name)   {               \
+        (cp)->cc_lockp = lockp;                                 \
+}
+
+#define CALLB_CPR_SAFE_BEGIN(cp) {                              \
+	CALLB_CPR_ASSERT(cp);					\
+}
+
+#define CALLB_CPR_SAFE_END(cp, lockp) {                         \
+	CALLB_CPR_ASSERT(cp);					\
+}
+
+#define CALLB_CPR_EXIT(cp) {                                    \
+        ASSERT(MUTEX_HELD((cp)->cc_lockp));                     \
+        mutex_exit((cp)->cc_lockp);                             \
+}
+
+#endif  /* _SPL_CALLB_H */
+
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/sys/callo.h
@@ -0,0 +1,52 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2013 Lawrence Livermore National Security, LLC.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+\*****************************************************************************/
+
+#ifndef _SPL_CALLO_H
+#define _SPL_CALLO_H
+
+/*
+ * Callout flags:
+ *
+ * CALLOUT_FLAG_ROUNDUP
+ *      Roundup the expiration time to the next resolution boundary.
+ *      If this flag is not specified, the expiration time is rounded down.
+ * CALLOUT_FLAG_ABSOLUTE
+ *      Normally, the expiration passed to the timeout API functions is an
+ *      expiration interval. If this flag is specified, then it is
+ *      interpreted as the expiration time itself.
+ * CALLOUT_FLAG_HRESTIME
+ *      Normally, callouts are not affected by changes to system time
+ *      (hrestime). This flag is used to create a callout that is affected
+ *      by system time. If system time changes, these timers must be
+ *      handled in a special way (see callout.c). These are used by condition
+ *      variables and LWP timers that need this behavior.
+ * CALLOUT_FLAG_32BIT
+ *      Legacy interfaces timeout() and realtime_timeout() pass this flag
+ *      to timeout_generic() to indicate that a 32-bit ID should be allocated.
+ */
+#define CALLOUT_FLAG_ROUNDUP            0x1
+#define CALLOUT_FLAG_ABSOLUTE           0x2
+#define CALLOUT_FLAG_HRESTIME           0x4
+#define CALLOUT_FLAG_32BIT              0x8
+
+#endif  /* _SPL_CALLB_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/sys/cmn_err.h
@@ -0,0 +1,42 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+\*****************************************************************************/
+
+#ifndef _SPL_CMN_ERR_H
+#define _SPL_CMN_ERR_H
+
+#include <sys/varargs.h>
+
+#define CE_CONT         0       /* continuation         */
+#define CE_NOTE         1       /* notice               */
+#define CE_WARN         2       /* warning              */
+#define CE_PANIC        3       /* panic                */
+#define CE_IGNORE       4       /* print nothing        */
+
+extern void cmn_err(int, const char *, ...);
+extern void vcmn_err(int, const char *, __va_list);
+extern void vpanic(const char *, __va_list);
+
+#define fm_panic	panic
+
+#endif /* SPL_CMN_ERR_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/sys/compress.h
@@ -0,0 +1,28 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+\*****************************************************************************/
+
+#ifndef _SPL_COMPRESS_H
+#define _SPL_COMPRESS_H
+
+#endif /* SPL_COMPRESS_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/sys/condvar.h
@@ -0,0 +1,77 @@
+/*
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _SPL_CONDVAR_H
+#define	_SPL_CONDVAR_H
+
+#include <linux/module.h>
+#include <linux/wait.h>
+#include <linux/delay_compat.h>
+#include <sys/kmem.h>
+#include <sys/mutex.h>
+#include <sys/callo.h>
+
+/*
+ * The kcondvar_t struct is protected by mutex taken externally before
+ * calling any of the wait/signal funs, and passed into the wait funs.
+ */
+#define	CV_MAGIC			0x346545f4
+#define	CV_DESTROY			0x346545f5
+
+typedef struct {
+	int cv_magic;
+	wait_queue_head_t cv_event;
+	wait_queue_head_t cv_destroy;
+	atomic_t cv_refs;
+	atomic_t cv_waiters;
+	kmutex_t *cv_mutex;
+} kcondvar_t;
+
+typedef enum { CV_DEFAULT = 0, CV_DRIVER } kcv_type_t;
+
+extern void __cv_init(kcondvar_t *, char *, kcv_type_t, void *);
+extern void __cv_destroy(kcondvar_t *);
+extern void __cv_wait(kcondvar_t *, kmutex_t *);
+extern void __cv_wait_io(kcondvar_t *, kmutex_t *);
+extern void __cv_wait_sig(kcondvar_t *, kmutex_t *);
+extern clock_t __cv_timedwait(kcondvar_t *, kmutex_t *, clock_t);
+extern clock_t __cv_timedwait_sig(kcondvar_t *, kmutex_t *, clock_t);
+extern clock_t cv_timedwait_hires(kcondvar_t *, kmutex_t *, hrtime_t,
+    hrtime_t res, int flag);
+extern void __cv_signal(kcondvar_t *);
+extern void __cv_broadcast(kcondvar_t *c);
+
+#define	cv_init(cvp, name, type, arg)		__cv_init(cvp, name, type, arg)
+#define	cv_destroy(cvp)				__cv_destroy(cvp)
+#define	cv_wait(cvp, mp)			__cv_wait(cvp, mp)
+#define	cv_wait_io(cvp, mp)			__cv_wait_io(cvp, mp)
+#define	cv_wait_sig(cvp, mp)			__cv_wait_sig(cvp, mp)
+#define	cv_wait_interruptible(cvp, mp)		cv_wait_sig(cvp, mp)
+#define	cv_timedwait(cvp, mp, t)		__cv_timedwait(cvp, mp, t)
+#define	cv_timedwait_sig(cvp, mp, t)		__cv_timedwait_sig(cvp, mp, t)
+#define	cv_timedwait_interruptible(cvp, mp, t)	cv_timedwait_sig(cvp, mp, t)
+#define	cv_signal(cvp)				__cv_signal(cvp)
+#define	cv_broadcast(cvp)			__cv_broadcast(cvp)
+
+#endif /* _SPL_CONDVAR_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/sys/conf.h
@@ -0,0 +1,28 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+\*****************************************************************************/
+
+#ifndef _SPL_CONF_H
+#define _SPL_CONF_H
+
+#endif /* SPL_CONF_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/sys/console.h
@@ -0,0 +1,44 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+\*****************************************************************************/
+
+#ifndef	_SPL_CONSOLE_H
+#define	_SPL_CONSOLE_H
+
+void
+console_vprintf(const char *fmt, va_list args)
+{
+        vprintk(fmt, args);
+}
+
+void
+console_printf(const char *fmt, ...)
+{
+        va_list args;
+
+        va_start(args, fmt);
+        console_vprintf(fmt, args);
+        va_end(args);
+}
+
+#endif /* _SPL_CONSOLE_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/sys/cpupart.h
@@ -0,0 +1,28 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+\*****************************************************************************/
+
+#ifndef _SPL_CPUPART_H
+#define _SPL_CPUPART_H
+
+#endif /* SPL_CPUPART_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/sys/cpuvar.h
@@ -0,0 +1,28 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+\*****************************************************************************/
+
+#ifndef _SPL_CPUVAR_H
+#define _SPL_CPUVAR_H
+
+#endif /* SPL_CPUVAR_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/sys/crc32.h
@@ -0,0 +1,28 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+\*****************************************************************************/
+
+#ifndef _SPL_CRC32_H
+#define _SPL_CRC32_H
+
+#endif /* SPL_CRC32_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/sys/cred.h
@@ -0,0 +1,81 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+\*****************************************************************************/
+
+#ifndef _SPL_CRED_H
+#define _SPL_CRED_H
+
+#include <linux/module.h>
+#include <sys/types.h>
+#include <sys/vfs.h>
+
+typedef struct cred cred_t;
+
+#define	kcred		((cred_t *)(init_task.cred))
+#define	CRED()		((cred_t *)current_cred())
+
+#ifdef HAVE_KUIDGID_T
+
+/*
+ * Linux 3.8+ uses typedefs to redefine uid_t and gid_t. We have to rename the
+ * typedefs to recover the original types. We then can use them provided that
+ * we are careful about translating from k{g,u}id_t to the original versions
+ * and vice versa.
+ */
+#define	uid_t		xuid_t
+#define	gid_t		xgid_t
+#include <linux/uidgid.h>
+#undef uid_t
+#undef gid_t
+
+#define	KUID_TO_SUID(x)		(__kuid_val(x))
+#define	KGID_TO_SGID(x)		(__kgid_val(x))
+#define	SUID_TO_KUID(x)		(KUIDT_INIT(x))
+#define	SGID_TO_KGID(x)		(KGIDT_INIT(x))
+#define	KGIDP_TO_SGIDP(x)	(&(x)->val)
+
+#else /* HAVE_KUIDGID_T */
+
+#define	KUID_TO_SUID(x)		(x)
+#define	KGID_TO_SGID(x)		(x)
+#define	SUID_TO_KUID(x)		(x)
+#define	SGID_TO_KGID(x)		(x)
+#define	KGIDP_TO_SGIDP(x)	(x)
+
+#endif /* HAVE_KUIDGID_T */
+
+extern void crhold(cred_t *cr);
+extern void crfree(cred_t *cr);
+extern uid_t crgetuid(const cred_t *cr);
+extern uid_t crgetruid(const cred_t *cr);
+extern uid_t crgetsuid(const cred_t *cr);
+extern uid_t crgetfsuid(const cred_t *cr);
+extern gid_t crgetgid(const cred_t *cr);
+extern gid_t crgetrgid(const cred_t *cr);
+extern gid_t crgetsgid(const cred_t *cr);
+extern gid_t crgetfsgid(const cred_t *cr);
+extern int crgetngroups(const cred_t *cr);
+extern gid_t * crgetgroups(const cred_t *cr);
+extern int groupmember(gid_t gid, const cred_t *cr);
+
+#endif  /* _SPL_CRED_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/sys/ctype.h
@@ -0,0 +1,30 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+\*****************************************************************************/
+
+#ifndef _SPL_CTYPE_H
+#define _SPL_CTYPE_H
+
+#include <linux/ctype.h>
+
+#endif /* SPL_CTYPE_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/sys/ddi.h
@@ -0,0 +1,28 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+\*****************************************************************************/
+
+#ifndef _SPL_DDI_H
+#define _SPL_DDI_H
+
+#endif /* SPL_DDI_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/sys/debug.h
@@ -0,0 +1,121 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+\*****************************************************************************/
+
+/*
+ * Available Solaris debug functions.  All of the ASSERT() macros will be
+ * compiled out when NDEBUG is defined, this is the default behavior for
+ * the SPL.  To enable assertions use the --enable-debug with configure.
+ * The VERIFY() functions are never compiled out and cannot be disabled.
+ *
+ * PANIC()	- Panic the node and print message.
+ * ASSERT()	- Assert X is true, if not panic.
+ * ASSERTV()	- Wraps a variable declaration which is only used by ASSERT().
+ * ASSERT3S()	- Assert signed X OP Y is true, if not panic.
+ * ASSERT3U()	- Assert unsigned X OP Y is true, if not panic.
+ * ASSERT3P()	- Assert pointer X OP Y is true, if not panic.
+ * ASSERT0()	- Assert value is zero, if not panic.
+ * VERIFY()	- Verify X is true, if not panic.
+ * VERIFY3S()	- Verify signed X OP Y is true, if not panic.
+ * VERIFY3U()	- Verify unsigned X OP Y is true, if not panic.
+ * VERIFY3P()	- Verify pointer X OP Y is true, if not panic.
+ * VERIFY0()	- Verify value is zero, if not panic.
+ */
+
+#ifndef _SPL_DEBUG_H
+#define	_SPL_DEBUG_H
+
+/*
+ * Common DEBUG functionality.
+ */
+int spl_panic(const char *file, const char *func, int line,
+    const char *fmt, ...);
+void spl_dumpstack(void);
+
+#define	PANIC(fmt, a...)						\
+	spl_panic(__FILE__, __FUNCTION__, __LINE__, fmt, ## a)
+
+#define	VERIFY(cond)							\
+	(void)(unlikely(!(cond)) &&					\
+	    spl_panic(__FILE__, __FUNCTION__, __LINE__,			\
+	    "%s", "VERIFY(" #cond ") failed\n"))
+
+#define	VERIFY3_IMPL(LEFT, OP, RIGHT, TYPE, FMT, CAST)			\
+	(void)((!((TYPE)(LEFT) OP (TYPE)(RIGHT))) &&			\
+	    spl_panic(__FILE__, __FUNCTION__, __LINE__,			\
+	    "VERIFY3(" #LEFT " " #OP " " #RIGHT ") "			\
+	    "failed (" FMT " " #OP " " FMT ")\n",			\
+	    CAST (LEFT), CAST (RIGHT)))
+
+#define	VERIFY3S(x,y,z)	VERIFY3_IMPL(x, y, z, int64_t, "%lld", (long long))
+#define	VERIFY3U(x,y,z)	VERIFY3_IMPL(x, y, z, uint64_t, "%llu",		\
+				    (unsigned long long))
+#define	VERIFY3P(x,y,z)	VERIFY3_IMPL(x, y, z, uintptr_t, "%p", (void *))
+#define	VERIFY0(x)	VERIFY3_IMPL(0, ==, x, int64_t, "%lld",	(long long))
+
+#define	CTASSERT_GLOBAL(x)		_CTASSERT(x, __LINE__)
+#define	CTASSERT(x)			{ _CTASSERT(x, __LINE__); }
+#define	_CTASSERT(x, y)			__CTASSERT(x, y)
+#define	__CTASSERT(x, y)						\
+	typedef char __attribute__ ((unused))				\
+	__compile_time_assertion__ ## y[(x) ? 1 : -1]
+
+/*
+ * Debugging disabled (--disable-debug)
+ */
+#ifdef NDEBUG
+
+#define	SPL_DEBUG_STR		""
+#define	ASSERT(x)		((void)0)
+#define	ASSERTV(x)
+#define	ASSERT3S(x,y,z)		((void)0)
+#define	ASSERT3U(x,y,z)		((void)0)
+#define	ASSERT3P(x,y,z)		((void)0)
+#define	ASSERT0(x)		((void)0)
+#define	IMPLY(A, B)		((void)0)
+#define	EQUIV(A, B)		((void)0)
+
+/*
+ * Debugging enabled (--enable-debug)
+ */
+#else
+
+#define	SPL_DEBUG_STR		" (DEBUG mode)"
+#define	ASSERT(cond)		VERIFY(cond)
+#define	ASSERTV(x)		x
+#define	ASSERT3S(x,y,z)		VERIFY3S(x, y, z)
+#define	ASSERT3U(x,y,z)		VERIFY3U(x, y, z)
+#define	ASSERT3P(x,y,z)		VERIFY3P(x, y, z)
+#define	ASSERT0(x)		VERIFY0(x)
+#define	IMPLY(A, B) \
+	((void)(((!(A)) || (B)) || \
+	    spl_panic(__FILE__, __FUNCTION__, __LINE__, \
+	    "(" #A ") implies (" #B ")")))
+#define	EQUIV(A, B) \
+	((void)((!!(A) == !!(B)) || \
+	    spl_panic(__FILE__, __FUNCTION__, __LINE__, \
+	    "(" #A ") is equivalent to (" #B ")")))
+
+#endif /* NDEBUG */
+
+#endif /* SPL_DEBUG_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/sys/dirent.h
@@ -0,0 +1,28 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+\*****************************************************************************/
+
+#ifndef _SPL_DIRENT_H
+#define _SPL_DIRENT_H
+
+#endif /* SPL_DIRENT_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/sys/disp.h
@@ -0,0 +1,34 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+\*****************************************************************************/
+
+#ifndef _SPL_DISP_H
+#define _SPL_DISP_H
+
+#include <linux/preempt.h>
+
+#define	kpreempt(unused)	schedule()
+#define	kpreempt_disable()	preempt_disable()
+#define	kpreempt_enable()	preempt_enable()
+
+#endif /* SPL_DISP_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/sys/dkio.h
@@ -0,0 +1,38 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+\*****************************************************************************/
+
+#ifndef _SPL_DKIO_H
+#define	_SPL_DKIO_H
+
+struct dk_callback {
+	void (*dkc_callback)(void *dkc_cookie, int error);
+	void *dkc_cookie;
+	int dkc_flag;
+};
+
+#define	DKIOC			(0x04 << 8)
+#define	DKIOCFLUSHWRITECACHE	(DKIOC | 34)
+#define	DKIOCTRIM		(DKIOC | 35)
+
+#endif /* _SPL_DKIO_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/sys/dklabel.h
@@ -0,0 +1,28 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+\*****************************************************************************/
+
+#ifndef _SPL_DKLABEL_H
+#define	_SPL_DKLABEL_H
+
+#endif	/* _SPL_DKLABEL_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/sys/dnlc.h
@@ -0,0 +1,28 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+\*****************************************************************************/
+
+#ifndef _SPL_DNLC_H
+#define _SPL_DNLC_H
+
+#endif /* SPL_DNLC_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/sys/dumphdr.h
@@ -0,0 +1,28 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+\*****************************************************************************/
+
+#ifndef _SPL_DUMPHDR_H
+#define _SPL_DUMPHDR_H
+
+#endif /* SPL_DUMPHDR_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/sys/efi_partition.h
@@ -0,0 +1,28 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+\*****************************************************************************/
+
+#ifndef _SPL_EFI_PARTITION_H
+#define _SPL_EFI_PARTITION_H
+
+#endif /* SPL_EFI_PARTITION_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/sys/errno.h
@@ -0,0 +1,28 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+\*****************************************************************************/
+
+#ifndef _SPL_ERRNO_H
+#define _SPL_ERRNO_H
+
+#endif /* SPL_ERRNO_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/sys/extdirent.h
@@ -0,0 +1,29 @@
+/*****************************************************************************\
+ *  Copyright (C) 2010 Lawrence Livermore National Security, LLC.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+\*****************************************************************************/
+
+#ifndef	_SPL_EXTDIRENT_H
+#define	_SPL_EXTDIRENT_H
+
+#define	ED_CASE_CONFLICT	0x10
+
+#endif /* _SPL_EXTDIRENT_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/sys/fcntl.h
@@ -0,0 +1,37 @@
+/*****************************************************************************\
+ *  Copyright (C) 2010 Lawrence Livermore National Security, LLC.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+\*****************************************************************************/
+
+#ifndef _SPL_FCNTL_H
+#define _SPL_FCNTL_H
+
+#include <asm/fcntl.h>
+
+#define F_FREESP 11
+
+#ifdef CONFIG_64BIT
+typedef struct flock flock64_t;
+#else
+typedef struct flock64 flock64_t;
+#endif /* CONFIG_64BIT */
+
+#endif /* _SPL_FCNTL_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/sys/file.h
@@ -0,0 +1,31 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+\*****************************************************************************/
+
+#ifndef _SPL_FILE_H
+#define _SPL_FILE_H
+
+#define	FIGNORECASE	0x00080000
+#define	FKIOCTL		0x80000000
+
+#endif /* SPL_FILE_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/sys/fm/Makefile.am
@@ -0,0 +1,14 @@
+COMMON_H =
+
+KERNEL_H = \
+	$(top_srcdir)/include/sys/fm/protocol.h \
+	$(top_srcdir)/include/sys/fm/util.h
+
+USER_H =
+
+EXTRA_DIST = $(COMMON_H) $(KERNEL_H) $(USER_H)
+
+if CONFIG_KERNEL
+kerneldir = @prefix@/src/spl-$(VERSION)/include/sys/fm
+kernel_HEADERS = $(KERNEL_H)
+endif
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/sys/fm/Makefile.in
@@ -0,0 +1,623 @@
+# Makefile.in generated by automake 1.15 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2014 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+VPATH = @srcdir@
+am__is_gnu_make = { \
+  if test -z '$(MAKELEVEL)'; then \
+    false; \
+  elif test -n '$(MAKE_HOST)'; then \
+    true; \
+  elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+    true; \
+  else \
+    false; \
+  fi; \
+}
+am__make_running_with_option = \
+  case $${target_option-} in \
+      ?) ;; \
+      *) echo "am__make_running_with_option: internal error: invalid" \
+              "target option '$${target_option-}' specified" >&2; \
+         exit 1;; \
+  esac; \
+  has_opt=no; \
+  sane_makeflags=$$MAKEFLAGS; \
+  if $(am__is_gnu_make); then \
+    sane_makeflags=$$MFLAGS; \
+  else \
+    case $$MAKEFLAGS in \
+      *\\[\ \	]*) \
+        bs=\\; \
+        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
+    esac; \
+  fi; \
+  skip_next=no; \
+  strip_trailopt () \
+  { \
+    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+  }; \
+  for flg in $$sane_makeflags; do \
+    test $$skip_next = yes && { skip_next=no; continue; }; \
+    case $$flg in \
+      *=*|--*) continue;; \
+        -*I) strip_trailopt 'I'; skip_next=yes;; \
+      -*I?*) strip_trailopt 'I';; \
+        -*O) strip_trailopt 'O'; skip_next=yes;; \
+      -*O?*) strip_trailopt 'O';; \
+        -*l) strip_trailopt 'l'; skip_next=yes;; \
+      -*l?*) strip_trailopt 'l';; \
+      -[dEDm]) skip_next=yes;; \
+      -[JT]) skip_next=yes;; \
+    esac; \
+    case $$flg in \
+      *$$target_option*) has_opt=yes; break;; \
+    esac; \
+  done; \
+  test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+target_triplet = @target@
+subdir = include/sys/fm
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/config/libtool.m4 \
+	$(top_srcdir)/config/ltoptions.m4 \
+	$(top_srcdir)/config/ltsugar.m4 \
+	$(top_srcdir)/config/ltversion.m4 \
+	$(top_srcdir)/config/lt~obsolete.m4 \
+	$(top_srcdir)/config/spl-build.m4 \
+	$(top_srcdir)/config/spl-meta.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(am__kernel_HEADERS_DIST) \
+	$(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/spl_config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo "  GEN     " $@;
+am__v_GEN_1 = 
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 = 
+SOURCES =
+DIST_SOURCES =
+am__can_run_installinfo = \
+  case $$AM_UPDATE_INFO_DIR in \
+    n|no|NO) false;; \
+    *) (install-info --version) >/dev/null 2>&1;; \
+  esac
+am__kernel_HEADERS_DIST = $(top_srcdir)/include/sys/fm/protocol.h \
+	$(top_srcdir)/include/sys/fm/util.h
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+    $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+    *) f=$$p;; \
+  esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+  srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+  for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+  for p in $$list; do echo "$$p $$p"; done | \
+  sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+  $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+    if (++n[$$2] == $(am__install_max)) \
+      { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+    END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+  sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+  sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+  test -z "$$files" \
+    || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+    || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+         $(am__cd) "$$dir" && rm -f $$files; }; \
+  }
+am__installdirs = "$(DESTDIR)$(kerneldir)"
+HEADERS = $(kernel_HEADERS)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates.  Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+  BEGIN { nonempty = 0; } \
+  { items[$$0] = 1; nonempty = 1; } \
+  END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique.  This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+  list='$(am__tagged_files)'; \
+  unique=`for i in $$list; do \
+    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+  done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+am__DIST_COMMON = $(srcdir)/Makefile.in
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ALIEN = @ALIEN@
+ALIEN_VERSION = @ALIEN_VERSION@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEBUG_CFLAGS = @DEBUG_CFLAGS@
+DEBUG_KMEM = @DEBUG_KMEM@
+DEBUG_KMEM_TRACKING = @DEBUG_KMEM_TRACKING@
+DEBUG_SPL = @DEBUG_SPL@
+DEFAULT_PACKAGE = @DEFAULT_PACKAGE@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DPKG = @DPKG@
+DPKGBUILD = @DPKGBUILD@
+DPKGBUILD_VERSION = @DPKGBUILD_VERSION@
+DPKG_VERSION = @DPKG_VERSION@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GREP = @GREP@
+HAVE_ALIEN = @HAVE_ALIEN@
+HAVE_DPKG = @HAVE_DPKG@
+HAVE_DPKGBUILD = @HAVE_DPKGBUILD@
+HAVE_RPM = @HAVE_RPM@
+HAVE_RPMBUILD = @HAVE_RPMBUILD@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+KERNELCPPFLAGS = @KERNELCPPFLAGS@
+KERNELMAKE_PARAMS = @KERNELMAKE_PARAMS@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LINUX = @LINUX@
+LINUX_OBJ = @LINUX_OBJ@
+LINUX_SYMBOLS = @LINUX_SYMBOLS@
+LINUX_VERSION = @LINUX_VERSION@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+RANLIB = @RANLIB@
+RELEASE = @RELEASE@
+RPM = @RPM@
+RPMBUILD = @RPMBUILD@
+RPMBUILD_VERSION = @RPMBUILD_VERSION@
+RPM_DEFINE_COMMON = @RPM_DEFINE_COMMON@
+RPM_DEFINE_DKMS = @RPM_DEFINE_DKMS@
+RPM_DEFINE_KMOD = @RPM_DEFINE_KMOD@
+RPM_DEFINE_UTIL = @RPM_DEFINE_UTIL@
+RPM_SPEC_DIR = @RPM_SPEC_DIR@
+RPM_VERSION = @RPM_VERSION@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SPL_CONFIG = @SPL_CONFIG@
+SPL_META_ALIAS = @SPL_META_ALIAS@
+SPL_META_AUTHOR = @SPL_META_AUTHOR@
+SPL_META_DATA = @SPL_META_DATA@
+SPL_META_LICENSE = @SPL_META_LICENSE@
+SPL_META_LT_AGE = @SPL_META_LT_AGE@
+SPL_META_LT_CURRENT = @SPL_META_LT_CURRENT@
+SPL_META_LT_REVISION = @SPL_META_LT_REVISION@
+SPL_META_NAME = @SPL_META_NAME@
+SPL_META_RELEASE = @SPL_META_RELEASE@
+SPL_META_VERSION = @SPL_META_VERSION@
+SRPM_DEFINE_COMMON = @SRPM_DEFINE_COMMON@
+SRPM_DEFINE_DKMS = @SRPM_DEFINE_DKMS@
+SRPM_DEFINE_KMOD = @SRPM_DEFINE_KMOD@
+SRPM_DEFINE_UTIL = @SRPM_DEFINE_UTIL@
+STRIP = @STRIP@
+VENDOR = @VENDOR@
+VERSION = @VERSION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+runstatedir = @runstatedir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+COMMON_H = 
+KERNEL_H = \
+	$(top_srcdir)/include/sys/fm/protocol.h \
+	$(top_srcdir)/include/sys/fm/util.h
+
+USER_H = 
+EXTRA_DIST = $(COMMON_H) $(KERNEL_H) $(USER_H)
+@CONFIG_KERNEL_TRUE@kerneldir = @prefix@/src/spl-$(VERSION)/include/sys/fm
+@CONFIG_KERNEL_TRUE@kernel_HEADERS = $(KERNEL_H)
+all: all-am
+
+.SUFFIXES:
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+	        && { if test -f $@; then exit 0; else break; fi; }; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu include/sys/fm/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --gnu include/sys/fm/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+	esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
+install-kernelHEADERS: $(kernel_HEADERS)
+	@$(NORMAL_INSTALL)
+	@list='$(kernel_HEADERS)'; test -n "$(kerneldir)" || list=; \
+	if test -n "$$list"; then \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(kerneldir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(kerneldir)" || exit 1; \
+	fi; \
+	for p in $$list; do \
+	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+	  echo "$$d$$p"; \
+	done | $(am__base_list) | \
+	while read files; do \
+	  echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(kerneldir)'"; \
+	  $(INSTALL_HEADER) $$files "$(DESTDIR)$(kerneldir)" || exit $$?; \
+	done
+
+uninstall-kernelHEADERS:
+	@$(NORMAL_UNINSTALL)
+	@list='$(kernel_HEADERS)'; test -n "$(kerneldir)" || list=; \
+	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+	dir='$(DESTDIR)$(kerneldir)'; $(am__uninstall_files_from_dir)
+
+ID: $(am__tagged_files)
+	$(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	set x; \
+	here=`pwd`; \
+	$(am__define_uniq_tagged_files); \
+	shift; \
+	if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+	  test -n "$$unique" || unique=$$empty_fix; \
+	  if test $$# -gt 0; then \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      "$$@" $$unique; \
+	  else \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      $$unique; \
+	  fi; \
+	fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	$(am__define_uniq_tagged_files); \
+	test -z "$(CTAGS_ARGS)$$unique" \
+	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+	     $$unique
+
+GTAGS:
+	here=`$(am__cd) $(top_builddir) && pwd` \
+	  && $(am__cd) $(top_srcdir) \
+	  && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+	list='$(am__tagged_files)'; \
+	case "$(srcdir)" in \
+	  [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+	  *) sdir=$(subdir)/$(srcdir) ;; \
+	esac; \
+	for i in $$list; do \
+	  if test -f "$$i"; then \
+	    echo "$(subdir)/$$i"; \
+	  else \
+	    echo "$$sdir/$$i"; \
+	  fi; \
+	done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	list='$(DISTFILES)'; \
+	  dist_files=`for file in $$list; do echo $$file; done | \
+	  sed -e "s|^$$srcdirstrip/||;t" \
+	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+	case $$dist_files in \
+	  */*) $(MKDIR_P) `echo "$$dist_files" | \
+			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+			   sort -u` ;; \
+	esac; \
+	for file in $$dist_files; do \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  if test -d $$d/$$file; then \
+	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+	    if test -d "$(distdir)/$$file"; then \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+	  else \
+	    test -f "$(distdir)/$$file" \
+	    || cp -p $$d/$$file "$(distdir)/$$file" \
+	    || exit 1; \
+	  fi; \
+	done
+check-am: all-am
+check: check-am
+all-am: Makefile $(HEADERS)
+installdirs:
+	for dir in "$(DESTDIR)$(kerneldir)"; do \
+	  test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+	done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+	if test -z '$(STRIP)'; then \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	      install; \
+	else \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+	fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-am
+	-rm -f Makefile
+distclean-am: clean-am distclean-generic distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-kernelHEADERS
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-kernelHEADERS
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \
+	clean-libtool cscopelist-am ctags ctags-am distclean \
+	distclean-generic distclean-libtool distclean-tags distdir dvi \
+	dvi-am html html-am info info-am install install-am \
+	install-data install-data-am install-dvi install-dvi-am \
+	install-exec install-exec-am install-html install-html-am \
+	install-info install-info-am install-kernelHEADERS install-man \
+	install-pdf install-pdf-am install-ps install-ps-am \
+	install-strip installcheck installcheck-am installdirs \
+	maintainer-clean maintainer-clean-generic mostlyclean \
+	mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+	tags tags-am uninstall uninstall-am uninstall-kernelHEADERS
+
+.PRECIOUS: Makefile
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/sys/fm/protocol.h
@@ -0,0 +1,28 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+\*****************************************************************************/
+
+#ifndef	_SPL_FM_PROTOCOL_H
+#define	_SPL_FM_PROTOCOL_H
+
+#endif /* _SPL_FM_PROTOCOL_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/sys/fm/util.h
@@ -0,0 +1,28 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+\*****************************************************************************/
+
+#ifndef	_SPL_FM_UTIL_H
+#define	_SPL_FM_UTIL_H
+
+#endif /* _SPL_FM_UTIL_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/sys/fs/Makefile.am
@@ -0,0 +1,13 @@
+COMMON_H =
+
+KERNEL_H = \
+	$(top_srcdir)/include/sys/fs/swapnode.h
+
+USER_H =
+
+EXTRA_DIST = $(COMMON_H) $(KERNEL_H) $(USER_H)
+
+if CONFIG_KERNEL
+kerneldir = @prefix@/src/spl-$(VERSION)/include/sys/fs
+kernel_HEADERS = $(KERNEL_H)
+endif
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/sys/fs/Makefile.in
@@ -0,0 +1,621 @@
+# Makefile.in generated by automake 1.15 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2014 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+VPATH = @srcdir@
+am__is_gnu_make = { \
+  if test -z '$(MAKELEVEL)'; then \
+    false; \
+  elif test -n '$(MAKE_HOST)'; then \
+    true; \
+  elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+    true; \
+  else \
+    false; \
+  fi; \
+}
+am__make_running_with_option = \
+  case $${target_option-} in \
+      ?) ;; \
+      *) echo "am__make_running_with_option: internal error: invalid" \
+              "target option '$${target_option-}' specified" >&2; \
+         exit 1;; \
+  esac; \
+  has_opt=no; \
+  sane_makeflags=$$MAKEFLAGS; \
+  if $(am__is_gnu_make); then \
+    sane_makeflags=$$MFLAGS; \
+  else \
+    case $$MAKEFLAGS in \
+      *\\[\ \	]*) \
+        bs=\\; \
+        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
+    esac; \
+  fi; \
+  skip_next=no; \
+  strip_trailopt () \
+  { \
+    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+  }; \
+  for flg in $$sane_makeflags; do \
+    test $$skip_next = yes && { skip_next=no; continue; }; \
+    case $$flg in \
+      *=*|--*) continue;; \
+        -*I) strip_trailopt 'I'; skip_next=yes;; \
+      -*I?*) strip_trailopt 'I';; \
+        -*O) strip_trailopt 'O'; skip_next=yes;; \
+      -*O?*) strip_trailopt 'O';; \
+        -*l) strip_trailopt 'l'; skip_next=yes;; \
+      -*l?*) strip_trailopt 'l';; \
+      -[dEDm]) skip_next=yes;; \
+      -[JT]) skip_next=yes;; \
+    esac; \
+    case $$flg in \
+      *$$target_option*) has_opt=yes; break;; \
+    esac; \
+  done; \
+  test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+target_triplet = @target@
+subdir = include/sys/fs
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/config/libtool.m4 \
+	$(top_srcdir)/config/ltoptions.m4 \
+	$(top_srcdir)/config/ltsugar.m4 \
+	$(top_srcdir)/config/ltversion.m4 \
+	$(top_srcdir)/config/lt~obsolete.m4 \
+	$(top_srcdir)/config/spl-build.m4 \
+	$(top_srcdir)/config/spl-meta.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(am__kernel_HEADERS_DIST) \
+	$(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/spl_config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo "  GEN     " $@;
+am__v_GEN_1 = 
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 = 
+SOURCES =
+DIST_SOURCES =
+am__can_run_installinfo = \
+  case $$AM_UPDATE_INFO_DIR in \
+    n|no|NO) false;; \
+    *) (install-info --version) >/dev/null 2>&1;; \
+  esac
+am__kernel_HEADERS_DIST = $(top_srcdir)/include/sys/fs/swapnode.h
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+    $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+    *) f=$$p;; \
+  esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+  srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+  for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+  for p in $$list; do echo "$$p $$p"; done | \
+  sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+  $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+    if (++n[$$2] == $(am__install_max)) \
+      { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+    END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+  sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+  sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+  test -z "$$files" \
+    || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+    || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+         $(am__cd) "$$dir" && rm -f $$files; }; \
+  }
+am__installdirs = "$(DESTDIR)$(kerneldir)"
+HEADERS = $(kernel_HEADERS)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates.  Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+  BEGIN { nonempty = 0; } \
+  { items[$$0] = 1; nonempty = 1; } \
+  END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique.  This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+  list='$(am__tagged_files)'; \
+  unique=`for i in $$list; do \
+    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+  done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+am__DIST_COMMON = $(srcdir)/Makefile.in
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ALIEN = @ALIEN@
+ALIEN_VERSION = @ALIEN_VERSION@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEBUG_CFLAGS = @DEBUG_CFLAGS@
+DEBUG_KMEM = @DEBUG_KMEM@
+DEBUG_KMEM_TRACKING = @DEBUG_KMEM_TRACKING@
+DEBUG_SPL = @DEBUG_SPL@
+DEFAULT_PACKAGE = @DEFAULT_PACKAGE@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DPKG = @DPKG@
+DPKGBUILD = @DPKGBUILD@
+DPKGBUILD_VERSION = @DPKGBUILD_VERSION@
+DPKG_VERSION = @DPKG_VERSION@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GREP = @GREP@
+HAVE_ALIEN = @HAVE_ALIEN@
+HAVE_DPKG = @HAVE_DPKG@
+HAVE_DPKGBUILD = @HAVE_DPKGBUILD@
+HAVE_RPM = @HAVE_RPM@
+HAVE_RPMBUILD = @HAVE_RPMBUILD@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+KERNELCPPFLAGS = @KERNELCPPFLAGS@
+KERNELMAKE_PARAMS = @KERNELMAKE_PARAMS@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LINUX = @LINUX@
+LINUX_OBJ = @LINUX_OBJ@
+LINUX_SYMBOLS = @LINUX_SYMBOLS@
+LINUX_VERSION = @LINUX_VERSION@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+RANLIB = @RANLIB@
+RELEASE = @RELEASE@
+RPM = @RPM@
+RPMBUILD = @RPMBUILD@
+RPMBUILD_VERSION = @RPMBUILD_VERSION@
+RPM_DEFINE_COMMON = @RPM_DEFINE_COMMON@
+RPM_DEFINE_DKMS = @RPM_DEFINE_DKMS@
+RPM_DEFINE_KMOD = @RPM_DEFINE_KMOD@
+RPM_DEFINE_UTIL = @RPM_DEFINE_UTIL@
+RPM_SPEC_DIR = @RPM_SPEC_DIR@
+RPM_VERSION = @RPM_VERSION@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SPL_CONFIG = @SPL_CONFIG@
+SPL_META_ALIAS = @SPL_META_ALIAS@
+SPL_META_AUTHOR = @SPL_META_AUTHOR@
+SPL_META_DATA = @SPL_META_DATA@
+SPL_META_LICENSE = @SPL_META_LICENSE@
+SPL_META_LT_AGE = @SPL_META_LT_AGE@
+SPL_META_LT_CURRENT = @SPL_META_LT_CURRENT@
+SPL_META_LT_REVISION = @SPL_META_LT_REVISION@
+SPL_META_NAME = @SPL_META_NAME@
+SPL_META_RELEASE = @SPL_META_RELEASE@
+SPL_META_VERSION = @SPL_META_VERSION@
+SRPM_DEFINE_COMMON = @SRPM_DEFINE_COMMON@
+SRPM_DEFINE_DKMS = @SRPM_DEFINE_DKMS@
+SRPM_DEFINE_KMOD = @SRPM_DEFINE_KMOD@
+SRPM_DEFINE_UTIL = @SRPM_DEFINE_UTIL@
+STRIP = @STRIP@
+VENDOR = @VENDOR@
+VERSION = @VERSION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+runstatedir = @runstatedir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+COMMON_H = 
+KERNEL_H = \
+	$(top_srcdir)/include/sys/fs/swapnode.h
+
+USER_H = 
+EXTRA_DIST = $(COMMON_H) $(KERNEL_H) $(USER_H)
+@CONFIG_KERNEL_TRUE@kerneldir = @prefix@/src/spl-$(VERSION)/include/sys/fs
+@CONFIG_KERNEL_TRUE@kernel_HEADERS = $(KERNEL_H)
+all: all-am
+
+.SUFFIXES:
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+	        && { if test -f $@; then exit 0; else break; fi; }; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu include/sys/fs/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --gnu include/sys/fs/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+	esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
+install-kernelHEADERS: $(kernel_HEADERS)
+	@$(NORMAL_INSTALL)
+	@list='$(kernel_HEADERS)'; test -n "$(kerneldir)" || list=; \
+	if test -n "$$list"; then \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(kerneldir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(kerneldir)" || exit 1; \
+	fi; \
+	for p in $$list; do \
+	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+	  echo "$$d$$p"; \
+	done | $(am__base_list) | \
+	while read files; do \
+	  echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(kerneldir)'"; \
+	  $(INSTALL_HEADER) $$files "$(DESTDIR)$(kerneldir)" || exit $$?; \
+	done
+
+uninstall-kernelHEADERS:
+	@$(NORMAL_UNINSTALL)
+	@list='$(kernel_HEADERS)'; test -n "$(kerneldir)" || list=; \
+	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+	dir='$(DESTDIR)$(kerneldir)'; $(am__uninstall_files_from_dir)
+
+ID: $(am__tagged_files)
+	$(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	set x; \
+	here=`pwd`; \
+	$(am__define_uniq_tagged_files); \
+	shift; \
+	if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+	  test -n "$$unique" || unique=$$empty_fix; \
+	  if test $$# -gt 0; then \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      "$$@" $$unique; \
+	  else \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      $$unique; \
+	  fi; \
+	fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	$(am__define_uniq_tagged_files); \
+	test -z "$(CTAGS_ARGS)$$unique" \
+	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+	     $$unique
+
+GTAGS:
+	here=`$(am__cd) $(top_builddir) && pwd` \
+	  && $(am__cd) $(top_srcdir) \
+	  && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+	list='$(am__tagged_files)'; \
+	case "$(srcdir)" in \
+	  [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+	  *) sdir=$(subdir)/$(srcdir) ;; \
+	esac; \
+	for i in $$list; do \
+	  if test -f "$$i"; then \
+	    echo "$(subdir)/$$i"; \
+	  else \
+	    echo "$$sdir/$$i"; \
+	  fi; \
+	done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	list='$(DISTFILES)'; \
+	  dist_files=`for file in $$list; do echo $$file; done | \
+	  sed -e "s|^$$srcdirstrip/||;t" \
+	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+	case $$dist_files in \
+	  */*) $(MKDIR_P) `echo "$$dist_files" | \
+			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+			   sort -u` ;; \
+	esac; \
+	for file in $$dist_files; do \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  if test -d $$d/$$file; then \
+	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+	    if test -d "$(distdir)/$$file"; then \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+	  else \
+	    test -f "$(distdir)/$$file" \
+	    || cp -p $$d/$$file "$(distdir)/$$file" \
+	    || exit 1; \
+	  fi; \
+	done
+check-am: all-am
+check: check-am
+all-am: Makefile $(HEADERS)
+installdirs:
+	for dir in "$(DESTDIR)$(kerneldir)"; do \
+	  test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+	done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+	if test -z '$(STRIP)'; then \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	      install; \
+	else \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+	fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-am
+	-rm -f Makefile
+distclean-am: clean-am distclean-generic distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-kernelHEADERS
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-kernelHEADERS
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \
+	clean-libtool cscopelist-am ctags ctags-am distclean \
+	distclean-generic distclean-libtool distclean-tags distdir dvi \
+	dvi-am html html-am info info-am install install-am \
+	install-data install-data-am install-dvi install-dvi-am \
+	install-exec install-exec-am install-html install-html-am \
+	install-info install-info-am install-kernelHEADERS install-man \
+	install-pdf install-pdf-am install-ps install-ps-am \
+	install-strip installcheck installcheck-am installdirs \
+	maintainer-clean maintainer-clean-generic mostlyclean \
+	mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+	tags tags-am uninstall uninstall-am uninstall-kernelHEADERS
+
+.PRECIOUS: Makefile
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/sys/fs/swapnode.h
@@ -0,0 +1,28 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+\*****************************************************************************/
+
+#ifndef _SPL_SWAPNODE_H
+#define _SPL_SWAPNODE_H
+
+#endif /* SPL_SWAPNODE_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/sys/idmap.h
@@ -0,0 +1,29 @@
+/*****************************************************************************\
+ *  Copyright (C) 2010 Lawrence Livermore National Security, LLC.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+\*****************************************************************************/
+
+#ifndef _SPL_IDMAP_H
+#define _SPL_IDMAP_H
+
+#define IDMAP_WK_CREATOR_OWNER_UID	2147483648U
+
+#endif /* SPL_IDMAP_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/sys/int_limits.h
@@ -0,0 +1,28 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+\*****************************************************************************/
+
+#ifndef _SPL_INT_LIMITS_H
+#define _SPL_INT_LIMITS_H
+
+#endif /* SPL_INT_LIMITS_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/sys/int_types.h
@@ -0,0 +1,30 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+\*****************************************************************************/
+
+#ifndef _SPL_INT_TYPES_H
+#define _SPL_INT_TYPES_H
+
+#include <sys/inttypes.h>
+
+#endif /* SPL_INT_TYPES_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/sys/inttypes.h
@@ -0,0 +1,28 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+\*****************************************************************************/
+
+#ifndef _SPL_INTTYPES_H
+#define _SPL_INTTYPES_H
+
+#endif /* SPL_INTTYPES_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/sys/isa_defs.h
@@ -0,0 +1,178 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+\*****************************************************************************/
+
+#ifndef	_SPL_ISA_DEFS_H
+#define	_SPL_ISA_DEFS_H
+
+/* x86_64 arch specific defines */
+#if defined(__x86_64) || defined(__x86_64__)
+
+#if !defined(__x86_64)
+#define __x86_64
+#endif
+
+#if !defined(__amd64)
+#define __amd64
+#endif
+
+#if !defined(__x86)
+#define __x86
+#endif
+
+#if !defined(_LP64)
+#define _LP64
+#endif
+
+/* i386 arch specific defines */
+#elif defined(__i386) || defined(__i386__)
+
+#if !defined(__i386)
+#define __i386
+#endif
+
+#if !defined(__x86)
+#define __x86
+#endif
+
+#if !defined(_ILP32)
+#define _ILP32
+#endif
+
+/* powerpc (ppc64) arch specific defines */
+#elif defined(__powerpc) || defined(__powerpc__) || defined(__powerpc64__)
+
+#if !defined(__powerpc)
+#define __powerpc
+#endif
+
+#if !defined(__powerpc__)
+#define __powerpc__
+#endif
+
+#if defined(__powerpc64__)
+#if !defined(_LP64)
+#define _LP64
+#endif
+#else
+#if !defined(_ILP32)
+#define _ILP32
+#endif
+#endif
+
+/* arm arch specific defines */
+#elif defined(__arm) || defined(__arm__) || defined(__aarch64__)
+
+#if !defined(__arm)
+#define __arm
+#endif
+
+#if !defined(__arm__)
+#define __arm__
+#endif
+
+#if defined(__aarch64__)
+#if !defined(_LP64)
+#define _LP64
+#endif
+#else
+#if !defined(_ILP32)
+#define _ILP32
+#endif
+#endif
+
+#if defined(__ARMEL__) || defined(__AARCH64EL__)
+#define _LITTLE_ENDIAN
+#else
+#define _BIG_ENDIAN
+#endif
+
+/* sparc arch specific defines */
+#elif defined(__sparc) || defined(__sparc__)
+
+#if !defined(__sparc)
+#define __sparc
+#endif
+
+#if !defined(__sparc__)
+#define __sparc__
+#endif
+
+#if defined(__arch64__)
+#if !defined(_LP64)
+#define _LP64
+#endif
+#else
+#if !defined(_ILP32)
+#define _ILP32
+#endif
+#endif
+
+#define _BIG_ENDIAN
+#define _SUNOS_VTOC_16
+
+/* s390 arch specific defines */
+#elif defined(__s390__)
+#if defined(__s390x__)
+#if !defined(_LP64)
+#define	_LP64
+#endif
+#else
+#if !defined(_ILP32)
+#define	_ILP32
+#endif
+#endif
+
+#define	_BIG_ENDIAN
+
+#else /* Currently x86_64, i386, arm, powerpc, s390, and sparc are supported */
+#error "Unsupported ISA type"
+#endif
+
+#if defined(_ILP32) && defined(_LP64)
+#error "Both _ILP32 and _LP64 are defined"
+#endif
+
+#if !defined(_ILP32) && !defined(_LP64)
+#error "Neither _ILP32 or _LP64 are defined"
+#endif
+
+#include <sys/byteorder.h>
+
+#if defined(__LITTLE_ENDIAN) && !defined(_LITTLE_ENDIAN)
+#define _LITTLE_ENDIAN __LITTLE_ENDIAN
+#endif
+
+#if defined(__BIG_ENDIAN) && !defined(_BIG_ENDIAN)
+#define _BIG_ENDIAN __BIG_ENDIAN
+#endif
+
+#if defined(_LITTLE_ENDIAN) && defined(_BIG_ENDIAN)
+#error "Both _LITTLE_ENDIAN and _BIG_ENDIAN are defined"
+#endif
+
+#if !defined(_LITTLE_ENDIAN) && !defined(_BIG_ENDIAN)
+#error "Neither _LITTLE_ENDIAN or _BIG_ENDIAN are defined"
+#endif
+
+#endif	/* _SPL_ISA_DEFS_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/sys/kidmap.h
@@ -0,0 +1,30 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+\*****************************************************************************/
+
+#ifndef _SPL_KIDMAP_H
+#define _SPL_KIDMAP_H
+
+#include <sys/idmap.h>
+
+#endif /* SPL_KIDMAP_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/sys/kmem.h
@@ -0,0 +1,156 @@
+/*
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _SPL_KMEM_H
+#define	_SPL_KMEM_H
+
+#include <sys/debug.h>
+#include <linux/slab.h>
+#include <linux/sched.h>
+
+extern int kmem_debugging(void);
+extern char *kmem_vasprintf(const char *fmt, va_list ap);
+extern char *kmem_asprintf(const char *fmt, ...);
+extern char *strdup(const char *str);
+extern void strfree(char *str);
+
+/*
+ * Memory allocation interfaces
+ */
+#define	KM_SLEEP	0x0000	/* can block for memory; success guaranteed */
+#define	KM_NOSLEEP	0x0001	/* cannot block for memory; may fail */
+#define	KM_PUSHPAGE	0x0004	/* can block for memory; may use reserve */
+#define	KM_ZERO		0x1000	/* zero the allocation */
+#define	KM_VMEM		0x2000	/* caller is vmem_* wrapper */
+
+#define	KM_PUBLIC_MASK	(KM_SLEEP | KM_NOSLEEP | KM_PUSHPAGE)
+
+/*
+ * Convert a KM_* flags mask to its Linux GFP_* counterpart.  The conversion
+ * function is context aware which means that KM_SLEEP allocations can be
+ * safely used in syncing contexts which have set PF_FSTRANS.
+ */
+static inline gfp_t
+kmem_flags_convert(int flags)
+{
+	gfp_t lflags = __GFP_NOWARN | __GFP_COMP;
+
+	if (flags & KM_NOSLEEP) {
+		lflags |= GFP_ATOMIC | __GFP_NORETRY;
+	} else {
+		lflags |= GFP_KERNEL;
+		if ((current->flags & PF_FSTRANS))
+			lflags &= ~(__GFP_IO|__GFP_FS);
+	}
+
+	if (flags & KM_PUSHPAGE)
+		lflags |= __GFP_HIGH;
+
+	if (flags & KM_ZERO)
+		lflags |= __GFP_ZERO;
+
+	return (lflags);
+}
+
+typedef struct {
+	struct task_struct *fstrans_thread;
+	unsigned int saved_flags;
+} fstrans_cookie_t;
+
+#ifdef PF_MEMALLOC_NOIO
+#define	SPL_FSTRANS (PF_FSTRANS|PF_MEMALLOC_NOIO)
+#else
+#define	SPL_FSTRANS (PF_FSTRANS)
+#endif
+
+static inline fstrans_cookie_t
+spl_fstrans_mark(void)
+{
+	fstrans_cookie_t cookie;
+
+	cookie.fstrans_thread = current;
+	cookie.saved_flags = current->flags & SPL_FSTRANS;
+	current->flags |= SPL_FSTRANS;
+
+	return (cookie);
+}
+
+static inline void
+spl_fstrans_unmark(fstrans_cookie_t cookie)
+{
+	ASSERT3P(cookie.fstrans_thread, ==, current);
+	ASSERT((current->flags & SPL_FSTRANS) == SPL_FSTRANS);
+
+	current->flags &= ~SPL_FSTRANS;
+	current->flags |= cookie.saved_flags;
+}
+
+static inline int
+spl_fstrans_check(void)
+{
+	return (current->flags & PF_FSTRANS);
+}
+
+#ifdef HAVE_ATOMIC64_T
+#define	kmem_alloc_used_add(size)	atomic64_add(size, &kmem_alloc_used)
+#define	kmem_alloc_used_sub(size)	atomic64_sub(size, &kmem_alloc_used)
+#define	kmem_alloc_used_read()		atomic64_read(&kmem_alloc_used)
+#define	kmem_alloc_used_set(size)	atomic64_set(&kmem_alloc_used, size)
+extern atomic64_t kmem_alloc_used;
+extern unsigned long long kmem_alloc_max;
+#else  /* HAVE_ATOMIC64_T */
+#define	kmem_alloc_used_add(size)	atomic_add(size, &kmem_alloc_used)
+#define	kmem_alloc_used_sub(size)	atomic_sub(size, &kmem_alloc_used)
+#define	kmem_alloc_used_read()		atomic_read(&kmem_alloc_used)
+#define	kmem_alloc_used_set(size)	atomic_set(&kmem_alloc_used, size)
+extern atomic_t kmem_alloc_used;
+extern unsigned long long kmem_alloc_max;
+#endif /* HAVE_ATOMIC64_T */
+
+extern unsigned int spl_kmem_alloc_warn;
+extern unsigned int spl_kmem_alloc_max;
+
+#define	kmem_alloc(sz, fl)	spl_kmem_alloc((sz), (fl), __func__, __LINE__)
+#define	kmem_zalloc(sz, fl)	spl_kmem_zalloc((sz), (fl), __func__, __LINE__)
+#define	kmem_free(ptr, sz)	spl_kmem_free((ptr), (sz))
+
+extern void *spl_kmem_alloc(size_t sz, int fl, const char *func, int line);
+extern void *spl_kmem_zalloc(size_t sz, int fl, const char *func, int line);
+extern void spl_kmem_free(const void *ptr, size_t sz);
+
+/*
+ * The following functions are only available for internal use.
+ */
+extern void *spl_kmem_alloc_impl(size_t size, int flags, int node);
+extern void *spl_kmem_alloc_debug(size_t size, int flags, int node);
+extern void *spl_kmem_alloc_track(size_t size, int flags,
+    const char *func, int line, int node);
+extern void spl_kmem_free_impl(const void *buf, size_t size);
+extern void spl_kmem_free_debug(const void *buf, size_t size);
+extern void spl_kmem_free_track(const void *buf, size_t size);
+
+extern int spl_kmem_init(void);
+extern void spl_kmem_fini(void);
+
+#endif	/* _SPL_KMEM_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/sys/kmem_cache.h
@@ -0,0 +1,240 @@
+/*
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _SPL_KMEM_CACHE_H
+#define	_SPL_KMEM_CACHE_H
+
+#include <sys/taskq.h>
+
+/*
+ * Slab allocation interfaces.  The SPL slab differs from the standard
+ * Linux SLAB or SLUB primarily in that each cache may be backed by slabs
+ * allocated from the physical or virtal memory address space.  The virtual
+ * slabs allow for good behavior when allocation large objects of identical
+ * size.  This slab implementation also supports both constructors and
+ * destructors which the Linux slab does not.
+ */
+enum {
+	KMC_BIT_NOTOUCH		= 0,	/* Don't update ages */
+	KMC_BIT_NODEBUG		= 1,	/* Default behavior */
+	KMC_BIT_NOMAGAZINE	= 2,	/* XXX: Unsupported */
+	KMC_BIT_NOHASH		= 3,	/* XXX: Unsupported */
+	KMC_BIT_QCACHE		= 4,	/* XXX: Unsupported */
+	KMC_BIT_KMEM		= 5,	/* Use kmem cache */
+	KMC_BIT_VMEM		= 6,	/* Use vmem cache */
+	KMC_BIT_SLAB		= 7,	/* Use Linux slab cache */
+	KMC_BIT_OFFSLAB		= 8,	/* Objects not on slab */
+	KMC_BIT_NOEMERGENCY	= 9,	/* Disable emergency objects */
+	KMC_BIT_DEADLOCKED	= 14,	/* Deadlock detected */
+	KMC_BIT_GROWING		= 15,	/* Growing in progress */
+	KMC_BIT_REAPING		= 16,	/* Reaping in progress */
+	KMC_BIT_DESTROY		= 17,	/* Destroy in progress */
+	KMC_BIT_TOTAL		= 18,	/* Proc handler helper bit */
+	KMC_BIT_ALLOC		= 19,	/* Proc handler helper bit */
+	KMC_BIT_MAX		= 20,	/* Proc handler helper bit */
+};
+
+/* kmem move callback return values */
+typedef enum kmem_cbrc {
+	KMEM_CBRC_YES		= 0,	/* Object moved */
+	KMEM_CBRC_NO		= 1,	/* Object not moved */
+	KMEM_CBRC_LATER		= 2,	/* Object not moved, try again later */
+	KMEM_CBRC_DONT_NEED	= 3,	/* Neither object is needed */
+	KMEM_CBRC_DONT_KNOW	= 4,	/* Object unknown */
+} kmem_cbrc_t;
+
+#define	KMC_NOTOUCH		(1 << KMC_BIT_NOTOUCH)
+#define	KMC_NODEBUG		(1 << KMC_BIT_NODEBUG)
+#define	KMC_NOMAGAZINE		(1 << KMC_BIT_NOMAGAZINE)
+#define	KMC_NOHASH		(1 << KMC_BIT_NOHASH)
+#define	KMC_QCACHE		(1 << KMC_BIT_QCACHE)
+#define	KMC_KMEM		(1 << KMC_BIT_KMEM)
+#define	KMC_VMEM		(1 << KMC_BIT_VMEM)
+#define	KMC_SLAB		(1 << KMC_BIT_SLAB)
+#define	KMC_OFFSLAB		(1 << KMC_BIT_OFFSLAB)
+#define	KMC_NOEMERGENCY		(1 << KMC_BIT_NOEMERGENCY)
+#define	KMC_DEADLOCKED		(1 << KMC_BIT_DEADLOCKED)
+#define	KMC_GROWING		(1 << KMC_BIT_GROWING)
+#define	KMC_REAPING		(1 << KMC_BIT_REAPING)
+#define	KMC_DESTROY		(1 << KMC_BIT_DESTROY)
+#define	KMC_TOTAL		(1 << KMC_BIT_TOTAL)
+#define	KMC_ALLOC		(1 << KMC_BIT_ALLOC)
+#define	KMC_MAX			(1 << KMC_BIT_MAX)
+
+#define	KMC_REAP_CHUNK		INT_MAX
+#define	KMC_DEFAULT_SEEKS	1
+
+#define	KMC_EXPIRE_AGE		0x1	/* Due to age */
+#define	KMC_EXPIRE_MEM		0x2	/* Due to low memory */
+
+#define	KMC_RECLAIM_ONCE	0x1	/* Force a single shrinker pass */
+
+extern unsigned int spl_kmem_cache_expire;
+extern struct list_head spl_kmem_cache_list;
+extern struct rw_semaphore spl_kmem_cache_sem;
+
+#define	SKM_MAGIC			0x2e2e2e2e
+#define	SKO_MAGIC			0x20202020
+#define	SKS_MAGIC			0x22222222
+#define	SKC_MAGIC			0x2c2c2c2c
+
+#define	SPL_KMEM_CACHE_DELAY		15	/* Minimum slab release age */
+#define	SPL_KMEM_CACHE_REAP		0	/* Default reap everything */
+#define	SPL_KMEM_CACHE_OBJ_PER_SLAB	8	/* Target objects per slab */
+#define	SPL_KMEM_CACHE_OBJ_PER_SLAB_MIN	1	/* Minimum objects per slab */
+#define	SPL_KMEM_CACHE_ALIGN		8	/* Default object alignment */
+#ifdef _LP64
+#define	SPL_KMEM_CACHE_MAX_SIZE		32	/* Max slab size in MB */
+#else
+#define	SPL_KMEM_CACHE_MAX_SIZE		4	/* Max slab size in MB */
+#endif
+
+#define	SPL_MAX_ORDER			(MAX_ORDER - 3)
+#define	SPL_MAX_ORDER_NR_PAGES		(1 << (SPL_MAX_ORDER - 1))
+
+#ifdef CONFIG_SLUB
+#define	SPL_MAX_KMEM_CACHE_ORDER	PAGE_ALLOC_COSTLY_ORDER
+#define	SPL_MAX_KMEM_ORDER_NR_PAGES	(1 << (SPL_MAX_KMEM_CACHE_ORDER - 1))
+#else
+#define	SPL_MAX_KMEM_ORDER_NR_PAGES	(KMALLOC_MAX_SIZE >> PAGE_SHIFT)
+#endif
+
+#define	POINTER_IS_VALID(p)		0	/* Unimplemented */
+#define	POINTER_INVALIDATE(pp)			/* Unimplemented */
+
+typedef int (*spl_kmem_ctor_t)(void *, void *, int);
+typedef void (*spl_kmem_dtor_t)(void *, void *);
+typedef void (*spl_kmem_reclaim_t)(void *);
+
+typedef struct spl_kmem_magazine {
+	uint32_t		skm_magic;	/* Sanity magic */
+	uint32_t		skm_avail;	/* Available objects */
+	uint32_t		skm_size;	/* Magazine size */
+	uint32_t		skm_refill;	/* Batch refill size */
+	struct spl_kmem_cache	*skm_cache;	/* Owned by cache */
+	unsigned long		skm_age;	/* Last cache access */
+	unsigned int		skm_cpu;	/* Owned by cpu */
+	void			*skm_objs[0];	/* Object pointers */
+} spl_kmem_magazine_t;
+
+typedef struct spl_kmem_obj {
+	uint32_t		sko_magic;	/* Sanity magic */
+	void			*sko_addr;	/* Buffer address */
+	struct spl_kmem_slab	*sko_slab;	/* Owned by slab */
+	struct list_head	sko_list;	/* Free object list linkage */
+} spl_kmem_obj_t;
+
+typedef struct spl_kmem_slab {
+	uint32_t		sks_magic;	/* Sanity magic */
+	uint32_t		sks_objs;	/* Objects per slab */
+	struct spl_kmem_cache	*sks_cache;	/* Owned by cache */
+	struct list_head	sks_list;	/* Slab list linkage */
+	struct list_head	sks_free_list;	/* Free object list */
+	unsigned long		sks_age;	/* Last modify jiffie */
+	uint32_t		sks_ref;	/* Ref count used objects */
+} spl_kmem_slab_t;
+
+typedef struct spl_kmem_alloc {
+	struct spl_kmem_cache	*ska_cache;	/* Owned by cache */
+	int			ska_flags;	/* Allocation flags */
+	taskq_ent_t		ska_tqe;	/* Task queue entry */
+} spl_kmem_alloc_t;
+
+typedef struct spl_kmem_emergency {
+	struct rb_node		ske_node;	/* Emergency tree linkage */
+	unsigned long		ske_obj;	/* Buffer address */
+} spl_kmem_emergency_t;
+
+typedef struct spl_kmem_cache {
+	uint32_t		skc_magic;	/* Sanity magic */
+	uint32_t		skc_name_size;	/* Name length */
+	char			*skc_name;	/* Name string */
+	spl_kmem_magazine_t	**skc_mag;	/* Per-CPU warm cache */
+	uint32_t		skc_mag_size;	/* Magazine size */
+	uint32_t		skc_mag_refill;	/* Magazine refill count */
+	spl_kmem_ctor_t		skc_ctor;	/* Constructor */
+	spl_kmem_dtor_t		skc_dtor;	/* Destructor */
+	spl_kmem_reclaim_t	skc_reclaim;	/* Reclaimator */
+	void			*skc_private;	/* Private data */
+	void			*skc_vmp;	/* Unused */
+	struct kmem_cache	*skc_linux_cache; /* Linux slab cache if used */
+	unsigned long		skc_flags;	/* Flags */
+	uint32_t		skc_obj_size;	/* Object size */
+	uint32_t		skc_obj_align;	/* Object alignment */
+	uint32_t		skc_slab_objs;	/* Objects per slab */
+	uint32_t		skc_slab_size;	/* Slab size */
+	uint32_t		skc_delay;	/* Slab reclaim interval */
+	uint32_t		skc_reap;	/* Slab reclaim count */
+	atomic_t		skc_ref;	/* Ref count callers */
+	taskqid_t		skc_taskqid;	/* Slab reclaim task */
+	struct list_head	skc_list;	/* List of caches linkage */
+	struct list_head	skc_complete_list; /* Completely alloc'ed */
+	struct list_head	skc_partial_list;  /* Partially alloc'ed */
+	struct rb_root		skc_emergency_tree; /* Min sized objects */
+	spinlock_t		skc_lock;	/* Cache lock */
+	wait_queue_head_t	skc_waitq;	/* Allocation waiters */
+	uint64_t		skc_slab_fail;	/* Slab alloc failures */
+	uint64_t		skc_slab_create;  /* Slab creates */
+	uint64_t		skc_slab_destroy; /* Slab destroys */
+	uint64_t		skc_slab_total;	/* Slab total current */
+	uint64_t		skc_slab_alloc;	/* Slab alloc current */
+	uint64_t		skc_slab_max;	/* Slab max historic  */
+	uint64_t		skc_obj_total;	/* Obj total current */
+	uint64_t		skc_obj_alloc;	/* Obj alloc current */
+	uint64_t		skc_obj_max;	/* Obj max historic */
+	uint64_t		skc_obj_deadlock;  /* Obj emergency deadlocks */
+	uint64_t		skc_obj_emergency; /* Obj emergency current */
+	uint64_t		skc_obj_emergency_max; /* Obj emergency max */
+} spl_kmem_cache_t;
+#define	kmem_cache_t		spl_kmem_cache_t
+
+extern spl_kmem_cache_t *spl_kmem_cache_create(char *name, size_t size,
+    size_t align, spl_kmem_ctor_t ctor, spl_kmem_dtor_t dtor,
+    spl_kmem_reclaim_t reclaim, void *priv, void *vmp, int flags);
+extern void spl_kmem_cache_set_move(spl_kmem_cache_t *,
+    kmem_cbrc_t (*)(void *, void *, size_t, void *));
+extern void spl_kmem_cache_destroy(spl_kmem_cache_t *skc);
+extern void *spl_kmem_cache_alloc(spl_kmem_cache_t *skc, int flags);
+extern void spl_kmem_cache_free(spl_kmem_cache_t *skc, void *obj);
+extern void spl_kmem_cache_set_allocflags(spl_kmem_cache_t *skc, gfp_t flags);
+extern void spl_kmem_cache_reap_now(spl_kmem_cache_t *skc, int count);
+extern void spl_kmem_reap(void);
+
+#define	kmem_cache_create(name, size, align, ctor, dtor, rclm, priv, vmp, fl) \
+    spl_kmem_cache_create(name, size, align, ctor, dtor, rclm, priv, vmp, fl)
+#define	kmem_cache_set_move(skc, move)	spl_kmem_cache_set_move(skc, move)
+#define	kmem_cache_destroy(skc)		spl_kmem_cache_destroy(skc)
+#define	kmem_cache_alloc(skc, flags)	spl_kmem_cache_alloc(skc, flags)
+#define	kmem_cache_free(skc, obj)	spl_kmem_cache_free(skc, obj)
+#define	kmem_cache_reap_now(skc)	\
+    spl_kmem_cache_reap_now(skc, skc->skc_reap)
+#define	kmem_reap()			spl_kmem_reap()
+
+/*
+ * The following functions are only available for internal use.
+ */
+extern int spl_kmem_cache_init(void);
+extern void spl_kmem_cache_fini(void);
+
+#endif	/* _SPL_KMEM_CACHE_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/sys/kobj.h
@@ -0,0 +1,42 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+\*****************************************************************************/
+
+#ifndef _SPL_KOBJ_H
+#define _SPL_KOBJ_H
+
+#include <sys/vnode.h>
+
+typedef struct _buf {
+	vnode_t *vp;
+} _buf_t;
+
+typedef struct _buf buf_t;
+
+extern struct _buf *kobj_open_file(const char *name);
+extern void kobj_close_file(struct _buf *file);
+extern int kobj_read_file(struct _buf *file, char *buf,
+			  ssize_t size, offset_t off);
+extern int kobj_get_filesize(struct _buf *file, uint64_t *size);
+
+#endif /* SPL_KOBJ_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/sys/kstat.h
@@ -0,0 +1,202 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+\*****************************************************************************/
+
+#ifndef _SPL_KSTAT_H
+#define _SPL_KSTAT_H
+
+#include <linux/module.h>
+#include <linux/proc_compat.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/kmem.h>
+#include <sys/mutex.h>
+
+#define KSTAT_STRLEN            31
+#define KSTAT_RAW_MAX		(128*1024)
+
+/* For reference valid classes are:
+ * disk, tape, net, controller, vm, kvm, hat, streams, kstat, misc
+ */
+
+#define KSTAT_TYPE_RAW          0       /* can be anything; ks_ndata >= 1 */
+#define KSTAT_TYPE_NAMED        1       /* name/value pair; ks_ndata >= 1 */
+#define KSTAT_TYPE_INTR         2       /* interrupt stats; ks_ndata == 1 */
+#define KSTAT_TYPE_IO           3       /* I/O stats; ks_ndata == 1 */
+#define KSTAT_TYPE_TIMER        4       /* event timer; ks_ndata >= 1 */
+#define KSTAT_NUM_TYPES         5
+
+#define KSTAT_DATA_CHAR         0
+#define KSTAT_DATA_INT32        1
+#define KSTAT_DATA_UINT32       2
+#define KSTAT_DATA_INT64        3
+#define KSTAT_DATA_UINT64       4
+#define KSTAT_DATA_LONG         5
+#define KSTAT_DATA_ULONG        6
+#define KSTAT_DATA_STRING       7
+#define KSTAT_NUM_DATAS         8
+
+#define KSTAT_INTR_HARD         0
+#define KSTAT_INTR_SOFT         1
+#define KSTAT_INTR_WATCHDOG     2
+#define KSTAT_INTR_SPURIOUS     3
+#define KSTAT_INTR_MULTSVC      4
+#define KSTAT_NUM_INTRS         5
+
+#define KSTAT_FLAG_VIRTUAL      0x01
+#define KSTAT_FLAG_VAR_SIZE     0x02
+#define KSTAT_FLAG_WRITABLE     0x04
+#define KSTAT_FLAG_PERSISTENT   0x08
+#define KSTAT_FLAG_DORMANT      0x10
+#define KSTAT_FLAG_UNSUPPORTED  (KSTAT_FLAG_VAR_SIZE | KSTAT_FLAG_WRITABLE | \
+				 KSTAT_FLAG_PERSISTENT | KSTAT_FLAG_DORMANT)
+
+
+#define KS_MAGIC                0x9d9d9d9d
+
+/* Dynamic updates */
+#define KSTAT_READ              0
+#define KSTAT_WRITE             1
+
+struct kstat_s;
+typedef struct kstat_s kstat_t;
+
+typedef int kid_t;                                  /* unique kstat id */
+typedef int kstat_update_t(struct kstat_s *, int);  /* dynamic update cb */
+
+typedef struct kstat_module {
+	char             ksm_name[KSTAT_STRLEN+1];  /* module name */
+	struct list_head ksm_module_list;           /* module linkage */
+	struct list_head ksm_kstat_list;            /* list of kstat entries */
+	struct proc_dir_entry *ksm_proc;            /* proc entry */
+} kstat_module_t;
+
+typedef struct kstat_raw_ops {
+	int (*headers)(char *buf, size_t size);
+	int (*data)(char *buf, size_t size, void *data);
+	void *(*addr)(kstat_t *ksp, loff_t index);
+} kstat_raw_ops_t;
+
+struct kstat_s {
+	int              ks_magic;                  /* magic value */
+        kid_t            ks_kid;                    /* unique kstat ID */
+        hrtime_t         ks_crtime;                 /* creation time */
+	hrtime_t         ks_snaptime;               /* last access time */
+        char             ks_module[KSTAT_STRLEN+1]; /* provider module name */
+        int              ks_instance;               /* provider module instance */
+        char             ks_name[KSTAT_STRLEN+1];   /* kstat name */
+        char             ks_class[KSTAT_STRLEN+1];  /* kstat class */
+        uchar_t          ks_type;                   /* kstat data type */
+        uchar_t          ks_flags;                  /* kstat flags */
+        void             *ks_data;                  /* kstat type-specific data */
+        uint_t           ks_ndata;                  /* # of type-specific data records */
+        size_t           ks_data_size;              /* size of kstat data section */
+        struct proc_dir_entry *ks_proc;             /* proc linkage */
+        kstat_update_t   *ks_update;                /* dynamic updates */
+        void             *ks_private;               /* private data */
+	kmutex_t         ks_private_lock;           /* kstat private data lock */
+	kmutex_t         *ks_lock;                  /* kstat data lock */
+        struct list_head ks_list;                   /* kstat linkage */
+	kstat_module_t   *ks_owner;                 /* kstat module linkage */
+	kstat_raw_ops_t  ks_raw_ops;                /* ops table for raw type */
+	char             *ks_raw_buf;               /* buf used for raw ops */
+	size_t           ks_raw_bufsize;            /* size of raw ops buffer */
+};
+
+typedef struct kstat_named_s {
+        char             name[KSTAT_STRLEN];        /* name of counter */
+        uchar_t          data_type;                 /* data type */
+        union {
+                char            c[16];              /* 128-bit int */
+                int32_t         i32;                /* 32-bit signed int */
+                uint32_t        ui32;               /* 32-bit unsigned int */
+                int64_t         i64;                /* 64-bit signed int */
+                uint64_t        ui64;               /* 64-bit unsigned int */
+                long            l;                  /* native signed long */
+                ulong_t         ul;                 /* native unsigned long */
+                struct {
+                        union {
+                                char *ptr;          /* NULL-term string */
+                                char __pad[8];      /* 64-bit padding */
+                        } addr;
+                        uint32_t len;               /* # bytes for strlen + '\0' */
+                } string;
+        } value;
+} kstat_named_t;
+
+#define KSTAT_NAMED_STR_PTR(knptr) ((knptr)->value.string.addr.ptr)
+#define KSTAT_NAMED_STR_BUFLEN(knptr) ((knptr)->value.string.len)
+
+typedef struct kstat_intr {
+        uint_t intrs[KSTAT_NUM_INTRS];
+} kstat_intr_t;
+
+typedef struct kstat_io {
+        u_longlong_t     nread;       /* number of bytes read */
+        u_longlong_t     nwritten;    /* number of bytes written */
+        uint_t           reads;       /* number of read operations */
+        uint_t           writes;      /* number of write operations */
+        hrtime_t         wtime;       /* cumulative wait (pre-service) time */
+        hrtime_t         wlentime;    /* cumulative wait length*time product*/
+        hrtime_t         wlastupdate; /* last time wait queue changed */
+        hrtime_t         rtime;       /* cumulative run (service) time */
+        hrtime_t         rlentime;    /* cumulative run length*time product */
+        hrtime_t         rlastupdate; /* last time run queue changed */
+        uint_t           wcnt;        /* count of elements in wait state */
+        uint_t           rcnt;        /* count of elements in run state */
+} kstat_io_t;
+
+typedef struct kstat_timer {
+        char         name[KSTAT_STRLEN+1]; /* event name */
+        u_longlong_t num_events;           /* number of events */
+        hrtime_t     elapsed_time;         /* cumulative elapsed time */
+        hrtime_t     min_time;             /* shortest event duration */
+        hrtime_t     max_time;             /* longest event duration */
+        hrtime_t     start_time;           /* previous event start time */
+        hrtime_t     stop_time;            /* previous event stop time */
+} kstat_timer_t;
+
+int spl_kstat_init(void);
+void spl_kstat_fini(void);
+
+extern void __kstat_set_raw_ops(kstat_t *ksp,
+		    int (*headers)(char *buf, size_t size),
+		    int (*data)(char *buf, size_t size, void *data),
+		    void* (*addr)(kstat_t *ksp, loff_t index));
+extern kstat_t *__kstat_create(const char *ks_module, int ks_instance,
+			     const char *ks_name, const char *ks_class,
+			     uchar_t ks_type, uint_t ks_ndata,
+			     uchar_t ks_flags);
+extern void __kstat_install(kstat_t *ksp);
+extern void __kstat_delete(kstat_t *ksp);
+extern void kstat_waitq_enter(kstat_io_t *);
+extern void kstat_waitq_exit(kstat_io_t *);
+extern void kstat_runq_enter(kstat_io_t *);
+extern void kstat_runq_exit(kstat_io_t *);
+
+#define kstat_set_raw_ops(k,h,d,a)	__kstat_set_raw_ops(k,h,d,a)
+#define kstat_create(m,i,n,c,t,s,f)	__kstat_create(m,i,n,c,t,s,f)
+#define kstat_install(k)		__kstat_install(k)
+#define kstat_delete(k)			__kstat_delete(k)
+
+#endif  /* _SPL_KSTAT_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/sys/list.h
@@ -0,0 +1,219 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+\*****************************************************************************/
+
+#ifndef _SPL_LIST_H
+#define _SPL_LIST_H
+
+#include <sys/types.h>
+#include <linux/list.h>
+
+/*
+ * NOTE: I have implemented the Solaris list API in terms of the native
+ * linux API.  This has certain advantages in terms of leveraging the linux
+ * list debugging infrastructure, but it also means that the internals of a
+ * list differ slightly than on Solaris.  This is not a problem as long as
+ * all callers stick to the published API.  The two major differences are:
+ *
+ * 1) A list_node_t is mapped to a linux list_head struct which changes
+ *    the name of the list_next/list_prev pointers to next/prev respectively.
+ *
+ * 2) A list_node_t which is not attached to a list on Solaris is denoted
+ *    by having its list_next/list_prev pointers set to NULL.  Under linux
+ *    the next/prev pointers are set to LIST_POISON1 and LIST_POISON2
+ *    respectively.  At this moment this only impacts the implementation
+ *    of the list_link_init() and list_link_active() functions.
+ */
+
+typedef struct list_head list_node_t;
+
+typedef struct list {
+	size_t list_size;
+	size_t list_offset;
+	list_node_t list_head;
+} list_t;
+
+#define list_d2l(a, obj) ((list_node_t *)(((char *)obj) + (a)->list_offset))
+#define list_object(a, node) ((void *)(((char *)node) - (a)->list_offset))
+
+static inline int
+list_is_empty(list_t *list)
+{
+	return list_empty(&list->list_head);
+}
+
+static inline void
+list_link_init(list_node_t *node)
+{
+	node->next = LIST_POISON1;
+	node->prev = LIST_POISON2;
+}
+
+static inline void
+list_create(list_t *list, size_t size, size_t offset)
+{
+	ASSERT(list);
+	ASSERT(size > 0);
+	ASSERT(size >= offset + sizeof(list_node_t));
+
+	list->list_size = size;
+	list->list_offset = offset;
+	INIT_LIST_HEAD(&list->list_head);
+}
+
+static inline void
+list_destroy(list_t *list)
+{
+	ASSERT(list);
+	ASSERT(list_is_empty(list));
+
+	list_del(&list->list_head);
+}
+
+static inline void
+list_insert_head(list_t *list, void *object)
+{
+	list_add(list_d2l(list, object), &list->list_head);
+}
+
+static inline void
+list_insert_tail(list_t *list, void *object)
+{
+	list_add_tail(list_d2l(list, object), &list->list_head);
+}
+
+static inline void
+list_insert_after(list_t *list, void *object, void *nobject)
+{
+	if (object == NULL)
+		list_insert_head(list, nobject);
+	else
+		list_add(list_d2l(list, nobject), list_d2l(list, object));
+}
+
+static inline void
+list_insert_before(list_t *list, void *object, void *nobject)
+{
+	if (object == NULL)
+		list_insert_tail(list, nobject);
+	else
+		list_add_tail(list_d2l(list, nobject), list_d2l(list, object));
+}
+
+static inline void
+list_remove(list_t *list, void *object)
+{
+	ASSERT(!list_is_empty(list));
+	list_del(list_d2l(list, object));
+}
+
+static inline void *
+list_remove_head(list_t *list)
+{
+	list_node_t *head = list->list_head.next;
+	if (head == &list->list_head)
+		return NULL;
+
+	list_del(head);
+	return list_object(list, head);
+}
+
+static inline void *
+list_remove_tail(list_t *list)
+{
+	list_node_t *tail = list->list_head.prev;
+	if (tail == &list->list_head)
+		return NULL;
+
+	list_del(tail);
+	return list_object(list, tail);
+}
+
+static inline void *
+list_head(list_t *list)
+{
+	if (list_is_empty(list))
+		return NULL;
+
+	return list_object(list, list->list_head.next);
+}
+
+static inline void *
+list_tail(list_t *list)
+{
+	if (list_is_empty(list))
+		return NULL;
+
+	return list_object(list, list->list_head.prev);
+}
+
+static inline void *
+list_next(list_t *list, void *object)
+{
+	list_node_t *node = list_d2l(list, object);
+
+	if (node->next != &list->list_head)
+		return list_object(list, node->next);
+
+	return NULL;
+}
+
+static inline void *
+list_prev(list_t *list, void *object)
+{
+	list_node_t *node = list_d2l(list, object);
+
+	if (node->prev != &list->list_head)
+		return list_object(list, node->prev);
+
+	return NULL;
+}
+
+static inline int
+list_link_active(list_node_t *node)
+{
+	return (node->next != LIST_POISON1) && (node->prev != LIST_POISON2);
+}
+
+static inline void
+spl_list_move_tail(list_t *dst, list_t *src)
+{
+	list_splice_init(&src->list_head, dst->list_head.prev);
+}
+
+#define list_move_tail(dst, src)	spl_list_move_tail(dst, src)
+
+static inline void
+list_link_replace(list_node_t *old_node, list_node_t *new_node)
+{
+	ASSERT(list_link_active(old_node));
+	ASSERT(!list_link_active(new_node));
+
+	new_node->next = old_node->next;
+	new_node->prev = old_node->prev;
+	old_node->prev->next = new_node;
+	old_node->next->prev = new_node;
+	list_link_init(old_node);
+}
+
+#endif /* SPL_LIST_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/sys/mkdev.h
@@ -0,0 +1,28 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+\*****************************************************************************/
+
+#ifndef _SPL_MKDEV_H
+#define _SPL_MKDEV_H
+
+#endif /* SPL_MKDEV_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/sys/mntent.h
@@ -0,0 +1,28 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+\*****************************************************************************/
+
+#ifndef _SPL_MNTENT_H
+#define _SPL_MNTENT_H
+
+#endif /* SPL_MNTENT_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/sys/modctl.h
@@ -0,0 +1,28 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+\*****************************************************************************/
+
+#ifndef _SPL_MODCTL_H
+#define _SPL_MODCTL_H
+
+#endif /* SPL_MODCTL_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/sys/mode.h
@@ -0,0 +1,32 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+\*****************************************************************************/
+
+#ifndef _SPL_MODE_H
+#define _SPL_MODE_H
+
+#define IFTOVT(mode)	vn_mode_to_vtype(mode)
+#define VTTOIF(vtype)	vn_vtype_to_mode(vtype)
+#define MAKEIMODE(T, M) (VTTOIF(T) | ((M) & ~S_IFMT))
+
+#endif /* SPL_MODE_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/sys/mount.h
@@ -0,0 +1,28 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+\*****************************************************************************/
+
+#ifndef _SPL_MOUNT_H
+#define _SPL_MOUNT_H
+
+#endif /* SPL_MOUNT_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/sys/mutex.h
@@ -0,0 +1,144 @@
+/*
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _SPL_MUTEX_H
+#define	_SPL_MUTEX_H
+
+#include <sys/types.h>
+#include <linux/mutex.h>
+#include <linux/compiler_compat.h>
+
+typedef enum {
+	MUTEX_DEFAULT	= 0,
+	MUTEX_SPIN	= 1,
+	MUTEX_ADAPTIVE	= 2
+} kmutex_type_t;
+
+typedef struct {
+	struct mutex		m_mutex;
+	spinlock_t		m_lock;	/* used for serializing mutex_exit */
+	kthread_t		*m_owner;
+} kmutex_t;
+
+#define	MUTEX(mp)		(&((mp)->m_mutex))
+
+static inline void
+spl_mutex_set_owner(kmutex_t *mp)
+{
+	mp->m_owner = current;
+}
+
+static inline void
+spl_mutex_clear_owner(kmutex_t *mp)
+{
+	mp->m_owner = NULL;
+}
+
+#define	mutex_owner(mp)		(ACCESS_ONCE((mp)->m_owner))
+#define	mutex_owned(mp)		(mutex_owner(mp) == current)
+#define	MUTEX_HELD(mp)		mutex_owned(mp)
+#define	MUTEX_NOT_HELD(mp)	(!MUTEX_HELD(mp))
+
+/*
+ * The following functions must be a #define and not static inline.
+ * This ensures that the native linux mutex functions (lock/unlock)
+ * will be correctly located in the users code which is important
+ * for the built in kernel lock analysis tools
+ */
+#undef mutex_init
+#define	mutex_init(mp, name, type, ibc)				\
+{								\
+	static struct lock_class_key __key;			\
+	ASSERT(type == MUTEX_DEFAULT);				\
+								\
+	__mutex_init(MUTEX(mp), (name) ? (#name) : (#mp), &__key); \
+	spin_lock_init(&(mp)->m_lock);				\
+	spl_mutex_clear_owner(mp);				\
+}
+
+#undef mutex_destroy
+#define	mutex_destroy(mp)					\
+{								\
+	VERIFY3P(mutex_owner(mp), ==, NULL);			\
+}
+
+#define	mutex_tryenter(mp)					\
+({								\
+	int _rc_;						\
+								\
+	if ((_rc_ = mutex_trylock(MUTEX(mp))) == 1)		\
+		spl_mutex_set_owner(mp);			\
+								\
+	_rc_;							\
+})
+
+#ifdef CONFIG_DEBUG_LOCK_ALLOC
+#define	mutex_enter_nested(mp, subclass)			\
+{								\
+	ASSERT3P(mutex_owner(mp), !=, current);			\
+	mutex_lock_nested(MUTEX(mp), (subclass));		\
+	spl_mutex_set_owner(mp);				\
+}
+#else /* CONFIG_DEBUG_LOCK_ALLOC */
+#define	mutex_enter_nested(mp, subclass)			\
+{								\
+	ASSERT3P(mutex_owner(mp), !=, current);			\
+	mutex_lock(MUTEX(mp));					\
+	spl_mutex_set_owner(mp);				\
+}
+#endif /*  CONFIG_DEBUG_LOCK_ALLOC */
+
+#define	mutex_enter(mp) mutex_enter_nested((mp), 0)
+
+/*
+ * The reason for the spinlock:
+ *
+ * The Linux mutex is designed with a fast-path/slow-path design such that it
+ * does not guarantee serialization upon itself, allowing a race where latter
+ * acquirers finish mutex_unlock before former ones.
+ *
+ * The race renders it unsafe to be used for serializing the freeing of an
+ * object in which the mutex is embedded, where the latter acquirer could go
+ * on to free the object while the former one is still doing mutex_unlock and
+ * causing memory corruption.
+ *
+ * However, there are many places in ZFS where the mutex is used for
+ * serializing object freeing, and the code is shared among other OSes without
+ * this issue. Thus, we need the spinlock to force the serialization on
+ * mutex_exit().
+ *
+ * See http://lwn.net/Articles/575477/ for the information about the race.
+ */
+#define	mutex_exit(mp)						\
+{								\
+	spin_lock(&(mp)->m_lock);				\
+	spl_mutex_clear_owner(mp);				\
+	mutex_unlock(MUTEX(mp));				\
+	spin_unlock(&(mp)->m_lock);				\
+}
+
+int spl_mutex_init(void);
+void spl_mutex_fini(void);
+
+#endif /* _SPL_MUTEX_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/sys/note.h
@@ -0,0 +1,28 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+\*****************************************************************************/
+
+#ifndef _SPL_NOTE_H
+#define _SPL_NOTE_H
+
+#endif /* SPL_NOTE_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/sys/open.h
@@ -0,0 +1,28 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+\*****************************************************************************/
+
+#ifndef _SPL_OPEN_H
+#define _SPL_OPEN_H
+
+#endif /* SPL_OPEN_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/sys/param.h
@@ -0,0 +1,36 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+\*****************************************************************************/
+
+#ifndef _SPL_PARAM_H
+#define _SPL_PARAM_H
+
+#include <asm/page.h>
+
+/* Pages to bytes and back */
+#define ptob(pages)			(pages << PAGE_SHIFT)
+#define btop(bytes)			(bytes >> PAGE_SHIFT)
+
+#define MAXUID				UINT32_MAX
+
+#endif /* SPL_PARAM_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/sys/pathname.h
@@ -0,0 +1,35 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+\*****************************************************************************/
+
+#ifndef _SPL_PATHNAME_H
+#define _SPL_PATHNAME_H
+
+typedef struct pathname {
+	char	*pn_buf;		/* underlying storage */
+	char	*pn_path;		/* remaining pathname */
+	size_t	pn_pathlen;		/* remaining length */
+	size_t	pn_bufsize;		/* total size of pn_buf */
+} pathname_t;
+
+#endif /* SPL_PATHNAME_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/sys/policy.h
@@ -0,0 +1,47 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+\*****************************************************************************/
+
+#ifndef _SPL_POLICY_H
+#define _SPL_POLICY_H
+
+#define	secpolicy_fs_unmount(c,vfs)			(0)
+#define	secpolicy_nfs(c)				(0)
+#define	secpolicy_sys_config(c,co)			(0)
+#define	secpolicy_zfs(c)				(0)
+#define	secpolicy_zinject(c)				(0)
+#define	secpolicy_vnode_setids_setgids(c,id)		(0)
+#define	secpolicy_vnode_setid_retain(c, sr)		(0)
+#define	secpolicy_setid_clear(v, c)			(0)
+#define	secpolicy_vnode_any_access(c,vp,o)		(0)
+#define	secpolicy_vnode_access2(c,cp,o,m1,m2)		(0)
+#define	secpolicy_vnode_chown(c,o)			(0)
+#define	secpolicy_vnode_setdac(c,o)			(0)
+#define	secpolicy_vnode_remove(c)			(0)
+#define	secpolicy_vnode_setattr(c,v,a,o,f,func,n)	(0)
+#define	secpolicy_xvattr(x, o, c, t)			(0)
+#define	secpolicy_vnode_stky_modify(c)			(0)
+#define	secpolicy_setid_setsticky_clear(v,a,o,c)	(0)
+#define	secpolicy_basic_link(c)				(0)
+
+#endif /* SPL_POLICY_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/sys/pool.h
@@ -0,0 +1,30 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+\*****************************************************************************/
+
+#ifndef _SPL_POOL_H
+#define _SPL_POOL_H
+
+#include <sys/pset.h>
+
+#endif /* SPL_POOL_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/sys/priv_impl.h
@@ -0,0 +1,28 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+\*****************************************************************************/
+
+#ifndef _SPL_PRIV_IMPL_H
+#define _SPL_PRIV_IMPL_H
+
+#endif /* _SPL_PRIV_IMPL_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/sys/proc.h
@@ -0,0 +1,28 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+\*****************************************************************************/
+
+#ifndef _SPL_PROC_H
+#define _SPL_PROC_H
+
+#endif /* SPL_PROC_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/sys/processor.h
@@ -0,0 +1,32 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+\*****************************************************************************/
+
+#ifndef	_SPL_PROCESSOR_H
+#define	_SPL_PROCESSOR_H
+
+#define getcpuid() smp_processor_id()
+
+typedef int	processorid_t;
+
+#endif /* _SPL_PROCESSOR_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/sys/pset.h
@@ -0,0 +1,38 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+\*****************************************************************************/
+
+#ifndef _SPL_PSET_H
+#define _SPL_PSET_H
+
+typedef int psetid_t;
+
+/* special processor set id's */
+#define PS_NONE         -1
+#define PS_QUERY        -2
+#define PS_MYID         -3
+#define PS_SOFT         -4
+#define PS_HARD         -5
+#define PS_QUERY_TYPE   -6
+
+#endif /* SPL_PSET_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/sys/random.h
@@ -0,0 +1,45 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+\*****************************************************************************/
+
+#ifndef _SPL_RANDOM_H
+#define	_SPL_RANDOM_H
+
+#include <linux/module.h>
+#include <linux/random.h>
+
+static __inline__ int
+random_get_bytes(uint8_t *ptr, size_t len)
+{
+	get_random_bytes((void *)ptr,(int)len);
+	return 0;
+}
+
+static __inline__ int
+random_get_pseudo_bytes(uint8_t *ptr, size_t len)
+{
+	get_random_bytes((void *)ptr,(int)len);
+	return 0;
+}
+
+#endif	/* _SPL_RANDOM_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/sys/refstr.h
@@ -0,0 +1,28 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+\*****************************************************************************/
+
+#ifndef _SPL_REFSTR_H
+#define _SPL_REFSTR_H
+
+#endif /* SPL_REFSTR_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/sys/resource.h
@@ -0,0 +1,30 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+\*****************************************************************************/
+
+#ifndef _SPL_RESOURCE_H
+#define _SPL_RESOURCE_H
+
+#include <linux/resource.h>
+
+#endif /* SPL_RESOURCE_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/sys/rwlock.h
@@ -0,0 +1,212 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+\*****************************************************************************/
+
+#ifndef _SPL_RWLOCK_H
+#define _SPL_RWLOCK_H
+
+#include <sys/types.h>
+#include <linux/rwsem.h>
+#include <linux/rwsem_compat.h>
+
+typedef enum {
+        RW_DRIVER  = 2,
+        RW_DEFAULT = 4
+} krw_type_t;
+
+typedef enum {
+        RW_NONE   = 0,
+        RW_WRITER = 1,
+        RW_READER = 2
+} krw_t;
+
+typedef struct {
+        struct rw_semaphore rw_rwlock;
+        kthread_t *rw_owner;
+} krwlock_t;
+
+#define SEM(rwp)                        ((struct rw_semaphore *)(rwp))
+
+static inline void
+spl_rw_set_owner(krwlock_t *rwp)
+{
+        unsigned long flags;
+
+        spl_rwsem_lock_irqsave(&SEM(rwp)->wait_lock, flags);
+        rwp->rw_owner = current;
+        spl_rwsem_unlock_irqrestore(&SEM(rwp)->wait_lock, flags);
+}
+
+static inline void
+spl_rw_clear_owner(krwlock_t *rwp)
+{
+        unsigned long flags;
+
+        spl_rwsem_lock_irqsave(&SEM(rwp)->wait_lock, flags);
+        rwp->rw_owner = NULL;
+        spl_rwsem_unlock_irqrestore(&SEM(rwp)->wait_lock, flags);
+}
+
+static inline kthread_t *
+rw_owner(krwlock_t *rwp)
+{
+        unsigned long flags;
+        kthread_t *owner;
+
+        spl_rwsem_lock_irqsave(&SEM(rwp)->wait_lock, flags);
+        owner = rwp->rw_owner;
+        spl_rwsem_unlock_irqrestore(&SEM(rwp)->wait_lock, flags);
+
+        return owner;
+}
+
+static inline int
+RW_READ_HELD(krwlock_t *rwp)
+{
+	return (spl_rwsem_is_locked(SEM(rwp)) && rw_owner(rwp) == NULL);
+}
+
+static inline int
+RW_WRITE_HELD(krwlock_t *rwp)
+{
+	return (spl_rwsem_is_locked(SEM(rwp)) && rw_owner(rwp) == current);
+}
+
+static inline int
+RW_LOCK_HELD(krwlock_t *rwp)
+{
+	return spl_rwsem_is_locked(SEM(rwp));
+}
+
+/*
+ * The following functions must be a #define and not static inline.
+ * This ensures that the native linux semaphore functions (down/up)
+ * will be correctly located in the users code which is important
+ * for the built in kernel lock analysis tools
+ */
+#define rw_init(rwp, name, type, arg)                                   \
+({                                                                      \
+        static struct lock_class_key __key;                             \
+                                                                        \
+        __init_rwsem(SEM(rwp), #rwp, &__key);                           \
+        spl_rw_clear_owner(rwp);                                        \
+})
+
+#define rw_destroy(rwp)                                                 \
+({                                                                      \
+        VERIFY(!RW_LOCK_HELD(rwp));                                     \
+})
+
+#define rw_tryenter(rwp, rw)                                            \
+({                                                                      \
+        int _rc_ = 0;                                                   \
+                                                                        \
+        switch (rw) {                                                   \
+        case RW_READER:                                                 \
+                _rc_ = down_read_trylock(SEM(rwp));                     \
+                break;                                                  \
+        case RW_WRITER:                                                 \
+                if ((_rc_ = down_write_trylock(SEM(rwp))))              \
+                        spl_rw_set_owner(rwp);                          \
+                break;                                                  \
+        default:                                                        \
+                VERIFY(0);                                              \
+        }                                                               \
+        _rc_;                                                           \
+})
+
+#define rw_enter(rwp, rw)                                               \
+({                                                                      \
+        switch (rw) {                                                   \
+        case RW_READER:                                                 \
+                down_read(SEM(rwp));                                    \
+                break;                                                  \
+        case RW_WRITER:                                                 \
+                down_write(SEM(rwp));                                   \
+                spl_rw_set_owner(rwp);                                  \
+                break;                                                  \
+        default:                                                        \
+                VERIFY(0);                                              \
+        }                                                               \
+})
+
+#define rw_exit(rwp)                                                    \
+({                                                                      \
+        if (RW_WRITE_HELD(rwp)) {                                       \
+                spl_rw_clear_owner(rwp);                                \
+                up_write(SEM(rwp));                                     \
+        } else {                                                        \
+                ASSERT(RW_READ_HELD(rwp));                              \
+                up_read(SEM(rwp));                                      \
+        }                                                               \
+})
+
+#define rw_downgrade(rwp)                                               \
+({                                                                      \
+        spl_rw_clear_owner(rwp);                                        \
+        downgrade_write(SEM(rwp));                                      \
+})
+
+#if defined(CONFIG_RWSEM_GENERIC_SPINLOCK)
+/*
+ * For the generic implementations of rw-semaphores the following is
+ * true.  If your semaphore implementation internally represents the
+ * semaphore state differently then special case handling is required.
+ * - if activity/count is 0 then there are no active readers or writers
+ * - if activity/count is +ve then that is the number of active readers
+ * - if activity/count is -1 then there is one active writer
+ */
+
+extern void __up_read_locked(struct rw_semaphore *);
+extern int __down_write_trylock_locked(struct rw_semaphore *);
+
+#define rw_tryupgrade(rwp)                                              \
+({                                                                      \
+        unsigned long _flags_;                                          \
+        int _rc_ = 0;                                                   \
+                                                                        \
+        spl_rwsem_lock_irqsave(&SEM(rwp)->wait_lock, _flags_);           \
+        if ((list_empty(&SEM(rwp)->wait_list)) &&                       \
+            (SEM(rwp)->activity == 1)) {                                \
+                __up_read_locked(SEM(rwp));                             \
+                VERIFY(_rc_ = __down_write_trylock_locked(SEM(rwp)));   \
+                (rwp)->rw_owner = current;                              \
+        }                                                               \
+        spl_rwsem_unlock_irqrestore(&SEM(rwp)->wait_lock, _flags_);      \
+        _rc_;                                                           \
+})
+#else
+/*
+ * rw_tryupgrade() can be implemented correctly but for each supported
+ * arch we will need a custom implementation.  For the x86 implementation
+ * it looks like a custom cmpxchg() to atomically check and promote the
+ * rwsem would be safe.  For now that's not worth the trouble so in this
+ * case rw_tryupgrade() has just been disabled.
+ */
+#define rw_tryupgrade(rwp)      ({ 0; })
+#endif
+
+int spl_rw_init(void);
+void spl_rw_fini(void);
+
+#endif /* _SPL_RWLOCK_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/sys/sdt.h
@@ -0,0 +1,30 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+\*****************************************************************************/
+
+#ifndef _SPL_SDT_H
+#define _SPL_SDT_H
+
+#define SET_ERROR(x) (x)
+
+#endif /* SPL_SDT_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/sys/sid.h
@@ -0,0 +1,61 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+\*****************************************************************************/
+
+#ifndef _SPL_SID_H
+#define _SPL_SID_H
+
+typedef struct ksiddomain {
+	char		*kd_name;
+} ksiddomain_t;
+
+typedef enum ksid_index {
+	KSID_USER,
+	KSID_GROUP,
+	KSID_OWNER,
+	KSID_COUNT
+} ksid_index_t;
+
+typedef int ksid_t;
+
+static inline ksiddomain_t *
+ksid_lookupdomain(const char *dom)
+{
+        ksiddomain_t *kd;
+	int len = strlen(dom);
+
+        kd = kmem_zalloc(sizeof(ksiddomain_t), KM_SLEEP);
+        kd->kd_name = kmem_zalloc(len + 1, KM_SLEEP);
+	memcpy(kd->kd_name, dom, len);
+
+        return (kd);
+}
+
+static inline void
+ksiddomain_rele(ksiddomain_t *ksid)
+{
+	kmem_free(ksid->kd_name, strlen(ksid->kd_name) + 1);
+        kmem_free(ksid, sizeof(ksiddomain_t));
+}
+
+#endif /* _SPL_SID_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/sys/signal.h
@@ -0,0 +1,50 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+\*****************************************************************************/
+
+#ifndef _SPL_SIGNAL_H
+#define _SPL_SIGNAL_H
+
+#include <linux/sched.h>
+
+#define	FORREAL		0	/* Usual side-effects */
+#define	JUSTLOOKING	1	/* Don't stop the process */
+
+/* The "why" argument indicates the allowable side-effects of the call:
+ *
+ * FORREAL:  Extract the next pending signal from p_sig into p_cursig;
+ * stop the process if a stop has been requested or if a traced signal
+ * is pending.
+ *
+ * JUSTLOOKING:  Don't stop the process, just indicate whether or not
+ * a signal might be pending (FORREAL is needed to tell for sure).
+ */
+static __inline__ int
+issig(int why)
+{
+	ASSERT(why == FORREAL || why == JUSTLOOKING);
+
+	return signal_pending(current);
+}
+
+#endif /* SPL_SIGNAL_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/sys/stat.h
@@ -0,0 +1,30 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+\*****************************************************************************/
+
+#ifndef _SPL_STAT_H
+#define _SPL_STAT_H
+
+#include <linux/stat.h>
+
+#endif /* SPL_STAT_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/sys/stropts.h
@@ -0,0 +1,28 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+\*****************************************************************************/
+
+#ifndef _SPL_STROPTS_H
+#define _SPL_STROPTS_H
+
+#endif /* SPL_STROPTS_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/sys/sunddi.h
@@ -0,0 +1,59 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+\*****************************************************************************/
+
+#ifndef _SPL_SUNDDI_H
+#define _SPL_SUNDDI_H
+
+#include <sys/cred.h>
+#include <sys/uio.h>
+#include <sys/sunldi.h>
+#include <sys/mutex.h>
+#include <sys/u8_textprep.h>
+#include <sys/vnode.h>
+
+typedef int ddi_devid_t;
+
+#define	DDI_DEV_T_NONE				((dev_t)-1)
+#define	DDI_DEV_T_ANY				((dev_t)-2)
+#define	DI_MAJOR_T_UNKNOWN			((major_t)0)
+
+#define	DDI_PROP_DONTPASS			0x0001
+#define	DDI_PROP_CANSLEEP			0x0002
+
+#define	DDI_SUCCESS				0
+#define	DDI_FAILURE				-1
+
+#define	ddi_prop_lookup_string(x1,x2,x3,x4,x5)	(*x5 = NULL)
+#define	ddi_prop_free(x)			(void)0
+#define	ddi_root_node()				(void)0
+
+extern int ddi_strtoul(const char *, char **, int, unsigned long *);
+extern int ddi_strtol(const char *, char **, int, long *);
+extern int ddi_strtoull(const char *, char **, int, unsigned long long *);
+extern int ddi_strtoll(const char *, char **, int, long long *);
+
+extern int ddi_copyin(const void *from, void *to, size_t len, int flags);
+extern int ddi_copyout(const void *from, void *to, size_t len, int flags);
+
+#endif /* SPL_SUNDDI_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/sys/sunldi.h
@@ -0,0 +1,56 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+\*****************************************************************************/
+
+#ifndef _SPL_SUNLDI_H
+#define _SPL_SUNLDI_H
+
+#include <sys/types.h>
+#include <linux/fs.h>
+#include <linux/genhd.h>
+#include <linux/hdreg.h>
+#include <linux/bio.h>
+#include <linux/blkdev.h>
+
+#define SECTOR_SIZE 512
+
+typedef struct modlinkage {
+	int ml_rev;
+	struct modlfs *ml_modlfs;
+	struct modldrv *ml_modldrv;
+	major_t ml_major;
+	unsigned ml_minors;
+	void *pad1;
+} modlinkage_t;
+
+typedef struct ldi_ident {
+	char li_modname[MAXNAMELEN];
+	dev_t li_dev;
+} *ldi_ident_t;
+
+typedef struct block_device *ldi_handle_t;
+
+extern int ldi_ident_from_mod(struct modlinkage *modlp, ldi_ident_t *lip);
+extern void ldi_ident_release(ldi_ident_t li);
+
+#endif /* SPL_SUNLDI_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/sys/sysdc.h
@@ -0,0 +1,28 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+\*****************************************************************************/
+
+#ifndef _SPL_SYSDC_H
+#define _SPL_SYSDC_H
+
+#endif /* SPL_SYSDC_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/sys/sysevent.h
@@ -0,0 +1,28 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+\*****************************************************************************/
+
+#ifndef	_SPL_SYSEVENT_H
+#define	_SPL_SYSEVENT_H
+
+#endif /* _SPL_SYSEVENT_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/sys/sysevent/Makefile.am
@@ -0,0 +1,13 @@
+COMMON_H =
+
+KERNEL_H = \
+	$(top_srcdir)/include/sys/sysevent/eventdefs.h
+
+USER_H =
+
+EXTRA_DIST = $(COMMON_H) $(KERNEL_H) $(USER_H)
+
+if CONFIG_KERNEL
+kerneldir = @prefix@/src/spl-$(VERSION)/include/sys/sysevent
+kernel_HEADERS = $(KERNEL_H)
+endif
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/sys/sysevent/Makefile.in
@@ -0,0 +1,622 @@
+# Makefile.in generated by automake 1.15 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2014 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+VPATH = @srcdir@
+am__is_gnu_make = { \
+  if test -z '$(MAKELEVEL)'; then \
+    false; \
+  elif test -n '$(MAKE_HOST)'; then \
+    true; \
+  elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+    true; \
+  else \
+    false; \
+  fi; \
+}
+am__make_running_with_option = \
+  case $${target_option-} in \
+      ?) ;; \
+      *) echo "am__make_running_with_option: internal error: invalid" \
+              "target option '$${target_option-}' specified" >&2; \
+         exit 1;; \
+  esac; \
+  has_opt=no; \
+  sane_makeflags=$$MAKEFLAGS; \
+  if $(am__is_gnu_make); then \
+    sane_makeflags=$$MFLAGS; \
+  else \
+    case $$MAKEFLAGS in \
+      *\\[\ \	]*) \
+        bs=\\; \
+        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
+    esac; \
+  fi; \
+  skip_next=no; \
+  strip_trailopt () \
+  { \
+    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+  }; \
+  for flg in $$sane_makeflags; do \
+    test $$skip_next = yes && { skip_next=no; continue; }; \
+    case $$flg in \
+      *=*|--*) continue;; \
+        -*I) strip_trailopt 'I'; skip_next=yes;; \
+      -*I?*) strip_trailopt 'I';; \
+        -*O) strip_trailopt 'O'; skip_next=yes;; \
+      -*O?*) strip_trailopt 'O';; \
+        -*l) strip_trailopt 'l'; skip_next=yes;; \
+      -*l?*) strip_trailopt 'l';; \
+      -[dEDm]) skip_next=yes;; \
+      -[JT]) skip_next=yes;; \
+    esac; \
+    case $$flg in \
+      *$$target_option*) has_opt=yes; break;; \
+    esac; \
+  done; \
+  test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+target_triplet = @target@
+subdir = include/sys/sysevent
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/config/libtool.m4 \
+	$(top_srcdir)/config/ltoptions.m4 \
+	$(top_srcdir)/config/ltsugar.m4 \
+	$(top_srcdir)/config/ltversion.m4 \
+	$(top_srcdir)/config/lt~obsolete.m4 \
+	$(top_srcdir)/config/spl-build.m4 \
+	$(top_srcdir)/config/spl-meta.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(am__kernel_HEADERS_DIST) \
+	$(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/spl_config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo "  GEN     " $@;
+am__v_GEN_1 = 
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 = 
+SOURCES =
+DIST_SOURCES =
+am__can_run_installinfo = \
+  case $$AM_UPDATE_INFO_DIR in \
+    n|no|NO) false;; \
+    *) (install-info --version) >/dev/null 2>&1;; \
+  esac
+am__kernel_HEADERS_DIST =  \
+	$(top_srcdir)/include/sys/sysevent/eventdefs.h
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+    $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+    *) f=$$p;; \
+  esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+  srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+  for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+  for p in $$list; do echo "$$p $$p"; done | \
+  sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+  $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+    if (++n[$$2] == $(am__install_max)) \
+      { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+    END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+  sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+  sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+  test -z "$$files" \
+    || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+    || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+         $(am__cd) "$$dir" && rm -f $$files; }; \
+  }
+am__installdirs = "$(DESTDIR)$(kerneldir)"
+HEADERS = $(kernel_HEADERS)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates.  Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+  BEGIN { nonempty = 0; } \
+  { items[$$0] = 1; nonempty = 1; } \
+  END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique.  This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+  list='$(am__tagged_files)'; \
+  unique=`for i in $$list; do \
+    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+  done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+am__DIST_COMMON = $(srcdir)/Makefile.in
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ALIEN = @ALIEN@
+ALIEN_VERSION = @ALIEN_VERSION@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEBUG_CFLAGS = @DEBUG_CFLAGS@
+DEBUG_KMEM = @DEBUG_KMEM@
+DEBUG_KMEM_TRACKING = @DEBUG_KMEM_TRACKING@
+DEBUG_SPL = @DEBUG_SPL@
+DEFAULT_PACKAGE = @DEFAULT_PACKAGE@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DPKG = @DPKG@
+DPKGBUILD = @DPKGBUILD@
+DPKGBUILD_VERSION = @DPKGBUILD_VERSION@
+DPKG_VERSION = @DPKG_VERSION@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GREP = @GREP@
+HAVE_ALIEN = @HAVE_ALIEN@
+HAVE_DPKG = @HAVE_DPKG@
+HAVE_DPKGBUILD = @HAVE_DPKGBUILD@
+HAVE_RPM = @HAVE_RPM@
+HAVE_RPMBUILD = @HAVE_RPMBUILD@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+KERNELCPPFLAGS = @KERNELCPPFLAGS@
+KERNELMAKE_PARAMS = @KERNELMAKE_PARAMS@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LINUX = @LINUX@
+LINUX_OBJ = @LINUX_OBJ@
+LINUX_SYMBOLS = @LINUX_SYMBOLS@
+LINUX_VERSION = @LINUX_VERSION@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+RANLIB = @RANLIB@
+RELEASE = @RELEASE@
+RPM = @RPM@
+RPMBUILD = @RPMBUILD@
+RPMBUILD_VERSION = @RPMBUILD_VERSION@
+RPM_DEFINE_COMMON = @RPM_DEFINE_COMMON@
+RPM_DEFINE_DKMS = @RPM_DEFINE_DKMS@
+RPM_DEFINE_KMOD = @RPM_DEFINE_KMOD@
+RPM_DEFINE_UTIL = @RPM_DEFINE_UTIL@
+RPM_SPEC_DIR = @RPM_SPEC_DIR@
+RPM_VERSION = @RPM_VERSION@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SPL_CONFIG = @SPL_CONFIG@
+SPL_META_ALIAS = @SPL_META_ALIAS@
+SPL_META_AUTHOR = @SPL_META_AUTHOR@
+SPL_META_DATA = @SPL_META_DATA@
+SPL_META_LICENSE = @SPL_META_LICENSE@
+SPL_META_LT_AGE = @SPL_META_LT_AGE@
+SPL_META_LT_CURRENT = @SPL_META_LT_CURRENT@
+SPL_META_LT_REVISION = @SPL_META_LT_REVISION@
+SPL_META_NAME = @SPL_META_NAME@
+SPL_META_RELEASE = @SPL_META_RELEASE@
+SPL_META_VERSION = @SPL_META_VERSION@
+SRPM_DEFINE_COMMON = @SRPM_DEFINE_COMMON@
+SRPM_DEFINE_DKMS = @SRPM_DEFINE_DKMS@
+SRPM_DEFINE_KMOD = @SRPM_DEFINE_KMOD@
+SRPM_DEFINE_UTIL = @SRPM_DEFINE_UTIL@
+STRIP = @STRIP@
+VENDOR = @VENDOR@
+VERSION = @VERSION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+runstatedir = @runstatedir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+COMMON_H = 
+KERNEL_H = \
+	$(top_srcdir)/include/sys/sysevent/eventdefs.h
+
+USER_H = 
+EXTRA_DIST = $(COMMON_H) $(KERNEL_H) $(USER_H)
+@CONFIG_KERNEL_TRUE@kerneldir = @prefix@/src/spl-$(VERSION)/include/sys/sysevent
+@CONFIG_KERNEL_TRUE@kernel_HEADERS = $(KERNEL_H)
+all: all-am
+
+.SUFFIXES:
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+	        && { if test -f $@; then exit 0; else break; fi; }; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu include/sys/sysevent/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --gnu include/sys/sysevent/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+	esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
+install-kernelHEADERS: $(kernel_HEADERS)
+	@$(NORMAL_INSTALL)
+	@list='$(kernel_HEADERS)'; test -n "$(kerneldir)" || list=; \
+	if test -n "$$list"; then \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(kerneldir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(kerneldir)" || exit 1; \
+	fi; \
+	for p in $$list; do \
+	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+	  echo "$$d$$p"; \
+	done | $(am__base_list) | \
+	while read files; do \
+	  echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(kerneldir)'"; \
+	  $(INSTALL_HEADER) $$files "$(DESTDIR)$(kerneldir)" || exit $$?; \
+	done
+
+uninstall-kernelHEADERS:
+	@$(NORMAL_UNINSTALL)
+	@list='$(kernel_HEADERS)'; test -n "$(kerneldir)" || list=; \
+	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+	dir='$(DESTDIR)$(kerneldir)'; $(am__uninstall_files_from_dir)
+
+ID: $(am__tagged_files)
+	$(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	set x; \
+	here=`pwd`; \
+	$(am__define_uniq_tagged_files); \
+	shift; \
+	if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+	  test -n "$$unique" || unique=$$empty_fix; \
+	  if test $$# -gt 0; then \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      "$$@" $$unique; \
+	  else \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      $$unique; \
+	  fi; \
+	fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	$(am__define_uniq_tagged_files); \
+	test -z "$(CTAGS_ARGS)$$unique" \
+	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+	     $$unique
+
+GTAGS:
+	here=`$(am__cd) $(top_builddir) && pwd` \
+	  && $(am__cd) $(top_srcdir) \
+	  && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+	list='$(am__tagged_files)'; \
+	case "$(srcdir)" in \
+	  [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+	  *) sdir=$(subdir)/$(srcdir) ;; \
+	esac; \
+	for i in $$list; do \
+	  if test -f "$$i"; then \
+	    echo "$(subdir)/$$i"; \
+	  else \
+	    echo "$$sdir/$$i"; \
+	  fi; \
+	done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	list='$(DISTFILES)'; \
+	  dist_files=`for file in $$list; do echo $$file; done | \
+	  sed -e "s|^$$srcdirstrip/||;t" \
+	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+	case $$dist_files in \
+	  */*) $(MKDIR_P) `echo "$$dist_files" | \
+			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+			   sort -u` ;; \
+	esac; \
+	for file in $$dist_files; do \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  if test -d $$d/$$file; then \
+	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+	    if test -d "$(distdir)/$$file"; then \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+	  else \
+	    test -f "$(distdir)/$$file" \
+	    || cp -p $$d/$$file "$(distdir)/$$file" \
+	    || exit 1; \
+	  fi; \
+	done
+check-am: all-am
+check: check-am
+all-am: Makefile $(HEADERS)
+installdirs:
+	for dir in "$(DESTDIR)$(kerneldir)"; do \
+	  test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+	done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+	if test -z '$(STRIP)'; then \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	      install; \
+	else \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+	fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-am
+	-rm -f Makefile
+distclean-am: clean-am distclean-generic distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-kernelHEADERS
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-kernelHEADERS
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \
+	clean-libtool cscopelist-am ctags ctags-am distclean \
+	distclean-generic distclean-libtool distclean-tags distdir dvi \
+	dvi-am html html-am info info-am install install-am \
+	install-data install-data-am install-dvi install-dvi-am \
+	install-exec install-exec-am install-html install-html-am \
+	install-info install-info-am install-kernelHEADERS install-man \
+	install-pdf install-pdf-am install-ps install-ps-am \
+	install-strip installcheck installcheck-am installdirs \
+	maintainer-clean maintainer-clean-generic mostlyclean \
+	mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+	tags tags-am uninstall uninstall-am uninstall-kernelHEADERS
+
+.PRECIOUS: Makefile
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/sys/sysevent/eventdefs.h
@@ -0,0 +1,28 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+\*****************************************************************************/
+
+#ifndef	_SPL_SYSEVENT_EVENTDEFS_H
+#define	_SPL_SYSEVENT_EVENTDEFS_H
+
+#endif /* _SPL_SYSEVENT_EVENTDEFS_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/sys/sysmacros.h
@@ -0,0 +1,233 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+\*****************************************************************************/
+
+#ifndef _SPL_SYSMACROS_H
+#define _SPL_SYSMACROS_H
+
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/cpumask.h>
+#include <sys/debug.h>
+#include <sys/varargs.h>
+#include <sys/zone.h>
+#include <sys/signal.h>
+
+#ifdef HAVE_SCHED_RT_HEADER
+#include <linux/sched/rt.h>
+#endif
+
+#ifndef _KERNEL
+#define _KERNEL				__KERNEL__
+#endif
+
+#define FALSE				0
+#define TRUE				1
+
+#define INT8_MAX			(127)
+#define INT8_MIN			(-128)
+#define UINT8_MAX			(255)
+#define UINT8_MIN			(0)
+
+#define INT16_MAX			(32767)
+#define INT16_MIN			(-32768)
+#define UINT16_MAX			(65535)
+#define UINT16_MIN			(0)
+
+#define INT32_MAX			INT_MAX
+#define INT32_MIN			INT_MIN
+#define UINT32_MAX			UINT_MAX
+#define UINT32_MIN			UINT_MIN
+
+#define INT64_MAX			LLONG_MAX
+#define INT64_MIN			LLONG_MIN
+#define UINT64_MAX			ULLONG_MAX
+#define UINT64_MIN			ULLONG_MIN
+
+#define NBBY				8
+#define ENOTSUP				EOPNOTSUPP
+
+#define MAXMSGLEN			256
+#define MAXNAMELEN			256
+#define MAXPATHLEN			PATH_MAX
+#define MAXOFFSET_T			LLONG_MAX
+#define MAXBSIZE			8192
+#define DEV_BSIZE			512
+#define DEV_BSHIFT			9 /* log2(DEV_BSIZE) */
+
+#define proc_pageout			NULL
+#define curproc				current
+#define max_ncpus			num_possible_cpus()
+#define boot_ncpus			num_online_cpus()
+#define CPU_SEQID			smp_processor_id()
+#define _NOTE(x)
+#define is_system_labeled()		0
+
+#ifndef RLIM64_INFINITY
+#define RLIM64_INFINITY			(~0ULL)
+#endif
+
+/* 0..MAX_PRIO-1:		Process priority
+ * 0..MAX_RT_PRIO-1:		RT priority tasks
+ * MAX_RT_PRIO..MAX_PRIO-1:	SCHED_NORMAL tasks
+ *
+ * Treat shim tasks as SCHED_NORMAL tasks
+ */
+#define minclsyspri			(MAX_PRIO-1)
+#define maxclsyspri			(MAX_RT_PRIO)
+#define defclsyspri			(DEFAULT_PRIO)
+
+#ifndef NICE_TO_PRIO
+#define NICE_TO_PRIO(nice)		(MAX_RT_PRIO + (nice) + 20)
+#endif
+#ifndef PRIO_TO_NICE
+#define PRIO_TO_NICE(prio)		((prio) - MAX_RT_PRIO - 20)
+#endif
+
+/*
+ * Missing macros
+ */
+#ifndef PAGESIZE
+#define PAGESIZE			PAGE_SIZE
+#endif
+
+/* from Solaris sys/byteorder.h */
+#define BSWAP_8(x)	((x) & 0xff)
+#define BSWAP_16(x)	((BSWAP_8(x) << 8) | BSWAP_8((x) >> 8))
+#define BSWAP_32(x)	((BSWAP_16(x) << 16) | BSWAP_16((x) >> 16))
+#define BSWAP_64(x)	((BSWAP_32(x) << 32) | BSWAP_32((x) >> 32))
+
+/* Map some simple functions.
+ */
+#define bzero(ptr,size)			memset(ptr,0,size)
+#define bcopy(src,dest,size)		memmove(dest,src,size)
+#define bcmp(src,dest,size)		memcmp((src), (dest), (size_t)(size))
+
+/* Dtrace probes do not exist in the linux kernel */
+#ifdef DTRACE_PROBE
+#undef  DTRACE_PROBE
+#endif  /* DTRACE_PROBE */
+#define DTRACE_PROBE(a)					((void)0)
+
+#ifdef DTRACE_PROBE1
+#undef  DTRACE_PROBE1
+#endif  /* DTRACE_PROBE1 */
+#define DTRACE_PROBE1(a, b, c)				((void)0)
+
+#ifdef DTRACE_PROBE2
+#undef  DTRACE_PROBE2
+#endif  /* DTRACE_PROBE2 */
+#define DTRACE_PROBE2(a, b, c, d, e)			((void)0)
+
+#ifdef DTRACE_PROBE3
+#undef  DTRACE_PROBE3
+#endif  /* DTRACE_PROBE3 */
+#define DTRACE_PROBE3(a, b, c, d, e, f, g)		((void)0)
+
+#ifdef DTRACE_PROBE4
+#undef  DTRACE_PROBE4
+#endif  /* DTRACE_PROBE4 */
+#define DTRACE_PROBE4(a, b, c, d, e, f, g, h, i)	((void)0)
+
+/* Missing globals */
+extern char spl_version[32];
+extern unsigned long spl_hostid;
+
+/* Missing misc functions */
+extern uint32_t zone_get_hostid(void *zone);
+extern void spl_setup(void);
+extern void spl_cleanup(void);
+
+#define	highbit64(x)		fls64(x)
+#define	makedevice(maj,min)	makedev(maj,min)
+
+/* common macros */
+#ifndef MIN
+#define MIN(a, b)		((a) < (b) ? (a) : (b))
+#endif
+#ifndef MAX
+#define MAX(a, b)		((a) < (b) ? (b) : (a))
+#endif
+#ifndef ABS
+#define ABS(a)			((a) < 0 ? -(a) : (a))
+#endif
+#ifndef DIV_ROUND_UP
+#define DIV_ROUND_UP(n,d)	(((n) + (d) - 1) / (d))
+#endif
+#ifndef roundup
+#define roundup(x, y)		((((x) + ((y) - 1)) / (y)) * (y))
+#endif
+#ifndef howmany
+#define howmany(x, y)		(((x) + ((y) - 1)) / (y))
+#endif
+
+/*
+ * Compatibility macros/typedefs needed for Solaris -> Linux port
+ */
+#define P2ALIGN(x, align)	((x) & -(align))
+#define P2CROSS(x, y, align)	(((x) ^ (y)) > (align) - 1)
+#define P2ROUNDUP(x, align)	((((x) - 1) | ((align) - 1)) + 1)
+#define P2PHASE(x, align)	((x) & ((align) - 1))
+#define P2NPHASE(x, align)	(-(x) & ((align) - 1))
+#define ISP2(x)			(((x) & ((x) - 1)) == 0)
+#define IS_P2ALIGNED(v, a)	((((uintptr_t)(v)) & ((uintptr_t)(a) - 1))==0)
+#define P2BOUNDARY(off, len, align) \
+				(((off) ^ ((off) + (len) - 1)) > (align) - 1)
+
+/*
+ * Typed version of the P2* macros.  These macros should be used to ensure
+ * that the result is correctly calculated based on the data type of (x),
+ * which is passed in as the last argument, regardless of the data
+ * type of the alignment.  For example, if (x) is of type uint64_t,
+ * and we want to round it up to a page boundary using "PAGESIZE" as
+ * the alignment, we can do either
+ *
+ * P2ROUNDUP(x, (uint64_t)PAGESIZE)
+ * or
+ * P2ROUNDUP_TYPED(x, PAGESIZE, uint64_t)
+ */
+#define P2ALIGN_TYPED(x, align, type)   \
+        ((type)(x) & -(type)(align))
+#define P2PHASE_TYPED(x, align, type)   \
+        ((type)(x) & ((type)(align) - 1))
+#define P2NPHASE_TYPED(x, align, type)  \
+        (-(type)(x) & ((type)(align) - 1))
+#define P2ROUNDUP_TYPED(x, align, type) \
+        ((((type)(x) - 1) | ((type)(align) - 1)) + 1)
+#define P2END_TYPED(x, align, type)     \
+        (-(~(type)(x) & -(type)(align)))
+#define P2PHASEUP_TYPED(x, align, phase, type)  \
+        ((type)(phase) - (((type)(phase) - (type)(x)) & -(type)(align)))
+#define P2CROSS_TYPED(x, y, align, type)        \
+        (((type)(x) ^ (type)(y)) > (type)(align) - 1)
+#define P2SAMEHIGHBIT_TYPED(x, y, type) \
+        (((type)(x) ^ (type)(y)) < ((type)(x) & (type)(y)))
+
+#if defined(_KERNEL) && !defined(_KMEMUSER) && !defined(offsetof)
+
+/* avoid any possibility of clashing with <stddef.h> version */
+
+#define offsetof(s, m)  ((size_t)(&(((s *)0)->m)))
+#endif
+
+#endif  /* _SPL_SYSMACROS_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/sys/systeminfo.h
@@ -0,0 +1,36 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+\*****************************************************************************/
+
+#ifndef _SPL_SYSTEMINFO_H
+#define _SPL_SYSTEMINFO_H
+
+#define HW_HOSTID_LEN		11		/* minimum buffer size needed */
+						/* to hold a decimal or hex */
+						/* hostid string */
+
+/* Supplemental definitions for Linux. */
+#define HW_HOSTID_PATH		"/etc/hostid"   /* binary configuration file */
+#define HW_HOSTID_MASK		0xFFFFFFFF 	/* significant hostid bits */
+
+#endif /* SPL_SYSTEMINFO_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/sys/systm.h
@@ -0,0 +1,32 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+\*****************************************************************************/
+
+#ifndef _SPL_SYSTM_H
+#define _SPL_SYSTM_H
+
+#include <sys/sunddi.h>
+
+typedef uintptr_t pc_t;
+
+#endif /* SPL_SYSTM_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/sys/t_lock.h
@@ -0,0 +1,33 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+\*****************************************************************************/
+
+#ifndef _SPL_T_LOCK_H
+#define _SPL_T_LOCK_H
+
+#include <sys/param.h>
+#include <sys/mutex.h>
+#include <sys/rwlock.h>
+#include <sys/condvar.h>
+
+#endif /* SPL_T_LOCK_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/sys/taskq.h
@@ -0,0 +1,137 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+\*****************************************************************************/
+
+#ifndef _SPL_TASKQ_H
+#define _SPL_TASKQ_H
+
+#include <linux/module.h>
+#include <linux/gfp.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/kthread.h>
+#include <sys/types.h>
+#include <sys/thread.h>
+
+#define TASKQ_NAMELEN		31
+
+#define TASKQ_PREPOPULATE	0x00000001
+#define TASKQ_CPR_SAFE		0x00000002
+#define TASKQ_DYNAMIC		0x00000004
+#define TASKQ_THREADS_CPU_PCT	0x00000008
+#define TASKQ_DC_BATCH		0x00000010
+#define TASKQ_ACTIVE		0x80000000
+
+/*
+ * Flags for taskq_dispatch. TQ_SLEEP/TQ_NOSLEEP should be same as
+ * KM_SLEEP/KM_NOSLEEP.  TQ_NOQUEUE/TQ_NOALLOC are set particularly
+ * large so as not to conflict with already used GFP_* defines.
+ */
+#define TQ_SLEEP		0x00000000
+#define TQ_NOSLEEP		0x00000001
+#define TQ_PUSHPAGE		0x00000002
+#define TQ_NOQUEUE		0x01000000
+#define TQ_NOALLOC		0x02000000
+#define TQ_NEW			0x04000000
+#define TQ_FRONT		0x08000000
+
+typedef unsigned long taskqid_t;
+typedef void (task_func_t)(void *);
+
+typedef struct taskq {
+	spinlock_t		tq_lock;       /* protects taskq_t */
+	unsigned long		tq_lock_flags; /* interrupt state */
+	char			*tq_name;      /* taskq name */
+	struct list_head	tq_thread_list;/* list of all threads */
+	struct list_head	tq_active_list;/* list of active threads */
+	int			tq_nactive;    /* # of active threads */
+	int			tq_nthreads;   /* # of existing threads */
+	int			tq_nspawn;     /* # of threads being spawned */
+	int			tq_maxthreads; /* # of threads maximum */
+	int			tq_pri;        /* priority */
+	int			tq_minalloc;   /* min task_t pool size */
+	int			tq_maxalloc;   /* max task_t pool size */
+	int			tq_nalloc;     /* cur task_t pool size */
+	uint_t			tq_flags;      /* flags */
+	taskqid_t		tq_next_id;    /* next pend/work id */
+	taskqid_t		tq_lowest_id;  /* lowest pend/work id */
+	struct list_head	tq_free_list;  /* free task_t's */
+	struct list_head	tq_pend_list;  /* pending task_t's */
+	struct list_head	tq_prio_list;  /* priority pending task_t's */
+	struct list_head	tq_delay_list; /* delayed task_t's */
+	wait_queue_head_t	tq_work_waitq; /* new work waitq */
+	wait_queue_head_t	tq_wait_waitq; /* wait waitq */
+} taskq_t;
+
+typedef struct taskq_ent {
+	spinlock_t		tqent_lock;
+	wait_queue_head_t	tqent_waitq;
+	struct timer_list	tqent_timer;
+	struct list_head	tqent_list;
+	taskqid_t		tqent_id;
+	task_func_t		*tqent_func;
+	void			*tqent_arg;
+	taskq_t			*tqent_taskq;
+	uintptr_t		tqent_flags;
+} taskq_ent_t;
+
+#define TQENT_FLAG_PREALLOC     0x1
+#define TQENT_FLAG_CANCEL       0x2
+
+typedef struct taskq_thread {
+	struct list_head	tqt_thread_list;
+	struct list_head	tqt_active_list;
+	struct task_struct	*tqt_thread;
+	taskq_t			*tqt_tq;
+	taskqid_t		tqt_id;
+	taskq_ent_t		*tqt_task;
+	uintptr_t		tqt_flags;
+} taskq_thread_t;
+
+/* Global system-wide dynamic task queue available for all consumers */
+extern taskq_t *system_taskq;
+
+extern taskqid_t taskq_dispatch(taskq_t *, task_func_t, void *, uint_t);
+extern taskqid_t taskq_dispatch_delay(taskq_t *, task_func_t, void *,
+    uint_t, clock_t);
+extern void taskq_dispatch_ent(taskq_t *, task_func_t, void *, uint_t,
+    taskq_ent_t *);
+extern int taskq_empty_ent(taskq_ent_t *);
+extern void taskq_init_ent(taskq_ent_t *);
+extern taskq_t *taskq_create(const char *, int, pri_t, int, int, uint_t);
+extern void taskq_destroy(taskq_t *);
+extern void taskq_wait_id(taskq_t *, taskqid_t);
+extern void taskq_wait_outstanding(taskq_t *, taskqid_t);
+extern void taskq_wait(taskq_t *);
+extern int taskq_cancel_id(taskq_t *, taskqid_t);
+extern int taskq_member(taskq_t *, void *);
+
+#define taskq_create_proc(name, nthreads, pri, min, max, proc, flags) \
+    taskq_create(name, nthreads, pri, min, max, flags)
+#define taskq_create_sysdc(name, nthreads, min, max, proc, dc, flags) \
+    taskq_create(name, nthreads, maxclsyspri, min, max, flags)
+
+int spl_taskq_init(void);
+void spl_taskq_fini(void);
+
+#endif  /* _SPL_TASKQ_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/sys/thread.h
@@ -0,0 +1,65 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+\*****************************************************************************/
+
+#ifndef _SPL_THREAD_H
+#define _SPL_THREAD_H
+
+#include <linux/module.h>
+#include <linux/mm.h>
+#include <linux/spinlock.h>
+#include <linux/kthread.h>
+#include <sys/types.h>
+#include <sys/sysmacros.h>
+#include <sys/tsd.h>
+
+/*
+ * Thread interfaces
+ */
+#define TP_MAGIC			0x53535353
+
+#define TS_SLEEP			TASK_INTERRUPTIBLE
+#define TS_RUN				TASK_RUNNING
+#define TS_ZOMB				EXIT_ZOMBIE
+#define TS_STOPPED			TASK_STOPPED
+
+typedef void (*thread_func_t)(void *);
+
+#define thread_create(stk, stksize, func, arg, len, pp, state, pri)      \
+	__thread_create(stk, stksize, (thread_func_t)func,               \
+	                #func, arg, len, pp, state, pri)
+#define thread_exit()			__thread_exit()
+#define thread_join(t)			VERIFY(0)
+#define curthread			current
+#define getcomm()			current->comm
+#define getpid()			current->pid
+
+extern kthread_t *__thread_create(caddr_t stk, size_t  stksize,
+                                  thread_func_t func, const char *name,
+                                  void *args, size_t len, proc_t *pp,
+                                  int state, pri_t pri);
+extern void __thread_exit(void);
+extern struct task_struct *spl_kthread_create(int (*func)(void *),
+			void *data, const char namefmt[], ...);
+
+#endif  /* _SPL_THREAD_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/sys/time.h
@@ -0,0 +1,76 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+\*****************************************************************************/
+
+#ifndef _SPL_TIME_H
+#define	_SPL_TIME_H
+
+#include <linux/module.h>
+#include <linux/time.h>
+#include <sys/types.h>
+#include <sys/timer.h>
+
+#if defined(CONFIG_64BIT)
+#define	TIME_MAX			INT64_MAX
+#define	TIME_MIN			INT64_MIN
+#else
+#define	TIME_MAX			INT32_MAX
+#define	TIME_MIN			INT32_MIN
+#endif
+
+#define	SEC				1
+#define	MILLISEC			1000
+#define	MICROSEC			1000000
+#define	NANOSEC				1000000000
+
+#define	MSEC2NSEC(m)	((hrtime_t)(m) * (NANOSEC / MILLISEC))
+#define	NSEC2MSEC(n)	((n) / (NANOSEC / MILLISEC))
+
+static const int hz = HZ;
+
+#define	TIMESPEC_OVERFLOW(ts)		\
+	((ts)->tv_sec < TIME_MIN || (ts)->tv_sec > TIME_MAX)
+
+static inline void
+gethrestime(timestruc_t *now)
+{
+	*now = current_kernel_time();
+}
+
+static inline time_t
+gethrestime_sec(void)
+{
+	struct timespec ts;
+	ts = current_kernel_time();
+	return (ts.tv_sec);
+}
+
+static inline hrtime_t
+gethrtime(void)
+{
+	struct timespec now;
+	getrawmonotonic(&now);
+	return (((hrtime_t)now.tv_sec * NSEC_PER_SEC) + now.tv_nsec);
+}
+
+#endif  /* _SPL_TIME_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/sys/timer.h
@@ -0,0 +1,60 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+\*****************************************************************************/
+
+#ifndef _SPL_TIMER_H
+#define _SPL_TIMER_H
+
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/timer.h>
+
+#define lbolt				((clock_t)jiffies)
+#define lbolt64				((int64_t)get_jiffies_64())
+
+#define ddi_get_lbolt()			((clock_t)jiffies)
+#define ddi_get_lbolt64()		((int64_t)get_jiffies_64())
+
+#define ddi_time_before(a, b)		(typecheck(clock_t, a) && \
+					typecheck(clock_t, b) && \
+					((a) - (b) < 0))
+#define ddi_time_after(a, b)		ddi_time_before(b, a)
+#define ddi_time_before_eq(a, b)	(!ddi_time_after(a, b))
+#define ddi_time_after_eq(a, b)		ddi_time_before_eq(b, a)
+
+#define ddi_time_before64(a, b)		(typecheck(int64_t, a) && \
+					typecheck(int64_t, b) && \
+					((a) - (b) < 0))
+#define ddi_time_after64(a, b)		ddi_time_before64(b, a)
+#define ddi_time_before_eq64(a, b)	(!ddi_time_after64(a, b))
+#define ddi_time_after_eq64(a, b)	ddi_time_before_eq64(b, a)
+
+#define delay(ticks)			schedule_timeout_uninterruptible(ticks)
+
+#define SEC_TO_TICK(sec)		((sec) * HZ)
+#define MSEC_TO_TICK(ms)		msecs_to_jiffies(ms)
+#define USEC_TO_TICK(us)		usecs_to_jiffies(us)
+#define NSEC_TO_TICK(ns)		usecs_to_jiffies(ns / NSEC_PER_USEC)
+
+#endif  /* _SPL_TIMER_H */
+
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/sys/tsd.h
@@ -0,0 +1,45 @@
+/*****************************************************************************\
+ *  Copyright (C) 2010 Lawrence Livermore National Security, LLC.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+\*****************************************************************************/
+
+#ifndef _SPL_TSD_H
+#define _SPL_TSD_H
+
+#include <sys/types.h>
+
+#define TSD_HASH_TABLE_BITS_DEFAULT	9
+#define TSD_KEYS_MAX			32768
+#define DTOR_PID			(PID_MAX_LIMIT+1)
+#define PID_KEY				(TSD_KEYS_MAX+1)
+
+typedef void (*dtor_func_t)(void *);
+
+extern int tsd_set(uint_t, void *);
+extern void *tsd_get(uint_t);
+extern void tsd_create(uint_t *, dtor_func_t);
+extern void tsd_destroy(uint_t *);
+extern void tsd_exit(void);
+
+int spl_tsd_init(void);
+void spl_tsd_fini(void);
+
+#endif /* _SPL_TSD_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/sys/types.h
@@ -0,0 +1,68 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+\*****************************************************************************/
+
+#ifndef _SPL_TYPES_H
+#define	_SPL_TYPES_H
+
+#include <linux/types.h>
+#include <sys/sysmacros.h>
+
+#ifndef ULLONG_MAX
+#define ULLONG_MAX			(~0ULL)
+#endif
+
+#ifndef LLONG_MAX
+#define LLONG_MAX			((long long)(~0ULL>>1))
+#endif
+
+typedef enum { B_FALSE=0, B_TRUE=1 }	boolean_t;
+typedef unsigned long			intptr_t;
+typedef unsigned long			ulong_t;
+typedef unsigned int			uint_t;
+typedef unsigned char			uchar_t;
+typedef unsigned long long		u_longlong_t;
+typedef unsigned long long		u_offset_t;
+typedef unsigned long long		rlim64_t;
+typedef long long			longlong_t;
+typedef long long			offset_t;
+typedef struct task_struct		kthread_t;
+typedef struct task_struct		proc_t;
+typedef short				pri_t;
+typedef struct timespec			timestruc_t; /* definition per SVr4 */
+typedef struct timespec			timespec_t;
+typedef longlong_t			hrtime_t;
+typedef unsigned short			ushort_t;
+typedef u_longlong_t			len_t;
+typedef longlong_t			diskaddr_t;
+typedef ushort_t			o_mode_t;
+typedef uint_t				major_t;
+typedef uint_t				minor_t;
+typedef ulong_t				pgcnt_t;
+typedef long				spgcnt_t;
+typedef short				index_t;
+typedef int				id_t;
+
+extern proc_t p0;
+
+#endif	/* _SPL_TYPES_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/sys/types32.h
@@ -0,0 +1,36 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+\*****************************************************************************/
+
+#ifndef _SPL_TYPES32_H
+#define	_SPL_TYPES32_H
+
+#include <sys/int_types.h>
+#include <sys/types.h>
+
+typedef uint32_t	caddr32_t;
+typedef int32_t		daddr32_t;
+typedef int32_t		time32_t;
+typedef uint32_t	size32_t;
+
+#endif	/* _SPL_TYPES32_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/sys/u8_textprep.h
@@ -0,0 +1,28 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+\*****************************************************************************/
+
+#ifndef _SPL_U8_TEXTPREP_H
+#define _SPL_U8_TEXTPREP_H
+
+#endif /* SPL_U8_TEXTPREP_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/sys/uio.h
@@ -0,0 +1,106 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Copyright (c) 2015 by Chunwei Chen. All rights reserved.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+\*****************************************************************************/
+
+#ifndef _SPL_UIO_H
+#define _SPL_UIO_H
+
+#include <linux/uio.h>
+#include <linux/blkdev.h>
+#include <asm/uaccess.h>
+#include <sys/types.h>
+
+typedef struct iovec iovec_t;
+
+typedef enum uio_rw {
+	UIO_READ =	0,
+	UIO_WRITE =	1,
+} uio_rw_t;
+
+typedef enum uio_seg {
+	UIO_USERSPACE =	0,
+	UIO_SYSSPACE =	1,
+	UIO_USERISPACE=	2,
+	UIO_BVEC =	3,
+} uio_seg_t;
+
+typedef struct uio {
+	union {
+		const struct iovec	*uio_iov;
+		const struct bio_vec	*uio_bvec;
+	};
+	int		uio_iovcnt;
+	offset_t	uio_loffset;
+	uio_seg_t	uio_segflg;
+	uint16_t	uio_fmode;
+	uint16_t	uio_extflg;
+	offset_t	uio_limit;
+	ssize_t		uio_resid;
+	size_t		uio_skip;
+} uio_t;
+
+typedef struct aio_req {
+	uio_t		*aio_uio;
+	void		*aio_private;
+} aio_req_t;
+
+typedef enum xuio_type {
+	UIOTYPE_ASYNCIO,
+	UIOTYPE_ZEROCOPY,
+} xuio_type_t;
+
+
+#define UIOA_IOV_MAX    16
+
+typedef struct uioa_page_s {
+	int	uioa_pfncnt;
+	void	**uioa_ppp;
+	caddr_t	uioa_base;
+	size_t	uioa_len;
+} uioa_page_t;
+
+typedef struct xuio {
+	uio_t xu_uio;
+	enum xuio_type xu_type;
+	union {
+		struct {
+			uint32_t xu_a_state;
+			ssize_t xu_a_mbytes;
+			uioa_page_t *xu_a_lcur;
+			void **xu_a_lppp;
+			void *xu_a_hwst[4];
+			uioa_page_t xu_a_locked[UIOA_IOV_MAX];
+		} xu_aio;
+
+		struct {
+			int xu_zc_rw;
+			void *xu_zc_priv;
+		} xu_zc;
+	} xu_ext;
+} xuio_t;
+
+#define XUIO_XUZC_PRIV(xuio)	xuio->xu_ext.xu_zc.xu_zc_priv
+#define XUIO_XUZC_RW(xuio)	xuio->xu_ext.xu_zc.xu_zc_rw
+
+#endif /* SPL_UIO_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/sys/unistd.h
@@ -0,0 +1,28 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+\*****************************************************************************/
+
+#ifndef _SPL_UNISTD_H
+#define _SPL_UNISTD_H
+
+#endif /* SPL_UNISTD_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/sys/user.h
@@ -0,0 +1,42 @@
+/*****************************************************************************\
+ *  Copyright (C) 2015 Cluster Inc.
+ *  Produced at ClusterHQ Inc (cf, DISCLAIMER).
+ *  Written by Richard Yao <richard.yao@clusterhq.com>.
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+\*****************************************************************************/
+
+#ifndef _SPL_USER_H
+#define _SPL_USER_H
+
+/*
+ * We have uf_info_t for areleasef(). We implement areleasef() using a global
+ * linked list of all open file descriptors with the task structs referenced,
+ * so accessing the correct descriptor from areleasef() only requires knowing
+ * about the Linux task_struct. Since this is internal to our compatibility
+ * layer, we make it an opaque type.
+ *
+ * XXX: If the descriptor changes under us, we would get an incorrect
+ * reference.
+ */
+
+struct uf_info;
+typedef struct uf_info uf_info_t;
+
+#define P_FINFO(x) ((uf_info_t *)x)
+
+#endif /* SPL_USER_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/sys/va_list.h
@@ -0,0 +1,28 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+\*****************************************************************************/
+
+#ifndef _SPL_VA_LIST_H
+#define _SPL_VA_LIST_H
+
+#endif /* SPL_VA_LIST_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/sys/varargs.h
@@ -0,0 +1,30 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+\*****************************************************************************/
+
+#ifndef _SPL_VARARGS_H
+#define _SPL_VARARGS_H
+
+#define __va_list                       va_list
+
+#endif /* SPL_VARARGS_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/sys/vfs.h
@@ -0,0 +1,51 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+\*****************************************************************************/
+
+#ifndef _SPL_ZFS_H
+#define _SPL_ZFS_H
+
+#include <linux/mount.h>
+#include <linux/fs.h>
+#include <linux/dcache.h>
+#include <linux/statfs.h>
+#include <linux/xattr.h>
+#include <linux/security.h>
+#include <linux/seq_file.h>
+
+#define	MAXFIDSZ	64
+
+typedef struct spl_fid {
+	union {
+		long fid_pad;
+		struct {
+			ushort_t len;		/* length of data in bytes */
+			char     data[MAXFIDSZ];/* data (variable len) */
+		} _fid;
+	} un;
+} fid_t;
+
+#define	fid_len		un._fid.len
+#define	fid_data	un._fid.data
+
+#endif /* SPL_ZFS_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/sys/vfs_opreg.h
@@ -0,0 +1,28 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+\*****************************************************************************/
+
+#ifndef _SPL_OPREG_H
+#define _SPL_OPREG_H
+
+#endif /* SPL_OPREG_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/sys/vmem.h
@@ -0,0 +1,109 @@
+/*
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _SPL_VMEM_H
+#define	_SPL_VMEM_H
+
+#include <sys/kmem.h>
+#include <linux/sched.h>
+#include <linux/vmalloc.h>
+
+typedef struct vmem { } vmem_t;
+
+extern vmem_t *heap_arena;
+extern vmem_t *zio_alloc_arena;
+extern vmem_t *zio_arena;
+
+extern size_t vmem_size(vmem_t *vmp, int typemask);
+
+/*
+ * Memory allocation interfaces
+ */
+#define	VMEM_ALLOC	0x01
+#define	VMEM_FREE	0x02
+
+#ifndef VMALLOC_TOTAL
+#define	VMALLOC_TOTAL	(VMALLOC_END - VMALLOC_START)
+#endif
+
+/*
+ * vmem_* is an interface to a low level arena-based memory allocator on
+ * Illumos that is used to allocate virtual address space. The kmem SLAB
+ * allocator allocates slabs from it. Then the generic allocation functions
+ * kmem_{alloc,zalloc,free}() are layered on top of SLAB allocators.
+ *
+ * On Linux, the primary means of doing allocations is via kmalloc(), which
+ * is similarly layered on top of something called the buddy allocator. The
+ * buddy allocator is not available to kernel modules, it uses physical
+ * memory addresses rather than virtual memory addresses and is prone to
+ * fragmentation.
+ *
+ * Linux sets aside a relatively small address space for in-kernel virtual
+ * memory from which allocations can be done using vmalloc().  It might seem
+ * like a good idea to use vmalloc() to implement something similar to
+ * Illumos' allocator. However, this has the following problems:
+ *
+ * 1. Page directory table allocations are hard coded to use GFP_KERNEL.
+ *    Consequently, any KM_PUSHPAGE or KM_NOSLEEP allocations done using
+ *    vmalloc() will not have proper semantics.
+ *
+ * 2. Address space exhaustion is a real issue on 32-bit platforms where
+ *    only a few 100MB are available. The kernel will handle it by spinning
+ *    when it runs out of address space.
+ *
+ * 3. All vmalloc() allocations and frees are protected by a single global
+ *    lock which serializes all allocations.
+ *
+ * 4. Accessing /proc/meminfo and /proc/vmallocinfo will iterate the entire
+ *    list. The former will sum the allocations while the latter will print
+ *    them to user space in a way that user space can keep the lock held
+ *    indefinitely.  When the total number of mapped allocations is large
+ *    (several 100,000) a large amount of time will be spent waiting on locks.
+ *
+ * 5. Linux has a wait_on_bit() locking primitive that assumes physical
+ *    memory is used, it simply does not work on virtual memory.  Certain
+ *    Linux structures (e.g. the superblock) use them and might be embedded
+ *    into a structure from Illumos.  This makes using Linux virtual memory
+ *    unsafe in certain situations.
+ *
+ * It follows that we cannot obtain identical semantics to those on Illumos.
+ * Consequently, we implement the kmem_{alloc,zalloc,free}() functions in
+ * such a way that they can be used as drop-in replacements for small vmem_*
+ * allocations (8MB in size or smaller) and map vmem_{alloc,zalloc,free}()
+ * to them.
+ */
+
+#define	vmem_alloc(sz, fl)	spl_vmem_alloc((sz), (fl), __func__, __LINE__)
+#define	vmem_zalloc(sz, fl)	spl_vmem_zalloc((sz), (fl), __func__, __LINE__)
+#define	vmem_free(ptr, sz)	spl_vmem_free((ptr), (sz))
+#define	vmem_qcache_reap(ptr)	((void)0)
+
+extern void *spl_vmem_alloc(size_t sz, int fl, const char *func, int line);
+extern void *spl_vmem_zalloc(size_t sz, int fl, const char *func, int line);
+extern void spl_vmem_free(const void *ptr, size_t sz);
+
+int spl_vmem_init(void);
+void spl_vmem_fini(void);
+
+#endif	/* _SPL_VMEM_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/sys/vmsystm.h
@@ -0,0 +1,84 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+\*****************************************************************************/
+
+#ifndef _SPL_VMSYSTM_H
+#define _SPL_VMSYSTM_H
+
+#include <linux/mmzone.h>
+#include <linux/mm.h>
+#include <linux/swap.h>
+#include <linux/highmem.h>
+#include <linux/vmalloc.h>
+#include <sys/types.h>
+#include <asm/uaccess.h>
+
+#define	membar_producer()		smp_wmb()
+#define	physmem				totalram_pages
+#define	freemem			(nr_free_pages() + \
+				global_page_state(NR_INACTIVE_FILE) + \
+				global_page_state(NR_INACTIVE_ANON) + \
+				global_page_state(NR_SLAB_RECLAIMABLE))
+
+#define	xcopyin(from, to, size)		copy_from_user(to, from, size)
+#define	xcopyout(from, to, size)	copy_to_user(to, from, size)
+
+static __inline__ int
+copyin(const void *from, void *to, size_t len)
+{
+	/* On error copyin routine returns -1 */
+	if (xcopyin(from, to, len))
+		return -1;
+
+	return 0;
+}
+
+static __inline__ int
+copyout(const void *from, void *to, size_t len)
+{
+	/* On error copyout routine returns -1 */
+	if (xcopyout(from, to, len))
+		return -1;
+
+	return 0;
+}
+
+static __inline__ int
+copyinstr(const void *from, void *to, size_t len, size_t *done)
+{
+	size_t rc;
+
+	if (len == 0)
+		return -ENAMETOOLONG;
+
+	/* XXX: Should return ENAMETOOLONG if 'strlen(from) > len' */
+
+	memset(to, 0, len);
+	rc = copyin(from, to, len - 1);
+	if (done != NULL)
+		*done = rc;
+
+	return 0;
+}
+
+#endif /* SPL_VMSYSTM_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/sys/vnode.h
@@ -0,0 +1,207 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+\*****************************************************************************/
+
+#ifndef _SPL_VNODE_H
+#define _SPL_VNODE_H
+
+#include <linux/module.h>
+#include <linux/syscalls.h>
+#include <linux/fcntl.h>
+#include <linux/buffer_head.h>
+#include <linux/dcache.h>
+#include <linux/namei.h>
+#include <linux/file.h>
+#include <linux/fs.h>
+#include <linux/fs_struct.h>
+#include <linux/mount.h>
+#include <sys/kmem.h>
+#include <sys/mutex.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/uio.h>
+#include <sys/user.h>
+#include <sys/sunldi.h>
+
+/*
+ * Prior to linux-2.6.33 only O_DSYNC semantics were implemented and
+ * they used the O_SYNC flag.  As of linux-2.6.33 the this behavior
+ * was properly split in to O_SYNC and O_DSYNC respectively.
+ */
+#ifndef O_DSYNC
+#define O_DSYNC		O_SYNC
+#endif
+
+#define FREAD		1
+#define FWRITE		2
+#define FCREAT		O_CREAT
+#define FTRUNC		O_TRUNC
+#define FOFFMAX		O_LARGEFILE
+#define FSYNC		O_SYNC
+#define FDSYNC		O_DSYNC
+#define FRSYNC		O_SYNC
+#define FEXCL		O_EXCL
+#define FDIRECT		O_DIRECT
+#define FAPPEND		O_APPEND
+
+#define FNODSYNC	0x10000 /* fsync pseudo flag */
+#define FNOFOLLOW	0x20000 /* don't follow symlinks */
+
+#define F_FREESP	11 	/* Free file space */
+
+
+/*
+ * The vnode AT_ flags are mapped to the Linux ATTR_* flags.
+ * This allows them to be used safely with an iattr structure.
+ * The AT_XVATTR flag has been added and mapped to the upper
+ * bit range to avoid conflicting with the standard Linux set.
+ */
+#undef AT_UID
+#undef AT_GID
+
+#define AT_MODE		ATTR_MODE
+#define AT_UID		ATTR_UID
+#define AT_GID		ATTR_GID
+#define AT_SIZE		ATTR_SIZE
+#define AT_ATIME	ATTR_ATIME
+#define AT_MTIME	ATTR_MTIME
+#define AT_CTIME	ATTR_CTIME
+
+#define ATTR_XVATTR	(1 << 31)
+#define AT_XVATTR	ATTR_XVATTR
+
+#define ATTR_IATTR_MASK	(ATTR_MODE | ATTR_UID | ATTR_GID | ATTR_SIZE | \
+			ATTR_ATIME | ATTR_MTIME | ATTR_CTIME | ATTR_FILE)
+
+#define CRCREAT		0x01
+#define RMFILE		0x02
+
+#define B_INVAL		0x01
+#define B_TRUNC		0x02
+
+#define LOOKUP_DIR		0x01
+#define LOOKUP_XATTR		0x02
+#define CREATE_XATTR_DIR	0x04
+#define ATTR_NOACLCHECK		0x20
+
+typedef enum vtype {
+	VNON		= 0,
+	VREG		= 1,
+	VDIR		= 2,
+	VBLK		= 3,
+	VCHR		= 4,
+	VLNK		= 5,
+	VFIFO		= 6,
+	VDOOR		= 7,
+	VPROC		= 8,
+	VSOCK		= 9,
+	VPORT		= 10,
+	VBAD		= 11
+} vtype_t;
+
+typedef struct vattr {
+	enum vtype	va_type;	/* vnode type */
+	u_int		va_mask;	/* attribute bit-mask */
+	u_short		va_mode;	/* acc mode */
+	uid_t		va_uid;		/* owner uid */
+	gid_t		va_gid;		/* owner gid */
+	long		va_fsid;	/* fs id */
+	long		va_nodeid;	/* node # */
+	uint32_t	va_nlink;	/* # links */
+	uint64_t	va_size;	/* file size */
+	struct timespec	va_atime;	/* last acc */
+	struct timespec	va_mtime;	/* last mod */
+	struct timespec	va_ctime;	/* last chg */
+	dev_t		va_rdev;	/* dev */
+	uint64_t	va_nblocks;	/* space used */
+	uint32_t	va_blksize;	/* block size */
+	uint32_t	va_seq;		/* sequence */
+	struct dentry	*va_dentry;	/* dentry to wire */
+} vattr_t;
+
+typedef struct vnode {
+	struct file	*v_file;
+	kmutex_t	v_lock;		/* protects vnode fields */
+	uint_t		v_flag;		/* vnode flags (see below) */
+	uint_t		v_count;	/* reference count */
+	void		*v_data;	/* private data for fs */
+	struct vfs	*v_vfsp;	/* ptr to containing VFS */
+	struct stdata	*v_stream;	/* associated stream */
+	enum vtype	v_type;		/* vnode type */
+	dev_t		v_rdev;		/* device (VCHR, VBLK) */
+	gfp_t		v_gfp_mask;	/* original mapping gfp mask */
+} vnode_t;
+
+typedef struct vn_file {
+	int		f_fd;		/* linux fd for lookup */
+	struct task_struct *f_task;	/* linux task this fd belongs to */
+	struct file	*f_file;	/* linux file struct */
+	atomic_t	f_ref;		/* ref count */
+	kmutex_t	f_lock;		/* struct lock */
+	loff_t		f_offset;	/* offset */
+	vnode_t		*f_vnode;	/* vnode */
+	struct list_head f_list;	/* list referenced file_t's */
+} file_t;
+
+extern vnode_t *vn_alloc(int flag);
+void vn_free(vnode_t *vp);
+extern vtype_t vn_mode_to_vtype(mode_t);
+extern mode_t vn_vtype_to_mode(vtype_t);
+extern int vn_open(const char *path, uio_seg_t seg, int flags, int mode,
+		   vnode_t **vpp, int x1, void *x2);
+extern int vn_openat(const char *path, uio_seg_t seg, int flags, int mode,
+		     vnode_t **vpp, int x1, void *x2, vnode_t *vp, int fd);
+extern int vn_rdwr(uio_rw_t uio, vnode_t *vp, void *addr, ssize_t len,
+		   offset_t off, uio_seg_t seg, int x1, rlim64_t x2,
+		   void *x3, ssize_t *residp);
+extern int vn_close(vnode_t *vp, int flags, int x1, int x2, void *x3, void *x4);
+extern int vn_seek(vnode_t *vp, offset_t o, offset_t *op, void *ct);
+
+extern int vn_remove(const char *path, uio_seg_t seg, int flags);
+extern int vn_rename(const char *path1, const char *path2, int x1);
+extern int vn_getattr(vnode_t *vp, vattr_t *vap, int flags, void *x3, void *x4);
+extern int vn_fsync(vnode_t *vp, int flags, void *x3, void *x4);
+extern int vn_space(vnode_t *vp, int cmd, struct flock *bfp, int flag,
+    offset_t offset, void *x6, void *x7);
+extern file_t *vn_getf(int fd);
+extern void vn_releasef(int fd);
+extern void vn_areleasef(int fd, uf_info_t *fip);
+extern int vn_set_pwd(const char *filename);
+
+int spl_vn_init(void);
+void spl_vn_fini(void);
+
+#define VOP_CLOSE				vn_close
+#define VOP_SEEK				vn_seek
+#define VOP_GETATTR				vn_getattr
+#define VOP_FSYNC				vn_fsync
+#define VOP_SPACE				vn_space
+#define VOP_PUTPAGE(vp, o, s, f, x1, x2)	((void)0)
+#define vn_is_readonly(vp)			0
+#define getf					vn_getf
+#define releasef				vn_releasef
+#define areleasef				vn_areleasef
+
+extern vnode_t *rootdir;
+
+#endif /* SPL_VNODE_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/sys/zmod.h
@@ -0,0 +1,69 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+ *****************************************************************************
+ *  z_compress_level/z_uncompress are nearly identical copies of the
+ *  compress2/uncompress functions provided by the official zlib package
+ *  available at http://zlib.net/.  The only changes made we to slightly
+ *  adapt the functions called to match the linux kernel implementation
+ *  of zlib.  The full zlib license follows:
+ *
+ *  zlib.h -- interface of the 'zlib' general purpose compression library
+ *  version 1.2.5, April 19th, 2010
+ *
+ *  Copyright (C) 1995-2010 Jean-loup Gailly and Mark Adler
+ *
+ *  This software is provided 'as-is', without any express or implied
+ *  warranty.  In no event will the authors be held liable for any damages
+ *  arising from the use of this software.
+ *
+ *  Permission is granted to anyone to use this software for any purpose,
+ *  including commercial applications, and to alter it and redistribute it
+ *  freely, subject to the following restrictions:
+ *
+ *  1. The origin of this software must not be misrepresented; you must not
+ *     claim that you wrote the original software. If you use this software
+ *     in a product, an acknowledgment in the product documentation would be
+ *     appreciated but is not required.
+ *  2. Altered source versions must be plainly marked as such, and must not be
+ *     misrepresented as being the original software.
+ *  3. This notice may not be removed or altered from any source distribution.
+ *
+ *  Jean-loup Gailly
+ *  Mark Adler
+\*****************************************************************************/
+
+#ifndef _SPL_ZMOD_H
+#define _SPL_ZMOD_H
+
+#include <sys/types.h>
+#include <linux/zlib.h>
+
+extern int z_compress_level(void *dest, size_t *destLen, const void *source,
+    size_t sourceLen, int level);
+extern int z_uncompress(void *dest, size_t *destLen, const void *source,
+    size_t sourceLen);
+
+int spl_zlib_init(void);
+void spl_zlib_fini(void);
+
+#endif /* SPL_ZMOD_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/sys/zone.h
@@ -0,0 +1,36 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+\*****************************************************************************/
+
+#ifndef _SPL_ZONE_H
+#define _SPL_ZONE_H
+
+#include <sys/byteorder.h>
+
+#define	GLOBAL_ZONEID			0
+
+#define	zone_dataset_visible(x, y)	(1)
+#define	crgetzoneid(x)			(GLOBAL_ZONEID)
+#define	INGLOBALZONE(z)			(1)
+
+#endif /* SPL_ZONE_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/unistd.h
@@ -0,0 +1,28 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+\*****************************************************************************/
+
+#ifndef _SPL_UNISTD_H
+#define _SPL_UNISTD_H
+
+#endif /* SPL_UNISTD_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/util/Makefile.am
@@ -0,0 +1,14 @@
+COMMON_H =
+
+KERNEL_H = \
+	$(top_srcdir)/include/util/qsort.h \
+	$(top_srcdir)/include/util/sscanf.h
+
+USER_H =
+
+EXTRA_DIST = $(COMMON_H) $(KERNEL_H) $(USER_H)
+
+if CONFIG_KERNEL
+kerneldir = @prefix@/src/spl-$(VERSION)/include/util
+kernel_HEADERS = $(KERNEL_H)
+endif
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/util/Makefile.in
@@ -0,0 +1,623 @@
+# Makefile.in generated by automake 1.15 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2014 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+VPATH = @srcdir@
+am__is_gnu_make = { \
+  if test -z '$(MAKELEVEL)'; then \
+    false; \
+  elif test -n '$(MAKE_HOST)'; then \
+    true; \
+  elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+    true; \
+  else \
+    false; \
+  fi; \
+}
+am__make_running_with_option = \
+  case $${target_option-} in \
+      ?) ;; \
+      *) echo "am__make_running_with_option: internal error: invalid" \
+              "target option '$${target_option-}' specified" >&2; \
+         exit 1;; \
+  esac; \
+  has_opt=no; \
+  sane_makeflags=$$MAKEFLAGS; \
+  if $(am__is_gnu_make); then \
+    sane_makeflags=$$MFLAGS; \
+  else \
+    case $$MAKEFLAGS in \
+      *\\[\ \	]*) \
+        bs=\\; \
+        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
+    esac; \
+  fi; \
+  skip_next=no; \
+  strip_trailopt () \
+  { \
+    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+  }; \
+  for flg in $$sane_makeflags; do \
+    test $$skip_next = yes && { skip_next=no; continue; }; \
+    case $$flg in \
+      *=*|--*) continue;; \
+        -*I) strip_trailopt 'I'; skip_next=yes;; \
+      -*I?*) strip_trailopt 'I';; \
+        -*O) strip_trailopt 'O'; skip_next=yes;; \
+      -*O?*) strip_trailopt 'O';; \
+        -*l) strip_trailopt 'l'; skip_next=yes;; \
+      -*l?*) strip_trailopt 'l';; \
+      -[dEDm]) skip_next=yes;; \
+      -[JT]) skip_next=yes;; \
+    esac; \
+    case $$flg in \
+      *$$target_option*) has_opt=yes; break;; \
+    esac; \
+  done; \
+  test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+target_triplet = @target@
+subdir = include/util
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/config/libtool.m4 \
+	$(top_srcdir)/config/ltoptions.m4 \
+	$(top_srcdir)/config/ltsugar.m4 \
+	$(top_srcdir)/config/ltversion.m4 \
+	$(top_srcdir)/config/lt~obsolete.m4 \
+	$(top_srcdir)/config/spl-build.m4 \
+	$(top_srcdir)/config/spl-meta.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(am__kernel_HEADERS_DIST) \
+	$(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/spl_config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo "  GEN     " $@;
+am__v_GEN_1 = 
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 = 
+SOURCES =
+DIST_SOURCES =
+am__can_run_installinfo = \
+  case $$AM_UPDATE_INFO_DIR in \
+    n|no|NO) false;; \
+    *) (install-info --version) >/dev/null 2>&1;; \
+  esac
+am__kernel_HEADERS_DIST = $(top_srcdir)/include/util/qsort.h \
+	$(top_srcdir)/include/util/sscanf.h
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+    $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+    *) f=$$p;; \
+  esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+  srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+  for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+  for p in $$list; do echo "$$p $$p"; done | \
+  sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+  $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+    if (++n[$$2] == $(am__install_max)) \
+      { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+    END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+  sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+  sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+  test -z "$$files" \
+    || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+    || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+         $(am__cd) "$$dir" && rm -f $$files; }; \
+  }
+am__installdirs = "$(DESTDIR)$(kerneldir)"
+HEADERS = $(kernel_HEADERS)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates.  Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+  BEGIN { nonempty = 0; } \
+  { items[$$0] = 1; nonempty = 1; } \
+  END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique.  This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+  list='$(am__tagged_files)'; \
+  unique=`for i in $$list; do \
+    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+  done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+am__DIST_COMMON = $(srcdir)/Makefile.in
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ALIEN = @ALIEN@
+ALIEN_VERSION = @ALIEN_VERSION@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEBUG_CFLAGS = @DEBUG_CFLAGS@
+DEBUG_KMEM = @DEBUG_KMEM@
+DEBUG_KMEM_TRACKING = @DEBUG_KMEM_TRACKING@
+DEBUG_SPL = @DEBUG_SPL@
+DEFAULT_PACKAGE = @DEFAULT_PACKAGE@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DPKG = @DPKG@
+DPKGBUILD = @DPKGBUILD@
+DPKGBUILD_VERSION = @DPKGBUILD_VERSION@
+DPKG_VERSION = @DPKG_VERSION@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GREP = @GREP@
+HAVE_ALIEN = @HAVE_ALIEN@
+HAVE_DPKG = @HAVE_DPKG@
+HAVE_DPKGBUILD = @HAVE_DPKGBUILD@
+HAVE_RPM = @HAVE_RPM@
+HAVE_RPMBUILD = @HAVE_RPMBUILD@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+KERNELCPPFLAGS = @KERNELCPPFLAGS@
+KERNELMAKE_PARAMS = @KERNELMAKE_PARAMS@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LINUX = @LINUX@
+LINUX_OBJ = @LINUX_OBJ@
+LINUX_SYMBOLS = @LINUX_SYMBOLS@
+LINUX_VERSION = @LINUX_VERSION@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+RANLIB = @RANLIB@
+RELEASE = @RELEASE@
+RPM = @RPM@
+RPMBUILD = @RPMBUILD@
+RPMBUILD_VERSION = @RPMBUILD_VERSION@
+RPM_DEFINE_COMMON = @RPM_DEFINE_COMMON@
+RPM_DEFINE_DKMS = @RPM_DEFINE_DKMS@
+RPM_DEFINE_KMOD = @RPM_DEFINE_KMOD@
+RPM_DEFINE_UTIL = @RPM_DEFINE_UTIL@
+RPM_SPEC_DIR = @RPM_SPEC_DIR@
+RPM_VERSION = @RPM_VERSION@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SPL_CONFIG = @SPL_CONFIG@
+SPL_META_ALIAS = @SPL_META_ALIAS@
+SPL_META_AUTHOR = @SPL_META_AUTHOR@
+SPL_META_DATA = @SPL_META_DATA@
+SPL_META_LICENSE = @SPL_META_LICENSE@
+SPL_META_LT_AGE = @SPL_META_LT_AGE@
+SPL_META_LT_CURRENT = @SPL_META_LT_CURRENT@
+SPL_META_LT_REVISION = @SPL_META_LT_REVISION@
+SPL_META_NAME = @SPL_META_NAME@
+SPL_META_RELEASE = @SPL_META_RELEASE@
+SPL_META_VERSION = @SPL_META_VERSION@
+SRPM_DEFINE_COMMON = @SRPM_DEFINE_COMMON@
+SRPM_DEFINE_DKMS = @SRPM_DEFINE_DKMS@
+SRPM_DEFINE_KMOD = @SRPM_DEFINE_KMOD@
+SRPM_DEFINE_UTIL = @SRPM_DEFINE_UTIL@
+STRIP = @STRIP@
+VENDOR = @VENDOR@
+VERSION = @VERSION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+runstatedir = @runstatedir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+COMMON_H = 
+KERNEL_H = \
+	$(top_srcdir)/include/util/qsort.h \
+	$(top_srcdir)/include/util/sscanf.h
+
+USER_H = 
+EXTRA_DIST = $(COMMON_H) $(KERNEL_H) $(USER_H)
+@CONFIG_KERNEL_TRUE@kerneldir = @prefix@/src/spl-$(VERSION)/include/util
+@CONFIG_KERNEL_TRUE@kernel_HEADERS = $(KERNEL_H)
+all: all-am
+
+.SUFFIXES:
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+	        && { if test -f $@; then exit 0; else break; fi; }; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu include/util/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --gnu include/util/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+	esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
+install-kernelHEADERS: $(kernel_HEADERS)
+	@$(NORMAL_INSTALL)
+	@list='$(kernel_HEADERS)'; test -n "$(kerneldir)" || list=; \
+	if test -n "$$list"; then \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(kerneldir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(kerneldir)" || exit 1; \
+	fi; \
+	for p in $$list; do \
+	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+	  echo "$$d$$p"; \
+	done | $(am__base_list) | \
+	while read files; do \
+	  echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(kerneldir)'"; \
+	  $(INSTALL_HEADER) $$files "$(DESTDIR)$(kerneldir)" || exit $$?; \
+	done
+
+uninstall-kernelHEADERS:
+	@$(NORMAL_UNINSTALL)
+	@list='$(kernel_HEADERS)'; test -n "$(kerneldir)" || list=; \
+	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+	dir='$(DESTDIR)$(kerneldir)'; $(am__uninstall_files_from_dir)
+
+ID: $(am__tagged_files)
+	$(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	set x; \
+	here=`pwd`; \
+	$(am__define_uniq_tagged_files); \
+	shift; \
+	if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+	  test -n "$$unique" || unique=$$empty_fix; \
+	  if test $$# -gt 0; then \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      "$$@" $$unique; \
+	  else \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      $$unique; \
+	  fi; \
+	fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	$(am__define_uniq_tagged_files); \
+	test -z "$(CTAGS_ARGS)$$unique" \
+	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+	     $$unique
+
+GTAGS:
+	here=`$(am__cd) $(top_builddir) && pwd` \
+	  && $(am__cd) $(top_srcdir) \
+	  && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+	list='$(am__tagged_files)'; \
+	case "$(srcdir)" in \
+	  [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+	  *) sdir=$(subdir)/$(srcdir) ;; \
+	esac; \
+	for i in $$list; do \
+	  if test -f "$$i"; then \
+	    echo "$(subdir)/$$i"; \
+	  else \
+	    echo "$$sdir/$$i"; \
+	  fi; \
+	done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	list='$(DISTFILES)'; \
+	  dist_files=`for file in $$list; do echo $$file; done | \
+	  sed -e "s|^$$srcdirstrip/||;t" \
+	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+	case $$dist_files in \
+	  */*) $(MKDIR_P) `echo "$$dist_files" | \
+			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+			   sort -u` ;; \
+	esac; \
+	for file in $$dist_files; do \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  if test -d $$d/$$file; then \
+	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+	    if test -d "$(distdir)/$$file"; then \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+	  else \
+	    test -f "$(distdir)/$$file" \
+	    || cp -p $$d/$$file "$(distdir)/$$file" \
+	    || exit 1; \
+	  fi; \
+	done
+check-am: all-am
+check: check-am
+all-am: Makefile $(HEADERS)
+installdirs:
+	for dir in "$(DESTDIR)$(kerneldir)"; do \
+	  test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+	done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+	if test -z '$(STRIP)'; then \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	      install; \
+	else \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+	fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-am
+	-rm -f Makefile
+distclean-am: clean-am distclean-generic distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-kernelHEADERS
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-kernelHEADERS
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \
+	clean-libtool cscopelist-am ctags ctags-am distclean \
+	distclean-generic distclean-libtool distclean-tags distdir dvi \
+	dvi-am html html-am info info-am install install-am \
+	install-data install-data-am install-dvi install-dvi-am \
+	install-exec install-exec-am install-html install-html-am \
+	install-info install-info-am install-kernelHEADERS install-man \
+	install-pdf install-pdf-am install-ps install-ps-am \
+	install-strip installcheck installcheck-am installdirs \
+	maintainer-clean maintainer-clean-generic mostlyclean \
+	mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+	tags tags-am uninstall uninstall-am uninstall-kernelHEADERS
+
+.PRECIOUS: Makefile
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/util/qsort.h
@@ -0,0 +1,32 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+\*****************************************************************************/
+
+#ifndef _SPL_QSORT_H
+#define _SPL_QSORT_H
+
+#include <linux/sort.h>
+
+#define qsort(base, num, size, cmp)	sort(base, num, size, cmp, NULL)
+
+#endif /* SPL_QSORT_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/util/sscanf.h
@@ -0,0 +1,28 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+\*****************************************************************************/
+
+#ifndef _SPL_UTIL_SSCANF_H
+#define _SPL_UTIL_SSCANF_H
+
+#endif /* SPL_UTIL_SSCAN_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/vm/Makefile.am
@@ -0,0 +1,15 @@
+COMMON_H =
+
+KERNEL_H = \
+	$(top_srcdir)/include/vm/anon.h \
+	$(top_srcdir)/include/vm/pvn.h \
+	$(top_srcdir)/include/vm/seg_kmem.h
+
+USER_H =
+
+EXTRA_DIST = $(COMMON_H) $(KERNEL_H) $(USER_H)
+
+if CONFIG_KERNEL
+kerneldir = @prefix@/src/spl-$(VERSION)/include/vm
+kernel_HEADERS = $(KERNEL_H)
+endif
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/vm/Makefile.in
@@ -0,0 +1,625 @@
+# Makefile.in generated by automake 1.15 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2014 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+VPATH = @srcdir@
+am__is_gnu_make = { \
+  if test -z '$(MAKELEVEL)'; then \
+    false; \
+  elif test -n '$(MAKE_HOST)'; then \
+    true; \
+  elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+    true; \
+  else \
+    false; \
+  fi; \
+}
+am__make_running_with_option = \
+  case $${target_option-} in \
+      ?) ;; \
+      *) echo "am__make_running_with_option: internal error: invalid" \
+              "target option '$${target_option-}' specified" >&2; \
+         exit 1;; \
+  esac; \
+  has_opt=no; \
+  sane_makeflags=$$MAKEFLAGS; \
+  if $(am__is_gnu_make); then \
+    sane_makeflags=$$MFLAGS; \
+  else \
+    case $$MAKEFLAGS in \
+      *\\[\ \	]*) \
+        bs=\\; \
+        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
+    esac; \
+  fi; \
+  skip_next=no; \
+  strip_trailopt () \
+  { \
+    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+  }; \
+  for flg in $$sane_makeflags; do \
+    test $$skip_next = yes && { skip_next=no; continue; }; \
+    case $$flg in \
+      *=*|--*) continue;; \
+        -*I) strip_trailopt 'I'; skip_next=yes;; \
+      -*I?*) strip_trailopt 'I';; \
+        -*O) strip_trailopt 'O'; skip_next=yes;; \
+      -*O?*) strip_trailopt 'O';; \
+        -*l) strip_trailopt 'l'; skip_next=yes;; \
+      -*l?*) strip_trailopt 'l';; \
+      -[dEDm]) skip_next=yes;; \
+      -[JT]) skip_next=yes;; \
+    esac; \
+    case $$flg in \
+      *$$target_option*) has_opt=yes; break;; \
+    esac; \
+  done; \
+  test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+target_triplet = @target@
+subdir = include/vm
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/config/libtool.m4 \
+	$(top_srcdir)/config/ltoptions.m4 \
+	$(top_srcdir)/config/ltsugar.m4 \
+	$(top_srcdir)/config/ltversion.m4 \
+	$(top_srcdir)/config/lt~obsolete.m4 \
+	$(top_srcdir)/config/spl-build.m4 \
+	$(top_srcdir)/config/spl-meta.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(am__kernel_HEADERS_DIST) \
+	$(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/spl_config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo "  GEN     " $@;
+am__v_GEN_1 = 
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 = 
+SOURCES =
+DIST_SOURCES =
+am__can_run_installinfo = \
+  case $$AM_UPDATE_INFO_DIR in \
+    n|no|NO) false;; \
+    *) (install-info --version) >/dev/null 2>&1;; \
+  esac
+am__kernel_HEADERS_DIST = $(top_srcdir)/include/vm/anon.h \
+	$(top_srcdir)/include/vm/pvn.h \
+	$(top_srcdir)/include/vm/seg_kmem.h
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+    $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+    *) f=$$p;; \
+  esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+  srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+  for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+  for p in $$list; do echo "$$p $$p"; done | \
+  sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+  $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+    if (++n[$$2] == $(am__install_max)) \
+      { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+    END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+  sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+  sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+  test -z "$$files" \
+    || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+    || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+         $(am__cd) "$$dir" && rm -f $$files; }; \
+  }
+am__installdirs = "$(DESTDIR)$(kerneldir)"
+HEADERS = $(kernel_HEADERS)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates.  Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+  BEGIN { nonempty = 0; } \
+  { items[$$0] = 1; nonempty = 1; } \
+  END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique.  This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+  list='$(am__tagged_files)'; \
+  unique=`for i in $$list; do \
+    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+  done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+am__DIST_COMMON = $(srcdir)/Makefile.in
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ALIEN = @ALIEN@
+ALIEN_VERSION = @ALIEN_VERSION@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEBUG_CFLAGS = @DEBUG_CFLAGS@
+DEBUG_KMEM = @DEBUG_KMEM@
+DEBUG_KMEM_TRACKING = @DEBUG_KMEM_TRACKING@
+DEBUG_SPL = @DEBUG_SPL@
+DEFAULT_PACKAGE = @DEFAULT_PACKAGE@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DPKG = @DPKG@
+DPKGBUILD = @DPKGBUILD@
+DPKGBUILD_VERSION = @DPKGBUILD_VERSION@
+DPKG_VERSION = @DPKG_VERSION@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GREP = @GREP@
+HAVE_ALIEN = @HAVE_ALIEN@
+HAVE_DPKG = @HAVE_DPKG@
+HAVE_DPKGBUILD = @HAVE_DPKGBUILD@
+HAVE_RPM = @HAVE_RPM@
+HAVE_RPMBUILD = @HAVE_RPMBUILD@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+KERNELCPPFLAGS = @KERNELCPPFLAGS@
+KERNELMAKE_PARAMS = @KERNELMAKE_PARAMS@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LINUX = @LINUX@
+LINUX_OBJ = @LINUX_OBJ@
+LINUX_SYMBOLS = @LINUX_SYMBOLS@
+LINUX_VERSION = @LINUX_VERSION@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+RANLIB = @RANLIB@
+RELEASE = @RELEASE@
+RPM = @RPM@
+RPMBUILD = @RPMBUILD@
+RPMBUILD_VERSION = @RPMBUILD_VERSION@
+RPM_DEFINE_COMMON = @RPM_DEFINE_COMMON@
+RPM_DEFINE_DKMS = @RPM_DEFINE_DKMS@
+RPM_DEFINE_KMOD = @RPM_DEFINE_KMOD@
+RPM_DEFINE_UTIL = @RPM_DEFINE_UTIL@
+RPM_SPEC_DIR = @RPM_SPEC_DIR@
+RPM_VERSION = @RPM_VERSION@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SPL_CONFIG = @SPL_CONFIG@
+SPL_META_ALIAS = @SPL_META_ALIAS@
+SPL_META_AUTHOR = @SPL_META_AUTHOR@
+SPL_META_DATA = @SPL_META_DATA@
+SPL_META_LICENSE = @SPL_META_LICENSE@
+SPL_META_LT_AGE = @SPL_META_LT_AGE@
+SPL_META_LT_CURRENT = @SPL_META_LT_CURRENT@
+SPL_META_LT_REVISION = @SPL_META_LT_REVISION@
+SPL_META_NAME = @SPL_META_NAME@
+SPL_META_RELEASE = @SPL_META_RELEASE@
+SPL_META_VERSION = @SPL_META_VERSION@
+SRPM_DEFINE_COMMON = @SRPM_DEFINE_COMMON@
+SRPM_DEFINE_DKMS = @SRPM_DEFINE_DKMS@
+SRPM_DEFINE_KMOD = @SRPM_DEFINE_KMOD@
+SRPM_DEFINE_UTIL = @SRPM_DEFINE_UTIL@
+STRIP = @STRIP@
+VENDOR = @VENDOR@
+VERSION = @VERSION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+runstatedir = @runstatedir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+COMMON_H = 
+KERNEL_H = \
+	$(top_srcdir)/include/vm/anon.h \
+	$(top_srcdir)/include/vm/pvn.h \
+	$(top_srcdir)/include/vm/seg_kmem.h
+
+USER_H = 
+EXTRA_DIST = $(COMMON_H) $(KERNEL_H) $(USER_H)
+@CONFIG_KERNEL_TRUE@kerneldir = @prefix@/src/spl-$(VERSION)/include/vm
+@CONFIG_KERNEL_TRUE@kernel_HEADERS = $(KERNEL_H)
+all: all-am
+
+.SUFFIXES:
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+	        && { if test -f $@; then exit 0; else break; fi; }; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu include/vm/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --gnu include/vm/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+	esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
+install-kernelHEADERS: $(kernel_HEADERS)
+	@$(NORMAL_INSTALL)
+	@list='$(kernel_HEADERS)'; test -n "$(kerneldir)" || list=; \
+	if test -n "$$list"; then \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(kerneldir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(kerneldir)" || exit 1; \
+	fi; \
+	for p in $$list; do \
+	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+	  echo "$$d$$p"; \
+	done | $(am__base_list) | \
+	while read files; do \
+	  echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(kerneldir)'"; \
+	  $(INSTALL_HEADER) $$files "$(DESTDIR)$(kerneldir)" || exit $$?; \
+	done
+
+uninstall-kernelHEADERS:
+	@$(NORMAL_UNINSTALL)
+	@list='$(kernel_HEADERS)'; test -n "$(kerneldir)" || list=; \
+	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+	dir='$(DESTDIR)$(kerneldir)'; $(am__uninstall_files_from_dir)
+
+ID: $(am__tagged_files)
+	$(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	set x; \
+	here=`pwd`; \
+	$(am__define_uniq_tagged_files); \
+	shift; \
+	if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+	  test -n "$$unique" || unique=$$empty_fix; \
+	  if test $$# -gt 0; then \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      "$$@" $$unique; \
+	  else \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      $$unique; \
+	  fi; \
+	fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	$(am__define_uniq_tagged_files); \
+	test -z "$(CTAGS_ARGS)$$unique" \
+	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+	     $$unique
+
+GTAGS:
+	here=`$(am__cd) $(top_builddir) && pwd` \
+	  && $(am__cd) $(top_srcdir) \
+	  && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+	list='$(am__tagged_files)'; \
+	case "$(srcdir)" in \
+	  [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+	  *) sdir=$(subdir)/$(srcdir) ;; \
+	esac; \
+	for i in $$list; do \
+	  if test -f "$$i"; then \
+	    echo "$(subdir)/$$i"; \
+	  else \
+	    echo "$$sdir/$$i"; \
+	  fi; \
+	done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	list='$(DISTFILES)'; \
+	  dist_files=`for file in $$list; do echo $$file; done | \
+	  sed -e "s|^$$srcdirstrip/||;t" \
+	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+	case $$dist_files in \
+	  */*) $(MKDIR_P) `echo "$$dist_files" | \
+			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+			   sort -u` ;; \
+	esac; \
+	for file in $$dist_files; do \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  if test -d $$d/$$file; then \
+	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+	    if test -d "$(distdir)/$$file"; then \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+	  else \
+	    test -f "$(distdir)/$$file" \
+	    || cp -p $$d/$$file "$(distdir)/$$file" \
+	    || exit 1; \
+	  fi; \
+	done
+check-am: all-am
+check: check-am
+all-am: Makefile $(HEADERS)
+installdirs:
+	for dir in "$(DESTDIR)$(kerneldir)"; do \
+	  test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+	done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+	if test -z '$(STRIP)'; then \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	      install; \
+	else \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+	fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-am
+	-rm -f Makefile
+distclean-am: clean-am distclean-generic distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-kernelHEADERS
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-kernelHEADERS
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \
+	clean-libtool cscopelist-am ctags ctags-am distclean \
+	distclean-generic distclean-libtool distclean-tags distdir dvi \
+	dvi-am html html-am info info-am install install-am \
+	install-data install-data-am install-dvi install-dvi-am \
+	install-exec install-exec-am install-html install-html-am \
+	install-info install-info-am install-kernelHEADERS install-man \
+	install-pdf install-pdf-am install-ps install-ps-am \
+	install-strip installcheck installcheck-am installdirs \
+	maintainer-clean maintainer-clean-generic mostlyclean \
+	mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+	tags tags-am uninstall uninstall-am uninstall-kernelHEADERS
+
+.PRECIOUS: Makefile
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/vm/anon.h
@@ -0,0 +1,28 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+\*****************************************************************************/
+
+#ifndef _SPL_VM_ANON_H
+#define _SPL_VM_ANON_H
+
+#endif /* SPL_VM_ANON_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/vm/pvn.h
@@ -0,0 +1,28 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+\*****************************************************************************/
+
+#ifndef _SPL_VM_PVN_H
+#define _SPL_VM_PVN_H
+
+#endif /* SPL_VM_PVN_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/include/vm/seg_kmem.h
@@ -0,0 +1,30 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+\*****************************************************************************/
+
+#ifndef _SPL_SEG_KMEM_H
+#define _SPL_SEG_KMEM_H
+
+#include <sys/vmsystm.h>
+
+#endif /* SPL_SEG_KMEM_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/lib/Makefile.am
@@ -0,0 +1,6 @@
+include $(top_srcdir)/config/Rules.am
+
+noinst_LTLIBRARIES = libcommon.la
+libcommon_la_SOURCES = list.c
+
+EXTRA_DIST = list.h
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/lib/Makefile.in
@@ -0,0 +1,655 @@
+# Makefile.in generated by automake 1.15 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2014 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+###############################################################################
+# Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+# Copyright (C) 2007 The Regents of the University of California.
+# Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+###############################################################################
+# Common rules for user space components.
+###############################################################################
+
+VPATH = @srcdir@
+am__is_gnu_make = { \
+  if test -z '$(MAKELEVEL)'; then \
+    false; \
+  elif test -n '$(MAKE_HOST)'; then \
+    true; \
+  elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+    true; \
+  else \
+    false; \
+  fi; \
+}
+am__make_running_with_option = \
+  case $${target_option-} in \
+      ?) ;; \
+      *) echo "am__make_running_with_option: internal error: invalid" \
+              "target option '$${target_option-}' specified" >&2; \
+         exit 1;; \
+  esac; \
+  has_opt=no; \
+  sane_makeflags=$$MAKEFLAGS; \
+  if $(am__is_gnu_make); then \
+    sane_makeflags=$$MFLAGS; \
+  else \
+    case $$MAKEFLAGS in \
+      *\\[\ \	]*) \
+        bs=\\; \
+        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
+    esac; \
+  fi; \
+  skip_next=no; \
+  strip_trailopt () \
+  { \
+    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+  }; \
+  for flg in $$sane_makeflags; do \
+    test $$skip_next = yes && { skip_next=no; continue; }; \
+    case $$flg in \
+      *=*|--*) continue;; \
+        -*I) strip_trailopt 'I'; skip_next=yes;; \
+      -*I?*) strip_trailopt 'I';; \
+        -*O) strip_trailopt 'O'; skip_next=yes;; \
+      -*O?*) strip_trailopt 'O';; \
+        -*l) strip_trailopt 'l'; skip_next=yes;; \
+      -*l?*) strip_trailopt 'l';; \
+      -[dEDm]) skip_next=yes;; \
+      -[JT]) skip_next=yes;; \
+    esac; \
+    case $$flg in \
+      *$$target_option*) has_opt=yes; break;; \
+    esac; \
+  done; \
+  test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+target_triplet = @target@
+subdir = lib
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/config/libtool.m4 \
+	$(top_srcdir)/config/ltoptions.m4 \
+	$(top_srcdir)/config/ltsugar.m4 \
+	$(top_srcdir)/config/ltversion.m4 \
+	$(top_srcdir)/config/lt~obsolete.m4 \
+	$(top_srcdir)/config/spl-build.m4 \
+	$(top_srcdir)/config/spl-meta.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/spl_config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+LTLIBRARIES = $(noinst_LTLIBRARIES)
+libcommon_la_LIBADD =
+am_libcommon_la_OBJECTS = list.lo
+libcommon_la_OBJECTS = $(am_libcommon_la_OBJECTS)
+AM_V_lt = $(am__v_lt_@AM_V@)
+am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 = 
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo "  GEN     " $@;
+am__v_GEN_1 = 
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 = 
+depcomp = $(SHELL) $(top_srcdir)/config/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+	$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+	$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+	$(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_@AM_V@)
+am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
+am__v_CC_0 = @echo "  CC      " $@;
+am__v_CC_1 = 
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+	$(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_@AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo "  CCLD    " $@;
+am__v_CCLD_1 = 
+SOURCES = $(libcommon_la_SOURCES)
+DIST_SOURCES = $(libcommon_la_SOURCES)
+am__can_run_installinfo = \
+  case $$AM_UPDATE_INFO_DIR in \
+    n|no|NO) false;; \
+    *) (install-info --version) >/dev/null 2>&1;; \
+  esac
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates.  Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+  BEGIN { nonempty = 0; } \
+  { items[$$0] = 1; nonempty = 1; } \
+  END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique.  This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+  list='$(am__tagged_files)'; \
+  unique=`for i in $$list; do \
+    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+  done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/config/Rules.am \
+	$(top_srcdir)/config/depcomp
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ALIEN = @ALIEN@
+ALIEN_VERSION = @ALIEN_VERSION@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEBUG_CFLAGS = @DEBUG_CFLAGS@
+DEBUG_KMEM = @DEBUG_KMEM@
+DEBUG_KMEM_TRACKING = @DEBUG_KMEM_TRACKING@
+DEBUG_SPL = @DEBUG_SPL@
+DEFAULT_PACKAGE = @DEFAULT_PACKAGE@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DPKG = @DPKG@
+DPKGBUILD = @DPKGBUILD@
+DPKGBUILD_VERSION = @DPKGBUILD_VERSION@
+DPKG_VERSION = @DPKG_VERSION@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GREP = @GREP@
+HAVE_ALIEN = @HAVE_ALIEN@
+HAVE_DPKG = @HAVE_DPKG@
+HAVE_DPKGBUILD = @HAVE_DPKGBUILD@
+HAVE_RPM = @HAVE_RPM@
+HAVE_RPMBUILD = @HAVE_RPMBUILD@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+KERNELCPPFLAGS = @KERNELCPPFLAGS@
+KERNELMAKE_PARAMS = @KERNELMAKE_PARAMS@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LINUX = @LINUX@
+LINUX_OBJ = @LINUX_OBJ@
+LINUX_SYMBOLS = @LINUX_SYMBOLS@
+LINUX_VERSION = @LINUX_VERSION@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+RANLIB = @RANLIB@
+RELEASE = @RELEASE@
+RPM = @RPM@
+RPMBUILD = @RPMBUILD@
+RPMBUILD_VERSION = @RPMBUILD_VERSION@
+RPM_DEFINE_COMMON = @RPM_DEFINE_COMMON@
+RPM_DEFINE_DKMS = @RPM_DEFINE_DKMS@
+RPM_DEFINE_KMOD = @RPM_DEFINE_KMOD@
+RPM_DEFINE_UTIL = @RPM_DEFINE_UTIL@
+RPM_SPEC_DIR = @RPM_SPEC_DIR@
+RPM_VERSION = @RPM_VERSION@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SPL_CONFIG = @SPL_CONFIG@
+SPL_META_ALIAS = @SPL_META_ALIAS@
+SPL_META_AUTHOR = @SPL_META_AUTHOR@
+SPL_META_DATA = @SPL_META_DATA@
+SPL_META_LICENSE = @SPL_META_LICENSE@
+SPL_META_LT_AGE = @SPL_META_LT_AGE@
+SPL_META_LT_CURRENT = @SPL_META_LT_CURRENT@
+SPL_META_LT_REVISION = @SPL_META_LT_REVISION@
+SPL_META_NAME = @SPL_META_NAME@
+SPL_META_RELEASE = @SPL_META_RELEASE@
+SPL_META_VERSION = @SPL_META_VERSION@
+SRPM_DEFINE_COMMON = @SRPM_DEFINE_COMMON@
+SRPM_DEFINE_DKMS = @SRPM_DEFINE_DKMS@
+SRPM_DEFINE_KMOD = @SRPM_DEFINE_KMOD@
+SRPM_DEFINE_UTIL = @SRPM_DEFINE_UTIL@
+STRIP = @STRIP@
+VENDOR = @VENDOR@
+VERSION = @VERSION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+runstatedir = @runstatedir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+DEFAULT_INCLUDES = -include ${top_builddir}/spl_config.h
+AM_LIBTOOLFLAGS = --silent
+AM_CPPFLAGS = -D__USE_LARGEFILE64
+AM_CFLAGS = -Wall -Wshadow -Wstrict-prototypes -fno-strict-aliasing \
+	${DEBUG_CFLAGS}
+noinst_LTLIBRARIES = libcommon.la
+libcommon_la_SOURCES = list.c
+EXTRA_DIST = list.h
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(top_srcdir)/config/Rules.am $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+	        && { if test -f $@; then exit 0; else break; fi; }; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu lib/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --gnu lib/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+	esac;
+$(top_srcdir)/config/Rules.am $(am__empty):
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+clean-noinstLTLIBRARIES:
+	-test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
+	@list='$(noinst_LTLIBRARIES)'; \
+	locs=`for p in $$list; do echo $$p; done | \
+	      sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+	      sort -u`; \
+	test -z "$$locs" || { \
+	  echo rm -f $${locs}; \
+	  rm -f $${locs}; \
+	}
+
+libcommon.la: $(libcommon_la_OBJECTS) $(libcommon_la_DEPENDENCIES) $(EXTRA_libcommon_la_DEPENDENCIES) 
+	$(AM_V_CCLD)$(LINK)  $(libcommon_la_OBJECTS) $(libcommon_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+	-rm -f *.$(OBJEXT)
+
+distclean-compile:
+	-rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/list.Plo@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
+
+.c.obj:
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
+
+ID: $(am__tagged_files)
+	$(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	set x; \
+	here=`pwd`; \
+	$(am__define_uniq_tagged_files); \
+	shift; \
+	if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+	  test -n "$$unique" || unique=$$empty_fix; \
+	  if test $$# -gt 0; then \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      "$$@" $$unique; \
+	  else \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      $$unique; \
+	  fi; \
+	fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	$(am__define_uniq_tagged_files); \
+	test -z "$(CTAGS_ARGS)$$unique" \
+	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+	     $$unique
+
+GTAGS:
+	here=`$(am__cd) $(top_builddir) && pwd` \
+	  && $(am__cd) $(top_srcdir) \
+	  && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+	list='$(am__tagged_files)'; \
+	case "$(srcdir)" in \
+	  [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+	  *) sdir=$(subdir)/$(srcdir) ;; \
+	esac; \
+	for i in $$list; do \
+	  if test -f "$$i"; then \
+	    echo "$(subdir)/$$i"; \
+	  else \
+	    echo "$$sdir/$$i"; \
+	  fi; \
+	done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	list='$(DISTFILES)'; \
+	  dist_files=`for file in $$list; do echo $$file; done | \
+	  sed -e "s|^$$srcdirstrip/||;t" \
+	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+	case $$dist_files in \
+	  */*) $(MKDIR_P) `echo "$$dist_files" | \
+			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+			   sort -u` ;; \
+	esac; \
+	for file in $$dist_files; do \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  if test -d $$d/$$file; then \
+	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+	    if test -d "$(distdir)/$$file"; then \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+	  else \
+	    test -f "$(distdir)/$$file" \
+	    || cp -p $$d/$$file "$(distdir)/$$file" \
+	    || exit 1; \
+	  fi; \
+	done
+check-am: all-am
+check: check-am
+all-am: Makefile $(LTLIBRARIES)
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+	if test -z '$(STRIP)'; then \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	      install; \
+	else \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+	fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \
+	mostlyclean-am
+
+distclean: distclean-am
+	-rm -rf ./$(DEPDIR)
+	-rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+	distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+	-rm -rf ./$(DEPDIR)
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+	mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \
+	clean-libtool clean-noinstLTLIBRARIES cscopelist-am ctags \
+	ctags-am distclean distclean-compile distclean-generic \
+	distclean-libtool distclean-tags distdir dvi dvi-am html \
+	html-am info info-am install install-am install-data \
+	install-data-am install-dvi install-dvi-am install-exec \
+	install-exec-am install-html install-html-am install-info \
+	install-info-am install-man install-pdf install-pdf-am \
+	install-ps install-ps-am install-strip installcheck \
+	installcheck-am installdirs maintainer-clean \
+	maintainer-clean-generic mostlyclean mostlyclean-compile \
+	mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+	tags tags-am uninstall uninstall-am
+
+.PRECIOUS: Makefile
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/lib/list.c
@@ -0,0 +1,827 @@
+/*****************************************************************************
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2001-2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Chris Dunlap <cdunlap@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is from LSD-Tools, the LLNL Software Development Toolbox.
+ *
+ *  LSD-Tools is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  LSD-Tools is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with LSD-Tools.  If not, see <http://www.gnu.org/licenses/>.
+ *****************************************************************************
+ *  Refer to "list.h" for documentation on public functions.
+ *****************************************************************************/
+
+#ifdef WITH_PTHREADS
+#  include <pthread.h>
+#endif /* WITH_PTHREADS */
+
+#include <assert.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include "list.h"
+
+
+/*********************
+ *  lsd_fatal_error  *
+ *********************/
+
+#ifdef WITH_LSD_FATAL_ERROR_FUNC
+#  undef lsd_fatal_error
+   extern void lsd_fatal_error(char *file, int line, char *mesg);
+#else /* !WITH_LSD_FATAL_ERROR_FUNC */
+#  ifndef lsd_fatal_error
+#    include <errno.h>
+#    include <stdio.h>
+#    include <string.h>
+#    define lsd_fatal_error(file, line, mesg)                                 \
+       do {                                                                   \
+           fprintf(stderr, "ERROR: [%s:%d] %s: %s\n",                         \
+                   file, line, mesg, strerror(errno));                        \
+       } while (0)
+#  endif /* !lsd_fatal_error */
+#endif /* !WITH_LSD_FATAL_ERROR_FUNC */
+
+
+/*********************
+ *  lsd_nomem_error  *
+ *********************/
+
+#ifdef WITH_LSD_NOMEM_ERROR_FUNC
+#  undef lsd_nomem_error
+   extern void * lsd_nomem_error(char *file, int line, char *mesg);
+#else /* !WITH_LSD_NOMEM_ERROR_FUNC */
+#  ifndef lsd_nomem_error
+#    define lsd_nomem_error(file, line, mesg) (NULL)
+#  endif /* !lsd_nomem_error */
+#endif /* !WITH_LSD_NOMEM_ERROR_FUNC */
+
+
+/***************
+ *  Constants  *
+ ***************/
+
+#define LIST_ALLOC 32
+#define LIST_MAGIC 0xDEADBEEF
+
+
+/****************
+ *  Data Types  *
+ ****************/
+
+struct listNode {
+    void                 *data;         /* node's data                       */
+    struct listNode      *next;         /* next node in list                 */
+};
+
+struct listIterator {
+    struct list          *list;         /* the list being iterated           */
+    struct listNode      *pos;          /* the next node to be iterated      */
+    struct listNode     **prev;         /* addr of 'next' ptr to prv It node */
+    struct listIterator  *iNext;        /* iterator chain for list_destroy() */
+#ifndef NDEBUG
+    unsigned int          magic;        /* sentinel for asserting validity   */
+#endif /* !NDEBUG */
+};
+
+struct list {
+    struct listNode      *head;         /* head of the list                  */
+    struct listNode     **tail;         /* addr of last node's 'next' ptr    */
+    struct listIterator  *iNext;        /* iterator chain for list_destroy() */
+    ListDelF              fDel;         /* function to delete node data      */
+    int                   count;        /* number of nodes in list           */
+#ifdef WITH_PTHREADS
+    pthread_mutex_t       mutex;        /* mutex to protect access to list   */
+#endif /* WITH_PTHREADS */
+#ifndef NDEBUG
+    unsigned int          magic;        /* sentinel for asserting validity   */
+#endif /* !NDEBUG */
+};
+
+typedef struct listNode * ListNode;
+
+
+/****************
+ *  Prototypes  *
+ ****************/
+
+static void * list_node_create (List l, ListNode *pp, void *x);
+static void * list_node_destroy (List l, ListNode *pp);
+static List list_alloc (void);
+static void list_free (List l);
+static ListNode list_node_alloc (void);
+static void list_node_free (ListNode p);
+static ListIterator list_iterator_alloc (void);
+static void list_iterator_free (ListIterator i);
+static void * list_alloc_aux (int size, void *pfreelist);
+static void list_free_aux (void *x, void *pfreelist);
+
+
+/***************
+ *  Variables  *
+ ***************/
+
+static List list_free_lists = NULL;
+static ListNode list_free_nodes = NULL;
+static ListIterator list_free_iterators = NULL;
+
+#ifdef WITH_PTHREADS
+static pthread_mutex_t list_free_lock = PTHREAD_MUTEX_INITIALIZER;
+#endif /* WITH_PTHREADS */
+
+
+/************
+ *  Macros  *
+ ************/
+
+#ifdef WITH_PTHREADS
+
+#  define list_mutex_init(mutex)                                              \
+     do {                                                                     \
+         int e = pthread_mutex_init(mutex, NULL);                             \
+         if (e != 0) {                                                        \
+             errno = e;                                                       \
+             lsd_fatal_error(__FILE__, __LINE__, "list mutex init");          \
+             abort();                                                         \
+         }                                                                    \
+     } while (0)
+
+#  define list_mutex_lock(mutex)                                              \
+     do {                                                                     \
+         int e = pthread_mutex_lock(mutex);                                   \
+         if (e != 0) {                                                        \
+             errno = e;                                                       \
+             lsd_fatal_error(__FILE__, __LINE__, "list mutex lock");          \
+             abort();                                                         \
+         }                                                                    \
+     } while (0)
+
+#  define list_mutex_unlock(mutex)                                            \
+     do {                                                                     \
+         int e = pthread_mutex_unlock(mutex);                                 \
+         if (e != 0) {                                                        \
+             errno = e;                                                       \
+             lsd_fatal_error(__FILE__, __LINE__, "list mutex unlock");        \
+             abort();                                                         \
+         }                                                                    \
+     } while (0)
+
+#  define list_mutex_destroy(mutex)                                           \
+     do {                                                                     \
+         int e = pthread_mutex_destroy(mutex);                                \
+         if (e != 0) {                                                        \
+             errno = e;                                                       \
+             lsd_fatal_error(__FILE__, __LINE__, "list mutex destroy");       \
+             abort();                                                         \
+         }                                                                    \
+     } while (0)
+
+#  ifndef NDEBUG
+     static int list_mutex_is_locked (pthread_mutex_t *mutex);
+#  endif /* !NDEBUG */
+
+#else /* !WITH_PTHREADS */
+
+#  define list_mutex_init(mutex)
+#  define list_mutex_lock(mutex)
+#  define list_mutex_unlock(mutex)
+#  define list_mutex_destroy(mutex)
+#  define list_mutex_is_locked(mutex) (1)
+
+#endif /* !WITH_PTHREADS */
+
+
+/***************
+ *  Functions  *
+ ***************/
+
+List
+list_create (ListDelF f)
+{
+    List l;
+
+    if (!(l = list_alloc()))
+        return(lsd_nomem_error(__FILE__, __LINE__, "list create"));
+    l->head = NULL;
+    l->tail = &l->head;
+    l->iNext = NULL;
+    l->fDel = f;
+    l->count = 0;
+    list_mutex_init(&l->mutex);
+    assert(l->magic = LIST_MAGIC);      /* set magic via assert abuse */
+    return(l);
+}
+
+
+void
+list_destroy (List l)
+{
+    ListIterator i, iTmp;
+    ListNode p, pTmp;
+
+    assert(l != NULL);
+    list_mutex_lock(&l->mutex);
+    assert(l->magic == LIST_MAGIC);
+    i = l->iNext;
+    while (i) {
+        assert(i->magic == LIST_MAGIC);
+        iTmp = i->iNext;
+        assert(i->magic = ~LIST_MAGIC); /* clear magic via assert abuse */
+        list_iterator_free(i);
+        i = iTmp;
+    }
+    p = l->head;
+    while (p) {
+        pTmp = p->next;
+        if (p->data && l->fDel)
+            l->fDel(p->data);
+        list_node_free(p);
+        p = pTmp;
+    }
+    assert(l->magic = ~LIST_MAGIC);     /* clear magic via assert abuse */
+    list_mutex_unlock(&l->mutex);
+    list_mutex_destroy(&l->mutex);
+    list_free(l);
+    return;
+}
+
+
+int
+list_is_empty (List l)
+{
+    int n;
+
+    assert(l != NULL);
+    list_mutex_lock(&l->mutex);
+    assert(l->magic == LIST_MAGIC);
+    n = l->count;
+    list_mutex_unlock(&l->mutex);
+    return(n == 0);
+}
+
+
+int
+list_count (List l)
+{
+    int n;
+
+    assert(l != NULL);
+    list_mutex_lock(&l->mutex);
+    assert(l->magic == LIST_MAGIC);
+    n = l->count;
+    list_mutex_unlock(&l->mutex);
+    return(n);
+}
+
+
+void *
+list_append (List l, void *x)
+{
+    void *v;
+
+    assert(l != NULL);
+    assert(x != NULL);
+    list_mutex_lock(&l->mutex);
+    assert(l->magic == LIST_MAGIC);
+    v = list_node_create(l, l->tail, x);
+    list_mutex_unlock(&l->mutex);
+    return(v);
+}
+
+
+void *
+list_prepend (List l, void *x)
+{
+    void *v;
+
+    assert(l != NULL);
+    assert(x != NULL);
+    list_mutex_lock(&l->mutex);
+    assert(l->magic == LIST_MAGIC);
+    v = list_node_create(l, &l->head, x);
+    list_mutex_unlock(&l->mutex);
+    return(v);
+}
+
+
+void *
+list_find_first (List l, ListFindF f, void *key)
+{
+    ListNode p;
+    void *v = NULL;
+
+    assert(l != NULL);
+    assert(f != NULL);
+    list_mutex_lock(&l->mutex);
+    assert(l->magic == LIST_MAGIC);
+    for (p=l->head; p; p=p->next) {
+        if (f(p->data, key)) {
+            v = p->data;
+            break;
+        }
+    }
+    list_mutex_unlock(&l->mutex);
+    return(v);
+}
+
+
+int
+list_delete_all (List l, ListFindF f, void *key)
+{
+    ListNode *pp;
+    void *v;
+    int n = 0;
+
+    assert(l != NULL);
+    assert(f != NULL);
+    list_mutex_lock(&l->mutex);
+    assert(l->magic == LIST_MAGIC);
+    pp = &l->head;
+    while (*pp) {
+        if (f((*pp)->data, key)) {
+            if ((v = list_node_destroy(l, pp))) {
+                if (l->fDel)
+                    l->fDel(v);
+                n++;
+            }
+        }
+        else {
+            pp = &(*pp)->next;
+        }
+    }
+    list_mutex_unlock(&l->mutex);
+    return(n);
+}
+
+
+int
+list_for_each (List l, ListForF f, void *arg)
+{
+    ListNode p;
+    int n = 0;
+
+    assert(l != NULL);
+    assert(f != NULL);
+    list_mutex_lock(&l->mutex);
+    assert(l->magic == LIST_MAGIC);
+    for (p=l->head; p; p=p->next) {
+        n++;
+        if (f(p->data, arg) < 0) {
+            n = -n;
+            break;
+        }
+    }
+    list_mutex_unlock(&l->mutex);
+    return(n);
+}
+
+
+void
+list_sort (List l, ListCmpF f)
+{
+/*  Note: Time complexity O(n^2).
+ */
+    ListNode *pp, *ppPrev, *ppPos, pTmp;
+    ListIterator i;
+
+    assert(l != NULL);
+    assert(f != NULL);
+    list_mutex_lock(&l->mutex);
+    assert(l->magic == LIST_MAGIC);
+    if (l->count > 1) {
+        ppPrev = &l->head;
+        pp = &(*ppPrev)->next;
+        while (*pp) {
+            if (f((*pp)->data, (*ppPrev)->data) < 0) {
+                ppPos = &l->head;
+                while (f((*pp)->data, (*ppPos)->data) >= 0)
+                    ppPos = &(*ppPos)->next;
+                pTmp = (*pp)->next;
+                (*pp)->next = *ppPos;
+                *ppPos = *pp;
+                *pp = pTmp;
+                if (ppPrev == ppPos)
+                    ppPrev = &(*ppPrev)->next;
+            }
+            else {
+                ppPrev = pp;
+                pp = &(*pp)->next;
+            }
+        }
+        l->tail = pp;
+
+        for (i=l->iNext; i; i=i->iNext) {
+            assert(i->magic == LIST_MAGIC);
+            i->pos = i->list->head;
+            i->prev = &i->list->head;
+        }
+    }
+    list_mutex_unlock(&l->mutex);
+    return;
+}
+
+
+void *
+list_push (List l, void *x)
+{
+    void *v;
+
+    assert(l != NULL);
+    assert(x != NULL);
+    list_mutex_lock(&l->mutex);
+    assert(l->magic == LIST_MAGIC);
+    v = list_node_create(l, &l->head, x);
+    list_mutex_unlock(&l->mutex);
+    return(v);
+}
+
+
+void *
+list_pop (List l)
+{
+    void *v;
+
+    assert(l != NULL);
+    list_mutex_lock(&l->mutex);
+    assert(l->magic == LIST_MAGIC);
+    v = list_node_destroy(l, &l->head);
+    list_mutex_unlock(&l->mutex);
+    return(v);
+}
+
+
+void *
+list_peek (List l)
+{
+    void *v;
+
+    assert(l != NULL);
+    list_mutex_lock(&l->mutex);
+    assert(l->magic == LIST_MAGIC);
+    v = (l->head) ? l->head->data : NULL;
+    list_mutex_unlock(&l->mutex);
+    return(v);
+}
+
+
+void *
+list_enqueue (List l, void *x)
+{
+    void *v;
+
+    assert(l != NULL);
+    assert(x != NULL);
+    list_mutex_lock(&l->mutex);
+    assert(l->magic == LIST_MAGIC);
+    v = list_node_create(l, l->tail, x);
+    list_mutex_unlock(&l->mutex);
+    return(v);
+}
+
+
+void *
+list_dequeue (List l)
+{
+    void *v;
+
+    assert(l != NULL);
+    list_mutex_lock(&l->mutex);
+    assert(l->magic == LIST_MAGIC);
+    v = list_node_destroy(l, &l->head);
+    list_mutex_unlock(&l->mutex);
+    return(v);
+}
+
+
+ListIterator
+list_iterator_create (List l)
+{
+    ListIterator i;
+
+    assert(l != NULL);
+    if (!(i = list_iterator_alloc()))
+        return(lsd_nomem_error(__FILE__, __LINE__, "list iterator create"));
+    i->list = l;
+    list_mutex_lock(&l->mutex);
+    assert(l->magic == LIST_MAGIC);
+    i->pos = l->head;
+    i->prev = &l->head;
+    i->iNext = l->iNext;
+    l->iNext = i;
+    assert(i->magic = LIST_MAGIC);      /* set magic via assert abuse */
+    list_mutex_unlock(&l->mutex);
+    return(i);
+}
+
+
+void
+list_iterator_reset (ListIterator i)
+{
+    assert(i != NULL);
+    assert(i->magic == LIST_MAGIC);
+    list_mutex_lock(&i->list->mutex);
+    assert(i->list->magic == LIST_MAGIC);
+    i->pos = i->list->head;
+    i->prev = &i->list->head;
+    list_mutex_unlock(&i->list->mutex);
+    return;
+}
+
+
+void
+list_iterator_destroy (ListIterator i)
+{
+    ListIterator *pi;
+
+    assert(i != NULL);
+    assert(i->magic == LIST_MAGIC);
+    list_mutex_lock(&i->list->mutex);
+    assert(i->list->magic == LIST_MAGIC);
+    for (pi=&i->list->iNext; *pi; pi=&(*pi)->iNext) {
+        assert((*pi)->magic == LIST_MAGIC);
+        if (*pi == i) {
+            *pi = (*pi)->iNext;
+            break;
+        }
+    }
+    list_mutex_unlock(&i->list->mutex);
+    assert(i->magic = ~LIST_MAGIC);     /* clear magic via assert abuse */
+    list_iterator_free(i);
+    return;
+}
+
+
+void *
+list_next (ListIterator i)
+{
+    ListNode p;
+
+    assert(i != NULL);
+    assert(i->magic == LIST_MAGIC);
+    list_mutex_lock(&i->list->mutex);
+    assert(i->list->magic == LIST_MAGIC);
+    if ((p = i->pos))
+        i->pos = p->next;
+    if (*i->prev != p)
+        i->prev = &(*i->prev)->next;
+    list_mutex_unlock(&i->list->mutex);
+    return(p ? p->data : NULL);
+}
+
+
+void *
+list_insert (ListIterator i, void *x)
+{
+    void *v;
+
+    assert(i != NULL);
+    assert(x != NULL);
+    assert(i->magic == LIST_MAGIC);
+    list_mutex_lock(&i->list->mutex);
+    assert(i->list->magic == LIST_MAGIC);
+    v = list_node_create(i->list, i->prev, x);
+    list_mutex_unlock(&i->list->mutex);
+    return(v);
+}
+
+
+void *
+list_find (ListIterator i, ListFindF f, void *key)
+{
+    void *v;
+
+    assert(i != NULL);
+    assert(f != NULL);
+    assert(i->magic == LIST_MAGIC);
+    while ((v=list_next(i)) && !f(v,key)) {;}
+    return(v);
+}
+
+
+void *
+list_remove (ListIterator i)
+{
+    void *v = NULL;
+
+    assert(i != NULL);
+    assert(i->magic == LIST_MAGIC);
+    list_mutex_lock(&i->list->mutex);
+    assert(i->list->magic == LIST_MAGIC);
+    if (*i->prev != i->pos)
+        v = list_node_destroy(i->list, i->prev);
+    list_mutex_unlock(&i->list->mutex);
+    return(v);
+}
+
+
+int
+list_delete (ListIterator i)
+{
+    void *v;
+
+    assert(i != NULL);
+    assert(i->magic == LIST_MAGIC);
+    if ((v = list_remove(i))) {
+        if (i->list->fDel)
+            i->list->fDel(v);
+        return(1);
+    }
+    return(0);
+}
+
+
+static void *
+list_node_create (List l, ListNode *pp, void *x)
+{
+/*  Inserts data pointed to by [x] into list [l] after [pp],
+ *    the address of the previous node's "next" ptr.
+ *  Returns a ptr to data [x], or NULL if insertion fails.
+ *  This routine assumes the list is already locked upon entry.
+ */
+    ListNode p;
+    ListIterator i;
+
+    assert(l != NULL);
+    assert(l->magic == LIST_MAGIC);
+    assert(list_mutex_is_locked(&l->mutex));
+    assert(pp != NULL);
+    assert(x != NULL);
+    if (!(p = list_node_alloc()))
+        return(lsd_nomem_error(__FILE__, __LINE__, "list node create"));
+    p->data = x;
+    if (!(p->next = *pp))
+        l->tail = &p->next;
+    *pp = p;
+    l->count++;
+    for (i=l->iNext; i; i=i->iNext) {
+        assert(i->magic == LIST_MAGIC);
+        if (i->prev == pp)
+            i->prev = &p->next;
+        else if (i->pos == p->next)
+            i->pos = p;
+        assert((i->pos == *i->prev) || (i->pos == (*i->prev)->next));
+    }
+    return(x);
+}
+
+
+static void *
+list_node_destroy (List l, ListNode *pp)
+{
+/*  Removes the node pointed to by [*pp] from from list [l],
+ *    where [pp] is the address of the previous node's "next" ptr.
+ *  Returns the data ptr associated with list item being removed,
+ *    or NULL if [*pp] points to the NULL element.
+ *  This routine assumes the list is already locked upon entry.
+ */
+    void *v;
+    ListNode p;
+    ListIterator i;
+
+    assert(l != NULL);
+    assert(l->magic == LIST_MAGIC);
+    assert(list_mutex_is_locked(&l->mutex));
+    assert(pp != NULL);
+    if (!(p = *pp))
+        return(NULL);
+    v = p->data;
+    if (!(*pp = p->next))
+        l->tail = pp;
+    l->count--;
+    for (i=l->iNext; i; i=i->iNext) {
+        assert(i->magic == LIST_MAGIC);
+        if (i->pos == p)
+            i->pos = p->next, i->prev = pp;
+        else if (i->prev == &p->next)
+            i->prev = pp;
+        assert((i->pos == *i->prev) || (i->pos == (*i->prev)->next));
+    }
+    list_node_free(p);
+    return(v);
+}
+
+
+static List
+list_alloc (void)
+{
+    return(list_alloc_aux(sizeof(struct list), &list_free_lists));
+}
+
+
+static void
+list_free (List l)
+{
+    list_free_aux(l, &list_free_lists);
+    return;
+}
+
+
+static ListNode
+list_node_alloc (void)
+{
+    return(list_alloc_aux(sizeof(struct listNode), &list_free_nodes));
+}
+
+
+static void
+list_node_free (ListNode p)
+{
+    list_free_aux(p, &list_free_nodes);
+    return;
+}
+
+
+static ListIterator
+list_iterator_alloc (void)
+{
+    return(list_alloc_aux(sizeof(struct listIterator), &list_free_iterators));
+}
+
+
+static void
+list_iterator_free (ListIterator i)
+{
+    list_free_aux(i, &list_free_iterators);
+    return;
+}
+
+
+static void *
+list_alloc_aux (int size, void *pfreelist)
+{
+/*  Allocates an object of [size] bytes from the freelist [*pfreelist].
+ *  Memory is added to the freelist in chunks of size LIST_ALLOC.
+ *  Returns a ptr to the object, or NULL if the memory request fails.
+ */
+    void **px;
+    void **pfree = pfreelist;
+    void **plast;
+
+    assert(sizeof(char) == 1);
+    assert(size >= (int)sizeof(void *));
+    assert(pfreelist != NULL);
+    assert(LIST_ALLOC > 0);
+    list_mutex_lock(&list_free_lock);
+    if (!*pfree) {
+        if ((*pfree = malloc(LIST_ALLOC * size))) {
+            px = *pfree;
+            plast = (void **) ((char *) *pfree + ((LIST_ALLOC - 1) * size));
+            while (px < plast)
+                *px = (char *) px + size, px = *px;
+            *plast = NULL;
+        }
+    }
+    if ((px = *pfree))
+        *pfree = *px;
+    else
+        errno = ENOMEM;
+    list_mutex_unlock(&list_free_lock);
+    return(px);
+}
+
+
+static void
+list_free_aux (void *x, void *pfreelist)
+{
+/*  Frees the object [x], returning it to the freelist [*pfreelist].
+ */
+    void **px = x;
+    void **pfree = pfreelist;
+
+    assert(x != NULL);
+    assert(pfreelist != NULL);
+    list_mutex_lock(&list_free_lock);
+    *px = *pfree;
+    *pfree = px;
+    list_mutex_unlock(&list_free_lock);
+    return;
+}
+
+
+#ifndef NDEBUG
+#ifdef WITH_PTHREADS
+static int
+list_mutex_is_locked (pthread_mutex_t *mutex)
+{
+/*  Returns true if the mutex is locked; o/w, returns false.
+ */
+    int rc;
+
+    assert(mutex != NULL);
+    rc = pthread_mutex_trylock(mutex);
+    return(rc == EBUSY ? 1 : 0);
+}
+#endif /* WITH_PTHREADS */
+#endif /* !NDEBUG */
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/lib/list.h
@@ -0,0 +1,279 @@
+/*****************************************************************************
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2001-2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Chris Dunlap <cdunlap@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is from LSD-Tools, the LLNL Software Development Toolbox.
+ *
+ *  LSD-Tools is free software; you can redistribute it and/or modify it under
+ *  the terms of the GNU General Public License as published by the Free
+ *  Software Foundation; either version 2 of the License, or (at your option)
+ *  any later version.
+ *
+ *  LSD-Tools is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ *  more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with LSD-Tools.  If not, see <http://www.gnu.org/licenses/>.
+ *****************************************************************************/
+
+#ifndef LSD_LIST_H
+#define LSD_LIST_H
+
+
+/***********
+ *  Notes  *
+ ***********/
+/*
+ *  If NDEBUG is not defined, internal debug code will be enabled.  This is
+ *  intended for development use only and production code should define NDEBUG.
+ *
+ *  If WITH_LSD_FATAL_ERROR_FUNC is defined, the linker will expect to
+ *  find an external lsd_fatal_error(file,line,mesg) function.  By default,
+ *  lsd_fatal_error(file,line,mesg) is a macro definition that outputs an
+ *  error message to stderr.  This macro may be redefined to invoke another
+ *  routine instead.
+ *
+ *  If WITH_LSD_NOMEM_ERROR_FUNC is defined, the linker will expect to
+ *  find an external lsd_nomem_error(file,line,mesg) function.  By default,
+ *  lsd_nomem_error(file,line,mesg) is a macro definition that returns NULL.
+ *  This macro may be redefined to invoke another routine instead.
+ *
+ *  If WITH_PTHREADS is defined, these routines will be thread-safe.
+ */
+
+
+/****************
+ *  Data Types  *
+ ****************/
+
+typedef struct list * List;
+/*
+ *  List opaque data type.
+ */
+
+typedef struct listIterator * ListIterator;
+/*
+ *  List Iterator opaque data type.
+ */
+
+typedef void (*ListDelF) (void *x);
+/*
+ *  Function prototype to deallocate data stored in a list.
+ *    This function is responsible for freeing all memory associated
+ *    with an item, including all subordinate items (if applicable).
+ */
+
+typedef int (*ListCmpF) (void *x, void *y);
+/*
+ *  Function prototype for comparing two items in a list.
+ *  Returns less-than-zero if (x<y), zero if (x==y), and
+ *    greather-than-zero if (x>y).
+ */
+
+typedef int (*ListFindF) (void *x, void *key);
+/*
+ *  Function prototype for matching items in a list.
+ *  Returns non-zero if (x==key); o/w returns zero.
+ */
+
+typedef int (*ListForF) (void *x, void *arg);
+/*
+ *  Function prototype for operating on each item in a list.
+ *  Returns less-than-zero on error.
+ */
+
+
+/*******************************
+ *  General-Purpose Functions  *
+ *******************************/
+
+List list_create (ListDelF f);
+/*
+ *  Creates and returns a new empty list, or lsd_nomem_error() on failure.
+ *  The deletion function [f] is used to deallocate memory used by items
+ *    in the list; if this is NULL, memory associated with these items
+ *    will not be freed when the list is destroyed.
+ *  Note: Abandoning a list without calling list_destroy() will result
+ *    in a memory leak.
+ */
+
+void list_destroy (List l);
+/*
+ *  Destroys list [l], freeing memory used for list iterators and the
+ *    list itself; if a deletion function was specified when the list
+ *    was created, it will be called for each item in the list.
+ */
+
+int list_is_empty (List l);
+/*
+ *  Returns non-zero if list [l] is empty; o/w returns zero.
+ */
+
+int list_count (List l);
+/*
+ *  Returns the number of items in list [l].
+ */
+
+
+/***************************
+ *  List Access Functions  *
+ ***************************/
+
+void * list_append (List l, void *x);
+/*
+ *  Inserts data [x] at the end of list [l].
+ *  Returns the data's ptr, or lsd_nomem_error() if insertion failed.
+ */
+
+void * list_prepend (List l, void *x);
+/*
+ *  Inserts data [x] at the beginning of list [l].
+ *  Returns the data's ptr, or lsd_nomem_error() if insertion failed.
+ */
+
+void * list_find_first (List l, ListFindF f, void *key);
+/*
+ *  Traverses list [l] using [f] to match each item with [key].
+ *  Returns a ptr to the first item for which the function [f]
+ *    returns non-zero, or NULL if no such item is found.
+ *  Note: This function differs from list_find() in that it does not require
+ *    a list iterator; it should only be used when all list items are known
+ *    to be unique (according to the function [f]).
+ */
+
+int list_delete_all (List l, ListFindF f, void *key);
+/*
+ *  Traverses list [l] using [f] to match each item with [key].
+ *  Removes all items from the list for which the function [f] returns
+ *    non-zero; if a deletion function was specified when the list was
+ *    created, it will be called to deallocate each item being removed.
+ *  Returns a count of the number of items removed from the list.
+ */
+
+int list_for_each (List l, ListForF f, void *arg);
+/*
+ *  For each item in list [l], invokes the function [f] with [arg].
+ *  Returns a count of the number of items on which [f] was invoked.
+ *  If [f] returns <0 for a given item, the iteration is aborted and the
+ *    function returns the negative of that item's position in the list.
+ */
+
+void list_sort (List l, ListCmpF f);
+/*
+ *  Sorts list [l] into ascending order according to the function [f].
+ *  Note: Sorting a list resets all iterators associated with the list.
+ *  Note: The sort algorithm is stable.
+ */
+
+
+/****************************
+ *  Stack Access Functions  *
+ ****************************/
+
+void * list_push (List l, void *x);
+/*
+ *  Pushes data [x] onto the top of stack [l].
+ *  Returns the data's ptr, or lsd_nomem_error() if insertion failed.
+ */
+
+void * list_pop (List l);
+/*
+ *  Pops the data item at the top of the stack [l].
+ *  Returns the data's ptr, or NULL if the stack is empty.
+ */
+
+void * list_peek (List l);
+/*
+ *  Peeks at the data item at the top of the stack (or head of the queue) [l].
+ *  Returns the data's ptr, or NULL if the stack (or queue) is empty.
+ *  Note: The item is not removed from the list.
+ */
+
+
+/****************************
+ *  Queue Access Functions  *
+ ****************************/
+
+void * list_enqueue (List l, void *x);
+/*
+ *  Enqueues data [x] at the tail of queue [l].
+ *  Returns the data's ptr, or lsd_nomem_error() if insertion failed.
+ */
+
+void * list_dequeue (List l);
+/*
+ *  Dequeues the data item at the head of the queue [l].
+ *  Returns the data's ptr, or NULL if the queue is empty.
+ */
+
+
+/*****************************
+ *  List Iterator Functions  *
+ *****************************/
+
+ListIterator list_iterator_create (List l);
+/*
+ *  Creates and returns a list iterator for non-destructively traversing
+ *    list [l], or lsd_nomem_error() on failure.
+ */
+
+void list_iterator_reset (ListIterator i);
+/*
+ *  Resets the list iterator [i] to start traversal at the beginning
+ *    of the list.
+ */
+
+void list_iterator_destroy (ListIterator i);
+/*
+ *  Destroys the list iterator [i]; list iterators not explicitly destroyed
+ *    in this manner will be destroyed when the list is deallocated via
+ *    list_destroy().
+ */
+
+void * list_next (ListIterator i);
+/*
+ *  Returns a ptr to the next item's data,
+ *    or NULL once the end of the list is reached.
+ *  Example: i=list_iterator_create(i); while ((x=list_next(i))) {...}
+ */
+
+void * list_insert (ListIterator i, void *x);
+/*
+ *  Inserts data [x] immediately before the last item returned via list
+ *    iterator [i]; once the list iterator reaches the end of the list,
+ *    insertion is made at the list's end.
+ *  Returns the data's ptr, or lsd_nomem_error() if insertion failed.
+ */
+
+void * list_find (ListIterator i, ListFindF f, void *key);
+/*
+ *  Traverses the list from the point of the list iterator [i]
+ *    using [f] to match each item with [key].
+ *  Returns a ptr to the next item for which the function [f]
+ *    returns non-zero, or NULL once the end of the list is reached.
+ *  Example: i=list_iterator_reset(i); while ((x=list_find(i,f,k))) {...}
+ */
+
+void * list_remove (ListIterator i);
+/*
+ *  Removes from the list the last item returned via list iterator [i]
+ *    and returns the data's ptr.
+ *  Note: The client is responsible for freeing the returned data.
+ */
+
+int list_delete (ListIterator i);
+/*
+ *  Removes from the list the last item returned via list iterator [i];
+ *    if a deletion function was specified when the list was created,
+ *    it will be called to deallocate the item being removed.
+ *  Returns a count of the number of items removed from the list
+ *    (ie, '1' if the item was removed, and '0' otherwise).
+ */
+
+
+#endif /* !LSD_LIST_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/man/Makefile.am
@@ -0,0 +1 @@
+SUBDIRS = man1 man5
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/man/Makefile.in
@@ -0,0 +1,673 @@
+# Makefile.in generated by automake 1.15 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2014 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+VPATH = @srcdir@
+am__is_gnu_make = { \
+  if test -z '$(MAKELEVEL)'; then \
+    false; \
+  elif test -n '$(MAKE_HOST)'; then \
+    true; \
+  elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+    true; \
+  else \
+    false; \
+  fi; \
+}
+am__make_running_with_option = \
+  case $${target_option-} in \
+      ?) ;; \
+      *) echo "am__make_running_with_option: internal error: invalid" \
+              "target option '$${target_option-}' specified" >&2; \
+         exit 1;; \
+  esac; \
+  has_opt=no; \
+  sane_makeflags=$$MAKEFLAGS; \
+  if $(am__is_gnu_make); then \
+    sane_makeflags=$$MFLAGS; \
+  else \
+    case $$MAKEFLAGS in \
+      *\\[\ \	]*) \
+        bs=\\; \
+        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
+    esac; \
+  fi; \
+  skip_next=no; \
+  strip_trailopt () \
+  { \
+    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+  }; \
+  for flg in $$sane_makeflags; do \
+    test $$skip_next = yes && { skip_next=no; continue; }; \
+    case $$flg in \
+      *=*|--*) continue;; \
+        -*I) strip_trailopt 'I'; skip_next=yes;; \
+      -*I?*) strip_trailopt 'I';; \
+        -*O) strip_trailopt 'O'; skip_next=yes;; \
+      -*O?*) strip_trailopt 'O';; \
+        -*l) strip_trailopt 'l'; skip_next=yes;; \
+      -*l?*) strip_trailopt 'l';; \
+      -[dEDm]) skip_next=yes;; \
+      -[JT]) skip_next=yes;; \
+    esac; \
+    case $$flg in \
+      *$$target_option*) has_opt=yes; break;; \
+    esac; \
+  done; \
+  test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+target_triplet = @target@
+subdir = man
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/config/libtool.m4 \
+	$(top_srcdir)/config/ltoptions.m4 \
+	$(top_srcdir)/config/ltsugar.m4 \
+	$(top_srcdir)/config/ltversion.m4 \
+	$(top_srcdir)/config/lt~obsolete.m4 \
+	$(top_srcdir)/config/spl-build.m4 \
+	$(top_srcdir)/config/spl-meta.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/spl_config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo "  GEN     " $@;
+am__v_GEN_1 = 
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 = 
+SOURCES =
+DIST_SOURCES =
+RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \
+	ctags-recursive dvi-recursive html-recursive info-recursive \
+	install-data-recursive install-dvi-recursive \
+	install-exec-recursive install-html-recursive \
+	install-info-recursive install-pdf-recursive \
+	install-ps-recursive install-recursive installcheck-recursive \
+	installdirs-recursive pdf-recursive ps-recursive \
+	tags-recursive uninstall-recursive
+am__can_run_installinfo = \
+  case $$AM_UPDATE_INFO_DIR in \
+    n|no|NO) false;; \
+    *) (install-info --version) >/dev/null 2>&1;; \
+  esac
+RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive	\
+  distclean-recursive maintainer-clean-recursive
+am__recursive_targets = \
+  $(RECURSIVE_TARGETS) \
+  $(RECURSIVE_CLEAN_TARGETS) \
+  $(am__extra_recursive_targets)
+AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \
+	distdir
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates.  Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+  BEGIN { nonempty = 0; } \
+  { items[$$0] = 1; nonempty = 1; } \
+  END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique.  This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+  list='$(am__tagged_files)'; \
+  unique=`for i in $$list; do \
+    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+  done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+DIST_SUBDIRS = $(SUBDIRS)
+am__DIST_COMMON = $(srcdir)/Makefile.in
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+am__relativize = \
+  dir0=`pwd`; \
+  sed_first='s,^\([^/]*\)/.*$$,\1,'; \
+  sed_rest='s,^[^/]*/*,,'; \
+  sed_last='s,^.*/\([^/]*\)$$,\1,'; \
+  sed_butlast='s,/*[^/]*$$,,'; \
+  while test -n "$$dir1"; do \
+    first=`echo "$$dir1" | sed -e "$$sed_first"`; \
+    if test "$$first" != "."; then \
+      if test "$$first" = ".."; then \
+        dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \
+        dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \
+      else \
+        first2=`echo "$$dir2" | sed -e "$$sed_first"`; \
+        if test "$$first2" = "$$first"; then \
+          dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \
+        else \
+          dir2="../$$dir2"; \
+        fi; \
+        dir0="$$dir0"/"$$first"; \
+      fi; \
+    fi; \
+    dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \
+  done; \
+  reldir="$$dir2"
+ACLOCAL = @ACLOCAL@
+ALIEN = @ALIEN@
+ALIEN_VERSION = @ALIEN_VERSION@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEBUG_CFLAGS = @DEBUG_CFLAGS@
+DEBUG_KMEM = @DEBUG_KMEM@
+DEBUG_KMEM_TRACKING = @DEBUG_KMEM_TRACKING@
+DEBUG_SPL = @DEBUG_SPL@
+DEFAULT_PACKAGE = @DEFAULT_PACKAGE@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DPKG = @DPKG@
+DPKGBUILD = @DPKGBUILD@
+DPKGBUILD_VERSION = @DPKGBUILD_VERSION@
+DPKG_VERSION = @DPKG_VERSION@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GREP = @GREP@
+HAVE_ALIEN = @HAVE_ALIEN@
+HAVE_DPKG = @HAVE_DPKG@
+HAVE_DPKGBUILD = @HAVE_DPKGBUILD@
+HAVE_RPM = @HAVE_RPM@
+HAVE_RPMBUILD = @HAVE_RPMBUILD@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+KERNELCPPFLAGS = @KERNELCPPFLAGS@
+KERNELMAKE_PARAMS = @KERNELMAKE_PARAMS@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LINUX = @LINUX@
+LINUX_OBJ = @LINUX_OBJ@
+LINUX_SYMBOLS = @LINUX_SYMBOLS@
+LINUX_VERSION = @LINUX_VERSION@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+RANLIB = @RANLIB@
+RELEASE = @RELEASE@
+RPM = @RPM@
+RPMBUILD = @RPMBUILD@
+RPMBUILD_VERSION = @RPMBUILD_VERSION@
+RPM_DEFINE_COMMON = @RPM_DEFINE_COMMON@
+RPM_DEFINE_DKMS = @RPM_DEFINE_DKMS@
+RPM_DEFINE_KMOD = @RPM_DEFINE_KMOD@
+RPM_DEFINE_UTIL = @RPM_DEFINE_UTIL@
+RPM_SPEC_DIR = @RPM_SPEC_DIR@
+RPM_VERSION = @RPM_VERSION@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SPL_CONFIG = @SPL_CONFIG@
+SPL_META_ALIAS = @SPL_META_ALIAS@
+SPL_META_AUTHOR = @SPL_META_AUTHOR@
+SPL_META_DATA = @SPL_META_DATA@
+SPL_META_LICENSE = @SPL_META_LICENSE@
+SPL_META_LT_AGE = @SPL_META_LT_AGE@
+SPL_META_LT_CURRENT = @SPL_META_LT_CURRENT@
+SPL_META_LT_REVISION = @SPL_META_LT_REVISION@
+SPL_META_NAME = @SPL_META_NAME@
+SPL_META_RELEASE = @SPL_META_RELEASE@
+SPL_META_VERSION = @SPL_META_VERSION@
+SRPM_DEFINE_COMMON = @SRPM_DEFINE_COMMON@
+SRPM_DEFINE_DKMS = @SRPM_DEFINE_DKMS@
+SRPM_DEFINE_KMOD = @SRPM_DEFINE_KMOD@
+SRPM_DEFINE_UTIL = @SRPM_DEFINE_UTIL@
+STRIP = @STRIP@
+VENDOR = @VENDOR@
+VERSION = @VERSION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+runstatedir = @runstatedir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+SUBDIRS = man1 man5
+all: all-recursive
+
+.SUFFIXES:
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+	        && { if test -f $@; then exit 0; else break; fi; }; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu man/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --gnu man/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+	esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
+
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run 'make' without going through this Makefile.
+# To change the values of 'make' variables: instead of editing Makefiles,
+# (1) if the variable is set in 'config.status', edit 'config.status'
+#     (which will cause the Makefiles to be regenerated when you run 'make');
+# (2) otherwise, pass the desired values on the 'make' command line.
+$(am__recursive_targets):
+	@fail=; \
+	if $(am__make_keepgoing); then \
+	  failcom='fail=yes'; \
+	else \
+	  failcom='exit 1'; \
+	fi; \
+	dot_seen=no; \
+	target=`echo $@ | sed s/-recursive//`; \
+	case "$@" in \
+	  distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
+	  *) list='$(SUBDIRS)' ;; \
+	esac; \
+	for subdir in $$list; do \
+	  echo "Making $$target in $$subdir"; \
+	  if test "$$subdir" = "."; then \
+	    dot_seen=yes; \
+	    local_target="$$target-am"; \
+	  else \
+	    local_target="$$target"; \
+	  fi; \
+	  ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+	  || eval $$failcom; \
+	done; \
+	if test "$$dot_seen" = "no"; then \
+	  $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+	fi; test -z "$$fail"
+
+ID: $(am__tagged_files)
+	$(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-recursive
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	set x; \
+	here=`pwd`; \
+	if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
+	  include_option=--etags-include; \
+	  empty_fix=.; \
+	else \
+	  include_option=--include; \
+	  empty_fix=; \
+	fi; \
+	list='$(SUBDIRS)'; for subdir in $$list; do \
+	  if test "$$subdir" = .; then :; else \
+	    test ! -f $$subdir/TAGS || \
+	      set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \
+	  fi; \
+	done; \
+	$(am__define_uniq_tagged_files); \
+	shift; \
+	if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+	  test -n "$$unique" || unique=$$empty_fix; \
+	  if test $$# -gt 0; then \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      "$$@" $$unique; \
+	  else \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      $$unique; \
+	  fi; \
+	fi
+ctags: ctags-recursive
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	$(am__define_uniq_tagged_files); \
+	test -z "$(CTAGS_ARGS)$$unique" \
+	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+	     $$unique
+
+GTAGS:
+	here=`$(am__cd) $(top_builddir) && pwd` \
+	  && $(am__cd) $(top_srcdir) \
+	  && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-recursive
+
+cscopelist-am: $(am__tagged_files)
+	list='$(am__tagged_files)'; \
+	case "$(srcdir)" in \
+	  [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+	  *) sdir=$(subdir)/$(srcdir) ;; \
+	esac; \
+	for i in $$list; do \
+	  if test -f "$$i"; then \
+	    echo "$(subdir)/$$i"; \
+	  else \
+	    echo "$$sdir/$$i"; \
+	  fi; \
+	done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	list='$(DISTFILES)'; \
+	  dist_files=`for file in $$list; do echo $$file; done | \
+	  sed -e "s|^$$srcdirstrip/||;t" \
+	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+	case $$dist_files in \
+	  */*) $(MKDIR_P) `echo "$$dist_files" | \
+			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+			   sort -u` ;; \
+	esac; \
+	for file in $$dist_files; do \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  if test -d $$d/$$file; then \
+	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+	    if test -d "$(distdir)/$$file"; then \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+	  else \
+	    test -f "$(distdir)/$$file" \
+	    || cp -p $$d/$$file "$(distdir)/$$file" \
+	    || exit 1; \
+	  fi; \
+	done
+	@list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
+	  if test "$$subdir" = .; then :; else \
+	    $(am__make_dryrun) \
+	      || test -d "$(distdir)/$$subdir" \
+	      || $(MKDIR_P) "$(distdir)/$$subdir" \
+	      || exit 1; \
+	    dir1=$$subdir; dir2="$(distdir)/$$subdir"; \
+	    $(am__relativize); \
+	    new_distdir=$$reldir; \
+	    dir1=$$subdir; dir2="$(top_distdir)"; \
+	    $(am__relativize); \
+	    new_top_distdir=$$reldir; \
+	    echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \
+	    echo "     am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \
+	    ($(am__cd) $$subdir && \
+	      $(MAKE) $(AM_MAKEFLAGS) \
+	        top_distdir="$$new_top_distdir" \
+	        distdir="$$new_distdir" \
+		am__remove_distdir=: \
+		am__skip_length_check=: \
+		am__skip_mode_fix=: \
+	        distdir) \
+	      || exit 1; \
+	  fi; \
+	done
+check-am: all-am
+check: check-recursive
+all-am: Makefile
+installdirs: installdirs-recursive
+installdirs-am:
+install: install-recursive
+install-exec: install-exec-recursive
+install-data: install-data-recursive
+uninstall: uninstall-recursive
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-recursive
+install-strip:
+	if test -z '$(STRIP)'; then \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	      install; \
+	else \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+	fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+clean: clean-recursive
+
+clean-am: clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-recursive
+	-rm -f Makefile
+distclean-am: clean-am distclean-generic distclean-tags
+
+dvi: dvi-recursive
+
+dvi-am:
+
+html: html-recursive
+
+html-am:
+
+info: info-recursive
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-recursive
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-recursive
+
+install-html-am:
+
+install-info: install-info-recursive
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-recursive
+
+install-pdf-am:
+
+install-ps: install-ps-recursive
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-recursive
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-recursive
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-recursive
+
+pdf-am:
+
+ps: ps-recursive
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: $(am__recursive_targets) install-am install-strip
+
+.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \
+	check-am clean clean-generic clean-libtool cscopelist-am ctags \
+	ctags-am distclean distclean-generic distclean-libtool \
+	distclean-tags distdir dvi dvi-am html html-am info info-am \
+	install install-am install-data install-data-am install-dvi \
+	install-dvi-am install-exec install-exec-am install-html \
+	install-html-am install-info install-info-am install-man \
+	install-pdf install-pdf-am install-ps install-ps-am \
+	install-strip installcheck installcheck-am installdirs \
+	installdirs-am maintainer-clean maintainer-clean-generic \
+	mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \
+	ps ps-am tags tags-am uninstall uninstall-am
+
+.PRECIOUS: Makefile
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/man/man1/Makefile.am
@@ -0,0 +1,4 @@
+dist_man_MANS = splat.1
+
+install-data-local:
+	$(INSTALL) -d -m 0755 "$(DESTDIR)$(mandir)/man1"
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/man/man1/Makefile.in
@@ -0,0 +1,576 @@
+# Makefile.in generated by automake 1.15 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2014 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+VPATH = @srcdir@
+am__is_gnu_make = { \
+  if test -z '$(MAKELEVEL)'; then \
+    false; \
+  elif test -n '$(MAKE_HOST)'; then \
+    true; \
+  elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+    true; \
+  else \
+    false; \
+  fi; \
+}
+am__make_running_with_option = \
+  case $${target_option-} in \
+      ?) ;; \
+      *) echo "am__make_running_with_option: internal error: invalid" \
+              "target option '$${target_option-}' specified" >&2; \
+         exit 1;; \
+  esac; \
+  has_opt=no; \
+  sane_makeflags=$$MAKEFLAGS; \
+  if $(am__is_gnu_make); then \
+    sane_makeflags=$$MFLAGS; \
+  else \
+    case $$MAKEFLAGS in \
+      *\\[\ \	]*) \
+        bs=\\; \
+        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
+    esac; \
+  fi; \
+  skip_next=no; \
+  strip_trailopt () \
+  { \
+    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+  }; \
+  for flg in $$sane_makeflags; do \
+    test $$skip_next = yes && { skip_next=no; continue; }; \
+    case $$flg in \
+      *=*|--*) continue;; \
+        -*I) strip_trailopt 'I'; skip_next=yes;; \
+      -*I?*) strip_trailopt 'I';; \
+        -*O) strip_trailopt 'O'; skip_next=yes;; \
+      -*O?*) strip_trailopt 'O';; \
+        -*l) strip_trailopt 'l'; skip_next=yes;; \
+      -*l?*) strip_trailopt 'l';; \
+      -[dEDm]) skip_next=yes;; \
+      -[JT]) skip_next=yes;; \
+    esac; \
+    case $$flg in \
+      *$$target_option*) has_opt=yes; break;; \
+    esac; \
+  done; \
+  test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+target_triplet = @target@
+subdir = man/man1
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/config/libtool.m4 \
+	$(top_srcdir)/config/ltoptions.m4 \
+	$(top_srcdir)/config/ltsugar.m4 \
+	$(top_srcdir)/config/ltversion.m4 \
+	$(top_srcdir)/config/lt~obsolete.m4 \
+	$(top_srcdir)/config/spl-build.m4 \
+	$(top_srcdir)/config/spl-meta.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/spl_config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo "  GEN     " $@;
+am__v_GEN_1 = 
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 = 
+SOURCES =
+DIST_SOURCES =
+am__can_run_installinfo = \
+  case $$AM_UPDATE_INFO_DIR in \
+    n|no|NO) false;; \
+    *) (install-info --version) >/dev/null 2>&1;; \
+  esac
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+    $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+    *) f=$$p;; \
+  esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+  srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+  for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+  for p in $$list; do echo "$$p $$p"; done | \
+  sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+  $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+    if (++n[$$2] == $(am__install_max)) \
+      { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+    END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+  sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+  sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+  test -z "$$files" \
+    || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+    || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+         $(am__cd) "$$dir" && rm -f $$files; }; \
+  }
+man1dir = $(mandir)/man1
+am__installdirs = "$(DESTDIR)$(man1dir)"
+NROFF = nroff
+MANS = $(dist_man_MANS)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+am__DIST_COMMON = $(dist_man_MANS) $(srcdir)/Makefile.in
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ALIEN = @ALIEN@
+ALIEN_VERSION = @ALIEN_VERSION@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEBUG_CFLAGS = @DEBUG_CFLAGS@
+DEBUG_KMEM = @DEBUG_KMEM@
+DEBUG_KMEM_TRACKING = @DEBUG_KMEM_TRACKING@
+DEBUG_SPL = @DEBUG_SPL@
+DEFAULT_PACKAGE = @DEFAULT_PACKAGE@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DPKG = @DPKG@
+DPKGBUILD = @DPKGBUILD@
+DPKGBUILD_VERSION = @DPKGBUILD_VERSION@
+DPKG_VERSION = @DPKG_VERSION@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GREP = @GREP@
+HAVE_ALIEN = @HAVE_ALIEN@
+HAVE_DPKG = @HAVE_DPKG@
+HAVE_DPKGBUILD = @HAVE_DPKGBUILD@
+HAVE_RPM = @HAVE_RPM@
+HAVE_RPMBUILD = @HAVE_RPMBUILD@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+KERNELCPPFLAGS = @KERNELCPPFLAGS@
+KERNELMAKE_PARAMS = @KERNELMAKE_PARAMS@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LINUX = @LINUX@
+LINUX_OBJ = @LINUX_OBJ@
+LINUX_SYMBOLS = @LINUX_SYMBOLS@
+LINUX_VERSION = @LINUX_VERSION@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+RANLIB = @RANLIB@
+RELEASE = @RELEASE@
+RPM = @RPM@
+RPMBUILD = @RPMBUILD@
+RPMBUILD_VERSION = @RPMBUILD_VERSION@
+RPM_DEFINE_COMMON = @RPM_DEFINE_COMMON@
+RPM_DEFINE_DKMS = @RPM_DEFINE_DKMS@
+RPM_DEFINE_KMOD = @RPM_DEFINE_KMOD@
+RPM_DEFINE_UTIL = @RPM_DEFINE_UTIL@
+RPM_SPEC_DIR = @RPM_SPEC_DIR@
+RPM_VERSION = @RPM_VERSION@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SPL_CONFIG = @SPL_CONFIG@
+SPL_META_ALIAS = @SPL_META_ALIAS@
+SPL_META_AUTHOR = @SPL_META_AUTHOR@
+SPL_META_DATA = @SPL_META_DATA@
+SPL_META_LICENSE = @SPL_META_LICENSE@
+SPL_META_LT_AGE = @SPL_META_LT_AGE@
+SPL_META_LT_CURRENT = @SPL_META_LT_CURRENT@
+SPL_META_LT_REVISION = @SPL_META_LT_REVISION@
+SPL_META_NAME = @SPL_META_NAME@
+SPL_META_RELEASE = @SPL_META_RELEASE@
+SPL_META_VERSION = @SPL_META_VERSION@
+SRPM_DEFINE_COMMON = @SRPM_DEFINE_COMMON@
+SRPM_DEFINE_DKMS = @SRPM_DEFINE_DKMS@
+SRPM_DEFINE_KMOD = @SRPM_DEFINE_KMOD@
+SRPM_DEFINE_UTIL = @SRPM_DEFINE_UTIL@
+STRIP = @STRIP@
+VENDOR = @VENDOR@
+VERSION = @VERSION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+runstatedir = @runstatedir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+dist_man_MANS = splat.1
+all: all-am
+
+.SUFFIXES:
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+	        && { if test -f $@; then exit 0; else break; fi; }; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu man/man1/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --gnu man/man1/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+	esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
+install-man1: $(dist_man_MANS)
+	@$(NORMAL_INSTALL)
+	@list1=''; \
+	list2='$(dist_man_MANS)'; \
+	test -n "$(man1dir)" \
+	  && test -n "`echo $$list1$$list2`" \
+	  || exit 0; \
+	echo " $(MKDIR_P) '$(DESTDIR)$(man1dir)'"; \
+	$(MKDIR_P) "$(DESTDIR)$(man1dir)" || exit 1; \
+	{ for i in $$list1; do echo "$$i"; done;  \
+	if test -n "$$list2"; then \
+	  for i in $$list2; do echo "$$i"; done \
+	    | sed -n '/\.1[a-z]*$$/p'; \
+	fi; \
+	} | while read p; do \
+	  if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
+	  echo "$$d$$p"; echo "$$p"; \
+	done | \
+	sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \
+	      -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \
+	sed 'N;N;s,\n, ,g' | { \
+	list=; while read file base inst; do \
+	  if test "$$base" = "$$inst"; then list="$$list $$file"; else \
+	    echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man1dir)/$$inst'"; \
+	    $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man1dir)/$$inst" || exit $$?; \
+	  fi; \
+	done; \
+	for i in $$list; do echo "$$i"; done | $(am__base_list) | \
+	while read files; do \
+	  test -z "$$files" || { \
+	    echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man1dir)'"; \
+	    $(INSTALL_DATA) $$files "$(DESTDIR)$(man1dir)" || exit $$?; }; \
+	done; }
+
+uninstall-man1:
+	@$(NORMAL_UNINSTALL)
+	@list=''; test -n "$(man1dir)" || exit 0; \
+	files=`{ for i in $$list; do echo "$$i"; done; \
+	l2='$(dist_man_MANS)'; for i in $$l2; do echo "$$i"; done | \
+	  sed -n '/\.1[a-z]*$$/p'; \
+	} | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \
+	      -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \
+	dir='$(DESTDIR)$(man1dir)'; $(am__uninstall_files_from_dir)
+tags TAGS:
+
+ctags CTAGS:
+
+cscope cscopelist:
+
+
+distdir: $(DISTFILES)
+	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	list='$(DISTFILES)'; \
+	  dist_files=`for file in $$list; do echo $$file; done | \
+	  sed -e "s|^$$srcdirstrip/||;t" \
+	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+	case $$dist_files in \
+	  */*) $(MKDIR_P) `echo "$$dist_files" | \
+			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+			   sort -u` ;; \
+	esac; \
+	for file in $$dist_files; do \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  if test -d $$d/$$file; then \
+	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+	    if test -d "$(distdir)/$$file"; then \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+	  else \
+	    test -f "$(distdir)/$$file" \
+	    || cp -p $$d/$$file "$(distdir)/$$file" \
+	    || exit 1; \
+	  fi; \
+	done
+check-am: all-am
+check: check-am
+all-am: Makefile $(MANS)
+installdirs:
+	for dir in "$(DESTDIR)$(man1dir)"; do \
+	  test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+	done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+	if test -z '$(STRIP)'; then \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	      install; \
+	else \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+	fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-am
+	-rm -f Makefile
+distclean-am: clean-am distclean-generic
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-data-local install-man
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man: install-man1
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-man
+
+uninstall-man: uninstall-man1
+
+.MAKE: install-am install-strip
+
+.PHONY: all all-am check check-am clean clean-generic clean-libtool \
+	cscopelist-am ctags-am distclean distclean-generic \
+	distclean-libtool distdir dvi dvi-am html html-am info info-am \
+	install install-am install-data install-data-am \
+	install-data-local install-dvi install-dvi-am install-exec \
+	install-exec-am install-html install-html-am install-info \
+	install-info-am install-man install-man1 install-pdf \
+	install-pdf-am install-ps install-ps-am install-strip \
+	installcheck installcheck-am installdirs maintainer-clean \
+	maintainer-clean-generic mostlyclean mostlyclean-generic \
+	mostlyclean-libtool pdf pdf-am ps ps-am tags-am uninstall \
+	uninstall-am uninstall-man uninstall-man1
+
+.PRECIOUS: Makefile
+
+
+install-data-local:
+	$(INSTALL) -d -m 0755 "$(DESTDIR)$(mandir)/man1"
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/man/man1/splat.1
@@ -0,0 +1,94 @@
+'\" t
+.\"
+.\" Copyright 2013 Darik Horn <dajhorn@vanadac.com>. All rights reserved.
+.\"
+.TH splat 1 "2013 MAR 16" "ZFS on Linux" "User Commands"
+
+.SH NAME
+splat \- Solaris Porting LAyer Tests
+.SH SYNOPSIS
+.LP
+.BI "splat [\-chvx] < \-\-all | \-\-list | \-\-test " "subsystem" ":" "test" " [...] >"
+
+.SH DESCRIPTION
+This utility uses the splat.ko kernel module to test the spl.ko kernel
+module. Run "modprobe splat" before invoking \fBsplat\fR.
+
+.SH OPTIONS
+.HP
+.BI "\-a" "" ", \-\-all" ""
+.IP
+Run all available tests on all subsystems.
+.HP
+.BI "\-c" "" ", \-\-nocolor" ""
+.IP
+Disable output highlighting. By default, "Fail" is printed in red text
+and "Pass" is printed in green text.
+.HP
+.BI "\-h" "" ", \-\-help" ""
+.IP
+Print the usage message.
+.HP
+.BI "\-l" "" ", \-\-list" ""
+.IP
+For each spl.ko subsystem, print all available test names and
+hexidecimal identifiers with a short description.
+.HP
+.BI "\-t" " subsystem" ":" "test" ", \-\-test" " subsystem" ":" "test"
+.HP
+.BI "\-t" " subsystem" ":all" "" ", \-\-test" " subsystem" ":all" ""
+.IP
+Run the \fItest\fR diagnostic routine for the spl.ko \fIsubsystem\fR.
+Specify this option more than once to run multiple tests.
+
+The \fItest\fR and \fIsubsystem\fR parameters are the names or
+hexidecimal identifiers returned by the \fBsplat --list\fR command.
+
+If \fIsubsystem\fR is a name and not a hexidecimal identifier, then the
+\fBall\fR keyword can be used to run all available \fIsubsystem\fR
+tests.
+
+.HP
+.BI "\-v" "" ", \-\-verbose" ""
+.HP
+.IP
+Increase verbosity.
+.HP
+.BI "\-x" "" ", \-\-exit" ""
+.IP
+Stop running tests after the first failure.
+
+.SH "EXAMPLES"
+.LP
+Test everything in the spl.ko kernel module:
+.IP
+# splat --all --verbose
+.LP
+Test the entire kernel memory subsystem:
+.IP
+# splat --test kmem:all
+.LP
+Test the kernel compression and queue waiting facilities:
+.IP
+# splat --test zlib:compress/uncompress --test taskq:wait
+.LP
+This is the same as the previous command, except that the subsystems
+and tests are referenced by hexidecimal identifier instead of by name:
+.IP
+# splat -t 0x0f00:0x0f01 -t 0x0200:0x0204
+
+.SH "NOTES"
+All tests always return a green "Pass" result on a healthy system. Any
+red "Fail" result should be investigated or reported.
+
+.SH "BUGS"
+Some tests can deadlock the kernel if an X11 desktop is running,
+especially if a proprietary blob driver is loaded for the video
+hardware.
+
+.SH "AUTHORS"
+This man page was written by Darik Horn <dajhorn@vanadac.com>.
+
+.SH "SEE ALSO"
+.BR zpios (1),
+.BR ztest (1)
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/man/man5/Makefile.am
@@ -0,0 +1,4 @@
+dist_man_MANS = spl-module-parameters.5
+
+install-data-local:
+	$(INSTALL) -d -m 0755 "$(DESTDIR)$(mandir)/man5"
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/man/man5/Makefile.in
@@ -0,0 +1,576 @@
+# Makefile.in generated by automake 1.15 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2014 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+VPATH = @srcdir@
+am__is_gnu_make = { \
+  if test -z '$(MAKELEVEL)'; then \
+    false; \
+  elif test -n '$(MAKE_HOST)'; then \
+    true; \
+  elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+    true; \
+  else \
+    false; \
+  fi; \
+}
+am__make_running_with_option = \
+  case $${target_option-} in \
+      ?) ;; \
+      *) echo "am__make_running_with_option: internal error: invalid" \
+              "target option '$${target_option-}' specified" >&2; \
+         exit 1;; \
+  esac; \
+  has_opt=no; \
+  sane_makeflags=$$MAKEFLAGS; \
+  if $(am__is_gnu_make); then \
+    sane_makeflags=$$MFLAGS; \
+  else \
+    case $$MAKEFLAGS in \
+      *\\[\ \	]*) \
+        bs=\\; \
+        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
+    esac; \
+  fi; \
+  skip_next=no; \
+  strip_trailopt () \
+  { \
+    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+  }; \
+  for flg in $$sane_makeflags; do \
+    test $$skip_next = yes && { skip_next=no; continue; }; \
+    case $$flg in \
+      *=*|--*) continue;; \
+        -*I) strip_trailopt 'I'; skip_next=yes;; \
+      -*I?*) strip_trailopt 'I';; \
+        -*O) strip_trailopt 'O'; skip_next=yes;; \
+      -*O?*) strip_trailopt 'O';; \
+        -*l) strip_trailopt 'l'; skip_next=yes;; \
+      -*l?*) strip_trailopt 'l';; \
+      -[dEDm]) skip_next=yes;; \
+      -[JT]) skip_next=yes;; \
+    esac; \
+    case $$flg in \
+      *$$target_option*) has_opt=yes; break;; \
+    esac; \
+  done; \
+  test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+target_triplet = @target@
+subdir = man/man5
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/config/libtool.m4 \
+	$(top_srcdir)/config/ltoptions.m4 \
+	$(top_srcdir)/config/ltsugar.m4 \
+	$(top_srcdir)/config/ltversion.m4 \
+	$(top_srcdir)/config/lt~obsolete.m4 \
+	$(top_srcdir)/config/spl-build.m4 \
+	$(top_srcdir)/config/spl-meta.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/spl_config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo "  GEN     " $@;
+am__v_GEN_1 = 
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 = 
+SOURCES =
+DIST_SOURCES =
+am__can_run_installinfo = \
+  case $$AM_UPDATE_INFO_DIR in \
+    n|no|NO) false;; \
+    *) (install-info --version) >/dev/null 2>&1;; \
+  esac
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+    $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+    *) f=$$p;; \
+  esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+  srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+  for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+  for p in $$list; do echo "$$p $$p"; done | \
+  sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+  $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+    if (++n[$$2] == $(am__install_max)) \
+      { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+    END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+  sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+  sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+  test -z "$$files" \
+    || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+    || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+         $(am__cd) "$$dir" && rm -f $$files; }; \
+  }
+man5dir = $(mandir)/man5
+am__installdirs = "$(DESTDIR)$(man5dir)"
+NROFF = nroff
+MANS = $(dist_man_MANS)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+am__DIST_COMMON = $(dist_man_MANS) $(srcdir)/Makefile.in
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ALIEN = @ALIEN@
+ALIEN_VERSION = @ALIEN_VERSION@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEBUG_CFLAGS = @DEBUG_CFLAGS@
+DEBUG_KMEM = @DEBUG_KMEM@
+DEBUG_KMEM_TRACKING = @DEBUG_KMEM_TRACKING@
+DEBUG_SPL = @DEBUG_SPL@
+DEFAULT_PACKAGE = @DEFAULT_PACKAGE@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DPKG = @DPKG@
+DPKGBUILD = @DPKGBUILD@
+DPKGBUILD_VERSION = @DPKGBUILD_VERSION@
+DPKG_VERSION = @DPKG_VERSION@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GREP = @GREP@
+HAVE_ALIEN = @HAVE_ALIEN@
+HAVE_DPKG = @HAVE_DPKG@
+HAVE_DPKGBUILD = @HAVE_DPKGBUILD@
+HAVE_RPM = @HAVE_RPM@
+HAVE_RPMBUILD = @HAVE_RPMBUILD@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+KERNELCPPFLAGS = @KERNELCPPFLAGS@
+KERNELMAKE_PARAMS = @KERNELMAKE_PARAMS@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LINUX = @LINUX@
+LINUX_OBJ = @LINUX_OBJ@
+LINUX_SYMBOLS = @LINUX_SYMBOLS@
+LINUX_VERSION = @LINUX_VERSION@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+RANLIB = @RANLIB@
+RELEASE = @RELEASE@
+RPM = @RPM@
+RPMBUILD = @RPMBUILD@
+RPMBUILD_VERSION = @RPMBUILD_VERSION@
+RPM_DEFINE_COMMON = @RPM_DEFINE_COMMON@
+RPM_DEFINE_DKMS = @RPM_DEFINE_DKMS@
+RPM_DEFINE_KMOD = @RPM_DEFINE_KMOD@
+RPM_DEFINE_UTIL = @RPM_DEFINE_UTIL@
+RPM_SPEC_DIR = @RPM_SPEC_DIR@
+RPM_VERSION = @RPM_VERSION@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SPL_CONFIG = @SPL_CONFIG@
+SPL_META_ALIAS = @SPL_META_ALIAS@
+SPL_META_AUTHOR = @SPL_META_AUTHOR@
+SPL_META_DATA = @SPL_META_DATA@
+SPL_META_LICENSE = @SPL_META_LICENSE@
+SPL_META_LT_AGE = @SPL_META_LT_AGE@
+SPL_META_LT_CURRENT = @SPL_META_LT_CURRENT@
+SPL_META_LT_REVISION = @SPL_META_LT_REVISION@
+SPL_META_NAME = @SPL_META_NAME@
+SPL_META_RELEASE = @SPL_META_RELEASE@
+SPL_META_VERSION = @SPL_META_VERSION@
+SRPM_DEFINE_COMMON = @SRPM_DEFINE_COMMON@
+SRPM_DEFINE_DKMS = @SRPM_DEFINE_DKMS@
+SRPM_DEFINE_KMOD = @SRPM_DEFINE_KMOD@
+SRPM_DEFINE_UTIL = @SRPM_DEFINE_UTIL@
+STRIP = @STRIP@
+VENDOR = @VENDOR@
+VERSION = @VERSION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+runstatedir = @runstatedir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+dist_man_MANS = spl-module-parameters.5
+all: all-am
+
+.SUFFIXES:
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+	        && { if test -f $@; then exit 0; else break; fi; }; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu man/man5/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --gnu man/man5/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+	esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
+install-man5: $(dist_man_MANS)
+	@$(NORMAL_INSTALL)
+	@list1=''; \
+	list2='$(dist_man_MANS)'; \
+	test -n "$(man5dir)" \
+	  && test -n "`echo $$list1$$list2`" \
+	  || exit 0; \
+	echo " $(MKDIR_P) '$(DESTDIR)$(man5dir)'"; \
+	$(MKDIR_P) "$(DESTDIR)$(man5dir)" || exit 1; \
+	{ for i in $$list1; do echo "$$i"; done;  \
+	if test -n "$$list2"; then \
+	  for i in $$list2; do echo "$$i"; done \
+	    | sed -n '/\.5[a-z]*$$/p'; \
+	fi; \
+	} | while read p; do \
+	  if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
+	  echo "$$d$$p"; echo "$$p"; \
+	done | \
+	sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^5][0-9a-z]*$$,5,;x' \
+	      -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \
+	sed 'N;N;s,\n, ,g' | { \
+	list=; while read file base inst; do \
+	  if test "$$base" = "$$inst"; then list="$$list $$file"; else \
+	    echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man5dir)/$$inst'"; \
+	    $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man5dir)/$$inst" || exit $$?; \
+	  fi; \
+	done; \
+	for i in $$list; do echo "$$i"; done | $(am__base_list) | \
+	while read files; do \
+	  test -z "$$files" || { \
+	    echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man5dir)'"; \
+	    $(INSTALL_DATA) $$files "$(DESTDIR)$(man5dir)" || exit $$?; }; \
+	done; }
+
+uninstall-man5:
+	@$(NORMAL_UNINSTALL)
+	@list=''; test -n "$(man5dir)" || exit 0; \
+	files=`{ for i in $$list; do echo "$$i"; done; \
+	l2='$(dist_man_MANS)'; for i in $$l2; do echo "$$i"; done | \
+	  sed -n '/\.5[a-z]*$$/p'; \
+	} | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^5][0-9a-z]*$$,5,;x' \
+	      -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \
+	dir='$(DESTDIR)$(man5dir)'; $(am__uninstall_files_from_dir)
+tags TAGS:
+
+ctags CTAGS:
+
+cscope cscopelist:
+
+
+distdir: $(DISTFILES)
+	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	list='$(DISTFILES)'; \
+	  dist_files=`for file in $$list; do echo $$file; done | \
+	  sed -e "s|^$$srcdirstrip/||;t" \
+	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+	case $$dist_files in \
+	  */*) $(MKDIR_P) `echo "$$dist_files" | \
+			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+			   sort -u` ;; \
+	esac; \
+	for file in $$dist_files; do \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  if test -d $$d/$$file; then \
+	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+	    if test -d "$(distdir)/$$file"; then \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+	  else \
+	    test -f "$(distdir)/$$file" \
+	    || cp -p $$d/$$file "$(distdir)/$$file" \
+	    || exit 1; \
+	  fi; \
+	done
+check-am: all-am
+check: check-am
+all-am: Makefile $(MANS)
+installdirs:
+	for dir in "$(DESTDIR)$(man5dir)"; do \
+	  test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+	done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+	if test -z '$(STRIP)'; then \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	      install; \
+	else \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+	fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-am
+	-rm -f Makefile
+distclean-am: clean-am distclean-generic
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-data-local install-man
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man: install-man5
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-man
+
+uninstall-man: uninstall-man5
+
+.MAKE: install-am install-strip
+
+.PHONY: all all-am check check-am clean clean-generic clean-libtool \
+	cscopelist-am ctags-am distclean distclean-generic \
+	distclean-libtool distdir dvi dvi-am html html-am info info-am \
+	install install-am install-data install-data-am \
+	install-data-local install-dvi install-dvi-am install-exec \
+	install-exec-am install-html install-html-am install-info \
+	install-info-am install-man install-man5 install-pdf \
+	install-pdf-am install-ps install-ps-am install-strip \
+	installcheck installcheck-am installdirs maintainer-clean \
+	maintainer-clean-generic mostlyclean mostlyclean-generic \
+	mostlyclean-libtool pdf pdf-am ps ps-am tags-am uninstall \
+	uninstall-am uninstall-man uninstall-man5
+
+.PRECIOUS: Makefile
+
+
+install-data-local:
+	$(INSTALL) -d -m 0755 "$(DESTDIR)$(mandir)/man5"
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/man/man5/spl-module-parameters.5
@@ -0,0 +1,300 @@
+'\" te
+.\"
+.\" Copyright 2013 Turbo Fredriksson <turbo@bayour.com>. All rights reserved.
+.\"
+.TH SPL-MODULE-PARAMETERS 5 "Nov 18, 2013"
+.SH NAME
+spl\-module\-parameters \- SPL module parameters
+.SH DESCRIPTION
+.sp
+.LP
+Description of the different parameters to the SPL module.
+
+.SS "Module parameters"
+.sp
+.LP
+
+.sp
+.ne 2
+.na
+\fBspl_kmem_cache_expire\fR (uint)
+.ad
+.RS 12n
+Cache expiration is part of default Illumos cache behavior.  The idea is
+that objects in magazines which have not been recently accessed should be
+returned to the slabs periodically.  This is known as cache aging and
+when enabled objects will be typically returned after 15 seconds.
+.sp
+On the other hand Linux slabs are designed to never move objects back to
+the slabs unless there is memory pressure.  This is possible because under
+Linux the cache will be notified when memory is low and objects can be
+released.
+.sp
+By default only the Linux method is enabled.  It has been shown to improve
+responsiveness on low memory systems and not negatively impact the performance
+of systems with more memory.  This policy may be changed by setting the
+\fBspl_kmem_cache_expire\fR bit mask as follows, both policies may be enabled
+concurrently.
+.sp
+0x01 - Aging (Illumos), 0x02 - Low memory (Linux)
+.sp
+Default value: \fB0x02\fR
+.RE
+
+.sp
+.ne 2
+.na
+\fBspl_kmem_cache_reclaim\fR (uint)
+.ad
+.RS 12n
+When this is set it prevents Linux from being able to rapidly reclaim all the
+memory held by the kmem caches.  This may be useful in circumstances where
+it's preferable that Linux reclaim memory from some other subsystem first.
+Setting this will increase the likelihood out of memory events on a memory
+constrained system.
+.sp
+Default value: \fB0\fR
+.RE
+
+.sp
+.ne 2
+.na
+\fBspl_kmem_cache_obj_per_slab\fR (uint)
+.ad
+.RS 12n
+The preferred number of objects per slab in the cache.   In general, a larger
+value will increase the caches memory footprint while decreasing the time
+required to perform an allocation.  Conversely, a smaller value will minimize
+the footprint and improve cache reclaim time but individual allocations may
+take longer.
+.sp
+Default value: \fB8\fR
+.RE
+
+.sp
+.ne 2
+.na
+\fBspl_kmem_cache_obj_per_slab_min\fR (uint)
+.ad
+.RS 12n
+The minimum number of objects allowed per slab.  Normally slabs will contain
+\fBspl_kmem_cache_obj_per_slab\fR objects but for caches that contain very
+large objects it's desirable to only have a few, or even just one, object per
+slab.
+.sp
+Default value: \fB1\fR
+.RE
+
+.sp
+.ne 2
+.na
+\fBspl_kmem_cache_max_size\fR (uint)
+.ad
+.RS 12n
+The maximum size of a kmem cache slab in MiB.  This effectively limits
+the maximum cache object size to \fBspl_kmem_cache_max_size\fR /
+\fBspl_kmem_cache_obj_per_slab\fR.  Caches may not be created with
+object sized larger than this limit.
+.sp
+Default value: \fB32 (64-bit) or 4 (32-bit)\fR
+.RE
+
+.sp
+.ne 2
+.na
+\fBspl_kmem_cache_slab_limit\fR (uint)
+.ad
+.RS 12n
+For small objects the Linux slab allocator should be used to make the most
+efficient use of the memory.  However, large objects are not supported by
+the Linux slab and therefore the SPL implementation is preferred.  This
+value is used to determine the cutoff between a small and large object.
+.sp
+Objects of \fBspl_kmem_cache_slab_limit\fR or smaller will be allocated
+using the Linux slab allocator, large objects use the SPL allocator.  A
+cutoff of 16K was determined to be optimal for architectures using 4K pages.
+.sp
+Default value: \fB16,384\fR
+.RE
+
+.sp
+.ne 2
+.na
+\fBspl_kmem_cache_kmem_limit\fR (uint)
+.ad
+.RS 12n
+Depending on the size of a cache object it may be backed by kmalloc()'d
+or vmalloc()'d memory.  This is because the size of the required allocation
+greatly impacts the best way to allocate the memory.
+.sp
+When objects are small and only a small number of memory pages need to be
+allocated, ideally just one, then kmalloc() is very efficient.  However,
+when allocating multiple pages with kmalloc() it gets increasingly expensive
+because the pages must be physically contiguous.
+.sp
+For this reason we shift to vmalloc() for slabs of large objects which
+which removes the need for contiguous pages.  We cannot use vmalloc() in
+all cases because there is significant locking overhead involved.  This
+function takes a single global lock over the entire virtual address range
+which serializes all allocations.  Using slightly different allocation
+functions for small and large objects allows us to handle a wide range of
+object sizes.
+.sh
+The \fBspl_kmem_cache_kmem_limit\fR value is used to determine this cutoff
+size.  One quarter the PAGE_SIZE is used as the default value because
+\fBspl_kmem_cache_obj_per_slab\fR defaults to 16.  This means that at
+most we will need to allocate four contiguous pages.
+.sp
+Default value: \fBPAGE_SIZE/4\fR
+.RE
+
+.sp
+.ne 2
+.na
+\fBspl_kmem_alloc_warn\fR (uint)
+.ad
+.RS 12n
+As a general rule kmem_alloc() allocations should be small, preferably
+just a few pages since they must by physically contiguous.  Therefore, a
+rate limited warning will be printed to the console for any kmem_alloc()
+which exceeds a reasonable threshold.
+.sp
+The default warning threshold is set to eight pages but capped at 32K to
+accommodate systems using large pages.  This value was selected to be small
+enough to ensure the largest allocations are quickly noticed and fixed.
+But large enough to avoid logging any warnings when a allocation size is
+larger than optimal but not a serious concern.  Since this value is tunable,
+developers are encouraged to set it lower when testing so any new largish
+allocations are quickly caught.  These warnings may be disabled by setting
+the threshold to zero.
+.sp
+Default value: \fB32,768\fR
+.RE
+
+.sp
+.ne 2
+.na
+\fBspl_kmem_alloc_max\fR (uint)
+.ad
+.RS 12n
+Large kmem_alloc() allocations will fail if they exceed KMALLOC_MAX_SIZE.
+Allocations which are marginally smaller than this limit may succeed but
+should still be avoided due to the expense of locating a contiguous range
+of free pages.  Therefore, a maximum kmem size with reasonable safely
+margin of 4x is set.  Kmem_alloc() allocations larger than this maximum
+will quickly fail.  Vmem_alloc() allocations less than or equal to this
+value will use kmalloc(), but shift to vmalloc() when exceeding this value.
+.sp
+Default value: \fBKMALLOC_MAX_SIZE/4\fR
+.RE
+
+.sp
+.ne 2
+.na
+\fBspl_kmem_cache_magazine_size\fR (uint)
+.ad
+.RS 12n
+Cache magazines are an optimization designed to minimize the cost of
+allocating memory.  They do this by keeping a per-cpu cache of recently
+freed objects, which can then be reallocated without taking a lock. This
+can improve performance on highly contended caches.  However, because
+objects in magazines will prevent otherwise empty slabs from being
+immediately released this may not be ideal for low memory machines.
+.sp
+For this reason \fBspl_kmem_cache_magazine_size\fR can be used to set a
+maximum magazine size.  When this value is set to 0 the magazine size will
+be automatically determined based on the object size.  Otherwise magazines
+will be limited to 2-256 objects per magazine (i.e per cpu).  Magazines
+may never be entirely disabled in this implementation.
+.sp
+Default value: \fB0\fR
+.RE
+
+.sp
+.ne 2
+.na
+\fBspl_hostid\fR (ulong)
+.ad
+.RS 12n
+The system hostid, when set this can be used to uniquely identify a system.
+By default this value is set to zero which indicates the hostid is disabled.
+It can be explicitly enabled by placing a unique non-zero value in
+\fB/etc/hostid/\fR.
+.sp
+Default value: \fB0\fR
+.RE
+
+.sp
+.ne 2
+.na
+\fBspl_hostid_path\fR (charp)
+.ad
+.RS 12n
+The expected path to locate the system hostid when specified.  This value
+may be overridden for non-standard configurations.
+.sp
+Default value: \fB/etc/hostid\fR
+.RE
+
+.sp
+.ne 2
+.na
+\fBspl_taskq_thread_bind\fR (int)
+.ad
+.RS 12n
+Bind taskq threads to specific CPUs.  When enabled all taskq threads will
+be distributed evenly  over the available CPUs.  By default, this behavior
+is disabled to allow the Linux scheduler the maximum flexibility to determine
+where a thread should run.
+.sp
+Default value: \fB0\fR
+.RE
+
+.sp
+.ne 2
+.na
+\fBspl_taskq_thread_dynamic\fR (int)
+.ad
+.RS 12n
+Allow dynamic taskqs.  When enabled taskqs which set the TASKQ_DYNAMIC flag
+will by default create only a single thread.  New threads will be created on
+demand up to a maximum allowed number to facilitate the completion of
+outstanding tasks.  Threads which are no longer needed will be promptly
+destroyed.  By default this behavior is enabled but it can be disabled to
+aid performance analysis or troubleshooting.
+.sp
+Default value: \fB1\fR
+.RE
+
+.sp
+.ne 2
+.na
+\fBspl_taskq_thread_priority\fR (int)
+.ad
+.RS 12n
+Allow newly created taskq threads to set a non-default scheduler priority.
+When enabled the priority specified when a taskq is created will be applied
+to all threads created by that taskq.  When disabled all threads will use
+the default Linux kernel thread priority.  By default, this behavior is
+enabled.
+.sp
+Default value: \fB1\fR
+.RE
+
+.sp
+.ne 2
+.na
+\fBspl_taskq_thread_sequential\fR (int)
+.ad
+.RS 12n
+The number of items a taskq worker thread must handle without interruption
+before requesting a new worker thread be spawned.  This is used to control
+how quickly taskqs ramp up the number of threads processing the queue.
+Because Linux thread creation and destruction are relatively inexpensive a
+small default value has been selected.  This means that normally threads will
+be created aggressively which is desirable.  Increasing this value will
+result in a slower thread creation rate which may be preferable for some
+configurations.
+.sp
+Default value: \fB4\fR
+.RE
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/module/Makefile.in
@@ -0,0 +1,54 @@
+subdir-m += spl
+subdir-m += splat
+
+INSTALL_MOD_DIR ?= extra
+
+SPL_MODULE_CFLAGS  = -I@abs_top_srcdir@/include
+SPL_MODULE_CFLAGS += -include @abs_top_builddir@/spl_config.h
+export SPL_MODULE_CFLAGS
+
+modules:
+	$(MAKE) -C @LINUX_OBJ@ SUBDIRS=`pwd` @KERNELMAKE_PARAMS@ CONFIG_SPL=m $@
+
+clean:
+	@# Only cleanup the kernel build directories when CONFIG_KERNEL
+	@# is defined.  This indicates that kernel modules should be built.
+@CONFIG_KERNEL_TRUE@	$(MAKE) -C @LINUX_OBJ@ SUBDIRS=`pwd` @KERNELMAKE_PARAMS@ $@
+
+	if [ -f @LINUX_SYMBOLS@ ]; then $(RM) @LINUX_SYMBOLS@; fi
+	if [ -f Module.markers ]; then $(RM) Module.markers; fi
+
+modules_install:
+	@# Install the kernel modules
+	$(MAKE) -C @LINUX_OBJ@ SUBDIRS=`pwd` $@ \
+		INSTALL_MOD_PATH=$(DESTDIR)$(INSTALL_MOD_PATH) \
+		INSTALL_MOD_DIR=$(INSTALL_MOD_DIR) \
+		KERNELRELEASE=@LINUX_VERSION@
+	@# Remove extraneous build products when packaging
+	kmoddir=$(DESTDIR)$(INSTALL_MOD_PATH)/lib/modules/@LINUX_VERSION@; \
+	if [ -n "$(DESTDIR)" ]; then \
+		find $$kmoddir -name 'modules.*' | xargs $(RM); \
+	fi
+	sysmap=$(DESTDIR)$(INSTALL_MOD_PATH)/boot/System.map-@LINUX_VERSION@; \
+	if [ -f $$sysmap ]; then \
+		depmod -ae -F $$sysmap @LINUX_VERSION@; \
+	fi
+
+modules_uninstall:
+	@# Uninstall the kernel modules
+	kmoddir=$(DESTDIR)$(INSTALL_MOD_PATH)/lib/modules/@LINUX_VERSION@
+	list='$(subdir-m)'; for subdir in $$list; do \
+		$(RM) -R $$kmoddir/$(INSTALL_MOD_DIR)/$$subdir; \
+	done
+
+distdir:
+	list='$(subdir-m)'; for subdir in $$list; do \
+		(find @top_srcdir@/module/$$subdir -name '*.c' -o -name '*.h' |\
+		 xargs /bin/cp -t $$distdir/$$subdir); \
+	done
+
+distclean maintainer-clean: clean
+install: modules_install
+uninstall: modules_uninstall
+all: modules
+check:
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/module/spl/Makefile.in
@@ -0,0 +1,30 @@
+# Makefile.in for spl kernel module
+
+src = @abs_top_srcdir@/module/spl
+obj = @abs_builddir@
+
+MODULE := spl
+EXTRA_CFLAGS = $(SPL_MODULE_CFLAGS) @KERNELCPPFLAGS@
+
+# Solaris porting layer module
+obj-$(CONFIG_SPL) := $(MODULE).o
+
+$(MODULE)-objs += spl-proc.o
+$(MODULE)-objs += spl-kmem.o
+$(MODULE)-objs += spl-kmem-cache.o
+$(MODULE)-objs += spl-vmem.o
+$(MODULE)-objs += spl-thread.o
+$(MODULE)-objs += spl-taskq.o
+$(MODULE)-objs += spl-rwlock.o
+$(MODULE)-objs += spl-vnode.o
+$(MODULE)-objs += spl-err.o
+$(MODULE)-objs += spl-kobj.o
+$(MODULE)-objs += spl-generic.o
+$(MODULE)-objs += spl-atomic.o
+$(MODULE)-objs += spl-mutex.o
+$(MODULE)-objs += spl-kstat.o
+$(MODULE)-objs += spl-condvar.o
+$(MODULE)-objs += spl-xdr.o
+$(MODULE)-objs += spl-cred.o
+$(MODULE)-objs += spl-tsd.o
+$(MODULE)-objs += spl-zlib.o
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/module/spl/spl-atomic.c
@@ -0,0 +1,42 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+ *****************************************************************************
+ *  Solaris Porting Layer (SPL) Atomic Implementation.
+\*****************************************************************************/
+
+#include <sys/atomic.h>
+
+#ifdef DEBUG_SUBSYSTEM
+#undef DEBUG_SUBSYSTEM
+#endif
+
+#define DEBUG_SUBSYSTEM S_ATOMIC
+
+#ifdef ATOMIC_SPINLOCK
+/* Global atomic lock declarations */
+DEFINE_SPINLOCK(atomic32_lock);
+DEFINE_SPINLOCK(atomic64_lock);
+
+EXPORT_SYMBOL(atomic32_lock);
+EXPORT_SYMBOL(atomic64_lock);
+#endif /* ATOMIC_SPINLOCK */
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/module/spl/spl-condvar.c
@@ -0,0 +1,355 @@
+/*
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ *  Solaris Porting Layer (SPL) Credential Implementation.
+ */
+
+#include <sys/condvar.h>
+#include <sys/time.h>
+
+void
+__cv_init(kcondvar_t *cvp, char *name, kcv_type_t type, void *arg)
+{
+	ASSERT(cvp);
+	ASSERT(name == NULL);
+	ASSERT(type == CV_DEFAULT);
+	ASSERT(arg == NULL);
+
+	cvp->cv_magic = CV_MAGIC;
+	init_waitqueue_head(&cvp->cv_event);
+	init_waitqueue_head(&cvp->cv_destroy);
+	atomic_set(&cvp->cv_waiters, 0);
+	atomic_set(&cvp->cv_refs, 1);
+	cvp->cv_mutex = NULL;
+}
+EXPORT_SYMBOL(__cv_init);
+
+static int
+cv_destroy_wakeup(kcondvar_t *cvp)
+{
+	if (!atomic_read(&cvp->cv_waiters) && !atomic_read(&cvp->cv_refs)) {
+		ASSERT(cvp->cv_mutex == NULL);
+		ASSERT(!waitqueue_active(&cvp->cv_event));
+		return (1);
+	}
+
+	return (0);
+}
+
+void
+__cv_destroy(kcondvar_t *cvp)
+{
+	ASSERT(cvp);
+	ASSERT(cvp->cv_magic == CV_MAGIC);
+
+	cvp->cv_magic = CV_DESTROY;
+	atomic_dec(&cvp->cv_refs);
+
+	/* Block until all waiters are woken and references dropped. */
+	while (cv_destroy_wakeup(cvp) == 0)
+		wait_event_timeout(cvp->cv_destroy, cv_destroy_wakeup(cvp), 1);
+
+	ASSERT3P(cvp->cv_mutex, ==, NULL);
+	ASSERT3S(atomic_read(&cvp->cv_refs), ==, 0);
+	ASSERT3S(atomic_read(&cvp->cv_waiters), ==, 0);
+	ASSERT3S(waitqueue_active(&cvp->cv_event), ==, 0);
+}
+EXPORT_SYMBOL(__cv_destroy);
+
+static void
+cv_wait_common(kcondvar_t *cvp, kmutex_t *mp, int state, int io)
+{
+	DEFINE_WAIT(wait);
+	kmutex_t *m;
+
+	ASSERT(cvp);
+	ASSERT(mp);
+	ASSERT(cvp->cv_magic == CV_MAGIC);
+	ASSERT(mutex_owned(mp));
+	atomic_inc(&cvp->cv_refs);
+
+	m = ACCESS_ONCE(cvp->cv_mutex);
+	if (!m)
+		m = xchg(&cvp->cv_mutex, mp);
+	/* Ensure the same mutex is used by all callers */
+	ASSERT(m == NULL || m == mp);
+
+	prepare_to_wait_exclusive(&cvp->cv_event, &wait, state);
+	atomic_inc(&cvp->cv_waiters);
+
+	/*
+	 * Mutex should be dropped after prepare_to_wait() this
+	 * ensures we're linked in to the waiters list and avoids the
+	 * race where 'cvp->cv_waiters > 0' but the list is empty.
+	 */
+	mutex_exit(mp);
+	if (io)
+		io_schedule();
+	else
+		schedule();
+
+	/* No more waiters a different mutex could be used */
+	if (atomic_dec_and_test(&cvp->cv_waiters)) {
+		/*
+		 * This is set without any lock, so it's racy. But this is
+		 * just for debug anyway, so make it best-effort
+		 */
+		cvp->cv_mutex = NULL;
+		wake_up(&cvp->cv_destroy);
+	}
+
+	finish_wait(&cvp->cv_event, &wait);
+	atomic_dec(&cvp->cv_refs);
+
+	/*
+	 * Hold mutex after we release the cvp, otherwise we could dead lock
+	 * with a thread holding the mutex and call cv_destroy.
+	 */
+	mutex_enter(mp);
+}
+
+void
+__cv_wait(kcondvar_t *cvp, kmutex_t *mp)
+{
+	cv_wait_common(cvp, mp, TASK_UNINTERRUPTIBLE, 0);
+}
+EXPORT_SYMBOL(__cv_wait);
+
+void
+__cv_wait_sig(kcondvar_t *cvp, kmutex_t *mp)
+{
+	cv_wait_common(cvp, mp, TASK_INTERRUPTIBLE, 0);
+}
+EXPORT_SYMBOL(__cv_wait_sig);
+
+void
+__cv_wait_io(kcondvar_t *cvp, kmutex_t *mp)
+{
+	cv_wait_common(cvp, mp, TASK_UNINTERRUPTIBLE, 1);
+}
+EXPORT_SYMBOL(__cv_wait_io);
+
+/*
+ * 'expire_time' argument is an absolute wall clock time in jiffies.
+ * Return value is time left (expire_time - now) or -1 if timeout occurred.
+ */
+static clock_t
+__cv_timedwait_common(kcondvar_t *cvp, kmutex_t *mp, clock_t expire_time,
+    int state)
+{
+	DEFINE_WAIT(wait);
+	kmutex_t *m;
+	clock_t time_left;
+
+	ASSERT(cvp);
+	ASSERT(mp);
+	ASSERT(cvp->cv_magic == CV_MAGIC);
+	ASSERT(mutex_owned(mp));
+	atomic_inc(&cvp->cv_refs);
+
+	m = ACCESS_ONCE(cvp->cv_mutex);
+	if (!m)
+		m = xchg(&cvp->cv_mutex, mp);
+	/* Ensure the same mutex is used by all callers */
+	ASSERT(m == NULL || m == mp);
+
+	/* XXX - Does not handle jiffie wrap properly */
+	time_left = expire_time - jiffies;
+	if (time_left <= 0) {
+		/* XXX - doesn't reset cv_mutex */
+		atomic_dec(&cvp->cv_refs);
+		return (-1);
+	}
+
+	prepare_to_wait_exclusive(&cvp->cv_event, &wait, state);
+	atomic_inc(&cvp->cv_waiters);
+
+	/*
+	 * Mutex should be dropped after prepare_to_wait() this
+	 * ensures we're linked in to the waiters list and avoids the
+	 * race where 'cvp->cv_waiters > 0' but the list is empty.
+	 */
+	mutex_exit(mp);
+	time_left = schedule_timeout(time_left);
+
+	/* No more waiters a different mutex could be used */
+	if (atomic_dec_and_test(&cvp->cv_waiters)) {
+		/*
+		 * This is set without any lock, so it's racy. But this is
+		 * just for debug anyway, so make it best-effort
+		 */
+		cvp->cv_mutex = NULL;
+		wake_up(&cvp->cv_destroy);
+	}
+
+	finish_wait(&cvp->cv_event, &wait);
+	atomic_dec(&cvp->cv_refs);
+
+	/*
+	 * Hold mutex after we release the cvp, otherwise we could dead lock
+	 * with a thread holding the mutex and call cv_destroy.
+	 */
+	mutex_enter(mp);
+	return (time_left > 0 ? time_left : -1);
+}
+
+clock_t
+__cv_timedwait(kcondvar_t *cvp, kmutex_t *mp, clock_t exp_time)
+{
+	return (__cv_timedwait_common(cvp, mp, exp_time, TASK_UNINTERRUPTIBLE));
+}
+EXPORT_SYMBOL(__cv_timedwait);
+
+clock_t
+__cv_timedwait_sig(kcondvar_t *cvp, kmutex_t *mp, clock_t exp_time)
+{
+	return (__cv_timedwait_common(cvp, mp, exp_time, TASK_INTERRUPTIBLE));
+}
+EXPORT_SYMBOL(__cv_timedwait_sig);
+
+/*
+ * 'expire_time' argument is an absolute clock time in nanoseconds.
+ * Return value is time left (expire_time - now) or -1 if timeout occurred.
+ */
+static clock_t
+__cv_timedwait_hires(kcondvar_t *cvp, kmutex_t *mp, hrtime_t expire_time,
+    int state)
+{
+	DEFINE_WAIT(wait);
+	kmutex_t *m;
+	hrtime_t time_left, now;
+	unsigned long time_left_us;
+
+	ASSERT(cvp);
+	ASSERT(mp);
+	ASSERT(cvp->cv_magic == CV_MAGIC);
+	ASSERT(mutex_owned(mp));
+	atomic_inc(&cvp->cv_refs);
+
+	m = ACCESS_ONCE(cvp->cv_mutex);
+	if (!m)
+		m = xchg(&cvp->cv_mutex, mp);
+	/* Ensure the same mutex is used by all callers */
+	ASSERT(m == NULL || m == mp);
+
+	now = gethrtime();
+	time_left = expire_time - now;
+	if (time_left <= 0) {
+		atomic_dec(&cvp->cv_refs);
+		return (-1);
+	}
+	time_left_us = time_left / NSEC_PER_USEC;
+
+	prepare_to_wait_exclusive(&cvp->cv_event, &wait, state);
+	atomic_inc(&cvp->cv_waiters);
+
+	/*
+	 * Mutex should be dropped after prepare_to_wait() this
+	 * ensures we're linked in to the waiters list and avoids the
+	 * race where 'cvp->cv_waiters > 0' but the list is empty.
+	 */
+	mutex_exit(mp);
+	/*
+	 * Allow a 100 us range to give kernel an opportunity to coalesce
+	 * interrupts
+	 */
+	usleep_range(time_left_us, time_left_us + 100);
+
+	/* No more waiters a different mutex could be used */
+	if (atomic_dec_and_test(&cvp->cv_waiters)) {
+		/*
+		 * This is set without any lock, so it's racy. But this is
+		 * just for debug anyway, so make it best-effort
+		 */
+		cvp->cv_mutex = NULL;
+		wake_up(&cvp->cv_destroy);
+	}
+
+	finish_wait(&cvp->cv_event, &wait);
+	atomic_dec(&cvp->cv_refs);
+
+	mutex_enter(mp);
+	time_left = expire_time - gethrtime();
+	return (time_left > 0 ? time_left : -1);
+}
+
+/*
+ * Compatibility wrapper for the cv_timedwait_hires() Illumos interface.
+ */
+clock_t
+cv_timedwait_hires(kcondvar_t *cvp, kmutex_t *mp, hrtime_t tim, hrtime_t res,
+    int flag)
+{
+	if (res > 1) {
+		/*
+		 * Align expiration to the specified resolution.
+		 */
+		if (flag & CALLOUT_FLAG_ROUNDUP)
+			tim += res - 1;
+		tim = (tim / res) * res;
+	}
+
+	if (!(flag & CALLOUT_FLAG_ABSOLUTE))
+		tim += gethrtime();
+
+	return (__cv_timedwait_hires(cvp, mp, tim, TASK_UNINTERRUPTIBLE));
+}
+EXPORT_SYMBOL(cv_timedwait_hires);
+
+void
+__cv_signal(kcondvar_t *cvp)
+{
+	ASSERT(cvp);
+	ASSERT(cvp->cv_magic == CV_MAGIC);
+	atomic_inc(&cvp->cv_refs);
+
+	/*
+	 * All waiters are added with WQ_FLAG_EXCLUSIVE so only one
+	 * waiter will be set runable with each call to wake_up().
+	 * Additionally wake_up() holds a spin_lock assoicated with
+	 * the wait queue to ensure we don't race waking up processes.
+	 */
+	if (atomic_read(&cvp->cv_waiters) > 0)
+		wake_up(&cvp->cv_event);
+
+	atomic_dec(&cvp->cv_refs);
+}
+EXPORT_SYMBOL(__cv_signal);
+
+void
+__cv_broadcast(kcondvar_t *cvp)
+{
+	ASSERT(cvp);
+	ASSERT(cvp->cv_magic == CV_MAGIC);
+	atomic_inc(&cvp->cv_refs);
+
+	/*
+	 * Wake_up_all() will wake up all waiters even those which
+	 * have the WQ_FLAG_EXCLUSIVE flag set.
+	 */
+	if (atomic_read(&cvp->cv_waiters) > 0)
+		wake_up_all(&cvp->cv_event);
+
+	atomic_dec(&cvp->cv_refs);
+}
+EXPORT_SYMBOL(__cv_broadcast);
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/module/spl/spl-cred.c
@@ -0,0 +1,195 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+ *****************************************************************************
+ *  Solaris Porting Layer (SPL) Credential Implementation.
+\*****************************************************************************/
+
+#include <sys/cred.h>
+
+#ifdef DEBUG_SUBSYSTEM
+#undef DEBUG_SUBSYSTEM
+#endif
+
+#define DEBUG_SUBSYSTEM S_CRED
+
+static int
+#ifdef HAVE_KUIDGID_T
+cr_groups_search(const struct group_info *group_info, kgid_t grp)
+#else
+cr_groups_search(const struct group_info *group_info, gid_t grp)
+#endif
+{
+	unsigned int left, right, mid;
+	int cmp;
+
+	if (!group_info)
+		return 0;
+
+	left = 0;
+	right = group_info->ngroups;
+	while (left < right) {
+		mid = (left + right) / 2;
+		cmp = KGID_TO_SGID(grp) -
+		    KGID_TO_SGID(GROUP_AT(group_info, mid));
+
+		if (cmp > 0)
+			left = mid + 1;
+		else if (cmp < 0)
+			right = mid;
+		else
+			return 1;
+	}
+	return 0;
+}
+
+/* Hold a reference on the credential and group info */
+void
+crhold(cred_t *cr)
+{
+	(void)get_cred((const cred_t *)cr);
+	(void)get_group_info(cr->group_info);
+}
+
+/* Free a reference on the credential and group info */
+void
+crfree(cred_t *cr)
+{
+	put_group_info(cr->group_info);
+	put_cred((const cred_t *)cr);
+}
+
+/* Return the number of supplemental groups */
+int
+crgetngroups(const cred_t *cr)
+{
+	struct group_info *gi;
+	int rc;
+
+	gi = get_group_info(cr->group_info);
+	rc = gi->ngroups;
+	put_group_info(gi);
+
+	return rc;
+}
+
+/*
+ * Return an array of supplemental gids.  The returned address is safe
+ * to use as long as the caller has taken a reference with crhold().
+ * The caller is responsible for releasing the reference with crfree().
+ */
+gid_t *
+crgetgroups(const cred_t *cr)
+{
+	struct group_info *gi;
+	gid_t *gids;
+
+	gi = get_group_info(cr->group_info);
+	gids = KGIDP_TO_SGIDP(gi->blocks[0]);
+	put_group_info(gi);
+
+	return gids;
+}
+
+/* Check if the passed gid is available in supplied credential. */
+int
+groupmember(gid_t gid, const cred_t *cr)
+{
+	struct group_info *gi;
+	int rc;
+
+	gi = get_group_info(cr->group_info);
+	rc = cr_groups_search(gi, SGID_TO_KGID(gid));
+	put_group_info(gi);
+
+	return rc;
+}
+
+/* Return the effective user id */
+uid_t
+crgetuid(const cred_t *cr)
+{
+	return KUID_TO_SUID(cr->euid);
+}
+
+/* Return the real user id */
+uid_t
+crgetruid(const cred_t *cr)
+{
+	return KUID_TO_SUID(cr->uid);
+}
+
+/* Return the saved user id */
+uid_t
+crgetsuid(const cred_t *cr)
+{
+	return KUID_TO_SUID(cr->suid);
+}
+
+/* Return the filesystem user id */
+uid_t
+crgetfsuid(const cred_t *cr)
+{
+	return KUID_TO_SUID(cr->fsuid);
+}
+
+/* Return the effective group id */
+gid_t
+crgetgid(const cred_t *cr)
+{
+	return KGID_TO_SGID(cr->egid);
+}
+
+/* Return the real group id */
+gid_t
+crgetrgid(const cred_t *cr)
+{
+	return KGID_TO_SGID(cr->gid);
+}
+
+/* Return the saved group id */
+gid_t
+crgetsgid(const cred_t *cr)
+{
+	return KGID_TO_SGID(cr->sgid);
+}
+
+/* Return the filesystem group id */
+gid_t
+crgetfsgid(const cred_t *cr)
+{
+	return KGID_TO_SGID(cr->fsgid);
+}
+
+EXPORT_SYMBOL(crhold);
+EXPORT_SYMBOL(crfree);
+EXPORT_SYMBOL(crgetuid);
+EXPORT_SYMBOL(crgetruid);
+EXPORT_SYMBOL(crgetsuid);
+EXPORT_SYMBOL(crgetfsuid);
+EXPORT_SYMBOL(crgetgid);
+EXPORT_SYMBOL(crgetrgid);
+EXPORT_SYMBOL(crgetsgid);
+EXPORT_SYMBOL(crgetfsgid);
+EXPORT_SYMBOL(crgetngroups);
+EXPORT_SYMBOL(crgetgroups);
+EXPORT_SYMBOL(groupmember);
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/module/spl/spl-err.c
@@ -0,0 +1,117 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+ *****************************************************************************
+ *  Solaris Porting Layer (SPL) Error Implementation.
+\*****************************************************************************/
+
+#include <sys/sysmacros.h>
+#include <sys/cmn_err.h>
+#include <linux/ratelimit.h>
+
+/*
+ * Limit the number of stack traces dumped to not more than 5 every
+ * 60 seconds to prevent denial-of-service attacks from debug code.
+ */
+DEFINE_RATELIMIT_STATE(dumpstack_ratelimit_state, 60 * HZ, 5);
+
+void
+spl_dumpstack(void)
+{
+	if (__ratelimit(&dumpstack_ratelimit_state)) {
+		printk("Showing stack for process %d\n", current->pid);
+		dump_stack();
+	}
+}
+EXPORT_SYMBOL(spl_dumpstack);
+
+int
+spl_panic(const char *file, const char *func, int line, const char *fmt, ...) {
+	const char *newfile;
+	char msg[MAXMSGLEN];
+	va_list ap;
+
+	newfile = strrchr(file, '/');
+	if (newfile != NULL)
+		newfile = newfile + 1;
+	else
+		newfile = file;
+
+	va_start(ap, fmt);
+	(void) vsnprintf(msg, sizeof (msg), fmt, ap);
+	va_end(ap);
+
+	printk(KERN_EMERG "%s", msg);
+	printk(KERN_EMERG "PANIC at %s:%d:%s()\n", newfile, line, func);
+	spl_dumpstack();
+
+	/* Halt the thread to facilitate further debugging */
+	set_task_state(current, TASK_UNINTERRUPTIBLE);
+	while (1)
+		schedule();
+
+	/* Unreachable */
+	return (1);
+}
+EXPORT_SYMBOL(spl_panic);
+
+void
+vcmn_err(int ce, const char *fmt, va_list ap)
+{
+	char msg[MAXMSGLEN];
+
+	vsnprintf(msg, MAXMSGLEN - 1, fmt, ap);
+
+	switch (ce) {
+	case CE_IGNORE:
+		break;
+	case CE_CONT:
+		printk("%s", msg);
+		break;
+	case CE_NOTE:
+		printk(KERN_NOTICE "NOTICE: %s\n", msg);
+		break;
+	case CE_WARN:
+		printk(KERN_WARNING "WARNING: %s\n", msg);
+		break;
+	case CE_PANIC:
+		printk(KERN_EMERG "PANIC: %s\n", msg);
+		spl_dumpstack();
+
+		/* Halt the thread to facilitate further debugging */
+		set_task_state(current, TASK_UNINTERRUPTIBLE);
+		while (1)
+			schedule();
+	}
+} /* vcmn_err() */
+EXPORT_SYMBOL(vcmn_err);
+
+void
+cmn_err(int ce, const char *fmt, ...)
+{
+	va_list ap;
+
+	va_start(ap, fmt);
+	vcmn_err(ce, fmt, ap);
+	va_end(ap);
+} /* cmn_err() */
+EXPORT_SYMBOL(cmn_err);
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/module/spl/spl-generic.c
@@ -0,0 +1,607 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+ *****************************************************************************
+ *  Solaris Porting Layer (SPL) Generic Implementation.
+\*****************************************************************************/
+
+#include <sys/sysmacros.h>
+#include <sys/systeminfo.h>
+#include <sys/vmsystm.h>
+#include <sys/kobj.h>
+#include <sys/kmem.h>
+#include <sys/kmem_cache.h>
+#include <sys/vmem.h>
+#include <sys/mutex.h>
+#include <sys/rwlock.h>
+#include <sys/taskq.h>
+#include <sys/tsd.h>
+#include <sys/zmod.h>
+#include <sys/debug.h>
+#include <sys/proc.h>
+#include <sys/kstat.h>
+#include <sys/file.h>
+#include <linux/ctype.h>
+#include <linux/kmod.h>
+#include <linux/math64_compat.h>
+#include <linux/proc_compat.h>
+
+char spl_version[32] = "SPL v" SPL_META_VERSION "-" SPL_META_RELEASE;
+EXPORT_SYMBOL(spl_version);
+
+unsigned long spl_hostid = 0;
+EXPORT_SYMBOL(spl_hostid);
+module_param(spl_hostid, ulong, 0644);
+MODULE_PARM_DESC(spl_hostid, "The system hostid.");
+
+proc_t p0 = { 0 };
+EXPORT_SYMBOL(p0);
+
+#if BITS_PER_LONG == 32
+/*
+ * Support 64/64 => 64 division on a 32-bit platform.  While the kernel
+ * provides a div64_u64() function for this we do not use it because the
+ * implementation is flawed.  There are cases which return incorrect
+ * results as late as linux-2.6.35.  Until this is fixed upstream the
+ * spl must provide its own implementation.
+ *
+ * This implementation is a slightly modified version of the algorithm
+ * proposed by the book 'Hacker's Delight'.  The original source can be
+ * found here and is available for use without restriction.
+ *
+ * http://www.hackersdelight.org/HDcode/newCode/divDouble.c
+ */
+
+/*
+ * Calculate number of leading of zeros for a 64-bit value.
+ */
+static int
+nlz64(uint64_t x) {
+	register int n = 0;
+
+	if (x == 0)
+		return 64;
+
+	if (x <= 0x00000000FFFFFFFFULL) {n = n + 32; x = x << 32;}
+	if (x <= 0x0000FFFFFFFFFFFFULL) {n = n + 16; x = x << 16;}
+	if (x <= 0x00FFFFFFFFFFFFFFULL) {n = n +  8; x = x <<  8;}
+	if (x <= 0x0FFFFFFFFFFFFFFFULL) {n = n +  4; x = x <<  4;}
+	if (x <= 0x3FFFFFFFFFFFFFFFULL) {n = n +  2; x = x <<  2;}
+	if (x <= 0x7FFFFFFFFFFFFFFFULL) {n = n +  1;}
+
+	return n;
+}
+
+/*
+ * Newer kernels have a div_u64() function but we define our own
+ * to simplify portibility between kernel versions.
+ */
+static inline uint64_t
+__div_u64(uint64_t u, uint32_t v)
+{
+	(void) do_div(u, v);
+	return u;
+}
+
+/*
+ * Implementation of 64-bit unsigned division for 32-bit machines.
+ *
+ * First the procedure takes care of the case in which the divisor is a
+ * 32-bit quantity. There are two subcases: (1) If the left half of the
+ * dividend is less than the divisor, one execution of do_div() is all that
+ * is required (overflow is not possible). (2) Otherwise it does two
+ * divisions, using the grade school method.
+ */
+uint64_t
+__udivdi3(uint64_t u, uint64_t v)
+{
+	uint64_t u0, u1, v1, q0, q1, k;
+	int n;
+
+	if (v >> 32 == 0) {			// If v < 2**32:
+		if (u >> 32 < v) {		// If u/v cannot overflow,
+			return __div_u64(u, v);	// just do one division.
+		} else {			// If u/v would overflow:
+			u1 = u >> 32;		// Break u into two halves.
+			u0 = u & 0xFFFFFFFF;
+			q1 = __div_u64(u1, v);	// First quotient digit.
+			k  = u1 - q1 * v;	// First remainder, < v.
+			u0 += (k << 32);
+			q0 = __div_u64(u0, v);	// Seconds quotient digit.
+			return (q1 << 32) + q0;
+		}
+	} else {				// If v >= 2**32:
+		n = nlz64(v);			// 0 <= n <= 31.
+		v1 = (v << n) >> 32;		// Normalize divisor, MSB is 1.
+		u1 = u >> 1;			// To ensure no overflow.
+		q1 = __div_u64(u1, v1);		// Get quotient from
+		q0 = (q1 << n) >> 31;		// Undo normalization and
+						// division of u by 2.
+		if (q0 != 0)			// Make q0 correct or
+			q0 = q0 - 1;		// too small by 1.
+		if ((u - q0 * v) >= v)
+			q0 = q0 + 1;		// Now q0 is correct.
+
+		return q0;
+	}
+}
+EXPORT_SYMBOL(__udivdi3);
+
+/*
+ * Implementation of 64-bit signed division for 32-bit machines.
+ */
+int64_t
+__divdi3(int64_t u, int64_t v)
+{
+	int64_t q, t;
+	q = __udivdi3(abs64(u), abs64(v));
+	t = (u ^ v) >> 63;	// If u, v have different
+	return (q ^ t) - t;	// signs, negate q.
+}
+EXPORT_SYMBOL(__divdi3);
+
+/*
+ * Implementation of 64-bit unsigned modulo for 32-bit machines.
+ */
+uint64_t
+__umoddi3(uint64_t dividend, uint64_t divisor)
+{
+	return (dividend - (divisor * __udivdi3(dividend, divisor)));
+}
+EXPORT_SYMBOL(__umoddi3);
+
+#if defined(__arm) || defined(__arm__)
+/*
+ * Implementation of 64-bit (un)signed division for 32-bit arm machines.
+ *
+ * Run-time ABI for the ARM Architecture (page 20).  A pair of (unsigned)
+ * long longs is returned in {{r0, r1}, {r2,r3}}, the quotient in {r0, r1},
+ * and the remainder in {r2, r3}.  The return type is specifically left
+ * set to 'void' to ensure the compiler does not overwrite these registers
+ * during the return.  All results are in registers as per ABI
+ */
+void
+__aeabi_uldivmod(uint64_t u, uint64_t v)
+{
+	uint64_t res;
+	uint64_t mod;
+
+	res = __udivdi3(u, v);
+	mod = __umoddi3(u, v);
+	{
+		register uint32_t r0 asm("r0") = (res & 0xFFFFFFFF);
+		register uint32_t r1 asm("r1") = (res >> 32);
+		register uint32_t r2 asm("r2") = (mod & 0xFFFFFFFF);
+		register uint32_t r3 asm("r3") = (mod >> 32);
+
+		asm volatile(""
+		    : "+r"(r0), "+r"(r1), "+r"(r2),"+r"(r3)  /* output */
+		    : "r"(r0), "r"(r1), "r"(r2), "r"(r3));   /* input */
+
+		return; /* r0; */
+	}
+}
+EXPORT_SYMBOL(__aeabi_uldivmod);
+
+void
+__aeabi_ldivmod(int64_t u, int64_t v)
+{
+	int64_t res;
+	uint64_t mod;
+
+	res =  __divdi3(u, v);
+	mod = __umoddi3(u, v);
+	{
+		register uint32_t r0 asm("r0") = (res & 0xFFFFFFFF);
+		register uint32_t r1 asm("r1") = (res >> 32);
+		register uint32_t r2 asm("r2") = (mod & 0xFFFFFFFF);
+		register uint32_t r3 asm("r3") = (mod >> 32);
+
+		asm volatile(""
+		    : "+r"(r0), "+r"(r1), "+r"(r2),"+r"(r3)  /* output */
+		    : "r"(r0), "r"(r1), "r"(r2), "r"(r3));   /* input */
+
+		return; /* r0; */
+	}
+}
+EXPORT_SYMBOL(__aeabi_ldivmod);
+#endif /* __arm || __arm__ */
+#endif /* BITS_PER_LONG */
+
+/* NOTE: The strtoxx behavior is solely based on my reading of the Solaris
+ * ddi_strtol(9F) man page.  I have not verified the behavior of these
+ * functions against their Solaris counterparts.  It is possible that I
+ * may have misinterpreted the man page or the man page is incorrect.
+ */
+int ddi_strtoul(const char *, char **, int, unsigned long *);
+int ddi_strtol(const char *, char **, int, long *);
+int ddi_strtoull(const char *, char **, int, unsigned long long *);
+int ddi_strtoll(const char *, char **, int, long long *);
+
+#define define_ddi_strtoux(type, valtype)				\
+int ddi_strtou##type(const char *str, char **endptr,			\
+		     int base, valtype *result)				\
+{									\
+	valtype last_value, value = 0;					\
+	char *ptr = (char *)str;					\
+	int flag = 1, digit;						\
+									\
+	if (strlen(ptr) == 0)						\
+		return EINVAL;						\
+									\
+	/* Auto-detect base based on prefix */				\
+	if (!base) {							\
+		if (str[0] == '0') {					\
+			if (tolower(str[1])=='x' && isxdigit(str[2])) {	\
+				base = 16; /* hex */			\
+				ptr += 2;				\
+			} else if (str[1] >= '0' && str[1] < 8) {	\
+				base = 8; /* octal */			\
+				ptr += 1;				\
+			} else {					\
+				return EINVAL;				\
+			}						\
+		} else {						\
+			base = 10; /* decimal */			\
+		}							\
+	}								\
+									\
+	while (1) {							\
+		if (isdigit(*ptr))					\
+			digit = *ptr - '0';				\
+		else if (isalpha(*ptr))					\
+			digit = tolower(*ptr) - 'a' + 10;		\
+		else							\
+			break;						\
+									\
+		if (digit >= base)					\
+			break;						\
+									\
+		last_value = value;					\
+		value = value * base + digit;				\
+		if (last_value > value) /* Overflow */			\
+			return ERANGE;					\
+									\
+		flag = 1;						\
+		ptr++;							\
+	}								\
+									\
+	if (flag)							\
+		*result = value;					\
+									\
+	if (endptr)							\
+		*endptr = (char *)(flag ? ptr : str);			\
+									\
+	return 0;							\
+}									\
+
+#define define_ddi_strtox(type, valtype)				\
+int ddi_strto##type(const char *str, char **endptr,			\
+		       int base, valtype *result)			\
+{									\
+	int rc;								\
+									\
+	if (*str == '-') {						\
+		rc = ddi_strtou##type(str + 1, endptr, base, result);	\
+		if (!rc) {						\
+			if (*endptr == str + 1)				\
+				*endptr = (char *)str;			\
+			else						\
+				*result = -*result;			\
+		}							\
+	} else {							\
+		rc = ddi_strtou##type(str, endptr, base, result);	\
+	}								\
+									\
+	return rc;							\
+}
+
+define_ddi_strtoux(l, unsigned long)
+define_ddi_strtox(l, long)
+define_ddi_strtoux(ll, unsigned long long)
+define_ddi_strtox(ll, long long)
+
+EXPORT_SYMBOL(ddi_strtoul);
+EXPORT_SYMBOL(ddi_strtol);
+EXPORT_SYMBOL(ddi_strtoll);
+EXPORT_SYMBOL(ddi_strtoull);
+
+int
+ddi_copyin(const void *from, void *to, size_t len, int flags)
+{
+	/* Fake ioctl() issued by kernel, 'from' is a kernel address */
+	if (flags & FKIOCTL) {
+		memcpy(to, from, len);
+		return 0;
+	}
+
+	return copyin(from, to, len);
+}
+EXPORT_SYMBOL(ddi_copyin);
+
+int
+ddi_copyout(const void *from, void *to, size_t len, int flags)
+{
+	/* Fake ioctl() issued by kernel, 'from' is a kernel address */
+	if (flags & FKIOCTL) {
+		memcpy(to, from, len);
+		return 0;
+	}
+
+	return copyout(from, to, len);
+}
+EXPORT_SYMBOL(ddi_copyout);
+
+#ifndef HAVE_PUT_TASK_STRUCT
+/*
+ * This is only a stub function which should never be used.  The SPL should
+ * never be putting away the last reference on a task structure so this will
+ * not be called.  However, we still need to define it so the module does not
+ * have undefined symbol at load time.  That all said if this impossible
+ * thing does somehow happen PANIC immediately so we know about it.
+ */
+void
+__put_task_struct(struct task_struct *t)
+{
+	PANIC("Unexpectly put last reference on task %d\n", (int)t->pid);
+}
+EXPORT_SYMBOL(__put_task_struct);
+#endif /* HAVE_PUT_TASK_STRUCT */
+
+/*
+ * Read the unique system identifier from the /etc/hostid file.
+ *
+ * The behavior of /usr/bin/hostid on Linux systems with the
+ * regular eglibc and coreutils is:
+ *
+ *   1. Generate the value if the /etc/hostid file does not exist
+ *      or if the /etc/hostid file is less than four bytes in size.
+ *
+ *   2. If the /etc/hostid file is at least 4 bytes, then return
+ *      the first four bytes [0..3] in native endian order.
+ *
+ *   3. Always ignore bytes [4..] if they exist in the file.
+ *
+ * Only the first four bytes are significant, even on systems that
+ * have a 64-bit word size.
+ *
+ * See:
+ *
+ *   eglibc: sysdeps/unix/sysv/linux/gethostid.c
+ *   coreutils: src/hostid.c
+ *
+ * Notes:
+ *
+ * The /etc/hostid file on Solaris is a text file that often reads:
+ *
+ *   # DO NOT EDIT
+ *   "0123456789"
+ *
+ * Directly copying this file to Linux results in a constant
+ * hostid of 4f442023 because the default comment constitutes
+ * the first four bytes of the file.
+ *
+ */
+
+char *spl_hostid_path = HW_HOSTID_PATH;
+module_param(spl_hostid_path, charp, 0444);
+MODULE_PARM_DESC(spl_hostid_path, "The system hostid file (/etc/hostid)");
+
+static int
+hostid_read(void)
+{
+	int result;
+	uint64_t size;
+	struct _buf *file;
+	uint32_t hostid = 0;
+
+	file = kobj_open_file(spl_hostid_path);
+
+	if (file == (struct _buf *)-1) {
+		printk(KERN_WARNING
+		       "SPL: The %s file is not found.\n",
+		       spl_hostid_path);
+		return -1;
+	}
+
+	result = kobj_get_filesize(file, &size);
+
+	if (result != 0) {
+		printk(KERN_WARNING
+		       "SPL: kobj_get_filesize returned %i on %s\n",
+		       result, spl_hostid_path);
+		kobj_close_file(file);
+		return -2;
+	}
+
+	if (size < sizeof(HW_HOSTID_MASK)) {
+		printk(KERN_WARNING
+		       "SPL: Ignoring the %s file because it is %llu bytes; "
+		       "expecting %lu bytes instead.\n", spl_hostid_path,
+		       size, (unsigned long)sizeof(HW_HOSTID_MASK));
+		kobj_close_file(file);
+		return -3;
+	}
+
+	/* Read directly into the variable like eglibc does. */
+	/* Short reads are okay; native behavior is preserved. */
+	result = kobj_read_file(file, (char *)&hostid, sizeof(hostid), 0);
+
+	if (result < 0) {
+		printk(KERN_WARNING
+		       "SPL: kobj_read_file returned %i on %s\n",
+		       result, spl_hostid_path);
+		kobj_close_file(file);
+		return -4;
+	}
+
+	/* Mask down to 32 bits like coreutils does. */
+	spl_hostid = hostid & HW_HOSTID_MASK;
+	kobj_close_file(file);
+	return 0;
+}
+
+uint32_t
+zone_get_hostid(void *zone)
+{
+	static int first = 1;
+
+	/* Only the global zone is supported */
+	ASSERT(zone == NULL);
+
+	if (first) {
+		first = 0;
+
+		spl_hostid &= HW_HOSTID_MASK;
+		/*
+		 * Get the hostid if it was not passed as a module parameter.
+		 * Try reading the /etc/hostid file directly.
+		 */
+		if (spl_hostid == 0 && hostid_read())
+			spl_hostid = 0;
+
+
+		printk(KERN_NOTICE "SPL: using hostid 0x%08x\n",
+			(unsigned int) spl_hostid);
+	}
+
+	return spl_hostid;
+}
+EXPORT_SYMBOL(zone_get_hostid);
+
+static int
+spl_kvmem_init(void)
+{
+	int rc = 0;
+
+	rc = spl_kmem_init();
+	if (rc)
+		goto out1;
+
+	rc = spl_vmem_init();
+	if (rc)
+		goto out2;
+
+	rc = spl_kmem_cache_init();
+	if (rc)
+		goto out3;
+
+	return (rc);
+out3:
+	spl_vmem_fini();
+out2:
+	spl_kmem_fini();
+out1:
+	return (rc);
+}
+
+static void
+spl_kvmem_fini(void)
+{
+	spl_kmem_cache_fini();
+	spl_vmem_fini();
+	spl_kmem_fini();
+}
+
+static int __init
+spl_init(void)
+{
+	int rc = 0;
+
+	if ((rc = spl_kvmem_init()))
+		goto out1;
+
+	if ((rc = spl_mutex_init()))
+		goto out2;
+
+	if ((rc = spl_rw_init()))
+		goto out3;
+
+	if ((rc = spl_taskq_init()))
+		goto out4;
+
+	if ((rc = spl_vn_init()))
+		goto out5;
+
+	if ((rc = spl_proc_init()))
+		goto out6;
+
+	if ((rc = spl_kstat_init()))
+		goto out7;
+
+	if ((rc = spl_tsd_init()))
+		goto out8;
+
+	if ((rc = spl_zlib_init()))
+		goto out9;
+
+	printk(KERN_NOTICE "SPL: Loaded module v%s-%s%s\n", SPL_META_VERSION,
+	       SPL_META_RELEASE, SPL_DEBUG_STR);
+	return (rc);
+
+out9:
+	spl_tsd_fini();
+out8:
+	spl_kstat_fini();
+out7:
+	spl_proc_fini();
+out6:
+	spl_vn_fini();
+out5:
+	spl_taskq_fini();
+out4:
+	spl_rw_fini();
+out3:
+	spl_mutex_fini();
+out2:
+	spl_kvmem_fini();
+out1:
+	printk(KERN_NOTICE "SPL: Failed to Load Solaris Porting Layer "
+	       "v%s-%s%s, rc = %d\n", SPL_META_VERSION, SPL_META_RELEASE,
+	       SPL_DEBUG_STR, rc);
+
+	return (rc);
+}
+
+static void __exit
+spl_fini(void)
+{
+	printk(KERN_NOTICE "SPL: Unloaded module v%s-%s%s\n",
+	       SPL_META_VERSION, SPL_META_RELEASE, SPL_DEBUG_STR);
+	spl_zlib_fini();
+	spl_tsd_fini();
+	spl_kstat_fini();
+	spl_proc_fini();
+	spl_vn_fini();
+	spl_taskq_fini();
+	spl_rw_fini();
+	spl_mutex_fini();
+	spl_kvmem_fini();
+}
+
+module_init(spl_init);
+module_exit(spl_fini);
+
+MODULE_DESCRIPTION("Solaris Porting Layer");
+MODULE_AUTHOR(SPL_META_AUTHOR);
+MODULE_LICENSE(SPL_META_LICENSE);
+MODULE_VERSION(SPL_META_VERSION "-" SPL_META_RELEASE);
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/module/spl/spl-kmem-cache.c
@@ -0,0 +1,1734 @@
+/*
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <sys/kmem.h>
+#include <sys/kmem_cache.h>
+#include <sys/taskq.h>
+#include <sys/timer.h>
+#include <sys/vmem.h>
+#include <linux/slab.h>
+#include <linux/swap.h>
+#include <linux/mm_compat.h>
+#include <linux/wait_compat.h>
+#include <linux/prefetch.h>
+
+/*
+ * Within the scope of spl-kmem.c file the kmem_cache_* definitions
+ * are removed to allow access to the real Linux slab allocator.
+ */
+#undef kmem_cache_destroy
+#undef kmem_cache_create
+#undef kmem_cache_alloc
+#undef kmem_cache_free
+
+
+/*
+ * Linux 3.16 replaced smp_mb__{before,after}_{atomic,clear}_{dec,inc,bit}()
+ * with smp_mb__{before,after}_atomic() because they were redundant. This is
+ * only used inside our SLAB allocator, so we implement an internal wrapper
+ * here to give us smp_mb__{before,after}_atomic() on older kernels.
+ */
+#ifndef smp_mb__before_atomic
+#define	smp_mb__before_atomic(x) smp_mb__before_clear_bit(x)
+#endif
+
+#ifndef smp_mb__after_atomic
+#define	smp_mb__after_atomic(x) smp_mb__after_clear_bit(x)
+#endif
+
+/*
+ * Cache expiration was implemented because it was part of the default Solaris
+ * kmem_cache behavior.  The idea is that per-cpu objects which haven't been
+ * accessed in several seconds should be returned to the cache.  On the other
+ * hand Linux slabs never move objects back to the slabs unless there is
+ * memory pressure on the system.  By default the Linux method is enabled
+ * because it has been shown to improve responsiveness on low memory systems.
+ * This policy may be changed by setting KMC_EXPIRE_AGE or KMC_EXPIRE_MEM.
+ */
+unsigned int spl_kmem_cache_expire = KMC_EXPIRE_MEM;
+EXPORT_SYMBOL(spl_kmem_cache_expire);
+module_param(spl_kmem_cache_expire, uint, 0644);
+MODULE_PARM_DESC(spl_kmem_cache_expire, "By age (0x1) or low memory (0x2)");
+
+/*
+ * Cache magazines are an optimization designed to minimize the cost of
+ * allocating memory.  They do this by keeping a per-cpu cache of recently
+ * freed objects, which can then be reallocated without taking a lock. This
+ * can improve performance on highly contended caches.  However, because
+ * objects in magazines will prevent otherwise empty slabs from being
+ * immediately released this may not be ideal for low memory machines.
+ *
+ * For this reason spl_kmem_cache_magazine_size can be used to set a maximum
+ * magazine size.  When this value is set to 0 the magazine size will be
+ * automatically determined based on the object size.  Otherwise magazines
+ * will be limited to 2-256 objects per magazine (i.e per cpu).  Magazines
+ * may never be entirely disabled in this implementation.
+ */
+unsigned int spl_kmem_cache_magazine_size = 0;
+module_param(spl_kmem_cache_magazine_size, uint, 0444);
+MODULE_PARM_DESC(spl_kmem_cache_magazine_size,
+	"Default magazine size (2-256), set automatically (0)\n");
+
+/*
+ * The default behavior is to report the number of objects remaining in the
+ * cache.  This allows the Linux VM to repeatedly reclaim objects from the
+ * cache when memory is low satisfy other memory allocations.  Alternately,
+ * setting this value to KMC_RECLAIM_ONCE limits how aggressively the cache
+ * is reclaimed.  This may increase the likelihood of out of memory events.
+ */
+unsigned int spl_kmem_cache_reclaim = 0 /* KMC_RECLAIM_ONCE */;
+module_param(spl_kmem_cache_reclaim, uint, 0644);
+MODULE_PARM_DESC(spl_kmem_cache_reclaim, "Single reclaim pass (0x1)");
+
+unsigned int spl_kmem_cache_obj_per_slab = SPL_KMEM_CACHE_OBJ_PER_SLAB;
+module_param(spl_kmem_cache_obj_per_slab, uint, 0644);
+MODULE_PARM_DESC(spl_kmem_cache_obj_per_slab, "Number of objects per slab");
+
+unsigned int spl_kmem_cache_obj_per_slab_min = SPL_KMEM_CACHE_OBJ_PER_SLAB_MIN;
+module_param(spl_kmem_cache_obj_per_slab_min, uint, 0644);
+MODULE_PARM_DESC(spl_kmem_cache_obj_per_slab_min,
+	"Minimal number of objects per slab");
+
+unsigned int spl_kmem_cache_max_size = SPL_KMEM_CACHE_MAX_SIZE;
+module_param(spl_kmem_cache_max_size, uint, 0644);
+MODULE_PARM_DESC(spl_kmem_cache_max_size, "Maximum size of slab in MB");
+
+/*
+ * For small objects the Linux slab allocator should be used to make the most
+ * efficient use of the memory.  However, large objects are not supported by
+ * the Linux slab and therefore the SPL implementation is preferred.  A cutoff
+ * of 16K was determined to be optimal for architectures using 4K pages.
+ */
+#if PAGE_SIZE == 4096
+unsigned int spl_kmem_cache_slab_limit = 16384;
+#else
+unsigned int spl_kmem_cache_slab_limit = 0;
+#endif
+module_param(spl_kmem_cache_slab_limit, uint, 0644);
+MODULE_PARM_DESC(spl_kmem_cache_slab_limit,
+	"Objects less than N bytes use the Linux slab");
+
+/*
+ * This value defaults to a threshold designed to avoid allocations which
+ * have been deemed costly by the kernel.
+ */
+unsigned int spl_kmem_cache_kmem_limit =
+    ((1 << (PAGE_ALLOC_COSTLY_ORDER - 1)) * PAGE_SIZE) /
+    SPL_KMEM_CACHE_OBJ_PER_SLAB;
+module_param(spl_kmem_cache_kmem_limit, uint, 0644);
+MODULE_PARM_DESC(spl_kmem_cache_kmem_limit,
+	"Objects less than N bytes use the kmalloc");
+
+/*
+ * The number of threads available to allocate new slabs for caches.  This
+ * should not need to be tuned but it is available for performance analysis.
+ */
+unsigned int spl_kmem_cache_kmem_threads = 4;
+module_param(spl_kmem_cache_kmem_threads, uint, 0444);
+MODULE_PARM_DESC(spl_kmem_cache_kmem_threads,
+	"Number of spl_kmem_cache threads");
+
+/*
+ * Slab allocation interfaces
+ *
+ * While the Linux slab implementation was inspired by the Solaris
+ * implementation I cannot use it to emulate the Solaris APIs.  I
+ * require two features which are not provided by the Linux slab.
+ *
+ * 1) Constructors AND destructors.  Recent versions of the Linux
+ *    kernel have removed support for destructors.  This is a deal
+ *    breaker for the SPL which contains particularly expensive
+ *    initializers for mutex's, condition variables, etc.  We also
+ *    require a minimal level of cleanup for these data types unlike
+ *    many Linux data types which do need to be explicitly destroyed.
+ *
+ * 2) Virtual address space backed slab.  Callers of the Solaris slab
+ *    expect it to work well for both small are very large allocations.
+ *    Because of memory fragmentation the Linux slab which is backed
+ *    by kmalloc'ed memory performs very badly when confronted with
+ *    large numbers of large allocations.  Basing the slab on the
+ *    virtual address space removes the need for contiguous pages
+ *    and greatly improve performance for large allocations.
+ *
+ * For these reasons, the SPL has its own slab implementation with
+ * the needed features.  It is not as highly optimized as either the
+ * Solaris or Linux slabs, but it should get me most of what is
+ * needed until it can be optimized or obsoleted by another approach.
+ *
+ * One serious concern I do have about this method is the relatively
+ * small virtual address space on 32bit arches.  This will seriously
+ * constrain the size of the slab caches and their performance.
+ */
+
+struct list_head spl_kmem_cache_list;   /* List of caches */
+struct rw_semaphore spl_kmem_cache_sem; /* Cache list lock */
+taskq_t *spl_kmem_cache_taskq;		/* Task queue for ageing / reclaim */
+
+static void spl_cache_shrink(spl_kmem_cache_t *skc, void *obj);
+
+SPL_SHRINKER_CALLBACK_FWD_DECLARE(spl_kmem_cache_generic_shrinker);
+SPL_SHRINKER_DECLARE(spl_kmem_cache_shrinker,
+	spl_kmem_cache_generic_shrinker, KMC_DEFAULT_SEEKS);
+
+static void *
+kv_alloc(spl_kmem_cache_t *skc, int size, int flags)
+{
+	gfp_t lflags = kmem_flags_convert(flags);
+	void *ptr;
+
+	if (skc->skc_flags & KMC_KMEM) {
+		ASSERT(ISP2(size));
+		ptr = (void *)__get_free_pages(lflags, get_order(size));
+	} else {
+		ptr = __vmalloc(size, lflags | __GFP_HIGHMEM, PAGE_KERNEL);
+	}
+
+	/* Resulting allocated memory will be page aligned */
+	ASSERT(IS_P2ALIGNED(ptr, PAGE_SIZE));
+
+	return (ptr);
+}
+
+static void
+kv_free(spl_kmem_cache_t *skc, void *ptr, int size)
+{
+	ASSERT(IS_P2ALIGNED(ptr, PAGE_SIZE));
+
+	/*
+	 * The Linux direct reclaim path uses this out of band value to
+	 * determine if forward progress is being made.  Normally this is
+	 * incremented by kmem_freepages() which is part of the various
+	 * Linux slab implementations.  However, since we are using none
+	 * of that infrastructure we are responsible for incrementing it.
+	 */
+	if (current->reclaim_state)
+		current->reclaim_state->reclaimed_slab += size >> PAGE_SHIFT;
+
+	if (skc->skc_flags & KMC_KMEM) {
+		ASSERT(ISP2(size));
+		free_pages((unsigned long)ptr, get_order(size));
+	} else {
+		vfree(ptr);
+	}
+}
+
+/*
+ * Required space for each aligned sks.
+ */
+static inline uint32_t
+spl_sks_size(spl_kmem_cache_t *skc)
+{
+	return (P2ROUNDUP_TYPED(sizeof (spl_kmem_slab_t),
+	    skc->skc_obj_align, uint32_t));
+}
+
+/*
+ * Required space for each aligned object.
+ */
+static inline uint32_t
+spl_obj_size(spl_kmem_cache_t *skc)
+{
+	uint32_t align = skc->skc_obj_align;
+
+	return (P2ROUNDUP_TYPED(skc->skc_obj_size, align, uint32_t) +
+	    P2ROUNDUP_TYPED(sizeof (spl_kmem_obj_t), align, uint32_t));
+}
+
+/*
+ * Lookup the spl_kmem_object_t for an object given that object.
+ */
+static inline spl_kmem_obj_t *
+spl_sko_from_obj(spl_kmem_cache_t *skc, void *obj)
+{
+	return (obj + P2ROUNDUP_TYPED(skc->skc_obj_size,
+	    skc->skc_obj_align, uint32_t));
+}
+
+/*
+ * Required space for each offslab object taking in to account alignment
+ * restrictions and the power-of-two requirement of kv_alloc().
+ */
+static inline uint32_t
+spl_offslab_size(spl_kmem_cache_t *skc)
+{
+	return (1UL << (fls64(spl_obj_size(skc)) + 1));
+}
+
+/*
+ * It's important that we pack the spl_kmem_obj_t structure and the
+ * actual objects in to one large address space to minimize the number
+ * of calls to the allocator.  It is far better to do a few large
+ * allocations and then subdivide it ourselves.  Now which allocator
+ * we use requires balancing a few trade offs.
+ *
+ * For small objects we use kmem_alloc() because as long as you are
+ * only requesting a small number of pages (ideally just one) its cheap.
+ * However, when you start requesting multiple pages with kmem_alloc()
+ * it gets increasingly expensive since it requires contiguous pages.
+ * For this reason we shift to vmem_alloc() for slabs of large objects
+ * which removes the need for contiguous pages.  We do not use
+ * vmem_alloc() in all cases because there is significant locking
+ * overhead in __get_vm_area_node().  This function takes a single
+ * global lock when acquiring an available virtual address range which
+ * serializes all vmem_alloc()'s for all slab caches.  Using slightly
+ * different allocation functions for small and large objects should
+ * give us the best of both worlds.
+ *
+ * KMC_ONSLAB                       KMC_OFFSLAB
+ *
+ * +------------------------+       +-----------------+
+ * | spl_kmem_slab_t --+-+  |       | spl_kmem_slab_t |---+-+
+ * | skc_obj_size    <-+ |  |       +-----------------+   | |
+ * | spl_kmem_obj_t      |  |                             | |
+ * | skc_obj_size    <---+  |       +-----------------+   | |
+ * | spl_kmem_obj_t      |  |       | skc_obj_size    | <-+ |
+ * | ...                 v  |       | spl_kmem_obj_t  |     |
+ * +------------------------+       +-----------------+     v
+ */
+static spl_kmem_slab_t *
+spl_slab_alloc(spl_kmem_cache_t *skc, int flags)
+{
+	spl_kmem_slab_t *sks;
+	spl_kmem_obj_t *sko, *n;
+	void *base, *obj;
+	uint32_t obj_size, offslab_size = 0;
+	int i,  rc = 0;
+
+	base = kv_alloc(skc, skc->skc_slab_size, flags);
+	if (base == NULL)
+		return (NULL);
+
+	sks = (spl_kmem_slab_t *)base;
+	sks->sks_magic = SKS_MAGIC;
+	sks->sks_objs = skc->skc_slab_objs;
+	sks->sks_age = jiffies;
+	sks->sks_cache = skc;
+	INIT_LIST_HEAD(&sks->sks_list);
+	INIT_LIST_HEAD(&sks->sks_free_list);
+	sks->sks_ref = 0;
+	obj_size = spl_obj_size(skc);
+
+	if (skc->skc_flags & KMC_OFFSLAB)
+		offslab_size = spl_offslab_size(skc);
+
+	for (i = 0; i < sks->sks_objs; i++) {
+		if (skc->skc_flags & KMC_OFFSLAB) {
+			obj = kv_alloc(skc, offslab_size, flags);
+			if (!obj) {
+				rc = -ENOMEM;
+				goto out;
+			}
+		} else {
+			obj = base + spl_sks_size(skc) + (i * obj_size);
+		}
+
+		ASSERT(IS_P2ALIGNED(obj, skc->skc_obj_align));
+		sko = spl_sko_from_obj(skc, obj);
+		sko->sko_addr = obj;
+		sko->sko_magic = SKO_MAGIC;
+		sko->sko_slab = sks;
+		INIT_LIST_HEAD(&sko->sko_list);
+		list_add_tail(&sko->sko_list, &sks->sks_free_list);
+	}
+
+out:
+	if (rc) {
+		if (skc->skc_flags & KMC_OFFSLAB)
+			list_for_each_entry_safe(sko,
+			    n, &sks->sks_free_list, sko_list)
+				kv_free(skc, sko->sko_addr, offslab_size);
+
+		kv_free(skc, base, skc->skc_slab_size);
+		sks = NULL;
+	}
+
+	return (sks);
+}
+
+/*
+ * Remove a slab from complete or partial list, it must be called with
+ * the 'skc->skc_lock' held but the actual free must be performed
+ * outside the lock to prevent deadlocking on vmem addresses.
+ */
+static void
+spl_slab_free(spl_kmem_slab_t *sks,
+    struct list_head *sks_list, struct list_head *sko_list)
+{
+	spl_kmem_cache_t *skc;
+
+	ASSERT(sks->sks_magic == SKS_MAGIC);
+	ASSERT(sks->sks_ref == 0);
+
+	skc = sks->sks_cache;
+	ASSERT(skc->skc_magic == SKC_MAGIC);
+	ASSERT(spin_is_locked(&skc->skc_lock));
+
+	/*
+	 * Update slab/objects counters in the cache, then remove the
+	 * slab from the skc->skc_partial_list.  Finally add the slab
+	 * and all its objects in to the private work lists where the
+	 * destructors will be called and the memory freed to the system.
+	 */
+	skc->skc_obj_total -= sks->sks_objs;
+	skc->skc_slab_total--;
+	list_del(&sks->sks_list);
+	list_add(&sks->sks_list, sks_list);
+	list_splice_init(&sks->sks_free_list, sko_list);
+}
+
+/*
+ * Reclaim empty slabs at the end of the partial list.
+ */
+static void
+spl_slab_reclaim(spl_kmem_cache_t *skc)
+{
+	spl_kmem_slab_t *sks, *m;
+	spl_kmem_obj_t *sko, *n;
+	LIST_HEAD(sks_list);
+	LIST_HEAD(sko_list);
+	uint32_t size = 0;
+
+	/*
+	 * Empty slabs and objects must be moved to a private list so they
+	 * can be safely freed outside the spin lock.  All empty slabs are
+	 * at the end of skc->skc_partial_list, therefore once a non-empty
+	 * slab is found we can stop scanning.
+	 */
+	spin_lock(&skc->skc_lock);
+	list_for_each_entry_safe_reverse(sks, m,
+	    &skc->skc_partial_list, sks_list) {
+
+		if (sks->sks_ref > 0)
+			break;
+
+		spl_slab_free(sks, &sks_list, &sko_list);
+	}
+	spin_unlock(&skc->skc_lock);
+
+	/*
+	 * The following two loops ensure all the object destructors are
+	 * run, any offslab objects are freed, and the slabs themselves
+	 * are freed.  This is all done outside the skc->skc_lock since
+	 * this allows the destructor to sleep, and allows us to perform
+	 * a conditional reschedule when a freeing a large number of
+	 * objects and slabs back to the system.
+	 */
+	if (skc->skc_flags & KMC_OFFSLAB)
+		size = spl_offslab_size(skc);
+
+	list_for_each_entry_safe(sko, n, &sko_list, sko_list) {
+		ASSERT(sko->sko_magic == SKO_MAGIC);
+
+		if (skc->skc_flags & KMC_OFFSLAB)
+			kv_free(skc, sko->sko_addr, size);
+	}
+
+	list_for_each_entry_safe(sks, m, &sks_list, sks_list) {
+		ASSERT(sks->sks_magic == SKS_MAGIC);
+		kv_free(skc, sks, skc->skc_slab_size);
+	}
+}
+
+static spl_kmem_emergency_t *
+spl_emergency_search(struct rb_root *root, void *obj)
+{
+	struct rb_node *node = root->rb_node;
+	spl_kmem_emergency_t *ske;
+	unsigned long address = (unsigned long)obj;
+
+	while (node) {
+		ske = container_of(node, spl_kmem_emergency_t, ske_node);
+
+		if (address < ske->ske_obj)
+			node = node->rb_left;
+		else if (address > ske->ske_obj)
+			node = node->rb_right;
+		else
+			return (ske);
+	}
+
+	return (NULL);
+}
+
+static int
+spl_emergency_insert(struct rb_root *root, spl_kmem_emergency_t *ske)
+{
+	struct rb_node **new = &(root->rb_node), *parent = NULL;
+	spl_kmem_emergency_t *ske_tmp;
+	unsigned long address = ske->ske_obj;
+
+	while (*new) {
+		ske_tmp = container_of(*new, spl_kmem_emergency_t, ske_node);
+
+		parent = *new;
+		if (address < ske_tmp->ske_obj)
+			new = &((*new)->rb_left);
+		else if (address > ske_tmp->ske_obj)
+			new = &((*new)->rb_right);
+		else
+			return (0);
+	}
+
+	rb_link_node(&ske->ske_node, parent, new);
+	rb_insert_color(&ske->ske_node, root);
+
+	return (1);
+}
+
+/*
+ * Allocate a single emergency object and track it in a red black tree.
+ */
+static int
+spl_emergency_alloc(spl_kmem_cache_t *skc, int flags, void **obj)
+{
+	gfp_t lflags = kmem_flags_convert(flags);
+	spl_kmem_emergency_t *ske;
+	int order = get_order(skc->skc_obj_size);
+	int empty;
+
+	/* Last chance use a partial slab if one now exists */
+	spin_lock(&skc->skc_lock);
+	empty = list_empty(&skc->skc_partial_list);
+	spin_unlock(&skc->skc_lock);
+	if (!empty)
+		return (-EEXIST);
+
+	ske = kmalloc(sizeof (*ske), lflags);
+	if (ske == NULL)
+		return (-ENOMEM);
+
+	ske->ske_obj = __get_free_pages(lflags, order);
+	if (ske->ske_obj == 0) {
+		kfree(ske);
+		return (-ENOMEM);
+	}
+
+	spin_lock(&skc->skc_lock);
+	empty = spl_emergency_insert(&skc->skc_emergency_tree, ske);
+	if (likely(empty)) {
+		skc->skc_obj_total++;
+		skc->skc_obj_emergency++;
+		if (skc->skc_obj_emergency > skc->skc_obj_emergency_max)
+			skc->skc_obj_emergency_max = skc->skc_obj_emergency;
+	}
+	spin_unlock(&skc->skc_lock);
+
+	if (unlikely(!empty)) {
+		free_pages(ske->ske_obj, order);
+		kfree(ske);
+		return (-EINVAL);
+	}
+
+	*obj = (void *)ske->ske_obj;
+
+	return (0);
+}
+
+/*
+ * Locate the passed object in the red black tree and free it.
+ */
+static int
+spl_emergency_free(spl_kmem_cache_t *skc, void *obj)
+{
+	spl_kmem_emergency_t *ske;
+	int order = get_order(skc->skc_obj_size);
+
+	spin_lock(&skc->skc_lock);
+	ske = spl_emergency_search(&skc->skc_emergency_tree, obj);
+	if (ske) {
+		rb_erase(&ske->ske_node, &skc->skc_emergency_tree);
+		skc->skc_obj_emergency--;
+		skc->skc_obj_total--;
+	}
+	spin_unlock(&skc->skc_lock);
+
+	if (ske == NULL)
+		return (-ENOENT);
+
+	free_pages(ske->ske_obj, order);
+	kfree(ske);
+
+	return (0);
+}
+
+/*
+ * Release objects from the per-cpu magazine back to their slab.  The flush
+ * argument contains the max number of entries to remove from the magazine.
+ */
+static void
+__spl_cache_flush(spl_kmem_cache_t *skc, spl_kmem_magazine_t *skm, int flush)
+{
+	int i, count = MIN(flush, skm->skm_avail);
+
+	ASSERT(skc->skc_magic == SKC_MAGIC);
+	ASSERT(skm->skm_magic == SKM_MAGIC);
+	ASSERT(spin_is_locked(&skc->skc_lock));
+
+	for (i = 0; i < count; i++)
+		spl_cache_shrink(skc, skm->skm_objs[i]);
+
+	skm->skm_avail -= count;
+	memmove(skm->skm_objs, &(skm->skm_objs[count]),
+	    sizeof (void *) * skm->skm_avail);
+}
+
+static void
+spl_cache_flush(spl_kmem_cache_t *skc, spl_kmem_magazine_t *skm, int flush)
+{
+	spin_lock(&skc->skc_lock);
+	__spl_cache_flush(skc, skm, flush);
+	spin_unlock(&skc->skc_lock);
+}
+
+static void
+spl_magazine_age(void *data)
+{
+	spl_kmem_cache_t *skc = (spl_kmem_cache_t *)data;
+	spl_kmem_magazine_t *skm = skc->skc_mag[smp_processor_id()];
+
+	ASSERT(skm->skm_magic == SKM_MAGIC);
+	ASSERT(skm->skm_cpu == smp_processor_id());
+	ASSERT(irqs_disabled());
+
+	/* There are no available objects or they are too young to age out */
+	if ((skm->skm_avail == 0) ||
+	    time_before(jiffies, skm->skm_age + skc->skc_delay * HZ))
+		return;
+
+	/*
+	 * Because we're executing in interrupt context we may have
+	 * interrupted the holder of this lock.  To avoid a potential
+	 * deadlock return if the lock is contended.
+	 */
+	if (!spin_trylock(&skc->skc_lock))
+		return;
+
+	__spl_cache_flush(skc, skm, skm->skm_refill);
+	spin_unlock(&skc->skc_lock);
+}
+
+/*
+ * Called regularly to keep a downward pressure on the cache.
+ *
+ * Objects older than skc->skc_delay seconds in the per-cpu magazines will
+ * be returned to the caches.  This is done to prevent idle magazines from
+ * holding memory which could be better used elsewhere.  The delay is
+ * present to prevent thrashing the magazine.
+ *
+ * The newly released objects may result in empty partial slabs.  Those
+ * slabs should be released to the system.  Otherwise moving the objects
+ * out of the magazines is just wasted work.
+ */
+static void
+spl_cache_age(void *data)
+{
+	spl_kmem_cache_t *skc = (spl_kmem_cache_t *)data;
+	taskqid_t id = 0;
+
+	ASSERT(skc->skc_magic == SKC_MAGIC);
+
+	/* Dynamically disabled at run time */
+	if (!(spl_kmem_cache_expire & KMC_EXPIRE_AGE))
+		return;
+
+	atomic_inc(&skc->skc_ref);
+
+	if (!(skc->skc_flags & KMC_NOMAGAZINE))
+		on_each_cpu(spl_magazine_age, skc, 1);
+
+	spl_slab_reclaim(skc);
+
+	while (!test_bit(KMC_BIT_DESTROY, &skc->skc_flags) && !id) {
+		id = taskq_dispatch_delay(
+		    spl_kmem_cache_taskq, spl_cache_age, skc, TQ_SLEEP,
+		    ddi_get_lbolt() + skc->skc_delay / 3 * HZ);
+
+		/* Destroy issued after dispatch immediately cancel it */
+		if (test_bit(KMC_BIT_DESTROY, &skc->skc_flags) && id)
+			taskq_cancel_id(spl_kmem_cache_taskq, id);
+	}
+
+	spin_lock(&skc->skc_lock);
+	skc->skc_taskqid = id;
+	spin_unlock(&skc->skc_lock);
+
+	atomic_dec(&skc->skc_ref);
+}
+
+/*
+ * Size a slab based on the size of each aligned object plus spl_kmem_obj_t.
+ * When on-slab we want to target spl_kmem_cache_obj_per_slab.  However,
+ * for very small objects we may end up with more than this so as not
+ * to waste space in the minimal allocation of a single page.  Also for
+ * very large objects we may use as few as spl_kmem_cache_obj_per_slab_min,
+ * lower than this and we will fail.
+ */
+static int
+spl_slab_size(spl_kmem_cache_t *skc, uint32_t *objs, uint32_t *size)
+{
+	uint32_t sks_size, obj_size, max_size, tgt_size, tgt_objs;
+
+	if (skc->skc_flags & KMC_OFFSLAB) {
+		tgt_objs = spl_kmem_cache_obj_per_slab;
+		tgt_size = P2ROUNDUP(sizeof (spl_kmem_slab_t), PAGE_SIZE);
+
+		if ((skc->skc_flags & KMC_KMEM) &&
+		    (spl_obj_size(skc) > (SPL_MAX_ORDER_NR_PAGES * PAGE_SIZE)))
+			return (-ENOSPC);
+	} else {
+		sks_size = spl_sks_size(skc);
+		obj_size = spl_obj_size(skc);
+		max_size = (spl_kmem_cache_max_size * 1024 * 1024);
+		tgt_size = (spl_kmem_cache_obj_per_slab * obj_size + sks_size);
+
+		/*
+		 * KMC_KMEM slabs are allocated by __get_free_pages() which
+		 * rounds up to the nearest order.  Knowing this the size
+		 * should be rounded up to the next power of two with a hard
+		 * maximum defined by the maximum allowed allocation order.
+		 */
+		if (skc->skc_flags & KMC_KMEM) {
+			max_size = SPL_MAX_ORDER_NR_PAGES * PAGE_SIZE;
+			tgt_size = MIN(max_size,
+			    PAGE_SIZE * (1 << MAX(get_order(tgt_size) - 1, 1)));
+		}
+
+		if (tgt_size <= max_size) {
+			tgt_objs = (tgt_size - sks_size) / obj_size;
+		} else {
+			tgt_objs = (max_size - sks_size) / obj_size;
+			tgt_size = (tgt_objs * obj_size) + sks_size;
+		}
+	}
+
+	if (tgt_objs == 0)
+		return (-ENOSPC);
+
+	*objs = tgt_objs;
+	*size = tgt_size;
+
+	return (0);
+}
+
+/*
+ * Make a guess at reasonable per-cpu magazine size based on the size of
+ * each object and the cost of caching N of them in each magazine.  Long
+ * term this should really adapt based on an observed usage heuristic.
+ */
+static int
+spl_magazine_size(spl_kmem_cache_t *skc)
+{
+	uint32_t obj_size = spl_obj_size(skc);
+	int size;
+
+	if (spl_kmem_cache_magazine_size > 0)
+		return (MAX(MIN(spl_kmem_cache_magazine_size, 256), 2));
+
+	/* Per-magazine sizes below assume a 4Kib page size */
+	if (obj_size > (PAGE_SIZE * 256))
+		size = 4;  /* Minimum 4Mib per-magazine */
+	else if (obj_size > (PAGE_SIZE * 32))
+		size = 16; /* Minimum 2Mib per-magazine */
+	else if (obj_size > (PAGE_SIZE))
+		size = 64; /* Minimum 256Kib per-magazine */
+	else if (obj_size > (PAGE_SIZE / 4))
+		size = 128; /* Minimum 128Kib per-magazine */
+	else
+		size = 256;
+
+	return (size);
+}
+
+/*
+ * Allocate a per-cpu magazine to associate with a specific core.
+ */
+static spl_kmem_magazine_t *
+spl_magazine_alloc(spl_kmem_cache_t *skc, int cpu)
+{
+	spl_kmem_magazine_t *skm;
+	int size = sizeof (spl_kmem_magazine_t) +
+	    sizeof (void *) * skc->skc_mag_size;
+
+	skm = kmalloc_node(size, GFP_KERNEL, cpu_to_node(cpu));
+	if (skm) {
+		skm->skm_magic = SKM_MAGIC;
+		skm->skm_avail = 0;
+		skm->skm_size = skc->skc_mag_size;
+		skm->skm_refill = skc->skc_mag_refill;
+		skm->skm_cache = skc;
+		skm->skm_age = jiffies;
+		skm->skm_cpu = cpu;
+	}
+
+	return (skm);
+}
+
+/*
+ * Free a per-cpu magazine associated with a specific core.
+ */
+static void
+spl_magazine_free(spl_kmem_magazine_t *skm)
+{
+	ASSERT(skm->skm_magic == SKM_MAGIC);
+	ASSERT(skm->skm_avail == 0);
+	kfree(skm);
+}
+
+/*
+ * Create all pre-cpu magazines of reasonable sizes.
+ */
+static int
+spl_magazine_create(spl_kmem_cache_t *skc)
+{
+	int i;
+
+	if (skc->skc_flags & KMC_NOMAGAZINE)
+		return (0);
+
+	skc->skc_mag = kzalloc(sizeof (spl_kmem_magazine_t *) *
+	    num_possible_cpus(), kmem_flags_convert(KM_SLEEP));
+	skc->skc_mag_size = spl_magazine_size(skc);
+	skc->skc_mag_refill = (skc->skc_mag_size + 1) / 2;
+
+	for_each_possible_cpu(i) {
+		skc->skc_mag[i] = spl_magazine_alloc(skc, i);
+		if (!skc->skc_mag[i]) {
+			for (i--; i >= 0; i--)
+				spl_magazine_free(skc->skc_mag[i]);
+
+			kfree(skc->skc_mag);
+			return (-ENOMEM);
+		}
+	}
+
+	return (0);
+}
+
+/*
+ * Destroy all pre-cpu magazines.
+ */
+static void
+spl_magazine_destroy(spl_kmem_cache_t *skc)
+{
+	spl_kmem_magazine_t *skm;
+	int i;
+
+	if (skc->skc_flags & KMC_NOMAGAZINE)
+		return;
+
+	for_each_possible_cpu(i) {
+		skm = skc->skc_mag[i];
+		spl_cache_flush(skc, skm, skm->skm_avail);
+		spl_magazine_free(skm);
+	}
+
+	kfree(skc->skc_mag);
+}
+
+/*
+ * Create a object cache based on the following arguments:
+ * name		cache name
+ * size		cache object size
+ * align	cache object alignment
+ * ctor		cache object constructor
+ * dtor		cache object destructor
+ * reclaim	cache object reclaim
+ * priv		cache private data for ctor/dtor/reclaim
+ * vmp		unused must be NULL
+ * flags
+ *	KMC_NOTOUCH	Disable cache object aging (unsupported)
+ *	KMC_NODEBUG	Disable debugging (unsupported)
+ *	KMC_NOHASH      Disable hashing (unsupported)
+ *	KMC_QCACHE	Disable qcache (unsupported)
+ *	KMC_NOMAGAZINE	Enabled for kmem/vmem, Disabled for Linux slab
+ *	KMC_KMEM	Force kmem backed cache
+ *	KMC_VMEM        Force vmem backed cache
+ *	KMC_SLAB        Force Linux slab backed cache
+ *	KMC_OFFSLAB	Locate objects off the slab
+ */
+spl_kmem_cache_t *
+spl_kmem_cache_create(char *name, size_t size, size_t align,
+    spl_kmem_ctor_t ctor, spl_kmem_dtor_t dtor, spl_kmem_reclaim_t reclaim,
+    void *priv, void *vmp, int flags)
+{
+	gfp_t lflags = kmem_flags_convert(KM_SLEEP);
+	spl_kmem_cache_t *skc;
+	int rc;
+
+	/*
+	 * Unsupported flags
+	 */
+	ASSERT0(flags & KMC_NOMAGAZINE);
+	ASSERT0(flags & KMC_NOHASH);
+	ASSERT0(flags & KMC_QCACHE);
+	ASSERT(vmp == NULL);
+
+	might_sleep();
+
+	skc = kzalloc(sizeof (*skc), lflags);
+	if (skc == NULL)
+		return (NULL);
+
+	skc->skc_magic = SKC_MAGIC;
+	skc->skc_name_size = strlen(name) + 1;
+	skc->skc_name = (char *)kmalloc(skc->skc_name_size, lflags);
+	if (skc->skc_name == NULL) {
+		kfree(skc);
+		return (NULL);
+	}
+	strncpy(skc->skc_name, name, skc->skc_name_size);
+
+	skc->skc_ctor = ctor;
+	skc->skc_dtor = dtor;
+	skc->skc_reclaim = reclaim;
+	skc->skc_private = priv;
+	skc->skc_vmp = vmp;
+	skc->skc_linux_cache = NULL;
+	skc->skc_flags = flags;
+	skc->skc_obj_size = size;
+	skc->skc_obj_align = SPL_KMEM_CACHE_ALIGN;
+	skc->skc_delay = SPL_KMEM_CACHE_DELAY;
+	skc->skc_reap = SPL_KMEM_CACHE_REAP;
+	atomic_set(&skc->skc_ref, 0);
+
+	INIT_LIST_HEAD(&skc->skc_list);
+	INIT_LIST_HEAD(&skc->skc_complete_list);
+	INIT_LIST_HEAD(&skc->skc_partial_list);
+	skc->skc_emergency_tree = RB_ROOT;
+	spin_lock_init(&skc->skc_lock);
+	init_waitqueue_head(&skc->skc_waitq);
+	skc->skc_slab_fail = 0;
+	skc->skc_slab_create = 0;
+	skc->skc_slab_destroy = 0;
+	skc->skc_slab_total = 0;
+	skc->skc_slab_alloc = 0;
+	skc->skc_slab_max = 0;
+	skc->skc_obj_total = 0;
+	skc->skc_obj_alloc = 0;
+	skc->skc_obj_max = 0;
+	skc->skc_obj_deadlock = 0;
+	skc->skc_obj_emergency = 0;
+	skc->skc_obj_emergency_max = 0;
+
+	/*
+	 * Verify the requested alignment restriction is sane.
+	 */
+	if (align) {
+		VERIFY(ISP2(align));
+		VERIFY3U(align, >=, SPL_KMEM_CACHE_ALIGN);
+		VERIFY3U(align, <=, PAGE_SIZE);
+		skc->skc_obj_align = align;
+	}
+
+	/*
+	 * When no specific type of slab is requested (kmem, vmem, or
+	 * linuxslab) then select a cache type based on the object size
+	 * and default tunables.
+	 */
+	if (!(skc->skc_flags & (KMC_KMEM | KMC_VMEM | KMC_SLAB))) {
+
+		/*
+		 * Objects smaller than spl_kmem_cache_slab_limit can
+		 * use the Linux slab for better space-efficiency.  By
+		 * default this functionality is disabled until its
+		 * performance characteristics are fully understood.
+		 */
+		if (spl_kmem_cache_slab_limit &&
+		    size <= (size_t)spl_kmem_cache_slab_limit)
+			skc->skc_flags |= KMC_SLAB;
+
+		/*
+		 * Small objects, less than spl_kmem_cache_kmem_limit per
+		 * object should use kmem because their slabs are small.
+		 */
+		else if (spl_obj_size(skc) <= spl_kmem_cache_kmem_limit)
+			skc->skc_flags |= KMC_KMEM;
+
+		/*
+		 * All other objects are considered large and are placed
+		 * on vmem backed slabs.
+		 */
+		else
+			skc->skc_flags |= KMC_VMEM;
+	}
+
+	/*
+	 * Given the type of slab allocate the required resources.
+	 */
+	if (skc->skc_flags & (KMC_KMEM | KMC_VMEM)) {
+		rc = spl_slab_size(skc,
+		    &skc->skc_slab_objs, &skc->skc_slab_size);
+		if (rc)
+			goto out;
+
+		rc = spl_magazine_create(skc);
+		if (rc)
+			goto out;
+	} else {
+		unsigned long slabflags = 0;
+
+		if (size > (SPL_MAX_KMEM_ORDER_NR_PAGES * PAGE_SIZE)) {
+			rc = EINVAL;
+			goto out;
+		}
+
+#if defined(SLAB_USERCOPY)
+		/*
+		 * Required for PAX-enabled kernels if the slab is to be
+		 * used for coping between user and kernel space.
+		 */
+		slabflags |= SLAB_USERCOPY;
+#endif
+
+		skc->skc_linux_cache = kmem_cache_create(
+		    skc->skc_name, size, align, slabflags, NULL);
+		if (skc->skc_linux_cache == NULL) {
+			rc = ENOMEM;
+			goto out;
+		}
+
+#if defined(HAVE_KMEM_CACHE_ALLOCFLAGS)
+		skc->skc_linux_cache->allocflags |= __GFP_COMP;
+#elif defined(HAVE_KMEM_CACHE_GFPFLAGS)
+		skc->skc_linux_cache->gfpflags |= __GFP_COMP;
+#endif
+		skc->skc_flags |= KMC_NOMAGAZINE;
+	}
+
+	if (spl_kmem_cache_expire & KMC_EXPIRE_AGE)
+		skc->skc_taskqid = taskq_dispatch_delay(spl_kmem_cache_taskq,
+		    spl_cache_age, skc, TQ_SLEEP,
+		    ddi_get_lbolt() + skc->skc_delay / 3 * HZ);
+
+	down_write(&spl_kmem_cache_sem);
+	list_add_tail(&skc->skc_list, &spl_kmem_cache_list);
+	up_write(&spl_kmem_cache_sem);
+
+	return (skc);
+out:
+	kfree(skc->skc_name);
+	kfree(skc);
+	return (NULL);
+}
+EXPORT_SYMBOL(spl_kmem_cache_create);
+
+/*
+ * Register a move callback for cache defragmentation.
+ * XXX: Unimplemented but harmless to stub out for now.
+ */
+void
+spl_kmem_cache_set_move(spl_kmem_cache_t *skc,
+    kmem_cbrc_t (move)(void *, void *, size_t, void *))
+{
+	ASSERT(move != NULL);
+}
+EXPORT_SYMBOL(spl_kmem_cache_set_move);
+
+/*
+ * Destroy a cache and all objects associated with the cache.
+ */
+void
+spl_kmem_cache_destroy(spl_kmem_cache_t *skc)
+{
+	DECLARE_WAIT_QUEUE_HEAD(wq);
+	taskqid_t id;
+
+	ASSERT(skc->skc_magic == SKC_MAGIC);
+	ASSERT(skc->skc_flags & (KMC_KMEM | KMC_VMEM | KMC_SLAB));
+
+	down_write(&spl_kmem_cache_sem);
+	list_del_init(&skc->skc_list);
+	up_write(&spl_kmem_cache_sem);
+
+	/* Cancel any and wait for any pending delayed tasks */
+	VERIFY(!test_and_set_bit(KMC_BIT_DESTROY, &skc->skc_flags));
+
+	spin_lock(&skc->skc_lock);
+	id = skc->skc_taskqid;
+	spin_unlock(&skc->skc_lock);
+
+	taskq_cancel_id(spl_kmem_cache_taskq, id);
+
+	/*
+	 * Wait until all current callers complete, this is mainly
+	 * to catch the case where a low memory situation triggers a
+	 * cache reaping action which races with this destroy.
+	 */
+	wait_event(wq, atomic_read(&skc->skc_ref) == 0);
+
+	if (skc->skc_flags & (KMC_KMEM | KMC_VMEM)) {
+		spl_magazine_destroy(skc);
+		spl_slab_reclaim(skc);
+	} else {
+		ASSERT(skc->skc_flags & KMC_SLAB);
+		kmem_cache_destroy(skc->skc_linux_cache);
+	}
+
+	spin_lock(&skc->skc_lock);
+
+	/*
+	 * Validate there are no objects in use and free all the
+	 * spl_kmem_slab_t, spl_kmem_obj_t, and object buffers.
+	 */
+	ASSERT3U(skc->skc_slab_alloc, ==, 0);
+	ASSERT3U(skc->skc_obj_alloc, ==, 0);
+	ASSERT3U(skc->skc_slab_total, ==, 0);
+	ASSERT3U(skc->skc_obj_total, ==, 0);
+	ASSERT3U(skc->skc_obj_emergency, ==, 0);
+	ASSERT(list_empty(&skc->skc_complete_list));
+
+	spin_unlock(&skc->skc_lock);
+
+	kfree(skc->skc_name);
+	kfree(skc);
+}
+EXPORT_SYMBOL(spl_kmem_cache_destroy);
+
+/*
+ * Allocate an object from a slab attached to the cache.  This is used to
+ * repopulate the per-cpu magazine caches in batches when they run low.
+ */
+static void *
+spl_cache_obj(spl_kmem_cache_t *skc, spl_kmem_slab_t *sks)
+{
+	spl_kmem_obj_t *sko;
+
+	ASSERT(skc->skc_magic == SKC_MAGIC);
+	ASSERT(sks->sks_magic == SKS_MAGIC);
+	ASSERT(spin_is_locked(&skc->skc_lock));
+
+	sko = list_entry(sks->sks_free_list.next, spl_kmem_obj_t, sko_list);
+	ASSERT(sko->sko_magic == SKO_MAGIC);
+	ASSERT(sko->sko_addr != NULL);
+
+	/* Remove from sks_free_list */
+	list_del_init(&sko->sko_list);
+
+	sks->sks_age = jiffies;
+	sks->sks_ref++;
+	skc->skc_obj_alloc++;
+
+	/* Track max obj usage statistics */
+	if (skc->skc_obj_alloc > skc->skc_obj_max)
+		skc->skc_obj_max = skc->skc_obj_alloc;
+
+	/* Track max slab usage statistics */
+	if (sks->sks_ref == 1) {
+		skc->skc_slab_alloc++;
+
+		if (skc->skc_slab_alloc > skc->skc_slab_max)
+			skc->skc_slab_max = skc->skc_slab_alloc;
+	}
+
+	return (sko->sko_addr);
+}
+
+/*
+ * Generic slab allocation function to run by the global work queues.
+ * It is responsible for allocating a new slab, linking it in to the list
+ * of partial slabs, and then waking any waiters.
+ */
+static void
+spl_cache_grow_work(void *data)
+{
+	spl_kmem_alloc_t *ska = (spl_kmem_alloc_t *)data;
+	spl_kmem_cache_t *skc = ska->ska_cache;
+	spl_kmem_slab_t *sks;
+
+	fstrans_cookie_t cookie = spl_fstrans_mark();
+	sks = spl_slab_alloc(skc, ska->ska_flags);
+	spl_fstrans_unmark(cookie);
+
+	spin_lock(&skc->skc_lock);
+	if (sks) {
+		skc->skc_slab_total++;
+		skc->skc_obj_total += sks->sks_objs;
+		list_add_tail(&sks->sks_list, &skc->skc_partial_list);
+	}
+
+	atomic_dec(&skc->skc_ref);
+	smp_mb__before_atomic();
+	clear_bit(KMC_BIT_GROWING, &skc->skc_flags);
+	clear_bit(KMC_BIT_DEADLOCKED, &skc->skc_flags);
+	smp_mb__after_atomic();
+	wake_up_all(&skc->skc_waitq);
+	spin_unlock(&skc->skc_lock);
+
+	kfree(ska);
+}
+
+/*
+ * Returns non-zero when a new slab should be available.
+ */
+static int
+spl_cache_grow_wait(spl_kmem_cache_t *skc)
+{
+	return (!test_bit(KMC_BIT_GROWING, &skc->skc_flags));
+}
+
+/*
+ * No available objects on any slabs, create a new slab.  Note that this
+ * functionality is disabled for KMC_SLAB caches which are backed by the
+ * Linux slab.
+ */
+static int
+spl_cache_grow(spl_kmem_cache_t *skc, int flags, void **obj)
+{
+	int remaining, rc = 0;
+
+	ASSERT0(flags & ~KM_PUBLIC_MASK);
+	ASSERT(skc->skc_magic == SKC_MAGIC);
+	ASSERT((skc->skc_flags & KMC_SLAB) == 0);
+	might_sleep();
+	*obj = NULL;
+
+	/*
+	 * Before allocating a new slab wait for any reaping to complete and
+	 * then return so the local magazine can be rechecked for new objects.
+	 */
+	if (test_bit(KMC_BIT_REAPING, &skc->skc_flags)) {
+		rc = spl_wait_on_bit(&skc->skc_flags, KMC_BIT_REAPING,
+		    TASK_UNINTERRUPTIBLE);
+		return (rc ? rc : -EAGAIN);
+	}
+
+	/*
+	 * This is handled by dispatching a work request to the global work
+	 * queue.  This allows us to asynchronously allocate a new slab while
+	 * retaining the ability to safely fall back to a smaller synchronous
+	 * allocations to ensure forward progress is always maintained.
+	 */
+	if (test_and_set_bit(KMC_BIT_GROWING, &skc->skc_flags) == 0) {
+		spl_kmem_alloc_t *ska;
+
+		ska = kmalloc(sizeof (*ska), kmem_flags_convert(flags));
+		if (ska == NULL) {
+			clear_bit_unlock(KMC_BIT_GROWING, &skc->skc_flags);
+			smp_mb__after_atomic();
+			wake_up_all(&skc->skc_waitq);
+			return (-ENOMEM);
+		}
+
+		atomic_inc(&skc->skc_ref);
+		ska->ska_cache = skc;
+		ska->ska_flags = flags;
+		taskq_init_ent(&ska->ska_tqe);
+		taskq_dispatch_ent(spl_kmem_cache_taskq,
+		    spl_cache_grow_work, ska, 0, &ska->ska_tqe);
+	}
+
+	/*
+	 * The goal here is to only detect the rare case where a virtual slab
+	 * allocation has deadlocked.  We must be careful to minimize the use
+	 * of emergency objects which are more expensive to track.  Therefore,
+	 * we set a very long timeout for the asynchronous allocation and if
+	 * the timeout is reached the cache is flagged as deadlocked.  From
+	 * this point only new emergency objects will be allocated until the
+	 * asynchronous allocation completes and clears the deadlocked flag.
+	 */
+	if (test_bit(KMC_BIT_DEADLOCKED, &skc->skc_flags)) {
+		rc = spl_emergency_alloc(skc, flags, obj);
+	} else {
+		remaining = wait_event_timeout(skc->skc_waitq,
+		    spl_cache_grow_wait(skc), HZ / 10);
+
+		if (!remaining) {
+			spin_lock(&skc->skc_lock);
+			if (test_bit(KMC_BIT_GROWING, &skc->skc_flags)) {
+				set_bit(KMC_BIT_DEADLOCKED, &skc->skc_flags);
+				skc->skc_obj_deadlock++;
+			}
+			spin_unlock(&skc->skc_lock);
+		}
+
+		rc = -ENOMEM;
+	}
+
+	return (rc);
+}
+
+/*
+ * Refill a per-cpu magazine with objects from the slabs for this cache.
+ * Ideally the magazine can be repopulated using existing objects which have
+ * been released, however if we are unable to locate enough free objects new
+ * slabs of objects will be created.  On success NULL is returned, otherwise
+ * the address of a single emergency object is returned for use by the caller.
+ */
+static void *
+spl_cache_refill(spl_kmem_cache_t *skc, spl_kmem_magazine_t *skm, int flags)
+{
+	spl_kmem_slab_t *sks;
+	int count = 0, rc, refill;
+	void *obj = NULL;
+
+	ASSERT(skc->skc_magic == SKC_MAGIC);
+	ASSERT(skm->skm_magic == SKM_MAGIC);
+
+	refill = MIN(skm->skm_refill, skm->skm_size - skm->skm_avail);
+	spin_lock(&skc->skc_lock);
+
+	while (refill > 0) {
+		/* No slabs available we may need to grow the cache */
+		if (list_empty(&skc->skc_partial_list)) {
+			spin_unlock(&skc->skc_lock);
+
+			local_irq_enable();
+			rc = spl_cache_grow(skc, flags, &obj);
+			local_irq_disable();
+
+			/* Emergency object for immediate use by caller */
+			if (rc == 0 && obj != NULL)
+				return (obj);
+
+			if (rc)
+				goto out;
+
+			/* Rescheduled to different CPU skm is not local */
+			if (skm != skc->skc_mag[smp_processor_id()])
+				goto out;
+
+			/*
+			 * Potentially rescheduled to the same CPU but
+			 * allocations may have occurred from this CPU while
+			 * we were sleeping so recalculate max refill.
+			 */
+			refill = MIN(refill, skm->skm_size - skm->skm_avail);
+
+			spin_lock(&skc->skc_lock);
+			continue;
+		}
+
+		/* Grab the next available slab */
+		sks = list_entry((&skc->skc_partial_list)->next,
+		    spl_kmem_slab_t, sks_list);
+		ASSERT(sks->sks_magic == SKS_MAGIC);
+		ASSERT(sks->sks_ref < sks->sks_objs);
+		ASSERT(!list_empty(&sks->sks_free_list));
+
+		/*
+		 * Consume as many objects as needed to refill the requested
+		 * cache.  We must also be careful not to overfill it.
+		 */
+		while (sks->sks_ref < sks->sks_objs && refill-- > 0 &&
+		    ++count) {
+			ASSERT(skm->skm_avail < skm->skm_size);
+			ASSERT(count < skm->skm_size);
+			skm->skm_objs[skm->skm_avail++] =
+			    spl_cache_obj(skc, sks);
+		}
+
+		/* Move slab to skc_complete_list when full */
+		if (sks->sks_ref == sks->sks_objs) {
+			list_del(&sks->sks_list);
+			list_add(&sks->sks_list, &skc->skc_complete_list);
+		}
+	}
+
+	spin_unlock(&skc->skc_lock);
+out:
+	return (NULL);
+}
+
+/*
+ * Release an object back to the slab from which it came.
+ */
+static void
+spl_cache_shrink(spl_kmem_cache_t *skc, void *obj)
+{
+	spl_kmem_slab_t *sks = NULL;
+	spl_kmem_obj_t *sko = NULL;
+
+	ASSERT(skc->skc_magic == SKC_MAGIC);
+	ASSERT(spin_is_locked(&skc->skc_lock));
+
+	sko = spl_sko_from_obj(skc, obj);
+	ASSERT(sko->sko_magic == SKO_MAGIC);
+	sks = sko->sko_slab;
+	ASSERT(sks->sks_magic == SKS_MAGIC);
+	ASSERT(sks->sks_cache == skc);
+	list_add(&sko->sko_list, &sks->sks_free_list);
+
+	sks->sks_age = jiffies;
+	sks->sks_ref--;
+	skc->skc_obj_alloc--;
+
+	/*
+	 * Move slab to skc_partial_list when no longer full.  Slabs
+	 * are added to the head to keep the partial list is quasi-full
+	 * sorted order.  Fuller at the head, emptier at the tail.
+	 */
+	if (sks->sks_ref == (sks->sks_objs - 1)) {
+		list_del(&sks->sks_list);
+		list_add(&sks->sks_list, &skc->skc_partial_list);
+	}
+
+	/*
+	 * Move empty slabs to the end of the partial list so
+	 * they can be easily found and freed during reclamation.
+	 */
+	if (sks->sks_ref == 0) {
+		list_del(&sks->sks_list);
+		list_add_tail(&sks->sks_list, &skc->skc_partial_list);
+		skc->skc_slab_alloc--;
+	}
+}
+
+/*
+ * Allocate an object from the per-cpu magazine, or if the magazine
+ * is empty directly allocate from a slab and repopulate the magazine.
+ */
+void *
+spl_kmem_cache_alloc(spl_kmem_cache_t *skc, int flags)
+{
+	spl_kmem_magazine_t *skm;
+	void *obj = NULL;
+
+	ASSERT0(flags & ~KM_PUBLIC_MASK);
+	ASSERT(skc->skc_magic == SKC_MAGIC);
+	ASSERT(!test_bit(KMC_BIT_DESTROY, &skc->skc_flags));
+
+	/*
+	 * Allocate directly from a Linux slab.  All optimizations are left
+	 * to the underlying cache we only need to guarantee that KM_SLEEP
+	 * callers will never fail.
+	 */
+	if (skc->skc_flags & KMC_SLAB) {
+		struct kmem_cache *slc = skc->skc_linux_cache;
+		do {
+			obj = kmem_cache_alloc(slc, kmem_flags_convert(flags));
+		} while ((obj == NULL) && !(flags & KM_NOSLEEP));
+
+		goto ret;
+	}
+
+	local_irq_disable();
+
+restart:
+	/*
+	 * Safe to update per-cpu structure without lock, but
+	 * in the restart case we must be careful to reacquire
+	 * the local magazine since this may have changed
+	 * when we need to grow the cache.
+	 */
+	skm = skc->skc_mag[smp_processor_id()];
+	ASSERT(skm->skm_magic == SKM_MAGIC);
+
+	if (likely(skm->skm_avail)) {
+		/* Object available in CPU cache, use it */
+		obj = skm->skm_objs[--skm->skm_avail];
+		skm->skm_age = jiffies;
+	} else {
+		obj = spl_cache_refill(skc, skm, flags);
+		if ((obj == NULL) && !(flags & KM_NOSLEEP))
+			goto restart;
+
+		local_irq_enable();
+		goto ret;
+	}
+
+	local_irq_enable();
+	ASSERT(obj);
+	ASSERT(IS_P2ALIGNED(obj, skc->skc_obj_align));
+
+ret:
+	/* Pre-emptively migrate object to CPU L1 cache */
+	if (obj) {
+		if (obj && skc->skc_ctor)
+			skc->skc_ctor(obj, skc->skc_private, flags);
+		else
+			prefetchw(obj);
+	}
+
+	return (obj);
+}
+EXPORT_SYMBOL(spl_kmem_cache_alloc);
+
+/*
+ * Free an object back to the local per-cpu magazine, there is no
+ * guarantee that this is the same magazine the object was originally
+ * allocated from.  We may need to flush entire from the magazine
+ * back to the slabs to make space.
+ */
+void
+spl_kmem_cache_free(spl_kmem_cache_t *skc, void *obj)
+{
+	spl_kmem_magazine_t *skm;
+	unsigned long flags;
+	int do_reclaim = 0;
+	int do_emergency = 0;
+
+	ASSERT(skc->skc_magic == SKC_MAGIC);
+	ASSERT(!test_bit(KMC_BIT_DESTROY, &skc->skc_flags));
+
+	/*
+	 * Run the destructor
+	 */
+	if (skc->skc_dtor)
+		skc->skc_dtor(obj, skc->skc_private);
+
+	/*
+	 * Free the object from the Linux underlying Linux slab.
+	 */
+	if (skc->skc_flags & KMC_SLAB) {
+		kmem_cache_free(skc->skc_linux_cache, obj);
+		return;
+	}
+
+	/*
+	 * While a cache has outstanding emergency objects all freed objects
+	 * must be checked.  However, since emergency objects will never use
+	 * a virtual address these objects can be safely excluded as an
+	 * optimization.
+	 */
+	if (!is_vmalloc_addr(obj)) {
+		spin_lock(&skc->skc_lock);
+		do_emergency = (skc->skc_obj_emergency > 0);
+		spin_unlock(&skc->skc_lock);
+
+		if (do_emergency && (spl_emergency_free(skc, obj) == 0))
+			return;
+	}
+
+	local_irq_save(flags);
+
+	/*
+	 * Safe to update per-cpu structure without lock, but
+	 * no remote memory allocation tracking is being performed
+	 * it is entirely possible to allocate an object from one
+	 * CPU cache and return it to another.
+	 */
+	skm = skc->skc_mag[smp_processor_id()];
+	ASSERT(skm->skm_magic == SKM_MAGIC);
+
+	/*
+	 * Per-CPU cache full, flush it to make space for this object,
+	 * this may result in an empty slab which can be reclaimed once
+	 * interrupts are re-enabled.
+	 */
+	if (unlikely(skm->skm_avail >= skm->skm_size)) {
+		spl_cache_flush(skc, skm, skm->skm_refill);
+		do_reclaim = 1;
+	}
+
+	/* Available space in cache, use it */
+	skm->skm_objs[skm->skm_avail++] = obj;
+
+	local_irq_restore(flags);
+
+	if (do_reclaim)
+		spl_slab_reclaim(skc);
+}
+EXPORT_SYMBOL(spl_kmem_cache_free);
+
+/*
+ * The generic shrinker function for all caches.  Under Linux a shrinker
+ * may not be tightly coupled with a slab cache.  In fact Linux always
+ * systematically tries calling all registered shrinker callbacks which
+ * report that they contain unused objects.  Because of this we only
+ * register one shrinker function in the shim layer for all slab caches.
+ * We always attempt to shrink all caches when this generic shrinker
+ * is called.
+ *
+ * If sc->nr_to_scan is zero, the caller is requesting a query of the
+ * number of objects which can potentially be freed.  If it is nonzero,
+ * the request is to free that many objects.
+ *
+ * Linux kernels >= 3.12 have the count_objects and scan_objects callbacks
+ * in struct shrinker and also require the shrinker to return the number
+ * of objects freed.
+ *
+ * Older kernels require the shrinker to return the number of freeable
+ * objects following the freeing of nr_to_free.
+ *
+ * Linux semantics differ from those under Solaris, which are to
+ * free all available objects which may (and probably will) be more
+ * objects than the requested nr_to_scan.
+ */
+static spl_shrinker_t
+__spl_kmem_cache_generic_shrinker(struct shrinker *shrink,
+    struct shrink_control *sc)
+{
+	spl_kmem_cache_t *skc;
+	int alloc = 0;
+
+	/*
+	 * No shrinking in a transaction context.  Can cause deadlocks.
+	 */
+	if (sc->nr_to_scan && spl_fstrans_check())
+		return (SHRINK_STOP);
+
+	down_read(&spl_kmem_cache_sem);
+	list_for_each_entry(skc, &spl_kmem_cache_list, skc_list) {
+		if (sc->nr_to_scan) {
+#ifdef HAVE_SPLIT_SHRINKER_CALLBACK
+			uint64_t oldalloc = skc->skc_obj_alloc;
+			spl_kmem_cache_reap_now(skc,
+			    MAX(sc->nr_to_scan>>fls64(skc->skc_slab_objs), 1));
+			if (oldalloc > skc->skc_obj_alloc)
+				alloc += oldalloc - skc->skc_obj_alloc;
+#else
+			spl_kmem_cache_reap_now(skc,
+			    MAX(sc->nr_to_scan>>fls64(skc->skc_slab_objs), 1));
+			alloc += skc->skc_obj_alloc;
+#endif /* HAVE_SPLIT_SHRINKER_CALLBACK */
+		} else {
+			/* Request to query number of freeable objects */
+			alloc += skc->skc_obj_alloc;
+		}
+	}
+	up_read(&spl_kmem_cache_sem);
+
+	/*
+	 * When KMC_RECLAIM_ONCE is set allow only a single reclaim pass.
+	 * This functionality only exists to work around a rare issue where
+	 * shrink_slabs() is repeatedly invoked by many cores causing the
+	 * system to thrash.
+	 */
+	if ((spl_kmem_cache_reclaim & KMC_RECLAIM_ONCE) && sc->nr_to_scan)
+		return (SHRINK_STOP);
+
+	return (MAX(alloc, 0));
+}
+
+SPL_SHRINKER_CALLBACK_WRAPPER(spl_kmem_cache_generic_shrinker);
+
+/*
+ * Call the registered reclaim function for a cache.  Depending on how
+ * many and which objects are released it may simply repopulate the
+ * local magazine which will then need to age-out.  Objects which cannot
+ * fit in the magazine we will be released back to their slabs which will
+ * also need to age out before being release.  This is all just best
+ * effort and we do not want to thrash creating and destroying slabs.
+ */
+void
+spl_kmem_cache_reap_now(spl_kmem_cache_t *skc, int count)
+{
+	ASSERT(skc->skc_magic == SKC_MAGIC);
+	ASSERT(!test_bit(KMC_BIT_DESTROY, &skc->skc_flags));
+
+	atomic_inc(&skc->skc_ref);
+
+	/*
+	 * Execute the registered reclaim callback if it exists.
+	 */
+	if (skc->skc_flags & KMC_SLAB) {
+		if (skc->skc_reclaim)
+			skc->skc_reclaim(skc->skc_private);
+		goto out;
+	}
+
+	/*
+	 * Prevent concurrent cache reaping when contended.
+	 */
+	if (test_and_set_bit(KMC_BIT_REAPING, &skc->skc_flags))
+		goto out;
+
+	/*
+	 * When a reclaim function is available it may be invoked repeatedly
+	 * until at least a single slab can be freed.  This ensures that we
+	 * do free memory back to the system.  This helps minimize the chance
+	 * of an OOM event when the bulk of memory is used by the slab.
+	 *
+	 * When free slabs are already available the reclaim callback will be
+	 * skipped.  Additionally, if no forward progress is detected despite
+	 * a reclaim function the cache will be skipped to avoid deadlock.
+	 *
+	 * Longer term this would be the correct place to add the code which
+	 * repacks the slabs in order minimize fragmentation.
+	 */
+	if (skc->skc_reclaim) {
+		uint64_t objects = UINT64_MAX;
+		int do_reclaim;
+
+		do {
+			spin_lock(&skc->skc_lock);
+			do_reclaim =
+			    (skc->skc_slab_total > 0) &&
+			    ((skc->skc_slab_total-skc->skc_slab_alloc) == 0) &&
+			    (skc->skc_obj_alloc < objects);
+
+			objects = skc->skc_obj_alloc;
+			spin_unlock(&skc->skc_lock);
+
+			if (do_reclaim)
+				skc->skc_reclaim(skc->skc_private);
+
+		} while (do_reclaim);
+	}
+
+	/* Reclaim from the magazine and free all now empty slabs. */
+	if (spl_kmem_cache_expire & KMC_EXPIRE_MEM) {
+		spl_kmem_magazine_t *skm;
+		unsigned long irq_flags;
+
+		local_irq_save(irq_flags);
+		skm = skc->skc_mag[smp_processor_id()];
+		spl_cache_flush(skc, skm, skm->skm_avail);
+		local_irq_restore(irq_flags);
+	}
+
+	spl_slab_reclaim(skc);
+	clear_bit_unlock(KMC_BIT_REAPING, &skc->skc_flags);
+	smp_mb__after_atomic();
+	wake_up_bit(&skc->skc_flags, KMC_BIT_REAPING);
+out:
+	atomic_dec(&skc->skc_ref);
+}
+EXPORT_SYMBOL(spl_kmem_cache_reap_now);
+
+/*
+ * Reap all free slabs from all registered caches.
+ */
+void
+spl_kmem_reap(void)
+{
+	struct shrink_control sc;
+
+	sc.nr_to_scan = KMC_REAP_CHUNK;
+	sc.gfp_mask = GFP_KERNEL;
+
+	(void) __spl_kmem_cache_generic_shrinker(NULL, &sc);
+}
+EXPORT_SYMBOL(spl_kmem_reap);
+
+int
+spl_kmem_cache_init(void)
+{
+	init_rwsem(&spl_kmem_cache_sem);
+	INIT_LIST_HEAD(&spl_kmem_cache_list);
+	spl_kmem_cache_taskq = taskq_create("spl_kmem_cache",
+	    spl_kmem_cache_kmem_threads, maxclsyspri,
+	    spl_kmem_cache_kmem_threads * 8, INT_MAX,
+	    TASKQ_PREPOPULATE | TASKQ_DYNAMIC);
+	spl_register_shrinker(&spl_kmem_cache_shrinker);
+
+	return (0);
+}
+
+void
+spl_kmem_cache_fini(void)
+{
+	spl_unregister_shrinker(&spl_kmem_cache_shrinker);
+	taskq_destroy(spl_kmem_cache_taskq);
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/module/spl/spl-kmem.c
@@ -0,0 +1,560 @@
+/*
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <sys/debug.h>
+#include <sys/sysmacros.h>
+#include <sys/kmem.h>
+#include <sys/vmem.h>
+#include <linux/mm.h>
+#include <linux/ratelimit.h>
+
+/*
+ * As a general rule kmem_alloc() allocations should be small, preferably
+ * just a few pages since they must by physically contiguous.  Therefore, a
+ * rate limited warning will be printed to the console for any kmem_alloc()
+ * which exceeds a reasonable threshold.
+ *
+ * The default warning threshold is set to eight pages but capped at 32K to
+ * accommodate systems using large pages.  This value was selected to be small
+ * enough to ensure the largest allocations are quickly noticed and fixed.
+ * But large enough to avoid logging any warnings when a allocation size is
+ * larger than optimal but not a serious concern.  Since this value is tunable,
+ * developers are encouraged to set it lower when testing so any new largish
+ * allocations are quickly caught.  These warnings may be disabled by setting
+ * the threshold to zero.
+ */
+unsigned int spl_kmem_alloc_warn = MAX(8 * PAGE_SIZE, 32 * 1024);
+module_param(spl_kmem_alloc_warn, uint, 0644);
+MODULE_PARM_DESC(spl_kmem_alloc_warn,
+	"Warning threshold in bytes for a kmem_alloc()");
+EXPORT_SYMBOL(spl_kmem_alloc_warn);
+
+/*
+ * Large kmem_alloc() allocations will fail if they exceed KMALLOC_MAX_SIZE.
+ * Allocations which are marginally smaller than this limit may succeed but
+ * should still be avoided due to the expense of locating a contiguous range
+ * of free pages.  Therefore, a maximum kmem size with reasonable safely
+ * margin of 4x is set.  Kmem_alloc() allocations larger than this maximum
+ * will quickly fail.  Vmem_alloc() allocations less than or equal to this
+ * value will use kmalloc(), but shift to vmalloc() when exceeding this value.
+ */
+unsigned int spl_kmem_alloc_max = (KMALLOC_MAX_SIZE >> 2);
+module_param(spl_kmem_alloc_max, uint, 0644);
+MODULE_PARM_DESC(spl_kmem_alloc_max,
+	"Maximum size in bytes for a kmem_alloc()");
+EXPORT_SYMBOL(spl_kmem_alloc_max);
+
+int
+kmem_debugging(void)
+{
+	return (0);
+}
+EXPORT_SYMBOL(kmem_debugging);
+
+char *
+kmem_vasprintf(const char *fmt, va_list ap)
+{
+	va_list aq;
+	char *ptr;
+
+	do {
+		va_copy(aq, ap);
+		ptr = kvasprintf(kmem_flags_convert(KM_SLEEP), fmt, aq);
+		va_end(aq);
+	} while (ptr == NULL);
+
+	return (ptr);
+}
+EXPORT_SYMBOL(kmem_vasprintf);
+
+char *
+kmem_asprintf(const char *fmt, ...)
+{
+	va_list ap;
+	char *ptr;
+
+	do {
+		va_start(ap, fmt);
+		ptr = kvasprintf(kmem_flags_convert(KM_SLEEP), fmt, ap);
+		va_end(ap);
+	} while (ptr == NULL);
+
+	return (ptr);
+}
+EXPORT_SYMBOL(kmem_asprintf);
+
+static char *
+__strdup(const char *str, int flags)
+{
+	char *ptr;
+	int n;
+
+	n = strlen(str);
+	ptr = kmalloc(n + 1, kmem_flags_convert(flags));
+	if (ptr)
+		memcpy(ptr, str, n + 1);
+
+	return (ptr);
+}
+
+char *
+strdup(const char *str)
+{
+	return (__strdup(str, KM_SLEEP));
+}
+EXPORT_SYMBOL(strdup);
+
+void
+strfree(char *str)
+{
+	kfree(str);
+}
+EXPORT_SYMBOL(strfree);
+
+/*
+ * Limit the number of large allocation stack traces dumped to not more than
+ * 5 every 60 seconds to prevent denial-of-service attacks from debug code.
+ */
+DEFINE_RATELIMIT_STATE(kmem_alloc_ratelimit_state, 60 * HZ, 5);
+
+/*
+ * General purpose unified implementation of kmem_alloc(). It is an
+ * amalgamation of Linux and Illumos allocator design. It should never be
+ * exported to ensure that code using kmem_alloc()/kmem_zalloc() remains
+ * relatively portable.  Consumers may only access this function through
+ * wrappers that enforce the common flags to ensure portability.
+ */
+inline void *
+spl_kmem_alloc_impl(size_t size, int flags, int node)
+{
+	gfp_t lflags = kmem_flags_convert(flags);
+	int use_vmem = 0;
+	void *ptr;
+
+	/*
+	 * Log abnormally large allocations and rate limit the console output.
+	 * Allocations larger than spl_kmem_alloc_warn should be performed
+	 * through the vmem_alloc()/vmem_zalloc() interfaces.
+	 */
+	if ((spl_kmem_alloc_warn > 0) && (size > spl_kmem_alloc_warn) &&
+	    !(flags & KM_VMEM) && __ratelimit(&kmem_alloc_ratelimit_state)) {
+		printk(KERN_WARNING
+		    "Large kmem_alloc(%lu, 0x%x), please file an issue at:\n"
+		    "https://github.com/zfsonlinux/zfs/issues/new\n",
+		    (unsigned long)size, flags);
+		dump_stack();
+	}
+
+	/*
+	 * Use a loop because kmalloc_node() can fail when GFP_KERNEL is used
+	 * unlike kmem_alloc() with KM_SLEEP on Illumos.
+	 */
+	do {
+		/*
+		 * Calling kmalloc_node() when the size >= spl_kmem_alloc_max
+		 * is unsafe.  This must fail for all for kmem_alloc() and
+		 * kmem_zalloc() callers.
+		 *
+		 * For vmem_alloc() and vmem_zalloc() callers it is permissible
+		 * to use __vmalloc().  However, in general use of __vmalloc()
+		 * is strongly discouraged because a global lock must be
+		 * acquired.  Contention on this lock can significantly
+		 * impact performance so frequently manipulating the virtual
+		 * address space is strongly discouraged.
+		 */
+		if ((size > spl_kmem_alloc_max) || use_vmem) {
+			if (flags & KM_VMEM) {
+				ptr = __vmalloc(size, lflags, PAGE_KERNEL);
+			} else {
+				return (NULL);
+			}
+		} else {
+			ptr = kmalloc_node(size, lflags, node);
+		}
+
+		if (likely(ptr) || (flags & KM_NOSLEEP))
+			return (ptr);
+
+		/*
+		 * For vmem_alloc() and vmem_zalloc() callers retry immediately
+		 * using __vmalloc() which is unlikely to fail.
+		 */
+		if ((flags & KM_VMEM) && (use_vmem == 0))  {
+			use_vmem = 1;
+			continue;
+		}
+
+		if (unlikely(__ratelimit(&kmem_alloc_ratelimit_state))) {
+			printk(KERN_WARNING
+			    "Possible memory allocation deadlock: "
+			    "size=%lu lflags=0x%x",
+			    (unsigned long)size, lflags);
+			dump_stack();
+		}
+
+		/*
+		 * Use cond_resched() instead of congestion_wait() to avoid
+		 * deadlocking systems where there are no block devices.
+		 */
+		cond_resched();
+	} while (1);
+
+	return (NULL);
+}
+
+inline void
+spl_kmem_free_impl(const void *buf, size_t size)
+{
+	if (is_vmalloc_addr(buf))
+		vfree(buf);
+	else
+		kfree(buf);
+}
+
+/*
+ * Memory allocation and accounting for kmem_* * style allocations.  When
+ * DEBUG_KMEM is enabled the total memory allocated will be tracked and
+ * any memory leaked will be reported during module unload.
+ *
+ * ./configure --enable-debug-kmem
+ */
+#ifdef DEBUG_KMEM
+
+/* Shim layer memory accounting */
+#ifdef HAVE_ATOMIC64_T
+atomic64_t kmem_alloc_used = ATOMIC64_INIT(0);
+unsigned long long kmem_alloc_max = 0;
+#else  /* HAVE_ATOMIC64_T */
+atomic_t kmem_alloc_used = ATOMIC_INIT(0);
+unsigned long long kmem_alloc_max = 0;
+#endif /* HAVE_ATOMIC64_T */
+
+EXPORT_SYMBOL(kmem_alloc_used);
+EXPORT_SYMBOL(kmem_alloc_max);
+
+inline void *
+spl_kmem_alloc_debug(size_t size, int flags, int node)
+{
+	void *ptr;
+
+	ptr = spl_kmem_alloc_impl(size, flags, node);
+	if (ptr) {
+		kmem_alloc_used_add(size);
+		if (unlikely(kmem_alloc_used_read() > kmem_alloc_max))
+			kmem_alloc_max = kmem_alloc_used_read();
+	}
+
+	return (ptr);
+}
+
+inline void
+spl_kmem_free_debug(const void *ptr, size_t size)
+{
+	kmem_alloc_used_sub(size);
+	spl_kmem_free_impl(ptr, size);
+}
+
+/*
+ * When DEBUG_KMEM_TRACKING is enabled not only will total bytes be tracked
+ * but also the location of every alloc and free.  When the SPL module is
+ * unloaded a list of all leaked addresses and where they were allocated
+ * will be dumped to the console.  Enabling this feature has a significant
+ * impact on performance but it makes finding memory leaks straight forward.
+ *
+ * Not surprisingly with debugging enabled the xmem_locks are very highly
+ * contended particularly on xfree().  If we want to run with this detailed
+ * debugging enabled for anything other than debugging  we need to minimize
+ * the contention by moving to a lock per xmem_table entry model.
+ *
+ * ./configure --enable-debug-kmem-tracking
+ */
+#ifdef DEBUG_KMEM_TRACKING
+
+#include <linux/hash.h>
+#include <linux/ctype.h>
+
+#define	KMEM_HASH_BITS		10
+#define	KMEM_TABLE_SIZE		(1 << KMEM_HASH_BITS)
+
+typedef struct kmem_debug {
+	struct hlist_node kd_hlist;	/* Hash node linkage */
+	struct list_head kd_list;	/* List of all allocations */
+	void *kd_addr;			/* Allocation pointer */
+	size_t kd_size;			/* Allocation size */
+	const char *kd_func;		/* Allocation function */
+	int kd_line;			/* Allocation line */
+} kmem_debug_t;
+
+static spinlock_t kmem_lock;
+static struct hlist_head kmem_table[KMEM_TABLE_SIZE];
+static struct list_head kmem_list;
+
+static kmem_debug_t *
+kmem_del_init(spinlock_t *lock, struct hlist_head *table,
+    int bits, const void *addr)
+{
+	struct hlist_head *head;
+	struct hlist_node *node;
+	struct kmem_debug *p;
+	unsigned long flags;
+
+	spin_lock_irqsave(lock, flags);
+
+	head = &table[hash_ptr((void *)addr, bits)];
+	hlist_for_each(node, head) {
+		p = list_entry(node, struct kmem_debug, kd_hlist);
+		if (p->kd_addr == addr) {
+			hlist_del_init(&p->kd_hlist);
+			list_del_init(&p->kd_list);
+			spin_unlock_irqrestore(lock, flags);
+			return (p);
+		}
+	}
+
+	spin_unlock_irqrestore(lock, flags);
+
+	return (NULL);
+}
+
+inline void *
+spl_kmem_alloc_track(size_t size, int flags,
+    const char *func, int line, int node)
+{
+	void *ptr = NULL;
+	kmem_debug_t *dptr;
+	unsigned long irq_flags;
+
+	dptr = kmalloc(sizeof (kmem_debug_t), kmem_flags_convert(flags));
+	if (dptr == NULL)
+		return (NULL);
+
+	dptr->kd_func = __strdup(func, flags);
+	if (dptr->kd_func == NULL) {
+		kfree(dptr);
+		return (NULL);
+	}
+
+	ptr = spl_kmem_alloc_debug(size, flags, node);
+	if (ptr == NULL) {
+		kfree(dptr->kd_func);
+		kfree(dptr);
+		return (NULL);
+	}
+
+	INIT_HLIST_NODE(&dptr->kd_hlist);
+	INIT_LIST_HEAD(&dptr->kd_list);
+
+	dptr->kd_addr = ptr;
+	dptr->kd_size = size;
+	dptr->kd_line = line;
+
+	spin_lock_irqsave(&kmem_lock, irq_flags);
+	hlist_add_head(&dptr->kd_hlist,
+	    &kmem_table[hash_ptr(ptr, KMEM_HASH_BITS)]);
+	list_add_tail(&dptr->kd_list, &kmem_list);
+	spin_unlock_irqrestore(&kmem_lock, irq_flags);
+
+	return (ptr);
+}
+
+inline void
+spl_kmem_free_track(const void *ptr, size_t size)
+{
+	kmem_debug_t *dptr;
+
+	/* Must exist in hash due to kmem_alloc() */
+	dptr = kmem_del_init(&kmem_lock, kmem_table, KMEM_HASH_BITS, ptr);
+	ASSERT3P(dptr, !=, NULL);
+	ASSERT3S(dptr->kd_size, ==, size);
+
+	kfree(dptr->kd_func);
+	kfree(dptr);
+
+	spl_kmem_free_debug(ptr, size);
+}
+#endif /* DEBUG_KMEM_TRACKING */
+#endif /* DEBUG_KMEM */
+
+/*
+ * Public kmem_alloc(), kmem_zalloc() and kmem_free() interfaces.
+ */
+void *
+spl_kmem_alloc(size_t size, int flags, const char *func, int line)
+{
+	ASSERT0(flags & ~KM_PUBLIC_MASK);
+
+#if !defined(DEBUG_KMEM)
+	return (spl_kmem_alloc_impl(size, flags, NUMA_NO_NODE));
+#elif !defined(DEBUG_KMEM_TRACKING)
+	return (spl_kmem_alloc_debug(size, flags, NUMA_NO_NODE));
+#else
+	return (spl_kmem_alloc_track(size, flags, func, line, NUMA_NO_NODE));
+#endif
+}
+EXPORT_SYMBOL(spl_kmem_alloc);
+
+void *
+spl_kmem_zalloc(size_t size, int flags, const char *func, int line)
+{
+	ASSERT0(flags & ~KM_PUBLIC_MASK);
+
+	flags |= KM_ZERO;
+
+#if !defined(DEBUG_KMEM)
+	return (spl_kmem_alloc_impl(size, flags, NUMA_NO_NODE));
+#elif !defined(DEBUG_KMEM_TRACKING)
+	return (spl_kmem_alloc_debug(size, flags, NUMA_NO_NODE));
+#else
+	return (spl_kmem_alloc_track(size, flags, func, line, NUMA_NO_NODE));
+#endif
+}
+EXPORT_SYMBOL(spl_kmem_zalloc);
+
+void
+spl_kmem_free(const void *buf, size_t size)
+{
+#if !defined(DEBUG_KMEM)
+	return (spl_kmem_free_impl(buf, size));
+#elif !defined(DEBUG_KMEM_TRACKING)
+	return (spl_kmem_free_debug(buf, size));
+#else
+	return (spl_kmem_free_track(buf, size));
+#endif
+}
+EXPORT_SYMBOL(spl_kmem_free);
+
+#if defined(DEBUG_KMEM) && defined(DEBUG_KMEM_TRACKING)
+static char *
+spl_sprintf_addr(kmem_debug_t *kd, char *str, int len, int min)
+{
+	int size = ((len - 1) < kd->kd_size) ? (len - 1) : kd->kd_size;
+	int i, flag = 1;
+
+	ASSERT(str != NULL && len >= 17);
+	memset(str, 0, len);
+
+	/*
+	 * Check for a fully printable string, and while we are at
+	 * it place the printable characters in the passed buffer.
+	 */
+	for (i = 0; i < size; i++) {
+		str[i] = ((char *)(kd->kd_addr))[i];
+		if (isprint(str[i])) {
+			continue;
+		} else {
+			/*
+			 * Minimum number of printable characters found
+			 * to make it worthwhile to print this as ascii.
+			 */
+			if (i > min)
+				break;
+
+			flag = 0;
+			break;
+		}
+	}
+
+	if (!flag) {
+		sprintf(str, "%02x%02x%02x%02x%02x%02x%02x%02x",
+		    *((uint8_t *)kd->kd_addr),
+		    *((uint8_t *)kd->kd_addr + 2),
+		    *((uint8_t *)kd->kd_addr + 4),
+		    *((uint8_t *)kd->kd_addr + 6),
+		    *((uint8_t *)kd->kd_addr + 8),
+		    *((uint8_t *)kd->kd_addr + 10),
+		    *((uint8_t *)kd->kd_addr + 12),
+		    *((uint8_t *)kd->kd_addr + 14));
+	}
+
+	return (str);
+}
+
+static int
+spl_kmem_init_tracking(struct list_head *list, spinlock_t *lock, int size)
+{
+	int i;
+
+	spin_lock_init(lock);
+	INIT_LIST_HEAD(list);
+
+	for (i = 0; i < size; i++)
+		INIT_HLIST_HEAD(&kmem_table[i]);
+
+	return (0);
+}
+
+static void
+spl_kmem_fini_tracking(struct list_head *list, spinlock_t *lock)
+{
+	unsigned long flags;
+	kmem_debug_t *kd;
+	char str[17];
+
+	spin_lock_irqsave(lock, flags);
+	if (!list_empty(list))
+		printk(KERN_WARNING "%-16s %-5s %-16s %s:%s\n", "address",
+		    "size", "data", "func", "line");
+
+	list_for_each_entry(kd, list, kd_list)
+		printk(KERN_WARNING "%p %-5d %-16s %s:%d\n", kd->kd_addr,
+		    (int)kd->kd_size, spl_sprintf_addr(kd, str, 17, 8),
+		    kd->kd_func, kd->kd_line);
+
+	spin_unlock_irqrestore(lock, flags);
+}
+#endif /* DEBUG_KMEM && DEBUG_KMEM_TRACKING */
+
+int
+spl_kmem_init(void)
+{
+#ifdef DEBUG_KMEM
+	kmem_alloc_used_set(0);
+
+#ifdef DEBUG_KMEM_TRACKING
+	spl_kmem_init_tracking(&kmem_list, &kmem_lock, KMEM_TABLE_SIZE);
+#endif /* DEBUG_KMEM_TRACKING */
+#endif /* DEBUG_KMEM */
+
+	return (0);
+}
+
+void
+spl_kmem_fini(void)
+{
+#ifdef DEBUG_KMEM
+	/*
+	 * Display all unreclaimed memory addresses, including the
+	 * allocation size and the first few bytes of what's located
+	 * at that address to aid in debugging.  Performance is not
+	 * a serious concern here since it is module unload time.
+	 */
+	if (kmem_alloc_used_read() != 0)
+		printk(KERN_WARNING "kmem leaked %ld/%llu bytes\n",
+		    (unsigned long)kmem_alloc_used_read(), kmem_alloc_max);
+
+#ifdef DEBUG_KMEM_TRACKING
+	spl_kmem_fini_tracking(&kmem_list, &kmem_lock);
+#endif /* DEBUG_KMEM_TRACKING */
+#endif /* DEBUG_KMEM */
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/module/spl/spl-kobj.c
@@ -0,0 +1,81 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+ *****************************************************************************
+ *  Solaris Porting Layer (SPL) Kobj Implementation.
+\*****************************************************************************/
+
+#include <sys/kobj.h>
+
+struct _buf *
+kobj_open_file(const char *name)
+{
+	struct _buf *file;
+	vnode_t *vp;
+	int rc;
+
+	file = kmalloc(sizeof(_buf_t), kmem_flags_convert(KM_SLEEP));
+	if (file == NULL)
+		return ((_buf_t *)-1UL);
+
+	if ((rc = vn_open(name, UIO_SYSSPACE, FREAD, 0644, &vp, 0, 0))) {
+		kfree(file);
+		return ((_buf_t *)-1UL);
+	}
+
+	file->vp = vp;
+
+	return (file);
+} /* kobj_open_file() */
+EXPORT_SYMBOL(kobj_open_file);
+
+void
+kobj_close_file(struct _buf *file)
+{
+	VOP_CLOSE(file->vp, 0, 0, 0, 0, 0);
+        kfree(file);
+} /* kobj_close_file() */
+EXPORT_SYMBOL(kobj_close_file);
+
+int
+kobj_read_file(struct _buf *file, char *buf, ssize_t size, offset_t off)
+{
+	return (vn_rdwr(UIO_READ, file->vp, buf, size, off,
+	       UIO_SYSSPACE, 0, RLIM64_INFINITY, 0, NULL));
+} /* kobj_read_file() */
+EXPORT_SYMBOL(kobj_read_file);
+
+int
+kobj_get_filesize(struct _buf *file, uint64_t *size)
+{
+        vattr_t vap;
+	int rc;
+
+	rc = VOP_GETATTR(file->vp, &vap, 0, 0, NULL);
+	if (rc)
+		return (rc);
+
+        *size = vap.va_size;
+
+        return (rc);
+} /* kobj_get_filesize() */
+EXPORT_SYMBOL(kobj_get_filesize);
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/module/spl/spl-kstat.c
@@ -0,0 +1,696 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+ *****************************************************************************
+ *  Solaris Porting Layer (SPL) Kstat Implementation.
+\*****************************************************************************/
+
+#include <linux/seq_file.h>
+#include <sys/kstat.h>
+#include <sys/vmem.h>
+
+#ifndef HAVE_PDE_DATA
+#define PDE_DATA(x) (PDE(x)->data)
+#endif
+
+static kmutex_t kstat_module_lock;
+static struct list_head kstat_module_list;
+static kid_t kstat_id;
+
+static int
+kstat_resize_raw(kstat_t *ksp)
+{
+	if (ksp->ks_raw_bufsize == KSTAT_RAW_MAX)
+		return ENOMEM;
+
+	vmem_free(ksp->ks_raw_buf, ksp->ks_raw_bufsize);
+	ksp->ks_raw_bufsize = MIN(ksp->ks_raw_bufsize * 2, KSTAT_RAW_MAX);
+	ksp->ks_raw_buf = vmem_alloc(ksp->ks_raw_bufsize, KM_SLEEP);
+
+	return 0;
+}
+
+void
+kstat_waitq_enter(kstat_io_t *kiop)
+{
+	hrtime_t new, delta;
+	ulong_t wcnt;
+
+	new = gethrtime();
+	delta = new - kiop->wlastupdate;
+	kiop->wlastupdate = new;
+	wcnt = kiop->wcnt++;
+	if (wcnt != 0) {
+		kiop->wlentime += delta * wcnt;
+		kiop->wtime += delta;
+	}
+}
+EXPORT_SYMBOL(kstat_waitq_enter);
+
+void
+kstat_waitq_exit(kstat_io_t *kiop)
+{
+	hrtime_t new, delta;
+	ulong_t wcnt;
+
+	new = gethrtime();
+	delta = new - kiop->wlastupdate;
+	kiop->wlastupdate = new;
+	wcnt = kiop->wcnt--;
+	ASSERT((int)wcnt > 0);
+	kiop->wlentime += delta * wcnt;
+	kiop->wtime += delta;
+}
+EXPORT_SYMBOL(kstat_waitq_exit);
+
+void
+kstat_runq_enter(kstat_io_t *kiop)
+{
+	hrtime_t new, delta;
+	ulong_t rcnt;
+
+	new = gethrtime();
+	delta = new - kiop->rlastupdate;
+	kiop->rlastupdate = new;
+	rcnt = kiop->rcnt++;
+	if (rcnt != 0) {
+		kiop->rlentime += delta * rcnt;
+		kiop->rtime += delta;
+	}
+}
+EXPORT_SYMBOL(kstat_runq_enter);
+
+void
+kstat_runq_exit(kstat_io_t *kiop)
+{
+	hrtime_t new, delta;
+	ulong_t rcnt;
+
+	new = gethrtime();
+	delta = new - kiop->rlastupdate;
+	kiop->rlastupdate = new;
+	rcnt = kiop->rcnt--;
+	ASSERT((int)rcnt > 0);
+	kiop->rlentime += delta * rcnt;
+	kiop->rtime += delta;
+}
+EXPORT_SYMBOL(kstat_runq_exit);
+
+static int
+kstat_seq_show_headers(struct seq_file *f)
+{
+        kstat_t *ksp = (kstat_t *)f->private;
+	int rc = 0;
+
+        ASSERT(ksp->ks_magic == KS_MAGIC);
+
+        seq_printf(f, "%d %d 0x%02x %d %d %lld %lld\n",
+		   ksp->ks_kid, ksp->ks_type, ksp->ks_flags,
+		   ksp->ks_ndata, (int)ksp->ks_data_size,
+		   ksp->ks_crtime, ksp->ks_snaptime);
+
+	switch (ksp->ks_type) {
+                case KSTAT_TYPE_RAW:
+restart:
+                        if (ksp->ks_raw_ops.headers) {
+                                rc = ksp->ks_raw_ops.headers(
+                                    ksp->ks_raw_buf, ksp->ks_raw_bufsize);
+				if (rc == ENOMEM && !kstat_resize_raw(ksp))
+					goto restart;
+				if (!rc)
+	                                seq_puts(f, ksp->ks_raw_buf);
+                        } else {
+                                seq_printf(f, "raw data\n");
+                        }
+                        break;
+                case KSTAT_TYPE_NAMED:
+                        seq_printf(f, "%-31s %-4s %s\n",
+                                   "name", "type", "data");
+                        break;
+                case KSTAT_TYPE_INTR:
+                        seq_printf(f, "%-8s %-8s %-8s %-8s %-8s\n",
+                                   "hard", "soft", "watchdog",
+                                   "spurious", "multsvc");
+                        break;
+                case KSTAT_TYPE_IO:
+                        seq_printf(f,
+                                   "%-8s %-8s %-8s %-8s %-8s %-8s "
+                                   "%-8s %-8s %-8s %-8s %-8s %-8s\n",
+                                   "nread", "nwritten", "reads", "writes",
+                                   "wtime", "wlentime", "wupdate",
+                                   "rtime", "rlentime", "rupdate",
+                                   "wcnt", "rcnt");
+                        break;
+                case KSTAT_TYPE_TIMER:
+                        seq_printf(f,
+                                   "%-31s %-8s "
+                                   "%-8s %-8s %-8s %-8s %-8s\n",
+                                   "name", "events", "elapsed",
+                                   "min", "max", "start", "stop");
+                        break;
+                default:
+                        PANIC("Undefined kstat type %d\n", ksp->ks_type);
+        }
+
+	return -rc;
+}
+
+static int
+kstat_seq_show_raw(struct seq_file *f, unsigned char *p, int l)
+{
+        int i, j;
+
+        for (i = 0; ; i++) {
+                seq_printf(f, "%03x:", i);
+
+                for (j = 0; j < 16; j++) {
+                        if (i * 16 + j >= l) {
+                                seq_printf(f, "\n");
+                                goto out;
+                        }
+
+                        seq_printf(f, " %02x", (unsigned char)p[i * 16 + j]);
+                }
+                seq_printf(f, "\n");
+        }
+out:
+        return 0;
+}
+
+static int
+kstat_seq_show_named(struct seq_file *f, kstat_named_t *knp)
+{
+        seq_printf(f, "%-31s %-4d ", knp->name, knp->data_type);
+
+        switch (knp->data_type) {
+                case KSTAT_DATA_CHAR:
+                        knp->value.c[15] = '\0'; /* NULL terminate */
+                        seq_printf(f, "%-16s", knp->value.c);
+                        break;
+                /* XXX - We need to be more careful able what tokens are
+                 * used for each arch, for now this is correct for x86_64.
+                 */
+                case KSTAT_DATA_INT32:
+                        seq_printf(f, "%d", knp->value.i32);
+                        break;
+                case KSTAT_DATA_UINT32:
+                        seq_printf(f, "%u", knp->value.ui32);
+                        break;
+                case KSTAT_DATA_INT64:
+                        seq_printf(f, "%lld", (signed long long)knp->value.i64);
+                        break;
+                case KSTAT_DATA_UINT64:
+                        seq_printf(f, "%llu", (unsigned long long)knp->value.ui64);
+                        break;
+                case KSTAT_DATA_LONG:
+                        seq_printf(f, "%ld", knp->value.l);
+                        break;
+                case KSTAT_DATA_ULONG:
+                        seq_printf(f, "%lu", knp->value.ul);
+                        break;
+                case KSTAT_DATA_STRING:
+                        KSTAT_NAMED_STR_PTR(knp)
+                                [KSTAT_NAMED_STR_BUFLEN(knp)-1] = '\0';
+                        seq_printf(f, "%s", KSTAT_NAMED_STR_PTR(knp));
+                        break;
+                default:
+                        PANIC("Undefined kstat data type %d\n", knp->data_type);
+        }
+
+        seq_printf(f, "\n");
+
+        return 0;
+}
+
+static int
+kstat_seq_show_intr(struct seq_file *f, kstat_intr_t *kip)
+{
+        seq_printf(f, "%-8u %-8u %-8u %-8u %-8u\n",
+                   kip->intrs[KSTAT_INTR_HARD],
+                   kip->intrs[KSTAT_INTR_SOFT],
+                   kip->intrs[KSTAT_INTR_WATCHDOG],
+                   kip->intrs[KSTAT_INTR_SPURIOUS],
+                   kip->intrs[KSTAT_INTR_MULTSVC]);
+
+        return 0;
+}
+
+static int
+kstat_seq_show_io(struct seq_file *f, kstat_io_t *kip)
+{
+        seq_printf(f,
+                   "%-8llu %-8llu %-8u %-8u %-8lld %-8lld "
+                   "%-8lld %-8lld %-8lld %-8lld %-8u %-8u\n",
+                   kip->nread, kip->nwritten,
+                   kip->reads, kip->writes,
+                   kip->wtime, kip->wlentime, kip->wlastupdate,
+                   kip->rtime, kip->wlentime, kip->rlastupdate,
+                   kip->wcnt,  kip->rcnt);
+
+        return 0;
+}
+
+static int
+kstat_seq_show_timer(struct seq_file *f, kstat_timer_t *ktp)
+{
+        seq_printf(f,
+                   "%-31s %-8llu %-8lld %-8lld %-8lld %-8lld %-8lld\n",
+                   ktp->name, ktp->num_events, ktp->elapsed_time,
+                   ktp->min_time, ktp->max_time,
+                   ktp->start_time, ktp->stop_time);
+
+        return 0;
+}
+
+static int
+kstat_seq_show(struct seq_file *f, void *p)
+{
+        kstat_t *ksp = (kstat_t *)f->private;
+        int rc = 0;
+
+        ASSERT(ksp->ks_magic == KS_MAGIC);
+
+	switch (ksp->ks_type) {
+                case KSTAT_TYPE_RAW:
+restart:
+                        if (ksp->ks_raw_ops.data) {
+                                rc = ksp->ks_raw_ops.data(
+				    ksp->ks_raw_buf, ksp->ks_raw_bufsize, p);
+				if (rc == ENOMEM && !kstat_resize_raw(ksp))
+					goto restart;
+				if (!rc)
+	                                seq_puts(f, ksp->ks_raw_buf);
+                        } else {
+                                ASSERT(ksp->ks_ndata == 1);
+                                rc = kstat_seq_show_raw(f, ksp->ks_data,
+                                                        ksp->ks_data_size);
+                        }
+                        break;
+                case KSTAT_TYPE_NAMED:
+                        rc = kstat_seq_show_named(f, (kstat_named_t *)p);
+                        break;
+                case KSTAT_TYPE_INTR:
+                        rc = kstat_seq_show_intr(f, (kstat_intr_t *)p);
+                        break;
+                case KSTAT_TYPE_IO:
+                        rc = kstat_seq_show_io(f, (kstat_io_t *)p);
+                        break;
+                case KSTAT_TYPE_TIMER:
+                        rc = kstat_seq_show_timer(f, (kstat_timer_t *)p);
+                        break;
+                default:
+                        PANIC("Undefined kstat type %d\n", ksp->ks_type);
+        }
+
+        return -rc;
+}
+
+int
+kstat_default_update(kstat_t *ksp, int rw)
+{
+	ASSERT(ksp != NULL);
+
+	if (rw == KSTAT_WRITE)
+		return (EACCES);
+
+	return 0;
+}
+
+static void *
+kstat_seq_data_addr(kstat_t *ksp, loff_t n)
+{
+        void *rc = NULL;
+
+	switch (ksp->ks_type) {
+                case KSTAT_TYPE_RAW:
+                        if (ksp->ks_raw_ops.addr)
+                                rc = ksp->ks_raw_ops.addr(ksp, n);
+                        else
+                                rc = ksp->ks_data;
+                        break;
+                case KSTAT_TYPE_NAMED:
+                        rc = ksp->ks_data + n * sizeof(kstat_named_t);
+                        break;
+                case KSTAT_TYPE_INTR:
+                        rc = ksp->ks_data + n * sizeof(kstat_intr_t);
+                        break;
+                case KSTAT_TYPE_IO:
+                        rc = ksp->ks_data + n * sizeof(kstat_io_t);
+                        break;
+                case KSTAT_TYPE_TIMER:
+                        rc = ksp->ks_data + n * sizeof(kstat_timer_t);
+                        break;
+                default:
+                        PANIC("Undefined kstat type %d\n", ksp->ks_type);
+        }
+
+        return (rc);
+}
+
+static void *
+kstat_seq_start(struct seq_file *f, loff_t *pos)
+{
+        loff_t n = *pos;
+        kstat_t *ksp = (kstat_t *)f->private;
+        ASSERT(ksp->ks_magic == KS_MAGIC);
+
+	mutex_enter(ksp->ks_lock);
+
+        if (ksp->ks_type == KSTAT_TYPE_RAW) {
+                ksp->ks_raw_bufsize = PAGE_SIZE;
+                ksp->ks_raw_buf = vmem_alloc(ksp->ks_raw_bufsize, KM_SLEEP);
+        }
+
+        /* Dynamically update kstat, on error existing kstats are used */
+        (void) ksp->ks_update(ksp, KSTAT_READ);
+
+	ksp->ks_snaptime = gethrtime();
+
+        if (!n && kstat_seq_show_headers(f))
+		return (NULL);
+
+        if (n >= ksp->ks_ndata)
+                return (NULL);
+
+        return (kstat_seq_data_addr(ksp, n));
+}
+
+static void *
+kstat_seq_next(struct seq_file *f, void *p, loff_t *pos)
+{
+        kstat_t *ksp = (kstat_t *)f->private;
+        ASSERT(ksp->ks_magic == KS_MAGIC);
+
+        ++*pos;
+        if (*pos >= ksp->ks_ndata)
+                return (NULL);
+
+        return (kstat_seq_data_addr(ksp, *pos));
+}
+
+static void
+kstat_seq_stop(struct seq_file *f, void *v)
+{
+	kstat_t *ksp = (kstat_t *)f->private;
+	ASSERT(ksp->ks_magic == KS_MAGIC);
+
+	if (ksp->ks_type == KSTAT_TYPE_RAW)
+		vmem_free(ksp->ks_raw_buf, ksp->ks_raw_bufsize);
+
+	mutex_exit(ksp->ks_lock);
+}
+
+static struct seq_operations kstat_seq_ops = {
+        .show  = kstat_seq_show,
+        .start = kstat_seq_start,
+        .next  = kstat_seq_next,
+        .stop  = kstat_seq_stop,
+};
+
+static kstat_module_t *
+kstat_find_module(char *name)
+{
+	kstat_module_t *module;
+
+	list_for_each_entry(module, &kstat_module_list, ksm_module_list)
+		if (strncmp(name, module->ksm_name, KSTAT_STRLEN) == 0)
+			return (module);
+
+	return (NULL);
+}
+
+static kstat_module_t *
+kstat_create_module(char *name)
+{
+	kstat_module_t *module;
+	struct proc_dir_entry *pde;
+
+	pde = proc_mkdir(name, proc_spl_kstat);
+	if (pde == NULL)
+		return (NULL);
+
+	module = kmem_alloc(sizeof (kstat_module_t), KM_SLEEP);
+	module->ksm_proc = pde;
+	strlcpy(module->ksm_name, name, KSTAT_STRLEN+1);
+	INIT_LIST_HEAD(&module->ksm_kstat_list);
+	list_add_tail(&module->ksm_module_list, &kstat_module_list);
+
+	return (module);
+
+}
+
+static void
+kstat_delete_module(kstat_module_t *module)
+{
+	ASSERT(list_empty(&module->ksm_kstat_list));
+	remove_proc_entry(module->ksm_name, proc_spl_kstat);
+	list_del(&module->ksm_module_list);
+	kmem_free(module, sizeof(kstat_module_t));
+}
+
+static int
+proc_kstat_open(struct inode *inode, struct file *filp)
+{
+        struct seq_file *f;
+        int rc;
+
+        rc = seq_open(filp, &kstat_seq_ops);
+        if (rc)
+                return rc;
+
+        f = filp->private_data;
+        f->private = PDE_DATA(inode);
+
+        return rc;
+}
+
+static ssize_t
+proc_kstat_write(struct file *filp, const char __user *buf,
+		 size_t len, loff_t *ppos)
+{
+	struct seq_file *f = filp->private_data;
+	kstat_t *ksp = f->private;
+	int rc;
+
+	ASSERT(ksp->ks_magic == KS_MAGIC);
+
+	mutex_enter(ksp->ks_lock);
+	rc = ksp->ks_update(ksp, KSTAT_WRITE);
+	mutex_exit(ksp->ks_lock);
+
+	if (rc)
+		return (-rc);
+
+	*ppos += len;
+	return (len);
+}
+
+static struct file_operations proc_kstat_operations = {
+	.open		= proc_kstat_open,
+	.write		= proc_kstat_write,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= seq_release,
+};
+
+void
+__kstat_set_raw_ops(kstat_t *ksp,
+		    int (*headers)(char *buf, size_t size),
+		    int (*data)(char *buf, size_t size, void *data),
+		    void *(*addr)(kstat_t *ksp, loff_t index))
+{
+	ksp->ks_raw_ops.headers = headers;
+	ksp->ks_raw_ops.data    = data;
+	ksp->ks_raw_ops.addr    = addr;
+}
+EXPORT_SYMBOL(__kstat_set_raw_ops);
+
+kstat_t *
+__kstat_create(const char *ks_module, int ks_instance, const char *ks_name,
+             const char *ks_class, uchar_t ks_type, uint_t ks_ndata,
+             uchar_t ks_flags)
+{
+	kstat_t *ksp;
+
+	ASSERT(ks_module);
+	ASSERT(ks_instance == 0);
+	ASSERT(ks_name);
+	ASSERT(!(ks_flags & KSTAT_FLAG_UNSUPPORTED));
+
+	if ((ks_type == KSTAT_TYPE_INTR) || (ks_type == KSTAT_TYPE_IO))
+                ASSERT(ks_ndata == 1);
+
+	ksp = kmem_zalloc(sizeof(*ksp), KM_SLEEP);
+	if (ksp == NULL)
+		return ksp;
+
+	mutex_enter(&kstat_module_lock);
+	ksp->ks_kid = kstat_id;
+        kstat_id++;
+	mutex_exit(&kstat_module_lock);
+
+        ksp->ks_magic = KS_MAGIC;
+	mutex_init(&ksp->ks_private_lock, NULL, MUTEX_DEFAULT, NULL);
+	ksp->ks_lock = &ksp->ks_private_lock;
+	INIT_LIST_HEAD(&ksp->ks_list);
+
+	ksp->ks_crtime = gethrtime();
+        ksp->ks_snaptime = ksp->ks_crtime;
+	strncpy(ksp->ks_module, ks_module, KSTAT_STRLEN);
+	ksp->ks_instance = ks_instance;
+	strncpy(ksp->ks_name, ks_name, KSTAT_STRLEN);
+	strncpy(ksp->ks_class, ks_class, KSTAT_STRLEN);
+	ksp->ks_type = ks_type;
+	ksp->ks_flags = ks_flags;
+	ksp->ks_update = kstat_default_update;
+	ksp->ks_private = NULL;
+	ksp->ks_raw_ops.headers = NULL;
+	ksp->ks_raw_ops.data = NULL;
+	ksp->ks_raw_ops.addr = NULL;
+	ksp->ks_raw_buf = NULL;
+	ksp->ks_raw_bufsize = 0;
+
+	switch (ksp->ks_type) {
+                case KSTAT_TYPE_RAW:
+	                ksp->ks_ndata = 1;
+                        ksp->ks_data_size = ks_ndata;
+                        break;
+                case KSTAT_TYPE_NAMED:
+	                ksp->ks_ndata = ks_ndata;
+                        ksp->ks_data_size = ks_ndata * sizeof(kstat_named_t);
+                        break;
+                case KSTAT_TYPE_INTR:
+	                ksp->ks_ndata = ks_ndata;
+                        ksp->ks_data_size = ks_ndata * sizeof(kstat_intr_t);
+                        break;
+                case KSTAT_TYPE_IO:
+	                ksp->ks_ndata = ks_ndata;
+                        ksp->ks_data_size = ks_ndata * sizeof(kstat_io_t);
+                        break;
+                case KSTAT_TYPE_TIMER:
+	                ksp->ks_ndata = ks_ndata;
+                        ksp->ks_data_size = ks_ndata * sizeof(kstat_timer_t);
+                        break;
+                default:
+                        PANIC("Undefined kstat type %d\n", ksp->ks_type);
+        }
+
+	if (ksp->ks_flags & KSTAT_FLAG_VIRTUAL) {
+                ksp->ks_data = NULL;
+        } else {
+                ksp->ks_data = kmem_zalloc(ksp->ks_data_size, KM_SLEEP);
+                if (ksp->ks_data == NULL) {
+                        kmem_free(ksp, sizeof(*ksp));
+                        ksp = NULL;
+                }
+        }
+
+	return ksp;
+}
+EXPORT_SYMBOL(__kstat_create);
+
+void
+__kstat_install(kstat_t *ksp)
+{
+	kstat_module_t *module;
+	kstat_t *tmp;
+
+	ASSERT(ksp);
+
+	mutex_enter(&kstat_module_lock);
+
+	module = kstat_find_module(ksp->ks_module);
+	if (module == NULL) {
+		module = kstat_create_module(ksp->ks_module);
+		if (module == NULL)
+			goto out;
+	}
+
+	/*
+	 * Only one entry by this name per-module, on failure the module
+	 * shouldn't be deleted because we know it has at least one entry.
+	 */
+	list_for_each_entry(tmp, &module->ksm_kstat_list, ks_list)
+		if (strncmp(tmp->ks_name, ksp->ks_name, KSTAT_STRLEN) == 0)
+			goto out;
+
+	list_add_tail(&ksp->ks_list, &module->ksm_kstat_list);
+
+	mutex_enter(ksp->ks_lock);
+	ksp->ks_owner = module;
+	ksp->ks_proc = proc_create_data(ksp->ks_name, 0644,
+	    module->ksm_proc, &proc_kstat_operations, (void *)ksp);
+	if (ksp->ks_proc == NULL) {
+		list_del_init(&ksp->ks_list);
+		if (list_empty(&module->ksm_kstat_list))
+			kstat_delete_module(module);
+	}
+	mutex_exit(ksp->ks_lock);
+out:
+	mutex_exit(&kstat_module_lock);
+}
+EXPORT_SYMBOL(__kstat_install);
+
+void
+__kstat_delete(kstat_t *ksp)
+{
+	kstat_module_t *module = ksp->ks_owner;
+
+	mutex_enter(&kstat_module_lock);
+	list_del_init(&ksp->ks_list);
+	mutex_exit(&kstat_module_lock);
+
+	if (ksp->ks_proc) {
+		remove_proc_entry(ksp->ks_name, module->ksm_proc);
+
+		/* Remove top level module directory if it's empty */
+		if (list_empty(&module->ksm_kstat_list))
+			kstat_delete_module(module);
+	}
+
+	if (!(ksp->ks_flags & KSTAT_FLAG_VIRTUAL))
+		kmem_free(ksp->ks_data, ksp->ks_data_size);
+
+	ksp->ks_lock = NULL;
+	mutex_destroy(&ksp->ks_private_lock);
+	kmem_free(ksp, sizeof(*ksp));
+
+	return;
+}
+EXPORT_SYMBOL(__kstat_delete);
+
+int
+spl_kstat_init(void)
+{
+	mutex_init(&kstat_module_lock, NULL, MUTEX_DEFAULT, NULL);
+	INIT_LIST_HEAD(&kstat_module_list);
+        kstat_id = 0;
+	return (0);
+}
+
+void
+spl_kstat_fini(void)
+{
+	ASSERT(list_empty(&kstat_module_list));
+	mutex_destroy(&kstat_module_lock);
+}
+
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/module/spl/spl-mutex.c
@@ -0,0 +1,36 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+ *****************************************************************************
+ *  Solaris Porting Layer (SPL) Mutex Implementation.
+\*****************************************************************************/
+
+#include <sys/mutex.h>
+
+#ifdef DEBUG_SUBSYSTEM
+#undef DEBUG_SUBSYSTEM
+#endif
+
+#define DEBUG_SUBSYSTEM S_MUTEX
+
+int spl_mutex_init(void) { return 0; }
+void spl_mutex_fini(void) { }
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/module/spl/spl-proc.c
@@ -0,0 +1,519 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+ *****************************************************************************
+ *  Solaris Porting Layer (SPL) Proc Implementation.
+\*****************************************************************************/
+
+#include <sys/systeminfo.h>
+#include <sys/kstat.h>
+#include <sys/kmem.h>
+#include <sys/kmem_cache.h>
+#include <sys/vmem.h>
+#include <linux/ctype.h>
+#include <linux/kmod.h>
+#include <linux/seq_file.h>
+#include <linux/proc_compat.h>
+#include <linux/uaccess.h>
+#include <linux/version.h>
+
+#if defined(CONSTIFY_PLUGIN) && LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
+typedef struct ctl_table __no_const spl_ctl_table;
+#else
+typedef struct ctl_table spl_ctl_table;
+#endif
+
+static unsigned long table_min = 0;
+static unsigned long table_max = ~0;
+
+static struct ctl_table_header *spl_header = NULL;
+static struct proc_dir_entry *proc_spl = NULL;
+static struct proc_dir_entry *proc_spl_kmem = NULL;
+static struct proc_dir_entry *proc_spl_kmem_slab = NULL;
+struct proc_dir_entry *proc_spl_kstat = NULL;
+
+static int
+proc_copyin_string(char *kbuffer, int kbuffer_size,
+                   const char *ubuffer, int ubuffer_size)
+{
+        int size;
+
+        if (ubuffer_size > kbuffer_size)
+                return -EOVERFLOW;
+
+        if (copy_from_user((void *)kbuffer, (void *)ubuffer, ubuffer_size))
+                return -EFAULT;
+
+        /* strip trailing whitespace */
+        size = strnlen(kbuffer, ubuffer_size);
+        while (size-- >= 0)
+                if (!isspace(kbuffer[size]))
+                        break;
+
+        /* empty string */
+        if (size < 0)
+                return -EINVAL;
+
+        /* no space to terminate */
+        if (size == kbuffer_size)
+                return -EOVERFLOW;
+
+        kbuffer[size + 1] = 0;
+        return 0;
+}
+
+static int
+proc_copyout_string(char *ubuffer, int ubuffer_size,
+                    const char *kbuffer, char *append)
+{
+        /* NB if 'append' != NULL, it's a single character to append to the
+         * copied out string - usually "\n", for /proc entries and
+         * (i.e. a terminating zero byte) for sysctl entries
+         */
+        int size = MIN(strlen(kbuffer), ubuffer_size);
+
+        if (copy_to_user(ubuffer, kbuffer, size))
+                return -EFAULT;
+
+        if (append != NULL && size < ubuffer_size) {
+                if (copy_to_user(ubuffer + size, append, 1))
+                        return -EFAULT;
+
+                size++;
+        }
+
+        return size;
+}
+
+#ifdef DEBUG_KMEM
+static int
+proc_domemused(struct ctl_table *table, int write,
+    void __user *buffer, size_t *lenp, loff_t *ppos)
+{
+        int rc = 0;
+        unsigned long min = 0, max = ~0, val;
+        spl_ctl_table dummy = *table;
+
+        dummy.data = &val;
+        dummy.proc_handler = &proc_dointvec;
+        dummy.extra1 = &min;
+        dummy.extra2 = &max;
+
+        if (write) {
+                *ppos += *lenp;
+        } else {
+# ifdef HAVE_ATOMIC64_T
+                val = atomic64_read((atomic64_t *)table->data);
+# else
+                val = atomic_read((atomic_t *)table->data);
+# endif /* HAVE_ATOMIC64_T */
+                rc = proc_doulongvec_minmax(&dummy, write, buffer, lenp, ppos);
+        }
+
+        return (rc);
+}
+#endif /* DEBUG_KMEM */
+
+static int
+proc_doslab(struct ctl_table *table, int write,
+    void __user *buffer, size_t *lenp, loff_t *ppos)
+{
+        int rc = 0;
+        unsigned long min = 0, max = ~0, val = 0, mask;
+        spl_ctl_table dummy = *table;
+        spl_kmem_cache_t *skc;
+
+        dummy.data = &val;
+        dummy.proc_handler = &proc_dointvec;
+        dummy.extra1 = &min;
+        dummy.extra2 = &max;
+
+        if (write) {
+                *ppos += *lenp;
+        } else {
+                down_read(&spl_kmem_cache_sem);
+                mask = (unsigned long)table->data;
+
+                list_for_each_entry(skc, &spl_kmem_cache_list, skc_list) {
+
+			/* Only use slabs of the correct kmem/vmem type */
+			if (!(skc->skc_flags & mask))
+				continue;
+
+			/* Sum the specified field for selected slabs */
+			switch (mask & (KMC_TOTAL | KMC_ALLOC | KMC_MAX)) {
+			case KMC_TOTAL:
+	                        val += skc->skc_slab_size * skc->skc_slab_total;
+				break;
+			case KMC_ALLOC:
+	                        val += skc->skc_obj_size * skc->skc_obj_alloc;
+				break;
+			case KMC_MAX:
+	                        val += skc->skc_obj_size * skc->skc_obj_max;
+				break;
+			}
+                }
+
+                up_read(&spl_kmem_cache_sem);
+                rc = proc_doulongvec_minmax(&dummy, write, buffer, lenp, ppos);
+        }
+
+        return (rc);
+}
+
+static int
+proc_dohostid(struct ctl_table *table, int write,
+    void __user *buffer, size_t *lenp, loff_t *ppos)
+{
+        int len, rc = 0;
+        char *end, str[32];
+
+        if (write) {
+                /* We can't use proc_doulongvec_minmax() in the write
+                 * case here because hostid while a hex value has no
+                 * leading 0x which confuses the helper function. */
+                rc = proc_copyin_string(str, sizeof(str), buffer, *lenp);
+                if (rc < 0)
+                        return (rc);
+
+                spl_hostid = simple_strtoul(str, &end, 16);
+                if (str == end)
+                        return (-EINVAL);
+
+        } else {
+                len = snprintf(str, sizeof(str), "%lx", spl_hostid);
+                if (*ppos >= len)
+                        rc = 0;
+                else
+                        rc = proc_copyout_string(buffer,*lenp,str+*ppos,"\n");
+
+                if (rc >= 0) {
+                        *lenp = rc;
+                        *ppos += rc;
+                }
+        }
+
+        return (rc);
+}
+
+static void
+slab_seq_show_headers(struct seq_file *f)
+{
+        seq_printf(f,
+            "--------------------- cache ----------"
+            "---------------------------------------------  "
+            "----- slab ------  "
+            "---- object -----  "
+            "--- emergency ---\n");
+        seq_printf(f,
+            "name                                  "
+            "  flags      size     alloc slabsize  objsize  "
+            "total alloc   max  "
+            "total alloc   max  "
+            "dlock alloc   max\n");
+}
+
+static int
+slab_seq_show(struct seq_file *f, void *p)
+{
+        spl_kmem_cache_t *skc = p;
+
+        ASSERT(skc->skc_magic == SKC_MAGIC);
+
+	/*
+	 * Backed by Linux slab see /proc/slabinfo.
+	 */
+	if (skc->skc_flags & KMC_SLAB)
+		return (0);
+
+        spin_lock(&skc->skc_lock);
+        seq_printf(f, "%-36s  ", skc->skc_name);
+        seq_printf(f, "0x%05lx %9lu %9lu %8u %8u  "
+            "%5lu %5lu %5lu  %5lu %5lu %5lu  %5lu %5lu %5lu\n",
+            (long unsigned)skc->skc_flags,
+            (long unsigned)(skc->skc_slab_size * skc->skc_slab_total),
+            (long unsigned)(skc->skc_obj_size * skc->skc_obj_alloc),
+            (unsigned)skc->skc_slab_size,
+            (unsigned)skc->skc_obj_size,
+            (long unsigned)skc->skc_slab_total,
+            (long unsigned)skc->skc_slab_alloc,
+            (long unsigned)skc->skc_slab_max,
+            (long unsigned)skc->skc_obj_total,
+            (long unsigned)skc->skc_obj_alloc,
+            (long unsigned)skc->skc_obj_max,
+            (long unsigned)skc->skc_obj_deadlock,
+            (long unsigned)skc->skc_obj_emergency,
+            (long unsigned)skc->skc_obj_emergency_max);
+
+        spin_unlock(&skc->skc_lock);
+
+        return 0;
+}
+
+static void *
+slab_seq_start(struct seq_file *f, loff_t *pos)
+{
+        struct list_head *p;
+        loff_t n = *pos;
+
+	down_read(&spl_kmem_cache_sem);
+        if (!n)
+                slab_seq_show_headers(f);
+
+        p = spl_kmem_cache_list.next;
+        while (n--) {
+                p = p->next;
+                if (p == &spl_kmem_cache_list)
+                        return (NULL);
+        }
+
+        return (list_entry(p, spl_kmem_cache_t, skc_list));
+}
+
+static void *
+slab_seq_next(struct seq_file *f, void *p, loff_t *pos)
+{
+	spl_kmem_cache_t *skc = p;
+
+        ++*pos;
+        return ((skc->skc_list.next == &spl_kmem_cache_list) ?
+	       NULL : list_entry(skc->skc_list.next,spl_kmem_cache_t,skc_list));
+}
+
+static void
+slab_seq_stop(struct seq_file *f, void *v)
+{
+	up_read(&spl_kmem_cache_sem);
+}
+
+static struct seq_operations slab_seq_ops = {
+        .show  = slab_seq_show,
+        .start = slab_seq_start,
+        .next  = slab_seq_next,
+        .stop  = slab_seq_stop,
+};
+
+static int
+proc_slab_open(struct inode *inode, struct file *filp)
+{
+        return seq_open(filp, &slab_seq_ops);
+}
+
+static struct file_operations proc_slab_operations = {
+        .open           = proc_slab_open,
+        .read           = seq_read,
+        .llseek         = seq_lseek,
+        .release        = seq_release,
+};
+
+static struct ctl_table spl_kmem_table[] = {
+#ifdef DEBUG_KMEM
+        {
+                .procname = "kmem_used",
+                .data     = &kmem_alloc_used,
+# ifdef HAVE_ATOMIC64_T
+                .maxlen   = sizeof(atomic64_t),
+# else
+                .maxlen   = sizeof(atomic_t),
+# endif /* HAVE_ATOMIC64_T */
+                .mode     = 0444,
+                .proc_handler = &proc_domemused,
+        },
+        {
+                .procname = "kmem_max",
+                .data     = &kmem_alloc_max,
+                .maxlen   = sizeof(unsigned long),
+                .extra1   = &table_min,
+                .extra2   = &table_max,
+                .mode     = 0444,
+                .proc_handler = &proc_doulongvec_minmax,
+        },
+#endif /* DEBUG_KMEM */
+        {
+                .procname = "slab_kmem_total",
+		.data     = (void *)(KMC_KMEM | KMC_TOTAL),
+                .maxlen   = sizeof(unsigned long),
+                .extra1   = &table_min,
+                .extra2   = &table_max,
+                .mode     = 0444,
+                .proc_handler = &proc_doslab,
+        },
+        {
+                .procname = "slab_kmem_alloc",
+		.data     = (void *)(KMC_KMEM | KMC_ALLOC),
+                .maxlen   = sizeof(unsigned long),
+                .extra1   = &table_min,
+                .extra2   = &table_max,
+                .mode     = 0444,
+                .proc_handler = &proc_doslab,
+        },
+        {
+                .procname = "slab_kmem_max",
+		.data     = (void *)(KMC_KMEM | KMC_MAX),
+                .maxlen   = sizeof(unsigned long),
+                .extra1   = &table_min,
+                .extra2   = &table_max,
+                .mode     = 0444,
+                .proc_handler = &proc_doslab,
+        },
+        {
+                .procname = "slab_vmem_total",
+		.data     = (void *)(KMC_VMEM | KMC_TOTAL),
+                .maxlen   = sizeof(unsigned long),
+                .extra1   = &table_min,
+                .extra2   = &table_max,
+                .mode     = 0444,
+                .proc_handler = &proc_doslab,
+        },
+        {
+                .procname = "slab_vmem_alloc",
+		.data     = (void *)(KMC_VMEM | KMC_ALLOC),
+                .maxlen   = sizeof(unsigned long),
+                .extra1   = &table_min,
+                .extra2   = &table_max,
+                .mode     = 0444,
+                .proc_handler = &proc_doslab,
+        },
+        {
+                .procname = "slab_vmem_max",
+		.data     = (void *)(KMC_VMEM | KMC_MAX),
+                .maxlen   = sizeof(unsigned long),
+                .extra1   = &table_min,
+                .extra2   = &table_max,
+                .mode     = 0444,
+                .proc_handler = &proc_doslab,
+        },
+	{0},
+};
+
+static struct ctl_table spl_kstat_table[] = {
+	{0},
+};
+
+static struct ctl_table spl_table[] = {
+        /* NB No .strategy entries have been provided since
+         * sysctl(8) prefers to go via /proc for portability.
+         */
+        {
+                .procname = "version",
+                .data     = spl_version,
+                .maxlen   = sizeof(spl_version),
+                .mode     = 0444,
+                .proc_handler = &proc_dostring,
+        },
+        {
+                .procname = "hostid",
+                .data     = &spl_hostid,
+                .maxlen   = sizeof(unsigned long),
+                .mode     = 0644,
+                .proc_handler = &proc_dohostid,
+        },
+	{
+		.procname = "kmem",
+		.mode     = 0555,
+		.child    = spl_kmem_table,
+	},
+	{
+		.procname = "kstat",
+		.mode     = 0555,
+		.child    = spl_kstat_table,
+	},
+        { 0 },
+};
+
+static struct ctl_table spl_dir[] = {
+        {
+                .procname = "spl",
+                .mode     = 0555,
+                .child    = spl_table,
+        },
+        { 0 }
+};
+
+static struct ctl_table spl_root[] = {
+	{
+#ifdef HAVE_CTL_NAME
+	.ctl_name = CTL_KERN,
+#endif
+	.procname = "kernel",
+	.mode = 0555,
+	.child = spl_dir,
+	},
+	{ 0 }
+};
+
+int
+spl_proc_init(void)
+{
+	int rc = 0;
+
+        spl_header = register_sysctl_table(spl_root);
+	if (spl_header == NULL)
+		return (-EUNATCH);
+
+	proc_spl = proc_mkdir("spl", NULL);
+	if (proc_spl == NULL) {
+		rc = -EUNATCH;
+		goto out;
+	}
+
+        proc_spl_kmem = proc_mkdir("kmem", proc_spl);
+        if (proc_spl_kmem == NULL) {
+                rc = -EUNATCH;
+		goto out;
+	}
+
+	proc_spl_kmem_slab = proc_create_data("slab", 0444,
+		proc_spl_kmem, &proc_slab_operations, NULL);
+        if (proc_spl_kmem_slab == NULL) {
+		rc = -EUNATCH;
+		goto out;
+	}
+
+        proc_spl_kstat = proc_mkdir("kstat", proc_spl);
+        if (proc_spl_kstat == NULL) {
+                rc = -EUNATCH;
+		goto out;
+	}
+out:
+	if (rc) {
+		remove_proc_entry("kstat", proc_spl);
+	        remove_proc_entry("slab", proc_spl_kmem);
+		remove_proc_entry("kmem", proc_spl);
+		remove_proc_entry("spl", NULL);
+	        unregister_sysctl_table(spl_header);
+	}
+
+        return (rc);
+}
+
+void
+spl_proc_fini(void)
+{
+	remove_proc_entry("kstat", proc_spl);
+        remove_proc_entry("slab", proc_spl_kmem);
+	remove_proc_entry("kmem", proc_spl);
+	remove_proc_entry("spl", NULL);
+
+        ASSERT(spl_header != NULL);
+        unregister_sysctl_table(spl_header);
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/module/spl/spl-rwlock.c
@@ -0,0 +1,96 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+ *****************************************************************************
+ *  Solaris Porting Layer (SPL) Reader/Writer Lock Implementation.
+\*****************************************************************************/
+
+#include <sys/rwlock.h>
+
+#ifdef DEBUG_SUBSYSTEM
+#undef DEBUG_SUBSYSTEM
+#endif
+
+#define DEBUG_SUBSYSTEM S_RWLOCK
+
+#ifdef CONFIG_RWSEM_GENERIC_SPINLOCK
+
+/*
+ * From lib/rwsem-spinlock.c but modified such that the caller is
+ * responsible for acquiring and dropping the sem->wait_lock.
+ */
+struct rwsem_waiter {
+        struct list_head list;
+        struct task_struct *task;
+        unsigned int flags;
+#define RWSEM_WAITING_FOR_READ  0x00000001
+#define RWSEM_WAITING_FOR_WRITE 0x00000002
+};
+
+/* wake a single writer */
+static struct rw_semaphore *
+__rwsem_wake_one_writer_locked(struct rw_semaphore *sem)
+{
+        struct rwsem_waiter *waiter;
+        struct task_struct *tsk;
+
+        sem->activity = -1;
+
+        waiter = list_entry(sem->wait_list.next, struct rwsem_waiter, list);
+        list_del(&waiter->list);
+
+        tsk = waiter->task;
+        smp_mb();
+        waiter->task = NULL;
+        wake_up_process(tsk);
+        put_task_struct(tsk);
+        return sem;
+}
+
+/* release a read lock on the semaphore */
+void
+__up_read_locked(struct rw_semaphore *sem)
+{
+        if (--sem->activity == 0 && !list_empty(&sem->wait_list))
+                (void)__rwsem_wake_one_writer_locked(sem);
+}
+EXPORT_SYMBOL(__up_read_locked);
+
+/* trylock for writing -- returns 1 if successful, 0 if contention */
+int
+__down_write_trylock_locked(struct rw_semaphore *sem)
+{
+        int ret = 0;
+
+        if (sem->activity == 0 && list_empty(&sem->wait_list)) {
+                sem->activity = -1;
+                ret = 1;
+        }
+
+        return ret;
+}
+EXPORT_SYMBOL(__down_write_trylock_locked);
+
+#endif
+
+int spl_rw_init(void) { return 0; }
+void spl_rw_fini(void) { }
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/module/spl/spl-taskq.c
@@ -0,0 +1,1125 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+ *****************************************************************************
+ *  Solaris Porting Layer (SPL) Task Queue Implementation.
+\*****************************************************************************/
+
+#include <sys/taskq.h>
+#include <sys/kmem.h>
+
+int spl_taskq_thread_bind = 0;
+module_param(spl_taskq_thread_bind, int, 0644);
+MODULE_PARM_DESC(spl_taskq_thread_bind, "Bind taskq thread to CPU by default");
+
+
+int spl_taskq_thread_dynamic = 0;
+module_param(spl_taskq_thread_dynamic, int, 0644);
+MODULE_PARM_DESC(spl_taskq_thread_dynamic, "Allow dynamic taskq threads");
+
+int spl_taskq_thread_priority = 1;
+module_param(spl_taskq_thread_priority, int, 0644);
+MODULE_PARM_DESC(spl_taskq_thread_priority,
+    "Allow non-default priority for taskq threads");
+
+int spl_taskq_thread_sequential = 4;
+module_param(spl_taskq_thread_sequential, int, 0644);
+MODULE_PARM_DESC(spl_taskq_thread_sequential,
+    "Create new taskq threads after N sequential tasks");
+
+/* Global system-wide dynamic task queue available for all consumers */
+taskq_t *system_taskq;
+EXPORT_SYMBOL(system_taskq);
+
+/* Private dedicated taskq for creating new taskq threads on demand. */
+static taskq_t *dynamic_taskq;
+static taskq_thread_t *taskq_thread_create(taskq_t *);
+
+static int
+task_km_flags(uint_t flags)
+{
+	if (flags & TQ_NOSLEEP)
+		return KM_NOSLEEP;
+
+	if (flags & TQ_PUSHPAGE)
+		return KM_PUSHPAGE;
+
+	return KM_SLEEP;
+}
+
+/*
+ * NOTE: Must be called with tq->tq_lock held, returns a list_t which
+ * is not attached to the free, work, or pending taskq lists.
+ */
+static taskq_ent_t *
+task_alloc(taskq_t *tq, uint_t flags)
+{
+	taskq_ent_t *t;
+	int count = 0;
+
+	ASSERT(tq);
+	ASSERT(spin_is_locked(&tq->tq_lock));
+retry:
+	/* Acquire taskq_ent_t's from free list if available */
+	if (!list_empty(&tq->tq_free_list) && !(flags & TQ_NEW)) {
+		t = list_entry(tq->tq_free_list.next, taskq_ent_t, tqent_list);
+
+		ASSERT(!(t->tqent_flags & TQENT_FLAG_PREALLOC));
+		ASSERT(!(t->tqent_flags & TQENT_FLAG_CANCEL));
+		ASSERT(!timer_pending(&t->tqent_timer));
+
+		list_del_init(&t->tqent_list);
+		return (t);
+	}
+
+	/* Free list is empty and memory allocations are prohibited */
+	if (flags & TQ_NOALLOC)
+		return (NULL);
+
+	/* Hit maximum taskq_ent_t pool size */
+	if (tq->tq_nalloc >= tq->tq_maxalloc) {
+		if (flags & TQ_NOSLEEP)
+			return (NULL);
+
+		/*
+		 * Sleep periodically polling the free list for an available
+		 * taskq_ent_t. Dispatching with TQ_SLEEP should always succeed
+		 * but we cannot block forever waiting for an taskq_ent_t to
+		 * show up in the free list, otherwise a deadlock can happen.
+		 *
+		 * Therefore, we need to allocate a new task even if the number
+		 * of allocated tasks is above tq->tq_maxalloc, but we still
+		 * end up delaying the task allocation by one second, thereby
+		 * throttling the task dispatch rate.
+		 */
+		spin_unlock_irqrestore(&tq->tq_lock, tq->tq_lock_flags);
+		schedule_timeout(HZ / 100);
+		spin_lock_irqsave(&tq->tq_lock, tq->tq_lock_flags);
+		if (count < 100) {
+			count++;
+			goto retry;
+		}
+	}
+
+	spin_unlock_irqrestore(&tq->tq_lock, tq->tq_lock_flags);
+	t = kmem_alloc(sizeof(taskq_ent_t), task_km_flags(flags));
+	spin_lock_irqsave(&tq->tq_lock, tq->tq_lock_flags);
+
+	if (t) {
+		taskq_init_ent(t);
+		tq->tq_nalloc++;
+	}
+
+	return (t);
+}
+
+/*
+ * NOTE: Must be called with tq->tq_lock held, expects the taskq_ent_t
+ * to already be removed from the free, work, or pending taskq lists.
+ */
+static void
+task_free(taskq_t *tq, taskq_ent_t *t)
+{
+	ASSERT(tq);
+	ASSERT(t);
+	ASSERT(spin_is_locked(&tq->tq_lock));
+	ASSERT(list_empty(&t->tqent_list));
+	ASSERT(!timer_pending(&t->tqent_timer));
+
+	kmem_free(t, sizeof(taskq_ent_t));
+	tq->tq_nalloc--;
+}
+
+/*
+ * NOTE: Must be called with tq->tq_lock held, either destroys the
+ * taskq_ent_t if too many exist or moves it to the free list for later use.
+ */
+static void
+task_done(taskq_t *tq, taskq_ent_t *t)
+{
+	ASSERT(tq);
+	ASSERT(t);
+	ASSERT(spin_is_locked(&tq->tq_lock));
+
+	/* Wake tasks blocked in taskq_wait_id() */
+	wake_up_all(&t->tqent_waitq);
+
+	list_del_init(&t->tqent_list);
+
+	if (tq->tq_nalloc <= tq->tq_minalloc) {
+		t->tqent_id = 0;
+		t->tqent_func = NULL;
+		t->tqent_arg = NULL;
+		t->tqent_flags = 0;
+
+		list_add_tail(&t->tqent_list, &tq->tq_free_list);
+	} else {
+		task_free(tq, t);
+	}
+}
+
+/*
+ * When a delayed task timer expires remove it from the delay list and
+ * add it to the priority list in order for immediate processing.
+ */
+static void
+task_expire(unsigned long data)
+{
+	taskq_ent_t *w, *t = (taskq_ent_t *)data;
+	taskq_t *tq = t->tqent_taskq;
+	struct list_head *l;
+
+	spin_lock_irqsave(&tq->tq_lock, tq->tq_lock_flags);
+
+	if (t->tqent_flags & TQENT_FLAG_CANCEL) {
+		ASSERT(list_empty(&t->tqent_list));
+		spin_unlock_irqrestore(&tq->tq_lock, tq->tq_lock_flags);
+		return;
+	}
+
+	/*
+	 * The priority list must be maintained in strict task id order
+	 * from lowest to highest for lowest_id to be easily calculable.
+	 */
+	list_del(&t->tqent_list);
+	list_for_each_prev(l, &tq->tq_prio_list) {
+		w = list_entry(l, taskq_ent_t, tqent_list);
+		if (w->tqent_id < t->tqent_id) {
+			list_add(&t->tqent_list, l);
+			break;
+		}
+	}
+	if (l == &tq->tq_prio_list)
+		list_add(&t->tqent_list, &tq->tq_prio_list);
+
+	spin_unlock_irqrestore(&tq->tq_lock, tq->tq_lock_flags);
+
+	wake_up(&tq->tq_work_waitq);
+}
+
+/*
+ * Returns the lowest incomplete taskqid_t.  The taskqid_t may
+ * be queued on the pending list, on the priority list, on the
+ * delay list, or on the work list currently being handled, but
+ * it is not 100% complete yet.
+ */
+static taskqid_t
+taskq_lowest_id(taskq_t *tq)
+{
+	taskqid_t lowest_id = tq->tq_next_id;
+	taskq_ent_t *t;
+	taskq_thread_t *tqt;
+
+	ASSERT(tq);
+	ASSERT(spin_is_locked(&tq->tq_lock));
+
+	if (!list_empty(&tq->tq_pend_list)) {
+		t = list_entry(tq->tq_pend_list.next, taskq_ent_t, tqent_list);
+		lowest_id = MIN(lowest_id, t->tqent_id);
+	}
+
+	if (!list_empty(&tq->tq_prio_list)) {
+		t = list_entry(tq->tq_prio_list.next, taskq_ent_t, tqent_list);
+		lowest_id = MIN(lowest_id, t->tqent_id);
+	}
+
+	if (!list_empty(&tq->tq_delay_list)) {
+		t = list_entry(tq->tq_delay_list.next, taskq_ent_t, tqent_list);
+		lowest_id = MIN(lowest_id, t->tqent_id);
+	}
+
+	if (!list_empty(&tq->tq_active_list)) {
+		tqt = list_entry(tq->tq_active_list.next, taskq_thread_t,
+		    tqt_active_list);
+		ASSERT(tqt->tqt_id != 0);
+		lowest_id = MIN(lowest_id, tqt->tqt_id);
+	}
+
+	return (lowest_id);
+}
+
+/*
+ * Insert a task into a list keeping the list sorted by increasing taskqid.
+ */
+static void
+taskq_insert_in_order(taskq_t *tq, taskq_thread_t *tqt)
+{
+	taskq_thread_t *w;
+	struct list_head *l;
+
+	ASSERT(tq);
+	ASSERT(tqt);
+	ASSERT(spin_is_locked(&tq->tq_lock));
+
+	list_for_each_prev(l, &tq->tq_active_list) {
+		w = list_entry(l, taskq_thread_t, tqt_active_list);
+		if (w->tqt_id < tqt->tqt_id) {
+			list_add(&tqt->tqt_active_list, l);
+			break;
+		}
+	}
+	if (l == &tq->tq_active_list)
+		list_add(&tqt->tqt_active_list, &tq->tq_active_list);
+}
+
+/*
+ * Find and return a task from the given list if it exists.  The list
+ * must be in lowest to highest task id order.
+ */
+static taskq_ent_t *
+taskq_find_list(taskq_t *tq, struct list_head *lh, taskqid_t id)
+{
+	struct list_head *l;
+	taskq_ent_t *t;
+
+	ASSERT(spin_is_locked(&tq->tq_lock));
+
+	list_for_each(l, lh) {
+		t = list_entry(l, taskq_ent_t, tqent_list);
+
+		if (t->tqent_id == id)
+			return (t);
+
+		if (t->tqent_id > id)
+			break;
+	}
+
+	return (NULL);
+}
+
+/*
+ * Find an already dispatched task given the task id regardless of what
+ * state it is in.  If a task is still pending or executing it will be
+ * returned and 'active' set appropriately.  If the task has already
+ * been run then NULL is returned.
+ */
+static taskq_ent_t *
+taskq_find(taskq_t *tq, taskqid_t id, int *active)
+{
+	taskq_thread_t *tqt;
+	struct list_head *l;
+	taskq_ent_t *t;
+
+	ASSERT(spin_is_locked(&tq->tq_lock));
+	*active = 0;
+
+	t = taskq_find_list(tq, &tq->tq_delay_list, id);
+	if (t)
+		return (t);
+
+	t = taskq_find_list(tq, &tq->tq_prio_list, id);
+	if (t)
+		return (t);
+
+	t = taskq_find_list(tq, &tq->tq_pend_list, id);
+	if (t)
+		return (t);
+
+	list_for_each(l, &tq->tq_active_list) {
+		tqt = list_entry(l, taskq_thread_t, tqt_active_list);
+		if (tqt->tqt_id == id) {
+			t = tqt->tqt_task;
+			*active = 1;
+			return (t);
+		}
+	}
+
+	return (NULL);
+}
+
+/*
+ * Theory for the taskq_wait_id(), taskq_wait_outstanding(), and
+ * taskq_wait() functions below.
+ *
+ * Taskq waiting is accomplished by tracking the lowest outstanding task
+ * id and the next available task id.  As tasks are dispatched they are
+ * added to the tail of the pending, priority, or delay lists.  As worker
+ * threads become available the tasks are removed from the heads of these
+ * lists and linked to the worker threads.  This ensures the lists are
+ * kept sorted by lowest to highest task id.
+ *
+ * Therefore the lowest outstanding task id can be quickly determined by
+ * checking the head item from all of these lists.  This value is stored
+ * with the taskq as the lowest id.  It only needs to be recalculated when
+ * either the task with the current lowest id completes or is canceled.
+ *
+ * By blocking until the lowest task id exceeds the passed task id the
+ * taskq_wait_outstanding() function can be easily implemented.  Similarly,
+ * by blocking until the lowest task id matches the next task id taskq_wait()
+ * can be implemented.
+ *
+ * Callers should be aware that when there are multiple worked threads it
+ * is possible for larger task ids to complete before smaller ones.  Also
+ * when the taskq contains delay tasks with small task ids callers may
+ * block for a considerable length of time waiting for them to expire and
+ * execute.
+ */
+static int
+taskq_wait_id_check(taskq_t *tq, taskqid_t id)
+{
+	int active = 0;
+	int rc;
+
+	spin_lock_irqsave(&tq->tq_lock, tq->tq_lock_flags);
+	rc = (taskq_find(tq, id, &active) == NULL);
+	spin_unlock_irqrestore(&tq->tq_lock, tq->tq_lock_flags);
+
+	return (rc);
+}
+
+/*
+ * The taskq_wait_id() function blocks until the passed task id completes.
+ * This does not guarantee that all lower task ids have completed.
+ */
+void
+taskq_wait_id(taskq_t *tq, taskqid_t id)
+{
+	wait_event(tq->tq_wait_waitq, taskq_wait_id_check(tq, id));
+}
+EXPORT_SYMBOL(taskq_wait_id);
+
+static int
+taskq_wait_outstanding_check(taskq_t *tq, taskqid_t id)
+{
+	int rc;
+
+	spin_lock_irqsave(&tq->tq_lock, tq->tq_lock_flags);
+	rc = (id < tq->tq_lowest_id);
+	spin_unlock_irqrestore(&tq->tq_lock, tq->tq_lock_flags);
+
+	return (rc);
+}
+
+/*
+ * The taskq_wait_outstanding() function will block until all tasks with a
+ * lower taskqid than the passed 'id' have been completed.  Note that all
+ * task id's are assigned monotonically at dispatch time.  Zero may be
+ * passed for the id to indicate all tasks dispatch up to this point,
+ * but not after, should be waited for.
+ */
+void
+taskq_wait_outstanding(taskq_t *tq, taskqid_t id)
+{
+	wait_event(tq->tq_wait_waitq,
+	    taskq_wait_outstanding_check(tq, id ? id : tq->tq_next_id - 1));
+}
+EXPORT_SYMBOL(taskq_wait_outstanding);
+
+static int
+taskq_wait_check(taskq_t *tq)
+{
+	int rc;
+
+	spin_lock_irqsave(&tq->tq_lock, tq->tq_lock_flags);
+	rc = (tq->tq_lowest_id == tq->tq_next_id);
+	spin_unlock_irqrestore(&tq->tq_lock, tq->tq_lock_flags);
+
+	return (rc);
+}
+
+/*
+ * The taskq_wait() function will block until the taskq is empty.
+ * This means that if a taskq re-dispatches work to itself taskq_wait()
+ * callers will block indefinitely.
+ */
+void
+taskq_wait(taskq_t *tq)
+{
+	wait_event(tq->tq_wait_waitq, taskq_wait_check(tq));
+}
+EXPORT_SYMBOL(taskq_wait);
+
+static int
+taskq_member_impl(taskq_t *tq, void *t)
+{
+	struct list_head *l;
+	taskq_thread_t *tqt;
+	int found = 0;
+
+	ASSERT(tq);
+	ASSERT(t);
+	ASSERT(spin_is_locked(&tq->tq_lock));
+
+	list_for_each(l, &tq->tq_thread_list) {
+		tqt = list_entry(l, taskq_thread_t, tqt_thread_list);
+		if (tqt->tqt_thread == (struct task_struct *)t) {
+			found = 1;
+			break;
+		}
+	}
+	return (found);
+}
+
+int
+taskq_member(taskq_t *tq, void *t)
+{
+	int found;
+
+	spin_lock_irqsave(&tq->tq_lock, tq->tq_lock_flags);
+	found = taskq_member_impl(tq, t);
+	spin_unlock_irqrestore(&tq->tq_lock, tq->tq_lock_flags);
+
+	return (found);
+}
+EXPORT_SYMBOL(taskq_member);
+
+/*
+ * Cancel an already dispatched task given the task id.  Still pending tasks
+ * will be immediately canceled, and if the task is active the function will
+ * block until it completes.  Preallocated tasks which are canceled must be
+ * freed by the caller.
+ */
+int
+taskq_cancel_id(taskq_t *tq, taskqid_t id)
+{
+	taskq_ent_t *t;
+	int active = 0;
+	int rc = ENOENT;
+
+	ASSERT(tq);
+
+	spin_lock_irqsave(&tq->tq_lock, tq->tq_lock_flags);
+	t = taskq_find(tq, id, &active);
+	if (t && !active) {
+		list_del_init(&t->tqent_list);
+		t->tqent_flags |= TQENT_FLAG_CANCEL;
+
+		/*
+		 * When canceling the lowest outstanding task id we
+		 * must recalculate the new lowest outstanding id.
+		 */
+		if (tq->tq_lowest_id == t->tqent_id) {
+			tq->tq_lowest_id = taskq_lowest_id(tq);
+			ASSERT3S(tq->tq_lowest_id, >, t->tqent_id);
+		}
+
+		/*
+		 * The task_expire() function takes the tq->tq_lock so drop
+		 * drop the lock before synchronously cancelling the timer.
+		 */
+		if (timer_pending(&t->tqent_timer)) {
+			spin_unlock_irqrestore(&tq->tq_lock, tq->tq_lock_flags);
+			del_timer_sync(&t->tqent_timer);
+			spin_lock_irqsave(&tq->tq_lock, tq->tq_lock_flags);
+		}
+
+		if (!(t->tqent_flags & TQENT_FLAG_PREALLOC))
+			task_done(tq, t);
+
+		rc = 0;
+	}
+	spin_unlock_irqrestore(&tq->tq_lock, tq->tq_lock_flags);
+
+	if (active) {
+		taskq_wait_id(tq, id);
+		rc = EBUSY;
+	}
+
+	return (rc);
+}
+EXPORT_SYMBOL(taskq_cancel_id);
+
+static int taskq_thread_spawn(taskq_t *tq);
+
+taskqid_t
+taskq_dispatch(taskq_t *tq, task_func_t func, void *arg, uint_t flags)
+{
+	taskq_ent_t *t;
+	taskqid_t rc = 0;
+
+	ASSERT(tq);
+	ASSERT(func);
+
+	spin_lock_irqsave(&tq->tq_lock, tq->tq_lock_flags);
+
+	/* Taskq being destroyed and all tasks drained */
+	if (!(tq->tq_flags & TASKQ_ACTIVE))
+		goto out;
+
+	/* Do not queue the task unless there is idle thread for it */
+	ASSERT(tq->tq_nactive <= tq->tq_nthreads);
+	if ((flags & TQ_NOQUEUE) && (tq->tq_nactive == tq->tq_nthreads))
+		goto out;
+
+	if ((t = task_alloc(tq, flags)) == NULL)
+		goto out;
+
+	spin_lock(&t->tqent_lock);
+
+	/* Queue to the priority list instead of the pending list */
+	if (flags & TQ_FRONT)
+		list_add_tail(&t->tqent_list, &tq->tq_prio_list);
+	else
+		list_add_tail(&t->tqent_list, &tq->tq_pend_list);
+
+	t->tqent_id = rc = tq->tq_next_id;
+	tq->tq_next_id++;
+	t->tqent_func = func;
+	t->tqent_arg = arg;
+	t->tqent_taskq = tq;
+	t->tqent_timer.data = 0;
+	t->tqent_timer.function = NULL;
+	t->tqent_timer.expires = 0;
+
+	ASSERT(!(t->tqent_flags & TQENT_FLAG_PREALLOC));
+
+	spin_unlock(&t->tqent_lock);
+
+	wake_up(&tq->tq_work_waitq);
+out:
+	/* Spawn additional taskq threads if required. */
+	if (tq->tq_nactive == tq->tq_nthreads)
+		(void) taskq_thread_spawn(tq);
+
+	spin_unlock_irqrestore(&tq->tq_lock, tq->tq_lock_flags);
+	return (rc);
+}
+EXPORT_SYMBOL(taskq_dispatch);
+
+taskqid_t
+taskq_dispatch_delay(taskq_t *tq, task_func_t func, void *arg,
+    uint_t flags, clock_t expire_time)
+{
+	taskqid_t rc = 0;
+	taskq_ent_t *t;
+
+	ASSERT(tq);
+	ASSERT(func);
+
+	spin_lock_irqsave(&tq->tq_lock, tq->tq_lock_flags);
+
+	/* Taskq being destroyed and all tasks drained */
+	if (!(tq->tq_flags & TASKQ_ACTIVE))
+		goto out;
+
+	if ((t = task_alloc(tq, flags)) == NULL)
+		goto out;
+
+	spin_lock(&t->tqent_lock);
+
+	/* Queue to the delay list for subsequent execution */
+	list_add_tail(&t->tqent_list, &tq->tq_delay_list);
+
+	t->tqent_id = rc = tq->tq_next_id;
+	tq->tq_next_id++;
+	t->tqent_func = func;
+	t->tqent_arg = arg;
+	t->tqent_taskq = tq;
+	t->tqent_timer.data = (unsigned long)t;
+	t->tqent_timer.function = task_expire;
+	t->tqent_timer.expires = (unsigned long)expire_time;
+	add_timer(&t->tqent_timer);
+
+	ASSERT(!(t->tqent_flags & TQENT_FLAG_PREALLOC));
+
+	spin_unlock(&t->tqent_lock);
+out:
+	/* Spawn additional taskq threads if required. */
+	if (tq->tq_nactive == tq->tq_nthreads)
+		(void) taskq_thread_spawn(tq);
+	spin_unlock_irqrestore(&tq->tq_lock, tq->tq_lock_flags);
+	return (rc);
+}
+EXPORT_SYMBOL(taskq_dispatch_delay);
+
+void
+taskq_dispatch_ent(taskq_t *tq, task_func_t func, void *arg, uint_t flags,
+   taskq_ent_t *t)
+{
+	ASSERT(tq);
+	ASSERT(func);
+
+	spin_lock_irqsave(&tq->tq_lock, tq->tq_lock_flags);
+
+	/* Taskq being destroyed and all tasks drained */
+	if (!(tq->tq_flags & TASKQ_ACTIVE)) {
+		t->tqent_id = 0;
+		goto out;
+	}
+
+	spin_lock(&t->tqent_lock);
+
+	/*
+	 * Mark it as a prealloc'd task.  This is important
+	 * to ensure that we don't free it later.
+	 */
+	t->tqent_flags |= TQENT_FLAG_PREALLOC;
+
+	/* Queue to the priority list instead of the pending list */
+	if (flags & TQ_FRONT)
+		list_add_tail(&t->tqent_list, &tq->tq_prio_list);
+	else
+		list_add_tail(&t->tqent_list, &tq->tq_pend_list);
+
+	t->tqent_id = tq->tq_next_id;
+	tq->tq_next_id++;
+	t->tqent_func = func;
+	t->tqent_arg = arg;
+	t->tqent_taskq = tq;
+
+	spin_unlock(&t->tqent_lock);
+
+	wake_up(&tq->tq_work_waitq);
+out:
+	/* Spawn additional taskq threads if required. */
+	if (tq->tq_nactive == tq->tq_nthreads)
+		(void) taskq_thread_spawn(tq);
+	spin_unlock_irqrestore(&tq->tq_lock, tq->tq_lock_flags);
+}
+EXPORT_SYMBOL(taskq_dispatch_ent);
+
+int
+taskq_empty_ent(taskq_ent_t *t)
+{
+	return list_empty(&t->tqent_list);
+}
+EXPORT_SYMBOL(taskq_empty_ent);
+
+void
+taskq_init_ent(taskq_ent_t *t)
+{
+	spin_lock_init(&t->tqent_lock);
+	init_waitqueue_head(&t->tqent_waitq);
+	init_timer(&t->tqent_timer);
+	INIT_LIST_HEAD(&t->tqent_list);
+	t->tqent_id = 0;
+	t->tqent_func = NULL;
+	t->tqent_arg = NULL;
+	t->tqent_flags = 0;
+	t->tqent_taskq = NULL;
+}
+EXPORT_SYMBOL(taskq_init_ent);
+
+/*
+ * Return the next pending task, preference is given to tasks on the
+ * priority list which were dispatched with TQ_FRONT.
+ */
+static taskq_ent_t *
+taskq_next_ent(taskq_t *tq)
+{
+	struct list_head *list;
+
+	ASSERT(spin_is_locked(&tq->tq_lock));
+
+	if (!list_empty(&tq->tq_prio_list))
+		list = &tq->tq_prio_list;
+	else if (!list_empty(&tq->tq_pend_list))
+		list = &tq->tq_pend_list;
+	else
+		return (NULL);
+
+	return (list_entry(list->next, taskq_ent_t, tqent_list));
+}
+
+/*
+ * Spawns a new thread for the specified taskq.
+ */
+static void
+taskq_thread_spawn_task(void *arg)
+{
+	taskq_t *tq = (taskq_t *)arg;
+
+	(void) taskq_thread_create(tq);
+
+	spin_lock_irqsave(&tq->tq_lock, tq->tq_lock_flags);
+	tq->tq_nspawn--;
+	spin_unlock_irqrestore(&tq->tq_lock, tq->tq_lock_flags);
+}
+
+/*
+ * Spawn addition threads for dynamic taskqs (TASKQ_DYNMAIC) the current
+ * number of threads is insufficient to handle the pending tasks.  These
+ * new threads must be created by the dedicated dynamic_taskq to avoid
+ * deadlocks between thread creation and memory reclaim.  The system_taskq
+ * which is also a dynamic taskq cannot be safely used for this.
+ */
+static int
+taskq_thread_spawn(taskq_t *tq)
+{
+	int spawning = 0;
+
+	if (!(tq->tq_flags & TASKQ_DYNAMIC))
+		return (0);
+
+	if ((tq->tq_nthreads + tq->tq_nspawn < tq->tq_maxthreads) &&
+	    (tq->tq_flags & TASKQ_ACTIVE)) {
+		spawning = (++tq->tq_nspawn);
+		taskq_dispatch(dynamic_taskq, taskq_thread_spawn_task,
+		    tq, TQ_NOSLEEP);
+	}
+
+	return (spawning);
+}
+
+/*
+ * Threads in a dynamic taskq should only exit once it has been completely
+ * drained and no other threads are actively servicing tasks.  This prevents
+ * threads from being created and destroyed more than is required.
+ *
+ * The first thread is the thread list is treated as the primary thread.
+ * There is nothing special about the primary thread but in order to avoid
+ * all the taskq pids from changing we opt to make it long running.
+ */
+static int
+taskq_thread_should_stop(taskq_t *tq, taskq_thread_t *tqt)
+{
+	ASSERT(spin_is_locked(&tq->tq_lock));
+
+	if (!(tq->tq_flags & TASKQ_DYNAMIC))
+		return (0);
+
+	if (list_first_entry(&(tq->tq_thread_list), taskq_thread_t,
+	    tqt_thread_list) == tqt)
+		return (0);
+
+	return
+	    ((tq->tq_nspawn == 0) &&	/* No threads are being spawned */
+	    (tq->tq_nactive == 0) &&	/* No threads are handling tasks */
+	    (tq->tq_nthreads > 1) &&	/* More than 1 thread is running */
+	    (!taskq_next_ent(tq)) &&	/* There are no pending tasks */
+	    (spl_taskq_thread_dynamic));/* Dynamic taskqs are allowed */
+}
+
+static int
+taskq_thread(void *args)
+{
+	DECLARE_WAITQUEUE(wait, current);
+	sigset_t blocked;
+	taskq_thread_t *tqt = args;
+	taskq_t *tq;
+	taskq_ent_t *t;
+	int seq_tasks = 0;
+
+	ASSERT(tqt);
+	tq = tqt->tqt_tq;
+	current->flags |= PF_NOFREEZE;
+
+	(void) spl_fstrans_mark();
+
+	sigfillset(&blocked);
+	sigprocmask(SIG_BLOCK, &blocked, NULL);
+	flush_signals(current);
+
+	spin_lock_irqsave(&tq->tq_lock, tq->tq_lock_flags);
+
+	/* Immediately exit if more threads than allowed were created. */
+	if (tq->tq_nthreads >= tq->tq_maxthreads)
+		goto error;
+
+	tq->tq_nthreads++;
+	list_add_tail(&tqt->tqt_thread_list, &tq->tq_thread_list);
+	wake_up(&tq->tq_wait_waitq);
+	set_current_state(TASK_INTERRUPTIBLE);
+
+	while (!kthread_should_stop()) {
+
+		if (list_empty(&tq->tq_pend_list) &&
+		    list_empty(&tq->tq_prio_list)) {
+
+			if (taskq_thread_should_stop(tq, tqt)) {
+				wake_up_all(&tq->tq_wait_waitq);
+				break;
+			}
+
+			add_wait_queue_exclusive(&tq->tq_work_waitq, &wait);
+			spin_unlock_irqrestore(&tq->tq_lock, tq->tq_lock_flags);
+
+			schedule();
+			seq_tasks = 0;
+
+			spin_lock_irqsave(&tq->tq_lock, tq->tq_lock_flags);
+			remove_wait_queue(&tq->tq_work_waitq, &wait);
+		} else {
+			__set_current_state(TASK_RUNNING);
+		}
+
+		if ((t = taskq_next_ent(tq)) != NULL) {
+			list_del_init(&t->tqent_list);
+
+			/* In order to support recursively dispatching a
+			 * preallocated taskq_ent_t, tqent_id must be
+			 * stored prior to executing tqent_func. */
+			tqt->tqt_id = t->tqent_id;
+			tqt->tqt_task = t;
+
+			/* We must store a copy of the flags prior to
+			 * servicing the task (servicing a prealloc'd task
+			 * returns the ownership of the tqent back to
+			 * the caller of taskq_dispatch). Thus,
+			 * tqent_flags _may_ change within the call. */
+			tqt->tqt_flags = t->tqent_flags;
+
+			taskq_insert_in_order(tq, tqt);
+			tq->tq_nactive++;
+			spin_unlock_irqrestore(&tq->tq_lock, tq->tq_lock_flags);
+
+			/* Perform the requested task */
+			t->tqent_func(t->tqent_arg);
+
+			spin_lock_irqsave(&tq->tq_lock, tq->tq_lock_flags);
+			tq->tq_nactive--;
+			list_del_init(&tqt->tqt_active_list);
+			tqt->tqt_task = NULL;
+
+			/* For prealloc'd tasks, we don't free anything. */
+			if (!(tqt->tqt_flags & TQENT_FLAG_PREALLOC))
+				task_done(tq, t);
+
+			/* When the current lowest outstanding taskqid is
+			 * done calculate the new lowest outstanding id */
+			if (tq->tq_lowest_id == tqt->tqt_id) {
+				tq->tq_lowest_id = taskq_lowest_id(tq);
+				ASSERT3S(tq->tq_lowest_id, >, tqt->tqt_id);
+			}
+
+			/* Spawn additional taskq threads if required. */
+			if ((++seq_tasks) > spl_taskq_thread_sequential &&
+			    taskq_thread_spawn(tq))
+				seq_tasks = 0;
+
+			tqt->tqt_id = 0;
+			tqt->tqt_flags = 0;
+			wake_up_all(&tq->tq_wait_waitq);
+		} else {
+			if (taskq_thread_should_stop(tq, tqt))
+				break;
+		}
+
+		set_current_state(TASK_INTERRUPTIBLE);
+
+	}
+
+	__set_current_state(TASK_RUNNING);
+	tq->tq_nthreads--;
+	list_del_init(&tqt->tqt_thread_list);
+error:
+	kmem_free(tqt, sizeof (taskq_thread_t));
+	spin_unlock_irqrestore(&tq->tq_lock, tq->tq_lock_flags);
+
+	return (0);
+}
+
+static taskq_thread_t *
+taskq_thread_create(taskq_t *tq)
+{
+	static int last_used_cpu = 0;
+	taskq_thread_t *tqt;
+
+	tqt = kmem_alloc(sizeof (*tqt), KM_PUSHPAGE);
+	INIT_LIST_HEAD(&tqt->tqt_thread_list);
+	INIT_LIST_HEAD(&tqt->tqt_active_list);
+	tqt->tqt_tq = tq;
+	tqt->tqt_id = 0;
+
+	tqt->tqt_thread = spl_kthread_create(taskq_thread, tqt,
+	    "%s", tq->tq_name);
+	if (tqt->tqt_thread == NULL) {
+		kmem_free(tqt, sizeof (taskq_thread_t));
+		return (NULL);
+	}
+
+	if (spl_taskq_thread_bind) {
+		last_used_cpu = (last_used_cpu + 1) % num_online_cpus();
+		kthread_bind(tqt->tqt_thread, last_used_cpu);
+	}
+
+	if (spl_taskq_thread_priority)
+		set_user_nice(tqt->tqt_thread, PRIO_TO_NICE(tq->tq_pri));
+
+	wake_up_process(tqt->tqt_thread);
+
+	return (tqt);
+}
+
+taskq_t *
+taskq_create(const char *name, int nthreads, pri_t pri,
+    int minalloc, int maxalloc, uint_t flags)
+{
+	taskq_t *tq;
+	taskq_thread_t *tqt;
+	int count = 0, rc = 0, i;
+
+	ASSERT(name != NULL);
+	ASSERT(minalloc >= 0);
+	ASSERT(maxalloc <= INT_MAX);
+	ASSERT(!(flags & (TASKQ_CPR_SAFE))); /* Unsupported */
+
+	/* Scale the number of threads using nthreads as a percentage */
+	if (flags & TASKQ_THREADS_CPU_PCT) {
+		ASSERT(nthreads <= 100);
+		ASSERT(nthreads >= 0);
+		nthreads = MIN(nthreads, 100);
+		nthreads = MAX(nthreads, 0);
+		nthreads = MAX((num_online_cpus() * nthreads) / 100, 1);
+	}
+
+	tq = kmem_alloc(sizeof (*tq), KM_PUSHPAGE);
+	if (tq == NULL)
+		return (NULL);
+
+	spin_lock_init(&tq->tq_lock);
+	INIT_LIST_HEAD(&tq->tq_thread_list);
+	INIT_LIST_HEAD(&tq->tq_active_list);
+	tq->tq_name       = strdup(name);
+	tq->tq_nactive    = 0;
+	tq->tq_nthreads   = 0;
+	tq->tq_nspawn     = 0;
+	tq->tq_maxthreads = nthreads;
+	tq->tq_pri        = pri;
+	tq->tq_minalloc   = minalloc;
+	tq->tq_maxalloc   = maxalloc;
+	tq->tq_nalloc     = 0;
+	tq->tq_flags      = (flags | TASKQ_ACTIVE);
+	tq->tq_next_id    = 1;
+	tq->tq_lowest_id  = 1;
+	INIT_LIST_HEAD(&tq->tq_free_list);
+	INIT_LIST_HEAD(&tq->tq_pend_list);
+	INIT_LIST_HEAD(&tq->tq_prio_list);
+	INIT_LIST_HEAD(&tq->tq_delay_list);
+	init_waitqueue_head(&tq->tq_work_waitq);
+	init_waitqueue_head(&tq->tq_wait_waitq);
+
+	if (flags & TASKQ_PREPOPULATE) {
+		spin_lock_irqsave(&tq->tq_lock, tq->tq_lock_flags);
+
+		for (i = 0; i < minalloc; i++)
+			task_done(tq, task_alloc(tq, TQ_PUSHPAGE | TQ_NEW));
+
+		spin_unlock_irqrestore(&tq->tq_lock, tq->tq_lock_flags);
+	}
+
+	if ((flags & TASKQ_DYNAMIC) && spl_taskq_thread_dynamic)
+		nthreads = 1;
+
+	for (i = 0; i < nthreads; i++) {
+		tqt = taskq_thread_create(tq);
+		if (tqt == NULL)
+			rc = 1;
+		else
+			count++;
+	}
+
+	/* Wait for all threads to be started before potential destroy */
+	wait_event(tq->tq_wait_waitq, tq->tq_nthreads == count);
+
+	if (rc) {
+		taskq_destroy(tq);
+		tq = NULL;
+	}
+
+	return (tq);
+}
+EXPORT_SYMBOL(taskq_create);
+
+void
+taskq_destroy(taskq_t *tq)
+{
+	struct task_struct *thread;
+	taskq_thread_t *tqt;
+	taskq_ent_t *t;
+
+	ASSERT(tq);
+	spin_lock_irqsave(&tq->tq_lock, tq->tq_lock_flags);
+	tq->tq_flags &= ~TASKQ_ACTIVE;
+	spin_unlock_irqrestore(&tq->tq_lock, tq->tq_lock_flags);
+
+	/*
+	 * When TASKQ_ACTIVE is clear new tasks may not be added nor may
+	 * new worker threads be spawned for dynamic taskq.
+	 */
+	if (dynamic_taskq != NULL)
+		taskq_wait_outstanding(dynamic_taskq, 0);
+
+	taskq_wait(tq);
+
+	spin_lock_irqsave(&tq->tq_lock, tq->tq_lock_flags);
+
+	/*
+	 * Signal each thread to exit and block until it does.  Each thread
+	 * is responsible for removing itself from the list and freeing its
+	 * taskq_thread_t.  This allows for idle threads to opt to remove
+	 * themselves from the taskq.  They can be recreated as needed.
+	 */
+	while (!list_empty(&tq->tq_thread_list)) {
+		tqt = list_entry(tq->tq_thread_list.next,
+		    taskq_thread_t, tqt_thread_list);
+		thread = tqt->tqt_thread;
+		spin_unlock_irqrestore(&tq->tq_lock, tq->tq_lock_flags);
+
+		kthread_stop(thread);
+
+		spin_lock_irqsave(&tq->tq_lock, tq->tq_lock_flags);
+	}
+
+	while (!list_empty(&tq->tq_free_list)) {
+		t = list_entry(tq->tq_free_list.next, taskq_ent_t, tqent_list);
+
+		ASSERT(!(t->tqent_flags & TQENT_FLAG_PREALLOC));
+
+		list_del_init(&t->tqent_list);
+		task_free(tq, t);
+	}
+
+	ASSERT0(tq->tq_nthreads);
+	ASSERT0(tq->tq_nalloc);
+	ASSERT0(tq->tq_nspawn);
+	ASSERT(list_empty(&tq->tq_thread_list));
+	ASSERT(list_empty(&tq->tq_active_list));
+	ASSERT(list_empty(&tq->tq_free_list));
+	ASSERT(list_empty(&tq->tq_pend_list));
+	ASSERT(list_empty(&tq->tq_prio_list));
+	ASSERT(list_empty(&tq->tq_delay_list));
+
+	spin_unlock_irqrestore(&tq->tq_lock, tq->tq_lock_flags);
+
+	strfree(tq->tq_name);
+	kmem_free(tq, sizeof (taskq_t));
+}
+EXPORT_SYMBOL(taskq_destroy);
+
+int
+spl_taskq_init(void)
+{
+	system_taskq = taskq_create("spl_system_taskq", MAX(boot_ncpus, 64),
+	    maxclsyspri, boot_ncpus, INT_MAX, TASKQ_PREPOPULATE|TASKQ_DYNAMIC);
+	if (system_taskq == NULL)
+		return (1);
+
+	dynamic_taskq = taskq_create("spl_dynamic_taskq", 1,
+	    maxclsyspri, boot_ncpus, INT_MAX, TASKQ_PREPOPULATE);
+	if (dynamic_taskq == NULL) {
+		taskq_destroy(system_taskq);
+		return (1);
+	}
+
+	return (0);
+}
+
+void
+spl_taskq_fini(void)
+{
+	taskq_destroy(dynamic_taskq);
+	dynamic_taskq = NULL;
+
+	taskq_destroy(system_taskq);
+	system_taskq = NULL;
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/module/spl/spl-thread.c
@@ -0,0 +1,158 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+ *****************************************************************************
+ *  Solaris Porting Layer (SPL) Thread Implementation.
+\*****************************************************************************/
+
+#include <sys/thread.h>
+#include <sys/kmem.h>
+#include <sys/tsd.h>
+
+/*
+ * Thread interfaces
+ */
+typedef struct thread_priv_s {
+	unsigned long tp_magic;		/* Magic */
+        int tp_name_size;		/* Name size */
+        char *tp_name;			/* Name (without _thread suffix) */
+	void (*tp_func)(void *);	/* Registered function */
+	void *tp_args;			/* Args to be passed to function */
+	size_t tp_len;			/* Len to be passed to function */
+	int tp_state;			/* State to start thread at */
+	pri_t tp_pri;			/* Priority to start threat at */
+} thread_priv_t;
+
+static int
+thread_generic_wrapper(void *arg)
+{
+	thread_priv_t *tp = (thread_priv_t *)arg;
+	void (*func)(void *);
+	void *args;
+
+	ASSERT(tp->tp_magic == TP_MAGIC);
+	func = tp->tp_func;
+	args = tp->tp_args;
+	set_current_state(tp->tp_state);
+	set_user_nice((kthread_t *)current, PRIO_TO_NICE(tp->tp_pri));
+	kmem_free(tp->tp_name, tp->tp_name_size);
+	kmem_free(tp, sizeof(thread_priv_t));
+
+	if (func)
+		func(args);
+
+	return 0;
+}
+
+void
+__thread_exit(void)
+{
+	tsd_exit();
+	complete_and_exit(NULL, 0);
+	/* Unreachable */
+}
+EXPORT_SYMBOL(__thread_exit);
+
+/* thread_create() may block forever if it cannot create a thread or
+ * allocate memory.  This is preferable to returning a NULL which Solaris
+ * style callers likely never check for... since it can't fail. */
+kthread_t *
+__thread_create(caddr_t stk, size_t  stksize, thread_func_t func,
+		const char *name, void *args, size_t len, proc_t *pp,
+		int state, pri_t pri)
+{
+	thread_priv_t *tp;
+	struct task_struct *tsk;
+	char *p;
+
+	/* Option pp is simply ignored */
+	/* Variable stack size unsupported */
+	ASSERT(stk == NULL);
+
+	tp = kmem_alloc(sizeof(thread_priv_t), KM_PUSHPAGE);
+	if (tp == NULL)
+		return (NULL);
+
+	tp->tp_magic = TP_MAGIC;
+	tp->tp_name_size = strlen(name) + 1;
+
+	tp->tp_name = kmem_alloc(tp->tp_name_size, KM_PUSHPAGE);
+        if (tp->tp_name == NULL) {
+		kmem_free(tp, sizeof(thread_priv_t));
+		return (NULL);
+	}
+
+	strncpy(tp->tp_name, name, tp->tp_name_size);
+
+	/* Strip trailing "_thread" from passed name which will be the func
+	 * name since the exposed API has no parameter for passing a name.
+	 */
+	p = strstr(tp->tp_name, "_thread");
+	if (p)
+		p[0] = '\0';
+
+	tp->tp_func  = func;
+	tp->tp_args  = args;
+	tp->tp_len   = len;
+	tp->tp_state = state;
+	tp->tp_pri   = pri;
+
+	tsk = spl_kthread_create(thread_generic_wrapper, (void *)tp,
+			     "%s", tp->tp_name);
+	if (IS_ERR(tsk))
+		return (NULL);
+
+	wake_up_process(tsk);
+	return ((kthread_t *)tsk);
+}
+EXPORT_SYMBOL(__thread_create);
+
+/*
+ * spl_kthread_create - Wrapper providing pre-3.13 semantics for
+ * kthread_create() in which it is not killable and less likely
+ * to return -ENOMEM.
+ */
+struct task_struct *
+spl_kthread_create(int (*func)(void *), void *data, const char namefmt[], ...)
+{
+	struct task_struct *tsk;
+	va_list args;
+	char name[TASK_COMM_LEN];
+
+	va_start(args, namefmt);
+	vsnprintf(name, sizeof(name), namefmt, args);
+	va_end(args);
+	do {
+		tsk = kthread_create(func, data, "%s", name);
+		if (IS_ERR(tsk)) {
+			if (signal_pending(current)) {
+				clear_thread_flag(TIF_SIGPENDING);
+				continue;
+			}
+			if (PTR_ERR(tsk) == -ENOMEM)
+				continue;
+			return (NULL);
+		} else
+			return (tsk);
+	} while (1);
+}
+EXPORT_SYMBOL(spl_kthread_create);
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/module/spl/spl-tsd.c
@@ -0,0 +1,694 @@
+/*
+ *  Copyright (C) 2010 Lawrence Livermore National Security, LLC.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ *
+ *  Solaris Porting Layer (SPL) Thread Specific Data Implementation.
+ *
+ *  Thread specific data has implemented using a hash table, this avoids
+ *  the need to add a member to the task structure and allows maximum
+ *  portability between kernels.  This implementation has been optimized
+ *  to keep the tsd_set() and tsd_get() times as small as possible.
+ *
+ *  The majority of the entries in the hash table are for specific tsd
+ *  entries.  These entries are hashed by the product of their key and
+ *  pid because by design the key and pid are guaranteed to be unique.
+ *  Their product also has the desirable properly that it will be uniformly
+ *  distributed over the hash bins providing neither the pid nor key is zero.
+ *  Under linux the zero pid is always the init process and thus won't be
+ *  used, and this implementation is careful to never to assign a zero key.
+ *  By default the hash table is sized to 512 bins which is expected to
+ *  be sufficient for light to moderate usage of thread specific data.
+ *
+ *  The hash table contains two additional type of entries.  They first
+ *  type is entry is called a 'key' entry and it is added to the hash during
+ *  tsd_create().  It is used to store the address of the destructor function
+ *  and it is used as an anchor point.  All tsd entries which use the same
+ *  key will be linked to this entry.  This is used during tsd_destory() to
+ *  quickly call the destructor function for all tsd associated with the key.
+ *  The 'key' entry may be looked up with tsd_hash_search() by passing the
+ *  key you wish to lookup and DTOR_PID constant as the pid.
+ *
+ *  The second type of entry is called a 'pid' entry and it is added to the
+ *  hash the first time a process set a key.  The 'pid' entry is also used
+ *  as an anchor and all tsd for the process will be linked to it.  This
+ *  list is using during tsd_exit() to ensure all registered destructors
+ *  are run for the process.  The 'pid' entry may be looked up with
+ *  tsd_hash_search() by passing the PID_KEY constant as the key, and
+ *  the process pid.  Note that tsd_exit() is called by thread_exit()
+ *  so if your using the Solaris thread API you should not need to call
+ *  tsd_exit() directly.
+ *
+ */
+
+#include <sys/kmem.h>
+#include <sys/thread.h>
+#include <sys/tsd.h>
+#include <linux/hash.h>
+
+typedef struct tsd_hash_bin {
+	spinlock_t		hb_lock;
+	struct hlist_head	hb_head;
+} tsd_hash_bin_t;
+
+typedef struct tsd_hash_table {
+	spinlock_t		ht_lock;
+	uint_t			ht_bits;
+	uint_t			ht_key;
+	tsd_hash_bin_t		*ht_bins;
+} tsd_hash_table_t;
+
+typedef struct tsd_hash_entry {
+	uint_t			he_key;
+	pid_t			he_pid;
+	dtor_func_t		he_dtor;
+	void			*he_value;
+	struct hlist_node	he_list;
+	struct list_head	he_key_list;
+	struct list_head	he_pid_list;
+} tsd_hash_entry_t;
+
+static tsd_hash_table_t *tsd_hash_table = NULL;
+
+
+/*
+ * tsd_hash_search - searches hash table for tsd_hash_entry
+ * @table: hash table
+ * @key: search key
+ * @pid: search pid
+ */
+static tsd_hash_entry_t *
+tsd_hash_search(tsd_hash_table_t *table, uint_t key, pid_t pid)
+{
+	struct hlist_node *node;
+	tsd_hash_entry_t *entry;
+	tsd_hash_bin_t *bin;
+	ulong_t hash;
+
+	hash = hash_long((ulong_t)key * (ulong_t)pid, table->ht_bits);
+	bin = &table->ht_bins[hash];
+	spin_lock(&bin->hb_lock);
+	hlist_for_each(node, &bin->hb_head) {
+		entry = list_entry(node, tsd_hash_entry_t, he_list);
+		if ((entry->he_key == key) && (entry->he_pid == pid)) {
+			spin_unlock(&bin->hb_lock);
+			return (entry);
+		}
+	}
+
+	spin_unlock(&bin->hb_lock);
+	return (NULL);
+}
+
+/*
+ * tsd_hash_dtor - call the destructor and free all entries on the list
+ * @work: list of hash entries
+ *
+ * For a list of entries which have all already been removed from the
+ * hash call their registered destructor then free the associated memory.
+ */
+static void
+tsd_hash_dtor(struct hlist_head *work)
+{
+	tsd_hash_entry_t *entry;
+
+	while (!hlist_empty(work)) {
+		entry = hlist_entry(work->first, tsd_hash_entry_t, he_list);
+		hlist_del(&entry->he_list);
+
+		if (entry->he_dtor && entry->he_pid != DTOR_PID)
+			entry->he_dtor(entry->he_value);
+
+		kmem_free(entry, sizeof (tsd_hash_entry_t));
+	}
+}
+
+/*
+ * tsd_hash_add - adds an entry to hash table
+ * @table: hash table
+ * @key: search key
+ * @pid: search pid
+ *
+ * The caller is responsible for ensuring the unique key/pid do not
+ * already exist in the hash table.  This possible because all entries
+ * are thread specific thus a concurrent thread will never attempt to
+ * add this key/pid.  Because multiple bins must be checked to add
+ * links to the dtor and pid entries the entire table is locked.
+ */
+static int
+tsd_hash_add(tsd_hash_table_t *table, uint_t key, pid_t pid, void *value)
+{
+	tsd_hash_entry_t *entry, *dtor_entry, *pid_entry;
+	tsd_hash_bin_t *bin;
+	ulong_t hash;
+	int rc = 0;
+
+	ASSERT3P(tsd_hash_search(table, key, pid), ==, NULL);
+
+	/* New entry allocate structure, set value, and add to hash */
+	entry = kmem_alloc(sizeof (tsd_hash_entry_t), KM_PUSHPAGE);
+	if (entry == NULL)
+		return (ENOMEM);
+
+	entry->he_key = key;
+	entry->he_pid = pid;
+	entry->he_value = value;
+	INIT_HLIST_NODE(&entry->he_list);
+	INIT_LIST_HEAD(&entry->he_key_list);
+	INIT_LIST_HEAD(&entry->he_pid_list);
+
+	spin_lock(&table->ht_lock);
+
+	/* Destructor entry must exist for all valid keys */
+	dtor_entry = tsd_hash_search(table, entry->he_key, DTOR_PID);
+	ASSERT3P(dtor_entry, !=, NULL);
+	entry->he_dtor = dtor_entry->he_dtor;
+
+	/* Process entry must exist for all valid processes */
+	pid_entry = tsd_hash_search(table, PID_KEY, entry->he_pid);
+	ASSERT3P(pid_entry, !=, NULL);
+
+	hash = hash_long((ulong_t)key * (ulong_t)pid, table->ht_bits);
+	bin = &table->ht_bins[hash];
+	spin_lock(&bin->hb_lock);
+
+	/* Add to the hash, key, and pid lists */
+	hlist_add_head(&entry->he_list, &bin->hb_head);
+	list_add(&entry->he_key_list, &dtor_entry->he_key_list);
+	list_add(&entry->he_pid_list, &pid_entry->he_pid_list);
+
+	spin_unlock(&bin->hb_lock);
+	spin_unlock(&table->ht_lock);
+
+	return (rc);
+}
+
+/*
+ * tsd_hash_add_key - adds a destructor entry to the hash table
+ * @table: hash table
+ * @keyp: search key
+ * @dtor: key destructor
+ *
+ * For every unique key there is a single entry in the hash which is used
+ * as anchor.  All other thread specific entries for this key are linked
+ * to this anchor via the 'he_key_list' list head.  On return they keyp
+ * will be set to the next available key for the hash table.
+ */
+static int
+tsd_hash_add_key(tsd_hash_table_t *table, uint_t *keyp, dtor_func_t dtor)
+{
+	tsd_hash_entry_t *tmp_entry, *entry;
+	tsd_hash_bin_t *bin;
+	ulong_t hash;
+	int keys_checked = 0;
+
+	ASSERT3P(table, !=, NULL);
+
+	/* Allocate entry to be used as a destructor for this key */
+	entry = kmem_alloc(sizeof (tsd_hash_entry_t), KM_PUSHPAGE);
+	if (entry == NULL)
+		return (ENOMEM);
+
+	/* Determine next available key value */
+	spin_lock(&table->ht_lock);
+	do {
+		/* Limited to TSD_KEYS_MAX concurrent unique keys */
+		if (table->ht_key++ > TSD_KEYS_MAX)
+			table->ht_key = 1;
+
+		/* Ensure failure when all TSD_KEYS_MAX keys are in use */
+		if (keys_checked++ >= TSD_KEYS_MAX) {
+			spin_unlock(&table->ht_lock);
+			return (ENOENT);
+		}
+
+		tmp_entry = tsd_hash_search(table, table->ht_key, DTOR_PID);
+	} while (tmp_entry);
+
+	/* Add destructor entry in to hash table */
+	entry->he_key = *keyp = table->ht_key;
+	entry->he_pid = DTOR_PID;
+	entry->he_dtor = dtor;
+	entry->he_value = NULL;
+	INIT_HLIST_NODE(&entry->he_list);
+	INIT_LIST_HEAD(&entry->he_key_list);
+	INIT_LIST_HEAD(&entry->he_pid_list);
+
+	hash = hash_long((ulong_t)*keyp * (ulong_t)DTOR_PID, table->ht_bits);
+	bin = &table->ht_bins[hash];
+	spin_lock(&bin->hb_lock);
+
+	hlist_add_head(&entry->he_list, &bin->hb_head);
+
+	spin_unlock(&bin->hb_lock);
+	spin_unlock(&table->ht_lock);
+
+	return (0);
+}
+
+/*
+ * tsd_hash_add_pid - adds a process entry to the hash table
+ * @table: hash table
+ * @pid: search pid
+ *
+ * For every process these is a single entry in the hash which is used
+ * as anchor.  All other thread specific entries for this process are
+ * linked to this anchor via the 'he_pid_list' list head.
+ */
+static int
+tsd_hash_add_pid(tsd_hash_table_t *table, pid_t pid)
+{
+	tsd_hash_entry_t *entry;
+	tsd_hash_bin_t *bin;
+	ulong_t hash;
+
+	/* Allocate entry to be used as the process reference */
+	entry = kmem_alloc(sizeof (tsd_hash_entry_t), KM_PUSHPAGE);
+	if (entry == NULL)
+		return (ENOMEM);
+
+	spin_lock(&table->ht_lock);
+	entry->he_key = PID_KEY;
+	entry->he_pid = pid;
+	entry->he_dtor = NULL;
+	entry->he_value = NULL;
+	INIT_HLIST_NODE(&entry->he_list);
+	INIT_LIST_HEAD(&entry->he_key_list);
+	INIT_LIST_HEAD(&entry->he_pid_list);
+
+	hash = hash_long((ulong_t)PID_KEY * (ulong_t)pid, table->ht_bits);
+	bin = &table->ht_bins[hash];
+	spin_lock(&bin->hb_lock);
+
+	hlist_add_head(&entry->he_list, &bin->hb_head);
+
+	spin_unlock(&bin->hb_lock);
+	spin_unlock(&table->ht_lock);
+
+	return (0);
+}
+
+/*
+ * tsd_hash_del - delete an entry from hash table, key, and pid lists
+ * @table: hash table
+ * @key: search key
+ * @pid: search pid
+ */
+static void
+tsd_hash_del(tsd_hash_table_t *table, tsd_hash_entry_t *entry)
+{
+	ASSERT(spin_is_locked(&table->ht_lock));
+	hlist_del(&entry->he_list);
+	list_del_init(&entry->he_key_list);
+	list_del_init(&entry->he_pid_list);
+}
+
+/*
+ * tsd_hash_table_init - allocate a hash table
+ * @bits: hash table size
+ *
+ * A hash table with 2^bits bins will be created, it may not be resized
+ * after the fact and must be free'd with tsd_hash_table_fini().
+ */
+static tsd_hash_table_t *
+tsd_hash_table_init(uint_t bits)
+{
+	tsd_hash_table_t *table;
+	int hash, size = (1 << bits);
+
+	table = kmem_zalloc(sizeof (tsd_hash_table_t), KM_SLEEP);
+	if (table == NULL)
+		return (NULL);
+
+	table->ht_bins = kmem_zalloc(sizeof (tsd_hash_bin_t) * size, KM_SLEEP);
+	if (table->ht_bins == NULL) {
+		kmem_free(table, sizeof (tsd_hash_table_t));
+		return (NULL);
+	}
+
+	for (hash = 0; hash < size; hash++) {
+		spin_lock_init(&table->ht_bins[hash].hb_lock);
+		INIT_HLIST_HEAD(&table->ht_bins[hash].hb_head);
+	}
+
+	spin_lock_init(&table->ht_lock);
+	table->ht_bits = bits;
+	table->ht_key = 1;
+
+	return (table);
+}
+
+/*
+ * tsd_hash_table_fini - free a hash table
+ * @table: hash table
+ *
+ * Free a hash table allocated by tsd_hash_table_init().  If the hash
+ * table is not empty this function will call the proper destructor for
+ * all remaining entries before freeing the memory used by those entries.
+ */
+static void
+tsd_hash_table_fini(tsd_hash_table_t *table)
+{
+	HLIST_HEAD(work);
+	tsd_hash_bin_t *bin;
+	tsd_hash_entry_t *entry;
+	int size, i;
+
+	ASSERT3P(table, !=, NULL);
+	spin_lock(&table->ht_lock);
+	for (i = 0, size = (1 << table->ht_bits); i < size; i++) {
+		bin = &table->ht_bins[i];
+		spin_lock(&bin->hb_lock);
+		while (!hlist_empty(&bin->hb_head)) {
+			entry = hlist_entry(bin->hb_head.first,
+			    tsd_hash_entry_t, he_list);
+			tsd_hash_del(table, entry);
+			hlist_add_head(&entry->he_list, &work);
+		}
+		spin_unlock(&bin->hb_lock);
+	}
+	spin_unlock(&table->ht_lock);
+
+	tsd_hash_dtor(&work);
+	kmem_free(table->ht_bins, sizeof (tsd_hash_bin_t)*(1<<table->ht_bits));
+	kmem_free(table, sizeof (tsd_hash_table_t));
+}
+
+/*
+ * tsd_remove_entry - remove a tsd entry for this thread
+ * @entry: entry to remove
+ *
+ * Remove the thread specific data @entry for this thread.
+ * If this is the last entry for this thread, also remove the PID entry.
+ */
+static void
+tsd_remove_entry(tsd_hash_entry_t *entry)
+{
+	HLIST_HEAD(work);
+	tsd_hash_table_t *table;
+	tsd_hash_entry_t *pid_entry;
+	tsd_hash_bin_t *pid_entry_bin, *entry_bin;
+	ulong_t hash;
+
+	table = tsd_hash_table;
+	ASSERT3P(table, !=, NULL);
+	ASSERT3P(entry, !=, NULL);
+
+	spin_lock(&table->ht_lock);
+
+	hash = hash_long((ulong_t)entry->he_key *
+	    (ulong_t)entry->he_pid, table->ht_bits);
+	entry_bin = &table->ht_bins[hash];
+
+	/* save the possible pid_entry */
+	pid_entry = list_entry(entry->he_pid_list.next, tsd_hash_entry_t,
+	    he_pid_list);
+
+	/* remove entry */
+	spin_lock(&entry_bin->hb_lock);
+	tsd_hash_del(table, entry);
+	hlist_add_head(&entry->he_list, &work);
+	spin_unlock(&entry_bin->hb_lock);
+
+	/* if pid_entry is indeed pid_entry, then remove it if it's empty */
+	if (pid_entry->he_key == PID_KEY &&
+	    list_empty(&pid_entry->he_pid_list)) {
+		hash = hash_long((ulong_t)pid_entry->he_key *
+		    (ulong_t)pid_entry->he_pid, table->ht_bits);
+		pid_entry_bin = &table->ht_bins[hash];
+
+		spin_lock(&pid_entry_bin->hb_lock);
+		tsd_hash_del(table, pid_entry);
+		hlist_add_head(&pid_entry->he_list, &work);
+		spin_unlock(&pid_entry_bin->hb_lock);
+	}
+
+	spin_unlock(&table->ht_lock);
+
+	tsd_hash_dtor(&work);
+}
+
+/*
+ * tsd_set - set thread specific data
+ * @key: lookup key
+ * @value: value to set
+ *
+ * Caller must prevent racing tsd_create() or tsd_destroy(), protected
+ * from racing tsd_get() or tsd_set() because it is thread specific.
+ * This function has been optimized to be fast for the update case.
+ * When setting the tsd initially it will be slower due to additional
+ * required locking and potential memory allocations.
+ */
+int
+tsd_set(uint_t key, void *value)
+{
+	tsd_hash_table_t *table;
+	tsd_hash_entry_t *entry;
+	pid_t pid;
+	int rc;
+	/* mark remove if value is NULL */
+	boolean_t remove = (value == NULL);
+
+	table = tsd_hash_table;
+	pid = curthread->pid;
+	ASSERT3P(table, !=, NULL);
+
+	if ((key == 0) || (key > TSD_KEYS_MAX))
+		return (EINVAL);
+
+	/* Entry already exists in hash table update value */
+	entry = tsd_hash_search(table, key, pid);
+	if (entry) {
+		entry->he_value = value;
+		/* remove the entry */
+		if (remove)
+			tsd_remove_entry(entry);
+		return (0);
+	}
+
+	/* don't create entry if value is NULL */
+	if (remove)
+		return (0);
+
+	/* Add a process entry to the hash if not yet exists */
+	entry = tsd_hash_search(table, PID_KEY, pid);
+	if (entry == NULL) {
+		rc = tsd_hash_add_pid(table, pid);
+		if (rc)
+			return (rc);
+	}
+
+	rc = tsd_hash_add(table, key, pid, value);
+	return (rc);
+}
+EXPORT_SYMBOL(tsd_set);
+
+/*
+ * tsd_get - get thread specific data
+ * @key: lookup key
+ *
+ * Caller must prevent racing tsd_create() or tsd_destroy().  This
+ * implementation is designed to be fast and scalable, it does not
+ * lock the entire table only a single hash bin.
+ */
+void *
+tsd_get(uint_t key)
+{
+	tsd_hash_entry_t *entry;
+
+	ASSERT3P(tsd_hash_table, !=, NULL);
+
+	if ((key == 0) || (key > TSD_KEYS_MAX))
+		return (NULL);
+
+	entry = tsd_hash_search(tsd_hash_table, key, curthread->pid);
+	if (entry == NULL)
+		return (NULL);
+
+	return (entry->he_value);
+}
+EXPORT_SYMBOL(tsd_get);
+
+/*
+ * tsd_create - create thread specific data key
+ * @keyp: lookup key address
+ * @dtor: destructor called during tsd_destroy() or tsd_exit()
+ *
+ * Provided key must be set to 0 or it assumed to be already in use.
+ * The dtor is allowed to be NULL in which case no additional cleanup
+ * for the data is performed during tsd_destroy() or tsd_exit().
+ *
+ * Caller must prevent racing tsd_set() or tsd_get(), this function is
+ * safe from racing tsd_create(), tsd_destroy(), and tsd_exit().
+ */
+void
+tsd_create(uint_t *keyp, dtor_func_t dtor)
+{
+	ASSERT3P(keyp, !=, NULL);
+	if (*keyp)
+		return;
+
+	(void) tsd_hash_add_key(tsd_hash_table, keyp, dtor);
+}
+EXPORT_SYMBOL(tsd_create);
+
+/*
+ * tsd_destroy - destroy thread specific data
+ * @keyp: lookup key address
+ *
+ * Destroys the thread specific data on all threads which use this key.
+ *
+ * Caller must prevent racing tsd_set() or tsd_get(), this function is
+ * safe from racing tsd_create(), tsd_destroy(), and tsd_exit().
+ */
+void
+tsd_destroy(uint_t *keyp)
+{
+	HLIST_HEAD(work);
+	tsd_hash_table_t *table;
+	tsd_hash_entry_t *dtor_entry, *entry;
+	tsd_hash_bin_t *dtor_entry_bin, *entry_bin;
+	ulong_t hash;
+
+	table = tsd_hash_table;
+	ASSERT3P(table, !=, NULL);
+
+	spin_lock(&table->ht_lock);
+	dtor_entry = tsd_hash_search(table, *keyp, DTOR_PID);
+	if (dtor_entry == NULL) {
+		spin_unlock(&table->ht_lock);
+		return;
+	}
+
+	/*
+	 * All threads which use this key must be linked off of the
+	 * DTOR_PID entry.  They are removed from the hash table and
+	 * linked in to a private working list to be destroyed.
+	 */
+	while (!list_empty(&dtor_entry->he_key_list)) {
+		entry = list_entry(dtor_entry->he_key_list.next,
+		    tsd_hash_entry_t, he_key_list);
+		ASSERT3U(dtor_entry->he_key, ==, entry->he_key);
+		ASSERT3P(dtor_entry->he_dtor, ==, entry->he_dtor);
+
+		hash = hash_long((ulong_t)entry->he_key *
+		    (ulong_t)entry->he_pid, table->ht_bits);
+		entry_bin = &table->ht_bins[hash];
+
+		spin_lock(&entry_bin->hb_lock);
+		tsd_hash_del(table, entry);
+		hlist_add_head(&entry->he_list, &work);
+		spin_unlock(&entry_bin->hb_lock);
+	}
+
+	hash = hash_long((ulong_t)dtor_entry->he_key *
+	    (ulong_t)dtor_entry->he_pid, table->ht_bits);
+	dtor_entry_bin = &table->ht_bins[hash];
+
+	spin_lock(&dtor_entry_bin->hb_lock);
+	tsd_hash_del(table, dtor_entry);
+	hlist_add_head(&dtor_entry->he_list, &work);
+	spin_unlock(&dtor_entry_bin->hb_lock);
+	spin_unlock(&table->ht_lock);
+
+	tsd_hash_dtor(&work);
+	*keyp = 0;
+}
+EXPORT_SYMBOL(tsd_destroy);
+
+/*
+ * tsd_exit - destroys all thread specific data for this thread
+ *
+ * Destroys all the thread specific data for this thread.
+ *
+ * Caller must prevent racing tsd_set() or tsd_get(), this function is
+ * safe from racing tsd_create(), tsd_destroy(), and tsd_exit().
+ */
+void
+tsd_exit(void)
+{
+	HLIST_HEAD(work);
+	tsd_hash_table_t *table;
+	tsd_hash_entry_t *pid_entry, *entry;
+	tsd_hash_bin_t *pid_entry_bin, *entry_bin;
+	ulong_t hash;
+
+	table = tsd_hash_table;
+	ASSERT3P(table, !=, NULL);
+
+	spin_lock(&table->ht_lock);
+	pid_entry = tsd_hash_search(table, PID_KEY, curthread->pid);
+	if (pid_entry == NULL) {
+		spin_unlock(&table->ht_lock);
+		return;
+	}
+
+	/*
+	 * All keys associated with this pid must be linked off of the
+	 * PID_KEY entry.  They are removed from the hash table and
+	 * linked in to a private working list to be destroyed.
+	 */
+
+	while (!list_empty(&pid_entry->he_pid_list)) {
+		entry = list_entry(pid_entry->he_pid_list.next,
+		    tsd_hash_entry_t, he_pid_list);
+		ASSERT3U(pid_entry->he_pid, ==, entry->he_pid);
+
+		hash = hash_long((ulong_t)entry->he_key *
+		    (ulong_t)entry->he_pid, table->ht_bits);
+		entry_bin = &table->ht_bins[hash];
+
+		spin_lock(&entry_bin->hb_lock);
+		tsd_hash_del(table, entry);
+		hlist_add_head(&entry->he_list, &work);
+		spin_unlock(&entry_bin->hb_lock);
+	}
+
+	hash = hash_long((ulong_t)pid_entry->he_key *
+	    (ulong_t)pid_entry->he_pid, table->ht_bits);
+	pid_entry_bin = &table->ht_bins[hash];
+
+	spin_lock(&pid_entry_bin->hb_lock);
+	tsd_hash_del(table, pid_entry);
+	hlist_add_head(&pid_entry->he_list, &work);
+	spin_unlock(&pid_entry_bin->hb_lock);
+	spin_unlock(&table->ht_lock);
+
+	tsd_hash_dtor(&work);
+}
+EXPORT_SYMBOL(tsd_exit);
+
+int
+spl_tsd_init(void)
+{
+	tsd_hash_table = tsd_hash_table_init(TSD_HASH_TABLE_BITS_DEFAULT);
+	if (tsd_hash_table == NULL)
+		return (1);
+
+	return (0);
+}
+
+void
+spl_tsd_fini(void)
+{
+	tsd_hash_table_fini(tsd_hash_table);
+	tsd_hash_table = NULL;
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/module/spl/spl-vmem.c
@@ -0,0 +1,109 @@
+/*
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <sys/debug.h>
+#include <sys/vmem.h>
+#include <linux/mm_compat.h>
+#include <linux/module.h>
+
+vmem_t *heap_arena = NULL;
+EXPORT_SYMBOL(heap_arena);
+
+vmem_t *zio_alloc_arena = NULL;
+EXPORT_SYMBOL(zio_alloc_arena);
+
+vmem_t *zio_arena = NULL;
+EXPORT_SYMBOL(zio_arena);
+
+size_t
+vmem_size(vmem_t *vmp, int typemask)
+{
+	ASSERT3P(vmp, ==, NULL);
+	ASSERT3S(typemask & VMEM_ALLOC, ==, VMEM_ALLOC);
+	ASSERT3S(typemask & VMEM_FREE, ==, VMEM_FREE);
+
+	return (VMALLOC_TOTAL);
+}
+EXPORT_SYMBOL(vmem_size);
+
+/*
+ * Public vmem_alloc(), vmem_zalloc() and vmem_free() interfaces.
+ */
+void *
+spl_vmem_alloc(size_t size, int flags, const char *func, int line)
+{
+	ASSERT0(flags & ~KM_PUBLIC_MASK);
+
+	flags |= KM_VMEM;
+
+#if !defined(DEBUG_KMEM)
+	return (spl_kmem_alloc_impl(size, flags, NUMA_NO_NODE));
+#elif !defined(DEBUG_KMEM_TRACKING)
+	return (spl_kmem_alloc_debug(size, flags, NUMA_NO_NODE));
+#else
+	return (spl_kmem_alloc_track(size, flags, func, line, NUMA_NO_NODE));
+#endif
+}
+EXPORT_SYMBOL(spl_vmem_alloc);
+
+void *
+spl_vmem_zalloc(size_t size, int flags, const char *func, int line)
+{
+	ASSERT0(flags & ~KM_PUBLIC_MASK);
+
+	flags |= (KM_VMEM | KM_ZERO);
+
+#if !defined(DEBUG_KMEM)
+	return (spl_kmem_alloc_impl(size, flags, NUMA_NO_NODE));
+#elif !defined(DEBUG_KMEM_TRACKING)
+	return (spl_kmem_alloc_debug(size, flags, NUMA_NO_NODE));
+#else
+	return (spl_kmem_alloc_track(size, flags, func, line, NUMA_NO_NODE));
+#endif
+}
+EXPORT_SYMBOL(spl_vmem_zalloc);
+
+void
+spl_vmem_free(const void *buf, size_t size)
+{
+#if !defined(DEBUG_KMEM)
+	return (spl_kmem_free_impl(buf, size));
+#elif !defined(DEBUG_KMEM_TRACKING)
+	return (spl_kmem_free_debug(buf, size));
+#else
+	return (spl_kmem_free_track(buf, size));
+#endif
+}
+EXPORT_SYMBOL(spl_vmem_free);
+
+int
+spl_vmem_init(void)
+{
+	return (0);
+}
+
+void
+spl_vmem_fini(void)
+{
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/module/spl/spl-vnode.c
@@ -0,0 +1,908 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+ *****************************************************************************
+ *  Solaris Porting Layer (SPL) Vnode Implementation.
+\*****************************************************************************/
+
+#include <sys/cred.h>
+#include <sys/vnode.h>
+#include <sys/kmem_cache.h>
+#include <linux/falloc.h>
+#include <linux/file_compat.h>
+
+vnode_t *rootdir = (vnode_t *)0xabcd1234;
+EXPORT_SYMBOL(rootdir);
+
+static spl_kmem_cache_t *vn_cache;
+static spl_kmem_cache_t *vn_file_cache;
+
+static DEFINE_SPINLOCK(vn_file_lock);
+static LIST_HEAD(vn_file_list);
+
+vtype_t
+vn_mode_to_vtype(mode_t mode)
+{
+	if (S_ISREG(mode))
+		return VREG;
+
+	if (S_ISDIR(mode))
+		return VDIR;
+
+	if (S_ISCHR(mode))
+		return VCHR;
+
+	if (S_ISBLK(mode))
+		return VBLK;
+
+	if (S_ISFIFO(mode))
+		return VFIFO;
+
+	if (S_ISLNK(mode))
+		return VLNK;
+
+	if (S_ISSOCK(mode))
+		return VSOCK;
+
+	if (S_ISCHR(mode))
+		return VCHR;
+
+	return VNON;
+} /* vn_mode_to_vtype() */
+EXPORT_SYMBOL(vn_mode_to_vtype);
+
+mode_t
+vn_vtype_to_mode(vtype_t vtype)
+{
+	if (vtype == VREG)
+		return S_IFREG;
+
+	if (vtype == VDIR)
+		return S_IFDIR;
+
+	if (vtype == VCHR)
+		return S_IFCHR;
+
+	if (vtype == VBLK)
+		return S_IFBLK;
+
+	if (vtype == VFIFO)
+		return S_IFIFO;
+
+	if (vtype == VLNK)
+		return S_IFLNK;
+
+	if (vtype == VSOCK)
+		return S_IFSOCK;
+
+	return VNON;
+} /* vn_vtype_to_mode() */
+EXPORT_SYMBOL(vn_vtype_to_mode);
+
+vnode_t *
+vn_alloc(int flag)
+{
+	vnode_t *vp;
+
+	vp = kmem_cache_alloc(vn_cache, flag);
+	if (vp != NULL) {
+		vp->v_file = NULL;
+		vp->v_type = 0;
+	}
+
+	return (vp);
+} /* vn_alloc() */
+EXPORT_SYMBOL(vn_alloc);
+
+void
+vn_free(vnode_t *vp)
+{
+	kmem_cache_free(vn_cache, vp);
+} /* vn_free() */
+EXPORT_SYMBOL(vn_free);
+
+int
+vn_open(const char *path, uio_seg_t seg, int flags, int mode,
+	vnode_t **vpp, int x1, void *x2)
+{
+	struct file *fp;
+	struct kstat stat;
+	int rc, saved_umask = 0;
+	gfp_t saved_gfp;
+	vnode_t *vp;
+
+	ASSERT(flags & (FWRITE | FREAD));
+	ASSERT(seg == UIO_SYSSPACE);
+	ASSERT(vpp);
+	*vpp = NULL;
+
+	if (!(flags & FCREAT) && (flags & FWRITE))
+		flags |= FEXCL;
+
+	/* Note for filp_open() the two low bits must be remapped to mean:
+	 * 01 - read-only  -> 00 read-only
+	 * 10 - write-only -> 01 write-only
+	 * 11 - read-write -> 10 read-write
+	 */
+	flags--;
+
+	if (flags & FCREAT)
+		saved_umask = xchg(&current->fs->umask, 0);
+
+	fp = filp_open(path, flags, mode);
+
+	if (flags & FCREAT)
+		(void)xchg(&current->fs->umask, saved_umask);
+
+	if (IS_ERR(fp))
+		return (-PTR_ERR(fp));
+
+#ifdef HAVE_2ARGS_VFS_GETATTR
+	rc = vfs_getattr(&fp->f_path, &stat);
+#else
+	rc = vfs_getattr(fp->f_path.mnt, fp->f_dentry, &stat);
+#endif
+	if (rc) {
+		filp_close(fp, 0);
+		return (-rc);
+	}
+
+	vp = vn_alloc(KM_SLEEP);
+	if (!vp) {
+		filp_close(fp, 0);
+		return (ENOMEM);
+	}
+
+	saved_gfp = mapping_gfp_mask(fp->f_mapping);
+	mapping_set_gfp_mask(fp->f_mapping, saved_gfp & ~(__GFP_IO|__GFP_FS));
+
+	mutex_enter(&vp->v_lock);
+	vp->v_type = vn_mode_to_vtype(stat.mode);
+	vp->v_file = fp;
+	vp->v_gfp_mask = saved_gfp;
+	*vpp = vp;
+	mutex_exit(&vp->v_lock);
+
+	return (0);
+} /* vn_open() */
+EXPORT_SYMBOL(vn_open);
+
+int
+vn_openat(const char *path, uio_seg_t seg, int flags, int mode,
+	  vnode_t **vpp, int x1, void *x2, vnode_t *vp, int fd)
+{
+	char *realpath;
+	int len, rc;
+
+	ASSERT(vp == rootdir);
+
+	len = strlen(path) + 2;
+	realpath = kmalloc(len, kmem_flags_convert(KM_SLEEP));
+	if (!realpath)
+		return (ENOMEM);
+
+	(void)snprintf(realpath, len, "/%s", path);
+	rc = vn_open(realpath, seg, flags, mode, vpp, x1, x2);
+	kfree(realpath);
+
+	return (rc);
+} /* vn_openat() */
+EXPORT_SYMBOL(vn_openat);
+
+int
+vn_rdwr(uio_rw_t uio, vnode_t *vp, void *addr, ssize_t len, offset_t off,
+	uio_seg_t seg, int ioflag, rlim64_t x2, void *x3, ssize_t *residp)
+{
+	loff_t offset;
+	mm_segment_t saved_fs;
+	struct file *fp;
+	int rc;
+
+	ASSERT(uio == UIO_WRITE || uio == UIO_READ);
+	ASSERT(vp);
+	ASSERT(vp->v_file);
+	ASSERT(seg == UIO_SYSSPACE);
+	ASSERT((ioflag & ~FAPPEND) == 0);
+	ASSERT(x2 == RLIM64_INFINITY);
+
+	fp = vp->v_file;
+
+	offset = off;
+	if (ioflag & FAPPEND)
+		offset = fp->f_pos;
+
+	/* Writable user data segment must be briefly increased for this
+	 * process so we can use the user space read call paths to write
+	 * in to memory allocated by the kernel. */
+	saved_fs = get_fs();
+        set_fs(get_ds());
+
+	if (uio & UIO_WRITE)
+		rc = vfs_write(fp, addr, len, &offset);
+	else
+		rc = vfs_read(fp, addr, len, &offset);
+
+	set_fs(saved_fs);
+	fp->f_pos = offset;
+
+	if (rc < 0)
+		return (-rc);
+
+	if (residp) {
+		*residp = len - rc;
+	} else {
+		if (rc != len)
+			return (EIO);
+	}
+
+	return (0);
+} /* vn_rdwr() */
+EXPORT_SYMBOL(vn_rdwr);
+
+int
+vn_close(vnode_t *vp, int flags, int x1, int x2, void *x3, void *x4)
+{
+	int rc;
+
+	ASSERT(vp);
+	ASSERT(vp->v_file);
+
+	mapping_set_gfp_mask(vp->v_file->f_mapping, vp->v_gfp_mask);
+	rc = filp_close(vp->v_file, 0);
+	vn_free(vp);
+
+	return (-rc);
+} /* vn_close() */
+EXPORT_SYMBOL(vn_close);
+
+/* vn_seek() does not actually seek it only performs bounds checking on the
+ * proposed seek.  We perform minimal checking and allow vn_rdwr() to catch
+ * anything more serious. */
+int
+vn_seek(vnode_t *vp, offset_t ooff, offset_t *noffp, void *ct)
+{
+	return ((*noffp < 0 || *noffp > MAXOFFSET_T) ? EINVAL : 0);
+}
+EXPORT_SYMBOL(vn_seek);
+
+/*
+ * spl_basename() takes a NULL-terminated string s as input containing a path.
+ * It returns a char pointer to a string and a length that describe the
+ * basename of the path. If the basename is not "." or "/", it will be an index
+ * into the string. While the string should be NULL terminated, the section
+ * referring to the basename is not. spl_basename is dual-licensed GPLv2+ and
+ * CC0. Anyone wishing to reuse it in another codebase may pick either license.
+ */
+static void
+spl_basename(const char *s, const char **str, int *len)
+{
+	size_t i, end;
+
+	ASSERT(str);
+	ASSERT(len);
+
+	if (!s || !*s) {
+		*str = ".";
+		*len = 1;
+		return;
+	}
+
+	i = strlen(s) - 1;
+
+	while (i && s[i--] == '/');
+
+	if (i == 0) {
+		*str = "/";
+		*len = 1;
+		return;
+	}
+
+	end = i;
+
+	for (end = i; i; i--) {
+		if (s[i] == '/') {
+			*str = &s[i+1];
+			*len = end - i + 1;
+			return;
+		}
+	}
+
+	*str = s;
+	*len = end + 1;
+}
+
+static struct dentry *
+spl_kern_path_locked(const char *name, struct path *path)
+{
+	struct path parent;
+	struct dentry *dentry;
+	const char *basename;
+	int len;
+	int rc;
+
+	ASSERT(name);
+	ASSERT(path);
+
+	spl_basename(name, &basename, &len);
+
+	/* We do not accept "." or ".." */
+	if (len <= 2 && basename[0] == '.')
+		if (len == 1 || basename[1] == '.')
+			return (ERR_PTR(-EACCES));
+
+	rc = kern_path(name, LOOKUP_PARENT, &parent);
+	if (rc)
+		return (ERR_PTR(rc));
+
+	spl_inode_lock(parent.dentry->d_inode);
+
+	dentry = lookup_one_len(basename, parent.dentry, len);
+	if (IS_ERR(dentry)) {
+		spl_inode_unlock(parent.dentry->d_inode);
+		path_put(&parent);
+	} else {
+		*path = parent;
+	}
+
+	return (dentry);
+}
+
+/* Based on do_unlinkat() from linux/fs/namei.c */
+int
+vn_remove(const char *path, uio_seg_t seg, int flags)
+{
+	struct dentry *dentry;
+	struct path parent;
+	struct inode *inode = NULL;
+	int rc = 0;
+
+	ASSERT(seg == UIO_SYSSPACE);
+	ASSERT(flags == RMFILE);
+
+	dentry = spl_kern_path_locked(path, &parent);
+	rc = PTR_ERR(dentry);
+	if (!IS_ERR(dentry)) {
+		if (parent.dentry->d_name.name[parent.dentry->d_name.len]) {
+			rc = 0;
+			goto slashes;
+		}
+
+		inode = dentry->d_inode;
+		if (inode) {
+			atomic_inc(&inode->i_count);
+		} else {
+			rc = 0;
+			goto slashes;
+		}
+
+#ifdef HAVE_2ARGS_VFS_UNLINK
+		rc = vfs_unlink(parent.dentry->d_inode, dentry);
+#else
+		rc = vfs_unlink(parent.dentry->d_inode, dentry, NULL);
+#endif /* HAVE_2ARGS_VFS_UNLINK */
+exit1:
+		dput(dentry);
+	} else {
+		return (-rc);
+	}
+
+	spl_inode_unlock(parent.dentry->d_inode);
+	if (inode)
+		iput(inode);    /* truncate the inode here */
+
+	path_put(&parent);
+	return (-rc);
+
+slashes:
+	rc = !dentry->d_inode ? -ENOENT :
+	    S_ISDIR(dentry->d_inode->i_mode) ? -EISDIR : -ENOTDIR;
+	goto exit1;
+} /* vn_remove() */
+EXPORT_SYMBOL(vn_remove);
+
+/* Based on do_rename() from linux/fs/namei.c */
+int
+vn_rename(const char *oldname, const char *newname, int x1)
+{
+	struct dentry *old_dir, *new_dir;
+	struct dentry *old_dentry, *new_dentry;
+	struct dentry *trap;
+	struct path old_parent, new_parent;
+	int rc = 0;
+
+	old_dentry = spl_kern_path_locked(oldname, &old_parent);
+	if (IS_ERR(old_dentry)) {
+		rc = PTR_ERR(old_dentry);
+		goto exit;
+	}
+
+	spl_inode_unlock(old_parent.dentry->d_inode);
+
+	new_dentry = spl_kern_path_locked(newname, &new_parent);
+	if (IS_ERR(new_dentry)) {
+		rc = PTR_ERR(new_dentry);
+		goto exit2;
+	}
+
+	spl_inode_unlock(new_parent.dentry->d_inode);
+
+	rc = -EXDEV;
+	if (old_parent.mnt != new_parent.mnt)
+		goto exit3;
+
+	old_dir = old_parent.dentry;
+	new_dir = new_parent.dentry;
+	trap = lock_rename(new_dir, old_dir);
+
+	/* source should not be ancestor of target */
+	rc = -EINVAL;
+	if (old_dentry == trap)
+		goto exit4;
+
+	/* target should not be an ancestor of source */
+	rc = -ENOTEMPTY;
+	if (new_dentry == trap)
+		goto exit4;
+
+	/* source must exist */
+	rc = -ENOENT;
+	if (!old_dentry->d_inode)
+		goto exit4;
+
+	/* unless the source is a directory trailing slashes give -ENOTDIR */
+	if (!S_ISDIR(old_dentry->d_inode->i_mode)) {
+		rc = -ENOTDIR;
+		if (old_dentry->d_name.name[old_dentry->d_name.len])
+			goto exit4;
+		if (new_dentry->d_name.name[new_dentry->d_name.len])
+			goto exit4;
+	}
+
+#if defined(HAVE_4ARGS_VFS_RENAME)
+	rc = vfs_rename(old_dir->d_inode, old_dentry,
+	    new_dir->d_inode, new_dentry);
+#elif defined(HAVE_5ARGS_VFS_RENAME)
+	rc = vfs_rename(old_dir->d_inode, old_dentry,
+	    new_dir->d_inode, new_dentry, NULL);
+#else
+	rc = vfs_rename(old_dir->d_inode, old_dentry,
+	    new_dir->d_inode, new_dentry, NULL, 0);
+#endif
+exit4:
+	unlock_rename(new_dir, old_dir);
+exit3:
+	dput(new_dentry);
+	path_put(&new_parent);
+exit2:
+	dput(old_dentry);
+	path_put(&old_parent);
+exit:
+	return (-rc);
+}
+EXPORT_SYMBOL(vn_rename);
+
+int
+vn_getattr(vnode_t *vp, vattr_t *vap, int flags, void *x3, void *x4)
+{
+	struct file *fp;
+	struct kstat stat;
+	int rc;
+
+	ASSERT(vp);
+	ASSERT(vp->v_file);
+	ASSERT(vap);
+
+	fp = vp->v_file;
+
+#ifdef HAVE_2ARGS_VFS_GETATTR
+	rc = vfs_getattr(&fp->f_path, &stat);
+#else
+	rc = vfs_getattr(fp->f_path.mnt, fp->f_dentry, &stat);
+#endif
+	if (rc)
+		return (-rc);
+
+	vap->va_type          = vn_mode_to_vtype(stat.mode);
+	vap->va_mode          = stat.mode;
+	vap->va_uid           = KUID_TO_SUID(stat.uid);
+	vap->va_gid           = KGID_TO_SGID(stat.gid);
+	vap->va_fsid          = 0;
+	vap->va_nodeid        = stat.ino;
+	vap->va_nlink         = stat.nlink;
+        vap->va_size          = stat.size;
+	vap->va_blksize       = stat.blksize;
+	vap->va_atime         = stat.atime;
+	vap->va_mtime         = stat.mtime;
+	vap->va_ctime         = stat.ctime;
+	vap->va_rdev          = stat.rdev;
+	vap->va_nblocks       = stat.blocks;
+
+	return (0);
+}
+EXPORT_SYMBOL(vn_getattr);
+
+int vn_fsync(vnode_t *vp, int flags, void *x3, void *x4)
+{
+	int datasync = 0;
+	int error;
+	int fstrans;
+
+	ASSERT(vp);
+	ASSERT(vp->v_file);
+
+	if (flags & FDSYNC)
+		datasync = 1;
+
+	/*
+	 * May enter XFS which generates a warning when PF_FSTRANS is set.
+	 * To avoid this the flag is cleared over vfs_sync() and then reset.
+	 */
+	fstrans = spl_fstrans_check();
+	if (fstrans)
+		current->flags &= ~(PF_FSTRANS);
+
+	error = -spl_filp_fsync(vp->v_file, datasync);
+	if (fstrans)
+		current->flags |= PF_FSTRANS;
+
+	return (error);
+} /* vn_fsync() */
+EXPORT_SYMBOL(vn_fsync);
+
+int vn_space(vnode_t *vp, int cmd, struct flock *bfp, int flag,
+    offset_t offset, void *x6, void *x7)
+{
+	int error = EOPNOTSUPP;
+
+	if (cmd != F_FREESP || bfp->l_whence != 0)
+		return (EOPNOTSUPP);
+
+	ASSERT(vp);
+	ASSERT(vp->v_file);
+	ASSERT(bfp->l_start >= 0 && bfp->l_len > 0);
+
+#ifdef FALLOC_FL_PUNCH_HOLE
+	/*
+	 * When supported by the underlying file system preferentially
+	 * use the fallocate() callback to preallocate the space.
+	 */
+	error = -spl_filp_fallocate(vp->v_file,
+	    FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE,
+	    bfp->l_start, bfp->l_len);
+	if (error == 0)
+		return (0);
+#endif
+
+#ifdef HAVE_INODE_TRUNCATE_RANGE
+	if (vp->v_file->f_dentry && vp->v_file->f_dentry->d_inode &&
+	    vp->v_file->f_dentry->d_inode->i_op &&
+	    vp->v_file->f_dentry->d_inode->i_op->truncate_range) {
+		off_t end = bfp->l_start + bfp->l_len;
+		/*
+		 * Judging from the code in shmem_truncate_range(),
+		 * it seems the kernel expects the end offset to be
+		 * inclusive and aligned to the end of a page.
+		 */
+		if (end % PAGE_SIZE != 0) {
+			end &= ~(off_t)(PAGE_SIZE - 1);
+			if (end <= bfp->l_start)
+				return (0);
+		}
+		--end;
+
+		vp->v_file->f_dentry->d_inode->i_op->truncate_range(
+			vp->v_file->f_dentry->d_inode,
+			bfp->l_start, end
+		);
+		return (0);
+	}
+#endif
+
+	return (error);
+}
+EXPORT_SYMBOL(vn_space);
+
+/* Function must be called while holding the vn_file_lock */
+static file_t *
+file_find(int fd, struct task_struct *task)
+{
+        file_t *fp;
+
+	ASSERT(spin_is_locked(&vn_file_lock));
+
+        list_for_each_entry(fp, &vn_file_list,  f_list) {
+		if (fd == fp->f_fd && fp->f_task == task) {
+			ASSERT(atomic_read(&fp->f_ref) != 0);
+                        return fp;
+		}
+	}
+
+        return NULL;
+} /* file_find() */
+
+file_t *
+vn_getf(int fd)
+{
+        struct kstat stat;
+	struct file *lfp;
+	file_t *fp;
+	vnode_t *vp;
+	int rc = 0;
+
+	if (fd < 0)
+		return (NULL);
+
+	/* Already open just take an extra reference */
+	spin_lock(&vn_file_lock);
+
+	fp = file_find(fd, current);
+	if (fp) {
+		atomic_inc(&fp->f_ref);
+		spin_unlock(&vn_file_lock);
+		return (fp);
+	}
+
+	spin_unlock(&vn_file_lock);
+
+	/* File was not yet opened create the object and setup */
+	fp = kmem_cache_alloc(vn_file_cache, KM_SLEEP);
+	if (fp == NULL)
+		goto out;
+
+	mutex_enter(&fp->f_lock);
+
+	fp->f_fd = fd;
+	fp->f_task = current;
+	fp->f_offset = 0;
+	atomic_inc(&fp->f_ref);
+
+	lfp = fget(fd);
+	if (lfp == NULL)
+		goto out_mutex;
+
+	vp = vn_alloc(KM_SLEEP);
+	if (vp == NULL)
+		goto out_fget;
+
+#ifdef HAVE_2ARGS_VFS_GETATTR
+	rc = vfs_getattr(&lfp->f_path, &stat);
+#else
+	rc = vfs_getattr(lfp->f_path.mnt, lfp->f_dentry, &stat);
+#endif
+        if (rc)
+		goto out_vnode;
+
+	mutex_enter(&vp->v_lock);
+	vp->v_type = vn_mode_to_vtype(stat.mode);
+	vp->v_file = lfp;
+	mutex_exit(&vp->v_lock);
+
+	fp->f_vnode = vp;
+	fp->f_file = lfp;
+
+	/* Put it on the tracking list */
+	spin_lock(&vn_file_lock);
+	list_add(&fp->f_list, &vn_file_list);
+	spin_unlock(&vn_file_lock);
+
+	mutex_exit(&fp->f_lock);
+	return (fp);
+
+out_vnode:
+	vn_free(vp);
+out_fget:
+	fput(lfp);
+out_mutex:
+	mutex_exit(&fp->f_lock);
+	kmem_cache_free(vn_file_cache, fp);
+out:
+        return (NULL);
+} /* getf() */
+EXPORT_SYMBOL(getf);
+
+static void releasef_locked(file_t *fp)
+{
+	ASSERT(fp->f_file);
+	ASSERT(fp->f_vnode);
+
+	/* Unlinked from list, no refs, safe to free outside mutex */
+	fput(fp->f_file);
+	vn_free(fp->f_vnode);
+
+	kmem_cache_free(vn_file_cache, fp);
+}
+
+void
+vn_releasef(int fd)
+{
+	areleasef(fd, P_FINFO(current));
+}
+EXPORT_SYMBOL(releasef);
+
+void
+vn_areleasef(int fd, uf_info_t *fip)
+{
+	file_t *fp;
+	struct task_struct *task = (struct task_struct *)fip;
+
+	if (fd < 0)
+		return;
+
+	spin_lock(&vn_file_lock);
+	fp = file_find(fd, task);
+	if (fp) {
+		atomic_dec(&fp->f_ref);
+		if (atomic_read(&fp->f_ref) > 0) {
+			spin_unlock(&vn_file_lock);
+			return;
+		}
+
+	        list_del(&fp->f_list);
+		releasef_locked(fp);
+	}
+	spin_unlock(&vn_file_lock);
+
+	return;
+} /* releasef() */
+EXPORT_SYMBOL(areleasef);
+
+
+static void
+#ifdef HAVE_SET_FS_PWD_WITH_CONST
+vn_set_fs_pwd(struct fs_struct *fs, const struct path *path)
+#else
+vn_set_fs_pwd(struct fs_struct *fs, struct path *path)
+#endif /* HAVE_SET_FS_PWD_WITH_CONST */
+{
+	struct path old_pwd;
+
+#ifdef HAVE_FS_STRUCT_SPINLOCK
+	spin_lock(&fs->lock);
+	old_pwd = fs->pwd;
+	fs->pwd = *path;
+	path_get(path);
+	spin_unlock(&fs->lock);
+#else
+	write_lock(&fs->lock);
+	old_pwd = fs->pwd;
+	fs->pwd = *path;
+	path_get(path);
+	write_unlock(&fs->lock);
+#endif /* HAVE_FS_STRUCT_SPINLOCK */
+
+	if (old_pwd.dentry)
+		path_put(&old_pwd);
+}
+
+int
+vn_set_pwd(const char *filename)
+{
+        struct path path;
+        mm_segment_t saved_fs;
+        int rc;
+
+        /*
+         * user_path_dir() and __user_walk() both expect 'filename' to be
+         * a user space address so we must briefly increase the data segment
+         * size to ensure strncpy_from_user() does not fail with -EFAULT.
+         */
+        saved_fs = get_fs();
+        set_fs(get_ds());
+
+        rc = user_path_dir(filename, &path);
+        if (rc)
+		goto out;
+
+        rc = inode_permission(path.dentry->d_inode, MAY_EXEC | MAY_ACCESS);
+        if (rc)
+		goto dput_and_out;
+
+        vn_set_fs_pwd(current->fs, &path);
+
+dput_and_out:
+        path_put(&path);
+out:
+	set_fs(saved_fs);
+
+        return (-rc);
+} /* vn_set_pwd() */
+EXPORT_SYMBOL(vn_set_pwd);
+
+static int
+vn_cache_constructor(void *buf, void *cdrarg, int kmflags)
+{
+	struct vnode *vp = buf;
+
+	mutex_init(&vp->v_lock, NULL, MUTEX_DEFAULT, NULL);
+
+	return (0);
+} /* vn_cache_constructor() */
+
+static void
+vn_cache_destructor(void *buf, void *cdrarg)
+{
+	struct vnode *vp = buf;
+
+	mutex_destroy(&vp->v_lock);
+} /* vn_cache_destructor() */
+
+static int
+vn_file_cache_constructor(void *buf, void *cdrarg, int kmflags)
+{
+	file_t *fp = buf;
+
+	atomic_set(&fp->f_ref, 0);
+        mutex_init(&fp->f_lock, NULL, MUTEX_DEFAULT, NULL);
+	INIT_LIST_HEAD(&fp->f_list);
+
+        return (0);
+} /* file_cache_constructor() */
+
+static void
+vn_file_cache_destructor(void *buf, void *cdrarg)
+{
+	file_t *fp = buf;
+
+	mutex_destroy(&fp->f_lock);
+} /* vn_file_cache_destructor() */
+
+int
+spl_vn_init(void)
+{
+	vn_cache = kmem_cache_create("spl_vn_cache",
+				     sizeof(struct vnode), 64,
+	                             vn_cache_constructor,
+				     vn_cache_destructor,
+				     NULL, NULL, NULL, KMC_KMEM);
+
+	vn_file_cache = kmem_cache_create("spl_vn_file_cache",
+					  sizeof(file_t), 64,
+				          vn_file_cache_constructor,
+				          vn_file_cache_destructor,
+				          NULL, NULL, NULL, KMC_KMEM);
+	return (0);
+} /* vn_init() */
+
+void
+spl_vn_fini(void)
+{
+        file_t *fp, *next_fp;
+	int leaked = 0;
+
+	spin_lock(&vn_file_lock);
+
+        list_for_each_entry_safe(fp, next_fp, &vn_file_list,  f_list) {
+	        list_del(&fp->f_list);
+		releasef_locked(fp);
+		leaked++;
+	}
+
+	spin_unlock(&vn_file_lock);
+
+	if (leaked > 0)
+		printk(KERN_WARNING "WARNING: %d vnode files leaked\n", leaked);
+
+	kmem_cache_destroy(vn_file_cache);
+	kmem_cache_destroy(vn_cache);
+
+	return;
+} /* vn_fini() */
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/module/spl/spl-xdr.c
@@ -0,0 +1,514 @@
+/*****************************************************************************\
+ *  Copyright (c) 2008-2010 Sun Microsystems, Inc.
+ *  Written by Ricardo Correia <Ricardo.M.Correia@Sun.COM>
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+ *****************************************************************************
+ *  Solaris Porting Layer (SPL) XDR Implementation.
+\*****************************************************************************/
+
+#include <linux/string.h>
+#include <sys/kmem.h>
+#include <sys/debug.h>
+#include <sys/types.h>
+#include <rpc/types.h>
+#include <rpc/xdr.h>
+
+/*
+ * SPL's XDR mem implementation.
+ *
+ * This is used by libnvpair to serialize/deserialize the name-value pair data
+ * structures into byte arrays in a well-defined and portable manner.
+ *
+ * These data structures are used by the DMU/ZFS to flexibly manipulate various
+ * information in memory and later serialize it/deserialize it to disk.
+ * Examples of usages include the pool configuration, lists of pool and dataset
+ * properties, etc.
+ *
+ * Reference documentation for the XDR representation and XDR operations can be
+ * found in RFC 1832 and xdr(3), respectively.
+ *
+ * ===  Implementation shortcomings ===
+ *
+ * It is assumed that the following C types have the following sizes:
+ *
+ * char/unsigned char:      1 byte
+ * short/unsigned short:    2 bytes
+ * int/unsigned int:        4 bytes
+ * longlong_t/u_longlong_t: 8 bytes
+ *
+ * The C standard allows these types to be larger (and in the case of ints,
+ * shorter), so if that is the case on some compiler/architecture, the build
+ * will fail (on purpose).
+ *
+ * If someone wants to fix the code to work properly on such environments, then:
+ *
+ * 1) Preconditions should be added to xdrmem_enc functions to make sure the
+ *    caller doesn't pass arguments which exceed the expected range.
+ * 2) Functions which take signed integers should be changed to properly do
+ *    sign extension.
+ * 3) For ints with less than 32 bits, well.. I suspect you'll have bigger
+ *    problems than this implementation.
+ *
+ * It is also assumed that:
+ *
+ * 1) Chars have 8 bits.
+ * 2) We can always do 32-bit-aligned int memory accesses and byte-aligned
+ *    memcpy, memset and memcmp.
+ * 3) Arrays passed to xdr_array() are packed and the compiler/architecture
+ *    supports element-sized-aligned memory accesses.
+ * 4) Negative integers are natively stored in two's complement binary
+ *    representation.
+ *
+ * No checks are done for the 4 assumptions above, though.
+ *
+ * === Caller expectations ===
+ *
+ * Existing documentation does not describe the semantics of XDR operations very
+ * well.  Therefore, some assumptions about failure semantics will be made and
+ * will be described below:
+ *
+ * 1) If any encoding operation fails (e.g., due to lack of buffer space), the
+ * the stream should be considered valid only up to the encoding operation
+ * previous to the one that first failed. However, the stream size as returned
+ * by xdr_control() cannot be considered to be strictly correct (it may be
+ * bigger).
+ *
+ * Putting it another way, if there is an encoding failure it's undefined
+ * whether anything is added to the stream in that operation and therefore
+ * neither xdr_control() nor future encoding operations on the same stream can
+ * be relied upon to produce correct results.
+ *
+ * 2) If a decoding operation fails, it's undefined whether anything will be
+ * decoded into passed buffers/pointers during that operation, or what the
+ * values on those buffers will look like.
+ *
+ * Future decoding operations on the same stream will also have similar
+ * undefined behavior.
+ *
+ * 3) When the first decoding operation fails it is OK to trust the results of
+ * previous decoding operations on the same stream, as long as the caller
+ * expects a failure to be possible (e.g. due to end-of-stream).
+ *
+ * However, this is highly discouraged because the caller should know the
+ * stream size and should be coded to expect any decoding failure to be data
+ * corruption due to hardware, accidental or even malicious causes, which should
+ * be handled gracefully in all cases.
+ *
+ * In very rare situations where there are strong reasons to believe the data
+ * can be trusted to be valid and non-tampered with, then the caller may assume
+ * a decoding failure to be a bug (e.g. due to mismatched data types) and may
+ * fail non-gracefully.
+ *
+ * 4) Non-zero padding bytes will cause the decoding operation to fail.
+ *
+ * 5) Zero bytes on string types will also cause the decoding operation to fail.
+ *
+ * 6) It is assumed that either the pointer to the stream buffer given by the
+ * caller is 32-bit aligned or the architecture supports non-32-bit-aligned int
+ * memory accesses.
+ *
+ * 7) The stream buffer and encoding/decoding buffers/ptrs should not overlap.
+ *
+ * 8) If a caller passes pointers to non-kernel memory (e.g., pointers to user
+ * space or MMIO space), the computer may explode.
+ */
+
+static struct xdr_ops xdrmem_encode_ops;
+static struct xdr_ops xdrmem_decode_ops;
+
+void
+xdrmem_create(XDR *xdrs, const caddr_t addr, const uint_t size,
+    const enum xdr_op op)
+{
+	switch (op) {
+		case XDR_ENCODE:
+			xdrs->x_ops = &xdrmem_encode_ops;
+			break;
+		case XDR_DECODE:
+			xdrs->x_ops = &xdrmem_decode_ops;
+			break;
+		default:
+			xdrs->x_ops = NULL; /* Let the caller know we failed */
+			return;
+	}
+
+	xdrs->x_op = op;
+	xdrs->x_addr = addr;
+	xdrs->x_addr_end = addr + size;
+
+	if (xdrs->x_addr_end < xdrs->x_addr) {
+		xdrs->x_ops = NULL;
+	}
+}
+EXPORT_SYMBOL(xdrmem_create);
+
+static bool_t
+xdrmem_control(XDR *xdrs, int req, void *info)
+{
+	struct xdr_bytesrec *rec = (struct xdr_bytesrec *) info;
+
+	if (req != XDR_GET_BYTES_AVAIL)
+		return FALSE;
+
+	rec->xc_is_last_record = TRUE; /* always TRUE in xdrmem streams */
+	rec->xc_num_avail = xdrs->x_addr_end - xdrs->x_addr;
+
+	return TRUE;
+}
+
+static bool_t
+xdrmem_enc_bytes(XDR *xdrs, caddr_t cp, const uint_t cnt)
+{
+	uint_t size = roundup(cnt, 4);
+	uint_t pad;
+
+	if (size < cnt)
+		return FALSE; /* Integer overflow */
+
+	if (xdrs->x_addr > xdrs->x_addr_end)
+		return FALSE;
+
+	if (xdrs->x_addr_end - xdrs->x_addr < size)
+		return FALSE;
+
+	memcpy(xdrs->x_addr, cp, cnt);
+
+	xdrs->x_addr += cnt;
+
+	pad = size - cnt;
+	if (pad > 0) {
+		memset(xdrs->x_addr, 0, pad);
+		xdrs->x_addr += pad;
+	}
+
+	return TRUE;
+}
+
+static bool_t
+xdrmem_dec_bytes(XDR *xdrs, caddr_t cp, const uint_t cnt)
+{
+	static uint32_t zero = 0;
+	uint_t size = roundup(cnt, 4);
+	uint_t pad;
+
+	if (size < cnt)
+		return FALSE; /* Integer overflow */
+
+	if (xdrs->x_addr > xdrs->x_addr_end)
+		return FALSE;
+
+	if (xdrs->x_addr_end - xdrs->x_addr < size)
+		return FALSE;
+
+	memcpy(cp, xdrs->x_addr, cnt);
+	xdrs->x_addr += cnt;
+
+	pad = size - cnt;
+	if (pad > 0) {
+		/* An inverted memchr() would be useful here... */
+		if (memcmp(&zero, xdrs->x_addr, pad) != 0)
+			return FALSE;
+
+		xdrs->x_addr += pad;
+	}
+
+	return TRUE;
+}
+
+static bool_t
+xdrmem_enc_uint32(XDR *xdrs, uint32_t val)
+{
+	if (xdrs->x_addr + sizeof(uint32_t) > xdrs->x_addr_end)
+		return FALSE;
+
+	*((uint32_t *) xdrs->x_addr) = cpu_to_be32(val);
+
+	xdrs->x_addr += sizeof(uint32_t);
+
+	return TRUE;
+}
+
+static bool_t
+xdrmem_dec_uint32(XDR *xdrs, uint32_t *val)
+{
+	if (xdrs->x_addr + sizeof(uint32_t) > xdrs->x_addr_end)
+		return FALSE;
+
+	*val = be32_to_cpu(*((uint32_t *) xdrs->x_addr));
+
+	xdrs->x_addr += sizeof(uint32_t);
+
+	return TRUE;
+}
+
+static bool_t
+xdrmem_enc_char(XDR *xdrs, char *cp)
+{
+	uint32_t val;
+
+	BUILD_BUG_ON(sizeof(char) != 1);
+	val = *((unsigned char *) cp);
+
+	return xdrmem_enc_uint32(xdrs, val);
+}
+
+static bool_t
+xdrmem_dec_char(XDR *xdrs, char *cp)
+{
+	uint32_t val;
+
+	BUILD_BUG_ON(sizeof(char) != 1);
+
+	if (!xdrmem_dec_uint32(xdrs, &val))
+		return FALSE;
+
+	/*
+	 * If any of the 3 other bytes are non-zero then val will be greater
+	 * than 0xff and we fail because according to the RFC, this block does
+	 * not have a char encoded in it.
+	 */
+	if (val > 0xff)
+		return FALSE;
+
+	*((unsigned char *) cp) = val;
+
+	return TRUE;
+}
+
+static bool_t
+xdrmem_enc_ushort(XDR *xdrs, unsigned short *usp)
+{
+	BUILD_BUG_ON(sizeof(unsigned short) != 2);
+
+	return xdrmem_enc_uint32(xdrs, *usp);
+}
+
+static bool_t
+xdrmem_dec_ushort(XDR *xdrs, unsigned short *usp)
+{
+	uint32_t val;
+
+	BUILD_BUG_ON(sizeof(unsigned short) != 2);
+
+	if (!xdrmem_dec_uint32(xdrs, &val))
+		return FALSE;
+
+	/*
+	 * Short ints are not in the RFC, but we assume similar logic as in
+	 * xdrmem_dec_char().
+	 */
+	if (val > 0xffff)
+		return FALSE;
+
+	*usp = val;
+
+	return TRUE;
+}
+
+static bool_t
+xdrmem_enc_uint(XDR *xdrs, unsigned *up)
+{
+	BUILD_BUG_ON(sizeof(unsigned) != 4);
+
+	return xdrmem_enc_uint32(xdrs, *up);
+}
+
+static bool_t
+xdrmem_dec_uint(XDR *xdrs, unsigned *up)
+{
+	BUILD_BUG_ON(sizeof(unsigned) != 4);
+
+	return xdrmem_dec_uint32(xdrs, (uint32_t *) up);
+}
+
+static bool_t
+xdrmem_enc_ulonglong(XDR *xdrs, u_longlong_t *ullp)
+{
+	BUILD_BUG_ON(sizeof(u_longlong_t) != 8);
+
+	if (!xdrmem_enc_uint32(xdrs, *ullp >> 32))
+		return FALSE;
+
+	return xdrmem_enc_uint32(xdrs, *ullp & 0xffffffff);
+}
+
+static bool_t
+xdrmem_dec_ulonglong(XDR *xdrs, u_longlong_t *ullp)
+{
+	uint32_t low, high;
+
+	BUILD_BUG_ON(sizeof(u_longlong_t) != 8);
+
+	if (!xdrmem_dec_uint32(xdrs, &high))
+		return FALSE;
+	if (!xdrmem_dec_uint32(xdrs, &low))
+		return FALSE;
+
+	*ullp = ((u_longlong_t) high << 32) | low;
+
+	return TRUE;
+}
+
+static bool_t
+xdr_enc_array(XDR *xdrs, caddr_t *arrp, uint_t *sizep, const uint_t maxsize,
+    const uint_t elsize, const xdrproc_t elproc)
+{
+	uint_t i;
+	caddr_t addr = *arrp;
+
+	if (*sizep > maxsize || *sizep > UINT_MAX / elsize)
+		return FALSE;
+
+	if (!xdrmem_enc_uint(xdrs, sizep))
+		return FALSE;
+
+	for (i = 0; i < *sizep; i++) {
+		if (!elproc(xdrs, addr))
+			return FALSE;
+		addr += elsize;
+	}
+
+	return TRUE;
+}
+
+static bool_t
+xdr_dec_array(XDR *xdrs, caddr_t *arrp, uint_t *sizep, const uint_t maxsize,
+    const uint_t elsize, const xdrproc_t elproc)
+{
+	uint_t i, size;
+	bool_t alloc = FALSE;
+	caddr_t addr;
+
+	if (!xdrmem_dec_uint(xdrs, sizep))
+		return FALSE;
+
+	size = *sizep;
+
+	if (size > maxsize || size > UINT_MAX / elsize)
+		return FALSE;
+
+	/*
+	 * The Solaris man page says: "If *arrp is NULL when decoding,
+	 * xdr_array() allocates memory and *arrp points to it".
+	 */
+	if (*arrp == NULL) {
+		BUILD_BUG_ON(sizeof(uint_t) > sizeof(size_t));
+
+		*arrp = kmem_alloc(size * elsize, KM_NOSLEEP);
+		if (*arrp == NULL)
+			return FALSE;
+
+		alloc = TRUE;
+	}
+
+	addr = *arrp;
+
+	for (i = 0; i < size; i++) {
+		if (!elproc(xdrs, addr)) {
+			if (alloc)
+				kmem_free(*arrp, size * elsize);
+			return FALSE;
+		}
+		addr += elsize;
+	}
+
+	return TRUE;
+}
+
+static bool_t
+xdr_enc_string(XDR *xdrs, char **sp, const uint_t maxsize)
+{
+	size_t slen = strlen(*sp);
+	uint_t len;
+
+	if (slen > maxsize)
+		return FALSE;
+
+	len = slen;
+
+	if (!xdrmem_enc_uint(xdrs, &len))
+		return FALSE;
+
+	return xdrmem_enc_bytes(xdrs, *sp, len);
+}
+
+static bool_t
+xdr_dec_string(XDR *xdrs, char **sp, const uint_t maxsize)
+{
+	uint_t size;
+	bool_t alloc = FALSE;
+
+	if (!xdrmem_dec_uint(xdrs, &size))
+		return FALSE;
+
+	if (size > maxsize || size > UINT_MAX - 1)
+		return FALSE;
+
+	/*
+	 * Solaris man page: "If *sp is NULL when decoding, xdr_string()
+	 * allocates memory and *sp points to it".
+	 */
+	if (*sp == NULL) {
+		BUILD_BUG_ON(sizeof(uint_t) > sizeof(size_t));
+
+		*sp = kmem_alloc(size + 1, KM_NOSLEEP);
+		if (*sp == NULL)
+			return FALSE;
+
+		alloc = TRUE;
+	}
+
+	if (!xdrmem_dec_bytes(xdrs, *sp, size))
+		goto fail;
+
+	if (memchr(*sp, 0, size) != NULL)
+		goto fail;
+
+	(*sp)[size] = '\0';
+
+	return TRUE;
+
+fail:
+	if (alloc)
+		kmem_free(*sp, size + 1);
+
+	return FALSE;
+}
+
+static struct xdr_ops xdrmem_encode_ops = {
+	.xdr_control      = xdrmem_control,
+	.xdr_char         = xdrmem_enc_char,
+	.xdr_u_short      = xdrmem_enc_ushort,
+	.xdr_u_int        = xdrmem_enc_uint,
+	.xdr_u_longlong_t = xdrmem_enc_ulonglong,
+	.xdr_opaque       = xdrmem_enc_bytes,
+	.xdr_string       = xdr_enc_string,
+	.xdr_array        = xdr_enc_array
+};
+
+static struct xdr_ops xdrmem_decode_ops = {
+	.xdr_control      = xdrmem_control,
+	.xdr_char         = xdrmem_dec_char,
+	.xdr_u_short      = xdrmem_dec_ushort,
+	.xdr_u_int        = xdrmem_dec_uint,
+	.xdr_u_longlong_t = xdrmem_dec_ulonglong,
+	.xdr_opaque       = xdrmem_dec_bytes,
+	.xdr_string       = xdr_dec_string,
+	.xdr_array        = xdr_dec_array
+};
+
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/module/spl/spl-zlib.c
@@ -0,0 +1,217 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+ *****************************************************************************
+ *  z_compress_level/z_uncompress are nearly identical copies of the
+ *  compress2/uncompress functions provided by the official zlib package
+ *  available at http://zlib.net/.  The only changes made we to slightly
+ *  adapt the functions called to match the linux kernel implementation
+ *  of zlib.  The full zlib license follows:
+ *
+ *  zlib.h -- interface of the 'zlib' general purpose compression library
+ *  version 1.2.5, April 19th, 2010
+ *
+ *  Copyright (C) 1995-2010 Jean-loup Gailly and Mark Adler
+ *
+ *  This software is provided 'as-is', without any express or implied
+ *  warranty.  In no event will the authors be held liable for any damages
+ *  arising from the use of this software.
+ *
+ *  Permission is granted to anyone to use this software for any purpose,
+ *  including commercial applications, and to alter it and redistribute it
+ *  freely, subject to the following restrictions:
+ *
+ *  1. The origin of this software must not be misrepresented; you must not
+ *     claim that you wrote the original software. If you use this software
+ *     in a product, an acknowledgment in the product documentation would be
+ *     appreciated but is not required.
+ *  2. Altered source versions must be plainly marked as such, and must not be
+ *     misrepresented as being the original software.
+ *  3. This notice may not be removed or altered from any source distribution.
+ *
+ *  Jean-loup Gailly
+ *  Mark Adler
+\*****************************************************************************/
+
+
+#include <sys/kmem.h>
+#include <sys/kmem_cache.h>
+#include <sys/zmod.h>
+#include <linux/zlib_compat.h>
+
+static spl_kmem_cache_t *zlib_workspace_cache;
+
+/*
+ * A kmem_cache is used for the zlib workspaces to avoid having to vmalloc
+ * and vfree for every call.  Using a kmem_cache also has the advantage
+ * that improves the odds that the memory used will be local to this cpu.
+ * To further improve things it might be wise to create a dedicated per-cpu
+ * workspace for use.  This would take some additional care because we then
+ * must disable preemption around the critical section, and verify that
+ * zlib_deflate* and zlib_inflate* never internally call schedule().
+ */
+static void *
+zlib_workspace_alloc(int flags)
+{
+	return kmem_cache_alloc(zlib_workspace_cache, flags & ~(__GFP_FS));
+}
+
+static void
+zlib_workspace_free(void *workspace)
+{
+	kmem_cache_free(zlib_workspace_cache, workspace);
+}
+
+/*
+ * Compresses the source buffer into the destination buffer. The level
+ * parameter has the same meaning as in deflateInit.  sourceLen is the byte
+ * length of the source buffer. Upon entry, destLen is the total size of the
+ * destination buffer, which must be at least 0.1% larger than sourceLen plus
+ * 12 bytes. Upon exit, destLen is the actual size of the compressed buffer.
+ *
+ * compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
+ * memory, Z_BUF_ERROR if there was not enough room in the output buffer,
+ * Z_STREAM_ERROR if the level parameter is invalid.
+ */
+int
+z_compress_level(void *dest, size_t *destLen, const void *source,
+                 size_t sourceLen, int level)
+{
+	z_stream stream;
+	int err;
+
+	stream.next_in = (Byte *)source;
+	stream.avail_in = (uInt)sourceLen;
+	stream.next_out = dest;
+	stream.avail_out = (uInt)*destLen;
+
+	if ((size_t)stream.avail_out != *destLen)
+		return Z_BUF_ERROR;
+
+	stream.workspace = zlib_workspace_alloc(KM_SLEEP);
+	if (!stream.workspace)
+		return Z_MEM_ERROR;
+
+	err = zlib_deflateInit(&stream, level);
+	if (err != Z_OK) {
+		zlib_workspace_free(stream.workspace);
+		return err;
+	}
+
+	err = zlib_deflate(&stream, Z_FINISH);
+	if (err != Z_STREAM_END) {
+		zlib_deflateEnd(&stream);
+		zlib_workspace_free(stream.workspace);
+		return err == Z_OK ? Z_BUF_ERROR : err;
+	}
+	*destLen = stream.total_out;
+
+	err = zlib_deflateEnd(&stream);
+	zlib_workspace_free(stream.workspace);
+
+	return err;
+}
+EXPORT_SYMBOL(z_compress_level);
+
+/*
+ * Decompresses the source buffer into the destination buffer.  sourceLen is
+ * the byte length of the source buffer. Upon entry, destLen is the total
+ * size of the destination buffer, which must be large enough to hold the
+ * entire uncompressed data. (The size of the uncompressed data must have
+ * been saved previously by the compressor and transmitted to the decompressor
+ * by some mechanism outside the scope of this compression library.)
+ * Upon exit, destLen is the actual size of the compressed buffer.
+ * This function can be used to decompress a whole file at once if the
+ * input file is mmap'ed.
+ *
+ * uncompress returns Z_OK if success, Z_MEM_ERROR if there was not
+ * enough memory, Z_BUF_ERROR if there was not enough room in the output
+ * buffer, or Z_DATA_ERROR if the input data was corrupted.
+ */
+int
+z_uncompress(void *dest, size_t *destLen, const void *source, size_t sourceLen)
+{
+	z_stream stream;
+	int err;
+
+	stream.next_in = (Byte *)source;
+	stream.avail_in = (uInt)sourceLen;
+	stream.next_out = dest;
+	stream.avail_out = (uInt)*destLen;
+
+	if ((size_t)stream.avail_out != *destLen)
+		return Z_BUF_ERROR;
+
+	stream.workspace = zlib_workspace_alloc(KM_SLEEP);
+	if (!stream.workspace)
+		return Z_MEM_ERROR;
+
+	err = zlib_inflateInit(&stream);
+	if (err != Z_OK) {
+		zlib_workspace_free(stream.workspace);
+		return err;
+	}
+
+	err = zlib_inflate(&stream, Z_FINISH);
+	if (err != Z_STREAM_END) {
+		zlib_inflateEnd(&stream);
+		zlib_workspace_free(stream.workspace);
+
+		if (err == Z_NEED_DICT ||
+		   (err == Z_BUF_ERROR && stream.avail_in == 0))
+			return Z_DATA_ERROR;
+
+		return err;
+	}
+	*destLen = stream.total_out;
+
+	err = zlib_inflateEnd(&stream);
+	zlib_workspace_free(stream.workspace);
+
+	return err;
+}
+EXPORT_SYMBOL(z_uncompress);
+
+int
+spl_zlib_init(void)
+{
+	int size;
+
+	size = MAX(spl_zlib_deflate_workspacesize(MAX_WBITS, MAX_MEM_LEVEL),
+	    zlib_inflate_workspacesize());
+
+	zlib_workspace_cache = kmem_cache_create(
+	    "spl_zlib_workspace_cache",
+	    size, 0, NULL, NULL, NULL, NULL, NULL,
+	    KMC_VMEM | KMC_NOEMERGENCY);
+        if (!zlib_workspace_cache)
+		return (1);
+
+        return (0);
+}
+
+void
+spl_zlib_fini(void)
+{
+	kmem_cache_destroy(zlib_workspace_cache);
+        zlib_workspace_cache = NULL;
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/module/splat/Makefile.in
@@ -0,0 +1,28 @@
+# Makefile.in for splat kernel module
+
+src = @abs_top_srcdir@/module/splat
+obj = @abs_builddir@
+
+MODULE := splat
+EXTRA_CFLAGS = $(SPL_MODULE_CFLAGS) @KERNELCPPFLAGS@
+
+# Solaris Porting LAyer Tests
+obj-$(CONFIG_SPL) := $(MODULE).o
+
+$(MODULE)-objs += splat-ctl.o
+$(MODULE)-objs += splat-kmem.o
+$(MODULE)-objs += splat-taskq.o
+$(MODULE)-objs += splat-random.o
+$(MODULE)-objs += splat-mutex.o
+$(MODULE)-objs += splat-condvar.o
+$(MODULE)-objs += splat-thread.o
+$(MODULE)-objs += splat-rwlock.o
+$(MODULE)-objs += splat-time.o
+$(MODULE)-objs += splat-vnode.o
+$(MODULE)-objs += splat-kobj.o
+$(MODULE)-objs += splat-atomic.o
+$(MODULE)-objs += splat-list.o
+$(MODULE)-objs += splat-generic.o
+$(MODULE)-objs += splat-cred.o
+$(MODULE)-objs += splat-zlib.o
+$(MODULE)-objs += splat-linux.o
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/module/splat/splat-atomic.c
@@ -0,0 +1,232 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+ *****************************************************************************
+ *  Solaris Porting LAyer Tests (SPLAT) Atomic Tests.
+\*****************************************************************************/
+
+#include <sys/atomic.h>
+#include <sys/thread.h>
+#include <sys/mutex.h>
+#include <linux/mm_compat.h>
+#include <linux/slab.h>
+#include "splat-internal.h"
+
+#define SPLAT_ATOMIC_NAME		"atomic"
+#define SPLAT_ATOMIC_DESC		"Kernel Atomic Tests"
+
+#define SPLAT_ATOMIC_TEST1_ID		0x0b01
+#define SPLAT_ATOMIC_TEST1_NAME		"64-bit"
+#define SPLAT_ATOMIC_TEST1_DESC		"Validate 64-bit atomic ops"
+
+#define SPLAT_ATOMIC_TEST_MAGIC		0x43435454UL
+#define SPLAT_ATOMIC_INIT_VALUE		10000000UL
+
+typedef enum {
+	SPLAT_ATOMIC_INC_64    = 0,
+	SPLAT_ATOMIC_DEC_64    = 1,
+	SPLAT_ATOMIC_ADD_64    = 2,
+	SPLAT_ATOMIC_SUB_64    = 3,
+	SPLAT_ATOMIC_ADD_64_NV = 4,
+	SPLAT_ATOMIC_SUB_64_NV = 5,
+	SPLAT_ATOMIC_COUNT_64  = 6
+} atomic_op_t;
+
+typedef struct atomic_priv {
+        unsigned long ap_magic;
+        struct file *ap_file;
+	kmutex_t ap_lock;
+        wait_queue_head_t ap_waitq;
+	volatile uint64_t ap_atomic;
+	volatile uint64_t ap_atomic_exited;
+	atomic_op_t ap_op;
+
+} atomic_priv_t;
+
+static void
+splat_atomic_work(void *priv)
+{
+	atomic_priv_t *ap;
+	atomic_op_t op;
+	int i;
+
+	ap = (atomic_priv_t *)priv;
+	ASSERT(ap->ap_magic == SPLAT_ATOMIC_TEST_MAGIC);
+
+	mutex_enter(&ap->ap_lock);
+	op = ap->ap_op;
+	wake_up(&ap->ap_waitq);
+	mutex_exit(&ap->ap_lock);
+
+        splat_vprint(ap->ap_file, SPLAT_ATOMIC_TEST1_NAME,
+	             "Thread %d successfully started: %lu/%lu\n", op,
+		     (long unsigned)ap->ap_atomic,
+		     (long unsigned)ap->ap_atomic_exited);
+
+	for (i = 0; i < SPLAT_ATOMIC_INIT_VALUE / 10; i++) {
+
+		/* Periodically sleep to mix up the ordering */
+		if ((i % (SPLAT_ATOMIC_INIT_VALUE / 100)) == 0) {
+		        splat_vprint(ap->ap_file, SPLAT_ATOMIC_TEST1_NAME,
+			     "Thread %d sleeping: %lu/%lu\n", op,
+			     (long unsigned)ap->ap_atomic,
+			     (long unsigned)ap->ap_atomic_exited);
+		        set_current_state(TASK_INTERRUPTIBLE);
+			schedule_timeout(HZ / 100);
+		}
+
+		switch (op) {
+			case SPLAT_ATOMIC_INC_64:
+				atomic_inc_64(&ap->ap_atomic);
+				break;
+			case SPLAT_ATOMIC_DEC_64:
+				atomic_dec_64(&ap->ap_atomic);
+				break;
+			case SPLAT_ATOMIC_ADD_64:
+				atomic_add_64(&ap->ap_atomic, 3);
+				break;
+			case SPLAT_ATOMIC_SUB_64:
+				atomic_sub_64(&ap->ap_atomic, 3);
+				break;
+			case SPLAT_ATOMIC_ADD_64_NV:
+				atomic_add_64_nv(&ap->ap_atomic, 5);
+				break;
+			case SPLAT_ATOMIC_SUB_64_NV:
+				atomic_sub_64_nv(&ap->ap_atomic, 5);
+				break;
+			default:
+				PANIC("Undefined op %d\n", op);
+		}
+	}
+
+	atomic_inc_64(&ap->ap_atomic_exited);
+
+        splat_vprint(ap->ap_file, SPLAT_ATOMIC_TEST1_NAME,
+	             "Thread %d successfully exited: %lu/%lu\n", op,
+		     (long unsigned)ap->ap_atomic,
+		     (long unsigned)ap->ap_atomic_exited);
+
+	wake_up(&ap->ap_waitq);
+	thread_exit();
+}
+
+static int
+splat_atomic_test1_cond(atomic_priv_t *ap, int started)
+{
+	return (ap->ap_atomic_exited == started);
+}
+
+static int
+splat_atomic_test1(struct file *file, void *arg)
+{
+	atomic_priv_t ap;
+        DEFINE_WAIT(wait);
+	kthread_t *thr;
+	int i, rc = 0;
+
+	ap.ap_magic = SPLAT_ATOMIC_TEST_MAGIC;
+	ap.ap_file = file;
+	mutex_init(&ap.ap_lock, SPLAT_ATOMIC_TEST1_NAME, MUTEX_DEFAULT, NULL);
+	init_waitqueue_head(&ap.ap_waitq);
+	ap.ap_atomic = SPLAT_ATOMIC_INIT_VALUE;
+	ap.ap_atomic_exited = 0;
+
+	for (i = 0; i < SPLAT_ATOMIC_COUNT_64; i++) {
+		mutex_enter(&ap.ap_lock);
+		ap.ap_op = i;
+
+		thr = (kthread_t *)thread_create(NULL, 0, splat_atomic_work,
+						 &ap, 0, &p0, TS_RUN,
+						 defclsyspri);
+		if (thr == NULL) {
+			rc = -ESRCH;
+			mutex_exit(&ap.ap_lock);
+			break;
+		}
+
+		/* Prepare to wait, the new thread will wake us once it
+		 * has made a copy of the unique private passed data */
+                prepare_to_wait(&ap.ap_waitq, &wait, TASK_UNINTERRUPTIBLE);
+		mutex_exit(&ap.ap_lock);
+		schedule();
+	}
+
+	wait_event(ap.ap_waitq, splat_atomic_test1_cond(&ap, i));
+
+	if (rc) {
+		splat_vprint(file, SPLAT_ATOMIC_TEST1_NAME, "Only started "
+			     "%d/%d test threads\n", i, SPLAT_ATOMIC_COUNT_64);
+		return rc;
+	}
+
+	if (ap.ap_atomic != SPLAT_ATOMIC_INIT_VALUE) {
+		splat_vprint(file, SPLAT_ATOMIC_TEST1_NAME,
+			     "Final value %lu does not match initial value %lu\n",
+			     (long unsigned)ap.ap_atomic, SPLAT_ATOMIC_INIT_VALUE);
+		return -EINVAL;
+	}
+
+        splat_vprint(file, SPLAT_ATOMIC_TEST1_NAME,
+	           "Success initial and final values match, %lu == %lu\n",
+	           (long unsigned)ap.ap_atomic, SPLAT_ATOMIC_INIT_VALUE);
+
+	mutex_destroy(&ap.ap_lock);
+
+	return 0;
+}
+
+splat_subsystem_t *
+splat_atomic_init(void)
+{
+        splat_subsystem_t *sub;
+
+        sub = kmalloc(sizeof(*sub), GFP_KERNEL);
+        if (sub == NULL)
+                return NULL;
+
+        memset(sub, 0, sizeof(*sub));
+        strncpy(sub->desc.name, SPLAT_ATOMIC_NAME, SPLAT_NAME_SIZE);
+        strncpy(sub->desc.desc, SPLAT_ATOMIC_DESC, SPLAT_DESC_SIZE);
+        INIT_LIST_HEAD(&sub->subsystem_list);
+        INIT_LIST_HEAD(&sub->test_list);
+        spin_lock_init(&sub->test_lock);
+        sub->desc.id = SPLAT_SUBSYSTEM_ATOMIC;
+
+        SPLAT_TEST_INIT(sub, SPLAT_ATOMIC_TEST1_NAME, SPLAT_ATOMIC_TEST1_DESC,
+                      SPLAT_ATOMIC_TEST1_ID, splat_atomic_test1);
+
+        return sub;
+}
+
+void
+splat_atomic_fini(splat_subsystem_t *sub)
+{
+        ASSERT(sub);
+        SPLAT_TEST_FINI(sub, SPLAT_ATOMIC_TEST1_ID);
+
+        kfree(sub);
+}
+
+int
+splat_atomic_id(void) {
+        return SPLAT_SUBSYSTEM_ATOMIC;
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/module/splat/splat-condvar.c
@@ -0,0 +1,511 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+ *****************************************************************************
+ *  Solaris Porting LAyer Tests (SPLAT) Condition Variable Tests.
+\*****************************************************************************/
+
+#include <sys/condvar.h>
+#include <sys/timer.h>
+#include <sys/thread.h>
+#include "splat-internal.h"
+
+#define SPLAT_CONDVAR_NAME		"condvar"
+#define SPLAT_CONDVAR_DESC		"Kernel Condition Variable Tests"
+
+#define SPLAT_CONDVAR_TEST1_ID		0x0501
+#define SPLAT_CONDVAR_TEST1_NAME	"signal1"
+#define SPLAT_CONDVAR_TEST1_DESC	"Wake a single thread, cv_wait()/cv_signal()"
+
+#define SPLAT_CONDVAR_TEST2_ID		0x0502
+#define SPLAT_CONDVAR_TEST2_NAME	"broadcast1"
+#define SPLAT_CONDVAR_TEST2_DESC	"Wake all threads, cv_wait()/cv_broadcast()"
+
+#define SPLAT_CONDVAR_TEST3_ID		0x0503
+#define SPLAT_CONDVAR_TEST3_NAME	"signal2"
+#define SPLAT_CONDVAR_TEST3_DESC	"Wake a single thread, cv_wait_timeout()/cv_signal()"
+
+#define SPLAT_CONDVAR_TEST4_ID		0x0504
+#define SPLAT_CONDVAR_TEST4_NAME	"broadcast2"
+#define SPLAT_CONDVAR_TEST4_DESC	"Wake all threads, cv_wait_timeout()/cv_broadcast()"
+
+#define SPLAT_CONDVAR_TEST5_ID		0x0505
+#define SPLAT_CONDVAR_TEST5_NAME	"timeout"
+#define SPLAT_CONDVAR_TEST5_DESC	"Timeout thread, cv_wait_timeout()"
+
+#define SPLAT_CONDVAR_TEST_MAGIC	0x115599DDUL
+#define SPLAT_CONDVAR_TEST_NAME		"condvar"
+#define SPLAT_CONDVAR_TEST_COUNT	8
+
+typedef struct condvar_priv {
+	unsigned long cv_magic;
+	struct file *cv_file;
+	kcondvar_t cv_condvar;
+	kmutex_t cv_mtx;
+} condvar_priv_t;
+
+typedef struct condvar_thr {
+	const char *ct_name;
+	condvar_priv_t *ct_cvp;
+	struct task_struct *ct_thread;
+	int ct_rc;
+} condvar_thr_t;
+
+int
+splat_condvar_test12_thread(void *arg)
+{
+	condvar_thr_t *ct = (condvar_thr_t *)arg;
+	condvar_priv_t *cv = ct->ct_cvp;
+
+	ASSERT(cv->cv_magic == SPLAT_CONDVAR_TEST_MAGIC);
+
+	mutex_enter(&cv->cv_mtx);
+	splat_vprint(cv->cv_file, ct->ct_name,
+	    "%s thread sleeping with %d waiters\n",
+	    ct->ct_thread->comm, atomic_read(&cv->cv_condvar.cv_waiters));
+	cv_wait(&cv->cv_condvar, &cv->cv_mtx);
+	splat_vprint(cv->cv_file, ct->ct_name,
+	    "%s thread woken %d waiters remain\n",
+	    ct->ct_thread->comm, atomic_read(&cv->cv_condvar.cv_waiters));
+	mutex_exit(&cv->cv_mtx);
+
+	/* wait for main thread reap us */
+	while (!kthread_should_stop())
+		schedule();
+	return 0;
+}
+
+static int
+splat_condvar_test1(struct file *file, void *arg)
+{
+	int i, count = 0, rc = 0;
+	condvar_thr_t ct[SPLAT_CONDVAR_TEST_COUNT];
+	condvar_priv_t cv;
+
+	cv.cv_magic = SPLAT_CONDVAR_TEST_MAGIC;
+	cv.cv_file = file;
+	mutex_init(&cv.cv_mtx, SPLAT_CONDVAR_TEST_NAME, MUTEX_DEFAULT, NULL);
+	cv_init(&cv.cv_condvar, NULL, CV_DEFAULT, NULL);
+
+	/* Create some threads, the exact number isn't important just as
+	 * long as we know how many we managed to create and should expect. */
+	for (i = 0; i < SPLAT_CONDVAR_TEST_COUNT; i++) {
+		ct[i].ct_cvp = &cv;
+		ct[i].ct_name = SPLAT_CONDVAR_TEST1_NAME;
+		ct[i].ct_rc = 0;
+		ct[i].ct_thread = spl_kthread_create(splat_condvar_test12_thread,
+		    &ct[i], "%s/%d", SPLAT_CONDVAR_TEST_NAME, i);
+
+		if (!IS_ERR(ct[i].ct_thread)) {
+			wake_up_process(ct[i].ct_thread);
+			count++;
+		}
+	}
+
+	/* Wait until all threads are waiting on the condition variable */
+	while (atomic_read(&cv.cv_condvar.cv_waiters) != count)
+		schedule();
+
+	/* Wake a single thread at a time, wait until it exits */
+	for (i = 1; i <= count; i++) {
+		cv_signal(&cv.cv_condvar);
+
+		while (atomic_read(&cv.cv_condvar.cv_waiters) > (count - i))
+			schedule();
+
+		/* Correct behavior 1 thread woken */
+		if (atomic_read(&cv.cv_condvar.cv_waiters) == (count - i))
+			continue;
+
+                splat_vprint(file, SPLAT_CONDVAR_TEST1_NAME, "Attempted to "
+			   "wake %d thread but work %d threads woke\n",
+			   1, count - atomic_read(&cv.cv_condvar.cv_waiters));
+		rc = -EINVAL;
+		break;
+	}
+
+	if (!rc)
+                splat_vprint(file, SPLAT_CONDVAR_TEST1_NAME, "Correctly woke "
+			   "%d sleeping threads %d at a time\n", count, 1);
+
+	/* Wait until that last nutex is dropped */
+	while (mutex_owner(&cv.cv_mtx))
+		schedule();
+
+	/* Wake everything for the failure case */
+	cv_broadcast(&cv.cv_condvar);
+	cv_destroy(&cv.cv_condvar);
+
+	/* wait for threads to exit */
+	for (i = 0; i < SPLAT_CONDVAR_TEST_COUNT; i++) {
+		if (!IS_ERR(ct[i].ct_thread))
+			kthread_stop(ct[i].ct_thread);
+	}
+	mutex_destroy(&cv.cv_mtx);
+
+	return rc;
+}
+
+static int
+splat_condvar_test2(struct file *file, void *arg)
+{
+	int i, count = 0, rc = 0;
+	condvar_thr_t ct[SPLAT_CONDVAR_TEST_COUNT];
+	condvar_priv_t cv;
+
+	cv.cv_magic = SPLAT_CONDVAR_TEST_MAGIC;
+	cv.cv_file = file;
+	mutex_init(&cv.cv_mtx, SPLAT_CONDVAR_TEST_NAME, MUTEX_DEFAULT, NULL);
+	cv_init(&cv.cv_condvar, NULL, CV_DEFAULT, NULL);
+
+	/* Create some threads, the exact number isn't important just as
+	 * long as we know how many we managed to create and should expect. */
+	for (i = 0; i < SPLAT_CONDVAR_TEST_COUNT; i++) {
+		ct[i].ct_cvp = &cv;
+		ct[i].ct_name = SPLAT_CONDVAR_TEST2_NAME;
+		ct[i].ct_rc = 0;
+		ct[i].ct_thread = spl_kthread_create(splat_condvar_test12_thread,
+		    &ct[i], "%s/%d", SPLAT_CONDVAR_TEST_NAME, i);
+
+		if (!IS_ERR(ct[i].ct_thread)) {
+			wake_up_process(ct[i].ct_thread);
+			count++;
+		}
+	}
+
+	/* Wait until all threads are waiting on the condition variable */
+	while (atomic_read(&cv.cv_condvar.cv_waiters) != count)
+		schedule();
+
+	/* Wake all threads waiting on the condition variable */
+	cv_broadcast(&cv.cv_condvar);
+
+	/* Wait until all threads have exited */
+	while ((atomic_read(&cv.cv_condvar.cv_waiters) > 0) || mutex_owner(&cv.cv_mtx))
+		schedule();
+
+        splat_vprint(file, SPLAT_CONDVAR_TEST2_NAME, "Correctly woke all "
+			   "%d sleeping threads at once\n", count);
+
+	/* Wake everything for the failure case */
+	cv_destroy(&cv.cv_condvar);
+
+	/* wait for threads to exit */
+	for (i = 0; i < SPLAT_CONDVAR_TEST_COUNT; i++) {
+		if (!IS_ERR(ct[i].ct_thread))
+			kthread_stop(ct[i].ct_thread);
+	}
+	mutex_destroy(&cv.cv_mtx);
+
+	return rc;
+}
+
+int
+splat_condvar_test34_thread(void *arg)
+{
+	condvar_thr_t *ct = (condvar_thr_t *)arg;
+	condvar_priv_t *cv = ct->ct_cvp;
+	clock_t rc;
+
+	ASSERT(cv->cv_magic == SPLAT_CONDVAR_TEST_MAGIC);
+
+	mutex_enter(&cv->cv_mtx);
+	splat_vprint(cv->cv_file, ct->ct_name,
+	    "%s thread sleeping with %d waiters\n",
+	    ct->ct_thread->comm, atomic_read(&cv->cv_condvar.cv_waiters));
+
+	/* Sleep no longer than 3 seconds, for this test we should
+	 * actually never sleep that long without being woken up. */
+	rc = cv_timedwait(&cv->cv_condvar, &cv->cv_mtx, lbolt + HZ * 3);
+	if (rc == -1) {
+		ct->ct_rc = -ETIMEDOUT;
+		splat_vprint(cv->cv_file, ct->ct_name, "%s thread timed out, "
+		    "should have been woken\n", ct->ct_thread->comm);
+	} else {
+		splat_vprint(cv->cv_file, ct->ct_name,
+		    "%s thread woken %d waiters remain\n",
+		    ct->ct_thread->comm,
+		    atomic_read(&cv->cv_condvar.cv_waiters));
+	}
+
+	mutex_exit(&cv->cv_mtx);
+
+	/* wait for main thread reap us */
+	while (!kthread_should_stop())
+		schedule();
+	return 0;
+}
+
+static int
+splat_condvar_test3(struct file *file, void *arg)
+{
+	int i, count = 0, rc = 0;
+	condvar_thr_t ct[SPLAT_CONDVAR_TEST_COUNT];
+	condvar_priv_t cv;
+
+	cv.cv_magic = SPLAT_CONDVAR_TEST_MAGIC;
+	cv.cv_file = file;
+	mutex_init(&cv.cv_mtx, SPLAT_CONDVAR_TEST_NAME, MUTEX_DEFAULT, NULL);
+	cv_init(&cv.cv_condvar, NULL, CV_DEFAULT, NULL);
+
+	/* Create some threads, the exact number isn't important just as
+	 * long as we know how many we managed to create and should expect. */
+	for (i = 0; i < SPLAT_CONDVAR_TEST_COUNT; i++) {
+		ct[i].ct_cvp = &cv;
+		ct[i].ct_name = SPLAT_CONDVAR_TEST3_NAME;
+		ct[i].ct_rc = 0;
+		ct[i].ct_thread = spl_kthread_create(splat_condvar_test34_thread,
+		    &ct[i], "%s/%d", SPLAT_CONDVAR_TEST_NAME, i);
+
+		if (!IS_ERR(ct[i].ct_thread)) {
+			wake_up_process(ct[i].ct_thread);
+			count++;
+		}
+	}
+
+	/* Wait until all threads are waiting on the condition variable */
+	while (atomic_read(&cv.cv_condvar.cv_waiters) != count)
+		schedule();
+
+	/* Wake a single thread at a time, wait until it exits */
+	for (i = 1; i <= count; i++) {
+		cv_signal(&cv.cv_condvar);
+
+		while (atomic_read(&cv.cv_condvar.cv_waiters) > (count - i))
+			schedule();
+
+		/* Correct behavior 1 thread woken */
+		if (atomic_read(&cv.cv_condvar.cv_waiters) == (count - i))
+			continue;
+
+                splat_vprint(file, SPLAT_CONDVAR_TEST3_NAME, "Attempted to "
+			   "wake %d thread but work %d threads woke\n",
+			   1, count - atomic_read(&cv.cv_condvar.cv_waiters));
+		rc = -EINVAL;
+		break;
+	}
+
+	/* Validate no waiting thread timed out early */
+	for (i = 0; i < count; i++)
+		if (ct[i].ct_rc)
+			rc = ct[i].ct_rc;
+
+	if (!rc)
+                splat_vprint(file, SPLAT_CONDVAR_TEST3_NAME, "Correctly woke "
+			   "%d sleeping threads %d at a time\n", count, 1);
+
+	/* Wait until that last nutex is dropped */
+	while (mutex_owner(&cv.cv_mtx))
+		schedule();
+
+	/* Wake everything for the failure case */
+	cv_broadcast(&cv.cv_condvar);
+	cv_destroy(&cv.cv_condvar);
+
+	/* wait for threads to exit */
+	for (i = 0; i < SPLAT_CONDVAR_TEST_COUNT; i++) {
+		if (!IS_ERR(ct[i].ct_thread))
+			kthread_stop(ct[i].ct_thread);
+	}
+	mutex_destroy(&cv.cv_mtx);
+
+	return rc;
+}
+
+static int
+splat_condvar_test4(struct file *file, void *arg)
+{
+	int i, count = 0, rc = 0;
+	condvar_thr_t ct[SPLAT_CONDVAR_TEST_COUNT];
+	condvar_priv_t cv;
+
+	cv.cv_magic = SPLAT_CONDVAR_TEST_MAGIC;
+	cv.cv_file = file;
+	mutex_init(&cv.cv_mtx, SPLAT_CONDVAR_TEST_NAME, MUTEX_DEFAULT, NULL);
+	cv_init(&cv.cv_condvar, NULL, CV_DEFAULT, NULL);
+
+	/* Create some threads, the exact number isn't important just as
+	 * long as we know how many we managed to create and should expect. */
+	for (i = 0; i < SPLAT_CONDVAR_TEST_COUNT; i++) {
+		ct[i].ct_cvp = &cv;
+		ct[i].ct_name = SPLAT_CONDVAR_TEST3_NAME;
+		ct[i].ct_rc = 0;
+		ct[i].ct_thread = spl_kthread_create(splat_condvar_test34_thread,
+		    &ct[i], "%s/%d", SPLAT_CONDVAR_TEST_NAME, i);
+
+		if (!IS_ERR(ct[i].ct_thread)) {
+			wake_up_process(ct[i].ct_thread);
+			count++;
+		}
+	}
+
+	/* Wait until all threads are waiting on the condition variable */
+	while (atomic_read(&cv.cv_condvar.cv_waiters) != count)
+		schedule();
+
+	/* Wake a single thread at a time, wait until it exits */
+	for (i = 1; i <= count; i++) {
+		cv_signal(&cv.cv_condvar);
+
+		while (atomic_read(&cv.cv_condvar.cv_waiters) > (count - i))
+			schedule();
+
+		/* Correct behavior 1 thread woken */
+		if (atomic_read(&cv.cv_condvar.cv_waiters) == (count - i))
+			continue;
+
+                splat_vprint(file, SPLAT_CONDVAR_TEST3_NAME, "Attempted to "
+			   "wake %d thread but work %d threads woke\n",
+			   1, count - atomic_read(&cv.cv_condvar.cv_waiters));
+		rc = -EINVAL;
+		break;
+	}
+
+	/* Validate no waiting thread timed out early */
+	for (i = 0; i < count; i++)
+		if (ct[i].ct_rc)
+			rc = ct[i].ct_rc;
+
+	if (!rc)
+                splat_vprint(file, SPLAT_CONDVAR_TEST3_NAME, "Correctly woke "
+			   "%d sleeping threads %d at a time\n", count, 1);
+
+	/* Wait until that last nutex is dropped */
+	while (mutex_owner(&cv.cv_mtx))
+		schedule();
+
+	/* Wake everything for the failure case */
+	cv_broadcast(&cv.cv_condvar);
+	cv_destroy(&cv.cv_condvar);
+
+	/* wait for threads to exit */
+	for (i = 0; i < SPLAT_CONDVAR_TEST_COUNT; i++) {
+		if (!IS_ERR(ct[i].ct_thread))
+			kthread_stop(ct[i].ct_thread);
+	}
+	mutex_destroy(&cv.cv_mtx);
+
+	return rc;
+}
+
+static int
+splat_condvar_test5(struct file *file, void *arg)
+{
+        kcondvar_t condvar;
+        kmutex_t mtx;
+	clock_t time_left, time_before, time_after, time_delta;
+	uint64_t whole_delta;
+	uint32_t remain_delta;
+	int rc = 0;
+
+	mutex_init(&mtx, SPLAT_CONDVAR_TEST_NAME, MUTEX_DEFAULT, NULL);
+	cv_init(&condvar, NULL, CV_DEFAULT, NULL);
+
+        splat_vprint(file, SPLAT_CONDVAR_TEST5_NAME, "Thread going to sleep for "
+	           "%d second and expecting to be woken by timeout\n", 1);
+
+	/* Allow a 1 second timeout, plenty long to validate correctness. */
+	time_before = lbolt;
+	mutex_enter(&mtx);
+	time_left = cv_timedwait(&condvar, &mtx, lbolt + HZ);
+	mutex_exit(&mtx);
+	time_after = lbolt;
+	time_delta = time_after - time_before; /* XXX - Handle jiffie wrap */
+	whole_delta  = time_delta;
+	remain_delta = do_div(whole_delta, HZ);
+
+	if (time_left == -1) {
+		if (time_delta >= HZ) {
+			splat_vprint(file, SPLAT_CONDVAR_TEST5_NAME,
+			           "Thread correctly timed out and was asleep "
+			           "for %d.%d seconds (%d second min)\n",
+			           (int)whole_delta, (int)remain_delta, 1);
+		} else {
+			splat_vprint(file, SPLAT_CONDVAR_TEST5_NAME,
+			           "Thread correctly timed out but was only "
+			           "asleep for %d.%d seconds (%d second "
+			           "min)\n", (int)whole_delta,
+				   (int)remain_delta, 1);
+			rc = -ETIMEDOUT;
+		}
+	} else {
+		splat_vprint(file, SPLAT_CONDVAR_TEST5_NAME,
+		           "Thread exited after only %d.%d seconds, it "
+		           "did not hit the %d second timeout\n",
+		           (int)whole_delta, (int)remain_delta, 1);
+		rc = -ETIMEDOUT;
+	}
+
+	cv_destroy(&condvar);
+	mutex_destroy(&mtx);
+
+	return rc;
+}
+
+splat_subsystem_t *
+splat_condvar_init(void)
+{
+        splat_subsystem_t *sub;
+
+        sub = kmalloc(sizeof(*sub), GFP_KERNEL);
+        if (sub == NULL)
+                return NULL;
+
+        memset(sub, 0, sizeof(*sub));
+        strncpy(sub->desc.name, SPLAT_CONDVAR_NAME, SPLAT_NAME_SIZE);
+        strncpy(sub->desc.desc, SPLAT_CONDVAR_DESC, SPLAT_DESC_SIZE);
+        INIT_LIST_HEAD(&sub->subsystem_list);
+        INIT_LIST_HEAD(&sub->test_list);
+        spin_lock_init(&sub->test_lock);
+        sub->desc.id = SPLAT_SUBSYSTEM_CONDVAR;
+
+        SPLAT_TEST_INIT(sub, SPLAT_CONDVAR_TEST1_NAME, SPLAT_CONDVAR_TEST1_DESC,
+                      SPLAT_CONDVAR_TEST1_ID, splat_condvar_test1);
+        SPLAT_TEST_INIT(sub, SPLAT_CONDVAR_TEST2_NAME, SPLAT_CONDVAR_TEST2_DESC,
+                      SPLAT_CONDVAR_TEST2_ID, splat_condvar_test2);
+        SPLAT_TEST_INIT(sub, SPLAT_CONDVAR_TEST3_NAME, SPLAT_CONDVAR_TEST3_DESC,
+                      SPLAT_CONDVAR_TEST3_ID, splat_condvar_test3);
+        SPLAT_TEST_INIT(sub, SPLAT_CONDVAR_TEST4_NAME, SPLAT_CONDVAR_TEST4_DESC,
+                      SPLAT_CONDVAR_TEST4_ID, splat_condvar_test4);
+        SPLAT_TEST_INIT(sub, SPLAT_CONDVAR_TEST5_NAME, SPLAT_CONDVAR_TEST5_DESC,
+                      SPLAT_CONDVAR_TEST5_ID, splat_condvar_test5);
+
+        return sub;
+}
+
+void
+splat_condvar_fini(splat_subsystem_t *sub)
+{
+        ASSERT(sub);
+        SPLAT_TEST_FINI(sub, SPLAT_CONDVAR_TEST5_ID);
+        SPLAT_TEST_FINI(sub, SPLAT_CONDVAR_TEST4_ID);
+        SPLAT_TEST_FINI(sub, SPLAT_CONDVAR_TEST3_ID);
+        SPLAT_TEST_FINI(sub, SPLAT_CONDVAR_TEST2_ID);
+        SPLAT_TEST_FINI(sub, SPLAT_CONDVAR_TEST1_ID);
+
+        kfree(sub);
+}
+
+int
+splat_condvar_id(void) {
+        return SPLAT_SUBSYSTEM_CONDVAR;
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/module/splat/splat-cred.c
@@ -0,0 +1,298 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+ *****************************************************************************
+ *  Solaris Porting LAyer Tests (SPLAT) Credential Tests.
+\*****************************************************************************/
+
+#include <sys/cred.h>
+#include <sys/random.h>
+#include "splat-internal.h"
+
+#define SPLAT_CRED_NAME			"cred"
+#define SPLAT_CRED_DESC			"Kernel Cred Tests"
+
+#define SPLAT_CRED_TEST1_ID		0x0e01
+#define SPLAT_CRED_TEST1_NAME		"cred"
+#define SPLAT_CRED_TEST1_DESC		"Task Credential Test"
+
+#define SPLAT_CRED_TEST2_ID		0x0e02
+#define SPLAT_CRED_TEST2_NAME		"kcred"
+#define SPLAT_CRED_TEST2_DESC		"Kernel Credential Test"
+
+#define SPLAT_CRED_TEST3_ID		0x0e03
+#define SPLAT_CRED_TEST3_NAME		"groupmember"
+#define SPLAT_CRED_TEST3_DESC		"Group Member Test"
+
+#define GROUP_STR_SIZE			128
+#define GROUP_STR_REDZONE		16
+
+static int
+splat_cred_test1(struct file *file, void *arg)
+{
+	char str[GROUP_STR_SIZE];
+	uid_t uid, ruid, suid;
+	gid_t gid, rgid, sgid, *groups;
+	int ngroups, i, count = 0;
+
+	uid  = crgetuid(CRED());
+	ruid = crgetruid(CRED());
+	suid = crgetsuid(CRED());
+
+	gid  = crgetgid(CRED());
+	rgid = crgetrgid(CRED());
+	sgid = crgetsgid(CRED());
+
+	crhold(CRED());
+	ngroups = crgetngroups(CRED());
+	groups  = crgetgroups(CRED());
+
+	memset(str, 0, GROUP_STR_SIZE);
+	for (i = 0; i < ngroups; i++) {
+		count += sprintf(str + count, "%d ", groups[i]);
+
+		if (count > (GROUP_STR_SIZE - GROUP_STR_REDZONE)) {
+			splat_vprint(file, SPLAT_CRED_TEST1_NAME,
+				     "Failed too many group entries for temp "
+				     "buffer: %d, %s\n", ngroups, str);
+			return -ENOSPC;
+		}
+	}
+
+	crfree(CRED());
+
+	splat_vprint(file, SPLAT_CRED_TEST1_NAME,
+		     "uid: %d ruid: %d suid: %d "
+		     "gid: %d rgid: %d sgid: %d\n",
+		     uid, ruid, suid, gid, rgid, sgid);
+	splat_vprint(file, SPLAT_CRED_TEST1_NAME,
+		     "ngroups: %d groups: %s\n", ngroups, str);
+
+	if (uid || ruid || suid || gid || rgid || sgid) {
+		splat_vprint(file, SPLAT_CRED_TEST1_NAME,
+			     "Failed expected all uids+gids to be %d\n", 0);
+		return -EIDRM;
+	}
+
+	if (ngroups > NGROUPS_MAX) {
+		splat_vprint(file, SPLAT_CRED_TEST1_NAME,
+			     "Failed ngroups must not exceed NGROUPS_MAX: "
+			     "%d > %d\n", ngroups, NGROUPS_MAX);
+		return -EIDRM;
+	}
+
+	splat_vprint(file, SPLAT_CRED_TEST1_NAME,
+		     "Success sane CRED(): %d\n", 0);
+
+        return 0;
+} /* splat_cred_test1() */
+
+static int
+splat_cred_test2(struct file *file, void *arg)
+{
+	char str[GROUP_STR_SIZE];
+	uid_t uid, ruid, suid;
+	gid_t gid, rgid, sgid, *groups;
+	int ngroups, i, count = 0;
+
+	uid  = crgetuid(kcred);
+	ruid = crgetruid(kcred);
+	suid = crgetsuid(kcred);
+
+	gid  = crgetgid(kcred);
+	rgid = crgetrgid(kcred);
+	sgid = crgetsgid(kcred);
+
+	crhold(kcred);
+	ngroups = crgetngroups(kcred);
+	groups  = crgetgroups(kcred);
+
+	memset(str, 0, GROUP_STR_SIZE);
+	for (i = 0; i < ngroups; i++) {
+		count += sprintf(str + count, "%d ", groups[i]);
+
+		if (count > (GROUP_STR_SIZE - GROUP_STR_REDZONE)) {
+			splat_vprint(file, SPLAT_CRED_TEST2_NAME,
+				     "Failed too many group entries for temp "
+				     "buffer: %d, %s\n", ngroups, str);
+			return -ENOSPC;
+		}
+	}
+
+	crfree(kcred);
+
+	splat_vprint(file, SPLAT_CRED_TEST2_NAME,
+		     "uid: %d ruid: %d suid: %d "
+		     "gid: %d rgid: %d sgid: %d\n",
+		     uid, ruid, suid, gid, rgid, sgid);
+	splat_vprint(file, SPLAT_CRED_TEST2_NAME,
+		     "ngroups: %d groups: %s\n", ngroups, str);
+
+	if (uid || ruid || suid || gid || rgid || sgid) {
+		splat_vprint(file, SPLAT_CRED_TEST2_NAME,
+			     "Failed expected all uids+gids to be %d\n", 0);
+		return -EIDRM;
+	}
+
+	if (ngroups > NGROUPS_MAX) {
+		splat_vprint(file, SPLAT_CRED_TEST2_NAME,
+			     "Failed ngroups must not exceed NGROUPS_MAX: "
+			     "%d > %d\n", ngroups, NGROUPS_MAX);
+		return -EIDRM;
+	}
+
+	splat_vprint(file, SPLAT_CRED_TEST2_NAME,
+		     "Success sane kcred: %d\n", 0);
+
+        return 0;
+} /* splat_cred_test2() */
+
+/*
+ * Verify the groupmember() works correctly by constructing an interesting
+ * CRED() and checking that the expected gids are part of it.
+ */
+static int
+splat_cred_test3(struct file *file, void *arg)
+{
+	gid_t known_gid, missing_gid, tmp_gid;
+	unsigned char rnd;
+	struct group_info *gi;
+	int i, rc;
+
+	get_random_bytes((void *)&rnd, 1);
+	known_gid = (rnd > 0) ? rnd : 1;
+	missing_gid = 0;
+
+	/*
+	 * Create an interesting known set of gids for test purposes. The
+	 * gids are pseudo randomly selected are will be in the range of
+	 * 1:(NGROUPS_MAX-1).  Gid 0 is explicitly avoided so we can reliably
+	 * test for its absence in the test cases.
+	 */
+	gi = groups_alloc(NGROUPS_SMALL);
+	if (gi == NULL) {
+		splat_vprint(file, SPLAT_CRED_TEST3_NAME, "Failed create "
+		    "group_info for known gids: %d\n", -ENOMEM);
+		rc = -ENOMEM;
+		goto show_groups;
+	}
+
+	for (i = 0, tmp_gid = known_gid; i < NGROUPS_SMALL; i++) {
+		splat_vprint(file, SPLAT_CRED_TEST3_NAME, "Adding gid %d "
+		    "to current CRED() (%d/%d)\n", tmp_gid, i, gi->ngroups);
+#ifdef HAVE_KUIDGID_T
+		GROUP_AT(gi, i) = make_kgid(current_user_ns(), tmp_gid);
+#else
+		GROUP_AT(gi, i) = tmp_gid;
+#endif /* HAVE_KUIDGID_T */
+		tmp_gid = ((tmp_gid * 17) % (NGROUPS_MAX - 1)) + 1;
+	}
+
+	/* Set the new groups in the CRED() and release our reference. */
+	rc = set_current_groups(gi);
+	put_group_info(gi);
+
+	if (rc) {
+		splat_vprint(file, SPLAT_CRED_TEST3_NAME, "Failed to add "
+		    "gid %d to current group: %d\n", known_gid, rc);
+		goto show_groups;
+	}
+
+	/* Verify groupmember() finds the known_gid in the CRED() */
+	rc = groupmember(known_gid, CRED());
+	if (!rc) {
+		splat_vprint(file, SPLAT_CRED_TEST3_NAME, "Failed to find "
+		    "known gid %d in CRED()'s groups.\n", known_gid);
+		rc = -EIDRM;
+		goto show_groups;
+	}
+
+	/* Verify groupmember() does NOT finds the missing gid in the CRED() */
+	rc = groupmember(missing_gid, CRED());
+	if (rc) {
+		splat_vprint(file, SPLAT_CRED_TEST3_NAME, "Failed missing "
+		    "gid %d was found in CRED()'s groups.\n", missing_gid);
+		rc = -EIDRM;
+		goto show_groups;
+	}
+
+	splat_vprint(file, SPLAT_CRED_TEST3_NAME, "Success groupmember() "
+	    "correctly detects expected gids in CRED(): %d\n", rc);
+
+show_groups:
+	if (rc) {
+		int i, grps = crgetngroups(CRED());
+
+		splat_vprint(file, SPLAT_CRED_TEST3_NAME, "%d groups: ", grps);
+		for (i = 0; i < grps; i++)
+			splat_print(file, "%d ", crgetgroups(CRED())[i]);
+		splat_print(file, "%s", "\n");
+	}
+
+
+	return (rc);
+} /* splat_cred_test3() */
+
+splat_subsystem_t *
+splat_cred_init(void)
+{
+        splat_subsystem_t *sub;
+
+        sub = kmalloc(sizeof(*sub), GFP_KERNEL);
+        if (sub == NULL)
+                return NULL;
+
+        memset(sub, 0, sizeof(*sub));
+        strncpy(sub->desc.name, SPLAT_CRED_NAME, SPLAT_NAME_SIZE);
+	strncpy(sub->desc.desc, SPLAT_CRED_DESC, SPLAT_DESC_SIZE);
+        INIT_LIST_HEAD(&sub->subsystem_list);
+	INIT_LIST_HEAD(&sub->test_list);
+        spin_lock_init(&sub->test_lock);
+        sub->desc.id = SPLAT_SUBSYSTEM_CRED;
+
+        SPLAT_TEST_INIT(sub, SPLAT_CRED_TEST1_NAME, SPLAT_CRED_TEST1_DESC,
+	              SPLAT_CRED_TEST1_ID, splat_cred_test1);
+        SPLAT_TEST_INIT(sub, SPLAT_CRED_TEST2_NAME, SPLAT_CRED_TEST2_DESC,
+	              SPLAT_CRED_TEST2_ID, splat_cred_test2);
+        SPLAT_TEST_INIT(sub, SPLAT_CRED_TEST3_NAME, SPLAT_CRED_TEST3_DESC,
+	              SPLAT_CRED_TEST3_ID, splat_cred_test3);
+
+        return sub;
+} /* splat_cred_init() */
+
+void
+splat_cred_fini(splat_subsystem_t *sub)
+{
+        ASSERT(sub);
+
+        SPLAT_TEST_FINI(sub, SPLAT_CRED_TEST3_ID);
+        SPLAT_TEST_FINI(sub, SPLAT_CRED_TEST2_ID);
+        SPLAT_TEST_FINI(sub, SPLAT_CRED_TEST1_ID);
+
+        kfree(sub);
+} /* splat_cred_fini() */
+
+int
+splat_cred_id(void)
+{
+        return SPLAT_SUBSYSTEM_CRED;
+} /* splat_cred_id() */
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/module/splat/splat-ctl.c
@@ -0,0 +1,671 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+ *****************************************************************************
+ *  Solaris Porting LAyer Tests (SPLAT) Test Control Interface.
+ *
+ *  The 'splat' (Solaris Porting LAyer Tests) module is designed as a
+ *  framework which runs various in kernel regression tests to validate
+ *  the SPL primitives honor the Solaris ABI.
+ *
+ *  The splat module is constructed of various splat_* source files each
+ *  of which contain regression tests for a particular subsystem.  For
+ *  example, the splat_kmem.c file contains all the tests for validating
+ *  the kmem interfaces have been implemented correctly.  When the splat
+ *  module is loaded splat_*_init() will be called for each subsystems
+ *  tests.  It is the responsibility of splat_*_init() to register all
+ *  the tests for this subsystem using the SPLAT_TEST_INIT() macro.
+ *  Similarly splat_*_fini() is called when the splat module is removed
+ *  and is responsible for unregistering its tests via the SPLAT_TEST_FINI
+ *  macro.  Once a test is registered it can then be run with an ioctl()
+ *  call which specifies the subsystem and test to be run.  The provided
+ *  splat command line tool can be used to display all available
+ *  subsystems and tests.  It can also be used to run the full suite
+ *  of regression tests or particular tests.
+\*****************************************************************************/
+
+#include <sys/debug.h>
+#include <sys/mutex.h>
+#include <sys/types.h>
+#include <linux/cdev.h>
+#include <linux/fs.h>
+#include <linux/miscdevice.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/uaccess.h>
+#include <linux/vmalloc.h>
+#include "splat-internal.h"
+
+static struct list_head splat_module_list;
+static spinlock_t splat_module_lock;
+
+static int
+splat_open(struct inode *inode, struct file *file)
+{
+	splat_info_t *info;
+
+	info = (splat_info_t *)kmalloc(sizeof(*info), GFP_KERNEL);
+	if (info == NULL)
+		return -ENOMEM;
+
+	mutex_init(&info->info_lock, SPLAT_NAME, MUTEX_DEFAULT, NULL);
+	info->info_size = SPLAT_INFO_BUFFER_SIZE;
+	info->info_buffer = (char *)vmalloc(SPLAT_INFO_BUFFER_SIZE);
+	if (info->info_buffer == NULL) {
+		kfree(info);
+		return -ENOMEM;
+	}
+	memset(info->info_buffer, 0, info->info_size);
+
+	info->info_head = info->info_buffer;
+	file->private_data = (void *)info;
+
+	splat_print(file, "%s\n", spl_version);
+
+	return 0;
+}
+
+static int
+splat_release(struct inode *inode, struct file *file)
+{
+	splat_info_t *info = (splat_info_t *)file->private_data;
+
+	ASSERT(info);
+	ASSERT(info->info_buffer);
+
+	mutex_destroy(&info->info_lock);
+	vfree(info->info_buffer);
+	kfree(info);
+
+	return 0;
+}
+
+static int
+splat_buffer_clear(struct file *file, splat_cfg_t *kcfg, unsigned long arg)
+{
+	splat_info_t *info = (splat_info_t *)file->private_data;
+
+	ASSERT(info);
+	ASSERT(info->info_buffer);
+
+	mutex_enter(&info->info_lock);
+	memset(info->info_buffer, 0, info->info_size);
+	info->info_head = info->info_buffer;
+	mutex_exit(&info->info_lock);
+
+	return 0;
+}
+
+static int
+splat_buffer_size(struct file *file, splat_cfg_t *kcfg, unsigned long arg)
+{
+	splat_info_t *info = (splat_info_t *)file->private_data;
+	char *buf;
+	int min, size, rc = 0;
+
+	ASSERT(info);
+	ASSERT(info->info_buffer);
+
+	mutex_enter(&info->info_lock);
+	if (kcfg->cfg_arg1 > 0) {
+
+		size = kcfg->cfg_arg1;
+		buf = (char *)vmalloc(size);
+		if (buf == NULL) {
+			rc = -ENOMEM;
+			goto out;
+		}
+
+		/* Zero fill and truncate contents when coping buffer */
+		min = ((size < info->info_size) ? size : info->info_size);
+		memset(buf, 0, size);
+		memcpy(buf, info->info_buffer, min);
+		vfree(info->info_buffer);
+		info->info_size = size;
+		info->info_buffer = buf;
+		info->info_head = info->info_buffer;
+	}
+
+	kcfg->cfg_rc1 = info->info_size;
+
+	if (copy_to_user((struct splat_cfg_t __user *)arg, kcfg, sizeof(*kcfg)))
+		rc = -EFAULT;
+out:
+	mutex_exit(&info->info_lock);
+
+	return rc;
+}
+
+
+static splat_subsystem_t *
+splat_subsystem_find(int id) {
+	splat_subsystem_t *sub;
+
+        spin_lock(&splat_module_lock);
+        list_for_each_entry(sub, &splat_module_list, subsystem_list) {
+		if (id == sub->desc.id) {
+		        spin_unlock(&splat_module_lock);
+			return sub;
+		}
+        }
+        spin_unlock(&splat_module_lock);
+
+	return NULL;
+}
+
+static int
+splat_subsystem_count(splat_cfg_t *kcfg, unsigned long arg)
+{
+	splat_subsystem_t *sub;
+	int i = 0;
+
+        spin_lock(&splat_module_lock);
+        list_for_each_entry(sub, &splat_module_list, subsystem_list)
+		i++;
+
+        spin_unlock(&splat_module_lock);
+	kcfg->cfg_rc1 = i;
+
+	if (copy_to_user((struct splat_cfg_t __user *)arg, kcfg, sizeof(*kcfg)))
+		return -EFAULT;
+
+	return 0;
+}
+
+static int
+splat_subsystem_list(splat_cfg_t *kcfg, unsigned long arg)
+{
+	splat_subsystem_t *sub;
+	splat_cfg_t *tmp;
+	int size, i = 0;
+
+	/* Structure will be sized large enough for N subsystem entries
+	 * which is passed in by the caller.  On exit the number of
+	 * entries filled in with valid subsystems will be stored in
+	 * cfg_rc1.  If the caller does not provide enough entries
+	 * for all subsystems we will truncate the list to avoid overrun.
+	 */
+	size = sizeof(*tmp) + kcfg->cfg_data.splat_subsystems.size *
+	       sizeof(splat_user_t);
+	tmp = kmalloc(size, GFP_KERNEL);
+	if (tmp == NULL)
+		return -ENOMEM;
+
+	/* Local 'tmp' is used as the structure copied back to user space */
+	memset(tmp, 0, size);
+	memcpy(tmp, kcfg, sizeof(*kcfg));
+
+        spin_lock(&splat_module_lock);
+        list_for_each_entry(sub, &splat_module_list, subsystem_list) {
+		strncpy(tmp->cfg_data.splat_subsystems.descs[i].name,
+		        sub->desc.name, SPLAT_NAME_SIZE);
+		strncpy(tmp->cfg_data.splat_subsystems.descs[i].desc,
+		        sub->desc.desc, SPLAT_DESC_SIZE);
+		tmp->cfg_data.splat_subsystems.descs[i].id = sub->desc.id;
+
+		/* Truncate list if we are about to overrun alloc'ed memory */
+		if ((i++) == kcfg->cfg_data.splat_subsystems.size)
+			break;
+        }
+        spin_unlock(&splat_module_lock);
+	tmp->cfg_rc1 = i;
+
+	if (copy_to_user((struct splat_cfg_t __user *)arg, tmp, size)) {
+		kfree(tmp);
+		return -EFAULT;
+	}
+
+	kfree(tmp);
+	return 0;
+}
+
+static int
+splat_test_count(splat_cfg_t *kcfg, unsigned long arg)
+{
+	splat_subsystem_t *sub;
+	splat_test_t *test;
+	int i = 0;
+
+	/* Subsystem ID passed as arg1 */
+	sub = splat_subsystem_find(kcfg->cfg_arg1);
+	if (sub == NULL)
+		return -EINVAL;
+
+        spin_lock(&(sub->test_lock));
+        list_for_each_entry(test, &(sub->test_list), test_list)
+		i++;
+
+        spin_unlock(&(sub->test_lock));
+	kcfg->cfg_rc1 = i;
+
+	if (copy_to_user((struct splat_cfg_t __user *)arg, kcfg, sizeof(*kcfg)))
+		return -EFAULT;
+
+	return 0;
+}
+
+static int
+splat_test_list(splat_cfg_t *kcfg, unsigned long arg)
+{
+	splat_subsystem_t *sub;
+	splat_test_t *test;
+	splat_cfg_t *tmp;
+	int size, i = 0;
+
+	/* Subsystem ID passed as arg1 */
+	sub = splat_subsystem_find(kcfg->cfg_arg1);
+	if (sub == NULL)
+		return -EINVAL;
+
+	/* Structure will be sized large enough for N test entries
+	 * which is passed in by the caller.  On exit the number of
+	 * entries filled in with valid tests will be stored in
+	 * cfg_rc1.  If the caller does not provide enough entries
+	 * for all tests we will truncate the list to avoid overrun.
+	 */
+	size = sizeof(*tmp)+kcfg->cfg_data.splat_tests.size*sizeof(splat_user_t);
+	tmp = kmalloc(size, GFP_KERNEL);
+	if (tmp == NULL)
+		return -ENOMEM;
+
+	/* Local 'tmp' is used as the structure copied back to user space */
+	memset(tmp, 0, size);
+	memcpy(tmp, kcfg, sizeof(*kcfg));
+
+        spin_lock(&(sub->test_lock));
+        list_for_each_entry(test, &(sub->test_list), test_list) {
+		strncpy(tmp->cfg_data.splat_tests.descs[i].name,
+		        test->desc.name, SPLAT_NAME_SIZE);
+		strncpy(tmp->cfg_data.splat_tests.descs[i].desc,
+		        test->desc.desc, SPLAT_DESC_SIZE);
+		tmp->cfg_data.splat_tests.descs[i].id = test->desc.id;
+
+		/* Truncate list if we are about to overrun alloc'ed memory */
+		if ((i++) == kcfg->cfg_data.splat_tests.size)
+			break;
+        }
+        spin_unlock(&(sub->test_lock));
+	tmp->cfg_rc1 = i;
+
+	if (copy_to_user((struct splat_cfg_t __user *)arg, tmp, size)) {
+		kfree(tmp);
+		return -EFAULT;
+	}
+
+	kfree(tmp);
+	return 0;
+}
+
+static int
+splat_validate(struct file *file, splat_subsystem_t *sub, int cmd, void *arg)
+{
+        splat_test_t *test;
+
+        spin_lock(&(sub->test_lock));
+        list_for_each_entry(test, &(sub->test_list), test_list) {
+                if (test->desc.id == cmd) {
+			spin_unlock(&(sub->test_lock));
+                        return test->test(file, arg);
+                }
+        }
+        spin_unlock(&(sub->test_lock));
+
+        return -EINVAL;
+}
+
+static int
+splat_ioctl_cfg(struct file *file, unsigned int cmd, unsigned long arg)
+{
+	splat_cfg_t kcfg;
+	int rc = 0;
+
+	/* User and kernel space agree about arg size */
+	if (_IOC_SIZE(cmd) != sizeof(kcfg))
+		return -EBADMSG;
+
+	if (copy_from_user(&kcfg, (splat_cfg_t *)arg, sizeof(kcfg)))
+		return -EFAULT;
+
+	if (kcfg.cfg_magic != SPLAT_CFG_MAGIC) {
+		splat_print(file, "Bad config magic 0x%x != 0x%x\n",
+		          kcfg.cfg_magic, SPLAT_CFG_MAGIC);
+		return -EINVAL;
+	}
+
+	switch (kcfg.cfg_cmd) {
+		case SPLAT_CFG_BUFFER_CLEAR:
+			/* cfg_arg1 - Unused
+			 * cfg_rc1  - Unused
+			 */
+			rc = splat_buffer_clear(file, &kcfg, arg);
+			break;
+		case SPLAT_CFG_BUFFER_SIZE:
+			/* cfg_arg1 - 0 - query size; >0 resize
+			 * cfg_rc1  - Set to current buffer size
+			 */
+			rc = splat_buffer_size(file, &kcfg, arg);
+			break;
+		case SPLAT_CFG_SUBSYSTEM_COUNT:
+			/* cfg_arg1 - Unused
+			 * cfg_rc1  - Set to number of subsystems
+			 */
+			rc = splat_subsystem_count(&kcfg, arg);
+			break;
+		case SPLAT_CFG_SUBSYSTEM_LIST:
+			/* cfg_arg1 - Unused
+			 * cfg_rc1  - Set to number of subsystems
+			 * cfg_data.splat_subsystems - Set with subsystems
+			 */
+			rc = splat_subsystem_list(&kcfg, arg);
+			break;
+		case SPLAT_CFG_TEST_COUNT:
+			/* cfg_arg1 - Set to a target subsystem
+			 * cfg_rc1  - Set to number of tests
+			 */
+			rc = splat_test_count(&kcfg, arg);
+			break;
+		case SPLAT_CFG_TEST_LIST:
+			/* cfg_arg1 - Set to a target subsystem
+			 * cfg_rc1  - Set to number of tests
+			 * cfg_data.splat_subsystems - Populated with tests
+			 */
+			rc = splat_test_list(&kcfg, arg);
+			break;
+		default:
+			splat_print(file, "Bad config command %d\n",
+				    kcfg.cfg_cmd);
+			rc = -EINVAL;
+			break;
+	}
+
+	return rc;
+}
+
+static int
+splat_ioctl_cmd(struct file *file, unsigned int cmd, unsigned long arg)
+{
+	splat_subsystem_t *sub;
+	splat_cmd_t kcmd;
+	int rc = -EINVAL;
+	void *data = NULL;
+
+	/* User and kernel space agree about arg size */
+	if (_IOC_SIZE(cmd) != sizeof(kcmd))
+		return -EBADMSG;
+
+	if (copy_from_user(&kcmd, (splat_cfg_t *)arg, sizeof(kcmd)))
+		return -EFAULT;
+
+	if (kcmd.cmd_magic != SPLAT_CMD_MAGIC) {
+		splat_print(file, "Bad command magic 0x%x != 0x%x\n",
+		          kcmd.cmd_magic, SPLAT_CFG_MAGIC);
+		return -EINVAL;
+	}
+
+	/* Allocate memory for any opaque data the caller needed to pass on */
+	if (kcmd.cmd_data_size > 0) {
+		data = (void *)kmalloc(kcmd.cmd_data_size, GFP_KERNEL);
+		if (data == NULL)
+			return -ENOMEM;
+
+		if (copy_from_user(data, (void *)(arg + offsetof(splat_cmd_t,
+		                   cmd_data_str)), kcmd.cmd_data_size)) {
+			kfree(data);
+			return -EFAULT;
+		}
+	}
+
+	sub = splat_subsystem_find(kcmd.cmd_subsystem);
+	if (sub != NULL)
+		rc = splat_validate(file, sub, kcmd.cmd_test, data);
+	else
+		rc = -EINVAL;
+
+	if (data != NULL)
+		kfree(data);
+
+	return rc;
+}
+
+static long
+splat_unlocked_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+	int rc = 0;
+
+	/* Ignore tty ioctls */
+	if ((cmd & 0xffffff00) == ((int)'T') << 8)
+		return -ENOTTY;
+
+	switch (cmd) {
+		case SPLAT_CFG:
+			rc = splat_ioctl_cfg(file, cmd, arg);
+			break;
+		case SPLAT_CMD:
+			rc = splat_ioctl_cmd(file, cmd, arg);
+			break;
+		default:
+			splat_print(file, "Bad ioctl command %d\n", cmd);
+			rc = -EINVAL;
+			break;
+	}
+
+	return rc;
+}
+
+#ifdef CONFIG_COMPAT
+/* Compatibility handler for ioctls from 32-bit ELF binaries */
+static long
+splat_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+	return splat_unlocked_ioctl(file, cmd, arg);
+}
+#endif /* CONFIG_COMPAT */
+
+/* I'm not sure why you would want to write in to this buffer from
+ * user space since its principle use is to pass test status info
+ * back to the user space, but I don't see any reason to prevent it.
+ */
+static ssize_t splat_write(struct file *file, const char __user *buf,
+                         size_t count, loff_t *ppos)
+{
+	splat_info_t *info = (splat_info_t *)file->private_data;
+	int rc = 0;
+
+	ASSERT(info);
+	ASSERT(info->info_buffer);
+
+	mutex_enter(&info->info_lock);
+
+	/* Write beyond EOF */
+	if (*ppos >= info->info_size) {
+		rc = -EFBIG;
+		goto out;
+	}
+
+	/* Resize count if beyond EOF */
+	if (*ppos + count > info->info_size)
+		count = info->info_size - *ppos;
+
+	if (copy_from_user(info->info_buffer, buf, count)) {
+		rc = -EFAULT;
+		goto out;
+	}
+
+	*ppos += count;
+	rc = count;
+out:
+	mutex_exit(&info->info_lock);
+	return rc;
+}
+
+static ssize_t splat_read(struct file *file, char __user *buf,
+		        size_t count, loff_t *ppos)
+{
+	splat_info_t *info = (splat_info_t *)file->private_data;
+	int rc = 0;
+
+	ASSERT(info);
+	ASSERT(info->info_buffer);
+
+	mutex_enter(&info->info_lock);
+
+	/* Read beyond EOF */
+	if (*ppos >= info->info_size)
+		goto out;
+
+	/* Resize count if beyond EOF */
+	if (*ppos + count > info->info_size)
+		count = info->info_size - *ppos;
+
+	if (copy_to_user(buf, info->info_buffer + *ppos, count)) {
+		rc = -EFAULT;
+		goto out;
+	}
+
+	*ppos += count;
+	rc = count;
+out:
+	mutex_exit(&info->info_lock);
+	return rc;
+}
+
+static loff_t splat_seek(struct file *file, loff_t offset, int origin)
+{
+	splat_info_t *info = (splat_info_t *)file->private_data;
+	int rc = -EINVAL;
+
+	ASSERT(info);
+	ASSERT(info->info_buffer);
+
+	mutex_enter(&info->info_lock);
+
+	switch (origin) {
+	case 0: /* SEEK_SET - No-op just do it */
+		break;
+	case 1: /* SEEK_CUR - Seek from current */
+		offset = file->f_pos + offset;
+		break;
+	case 2: /* SEEK_END - Seek from end */
+		offset = info->info_size + offset;
+		break;
+	}
+
+	if (offset >= 0) {
+		file->f_pos = offset;
+		file->f_version = 0;
+		rc = offset;
+	}
+
+	mutex_exit(&info->info_lock);
+
+	return rc;
+}
+
+static struct file_operations splat_fops = {
+	.owner		= THIS_MODULE,
+	.open		= splat_open,
+	.release	= splat_release,
+	.unlocked_ioctl	= splat_unlocked_ioctl,
+#ifdef CONFIG_COMPAT
+	.compat_ioctl	= splat_compat_ioctl,
+#endif
+	.read		= splat_read,
+	.write		= splat_write,
+	.llseek		= splat_seek,
+};
+
+static struct miscdevice splat_misc = {
+	.minor		= MISC_DYNAMIC_MINOR,
+	.name		= SPLAT_NAME,
+	.fops		= &splat_fops,
+};
+
+static int __init
+splat_init(void)
+{
+	int error;
+
+	spin_lock_init(&splat_module_lock);
+	INIT_LIST_HEAD(&splat_module_list);
+
+	SPLAT_SUBSYSTEM_INIT(kmem);
+	SPLAT_SUBSYSTEM_INIT(taskq);
+	SPLAT_SUBSYSTEM_INIT(krng);
+	SPLAT_SUBSYSTEM_INIT(mutex);
+	SPLAT_SUBSYSTEM_INIT(condvar);
+	SPLAT_SUBSYSTEM_INIT(thread);
+	SPLAT_SUBSYSTEM_INIT(rwlock);
+	SPLAT_SUBSYSTEM_INIT(time);
+	SPLAT_SUBSYSTEM_INIT(vnode);
+	SPLAT_SUBSYSTEM_INIT(kobj);
+	SPLAT_SUBSYSTEM_INIT(atomic);
+	SPLAT_SUBSYSTEM_INIT(list);
+	SPLAT_SUBSYSTEM_INIT(generic);
+	SPLAT_SUBSYSTEM_INIT(cred);
+	SPLAT_SUBSYSTEM_INIT(zlib);
+	SPLAT_SUBSYSTEM_INIT(linux);
+
+	error = misc_register(&splat_misc);
+	if (error) {
+		printk(KERN_INFO "SPLAT: misc_register() failed %d\n", error);
+	} else {
+		printk(KERN_INFO "SPLAT: Loaded module v%s-%s%s\n",
+		    SPL_META_VERSION, SPL_META_RELEASE, SPL_DEBUG_STR);
+	}
+
+	return (error);
+}
+
+static void __exit
+splat_fini(void)
+{
+	misc_deregister(&splat_misc);
+
+	SPLAT_SUBSYSTEM_FINI(linux);
+	SPLAT_SUBSYSTEM_FINI(zlib);
+	SPLAT_SUBSYSTEM_FINI(cred);
+	SPLAT_SUBSYSTEM_FINI(generic);
+	SPLAT_SUBSYSTEM_FINI(list);
+	SPLAT_SUBSYSTEM_FINI(atomic);
+	SPLAT_SUBSYSTEM_FINI(kobj);
+	SPLAT_SUBSYSTEM_FINI(vnode);
+	SPLAT_SUBSYSTEM_FINI(time);
+	SPLAT_SUBSYSTEM_FINI(rwlock);
+	SPLAT_SUBSYSTEM_FINI(thread);
+	SPLAT_SUBSYSTEM_FINI(condvar);
+	SPLAT_SUBSYSTEM_FINI(mutex);
+	SPLAT_SUBSYSTEM_FINI(krng);
+	SPLAT_SUBSYSTEM_FINI(taskq);
+	SPLAT_SUBSYSTEM_FINI(kmem);
+
+	ASSERT(list_empty(&splat_module_list));
+	printk(KERN_INFO "SPLAT: Unloaded module v%s-%s%s\n",
+	    SPL_META_VERSION, SPL_META_RELEASE, SPL_DEBUG_STR);
+}
+
+module_init(splat_init);
+module_exit(splat_fini);
+
+MODULE_DESCRIPTION("Solaris Porting LAyer Tests");
+MODULE_AUTHOR(SPL_META_AUTHOR);
+MODULE_LICENSE(SPL_META_LICENSE);
+MODULE_VERSION(SPL_META_VERSION "-" SPL_META_RELEASE);
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/module/splat/splat-generic.c
@@ -0,0 +1,367 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+ *****************************************************************************
+ *  Solaris Porting LAyer Tests (SPLAT) Generic Tests.
+\*****************************************************************************/
+
+#include <sys/sunddi.h>
+#include <linux/math64_compat.h>
+#include "splat-internal.h"
+
+#define SPLAT_GENERIC_NAME		"generic"
+#define SPLAT_GENERIC_DESC		"Kernel Generic Tests"
+
+#define SPLAT_GENERIC_TEST1_ID		0x0d01
+#define SPLAT_GENERIC_TEST1_NAME	"ddi_strtoul"
+#define SPLAT_GENERIC_TEST1_DESC	"ddi_strtoul Test"
+
+#define SPLAT_GENERIC_TEST2_ID		0x0d02
+#define SPLAT_GENERIC_TEST2_NAME	"ddi_strtol"
+#define SPLAT_GENERIC_TEST2_DESC	"ddi_strtol Test"
+
+#define SPLAT_GENERIC_TEST3_ID		0x0d03
+#define SPLAT_GENERIC_TEST3_NAME	"ddi_strtoull"
+#define SPLAT_GENERIC_TEST3_DESC	"ddi_strtoull Test"
+
+#define SPLAT_GENERIC_TEST4_ID		0x0d04
+#define SPLAT_GENERIC_TEST4_NAME	"ddi_strtoll"
+#define SPLAT_GENERIC_TEST4_DESC	"ddi_strtoll Test"
+
+# define SPLAT_GENERIC_TEST5_ID		0x0d05
+# define SPLAT_GENERIC_TEST5_NAME	"udivdi3"
+# define SPLAT_GENERIC_TEST5_DESC	"Unsigned Div-64 Test"
+
+# define SPLAT_GENERIC_TEST6_ID		0x0d06
+# define SPLAT_GENERIC_TEST6_NAME	"divdi3"
+# define SPLAT_GENERIC_TEST6_DESC	"Signed Div-64 Test"
+
+#define STR_POS				"123456789"
+#define STR_NEG				"-123456789"
+#define STR_BASE			"0xabcdef"
+#define STR_RANGE_MAX			"10000000000000000"
+#define STR_RANGE_MIN			"-10000000000000000"
+#define STR_INVAL1			"12345U"
+#define STR_INVAL2			"invald"
+
+#define VAL_POS				123456789
+#define VAL_NEG				-123456789
+#define VAL_BASE			0xabcdef
+#define VAL_INVAL1			12345U
+
+#define define_generic_msg_strtox(type, valtype)			\
+static void								\
+generic_msg_strto##type(struct file *file, char *msg, int rc, int *err, \
+			const char *s, valtype d, char *endptr)		\
+{									\
+	splat_vprint(file, SPLAT_GENERIC_TEST1_NAME,			\
+		     "%s (%d) %s: %s == %lld, 0x%p\n",			\
+		     rc ? "Fail" : "Pass", *err, msg, s,		\
+		     (unsigned long long)d, endptr);			\
+	*err = rc;							\
+}
+
+define_generic_msg_strtox(ul, unsigned long);
+define_generic_msg_strtox(l, long);
+define_generic_msg_strtox(ull, unsigned long long);
+define_generic_msg_strtox(ll, long long);
+
+#define define_splat_generic_test_strtox(type, valtype)			\
+static int								\
+splat_generic_test_strto##type(struct file *file, void *arg)		\
+{									\
+	int rc, rc1, rc2, rc3, rc4, rc5, rc6, rc7;			\
+	char str[20], *endptr;						\
+	valtype r;							\
+									\
+	/* Positive value: expect success */				\
+	r = 0;								\
+	rc = 1;								\
+	endptr = NULL;							\
+	rc1 = ddi_strto##type(STR_POS, &endptr, 10, &r);		\
+	if (rc1 == 0 && r == VAL_POS && endptr && *endptr == '\0')	\
+		rc = 0;							\
+									\
+	generic_msg_strto##type(file, "positive", rc , &rc1,		\
+				STR_POS, r, endptr);			\
+									\
+	/* Negative value: expect success */				\
+	r = 0;								\
+	rc = 1;								\
+	endptr = NULL;							\
+	strcpy(str, STR_NEG);						\
+	rc2 = ddi_strto##type(str, &endptr, 10, &r);			\
+	if (#type[0] == 'u') {						\
+		if (rc2 == 0 && r == 0 && endptr == str)		\
+			rc = 0;						\
+	} else {							\
+		if (rc2 == 0 && r == VAL_NEG &&				\
+		    endptr && *endptr == '\0')				\
+			rc = 0;						\
+	}								\
+									\
+	generic_msg_strto##type(file, "negative", rc, &rc2,		\
+				STR_NEG, r, endptr);			\
+									\
+	/* Non decimal base: expect sucess */				\
+	r = 0;								\
+	rc = 1;								\
+	endptr = NULL;							\
+	rc3 = ddi_strto##type(STR_BASE, &endptr, 0, &r);		\
+	if (rc3 == 0 && r == VAL_BASE && endptr && *endptr == '\0')	\
+		rc = 0;							\
+									\
+	generic_msg_strto##type(file, "base", rc, &rc3,			\
+				STR_BASE, r, endptr);			\
+									\
+	/* Max out of range: failure expected, r unchanged */		\
+	r = 0;								\
+	rc = 1;								\
+	endptr = NULL;							\
+	rc4 = ddi_strto##type(STR_RANGE_MAX, &endptr, 16, &r);		\
+	if (rc4 == ERANGE && r == 0 && endptr == NULL)			\
+		rc = 0;							\
+									\
+	generic_msg_strto##type(file, "max", rc, &rc4,			\
+				STR_RANGE_MAX, r, endptr);		\
+									\
+	/* Min out of range: failure expected, r unchanged */		\
+	r = 0;								\
+	rc = 1;								\
+	endptr = NULL;							\
+	strcpy(str, STR_RANGE_MIN);					\
+	rc5 = ddi_strto##type(str, &endptr, 16, &r);			\
+	if (#type[0] == 'u') {						\
+		if (rc5 == 0 && r == 0 && endptr == str)		\
+			rc = 0;						\
+	} else {							\
+		if (rc5 == ERANGE && r == 0 && endptr == NULL)		\
+			rc = 0;						\
+	}								\
+									\
+	generic_msg_strto##type(file, "min", rc, &rc5,			\
+				STR_RANGE_MIN, r, endptr);		\
+									\
+	/* Invalid string: success expected, endptr == 'U' */		\
+	r = 0;								\
+	rc = 1;								\
+	endptr = NULL;							\
+	rc6 = ddi_strto##type(STR_INVAL1, &endptr, 10, &r);		\
+	if (rc6 == 0 && r == VAL_INVAL1 && endptr && *endptr == 'U')	\
+		rc = 0;							\
+									\
+	generic_msg_strto##type(file, "invalid", rc, &rc6,		\
+				STR_INVAL1, r, endptr);			\
+									\
+	/* Invalid string: failure expected, endptr == str */		\
+	r = 0;								\
+	rc = 1;								\
+	endptr = NULL;							\
+	strcpy(str, STR_INVAL2);					\
+	rc7 = ddi_strto##type(str, &endptr, 10, &r);			\
+	if (rc7 == 0 && r == 0 && endptr == str)			\
+		rc = 0;							\
+									\
+	generic_msg_strto##type(file, "invalid", rc, &rc7,		\
+				STR_INVAL2, r, endptr);			\
+									\
+        return (rc1 || rc2 || rc3 || rc4 || rc5 || rc6 || rc7) ?	\
+		-EINVAL : 0;						\
+}
+
+define_splat_generic_test_strtox(ul, unsigned long);
+define_splat_generic_test_strtox(l, long);
+define_splat_generic_test_strtox(ull, unsigned long long);
+define_splat_generic_test_strtox(ll, long long);
+
+/*
+ * The entries in the table are used in all combinations and the
+ * return value is checked to ensure it is range.  On 32-bit
+ * systems __udivdi3 will be invoked for the 64-bit division.
+ * On 64-bit system the native 64-bit divide will be used so
+ * __udivdi3 isn't used but we might as well stil run the test.
+ */
+static int
+splat_generic_test_udivdi3(struct file *file, void *arg)
+{
+	const uint64_t tabu[] = {
+	    0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
+	    10, 11, 12, 13, 14, 15, 16, 1000, 2003,
+	    32765, 32766, 32767, 32768, 32769, 32760,
+	    65533, 65534, 65535, 65536, 65537, 65538,
+	    0x7ffffffeULL, 0x7fffffffULL, 0x80000000ULL, 0x80000001ULL,
+	    0x7000000000000000ULL, 0x7000000080000000ULL, 0x7000000080000001ULL,
+	    0x7fffffffffffffffULL, 0x7fffffff8fffffffULL, 0x7fffffff8ffffff1ULL,
+	    0x7fffffff00000000ULL, 0x7fffffff80000000ULL, 0x7fffffff00000001ULL,
+	    0x8000000000000000ULL, 0x8000000080000000ULL, 0x8000000080000001ULL,
+	    0xc000000000000000ULL, 0xc000000080000000ULL, 0xc000000080000001ULL,
+	    0xfffffffffffffffdULL, 0xfffffffffffffffeULL, 0xffffffffffffffffULL,
+	};
+	uint64_t uu, vu, qu, ru;
+	int n, i, j, errors = 0;
+
+	splat_vprint(file, SPLAT_GENERIC_TEST5_NAME, "%s",
+	    "Testing unsigned 64-bit division.\n");
+	n = sizeof(tabu) / sizeof(tabu[0]);
+	for (i = 0; i < n; i++) {
+		for (j = 1; j < n; j++) {
+			uu = tabu[i];
+			vu = tabu[j];
+			qu = uu / vu; /* __udivdi3 */
+			ru = uu - qu * vu;
+			if (qu > uu || ru >= vu) {
+				splat_vprint(file, SPLAT_GENERIC_TEST5_NAME,
+				    "%016llx/%016llx != %016llx rem %016llx\n",
+				    uu, vu, qu, ru);
+				errors++;
+			}
+		}
+	}
+
+	if (errors) {
+		splat_vprint(file, SPLAT_GENERIC_TEST5_NAME,
+		    "Failed %d/%d tests\n", errors, n * (n - 1));
+		return -ERANGE;
+	}
+
+	splat_vprint(file, SPLAT_GENERIC_TEST5_NAME,
+	    "Passed all %d tests\n", n * (n - 1));
+
+	return 0;
+}
+
+/*
+ * The entries the table are used in all combinations, with + and - signs
+ * preceding them.  The return value is checked to ensure it is range.
+ * On 32-bit systems __divdi3 will be invoked for the 64-bit division.
+ * On 64-bit system the native 64-bit divide will be used so __divdi3
+ *  isn't used but we might as well stil run the test.
+ */
+static int
+splat_generic_test_divdi3(struct file *file, void *arg)
+{
+	const int64_t tabs[] = {
+	    0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
+	    10, 11, 12, 13, 14, 15, 16, 1000, 2003,
+	    32765, 32766, 32767, 32768, 32769, 32760,
+	    65533, 65534, 65535, 65536, 65537, 65538,
+	    0x7ffffffeLL, 0x7fffffffLL, 0x80000000LL, 0x80000001LL,
+	    0x7000000000000000LL, 0x7000000080000000LL, 0x7000000080000001LL,
+	    0x7fffffffffffffffLL, 0x7fffffff8fffffffLL, 0x7fffffff8ffffff1LL,
+	    0x7fffffff00000000LL, 0x7fffffff80000000LL, 0x7fffffff00000001LL,
+	    0x0123456789abcdefLL, 0x00000000abcdef01LL, 0x0000000012345678LL,
+#if BITS_PER_LONG == 32
+	    0x8000000000000000LL, 0x8000000080000000LL, 0x8000000080000001LL,
+#endif
+	};
+	int64_t u, v, q, r;
+	int n, i, j, k, errors = 0;
+
+	splat_vprint(file, SPLAT_GENERIC_TEST6_NAME, "%s",
+	    "Testing signed 64-bit division.\n");
+	n = sizeof(tabs) / sizeof(tabs[0]);
+	for (i = 0; i < n; i++) {
+		for (j = 1; j < n; j++) {
+			for (k = 0; k <= 3; k++) {
+				u = (k & 1)  ? -tabs[i] : tabs[i];
+				v = (k >= 2) ? -tabs[j] : tabs[j];
+
+				q = u / v; /* __divdi3 */
+				r = u - q * v;
+				if (abs64(q) >  abs64(u) ||
+				    abs64(r) >= abs64(v) ||
+				    (r != 0 && (r ^ u) < 0)) {
+					splat_vprint(file,
+					    SPLAT_GENERIC_TEST6_NAME,
+					    "%016llx/%016llx != %016llx "
+					    "rem %016llx\n", u, v, q, r);
+					errors++;
+				}
+			}
+		}
+	}
+
+	if (errors) {
+		splat_vprint(file, SPLAT_GENERIC_TEST6_NAME,
+		    "Failed %d/%d tests\n", errors, n * (n - 1));
+		return -ERANGE;
+	}
+
+	splat_vprint(file, SPLAT_GENERIC_TEST6_NAME,
+	    "Passed all %d tests\n", n * (n - 1));
+
+	return 0;
+}
+
+splat_subsystem_t *
+splat_generic_init(void)
+{
+        splat_subsystem_t *sub;
+
+        sub = kmalloc(sizeof(*sub), GFP_KERNEL);
+        if (sub == NULL)
+                return NULL;
+
+        memset(sub, 0, sizeof(*sub));
+        strncpy(sub->desc.name, SPLAT_GENERIC_NAME, SPLAT_NAME_SIZE);
+	strncpy(sub->desc.desc, SPLAT_GENERIC_DESC, SPLAT_DESC_SIZE);
+        INIT_LIST_HEAD(&sub->subsystem_list);
+	INIT_LIST_HEAD(&sub->test_list);
+        spin_lock_init(&sub->test_lock);
+        sub->desc.id = SPLAT_SUBSYSTEM_GENERIC;
+
+        SPLAT_TEST_INIT(sub, SPLAT_GENERIC_TEST1_NAME, SPLAT_GENERIC_TEST1_DESC,
+	                SPLAT_GENERIC_TEST1_ID, splat_generic_test_strtoul);
+        SPLAT_TEST_INIT(sub, SPLAT_GENERIC_TEST2_NAME, SPLAT_GENERIC_TEST2_DESC,
+	                SPLAT_GENERIC_TEST2_ID, splat_generic_test_strtol);
+        SPLAT_TEST_INIT(sub, SPLAT_GENERIC_TEST3_NAME, SPLAT_GENERIC_TEST3_DESC,
+	                SPLAT_GENERIC_TEST3_ID, splat_generic_test_strtoull);
+        SPLAT_TEST_INIT(sub, SPLAT_GENERIC_TEST4_NAME, SPLAT_GENERIC_TEST4_DESC,
+	                SPLAT_GENERIC_TEST4_ID, splat_generic_test_strtoll);
+        SPLAT_TEST_INIT(sub, SPLAT_GENERIC_TEST5_NAME, SPLAT_GENERIC_TEST5_DESC,
+	                SPLAT_GENERIC_TEST5_ID, splat_generic_test_udivdi3);
+        SPLAT_TEST_INIT(sub, SPLAT_GENERIC_TEST6_NAME, SPLAT_GENERIC_TEST6_DESC,
+	                SPLAT_GENERIC_TEST6_ID, splat_generic_test_divdi3);
+
+        return sub;
+}
+
+void
+splat_generic_fini(splat_subsystem_t *sub)
+{
+        ASSERT(sub);
+
+        SPLAT_TEST_FINI(sub, SPLAT_GENERIC_TEST6_ID);
+        SPLAT_TEST_FINI(sub, SPLAT_GENERIC_TEST5_ID);
+        SPLAT_TEST_FINI(sub, SPLAT_GENERIC_TEST4_ID);
+        SPLAT_TEST_FINI(sub, SPLAT_GENERIC_TEST3_ID);
+        SPLAT_TEST_FINI(sub, SPLAT_GENERIC_TEST2_ID);
+        SPLAT_TEST_FINI(sub, SPLAT_GENERIC_TEST1_ID);
+
+        kfree(sub);
+}
+
+int
+splat_generic_id(void)
+{
+        return SPLAT_SUBSYSTEM_GENERIC;
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/module/splat/splat-internal.h
@@ -0,0 +1,219 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+\*****************************************************************************/
+
+#ifndef _SPLAT_INTERNAL_H
+#define _SPLAT_INTERNAL_H
+
+#include "splat-ctl.h"
+#include <sys/mutex.h>
+#include <linux/file_compat.h>
+#include <linux/version.h>
+
+#define SPLAT_SUBSYSTEM_INIT(type)                                      \
+({      splat_subsystem_t *_sub_;                                       \
+                                                                        \
+        _sub_ = (splat_subsystem_t *)splat_##type##_init();             \
+        if (_sub_ == NULL) {                                            \
+                printk(KERN_ERR "splat: Error initializing: " #type "\n"); \
+        } else {                                                        \
+                spin_lock(&splat_module_lock);                          \
+                list_add_tail(&(_sub_->subsystem_list),			\
+		              &splat_module_list);			\
+                spin_unlock(&splat_module_lock);                        \
+        }                                                               \
+})
+
+#define SPLAT_SUBSYSTEM_FINI(type)                                      \
+({      splat_subsystem_t *_sub_, *_tmp_;                               \
+        int _id_, _flag_ = 0;                                           \
+                                                                        \
+	_id_ = splat_##type##_id();                                     \
+        spin_lock(&splat_module_lock);                                  \
+        list_for_each_entry_safe(_sub_, _tmp_,  &splat_module_list,	\
+		                 subsystem_list) {			\
+                if (_sub_->desc.id == _id_) {                           \
+                        list_del_init(&(_sub_->subsystem_list));        \
+                        spin_unlock(&splat_module_lock);                \
+                        splat_##type##_fini(_sub_);                     \
+			spin_lock(&splat_module_lock);			\
+                        _flag_ = 1;                                     \
+                }                                                       \
+        }                                                               \
+        spin_unlock(&splat_module_lock);                                \
+                                                                        \
+	if (!_flag_)                                                    \
+                printk(KERN_ERR "splat: Error finalizing: " #type "\n"); \
+})
+
+#define SPLAT_TEST_INIT(sub, n, d, tid, func)				\
+({      splat_test_t *_test_;                                           \
+                                                                        \
+	_test_ = (splat_test_t *)kmalloc(sizeof(*_test_), GFP_KERNEL);  \
+        if (_test_ == NULL) {						\
+		printk(KERN_ERR "splat: Error initializing: " n "/" #tid" \n");\
+	} else {							\
+		memset(_test_, 0, sizeof(*_test_));			\
+		strncpy(_test_->desc.name, n, SPLAT_NAME_SIZE-1);	\
+		strncpy(_test_->desc.desc, d, SPLAT_DESC_SIZE-1);	\
+		_test_->desc.id = tid;					\
+	        _test_->test = func;					\
+		INIT_LIST_HEAD(&(_test_->test_list));			\
+                spin_lock(&((sub)->test_lock));				\
+                list_add_tail(&(_test_->test_list),&((sub)->test_list));\
+                spin_unlock(&((sub)->test_lock));			\
+        }								\
+})
+
+#define SPLAT_TEST_FINI(sub, tid)					\
+({      splat_test_t *_test_, *_tmp_;                                   \
+        int _flag_ = 0;							\
+                                                                        \
+        spin_lock(&((sub)->test_lock));					\
+        list_for_each_entry_safe(_test_, _tmp_,				\
+		                 &((sub)->test_list), test_list) {	\
+                if (_test_->desc.id == tid) {                           \
+                        list_del_init(&(_test_->test_list));		\
+                        _flag_ = 1;                                     \
+                }                                                       \
+        }                                                               \
+        spin_unlock(&((sub)->test_lock));				\
+                                                                        \
+	if (!_flag_)                                                    \
+                printk(KERN_ERR "splat: Error finalizing: " #tid "\n");	\
+})
+
+typedef int (*splat_test_func_t)(struct file *, void *);
+
+typedef struct splat_test {
+	struct list_head test_list;
+	splat_user_t desc;
+	splat_test_func_t test;
+} splat_test_t;
+
+typedef struct splat_subsystem {
+	struct list_head subsystem_list;/* List had to chain entries */
+	splat_user_t desc;
+	spinlock_t test_lock;
+	struct list_head test_list;
+} splat_subsystem_t;
+
+#define SPLAT_INFO_BUFFER_SIZE		65536
+#define SPLAT_INFO_BUFFER_REDZONE	256
+
+typedef struct splat_info {
+	kmutex_t info_lock;
+	int info_size;
+	char *info_buffer;
+	char *info_head;	/* Internal kernel use only */
+} splat_info_t;
+
+#define sym2str(sym)			(char *)(#sym)
+
+#define splat_print(file, format, args...)				\
+({	splat_info_t *_info_ = (splat_info_t *)file->private_data;	\
+	int _rc_;							\
+									\
+	ASSERT(_info_);							\
+	ASSERT(_info_->info_buffer);					\
+									\
+	mutex_enter(&_info_->info_lock);				\
+									\
+	/* Don't allow the kernel to start a write in the red zone */	\
+	if ((int)(_info_->info_head - _info_->info_buffer) >		\
+	    (SPLAT_INFO_BUFFER_SIZE - SPLAT_INFO_BUFFER_REDZONE)) {	\
+		_rc_ = -EOVERFLOW;					\
+	} else {							\
+		_rc_ = sprintf(_info_->info_head, format, args);	\
+		if (_rc_ >= 0)						\
+			_info_->info_head += _rc_;			\
+	}								\
+									\
+	mutex_exit(&_info_->info_lock);					\
+	_rc_;								\
+})
+
+#define splat_vprint(file, test, format, args...)			\
+	splat_print(file, "%*s: " format, SPLAT_NAME_SIZE, test, args)
+
+#define splat_locked_test(lock, test)					\
+({									\
+	int _rc_;							\
+	spin_lock(lock);						\
+	_rc_ = (test) ? 1 : 0;						\
+	spin_unlock(lock);						\
+	_rc_;								\
+})
+
+splat_subsystem_t *splat_condvar_init(void);
+splat_subsystem_t *splat_kmem_init(void);
+splat_subsystem_t *splat_mutex_init(void);
+splat_subsystem_t *splat_krng_init(void);
+splat_subsystem_t *splat_rwlock_init(void);
+splat_subsystem_t *splat_taskq_init(void);
+splat_subsystem_t *splat_thread_init(void);
+splat_subsystem_t *splat_time_init(void);
+splat_subsystem_t *splat_vnode_init(void);
+splat_subsystem_t *splat_kobj_init(void);
+splat_subsystem_t *splat_atomic_init(void);
+splat_subsystem_t *splat_list_init(void);
+splat_subsystem_t *splat_generic_init(void);
+splat_subsystem_t *splat_cred_init(void);
+splat_subsystem_t *splat_zlib_init(void);
+splat_subsystem_t *splat_linux_init(void);
+
+void splat_condvar_fini(splat_subsystem_t *);
+void splat_kmem_fini(splat_subsystem_t *);
+void splat_mutex_fini(splat_subsystem_t *);
+void splat_krng_fini(splat_subsystem_t *);
+void splat_rwlock_fini(splat_subsystem_t *);
+void splat_taskq_fini(splat_subsystem_t *);
+void splat_thread_fini(splat_subsystem_t *);
+void splat_time_fini(splat_subsystem_t *);
+void splat_vnode_fini(splat_subsystem_t *);
+void splat_kobj_fini(splat_subsystem_t *);
+void splat_atomic_fini(splat_subsystem_t *);
+void splat_list_fini(splat_subsystem_t *);
+void splat_generic_fini(splat_subsystem_t *);
+void splat_cred_fini(splat_subsystem_t *);
+void splat_zlib_fini(splat_subsystem_t *);
+void splat_linux_fini(splat_subsystem_t *);
+
+int splat_condvar_id(void);
+int splat_kmem_id(void);
+int splat_mutex_id(void);
+int splat_krng_id(void);
+int splat_rwlock_id(void);
+int splat_taskq_id(void);
+int splat_thread_id(void);
+int splat_time_id(void);
+int splat_vnode_id(void);
+int splat_kobj_id(void);
+int splat_atomic_id(void);
+int splat_list_id(void);
+int splat_generic_id(void);
+int splat_cred_id(void);
+int splat_zlib_id(void);
+int splat_linux_id(void);
+
+#endif /* _SPLAT_INTERNAL_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/module/splat/splat-kmem.c
@@ -0,0 +1,1398 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+ *****************************************************************************
+ *  Solaris Porting LAyer Tests (SPLAT) Kmem Tests.
+\*****************************************************************************/
+
+#include <sys/kmem.h>
+#include <sys/kmem_cache.h>
+#include <sys/vmem.h>
+#include <sys/random.h>
+#include <sys/thread.h>
+#include <sys/vmsystm.h>
+#include "splat-internal.h"
+
+#define SPLAT_KMEM_NAME			"kmem"
+#define SPLAT_KMEM_DESC			"Kernel Malloc/Slab Tests"
+
+#define SPLAT_KMEM_TEST1_ID		0x0101
+#define SPLAT_KMEM_TEST1_NAME		"kmem_alloc"
+#define SPLAT_KMEM_TEST1_DESC		"Memory allocation test (kmem_alloc)"
+
+#define SPLAT_KMEM_TEST2_ID		0x0102
+#define SPLAT_KMEM_TEST2_NAME		"kmem_zalloc"
+#define SPLAT_KMEM_TEST2_DESC		"Memory allocation test (kmem_zalloc)"
+
+#define SPLAT_KMEM_TEST3_ID		0x0103
+#define SPLAT_KMEM_TEST3_NAME		"vmem_alloc"
+#define SPLAT_KMEM_TEST3_DESC		"Memory allocation test (vmem_alloc)"
+
+#define SPLAT_KMEM_TEST4_ID		0x0104
+#define SPLAT_KMEM_TEST4_NAME		"vmem_zalloc"
+#define SPLAT_KMEM_TEST4_DESC		"Memory allocation test (vmem_zalloc)"
+
+#define SPLAT_KMEM_TEST5_ID		0x0105
+#define SPLAT_KMEM_TEST5_NAME		"slab_small"
+#define SPLAT_KMEM_TEST5_DESC		"Slab ctor/dtor test (small)"
+
+#define SPLAT_KMEM_TEST6_ID		0x0106
+#define SPLAT_KMEM_TEST6_NAME		"slab_large"
+#define SPLAT_KMEM_TEST6_DESC		"Slab ctor/dtor test (large)"
+
+#define SPLAT_KMEM_TEST7_ID		0x0107
+#define SPLAT_KMEM_TEST7_NAME		"slab_align"
+#define SPLAT_KMEM_TEST7_DESC		"Slab alignment test"
+
+#define SPLAT_KMEM_TEST8_ID		0x0108
+#define SPLAT_KMEM_TEST8_NAME		"slab_reap"
+#define SPLAT_KMEM_TEST8_DESC		"Slab reaping test"
+
+#define SPLAT_KMEM_TEST9_ID		0x0109
+#define SPLAT_KMEM_TEST9_NAME		"slab_age"
+#define SPLAT_KMEM_TEST9_DESC		"Slab aging test"
+
+#define SPLAT_KMEM_TEST10_ID		0x010a
+#define SPLAT_KMEM_TEST10_NAME		"slab_lock"
+#define SPLAT_KMEM_TEST10_DESC		"Slab locking test"
+
+#if 0
+#define SPLAT_KMEM_TEST11_ID		0x010b
+#define SPLAT_KMEM_TEST11_NAME		"slab_overcommit"
+#define SPLAT_KMEM_TEST11_DESC		"Slab memory overcommit test"
+#endif
+
+#define SPLAT_KMEM_TEST13_ID		0x010d
+#define SPLAT_KMEM_TEST13_NAME		"slab_reclaim"
+#define SPLAT_KMEM_TEST13_DESC		"Slab direct memory reclaim test"
+
+#define SPLAT_KMEM_ALLOC_COUNT		10
+#define SPLAT_VMEM_ALLOC_COUNT		10
+
+
+static int
+splat_kmem_test1(struct file *file, void *arg)
+{
+	void *ptr[SPLAT_KMEM_ALLOC_COUNT];
+	int size = PAGE_SIZE;
+	int i, count, rc = 0;
+
+	while ((!rc) && (size <= spl_kmem_alloc_warn)) {
+		count = 0;
+
+		for (i = 0; i < SPLAT_KMEM_ALLOC_COUNT; i++) {
+			ptr[i] = kmem_alloc(size, KM_SLEEP);
+			if (ptr[i])
+				count++;
+		}
+
+		for (i = 0; i < SPLAT_KMEM_ALLOC_COUNT; i++)
+			if (ptr[i])
+				kmem_free(ptr[i], size);
+
+		splat_vprint(file, SPLAT_KMEM_TEST1_NAME,
+			   "%d byte allocations, %d/%d successful\n",
+			   size, count, SPLAT_KMEM_ALLOC_COUNT);
+		if (count != SPLAT_KMEM_ALLOC_COUNT)
+			rc = -ENOMEM;
+
+		size *= 2;
+	}
+
+	return rc;
+}
+
+static int
+splat_kmem_test2(struct file *file, void *arg)
+{
+	void *ptr[SPLAT_KMEM_ALLOC_COUNT];
+	int size = PAGE_SIZE;
+	int i, j, count, rc = 0;
+
+	while ((!rc) && (size <= spl_kmem_alloc_warn)) {
+		count = 0;
+
+		for (i = 0; i < SPLAT_KMEM_ALLOC_COUNT; i++) {
+			ptr[i] = kmem_zalloc(size, KM_SLEEP);
+			if (ptr[i])
+				count++;
+		}
+
+		/* Ensure buffer has been zero filled */
+		for (i = 0; i < SPLAT_KMEM_ALLOC_COUNT; i++) {
+			for (j = 0; j < size; j++) {
+				if (((char *)ptr[i])[j] != '\0') {
+					splat_vprint(file,SPLAT_KMEM_TEST2_NAME,
+						  "%d-byte allocation was "
+						  "not zeroed\n", size);
+					rc = -EFAULT;
+				}
+			}
+		}
+
+		for (i = 0; i < SPLAT_KMEM_ALLOC_COUNT; i++)
+			if (ptr[i])
+				kmem_free(ptr[i], size);
+
+		splat_vprint(file, SPLAT_KMEM_TEST2_NAME,
+			   "%d byte allocations, %d/%d successful\n",
+			   size, count, SPLAT_KMEM_ALLOC_COUNT);
+		if (count != SPLAT_KMEM_ALLOC_COUNT)
+			rc = -ENOMEM;
+
+		size *= 2;
+	}
+
+	return rc;
+}
+
+static int
+splat_kmem_test3(struct file *file, void *arg)
+{
+	void *ptr[SPLAT_VMEM_ALLOC_COUNT];
+	int size = PAGE_SIZE;
+	int i, count, rc = 0;
+
+	/*
+	 * Test up to 4x the maximum kmem_alloc() size to ensure both
+	 * the kmem_alloc() and vmem_alloc() call paths are used.
+	 */
+	while ((!rc) && (size <= (4 * spl_kmem_alloc_max))) {
+		count = 0;
+
+		for (i = 0; i < SPLAT_VMEM_ALLOC_COUNT; i++) {
+			ptr[i] = vmem_alloc(size, KM_SLEEP);
+			if (ptr[i])
+				count++;
+		}
+
+		for (i = 0; i < SPLAT_VMEM_ALLOC_COUNT; i++)
+			if (ptr[i])
+				vmem_free(ptr[i], size);
+
+		splat_vprint(file, SPLAT_KMEM_TEST3_NAME,
+			   "%d byte allocations, %d/%d successful\n",
+			   size, count, SPLAT_VMEM_ALLOC_COUNT);
+		if (count != SPLAT_VMEM_ALLOC_COUNT)
+			rc = -ENOMEM;
+
+		size *= 2;
+	}
+
+	return rc;
+}
+
+static int
+splat_kmem_test4(struct file *file, void *arg)
+{
+	void *ptr[SPLAT_VMEM_ALLOC_COUNT];
+	int size = PAGE_SIZE;
+	int i, j, count, rc = 0;
+
+	/*
+	 * Test up to 4x the maximum kmem_zalloc() size to ensure both
+	 * the kmem_zalloc() and vmem_zalloc() call paths are used.
+	 */
+	while ((!rc) && (size <= (4 * spl_kmem_alloc_max))) {
+		count = 0;
+
+		for (i = 0; i < SPLAT_VMEM_ALLOC_COUNT; i++) {
+			ptr[i] = vmem_zalloc(size, KM_SLEEP);
+			if (ptr[i])
+				count++;
+		}
+
+		/* Ensure buffer has been zero filled */
+		for (i = 0; i < SPLAT_VMEM_ALLOC_COUNT; i++) {
+			for (j = 0; j < size; j++) {
+				if (((char *)ptr[i])[j] != '\0') {
+					splat_vprint(file, SPLAT_KMEM_TEST4_NAME,
+						  "%d-byte allocation was "
+						  "not zeroed\n", size);
+					rc = -EFAULT;
+				}
+			}
+		}
+
+		for (i = 0; i < SPLAT_VMEM_ALLOC_COUNT; i++)
+			if (ptr[i])
+				vmem_free(ptr[i], size);
+
+		splat_vprint(file, SPLAT_KMEM_TEST4_NAME,
+			   "%d byte allocations, %d/%d successful\n",
+			   size, count, SPLAT_VMEM_ALLOC_COUNT);
+		if (count != SPLAT_VMEM_ALLOC_COUNT)
+			rc = -ENOMEM;
+
+		size *= 2;
+	}
+
+	return rc;
+}
+
+#define SPLAT_KMEM_TEST_MAGIC		0x004488CCUL
+#define SPLAT_KMEM_CACHE_NAME		"kmem_test"
+#define SPLAT_KMEM_OBJ_COUNT		1024
+#define SPLAT_KMEM_OBJ_RECLAIM		32 /* objects */
+#define SPLAT_KMEM_THREADS		32
+
+#define KCP_FLAG_READY			0x01
+
+typedef struct kmem_cache_data {
+	unsigned long kcd_magic;
+	struct list_head kcd_node;
+	int kcd_flag;
+	char kcd_buf[0];
+} kmem_cache_data_t;
+
+typedef struct kmem_cache_thread {
+	spinlock_t kct_lock;
+	int kct_id;
+	struct list_head kct_list;
+} kmem_cache_thread_t;
+
+typedef struct kmem_cache_priv {
+	unsigned long kcp_magic;
+	struct file *kcp_file;
+	kmem_cache_t *kcp_cache;
+	spinlock_t kcp_lock;
+	wait_queue_head_t kcp_ctl_waitq;
+	wait_queue_head_t kcp_thr_waitq;
+	int kcp_flags;
+	int kcp_kct_count;
+	kmem_cache_thread_t *kcp_kct[SPLAT_KMEM_THREADS];
+	int kcp_size;
+	int kcp_align;
+	int kcp_count;
+	int kcp_alloc;
+	int kcp_rc;
+} kmem_cache_priv_t;
+
+static kmem_cache_priv_t *
+splat_kmem_cache_test_kcp_alloc(struct file *file, char *name,
+				int size, int align, int alloc)
+{
+	kmem_cache_priv_t *kcp;
+
+	kcp = kmem_zalloc(sizeof(kmem_cache_priv_t), KM_SLEEP);
+	if (!kcp)
+		return NULL;
+
+	kcp->kcp_magic = SPLAT_KMEM_TEST_MAGIC;
+	kcp->kcp_file = file;
+	kcp->kcp_cache = NULL;
+	spin_lock_init(&kcp->kcp_lock);
+	init_waitqueue_head(&kcp->kcp_ctl_waitq);
+	init_waitqueue_head(&kcp->kcp_thr_waitq);
+	kcp->kcp_flags = 0;
+	kcp->kcp_kct_count = -1;
+	kcp->kcp_size = size;
+	kcp->kcp_align = align;
+	kcp->kcp_count = 0;
+	kcp->kcp_alloc = alloc;
+	kcp->kcp_rc = 0;
+
+	return kcp;
+}
+
+static void
+splat_kmem_cache_test_kcp_free(kmem_cache_priv_t *kcp)
+{
+	kmem_free(kcp, sizeof(kmem_cache_priv_t));
+}
+
+static kmem_cache_thread_t *
+splat_kmem_cache_test_kct_alloc(kmem_cache_priv_t *kcp, int id)
+{
+	kmem_cache_thread_t *kct;
+
+	ASSERT3S(id, <, SPLAT_KMEM_THREADS);
+	ASSERT(kcp->kcp_kct[id] == NULL);
+
+	kct = kmem_zalloc(sizeof(kmem_cache_thread_t), KM_SLEEP);
+	if (!kct)
+		return NULL;
+
+	spin_lock_init(&kct->kct_lock);
+	kct->kct_id = id;
+	INIT_LIST_HEAD(&kct->kct_list);
+
+	spin_lock(&kcp->kcp_lock);
+	kcp->kcp_kct[id] = kct;
+	spin_unlock(&kcp->kcp_lock);
+
+	return kct;
+}
+
+static void
+splat_kmem_cache_test_kct_free(kmem_cache_priv_t *kcp,
+			       kmem_cache_thread_t *kct)
+{
+	spin_lock(&kcp->kcp_lock);
+	kcp->kcp_kct[kct->kct_id] = NULL;
+	spin_unlock(&kcp->kcp_lock);
+
+	kmem_free(kct, sizeof(kmem_cache_thread_t));
+}
+
+static void
+splat_kmem_cache_test_kcd_free(kmem_cache_priv_t *kcp,
+			       kmem_cache_thread_t *kct)
+{
+	kmem_cache_data_t *kcd;
+
+	spin_lock(&kct->kct_lock);
+	while (!list_empty(&kct->kct_list)) {
+		kcd = list_entry(kct->kct_list.next,
+				 kmem_cache_data_t, kcd_node);
+		list_del(&kcd->kcd_node);
+		spin_unlock(&kct->kct_lock);
+
+		kmem_cache_free(kcp->kcp_cache, kcd);
+
+		spin_lock(&kct->kct_lock);
+	}
+	spin_unlock(&kct->kct_lock);
+}
+
+static int
+splat_kmem_cache_test_kcd_alloc(kmem_cache_priv_t *kcp,
+				kmem_cache_thread_t *kct, int count)
+{
+	kmem_cache_data_t *kcd;
+	int i;
+
+	for (i = 0; i < count; i++) {
+		kcd = kmem_cache_alloc(kcp->kcp_cache, KM_SLEEP);
+		if (kcd == NULL) {
+			splat_kmem_cache_test_kcd_free(kcp, kct);
+			return -ENOMEM;
+		}
+
+		spin_lock(&kct->kct_lock);
+		list_add_tail(&kcd->kcd_node, &kct->kct_list);
+		spin_unlock(&kct->kct_lock);
+	}
+
+	return 0;
+}
+
+static void
+splat_kmem_cache_test_debug(struct file *file, char *name,
+			    kmem_cache_priv_t *kcp)
+{
+	int j;
+
+	splat_vprint(file, name, "%s cache objects %d",
+	     kcp->kcp_cache->skc_name, kcp->kcp_count);
+
+	if (kcp->kcp_cache->skc_flags & (KMC_KMEM | KMC_VMEM)) {
+		splat_vprint(file, name, ", slabs %u/%u objs %u/%u",
+		     (unsigned)kcp->kcp_cache->skc_slab_alloc,
+		     (unsigned)kcp->kcp_cache->skc_slab_total,
+		     (unsigned)kcp->kcp_cache->skc_obj_alloc,
+		     (unsigned)kcp->kcp_cache->skc_obj_total);
+
+		if (!(kcp->kcp_cache->skc_flags & KMC_NOMAGAZINE)) {
+			splat_vprint(file, name, "%s", "mags");
+
+			for_each_online_cpu(j)
+				splat_print(file, "%u/%u ",
+				     kcp->kcp_cache->skc_mag[j]->skm_avail,
+				     kcp->kcp_cache->skc_mag[j]->skm_size);
+		}
+	}
+
+	splat_print(file, "%s\n", "");
+}
+
+static int
+splat_kmem_cache_test_constructor(void *ptr, void *priv, int flags)
+{
+	kmem_cache_priv_t *kcp = (kmem_cache_priv_t *)priv;
+	kmem_cache_data_t *kcd = (kmem_cache_data_t *)ptr;
+
+	if (kcd && kcp) {
+		kcd->kcd_magic = kcp->kcp_magic;
+		INIT_LIST_HEAD(&kcd->kcd_node);
+		kcd->kcd_flag = 1;
+		memset(kcd->kcd_buf, 0xaa, kcp->kcp_size - (sizeof *kcd));
+		kcp->kcp_count++;
+	}
+
+	return 0;
+}
+
+static void
+splat_kmem_cache_test_destructor(void *ptr, void *priv)
+{
+	kmem_cache_priv_t *kcp = (kmem_cache_priv_t *)priv;
+	kmem_cache_data_t *kcd = (kmem_cache_data_t *)ptr;
+
+	if (kcd && kcp) {
+		kcd->kcd_magic = 0;
+		kcd->kcd_flag = 0;
+		memset(kcd->kcd_buf, 0xbb, kcp->kcp_size - (sizeof *kcd));
+		kcp->kcp_count--;
+	}
+
+	return;
+}
+
+/*
+ * Generic reclaim function which assumes that all objects may
+ * be reclaimed at any time.  We free a small  percentage of the
+ * objects linked off the kcp or kct[] every time we are called.
+ */
+static void
+splat_kmem_cache_test_reclaim(void *priv)
+{
+	kmem_cache_priv_t *kcp = (kmem_cache_priv_t *)priv;
+	kmem_cache_thread_t *kct;
+	kmem_cache_data_t *kcd;
+	LIST_HEAD(reclaim);
+	int i, count;
+
+	ASSERT(kcp->kcp_magic == SPLAT_KMEM_TEST_MAGIC);
+
+	/* For each kct thread reclaim some objects */
+	spin_lock(&kcp->kcp_lock);
+	for (i = 0; i < SPLAT_KMEM_THREADS; i++) {
+		kct = kcp->kcp_kct[i];
+		if (!kct)
+			continue;
+
+		spin_unlock(&kcp->kcp_lock);
+		spin_lock(&kct->kct_lock);
+
+		count = SPLAT_KMEM_OBJ_RECLAIM;
+		while (count > 0 && !list_empty(&kct->kct_list)) {
+			kcd = list_entry(kct->kct_list.next,
+					 kmem_cache_data_t, kcd_node);
+			list_del(&kcd->kcd_node);
+			list_add(&kcd->kcd_node, &reclaim);
+			count--;
+		}
+
+		spin_unlock(&kct->kct_lock);
+		spin_lock(&kcp->kcp_lock);
+	}
+	spin_unlock(&kcp->kcp_lock);
+
+	/* Freed outside the spin lock */
+	while (!list_empty(&reclaim)) {
+		kcd = list_entry(reclaim.next, kmem_cache_data_t, kcd_node);
+		list_del(&kcd->kcd_node);
+		kmem_cache_free(kcp->kcp_cache, kcd);
+	}
+
+	return;
+}
+
+static int
+splat_kmem_cache_test_threads(kmem_cache_priv_t *kcp, int threads)
+{
+	int rc;
+
+	spin_lock(&kcp->kcp_lock);
+	rc = (kcp->kcp_kct_count == threads);
+	spin_unlock(&kcp->kcp_lock);
+
+	return rc;
+}
+
+static int
+splat_kmem_cache_test_flags(kmem_cache_priv_t *kcp, int flags)
+{
+	int rc;
+
+	spin_lock(&kcp->kcp_lock);
+	rc = (kcp->kcp_flags & flags);
+	spin_unlock(&kcp->kcp_lock);
+
+	return rc;
+}
+
+static void
+splat_kmem_cache_test_thread(void *arg)
+{
+	kmem_cache_priv_t *kcp = (kmem_cache_priv_t *)arg;
+	kmem_cache_thread_t *kct;
+	int rc = 0, id;
+
+	ASSERT(kcp->kcp_magic == SPLAT_KMEM_TEST_MAGIC);
+
+	/* Assign thread ids */
+	spin_lock(&kcp->kcp_lock);
+	if (kcp->kcp_kct_count == -1)
+		kcp->kcp_kct_count = 0;
+
+	id = kcp->kcp_kct_count;
+	kcp->kcp_kct_count++;
+	spin_unlock(&kcp->kcp_lock);
+
+	kct = splat_kmem_cache_test_kct_alloc(kcp, id);
+	if (!kct) {
+		rc = -ENOMEM;
+		goto out;
+	}
+
+	/* Wait for all threads to have started and report they are ready */
+	if (kcp->kcp_kct_count == SPLAT_KMEM_THREADS)
+		wake_up(&kcp->kcp_ctl_waitq);
+
+	wait_event(kcp->kcp_thr_waitq,
+		splat_kmem_cache_test_flags(kcp, KCP_FLAG_READY));
+
+	/* Create and destroy objects */
+	rc = splat_kmem_cache_test_kcd_alloc(kcp, kct, kcp->kcp_alloc);
+	splat_kmem_cache_test_kcd_free(kcp, kct);
+out:
+	if (kct)
+		splat_kmem_cache_test_kct_free(kcp, kct);
+
+	spin_lock(&kcp->kcp_lock);
+	if (!kcp->kcp_rc)
+		kcp->kcp_rc = rc;
+
+	if ((--kcp->kcp_kct_count) == 0)
+		wake_up(&kcp->kcp_ctl_waitq);
+
+	spin_unlock(&kcp->kcp_lock);
+
+	thread_exit();
+}
+
+static int
+splat_kmem_cache_test(struct file *file, void *arg, char *name,
+    int size, int align, int flags)
+{
+	kmem_cache_priv_t *kcp = NULL;
+	kmem_cache_data_t **kcd = NULL;
+	int i, rc = 0, objs = 0;
+
+	splat_vprint(file, name,
+	    "Testing size=%d, align=%d, flags=0x%04x\n",
+	    size, align, flags);
+
+	kcp = splat_kmem_cache_test_kcp_alloc(file, name, size, align, 0);
+	if (!kcp) {
+		splat_vprint(file, name, "Unable to create '%s'\n", "kcp");
+		return (-ENOMEM);
+	}
+
+	kcp->kcp_cache = kmem_cache_create(SPLAT_KMEM_CACHE_NAME,
+	    kcp->kcp_size, kcp->kcp_align,
+	    splat_kmem_cache_test_constructor,
+	    splat_kmem_cache_test_destructor,
+	    NULL, kcp, NULL, flags);
+	if (kcp->kcp_cache == NULL) {
+		splat_vprint(file, name, "Unable to create "
+		    "name='%s', size=%d, align=%d, flags=0x%x\n",
+		    SPLAT_KMEM_CACHE_NAME, size, align, flags);
+		rc = -ENOMEM;
+		goto out_free;
+	}
+
+	/*
+	 * Allocate several slabs worth of objects to verify functionality.
+	 * However, on 32-bit systems with limited address space constrain
+	 * it to a single slab for the purposes of this test.
+	 */
+#ifdef _LP64
+	objs = SPL_KMEM_CACHE_OBJ_PER_SLAB * 4;
+#else
+	objs = 1;
+#endif
+	kcd = kmem_zalloc(sizeof (kmem_cache_data_t *) * objs, KM_SLEEP);
+	if (kcd == NULL) {
+		splat_vprint(file, name, "Unable to allocate pointers "
+		    "for %d objects\n", objs);
+		rc = -ENOMEM;
+		goto out_free;
+	}
+
+	for (i = 0; i < objs; i++) {
+		kcd[i] = kmem_cache_alloc(kcp->kcp_cache, KM_SLEEP);
+		if (kcd[i] == NULL) {
+			splat_vprint(file, name, "Unable to allocate "
+			    "from '%s'\n", SPLAT_KMEM_CACHE_NAME);
+			rc = -EINVAL;
+			goto out_free;
+		}
+
+		if (!kcd[i]->kcd_flag) {
+			splat_vprint(file, name, "Failed to run constructor "
+			    "for '%s'\n", SPLAT_KMEM_CACHE_NAME);
+			rc = -EINVAL;
+			goto out_free;
+		}
+
+		if (kcd[i]->kcd_magic != kcp->kcp_magic) {
+			splat_vprint(file, name,
+			    "Failed to pass private data to constructor "
+			    "for '%s'\n", SPLAT_KMEM_CACHE_NAME);
+			rc = -EINVAL;
+			goto out_free;
+		}
+	}
+
+	for (i = 0; i < objs; i++) {
+		kmem_cache_free(kcp->kcp_cache, kcd[i]);
+
+		/* Destructors are run for every kmem_cache_free() */
+		if (kcd[i]->kcd_flag) {
+			splat_vprint(file, name,
+			    "Failed to run destructor for '%s'\n",
+			    SPLAT_KMEM_CACHE_NAME);
+			rc = -EINVAL;
+			goto out_free;
+		}
+	}
+
+	if (kcp->kcp_count) {
+		splat_vprint(file, name,
+		    "Failed to run destructor on all slab objects for '%s'\n",
+		    SPLAT_KMEM_CACHE_NAME);
+		rc = -EINVAL;
+	}
+
+	kmem_free(kcd, sizeof (kmem_cache_data_t *) * objs);
+	kmem_cache_destroy(kcp->kcp_cache);
+
+	splat_kmem_cache_test_kcp_free(kcp);
+	splat_vprint(file, name,
+	    "Success ran alloc'd/free'd %d objects of size %d\n",
+	    objs, size);
+
+	return (rc);
+
+out_free:
+	if (kcd) {
+		for (i = 0; i < objs; i++) {
+			if (kcd[i] != NULL)
+				kmem_cache_free(kcp->kcp_cache, kcd[i]);
+		}
+
+		kmem_free(kcd, sizeof (kmem_cache_data_t *) * objs);
+	}
+
+	if (kcp->kcp_cache)
+		kmem_cache_destroy(kcp->kcp_cache);
+
+	splat_kmem_cache_test_kcp_free(kcp);
+
+	return (rc);
+}
+
+static int
+splat_kmem_cache_thread_test(struct file *file, void *arg, char *name,
+			     int size, int alloc, int max_time)
+{
+	kmem_cache_priv_t *kcp;
+	kthread_t *thr;
+	struct timespec start, stop, delta;
+	char cache_name[32];
+	int i, rc = 0;
+
+	kcp = splat_kmem_cache_test_kcp_alloc(file, name, size, 0, alloc);
+	if (!kcp) {
+		splat_vprint(file, name, "Unable to create '%s'\n", "kcp");
+		return -ENOMEM;
+	}
+
+	(void)snprintf(cache_name, 32, "%s-%d-%d",
+		       SPLAT_KMEM_CACHE_NAME, size, alloc);
+	kcp->kcp_cache =
+		kmem_cache_create(cache_name, kcp->kcp_size, 0,
+				  splat_kmem_cache_test_constructor,
+				  splat_kmem_cache_test_destructor,
+				  splat_kmem_cache_test_reclaim,
+				  kcp, NULL, 0);
+	if (!kcp->kcp_cache) {
+		splat_vprint(file, name, "Unable to create '%s'\n", cache_name);
+		rc = -ENOMEM;
+		goto out_kcp;
+	}
+
+	getnstimeofday(&start);
+
+	for (i = 0; i < SPLAT_KMEM_THREADS; i++) {
+		thr = thread_create(NULL, 0,
+				    splat_kmem_cache_test_thread,
+				    kcp, 0, &p0, TS_RUN, defclsyspri);
+		if (thr == NULL) {
+			rc = -ESRCH;
+			goto out_cache;
+		}
+	}
+
+	/* Sleep until all threads have started, then set the ready
+	 * flag and wake them all up for maximum concurrency. */
+	wait_event(kcp->kcp_ctl_waitq,
+		   splat_kmem_cache_test_threads(kcp, SPLAT_KMEM_THREADS));
+
+	spin_lock(&kcp->kcp_lock);
+	kcp->kcp_flags |= KCP_FLAG_READY;
+	spin_unlock(&kcp->kcp_lock);
+	wake_up_all(&kcp->kcp_thr_waitq);
+
+	/* Sleep until all thread have finished */
+	wait_event(kcp->kcp_ctl_waitq, splat_kmem_cache_test_threads(kcp, 0));
+
+	getnstimeofday(&stop);
+	delta = timespec_sub(stop, start);
+
+	splat_vprint(file, name,
+		     "%-22s %2ld.%09ld\t"
+		     "%lu/%lu/%lu\t%lu/%lu/%lu\n",
+		     kcp->kcp_cache->skc_name,
+		     delta.tv_sec, delta.tv_nsec,
+		     (unsigned long)kcp->kcp_cache->skc_slab_total,
+		     (unsigned long)kcp->kcp_cache->skc_slab_max,
+		     (unsigned long)(kcp->kcp_alloc *
+				    SPLAT_KMEM_THREADS /
+				    SPL_KMEM_CACHE_OBJ_PER_SLAB),
+		     (unsigned long)kcp->kcp_cache->skc_obj_total,
+		     (unsigned long)kcp->kcp_cache->skc_obj_max,
+		     (unsigned long)(kcp->kcp_alloc *
+				     SPLAT_KMEM_THREADS));
+
+	if (delta.tv_sec >= max_time)
+		rc = -ETIME;
+
+	if (!rc && kcp->kcp_rc)
+		rc = kcp->kcp_rc;
+
+out_cache:
+	kmem_cache_destroy(kcp->kcp_cache);
+out_kcp:
+	splat_kmem_cache_test_kcp_free(kcp);
+	return rc;
+}
+
+/* Validate small object cache behavior for dynamic/kmem/vmem caches */
+static int
+splat_kmem_test5(struct file *file, void *arg)
+{
+	char *name = SPLAT_KMEM_TEST5_NAME;
+	int i, rc = 0;
+
+	/* Randomly pick small object sizes and alignments. */
+	for (i = 0; i < 100; i++) {
+		int size, align, flags = 0;
+		uint32_t rnd;
+
+		/* Evenly distribute tests over all value cache types */
+		get_random_bytes((void *)&rnd, sizeof (uint32_t));
+		switch (rnd & 0x03) {
+		default:
+		case 0x00:
+			flags = 0;
+			break;
+		case 0x01:
+			flags = KMC_KMEM;
+			break;
+		case 0x02:
+			flags = KMC_VMEM;
+			break;
+		case 0x03:
+			flags = KMC_SLAB;
+			break;
+		}
+
+		/* The following flags are set with a 1/10 chance */
+		flags |= ((((rnd >> 8) % 10) == 0) ? KMC_OFFSLAB : 0);
+		flags |= ((((rnd >> 16) % 10) == 0) ? KMC_NOEMERGENCY : 0);
+
+		/* 32b - PAGE_SIZE */
+		get_random_bytes((void *)&rnd, sizeof (uint32_t));
+		size = MAX(rnd % (PAGE_SIZE + 1), 32);
+
+		/* 2^N where (3 <= N <= PAGE_SHIFT) */
+		get_random_bytes((void *)&rnd, sizeof (uint32_t));
+		align = (1 << MAX(3, rnd % (PAGE_SHIFT + 1)));
+
+		rc = splat_kmem_cache_test(file, arg, name, size, align, flags);
+		if (rc)
+			return (rc);
+	}
+
+	return (rc);
+}
+
+/*
+ * Validate large object cache behavior for dynamic/kmem/vmem caches
+ */
+static int
+splat_kmem_test6(struct file *file, void *arg)
+{
+	char *name = SPLAT_KMEM_TEST6_NAME;
+	int i, max_size, rc = 0;
+
+	/* Randomly pick large object sizes and alignments. */
+	for (i = 0; i < 100; i++) {
+		int size, align, flags = 0;
+		uint32_t rnd;
+
+		/* Evenly distribute tests over all value cache types */
+		get_random_bytes((void *)&rnd, sizeof (uint32_t));
+		switch (rnd & 0x03) {
+		default:
+		case 0x00:
+			flags = 0;
+			max_size = (SPL_KMEM_CACHE_MAX_SIZE * 1024 * 1024) / 2;
+			break;
+		case 0x01:
+			flags = KMC_KMEM;
+			max_size = (SPL_MAX_ORDER_NR_PAGES - 2) * PAGE_SIZE;
+			break;
+		case 0x02:
+			flags = KMC_VMEM;
+			max_size = (SPL_KMEM_CACHE_MAX_SIZE * 1024 * 1024) / 2;
+			break;
+		case 0x03:
+			flags = KMC_SLAB;
+			max_size = SPL_MAX_KMEM_ORDER_NR_PAGES * PAGE_SIZE;
+			break;
+		}
+
+		/* The following flags are set with a 1/10 chance */
+		flags |= ((((rnd >> 8) % 10) == 0) ? KMC_OFFSLAB : 0);
+		flags |= ((((rnd >> 16) % 10) == 0) ? KMC_NOEMERGENCY : 0);
+
+		/* PAGE_SIZE - max_size */
+		get_random_bytes((void *)&rnd, sizeof (uint32_t));
+		size = MAX(rnd % (max_size + 1), PAGE_SIZE),
+
+		/* 2^N where (3 <= N <= PAGE_SHIFT) */
+		get_random_bytes((void *)&rnd, sizeof (uint32_t));
+		align = (1 << MAX(3, rnd % (PAGE_SHIFT + 1)));
+
+		rc = splat_kmem_cache_test(file, arg, name, size, align, flags);
+		if (rc)
+			return (rc);
+	}
+
+	return (rc);
+}
+
+/*
+ * Validate object alignment cache behavior for caches
+ */
+static int
+splat_kmem_test7(struct file *file, void *arg)
+{
+	char *name = SPLAT_KMEM_TEST7_NAME;
+	int max_size = (SPL_KMEM_CACHE_MAX_SIZE * 1024 * 1024) / 2;
+	int i, rc;
+
+	for (i = SPL_KMEM_CACHE_ALIGN; i <= PAGE_SIZE; i *= 2) {
+		uint32_t size;
+
+		get_random_bytes((void *)&size, sizeof (uint32_t));
+		size = MAX(size % (max_size + 1), 32);
+
+		rc = splat_kmem_cache_test(file, arg, name, size, i, 0);
+		if (rc)
+			return rc;
+
+		rc = splat_kmem_cache_test(file, arg, name, size, i,
+		    KMC_OFFSLAB);
+		if (rc)
+			return rc;
+	}
+
+	return rc;
+}
+
+/*
+ * Validate kmem_cache_reap() by requesting the slab cache free any objects
+ * it can.  For a few reasons this may not immediately result in more free
+ * memory even if objects are freed.  First off, due to fragmentation we
+ * may not be able to reclaim any slabs.  Secondly, even if we do we fully
+ * clear some slabs we will not want to immediately reclaim all of them
+ * because we may contend with cache allocations and thrash.  What we want
+ * to see is the slab size decrease more gradually as it becomes clear they
+ * will not be needed.  This should be achievable in less than a minute.
+ * If it takes longer than this something has gone wrong.
+ */
+static int
+splat_kmem_test8(struct file *file, void *arg)
+{
+	kmem_cache_priv_t *kcp;
+	kmem_cache_thread_t *kct;
+	unsigned int spl_kmem_cache_expire_old;
+	int i, rc = 0;
+
+	/* Enable cache aging just for this test if it is disabled */
+	spl_kmem_cache_expire_old = spl_kmem_cache_expire;
+	spl_kmem_cache_expire = KMC_EXPIRE_AGE;
+
+	kcp = splat_kmem_cache_test_kcp_alloc(file, SPLAT_KMEM_TEST8_NAME,
+					      256, 0, 0);
+	if (!kcp) {
+		splat_vprint(file, SPLAT_KMEM_TEST8_NAME,
+			     "Unable to create '%s'\n", "kcp");
+		rc = -ENOMEM;
+		goto out;
+	}
+
+	kcp->kcp_cache =
+		kmem_cache_create(SPLAT_KMEM_CACHE_NAME, kcp->kcp_size, 0,
+				  splat_kmem_cache_test_constructor,
+				  splat_kmem_cache_test_destructor,
+				  splat_kmem_cache_test_reclaim,
+				  kcp, NULL, 0);
+	if (!kcp->kcp_cache) {
+		splat_vprint(file, SPLAT_KMEM_TEST8_NAME,
+			   "Unable to create '%s'\n", SPLAT_KMEM_CACHE_NAME);
+		rc = -ENOMEM;
+		goto out_kcp;
+	}
+
+	kct = splat_kmem_cache_test_kct_alloc(kcp, 0);
+	if (!kct) {
+		splat_vprint(file, SPLAT_KMEM_TEST8_NAME,
+			     "Unable to create '%s'\n", "kct");
+		rc = -ENOMEM;
+		goto out_cache;
+	}
+
+	rc = splat_kmem_cache_test_kcd_alloc(kcp, kct, SPLAT_KMEM_OBJ_COUNT);
+	if (rc) {
+		splat_vprint(file, SPLAT_KMEM_TEST8_NAME, "Unable to "
+			     "allocate from '%s'\n", SPLAT_KMEM_CACHE_NAME);
+		goto out_kct;
+	}
+
+	/* Force reclaim every 1/10 a second for 60 seconds. */
+	for (i = 0; i < 600; i++) {
+		kmem_cache_reap_now(kcp->kcp_cache);
+		splat_kmem_cache_test_debug(file, SPLAT_KMEM_TEST8_NAME, kcp);
+
+		if (kcp->kcp_count == 0)
+			break;
+
+		set_current_state(TASK_INTERRUPTIBLE);
+		schedule_timeout(HZ / 10);
+	}
+
+	if (kcp->kcp_count == 0) {
+		splat_vprint(file, SPLAT_KMEM_TEST8_NAME,
+			"Successfully created %d objects "
+			"in cache %s and reclaimed them\n",
+			SPLAT_KMEM_OBJ_COUNT, SPLAT_KMEM_CACHE_NAME);
+	} else {
+		splat_vprint(file, SPLAT_KMEM_TEST8_NAME,
+			"Failed to reclaim %u/%d objects from cache %s\n",
+			(unsigned)kcp->kcp_count,
+			SPLAT_KMEM_OBJ_COUNT, SPLAT_KMEM_CACHE_NAME);
+		rc = -ENOMEM;
+	}
+
+	/* Cleanup our mess (for failure case of time expiring) */
+	splat_kmem_cache_test_kcd_free(kcp, kct);
+out_kct:
+	splat_kmem_cache_test_kct_free(kcp, kct);
+out_cache:
+	kmem_cache_destroy(kcp->kcp_cache);
+out_kcp:
+	splat_kmem_cache_test_kcp_free(kcp);
+out:
+	spl_kmem_cache_expire = spl_kmem_cache_expire_old;
+
+	return rc;
+}
+
+/* Test cache aging, we have allocated a large number of objects thus
+ * creating a large number of slabs and then free'd them all.  However,
+ * since there should be little memory pressure at the moment those
+ * slabs have not been freed.  What we want to see is the slab size
+ * decrease gradually as it becomes clear they will not be be needed.
+ * This should be achievable in less than minute.  If it takes longer
+ * than this something has gone wrong.
+ */
+static int
+splat_kmem_test9(struct file *file, void *arg)
+{
+	kmem_cache_priv_t *kcp;
+	kmem_cache_thread_t *kct;
+	unsigned int spl_kmem_cache_expire_old;
+	int i, rc = 0, count = SPLAT_KMEM_OBJ_COUNT * 128;
+
+	/* Enable cache aging just for this test if it is disabled */
+	spl_kmem_cache_expire_old = spl_kmem_cache_expire;
+	spl_kmem_cache_expire = KMC_EXPIRE_AGE;
+
+	kcp = splat_kmem_cache_test_kcp_alloc(file, SPLAT_KMEM_TEST9_NAME,
+					      256, 0, 0);
+	if (!kcp) {
+		splat_vprint(file, SPLAT_KMEM_TEST9_NAME,
+			     "Unable to create '%s'\n", "kcp");
+		rc = -ENOMEM;
+		goto out;
+	}
+
+	kcp->kcp_cache =
+		kmem_cache_create(SPLAT_KMEM_CACHE_NAME, kcp->kcp_size, 0,
+				  splat_kmem_cache_test_constructor,
+				  splat_kmem_cache_test_destructor,
+				  NULL, kcp, NULL, 0);
+	if (!kcp->kcp_cache) {
+		splat_vprint(file, SPLAT_KMEM_TEST9_NAME,
+			   "Unable to create '%s'\n", SPLAT_KMEM_CACHE_NAME);
+		rc = -ENOMEM;
+		goto out_kcp;
+	}
+
+	kct = splat_kmem_cache_test_kct_alloc(kcp, 0);
+	if (!kct) {
+		splat_vprint(file, SPLAT_KMEM_TEST8_NAME,
+			     "Unable to create '%s'\n", "kct");
+		rc = -ENOMEM;
+		goto out_cache;
+	}
+
+	rc = splat_kmem_cache_test_kcd_alloc(kcp, kct, count);
+	if (rc) {
+		splat_vprint(file, SPLAT_KMEM_TEST9_NAME, "Unable to "
+			     "allocate from '%s'\n", SPLAT_KMEM_CACHE_NAME);
+		goto out_kct;
+	}
+
+	splat_kmem_cache_test_kcd_free(kcp, kct);
+
+	for (i = 0; i < 60; i++) {
+		splat_kmem_cache_test_debug(file, SPLAT_KMEM_TEST9_NAME, kcp);
+
+		if (kcp->kcp_count == 0)
+			break;
+
+		set_current_state(TASK_INTERRUPTIBLE);
+		schedule_timeout(HZ);
+	}
+
+	if (kcp->kcp_count == 0) {
+		splat_vprint(file, SPLAT_KMEM_TEST9_NAME,
+			"Successfully created %d objects "
+			"in cache %s and reclaimed them\n",
+			count, SPLAT_KMEM_CACHE_NAME);
+	} else {
+		splat_vprint(file, SPLAT_KMEM_TEST9_NAME,
+			"Failed to reclaim %u/%d objects from cache %s\n",
+			(unsigned)kcp->kcp_count, count,
+			SPLAT_KMEM_CACHE_NAME);
+		rc = -ENOMEM;
+	}
+
+out_kct:
+	splat_kmem_cache_test_kct_free(kcp, kct);
+out_cache:
+	kmem_cache_destroy(kcp->kcp_cache);
+out_kcp:
+	splat_kmem_cache_test_kcp_free(kcp);
+out:
+	spl_kmem_cache_expire = spl_kmem_cache_expire_old;
+
+	return rc;
+}
+
+/*
+ * This test creates N threads with a shared kmem cache.  They then all
+ * concurrently allocate and free from the cache to stress the locking and
+ * concurrent cache performance.  If any one test takes longer than 5
+ * seconds to complete it is treated as a failure and may indicate a
+ * performance regression.  On my test system no one test takes more
+ * than 1 second to complete so a 5x slowdown likely a problem.
+ */
+static int
+splat_kmem_test10(struct file *file, void *arg)
+{
+	uint64_t size, alloc, rc = 0;
+
+	for (size = 32; size <= 1024*1024; size *= 2) {
+
+		splat_vprint(file, SPLAT_KMEM_TEST10_NAME, "%-22s  %s", "name",
+			     "time (sec)\tslabs       \tobjs	\thash\n");
+		splat_vprint(file, SPLAT_KMEM_TEST10_NAME, "%-22s  %s", "",
+			     "	  \ttot/max/calc\ttot/max/calc\n");
+
+		for (alloc = 1; alloc <= 1024; alloc *= 2) {
+
+			/* Skip tests which exceed 1/2 of physical memory. */
+			if (size * alloc * SPLAT_KMEM_THREADS > physmem / 2)
+				continue;
+
+			rc = splat_kmem_cache_thread_test(file, arg,
+				SPLAT_KMEM_TEST10_NAME, size, alloc, 5);
+			if (rc)
+				break;
+		}
+	}
+
+	return rc;
+}
+
+#if 0
+/*
+ * This test creates N threads with a shared kmem cache which overcommits
+ * memory by 4x.  This makes it impossible for the slab to satify the
+ * thread requirements without having its reclaim hook run which will
+ * free objects back for use.  This behavior is triggered by the linum VM
+ * detecting a low memory condition on the node and invoking the shrinkers.
+ * This should allow all the threads to complete while avoiding deadlock
+ * and for the most part out of memory events.  This is very tough on the
+ * system so it is possible the test app may get oom'ed.  This particular
+ * test has proven troublesome on 32-bit archs with limited virtual
+ * address space so it only run on 64-bit systems.
+ */
+static int
+splat_kmem_test11(struct file *file, void *arg)
+{
+	uint64_t size, alloc, rc;
+
+	size = 8 * 1024;
+	alloc = ((4 * physmem * PAGE_SIZE) / size) / SPLAT_KMEM_THREADS;
+
+	splat_vprint(file, SPLAT_KMEM_TEST11_NAME, "%-22s  %s", "name",
+		     "time (sec)\tslabs       \tobjs	\thash\n");
+	splat_vprint(file, SPLAT_KMEM_TEST11_NAME, "%-22s  %s", "",
+		     "	  \ttot/max/calc\ttot/max/calc\n");
+
+	rc = splat_kmem_cache_thread_test(file, arg,
+		SPLAT_KMEM_TEST11_NAME, size, alloc, 60);
+
+	return rc;
+}
+#endif
+
+typedef struct dummy_page {
+	struct list_head dp_list;
+	char             dp_pad[PAGE_SIZE - sizeof(struct list_head)];
+} dummy_page_t;
+
+/*
+ * This test is designed to verify that direct reclaim is functioning as
+ * expected.  We allocate a large number of objects thus creating a large
+ * number of slabs.  We then apply memory pressure and expect that the
+ * direct reclaim path can easily recover those slabs.  The registered
+ * reclaim function will free the objects and the slab shrinker will call
+ * it repeatedly until at least a single slab can be freed.
+ *
+ * Note it may not be possible to reclaim every last slab via direct reclaim
+ * without a failure because the shrinker_rwsem may be contended.  For this
+ * reason, quickly reclaiming 3/4 of the slabs is considered a success.
+ *
+ * This should all be possible within 10 seconds.  For reference, on a
+ * system with 2G of memory this test takes roughly 0.2 seconds to run.
+ * It may take longer on larger memory systems but should still easily
+ * complete in the alloted 10 seconds.
+ */
+static int
+splat_kmem_test13(struct file *file, void *arg)
+{
+	kmem_cache_priv_t *kcp;
+	kmem_cache_thread_t *kct;
+	dummy_page_t *dp;
+	struct list_head list;
+	struct timespec start, stop, delta = { 0, 0 };
+	int size, count, slabs, fails = 0;
+	int i, rc = 0, max_time = 10;
+
+	size = 128 * 1024;
+	count = ((physmem * PAGE_SIZE) / 4 / size);
+
+	kcp = splat_kmem_cache_test_kcp_alloc(file, SPLAT_KMEM_TEST13_NAME,
+	                                      size, 0, 0);
+	if (!kcp) {
+		splat_vprint(file, SPLAT_KMEM_TEST13_NAME,
+		             "Unable to create '%s'\n", "kcp");
+		rc = -ENOMEM;
+		goto out;
+	}
+
+	kcp->kcp_cache =
+		kmem_cache_create(SPLAT_KMEM_CACHE_NAME, kcp->kcp_size, 0,
+		                  splat_kmem_cache_test_constructor,
+		                  splat_kmem_cache_test_destructor,
+				  splat_kmem_cache_test_reclaim,
+		                  kcp, NULL, 0);
+	if (!kcp->kcp_cache) {
+		splat_vprint(file, SPLAT_KMEM_TEST13_NAME,
+		             "Unable to create '%s'\n", SPLAT_KMEM_CACHE_NAME);
+		rc = -ENOMEM;
+		goto out_kcp;
+	}
+
+	kct = splat_kmem_cache_test_kct_alloc(kcp, 0);
+	if (!kct) {
+		splat_vprint(file, SPLAT_KMEM_TEST13_NAME,
+			     "Unable to create '%s'\n", "kct");
+		rc = -ENOMEM;
+		goto out_cache;
+	}
+
+	rc = splat_kmem_cache_test_kcd_alloc(kcp, kct, count);
+	if (rc) {
+		splat_vprint(file, SPLAT_KMEM_TEST13_NAME, "Unable to "
+			     "allocate from '%s'\n", SPLAT_KMEM_CACHE_NAME);
+		goto out_kct;
+	}
+
+	i = 0;
+	slabs = kcp->kcp_cache->skc_slab_total;
+	INIT_LIST_HEAD(&list);
+	getnstimeofday(&start);
+
+	/* Apply memory pressure */
+	while (kcp->kcp_cache->skc_slab_total > (slabs >> 2)) {
+
+		if ((i % 10000) == 0)
+			splat_kmem_cache_test_debug(
+			    file, SPLAT_KMEM_TEST13_NAME, kcp);
+
+		getnstimeofday(&stop);
+		delta = timespec_sub(stop, start);
+		if (delta.tv_sec >= max_time) {
+			splat_vprint(file, SPLAT_KMEM_TEST13_NAME,
+				     "Failed to reclaim 3/4 of cache in %ds, "
+				     "%u/%u slabs remain\n", max_time,
+				     (unsigned)kcp->kcp_cache->skc_slab_total,
+				     slabs);
+			rc = -ETIME;
+			break;
+		}
+
+		dp = (dummy_page_t *)__get_free_page(GFP_KERNEL);
+		if (!dp) {
+			fails++;
+			splat_vprint(file, SPLAT_KMEM_TEST13_NAME,
+				     "Failed (%d) to allocate page with %u "
+				     "slabs still in the cache\n", fails,
+				     (unsigned)kcp->kcp_cache->skc_slab_total);
+			continue;
+		}
+
+		list_add(&dp->dp_list, &list);
+		i++;
+	}
+
+	if (rc == 0)
+		splat_vprint(file, SPLAT_KMEM_TEST13_NAME,
+			     "Successfully created %u slabs and with %d alloc "
+			     "failures reclaimed 3/4 of them in %d.%03ds\n",
+			     slabs, fails,
+			     (int)delta.tv_sec, (int)delta.tv_nsec / 1000000);
+
+	/* Release memory pressure pages */
+	while (!list_empty(&list)) {
+		dp = list_entry(list.next, dummy_page_t, dp_list);
+		list_del_init(&dp->dp_list);
+		free_page((unsigned long)dp);
+	}
+
+	/* Release remaining kmem cache objects */
+	splat_kmem_cache_test_kcd_free(kcp, kct);
+out_kct:
+	splat_kmem_cache_test_kct_free(kcp, kct);
+out_cache:
+	kmem_cache_destroy(kcp->kcp_cache);
+out_kcp:
+	splat_kmem_cache_test_kcp_free(kcp);
+out:
+	return rc;
+}
+
+splat_subsystem_t *
+splat_kmem_init(void)
+{
+	splat_subsystem_t *sub;
+
+	sub = kmalloc(sizeof(*sub), GFP_KERNEL);
+	if (sub == NULL)
+		return NULL;
+
+	memset(sub, 0, sizeof(*sub));
+	strncpy(sub->desc.name, SPLAT_KMEM_NAME, SPLAT_NAME_SIZE);
+	strncpy(sub->desc.desc, SPLAT_KMEM_DESC, SPLAT_DESC_SIZE);
+	INIT_LIST_HEAD(&sub->subsystem_list);
+	INIT_LIST_HEAD(&sub->test_list);
+	spin_lock_init(&sub->test_lock);
+	sub->desc.id = SPLAT_SUBSYSTEM_KMEM;
+
+	SPLAT_TEST_INIT(sub, SPLAT_KMEM_TEST1_NAME, SPLAT_KMEM_TEST1_DESC,
+			SPLAT_KMEM_TEST1_ID, splat_kmem_test1);
+	SPLAT_TEST_INIT(sub, SPLAT_KMEM_TEST2_NAME, SPLAT_KMEM_TEST2_DESC,
+			SPLAT_KMEM_TEST2_ID, splat_kmem_test2);
+	SPLAT_TEST_INIT(sub, SPLAT_KMEM_TEST3_NAME, SPLAT_KMEM_TEST3_DESC,
+			SPLAT_KMEM_TEST3_ID, splat_kmem_test3);
+	SPLAT_TEST_INIT(sub, SPLAT_KMEM_TEST4_NAME, SPLAT_KMEM_TEST4_DESC,
+			SPLAT_KMEM_TEST4_ID, splat_kmem_test4);
+	SPLAT_TEST_INIT(sub, SPLAT_KMEM_TEST5_NAME, SPLAT_KMEM_TEST5_DESC,
+			SPLAT_KMEM_TEST5_ID, splat_kmem_test5);
+	SPLAT_TEST_INIT(sub, SPLAT_KMEM_TEST6_NAME, SPLAT_KMEM_TEST6_DESC,
+			SPLAT_KMEM_TEST6_ID, splat_kmem_test6);
+	SPLAT_TEST_INIT(sub, SPLAT_KMEM_TEST7_NAME, SPLAT_KMEM_TEST7_DESC,
+			SPLAT_KMEM_TEST7_ID, splat_kmem_test7);
+	SPLAT_TEST_INIT(sub, SPLAT_KMEM_TEST8_NAME, SPLAT_KMEM_TEST8_DESC,
+			SPLAT_KMEM_TEST8_ID, splat_kmem_test8);
+	SPLAT_TEST_INIT(sub, SPLAT_KMEM_TEST9_NAME, SPLAT_KMEM_TEST9_DESC,
+			SPLAT_KMEM_TEST9_ID, splat_kmem_test9);
+	SPLAT_TEST_INIT(sub, SPLAT_KMEM_TEST10_NAME, SPLAT_KMEM_TEST10_DESC,
+			SPLAT_KMEM_TEST10_ID, splat_kmem_test10);
+#if 0
+	SPLAT_TEST_INIT(sub, SPLAT_KMEM_TEST11_NAME, SPLAT_KMEM_TEST11_DESC,
+			SPLAT_KMEM_TEST11_ID, splat_kmem_test11);
+#endif
+	SPLAT_TEST_INIT(sub, SPLAT_KMEM_TEST13_NAME, SPLAT_KMEM_TEST13_DESC,
+			SPLAT_KMEM_TEST13_ID, splat_kmem_test13);
+
+	return sub;
+}
+
+void
+splat_kmem_fini(splat_subsystem_t *sub)
+{
+	ASSERT(sub);
+	SPLAT_TEST_FINI(sub, SPLAT_KMEM_TEST13_ID);
+#if 0
+	SPLAT_TEST_FINI(sub, SPLAT_KMEM_TEST11_ID);
+#endif
+	SPLAT_TEST_FINI(sub, SPLAT_KMEM_TEST10_ID);
+	SPLAT_TEST_FINI(sub, SPLAT_KMEM_TEST9_ID);
+	SPLAT_TEST_FINI(sub, SPLAT_KMEM_TEST8_ID);
+	SPLAT_TEST_FINI(sub, SPLAT_KMEM_TEST7_ID);
+	SPLAT_TEST_FINI(sub, SPLAT_KMEM_TEST6_ID);
+	SPLAT_TEST_FINI(sub, SPLAT_KMEM_TEST5_ID);
+	SPLAT_TEST_FINI(sub, SPLAT_KMEM_TEST4_ID);
+	SPLAT_TEST_FINI(sub, SPLAT_KMEM_TEST3_ID);
+	SPLAT_TEST_FINI(sub, SPLAT_KMEM_TEST2_ID);
+	SPLAT_TEST_FINI(sub, SPLAT_KMEM_TEST1_ID);
+
+	kfree(sub);
+}
+
+int
+splat_kmem_id(void) {
+	return SPLAT_SUBSYSTEM_KMEM;
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/module/splat/splat-kobj.c
@@ -0,0 +1,166 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+ *****************************************************************************
+ *  Solaris Porting LAyer Tests (SPLAT) Kobj Tests.
+\*****************************************************************************/
+
+#include <sys/kobj.h>
+#include "splat-internal.h"
+
+#define SPLAT_KOBJ_NAME			"kobj"
+#define SPLAT_KOBJ_DESC			"Kernel Kobj Tests"
+
+#define SPLAT_KOBJ_TEST1_ID		0x0a01
+#define SPLAT_KOBJ_TEST1_NAME		"open"
+#define SPLAT_KOBJ_TEST1_DESC		"Kobj Open/Close Test"
+
+#define SPLAT_KOBJ_TEST2_ID		0x0a02
+#define SPLAT_KOBJ_TEST2_NAME		"size/read"
+#define SPLAT_KOBJ_TEST2_DESC		"Kobj Size/Read Test"
+
+#define SPLAT_KOBJ_TEST_FILE		"/etc/fstab"
+
+static int
+splat_kobj_test1(struct file *file, void *arg)
+{
+	struct _buf *f;
+
+	f = kobj_open_file(SPLAT_KOBJ_TEST_FILE);
+	if (f == (struct _buf *)-1) {
+		splat_vprint(file, SPLAT_KOBJ_TEST1_NAME, "Failed to open "
+			     "test file: %s\n", SPLAT_KOBJ_TEST_FILE);
+		return -ENOENT;
+	}
+
+	kobj_close_file(f);
+	splat_vprint(file, SPLAT_KOBJ_TEST1_NAME, "Successfully opened and "
+		     "closed test file: %s\n", SPLAT_KOBJ_TEST_FILE);
+
+        return 0;
+} /* splat_kobj_test1() */
+
+static int
+splat_kobj_test2(struct file *file, void *arg)
+{
+	struct _buf *f;
+	char *buf;
+	uint64_t size;
+	int rc;
+
+	f = kobj_open_file(SPLAT_KOBJ_TEST_FILE);
+	if (f == (struct _buf *)-1) {
+		splat_vprint(file, SPLAT_KOBJ_TEST2_NAME, "Failed to open "
+			     "test file: %s\n", SPLAT_KOBJ_TEST_FILE);
+		return -ENOENT;
+	}
+
+	rc = kobj_get_filesize(f, &size);
+	if (rc) {
+		splat_vprint(file, SPLAT_KOBJ_TEST2_NAME, "Failed stat of "
+			     "test file: %s (%d)\n", SPLAT_KOBJ_TEST_FILE, rc);
+		goto out;
+	}
+
+	buf = kmalloc(size + 1, GFP_KERNEL);
+	if (!buf) {
+		rc = -ENOMEM;
+		splat_vprint(file, SPLAT_KOBJ_TEST2_NAME, "Failed to alloc "
+			     "%lld bytes for tmp buffer (%d)\n",
+			     (long long)size, rc);
+		goto out;
+	}
+
+	memset(buf, 0, size + 1);
+	rc = kobj_read_file(f, buf, size, 0);
+	if (rc < 0) {
+		splat_vprint(file, SPLAT_KOBJ_TEST2_NAME, "Failed read of "
+			     "test file: %s (%d)\n", SPLAT_KOBJ_TEST_FILE, rc);
+		goto out2;
+	}
+
+	/* Validate we read as many bytes as expected based on the stat.  This
+	 * isn't a perfect test since we didn't create the file however it is
+	 * pretty unlikely there are garbage characters in your /etc/fstab */
+	if (size != (uint64_t)strlen(buf)) {
+		rc = -EFBIG;
+		splat_vprint(file, SPLAT_KOBJ_TEST2_NAME, "Stat'ed size "
+			     "(%lld) does not match number of bytes read "
+			     "(%lld)\n", (long long)size,
+			     (long long)strlen(buf));
+		goto out2;
+	}
+
+	rc = 0;
+	splat_vprint(file, SPLAT_KOBJ_TEST2_NAME, "\n%s\n", buf);
+	splat_vprint(file, SPLAT_KOBJ_TEST2_NAME, "Successfully stat'ed "
+		     "and read expected number of bytes (%lld) from test "
+		     "file: %s\n", (long long)size, SPLAT_KOBJ_TEST_FILE);
+out2:
+	kfree(buf);
+out:
+	kobj_close_file(f);
+
+        return rc;
+} /* splat_kobj_test2() */
+
+splat_subsystem_t *
+splat_kobj_init(void)
+{
+        splat_subsystem_t *sub;
+
+        sub = kmalloc(sizeof(*sub), GFP_KERNEL);
+        if (sub == NULL)
+                return NULL;
+
+        memset(sub, 0, sizeof(*sub));
+        strncpy(sub->desc.name, SPLAT_KOBJ_NAME, SPLAT_NAME_SIZE);
+	strncpy(sub->desc.desc, SPLAT_KOBJ_DESC, SPLAT_DESC_SIZE);
+        INIT_LIST_HEAD(&sub->subsystem_list);
+	INIT_LIST_HEAD(&sub->test_list);
+        spin_lock_init(&sub->test_lock);
+        sub->desc.id = SPLAT_SUBSYSTEM_KOBJ;
+
+        SPLAT_TEST_INIT(sub, SPLAT_KOBJ_TEST1_NAME, SPLAT_KOBJ_TEST1_DESC,
+	              SPLAT_KOBJ_TEST1_ID, splat_kobj_test1);
+        SPLAT_TEST_INIT(sub, SPLAT_KOBJ_TEST2_NAME, SPLAT_KOBJ_TEST2_DESC,
+	              SPLAT_KOBJ_TEST2_ID, splat_kobj_test2);
+
+        return sub;
+} /* splat_kobj_init() */
+
+void
+splat_kobj_fini(splat_subsystem_t *sub)
+{
+        ASSERT(sub);
+
+        SPLAT_TEST_FINI(sub, SPLAT_KOBJ_TEST2_ID);
+        SPLAT_TEST_FINI(sub, SPLAT_KOBJ_TEST1_ID);
+
+        kfree(sub);
+} /* splat_kobj_fini() */
+
+int
+splat_kobj_id(void)
+{
+        return SPLAT_SUBSYSTEM_KOBJ;
+} /* splat_kobj_id() */
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/module/splat/splat-linux.c
@@ -0,0 +1,237 @@
+/*****************************************************************************\
+ *  Copyright (C) 2011 Lawrence Livermore National Security, LLC.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+ *****************************************************************************
+ *  Solaris Porting LAyer Tests (SPLAT) Kernel Compatibility Tests.
+\*****************************************************************************/
+
+#include <sys/kmem.h>
+#include <linux/mm_compat.h>
+#include "splat-internal.h"
+
+#define SPLAT_LINUX_NAME		"linux"
+#define SPLAT_LINUX_DESC		"Kernel Compatibility Tests"
+
+#define SPLAT_LINUX_TEST1_ID		0x1001
+#define SPLAT_LINUX_TEST1_NAME		"shrinker"
+#define SPLAT_LINUX_TEST1_DESC		"Shrinker test"
+
+/*
+ * Wait queue used to eliminate race between dropping of slab
+ * and execution of the shrinker callback
+ */
+DECLARE_WAIT_QUEUE_HEAD(shrinker_wait);
+
+SPL_SHRINKER_CALLBACK_FWD_DECLARE(splat_linux_shrinker_fn);
+SPL_SHRINKER_DECLARE(splat_linux_shrinker, splat_linux_shrinker_fn, 1);
+static unsigned long splat_linux_shrinker_size = 0;
+static struct file *splat_linux_shrinker_file = NULL;
+
+static spl_shrinker_t
+__splat_linux_shrinker_fn(struct shrinker *shrink, struct shrink_control *sc)
+{
+	static int failsafe = 0;
+	static unsigned long last_splat_linux_shrinker_size = 0;
+	unsigned long size;
+	spl_shrinker_t count;
+
+	/*
+	 * shrinker_size can only decrease or stay the same between callbacks
+	 * in the same run, so Reset failsafe whenever shrinker increases
+	 * as this indicates a new run.
+	 */
+	if (last_splat_linux_shrinker_size < splat_linux_shrinker_size)
+		failsafe = 0;
+
+	last_splat_linux_shrinker_size = splat_linux_shrinker_size;
+
+	if (sc->nr_to_scan) {
+		size = MIN(sc->nr_to_scan, splat_linux_shrinker_size);
+		splat_linux_shrinker_size -= size;
+
+		splat_vprint(splat_linux_shrinker_file, SPLAT_LINUX_TEST1_NAME,
+		    "Reclaimed %lu objects, size now %lu\n",
+		    size, splat_linux_shrinker_size);
+
+#ifdef HAVE_SPLIT_SHRINKER_CALLBACK
+		count = size;
+#else
+		count = splat_linux_shrinker_size;
+#endif /* HAVE_SPLIT_SHRINKER_CALLBACK */
+
+	} else {
+		count = splat_linux_shrinker_size;
+		splat_vprint(splat_linux_shrinker_file, SPLAT_LINUX_TEST1_NAME,
+		    "Cache size is %lu\n", splat_linux_shrinker_size);
+	}
+
+	/* Far more calls than expected abort drop_slab as a failsafe */
+	if (failsafe > 100) {
+		splat_vprint(splat_linux_shrinker_file, SPLAT_LINUX_TEST1_NAME,
+		    "Far more calls than expected (%d), size now %lu\n",
+		   failsafe, splat_linux_shrinker_size);
+		return (SHRINK_STOP);
+	} else {
+		/*
+		 * We only increment failsafe if it doesn't trigger.  This
+		 * makes any failsafe failure persistent until the next test.
+		 */
+		failsafe++;
+	}
+
+	/* Shrinker has run, so signal back to test. */
+	wake_up(&shrinker_wait);
+
+	return (count);
+}
+
+SPL_SHRINKER_CALLBACK_WRAPPER(splat_linux_shrinker_fn);
+
+#define DROP_SLAB_CMD \
+	"exec 0</dev/null " \
+	"     1>/proc/sys/vm/drop_caches " \
+	"     2>/dev/null; " \
+	"echo 2"
+
+static int
+splat_linux_drop_slab(struct file *file)
+{
+	char *argv[] = { "/bin/sh",
+	                 "-c",
+	                 DROP_SLAB_CMD,
+	                 NULL };
+	char *envp[] = { "HOME=/",
+	                 "TERM=linux",
+	                 "PATH=/sbin:/usr/sbin:/bin:/usr/bin",
+	                 NULL };
+	int rc;
+
+	rc = call_usermodehelper(argv[0], argv, envp, UMH_WAIT_PROC);
+	if (rc)
+		splat_vprint(file, SPLAT_LINUX_TEST1_NAME,
+	            "Failed user helper '%s %s %s', rc = %d\n",
+		    argv[0], argv[1], argv[2], rc);
+
+	return rc;
+}
+
+/*
+ * Verify correct shrinker functionality by registering a shrinker
+ * with the required compatibility macros.  We then use a simulated
+ * cache and force the systems caches to be dropped.  The shrinker
+ * should be repeatedly called until it reports that the cache is
+ * empty.  It is then cleanly unregistered and correct behavior is
+ * verified.  There are now four slightly different supported shrinker
+ * API and this test ensures the compatibility code is correct.
+ */
+static int
+splat_linux_test1(struct file *file, void *arg)
+{
+	int rc = -EINVAL;
+
+	/*
+	 * Globals used by the shrinker, it is not safe to run this
+	 * test concurrently this is a safe assumption for SPLAT tests.
+	 * Regardless we do some minimal checking a bail if concurrent
+	 * use is detected.
+	 */
+	if (splat_linux_shrinker_size || splat_linux_shrinker_file) {
+		splat_vprint(file, SPLAT_LINUX_TEST1_NAME,
+		    "Failed due to concurrent shrinker test, rc = %d\n", rc);
+		return (rc);
+	}
+
+	splat_linux_shrinker_size = 1024;
+	splat_linux_shrinker_file = file;
+
+	spl_register_shrinker(&splat_linux_shrinker);
+	rc = splat_linux_drop_slab(file);
+	if (rc)
+		goto out;
+
+	/*
+	 * By the time we get here, it is possible that the shrinker has not
+	 * yet run. splat_linux_drop_slab sends a signal for it to run, but
+	 * there is no guarantee of when it will actually run. We wait for it
+	 * to run here, terminating when either the shrinker size is now 0 or
+	 * we timeout after 1 second, which should be an eternity (error).
+	 */
+	rc = wait_event_timeout(shrinker_wait, !splat_linux_shrinker_size, HZ);
+	if (!rc) {
+		splat_vprint(file, SPLAT_LINUX_TEST1_NAME,
+		    "Failed cache shrinking timed out, size now %lu",
+		    splat_linux_shrinker_size);
+		rc = -ETIMEDOUT;
+	} else {
+		rc = 0;
+	}
+
+	if (!rc && splat_linux_shrinker_size != 0) {
+		splat_vprint(file, SPLAT_LINUX_TEST1_NAME,
+		    "Failed cache was not shrunk to 0, size now %lu",
+		    splat_linux_shrinker_size);
+		rc = -EDOM;
+	}
+out:
+	spl_unregister_shrinker(&splat_linux_shrinker);
+
+	splat_linux_shrinker_size = 0;
+	splat_linux_shrinker_file = NULL;
+
+	return rc;
+}
+
+splat_subsystem_t *
+splat_linux_init(void)
+{
+	splat_subsystem_t *sub;
+
+	sub = kmalloc(sizeof(*sub), GFP_KERNEL);
+	if (sub == NULL)
+		return NULL;
+
+	memset(sub, 0, sizeof(*sub));
+	strncpy(sub->desc.name, SPLAT_LINUX_NAME, SPLAT_NAME_SIZE);
+	strncpy(sub->desc.desc, SPLAT_LINUX_DESC, SPLAT_DESC_SIZE);
+	INIT_LIST_HEAD(&sub->subsystem_list);
+	INIT_LIST_HEAD(&sub->test_list);
+	spin_lock_init(&sub->test_lock);
+	sub->desc.id = SPLAT_SUBSYSTEM_LINUX;
+
+	SPLAT_TEST_INIT(sub, SPLAT_LINUX_TEST1_NAME, SPLAT_LINUX_TEST1_DESC,
+			SPLAT_LINUX_TEST1_ID, splat_linux_test1);
+
+	return sub;
+}
+
+void
+splat_linux_fini(splat_subsystem_t *sub)
+{
+	ASSERT(sub);
+	SPLAT_TEST_FINI(sub, SPLAT_LINUX_TEST1_ID);
+
+	kfree(sub);
+}
+
+int
+splat_linux_id(void) {
+	return SPLAT_SUBSYSTEM_LINUX;
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/module/splat/splat-list.c
@@ -0,0 +1,475 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+ *****************************************************************************
+ *  Solaris Porting LAyer Tests (SPLAT) List Tests.
+\*****************************************************************************/
+
+#include <sys/list.h>
+#include <sys/kmem.h>
+#include "splat-internal.h"
+
+#define SPLAT_LIST_NAME			"list"
+#define SPLAT_LIST_DESC			"Kernel List Tests"
+
+#define SPLAT_LIST_TEST1_ID		0x0c01
+#define SPLAT_LIST_TEST1_NAME		"create/destroy"
+#define SPLAT_LIST_TEST1_DESC		"Create/destroy Test"
+
+#define SPLAT_LIST_TEST2_ID		0x0c02
+#define SPLAT_LIST_TEST2_NAME		"ins/rm head"
+#define SPLAT_LIST_TEST2_DESC		"Insert/remove head Test"
+
+#define SPLAT_LIST_TEST3_ID		0x0c03
+#define SPLAT_LIST_TEST3_NAME		"ins/rm tail"
+#define SPLAT_LIST_TEST3_DESC		"Insert/remove tail Test"
+
+#define SPLAT_LIST_TEST4_ID		0x0c04
+#define SPLAT_LIST_TEST4_NAME		"insert_after"
+#define SPLAT_LIST_TEST4_DESC		"Insert_after Test"
+
+#define SPLAT_LIST_TEST5_ID		0x0c05
+#define SPLAT_LIST_TEST5_NAME		"insert_before"
+#define SPLAT_LIST_TEST5_DESC		"Insert_before Test"
+
+#define SPLAT_LIST_TEST6_ID		0x0c06
+#define SPLAT_LIST_TEST6_NAME		"remove"
+#define SPLAT_LIST_TEST6_DESC		"Remove Test"
+
+#define SPLAT_LIST_TEST7_ID		0x0c7
+#define SPLAT_LIST_TEST7_NAME		"active"
+#define SPLAT_LIST_TEST7_DESC		"Active Test"
+
+/* It is important that li_node is not the first element, this
+ * ensures the list_d2l/list_object macros are working correctly. */
+typedef struct list_item {
+	int li_data;
+	list_node_t li_node;
+} list_item_t;
+
+#define LIST_ORDER_STACK		0
+#define LIST_ORDER_QUEUE		1
+
+static int
+splat_list_test1(struct file *file, void *arg)
+{
+	list_t list;
+
+	splat_vprint(file, SPLAT_LIST_TEST1_NAME, "Creating list\n%s", "");
+	list_create(&list, sizeof(list_item_t), offsetof(list_item_t, li_node));
+
+	if (!list_is_empty(&list)) {
+		splat_vprint(file, SPLAT_LIST_TEST1_NAME,
+			     "New list NOT empty%s\n", "");
+		/* list_destroy() intentionally skipped to avoid assert */
+		return -EEXIST;
+	}
+
+	splat_vprint(file, SPLAT_LIST_TEST1_NAME, "Destroying list\n%s", "");
+	list_destroy(&list);
+
+	/* Validate the list has been destroyed */
+	if (list_link_active(&list.list_head)) {
+		splat_vprint(file, SPLAT_LIST_TEST1_NAME,
+			     "Destroyed list still active%s", "");
+		return -EIO;
+	}
+
+        return 0;
+}
+
+static int
+splat_list_validate(list_t *list, int size, int order, int mult)
+{
+	list_item_t *li;
+	int i;
+
+	/* Walk all items in list from head to verify stack or queue
+	 * ordering.  We bound the for loop by size+1 to ensure that
+	 * we still terminate if there is list corruption.  We also
+	 * intentionally make things a little more complex than they
+	 * need to be by using list_head/list_next for queues, and
+	 * list_tail/list_prev for stacks.  This is simply done for
+	 * coverage and to ensure these function are working right.
+	 */
+	for (i = 0, li = (order ? list_head(list) : list_tail(list));
+	     i < size + 1 && li != NULL;
+	     i++, li = (order ? list_next(list, li) : list_prev(list, li)))
+		if (li->li_data != i * mult)
+			return -EIDRM;
+
+	if (i != size)
+		return -E2BIG;
+
+	return 0;
+}
+
+static int
+splat_list_test2(struct file *file, void *arg)
+{
+	list_t list;
+	list_item_t *li;
+	int i, list_size = 8, rc = 0;
+
+	splat_vprint(file, SPLAT_LIST_TEST2_NAME, "Creating list\n%s", "");
+	list_create(&list, sizeof(list_item_t), offsetof(list_item_t, li_node));
+
+	/* Insert all items at the list head to form a stack */
+	splat_vprint(file, SPLAT_LIST_TEST2_NAME,
+		     "Adding %d items to list head\n", list_size);
+	for (i = 0; i < list_size; i++) {
+		li = kmem_alloc(sizeof(list_item_t), KM_SLEEP);
+		if (li == NULL) {
+			rc = -ENOMEM;
+			goto out;
+		}
+
+		list_link_init(&li->li_node);
+		li->li_data = i;
+		list_insert_head(&list, li);
+	}
+
+	splat_vprint(file, SPLAT_LIST_TEST2_NAME,
+		     "Validating %d item list is a stack\n", list_size);
+	rc = splat_list_validate(&list, list_size, LIST_ORDER_STACK, 1);
+	if (rc)
+		splat_vprint(file, SPLAT_LIST_TEST2_NAME,
+			     "List validation failed, %d\n", rc);
+out:
+	/* Remove all items */
+	splat_vprint(file, SPLAT_LIST_TEST2_NAME,
+		     "Removing %d items from list head\n", list_size);
+	while ((li = list_remove_head(&list)))
+		kmem_free(li, sizeof(list_item_t));
+
+	splat_vprint(file, SPLAT_LIST_TEST2_NAME, "Destroying list\n%s", "");
+	list_destroy(&list);
+
+        return rc;
+}
+
+static int
+splat_list_test3(struct file *file, void *arg)
+{
+	list_t list;
+	list_item_t *li;
+	int i, list_size = 8, rc = 0;
+
+	splat_vprint(file, SPLAT_LIST_TEST3_NAME, "Creating list\n%s", "");
+	list_create(&list, sizeof(list_item_t), offsetof(list_item_t, li_node));
+
+	/* Insert all items at the list tail to form a queue */
+	splat_vprint(file, SPLAT_LIST_TEST3_NAME,
+		     "Adding %d items to list tail\n", list_size);
+	for (i = 0; i < list_size; i++) {
+		li = kmem_alloc(sizeof(list_item_t), KM_SLEEP);
+		if (li == NULL) {
+			rc = -ENOMEM;
+			goto out;
+		}
+
+		list_link_init(&li->li_node);
+		li->li_data = i;
+		list_insert_tail(&list, li);
+	}
+
+	splat_vprint(file, SPLAT_LIST_TEST3_NAME,
+		     "Validating %d item list is a queue\n", list_size);
+	rc = splat_list_validate(&list, list_size, LIST_ORDER_QUEUE, 1);
+	if (rc)
+		splat_vprint(file, SPLAT_LIST_TEST3_NAME,
+			     "List validation failed, %d\n", rc);
+out:
+	/* Remove all items */
+	splat_vprint(file, SPLAT_LIST_TEST3_NAME,
+		     "Removing %d items from list tail\n", list_size);
+	while ((li = list_remove_tail(&list)))
+		kmem_free(li, sizeof(list_item_t));
+
+	splat_vprint(file, SPLAT_LIST_TEST3_NAME, "Destroying list\n%s", "");
+	list_destroy(&list);
+
+        return rc;
+}
+
+static int
+splat_list_test4(struct file *file, void *arg)
+{
+	list_t list;
+	list_item_t *li_new, *li_last = NULL;
+	int i, list_size = 8, rc = 0;
+
+	splat_vprint(file, SPLAT_LIST_TEST4_NAME, "Creating list\n%s", "");
+	list_create(&list, sizeof(list_item_t), offsetof(list_item_t, li_node));
+
+	/* Insert all items after the last item to form a queue */
+	splat_vprint(file, SPLAT_LIST_TEST4_NAME,
+		     "Adding %d items each after the last item\n", list_size);
+	for (i = 0; i < list_size; i++) {
+		li_new = kmem_alloc(sizeof(list_item_t), KM_SLEEP);
+		if (li_new == NULL) {
+			rc = -ENOMEM;
+			goto out;
+		}
+
+		list_link_init(&li_new->li_node);
+		li_new->li_data = i;
+		list_insert_after(&list, li_last, li_new);
+		li_last = li_new;
+	}
+
+	splat_vprint(file, SPLAT_LIST_TEST4_NAME,
+		     "Validating %d item list is a queue\n", list_size);
+	rc = splat_list_validate(&list, list_size, LIST_ORDER_QUEUE, 1);
+	if (rc)
+		splat_vprint(file, SPLAT_LIST_TEST4_NAME,
+			     "List validation failed, %d\n", rc);
+out:
+	/* Remove all items */
+	splat_vprint(file, SPLAT_LIST_TEST4_NAME,
+		     "Removing %d items from list tail\n", list_size);
+	while ((li_new = list_remove_head(&list)))
+		kmem_free(li_new, sizeof(list_item_t));
+
+	splat_vprint(file, SPLAT_LIST_TEST4_NAME, "Destroying list\n%s", "");
+	list_destroy(&list);
+
+        return rc;
+}
+
+static int
+splat_list_test5(struct file *file, void *arg)
+{
+	list_t list;
+	list_item_t *li_new, *li_last = NULL;
+	int i, list_size = 8, rc = 0;
+
+	splat_vprint(file, SPLAT_LIST_TEST5_NAME, "Creating list\n%s", "");
+	list_create(&list, sizeof(list_item_t), offsetof(list_item_t, li_node));
+
+	/* Insert all items before the last item to form a stack */
+	splat_vprint(file, SPLAT_LIST_TEST5_NAME,
+		     "Adding %d items each before the last item\n", list_size);
+	for (i = 0; i < list_size; i++) {
+		li_new = kmem_alloc(sizeof(list_item_t), KM_SLEEP);
+		if (li_new == NULL) {
+			rc = -ENOMEM;
+			goto out;
+		}
+
+		list_link_init(&li_new->li_node);
+		li_new->li_data = i;
+		list_insert_before(&list, li_last, li_new);
+		li_last = li_new;
+	}
+
+	splat_vprint(file, SPLAT_LIST_TEST5_NAME,
+		     "Validating %d item list is a queue\n", list_size);
+	rc = splat_list_validate(&list, list_size, LIST_ORDER_STACK, 1);
+	if (rc)
+		splat_vprint(file, SPLAT_LIST_TEST5_NAME,
+			     "List validation failed, %d\n", rc);
+out:
+	/* Remove all items */
+	splat_vprint(file, SPLAT_LIST_TEST5_NAME,
+		     "Removing %d items from list tail\n", list_size);
+	while ((li_new = list_remove_tail(&list)))
+		kmem_free(li_new, sizeof(list_item_t));
+
+	splat_vprint(file, SPLAT_LIST_TEST5_NAME, "Destroying list\n%s", "");
+	list_destroy(&list);
+
+        return rc;
+}
+
+static int
+splat_list_test6(struct file *file, void *arg)
+{
+	list_t list;
+	list_item_t *li, *li_prev;
+	int i, list_size = 8, rc = 0;
+
+	splat_vprint(file, SPLAT_LIST_TEST6_NAME, "Creating list\n%s", "");
+	list_create(&list, sizeof(list_item_t), offsetof(list_item_t, li_node));
+
+	/* Insert all items at the list tail to form a queue */
+	splat_vprint(file, SPLAT_LIST_TEST6_NAME,
+		     "Adding %d items to list tail\n", list_size);
+	for (i = 0; i < list_size; i++) {
+		li = kmem_alloc(sizeof(list_item_t), KM_SLEEP);
+		if (li == NULL) {
+			rc = -ENOMEM;
+			goto out;
+		}
+
+		list_link_init(&li->li_node);
+		li->li_data = i;
+		list_insert_tail(&list, li);
+	}
+
+	/* Remove all odd items from the queue */
+	splat_vprint(file, SPLAT_LIST_TEST6_NAME,
+		     "Removing %d odd items from the list\n", list_size >> 1);
+	for (li = list_head(&list); li != NULL; li = list_next(&list, li)) {
+		if (li->li_data % 2 == 1) {
+			li_prev = list_prev(&list, li);
+			list_remove(&list, li);
+			kmem_free(li, sizeof(list_item_t));
+			li = li_prev;
+		}
+	}
+
+	splat_vprint(file, SPLAT_LIST_TEST6_NAME, "Validating %d item "
+		     "list is a queue of only even elements\n", list_size / 2);
+	rc = splat_list_validate(&list, list_size / 2, LIST_ORDER_QUEUE, 2);
+	if (rc)
+		splat_vprint(file, SPLAT_LIST_TEST6_NAME,
+			     "List validation failed, %d\n", rc);
+out:
+	/* Remove all items */
+	splat_vprint(file, SPLAT_LIST_TEST6_NAME,
+		     "Removing %d items from list tail\n", list_size / 2);
+	while ((li = list_remove_tail(&list)))
+		kmem_free(li, sizeof(list_item_t));
+
+	splat_vprint(file, SPLAT_LIST_TEST6_NAME, "Destroying list\n%s", "");
+	list_destroy(&list);
+
+        return rc;
+}
+
+static int
+splat_list_test7(struct file *file, void *arg)
+{
+	list_t list;
+	list_item_t *li;
+	int rc = 0;
+
+	splat_vprint(file, SPLAT_LIST_TEST7_NAME, "Creating list\n%s", "");
+	list_create(&list, sizeof(list_item_t), offsetof(list_item_t, li_node));
+
+	li = kmem_alloc(sizeof(list_item_t), KM_SLEEP);
+	if (li == NULL) {
+		rc = -ENOMEM;
+		goto out;
+	}
+
+	/* Validate newly initialized node is inactive */
+	splat_vprint(file, SPLAT_LIST_TEST7_NAME, "Init list node\n%s", "");
+	list_link_init(&li->li_node);
+	if (list_link_active(&li->li_node)) {
+		splat_vprint(file, SPLAT_LIST_TEST7_NAME, "Newly initialized "
+			    "list node should inactive %p/%p\n",
+			    li->li_node.prev, li->li_node.next);
+		rc = -EINVAL;
+		goto out_li;
+	}
+
+	/* Validate node is active when linked in to a list */
+	splat_vprint(file, SPLAT_LIST_TEST7_NAME, "Insert list node\n%s", "");
+	list_insert_head(&list, li);
+	if (!list_link_active(&li->li_node)) {
+		splat_vprint(file, SPLAT_LIST_TEST7_NAME, "List node "
+			    "inserted in list should be active %p/%p\n",
+			    li->li_node.prev, li->li_node.next);
+		rc = -EINVAL;
+		goto out;
+	}
+
+	/* Validate node is inactive when removed from list */
+	splat_vprint(file, SPLAT_LIST_TEST7_NAME, "Remove list node\n%s", "");
+	list_remove(&list, li);
+	if (list_link_active(&li->li_node)) {
+		splat_vprint(file, SPLAT_LIST_TEST7_NAME, "List node "
+			    "removed from list should be inactive %p/%p\n",
+			    li->li_node.prev, li->li_node.next);
+		rc = -EINVAL;
+	}
+out_li:
+	kmem_free(li, sizeof(list_item_t));
+out:
+	/* Remove all items */
+	while ((li = list_remove_head(&list)))
+		kmem_free(li, sizeof(list_item_t));
+
+	splat_vprint(file, SPLAT_LIST_TEST7_NAME, "Destroying list\n%s", "");
+	list_destroy(&list);
+
+        return rc;
+}
+
+splat_subsystem_t *
+splat_list_init(void)
+{
+        splat_subsystem_t *sub;
+
+        sub = kmalloc(sizeof(*sub), GFP_KERNEL);
+        if (sub == NULL)
+                return NULL;
+
+        memset(sub, 0, sizeof(*sub));
+        strncpy(sub->desc.name, SPLAT_LIST_NAME, SPLAT_NAME_SIZE);
+	strncpy(sub->desc.desc, SPLAT_LIST_DESC, SPLAT_DESC_SIZE);
+        INIT_LIST_HEAD(&sub->subsystem_list);
+	INIT_LIST_HEAD(&sub->test_list);
+        spin_lock_init(&sub->test_lock);
+        sub->desc.id = SPLAT_SUBSYSTEM_LIST;
+
+        SPLAT_TEST_INIT(sub, SPLAT_LIST_TEST1_NAME, SPLAT_LIST_TEST1_DESC,
+	                SPLAT_LIST_TEST1_ID, splat_list_test1);
+        SPLAT_TEST_INIT(sub, SPLAT_LIST_TEST2_NAME, SPLAT_LIST_TEST2_DESC,
+	                SPLAT_LIST_TEST2_ID, splat_list_test2);
+        SPLAT_TEST_INIT(sub, SPLAT_LIST_TEST3_NAME, SPLAT_LIST_TEST3_DESC,
+	                SPLAT_LIST_TEST3_ID, splat_list_test3);
+        SPLAT_TEST_INIT(sub, SPLAT_LIST_TEST4_NAME, SPLAT_LIST_TEST4_DESC,
+	                SPLAT_LIST_TEST4_ID, splat_list_test4);
+        SPLAT_TEST_INIT(sub, SPLAT_LIST_TEST5_NAME, SPLAT_LIST_TEST5_DESC,
+	                SPLAT_LIST_TEST5_ID, splat_list_test5);
+        SPLAT_TEST_INIT(sub, SPLAT_LIST_TEST6_NAME, SPLAT_LIST_TEST6_DESC,
+	                SPLAT_LIST_TEST6_ID, splat_list_test6);
+        SPLAT_TEST_INIT(sub, SPLAT_LIST_TEST7_NAME, SPLAT_LIST_TEST7_DESC,
+	                SPLAT_LIST_TEST7_ID, splat_list_test7);
+
+        return sub;
+}
+
+void
+splat_list_fini(splat_subsystem_t *sub)
+{
+        ASSERT(sub);
+
+        SPLAT_TEST_FINI(sub, SPLAT_LIST_TEST7_ID);
+        SPLAT_TEST_FINI(sub, SPLAT_LIST_TEST6_ID);
+        SPLAT_TEST_FINI(sub, SPLAT_LIST_TEST5_ID);
+        SPLAT_TEST_FINI(sub, SPLAT_LIST_TEST4_ID);
+        SPLAT_TEST_FINI(sub, SPLAT_LIST_TEST3_ID);
+        SPLAT_TEST_FINI(sub, SPLAT_LIST_TEST2_ID);
+        SPLAT_TEST_FINI(sub, SPLAT_LIST_TEST1_ID);
+
+        kfree(sub);
+}
+
+int
+splat_list_id(void)
+{
+        return SPLAT_SUBSYSTEM_LIST;
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/module/splat/splat-mutex.c
@@ -0,0 +1,441 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+ *****************************************************************************
+ *  Solaris Porting LAyer Tests (SPLAT) Mutex Tests.
+\*****************************************************************************/
+
+#include <sys/mutex.h>
+#include <sys/taskq.h>
+#include <linux/delay.h>
+#include <linux/mm_compat.h>
+#include "splat-internal.h"
+
+#define SPLAT_MUTEX_NAME                "mutex"
+#define SPLAT_MUTEX_DESC                "Kernel Mutex Tests"
+
+#define SPLAT_MUTEX_TEST1_ID            0x0401
+#define SPLAT_MUTEX_TEST1_NAME          "tryenter"
+#define SPLAT_MUTEX_TEST1_DESC          "Validate mutex_tryenter() correctness"
+
+#define SPLAT_MUTEX_TEST2_ID            0x0402
+#define SPLAT_MUTEX_TEST2_NAME          "race"
+#define SPLAT_MUTEX_TEST2_DESC          "Many threads entering/exiting the mutex"
+
+#define SPLAT_MUTEX_TEST3_ID            0x0403
+#define SPLAT_MUTEX_TEST3_NAME          "owned"
+#define SPLAT_MUTEX_TEST3_DESC          "Validate mutex_owned() correctness"
+
+#define SPLAT_MUTEX_TEST4_ID            0x0404
+#define SPLAT_MUTEX_TEST4_NAME          "owner"
+#define SPLAT_MUTEX_TEST4_DESC          "Validate mutex_owner() correctness"
+
+#define SPLAT_MUTEX_TEST_MAGIC          0x115599DDUL
+#define SPLAT_MUTEX_TEST_NAME           "mutex_test"
+#define SPLAT_MUTEX_TEST_TASKQ          "mutex_taskq"
+#define SPLAT_MUTEX_TEST_COUNT          128
+
+typedef struct mutex_priv {
+        unsigned long mp_magic;
+        struct file *mp_file;
+        kmutex_t mp_mtx;
+        int mp_rc;
+        int mp_rc2;
+} mutex_priv_t;
+
+static void
+splat_mutex_test1_func(void *arg)
+{
+        mutex_priv_t *mp = (mutex_priv_t *)arg;
+        ASSERT(mp->mp_magic == SPLAT_MUTEX_TEST_MAGIC);
+
+        if (mutex_tryenter(&mp->mp_mtx)) {
+                mp->mp_rc = 0;
+                mutex_exit(&mp->mp_mtx);
+        } else {
+                mp->mp_rc = -EBUSY;
+        }
+}
+
+static int
+splat_mutex_test1(struct file *file, void *arg)
+{
+        mutex_priv_t *mp;
+        taskq_t *tq;
+        int id, rc = 0;
+
+        mp = (mutex_priv_t *)kmalloc(sizeof(*mp), GFP_KERNEL);
+        if (mp == NULL)
+                return -ENOMEM;
+
+        tq = taskq_create(SPLAT_MUTEX_TEST_TASKQ, 1, defclsyspri,
+                          50, INT_MAX, TASKQ_PREPOPULATE);
+        if (tq == NULL) {
+                rc = -ENOMEM;
+                goto out2;
+        }
+
+        mp->mp_magic = SPLAT_MUTEX_TEST_MAGIC;
+        mp->mp_file = file;
+        mutex_init(&mp->mp_mtx, SPLAT_MUTEX_TEST_NAME, MUTEX_DEFAULT, NULL);
+        mutex_enter(&mp->mp_mtx);
+
+        /*
+         * Schedule a task function which will try and acquire the mutex via
+         * mutex_tryenter() while it's held.  This should fail and the task
+         * function will indicate this status in the passed private data.
+         */
+        mp->mp_rc = -EINVAL;
+        id = taskq_dispatch(tq, splat_mutex_test1_func, mp, TQ_SLEEP);
+        if (id == 0) {
+                mutex_exit(&mp->mp_mtx);
+                splat_vprint(file, SPLAT_MUTEX_TEST1_NAME, "%s",
+                             "taskq_dispatch() failed\n");
+                rc = -EINVAL;
+                goto out;
+        }
+
+        taskq_wait_id(tq, id);
+        mutex_exit(&mp->mp_mtx);
+
+        /* Task function successfully acquired mutex, very bad! */
+        if (mp->mp_rc != -EBUSY) {
+                splat_vprint(file, SPLAT_MUTEX_TEST1_NAME,
+                             "mutex_trylock() incorrectly succeeded when "
+                             "the mutex was held, %d/%d\n", id, mp->mp_rc);
+                rc = -EINVAL;
+                goto out;
+        } else {
+                splat_vprint(file, SPLAT_MUTEX_TEST1_NAME, "%s",
+                             "mutex_trylock() correctly failed when "
+                             "the mutex was held\n");
+        }
+
+        /*
+         * Schedule a task function which will try and acquire the mutex via
+         * mutex_tryenter() while it is not held.  This should succeed and
+         * can be verified by checking the private data.
+         */
+        mp->mp_rc = -EINVAL;
+        id = taskq_dispatch(tq, splat_mutex_test1_func, mp, TQ_SLEEP);
+        if (id == 0) {
+                splat_vprint(file, SPLAT_MUTEX_TEST1_NAME, "%s",
+                             "taskq_dispatch() failed\n");
+                rc = -EINVAL;
+                goto out;
+        }
+
+        taskq_wait_id(tq, id);
+
+        /* Task function failed to acquire mutex, very bad! */
+        if (mp->mp_rc != 0) {
+                splat_vprint(file, SPLAT_MUTEX_TEST1_NAME,
+                             "mutex_trylock() incorrectly failed when "
+                             "the mutex was not held, %d/%d\n", id, mp->mp_rc);
+                rc = -EINVAL;
+        } else {
+                splat_vprint(file, SPLAT_MUTEX_TEST1_NAME, "%s",
+                             "mutex_trylock() correctly succeeded "
+                             "when the mutex was not held\n");
+        }
+out:
+        taskq_destroy(tq);
+        mutex_destroy(&(mp->mp_mtx));
+out2:
+        kfree(mp);
+        return rc;
+}
+
+static void
+splat_mutex_test2_func(void *arg)
+{
+        mutex_priv_t *mp = (mutex_priv_t *)arg;
+        int rc;
+        ASSERT(mp->mp_magic == SPLAT_MUTEX_TEST_MAGIC);
+
+        /* Read the value before sleeping and write it after we wake up to
+         * maximize the chance of a race if mutexs are not working properly */
+        mutex_enter(&mp->mp_mtx);
+        rc = mp->mp_rc;
+        set_current_state(TASK_INTERRUPTIBLE);
+        schedule_timeout(HZ / 100);  /* 1/100 of a second */
+        VERIFY(mp->mp_rc == rc);
+        mp->mp_rc = rc + 1;
+        mutex_exit(&mp->mp_mtx);
+}
+
+static int
+splat_mutex_test2(struct file *file, void *arg)
+{
+        mutex_priv_t *mp;
+        taskq_t *tq;
+        int i, rc = 0;
+
+        mp = (mutex_priv_t *)kmalloc(sizeof(*mp), GFP_KERNEL);
+        if (mp == NULL)
+                return -ENOMEM;
+
+        /* Create several threads allowing tasks to race with each other */
+        tq = taskq_create(SPLAT_MUTEX_TEST_TASKQ, num_online_cpus(),
+                          defclsyspri, 50, INT_MAX, TASKQ_PREPOPULATE);
+        if (tq == NULL) {
+                rc = -ENOMEM;
+                goto out;
+        }
+
+        mp->mp_magic = SPLAT_MUTEX_TEST_MAGIC;
+        mp->mp_file = file;
+        mutex_init(&(mp->mp_mtx), SPLAT_MUTEX_TEST_NAME, MUTEX_DEFAULT, NULL);
+        mp->mp_rc = 0;
+
+        /*
+         * Schedule N work items to the work queue each of which enters the
+         * mutex, sleeps briefly, then exits the mutex.  On a multiprocessor
+         * box these work items will be handled by all available CPUs.  The
+         * task function checks to ensure the tracked shared variable is
+         * always only incremented by one.  Additionally, the mutex itself
+         * is instrumented such that if any two processors are in the
+         * critical region at the same time the system will panic.  If the
+         * mutex is implemented right this will never happy, that's a pass.
+         */
+        for (i = 0; i < SPLAT_MUTEX_TEST_COUNT; i++) {
+                if (!taskq_dispatch(tq, splat_mutex_test2_func, mp, TQ_SLEEP)) {
+                        splat_vprint(file, SPLAT_MUTEX_TEST2_NAME,
+                                     "Failed to queue task %d\n", i);
+                        rc = -EINVAL;
+                }
+        }
+
+        taskq_wait(tq);
+
+        if (mp->mp_rc == SPLAT_MUTEX_TEST_COUNT) {
+                splat_vprint(file, SPLAT_MUTEX_TEST2_NAME, "%d racing threads "
+                           "correctly entered/exited the mutex %d times\n",
+                           num_online_cpus(), mp->mp_rc);
+        } else {
+                splat_vprint(file, SPLAT_MUTEX_TEST2_NAME, "%d racing threads "
+                           "only processed %d/%d mutex work items\n",
+                           num_online_cpus(),mp->mp_rc,SPLAT_MUTEX_TEST_COUNT);
+                rc = -EINVAL;
+        }
+
+        taskq_destroy(tq);
+        mutex_destroy(&(mp->mp_mtx));
+out:
+        kfree(mp);
+        return rc;
+}
+
+static void
+splat_mutex_owned(void *priv)
+{
+        mutex_priv_t *mp = (mutex_priv_t *)priv;
+
+        ASSERT(mp->mp_magic == SPLAT_MUTEX_TEST_MAGIC);
+        mp->mp_rc = mutex_owned(&mp->mp_mtx);
+        mp->mp_rc2 = MUTEX_HELD(&mp->mp_mtx);
+}
+
+static int
+splat_mutex_test3(struct file *file, void *arg)
+{
+        mutex_priv_t mp;
+        taskq_t *tq;
+        int rc = 0;
+
+        mp.mp_magic = SPLAT_MUTEX_TEST_MAGIC;
+        mp.mp_file = file;
+        mutex_init(&mp.mp_mtx, SPLAT_MUTEX_TEST_NAME, MUTEX_DEFAULT, NULL);
+
+        if ((tq = taskq_create(SPLAT_MUTEX_TEST_NAME, 1, defclsyspri,
+                               50, INT_MAX, TASKQ_PREPOPULATE)) == NULL) {
+                splat_vprint(file, SPLAT_MUTEX_TEST3_NAME, "Taskq '%s' "
+                             "create failed\n", SPLAT_MUTEX_TEST3_NAME);
+                return -EINVAL;
+        }
+
+        mutex_enter(&mp.mp_mtx);
+
+        /* Mutex should be owned by current */
+        if (!mutex_owned(&mp.mp_mtx)) {
+                splat_vprint(file, SPLAT_MUTEX_TEST3_NAME, "Unowned mutex "
+                             "should be owned by pid %d\n", current->pid);
+                rc = -EINVAL;
+                goto out_exit;
+        }
+
+        if (taskq_dispatch(tq, splat_mutex_owned, &mp, TQ_SLEEP) == 0) {
+                splat_vprint(file, SPLAT_MUTEX_TEST3_NAME, "Failed to "
+                             "dispatch function '%s' to taskq\n",
+                             sym2str(splat_mutex_owned));
+                rc = -EINVAL;
+                goto out_exit;
+        }
+        taskq_wait(tq);
+
+        /* Mutex should not be owned which checked from a different thread */
+        if (mp.mp_rc || mp.mp_rc2) {
+                splat_vprint(file, SPLAT_MUTEX_TEST3_NAME, "Mutex owned by "
+                             "pid %d not by taskq\n", current->pid);
+                rc = -EINVAL;
+                goto out_exit;
+        }
+
+        mutex_exit(&mp.mp_mtx);
+
+        /* Mutex should not be owned by current */
+        if (mutex_owned(&mp.mp_mtx)) {
+                splat_vprint(file, SPLAT_MUTEX_TEST3_NAME, "Mutex owned by "
+                             "pid %d it should be unowned\b", current->pid);
+                rc = -EINVAL;
+                goto out;
+        }
+
+        if (taskq_dispatch(tq, splat_mutex_owned, &mp, TQ_SLEEP) == 0) {
+                splat_vprint(file, SPLAT_MUTEX_TEST3_NAME, "Failed to "
+                             "dispatch function '%s' to taskq\n",
+                             sym2str(splat_mutex_owned));
+                rc = -EINVAL;
+                goto out;
+        }
+        taskq_wait(tq);
+
+        /* Mutex should be owned by no one */
+        if (mp.mp_rc || mp.mp_rc2) {
+                splat_vprint(file, SPLAT_MUTEX_TEST3_NAME, "Mutex owned by "
+                             "no one, %d/%d disagrees\n", mp.mp_rc, mp.mp_rc2);
+                rc = -EINVAL;
+                goto out;
+        }
+
+        splat_vprint(file, SPLAT_MUTEX_TEST3_NAME, "%s",
+                   "Correct mutex_owned() behavior\n");
+        goto out;
+out_exit:
+        mutex_exit(&mp.mp_mtx);
+out:
+        mutex_destroy(&mp.mp_mtx);
+        taskq_destroy(tq);
+
+        return rc;
+}
+
+static int
+splat_mutex_test4(struct file *file, void *arg)
+{
+        kmutex_t mtx;
+        kthread_t *owner;
+        int rc = 0;
+
+        mutex_init(&mtx, SPLAT_MUTEX_TEST_NAME, MUTEX_DEFAULT, NULL);
+
+        /*
+         * Verify mutex owner is cleared after being dropped.  Depending
+         * on how you build your kernel this behavior changes, ensure the
+         * SPL mutex implementation is properly detecting this.
+         */
+        mutex_enter(&mtx);
+        msleep(100);
+        mutex_exit(&mtx);
+        if (MUTEX_HELD(&mtx)) {
+                splat_vprint(file, SPLAT_MUTEX_TEST4_NAME, "Mutex should "
+                           "not be held, bit is by %p\n", mutex_owner(&mtx));
+                rc = -EINVAL;
+                goto out;
+        }
+
+        mutex_enter(&mtx);
+
+        /* Mutex should be owned by current */
+        owner = mutex_owner(&mtx);
+        if (current != owner) {
+                splat_vprint(file, SPLAT_MUTEX_TEST4_NAME, "Mutex should "
+                           "be owned by pid %d but is owned by pid %d\n",
+                           current->pid, owner ? owner->pid : -1);
+                rc = -EINVAL;
+                goto out;
+        }
+
+        mutex_exit(&mtx);
+
+        /* Mutex should not be owned by any task */
+        owner = mutex_owner(&mtx);
+        if (owner) {
+                splat_vprint(file, SPLAT_MUTEX_TEST4_NAME, "Mutex should not "
+                           "be owned but is owned by pid %d\n", owner->pid);
+                rc = -EINVAL;
+                goto out;
+        }
+
+        splat_vprint(file, SPLAT_MUTEX_TEST3_NAME, "%s",
+                   "Correct mutex_owner() behavior\n");
+out:
+        mutex_destroy(&mtx);
+
+        return rc;
+}
+
+splat_subsystem_t *
+splat_mutex_init(void)
+{
+        splat_subsystem_t *sub;
+
+        sub = kmalloc(sizeof(*sub), GFP_KERNEL);
+        if (sub == NULL)
+                return NULL;
+
+        memset(sub, 0, sizeof(*sub));
+        strncpy(sub->desc.name, SPLAT_MUTEX_NAME, SPLAT_NAME_SIZE);
+        strncpy(sub->desc.desc, SPLAT_MUTEX_DESC, SPLAT_DESC_SIZE);
+        INIT_LIST_HEAD(&sub->subsystem_list);
+        INIT_LIST_HEAD(&sub->test_list);
+        spin_lock_init(&sub->test_lock);
+        sub->desc.id = SPLAT_SUBSYSTEM_MUTEX;
+
+        SPLAT_TEST_INIT(sub, SPLAT_MUTEX_TEST1_NAME, SPLAT_MUTEX_TEST1_DESC,
+                      SPLAT_MUTEX_TEST1_ID, splat_mutex_test1);
+        SPLAT_TEST_INIT(sub, SPLAT_MUTEX_TEST2_NAME, SPLAT_MUTEX_TEST2_DESC,
+                      SPLAT_MUTEX_TEST2_ID, splat_mutex_test2);
+        SPLAT_TEST_INIT(sub, SPLAT_MUTEX_TEST3_NAME, SPLAT_MUTEX_TEST3_DESC,
+                      SPLAT_MUTEX_TEST3_ID, splat_mutex_test3);
+        SPLAT_TEST_INIT(sub, SPLAT_MUTEX_TEST4_NAME, SPLAT_MUTEX_TEST4_DESC,
+                      SPLAT_MUTEX_TEST4_ID, splat_mutex_test4);
+
+        return sub;
+}
+
+void
+splat_mutex_fini(splat_subsystem_t *sub)
+{
+        ASSERT(sub);
+        SPLAT_TEST_FINI(sub, SPLAT_MUTEX_TEST4_ID);
+        SPLAT_TEST_FINI(sub, SPLAT_MUTEX_TEST3_ID);
+        SPLAT_TEST_FINI(sub, SPLAT_MUTEX_TEST2_ID);
+        SPLAT_TEST_FINI(sub, SPLAT_MUTEX_TEST1_ID);
+
+        kfree(sub);
+}
+
+int
+splat_mutex_id(void) {
+        return SPLAT_SUBSYSTEM_MUTEX;
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/module/splat/splat-random.c
@@ -0,0 +1,130 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+ *****************************************************************************
+ *  Solaris Porting LAyer Tests (SPLAT) Random Number Generator Tests.
+\*****************************************************************************/
+
+#include <sys/random.h>
+#include <sys/kmem.h>
+#include "splat-internal.h"
+
+#define SPLAT_KRNG_NAME			"krng"
+#define SPLAT_KRNG_DESC			"Kernel Random Number Generator Tests"
+
+#define SPLAT_KRNG_TEST1_ID		0x0301
+#define SPLAT_KRNG_TEST1_NAME		"freq"
+#define SPLAT_KRNG_TEST1_DESC		"Frequency Test"
+
+#define KRNG_NUM_BITS			1048576
+#define KRNG_NUM_BYTES			(KRNG_NUM_BITS >> 3)
+#define KRNG_NUM_BITS_DIV2		(KRNG_NUM_BITS >> 1)
+#define KRNG_ERROR_RANGE		2097
+
+/* Random Number Generator Tests
+   There can be meny more tests on quality of the
+   random number generator.  For now we are only
+   testing the frequency of particular bits.
+   We could also test consecutive sequences,
+   randomness within a particular block, etc.
+   but is probably not necessary for our purposes */
+
+static int
+splat_krng_test1(struct file *file, void *arg)
+{
+	uint8_t *buf;
+	int i, j, diff, num = 0, rc = 0;
+
+	buf = kmalloc(sizeof(*buf) * KRNG_NUM_BYTES, GFP_KERNEL);
+	if (buf == NULL) {
+		rc = -ENOMEM;
+		goto out;
+	}
+
+	memset(buf, 0, sizeof(*buf) * KRNG_NUM_BYTES);
+
+	/* Always succeeds */
+	random_get_pseudo_bytes(buf, sizeof(uint8_t) * KRNG_NUM_BYTES);
+
+	for (i = 0; i < KRNG_NUM_BYTES; i++) {
+		uint8_t tmp = buf[i];
+		for (j = 0; j < 8; j++) {
+			uint8_t tmp2 = ((tmp >> j) & 0x01);
+			if (tmp2 == 1) {
+				num++;
+			}
+		}
+	}
+
+	kfree(buf);
+
+	diff = KRNG_NUM_BITS_DIV2 - num;
+	if (diff < 0)
+		diff *= -1;
+
+	splat_print(file, "Test 1 Number of ones: %d\n", num);
+	splat_print(file, "Test 1 Difference from expected: %d Allowed: %d\n",
+                  diff, KRNG_ERROR_RANGE);
+
+	if (diff > KRNG_ERROR_RANGE)
+		rc = -ERANGE;
+out:
+	return rc;
+}
+
+splat_subsystem_t *
+splat_krng_init(void)
+{
+        splat_subsystem_t *sub;
+
+        sub = kmalloc(sizeof(*sub), GFP_KERNEL);
+        if (sub == NULL)
+                return NULL;
+
+        memset(sub, 0, sizeof(*sub));
+        strncpy(sub->desc.name, SPLAT_KRNG_NAME, SPLAT_NAME_SIZE);
+	strncpy(sub->desc.desc, SPLAT_KRNG_DESC, SPLAT_DESC_SIZE);
+        INIT_LIST_HEAD(&sub->subsystem_list);
+	INIT_LIST_HEAD(&sub->test_list);
+        spin_lock_init(&sub->test_lock);
+        sub->desc.id = SPLAT_SUBSYSTEM_KRNG;
+
+        SPLAT_TEST_INIT(sub, SPLAT_KRNG_TEST1_NAME, SPLAT_KRNG_TEST1_DESC,
+	              SPLAT_KRNG_TEST1_ID, splat_krng_test1);
+
+        return sub;
+}
+
+void
+splat_krng_fini(splat_subsystem_t *sub)
+{
+        ASSERT(sub);
+
+        SPLAT_TEST_FINI(sub, SPLAT_KRNG_TEST1_ID);
+
+        kfree(sub);
+}
+
+int
+splat_krng_id(void) {
+        return SPLAT_SUBSYSTEM_KRNG;
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/module/splat/splat-rwlock.c
@@ -0,0 +1,675 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+ *****************************************************************************
+ *  Solaris Porting LAyer Tests (SPLAT) Read/Writer Lock Tests.
+\*****************************************************************************/
+
+#include <sys/random.h>
+#include <sys/rwlock.h>
+#include <sys/taskq.h>
+#include <linux/delay.h>
+#include <linux/mm_compat.h>
+#include "splat-internal.h"
+
+#define SPLAT_RWLOCK_NAME		"rwlock"
+#define SPLAT_RWLOCK_DESC		"Kernel RW Lock Tests"
+
+#define SPLAT_RWLOCK_TEST1_ID		0x0701
+#define SPLAT_RWLOCK_TEST1_NAME		"N-rd/1-wr"
+#define SPLAT_RWLOCK_TEST1_DESC		"Multiple readers one writer"
+
+#define SPLAT_RWLOCK_TEST2_ID		0x0702
+#define SPLAT_RWLOCK_TEST2_NAME		"0-rd/N-wr"
+#define SPLAT_RWLOCK_TEST2_DESC		"Multiple writers"
+
+#define SPLAT_RWLOCK_TEST3_ID		0x0703
+#define SPLAT_RWLOCK_TEST3_NAME		"held"
+#define SPLAT_RWLOCK_TEST3_DESC		"RW_{LOCK|READ|WRITE}_HELD"
+
+#define SPLAT_RWLOCK_TEST4_ID		0x0704
+#define SPLAT_RWLOCK_TEST4_NAME		"tryenter"
+#define SPLAT_RWLOCK_TEST4_DESC		"Tryenter"
+
+#define SPLAT_RWLOCK_TEST5_ID		0x0705
+#define SPLAT_RWLOCK_TEST5_NAME		"rw_downgrade"
+#define SPLAT_RWLOCK_TEST5_DESC		"Write downgrade"
+
+#define SPLAT_RWLOCK_TEST6_ID		0x0706
+#define SPLAT_RWLOCK_TEST6_NAME		"rw_tryupgrade"
+#define SPLAT_RWLOCK_TEST6_DESC		"Read upgrade"
+
+#define SPLAT_RWLOCK_TEST_MAGIC		0x115599DDUL
+#define SPLAT_RWLOCK_TEST_NAME		"rwlock_test"
+#define SPLAT_RWLOCK_TEST_TASKQ		"rwlock_taskq"
+#define SPLAT_RWLOCK_TEST_COUNT		8
+
+#define SPLAT_RWLOCK_RELEASE_INIT	0
+#define SPLAT_RWLOCK_RELEASE_WR		1
+#define SPLAT_RWLOCK_RELEASE_RD		2
+
+typedef struct rw_priv {
+	unsigned long rw_magic;
+	struct file *rw_file;
+	krwlock_t rw_rwlock;
+	spinlock_t rw_lock;
+	wait_queue_head_t rw_waitq;
+	int rw_completed;
+	int rw_holders;
+	int rw_waiters;
+	int rw_release;
+	int rw_rc;
+	krw_t rw_type;
+} rw_priv_t;
+
+typedef struct rw_thr {
+	const char *rwt_name;
+	rw_priv_t *rwt_rwp;
+	struct task_struct *rwt_thread;
+} rw_thr_t;
+
+void splat_init_rw_priv(rw_priv_t *rwp, struct file *file)
+{
+	rwp->rw_magic = SPLAT_RWLOCK_TEST_MAGIC;
+	rwp->rw_file = file;
+	rw_init(&rwp->rw_rwlock, SPLAT_RWLOCK_TEST_NAME, RW_DEFAULT, NULL);
+	spin_lock_init(&rwp->rw_lock);
+	init_waitqueue_head(&rwp->rw_waitq);
+	rwp->rw_completed = 0;
+	rwp->rw_holders = 0;
+	rwp->rw_waiters = 0;
+	rwp->rw_release = SPLAT_RWLOCK_RELEASE_INIT;
+	rwp->rw_rc = 0;
+	rwp->rw_type = 0;
+}
+
+static int
+splat_rwlock_wr_thr(void *arg)
+{
+	rw_thr_t *rwt = (rw_thr_t *)arg;
+	rw_priv_t *rwp = rwt->rwt_rwp;
+	uint8_t rnd;
+
+	ASSERT(rwp->rw_magic == SPLAT_RWLOCK_TEST_MAGIC);
+
+	get_random_bytes((void *)&rnd, 1);
+	msleep((unsigned int)rnd);
+
+	splat_vprint(rwp->rw_file, rwt->rwt_name,
+	    "%s trying to acquire rwlock (%d holding/%d waiting)\n",
+	    rwt->rwt_thread->comm, rwp->rw_holders, rwp->rw_waiters);
+	spin_lock(&rwp->rw_lock);
+	rwp->rw_waiters++;
+	spin_unlock(&rwp->rw_lock);
+	rw_enter(&rwp->rw_rwlock, RW_WRITER);
+
+	spin_lock(&rwp->rw_lock);
+	rwp->rw_waiters--;
+	rwp->rw_holders++;
+	spin_unlock(&rwp->rw_lock);
+	splat_vprint(rwp->rw_file, rwt->rwt_name,
+	    "%s acquired rwlock (%d holding/%d waiting)\n",
+	    rwt->rwt_thread->comm, rwp->rw_holders, rwp->rw_waiters);
+
+	/* Wait for control thread to signal we can release the write lock */
+	wait_event_interruptible(rwp->rw_waitq, splat_locked_test(&rwp->rw_lock,
+	    rwp->rw_release == SPLAT_RWLOCK_RELEASE_WR));
+
+	spin_lock(&rwp->rw_lock);
+	rwp->rw_completed++;
+	rwp->rw_holders--;
+	spin_unlock(&rwp->rw_lock);
+	splat_vprint(rwp->rw_file, rwt->rwt_name,
+	    "%s dropped rwlock (%d holding/%d waiting)\n",
+	    rwt->rwt_thread->comm, rwp->rw_holders, rwp->rw_waiters);
+
+	rw_exit(&rwp->rw_rwlock);
+
+	return 0;
+}
+
+static int
+splat_rwlock_rd_thr(void *arg)
+{
+	rw_thr_t *rwt = (rw_thr_t *)arg;
+	rw_priv_t *rwp = rwt->rwt_rwp;
+	uint8_t rnd;
+
+	ASSERT(rwp->rw_magic == SPLAT_RWLOCK_TEST_MAGIC);
+
+	get_random_bytes((void *)&rnd, 1);
+	msleep((unsigned int)rnd);
+
+	/* Don't try and take the semaphore until after someone has it */
+	wait_event_interruptible(rwp->rw_waitq,
+	    splat_locked_test(&rwp->rw_lock, rwp->rw_holders > 0));
+
+	splat_vprint(rwp->rw_file, rwt->rwt_name,
+	    "%s trying to acquire rwlock (%d holding/%d waiting)\n",
+	    rwt->rwt_thread->comm, rwp->rw_holders, rwp->rw_waiters);
+	spin_lock(&rwp->rw_lock);
+	rwp->rw_waiters++;
+	spin_unlock(&rwp->rw_lock);
+	rw_enter(&rwp->rw_rwlock, RW_READER);
+
+	spin_lock(&rwp->rw_lock);
+	rwp->rw_waiters--;
+	rwp->rw_holders++;
+	spin_unlock(&rwp->rw_lock);
+	splat_vprint(rwp->rw_file, rwt->rwt_name,
+	    "%s acquired rwlock (%d holding/%d waiting)\n",
+	    rwt->rwt_thread->comm, rwp->rw_holders, rwp->rw_waiters);
+
+	/* Wait for control thread to signal we can release the read lock */
+	wait_event_interruptible(rwp->rw_waitq, splat_locked_test(&rwp->rw_lock,
+	    rwp->rw_release == SPLAT_RWLOCK_RELEASE_RD));
+
+	spin_lock(&rwp->rw_lock);
+	rwp->rw_completed++;
+	rwp->rw_holders--;
+	spin_unlock(&rwp->rw_lock);
+	splat_vprint(rwp->rw_file, rwt->rwt_name,
+	    "%s dropped rwlock (%d holding/%d waiting)\n",
+	    rwt->rwt_thread->comm, rwp->rw_holders, rwp->rw_waiters);
+
+	rw_exit(&rwp->rw_rwlock);
+
+	return 0;
+}
+
+static int
+splat_rwlock_test1(struct file *file, void *arg)
+{
+	int i, count = 0, rc = 0;
+	rw_thr_t rwt[SPLAT_RWLOCK_TEST_COUNT];
+	rw_priv_t *rwp;
+
+	rwp = (rw_priv_t *)kmalloc(sizeof(*rwp), GFP_KERNEL);
+	if (rwp == NULL)
+		return -ENOMEM;
+
+	splat_init_rw_priv(rwp, file);
+
+	/* Create some threads, the exact number isn't important just as
+	 * long as we know how many we managed to create and should expect. */
+	for (i = 0; i < SPLAT_RWLOCK_TEST_COUNT; i++) {
+		rwt[i].rwt_rwp = rwp;
+		rwt[i].rwt_name = SPLAT_RWLOCK_TEST1_NAME;
+
+		/* The first thread will be the writer */
+		if (i == 0)
+			rwt[i].rwt_thread = spl_kthread_create(splat_rwlock_wr_thr,
+			    &rwt[i], "%s/%d", SPLAT_RWLOCK_TEST_NAME, i);
+		else
+			rwt[i].rwt_thread = spl_kthread_create(splat_rwlock_rd_thr,
+			    &rwt[i], "%s/%d", SPLAT_RWLOCK_TEST_NAME, i);
+
+		if (!IS_ERR(rwt[i].rwt_thread)) {
+			wake_up_process(rwt[i].rwt_thread);
+			count++;
+		}
+	}
+
+	/* Wait for the writer */
+	while (splat_locked_test(&rwp->rw_lock, rwp->rw_holders == 0)) {
+		wake_up_interruptible(&rwp->rw_waitq);
+		msleep(100);
+	}
+
+	/* Wait for 'count-1' readers */
+	while (splat_locked_test(&rwp->rw_lock, rwp->rw_waiters < count - 1)) {
+		wake_up_interruptible(&rwp->rw_waitq);
+		msleep(100);
+	}
+
+	/* Verify there is only one lock holder */
+	if (splat_locked_test(&rwp->rw_lock, rwp->rw_holders) != 1) {
+		splat_vprint(file, SPLAT_RWLOCK_TEST1_NAME, "Only 1 holder "
+			     "expected for rwlock (%d holding/%d waiting)\n",
+			     rwp->rw_holders, rwp->rw_waiters);
+		rc = -EINVAL;
+	}
+
+	/* Verify 'count-1' readers */
+	if (splat_locked_test(&rwp->rw_lock, rwp->rw_waiters != count - 1)) {
+		splat_vprint(file, SPLAT_RWLOCK_TEST1_NAME, "Only %d waiters "
+			     "expected for rwlock (%d holding/%d waiting)\n",
+			     count - 1, rwp->rw_holders, rwp->rw_waiters);
+		rc = -EINVAL;
+	}
+
+	/* Signal the writer to release, allows readers to acquire */
+	spin_lock(&rwp->rw_lock);
+	rwp->rw_release = SPLAT_RWLOCK_RELEASE_WR;
+	wake_up_interruptible(&rwp->rw_waitq);
+	spin_unlock(&rwp->rw_lock);
+
+	/* Wait for 'count-1' readers to hold the lock */
+	while (splat_locked_test(&rwp->rw_lock, rwp->rw_holders < count - 1)) {
+		wake_up_interruptible(&rwp->rw_waitq);
+		msleep(100);
+	}
+
+	/* Verify there are 'count-1' readers */
+	if (splat_locked_test(&rwp->rw_lock, rwp->rw_holders != count - 1)) {
+		splat_vprint(file, SPLAT_RWLOCK_TEST1_NAME, "Only %d holders "
+			     "expected for rwlock (%d holding/%d waiting)\n",
+			     count - 1, rwp->rw_holders, rwp->rw_waiters);
+		rc = -EINVAL;
+	}
+
+	/* Release 'count-1' readers */
+	spin_lock(&rwp->rw_lock);
+	rwp->rw_release = SPLAT_RWLOCK_RELEASE_RD;
+	wake_up_interruptible(&rwp->rw_waitq);
+	spin_unlock(&rwp->rw_lock);
+
+	/* Wait for the test to complete */
+	while (splat_locked_test(&rwp->rw_lock,
+				 rwp->rw_holders>0 || rwp->rw_waiters>0))
+		msleep(100);
+
+	rw_destroy(&(rwp->rw_rwlock));
+	kfree(rwp);
+
+	return rc;
+}
+
+static void
+splat_rwlock_test2_func(void *arg)
+{
+	rw_priv_t *rwp = (rw_priv_t *)arg;
+	int rc;
+	ASSERT(rwp->rw_magic == SPLAT_RWLOCK_TEST_MAGIC);
+
+	/* Read the value before sleeping and write it after we wake up to
+	 * maximize the chance of a race if rwlocks are not working properly */
+	rw_enter(&rwp->rw_rwlock, RW_WRITER);
+	rc = rwp->rw_rc;
+	set_current_state(TASK_INTERRUPTIBLE);
+	schedule_timeout(HZ / 100);  /* 1/100 of a second */
+	VERIFY(rwp->rw_rc == rc);
+	rwp->rw_rc = rc + 1;
+	rw_exit(&rwp->rw_rwlock);
+}
+
+static int
+splat_rwlock_test2(struct file *file, void *arg)
+{
+	rw_priv_t *rwp;
+	taskq_t *tq;
+	int i, rc = 0, tq_count = 256;
+
+	rwp = (rw_priv_t *)kmalloc(sizeof(*rwp), GFP_KERNEL);
+	if (rwp == NULL)
+		return -ENOMEM;
+
+	splat_init_rw_priv(rwp, file);
+
+	/* Create several threads allowing tasks to race with each other */
+	tq = taskq_create(SPLAT_RWLOCK_TEST_TASKQ, num_online_cpus(),
+			  defclsyspri, 50, INT_MAX, TASKQ_PREPOPULATE);
+	if (tq == NULL) {
+		rc = -ENOMEM;
+		goto out;
+	}
+
+	/*
+	 * Schedule N work items to the work queue each of which enters the
+	 * writer rwlock, sleeps briefly, then exits the writer rwlock.  On a
+	 * multiprocessor box these work items will be handled by all available
+	 * CPUs.  The task function checks to ensure the tracked shared variable
+	 * is always only incremented by one.  Additionally, the rwlock itself
+	 * is instrumented such that if any two processors are in the
+	 * critical region at the same time the system will panic.  If the
+	 * rwlock is implemented right this will never happy, that's a pass.
+	 */
+	for (i = 0; i < tq_count; i++) {
+		if (!taskq_dispatch(tq,splat_rwlock_test2_func,rwp,TQ_SLEEP)) {
+			splat_vprint(file, SPLAT_RWLOCK_TEST2_NAME,
+				     "Failed to queue task %d\n", i);
+			rc = -EINVAL;
+		}
+	}
+
+	taskq_wait(tq);
+
+	if (rwp->rw_rc == tq_count) {
+		splat_vprint(file, SPLAT_RWLOCK_TEST2_NAME, "%d racing threads "
+			     "correctly entered/exited the rwlock %d times\n",
+			     num_online_cpus(), rwp->rw_rc);
+	} else {
+		splat_vprint(file, SPLAT_RWLOCK_TEST2_NAME, "%d racing threads "
+			     "only processed %d/%d w rwlock work items\n",
+			     num_online_cpus(), rwp->rw_rc, tq_count);
+		rc = -EINVAL;
+	}
+
+	taskq_destroy(tq);
+	rw_destroy(&(rwp->rw_rwlock));
+out:
+	kfree(rwp);
+	return rc;
+}
+
+#define splat_rwlock_test3_helper(rwp,rex1,rex2,wex1,wex2,held_func,rc)	\
+do {									\
+	int result, _rc1_, _rc2_, _rc3_, _rc4_;				\
+									\
+	rc = 0;								\
+	rw_enter(&(rwp)->rw_rwlock, RW_READER);				\
+	_rc1_ = ((result = held_func(&(rwp)->rw_rwlock)) != rex1);	\
+	splat_vprint(file, SPLAT_RWLOCK_TEST3_NAME, "%s" #held_func	\
+		     " returned %d (expected %d) when RW_READER\n",	\
+		     _rc1_ ? "Fail " : "", result, rex1);		\
+	rw_exit(&(rwp)->rw_rwlock);					\
+	_rc2_ = ((result = held_func(&(rwp)->rw_rwlock)) != rex2);	\
+	splat_vprint(file, SPLAT_RWLOCK_TEST3_NAME, "%s" #held_func	\
+		     " returned %d (expected %d) when !RW_READER\n",	\
+		     _rc2_ ? "Fail " : "", result, rex2);		\
+									\
+	rw_enter(&(rwp)->rw_rwlock, RW_WRITER);				\
+	_rc3_ = ((result = held_func(&(rwp)->rw_rwlock)) != wex1);	\
+	splat_vprint(file, SPLAT_RWLOCK_TEST3_NAME, "%s" #held_func	\
+		     " returned %d (expected %d) when RW_WRITER\n",	\
+		     _rc3_ ? "Fail " : "", result, wex1);		\
+	rw_exit(&(rwp)->rw_rwlock);					\
+	_rc4_ = ((result = held_func(&(rwp)->rw_rwlock)) != wex2);	\
+	splat_vprint(file, SPLAT_RWLOCK_TEST3_NAME, "%s" #held_func	\
+		     " returned %d (expected %d) when !RW_WRITER\n",	\
+		     _rc4_ ? "Fail " : "", result, wex2);		\
+									\
+	rc = ((_rc1_ ||  _rc2_ || _rc3_ || _rc4_) ? -EINVAL : 0);	\
+} while(0);
+
+static int
+splat_rwlock_test3(struct file *file, void *arg)
+{
+	rw_priv_t *rwp;
+	int rc1, rc2, rc3;
+
+	rwp = (rw_priv_t *)kmalloc(sizeof(*rwp), GFP_KERNEL);
+	if (rwp == NULL)
+		return -ENOMEM;
+
+	splat_init_rw_priv(rwp, file);
+
+	splat_rwlock_test3_helper(rwp, 1, 0, 1, 0, RW_LOCK_HELD, rc1);
+	splat_rwlock_test3_helper(rwp, 1, 0, 0, 0, RW_READ_HELD, rc2);
+	splat_rwlock_test3_helper(rwp, 0, 0, 1, 0, RW_WRITE_HELD, rc3);
+
+	rw_destroy(&rwp->rw_rwlock);
+	kfree(rwp);
+
+	return ((rc1 || rc2 || rc3) ? -EINVAL : 0);
+}
+
+static void
+splat_rwlock_test4_func(void *arg)
+{
+	rw_priv_t *rwp = (rw_priv_t *)arg;
+	ASSERT(rwp->rw_magic == SPLAT_RWLOCK_TEST_MAGIC);
+
+	if (rw_tryenter(&rwp->rw_rwlock, rwp->rw_type)) {
+		rwp->rw_rc = 0;
+		rw_exit(&rwp->rw_rwlock);
+	} else {
+		rwp->rw_rc = -EBUSY;
+	}
+}
+
+static char *
+splat_rwlock_test4_name(krw_t type)
+{
+	switch (type) {
+		case RW_NONE: return "RW_NONE";
+		case RW_WRITER: return "RW_WRITER";
+		case RW_READER: return "RW_READER";
+	}
+
+	return NULL;
+}
+
+static int
+splat_rwlock_test4_type(taskq_t *tq, rw_priv_t *rwp, int expected_rc,
+			krw_t holder_type, krw_t try_type)
+{
+	int id, rc = 0;
+
+	/* Schedule a task function which will try and acquire the rwlock
+	 * using type try_type while the rwlock is being held as holder_type.
+	 * The result must match expected_rc for the test to pass */
+	rwp->rw_rc = -EINVAL;
+	rwp->rw_type = try_type;
+
+	if (holder_type == RW_WRITER || holder_type == RW_READER)
+		rw_enter(&rwp->rw_rwlock, holder_type);
+
+	id = taskq_dispatch(tq, splat_rwlock_test4_func, rwp, TQ_SLEEP);
+	if (id == 0) {
+		splat_vprint(rwp->rw_file, SPLAT_RWLOCK_TEST4_NAME, "%s",
+			     "taskq_dispatch() failed\n");
+		rc = -EINVAL;
+		goto out;
+	}
+
+	taskq_wait_id(tq, id);
+
+	if (rwp->rw_rc != expected_rc)
+		rc = -EINVAL;
+
+	splat_vprint(rwp->rw_file, SPLAT_RWLOCK_TEST4_NAME,
+		     "%srw_tryenter(%s) returned %d (expected %d) when %s\n",
+		     rc ? "Fail " : "", splat_rwlock_test4_name(try_type),
+		     rwp->rw_rc, expected_rc,
+		     splat_rwlock_test4_name(holder_type));
+out:
+	if (holder_type == RW_WRITER || holder_type == RW_READER)
+		rw_exit(&rwp->rw_rwlock);
+
+	return rc;
+}
+
+static int
+splat_rwlock_test4(struct file *file, void *arg)
+{
+	rw_priv_t *rwp;
+	taskq_t *tq;
+	int rc = 0, rc1, rc2, rc3, rc4, rc5, rc6;
+
+	rwp = (rw_priv_t *)kmalloc(sizeof(*rwp), GFP_KERNEL);
+	if (rwp == NULL)
+		return -ENOMEM;
+
+	tq = taskq_create(SPLAT_RWLOCK_TEST_TASKQ, 1, defclsyspri,
+			  50, INT_MAX, TASKQ_PREPOPULATE);
+	if (tq == NULL) {
+		rc = -ENOMEM;
+		goto out;
+	}
+
+	splat_init_rw_priv(rwp, file);
+
+	/* Validate all combinations of rw_tryenter() contention */
+	rc1 = splat_rwlock_test4_type(tq, rwp, -EBUSY, RW_WRITER, RW_WRITER);
+	rc2 = splat_rwlock_test4_type(tq, rwp, -EBUSY, RW_WRITER, RW_READER);
+	rc3 = splat_rwlock_test4_type(tq, rwp, -EBUSY, RW_READER, RW_WRITER);
+	rc4 = splat_rwlock_test4_type(tq, rwp, 0,      RW_READER, RW_READER);
+	rc5 = splat_rwlock_test4_type(tq, rwp, 0,      RW_NONE,   RW_WRITER);
+	rc6 = splat_rwlock_test4_type(tq, rwp, 0,      RW_NONE,   RW_READER);
+
+	if (rc1 || rc2 || rc3 || rc4 || rc5 || rc6)
+		rc = -EINVAL;
+
+	taskq_destroy(tq);
+out:
+	rw_destroy(&(rwp->rw_rwlock));
+	kfree(rwp);
+
+	return rc;
+}
+
+static int
+splat_rwlock_test5(struct file *file, void *arg)
+{
+	rw_priv_t *rwp;
+	int rc = -EINVAL;
+
+	rwp = (rw_priv_t *)kmalloc(sizeof(*rwp), GFP_KERNEL);
+	if (rwp == NULL)
+		return -ENOMEM;
+
+	splat_init_rw_priv(rwp, file);
+
+	rw_enter(&rwp->rw_rwlock, RW_WRITER);
+	if (!RW_WRITE_HELD(&rwp->rw_rwlock)) {
+		splat_vprint(file, SPLAT_RWLOCK_TEST5_NAME,
+			     "rwlock should be write lock: %d\n",
+			     RW_WRITE_HELD(&rwp->rw_rwlock));
+		goto out;
+	}
+
+	rw_downgrade(&rwp->rw_rwlock);
+	if (!RW_READ_HELD(&rwp->rw_rwlock)) {
+		splat_vprint(file, SPLAT_RWLOCK_TEST5_NAME,
+			     "rwlock should be read lock: %d\n",
+			     RW_READ_HELD(&rwp->rw_rwlock));
+		goto out;
+	}
+
+	rc = 0;
+	splat_vprint(file, SPLAT_RWLOCK_TEST5_NAME, "%s",
+		     "rwlock properly downgraded\n");
+out:
+	rw_exit(&rwp->rw_rwlock);
+	rw_destroy(&rwp->rw_rwlock);
+	kfree(rwp);
+
+	return rc;
+}
+
+static int
+splat_rwlock_test6(struct file *file, void *arg)
+{
+	rw_priv_t *rwp;
+	int rc;
+
+	rwp = (rw_priv_t *)kmalloc(sizeof(*rwp), GFP_KERNEL);
+	if (rwp == NULL)
+		return -ENOMEM;
+
+	splat_init_rw_priv(rwp, file);
+
+	rw_enter(&rwp->rw_rwlock, RW_READER);
+	if (!RW_READ_HELD(&rwp->rw_rwlock)) {
+		splat_vprint(file, SPLAT_RWLOCK_TEST6_NAME,
+		             "rwlock should be read lock: %d\n",
+			     RW_READ_HELD(&rwp->rw_rwlock));
+		rc = -ENOLCK;
+		goto out;
+	}
+
+#if defined(CONFIG_RWSEM_GENERIC_SPINLOCK)
+	/* With one reader upgrade should never fail. */
+	rc = rw_tryupgrade(&rwp->rw_rwlock);
+	if (!rc) {
+		splat_vprint(file, SPLAT_RWLOCK_TEST6_NAME,
+			     "rwlock failed upgrade from reader: %d\n",
+			     RW_READ_HELD(&rwp->rw_rwlock));
+		rc = -ENOLCK;
+		goto out;
+	}
+
+	if (RW_READ_HELD(&rwp->rw_rwlock) || !RW_WRITE_HELD(&rwp->rw_rwlock)) {
+		splat_vprint(file, SPLAT_RWLOCK_TEST6_NAME, "rwlock should "
+			   "have 0 (not %d) reader and 1 (not %d) writer\n",
+			   RW_READ_HELD(&rwp->rw_rwlock),
+			   RW_WRITE_HELD(&rwp->rw_rwlock));
+		goto out;
+	}
+
+	rc = 0;
+	splat_vprint(file, SPLAT_RWLOCK_TEST6_NAME, "%s",
+		     "rwlock properly upgraded\n");
+#else
+	rc = 0;
+	splat_vprint(file, SPLAT_RWLOCK_TEST6_NAME, "%s",
+		     "rw_tryupgrade() is disabled for this arch\n");
+#endif
+out:
+	rw_exit(&rwp->rw_rwlock);
+	rw_destroy(&rwp->rw_rwlock);
+	kfree(rwp);
+
+	return rc;
+}
+
+splat_subsystem_t *
+splat_rwlock_init(void)
+{
+	splat_subsystem_t *sub;
+
+	sub = kmalloc(sizeof(*sub), GFP_KERNEL);
+	if (sub == NULL)
+		return NULL;
+
+	memset(sub, 0, sizeof(*sub));
+	strncpy(sub->desc.name, SPLAT_RWLOCK_NAME, SPLAT_NAME_SIZE);
+	strncpy(sub->desc.desc, SPLAT_RWLOCK_DESC, SPLAT_DESC_SIZE);
+	INIT_LIST_HEAD(&sub->subsystem_list);
+	INIT_LIST_HEAD(&sub->test_list);
+	spin_lock_init(&sub->test_lock);
+	sub->desc.id = SPLAT_SUBSYSTEM_RWLOCK;
+
+	SPLAT_TEST_INIT(sub, SPLAT_RWLOCK_TEST1_NAME, SPLAT_RWLOCK_TEST1_DESC,
+		      SPLAT_RWLOCK_TEST1_ID, splat_rwlock_test1);
+	SPLAT_TEST_INIT(sub, SPLAT_RWLOCK_TEST2_NAME, SPLAT_RWLOCK_TEST2_DESC,
+		      SPLAT_RWLOCK_TEST2_ID, splat_rwlock_test2);
+	SPLAT_TEST_INIT(sub, SPLAT_RWLOCK_TEST3_NAME, SPLAT_RWLOCK_TEST3_DESC,
+		      SPLAT_RWLOCK_TEST3_ID, splat_rwlock_test3);
+	SPLAT_TEST_INIT(sub, SPLAT_RWLOCK_TEST4_NAME, SPLAT_RWLOCK_TEST4_DESC,
+		      SPLAT_RWLOCK_TEST4_ID, splat_rwlock_test4);
+	SPLAT_TEST_INIT(sub, SPLAT_RWLOCK_TEST5_NAME, SPLAT_RWLOCK_TEST5_DESC,
+		      SPLAT_RWLOCK_TEST5_ID, splat_rwlock_test5);
+	SPLAT_TEST_INIT(sub, SPLAT_RWLOCK_TEST6_NAME, SPLAT_RWLOCK_TEST6_DESC,
+		      SPLAT_RWLOCK_TEST6_ID, splat_rwlock_test6);
+
+	return sub;
+}
+
+void
+splat_rwlock_fini(splat_subsystem_t *sub)
+{
+	ASSERT(sub);
+	SPLAT_TEST_FINI(sub, SPLAT_RWLOCK_TEST6_ID);
+	SPLAT_TEST_FINI(sub, SPLAT_RWLOCK_TEST5_ID);
+	SPLAT_TEST_FINI(sub, SPLAT_RWLOCK_TEST4_ID);
+	SPLAT_TEST_FINI(sub, SPLAT_RWLOCK_TEST3_ID);
+	SPLAT_TEST_FINI(sub, SPLAT_RWLOCK_TEST2_ID);
+	SPLAT_TEST_FINI(sub, SPLAT_RWLOCK_TEST1_ID);
+	kfree(sub);
+}
+
+int
+splat_rwlock_id(void) {
+	return SPLAT_SUBSYSTEM_RWLOCK;
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/module/splat/splat-taskq.c
@@ -0,0 +1,1547 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+ *****************************************************************************
+ *  Solaris Porting LAyer Tests (SPLAT) Task Queue Tests.
+\*****************************************************************************/
+
+#include <sys/kmem.h>
+#include <sys/vmem.h>
+#include <sys/random.h>
+#include <sys/taskq.h>
+#include <sys/time.h>
+#include <sys/timer.h>
+#include <linux/delay.h>
+#include "splat-internal.h"
+
+#define SPLAT_TASKQ_NAME		"taskq"
+#define SPLAT_TASKQ_DESC		"Kernel Task Queue Tests"
+
+#define SPLAT_TASKQ_TEST1_ID		0x0201
+#define SPLAT_TASKQ_TEST1_NAME		"single"
+#define SPLAT_TASKQ_TEST1_DESC		"Single task queue, single task"
+
+#define SPLAT_TASKQ_TEST2_ID		0x0202
+#define SPLAT_TASKQ_TEST2_NAME		"multiple"
+#define SPLAT_TASKQ_TEST2_DESC		"Multiple task queues, multiple tasks"
+
+#define SPLAT_TASKQ_TEST3_ID		0x0203
+#define SPLAT_TASKQ_TEST3_NAME		"system"
+#define SPLAT_TASKQ_TEST3_DESC		"System task queue, multiple tasks"
+
+#define SPLAT_TASKQ_TEST4_ID		0x0204
+#define SPLAT_TASKQ_TEST4_NAME		"wait"
+#define SPLAT_TASKQ_TEST4_DESC		"Multiple task waiting"
+
+#define SPLAT_TASKQ_TEST5_ID		0x0205
+#define SPLAT_TASKQ_TEST5_NAME		"order"
+#define SPLAT_TASKQ_TEST5_DESC		"Correct task ordering"
+
+#define SPLAT_TASKQ_TEST6_ID		0x0206
+#define SPLAT_TASKQ_TEST6_NAME		"front"
+#define SPLAT_TASKQ_TEST6_DESC		"Correct ordering with TQ_FRONT flag"
+
+#define SPLAT_TASKQ_TEST7_ID		0x0207
+#define SPLAT_TASKQ_TEST7_NAME		"recurse"
+#define SPLAT_TASKQ_TEST7_DESC		"Single task queue, recursive dispatch"
+
+#define SPLAT_TASKQ_TEST8_ID		0x0208
+#define SPLAT_TASKQ_TEST8_NAME		"contention"
+#define SPLAT_TASKQ_TEST8_DESC		"1 queue, 100 threads, 131072 tasks"
+
+#define SPLAT_TASKQ_TEST9_ID		0x0209
+#define SPLAT_TASKQ_TEST9_NAME		"delay"
+#define SPLAT_TASKQ_TEST9_DESC		"Delayed task execution"
+
+#define SPLAT_TASKQ_TEST10_ID		0x020a
+#define SPLAT_TASKQ_TEST10_NAME		"cancel"
+#define SPLAT_TASKQ_TEST10_DESC		"Cancel task execution"
+
+#define SPLAT_TASKQ_TEST11_ID		0x020b
+#define SPLAT_TASKQ_TEST11_NAME		"dynamic"
+#define SPLAT_TASKQ_TEST11_DESC		"Dynamic task queue thread creation"
+
+#define SPLAT_TASKQ_ORDER_MAX		8
+#define SPLAT_TASKQ_DEPTH_MAX		16
+
+
+typedef struct splat_taskq_arg {
+	int flag;
+	int id;
+	atomic_t *count;
+	int order[SPLAT_TASKQ_ORDER_MAX];
+	unsigned int depth;
+	clock_t expire;
+	taskq_t *tq;
+	taskq_ent_t *tqe;
+	spinlock_t lock;
+	struct file *file;
+	const char *name;
+} splat_taskq_arg_t;
+
+typedef struct splat_taskq_id {
+	int id;
+	splat_taskq_arg_t *arg;
+} splat_taskq_id_t;
+
+/*
+ * Create a taskq, queue a task, wait until task completes, ensure
+ * task ran properly, cleanup taskq.
+ */
+static void
+splat_taskq_test13_func(void *arg)
+{
+	splat_taskq_arg_t *tq_arg = (splat_taskq_arg_t *)arg;
+
+	ASSERT(tq_arg);
+	splat_vprint(tq_arg->file, SPLAT_TASKQ_TEST1_NAME,
+	           "Taskq '%s' function '%s' setting flag\n",
+	           tq_arg->name, sym2str(splat_taskq_test13_func));
+	tq_arg->flag = 1;
+}
+
+static int
+splat_taskq_test1_impl(struct file *file, void *arg, boolean_t prealloc)
+{
+	taskq_t *tq;
+	taskqid_t id;
+	splat_taskq_arg_t tq_arg;
+	taskq_ent_t *tqe;
+
+	tqe = kmem_alloc(sizeof (taskq_ent_t), KM_SLEEP);
+	taskq_init_ent(tqe);
+
+	splat_vprint(file, SPLAT_TASKQ_TEST1_NAME,
+		     "Taskq '%s' creating (%s dispatch)\n",
+	             SPLAT_TASKQ_TEST1_NAME,
+		     prealloc ? "prealloc" : "dynamic");
+	if ((tq = taskq_create(SPLAT_TASKQ_TEST1_NAME, 1, defclsyspri,
+			       50, INT_MAX, TASKQ_PREPOPULATE)) == NULL) {
+		splat_vprint(file, SPLAT_TASKQ_TEST1_NAME,
+		           "Taskq '%s' create failed\n",
+		           SPLAT_TASKQ_TEST1_NAME);
+		kmem_free(tqe, sizeof (taskq_ent_t));
+		return -EINVAL;
+	}
+
+	tq_arg.flag = 0;
+	tq_arg.id   = 0;
+	tq_arg.file = file;
+	tq_arg.name = SPLAT_TASKQ_TEST1_NAME;
+
+	splat_vprint(file, SPLAT_TASKQ_TEST1_NAME,
+	           "Taskq '%s' function '%s' dispatching\n",
+	           tq_arg.name, sym2str(splat_taskq_test13_func));
+	if (prealloc) {
+		taskq_dispatch_ent(tq, splat_taskq_test13_func,
+		                   &tq_arg, TQ_SLEEP, tqe);
+		id = tqe->tqent_id;
+	} else {
+		id = taskq_dispatch(tq, splat_taskq_test13_func,
+				    &tq_arg, TQ_SLEEP);
+	}
+
+	if (id == 0) {
+		splat_vprint(file, SPLAT_TASKQ_TEST1_NAME,
+		             "Taskq '%s' function '%s' dispatch failed\n",
+		             tq_arg.name, sym2str(splat_taskq_test13_func));
+		kmem_free(tqe, sizeof (taskq_ent_t));
+		taskq_destroy(tq);
+		return -EINVAL;
+	}
+
+	splat_vprint(file, SPLAT_TASKQ_TEST1_NAME, "Taskq '%s' waiting\n",
+	           tq_arg.name);
+	taskq_wait(tq);
+	splat_vprint(file, SPLAT_TASKQ_TEST1_NAME, "Taskq '%s' destroying\n",
+	           tq_arg.name);
+
+	kmem_free(tqe, sizeof (taskq_ent_t));
+	taskq_destroy(tq);
+
+	return (tq_arg.flag) ? 0 : -EINVAL;
+}
+
+static int
+splat_taskq_test1(struct file *file, void *arg)
+{
+	int rc;
+
+	rc = splat_taskq_test1_impl(file, arg, B_FALSE);
+	if (rc)
+		return rc;
+
+	rc = splat_taskq_test1_impl(file, arg, B_TRUE);
+
+	return rc;
+}
+
+/*
+ * Create multiple taskq's, each with multiple tasks, wait until
+ * all tasks complete, ensure all tasks ran properly and in the
+ * correct order.  Run order must be the same as the order submitted
+ * because we only have 1 thread per taskq.  Finally cleanup the taskq.
+ */
+static void
+splat_taskq_test2_func1(void *arg)
+{
+	splat_taskq_arg_t *tq_arg = (splat_taskq_arg_t *)arg;
+
+	ASSERT(tq_arg);
+	splat_vprint(tq_arg->file, SPLAT_TASKQ_TEST2_NAME,
+	           "Taskq '%s/%d' function '%s' flag = %d = %d * 2\n",
+	           tq_arg->name, tq_arg->id,
+	           sym2str(splat_taskq_test2_func1),
+	           tq_arg->flag * 2, tq_arg->flag);
+	tq_arg->flag *= 2;
+}
+
+static void
+splat_taskq_test2_func2(void *arg)
+{
+	splat_taskq_arg_t *tq_arg = (splat_taskq_arg_t *)arg;
+
+	ASSERT(tq_arg);
+	splat_vprint(tq_arg->file, SPLAT_TASKQ_TEST2_NAME,
+	           "Taskq '%s/%d' function '%s' flag = %d = %d + 1\n",
+	           tq_arg->name, tq_arg->id,
+	           sym2str(splat_taskq_test2_func2),
+	           tq_arg->flag + 1, tq_arg->flag);
+	tq_arg->flag += 1;
+}
+
+#define TEST2_TASKQS                    8
+#define TEST2_THREADS_PER_TASKQ         1
+
+static int
+splat_taskq_test2_impl(struct file *file, void *arg, boolean_t prealloc) {
+	taskq_t *tq[TEST2_TASKQS] = { NULL };
+	taskqid_t id;
+	splat_taskq_arg_t *tq_args[TEST2_TASKQS] = { NULL };
+	taskq_ent_t *func1_tqes = NULL;
+	taskq_ent_t *func2_tqes = NULL;
+	int i, rc = 0;
+
+	func1_tqes = kmalloc(sizeof(*func1_tqes) * TEST2_TASKQS, GFP_KERNEL);
+	if (func1_tqes == NULL) {
+		rc = -ENOMEM;
+		goto out;
+	}
+
+	func2_tqes = kmalloc(sizeof(*func2_tqes) * TEST2_TASKQS, GFP_KERNEL);
+	if (func2_tqes == NULL) {
+		rc = -ENOMEM;
+		goto out;
+	}
+
+	for (i = 0; i < TEST2_TASKQS; i++) {
+		taskq_init_ent(&func1_tqes[i]);
+		taskq_init_ent(&func2_tqes[i]);
+
+		tq_args[i] = kmalloc(sizeof (splat_taskq_arg_t), GFP_KERNEL);
+		if (tq_args[i] == NULL) {
+			rc = -ENOMEM;
+			break;
+		}
+
+		splat_vprint(file, SPLAT_TASKQ_TEST2_NAME,
+			     "Taskq '%s/%d' creating (%s dispatch)\n",
+			     SPLAT_TASKQ_TEST2_NAME, i,
+			     prealloc ? "prealloc" : "dynamic");
+		if ((tq[i] = taskq_create(SPLAT_TASKQ_TEST2_NAME,
+			                  TEST2_THREADS_PER_TASKQ,
+					  defclsyspri, 50, INT_MAX,
+					  TASKQ_PREPOPULATE)) == NULL) {
+			splat_vprint(file, SPLAT_TASKQ_TEST2_NAME,
+			           "Taskq '%s/%d' create failed\n",
+				   SPLAT_TASKQ_TEST2_NAME, i);
+			rc = -EINVAL;
+			break;
+		}
+
+		tq_args[i]->flag = i;
+		tq_args[i]->id   = i;
+		tq_args[i]->file = file;
+		tq_args[i]->name = SPLAT_TASKQ_TEST2_NAME;
+
+		splat_vprint(file, SPLAT_TASKQ_TEST2_NAME,
+		           "Taskq '%s/%d' function '%s' dispatching\n",
+			   tq_args[i]->name, tq_args[i]->id,
+		           sym2str(splat_taskq_test2_func1));
+		if (prealloc) {
+			taskq_dispatch_ent(tq[i], splat_taskq_test2_func1,
+			    tq_args[i], TQ_SLEEP, &func1_tqes[i]);
+			id = func1_tqes[i].tqent_id;
+		} else {
+			id = taskq_dispatch(tq[i], splat_taskq_test2_func1,
+			    tq_args[i], TQ_SLEEP);
+		}
+
+		if (id == 0) {
+			splat_vprint(file, SPLAT_TASKQ_TEST2_NAME,
+			           "Taskq '%s/%d' function '%s' dispatch "
+			           "failed\n", tq_args[i]->name, tq_args[i]->id,
+			           sym2str(splat_taskq_test2_func1));
+			rc = -EINVAL;
+			break;
+		}
+
+		splat_vprint(file, SPLAT_TASKQ_TEST2_NAME,
+		           "Taskq '%s/%d' function '%s' dispatching\n",
+			   tq_args[i]->name, tq_args[i]->id,
+		           sym2str(splat_taskq_test2_func2));
+		if (prealloc) {
+			taskq_dispatch_ent(tq[i], splat_taskq_test2_func2,
+			    tq_args[i], TQ_SLEEP, &func2_tqes[i]);
+			id = func2_tqes[i].tqent_id;
+		} else {
+			id = taskq_dispatch(tq[i], splat_taskq_test2_func2,
+			    tq_args[i], TQ_SLEEP);
+		}
+
+		if (id == 0) {
+			splat_vprint(file, SPLAT_TASKQ_TEST2_NAME, "Taskq "
+				     "'%s/%d' function '%s' dispatch failed\n",
+			             tq_args[i]->name, tq_args[i]->id,
+			             sym2str(splat_taskq_test2_func2));
+			rc = -EINVAL;
+			break;
+		}
+	}
+
+	/* When rc is set we're effectively just doing cleanup here, so
+	 * ignore new errors in that case.  They just cause noise. */
+	for (i = 0; i < TEST2_TASKQS; i++) {
+		if (tq_args[i] == NULL)
+			continue;
+
+		if (tq[i] != NULL) {
+			splat_vprint(file, SPLAT_TASKQ_TEST2_NAME,
+			           "Taskq '%s/%d' waiting\n",
+			           tq_args[i]->name, tq_args[i]->id);
+			taskq_wait(tq[i]);
+			splat_vprint(file, SPLAT_TASKQ_TEST2_NAME,
+			           "Taskq '%s/%d; destroying\n",
+			          tq_args[i]->name, tq_args[i]->id);
+
+			taskq_destroy(tq[i]);
+
+			if (!rc && tq_args[i]->flag != ((i * 2) + 1)) {
+				splat_vprint(file, SPLAT_TASKQ_TEST2_NAME,
+				           "Taskq '%s/%d' processed tasks "
+				           "out of order; %d != %d\n",
+				           tq_args[i]->name, tq_args[i]->id,
+				           tq_args[i]->flag, i * 2 + 1);
+				rc = -EINVAL;
+			} else {
+				splat_vprint(file, SPLAT_TASKQ_TEST2_NAME,
+				           "Taskq '%s/%d' processed tasks "
+					   "in the correct order; %d == %d\n",
+				           tq_args[i]->name, tq_args[i]->id,
+				           tq_args[i]->flag, i * 2 + 1);
+			}
+
+			kfree(tq_args[i]);
+		}
+	}
+out:
+	if (func1_tqes)
+		kfree(func1_tqes);
+
+	if (func2_tqes)
+		kfree(func2_tqes);
+
+	return rc;
+}
+
+static int
+splat_taskq_test2(struct file *file, void *arg) {
+	int rc;
+
+	rc = splat_taskq_test2_impl(file, arg, B_FALSE);
+	if (rc)
+		return rc;
+
+	rc = splat_taskq_test2_impl(file, arg, B_TRUE);
+
+	return rc;
+}
+
+/*
+ * Use the global system task queue with a single task, wait until task
+ * completes, ensure task ran properly.
+ */
+static int
+splat_taskq_test3_impl(struct file *file, void *arg, boolean_t prealloc)
+{
+	taskqid_t id;
+	splat_taskq_arg_t *tq_arg;
+	taskq_ent_t *tqe;
+	int error;
+
+	tq_arg = kmem_alloc(sizeof (splat_taskq_arg_t), KM_SLEEP);
+	tqe = kmem_alloc(sizeof (taskq_ent_t), KM_SLEEP);
+	taskq_init_ent(tqe);
+
+	tq_arg->flag = 0;
+	tq_arg->id   = 0;
+	tq_arg->file = file;
+	tq_arg->name = SPLAT_TASKQ_TEST3_NAME;
+
+	splat_vprint(file, SPLAT_TASKQ_TEST3_NAME,
+	           "Taskq '%s' function '%s' %s dispatch\n",
+	           tq_arg->name, sym2str(splat_taskq_test13_func),
+		   prealloc ? "prealloc" : "dynamic");
+	if (prealloc) {
+		taskq_dispatch_ent(system_taskq, splat_taskq_test13_func,
+		                   tq_arg, TQ_SLEEP, tqe);
+		id = tqe->tqent_id;
+	} else {
+		id = taskq_dispatch(system_taskq, splat_taskq_test13_func,
+				    tq_arg, TQ_SLEEP);
+	}
+
+	if (id == 0) {
+		splat_vprint(file, SPLAT_TASKQ_TEST3_NAME,
+		           "Taskq '%s' function '%s' dispatch failed\n",
+		           tq_arg->name, sym2str(splat_taskq_test13_func));
+		kmem_free(tqe, sizeof (taskq_ent_t));
+		kmem_free(tq_arg, sizeof (splat_taskq_arg_t));
+		return -EINVAL;
+	}
+
+	splat_vprint(file, SPLAT_TASKQ_TEST3_NAME, "Taskq '%s' waiting\n",
+	           tq_arg->name);
+	taskq_wait(system_taskq);
+
+	error = (tq_arg->flag) ? 0 : -EINVAL;
+
+	kmem_free(tqe, sizeof (taskq_ent_t));
+	kmem_free(tq_arg, sizeof (splat_taskq_arg_t));
+
+	return (error);
+}
+
+static int
+splat_taskq_test3(struct file *file, void *arg)
+{
+	int rc;
+
+	rc = splat_taskq_test3_impl(file, arg, B_FALSE);
+	if (rc)
+		return rc;
+
+	rc = splat_taskq_test3_impl(file, arg, B_TRUE);
+
+	return rc;
+}
+
+/*
+ * Create a taskq and dispatch a large number of tasks to the queue.
+ * Then use taskq_wait() to block until all the tasks complete, then
+ * cross check that all the tasks ran by checking the shared atomic
+ * counter which is incremented in the task function.
+ *
+ * First we try with a large 'maxalloc' value, then we try with a small one.
+ * We should not drop tasks when TQ_SLEEP is used in taskq_dispatch(), even
+ * if the number of pending tasks is above maxalloc.
+ */
+static void
+splat_taskq_test4_func(void *arg)
+{
+	splat_taskq_arg_t *tq_arg = (splat_taskq_arg_t *)arg;
+	ASSERT(tq_arg);
+
+	atomic_inc(tq_arg->count);
+}
+
+static int
+splat_taskq_test4_common(struct file *file, void *arg, int minalloc,
+                         int maxalloc, int nr_tasks, boolean_t prealloc)
+{
+	taskq_t *tq;
+	taskqid_t id;
+	splat_taskq_arg_t tq_arg;
+	taskq_ent_t *tqes;
+	atomic_t count;
+	int i, j, rc = 0;
+
+	tqes = kmalloc(sizeof(*tqes) * nr_tasks, GFP_KERNEL);
+	if (tqes == NULL)
+		return -ENOMEM;
+
+	splat_vprint(file, SPLAT_TASKQ_TEST4_NAME,
+		     "Taskq '%s' creating (%s dispatch) (%d/%d/%d)\n",
+		     SPLAT_TASKQ_TEST4_NAME,
+		     prealloc ? "prealloc" : "dynamic",
+		     minalloc, maxalloc, nr_tasks);
+	if ((tq = taskq_create(SPLAT_TASKQ_TEST4_NAME, 1, defclsyspri,
+		               minalloc, maxalloc, TASKQ_PREPOPULATE)) == NULL) {
+		splat_vprint(file, SPLAT_TASKQ_TEST4_NAME,
+		             "Taskq '%s' create failed\n",
+		             SPLAT_TASKQ_TEST4_NAME);
+		rc = -EINVAL;
+		goto out_free;
+	}
+
+	tq_arg.file = file;
+	tq_arg.name = SPLAT_TASKQ_TEST4_NAME;
+	tq_arg.count = &count;
+
+	for (i = 1; i <= nr_tasks; i *= 2) {
+		atomic_set(tq_arg.count, 0);
+		splat_vprint(file, SPLAT_TASKQ_TEST4_NAME,
+		             "Taskq '%s' function '%s' dispatched %d times\n",
+		             tq_arg.name, sym2str(splat_taskq_test4_func), i);
+
+		for (j = 0; j < i; j++) {
+			taskq_init_ent(&tqes[j]);
+
+			if (prealloc) {
+				taskq_dispatch_ent(tq, splat_taskq_test4_func,
+				                   &tq_arg, TQ_SLEEP, &tqes[j]);
+				id = tqes[j].tqent_id;
+			} else {
+				id = taskq_dispatch(tq, splat_taskq_test4_func,
+						    &tq_arg, TQ_SLEEP);
+			}
+
+			if (id == 0) {
+				splat_vprint(file, SPLAT_TASKQ_TEST4_NAME,
+				        "Taskq '%s' function '%s' dispatch "
+					"%d failed\n", tq_arg.name,
+					sym2str(splat_taskq_test4_func), j);
+					rc = -EINVAL;
+					goto out;
+			}
+		}
+
+		splat_vprint(file, SPLAT_TASKQ_TEST4_NAME, "Taskq '%s' "
+			     "waiting for %d dispatches\n", tq_arg.name, i);
+		taskq_wait(tq);
+		splat_vprint(file, SPLAT_TASKQ_TEST4_NAME, "Taskq '%s' "
+			     "%d/%d dispatches finished\n", tq_arg.name,
+			     atomic_read(&count), i);
+		if (atomic_read(&count) != i) {
+			rc = -ERANGE;
+			goto out;
+
+		}
+	}
+out:
+	splat_vprint(file, SPLAT_TASKQ_TEST4_NAME, "Taskq '%s' destroying\n",
+	           tq_arg.name);
+	taskq_destroy(tq);
+
+out_free:
+	kfree(tqes);
+
+	return rc;
+}
+
+static int
+splat_taskq_test4_impl(struct file *file, void *arg, boolean_t prealloc)
+{
+	int rc;
+
+	rc = splat_taskq_test4_common(file, arg, 50, INT_MAX, 1024, prealloc);
+	if (rc)
+		return rc;
+
+	rc = splat_taskq_test4_common(file, arg, 1, 1, 32, prealloc);
+
+	return rc;
+}
+
+static int
+splat_taskq_test4(struct file *file, void *arg)
+{
+	int rc;
+
+	rc = splat_taskq_test4_impl(file, arg, B_FALSE);
+	if (rc)
+		return rc;
+
+	rc = splat_taskq_test4_impl(file, arg, B_TRUE);
+
+	return rc;
+}
+
+/*
+ * Create a taskq and dispatch a specific sequence of tasks carefully
+ * crafted to validate the order in which tasks are processed.  When
+ * there are multiple worker threads each thread will process the
+ * next pending task as soon as it completes its current task.  This
+ * means that tasks do not strictly complete in order in which they
+ * were dispatched (increasing task id).  This is fine but we need to
+ * verify taskq_wait_outstanding() blocks until the passed task id and
+ * all lower task ids complete.  We do this by dispatching the following
+ * specific sequence of tasks each of which block for N time units.
+ * We then use taskq_wait_outstanding() to unblock at specific task id and
+ * verify the only the expected task ids have completed and in the
+ * correct order.  The two cases of interest are:
+ *
+ * 1) Task ids larger than the waited for task id can run and
+ *    complete as long as there is an available worker thread.
+ * 2) All task ids lower than the waited one must complete before
+ *    unblocking even if the waited task id itself has completed.
+ *
+ * The following table shows each task id and how they will be
+ * scheduled.  Each rows represent one time unit and each column
+ * one of the three worker threads.  The places taskq_wait_outstanding()
+ * must unblock for a specific id are identified as well as the
+ * task ids which must have completed and their order.
+ *
+ *       +-----+       <--- taskq_wait_outstanding(tq, 8) unblocks
+ *       |     |            Required Completion Order: 1,2,4,5,3,8,6,7
+ * +-----+     |
+ * |     |     |
+ * |     |     +-----+
+ * |     |     |  8  |
+ * |     |     +-----+ <--- taskq_wait_outstanding(tq, 3) unblocks
+ * |     |  7  |     |      Required Completion Order: 1,2,4,5,3
+ * |     +-----+     |
+ * |  6  |     |     |
+ * +-----+     |     |
+ * |     |  5  |     |
+ * |     +-----+     |
+ * |  4  |     |     |
+ * +-----+     |     |
+ * |  1  |  2  |  3  |
+ * +-----+-----+-----+
+ *
+ */
+static void
+splat_taskq_test5_func(void *arg)
+{
+	splat_taskq_id_t *tq_id = (splat_taskq_id_t *)arg;
+	splat_taskq_arg_t *tq_arg = tq_id->arg;
+	int factor;
+
+	/* Delays determined by above table */
+	switch (tq_id->id) {
+		default:		factor = 0;	break;
+		case 1: case 8:		factor = 1;	break;
+		case 2: case 4: case 5:	factor = 2;	break;
+		case 6: case 7:		factor = 4;	break;
+		case 3:			factor = 5;	break;
+	}
+
+	msleep(factor * 100);
+	splat_vprint(tq_arg->file, tq_arg->name,
+		     "Taskqid %d complete for taskq '%s'\n",
+		     tq_id->id, tq_arg->name);
+
+	spin_lock(&tq_arg->lock);
+	tq_arg->order[tq_arg->flag] = tq_id->id;
+	tq_arg->flag++;
+	spin_unlock(&tq_arg->lock);
+}
+
+static int
+splat_taskq_test_order(splat_taskq_arg_t *tq_arg, int *order)
+{
+	int i, j;
+
+	for (i = 0; i < SPLAT_TASKQ_ORDER_MAX; i++) {
+		if (tq_arg->order[i] != order[i]) {
+			splat_vprint(tq_arg->file, tq_arg->name,
+				     "Taskq '%s' incorrect completion "
+				     "order\n", tq_arg->name);
+			splat_vprint(tq_arg->file, tq_arg->name,
+				     "%s", "Expected { ");
+
+			for (j = 0; j < SPLAT_TASKQ_ORDER_MAX; j++)
+				splat_print(tq_arg->file, "%d ", order[j]);
+
+			splat_print(tq_arg->file, "%s", "}\n");
+			splat_vprint(tq_arg->file, tq_arg->name,
+				     "%s", "Got      { ");
+
+			for (j = 0; j < SPLAT_TASKQ_ORDER_MAX; j++)
+				splat_print(tq_arg->file, "%d ",
+					    tq_arg->order[j]);
+
+			splat_print(tq_arg->file, "%s", "}\n");
+			return -EILSEQ;
+		}
+	}
+
+	splat_vprint(tq_arg->file, tq_arg->name,
+		     "Taskq '%s' validated correct completion order\n",
+		     tq_arg->name);
+
+	return 0;
+}
+
+static int
+splat_taskq_test5_impl(struct file *file, void *arg, boolean_t prealloc)
+{
+	taskq_t *tq;
+	taskqid_t id;
+	splat_taskq_id_t tq_id[SPLAT_TASKQ_ORDER_MAX];
+	splat_taskq_arg_t tq_arg;
+	int order1[SPLAT_TASKQ_ORDER_MAX] = { 1,2,4,5,3,0,0,0 };
+	int order2[SPLAT_TASKQ_ORDER_MAX] = { 1,2,4,5,3,8,6,7 };
+	taskq_ent_t *tqes;
+	int i, rc = 0;
+
+	tqes = kmem_alloc(sizeof(*tqes) * SPLAT_TASKQ_ORDER_MAX, KM_SLEEP);
+	memset(tqes, 0, sizeof(*tqes) * SPLAT_TASKQ_ORDER_MAX);
+
+	splat_vprint(file, SPLAT_TASKQ_TEST5_NAME,
+		     "Taskq '%s' creating (%s dispatch)\n",
+		     SPLAT_TASKQ_TEST5_NAME,
+		     prealloc ? "prealloc" : "dynamic");
+	if ((tq = taskq_create(SPLAT_TASKQ_TEST5_NAME, 3, defclsyspri,
+		               50, INT_MAX, TASKQ_PREPOPULATE)) == NULL) {
+		splat_vprint(file, SPLAT_TASKQ_TEST5_NAME,
+		             "Taskq '%s' create failed\n",
+		             SPLAT_TASKQ_TEST5_NAME);
+		return -EINVAL;
+	}
+
+	tq_arg.flag = 0;
+	memset(&tq_arg.order, 0, sizeof(int) * SPLAT_TASKQ_ORDER_MAX);
+	spin_lock_init(&tq_arg.lock);
+	tq_arg.file = file;
+	tq_arg.name = SPLAT_TASKQ_TEST5_NAME;
+
+	for (i = 0; i < SPLAT_TASKQ_ORDER_MAX; i++) {
+		taskq_init_ent(&tqes[i]);
+
+		tq_id[i].id = i + 1;
+		tq_id[i].arg = &tq_arg;
+
+		if (prealloc) {
+			taskq_dispatch_ent(tq, splat_taskq_test5_func,
+			               &tq_id[i], TQ_SLEEP, &tqes[i]);
+			id = tqes[i].tqent_id;
+		} else {
+			id = taskq_dispatch(tq, splat_taskq_test5_func,
+					    &tq_id[i], TQ_SLEEP);
+		}
+
+		if (id == 0) {
+			splat_vprint(file, SPLAT_TASKQ_TEST5_NAME,
+			        "Taskq '%s' function '%s' dispatch failed\n",
+				tq_arg.name, sym2str(splat_taskq_test5_func));
+				rc = -EINVAL;
+				goto out;
+		}
+
+		if (tq_id[i].id != id) {
+			splat_vprint(file, SPLAT_TASKQ_TEST5_NAME,
+			        "Taskq '%s' expected taskqid %d got %d\n",
+				tq_arg.name, (int)tq_id[i].id, (int)id);
+				rc = -EINVAL;
+				goto out;
+		}
+	}
+
+	splat_vprint(file, SPLAT_TASKQ_TEST5_NAME, "Taskq '%s' "
+		     "waiting for taskqid %d completion\n", tq_arg.name, 3);
+	taskq_wait_outstanding(tq, 3);
+	if ((rc = splat_taskq_test_order(&tq_arg, order1)))
+		goto out;
+
+	splat_vprint(file, SPLAT_TASKQ_TEST5_NAME, "Taskq '%s' "
+		     "waiting for taskqid %d completion\n", tq_arg.name, 8);
+	taskq_wait_outstanding(tq, 8);
+	rc = splat_taskq_test_order(&tq_arg, order2);
+
+out:
+	splat_vprint(file, SPLAT_TASKQ_TEST5_NAME,
+		     "Taskq '%s' destroying\n", tq_arg.name);
+	taskq_destroy(tq);
+
+	kmem_free(tqes, sizeof(*tqes) * SPLAT_TASKQ_ORDER_MAX);
+
+	return rc;
+}
+
+static int
+splat_taskq_test5(struct file *file, void *arg)
+{
+	int rc;
+
+	rc = splat_taskq_test5_impl(file, arg, B_FALSE);
+	if (rc)
+		return rc;
+
+	rc = splat_taskq_test5_impl(file, arg, B_TRUE);
+
+	return rc;
+}
+
+/*
+ * Create a single task queue with three threads.  Dispatch 8 tasks,
+ * setting TQ_FRONT on only the last three.  Sleep after
+ * dispatching tasks 1-3 to ensure they will run and hold the threads
+ * busy while we dispatch the remaining tasks.  Verify that tasks 6-8
+ * run before task 4-5.
+ *
+ * The following table shows each task id and how they will be
+ * scheduled.  Each rows represent one time unit and each column
+ * one of the three worker threads.
+ *
+ * NB: The Horizontal Line is the LAST Time unit consumed by the Task,
+ *     and must be included in the factor calculation.
+ *  T
+ * 17->       +-----+
+ * 16         | T6  |
+ * 15-> +-----+     |
+ * 14   | T6  |     |
+ * 13-> |     |  5  +-----+
+ * 12   |     |     | T6  |
+ * 11-> |     +-----|     |
+ * 10   |  4  | T6  |     |
+ *  9-> +-----+     |  8  |
+ *  8   | T5  |     |     |
+ *  7-> |     |  7  +-----+
+ *  6   |     |     | T7  |
+ *  5-> |     +-----+     |
+ *  4   |  6  |  T5 |     |
+ *  3-> +-----+     |     |
+ *  2   | T3  |     |     |
+ *  1   |  1  |  2  |  3  |
+ *  0   +-----+-----+-----+
+ *
+ */
+static void
+splat_taskq_test6_func(void *arg)
+{
+        /* Delays determined by above table */
+        static const int factor[SPLAT_TASKQ_ORDER_MAX+1] = {0,3,5,7,6,6,5,6,6};
+
+	splat_taskq_id_t *tq_id = (splat_taskq_id_t *)arg;
+	splat_taskq_arg_t *tq_arg = tq_id->arg;
+
+	splat_vprint(tq_arg->file, tq_arg->name,
+		     "Taskqid %d starting for taskq '%s'\n",
+		     tq_id->id, tq_arg->name);
+
+        if (tq_id->id < SPLAT_TASKQ_ORDER_MAX+1) {
+		msleep(factor[tq_id->id] * 50);
+	}
+
+	spin_lock(&tq_arg->lock);
+	tq_arg->order[tq_arg->flag] = tq_id->id;
+	tq_arg->flag++;
+	spin_unlock(&tq_arg->lock);
+
+	splat_vprint(tq_arg->file, tq_arg->name,
+		     "Taskqid %d complete for taskq '%s'\n",
+		     tq_id->id, tq_arg->name);
+}
+
+static int
+splat_taskq_test6_impl(struct file *file, void *arg, boolean_t prealloc)
+{
+	taskq_t *tq;
+	taskqid_t id;
+	splat_taskq_id_t tq_id[SPLAT_TASKQ_ORDER_MAX];
+	splat_taskq_arg_t tq_arg;
+	int order[SPLAT_TASKQ_ORDER_MAX] = { 1,2,3,6,7,8,4,5 };
+	taskq_ent_t *tqes;
+	int i, rc = 0;
+	uint_t tflags;
+
+	tqes = kmem_alloc(sizeof(*tqes) * SPLAT_TASKQ_ORDER_MAX, KM_SLEEP);
+	memset(tqes, 0, sizeof(*tqes) * SPLAT_TASKQ_ORDER_MAX);
+
+	splat_vprint(file, SPLAT_TASKQ_TEST6_NAME,
+		     "Taskq '%s' creating (%s dispatch)\n",
+		     SPLAT_TASKQ_TEST6_NAME,
+		     prealloc ? "prealloc" : "dynamic");
+	if ((tq = taskq_create(SPLAT_TASKQ_TEST6_NAME, 3, defclsyspri,
+		               50, INT_MAX, TASKQ_PREPOPULATE)) == NULL) {
+		splat_vprint(file, SPLAT_TASKQ_TEST6_NAME,
+		             "Taskq '%s' create failed\n",
+		             SPLAT_TASKQ_TEST6_NAME);
+		return -EINVAL;
+	}
+
+	tq_arg.flag = 0;
+	memset(&tq_arg.order, 0, sizeof(int) * SPLAT_TASKQ_ORDER_MAX);
+	spin_lock_init(&tq_arg.lock);
+	tq_arg.file = file;
+	tq_arg.name = SPLAT_TASKQ_TEST6_NAME;
+
+	for (i = 0; i < SPLAT_TASKQ_ORDER_MAX; i++) {
+		taskq_init_ent(&tqes[i]);
+
+		tq_id[i].id = i + 1;
+		tq_id[i].arg = &tq_arg;
+		tflags = TQ_SLEEP;
+		if (i > 4)
+			tflags |= TQ_FRONT;
+
+		if (prealloc) {
+			taskq_dispatch_ent(tq, splat_taskq_test6_func,
+			                   &tq_id[i], tflags, &tqes[i]);
+			id = tqes[i].tqent_id;
+		} else {
+			id = taskq_dispatch(tq, splat_taskq_test6_func,
+					    &tq_id[i], tflags);
+		}
+
+		if (id == 0) {
+			splat_vprint(file, SPLAT_TASKQ_TEST6_NAME,
+			        "Taskq '%s' function '%s' dispatch failed\n",
+				tq_arg.name, sym2str(splat_taskq_test6_func));
+				rc = -EINVAL;
+				goto out;
+		}
+
+		if (tq_id[i].id != id) {
+			splat_vprint(file, SPLAT_TASKQ_TEST6_NAME,
+			        "Taskq '%s' expected taskqid %d got %d\n",
+				tq_arg.name, (int)tq_id[i].id, (int)id);
+				rc = -EINVAL;
+				goto out;
+		}
+		/* Sleep to let tasks 1-3 start executing. */
+		if ( i == 2 )
+			msleep(100);
+	}
+
+	splat_vprint(file, SPLAT_TASKQ_TEST6_NAME, "Taskq '%s' "
+		     "waiting for taskqid %d completion\n", tq_arg.name,
+		     SPLAT_TASKQ_ORDER_MAX);
+	taskq_wait_outstanding(tq, SPLAT_TASKQ_ORDER_MAX);
+	rc = splat_taskq_test_order(&tq_arg, order);
+
+out:
+	splat_vprint(file, SPLAT_TASKQ_TEST6_NAME,
+		     "Taskq '%s' destroying\n", tq_arg.name);
+	taskq_destroy(tq);
+
+	kmem_free(tqes, sizeof(*tqes) * SPLAT_TASKQ_ORDER_MAX);
+
+	return rc;
+}
+
+static int
+splat_taskq_test6(struct file *file, void *arg)
+{
+	int rc;
+
+	rc = splat_taskq_test6_impl(file, arg, B_FALSE);
+	if (rc)
+		return rc;
+
+	rc = splat_taskq_test6_impl(file, arg, B_TRUE);
+
+	return rc;
+}
+
+static void
+splat_taskq_test7_func(void *arg)
+{
+	splat_taskq_arg_t *tq_arg = (splat_taskq_arg_t *)arg;
+	taskqid_t id;
+
+	ASSERT(tq_arg);
+
+	if (tq_arg->depth >= SPLAT_TASKQ_DEPTH_MAX)
+		return;
+
+	tq_arg->depth++;
+
+	splat_vprint(tq_arg->file, SPLAT_TASKQ_TEST7_NAME,
+	             "Taskq '%s' function '%s' dispatching (depth = %u)\n",
+	             tq_arg->name, sym2str(splat_taskq_test7_func),
+	             tq_arg->depth);
+
+	if (tq_arg->tqe) {
+		VERIFY(taskq_empty_ent(tq_arg->tqe));
+		taskq_dispatch_ent(tq_arg->tq, splat_taskq_test7_func,
+		                   tq_arg, TQ_SLEEP, tq_arg->tqe);
+		id = tq_arg->tqe->tqent_id;
+	} else {
+		id = taskq_dispatch(tq_arg->tq, splat_taskq_test7_func,
+		                    tq_arg, TQ_SLEEP);
+	}
+
+	if (id == 0) {
+		splat_vprint(tq_arg->file, SPLAT_TASKQ_TEST7_NAME,
+		             "Taskq '%s' function '%s' dispatch failed "
+		             "(depth = %u)\n", tq_arg->name,
+		             sym2str(splat_taskq_test7_func), tq_arg->depth);
+		tq_arg->flag = -EINVAL;
+		return;
+	}
+}
+
+static int
+splat_taskq_test7_impl(struct file *file, void *arg, boolean_t prealloc)
+{
+	taskq_t *tq;
+	splat_taskq_arg_t *tq_arg;
+	taskq_ent_t *tqe;
+	int error;
+
+	splat_vprint(file, SPLAT_TASKQ_TEST7_NAME,
+	             "Taskq '%s' creating (%s dispatch)\n",
+	             SPLAT_TASKQ_TEST7_NAME,
+	             prealloc ? "prealloc" :  "dynamic");
+	if ((tq = taskq_create(SPLAT_TASKQ_TEST7_NAME, 1, defclsyspri,
+	                       50, INT_MAX, TASKQ_PREPOPULATE)) == NULL) {
+		splat_vprint(file, SPLAT_TASKQ_TEST7_NAME,
+		             "Taskq '%s' create failed\n",
+		             SPLAT_TASKQ_TEST7_NAME);
+		return -EINVAL;
+	}
+
+	tq_arg = kmem_alloc(sizeof (splat_taskq_arg_t), KM_SLEEP);
+	tqe = kmem_alloc(sizeof (taskq_ent_t), KM_SLEEP);
+
+	tq_arg->depth = 0;
+	tq_arg->flag  = 0;
+	tq_arg->id    = 0;
+	tq_arg->file  = file;
+	tq_arg->name  = SPLAT_TASKQ_TEST7_NAME;
+	tq_arg->tq    = tq;
+
+	if (prealloc) {
+		taskq_init_ent(tqe);
+		tq_arg->tqe = tqe;
+	} else {
+		tq_arg->tqe = NULL;
+	}
+
+	splat_taskq_test7_func(tq_arg);
+
+	if (tq_arg->flag == 0) {
+		splat_vprint(file, SPLAT_TASKQ_TEST7_NAME,
+		             "Taskq '%s' waiting\n", tq_arg->name);
+		taskq_wait_outstanding(tq, SPLAT_TASKQ_DEPTH_MAX);
+	}
+
+	error = (tq_arg->depth == SPLAT_TASKQ_DEPTH_MAX ? 0 : -EINVAL);
+
+	kmem_free(tqe, sizeof (taskq_ent_t));
+	kmem_free(tq_arg, sizeof (splat_taskq_arg_t));
+
+	splat_vprint(file, SPLAT_TASKQ_TEST7_NAME,
+	              "Taskq '%s' destroying\n", tq_arg->name);
+	taskq_destroy(tq);
+
+	return (error);
+}
+
+static int
+splat_taskq_test7(struct file *file, void *arg)
+{
+	int rc;
+
+	rc = splat_taskq_test7_impl(file, arg, B_FALSE);
+	if (rc)
+		return (rc);
+
+	rc = splat_taskq_test7_impl(file, arg, B_TRUE);
+
+	return (rc);
+}
+
+static void
+splat_taskq_throughput_func(void *arg)
+{
+	splat_taskq_arg_t *tq_arg = (splat_taskq_arg_t *)arg;
+	ASSERT(tq_arg);
+
+	atomic_inc(tq_arg->count);
+}
+
+static int
+splat_taskq_throughput(struct file *file, void *arg, const char *name,
+    int nthreads, int minalloc, int maxalloc, int flags, int tasks,
+    struct timespec *delta)
+{
+	taskq_t *tq;
+	taskqid_t id;
+	splat_taskq_arg_t tq_arg;
+	taskq_ent_t **tqes;
+	atomic_t count;
+	struct timespec start, stop;
+	int i, j, rc = 0;
+
+	tqes = vmalloc(sizeof (*tqes) * tasks);
+	if (tqes == NULL)
+		return (-ENOMEM);
+
+	memset(tqes, 0, sizeof (*tqes) * tasks);
+
+	splat_vprint(file, name, "Taskq '%s' creating (%d/%d/%d/%d)\n",
+	    name, nthreads, minalloc, maxalloc, tasks);
+	if ((tq = taskq_create(name, nthreads, defclsyspri,
+	    minalloc, maxalloc, flags)) == NULL) {
+		splat_vprint(file, name, "Taskq '%s' create failed\n", name);
+		rc = -EINVAL;
+		goto out_free;
+	}
+
+	tq_arg.file = file;
+	tq_arg.name = name;
+	tq_arg.count = &count;
+	atomic_set(tq_arg.count, 0);
+
+	getnstimeofday(&start);
+
+	for (i = 0; i < tasks; i++) {
+		tqes[i] = kmalloc(sizeof (taskq_ent_t), GFP_KERNEL);
+		if (tqes[i] == NULL) {
+			rc = -ENOMEM;
+			goto out;
+		}
+
+		taskq_init_ent(tqes[i]);
+		taskq_dispatch_ent(tq, splat_taskq_throughput_func,
+		    &tq_arg, TQ_SLEEP, tqes[i]);
+		id = tqes[i]->tqent_id;
+
+		if (id == 0) {
+			splat_vprint(file, name, "Taskq '%s' function '%s' "
+			    "dispatch %d failed\n", tq_arg.name,
+			    sym2str(splat_taskq_throughput_func), i);
+			rc = -EINVAL;
+			goto out;
+		}
+	}
+
+	splat_vprint(file, name, "Taskq '%s' waiting for %d dispatches\n",
+	    tq_arg.name, tasks);
+
+	taskq_wait(tq);
+
+	if (delta != NULL) {
+		getnstimeofday(&stop);
+		*delta = timespec_sub(stop, start);
+	}
+
+	splat_vprint(file, name, "Taskq '%s' %d/%d dispatches finished\n",
+	    tq_arg.name, atomic_read(tq_arg.count), tasks);
+
+	if (atomic_read(tq_arg.count) != tasks)
+		rc = -ERANGE;
+
+out:
+	splat_vprint(file, name, "Taskq '%s' destroying\n", tq_arg.name);
+	taskq_destroy(tq);
+out_free:
+	for (j = 0; j < tasks && tqes[j] != NULL; j++)
+		kfree(tqes[j]);
+
+	vfree(tqes);
+
+	return (rc);
+}
+
+/*
+ * Create a taskq with 100 threads and dispatch a huge number of trivial
+ * tasks to generate contention on tq->tq_lock.  This test should always
+ * pass.  The purpose is to provide a benchmark for measuring the
+ * effectiveness of taskq optimizations.
+ */
+#define	TEST8_NUM_TASKS			0x20000
+#define	TEST8_THREADS_PER_TASKQ		100
+
+static int
+splat_taskq_test8(struct file *file, void *arg)
+{
+	return (splat_taskq_throughput(file, arg,
+	    SPLAT_TASKQ_TEST8_NAME, TEST8_THREADS_PER_TASKQ,
+	    1, INT_MAX, TASKQ_PREPOPULATE, TEST8_NUM_TASKS, NULL));
+}
+
+/*
+ * Create a taskq and dispatch a number of delayed tasks to the queue.
+ * For each task verify that it was run no early than requested.
+ */
+static void
+splat_taskq_test9_func(void *arg)
+{
+	splat_taskq_arg_t *tq_arg = (splat_taskq_arg_t *)arg;
+	ASSERT(tq_arg);
+
+	if (ddi_time_after_eq(ddi_get_lbolt(), tq_arg->expire))
+		atomic_inc(tq_arg->count);
+
+	kmem_free(tq_arg, sizeof(splat_taskq_arg_t));
+}
+
+static int
+splat_taskq_test9(struct file *file, void *arg)
+{
+	taskq_t *tq;
+	atomic_t count;
+	int i, rc = 0;
+	int minalloc = 1;
+	int maxalloc = 10;
+	int nr_tasks = 100;
+
+	splat_vprint(file, SPLAT_TASKQ_TEST9_NAME,
+	    "Taskq '%s' creating (%s dispatch) (%d/%d/%d)\n",
+	    SPLAT_TASKQ_TEST9_NAME, "delay", minalloc, maxalloc, nr_tasks);
+	if ((tq = taskq_create(SPLAT_TASKQ_TEST9_NAME, 3, defclsyspri,
+	    minalloc, maxalloc, TASKQ_PREPOPULATE)) == NULL) {
+		splat_vprint(file, SPLAT_TASKQ_TEST9_NAME,
+		    "Taskq '%s' create failed\n", SPLAT_TASKQ_TEST9_NAME);
+		return -EINVAL;
+	}
+
+	atomic_set(&count, 0);
+
+	for (i = 1; i <= nr_tasks; i++) {
+		splat_taskq_arg_t *tq_arg;
+		taskqid_t id;
+		uint32_t rnd;
+
+		/* A random timeout in jiffies of at most 5 seconds */
+		get_random_bytes((void *)&rnd, 4);
+		rnd = rnd % (5 * HZ);
+
+		tq_arg = kmem_alloc(sizeof(splat_taskq_arg_t), KM_SLEEP);
+		tq_arg->file = file;
+		tq_arg->name = SPLAT_TASKQ_TEST9_NAME;
+		tq_arg->expire = ddi_get_lbolt() + rnd;
+		tq_arg->count = &count;
+
+		splat_vprint(file, SPLAT_TASKQ_TEST9_NAME,
+		    "Taskq '%s' delay dispatch %u jiffies\n",
+		    SPLAT_TASKQ_TEST9_NAME, rnd);
+
+		id = taskq_dispatch_delay(tq, splat_taskq_test9_func,
+		    tq_arg, TQ_SLEEP, ddi_get_lbolt() + rnd);
+
+		if (id == 0) {
+			splat_vprint(file, SPLAT_TASKQ_TEST9_NAME,
+			   "Taskq '%s' delay dispatch failed\n",
+			   SPLAT_TASKQ_TEST9_NAME);
+			kmem_free(tq_arg, sizeof(splat_taskq_arg_t));
+			taskq_wait(tq);
+			rc = -EINVAL;
+			goto out;
+		}
+	}
+
+	splat_vprint(file, SPLAT_TASKQ_TEST9_NAME, "Taskq '%s' waiting for "
+	    "%d delay dispatches\n", SPLAT_TASKQ_TEST9_NAME, nr_tasks);
+
+	taskq_wait(tq);
+	if (atomic_read(&count) != nr_tasks)
+		rc = -ERANGE;
+
+	splat_vprint(file, SPLAT_TASKQ_TEST9_NAME, "Taskq '%s' %d/%d delay "
+	    "dispatches finished on time\n", SPLAT_TASKQ_TEST9_NAME,
+	    atomic_read(&count), nr_tasks);
+	splat_vprint(file, SPLAT_TASKQ_TEST9_NAME, "Taskq '%s' destroying\n",
+	    SPLAT_TASKQ_TEST9_NAME);
+out:
+	taskq_destroy(tq);
+
+	return rc;
+}
+
+/*
+ * Create a taskq and dispatch then cancel tasks in the queue.
+ */
+static void
+splat_taskq_test10_func(void *arg)
+{
+	splat_taskq_arg_t *tq_arg = (splat_taskq_arg_t *)arg;
+	uint8_t rnd;
+
+	if (ddi_time_after_eq(ddi_get_lbolt(), tq_arg->expire))
+		atomic_inc(tq_arg->count);
+
+	/* Randomly sleep to further perturb the system */
+	get_random_bytes((void *)&rnd, 1);
+	msleep(1 + (rnd % 9));
+}
+
+static int
+splat_taskq_test10(struct file *file, void *arg)
+{
+	taskq_t *tq;
+	splat_taskq_arg_t **tqas;
+	atomic_t count;
+	int i, j, rc = 0;
+	int minalloc = 1;
+	int maxalloc = 10;
+	int nr_tasks = 100;
+	int canceled = 0;
+	int completed = 0;
+	int blocked = 0;
+	clock_t start, cancel;
+
+	tqas = vmalloc(sizeof(*tqas) * nr_tasks);
+	if (tqas == NULL)
+		return -ENOMEM;
+        memset(tqas, 0, sizeof(*tqas) * nr_tasks);
+
+	splat_vprint(file, SPLAT_TASKQ_TEST10_NAME,
+	    "Taskq '%s' creating (%s dispatch) (%d/%d/%d)\n",
+	    SPLAT_TASKQ_TEST10_NAME, "delay", minalloc, maxalloc, nr_tasks);
+	if ((tq = taskq_create(SPLAT_TASKQ_TEST10_NAME, 3, defclsyspri,
+	    minalloc, maxalloc, TASKQ_PREPOPULATE)) == NULL) {
+		splat_vprint(file, SPLAT_TASKQ_TEST10_NAME,
+		    "Taskq '%s' create failed\n", SPLAT_TASKQ_TEST10_NAME);
+		rc = -EINVAL;
+		goto out_free;
+	}
+
+	atomic_set(&count, 0);
+
+	for (i = 0; i < nr_tasks; i++) {
+		splat_taskq_arg_t *tq_arg;
+		uint32_t rnd;
+
+		/* A random timeout in jiffies of at most 5 seconds */
+		get_random_bytes((void *)&rnd, 4);
+		rnd = rnd % (5 * HZ);
+
+		tq_arg = kmem_alloc(sizeof(splat_taskq_arg_t), KM_SLEEP);
+		tq_arg->file = file;
+		tq_arg->name = SPLAT_TASKQ_TEST10_NAME;
+		tq_arg->count = &count;
+		tqas[i] = tq_arg;
+
+		/*
+		 * Dispatch every 1/3 one immediately to mix it up, the cancel
+		 * code is inherently racy and we want to try and provoke any
+		 * subtle concurrently issues.
+		 */
+		if ((i % 3) == 0) {
+			tq_arg->expire = ddi_get_lbolt();
+			tq_arg->id = taskq_dispatch(tq, splat_taskq_test10_func,
+			    tq_arg, TQ_SLEEP);
+		} else {
+			tq_arg->expire = ddi_get_lbolt() + rnd;
+			tq_arg->id = taskq_dispatch_delay(tq,
+			    splat_taskq_test10_func,
+			    tq_arg, TQ_SLEEP, ddi_get_lbolt() + rnd);
+		}
+
+		if (tq_arg->id == 0) {
+			splat_vprint(file, SPLAT_TASKQ_TEST10_NAME,
+			   "Taskq '%s' dispatch failed\n",
+			   SPLAT_TASKQ_TEST10_NAME);
+			kmem_free(tq_arg, sizeof(splat_taskq_arg_t));
+			taskq_wait(tq);
+			rc = -EINVAL;
+			goto out;
+		} else {
+			splat_vprint(file, SPLAT_TASKQ_TEST10_NAME,
+			    "Taskq '%s' dispatch %lu in %lu jiffies\n",
+			    SPLAT_TASKQ_TEST10_NAME, (unsigned long)tq_arg->id,
+			    !(i % 3) ? 0 : tq_arg->expire - ddi_get_lbolt());
+		}
+	}
+
+	/*
+	 * Start randomly canceling tasks for the duration of the test.  We
+	 * happen to know the valid task id's will be in the range 1..nr_tasks
+	 * because the taskq is private and was just created.  However, we
+	 * have no idea of a particular task has already executed or not.
+	 */
+	splat_vprint(file, SPLAT_TASKQ_TEST10_NAME, "Taskq '%s' randomly "
+	    "canceling task ids\n", SPLAT_TASKQ_TEST10_NAME);
+
+	start = ddi_get_lbolt();
+	i = 0;
+
+	while (ddi_time_before(ddi_get_lbolt(), start + 5 * HZ)) {
+		taskqid_t id;
+		uint32_t rnd;
+
+		i++;
+		cancel = ddi_get_lbolt();
+		get_random_bytes((void *)&rnd, 4);
+		id = 1 + (rnd % nr_tasks);
+		rc = taskq_cancel_id(tq, id);
+
+		/*
+		 * Keep track of the results of the random cancels.
+		 */
+		if (rc == 0) {
+			canceled++;
+		} else if (rc == ENOENT) {
+			completed++;
+		} else if (rc == EBUSY) {
+			blocked++;
+		} else {
+			rc = -EINVAL;
+			break;
+		}
+
+		/*
+		 * Verify we never get blocked to long in taskq_cancel_id().
+		 * The worst case is 10ms if we happen to cancel the task
+		 * which is currently executing.  We allow a factor of 2x.
+		 */
+		if (ddi_get_lbolt() - cancel > HZ / 50) {
+			splat_vprint(file, SPLAT_TASKQ_TEST10_NAME,
+			    "Taskq '%s' cancel for %lu took %lu\n",
+			    SPLAT_TASKQ_TEST10_NAME, (unsigned long)id,
+			    ddi_get_lbolt() - cancel);
+			rc = -ETIMEDOUT;
+			break;
+		}
+
+		get_random_bytes((void *)&rnd, 4);
+		msleep(1 + (rnd % 100));
+		rc = 0;
+	}
+
+	taskq_wait(tq);
+
+	/*
+	 * Cross check the results of taskq_cancel_id() with the number of
+	 * times the dispatched function actually ran successfully.
+	 */
+	if ((rc == 0) && (nr_tasks - canceled != atomic_read(&count)))
+		rc = -EDOM;
+
+	splat_vprint(file, SPLAT_TASKQ_TEST10_NAME, "Taskq '%s' %d attempts, "
+	    "%d canceled, %d completed, %d blocked, %d/%d tasks run\n",
+	    SPLAT_TASKQ_TEST10_NAME, i, canceled, completed, blocked,
+	    atomic_read(&count), nr_tasks);
+	splat_vprint(file, SPLAT_TASKQ_TEST10_NAME, "Taskq '%s' destroying %d\n",
+	    SPLAT_TASKQ_TEST10_NAME, rc);
+out:
+	taskq_destroy(tq);
+out_free:
+	for (j = 0; j < nr_tasks && tqas[j] != NULL; j++)
+		kmem_free(tqas[j], sizeof(splat_taskq_arg_t));
+	vfree(tqas);
+
+	return rc;
+}
+
+/*
+ * Create a dynamic taskq with 100 threads and dispatch a huge number of
+ * trivial tasks.  This will cause the taskq to grow quickly to its max
+ * thread count.  This test should always pass.  The purpose is to provide
+ * a benchmark for measuring the performance of dynamic taskqs.
+ */
+#define	TEST11_NUM_TASKS			100000
+#define	TEST11_THREADS_PER_TASKQ		100
+
+static int
+splat_taskq_test11(struct file *file, void *arg)
+{
+	struct timespec normal, dynamic;
+	int error;
+
+	error = splat_taskq_throughput(file, arg, SPLAT_TASKQ_TEST11_NAME,
+	    TEST11_THREADS_PER_TASKQ, 1, INT_MAX,
+	    TASKQ_PREPOPULATE, TEST11_NUM_TASKS, &normal);
+	if (error)
+		return (error);
+
+	error = splat_taskq_throughput(file, arg, SPLAT_TASKQ_TEST11_NAME,
+	    TEST11_THREADS_PER_TASKQ, 1, INT_MAX,
+	    TASKQ_PREPOPULATE | TASKQ_DYNAMIC, TEST11_NUM_TASKS, &dynamic);
+	if (error)
+		return (error);
+
+	splat_vprint(file, SPLAT_TASKQ_TEST11_NAME,
+	    "Timing taskq_wait(): normal=%ld.%09lds, dynamic=%ld.%09lds\n",
+	    normal.tv_sec, normal.tv_nsec,
+	    dynamic.tv_sec, dynamic.tv_nsec);
+
+	/* A 10x increase in runtime is used to indicate a core problem. */
+	if ((dynamic.tv_sec * NANOSEC + dynamic.tv_nsec) >
+	    ((normal.tv_sec * NANOSEC + normal.tv_nsec) * 10))
+		error = -ETIME;
+
+	return (error);
+}
+
+splat_subsystem_t *
+splat_taskq_init(void)
+{
+        splat_subsystem_t *sub;
+
+        sub = kmalloc(sizeof(*sub), GFP_KERNEL);
+        if (sub == NULL)
+                return NULL;
+
+        memset(sub, 0, sizeof(*sub));
+        strncpy(sub->desc.name, SPLAT_TASKQ_NAME, SPLAT_NAME_SIZE);
+        strncpy(sub->desc.desc, SPLAT_TASKQ_DESC, SPLAT_DESC_SIZE);
+        INIT_LIST_HEAD(&sub->subsystem_list);
+	INIT_LIST_HEAD(&sub->test_list);
+	spin_lock_init(&sub->test_lock);
+        sub->desc.id = SPLAT_SUBSYSTEM_TASKQ;
+
+	SPLAT_TEST_INIT(sub, SPLAT_TASKQ_TEST1_NAME, SPLAT_TASKQ_TEST1_DESC,
+	              SPLAT_TASKQ_TEST1_ID, splat_taskq_test1);
+	SPLAT_TEST_INIT(sub, SPLAT_TASKQ_TEST2_NAME, SPLAT_TASKQ_TEST2_DESC,
+	              SPLAT_TASKQ_TEST2_ID, splat_taskq_test2);
+	SPLAT_TEST_INIT(sub, SPLAT_TASKQ_TEST3_NAME, SPLAT_TASKQ_TEST3_DESC,
+	              SPLAT_TASKQ_TEST3_ID, splat_taskq_test3);
+	SPLAT_TEST_INIT(sub, SPLAT_TASKQ_TEST4_NAME, SPLAT_TASKQ_TEST4_DESC,
+	              SPLAT_TASKQ_TEST4_ID, splat_taskq_test4);
+	SPLAT_TEST_INIT(sub, SPLAT_TASKQ_TEST5_NAME, SPLAT_TASKQ_TEST5_DESC,
+	              SPLAT_TASKQ_TEST5_ID, splat_taskq_test5);
+	SPLAT_TEST_INIT(sub, SPLAT_TASKQ_TEST6_NAME, SPLAT_TASKQ_TEST6_DESC,
+	              SPLAT_TASKQ_TEST6_ID, splat_taskq_test6);
+	SPLAT_TEST_INIT(sub, SPLAT_TASKQ_TEST7_NAME, SPLAT_TASKQ_TEST7_DESC,
+	              SPLAT_TASKQ_TEST7_ID, splat_taskq_test7);
+	SPLAT_TEST_INIT(sub, SPLAT_TASKQ_TEST8_NAME, SPLAT_TASKQ_TEST8_DESC,
+	              SPLAT_TASKQ_TEST8_ID, splat_taskq_test8);
+	SPLAT_TEST_INIT(sub, SPLAT_TASKQ_TEST9_NAME, SPLAT_TASKQ_TEST9_DESC,
+	              SPLAT_TASKQ_TEST9_ID, splat_taskq_test9);
+	SPLAT_TEST_INIT(sub, SPLAT_TASKQ_TEST10_NAME, SPLAT_TASKQ_TEST10_DESC,
+	              SPLAT_TASKQ_TEST10_ID, splat_taskq_test10);
+	SPLAT_TEST_INIT(sub, SPLAT_TASKQ_TEST11_NAME, SPLAT_TASKQ_TEST11_DESC,
+	              SPLAT_TASKQ_TEST11_ID, splat_taskq_test11);
+
+        return sub;
+}
+
+void
+splat_taskq_fini(splat_subsystem_t *sub)
+{
+        ASSERT(sub);
+	SPLAT_TEST_FINI(sub, SPLAT_TASKQ_TEST11_ID);
+	SPLAT_TEST_FINI(sub, SPLAT_TASKQ_TEST10_ID);
+	SPLAT_TEST_FINI(sub, SPLAT_TASKQ_TEST9_ID);
+	SPLAT_TEST_FINI(sub, SPLAT_TASKQ_TEST8_ID);
+	SPLAT_TEST_FINI(sub, SPLAT_TASKQ_TEST7_ID);
+	SPLAT_TEST_FINI(sub, SPLAT_TASKQ_TEST6_ID);
+	SPLAT_TEST_FINI(sub, SPLAT_TASKQ_TEST5_ID);
+	SPLAT_TEST_FINI(sub, SPLAT_TASKQ_TEST4_ID);
+	SPLAT_TEST_FINI(sub, SPLAT_TASKQ_TEST3_ID);
+	SPLAT_TEST_FINI(sub, SPLAT_TASKQ_TEST2_ID);
+	SPLAT_TEST_FINI(sub, SPLAT_TASKQ_TEST1_ID);
+
+        kfree(sub);
+}
+
+int
+splat_taskq_id(void) {
+        return SPLAT_SUBSYSTEM_TASKQ;
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/module/splat/splat-thread.c
@@ -0,0 +1,389 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+ *****************************************************************************
+ *  Solaris Porting LAyer Tests (SPLAT) Thread Tests.
+\*****************************************************************************/
+
+#include <sys/thread.h>
+#include <sys/random.h>
+#include <linux/delay.h>
+#include <linux/mm_compat.h>
+#include <linux/slab.h>
+#include "splat-internal.h"
+
+#define SPLAT_THREAD_NAME		"thread"
+#define SPLAT_THREAD_DESC		"Kernel Thread Tests"
+
+#define SPLAT_THREAD_TEST1_ID		0x0601
+#define SPLAT_THREAD_TEST1_NAME		"create"
+#define SPLAT_THREAD_TEST1_DESC		"Validate thread creation"
+
+#define SPLAT_THREAD_TEST2_ID		0x0602
+#define SPLAT_THREAD_TEST2_NAME		"exit"
+#define SPLAT_THREAD_TEST2_DESC		"Validate thread exit"
+
+#define SPLAT_THREAD_TEST3_ID		0x6003
+#define SPLAT_THREAD_TEST3_NAME		"tsd"
+#define SPLAT_THREAD_TEST3_DESC		"Validate thread specific data"
+
+#define SPLAT_THREAD_TEST_MAGIC		0x4488CC00UL
+#define SPLAT_THREAD_TEST_KEYS		32
+#define SPLAT_THREAD_TEST_THREADS	16
+
+typedef struct thread_priv {
+        unsigned long tp_magic;
+        struct file *tp_file;
+        spinlock_t tp_lock;
+        wait_queue_head_t tp_waitq;
+	uint_t tp_keys[SPLAT_THREAD_TEST_KEYS];
+	int tp_rc;
+	int tp_count;
+	int tp_dtor_count;
+} thread_priv_t;
+
+static int
+splat_thread_rc(thread_priv_t *tp, int rc)
+{
+	int ret;
+
+	spin_lock(&tp->tp_lock);
+	ret = (tp->tp_rc == rc);
+	spin_unlock(&tp->tp_lock);
+
+	return ret;
+}
+
+static int
+splat_thread_count(thread_priv_t *tp, int count)
+{
+	int ret;
+
+	spin_lock(&tp->tp_lock);
+	ret = (tp->tp_count == count);
+	spin_unlock(&tp->tp_lock);
+
+	return ret;
+}
+
+static void
+splat_thread_work1(void *priv)
+{
+	thread_priv_t *tp = (thread_priv_t *)priv;
+
+	spin_lock(&tp->tp_lock);
+	ASSERT(tp->tp_magic == SPLAT_THREAD_TEST_MAGIC);
+	tp->tp_rc = 1;
+	wake_up(&tp->tp_waitq);
+	spin_unlock(&tp->tp_lock);
+
+	thread_exit();
+}
+
+static int
+splat_thread_test1(struct file *file, void *arg)
+{
+	thread_priv_t tp;
+	kthread_t *thr;
+
+	tp.tp_magic = SPLAT_THREAD_TEST_MAGIC;
+	tp.tp_file = file;
+        spin_lock_init(&tp.tp_lock);
+	init_waitqueue_head(&tp.tp_waitq);
+	tp.tp_rc = 0;
+
+	thr = (kthread_t *)thread_create(NULL, 0, splat_thread_work1, &tp, 0,
+			                 &p0, TS_RUN, defclsyspri);
+	/* Must never fail under Solaris, but we check anyway since this
+	 * can happen in the linux SPL, we may want to change this behavior */
+	if (thr == NULL)
+		return  -ESRCH;
+
+	/* Sleep until the thread sets tp.tp_rc == 1 */
+	wait_event(tp.tp_waitq, splat_thread_rc(&tp, 1));
+
+        splat_vprint(file, SPLAT_THREAD_TEST1_NAME, "%s",
+	           "Thread successfully started properly\n");
+	return 0;
+}
+
+static void
+splat_thread_work2(void *priv)
+{
+	thread_priv_t *tp = (thread_priv_t *)priv;
+
+	spin_lock(&tp->tp_lock);
+	ASSERT(tp->tp_magic == SPLAT_THREAD_TEST_MAGIC);
+	tp->tp_rc = 1;
+	wake_up(&tp->tp_waitq);
+	spin_unlock(&tp->tp_lock);
+
+	thread_exit();
+
+	/* The following code is unreachable when thread_exit() is
+	 * working properly, which is exactly what we're testing */
+	spin_lock(&tp->tp_lock);
+	tp->tp_rc = 2;
+	wake_up(&tp->tp_waitq);
+	spin_unlock(&tp->tp_lock);
+}
+
+static int
+splat_thread_test2(struct file *file, void *arg)
+{
+	thread_priv_t tp;
+	kthread_t *thr;
+	int rc = 0;
+
+	tp.tp_magic = SPLAT_THREAD_TEST_MAGIC;
+	tp.tp_file = file;
+        spin_lock_init(&tp.tp_lock);
+	init_waitqueue_head(&tp.tp_waitq);
+	tp.tp_rc = 0;
+
+	thr = (kthread_t *)thread_create(NULL, 0, splat_thread_work2, &tp, 0,
+			                 &p0, TS_RUN, defclsyspri);
+	/* Must never fail under Solaris, but we check anyway since this
+	 * can happen in the linux SPL, we may want to change this behavior */
+	if (thr == NULL)
+		return -ESRCH;
+
+	/* Sleep until the thread sets tp.tp_rc == 1 */
+	wait_event(tp.tp_waitq, splat_thread_rc(&tp, 1));
+
+	/* Sleep until the thread sets tp.tp_rc == 2, or until we hit
+	 * the timeout.  If thread exit is working properly we should
+	 * hit the timeout and never see to.tp_rc == 2. */
+	rc = wait_event_timeout(tp.tp_waitq, splat_thread_rc(&tp, 2), HZ / 10);
+	if (rc > 0) {
+		rc = -EINVAL;
+	        splat_vprint(file, SPLAT_THREAD_TEST2_NAME, "%s",
+		           "Thread did not exit properly at thread_exit()\n");
+	} else {
+	        splat_vprint(file, SPLAT_THREAD_TEST2_NAME, "%s",
+		           "Thread successfully exited at thread_exit()\n");
+	}
+
+	return rc;
+}
+
+static void
+splat_thread_work3_common(thread_priv_t *tp)
+{
+	ulong_t rnd;
+	int i, rc = 0;
+
+	/* set a unique value for each key using a random value */
+	get_random_bytes((void *)&rnd, 4);
+	for (i = 0; i < SPLAT_THREAD_TEST_KEYS; i++)
+		tsd_set(tp->tp_keys[i], (void *)(i + rnd));
+
+	/* verify the unique value for each key */
+	for (i = 0; i < SPLAT_THREAD_TEST_KEYS; i++)
+		if (tsd_get(tp->tp_keys[i]) !=  (void *)(i + rnd))
+			rc = -EINVAL;
+
+	/* set the value to thread_priv_t for use by the destructor */
+	for (i = 0; i < SPLAT_THREAD_TEST_KEYS; i++)
+		tsd_set(tp->tp_keys[i], (void *)tp);
+
+	spin_lock(&tp->tp_lock);
+	if (rc && !tp->tp_rc)
+		tp->tp_rc = rc;
+
+	tp->tp_count++;
+	wake_up_all(&tp->tp_waitq);
+	spin_unlock(&tp->tp_lock);
+}
+
+static void
+splat_thread_work3_wait(void *priv)
+{
+	thread_priv_t *tp = (thread_priv_t *)priv;
+
+	ASSERT(tp->tp_magic == SPLAT_THREAD_TEST_MAGIC);
+	splat_thread_work3_common(tp);
+	wait_event(tp->tp_waitq, splat_thread_count(tp, 0));
+	thread_exit();
+}
+
+static void
+splat_thread_work3_exit(void *priv)
+{
+	thread_priv_t *tp = (thread_priv_t *)priv;
+
+	ASSERT(tp->tp_magic == SPLAT_THREAD_TEST_MAGIC);
+	splat_thread_work3_common(tp);
+	thread_exit();
+}
+
+static void
+splat_thread_dtor3(void *priv)
+{
+	thread_priv_t *tp = (thread_priv_t *)priv;
+
+	ASSERT(tp->tp_magic == SPLAT_THREAD_TEST_MAGIC);
+	spin_lock(&tp->tp_lock);
+	tp->tp_dtor_count++;
+	spin_unlock(&tp->tp_lock);
+}
+
+/*
+ * Create threads which set and verify SPLAT_THREAD_TEST_KEYS number of
+ * keys.  These threads may then exit by calling thread_exit() which calls
+ * tsd_exit() resulting in all their thread specific data being reclaimed.
+ * Alternately, the thread may block in which case the thread specific
+ * data will be reclaimed as part of tsd_destroy().  In either case all
+ * thread specific data must be reclaimed, this is verified by ensuring
+ * the registered destructor is called the correct number of times.
+ */
+static int
+splat_thread_test3(struct file *file, void *arg)
+{
+	int i, rc = 0, expected, wait_count = 0, exit_count = 0;
+	thread_priv_t tp;
+
+	tp.tp_magic = SPLAT_THREAD_TEST_MAGIC;
+	tp.tp_file = file;
+        spin_lock_init(&tp.tp_lock);
+	init_waitqueue_head(&tp.tp_waitq);
+	tp.tp_rc = 0;
+	tp.tp_count = 0;
+	tp.tp_dtor_count = 0;
+
+	for (i = 0; i < SPLAT_THREAD_TEST_KEYS; i++) {
+		tp.tp_keys[i] = 0;
+		tsd_create(&tp.tp_keys[i], splat_thread_dtor3);
+	}
+
+	/* Start tsd wait threads */
+	for (i = 0; i < SPLAT_THREAD_TEST_THREADS; i++) {
+		if (thread_create(NULL, 0, splat_thread_work3_wait,
+				  &tp, 0, &p0, TS_RUN, defclsyspri))
+			wait_count++;
+	}
+
+	/* All wait threads have setup their tsd and are blocking. */
+	wait_event(tp.tp_waitq, splat_thread_count(&tp, wait_count));
+
+	if (tp.tp_dtor_count != 0) {
+	        splat_vprint(file, SPLAT_THREAD_TEST3_NAME,
+		    "Prematurely ran %d tsd destructors\n", tp.tp_dtor_count);
+		if (!rc)
+			rc = -ERANGE;
+	}
+
+	/* Start tsd exit threads */
+	for (i = 0; i < SPLAT_THREAD_TEST_THREADS; i++) {
+		if (thread_create(NULL, 0, splat_thread_work3_exit,
+				  &tp, 0, &p0, TS_RUN, defclsyspri))
+			exit_count++;
+	}
+
+	/* All exit threads verified tsd and are in the process of exiting */
+	wait_event(tp.tp_waitq,splat_thread_count(&tp, wait_count+exit_count));
+	msleep(500);
+
+	expected = (SPLAT_THREAD_TEST_KEYS * exit_count);
+	if (tp.tp_dtor_count != expected) {
+	        splat_vprint(file, SPLAT_THREAD_TEST3_NAME,
+		    "Expected %d exit tsd destructors but saw %d\n",
+		    expected, tp.tp_dtor_count);
+		if (!rc)
+			rc = -ERANGE;
+	}
+
+	/* Destroy all keys and associated tsd in blocked threads */
+	for (i = 0; i < SPLAT_THREAD_TEST_KEYS; i++)
+		tsd_destroy(&tp.tp_keys[i]);
+
+	expected = (SPLAT_THREAD_TEST_KEYS * (exit_count + wait_count));
+	if (tp.tp_dtor_count != expected) {
+	        splat_vprint(file, SPLAT_THREAD_TEST3_NAME,
+		    "Expected %d wait+exit tsd destructors but saw %d\n",
+		    expected, tp.tp_dtor_count);
+		if (!rc)
+			rc = -ERANGE;
+	}
+
+	/* Release the remaining wait threads, sleep briefly while they exit */
+	spin_lock(&tp.tp_lock);
+	tp.tp_count = 0;
+	wake_up_all(&tp.tp_waitq);
+	spin_unlock(&tp.tp_lock);
+	msleep(500);
+
+	if (tp.tp_rc) {
+	        splat_vprint(file, SPLAT_THREAD_TEST3_NAME,
+		    "Thread tsd_get()/tsd_set() error %d\n", tp.tp_rc);
+		if (!rc)
+			rc = tp.tp_rc;
+	} else if (!rc) {
+	        splat_vprint(file, SPLAT_THREAD_TEST3_NAME, "%s",
+		    "Thread specific data verified\n");
+	}
+
+	return rc;
+}
+
+splat_subsystem_t *
+splat_thread_init(void)
+{
+        splat_subsystem_t *sub;
+
+        sub = kmalloc(sizeof(*sub), GFP_KERNEL);
+        if (sub == NULL)
+                return NULL;
+
+        memset(sub, 0, sizeof(*sub));
+        strncpy(sub->desc.name, SPLAT_THREAD_NAME, SPLAT_NAME_SIZE);
+        strncpy(sub->desc.desc, SPLAT_THREAD_DESC, SPLAT_DESC_SIZE);
+        INIT_LIST_HEAD(&sub->subsystem_list);
+        INIT_LIST_HEAD(&sub->test_list);
+        spin_lock_init(&sub->test_lock);
+        sub->desc.id = SPLAT_SUBSYSTEM_THREAD;
+
+        SPLAT_TEST_INIT(sub, SPLAT_THREAD_TEST1_NAME, SPLAT_THREAD_TEST1_DESC,
+                      SPLAT_THREAD_TEST1_ID, splat_thread_test1);
+        SPLAT_TEST_INIT(sub, SPLAT_THREAD_TEST2_NAME, SPLAT_THREAD_TEST2_DESC,
+                      SPLAT_THREAD_TEST2_ID, splat_thread_test2);
+        SPLAT_TEST_INIT(sub, SPLAT_THREAD_TEST3_NAME, SPLAT_THREAD_TEST3_DESC,
+                      SPLAT_THREAD_TEST3_ID, splat_thread_test3);
+
+        return sub;
+}
+
+void
+splat_thread_fini(splat_subsystem_t *sub)
+{
+        ASSERT(sub);
+        SPLAT_TEST_FINI(sub, SPLAT_THREAD_TEST3_ID);
+        SPLAT_TEST_FINI(sub, SPLAT_THREAD_TEST2_ID);
+        SPLAT_TEST_FINI(sub, SPLAT_THREAD_TEST1_ID);
+
+        kfree(sub);
+}
+
+int
+splat_thread_id(void) {
+        return SPLAT_SUBSYSTEM_THREAD;
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/module/splat/splat-time.c
@@ -0,0 +1,119 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+ *****************************************************************************
+ *  Solaris Porting LAyer Tests (SPLAT) Time Tests.
+\*****************************************************************************/
+
+#include <sys/time.h>
+#include <linux/mm_compat.h>
+#include <linux/slab.h>
+#include "splat-internal.h"
+
+#define SPLAT_TIME_NAME			"time"
+#define SPLAT_TIME_DESC			"Kernel Time Tests"
+
+#define SPLAT_TIME_TEST1_ID		0x0801
+#define SPLAT_TIME_TEST1_NAME		"time1"
+#define SPLAT_TIME_TEST1_DESC		"HZ Test"
+
+#define SPLAT_TIME_TEST2_ID		0x0802
+#define SPLAT_TIME_TEST2_NAME		"time2"
+#define SPLAT_TIME_TEST2_DESC		"Monotonic Test"
+
+static int
+splat_time_test1(struct file *file, void *arg)
+{
+	int myhz = hz;
+	splat_vprint(file, SPLAT_TIME_TEST1_NAME, "hz is %d\n", myhz);
+        return 0;
+}
+
+static int
+splat_time_test2(struct file *file, void *arg)
+{
+        hrtime_t tm1, tm2;
+	int i;
+
+        tm1 = gethrtime();
+        splat_vprint(file, SPLAT_TIME_TEST2_NAME, "time is %lld\n", tm1);
+
+        for(i = 0; i < 100; i++) {
+                tm2 = gethrtime();
+                splat_vprint(file, SPLAT_TIME_TEST2_NAME, "time is %lld\n", tm2);
+
+                if(tm1 > tm2) {
+                        splat_print(file, "%s: gethrtime() is not giving "
+				    "monotonically increasing values\n",
+				    SPLAT_TIME_TEST2_NAME);
+                        return 1;
+                }
+                tm1 = tm2;
+
+                set_current_state(TASK_INTERRUPTIBLE);
+                schedule_timeout(10);
+        }
+
+        return 0;
+}
+
+splat_subsystem_t *
+splat_time_init(void)
+{
+        splat_subsystem_t *sub;
+
+        sub = kmalloc(sizeof(*sub), GFP_KERNEL);
+        if (sub == NULL)
+                return NULL;
+
+        memset(sub, 0, sizeof(*sub));
+        strncpy(sub->desc.name, SPLAT_TIME_NAME, SPLAT_NAME_SIZE);
+	strncpy(sub->desc.desc, SPLAT_TIME_DESC, SPLAT_DESC_SIZE);
+        INIT_LIST_HEAD(&sub->subsystem_list);
+	INIT_LIST_HEAD(&sub->test_list);
+        spin_lock_init(&sub->test_lock);
+        sub->desc.id = SPLAT_SUBSYSTEM_TIME;
+
+        SPLAT_TEST_INIT(sub, SPLAT_TIME_TEST1_NAME, SPLAT_TIME_TEST1_DESC,
+	              SPLAT_TIME_TEST1_ID, splat_time_test1);
+        SPLAT_TEST_INIT(sub, SPLAT_TIME_TEST2_NAME, SPLAT_TIME_TEST2_DESC,
+	              SPLAT_TIME_TEST2_ID, splat_time_test2);
+
+        return sub;
+}
+
+void
+splat_time_fini(splat_subsystem_t *sub)
+{
+        ASSERT(sub);
+
+        SPLAT_TEST_FINI(sub, SPLAT_TIME_TEST2_ID);
+        SPLAT_TEST_FINI(sub, SPLAT_TIME_TEST1_ID);
+
+        kfree(sub);
+}
+
+int
+splat_time_id(void)
+{
+        return SPLAT_SUBSYSTEM_TIME;
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/module/splat/splat-vnode.c
@@ -0,0 +1,451 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+ *****************************************************************************
+ *  Solaris Porting LAyer Tests (SPLAT) Vnode Tests.
+\*****************************************************************************/
+
+#include <sys/vnode.h>
+#include "splat-internal.h"
+
+#define SPLAT_VNODE_NAME		"vnode"
+#define SPLAT_VNODE_DESC		"Kernel Vnode Tests"
+
+#define SPLAT_VNODE_TEST1_ID		0x0901
+#define SPLAT_VNODE_TEST1_NAME		"vn_open"
+#define SPLAT_VNODE_TEST1_DESC		"Vn_open Test"
+
+#define SPLAT_VNODE_TEST2_ID		0x0902
+#define SPLAT_VNODE_TEST2_NAME		"vn_openat"
+#define SPLAT_VNODE_TEST2_DESC		"Vn_openat Test"
+
+#define SPLAT_VNODE_TEST3_ID		0x0903
+#define SPLAT_VNODE_TEST3_NAME		"vn_rdwr"
+#define SPLAT_VNODE_TEST3_DESC		"Vn_rdwrt Test"
+
+#define SPLAT_VNODE_TEST4_ID		0x0904
+#define SPLAT_VNODE_TEST4_NAME		"vn_rename"
+#define SPLAT_VNODE_TEST4_DESC		"Vn_rename Test"
+
+#define SPLAT_VNODE_TEST5_ID		0x0905
+#define SPLAT_VNODE_TEST5_NAME		"vn_getattr"
+#define SPLAT_VNODE_TEST5_DESC		"Vn_getattr Test"
+
+#define SPLAT_VNODE_TEST6_ID		0x0906
+#define SPLAT_VNODE_TEST6_NAME		"vn_sync"
+#define SPLAT_VNODE_TEST6_DESC		"Vn_sync Test"
+
+#define SPLAT_VNODE_TEST_FILE		"/etc/fstab"
+#define SPLAT_VNODE_TEST_FILE_AT	"etc/fstab"
+#define SPLAT_VNODE_TEST_FILE_RW	"/tmp/spl.vnode.tmp"
+#define SPLAT_VNODE_TEST_FILE_RW1	"/tmp/spl.vnode.tmp.1"
+#define SPLAT_VNODE_TEST_FILE_RW2	"/tmp/spl.vnode.tmp.2"
+
+static int
+splat_vnode_user_cmd(struct file *file, void *arg,
+                     char *name, char *cmd)
+{
+	char sh_path[] = "/bin/sh";
+	char *argv[] = { sh_path,
+	                 "-c",
+	                 cmd,
+	                 NULL };
+	char *envp[] = { "HOME=/",
+	                 "TERM=linux",
+	                 "PATH=/sbin:/usr/sbin:/bin:/usr/bin",
+	                 NULL };
+	int rc;
+
+	rc = call_usermodehelper(sh_path, argv, envp, UMH_WAIT_PROC);
+	if (rc) {
+		splat_vprint(file, name,
+			     "Failed command: %s %s %s (%d)\n",
+			     argv[0], argv[1], cmd, rc);
+		return -EPERM;
+	}
+
+	return 0;
+}
+
+static int
+splat_vnode_unlink_all(struct file *file, void *arg, char *name)
+{
+	char *cmds[] = { "rm -f " SPLAT_VNODE_TEST_FILE_RW,
+	                 "rm -f " SPLAT_VNODE_TEST_FILE_RW1,
+			 "rm -f " SPLAT_VNODE_TEST_FILE_RW2,
+	                 NULL };
+	int i = 0, rc = 0;
+
+	while (cmds[i] != NULL) {
+		if ((rc = splat_vnode_user_cmd(file, arg, name, cmds[i])))
+			return rc;
+
+		i++;
+	}
+
+	return rc;
+}
+
+static int
+splat_vnode_test1(struct file *file, void *arg)
+{
+	vnode_t *vp;
+	int rc;
+
+	if ((rc = vn_open(SPLAT_VNODE_TEST_FILE, UIO_SYSSPACE,
+			  FREAD, 0644, &vp, 0, 0))) {
+		splat_vprint(file, SPLAT_VNODE_TEST1_NAME,
+			     "Failed to vn_open test file: %s (%d)\n",
+			     SPLAT_VNODE_TEST_FILE, rc);
+		return -rc;
+	}
+
+        rc = VOP_CLOSE(vp, 0, 0, 0, 0, 0);
+
+	if (rc) {
+		splat_vprint(file, SPLAT_VNODE_TEST1_NAME,
+			     "Failed to vn_close test file: %s (%d)\n",
+			     SPLAT_VNODE_TEST_FILE, rc);
+		return -rc;
+	}
+
+	splat_vprint(file, SPLAT_VNODE_TEST1_NAME, "Successfully vn_open'ed "
+		     "and vn_closed test file: %s\n", SPLAT_VNODE_TEST_FILE);
+
+        return -rc;
+} /* splat_vnode_test1() */
+
+static int
+splat_vnode_test2(struct file *file, void *arg)
+{
+	vnode_t *vp;
+	int rc;
+
+	if ((rc = vn_openat(SPLAT_VNODE_TEST_FILE_AT, UIO_SYSSPACE,
+			    FREAD, 0644, &vp, 0, 0, rootdir, 0))) {
+		splat_vprint(file, SPLAT_VNODE_TEST2_NAME,
+			     "Failed to vn_openat test file: %s (%d)\n",
+			     SPLAT_VNODE_TEST_FILE, rc);
+		return -rc;
+	}
+
+        rc = VOP_CLOSE(vp, 0, 0, 0, 0, 0);
+
+	if (rc) {
+		splat_vprint(file, SPLAT_VNODE_TEST2_NAME,
+			     "Failed to vn_close test file: %s (%d)\n",
+			     SPLAT_VNODE_TEST_FILE, rc);
+		return -rc;
+	}
+
+	splat_vprint(file, SPLAT_VNODE_TEST2_NAME, "Successfully vn_openat'ed "
+		     "and vn_closed test file: %s\n", SPLAT_VNODE_TEST_FILE);
+
+        return -rc;
+} /* splat_vnode_test2() */
+
+static int
+splat_vnode_test3(struct file *file, void *arg)
+{
+	vnode_t *vp;
+	char buf1[32] = "SPL VNode Interface Test File\n";
+	char buf2[32] = "";
+	int rc;
+
+	if ((rc = splat_vnode_unlink_all(file, arg, SPLAT_VNODE_TEST3_NAME)))
+		return rc;
+
+	if ((rc = vn_open(SPLAT_VNODE_TEST_FILE_RW, UIO_SYSSPACE,
+			  FWRITE | FREAD | FCREAT | FEXCL,
+			  0644, &vp, 0, 0))) {
+		splat_vprint(file, SPLAT_VNODE_TEST3_NAME,
+			     "Failed to vn_open test file: %s (%d)\n",
+			     SPLAT_VNODE_TEST_FILE_RW, rc);
+		return -rc;
+	}
+
+        rc = vn_rdwr(UIO_WRITE, vp, buf1, strlen(buf1), 0,
+                     UIO_SYSSPACE, 0, RLIM64_INFINITY, 0, NULL);
+	if (rc) {
+		splat_vprint(file, SPLAT_VNODE_TEST3_NAME,
+			     "Failed vn_rdwr write of test file: %s (%d)\n",
+			     SPLAT_VNODE_TEST_FILE_RW, rc);
+		goto out;
+	}
+
+        rc = vn_rdwr(UIO_READ, vp, buf2, strlen(buf1), 0,
+                     UIO_SYSSPACE, 0, RLIM64_INFINITY, 0, NULL);
+	if (rc) {
+		splat_vprint(file, SPLAT_VNODE_TEST3_NAME,
+			     "Failed vn_rdwr read of test file: %s (%d)\n",
+			     SPLAT_VNODE_TEST_FILE_RW, rc);
+		goto out;
+	}
+
+	if (strncmp(buf1, buf2, strlen(buf1))) {
+		rc = EINVAL;
+		splat_vprint(file, SPLAT_VNODE_TEST3_NAME,
+			     "Failed strncmp data written does not match "
+			     "data read\nWrote: %sRead:  %s\n", buf1, buf2);
+		goto out;
+	}
+
+	rc = 0;
+	splat_vprint(file, SPLAT_VNODE_TEST3_NAME, "Wrote: %s", buf1);
+	splat_vprint(file, SPLAT_VNODE_TEST3_NAME, "Read:  %s", buf2);
+	splat_vprint(file, SPLAT_VNODE_TEST3_NAME, "Successfully wrote and "
+		     "read expected data pattern to test file: %s\n",
+		     SPLAT_VNODE_TEST_FILE_RW);
+
+out:
+        VOP_CLOSE(vp, 0, 0, 0, 0, 0);
+	vn_remove(SPLAT_VNODE_TEST_FILE_RW, UIO_SYSSPACE, RMFILE);
+
+        return -rc;
+} /* splat_vnode_test3() */
+
+#if LINUX_VERSION_CODE <= KERNEL_VERSION(4,1,0)
+static int
+splat_vnode_test4(struct file *file, void *arg)
+{
+	vnode_t *vp;
+	char buf1[32] = "SPL VNode Interface Test File\n";
+	char buf2[32] = "";
+	int rc;
+
+	if ((rc = splat_vnode_unlink_all(file, arg, SPLAT_VNODE_TEST4_NAME)))
+		return rc;
+
+	if ((rc = vn_open(SPLAT_VNODE_TEST_FILE_RW1, UIO_SYSSPACE,
+			  FWRITE | FREAD | FCREAT | FEXCL, 0644, &vp, 0, 0))) {
+		splat_vprint(file, SPLAT_VNODE_TEST4_NAME,
+			     "Failed to vn_open test file: %s (%d)\n",
+			     SPLAT_VNODE_TEST_FILE_RW1, rc);
+		goto out;
+	}
+
+        rc = vn_rdwr(UIO_WRITE, vp, buf1, strlen(buf1), 0,
+                     UIO_SYSSPACE, 0, RLIM64_INFINITY, 0, NULL);
+	if (rc) {
+		splat_vprint(file, SPLAT_VNODE_TEST4_NAME,
+			     "Failed vn_rdwr write of test file: %s (%d)\n",
+			     SPLAT_VNODE_TEST_FILE_RW1, rc);
+		goto out2;
+	}
+
+        VOP_CLOSE(vp, 0, 0, 0, 0, 0);
+
+	rc = vn_rename(SPLAT_VNODE_TEST_FILE_RW1,SPLAT_VNODE_TEST_FILE_RW2,0);
+	if (rc) {
+		splat_vprint(file, SPLAT_VNODE_TEST4_NAME, "Failed vn_rename "
+			     "%s -> %s (%d)\n",
+			     SPLAT_VNODE_TEST_FILE_RW1,
+			     SPLAT_VNODE_TEST_FILE_RW2, rc);
+		goto out;
+	}
+
+	if ((rc = vn_open(SPLAT_VNODE_TEST_FILE_RW2, UIO_SYSSPACE,
+			  FREAD | FEXCL, 0644, &vp, 0, 0))) {
+		splat_vprint(file, SPLAT_VNODE_TEST4_NAME,
+			     "Failed to vn_open test file: %s (%d)\n",
+			     SPLAT_VNODE_TEST_FILE_RW2, rc);
+		goto out;
+	}
+
+        rc = vn_rdwr(UIO_READ, vp, buf2, strlen(buf1), 0,
+                     UIO_SYSSPACE, 0, RLIM64_INFINITY, 0, NULL);
+	if (rc) {
+		splat_vprint(file, SPLAT_VNODE_TEST4_NAME,
+			     "Failed vn_rdwr read of test file: %s (%d)\n",
+			     SPLAT_VNODE_TEST_FILE_RW2, rc);
+		goto out2;
+	}
+
+	if (strncmp(buf1, buf2, strlen(buf1))) {
+		rc = EINVAL;
+		splat_vprint(file, SPLAT_VNODE_TEST4_NAME,
+			     "Failed strncmp data written does not match "
+			     "data read\nWrote: %sRead:  %s\n", buf1, buf2);
+		goto out2;
+	}
+
+	rc = 0;
+	splat_vprint(file, SPLAT_VNODE_TEST4_NAME, "Wrote to %s:  %s",
+		     SPLAT_VNODE_TEST_FILE_RW1, buf1);
+	splat_vprint(file, SPLAT_VNODE_TEST4_NAME, "Read from %s: %s",
+		     SPLAT_VNODE_TEST_FILE_RW2, buf2);
+	splat_vprint(file, SPLAT_VNODE_TEST4_NAME, "Successfully renamed "
+		     "test file %s -> %s and verified data pattern\n",
+		     SPLAT_VNODE_TEST_FILE_RW1, SPLAT_VNODE_TEST_FILE_RW2);
+out2:
+        VOP_CLOSE(vp, 0, 0, 0, 0, 0);
+out:
+	vn_remove(SPLAT_VNODE_TEST_FILE_RW1, UIO_SYSSPACE, RMFILE);
+	vn_remove(SPLAT_VNODE_TEST_FILE_RW2, UIO_SYSSPACE, RMFILE);
+
+        return -rc;
+} /* splat_vnode_test4() */
+#endif
+
+static int
+splat_vnode_test5(struct file *file, void *arg)
+{
+	vnode_t *vp;
+	vattr_t vap;
+	int rc;
+
+	if ((rc = vn_open(SPLAT_VNODE_TEST_FILE, UIO_SYSSPACE,
+			  FREAD, 0644, &vp, 0, 0))) {
+		splat_vprint(file, SPLAT_VNODE_TEST5_NAME,
+			     "Failed to vn_open test file: %s (%d)\n",
+			     SPLAT_VNODE_TEST_FILE, rc);
+		return -rc;
+	}
+
+	rc = VOP_GETATTR(vp, &vap, 0, 0, NULL);
+	if (rc) {
+		splat_vprint(file, SPLAT_VNODE_TEST5_NAME,
+			     "Failed to vn_getattr test file: %s (%d)\n",
+			     SPLAT_VNODE_TEST_FILE, rc);
+		goto out;
+	}
+
+	if (vap.va_type != VREG) {
+		rc = EINVAL;
+		splat_vprint(file, SPLAT_VNODE_TEST5_NAME,
+			     "Failed expected regular file type "
+			     "(%d != VREG): %s (%d)\n", vap.va_type,
+			     SPLAT_VNODE_TEST_FILE, rc);
+		goto out;
+	}
+
+	splat_vprint(file, SPLAT_VNODE_TEST1_NAME, "Successfully "
+		     "vn_getattr'ed test file: %s\n", SPLAT_VNODE_TEST_FILE);
+
+out:
+        VOP_CLOSE(vp, 0, 0, 0, 0, 0);
+
+        return -rc;
+} /* splat_vnode_test5() */
+
+static int
+splat_vnode_test6(struct file *file, void *arg)
+{
+	vnode_t *vp;
+	char buf[32] = "SPL VNode Interface Test File\n";
+	int rc;
+
+	if ((rc = splat_vnode_unlink_all(file, arg, SPLAT_VNODE_TEST6_NAME)))
+		return rc;
+
+	if ((rc = vn_open(SPLAT_VNODE_TEST_FILE_RW, UIO_SYSSPACE,
+			  FWRITE | FCREAT | FEXCL, 0644, &vp, 0, 0))) {
+		splat_vprint(file, SPLAT_VNODE_TEST6_NAME,
+			     "Failed to vn_open test file: %s (%d)\n",
+			     SPLAT_VNODE_TEST_FILE_RW, rc);
+		return -rc;
+	}
+
+        rc = vn_rdwr(UIO_WRITE, vp, buf, strlen(buf), 0,
+                     UIO_SYSSPACE, 0, RLIM64_INFINITY, 0, NULL);
+	if (rc) {
+		splat_vprint(file, SPLAT_VNODE_TEST6_NAME,
+			     "Failed vn_rdwr write of test file: %s (%d)\n",
+			     SPLAT_VNODE_TEST_FILE_RW, rc);
+		goto out;
+	}
+
+	rc = vn_fsync(vp, 0, 0, 0);
+	if (rc) {
+		splat_vprint(file, SPLAT_VNODE_TEST6_NAME,
+			     "Failed vn_fsync of test file: %s (%d)\n",
+			     SPLAT_VNODE_TEST_FILE_RW, rc);
+		goto out;
+	}
+
+	rc = 0;
+	splat_vprint(file, SPLAT_VNODE_TEST6_NAME, "Successfully "
+		     "fsync'ed test file %s\n", SPLAT_VNODE_TEST_FILE_RW);
+out:
+        VOP_CLOSE(vp, 0, 0, 0, 0, 0);
+	vn_remove(SPLAT_VNODE_TEST_FILE_RW, UIO_SYSSPACE, RMFILE);
+
+        return -rc;
+} /* splat_vnode_test6() */
+
+splat_subsystem_t *
+splat_vnode_init(void)
+{
+        splat_subsystem_t *sub;
+
+        sub = kmalloc(sizeof(*sub), GFP_KERNEL);
+        if (sub == NULL)
+                return NULL;
+
+        memset(sub, 0, sizeof(*sub));
+        strncpy(sub->desc.name, SPLAT_VNODE_NAME, SPLAT_NAME_SIZE);
+	strncpy(sub->desc.desc, SPLAT_VNODE_DESC, SPLAT_DESC_SIZE);
+        INIT_LIST_HEAD(&sub->subsystem_list);
+	INIT_LIST_HEAD(&sub->test_list);
+        spin_lock_init(&sub->test_lock);
+        sub->desc.id = SPLAT_SUBSYSTEM_VNODE;
+
+        SPLAT_TEST_INIT(sub, SPLAT_VNODE_TEST1_NAME, SPLAT_VNODE_TEST1_DESC,
+	                SPLAT_VNODE_TEST1_ID, splat_vnode_test1);
+        SPLAT_TEST_INIT(sub, SPLAT_VNODE_TEST2_NAME, SPLAT_VNODE_TEST2_DESC,
+	                SPLAT_VNODE_TEST2_ID, splat_vnode_test2);
+        SPLAT_TEST_INIT(sub, SPLAT_VNODE_TEST3_NAME, SPLAT_VNODE_TEST3_DESC,
+	                SPLAT_VNODE_TEST3_ID, splat_vnode_test3);
+#if LINUX_VERSION_CODE <= KERNEL_VERSION(4,1,0)
+        SPLAT_TEST_INIT(sub, SPLAT_VNODE_TEST4_NAME, SPLAT_VNODE_TEST4_DESC,
+	                SPLAT_VNODE_TEST4_ID, splat_vnode_test4);
+#endif
+        SPLAT_TEST_INIT(sub, SPLAT_VNODE_TEST5_NAME, SPLAT_VNODE_TEST5_DESC,
+	                SPLAT_VNODE_TEST5_ID, splat_vnode_test5);
+        SPLAT_TEST_INIT(sub, SPLAT_VNODE_TEST6_NAME, SPLAT_VNODE_TEST6_DESC,
+	                SPLAT_VNODE_TEST6_ID, splat_vnode_test6);
+
+        return sub;
+} /* splat_vnode_init() */
+
+void
+splat_vnode_fini(splat_subsystem_t *sub)
+{
+        ASSERT(sub);
+
+        SPLAT_TEST_FINI(sub, SPLAT_VNODE_TEST6_ID);
+        SPLAT_TEST_FINI(sub, SPLAT_VNODE_TEST5_ID);
+#if LINUX_VERSION_CODE <= KERNEL_VERSION(4,1,0)
+        SPLAT_TEST_FINI(sub, SPLAT_VNODE_TEST4_ID);
+#endif
+        SPLAT_TEST_FINI(sub, SPLAT_VNODE_TEST3_ID);
+        SPLAT_TEST_FINI(sub, SPLAT_VNODE_TEST2_ID);
+        SPLAT_TEST_FINI(sub, SPLAT_VNODE_TEST1_ID);
+
+        kfree(sub);
+} /* splat_vnode_fini() */
+
+int
+splat_vnode_id(void)
+{
+        return SPLAT_SUBSYSTEM_VNODE;
+} /* splat_vnode_id() */
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/module/splat/splat-zlib.c
@@ -0,0 +1,166 @@
+/*****************************************************************************\
+ *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+ *  Copyright (C) 2007 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  UCRL-CODE-235197
+ *
+ *  This file is part of the SPL, Solaris Porting Layer.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  The SPL is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  The SPL is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+ *****************************************************************************
+ *  Solaris Porting LAyer Tests (SPLAT) Zlib Compression Tests.
+\*****************************************************************************/
+
+#include <sys/zmod.h>
+#include <sys/random.h>
+#include <sys/kmem.h>
+#include <sys/vmem.h>
+#include "splat-internal.h"
+
+#define SPLAT_ZLIB_NAME			"zlib"
+#define SPLAT_ZLIB_DESC			"Zlib Compression Tests"
+
+#define SPLAT_ZLIB_TEST1_ID		0x0f01
+#define SPLAT_ZLIB_TEST1_NAME		"compress/uncompress"
+#define SPLAT_ZLIB_TEST1_DESC		"Compress/Uncompress Test"
+
+#define BUFFER_SIZE			(128 * 1024)
+
+static int
+splat_zlib_test1_check(struct file *file, void *src, void *dst, void *chk,
+    int level)
+{
+	size_t dst_len = BUFFER_SIZE;
+	size_t chk_len = BUFFER_SIZE;
+	int rc;
+
+	memset(dst, 0, BUFFER_SIZE);
+	memset(chk, 0, BUFFER_SIZE);
+
+	rc = z_compress_level(dst, &dst_len, src, BUFFER_SIZE, level);
+	if (rc != Z_OK) {
+		splat_vprint(file, SPLAT_ZLIB_TEST1_NAME,
+		    "Failed level %d z_compress_level(), %d\n", level, rc);
+		return -EINVAL;
+	}
+
+	rc = z_uncompress(chk, &chk_len, dst, dst_len);
+	if (rc != Z_OK) {
+		splat_vprint(file, SPLAT_ZLIB_TEST1_NAME,
+		    "Failed level %d z_uncompress(), %d\n", level, rc);
+		return -EINVAL;
+	}
+
+	rc = memcmp(src, chk, BUFFER_SIZE);
+	if (rc) {
+		splat_vprint(file, SPLAT_ZLIB_TEST1_NAME,
+		    "Failed level %d memcmp()), %d\n", level, rc);
+		return -EINVAL;
+	}
+
+	splat_vprint(file, SPLAT_ZLIB_TEST1_NAME,
+	    "Passed level %d, compressed %d bytes to %d bytes\n",
+	    level, BUFFER_SIZE, (int)dst_len);
+
+	return 0;
+}
+
+/*
+ * Compress a buffer, uncompress the newly compressed buffer, then
+ * compare it to the original.  Do this for all 9 compression levels.
+ */
+static int
+splat_zlib_test1(struct file *file, void *arg)
+{
+	void *src = NULL, *dst = NULL, *chk = NULL;
+	int i, rc, level;
+
+	src = vmalloc(BUFFER_SIZE);
+	if (src == NULL) {
+		rc = -ENOMEM;
+		goto out;
+	}
+
+	dst = vmalloc(BUFFER_SIZE);
+	if (dst == NULL) {
+		rc = -ENOMEM;
+		goto out;
+	}
+
+	chk = vmalloc(BUFFER_SIZE);
+	if (chk == NULL) {
+		rc = -ENOMEM;
+		goto out;
+	}
+
+	/* Source buffer is a repeating 1024 byte random pattern. */
+	random_get_pseudo_bytes(src, sizeof(uint8_t) * 1024);
+	for (i = 1; i < 128; i++)
+		memcpy(src + (i * 1024), src, 1024);
+
+	for (level = 1; level <= 9; level++)
+		if ((rc = splat_zlib_test1_check(file, src, dst, chk, level)))
+			break;
+out:
+	if (src)
+		vfree(src);
+
+	if (dst)
+		vfree(dst);
+
+	if (chk)
+		vfree(chk);
+
+	return rc;
+}
+
+splat_subsystem_t *
+splat_zlib_init(void)
+{
+        splat_subsystem_t *sub;
+
+        sub = kmalloc(sizeof(*sub), GFP_KERNEL);
+        if (sub == NULL)
+                return NULL;
+
+        memset(sub, 0, sizeof(*sub));
+        strncpy(sub->desc.name, SPLAT_ZLIB_NAME, SPLAT_NAME_SIZE);
+	strncpy(sub->desc.desc, SPLAT_ZLIB_DESC, SPLAT_DESC_SIZE);
+        INIT_LIST_HEAD(&sub->subsystem_list);
+	INIT_LIST_HEAD(&sub->test_list);
+        spin_lock_init(&sub->test_lock);
+        sub->desc.id = SPLAT_SUBSYSTEM_ZLIB;
+
+        SPLAT_TEST_INIT(sub, SPLAT_ZLIB_TEST1_NAME, SPLAT_ZLIB_TEST1_DESC,
+	              SPLAT_ZLIB_TEST1_ID, splat_zlib_test1);
+
+        return sub;
+}
+
+void
+splat_zlib_fini(splat_subsystem_t *sub)
+{
+        ASSERT(sub);
+
+        SPLAT_TEST_FINI(sub, SPLAT_ZLIB_TEST1_ID);
+
+        kfree(sub);
+}
+
+int
+splat_zlib_id(void) {
+        return SPLAT_SUBSYSTEM_ZLIB;
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/rpm/Makefile.am
@@ -0,0 +1 @@
+SUBDIRS = generic redhat
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/rpm/Makefile.in
@@ -0,0 +1,673 @@
+# Makefile.in generated by automake 1.15 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2014 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+VPATH = @srcdir@
+am__is_gnu_make = { \
+  if test -z '$(MAKELEVEL)'; then \
+    false; \
+  elif test -n '$(MAKE_HOST)'; then \
+    true; \
+  elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+    true; \
+  else \
+    false; \
+  fi; \
+}
+am__make_running_with_option = \
+  case $${target_option-} in \
+      ?) ;; \
+      *) echo "am__make_running_with_option: internal error: invalid" \
+              "target option '$${target_option-}' specified" >&2; \
+         exit 1;; \
+  esac; \
+  has_opt=no; \
+  sane_makeflags=$$MAKEFLAGS; \
+  if $(am__is_gnu_make); then \
+    sane_makeflags=$$MFLAGS; \
+  else \
+    case $$MAKEFLAGS in \
+      *\\[\ \	]*) \
+        bs=\\; \
+        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
+    esac; \
+  fi; \
+  skip_next=no; \
+  strip_trailopt () \
+  { \
+    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+  }; \
+  for flg in $$sane_makeflags; do \
+    test $$skip_next = yes && { skip_next=no; continue; }; \
+    case $$flg in \
+      *=*|--*) continue;; \
+        -*I) strip_trailopt 'I'; skip_next=yes;; \
+      -*I?*) strip_trailopt 'I';; \
+        -*O) strip_trailopt 'O'; skip_next=yes;; \
+      -*O?*) strip_trailopt 'O';; \
+        -*l) strip_trailopt 'l'; skip_next=yes;; \
+      -*l?*) strip_trailopt 'l';; \
+      -[dEDm]) skip_next=yes;; \
+      -[JT]) skip_next=yes;; \
+    esac; \
+    case $$flg in \
+      *$$target_option*) has_opt=yes; break;; \
+    esac; \
+  done; \
+  test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+target_triplet = @target@
+subdir = rpm
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/config/libtool.m4 \
+	$(top_srcdir)/config/ltoptions.m4 \
+	$(top_srcdir)/config/ltsugar.m4 \
+	$(top_srcdir)/config/ltversion.m4 \
+	$(top_srcdir)/config/lt~obsolete.m4 \
+	$(top_srcdir)/config/spl-build.m4 \
+	$(top_srcdir)/config/spl-meta.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/spl_config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo "  GEN     " $@;
+am__v_GEN_1 = 
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 = 
+SOURCES =
+DIST_SOURCES =
+RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \
+	ctags-recursive dvi-recursive html-recursive info-recursive \
+	install-data-recursive install-dvi-recursive \
+	install-exec-recursive install-html-recursive \
+	install-info-recursive install-pdf-recursive \
+	install-ps-recursive install-recursive installcheck-recursive \
+	installdirs-recursive pdf-recursive ps-recursive \
+	tags-recursive uninstall-recursive
+am__can_run_installinfo = \
+  case $$AM_UPDATE_INFO_DIR in \
+    n|no|NO) false;; \
+    *) (install-info --version) >/dev/null 2>&1;; \
+  esac
+RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive	\
+  distclean-recursive maintainer-clean-recursive
+am__recursive_targets = \
+  $(RECURSIVE_TARGETS) \
+  $(RECURSIVE_CLEAN_TARGETS) \
+  $(am__extra_recursive_targets)
+AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \
+	distdir
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates.  Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+  BEGIN { nonempty = 0; } \
+  { items[$$0] = 1; nonempty = 1; } \
+  END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique.  This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+  list='$(am__tagged_files)'; \
+  unique=`for i in $$list; do \
+    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+  done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+DIST_SUBDIRS = $(SUBDIRS)
+am__DIST_COMMON = $(srcdir)/Makefile.in
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+am__relativize = \
+  dir0=`pwd`; \
+  sed_first='s,^\([^/]*\)/.*$$,\1,'; \
+  sed_rest='s,^[^/]*/*,,'; \
+  sed_last='s,^.*/\([^/]*\)$$,\1,'; \
+  sed_butlast='s,/*[^/]*$$,,'; \
+  while test -n "$$dir1"; do \
+    first=`echo "$$dir1" | sed -e "$$sed_first"`; \
+    if test "$$first" != "."; then \
+      if test "$$first" = ".."; then \
+        dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \
+        dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \
+      else \
+        first2=`echo "$$dir2" | sed -e "$$sed_first"`; \
+        if test "$$first2" = "$$first"; then \
+          dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \
+        else \
+          dir2="../$$dir2"; \
+        fi; \
+        dir0="$$dir0"/"$$first"; \
+      fi; \
+    fi; \
+    dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \
+  done; \
+  reldir="$$dir2"
+ACLOCAL = @ACLOCAL@
+ALIEN = @ALIEN@
+ALIEN_VERSION = @ALIEN_VERSION@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEBUG_CFLAGS = @DEBUG_CFLAGS@
+DEBUG_KMEM = @DEBUG_KMEM@
+DEBUG_KMEM_TRACKING = @DEBUG_KMEM_TRACKING@
+DEBUG_SPL = @DEBUG_SPL@
+DEFAULT_PACKAGE = @DEFAULT_PACKAGE@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DPKG = @DPKG@
+DPKGBUILD = @DPKGBUILD@
+DPKGBUILD_VERSION = @DPKGBUILD_VERSION@
+DPKG_VERSION = @DPKG_VERSION@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GREP = @GREP@
+HAVE_ALIEN = @HAVE_ALIEN@
+HAVE_DPKG = @HAVE_DPKG@
+HAVE_DPKGBUILD = @HAVE_DPKGBUILD@
+HAVE_RPM = @HAVE_RPM@
+HAVE_RPMBUILD = @HAVE_RPMBUILD@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+KERNELCPPFLAGS = @KERNELCPPFLAGS@
+KERNELMAKE_PARAMS = @KERNELMAKE_PARAMS@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LINUX = @LINUX@
+LINUX_OBJ = @LINUX_OBJ@
+LINUX_SYMBOLS = @LINUX_SYMBOLS@
+LINUX_VERSION = @LINUX_VERSION@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+RANLIB = @RANLIB@
+RELEASE = @RELEASE@
+RPM = @RPM@
+RPMBUILD = @RPMBUILD@
+RPMBUILD_VERSION = @RPMBUILD_VERSION@
+RPM_DEFINE_COMMON = @RPM_DEFINE_COMMON@
+RPM_DEFINE_DKMS = @RPM_DEFINE_DKMS@
+RPM_DEFINE_KMOD = @RPM_DEFINE_KMOD@
+RPM_DEFINE_UTIL = @RPM_DEFINE_UTIL@
+RPM_SPEC_DIR = @RPM_SPEC_DIR@
+RPM_VERSION = @RPM_VERSION@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SPL_CONFIG = @SPL_CONFIG@
+SPL_META_ALIAS = @SPL_META_ALIAS@
+SPL_META_AUTHOR = @SPL_META_AUTHOR@
+SPL_META_DATA = @SPL_META_DATA@
+SPL_META_LICENSE = @SPL_META_LICENSE@
+SPL_META_LT_AGE = @SPL_META_LT_AGE@
+SPL_META_LT_CURRENT = @SPL_META_LT_CURRENT@
+SPL_META_LT_REVISION = @SPL_META_LT_REVISION@
+SPL_META_NAME = @SPL_META_NAME@
+SPL_META_RELEASE = @SPL_META_RELEASE@
+SPL_META_VERSION = @SPL_META_VERSION@
+SRPM_DEFINE_COMMON = @SRPM_DEFINE_COMMON@
+SRPM_DEFINE_DKMS = @SRPM_DEFINE_DKMS@
+SRPM_DEFINE_KMOD = @SRPM_DEFINE_KMOD@
+SRPM_DEFINE_UTIL = @SRPM_DEFINE_UTIL@
+STRIP = @STRIP@
+VENDOR = @VENDOR@
+VERSION = @VERSION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+runstatedir = @runstatedir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+SUBDIRS = generic redhat
+all: all-recursive
+
+.SUFFIXES:
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+	        && { if test -f $@; then exit 0; else break; fi; }; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu rpm/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --gnu rpm/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+	esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
+
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run 'make' without going through this Makefile.
+# To change the values of 'make' variables: instead of editing Makefiles,
+# (1) if the variable is set in 'config.status', edit 'config.status'
+#     (which will cause the Makefiles to be regenerated when you run 'make');
+# (2) otherwise, pass the desired values on the 'make' command line.
+$(am__recursive_targets):
+	@fail=; \
+	if $(am__make_keepgoing); then \
+	  failcom='fail=yes'; \
+	else \
+	  failcom='exit 1'; \
+	fi; \
+	dot_seen=no; \
+	target=`echo $@ | sed s/-recursive//`; \
+	case "$@" in \
+	  distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
+	  *) list='$(SUBDIRS)' ;; \
+	esac; \
+	for subdir in $$list; do \
+	  echo "Making $$target in $$subdir"; \
+	  if test "$$subdir" = "."; then \
+	    dot_seen=yes; \
+	    local_target="$$target-am"; \
+	  else \
+	    local_target="$$target"; \
+	  fi; \
+	  ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+	  || eval $$failcom; \
+	done; \
+	if test "$$dot_seen" = "no"; then \
+	  $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+	fi; test -z "$$fail"
+
+ID: $(am__tagged_files)
+	$(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-recursive
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	set x; \
+	here=`pwd`; \
+	if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
+	  include_option=--etags-include; \
+	  empty_fix=.; \
+	else \
+	  include_option=--include; \
+	  empty_fix=; \
+	fi; \
+	list='$(SUBDIRS)'; for subdir in $$list; do \
+	  if test "$$subdir" = .; then :; else \
+	    test ! -f $$subdir/TAGS || \
+	      set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \
+	  fi; \
+	done; \
+	$(am__define_uniq_tagged_files); \
+	shift; \
+	if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+	  test -n "$$unique" || unique=$$empty_fix; \
+	  if test $$# -gt 0; then \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      "$$@" $$unique; \
+	  else \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      $$unique; \
+	  fi; \
+	fi
+ctags: ctags-recursive
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	$(am__define_uniq_tagged_files); \
+	test -z "$(CTAGS_ARGS)$$unique" \
+	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+	     $$unique
+
+GTAGS:
+	here=`$(am__cd) $(top_builddir) && pwd` \
+	  && $(am__cd) $(top_srcdir) \
+	  && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-recursive
+
+cscopelist-am: $(am__tagged_files)
+	list='$(am__tagged_files)'; \
+	case "$(srcdir)" in \
+	  [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+	  *) sdir=$(subdir)/$(srcdir) ;; \
+	esac; \
+	for i in $$list; do \
+	  if test -f "$$i"; then \
+	    echo "$(subdir)/$$i"; \
+	  else \
+	    echo "$$sdir/$$i"; \
+	  fi; \
+	done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	list='$(DISTFILES)'; \
+	  dist_files=`for file in $$list; do echo $$file; done | \
+	  sed -e "s|^$$srcdirstrip/||;t" \
+	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+	case $$dist_files in \
+	  */*) $(MKDIR_P) `echo "$$dist_files" | \
+			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+			   sort -u` ;; \
+	esac; \
+	for file in $$dist_files; do \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  if test -d $$d/$$file; then \
+	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+	    if test -d "$(distdir)/$$file"; then \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+	  else \
+	    test -f "$(distdir)/$$file" \
+	    || cp -p $$d/$$file "$(distdir)/$$file" \
+	    || exit 1; \
+	  fi; \
+	done
+	@list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
+	  if test "$$subdir" = .; then :; else \
+	    $(am__make_dryrun) \
+	      || test -d "$(distdir)/$$subdir" \
+	      || $(MKDIR_P) "$(distdir)/$$subdir" \
+	      || exit 1; \
+	    dir1=$$subdir; dir2="$(distdir)/$$subdir"; \
+	    $(am__relativize); \
+	    new_distdir=$$reldir; \
+	    dir1=$$subdir; dir2="$(top_distdir)"; \
+	    $(am__relativize); \
+	    new_top_distdir=$$reldir; \
+	    echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \
+	    echo "     am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \
+	    ($(am__cd) $$subdir && \
+	      $(MAKE) $(AM_MAKEFLAGS) \
+	        top_distdir="$$new_top_distdir" \
+	        distdir="$$new_distdir" \
+		am__remove_distdir=: \
+		am__skip_length_check=: \
+		am__skip_mode_fix=: \
+	        distdir) \
+	      || exit 1; \
+	  fi; \
+	done
+check-am: all-am
+check: check-recursive
+all-am: Makefile
+installdirs: installdirs-recursive
+installdirs-am:
+install: install-recursive
+install-exec: install-exec-recursive
+install-data: install-data-recursive
+uninstall: uninstall-recursive
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-recursive
+install-strip:
+	if test -z '$(STRIP)'; then \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	      install; \
+	else \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+	fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+clean: clean-recursive
+
+clean-am: clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-recursive
+	-rm -f Makefile
+distclean-am: clean-am distclean-generic distclean-tags
+
+dvi: dvi-recursive
+
+dvi-am:
+
+html: html-recursive
+
+html-am:
+
+info: info-recursive
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-recursive
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-recursive
+
+install-html-am:
+
+install-info: install-info-recursive
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-recursive
+
+install-pdf-am:
+
+install-ps: install-ps-recursive
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-recursive
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-recursive
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-recursive
+
+pdf-am:
+
+ps: ps-recursive
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: $(am__recursive_targets) install-am install-strip
+
+.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \
+	check-am clean clean-generic clean-libtool cscopelist-am ctags \
+	ctags-am distclean distclean-generic distclean-libtool \
+	distclean-tags distdir dvi dvi-am html html-am info info-am \
+	install install-am install-data install-data-am install-dvi \
+	install-dvi-am install-exec install-exec-am install-html \
+	install-html-am install-info install-info-am install-man \
+	install-pdf install-pdf-am install-ps install-ps-am \
+	install-strip installcheck installcheck-am installdirs \
+	installdirs-am maintainer-clean maintainer-clean-generic \
+	mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \
+	ps ps-am tags tags-am uninstall uninstall-am
+
+.PRECIOUS: Makefile
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/rpm/generic/Makefile.am
@@ -0,0 +1 @@
+EXTRA_DIST = spl.spec.in spl-kmod.spec.in spl-dkms.spec.in
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/rpm/generic/Makefile.in
@@ -0,0 +1,500 @@
+# Makefile.in generated by automake 1.15 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2014 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+VPATH = @srcdir@
+am__is_gnu_make = { \
+  if test -z '$(MAKELEVEL)'; then \
+    false; \
+  elif test -n '$(MAKE_HOST)'; then \
+    true; \
+  elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+    true; \
+  else \
+    false; \
+  fi; \
+}
+am__make_running_with_option = \
+  case $${target_option-} in \
+      ?) ;; \
+      *) echo "am__make_running_with_option: internal error: invalid" \
+              "target option '$${target_option-}' specified" >&2; \
+         exit 1;; \
+  esac; \
+  has_opt=no; \
+  sane_makeflags=$$MAKEFLAGS; \
+  if $(am__is_gnu_make); then \
+    sane_makeflags=$$MFLAGS; \
+  else \
+    case $$MAKEFLAGS in \
+      *\\[\ \	]*) \
+        bs=\\; \
+        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
+    esac; \
+  fi; \
+  skip_next=no; \
+  strip_trailopt () \
+  { \
+    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+  }; \
+  for flg in $$sane_makeflags; do \
+    test $$skip_next = yes && { skip_next=no; continue; }; \
+    case $$flg in \
+      *=*|--*) continue;; \
+        -*I) strip_trailopt 'I'; skip_next=yes;; \
+      -*I?*) strip_trailopt 'I';; \
+        -*O) strip_trailopt 'O'; skip_next=yes;; \
+      -*O?*) strip_trailopt 'O';; \
+        -*l) strip_trailopt 'l'; skip_next=yes;; \
+      -*l?*) strip_trailopt 'l';; \
+      -[dEDm]) skip_next=yes;; \
+      -[JT]) skip_next=yes;; \
+    esac; \
+    case $$flg in \
+      *$$target_option*) has_opt=yes; break;; \
+    esac; \
+  done; \
+  test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+target_triplet = @target@
+subdir = rpm/generic
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/config/libtool.m4 \
+	$(top_srcdir)/config/ltoptions.m4 \
+	$(top_srcdir)/config/ltsugar.m4 \
+	$(top_srcdir)/config/ltversion.m4 \
+	$(top_srcdir)/config/lt~obsolete.m4 \
+	$(top_srcdir)/config/spl-build.m4 \
+	$(top_srcdir)/config/spl-meta.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/spl_config.h
+CONFIG_CLEAN_FILES = spl.spec spl-kmod.spec spl-dkms.spec
+CONFIG_CLEAN_VPATH_FILES =
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo "  GEN     " $@;
+am__v_GEN_1 = 
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 = 
+SOURCES =
+DIST_SOURCES =
+am__can_run_installinfo = \
+  case $$AM_UPDATE_INFO_DIR in \
+    n|no|NO) false;; \
+    *) (install-info --version) >/dev/null 2>&1;; \
+  esac
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/spl-dkms.spec.in \
+	$(srcdir)/spl-kmod.spec.in $(srcdir)/spl.spec.in
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ALIEN = @ALIEN@
+ALIEN_VERSION = @ALIEN_VERSION@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEBUG_CFLAGS = @DEBUG_CFLAGS@
+DEBUG_KMEM = @DEBUG_KMEM@
+DEBUG_KMEM_TRACKING = @DEBUG_KMEM_TRACKING@
+DEBUG_SPL = @DEBUG_SPL@
+DEFAULT_PACKAGE = @DEFAULT_PACKAGE@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DPKG = @DPKG@
+DPKGBUILD = @DPKGBUILD@
+DPKGBUILD_VERSION = @DPKGBUILD_VERSION@
+DPKG_VERSION = @DPKG_VERSION@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GREP = @GREP@
+HAVE_ALIEN = @HAVE_ALIEN@
+HAVE_DPKG = @HAVE_DPKG@
+HAVE_DPKGBUILD = @HAVE_DPKGBUILD@
+HAVE_RPM = @HAVE_RPM@
+HAVE_RPMBUILD = @HAVE_RPMBUILD@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+KERNELCPPFLAGS = @KERNELCPPFLAGS@
+KERNELMAKE_PARAMS = @KERNELMAKE_PARAMS@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LINUX = @LINUX@
+LINUX_OBJ = @LINUX_OBJ@
+LINUX_SYMBOLS = @LINUX_SYMBOLS@
+LINUX_VERSION = @LINUX_VERSION@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+RANLIB = @RANLIB@
+RELEASE = @RELEASE@
+RPM = @RPM@
+RPMBUILD = @RPMBUILD@
+RPMBUILD_VERSION = @RPMBUILD_VERSION@
+RPM_DEFINE_COMMON = @RPM_DEFINE_COMMON@
+RPM_DEFINE_DKMS = @RPM_DEFINE_DKMS@
+RPM_DEFINE_KMOD = @RPM_DEFINE_KMOD@
+RPM_DEFINE_UTIL = @RPM_DEFINE_UTIL@
+RPM_SPEC_DIR = @RPM_SPEC_DIR@
+RPM_VERSION = @RPM_VERSION@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SPL_CONFIG = @SPL_CONFIG@
+SPL_META_ALIAS = @SPL_META_ALIAS@
+SPL_META_AUTHOR = @SPL_META_AUTHOR@
+SPL_META_DATA = @SPL_META_DATA@
+SPL_META_LICENSE = @SPL_META_LICENSE@
+SPL_META_LT_AGE = @SPL_META_LT_AGE@
+SPL_META_LT_CURRENT = @SPL_META_LT_CURRENT@
+SPL_META_LT_REVISION = @SPL_META_LT_REVISION@
+SPL_META_NAME = @SPL_META_NAME@
+SPL_META_RELEASE = @SPL_META_RELEASE@
+SPL_META_VERSION = @SPL_META_VERSION@
+SRPM_DEFINE_COMMON = @SRPM_DEFINE_COMMON@
+SRPM_DEFINE_DKMS = @SRPM_DEFINE_DKMS@
+SRPM_DEFINE_KMOD = @SRPM_DEFINE_KMOD@
+SRPM_DEFINE_UTIL = @SRPM_DEFINE_UTIL@
+STRIP = @STRIP@
+VENDOR = @VENDOR@
+VERSION = @VERSION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+runstatedir = @runstatedir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+EXTRA_DIST = spl.spec.in spl-kmod.spec.in spl-dkms.spec.in
+all: all-am
+
+.SUFFIXES:
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+	        && { if test -f $@; then exit 0; else break; fi; }; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu rpm/generic/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --gnu rpm/generic/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+	esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+spl.spec: $(top_builddir)/config.status $(srcdir)/spl.spec.in
+	cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+spl-kmod.spec: $(top_builddir)/config.status $(srcdir)/spl-kmod.spec.in
+	cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+spl-dkms.spec: $(top_builddir)/config.status $(srcdir)/spl-dkms.spec.in
+	cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
+tags TAGS:
+
+ctags CTAGS:
+
+cscope cscopelist:
+
+
+distdir: $(DISTFILES)
+	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	list='$(DISTFILES)'; \
+	  dist_files=`for file in $$list; do echo $$file; done | \
+	  sed -e "s|^$$srcdirstrip/||;t" \
+	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+	case $$dist_files in \
+	  */*) $(MKDIR_P) `echo "$$dist_files" | \
+			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+			   sort -u` ;; \
+	esac; \
+	for file in $$dist_files; do \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  if test -d $$d/$$file; then \
+	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+	    if test -d "$(distdir)/$$file"; then \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+	  else \
+	    test -f "$(distdir)/$$file" \
+	    || cp -p $$d/$$file "$(distdir)/$$file" \
+	    || exit 1; \
+	  fi; \
+	done
+check-am: all-am
+check: check-am
+all-am: Makefile
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+	if test -z '$(STRIP)'; then \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	      install; \
+	else \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+	fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-am
+	-rm -f Makefile
+distclean-am: clean-am distclean-generic
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: install-am install-strip
+
+.PHONY: all all-am check check-am clean clean-generic clean-libtool \
+	cscopelist-am ctags-am distclean distclean-generic \
+	distclean-libtool distdir dvi dvi-am html html-am info info-am \
+	install install-am install-data install-data-am install-dvi \
+	install-dvi-am install-exec install-exec-am install-html \
+	install-html-am install-info install-info-am install-man \
+	install-pdf install-pdf-am install-ps install-ps-am \
+	install-strip installcheck installcheck-am installdirs \
+	maintainer-clean maintainer-clean-generic mostlyclean \
+	mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+	tags-am uninstall uninstall-am
+
+.PRECIOUS: Makefile
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/rpm/generic/spl-dkms.spec.in
@@ -0,0 +1,71 @@
+%{?!packager: %define packager Brian Behlendorf <behlendorf1@llnl.gov>}
+
+%define module  @PACKAGE@
+%define mkconf  scripts/dkms.mkconf
+
+Name:           %{module}-dkms
+
+Version:        @VERSION@
+Release:        @RELEASE@%{?dist}
+Summary:        Kernel module(s) (dkms)
+
+Group:          System Environment/Kernel
+License:        GPLv2+
+URL:            http://zfsonlinux.org/
+Source0:        %{module}-%{version}.tar.gz
+BuildRoot:      %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
+BuildArch:      noarch
+
+Requires:       dkms >= 2.2.0.2
+Requires:       gcc, make, perl
+Requires:       kernel-devel
+Provides:       %{module}-kmod = %{version}
+
+%description
+This package contains the dkms kernel modules required to emulate
+several interfaces provided by the Solaris kernel.
+
+%prep
+%setup -q -n %{module}-%{version}
+
+%build
+%{mkconf} -n %{module} -v %{version} -f dkms.conf
+
+%install
+if [ "$RPM_BUILD_ROOT" != "/" ]; then
+    rm -rf $RPM_BUILD_ROOT
+fi
+mkdir -p $RPM_BUILD_ROOT/usr/src/
+cp -rf ${RPM_BUILD_DIR}/%{module}-%{version} $RPM_BUILD_ROOT/usr/src/
+
+%clean
+if [ "$RPM_BUILD_ROOT" != "/" ]; then
+    rm -rf $RPM_BUILD_ROOT
+fi
+
+%files
+%defattr(-,root,root)
+/usr/src/%{module}-%{version}
+
+%post
+for POSTINST in /usr/lib/dkms/common.postinst; do
+    if [ -f $POSTINST ]; then
+        $POSTINST %{module} %{version}
+        exit $?
+    fi
+    echo "WARNING: $POSTINST does not exist."
+done
+echo -e "ERROR: DKMS version is too old and %{module} was not"
+echo -e "built with legacy DKMS support."
+echo -e "You must either rebuild %{module} with legacy postinst"
+echo -e "support or upgrade DKMS to a more current version."
+exit 1
+
+%preun
+echo -e "Uninstall of %{module} module (version %{version}) beginning:"
+dkms remove -m %{module} -v %{version} --all --rpm_safe_upgrade
+exit 0
+
+%changelog
+* %(date "+%a %b %d %Y") %packager %{version}-%{release}
+- Automatic build by DKMS
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/rpm/generic/spl-kmod.spec.in
@@ -0,0 +1,200 @@
+%define module  @PACKAGE@
+#define repo    rpmfusion
+#define repo    chaos
+
+# (un)define the next line to either build for the newest or all current kernels
+%define buildforkernels newest
+#define buildforkernels current
+#define buildforkernels akmod
+
+%bcond_with     debug
+%bcond_with     debug_log
+%bcond_with     debug_kmem
+%bcond_with     debug_kmem_tracking
+%bcond_with     atomic_spinlocks
+
+
+Name:           %{module}-kmod
+
+Version:        @VERSION@
+Release:        @RELEASE@%{?dist}
+Summary:        Kernel module(s)
+
+Group:          System Environment/Kernel
+License:        GPLv2+
+URL:            http://zfsonlinux.org/
+Source0:        %{module}-%{version}.tar.gz
+Source10:       kmodtool
+BuildRoot:      %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id} -u -n)
+
+# The developments headers will conflict with the dkms packages.
+Conflicts:      %{module}-dkms
+
+%if %{defined repo}
+
+# Building for a repository use the proper build-sysbuild package
+# to determine which kernel-devel packages should be installed.
+BuildRequires:  %{_bindir}/kmodtool
+%{!?kernels:BuildRequires: buildsys-build-%{repo}-kerneldevpkgs-%{?buildforkernels:%{buildforkernels}}%{!?buildforkernels:current}-%{_target_cpu}}
+
+%else
+
+# Building local packages attempt to to use the installed kernel.
+%{?rhel:BuildRequires: kernel-devel}
+%{?fedora:BuildRequires: kernel-devel}
+%{?suse_version:BuildRequires: kernel-source}
+
+%if !%{defined kernels} && !%{defined build_src_rpm}
+    %if 0%{?rhel}%{?fedora}%{?suse_version}
+        %define kernels %(ls -1 /usr/src/kernels)
+    %else
+        %define kernels %(ls -1 /lib/modules)
+    %endif
+%endif
+%endif
+
+%if 0%{?fedora} >= 17
+%define prefix  /usr
+%endif
+
+# Kmodtool does its magic here.  A patched version of kmodtool is shipped
+# because the latest versions may not be available for your distribution.
+# https://bugzilla.rpmfusion.org/show_bug.cgi?id=2714
+%{expand:%(bash %{SOURCE10} --target %{_target_cpu} %{?repo:--repo %{?repo}} --kmodname %{name} %{?buildforkernels:--%{buildforkernels}} --devel %{?prefix:--prefix "%{?prefix}"} %{?kernels:--for-kernels "%{?kernels}"} %{?kernelbuildroot:--buildroot "%{?kernelbuildroot}"} 2>/dev/null) }
+
+
+%description
+This package contains the kernel modules required to emulate
+several interfaces provided by the Solaris kernel.
+
+%prep
+# Error out if there was something wrong with kmodtool.
+%{?kmodtool_check}
+
+# Print kmodtool output for debugging purposes:
+bash %{SOURCE10} --target %{_target_cpu} %{?repo:--repo %{?repo}}  --kmodname %{name} %{?buildforkernels:--%{buildforkernels}} --devel  %{?prefix:--prefix "%{?prefix}"} %{?kernels:--for-kernels "%{?kernels}"} %{?kernelbuildroot:--buildroot "%{?kernelbuildroot}"} 2>/dev/null
+
+%if %{with debug}
+    %define debug --enable-debug
+%else
+    %define debug --disable-debug
+%endif
+
+%if %{with debug_log}
+    %define debug_log --enable-debug-log
+%else
+    %define debug_log --disable-debug-log
+%endif
+
+%if %{with debug_kmem}
+    %define debug_kmem --enable-debug-kmem
+%else
+    %define debug_kmem --disable-debug-kmem
+%endif
+
+%if %{with debug_kmem_tracking}
+    %define debug_kmem_tracking --enable-debug-kmem-tracking
+%else
+    %define debug_kmem_tracking --disable-debug-kmem-tracking
+%endif
+
+%if %{with atomic_spinlocks}
+    %define atomic_spinlocks --enable-atomic-spinlocks
+%else
+    %define atomic_spinlocks --disable-atomic-spinlocks
+%endif
+
+# Leverage VPATH from configure to avoid making multiple copies.
+%define _configure ../%{module}-%{version}/configure
+
+%setup -q -c -T -a 0
+
+for kernel_version in %{?kernel_versions}; do
+    %{__mkdir} _kmod_build_${kernel_version%%___*}
+done
+
+%build
+for kernel_version in %{?kernel_versions}; do
+    cd _kmod_build_${kernel_version%%___*}
+    %configure \
+        --with-config=kernel \
+%if 0%{?rhel}%{?fedora}
+        --with-linux="${kernel_version##*___}" \
+        --with-linux-obj="${kernel_version##*___}" \
+%else
+        --with-linux="$( \
+        if [ -e "/lib/modules/${kernel_version%%___*}/source" ]; then \
+            echo "/lib/modules/${kernel_version%%___*}/source"; \
+        else \
+            echo "/lib/modules/${kernel_version%%___*}/build"; \
+        fi)" \
+        --with-linux-obj="/lib/modules/${kernel_version%%___*}/build" \
+%endif
+        %{debug} \
+        %{debug_log} \
+        %{debug_kmem} \
+        %{debug_kmem_tracking} \
+        %{atomic_spinlocks}
+    make %{?_smp_mflags}
+    cd ..
+done
+
+
+%install
+rm -rf ${RPM_BUILD_ROOT}
+
+# Relies on the kernel 'modules_install' make target.
+for kernel_version in %{?kernel_versions}; do
+    cd _kmod_build_${kernel_version%%___*}
+    make install \
+        DESTDIR=${RPM_BUILD_ROOT} \
+        %{?prefix:INSTALL_MOD_PATH=%{?prefix}} \
+        INSTALL_MOD_DIR=%{kmodinstdir_postfix}
+    cd ..
+done
+
+# find-debuginfo.sh only considers executables
+chmod u+x ${RPM_BUILD_ROOT}%{kmodinstdir_prefix}/*/extra/*/*/*
+%{?akmod_install}
+
+
+%clean
+rm -rf $RPM_BUILD_ROOT
+
+%changelog
+* Tue Mar 22 2016 Ned Bass <bass6@llnl.gov> - 0.6.5.6-1
+- Remove artificial architecture restrictions in packaging
+- Add support for s390[x] zfsonlinux/spl#537
+* Wed Mar 9 2016 Ned Bass <bass6@llnl.gov> - 0.6.5.5-1
+- Linux 4.5 compatibility zfsonlinux/spl#524
+- Create working debuginfo packages on Red Hat zfsonlinux/zfs#4224
+- Allow copy-builtin to run multiple times zfsonlinux/spl#526
+- Use safer flags for in-kernel memory allocations zfsonlinux/spl#523
+- Fix potential deadlock in cv_wait() zfsonlinux/zfs#4106
+- Fix livelock in shrinker zfsonlinux/zfs#3936
+* Fri Jan  8 2016 Ned Bass <bass6@llnl.gov> - 0.6.5.4-1
+- Build fixes on SPARC and some kernels
+- Fix taskq dynamic spawning deadlock
+- Fix builtin kernel builds
+- Fix crash due to overflow in P2ROUNDUP macro
+- Fix deadlock during direct memory reclaim
+* Tue Oct 13 2015 Ned Bass <bass6@llnl.gov> - 0.6.5.3-1
+- Fix CPU hotplug zfsonlinux/spl#482
+- Disable dynamic taskqs by default to avoid deadlock zfsonlinux/spl#484
+* Tue Sep 29 2015 Ned Bass <bass6@llnl.gov> - 0.6.5.2-1
+- Released 0.6.5.2-1
+- Fix PAX Patch/Grsec SLAB_USERCOPY panic zfsonlinux/zfs#3796
+- Always remove during dkms uninstall/update zfsonlinux/spl#476
+* Thu Sep 19 2015 Ned Bass <bass6@llnl.gov> - 0.6.5.1-1
+- Released 0.6.5.1-1, no changes from spl-0.6.5
+* Thu Sep 10 2015 Brian Behlendorf <behlendorf1@llnl.gov> - 0.6.5-1
+- Released 0.6.5-1, detailed release notes are available at:
+- https://github.com/zfsonlinux/zfs/releases/tag/zfs-0.6.5
+* Wed Apr  8 2015 Brian Behlendorf <behlendorf1@llnl.gov> - 0.6.4-1
+- Released 0.6.4-1
+* Thu Jun 12 2014 Brian Behlendorf <behlendorf1@llnl.gov> - 0.6.3-1
+- Released 0.6.3-1
+* Wed Aug 21 2013 Brian Behlendorf <behlendorf1@llnl.gov> - 0.6.2-1
+- Released 0.6.2-1
+* Fri Mar 22 2013 Brian Behlendorf <behlendorf1@llnl.gov> - 0.6.1-1
+- First official stable release.
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/rpm/generic/spl.spec.in
@@ -0,0 +1,71 @@
+Name:           @PACKAGE@
+Version:        @VERSION@
+Release:        @RELEASE@%{?dist}
+Summary:        Commands to control the kernel modules
+
+Group:          System Environment/Kernel
+License:        GPLv2+
+URL:            http://zfsonlinux.org/
+Source0:        %{name}-%{version}.tar.gz
+BuildRoot:      %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
+Requires:       %{name}-kmod = %{version}
+Provides:       %{name}-kmod-common = %{version}
+
+%description
+This package contains the commands to verify the SPL
+kernel modules are functioning properly.
+
+%prep
+%setup -q
+
+%build
+%configure --with-config=user
+make %{?_smp_mflags}
+
+%install
+%{__rm} -rf $RPM_BUILD_ROOT
+make install DESTDIR=%{?buildroot}
+
+%files
+%doc AUTHORS COPYING DISCLAIMER
+%{_sbindir}/*
+%{_mandir}/man1/*
+%{_mandir}/man5/*
+
+%changelog
+* Tue Mar 22 2016 Ned Bass <bass6@llnl.gov> - 0.6.5.6-1
+- Remove artificial architecture restrictions in packaging
+- Add support for s390[x] zfsonlinux/spl#537
+* Wed Mar 9 2016 Ned Bass <bass6@llnl.gov> - 0.6.5.5-1
+- Linux 4.5 compatibility zfsonlinux/spl#524
+- Create working debuginfo packages on Red Hat zfsonlinux/zfs#4224
+- Allow copy-builtin to run multiple times zfsonlinux/spl#526
+- Use safer flags for in-kernel memory allocations zfsonlinux/spl#523
+- Fix potential deadlock in cv_wait() zfsonlinux/zfs#4106
+- Fix livelock in shrinker zfsonlinux/zfs#3936
+* Fri Jan  8 2016 Ned Bass <bass6@llnl.gov> - 0.6.5.4-1
+- Build fixes on SPARC and some kernels
+- Fix taskq dynamic spawning deadlock
+- Fix builtin kernel builds
+- Fix crash due to overflow in P2ROUNDUP macro
+- Fix deadlock during direct memory reclaim
+* Tue Oct 13 2015 Ned Bass <bass6@llnl.gov> - 0.6.5.3-1
+- Fix CPU hotplug zfsonlinux/spl#482
+- Disable dynamic taskqs by default to avoid deadlock zfsonlinux/spl#484
+* Tue Sep 29 2015 Ned Bass <bass6@llnl.gov> - 0.6.5.2-1
+- Released 0.6.5.2-1
+- Fix PAX Patch/Grsec SLAB_USERCOPY panic zfsonlinux/zfs#3796
+- Always remove during dkms uninstall/update zfsonlinux/spl#476
+* Thu Sep 19 2015 Ned Bass <bass6@llnl.gov> - 0.6.5.1-1
+- Released 0.6.5.1-1, no changes from spl-0.6.5
+* Thu Sep 10 2015 Brian Behlendorf <behlendorf1@llnl.gov> - 0.6.5-1
+- Released 0.6.5-1, detailed release notes are available at:
+- https://github.com/zfsonlinux/zfs/releases/tag/zfs-0.6.5
+* Wed Apr  8 2015 Brian Behlendorf <behlendorf1@llnl.gov> - 0.6.4-1
+- Released 0.6.4-1
+* Thu Jun 12 2014 Brian Behlendorf <behlendorf1@llnl.gov> - 0.6.3-1
+- Released 0.6.3-1
+* Wed Aug 21 2013 Brian Behlendorf <behlendorf1@llnl.gov> - 0.6.2-1
+- Released 0.6.2-1
+* Fri Mar 22 2013 Brian Behlendorf <behlendorf1@llnl.gov> - 0.6.1-1
+- First official stable release.
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/rpm/redhat/Makefile.am
@@ -0,0 +1 @@
+EXTRA_DIST = spl.spec.in spl-kmod.spec.in spl-dkms.spec.in
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/rpm/redhat/Makefile.in
@@ -0,0 +1,500 @@
+# Makefile.in generated by automake 1.15 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2014 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+VPATH = @srcdir@
+am__is_gnu_make = { \
+  if test -z '$(MAKELEVEL)'; then \
+    false; \
+  elif test -n '$(MAKE_HOST)'; then \
+    true; \
+  elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+    true; \
+  else \
+    false; \
+  fi; \
+}
+am__make_running_with_option = \
+  case $${target_option-} in \
+      ?) ;; \
+      *) echo "am__make_running_with_option: internal error: invalid" \
+              "target option '$${target_option-}' specified" >&2; \
+         exit 1;; \
+  esac; \
+  has_opt=no; \
+  sane_makeflags=$$MAKEFLAGS; \
+  if $(am__is_gnu_make); then \
+    sane_makeflags=$$MFLAGS; \
+  else \
+    case $$MAKEFLAGS in \
+      *\\[\ \	]*) \
+        bs=\\; \
+        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
+    esac; \
+  fi; \
+  skip_next=no; \
+  strip_trailopt () \
+  { \
+    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+  }; \
+  for flg in $$sane_makeflags; do \
+    test $$skip_next = yes && { skip_next=no; continue; }; \
+    case $$flg in \
+      *=*|--*) continue;; \
+        -*I) strip_trailopt 'I'; skip_next=yes;; \
+      -*I?*) strip_trailopt 'I';; \
+        -*O) strip_trailopt 'O'; skip_next=yes;; \
+      -*O?*) strip_trailopt 'O';; \
+        -*l) strip_trailopt 'l'; skip_next=yes;; \
+      -*l?*) strip_trailopt 'l';; \
+      -[dEDm]) skip_next=yes;; \
+      -[JT]) skip_next=yes;; \
+    esac; \
+    case $$flg in \
+      *$$target_option*) has_opt=yes; break;; \
+    esac; \
+  done; \
+  test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+target_triplet = @target@
+subdir = rpm/redhat
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/config/libtool.m4 \
+	$(top_srcdir)/config/ltoptions.m4 \
+	$(top_srcdir)/config/ltsugar.m4 \
+	$(top_srcdir)/config/ltversion.m4 \
+	$(top_srcdir)/config/lt~obsolete.m4 \
+	$(top_srcdir)/config/spl-build.m4 \
+	$(top_srcdir)/config/spl-meta.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/spl_config.h
+CONFIG_CLEAN_FILES = spl.spec spl-kmod.spec spl-dkms.spec
+CONFIG_CLEAN_VPATH_FILES =
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo "  GEN     " $@;
+am__v_GEN_1 = 
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 = 
+SOURCES =
+DIST_SOURCES =
+am__can_run_installinfo = \
+  case $$AM_UPDATE_INFO_DIR in \
+    n|no|NO) false;; \
+    *) (install-info --version) >/dev/null 2>&1;; \
+  esac
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/spl-dkms.spec.in \
+	$(srcdir)/spl-kmod.spec.in $(srcdir)/spl.spec.in
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ALIEN = @ALIEN@
+ALIEN_VERSION = @ALIEN_VERSION@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEBUG_CFLAGS = @DEBUG_CFLAGS@
+DEBUG_KMEM = @DEBUG_KMEM@
+DEBUG_KMEM_TRACKING = @DEBUG_KMEM_TRACKING@
+DEBUG_SPL = @DEBUG_SPL@
+DEFAULT_PACKAGE = @DEFAULT_PACKAGE@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DPKG = @DPKG@
+DPKGBUILD = @DPKGBUILD@
+DPKGBUILD_VERSION = @DPKGBUILD_VERSION@
+DPKG_VERSION = @DPKG_VERSION@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GREP = @GREP@
+HAVE_ALIEN = @HAVE_ALIEN@
+HAVE_DPKG = @HAVE_DPKG@
+HAVE_DPKGBUILD = @HAVE_DPKGBUILD@
+HAVE_RPM = @HAVE_RPM@
+HAVE_RPMBUILD = @HAVE_RPMBUILD@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+KERNELCPPFLAGS = @KERNELCPPFLAGS@
+KERNELMAKE_PARAMS = @KERNELMAKE_PARAMS@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LINUX = @LINUX@
+LINUX_OBJ = @LINUX_OBJ@
+LINUX_SYMBOLS = @LINUX_SYMBOLS@
+LINUX_VERSION = @LINUX_VERSION@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+RANLIB = @RANLIB@
+RELEASE = @RELEASE@
+RPM = @RPM@
+RPMBUILD = @RPMBUILD@
+RPMBUILD_VERSION = @RPMBUILD_VERSION@
+RPM_DEFINE_COMMON = @RPM_DEFINE_COMMON@
+RPM_DEFINE_DKMS = @RPM_DEFINE_DKMS@
+RPM_DEFINE_KMOD = @RPM_DEFINE_KMOD@
+RPM_DEFINE_UTIL = @RPM_DEFINE_UTIL@
+RPM_SPEC_DIR = @RPM_SPEC_DIR@
+RPM_VERSION = @RPM_VERSION@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SPL_CONFIG = @SPL_CONFIG@
+SPL_META_ALIAS = @SPL_META_ALIAS@
+SPL_META_AUTHOR = @SPL_META_AUTHOR@
+SPL_META_DATA = @SPL_META_DATA@
+SPL_META_LICENSE = @SPL_META_LICENSE@
+SPL_META_LT_AGE = @SPL_META_LT_AGE@
+SPL_META_LT_CURRENT = @SPL_META_LT_CURRENT@
+SPL_META_LT_REVISION = @SPL_META_LT_REVISION@
+SPL_META_NAME = @SPL_META_NAME@
+SPL_META_RELEASE = @SPL_META_RELEASE@
+SPL_META_VERSION = @SPL_META_VERSION@
+SRPM_DEFINE_COMMON = @SRPM_DEFINE_COMMON@
+SRPM_DEFINE_DKMS = @SRPM_DEFINE_DKMS@
+SRPM_DEFINE_KMOD = @SRPM_DEFINE_KMOD@
+SRPM_DEFINE_UTIL = @SRPM_DEFINE_UTIL@
+STRIP = @STRIP@
+VENDOR = @VENDOR@
+VERSION = @VERSION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+runstatedir = @runstatedir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+EXTRA_DIST = spl.spec.in spl-kmod.spec.in spl-dkms.spec.in
+all: all-am
+
+.SUFFIXES:
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+	        && { if test -f $@; then exit 0; else break; fi; }; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu rpm/redhat/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --gnu rpm/redhat/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+	esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+spl.spec: $(top_builddir)/config.status $(srcdir)/spl.spec.in
+	cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+spl-kmod.spec: $(top_builddir)/config.status $(srcdir)/spl-kmod.spec.in
+	cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+spl-dkms.spec: $(top_builddir)/config.status $(srcdir)/spl-dkms.spec.in
+	cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
+tags TAGS:
+
+ctags CTAGS:
+
+cscope cscopelist:
+
+
+distdir: $(DISTFILES)
+	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	list='$(DISTFILES)'; \
+	  dist_files=`for file in $$list; do echo $$file; done | \
+	  sed -e "s|^$$srcdirstrip/||;t" \
+	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+	case $$dist_files in \
+	  */*) $(MKDIR_P) `echo "$$dist_files" | \
+			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+			   sort -u` ;; \
+	esac; \
+	for file in $$dist_files; do \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  if test -d $$d/$$file; then \
+	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+	    if test -d "$(distdir)/$$file"; then \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+	  else \
+	    test -f "$(distdir)/$$file" \
+	    || cp -p $$d/$$file "$(distdir)/$$file" \
+	    || exit 1; \
+	  fi; \
+	done
+check-am: all-am
+check: check-am
+all-am: Makefile
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+	if test -z '$(STRIP)'; then \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	      install; \
+	else \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+	fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-am
+	-rm -f Makefile
+distclean-am: clean-am distclean-generic
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: install-am install-strip
+
+.PHONY: all all-am check check-am clean clean-generic clean-libtool \
+	cscopelist-am ctags-am distclean distclean-generic \
+	distclean-libtool distdir dvi dvi-am html html-am info info-am \
+	install install-am install-data install-data-am install-dvi \
+	install-dvi-am install-exec install-exec-am install-html \
+	install-html-am install-info install-info-am install-man \
+	install-pdf install-pdf-am install-ps install-ps-am \
+	install-strip installcheck installcheck-am installdirs \
+	maintainer-clean maintainer-clean-generic mostlyclean \
+	mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+	tags-am uninstall uninstall-am
+
+.PRECIOUS: Makefile
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/rpm/redhat/spl-dkms.spec.in
@@ -0,0 +1,71 @@
+%{?!packager: %define packager Brian Behlendorf <behlendorf1@llnl.gov>}
+
+%define module  @PACKAGE@
+%define mkconf  scripts/dkms.mkconf
+
+Name:           %{module}-dkms
+
+Version:        @VERSION@
+Release:        @RELEASE@%{?dist}
+Summary:        Kernel module(s) (dkms)
+
+Group:          System Environment/Kernel
+License:        GPLv2+
+URL:            http://zfsonlinux.org/
+Source0:        %{module}-%{version}.tar.gz
+BuildRoot:      %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
+BuildArch:      noarch
+
+Requires:       dkms >= 2.2.0.2
+Requires:       gcc, make, perl
+Requires:       kernel-devel
+Provides:       %{module}-kmod = %{version}
+
+%description
+This package contains the dkms kernel modules required to emulate
+several interfaces provided by the Solaris kernel.
+
+%prep
+%setup -q -n %{module}-%{version}
+
+%build
+%{mkconf} -n %{module} -v %{version} -f dkms.conf
+
+%install
+if [ "$RPM_BUILD_ROOT" != "/" ]; then
+    rm -rf $RPM_BUILD_ROOT
+fi
+mkdir -p $RPM_BUILD_ROOT/usr/src/
+cp -rf ${RPM_BUILD_DIR}/%{module}-%{version} $RPM_BUILD_ROOT/usr/src/
+
+%clean
+if [ "$RPM_BUILD_ROOT" != "/" ]; then
+    rm -rf $RPM_BUILD_ROOT
+fi
+
+%files
+%defattr(-,root,root)
+/usr/src/%{module}-%{version}
+
+%post
+for POSTINST in /usr/lib/dkms/common.postinst; do
+    if [ -f $POSTINST ]; then
+        $POSTINST %{module} %{version}
+        exit $?
+    fi
+    echo "WARNING: $POSTINST does not exist."
+done
+echo -e "ERROR: DKMS version is too old and %{module} was not"
+echo -e "built with legacy DKMS support."
+echo -e "You must either rebuild %{module} with legacy postinst"
+echo -e "support or upgrade DKMS to a more current version."
+exit 1
+
+%preun
+echo -e "Uninstall of %{module} module (version %{version}) beginning:"
+dkms remove -m %{module} -v %{version} --all --rpm_safe_upgrade
+exit 0
+
+%changelog
+* %(date "+%a %b %d %Y") %packager %{version}-%{release}
+- Automatic build by DKMS
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/rpm/redhat/spl-kmod.spec.in
@@ -0,0 +1,105 @@
+%bcond_with     debug
+%bcond_with     debug_log
+%bcond_with     debug_kmem
+%bcond_with     debug_kmem_tracking
+%bcond_with     atomic_spinlocks
+
+Name:           @PACKAGE@-kmod
+Version:        @VERSION@
+Release:        @RELEASE@%{?dist}
+
+Summary:        Kernel module(s)
+Group:          System Environment/Kernel
+License:        GPLv2+
+URL:            http://zfsonlinux.org/
+BuildRequires:  %kernel_module_package_buildreqs
+Source0:        @PACKAGE@-%{version}.tar.gz
+BuildRoot:      %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
+
+# Additional dependency information for the kmod sub-package must be specified
+# by generating a preamble text file which kmodtool can append to the spec file.
+%(/bin/echo -e "\
+Requires:       @PACKAGE@ = %{version}\n\
+Conflicts:      @PACKAGE@-dkms\n\n" > %{_sourcedir}/kmod-preamble)
+
+%description
+This package contains the kernel modules required to emulate
+several interfaces provided by the Solaris kernel.
+
+%define kmod_name spl
+
+%kernel_module_package -n %{kmod_name} -p %{_sourcedir}/kmod-preamble
+
+%define ksrc %{_usrsrc}/kernels/%{kverrel}
+%define kobj %{ksrc}
+
+%package -n kmod-%{kmod_name}-devel
+Summary:        SPL kernel module(s) devel common
+Group:          System Environment/Kernel
+
+%description -n  kmod-%{kmod_name}-devel
+This package provides the header files and objects to build kernel modules
+which depend on the SPL kernel module.
+
+%prep
+if ! [ -d "%{ksrc}"  ]; then
+        echo "Kernel build directory isn't set properly, cannot continue"
+        exit 1
+fi
+
+%if %{with debug}
+%define debug --enable-debug
+%else
+%define debug --disable-debug
+%endif
+
+%if %{with debug_log}
+%define debug_log --enable-debug-log
+%else
+%define debug_log --disable-debug-log
+%endif
+
+%if %{with debug_kmem}
+%define debug_kmem --enable-debug-kmem
+%else
+%define debug_kmem --disable-debug-kmem
+%endif
+
+%if %{with debug_kmem_tracking}
+%define debug_kmem_tracking --enable-debug-kmem-tracking
+%else
+%define debug_kmem_tracking --disable-debug-kmem-tracking
+%endif
+
+%if %{with atomic_spinlocks}
+%define atomic_spinlocks --enable-atomic-spinlocks
+%else
+%define atomic_spinlocks --disable-atomic-spinlocks
+%endif
+
+%setup -n %{kmod_name}-%{version}
+%build
+%configure \
+        --with-config=kernel \
+        --with-linux=%{ksrc} \
+        --with-linux-obj=%{kobj} \
+        %{debug} \
+        %{debug_log} \
+        %{debug_kmem} \
+        %{debug_kmem_tracking} \
+        %{atomic_spinlocks}
+make %{?_smp_mflags}
+
+%install
+make install \
+        DESTDIR=${RPM_BUILD_ROOT} \
+        INSTALL_MOD_DIR=extra/%{kmod_name}
+%{__rm} -f %{buildroot}/lib/modules/%{kverrel}/modules.*
+# find-debuginfo.sh only considers executables
+%{__chmod} u+x  %{buildroot}/lib/modules/%{kverrel}/extra/*/*/*
+
+%clean
+rm -rf $RPM_BUILD_ROOT
+
+%files -n kmod-%{kmod_name}-devel
+%{_usrsrc}/%{kmod_name}-%{version}
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/rpm/redhat/spl.spec.in
@@ -0,0 +1,71 @@
+Name:           @PACKAGE@
+Version:        @VERSION@
+Release:        @RELEASE@%{?dist}
+Summary:        Commands to control the kernel modules
+
+Group:          System Environment/Kernel
+License:        GPLv2+
+URL:            http://zfsonlinux.org/
+Source0:        %{name}-%{version}.tar.gz
+BuildRoot:      %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
+Requires:       %{name}-kmod = %{version}
+Provides:       %{name}-kmod-common = %{version}
+
+%description
+This package contains the commands to verify the SPL
+kernel modules are functioning properly.
+
+%prep
+%setup -q
+
+%build
+%configure --with-config=user
+make %{?_smp_mflags}
+
+%install
+%{__rm} -rf $RPM_BUILD_ROOT
+make install DESTDIR=%{?buildroot}
+
+%files
+%doc AUTHORS COPYING DISCLAIMER
+%{_sbindir}/*
+%{_mandir}/man1/*
+%{_mandir}/man5/*
+
+%changelog
+* Tue Mar 22 2016 Ned Bass <bass6@llnl.gov> - 0.6.5.6-1
+- Remove artificial architecture restrictions in packaging
+- Add support for s390[x] zfsonlinux/spl#537
+* Wed Mar 9 2016 Ned Bass <bass6@llnl.gov> - 0.6.5.5-1
+- Linux 4.5 compatibility zfsonlinux/spl#524
+- Create working debuginfo packages on Red Hat zfsonlinux/zfs#4224
+- Allow copy-builtin to run multiple times zfsonlinux/spl#526
+- Use safer flags for in-kernel memory allocations zfsonlinux/spl#523
+- Fix potential deadlock in cv_wait() zfsonlinux/zfs#4106
+- Fix livelock in shrinker zfsonlinux/zfs#3936
+* Fri Jan  8 2016 Ned Bass <bass6@llnl.gov> - 0.6.5.4-1
+- Build fixes on SPARC and some kernels
+- Fix taskq dynamic spawning deadlock
+- Fix builtin kernel builds
+- Fix crash due to overflow in P2ROUNDUP macro
+- Fix deadlock during direct memory reclaim
+* Tue Oct 13 2015 Ned Bass <bass6@llnl.gov> - 0.6.5.3-1
+- Fix CPU hotplug zfsonlinux/spl#482
+- Disable dynamic taskqs by default to avoid deadlock zfsonlinux/spl#484
+* Tue Sep 29 2015 Ned Bass <bass6@llnl.gov> - 0.6.5.2-1
+- Released 0.6.5.2-1
+- Fix PAX Patch/Grsec SLAB_USERCOPY panic zfsonlinux/zfs#3796
+- Always remove during dkms uninstall/update zfsonlinux/spl#476
+* Thu Sep 19 2015 Ned Bass <bass6@llnl.gov> - 0.6.5.1-1
+- Released 0.6.5.1-1, no changes from spl-0.6.5
+* Thu Sep 10 2015 Brian Behlendorf <behlendorf1@llnl.gov> - 0.6.5-1
+- Released 0.6.5-1, detailed release notes are available at:
+- https://github.com/zfsonlinux/zfs/releases/tag/zfs-0.6.5
+* Wed Apr  8 2015 Brian Behlendorf <behlendorf1@llnl.gov> - 0.6.4-1
+- Released 0.6.4-1
+* Thu Jun 12 2014 Brian Behlendorf <behlendorf1@llnl.gov> - 0.6.3-1
+- Released 0.6.3-1
+* Wed Aug 21 2013 Brian Behlendorf <behlendorf1@llnl.gov> - 0.6.2-1
+- Released 0.6.2-1
+* Fri Mar 22 2013 Brian Behlendorf <behlendorf1@llnl.gov> - 0.6.1-1
+- First official stable release.
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/scripts/Makefile.am
@@ -0,0 +1,4 @@
+EXTRA_DIST = check.sh dkms.mkconf dkms.postbuild kmodtool
+
+check:
+	scripts/check.sh
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/scripts/Makefile.in
@@ -0,0 +1,496 @@
+# Makefile.in generated by automake 1.15 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2014 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+VPATH = @srcdir@
+am__is_gnu_make = { \
+  if test -z '$(MAKELEVEL)'; then \
+    false; \
+  elif test -n '$(MAKE_HOST)'; then \
+    true; \
+  elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+    true; \
+  else \
+    false; \
+  fi; \
+}
+am__make_running_with_option = \
+  case $${target_option-} in \
+      ?) ;; \
+      *) echo "am__make_running_with_option: internal error: invalid" \
+              "target option '$${target_option-}' specified" >&2; \
+         exit 1;; \
+  esac; \
+  has_opt=no; \
+  sane_makeflags=$$MAKEFLAGS; \
+  if $(am__is_gnu_make); then \
+    sane_makeflags=$$MFLAGS; \
+  else \
+    case $$MAKEFLAGS in \
+      *\\[\ \	]*) \
+        bs=\\; \
+        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
+    esac; \
+  fi; \
+  skip_next=no; \
+  strip_trailopt () \
+  { \
+    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+  }; \
+  for flg in $$sane_makeflags; do \
+    test $$skip_next = yes && { skip_next=no; continue; }; \
+    case $$flg in \
+      *=*|--*) continue;; \
+        -*I) strip_trailopt 'I'; skip_next=yes;; \
+      -*I?*) strip_trailopt 'I';; \
+        -*O) strip_trailopt 'O'; skip_next=yes;; \
+      -*O?*) strip_trailopt 'O';; \
+        -*l) strip_trailopt 'l'; skip_next=yes;; \
+      -*l?*) strip_trailopt 'l';; \
+      -[dEDm]) skip_next=yes;; \
+      -[JT]) skip_next=yes;; \
+    esac; \
+    case $$flg in \
+      *$$target_option*) has_opt=yes; break;; \
+    esac; \
+  done; \
+  test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+target_triplet = @target@
+subdir = scripts
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/config/libtool.m4 \
+	$(top_srcdir)/config/ltoptions.m4 \
+	$(top_srcdir)/config/ltsugar.m4 \
+	$(top_srcdir)/config/ltversion.m4 \
+	$(top_srcdir)/config/lt~obsolete.m4 \
+	$(top_srcdir)/config/spl-build.m4 \
+	$(top_srcdir)/config/spl-meta.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/spl_config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo "  GEN     " $@;
+am__v_GEN_1 = 
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 = 
+SOURCES =
+DIST_SOURCES =
+am__can_run_installinfo = \
+  case $$AM_UPDATE_INFO_DIR in \
+    n|no|NO) false;; \
+    *) (install-info --version) >/dev/null 2>&1;; \
+  esac
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+am__DIST_COMMON = $(srcdir)/Makefile.in
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ALIEN = @ALIEN@
+ALIEN_VERSION = @ALIEN_VERSION@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEBUG_CFLAGS = @DEBUG_CFLAGS@
+DEBUG_KMEM = @DEBUG_KMEM@
+DEBUG_KMEM_TRACKING = @DEBUG_KMEM_TRACKING@
+DEBUG_SPL = @DEBUG_SPL@
+DEFAULT_PACKAGE = @DEFAULT_PACKAGE@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DPKG = @DPKG@
+DPKGBUILD = @DPKGBUILD@
+DPKGBUILD_VERSION = @DPKGBUILD_VERSION@
+DPKG_VERSION = @DPKG_VERSION@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GREP = @GREP@
+HAVE_ALIEN = @HAVE_ALIEN@
+HAVE_DPKG = @HAVE_DPKG@
+HAVE_DPKGBUILD = @HAVE_DPKGBUILD@
+HAVE_RPM = @HAVE_RPM@
+HAVE_RPMBUILD = @HAVE_RPMBUILD@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+KERNELCPPFLAGS = @KERNELCPPFLAGS@
+KERNELMAKE_PARAMS = @KERNELMAKE_PARAMS@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LINUX = @LINUX@
+LINUX_OBJ = @LINUX_OBJ@
+LINUX_SYMBOLS = @LINUX_SYMBOLS@
+LINUX_VERSION = @LINUX_VERSION@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+RANLIB = @RANLIB@
+RELEASE = @RELEASE@
+RPM = @RPM@
+RPMBUILD = @RPMBUILD@
+RPMBUILD_VERSION = @RPMBUILD_VERSION@
+RPM_DEFINE_COMMON = @RPM_DEFINE_COMMON@
+RPM_DEFINE_DKMS = @RPM_DEFINE_DKMS@
+RPM_DEFINE_KMOD = @RPM_DEFINE_KMOD@
+RPM_DEFINE_UTIL = @RPM_DEFINE_UTIL@
+RPM_SPEC_DIR = @RPM_SPEC_DIR@
+RPM_VERSION = @RPM_VERSION@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SPL_CONFIG = @SPL_CONFIG@
+SPL_META_ALIAS = @SPL_META_ALIAS@
+SPL_META_AUTHOR = @SPL_META_AUTHOR@
+SPL_META_DATA = @SPL_META_DATA@
+SPL_META_LICENSE = @SPL_META_LICENSE@
+SPL_META_LT_AGE = @SPL_META_LT_AGE@
+SPL_META_LT_CURRENT = @SPL_META_LT_CURRENT@
+SPL_META_LT_REVISION = @SPL_META_LT_REVISION@
+SPL_META_NAME = @SPL_META_NAME@
+SPL_META_RELEASE = @SPL_META_RELEASE@
+SPL_META_VERSION = @SPL_META_VERSION@
+SRPM_DEFINE_COMMON = @SRPM_DEFINE_COMMON@
+SRPM_DEFINE_DKMS = @SRPM_DEFINE_DKMS@
+SRPM_DEFINE_KMOD = @SRPM_DEFINE_KMOD@
+SRPM_DEFINE_UTIL = @SRPM_DEFINE_UTIL@
+STRIP = @STRIP@
+VENDOR = @VENDOR@
+VERSION = @VERSION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+runstatedir = @runstatedir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+EXTRA_DIST = check.sh dkms.mkconf dkms.postbuild kmodtool
+all: all-am
+
+.SUFFIXES:
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+	        && { if test -f $@; then exit 0; else break; fi; }; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu scripts/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --gnu scripts/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+	esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
+tags TAGS:
+
+ctags CTAGS:
+
+cscope cscopelist:
+
+
+distdir: $(DISTFILES)
+	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	list='$(DISTFILES)'; \
+	  dist_files=`for file in $$list; do echo $$file; done | \
+	  sed -e "s|^$$srcdirstrip/||;t" \
+	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+	case $$dist_files in \
+	  */*) $(MKDIR_P) `echo "$$dist_files" | \
+			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+			   sort -u` ;; \
+	esac; \
+	for file in $$dist_files; do \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  if test -d $$d/$$file; then \
+	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+	    if test -d "$(distdir)/$$file"; then \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+	  else \
+	    test -f "$(distdir)/$$file" \
+	    || cp -p $$d/$$file "$(distdir)/$$file" \
+	    || exit 1; \
+	  fi; \
+	done
+check-am: all-am
+check: check-am
+all-am: Makefile
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+	if test -z '$(STRIP)'; then \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	      install; \
+	else \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+	fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-am
+	-rm -f Makefile
+distclean-am: clean-am distclean-generic
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: install-am install-strip
+
+.PHONY: all all-am check check-am clean clean-generic clean-libtool \
+	cscopelist-am ctags-am distclean distclean-generic \
+	distclean-libtool distdir dvi dvi-am html html-am info info-am \
+	install install-am install-data install-data-am install-dvi \
+	install-dvi-am install-exec install-exec-am install-html \
+	install-html-am install-info install-info-am install-man \
+	install-pdf install-pdf-am install-ps install-ps-am \
+	install-strip installcheck installcheck-am installdirs \
+	maintainer-clean maintainer-clean-generic mostlyclean \
+	mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+	tags-am uninstall uninstall-am
+
+.PRECIOUS: Makefile
+
+
+check:
+	scripts/check.sh
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/scripts/check.sh
@@ -0,0 +1,97 @@
+#!/bin/bash
+###############################################################################
+# Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
+# Copyright (C) 2007 The Regents of the University of California.
+# Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+# Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+# UCRL-CODE-235197
+#
+# This file is part of the SPL, Solaris Porting Layer.
+# For details, see <http://zfsonlinux.org/>.
+#
+# The SPL is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 2 of the License, or (at your
+# option) any later version.
+#
+# The SPL is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+###############################################################################
+# This script runs the full set of regression tests.
+###############################################################################
+
+prog=check.sh
+spl_module=../module/spl/spl.ko
+splat_module=../module/splat/splat.ko
+splat_cmd=../cmd/splat
+verbose=
+
+die() {
+	echo "${prog}: $1" >&2
+	exit 1
+}
+
+warn() {
+	echo "${prog}: $1" >&2
+}
+
+if [ -n "$V" ]; then
+	verbose="-v"
+fi
+
+if [ -n "$TESTS" ]; then
+	tests="$TESTS"
+else
+	tests="-a"
+fi
+
+if [ $(id -u) != 0 ]; then
+	die "Must run as root"
+fi
+
+if /sbin/lsmod | egrep -q "^spl|^splat"; then
+	die "Must start with spl modules unloaded"
+fi
+
+if [ ! -f ${spl_module} ] || [ ! -f ${splat_module} ]; then
+	die "Source tree must be built, run 'make'"
+fi
+
+/sbin/modprobe zlib_inflate &>/dev/null
+/sbin/modprobe zlib_deflate &>/dev/null
+
+echo "Loading ${spl_module}"
+/sbin/insmod ${spl_module} || die "Failed to load ${spl_module}"
+
+echo "Loading ${splat_module}"
+/sbin/insmod ${splat_module} || die "Unable to load ${splat_module}"
+
+# Wait a maximum of 3 seconds for udev to detect the new splatctl 
+# device, if we do not see the character device file created assume
+# udev is not running and manually create the character device.
+for i in `seq 1 50`; do
+	sleep 0.1
+
+	if [ -c /dev/splatctl ]; then
+		break
+	fi
+
+	if [ $i -eq 50 ]; then
+		mknod /dev/splatctl c 229 0
+	fi
+done
+
+$splat_cmd $tests $verbose
+
+echo "Unloading ${splat_module}"
+/sbin/rmmod ${splat_module} || die "Failed to unload ${splat_module}"
+
+echo "Unloading ${spl_module}"
+/sbin/rmmod ${spl_module} || die "Unable to unload ${spl_module}"
+
+exit 0
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/scripts/dkms.mkconf
@@ -0,0 +1,79 @@
+#!/bin/sh
+
+PROG=$0
+
+pkgcfg=/etc/sysconfig/spl
+
+while getopts "n:v:c:f:" opt; do
+        case $opt in
+                n) pkgname=$OPTARG ;;
+                v) pkgver=$OPTARG  ;;
+                c) pkgcfg=$OPTARG ;;
+                f) filename=$OPTARG ;;
+        esac
+done
+
+if [ -z "${pkgname}" -o -z "${pkgver}" -o -z "${filename}" ]; then
+        echo "Usage: $PROG -n <pkgname> -v <pkgver> -c <pkgcfg> -f <filename>"
+        exit 1
+fi
+
+cat >${filename} <<EOF
+PACKAGE_NAME="${pkgname}"
+PACKAGE_VERSION="${pkgver}"
+PACKAGE_CONFIG="${pkgcfg}"
+PRE_BUILD="configure
+  --prefix=/usr
+  --with-config=kernel
+  --with-linux=\${kernel_source_dir}
+  --with-linux-obj=\${kernel_source_dir}
+  \$(
+    [[ -r \${PACKAGE_CONFIG} ]] \\
+    && source \${PACKAGE_CONFIG} \\
+    && shopt -q -s extglob \\
+    && \\
+    {
+      if [[ \${SPL_DKMS_ENABLE_DEBUG,,} == @(y|yes) ]]
+      then
+        echo --enable-debug
+      fi
+      if [[ \${SPL_DKMS_ENABLE_DEBUG_KMEM,,} == @(y|yes) ]]
+      then
+        echo --enable-debug-kmem
+      fi
+      if [[ \${SPL_DKMS_ENABLE_DEBUG_KMEM_TRACKING,,} == @(y|yes) ]]
+      then
+        echo --enable-debug-kmem-tracking
+      fi
+      if [[ \${SPL_DKMS_ENABLE_ATOMIC_SPINLOCKS,,} == @(y|yes) ]]
+      then
+        echo --enable-atomic-spinlocks
+      fi
+    }
+  )
+"
+POST_BUILD="scripts/dkms.postbuild
+  -n \${PACKAGE_NAME}
+  -v \${PACKAGE_VERSION}
+  -a \${arch}
+  -k \${kernelver}
+  -t \${dkms_tree}
+"
+AUTOINSTALL="yes"
+REMAKE_INITRD="no"
+MAKE[0]="make"
+STRIP[0]="\$(
+  [[ -r \${PACKAGE_CONFIG} ]] \\
+  && source \${PACKAGE_CONFIG} \\
+  && shopt -q -s extglob \\
+  && [[ \${SPL_DKMS_DISABLE_STRIP,,} == @(y|yes) ]] \\
+  && echo -n no
+)"
+STRIP[1]="\${STRIP[0]}"
+BUILT_MODULE_NAME[0]="spl"
+BUILT_MODULE_LOCATION[0]="module/spl/"
+DEST_MODULE_LOCATION[0]="/extra/spl/spl"
+BUILT_MODULE_NAME[1]="splat"
+BUILT_MODULE_LOCATION[1]="module/splat/"
+DEST_MODULE_LOCATION[1]="/extra/splat/splat"
+EOF
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/scripts/dkms.postbuild
@@ -0,0 +1,24 @@
+#!/bin/sh
+
+PROG=$0
+
+while getopts "a:k:n:t:v:" opt; do
+	case $opt in
+		a) arch=$OPTARG    ;;
+		k) kver=$OPTARG    ;;
+		n) pkgname=$OPTARG ;;
+		t) tree=$OPTARG    ;;
+		v) pkgver=$OPTARG  ;;
+	esac
+done
+
+if [ -z "${arch}" -o -z "${kver}" -o -z "${pkgname}" -o \
+     -z "${tree}" -o -z "${pkgver}" ]; then
+	echo "Usage: $PROG -a <arch> -k <kver> -n <pkgname>" \
+	     "-t <tree> -v <pkgver>"
+	exit 1
+fi
+
+cp ${tree}/${pkgname}/${pkgver}/build/spl_config.h          \
+   ${tree}/${pkgname}/${pkgver}/build/module/Module.symvers \
+   ${tree}/${pkgname}/${pkgver}/${kver}/${arch}/
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/scripts/kmodtool
@@ -0,0 +1,592 @@
+#!/bin/bash
+
+# kmodtool - Helper script for building kernel module RPMs
+# Copyright (c) 2003-2012 Ville Skyttä <ville.skytta@iki.fi>,
+#                         Thorsten Leemhuis <fedora@leemhuis.info>
+#                         Nicolas Chauvet <kwizart@gmail.com>
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be
+# included in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+shopt -s extglob
+
+myprog="kmodtool-${repo}"
+myver="0.12.1"
+
+kmodname=
+build_kernels="current"
+kernels_known_variants=
+kernel_versions=
+kernel_versions_to_build_for=
+prefix=
+filterfile=
+target=
+buildroot=
+
+error_out()
+{
+	local errorlevel=${1}
+	shift
+	echo "Error: $@" >&2
+	# the next line is not multi-line safe -- not needed *yet*
+	echo "%global kmodtool_check echo \"kmodtool error: $@\"; exit ${errorlevel};"
+	exit ${errorlevel}
+}
+
+print_rpmtemplate_header()
+{
+	echo
+	echo '%global kmodinstdir_prefix  '${prefix}/lib/modules/
+	echo '%global kmodinstdir_postfix '/extra/${kmodname}/
+	echo '%global kernel_versions     '${kernel_versions}
+	echo
+}
+
+print_akmodtemplate ()
+{
+	echo
+	cat <<EOF
+
+%global akmod_install mkdir -p \$RPM_BUILD_ROOT/%{_usrsrc}/akmods/; \\\
+LANG=C rpmbuild --define "_sourcedir %{_sourcedir}" \\\
+--define "_srcrpmdir \$RPM_BUILD_ROOT/%{_usrsrc}/akmods/" \\\
+-bs --nodeps %{_specdir}/%{name}.spec ; \\\
+ln -s \$(ls \$RPM_BUILD_ROOT/%{_usrsrc}/akmods/) \$RPM_BUILD_ROOT/%{_usrsrc}/akmods/${kmodname}-kmod.latest
+
+%package -n akmod-${kmodname}
+Summary:	Akmod package for ${kmodname} kernel module(s) 
+Group: 		System Environment/Kernel
+Requires:   kmodtool
+Requires: 	akmods
+%{?AkmodsBuildRequires:Requires: %{AkmodsBuildRequires}}
+# same requires and provides as a kmods package would have
+Requires: 	${kmodname}-kmod-common >= %{?epoch:%{epoch}:}%{version}
+Provides: 	${kmodname}-kmod = %{?epoch:%{epoch}:}%{version}-%{release}
+EOF
+
+	if [[ ${obsolete_name} ]]; then
+		echo "Provides:   akmod-${obsolete_name} = ${obsolete_version}"
+		echo "Obsoletes:  akmod-${obsolete_name} < ${obsolete_version}"
+	fi
+
+	cat <<EOF
+
+%description -n akmod-${kmodname}
+This package provides the akmod package for the ${kmodname} kernel modules.
+
+%posttrans -n akmod-${kmodname}
+nohup ${prefix}/sbin/akmods --from-akmod-posttrans --akmod ${kmodname} &> /dev/null &
+
+%files -n akmod-${kmodname}
+%defattr(-,root,root,-)
+%{_usrsrc}/akmods/*
+
+EOF
+}
+
+print_akmodmeta ()
+{
+		cat <<EOF
+%package      -n kmod-${kmodname}
+Summary:         Metapackage which tracks in ${kmodname} kernel module for newest kernel${dashvariant}
+Group:           System Environment/Kernel
+
+Provides:        ${kmodname}-kmod = %{?epoch:%{epoch}:}%{version}-%{release}
+Provides:        kmod-${kmodname}-xen = %{?epoch:%{epoch}:}%{version}-%{release}
+Provides:        kmod-${kmodname}-smp = %{?epoch:%{epoch}:}%{version}-%{release}
+Provides:        kmod-${kmodname}-PAE = %{?epoch:%{epoch}:}%{version}-%{release}
+Requires:        akmod-${kmodname} = %{?epoch:%{epoch}:}%{version}-%{release}
+EOF
+
+	if [[ ${obsolete_name} ]]; then
+		echo "Provides:        kmod-${obsolete_name} = ${obsolete_version}"
+		echo "Obsoletes:       kmod-${obsolete_name} < ${obsolete_version}"
+	fi
+cat <<EOF
+
+%description  -n kmod-${kmodname}${dashvariant}
+This is a meta-package without payload which sole purpose is to require the
+${kmodname} kernel module(s) for the newest kernel${dashvariant},
+to make sure you get it together with a new kernel.
+
+%files        -n kmod-${kmodname}${dashvariant}
+%defattr(644,root,root,755)
+EOF
+}
+
+print_rpmtemplate_per_kmodpkg ()
+{
+	if [[ "${1}" == "--custom" ]]; then
+		shift
+		local customkernel=true
+	elif [[ "${1}" == "--redhat" ]]; then
+		# this is needed for akmods
+		shift
+		local redhatkernel=true
+	fi
+
+	local kernel_uname_r=${1}
+	local kernel_variant="${2:+-${2}}"
+
+    # first part
+	cat <<EOF
+%package       -n kmod-${kmodname}-${kernel_uname_r}
+Summary:          ${kmodname} kernel module(s) for ${kernel_uname_r}
+Group:            System Environment/Kernel
+Provides:         kernel-modules-for-kernel = ${kernel_uname_r}
+Provides:         kmod-${kmodname}-uname-r = ${kernel_uname_r}
+Provides:         ${kmodname}-kmod = %{?epoch:%{epoch}:}%{version}-%{release}
+Requires:         ${kmodname}-kmod-common >= %{?epoch:%{epoch}:}%{version}
+Requires(post):   ${prefix}/sbin/depmod
+Requires(postun): ${prefix}/sbin/depmod
+EOF
+
+	if [[ ${obsolete_name} ]]; then
+		echo "Provides:        kmod-${obsolete_name}-${kernel_uname_r} = ${obsolete_version}"
+		echo "Obsoletes:       kmod-${obsolete_name}-${kernel_uname_r} < ${obsolete_version}"
+	fi
+
+	# second part
+	if [[ ! "${customkernel}" ]]; then
+	     cat <<EOF
+Requires:         kernel-uname-r = ${kernel_uname_r}
+BuildRequires:	  kernel-devel-uname-r = ${kernel_uname_r}
+%{?KmodsRequires:Requires: %{KmodsRequires}-uname-r = ${kernel_uname_r}}
+%{?KmodsRequires:BuildRequires: %{KmodsRequires}-uname-r = ${kernel_uname_r}}
+%post          -n kmod-${kmodname}-${kernel_uname_r}
+${prefix}/sbin/depmod -aeF /boot/System.map-${kernel_uname_r} ${kernel_uname_r} > /dev/null || :
+%postun        -n kmod-${kmodname}-${kernel_uname_r}
+${prefix}/sbin/depmod  -aF /boot/System.map-${kernel_uname_r} ${kernel_uname_r} &> /dev/null || :
+
+EOF
+	else
+	  cat <<EOF
+%post          -n kmod-${kmodname}-${kernel_uname_r}
+[[ "$(uname -r)" == "${kernel_uname_r}"  ]] && ${prefix}/sbin/depmod -a > /dev/null || :
+%postun        -n kmod-${kmodname}-${kernel_uname_r}
+[[ "$(uname -r)" == "${kernel_uname_r}"  ]] && ${prefix}/sbin/depmod -a > /dev/null || :
+
+EOF
+	fi
+
+  # third part
+	cat <<EOF
+%description  -n kmod-${kmodname}-${kernel_uname_r}
+This package provides the ${kmodname} kernel modules built for the Linux
+kernel ${kernel_uname_r} for the %{_target_cpu} family of processors.
+%files        -n kmod-${kmodname}-${kernel_uname_r}
+%defattr(644,root,root,755)
+%dir $prefix/lib/modules/${kernel_uname_r}/extra
+${prefix}/lib/modules/${kernel_uname_r}/extra/${kmodname}/
+
+
+EOF
+}
+
+print_rpmtemplate_kmoddevelpkg ()
+{
+	if [[ "${1}" == "--custom" ]]; then
+		shift
+		local customkernel=true
+	elif [[ "${1}" == "--redhat" ]]; then
+		shift
+		local redhatkernel=true
+	fi
+
+	local kernel_uname_r=${1}
+
+	cat <<EOF
+%package       -n kmod-${kmodname}-devel
+Summary:          ${kmodname} kernel module(s) devel common
+Group:            System Environment/Kernel
+Provides:         ${kmodname}-devel-kmod = %{?epoch:%{epoch}:}%{version}-%{release}
+EOF
+
+	if [[ ! ${customkernel} ]] && [[ ! ${redhatkernel} ]]; then
+		echo "Requires:        kmod-${kmodname}-devel-${kernel_uname_r} >= %{?epoch:%{epoch}:}%{version}-%{release}"
+	fi
+
+	if [[ ${obsolete_name} ]]; then
+		echo "Provides:        kmod-${obsolete_name}-devel = ${obsolete_version}"
+		echo "Obsoletes:       kmod-${obsolete_name}-devel < ${obsolete_version}"
+	fi
+
+	cat <<EOF
+%description  -n kmod-${kmodname}-devel
+This package provides the common header files to build kernel modules
+which depend on the ${kmodname} kernel module.  It may optionally require
+the ${kmodname}-devel-<kernel> objects for the newest kernel.
+
+%files        -n kmod-${kmodname}-devel
+%defattr(644,root,root,755)
+%{_usrsrc}/${kmodname}-%{version}
+EOF
+
+	for kernel in ${1}; do
+		local kernel_uname_r=${kernel}
+		echo "%exclude %{_usrsrc}/${kmodname}-%{version}/${kernel_uname_r}"
+	done
+
+	echo
+	echo
+}
+
+print_rpmtemplate_per_kmoddevelpkg ()
+{
+	if [[ "${1}" == "--custom" ]]; then
+		shift
+		local customkernel=true
+	elif [[ "${1}" == "--redhat" ]]; then
+		# this is needed for akmods
+		shift
+		local redhatkernel=true
+	fi
+
+	local kernel_uname_r=${1}
+	local kernel_variant="${2:+-${2}}"
+
+	# first part
+	cat <<EOF
+%package       -n kmod-${kmodname}-devel-${kernel_uname_r}
+Summary:          ${kmodname} kernel module(s) devel for ${kernel_uname_r}
+Group:            System Environment/Kernel
+Provides:         kernel-objects-for-kernel = ${kernel_uname_r}
+Provides:         ${kmodname}-devel-kmod = %{?epoch:%{epoch}:}%{version}-%{release}
+Provides:         kmod-${kmodname}-devel-uname-r = ${kernel_uname_r}
+EOF
+
+	if [[ ${obsolete_name} ]]; then
+		echo "Provides:        kmod-${obsolete_name}-devel-${kernel_uname_r} = ${obsolete_version}"
+		echo "Obsoletes:       kmod-${obsolete_name}-devel-${kernel_uname_r} < ${obsolete_version}"
+	fi
+
+	# second part
+	if [[ ! "${customkernel}" ]]; then
+		cat <<EOF
+Requires:         kernel-devel-uname-r = ${kernel_uname_r}
+BuildRequires:    kernel-devel-uname-r = ${kernel_uname_r}
+%{?KmodsDevelRequires:Requires: %{KmodsDevelRequires}-uname-r = ${kernel_uname_r}}
+%{?KmodsDevelRequires:BuildRequires: %{KmodsDevelRequires}-uname-r = ${kernel_uname_r}}
+EOF
+	fi
+
+	# third part
+	cat <<EOF
+%description  -n kmod-${kmodname}-devel-${kernel_uname_r}
+This package provides objects and symbols required to build kernel modules
+which depend on the ${kmodname} kernel modules built for the Linux
+kernel ${kernel_uname_r} for the %{_target_cpu} family of processors.
+%files        -n kmod-${kmodname}-devel-${kernel_uname_r}
+%defattr(644,root,root,755)
+%{_usrsrc}/${kmodname}-%{version}/${kernel_uname_r}
+
+
+EOF
+}
+
+print_rpmtemplate_kmodmetapkg ()
+{
+		local kernel_uname_r=${1}
+		local kernel_variant="${2:+-${2}}"
+
+		cat <<EOF
+%package      -n kmod-${kmodname}${kernel_variant}
+Summary:         Metapackage which tracks in ${kmodname} kernel module for newest kernel${kernel_variant}
+Group:           System Environment/Kernel
+
+Provides:        ${kmodname}-kmod = %{?epoch:%{epoch}:}%{version}-%{release}
+Requires:        kmod-${kmodname}-${kernel_uname_r} >= %{?epoch:%{epoch}:}%{version}-%{release}
+%{?KmodsMetaRequires:Requires: %{?KmodsMetaRequires}}
+EOF
+
+		if [[ ${obsolete_name} ]]; then
+			echo "Provides:        kmod-${obsolete_name}${kernel_variant} = ${obsolete_version}"
+			echo "Obsoletes:       kmod-${obsolete_name}${kernel_variant} < ${obsolete_version}"
+		fi
+
+		cat <<EOF
+
+%description  -n kmod-${kmodname}${kernel_variant}
+This is a meta-package without payload which sole purpose is to require the
+${kmodname} kernel module(s) for the newest kernel${kernel_variant}.
+to make sure you get it together with a new kernel.
+
+%files        -n kmod-${kmodname}${kernel_variant}
+%defattr(644,root,root,755)
+
+
+EOF
+}
+
+print_customrpmtemplate ()
+{
+	for kernel in ${1}
+	do
+		if [[ -e "${buildroot}/usr/src/kernels/${kernel}" ]] ; then
+			# this looks like a Fedora/RH kernel -- print a normal template (which includes the proper BR) and be happy :)
+			kernel_versions="${kernel_versions}${kernel}___${buildroot}%{_usrsrc}/kernels/${kernel} "
+
+			# parse kernel versions string and print template
+			local kernel_verrelarch=${kernel%%${kernels_known_variants}}
+			print_rpmtemplate_per_kmodpkg --redhat ${kernel} ${kernel##${kernel_verrelarch}}
+
+			# create development package
+			if [[ "${devel}" ]]; then
+				# create devel package including common headers
+				print_rpmtemplate_kmoddevelpkg --redhat ${kernel} ${kernel##${kernel_verrelarch}}
+
+				# create devel package
+				print_rpmtemplate_per_kmoddevelpkg --redhat ${kernel} ${kernel##${kernel_verrelarch}}
+			fi
+		elif [[ -e ${prefix}/lib/modules/"${kernel}"/build/Makefile ]] ; then 
+			# likely a user-build-kernel with available buildfiles
+			# fixme: we should check if uname from Makefile is the same as ${kernel}
+
+			kernel_versions="${kernel_versions}${kernel}___${prefix}/lib/modules/${kernel}/build/ "
+			print_rpmtemplate_per_kmodpkg --custom "${kernel}"
+
+			# create development package
+			if [[ "${devel}" ]]; then
+				# create devel package including common headers
+				print_rpmtemplate_kmoddevelpkg --custom "${kernel}"
+
+				# create devel package
+				print_rpmtemplate_per_kmoddevelpkg --custom "${kernel}"
+			fi
+		else
+			error_out 2 "Don't know how to handle ${kernel} -- ${prefix}/lib/modules/${kernel}/build/Makefile not found"
+		fi
+	done
+
+	# well, it's no header anymore, but who cares ;-)
+	print_rpmtemplate_header
+}
+
+
+print_rpmtemplate ()
+{
+	# create kernel_versions var
+	for kernel_version in ${kernel_versions_to_build_for}
+	do
+		kernel_versions="${kernel_versions}${kernel_version}___%{_usrsrc}/kernels/${kernel_version} "
+	done
+
+	# and print it and some other required stuff as macro
+	print_rpmtemplate_header
+
+	# now print the packages itselfs
+	for kernel in ${kernel_versions_to_build_for} ; do
+
+		local kernel_verrelarch=${kernel%%${kernels_known_variants}}
+
+		# create metapackage 
+		print_rpmtemplate_kmodmetapkg ${kernel} ${kernel##${kernel_verrelarch}}
+
+		# create package
+		print_rpmtemplate_per_kmodpkg ${kernel} ${kernel##${kernel_verrelarch}}
+
+		if [[ "${devel}" ]]; then
+			# create devel package including common headers
+			print_rpmtemplate_kmoddevelpkg ${kernel} ${kernel##${kernel_verrelarch}}
+
+			# create devel package
+			print_rpmtemplate_per_kmoddevelpkg ${kernel} ${kernel##${kernel_verrelarch}}
+		fi
+	done
+}
+
+myprog_help ()
+{
+	echo "Usage: $(basename ${0}) [OPTIONS]"
+	echo $'\n'"Creates a template to be used during kmod building"
+	echo $'\n'"Available options:"
+	echo " --filterfile <file>  -- filter the results with grep --file <file>"
+	echo " --for-kernels <list> -- created templates only for these kernels"
+	echo " --kmodname <file>    -- name of the kmod (required)"
+	echo " --devel              -- make kmod-devel package"
+	echo " --noakmod            -- no akmod package"
+	echo " --repo <name>        -- use buildsys-build-<name>-kerneldevpkgs"
+	echo " --target <arch>      -- target-arch (required)"
+	echo " --buildroot <dir>    -- Build root (place to look for build files)"
+}
+
+while [ "${1}" ] ; do
+	case "${1}" in
+		--filterfile)
+			shift
+			if [[ ! "${1}" ]] ; then
+				error_out 2 "Please provide path to a filter-file together with --filterfile" >&2
+			elif [[ ! -e "${1}" ]]; then	
+				error_out 2 "Filterfile ${1} not found" >&2
+			fi
+			filterfile="${1}"
+			shift
+			;;
+		--kmodname)
+			shift
+			if [[ ! "${1}" ]] ; then
+				error_out 2 "Please provide the name of the kmod together with --kmodname" >&2
+	 	    fi
+			# strip pending -kmod
+			kmodname="${1%%-kmod}"
+			shift
+			;;
+		--devel)
+			shift
+			devel="true"
+			;;
+		--prefix)
+			shift
+			if [[ ! "${1}" ]] ; then
+				error_out 2 "Please provide a prefix with --prefix" >&2
+		    fi
+			prefix="${1}"
+			shift
+			;;
+		--repo)
+			shift
+			if [[ ! "${1}" ]] ; then
+				error_out 2 "Please provide the name of the repo together with --repo" >&2
+	 	    fi
+			repo=${1}
+			shift
+			;;
+		--for-kernels)
+			shift
+			if [[ ! "${1}" ]] ; then
+				error_out 2 "Please provide the name of the kmod together with --kmodname" >&2
+	 		fi
+			for_kernels="${1}"
+			shift
+			;;
+		--noakmod)
+			shift
+			noakmod="true"
+			;;
+		--obsolete-name)
+			shift
+			if [[ ! "${1}" ]] ; then
+				error_out 2 "Please provide the name of the kmod to obsolte together with --obsolete-name" >&2
+	 		fi
+			obsolete_name="${1}"
+			shift
+			;;
+		--obsolete-version)
+			shift
+			if [[ ! "${1}" ]] ; then
+				error_out 2 "Please provide the version of the kmod to obsolte together with --obsolete-version" >&2
+	 		fi
+			obsolete_version="${1}"
+			shift
+			;;
+		--target)
+			shift
+			target="${1}"
+			shift
+			;;
+		--akmod)
+			shift
+			build_kernels="akmod"
+			;;
+		--newest)
+			shift
+			build_kernels="newest"
+			;;
+		--current)
+			shift
+			build_kernels="current"
+			;;
+		--buildroot)
+			shift
+			buildroot="${1}"
+			shift
+			;;
+		--help)
+			myprog_help
+			exit 0
+			;;
+		--version)
+			echo "${myprog} ${myver}"
+			exit 0
+			;;
+		*)
+			echo "Error: Unknown option '${1}'." >&2
+			usage >&2
+			exit 2
+			;;
+	esac
+done
+
+if [[ -e ./kmodtool-kernel-variants ]]; then
+	kernels_known_variants="$(cat ./kmodtool-kernel-variants)"
+elif [[ -e /usr/share/kmodtool/kernel-variants ]] ; then
+	kernels_known_variants="$(cat /usr/share/kmodtool/kernel-variants)"
+else
+	kernels_known_variants="@(smp?(-debug)|PAE?(-debug)|debug|kdump|xen|kirkwood|highbank|imx|omap|tegra)"
+fi
+
+# general sanity checks
+if [[ ! "${target}" ]]; then
+		error_out 2 "please pass target arch with --target"
+elif [[ ! "${kmodname}" ]]; then
+		error_out 2 "please pass kmodname with --kmodname"
+elif [[ ! "${kernels_known_variants}" ]] ; then
+		error_out 2 "could not determine known variants"
+elif ( [[ "${obsolete_name}" ]] && [[ ! "${obsolete_version}" ]] ) ||  ( [[ ! "${obsolete_name}" ]] && [[ "${obsolete_version}" ]] ) ; then
+		error_out 2 "you need to provide both --obsolete-name and --obsolete-version"
+fi
+
+# go
+if [[ "${for_kernels}" ]]; then
+	# this is easy:
+	print_customrpmtemplate "${for_kernels}"
+elif [[ "${build_kernels}" == "akmod" ]]; then
+	# do only a akmod package
+	print_akmodtemplate
+	print_akmodmeta
+else
+	# seems we are on out own to decide for which kernels to build
+
+	# we need more sanity checks in this case
+	if [[ ! "${repo}" ]]; then
+		error_out 2 "please provide repo name with --repo"
+	elif ! $(which buildsys-build-${repo}-kerneldevpkgs &> /dev/null) ; then
+		error_out 2 "buildsys-build-${repo}-kerneldevpkgs not found"
+	fi
+
+	# call buildsys-build-${repo}-kerneldevpkgs to get the list of kernels
+	cmdoptions="--target ${target}"
+
+	# filterfile to filter list of kernels?	
+	if [[ "${filterfile}" ]] ; then
+		 cmdoptions="${cmdoptions} --filterfile ${filterfile}"
+	fi
+
+	kernel_versions_to_build_for="$(buildsys-build-${repo}-kerneldevpkgs --${build_kernels} ${cmdoptions})"
+	returncode=$?
+	if (( ${returncode} != 0 )); then
+		error_out 2 "buildsys-build-${repo}-kerneldevpkgs failed: $(buildsys-build-${repo}-kerneldevpkgs --${build_kernels} ${cmdoptions})"
+	fi
+
+	if [[ "${build_kernels}" == "current" ]] && [[ ! "${noakmod}" ]]; then
+		print_akmodtemplate
+	fi
+
+	print_rpmtemplate 
+fi
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/spl.release.in
@@ -0,0 +1 @@
+@SPL_META_VERSION@-@SPL_META_RELEASE@
--- /dev/null
+++ zfcpdump-kernel-4.4/spl/spl_config.h.in
@@ -0,0 +1,190 @@
+/* spl_config.h.in.  Generated from configure.ac by autoheader.  */
+
+/* Atomic types use spinlocks */
+#undef ATOMIC_SPINLOCK
+
+/* Define to 1 to enable basic kmem accounting */
+#undef DEBUG_KMEM
+
+/* Define to 1 to enable detailed kmem tracking */
+#undef DEBUG_KMEM_TRACKING
+
+/* new shrinker callback wants 2 args */
+#undef HAVE_2ARGS_NEW_SHRINKER_CALLBACK
+
+/* old shrinker callback wants 2 args */
+#undef HAVE_2ARGS_OLD_SHRINKER_CALLBACK
+
+/* vfs_fsync() wants 2 args */
+#undef HAVE_2ARGS_VFS_FSYNC
+
+/* vfs_getattr wants 2 args */
+#undef HAVE_2ARGS_VFS_GETATTR
+
+/* vfs_unlink() wants 2 args */
+#undef HAVE_2ARGS_VFS_UNLINK
+
+/* zlib_deflate_workspacesize() wants 2 args */
+#undef HAVE_2ARGS_ZLIB_DEFLATE_WORKSPACESIZE
+
+/* old shrinker callback wants 3 args */
+#undef HAVE_3ARGS_SHRINKER_CALLBACK
+
+/* vfs_unlink() wants 3 args */
+#undef HAVE_3ARGS_VFS_UNLINK
+
+/* vfs_rename() wants 4 args */
+#undef HAVE_4ARGS_VFS_RENAME
+
+/* vfs_rename() wants 5 args */
+#undef HAVE_5ARGS_VFS_RENAME
+
+/* vfs_rename() wants 6 args */
+#undef HAVE_6ARGS_VFS_RENAME
+
+/* kernel defines atomic64_t */
+#undef HAVE_ATOMIC64_T
+
+/* struct ctl_table has ctl_name */
+#undef HAVE_CTL_NAME
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#undef HAVE_DLFCN_H
+
+/* fops->fallocate() exists */
+#undef HAVE_FILE_FALLOCATE
+
+/* struct fs_struct uses spinlock_t */
+#undef HAVE_FS_STRUCT_SPINLOCK
+
+/* fops->fallocate() exists */
+#undef HAVE_INODE_FALLOCATE
+
+/* truncate_range() inode operation is available */
+#undef HAVE_INODE_TRUNCATE_RANGE
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#undef HAVE_INTTYPES_H
+
+/* struct kmem_cache has allocflags */
+#undef HAVE_KMEM_CACHE_ALLOCFLAGS
+
+/* struct kmem_cache has gfpflags */
+#undef HAVE_KMEM_CACHE_GFPFLAGS
+
+/* kuid_t/kgid_t in use */
+#undef HAVE_KUIDGID_T
+
+/* Define to 1 if you have the <memory.h> header file. */
+#undef HAVE_MEMORY_H
+
+/* yes */
+#undef HAVE_PDE_DATA
+
+/* __put_task_struct() is available */
+#undef HAVE_PUT_TASK_STRUCT
+
+/* linux/sched/rt.h exists */
+#undef HAVE_SCHED_RT_HEADER
+
+/* set_fs_pwd() needs const path * */
+#undef HAVE_SET_FS_PWD_WITH_CONST
+
+/* struct shrink_control exists */
+#undef HAVE_SHRINK_CONTROL_STRUCT
+
+/* ->count_objects exists */
+#undef HAVE_SPLIT_SHRINKER_CALLBACK
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#undef HAVE_STDINT_H
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#undef HAVE_STDLIB_H
+
+/* Define to 1 if you have the <strings.h> header file. */
+#undef HAVE_STRINGS_H
+
+/* Define to 1 if you have the <string.h> header file. */
+#undef HAVE_STRING_H
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#undef HAVE_SYS_STAT_H
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#undef HAVE_SYS_TYPES_H
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#undef HAVE_UNISTD_H
+
+/* usleep_range is available */
+#undef HAVE_USLEEP_RANGE
+
+/* yes */
+#undef HAVE_WAIT_ON_BIT_ACTION
+
+/* Define to the sub-directory where libtool stores uninstalled libraries. */
+#undef LT_OBJDIR
+
+/* Name of package */
+#undef PACKAGE
+
+/* Define to the address where bug reports for this package should be sent. */
+#undef PACKAGE_BUGREPORT
+
+/* Define to the full name of this package. */
+#undef PACKAGE_NAME
+
+/* Define to the full name and version of this package. */
+#undef PACKAGE_STRING
+
+/* Define to the one symbol short name of this package. */
+#undef PACKAGE_TARNAME
+
+/* Define to the home page for this package. */
+#undef PACKAGE_URL
+
+/* Define to the version of this package. */
+#undef PACKAGE_VERSION
+
+/* struct rw_semaphore member wait_lock is raw_spinlock_t */
+#undef RWSEM_SPINLOCK_IS_RAW
+
+/* Define to 1 if GPL-only symbols can be used */
+#undef SPL_IS_GPL_COMPATIBLE
+
+/* Define the project alias string. */
+#undef SPL_META_ALIAS
+
+/* Define the project author. */
+#undef SPL_META_AUTHOR
+
+/* Define the project release date. */
+#undef SPL_META_DATA
+
+/* Define the project license. */
+#undef SPL_META_LICENSE
+
+/* Define the libtool library 'age' version information. */
+#undef SPL_META_LT_AGE
+
+/* Define the libtool library 'current' version information. */
+#undef SPL_META_LT_CURRENT
+
+/* Define the libtool library 'revision' version information. */
+#undef SPL_META_LT_REVISION
+
+/* Define the project name. */
+#undef SPL_META_NAME
+
+/* Define the project release. */
+#undef SPL_META_RELEASE
+
+/* Define the project version. */
+#undef SPL_META_VERSION
+
+/* Define to 1 if you have the ANSI C header files. */
+#undef STDC_HEADERS
+
+/* Version number of package */
+#undef VERSION
--- zfcpdump-kernel-4.4.orig/tools/hv/Makefile
+++ zfcpdump-kernel-4.4/tools/hv/Makefile
@@ -5,6 +5,8 @@ PTHREAD_LIBS = -lpthread
 WARNINGS = -Wall -Wextra
 CFLAGS = $(WARNINGS) -g $(PTHREAD_LIBS) $(shell getconf LFS_CFLAGS)
 
+CFLAGS += -D__EXPORTED_HEADERS__ -I../../include/uapi -I../../include
+
 all: hv_kvp_daemon hv_vss_daemon hv_fcopy_daemon
 %: %.c
 	$(CC) $(CFLAGS) -o $@ $^
--- zfcpdump-kernel-4.4.orig/tools/hv/hv_fcopy_daemon.c
+++ zfcpdump-kernel-4.4/tools/hv/hv_fcopy_daemon.c
@@ -37,12 +37,14 @@
 
 static int target_fd;
 static char target_fname[W_MAX_PATH];
+static unsigned long long filesize;
 
 static int hv_start_fcopy(struct hv_start_fcopy *smsg)
 {
 	int error = HV_E_FAIL;
 	char *q, *p;
 
+	filesize = 0;
 	p = (char *)smsg->path_name;
 	snprintf(target_fname, sizeof(target_fname), "%s/%s",
 		 (char *)smsg->path_name, (char *)smsg->file_name);
@@ -98,14 +100,26 @@ done:
 static int hv_copy_data(struct hv_do_fcopy *cpmsg)
 {
 	ssize_t bytes_written;
+	int ret = 0;
 
 	bytes_written = pwrite(target_fd, cpmsg->data, cpmsg->size,
 				cpmsg->offset);
 
-	if (bytes_written != cpmsg->size)
-		return HV_E_FAIL;
+	filesize += cpmsg->size;
+	if (bytes_written != cpmsg->size) {
+		switch (errno) {
+		case ENOSPC:
+			ret = HV_ERROR_DISK_FULL;
+			break;
+		default:
+			ret = HV_E_FAIL;
+			break;
+		}
+		syslog(LOG_ERR, "pwrite failed to write %llu bytes: %ld (%s)",
+		       filesize, (long)bytes_written, strerror(errno));
+	}
 
-	return 0;
+	return ret;
 }
 
 static int hv_copy_finished(void)
@@ -165,7 +179,7 @@ int main(int argc, char *argv[])
 	}
 
 	openlog("HV_FCOPY", 0, LOG_USER);
-	syslog(LOG_INFO, "HV_FCOPY starting; pid is:%d", getpid());
+	syslog(LOG_INFO, "starting; pid is:%d", getpid());
 
 	fcopy_fd = open("/dev/vmbus/hv_fcopy", O_RDWR);
 
@@ -201,7 +215,7 @@ int main(int argc, char *argv[])
 			}
 			kernel_modver = *(__u32 *)buffer;
 			in_handshake = 0;
-			syslog(LOG_INFO, "HV_FCOPY: kernel module version: %d",
+			syslog(LOG_INFO, "kernel module version: %d",
 			       kernel_modver);
 			continue;
 		}
--- /dev/null
+++ zfcpdump-kernel-4.4/tools/hv/hv_kvp_daemon.8
@@ -0,0 +1,26 @@
+.\"  This page Copyright (C) 2012 Andy Whitcroft <apw@canonical.com>
+.\"  Distributed under the GPL v2 or later.
+.TH HV_KVP_DAEMON 8
+.SH NAME
+hv_kvp_daemon \- Hyper-V Key Value Pair daemon
+.SH SYNOPSIS
+.ft B
+.B hv_kvp_daemon
+.br
+.SH DESCRIPTION
+\fBhv_kvp_daemon\fP
+is the userspace component of the Hyper-V key value pair functionality,
+communicating via a netlink socket with the kernel HV-KVP driver.
+This pairing allows the Hyper-V host to pass configuration information
+(such as IP addresses) to the guest and allows the host to obtain guest
+version information.
+
+.SH FILES
+.ta
+.nf
+/var/opt/hyperv/.kvp_pool_*
+.fi
+
+.SH AUTHORS
+.nf
+Written by K. Y. Srinivasan <ksrinivasan@novell.com>
--- zfcpdump-kernel-4.4.orig/tools/hv/hv_vss_daemon.c
+++ zfcpdump-kernel-4.4/tools/hv/hv_vss_daemon.c
@@ -254,7 +254,7 @@ int main(int argc, char *argv[])
 			syslog(LOG_ERR, "Illegal op:%d\n", op);
 		}
 		vss_msg->error = error;
-		len = write(vss_fd, &error, sizeof(struct hv_vss_msg));
+		len = write(vss_fd, vss_msg, sizeof(struct hv_vss_msg));
 		if (len != sizeof(struct hv_vss_msg)) {
 			syslog(LOG_ERR, "write failed; error: %d %s", errno,
 			       strerror(errno));
--- zfcpdump-kernel-4.4.orig/tools/hv/lsvmbus
+++ zfcpdump-kernel-4.4/tools/hv/lsvmbus
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 
 import os
 from optparse import OptionParser
@@ -16,7 +16,7 @@ if options.verbose is not None:
 
 vmbus_sys_path = '/sys/bus/vmbus/devices'
 if not os.path.isdir(vmbus_sys_path):
-	print "%s doesn't exist: exiting..." % vmbus_sys_path
+	print("%s doesn't exist: exiting..." % vmbus_sys_path)
 	exit(-1)
 
 vmbus_dev_dict = {
@@ -35,6 +35,7 @@ vmbus_dev_dict = {
 	'{ba6163d9-04a1-4d29-b605-72e2ffb1dc7f}' : 'Synthetic SCSI Controller',
 	'{2f9bcc4a-0069-4af3-b76b-6fd0be528cda}' : 'Synthetic fiber channel adapter',
 	'{8c2eaf3d-32a7-4b09-ab99-bd1f1c86b501}' : 'Synthetic RDMA adapter',
+	'{44c4f61d-4444-4400-9d52-802e27ede19f}' : 'PCI Express pass-through',
 	'{276aacf4-ac15-426c-98dd-7521ad3f01fe}' : '[Reserved system device]',
 	'{f8e65716-3cb3-4a06-9a60-1889c5cccab5}' : '[Reserved system device]',
 	'{3375baf4-9e15-4b30-b765-67acb10d607b}' : '[Reserved system device]',
@@ -91,11 +92,11 @@ format2 = '%2s: Class_ID = %s - %s\n\tDe
 
 for d in vmbus_dev_list:
 	if verbose == 0:
-		print ('VMBUS ID ' + format0) % (d.vmbus_id, d.dev_desc)
+		print(('VMBUS ID ' + format0) % (d.vmbus_id, d.dev_desc))
 	elif verbose == 1:
-		print ('VMBUS ID ' + format1) %	\
-			(d.vmbus_id, d.class_id, d.dev_desc, d.chn_vp_mapping)
+		print(('VMBUS ID ' + format1) %	\
+			(d.vmbus_id, d.class_id, d.dev_desc, d.chn_vp_mapping))
 	else:
-		print ('VMBUS ID ' + format2) % \
+		print(('VMBUS ID ' + format2) % \
 			(d.vmbus_id, d.class_id, d.dev_desc, \
-			d.device_id, d.sysfs_path, d.chn_vp_mapping)
+			d.device_id, d.sysfs_path, d.chn_vp_mapping))
--- /dev/null
+++ zfcpdump-kernel-4.4/tools/hv/lsvmbus.8
@@ -0,0 +1,23 @@
+.\"  This page Copyright (C) 2016 Andy Whitcroft <apw@canonical.com>
+.\"  Distributed under the GPL v2 or later.
+.TH LSVMBUS 8
+.SH NAME
+lsvmbus \- List Hyper-V VMBus devices
+.SH SYNOPSIS
+.ft B
+.B lsvmbus [-vv]
+.br
+.SH DESCRIPTION
+\fBlsvmbus\fP
+displays devices attached to the Hyper-V VMBus.
+.SH OPTIONS
+.\"
+.TP
+.B -v
+With -v more information is printed including the VMBus Rel_ID, class ID,
+Rel_ID, and which channel is bound to which virtual processor.  Use -vv
+for additional detail including the Device_ID and the sysfs path.
+.\"
+.SH AUTHORS
+.nf
+Written by Dexuan Cui <decui@microsoft.com>
--- zfcpdump-kernel-4.4.orig/tools/lib/bpf/Makefile
+++ zfcpdump-kernel-4.4/tools/lib/bpf/Makefile
@@ -68,7 +68,7 @@ FEATURE_USER = .libbpf
 FEATURE_TESTS = libelf libelf-getphdrnum libelf-mmap bpf
 FEATURE_DISPLAY = libelf bpf
 
-INCLUDES = -I. -I$(srctree)/tools/include -I$(srctree)/arch/$(ARCH)/include/uapi -I$(srctree)/include/uapi
+INCLUDES = -I. -I$(srctree)/tools/include -I$(srctree)/arch/$(ARCH)/include/uapi -I$(srctree)/arch/$(ARCH)/include/generated/uapi -I$(srctree)/include/uapi -I$(srctree)/include/generated/uapi
 FEATURE_CHECK_CFLAGS-bpf = $(INCLUDES)
 
 include $(srctree)/tools/build/Makefile.feature
--- zfcpdump-kernel-4.4.orig/tools/lib/traceevent/event-parse.c
+++ zfcpdump-kernel-4.4/tools/lib/traceevent/event-parse.c
@@ -4968,13 +4968,12 @@ static void pretty_print(struct trace_se
 				    sizeof(long) != 8) {
 					char *p;
 
-					ls = 2;
 					/* make %l into %ll */
-					p = strchr(format, 'l');
-					if (p)
+					if (ls == 1 && (p = strchr(format, 'l')))
 						memmove(p+1, p, strlen(p)+1);
 					else if (strcmp(format, "%p") == 0)
 						strcpy(format, "0x%llx");
+					ls = 2;
 				}
 				switch (ls) {
 				case -2:
--- zfcpdump-kernel-4.4.orig/tools/lib/traceevent/parse-filter.c
+++ zfcpdump-kernel-4.4/tools/lib/traceevent/parse-filter.c
@@ -1164,11 +1164,11 @@ process_filter(struct event_format *even
 		current_op = current_exp;
 
 	ret = collapse_tree(current_op, parg, error_str);
+	/* collapse_tree() may free current_op, and updates parg accordingly */
+	current_op = NULL;
 	if (ret < 0)
 		goto fail;
 
-	*parg = current_op;
-
 	free(token);
 	return 0;
 
--- zfcpdump-kernel-4.4.orig/tools/perf/Documentation/perf-stat.txt
+++ zfcpdump-kernel-4.4/tools/perf/Documentation/perf-stat.txt
@@ -62,6 +62,14 @@ OPTIONS
 --scale::
 	scale/normalize counter values
 
+-d::
+--detailed::
+	print more detailed statistics, can be specified up to 3 times
+
+	   -d:          detailed events, L1 and LLC data cache
+        -d -d:     more detailed events, dTLB and iTLB events
+     -d -d -d:     very detailed events, adding prefetch events
+
 -r::
 --repeat=<n>::
 	repeat command and print average + stddev (max: 100). 0 means forever.
--- zfcpdump-kernel-4.4.orig/tools/perf/arch/powerpc/Makefile
+++ zfcpdump-kernel-4.4/tools/perf/arch/powerpc/Makefile
@@ -1,3 +1,5 @@
 ifndef NO_DWARF
 PERF_HAVE_DWARF_REGS := 1
 endif
+
+HAVE_KVM_STAT_SUPPORT := 1
--- zfcpdump-kernel-4.4.orig/tools/perf/arch/powerpc/util/Build
+++ zfcpdump-kernel-4.4/tools/perf/arch/powerpc/util/Build
@@ -1,5 +1,6 @@
 libperf-y += header.o
 libperf-y += sym-handling.o
+libperf-y += kvm-stat.o
 
 libperf-$(CONFIG_DWARF) += dwarf-regs.o
 libperf-$(CONFIG_DWARF) += skip-callchain-idx.o
--- /dev/null
+++ zfcpdump-kernel-4.4/tools/perf/arch/powerpc/util/book3s_hcalls.h
@@ -0,0 +1,123 @@
+#ifndef ARCH_PERF_BOOK3S_HV_HCALLS_H
+#define ARCH_PERF_BOOK3S_HV_HCALLS_H
+
+/*
+ * PowerPC HCALL codes : hcall code to name mapping
+ */
+#define kvm_trace_symbol_hcall \
+	{0x4, "H_REMOVE"},					\
+	{0x8, "H_ENTER"},					\
+	{0xc, "H_READ"},					\
+	{0x10, "H_CLEAR_MOD"},					\
+	{0x14, "H_CLEAR_REF"},					\
+	{0x18, "H_PROTECT"},					\
+	{0x1c, "H_GET_TCE"},					\
+	{0x20, "H_PUT_TCE"},					\
+	{0x24, "H_SET_SPRG0"},					\
+	{0x28, "H_SET_DABR"},					\
+	{0x2c, "H_PAGE_INIT"},					\
+	{0x30, "H_SET_ASR"},					\
+	{0x34, "H_ASR_ON"},					\
+	{0x38, "H_ASR_OFF"},					\
+	{0x3c, "H_LOGICAL_CI_LOAD"},				\
+	{0x40, "H_LOGICAL_CI_STORE"},				\
+	{0x44, "H_LOGICAL_CACHE_LOAD"},				\
+	{0x48, "H_LOGICAL_CACHE_STORE"},			\
+	{0x4c, "H_LOGICAL_ICBI"},				\
+	{0x50, "H_LOGICAL_DCBF"},				\
+	{0x54, "H_GET_TERM_CHAR"},				\
+	{0x58, "H_PUT_TERM_CHAR"},				\
+	{0x5c, "H_REAL_TO_LOGICAL"},				\
+	{0x60, "H_HYPERVISOR_DATA"},				\
+	{0x64, "H_EOI"},					\
+	{0x68, "H_CPPR"},					\
+	{0x6c, "H_IPI"},					\
+	{0x70, "H_IPOLL"},					\
+	{0x74, "H_XIRR"},					\
+	{0x78, "H_MIGRATE_DMA"},				\
+	{0x7c, "H_PERFMON"},					\
+	{0xdc, "H_REGISTER_VPA"},				\
+	{0xe0, "H_CEDE"},					\
+	{0xe4, "H_CONFER"},					\
+	{0xe8, "H_PROD"},					\
+	{0xec, "H_GET_PPP"},					\
+	{0xf0, "H_SET_PPP"},					\
+	{0xf4, "H_PURR"},					\
+	{0xf8, "H_PIC"},					\
+	{0xfc, "H_REG_CRQ"},					\
+	{0x100, "H_FREE_CRQ"},					\
+	{0x104, "H_VIO_SIGNAL"},				\
+	{0x108, "H_SEND_CRQ"},					\
+	{0x110, "H_COPY_RDMA"},					\
+	{0x114, "H_REGISTER_LOGICAL_LAN"},			\
+	{0x118, "H_FREE_LOGICAL_LAN"},				\
+	{0x11c, "H_ADD_LOGICAL_LAN_BUFFER"},			\
+	{0x120, "H_SEND_LOGICAL_LAN"},				\
+	{0x124, "H_BULK_REMOVE"},				\
+	{0x130, "H_MULTICAST_CTRL"},				\
+	{0x134, "H_SET_XDABR"},					\
+	{0x138, "H_STUFF_TCE"},					\
+	{0x13c, "H_PUT_TCE_INDIRECT"},				\
+	{0x14c, "H_CHANGE_LOGICAL_LAN_MAC"},			\
+	{0x150, "H_VTERM_PARTNER_INFO"},			\
+	{0x154, "H_REGISTER_VTERM"},				\
+	{0x158, "H_FREE_VTERM"},				\
+	{0x15c, "H_RESET_EVENTS"},				\
+	{0x160, "H_ALLOC_RESOURCE"},				\
+	{0x164, "H_FREE_RESOURCE"},				\
+	{0x168, "H_MODIFY_QP"},					\
+	{0x16c, "H_QUERY_QP"},					\
+	{0x170, "H_REREGISTER_PMR"},				\
+	{0x174, "H_REGISTER_SMR"},				\
+	{0x178, "H_QUERY_MR"},					\
+	{0x17c, "H_QUERY_MW"},					\
+	{0x180, "H_QUERY_HCA"},					\
+	{0x184, "H_QUERY_PORT"},				\
+	{0x188, "H_MODIFY_PORT"},				\
+	{0x18c, "H_DEFINE_AQP1"},				\
+	{0x190, "H_GET_TRACE_BUFFER"},				\
+	{0x194, "H_DEFINE_AQP0"},				\
+	{0x198, "H_RESIZE_MR"},					\
+	{0x19c, "H_ATTACH_MCQP"},				\
+	{0x1a0, "H_DETACH_MCQP"},				\
+	{0x1a4, "H_CREATE_RPT"},				\
+	{0x1a8, "H_REMOVE_RPT"},				\
+	{0x1ac, "H_REGISTER_RPAGES"},				\
+	{0x1b0, "H_DISABLE_AND_GETC"},				\
+	{0x1b4, "H_ERROR_DATA"},				\
+	{0x1b8, "H_GET_HCA_INFO"},				\
+	{0x1bc, "H_GET_PERF_COUNT"},				\
+	{0x1c0, "H_MANAGE_TRACE"},				\
+	{0x1d4, "H_FREE_LOGICAL_LAN_BUFFER"},			\
+	{0x1d8, "H_POLL_PENDING"},				\
+	{0x1e4, "H_QUERY_INT_STATE"},				\
+	{0x244, "H_ILLAN_ATTRIBUTES"},				\
+	{0x250, "H_MODIFY_HEA_QP"},				\
+	{0x254, "H_QUERY_HEA_QP"},				\
+	{0x258, "H_QUERY_HEA"},					\
+	{0x25c, "H_QUERY_HEA_PORT"},				\
+	{0x260, "H_MODIFY_HEA_PORT"},				\
+	{0x264, "H_REG_BCMC"},					\
+	{0x268, "H_DEREG_BCMC"},				\
+	{0x26c, "H_REGISTER_HEA_RPAGES"},			\
+	{0x270, "H_DISABLE_AND_GET_HEA"},			\
+	{0x274, "H_GET_HEA_INFO"},				\
+	{0x278, "H_ALLOC_HEA_RESOURCE"},			\
+	{0x284, "H_ADD_CONN"},					\
+	{0x288, "H_DEL_CONN"},					\
+	{0x298, "H_JOIN"},					\
+	{0x2a4, "H_VASI_STATE"},				\
+	{0x2b0, "H_ENABLE_CRQ"},				\
+	{0x2b8, "H_GET_EM_PARMS"},				\
+	{0x2d0, "H_SET_MPP"},					\
+	{0x2d4, "H_GET_MPP"},					\
+	{0x2ec, "H_HOME_NODE_ASSOCIATIVITY"},			\
+	{0x2f4, "H_BEST_ENERGY"},				\
+	{0x2fc, "H_XIRR_X"},					\
+	{0x300, "H_RANDOM"},					\
+	{0x304, "H_COP"},					\
+	{0x314, "H_GET_MPP_X"},					\
+	{0x31c, "H_SET_MODE"},					\
+	{0xf000, "H_RTAS"}					\
+
+#endif
--- /dev/null
+++ zfcpdump-kernel-4.4/tools/perf/arch/powerpc/util/book3s_hv_exits.h
@@ -0,0 +1,33 @@
+#ifndef ARCH_PERF_BOOK3S_HV_EXITS_H
+#define ARCH_PERF_BOOK3S_HV_EXITS_H
+
+/*
+ * PowerPC Interrupt vectors : exit code to name mapping
+ */
+
+#define kvm_trace_symbol_exit \
+	{0x0,	"RETURN_TO_HOST"}, \
+	{0x100, "SYSTEM_RESET"}, \
+	{0x200, "MACHINE_CHECK"}, \
+	{0x300, "DATA_STORAGE"}, \
+	{0x380, "DATA_SEGMENT"}, \
+	{0x400, "INST_STORAGE"}, \
+	{0x480, "INST_SEGMENT"}, \
+	{0x500, "EXTERNAL"}, \
+	{0x501, "EXTERNAL_LEVEL"}, \
+	{0x502, "EXTERNAL_HV"}, \
+	{0x600, "ALIGNMENT"}, \
+	{0x700, "PROGRAM"}, \
+	{0x800, "FP_UNAVAIL"}, \
+	{0x900, "DECREMENTER"}, \
+	{0x980, "HV_DECREMENTER"}, \
+	{0xc00, "SYSCALL"}, \
+	{0xd00, "TRACE"}, \
+	{0xe00, "H_DATA_STORAGE"}, \
+	{0xe20, "H_INST_STORAGE"}, \
+	{0xe40, "H_EMUL_ASSIST"}, \
+	{0xf00, "PERFMON"}, \
+	{0xf20, "ALTIVEC"}, \
+	{0xf40, "VSX"}
+
+#endif
--- /dev/null
+++ zfcpdump-kernel-4.4/tools/perf/arch/powerpc/util/kvm-stat.c
@@ -0,0 +1,170 @@
+#include "util/kvm-stat.h"
+#include "util/parse-events.h"
+#include "util/debug.h"
+
+#include "book3s_hv_exits.h"
+#include "book3s_hcalls.h"
+
+#define NR_TPS 4
+
+const char *vcpu_id_str = "vcpu_id";
+const int decode_str_len = 40;
+const char *kvm_entry_trace = "kvm_hv:kvm_guest_enter";
+const char *kvm_exit_trace = "kvm_hv:kvm_guest_exit";
+
+define_exit_reasons_table(hv_exit_reasons, kvm_trace_symbol_exit);
+define_exit_reasons_table(hcall_reasons, kvm_trace_symbol_hcall);
+
+/* Tracepoints specific to ppc_book3s_hv */
+const char *ppc_book3s_hv_kvm_tp[] = {
+	"kvm_hv:kvm_guest_enter",
+	"kvm_hv:kvm_guest_exit",
+	"kvm_hv:kvm_hcall_enter",
+	"kvm_hv:kvm_hcall_exit",
+	NULL,
+};
+
+/* 1 extra placeholder for NULL */
+const char *kvm_events_tp[NR_TPS + 1];
+const char *kvm_exit_reason;
+
+static void hcall_event_get_key(struct perf_evsel *evsel,
+				struct perf_sample *sample,
+				struct event_key *key)
+{
+	key->info = 0;
+	key->key = perf_evsel__intval(evsel, sample, "req");
+}
+
+static const char *get_hcall_exit_reason(u64 exit_code)
+{
+	struct exit_reasons_table *tbl = hcall_reasons;
+
+	while (tbl->reason != NULL) {
+		if (tbl->exit_code == exit_code)
+			return tbl->reason;
+		tbl++;
+	}
+
+	pr_debug("Unknown hcall code: %lld\n",
+	       (unsigned long long)exit_code);
+	return "UNKNOWN";
+}
+
+static bool hcall_event_end(struct perf_evsel *evsel,
+			    struct perf_sample *sample __maybe_unused,
+			    struct event_key *key __maybe_unused)
+{
+	return (!strcmp(evsel->name, kvm_events_tp[3]));
+}
+
+static bool hcall_event_begin(struct perf_evsel *evsel,
+			      struct perf_sample *sample, struct event_key *key)
+{
+	if (!strcmp(evsel->name, kvm_events_tp[2])) {
+		hcall_event_get_key(evsel, sample, key);
+		return true;
+	}
+
+	return false;
+}
+static void hcall_event_decode_key(struct perf_kvm_stat *kvm __maybe_unused,
+				   struct event_key *key,
+				   char *decode)
+{
+	const char *hcall_reason = get_hcall_exit_reason(key->key);
+
+	scnprintf(decode, decode_str_len, "%s", hcall_reason);
+}
+
+static struct kvm_events_ops hcall_events = {
+	.is_begin_event = hcall_event_begin,
+	.is_end_event = hcall_event_end,
+	.decode_key = hcall_event_decode_key,
+	.name = "HCALL-EVENT",
+};
+
+static struct kvm_events_ops exit_events = {
+	.is_begin_event = exit_event_begin,
+	.is_end_event = exit_event_end,
+	.decode_key = exit_event_decode_key,
+	.name = "VM-EXIT"
+};
+
+struct kvm_reg_events_ops kvm_reg_events_ops[] = {
+	{ .name = "vmexit", .ops = &exit_events },
+	{ .name = "hcall", .ops = &hcall_events },
+	{ NULL, NULL },
+};
+
+const char * const kvm_skip_events[] = {
+	NULL,
+};
+
+
+static int is_tracepoint_available(const char *str, struct perf_evlist *evlist)
+{
+	struct parse_events_error err;
+	int ret;
+
+	err.str = NULL;
+	ret = parse_events(evlist, str, &err);
+	if (err.str)
+		pr_err("%s : %s\n", str, err.str);
+	return ret;
+}
+
+static int ppc__setup_book3s_hv(struct perf_kvm_stat *kvm,
+				struct perf_evlist *evlist)
+{
+	const char **events_ptr;
+	int i, nr_tp = 0, err = -1;
+
+	/* Check for book3s_hv tracepoints */
+	for (events_ptr = ppc_book3s_hv_kvm_tp; *events_ptr; events_ptr++) {
+		err = is_tracepoint_available(*events_ptr, evlist);
+		if (err)
+			return -1;
+		nr_tp++;
+	}
+
+	for (i = 0; i < nr_tp; i++)
+		kvm_events_tp[i] = ppc_book3s_hv_kvm_tp[i];
+
+	kvm_events_tp[i] = NULL;
+	kvm_exit_reason = "trap";
+	kvm->exit_reasons = hv_exit_reasons;
+	kvm->exit_reasons_isa = "HV";
+
+	return 0;
+}
+
+/* Wrapper to setup kvm tracepoints */
+static int ppc__setup_kvm_tp(struct perf_kvm_stat *kvm)
+{
+	struct perf_evlist *evlist = perf_evlist__new();
+
+	if (evlist == NULL)
+		return -ENOMEM;
+
+	/* Right now, only supported on book3s_hv */
+	return ppc__setup_book3s_hv(kvm, evlist);
+}
+
+int setup_kvm_events_tp(struct perf_kvm_stat *kvm)
+{
+	return ppc__setup_kvm_tp(kvm);
+}
+
+int cpu_isa_init(struct perf_kvm_stat *kvm, const char *cpuid __maybe_unused)
+{
+	int ret;
+
+	ret = ppc__setup_kvm_tp(kvm);
+	if (ret) {
+		kvm->exit_reasons = NULL;
+		kvm->exit_reasons_isa = NULL;
+	}
+
+	return ret;
+}
--- zfcpdump-kernel-4.4.orig/tools/perf/arch/s390/util/kvm-stat.c
+++ zfcpdump-kernel-4.4/tools/perf/arch/s390/util/kvm-stat.c
@@ -10,7 +10,7 @@
  */
 
 #include "../../util/kvm-stat.h"
-#include <asm/kvm_perf.h>
+#include <asm/sie.h>
 
 define_exit_reasons_table(sie_exit_reasons, sie_intercept_code);
 define_exit_reasons_table(sie_icpt_insn_codes, icpt_insn_codes);
@@ -18,6 +18,12 @@ define_exit_reasons_table(sie_sigp_order
 define_exit_reasons_table(sie_diagnose_codes, diagnose_codes);
 define_exit_reasons_table(sie_icpt_prog_codes, icpt_prog_codes);
 
+const char *vcpu_id_str = "id";
+const int decode_str_len = 40;
+const char *kvm_exit_reason = "icptcode";
+const char *kvm_entry_trace = "kvm:kvm_s390_sie_enter";
+const char *kvm_exit_trace = "kvm:kvm_s390_sie_exit";
+
 static void event_icpt_insn_get_key(struct perf_evsel *evsel,
 				    struct perf_sample *sample,
 				    struct event_key *key)
@@ -73,7 +79,7 @@ static struct kvm_events_ops exit_events
 	.name = "VM-EXIT"
 };
 
-const char * const kvm_events_tp[] = {
+const char *kvm_events_tp[] = {
 	"kvm:kvm_s390_sie_enter",
 	"kvm:kvm_s390_sie_exit",
 	"kvm:kvm_s390_intercept_instruction",
--- zfcpdump-kernel-4.4.orig/tools/perf/arch/x86/tests/insn-x86-dat-32.c
+++ zfcpdump-kernel-4.4/tools/perf/arch/x86/tests/insn-x86-dat-32.c
@@ -6,6 +6,1016 @@
 
 {{0x0f, 0x31, }, 2, 0, "", "",
 "0f 31                \trdtsc  ",},
+{{0xc4, 0xe2, 0x7d, 0x13, 0xeb, }, 5, 0, "", "",
+"c4 e2 7d 13 eb       \tvcvtph2ps %xmm3,%ymm5",},
+{{0x62, 0x81, 0x78, 0x56, 0x34, 0x12, }, 6, 0, "", "",
+"62 81 78 56 34 12    \tbound  %eax,0x12345678(%ecx)",},
+{{0x62, 0x88, 0x78, 0x56, 0x34, 0x12, }, 6, 0, "", "",
+"62 88 78 56 34 12    \tbound  %ecx,0x12345678(%eax)",},
+{{0x62, 0x90, 0x78, 0x56, 0x34, 0x12, }, 6, 0, "", "",
+"62 90 78 56 34 12    \tbound  %edx,0x12345678(%eax)",},
+{{0x62, 0x98, 0x78, 0x56, 0x34, 0x12, }, 6, 0, "", "",
+"62 98 78 56 34 12    \tbound  %ebx,0x12345678(%eax)",},
+{{0x62, 0xa0, 0x78, 0x56, 0x34, 0x12, }, 6, 0, "", "",
+"62 a0 78 56 34 12    \tbound  %esp,0x12345678(%eax)",},
+{{0x62, 0xa8, 0x78, 0x56, 0x34, 0x12, }, 6, 0, "", "",
+"62 a8 78 56 34 12    \tbound  %ebp,0x12345678(%eax)",},
+{{0x62, 0xb0, 0x78, 0x56, 0x34, 0x12, }, 6, 0, "", "",
+"62 b0 78 56 34 12    \tbound  %esi,0x12345678(%eax)",},
+{{0x62, 0xb8, 0x78, 0x56, 0x34, 0x12, }, 6, 0, "", "",
+"62 b8 78 56 34 12    \tbound  %edi,0x12345678(%eax)",},
+{{0x62, 0x08, }, 2, 0, "", "",
+"62 08                \tbound  %ecx,(%eax)",},
+{{0x62, 0x05, 0x78, 0x56, 0x34, 0x12, }, 6, 0, "", "",
+"62 05 78 56 34 12    \tbound  %eax,0x12345678",},
+{{0x62, 0x14, 0x01, }, 3, 0, "", "",
+"62 14 01             \tbound  %edx,(%ecx,%eax,1)",},
+{{0x62, 0x14, 0x05, 0x78, 0x56, 0x34, 0x12, }, 7, 0, "", "",
+"62 14 05 78 56 34 12 \tbound  %edx,0x12345678(,%eax,1)",},
+{{0x62, 0x14, 0x08, }, 3, 0, "", "",
+"62 14 08             \tbound  %edx,(%eax,%ecx,1)",},
+{{0x62, 0x14, 0xc8, }, 3, 0, "", "",
+"62 14 c8             \tbound  %edx,(%eax,%ecx,8)",},
+{{0x62, 0x50, 0x12, }, 3, 0, "", "",
+"62 50 12             \tbound  %edx,0x12(%eax)",},
+{{0x62, 0x55, 0x12, }, 3, 0, "", "",
+"62 55 12             \tbound  %edx,0x12(%ebp)",},
+{{0x62, 0x54, 0x01, 0x12, }, 4, 0, "", "",
+"62 54 01 12          \tbound  %edx,0x12(%ecx,%eax,1)",},
+{{0x62, 0x54, 0x05, 0x12, }, 4, 0, "", "",
+"62 54 05 12          \tbound  %edx,0x12(%ebp,%eax,1)",},
+{{0x62, 0x54, 0x08, 0x12, }, 4, 0, "", "",
+"62 54 08 12          \tbound  %edx,0x12(%eax,%ecx,1)",},
+{{0x62, 0x54, 0xc8, 0x12, }, 4, 0, "", "",
+"62 54 c8 12          \tbound  %edx,0x12(%eax,%ecx,8)",},
+{{0x62, 0x90, 0x78, 0x56, 0x34, 0x12, }, 6, 0, "", "",
+"62 90 78 56 34 12    \tbound  %edx,0x12345678(%eax)",},
+{{0x62, 0x95, 0x78, 0x56, 0x34, 0x12, }, 6, 0, "", "",
+"62 95 78 56 34 12    \tbound  %edx,0x12345678(%ebp)",},
+{{0x62, 0x94, 0x01, 0x78, 0x56, 0x34, 0x12, }, 7, 0, "", "",
+"62 94 01 78 56 34 12 \tbound  %edx,0x12345678(%ecx,%eax,1)",},
+{{0x62, 0x94, 0x05, 0x78, 0x56, 0x34, 0x12, }, 7, 0, "", "",
+"62 94 05 78 56 34 12 \tbound  %edx,0x12345678(%ebp,%eax,1)",},
+{{0x62, 0x94, 0x08, 0x78, 0x56, 0x34, 0x12, }, 7, 0, "", "",
+"62 94 08 78 56 34 12 \tbound  %edx,0x12345678(%eax,%ecx,1)",},
+{{0x62, 0x94, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 7, 0, "", "",
+"62 94 c8 78 56 34 12 \tbound  %edx,0x12345678(%eax,%ecx,8)",},
+{{0x66, 0x62, 0x81, 0x78, 0x56, 0x34, 0x12, }, 7, 0, "", "",
+"66 62 81 78 56 34 12 \tbound  %ax,0x12345678(%ecx)",},
+{{0x66, 0x62, 0x88, 0x78, 0x56, 0x34, 0x12, }, 7, 0, "", "",
+"66 62 88 78 56 34 12 \tbound  %cx,0x12345678(%eax)",},
+{{0x66, 0x62, 0x90, 0x78, 0x56, 0x34, 0x12, }, 7, 0, "", "",
+"66 62 90 78 56 34 12 \tbound  %dx,0x12345678(%eax)",},
+{{0x66, 0x62, 0x98, 0x78, 0x56, 0x34, 0x12, }, 7, 0, "", "",
+"66 62 98 78 56 34 12 \tbound  %bx,0x12345678(%eax)",},
+{{0x66, 0x62, 0xa0, 0x78, 0x56, 0x34, 0x12, }, 7, 0, "", "",
+"66 62 a0 78 56 34 12 \tbound  %sp,0x12345678(%eax)",},
+{{0x66, 0x62, 0xa8, 0x78, 0x56, 0x34, 0x12, }, 7, 0, "", "",
+"66 62 a8 78 56 34 12 \tbound  %bp,0x12345678(%eax)",},
+{{0x66, 0x62, 0xb0, 0x78, 0x56, 0x34, 0x12, }, 7, 0, "", "",
+"66 62 b0 78 56 34 12 \tbound  %si,0x12345678(%eax)",},
+{{0x66, 0x62, 0xb8, 0x78, 0x56, 0x34, 0x12, }, 7, 0, "", "",
+"66 62 b8 78 56 34 12 \tbound  %di,0x12345678(%eax)",},
+{{0x66, 0x62, 0x08, }, 3, 0, "", "",
+"66 62 08             \tbound  %cx,(%eax)",},
+{{0x66, 0x62, 0x05, 0x78, 0x56, 0x34, 0x12, }, 7, 0, "", "",
+"66 62 05 78 56 34 12 \tbound  %ax,0x12345678",},
+{{0x66, 0x62, 0x14, 0x01, }, 4, 0, "", "",
+"66 62 14 01          \tbound  %dx,(%ecx,%eax,1)",},
+{{0x66, 0x62, 0x14, 0x05, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
+"66 62 14 05 78 56 34 12 \tbound  %dx,0x12345678(,%eax,1)",},
+{{0x66, 0x62, 0x14, 0x08, }, 4, 0, "", "",
+"66 62 14 08          \tbound  %dx,(%eax,%ecx,1)",},
+{{0x66, 0x62, 0x14, 0xc8, }, 4, 0, "", "",
+"66 62 14 c8          \tbound  %dx,(%eax,%ecx,8)",},
+{{0x66, 0x62, 0x50, 0x12, }, 4, 0, "", "",
+"66 62 50 12          \tbound  %dx,0x12(%eax)",},
+{{0x66, 0x62, 0x55, 0x12, }, 4, 0, "", "",
+"66 62 55 12          \tbound  %dx,0x12(%ebp)",},
+{{0x66, 0x62, 0x54, 0x01, 0x12, }, 5, 0, "", "",
+"66 62 54 01 12       \tbound  %dx,0x12(%ecx,%eax,1)",},
+{{0x66, 0x62, 0x54, 0x05, 0x12, }, 5, 0, "", "",
+"66 62 54 05 12       \tbound  %dx,0x12(%ebp,%eax,1)",},
+{{0x66, 0x62, 0x54, 0x08, 0x12, }, 5, 0, "", "",
+"66 62 54 08 12       \tbound  %dx,0x12(%eax,%ecx,1)",},
+{{0x66, 0x62, 0x54, 0xc8, 0x12, }, 5, 0, "", "",
+"66 62 54 c8 12       \tbound  %dx,0x12(%eax,%ecx,8)",},
+{{0x66, 0x62, 0x90, 0x78, 0x56, 0x34, 0x12, }, 7, 0, "", "",
+"66 62 90 78 56 34 12 \tbound  %dx,0x12345678(%eax)",},
+{{0x66, 0x62, 0x95, 0x78, 0x56, 0x34, 0x12, }, 7, 0, "", "",
+"66 62 95 78 56 34 12 \tbound  %dx,0x12345678(%ebp)",},
+{{0x66, 0x62, 0x94, 0x01, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
+"66 62 94 01 78 56 34 12 \tbound  %dx,0x12345678(%ecx,%eax,1)",},
+{{0x66, 0x62, 0x94, 0x05, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
+"66 62 94 05 78 56 34 12 \tbound  %dx,0x12345678(%ebp,%eax,1)",},
+{{0x66, 0x62, 0x94, 0x08, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
+"66 62 94 08 78 56 34 12 \tbound  %dx,0x12345678(%eax,%ecx,1)",},
+{{0x66, 0x62, 0x94, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
+"66 62 94 c8 78 56 34 12 \tbound  %dx,0x12345678(%eax,%ecx,8)",},
+{{0x0f, 0x41, 0xd8, }, 3, 0, "", "",
+"0f 41 d8             \tcmovno %eax,%ebx",},
+{{0x0f, 0x41, 0x88, 0x78, 0x56, 0x34, 0x12, }, 7, 0, "", "",
+"0f 41 88 78 56 34 12 \tcmovno 0x12345678(%eax),%ecx",},
+{{0x66, 0x0f, 0x41, 0x88, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
+"66 0f 41 88 78 56 34 12 \tcmovno 0x12345678(%eax),%cx",},
+{{0x0f, 0x44, 0xd8, }, 3, 0, "", "",
+"0f 44 d8             \tcmove  %eax,%ebx",},
+{{0x0f, 0x44, 0x88, 0x78, 0x56, 0x34, 0x12, }, 7, 0, "", "",
+"0f 44 88 78 56 34 12 \tcmove  0x12345678(%eax),%ecx",},
+{{0x66, 0x0f, 0x44, 0x88, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
+"66 0f 44 88 78 56 34 12 \tcmove  0x12345678(%eax),%cx",},
+{{0x0f, 0x90, 0x80, 0x78, 0x56, 0x34, 0x12, }, 7, 0, "", "",
+"0f 90 80 78 56 34 12 \tseto   0x12345678(%eax)",},
+{{0x0f, 0x91, 0x80, 0x78, 0x56, 0x34, 0x12, }, 7, 0, "", "",
+"0f 91 80 78 56 34 12 \tsetno  0x12345678(%eax)",},
+{{0x0f, 0x92, 0x80, 0x78, 0x56, 0x34, 0x12, }, 7, 0, "", "",
+"0f 92 80 78 56 34 12 \tsetb   0x12345678(%eax)",},
+{{0x0f, 0x92, 0x80, 0x78, 0x56, 0x34, 0x12, }, 7, 0, "", "",
+"0f 92 80 78 56 34 12 \tsetb   0x12345678(%eax)",},
+{{0x0f, 0x92, 0x80, 0x78, 0x56, 0x34, 0x12, }, 7, 0, "", "",
+"0f 92 80 78 56 34 12 \tsetb   0x12345678(%eax)",},
+{{0x0f, 0x93, 0x80, 0x78, 0x56, 0x34, 0x12, }, 7, 0, "", "",
+"0f 93 80 78 56 34 12 \tsetae  0x12345678(%eax)",},
+{{0x0f, 0x93, 0x80, 0x78, 0x56, 0x34, 0x12, }, 7, 0, "", "",
+"0f 93 80 78 56 34 12 \tsetae  0x12345678(%eax)",},
+{{0x0f, 0x93, 0x80, 0x78, 0x56, 0x34, 0x12, }, 7, 0, "", "",
+"0f 93 80 78 56 34 12 \tsetae  0x12345678(%eax)",},
+{{0x0f, 0x98, 0x80, 0x78, 0x56, 0x34, 0x12, }, 7, 0, "", "",
+"0f 98 80 78 56 34 12 \tsets   0x12345678(%eax)",},
+{{0x0f, 0x99, 0x80, 0x78, 0x56, 0x34, 0x12, }, 7, 0, "", "",
+"0f 99 80 78 56 34 12 \tsetns  0x12345678(%eax)",},
+{{0xc5, 0xcc, 0x41, 0xef, }, 4, 0, "", "",
+"c5 cc 41 ef          \tkandw  %k7,%k6,%k5",},
+{{0xc4, 0xe1, 0xcc, 0x41, 0xef, }, 5, 0, "", "",
+"c4 e1 cc 41 ef       \tkandq  %k7,%k6,%k5",},
+{{0xc5, 0xcd, 0x41, 0xef, }, 4, 0, "", "",
+"c5 cd 41 ef          \tkandb  %k7,%k6,%k5",},
+{{0xc4, 0xe1, 0xcd, 0x41, 0xef, }, 5, 0, "", "",
+"c4 e1 cd 41 ef       \tkandd  %k7,%k6,%k5",},
+{{0xc5, 0xcc, 0x42, 0xef, }, 4, 0, "", "",
+"c5 cc 42 ef          \tkandnw %k7,%k6,%k5",},
+{{0xc4, 0xe1, 0xcc, 0x42, 0xef, }, 5, 0, "", "",
+"c4 e1 cc 42 ef       \tkandnq %k7,%k6,%k5",},
+{{0xc5, 0xcd, 0x42, 0xef, }, 4, 0, "", "",
+"c5 cd 42 ef          \tkandnb %k7,%k6,%k5",},
+{{0xc4, 0xe1, 0xcd, 0x42, 0xef, }, 5, 0, "", "",
+"c4 e1 cd 42 ef       \tkandnd %k7,%k6,%k5",},
+{{0xc5, 0xf8, 0x44, 0xf7, }, 4, 0, "", "",
+"c5 f8 44 f7          \tknotw  %k7,%k6",},
+{{0xc4, 0xe1, 0xf8, 0x44, 0xf7, }, 5, 0, "", "",
+"c4 e1 f8 44 f7       \tknotq  %k7,%k6",},
+{{0xc5, 0xf9, 0x44, 0xf7, }, 4, 0, "", "",
+"c5 f9 44 f7          \tknotb  %k7,%k6",},
+{{0xc4, 0xe1, 0xf9, 0x44, 0xf7, }, 5, 0, "", "",
+"c4 e1 f9 44 f7       \tknotd  %k7,%k6",},
+{{0xc5, 0xcc, 0x45, 0xef, }, 4, 0, "", "",
+"c5 cc 45 ef          \tkorw   %k7,%k6,%k5",},
+{{0xc4, 0xe1, 0xcc, 0x45, 0xef, }, 5, 0, "", "",
+"c4 e1 cc 45 ef       \tkorq   %k7,%k6,%k5",},
+{{0xc5, 0xcd, 0x45, 0xef, }, 4, 0, "", "",
+"c5 cd 45 ef          \tkorb   %k7,%k6,%k5",},
+{{0xc4, 0xe1, 0xcd, 0x45, 0xef, }, 5, 0, "", "",
+"c4 e1 cd 45 ef       \tkord   %k7,%k6,%k5",},
+{{0xc5, 0xcc, 0x46, 0xef, }, 4, 0, "", "",
+"c5 cc 46 ef          \tkxnorw %k7,%k6,%k5",},
+{{0xc4, 0xe1, 0xcc, 0x46, 0xef, }, 5, 0, "", "",
+"c4 e1 cc 46 ef       \tkxnorq %k7,%k6,%k5",},
+{{0xc5, 0xcd, 0x46, 0xef, }, 4, 0, "", "",
+"c5 cd 46 ef          \tkxnorb %k7,%k6,%k5",},
+{{0xc4, 0xe1, 0xcd, 0x46, 0xef, }, 5, 0, "", "",
+"c4 e1 cd 46 ef       \tkxnord %k7,%k6,%k5",},
+{{0xc5, 0xcc, 0x47, 0xef, }, 4, 0, "", "",
+"c5 cc 47 ef          \tkxorw  %k7,%k6,%k5",},
+{{0xc4, 0xe1, 0xcc, 0x47, 0xef, }, 5, 0, "", "",
+"c4 e1 cc 47 ef       \tkxorq  %k7,%k6,%k5",},
+{{0xc5, 0xcd, 0x47, 0xef, }, 4, 0, "", "",
+"c5 cd 47 ef          \tkxorb  %k7,%k6,%k5",},
+{{0xc4, 0xe1, 0xcd, 0x47, 0xef, }, 5, 0, "", "",
+"c4 e1 cd 47 ef       \tkxord  %k7,%k6,%k5",},
+{{0xc5, 0xcc, 0x4a, 0xef, }, 4, 0, "", "",
+"c5 cc 4a ef          \tkaddw  %k7,%k6,%k5",},
+{{0xc4, 0xe1, 0xcc, 0x4a, 0xef, }, 5, 0, "", "",
+"c4 e1 cc 4a ef       \tkaddq  %k7,%k6,%k5",},
+{{0xc5, 0xcd, 0x4a, 0xef, }, 4, 0, "", "",
+"c5 cd 4a ef          \tkaddb  %k7,%k6,%k5",},
+{{0xc4, 0xe1, 0xcd, 0x4a, 0xef, }, 5, 0, "", "",
+"c4 e1 cd 4a ef       \tkaddd  %k7,%k6,%k5",},
+{{0xc5, 0xcd, 0x4b, 0xef, }, 4, 0, "", "",
+"c5 cd 4b ef          \tkunpckbw %k7,%k6,%k5",},
+{{0xc5, 0xcc, 0x4b, 0xef, }, 4, 0, "", "",
+"c5 cc 4b ef          \tkunpckwd %k7,%k6,%k5",},
+{{0xc4, 0xe1, 0xcc, 0x4b, 0xef, }, 5, 0, "", "",
+"c4 e1 cc 4b ef       \tkunpckdq %k7,%k6,%k5",},
+{{0xc5, 0xf8, 0x90, 0xee, }, 4, 0, "", "",
+"c5 f8 90 ee          \tkmovw  %k6,%k5",},
+{{0xc5, 0xf8, 0x90, 0x29, }, 4, 0, "", "",
+"c5 f8 90 29          \tkmovw  (%ecx),%k5",},
+{{0xc5, 0xf8, 0x90, 0xac, 0xc8, 0x23, 0x01, 0x00, 0x00, }, 9, 0, "", "",
+"c5 f8 90 ac c8 23 01 00 00 \tkmovw  0x123(%eax,%ecx,8),%k5",},
+{{0xc5, 0xf8, 0x91, 0x29, }, 4, 0, "", "",
+"c5 f8 91 29          \tkmovw  %k5,(%ecx)",},
+{{0xc5, 0xf8, 0x91, 0xac, 0xc8, 0x23, 0x01, 0x00, 0x00, }, 9, 0, "", "",
+"c5 f8 91 ac c8 23 01 00 00 \tkmovw  %k5,0x123(%eax,%ecx,8)",},
+{{0xc5, 0xf8, 0x92, 0xe8, }, 4, 0, "", "",
+"c5 f8 92 e8          \tkmovw  %eax,%k5",},
+{{0xc5, 0xf8, 0x92, 0xed, }, 4, 0, "", "",
+"c5 f8 92 ed          \tkmovw  %ebp,%k5",},
+{{0xc5, 0xf8, 0x93, 0xc5, }, 4, 0, "", "",
+"c5 f8 93 c5          \tkmovw  %k5,%eax",},
+{{0xc5, 0xf8, 0x93, 0xed, }, 4, 0, "", "",
+"c5 f8 93 ed          \tkmovw  %k5,%ebp",},
+{{0xc4, 0xe1, 0xf8, 0x90, 0xee, }, 5, 0, "", "",
+"c4 e1 f8 90 ee       \tkmovq  %k6,%k5",},
+{{0xc4, 0xe1, 0xf8, 0x90, 0x29, }, 5, 0, "", "",
+"c4 e1 f8 90 29       \tkmovq  (%ecx),%k5",},
+{{0xc4, 0xe1, 0xf8, 0x90, 0xac, 0xc8, 0x23, 0x01, 0x00, 0x00, }, 10, 0, "", "",
+"c4 e1 f8 90 ac c8 23 01 00 00 \tkmovq  0x123(%eax,%ecx,8),%k5",},
+{{0xc4, 0xe1, 0xf8, 0x91, 0x29, }, 5, 0, "", "",
+"c4 e1 f8 91 29       \tkmovq  %k5,(%ecx)",},
+{{0xc4, 0xe1, 0xf8, 0x91, 0xac, 0xc8, 0x23, 0x01, 0x00, 0x00, }, 10, 0, "", "",
+"c4 e1 f8 91 ac c8 23 01 00 00 \tkmovq  %k5,0x123(%eax,%ecx,8)",},
+{{0xc5, 0xf9, 0x90, 0xee, }, 4, 0, "", "",
+"c5 f9 90 ee          \tkmovb  %k6,%k5",},
+{{0xc5, 0xf9, 0x90, 0x29, }, 4, 0, "", "",
+"c5 f9 90 29          \tkmovb  (%ecx),%k5",},
+{{0xc5, 0xf9, 0x90, 0xac, 0xc8, 0x23, 0x01, 0x00, 0x00, }, 9, 0, "", "",
+"c5 f9 90 ac c8 23 01 00 00 \tkmovb  0x123(%eax,%ecx,8),%k5",},
+{{0xc5, 0xf9, 0x91, 0x29, }, 4, 0, "", "",
+"c5 f9 91 29          \tkmovb  %k5,(%ecx)",},
+{{0xc5, 0xf9, 0x91, 0xac, 0xc8, 0x23, 0x01, 0x00, 0x00, }, 9, 0, "", "",
+"c5 f9 91 ac c8 23 01 00 00 \tkmovb  %k5,0x123(%eax,%ecx,8)",},
+{{0xc5, 0xf9, 0x92, 0xe8, }, 4, 0, "", "",
+"c5 f9 92 e8          \tkmovb  %eax,%k5",},
+{{0xc5, 0xf9, 0x92, 0xed, }, 4, 0, "", "",
+"c5 f9 92 ed          \tkmovb  %ebp,%k5",},
+{{0xc5, 0xf9, 0x93, 0xc5, }, 4, 0, "", "",
+"c5 f9 93 c5          \tkmovb  %k5,%eax",},
+{{0xc5, 0xf9, 0x93, 0xed, }, 4, 0, "", "",
+"c5 f9 93 ed          \tkmovb  %k5,%ebp",},
+{{0xc4, 0xe1, 0xf9, 0x90, 0xee, }, 5, 0, "", "",
+"c4 e1 f9 90 ee       \tkmovd  %k6,%k5",},
+{{0xc4, 0xe1, 0xf9, 0x90, 0x29, }, 5, 0, "", "",
+"c4 e1 f9 90 29       \tkmovd  (%ecx),%k5",},
+{{0xc4, 0xe1, 0xf9, 0x90, 0xac, 0xc8, 0x23, 0x01, 0x00, 0x00, }, 10, 0, "", "",
+"c4 e1 f9 90 ac c8 23 01 00 00 \tkmovd  0x123(%eax,%ecx,8),%k5",},
+{{0xc4, 0xe1, 0xf9, 0x91, 0x29, }, 5, 0, "", "",
+"c4 e1 f9 91 29       \tkmovd  %k5,(%ecx)",},
+{{0xc4, 0xe1, 0xf9, 0x91, 0xac, 0xc8, 0x23, 0x01, 0x00, 0x00, }, 10, 0, "", "",
+"c4 e1 f9 91 ac c8 23 01 00 00 \tkmovd  %k5,0x123(%eax,%ecx,8)",},
+{{0xc5, 0xfb, 0x92, 0xe8, }, 4, 0, "", "",
+"c5 fb 92 e8          \tkmovd  %eax,%k5",},
+{{0xc5, 0xfb, 0x92, 0xed, }, 4, 0, "", "",
+"c5 fb 92 ed          \tkmovd  %ebp,%k5",},
+{{0xc5, 0xfb, 0x93, 0xc5, }, 4, 0, "", "",
+"c5 fb 93 c5          \tkmovd  %k5,%eax",},
+{{0xc5, 0xfb, 0x93, 0xed, }, 4, 0, "", "",
+"c5 fb 93 ed          \tkmovd  %k5,%ebp",},
+{{0xc5, 0xf8, 0x98, 0xee, }, 4, 0, "", "",
+"c5 f8 98 ee          \tkortestw %k6,%k5",},
+{{0xc4, 0xe1, 0xf8, 0x98, 0xee, }, 5, 0, "", "",
+"c4 e1 f8 98 ee       \tkortestq %k6,%k5",},
+{{0xc5, 0xf9, 0x98, 0xee, }, 4, 0, "", "",
+"c5 f9 98 ee          \tkortestb %k6,%k5",},
+{{0xc4, 0xe1, 0xf9, 0x98, 0xee, }, 5, 0, "", "",
+"c4 e1 f9 98 ee       \tkortestd %k6,%k5",},
+{{0xc5, 0xf8, 0x99, 0xee, }, 4, 0, "", "",
+"c5 f8 99 ee          \tktestw %k6,%k5",},
+{{0xc4, 0xe1, 0xf8, 0x99, 0xee, }, 5, 0, "", "",
+"c4 e1 f8 99 ee       \tktestq %k6,%k5",},
+{{0xc5, 0xf9, 0x99, 0xee, }, 4, 0, "", "",
+"c5 f9 99 ee          \tktestb %k6,%k5",},
+{{0xc4, 0xe1, 0xf9, 0x99, 0xee, }, 5, 0, "", "",
+"c4 e1 f9 99 ee       \tktestd %k6,%k5",},
+{{0xc4, 0xe3, 0xf9, 0x30, 0xee, 0x12, }, 6, 0, "", "",
+"c4 e3 f9 30 ee 12    \tkshiftrw $0x12,%k6,%k5",},
+{{0xc4, 0xe3, 0xf9, 0x31, 0xee, 0x5b, }, 6, 0, "", "",
+"c4 e3 f9 31 ee 5b    \tkshiftrq $0x5b,%k6,%k5",},
+{{0xc4, 0xe3, 0xf9, 0x32, 0xee, 0x12, }, 6, 0, "", "",
+"c4 e3 f9 32 ee 12    \tkshiftlw $0x12,%k6,%k5",},
+{{0xc4, 0xe3, 0xf9, 0x33, 0xee, 0x5b, }, 6, 0, "", "",
+"c4 e3 f9 33 ee 5b    \tkshiftlq $0x5b,%k6,%k5",},
+{{0xc5, 0xf8, 0x5b, 0xf5, }, 4, 0, "", "",
+"c5 f8 5b f5          \tvcvtdq2ps %xmm5,%xmm6",},
+{{0x62, 0xf1, 0xfc, 0x4f, 0x5b, 0xf5, }, 6, 0, "", "",
+"62 f1 fc 4f 5b f5    \tvcvtqq2ps %zmm5,%ymm6{%k7}",},
+{{0xc5, 0xf9, 0x5b, 0xf5, }, 4, 0, "", "",
+"c5 f9 5b f5          \tvcvtps2dq %xmm5,%xmm6",},
+{{0xc5, 0xfa, 0x5b, 0xf5, }, 4, 0, "", "",
+"c5 fa 5b f5          \tvcvttps2dq %xmm5,%xmm6",},
+{{0x0f, 0x6f, 0xe0, }, 3, 0, "", "",
+"0f 6f e0             \tmovq   %mm0,%mm4",},
+{{0xc5, 0xfd, 0x6f, 0xf4, }, 4, 0, "", "",
+"c5 fd 6f f4          \tvmovdqa %ymm4,%ymm6",},
+{{0x62, 0xf1, 0x7d, 0x48, 0x6f, 0xf5, }, 6, 0, "", "",
+"62 f1 7d 48 6f f5    \tvmovdqa32 %zmm5,%zmm6",},
+{{0x62, 0xf1, 0xfd, 0x48, 0x6f, 0xf5, }, 6, 0, "", "",
+"62 f1 fd 48 6f f5    \tvmovdqa64 %zmm5,%zmm6",},
+{{0xc5, 0xfe, 0x6f, 0xf4, }, 4, 0, "", "",
+"c5 fe 6f f4          \tvmovdqu %ymm4,%ymm6",},
+{{0x62, 0xf1, 0x7e, 0x48, 0x6f, 0xf5, }, 6, 0, "", "",
+"62 f1 7e 48 6f f5    \tvmovdqu32 %zmm5,%zmm6",},
+{{0x62, 0xf1, 0xfe, 0x48, 0x6f, 0xf5, }, 6, 0, "", "",
+"62 f1 fe 48 6f f5    \tvmovdqu64 %zmm5,%zmm6",},
+{{0x62, 0xf1, 0x7f, 0x48, 0x6f, 0xf5, }, 6, 0, "", "",
+"62 f1 7f 48 6f f5    \tvmovdqu8 %zmm5,%zmm6",},
+{{0x62, 0xf1, 0xff, 0x48, 0x6f, 0xf5, }, 6, 0, "", "",
+"62 f1 ff 48 6f f5    \tvmovdqu16 %zmm5,%zmm6",},
+{{0x0f, 0x78, 0xc3, }, 3, 0, "", "",
+"0f 78 c3             \tvmread %eax,%ebx",},
+{{0x62, 0xf1, 0x7c, 0x48, 0x78, 0xf5, }, 6, 0, "", "",
+"62 f1 7c 48 78 f5    \tvcvttps2udq %zmm5,%zmm6",},
+{{0x62, 0xf1, 0xfc, 0x4f, 0x78, 0xf5, }, 6, 0, "", "",
+"62 f1 fc 4f 78 f5    \tvcvttpd2udq %zmm5,%ymm6{%k7}",},
+{{0x62, 0xf1, 0x7f, 0x08, 0x78, 0xc6, }, 6, 0, "", "",
+"62 f1 7f 08 78 c6    \tvcvttsd2usi %xmm6,%eax",},
+{{0x62, 0xf1, 0x7e, 0x08, 0x78, 0xc6, }, 6, 0, "", "",
+"62 f1 7e 08 78 c6    \tvcvttss2usi %xmm6,%eax",},
+{{0x62, 0xf1, 0x7d, 0x4f, 0x78, 0xf5, }, 6, 0, "", "",
+"62 f1 7d 4f 78 f5    \tvcvttps2uqq %ymm5,%zmm6{%k7}",},
+{{0x62, 0xf1, 0xfd, 0x48, 0x78, 0xf5, }, 6, 0, "", "",
+"62 f1 fd 48 78 f5    \tvcvttpd2uqq %zmm5,%zmm6",},
+{{0x0f, 0x79, 0xd8, }, 3, 0, "", "",
+"0f 79 d8             \tvmwrite %eax,%ebx",},
+{{0x62, 0xf1, 0x7c, 0x48, 0x79, 0xf5, }, 6, 0, "", "",
+"62 f1 7c 48 79 f5    \tvcvtps2udq %zmm5,%zmm6",},
+{{0x62, 0xf1, 0xfc, 0x4f, 0x79, 0xf5, }, 6, 0, "", "",
+"62 f1 fc 4f 79 f5    \tvcvtpd2udq %zmm5,%ymm6{%k7}",},
+{{0x62, 0xf1, 0x7f, 0x08, 0x79, 0xc6, }, 6, 0, "", "",
+"62 f1 7f 08 79 c6    \tvcvtsd2usi %xmm6,%eax",},
+{{0x62, 0xf1, 0x7e, 0x08, 0x79, 0xc6, }, 6, 0, "", "",
+"62 f1 7e 08 79 c6    \tvcvtss2usi %xmm6,%eax",},
+{{0x62, 0xf1, 0x7d, 0x4f, 0x79, 0xf5, }, 6, 0, "", "",
+"62 f1 7d 4f 79 f5    \tvcvtps2uqq %ymm5,%zmm6{%k7}",},
+{{0x62, 0xf1, 0xfd, 0x48, 0x79, 0xf5, }, 6, 0, "", "",
+"62 f1 fd 48 79 f5    \tvcvtpd2uqq %zmm5,%zmm6",},
+{{0x62, 0xf1, 0x7e, 0x4f, 0x7a, 0xf5, }, 6, 0, "", "",
+"62 f1 7e 4f 7a f5    \tvcvtudq2pd %ymm5,%zmm6{%k7}",},
+{{0x62, 0xf1, 0xfe, 0x48, 0x7a, 0xf5, }, 6, 0, "", "",
+"62 f1 fe 48 7a f5    \tvcvtuqq2pd %zmm5,%zmm6",},
+{{0x62, 0xf1, 0x7f, 0x48, 0x7a, 0xf5, }, 6, 0, "", "",
+"62 f1 7f 48 7a f5    \tvcvtudq2ps %zmm5,%zmm6",},
+{{0x62, 0xf1, 0xff, 0x4f, 0x7a, 0xf5, }, 6, 0, "", "",
+"62 f1 ff 4f 7a f5    \tvcvtuqq2ps %zmm5,%ymm6{%k7}",},
+{{0x62, 0xf1, 0x7d, 0x4f, 0x7a, 0xf5, }, 6, 0, "", "",
+"62 f1 7d 4f 7a f5    \tvcvttps2qq %ymm5,%zmm6{%k7}",},
+{{0x62, 0xf1, 0xfd, 0x48, 0x7a, 0xf5, }, 6, 0, "", "",
+"62 f1 fd 48 7a f5    \tvcvttpd2qq %zmm5,%zmm6",},
+{{0x62, 0xf1, 0x57, 0x08, 0x7b, 0xf0, }, 6, 0, "", "",
+"62 f1 57 08 7b f0    \tvcvtusi2sd %eax,%xmm5,%xmm6",},
+{{0x62, 0xf1, 0x56, 0x08, 0x7b, 0xf0, }, 6, 0, "", "",
+"62 f1 56 08 7b f0    \tvcvtusi2ss %eax,%xmm5,%xmm6",},
+{{0x62, 0xf1, 0x7d, 0x4f, 0x7b, 0xf5, }, 6, 0, "", "",
+"62 f1 7d 4f 7b f5    \tvcvtps2qq %ymm5,%zmm6{%k7}",},
+{{0x62, 0xf1, 0xfd, 0x48, 0x7b, 0xf5, }, 6, 0, "", "",
+"62 f1 fd 48 7b f5    \tvcvtpd2qq %zmm5,%zmm6",},
+{{0x0f, 0x7f, 0xc4, }, 3, 0, "", "",
+"0f 7f c4             \tmovq   %mm0,%mm4",},
+{{0xc5, 0xfd, 0x7f, 0xee, }, 4, 0, "", "",
+"c5 fd 7f ee          \tvmovdqa %ymm5,%ymm6",},
+{{0x62, 0xf1, 0x7d, 0x48, 0x7f, 0xee, }, 6, 0, "", "",
+"62 f1 7d 48 7f ee    \tvmovdqa32 %zmm5,%zmm6",},
+{{0x62, 0xf1, 0xfd, 0x48, 0x7f, 0xee, }, 6, 0, "", "",
+"62 f1 fd 48 7f ee    \tvmovdqa64 %zmm5,%zmm6",},
+{{0xc5, 0xfe, 0x7f, 0xee, }, 4, 0, "", "",
+"c5 fe 7f ee          \tvmovdqu %ymm5,%ymm6",},
+{{0x62, 0xf1, 0x7e, 0x48, 0x7f, 0xee, }, 6, 0, "", "",
+"62 f1 7e 48 7f ee    \tvmovdqu32 %zmm5,%zmm6",},
+{{0x62, 0xf1, 0xfe, 0x48, 0x7f, 0xee, }, 6, 0, "", "",
+"62 f1 fe 48 7f ee    \tvmovdqu64 %zmm5,%zmm6",},
+{{0x62, 0xf1, 0x7f, 0x48, 0x7f, 0xee, }, 6, 0, "", "",
+"62 f1 7f 48 7f ee    \tvmovdqu8 %zmm5,%zmm6",},
+{{0x62, 0xf1, 0xff, 0x48, 0x7f, 0xee, }, 6, 0, "", "",
+"62 f1 ff 48 7f ee    \tvmovdqu16 %zmm5,%zmm6",},
+{{0x0f, 0xdb, 0xd1, }, 3, 0, "", "",
+"0f db d1             \tpand   %mm1,%mm2",},
+{{0x66, 0x0f, 0xdb, 0xd1, }, 4, 0, "", "",
+"66 0f db d1          \tpand   %xmm1,%xmm2",},
+{{0xc5, 0xcd, 0xdb, 0xd4, }, 4, 0, "", "",
+"c5 cd db d4          \tvpand  %ymm4,%ymm6,%ymm2",},
+{{0x62, 0xf1, 0x55, 0x48, 0xdb, 0xf4, }, 6, 0, "", "",
+"62 f1 55 48 db f4    \tvpandd %zmm4,%zmm5,%zmm6",},
+{{0x62, 0xf1, 0xd5, 0x48, 0xdb, 0xf4, }, 6, 0, "", "",
+"62 f1 d5 48 db f4    \tvpandq %zmm4,%zmm5,%zmm6",},
+{{0x0f, 0xdf, 0xd1, }, 3, 0, "", "",
+"0f df d1             \tpandn  %mm1,%mm2",},
+{{0x66, 0x0f, 0xdf, 0xd1, }, 4, 0, "", "",
+"66 0f df d1          \tpandn  %xmm1,%xmm2",},
+{{0xc5, 0xcd, 0xdf, 0xd4, }, 4, 0, "", "",
+"c5 cd df d4          \tvpandn %ymm4,%ymm6,%ymm2",},
+{{0x62, 0xf1, 0x55, 0x48, 0xdf, 0xf4, }, 6, 0, "", "",
+"62 f1 55 48 df f4    \tvpandnd %zmm4,%zmm5,%zmm6",},
+{{0x62, 0xf1, 0xd5, 0x48, 0xdf, 0xf4, }, 6, 0, "", "",
+"62 f1 d5 48 df f4    \tvpandnq %zmm4,%zmm5,%zmm6",},
+{{0xc5, 0xf9, 0xe6, 0xd1, }, 4, 0, "", "",
+"c5 f9 e6 d1          \tvcvttpd2dq %xmm1,%xmm2",},
+{{0xc5, 0xfa, 0xe6, 0xf5, }, 4, 0, "", "",
+"c5 fa e6 f5          \tvcvtdq2pd %xmm5,%xmm6",},
+{{0x62, 0xf1, 0x7e, 0x4f, 0xe6, 0xf5, }, 6, 0, "", "",
+"62 f1 7e 4f e6 f5    \tvcvtdq2pd %ymm5,%zmm6{%k7}",},
+{{0x62, 0xf1, 0xfe, 0x48, 0xe6, 0xf5, }, 6, 0, "", "",
+"62 f1 fe 48 e6 f5    \tvcvtqq2pd %zmm5,%zmm6",},
+{{0xc5, 0xfb, 0xe6, 0xd1, }, 4, 0, "", "",
+"c5 fb e6 d1          \tvcvtpd2dq %xmm1,%xmm2",},
+{{0x0f, 0xeb, 0xf4, }, 3, 0, "", "",
+"0f eb f4             \tpor    %mm4,%mm6",},
+{{0xc5, 0xcd, 0xeb, 0xd4, }, 4, 0, "", "",
+"c5 cd eb d4          \tvpor   %ymm4,%ymm6,%ymm2",},
+{{0x62, 0xf1, 0x55, 0x48, 0xeb, 0xf4, }, 6, 0, "", "",
+"62 f1 55 48 eb f4    \tvpord  %zmm4,%zmm5,%zmm6",},
+{{0x62, 0xf1, 0xd5, 0x48, 0xeb, 0xf4, }, 6, 0, "", "",
+"62 f1 d5 48 eb f4    \tvporq  %zmm4,%zmm5,%zmm6",},
+{{0x0f, 0xef, 0xf4, }, 3, 0, "", "",
+"0f ef f4             \tpxor   %mm4,%mm6",},
+{{0xc5, 0xcd, 0xef, 0xd4, }, 4, 0, "", "",
+"c5 cd ef d4          \tvpxor  %ymm4,%ymm6,%ymm2",},
+{{0x62, 0xf1, 0x55, 0x48, 0xef, 0xf4, }, 6, 0, "", "",
+"62 f1 55 48 ef f4    \tvpxord %zmm4,%zmm5,%zmm6",},
+{{0x62, 0xf1, 0xd5, 0x48, 0xef, 0xf4, }, 6, 0, "", "",
+"62 f1 d5 48 ef f4    \tvpxorq %zmm4,%zmm5,%zmm6",},
+{{0x66, 0x0f, 0x38, 0x10, 0xc1, }, 5, 0, "", "",
+"66 0f 38 10 c1       \tpblendvb %xmm0,%xmm1,%xmm0",},
+{{0x62, 0xf2, 0xd5, 0x48, 0x10, 0xf4, }, 6, 0, "", "",
+"62 f2 d5 48 10 f4    \tvpsrlvw %zmm4,%zmm5,%zmm6",},
+{{0x62, 0xf2, 0x7e, 0x4f, 0x10, 0xee, }, 6, 0, "", "",
+"62 f2 7e 4f 10 ee    \tvpmovuswb %zmm5,%ymm6{%k7}",},
+{{0x62, 0xf2, 0x7e, 0x4f, 0x11, 0xee, }, 6, 0, "", "",
+"62 f2 7e 4f 11 ee    \tvpmovusdb %zmm5,%xmm6{%k7}",},
+{{0x62, 0xf2, 0xd5, 0x48, 0x11, 0xf4, }, 6, 0, "", "",
+"62 f2 d5 48 11 f4    \tvpsravw %zmm4,%zmm5,%zmm6",},
+{{0x62, 0xf2, 0x7e, 0x4f, 0x12, 0xee, }, 6, 0, "", "",
+"62 f2 7e 4f 12 ee    \tvpmovusqb %zmm5,%xmm6{%k7}",},
+{{0x62, 0xf2, 0xd5, 0x48, 0x12, 0xf4, }, 6, 0, "", "",
+"62 f2 d5 48 12 f4    \tvpsllvw %zmm4,%zmm5,%zmm6",},
+{{0xc4, 0xe2, 0x7d, 0x13, 0xeb, }, 5, 0, "", "",
+"c4 e2 7d 13 eb       \tvcvtph2ps %xmm3,%ymm5",},
+{{0x62, 0xf2, 0x7d, 0x4f, 0x13, 0xf5, }, 6, 0, "", "",
+"62 f2 7d 4f 13 f5    \tvcvtph2ps %ymm5,%zmm6{%k7}",},
+{{0x62, 0xf2, 0x7e, 0x4f, 0x13, 0xee, }, 6, 0, "", "",
+"62 f2 7e 4f 13 ee    \tvpmovusdw %zmm5,%ymm6{%k7}",},
+{{0x66, 0x0f, 0x38, 0x14, 0xc1, }, 5, 0, "", "",
+"66 0f 38 14 c1       \tblendvps %xmm0,%xmm1,%xmm0",},
+{{0x62, 0xf2, 0x7e, 0x4f, 0x14, 0xee, }, 6, 0, "", "",
+"62 f2 7e 4f 14 ee    \tvpmovusqw %zmm5,%xmm6{%k7}",},
+{{0x62, 0xf2, 0x55, 0x48, 0x14, 0xf4, }, 6, 0, "", "",
+"62 f2 55 48 14 f4    \tvprorvd %zmm4,%zmm5,%zmm6",},
+{{0x62, 0xf2, 0xd5, 0x48, 0x14, 0xf4, }, 6, 0, "", "",
+"62 f2 d5 48 14 f4    \tvprorvq %zmm4,%zmm5,%zmm6",},
+{{0x66, 0x0f, 0x38, 0x15, 0xc1, }, 5, 0, "", "",
+"66 0f 38 15 c1       \tblendvpd %xmm0,%xmm1,%xmm0",},
+{{0x62, 0xf2, 0x7e, 0x4f, 0x15, 0xee, }, 6, 0, "", "",
+"62 f2 7e 4f 15 ee    \tvpmovusqd %zmm5,%ymm6{%k7}",},
+{{0x62, 0xf2, 0x55, 0x48, 0x15, 0xf4, }, 6, 0, "", "",
+"62 f2 55 48 15 f4    \tvprolvd %zmm4,%zmm5,%zmm6",},
+{{0x62, 0xf2, 0xd5, 0x48, 0x15, 0xf4, }, 6, 0, "", "",
+"62 f2 d5 48 15 f4    \tvprolvq %zmm4,%zmm5,%zmm6",},
+{{0xc4, 0xe2, 0x4d, 0x16, 0xd4, }, 5, 0, "", "",
+"c4 e2 4d 16 d4       \tvpermps %ymm4,%ymm6,%ymm2",},
+{{0x62, 0xf2, 0x4d, 0x2f, 0x16, 0xd4, }, 6, 0, "", "",
+"62 f2 4d 2f 16 d4    \tvpermps %ymm4,%ymm6,%ymm2{%k7}",},
+{{0x62, 0xf2, 0xcd, 0x2f, 0x16, 0xd4, }, 6, 0, "", "",
+"62 f2 cd 2f 16 d4    \tvpermpd %ymm4,%ymm6,%ymm2{%k7}",},
+{{0xc4, 0xe2, 0x7d, 0x19, 0xf4, }, 5, 0, "", "",
+"c4 e2 7d 19 f4       \tvbroadcastsd %xmm4,%ymm6",},
+{{0x62, 0xf2, 0x7d, 0x48, 0x19, 0xf7, }, 6, 0, "", "",
+"62 f2 7d 48 19 f7    \tvbroadcastf32x2 %xmm7,%zmm6",},
+{{0xc4, 0xe2, 0x7d, 0x1a, 0x21, }, 5, 0, "", "",
+"c4 e2 7d 1a 21       \tvbroadcastf128 (%ecx),%ymm4",},
+{{0x62, 0xf2, 0x7d, 0x48, 0x1a, 0x31, }, 6, 0, "", "",
+"62 f2 7d 48 1a 31    \tvbroadcastf32x4 (%ecx),%zmm6",},
+{{0x62, 0xf2, 0xfd, 0x48, 0x1a, 0x31, }, 6, 0, "", "",
+"62 f2 fd 48 1a 31    \tvbroadcastf64x2 (%ecx),%zmm6",},
+{{0x62, 0xf2, 0x7d, 0x48, 0x1b, 0x31, }, 6, 0, "", "",
+"62 f2 7d 48 1b 31    \tvbroadcastf32x8 (%ecx),%zmm6",},
+{{0x62, 0xf2, 0xfd, 0x48, 0x1b, 0x31, }, 6, 0, "", "",
+"62 f2 fd 48 1b 31    \tvbroadcastf64x4 (%ecx),%zmm6",},
+{{0x62, 0xf2, 0xfd, 0x48, 0x1f, 0xf4, }, 6, 0, "", "",
+"62 f2 fd 48 1f f4    \tvpabsq %zmm4,%zmm6",},
+{{0xc4, 0xe2, 0x79, 0x20, 0xec, }, 5, 0, "", "",
+"c4 e2 79 20 ec       \tvpmovsxbw %xmm4,%xmm5",},
+{{0x62, 0xf2, 0x7e, 0x4f, 0x20, 0xee, }, 6, 0, "", "",
+"62 f2 7e 4f 20 ee    \tvpmovswb %zmm5,%ymm6{%k7}",},
+{{0xc4, 0xe2, 0x7d, 0x21, 0xf4, }, 5, 0, "", "",
+"c4 e2 7d 21 f4       \tvpmovsxbd %xmm4,%ymm6",},
+{{0x62, 0xf2, 0x7e, 0x4f, 0x21, 0xee, }, 6, 0, "", "",
+"62 f2 7e 4f 21 ee    \tvpmovsdb %zmm5,%xmm6{%k7}",},
+{{0xc4, 0xe2, 0x7d, 0x22, 0xe4, }, 5, 0, "", "",
+"c4 e2 7d 22 e4       \tvpmovsxbq %xmm4,%ymm4",},
+{{0x62, 0xf2, 0x7e, 0x4f, 0x22, 0xee, }, 6, 0, "", "",
+"62 f2 7e 4f 22 ee    \tvpmovsqb %zmm5,%xmm6{%k7}",},
+{{0xc4, 0xe2, 0x7d, 0x23, 0xe4, }, 5, 0, "", "",
+"c4 e2 7d 23 e4       \tvpmovsxwd %xmm4,%ymm4",},
+{{0x62, 0xf2, 0x7e, 0x4f, 0x23, 0xee, }, 6, 0, "", "",
+"62 f2 7e 4f 23 ee    \tvpmovsdw %zmm5,%ymm6{%k7}",},
+{{0xc4, 0xe2, 0x7d, 0x24, 0xf4, }, 5, 0, "", "",
+"c4 e2 7d 24 f4       \tvpmovsxwq %xmm4,%ymm6",},
+{{0x62, 0xf2, 0x7e, 0x4f, 0x24, 0xee, }, 6, 0, "", "",
+"62 f2 7e 4f 24 ee    \tvpmovsqw %zmm5,%xmm6{%k7}",},
+{{0xc4, 0xe2, 0x7d, 0x25, 0xe4, }, 5, 0, "", "",
+"c4 e2 7d 25 e4       \tvpmovsxdq %xmm4,%ymm4",},
+{{0x62, 0xf2, 0x7e, 0x4f, 0x25, 0xee, }, 6, 0, "", "",
+"62 f2 7e 4f 25 ee    \tvpmovsqd %zmm5,%ymm6{%k7}",},
+{{0x62, 0xf2, 0x4d, 0x48, 0x26, 0xed, }, 6, 0, "", "",
+"62 f2 4d 48 26 ed    \tvptestmb %zmm5,%zmm6,%k5",},
+{{0x62, 0xf2, 0xcd, 0x48, 0x26, 0xed, }, 6, 0, "", "",
+"62 f2 cd 48 26 ed    \tvptestmw %zmm5,%zmm6,%k5",},
+{{0x62, 0xf2, 0x56, 0x48, 0x26, 0xec, }, 6, 0, "", "",
+"62 f2 56 48 26 ec    \tvptestnmb %zmm4,%zmm5,%k5",},
+{{0x62, 0xf2, 0xd6, 0x48, 0x26, 0xec, }, 6, 0, "", "",
+"62 f2 d6 48 26 ec    \tvptestnmw %zmm4,%zmm5,%k5",},
+{{0x62, 0xf2, 0x4d, 0x48, 0x27, 0xed, }, 6, 0, "", "",
+"62 f2 4d 48 27 ed    \tvptestmd %zmm5,%zmm6,%k5",},
+{{0x62, 0xf2, 0xcd, 0x48, 0x27, 0xed, }, 6, 0, "", "",
+"62 f2 cd 48 27 ed    \tvptestmq %zmm5,%zmm6,%k5",},
+{{0x62, 0xf2, 0x56, 0x48, 0x27, 0xec, }, 6, 0, "", "",
+"62 f2 56 48 27 ec    \tvptestnmd %zmm4,%zmm5,%k5",},
+{{0x62, 0xf2, 0xd6, 0x48, 0x27, 0xec, }, 6, 0, "", "",
+"62 f2 d6 48 27 ec    \tvptestnmq %zmm4,%zmm5,%k5",},
+{{0xc4, 0xe2, 0x4d, 0x28, 0xd4, }, 5, 0, "", "",
+"c4 e2 4d 28 d4       \tvpmuldq %ymm4,%ymm6,%ymm2",},
+{{0x62, 0xf2, 0x7e, 0x48, 0x28, 0xf5, }, 6, 0, "", "",
+"62 f2 7e 48 28 f5    \tvpmovm2b %k5,%zmm6",},
+{{0x62, 0xf2, 0xfe, 0x48, 0x28, 0xf5, }, 6, 0, "", "",
+"62 f2 fe 48 28 f5    \tvpmovm2w %k5,%zmm6",},
+{{0xc4, 0xe2, 0x4d, 0x29, 0xd4, }, 5, 0, "", "",
+"c4 e2 4d 29 d4       \tvpcmpeqq %ymm4,%ymm6,%ymm2",},
+{{0x62, 0xf2, 0x7e, 0x48, 0x29, 0xee, }, 6, 0, "", "",
+"62 f2 7e 48 29 ee    \tvpmovb2m %zmm6,%k5",},
+{{0x62, 0xf2, 0xfe, 0x48, 0x29, 0xee, }, 6, 0, "", "",
+"62 f2 fe 48 29 ee    \tvpmovw2m %zmm6,%k5",},
+{{0xc4, 0xe2, 0x7d, 0x2a, 0x21, }, 5, 0, "", "",
+"c4 e2 7d 2a 21       \tvmovntdqa (%ecx),%ymm4",},
+{{0x62, 0xf2, 0xfe, 0x48, 0x2a, 0xce, }, 6, 0, "", "",
+"62 f2 fe 48 2a ce    \tvpbroadcastmb2q %k6,%zmm1",},
+{{0xc4, 0xe2, 0x5d, 0x2c, 0x31, }, 5, 0, "", "",
+"c4 e2 5d 2c 31       \tvmaskmovps (%ecx),%ymm4,%ymm6",},
+{{0x62, 0xf2, 0x55, 0x48, 0x2c, 0xf4, }, 6, 0, "", "",
+"62 f2 55 48 2c f4    \tvscalefps %zmm4,%zmm5,%zmm6",},
+{{0x62, 0xf2, 0xd5, 0x48, 0x2c, 0xf4, }, 6, 0, "", "",
+"62 f2 d5 48 2c f4    \tvscalefpd %zmm4,%zmm5,%zmm6",},
+{{0xc4, 0xe2, 0x5d, 0x2d, 0x31, }, 5, 0, "", "",
+"c4 e2 5d 2d 31       \tvmaskmovpd (%ecx),%ymm4,%ymm6",},
+{{0x62, 0xf2, 0x55, 0x0f, 0x2d, 0xf4, }, 6, 0, "", "",
+"62 f2 55 0f 2d f4    \tvscalefss %xmm4,%xmm5,%xmm6{%k7}",},
+{{0x62, 0xf2, 0xd5, 0x0f, 0x2d, 0xf4, }, 6, 0, "", "",
+"62 f2 d5 0f 2d f4    \tvscalefsd %xmm4,%xmm5,%xmm6{%k7}",},
+{{0xc4, 0xe2, 0x7d, 0x30, 0xe4, }, 5, 0, "", "",
+"c4 e2 7d 30 e4       \tvpmovzxbw %xmm4,%ymm4",},
+{{0x62, 0xf2, 0x7e, 0x4f, 0x30, 0xee, }, 6, 0, "", "",
+"62 f2 7e 4f 30 ee    \tvpmovwb %zmm5,%ymm6{%k7}",},
+{{0xc4, 0xe2, 0x7d, 0x31, 0xf4, }, 5, 0, "", "",
+"c4 e2 7d 31 f4       \tvpmovzxbd %xmm4,%ymm6",},
+{{0x62, 0xf2, 0x7e, 0x4f, 0x31, 0xee, }, 6, 0, "", "",
+"62 f2 7e 4f 31 ee    \tvpmovdb %zmm5,%xmm6{%k7}",},
+{{0xc4, 0xe2, 0x7d, 0x32, 0xe4, }, 5, 0, "", "",
+"c4 e2 7d 32 e4       \tvpmovzxbq %xmm4,%ymm4",},
+{{0x62, 0xf2, 0x7e, 0x4f, 0x32, 0xee, }, 6, 0, "", "",
+"62 f2 7e 4f 32 ee    \tvpmovqb %zmm5,%xmm6{%k7}",},
+{{0xc4, 0xe2, 0x7d, 0x33, 0xe4, }, 5, 0, "", "",
+"c4 e2 7d 33 e4       \tvpmovzxwd %xmm4,%ymm4",},
+{{0x62, 0xf2, 0x7e, 0x4f, 0x33, 0xee, }, 6, 0, "", "",
+"62 f2 7e 4f 33 ee    \tvpmovdw %zmm5,%ymm6{%k7}",},
+{{0xc4, 0xe2, 0x7d, 0x34, 0xf4, }, 5, 0, "", "",
+"c4 e2 7d 34 f4       \tvpmovzxwq %xmm4,%ymm6",},
+{{0x62, 0xf2, 0x7e, 0x4f, 0x34, 0xee, }, 6, 0, "", "",
+"62 f2 7e 4f 34 ee    \tvpmovqw %zmm5,%xmm6{%k7}",},
+{{0xc4, 0xe2, 0x7d, 0x35, 0xe4, }, 5, 0, "", "",
+"c4 e2 7d 35 e4       \tvpmovzxdq %xmm4,%ymm4",},
+{{0x62, 0xf2, 0x7e, 0x4f, 0x35, 0xee, }, 6, 0, "", "",
+"62 f2 7e 4f 35 ee    \tvpmovqd %zmm5,%ymm6{%k7}",},
+{{0xc4, 0xe2, 0x4d, 0x36, 0xd4, }, 5, 0, "", "",
+"c4 e2 4d 36 d4       \tvpermd %ymm4,%ymm6,%ymm2",},
+{{0x62, 0xf2, 0x4d, 0x2f, 0x36, 0xd4, }, 6, 0, "", "",
+"62 f2 4d 2f 36 d4    \tvpermd %ymm4,%ymm6,%ymm2{%k7}",},
+{{0x62, 0xf2, 0xcd, 0x2f, 0x36, 0xd4, }, 6, 0, "", "",
+"62 f2 cd 2f 36 d4    \tvpermq %ymm4,%ymm6,%ymm2{%k7}",},
+{{0xc4, 0xe2, 0x4d, 0x38, 0xd4, }, 5, 0, "", "",
+"c4 e2 4d 38 d4       \tvpminsb %ymm4,%ymm6,%ymm2",},
+{{0x62, 0xf2, 0x7e, 0x48, 0x38, 0xf5, }, 6, 0, "", "",
+"62 f2 7e 48 38 f5    \tvpmovm2d %k5,%zmm6",},
+{{0x62, 0xf2, 0xfe, 0x48, 0x38, 0xf5, }, 6, 0, "", "",
+"62 f2 fe 48 38 f5    \tvpmovm2q %k5,%zmm6",},
+{{0xc4, 0xe2, 0x69, 0x39, 0xd9, }, 5, 0, "", "",
+"c4 e2 69 39 d9       \tvpminsd %xmm1,%xmm2,%xmm3",},
+{{0x62, 0xf2, 0x55, 0x48, 0x39, 0xf4, }, 6, 0, "", "",
+"62 f2 55 48 39 f4    \tvpminsd %zmm4,%zmm5,%zmm6",},
+{{0x62, 0xf2, 0xd5, 0x48, 0x39, 0xf4, }, 6, 0, "", "",
+"62 f2 d5 48 39 f4    \tvpminsq %zmm4,%zmm5,%zmm6",},
+{{0x62, 0xf2, 0x7e, 0x48, 0x39, 0xee, }, 6, 0, "", "",
+"62 f2 7e 48 39 ee    \tvpmovd2m %zmm6,%k5",},
+{{0x62, 0xf2, 0xfe, 0x48, 0x39, 0xee, }, 6, 0, "", "",
+"62 f2 fe 48 39 ee    \tvpmovq2m %zmm6,%k5",},
+{{0xc4, 0xe2, 0x4d, 0x3a, 0xd4, }, 5, 0, "", "",
+"c4 e2 4d 3a d4       \tvpminuw %ymm4,%ymm6,%ymm2",},
+{{0x62, 0xf2, 0x7e, 0x48, 0x3a, 0xf6, }, 6, 0, "", "",
+"62 f2 7e 48 3a f6    \tvpbroadcastmw2d %k6,%zmm6",},
+{{0xc4, 0xe2, 0x4d, 0x3b, 0xd4, }, 5, 0, "", "",
+"c4 e2 4d 3b d4       \tvpminud %ymm4,%ymm6,%ymm2",},
+{{0x62, 0xf2, 0x55, 0x48, 0x3b, 0xf4, }, 6, 0, "", "",
+"62 f2 55 48 3b f4    \tvpminud %zmm4,%zmm5,%zmm6",},
+{{0x62, 0xf2, 0xd5, 0x48, 0x3b, 0xf4, }, 6, 0, "", "",
+"62 f2 d5 48 3b f4    \tvpminuq %zmm4,%zmm5,%zmm6",},
+{{0xc4, 0xe2, 0x4d, 0x3d, 0xd4, }, 5, 0, "", "",
+"c4 e2 4d 3d d4       \tvpmaxsd %ymm4,%ymm6,%ymm2",},
+{{0x62, 0xf2, 0x55, 0x48, 0x3d, 0xf4, }, 6, 0, "", "",
+"62 f2 55 48 3d f4    \tvpmaxsd %zmm4,%zmm5,%zmm6",},
+{{0x62, 0xf2, 0xd5, 0x48, 0x3d, 0xf4, }, 6, 0, "", "",
+"62 f2 d5 48 3d f4    \tvpmaxsq %zmm4,%zmm5,%zmm6",},
+{{0xc4, 0xe2, 0x4d, 0x3f, 0xd4, }, 5, 0, "", "",
+"c4 e2 4d 3f d4       \tvpmaxud %ymm4,%ymm6,%ymm2",},
+{{0x62, 0xf2, 0x55, 0x48, 0x3f, 0xf4, }, 6, 0, "", "",
+"62 f2 55 48 3f f4    \tvpmaxud %zmm4,%zmm5,%zmm6",},
+{{0x62, 0xf2, 0xd5, 0x48, 0x3f, 0xf4, }, 6, 0, "", "",
+"62 f2 d5 48 3f f4    \tvpmaxuq %zmm4,%zmm5,%zmm6",},
+{{0xc4, 0xe2, 0x4d, 0x40, 0xd4, }, 5, 0, "", "",
+"c4 e2 4d 40 d4       \tvpmulld %ymm4,%ymm6,%ymm2",},
+{{0x62, 0xf2, 0x55, 0x48, 0x40, 0xf4, }, 6, 0, "", "",
+"62 f2 55 48 40 f4    \tvpmulld %zmm4,%zmm5,%zmm6",},
+{{0x62, 0xf2, 0xd5, 0x48, 0x40, 0xf4, }, 6, 0, "", "",
+"62 f2 d5 48 40 f4    \tvpmullq %zmm4,%zmm5,%zmm6",},
+{{0x62, 0xf2, 0x7d, 0x48, 0x42, 0xf5, }, 6, 0, "", "",
+"62 f2 7d 48 42 f5    \tvgetexpps %zmm5,%zmm6",},
+{{0x62, 0xf2, 0xfd, 0x48, 0x42, 0xf5, }, 6, 0, "", "",
+"62 f2 fd 48 42 f5    \tvgetexppd %zmm5,%zmm6",},
+{{0x62, 0xf2, 0x55, 0x0f, 0x43, 0xf4, }, 6, 0, "", "",
+"62 f2 55 0f 43 f4    \tvgetexpss %xmm4,%xmm5,%xmm6{%k7}",},
+{{0x62, 0xf2, 0xe5, 0x0f, 0x43, 0xe2, }, 6, 0, "", "",
+"62 f2 e5 0f 43 e2    \tvgetexpsd %xmm2,%xmm3,%xmm4{%k7}",},
+{{0x62, 0xf2, 0x7d, 0x48, 0x44, 0xf5, }, 6, 0, "", "",
+"62 f2 7d 48 44 f5    \tvplzcntd %zmm5,%zmm6",},
+{{0x62, 0xf2, 0xfd, 0x48, 0x44, 0xf5, }, 6, 0, "", "",
+"62 f2 fd 48 44 f5    \tvplzcntq %zmm5,%zmm6",},
+{{0xc4, 0xe2, 0x4d, 0x46, 0xd4, }, 5, 0, "", "",
+"c4 e2 4d 46 d4       \tvpsravd %ymm4,%ymm6,%ymm2",},
+{{0x62, 0xf2, 0x55, 0x48, 0x46, 0xf4, }, 6, 0, "", "",
+"62 f2 55 48 46 f4    \tvpsravd %zmm4,%zmm5,%zmm6",},
+{{0x62, 0xf2, 0xd5, 0x48, 0x46, 0xf4, }, 6, 0, "", "",
+"62 f2 d5 48 46 f4    \tvpsravq %zmm4,%zmm5,%zmm6",},
+{{0x62, 0xf2, 0x7d, 0x48, 0x4c, 0xf5, }, 6, 0, "", "",
+"62 f2 7d 48 4c f5    \tvrcp14ps %zmm5,%zmm6",},
+{{0x62, 0xf2, 0xfd, 0x48, 0x4c, 0xf5, }, 6, 0, "", "",
+"62 f2 fd 48 4c f5    \tvrcp14pd %zmm5,%zmm6",},
+{{0x62, 0xf2, 0x55, 0x0f, 0x4d, 0xf4, }, 6, 0, "", "",
+"62 f2 55 0f 4d f4    \tvrcp14ss %xmm4,%xmm5,%xmm6{%k7}",},
+{{0x62, 0xf2, 0xd5, 0x0f, 0x4d, 0xf4, }, 6, 0, "", "",
+"62 f2 d5 0f 4d f4    \tvrcp14sd %xmm4,%xmm5,%xmm6{%k7}",},
+{{0x62, 0xf2, 0x7d, 0x48, 0x4e, 0xf5, }, 6, 0, "", "",
+"62 f2 7d 48 4e f5    \tvrsqrt14ps %zmm5,%zmm6",},
+{{0x62, 0xf2, 0xfd, 0x48, 0x4e, 0xf5, }, 6, 0, "", "",
+"62 f2 fd 48 4e f5    \tvrsqrt14pd %zmm5,%zmm6",},
+{{0x62, 0xf2, 0x55, 0x0f, 0x4f, 0xf4, }, 6, 0, "", "",
+"62 f2 55 0f 4f f4    \tvrsqrt14ss %xmm4,%xmm5,%xmm6{%k7}",},
+{{0x62, 0xf2, 0xd5, 0x0f, 0x4f, 0xf4, }, 6, 0, "", "",
+"62 f2 d5 0f 4f f4    \tvrsqrt14sd %xmm4,%xmm5,%xmm6{%k7}",},
+{{0xc4, 0xe2, 0x79, 0x59, 0xf4, }, 5, 0, "", "",
+"c4 e2 79 59 f4       \tvpbroadcastq %xmm4,%xmm6",},
+{{0x62, 0xf2, 0x7d, 0x48, 0x59, 0xf7, }, 6, 0, "", "",
+"62 f2 7d 48 59 f7    \tvbroadcasti32x2 %xmm7,%zmm6",},
+{{0xc4, 0xe2, 0x7d, 0x5a, 0x21, }, 5, 0, "", "",
+"c4 e2 7d 5a 21       \tvbroadcasti128 (%ecx),%ymm4",},
+{{0x62, 0xf2, 0x7d, 0x48, 0x5a, 0x31, }, 6, 0, "", "",
+"62 f2 7d 48 5a 31    \tvbroadcasti32x4 (%ecx),%zmm6",},
+{{0x62, 0xf2, 0xfd, 0x48, 0x5a, 0x31, }, 6, 0, "", "",
+"62 f2 fd 48 5a 31    \tvbroadcasti64x2 (%ecx),%zmm6",},
+{{0x62, 0xf2, 0x7d, 0x48, 0x5b, 0x31, }, 6, 0, "", "",
+"62 f2 7d 48 5b 31    \tvbroadcasti32x8 (%ecx),%zmm6",},
+{{0x62, 0xf2, 0xfd, 0x48, 0x5b, 0x31, }, 6, 0, "", "",
+"62 f2 fd 48 5b 31    \tvbroadcasti64x4 (%ecx),%zmm6",},
+{{0x62, 0xf2, 0x55, 0x48, 0x64, 0xf4, }, 6, 0, "", "",
+"62 f2 55 48 64 f4    \tvpblendmd %zmm4,%zmm5,%zmm6",},
+{{0x62, 0xf2, 0xd5, 0x48, 0x64, 0xf4, }, 6, 0, "", "",
+"62 f2 d5 48 64 f4    \tvpblendmq %zmm4,%zmm5,%zmm6",},
+{{0x62, 0xf2, 0x55, 0x48, 0x65, 0xf4, }, 6, 0, "", "",
+"62 f2 55 48 65 f4    \tvblendmps %zmm4,%zmm5,%zmm6",},
+{{0x62, 0xf2, 0xd5, 0x48, 0x65, 0xf4, }, 6, 0, "", "",
+"62 f2 d5 48 65 f4    \tvblendmpd %zmm4,%zmm5,%zmm6",},
+{{0x62, 0xf2, 0x55, 0x48, 0x66, 0xf4, }, 6, 0, "", "",
+"62 f2 55 48 66 f4    \tvpblendmb %zmm4,%zmm5,%zmm6",},
+{{0x62, 0xf2, 0xd5, 0x48, 0x66, 0xf4, }, 6, 0, "", "",
+"62 f2 d5 48 66 f4    \tvpblendmw %zmm4,%zmm5,%zmm6",},
+{{0x62, 0xf2, 0x55, 0x48, 0x75, 0xf4, }, 6, 0, "", "",
+"62 f2 55 48 75 f4    \tvpermi2b %zmm4,%zmm5,%zmm6",},
+{{0x62, 0xf2, 0xd5, 0x48, 0x75, 0xf4, }, 6, 0, "", "",
+"62 f2 d5 48 75 f4    \tvpermi2w %zmm4,%zmm5,%zmm6",},
+{{0x62, 0xf2, 0x55, 0x48, 0x76, 0xf4, }, 6, 0, "", "",
+"62 f2 55 48 76 f4    \tvpermi2d %zmm4,%zmm5,%zmm6",},
+{{0x62, 0xf2, 0xd5, 0x48, 0x76, 0xf4, }, 6, 0, "", "",
+"62 f2 d5 48 76 f4    \tvpermi2q %zmm4,%zmm5,%zmm6",},
+{{0x62, 0xf2, 0x55, 0x48, 0x77, 0xf4, }, 6, 0, "", "",
+"62 f2 55 48 77 f4    \tvpermi2ps %zmm4,%zmm5,%zmm6",},
+{{0x62, 0xf2, 0xd5, 0x48, 0x77, 0xf4, }, 6, 0, "", "",
+"62 f2 d5 48 77 f4    \tvpermi2pd %zmm4,%zmm5,%zmm6",},
+{{0x62, 0xf2, 0x7d, 0x08, 0x7a, 0xd8, }, 6, 0, "", "",
+"62 f2 7d 08 7a d8    \tvpbroadcastb %eax,%xmm3",},
+{{0x62, 0xf2, 0x7d, 0x08, 0x7b, 0xd8, }, 6, 0, "", "",
+"62 f2 7d 08 7b d8    \tvpbroadcastw %eax,%xmm3",},
+{{0x62, 0xf2, 0x7d, 0x08, 0x7c, 0xd8, }, 6, 0, "", "",
+"62 f2 7d 08 7c d8    \tvpbroadcastd %eax,%xmm3",},
+{{0x62, 0xf2, 0x55, 0x48, 0x7d, 0xf4, }, 6, 0, "", "",
+"62 f2 55 48 7d f4    \tvpermt2b %zmm4,%zmm5,%zmm6",},
+{{0x62, 0xf2, 0xd5, 0x48, 0x7d, 0xf4, }, 6, 0, "", "",
+"62 f2 d5 48 7d f4    \tvpermt2w %zmm4,%zmm5,%zmm6",},
+{{0x62, 0xf2, 0x55, 0x48, 0x7e, 0xf4, }, 6, 0, "", "",
+"62 f2 55 48 7e f4    \tvpermt2d %zmm4,%zmm5,%zmm6",},
+{{0x62, 0xf2, 0xd5, 0x48, 0x7e, 0xf4, }, 6, 0, "", "",
+"62 f2 d5 48 7e f4    \tvpermt2q %zmm4,%zmm5,%zmm6",},
+{{0x62, 0xf2, 0x55, 0x48, 0x7f, 0xf4, }, 6, 0, "", "",
+"62 f2 55 48 7f f4    \tvpermt2ps %zmm4,%zmm5,%zmm6",},
+{{0x62, 0xf2, 0xd5, 0x48, 0x7f, 0xf4, }, 6, 0, "", "",
+"62 f2 d5 48 7f f4    \tvpermt2pd %zmm4,%zmm5,%zmm6",},
+{{0x62, 0xf2, 0xd5, 0x48, 0x83, 0xf4, }, 6, 0, "", "",
+"62 f2 d5 48 83 f4    \tvpmultishiftqb %zmm4,%zmm5,%zmm6",},
+{{0x62, 0xf2, 0x7d, 0x48, 0x88, 0x31, }, 6, 0, "", "",
+"62 f2 7d 48 88 31    \tvexpandps (%ecx),%zmm6",},
+{{0x62, 0xf2, 0xfd, 0x48, 0x88, 0x31, }, 6, 0, "", "",
+"62 f2 fd 48 88 31    \tvexpandpd (%ecx),%zmm6",},
+{{0x62, 0xf2, 0x7d, 0x48, 0x89, 0x31, }, 6, 0, "", "",
+"62 f2 7d 48 89 31    \tvpexpandd (%ecx),%zmm6",},
+{{0x62, 0xf2, 0xfd, 0x48, 0x89, 0x31, }, 6, 0, "", "",
+"62 f2 fd 48 89 31    \tvpexpandq (%ecx),%zmm6",},
+{{0x62, 0xf2, 0x7d, 0x48, 0x8a, 0x31, }, 6, 0, "", "",
+"62 f2 7d 48 8a 31    \tvcompressps %zmm6,(%ecx)",},
+{{0x62, 0xf2, 0xfd, 0x48, 0x8a, 0x31, }, 6, 0, "", "",
+"62 f2 fd 48 8a 31    \tvcompresspd %zmm6,(%ecx)",},
+{{0x62, 0xf2, 0x7d, 0x48, 0x8b, 0x31, }, 6, 0, "", "",
+"62 f2 7d 48 8b 31    \tvpcompressd %zmm6,(%ecx)",},
+{{0x62, 0xf2, 0xfd, 0x48, 0x8b, 0x31, }, 6, 0, "", "",
+"62 f2 fd 48 8b 31    \tvpcompressq %zmm6,(%ecx)",},
+{{0x62, 0xf2, 0x55, 0x48, 0x8d, 0xf4, }, 6, 0, "", "",
+"62 f2 55 48 8d f4    \tvpermb %zmm4,%zmm5,%zmm6",},
+{{0x62, 0xf2, 0xd5, 0x48, 0x8d, 0xf4, }, 6, 0, "", "",
+"62 f2 d5 48 8d f4    \tvpermw %zmm4,%zmm5,%zmm6",},
+{{0xc4, 0xe2, 0x69, 0x90, 0x4c, 0x7d, 0x02, }, 7, 0, "", "",
+"c4 e2 69 90 4c 7d 02 \tvpgatherdd %xmm2,0x2(%ebp,%xmm7,2),%xmm1",},
+{{0xc4, 0xe2, 0xe9, 0x90, 0x4c, 0x7d, 0x04, }, 7, 0, "", "",
+"c4 e2 e9 90 4c 7d 04 \tvpgatherdq %xmm2,0x4(%ebp,%xmm7,2),%xmm1",},
+{{0x62, 0xf2, 0x7d, 0x49, 0x90, 0xb4, 0xfd, 0x7b, 0x00, 0x00, 0x00, }, 11, 0, "", "",
+"62 f2 7d 49 90 b4 fd 7b 00 00 00 \tvpgatherdd 0x7b(%ebp,%zmm7,8),%zmm6{%k1}",},
+{{0x62, 0xf2, 0xfd, 0x49, 0x90, 0xb4, 0xfd, 0x7b, 0x00, 0x00, 0x00, }, 11, 0, "", "",
+"62 f2 fd 49 90 b4 fd 7b 00 00 00 \tvpgatherdq 0x7b(%ebp,%ymm7,8),%zmm6{%k1}",},
+{{0xc4, 0xe2, 0x69, 0x91, 0x4c, 0x7d, 0x02, }, 7, 0, "", "",
+"c4 e2 69 91 4c 7d 02 \tvpgatherqd %xmm2,0x2(%ebp,%xmm7,2),%xmm1",},
+{{0xc4, 0xe2, 0xe9, 0x91, 0x4c, 0x7d, 0x02, }, 7, 0, "", "",
+"c4 e2 e9 91 4c 7d 02 \tvpgatherqq %xmm2,0x2(%ebp,%xmm7,2),%xmm1",},
+{{0x62, 0xf2, 0x7d, 0x49, 0x91, 0xb4, 0xfd, 0x7b, 0x00, 0x00, 0x00, }, 11, 0, "", "",
+"62 f2 7d 49 91 b4 fd 7b 00 00 00 \tvpgatherqd 0x7b(%ebp,%zmm7,8),%ymm6{%k1}",},
+{{0x62, 0xf2, 0xfd, 0x49, 0x91, 0xb4, 0xfd, 0x7b, 0x00, 0x00, 0x00, }, 11, 0, "", "",
+"62 f2 fd 49 91 b4 fd 7b 00 00 00 \tvpgatherqq 0x7b(%ebp,%zmm7,8),%zmm6{%k1}",},
+{{0x62, 0xf2, 0x7d, 0x49, 0xa0, 0xb4, 0xfd, 0x7b, 0x00, 0x00, 0x00, }, 11, 0, "", "",
+"62 f2 7d 49 a0 b4 fd 7b 00 00 00 \tvpscatterdd %zmm6,0x7b(%ebp,%zmm7,8){%k1}",},
+{{0x62, 0xf2, 0xfd, 0x49, 0xa0, 0xb4, 0xfd, 0x7b, 0x00, 0x00, 0x00, }, 11, 0, "", "",
+"62 f2 fd 49 a0 b4 fd 7b 00 00 00 \tvpscatterdq %zmm6,0x7b(%ebp,%ymm7,8){%k1}",},
+{{0x62, 0xf2, 0x7d, 0x49, 0xa1, 0xb4, 0xfd, 0x7b, 0x00, 0x00, 0x00, }, 11, 0, "", "",
+"62 f2 7d 49 a1 b4 fd 7b 00 00 00 \tvpscatterqd %ymm6,0x7b(%ebp,%zmm7,8){%k1}",},
+{{0x62, 0xf2, 0xfd, 0x29, 0xa1, 0xb4, 0xfd, 0x7b, 0x00, 0x00, 0x00, }, 11, 0, "", "",
+"62 f2 fd 29 a1 b4 fd 7b 00 00 00 \tvpscatterqq %ymm6,0x7b(%ebp,%ymm7,8){%k1}",},
+{{0x62, 0xf2, 0x7d, 0x49, 0xa2, 0xb4, 0xfd, 0x7b, 0x00, 0x00, 0x00, }, 11, 0, "", "",
+"62 f2 7d 49 a2 b4 fd 7b 00 00 00 \tvscatterdps %zmm6,0x7b(%ebp,%zmm7,8){%k1}",},
+{{0x62, 0xf2, 0xfd, 0x49, 0xa2, 0xb4, 0xfd, 0x7b, 0x00, 0x00, 0x00, }, 11, 0, "", "",
+"62 f2 fd 49 a2 b4 fd 7b 00 00 00 \tvscatterdpd %zmm6,0x7b(%ebp,%ymm7,8){%k1}",},
+{{0x62, 0xf2, 0x7d, 0x49, 0xa3, 0xb4, 0xfd, 0x7b, 0x00, 0x00, 0x00, }, 11, 0, "", "",
+"62 f2 7d 49 a3 b4 fd 7b 00 00 00 \tvscatterqps %ymm6,0x7b(%ebp,%zmm7,8){%k1}",},
+{{0x62, 0xf2, 0xfd, 0x49, 0xa3, 0xb4, 0xfd, 0x7b, 0x00, 0x00, 0x00, }, 11, 0, "", "",
+"62 f2 fd 49 a3 b4 fd 7b 00 00 00 \tvscatterqpd %zmm6,0x7b(%ebp,%zmm7,8){%k1}",},
+{{0x62, 0xf2, 0xd5, 0x48, 0xb4, 0xf4, }, 6, 0, "", "",
+"62 f2 d5 48 b4 f4    \tvpmadd52luq %zmm4,%zmm5,%zmm6",},
+{{0x62, 0xf2, 0xd5, 0x48, 0xb5, 0xf4, }, 6, 0, "", "",
+"62 f2 d5 48 b5 f4    \tvpmadd52huq %zmm4,%zmm5,%zmm6",},
+{{0x62, 0xf2, 0x7d, 0x48, 0xc4, 0xf5, }, 6, 0, "", "",
+"62 f2 7d 48 c4 f5    \tvpconflictd %zmm5,%zmm6",},
+{{0x62, 0xf2, 0xfd, 0x48, 0xc4, 0xf5, }, 6, 0, "", "",
+"62 f2 fd 48 c4 f5    \tvpconflictq %zmm5,%zmm6",},
+{{0x62, 0xf2, 0x7d, 0x48, 0xc8, 0xfe, }, 6, 0, "", "",
+"62 f2 7d 48 c8 fe    \tvexp2ps %zmm6,%zmm7",},
+{{0x62, 0xf2, 0xfd, 0x48, 0xc8, 0xfe, }, 6, 0, "", "",
+"62 f2 fd 48 c8 fe    \tvexp2pd %zmm6,%zmm7",},
+{{0x62, 0xf2, 0x7d, 0x48, 0xca, 0xfe, }, 6, 0, "", "",
+"62 f2 7d 48 ca fe    \tvrcp28ps %zmm6,%zmm7",},
+{{0x62, 0xf2, 0xfd, 0x48, 0xca, 0xfe, }, 6, 0, "", "",
+"62 f2 fd 48 ca fe    \tvrcp28pd %zmm6,%zmm7",},
+{{0x62, 0xf2, 0x4d, 0x0f, 0xcb, 0xfd, }, 6, 0, "", "",
+"62 f2 4d 0f cb fd    \tvrcp28ss %xmm5,%xmm6,%xmm7{%k7}",},
+{{0x62, 0xf2, 0xcd, 0x0f, 0xcb, 0xfd, }, 6, 0, "", "",
+"62 f2 cd 0f cb fd    \tvrcp28sd %xmm5,%xmm6,%xmm7{%k7}",},
+{{0x62, 0xf2, 0x7d, 0x48, 0xcc, 0xfe, }, 6, 0, "", "",
+"62 f2 7d 48 cc fe    \tvrsqrt28ps %zmm6,%zmm7",},
+{{0x62, 0xf2, 0xfd, 0x48, 0xcc, 0xfe, }, 6, 0, "", "",
+"62 f2 fd 48 cc fe    \tvrsqrt28pd %zmm6,%zmm7",},
+{{0x62, 0xf2, 0x4d, 0x0f, 0xcd, 0xfd, }, 6, 0, "", "",
+"62 f2 4d 0f cd fd    \tvrsqrt28ss %xmm5,%xmm6,%xmm7{%k7}",},
+{{0x62, 0xf2, 0xcd, 0x0f, 0xcd, 0xfd, }, 6, 0, "", "",
+"62 f2 cd 0f cd fd    \tvrsqrt28sd %xmm5,%xmm6,%xmm7{%k7}",},
+{{0x62, 0xf3, 0x4d, 0x48, 0x03, 0xfd, 0x12, }, 7, 0, "", "",
+"62 f3 4d 48 03 fd 12 \tvalignd $0x12,%zmm5,%zmm6,%zmm7",},
+{{0x62, 0xf3, 0xcd, 0x48, 0x03, 0xfd, 0x12, }, 7, 0, "", "",
+"62 f3 cd 48 03 fd 12 \tvalignq $0x12,%zmm5,%zmm6,%zmm7",},
+{{0xc4, 0xe3, 0x7d, 0x08, 0xd6, 0x05, }, 6, 0, "", "",
+"c4 e3 7d 08 d6 05    \tvroundps $0x5,%ymm6,%ymm2",},
+{{0x62, 0xf3, 0x7d, 0x48, 0x08, 0xf5, 0x12, }, 7, 0, "", "",
+"62 f3 7d 48 08 f5 12 \tvrndscaleps $0x12,%zmm5,%zmm6",},
+{{0xc4, 0xe3, 0x7d, 0x09, 0xd6, 0x05, }, 6, 0, "", "",
+"c4 e3 7d 09 d6 05    \tvroundpd $0x5,%ymm6,%ymm2",},
+{{0x62, 0xf3, 0xfd, 0x48, 0x09, 0xf5, 0x12, }, 7, 0, "", "",
+"62 f3 fd 48 09 f5 12 \tvrndscalepd $0x12,%zmm5,%zmm6",},
+{{0xc4, 0xe3, 0x49, 0x0a, 0xd4, 0x05, }, 6, 0, "", "",
+"c4 e3 49 0a d4 05    \tvroundss $0x5,%xmm4,%xmm6,%xmm2",},
+{{0x62, 0xf3, 0x55, 0x0f, 0x0a, 0xf4, 0x12, }, 7, 0, "", "",
+"62 f3 55 0f 0a f4 12 \tvrndscaless $0x12,%xmm4,%xmm5,%xmm6{%k7}",},
+{{0xc4, 0xe3, 0x49, 0x0b, 0xd4, 0x05, }, 6, 0, "", "",
+"c4 e3 49 0b d4 05    \tvroundsd $0x5,%xmm4,%xmm6,%xmm2",},
+{{0x62, 0xf3, 0xd5, 0x0f, 0x0b, 0xf4, 0x12, }, 7, 0, "", "",
+"62 f3 d5 0f 0b f4 12 \tvrndscalesd $0x12,%xmm4,%xmm5,%xmm6{%k7}",},
+{{0xc4, 0xe3, 0x5d, 0x18, 0xf4, 0x05, }, 6, 0, "", "",
+"c4 e3 5d 18 f4 05    \tvinsertf128 $0x5,%xmm4,%ymm4,%ymm6",},
+{{0x62, 0xf3, 0x55, 0x4f, 0x18, 0xf4, 0x12, }, 7, 0, "", "",
+"62 f3 55 4f 18 f4 12 \tvinsertf32x4 $0x12,%xmm4,%zmm5,%zmm6{%k7}",},
+{{0x62, 0xf3, 0xd5, 0x4f, 0x18, 0xf4, 0x12, }, 7, 0, "", "",
+"62 f3 d5 4f 18 f4 12 \tvinsertf64x2 $0x12,%xmm4,%zmm5,%zmm6{%k7}",},
+{{0xc4, 0xe3, 0x7d, 0x19, 0xe4, 0x05, }, 6, 0, "", "",
+"c4 e3 7d 19 e4 05    \tvextractf128 $0x5,%ymm4,%xmm4",},
+{{0x62, 0xf3, 0x7d, 0x4f, 0x19, 0xee, 0x12, }, 7, 0, "", "",
+"62 f3 7d 4f 19 ee 12 \tvextractf32x4 $0x12,%zmm5,%xmm6{%k7}",},
+{{0x62, 0xf3, 0xfd, 0x4f, 0x19, 0xee, 0x12, }, 7, 0, "", "",
+"62 f3 fd 4f 19 ee 12 \tvextractf64x2 $0x12,%zmm5,%xmm6{%k7}",},
+{{0x62, 0xf3, 0x4d, 0x4f, 0x1a, 0xfd, 0x12, }, 7, 0, "", "",
+"62 f3 4d 4f 1a fd 12 \tvinsertf32x8 $0x12,%ymm5,%zmm6,%zmm7{%k7}",},
+{{0x62, 0xf3, 0xcd, 0x4f, 0x1a, 0xfd, 0x12, }, 7, 0, "", "",
+"62 f3 cd 4f 1a fd 12 \tvinsertf64x4 $0x12,%ymm5,%zmm6,%zmm7{%k7}",},
+{{0x62, 0xf3, 0x7d, 0x4f, 0x1b, 0xf7, 0x12, }, 7, 0, "", "",
+"62 f3 7d 4f 1b f7 12 \tvextractf32x8 $0x12,%zmm6,%ymm7{%k7}",},
+{{0x62, 0xf3, 0xfd, 0x4f, 0x1b, 0xf7, 0x12, }, 7, 0, "", "",
+"62 f3 fd 4f 1b f7 12 \tvextractf64x4 $0x12,%zmm6,%ymm7{%k7}",},
+{{0x62, 0xf3, 0x45, 0x48, 0x1e, 0xee, 0x12, }, 7, 0, "", "",
+"62 f3 45 48 1e ee 12 \tvpcmpud $0x12,%zmm6,%zmm7,%k5",},
+{{0x62, 0xf3, 0xc5, 0x48, 0x1e, 0xee, 0x12, }, 7, 0, "", "",
+"62 f3 c5 48 1e ee 12 \tvpcmpuq $0x12,%zmm6,%zmm7,%k5",},
+{{0x62, 0xf3, 0x45, 0x48, 0x1f, 0xee, 0x12, }, 7, 0, "", "",
+"62 f3 45 48 1f ee 12 \tvpcmpd $0x12,%zmm6,%zmm7,%k5",},
+{{0x62, 0xf3, 0xc5, 0x48, 0x1f, 0xee, 0x12, }, 7, 0, "", "",
+"62 f3 c5 48 1f ee 12 \tvpcmpq $0x12,%zmm6,%zmm7,%k5",},
+{{0x62, 0xf3, 0x4d, 0x48, 0x23, 0xfd, 0x12, }, 7, 0, "", "",
+"62 f3 4d 48 23 fd 12 \tvshuff32x4 $0x12,%zmm5,%zmm6,%zmm7",},
+{{0x62, 0xf3, 0xcd, 0x48, 0x23, 0xfd, 0x12, }, 7, 0, "", "",
+"62 f3 cd 48 23 fd 12 \tvshuff64x2 $0x12,%zmm5,%zmm6,%zmm7",},
+{{0x62, 0xf3, 0x4d, 0x48, 0x25, 0xfd, 0x12, }, 7, 0, "", "",
+"62 f3 4d 48 25 fd 12 \tvpternlogd $0x12,%zmm5,%zmm6,%zmm7",},
+{{0x62, 0xf3, 0xcd, 0x48, 0x25, 0xfd, 0x12, }, 7, 0, "", "",
+"62 f3 cd 48 25 fd 12 \tvpternlogq $0x12,%zmm5,%zmm6,%zmm7",},
+{{0x62, 0xf3, 0x7d, 0x48, 0x26, 0xfe, 0x12, }, 7, 0, "", "",
+"62 f3 7d 48 26 fe 12 \tvgetmantps $0x12,%zmm6,%zmm7",},
+{{0x62, 0xf3, 0xfd, 0x48, 0x26, 0xfe, 0x12, }, 7, 0, "", "",
+"62 f3 fd 48 26 fe 12 \tvgetmantpd $0x12,%zmm6,%zmm7",},
+{{0x62, 0xf3, 0x4d, 0x0f, 0x27, 0xfd, 0x12, }, 7, 0, "", "",
+"62 f3 4d 0f 27 fd 12 \tvgetmantss $0x12,%xmm5,%xmm6,%xmm7{%k7}",},
+{{0x62, 0xf3, 0xcd, 0x0f, 0x27, 0xfd, 0x12, }, 7, 0, "", "",
+"62 f3 cd 0f 27 fd 12 \tvgetmantsd $0x12,%xmm5,%xmm6,%xmm7{%k7}",},
+{{0xc4, 0xe3, 0x5d, 0x38, 0xf4, 0x05, }, 6, 0, "", "",
+"c4 e3 5d 38 f4 05    \tvinserti128 $0x5,%xmm4,%ymm4,%ymm6",},
+{{0x62, 0xf3, 0x55, 0x4f, 0x38, 0xf4, 0x12, }, 7, 0, "", "",
+"62 f3 55 4f 38 f4 12 \tvinserti32x4 $0x12,%xmm4,%zmm5,%zmm6{%k7}",},
+{{0x62, 0xf3, 0xd5, 0x4f, 0x38, 0xf4, 0x12, }, 7, 0, "", "",
+"62 f3 d5 4f 38 f4 12 \tvinserti64x2 $0x12,%xmm4,%zmm5,%zmm6{%k7}",},
+{{0xc4, 0xe3, 0x7d, 0x39, 0xe6, 0x05, }, 6, 0, "", "",
+"c4 e3 7d 39 e6 05    \tvextracti128 $0x5,%ymm4,%xmm6",},
+{{0x62, 0xf3, 0x7d, 0x4f, 0x39, 0xee, 0x12, }, 7, 0, "", "",
+"62 f3 7d 4f 39 ee 12 \tvextracti32x4 $0x12,%zmm5,%xmm6{%k7}",},
+{{0x62, 0xf3, 0xfd, 0x4f, 0x39, 0xee, 0x12, }, 7, 0, "", "",
+"62 f3 fd 4f 39 ee 12 \tvextracti64x2 $0x12,%zmm5,%xmm6{%k7}",},
+{{0x62, 0xf3, 0x4d, 0x4f, 0x3a, 0xfd, 0x12, }, 7, 0, "", "",
+"62 f3 4d 4f 3a fd 12 \tvinserti32x8 $0x12,%ymm5,%zmm6,%zmm7{%k7}",},
+{{0x62, 0xf3, 0xcd, 0x4f, 0x3a, 0xfd, 0x12, }, 7, 0, "", "",
+"62 f3 cd 4f 3a fd 12 \tvinserti64x4 $0x12,%ymm5,%zmm6,%zmm7{%k7}",},
+{{0x62, 0xf3, 0x7d, 0x4f, 0x3b, 0xf7, 0x12, }, 7, 0, "", "",
+"62 f3 7d 4f 3b f7 12 \tvextracti32x8 $0x12,%zmm6,%ymm7{%k7}",},
+{{0x62, 0xf3, 0xfd, 0x4f, 0x3b, 0xf7, 0x12, }, 7, 0, "", "",
+"62 f3 fd 4f 3b f7 12 \tvextracti64x4 $0x12,%zmm6,%ymm7{%k7}",},
+{{0x62, 0xf3, 0x45, 0x48, 0x3e, 0xee, 0x12, }, 7, 0, "", "",
+"62 f3 45 48 3e ee 12 \tvpcmpub $0x12,%zmm6,%zmm7,%k5",},
+{{0x62, 0xf3, 0xc5, 0x48, 0x3e, 0xee, 0x12, }, 7, 0, "", "",
+"62 f3 c5 48 3e ee 12 \tvpcmpuw $0x12,%zmm6,%zmm7,%k5",},
+{{0x62, 0xf3, 0x45, 0x48, 0x3f, 0xee, 0x12, }, 7, 0, "", "",
+"62 f3 45 48 3f ee 12 \tvpcmpb $0x12,%zmm6,%zmm7,%k5",},
+{{0x62, 0xf3, 0xc5, 0x48, 0x3f, 0xee, 0x12, }, 7, 0, "", "",
+"62 f3 c5 48 3f ee 12 \tvpcmpw $0x12,%zmm6,%zmm7,%k5",},
+{{0xc4, 0xe3, 0x4d, 0x42, 0xd4, 0x05, }, 6, 0, "", "",
+"c4 e3 4d 42 d4 05    \tvmpsadbw $0x5,%ymm4,%ymm6,%ymm2",},
+{{0x62, 0xf3, 0x55, 0x48, 0x42, 0xf4, 0x12, }, 7, 0, "", "",
+"62 f3 55 48 42 f4 12 \tvdbpsadbw $0x12,%zmm4,%zmm5,%zmm6",},
+{{0x62, 0xf3, 0x4d, 0x48, 0x43, 0xfd, 0x12, }, 7, 0, "", "",
+"62 f3 4d 48 43 fd 12 \tvshufi32x4 $0x12,%zmm5,%zmm6,%zmm7",},
+{{0x62, 0xf3, 0xcd, 0x48, 0x43, 0xfd, 0x12, }, 7, 0, "", "",
+"62 f3 cd 48 43 fd 12 \tvshufi64x2 $0x12,%zmm5,%zmm6,%zmm7",},
+{{0x62, 0xf3, 0x4d, 0x48, 0x50, 0xfd, 0x12, }, 7, 0, "", "",
+"62 f3 4d 48 50 fd 12 \tvrangeps $0x12,%zmm5,%zmm6,%zmm7",},
+{{0x62, 0xf3, 0xcd, 0x48, 0x50, 0xfd, 0x12, }, 7, 0, "", "",
+"62 f3 cd 48 50 fd 12 \tvrangepd $0x12,%zmm5,%zmm6,%zmm7",},
+{{0x62, 0xf3, 0x4d, 0x08, 0x51, 0xfd, 0x12, }, 7, 0, "", "",
+"62 f3 4d 08 51 fd 12 \tvrangess $0x12,%xmm5,%xmm6,%xmm7",},
+{{0x62, 0xf3, 0xcd, 0x08, 0x51, 0xfd, 0x12, }, 7, 0, "", "",
+"62 f3 cd 08 51 fd 12 \tvrangesd $0x12,%xmm5,%xmm6,%xmm7",},
+{{0x62, 0xf3, 0x4d, 0x48, 0x54, 0xfd, 0x12, }, 7, 0, "", "",
+"62 f3 4d 48 54 fd 12 \tvfixupimmps $0x12,%zmm5,%zmm6,%zmm7",},
+{{0x62, 0xf3, 0xcd, 0x48, 0x54, 0xfd, 0x12, }, 7, 0, "", "",
+"62 f3 cd 48 54 fd 12 \tvfixupimmpd $0x12,%zmm5,%zmm6,%zmm7",},
+{{0x62, 0xf3, 0x4d, 0x0f, 0x55, 0xfd, 0x12, }, 7, 0, "", "",
+"62 f3 4d 0f 55 fd 12 \tvfixupimmss $0x12,%xmm5,%xmm6,%xmm7{%k7}",},
+{{0x62, 0xf3, 0xcd, 0x0f, 0x55, 0xfd, 0x12, }, 7, 0, "", "",
+"62 f3 cd 0f 55 fd 12 \tvfixupimmsd $0x12,%xmm5,%xmm6,%xmm7{%k7}",},
+{{0x62, 0xf3, 0x7d, 0x48, 0x56, 0xfe, 0x12, }, 7, 0, "", "",
+"62 f3 7d 48 56 fe 12 \tvreduceps $0x12,%zmm6,%zmm7",},
+{{0x62, 0xf3, 0xfd, 0x48, 0x56, 0xfe, 0x12, }, 7, 0, "", "",
+"62 f3 fd 48 56 fe 12 \tvreducepd $0x12,%zmm6,%zmm7",},
+{{0x62, 0xf3, 0x4d, 0x08, 0x57, 0xfd, 0x12, }, 7, 0, "", "",
+"62 f3 4d 08 57 fd 12 \tvreducess $0x12,%xmm5,%xmm6,%xmm7",},
+{{0x62, 0xf3, 0xcd, 0x08, 0x57, 0xfd, 0x12, }, 7, 0, "", "",
+"62 f3 cd 08 57 fd 12 \tvreducesd $0x12,%xmm5,%xmm6,%xmm7",},
+{{0x62, 0xf3, 0x7d, 0x48, 0x66, 0xef, 0x12, }, 7, 0, "", "",
+"62 f3 7d 48 66 ef 12 \tvfpclassps $0x12,%zmm7,%k5",},
+{{0x62, 0xf3, 0xfd, 0x48, 0x66, 0xef, 0x12, }, 7, 0, "", "",
+"62 f3 fd 48 66 ef 12 \tvfpclasspd $0x12,%zmm7,%k5",},
+{{0x62, 0xf3, 0x7d, 0x08, 0x67, 0xef, 0x12, }, 7, 0, "", "",
+"62 f3 7d 08 67 ef 12 \tvfpclassss $0x12,%xmm7,%k5",},
+{{0x62, 0xf3, 0xfd, 0x08, 0x67, 0xef, 0x12, }, 7, 0, "", "",
+"62 f3 fd 08 67 ef 12 \tvfpclasssd $0x12,%xmm7,%k5",},
+{{0x62, 0xf1, 0x4d, 0x48, 0x72, 0xc5, 0x12, }, 7, 0, "", "",
+"62 f1 4d 48 72 c5 12 \tvprord $0x12,%zmm5,%zmm6",},
+{{0x62, 0xf1, 0xcd, 0x48, 0x72, 0xc5, 0x12, }, 7, 0, "", "",
+"62 f1 cd 48 72 c5 12 \tvprorq $0x12,%zmm5,%zmm6",},
+{{0x62, 0xf1, 0x4d, 0x48, 0x72, 0xcd, 0x12, }, 7, 0, "", "",
+"62 f1 4d 48 72 cd 12 \tvprold $0x12,%zmm5,%zmm6",},
+{{0x62, 0xf1, 0xcd, 0x48, 0x72, 0xcd, 0x12, }, 7, 0, "", "",
+"62 f1 cd 48 72 cd 12 \tvprolq $0x12,%zmm5,%zmm6",},
+{{0x0f, 0x72, 0xe6, 0x02, }, 4, 0, "", "",
+"0f 72 e6 02          \tpsrad  $0x2,%mm6",},
+{{0xc5, 0xed, 0x72, 0xe6, 0x05, }, 5, 0, "", "",
+"c5 ed 72 e6 05       \tvpsrad $0x5,%ymm6,%ymm2",},
+{{0x62, 0xf1, 0x6d, 0x48, 0x72, 0xe6, 0x05, }, 7, 0, "", "",
+"62 f1 6d 48 72 e6 05 \tvpsrad $0x5,%zmm6,%zmm2",},
+{{0x62, 0xf1, 0xed, 0x48, 0x72, 0xe6, 0x05, }, 7, 0, "", "",
+"62 f1 ed 48 72 e6 05 \tvpsraq $0x5,%zmm6,%zmm2",},
+{{0x62, 0xf2, 0x7d, 0x49, 0xc6, 0x8c, 0xfd, 0x7b, 0x00, 0x00, 0x00, }, 11, 0, "", "",
+"62 f2 7d 49 c6 8c fd 7b 00 00 00 \tvgatherpf0dps 0x7b(%ebp,%zmm7,8){%k1}",},
+{{0x62, 0xf2, 0xfd, 0x49, 0xc6, 0x8c, 0xfd, 0x7b, 0x00, 0x00, 0x00, }, 11, 0, "", "",
+"62 f2 fd 49 c6 8c fd 7b 00 00 00 \tvgatherpf0dpd 0x7b(%ebp,%ymm7,8){%k1}",},
+{{0x62, 0xf2, 0x7d, 0x49, 0xc6, 0x94, 0xfd, 0x7b, 0x00, 0x00, 0x00, }, 11, 0, "", "",
+"62 f2 7d 49 c6 94 fd 7b 00 00 00 \tvgatherpf1dps 0x7b(%ebp,%zmm7,8){%k1}",},
+{{0x62, 0xf2, 0xfd, 0x49, 0xc6, 0x94, 0xfd, 0x7b, 0x00, 0x00, 0x00, }, 11, 0, "", "",
+"62 f2 fd 49 c6 94 fd 7b 00 00 00 \tvgatherpf1dpd 0x7b(%ebp,%ymm7,8){%k1}",},
+{{0x62, 0xf2, 0x7d, 0x49, 0xc6, 0xac, 0xfd, 0x7b, 0x00, 0x00, 0x00, }, 11, 0, "", "",
+"62 f2 7d 49 c6 ac fd 7b 00 00 00 \tvscatterpf0dps 0x7b(%ebp,%zmm7,8){%k1}",},
+{{0x62, 0xf2, 0xfd, 0x49, 0xc6, 0xac, 0xfd, 0x7b, 0x00, 0x00, 0x00, }, 11, 0, "", "",
+"62 f2 fd 49 c6 ac fd 7b 00 00 00 \tvscatterpf0dpd 0x7b(%ebp,%ymm7,8){%k1}",},
+{{0x62, 0xf2, 0x7d, 0x49, 0xc6, 0xb4, 0xfd, 0x7b, 0x00, 0x00, 0x00, }, 11, 0, "", "",
+"62 f2 7d 49 c6 b4 fd 7b 00 00 00 \tvscatterpf1dps 0x7b(%ebp,%zmm7,8){%k1}",},
+{{0x62, 0xf2, 0xfd, 0x49, 0xc6, 0xb4, 0xfd, 0x7b, 0x00, 0x00, 0x00, }, 11, 0, "", "",
+"62 f2 fd 49 c6 b4 fd 7b 00 00 00 \tvscatterpf1dpd 0x7b(%ebp,%ymm7,8){%k1}",},
+{{0x62, 0xf2, 0x7d, 0x49, 0xc7, 0x8c, 0xfd, 0x7b, 0x00, 0x00, 0x00, }, 11, 0, "", "",
+"62 f2 7d 49 c7 8c fd 7b 00 00 00 \tvgatherpf0qps 0x7b(%ebp,%zmm7,8){%k1}",},
+{{0x62, 0xf2, 0xfd, 0x49, 0xc7, 0x8c, 0xfd, 0x7b, 0x00, 0x00, 0x00, }, 11, 0, "", "",
+"62 f2 fd 49 c7 8c fd 7b 00 00 00 \tvgatherpf0qpd 0x7b(%ebp,%zmm7,8){%k1}",},
+{{0x62, 0xf2, 0x7d, 0x49, 0xc7, 0x94, 0xfd, 0x7b, 0x00, 0x00, 0x00, }, 11, 0, "", "",
+"62 f2 7d 49 c7 94 fd 7b 00 00 00 \tvgatherpf1qps 0x7b(%ebp,%zmm7,8){%k1}",},
+{{0x62, 0xf2, 0xfd, 0x49, 0xc7, 0x94, 0xfd, 0x7b, 0x00, 0x00, 0x00, }, 11, 0, "", "",
+"62 f2 fd 49 c7 94 fd 7b 00 00 00 \tvgatherpf1qpd 0x7b(%ebp,%zmm7,8){%k1}",},
+{{0x62, 0xf2, 0x7d, 0x49, 0xc7, 0xac, 0xfd, 0x7b, 0x00, 0x00, 0x00, }, 11, 0, "", "",
+"62 f2 7d 49 c7 ac fd 7b 00 00 00 \tvscatterpf0qps 0x7b(%ebp,%zmm7,8){%k1}",},
+{{0x62, 0xf2, 0xfd, 0x49, 0xc7, 0xac, 0xfd, 0x7b, 0x00, 0x00, 0x00, }, 11, 0, "", "",
+"62 f2 fd 49 c7 ac fd 7b 00 00 00 \tvscatterpf0qpd 0x7b(%ebp,%zmm7,8){%k1}",},
+{{0x62, 0xf2, 0x7d, 0x49, 0xc7, 0xb4, 0xfd, 0x7b, 0x00, 0x00, 0x00, }, 11, 0, "", "",
+"62 f2 7d 49 c7 b4 fd 7b 00 00 00 \tvscatterpf1qps 0x7b(%ebp,%zmm7,8){%k1}",},
+{{0x62, 0xf2, 0xfd, 0x49, 0xc7, 0xb4, 0xfd, 0x7b, 0x00, 0x00, 0x00, }, 11, 0, "", "",
+"62 f2 fd 49 c7 b4 fd 7b 00 00 00 \tvscatterpf1qpd 0x7b(%ebp,%zmm7,8){%k1}",},
+{{0x62, 0xf1, 0xd5, 0x48, 0x58, 0xf4, }, 6, 0, "", "",
+"62 f1 d5 48 58 f4    \tvaddpd %zmm4,%zmm5,%zmm6",},
+{{0x62, 0xf1, 0xd5, 0x4f, 0x58, 0xf4, }, 6, 0, "", "",
+"62 f1 d5 4f 58 f4    \tvaddpd %zmm4,%zmm5,%zmm6{%k7}",},
+{{0x62, 0xf1, 0xd5, 0xcf, 0x58, 0xf4, }, 6, 0, "", "",
+"62 f1 d5 cf 58 f4    \tvaddpd %zmm4,%zmm5,%zmm6{%k7}{z}",},
+{{0x62, 0xf1, 0xd5, 0x18, 0x58, 0xf4, }, 6, 0, "", "",
+"62 f1 d5 18 58 f4    \tvaddpd {rn-sae},%zmm4,%zmm5,%zmm6",},
+{{0x62, 0xf1, 0xd5, 0x58, 0x58, 0xf4, }, 6, 0, "", "",
+"62 f1 d5 58 58 f4    \tvaddpd {ru-sae},%zmm4,%zmm5,%zmm6",},
+{{0x62, 0xf1, 0xd5, 0x38, 0x58, 0xf4, }, 6, 0, "", "",
+"62 f1 d5 38 58 f4    \tvaddpd {rd-sae},%zmm4,%zmm5,%zmm6",},
+{{0x62, 0xf1, 0xd5, 0x78, 0x58, 0xf4, }, 6, 0, "", "",
+"62 f1 d5 78 58 f4    \tvaddpd {rz-sae},%zmm4,%zmm5,%zmm6",},
+{{0x62, 0xf1, 0xd5, 0x48, 0x58, 0x31, }, 6, 0, "", "",
+"62 f1 d5 48 58 31    \tvaddpd (%ecx),%zmm5,%zmm6",},
+{{0x62, 0xf1, 0xd5, 0x48, 0x58, 0xb4, 0xc8, 0x23, 0x01, 0x00, 0x00, }, 11, 0, "", "",
+"62 f1 d5 48 58 b4 c8 23 01 00 00 \tvaddpd 0x123(%eax,%ecx,8),%zmm5,%zmm6",},
+{{0x62, 0xf1, 0xd5, 0x58, 0x58, 0x31, }, 6, 0, "", "",
+"62 f1 d5 58 58 31    \tvaddpd (%ecx){1to8},%zmm5,%zmm6",},
+{{0x62, 0xf1, 0xd5, 0x48, 0x58, 0x72, 0x7f, }, 7, 0, "", "",
+"62 f1 d5 48 58 72 7f \tvaddpd 0x1fc0(%edx),%zmm5,%zmm6",},
+{{0x62, 0xf1, 0xd5, 0x58, 0x58, 0x72, 0x7f, }, 7, 0, "", "",
+"62 f1 d5 58 58 72 7f \tvaddpd 0x3f8(%edx){1to8},%zmm5,%zmm6",},
+{{0x62, 0xf1, 0x4c, 0x58, 0xc2, 0x6a, 0x7f, 0x08, }, 8, 0, "", "",
+"62 f1 4c 58 c2 6a 7f 08 \tvcmpeq_uqps 0x1fc(%edx){1to16},%zmm6,%k5",},
+{{0x62, 0xf1, 0xe7, 0x0f, 0xc2, 0xac, 0xc8, 0x23, 0x01, 0x00, 0x00, 0x01, }, 12, 0, "", "",
+"62 f1 e7 0f c2 ac c8 23 01 00 00 01 \tvcmpltsd 0x123(%eax,%ecx,8),%xmm3,%k5{%k7}",},
+{{0x62, 0xf1, 0xd7, 0x1f, 0xc2, 0xec, 0x02, }, 7, 0, "", "",
+"62 f1 d7 1f c2 ec 02 \tvcmplesd {sae},%xmm4,%xmm5,%k5{%k7}",},
+{{0x62, 0xf3, 0x5d, 0x0f, 0x27, 0xac, 0xc8, 0x23, 0x01, 0x00, 0x00, 0x5b, }, 12, 0, "", "",
+"62 f3 5d 0f 27 ac c8 23 01 00 00 5b \tvgetmantss $0x5b,0x123(%eax,%ecx,8),%xmm4,%xmm5{%k7}",},
 {{0xf3, 0x0f, 0x1b, 0x00, }, 4, 0, "", "",
 "f3 0f 1b 00          \tbndmk  (%eax),%bnd0",},
 {{0xf3, 0x0f, 0x1b, 0x05, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
@@ -309,19 +1319,19 @@
 {{0x0f, 0x1b, 0x84, 0x08, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
 "0f 1b 84 08 78 56 34 12 \tbndstx %bnd0,0x12345678(%eax,%ecx,1)",},
 {{0xf2, 0xe8, 0xfc, 0xff, 0xff, 0xff, }, 6, 0xfffffffc, "call", "unconditional",
-"f2 e8 fc ff ff ff    \tbnd call 3c3 <main+0x3c3>",},
+"f2 e8 fc ff ff ff    \tbnd call fce <main+0xfce>",},
 {{0xf2, 0xff, 0x10, }, 3, 0, "call", "indirect",
 "f2 ff 10             \tbnd call *(%eax)",},
 {{0xf2, 0xc3, }, 2, 0, "ret", "indirect",
 "f2 c3                \tbnd ret ",},
 {{0xf2, 0xe9, 0xfc, 0xff, 0xff, 0xff, }, 6, 0xfffffffc, "jmp", "unconditional",
-"f2 e9 fc ff ff ff    \tbnd jmp 3ce <main+0x3ce>",},
+"f2 e9 fc ff ff ff    \tbnd jmp fd9 <main+0xfd9>",},
 {{0xf2, 0xe9, 0xfc, 0xff, 0xff, 0xff, }, 6, 0xfffffffc, "jmp", "unconditional",
-"f2 e9 fc ff ff ff    \tbnd jmp 3d4 <main+0x3d4>",},
+"f2 e9 fc ff ff ff    \tbnd jmp fdf <main+0xfdf>",},
 {{0xf2, 0xff, 0x21, }, 3, 0, "jmp", "indirect",
 "f2 ff 21             \tbnd jmp *(%ecx)",},
 {{0xf2, 0x0f, 0x85, 0xfc, 0xff, 0xff, 0xff, }, 7, 0xfffffffc, "jcc", "conditional",
-"f2 0f 85 fc ff ff ff \tbnd jne 3de <main+0x3de>",},
+"f2 0f 85 fc ff ff ff \tbnd jne fe9 <main+0xfe9>",},
 {{0x0f, 0x3a, 0xcc, 0xc1, 0x00, }, 5, 0, "", "",
 "0f 3a cc c1 00       \tsha1rnds4 $0x0,%xmm1,%xmm0",},
 {{0x0f, 0x3a, 0xcc, 0xd7, 0x91, }, 5, 0, "", "",
--- zfcpdump-kernel-4.4.orig/tools/perf/arch/x86/tests/insn-x86-dat-64.c
+++ zfcpdump-kernel-4.4/tools/perf/arch/x86/tests/insn-x86-dat-64.c
@@ -6,6 +6,938 @@
 
 {{0x0f, 0x31, }, 2, 0, "", "",
 "0f 31                \trdtsc  ",},
+{{0xc4, 0xe2, 0x7d, 0x13, 0xeb, }, 5, 0, "", "",
+"c4 e2 7d 13 eb       \tvcvtph2ps %xmm3,%ymm5",},
+{{0x48, 0x0f, 0x41, 0xd8, }, 4, 0, "", "",
+"48 0f 41 d8          \tcmovno %rax,%rbx",},
+{{0x48, 0x0f, 0x41, 0x88, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
+"48 0f 41 88 78 56 34 12 \tcmovno 0x12345678(%rax),%rcx",},
+{{0x66, 0x0f, 0x41, 0x88, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
+"66 0f 41 88 78 56 34 12 \tcmovno 0x12345678(%rax),%cx",},
+{{0x48, 0x0f, 0x44, 0xd8, }, 4, 0, "", "",
+"48 0f 44 d8          \tcmove  %rax,%rbx",},
+{{0x48, 0x0f, 0x44, 0x88, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
+"48 0f 44 88 78 56 34 12 \tcmove  0x12345678(%rax),%rcx",},
+{{0x66, 0x0f, 0x44, 0x88, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
+"66 0f 44 88 78 56 34 12 \tcmove  0x12345678(%rax),%cx",},
+{{0x0f, 0x90, 0x80, 0x78, 0x56, 0x34, 0x12, }, 7, 0, "", "",
+"0f 90 80 78 56 34 12 \tseto   0x12345678(%rax)",},
+{{0x0f, 0x91, 0x80, 0x78, 0x56, 0x34, 0x12, }, 7, 0, "", "",
+"0f 91 80 78 56 34 12 \tsetno  0x12345678(%rax)",},
+{{0x0f, 0x92, 0x80, 0x78, 0x56, 0x34, 0x12, }, 7, 0, "", "",
+"0f 92 80 78 56 34 12 \tsetb   0x12345678(%rax)",},
+{{0x0f, 0x92, 0x80, 0x78, 0x56, 0x34, 0x12, }, 7, 0, "", "",
+"0f 92 80 78 56 34 12 \tsetb   0x12345678(%rax)",},
+{{0x0f, 0x92, 0x80, 0x78, 0x56, 0x34, 0x12, }, 7, 0, "", "",
+"0f 92 80 78 56 34 12 \tsetb   0x12345678(%rax)",},
+{{0x0f, 0x93, 0x80, 0x78, 0x56, 0x34, 0x12, }, 7, 0, "", "",
+"0f 93 80 78 56 34 12 \tsetae  0x12345678(%rax)",},
+{{0x0f, 0x93, 0x80, 0x78, 0x56, 0x34, 0x12, }, 7, 0, "", "",
+"0f 93 80 78 56 34 12 \tsetae  0x12345678(%rax)",},
+{{0x0f, 0x93, 0x80, 0x78, 0x56, 0x34, 0x12, }, 7, 0, "", "",
+"0f 93 80 78 56 34 12 \tsetae  0x12345678(%rax)",},
+{{0x0f, 0x98, 0x80, 0x78, 0x56, 0x34, 0x12, }, 7, 0, "", "",
+"0f 98 80 78 56 34 12 \tsets   0x12345678(%rax)",},
+{{0x0f, 0x99, 0x80, 0x78, 0x56, 0x34, 0x12, }, 7, 0, "", "",
+"0f 99 80 78 56 34 12 \tsetns  0x12345678(%rax)",},
+{{0xc5, 0xcc, 0x41, 0xef, }, 4, 0, "", "",
+"c5 cc 41 ef          \tkandw  %k7,%k6,%k5",},
+{{0xc4, 0xe1, 0xcc, 0x41, 0xef, }, 5, 0, "", "",
+"c4 e1 cc 41 ef       \tkandq  %k7,%k6,%k5",},
+{{0xc5, 0xcd, 0x41, 0xef, }, 4, 0, "", "",
+"c5 cd 41 ef          \tkandb  %k7,%k6,%k5",},
+{{0xc4, 0xe1, 0xcd, 0x41, 0xef, }, 5, 0, "", "",
+"c4 e1 cd 41 ef       \tkandd  %k7,%k6,%k5",},
+{{0xc5, 0xcc, 0x42, 0xef, }, 4, 0, "", "",
+"c5 cc 42 ef          \tkandnw %k7,%k6,%k5",},
+{{0xc4, 0xe1, 0xcc, 0x42, 0xef, }, 5, 0, "", "",
+"c4 e1 cc 42 ef       \tkandnq %k7,%k6,%k5",},
+{{0xc5, 0xcd, 0x42, 0xef, }, 4, 0, "", "",
+"c5 cd 42 ef          \tkandnb %k7,%k6,%k5",},
+{{0xc4, 0xe1, 0xcd, 0x42, 0xef, }, 5, 0, "", "",
+"c4 e1 cd 42 ef       \tkandnd %k7,%k6,%k5",},
+{{0xc5, 0xf8, 0x44, 0xf7, }, 4, 0, "", "",
+"c5 f8 44 f7          \tknotw  %k7,%k6",},
+{{0xc4, 0xe1, 0xf8, 0x44, 0xf7, }, 5, 0, "", "",
+"c4 e1 f8 44 f7       \tknotq  %k7,%k6",},
+{{0xc5, 0xf9, 0x44, 0xf7, }, 4, 0, "", "",
+"c5 f9 44 f7          \tknotb  %k7,%k6",},
+{{0xc4, 0xe1, 0xf9, 0x44, 0xf7, }, 5, 0, "", "",
+"c4 e1 f9 44 f7       \tknotd  %k7,%k6",},
+{{0xc5, 0xcc, 0x45, 0xef, }, 4, 0, "", "",
+"c5 cc 45 ef          \tkorw   %k7,%k6,%k5",},
+{{0xc4, 0xe1, 0xcc, 0x45, 0xef, }, 5, 0, "", "",
+"c4 e1 cc 45 ef       \tkorq   %k7,%k6,%k5",},
+{{0xc5, 0xcd, 0x45, 0xef, }, 4, 0, "", "",
+"c5 cd 45 ef          \tkorb   %k7,%k6,%k5",},
+{{0xc4, 0xe1, 0xcd, 0x45, 0xef, }, 5, 0, "", "",
+"c4 e1 cd 45 ef       \tkord   %k7,%k6,%k5",},
+{{0xc5, 0xcc, 0x46, 0xef, }, 4, 0, "", "",
+"c5 cc 46 ef          \tkxnorw %k7,%k6,%k5",},
+{{0xc4, 0xe1, 0xcc, 0x46, 0xef, }, 5, 0, "", "",
+"c4 e1 cc 46 ef       \tkxnorq %k7,%k6,%k5",},
+{{0xc5, 0xcd, 0x46, 0xef, }, 4, 0, "", "",
+"c5 cd 46 ef          \tkxnorb %k7,%k6,%k5",},
+{{0xc4, 0xe1, 0xcd, 0x46, 0xef, }, 5, 0, "", "",
+"c4 e1 cd 46 ef       \tkxnord %k7,%k6,%k5",},
+{{0xc5, 0xcc, 0x47, 0xef, }, 4, 0, "", "",
+"c5 cc 47 ef          \tkxorw  %k7,%k6,%k5",},
+{{0xc4, 0xe1, 0xcc, 0x47, 0xef, }, 5, 0, "", "",
+"c4 e1 cc 47 ef       \tkxorq  %k7,%k6,%k5",},
+{{0xc5, 0xcd, 0x47, 0xef, }, 4, 0, "", "",
+"c5 cd 47 ef          \tkxorb  %k7,%k6,%k5",},
+{{0xc4, 0xe1, 0xcd, 0x47, 0xef, }, 5, 0, "", "",
+"c4 e1 cd 47 ef       \tkxord  %k7,%k6,%k5",},
+{{0xc5, 0xcc, 0x4a, 0xef, }, 4, 0, "", "",
+"c5 cc 4a ef          \tkaddw  %k7,%k6,%k5",},
+{{0xc4, 0xe1, 0xcc, 0x4a, 0xef, }, 5, 0, "", "",
+"c4 e1 cc 4a ef       \tkaddq  %k7,%k6,%k5",},
+{{0xc5, 0xcd, 0x4a, 0xef, }, 4, 0, "", "",
+"c5 cd 4a ef          \tkaddb  %k7,%k6,%k5",},
+{{0xc4, 0xe1, 0xcd, 0x4a, 0xef, }, 5, 0, "", "",
+"c4 e1 cd 4a ef       \tkaddd  %k7,%k6,%k5",},
+{{0xc5, 0xcd, 0x4b, 0xef, }, 4, 0, "", "",
+"c5 cd 4b ef          \tkunpckbw %k7,%k6,%k5",},
+{{0xc5, 0xcc, 0x4b, 0xef, }, 4, 0, "", "",
+"c5 cc 4b ef          \tkunpckwd %k7,%k6,%k5",},
+{{0xc4, 0xe1, 0xcc, 0x4b, 0xef, }, 5, 0, "", "",
+"c4 e1 cc 4b ef       \tkunpckdq %k7,%k6,%k5",},
+{{0xc5, 0xf8, 0x90, 0xee, }, 4, 0, "", "",
+"c5 f8 90 ee          \tkmovw  %k6,%k5",},
+{{0xc5, 0xf8, 0x90, 0x29, }, 4, 0, "", "",
+"c5 f8 90 29          \tkmovw  (%rcx),%k5",},
+{{0xc4, 0xa1, 0x78, 0x90, 0xac, 0xf0, 0x23, 0x01, 0x00, 0x00, }, 10, 0, "", "",
+"c4 a1 78 90 ac f0 23 01 00 00 \tkmovw  0x123(%rax,%r14,8),%k5",},
+{{0xc5, 0xf8, 0x91, 0x29, }, 4, 0, "", "",
+"c5 f8 91 29          \tkmovw  %k5,(%rcx)",},
+{{0xc4, 0xa1, 0x78, 0x91, 0xac, 0xf0, 0x23, 0x01, 0x00, 0x00, }, 10, 0, "", "",
+"c4 a1 78 91 ac f0 23 01 00 00 \tkmovw  %k5,0x123(%rax,%r14,8)",},
+{{0xc5, 0xf8, 0x92, 0xe8, }, 4, 0, "", "",
+"c5 f8 92 e8          \tkmovw  %eax,%k5",},
+{{0xc5, 0xf8, 0x92, 0xed, }, 4, 0, "", "",
+"c5 f8 92 ed          \tkmovw  %ebp,%k5",},
+{{0xc4, 0xc1, 0x78, 0x92, 0xed, }, 5, 0, "", "",
+"c4 c1 78 92 ed       \tkmovw  %r13d,%k5",},
+{{0xc5, 0xf8, 0x93, 0xc5, }, 4, 0, "", "",
+"c5 f8 93 c5          \tkmovw  %k5,%eax",},
+{{0xc5, 0xf8, 0x93, 0xed, }, 4, 0, "", "",
+"c5 f8 93 ed          \tkmovw  %k5,%ebp",},
+{{0xc5, 0x78, 0x93, 0xed, }, 4, 0, "", "",
+"c5 78 93 ed          \tkmovw  %k5,%r13d",},
+{{0xc4, 0xe1, 0xf8, 0x90, 0xee, }, 5, 0, "", "",
+"c4 e1 f8 90 ee       \tkmovq  %k6,%k5",},
+{{0xc4, 0xe1, 0xf8, 0x90, 0x29, }, 5, 0, "", "",
+"c4 e1 f8 90 29       \tkmovq  (%rcx),%k5",},
+{{0xc4, 0xa1, 0xf8, 0x90, 0xac, 0xf0, 0x23, 0x01, 0x00, 0x00, }, 10, 0, "", "",
+"c4 a1 f8 90 ac f0 23 01 00 00 \tkmovq  0x123(%rax,%r14,8),%k5",},
+{{0xc4, 0xe1, 0xf8, 0x91, 0x29, }, 5, 0, "", "",
+"c4 e1 f8 91 29       \tkmovq  %k5,(%rcx)",},
+{{0xc4, 0xa1, 0xf8, 0x91, 0xac, 0xf0, 0x23, 0x01, 0x00, 0x00, }, 10, 0, "", "",
+"c4 a1 f8 91 ac f0 23 01 00 00 \tkmovq  %k5,0x123(%rax,%r14,8)",},
+{{0xc4, 0xe1, 0xfb, 0x92, 0xe8, }, 5, 0, "", "",
+"c4 e1 fb 92 e8       \tkmovq  %rax,%k5",},
+{{0xc4, 0xe1, 0xfb, 0x92, 0xed, }, 5, 0, "", "",
+"c4 e1 fb 92 ed       \tkmovq  %rbp,%k5",},
+{{0xc4, 0xc1, 0xfb, 0x92, 0xed, }, 5, 0, "", "",
+"c4 c1 fb 92 ed       \tkmovq  %r13,%k5",},
+{{0xc4, 0xe1, 0xfb, 0x93, 0xc5, }, 5, 0, "", "",
+"c4 e1 fb 93 c5       \tkmovq  %k5,%rax",},
+{{0xc4, 0xe1, 0xfb, 0x93, 0xed, }, 5, 0, "", "",
+"c4 e1 fb 93 ed       \tkmovq  %k5,%rbp",},
+{{0xc4, 0x61, 0xfb, 0x93, 0xed, }, 5, 0, "", "",
+"c4 61 fb 93 ed       \tkmovq  %k5,%r13",},
+{{0xc5, 0xf9, 0x90, 0xee, }, 4, 0, "", "",
+"c5 f9 90 ee          \tkmovb  %k6,%k5",},
+{{0xc5, 0xf9, 0x90, 0x29, }, 4, 0, "", "",
+"c5 f9 90 29          \tkmovb  (%rcx),%k5",},
+{{0xc4, 0xa1, 0x79, 0x90, 0xac, 0xf0, 0x23, 0x01, 0x00, 0x00, }, 10, 0, "", "",
+"c4 a1 79 90 ac f0 23 01 00 00 \tkmovb  0x123(%rax,%r14,8),%k5",},
+{{0xc5, 0xf9, 0x91, 0x29, }, 4, 0, "", "",
+"c5 f9 91 29          \tkmovb  %k5,(%rcx)",},
+{{0xc4, 0xa1, 0x79, 0x91, 0xac, 0xf0, 0x23, 0x01, 0x00, 0x00, }, 10, 0, "", "",
+"c4 a1 79 91 ac f0 23 01 00 00 \tkmovb  %k5,0x123(%rax,%r14,8)",},
+{{0xc5, 0xf9, 0x92, 0xe8, }, 4, 0, "", "",
+"c5 f9 92 e8          \tkmovb  %eax,%k5",},
+{{0xc5, 0xf9, 0x92, 0xed, }, 4, 0, "", "",
+"c5 f9 92 ed          \tkmovb  %ebp,%k5",},
+{{0xc4, 0xc1, 0x79, 0x92, 0xed, }, 5, 0, "", "",
+"c4 c1 79 92 ed       \tkmovb  %r13d,%k5",},
+{{0xc5, 0xf9, 0x93, 0xc5, }, 4, 0, "", "",
+"c5 f9 93 c5          \tkmovb  %k5,%eax",},
+{{0xc5, 0xf9, 0x93, 0xed, }, 4, 0, "", "",
+"c5 f9 93 ed          \tkmovb  %k5,%ebp",},
+{{0xc5, 0x79, 0x93, 0xed, }, 4, 0, "", "",
+"c5 79 93 ed          \tkmovb  %k5,%r13d",},
+{{0xc4, 0xe1, 0xf9, 0x90, 0xee, }, 5, 0, "", "",
+"c4 e1 f9 90 ee       \tkmovd  %k6,%k5",},
+{{0xc4, 0xe1, 0xf9, 0x90, 0x29, }, 5, 0, "", "",
+"c4 e1 f9 90 29       \tkmovd  (%rcx),%k5",},
+{{0xc4, 0xa1, 0xf9, 0x90, 0xac, 0xf0, 0x23, 0x01, 0x00, 0x00, }, 10, 0, "", "",
+"c4 a1 f9 90 ac f0 23 01 00 00 \tkmovd  0x123(%rax,%r14,8),%k5",},
+{{0xc4, 0xe1, 0xf9, 0x91, 0x29, }, 5, 0, "", "",
+"c4 e1 f9 91 29       \tkmovd  %k5,(%rcx)",},
+{{0xc4, 0xa1, 0xf9, 0x91, 0xac, 0xf0, 0x23, 0x01, 0x00, 0x00, }, 10, 0, "", "",
+"c4 a1 f9 91 ac f0 23 01 00 00 \tkmovd  %k5,0x123(%rax,%r14,8)",},
+{{0xc5, 0xfb, 0x92, 0xe8, }, 4, 0, "", "",
+"c5 fb 92 e8          \tkmovd  %eax,%k5",},
+{{0xc5, 0xfb, 0x92, 0xed, }, 4, 0, "", "",
+"c5 fb 92 ed          \tkmovd  %ebp,%k5",},
+{{0xc4, 0xc1, 0x7b, 0x92, 0xed, }, 5, 0, "", "",
+"c4 c1 7b 92 ed       \tkmovd  %r13d,%k5",},
+{{0xc5, 0xfb, 0x93, 0xc5, }, 4, 0, "", "",
+"c5 fb 93 c5          \tkmovd  %k5,%eax",},
+{{0xc5, 0xfb, 0x93, 0xed, }, 4, 0, "", "",
+"c5 fb 93 ed          \tkmovd  %k5,%ebp",},
+{{0xc5, 0x7b, 0x93, 0xed, }, 4, 0, "", "",
+"c5 7b 93 ed          \tkmovd  %k5,%r13d",},
+{{0xc5, 0xf8, 0x98, 0xee, }, 4, 0, "", "",
+"c5 f8 98 ee          \tkortestw %k6,%k5",},
+{{0xc4, 0xe1, 0xf8, 0x98, 0xee, }, 5, 0, "", "",
+"c4 e1 f8 98 ee       \tkortestq %k6,%k5",},
+{{0xc5, 0xf9, 0x98, 0xee, }, 4, 0, "", "",
+"c5 f9 98 ee          \tkortestb %k6,%k5",},
+{{0xc4, 0xe1, 0xf9, 0x98, 0xee, }, 5, 0, "", "",
+"c4 e1 f9 98 ee       \tkortestd %k6,%k5",},
+{{0xc5, 0xf8, 0x99, 0xee, }, 4, 0, "", "",
+"c5 f8 99 ee          \tktestw %k6,%k5",},
+{{0xc4, 0xe1, 0xf8, 0x99, 0xee, }, 5, 0, "", "",
+"c4 e1 f8 99 ee       \tktestq %k6,%k5",},
+{{0xc5, 0xf9, 0x99, 0xee, }, 4, 0, "", "",
+"c5 f9 99 ee          \tktestb %k6,%k5",},
+{{0xc4, 0xe1, 0xf9, 0x99, 0xee, }, 5, 0, "", "",
+"c4 e1 f9 99 ee       \tktestd %k6,%k5",},
+{{0xc4, 0xe3, 0xf9, 0x30, 0xee, 0x12, }, 6, 0, "", "",
+"c4 e3 f9 30 ee 12    \tkshiftrw $0x12,%k6,%k5",},
+{{0xc4, 0xe3, 0xf9, 0x31, 0xee, 0x5b, }, 6, 0, "", "",
+"c4 e3 f9 31 ee 5b    \tkshiftrq $0x5b,%k6,%k5",},
+{{0xc4, 0xe3, 0xf9, 0x32, 0xee, 0x12, }, 6, 0, "", "",
+"c4 e3 f9 32 ee 12    \tkshiftlw $0x12,%k6,%k5",},
+{{0xc4, 0xe3, 0xf9, 0x33, 0xee, 0x5b, }, 6, 0, "", "",
+"c4 e3 f9 33 ee 5b    \tkshiftlq $0x5b,%k6,%k5",},
+{{0xc5, 0xf8, 0x5b, 0xf5, }, 4, 0, "", "",
+"c5 f8 5b f5          \tvcvtdq2ps %xmm5,%xmm6",},
+{{0x62, 0x91, 0xfc, 0x4f, 0x5b, 0xf5, }, 6, 0, "", "",
+"62 91 fc 4f 5b f5    \tvcvtqq2ps %zmm29,%ymm6{%k7}",},
+{{0xc5, 0xf9, 0x5b, 0xf5, }, 4, 0, "", "",
+"c5 f9 5b f5          \tvcvtps2dq %xmm5,%xmm6",},
+{{0xc5, 0xfa, 0x5b, 0xf5, }, 4, 0, "", "",
+"c5 fa 5b f5          \tvcvttps2dq %xmm5,%xmm6",},
+{{0x0f, 0x6f, 0xe0, }, 3, 0, "", "",
+"0f 6f e0             \tmovq   %mm0,%mm4",},
+{{0xc5, 0xfd, 0x6f, 0xf4, }, 4, 0, "", "",
+"c5 fd 6f f4          \tvmovdqa %ymm4,%ymm6",},
+{{0x62, 0x01, 0x7d, 0x48, 0x6f, 0xd1, }, 6, 0, "", "",
+"62 01 7d 48 6f d1    \tvmovdqa32 %zmm25,%zmm26",},
+{{0x62, 0x01, 0xfd, 0x48, 0x6f, 0xd1, }, 6, 0, "", "",
+"62 01 fd 48 6f d1    \tvmovdqa64 %zmm25,%zmm26",},
+{{0xc5, 0xfe, 0x6f, 0xf4, }, 4, 0, "", "",
+"c5 fe 6f f4          \tvmovdqu %ymm4,%ymm6",},
+{{0x62, 0x01, 0x7e, 0x48, 0x6f, 0xf5, }, 6, 0, "", "",
+"62 01 7e 48 6f f5    \tvmovdqu32 %zmm29,%zmm30",},
+{{0x62, 0x01, 0xfe, 0x48, 0x6f, 0xd1, }, 6, 0, "", "",
+"62 01 fe 48 6f d1    \tvmovdqu64 %zmm25,%zmm26",},
+{{0x62, 0x01, 0x7f, 0x48, 0x6f, 0xf5, }, 6, 0, "", "",
+"62 01 7f 48 6f f5    \tvmovdqu8 %zmm29,%zmm30",},
+{{0x62, 0x01, 0xff, 0x48, 0x6f, 0xd1, }, 6, 0, "", "",
+"62 01 ff 48 6f d1    \tvmovdqu16 %zmm25,%zmm26",},
+{{0x0f, 0x78, 0xc3, }, 3, 0, "", "",
+"0f 78 c3             \tvmread %rax,%rbx",},
+{{0x62, 0x01, 0x7c, 0x48, 0x78, 0xd1, }, 6, 0, "", "",
+"62 01 7c 48 78 d1    \tvcvttps2udq %zmm25,%zmm26",},
+{{0x62, 0x91, 0xfc, 0x4f, 0x78, 0xf5, }, 6, 0, "", "",
+"62 91 fc 4f 78 f5    \tvcvttpd2udq %zmm29,%ymm6{%k7}",},
+{{0x62, 0xf1, 0xff, 0x08, 0x78, 0xc6, }, 6, 0, "", "",
+"62 f1 ff 08 78 c6    \tvcvttsd2usi %xmm6,%rax",},
+{{0x62, 0xf1, 0xfe, 0x08, 0x78, 0xc6, }, 6, 0, "", "",
+"62 f1 fe 08 78 c6    \tvcvttss2usi %xmm6,%rax",},
+{{0x62, 0x61, 0x7d, 0x4f, 0x78, 0xd5, }, 6, 0, "", "",
+"62 61 7d 4f 78 d5    \tvcvttps2uqq %ymm5,%zmm26{%k7}",},
+{{0x62, 0x01, 0xfd, 0x48, 0x78, 0xf5, }, 6, 0, "", "",
+"62 01 fd 48 78 f5    \tvcvttpd2uqq %zmm29,%zmm30",},
+{{0x0f, 0x79, 0xd8, }, 3, 0, "", "",
+"0f 79 d8             \tvmwrite %rax,%rbx",},
+{{0x62, 0x01, 0x7c, 0x48, 0x79, 0xd1, }, 6, 0, "", "",
+"62 01 7c 48 79 d1    \tvcvtps2udq %zmm25,%zmm26",},
+{{0x62, 0x91, 0xfc, 0x4f, 0x79, 0xf5, }, 6, 0, "", "",
+"62 91 fc 4f 79 f5    \tvcvtpd2udq %zmm29,%ymm6{%k7}",},
+{{0x62, 0xf1, 0xff, 0x08, 0x79, 0xc6, }, 6, 0, "", "",
+"62 f1 ff 08 79 c6    \tvcvtsd2usi %xmm6,%rax",},
+{{0x62, 0xf1, 0xfe, 0x08, 0x79, 0xc6, }, 6, 0, "", "",
+"62 f1 fe 08 79 c6    \tvcvtss2usi %xmm6,%rax",},
+{{0x62, 0x61, 0x7d, 0x4f, 0x79, 0xd5, }, 6, 0, "", "",
+"62 61 7d 4f 79 d5    \tvcvtps2uqq %ymm5,%zmm26{%k7}",},
+{{0x62, 0x01, 0xfd, 0x48, 0x79, 0xf5, }, 6, 0, "", "",
+"62 01 fd 48 79 f5    \tvcvtpd2uqq %zmm29,%zmm30",},
+{{0x62, 0x61, 0x7e, 0x4f, 0x7a, 0xed, }, 6, 0, "", "",
+"62 61 7e 4f 7a ed    \tvcvtudq2pd %ymm5,%zmm29{%k7}",},
+{{0x62, 0x01, 0xfe, 0x48, 0x7a, 0xd1, }, 6, 0, "", "",
+"62 01 fe 48 7a d1    \tvcvtuqq2pd %zmm25,%zmm26",},
+{{0x62, 0x01, 0x7f, 0x48, 0x7a, 0xf5, }, 6, 0, "", "",
+"62 01 7f 48 7a f5    \tvcvtudq2ps %zmm29,%zmm30",},
+{{0x62, 0x01, 0xff, 0x4f, 0x7a, 0xd1, }, 6, 0, "", "",
+"62 01 ff 4f 7a d1    \tvcvtuqq2ps %zmm25,%ymm26{%k7}",},
+{{0x62, 0x01, 0x7d, 0x4f, 0x7a, 0xd1, }, 6, 0, "", "",
+"62 01 7d 4f 7a d1    \tvcvttps2qq %ymm25,%zmm26{%k7}",},
+{{0x62, 0x01, 0xfd, 0x48, 0x7a, 0xf5, }, 6, 0, "", "",
+"62 01 fd 48 7a f5    \tvcvttpd2qq %zmm29,%zmm30",},
+{{0x62, 0xf1, 0x57, 0x08, 0x7b, 0xf0, }, 6, 0, "", "",
+"62 f1 57 08 7b f0    \tvcvtusi2sd %eax,%xmm5,%xmm6",},
+{{0x62, 0xf1, 0x56, 0x08, 0x7b, 0xf0, }, 6, 0, "", "",
+"62 f1 56 08 7b f0    \tvcvtusi2ss %eax,%xmm5,%xmm6",},
+{{0x62, 0x61, 0x7d, 0x4f, 0x7b, 0xd5, }, 6, 0, "", "",
+"62 61 7d 4f 7b d5    \tvcvtps2qq %ymm5,%zmm26{%k7}",},
+{{0x62, 0x01, 0xfd, 0x48, 0x7b, 0xf5, }, 6, 0, "", "",
+"62 01 fd 48 7b f5    \tvcvtpd2qq %zmm29,%zmm30",},
+{{0x0f, 0x7f, 0xc4, }, 3, 0, "", "",
+"0f 7f c4             \tmovq   %mm0,%mm4",},
+{{0xc5, 0x7d, 0x7f, 0xc6, }, 4, 0, "", "",
+"c5 7d 7f c6          \tvmovdqa %ymm8,%ymm6",},
+{{0x62, 0x01, 0x7d, 0x48, 0x7f, 0xca, }, 6, 0, "", "",
+"62 01 7d 48 7f ca    \tvmovdqa32 %zmm25,%zmm26",},
+{{0x62, 0x01, 0xfd, 0x48, 0x7f, 0xca, }, 6, 0, "", "",
+"62 01 fd 48 7f ca    \tvmovdqa64 %zmm25,%zmm26",},
+{{0xc5, 0x7e, 0x7f, 0xc6, }, 4, 0, "", "",
+"c5 7e 7f c6          \tvmovdqu %ymm8,%ymm6",},
+{{0x62, 0x01, 0x7e, 0x48, 0x7f, 0xca, }, 6, 0, "", "",
+"62 01 7e 48 7f ca    \tvmovdqu32 %zmm25,%zmm26",},
+{{0x62, 0x01, 0xfe, 0x48, 0x7f, 0xca, }, 6, 0, "", "",
+"62 01 fe 48 7f ca    \tvmovdqu64 %zmm25,%zmm26",},
+{{0x62, 0x61, 0x7f, 0x48, 0x7f, 0x31, }, 6, 0, "", "",
+"62 61 7f 48 7f 31    \tvmovdqu8 %zmm30,(%rcx)",},
+{{0x62, 0x01, 0xff, 0x48, 0x7f, 0xca, }, 6, 0, "", "",
+"62 01 ff 48 7f ca    \tvmovdqu16 %zmm25,%zmm26",},
+{{0x0f, 0xdb, 0xd1, }, 3, 0, "", "",
+"0f db d1             \tpand   %mm1,%mm2",},
+{{0x66, 0x0f, 0xdb, 0xd1, }, 4, 0, "", "",
+"66 0f db d1          \tpand   %xmm1,%xmm2",},
+{{0xc5, 0xcd, 0xdb, 0xd4, }, 4, 0, "", "",
+"c5 cd db d4          \tvpand  %ymm4,%ymm6,%ymm2",},
+{{0x62, 0x01, 0x35, 0x40, 0xdb, 0xd0, }, 6, 0, "", "",
+"62 01 35 40 db d0    \tvpandd %zmm24,%zmm25,%zmm26",},
+{{0x62, 0x01, 0xb5, 0x40, 0xdb, 0xd0, }, 6, 0, "", "",
+"62 01 b5 40 db d0    \tvpandq %zmm24,%zmm25,%zmm26",},
+{{0x0f, 0xdf, 0xd1, }, 3, 0, "", "",
+"0f df d1             \tpandn  %mm1,%mm2",},
+{{0x66, 0x0f, 0xdf, 0xd1, }, 4, 0, "", "",
+"66 0f df d1          \tpandn  %xmm1,%xmm2",},
+{{0xc5, 0xcd, 0xdf, 0xd4, }, 4, 0, "", "",
+"c5 cd df d4          \tvpandn %ymm4,%ymm6,%ymm2",},
+{{0x62, 0x01, 0x35, 0x40, 0xdf, 0xd0, }, 6, 0, "", "",
+"62 01 35 40 df d0    \tvpandnd %zmm24,%zmm25,%zmm26",},
+{{0x62, 0x01, 0xb5, 0x40, 0xdf, 0xd0, }, 6, 0, "", "",
+"62 01 b5 40 df d0    \tvpandnq %zmm24,%zmm25,%zmm26",},
+{{0xc5, 0xf9, 0xe6, 0xd1, }, 4, 0, "", "",
+"c5 f9 e6 d1          \tvcvttpd2dq %xmm1,%xmm2",},
+{{0xc5, 0xfa, 0xe6, 0xf5, }, 4, 0, "", "",
+"c5 fa e6 f5          \tvcvtdq2pd %xmm5,%xmm6",},
+{{0x62, 0x61, 0x7e, 0x4f, 0xe6, 0xd5, }, 6, 0, "", "",
+"62 61 7e 4f e6 d5    \tvcvtdq2pd %ymm5,%zmm26{%k7}",},
+{{0x62, 0x01, 0xfe, 0x48, 0xe6, 0xd1, }, 6, 0, "", "",
+"62 01 fe 48 e6 d1    \tvcvtqq2pd %zmm25,%zmm26",},
+{{0xc5, 0xfb, 0xe6, 0xd1, }, 4, 0, "", "",
+"c5 fb e6 d1          \tvcvtpd2dq %xmm1,%xmm2",},
+{{0x0f, 0xeb, 0xf4, }, 3, 0, "", "",
+"0f eb f4             \tpor    %mm4,%mm6",},
+{{0xc5, 0xcd, 0xeb, 0xd4, }, 4, 0, "", "",
+"c5 cd eb d4          \tvpor   %ymm4,%ymm6,%ymm2",},
+{{0x62, 0x01, 0x35, 0x40, 0xeb, 0xd0, }, 6, 0, "", "",
+"62 01 35 40 eb d0    \tvpord  %zmm24,%zmm25,%zmm26",},
+{{0x62, 0x01, 0xb5, 0x40, 0xeb, 0xd0, }, 6, 0, "", "",
+"62 01 b5 40 eb d0    \tvporq  %zmm24,%zmm25,%zmm26",},
+{{0x0f, 0xef, 0xf4, }, 3, 0, "", "",
+"0f ef f4             \tpxor   %mm4,%mm6",},
+{{0xc5, 0xcd, 0xef, 0xd4, }, 4, 0, "", "",
+"c5 cd ef d4          \tvpxor  %ymm4,%ymm6,%ymm2",},
+{{0x62, 0x01, 0x35, 0x40, 0xef, 0xd0, }, 6, 0, "", "",
+"62 01 35 40 ef d0    \tvpxord %zmm24,%zmm25,%zmm26",},
+{{0x62, 0x01, 0xb5, 0x40, 0xef, 0xd0, }, 6, 0, "", "",
+"62 01 b5 40 ef d0    \tvpxorq %zmm24,%zmm25,%zmm26",},
+{{0x66, 0x0f, 0x38, 0x10, 0xc1, }, 5, 0, "", "",
+"66 0f 38 10 c1       \tpblendvb %xmm0,%xmm1,%xmm0",},
+{{0x62, 0x02, 0x9d, 0x40, 0x10, 0xeb, }, 6, 0, "", "",
+"62 02 9d 40 10 eb    \tvpsrlvw %zmm27,%zmm28,%zmm29",},
+{{0x62, 0x62, 0x7e, 0x4f, 0x10, 0xe6, }, 6, 0, "", "",
+"62 62 7e 4f 10 e6    \tvpmovuswb %zmm28,%ymm6{%k7}",},
+{{0x62, 0x62, 0x7e, 0x4f, 0x11, 0xe6, }, 6, 0, "", "",
+"62 62 7e 4f 11 e6    \tvpmovusdb %zmm28,%xmm6{%k7}",},
+{{0x62, 0x02, 0x9d, 0x40, 0x11, 0xeb, }, 6, 0, "", "",
+"62 02 9d 40 11 eb    \tvpsravw %zmm27,%zmm28,%zmm29",},
+{{0x62, 0x62, 0x7e, 0x4f, 0x12, 0xde, }, 6, 0, "", "",
+"62 62 7e 4f 12 de    \tvpmovusqb %zmm27,%xmm6{%k7}",},
+{{0x62, 0x02, 0x9d, 0x40, 0x12, 0xeb, }, 6, 0, "", "",
+"62 02 9d 40 12 eb    \tvpsllvw %zmm27,%zmm28,%zmm29",},
+{{0xc4, 0xe2, 0x7d, 0x13, 0xeb, }, 5, 0, "", "",
+"c4 e2 7d 13 eb       \tvcvtph2ps %xmm3,%ymm5",},
+{{0x62, 0x62, 0x7d, 0x4f, 0x13, 0xdd, }, 6, 0, "", "",
+"62 62 7d 4f 13 dd    \tvcvtph2ps %ymm5,%zmm27{%k7}",},
+{{0x62, 0x62, 0x7e, 0x4f, 0x13, 0xde, }, 6, 0, "", "",
+"62 62 7e 4f 13 de    \tvpmovusdw %zmm27,%ymm6{%k7}",},
+{{0x66, 0x0f, 0x38, 0x14, 0xc1, }, 5, 0, "", "",
+"66 0f 38 14 c1       \tblendvps %xmm0,%xmm1,%xmm0",},
+{{0x62, 0x62, 0x7e, 0x4f, 0x14, 0xde, }, 6, 0, "", "",
+"62 62 7e 4f 14 de    \tvpmovusqw %zmm27,%xmm6{%k7}",},
+{{0x62, 0x02, 0x1d, 0x40, 0x14, 0xeb, }, 6, 0, "", "",
+"62 02 1d 40 14 eb    \tvprorvd %zmm27,%zmm28,%zmm29",},
+{{0x62, 0x02, 0x9d, 0x40, 0x14, 0xeb, }, 6, 0, "", "",
+"62 02 9d 40 14 eb    \tvprorvq %zmm27,%zmm28,%zmm29",},
+{{0x66, 0x0f, 0x38, 0x15, 0xc1, }, 5, 0, "", "",
+"66 0f 38 15 c1       \tblendvpd %xmm0,%xmm1,%xmm0",},
+{{0x62, 0x62, 0x7e, 0x4f, 0x15, 0xde, }, 6, 0, "", "",
+"62 62 7e 4f 15 de    \tvpmovusqd %zmm27,%ymm6{%k7}",},
+{{0x62, 0x02, 0x1d, 0x40, 0x15, 0xeb, }, 6, 0, "", "",
+"62 02 1d 40 15 eb    \tvprolvd %zmm27,%zmm28,%zmm29",},
+{{0x62, 0x02, 0x9d, 0x40, 0x15, 0xeb, }, 6, 0, "", "",
+"62 02 9d 40 15 eb    \tvprolvq %zmm27,%zmm28,%zmm29",},
+{{0xc4, 0xe2, 0x4d, 0x16, 0xd4, }, 5, 0, "", "",
+"c4 e2 4d 16 d4       \tvpermps %ymm4,%ymm6,%ymm2",},
+{{0x62, 0x82, 0x2d, 0x27, 0x16, 0xf0, }, 6, 0, "", "",
+"62 82 2d 27 16 f0    \tvpermps %ymm24,%ymm26,%ymm22{%k7}",},
+{{0x62, 0x82, 0xad, 0x27, 0x16, 0xf0, }, 6, 0, "", "",
+"62 82 ad 27 16 f0    \tvpermpd %ymm24,%ymm26,%ymm22{%k7}",},
+{{0xc4, 0xe2, 0x7d, 0x19, 0xf4, }, 5, 0, "", "",
+"c4 e2 7d 19 f4       \tvbroadcastsd %xmm4,%ymm6",},
+{{0x62, 0x02, 0x7d, 0x48, 0x19, 0xd3, }, 6, 0, "", "",
+"62 02 7d 48 19 d3    \tvbroadcastf32x2 %xmm27,%zmm26",},
+{{0xc4, 0xe2, 0x7d, 0x1a, 0x21, }, 5, 0, "", "",
+"c4 e2 7d 1a 21       \tvbroadcastf128 (%rcx),%ymm4",},
+{{0x62, 0x62, 0x7d, 0x48, 0x1a, 0x11, }, 6, 0, "", "",
+"62 62 7d 48 1a 11    \tvbroadcastf32x4 (%rcx),%zmm26",},
+{{0x62, 0x62, 0xfd, 0x48, 0x1a, 0x11, }, 6, 0, "", "",
+"62 62 fd 48 1a 11    \tvbroadcastf64x2 (%rcx),%zmm26",},
+{{0x62, 0x62, 0x7d, 0x48, 0x1b, 0x19, }, 6, 0, "", "",
+"62 62 7d 48 1b 19    \tvbroadcastf32x8 (%rcx),%zmm27",},
+{{0x62, 0x62, 0xfd, 0x48, 0x1b, 0x11, }, 6, 0, "", "",
+"62 62 fd 48 1b 11    \tvbroadcastf64x4 (%rcx),%zmm26",},
+{{0x62, 0x02, 0xfd, 0x48, 0x1f, 0xe3, }, 6, 0, "", "",
+"62 02 fd 48 1f e3    \tvpabsq %zmm27,%zmm28",},
+{{0xc4, 0xe2, 0x79, 0x20, 0xec, }, 5, 0, "", "",
+"c4 e2 79 20 ec       \tvpmovsxbw %xmm4,%xmm5",},
+{{0x62, 0x62, 0x7e, 0x4f, 0x20, 0xde, }, 6, 0, "", "",
+"62 62 7e 4f 20 de    \tvpmovswb %zmm27,%ymm6{%k7}",},
+{{0xc4, 0xe2, 0x7d, 0x21, 0xf4, }, 5, 0, "", "",
+"c4 e2 7d 21 f4       \tvpmovsxbd %xmm4,%ymm6",},
+{{0x62, 0x62, 0x7e, 0x4f, 0x21, 0xde, }, 6, 0, "", "",
+"62 62 7e 4f 21 de    \tvpmovsdb %zmm27,%xmm6{%k7}",},
+{{0xc4, 0xe2, 0x7d, 0x22, 0xe4, }, 5, 0, "", "",
+"c4 e2 7d 22 e4       \tvpmovsxbq %xmm4,%ymm4",},
+{{0x62, 0x62, 0x7e, 0x4f, 0x22, 0xde, }, 6, 0, "", "",
+"62 62 7e 4f 22 de    \tvpmovsqb %zmm27,%xmm6{%k7}",},
+{{0xc4, 0xe2, 0x7d, 0x23, 0xe4, }, 5, 0, "", "",
+"c4 e2 7d 23 e4       \tvpmovsxwd %xmm4,%ymm4",},
+{{0x62, 0x62, 0x7e, 0x4f, 0x23, 0xde, }, 6, 0, "", "",
+"62 62 7e 4f 23 de    \tvpmovsdw %zmm27,%ymm6{%k7}",},
+{{0xc4, 0xe2, 0x7d, 0x24, 0xf4, }, 5, 0, "", "",
+"c4 e2 7d 24 f4       \tvpmovsxwq %xmm4,%ymm6",},
+{{0x62, 0x62, 0x7e, 0x4f, 0x24, 0xde, }, 6, 0, "", "",
+"62 62 7e 4f 24 de    \tvpmovsqw %zmm27,%xmm6{%k7}",},
+{{0xc4, 0xe2, 0x7d, 0x25, 0xe4, }, 5, 0, "", "",
+"c4 e2 7d 25 e4       \tvpmovsxdq %xmm4,%ymm4",},
+{{0x62, 0x62, 0x7e, 0x4f, 0x25, 0xde, }, 6, 0, "", "",
+"62 62 7e 4f 25 de    \tvpmovsqd %zmm27,%ymm6{%k7}",},
+{{0x62, 0x92, 0x1d, 0x40, 0x26, 0xeb, }, 6, 0, "", "",
+"62 92 1d 40 26 eb    \tvptestmb %zmm27,%zmm28,%k5",},
+{{0x62, 0x92, 0x9d, 0x40, 0x26, 0xeb, }, 6, 0, "", "",
+"62 92 9d 40 26 eb    \tvptestmw %zmm27,%zmm28,%k5",},
+{{0x62, 0x92, 0x26, 0x40, 0x26, 0xea, }, 6, 0, "", "",
+"62 92 26 40 26 ea    \tvptestnmb %zmm26,%zmm27,%k5",},
+{{0x62, 0x92, 0xa6, 0x40, 0x26, 0xea, }, 6, 0, "", "",
+"62 92 a6 40 26 ea    \tvptestnmw %zmm26,%zmm27,%k5",},
+{{0x62, 0x92, 0x1d, 0x40, 0x27, 0xeb, }, 6, 0, "", "",
+"62 92 1d 40 27 eb    \tvptestmd %zmm27,%zmm28,%k5",},
+{{0x62, 0x92, 0x9d, 0x40, 0x27, 0xeb, }, 6, 0, "", "",
+"62 92 9d 40 27 eb    \tvptestmq %zmm27,%zmm28,%k5",},
+{{0x62, 0x92, 0x26, 0x40, 0x27, 0xea, }, 6, 0, "", "",
+"62 92 26 40 27 ea    \tvptestnmd %zmm26,%zmm27,%k5",},
+{{0x62, 0x92, 0xa6, 0x40, 0x27, 0xea, }, 6, 0, "", "",
+"62 92 a6 40 27 ea    \tvptestnmq %zmm26,%zmm27,%k5",},
+{{0xc4, 0xe2, 0x4d, 0x28, 0xd4, }, 5, 0, "", "",
+"c4 e2 4d 28 d4       \tvpmuldq %ymm4,%ymm6,%ymm2",},
+{{0x62, 0x62, 0x7e, 0x48, 0x28, 0xe5, }, 6, 0, "", "",
+"62 62 7e 48 28 e5    \tvpmovm2b %k5,%zmm28",},
+{{0x62, 0x62, 0xfe, 0x48, 0x28, 0xe5, }, 6, 0, "", "",
+"62 62 fe 48 28 e5    \tvpmovm2w %k5,%zmm28",},
+{{0xc4, 0xe2, 0x4d, 0x29, 0xd4, }, 5, 0, "", "",
+"c4 e2 4d 29 d4       \tvpcmpeqq %ymm4,%ymm6,%ymm2",},
+{{0x62, 0x92, 0x7e, 0x48, 0x29, 0xec, }, 6, 0, "", "",
+"62 92 7e 48 29 ec    \tvpmovb2m %zmm28,%k5",},
+{{0x62, 0x92, 0xfe, 0x48, 0x29, 0xec, }, 6, 0, "", "",
+"62 92 fe 48 29 ec    \tvpmovw2m %zmm28,%k5",},
+{{0xc4, 0xe2, 0x7d, 0x2a, 0x21, }, 5, 0, "", "",
+"c4 e2 7d 2a 21       \tvmovntdqa (%rcx),%ymm4",},
+{{0x62, 0x62, 0xfe, 0x48, 0x2a, 0xf6, }, 6, 0, "", "",
+"62 62 fe 48 2a f6    \tvpbroadcastmb2q %k6,%zmm30",},
+{{0xc4, 0xe2, 0x5d, 0x2c, 0x31, }, 5, 0, "", "",
+"c4 e2 5d 2c 31       \tvmaskmovps (%rcx),%ymm4,%ymm6",},
+{{0x62, 0x02, 0x35, 0x40, 0x2c, 0xd0, }, 6, 0, "", "",
+"62 02 35 40 2c d0    \tvscalefps %zmm24,%zmm25,%zmm26",},
+{{0x62, 0x02, 0xb5, 0x40, 0x2c, 0xd0, }, 6, 0, "", "",
+"62 02 b5 40 2c d0    \tvscalefpd %zmm24,%zmm25,%zmm26",},
+{{0xc4, 0xe2, 0x5d, 0x2d, 0x31, }, 5, 0, "", "",
+"c4 e2 5d 2d 31       \tvmaskmovpd (%rcx),%ymm4,%ymm6",},
+{{0x62, 0x02, 0x35, 0x07, 0x2d, 0xd0, }, 6, 0, "", "",
+"62 02 35 07 2d d0    \tvscalefss %xmm24,%xmm25,%xmm26{%k7}",},
+{{0x62, 0x02, 0xb5, 0x07, 0x2d, 0xd0, }, 6, 0, "", "",
+"62 02 b5 07 2d d0    \tvscalefsd %xmm24,%xmm25,%xmm26{%k7}",},
+{{0xc4, 0xe2, 0x7d, 0x30, 0xe4, }, 5, 0, "", "",
+"c4 e2 7d 30 e4       \tvpmovzxbw %xmm4,%ymm4",},
+{{0x62, 0x62, 0x7e, 0x4f, 0x30, 0xde, }, 6, 0, "", "",
+"62 62 7e 4f 30 de    \tvpmovwb %zmm27,%ymm6{%k7}",},
+{{0xc4, 0xe2, 0x7d, 0x31, 0xf4, }, 5, 0, "", "",
+"c4 e2 7d 31 f4       \tvpmovzxbd %xmm4,%ymm6",},
+{{0x62, 0x62, 0x7e, 0x4f, 0x31, 0xde, }, 6, 0, "", "",
+"62 62 7e 4f 31 de    \tvpmovdb %zmm27,%xmm6{%k7}",},
+{{0xc4, 0xe2, 0x7d, 0x32, 0xe4, }, 5, 0, "", "",
+"c4 e2 7d 32 e4       \tvpmovzxbq %xmm4,%ymm4",},
+{{0x62, 0x62, 0x7e, 0x4f, 0x32, 0xde, }, 6, 0, "", "",
+"62 62 7e 4f 32 de    \tvpmovqb %zmm27,%xmm6{%k7}",},
+{{0xc4, 0xe2, 0x7d, 0x33, 0xe4, }, 5, 0, "", "",
+"c4 e2 7d 33 e4       \tvpmovzxwd %xmm4,%ymm4",},
+{{0x62, 0x62, 0x7e, 0x4f, 0x33, 0xde, }, 6, 0, "", "",
+"62 62 7e 4f 33 de    \tvpmovdw %zmm27,%ymm6{%k7}",},
+{{0xc4, 0xe2, 0x7d, 0x34, 0xf4, }, 5, 0, "", "",
+"c4 e2 7d 34 f4       \tvpmovzxwq %xmm4,%ymm6",},
+{{0x62, 0x62, 0x7e, 0x4f, 0x34, 0xde, }, 6, 0, "", "",
+"62 62 7e 4f 34 de    \tvpmovqw %zmm27,%xmm6{%k7}",},
+{{0xc4, 0xe2, 0x7d, 0x35, 0xe4, }, 5, 0, "", "",
+"c4 e2 7d 35 e4       \tvpmovzxdq %xmm4,%ymm4",},
+{{0x62, 0x62, 0x7e, 0x4f, 0x35, 0xde, }, 6, 0, "", "",
+"62 62 7e 4f 35 de    \tvpmovqd %zmm27,%ymm6{%k7}",},
+{{0xc4, 0xe2, 0x4d, 0x36, 0xd4, }, 5, 0, "", "",
+"c4 e2 4d 36 d4       \tvpermd %ymm4,%ymm6,%ymm2",},
+{{0x62, 0x82, 0x2d, 0x27, 0x36, 0xf0, }, 6, 0, "", "",
+"62 82 2d 27 36 f0    \tvpermd %ymm24,%ymm26,%ymm22{%k7}",},
+{{0x62, 0x82, 0xad, 0x27, 0x36, 0xf0, }, 6, 0, "", "",
+"62 82 ad 27 36 f0    \tvpermq %ymm24,%ymm26,%ymm22{%k7}",},
+{{0xc4, 0xe2, 0x4d, 0x38, 0xd4, }, 5, 0, "", "",
+"c4 e2 4d 38 d4       \tvpminsb %ymm4,%ymm6,%ymm2",},
+{{0x62, 0x62, 0x7e, 0x48, 0x38, 0xe5, }, 6, 0, "", "",
+"62 62 7e 48 38 e5    \tvpmovm2d %k5,%zmm28",},
+{{0x62, 0x62, 0xfe, 0x48, 0x38, 0xe5, }, 6, 0, "", "",
+"62 62 fe 48 38 e5    \tvpmovm2q %k5,%zmm28",},
+{{0xc4, 0xe2, 0x69, 0x39, 0xd9, }, 5, 0, "", "",
+"c4 e2 69 39 d9       \tvpminsd %xmm1,%xmm2,%xmm3",},
+{{0x62, 0x02, 0x35, 0x40, 0x39, 0xd0, }, 6, 0, "", "",
+"62 02 35 40 39 d0    \tvpminsd %zmm24,%zmm25,%zmm26",},
+{{0x62, 0x02, 0xb5, 0x40, 0x39, 0xd0, }, 6, 0, "", "",
+"62 02 b5 40 39 d0    \tvpminsq %zmm24,%zmm25,%zmm26",},
+{{0x62, 0x92, 0x7e, 0x48, 0x39, 0xec, }, 6, 0, "", "",
+"62 92 7e 48 39 ec    \tvpmovd2m %zmm28,%k5",},
+{{0x62, 0x92, 0xfe, 0x48, 0x39, 0xec, }, 6, 0, "", "",
+"62 92 fe 48 39 ec    \tvpmovq2m %zmm28,%k5",},
+{{0xc4, 0xe2, 0x4d, 0x3a, 0xd4, }, 5, 0, "", "",
+"c4 e2 4d 3a d4       \tvpminuw %ymm4,%ymm6,%ymm2",},
+{{0x62, 0x62, 0x7e, 0x48, 0x3a, 0xe6, }, 6, 0, "", "",
+"62 62 7e 48 3a e6    \tvpbroadcastmw2d %k6,%zmm28",},
+{{0xc4, 0xe2, 0x4d, 0x3b, 0xd4, }, 5, 0, "", "",
+"c4 e2 4d 3b d4       \tvpminud %ymm4,%ymm6,%ymm2",},
+{{0x62, 0x02, 0x35, 0x40, 0x3b, 0xd0, }, 6, 0, "", "",
+"62 02 35 40 3b d0    \tvpminud %zmm24,%zmm25,%zmm26",},
+{{0x62, 0x02, 0xb5, 0x40, 0x3b, 0xd0, }, 6, 0, "", "",
+"62 02 b5 40 3b d0    \tvpminuq %zmm24,%zmm25,%zmm26",},
+{{0xc4, 0xe2, 0x4d, 0x3d, 0xd4, }, 5, 0, "", "",
+"c4 e2 4d 3d d4       \tvpmaxsd %ymm4,%ymm6,%ymm2",},
+{{0x62, 0x02, 0x35, 0x40, 0x3d, 0xd0, }, 6, 0, "", "",
+"62 02 35 40 3d d0    \tvpmaxsd %zmm24,%zmm25,%zmm26",},
+{{0x62, 0x02, 0xb5, 0x40, 0x3d, 0xd0, }, 6, 0, "", "",
+"62 02 b5 40 3d d0    \tvpmaxsq %zmm24,%zmm25,%zmm26",},
+{{0xc4, 0xe2, 0x4d, 0x3f, 0xd4, }, 5, 0, "", "",
+"c4 e2 4d 3f d4       \tvpmaxud %ymm4,%ymm6,%ymm2",},
+{{0x62, 0x02, 0x35, 0x40, 0x3f, 0xd0, }, 6, 0, "", "",
+"62 02 35 40 3f d0    \tvpmaxud %zmm24,%zmm25,%zmm26",},
+{{0x62, 0x02, 0xb5, 0x40, 0x3f, 0xd0, }, 6, 0, "", "",
+"62 02 b5 40 3f d0    \tvpmaxuq %zmm24,%zmm25,%zmm26",},
+{{0xc4, 0xe2, 0x4d, 0x40, 0xd4, }, 5, 0, "", "",
+"c4 e2 4d 40 d4       \tvpmulld %ymm4,%ymm6,%ymm2",},
+{{0x62, 0x02, 0x35, 0x40, 0x40, 0xd0, }, 6, 0, "", "",
+"62 02 35 40 40 d0    \tvpmulld %zmm24,%zmm25,%zmm26",},
+{{0x62, 0x02, 0xb5, 0x40, 0x40, 0xd0, }, 6, 0, "", "",
+"62 02 b5 40 40 d0    \tvpmullq %zmm24,%zmm25,%zmm26",},
+{{0x62, 0x02, 0x7d, 0x48, 0x42, 0xd1, }, 6, 0, "", "",
+"62 02 7d 48 42 d1    \tvgetexpps %zmm25,%zmm26",},
+{{0x62, 0x02, 0xfd, 0x48, 0x42, 0xe3, }, 6, 0, "", "",
+"62 02 fd 48 42 e3    \tvgetexppd %zmm27,%zmm28",},
+{{0x62, 0x02, 0x35, 0x07, 0x43, 0xd0, }, 6, 0, "", "",
+"62 02 35 07 43 d0    \tvgetexpss %xmm24,%xmm25,%xmm26{%k7}",},
+{{0x62, 0x02, 0x95, 0x07, 0x43, 0xf4, }, 6, 0, "", "",
+"62 02 95 07 43 f4    \tvgetexpsd %xmm28,%xmm29,%xmm30{%k7}",},
+{{0x62, 0x02, 0x7d, 0x48, 0x44, 0xe3, }, 6, 0, "", "",
+"62 02 7d 48 44 e3    \tvplzcntd %zmm27,%zmm28",},
+{{0x62, 0x02, 0xfd, 0x48, 0x44, 0xe3, }, 6, 0, "", "",
+"62 02 fd 48 44 e3    \tvplzcntq %zmm27,%zmm28",},
+{{0xc4, 0xe2, 0x4d, 0x46, 0xd4, }, 5, 0, "", "",
+"c4 e2 4d 46 d4       \tvpsravd %ymm4,%ymm6,%ymm2",},
+{{0x62, 0x02, 0x35, 0x40, 0x46, 0xd0, }, 6, 0, "", "",
+"62 02 35 40 46 d0    \tvpsravd %zmm24,%zmm25,%zmm26",},
+{{0x62, 0x02, 0xb5, 0x40, 0x46, 0xd0, }, 6, 0, "", "",
+"62 02 b5 40 46 d0    \tvpsravq %zmm24,%zmm25,%zmm26",},
+{{0x62, 0x02, 0x7d, 0x48, 0x4c, 0xd1, }, 6, 0, "", "",
+"62 02 7d 48 4c d1    \tvrcp14ps %zmm25,%zmm26",},
+{{0x62, 0x02, 0xfd, 0x48, 0x4c, 0xe3, }, 6, 0, "", "",
+"62 02 fd 48 4c e3    \tvrcp14pd %zmm27,%zmm28",},
+{{0x62, 0x02, 0x35, 0x07, 0x4d, 0xd0, }, 6, 0, "", "",
+"62 02 35 07 4d d0    \tvrcp14ss %xmm24,%xmm25,%xmm26{%k7}",},
+{{0x62, 0x02, 0xb5, 0x07, 0x4d, 0xd0, }, 6, 0, "", "",
+"62 02 b5 07 4d d0    \tvrcp14sd %xmm24,%xmm25,%xmm26{%k7}",},
+{{0x62, 0x02, 0x7d, 0x48, 0x4e, 0xd1, }, 6, 0, "", "",
+"62 02 7d 48 4e d1    \tvrsqrt14ps %zmm25,%zmm26",},
+{{0x62, 0x02, 0xfd, 0x48, 0x4e, 0xe3, }, 6, 0, "", "",
+"62 02 fd 48 4e e3    \tvrsqrt14pd %zmm27,%zmm28",},
+{{0x62, 0x02, 0x35, 0x07, 0x4f, 0xd0, }, 6, 0, "", "",
+"62 02 35 07 4f d0    \tvrsqrt14ss %xmm24,%xmm25,%xmm26{%k7}",},
+{{0x62, 0x02, 0xb5, 0x07, 0x4f, 0xd0, }, 6, 0, "", "",
+"62 02 b5 07 4f d0    \tvrsqrt14sd %xmm24,%xmm25,%xmm26{%k7}",},
+{{0xc4, 0xe2, 0x79, 0x59, 0xf4, }, 5, 0, "", "",
+"c4 e2 79 59 f4       \tvpbroadcastq %xmm4,%xmm6",},
+{{0x62, 0x02, 0x7d, 0x48, 0x59, 0xd3, }, 6, 0, "", "",
+"62 02 7d 48 59 d3    \tvbroadcasti32x2 %xmm27,%zmm26",},
+{{0xc4, 0xe2, 0x7d, 0x5a, 0x21, }, 5, 0, "", "",
+"c4 e2 7d 5a 21       \tvbroadcasti128 (%rcx),%ymm4",},
+{{0x62, 0x62, 0x7d, 0x48, 0x5a, 0x11, }, 6, 0, "", "",
+"62 62 7d 48 5a 11    \tvbroadcasti32x4 (%rcx),%zmm26",},
+{{0x62, 0x62, 0xfd, 0x48, 0x5a, 0x11, }, 6, 0, "", "",
+"62 62 fd 48 5a 11    \tvbroadcasti64x2 (%rcx),%zmm26",},
+{{0x62, 0x62, 0x7d, 0x48, 0x5b, 0x21, }, 6, 0, "", "",
+"62 62 7d 48 5b 21    \tvbroadcasti32x8 (%rcx),%zmm28",},
+{{0x62, 0x62, 0xfd, 0x48, 0x5b, 0x11, }, 6, 0, "", "",
+"62 62 fd 48 5b 11    \tvbroadcasti64x4 (%rcx),%zmm26",},
+{{0x62, 0x02, 0x25, 0x40, 0x64, 0xe2, }, 6, 0, "", "",
+"62 02 25 40 64 e2    \tvpblendmd %zmm26,%zmm27,%zmm28",},
+{{0x62, 0x02, 0xa5, 0x40, 0x64, 0xe2, }, 6, 0, "", "",
+"62 02 a5 40 64 e2    \tvpblendmq %zmm26,%zmm27,%zmm28",},
+{{0x62, 0x02, 0x35, 0x40, 0x65, 0xd0, }, 6, 0, "", "",
+"62 02 35 40 65 d0    \tvblendmps %zmm24,%zmm25,%zmm26",},
+{{0x62, 0x02, 0xa5, 0x40, 0x65, 0xe2, }, 6, 0, "", "",
+"62 02 a5 40 65 e2    \tvblendmpd %zmm26,%zmm27,%zmm28",},
+{{0x62, 0x02, 0x25, 0x40, 0x66, 0xe2, }, 6, 0, "", "",
+"62 02 25 40 66 e2    \tvpblendmb %zmm26,%zmm27,%zmm28",},
+{{0x62, 0x02, 0xa5, 0x40, 0x66, 0xe2, }, 6, 0, "", "",
+"62 02 a5 40 66 e2    \tvpblendmw %zmm26,%zmm27,%zmm28",},
+{{0x62, 0x02, 0x35, 0x40, 0x75, 0xd0, }, 6, 0, "", "",
+"62 02 35 40 75 d0    \tvpermi2b %zmm24,%zmm25,%zmm26",},
+{{0x62, 0x02, 0xa5, 0x40, 0x75, 0xe2, }, 6, 0, "", "",
+"62 02 a5 40 75 e2    \tvpermi2w %zmm26,%zmm27,%zmm28",},
+{{0x62, 0x02, 0x25, 0x40, 0x76, 0xe2, }, 6, 0, "", "",
+"62 02 25 40 76 e2    \tvpermi2d %zmm26,%zmm27,%zmm28",},
+{{0x62, 0x02, 0xa5, 0x40, 0x76, 0xe2, }, 6, 0, "", "",
+"62 02 a5 40 76 e2    \tvpermi2q %zmm26,%zmm27,%zmm28",},
+{{0x62, 0x02, 0x25, 0x40, 0x77, 0xe2, }, 6, 0, "", "",
+"62 02 25 40 77 e2    \tvpermi2ps %zmm26,%zmm27,%zmm28",},
+{{0x62, 0x02, 0xa5, 0x40, 0x77, 0xe2, }, 6, 0, "", "",
+"62 02 a5 40 77 e2    \tvpermi2pd %zmm26,%zmm27,%zmm28",},
+{{0x62, 0x62, 0x7d, 0x08, 0x7a, 0xf0, }, 6, 0, "", "",
+"62 62 7d 08 7a f0    \tvpbroadcastb %eax,%xmm30",},
+{{0x62, 0x62, 0x7d, 0x08, 0x7b, 0xf0, }, 6, 0, "", "",
+"62 62 7d 08 7b f0    \tvpbroadcastw %eax,%xmm30",},
+{{0x62, 0x62, 0x7d, 0x08, 0x7c, 0xf0, }, 6, 0, "", "",
+"62 62 7d 08 7c f0    \tvpbroadcastd %eax,%xmm30",},
+{{0x62, 0x62, 0xfd, 0x48, 0x7c, 0xf0, }, 6, 0, "", "",
+"62 62 fd 48 7c f0    \tvpbroadcastq %rax,%zmm30",},
+{{0x62, 0x02, 0x25, 0x40, 0x7d, 0xe2, }, 6, 0, "", "",
+"62 02 25 40 7d e2    \tvpermt2b %zmm26,%zmm27,%zmm28",},
+{{0x62, 0x02, 0xa5, 0x40, 0x7d, 0xe2, }, 6, 0, "", "",
+"62 02 a5 40 7d e2    \tvpermt2w %zmm26,%zmm27,%zmm28",},
+{{0x62, 0x02, 0x25, 0x40, 0x7e, 0xe2, }, 6, 0, "", "",
+"62 02 25 40 7e e2    \tvpermt2d %zmm26,%zmm27,%zmm28",},
+{{0x62, 0x02, 0xa5, 0x40, 0x7e, 0xe2, }, 6, 0, "", "",
+"62 02 a5 40 7e e2    \tvpermt2q %zmm26,%zmm27,%zmm28",},
+{{0x62, 0x02, 0x25, 0x40, 0x7f, 0xe2, }, 6, 0, "", "",
+"62 02 25 40 7f e2    \tvpermt2ps %zmm26,%zmm27,%zmm28",},
+{{0x62, 0x02, 0xa5, 0x40, 0x7f, 0xe2, }, 6, 0, "", "",
+"62 02 a5 40 7f e2    \tvpermt2pd %zmm26,%zmm27,%zmm28",},
+{{0x62, 0x02, 0xa5, 0x40, 0x83, 0xe2, }, 6, 0, "", "",
+"62 02 a5 40 83 e2    \tvpmultishiftqb %zmm26,%zmm27,%zmm28",},
+{{0x62, 0x62, 0x7d, 0x48, 0x88, 0x11, }, 6, 0, "", "",
+"62 62 7d 48 88 11    \tvexpandps (%rcx),%zmm26",},
+{{0x62, 0x62, 0xfd, 0x48, 0x88, 0x21, }, 6, 0, "", "",
+"62 62 fd 48 88 21    \tvexpandpd (%rcx),%zmm28",},
+{{0x62, 0x62, 0x7d, 0x48, 0x89, 0x21, }, 6, 0, "", "",
+"62 62 7d 48 89 21    \tvpexpandd (%rcx),%zmm28",},
+{{0x62, 0x62, 0xfd, 0x48, 0x89, 0x11, }, 6, 0, "", "",
+"62 62 fd 48 89 11    \tvpexpandq (%rcx),%zmm26",},
+{{0x62, 0x62, 0x7d, 0x48, 0x8a, 0x21, }, 6, 0, "", "",
+"62 62 7d 48 8a 21    \tvcompressps %zmm28,(%rcx)",},
+{{0x62, 0x62, 0xfd, 0x48, 0x8a, 0x21, }, 6, 0, "", "",
+"62 62 fd 48 8a 21    \tvcompresspd %zmm28,(%rcx)",},
+{{0x62, 0x62, 0x7d, 0x48, 0x8b, 0x21, }, 6, 0, "", "",
+"62 62 7d 48 8b 21    \tvpcompressd %zmm28,(%rcx)",},
+{{0x62, 0x62, 0xfd, 0x48, 0x8b, 0x11, }, 6, 0, "", "",
+"62 62 fd 48 8b 11    \tvpcompressq %zmm26,(%rcx)",},
+{{0x62, 0x02, 0x25, 0x40, 0x8d, 0xe2, }, 6, 0, "", "",
+"62 02 25 40 8d e2    \tvpermb %zmm26,%zmm27,%zmm28",},
+{{0x62, 0x02, 0xa5, 0x40, 0x8d, 0xe2, }, 6, 0, "", "",
+"62 02 a5 40 8d e2    \tvpermw %zmm26,%zmm27,%zmm28",},
+{{0xc4, 0xe2, 0x69, 0x90, 0x4c, 0x7d, 0x02, }, 7, 0, "", "",
+"c4 e2 69 90 4c 7d 02 \tvpgatherdd %xmm2,0x2(%rbp,%xmm7,2),%xmm1",},
+{{0xc4, 0xe2, 0xe9, 0x90, 0x4c, 0x7d, 0x04, }, 7, 0, "", "",
+"c4 e2 e9 90 4c 7d 04 \tvpgatherdq %xmm2,0x4(%rbp,%xmm7,2),%xmm1",},
+{{0x62, 0x22, 0x7d, 0x41, 0x90, 0x94, 0xdd, 0x7b, 0x00, 0x00, 0x00, }, 11, 0, "", "",
+"62 22 7d 41 90 94 dd 7b 00 00 00 \tvpgatherdd 0x7b(%rbp,%zmm27,8),%zmm26{%k1}",},
+{{0x62, 0x22, 0xfd, 0x41, 0x90, 0x94, 0xdd, 0x7b, 0x00, 0x00, 0x00, }, 11, 0, "", "",
+"62 22 fd 41 90 94 dd 7b 00 00 00 \tvpgatherdq 0x7b(%rbp,%ymm27,8),%zmm26{%k1}",},
+{{0xc4, 0xe2, 0x69, 0x91, 0x4c, 0x7d, 0x02, }, 7, 0, "", "",
+"c4 e2 69 91 4c 7d 02 \tvpgatherqd %xmm2,0x2(%rbp,%xmm7,2),%xmm1",},
+{{0xc4, 0xe2, 0xe9, 0x91, 0x4c, 0x7d, 0x02, }, 7, 0, "", "",
+"c4 e2 e9 91 4c 7d 02 \tvpgatherqq %xmm2,0x2(%rbp,%xmm7,2),%xmm1",},
+{{0x62, 0x22, 0x7d, 0x41, 0x91, 0x94, 0xdd, 0x7b, 0x00, 0x00, 0x00, }, 11, 0, "", "",
+"62 22 7d 41 91 94 dd 7b 00 00 00 \tvpgatherqd 0x7b(%rbp,%zmm27,8),%ymm26{%k1}",},
+{{0x62, 0x22, 0xfd, 0x41, 0x91, 0x94, 0xdd, 0x7b, 0x00, 0x00, 0x00, }, 11, 0, "", "",
+"62 22 fd 41 91 94 dd 7b 00 00 00 \tvpgatherqq 0x7b(%rbp,%zmm27,8),%zmm26{%k1}",},
+{{0x62, 0x22, 0x7d, 0x41, 0xa0, 0xa4, 0xed, 0x7b, 0x00, 0x00, 0x00, }, 11, 0, "", "",
+"62 22 7d 41 a0 a4 ed 7b 00 00 00 \tvpscatterdd %zmm28,0x7b(%rbp,%zmm29,8){%k1}",},
+{{0x62, 0x22, 0xfd, 0x41, 0xa0, 0x94, 0xdd, 0x7b, 0x00, 0x00, 0x00, }, 11, 0, "", "",
+"62 22 fd 41 a0 94 dd 7b 00 00 00 \tvpscatterdq %zmm26,0x7b(%rbp,%ymm27,8){%k1}",},
+{{0x62, 0xb2, 0x7d, 0x41, 0xa1, 0xb4, 0xed, 0x7b, 0x00, 0x00, 0x00, }, 11, 0, "", "",
+"62 b2 7d 41 a1 b4 ed 7b 00 00 00 \tvpscatterqd %ymm6,0x7b(%rbp,%zmm29,8){%k1}",},
+{{0x62, 0xb2, 0xfd, 0x21, 0xa1, 0xb4, 0xdd, 0x7b, 0x00, 0x00, 0x00, }, 11, 0, "", "",
+"62 b2 fd 21 a1 b4 dd 7b 00 00 00 \tvpscatterqq %ymm6,0x7b(%rbp,%ymm27,8){%k1}",},
+{{0x62, 0x22, 0x7d, 0x41, 0xa2, 0xa4, 0xed, 0x7b, 0x00, 0x00, 0x00, }, 11, 0, "", "",
+"62 22 7d 41 a2 a4 ed 7b 00 00 00 \tvscatterdps %zmm28,0x7b(%rbp,%zmm29,8){%k1}",},
+{{0x62, 0x22, 0xfd, 0x41, 0xa2, 0xa4, 0xdd, 0x7b, 0x00, 0x00, 0x00, }, 11, 0, "", "",
+"62 22 fd 41 a2 a4 dd 7b 00 00 00 \tvscatterdpd %zmm28,0x7b(%rbp,%ymm27,8){%k1}",},
+{{0x62, 0xb2, 0x7d, 0x41, 0xa3, 0xb4, 0xed, 0x7b, 0x00, 0x00, 0x00, }, 11, 0, "", "",
+"62 b2 7d 41 a3 b4 ed 7b 00 00 00 \tvscatterqps %ymm6,0x7b(%rbp,%zmm29,8){%k1}",},
+{{0x62, 0x22, 0xfd, 0x41, 0xa3, 0xa4, 0xed, 0x7b, 0x00, 0x00, 0x00, }, 11, 0, "", "",
+"62 22 fd 41 a3 a4 ed 7b 00 00 00 \tvscatterqpd %zmm28,0x7b(%rbp,%zmm29,8){%k1}",},
+{{0x62, 0x02, 0xa5, 0x40, 0xb4, 0xe2, }, 6, 0, "", "",
+"62 02 a5 40 b4 e2    \tvpmadd52luq %zmm26,%zmm27,%zmm28",},
+{{0x62, 0x02, 0xa5, 0x40, 0xb5, 0xe2, }, 6, 0, "", "",
+"62 02 a5 40 b5 e2    \tvpmadd52huq %zmm26,%zmm27,%zmm28",},
+{{0x62, 0x02, 0x7d, 0x48, 0xc4, 0xda, }, 6, 0, "", "",
+"62 02 7d 48 c4 da    \tvpconflictd %zmm26,%zmm27",},
+{{0x62, 0x02, 0xfd, 0x48, 0xc4, 0xda, }, 6, 0, "", "",
+"62 02 fd 48 c4 da    \tvpconflictq %zmm26,%zmm27",},
+{{0x62, 0x02, 0x7d, 0x48, 0xc8, 0xf5, }, 6, 0, "", "",
+"62 02 7d 48 c8 f5    \tvexp2ps %zmm29,%zmm30",},
+{{0x62, 0x02, 0xfd, 0x48, 0xc8, 0xda, }, 6, 0, "", "",
+"62 02 fd 48 c8 da    \tvexp2pd %zmm26,%zmm27",},
+{{0x62, 0x02, 0x7d, 0x48, 0xca, 0xf5, }, 6, 0, "", "",
+"62 02 7d 48 ca f5    \tvrcp28ps %zmm29,%zmm30",},
+{{0x62, 0x02, 0xfd, 0x48, 0xca, 0xda, }, 6, 0, "", "",
+"62 02 fd 48 ca da    \tvrcp28pd %zmm26,%zmm27",},
+{{0x62, 0x02, 0x15, 0x07, 0xcb, 0xf4, }, 6, 0, "", "",
+"62 02 15 07 cb f4    \tvrcp28ss %xmm28,%xmm29,%xmm30{%k7}",},
+{{0x62, 0x02, 0xad, 0x07, 0xcb, 0xd9, }, 6, 0, "", "",
+"62 02 ad 07 cb d9    \tvrcp28sd %xmm25,%xmm26,%xmm27{%k7}",},
+{{0x62, 0x02, 0x7d, 0x48, 0xcc, 0xf5, }, 6, 0, "", "",
+"62 02 7d 48 cc f5    \tvrsqrt28ps %zmm29,%zmm30",},
+{{0x62, 0x02, 0xfd, 0x48, 0xcc, 0xda, }, 6, 0, "", "",
+"62 02 fd 48 cc da    \tvrsqrt28pd %zmm26,%zmm27",},
+{{0x62, 0x02, 0x15, 0x07, 0xcd, 0xf4, }, 6, 0, "", "",
+"62 02 15 07 cd f4    \tvrsqrt28ss %xmm28,%xmm29,%xmm30{%k7}",},
+{{0x62, 0x02, 0xad, 0x07, 0xcd, 0xd9, }, 6, 0, "", "",
+"62 02 ad 07 cd d9    \tvrsqrt28sd %xmm25,%xmm26,%xmm27{%k7}",},
+{{0x62, 0x03, 0x15, 0x40, 0x03, 0xf4, 0x12, }, 7, 0, "", "",
+"62 03 15 40 03 f4 12 \tvalignd $0x12,%zmm28,%zmm29,%zmm30",},
+{{0x62, 0x03, 0xad, 0x40, 0x03, 0xd9, 0x12, }, 7, 0, "", "",
+"62 03 ad 40 03 d9 12 \tvalignq $0x12,%zmm25,%zmm26,%zmm27",},
+{{0xc4, 0xe3, 0x7d, 0x08, 0xd6, 0x05, }, 6, 0, "", "",
+"c4 e3 7d 08 d6 05    \tvroundps $0x5,%ymm6,%ymm2",},
+{{0x62, 0x03, 0x7d, 0x48, 0x08, 0xd1, 0x12, }, 7, 0, "", "",
+"62 03 7d 48 08 d1 12 \tvrndscaleps $0x12,%zmm25,%zmm26",},
+{{0xc4, 0xe3, 0x7d, 0x09, 0xd6, 0x05, }, 6, 0, "", "",
+"c4 e3 7d 09 d6 05    \tvroundpd $0x5,%ymm6,%ymm2",},
+{{0x62, 0x03, 0xfd, 0x48, 0x09, 0xd1, 0x12, }, 7, 0, "", "",
+"62 03 fd 48 09 d1 12 \tvrndscalepd $0x12,%zmm25,%zmm26",},
+{{0xc4, 0xe3, 0x49, 0x0a, 0xd4, 0x05, }, 6, 0, "", "",
+"c4 e3 49 0a d4 05    \tvroundss $0x5,%xmm4,%xmm6,%xmm2",},
+{{0x62, 0x03, 0x35, 0x07, 0x0a, 0xd0, 0x12, }, 7, 0, "", "",
+"62 03 35 07 0a d0 12 \tvrndscaless $0x12,%xmm24,%xmm25,%xmm26{%k7}",},
+{{0xc4, 0xe3, 0x49, 0x0b, 0xd4, 0x05, }, 6, 0, "", "",
+"c4 e3 49 0b d4 05    \tvroundsd $0x5,%xmm4,%xmm6,%xmm2",},
+{{0x62, 0x03, 0xb5, 0x07, 0x0b, 0xd0, 0x12, }, 7, 0, "", "",
+"62 03 b5 07 0b d0 12 \tvrndscalesd $0x12,%xmm24,%xmm25,%xmm26{%k7}",},
+{{0xc4, 0xe3, 0x5d, 0x18, 0xf4, 0x05, }, 6, 0, "", "",
+"c4 e3 5d 18 f4 05    \tvinsertf128 $0x5,%xmm4,%ymm4,%ymm6",},
+{{0x62, 0x03, 0x35, 0x47, 0x18, 0xd0, 0x12, }, 7, 0, "", "",
+"62 03 35 47 18 d0 12 \tvinsertf32x4 $0x12,%xmm24,%zmm25,%zmm26{%k7}",},
+{{0x62, 0x03, 0xb5, 0x47, 0x18, 0xd0, 0x12, }, 7, 0, "", "",
+"62 03 b5 47 18 d0 12 \tvinsertf64x2 $0x12,%xmm24,%zmm25,%zmm26{%k7}",},
+{{0xc4, 0xe3, 0x7d, 0x19, 0xe4, 0x05, }, 6, 0, "", "",
+"c4 e3 7d 19 e4 05    \tvextractf128 $0x5,%ymm4,%xmm4",},
+{{0x62, 0x03, 0x7d, 0x4f, 0x19, 0xca, 0x12, }, 7, 0, "", "",
+"62 03 7d 4f 19 ca 12 \tvextractf32x4 $0x12,%zmm25,%xmm26{%k7}",},
+{{0x62, 0x03, 0xfd, 0x4f, 0x19, 0xca, 0x12, }, 7, 0, "", "",
+"62 03 fd 4f 19 ca 12 \tvextractf64x2 $0x12,%zmm25,%xmm26{%k7}",},
+{{0x62, 0x03, 0x2d, 0x47, 0x1a, 0xd9, 0x12, }, 7, 0, "", "",
+"62 03 2d 47 1a d9 12 \tvinsertf32x8 $0x12,%ymm25,%zmm26,%zmm27{%k7}",},
+{{0x62, 0x03, 0x95, 0x47, 0x1a, 0xf4, 0x12, }, 7, 0, "", "",
+"62 03 95 47 1a f4 12 \tvinsertf64x4 $0x12,%ymm28,%zmm29,%zmm30{%k7}",},
+{{0x62, 0x03, 0x7d, 0x4f, 0x1b, 0xee, 0x12, }, 7, 0, "", "",
+"62 03 7d 4f 1b ee 12 \tvextractf32x8 $0x12,%zmm29,%ymm30{%k7}",},
+{{0x62, 0x03, 0xfd, 0x4f, 0x1b, 0xd3, 0x12, }, 7, 0, "", "",
+"62 03 fd 4f 1b d3 12 \tvextractf64x4 $0x12,%zmm26,%ymm27{%k7}",},
+{{0x62, 0x93, 0x0d, 0x40, 0x1e, 0xed, 0x12, }, 7, 0, "", "",
+"62 93 0d 40 1e ed 12 \tvpcmpud $0x12,%zmm29,%zmm30,%k5",},
+{{0x62, 0x93, 0xa5, 0x40, 0x1e, 0xea, 0x12, }, 7, 0, "", "",
+"62 93 a5 40 1e ea 12 \tvpcmpuq $0x12,%zmm26,%zmm27,%k5",},
+{{0x62, 0x93, 0x0d, 0x40, 0x1f, 0xed, 0x12, }, 7, 0, "", "",
+"62 93 0d 40 1f ed 12 \tvpcmpd $0x12,%zmm29,%zmm30,%k5",},
+{{0x62, 0x93, 0xa5, 0x40, 0x1f, 0xea, 0x12, }, 7, 0, "", "",
+"62 93 a5 40 1f ea 12 \tvpcmpq $0x12,%zmm26,%zmm27,%k5",},
+{{0x62, 0x03, 0x15, 0x40, 0x23, 0xf4, 0x12, }, 7, 0, "", "",
+"62 03 15 40 23 f4 12 \tvshuff32x4 $0x12,%zmm28,%zmm29,%zmm30",},
+{{0x62, 0x03, 0xad, 0x40, 0x23, 0xd9, 0x12, }, 7, 0, "", "",
+"62 03 ad 40 23 d9 12 \tvshuff64x2 $0x12,%zmm25,%zmm26,%zmm27",},
+{{0x62, 0x03, 0x15, 0x40, 0x25, 0xf4, 0x12, }, 7, 0, "", "",
+"62 03 15 40 25 f4 12 \tvpternlogd $0x12,%zmm28,%zmm29,%zmm30",},
+{{0x62, 0x03, 0x95, 0x40, 0x25, 0xf4, 0x12, }, 7, 0, "", "",
+"62 03 95 40 25 f4 12 \tvpternlogq $0x12,%zmm28,%zmm29,%zmm30",},
+{{0x62, 0x03, 0x7d, 0x48, 0x26, 0xda, 0x12, }, 7, 0, "", "",
+"62 03 7d 48 26 da 12 \tvgetmantps $0x12,%zmm26,%zmm27",},
+{{0x62, 0x03, 0xfd, 0x48, 0x26, 0xf5, 0x12, }, 7, 0, "", "",
+"62 03 fd 48 26 f5 12 \tvgetmantpd $0x12,%zmm29,%zmm30",},
+{{0x62, 0x03, 0x2d, 0x07, 0x27, 0xd9, 0x12, }, 7, 0, "", "",
+"62 03 2d 07 27 d9 12 \tvgetmantss $0x12,%xmm25,%xmm26,%xmm27{%k7}",},
+{{0x62, 0x03, 0x95, 0x07, 0x27, 0xf4, 0x12, }, 7, 0, "", "",
+"62 03 95 07 27 f4 12 \tvgetmantsd $0x12,%xmm28,%xmm29,%xmm30{%k7}",},
+{{0xc4, 0xe3, 0x5d, 0x38, 0xf4, 0x05, }, 6, 0, "", "",
+"c4 e3 5d 38 f4 05    \tvinserti128 $0x5,%xmm4,%ymm4,%ymm6",},
+{{0x62, 0x03, 0x35, 0x47, 0x38, 0xd0, 0x12, }, 7, 0, "", "",
+"62 03 35 47 38 d0 12 \tvinserti32x4 $0x12,%xmm24,%zmm25,%zmm26{%k7}",},
+{{0x62, 0x03, 0xb5, 0x47, 0x38, 0xd0, 0x12, }, 7, 0, "", "",
+"62 03 b5 47 38 d0 12 \tvinserti64x2 $0x12,%xmm24,%zmm25,%zmm26{%k7}",},
+{{0xc4, 0xe3, 0x7d, 0x39, 0xe6, 0x05, }, 6, 0, "", "",
+"c4 e3 7d 39 e6 05    \tvextracti128 $0x5,%ymm4,%xmm6",},
+{{0x62, 0x03, 0x7d, 0x4f, 0x39, 0xca, 0x12, }, 7, 0, "", "",
+"62 03 7d 4f 39 ca 12 \tvextracti32x4 $0x12,%zmm25,%xmm26{%k7}",},
+{{0x62, 0x03, 0xfd, 0x4f, 0x39, 0xca, 0x12, }, 7, 0, "", "",
+"62 03 fd 4f 39 ca 12 \tvextracti64x2 $0x12,%zmm25,%xmm26{%k7}",},
+{{0x62, 0x03, 0x15, 0x47, 0x3a, 0xf4, 0x12, }, 7, 0, "", "",
+"62 03 15 47 3a f4 12 \tvinserti32x8 $0x12,%ymm28,%zmm29,%zmm30{%k7}",},
+{{0x62, 0x03, 0xad, 0x47, 0x3a, 0xd9, 0x12, }, 7, 0, "", "",
+"62 03 ad 47 3a d9 12 \tvinserti64x4 $0x12,%ymm25,%zmm26,%zmm27{%k7}",},
+{{0x62, 0x03, 0x7d, 0x4f, 0x3b, 0xee, 0x12, }, 7, 0, "", "",
+"62 03 7d 4f 3b ee 12 \tvextracti32x8 $0x12,%zmm29,%ymm30{%k7}",},
+{{0x62, 0x03, 0xfd, 0x4f, 0x3b, 0xd3, 0x12, }, 7, 0, "", "",
+"62 03 fd 4f 3b d3 12 \tvextracti64x4 $0x12,%zmm26,%ymm27{%k7}",},
+{{0x62, 0x93, 0x0d, 0x40, 0x3e, 0xed, 0x12, }, 7, 0, "", "",
+"62 93 0d 40 3e ed 12 \tvpcmpub $0x12,%zmm29,%zmm30,%k5",},
+{{0x62, 0x93, 0xa5, 0x40, 0x3e, 0xea, 0x12, }, 7, 0, "", "",
+"62 93 a5 40 3e ea 12 \tvpcmpuw $0x12,%zmm26,%zmm27,%k5",},
+{{0x62, 0x93, 0x0d, 0x40, 0x3f, 0xed, 0x12, }, 7, 0, "", "",
+"62 93 0d 40 3f ed 12 \tvpcmpb $0x12,%zmm29,%zmm30,%k5",},
+{{0x62, 0x93, 0xa5, 0x40, 0x3f, 0xea, 0x12, }, 7, 0, "", "",
+"62 93 a5 40 3f ea 12 \tvpcmpw $0x12,%zmm26,%zmm27,%k5",},
+{{0xc4, 0xe3, 0x4d, 0x42, 0xd4, 0x05, }, 6, 0, "", "",
+"c4 e3 4d 42 d4 05    \tvmpsadbw $0x5,%ymm4,%ymm6,%ymm2",},
+{{0x62, 0xf3, 0x55, 0x48, 0x42, 0xf4, 0x12, }, 7, 0, "", "",
+"62 f3 55 48 42 f4 12 \tvdbpsadbw $0x12,%zmm4,%zmm5,%zmm6",},
+{{0x62, 0x03, 0x2d, 0x40, 0x43, 0xd9, 0x12, }, 7, 0, "", "",
+"62 03 2d 40 43 d9 12 \tvshufi32x4 $0x12,%zmm25,%zmm26,%zmm27",},
+{{0x62, 0x03, 0x95, 0x40, 0x43, 0xf4, 0x12, }, 7, 0, "", "",
+"62 03 95 40 43 f4 12 \tvshufi64x2 $0x12,%zmm28,%zmm29,%zmm30",},
+{{0x62, 0x03, 0x2d, 0x40, 0x50, 0xd9, 0x12, }, 7, 0, "", "",
+"62 03 2d 40 50 d9 12 \tvrangeps $0x12,%zmm25,%zmm26,%zmm27",},
+{{0x62, 0x03, 0x95, 0x40, 0x50, 0xf4, 0x12, }, 7, 0, "", "",
+"62 03 95 40 50 f4 12 \tvrangepd $0x12,%zmm28,%zmm29,%zmm30",},
+{{0x62, 0x03, 0x2d, 0x00, 0x51, 0xd9, 0x12, }, 7, 0, "", "",
+"62 03 2d 00 51 d9 12 \tvrangess $0x12,%xmm25,%xmm26,%xmm27",},
+{{0x62, 0x03, 0x95, 0x00, 0x51, 0xf4, 0x12, }, 7, 0, "", "",
+"62 03 95 00 51 f4 12 \tvrangesd $0x12,%xmm28,%xmm29,%xmm30",},
+{{0x62, 0x03, 0x15, 0x40, 0x54, 0xf4, 0x12, }, 7, 0, "", "",
+"62 03 15 40 54 f4 12 \tvfixupimmps $0x12,%zmm28,%zmm29,%zmm30",},
+{{0x62, 0x03, 0xad, 0x40, 0x54, 0xd9, 0x12, }, 7, 0, "", "",
+"62 03 ad 40 54 d9 12 \tvfixupimmpd $0x12,%zmm25,%zmm26,%zmm27",},
+{{0x62, 0x03, 0x15, 0x07, 0x55, 0xf4, 0x12, }, 7, 0, "", "",
+"62 03 15 07 55 f4 12 \tvfixupimmss $0x12,%xmm28,%xmm29,%xmm30{%k7}",},
+{{0x62, 0x03, 0xad, 0x07, 0x55, 0xd9, 0x12, }, 7, 0, "", "",
+"62 03 ad 07 55 d9 12 \tvfixupimmsd $0x12,%xmm25,%xmm26,%xmm27{%k7}",},
+{{0x62, 0x03, 0x7d, 0x48, 0x56, 0xda, 0x12, }, 7, 0, "", "",
+"62 03 7d 48 56 da 12 \tvreduceps $0x12,%zmm26,%zmm27",},
+{{0x62, 0x03, 0xfd, 0x48, 0x56, 0xf5, 0x12, }, 7, 0, "", "",
+"62 03 fd 48 56 f5 12 \tvreducepd $0x12,%zmm29,%zmm30",},
+{{0x62, 0x03, 0x2d, 0x00, 0x57, 0xd9, 0x12, }, 7, 0, "", "",
+"62 03 2d 00 57 d9 12 \tvreducess $0x12,%xmm25,%xmm26,%xmm27",},
+{{0x62, 0x03, 0x95, 0x00, 0x57, 0xf4, 0x12, }, 7, 0, "", "",
+"62 03 95 00 57 f4 12 \tvreducesd $0x12,%xmm28,%xmm29,%xmm30",},
+{{0x62, 0x93, 0x7d, 0x48, 0x66, 0xeb, 0x12, }, 7, 0, "", "",
+"62 93 7d 48 66 eb 12 \tvfpclassps $0x12,%zmm27,%k5",},
+{{0x62, 0x93, 0xfd, 0x48, 0x66, 0xee, 0x12, }, 7, 0, "", "",
+"62 93 fd 48 66 ee 12 \tvfpclasspd $0x12,%zmm30,%k5",},
+{{0x62, 0x93, 0x7d, 0x08, 0x67, 0xeb, 0x12, }, 7, 0, "", "",
+"62 93 7d 08 67 eb 12 \tvfpclassss $0x12,%xmm27,%k5",},
+{{0x62, 0x93, 0xfd, 0x08, 0x67, 0xee, 0x12, }, 7, 0, "", "",
+"62 93 fd 08 67 ee 12 \tvfpclasssd $0x12,%xmm30,%k5",},
+{{0x62, 0x91, 0x2d, 0x40, 0x72, 0xc1, 0x12, }, 7, 0, "", "",
+"62 91 2d 40 72 c1 12 \tvprord $0x12,%zmm25,%zmm26",},
+{{0x62, 0x91, 0xad, 0x40, 0x72, 0xc1, 0x12, }, 7, 0, "", "",
+"62 91 ad 40 72 c1 12 \tvprorq $0x12,%zmm25,%zmm26",},
+{{0x62, 0x91, 0x0d, 0x40, 0x72, 0xcd, 0x12, }, 7, 0, "", "",
+"62 91 0d 40 72 cd 12 \tvprold $0x12,%zmm29,%zmm30",},
+{{0x62, 0x91, 0x8d, 0x40, 0x72, 0xcd, 0x12, }, 7, 0, "", "",
+"62 91 8d 40 72 cd 12 \tvprolq $0x12,%zmm29,%zmm30",},
+{{0x0f, 0x72, 0xe6, 0x02, }, 4, 0, "", "",
+"0f 72 e6 02          \tpsrad  $0x2,%mm6",},
+{{0xc5, 0xed, 0x72, 0xe6, 0x05, }, 5, 0, "", "",
+"c5 ed 72 e6 05       \tvpsrad $0x5,%ymm6,%ymm2",},
+{{0x62, 0x91, 0x4d, 0x40, 0x72, 0xe2, 0x05, }, 7, 0, "", "",
+"62 91 4d 40 72 e2 05 \tvpsrad $0x5,%zmm26,%zmm22",},
+{{0x62, 0x91, 0xcd, 0x40, 0x72, 0xe2, 0x05, }, 7, 0, "", "",
+"62 91 cd 40 72 e2 05 \tvpsraq $0x5,%zmm26,%zmm22",},
+{{0x62, 0x92, 0x7d, 0x41, 0xc6, 0x8c, 0xfe, 0x7b, 0x00, 0x00, 0x00, }, 11, 0, "", "",
+"62 92 7d 41 c6 8c fe 7b 00 00 00 \tvgatherpf0dps 0x7b(%r14,%zmm31,8){%k1}",},
+{{0x62, 0x92, 0xfd, 0x41, 0xc6, 0x8c, 0xfe, 0x7b, 0x00, 0x00, 0x00, }, 11, 0, "", "",
+"62 92 fd 41 c6 8c fe 7b 00 00 00 \tvgatherpf0dpd 0x7b(%r14,%ymm31,8){%k1}",},
+{{0x62, 0x92, 0x7d, 0x41, 0xc6, 0x94, 0xfe, 0x7b, 0x00, 0x00, 0x00, }, 11, 0, "", "",
+"62 92 7d 41 c6 94 fe 7b 00 00 00 \tvgatherpf1dps 0x7b(%r14,%zmm31,8){%k1}",},
+{{0x62, 0x92, 0xfd, 0x41, 0xc6, 0x94, 0xfe, 0x7b, 0x00, 0x00, 0x00, }, 11, 0, "", "",
+"62 92 fd 41 c6 94 fe 7b 00 00 00 \tvgatherpf1dpd 0x7b(%r14,%ymm31,8){%k1}",},
+{{0x62, 0x92, 0x7d, 0x41, 0xc6, 0xac, 0xfe, 0x7b, 0x00, 0x00, 0x00, }, 11, 0, "", "",
+"62 92 7d 41 c6 ac fe 7b 00 00 00 \tvscatterpf0dps 0x7b(%r14,%zmm31,8){%k1}",},
+{{0x62, 0x92, 0xfd, 0x41, 0xc6, 0xac, 0xfe, 0x7b, 0x00, 0x00, 0x00, }, 11, 0, "", "",
+"62 92 fd 41 c6 ac fe 7b 00 00 00 \tvscatterpf0dpd 0x7b(%r14,%ymm31,8){%k1}",},
+{{0x62, 0x92, 0x7d, 0x41, 0xc6, 0xb4, 0xfe, 0x7b, 0x00, 0x00, 0x00, }, 11, 0, "", "",
+"62 92 7d 41 c6 b4 fe 7b 00 00 00 \tvscatterpf1dps 0x7b(%r14,%zmm31,8){%k1}",},
+{{0x62, 0x92, 0xfd, 0x41, 0xc6, 0xb4, 0xfe, 0x7b, 0x00, 0x00, 0x00, }, 11, 0, "", "",
+"62 92 fd 41 c6 b4 fe 7b 00 00 00 \tvscatterpf1dpd 0x7b(%r14,%ymm31,8){%k1}",},
+{{0x62, 0x92, 0x7d, 0x41, 0xc7, 0x8c, 0xfe, 0x7b, 0x00, 0x00, 0x00, }, 11, 0, "", "",
+"62 92 7d 41 c7 8c fe 7b 00 00 00 \tvgatherpf0qps 0x7b(%r14,%zmm31,8){%k1}",},
+{{0x62, 0x92, 0xfd, 0x41, 0xc7, 0x8c, 0xfe, 0x7b, 0x00, 0x00, 0x00, }, 11, 0, "", "",
+"62 92 fd 41 c7 8c fe 7b 00 00 00 \tvgatherpf0qpd 0x7b(%r14,%zmm31,8){%k1}",},
+{{0x62, 0x92, 0x7d, 0x41, 0xc7, 0x94, 0xfe, 0x7b, 0x00, 0x00, 0x00, }, 11, 0, "", "",
+"62 92 7d 41 c7 94 fe 7b 00 00 00 \tvgatherpf1qps 0x7b(%r14,%zmm31,8){%k1}",},
+{{0x62, 0x92, 0xfd, 0x41, 0xc7, 0x94, 0xfe, 0x7b, 0x00, 0x00, 0x00, }, 11, 0, "", "",
+"62 92 fd 41 c7 94 fe 7b 00 00 00 \tvgatherpf1qpd 0x7b(%r14,%zmm31,8){%k1}",},
+{{0x62, 0x92, 0x7d, 0x41, 0xc7, 0xac, 0xfe, 0x7b, 0x00, 0x00, 0x00, }, 11, 0, "", "",
+"62 92 7d 41 c7 ac fe 7b 00 00 00 \tvscatterpf0qps 0x7b(%r14,%zmm31,8){%k1}",},
+{{0x62, 0x92, 0xfd, 0x41, 0xc7, 0xac, 0xfe, 0x7b, 0x00, 0x00, 0x00, }, 11, 0, "", "",
+"62 92 fd 41 c7 ac fe 7b 00 00 00 \tvscatterpf0qpd 0x7b(%r14,%zmm31,8){%k1}",},
+{{0x62, 0x92, 0x7d, 0x41, 0xc7, 0xb4, 0xfe, 0x7b, 0x00, 0x00, 0x00, }, 11, 0, "", "",
+"62 92 7d 41 c7 b4 fe 7b 00 00 00 \tvscatterpf1qps 0x7b(%r14,%zmm31,8){%k1}",},
+{{0x62, 0x92, 0xfd, 0x41, 0xc7, 0xb4, 0xfe, 0x7b, 0x00, 0x00, 0x00, }, 11, 0, "", "",
+"62 92 fd 41 c7 b4 fe 7b 00 00 00 \tvscatterpf1qpd 0x7b(%r14,%zmm31,8){%k1}",},
+{{0x62, 0x01, 0x95, 0x40, 0x58, 0xf4, }, 6, 0, "", "",
+"62 01 95 40 58 f4    \tvaddpd %zmm28,%zmm29,%zmm30",},
+{{0x62, 0x01, 0x95, 0x47, 0x58, 0xf4, }, 6, 0, "", "",
+"62 01 95 47 58 f4    \tvaddpd %zmm28,%zmm29,%zmm30{%k7}",},
+{{0x62, 0x01, 0x95, 0xc7, 0x58, 0xf4, }, 6, 0, "", "",
+"62 01 95 c7 58 f4    \tvaddpd %zmm28,%zmm29,%zmm30{%k7}{z}",},
+{{0x62, 0x01, 0x95, 0x10, 0x58, 0xf4, }, 6, 0, "", "",
+"62 01 95 10 58 f4    \tvaddpd {rn-sae},%zmm28,%zmm29,%zmm30",},
+{{0x62, 0x01, 0x95, 0x50, 0x58, 0xf4, }, 6, 0, "", "",
+"62 01 95 50 58 f4    \tvaddpd {ru-sae},%zmm28,%zmm29,%zmm30",},
+{{0x62, 0x01, 0x95, 0x30, 0x58, 0xf4, }, 6, 0, "", "",
+"62 01 95 30 58 f4    \tvaddpd {rd-sae},%zmm28,%zmm29,%zmm30",},
+{{0x62, 0x01, 0x95, 0x70, 0x58, 0xf4, }, 6, 0, "", "",
+"62 01 95 70 58 f4    \tvaddpd {rz-sae},%zmm28,%zmm29,%zmm30",},
+{{0x62, 0x61, 0x95, 0x40, 0x58, 0x31, }, 6, 0, "", "",
+"62 61 95 40 58 31    \tvaddpd (%rcx),%zmm29,%zmm30",},
+{{0x62, 0x21, 0x95, 0x40, 0x58, 0xb4, 0xf0, 0x23, 0x01, 0x00, 0x00, }, 11, 0, "", "",
+"62 21 95 40 58 b4 f0 23 01 00 00 \tvaddpd 0x123(%rax,%r14,8),%zmm29,%zmm30",},
+{{0x62, 0x61, 0x95, 0x50, 0x58, 0x31, }, 6, 0, "", "",
+"62 61 95 50 58 31    \tvaddpd (%rcx){1to8},%zmm29,%zmm30",},
+{{0x62, 0x61, 0x95, 0x40, 0x58, 0x72, 0x7f, }, 7, 0, "", "",
+"62 61 95 40 58 72 7f \tvaddpd 0x1fc0(%rdx),%zmm29,%zmm30",},
+{{0x62, 0x61, 0x95, 0x50, 0x58, 0x72, 0x7f, }, 7, 0, "", "",
+"62 61 95 50 58 72 7f \tvaddpd 0x3f8(%rdx){1to8},%zmm29,%zmm30",},
+{{0x62, 0xf1, 0x0c, 0x50, 0xc2, 0x6a, 0x7f, 0x08, }, 8, 0, "", "",
+"62 f1 0c 50 c2 6a 7f 08 \tvcmpeq_uqps 0x1fc(%rdx){1to16},%zmm30,%k5",},
+{{0x62, 0xb1, 0x97, 0x07, 0xc2, 0xac, 0xf0, 0x23, 0x01, 0x00, 0x00, 0x01, }, 12, 0, "", "",
+"62 b1 97 07 c2 ac f0 23 01 00 00 01 \tvcmpltsd 0x123(%rax,%r14,8),%xmm29,%k5{%k7}",},
+{{0x62, 0x91, 0x97, 0x17, 0xc2, 0xec, 0x02, }, 7, 0, "", "",
+"62 91 97 17 c2 ec 02 \tvcmplesd {sae},%xmm28,%xmm29,%k5{%k7}",},
+{{0x62, 0x23, 0x15, 0x07, 0x27, 0xb4, 0xf0, 0x23, 0x01, 0x00, 0x00, 0x5b, }, 12, 0, "", "",
+"62 23 15 07 27 b4 f0 23 01 00 00 5b \tvgetmantss $0x5b,0x123(%rax,%r14,8),%xmm29,%xmm30{%k7}",},
 {{0xf3, 0x0f, 0x1b, 0x00, }, 4, 0, "", "",
 "f3 0f 1b 00          \tbndmk  (%rax),%bnd0",},
 {{0xf3, 0x41, 0x0f, 0x1b, 0x00, }, 5, 0, "", "",
@@ -325,19 +1257,19 @@
 {{0x0f, 0x1b, 0x84, 0x08, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
 "0f 1b 84 08 78 56 34 12 \tbndstx %bnd0,0x12345678(%rax,%rcx,1)",},
 {{0xf2, 0xe8, 0x00, 0x00, 0x00, 0x00, }, 6, 0, "call", "unconditional",
-"f2 e8 00 00 00 00    \tbnd callq 3f6 <main+0x3f6>",},
+"f2 e8 00 00 00 00    \tbnd callq f22 <main+0xf22>",},
 {{0x67, 0xf2, 0xff, 0x10, }, 4, 0, "call", "indirect",
 "67 f2 ff 10          \tbnd callq *(%eax)",},
 {{0xf2, 0xc3, }, 2, 0, "ret", "indirect",
 "f2 c3                \tbnd retq ",},
 {{0xf2, 0xe9, 0x00, 0x00, 0x00, 0x00, }, 6, 0, "jmp", "unconditional",
-"f2 e9 00 00 00 00    \tbnd jmpq 402 <main+0x402>",},
+"f2 e9 00 00 00 00    \tbnd jmpq f2e <main+0xf2e>",},
 {{0xf2, 0xe9, 0x00, 0x00, 0x00, 0x00, }, 6, 0, "jmp", "unconditional",
-"f2 e9 00 00 00 00    \tbnd jmpq 408 <main+0x408>",},
+"f2 e9 00 00 00 00    \tbnd jmpq f34 <main+0xf34>",},
 {{0x67, 0xf2, 0xff, 0x21, }, 4, 0, "jmp", "indirect",
 "67 f2 ff 21          \tbnd jmpq *(%ecx)",},
 {{0xf2, 0x0f, 0x85, 0x00, 0x00, 0x00, 0x00, }, 7, 0, "jcc", "conditional",
-"f2 0f 85 00 00 00 00 \tbnd jne 413 <main+0x413>",},
+"f2 0f 85 00 00 00 00 \tbnd jne f3f <main+0xf3f>",},
 {{0x0f, 0x3a, 0xcc, 0xc1, 0x00, }, 5, 0, "", "",
 "0f 3a cc c1 00       \tsha1rnds4 $0x0,%xmm1,%xmm0",},
 {{0x0f, 0x3a, 0xcc, 0xd7, 0x91, }, 5, 0, "", "",
--- zfcpdump-kernel-4.4.orig/tools/perf/arch/x86/tests/insn-x86-dat-src.c
+++ zfcpdump-kernel-4.4/tools/perf/arch/x86/tests/insn-x86-dat-src.c
@@ -19,457 +19,2246 @@ int main(void)
 	/* Following line is a marker for the awk script - do not change */
 	asm volatile("rdtsc"); /* Start here */
 
+	/* Test fix for vcvtph2ps in x86-opcode-map.txt */
+
+	asm volatile("vcvtph2ps %xmm3,%ymm5");
+
 #ifdef __x86_64__
 
-	/* bndmk m64, bnd */
+	/* AVX-512: Instructions with the same op codes as Mask Instructions  */
 
-	asm volatile("bndmk (%rax), %bnd0");
-	asm volatile("bndmk (%r8), %bnd0");
-	asm volatile("bndmk (0x12345678), %bnd0");
-	asm volatile("bndmk (%rax), %bnd3");
-	asm volatile("bndmk (%rcx,%rax,1), %bnd0");
-	asm volatile("bndmk 0x12345678(,%rax,1), %bnd0");
-	asm volatile("bndmk (%rax,%rcx,1), %bnd0");
-	asm volatile("bndmk (%rax,%rcx,8), %bnd0");
-	asm volatile("bndmk 0x12(%rax), %bnd0");
-	asm volatile("bndmk 0x12(%rbp), %bnd0");
-	asm volatile("bndmk 0x12(%rcx,%rax,1), %bnd0");
-	asm volatile("bndmk 0x12(%rbp,%rax,1), %bnd0");
-	asm volatile("bndmk 0x12(%rax,%rcx,1), %bnd0");
-	asm volatile("bndmk 0x12(%rax,%rcx,8), %bnd0");
-	asm volatile("bndmk 0x12345678(%rax), %bnd0");
-	asm volatile("bndmk 0x12345678(%rbp), %bnd0");
-	asm volatile("bndmk 0x12345678(%rcx,%rax,1), %bnd0");
-	asm volatile("bndmk 0x12345678(%rbp,%rax,1), %bnd0");
-	asm volatile("bndmk 0x12345678(%rax,%rcx,1), %bnd0");
-	asm volatile("bndmk 0x12345678(%rax,%rcx,8), %bnd0");
+	asm volatile("cmovno %rax,%rbx");
+	asm volatile("cmovno 0x12345678(%rax),%rcx");
+	asm volatile("cmovno 0x12345678(%rax),%cx");
 
-	/* bndcl r/m64, bnd */
+	asm volatile("cmove  %rax,%rbx");
+	asm volatile("cmove 0x12345678(%rax),%rcx");
+	asm volatile("cmove 0x12345678(%rax),%cx");
 
-	asm volatile("bndcl (%rax), %bnd0");
-	asm volatile("bndcl (%r8), %bnd0");
-	asm volatile("bndcl (0x12345678), %bnd0");
-	asm volatile("bndcl (%rax), %bnd3");
-	asm volatile("bndcl (%rcx,%rax,1), %bnd0");
-	asm volatile("bndcl 0x12345678(,%rax,1), %bnd0");
-	asm volatile("bndcl (%rax,%rcx,1), %bnd0");
-	asm volatile("bndcl (%rax,%rcx,8), %bnd0");
-	asm volatile("bndcl 0x12(%rax), %bnd0");
-	asm volatile("bndcl 0x12(%rbp), %bnd0");
-	asm volatile("bndcl 0x12(%rcx,%rax,1), %bnd0");
-	asm volatile("bndcl 0x12(%rbp,%rax,1), %bnd0");
-	asm volatile("bndcl 0x12(%rax,%rcx,1), %bnd0");
-	asm volatile("bndcl 0x12(%rax,%rcx,8), %bnd0");
-	asm volatile("bndcl 0x12345678(%rax), %bnd0");
-	asm volatile("bndcl 0x12345678(%rbp), %bnd0");
-	asm volatile("bndcl 0x12345678(%rcx,%rax,1), %bnd0");
-	asm volatile("bndcl 0x12345678(%rbp,%rax,1), %bnd0");
-	asm volatile("bndcl 0x12345678(%rax,%rcx,1), %bnd0");
-	asm volatile("bndcl 0x12345678(%rax,%rcx,8), %bnd0");
-	asm volatile("bndcl %rax, %bnd0");
+	asm volatile("seto    0x12345678(%rax)");
+	asm volatile("setno   0x12345678(%rax)");
+	asm volatile("setb    0x12345678(%rax)");
+	asm volatile("setc    0x12345678(%rax)");
+	asm volatile("setnae  0x12345678(%rax)");
+	asm volatile("setae   0x12345678(%rax)");
+	asm volatile("setnb   0x12345678(%rax)");
+	asm volatile("setnc   0x12345678(%rax)");
+	asm volatile("sets    0x12345678(%rax)");
+	asm volatile("setns   0x12345678(%rax)");
 
-	/* bndcu r/m64, bnd */
+	/* AVX-512: Mask Instructions */
 
-	asm volatile("bndcu (%rax), %bnd0");
-	asm volatile("bndcu (%r8), %bnd0");
-	asm volatile("bndcu (0x12345678), %bnd0");
-	asm volatile("bndcu (%rax), %bnd3");
-	asm volatile("bndcu (%rcx,%rax,1), %bnd0");
-	asm volatile("bndcu 0x12345678(,%rax,1), %bnd0");
-	asm volatile("bndcu (%rax,%rcx,1), %bnd0");
-	asm volatile("bndcu (%rax,%rcx,8), %bnd0");
-	asm volatile("bndcu 0x12(%rax), %bnd0");
-	asm volatile("bndcu 0x12(%rbp), %bnd0");
-	asm volatile("bndcu 0x12(%rcx,%rax,1), %bnd0");
-	asm volatile("bndcu 0x12(%rbp,%rax,1), %bnd0");
-	asm volatile("bndcu 0x12(%rax,%rcx,1), %bnd0");
-	asm volatile("bndcu 0x12(%rax,%rcx,8), %bnd0");
-	asm volatile("bndcu 0x12345678(%rax), %bnd0");
-	asm volatile("bndcu 0x12345678(%rbp), %bnd0");
-	asm volatile("bndcu 0x12345678(%rcx,%rax,1), %bnd0");
-	asm volatile("bndcu 0x12345678(%rbp,%rax,1), %bnd0");
-	asm volatile("bndcu 0x12345678(%rax,%rcx,1), %bnd0");
-	asm volatile("bndcu 0x12345678(%rax,%rcx,8), %bnd0");
-	asm volatile("bndcu %rax, %bnd0");
+	asm volatile("kandw  %k7,%k6,%k5");
+	asm volatile("kandq  %k7,%k6,%k5");
+	asm volatile("kandb  %k7,%k6,%k5");
+	asm volatile("kandd  %k7,%k6,%k5");
 
-	/* bndcn r/m64, bnd */
+	asm volatile("kandnw  %k7,%k6,%k5");
+	asm volatile("kandnq  %k7,%k6,%k5");
+	asm volatile("kandnb  %k7,%k6,%k5");
+	asm volatile("kandnd  %k7,%k6,%k5");
 
-	asm volatile("bndcn (%rax), %bnd0");
-	asm volatile("bndcn (%r8), %bnd0");
-	asm volatile("bndcn (0x12345678), %bnd0");
-	asm volatile("bndcn (%rax), %bnd3");
-	asm volatile("bndcn (%rcx,%rax,1), %bnd0");
-	asm volatile("bndcn 0x12345678(,%rax,1), %bnd0");
-	asm volatile("bndcn (%rax,%rcx,1), %bnd0");
-	asm volatile("bndcn (%rax,%rcx,8), %bnd0");
-	asm volatile("bndcn 0x12(%rax), %bnd0");
-	asm volatile("bndcn 0x12(%rbp), %bnd0");
-	asm volatile("bndcn 0x12(%rcx,%rax,1), %bnd0");
-	asm volatile("bndcn 0x12(%rbp,%rax,1), %bnd0");
-	asm volatile("bndcn 0x12(%rax,%rcx,1), %bnd0");
-	asm volatile("bndcn 0x12(%rax,%rcx,8), %bnd0");
-	asm volatile("bndcn 0x12345678(%rax), %bnd0");
-	asm volatile("bndcn 0x12345678(%rbp), %bnd0");
-	asm volatile("bndcn 0x12345678(%rcx,%rax,1), %bnd0");
-	asm volatile("bndcn 0x12345678(%rbp,%rax,1), %bnd0");
-	asm volatile("bndcn 0x12345678(%rax,%rcx,1), %bnd0");
-	asm volatile("bndcn 0x12345678(%rax,%rcx,8), %bnd0");
-	asm volatile("bndcn %rax, %bnd0");
+	asm volatile("knotw  %k7,%k6");
+	asm volatile("knotq  %k7,%k6");
+	asm volatile("knotb  %k7,%k6");
+	asm volatile("knotd  %k7,%k6");
 
-	/* bndmov m128, bnd */
+	asm volatile("korw  %k7,%k6,%k5");
+	asm volatile("korq  %k7,%k6,%k5");
+	asm volatile("korb  %k7,%k6,%k5");
+	asm volatile("kord  %k7,%k6,%k5");
 
-	asm volatile("bndmov (%rax), %bnd0");
-	asm volatile("bndmov (%r8), %bnd0");
-	asm volatile("bndmov (0x12345678), %bnd0");
-	asm volatile("bndmov (%rax), %bnd3");
-	asm volatile("bndmov (%rcx,%rax,1), %bnd0");
-	asm volatile("bndmov 0x12345678(,%rax,1), %bnd0");
-	asm volatile("bndmov (%rax,%rcx,1), %bnd0");
-	asm volatile("bndmov (%rax,%rcx,8), %bnd0");
-	asm volatile("bndmov 0x12(%rax), %bnd0");
-	asm volatile("bndmov 0x12(%rbp), %bnd0");
-	asm volatile("bndmov 0x12(%rcx,%rax,1), %bnd0");
-	asm volatile("bndmov 0x12(%rbp,%rax,1), %bnd0");
-	asm volatile("bndmov 0x12(%rax,%rcx,1), %bnd0");
-	asm volatile("bndmov 0x12(%rax,%rcx,8), %bnd0");
-	asm volatile("bndmov 0x12345678(%rax), %bnd0");
-	asm volatile("bndmov 0x12345678(%rbp), %bnd0");
-	asm volatile("bndmov 0x12345678(%rcx,%rax,1), %bnd0");
-	asm volatile("bndmov 0x12345678(%rbp,%rax,1), %bnd0");
-	asm volatile("bndmov 0x12345678(%rax,%rcx,1), %bnd0");
-	asm volatile("bndmov 0x12345678(%rax,%rcx,8), %bnd0");
+	asm volatile("kxnorw  %k7,%k6,%k5");
+	asm volatile("kxnorq  %k7,%k6,%k5");
+	asm volatile("kxnorb  %k7,%k6,%k5");
+	asm volatile("kxnord  %k7,%k6,%k5");
 
-	/* bndmov bnd, m128 */
+	asm volatile("kxorw  %k7,%k6,%k5");
+	asm volatile("kxorq  %k7,%k6,%k5");
+	asm volatile("kxorb  %k7,%k6,%k5");
+	asm volatile("kxord  %k7,%k6,%k5");
 
-	asm volatile("bndmov %bnd0, (%rax)");
-	asm volatile("bndmov %bnd0, (%r8)");
-	asm volatile("bndmov %bnd0, (0x12345678)");
-	asm volatile("bndmov %bnd3, (%rax)");
-	asm volatile("bndmov %bnd0, (%rcx,%rax,1)");
-	asm volatile("bndmov %bnd0, 0x12345678(,%rax,1)");
-	asm volatile("bndmov %bnd0, (%rax,%rcx,1)");
-	asm volatile("bndmov %bnd0, (%rax,%rcx,8)");
-	asm volatile("bndmov %bnd0, 0x12(%rax)");
-	asm volatile("bndmov %bnd0, 0x12(%rbp)");
-	asm volatile("bndmov %bnd0, 0x12(%rcx,%rax,1)");
-	asm volatile("bndmov %bnd0, 0x12(%rbp,%rax,1)");
-	asm volatile("bndmov %bnd0, 0x12(%rax,%rcx,1)");
-	asm volatile("bndmov %bnd0, 0x12(%rax,%rcx,8)");
-	asm volatile("bndmov %bnd0, 0x12345678(%rax)");
-	asm volatile("bndmov %bnd0, 0x12345678(%rbp)");
-	asm volatile("bndmov %bnd0, 0x12345678(%rcx,%rax,1)");
-	asm volatile("bndmov %bnd0, 0x12345678(%rbp,%rax,1)");
-	asm volatile("bndmov %bnd0, 0x12345678(%rax,%rcx,1)");
-	asm volatile("bndmov %bnd0, 0x12345678(%rax,%rcx,8)");
+	asm volatile("kaddw  %k7,%k6,%k5");
+	asm volatile("kaddq  %k7,%k6,%k5");
+	asm volatile("kaddb  %k7,%k6,%k5");
+	asm volatile("kaddd  %k7,%k6,%k5");
 
-	/* bndmov bnd2, bnd1 */
+	asm volatile("kunpckbw %k7,%k6,%k5");
+	asm volatile("kunpckwd %k7,%k6,%k5");
+	asm volatile("kunpckdq %k7,%k6,%k5");
 
-	asm volatile("bndmov %bnd0, %bnd1");
-	asm volatile("bndmov %bnd1, %bnd0");
+	asm volatile("kmovw  %k6,%k5");
+	asm volatile("kmovw  (%rcx),%k5");
+	asm volatile("kmovw  0x123(%rax,%r14,8),%k5");
+	asm volatile("kmovw  %k5,(%rcx)");
+	asm volatile("kmovw  %k5,0x123(%rax,%r14,8)");
+	asm volatile("kmovw  %eax,%k5");
+	asm volatile("kmovw  %ebp,%k5");
+	asm volatile("kmovw  %r13d,%k5");
+	asm volatile("kmovw  %k5,%eax");
+	asm volatile("kmovw  %k5,%ebp");
+	asm volatile("kmovw  %k5,%r13d");
 
-	/* bndldx mib, bnd */
+	asm volatile("kmovq  %k6,%k5");
+	asm volatile("kmovq  (%rcx),%k5");
+	asm volatile("kmovq  0x123(%rax,%r14,8),%k5");
+	asm volatile("kmovq  %k5,(%rcx)");
+	asm volatile("kmovq  %k5,0x123(%rax,%r14,8)");
+	asm volatile("kmovq  %rax,%k5");
+	asm volatile("kmovq  %rbp,%k5");
+	asm volatile("kmovq  %r13,%k5");
+	asm volatile("kmovq  %k5,%rax");
+	asm volatile("kmovq  %k5,%rbp");
+	asm volatile("kmovq  %k5,%r13");
 
-	asm volatile("bndldx (%rax), %bnd0");
-	asm volatile("bndldx (%r8), %bnd0");
-	asm volatile("bndldx (0x12345678), %bnd0");
-	asm volatile("bndldx (%rax), %bnd3");
-	asm volatile("bndldx (%rcx,%rax,1), %bnd0");
-	asm volatile("bndldx 0x12345678(,%rax,1), %bnd0");
-	asm volatile("bndldx (%rax,%rcx,1), %bnd0");
-	asm volatile("bndldx 0x12(%rax), %bnd0");
-	asm volatile("bndldx 0x12(%rbp), %bnd0");
-	asm volatile("bndldx 0x12(%rcx,%rax,1), %bnd0");
-	asm volatile("bndldx 0x12(%rbp,%rax,1), %bnd0");
-	asm volatile("bndldx 0x12(%rax,%rcx,1), %bnd0");
-	asm volatile("bndldx 0x12345678(%rax), %bnd0");
-	asm volatile("bndldx 0x12345678(%rbp), %bnd0");
-	asm volatile("bndldx 0x12345678(%rcx,%rax,1), %bnd0");
-	asm volatile("bndldx 0x12345678(%rbp,%rax,1), %bnd0");
-	asm volatile("bndldx 0x12345678(%rax,%rcx,1), %bnd0");
+	asm volatile("kmovb  %k6,%k5");
+	asm volatile("kmovb  (%rcx),%k5");
+	asm volatile("kmovb  0x123(%rax,%r14,8),%k5");
+	asm volatile("kmovb  %k5,(%rcx)");
+	asm volatile("kmovb  %k5,0x123(%rax,%r14,8)");
+	asm volatile("kmovb  %eax,%k5");
+	asm volatile("kmovb  %ebp,%k5");
+	asm volatile("kmovb  %r13d,%k5");
+	asm volatile("kmovb  %k5,%eax");
+	asm volatile("kmovb  %k5,%ebp");
+	asm volatile("kmovb  %k5,%r13d");
+
+	asm volatile("kmovd  %k6,%k5");
+	asm volatile("kmovd  (%rcx),%k5");
+	asm volatile("kmovd  0x123(%rax,%r14,8),%k5");
+	asm volatile("kmovd  %k5,(%rcx)");
+	asm volatile("kmovd  %k5,0x123(%rax,%r14,8)");
+	asm volatile("kmovd  %eax,%k5");
+	asm volatile("kmovd  %ebp,%k5");
+	asm volatile("kmovd  %r13d,%k5");
+	asm volatile("kmovd  %k5,%eax");
+	asm volatile("kmovd  %k5,%ebp");
+	asm volatile("kmovd %k5,%r13d");
+
+	asm volatile("kortestw %k6,%k5");
+	asm volatile("kortestq %k6,%k5");
+	asm volatile("kortestb %k6,%k5");
+	asm volatile("kortestd %k6,%k5");
+
+	asm volatile("ktestw %k6,%k5");
+	asm volatile("ktestq %k6,%k5");
+	asm volatile("ktestb %k6,%k5");
+	asm volatile("ktestd %k6,%k5");
+
+	asm volatile("kshiftrw $0x12,%k6,%k5");
+	asm volatile("kshiftrq $0x5b,%k6,%k5");
+	asm volatile("kshiftlw $0x12,%k6,%k5");
+	asm volatile("kshiftlq $0x5b,%k6,%k5");
+
+	/* AVX-512: Op code 0f 5b */
+	asm volatile("vcvtdq2ps %xmm5,%xmm6");
+	asm volatile("vcvtqq2ps %zmm29,%ymm6{%k7}");
+	asm volatile("vcvtps2dq %xmm5,%xmm6");
+	asm volatile("vcvttps2dq %xmm5,%xmm6");
+
+	/* AVX-512: Op code 0f 6f */
+
+	asm volatile("movq   %mm0,%mm4");
+	asm volatile("vmovdqa %ymm4,%ymm6");
+	asm volatile("vmovdqa32 %zmm25,%zmm26");
+	asm volatile("vmovdqa64 %zmm25,%zmm26");
+	asm volatile("vmovdqu %ymm4,%ymm6");
+	asm volatile("vmovdqu32 %zmm29,%zmm30");
+	asm volatile("vmovdqu64 %zmm25,%zmm26");
+	asm volatile("vmovdqu8 %zmm29,%zmm30");
+	asm volatile("vmovdqu16 %zmm25,%zmm26");
+
+	/* AVX-512: Op code 0f 78 */
+
+	asm volatile("vmread %rax,%rbx");
+	asm volatile("vcvttps2udq %zmm25,%zmm26");
+	asm volatile("vcvttpd2udq %zmm29,%ymm6{%k7}");
+	asm volatile("vcvttsd2usi %xmm6,%rax");
+	asm volatile("vcvttss2usi %xmm6,%rax");
+	asm volatile("vcvttps2uqq %ymm5,%zmm26{%k7}");
+	asm volatile("vcvttpd2uqq %zmm29,%zmm30");
+
+	/* AVX-512: Op code 0f 79 */
+
+	asm volatile("vmwrite %rax,%rbx");
+	asm volatile("vcvtps2udq %zmm25,%zmm26");
+	asm volatile("vcvtpd2udq %zmm29,%ymm6{%k7}");
+	asm volatile("vcvtsd2usi %xmm6,%rax");
+	asm volatile("vcvtss2usi %xmm6,%rax");
+	asm volatile("vcvtps2uqq %ymm5,%zmm26{%k7}");
+	asm volatile("vcvtpd2uqq %zmm29,%zmm30");
+
+	/* AVX-512: Op code 0f 7a */
+
+	asm volatile("vcvtudq2pd %ymm5,%zmm29{%k7}");
+	asm volatile("vcvtuqq2pd %zmm25,%zmm26");
+	asm volatile("vcvtudq2ps %zmm29,%zmm30");
+	asm volatile("vcvtuqq2ps %zmm25,%ymm26{%k7}");
+	asm volatile("vcvttps2qq %ymm25,%zmm26{%k7}");
+	asm volatile("vcvttpd2qq %zmm29,%zmm30");
+
+	/* AVX-512: Op code 0f 7b */
+
+	asm volatile("vcvtusi2sd %eax,%xmm5,%xmm6");
+	asm volatile("vcvtusi2ss %eax,%xmm5,%xmm6");
+	asm volatile("vcvtps2qq %ymm5,%zmm26{%k7}");
+	asm volatile("vcvtpd2qq %zmm29,%zmm30");
+
+	/* AVX-512: Op code 0f 7f */
+
+	asm volatile("movq.s  %mm0,%mm4");
+	asm volatile("vmovdqa %ymm8,%ymm6");
+	asm volatile("vmovdqa32.s %zmm25,%zmm26");
+	asm volatile("vmovdqa64.s %zmm25,%zmm26");
+	asm volatile("vmovdqu %ymm8,%ymm6");
+	asm volatile("vmovdqu32.s %zmm25,%zmm26");
+	asm volatile("vmovdqu64.s %zmm25,%zmm26");
+	asm volatile("vmovdqu8.s %zmm30,(%rcx)");
+	asm volatile("vmovdqu16.s %zmm25,%zmm26");
+
+	/* AVX-512: Op code 0f db */
+
+	asm volatile("pand  %mm1,%mm2");
+	asm volatile("pand  %xmm1,%xmm2");
+	asm volatile("vpand  %ymm4,%ymm6,%ymm2");
+	asm volatile("vpandd %zmm24,%zmm25,%zmm26");
+	asm volatile("vpandq %zmm24,%zmm25,%zmm26");
+
+	/* AVX-512: Op code 0f df */
+
+	asm volatile("pandn  %mm1,%mm2");
+	asm volatile("pandn  %xmm1,%xmm2");
+	asm volatile("vpandn %ymm4,%ymm6,%ymm2");
+	asm volatile("vpandnd %zmm24,%zmm25,%zmm26");
+	asm volatile("vpandnq %zmm24,%zmm25,%zmm26");
+
+	/* AVX-512: Op code 0f e6 */
+
+	asm volatile("vcvttpd2dq %xmm1,%xmm2");
+	asm volatile("vcvtdq2pd %xmm5,%xmm6");
+	asm volatile("vcvtdq2pd %ymm5,%zmm26{%k7}");
+	asm volatile("vcvtqq2pd %zmm25,%zmm26");
+	asm volatile("vcvtpd2dq %xmm1,%xmm2");
+
+	/* AVX-512: Op code 0f eb */
+
+	asm volatile("por   %mm4,%mm6");
+	asm volatile("vpor   %ymm4,%ymm6,%ymm2");
+	asm volatile("vpord  %zmm24,%zmm25,%zmm26");
+	asm volatile("vporq  %zmm24,%zmm25,%zmm26");
+
+	/* AVX-512: Op code 0f ef */
+
+	asm volatile("pxor   %mm4,%mm6");
+	asm volatile("vpxor  %ymm4,%ymm6,%ymm2");
+	asm volatile("vpxord %zmm24,%zmm25,%zmm26");
+	asm volatile("vpxorq %zmm24,%zmm25,%zmm26");
+
+	/* AVX-512: Op code 0f 38 10 */
+
+	asm volatile("pblendvb %xmm1,%xmm0");
+	asm volatile("vpsrlvw %zmm27,%zmm28,%zmm29");
+	asm volatile("vpmovuswb %zmm28,%ymm6{%k7}");
+
+	/* AVX-512: Op code 0f 38 11 */
+
+	asm volatile("vpmovusdb %zmm28,%xmm6{%k7}");
+	asm volatile("vpsravw %zmm27,%zmm28,%zmm29");
+
+	/* AVX-512: Op code 0f 38 12 */
+
+	asm volatile("vpmovusqb %zmm27,%xmm6{%k7}");
+	asm volatile("vpsllvw %zmm27,%zmm28,%zmm29");
+
+	/* AVX-512: Op code 0f 38 13 */
+
+	asm volatile("vcvtph2ps %xmm3,%ymm5");
+	asm volatile("vcvtph2ps %ymm5,%zmm27{%k7}");
+	asm volatile("vpmovusdw %zmm27,%ymm6{%k7}");
+
+	/* AVX-512: Op code 0f 38 14 */
+
+	asm volatile("blendvps %xmm1,%xmm0");
+	asm volatile("vpmovusqw %zmm27,%xmm6{%k7}");
+	asm volatile("vprorvd %zmm27,%zmm28,%zmm29");
+	asm volatile("vprorvq %zmm27,%zmm28,%zmm29");
+
+	/* AVX-512: Op code 0f 38 15 */
+
+	asm volatile("blendvpd %xmm1,%xmm0");
+	asm volatile("vpmovusqd %zmm27,%ymm6{%k7}");
+	asm volatile("vprolvd %zmm27,%zmm28,%zmm29");
+	asm volatile("vprolvq %zmm27,%zmm28,%zmm29");
+
+	/* AVX-512: Op code 0f 38 16 */
+
+	asm volatile("vpermps %ymm4,%ymm6,%ymm2");
+	asm volatile("vpermps %ymm24,%ymm26,%ymm22{%k7}");
+	asm volatile("vpermpd %ymm24,%ymm26,%ymm22{%k7}");
+
+	/* AVX-512: Op code 0f 38 19 */
+
+	asm volatile("vbroadcastsd %xmm4,%ymm6");
+	asm volatile("vbroadcastf32x2 %xmm27,%zmm26");
+
+	/* AVX-512: Op code 0f 38 1a */
+
+	asm volatile("vbroadcastf128 (%rcx),%ymm4");
+	asm volatile("vbroadcastf32x4 (%rcx),%zmm26");
+	asm volatile("vbroadcastf64x2 (%rcx),%zmm26");
+
+	/* AVX-512: Op code 0f 38 1b */
+
+	asm volatile("vbroadcastf32x8 (%rcx),%zmm27");
+	asm volatile("vbroadcastf64x4 (%rcx),%zmm26");
+
+	/* AVX-512: Op code 0f 38 1f */
+
+	asm volatile("vpabsq %zmm27,%zmm28");
+
+	/* AVX-512: Op code 0f 38 20 */
+
+	asm volatile("vpmovsxbw %xmm4,%xmm5");
+	asm volatile("vpmovswb %zmm27,%ymm6{%k7}");
+
+	/* AVX-512: Op code 0f 38 21 */
+
+	asm volatile("vpmovsxbd %xmm4,%ymm6");
+	asm volatile("vpmovsdb %zmm27,%xmm6{%k7}");
+
+	/* AVX-512: Op code 0f 38 22 */
+
+	asm volatile("vpmovsxbq %xmm4,%ymm4");
+	asm volatile("vpmovsqb %zmm27,%xmm6{%k7}");
+
+	/* AVX-512: Op code 0f 38 23 */
+
+	asm volatile("vpmovsxwd %xmm4,%ymm4");
+	asm volatile("vpmovsdw %zmm27,%ymm6{%k7}");
+
+	/* AVX-512: Op code 0f 38 24 */
+
+	asm volatile("vpmovsxwq %xmm4,%ymm6");
+	asm volatile("vpmovsqw %zmm27,%xmm6{%k7}");
+
+	/* AVX-512: Op code 0f 38 25 */
+
+	asm volatile("vpmovsxdq %xmm4,%ymm4");
+	asm volatile("vpmovsqd %zmm27,%ymm6{%k7}");
+
+	/* AVX-512: Op code 0f 38 26 */
+
+	asm volatile("vptestmb %zmm27,%zmm28,%k5");
+	asm volatile("vptestmw %zmm27,%zmm28,%k5");
+	asm volatile("vptestnmb %zmm26,%zmm27,%k5");
+	asm volatile("vptestnmw %zmm26,%zmm27,%k5");
+
+	/* AVX-512: Op code 0f 38 27 */
+
+	asm volatile("vptestmd %zmm27,%zmm28,%k5");
+	asm volatile("vptestmq %zmm27,%zmm28,%k5");
+	asm volatile("vptestnmd %zmm26,%zmm27,%k5");
+	asm volatile("vptestnmq %zmm26,%zmm27,%k5");
+
+	/* AVX-512: Op code 0f 38 28 */
+
+	asm volatile("vpmuldq %ymm4,%ymm6,%ymm2");
+	asm volatile("vpmovm2b %k5,%zmm28");
+	asm volatile("vpmovm2w %k5,%zmm28");
+
+	/* AVX-512: Op code 0f 38 29 */
+
+	asm volatile("vpcmpeqq %ymm4,%ymm6,%ymm2");
+	asm volatile("vpmovb2m %zmm28,%k5");
+	asm volatile("vpmovw2m %zmm28,%k5");
+
+	/* AVX-512: Op code 0f 38 2a */
+
+	asm volatile("vmovntdqa (%rcx),%ymm4");
+	asm volatile("vpbroadcastmb2q %k6,%zmm30");
+
+	/* AVX-512: Op code 0f 38 2c */
+
+	asm volatile("vmaskmovps (%rcx),%ymm4,%ymm6");
+	asm volatile("vscalefps %zmm24,%zmm25,%zmm26");
+	asm volatile("vscalefpd %zmm24,%zmm25,%zmm26");
+
+	/* AVX-512: Op code 0f 38 2d */
+
+	asm volatile("vmaskmovpd (%rcx),%ymm4,%ymm6");
+	asm volatile("vscalefss %xmm24,%xmm25,%xmm26{%k7}");
+	asm volatile("vscalefsd %xmm24,%xmm25,%xmm26{%k7}");
+
+	/* AVX-512: Op code 0f 38 30 */
+
+	asm volatile("vpmovzxbw %xmm4,%ymm4");
+	asm volatile("vpmovwb %zmm27,%ymm6{%k7}");
+
+	/* AVX-512: Op code 0f 38 31 */
+
+	asm volatile("vpmovzxbd %xmm4,%ymm6");
+	asm volatile("vpmovdb %zmm27,%xmm6{%k7}");
+
+	/* AVX-512: Op code 0f 38 32 */
+
+	asm volatile("vpmovzxbq %xmm4,%ymm4");
+	asm volatile("vpmovqb %zmm27,%xmm6{%k7}");
+
+	/* AVX-512: Op code 0f 38 33 */
+
+	asm volatile("vpmovzxwd %xmm4,%ymm4");
+	asm volatile("vpmovdw %zmm27,%ymm6{%k7}");
+
+	/* AVX-512: Op code 0f 38 34 */
+
+	asm volatile("vpmovzxwq %xmm4,%ymm6");
+	asm volatile("vpmovqw %zmm27,%xmm6{%k7}");
+
+	/* AVX-512: Op code 0f 38 35 */
+
+	asm volatile("vpmovzxdq %xmm4,%ymm4");
+	asm volatile("vpmovqd %zmm27,%ymm6{%k7}");
+
+	/* AVX-512: Op code 0f 38 38 */
+
+	asm volatile("vpermd %ymm4,%ymm6,%ymm2");
+	asm volatile("vpermd %ymm24,%ymm26,%ymm22{%k7}");
+	asm volatile("vpermq %ymm24,%ymm26,%ymm22{%k7}");
+
+	/* AVX-512: Op code 0f 38 38 */
+
+	asm volatile("vpminsb %ymm4,%ymm6,%ymm2");
+	asm volatile("vpmovm2d %k5,%zmm28");
+	asm volatile("vpmovm2q %k5,%zmm28");
+
+	/* AVX-512: Op code 0f 38 39 */
+
+	asm volatile("vpminsd %xmm1,%xmm2,%xmm3");
+	asm volatile("vpminsd %zmm24,%zmm25,%zmm26");
+	asm volatile("vpminsq %zmm24,%zmm25,%zmm26");
+	asm volatile("vpmovd2m %zmm28,%k5");
+	asm volatile("vpmovq2m %zmm28,%k5");
+
+	/* AVX-512: Op code 0f 38 3a */
+
+	asm volatile("vpminuw %ymm4,%ymm6,%ymm2");
+	asm volatile("vpbroadcastmw2d %k6,%zmm28");
+
+	/* AVX-512: Op code 0f 38 3b */
+
+	asm volatile("vpminud %ymm4,%ymm6,%ymm2");
+	asm volatile("vpminud %zmm24,%zmm25,%zmm26");
+	asm volatile("vpminuq %zmm24,%zmm25,%zmm26");
+
+	/* AVX-512: Op code 0f 38 3d */
+
+	asm volatile("vpmaxsd %ymm4,%ymm6,%ymm2");
+	asm volatile("vpmaxsd %zmm24,%zmm25,%zmm26");
+	asm volatile("vpmaxsq %zmm24,%zmm25,%zmm26");
+
+	/* AVX-512: Op code 0f 38 3f */
+
+	asm volatile("vpmaxud %ymm4,%ymm6,%ymm2");
+	asm volatile("vpmaxud %zmm24,%zmm25,%zmm26");
+	asm volatile("vpmaxuq %zmm24,%zmm25,%zmm26");
+
+	/* AVX-512: Op code 0f 38 42 */
+
+	asm volatile("vpmulld %ymm4,%ymm6,%ymm2");
+	asm volatile("vpmulld %zmm24,%zmm25,%zmm26");
+	asm volatile("vpmullq %zmm24,%zmm25,%zmm26");
+
+	/* AVX-512: Op code 0f 38 42 */
+
+	asm volatile("vgetexpps %zmm25,%zmm26");
+	asm volatile("vgetexppd %zmm27,%zmm28");
+
+	/* AVX-512: Op code 0f 38 43 */
+
+	asm volatile("vgetexpss %xmm24,%xmm25,%xmm26{%k7}");
+	asm volatile("vgetexpsd %xmm28,%xmm29,%xmm30{%k7}");
+
+	/* AVX-512: Op code 0f 38 44 */
+
+	asm volatile("vplzcntd %zmm27,%zmm28");
+	asm volatile("vplzcntq %zmm27,%zmm28");
+
+	/* AVX-512: Op code 0f 38 46 */
+
+	asm volatile("vpsravd %ymm4,%ymm6,%ymm2");
+	asm volatile("vpsravd %zmm24,%zmm25,%zmm26");
+	asm volatile("vpsravq %zmm24,%zmm25,%zmm26");
+
+	/* AVX-512: Op code 0f 38 4c */
+
+	asm volatile("vrcp14ps %zmm25,%zmm26");
+	asm volatile("vrcp14pd %zmm27,%zmm28");
+
+	/* AVX-512: Op code 0f 38 4d */
+
+	asm volatile("vrcp14ss %xmm24,%xmm25,%xmm26{%k7}");
+	asm volatile("vrcp14sd %xmm24,%xmm25,%xmm26{%k7}");
+
+	/* AVX-512: Op code 0f 38 4e */
+
+	asm volatile("vrsqrt14ps %zmm25,%zmm26");
+	asm volatile("vrsqrt14pd %zmm27,%zmm28");
+
+	/* AVX-512: Op code 0f 38 4f */
+
+	asm volatile("vrsqrt14ss %xmm24,%xmm25,%xmm26{%k7}");
+	asm volatile("vrsqrt14sd %xmm24,%xmm25,%xmm26{%k7}");
+
+	/* AVX-512: Op code 0f 38 59 */
+
+	asm volatile("vpbroadcastq %xmm4,%xmm6");
+	asm volatile("vbroadcasti32x2 %xmm27,%zmm26");
+
+	/* AVX-512: Op code 0f 38 5a */
+
+	asm volatile("vbroadcasti128 (%rcx),%ymm4");
+	asm volatile("vbroadcasti32x4 (%rcx),%zmm26");
+	asm volatile("vbroadcasti64x2 (%rcx),%zmm26");
+
+	/* AVX-512: Op code 0f 38 5b */
+
+	asm volatile("vbroadcasti32x8 (%rcx),%zmm28");
+	asm volatile("vbroadcasti64x4 (%rcx),%zmm26");
+
+	/* AVX-512: Op code 0f 38 64 */
+
+	asm volatile("vpblendmd %zmm26,%zmm27,%zmm28");
+	asm volatile("vpblendmq %zmm26,%zmm27,%zmm28");
+
+	/* AVX-512: Op code 0f 38 65 */
+
+	asm volatile("vblendmps %zmm24,%zmm25,%zmm26");
+	asm volatile("vblendmpd %zmm26,%zmm27,%zmm28");
+
+	/* AVX-512: Op code 0f 38 66 */
+
+	asm volatile("vpblendmb %zmm26,%zmm27,%zmm28");
+	asm volatile("vpblendmw %zmm26,%zmm27,%zmm28");
+
+	/* AVX-512: Op code 0f 38 75 */
+
+	asm volatile("vpermi2b %zmm24,%zmm25,%zmm26");
+	asm volatile("vpermi2w %zmm26,%zmm27,%zmm28");
+
+	/* AVX-512: Op code 0f 38 76 */
+
+	asm volatile("vpermi2d %zmm26,%zmm27,%zmm28");
+	asm volatile("vpermi2q %zmm26,%zmm27,%zmm28");
+
+	/* AVX-512: Op code 0f 38 77 */
+
+	asm volatile("vpermi2ps %zmm26,%zmm27,%zmm28");
+	asm volatile("vpermi2pd %zmm26,%zmm27,%zmm28");
+
+	/* AVX-512: Op code 0f 38 7a */
+
+	asm volatile("vpbroadcastb %eax,%xmm30");
+
+	/* AVX-512: Op code 0f 38 7b */
+
+	asm volatile("vpbroadcastw %eax,%xmm30");
+
+	/* AVX-512: Op code 0f 38 7c */
+
+	asm volatile("vpbroadcastd %eax,%xmm30");
+	asm volatile("vpbroadcastq %rax,%zmm30");
+
+	/* AVX-512: Op code 0f 38 7d */
+
+	asm volatile("vpermt2b %zmm26,%zmm27,%zmm28");
+	asm volatile("vpermt2w %zmm26,%zmm27,%zmm28");
+
+	/* AVX-512: Op code 0f 38 7e */
+
+	asm volatile("vpermt2d %zmm26,%zmm27,%zmm28");
+	asm volatile("vpermt2q %zmm26,%zmm27,%zmm28");
+
+	/* AVX-512: Op code 0f 38 7f */
+
+	asm volatile("vpermt2ps %zmm26,%zmm27,%zmm28");
+	asm volatile("vpermt2pd %zmm26,%zmm27,%zmm28");
+
+	/* AVX-512: Op code 0f 38 83 */
+
+	asm volatile("vpmultishiftqb %zmm26,%zmm27,%zmm28");
+
+	/* AVX-512: Op code 0f 38 88 */
+
+	asm volatile("vexpandps (%rcx),%zmm26");
+	asm volatile("vexpandpd (%rcx),%zmm28");
+
+	/* AVX-512: Op code 0f 38 89 */
+
+	asm volatile("vpexpandd (%rcx),%zmm28");
+	asm volatile("vpexpandq (%rcx),%zmm26");
+
+	/* AVX-512: Op code 0f 38 8a */
+
+	asm volatile("vcompressps %zmm28,(%rcx)");
+	asm volatile("vcompresspd %zmm28,(%rcx)");
+
+	/* AVX-512: Op code 0f 38 8b */
+
+	asm volatile("vpcompressd %zmm28,(%rcx)");
+	asm volatile("vpcompressq %zmm26,(%rcx)");
+
+	/* AVX-512: Op code 0f 38 8d */
+
+	asm volatile("vpermb %zmm26,%zmm27,%zmm28");
+	asm volatile("vpermw %zmm26,%zmm27,%zmm28");
+
+	/* AVX-512: Op code 0f 38 90 */
+
+	asm volatile("vpgatherdd %xmm2,0x02(%rbp,%xmm7,2),%xmm1");
+	asm volatile("vpgatherdq %xmm2,0x04(%rbp,%xmm7,2),%xmm1");
+	asm volatile("vpgatherdd 0x7b(%rbp,%zmm27,8),%zmm26{%k1}");
+	asm volatile("vpgatherdq 0x7b(%rbp,%ymm27,8),%zmm26{%k1}");
+
+	/* AVX-512: Op code 0f 38 91 */
+
+	asm volatile("vpgatherqd %xmm2,0x02(%rbp,%xmm7,2),%xmm1");
+	asm volatile("vpgatherqq %xmm2,0x02(%rbp,%xmm7,2),%xmm1");
+	asm volatile("vpgatherqd 0x7b(%rbp,%zmm27,8),%ymm26{%k1}");
+	asm volatile("vpgatherqq 0x7b(%rbp,%zmm27,8),%zmm26{%k1}");
+
+	/* AVX-512: Op code 0f 38 a0 */
+
+	asm volatile("vpscatterdd %zmm28,0x7b(%rbp,%zmm29,8){%k1}");
+	asm volatile("vpscatterdq %zmm26,0x7b(%rbp,%ymm27,8){%k1}");
+
+	/* AVX-512: Op code 0f 38 a1 */
+
+	asm volatile("vpscatterqd %ymm6,0x7b(%rbp,%zmm29,8){%k1}");
+	asm volatile("vpscatterqq %ymm6,0x7b(%rbp,%ymm27,8){%k1}");
+
+	/* AVX-512: Op code 0f 38 a2 */
+
+	asm volatile("vscatterdps %zmm28,0x7b(%rbp,%zmm29,8){%k1}");
+	asm volatile("vscatterdpd %zmm28,0x7b(%rbp,%ymm27,8){%k1}");
+
+	/* AVX-512: Op code 0f 38 a3 */
+
+	asm volatile("vscatterqps %ymm6,0x7b(%rbp,%zmm29,8){%k1}");
+	asm volatile("vscatterqpd %zmm28,0x7b(%rbp,%zmm29,8){%k1}");
+
+	/* AVX-512: Op code 0f 38 b4 */
+
+	asm volatile("vpmadd52luq %zmm26,%zmm27,%zmm28");
+
+	/* AVX-512: Op code 0f 38 b5 */
+
+	asm volatile("vpmadd52huq %zmm26,%zmm27,%zmm28");
+
+	/* AVX-512: Op code 0f 38 c4 */
+
+	asm volatile("vpconflictd %zmm26,%zmm27");
+	asm volatile("vpconflictq %zmm26,%zmm27");
+
+	/* AVX-512: Op code 0f 38 c8 */
+
+	asm volatile("vexp2ps %zmm29,%zmm30");
+	asm volatile("vexp2pd %zmm26,%zmm27");
+
+	/* AVX-512: Op code 0f 38 ca */
+
+	asm volatile("vrcp28ps %zmm29,%zmm30");
+	asm volatile("vrcp28pd %zmm26,%zmm27");
+
+	/* AVX-512: Op code 0f 38 cb */
+
+	asm volatile("vrcp28ss %xmm28,%xmm29,%xmm30{%k7}");
+	asm volatile("vrcp28sd %xmm25,%xmm26,%xmm27{%k7}");
+
+	/* AVX-512: Op code 0f 38 cc */
+
+	asm volatile("vrsqrt28ps %zmm29,%zmm30");
+	asm volatile("vrsqrt28pd %zmm26,%zmm27");
+
+	/* AVX-512: Op code 0f 38 cd */
+
+	asm volatile("vrsqrt28ss %xmm28,%xmm29,%xmm30{%k7}");
+	asm volatile("vrsqrt28sd %xmm25,%xmm26,%xmm27{%k7}");
+
+	/* AVX-512: Op code 0f 3a 03 */
+
+	asm volatile("valignd $0x12,%zmm28,%zmm29,%zmm30");
+	asm volatile("valignq $0x12,%zmm25,%zmm26,%zmm27");
+
+	/* AVX-512: Op code 0f 3a 08 */
+
+	asm volatile("vroundps $0x5,%ymm6,%ymm2");
+	asm volatile("vrndscaleps $0x12,%zmm25,%zmm26");
+
+	/* AVX-512: Op code 0f 3a 09 */
+
+	asm volatile("vroundpd $0x5,%ymm6,%ymm2");
+	asm volatile("vrndscalepd $0x12,%zmm25,%zmm26");
+
+	/* AVX-512: Op code 0f 3a 1a */
+
+	asm volatile("vroundss $0x5,%xmm4,%xmm6,%xmm2");
+	asm volatile("vrndscaless $0x12,%xmm24,%xmm25,%xmm26{%k7}");
+
+	/* AVX-512: Op code 0f 3a 0b */
+
+	asm volatile("vroundsd $0x5,%xmm4,%xmm6,%xmm2");
+	asm volatile("vrndscalesd $0x12,%xmm24,%xmm25,%xmm26{%k7}");
+
+	/* AVX-512: Op code 0f 3a 18 */
+
+	asm volatile("vinsertf128 $0x5,%xmm4,%ymm4,%ymm6");
+	asm volatile("vinsertf32x4 $0x12,%xmm24,%zmm25,%zmm26{%k7}");
+	asm volatile("vinsertf64x2 $0x12,%xmm24,%zmm25,%zmm26{%k7}");
+
+	/* AVX-512: Op code 0f 3a 19 */
+
+	asm volatile("vextractf128 $0x5,%ymm4,%xmm4");
+	asm volatile("vextractf32x4 $0x12,%zmm25,%xmm26{%k7}");
+	asm volatile("vextractf64x2 $0x12,%zmm25,%xmm26{%k7}");
+
+	/* AVX-512: Op code 0f 3a 1a */
+
+	asm volatile("vinsertf32x8 $0x12,%ymm25,%zmm26,%zmm27{%k7}");
+	asm volatile("vinsertf64x4 $0x12,%ymm28,%zmm29,%zmm30{%k7}");
+
+	/* AVX-512: Op code 0f 3a 1b */
+
+	asm volatile("vextractf32x8 $0x12,%zmm29,%ymm30{%k7}");
+	asm volatile("vextractf64x4 $0x12,%zmm26,%ymm27{%k7}");
+
+	/* AVX-512: Op code 0f 3a 1e */
+
+	asm volatile("vpcmpud $0x12,%zmm29,%zmm30,%k5");
+	asm volatile("vpcmpuq $0x12,%zmm26,%zmm27,%k5");
+
+	/* AVX-512: Op code 0f 3a 1f */
+
+	asm volatile("vpcmpd $0x12,%zmm29,%zmm30,%k5");
+	asm volatile("vpcmpq $0x12,%zmm26,%zmm27,%k5");
+
+	/* AVX-512: Op code 0f 3a 23 */
+
+	asm volatile("vshuff32x4 $0x12,%zmm28,%zmm29,%zmm30");
+	asm volatile("vshuff64x2 $0x12,%zmm25,%zmm26,%zmm27");
+
+	/* AVX-512: Op code 0f 3a 25 */
+
+	asm volatile("vpternlogd $0x12,%zmm28,%zmm29,%zmm30");
+	asm volatile("vpternlogq $0x12,%zmm28,%zmm29,%zmm30");
+
+	/* AVX-512: Op code 0f 3a 26 */
+
+	asm volatile("vgetmantps $0x12,%zmm26,%zmm27");
+	asm volatile("vgetmantpd $0x12,%zmm29,%zmm30");
+
+	/* AVX-512: Op code 0f 3a 27 */
+
+	asm volatile("vgetmantss $0x12,%xmm25,%xmm26,%xmm27{%k7}");
+	asm volatile("vgetmantsd $0x12,%xmm28,%xmm29,%xmm30{%k7}");
+
+	/* AVX-512: Op code 0f 3a 38 */
+
+	asm volatile("vinserti128 $0x5,%xmm4,%ymm4,%ymm6");
+	asm volatile("vinserti32x4 $0x12,%xmm24,%zmm25,%zmm26{%k7}");
+	asm volatile("vinserti64x2 $0x12,%xmm24,%zmm25,%zmm26{%k7}");
+
+	/* AVX-512: Op code 0f 3a 39 */
+
+	asm volatile("vextracti128 $0x5,%ymm4,%xmm6");
+	asm volatile("vextracti32x4 $0x12,%zmm25,%xmm26{%k7}");
+	asm volatile("vextracti64x2 $0x12,%zmm25,%xmm26{%k7}");
+
+	/* AVX-512: Op code 0f 3a 3a */
+
+	asm volatile("vinserti32x8 $0x12,%ymm28,%zmm29,%zmm30{%k7}");
+	asm volatile("vinserti64x4 $0x12,%ymm25,%zmm26,%zmm27{%k7}");
+
+	/* AVX-512: Op code 0f 3a 3b */
+
+	asm volatile("vextracti32x8 $0x12,%zmm29,%ymm30{%k7}");
+	asm volatile("vextracti64x4 $0x12,%zmm26,%ymm27{%k7}");
+
+	/* AVX-512: Op code 0f 3a 3e */
+
+	asm volatile("vpcmpub $0x12,%zmm29,%zmm30,%k5");
+	asm volatile("vpcmpuw $0x12,%zmm26,%zmm27,%k5");
+
+	/* AVX-512: Op code 0f 3a 3f */
+
+	asm volatile("vpcmpb $0x12,%zmm29,%zmm30,%k5");
+	asm volatile("vpcmpw $0x12,%zmm26,%zmm27,%k5");
+
+	/* AVX-512: Op code 0f 3a 43 */
+
+	asm volatile("vmpsadbw $0x5,%ymm4,%ymm6,%ymm2");
+	asm volatile("vdbpsadbw $0x12,%zmm4,%zmm5,%zmm6");
+
+	/* AVX-512: Op code 0f 3a 43 */
+
+	asm volatile("vshufi32x4 $0x12,%zmm25,%zmm26,%zmm27");
+	asm volatile("vshufi64x2 $0x12,%zmm28,%zmm29,%zmm30");
+
+	/* AVX-512: Op code 0f 3a 50 */
+
+	asm volatile("vrangeps $0x12,%zmm25,%zmm26,%zmm27");
+	asm volatile("vrangepd $0x12,%zmm28,%zmm29,%zmm30");
+
+	/* AVX-512: Op code 0f 3a 51 */
+
+	asm volatile("vrangess $0x12,%xmm25,%xmm26,%xmm27");
+	asm volatile("vrangesd $0x12,%xmm28,%xmm29,%xmm30");
+
+	/* AVX-512: Op code 0f 3a 54 */
+
+	asm volatile("vfixupimmps $0x12,%zmm28,%zmm29,%zmm30");
+	asm volatile("vfixupimmpd $0x12,%zmm25,%zmm26,%zmm27");
+
+	/* AVX-512: Op code 0f 3a 55 */
+
+	asm volatile("vfixupimmss $0x12,%xmm28,%xmm29,%xmm30{%k7}");
+	asm volatile("vfixupimmsd $0x12,%xmm25,%xmm26,%xmm27{%k7}");
+
+	/* AVX-512: Op code 0f 3a 56 */
+
+	asm volatile("vreduceps $0x12,%zmm26,%zmm27");
+	asm volatile("vreducepd $0x12,%zmm29,%zmm30");
+
+	/* AVX-512: Op code 0f 3a 57 */
+
+	asm volatile("vreducess $0x12,%xmm25,%xmm26,%xmm27");
+	asm volatile("vreducesd $0x12,%xmm28,%xmm29,%xmm30");
+
+	/* AVX-512: Op code 0f 3a 66 */
+
+	asm volatile("vfpclassps $0x12,%zmm27,%k5");
+	asm volatile("vfpclasspd $0x12,%zmm30,%k5");
+
+	/* AVX-512: Op code 0f 3a 67 */
+
+	asm volatile("vfpclassss $0x12,%xmm27,%k5");
+	asm volatile("vfpclasssd $0x12,%xmm30,%k5");
+
+	/* AVX-512: Op code 0f 72 (Grp13) */
+
+	asm volatile("vprord $0x12,%zmm25,%zmm26");
+	asm volatile("vprorq $0x12,%zmm25,%zmm26");
+	asm volatile("vprold $0x12,%zmm29,%zmm30");
+	asm volatile("vprolq $0x12,%zmm29,%zmm30");
+	asm volatile("psrad  $0x2,%mm6");
+	asm volatile("vpsrad $0x5,%ymm6,%ymm2");
+	asm volatile("vpsrad $0x5,%zmm26,%zmm22");
+	asm volatile("vpsraq $0x5,%zmm26,%zmm22");
+
+	/* AVX-512: Op code 0f 38 c6 (Grp18) */
+
+	asm volatile("vgatherpf0dps 0x7b(%r14,%zmm31,8){%k1}");
+	asm volatile("vgatherpf0dpd 0x7b(%r14,%ymm31,8){%k1}");
+	asm volatile("vgatherpf1dps 0x7b(%r14,%zmm31,8){%k1}");
+	asm volatile("vgatherpf1dpd 0x7b(%r14,%ymm31,8){%k1}");
+	asm volatile("vscatterpf0dps 0x7b(%r14,%zmm31,8){%k1}");
+	asm volatile("vscatterpf0dpd 0x7b(%r14,%ymm31,8){%k1}");
+	asm volatile("vscatterpf1dps 0x7b(%r14,%zmm31,8){%k1}");
+	asm volatile("vscatterpf1dpd 0x7b(%r14,%ymm31,8){%k1}");
+
+	/* AVX-512: Op code 0f 38 c7 (Grp19) */
+
+	asm volatile("vgatherpf0qps 0x7b(%r14,%zmm31,8){%k1}");
+	asm volatile("vgatherpf0qpd 0x7b(%r14,%zmm31,8){%k1}");
+	asm volatile("vgatherpf1qps 0x7b(%r14,%zmm31,8){%k1}");
+	asm volatile("vgatherpf1qpd 0x7b(%r14,%zmm31,8){%k1}");
+	asm volatile("vscatterpf0qps 0x7b(%r14,%zmm31,8){%k1}");
+	asm volatile("vscatterpf0qpd 0x7b(%r14,%zmm31,8){%k1}");
+	asm volatile("vscatterpf1qps 0x7b(%r14,%zmm31,8){%k1}");
+	asm volatile("vscatterpf1qpd 0x7b(%r14,%zmm31,8){%k1}");
+
+	/* AVX-512: Examples */
+
+	asm volatile("vaddpd %zmm28,%zmm29,%zmm30");
+	asm volatile("vaddpd %zmm28,%zmm29,%zmm30{%k7}");
+	asm volatile("vaddpd %zmm28,%zmm29,%zmm30{%k7}{z}");
+	asm volatile("vaddpd {rn-sae},%zmm28,%zmm29,%zmm30");
+	asm volatile("vaddpd {ru-sae},%zmm28,%zmm29,%zmm30");
+	asm volatile("vaddpd {rd-sae},%zmm28,%zmm29,%zmm30");
+	asm volatile("vaddpd {rz-sae},%zmm28,%zmm29,%zmm30");
+	asm volatile("vaddpd (%rcx),%zmm29,%zmm30");
+	asm volatile("vaddpd 0x123(%rax,%r14,8),%zmm29,%zmm30");
+	asm volatile("vaddpd (%rcx){1to8},%zmm29,%zmm30");
+	asm volatile("vaddpd 0x1fc0(%rdx),%zmm29,%zmm30");
+	asm volatile("vaddpd 0x3f8(%rdx){1to8},%zmm29,%zmm30");
+	asm volatile("vcmpeq_uqps 0x1fc(%rdx){1to16},%zmm30,%k5");
+	asm volatile("vcmpltsd 0x123(%rax,%r14,8),%xmm29,%k5{%k7}");
+	asm volatile("vcmplesd {sae},%xmm28,%xmm29,%k5{%k7}");
+	asm volatile("vgetmantss $0x5b,0x123(%rax,%r14,8),%xmm29,%xmm30{%k7}");
+
+	/* bndmk m64, bnd */
+
+	asm volatile("bndmk (%rax), %bnd0");
+	asm volatile("bndmk (%r8), %bnd0");
+	asm volatile("bndmk (0x12345678), %bnd0");
+	asm volatile("bndmk (%rax), %bnd3");
+	asm volatile("bndmk (%rcx,%rax,1), %bnd0");
+	asm volatile("bndmk 0x12345678(,%rax,1), %bnd0");
+	asm volatile("bndmk (%rax,%rcx,1), %bnd0");
+	asm volatile("bndmk (%rax,%rcx,8), %bnd0");
+	asm volatile("bndmk 0x12(%rax), %bnd0");
+	asm volatile("bndmk 0x12(%rbp), %bnd0");
+	asm volatile("bndmk 0x12(%rcx,%rax,1), %bnd0");
+	asm volatile("bndmk 0x12(%rbp,%rax,1), %bnd0");
+	asm volatile("bndmk 0x12(%rax,%rcx,1), %bnd0");
+	asm volatile("bndmk 0x12(%rax,%rcx,8), %bnd0");
+	asm volatile("bndmk 0x12345678(%rax), %bnd0");
+	asm volatile("bndmk 0x12345678(%rbp), %bnd0");
+	asm volatile("bndmk 0x12345678(%rcx,%rax,1), %bnd0");
+	asm volatile("bndmk 0x12345678(%rbp,%rax,1), %bnd0");
+	asm volatile("bndmk 0x12345678(%rax,%rcx,1), %bnd0");
+	asm volatile("bndmk 0x12345678(%rax,%rcx,8), %bnd0");
+
+	/* bndcl r/m64, bnd */
+
+	asm volatile("bndcl (%rax), %bnd0");
+	asm volatile("bndcl (%r8), %bnd0");
+	asm volatile("bndcl (0x12345678), %bnd0");
+	asm volatile("bndcl (%rax), %bnd3");
+	asm volatile("bndcl (%rcx,%rax,1), %bnd0");
+	asm volatile("bndcl 0x12345678(,%rax,1), %bnd0");
+	asm volatile("bndcl (%rax,%rcx,1), %bnd0");
+	asm volatile("bndcl (%rax,%rcx,8), %bnd0");
+	asm volatile("bndcl 0x12(%rax), %bnd0");
+	asm volatile("bndcl 0x12(%rbp), %bnd0");
+	asm volatile("bndcl 0x12(%rcx,%rax,1), %bnd0");
+	asm volatile("bndcl 0x12(%rbp,%rax,1), %bnd0");
+	asm volatile("bndcl 0x12(%rax,%rcx,1), %bnd0");
+	asm volatile("bndcl 0x12(%rax,%rcx,8), %bnd0");
+	asm volatile("bndcl 0x12345678(%rax), %bnd0");
+	asm volatile("bndcl 0x12345678(%rbp), %bnd0");
+	asm volatile("bndcl 0x12345678(%rcx,%rax,1), %bnd0");
+	asm volatile("bndcl 0x12345678(%rbp,%rax,1), %bnd0");
+	asm volatile("bndcl 0x12345678(%rax,%rcx,1), %bnd0");
+	asm volatile("bndcl 0x12345678(%rax,%rcx,8), %bnd0");
+	asm volatile("bndcl %rax, %bnd0");
+
+	/* bndcu r/m64, bnd */
+
+	asm volatile("bndcu (%rax), %bnd0");
+	asm volatile("bndcu (%r8), %bnd0");
+	asm volatile("bndcu (0x12345678), %bnd0");
+	asm volatile("bndcu (%rax), %bnd3");
+	asm volatile("bndcu (%rcx,%rax,1), %bnd0");
+	asm volatile("bndcu 0x12345678(,%rax,1), %bnd0");
+	asm volatile("bndcu (%rax,%rcx,1), %bnd0");
+	asm volatile("bndcu (%rax,%rcx,8), %bnd0");
+	asm volatile("bndcu 0x12(%rax), %bnd0");
+	asm volatile("bndcu 0x12(%rbp), %bnd0");
+	asm volatile("bndcu 0x12(%rcx,%rax,1), %bnd0");
+	asm volatile("bndcu 0x12(%rbp,%rax,1), %bnd0");
+	asm volatile("bndcu 0x12(%rax,%rcx,1), %bnd0");
+	asm volatile("bndcu 0x12(%rax,%rcx,8), %bnd0");
+	asm volatile("bndcu 0x12345678(%rax), %bnd0");
+	asm volatile("bndcu 0x12345678(%rbp), %bnd0");
+	asm volatile("bndcu 0x12345678(%rcx,%rax,1), %bnd0");
+	asm volatile("bndcu 0x12345678(%rbp,%rax,1), %bnd0");
+	asm volatile("bndcu 0x12345678(%rax,%rcx,1), %bnd0");
+	asm volatile("bndcu 0x12345678(%rax,%rcx,8), %bnd0");
+	asm volatile("bndcu %rax, %bnd0");
+
+	/* bndcn r/m64, bnd */
+
+	asm volatile("bndcn (%rax), %bnd0");
+	asm volatile("bndcn (%r8), %bnd0");
+	asm volatile("bndcn (0x12345678), %bnd0");
+	asm volatile("bndcn (%rax), %bnd3");
+	asm volatile("bndcn (%rcx,%rax,1), %bnd0");
+	asm volatile("bndcn 0x12345678(,%rax,1), %bnd0");
+	asm volatile("bndcn (%rax,%rcx,1), %bnd0");
+	asm volatile("bndcn (%rax,%rcx,8), %bnd0");
+	asm volatile("bndcn 0x12(%rax), %bnd0");
+	asm volatile("bndcn 0x12(%rbp), %bnd0");
+	asm volatile("bndcn 0x12(%rcx,%rax,1), %bnd0");
+	asm volatile("bndcn 0x12(%rbp,%rax,1), %bnd0");
+	asm volatile("bndcn 0x12(%rax,%rcx,1), %bnd0");
+	asm volatile("bndcn 0x12(%rax,%rcx,8), %bnd0");
+	asm volatile("bndcn 0x12345678(%rax), %bnd0");
+	asm volatile("bndcn 0x12345678(%rbp), %bnd0");
+	asm volatile("bndcn 0x12345678(%rcx,%rax,1), %bnd0");
+	asm volatile("bndcn 0x12345678(%rbp,%rax,1), %bnd0");
+	asm volatile("bndcn 0x12345678(%rax,%rcx,1), %bnd0");
+	asm volatile("bndcn 0x12345678(%rax,%rcx,8), %bnd0");
+	asm volatile("bndcn %rax, %bnd0");
+
+	/* bndmov m128, bnd */
+
+	asm volatile("bndmov (%rax), %bnd0");
+	asm volatile("bndmov (%r8), %bnd0");
+	asm volatile("bndmov (0x12345678), %bnd0");
+	asm volatile("bndmov (%rax), %bnd3");
+	asm volatile("bndmov (%rcx,%rax,1), %bnd0");
+	asm volatile("bndmov 0x12345678(,%rax,1), %bnd0");
+	asm volatile("bndmov (%rax,%rcx,1), %bnd0");
+	asm volatile("bndmov (%rax,%rcx,8), %bnd0");
+	asm volatile("bndmov 0x12(%rax), %bnd0");
+	asm volatile("bndmov 0x12(%rbp), %bnd0");
+	asm volatile("bndmov 0x12(%rcx,%rax,1), %bnd0");
+	asm volatile("bndmov 0x12(%rbp,%rax,1), %bnd0");
+	asm volatile("bndmov 0x12(%rax,%rcx,1), %bnd0");
+	asm volatile("bndmov 0x12(%rax,%rcx,8), %bnd0");
+	asm volatile("bndmov 0x12345678(%rax), %bnd0");
+	asm volatile("bndmov 0x12345678(%rbp), %bnd0");
+	asm volatile("bndmov 0x12345678(%rcx,%rax,1), %bnd0");
+	asm volatile("bndmov 0x12345678(%rbp,%rax,1), %bnd0");
+	asm volatile("bndmov 0x12345678(%rax,%rcx,1), %bnd0");
+	asm volatile("bndmov 0x12345678(%rax,%rcx,8), %bnd0");
+
+	/* bndmov bnd, m128 */
+
+	asm volatile("bndmov %bnd0, (%rax)");
+	asm volatile("bndmov %bnd0, (%r8)");
+	asm volatile("bndmov %bnd0, (0x12345678)");
+	asm volatile("bndmov %bnd3, (%rax)");
+	asm volatile("bndmov %bnd0, (%rcx,%rax,1)");
+	asm volatile("bndmov %bnd0, 0x12345678(,%rax,1)");
+	asm volatile("bndmov %bnd0, (%rax,%rcx,1)");
+	asm volatile("bndmov %bnd0, (%rax,%rcx,8)");
+	asm volatile("bndmov %bnd0, 0x12(%rax)");
+	asm volatile("bndmov %bnd0, 0x12(%rbp)");
+	asm volatile("bndmov %bnd0, 0x12(%rcx,%rax,1)");
+	asm volatile("bndmov %bnd0, 0x12(%rbp,%rax,1)");
+	asm volatile("bndmov %bnd0, 0x12(%rax,%rcx,1)");
+	asm volatile("bndmov %bnd0, 0x12(%rax,%rcx,8)");
+	asm volatile("bndmov %bnd0, 0x12345678(%rax)");
+	asm volatile("bndmov %bnd0, 0x12345678(%rbp)");
+	asm volatile("bndmov %bnd0, 0x12345678(%rcx,%rax,1)");
+	asm volatile("bndmov %bnd0, 0x12345678(%rbp,%rax,1)");
+	asm volatile("bndmov %bnd0, 0x12345678(%rax,%rcx,1)");
+	asm volatile("bndmov %bnd0, 0x12345678(%rax,%rcx,8)");
+
+	/* bndmov bnd2, bnd1 */
+
+	asm volatile("bndmov %bnd0, %bnd1");
+	asm volatile("bndmov %bnd1, %bnd0");
+
+	/* bndldx mib, bnd */
+
+	asm volatile("bndldx (%rax), %bnd0");
+	asm volatile("bndldx (%r8), %bnd0");
+	asm volatile("bndldx (0x12345678), %bnd0");
+	asm volatile("bndldx (%rax), %bnd3");
+	asm volatile("bndldx (%rcx,%rax,1), %bnd0");
+	asm volatile("bndldx 0x12345678(,%rax,1), %bnd0");
+	asm volatile("bndldx (%rax,%rcx,1), %bnd0");
+	asm volatile("bndldx 0x12(%rax), %bnd0");
+	asm volatile("bndldx 0x12(%rbp), %bnd0");
+	asm volatile("bndldx 0x12(%rcx,%rax,1), %bnd0");
+	asm volatile("bndldx 0x12(%rbp,%rax,1), %bnd0");
+	asm volatile("bndldx 0x12(%rax,%rcx,1), %bnd0");
+	asm volatile("bndldx 0x12345678(%rax), %bnd0");
+	asm volatile("bndldx 0x12345678(%rbp), %bnd0");
+	asm volatile("bndldx 0x12345678(%rcx,%rax,1), %bnd0");
+	asm volatile("bndldx 0x12345678(%rbp,%rax,1), %bnd0");
+	asm volatile("bndldx 0x12345678(%rax,%rcx,1), %bnd0");
+
+	/* bndstx bnd, mib */
+
+	asm volatile("bndstx %bnd0, (%rax)");
+	asm volatile("bndstx %bnd0, (%r8)");
+	asm volatile("bndstx %bnd0, (0x12345678)");
+	asm volatile("bndstx %bnd3, (%rax)");
+	asm volatile("bndstx %bnd0, (%rcx,%rax,1)");
+	asm volatile("bndstx %bnd0, 0x12345678(,%rax,1)");
+	asm volatile("bndstx %bnd0, (%rax,%rcx,1)");
+	asm volatile("bndstx %bnd0, 0x12(%rax)");
+	asm volatile("bndstx %bnd0, 0x12(%rbp)");
+	asm volatile("bndstx %bnd0, 0x12(%rcx,%rax,1)");
+	asm volatile("bndstx %bnd0, 0x12(%rbp,%rax,1)");
+	asm volatile("bndstx %bnd0, 0x12(%rax,%rcx,1)");
+	asm volatile("bndstx %bnd0, 0x12345678(%rax)");
+	asm volatile("bndstx %bnd0, 0x12345678(%rbp)");
+	asm volatile("bndstx %bnd0, 0x12345678(%rcx,%rax,1)");
+	asm volatile("bndstx %bnd0, 0x12345678(%rbp,%rax,1)");
+	asm volatile("bndstx %bnd0, 0x12345678(%rax,%rcx,1)");
+
+	/* bnd prefix on call, ret, jmp and all jcc */
+
+	asm volatile("bnd call label1");  /* Expecting: call unconditional 0 */
+	asm volatile("bnd call *(%eax)"); /* Expecting: call indirect      0 */
+	asm volatile("bnd ret");          /* Expecting: ret  indirect      0 */
+	asm volatile("bnd jmp label1");   /* Expecting: jmp  unconditional 0 */
+	asm volatile("bnd jmp label1");   /* Expecting: jmp  unconditional 0 */
+	asm volatile("bnd jmp *(%ecx)");  /* Expecting: jmp  indirect      0 */
+	asm volatile("bnd jne label1");   /* Expecting: jcc  conditional   0 */
+
+	/* sha1rnds4 imm8, xmm2/m128, xmm1 */
+
+	asm volatile("sha1rnds4 $0x0, %xmm1, %xmm0");
+	asm volatile("sha1rnds4 $0x91, %xmm7, %xmm2");
+	asm volatile("sha1rnds4 $0x91, %xmm8, %xmm0");
+	asm volatile("sha1rnds4 $0x91, %xmm7, %xmm8");
+	asm volatile("sha1rnds4 $0x91, %xmm15, %xmm8");
+	asm volatile("sha1rnds4 $0x91, (%rax), %xmm0");
+	asm volatile("sha1rnds4 $0x91, (%r8), %xmm0");
+	asm volatile("sha1rnds4 $0x91, (0x12345678), %xmm0");
+	asm volatile("sha1rnds4 $0x91, (%rax), %xmm3");
+	asm volatile("sha1rnds4 $0x91, (%rcx,%rax,1), %xmm0");
+	asm volatile("sha1rnds4 $0x91, 0x12345678(,%rax,1), %xmm0");
+	asm volatile("sha1rnds4 $0x91, (%rax,%rcx,1), %xmm0");
+	asm volatile("sha1rnds4 $0x91, (%rax,%rcx,8), %xmm0");
+	asm volatile("sha1rnds4 $0x91, 0x12(%rax), %xmm0");
+	asm volatile("sha1rnds4 $0x91, 0x12(%rbp), %xmm0");
+	asm volatile("sha1rnds4 $0x91, 0x12(%rcx,%rax,1), %xmm0");
+	asm volatile("sha1rnds4 $0x91, 0x12(%rbp,%rax,1), %xmm0");
+	asm volatile("sha1rnds4 $0x91, 0x12(%rax,%rcx,1), %xmm0");
+	asm volatile("sha1rnds4 $0x91, 0x12(%rax,%rcx,8), %xmm0");
+	asm volatile("sha1rnds4 $0x91, 0x12345678(%rax), %xmm0");
+	asm volatile("sha1rnds4 $0x91, 0x12345678(%rbp), %xmm0");
+	asm volatile("sha1rnds4 $0x91, 0x12345678(%rcx,%rax,1), %xmm0");
+	asm volatile("sha1rnds4 $0x91, 0x12345678(%rbp,%rax,1), %xmm0");
+	asm volatile("sha1rnds4 $0x91, 0x12345678(%rax,%rcx,1), %xmm0");
+	asm volatile("sha1rnds4 $0x91, 0x12345678(%rax,%rcx,8), %xmm0");
+	asm volatile("sha1rnds4 $0x91, 0x12345678(%rax,%rcx,8), %xmm15");
+
+	/* sha1nexte xmm2/m128, xmm1 */
+
+	asm volatile("sha1nexte %xmm1, %xmm0");
+	asm volatile("sha1nexte %xmm7, %xmm2");
+	asm volatile("sha1nexte %xmm8, %xmm0");
+	asm volatile("sha1nexte %xmm7, %xmm8");
+	asm volatile("sha1nexte %xmm15, %xmm8");
+	asm volatile("sha1nexte (%rax), %xmm0");
+	asm volatile("sha1nexte (%r8), %xmm0");
+	asm volatile("sha1nexte (0x12345678), %xmm0");
+	asm volatile("sha1nexte (%rax), %xmm3");
+	asm volatile("sha1nexte (%rcx,%rax,1), %xmm0");
+	asm volatile("sha1nexte 0x12345678(,%rax,1), %xmm0");
+	asm volatile("sha1nexte (%rax,%rcx,1), %xmm0");
+	asm volatile("sha1nexte (%rax,%rcx,8), %xmm0");
+	asm volatile("sha1nexte 0x12(%rax), %xmm0");
+	asm volatile("sha1nexte 0x12(%rbp), %xmm0");
+	asm volatile("sha1nexte 0x12(%rcx,%rax,1), %xmm0");
+	asm volatile("sha1nexte 0x12(%rbp,%rax,1), %xmm0");
+	asm volatile("sha1nexte 0x12(%rax,%rcx,1), %xmm0");
+	asm volatile("sha1nexte 0x12(%rax,%rcx,8), %xmm0");
+	asm volatile("sha1nexte 0x12345678(%rax), %xmm0");
+	asm volatile("sha1nexte 0x12345678(%rbp), %xmm0");
+	asm volatile("sha1nexte 0x12345678(%rcx,%rax,1), %xmm0");
+	asm volatile("sha1nexte 0x12345678(%rbp,%rax,1), %xmm0");
+	asm volatile("sha1nexte 0x12345678(%rax,%rcx,1), %xmm0");
+	asm volatile("sha1nexte 0x12345678(%rax,%rcx,8), %xmm0");
+	asm volatile("sha1nexte 0x12345678(%rax,%rcx,8), %xmm15");
+
+	/* sha1msg1 xmm2/m128, xmm1 */
+
+	asm volatile("sha1msg1 %xmm1, %xmm0");
+	asm volatile("sha1msg1 %xmm7, %xmm2");
+	asm volatile("sha1msg1 %xmm8, %xmm0");
+	asm volatile("sha1msg1 %xmm7, %xmm8");
+	asm volatile("sha1msg1 %xmm15, %xmm8");
+	asm volatile("sha1msg1 (%rax), %xmm0");
+	asm volatile("sha1msg1 (%r8), %xmm0");
+	asm volatile("sha1msg1 (0x12345678), %xmm0");
+	asm volatile("sha1msg1 (%rax), %xmm3");
+	asm volatile("sha1msg1 (%rcx,%rax,1), %xmm0");
+	asm volatile("sha1msg1 0x12345678(,%rax,1), %xmm0");
+	asm volatile("sha1msg1 (%rax,%rcx,1), %xmm0");
+	asm volatile("sha1msg1 (%rax,%rcx,8), %xmm0");
+	asm volatile("sha1msg1 0x12(%rax), %xmm0");
+	asm volatile("sha1msg1 0x12(%rbp), %xmm0");
+	asm volatile("sha1msg1 0x12(%rcx,%rax,1), %xmm0");
+	asm volatile("sha1msg1 0x12(%rbp,%rax,1), %xmm0");
+	asm volatile("sha1msg1 0x12(%rax,%rcx,1), %xmm0");
+	asm volatile("sha1msg1 0x12(%rax,%rcx,8), %xmm0");
+	asm volatile("sha1msg1 0x12345678(%rax), %xmm0");
+	asm volatile("sha1msg1 0x12345678(%rbp), %xmm0");
+	asm volatile("sha1msg1 0x12345678(%rcx,%rax,1), %xmm0");
+	asm volatile("sha1msg1 0x12345678(%rbp,%rax,1), %xmm0");
+	asm volatile("sha1msg1 0x12345678(%rax,%rcx,1), %xmm0");
+	asm volatile("sha1msg1 0x12345678(%rax,%rcx,8), %xmm0");
+	asm volatile("sha1msg1 0x12345678(%rax,%rcx,8), %xmm15");
+
+	/* sha1msg2 xmm2/m128, xmm1 */
+
+	asm volatile("sha1msg2 %xmm1, %xmm0");
+	asm volatile("sha1msg2 %xmm7, %xmm2");
+	asm volatile("sha1msg2 %xmm8, %xmm0");
+	asm volatile("sha1msg2 %xmm7, %xmm8");
+	asm volatile("sha1msg2 %xmm15, %xmm8");
+	asm volatile("sha1msg2 (%rax), %xmm0");
+	asm volatile("sha1msg2 (%r8), %xmm0");
+	asm volatile("sha1msg2 (0x12345678), %xmm0");
+	asm volatile("sha1msg2 (%rax), %xmm3");
+	asm volatile("sha1msg2 (%rcx,%rax,1), %xmm0");
+	asm volatile("sha1msg2 0x12345678(,%rax,1), %xmm0");
+	asm volatile("sha1msg2 (%rax,%rcx,1), %xmm0");
+	asm volatile("sha1msg2 (%rax,%rcx,8), %xmm0");
+	asm volatile("sha1msg2 0x12(%rax), %xmm0");
+	asm volatile("sha1msg2 0x12(%rbp), %xmm0");
+	asm volatile("sha1msg2 0x12(%rcx,%rax,1), %xmm0");
+	asm volatile("sha1msg2 0x12(%rbp,%rax,1), %xmm0");
+	asm volatile("sha1msg2 0x12(%rax,%rcx,1), %xmm0");
+	asm volatile("sha1msg2 0x12(%rax,%rcx,8), %xmm0");
+	asm volatile("sha1msg2 0x12345678(%rax), %xmm0");
+	asm volatile("sha1msg2 0x12345678(%rbp), %xmm0");
+	asm volatile("sha1msg2 0x12345678(%rcx,%rax,1), %xmm0");
+	asm volatile("sha1msg2 0x12345678(%rbp,%rax,1), %xmm0");
+	asm volatile("sha1msg2 0x12345678(%rax,%rcx,1), %xmm0");
+	asm volatile("sha1msg2 0x12345678(%rax,%rcx,8), %xmm0");
+	asm volatile("sha1msg2 0x12345678(%rax,%rcx,8), %xmm15");
+
+	/* sha256rnds2 <XMM0>, xmm2/m128, xmm1 */
+	/* Note sha256rnds2 has an implicit operand 'xmm0' */
+
+	asm volatile("sha256rnds2 %xmm4, %xmm1");
+	asm volatile("sha256rnds2 %xmm7, %xmm2");
+	asm volatile("sha256rnds2 %xmm8, %xmm1");
+	asm volatile("sha256rnds2 %xmm7, %xmm8");
+	asm volatile("sha256rnds2 %xmm15, %xmm8");
+	asm volatile("sha256rnds2 (%rax), %xmm1");
+	asm volatile("sha256rnds2 (%r8), %xmm1");
+	asm volatile("sha256rnds2 (0x12345678), %xmm1");
+	asm volatile("sha256rnds2 (%rax), %xmm3");
+	asm volatile("sha256rnds2 (%rcx,%rax,1), %xmm1");
+	asm volatile("sha256rnds2 0x12345678(,%rax,1), %xmm1");
+	asm volatile("sha256rnds2 (%rax,%rcx,1), %xmm1");
+	asm volatile("sha256rnds2 (%rax,%rcx,8), %xmm1");
+	asm volatile("sha256rnds2 0x12(%rax), %xmm1");
+	asm volatile("sha256rnds2 0x12(%rbp), %xmm1");
+	asm volatile("sha256rnds2 0x12(%rcx,%rax,1), %xmm1");
+	asm volatile("sha256rnds2 0x12(%rbp,%rax,1), %xmm1");
+	asm volatile("sha256rnds2 0x12(%rax,%rcx,1), %xmm1");
+	asm volatile("sha256rnds2 0x12(%rax,%rcx,8), %xmm1");
+	asm volatile("sha256rnds2 0x12345678(%rax), %xmm1");
+	asm volatile("sha256rnds2 0x12345678(%rbp), %xmm1");
+	asm volatile("sha256rnds2 0x12345678(%rcx,%rax,1), %xmm1");
+	asm volatile("sha256rnds2 0x12345678(%rbp,%rax,1), %xmm1");
+	asm volatile("sha256rnds2 0x12345678(%rax,%rcx,1), %xmm1");
+	asm volatile("sha256rnds2 0x12345678(%rax,%rcx,8), %xmm1");
+	asm volatile("sha256rnds2 0x12345678(%rax,%rcx,8), %xmm15");
+
+	/* sha256msg1 xmm2/m128, xmm1 */
+
+	asm volatile("sha256msg1 %xmm1, %xmm0");
+	asm volatile("sha256msg1 %xmm7, %xmm2");
+	asm volatile("sha256msg1 %xmm8, %xmm0");
+	asm volatile("sha256msg1 %xmm7, %xmm8");
+	asm volatile("sha256msg1 %xmm15, %xmm8");
+	asm volatile("sha256msg1 (%rax), %xmm0");
+	asm volatile("sha256msg1 (%r8), %xmm0");
+	asm volatile("sha256msg1 (0x12345678), %xmm0");
+	asm volatile("sha256msg1 (%rax), %xmm3");
+	asm volatile("sha256msg1 (%rcx,%rax,1), %xmm0");
+	asm volatile("sha256msg1 0x12345678(,%rax,1), %xmm0");
+	asm volatile("sha256msg1 (%rax,%rcx,1), %xmm0");
+	asm volatile("sha256msg1 (%rax,%rcx,8), %xmm0");
+	asm volatile("sha256msg1 0x12(%rax), %xmm0");
+	asm volatile("sha256msg1 0x12(%rbp), %xmm0");
+	asm volatile("sha256msg1 0x12(%rcx,%rax,1), %xmm0");
+	asm volatile("sha256msg1 0x12(%rbp,%rax,1), %xmm0");
+	asm volatile("sha256msg1 0x12(%rax,%rcx,1), %xmm0");
+	asm volatile("sha256msg1 0x12(%rax,%rcx,8), %xmm0");
+	asm volatile("sha256msg1 0x12345678(%rax), %xmm0");
+	asm volatile("sha256msg1 0x12345678(%rbp), %xmm0");
+	asm volatile("sha256msg1 0x12345678(%rcx,%rax,1), %xmm0");
+	asm volatile("sha256msg1 0x12345678(%rbp,%rax,1), %xmm0");
+	asm volatile("sha256msg1 0x12345678(%rax,%rcx,1), %xmm0");
+	asm volatile("sha256msg1 0x12345678(%rax,%rcx,8), %xmm0");
+	asm volatile("sha256msg1 0x12345678(%rax,%rcx,8), %xmm15");
+
+	/* sha256msg2 xmm2/m128, xmm1 */
+
+	asm volatile("sha256msg2 %xmm1, %xmm0");
+	asm volatile("sha256msg2 %xmm7, %xmm2");
+	asm volatile("sha256msg2 %xmm8, %xmm0");
+	asm volatile("sha256msg2 %xmm7, %xmm8");
+	asm volatile("sha256msg2 %xmm15, %xmm8");
+	asm volatile("sha256msg2 (%rax), %xmm0");
+	asm volatile("sha256msg2 (%r8), %xmm0");
+	asm volatile("sha256msg2 (0x12345678), %xmm0");
+	asm volatile("sha256msg2 (%rax), %xmm3");
+	asm volatile("sha256msg2 (%rcx,%rax,1), %xmm0");
+	asm volatile("sha256msg2 0x12345678(,%rax,1), %xmm0");
+	asm volatile("sha256msg2 (%rax,%rcx,1), %xmm0");
+	asm volatile("sha256msg2 (%rax,%rcx,8), %xmm0");
+	asm volatile("sha256msg2 0x12(%rax), %xmm0");
+	asm volatile("sha256msg2 0x12(%rbp), %xmm0");
+	asm volatile("sha256msg2 0x12(%rcx,%rax,1), %xmm0");
+	asm volatile("sha256msg2 0x12(%rbp,%rax,1), %xmm0");
+	asm volatile("sha256msg2 0x12(%rax,%rcx,1), %xmm0");
+	asm volatile("sha256msg2 0x12(%rax,%rcx,8), %xmm0");
+	asm volatile("sha256msg2 0x12345678(%rax), %xmm0");
+	asm volatile("sha256msg2 0x12345678(%rbp), %xmm0");
+	asm volatile("sha256msg2 0x12345678(%rcx,%rax,1), %xmm0");
+	asm volatile("sha256msg2 0x12345678(%rbp,%rax,1), %xmm0");
+	asm volatile("sha256msg2 0x12345678(%rax,%rcx,1), %xmm0");
+	asm volatile("sha256msg2 0x12345678(%rax,%rcx,8), %xmm0");
+	asm volatile("sha256msg2 0x12345678(%rax,%rcx,8), %xmm15");
+
+	/* clflushopt m8 */
+
+	asm volatile("clflushopt (%rax)");
+	asm volatile("clflushopt (%r8)");
+	asm volatile("clflushopt (0x12345678)");
+	asm volatile("clflushopt 0x12345678(%rax,%rcx,8)");
+	asm volatile("clflushopt 0x12345678(%r8,%rcx,8)");
+	/* Also check instructions in the same group encoding as clflushopt */
+	asm volatile("clflush (%rax)");
+	asm volatile("clflush (%r8)");
+	asm volatile("sfence");
+
+	/* clwb m8 */
+
+	asm volatile("clwb (%rax)");
+	asm volatile("clwb (%r8)");
+	asm volatile("clwb (0x12345678)");
+	asm volatile("clwb 0x12345678(%rax,%rcx,8)");
+	asm volatile("clwb 0x12345678(%r8,%rcx,8)");
+	/* Also check instructions in the same group encoding as clwb */
+	asm volatile("xsaveopt (%rax)");
+	asm volatile("xsaveopt (%r8)");
+	asm volatile("mfence");
+
+	/* xsavec mem */
+
+	asm volatile("xsavec (%rax)");
+	asm volatile("xsavec (%r8)");
+	asm volatile("xsavec (0x12345678)");
+	asm volatile("xsavec 0x12345678(%rax,%rcx,8)");
+	asm volatile("xsavec 0x12345678(%r8,%rcx,8)");
+
+	/* xsaves mem */
+
+	asm volatile("xsaves (%rax)");
+	asm volatile("xsaves (%r8)");
+	asm volatile("xsaves (0x12345678)");
+	asm volatile("xsaves 0x12345678(%rax,%rcx,8)");
+	asm volatile("xsaves 0x12345678(%r8,%rcx,8)");
+
+	/* xrstors mem */
+
+	asm volatile("xrstors (%rax)");
+	asm volatile("xrstors (%r8)");
+	asm volatile("xrstors (0x12345678)");
+	asm volatile("xrstors 0x12345678(%rax,%rcx,8)");
+	asm volatile("xrstors 0x12345678(%r8,%rcx,8)");
+
+#else  /* #ifdef __x86_64__ */
+
+	/* bound r32, mem (same op code as EVEX prefix) */
+
+	asm volatile("bound %eax, 0x12345678(%ecx)");
+	asm volatile("bound %ecx, 0x12345678(%eax)");
+	asm volatile("bound %edx, 0x12345678(%eax)");
+	asm volatile("bound %ebx, 0x12345678(%eax)");
+	asm volatile("bound %esp, 0x12345678(%eax)");
+	asm volatile("bound %ebp, 0x12345678(%eax)");
+	asm volatile("bound %esi, 0x12345678(%eax)");
+	asm volatile("bound %edi, 0x12345678(%eax)");
+	asm volatile("bound %ecx, (%eax)");
+	asm volatile("bound %eax, (0x12345678)");
+	asm volatile("bound %edx, (%ecx,%eax,1)");
+	asm volatile("bound %edx, 0x12345678(,%eax,1)");
+	asm volatile("bound %edx, (%eax,%ecx,1)");
+	asm volatile("bound %edx, (%eax,%ecx,8)");
+	asm volatile("bound %edx, 0x12(%eax)");
+	asm volatile("bound %edx, 0x12(%ebp)");
+	asm volatile("bound %edx, 0x12(%ecx,%eax,1)");
+	asm volatile("bound %edx, 0x12(%ebp,%eax,1)");
+	asm volatile("bound %edx, 0x12(%eax,%ecx,1)");
+	asm volatile("bound %edx, 0x12(%eax,%ecx,8)");
+	asm volatile("bound %edx, 0x12345678(%eax)");
+	asm volatile("bound %edx, 0x12345678(%ebp)");
+	asm volatile("bound %edx, 0x12345678(%ecx,%eax,1)");
+	asm volatile("bound %edx, 0x12345678(%ebp,%eax,1)");
+	asm volatile("bound %edx, 0x12345678(%eax,%ecx,1)");
+	asm volatile("bound %edx, 0x12345678(%eax,%ecx,8)");
+
+	/* bound r16, mem (same op code as EVEX prefix) */
+
+	asm volatile("bound %ax, 0x12345678(%ecx)");
+	asm volatile("bound %cx, 0x12345678(%eax)");
+	asm volatile("bound %dx, 0x12345678(%eax)");
+	asm volatile("bound %bx, 0x12345678(%eax)");
+	asm volatile("bound %sp, 0x12345678(%eax)");
+	asm volatile("bound %bp, 0x12345678(%eax)");
+	asm volatile("bound %si, 0x12345678(%eax)");
+	asm volatile("bound %di, 0x12345678(%eax)");
+	asm volatile("bound %cx, (%eax)");
+	asm volatile("bound %ax, (0x12345678)");
+	asm volatile("bound %dx, (%ecx,%eax,1)");
+	asm volatile("bound %dx, 0x12345678(,%eax,1)");
+	asm volatile("bound %dx, (%eax,%ecx,1)");
+	asm volatile("bound %dx, (%eax,%ecx,8)");
+	asm volatile("bound %dx, 0x12(%eax)");
+	asm volatile("bound %dx, 0x12(%ebp)");
+	asm volatile("bound %dx, 0x12(%ecx,%eax,1)");
+	asm volatile("bound %dx, 0x12(%ebp,%eax,1)");
+	asm volatile("bound %dx, 0x12(%eax,%ecx,1)");
+	asm volatile("bound %dx, 0x12(%eax,%ecx,8)");
+	asm volatile("bound %dx, 0x12345678(%eax)");
+	asm volatile("bound %dx, 0x12345678(%ebp)");
+	asm volatile("bound %dx, 0x12345678(%ecx,%eax,1)");
+	asm volatile("bound %dx, 0x12345678(%ebp,%eax,1)");
+	asm volatile("bound %dx, 0x12345678(%eax,%ecx,1)");
+	asm volatile("bound %dx, 0x12345678(%eax,%ecx,8)");
+
+	/* AVX-512: Instructions with the same op codes as Mask Instructions  */
+
+	asm volatile("cmovno %eax,%ebx");
+	asm volatile("cmovno 0x12345678(%eax),%ecx");
+	asm volatile("cmovno 0x12345678(%eax),%cx");
+
+	asm volatile("cmove  %eax,%ebx");
+	asm volatile("cmove 0x12345678(%eax),%ecx");
+	asm volatile("cmove 0x12345678(%eax),%cx");
+
+	asm volatile("seto    0x12345678(%eax)");
+	asm volatile("setno   0x12345678(%eax)");
+	asm volatile("setb    0x12345678(%eax)");
+	asm volatile("setc    0x12345678(%eax)");
+	asm volatile("setnae  0x12345678(%eax)");
+	asm volatile("setae   0x12345678(%eax)");
+	asm volatile("setnb   0x12345678(%eax)");
+	asm volatile("setnc   0x12345678(%eax)");
+	asm volatile("sets    0x12345678(%eax)");
+	asm volatile("setns   0x12345678(%eax)");
+
+	/* AVX-512: Mask Instructions */
+
+	asm volatile("kandw  %k7,%k6,%k5");
+	asm volatile("kandq  %k7,%k6,%k5");
+	asm volatile("kandb  %k7,%k6,%k5");
+	asm volatile("kandd  %k7,%k6,%k5");
+
+	asm volatile("kandnw  %k7,%k6,%k5");
+	asm volatile("kandnq  %k7,%k6,%k5");
+	asm volatile("kandnb  %k7,%k6,%k5");
+	asm volatile("kandnd  %k7,%k6,%k5");
+
+	asm volatile("knotw  %k7,%k6");
+	asm volatile("knotq  %k7,%k6");
+	asm volatile("knotb  %k7,%k6");
+	asm volatile("knotd  %k7,%k6");
+
+	asm volatile("korw  %k7,%k6,%k5");
+	asm volatile("korq  %k7,%k6,%k5");
+	asm volatile("korb  %k7,%k6,%k5");
+	asm volatile("kord  %k7,%k6,%k5");
+
+	asm volatile("kxnorw  %k7,%k6,%k5");
+	asm volatile("kxnorq  %k7,%k6,%k5");
+	asm volatile("kxnorb  %k7,%k6,%k5");
+	asm volatile("kxnord  %k7,%k6,%k5");
+
+	asm volatile("kxorw  %k7,%k6,%k5");
+	asm volatile("kxorq  %k7,%k6,%k5");
+	asm volatile("kxorb  %k7,%k6,%k5");
+	asm volatile("kxord  %k7,%k6,%k5");
+
+	asm volatile("kaddw  %k7,%k6,%k5");
+	asm volatile("kaddq  %k7,%k6,%k5");
+	asm volatile("kaddb  %k7,%k6,%k5");
+	asm volatile("kaddd  %k7,%k6,%k5");
+
+	asm volatile("kunpckbw %k7,%k6,%k5");
+	asm volatile("kunpckwd %k7,%k6,%k5");
+	asm volatile("kunpckdq %k7,%k6,%k5");
+
+	asm volatile("kmovw  %k6,%k5");
+	asm volatile("kmovw  (%ecx),%k5");
+	asm volatile("kmovw  0x123(%eax,%ecx,8),%k5");
+	asm volatile("kmovw  %k5,(%ecx)");
+	asm volatile("kmovw  %k5,0x123(%eax,%ecx,8)");
+	asm volatile("kmovw  %eax,%k5");
+	asm volatile("kmovw  %ebp,%k5");
+	asm volatile("kmovw  %k5,%eax");
+	asm volatile("kmovw  %k5,%ebp");
+
+	asm volatile("kmovq  %k6,%k5");
+	asm volatile("kmovq  (%ecx),%k5");
+	asm volatile("kmovq  0x123(%eax,%ecx,8),%k5");
+	asm volatile("kmovq  %k5,(%ecx)");
+	asm volatile("kmovq  %k5,0x123(%eax,%ecx,8)");
+
+	asm volatile("kmovb  %k6,%k5");
+	asm volatile("kmovb  (%ecx),%k5");
+	asm volatile("kmovb  0x123(%eax,%ecx,8),%k5");
+	asm volatile("kmovb  %k5,(%ecx)");
+	asm volatile("kmovb  %k5,0x123(%eax,%ecx,8)");
+	asm volatile("kmovb  %eax,%k5");
+	asm volatile("kmovb  %ebp,%k5");
+	asm volatile("kmovb  %k5,%eax");
+	asm volatile("kmovb  %k5,%ebp");
+
+	asm volatile("kmovd  %k6,%k5");
+	asm volatile("kmovd  (%ecx),%k5");
+	asm volatile("kmovd  0x123(%eax,%ecx,8),%k5");
+	asm volatile("kmovd  %k5,(%ecx)");
+	asm volatile("kmovd  %k5,0x123(%eax,%ecx,8)");
+	asm volatile("kmovd  %eax,%k5");
+	asm volatile("kmovd  %ebp,%k5");
+	asm volatile("kmovd  %k5,%eax");
+	asm volatile("kmovd  %k5,%ebp");
+
+	asm volatile("kortestw %k6,%k5");
+	asm volatile("kortestq %k6,%k5");
+	asm volatile("kortestb %k6,%k5");
+	asm volatile("kortestd %k6,%k5");
+
+	asm volatile("ktestw %k6,%k5");
+	asm volatile("ktestq %k6,%k5");
+	asm volatile("ktestb %k6,%k5");
+	asm volatile("ktestd %k6,%k5");
+
+	asm volatile("kshiftrw $0x12,%k6,%k5");
+	asm volatile("kshiftrq $0x5b,%k6,%k5");
+	asm volatile("kshiftlw $0x12,%k6,%k5");
+	asm volatile("kshiftlq $0x5b,%k6,%k5");
+
+	/* AVX-512: Op code 0f 5b */
+	asm volatile("vcvtdq2ps %xmm5,%xmm6");
+	asm volatile("vcvtqq2ps %zmm5,%ymm6{%k7}");
+	asm volatile("vcvtps2dq %xmm5,%xmm6");
+	asm volatile("vcvttps2dq %xmm5,%xmm6");
+
+	/* AVX-512: Op code 0f 6f */
+
+	asm volatile("movq   %mm0,%mm4");
+	asm volatile("vmovdqa %ymm4,%ymm6");
+	asm volatile("vmovdqa32 %zmm5,%zmm6");
+	asm volatile("vmovdqa64 %zmm5,%zmm6");
+	asm volatile("vmovdqu %ymm4,%ymm6");
+	asm volatile("vmovdqu32 %zmm5,%zmm6");
+	asm volatile("vmovdqu64 %zmm5,%zmm6");
+	asm volatile("vmovdqu8 %zmm5,%zmm6");
+	asm volatile("vmovdqu16 %zmm5,%zmm6");
+
+	/* AVX-512: Op code 0f 78 */
+
+	asm volatile("vmread %eax,%ebx");
+	asm volatile("vcvttps2udq %zmm5,%zmm6");
+	asm volatile("vcvttpd2udq %zmm5,%ymm6{%k7}");
+	asm volatile("vcvttsd2usi %xmm6,%eax");
+	asm volatile("vcvttss2usi %xmm6,%eax");
+	asm volatile("vcvttps2uqq %ymm5,%zmm6{%k7}");
+	asm volatile("vcvttpd2uqq %zmm5,%zmm6");
+
+	/* AVX-512: Op code 0f 79 */
+
+	asm volatile("vmwrite %eax,%ebx");
+	asm volatile("vcvtps2udq %zmm5,%zmm6");
+	asm volatile("vcvtpd2udq %zmm5,%ymm6{%k7}");
+	asm volatile("vcvtsd2usi %xmm6,%eax");
+	asm volatile("vcvtss2usi %xmm6,%eax");
+	asm volatile("vcvtps2uqq %ymm5,%zmm6{%k7}");
+	asm volatile("vcvtpd2uqq %zmm5,%zmm6");
+
+	/* AVX-512: Op code 0f 7a */
+
+	asm volatile("vcvtudq2pd %ymm5,%zmm6{%k7}");
+	asm volatile("vcvtuqq2pd %zmm5,%zmm6");
+	asm volatile("vcvtudq2ps %zmm5,%zmm6");
+	asm volatile("vcvtuqq2ps %zmm5,%ymm6{%k7}");
+	asm volatile("vcvttps2qq %ymm5,%zmm6{%k7}");
+	asm volatile("vcvttpd2qq %zmm5,%zmm6");
+
+	/* AVX-512: Op code 0f 7b */
+
+	asm volatile("vcvtusi2sd %eax,%xmm5,%xmm6");
+	asm volatile("vcvtusi2ss %eax,%xmm5,%xmm6");
+	asm volatile("vcvtps2qq %ymm5,%zmm6{%k7}");
+	asm volatile("vcvtpd2qq %zmm5,%zmm6");
+
+	/* AVX-512: Op code 0f 7f */
+
+	asm volatile("movq.s  %mm0,%mm4");
+	asm volatile("vmovdqa.s %ymm5,%ymm6");
+	asm volatile("vmovdqa32.s %zmm5,%zmm6");
+	asm volatile("vmovdqa64.s %zmm5,%zmm6");
+	asm volatile("vmovdqu.s %ymm5,%ymm6");
+	asm volatile("vmovdqu32.s %zmm5,%zmm6");
+	asm volatile("vmovdqu64.s %zmm5,%zmm6");
+	asm volatile("vmovdqu8.s %zmm5,%zmm6");
+	asm volatile("vmovdqu16.s %zmm5,%zmm6");
+
+	/* AVX-512: Op code 0f db */
+
+	asm volatile("pand  %mm1,%mm2");
+	asm volatile("pand  %xmm1,%xmm2");
+	asm volatile("vpand  %ymm4,%ymm6,%ymm2");
+	asm volatile("vpandd %zmm4,%zmm5,%zmm6");
+	asm volatile("vpandq %zmm4,%zmm5,%zmm6");
+
+	/* AVX-512: Op code 0f df */
+
+	asm volatile("pandn  %mm1,%mm2");
+	asm volatile("pandn  %xmm1,%xmm2");
+	asm volatile("vpandn %ymm4,%ymm6,%ymm2");
+	asm volatile("vpandnd %zmm4,%zmm5,%zmm6");
+	asm volatile("vpandnq %zmm4,%zmm5,%zmm6");
+
+	/* AVX-512: Op code 0f e6 */
+
+	asm volatile("vcvttpd2dq %xmm1,%xmm2");
+	asm volatile("vcvtdq2pd %xmm5,%xmm6");
+	asm volatile("vcvtdq2pd %ymm5,%zmm6{%k7}");
+	asm volatile("vcvtqq2pd %zmm5,%zmm6");
+	asm volatile("vcvtpd2dq %xmm1,%xmm2");
+
+	/* AVX-512: Op code 0f eb */
+
+	asm volatile("por   %mm4,%mm6");
+	asm volatile("vpor   %ymm4,%ymm6,%ymm2");
+	asm volatile("vpord  %zmm4,%zmm5,%zmm6");
+	asm volatile("vporq  %zmm4,%zmm5,%zmm6");
+
+	/* AVX-512: Op code 0f ef */
+
+	asm volatile("pxor   %mm4,%mm6");
+	asm volatile("vpxor  %ymm4,%ymm6,%ymm2");
+	asm volatile("vpxord %zmm4,%zmm5,%zmm6");
+	asm volatile("vpxorq %zmm4,%zmm5,%zmm6");
+
+	/* AVX-512: Op code 0f 38 10 */
+
+	asm volatile("pblendvb %xmm1,%xmm0");
+	asm volatile("vpsrlvw %zmm4,%zmm5,%zmm6");
+	asm volatile("vpmovuswb %zmm5,%ymm6{%k7}");
+
+	/* AVX-512: Op code 0f 38 11 */
+
+	asm volatile("vpmovusdb %zmm5,%xmm6{%k7}");
+	asm volatile("vpsravw %zmm4,%zmm5,%zmm6");
+
+	/* AVX-512: Op code 0f 38 12 */
+
+	asm volatile("vpmovusqb %zmm5,%xmm6{%k7}");
+	asm volatile("vpsllvw %zmm4,%zmm5,%zmm6");
+
+	/* AVX-512: Op code 0f 38 13 */
+
+	asm volatile("vcvtph2ps %xmm3,%ymm5");
+	asm volatile("vcvtph2ps %ymm5,%zmm6{%k7}");
+	asm volatile("vpmovusdw %zmm5,%ymm6{%k7}");
+
+	/* AVX-512: Op code 0f 38 14 */
+
+	asm volatile("blendvps %xmm1,%xmm0");
+	asm volatile("vpmovusqw %zmm5,%xmm6{%k7}");
+	asm volatile("vprorvd %zmm4,%zmm5,%zmm6");
+	asm volatile("vprorvq %zmm4,%zmm5,%zmm6");
+
+	/* AVX-512: Op code 0f 38 15 */
+
+	asm volatile("blendvpd %xmm1,%xmm0");
+	asm volatile("vpmovusqd %zmm5,%ymm6{%k7}");
+	asm volatile("vprolvd %zmm4,%zmm5,%zmm6");
+	asm volatile("vprolvq %zmm4,%zmm5,%zmm6");
+
+	/* AVX-512: Op code 0f 38 16 */
+
+	asm volatile("vpermps %ymm4,%ymm6,%ymm2");
+	asm volatile("vpermps %ymm4,%ymm6,%ymm2{%k7}");
+	asm volatile("vpermpd %ymm4,%ymm6,%ymm2{%k7}");
+
+	/* AVX-512: Op code 0f 38 19 */
+
+	asm volatile("vbroadcastsd %xmm4,%ymm6");
+	asm volatile("vbroadcastf32x2 %xmm7,%zmm6");
+
+	/* AVX-512: Op code 0f 38 1a */
+
+	asm volatile("vbroadcastf128 (%ecx),%ymm4");
+	asm volatile("vbroadcastf32x4 (%ecx),%zmm6");
+	asm volatile("vbroadcastf64x2 (%ecx),%zmm6");
+
+	/* AVX-512: Op code 0f 38 1b */
+
+	asm volatile("vbroadcastf32x8 (%ecx),%zmm6");
+	asm volatile("vbroadcastf64x4 (%ecx),%zmm6");
+
+	/* AVX-512: Op code 0f 38 1f */
+
+	asm volatile("vpabsq %zmm4,%zmm6");
+
+	/* AVX-512: Op code 0f 38 20 */
+
+	asm volatile("vpmovsxbw %xmm4,%xmm5");
+	asm volatile("vpmovswb %zmm5,%ymm6{%k7}");
+
+	/* AVX-512: Op code 0f 38 21 */
+
+	asm volatile("vpmovsxbd %xmm4,%ymm6");
+	asm volatile("vpmovsdb %zmm5,%xmm6{%k7}");
+
+	/* AVX-512: Op code 0f 38 22 */
+
+	asm volatile("vpmovsxbq %xmm4,%ymm4");
+	asm volatile("vpmovsqb %zmm5,%xmm6{%k7}");
+
+	/* AVX-512: Op code 0f 38 23 */
+
+	asm volatile("vpmovsxwd %xmm4,%ymm4");
+	asm volatile("vpmovsdw %zmm5,%ymm6{%k7}");
+
+	/* AVX-512: Op code 0f 38 24 */
+
+	asm volatile("vpmovsxwq %xmm4,%ymm6");
+	asm volatile("vpmovsqw %zmm5,%xmm6{%k7}");
+
+	/* AVX-512: Op code 0f 38 25 */
+
+	asm volatile("vpmovsxdq %xmm4,%ymm4");
+	asm volatile("vpmovsqd %zmm5,%ymm6{%k7}");
+
+	/* AVX-512: Op code 0f 38 26 */
+
+	asm volatile("vptestmb %zmm5,%zmm6,%k5");
+	asm volatile("vptestmw %zmm5,%zmm6,%k5");
+	asm volatile("vptestnmb %zmm4,%zmm5,%k5");
+	asm volatile("vptestnmw %zmm4,%zmm5,%k5");
+
+	/* AVX-512: Op code 0f 38 27 */
+
+	asm volatile("vptestmd %zmm5,%zmm6,%k5");
+	asm volatile("vptestmq %zmm5,%zmm6,%k5");
+	asm volatile("vptestnmd %zmm4,%zmm5,%k5");
+	asm volatile("vptestnmq %zmm4,%zmm5,%k5");
+
+	/* AVX-512: Op code 0f 38 28 */
+
+	asm volatile("vpmuldq %ymm4,%ymm6,%ymm2");
+	asm volatile("vpmovm2b %k5,%zmm6");
+	asm volatile("vpmovm2w %k5,%zmm6");
+
+	/* AVX-512: Op code 0f 38 29 */
+
+	asm volatile("vpcmpeqq %ymm4,%ymm6,%ymm2");
+	asm volatile("vpmovb2m %zmm6,%k5");
+	asm volatile("vpmovw2m %zmm6,%k5");
+
+	/* AVX-512: Op code 0f 38 2a */
+
+	asm volatile("vmovntdqa (%ecx),%ymm4");
+	asm volatile("vpbroadcastmb2q %k6,%zmm1");
+
+	/* AVX-512: Op code 0f 38 2c */
+
+	asm volatile("vmaskmovps (%ecx),%ymm4,%ymm6");
+	asm volatile("vscalefps %zmm4,%zmm5,%zmm6");
+	asm volatile("vscalefpd %zmm4,%zmm5,%zmm6");
+
+	/* AVX-512: Op code 0f 38 2d */
+
+	asm volatile("vmaskmovpd (%ecx),%ymm4,%ymm6");
+	asm volatile("vscalefss %xmm4,%xmm5,%xmm6{%k7}");
+	asm volatile("vscalefsd %xmm4,%xmm5,%xmm6{%k7}");
+
+	/* AVX-512: Op code 0f 38 30 */
+
+	asm volatile("vpmovzxbw %xmm4,%ymm4");
+	asm volatile("vpmovwb %zmm5,%ymm6{%k7}");
+
+	/* AVX-512: Op code 0f 38 31 */
+
+	asm volatile("vpmovzxbd %xmm4,%ymm6");
+	asm volatile("vpmovdb %zmm5,%xmm6{%k7}");
+
+	/* AVX-512: Op code 0f 38 32 */
+
+	asm volatile("vpmovzxbq %xmm4,%ymm4");
+	asm volatile("vpmovqb %zmm5,%xmm6{%k7}");
+
+	/* AVX-512: Op code 0f 38 33 */
+
+	asm volatile("vpmovzxwd %xmm4,%ymm4");
+	asm volatile("vpmovdw %zmm5,%ymm6{%k7}");
+
+	/* AVX-512: Op code 0f 38 34 */
+
+	asm volatile("vpmovzxwq %xmm4,%ymm6");
+	asm volatile("vpmovqw %zmm5,%xmm6{%k7}");
+
+	/* AVX-512: Op code 0f 38 35 */
+
+	asm volatile("vpmovzxdq %xmm4,%ymm4");
+	asm volatile("vpmovqd %zmm5,%ymm6{%k7}");
+
+	/* AVX-512: Op code 0f 38 36 */
+
+	asm volatile("vpermd %ymm4,%ymm6,%ymm2");
+	asm volatile("vpermd %ymm4,%ymm6,%ymm2{%k7}");
+	asm volatile("vpermq %ymm4,%ymm6,%ymm2{%k7}");
+
+	/* AVX-512: Op code 0f 38 38 */
+
+	asm volatile("vpminsb %ymm4,%ymm6,%ymm2");
+	asm volatile("vpmovm2d %k5,%zmm6");
+	asm volatile("vpmovm2q %k5,%zmm6");
+
+	/* AVX-512: Op code 0f 38 39 */
+
+	asm volatile("vpminsd %xmm1,%xmm2,%xmm3");
+	asm volatile("vpminsd %zmm4,%zmm5,%zmm6");
+	asm volatile("vpminsq %zmm4,%zmm5,%zmm6");
+	asm volatile("vpmovd2m %zmm6,%k5");
+	asm volatile("vpmovq2m %zmm6,%k5");
+
+	/* AVX-512: Op code 0f 38 3a */
+
+	asm volatile("vpminuw %ymm4,%ymm6,%ymm2");
+	asm volatile("vpbroadcastmw2d %k6,%zmm6");
+
+	/* AVX-512: Op code 0f 38 3b */
+
+	asm volatile("vpminud %ymm4,%ymm6,%ymm2");
+	asm volatile("vpminud %zmm4,%zmm5,%zmm6");
+	asm volatile("vpminuq %zmm4,%zmm5,%zmm6");
+
+	/* AVX-512: Op code 0f 38 3d */
+
+	asm volatile("vpmaxsd %ymm4,%ymm6,%ymm2");
+	asm volatile("vpmaxsd %zmm4,%zmm5,%zmm6");
+	asm volatile("vpmaxsq %zmm4,%zmm5,%zmm6");
+
+	/* AVX-512: Op code 0f 38 3f */
+
+	asm volatile("vpmaxud %ymm4,%ymm6,%ymm2");
+	asm volatile("vpmaxud %zmm4,%zmm5,%zmm6");
+	asm volatile("vpmaxuq %zmm4,%zmm5,%zmm6");
+
+	/* AVX-512: Op code 0f 38 40 */
+
+	asm volatile("vpmulld %ymm4,%ymm6,%ymm2");
+	asm volatile("vpmulld %zmm4,%zmm5,%zmm6");
+	asm volatile("vpmullq %zmm4,%zmm5,%zmm6");
+
+	/* AVX-512: Op code 0f 38 42 */
+
+	asm volatile("vgetexpps %zmm5,%zmm6");
+	asm volatile("vgetexppd %zmm5,%zmm6");
+
+	/* AVX-512: Op code 0f 38 43 */
+
+	asm volatile("vgetexpss %xmm4,%xmm5,%xmm6{%k7}");
+	asm volatile("vgetexpsd %xmm2,%xmm3,%xmm4{%k7}");
+
+	/* AVX-512: Op code 0f 38 44 */
+
+	asm volatile("vplzcntd %zmm5,%zmm6");
+	asm volatile("vplzcntq %zmm5,%zmm6");
+
+	/* AVX-512: Op code 0f 38 46 */
+
+	asm volatile("vpsravd %ymm4,%ymm6,%ymm2");
+	asm volatile("vpsravd %zmm4,%zmm5,%zmm6");
+	asm volatile("vpsravq %zmm4,%zmm5,%zmm6");
+
+	/* AVX-512: Op code 0f 38 4c */
+
+	asm volatile("vrcp14ps %zmm5,%zmm6");
+	asm volatile("vrcp14pd %zmm5,%zmm6");
+
+	/* AVX-512: Op code 0f 38 4d */
+
+	asm volatile("vrcp14ss %xmm4,%xmm5,%xmm6{%k7}");
+	asm volatile("vrcp14sd %xmm4,%xmm5,%xmm6{%k7}");
+
+	/* AVX-512: Op code 0f 38 4e */
+
+	asm volatile("vrsqrt14ps %zmm5,%zmm6");
+	asm volatile("vrsqrt14pd %zmm5,%zmm6");
+
+	/* AVX-512: Op code 0f 38 4f */
+
+	asm volatile("vrsqrt14ss %xmm4,%xmm5,%xmm6{%k7}");
+	asm volatile("vrsqrt14sd %xmm4,%xmm5,%xmm6{%k7}");
+
+	/* AVX-512: Op code 0f 38 59 */
+
+	asm volatile("vpbroadcastq %xmm4,%xmm6");
+	asm volatile("vbroadcasti32x2 %xmm7,%zmm6");
+
+	/* AVX-512: Op code 0f 38 5a */
+
+	asm volatile("vbroadcasti128 (%ecx),%ymm4");
+	asm volatile("vbroadcasti32x4 (%ecx),%zmm6");
+	asm volatile("vbroadcasti64x2 (%ecx),%zmm6");
+
+	/* AVX-512: Op code 0f 38 5b */
+
+	asm volatile("vbroadcasti32x8 (%ecx),%zmm6");
+	asm volatile("vbroadcasti64x4 (%ecx),%zmm6");
+
+	/* AVX-512: Op code 0f 38 64 */
+
+	asm volatile("vpblendmd %zmm4,%zmm5,%zmm6");
+	asm volatile("vpblendmq %zmm4,%zmm5,%zmm6");
+
+	/* AVX-512: Op code 0f 38 65 */
+
+	asm volatile("vblendmps %zmm4,%zmm5,%zmm6");
+	asm volatile("vblendmpd %zmm4,%zmm5,%zmm6");
+
+	/* AVX-512: Op code 0f 38 66 */
+
+	asm volatile("vpblendmb %zmm4,%zmm5,%zmm6");
+	asm volatile("vpblendmw %zmm4,%zmm5,%zmm6");
+
+	/* AVX-512: Op code 0f 38 75 */
+
+	asm volatile("vpermi2b %zmm4,%zmm5,%zmm6");
+	asm volatile("vpermi2w %zmm4,%zmm5,%zmm6");
+
+	/* AVX-512: Op code 0f 38 76 */
+
+	asm volatile("vpermi2d %zmm4,%zmm5,%zmm6");
+	asm volatile("vpermi2q %zmm4,%zmm5,%zmm6");
+
+	/* AVX-512: Op code 0f 38 77 */
+
+	asm volatile("vpermi2ps %zmm4,%zmm5,%zmm6");
+	asm volatile("vpermi2pd %zmm4,%zmm5,%zmm6");
+
+	/* AVX-512: Op code 0f 38 7a */
+
+	asm volatile("vpbroadcastb %eax,%xmm3");
+
+	/* AVX-512: Op code 0f 38 7b */
+
+	asm volatile("vpbroadcastw %eax,%xmm3");
+
+	/* AVX-512: Op code 0f 38 7c */
+
+	asm volatile("vpbroadcastd %eax,%xmm3");
+
+	/* AVX-512: Op code 0f 38 7d */
+
+	asm volatile("vpermt2b %zmm4,%zmm5,%zmm6");
+	asm volatile("vpermt2w %zmm4,%zmm5,%zmm6");
+
+	/* AVX-512: Op code 0f 38 7e */
+
+	asm volatile("vpermt2d %zmm4,%zmm5,%zmm6");
+	asm volatile("vpermt2q %zmm4,%zmm5,%zmm6");
+
+	/* AVX-512: Op code 0f 38 7f */
+
+	asm volatile("vpermt2ps %zmm4,%zmm5,%zmm6");
+	asm volatile("vpermt2pd %zmm4,%zmm5,%zmm6");
+
+	/* AVX-512: Op code 0f 38 83 */
+
+	asm volatile("vpmultishiftqb %zmm4,%zmm5,%zmm6");
+
+	/* AVX-512: Op code 0f 38 88 */
+
+	asm volatile("vexpandps (%ecx),%zmm6");
+	asm volatile("vexpandpd (%ecx),%zmm6");
+
+	/* AVX-512: Op code 0f 38 89 */
+
+	asm volatile("vpexpandd (%ecx),%zmm6");
+	asm volatile("vpexpandq (%ecx),%zmm6");
+
+	/* AVX-512: Op code 0f 38 8a */
+
+	asm volatile("vcompressps %zmm6,(%ecx)");
+	asm volatile("vcompresspd %zmm6,(%ecx)");
+
+	/* AVX-512: Op code 0f 38 8b */
+
+	asm volatile("vpcompressd %zmm6,(%ecx)");
+	asm volatile("vpcompressq %zmm6,(%ecx)");
+
+	/* AVX-512: Op code 0f 38 8d */
+
+	asm volatile("vpermb %zmm4,%zmm5,%zmm6");
+	asm volatile("vpermw %zmm4,%zmm5,%zmm6");
+
+	/* AVX-512: Op code 0f 38 90 */
+
+	asm volatile("vpgatherdd %xmm2,0x02(%ebp,%xmm7,2),%xmm1");
+	asm volatile("vpgatherdq %xmm2,0x04(%ebp,%xmm7,2),%xmm1");
+	asm volatile("vpgatherdd 0x7b(%ebp,%zmm7,8),%zmm6{%k1}");
+	asm volatile("vpgatherdq 0x7b(%ebp,%ymm7,8),%zmm6{%k1}");
+
+	/* AVX-512: Op code 0f 38 91 */
+
+	asm volatile("vpgatherqd %xmm2,0x02(%ebp,%xmm7,2),%xmm1");
+	asm volatile("vpgatherqq %xmm2,0x02(%ebp,%xmm7,2),%xmm1");
+	asm volatile("vpgatherqd 0x7b(%ebp,%zmm7,8),%ymm6{%k1}");
+	asm volatile("vpgatherqq 0x7b(%ebp,%zmm7,8),%zmm6{%k1}");
+
+	/* AVX-512: Op code 0f 38 a0 */
+
+	asm volatile("vpscatterdd %zmm6,0x7b(%ebp,%zmm7,8){%k1}");
+	asm volatile("vpscatterdq %zmm6,0x7b(%ebp,%ymm7,8){%k1}");
+
+	/* AVX-512: Op code 0f 38 a1 */
+
+	asm volatile("vpscatterqd %ymm6,0x7b(%ebp,%zmm7,8){%k1}");
+	asm volatile("vpscatterqq %ymm6,0x7b(%ebp,%ymm7,8){%k1}");
+
+	/* AVX-512: Op code 0f 38 a2 */
+
+	asm volatile("vscatterdps %zmm6,0x7b(%ebp,%zmm7,8){%k1}");
+	asm volatile("vscatterdpd %zmm6,0x7b(%ebp,%ymm7,8){%k1}");
+
+	/* AVX-512: Op code 0f 38 a3 */
+
+	asm volatile("vscatterqps %ymm6,0x7b(%ebp,%zmm7,8){%k1}");
+	asm volatile("vscatterqpd %zmm6,0x7b(%ebp,%zmm7,8){%k1}");
+
+	/* AVX-512: Op code 0f 38 b4 */
+
+	asm volatile("vpmadd52luq %zmm4,%zmm5,%zmm6");
+
+	/* AVX-512: Op code 0f 38 b5 */
+
+	asm volatile("vpmadd52huq %zmm4,%zmm5,%zmm6");
+
+	/* AVX-512: Op code 0f 38 c4 */
+
+	asm volatile("vpconflictd %zmm5,%zmm6");
+	asm volatile("vpconflictq %zmm5,%zmm6");
+
+	/* AVX-512: Op code 0f 38 c8 */
+
+	asm volatile("vexp2ps %zmm6,%zmm7");
+	asm volatile("vexp2pd %zmm6,%zmm7");
+
+	/* AVX-512: Op code 0f 38 ca */
+
+	asm volatile("vrcp28ps %zmm6,%zmm7");
+	asm volatile("vrcp28pd %zmm6,%zmm7");
+
+	/* AVX-512: Op code 0f 38 cb */
+
+	asm volatile("vrcp28ss %xmm5,%xmm6,%xmm7{%k7}");
+	asm volatile("vrcp28sd %xmm5,%xmm6,%xmm7{%k7}");
+
+	/* AVX-512: Op code 0f 38 cc */
+
+	asm volatile("vrsqrt28ps %zmm6,%zmm7");
+	asm volatile("vrsqrt28pd %zmm6,%zmm7");
+
+	/* AVX-512: Op code 0f 38 cd */
+
+	asm volatile("vrsqrt28ss %xmm5,%xmm6,%xmm7{%k7}");
+	asm volatile("vrsqrt28sd %xmm5,%xmm6,%xmm7{%k7}");
+
+	/* AVX-512: Op code 0f 3a 03 */
+
+	asm volatile("valignd $0x12,%zmm5,%zmm6,%zmm7");
+	asm volatile("valignq $0x12,%zmm5,%zmm6,%zmm7");
+
+	/* AVX-512: Op code 0f 3a 08 */
+
+	asm volatile("vroundps $0x5,%ymm6,%ymm2");
+	asm volatile("vrndscaleps $0x12,%zmm5,%zmm6");
+
+	/* AVX-512: Op code 0f 3a 09 */
+
+	asm volatile("vroundpd $0x5,%ymm6,%ymm2");
+	asm volatile("vrndscalepd $0x12,%zmm5,%zmm6");
+
+	/* AVX-512: Op code 0f 3a 0a */
+
+	asm volatile("vroundss $0x5,%xmm4,%xmm6,%xmm2");
+	asm volatile("vrndscaless $0x12,%xmm4,%xmm5,%xmm6{%k7}");
+
+	/* AVX-512: Op code 0f 3a 0b */
+
+	asm volatile("vroundsd $0x5,%xmm4,%xmm6,%xmm2");
+	asm volatile("vrndscalesd $0x12,%xmm4,%xmm5,%xmm6{%k7}");
+
+	/* AVX-512: Op code 0f 3a 18 */
+
+	asm volatile("vinsertf128 $0x5,%xmm4,%ymm4,%ymm6");
+	asm volatile("vinsertf32x4 $0x12,%xmm4,%zmm5,%zmm6{%k7}");
+	asm volatile("vinsertf64x2 $0x12,%xmm4,%zmm5,%zmm6{%k7}");
+
+	/* AVX-512: Op code 0f 3a 19 */
+
+	asm volatile("vextractf128 $0x5,%ymm4,%xmm4");
+	asm volatile("vextractf32x4 $0x12,%zmm5,%xmm6{%k7}");
+	asm volatile("vextractf64x2 $0x12,%zmm5,%xmm6{%k7}");
+
+	/* AVX-512: Op code 0f 3a 1a */
+
+	asm volatile("vinsertf32x8 $0x12,%ymm5,%zmm6,%zmm7{%k7}");
+	asm volatile("vinsertf64x4 $0x12,%ymm5,%zmm6,%zmm7{%k7}");
+
+	/* AVX-512: Op code 0f 3a 1b */
+
+	asm volatile("vextractf32x8 $0x12,%zmm6,%ymm7{%k7}");
+	asm volatile("vextractf64x4 $0x12,%zmm6,%ymm7{%k7}");
+
+	/* AVX-512: Op code 0f 3a 1e */
+
+	asm volatile("vpcmpud $0x12,%zmm6,%zmm7,%k5");
+	asm volatile("vpcmpuq $0x12,%zmm6,%zmm7,%k5");
+
+	/* AVX-512: Op code 0f 3a 1f */
+
+	asm volatile("vpcmpd $0x12,%zmm6,%zmm7,%k5");
+	asm volatile("vpcmpq $0x12,%zmm6,%zmm7,%k5");
+
+	/* AVX-512: Op code 0f 3a 23 */
+
+	asm volatile("vshuff32x4 $0x12,%zmm5,%zmm6,%zmm7");
+	asm volatile("vshuff64x2 $0x12,%zmm5,%zmm6,%zmm7");
+
+	/* AVX-512: Op code 0f 3a 25 */
+
+	asm volatile("vpternlogd $0x12,%zmm5,%zmm6,%zmm7");
+	asm volatile("vpternlogq $0x12,%zmm5,%zmm6,%zmm7");
+
+	/* AVX-512: Op code 0f 3a 26 */
+
+	asm volatile("vgetmantps $0x12,%zmm6,%zmm7");
+	asm volatile("vgetmantpd $0x12,%zmm6,%zmm7");
+
+	/* AVX-512: Op code 0f 3a 27 */
+
+	asm volatile("vgetmantss $0x12,%xmm5,%xmm6,%xmm7{%k7}");
+	asm volatile("vgetmantsd $0x12,%xmm5,%xmm6,%xmm7{%k7}");
+
+	/* AVX-512: Op code 0f 3a 38 */
+
+	asm volatile("vinserti128 $0x5,%xmm4,%ymm4,%ymm6");
+	asm volatile("vinserti32x4 $0x12,%xmm4,%zmm5,%zmm6{%k7}");
+	asm volatile("vinserti64x2 $0x12,%xmm4,%zmm5,%zmm6{%k7}");
+
+	/* AVX-512: Op code 0f 3a 39 */
+
+	asm volatile("vextracti128 $0x5,%ymm4,%xmm6");
+	asm volatile("vextracti32x4 $0x12,%zmm5,%xmm6{%k7}");
+	asm volatile("vextracti64x2 $0x12,%zmm5,%xmm6{%k7}");
+
+	/* AVX-512: Op code 0f 3a 3a */
+
+	asm volatile("vinserti32x8 $0x12,%ymm5,%zmm6,%zmm7{%k7}");
+	asm volatile("vinserti64x4 $0x12,%ymm5,%zmm6,%zmm7{%k7}");
+
+	/* AVX-512: Op code 0f 3a 3b */
+
+	asm volatile("vextracti32x8 $0x12,%zmm6,%ymm7{%k7}");
+	asm volatile("vextracti64x4 $0x12,%zmm6,%ymm7{%k7}");
+
+	/* AVX-512: Op code 0f 3a 3e */
+
+	asm volatile("vpcmpub $0x12,%zmm6,%zmm7,%k5");
+	asm volatile("vpcmpuw $0x12,%zmm6,%zmm7,%k5");
 
-	/* bndstx bnd, mib */
+	/* AVX-512: Op code 0f 3a 3f */
 
-	asm volatile("bndstx %bnd0, (%rax)");
-	asm volatile("bndstx %bnd0, (%r8)");
-	asm volatile("bndstx %bnd0, (0x12345678)");
-	asm volatile("bndstx %bnd3, (%rax)");
-	asm volatile("bndstx %bnd0, (%rcx,%rax,1)");
-	asm volatile("bndstx %bnd0, 0x12345678(,%rax,1)");
-	asm volatile("bndstx %bnd0, (%rax,%rcx,1)");
-	asm volatile("bndstx %bnd0, 0x12(%rax)");
-	asm volatile("bndstx %bnd0, 0x12(%rbp)");
-	asm volatile("bndstx %bnd0, 0x12(%rcx,%rax,1)");
-	asm volatile("bndstx %bnd0, 0x12(%rbp,%rax,1)");
-	asm volatile("bndstx %bnd0, 0x12(%rax,%rcx,1)");
-	asm volatile("bndstx %bnd0, 0x12345678(%rax)");
-	asm volatile("bndstx %bnd0, 0x12345678(%rbp)");
-	asm volatile("bndstx %bnd0, 0x12345678(%rcx,%rax,1)");
-	asm volatile("bndstx %bnd0, 0x12345678(%rbp,%rax,1)");
-	asm volatile("bndstx %bnd0, 0x12345678(%rax,%rcx,1)");
+	asm volatile("vpcmpb $0x12,%zmm6,%zmm7,%k5");
+	asm volatile("vpcmpw $0x12,%zmm6,%zmm7,%k5");
 
-	/* bnd prefix on call, ret, jmp and all jcc */
+	/* AVX-512: Op code 0f 3a 42 */
 
-	asm volatile("bnd call label1");  /* Expecting: call unconditional 0 */
-	asm volatile("bnd call *(%eax)"); /* Expecting: call indirect      0 */
-	asm volatile("bnd ret");          /* Expecting: ret  indirect      0 */
-	asm volatile("bnd jmp label1");   /* Expecting: jmp  unconditional 0 */
-	asm volatile("bnd jmp label1");   /* Expecting: jmp  unconditional 0 */
-	asm volatile("bnd jmp *(%ecx)");  /* Expecting: jmp  indirect      0 */
-	asm volatile("bnd jne label1");   /* Expecting: jcc  conditional   0 */
+	asm volatile("vmpsadbw $0x5,%ymm4,%ymm6,%ymm2");
+	asm volatile("vdbpsadbw $0x12,%zmm4,%zmm5,%zmm6");
 
-	/* sha1rnds4 imm8, xmm2/m128, xmm1 */
+	/* AVX-512: Op code 0f 3a 43 */
 
-	asm volatile("sha1rnds4 $0x0, %xmm1, %xmm0");
-	asm volatile("sha1rnds4 $0x91, %xmm7, %xmm2");
-	asm volatile("sha1rnds4 $0x91, %xmm8, %xmm0");
-	asm volatile("sha1rnds4 $0x91, %xmm7, %xmm8");
-	asm volatile("sha1rnds4 $0x91, %xmm15, %xmm8");
-	asm volatile("sha1rnds4 $0x91, (%rax), %xmm0");
-	asm volatile("sha1rnds4 $0x91, (%r8), %xmm0");
-	asm volatile("sha1rnds4 $0x91, (0x12345678), %xmm0");
-	asm volatile("sha1rnds4 $0x91, (%rax), %xmm3");
-	asm volatile("sha1rnds4 $0x91, (%rcx,%rax,1), %xmm0");
-	asm volatile("sha1rnds4 $0x91, 0x12345678(,%rax,1), %xmm0");
-	asm volatile("sha1rnds4 $0x91, (%rax,%rcx,1), %xmm0");
-	asm volatile("sha1rnds4 $0x91, (%rax,%rcx,8), %xmm0");
-	asm volatile("sha1rnds4 $0x91, 0x12(%rax), %xmm0");
-	asm volatile("sha1rnds4 $0x91, 0x12(%rbp), %xmm0");
-	asm volatile("sha1rnds4 $0x91, 0x12(%rcx,%rax,1), %xmm0");
-	asm volatile("sha1rnds4 $0x91, 0x12(%rbp,%rax,1), %xmm0");
-	asm volatile("sha1rnds4 $0x91, 0x12(%rax,%rcx,1), %xmm0");
-	asm volatile("sha1rnds4 $0x91, 0x12(%rax,%rcx,8), %xmm0");
-	asm volatile("sha1rnds4 $0x91, 0x12345678(%rax), %xmm0");
-	asm volatile("sha1rnds4 $0x91, 0x12345678(%rbp), %xmm0");
-	asm volatile("sha1rnds4 $0x91, 0x12345678(%rcx,%rax,1), %xmm0");
-	asm volatile("sha1rnds4 $0x91, 0x12345678(%rbp,%rax,1), %xmm0");
-	asm volatile("sha1rnds4 $0x91, 0x12345678(%rax,%rcx,1), %xmm0");
-	asm volatile("sha1rnds4 $0x91, 0x12345678(%rax,%rcx,8), %xmm0");
-	asm volatile("sha1rnds4 $0x91, 0x12345678(%rax,%rcx,8), %xmm15");
+	asm volatile("vshufi32x4 $0x12,%zmm5,%zmm6,%zmm7");
+	asm volatile("vshufi64x2 $0x12,%zmm5,%zmm6,%zmm7");
 
-	/* sha1nexte xmm2/m128, xmm1 */
+	/* AVX-512: Op code 0f 3a 50 */
 
-	asm volatile("sha1nexte %xmm1, %xmm0");
-	asm volatile("sha1nexte %xmm7, %xmm2");
-	asm volatile("sha1nexte %xmm8, %xmm0");
-	asm volatile("sha1nexte %xmm7, %xmm8");
-	asm volatile("sha1nexte %xmm15, %xmm8");
-	asm volatile("sha1nexte (%rax), %xmm0");
-	asm volatile("sha1nexte (%r8), %xmm0");
-	asm volatile("sha1nexte (0x12345678), %xmm0");
-	asm volatile("sha1nexte (%rax), %xmm3");
-	asm volatile("sha1nexte (%rcx,%rax,1), %xmm0");
-	asm volatile("sha1nexte 0x12345678(,%rax,1), %xmm0");
-	asm volatile("sha1nexte (%rax,%rcx,1), %xmm0");
-	asm volatile("sha1nexte (%rax,%rcx,8), %xmm0");
-	asm volatile("sha1nexte 0x12(%rax), %xmm0");
-	asm volatile("sha1nexte 0x12(%rbp), %xmm0");
-	asm volatile("sha1nexte 0x12(%rcx,%rax,1), %xmm0");
-	asm volatile("sha1nexte 0x12(%rbp,%rax,1), %xmm0");
-	asm volatile("sha1nexte 0x12(%rax,%rcx,1), %xmm0");
-	asm volatile("sha1nexte 0x12(%rax,%rcx,8), %xmm0");
-	asm volatile("sha1nexte 0x12345678(%rax), %xmm0");
-	asm volatile("sha1nexte 0x12345678(%rbp), %xmm0");
-	asm volatile("sha1nexte 0x12345678(%rcx,%rax,1), %xmm0");
-	asm volatile("sha1nexte 0x12345678(%rbp,%rax,1), %xmm0");
-	asm volatile("sha1nexte 0x12345678(%rax,%rcx,1), %xmm0");
-	asm volatile("sha1nexte 0x12345678(%rax,%rcx,8), %xmm0");
-	asm volatile("sha1nexte 0x12345678(%rax,%rcx,8), %xmm15");
+	asm volatile("vrangeps $0x12,%zmm5,%zmm6,%zmm7");
+	asm volatile("vrangepd $0x12,%zmm5,%zmm6,%zmm7");
 
-	/* sha1msg1 xmm2/m128, xmm1 */
+	/* AVX-512: Op code 0f 3a 51 */
 
-	asm volatile("sha1msg1 %xmm1, %xmm0");
-	asm volatile("sha1msg1 %xmm7, %xmm2");
-	asm volatile("sha1msg1 %xmm8, %xmm0");
-	asm volatile("sha1msg1 %xmm7, %xmm8");
-	asm volatile("sha1msg1 %xmm15, %xmm8");
-	asm volatile("sha1msg1 (%rax), %xmm0");
-	asm volatile("sha1msg1 (%r8), %xmm0");
-	asm volatile("sha1msg1 (0x12345678), %xmm0");
-	asm volatile("sha1msg1 (%rax), %xmm3");
-	asm volatile("sha1msg1 (%rcx,%rax,1), %xmm0");
-	asm volatile("sha1msg1 0x12345678(,%rax,1), %xmm0");
-	asm volatile("sha1msg1 (%rax,%rcx,1), %xmm0");
-	asm volatile("sha1msg1 (%rax,%rcx,8), %xmm0");
-	asm volatile("sha1msg1 0x12(%rax), %xmm0");
-	asm volatile("sha1msg1 0x12(%rbp), %xmm0");
-	asm volatile("sha1msg1 0x12(%rcx,%rax,1), %xmm0");
-	asm volatile("sha1msg1 0x12(%rbp,%rax,1), %xmm0");
-	asm volatile("sha1msg1 0x12(%rax,%rcx,1), %xmm0");
-	asm volatile("sha1msg1 0x12(%rax,%rcx,8), %xmm0");
-	asm volatile("sha1msg1 0x12345678(%rax), %xmm0");
-	asm volatile("sha1msg1 0x12345678(%rbp), %xmm0");
-	asm volatile("sha1msg1 0x12345678(%rcx,%rax,1), %xmm0");
-	asm volatile("sha1msg1 0x12345678(%rbp,%rax,1), %xmm0");
-	asm volatile("sha1msg1 0x12345678(%rax,%rcx,1), %xmm0");
-	asm volatile("sha1msg1 0x12345678(%rax,%rcx,8), %xmm0");
-	asm volatile("sha1msg1 0x12345678(%rax,%rcx,8), %xmm15");
+	asm volatile("vrangess $0x12,%xmm5,%xmm6,%xmm7");
+	asm volatile("vrangesd $0x12,%xmm5,%xmm6,%xmm7");
 
-	/* sha1msg2 xmm2/m128, xmm1 */
+	/* AVX-512: Op code 0f 3a 54 */
 
-	asm volatile("sha1msg2 %xmm1, %xmm0");
-	asm volatile("sha1msg2 %xmm7, %xmm2");
-	asm volatile("sha1msg2 %xmm8, %xmm0");
-	asm volatile("sha1msg2 %xmm7, %xmm8");
-	asm volatile("sha1msg2 %xmm15, %xmm8");
-	asm volatile("sha1msg2 (%rax), %xmm0");
-	asm volatile("sha1msg2 (%r8), %xmm0");
-	asm volatile("sha1msg2 (0x12345678), %xmm0");
-	asm volatile("sha1msg2 (%rax), %xmm3");
-	asm volatile("sha1msg2 (%rcx,%rax,1), %xmm0");
-	asm volatile("sha1msg2 0x12345678(,%rax,1), %xmm0");
-	asm volatile("sha1msg2 (%rax,%rcx,1), %xmm0");
-	asm volatile("sha1msg2 (%rax,%rcx,8), %xmm0");
-	asm volatile("sha1msg2 0x12(%rax), %xmm0");
-	asm volatile("sha1msg2 0x12(%rbp), %xmm0");
-	asm volatile("sha1msg2 0x12(%rcx,%rax,1), %xmm0");
-	asm volatile("sha1msg2 0x12(%rbp,%rax,1), %xmm0");
-	asm volatile("sha1msg2 0x12(%rax,%rcx,1), %xmm0");
-	asm volatile("sha1msg2 0x12(%rax,%rcx,8), %xmm0");
-	asm volatile("sha1msg2 0x12345678(%rax), %xmm0");
-	asm volatile("sha1msg2 0x12345678(%rbp), %xmm0");
-	asm volatile("sha1msg2 0x12345678(%rcx,%rax,1), %xmm0");
-	asm volatile("sha1msg2 0x12345678(%rbp,%rax,1), %xmm0");
-	asm volatile("sha1msg2 0x12345678(%rax,%rcx,1), %xmm0");
-	asm volatile("sha1msg2 0x12345678(%rax,%rcx,8), %xmm0");
-	asm volatile("sha1msg2 0x12345678(%rax,%rcx,8), %xmm15");
+	asm volatile("vfixupimmps $0x12,%zmm5,%zmm6,%zmm7");
+	asm volatile("vfixupimmpd $0x12,%zmm5,%zmm6,%zmm7");
 
-	/* sha256rnds2 <XMM0>, xmm2/m128, xmm1 */
-	/* Note sha256rnds2 has an implicit operand 'xmm0' */
+	/* AVX-512: Op code 0f 3a 55 */
 
-	asm volatile("sha256rnds2 %xmm4, %xmm1");
-	asm volatile("sha256rnds2 %xmm7, %xmm2");
-	asm volatile("sha256rnds2 %xmm8, %xmm1");
-	asm volatile("sha256rnds2 %xmm7, %xmm8");
-	asm volatile("sha256rnds2 %xmm15, %xmm8");
-	asm volatile("sha256rnds2 (%rax), %xmm1");
-	asm volatile("sha256rnds2 (%r8), %xmm1");
-	asm volatile("sha256rnds2 (0x12345678), %xmm1");
-	asm volatile("sha256rnds2 (%rax), %xmm3");
-	asm volatile("sha256rnds2 (%rcx,%rax,1), %xmm1");
-	asm volatile("sha256rnds2 0x12345678(,%rax,1), %xmm1");
-	asm volatile("sha256rnds2 (%rax,%rcx,1), %xmm1");
-	asm volatile("sha256rnds2 (%rax,%rcx,8), %xmm1");
-	asm volatile("sha256rnds2 0x12(%rax), %xmm1");
-	asm volatile("sha256rnds2 0x12(%rbp), %xmm1");
-	asm volatile("sha256rnds2 0x12(%rcx,%rax,1), %xmm1");
-	asm volatile("sha256rnds2 0x12(%rbp,%rax,1), %xmm1");
-	asm volatile("sha256rnds2 0x12(%rax,%rcx,1), %xmm1");
-	asm volatile("sha256rnds2 0x12(%rax,%rcx,8), %xmm1");
-	asm volatile("sha256rnds2 0x12345678(%rax), %xmm1");
-	asm volatile("sha256rnds2 0x12345678(%rbp), %xmm1");
-	asm volatile("sha256rnds2 0x12345678(%rcx,%rax,1), %xmm1");
-	asm volatile("sha256rnds2 0x12345678(%rbp,%rax,1), %xmm1");
-	asm volatile("sha256rnds2 0x12345678(%rax,%rcx,1), %xmm1");
-	asm volatile("sha256rnds2 0x12345678(%rax,%rcx,8), %xmm1");
-	asm volatile("sha256rnds2 0x12345678(%rax,%rcx,8), %xmm15");
+	asm volatile("vfixupimmss $0x12,%xmm5,%xmm6,%xmm7{%k7}");
+	asm volatile("vfixupimmsd $0x12,%xmm5,%xmm6,%xmm7{%k7}");
 
-	/* sha256msg1 xmm2/m128, xmm1 */
+	/* AVX-512: Op code 0f 3a 56 */
 
-	asm volatile("sha256msg1 %xmm1, %xmm0");
-	asm volatile("sha256msg1 %xmm7, %xmm2");
-	asm volatile("sha256msg1 %xmm8, %xmm0");
-	asm volatile("sha256msg1 %xmm7, %xmm8");
-	asm volatile("sha256msg1 %xmm15, %xmm8");
-	asm volatile("sha256msg1 (%rax), %xmm0");
-	asm volatile("sha256msg1 (%r8), %xmm0");
-	asm volatile("sha256msg1 (0x12345678), %xmm0");
-	asm volatile("sha256msg1 (%rax), %xmm3");
-	asm volatile("sha256msg1 (%rcx,%rax,1), %xmm0");
-	asm volatile("sha256msg1 0x12345678(,%rax,1), %xmm0");
-	asm volatile("sha256msg1 (%rax,%rcx,1), %xmm0");
-	asm volatile("sha256msg1 (%rax,%rcx,8), %xmm0");
-	asm volatile("sha256msg1 0x12(%rax), %xmm0");
-	asm volatile("sha256msg1 0x12(%rbp), %xmm0");
-	asm volatile("sha256msg1 0x12(%rcx,%rax,1), %xmm0");
-	asm volatile("sha256msg1 0x12(%rbp,%rax,1), %xmm0");
-	asm volatile("sha256msg1 0x12(%rax,%rcx,1), %xmm0");
-	asm volatile("sha256msg1 0x12(%rax,%rcx,8), %xmm0");
-	asm volatile("sha256msg1 0x12345678(%rax), %xmm0");
-	asm volatile("sha256msg1 0x12345678(%rbp), %xmm0");
-	asm volatile("sha256msg1 0x12345678(%rcx,%rax,1), %xmm0");
-	asm volatile("sha256msg1 0x12345678(%rbp,%rax,1), %xmm0");
-	asm volatile("sha256msg1 0x12345678(%rax,%rcx,1), %xmm0");
-	asm volatile("sha256msg1 0x12345678(%rax,%rcx,8), %xmm0");
-	asm volatile("sha256msg1 0x12345678(%rax,%rcx,8), %xmm15");
+	asm volatile("vreduceps $0x12,%zmm6,%zmm7");
+	asm volatile("vreducepd $0x12,%zmm6,%zmm7");
 
-	/* sha256msg2 xmm2/m128, xmm1 */
+	/* AVX-512: Op code 0f 3a 57 */
 
-	asm volatile("sha256msg2 %xmm1, %xmm0");
-	asm volatile("sha256msg2 %xmm7, %xmm2");
-	asm volatile("sha256msg2 %xmm8, %xmm0");
-	asm volatile("sha256msg2 %xmm7, %xmm8");
-	asm volatile("sha256msg2 %xmm15, %xmm8");
-	asm volatile("sha256msg2 (%rax), %xmm0");
-	asm volatile("sha256msg2 (%r8), %xmm0");
-	asm volatile("sha256msg2 (0x12345678), %xmm0");
-	asm volatile("sha256msg2 (%rax), %xmm3");
-	asm volatile("sha256msg2 (%rcx,%rax,1), %xmm0");
-	asm volatile("sha256msg2 0x12345678(,%rax,1), %xmm0");
-	asm volatile("sha256msg2 (%rax,%rcx,1), %xmm0");
-	asm volatile("sha256msg2 (%rax,%rcx,8), %xmm0");
-	asm volatile("sha256msg2 0x12(%rax), %xmm0");
-	asm volatile("sha256msg2 0x12(%rbp), %xmm0");
-	asm volatile("sha256msg2 0x12(%rcx,%rax,1), %xmm0");
-	asm volatile("sha256msg2 0x12(%rbp,%rax,1), %xmm0");
-	asm volatile("sha256msg2 0x12(%rax,%rcx,1), %xmm0");
-	asm volatile("sha256msg2 0x12(%rax,%rcx,8), %xmm0");
-	asm volatile("sha256msg2 0x12345678(%rax), %xmm0");
-	asm volatile("sha256msg2 0x12345678(%rbp), %xmm0");
-	asm volatile("sha256msg2 0x12345678(%rcx,%rax,1), %xmm0");
-	asm volatile("sha256msg2 0x12345678(%rbp,%rax,1), %xmm0");
-	asm volatile("sha256msg2 0x12345678(%rax,%rcx,1), %xmm0");
-	asm volatile("sha256msg2 0x12345678(%rax,%rcx,8), %xmm0");
-	asm volatile("sha256msg2 0x12345678(%rax,%rcx,8), %xmm15");
+	asm volatile("vreducess $0x12,%xmm5,%xmm6,%xmm7");
+	asm volatile("vreducesd $0x12,%xmm5,%xmm6,%xmm7");
 
-	/* clflushopt m8 */
+	/* AVX-512: Op code 0f 3a 66 */
 
-	asm volatile("clflushopt (%rax)");
-	asm volatile("clflushopt (%r8)");
-	asm volatile("clflushopt (0x12345678)");
-	asm volatile("clflushopt 0x12345678(%rax,%rcx,8)");
-	asm volatile("clflushopt 0x12345678(%r8,%rcx,8)");
-	/* Also check instructions in the same group encoding as clflushopt */
-	asm volatile("clflush (%rax)");
-	asm volatile("clflush (%r8)");
-	asm volatile("sfence");
+	asm volatile("vfpclassps $0x12,%zmm7,%k5");
+	asm volatile("vfpclasspd $0x12,%zmm7,%k5");
 
-	/* clwb m8 */
+	/* AVX-512: Op code 0f 3a 67 */
 
-	asm volatile("clwb (%rax)");
-	asm volatile("clwb (%r8)");
-	asm volatile("clwb (0x12345678)");
-	asm volatile("clwb 0x12345678(%rax,%rcx,8)");
-	asm volatile("clwb 0x12345678(%r8,%rcx,8)");
-	/* Also check instructions in the same group encoding as clwb */
-	asm volatile("xsaveopt (%rax)");
-	asm volatile("xsaveopt (%r8)");
-	asm volatile("mfence");
+	asm volatile("vfpclassss $0x12,%xmm7,%k5");
+	asm volatile("vfpclasssd $0x12,%xmm7,%k5");
 
-	/* xsavec mem */
+	/* AVX-512: Op code 0f 72 (Grp13) */
 
-	asm volatile("xsavec (%rax)");
-	asm volatile("xsavec (%r8)");
-	asm volatile("xsavec (0x12345678)");
-	asm volatile("xsavec 0x12345678(%rax,%rcx,8)");
-	asm volatile("xsavec 0x12345678(%r8,%rcx,8)");
+	asm volatile("vprord $0x12,%zmm5,%zmm6");
+	asm volatile("vprorq $0x12,%zmm5,%zmm6");
+	asm volatile("vprold $0x12,%zmm5,%zmm6");
+	asm volatile("vprolq $0x12,%zmm5,%zmm6");
+	asm volatile("psrad  $0x2,%mm6");
+	asm volatile("vpsrad $0x5,%ymm6,%ymm2");
+	asm volatile("vpsrad $0x5,%zmm6,%zmm2");
+	asm volatile("vpsraq $0x5,%zmm6,%zmm2");
 
-	/* xsaves mem */
+	/* AVX-512: Op code 0f 38 c6 (Grp18) */
 
-	asm volatile("xsaves (%rax)");
-	asm volatile("xsaves (%r8)");
-	asm volatile("xsaves (0x12345678)");
-	asm volatile("xsaves 0x12345678(%rax,%rcx,8)");
-	asm volatile("xsaves 0x12345678(%r8,%rcx,8)");
+	asm volatile("vgatherpf0dps 0x7b(%ebp,%zmm7,8){%k1}");
+	asm volatile("vgatherpf0dpd 0x7b(%ebp,%ymm7,8){%k1}");
+	asm volatile("vgatherpf1dps 0x7b(%ebp,%zmm7,8){%k1}");
+	asm volatile("vgatherpf1dpd 0x7b(%ebp,%ymm7,8){%k1}");
+	asm volatile("vscatterpf0dps 0x7b(%ebp,%zmm7,8){%k1}");
+	asm volatile("vscatterpf0dpd 0x7b(%ebp,%ymm7,8){%k1}");
+	asm volatile("vscatterpf1dps 0x7b(%ebp,%zmm7,8){%k1}");
+	asm volatile("vscatterpf1dpd 0x7b(%ebp,%ymm7,8){%k1}");
 
-	/* xrstors mem */
+	/* AVX-512: Op code 0f 38 c7 (Grp19) */
 
-	asm volatile("xrstors (%rax)");
-	asm volatile("xrstors (%r8)");
-	asm volatile("xrstors (0x12345678)");
-	asm volatile("xrstors 0x12345678(%rax,%rcx,8)");
-	asm volatile("xrstors 0x12345678(%r8,%rcx,8)");
+	asm volatile("vgatherpf0qps 0x7b(%ebp,%zmm7,8){%k1}");
+	asm volatile("vgatherpf0qpd 0x7b(%ebp,%zmm7,8){%k1}");
+	asm volatile("vgatherpf1qps 0x7b(%ebp,%zmm7,8){%k1}");
+	asm volatile("vgatherpf1qpd 0x7b(%ebp,%zmm7,8){%k1}");
+	asm volatile("vscatterpf0qps 0x7b(%ebp,%zmm7,8){%k1}");
+	asm volatile("vscatterpf0qpd 0x7b(%ebp,%zmm7,8){%k1}");
+	asm volatile("vscatterpf1qps 0x7b(%ebp,%zmm7,8){%k1}");
+	asm volatile("vscatterpf1qpd 0x7b(%ebp,%zmm7,8){%k1}");
 
-#else  /* #ifdef __x86_64__ */
+	/* AVX-512: Examples */
+
+	asm volatile("vaddpd %zmm4,%zmm5,%zmm6");
+	asm volatile("vaddpd %zmm4,%zmm5,%zmm6{%k7}");
+	asm volatile("vaddpd %zmm4,%zmm5,%zmm6{%k7}{z}");
+	asm volatile("vaddpd {rn-sae},%zmm4,%zmm5,%zmm6");
+	asm volatile("vaddpd {ru-sae},%zmm4,%zmm5,%zmm6");
+	asm volatile("vaddpd {rd-sae},%zmm4,%zmm5,%zmm6");
+	asm volatile("vaddpd {rz-sae},%zmm4,%zmm5,%zmm6");
+	asm volatile("vaddpd (%ecx),%zmm5,%zmm6");
+	asm volatile("vaddpd 0x123(%eax,%ecx,8),%zmm5,%zmm6");
+	asm volatile("vaddpd (%ecx){1to8},%zmm5,%zmm6");
+	asm volatile("vaddpd 0x1fc0(%edx),%zmm5,%zmm6");
+	asm volatile("vaddpd 0x3f8(%edx){1to8},%zmm5,%zmm6");
+	asm volatile("vcmpeq_uqps 0x1fc(%edx){1to16},%zmm6,%k5");
+	asm volatile("vcmpltsd 0x123(%eax,%ecx,8),%xmm3,%k5{%k7}");
+	asm volatile("vcmplesd {sae},%xmm4,%xmm5,%k5{%k7}");
+	asm volatile("vgetmantss $0x5b,0x123(%eax,%ecx,8),%xmm4,%xmm5{%k7}");
 
 	/* bndmk m32, bnd */
 
--- zfcpdump-kernel-4.4.orig/tools/perf/arch/x86/util/intel-pt.c
+++ zfcpdump-kernel-4.4/tools/perf/arch/x86/util/intel-pt.c
@@ -499,7 +499,7 @@ static int intel_pt_recording_options(st
 	struct intel_pt_recording *ptr =
 			container_of(itr, struct intel_pt_recording, itr);
 	struct perf_pmu *intel_pt_pmu = ptr->intel_pt_pmu;
-	bool have_timing_info;
+	bool have_timing_info, need_immediate = false;
 	struct perf_evsel *evsel, *intel_pt_evsel = NULL;
 	const struct cpu_map *cpus = evlist->cpus;
 	bool privileged = geteuid() == 0 || perf_event_paranoid() < 0;
@@ -653,6 +653,7 @@ static int intel_pt_recording_options(st
 				ptr->have_sched_switch = 3;
 			} else {
 				opts->record_switch_events = true;
+				need_immediate = true;
 				if (cpu_wide)
 					ptr->have_sched_switch = 3;
 				else
@@ -698,6 +699,9 @@ static int intel_pt_recording_options(st
 		tracking_evsel->attr.freq = 0;
 		tracking_evsel->attr.sample_period = 1;
 
+		if (need_immediate)
+			tracking_evsel->immediate = true;
+
 		/* In per-cpu case, always need the time of mmap events etc */
 		if (!cpu_map__empty(cpus)) {
 			perf_evsel__set_sample_bit(tracking_evsel, TIME);
--- zfcpdump-kernel-4.4.orig/tools/perf/arch/x86/util/kvm-stat.c
+++ zfcpdump-kernel-4.4/tools/perf/arch/x86/util/kvm-stat.c
@@ -1,5 +1,7 @@
 #include "../../util/kvm-stat.h"
-#include <asm/kvm_perf.h>
+#include <asm/svm.h>
+#include <asm/vmx.h>
+#include <asm/kvm.h>
 
 define_exit_reasons_table(vmx_exit_reasons, VMX_EXIT_REASONS);
 define_exit_reasons_table(svm_exit_reasons, SVM_EXIT_REASONS);
@@ -11,6 +13,12 @@ static struct kvm_events_ops exit_events
 	.name = "VM-EXIT"
 };
 
+const char *vcpu_id_str = "vcpu_id";
+const int decode_str_len = 20;
+const char *kvm_exit_reason = "exit_reason";
+const char *kvm_entry_trace = "kvm:kvm_entry";
+const char *kvm_exit_trace = "kvm:kvm_exit";
+
 /*
  * For the mmio events, we treat:
  * the time of MMIO write: kvm_mmio(KVM_TRACE_MMIO_WRITE...) -> kvm_entry
@@ -65,7 +73,7 @@ static void mmio_event_decode_key(struct
 				  struct event_key *key,
 				  char *decode)
 {
-	scnprintf(decode, DECODE_STR_LEN, "%#lx:%s",
+	scnprintf(decode, decode_str_len, "%#lx:%s",
 		  (unsigned long)key->key,
 		  key->info == KVM_TRACE_MMIO_WRITE ? "W" : "R");
 }
@@ -109,7 +117,7 @@ static void ioport_event_decode_key(stru
 				    struct event_key *key,
 				    char *decode)
 {
-	scnprintf(decode, DECODE_STR_LEN, "%#llx:%s",
+	scnprintf(decode, decode_str_len, "%#llx:%s",
 		  (unsigned long long)key->key,
 		  key->info ? "POUT" : "PIN");
 }
@@ -121,7 +129,7 @@ static struct kvm_events_ops ioport_even
 	.name = "IO Port Access"
 };
 
-const char * const kvm_events_tp[] = {
+const char *kvm_events_tp[] = {
 	"kvm:kvm_entry",
 	"kvm:kvm_exit",
 	"kvm:kvm_mmio",
--- zfcpdump-kernel-4.4.orig/tools/perf/builtin-kvm.c
+++ zfcpdump-kernel-4.4/tools/perf/builtin-kvm.c
@@ -30,7 +30,6 @@
 #include <math.h>
 
 #ifdef HAVE_KVM_STAT_SUPPORT
-#include <asm/kvm_perf.h>
 #include "util/kvm-stat.h"
 
 void exit_event_get_key(struct perf_evsel *evsel,
@@ -38,12 +37,12 @@ void exit_event_get_key(struct perf_evse
 			struct event_key *key)
 {
 	key->info = 0;
-	key->key = perf_evsel__intval(evsel, sample, KVM_EXIT_REASON);
+	key->key = perf_evsel__intval(evsel, sample, kvm_exit_reason);
 }
 
 bool kvm_exit_event(struct perf_evsel *evsel)
 {
-	return !strcmp(evsel->name, KVM_EXIT_TRACE);
+	return !strcmp(evsel->name, kvm_exit_trace);
 }
 
 bool exit_event_begin(struct perf_evsel *evsel,
@@ -59,7 +58,7 @@ bool exit_event_begin(struct perf_evsel
 
 bool kvm_entry_event(struct perf_evsel *evsel)
 {
-	return !strcmp(evsel->name, KVM_ENTRY_TRACE);
+	return !strcmp(evsel->name, kvm_entry_trace);
 }
 
 bool exit_event_end(struct perf_evsel *evsel,
@@ -91,7 +90,7 @@ void exit_event_decode_key(struct perf_k
 	const char *exit_reason = get_exit_reason(kvm, key->exit_reasons,
 						  key->key);
 
-	scnprintf(decode, DECODE_STR_LEN, "%s", exit_reason);
+	scnprintf(decode, decode_str_len, "%s", exit_reason);
 }
 
 static bool register_kvm_events_ops(struct perf_kvm_stat *kvm)
@@ -357,7 +356,7 @@ static bool handle_end_event(struct perf
 	time_diff = sample->time - time_begin;
 
 	if (kvm->duration && time_diff > kvm->duration) {
-		char decode[DECODE_STR_LEN];
+		char decode[decode_str_len];
 
 		kvm->events_ops->decode_key(kvm, &event->key, decode);
 		if (!skip_event(decode)) {
@@ -385,7 +384,8 @@ struct vcpu_event_record *per_vcpu_recor
 			return NULL;
 		}
 
-		vcpu_record->vcpu_id = perf_evsel__intval(evsel, sample, VCPU_ID);
+		vcpu_record->vcpu_id = perf_evsel__intval(evsel, sample,
+							  vcpu_id_str);
 		thread__set_priv(thread, vcpu_record);
 	}
 
@@ -574,7 +574,7 @@ static void show_timeofday(void)
 
 static void print_result(struct perf_kvm_stat *kvm)
 {
-	char decode[DECODE_STR_LEN];
+	char decode[decode_str_len];
 	struct kvm_event *event;
 	int vcpu = kvm->trace_vcpu;
 
@@ -585,7 +585,7 @@ static void print_result(struct perf_kvm
 
 	pr_info("\n\n");
 	print_vcpu_info(kvm);
-	pr_info("%*s ", DECODE_STR_LEN, kvm->events_ops->name);
+	pr_info("%*s ", decode_str_len, kvm->events_ops->name);
 	pr_info("%10s ", "Samples");
 	pr_info("%9s ", "Samples%");
 
@@ -604,7 +604,7 @@ static void print_result(struct perf_kvm
 		min = get_event_min(event, vcpu);
 
 		kvm->events_ops->decode_key(kvm, &event->key, decode);
-		pr_info("%*s ", DECODE_STR_LEN, decode);
+		pr_info("%*s ", decode_str_len, decode);
 		pr_info("%10llu ", (unsigned long long)ecount);
 		pr_info("%8.2f%% ", (double)ecount / kvm->total_count * 100);
 		pr_info("%8.2f%% ", (double)etime / kvm->total_time * 100);
@@ -1132,6 +1132,11 @@ exit:
 		_p;			\
 	})
 
+int __weak setup_kvm_events_tp(struct perf_kvm_stat *kvm __maybe_unused)
+{
+	return 0;
+}
+
 static int
 kvm_events_record(struct perf_kvm_stat *kvm, int argc, const char **argv)
 {
@@ -1148,7 +1153,14 @@ kvm_events_record(struct perf_kvm_stat *
 		NULL
 	};
 	const char * const *events_tp;
+	int ret;
+
 	events_tp_size = 0;
+	ret = setup_kvm_events_tp(kvm);
+	if (ret < 0) {
+		pr_err("Unable to setup the kvm tracepoints\n");
+		return ret;
+	}
 
 	for (events_tp = kvm_events_tp; *events_tp; events_tp++)
 		events_tp_size++;
@@ -1378,6 +1390,12 @@ static int kvm_events_live(struct perf_k
 	/*
 	 * generate the event list
 	 */
+	err = setup_kvm_events_tp(kvm);
+	if (err < 0) {
+		pr_err("Unable to setup the kvm tracepoints\n");
+		return err;
+	}
+
 	kvm->evlist = kvm_live_event_list();
 	if (kvm->evlist == NULL) {
 		err = -1;
--- zfcpdump-kernel-4.4.orig/tools/perf/tests/bpf.c
+++ zfcpdump-kernel-4.4/tools/perf/tests/bpf.c
@@ -146,7 +146,7 @@ prepare_bpf(void *obj_buf, size_t obj_bu
 	return obj;
 }
 
-static int __test__bpf(int index)
+static int __test__bpf(int idx)
 {
 	int ret;
 	void *obj_buf;
@@ -154,27 +154,27 @@ static int __test__bpf(int index)
 	struct bpf_object *obj;
 
 	ret = test_llvm__fetch_bpf_obj(&obj_buf, &obj_buf_sz,
-				       bpf_testcase_table[index].prog_id,
+				       bpf_testcase_table[idx].prog_id,
 				       true);
 	if (ret != TEST_OK || !obj_buf || !obj_buf_sz) {
 		pr_debug("Unable to get BPF object, %s\n",
-			 bpf_testcase_table[index].msg_compile_fail);
-		if (index == 0)
+			 bpf_testcase_table[idx].msg_compile_fail);
+		if (idx == 0)
 			return TEST_SKIP;
 		else
 			return TEST_FAIL;
 	}
 
 	obj = prepare_bpf(obj_buf, obj_buf_sz,
-			  bpf_testcase_table[index].name);
+			  bpf_testcase_table[idx].name);
 	if (!obj) {
 		ret = TEST_FAIL;
 		goto out;
 	}
 
 	ret = do_test(obj,
-		      bpf_testcase_table[index].target_func,
-		      bpf_testcase_table[index].expect_result);
+		      bpf_testcase_table[idx].target_func,
+		      bpf_testcase_table[idx].expect_result);
 out:
 	bpf__clear();
 	return ret;
--- zfcpdump-kernel-4.4.orig/tools/perf/tests/llvm.c
+++ zfcpdump-kernel-4.4/tools/perf/tests/llvm.c
@@ -50,7 +50,7 @@ static struct {
 int
 test_llvm__fetch_bpf_obj(void **p_obj_buf,
 			 size_t *p_obj_buf_sz,
-			 enum test_llvm__testcase index,
+			 enum test_llvm__testcase idx,
 			 bool force)
 {
 	const char *source;
@@ -59,11 +59,11 @@ test_llvm__fetch_bpf_obj(void **p_obj_bu
 	char *tmpl_new = NULL, *clang_opt_new = NULL;
 	int err, old_verbose, ret = TEST_FAIL;
 
-	if (index >= __LLVM_TESTCASE_MAX)
+	if (idx >= __LLVM_TESTCASE_MAX)
 		return TEST_FAIL;
 
-	source = bpf_source_table[index].source;
-	desc = bpf_source_table[index].desc;
+	source = bpf_source_table[idx].source;
+	desc = bpf_source_table[idx].desc;
 
 	perf_config(perf_config_cb, NULL);
 
--- zfcpdump-kernel-4.4.orig/tools/perf/ui/browsers/hists.c
+++ zfcpdump-kernel-4.4/tools/perf/ui/browsers/hists.c
@@ -2059,10 +2059,12 @@ skip_annotation:
 			 *
 			 * See hist_browser__show_entry.
 			 */
-			nr_options += add_script_opt(browser,
-						     &actions[nr_options],
-						     &options[nr_options],
-						     NULL, browser->selection->sym);
+			if (sort__has_sym && browser->selection->sym) {
+				nr_options += add_script_opt(browser,
+							     &actions[nr_options],
+							     &options[nr_options],
+							     NULL, browser->selection->sym);
+			}
 		}
 		nr_options += add_script_opt(browser, &actions[nr_options],
 					     &options[nr_options], NULL, NULL);
--- zfcpdump-kernel-4.4.orig/tools/perf/util/event.c
+++ zfcpdump-kernel-4.4/tools/perf/util/event.c
@@ -274,7 +274,7 @@ int perf_event__synthesize_mmap_events(s
 		strcpy(execname, "");
 
 		/* 00400000-0040c000 r-xp 00000000 fd:01 41038  /bin/cat */
-		n = sscanf(bf, "%"PRIx64"-%"PRIx64" %s %"PRIx64" %x:%x %u %s\n",
+		n = sscanf(bf, "%"PRIx64"-%"PRIx64" %s %"PRIx64" %x:%x %u %[^\n]\n",
 		       &event->mmap2.start, &event->mmap2.len, prot,
 		       &event->mmap2.pgoff, &event->mmap2.maj,
 		       &event->mmap2.min,
--- zfcpdump-kernel-4.4.orig/tools/perf/util/evlist.c
+++ zfcpdump-kernel-4.4/tools/perf/util/evlist.c
@@ -1211,12 +1211,12 @@ void perf_evlist__set_maps(struct perf_e
 	 */
 	if (cpus != evlist->cpus) {
 		cpu_map__put(evlist->cpus);
-		evlist->cpus = cpus;
+		evlist->cpus = cpu_map__get(cpus);
 	}
 
 	if (threads != evlist->threads) {
 		thread_map__put(evlist->threads);
-		evlist->threads = threads;
+		evlist->threads = thread_map__get(threads);
 	}
 
 	perf_evlist__propagate_maps(evlist);
--- zfcpdump-kernel-4.4.orig/tools/perf/util/intel-pt-decoder/gen-insn-attr-x86.awk
+++ zfcpdump-kernel-4.4/tools/perf/util/intel-pt-decoder/gen-insn-attr-x86.awk
@@ -72,12 +72,14 @@ BEGIN {
 	lprefix_expr = "\\((66|F2|F3)\\)"
 	max_lprefix = 4
 
-	# All opcodes starting with lower-case 'v' or with (v1) superscript
+	# All opcodes starting with lower-case 'v', 'k' or with (v1) superscript
 	# accepts VEX prefix
-	vexok_opcode_expr = "^v.*"
+	vexok_opcode_expr = "^[vk].*"
 	vexok_expr = "\\(v1\\)"
 	# All opcodes with (v) superscript supports *only* VEX prefix
 	vexonly_expr = "\\(v\\)"
+	# All opcodes with (ev) superscript supports *only* EVEX prefix
+	evexonly_expr = "\\(ev\\)"
 
 	prefix_expr = "\\(Prefix\\)"
 	prefix_num["Operand-Size"] = "INAT_PFX_OPNDSZ"
@@ -95,6 +97,7 @@ BEGIN {
 	prefix_num["Address-Size"] = "INAT_PFX_ADDRSZ"
 	prefix_num["VEX+1byte"] = "INAT_PFX_VEX2"
 	prefix_num["VEX+2byte"] = "INAT_PFX_VEX3"
+	prefix_num["EVEX"] = "INAT_PFX_EVEX"
 
 	clear_vars()
 }
@@ -319,7 +322,9 @@ function convert_operands(count,opnd,
 			flags = add_flags(flags, "INAT_MODRM")
 
 		# check VEX codes
-		if (match(ext, vexonly_expr))
+		if (match(ext, evexonly_expr))
+			flags = add_flags(flags, "INAT_VEXOK | INAT_EVEXONLY")
+		else if (match(ext, vexonly_expr))
 			flags = add_flags(flags, "INAT_VEXOK | INAT_VEXONLY")
 		else if (match(ext, vexok_expr) || match(opcode, vexok_opcode_expr))
 			flags = add_flags(flags, "INAT_VEXOK")
--- zfcpdump-kernel-4.4.orig/tools/perf/util/intel-pt-decoder/inat.h
+++ zfcpdump-kernel-4.4/tools/perf/util/intel-pt-decoder/inat.h
@@ -48,6 +48,7 @@
 /* AVX VEX prefixes */
 #define INAT_PFX_VEX2	13	/* 2-bytes VEX prefix */
 #define INAT_PFX_VEX3	14	/* 3-bytes VEX prefix */
+#define INAT_PFX_EVEX	15	/* EVEX prefix */
 
 #define INAT_LSTPFX_MAX	3
 #define INAT_LGCPFX_MAX	11
@@ -89,6 +90,7 @@
 #define INAT_VARIANT	(1 << (INAT_FLAG_OFFS + 4))
 #define INAT_VEXOK	(1 << (INAT_FLAG_OFFS + 5))
 #define INAT_VEXONLY	(1 << (INAT_FLAG_OFFS + 6))
+#define INAT_EVEXONLY	(1 << (INAT_FLAG_OFFS + 7))
 /* Attribute making macros for attribute tables */
 #define INAT_MAKE_PREFIX(pfx)	(pfx << INAT_PFX_OFFS)
 #define INAT_MAKE_ESCAPE(esc)	(esc << INAT_ESC_OFFS)
@@ -141,7 +143,13 @@ static inline int inat_last_prefix_id(in
 static inline int inat_is_vex_prefix(insn_attr_t attr)
 {
 	attr &= INAT_PFX_MASK;
-	return attr == INAT_PFX_VEX2 || attr == INAT_PFX_VEX3;
+	return attr == INAT_PFX_VEX2 || attr == INAT_PFX_VEX3 ||
+	       attr == INAT_PFX_EVEX;
+}
+
+static inline int inat_is_evex_prefix(insn_attr_t attr)
+{
+	return (attr & INAT_PFX_MASK) == INAT_PFX_EVEX;
 }
 
 static inline int inat_is_vex3_prefix(insn_attr_t attr)
@@ -216,6 +224,11 @@ static inline int inat_accept_vex(insn_a
 
 static inline int inat_must_vex(insn_attr_t attr)
 {
-	return attr & INAT_VEXONLY;
+	return attr & (INAT_VEXONLY | INAT_EVEXONLY);
+}
+
+static inline int inat_must_evex(insn_attr_t attr)
+{
+	return attr & INAT_EVEXONLY;
 }
 #endif
--- zfcpdump-kernel-4.4.orig/tools/perf/util/intel-pt-decoder/insn.c
+++ zfcpdump-kernel-4.4/tools/perf/util/intel-pt-decoder/insn.c
@@ -155,14 +155,24 @@ found:
 			/*
 			 * In 32-bits mode, if the [7:6] bits (mod bits of
 			 * ModRM) on the second byte are not 11b, it is
-			 * LDS or LES.
+			 * LDS or LES or BOUND.
 			 */
 			if (X86_MODRM_MOD(b2) != 3)
 				goto vex_end;
 		}
 		insn->vex_prefix.bytes[0] = b;
 		insn->vex_prefix.bytes[1] = b2;
-		if (inat_is_vex3_prefix(attr)) {
+		if (inat_is_evex_prefix(attr)) {
+			b2 = peek_nbyte_next(insn_byte_t, insn, 2);
+			insn->vex_prefix.bytes[2] = b2;
+			b2 = peek_nbyte_next(insn_byte_t, insn, 3);
+			insn->vex_prefix.bytes[3] = b2;
+			insn->vex_prefix.nbytes = 4;
+			insn->next_byte += 4;
+			if (insn->x86_64 && X86_VEX_W(b2))
+				/* VEX.W overrides opnd_size */
+				insn->opnd_bytes = 8;
+		} else if (inat_is_vex3_prefix(attr)) {
 			b2 = peek_nbyte_next(insn_byte_t, insn, 2);
 			insn->vex_prefix.bytes[2] = b2;
 			insn->vex_prefix.nbytes = 3;
@@ -221,7 +231,9 @@ void insn_get_opcode(struct insn *insn)
 		m = insn_vex_m_bits(insn);
 		p = insn_vex_p_bits(insn);
 		insn->attr = inat_get_avx_attribute(op, m, p);
-		if (!inat_accept_vex(insn->attr) && !inat_is_group(insn->attr))
+		if ((inat_must_evex(insn->attr) && !insn_is_evex(insn)) ||
+		    (!inat_accept_vex(insn->attr) &&
+		     !inat_is_group(insn->attr)))
 			insn->attr = 0;	/* This instruction is bad */
 		goto end;	/* VEX has only 1 byte for opcode */
 	}
--- zfcpdump-kernel-4.4.orig/tools/perf/util/intel-pt-decoder/insn.h
+++ zfcpdump-kernel-4.4/tools/perf/util/intel-pt-decoder/insn.h
@@ -91,6 +91,7 @@ struct insn {
 #define X86_VEX_B(vex)	((vex) & 0x20)	/* VEX3 Byte1 */
 #define X86_VEX_L(vex)	((vex) & 0x04)	/* VEX3 Byte2, VEX2 Byte1 */
 /* VEX bit fields */
+#define X86_EVEX_M(vex)	((vex) & 0x03)		/* EVEX Byte1 */
 #define X86_VEX3_M(vex)	((vex) & 0x1f)		/* VEX3 Byte1 */
 #define X86_VEX2_M	1			/* VEX2.M always 1 */
 #define X86_VEX_V(vex)	(((vex) & 0x78) >> 3)	/* VEX3 Byte2, VEX2 Byte1 */
@@ -133,6 +134,13 @@ static inline int insn_is_avx(struct ins
 	return (insn->vex_prefix.value != 0);
 }
 
+static inline int insn_is_evex(struct insn *insn)
+{
+	if (!insn->prefixes.got)
+		insn_get_prefixes(insn);
+	return (insn->vex_prefix.nbytes == 4);
+}
+
 /* Ensure this instruction is decoded completely */
 static inline int insn_complete(struct insn *insn)
 {
@@ -144,8 +152,10 @@ static inline insn_byte_t insn_vex_m_bit
 {
 	if (insn->vex_prefix.nbytes == 2)	/* 2 bytes VEX */
 		return X86_VEX2_M;
-	else
+	else if (insn->vex_prefix.nbytes == 3)	/* 3 bytes VEX */
 		return X86_VEX3_M(insn->vex_prefix.bytes[1]);
+	else					/* EVEX */
+		return X86_EVEX_M(insn->vex_prefix.bytes[1]);
 }
 
 static inline insn_byte_t insn_vex_p_bits(struct insn *insn)
--- zfcpdump-kernel-4.4.orig/tools/perf/util/intel-pt-decoder/x86-opcode-map.txt
+++ zfcpdump-kernel-4.4/tools/perf/util/intel-pt-decoder/x86-opcode-map.txt
@@ -13,12 +13,17 @@
 # opcode: escape # escaped-name
 # EndTable
 #
+# mnemonics that begin with lowercase 'v' accept a VEX or EVEX prefix
+# mnemonics that begin with lowercase 'k' accept a VEX prefix
+#
 #<group maps>
 # GrpTable: GrpXXX
 # reg:  mnemonic [operand1[,operand2...]] [(extra1)[,(extra2)...] [| 2nd-mnemonic ...]
 # EndTable
 #
 # AVX Superscripts
+#  (ev): this opcode requires EVEX prefix.
+#  (evo): this opcode is changed by EVEX prefix (EVEX opcode)
 #  (v): this opcode requires VEX prefix.
 #  (v1): this opcode only supports 128bit VEX.
 #
@@ -137,7 +142,7 @@ AVXcode:
 # 0x60 - 0x6f
 60: PUSHA/PUSHAD (i64)
 61: POPA/POPAD (i64)
-62: BOUND Gv,Ma (i64)
+62: BOUND Gv,Ma (i64) | EVEX (Prefix)
 63: ARPL Ew,Gw (i64) | MOVSXD Gv,Ev (o64)
 64: SEG=FS (Prefix)
 65: SEG=GS (Prefix)
@@ -399,17 +404,17 @@ AVXcode: 1
 3f:
 # 0x0f 0x40-0x4f
 40: CMOVO Gv,Ev
-41: CMOVNO Gv,Ev
-42: CMOVB/C/NAE Gv,Ev
+41: CMOVNO Gv,Ev | kandw/q Vk,Hk,Uk | kandb/d Vk,Hk,Uk (66)
+42: CMOVB/C/NAE Gv,Ev | kandnw/q Vk,Hk,Uk | kandnb/d Vk,Hk,Uk (66)
 43: CMOVAE/NB/NC Gv,Ev
-44: CMOVE/Z Gv,Ev
-45: CMOVNE/NZ Gv,Ev
-46: CMOVBE/NA Gv,Ev
-47: CMOVA/NBE Gv,Ev
+44: CMOVE/Z Gv,Ev | knotw/q Vk,Uk | knotb/d Vk,Uk (66)
+45: CMOVNE/NZ Gv,Ev | korw/q Vk,Hk,Uk | korb/d Vk,Hk,Uk (66)
+46: CMOVBE/NA Gv,Ev | kxnorw/q Vk,Hk,Uk | kxnorb/d Vk,Hk,Uk (66)
+47: CMOVA/NBE Gv,Ev | kxorw/q Vk,Hk,Uk | kxorb/d Vk,Hk,Uk (66)
 48: CMOVS Gv,Ev
 49: CMOVNS Gv,Ev
-4a: CMOVP/PE Gv,Ev
-4b: CMOVNP/PO Gv,Ev
+4a: CMOVP/PE Gv,Ev | kaddw/q Vk,Hk,Uk | kaddb/d Vk,Hk,Uk (66)
+4b: CMOVNP/PO Gv,Ev | kunpckbw Vk,Hk,Uk (66) | kunpckwd/dq Vk,Hk,Uk
 4c: CMOVL/NGE Gv,Ev
 4d: CMOVNL/GE Gv,Ev
 4e: CMOVLE/NG Gv,Ev
@@ -426,7 +431,7 @@ AVXcode: 1
 58: vaddps Vps,Hps,Wps | vaddpd Vpd,Hpd,Wpd (66) | vaddss Vss,Hss,Wss (F3),(v1) | vaddsd Vsd,Hsd,Wsd (F2),(v1)
 59: vmulps Vps,Hps,Wps | vmulpd Vpd,Hpd,Wpd (66) | vmulss Vss,Hss,Wss (F3),(v1) | vmulsd Vsd,Hsd,Wsd (F2),(v1)
 5a: vcvtps2pd Vpd,Wps | vcvtpd2ps Vps,Wpd (66) | vcvtss2sd Vsd,Hx,Wss (F3),(v1) | vcvtsd2ss Vss,Hx,Wsd (F2),(v1)
-5b: vcvtdq2ps Vps,Wdq | vcvtps2dq Vdq,Wps (66) | vcvttps2dq Vdq,Wps (F3)
+5b: vcvtdq2ps Vps,Wdq | vcvtqq2ps Vps,Wqq (evo) | vcvtps2dq Vdq,Wps (66) | vcvttps2dq Vdq,Wps (F3)
 5c: vsubps Vps,Hps,Wps | vsubpd Vpd,Hpd,Wpd (66) | vsubss Vss,Hss,Wss (F3),(v1) | vsubsd Vsd,Hsd,Wsd (F2),(v1)
 5d: vminps Vps,Hps,Wps | vminpd Vpd,Hpd,Wpd (66) | vminss Vss,Hss,Wss (F3),(v1) | vminsd Vsd,Hsd,Wsd (F2),(v1)
 5e: vdivps Vps,Hps,Wps | vdivpd Vpd,Hpd,Wpd (66) | vdivss Vss,Hss,Wss (F3),(v1) | vdivsd Vsd,Hsd,Wsd (F2),(v1)
@@ -447,7 +452,7 @@ AVXcode: 1
 6c: vpunpcklqdq Vx,Hx,Wx (66),(v1)
 6d: vpunpckhqdq Vx,Hx,Wx (66),(v1)
 6e: movd/q Pd,Ey | vmovd/q Vy,Ey (66),(v1)
-6f: movq Pq,Qq | vmovdqa Vx,Wx (66) | vmovdqu Vx,Wx (F3)
+6f: movq Pq,Qq | vmovdqa Vx,Wx (66) | vmovdqa32/64 Vx,Wx (66),(evo) | vmovdqu Vx,Wx (F3) | vmovdqu32/64 Vx,Wx (F3),(evo) | vmovdqu8/16 Vx,Wx (F2),(ev)
 # 0x0f 0x70-0x7f
 70: pshufw Pq,Qq,Ib | vpshufd Vx,Wx,Ib (66),(v1) | vpshufhw Vx,Wx,Ib (F3),(v1) | vpshuflw Vx,Wx,Ib (F2),(v1)
 71: Grp12 (1A)
@@ -458,14 +463,14 @@ AVXcode: 1
 76: pcmpeqd Pq,Qq | vpcmpeqd Vx,Hx,Wx (66),(v1)
 # Note: Remove (v), because vzeroall and vzeroupper becomes emms without VEX.
 77: emms | vzeroupper | vzeroall
-78: VMREAD Ey,Gy
-79: VMWRITE Gy,Ey
-7a:
-7b:
+78: VMREAD Ey,Gy | vcvttps2udq/pd2udq Vx,Wpd (evo) | vcvttsd2usi Gv,Wx (F2),(ev) | vcvttss2usi Gv,Wx (F3),(ev) | vcvttps2uqq/pd2uqq Vx,Wx (66),(ev)
+79: VMWRITE Gy,Ey | vcvtps2udq/pd2udq Vx,Wpd (evo) | vcvtsd2usi Gv,Wx (F2),(ev) | vcvtss2usi Gv,Wx (F3),(ev) | vcvtps2uqq/pd2uqq Vx,Wx (66),(ev)
+7a: vcvtudq2pd/uqq2pd Vpd,Wx (F3),(ev) | vcvtudq2ps/uqq2ps Vpd,Wx (F2),(ev) | vcvttps2qq/pd2qq Vx,Wx (66),(ev)
+7b: vcvtusi2sd Vpd,Hpd,Ev (F2),(ev) | vcvtusi2ss Vps,Hps,Ev (F3),(ev) | vcvtps2qq/pd2qq Vx,Wx (66),(ev)
 7c: vhaddpd Vpd,Hpd,Wpd (66) | vhaddps Vps,Hps,Wps (F2)
 7d: vhsubpd Vpd,Hpd,Wpd (66) | vhsubps Vps,Hps,Wps (F2)
 7e: movd/q Ey,Pd | vmovd/q Ey,Vy (66),(v1) | vmovq Vq,Wq (F3),(v1)
-7f: movq Qq,Pq | vmovdqa Wx,Vx (66) | vmovdqu Wx,Vx (F3)
+7f: movq Qq,Pq | vmovdqa Wx,Vx (66) | vmovdqa32/64 Wx,Vx (66),(evo) | vmovdqu Wx,Vx (F3) | vmovdqu32/64 Wx,Vx (F3),(evo) | vmovdqu8/16 Wx,Vx (F2),(ev)
 # 0x0f 0x80-0x8f
 # Note: "forced64" is Intel CPU behavior (see comment about CALL insn).
 80: JO Jz (f64)
@@ -485,16 +490,16 @@ AVXcode: 1
 8e: JLE/JNG Jz (f64)
 8f: JNLE/JG Jz (f64)
 # 0x0f 0x90-0x9f
-90: SETO Eb
-91: SETNO Eb
-92: SETB/C/NAE Eb
-93: SETAE/NB/NC Eb
+90: SETO Eb | kmovw/q Vk,Wk | kmovb/d Vk,Wk (66)
+91: SETNO Eb | kmovw/q Mv,Vk | kmovb/d Mv,Vk (66)
+92: SETB/C/NAE Eb | kmovw Vk,Rv | kmovb Vk,Rv (66) | kmovq/d Vk,Rv (F2)
+93: SETAE/NB/NC Eb | kmovw Gv,Uk | kmovb Gv,Uk (66) | kmovq/d Gv,Uk (F2)
 94: SETE/Z Eb
 95: SETNE/NZ Eb
 96: SETBE/NA Eb
 97: SETA/NBE Eb
-98: SETS Eb
-99: SETNS Eb
+98: SETS Eb | kortestw/q Vk,Uk | kortestb/d Vk,Uk (66)
+99: SETNS Eb | ktestw/q Vk,Uk | ktestb/d Vk,Uk (66)
 9a: SETP/PE Eb
 9b: SETNP/PO Eb
 9c: SETL/NGE Eb
@@ -564,11 +569,11 @@ d7: pmovmskb Gd,Nq | vpmovmskb Gd,Ux (66
 d8: psubusb Pq,Qq | vpsubusb Vx,Hx,Wx (66),(v1)
 d9: psubusw Pq,Qq | vpsubusw Vx,Hx,Wx (66),(v1)
 da: pminub Pq,Qq | vpminub Vx,Hx,Wx (66),(v1)
-db: pand Pq,Qq | vpand Vx,Hx,Wx (66),(v1)
+db: pand Pq,Qq | vpand Vx,Hx,Wx (66),(v1) | vpandd/q Vx,Hx,Wx (66),(evo)
 dc: paddusb Pq,Qq | vpaddusb Vx,Hx,Wx (66),(v1)
 dd: paddusw Pq,Qq | vpaddusw Vx,Hx,Wx (66),(v1)
 de: pmaxub Pq,Qq | vpmaxub Vx,Hx,Wx (66),(v1)
-df: pandn Pq,Qq | vpandn Vx,Hx,Wx (66),(v1)
+df: pandn Pq,Qq | vpandn Vx,Hx,Wx (66),(v1) | vpandnd/q Vx,Hx,Wx (66),(evo)
 # 0x0f 0xe0-0xef
 e0: pavgb Pq,Qq | vpavgb Vx,Hx,Wx (66),(v1)
 e1: psraw Pq,Qq | vpsraw Vx,Hx,Wx (66),(v1)
@@ -576,16 +581,16 @@ e2: psrad Pq,Qq | vpsrad Vx,Hx,Wx (66),(
 e3: pavgw Pq,Qq | vpavgw Vx,Hx,Wx (66),(v1)
 e4: pmulhuw Pq,Qq | vpmulhuw Vx,Hx,Wx (66),(v1)
 e5: pmulhw Pq,Qq | vpmulhw Vx,Hx,Wx (66),(v1)
-e6: vcvttpd2dq Vx,Wpd (66) | vcvtdq2pd Vx,Wdq (F3) | vcvtpd2dq Vx,Wpd (F2)
+e6: vcvttpd2dq Vx,Wpd (66) | vcvtdq2pd Vx,Wdq (F3) | vcvtdq2pd/qq2pd Vx,Wdq (F3),(evo) | vcvtpd2dq Vx,Wpd (F2)
 e7: movntq Mq,Pq | vmovntdq Mx,Vx (66)
 e8: psubsb Pq,Qq | vpsubsb Vx,Hx,Wx (66),(v1)
 e9: psubsw Pq,Qq | vpsubsw Vx,Hx,Wx (66),(v1)
 ea: pminsw Pq,Qq | vpminsw Vx,Hx,Wx (66),(v1)
-eb: por Pq,Qq | vpor Vx,Hx,Wx (66),(v1)
+eb: por Pq,Qq | vpor Vx,Hx,Wx (66),(v1) | vpord/q Vx,Hx,Wx (66),(evo)
 ec: paddsb Pq,Qq | vpaddsb Vx,Hx,Wx (66),(v1)
 ed: paddsw Pq,Qq | vpaddsw Vx,Hx,Wx (66),(v1)
 ee: pmaxsw Pq,Qq | vpmaxsw Vx,Hx,Wx (66),(v1)
-ef: pxor Pq,Qq | vpxor Vx,Hx,Wx (66),(v1)
+ef: pxor Pq,Qq | vpxor Vx,Hx,Wx (66),(v1) | vpxord/q Vx,Hx,Wx (66),(evo)
 # 0x0f 0xf0-0xff
 f0: vlddqu Vx,Mx (F2)
 f1: psllw Pq,Qq | vpsllw Vx,Hx,Wx (66),(v1)
@@ -626,81 +631,105 @@ AVXcode: 2
 0e: vtestps Vx,Wx (66),(v)
 0f: vtestpd Vx,Wx (66),(v)
 # 0x0f 0x38 0x10-0x1f
-10: pblendvb Vdq,Wdq (66)
-11:
-12:
-13: vcvtph2ps Vx,Wx,Ib (66),(v)
-14: blendvps Vdq,Wdq (66)
-15: blendvpd Vdq,Wdq (66)
-16: vpermps Vqq,Hqq,Wqq (66),(v)
+10: pblendvb Vdq,Wdq (66) | vpsrlvw Vx,Hx,Wx (66),(evo) | vpmovuswb Wx,Vx (F3),(ev)
+11: vpmovusdb Wx,Vd (F3),(ev) | vpsravw Vx,Hx,Wx (66),(ev)
+12: vpmovusqb Wx,Vq (F3),(ev) | vpsllvw Vx,Hx,Wx (66),(ev)
+13: vcvtph2ps Vx,Wx (66),(v) | vpmovusdw Wx,Vd (F3),(ev)
+14: blendvps Vdq,Wdq (66) | vpmovusqw Wx,Vq (F3),(ev) | vprorvd/q Vx,Hx,Wx (66),(evo)
+15: blendvpd Vdq,Wdq (66) | vpmovusqd Wx,Vq (F3),(ev) | vprolvd/q Vx,Hx,Wx (66),(evo)
+16: vpermps Vqq,Hqq,Wqq (66),(v) | vpermps/d Vqq,Hqq,Wqq (66),(evo)
 17: vptest Vx,Wx (66)
 18: vbroadcastss Vx,Wd (66),(v)
-19: vbroadcastsd Vqq,Wq (66),(v)
-1a: vbroadcastf128 Vqq,Mdq (66),(v)
-1b:
+19: vbroadcastsd Vqq,Wq (66),(v) | vbroadcastf32x2 Vqq,Wq (66),(evo)
+1a: vbroadcastf128 Vqq,Mdq (66),(v) | vbroadcastf32x4/64x2 Vqq,Wq (66),(evo)
+1b: vbroadcastf32x8/64x4 Vqq,Mdq (66),(ev)
 1c: pabsb Pq,Qq | vpabsb Vx,Wx (66),(v1)
 1d: pabsw Pq,Qq | vpabsw Vx,Wx (66),(v1)
 1e: pabsd Pq,Qq | vpabsd Vx,Wx (66),(v1)
-1f:
+1f: vpabsq Vx,Wx (66),(ev)
 # 0x0f 0x38 0x20-0x2f
-20: vpmovsxbw Vx,Ux/Mq (66),(v1)
-21: vpmovsxbd Vx,Ux/Md (66),(v1)
-22: vpmovsxbq Vx,Ux/Mw (66),(v1)
-23: vpmovsxwd Vx,Ux/Mq (66),(v1)
-24: vpmovsxwq Vx,Ux/Md (66),(v1)
-25: vpmovsxdq Vx,Ux/Mq (66),(v1)
-26:
-27:
-28: vpmuldq Vx,Hx,Wx (66),(v1)
-29: vpcmpeqq Vx,Hx,Wx (66),(v1)
-2a: vmovntdqa Vx,Mx (66),(v1)
+20: vpmovsxbw Vx,Ux/Mq (66),(v1) | vpmovswb Wx,Vx (F3),(ev)
+21: vpmovsxbd Vx,Ux/Md (66),(v1) | vpmovsdb Wx,Vd (F3),(ev)
+22: vpmovsxbq Vx,Ux/Mw (66),(v1) | vpmovsqb Wx,Vq (F3),(ev)
+23: vpmovsxwd Vx,Ux/Mq (66),(v1) | vpmovsdw Wx,Vd (F3),(ev)
+24: vpmovsxwq Vx,Ux/Md (66),(v1) | vpmovsqw Wx,Vq (F3),(ev)
+25: vpmovsxdq Vx,Ux/Mq (66),(v1) | vpmovsqd Wx,Vq (F3),(ev)
+26: vptestmb/w Vk,Hx,Wx (66),(ev) | vptestnmb/w Vk,Hx,Wx (F3),(ev)
+27: vptestmd/q Vk,Hx,Wx (66),(ev) | vptestnmd/q Vk,Hx,Wx (F3),(ev)
+28: vpmuldq Vx,Hx,Wx (66),(v1) | vpmovm2b/w Vx,Uk (F3),(ev)
+29: vpcmpeqq Vx,Hx,Wx (66),(v1) | vpmovb2m/w2m Vk,Ux (F3),(ev)
+2a: vmovntdqa Vx,Mx (66),(v1) | vpbroadcastmb2q Vx,Uk (F3),(ev)
 2b: vpackusdw Vx,Hx,Wx (66),(v1)
-2c: vmaskmovps Vx,Hx,Mx (66),(v)
-2d: vmaskmovpd Vx,Hx,Mx (66),(v)
+2c: vmaskmovps Vx,Hx,Mx (66),(v) | vscalefps/d Vx,Hx,Wx (66),(evo)
+2d: vmaskmovpd Vx,Hx,Mx (66),(v) | vscalefss/d Vx,Hx,Wx (66),(evo)
 2e: vmaskmovps Mx,Hx,Vx (66),(v)
 2f: vmaskmovpd Mx,Hx,Vx (66),(v)
 # 0x0f 0x38 0x30-0x3f
-30: vpmovzxbw Vx,Ux/Mq (66),(v1)
-31: vpmovzxbd Vx,Ux/Md (66),(v1)
-32: vpmovzxbq Vx,Ux/Mw (66),(v1)
-33: vpmovzxwd Vx,Ux/Mq (66),(v1)
-34: vpmovzxwq Vx,Ux/Md (66),(v1)
-35: vpmovzxdq Vx,Ux/Mq (66),(v1)
-36: vpermd Vqq,Hqq,Wqq (66),(v)
+30: vpmovzxbw Vx,Ux/Mq (66),(v1) | vpmovwb Wx,Vx (F3),(ev)
+31: vpmovzxbd Vx,Ux/Md (66),(v1) | vpmovdb Wx,Vd (F3),(ev)
+32: vpmovzxbq Vx,Ux/Mw (66),(v1) | vpmovqb Wx,Vq (F3),(ev)
+33: vpmovzxwd Vx,Ux/Mq (66),(v1) | vpmovdw Wx,Vd (F3),(ev)
+34: vpmovzxwq Vx,Ux/Md (66),(v1) | vpmovqw Wx,Vq (F3),(ev)
+35: vpmovzxdq Vx,Ux/Mq (66),(v1) | vpmovqd Wx,Vq (F3),(ev)
+36: vpermd Vqq,Hqq,Wqq (66),(v) | vpermd/q Vqq,Hqq,Wqq (66),(evo)
 37: vpcmpgtq Vx,Hx,Wx (66),(v1)
-38: vpminsb Vx,Hx,Wx (66),(v1)
-39: vpminsd Vx,Hx,Wx (66),(v1)
-3a: vpminuw Vx,Hx,Wx (66),(v1)
-3b: vpminud Vx,Hx,Wx (66),(v1)
+38: vpminsb Vx,Hx,Wx (66),(v1) | vpmovm2d/q Vx,Uk (F3),(ev)
+39: vpminsd Vx,Hx,Wx (66),(v1) | vpminsd/q Vx,Hx,Wx (66),(evo) | vpmovd2m/q2m Vk,Ux (F3),(ev)
+3a: vpminuw Vx,Hx,Wx (66),(v1) | vpbroadcastmw2d Vx,Uk (F3),(ev)
+3b: vpminud Vx,Hx,Wx (66),(v1) | vpminud/q Vx,Hx,Wx (66),(evo)
 3c: vpmaxsb Vx,Hx,Wx (66),(v1)
-3d: vpmaxsd Vx,Hx,Wx (66),(v1)
+3d: vpmaxsd Vx,Hx,Wx (66),(v1) | vpmaxsd/q Vx,Hx,Wx (66),(evo)
 3e: vpmaxuw Vx,Hx,Wx (66),(v1)
-3f: vpmaxud Vx,Hx,Wx (66),(v1)
+3f: vpmaxud Vx,Hx,Wx (66),(v1) | vpmaxud/q Vx,Hx,Wx (66),(evo)
 # 0x0f 0x38 0x40-0x8f
-40: vpmulld Vx,Hx,Wx (66),(v1)
+40: vpmulld Vx,Hx,Wx (66),(v1) | vpmulld/q Vx,Hx,Wx (66),(evo)
 41: vphminposuw Vdq,Wdq (66),(v1)
-42:
-43:
-44:
+42: vgetexpps/d Vx,Wx (66),(ev)
+43: vgetexpss/d Vx,Hx,Wx (66),(ev)
+44: vplzcntd/q Vx,Wx (66),(ev)
 45: vpsrlvd/q Vx,Hx,Wx (66),(v)
-46: vpsravd Vx,Hx,Wx (66),(v)
+46: vpsravd Vx,Hx,Wx (66),(v) | vpsravd/q Vx,Hx,Wx (66),(evo)
 47: vpsllvd/q Vx,Hx,Wx (66),(v)
-# Skip 0x48-0x57
+# Skip 0x48-0x4b
+4c: vrcp14ps/d Vpd,Wpd (66),(ev)
+4d: vrcp14ss/d Vsd,Hpd,Wsd (66),(ev)
+4e: vrsqrt14ps/d Vpd,Wpd (66),(ev)
+4f: vrsqrt14ss/d Vsd,Hsd,Wsd (66),(ev)
+# Skip 0x50-0x57
 58: vpbroadcastd Vx,Wx (66),(v)
-59: vpbroadcastq Vx,Wx (66),(v)
-5a: vbroadcasti128 Vqq,Mdq (66),(v)
-# Skip 0x5b-0x77
+59: vpbroadcastq Vx,Wx (66),(v) | vbroadcasti32x2 Vx,Wx (66),(evo)
+5a: vbroadcasti128 Vqq,Mdq (66),(v) | vbroadcasti32x4/64x2 Vx,Wx (66),(evo)
+5b: vbroadcasti32x8/64x4 Vqq,Mdq (66),(ev)
+# Skip 0x5c-0x63
+64: vpblendmd/q Vx,Hx,Wx (66),(ev)
+65: vblendmps/d Vx,Hx,Wx (66),(ev)
+66: vpblendmb/w Vx,Hx,Wx (66),(ev)
+# Skip 0x67-0x74
+75: vpermi2b/w Vx,Hx,Wx (66),(ev)
+76: vpermi2d/q Vx,Hx,Wx (66),(ev)
+77: vpermi2ps/d Vx,Hx,Wx (66),(ev)
 78: vpbroadcastb Vx,Wx (66),(v)
 79: vpbroadcastw Vx,Wx (66),(v)
-# Skip 0x7a-0x7f
+7a: vpbroadcastb Vx,Rv (66),(ev)
+7b: vpbroadcastw Vx,Rv (66),(ev)
+7c: vpbroadcastd/q Vx,Rv (66),(ev)
+7d: vpermt2b/w Vx,Hx,Wx (66),(ev)
+7e: vpermt2d/q Vx,Hx,Wx (66),(ev)
+7f: vpermt2ps/d Vx,Hx,Wx (66),(ev)
 80: INVEPT Gy,Mdq (66)
 81: INVPID Gy,Mdq (66)
 82: INVPCID Gy,Mdq (66)
+83: vpmultishiftqb Vx,Hx,Wx (66),(ev)
+88: vexpandps/d Vpd,Wpd (66),(ev)
+89: vpexpandd/q Vx,Wx (66),(ev)
+8a: vcompressps/d Wx,Vx (66),(ev)
+8b: vpcompressd/q Wx,Vx (66),(ev)
 8c: vpmaskmovd/q Vx,Hx,Mx (66),(v)
+8d: vpermb/w Vx,Hx,Wx (66),(ev)
 8e: vpmaskmovd/q Mx,Vx,Hx (66),(v)
 # 0x0f 0x38 0x90-0xbf (FMA)
-90: vgatherdd/q Vx,Hx,Wx (66),(v)
-91: vgatherqd/q Vx,Hx,Wx (66),(v)
+90: vgatherdd/q Vx,Hx,Wx (66),(v) | vpgatherdd/q Vx,Wx (66),(evo)
+91: vgatherqd/q Vx,Hx,Wx (66),(v) | vpgatherqd/q Vx,Wx (66),(evo)
 92: vgatherdps/d Vx,Hx,Wx (66),(v)
 93: vgatherqps/d Vx,Hx,Wx (66),(v)
 94:
@@ -715,6 +744,10 @@ AVXcode: 2
 9d: vfnmadd132ss/d Vx,Hx,Wx (66),(v),(v1)
 9e: vfnmsub132ps/d Vx,Hx,Wx (66),(v)
 9f: vfnmsub132ss/d Vx,Hx,Wx (66),(v),(v1)
+a0: vpscatterdd/q Wx,Vx (66),(ev)
+a1: vpscatterqd/q Wx,Vx (66),(ev)
+a2: vscatterdps/d Wx,Vx (66),(ev)
+a3: vscatterqps/d Wx,Vx (66),(ev)
 a6: vfmaddsub213ps/d Vx,Hx,Wx (66),(v)
 a7: vfmsubadd213ps/d Vx,Hx,Wx (66),(v)
 a8: vfmadd213ps/d Vx,Hx,Wx (66),(v)
@@ -725,6 +758,8 @@ ac: vfnmadd213ps/d Vx,Hx,Wx (66),(v)
 ad: vfnmadd213ss/d Vx,Hx,Wx (66),(v),(v1)
 ae: vfnmsub213ps/d Vx,Hx,Wx (66),(v)
 af: vfnmsub213ss/d Vx,Hx,Wx (66),(v),(v1)
+b4: vpmadd52luq Vx,Hx,Wx (66),(ev)
+b5: vpmadd52huq Vx,Hx,Wx (66),(ev)
 b6: vfmaddsub231ps/d Vx,Hx,Wx (66),(v)
 b7: vfmsubadd231ps/d Vx,Hx,Wx (66),(v)
 b8: vfmadd231ps/d Vx,Hx,Wx (66),(v)
@@ -736,12 +771,15 @@ bd: vfnmadd231ss/d Vx,Hx,Wx (66),(v),(v1
 be: vfnmsub231ps/d Vx,Hx,Wx (66),(v)
 bf: vfnmsub231ss/d Vx,Hx,Wx (66),(v),(v1)
 # 0x0f 0x38 0xc0-0xff
-c8: sha1nexte Vdq,Wdq
+c4: vpconflictd/q Vx,Wx (66),(ev)
+c6: Grp18 (1A)
+c7: Grp19 (1A)
+c8: sha1nexte Vdq,Wdq | vexp2ps/d Vx,Wx (66),(ev)
 c9: sha1msg1 Vdq,Wdq
-ca: sha1msg2 Vdq,Wdq
-cb: sha256rnds2 Vdq,Wdq
-cc: sha256msg1 Vdq,Wdq
-cd: sha256msg2 Vdq,Wdq
+ca: sha1msg2 Vdq,Wdq | vrcp28ps/d Vx,Wx (66),(ev)
+cb: sha256rnds2 Vdq,Wdq | vrcp28ss/d Vx,Hx,Wx (66),(ev)
+cc: sha256msg1 Vdq,Wdq | vrsqrt28ps/d Vx,Wx (66),(ev)
+cd: sha256msg2 Vdq,Wdq | vrsqrt28ss/d Vx,Hx,Wx (66),(ev)
 db: VAESIMC Vdq,Wdq (66),(v1)
 dc: VAESENC Vdq,Hdq,Wdq (66),(v1)
 dd: VAESENCLAST Vdq,Hdq,Wdq (66),(v1)
@@ -763,15 +801,15 @@ AVXcode: 3
 00: vpermq Vqq,Wqq,Ib (66),(v)
 01: vpermpd Vqq,Wqq,Ib (66),(v)
 02: vpblendd Vx,Hx,Wx,Ib (66),(v)
-03:
+03: valignd/q Vx,Hx,Wx,Ib (66),(ev)
 04: vpermilps Vx,Wx,Ib (66),(v)
 05: vpermilpd Vx,Wx,Ib (66),(v)
 06: vperm2f128 Vqq,Hqq,Wqq,Ib (66),(v)
 07:
-08: vroundps Vx,Wx,Ib (66)
-09: vroundpd Vx,Wx,Ib (66)
-0a: vroundss Vss,Wss,Ib (66),(v1)
-0b: vroundsd Vsd,Wsd,Ib (66),(v1)
+08: vroundps Vx,Wx,Ib (66) | vrndscaleps Vx,Wx,Ib (66),(evo)
+09: vroundpd Vx,Wx,Ib (66) | vrndscalepd Vx,Wx,Ib (66),(evo)
+0a: vroundss Vss,Wss,Ib (66),(v1) | vrndscaless Vx,Hx,Wx,Ib (66),(evo)
+0b: vroundsd Vsd,Wsd,Ib (66),(v1) | vrndscalesd Vx,Hx,Wx,Ib (66),(evo)
 0c: vblendps Vx,Hx,Wx,Ib (66)
 0d: vblendpd Vx,Hx,Wx,Ib (66)
 0e: vpblendw Vx,Hx,Wx,Ib (66),(v1)
@@ -780,26 +818,51 @@ AVXcode: 3
 15: vpextrw Rd/Mw,Vdq,Ib (66),(v1)
 16: vpextrd/q Ey,Vdq,Ib (66),(v1)
 17: vextractps Ed,Vdq,Ib (66),(v1)
-18: vinsertf128 Vqq,Hqq,Wqq,Ib (66),(v)
-19: vextractf128 Wdq,Vqq,Ib (66),(v)
+18: vinsertf128 Vqq,Hqq,Wqq,Ib (66),(v) | vinsertf32x4/64x2 Vqq,Hqq,Wqq,Ib (66),(evo)
+19: vextractf128 Wdq,Vqq,Ib (66),(v) | vextractf32x4/64x2 Wdq,Vqq,Ib (66),(evo)
+1a: vinsertf32x8/64x4 Vqq,Hqq,Wqq,Ib (66),(ev)
+1b: vextractf32x8/64x4 Wdq,Vqq,Ib (66),(ev)
 1d: vcvtps2ph Wx,Vx,Ib (66),(v)
+1e: vpcmpud/q Vk,Hd,Wd,Ib (66),(ev)
+1f: vpcmpd/q Vk,Hd,Wd,Ib (66),(ev)
 20: vpinsrb Vdq,Hdq,Ry/Mb,Ib (66),(v1)
 21: vinsertps Vdq,Hdq,Udq/Md,Ib (66),(v1)
 22: vpinsrd/q Vdq,Hdq,Ey,Ib (66),(v1)
-38: vinserti128 Vqq,Hqq,Wqq,Ib (66),(v)
-39: vextracti128 Wdq,Vqq,Ib (66),(v)
+23: vshuff32x4/64x2 Vx,Hx,Wx,Ib (66),(ev)
+25: vpternlogd/q Vx,Hx,Wx,Ib (66),(ev)
+26: vgetmantps/d Vx,Wx,Ib (66),(ev)
+27: vgetmantss/d Vx,Hx,Wx,Ib (66),(ev)
+30: kshiftrb/w Vk,Uk,Ib (66),(v)
+31: kshiftrd/q Vk,Uk,Ib (66),(v)
+32: kshiftlb/w Vk,Uk,Ib (66),(v)
+33: kshiftld/q Vk,Uk,Ib (66),(v)
+38: vinserti128 Vqq,Hqq,Wqq,Ib (66),(v) | vinserti32x4/64x2 Vqq,Hqq,Wqq,Ib (66),(evo)
+39: vextracti128 Wdq,Vqq,Ib (66),(v) | vextracti32x4/64x2 Wdq,Vqq,Ib (66),(evo)
+3a: vinserti32x8/64x4 Vqq,Hqq,Wqq,Ib (66),(ev)
+3b: vextracti32x8/64x4 Wdq,Vqq,Ib (66),(ev)
+3e: vpcmpub/w Vk,Hk,Wx,Ib (66),(ev)
+3f: vpcmpb/w Vk,Hk,Wx,Ib (66),(ev)
 40: vdpps Vx,Hx,Wx,Ib (66)
 41: vdppd Vdq,Hdq,Wdq,Ib (66),(v1)
-42: vmpsadbw Vx,Hx,Wx,Ib (66),(v1)
+42: vmpsadbw Vx,Hx,Wx,Ib (66),(v1) | vdbpsadbw Vx,Hx,Wx,Ib (66),(evo)
+43: vshufi32x4/64x2 Vx,Hx,Wx,Ib (66),(ev)
 44: vpclmulqdq Vdq,Hdq,Wdq,Ib (66),(v1)
 46: vperm2i128 Vqq,Hqq,Wqq,Ib (66),(v)
 4a: vblendvps Vx,Hx,Wx,Lx (66),(v)
 4b: vblendvpd Vx,Hx,Wx,Lx (66),(v)
 4c: vpblendvb Vx,Hx,Wx,Lx (66),(v1)
+50: vrangeps/d Vx,Hx,Wx,Ib (66),(ev)
+51: vrangess/d Vx,Hx,Wx,Ib (66),(ev)
+54: vfixupimmps/d Vx,Hx,Wx,Ib (66),(ev)
+55: vfixupimmss/d Vx,Hx,Wx,Ib (66),(ev)
+56: vreduceps/d Vx,Wx,Ib (66),(ev)
+57: vreducess/d Vx,Hx,Wx,Ib (66),(ev)
 60: vpcmpestrm Vdq,Wdq,Ib (66),(v1)
 61: vpcmpestri Vdq,Wdq,Ib (66),(v1)
 62: vpcmpistrm Vdq,Wdq,Ib (66),(v1)
 63: vpcmpistri Vdq,Wdq,Ib (66),(v1)
+66: vfpclassps/d Vk,Wx,Ib (66),(ev)
+67: vfpclassss/d Vk,Wx,Ib (66),(ev)
 cc: sha1rnds4 Vdq,Wdq,Ib
 df: VAESKEYGEN Vdq,Wdq,Ib (66),(v1)
 f0: RORX Gy,Ey,Ib (F2),(v)
@@ -927,8 +990,10 @@ GrpTable: Grp12
 EndTable
 
 GrpTable: Grp13
+0: vprord/q Hx,Wx,Ib (66),(ev)
+1: vprold/q Hx,Wx,Ib (66),(ev)
 2: psrld Nq,Ib (11B) | vpsrld Hx,Ux,Ib (66),(11B),(v1)
-4: psrad Nq,Ib (11B) | vpsrad Hx,Ux,Ib (66),(11B),(v1)
+4: psrad Nq,Ib (11B) | vpsrad Hx,Ux,Ib (66),(11B),(v1) | vpsrad/q Hx,Ux,Ib (66),(evo)
 6: pslld Nq,Ib (11B) | vpslld Hx,Ux,Ib (66),(11B),(v1)
 EndTable
 
@@ -963,6 +1028,20 @@ GrpTable: Grp17
 3: BLSI By,Ey (v)
 EndTable
 
+GrpTable: Grp18
+1: vgatherpf0dps/d Wx (66),(ev)
+2: vgatherpf1dps/d Wx (66),(ev)
+5: vscatterpf0dps/d Wx (66),(ev)
+6: vscatterpf1dps/d Wx (66),(ev)
+EndTable
+
+GrpTable: Grp19
+1: vgatherpf0qps/d Wx (66),(ev)
+2: vgatherpf1qps/d Wx (66),(ev)
+5: vscatterpf0qps/d Wx (66),(ev)
+6: vscatterpf1qps/d Wx (66),(ev)
+EndTable
+
 # AMD's Prefetch Group
 GrpTable: GrpP
 0: PREFETCH
--- zfcpdump-kernel-4.4.orig/tools/perf/util/intel-pt.c
+++ zfcpdump-kernel-4.4/tools/perf/util/intel-pt.c
@@ -1127,7 +1127,7 @@ static int intel_pt_synth_transaction_sa
 		pr_err("Intel Processor Trace: failed to deliver transaction event, error %d\n",
 		       ret);
 
-	if (pt->synth_opts.callchain)
+	if (pt->synth_opts.last_branch)
 		intel_pt_reset_last_branch_rb(ptq);
 
 	return ret;
--- zfcpdump-kernel-4.4.orig/tools/perf/util/kvm-stat.h
+++ zfcpdump-kernel-4.4/tools/perf/util/kvm-stat.h
@@ -122,6 +122,7 @@ void exit_event_decode_key(struct perf_k
 
 bool kvm_exit_event(struct perf_evsel *evsel);
 bool kvm_entry_event(struct perf_evsel *evsel);
+int setup_kvm_events_tp(struct perf_kvm_stat *kvm);
 
 #define define_exit_reasons_table(name, symbols)	\
 	static struct exit_reasons_table name[] = {	\
@@ -133,8 +134,13 @@ bool kvm_entry_event(struct perf_evsel *
  */
 int cpu_isa_init(struct perf_kvm_stat *kvm, const char *cpuid);
 
-extern const char * const kvm_events_tp[];
+extern const char *kvm_events_tp[];
 extern struct kvm_reg_events_ops kvm_reg_events_ops[];
 extern const char * const kvm_skip_events[];
+extern const char *vcpu_id_str;
+extern const int decode_str_len;
+extern const char *kvm_exit_reason;
+extern const char *kvm_entry_trace;
+extern const char *kvm_exit_trace;
 
 #endif /* __PERF_KVM_STAT_H */
--- zfcpdump-kernel-4.4.orig/tools/perf/util/parse-events.c
+++ zfcpdump-kernel-4.4/tools/perf/util/parse-events.c
@@ -399,6 +399,9 @@ static void tracepoint_error(struct pars
 {
 	char help[BUFSIZ];
 
+	if (!e)
+		return;
+
 	/*
 	 * We get error directly from syscall errno ( > 0),
 	 * or from encoded pointer's error ( < 0).
@@ -2098,11 +2101,11 @@ char *parse_events_formats_error_string(
 
 	/* valid terms */
 	if (additional_terms) {
-		if (!asprintf(&str, "valid terms: %s,%s",
-			      additional_terms, static_terms))
+		if (asprintf(&str, "valid terms: %s,%s",
+			     additional_terms, static_terms) < 0)
 			goto fail;
 	} else {
-		if (!asprintf(&str, "valid terms: %s", static_terms))
+		if (asprintf(&str, "valid terms: %s", static_terms) < 0)
 			goto fail;
 	}
 	return str;
--- zfcpdump-kernel-4.4.orig/tools/perf/util/pmu.c
+++ zfcpdump-kernel-4.4/tools/perf/util/pmu.c
@@ -283,13 +283,12 @@ static int pmu_aliases_parse(char *dir,
 {
 	struct dirent *evt_ent;
 	DIR *event_dir;
-	int ret = 0;
 
 	event_dir = opendir(dir);
 	if (!event_dir)
 		return -EINVAL;
 
-	while (!ret && (evt_ent = readdir(event_dir))) {
+	while ((evt_ent = readdir(event_dir))) {
 		char path[PATH_MAX];
 		char *name = evt_ent->d_name;
 		FILE *file;
@@ -305,17 +304,19 @@ static int pmu_aliases_parse(char *dir,
 
 		snprintf(path, PATH_MAX, "%s/%s", dir, name);
 
-		ret = -EINVAL;
 		file = fopen(path, "r");
-		if (!file)
-			break;
+		if (!file) {
+			pr_debug("Cannot open %s\n", path);
+			continue;
+		}
 
-		ret = perf_pmu__new_alias(head, dir, name, file);
+		if (perf_pmu__new_alias(head, dir, name, file) < 0)
+			pr_debug("Cannot set up %s\n", name);
 		fclose(file);
 	}
 
 	closedir(event_dir);
-	return ret;
+	return 0;
 }
 
 /*
--- zfcpdump-kernel-4.4.orig/tools/perf/util/session.c
+++ zfcpdump-kernel-4.4/tools/perf/util/session.c
@@ -972,7 +972,7 @@ static struct machine *machines__find_fo
 
 		machine = machines__find(machines, pid);
 		if (!machine)
-			machine = machines__find(machines, DEFAULT_GUEST_KERNEL_ID);
+			machine = machines__findnew(machines, DEFAULT_GUEST_KERNEL_ID);
 		return machine;
 	}
 
--- zfcpdump-kernel-4.4.orig/tools/perf/util/setup.py
+++ zfcpdump-kernel-4.4/tools/perf/util/setup.py
@@ -22,6 +22,7 @@ cflags = getenv('CFLAGS', '').split()
 # switch off several checks (need to be at the end of cflags list)
 cflags += ['-fno-strict-aliasing', '-Wno-write-strings', '-Wno-unused-parameter' ]
 
+src_perf  = getenv('srctree') + '/tools/perf'
 build_lib = getenv('PYTHON_EXTBUILD_LIB')
 build_tmp = getenv('PYTHON_EXTBUILD_TMP')
 libtraceevent = getenv('LIBTRACEEVENT')
@@ -30,6 +31,9 @@ libapikfs = getenv('LIBAPI')
 ext_sources = [f.strip() for f in file('util/python-ext-sources')
 				if len(f.strip()) > 0 and f[0] != '#']
 
+# use full paths with source files
+ext_sources = map(lambda x: '%s/%s' % (src_perf, x) , ext_sources)
+
 perf = Extension('perf',
 		  sources = ext_sources,
 		  include_dirs = ['util/include'],
--- zfcpdump-kernel-4.4.orig/tools/perf/util/stat.c
+++ zfcpdump-kernel-4.4/tools/perf/util/stat.c
@@ -310,7 +310,6 @@ int perf_stat_process_counter(struct per
 	int i, ret;
 
 	aggr->val = aggr->ena = aggr->run = 0;
-	init_stats(ps->res_stats);
 
 	if (counter->per_pkg)
 		zero_per_pkg(counter);
--- zfcpdump-kernel-4.4.orig/tools/power/x86/turbostat/turbostat.8
+++ zfcpdump-kernel-4.4/tools/power/x86/turbostat/turbostat.8
@@ -34,7 +34,10 @@ name as necessary to disambiguate it fro
 \fB--debug\fP displays additional system configuration information.  Invoking this parameter
 more than once may also enable internal turbostat debug information.
 .PP
-\fB--interval seconds\fP overrides the default 5-second measurement interval.
+\fB--interval seconds\fP overrides the default 5.0 second measurement interval.
+.PP
+\fB--out output_file\fP turbostat output is written to the specified output_file.
+The file is truncated if it already exists, and it is created if it does not exist.
 .PP
 \fB--help\fP displays usage for the most common parameters.
 .PP
@@ -61,7 +64,7 @@ displays the statistics gathered since i
 .nf
 \fBCPU\fP Linux CPU (logical processor) number.  Yes, it is okay that on many systems the CPUs are not listed in numerical order -- for efficiency reasons, turbostat runs in topology order, so HT siblings appear together.
 \fBAVG_MHz\fP number of cycles executed divided by time elapsed.
-\fB%Busy\fP percent of the interval that the CPU retired instructions, aka. % of time in "C0" state.
+\fBBusy%\fP percent of the interval that the CPU retired instructions, aka. % of time in "C0" state.
 \fBBzy_MHz\fP average clock rate while the CPU was busy (in "c0" state).
 \fBTSC_MHz\fP average MHz that the TSC ran during the entire interval.
 .fi
@@ -83,13 +86,14 @@ Note that multiple CPUs per core indicat
 \fBRAM_%\fP percent of the interval that RAPL throttling was active on DRAM.
 .fi
 .PP
-.SH EXAMPLE
+.SH PERIODIC EXAMPLE
 Without any parameters, turbostat displays statistics ever 5 seconds.
-(override interval with "-i sec" option, or specify a command
-for turbostat to fork).
+Periodic output goes to stdout, by default, unless --out is used to specify an output file.
+The 5-second interval can be changed with th "-i sec" option.
+Or a command may be specified as in "FORK EXAMPLE" below.
 .nf
 [root@hsw]# ./turbostat
-     CPU Avg_MHz   %Busy Bzy_MHz TSC_MHz
+     CPU Avg_MHz   Busy% Bzy_MHz TSC_MHz
        -     488   12.51    3898    3498
        0       0    0.01    3885    3498
        4    3897   99.99    3898    3498
@@ -145,7 +149,7 @@ cpu0: MSR_IA32_THERM_STATUS: 0x88340000
 cpu1: MSR_IA32_THERM_STATUS: 0x88440000 (32 C +/- 1)
 cpu2: MSR_IA32_THERM_STATUS: 0x88450000 (31 C +/- 1)
 cpu3: MSR_IA32_THERM_STATUS: 0x88490000 (27 C +/- 1)
-    Core     CPU Avg_MHz   %Busy Bzy_MHz TSC_MHz     SMI  CPU%c1  CPU%c3  CPU%c6  CPU%c7 CoreTmp  PkgTmp PkgWatt CorWatt GFXWatt
+    Core     CPU Avg_MHz   Busy% Bzy_MHz TSC_MHz     SMI  CPU%c1  CPU%c3  CPU%c6  CPU%c7 CoreTmp  PkgTmp PkgWatt CorWatt GFXWatt
        -       -     493   12.64    3898    3498       0   12.64    0.00    0.00   74.72      47      47   21.62   13.74    0.00
        0       0       4    0.11    3894    3498       0   99.89    0.00    0.00    0.00      47      47   21.62   13.74    0.00
        0       4    3897   99.98    3898    3498       0    0.02
@@ -171,14 +175,16 @@ The --debug option adds additional colum
 See the field definitions above.
 .SH FORK EXAMPLE
 If turbostat is invoked with a command, it will fork that command
-and output the statistics gathered when the command exits.
+and output the statistics gathered after the command exits.
+In this case, turbostat output goes to stderr, by default.
+Output can instead be saved to a file using the --out option.
 eg. Here a cycle soaker is run on 1 CPU (see %c0) for a few seconds
 until ^C while the other CPUs are mostly idle:
 
 .nf
 root@hsw: turbostat cat /dev/zero > /dev/null
 ^C
-     CPU Avg_MHz   %Busy Bzy_MHz TSC_MHz
+     CPU Avg_MHz   Busy% Bzy_MHz TSC_MHz
        -     482   12.51    3854    3498
        0       0    0.01    1960    3498
        4       0    0.00    2128    3498
@@ -192,12 +198,12 @@ root@hsw: turbostat cat /dev/zero > /dev
 
 .fi
 Above the cycle soaker drives cpu5 up its 3.9 GHz turbo limit.
-The first row shows the average MHz and %Busy across all the processors in the system.
+The first row shows the average MHz and Busy% across all the processors in the system.
 
 Note that the Avg_MHz column reflects the total number of cycles executed
-divided by the measurement interval.  If the %Busy column is 100%,
+divided by the measurement interval.  If the Busy% column is 100%,
 then the processor was running at that speed the entire interval.
-The Avg_MHz multiplied by the %Busy results in the Bzy_MHz --
+The Avg_MHz multiplied by the Busy% results in the Bzy_MHz --
 which is the average frequency while the processor was executing --
 not including any non-busy idle time.
 
@@ -233,7 +239,7 @@ in the brand string in /proc/cpuinfo.  O
 the TSC stops in idle, TSC_MHz will drop
 below the processor's base frequency.
 
-%Busy = MPERF_delta/TSC_delta
+Busy% = MPERF_delta/TSC_delta
 
 Bzy_MHz = TSC_delta/APERF_delta/MPERF_delta/measurement_interval
 
--- zfcpdump-kernel-4.4.orig/tools/power/x86/turbostat/turbostat.c
+++ zfcpdump-kernel-4.4/tools/power/x86/turbostat/turbostat.c
@@ -38,12 +38,15 @@
 #include <string.h>
 #include <ctype.h>
 #include <sched.h>
+#include <time.h>
 #include <cpuid.h>
 #include <linux/capability.h>
 #include <errno.h>
 
 char *proc_stat = "/proc/stat";
-unsigned int interval_sec = 5;
+FILE *outf;
+int *fd_percpu;
+struct timespec interval_ts = {5, 0};
 unsigned int debug;
 unsigned int rapl_joules;
 unsigned int summary_only;
@@ -63,6 +66,8 @@ unsigned int do_slm_cstates;
 unsigned int use_c1_residency_msr;
 unsigned int has_aperf;
 unsigned int has_epb;
+unsigned int do_irtl_snb;
+unsigned int do_irtl_hsw;
 unsigned int units = 1000000;	/* MHz etc */
 unsigned int genuine_intel;
 unsigned int has_invariant_tsc;
@@ -72,6 +77,7 @@ unsigned int extra_msr_offset64;
 unsigned int extra_delta_offset32;
 unsigned int extra_delta_offset64;
 unsigned int aperf_mperf_multiplier = 1;
+int do_irq = 1;
 int do_smi;
 double bclk;
 double base_hz;
@@ -86,6 +92,10 @@ char *output_buffer, *outp;
 unsigned int do_rapl;
 unsigned int do_dts;
 unsigned int do_ptm;
+unsigned int do_gfx_rc6_ms;
+unsigned long long  gfx_cur_rc6_ms;
+unsigned int do_gfx_mhz;
+unsigned int gfx_cur_mhz;
 unsigned int tcc_activation_temp;
 unsigned int tcc_activation_temp_override;
 double rapl_power_units, rapl_time_units;
@@ -98,6 +108,12 @@ unsigned int crystal_hz;
 unsigned long long tsc_hz;
 int base_cpu;
 double discover_bclk(unsigned int family, unsigned int model);
+unsigned int has_hwp;	/* IA32_PM_ENABLE, IA32_HWP_CAPABILITIES */
+			/* IA32_HWP_REQUEST, IA32_HWP_STATUS */
+unsigned int has_hwp_notify;		/* IA32_HWP_INTERRUPT */
+unsigned int has_hwp_activity_window;	/* IA32_HWP_REQUEST[bits 41:32] */
+unsigned int has_hwp_epp;		/* IA32_HWP_REQUEST[bits 31:24] */
+unsigned int has_hwp_pkg;		/* IA32_HWP_REQUEST_PKG */
 
 #define RAPL_PKG		(1 << 0)
 					/* 0x610 MSR_PKG_POWER_LIMIT */
@@ -145,6 +161,7 @@ struct thread_data {
 	unsigned long long extra_delta64;
 	unsigned long long extra_msr32;
 	unsigned long long extra_delta32;
+	unsigned int irq_count;
 	unsigned int smi_count;
 	unsigned int cpu_id;
 	unsigned int flags;
@@ -172,6 +189,8 @@ struct pkg_data {
 	unsigned long long pkg_any_core_c0;
 	unsigned long long pkg_any_gfxe_c0;
 	unsigned long long pkg_both_core_gfxe_c0;
+	unsigned long long gfx_rc6_ms;
+	unsigned int gfx_mhz;
 	unsigned int package_id;
 	unsigned int energy_pkg;	/* MSR_PKG_ENERGY_STATUS */
 	unsigned int energy_dram;	/* MSR_DRAM_ENERGY_STATUS */
@@ -212,6 +231,9 @@ struct topo_params {
 
 struct timeval tv_even, tv_odd, tv_delta;
 
+int *irq_column_2_cpu;	/* /proc/interrupts column numbers */
+int *irqs_per_cpu;		/* indexed by cpu_num */
+
 void setup_all_buffers(void);
 
 int cpu_is_not_present(int cpu)
@@ -262,23 +284,34 @@ int cpu_migrate(int cpu)
 	else
 		return 0;
 }
-
-int get_msr(int cpu, off_t offset, unsigned long long *msr)
+int get_msr_fd(int cpu)
 {
-	ssize_t retval;
 	char pathname[32];
 	int fd;
 
+	fd = fd_percpu[cpu];
+
+	if (fd)
+		return fd;
+
 	sprintf(pathname, "/dev/cpu/%d/msr", cpu);
 	fd = open(pathname, O_RDONLY);
 	if (fd < 0)
 		err(-1, "%s open failed, try chown or chmod +r /dev/cpu/*/msr, or run as root", pathname);
 
-	retval = pread(fd, msr, sizeof *msr, offset);
-	close(fd);
+	fd_percpu[cpu] = fd;
+
+	return fd;
+}
+
+int get_msr(int cpu, off_t offset, unsigned long long *msr)
+{
+	ssize_t retval;
+
+	retval = pread(get_msr_fd(cpu), msr, sizeof(*msr), offset);
 
 	if (retval != sizeof *msr)
-		err(-1, "%s offset 0x%llx read failed", pathname, (unsigned long long)offset);
+		err(-1, "msr %d offset 0x%llx read failed", cpu, (unsigned long long)offset);
 
 	return 0;
 }
@@ -286,8 +319,8 @@ int get_msr(int cpu, off_t offset, unsig
 /*
  * Example Format w/ field column widths:
  *
- *  Package    Core     CPU Avg_MHz Bzy_MHz TSC_MHz     SMI   %Busy CPU_%c1 CPU_%c3 CPU_%c6 CPU_%c7 CoreTmp  PkgTmp Pkg%pc2 Pkg%pc3 Pkg%pc6 Pkg%pc7 PkgWatt CorWatt GFXWatt
- * 123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678
+ *  Package    Core     CPU Avg_MHz Bzy_MHz TSC_MHz     IRQ   SMI   Busy% CPU_%c1 CPU_%c3 CPU_%c6 CPU_%c7 CoreTmp  PkgTmp  GFXMHz Pkg%pc2 Pkg%pc3 Pkg%pc6 Pkg%pc7 PkgWatt CorWatt GFXWatt
+ * 12345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678
  */
 
 void print_header(void)
@@ -301,7 +334,7 @@ void print_header(void)
 	if (has_aperf)
 		outp += sprintf(outp, " Avg_MHz");
 	if (has_aperf)
-		outp += sprintf(outp, "   %%Busy");
+		outp += sprintf(outp, "   Busy%%");
 	if (has_aperf)
 		outp += sprintf(outp, " Bzy_MHz");
 	outp += sprintf(outp, " TSC_MHz");
@@ -318,6 +351,8 @@ void print_header(void)
 	if (!debug)
 		goto done;
 
+	if (do_irq)
+		outp += sprintf(outp, "     IRQ");
 	if (do_smi)
 		outp += sprintf(outp, "     SMI");
 
@@ -335,6 +370,12 @@ void print_header(void)
 	if (do_ptm)
 		outp += sprintf(outp, "  PkgTmp");
 
+	if (do_gfx_rc6_ms)
+		outp += sprintf(outp, " GFX%%rc6");
+
+	if (do_gfx_mhz)
+		outp += sprintf(outp, "  GFXMHz");
+
 	if (do_skl_residency) {
 		outp += sprintf(outp, " Totl%%C0");
 		outp += sprintf(outp, "  Any%%C0");
@@ -409,6 +450,8 @@ int dump_counters(struct thread_data *t,
 			extra_msr_offset32, t->extra_msr32);
 		outp += sprintf(outp, "msr0x%x: %016llX\n",
 			extra_msr_offset64, t->extra_msr64);
+		if (do_irq)
+			outp += sprintf(outp, "IRQ: %08X\n", t->irq_count);
 		if (do_smi)
 			outp += sprintf(outp, "SMI: %08X\n", t->smi_count);
 	}
@@ -504,7 +547,7 @@ int format_counters(struct thread_data *
 		outp += sprintf(outp, "%8.0f",
 			1.0 / units * t->aperf / interval_float);
 
-	/* %Busy */
+	/* Busy% */
 	if (has_aperf) {
 		if (!skip_c0)
 			outp += sprintf(outp, "%8.2f", 100.0 * t->mperf/t->tsc/tsc_tweak);
@@ -542,6 +585,10 @@ int format_counters(struct thread_data *
 	if (!debug)
 		goto done;
 
+	/* IRQ */
+	if (do_irq)
+		outp += sprintf(outp, "%8d", t->irq_count);
+
 	/* SMI */
 	if (do_smi)
 		outp += sprintf(outp, "%8d", t->smi_count);
@@ -575,6 +622,14 @@ int format_counters(struct thread_data *
 	if (do_ptm)
 		outp += sprintf(outp, "%8d", p->pkg_temp_c);
 
+	/* GFXrc6 */
+	if (do_gfx_rc6_ms)
+		outp += sprintf(outp, "%8.2f", 100.0 * p->gfx_rc6_ms / 1000.0 / interval_float);
+
+	/* GFXMHz */
+	if (do_gfx_mhz)
+		outp += sprintf(outp, "%8d", p->gfx_mhz);
+
 	/* Totl%C0, Any%C0 GFX%C0 CPUGFX% */
 	if (do_skl_residency) {
 		outp += sprintf(outp, "%8.2f", 100.0 * p->pkg_wtd_core_c0/t->tsc);
@@ -645,15 +700,24 @@ done:
 	return 0;
 }
 
-void flush_stdout()
+void flush_output_stdout(void)
 {
-	fputs(output_buffer, stdout);
-	fflush(stdout);
+	FILE *filep;
+
+	if (outf == stderr)
+		filep = stdout;
+	else
+		filep = outf;
+
+	fputs(output_buffer, filep);
+	fflush(filep);
+
 	outp = output_buffer;
 }
-void flush_stderr()
+void flush_output_stderr(void)
 {
-	fputs(output_buffer, stderr);
+	fputs(output_buffer, outf);
+	fflush(outf);
 	outp = output_buffer;
 }
 void format_all_counters(struct thread_data *t, struct core_data *c, struct pkg_data *p)
@@ -704,6 +768,9 @@ delta_package(struct pkg_data *new, stru
 	old->pc10 = new->pc10 - old->pc10;
 	old->pkg_temp_c = new->pkg_temp_c;
 
+	old->gfx_rc6_ms = new->gfx_rc6_ms - old->gfx_rc6_ms;
+	old->gfx_mhz = new->gfx_mhz;
+
 	DELTA_WRAP32(new->energy_pkg, old->energy_pkg);
 	DELTA_WRAP32(new->energy_cores, old->energy_cores);
 	DELTA_WRAP32(new->energy_gfx, old->energy_gfx);
@@ -745,9 +812,9 @@ delta_thread(struct thread_data *new, st
 		} else {
 
 			if (!aperf_mperf_unstable) {
-				fprintf(stderr, "%s: APERF or MPERF went backwards *\n", progname);
-				fprintf(stderr, "* Frequency results do not cover entire interval *\n");
-				fprintf(stderr, "* fix this by running Linux-2.6.30 or later *\n");
+				fprintf(outf, "%s: APERF or MPERF went backwards *\n", progname);
+				fprintf(outf, "* Frequency results do not cover entire interval *\n");
+				fprintf(outf, "* fix this by running Linux-2.6.30 or later *\n");
 
 				aperf_mperf_unstable = 1;
 			}
@@ -782,7 +849,8 @@ delta_thread(struct thread_data *new, st
 	}
 
 	if (old->mperf == 0) {
-		if (debug > 1) fprintf(stderr, "cpu%d MPERF 0!\n", old->cpu_id);
+		if (debug > 1)
+			fprintf(outf, "cpu%d MPERF 0!\n", old->cpu_id);
 		old->mperf = 1;	/* divide by 0 protection */
 	}
 
@@ -797,6 +865,9 @@ delta_thread(struct thread_data *new, st
 	old->extra_msr32 = new->extra_msr32;
 	old->extra_msr64 = new->extra_msr64;
 
+	if (do_irq)
+		old->irq_count = new->irq_count - old->irq_count;
+
 	if (do_smi)
 		old->smi_count = new->smi_count - old->smi_count;
 }
@@ -826,10 +897,12 @@ void clear_counters(struct thread_data *
 	t->mperf = 0;
 	t->c1 = 0;
 
-	t->smi_count = 0;
 	t->extra_delta32 = 0;
 	t->extra_delta64 = 0;
 
+	t->irq_count = 0;
+	t->smi_count = 0;
+
 	/* tells format_counters to dump all fields from this set */
 	t->flags = CPU_IS_FIRST_THREAD_IN_CORE | CPU_IS_FIRST_CORE_IN_PACKAGE;
 
@@ -861,6 +934,9 @@ void clear_counters(struct thread_data *
 	p->rapl_pkg_perf_status = 0;
 	p->rapl_dram_perf_status = 0;
 	p->pkg_temp_c = 0;
+
+	p->gfx_rc6_ms = 0;
+	p->gfx_mhz = 0;
 }
 int sum_counters(struct thread_data *t, struct core_data *c,
 	struct pkg_data *p)
@@ -873,6 +949,9 @@ int sum_counters(struct thread_data *t,
 	average.threads.extra_delta32 += t->extra_delta32;
 	average.threads.extra_delta64 += t->extra_delta64;
 
+	average.threads.irq_count += t->irq_count;
+	average.threads.smi_count += t->smi_count;
+
 	/* sum per-core values only for 1st thread in core */
 	if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE))
 		return 0;
@@ -910,6 +989,9 @@ int sum_counters(struct thread_data *t,
 	average.packages.energy_cores += p->energy_cores;
 	average.packages.energy_gfx += p->energy_gfx;
 
+	average.packages.gfx_rc6_ms = p->gfx_rc6_ms;
+	average.packages.gfx_mhz = p->gfx_mhz;
+
 	average.packages.pkg_temp_c = MAX(average.packages.pkg_temp_c, p->pkg_temp_c);
 
 	average.packages.rapl_pkg_perf_status += p->rapl_pkg_perf_status;
@@ -970,7 +1052,6 @@ static unsigned long long rdtsc(void)
 	return low | ((unsigned long long)high) << 32;
 }
 
-
 /*
  * get_counters(...)
  * migrate to cpu
@@ -980,23 +1061,74 @@ int get_counters(struct thread_data *t,
 {
 	int cpu = t->cpu_id;
 	unsigned long long msr;
+	int aperf_mperf_retry_count = 0;
 
 	if (cpu_migrate(cpu)) {
-		fprintf(stderr, "Could not migrate to CPU %d\n", cpu);
+		fprintf(outf, "Could not migrate to CPU %d\n", cpu);
 		return -1;
 	}
 
+retry:
 	t->tsc = rdtsc();	/* we are running on local CPU of interest */
 
 	if (has_aperf) {
+		unsigned long long tsc_before, tsc_between, tsc_after, aperf_time, mperf_time;
+
+		/*
+		 * The TSC, APERF and MPERF must be read together for
+		 * APERF/MPERF and MPERF/TSC to give accurate results.
+		 *
+		 * Unfortunately, APERF and MPERF are read by
+		 * individual system call, so delays may occur
+		 * between them.  If the time to read them
+		 * varies by a large amount, we re-read them.
+		 */
+
+		/*
+		 * This initial dummy APERF read has been seen to
+		 * reduce jitter in the subsequent reads.
+		 */
+
 		if (get_msr(cpu, MSR_IA32_APERF, &t->aperf))
 			return -3;
+
+		t->tsc = rdtsc();	/* re-read close to APERF */
+
+		tsc_before = t->tsc;
+
+		if (get_msr(cpu, MSR_IA32_APERF, &t->aperf))
+			return -3;
+
+		tsc_between = rdtsc();
+
 		if (get_msr(cpu, MSR_IA32_MPERF, &t->mperf))
 			return -4;
+
+		tsc_after = rdtsc();
+
+		aperf_time = tsc_between - tsc_before;
+		mperf_time = tsc_after - tsc_between;
+
+		/*
+		 * If the system call latency to read APERF and MPERF
+		 * differ by more than 2x, then try again.
+		 */
+		if ((aperf_time > (2 * mperf_time)) || (mperf_time > (2 * aperf_time))) {
+			aperf_mperf_retry_count++;
+			if (aperf_mperf_retry_count < 5)
+				goto retry;
+			else
+				warnx("cpu%d jitter %lld %lld",
+					cpu, aperf_time, mperf_time);
+		}
+		aperf_mperf_retry_count = 0;
+
 		t->aperf = t->aperf * aperf_mperf_multiplier;
 		t->mperf = t->mperf * aperf_mperf_multiplier;
 	}
 
+	if (do_irq)
+		t->irq_count = irqs_per_cpu[cpu];
 	if (do_smi) {
 		if (get_msr(cpu, MSR_SMI_COUNT, &msr))
 			return -5;
@@ -1124,6 +1256,13 @@ int get_counters(struct thread_data *t,
 			return -17;
 		p->pkg_temp_c = tcc_activation_temp - ((msr >> 16) & 0x7F);
 	}
+
+	if (do_gfx_rc6_ms)
+		p->gfx_rc6_ms = gfx_cur_rc6_ms;
+
+	if (do_gfx_mhz)
+		p->gfx_mhz = gfx_cur_mhz;
+
 	return 0;
 }
 
@@ -1159,6 +1298,7 @@ int hsw_pkg_cstate_limits[16] = {PCL__0,
 int slv_pkg_cstate_limits[16] = {PCL__0, PCL__1, PCLRSV, PCLRSV, PCL__4, PCLRSV, PCL__6, PCL__7, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV};
 int amt_pkg_cstate_limits[16] = {PCL__0, PCL__1, PCL__2, PCLRSV, PCLRSV, PCLRSV, PCL__6, PCL__7, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV};
 int phi_pkg_cstate_limits[16] = {PCL__0, PCL__2, PCL_6N, PCL_6R, PCLRSV, PCLRSV, PCLRSV, PCLUNL, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV};
+int bxt_pkg_cstate_limits[16] = {PCL__0, PCL__2, PCLUNL, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV};
 
 
 static void
@@ -1175,18 +1315,18 @@ dump_nhm_platform_info(void)
 
 	get_msr(base_cpu, MSR_PLATFORM_INFO, &msr);
 
-	fprintf(stderr, "cpu%d: MSR_PLATFORM_INFO: 0x%08llx\n", base_cpu, msr);
+	fprintf(outf, "cpu%d: MSR_PLATFORM_INFO: 0x%08llx\n", base_cpu, msr);
 
 	ratio = (msr >> 40) & 0xFF;
-	fprintf(stderr, "%d * %.0f = %.0f MHz max efficiency frequency\n",
+	fprintf(outf, "%d * %.0f = %.0f MHz max efficiency frequency\n",
 		ratio, bclk, ratio * bclk);
 
 	ratio = (msr >> 8) & 0xFF;
-	fprintf(stderr, "%d * %.0f = %.0f MHz base frequency\n",
+	fprintf(outf, "%d * %.0f = %.0f MHz base frequency\n",
 		ratio, bclk, ratio * bclk);
 
 	get_msr(base_cpu, MSR_IA32_POWER_CTL, &msr);
-	fprintf(stderr, "cpu%d: MSR_IA32_POWER_CTL: 0x%08llx (C1E auto-promotion: %sabled)\n",
+	fprintf(outf, "cpu%d: MSR_IA32_POWER_CTL: 0x%08llx (C1E auto-promotion: %sabled)\n",
 		base_cpu, msr, msr & 0x2 ? "EN" : "DIS");
 
 	return;
@@ -1200,16 +1340,16 @@ dump_hsw_turbo_ratio_limits(void)
 
 	get_msr(base_cpu, MSR_TURBO_RATIO_LIMIT2, &msr);
 
-	fprintf(stderr, "cpu%d: MSR_TURBO_RATIO_LIMIT2: 0x%08llx\n", base_cpu, msr);
+	fprintf(outf, "cpu%d: MSR_TURBO_RATIO_LIMIT2: 0x%08llx\n", base_cpu, msr);
 
 	ratio = (msr >> 8) & 0xFF;
 	if (ratio)
-		fprintf(stderr, "%d * %.0f = %.0f MHz max turbo 18 active cores\n",
+		fprintf(outf, "%d * %.0f = %.0f MHz max turbo 18 active cores\n",
 			ratio, bclk, ratio * bclk);
 
 	ratio = (msr >> 0) & 0xFF;
 	if (ratio)
-		fprintf(stderr, "%d * %.0f = %.0f MHz max turbo 17 active cores\n",
+		fprintf(outf, "%d * %.0f = %.0f MHz max turbo 17 active cores\n",
 			ratio, bclk, ratio * bclk);
 	return;
 }
@@ -1222,46 +1362,46 @@ dump_ivt_turbo_ratio_limits(void)
 
 	get_msr(base_cpu, MSR_TURBO_RATIO_LIMIT1, &msr);
 
-	fprintf(stderr, "cpu%d: MSR_TURBO_RATIO_LIMIT1: 0x%08llx\n", base_cpu, msr);
+	fprintf(outf, "cpu%d: MSR_TURBO_RATIO_LIMIT1: 0x%08llx\n", base_cpu, msr);
 
 	ratio = (msr >> 56) & 0xFF;
 	if (ratio)
-		fprintf(stderr, "%d * %.0f = %.0f MHz max turbo 16 active cores\n",
+		fprintf(outf, "%d * %.0f = %.0f MHz max turbo 16 active cores\n",
 			ratio, bclk, ratio * bclk);
 
 	ratio = (msr >> 48) & 0xFF;
 	if (ratio)
-		fprintf(stderr, "%d * %.0f = %.0f MHz max turbo 15 active cores\n",
+		fprintf(outf, "%d * %.0f = %.0f MHz max turbo 15 active cores\n",
 			ratio, bclk, ratio * bclk);
 
 	ratio = (msr >> 40) & 0xFF;
 	if (ratio)
-		fprintf(stderr, "%d * %.0f = %.0f MHz max turbo 14 active cores\n",
+		fprintf(outf, "%d * %.0f = %.0f MHz max turbo 14 active cores\n",
 			ratio, bclk, ratio * bclk);
 
 	ratio = (msr >> 32) & 0xFF;
 	if (ratio)
-		fprintf(stderr, "%d * %.0f = %.0f MHz max turbo 13 active cores\n",
+		fprintf(outf, "%d * %.0f = %.0f MHz max turbo 13 active cores\n",
 			ratio, bclk, ratio * bclk);
 
 	ratio = (msr >> 24) & 0xFF;
 	if (ratio)
-		fprintf(stderr, "%d * %.0f = %.0f MHz max turbo 12 active cores\n",
+		fprintf(outf, "%d * %.0f = %.0f MHz max turbo 12 active cores\n",
 			ratio, bclk, ratio * bclk);
 
 	ratio = (msr >> 16) & 0xFF;
 	if (ratio)
-		fprintf(stderr, "%d * %.0f = %.0f MHz max turbo 11 active cores\n",
+		fprintf(outf, "%d * %.0f = %.0f MHz max turbo 11 active cores\n",
 			ratio, bclk, ratio * bclk);
 
 	ratio = (msr >> 8) & 0xFF;
 	if (ratio)
-		fprintf(stderr, "%d * %.0f = %.0f MHz max turbo 10 active cores\n",
+		fprintf(outf, "%d * %.0f = %.0f MHz max turbo 10 active cores\n",
 			ratio, bclk, ratio * bclk);
 
 	ratio = (msr >> 0) & 0xFF;
 	if (ratio)
-		fprintf(stderr, "%d * %.0f = %.0f MHz max turbo 9 active cores\n",
+		fprintf(outf, "%d * %.0f = %.0f MHz max turbo 9 active cores\n",
 			ratio, bclk, ratio * bclk);
 	return;
 }
@@ -1274,46 +1414,46 @@ dump_nhm_turbo_ratio_limits(void)
 
 	get_msr(base_cpu, MSR_TURBO_RATIO_LIMIT, &msr);
 
-	fprintf(stderr, "cpu%d: MSR_TURBO_RATIO_LIMIT: 0x%08llx\n", base_cpu, msr);
+	fprintf(outf, "cpu%d: MSR_TURBO_RATIO_LIMIT: 0x%08llx\n", base_cpu, msr);
 
 	ratio = (msr >> 56) & 0xFF;
 	if (ratio)
-		fprintf(stderr, "%d * %.0f = %.0f MHz max turbo 8 active cores\n",
+		fprintf(outf, "%d * %.0f = %.0f MHz max turbo 8 active cores\n",
 			ratio, bclk, ratio * bclk);
 
 	ratio = (msr >> 48) & 0xFF;
 	if (ratio)
-		fprintf(stderr, "%d * %.0f = %.0f MHz max turbo 7 active cores\n",
+		fprintf(outf, "%d * %.0f = %.0f MHz max turbo 7 active cores\n",
 			ratio, bclk, ratio * bclk);
 
 	ratio = (msr >> 40) & 0xFF;
 	if (ratio)
-		fprintf(stderr, "%d * %.0f = %.0f MHz max turbo 6 active cores\n",
+		fprintf(outf, "%d * %.0f = %.0f MHz max turbo 6 active cores\n",
 			ratio, bclk, ratio * bclk);
 
 	ratio = (msr >> 32) & 0xFF;
 	if (ratio)
-		fprintf(stderr, "%d * %.0f = %.0f MHz max turbo 5 active cores\n",
+		fprintf(outf, "%d * %.0f = %.0f MHz max turbo 5 active cores\n",
 			ratio, bclk, ratio * bclk);
 
 	ratio = (msr >> 24) & 0xFF;
 	if (ratio)
-		fprintf(stderr, "%d * %.0f = %.0f MHz max turbo 4 active cores\n",
+		fprintf(outf, "%d * %.0f = %.0f MHz max turbo 4 active cores\n",
 			ratio, bclk, ratio * bclk);
 
 	ratio = (msr >> 16) & 0xFF;
 	if (ratio)
-		fprintf(stderr, "%d * %.0f = %.0f MHz max turbo 3 active cores\n",
+		fprintf(outf, "%d * %.0f = %.0f MHz max turbo 3 active cores\n",
 			ratio, bclk, ratio * bclk);
 
 	ratio = (msr >> 8) & 0xFF;
 	if (ratio)
-		fprintf(stderr, "%d * %.0f = %.0f MHz max turbo 2 active cores\n",
+		fprintf(outf, "%d * %.0f = %.0f MHz max turbo 2 active cores\n",
 			ratio, bclk, ratio * bclk);
 
 	ratio = (msr >> 0) & 0xFF;
 	if (ratio)
-		fprintf(stderr, "%d * %.0f = %.0f MHz max turbo 1 active cores\n",
+		fprintf(outf, "%d * %.0f = %.0f MHz max turbo 1 active cores\n",
 			ratio, bclk, ratio * bclk);
 	return;
 }
@@ -1321,21 +1461,23 @@ dump_nhm_turbo_ratio_limits(void)
 static void
 dump_knl_turbo_ratio_limits(void)
 {
-	int cores;
-	unsigned int ratio;
+	const unsigned int buckets_no = 7;
+
 	unsigned long long msr;
-	int delta_cores;
-	int delta_ratio;
-	int i;
+	int delta_cores, delta_ratio;
+	int i, b_nr;
+	unsigned int cores[buckets_no];
+	unsigned int ratio[buckets_no];
 
 	get_msr(base_cpu, MSR_NHM_TURBO_RATIO_LIMIT, &msr);
 
-	fprintf(stderr, "cpu%d: MSR_NHM_TURBO_RATIO_LIMIT: 0x%08llx\n",
+	fprintf(outf, "cpu%d: MSR_TURBO_RATIO_LIMIT: 0x%08llx\n",
 		base_cpu, msr);
 
 	/**
 	 * Turbo encoding in KNL is as follows:
-	 * [7:0] -- Base value of number of active cores of bucket 1.
+	 * [0] -- Reserved
+	 * [7:1] -- Base value of number of active cores of bucket 1.
 	 * [15:8] -- Base value of freq ratio of bucket 1.
 	 * [20:16] -- +ve delta of number of active cores of bucket 2.
 	 * i.e. active cores of bucket 2 =
@@ -1354,29 +1496,25 @@ dump_knl_turbo_ratio_limits(void)
 	 * [60:56]-- +ve delta of number of active cores of bucket 7.
 	 * [63:61]-- -ve delta of freq ratio of bucket 7.
 	 */
-	cores = msr & 0xFF;
-	ratio = (msr >> 8) && 0xFF;
-	if (ratio > 0)
-		fprintf(stderr,
-			"%d * %.0f = %.0f MHz max turbo %d active cores\n",
-			ratio, bclk, ratio * bclk, cores);
 
-	for (i = 16; i < 64; i = i + 8) {
+	b_nr = 0;
+	cores[b_nr] = (msr & 0xFF) >> 1;
+	ratio[b_nr] = (msr >> 8) & 0xFF;
+
+	for (i = 16; i < 64; i += 8) {
 		delta_cores = (msr >> i) & 0x1F;
-		delta_ratio = (msr >> (i + 5)) && 0x7;
-		if (!delta_cores || !delta_ratio)
-			return;
-		cores = cores + delta_cores;
-		ratio = ratio - delta_ratio;
+		delta_ratio = (msr >> (i + 5)) & 0x7;
 
-		/** -ve ratios will make successive ratio calculations
-		 * negative. Hence return instead of carrying on.
-		 */
-		if (ratio > 0)
-			fprintf(stderr,
-				"%d * %.0f = %.0f MHz max turbo %d active cores\n",
-				ratio, bclk, ratio * bclk, cores);
+		cores[b_nr + 1] = cores[b_nr] + delta_cores;
+		ratio[b_nr + 1] = ratio[b_nr] - delta_ratio;
+		b_nr++;
 	}
+
+	for (i = buckets_no - 1; i >= 0; i--)
+		if (i > 0 ? ratio[i] != ratio[i - 1] : 1)
+			fprintf(outf,
+				"%d * %.0f = %.0f MHz max turbo %d active cores\n",
+				ratio[i], bclk, ratio[i] * bclk, cores[i]);
 }
 
 static void
@@ -1389,15 +1527,15 @@ dump_nhm_cst_cfg(void)
 #define SNB_C1_AUTO_UNDEMOTE              (1UL << 27)
 #define SNB_C3_AUTO_UNDEMOTE              (1UL << 28)
 
-	fprintf(stderr, "cpu%d: MSR_NHM_SNB_PKG_CST_CFG_CTL: 0x%08llx", base_cpu, msr);
+	fprintf(outf, "cpu%d: MSR_NHM_SNB_PKG_CST_CFG_CTL: 0x%08llx", base_cpu, msr);
 
-	fprintf(stderr, " (%s%s%s%s%slocked: pkg-cstate-limit=%d: %s)\n",
+	fprintf(outf, " (%s%s%s%s%slocked: pkg-cstate-limit=%d: %s)\n",
 		(msr & SNB_C3_AUTO_UNDEMOTE) ? "UNdemote-C3, " : "",
 		(msr & SNB_C1_AUTO_UNDEMOTE) ? "UNdemote-C1, " : "",
 		(msr & NHM_C3_AUTO_DEMOTE) ? "demote-C3, " : "",
 		(msr & NHM_C1_AUTO_DEMOTE) ? "demote-C1, " : "",
 		(msr & (1 << 15)) ? "" : "UN",
-		(unsigned int)msr & 7,
+		(unsigned int)msr & 0xF,
 		pkg_cstate_limit_strings[pkg_cstate_limit]);
 	return;
 }
@@ -1408,48 +1546,100 @@ dump_config_tdp(void)
 	unsigned long long msr;
 
 	get_msr(base_cpu, MSR_CONFIG_TDP_NOMINAL, &msr);
-	fprintf(stderr, "cpu%d: MSR_CONFIG_TDP_NOMINAL: 0x%08llx", base_cpu, msr);
-	fprintf(stderr, " (base_ratio=%d)\n", (unsigned int)msr & 0xEF);
+	fprintf(outf, "cpu%d: MSR_CONFIG_TDP_NOMINAL: 0x%08llx", base_cpu, msr);
+	fprintf(outf, " (base_ratio=%d)\n", (unsigned int)msr & 0xFF);
 
 	get_msr(base_cpu, MSR_CONFIG_TDP_LEVEL_1, &msr);
-	fprintf(stderr, "cpu%d: MSR_CONFIG_TDP_LEVEL_1: 0x%08llx (", base_cpu, msr);
+	fprintf(outf, "cpu%d: MSR_CONFIG_TDP_LEVEL_1: 0x%08llx (", base_cpu, msr);
 	if (msr) {
-		fprintf(stderr, "PKG_MIN_PWR_LVL1=%d ", (unsigned int)(msr >> 48) & 0xEFFF);
-		fprintf(stderr, "PKG_MAX_PWR_LVL1=%d ", (unsigned int)(msr >> 32) & 0xEFFF);
-		fprintf(stderr, "LVL1_RATIO=%d ", (unsigned int)(msr >> 16) & 0xEF);
-		fprintf(stderr, "PKG_TDP_LVL1=%d", (unsigned int)(msr) & 0xEFFF);
+		fprintf(outf, "PKG_MIN_PWR_LVL1=%d ", (unsigned int)(msr >> 48) & 0x7FFF);
+		fprintf(outf, "PKG_MAX_PWR_LVL1=%d ", (unsigned int)(msr >> 32) & 0x7FFF);
+		fprintf(outf, "LVL1_RATIO=%d ", (unsigned int)(msr >> 16) & 0xFF);
+		fprintf(outf, "PKG_TDP_LVL1=%d", (unsigned int)(msr) & 0x7FFF);
 	}
-	fprintf(stderr, ")\n");
+	fprintf(outf, ")\n");
 
 	get_msr(base_cpu, MSR_CONFIG_TDP_LEVEL_2, &msr);
-	fprintf(stderr, "cpu%d: MSR_CONFIG_TDP_LEVEL_2: 0x%08llx (", base_cpu, msr);
+	fprintf(outf, "cpu%d: MSR_CONFIG_TDP_LEVEL_2: 0x%08llx (", base_cpu, msr);
 	if (msr) {
-		fprintf(stderr, "PKG_MIN_PWR_LVL2=%d ", (unsigned int)(msr >> 48) & 0xEFFF);
-		fprintf(stderr, "PKG_MAX_PWR_LVL2=%d ", (unsigned int)(msr >> 32) & 0xEFFF);
-		fprintf(stderr, "LVL2_RATIO=%d ", (unsigned int)(msr >> 16) & 0xEF);
-		fprintf(stderr, "PKG_TDP_LVL2=%d", (unsigned int)(msr) & 0xEFFF);
+		fprintf(outf, "PKG_MIN_PWR_LVL2=%d ", (unsigned int)(msr >> 48) & 0x7FFF);
+		fprintf(outf, "PKG_MAX_PWR_LVL2=%d ", (unsigned int)(msr >> 32) & 0x7FFF);
+		fprintf(outf, "LVL2_RATIO=%d ", (unsigned int)(msr >> 16) & 0xFF);
+		fprintf(outf, "PKG_TDP_LVL2=%d", (unsigned int)(msr) & 0x7FFF);
 	}
-	fprintf(stderr, ")\n");
+	fprintf(outf, ")\n");
 
 	get_msr(base_cpu, MSR_CONFIG_TDP_CONTROL, &msr);
-	fprintf(stderr, "cpu%d: MSR_CONFIG_TDP_CONTROL: 0x%08llx (", base_cpu, msr);
+	fprintf(outf, "cpu%d: MSR_CONFIG_TDP_CONTROL: 0x%08llx (", base_cpu, msr);
 	if ((msr) & 0x3)
-		fprintf(stderr, "TDP_LEVEL=%d ", (unsigned int)(msr) & 0x3);
-	fprintf(stderr, " lock=%d", (unsigned int)(msr >> 31) & 1);
-	fprintf(stderr, ")\n");
-	
+		fprintf(outf, "TDP_LEVEL=%d ", (unsigned int)(msr) & 0x3);
+	fprintf(outf, " lock=%d", (unsigned int)(msr >> 31) & 1);
+	fprintf(outf, ")\n");
+
 	get_msr(base_cpu, MSR_TURBO_ACTIVATION_RATIO, &msr);
-	fprintf(stderr, "cpu%d: MSR_TURBO_ACTIVATION_RATIO: 0x%08llx (", base_cpu, msr);
-	fprintf(stderr, "MAX_NON_TURBO_RATIO=%d", (unsigned int)(msr) & 0x7F);
-	fprintf(stderr, " lock=%d", (unsigned int)(msr >> 31) & 1);
-	fprintf(stderr, ")\n");
+	fprintf(outf, "cpu%d: MSR_TURBO_ACTIVATION_RATIO: 0x%08llx (", base_cpu, msr);
+	fprintf(outf, "MAX_NON_TURBO_RATIO=%d", (unsigned int)(msr) & 0xFF);
+	fprintf(outf, " lock=%d", (unsigned int)(msr >> 31) & 1);
+	fprintf(outf, ")\n");
+}
+
+unsigned int irtl_time_units[] = {1, 32, 1024, 32768, 1048576, 33554432, 0, 0 };
+
+void print_irtl(void)
+{
+	unsigned long long msr;
+
+	get_msr(base_cpu, MSR_PKGC3_IRTL, &msr);
+	fprintf(outf, "cpu%d: MSR_PKGC3_IRTL: 0x%08llx (", base_cpu, msr);
+	fprintf(outf, "%svalid, %lld ns)\n", msr & (1 << 15) ? "" : "NOT",
+		(msr & 0x3FF) * irtl_time_units[(msr >> 10) & 0x3]);
+
+	get_msr(base_cpu, MSR_PKGC6_IRTL, &msr);
+	fprintf(outf, "cpu%d: MSR_PKGC6_IRTL: 0x%08llx (", base_cpu, msr);
+	fprintf(outf, "%svalid, %lld ns)\n", msr & (1 << 15) ? "" : "NOT",
+		(msr & 0x3FF) * irtl_time_units[(msr >> 10) & 0x3]);
+
+	get_msr(base_cpu, MSR_PKGC7_IRTL, &msr);
+	fprintf(outf, "cpu%d: MSR_PKGC7_IRTL: 0x%08llx (", base_cpu, msr);
+	fprintf(outf, "%svalid, %lld ns)\n", msr & (1 << 15) ? "" : "NOT",
+		(msr & 0x3FF) * irtl_time_units[(msr >> 10) & 0x3]);
+
+	if (!do_irtl_hsw)
+		return;
+
+	get_msr(base_cpu, MSR_PKGC8_IRTL, &msr);
+	fprintf(outf, "cpu%d: MSR_PKGC8_IRTL: 0x%08llx (", base_cpu, msr);
+	fprintf(outf, "%svalid, %lld ns)\n", msr & (1 << 15) ? "" : "NOT",
+		(msr & 0x3FF) * irtl_time_units[(msr >> 10) & 0x3]);
+
+	get_msr(base_cpu, MSR_PKGC9_IRTL, &msr);
+	fprintf(outf, "cpu%d: MSR_PKGC9_IRTL: 0x%08llx (", base_cpu, msr);
+	fprintf(outf, "%svalid, %lld ns)\n", msr & (1 << 15) ? "" : "NOT",
+		(msr & 0x3FF) * irtl_time_units[(msr >> 10) & 0x3]);
+
+	get_msr(base_cpu, MSR_PKGC10_IRTL, &msr);
+	fprintf(outf, "cpu%d: MSR_PKGC10_IRTL: 0x%08llx (", base_cpu, msr);
+	fprintf(outf, "%svalid, %lld ns)\n", msr & (1 << 15) ? "" : "NOT",
+		(msr & 0x3FF) * irtl_time_units[(msr >> 10) & 0x3]);
+
+}
+void free_fd_percpu(void)
+{
+	int i;
+
+	for (i = 0; i < topo.max_cpu_num; ++i) {
+		if (fd_percpu[i] != 0)
+			close(fd_percpu[i]);
+	}
+
+	free(fd_percpu);
 }
 
 void free_all_buffers(void)
 {
 	CPU_FREE(cpu_present_set);
 	cpu_present_set = NULL;
-	cpu_present_set = 0;
+	cpu_present_setsize = 0;
 
 	CPU_FREE(cpu_affinity_set);
 	cpu_affinity_set = NULL;
@@ -1474,6 +1664,11 @@ void free_all_buffers(void)
 	free(output_buffer);
 	output_buffer = NULL;
 	outp = NULL;
+
+	free_fd_percpu();
+
+	free(irq_column_2_cpu);
+	free(irqs_per_cpu);
 }
 
 /*
@@ -1481,7 +1676,7 @@ void free_all_buffers(void)
  */
 FILE *fopen_or_die(const char *path, const char *mode)
 {
-	FILE *filep = fopen(path, "r");
+	FILE *filep = fopen(path, mode);
 	if (!filep)
 		err(1, "%s: open failed", path);
 	return filep;
@@ -1696,6 +1891,136 @@ int mark_cpu_present(int cpu)
 	return 0;
 }
 
+/*
+ * snapshot_proc_interrupts()
+ *
+ * read and record summary of /proc/interrupts
+ *
+ * return 1 if config change requires a restart, else return 0
+ */
+int snapshot_proc_interrupts(void)
+{
+	static FILE *fp;
+	int column, retval;
+
+	if (fp == NULL)
+		fp = fopen_or_die("/proc/interrupts", "r");
+	else
+		rewind(fp);
+
+	/* read 1st line of /proc/interrupts to get cpu* name for each column */
+	for (column = 0; column < topo.num_cpus; ++column) {
+		int cpu_number;
+
+		retval = fscanf(fp, " CPU%d", &cpu_number);
+		if (retval != 1)
+			break;
+
+		if (cpu_number > topo.max_cpu_num) {
+			warn("/proc/interrupts: cpu%d: > %d", cpu_number, topo.max_cpu_num);
+			return 1;
+		}
+
+		irq_column_2_cpu[column] = cpu_number;
+		irqs_per_cpu[cpu_number] = 0;
+	}
+
+	/* read /proc/interrupt count lines and sum up irqs per cpu */
+	while (1) {
+		int column;
+		char buf[64];
+
+		retval = fscanf(fp, " %s:", buf);	/* flush irq# "N:" */
+		if (retval != 1)
+			break;
+
+		/* read the count per cpu */
+		for (column = 0; column < topo.num_cpus; ++column) {
+
+			int cpu_number, irq_count;
+
+			retval = fscanf(fp, " %d", &irq_count);
+			if (retval != 1)
+				break;
+
+			cpu_number = irq_column_2_cpu[column];
+			irqs_per_cpu[cpu_number] += irq_count;
+
+		}
+
+		while (getc(fp) != '\n')
+			;	/* flush interrupt description */
+
+	}
+	return 0;
+}
+/*
+ * snapshot_gfx_rc6_ms()
+ *
+ * record snapshot of
+ * /sys/class/drm/card0/power/rc6_residency_ms
+ *
+ * return 1 if config change requires a restart, else return 0
+ */
+int snapshot_gfx_rc6_ms(void)
+{
+	FILE *fp;
+	int retval;
+
+	fp = fopen_or_die("/sys/class/drm/card0/power/rc6_residency_ms", "r");
+
+	retval = fscanf(fp, "%lld", &gfx_cur_rc6_ms);
+	if (retval != 1)
+		err(1, "GFX rc6");
+
+	fclose(fp);
+
+	return 0;
+}
+/*
+ * snapshot_gfx_mhz()
+ *
+ * record snapshot of
+ * /sys/class/graphics/fb0/device/drm/card0/gt_cur_freq_mhz
+ *
+ * return 1 if config change requires a restart, else return 0
+ */
+int snapshot_gfx_mhz(void)
+{
+	static FILE *fp;
+	int retval;
+
+	if (fp == NULL)
+		fp = fopen_or_die("/sys/class/graphics/fb0/device/drm/card0/gt_cur_freq_mhz", "r");
+	else
+		rewind(fp);
+
+	retval = fscanf(fp, "%d", &gfx_cur_mhz);
+	if (retval != 1)
+		err(1, "GFX MHz");
+
+	return 0;
+}
+
+/*
+ * snapshot /proc and /sys files
+ *
+ * return 1 if configuration restart needed, else return 0
+ */
+int snapshot_proc_sysfs_files(void)
+{
+	if (snapshot_proc_interrupts())
+		return 1;
+
+	if (do_gfx_rc6_ms)
+		snapshot_gfx_rc6_ms();
+
+	if (do_gfx_mhz)
+		snapshot_gfx_mhz();
+
+	return 0;
+}
+
 void turbostat_loop()
 {
 	int retval;
@@ -1704,6 +2029,7 @@ void turbostat_loop()
 restart:
 	restarted++;
 
+	snapshot_proc_sysfs_files();
 	retval = for_all_cpus(get_counters, EVEN_COUNTERS);
 	if (retval < -1) {
 		exit(retval);
@@ -1722,7 +2048,9 @@ restart:
 			re_initialize();
 			goto restart;
 		}
-		sleep(interval_sec);
+		nanosleep(&interval_ts, NULL);
+		if (snapshot_proc_sysfs_files())
+			goto restart;
 		retval = for_all_cpus(get_counters, ODD_COUNTERS);
 		if (retval < -1) {
 			exit(retval);
@@ -1735,8 +2063,10 @@ restart:
 		for_all_cpus_2(delta_cpu, ODD_COUNTERS, EVEN_COUNTERS);
 		compute_average(EVEN_COUNTERS);
 		format_all_counters(EVEN_COUNTERS);
-		flush_stdout();
-		sleep(interval_sec);
+		flush_output_stdout();
+		nanosleep(&interval_ts, NULL);
+		if (snapshot_proc_sysfs_files())
+			goto restart;
 		retval = for_all_cpus(get_counters, EVEN_COUNTERS);
 		if (retval < -1) {
 			exit(retval);
@@ -1749,7 +2079,7 @@ restart:
 		for_all_cpus_2(delta_cpu, EVEN_COUNTERS, ODD_COUNTERS);
 		compute_average(ODD_COUNTERS);
 		format_all_counters(ODD_COUNTERS);
-		flush_stdout();
+		flush_output_stdout();
 	}
 }
 
@@ -1858,6 +2188,7 @@ int probe_nhm_msrs(unsigned int family,
 	case 0x56:	/* BDX-DE */
 	case 0x4E:	/* SKL */
 	case 0x5E:	/* SKL */
+	case 0x55:	/* SKX */
 		pkg_cstate_limits = hsw_pkg_cstate_limits;
 		break;
 	case 0x37:	/* BYT */
@@ -1870,6 +2201,9 @@ int probe_nhm_msrs(unsigned int family,
 	case 0x57:	/* PHI */
 		pkg_cstate_limits = phi_pkg_cstate_limits;
 		break;
+	case 0x5C:	/* BXT */
+		pkg_cstate_limits = bxt_pkg_cstate_limits;
+		break;
 	default:
 		return 0;
 	}
@@ -1889,6 +2223,7 @@ int has_nhm_turbo_ratio_limit(unsigned i
 	/* Nehalem compatible, but do not include turbo-ratio limit support */
 	case 0x2E:	/* Nehalem-EX Xeon - Beckton */
 	case 0x2F:	/* Westmere-EX Xeon - Eagleton */
+	case 0x57:	/* PHI - Knights Landing (different MSR definition) */
 		return 0;
 	default:
 		return 1;
@@ -1961,6 +2296,7 @@ int has_config_tdp(unsigned int family,
 	case 0x56:	/* BDX-DE */
 	case 0x4E:	/* SKL */
 	case 0x5E:	/* SKL */
+	case 0x55:	/* SKX */
 
 	case 0x57:	/* Knights Landing */
 		return 1;
@@ -1970,7 +2306,7 @@ int has_config_tdp(unsigned int family,
 }
 
 static void
-dump_cstate_pstate_config_info(family, model)
+dump_cstate_pstate_config_info(int family, int model)
 {
 	if (!do_nhm_platform_info)
 		return;
@@ -2016,7 +2352,7 @@ int print_epb(struct thread_data *t, str
 		return 0;
 
 	if (cpu_migrate(cpu)) {
-		fprintf(stderr, "Could not migrate to CPU %d\n", cpu);
+		fprintf(outf, "Could not migrate to CPU %d\n", cpu);
 		return -1;
 	}
 
@@ -2037,7 +2373,98 @@ int print_epb(struct thread_data *t, str
 		epb_string = "custom";
 		break;
 	}
-	fprintf(stderr, "cpu%d: MSR_IA32_ENERGY_PERF_BIAS: 0x%08llx (%s)\n", cpu, msr, epb_string);
+	fprintf(outf, "cpu%d: MSR_IA32_ENERGY_PERF_BIAS: 0x%08llx (%s)\n", cpu, msr, epb_string);
+
+	return 0;
+}
+/*
+ * print_hwp()
+ * Decode the MSR_HWP_CAPABILITIES
+ */
+int print_hwp(struct thread_data *t, struct core_data *c, struct pkg_data *p)
+{
+	unsigned long long msr;
+	int cpu;
+
+	if (!has_hwp)
+		return 0;
+
+	cpu = t->cpu_id;
+
+	/* MSR_HWP_CAPABILITIES is per-package */
+	if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE) || !(t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE))
+		return 0;
+
+	if (cpu_migrate(cpu)) {
+		fprintf(outf, "Could not migrate to CPU %d\n", cpu);
+		return -1;
+	}
+
+	if (get_msr(cpu, MSR_PM_ENABLE, &msr))
+		return 0;
+
+	fprintf(outf, "cpu%d: MSR_PM_ENABLE: 0x%08llx (%sHWP)\n",
+		cpu, msr, (msr & (1 << 0)) ? "" : "No-");
+
+	/* MSR_PM_ENABLE[1] == 1 if HWP is enabled and MSRs visible */
+	if ((msr & (1 << 0)) == 0)
+		return 0;
+
+	if (get_msr(cpu, MSR_HWP_CAPABILITIES, &msr))
+		return 0;
+
+	fprintf(outf, "cpu%d: MSR_HWP_CAPABILITIES: 0x%08llx "
+			"(high 0x%x guar 0x%x eff 0x%x low 0x%x)\n",
+			cpu, msr,
+			(unsigned int)HWP_HIGHEST_PERF(msr),
+			(unsigned int)HWP_GUARANTEED_PERF(msr),
+			(unsigned int)HWP_MOSTEFFICIENT_PERF(msr),
+			(unsigned int)HWP_LOWEST_PERF(msr));
+
+	if (get_msr(cpu, MSR_HWP_REQUEST, &msr))
+		return 0;
+
+	fprintf(outf, "cpu%d: MSR_HWP_REQUEST: 0x%08llx "
+			"(min 0x%x max 0x%x des 0x%x epp 0x%x window 0x%x pkg 0x%x)\n",
+			cpu, msr,
+			(unsigned int)(((msr) >> 0) & 0xff),
+			(unsigned int)(((msr) >> 8) & 0xff),
+			(unsigned int)(((msr) >> 16) & 0xff),
+			(unsigned int)(((msr) >> 24) & 0xff),
+			(unsigned int)(((msr) >> 32) & 0xff3),
+			(unsigned int)(((msr) >> 42) & 0x1));
+
+	if (has_hwp_pkg) {
+		if (get_msr(cpu, MSR_HWP_REQUEST_PKG, &msr))
+			return 0;
+
+		fprintf(outf, "cpu%d: MSR_HWP_REQUEST_PKG: 0x%08llx "
+			"(min 0x%x max 0x%x des 0x%x epp 0x%x window 0x%x)\n",
+			cpu, msr,
+			(unsigned int)(((msr) >> 0) & 0xff),
+			(unsigned int)(((msr) >> 8) & 0xff),
+			(unsigned int)(((msr) >> 16) & 0xff),
+			(unsigned int)(((msr) >> 24) & 0xff),
+			(unsigned int)(((msr) >> 32) & 0xff3));
+	}
+	if (has_hwp_notify) {
+		if (get_msr(cpu, MSR_HWP_INTERRUPT, &msr))
+			return 0;
+
+		fprintf(outf, "cpu%d: MSR_HWP_INTERRUPT: 0x%08llx "
+			"(%s_Guaranteed_Perf_Change, %s_Excursion_Min)\n",
+			cpu, msr,
+			((msr) & 0x1) ? "EN" : "Dis",
+			((msr) & 0x2) ? "EN" : "Dis");
+	}
+	if (get_msr(cpu, MSR_HWP_STATUS, &msr))
+		return 0;
+
+	fprintf(outf, "cpu%d: MSR_HWP_STATUS: 0x%08llx "
+			"(%sGuaranteed_Perf_Change, %sExcursion_Min)\n",
+			cpu, msr,
+			((msr) & 0x1) ? "" : "No-",
+			((msr) & 0x2) ? "" : "No-");
 
 	return 0;
 }
@@ -2057,14 +2484,14 @@ int print_perf_limit(struct thread_data
 		return 0;
 
 	if (cpu_migrate(cpu)) {
-		fprintf(stderr, "Could not migrate to CPU %d\n", cpu);
+		fprintf(outf, "Could not migrate to CPU %d\n", cpu);
 		return -1;
 	}
 
 	if (do_core_perf_limit_reasons) {
 		get_msr(cpu, MSR_CORE_PERF_LIMIT_REASONS, &msr);
-		fprintf(stderr, "cpu%d: MSR_CORE_PERF_LIMIT_REASONS, 0x%08llx", cpu, msr);
-		fprintf(stderr, " (Active: %s%s%s%s%s%s%s%s%s%s%s%s%s%s)",
+		fprintf(outf, "cpu%d: MSR_CORE_PERF_LIMIT_REASONS, 0x%08llx", cpu, msr);
+		fprintf(outf, " (Active: %s%s%s%s%s%s%s%s%s%s%s%s%s%s)",
 			(msr & 1 << 15) ? "bit15, " : "",
 			(msr & 1 << 14) ? "bit14, " : "",
 			(msr & 1 << 13) ? "Transitions, " : "",
@@ -2079,7 +2506,7 @@ int print_perf_limit(struct thread_data
 			(msr & 1 << 2) ? "bit2, " : "",
 			(msr & 1 << 1) ? "ThermStatus, " : "",
 			(msr & 1 << 0) ? "PROCHOT, " : "");
-		fprintf(stderr, " (Logged: %s%s%s%s%s%s%s%s%s%s%s%s%s%s)\n",
+		fprintf(outf, " (Logged: %s%s%s%s%s%s%s%s%s%s%s%s%s%s)\n",
 			(msr & 1 << 31) ? "bit31, " : "",
 			(msr & 1 << 30) ? "bit30, " : "",
 			(msr & 1 << 29) ? "Transitions, " : "",
@@ -2098,8 +2525,8 @@ int print_perf_limit(struct thread_data
 	}
 	if (do_gfx_perf_limit_reasons) {
 		get_msr(cpu, MSR_GFX_PERF_LIMIT_REASONS, &msr);
-		fprintf(stderr, "cpu%d: MSR_GFX_PERF_LIMIT_REASONS, 0x%08llx", cpu, msr);
-		fprintf(stderr, " (Active: %s%s%s%s%s%s%s%s)",
+		fprintf(outf, "cpu%d: MSR_GFX_PERF_LIMIT_REASONS, 0x%08llx", cpu, msr);
+		fprintf(outf, " (Active: %s%s%s%s%s%s%s%s)",
 			(msr & 1 << 0) ? "PROCHOT, " : "",
 			(msr & 1 << 1) ? "ThermStatus, " : "",
 			(msr & 1 << 4) ? "Graphics, " : "",
@@ -2108,7 +2535,7 @@ int print_perf_limit(struct thread_data
 			(msr & 1 << 9) ? "GFXPwr, " : "",
 			(msr & 1 << 10) ? "PkgPwrL1, " : "",
 			(msr & 1 << 11) ? "PkgPwrL2, " : "");
-		fprintf(stderr, " (Logged: %s%s%s%s%s%s%s%s)\n",
+		fprintf(outf, " (Logged: %s%s%s%s%s%s%s%s)\n",
 			(msr & 1 << 16) ? "PROCHOT, " : "",
 			(msr & 1 << 17) ? "ThermStatus, " : "",
 			(msr & 1 << 20) ? "Graphics, " : "",
@@ -2120,15 +2547,15 @@ int print_perf_limit(struct thread_data
 	}
 	if (do_ring_perf_limit_reasons) {
 		get_msr(cpu, MSR_RING_PERF_LIMIT_REASONS, &msr);
-		fprintf(stderr, "cpu%d: MSR_RING_PERF_LIMIT_REASONS, 0x%08llx", cpu, msr);
-		fprintf(stderr, " (Active: %s%s%s%s%s%s)",
+		fprintf(outf, "cpu%d: MSR_RING_PERF_LIMIT_REASONS, 0x%08llx", cpu, msr);
+		fprintf(outf, " (Active: %s%s%s%s%s%s)",
 			(msr & 1 << 0) ? "PROCHOT, " : "",
 			(msr & 1 << 1) ? "ThermStatus, " : "",
 			(msr & 1 << 6) ? "VR-Therm, " : "",
 			(msr & 1 << 8) ? "Amps, " : "",
 			(msr & 1 << 10) ? "PkgPwrL1, " : "",
 			(msr & 1 << 11) ? "PkgPwrL2, " : "");
-		fprintf(stderr, " (Logged: %s%s%s%s%s%s)\n",
+		fprintf(outf, " (Logged: %s%s%s%s%s%s)\n",
 			(msr & 1 << 16) ? "PROCHOT, " : "",
 			(msr & 1 << 17) ? "ThermStatus, " : "",
 			(msr & 1 << 22) ? "VR-Therm, " : "",
@@ -2142,7 +2569,7 @@ int print_perf_limit(struct thread_data
 #define	RAPL_POWER_GRANULARITY	0x7FFF	/* 15 bit power granularity */
 #define	RAPL_TIME_GRANULARITY	0x3F /* 6 bit time granularity */
 
-double get_tdp(model)
+double get_tdp(int model)
 {
 	unsigned long long msr;
 
@@ -2207,6 +2634,9 @@ void rapl_probe(unsigned int family, uns
 	case 0x47:	/* BDW */
 		do_rapl = RAPL_PKG | RAPL_CORES | RAPL_CORE_POLICY | RAPL_GFX | RAPL_PKG_POWER_INFO;
 		break;
+	case 0x5C:	/* BXT */
+		do_rapl = RAPL_PKG | RAPL_PKG_POWER_INFO;
+		break;
 	case 0x4E:	/* SKL */
 	case 0x5E:	/* SKL */
 		do_rapl = RAPL_PKG | RAPL_DRAM | RAPL_DRAM_PERF_STATUS | RAPL_PKG_PERF_STATUS | RAPL_PKG_POWER_INFO;
@@ -2214,6 +2644,7 @@ void rapl_probe(unsigned int family, uns
 	case 0x3F:	/* HSX */
 	case 0x4F:	/* BDX */
 	case 0x56:	/* BDX-DE */
+	case 0x55:	/* SKX */
 	case 0x57:	/* KNL */
 		do_rapl = RAPL_PKG | RAPL_DRAM | RAPL_DRAM_POWER_INFO | RAPL_DRAM_PERF_STATUS | RAPL_PKG_PERF_STATUS | RAPL_PKG_POWER_INFO;
 		break;
@@ -2251,12 +2682,12 @@ void rapl_probe(unsigned int family, uns
 
 	rapl_joule_counter_range = 0xFFFFFFFF * rapl_energy_units / tdp;
 	if (debug)
-		fprintf(stderr, "RAPL: %.0f sec. Joule Counter Range, at %.0f Watts\n", rapl_joule_counter_range, tdp);
+		fprintf(outf, "RAPL: %.0f sec. Joule Counter Range, at %.0f Watts\n", rapl_joule_counter_range, tdp);
 
 	return;
 }
 
-void perf_limit_reasons_probe(family, model)
+void perf_limit_reasons_probe(int family, int model)
 {
 	if (!genuine_intel)
 		return;
@@ -2293,7 +2724,7 @@ int print_thermal(struct thread_data *t,
 		return 0;
 
 	if (cpu_migrate(cpu)) {
-		fprintf(stderr, "Could not migrate to CPU %d\n", cpu);
+		fprintf(outf, "Could not migrate to CPU %d\n", cpu);
 		return -1;
 	}
 
@@ -2302,7 +2733,7 @@ int print_thermal(struct thread_data *t,
 			return 0;
 
 		dts = (msr >> 16) & 0x7F;
-		fprintf(stderr, "cpu%d: MSR_IA32_PACKAGE_THERM_STATUS: 0x%08llx (%d C)\n",
+		fprintf(outf, "cpu%d: MSR_IA32_PACKAGE_THERM_STATUS: 0x%08llx (%d C)\n",
 			cpu, msr, tcc_activation_temp - dts);
 
 #ifdef	THERM_DEBUG
@@ -2311,7 +2742,7 @@ int print_thermal(struct thread_data *t,
 
 		dts = (msr >> 16) & 0x7F;
 		dts2 = (msr >> 8) & 0x7F;
-		fprintf(stderr, "cpu%d: MSR_IA32_PACKAGE_THERM_INTERRUPT: 0x%08llx (%d C, %d C)\n",
+		fprintf(outf, "cpu%d: MSR_IA32_PACKAGE_THERM_INTERRUPT: 0x%08llx (%d C, %d C)\n",
 			cpu, msr, tcc_activation_temp - dts, tcc_activation_temp - dts2);
 #endif
 	}
@@ -2325,7 +2756,7 @@ int print_thermal(struct thread_data *t,
 
 		dts = (msr >> 16) & 0x7F;
 		resolution = (msr >> 27) & 0xF;
-		fprintf(stderr, "cpu%d: MSR_IA32_THERM_STATUS: 0x%08llx (%d C +/- %d)\n",
+		fprintf(outf, "cpu%d: MSR_IA32_THERM_STATUS: 0x%08llx (%d C +/- %d)\n",
 			cpu, msr, tcc_activation_temp - dts, resolution);
 
 #ifdef THERM_DEBUG
@@ -2334,17 +2765,17 @@ int print_thermal(struct thread_data *t,
 
 		dts = (msr >> 16) & 0x7F;
 		dts2 = (msr >> 8) & 0x7F;
-		fprintf(stderr, "cpu%d: MSR_IA32_THERM_INTERRUPT: 0x%08llx (%d C, %d C)\n",
+		fprintf(outf, "cpu%d: MSR_IA32_THERM_INTERRUPT: 0x%08llx (%d C, %d C)\n",
 			cpu, msr, tcc_activation_temp - dts, tcc_activation_temp - dts2);
 #endif
 	}
 
 	return 0;
 }
-	
+
 void print_power_limit_msr(int cpu, unsigned long long msr, char *label)
 {
-	fprintf(stderr, "cpu%d: %s: %sabled (%f Watts, %f sec, clamp %sabled)\n",
+	fprintf(outf, "cpu%d: %s: %sabled (%f Watts, %f sec, clamp %sabled)\n",
 		cpu, label,
 		((msr >> 15) & 1) ? "EN" : "DIS",
 		((msr >> 0) & 0x7FFF) * rapl_power_units,
@@ -2368,7 +2799,7 @@ int print_rapl(struct thread_data *t, st
 
 	cpu = t->cpu_id;
 	if (cpu_migrate(cpu)) {
-		fprintf(stderr, "Could not migrate to CPU %d\n", cpu);
+		fprintf(outf, "Could not migrate to CPU %d\n", cpu);
 		return -1;
 	}
 
@@ -2376,7 +2807,7 @@ int print_rapl(struct thread_data *t, st
 		return -1;
 
 	if (debug) {
-		fprintf(stderr, "cpu%d: MSR_RAPL_POWER_UNIT: 0x%08llx "
+		fprintf(outf, "cpu%d: MSR_RAPL_POWER_UNIT: 0x%08llx "
 			"(%f Watts, %f Joules, %f sec.)\n", cpu, msr,
 			rapl_power_units, rapl_energy_units, rapl_time_units);
 	}
@@ -2386,7 +2817,7 @@ int print_rapl(struct thread_data *t, st
                 	return -5;
 
 
-		fprintf(stderr, "cpu%d: MSR_PKG_POWER_INFO: 0x%08llx (%.0f W TDP, RAPL %.0f - %.0f W, %f sec.)\n",
+		fprintf(outf, "cpu%d: MSR_PKG_POWER_INFO: 0x%08llx (%.0f W TDP, RAPL %.0f - %.0f W, %f sec.)\n",
 			cpu, msr,
 			((msr >>  0) & RAPL_POWER_GRANULARITY) * rapl_power_units,
 			((msr >> 16) & RAPL_POWER_GRANULARITY) * rapl_power_units,
@@ -2399,11 +2830,11 @@ int print_rapl(struct thread_data *t, st
 		if (get_msr(cpu, MSR_PKG_POWER_LIMIT, &msr))
 			return -9;
 
-		fprintf(stderr, "cpu%d: MSR_PKG_POWER_LIMIT: 0x%08llx (%slocked)\n",
+		fprintf(outf, "cpu%d: MSR_PKG_POWER_LIMIT: 0x%08llx (%slocked)\n",
 			cpu, msr, (msr >> 63) & 1 ? "": "UN");
 
 		print_power_limit_msr(cpu, msr, "PKG Limit #1");
-		fprintf(stderr, "cpu%d: PKG Limit #2: %sabled (%f Watts, %f* sec, clamp %sabled)\n",
+		fprintf(outf, "cpu%d: PKG Limit #2: %sabled (%f Watts, %f* sec, clamp %sabled)\n",
 			cpu,
 			((msr >> 47) & 1) ? "EN" : "DIS",
 			((msr >> 32) & 0x7FFF) * rapl_power_units,
@@ -2415,7 +2846,7 @@ int print_rapl(struct thread_data *t, st
 		if (get_msr(cpu, MSR_DRAM_POWER_INFO, &msr))
                 	return -6;
 
-		fprintf(stderr, "cpu%d: MSR_DRAM_POWER_INFO,: 0x%08llx (%.0f W TDP, RAPL %.0f - %.0f W, %f sec.)\n",
+		fprintf(outf, "cpu%d: MSR_DRAM_POWER_INFO,: 0x%08llx (%.0f W TDP, RAPL %.0f - %.0f W, %f sec.)\n",
 			cpu, msr,
 			((msr >>  0) & RAPL_POWER_GRANULARITY) * rapl_power_units,
 			((msr >> 16) & RAPL_POWER_GRANULARITY) * rapl_power_units,
@@ -2425,7 +2856,7 @@ int print_rapl(struct thread_data *t, st
 	if (do_rapl & RAPL_DRAM) {
 		if (get_msr(cpu, MSR_DRAM_POWER_LIMIT, &msr))
 			return -9;
-		fprintf(stderr, "cpu%d: MSR_DRAM_POWER_LIMIT: 0x%08llx (%slocked)\n",
+		fprintf(outf, "cpu%d: MSR_DRAM_POWER_LIMIT: 0x%08llx (%slocked)\n",
 				cpu, msr, (msr >> 31) & 1 ? "": "UN");
 
 		print_power_limit_msr(cpu, msr, "DRAM Limit");
@@ -2435,7 +2866,7 @@ int print_rapl(struct thread_data *t, st
 			if (get_msr(cpu, MSR_PP0_POLICY, &msr))
 				return -7;
 
-			fprintf(stderr, "cpu%d: MSR_PP0_POLICY: %lld\n", cpu, msr & 0xF);
+			fprintf(outf, "cpu%d: MSR_PP0_POLICY: %lld\n", cpu, msr & 0xF);
 		}
 	}
 	if (do_rapl & RAPL_CORES) {
@@ -2443,7 +2874,7 @@ int print_rapl(struct thread_data *t, st
 
 			if (get_msr(cpu, MSR_PP0_POWER_LIMIT, &msr))
 				return -9;
-			fprintf(stderr, "cpu%d: MSR_PP0_POWER_LIMIT: 0x%08llx (%slocked)\n",
+			fprintf(outf, "cpu%d: MSR_PP0_POWER_LIMIT: 0x%08llx (%slocked)\n",
 					cpu, msr, (msr >> 31) & 1 ? "": "UN");
 			print_power_limit_msr(cpu, msr, "Cores Limit");
 		}
@@ -2453,11 +2884,11 @@ int print_rapl(struct thread_data *t, st
 			if (get_msr(cpu, MSR_PP1_POLICY, &msr))
 				return -8;
 
-			fprintf(stderr, "cpu%d: MSR_PP1_POLICY: %lld\n", cpu, msr & 0xF);
+			fprintf(outf, "cpu%d: MSR_PP1_POLICY: %lld\n", cpu, msr & 0xF);
 
 			if (get_msr(cpu, MSR_PP1_POWER_LIMIT, &msr))
 				return -9;
-			fprintf(stderr, "cpu%d: MSR_PP1_POWER_LIMIT: 0x%08llx (%slocked)\n",
+			fprintf(outf, "cpu%d: MSR_PP1_POWER_LIMIT: 0x%08llx (%slocked)\n",
 					cpu, msr, (msr >> 31) & 1 ? "": "UN");
 			print_power_limit_msr(cpu, msr, "GFX Limit");
 		}
@@ -2493,6 +2924,8 @@ int has_snb_msrs(unsigned int family, un
 	case 0x56:	/* BDX-DE */
 	case 0x4E:	/* SKL */
 	case 0x5E:	/* SKL */
+	case 0x55:	/* SKX */
+	case 0x5C:	/* BXT */
 		return 1;
 	}
 	return 0;
@@ -2501,9 +2934,14 @@ int has_snb_msrs(unsigned int family, un
 /*
  * HSW adds support for additional MSRs:
  *
- * MSR_PKG_C8_RESIDENCY            0x00000630
- * MSR_PKG_C9_RESIDENCY            0x00000631
- * MSR_PKG_C10_RESIDENCY           0x00000632
+ * MSR_PKG_C8_RESIDENCY		0x00000630
+ * MSR_PKG_C9_RESIDENCY		0x00000631
+ * MSR_PKG_C10_RESIDENCY	0x00000632
+ *
+ * MSR_PKGC8_IRTL		0x00000633
+ * MSR_PKGC9_IRTL		0x00000634
+ * MSR_PKGC10_IRTL		0x00000635
+ *
  */
 int has_hsw_msrs(unsigned int family, unsigned int model)
 {
@@ -2515,6 +2953,7 @@ int has_hsw_msrs(unsigned int family, un
 	case 0x3D:	/* BDW */
 	case 0x4E:	/* SKL */
 	case 0x5E:	/* SKL */
+	case 0x5C:	/* BXT */
 		return 1;
 	}
 	return 0;
@@ -2583,23 +3022,23 @@ double slm_bclk(void)
 	double freq;
 
 	if (get_msr(base_cpu, MSR_FSB_FREQ, &msr))
-		fprintf(stderr, "SLM BCLK: unknown\n");
+		fprintf(outf, "SLM BCLK: unknown\n");
 
 	i = msr & 0xf;
 	if (i >= SLM_BCLK_FREQS) {
-		fprintf(stderr, "SLM BCLK[%d] invalid\n", i);
+		fprintf(outf, "SLM BCLK[%d] invalid\n", i);
 		msr = 3;
 	}
 	freq = slm_freq_table[i];
 
-	fprintf(stderr, "SLM BCLK: %.1f Mhz\n", freq);
+	fprintf(outf, "SLM BCLK: %.1f Mhz\n", freq);
 
 	return freq;
 }
 
 double discover_bclk(unsigned int family, unsigned int model)
 {
-	if (has_snb_msrs(family, model))
+	if (has_snb_msrs(family, model) || is_knl(family, model))
 		return 100.00;
 	else if (is_slm(family, model))
 		return slm_bclk();
@@ -2635,13 +3074,13 @@ int set_temperature_target(struct thread
 
 	cpu = t->cpu_id;
 	if (cpu_migrate(cpu)) {
-		fprintf(stderr, "Could not migrate to CPU %d\n", cpu);
+		fprintf(outf, "Could not migrate to CPU %d\n", cpu);
 		return -1;
 	}
 
 	if (tcc_activation_temp_override != 0) {
 		tcc_activation_temp = tcc_activation_temp_override;
-		fprintf(stderr, "cpu%d: Using cmdline TCC Target (%d C)\n",
+		fprintf(outf, "cpu%d: Using cmdline TCC Target (%d C)\n",
 			cpu, tcc_activation_temp);
 		return 0;
 	}
@@ -2656,7 +3095,7 @@ int set_temperature_target(struct thread
 	target_c_local = (msr >> 16) & 0xFF;
 
 	if (debug)
-		fprintf(stderr, "cpu%d: MSR_IA32_TEMPERATURE_TARGET: 0x%08llx (%d C)\n",
+		fprintf(outf, "cpu%d: MSR_IA32_TEMPERATURE_TARGET: 0x%08llx (%d C)\n",
 			cpu, msr, target_c_local);
 
 	if (!target_c_local)
@@ -2668,37 +3107,93 @@ int set_temperature_target(struct thread
 
 guess:
 	tcc_activation_temp = TJMAX_DEFAULT;
-	fprintf(stderr, "cpu%d: Guessing tjMax %d C, Please use -T to specify\n",
+	fprintf(outf, "cpu%d: Guessing tjMax %d C, Please use -T to specify\n",
 		cpu, tcc_activation_temp);
 
 	return 0;
 }
+
+void decode_feature_control_msr(void)
+{
+	unsigned long long msr;
+
+	if (!get_msr(base_cpu, MSR_IA32_FEATURE_CONTROL, &msr))
+		fprintf(outf, "cpu%d: MSR_IA32_FEATURE_CONTROL: 0x%08llx (%sLocked %s)\n",
+			base_cpu, msr,
+			msr & FEATURE_CONTROL_LOCKED ? "" : "UN-",
+			msr & (1 << 18) ? "SGX" : "");
+}
+
+void decode_misc_enable_msr(void)
+{
+	unsigned long long msr;
+
+	if (!get_msr(base_cpu, MSR_IA32_MISC_ENABLE, &msr))
+		fprintf(outf, "cpu%d: MSR_IA32_MISC_ENABLE: 0x%08llx (%s %s %s)\n",
+			base_cpu, msr,
+			msr & (1 << 3) ? "TCC" : "",
+			msr & (1 << 16) ? "EIST" : "",
+			msr & (1 << 18) ? "MONITOR" : "");
+}
+
+/*
+ * Decode MSR_MISC_PWR_MGMT
+ *
+ * Decode the bits according to the Nehalem documentation
+ * bit[0] seems to continue to have same meaning going forward
+ * bit[1] less so...
+ */
+void decode_misc_pwr_mgmt_msr(void)
+{
+	unsigned long long msr;
+
+	if (!do_nhm_platform_info)
+		return;
+
+	if (!get_msr(base_cpu, MSR_MISC_PWR_MGMT, &msr))
+		fprintf(outf, "cpu%d: MSR_MISC_PWR_MGMT: 0x%08llx (%sable-EIST_Coordination %sable-EPB)\n",
+			base_cpu, msr,
+			msr & (1 << 0) ? "DIS" : "EN",
+			msr & (1 << 1) ? "EN" : "DIS");
+}
+
 void process_cpuid()
 {
-	unsigned int eax, ebx, ecx, edx, max_level;
+	unsigned int eax, ebx, ecx, edx, max_level, max_extended_level;
 	unsigned int fms, family, model, stepping;
 
 	eax = ebx = ecx = edx = 0;
 
-	__get_cpuid(0, &max_level, &ebx, &ecx, &edx);
+	__cpuid(0, max_level, ebx, ecx, edx);
 
 	if (ebx == 0x756e6547 && edx == 0x49656e69 && ecx == 0x6c65746e)
 		genuine_intel = 1;
 
 	if (debug)
-		fprintf(stderr, "CPUID(0): %.4s%.4s%.4s ",
+		fprintf(outf, "CPUID(0): %.4s%.4s%.4s ",
 			(char *)&ebx, (char *)&edx, (char *)&ecx);
 
-	__get_cpuid(1, &fms, &ebx, &ecx, &edx);
+	__cpuid(1, fms, ebx, ecx, edx);
 	family = (fms >> 8) & 0xf;
 	model = (fms >> 4) & 0xf;
 	stepping = fms & 0xf;
 	if (family == 6 || family == 0xf)
 		model += ((fms >> 16) & 0xf) << 4;
 
-	if (debug)
-		fprintf(stderr, "%d CPUID levels; family:model:stepping 0x%x:%x:%x (%d:%d:%d)\n",
+	if (debug) {
+		fprintf(outf, "%d CPUID levels; family:model:stepping 0x%x:%x:%x (%d:%d:%d)\n",
 			max_level, family, model, stepping, family, model, stepping);
+		fprintf(outf, "CPUID(1): %s %s %s %s %s %s %s %s %s\n",
+			ecx & (1 << 0) ? "SSE3" : "-",
+			ecx & (1 << 3) ? "MONITOR" : "-",
+			ecx & (1 << 6) ? "SMX" : "-",
+			ecx & (1 << 7) ? "EIST" : "-",
+			ecx & (1 << 8) ? "TM2" : "-",
+			edx & (1 << 4) ? "TSC" : "-",
+			edx & (1 << 5) ? "MSR" : "-",
+			edx & (1 << 22) ? "ACPI-TM" : "-",
+			edx & (1 << 29) ? "TM" : "-");
+	}
 
 	if (!(edx & (1 << 5)))
 		errx(1, "CPUID: no MSR");
@@ -2709,15 +3204,15 @@ void process_cpuid()
 	 * This check is valid for both Intel and AMD.
 	 */
 	ebx = ecx = edx = 0;
-	__get_cpuid(0x80000000, &max_level, &ebx, &ecx, &edx);
+	__cpuid(0x80000000, max_extended_level, ebx, ecx, edx);
 
-	if (max_level >= 0x80000007) {
+	if (max_extended_level >= 0x80000007) {
 
 		/*
 		 * Non-Stop TSC is advertised by CPUID.EAX=0x80000007: EDX.bit8
 		 * this check is valid for both Intel and AMD
 		 */
-		__get_cpuid(0x80000007, &eax, &ebx, &ecx, &edx);
+		__cpuid(0x80000007, eax, ebx, ecx, edx);
 		has_invariant_tsc = edx & (1 << 8);
 	}
 
@@ -2726,20 +3221,48 @@ void process_cpuid()
 	 * this check is valid for both Intel and AMD
 	 */
 
-	__get_cpuid(0x6, &eax, &ebx, &ecx, &edx);
+	__cpuid(0x6, eax, ebx, ecx, edx);
 	has_aperf = ecx & (1 << 0);
 	do_dts = eax & (1 << 0);
 	do_ptm = eax & (1 << 6);
+	has_hwp = eax & (1 << 7);
+	has_hwp_notify = eax & (1 << 8);
+	has_hwp_activity_window = eax & (1 << 9);
+	has_hwp_epp = eax & (1 << 10);
+	has_hwp_pkg = eax & (1 << 11);
 	has_epb = ecx & (1 << 3);
 
 	if (debug)
-		fprintf(stderr, "CPUID(6): %sAPERF, %sDTS, %sPTM, %sEPB\n",
-			has_aperf ? "" : "No ",
-			do_dts ? "" : "No ",
-			do_ptm ? "" : "No ",
-			has_epb ? "" : "No ");
+		fprintf(outf, "CPUID(6): %sAPERF, %sDTS, %sPTM, %sHWP, "
+			"%sHWPnotify, %sHWPwindow, %sHWPepp, %sHWPpkg, %sEPB\n",
+			has_aperf ? "" : "No-",
+			do_dts ? "" : "No-",
+			do_ptm ? "" : "No-",
+			has_hwp ? "" : "No-",
+			has_hwp_notify ? "" : "No-",
+			has_hwp_activity_window ? "" : "No-",
+			has_hwp_epp ? "" : "No-",
+			has_hwp_pkg ? "" : "No-",
+			has_epb ? "" : "No-");
 
-	if (max_level > 0x15) {
+	if (debug)
+		decode_misc_enable_msr();
+
+	if (max_level >= 0x7 && debug) {
+		int has_sgx;
+
+		ecx = 0;
+
+		__cpuid_count(0x7, 0, eax, ebx, ecx, edx);
+
+		has_sgx = ebx & (1 << 2);
+		fprintf(outf, "CPUID(7): %sSGX\n", has_sgx ? "" : "No-");
+
+		if (has_sgx)
+			decode_feature_control_msr();
+	}
+
+	if (max_level >= 0x15) {
 		unsigned int eax_crystal;
 		unsigned int ebx_tsc;
 
@@ -2747,19 +3270,25 @@ void process_cpuid()
 		 * CPUID 15H TSC/Crystal ratio, possibly Crystal Hz
 		 */
 		eax_crystal = ebx_tsc = crystal_hz = edx = 0;
-		__get_cpuid(0x15, &eax_crystal, &ebx_tsc, &crystal_hz, &edx);
+		__cpuid(0x15, eax_crystal, ebx_tsc, crystal_hz, edx);
 
 		if (ebx_tsc != 0) {
 
 			if (debug && (ebx != 0))
-				fprintf(stderr, "CPUID(0x15): eax_crystal: %d ebx_tsc: %d ecx_crystal_hz: %d\n",
+				fprintf(outf, "CPUID(0x15): eax_crystal: %d ebx_tsc: %d ecx_crystal_hz: %d\n",
 					eax_crystal, ebx_tsc, crystal_hz);
 
 			if (crystal_hz == 0)
 				switch(model) {
 				case 0x4E:	/* SKL */
 				case 0x5E:	/* SKL */
-					crystal_hz = 24000000;	/* 24 MHz */
+					crystal_hz = 24000000;	/* 24.0 MHz */
+					break;
+				case 0x55:	/* SKX */
+					crystal_hz = 25000000;	/* 25.0 MHz */
+					break;
+				case 0x5C:	/* BXT */
+					crystal_hz = 19200000;	/* 19.2 MHz */
 					break;
 				default:
 					crystal_hz = 0;
@@ -2768,41 +3297,63 @@ void process_cpuid()
 			if (crystal_hz) {
 				tsc_hz =  (unsigned long long) crystal_hz * ebx_tsc / eax_crystal;
 				if (debug)
-					fprintf(stderr, "TSC: %lld MHz (%d Hz * %d / %d / 1000000)\n",
+					fprintf(outf, "TSC: %lld MHz (%d Hz * %d / %d / 1000000)\n",
 						tsc_hz / 1000000, crystal_hz, ebx_tsc,  eax_crystal);
 			}
 		}
 	}
+	if (max_level >= 0x16) {
+		unsigned int base_mhz, max_mhz, bus_mhz, edx;
+
+		/*
+		 * CPUID 16H Base MHz, Max MHz, Bus MHz
+		 */
+		base_mhz = max_mhz = bus_mhz = edx = 0;
+
+		__cpuid(0x16, base_mhz, max_mhz, bus_mhz, edx);
+		if (debug)
+			fprintf(outf, "CPUID(0x16): base_mhz: %d max_mhz: %d bus_mhz: %d\n",
+				base_mhz, max_mhz, bus_mhz);
+	}
 
 	if (has_aperf)
 		aperf_mperf_multiplier = get_aperf_mperf_multiplier(family, model);
 
 	do_nhm_platform_info = do_nhm_cstates = do_smi = probe_nhm_msrs(family, model);
 	do_snb_cstates = has_snb_msrs(family, model);
+	do_irtl_snb = has_snb_msrs(family, model);
 	do_pc2 = do_snb_cstates && (pkg_cstate_limit >= PCL__2);
 	do_pc3 = (pkg_cstate_limit >= PCL__3);
 	do_pc6 = (pkg_cstate_limit >= PCL__6);
 	do_pc7 = do_snb_cstates && (pkg_cstate_limit >= PCL__7);
 	do_c8_c9_c10 = has_hsw_msrs(family, model);
+	do_irtl_hsw = has_hsw_msrs(family, model);
 	do_skl_residency = has_skl_msrs(family, model);
 	do_slm_cstates = is_slm(family, model);
 	do_knl_cstates  = is_knl(family, model);
 
+	if (debug)
+		decode_misc_pwr_mgmt_msr();
+
 	rapl_probe(family, model);
 	perf_limit_reasons_probe(family, model);
 
 	if (debug)
-		dump_cstate_pstate_config_info();
+		dump_cstate_pstate_config_info(family, model);
 
 	if (has_skl_msrs(family, model))
 		calculate_tsc_tweak();
 
+	do_gfx_rc6_ms = !access("/sys/class/drm/card0/power/rc6_residency_ms", R_OK);
+
+	do_gfx_mhz = !access("/sys/class/graphics/fb0/device/drm/card0/gt_cur_freq_mhz", R_OK);
+
 	return;
 }
 
 void help()
 {
-	fprintf(stderr,
+	fprintf(outf,
 	"Usage: turbostat [OPTIONS][(--interval seconds) | COMMAND ...]\n"
 	"\n"
 	"Turbostat forks the specified COMMAND and prints statistics\n"
@@ -2814,6 +3365,7 @@ void help()
 	"--help		print this help message\n"
 	"--counter msr	print 32-bit counter at address \"msr\"\n"
 	"--Counter msr	print 64-bit Counter at address \"msr\"\n"
+	"--out file	create or truncate \"file\" for all output\n"
 	"--msr msr	print 32-bit value at address \"msr\"\n"
 	"--MSR msr	print 64-bit Value at address \"msr\"\n"
 	"--version	print version information\n"
@@ -2858,7 +3410,7 @@ void topology_probe()
 		show_cpu = 1;
 
 	if (debug > 1)
-		fprintf(stderr, "num_cpus %d max_cpu_num %d\n", topo.num_cpus, topo.max_cpu_num);
+		fprintf(outf, "num_cpus %d max_cpu_num %d\n", topo.num_cpus, topo.max_cpu_num);
 
 	cpus = calloc(1, (topo.max_cpu_num  + 1) * sizeof(struct cpu_topology));
 	if (cpus == NULL)
@@ -2893,7 +3445,7 @@ void topology_probe()
 
 		if (cpu_is_not_present(i)) {
 			if (debug > 1)
-				fprintf(stderr, "cpu%d NOT PRESENT\n", i);
+				fprintf(outf, "cpu%d NOT PRESENT\n", i);
 			continue;
 		}
 		cpus[i].core_id = get_core_id(i);
@@ -2908,26 +3460,26 @@ void topology_probe()
 		if (siblings > max_siblings)
 			max_siblings = siblings;
 		if (debug > 1)
-			fprintf(stderr, "cpu %d pkg %d core %d\n",
+			fprintf(outf, "cpu %d pkg %d core %d\n",
 				i, cpus[i].physical_package_id, cpus[i].core_id);
 	}
 	topo.num_cores_per_pkg = max_core_id + 1;
 	if (debug > 1)
-		fprintf(stderr, "max_core_id %d, sizing for %d cores per package\n",
+		fprintf(outf, "max_core_id %d, sizing for %d cores per package\n",
 			max_core_id, topo.num_cores_per_pkg);
 	if (debug && !summary_only && topo.num_cores_per_pkg > 1)
 		show_core = 1;
 
 	topo.num_packages = max_package_id + 1;
 	if (debug > 1)
-		fprintf(stderr, "max_package_id %d, sizing for %d packages\n",
+		fprintf(outf, "max_package_id %d, sizing for %d packages\n",
 			max_package_id, topo.num_packages);
 	if (debug && !summary_only && topo.num_packages > 1)
 		show_pkg = 1;
 
 	topo.num_threads_per_core = max_siblings;
 	if (debug > 1)
-		fprintf(stderr, "max_siblings %d\n", max_siblings);
+		fprintf(outf, "max_siblings %d\n", max_siblings);
 
 	free(cpus);
 }
@@ -3019,10 +3571,27 @@ void allocate_output_buffer()
 	if (outp == NULL)
 		err(-1, "calloc output buffer");
 }
+void allocate_fd_percpu(void)
+{
+	fd_percpu = calloc(topo.max_cpu_num, sizeof(int));
+	if (fd_percpu == NULL)
+		err(-1, "calloc fd_percpu");
+}
+void allocate_irq_buffers(void)
+{
+	irq_column_2_cpu = calloc(topo.num_cpus, sizeof(int));
+	if (irq_column_2_cpu == NULL)
+		err(-1, "calloc %d", topo.num_cpus);
 
+	irqs_per_cpu = calloc(topo.max_cpu_num, sizeof(int));
+	if (irqs_per_cpu == NULL)
+		err(-1, "calloc %d", topo.max_cpu_num);
+}
 void setup_all_buffers(void)
 {
 	topology_probe();
+	allocate_irq_buffers();
+	allocate_fd_percpu();
 	allocate_counters(&thread_even, &core_even, &package_even);
 	allocate_counters(&thread_odd, &core_odd, &package_odd);
 	allocate_output_buffer();
@@ -3036,7 +3605,7 @@ void set_base_cpu(void)
 		err(-ENODEV, "No valid cpus found");
 
 	if (debug > 1)
-		fprintf(stderr, "base_cpu = %d\n", base_cpu);
+		fprintf(outf, "base_cpu = %d\n", base_cpu);
 }
 
 void turbostat_init()
@@ -3049,6 +3618,9 @@ void turbostat_init()
 
 
 	if (debug)
+		for_all_cpus(print_hwp, ODD_COUNTERS);
+
+	if (debug)
 		for_all_cpus(print_epb, ODD_COUNTERS);
 
 	if (debug)
@@ -3061,6 +3633,9 @@ void turbostat_init()
 
 	if (debug)
 		for_all_cpus(print_thermal, ODD_COUNTERS);
+
+	if (debug && do_irtl_snb)
+		print_irtl();
 }
 
 int fork_it(char **argv)
@@ -3100,9 +3675,10 @@ int fork_it(char **argv)
 	for_all_cpus_2(delta_cpu, ODD_COUNTERS, EVEN_COUNTERS);
 	compute_average(EVEN_COUNTERS);
 	format_all_counters(EVEN_COUNTERS);
-	flush_stderr();
 
-	fprintf(stderr, "%.6f sec\n", tv_delta.tv_sec + tv_delta.tv_usec/1000000.0);
+	fprintf(outf, "%.6f sec\n", tv_delta.tv_sec + tv_delta.tv_usec/1000000.0);
+
+	flush_output_stderr();
 
 	return status;
 }
@@ -3119,13 +3695,13 @@ int get_and_dump_counters(void)
 	if (status)
 		return status;
 
-	flush_stdout();
+	flush_output_stdout();
 
 	return status;
 }
 
 void print_version() {
-	fprintf(stderr, "turbostat version 4.8 26-Sep, 2015"
+	fprintf(outf, "turbostat version 4.12 5 Apr 2016"
 		" - Len Brown <lenb@kernel.org>\n");
 }
 
@@ -3143,6 +3719,7 @@ void cmdline(int argc, char **argv)
 		{"Joules",	no_argument,		0, 'J'},
 		{"MSR",		required_argument,	0, 'M'},
 		{"msr",		required_argument,	0, 'm'},
+		{"out",		required_argument,	0, 'o'},
 		{"Package",	no_argument,		0, 'p'},
 		{"processor",	no_argument,		0, 'p'},
 		{"Summary",	no_argument,		0, 'S'},
@@ -3153,7 +3730,7 @@ void cmdline(int argc, char **argv)
 
 	progname = argv[0];
 
-	while ((opt = getopt_long_only(argc, argv, "+C:c:Ddhi:JM:m:PpST:v",
+	while ((opt = getopt_long_only(argc, argv, "+C:c:Ddhi:JM:m:o:PpST:v",
 				long_options, &option_index)) != -1) {
 		switch (opt) {
 		case 'C':
@@ -3173,7 +3750,18 @@ void cmdline(int argc, char **argv)
 			help();
 			exit(1);
 		case 'i':
-			interval_sec = atoi(optarg);
+			{
+				double interval = strtod(optarg, NULL);
+
+				if (interval < 0.001) {
+					fprintf(outf, "interval %f seconds is too small\n",
+						interval);
+					exit(2);
+				}
+
+				interval_ts.tv_sec = interval;
+				interval_ts.tv_nsec = (interval - interval_ts.tv_sec) * 1000000000;
+			}
 			break;
 		case 'J':
 			rapl_joules++;
@@ -3184,6 +3772,9 @@ void cmdline(int argc, char **argv)
 		case 'm':
 			sscanf(optarg, "%x", &extra_msr_offset32);
 			break;
+		case 'o':
+			outf = fopen_or_die(optarg, "w");
+			break;
 		case 'P':
 			show_pkg_only++;
 			break;
@@ -3206,6 +3797,8 @@ void cmdline(int argc, char **argv)
 
 int main(int argc, char **argv)
 {
+	outf = stderr;
+
 	cmdline(argc, argv);
 
 	if (debug)
--- zfcpdump-kernel-4.4.orig/tools/testing/nvdimm/test/nfit.c
+++ zfcpdump-kernel-4.4/tools/testing/nvdimm/test/nfit.c
@@ -13,6 +13,7 @@
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 #include <linux/platform_device.h>
 #include <linux/dma-mapping.h>
+#include <linux/workqueue.h>
 #include <linux/libnvdimm.h>
 #include <linux/vmalloc.h>
 #include <linux/device.h>
@@ -1246,6 +1247,7 @@ static int nfit_test_probe(struct platfo
 	if (nfit_test->setup != nfit_test0_setup)
 		return 0;
 
+	flush_work(&acpi_desc->work);
 	nfit_test->setup_hotplug = 1;
 	nfit_test->setup(nfit_test);
 
--- zfcpdump-kernel-4.4.orig/tools/testing/selftests/efivarfs/efivarfs.sh
+++ zfcpdump-kernel-4.4/tools/testing/selftests/efivarfs/efivarfs.sh
@@ -88,7 +88,11 @@ test_delete()
 		exit 1
 	fi
 
-	rm $file
+	rm $file 2>/dev/null
+	if [ $? -ne 0 ]; then
+		chattr -i $file
+		rm $file
+	fi
 
 	if [ -e $file ]; then
 		echo "$file couldn't be deleted" >&2
@@ -111,6 +115,7 @@ test_zero_size_delete()
 		exit 1
 	fi
 
+	chattr -i $file
 	printf "$attrs" > $file
 
 	if [ -e $file ]; then
@@ -141,7 +146,11 @@ test_valid_filenames()
 			echo "$file could not be created" >&2
 			ret=1
 		else
-			rm $file
+			rm $file 2>/dev/null
+			if [ $? -ne 0 ]; then
+				chattr -i $file
+				rm $file
+			fi
 		fi
 	done
 
@@ -174,7 +183,11 @@ test_invalid_filenames()
 
 		if [ -e $file ]; then
 			echo "Creating $file should have failed" >&2
-			rm $file
+			rm $file 2>/dev/null
+			if [ $? -ne 0 ]; then
+				chattr -i $file
+				rm $file
+			fi
 			ret=1
 		fi
 	done
--- zfcpdump-kernel-4.4.orig/tools/testing/selftests/efivarfs/open-unlink.c
+++ zfcpdump-kernel-4.4/tools/testing/selftests/efivarfs/open-unlink.c
@@ -1,10 +1,68 @@
+#include <errno.h>
 #include <stdio.h>
 #include <stdint.h>
 #include <stdlib.h>
 #include <unistd.h>
+#include <sys/ioctl.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <fcntl.h>
+#include <linux/fs.h>
+
+static int set_immutable(const char *path, int immutable)
+{
+	unsigned int flags;
+	int fd;
+	int rc;
+	int error;
+
+	fd = open(path, O_RDONLY);
+	if (fd < 0)
+		return fd;
+
+	rc = ioctl(fd, FS_IOC_GETFLAGS, &flags);
+	if (rc < 0) {
+		error = errno;
+		close(fd);
+		errno = error;
+		return rc;
+	}
+
+	if (immutable)
+		flags |= FS_IMMUTABLE_FL;
+	else
+		flags &= ~FS_IMMUTABLE_FL;
+
+	rc = ioctl(fd, FS_IOC_SETFLAGS, &flags);
+	error = errno;
+	close(fd);
+	errno = error;
+	return rc;
+}
+
+static int get_immutable(const char *path)
+{
+	unsigned int flags;
+	int fd;
+	int rc;
+	int error;
+
+	fd = open(path, O_RDONLY);
+	if (fd < 0)
+		return fd;
+
+	rc = ioctl(fd, FS_IOC_GETFLAGS, &flags);
+	if (rc < 0) {
+		error = errno;
+		close(fd);
+		errno = error;
+		return rc;
+	}
+	close(fd);
+	if (flags & FS_IMMUTABLE_FL)
+		return 1;
+	return 0;
+}
 
 int main(int argc, char **argv)
 {
@@ -27,7 +85,7 @@ int main(int argc, char **argv)
 	buf[4] = 0;
 
 	/* create a test variable */
-	fd = open(path, O_WRONLY | O_CREAT);
+	fd = open(path, O_WRONLY | O_CREAT, 0600);
 	if (fd < 0) {
 		perror("open(O_WRONLY)");
 		return EXIT_FAILURE;
@@ -41,6 +99,18 @@ int main(int argc, char **argv)
 
 	close(fd);
 
+	rc = get_immutable(path);
+	if (rc < 0) {
+		perror("ioctl(FS_IOC_GETFLAGS)");
+		return EXIT_FAILURE;
+	} else if (rc) {
+		rc = set_immutable(path, 0);
+		if (rc < 0) {
+			perror("ioctl(FS_IOC_SETFLAGS)");
+			return EXIT_FAILURE;
+		}
+	}
+
 	fd = open(path, O_RDONLY);
 	if (fd < 0) {
 		perror("open");
--- zfcpdump-kernel-4.4.orig/tools/vm/slabinfo.c
+++ zfcpdump-kernel-4.4/tools/vm/slabinfo.c
@@ -510,10 +510,11 @@ static void slab_stats(struct slabinfo *
 			s->alloc_node_mismatch, (s->alloc_node_mismatch * 100) / total);
 	}
 
-	if (s->cmpxchg_double_fail || s->cmpxchg_double_cpu_fail)
+	if (s->cmpxchg_double_fail || s->cmpxchg_double_cpu_fail) {
 		printf("\nCmpxchg_double Looping\n------------------------\n");
 		printf("Locked Cmpxchg Double redos   %lu\nUnlocked Cmpxchg Double redos %lu\n",
 			s->cmpxchg_double_fail, s->cmpxchg_double_cpu_fail);
+	}
 }
 
 static void report(struct slabinfo *s)
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/Kconfig
@@ -0,0 +1,29 @@
+menu "Ubuntu Supplied Third-Party Device Drivers"
+
+#
+# NOTE: to allow drivers to be added and removed without causing merge
+# collisions you should add new entries in the middle of the six lines
+# of ## at the bottom of the list.  Always add three lines of ## above
+# your new entry and maintain the six lines below.
+#
+
+##
+##
+##
+source "ubuntu/dm-raid4-5/Kconfig"
+##
+##
+##
+source "ubuntu/i915/Kconfig"
+##
+##
+##
+source "ubuntu/hio/Kconfig"
+##
+##
+##
+##
+##
+##
+
+endmenu
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/Makefile
@@ -0,0 +1,41 @@
+#
+# Makefile for the Linux kernel ubuntu supplied third-party device drivers.
+#
+
+#
+# NOTE: to allow drivers to be added and removed without causing merge
+# collisions you should add new entries in the middle of the six lines
+# of ## at the bottom of the list.  Always add three lines of ## above
+# your new entry and maintain the six lines below.
+#
+
+##
+##
+##
+obj-$(CONFIG_DM_RAID45)		+= dm-raid4-5/
+##
+##
+##
+ifneq ($(filter $(ARCH), i386 x86_64),)
+obj-y                         += vbox/
+endif
+##
+##
+##
+obj-$(CONFIG_DRM_I915_BPO)	+= i915/
+##
+##
+##
+##
+##
+##
+obj-$(CONFIG_HIO)             += hio/
+##
+##
+##
+##
+##
+##
+
+# This is a stupid trick to get kbuild to create ubuntu/built-in.o
+obj- += foo.o
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/dm-raid4-5/BOM
@@ -0,0 +1,3 @@
+Downloaded from:	http://people.redhat.com/~heinzm/sw/dm/dm-raid45/
+Current Version:	2009.04.24 (2.6.30-rc3)
+Comments:		All of the patches to dmraid1/dm-log, etc are upstream.
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/dm-raid4-5/Kconfig
@@ -0,0 +1,6 @@
+config DM_RAID45
+	tristate "RAID 4/5 target (EXPERIMENTAL)"
+	depends on BLK_DEV_DM && XOR_BLOCKS && EXPERIMENTAL
+	default m
+	---help---
+	A target that supports RAID4 and RAID5 mappings.
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/dm-raid4-5/Makefile
@@ -0,0 +1,4 @@
+EXTRA_CFLAGS += -I$(srctree)/drivers/md
+
+obj-$(CONFIG_DM_RAID45) := dm-raid45.o
+dm-raid45-objs := dm-raid4-5.o dm-memcache.o dm-region-hash.o dm-message.o
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/dm-raid4-5/dm-memcache.c
@@ -0,0 +1,303 @@
+/*
+ * Copyright (C) 2006-2008 Red Hat, Inc. All rights reserved.
+ *
+ * Module Author: Heinz Mauelshagen <heinzm@redhat.com>
+ *
+ * Device-mapper memory object handling:
+ *
+ * o allocate/free total_pages in a per client page pool.
+ *
+ * o allocate/free memory objects with chunks (1..n) of
+ *   pages_per_chunk pages hanging off.
+ *
+ * This file is released under the GPL.
+ */
+
+#define	DM_MEM_CACHE_VERSION	"0.2"
+
+#include "dm.h"
+#include "dm-memcache.h"
+#include <linux/dm-io.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+
+struct dm_mem_cache_client {
+	spinlock_t lock;
+	mempool_t *objs_pool;
+	struct page_list *free_list;
+	unsigned objects;
+	unsigned chunks;
+	unsigned pages_per_chunk;
+	unsigned free_pages;
+	unsigned total_pages;
+};
+
+/*
+ * Free pages and page_list elements of client.
+ */
+static void free_cache_pages(struct page_list *list)
+{
+	while (list) {
+		struct page_list *pl = list;
+
+		list = pl->next;
+		BUG_ON(!pl->page);
+		__free_page(pl->page);
+		kfree(pl);
+	}
+}
+
+/*
+ * Alloc number of pages and page_list elements as required by client.
+ */
+static struct page_list *alloc_cache_pages(unsigned pages)
+{
+	struct page_list *pl, *ret = NULL;
+	struct page *page;
+
+	while (pages--) {
+		page = alloc_page(GFP_NOIO);
+		if (!page)
+			goto err;
+
+		pl = kmalloc(sizeof(*pl), GFP_NOIO);
+		if (!pl) {
+			__free_page(page);
+			goto err;
+		}
+
+		pl->page = page;
+		pl->next = ret;
+		ret = pl;
+	}
+
+	return ret;
+
+err:
+	free_cache_pages(ret);
+	return NULL;
+}
+
+/*
+ * Allocate page_list elements from the pool to chunks of the memory object.
+ */
+static void alloc_chunks(struct dm_mem_cache_client *cl,
+			 struct dm_mem_cache_object *obj)
+{
+	unsigned chunks = cl->chunks;
+	unsigned long flags;
+
+	local_irq_save(flags);
+	local_irq_disable();
+	while (chunks--) {
+		unsigned p = cl->pages_per_chunk;
+
+		obj[chunks].pl = NULL;
+
+		while (p--) {
+			struct page_list *pl;
+
+			/* Take next element from free list */
+			spin_lock(&cl->lock);
+			pl = cl->free_list;
+			BUG_ON(!pl);
+			cl->free_list = pl->next;
+			spin_unlock(&cl->lock);
+
+			pl->next = obj[chunks].pl;
+			obj[chunks].pl = pl;
+		}
+	}
+
+	local_irq_restore(flags);
+}
+
+/*
+ * Free page_list elements putting them back onto free list
+ */
+static void free_chunks(struct dm_mem_cache_client *cl,
+			struct dm_mem_cache_object *obj)
+{
+	unsigned chunks = cl->chunks;
+	unsigned long flags;
+	struct page_list *next, *pl;
+
+	local_irq_save(flags);
+	local_irq_disable();
+	while (chunks--) {
+		for (pl = obj[chunks].pl; pl; pl = next) {
+			next = pl->next;
+
+			spin_lock(&cl->lock);
+			pl->next = cl->free_list;
+			cl->free_list = pl;
+			cl->free_pages++;
+			spin_unlock(&cl->lock);
+		}
+	}
+
+	local_irq_restore(flags);
+}
+
+/*
+ * Create/destroy dm memory cache client resources.
+ */
+struct dm_mem_cache_client *
+dm_mem_cache_client_create(unsigned objects, unsigned chunks,
+			   unsigned pages_per_chunk)
+{
+	unsigned total_pages = objects * chunks * pages_per_chunk;
+	struct dm_mem_cache_client *client;
+
+	BUG_ON(!total_pages);
+	client = kzalloc(sizeof(*client), GFP_KERNEL);
+	if (!client)
+		return ERR_PTR(-ENOMEM);
+
+	client->objs_pool = mempool_create_kmalloc_pool(objects,
+				chunks * sizeof(struct dm_mem_cache_object));
+	if (!client->objs_pool)
+		goto err;
+
+	client->free_list = alloc_cache_pages(total_pages);
+	if (!client->free_list)
+		goto err1;
+
+	spin_lock_init(&client->lock);
+	client->objects = objects;
+	client->chunks = chunks;
+	client->pages_per_chunk = pages_per_chunk;
+	client->free_pages = client->total_pages = total_pages;
+	return client;
+
+err1:
+	mempool_destroy(client->objs_pool);
+err:
+	kfree(client);
+	return ERR_PTR(-ENOMEM);
+}
+EXPORT_SYMBOL(dm_mem_cache_client_create);
+
+void dm_mem_cache_client_destroy(struct dm_mem_cache_client *cl)
+{
+	BUG_ON(cl->free_pages != cl->total_pages);
+	free_cache_pages(cl->free_list);
+	mempool_destroy(cl->objs_pool);
+	kfree(cl);
+}
+EXPORT_SYMBOL(dm_mem_cache_client_destroy);
+
+/*
+ * Grow a clients cache by an amount of pages.
+ *
+ * Don't call from interrupt context!
+ */
+int dm_mem_cache_grow(struct dm_mem_cache_client *cl, unsigned objects)
+{
+	unsigned pages = objects * cl->chunks * cl->pages_per_chunk;
+	struct page_list *pl, *last;
+
+	BUG_ON(!pages);
+	pl = alloc_cache_pages(pages);
+	if (!pl)
+		return -ENOMEM;
+
+	last = pl;
+	while (last->next)
+		last = last->next;
+
+	spin_lock_irq(&cl->lock);
+	last->next = cl->free_list;
+	cl->free_list = pl;
+	cl->free_pages += pages;
+	cl->total_pages += pages;
+	cl->objects++;
+	spin_unlock_irq(&cl->lock);
+
+	mempool_resize(cl->objs_pool, cl->objects, GFP_NOIO);
+	return 0;
+}
+EXPORT_SYMBOL(dm_mem_cache_grow);
+
+/* Shrink a clients cache by an amount of pages */
+int dm_mem_cache_shrink(struct dm_mem_cache_client *cl, unsigned objects)
+{
+	int r;
+	unsigned pages = objects * cl->chunks * cl->pages_per_chunk, p = pages;
+	unsigned long flags;
+	struct page_list *last = NULL, *pl, *pos;
+
+	BUG_ON(!pages);
+
+	spin_lock_irqsave(&cl->lock, flags);
+	pl = pos = cl->free_list;
+	while (p-- && pos->next) {
+		last = pos;
+		pos = pos->next;
+	}
+
+	if (++p)
+		r = -ENOMEM;
+	else {
+		r = 0;
+		cl->free_list = pos;
+		cl->free_pages -= pages;
+		cl->total_pages -= pages;
+		cl->objects--;
+		last->next = NULL;
+	}
+	spin_unlock_irqrestore(&cl->lock, flags);
+
+	if (!r) {
+		free_cache_pages(pl);
+		mempool_resize(cl->objs_pool, cl->objects, GFP_NOIO);
+	}
+
+	return r;
+}
+EXPORT_SYMBOL(dm_mem_cache_shrink);
+
+/*
+ * Allocate/free a memory object
+ *
+ * Can be called from interrupt context
+ */
+struct dm_mem_cache_object *dm_mem_cache_alloc(struct dm_mem_cache_client *cl)
+{
+	int r = 0;
+	unsigned pages = cl->chunks * cl->pages_per_chunk;
+	unsigned long flags;
+	struct dm_mem_cache_object *obj;
+
+	obj = mempool_alloc(cl->objs_pool, GFP_NOIO);
+	if (!obj)
+		return ERR_PTR(-ENOMEM);
+
+	spin_lock_irqsave(&cl->lock, flags);
+	if (pages > cl->free_pages)
+		r = -ENOMEM;
+	else
+		cl->free_pages -= pages;
+	spin_unlock_irqrestore(&cl->lock, flags);
+
+	if (r) {
+		mempool_free(obj, cl->objs_pool);
+		return ERR_PTR(r);
+	}
+
+	alloc_chunks(cl, obj);
+	return obj;
+}
+EXPORT_SYMBOL(dm_mem_cache_alloc);
+
+void dm_mem_cache_free(struct dm_mem_cache_client *cl,
+		       struct dm_mem_cache_object *obj)
+{
+	free_chunks(cl, obj);
+	mempool_free(obj, cl->objs_pool);
+}
+EXPORT_SYMBOL(dm_mem_cache_free);
+
+MODULE_DESCRIPTION(DM_NAME " dm memory cache");
+MODULE_AUTHOR("Heinz Mauelshagen <hjm@redhat.com>");
+MODULE_LICENSE("GPL");
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/dm-raid4-5/dm-memcache.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2006-2008 Red Hat, Inc. All rights reserved.
+ *
+ * Module Author: Heinz Mauelshagen <Mauelshagen@RedHat.com>
+ *
+ * Device-mapper memory object handling:
+ *
+ * o allocate/free total_pages in a per client page pool.
+ *
+ * o allocate/free memory objects with chunks (1..n) of
+ *   pages_per_chunk pages hanging off.
+ *
+ * This file is released under the GPL.
+ */
+
+#ifndef _DM_MEM_CACHE_H
+#define _DM_MEM_CACHE_H
+
+#define	DM_MEM_CACHE_H_VERSION	"0.1"
+
+#include "dm.h"
+#include <linux/dm-io.h>
+
+static inline struct page_list *pl_elem(struct page_list *pl, unsigned p)
+{
+	while (pl && p--)
+		pl = pl->next;
+
+	return pl;
+}
+
+struct dm_mem_cache_object {
+	struct page_list *pl; /* Dynamically allocated array */
+	void *private;	      /* Caller context reference */
+};
+
+struct dm_mem_cache_client;
+
+/*
+ * Create/destroy dm memory cache client resources.
+ *
+ * On creation, a number of @objects with @chunks of
+ * @pages_per_chunk pages will be allocated.
+ */
+struct dm_mem_cache_client *
+dm_mem_cache_client_create(unsigned objects, unsigned chunks,
+			   unsigned pages_per_chunk);
+void dm_mem_cache_client_destroy(struct dm_mem_cache_client *client);
+
+/*
+ * Grow/shrink a dm memory cache client resources
+ * by @objetcs amount of objects.
+ */
+int dm_mem_cache_grow(struct dm_mem_cache_client *client, unsigned objects);
+int dm_mem_cache_shrink(struct dm_mem_cache_client *client, unsigned objects);
+
+/*
+ * Allocate/free a memory object
+ *
+ * On allocation one object with an amount of chunks and
+ * an amount of pages per chunk will be returned on success.
+ */
+struct dm_mem_cache_object *
+dm_mem_cache_alloc(struct dm_mem_cache_client *client);
+void dm_mem_cache_free(struct dm_mem_cache_client *client,
+		       struct dm_mem_cache_object *object);
+
+#endif
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/dm-raid4-5/dm-message.c
@@ -0,0 +1,184 @@
+/*
+ * Copyright (C) 2007,2008 Red Hat Inc. All rights reserved.
+ *
+ * Module Author: Heinz Mauelshagen <heinzm@redhat.com>
+ *
+ * General device-mapper message interface argument parser.
+ *
+ * This file is released under the GPL.
+ *
+ * device-mapper message parser.
+ *
+ */
+
+#include "dm.h"
+#include "dm-message.h"
+#include <linux/kernel.h>
+#include <linux/module.h>
+
+#define DM_MSG_PREFIX	"dm_message"
+
+/* Basename of a path. */
+static inline char *
+basename(char *s)
+{
+	char *p = strrchr(s, '/');
+
+	return p ? p + 1 : s;
+}
+
+/* Get an argument depending on type. */
+static void
+message_arguments(struct dm_msg *msg, int argc, char **argv)
+{
+
+	if (argc) {
+		int i;
+		struct dm_message_argument *args = msg->spec->args;
+
+		for (i = 0; i < args->num_args; i++) {
+			int r;
+			unsigned long **ptr = args->ptr;
+			enum dm_message_argument_type type = args->types[i];
+
+			switch (type) {
+			case dm_msg_base_t:
+				((char **) ptr)[i] = basename(argv[i]);
+				break;
+
+			case dm_msg_str_t:
+				((char **) ptr)[i] = argv[i];
+				break;
+
+			case dm_msg_int_t:
+				r = sscanf(argv[i], "%d", ((int **) ptr)[i]);
+				goto check;
+
+			case dm_msg_uint_t:
+				r = sscanf(argv[i], "%u",
+					   ((unsigned **) ptr)[i]);
+				goto check;
+
+			case dm_msg_uint64_t:
+				r = sscanf(argv[i], "%llu",
+					   ((unsigned long long **) ptr)[i]);
+
+check:
+				if (r != 1) {
+					set_bit(dm_msg_ret_undef, &msg->ret);
+					set_bit(dm_msg_ret_arg, &msg->ret);
+				}
+			}
+		}
+	}
+}
+
+/* Parse message options. */
+static void
+message_options_parse(struct dm_msg *msg, int argc, char **argv)
+{
+	int hit = 0;
+	unsigned long *action;
+	size_t l1 = strlen(*argv), l_hit = 0;
+	struct dm_message_option *o = msg->spec->options;
+	char **option, **option_end = o->options + o->num_options;
+
+	for (option = o->options, action = o->actions;
+	     option < option_end; option++, action++) {
+		size_t l2 = strlen(*option);
+
+		if (!strnicmp(*argv, *option, min(l1, l2))) {
+			hit++;
+			l_hit = l2;
+			set_bit(*action, &msg->action);
+		}
+	}
+
+	/* Assume error. */
+	msg->ret = 0;
+	set_bit(dm_msg_ret_option, &msg->ret);
+	if (!hit || l1 > l_hit)
+		set_bit(dm_msg_ret_undef, &msg->ret);	/* Undefined option. */
+	else if (hit > 1)
+		set_bit(dm_msg_ret_ambiguous, &msg->ret); /* Ambiguous option.*/
+	else {
+		clear_bit(dm_msg_ret_option, &msg->ret); /* Option OK. */
+		message_arguments(msg, --argc, ++argv);
+	}
+}
+
+static inline void
+print_ret(const char *caller, unsigned long ret)
+{
+	struct {
+		unsigned long err;
+		const char *err_str;
+	} static err_msg[] = {
+		{ dm_msg_ret_ambiguous, "message ambiguous" },
+		{ dm_msg_ret_inval, "message invalid" },
+		{ dm_msg_ret_undef, "message undefined" },
+		{ dm_msg_ret_arg, "message argument" },
+		{ dm_msg_ret_argcount, "message argument count" },
+		{ dm_msg_ret_option, "option" },
+	}, *e = ARRAY_END(err_msg);
+
+	while (e-- > err_msg) {
+		if (test_bit(e->err, &ret))
+			DMERR("%s %s", caller, e->err_str);
+	}
+}
+
+/* Parse a message action. */
+int
+dm_message_parse(const char *caller, struct dm_msg *msg, void *context,
+		 int argc, char **argv)
+{
+	int hit = 0;
+	size_t l1, l_hit = 0;
+	struct dm_msg_spec *s, *s_hit = NULL,
+			   *s_end = msg->specs + msg->num_specs;
+
+	if (argc < 2)
+		return -EINVAL;
+
+	l1 = strlen(*argv);
+	for (s = msg->specs; s < s_end; s++) {
+		size_t l2 = strlen(s->cmd);
+
+		if (!strnicmp(*argv, s->cmd, min(l1, l2))) {
+			hit++;
+			l_hit = l2;
+			s_hit = s;
+		}
+	}
+
+	msg->ret = 0;
+	if (!hit || l1 > l_hit)	/* No hit or message string too long. */
+		set_bit(dm_msg_ret_undef, &msg->ret);
+	else if (hit > 1)	/* Ambiguous message. */
+		set_bit(dm_msg_ret_ambiguous, &msg->ret);
+	else if (argc - 2 != s_hit->args->num_args) {
+		set_bit(dm_msg_ret_undef, &msg->ret);
+		set_bit(dm_msg_ret_argcount, &msg->ret);
+	}
+
+	if (msg->ret)
+		goto bad;
+
+	msg->action = 0;
+	msg->spec = s_hit;
+	set_bit(s_hit->action, &msg->action);
+	message_options_parse(msg, --argc, ++argv);
+
+	if (!msg->ret)
+		return msg->spec->f(msg, context);
+
+bad:
+	print_ret(caller, msg->ret);
+	return -EINVAL;
+}
+EXPORT_SYMBOL(dm_message_parse);
+
+MODULE_DESCRIPTION(DM_NAME " device-mapper target message parser");
+MODULE_AUTHOR("Heinz Mauelshagen <hjm@redhat.com>");
+MODULE_LICENSE("GPL");
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/dm-raid4-5/dm-message.h
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2007,2008 Red Hat, Inc. All rights reserved.
+ *
+ * Module Author: Heinz Mauelshagen <Mauelshagen@RedHat.de>
+ *
+ * General device-mapper message interface argument parser.
+ *
+ * This file is released under the GPL.
+ *
+ */
+
+#ifndef DM_MESSAGE_H
+#define DM_MESSAGE_H
+
+/* Factor out to dm.h. */
+/* Reference to array end. */
+#define ARRAY_END(a)    ((a) + ARRAY_SIZE(a))
+
+/* Message return bits. */
+enum dm_message_return {
+	dm_msg_ret_ambiguous,		/* Action ambiguous. */
+	dm_msg_ret_inval,		/* Action invalid. */
+	dm_msg_ret_undef,		/* Action undefined. */
+
+	dm_msg_ret_option,		/* Option error. */
+	dm_msg_ret_arg,			/* Argument error. */
+	dm_msg_ret_argcount,		/* Argument count error. */
+};
+
+/* Message argument type conversions. */
+enum dm_message_argument_type {
+	dm_msg_base_t,		/* Basename string. */
+	dm_msg_str_t,		/* String. */
+	dm_msg_int_t,		/* Signed int. */
+	dm_msg_uint_t,		/* Unsigned int. */
+	dm_msg_uint64_t,	/* Unsigned int 64. */
+};
+
+/* A message option. */
+struct dm_message_option {
+	unsigned num_options;
+	char **options;
+	unsigned long *actions;
+};
+
+/* Message arguments and types. */
+struct dm_message_argument {
+	unsigned num_args;
+	unsigned long **ptr;
+	enum dm_message_argument_type types[];
+};
+
+/* Client message. */
+struct dm_msg {
+	unsigned long action;		/* Identified action. */
+	unsigned long ret;		/* Return bits. */
+	unsigned num_specs;		/* # of sepcifications listed. */
+	struct dm_msg_spec *specs;	/* Specification list. */
+	struct dm_msg_spec *spec;	/* Specification selected. */
+};
+
+/* Secification of the message. */
+struct dm_msg_spec {
+	const char *cmd;	/* Name of the command (i.e. 'bandwidth'). */
+	unsigned long action;
+	struct dm_message_option *options;
+	struct dm_message_argument *args;
+	unsigned long parm;	/* Parameter to pass through to callback. */
+	/* Function to process for action. */
+	int (*f) (struct dm_msg *msg, void *context);
+};
+
+/* Parameter access macros. */
+#define	DM_MSG_PARM(msg) ((msg)->spec->parm)
+
+#define	DM_MSG_STR_ARGS(msg, idx) ((char *) *(msg)->spec->args->ptr[idx])
+#define	DM_MSG_INT_ARGS(msg, idx) ((int) *(msg)->spec->args->ptr[idx])
+#define	DM_MSG_UINT_ARGS(msg, idx) ((unsigned) DM_MSG_INT_ARG(msg, idx))
+#define	DM_MSG_UINT64_ARGS(msg, idx) ((uint64_t)  *(msg)->spec->args->ptr[idx])
+
+#define	DM_MSG_STR_ARG(msg)	DM_MSG_STR_ARGS(msg, 0)
+#define	DM_MSG_INT_ARG(msg)	DM_MSG_INT_ARGS(msg, 0)
+#define	DM_MSG_UINT_ARG(msg)	DM_MSG_UINT_ARGS(msg, 0)
+#define	DM_MSG_UINT64_ARG(msg)	DM_MSG_UINT64_ARGS(msg, 0)
+
+
+/* Parse a message and its options and optionally call a function back. */
+int dm_message_parse(const char *caller, struct dm_msg *msg, void *context,
+		     int argc, char **argv);
+
+#endif
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/dm-raid4-5/dm-raid4-5.c
@@ -0,0 +1,4536 @@
+/*[A[A
+ * Copyright (C) 2005-2009 Red Hat, Inc. All rights reserved.
+ *
+ * Module Author: Heinz Mauelshagen <heinzm@redhat.com>
+ *
+ * This file is released under the GPL.
+ *
+ *
+ * Linux 2.6 Device Mapper RAID4 and RAID5 target.
+ *
+ * Supports:
+ *	o RAID4 with dedicated and selectable parity device
+ *	o RAID5 with rotating parity (left+right, symmetric+asymmetric)
+ *	o recovery of out of sync device for initial
+ *	  RAID set creation or after dead drive replacement
+ *	o run time optimization of xor algorithm used to calculate parity
+ *
+ *
+ * Thanks to MD for:
+ *    o the raid address calculation algorithm
+ *    o the base of the biovec <-> page list copier.
+ *
+ *
+ * Uses region hash to keep track of how many writes are in flight to
+ * regions in order to use dirty log to keep state of regions to recover:
+ *
+ *    o clean regions (those which are synchronized
+ * 	and don't have write io in flight)
+ *    o dirty regions (those with write io in flight)
+ *
+ *
+ * On startup, any dirty regions are migrated to the
+ * 'nosync' state and are subject to recovery by the daemon.
+ *
+ * See raid_ctr() for table definition.
+ *
+ * FIXME: recovery bandwidth
+ */ 
+
+static const char *version = "v0.2594b";
+
+#include "dm.h"
+#include "dm-memcache.h"
+#include "dm-message.h"
+#include "dm-raid45.h"
+
+#include <linux/kernel.h>
+#include <linux/vmalloc.h>
+#include <linux/raid/xor.h>
+
+#include <linux/bio.h>
+#include <linux/dm-io.h>
+#include <linux/dm-dirty-log.h>
+#include "dm-region-hash.h"
+
+#include <linux/slab.h>
+#include <linux/module.h>
+
+/*
+ * Configurable parameters
+ */
+
+/* Minimum/maximum and default # of selectable stripes. */
+#define	STRIPES_MIN		8
+#define	STRIPES_MAX		16384
+#define	STRIPES_DEFAULT		80
+
+/* Maximum and default chunk size in sectors if not set in constructor. */
+#define	CHUNK_SIZE_MIN		8
+#define	CHUNK_SIZE_MAX		16384
+#define	CHUNK_SIZE_DEFAULT	64
+
+/* Default io size in sectors if not set in constructor. */
+#define	IO_SIZE_MIN		CHUNK_SIZE_MIN
+#define	IO_SIZE_DEFAULT		IO_SIZE_MIN
+
+/* Recover io size default in sectors. */
+#define	RECOVER_IO_SIZE_MIN		64
+#define	RECOVER_IO_SIZE_DEFAULT		256
+
+/* Default, minimum and maximum percentage of recover io bandwidth. */
+#define	BANDWIDTH_DEFAULT	10
+#define	BANDWIDTH_MIN		1
+#define	BANDWIDTH_MAX		100
+
+/* # of parallel recovered regions */
+#define RECOVERY_STRIPES_MIN	1
+#define RECOVERY_STRIPES_MAX	64
+#define RECOVERY_STRIPES_DEFAULT	RECOVERY_STRIPES_MIN
+/*
+ * END Configurable parameters
+ */
+
+#define	TARGET	"dm-raid45"
+#define	DAEMON	"kraid45d"
+#define	DM_MSG_PREFIX	TARGET
+
+#define	SECTORS_PER_PAGE	(PAGE_SIZE >> SECTOR_SHIFT)
+
+/* Amount/size for __xor(). */
+#define	XOR_SIZE	PAGE_SIZE
+
+/* Check value in range. */
+#define	range_ok(i, min, max)	(i >= min && i <= max)
+
+/* Check argument is power of 2. */
+#define POWER_OF_2(a) (!(a & (a - 1)))
+
+/* Structure access macros. */
+/* Derive raid_set from stripe_cache pointer. */
+#define	RS(x)	container_of(x, struct raid_set, sc)
+
+/* Page reference. */
+#define PAGE(stripe, p)  ((stripe)->obj[p].pl->page)
+
+/* Stripe chunk reference. */
+#define CHUNK(stripe, p) ((stripe)->chunk + p)
+
+/* Bio list reference. */
+#define	BL(stripe, p, rw)	(stripe->chunk[p].bl + rw)
+#define	BL_CHUNK(chunk, rw)	(chunk->bl + rw)
+
+/* Page list reference. */
+#define	PL(stripe, p)		(stripe->obj[p].pl)
+/* END: structure access macros. */
+
+/* Factor out to dm-bio-list.h */
+static inline void bio_list_push(struct bio_list *bl, struct bio *bio)
+{
+	bio->bi_next = bl->head;
+	bl->head = bio;
+
+	if (!bl->tail)
+		bl->tail = bio;
+}
+
+/* Factor out to dm.h */
+#define TI_ERR_RET(str, ret) \
+	do { ti->error = str; return ret; } while (0);
+#define TI_ERR(str)     TI_ERR_RET(str, -EINVAL)
+
+/* Macro to define access IO flags access inline functions. */
+#define	BITOPS(name, what, var, flag) \
+static inline int TestClear ## name ## what(struct var *v) \
+{ return test_and_clear_bit(flag, &v->io.flags); } \
+static inline int TestSet ## name ## what(struct var *v) \
+{ return test_and_set_bit(flag, &v->io.flags); } \
+static inline void Clear ## name ## what(struct var *v) \
+{ clear_bit(flag, &v->io.flags); } \
+static inline void Set ## name ## what(struct var *v) \
+{ set_bit(flag, &v->io.flags); } \
+static inline int name ## what(struct var *v) \
+{ return test_bit(flag, &v->io.flags); }
+
+/*-----------------------------------------------------------------
+ * Stripe cache
+ *
+ * Cache for all reads and writes to raid sets (operational or degraded)
+ *
+ * We need to run all data to and from a RAID set through this cache,
+ * because parity chunks need to get calculated from data chunks
+ * or, in the degraded/resynchronization case, missing chunks need
+ * to be reconstructed using the other chunks of the stripe.
+ *---------------------------------------------------------------*/
+/* A chunk within a stripe (holds bios hanging off). */
+/* IO status flags for chunks of a stripe. */
+enum chunk_flags {
+	CHUNK_DIRTY,		/* Pages of chunk dirty; need writing. */
+	CHUNK_ERROR,		/* IO error on any chunk page. */
+	CHUNK_IO,		/* Allow/prohibit IO on chunk pages. */
+	CHUNK_LOCKED,		/* Chunk pages locked during IO. */
+	CHUNK_MUST_IO,		/* Chunk must io. */
+	CHUNK_UNLOCK,		/* Enforce chunk unlock. */
+	CHUNK_UPTODATE,		/* Chunk pages are uptodate. */
+};
+
+/*
+ * This does not work anymore with __REQ_* values being enums
+ *
+#if READ != 0 || WRITE != 1
+#error dm-raid45: READ/WRITE != 0/1 used as index!!!
+#endif
+*/
+
+enum bl_type {
+	WRITE_QUEUED = WRITE + 1,
+	WRITE_MERGED,
+	NR_BL_TYPES,	/* Must be last one! */
+};
+struct stripe_chunk {
+	atomic_t cnt;		/* Reference count. */
+	struct stripe *stripe;	/* Backpointer to stripe for endio(). */
+	/* Bio lists for reads, writes, and writes merged. */
+	struct bio_list bl[NR_BL_TYPES];
+	struct {
+		unsigned long flags; /* IO status flags. */
+	} io;
+};
+
+/* Define chunk bit operations. */
+BITOPS(Chunk, Dirty,	 stripe_chunk, CHUNK_DIRTY)
+BITOPS(Chunk, Error,	 stripe_chunk, CHUNK_ERROR)
+BITOPS(Chunk, Io,	 stripe_chunk, CHUNK_IO)
+BITOPS(Chunk, Locked,	 stripe_chunk, CHUNK_LOCKED)
+BITOPS(Chunk, MustIo,	 stripe_chunk, CHUNK_MUST_IO)
+BITOPS(Chunk, Unlock,	 stripe_chunk, CHUNK_UNLOCK)
+BITOPS(Chunk, Uptodate,	 stripe_chunk, CHUNK_UPTODATE)
+
+/*
+ * Stripe linked list indexes. Keep order, because the stripe
+ * and the stripe cache rely on the first 3!
+ */
+enum list_types {
+	LIST_FLUSH,	/* Stripes to flush for io. */
+	LIST_ENDIO,	/* Stripes to endio. */
+	LIST_LRU,	/* Least recently used stripes. */
+	SC_NR_LISTS,	/* # of lists in stripe cache. */
+	LIST_HASH = SC_NR_LISTS,	/* Hashed stripes. */
+	LIST_RECOVER = LIST_HASH, /* For recovery type stripes only. */
+	STRIPE_NR_LISTS,/* To size array in struct stripe. */
+};
+
+/* Adressing region recovery. */
+struct recover_addr {
+	struct dm_region *reg;	/* Actual region to recover. */
+	sector_t pos;	/* Position within region to recover. */
+	sector_t end;	/* End of region to recover. */
+};
+
+/* A stripe: the io object to handle all reads and writes to a RAID set. */
+struct stripe {
+	atomic_t cnt;			/* Reference count. */
+	struct stripe_cache *sc;	/* Backpointer to stripe cache. */
+
+	/*
+	 * 4 linked lists:
+	 *   o io list to flush io
+	 *   o endio list
+	 *   o LRU list to put stripes w/o reference count on
+	 *   o stripe cache hash
+	 */
+	struct list_head lists[STRIPE_NR_LISTS];
+
+	sector_t key;	 /* Hash key. */
+	region_t region; /* Region stripe is mapped to. */
+
+	struct {
+		unsigned long flags;	/* Stripe state flags (see below). */
+
+		/*
+		 * Pending ios in flight:
+		 *
+		 * used to control move of stripe to endio list
+		 */
+		atomic_t pending;
+
+		/* Sectors to read and write for multi page stripe sets. */
+		unsigned size;
+	} io;
+
+	/* Address region recovery. */
+	struct recover_addr *recover;
+
+	/* Lock on stripe (Future: for clustering). */
+	void *lock;
+
+	struct {
+		unsigned short parity;	/* Parity chunk index. */
+		short recover;		/* Recovery chunk index. */
+	} idx;
+
+	/*
+	 * This stripe's memory cache object (dm-mem-cache);
+	 * i.e. the io chunk pages.
+	 */
+	struct dm_mem_cache_object *obj;
+
+	/* Array of stripe sets (dynamically allocated). */
+	struct stripe_chunk chunk[0];
+};
+
+/* States stripes can be in (flags field). */
+enum stripe_states {
+	STRIPE_ERROR,		/* io error on stripe. */
+	STRIPE_MERGED,		/* Writes got merged to be written. */
+	STRIPE_RBW,		/* Read-before-write stripe. */
+	STRIPE_RECONSTRUCT,	/* Reconstruct of a missing chunk required. */
+	STRIPE_RECONSTRUCTED,	/* Reconstructed of a missing chunk. */
+	STRIPE_RECOVER,		/* Stripe used for RAID set recovery. */
+};
+
+/* Define stripe bit operations. */
+BITOPS(Stripe, Error,	      stripe, STRIPE_ERROR)
+BITOPS(Stripe, Merged,        stripe, STRIPE_MERGED)
+BITOPS(Stripe, RBW,	      stripe, STRIPE_RBW)
+BITOPS(Stripe, Reconstruct,   stripe, STRIPE_RECONSTRUCT)
+BITOPS(Stripe, Reconstructed, stripe, STRIPE_RECONSTRUCTED)
+BITOPS(Stripe, Recover,	      stripe, STRIPE_RECOVER)
+
+/* A stripe hash. */
+struct stripe_hash {
+	struct list_head *hash;
+	unsigned buckets;
+	unsigned mask;
+	unsigned prime;
+	unsigned shift;
+};
+
+enum sc_lock_types {
+	LOCK_ENDIO,	/* Protect endio list. */
+	LOCK_LRU,	/* Protect LRU list. */
+	NR_LOCKS,       /* To size array in struct stripe_cache. */
+};
+
+/* A stripe cache. */
+struct stripe_cache {
+	/* Stripe hash. */
+	struct stripe_hash hash;
+
+	spinlock_t locks[NR_LOCKS];	/* Locks to protect lists. */
+
+	/* Stripes with io to flush, stripes to endio and LRU lists. */
+	struct list_head lists[SC_NR_LISTS];
+
+	/* Slab cache to allocate stripes from. */
+	struct {
+		struct kmem_cache *cache;	/* Cache itself. */
+		char name[32];	/* Unique name. */
+	} kc;
+
+	struct dm_io_client *dm_io_client; /* dm-io client resource context. */
+
+	/* dm-mem-cache client resource context. */
+	struct dm_mem_cache_client *mem_cache_client;
+
+	int stripes_parm;	    /* # stripes parameter from constructor. */
+	atomic_t stripes;	    /* actual # of stripes in cache. */
+	atomic_t stripes_to_set;    /* # of stripes to resize cache to. */
+	atomic_t stripes_last;	    /* last # of stripes in cache. */
+	atomic_t active_stripes;    /* actual # of active stripes in cache. */
+
+	/* REMOVEME: */
+	atomic_t active_stripes_max; /* actual # of active stripes in cache. */
+};
+
+/* Flag specs for raid_dev */ ;
+enum raid_dev_flags {
+	DEV_FAILED,	/* Device failed. */
+	DEV_IO_QUEUED,	/* Io got queued to device. */
+};
+
+/* The raid device in a set. */
+struct raid_dev {
+	struct dm_dev *dev;
+	sector_t start;		/* Offset to map to. */
+	struct {	/* Using struct to be able to BITOPS(). */
+		unsigned long flags;	/* raid_dev_flags. */
+	} io;
+};
+
+BITOPS(Dev, Failed,   raid_dev, DEV_FAILED)
+BITOPS(Dev, IoQueued, raid_dev, DEV_IO_QUEUED)
+
+/* Flags spec for raid_set. */
+enum raid_set_flags {
+	RS_CHECK_OVERWRITE,	/* Check for chunk overwrites. */
+	RS_DEAD,		/* RAID set inoperational. */
+	RS_DEGRADED,		/* Io errors on RAID device. */
+	RS_DEVEL_STATS,		/* REMOVEME: display status information. */
+	RS_RECOVER,		/* Do recovery. */
+	RS_RECOVERY_BANDWIDTH,	/* Allow recovery bandwidth (delayed bios). */
+	RS_SC_BUSY,		/* Stripe cache busy -> send an event. */
+	RS_SUSPEND,		/* Suspend RAID set. */
+};
+
+/* REMOVEME: devel stats counters. */
+enum stats_types {
+	S_BIOS_READ,
+	S_BIOS_ADDED_READ,
+	S_BIOS_ENDIO_READ,
+	S_BIOS_WRITE,
+	S_BIOS_ADDED_WRITE,
+	S_BIOS_ENDIO_WRITE,
+	S_CAN_MERGE,
+	S_CANT_MERGE,
+	S_CONGESTED,
+	S_DM_IO_READ,
+	S_DM_IO_WRITE,
+	S_BANDWIDTH,
+	S_BARRIER,
+	S_BIO_COPY_PL_NEXT,
+	S_DEGRADED,
+	S_DELAYED_BIOS,
+	S_FLUSHS,
+	S_HITS_1ST,
+	S_IOS_POST,
+	S_INSCACHE,
+	S_MAX_LOOKUP,
+	S_CHUNK_LOCKED,
+	S_NO_BANDWIDTH,
+	S_NOT_CONGESTED,
+	S_NO_RW,
+	S_NOSYNC,
+	S_OVERWRITE,
+	S_PROHIBITCHUNKIO,
+	S_RECONSTRUCT_EI,
+	S_RECONSTRUCT_DEV,
+	S_RECONSTRUCT_SET,
+	S_RECONSTRUCTED,
+	S_REQUEUE,
+	S_STRIPE_ERROR,
+	S_SUM_DELAYED_BIOS,
+	S_XORS,
+	S_NR_STATS,	/* # of stats counters. Must be last! */
+};
+
+/* Status type -> string mappings. */
+struct stats_map {
+	const enum stats_types type;
+	const char *str;
+};
+
+static struct stats_map stats_map[] = {
+	{ S_BIOS_READ, "r=" },
+	{ S_BIOS_ADDED_READ, "/" },
+	{ S_BIOS_ENDIO_READ, "/" },
+	{ S_BIOS_WRITE, " w=" },
+	{ S_BIOS_ADDED_WRITE, "/" },
+	{ S_BIOS_ENDIO_WRITE, "/" },
+	{ S_DM_IO_READ, " rc=" },
+	{ S_DM_IO_WRITE, " wc=" },
+	{ S_BANDWIDTH, "\nbw=" },
+	{ S_NO_BANDWIDTH, " no_bw=" },
+	{ S_BARRIER, "\nbarrier=" },
+	{ S_BIO_COPY_PL_NEXT, "\nbio_cp_next=" },
+	{ S_CAN_MERGE, "\nmerge=" },
+	{ S_CANT_MERGE, "/no_merge=" },
+	{ S_CHUNK_LOCKED, "\nchunk_locked=" },
+	{ S_CONGESTED, "\ncgst=" },
+	{ S_NOT_CONGESTED, "/not_cgst=" },
+	{ S_DEGRADED, "\ndegraded=" },
+	{ S_DELAYED_BIOS, "\ndel_bios=" },
+	{ S_SUM_DELAYED_BIOS, "/sum_del_bios=" },
+	{ S_FLUSHS, "\nflushs=" },
+	{ S_HITS_1ST, "\nhits_1st=" },
+	{ S_IOS_POST, " ios_post=" },
+	{ S_INSCACHE, " inscache=" },
+	{ S_MAX_LOOKUP, " maxlookup=" },
+	{ S_NO_RW, "\nno_rw=" },
+	{ S_NOSYNC, " nosync=" },
+	{ S_OVERWRITE, " ovr=" },
+	{ S_PROHIBITCHUNKIO, " prhbt_io=" },
+	{ S_RECONSTRUCT_EI, "\nrec_ei=" },
+	{ S_RECONSTRUCT_DEV, " rec_dev=" },
+	{ S_RECONSTRUCT_SET, " rec_set=" },
+	{ S_RECONSTRUCTED, " rec=" },
+	{ S_REQUEUE, " requeue=" },
+	{ S_STRIPE_ERROR, " stripe_err=" },
+	{ S_XORS, " xors=" },
+};
+
+/*
+ * A RAID set.
+ */
+#define	dm_rh_client	dm_region_hash
+enum count_type { IO_WORK = 0, IO_RECOVER, IO_NR_COUNT };
+typedef void (*xor_function_t)(unsigned count, unsigned long **data);
+struct raid_set {
+	struct dm_target *ti;	/* Target pointer. */
+
+	struct {
+		unsigned long flags;	/* State flags. */
+		struct mutex in_lock;	/* Protects central input list below. */
+		struct bio_list in;	/* Pending ios (central input list). */
+		struct bio_list work;	/* ios work set. */
+		wait_queue_head_t suspendq;	/* suspend synchronization. */
+		atomic_t in_process;	/* counter of queued bios (suspendq). */
+		atomic_t in_process_max;/* counter of queued bios max. */
+
+		/* io work. */
+		struct workqueue_struct *wq;
+		struct delayed_work dws_do_raid;	/* For main worker. */
+		struct work_struct ws_do_table_event;	/* For event worker. */
+	} io;
+
+	/* Stripe locking abstraction. */
+	struct dm_raid45_locking_type *locking;
+
+	struct stripe_cache sc;	/* Stripe cache for this set. */
+
+	/* Xor optimization. */
+	struct {
+		struct xor_func *f;
+		unsigned chunks;
+		unsigned speed;
+	} xor;
+
+	/* Recovery parameters. */
+	struct recover {
+		struct dm_dirty_log *dl;	/* Dirty log. */
+		struct dm_rh_client *rh;	/* Region hash. */
+
+		struct dm_io_client *dm_io_client; /* recovery dm-io client. */
+		/* dm-mem-cache client resource context for recovery stripes. */
+		struct dm_mem_cache_client *mem_cache_client;
+
+		struct list_head stripes;	/* List of recovery stripes. */
+
+		region_t nr_regions;
+		region_t nr_regions_to_recover;
+		region_t nr_regions_recovered;
+		unsigned long start_jiffies;
+		unsigned long end_jiffies;
+
+		unsigned bandwidth;	 /* Recovery bandwidth [%]. */
+		unsigned bandwidth_work; /* Recovery bandwidth [factor]. */
+		unsigned bandwidth_parm; /*  " constructor parm. */
+		unsigned io_size;        /* recovery io size <= region size. */
+		unsigned io_size_parm;   /* recovery io size ctr parameter. */
+		unsigned recovery;	 /* Recovery allowed/prohibited. */
+		unsigned recovery_stripes; /* # of parallel recovery stripes. */
+
+		/* recovery io throttling. */
+		atomic_t io_count[IO_NR_COUNT];	/* counter recover/regular io.*/
+		unsigned long last_jiffies;
+	} recover;
+
+	/* RAID set parameters. */
+	struct {
+		struct raid_type *raid_type;	/* RAID type (eg, RAID4). */
+		unsigned raid_parms;	/* # variable raid parameters. */
+
+		unsigned chunk_size;	/* Sectors per chunk. */
+		unsigned chunk_size_parm;
+		unsigned chunk_shift;	/* rsector chunk size shift. */
+
+		unsigned io_size;	/* Sectors per io. */
+		unsigned io_size_parm;
+		unsigned io_mask;	/* Mask for bio_copy_page_list(). */
+		unsigned io_inv_mask;	/* Mask for raid_address(). */
+
+		sector_t sectors_per_dev;	/* Sectors per device. */
+
+		atomic_t failed_devs;		/* Amount of devices failed. */
+
+		/* Index of device to initialize. */
+		int dev_to_init;
+		int dev_to_init_parm;
+
+		/* Raid devices dynamically allocated. */
+		unsigned raid_devs;	/* # of RAID devices below. */
+		unsigned data_devs;	/* # of RAID data devices. */
+
+		int ei;		/* index of failed RAID device. */
+
+		/* Index of dedicated parity device (i.e. RAID4). */
+		int pi;
+		int pi_parm;	/* constructor parm for status output. */
+	} set;
+
+	/* REMOVEME: devel stats counters. */
+	atomic_t stats[S_NR_STATS];
+
+	/* Dynamically allocated temporary pointers for xor(). */
+	unsigned long **data;
+
+	/* Dynamically allocated RAID devices. Alignment? */
+	struct raid_dev dev[0];
+};
+
+/* Define RAID set bit operations. */
+BITOPS(RS, Bandwidth, raid_set, RS_RECOVERY_BANDWIDTH)
+BITOPS(RS, CheckOverwrite, raid_set, RS_CHECK_OVERWRITE)
+BITOPS(RS, Dead, raid_set, RS_DEAD)
+BITOPS(RS, Degraded, raid_set, RS_DEGRADED)
+BITOPS(RS, DevelStats, raid_set, RS_DEVEL_STATS)
+BITOPS(RS, Recover, raid_set, RS_RECOVER)
+BITOPS(RS, ScBusy, raid_set, RS_SC_BUSY)
+BITOPS(RS, Suspend, raid_set, RS_SUSPEND)
+#undef BITOPS
+
+/*-----------------------------------------------------------------
+ * Raid-4/5 set structures.
+ *---------------------------------------------------------------*/
+/* RAID level definitions. */
+enum raid_level {
+	raid4,
+	raid5,
+};
+
+/* Symmetric/Asymmetric, Left/Right parity rotating algorithms. */
+enum raid_algorithm {
+	none,
+	left_asym,
+	right_asym,
+	left_sym,
+	right_sym,
+};
+
+struct raid_type {
+	const char *name;		/* RAID algorithm. */
+	const char *descr;		/* Descriptor text for logging. */
+	const unsigned parity_devs;	/* # of parity devices. */
+	const unsigned minimal_devs;	/* minimal # of devices in set. */
+	const enum raid_level level;		/* RAID level. */
+	const enum raid_algorithm algorithm;	/* RAID algorithm. */
+};
+
+/* Supported raid types and properties. */
+static struct raid_type raid_types[] = {
+	{"raid4",    "RAID4 (dedicated parity disk)", 1, 3, raid4, none},
+	{"raid5_la", "RAID5 (left asymmetric)",       1, 3, raid5, left_asym},
+	{"raid5_ra", "RAID5 (right asymmetric)",      1, 3, raid5, right_asym},
+	{"raid5_ls", "RAID5 (left symmetric)",        1, 3, raid5, left_sym},
+	{"raid5_rs", "RAID5 (right symmetric)",       1, 3, raid5, right_sym},
+};
+
+/* Address as calculated by raid_address(). */
+struct raid_address {
+	sector_t key;		/* Hash key (address of stripe % chunk_size). */
+	unsigned di, pi;	/* Data and parity disks index. */
+};
+
+/* REMOVEME: reset statistics counters. */
+static void stats_reset(struct raid_set *rs)
+{
+	unsigned s = S_NR_STATS;
+
+	while (s--)
+		atomic_set(rs->stats + s, 0);
+}
+
+/*----------------------------------------------------------------
+ * RAID set management routines.
+ *--------------------------------------------------------------*/
+/*
+ * Begin small helper functions.
+ */
+/* No need to be called from region hash indirectly at dm_rh_dec(). */
+static void wake_dummy(void *context) {}
+
+/* Return # of io reference. */
+static int io_ref(struct raid_set *rs)
+{
+	return atomic_read(&rs->io.in_process);
+}
+
+/* Get an io reference. */
+static void io_get(struct raid_set *rs)
+{
+	int p = atomic_inc_return(&rs->io.in_process);
+
+	if (p > atomic_read(&rs->io.in_process_max))
+		atomic_set(&rs->io.in_process_max, p); /* REMOVEME: max. */
+}
+
+/* Put the io reference and conditionally wake io waiters. */
+static void io_put(struct raid_set *rs)
+{
+	/* Intel: rebuild data corrupter? */
+	if (atomic_dec_and_test(&rs->io.in_process))
+		wake_up(&rs->io.suspendq);
+	else
+		BUG_ON(io_ref(rs) < 0);
+}
+
+/* Wait until all io has been processed. */
+static void wait_ios(struct raid_set *rs)
+{
+	wait_event(rs->io.suspendq, !io_ref(rs));
+}
+
+/* Queue (optionally delayed) io work. */
+static void wake_do_raid_delayed(struct raid_set *rs, unsigned long delay)
+{
+	queue_delayed_work(rs->io.wq, &rs->io.dws_do_raid, delay);
+}
+
+/* Queue io work immediately (called from region hash too). */
+static void wake_do_raid(void *context)
+{
+	struct raid_set *rs = context;
+
+	queue_work(rs->io.wq, &rs->io.dws_do_raid.work);
+}
+
+/* Calculate device sector offset. */
+static sector_t _sector(struct raid_set *rs, struct bio *bio)
+{
+	sector_t sector = bio->bi_sector;
+
+	sector_div(sector, rs->set.data_devs);
+	return sector;
+}
+
+/* Return # of active stripes in stripe cache. */
+static int sc_active(struct stripe_cache *sc)
+{
+	return atomic_read(&sc->active_stripes);
+}
+
+/* Stripe cache busy indicator. */
+static int sc_busy(struct raid_set *rs)
+{
+	return sc_active(&rs->sc) >
+	       atomic_read(&rs->sc.stripes) - (STRIPES_MIN / 2);
+}
+
+/* Set chunks states. */
+enum chunk_dirty_type { CLEAN, DIRTY, ERROR };
+static void chunk_set(struct stripe_chunk *chunk, enum chunk_dirty_type type)
+{
+	switch (type) {
+	case CLEAN:
+		ClearChunkDirty(chunk);
+		break;
+	case DIRTY:
+		SetChunkDirty(chunk);
+		break;
+	case ERROR:
+		SetChunkError(chunk);
+		SetStripeError(chunk->stripe);
+		return;
+	default:
+		BUG();
+	}
+
+	SetChunkUptodate(chunk);
+	SetChunkIo(chunk);
+	ClearChunkError(chunk);
+}
+
+/* Return region state for a sector. */
+static int region_state(struct raid_set *rs, sector_t sector, 
+			enum dm_rh_region_states state)
+{
+	struct dm_rh_client *rh = rs->recover.rh;
+	region_t region = dm_rh_sector_to_region(rh, sector);
+
+	return !!(dm_rh_get_state(rh, region, 1) & state);
+}
+
+/*
+ * Return true in case a chunk should be read/written
+ *
+ * Conditions to read/write:
+ *	o chunk not uptodate
+ *	o chunk dirty
+ *
+ * Conditios to avoid io:
+ *	o io already ongoing on chunk
+ *	o io explitely prohibited
+ */
+static int chunk_io(struct stripe_chunk *chunk)
+{
+	/* 2nd run optimization (flag set below on first run). */
+	if (TestClearChunkMustIo(chunk))
+		return 1;
+
+	/* Avoid io if prohibited or a locked chunk. */
+	if (!ChunkIo(chunk) || ChunkLocked(chunk))
+		return 0;
+
+	if (!ChunkUptodate(chunk) || ChunkDirty(chunk)) {
+		SetChunkMustIo(chunk); /* 2nd run optimization. */
+		return 1;
+	}
+
+	return 0;
+}
+
+/* Call a function on each chunk needing io unless device failed. */
+static unsigned for_each_io_dev(struct stripe *stripe,
+			        void (*f_io)(struct stripe *stripe, unsigned p))
+{
+	struct raid_set *rs = RS(stripe->sc);
+	unsigned p, r = 0;
+
+	for (p = 0; p < rs->set.raid_devs; p++) {
+		if (chunk_io(CHUNK(stripe, p)) && !DevFailed(rs->dev + p)) {
+			f_io(stripe, p);
+			r++;
+		}
+	}
+
+	return r;
+}
+
+/*
+ * Index of device to calculate parity on.
+ *
+ * Either the parity device index *or* the selected
+ * device to init after a spare replacement.
+ */
+static int dev_for_parity(struct stripe *stripe, int *sync)
+{
+	struct raid_set *rs = RS(stripe->sc);
+	int r = region_state(rs, stripe->key, DM_RH_NOSYNC | DM_RH_RECOVERING);
+
+	*sync = !r;
+
+	/* Reconstruct a particular device ?. */
+	if (r && rs->set.dev_to_init > -1)
+		return rs->set.dev_to_init;
+	else if (rs->set.raid_type->level == raid4)
+		return rs->set.pi;
+	else if (!StripeRecover(stripe))
+		return stripe->idx.parity;
+	else
+		return -1;
+}
+
+/* RAID set congested function. */
+static int rs_congested(void *congested_data, int bdi_bits)
+{
+	int r;
+	unsigned p;
+	struct raid_set *rs = congested_data;
+
+	if (sc_busy(rs) || RSSuspend(rs))
+		r = 1;
+	else for (r = 0, p = rs->set.raid_devs; !r && p--; ) {
+		/* If any of our component devices are overloaded. */
+		struct request_queue *q = bdev_get_queue(rs->dev[p].dev->bdev);
+
+		r |= bdi_congested(&q->backing_dev_info, bdi_bits);
+	}
+
+	/* REMOVEME: statistics. */
+	atomic_inc(rs->stats + (r ? S_CONGESTED : S_NOT_CONGESTED));
+	return r;
+}
+
+/* RAID device degrade check. */
+static void rs_check_degrade_dev(struct raid_set *rs,
+				       struct stripe *stripe, unsigned p)
+{
+	if (TestSetDevFailed(rs->dev + p))
+		return;
+
+	/* Through an event in case of member device errors. */
+	if (atomic_inc_return(&rs->set.failed_devs) >
+	    rs->set.raid_type->parity_devs &&
+	    !TestSetRSDead(rs)) {
+		/* Display RAID set dead message once. */
+		unsigned p;
+		char buf[BDEVNAME_SIZE];
+
+		DMERR("FATAL: too many devices failed -> RAID set broken");
+		for (p = 0; p < rs->set.raid_devs; p++) {
+			if (DevFailed(rs->dev + p))
+				DMERR("device /dev/%s failed",
+				      bdevname(rs->dev[p].dev->bdev, buf));
+		}
+	}
+
+	/* Only log the first member error. */
+	if (!TestSetRSDegraded(rs)) {
+		char buf[BDEVNAME_SIZE];
+
+		/* Store index for recovery. */
+		rs->set.ei = p;
+		DMERR("CRITICAL: %sio error on device /dev/%s "
+		      "in region=%llu; DEGRADING RAID set\n",
+		      stripe ? "" : "FAKED ",
+		      bdevname(rs->dev[p].dev->bdev, buf),
+		      (unsigned long long) (stripe ? stripe->key : 0));
+		DMERR("further device error messages suppressed");
+	}
+
+	schedule_work(&rs->io.ws_do_table_event);
+}
+
+/* RAID set degrade check. */
+static void rs_check_degrade(struct stripe *stripe)
+{
+	struct raid_set *rs = RS(stripe->sc);
+	unsigned p = rs->set.raid_devs;
+
+	while (p--) {
+		if (ChunkError(CHUNK(stripe, p)))
+			rs_check_degrade_dev(rs, stripe, p);
+	}
+}
+
+/* Lookup a RAID device by name or by major:minor number. */
+static int raid_dev_lookup(struct raid_set *rs, struct raid_dev *dev_lookup)
+{
+	unsigned p;
+	struct raid_dev *dev;
+
+	/*
+	 * Must be an incremental loop, because the device array
+	 * can have empty slots still on calls from raid_ctr()
+	 */
+	for (dev = rs->dev, p = 0;
+	     dev->dev && p < rs->set.raid_devs;
+	     dev++, p++) {
+		if (dev_lookup->dev->bdev->bd_dev == dev->dev->bdev->bd_dev)
+			return p;
+	}
+
+	return -ENODEV;
+}
+/*
+ * End small helper functions.
+ */
+
+/*
+ * Stripe hash functions
+ */
+/* Initialize/destroy stripe hash. */
+static int hash_init(struct stripe_hash *hash, unsigned stripes)
+{
+	unsigned buckets = 2, max_buckets = stripes >> 1;
+	static unsigned hash_primes[] = {
+		/* Table of primes for hash_fn/table size optimization. */
+		1, 2, 3, 7, 13, 27, 53, 97, 193, 389, 769,
+		1543, 3079, 6151, 12289, 24593, 49157, 98317,
+	};
+
+	/* Calculate number of buckets (2^^n <= stripes / 2). */
+	while (buckets < max_buckets)
+		buckets <<= 1;
+
+	/* Allocate stripe hash buckets. */
+	hash->hash = vmalloc(buckets * sizeof(*hash->hash));
+	if (!hash->hash)
+		return -ENOMEM;
+
+	hash->buckets = buckets;
+	hash->mask = buckets - 1;
+	hash->shift = ffs(buckets);
+	if (hash->shift > ARRAY_SIZE(hash_primes))
+		hash->shift = ARRAY_SIZE(hash_primes) - 1;
+
+	BUG_ON(hash->shift < 2);
+	hash->prime = hash_primes[hash->shift];
+
+	/* Initialize buckets. */
+	while (buckets--)
+		INIT_LIST_HEAD(hash->hash + buckets);
+	return 0;
+}
+
+static void hash_exit(struct stripe_hash *hash)
+{
+	if (hash->hash) {
+		vfree(hash->hash);
+		hash->hash = NULL;
+	}
+}
+
+static unsigned hash_fn(struct stripe_hash *hash, sector_t key)
+{
+	return (unsigned) (((key * hash->prime) >> hash->shift) & hash->mask);
+}
+
+static struct list_head *hash_bucket(struct stripe_hash *hash, sector_t key)
+{
+	return hash->hash + hash_fn(hash, key);
+}
+
+/* Insert an entry into a hash. */
+static void stripe_insert(struct stripe_hash *hash, struct stripe *stripe)
+{
+	list_add(stripe->lists + LIST_HASH, hash_bucket(hash, stripe->key));
+}
+
+/* Lookup an entry in the stripe hash. */
+static struct stripe *stripe_lookup(struct stripe_cache *sc, sector_t key)
+{
+	unsigned look = 0;
+	struct stripe *stripe;
+	struct list_head *bucket = hash_bucket(&sc->hash, key);
+
+	list_for_each_entry(stripe, bucket, lists[LIST_HASH]) {
+		look++;
+
+		if (stripe->key == key) {
+			/* REMOVEME: statisics. */
+			if (look > atomic_read(RS(sc)->stats + S_MAX_LOOKUP))
+				atomic_set(RS(sc)->stats + S_MAX_LOOKUP, look);
+			return stripe;
+		}
+	}
+
+	return NULL;
+}
+
+/* Resize the stripe cache hash on size changes. */
+static int sc_hash_resize(struct stripe_cache *sc)
+{
+	/* Resize indicated ? */
+	if (atomic_read(&sc->stripes) != atomic_read(&sc->stripes_last)) {
+		int r;
+		struct stripe_hash hash;
+
+		r = hash_init(&hash, atomic_read(&sc->stripes));
+		if (r)
+			return r;
+
+		if (sc->hash.hash) {
+			unsigned b = sc->hash.buckets;
+			struct list_head *pos, *tmp;
+
+			/* Walk old buckets and insert into new. */
+			while (b--) {
+				list_for_each_safe(pos, tmp, sc->hash.hash + b)
+				    stripe_insert(&hash,
+						  list_entry(pos, struct stripe,
+							     lists[LIST_HASH]));
+			}
+
+		}
+
+		hash_exit(&sc->hash);
+		memcpy(&sc->hash, &hash, sizeof(sc->hash));
+		atomic_set(&sc->stripes_last, atomic_read(&sc->stripes));
+	}
+
+	return 0;
+}
+/* End hash stripe hash function. */
+
+/* List add, delete, push and pop functions. */
+/* Add stripe to flush list. */
+#define	DEL_LIST(lh) \
+	if (!list_empty(lh)) \
+		list_del_init(lh);
+
+/* Delete stripe from hash. */
+static void stripe_hash_del(struct stripe *stripe)
+{
+	DEL_LIST(stripe->lists + LIST_HASH);
+}
+
+/* Return stripe reference count. */
+static inline int stripe_ref(struct stripe *stripe)
+{
+	return atomic_read(&stripe->cnt);
+}
+
+static void stripe_flush_add(struct stripe *stripe)
+{
+	struct stripe_cache *sc = stripe->sc;
+	struct list_head *lh = stripe->lists + LIST_FLUSH;
+
+	if (!StripeReconstruct(stripe) && list_empty(lh))
+		list_add_tail(lh, sc->lists + LIST_FLUSH);
+}
+
+/*
+ * Add stripe to LRU (inactive) list.
+ *
+ * Need lock, because of concurrent access from message interface.
+ */
+static void stripe_lru_add(struct stripe *stripe)
+{
+	if (!StripeRecover(stripe)) {
+		unsigned long flags;
+		struct list_head *lh = stripe->lists + LIST_LRU;
+		spinlock_t *lock = stripe->sc->locks + LOCK_LRU;
+
+		spin_lock_irqsave(lock, flags);
+		if (list_empty(lh))
+			list_add_tail(lh, stripe->sc->lists + LIST_LRU);
+		spin_unlock_irqrestore(lock, flags);
+	}
+}
+
+#define POP_LIST(list) \
+	do { \
+		if (list_empty(sc->lists + (list))) \
+			stripe = NULL; \
+		else { \
+			stripe = list_first_entry(sc->lists + (list), \
+						  struct stripe, \
+						  lists[(list)]); \
+			list_del_init(stripe->lists + (list)); \
+		} \
+	} while (0);
+
+/* Pop an available stripe off the LRU list. */
+static struct stripe *stripe_lru_pop(struct stripe_cache *sc)
+{
+	struct stripe *stripe;
+	spinlock_t *lock = sc->locks + LOCK_LRU;
+
+	spin_lock_irq(lock);
+	POP_LIST(LIST_LRU);
+	spin_unlock_irq(lock);
+
+	return stripe;
+}
+
+/* Pop an available stripe off the io list. */
+static struct stripe *stripe_io_pop(struct stripe_cache *sc)
+{
+	struct stripe *stripe;
+
+	POP_LIST(LIST_FLUSH);
+	return stripe;
+}
+
+/* Push a stripe safely onto the endio list to be handled by do_endios(). */
+static void stripe_endio_push(struct stripe *stripe)
+{
+	unsigned long flags;
+	struct stripe_cache *sc = stripe->sc;
+	struct list_head *stripe_list = stripe->lists + LIST_ENDIO,
+			 *sc_list = sc->lists + LIST_ENDIO;
+	spinlock_t *lock = sc->locks + LOCK_ENDIO;
+
+	/* This runs in parallel with do_endios(). */
+	spin_lock_irqsave(lock, flags);
+	if (list_empty(stripe_list))
+		list_add_tail(stripe_list, sc_list);
+	spin_unlock_irqrestore(lock, flags);
+
+	wake_do_raid(RS(sc)); /* Wake myself. */
+}
+
+/* Pop a stripe off safely off the endio list. */
+static struct stripe *stripe_endio_pop(struct stripe_cache *sc)
+{
+	struct stripe *stripe;
+	spinlock_t *lock = sc->locks + LOCK_ENDIO;
+
+	/* This runs in parallel with endio(). */
+	spin_lock_irq(lock);
+	POP_LIST(LIST_ENDIO)
+	spin_unlock_irq(lock);
+	return stripe;
+}
+#undef POP_LIST
+
+/*
+ * Stripe cache locking functions
+ */
+/* Dummy lock function for single host RAID4+5. */
+static void *no_lock(sector_t key, enum dm_lock_type type)
+{
+	return &no_lock;
+}
+
+/* Dummy unlock function for single host RAID4+5. */
+static void no_unlock(void *lock_handle)
+{
+}
+
+/* No locking (for single host RAID 4+5). */
+static struct dm_raid45_locking_type locking_none = {
+	.lock = no_lock,
+	.unlock = no_unlock,
+};
+
+/* Lock a stripe (for clustering). */
+static int
+stripe_lock(struct stripe *stripe, int rw, sector_t key)
+{
+	stripe->lock = RS(stripe->sc)->locking->lock(key, rw == READ ? DM_RAID45_SHARED : DM_RAID45_EX);
+	return stripe->lock ? 0 : -EPERM;
+}
+
+/* Unlock a stripe (for clustering). */
+static void stripe_unlock(struct stripe *stripe)
+{
+	RS(stripe->sc)->locking->unlock(stripe->lock);
+	stripe->lock = NULL;
+}
+
+/* Test io pending on stripe. */
+static int stripe_io_ref(struct stripe *stripe)
+{
+	return atomic_read(&stripe->io.pending);
+}
+
+static void stripe_io_get(struct stripe *stripe)
+{
+	if (atomic_inc_return(&stripe->io.pending) == 1)
+		/* REMOVEME: statistics */
+		atomic_inc(&stripe->sc->active_stripes);
+	else
+		BUG_ON(stripe_io_ref(stripe) < 0);
+}
+
+static void stripe_io_put(struct stripe *stripe)
+{
+	if (atomic_dec_and_test(&stripe->io.pending)) {
+		if (unlikely(StripeRecover(stripe)))
+			/* Don't put recovery stripe on endio list. */
+			wake_do_raid(RS(stripe->sc));
+		else
+			/* Add regular stripe to endio list and wake daemon. */
+			stripe_endio_push(stripe);
+
+		/* REMOVEME: statistics */
+		atomic_dec(&stripe->sc->active_stripes);
+	} else
+		BUG_ON(stripe_io_ref(stripe) < 0);
+}
+
+/* Take stripe reference out. */
+static int stripe_get(struct stripe *stripe)
+{
+	int r;
+	struct list_head *lh = stripe->lists + LIST_LRU;
+	spinlock_t *lock = stripe->sc->locks + LOCK_LRU;
+
+	/* Delete stripe from LRU (inactive) list if on. */
+	spin_lock_irq(lock);
+	DEL_LIST(lh);
+	spin_unlock_irq(lock);
+
+	BUG_ON(stripe_ref(stripe) < 0);
+
+	/* Lock stripe on first reference */
+	r = (atomic_inc_return(&stripe->cnt) == 1) ?
+	    stripe_lock(stripe, WRITE, stripe->key) : 0;
+
+	return r;
+}
+#undef DEL_LIST
+
+/* Return references on a chunk. */
+static int chunk_ref(struct stripe_chunk *chunk)
+{
+	return atomic_read(&chunk->cnt);
+}
+
+/* Take out reference on a chunk. */
+static int chunk_get(struct stripe_chunk *chunk)
+{
+	return atomic_inc_return(&chunk->cnt);
+}
+
+/* Drop reference on a chunk. */
+static void chunk_put(struct stripe_chunk *chunk)
+{
+	BUG_ON(atomic_dec_return(&chunk->cnt) < 0);
+}
+
+/*
+ * Drop reference on a stripe.
+ *
+ * Move it to list of LRU stripes if zero.
+ */
+static void stripe_put(struct stripe *stripe)
+{
+	if (atomic_dec_and_test(&stripe->cnt)) {
+		BUG_ON(stripe_io_ref(stripe));
+		stripe_unlock(stripe);
+	} else
+		BUG_ON(stripe_ref(stripe) < 0);
+}
+
+/* Helper needed by for_each_io_dev(). */
+static void stripe_get_references(struct stripe *stripe, unsigned p)
+{
+
+	/*
+	 * Another one to reference the stripe in
+	 * order to protect vs. LRU list moves.
+	 */
+	io_get(RS(stripe->sc));	/* Global io references. */
+	stripe_get(stripe);
+	stripe_io_get(stripe);	/* One for each chunk io. */
+}
+
+/* Helper for endio() to put all take references. */
+static void stripe_put_references(struct stripe *stripe)
+{
+	stripe_io_put(stripe);	/* One for each chunk io. */
+	stripe_put(stripe);
+	io_put(RS(stripe->sc));
+}
+
+/*
+ * Stripe cache functions.
+ */
+/*
+ * Invalidate all chunks (i.e. their pages)  of a stripe.
+ *
+ * I only keep state for the whole chunk.
+ */
+static inline void stripe_chunk_invalidate(struct stripe_chunk *chunk)
+{
+	chunk->io.flags = 0;
+}
+
+static void
+stripe_chunks_invalidate(struct stripe *stripe)
+{
+	unsigned p = RS(stripe->sc)->set.raid_devs;
+
+	while (p--)
+		stripe_chunk_invalidate(CHUNK(stripe, p));
+}
+
+/* Prepare stripe for (re)use. */
+static void stripe_invalidate(struct stripe *stripe)
+{
+	stripe->io.flags = 0;
+	stripe->idx.parity = stripe->idx.recover = -1;
+	stripe_chunks_invalidate(stripe);
+}
+
+/*
+ * Allow io on all chunks of a stripe.
+ * If not set, IO will not occur; i.e. it's prohibited.
+ *
+ * Actual IO submission for allowed chunks depends
+ * on their !uptodate or dirty state.
+ */
+static void stripe_allow_io(struct stripe *stripe)
+{
+	unsigned p = RS(stripe->sc)->set.raid_devs;
+
+	while (p--)
+		SetChunkIo(CHUNK(stripe, p));
+}
+
+/* Initialize a stripe. */
+static void stripe_init(struct stripe_cache *sc, struct stripe *stripe)
+{
+	unsigned i, p = RS(sc)->set.raid_devs;
+
+	/* Work all io chunks. */
+	while (p--) {
+		struct stripe_chunk *chunk = CHUNK(stripe, p);
+
+		atomic_set(&chunk->cnt, 0);
+		chunk->stripe = stripe;
+		i = ARRAY_SIZE(chunk->bl);
+		while (i--)
+			bio_list_init(chunk->bl + i);
+	}
+
+	stripe->sc = sc;
+
+
+	i = ARRAY_SIZE(stripe->lists);
+	while (i--)
+		INIT_LIST_HEAD(stripe->lists + i);
+
+	stripe->io.size = RS(sc)->set.io_size;
+	atomic_set(&stripe->cnt, 0);
+	atomic_set(&stripe->io.pending, 0);
+	stripe_invalidate(stripe);
+}
+
+/* Number of pages per chunk. */
+static inline unsigned chunk_pages(unsigned sectors)
+{
+	return dm_div_up(sectors, SECTORS_PER_PAGE);
+}
+
+/* Number of pages per stripe. */
+static inline unsigned stripe_pages(struct raid_set *rs, unsigned io_size)
+{
+	return chunk_pages(io_size) * rs->set.raid_devs;
+}
+
+/* Initialize part of page_list (recovery). */
+static void stripe_zero_pl_part(struct stripe *stripe, int p,
+				unsigned start, unsigned count)
+{
+	unsigned o = start / SECTORS_PER_PAGE, pages = chunk_pages(count);
+	/* Get offset into the page_list. */
+	struct page_list *pl = pl_elem(PL(stripe, p), o);
+
+	BUG_ON(!pl);
+	while (pl && pages--) {
+		BUG_ON(!pl->page);
+		memset(page_address(pl->page), 0, PAGE_SIZE);
+		pl = pl->next;
+	}
+}
+
+/* Initialize parity chunk of stripe. */
+static void stripe_zero_chunk(struct stripe *stripe, int p)
+{
+	if (p > -1)
+		stripe_zero_pl_part(stripe, p, 0, stripe->io.size);
+}
+
+/* Return dynamic stripe structure size. */
+static size_t stripe_size(struct raid_set *rs)
+{
+	return sizeof(struct stripe) +
+		      rs->set.raid_devs * sizeof(struct stripe_chunk);
+}
+
+/* Allocate a stripe and its memory object. */
+/* XXX adjust to cope with stripe cache and recovery stripe caches. */
+enum grow { SC_GROW, SC_KEEP };
+static struct stripe *stripe_alloc(struct stripe_cache *sc,
+				   struct dm_mem_cache_client *mc,
+				   enum grow grow)
+{
+	int r;
+	struct stripe *stripe;
+
+	stripe = kmem_cache_zalloc(sc->kc.cache, GFP_KERNEL);
+	if (stripe) {
+		/* Grow the dm-mem-cache by one object. */
+		if (grow == SC_GROW) {
+			r = dm_mem_cache_grow(mc, 1);
+			if (r)
+				goto err_free;
+		}
+
+		stripe->obj = dm_mem_cache_alloc(mc);
+		if (!stripe->obj)
+			goto err_shrink;
+
+		stripe_init(sc, stripe);
+	}
+
+	return stripe;
+
+err_shrink:
+	if (grow == SC_GROW)
+		dm_mem_cache_shrink(mc, 1);
+err_free:
+	kmem_cache_free(sc->kc.cache, stripe);
+	return NULL;
+}
+
+/*
+ * Free a stripes memory object, shrink the
+ * memory cache and free the stripe itself.
+ */
+static void stripe_free(struct stripe *stripe, struct dm_mem_cache_client *mc)
+{
+	dm_mem_cache_free(mc, stripe->obj);
+	dm_mem_cache_shrink(mc, 1);
+	kmem_cache_free(stripe->sc->kc.cache, stripe);
+}
+
+/* Free the recovery stripe. */
+static void stripe_recover_free(struct raid_set *rs)
+{
+	struct recover *rec = &rs->recover;
+	struct dm_mem_cache_client *mc;
+
+	mc = rec->mem_cache_client;
+	rec->mem_cache_client = NULL;
+	if (mc) {
+		struct stripe *stripe;
+
+		while (!list_empty(&rec->stripes)) {
+			stripe = list_first_entry(&rec->stripes, struct stripe,
+						  lists[LIST_RECOVER]);
+			list_del(stripe->lists + LIST_RECOVER);
+			kfree(stripe->recover);
+			stripe_free(stripe, mc);
+		}
+	
+		dm_mem_cache_client_destroy(mc);
+		dm_io_client_destroy(rec->dm_io_client);
+		rec->dm_io_client = NULL;
+	}
+}
+
+/* Grow stripe cache. */
+static int sc_grow(struct stripe_cache *sc, unsigned stripes, enum grow grow)
+{
+	int r = 0;
+
+	/* Try to allocate this many (additional) stripes. */
+	while (stripes--) {
+		struct stripe *stripe =
+			stripe_alloc(sc, sc->mem_cache_client, grow);
+
+		if (likely(stripe)) {
+			stripe_lru_add(stripe);
+			atomic_inc(&sc->stripes);
+		} else {
+			r = -ENOMEM;
+			break;
+		}
+	}
+
+	return r ? r : sc_hash_resize(sc);
+}
+
+/* Shrink stripe cache. */
+static int sc_shrink(struct stripe_cache *sc, unsigned stripes)
+{
+	int r = 0;
+
+	/* Try to get unused stripe from LRU list. */
+	while (stripes--) {
+		struct stripe *stripe;
+
+		stripe = stripe_lru_pop(sc);
+		if (stripe) {
+			/* An LRU stripe may never have ios pending! */
+			BUG_ON(stripe_io_ref(stripe));
+			BUG_ON(stripe_ref(stripe));
+			atomic_dec(&sc->stripes);
+			/* Remove from hash if on before deletion. */
+			stripe_hash_del(stripe);
+			stripe_free(stripe, sc->mem_cache_client);
+		} else {
+			r = -ENOENT;
+			break;
+		}
+	}
+
+	/* Check if stats are still sane. */
+	if (atomic_read(&sc->active_stripes_max) >
+	    atomic_read(&sc->stripes))
+		atomic_set(&sc->active_stripes_max, 0);
+
+	if (r)
+		return r;
+
+	return atomic_read(&sc->stripes) ? sc_hash_resize(sc) : 0;
+}
+
+/* Create stripe cache and recovery. */
+static int sc_init(struct raid_set *rs, unsigned stripes)
+{
+	unsigned i, r, rstripes;
+	struct stripe_cache *sc = &rs->sc;
+	struct stripe *stripe;
+	struct recover *rec = &rs->recover;
+	struct mapped_device *md;
+	struct gendisk *disk;
+
+	/* Initialize lists and locks. */
+	i = ARRAY_SIZE(sc->lists);
+	while (i--)
+		INIT_LIST_HEAD(sc->lists + i);
+
+	INIT_LIST_HEAD(&rec->stripes);
+
+	/* Initialize endio and LRU list locks. */
+	i = NR_LOCKS;
+	while (i--)
+		spin_lock_init(sc->locks + i);
+
+	/* Initialize atomic variables. */
+	atomic_set(&sc->stripes, 0);
+	atomic_set(&sc->stripes_to_set, 0);
+	atomic_set(&sc->active_stripes, 0);
+	atomic_set(&sc->active_stripes_max, 0);	/* REMOVEME: statistics. */
+
+	/*
+	 * We need a runtime unique # to suffix the kmem cache name
+	 * because we'll have one for each active RAID set.
+	 */
+	md = dm_table_get_md(rs->ti->table);
+	disk = dm_disk(md);
+	sprintf(sc->kc.name, "%s-%d", TARGET, disk->first_minor);
+	dm_put(md);
+	sc->kc.cache = kmem_cache_create(sc->kc.name, stripe_size(rs),
+					 0, 0, NULL);
+	if (!sc->kc.cache)
+		return -ENOMEM;
+
+	/* Create memory cache client context for RAID stripe cache. */
+	sc->mem_cache_client =
+		dm_mem_cache_client_create(stripes, rs->set.raid_devs,
+					   chunk_pages(rs->set.io_size));
+	if (IS_ERR(sc->mem_cache_client))
+		return PTR_ERR(sc->mem_cache_client);
+
+	/* Create memory cache client context for RAID recovery stripe(s). */
+	rstripes = rec->recovery_stripes;
+	rec->mem_cache_client =
+		dm_mem_cache_client_create(rstripes, rs->set.raid_devs,
+					   chunk_pages(rec->io_size));
+	if (IS_ERR(rec->mem_cache_client))
+		return PTR_ERR(rec->mem_cache_client);
+
+	/* Create dm-io client context for IO stripes. */
+	sc->dm_io_client =
+		dm_io_client_create();
+	if (IS_ERR(sc->dm_io_client))
+		return PTR_ERR(sc->dm_io_client);
+
+	/* FIXME: intermingeled with stripe cache initialization. */
+	/* Create dm-io client context for recovery stripes. */
+	rec->dm_io_client =
+		dm_io_client_create();
+	if (IS_ERR(rec->dm_io_client))
+		return PTR_ERR(rec->dm_io_client);
+
+	/* Allocate stripes for set recovery. */
+	while (rstripes--) {
+		stripe = stripe_alloc(sc, rec->mem_cache_client, SC_KEEP);
+		if (!stripe)
+			return -ENOMEM;
+
+		stripe->recover = kzalloc(sizeof(*stripe->recover), GFP_KERNEL);
+		if (!stripe->recover) {
+			stripe_free(stripe, rec->mem_cache_client);
+			return -ENOMEM;
+		}
+
+		SetStripeRecover(stripe);
+		stripe->io.size = rec->io_size;
+		list_add_tail(stripe->lists + LIST_RECOVER, &rec->stripes);
+		/* Don't add recovery stripes to LRU list! */
+	}
+
+	/*
+	 * Allocate the stripe objetcs from the
+	 * cache and add them to the LRU list.
+	 */
+	r = sc_grow(sc, stripes, SC_KEEP);
+	if (!r)
+		atomic_set(&sc->stripes_last, stripes);
+
+	return r;
+}
+
+/* Destroy the stripe cache. */
+static void sc_exit(struct stripe_cache *sc)
+{
+	struct raid_set *rs = RS(sc);
+
+	if (sc->kc.cache) {
+		stripe_recover_free(rs);
+		BUG_ON(sc_shrink(sc, atomic_read(&sc->stripes)));
+		kmem_cache_destroy(sc->kc.cache);
+		sc->kc.cache = NULL;
+
+		if (sc->mem_cache_client && !IS_ERR(sc->mem_cache_client))
+			dm_mem_cache_client_destroy(sc->mem_cache_client);
+
+		if (sc->dm_io_client && !IS_ERR(sc->dm_io_client))
+			dm_io_client_destroy(sc->dm_io_client);
+
+		hash_exit(&sc->hash);
+	}
+}
+
+/*
+ * Calculate RAID address
+ *
+ * Delivers tuple with the index of the data disk holding the chunk
+ * in the set, the parity disks index and the start of the stripe
+ * within the address space of the set (used as the stripe cache hash key).
+ */
+/* thx MD. */
+static struct raid_address *raid_address(struct raid_set *rs, sector_t sector,
+					 struct raid_address *addr)
+{
+	sector_t stripe, tmp;
+
+	/*
+	 * chunk_number = sector / chunk_size
+	 * stripe_number = chunk_number / data_devs
+	 * di = stripe % data_devs;
+	 */
+	stripe = sector >> rs->set.chunk_shift;
+	addr->di = sector_div(stripe, rs->set.data_devs);
+
+	switch (rs->set.raid_type->level) {
+	case raid4:
+		addr->pi = rs->set.pi;
+		goto check_shift_di;
+	case raid5:
+		tmp = stripe;
+		addr->pi = sector_div(tmp, rs->set.raid_devs);
+
+		switch (rs->set.raid_type->algorithm) {
+		case left_asym:		/* Left asymmetric. */
+			addr->pi = rs->set.data_devs - addr->pi;
+		case right_asym:	/* Right asymmetric. */
+check_shift_di:
+			if (addr->di >= addr->pi)
+				addr->di++;
+			break;
+		case left_sym:		/* Left symmetric. */
+			addr->pi = rs->set.data_devs - addr->pi;
+		case right_sym:		/* Right symmetric. */
+			addr->di = (addr->pi + addr->di + 1) %
+				   rs->set.raid_devs;
+			break;
+		case none: /* Ain't happen: RAID4 algorithm placeholder. */
+			BUG();
+		}
+	}
+
+	/*
+	 * Start offset of the stripes chunk on any single device of the RAID
+	 * set, adjusted in case io size differs from chunk size.
+	 */
+	addr->key = (stripe << rs->set.chunk_shift) +
+		    (sector & rs->set.io_inv_mask);
+	return addr;
+}
+
+/*
+ * Copy data across between stripe pages and bio vectors.
+ *
+ * Pay attention to data alignment in stripe and bio pages.
+ */
+static void bio_copy_page_list(int rw, struct stripe *stripe,
+			       struct page_list *pl, struct bio *bio)
+{
+	unsigned i, page_offset;
+	void *page_addr;
+	struct raid_set *rs = RS(stripe->sc);
+	struct bio_vec *bv;
+
+	/* Get start page in page list for this sector. */
+	i = (bio->bi_sector & rs->set.io_mask) / SECTORS_PER_PAGE;
+	pl = pl_elem(pl, i);
+	BUG_ON(!pl);
+	BUG_ON(!pl->page);
+
+	page_addr = page_address(pl->page);
+	page_offset = to_bytes(bio->bi_sector & (SECTORS_PER_PAGE - 1));
+
+	/* Walk all segments and copy data across between bio_vecs and pages. */
+	bio_for_each_segment(bv, bio, i) {
+		int len = bv->bv_len, size;
+		unsigned bio_offset = 0;
+		void *bio_addr = __bio_kmap_atomic(bio, i, KM_USER0);
+redo:
+		size = (page_offset + len > PAGE_SIZE) ?
+		       PAGE_SIZE - page_offset : len;
+
+		if (rw == READ)
+			memcpy(bio_addr + bio_offset,
+			       page_addr + page_offset, size);
+		else
+			memcpy(page_addr + page_offset,
+			       bio_addr + bio_offset, size);
+
+		page_offset += size;
+		if (page_offset == PAGE_SIZE) {
+			/*
+			 * We reached the end of the chunk page ->
+			 * need to refer to the next one to copy more data.
+			 */
+			len -= size;
+			if (len) {
+				/* Get next page. */
+				pl = pl->next;
+				BUG_ON(!pl);
+				BUG_ON(!pl->page);
+				page_addr = page_address(pl->page);
+				page_offset = 0;
+				bio_offset += size;
+				/* REMOVEME: statistics. */
+				atomic_inc(rs->stats + S_BIO_COPY_PL_NEXT);
+				goto redo;
+			}
+		}
+
+		__bio_kunmap_atomic(bio_addr, KM_USER0);
+	}
+}
+
+/*
+ * Xor optimization macros.
+ */
+/* Xor data pointer declaration and initialization macros. */
+#define DECLARE_2	unsigned long *d0 = data[0], *d1 = data[1]
+#define DECLARE_3	DECLARE_2, *d2 = data[2]
+#define DECLARE_4	DECLARE_3, *d3 = data[3]
+#define DECLARE_5	DECLARE_4, *d4 = data[4]
+#define DECLARE_6	DECLARE_5, *d5 = data[5]
+#define DECLARE_7	DECLARE_6, *d6 = data[6]
+#define DECLARE_8	DECLARE_7, *d7 = data[7]
+
+/* Xor unrole macros. */
+#define D2(n)	d0[n] = d0[n] ^ d1[n]
+#define D3(n)	D2(n) ^ d2[n]
+#define D4(n)	D3(n) ^ d3[n]
+#define D5(n)	D4(n) ^ d4[n]
+#define D6(n)	D5(n) ^ d5[n]
+#define D7(n)	D6(n) ^ d6[n]
+#define D8(n)	D7(n) ^ d7[n]
+
+#define	X_2(macro, offset)	macro(offset); macro(offset + 1);
+#define	X_4(macro, offset)	X_2(macro, offset); X_2(macro, offset + 2);
+#define	X_8(macro, offset)	X_4(macro, offset); X_4(macro, offset + 4);
+#define	X_16(macro, offset)	X_8(macro, offset); X_8(macro, offset + 8);
+#define	X_32(macro, offset)	X_16(macro, offset); X_16(macro, offset + 16);
+#define	X_64(macro, offset)	X_32(macro, offset); X_32(macro, offset + 32);
+
+/* Define a _xor_#chunks_#xors_per_run() function. */
+#define	_XOR(chunks, xors_per_run) \
+static void _xor ## chunks ## _ ## xors_per_run(unsigned long **data) \
+{ \
+	unsigned end = XOR_SIZE / sizeof(data[0]), i; \
+	DECLARE_ ## chunks; \
+\
+	for (i = 0; i < end; i += xors_per_run) { \
+		X_ ## xors_per_run(D ## chunks, i); \
+	} \
+}
+
+/* Define xor functions for 2 - 8 chunks and xors per run. */
+#define	MAKE_XOR_PER_RUN(xors_per_run) \
+	_XOR(2, xors_per_run); _XOR(3, xors_per_run); \
+	_XOR(4, xors_per_run); _XOR(5, xors_per_run); \
+	_XOR(6, xors_per_run); _XOR(7, xors_per_run); \
+	_XOR(8, xors_per_run);
+
+MAKE_XOR_PER_RUN(8)	/* Define _xor_*_8() functions. */
+MAKE_XOR_PER_RUN(16)	/* Define _xor_*_16() functions. */
+MAKE_XOR_PER_RUN(32)	/* Define _xor_*_32() functions. */
+MAKE_XOR_PER_RUN(64)	/* Define _xor_*_64() functions. */
+
+#define MAKE_XOR(xors_per_run) \
+struct { \
+	void (*f)(unsigned long **); \
+} static xor_funcs ## xors_per_run[] = { \
+	{ NULL }, /* NULL pointers to optimize indexing in xor(). */ \
+	{ NULL }, \
+	{ _xor2_ ## xors_per_run }, \
+	{ _xor3_ ## xors_per_run }, \
+	{ _xor4_ ## xors_per_run }, \
+	{ _xor5_ ## xors_per_run }, \
+	{ _xor6_ ## xors_per_run }, \
+	{ _xor7_ ## xors_per_run }, \
+	{ _xor8_ ## xors_per_run }, \
+}; \
+\
+static void xor_ ## xors_per_run(unsigned n, unsigned long **data) \
+{ \
+	/* Call respective function for amount of chunks. */ \
+	xor_funcs ## xors_per_run[n].f(data); \
+}
+
+/* Define xor_8() - xor_64 functions. */
+MAKE_XOR(8)
+MAKE_XOR(16)
+MAKE_XOR(32)
+MAKE_XOR(64)
+
+/* Maximum number of chunks, which can be xor'ed in one go. */
+#define	XOR_CHUNKS_MAX	(ARRAY_SIZE(xor_funcs8) - 1)
+
+static void xor_blocks_wrapper(unsigned n, unsigned long **data)
+{
+	BUG_ON(n < 2 || n > MAX_XOR_BLOCKS + 1);
+	xor_blocks(n - 1, XOR_SIZE, (void *) data[0], (void **) data + 1);
+}
+
+struct xor_func {
+	xor_function_t f;
+	const char *name;
+} static xor_funcs[] = {
+	{ xor_8,   "xor_8"  },
+	{ xor_16,  "xor_16" },
+	{ xor_32,  "xor_32" },
+	{ xor_64,  "xor_64" },
+	{ xor_blocks_wrapper, "xor_blocks" },
+};
+
+/*
+ * Check, if chunk has to be xored in/out:
+ *
+ * o if writes are queued
+ * o if writes are merged
+ * o if stripe is to be reconstructed
+ * o if recovery stripe
+ */
+static inline int chunk_must_xor(struct stripe_chunk *chunk)
+{
+	if (ChunkUptodate(chunk)) {
+		BUG_ON(!bio_list_empty(BL_CHUNK(chunk, WRITE_QUEUED)) &&
+		       !bio_list_empty(BL_CHUNK(chunk, WRITE_MERGED)));
+
+		if (!bio_list_empty(BL_CHUNK(chunk, WRITE_QUEUED)) ||
+		    !bio_list_empty(BL_CHUNK(chunk, WRITE_MERGED)))
+			return 1;
+
+		if (StripeReconstruct(chunk->stripe) ||
+		    StripeRecover(chunk->stripe))
+			return 1;
+	}
+
+	return 0;
+}
+
+/*
+ * Calculate crc.
+ *
+ * This indexes into the chunks of a stripe and their pages.
+ *
+ * All chunks will be xored into the indexed (@pi)
+ * chunk in maximum groups of xor.chunks.
+ *
+ */
+static void xor(struct stripe *stripe, unsigned pi, unsigned sector)
+{
+	struct raid_set *rs = RS(stripe->sc);
+	unsigned max_chunks = rs->xor.chunks, n = 1,
+		 o = sector / SECTORS_PER_PAGE, /* Offset into the page_list. */
+		 p = rs->set.raid_devs;
+	unsigned long **d = rs->data;
+	xor_function_t xor_f = rs->xor.f->f;
+
+	BUG_ON(sector > stripe->io.size);
+
+	/* Address of parity page to xor into. */
+	d[0] = page_address(pl_elem(PL(stripe, pi), o)->page);
+
+	while (p--) {
+		/* Preset pointers to data pages. */
+		if (p != pi && chunk_must_xor(CHUNK(stripe, p)))
+			d[n++] = page_address(pl_elem(PL(stripe, p), o)->page);
+
+		/* If max chunks -> xor. */
+		if (n == max_chunks) {
+			xor_f(n, d);
+			n = 1;
+		}
+	}
+
+	/* If chunks -> xor. */
+	if (n > 1)
+		xor_f(n, d);
+}
+
+/* Common xor loop through all stripe page lists. */
+static void common_xor(struct stripe *stripe, sector_t count,
+		       unsigned off, unsigned pi)
+{
+	unsigned sector;
+
+	BUG_ON(!count);
+	for (sector = off; sector < count; sector += SECTORS_PER_PAGE)
+		xor(stripe, pi, sector);
+
+	/* Set parity page uptodate and clean. */
+	chunk_set(CHUNK(stripe, pi), CLEAN);
+	atomic_inc(RS(stripe->sc)->stats + S_XORS); /* REMOVEME: statistics. */
+}
+
+/*
+ * Calculate parity sectors on intact stripes.
+ *
+ * Need to calculate raid address for recover stripe, because its
+ * chunk sizes differs and is typically larger than io chunk size.
+ */
+static void parity_xor(struct stripe *stripe)
+{
+	struct raid_set *rs = RS(stripe->sc);
+	unsigned chunk_size = rs->set.chunk_size, io_size = stripe->io.size,
+		 xor_size = chunk_size > io_size ? io_size : chunk_size;
+	sector_t off;
+
+	/* This can be the recover stripe with a larger io size. */
+	for (off = 0; off < io_size; off += xor_size) {
+		/*
+		 * Recover stripe is likely bigger than regular io
+		 * ones and has no precalculated parity disk index ->
+		 * need to calculate RAID address.
+		 */
+		if (unlikely(StripeRecover(stripe))) {
+			struct raid_address addr;
+
+			raid_address(rs,
+				     (stripe->key + off) * rs->set.data_devs,
+				     &addr);
+			stripe->idx.parity = addr.pi;
+			stripe_zero_pl_part(stripe, addr.pi, off, xor_size);
+		}
+
+		common_xor(stripe, xor_size, off, stripe->idx.parity);
+		chunk_set(CHUNK(stripe, stripe->idx.parity), DIRTY);
+	}
+}
+
+/* Reconstruct missing chunk. */
+static void stripe_reconstruct(struct stripe *stripe)
+{
+	struct raid_set *rs = RS(stripe->sc);
+	int p = rs->set.raid_devs, pr = stripe->idx.recover;
+
+	BUG_ON(pr < 0);
+
+	/* Check if all but the chunk to be reconstructed are uptodate. */
+	while (p--)
+		BUG_ON(p != pr && !ChunkUptodate(CHUNK(stripe, p)));
+
+	/* REMOVEME: statistics. */
+	atomic_inc(rs->stats + (RSDegraded(rs) ? S_RECONSTRUCT_EI :
+						 S_RECONSTRUCT_DEV));
+	/* Zero chunk to be reconstructed. */
+	stripe_zero_chunk(stripe, pr);
+	common_xor(stripe, stripe->io.size, 0, pr);
+	stripe->idx.recover = -1;
+}
+
+/*
+ * Recovery io throttling
+ */
+/* Conditionally reset io counters. */
+static int recover_io_reset(struct raid_set *rs)
+{
+	unsigned long j = jiffies;
+
+	/* Pay attention to jiffies overflows. */
+	if (j > rs->recover.last_jiffies + HZ / 20 ||
+	    j < rs->recover.last_jiffies) {
+		atomic_set(rs->recover.io_count + IO_WORK, 0);
+		atomic_set(rs->recover.io_count + IO_RECOVER, 0);
+		rs->recover.last_jiffies = j;
+		return 1;
+	}
+
+	return 0;
+}
+
+/* Count ios. */
+static void recover_io_count(struct stripe *stripe)
+{
+	struct raid_set *rs = RS(stripe->sc);
+
+	recover_io_reset(rs);
+	atomic_inc(rs->recover.io_count +
+		   (StripeRecover(stripe) ? IO_RECOVER : IO_WORK));
+}
+
+/* Try getting a stripe either from the hash or from the LRU list. */
+static struct stripe *stripe_find(struct raid_set *rs,
+				  struct raid_address *addr)
+{
+	int r;
+	struct stripe_cache *sc = &rs->sc;
+	struct stripe *stripe;
+
+	/* Try stripe from hash. */
+	stripe = stripe_lookup(sc, addr->key);
+	if (stripe) {
+		r = stripe_get(stripe);
+		if (r)
+			goto get_lock_failed;
+
+		atomic_inc(rs->stats + S_HITS_1ST); /* REMOVEME: statistics. */
+	} else {
+		/* Not in hash -> try to get an LRU stripe. */
+		stripe = stripe_lru_pop(sc);
+		if (stripe) {
+			/*
+			 * An LRU stripe may not be referenced
+			 * and may never have ios pending!
+			 */
+			BUG_ON(stripe_ref(stripe));
+			BUG_ON(stripe_io_ref(stripe));
+
+			/* Remove from hash if on before reuse. */
+			stripe_hash_del(stripe);
+
+			/* Invalidate before reinserting with changed key. */
+			stripe_invalidate(stripe);
+
+			stripe->key = addr->key;
+			stripe->region = dm_rh_sector_to_region(rs->recover.rh,
+								addr->key);
+			stripe->idx.parity = addr->pi;
+			r = stripe_get(stripe);
+			if (r)
+				goto get_lock_failed;
+
+			/* Insert stripe into the stripe hash. */
+			stripe_insert(&sc->hash, stripe);
+			/* REMOVEME: statistics. */
+			atomic_inc(rs->stats + S_INSCACHE);
+		}
+	}
+
+	return stripe;
+
+get_lock_failed:
+	stripe_put(stripe);
+	return NULL;
+}
+
+/*
+ * Process end io
+ *
+ * I need to do it here because I can't in interrupt
+ */
+/* End io all bios on a bio list. */
+static void bio_list_endio(struct stripe *stripe, struct bio_list *bl,
+			   int p, int error)
+{
+	struct raid_set *rs = RS(stripe->sc);
+	struct bio *bio;
+	struct page_list *pl = PL(stripe, p);
+	struct stripe_chunk *chunk = CHUNK(stripe, p);
+
+	/* Update region counters. */
+	while ((bio = bio_list_pop(bl))) {
+		if (bio_data_dir(bio) == WRITE)
+			/* Drop io pending count for any writes. */
+			dm_rh_dec(rs->recover.rh, stripe->region);
+		else if (!error)
+			/* Copy data accross. */
+			bio_copy_page_list(READ, stripe, pl, bio);
+
+		bio_endio(bio, error);
+
+		/* REMOVEME: statistics. */
+		atomic_inc(rs->stats + (bio_data_dir(bio) == READ ?
+			   S_BIOS_ENDIO_READ : S_BIOS_ENDIO_WRITE));
+
+		chunk_put(chunk);
+		stripe_put(stripe);
+		io_put(rs);	/* Wake any suspend waiters on last bio. */
+	}
+}
+
+/*
+ * End io all reads/writes on a stripe copying
+ * read data accross from stripe to bios and
+ * decrementing region counters for writes.
+ *
+ * Processing of ios depeding on state:
+ * o no chunk error -> endio ok
+ * o degraded:
+ *   - chunk error and read -> ignore to be requeued
+ *   - chunk error and write -> endio ok
+ * o dead (more than parity_devs failed) and chunk_error-> endio failed
+ */
+static void stripe_endio(int rw, struct stripe *stripe)
+{
+	struct raid_set *rs = RS(stripe->sc);
+	unsigned p = rs->set.raid_devs;
+	int write = (rw != READ);
+
+	while (p--) {
+		struct stripe_chunk *chunk = CHUNK(stripe, p);
+		struct bio_list *bl;
+
+		BUG_ON(ChunkLocked(chunk));
+
+		bl = BL_CHUNK(chunk, rw);
+		if (bio_list_empty(bl))
+			continue;
+
+		if (unlikely(ChunkError(chunk) || !ChunkUptodate(chunk))) {
+			/* RAID set dead. */
+			if (unlikely(RSDead(rs)))
+				bio_list_endio(stripe, bl, p, -EIO);
+			/* RAID set degraded. */
+			else if (write)
+				bio_list_endio(stripe, bl, p, 0);
+		} else {
+			BUG_ON(!RSDegraded(rs) && ChunkDirty(chunk));
+			bio_list_endio(stripe, bl, p, 0);
+		}
+	}
+}
+
+/* Fail all ios hanging off all bio lists of a stripe. */
+static void stripe_fail_io(struct stripe *stripe)
+{
+	struct raid_set *rs = RS(stripe->sc);
+	unsigned p = rs->set.raid_devs;
+
+	while (p--) {
+		struct stripe_chunk *chunk = CHUNK(stripe, p);
+		int i = ARRAY_SIZE(chunk->bl);
+
+		/* Fail all bios on all bio lists of the stripe. */
+		while (i--) {
+			struct bio_list *bl = chunk->bl + i;
+
+			if (!bio_list_empty(bl))
+				bio_list_endio(stripe, bl, p, -EIO);
+		}
+	}
+
+	/* Put stripe on LRU list. */
+	BUG_ON(stripe_io_ref(stripe));
+	BUG_ON(stripe_ref(stripe));
+}
+
+/* Unlock all required chunks. */
+static void stripe_chunks_unlock(struct stripe *stripe)
+{
+	unsigned p = RS(stripe->sc)->set.raid_devs;
+	struct stripe_chunk *chunk;
+
+	while (p--) {
+		chunk = CHUNK(stripe, p);
+
+		if (TestClearChunkUnlock(chunk))
+			ClearChunkLocked(chunk);
+	}
+}
+
+/*
+ * Queue reads and writes to a stripe by hanging
+ * their bios off the stripesets read/write lists.
+ */
+static int stripe_queue_bio(struct raid_set *rs, struct bio *bio,
+			    struct bio_list *reject)
+{
+	struct raid_address addr;
+	struct stripe *stripe;
+
+	stripe = stripe_find(rs, raid_address(rs, bio->bi_sector, &addr));
+	if (stripe) {
+		int r = 0, rw = bio_data_dir(bio);
+
+		/* Distinguish reads and writes. */
+		bio_list_add(BL(stripe, addr.di, rw), bio);
+	
+		if (rw == READ)
+			/* REMOVEME: statistics. */
+			atomic_inc(rs->stats + S_BIOS_ADDED_READ);
+		else {
+			/* Inrement pending write count on region. */
+			dm_rh_inc(rs->recover.rh, stripe->region);
+			r = 1;
+
+			/* REMOVEME: statistics. */
+			atomic_inc(rs->stats + S_BIOS_ADDED_WRITE);
+		}
+
+		/*
+		 * Put on io (flush) list in case of
+		 * initial bio queued to chunk.
+		 */
+		if (chunk_get(CHUNK(stripe, addr.di)) == 1)
+			stripe_flush_add(stripe);
+
+		return r;
+	}
+
+	/* Got no stripe from cache or failed to lock it -> reject bio. */
+	bio_list_add(reject, bio);
+	atomic_inc(rs->stats + S_IOS_POST); /* REMOVEME: statistics. */
+	return 0;
+}
+
+/*
+ * Handle all stripes by handing them to the daemon, because we can't
+ * map their chunk pages to copy the data in interrupt context.
+ *
+ * We don't want to handle them here either, while interrupts are disabled.
+ */
+
+/* Read/write endio function for dm-io (interrupt context). */
+static void endio(unsigned long error, void *context)
+{
+	struct stripe_chunk *chunk = context;
+
+	if (unlikely(error)) {
+		chunk_set(chunk, ERROR);
+		/* REMOVEME: statistics. */
+		atomic_inc(RS(chunk->stripe->sc)->stats + S_STRIPE_ERROR);
+	} else
+		chunk_set(chunk, CLEAN);
+
+	/*
+	 * For recovery stripes, I need to reset locked locked
+	 * here, because those aren't processed in do_endios().
+	 */
+	if (unlikely(StripeRecover(chunk->stripe)))
+		ClearChunkLocked(chunk);
+	else
+		SetChunkUnlock(chunk);
+
+	/* Indirectly puts stripe on cache's endio list via stripe_io_put(). */
+	stripe_put_references(chunk->stripe);
+}
+
+/* Read/Write a chunk asynchronously. */
+static void stripe_chunk_rw(struct stripe *stripe, unsigned p)
+{
+	struct stripe_cache *sc = stripe->sc;
+	struct raid_set *rs = RS(sc);
+	struct dm_mem_cache_object *obj = stripe->obj + p;
+	struct page_list *pl = obj->pl;
+	struct stripe_chunk *chunk = CHUNK(stripe, p);
+	struct raid_dev *dev = rs->dev + p;
+	struct dm_io_region io = {
+		.bdev = dev->dev->bdev,
+		.sector = stripe->key,
+		.count = stripe->io.size,
+	};
+	struct dm_io_request control = {
+		.bi_rw = ChunkDirty(chunk) ? WRITE : READ,
+		.mem = {
+			.type = DM_IO_PAGE_LIST,
+			.ptr.pl = pl,
+			.offset = 0,
+		},
+		.notify = {
+			.fn = endio,
+			.context = chunk,
+		},
+		.client = StripeRecover(stripe) ? rs->recover.dm_io_client :
+						  sc->dm_io_client,
+	};
+
+	BUG_ON(ChunkLocked(chunk));
+	BUG_ON(!ChunkUptodate(chunk) && ChunkDirty(chunk));
+	BUG_ON(ChunkUptodate(chunk) && !ChunkDirty(chunk));
+
+	/*
+	 * Don't rw past end of device, which can happen, because
+	 * typically sectors_per_dev isn't divisible by io_size.
+	 */
+	if (unlikely(io.sector + io.count > rs->set.sectors_per_dev))
+		io.count = rs->set.sectors_per_dev - io.sector;
+
+	BUG_ON(!io.count);
+	io.sector += dev->start;	/* Add <offset>. */
+	if (RSRecover(rs))
+		recover_io_count(stripe);	/* Recovery io accounting. */
+
+	/* REMOVEME: statistics. */
+	atomic_inc(rs->stats + (ChunkDirty(chunk) ? S_DM_IO_WRITE :
+						    S_DM_IO_READ));
+	SetChunkLocked(chunk);
+	SetDevIoQueued(dev);
+	BUG_ON(dm_io(&control, 1, &io, NULL));
+}
+
+/*
+ * Write dirty or read not uptodate page lists of a stripe.
+ */
+static int stripe_chunks_rw(struct stripe *stripe)
+{
+	int r;
+	struct raid_set *rs = RS(stripe->sc);
+
+	/*
+	 * Increment the pending count on the stripe
+	 * first, so that we don't race in endio().
+	 *
+	 * An inc (IO) is needed for any chunk unless !ChunkIo(chunk):
+	 *
+	 * o not uptodate
+	 * o dirtied by writes merged
+	 * o dirtied by parity calculations
+	 */
+	r = for_each_io_dev(stripe, stripe_get_references);
+	if (r) {
+		/* Io needed: chunks are either not uptodate or dirty. */
+		int max;	/* REMOVEME: */
+		struct stripe_cache *sc = &rs->sc;
+
+		/* Submit actual io. */
+		for_each_io_dev(stripe, stripe_chunk_rw);
+
+		/* REMOVEME: statistics */
+		max = sc_active(sc);
+		if (atomic_read(&sc->active_stripes_max) < max)
+			atomic_set(&sc->active_stripes_max, max);
+
+		atomic_inc(rs->stats + S_FLUSHS);
+		/* END REMOVEME: statistics */
+	}
+
+	return r;
+}
+
+/* Merge in all writes hence dirtying respective chunks. */
+static void stripe_merge_writes(struct stripe *stripe)
+{
+	unsigned p = RS(stripe->sc)->set.raid_devs;
+
+	while (p--) {
+		struct stripe_chunk *chunk = CHUNK(stripe, p);
+		struct bio_list *write = BL_CHUNK(chunk, WRITE_QUEUED);
+	
+		if (!bio_list_empty(write)) {
+			struct bio *bio;
+			struct page_list *pl = stripe->obj[p].pl;
+
+			/*
+			 * We can play with the lists without holding a lock,
+			 * because it is just us accessing them anyway.
+			 */
+			bio_list_for_each(bio, write)
+				bio_copy_page_list(WRITE, stripe, pl, bio);
+
+			bio_list_merge(BL_CHUNK(chunk, WRITE_MERGED), write);
+			bio_list_init(write);
+			chunk_set(chunk, DIRTY);
+		}
+	}
+}
+
+/* Queue all writes to get merged. */
+static int stripe_queue_writes(struct stripe *stripe)
+{
+	int r = 0;
+	unsigned p = RS(stripe->sc)->set.raid_devs;
+
+	while (p--) {
+		struct stripe_chunk *chunk = CHUNK(stripe, p);
+		struct bio_list *write = BL_CHUNK(chunk, WRITE);
+
+		if (!bio_list_empty(write)) {
+			bio_list_merge(BL_CHUNK(chunk, WRITE_QUEUED), write);
+			bio_list_init(write);
+SetChunkIo(chunk);
+			r = 1;
+		}
+	}
+
+	return r;
+}
+
+
+/* Check, if a chunk gets completely overwritten. */
+static int stripe_check_chunk_overwrite(struct stripe *stripe, unsigned p)
+{
+	unsigned sectors = 0;
+	struct bio *bio;
+	struct bio_list *bl = BL(stripe, p, WRITE_QUEUED);
+
+	bio_list_for_each(bio, bl)
+		sectors += bio_sectors(bio);
+
+	BUG_ON(sectors > RS(stripe->sc)->set.io_size);
+	return sectors == RS(stripe->sc)->set.io_size;
+}
+
+/*
+ * Avoid io on broken/reconstructed drive in order to
+ * reconstruct date on endio.
+ *
+ * (*1*) We set StripeReconstruct() in here, so that _do_endios()
+ *	 will trigger a reconstruct call before resetting it.
+ */
+static int stripe_chunk_set_io_flags(struct stripe *stripe, int pr)
+{
+	struct stripe_chunk *chunk = CHUNK(stripe, pr);
+
+	/*
+	 * Allow io on all chunks but the indexed one,
+	 * because we're either degraded or prohibit it
+	 * on the one for later reconstruction.
+	 */
+	/* Includes ClearChunkIo(), ClearChunkUptodate(). */
+	stripe_chunk_invalidate(chunk);
+	stripe->idx.recover = pr;
+	SetStripeReconstruct(stripe);
+
+	/* REMOVEME: statistics. */
+	atomic_inc(RS(stripe->sc)->stats + S_PROHIBITCHUNKIO);
+	return -EPERM;
+}
+
+/* Chunk locked/uptodate and device failed tests. */
+static struct stripe_chunk *
+stripe_chunk_check(struct stripe *stripe, unsigned p, unsigned *chunks_uptodate)
+{
+	struct raid_set *rs = RS(stripe->sc);
+	struct stripe_chunk *chunk = CHUNK(stripe, p);
+
+	/* Can't access active chunks. */
+	if (ChunkLocked(chunk)) {
+		/* REMOVEME: statistics. */
+		atomic_inc(rs->stats + S_CHUNK_LOCKED);
+		return NULL;
+	}
+
+	/* Can't access broken devive. */
+	if (ChunkError(chunk) || DevFailed(rs->dev + p))
+		return NULL;
+
+	/* Can access uptodate chunks. */
+	if (ChunkUptodate(chunk)) {
+		(*chunks_uptodate)++;
+		return NULL;
+	}
+
+	return chunk;
+}
+
+/*
+ * Degraded/reconstruction mode.
+ *
+ * Check stripe state to figure which chunks don't need IO.
+ *
+ * Returns 0 for fully operational, -EPERM for degraded/resynchronizing.
+ */
+static int stripe_check_reconstruct(struct stripe *stripe)
+{
+	struct raid_set *rs = RS(stripe->sc);
+
+	if (RSDead(rs)) {
+		ClearStripeReconstruct(stripe);
+		ClearStripeReconstructed(stripe);
+		stripe_allow_io(stripe);
+		return 0;
+	}
+
+	/* Avoid further reconstruction setting, when already set. */
+	if (StripeReconstruct(stripe)) {
+		/* REMOVEME: statistics. */
+		atomic_inc(rs->stats + S_RECONSTRUCT_SET);
+		return -EBUSY;
+	}
+
+	/* Initially allow io on all chunks. */
+	stripe_allow_io(stripe);
+
+	/* Return if stripe is already reconstructed. */
+	if (StripeReconstructed(stripe)) {
+		atomic_inc(rs->stats + S_RECONSTRUCTED);
+		return 0;
+	}
+
+	/*
+	 * Degraded/reconstruction mode (device failed) ->
+	 * avoid io on the failed device.
+	 */
+	if (unlikely(RSDegraded(rs))) {
+		/* REMOVEME: statistics. */
+		atomic_inc(rs->stats + S_DEGRADED);
+		/* Allow IO on all devices but the dead one. */
+		BUG_ON(rs->set.ei < 0);
+		return stripe_chunk_set_io_flags(stripe, rs->set.ei);
+	} else {
+		int sync, pi = dev_for_parity(stripe, &sync);
+
+		/*
+		 * Reconstruction mode (ie. a particular (replaced) device or
+		 * some (rotating) parity chunk is being resynchronized) ->
+		 *   o make sure all needed chunks are read in
+		 *   o writes are allowed to go through
+		 */
+		if (!sync) {
+			/* REMOVEME: statistics. */
+			atomic_inc(rs->stats + S_NOSYNC);
+			/* Allow IO on all devs but the one to reconstruct. */
+			return stripe_chunk_set_io_flags(stripe, pi);
+		}
+	}
+
+	return 0;
+}
+
+/*
+ * Check, if stripe is ready to merge writes.
+ * I.e. if all chunks present to allow to merge bios.
+ *
+ * We prohibit io on:
+ *
+ * o chunks without bios
+ * o chunks which get completely written over
+ */
+static int stripe_merge_possible(struct stripe *stripe, int nosync)
+{
+	struct raid_set *rs = RS(stripe->sc);
+	unsigned chunks_overwrite = 0, chunks_prohibited = 0,
+		 chunks_uptodate = 0, p = rs->set.raid_devs;
+
+	/* Walk all chunks. */
+	while (p--) {
+		struct stripe_chunk *chunk;
+
+		/* Prohibit io on broken devices. */
+		if (DevFailed(rs->dev + p)) {
+			chunk = CHUNK(stripe, p);
+			goto prohibit_io;
+		}
+
+		/* We can't optimize any further if no chunk. */
+		chunk = stripe_chunk_check(stripe, p, &chunks_uptodate);
+		if (!chunk || nosync)
+			continue;
+
+		/*
+		 * We have a chunk, which is not uptodate.
+		 *
+		 * If this is not parity and we don't have
+		 * reads queued, we can optimize further.
+		 */
+		if (p != stripe->idx.parity &&
+		    bio_list_empty(BL_CHUNK(chunk, READ)) &&
+		    bio_list_empty(BL_CHUNK(chunk, WRITE_MERGED))) {
+			if (bio_list_empty(BL_CHUNK(chunk, WRITE_QUEUED)))
+				goto prohibit_io;
+			else if (RSCheckOverwrite(rs) &&
+				 stripe_check_chunk_overwrite(stripe, p))
+				/* Completely overwritten chunk. */
+				chunks_overwrite++;
+		}
+
+		/* Allow io for chunks with bios and overwritten ones. */
+		SetChunkIo(chunk);
+		continue;
+
+prohibit_io:
+		/* No io for broken devices or for chunks w/o bios. */
+		ClearChunkIo(chunk);
+		chunks_prohibited++;
+		/* REMOVEME: statistics. */
+		atomic_inc(RS(stripe->sc)->stats + S_PROHIBITCHUNKIO);
+	}
+
+	/* All data chunks will get written over. */
+	if (chunks_overwrite == rs->set.data_devs)
+		atomic_inc(rs->stats + S_OVERWRITE); /* REMOVEME: statistics.*/
+	else if (chunks_uptodate + chunks_prohibited < rs->set.raid_devs) {
+		/* We don't have enough chunks to merge. */
+		atomic_inc(rs->stats + S_CANT_MERGE); /* REMOVEME: statistics.*/
+		return -EPERM;
+	}
+
+	/*
+	 * If we have all chunks up to date or overwrite them, we
+	 * just zero the parity chunk and let stripe_rw() recreate it.
+	 */
+	if (chunks_uptodate == rs->set.raid_devs ||
+	    chunks_overwrite == rs->set.data_devs) {
+		stripe_zero_chunk(stripe, stripe->idx.parity);
+		BUG_ON(StripeReconstruct(stripe));
+		SetStripeReconstruct(stripe);	/* Enforce xor in caller. */
+	} else {
+		/*
+		 * With less chunks, we xor parity out.
+		 *
+		 * (*4*) We rely on !StripeReconstruct() in chunk_must_xor(),
+		 *	 so that only chunks with queued or merged writes 
+		 *	 are being xored.
+		 */
+		parity_xor(stripe);
+	}
+
+	/*
+	 * We do have enough chunks to merge.
+	 * All chunks are uptodate or get written over.
+	 */
+	atomic_inc(rs->stats + S_CAN_MERGE); /* REMOVEME: statistics. */
+	return 0;
+}
+
+/*
+ * Avoid reading chunks in case we're fully operational.
+ *
+ * We prohibit io on any chunks without bios but the parity chunk.
+ */
+static void stripe_avoid_reads(struct stripe *stripe)
+{
+	struct raid_set *rs = RS(stripe->sc);
+	unsigned dummy = 0, p = rs->set.raid_devs;
+
+	/* Walk all chunks. */
+	while (p--) {
+		struct stripe_chunk *chunk =
+			stripe_chunk_check(stripe, p, &dummy);
+
+		if (!chunk)
+			continue;
+
+		/* If parity or any bios pending -> allow io. */
+		if (chunk_ref(chunk) || p == stripe->idx.parity)
+			SetChunkIo(chunk);
+		else {
+			ClearChunkIo(chunk);
+			/* REMOVEME: statistics. */
+			atomic_inc(RS(stripe->sc)->stats + S_PROHIBITCHUNKIO);
+		}
+	}
+}
+
+/*
+ * Read/write a stripe.
+ *
+ * All stripe read/write activity goes through this function
+ * unless recovery, which has to call stripe_chunk_rw() directly.
+ *
+ * Make sure we don't try already merged stripes in order
+ * to avoid data corruption.
+ *
+ * Check the state of the RAID set and if degraded (or
+ * resynchronizing for reads), read in all other chunks but
+ * the one on the dead/resynchronizing device in order to be
+ * able to reconstruct the missing one in _do_endios().
+ *
+ * Can be called on active stripes in order
+ * to dispatch new io on inactive chunks.
+ *
+ * States to cover:
+ *   o stripe to read and/or write
+ *   o stripe with error to reconstruct
+ */
+static void stripe_rw(struct stripe *stripe)
+{
+	int nosync, r;
+	struct raid_set *rs = RS(stripe->sc);
+
+	/*
+ 	 * Check, if a chunk needs to be reconstructed
+ 	 * because of a degraded set or a region out of sync.
+ 	 */
+	nosync = stripe_check_reconstruct(stripe);
+	switch (nosync) {
+	case -EBUSY:
+		return; /* Wait for stripe reconstruction to finish. */
+	case -EPERM:
+		goto io;
+	}
+
+	/*
+	 * If we don't have merged writes pending, we can schedule
+	 * queued writes to be merged next without corrupting data.
+	 */
+	if (!StripeMerged(stripe)) {
+		r = stripe_queue_writes(stripe);
+		if (r)
+			/* Writes got queued -> flag RBW. */
+			SetStripeRBW(stripe);
+	}
+
+	/*
+	 * Merge all writes hanging off uptodate/overwritten
+	 * chunks of the stripe.
+	 */
+	if (StripeRBW(stripe)) {
+		r = stripe_merge_possible(stripe, nosync);
+		if (!r) { /* Merge possible. */
+			struct stripe_chunk *chunk;
+
+			/*
+			 * I rely on valid parity in order
+			 * to xor a fraction of chunks out
+			 * of parity and back in.
+			 */
+			stripe_merge_writes(stripe);	/* Merge writes in. */
+			parity_xor(stripe);		/* Update parity. */
+			ClearStripeReconstruct(stripe);	/* Reset xor enforce. */
+			SetStripeMerged(stripe);	/* Writes merged. */
+			ClearStripeRBW(stripe);		/* Disable RBW. */
+
+			/*
+			 * REMOVEME: sanity check on parity chunk
+			 * 	     states after writes got merged.
+			 */
+			chunk = CHUNK(stripe, stripe->idx.parity);
+			BUG_ON(ChunkLocked(chunk));
+			BUG_ON(!ChunkUptodate(chunk));
+			BUG_ON(!ChunkDirty(chunk));
+			BUG_ON(!ChunkIo(chunk));
+		}
+	} else if (!nosync && !StripeMerged(stripe))
+		/* Read avoidance if not degraded/resynchronizing/merged. */
+		stripe_avoid_reads(stripe);
+
+io:
+	/* Now submit any reads/writes for non-uptodate or dirty chunks. */
+	r = stripe_chunks_rw(stripe);
+	if (!r) {
+		/*
+		 * No io submitted because of chunk io
+		 * prohibited or locked chunks/failed devices
+		 * -> push to end io list for processing.
+		 */
+		stripe_endio_push(stripe);
+		atomic_inc(rs->stats + S_NO_RW); /* REMOVEME: statistics. */
+	}
+}
+
+/*
+ * Recovery functions
+ */
+/* Read a stripe off a raid set for recovery. */
+static int stripe_recover_read(struct stripe *stripe, int pi)
+{
+	BUG_ON(stripe_io_ref(stripe));
+
+	/* Invalidate all chunks so that they get read in. */
+	stripe_chunks_invalidate(stripe);
+	stripe_allow_io(stripe); /* Allow io on all recovery chunks. */
+
+	/*
+	 * If we are reconstructing a perticular device, we can avoid
+ 	 * reading the respective chunk in, because we're going to
+	 * reconstruct it anyway.
+	 *
+	 * We can't do that for resynchronization of rotating parity,
+	 * because the recovery stripe chunk size is typically larger
+	 * than the sets chunk size.
+	 */
+	if (pi > -1)
+		ClearChunkIo(CHUNK(stripe, pi));
+
+	return stripe_chunks_rw(stripe);
+}
+
+/* Write a stripe to a raid set for recovery. */
+static int stripe_recover_write(struct stripe *stripe, int pi)
+{
+	BUG_ON(stripe_io_ref(stripe));
+
+	/*
+	 * If this is a reconstruct of a particular device, then
+	 * reconstruct the respective chunk, else create parity chunk.
+	 */
+	if (pi > -1) {
+		stripe_zero_chunk(stripe, pi);
+		common_xor(stripe, stripe->io.size, 0, pi);
+		chunk_set(CHUNK(stripe, pi), DIRTY);
+	} else
+		parity_xor(stripe);
+
+	return stripe_chunks_rw(stripe);
+}
+
+/* Read/write a recovery stripe. */
+static int stripe_recover_rw(struct stripe *stripe)
+{
+	int r = 0, sync = 0;
+
+	/* Read/write flip-flop. */
+	if (TestClearStripeRBW(stripe)) {
+		SetStripeMerged(stripe);
+		stripe->key = stripe->recover->pos;
+		r = stripe_recover_read(stripe, dev_for_parity(stripe, &sync));
+		BUG_ON(!r);
+	} else if (TestClearStripeMerged(stripe)) {
+		r = stripe_recover_write(stripe, dev_for_parity(stripe, &sync));
+		BUG_ON(!r);
+	}
+
+	BUG_ON(sync);
+	return r;
+}
+
+/* Recover bandwidth available ?. */
+static int recover_bandwidth(struct raid_set *rs)
+{
+	int r, work;
+
+	/* On reset or when bios delayed -> allow recovery. */
+	r = recover_io_reset(rs);
+	if (r || RSBandwidth(rs))
+		goto out;
+
+	work = atomic_read(rs->recover.io_count + IO_WORK);
+	if (work) {
+		/* Pay attention to larger recover stripe size. */
+		int recover = atomic_read(rs->recover.io_count + IO_RECOVER) *
+					  rs->recover.io_size / rs->set.io_size;
+
+		/*
+		 * Don't use more than given bandwidth
+		 * of the work io for recovery.
+		 */
+		if (recover > work / rs->recover.bandwidth_work) {
+			/* REMOVEME: statistics. */
+			atomic_inc(rs->stats + S_NO_BANDWIDTH);
+			return 0;
+		}
+	}
+
+out:
+	atomic_inc(rs->stats + S_BANDWIDTH);	/* REMOVEME: statistics. */
+	return 1;
+}
+
+/* Try to get a region to recover. */
+static int stripe_recover_get_region(struct stripe *stripe)
+{
+	struct raid_set *rs = RS(stripe->sc);
+	struct recover *rec = &rs->recover;
+	struct recover_addr *addr = stripe->recover;
+	struct dm_dirty_log *dl = rec->dl;
+	struct dm_rh_client *rh = rec->rh;
+
+	BUG_ON(!dl);
+	BUG_ON(!rh);
+
+	/* Return, that we have region first to finish it during suspension. */
+	if (addr->reg)
+		return 1;
+
+	if (RSSuspend(rs))
+		return -EPERM;
+
+	if (dl->type->get_sync_count(dl) >= rec->nr_regions)
+		return -ENOENT;
+
+	/* If we don't have enough bandwidth, we don't proceed recovering. */
+	if (!recover_bandwidth(rs))
+		return -EAGAIN;
+
+	/* Start quiescing a region. */
+	dm_rh_recovery_prepare(rh);
+	addr->reg = dm_rh_recovery_start(rh);
+	if (!addr->reg)
+		return -EAGAIN;
+
+	addr->pos = dm_rh_region_to_sector(rh, dm_rh_get_region_key(addr->reg));
+	addr->end = addr->pos + dm_rh_get_region_size(rh);
+
+	/*
+	 * Take one global io reference out for the
+	 * whole region, which is going to be released
+	 * when the region is completely done with.
+	 */
+	io_get(rs);
+	return 0;
+}
+
+/* Update region hash state. */
+enum recover_type { REC_FAILURE = 0, REC_SUCCESS = 1 };
+static void recover_rh_update(struct stripe *stripe, enum recover_type success)
+{
+	struct recover_addr *addr = stripe->recover;
+	struct raid_set *rs = RS(stripe->sc);
+	struct recover *rec = &rs->recover;
+
+	if (!addr->reg) {
+		DMERR("%s- Called w/o region", __func__);
+		return;
+	}
+
+	dm_rh_recovery_end(addr->reg, success);
+	if (success)
+		rec->nr_regions_recovered++;
+
+	addr->reg = NULL;
+
+	/*
+	 * Completely done with this region ->
+	 * release the 1st io reference.
+	 */
+	io_put(rs);
+}
+
+/* Set start of recovery state. */
+static void set_start_recovery(struct raid_set *rs)
+{
+	/* Initialize recovery. */
+	rs->recover.start_jiffies = jiffies;
+	rs->recover.end_jiffies = 0;
+}
+
+/* Set end of recovery state. */
+static void set_end_recovery(struct raid_set *rs)
+{
+	ClearRSRecover(rs);
+	rs->set.dev_to_init = -1;
+
+	/* Check for jiffies overrun. */
+	rs->recover.end_jiffies = jiffies;
+	if (rs->recover.end_jiffies < rs->recover.start_jiffies)
+		rs->recover.end_jiffies = ~0;
+}
+
+/* Handle recovery on one recovery stripe. */
+static int _do_recovery(struct stripe *stripe)
+{
+	int r;
+	struct raid_set *rs = RS(stripe->sc);
+	struct recover_addr *addr = stripe->recover;
+
+	/* If recovery is active -> return. */
+	if (stripe_io_ref(stripe))
+		return 1;
+
+	/* IO error is fatal for recovery -> stop it. */
+	if (unlikely(StripeError(stripe)))
+		goto err;
+
+	/* Recovery end required. */
+	if (!RSRecover(rs))
+		goto err;
+
+	/* Get a region to recover. */
+	r = stripe_recover_get_region(stripe);
+	switch (r) {
+	case 0:	/* Got a new region: flag initial read before write. */
+		SetStripeRBW(stripe);
+	case 1:	/* Have a region in the works. */
+		break;
+	case -EAGAIN:
+		/* No bandwidth/quiesced region yet, try later. */
+		if (!io_ref(rs))
+			wake_do_raid_delayed(rs, HZ / 4);
+	case -EPERM:
+		/* Suspend. */
+		return 1;
+	case -ENOENT:	/* No more regions to recover. */
+		schedule_work(&rs->io.ws_do_table_event);
+		return 0;
+	default:
+		BUG();
+	}
+
+	/* Read/write a recover stripe. */
+	r = stripe_recover_rw(stripe);
+	if (r)
+		/* IO initiated. */
+		return 1;
+
+	/* Read and write finished-> update recovery position within region. */
+	addr->pos += stripe->io.size;
+
+	/* If we're at end of region, update region hash. */
+	if (addr->pos >= addr->end ||
+	    addr->pos >= rs->set.sectors_per_dev)
+		recover_rh_update(stripe, REC_SUCCESS);
+	else
+		/* Prepare to read next region segment. */
+		SetStripeRBW(stripe);
+
+	/* Schedule myself for another round... */
+	wake_do_raid(rs);
+	return 1;
+
+err:
+	/* FIXME: rather try recovering other regions on error? */
+	rs_check_degrade(stripe);
+	recover_rh_update(stripe, REC_FAILURE);
+
+	/* Check state of partially recovered array. */
+	if (RSDegraded(rs) && !RSDead(rs) &&
+	    rs->set.dev_to_init != -1 &&
+	    rs->set.ei != rs->set.dev_to_init)
+		/* Broken drive != drive to recover -> FATAL. */
+		SetRSDead(rs);
+
+	if (StripeError(stripe)) {
+		char buf[BDEVNAME_SIZE];
+
+		DMERR("stopping recovery due to "
+		      "ERROR on /dev/%s, stripe at offset %llu",
+		      bdevname(rs->dev[rs->set.ei].dev->bdev, buf),
+		      (unsigned long long) stripe->key);
+
+	}
+
+	/* Make sure, that all quiesced regions get released. */
+	while (addr->reg) {
+		dm_rh_recovery_end(addr->reg, -EIO);
+		addr->reg = dm_rh_recovery_start(rs->recover.rh);
+	}
+
+	return 0;
+}
+
+/* Called by main io daemon to recover regions. */
+static void do_recovery(struct raid_set *rs)
+{
+	if (RSRecover(rs)) {
+		int r = 0;
+		struct stripe *stripe;
+
+		list_for_each_entry(stripe, &rs->recover.stripes,
+				    lists[LIST_RECOVER])
+			r += _do_recovery(stripe);
+
+		if (!r) {
+			set_end_recovery(rs);
+			stripe_recover_free(rs);
+		}
+	}
+}
+
+/*
+ * END recovery functions
+ */
+
+/* End io process all stripes handed in by endio() callback. */
+static void _do_endios(struct raid_set *rs, struct stripe *stripe,
+		       struct list_head *flush_list)
+{
+	/* First unlock all required chunks. */
+	stripe_chunks_unlock(stripe);
+
+	/*
+	 * If an io error on a stripe occured, degrade the RAID set
+	 * and try to endio as many bios as possible. If any bios can't
+	 * be endio processed, requeue the stripe (stripe_ref() != 0).
+	 */
+	if (TestClearStripeError(stripe)) {
+		/*
+		 * FIXME: if read, rewrite the failed chunk after reconstruction
+		 *        in order to trigger disk bad sector relocation.
+		 */
+		rs_check_degrade(stripe); /* Resets ChunkError(). */
+		ClearStripeReconstruct(stripe);
+		ClearStripeReconstructed(stripe);
+	}
+
+	/* Got to reconstruct a missing chunk. */
+	if (StripeReconstruct(stripe)) {
+		/*
+		 * (*2*) We use StripeReconstruct() to allow for
+		 *	 all chunks to be xored into the reconstructed
+		 *	 one (see chunk_must_xor()).
+		 */
+		stripe_reconstruct(stripe);
+
+		/*
+		 * (*3*) Now we reset StripeReconstruct() and flag
+		 * 	 StripeReconstructed() to show to stripe_rw(),
+		 * 	 that we have reconstructed a missing chunk.
+		 */
+		ClearStripeReconstruct(stripe);
+		SetStripeReconstructed(stripe);
+
+		/* FIXME: reschedule to be written in case of read. */
+		// if (!StripeRBW(stripe)) {
+		// 	chunk_set(CHUNK(stripe, pr), DIRTY);
+		// 	stripe_chunks_rw(stripe);
+		// }
+	}
+
+	/*
+	 * Now that we eventually got a complete stripe, we
+	 * can process the rest of the end ios on reads.
+	 */
+	stripe_endio(READ, stripe);
+
+	/* End io all merged writes. */
+	if (TestClearStripeMerged(stripe))
+		stripe_endio(WRITE_MERGED, stripe);
+
+	/* If RAID set is dead -> fail any ios to dead drives. */
+	if (RSDead(rs)) {
+		DMERR_LIMIT("RAID set dead: failing ios to dead devices");
+		stripe_fail_io(stripe);
+	}
+
+	/*
+	 * We have stripe references still,
+	 * beacuse of read befeore writes or IO errors ->
+	 * got to put on flush list for processing.
+	 */
+	if (stripe_ref(stripe)) {
+		BUG_ON(!list_empty(stripe->lists + LIST_LRU));
+		list_add_tail(stripe->lists + LIST_FLUSH, flush_list);
+		atomic_inc(rs->stats + S_REQUEUE); /* REMOVEME: statistics. */
+	} else
+		stripe_lru_add(stripe);
+}
+
+/* Pop any endio stripes off of the endio list and belabour them. */
+static void do_endios(struct raid_set *rs)
+{
+	struct stripe_cache *sc = &rs->sc;
+	struct stripe *stripe;
+	/* IO flush list for sorted requeued stripes. */
+	struct list_head flush_list;
+
+	INIT_LIST_HEAD(&flush_list);
+
+	while ((stripe = stripe_endio_pop(sc))) {
+		/* Avoid endio on stripes with newly io'ed chunks. */
+		if (!stripe_io_ref(stripe))
+			_do_endios(rs, stripe, &flush_list);
+	}
+
+	/*
+	 * Insert any requeued stripes in the proper
+	 * order at the beginning of the io (flush) list.
+	 */
+	list_splice(&flush_list, sc->lists + LIST_FLUSH);
+}
+
+/* Flush any stripes on the io list. */
+static void do_flush(struct raid_set *rs)
+{
+	struct stripe *stripe;
+
+	while ((stripe = stripe_io_pop(&rs->sc)))
+		stripe_rw(stripe); /* Read/write stripe. */
+}
+
+/* Stripe cache resizing. */
+static void do_sc_resize(struct raid_set *rs)
+{
+	unsigned set = atomic_read(&rs->sc.stripes_to_set);
+
+	if (set) {
+		unsigned cur = atomic_read(&rs->sc.stripes);
+		int r = (set > cur) ? sc_grow(&rs->sc, set - cur, SC_GROW) :
+				      sc_shrink(&rs->sc, cur - set);
+
+		/* Flag end of resizeing if ok. */
+		if (!r)
+			atomic_set(&rs->sc.stripes_to_set, 0);
+	}
+}
+
+/*
+ * Process all ios
+ *
+ * We do different things with the io depending
+ * on the state of the region that it is in:
+ *
+ * o reads: hang off stripe cache or postpone if full
+ *
+ * o writes:
+ *
+ *  CLEAN/DIRTY/NOSYNC:	increment pending and hang io off stripe's stripe set.
+ *			In case stripe cache is full or busy, postpone the io.
+ *
+ *  RECOVERING:		delay the io until recovery of the region completes.
+ *
+ */
+static void do_ios(struct raid_set *rs, struct bio_list *ios)
+{
+	int r;
+	unsigned flush = 0, delay = 0;
+	sector_t sector;
+	struct dm_rh_client *rh = rs->recover.rh;
+	struct bio *bio;
+	struct bio_list reject;
+
+	bio_list_init(&reject);
+
+	/*
+	 * Classify each io:
+	 *    o delay writes to recovering regions (let reads go through)
+	 *    o queue io to all other regions
+	 */
+	while ((bio = bio_list_pop(ios))) {
+		/*
+		 * In case we get a barrier bio, push it back onto
+		 * the input queue unless all work queues are empty
+		 * and the stripe cache is inactive.
+		 */
+		if (unlikely(bio->bi_rw & REQ_FLUSH)) {
+			/* REMOVEME: statistics. */
+			atomic_inc(rs->stats + S_BARRIER);
+			if (delay ||
+			    !list_empty(rs->sc.lists + LIST_FLUSH) ||
+			    !bio_list_empty(&reject) ||
+			    sc_active(&rs->sc)) {
+				bio_list_push(ios, bio);
+				break;
+			}
+		}
+
+		/* Check for recovering regions. */
+		sector = _sector(rs, bio);
+		r = region_state(rs, sector, DM_RH_RECOVERING);
+		if (unlikely(r && bio_data_dir(bio) == WRITE)) {
+			delay++;
+			/* Wait writing to recovering regions. */
+			dm_rh_delay_by_region(rh, bio,
+					      dm_rh_sector_to_region(rh,
+								     sector));
+			/* REMOVEME: statistics.*/
+			atomic_inc(rs->stats + S_DELAYED_BIOS);
+			atomic_inc(rs->stats + S_SUM_DELAYED_BIOS);
+
+			/* Force bandwidth tests in recovery. */
+			SetRSBandwidth(rs);
+		} else {
+			/*
+			 * Process ios to non-recovering regions by queueing
+			 * them to stripes (does dm_rh_inc()) for writes).
+			 */
+			flush += stripe_queue_bio(rs, bio, &reject);
+		}
+	}
+
+	if (flush) {
+		/* FIXME: better error handling. */
+		r = dm_rh_flush(rh); /* Writes got queued -> flush dirty log. */
+		if (r)
+			DMERR_LIMIT("dirty log flush");
+	}
+
+	/* Merge any rejected bios back to the head of the input list. */
+	bio_list_merge_head(ios, &reject);
+}
+
+/* Send an event in case we're getting too busy. */
+static void do_busy_event(struct raid_set *rs)
+{
+	if (sc_busy(rs)) {
+		if (!TestSetRSScBusy(rs))
+			schedule_work(&rs->io.ws_do_table_event);
+	}
+
+	ClearRSScBusy(rs);
+}
+
+/* Throw an event. */
+static void do_table_event(struct work_struct *ws)
+{
+	struct raid_set *rs = container_of(ws, struct raid_set,
+					   io.ws_do_table_event);
+	dm_table_event(rs->ti->table);
+}
+
+
+/*-----------------------------------------------------------------
+ * RAID daemon
+ *---------------------------------------------------------------*/
+/*
+ * o belabour all end ios
+ * o update the region hash states
+ * o optionally shrink the stripe cache
+ * o optionally do recovery
+ * o unplug any component raid devices with queued bios
+ * o grab the input queue
+ * o work an all requeued or new ios and perform stripe cache flushs
+ * o unplug any component raid devices with queued bios
+ * o check, if the stripe cache gets too busy and throw an event if so
+ */
+static void do_raid(struct work_struct *ws)
+{
+	struct raid_set *rs = container_of(ws, struct raid_set,
+					   io.dws_do_raid.work);
+	struct bio_list *ios = &rs->io.work, *ios_in = &rs->io.in;
+	struct blk_plug plug;
+
+	/*
+	 * We always need to end io, so that ios can get errored in
+	 * case the set failed and the region counters get decremented
+	 * before we update region hash states and go any further.
+	 */
+	do_endios(rs);
+	dm_rh_update_states(rs->recover.rh, 1);
+
+	/*
+	 * Now that we've end io'd, which may have put stripes on the LRU list
+	 * to allow for shrinking, we resize the stripe cache if requested.
+	 */
+	do_sc_resize(rs);
+
+	/* Try to recover regions. */
+	blk_start_plug(&plug);
+	do_recovery(rs);
+	blk_finish_plug(&plug);	/* Unplug the queue */
+
+	/* Quickly grab all new ios queued and add them to the work list. */
+	mutex_lock(&rs->io.in_lock);
+	bio_list_merge(ios, ios_in);
+	bio_list_init(ios_in);
+	mutex_unlock(&rs->io.in_lock);
+
+	blk_start_plug(&plug);
+	if (!bio_list_empty(ios))
+		do_ios(rs, ios); /* Got ios to work into the cache. */
+
+	do_flush(rs);		/* Flush any stripes on io list. */
+	blk_finish_plug(&plug);	/* Unplug the queue */
+	do_busy_event(rs);	/* Check if we got too busy. */
+}
+
+/*
+ * Callback for region hash to dispatch
+ * delayed bios queued to recovered regions
+ * (gets called via dm_rh_update_states()).
+ */
+static void dispatch_delayed_bios(void *context, struct bio_list *bl)
+{
+	struct raid_set *rs = context;
+	struct bio *bio;
+
+	/* REMOVEME: statistics; decrement pending delayed bios counter. */
+	bio_list_for_each(bio, bl)
+		atomic_dec(rs->stats + S_DELAYED_BIOS);
+
+	/* Merge region hash private list to work list. */
+	bio_list_merge_head(&rs->io.work, bl);
+	bio_list_init(bl);
+	ClearRSBandwidth(rs);
+}
+
+/*************************************************************
+ * Constructor helpers
+ *************************************************************/
+/* Calculate MB/sec. */
+static unsigned mbpers(struct raid_set *rs, unsigned speed)
+{
+	return to_bytes(speed * rs->set.data_devs *
+			rs->recover.io_size * HZ >> 10) >> 10;
+}
+
+/*
+ * Discover fastest xor algorithm and # of chunks combination.
+ */
+/* Calculate speed for algorithm and # of chunks. */
+static unsigned xor_speed(struct stripe *stripe)
+{
+	unsigned r = 0;
+	unsigned long j;
+
+	/* Wait for next tick. */
+	for (j = jiffies; j == jiffies; )
+		;
+
+	/* Do xors for a full tick. */
+	for (j = jiffies; j == jiffies; ) {
+		mb();
+		common_xor(stripe, stripe->io.size, 0, 0);
+		mb();
+		r++;
+	}
+
+	return r;
+}
+
+/* Optimize xor algorithm for this RAID set. */
+static unsigned xor_optimize(struct raid_set *rs)
+{
+	unsigned chunks_max = 2, p = rs->set.raid_devs, speed_max = 0;
+	struct xor_func *f = ARRAY_END(xor_funcs), *f_max = NULL;
+	struct stripe *stripe;
+
+	BUG_ON(list_empty(&rs->recover.stripes));
+	stripe = list_first_entry(&rs->recover.stripes, struct stripe,
+				  lists[LIST_RECOVER]);
+
+	/* Must set uptodate so that xor() will belabour chunks. */
+	while (p--)
+		SetChunkUptodate(CHUNK(stripe, p));
+
+	/* Try all xor functions. */
+	while (f-- > xor_funcs) {
+		unsigned speed;
+
+		/* Set actual xor function for common_xor(). */
+		rs->xor.f = f;
+		rs->xor.chunks = (f->f == xor_blocks_wrapper ?
+				  (MAX_XOR_BLOCKS + 1) : XOR_CHUNKS_MAX) + 1;
+
+		while (rs->xor.chunks-- > 2) {
+			speed = xor_speed(stripe);
+			if (speed > speed_max) {
+				speed_max = speed;
+				chunks_max = rs->xor.chunks;
+				f_max = f;
+			}
+		}
+	}
+
+	/* Memorize optimum parameters. */
+	rs->xor.f = f_max;
+	rs->xor.chunks = chunks_max;
+	return speed_max;
+}
+
+/*
+ * Allocate a RAID context (a RAID set)
+ */
+/* Structure for variable RAID parameters. */
+struct variable_parms {
+	int bandwidth;
+	int bandwidth_parm;
+	int chunk_size;
+	int chunk_size_parm;
+	int io_size;
+	int io_size_parm;
+	int stripes;
+	int stripes_parm;
+	int recover_io_size;
+	int recover_io_size_parm;
+	int raid_parms;
+	int recovery;
+	int recovery_stripes;
+	int recovery_stripes_parm;
+};
+
+static struct raid_set *
+context_alloc(struct raid_type *raid_type, struct variable_parms *p,
+	      unsigned raid_devs, sector_t sectors_per_dev,
+	      struct dm_target *ti, unsigned dl_parms, char **argv)
+{
+	int r;
+	size_t len;
+	sector_t region_size, ti_len;
+	struct raid_set *rs = NULL;
+	struct dm_dirty_log *dl;
+	struct recover *rec;
+
+	/*
+	 * Create the dirty log
+	 *
+	 * We need to change length for the dirty log constructor,
+	 * because we want an amount of regions for all stripes derived
+	 * from the single device size, so that we can keep region
+	 * size = 2^^n independant of the number of devices
+	 */
+	ti_len = ti->len;
+	ti->len = sectors_per_dev;
+	dl = dm_dirty_log_create(argv[0], ti, NULL, dl_parms, argv + 2);
+	ti->len = ti_len;
+	if (!dl)
+		goto bad_dirty_log;
+
+	/* Chunk size *must* be smaller than region size. */
+	region_size = dl->type->get_region_size(dl);
+	if (p->chunk_size > region_size)
+		goto bad_chunk_size;
+
+	/* Recover io size *must* be smaller than region size as well. */
+	if (p->recover_io_size > region_size)
+		goto bad_recover_io_size;
+
+	/* Size and allocate the RAID set structure. */
+	len = sizeof(*rs->data) + sizeof(*rs->dev);
+	if (dm_array_too_big(sizeof(*rs), len, raid_devs))
+		goto bad_array;
+
+	len = sizeof(*rs) + raid_devs * len;
+	rs = kzalloc(len, GFP_KERNEL);
+	if (!rs)
+		goto bad_alloc;
+
+	rec = &rs->recover;
+	atomic_set(&rs->io.in_process, 0);
+	atomic_set(&rs->io.in_process_max, 0);
+	rec->io_size = p->recover_io_size;
+
+	/* Pointer to data array. */
+	rs->data = (unsigned long **)
+		   ((void *) rs->dev + raid_devs * sizeof(*rs->dev));
+	rec->dl = dl;
+	rs->set.raid_devs = raid_devs;
+	rs->set.data_devs = raid_devs - raid_type->parity_devs;
+	rs->set.raid_type = raid_type;
+
+	rs->set.raid_parms = p->raid_parms;
+	rs->set.chunk_size_parm = p->chunk_size_parm;
+	rs->set.io_size_parm = p->io_size_parm;
+	rs->sc.stripes_parm = p->stripes_parm;
+	rec->io_size_parm = p->recover_io_size_parm;
+	rec->bandwidth_parm = p->bandwidth_parm;
+	rec->recovery = p->recovery;
+	rec->recovery_stripes = p->recovery_stripes;
+
+	/*
+	 * Set chunk and io size and respective shifts
+	 * (used to avoid divisions)
+	 */
+	rs->set.chunk_size = p->chunk_size;
+	rs->set.chunk_shift = ffs(p->chunk_size) - 1;
+
+	rs->set.io_size = p->io_size;
+	rs->set.io_mask = p->io_size - 1;
+	/* Mask to adjust address key in case io_size != chunk_size. */
+	rs->set.io_inv_mask = (p->chunk_size - 1) & ~rs->set.io_mask;
+
+	rs->set.sectors_per_dev = sectors_per_dev;
+
+	rs->set.ei = -1;	/* Indicate no failed device. */
+	atomic_set(&rs->set.failed_devs, 0);
+
+	rs->ti = ti;
+
+	atomic_set(rec->io_count + IO_WORK, 0);
+	atomic_set(rec->io_count + IO_RECOVER, 0);
+
+	/* Initialize io lock and queues. */
+	mutex_init(&rs->io.in_lock);
+	bio_list_init(&rs->io.in);
+	bio_list_init(&rs->io.work);
+
+	init_waitqueue_head(&rs->io.suspendq);	/* Suspend waiters (dm-io). */
+
+	rec->nr_regions = dm_sector_div_up(sectors_per_dev, region_size);
+	rec->rh = dm_region_hash_create(rs, dispatch_delayed_bios,
+			wake_dummy, wake_do_raid, 0, p->recovery_stripes,
+			dl, region_size, rec->nr_regions);
+	if (IS_ERR(rec->rh))
+		goto bad_rh;
+
+	/* Initialize stripe cache. */
+	r = sc_init(rs, p->stripes);
+	if (r)
+		goto bad_sc;
+
+	/* REMOVEME: statistics. */
+	stats_reset(rs);
+	ClearRSDevelStats(rs);	/* Disnable development status. */
+	return rs;
+
+bad_dirty_log:
+	TI_ERR_RET("Error creating dirty log", ERR_PTR(-ENOMEM));
+
+bad_chunk_size:
+	dm_dirty_log_destroy(dl);
+	TI_ERR_RET("Chunk size larger than region size", ERR_PTR(-EINVAL));
+
+bad_recover_io_size:
+	dm_dirty_log_destroy(dl);
+	TI_ERR_RET("Recover stripe io size larger than region size",
+			ERR_PTR(-EINVAL));
+
+bad_array:
+	dm_dirty_log_destroy(dl);
+	TI_ERR_RET("Arry too big", ERR_PTR(-EINVAL));
+
+bad_alloc:
+	dm_dirty_log_destroy(dl);
+	TI_ERR_RET("Cannot allocate raid context", ERR_PTR(-ENOMEM));
+
+bad_rh:
+	dm_dirty_log_destroy(dl);
+	ti->error = DM_MSG_PREFIX "Error creating dirty region hash";
+	goto free_rs;
+
+bad_sc:
+	dm_region_hash_destroy(rec->rh); /* Destroys dirty log too. */
+	sc_exit(&rs->sc);
+	ti->error = DM_MSG_PREFIX "Error creating stripe cache";
+free_rs:
+	kfree(rs);
+	return ERR_PTR(-ENOMEM);
+}
+
+/* Free a RAID context (a RAID set). */
+static void context_free(struct raid_set *rs, unsigned p)
+{
+	while (p--)
+		dm_put_device(rs->ti, rs->dev[p].dev);
+
+	sc_exit(&rs->sc);
+	dm_region_hash_destroy(rs->recover.rh); /* Destroys dirty log too. */
+	kfree(rs);
+}
+
+/* Create work queue and initialize delayed work. */
+static int rs_workqueue_init(struct raid_set *rs)
+{
+	struct dm_target *ti = rs->ti;
+
+	rs->io.wq = create_singlethread_workqueue(DAEMON);
+	if (!rs->io.wq)
+		TI_ERR_RET("failed to create " DAEMON, -ENOMEM);
+
+	INIT_DELAYED_WORK(&rs->io.dws_do_raid, do_raid);
+	INIT_WORK(&rs->io.ws_do_table_event, do_table_event);
+	return 0;
+}
+
+/* Return pointer to raid_type structure for raid name. */
+static struct raid_type *get_raid_type(char *name)
+{
+	struct raid_type *r = ARRAY_END(raid_types);
+
+	while (r-- > raid_types) {
+		if (!strcmp(r->name, name))
+			return r;
+	}
+
+	return NULL;
+}
+
+/* FIXME: factor out to dm core. */
+static int multiple(sector_t a, sector_t b, sector_t *n)
+{
+	sector_t r = a;
+
+	sector_div(r, b);
+	*n = r;
+	return a == r * b;
+}
+
+/* Log RAID set information to kernel log. */
+static void rs_log(struct raid_set *rs, unsigned speed)
+{
+	unsigned p;
+	char buf[BDEVNAME_SIZE];
+
+	for (p = 0; p < rs->set.raid_devs; p++)
+		DMINFO("/dev/%s is raid disk %u%s",
+				bdevname(rs->dev[p].dev->bdev, buf), p,
+				(p == rs->set.pi) ? " (parity)" : "");
+
+	DMINFO("%d/%d/%d sectors chunk/io/recovery size, %u stripes\n"
+	       "algorithm \"%s\", %u chunks with %uMB/s\n"
+	       "%s set with net %u/%u devices",
+	       rs->set.chunk_size, rs->set.io_size, rs->recover.io_size,
+	       atomic_read(&rs->sc.stripes),
+	       rs->xor.f->name, rs->xor.chunks, mbpers(rs, speed),
+	       rs->set.raid_type->descr, rs->set.data_devs, rs->set.raid_devs);
+}
+
+/* Get all devices and offsets. */
+static int dev_parms(struct raid_set *rs, char **argv, int *p)
+{
+	struct dm_target *ti = rs->ti;
+
+	for (*p = 0; *p < rs->set.raid_devs; (*p)++, argv += 2) {
+		int r;
+		unsigned long long tmp;
+		struct raid_dev *dev = rs->dev + *p;
+
+		/* Get offset and device. */
+		if (sscanf(argv[1], "%llu", &tmp) != 1 ||
+		    tmp > rs->set.sectors_per_dev)
+			TI_ERR("Invalid RAID device offset parameter");
+
+		dev->start = tmp;
+		r = dm_get_device(ti, *argv, dm_table_get_mode(ti->table), &dev->dev);
+		if (r)
+			TI_ERR_RET("RAID device lookup failure", r);
+
+		r = raid_dev_lookup(rs, dev);
+		if (r != -ENODEV && r < *p) {
+			(*p)++;	/* Ensure dm_put_device() on actual device. */
+			TI_ERR_RET("Duplicate RAID device", -ENXIO);
+		}
+	}
+
+	return 0;
+}
+
+/* Set recovery bandwidth. */
+static void
+recover_set_bandwidth(struct raid_set *rs, unsigned bandwidth)
+{
+	rs->recover.bandwidth = bandwidth;
+	rs->recover.bandwidth_work = 100 / bandwidth;
+}
+
+/* Handle variable number of RAID parameters. */
+static int get_raid_variable_parms(struct dm_target *ti, char **argv, 
+				   struct variable_parms *vp)
+{
+	int p, value;
+	struct {
+		int action; /* -1: skip, 0: no pwer2 check, 1: power2 check */
+		char *errmsg;
+		int min, max;
+		int *var, *var2, *var3;
+	} argctr[] = {
+		{ 1,
+		  "Invalid chunk size; must be -1 or 2^^n and <= 16384",
+ 		  IO_SIZE_MIN, CHUNK_SIZE_MAX,
+		  &vp->chunk_size_parm, &vp->chunk_size, &vp->io_size },
+		{ 0,
+		  "Invalid number of stripes: must be -1 or >= 8 and <= 16384",
+		  STRIPES_MIN, STRIPES_MAX,
+		  &vp->stripes_parm, &vp->stripes, NULL },
+		{ 1,
+		  "Invalid io size; must -1 or >= 8, 2^^n and less equal "
+		  "min(BIO_MAX_SECTORS/2, chunk size)",
+		  IO_SIZE_MIN, 0, /* Needs to be updated in loop below. */
+		  &vp->io_size_parm, &vp->io_size, NULL },
+		{ 1,
+		  "Invalid recovery io size; must be -1 or "
+		  "2^^n and less equal BIO_MAX_SECTORS/2",
+		  RECOVER_IO_SIZE_MIN, BIO_MAX_SECTORS / 2,
+		  &vp->recover_io_size_parm, &vp->recover_io_size, NULL },
+		{ 0,
+		  "Invalid recovery bandwidth percentage; "
+		  "must be -1 or > 0 and <= 100",
+		  BANDWIDTH_MIN, BANDWIDTH_MAX,
+		  &vp->bandwidth_parm, &vp->bandwidth, NULL },
+		/* Handle sync argument seperately in loop. */
+		{ -1,
+		  "Invalid recovery switch; must be \"sync\" or \"nosync\"" },
+		{ 0,
+		  "Invalid number of recovery stripes;"
+		  "must be -1, > 0 and <= 16384",
+		  RECOVERY_STRIPES_MIN, RECOVERY_STRIPES_MAX,
+		  &vp->recovery_stripes_parm, &vp->recovery_stripes, NULL },
+	}, *varp;
+
+	/* Fetch # of variable raid parameters. */
+	if (sscanf(*(argv++), "%d", &vp->raid_parms) != 1 ||
+	    !range_ok(vp->raid_parms, 0, 7))
+		TI_ERR("Bad variable raid parameters number");
+
+	/* Preset variable RAID parameters. */
+	vp->chunk_size = CHUNK_SIZE_DEFAULT;
+	vp->io_size = IO_SIZE_DEFAULT;
+	vp->stripes = STRIPES_DEFAULT;
+	vp->recover_io_size = RECOVER_IO_SIZE_DEFAULT;
+	vp->bandwidth = BANDWIDTH_DEFAULT;
+	vp->recovery = 1;
+	vp->recovery_stripes = RECOVERY_STRIPES_DEFAULT;
+
+	/* Walk the array of argument constraints for all given ones. */
+	for (p = 0, varp = argctr; p < vp->raid_parms; p++, varp++) {
+	     	BUG_ON(varp >= ARRAY_END(argctr));
+
+		/* Special case for "[no]sync" string argument. */
+		if (varp->action < 0) {
+			if (!strcmp(*argv, "sync"))
+				;
+			else if (!strcmp(*argv, "nosync"))
+				vp->recovery = 0;
+			else
+				TI_ERR(varp->errmsg);
+
+			argv++;
+			continue;
+		}
+
+		/*
+		 * Special case for io_size depending
+		 * on previously set chunk size.
+		 */
+		if (p == 2)
+			varp->max = min(BIO_MAX_SECTORS / 2, vp->chunk_size);
+
+		if (sscanf(*(argv++), "%d", &value) != 1 ||
+		    (value != -1 &&
+		     ((varp->action && !POWER_OF_2(value)) ||
+		      !range_ok(value, varp->min, varp->max))))
+			TI_ERR(varp->errmsg);
+
+		*varp->var = value;
+		if (value != -1) {
+			if (varp->var2)
+				*varp->var2 = value;
+			if (varp->var3)
+				*varp->var3 = value;
+		}
+	}
+
+	return 0;
+}
+
+/* Parse optional locking parameters. */
+static int get_raid_locking_parms(struct dm_target *ti, char **argv,
+				  int *locking_parms,
+				  struct dm_raid45_locking_type **locking_type)
+{
+	if (!strnicmp(argv[0], "locking", strlen(argv[0]))) {
+		char *lckstr = argv[1];
+		size_t lcksz = strlen(lckstr);
+
+		if (!strnicmp(lckstr, "none", lcksz)) {
+			*locking_type = &locking_none;
+			*locking_parms = 2;
+		} else if (!strnicmp(lckstr, "cluster", lcksz)) {
+			DMERR("locking type \"%s\" not yet implemented",
+			      lckstr);
+			return -EINVAL;
+		} else {
+			DMERR("unknown locking type \"%s\"", lckstr);
+			return -EINVAL;
+		}
+	}
+
+	*locking_parms = 0;
+	*locking_type = &locking_none;
+	return 0;
+}
+
+/* Set backing device read ahead properties of RAID set. */
+static void rs_set_read_ahead(struct raid_set *rs,
+			      unsigned sectors, unsigned stripes)
+{
+	unsigned ra_pages = dm_div_up(sectors, SECTORS_PER_PAGE);
+	struct mapped_device *md = dm_table_get_md(rs->ti->table);
+	struct backing_dev_info *bdi = &dm_disk(md)->queue->backing_dev_info;
+
+	/* Set read-ahead for the RAID set and the component devices. */
+	if (ra_pages) {
+		unsigned p = rs->set.raid_devs;
+
+		bdi->ra_pages = stripes * ra_pages * rs->set.data_devs;
+
+		while (p--) {
+			struct request_queue *q =
+				bdev_get_queue(rs->dev[p].dev->bdev);
+
+			q->backing_dev_info.ra_pages = ra_pages;
+		}
+	}
+
+	dm_put(md);
+}
+
+/* Set congested function. */
+static void rs_set_congested_fn(struct raid_set *rs)
+{
+	struct mapped_device *md = dm_table_get_md(rs->ti->table);
+	struct backing_dev_info *bdi = &dm_disk(md)->queue->backing_dev_info;
+
+	/* Set congested function and data. */
+	bdi->congested_fn = rs_congested;
+	bdi->congested_data = rs;
+	dm_put(md);
+}
+
+/*
+ * Construct a RAID4/5 mapping:
+ *
+ * log_type #log_params <log_params> \
+ * raid_type [#parity_dev] #raid_variable_params <raid_params> \
+ * [locking "none"/"cluster"]
+ * #raid_devs #dev_to_initialize [<dev_path> <offset>]{3,}
+ *
+ * log_type = "core"/"disk",
+ * #log_params = 1-3 (1-2 for core dirty log type, 3 for disk dirty log only)
+ * log_params = [dirty_log_path] region_size [[no]sync])
+ *
+ * raid_type = "raid4", "raid5_la", "raid5_ra", "raid5_ls", "raid5_rs"
+ *
+ * #parity_dev = N if raid_type = "raid4"
+ * o N = -1: pick default = last device
+ * o N >= 0 and < #raid_devs: parity device index
+ *
+ * #raid_variable_params = 0-7; raid_params (-1 = default):
+ *   [chunk_size [#stripes [io_size [recover_io_size \
+ *    [%recovery_bandwidth [recovery_switch [#recovery_stripes]]]]]]]
+ *   o chunk_size (unit to calculate drive addresses; must be 2^^n, > 8
+ *     and <= CHUNK_SIZE_MAX)
+ *   o #stripes is number of stripes allocated to stripe cache
+ *     (must be > 1 and < STRIPES_MAX)
+ *   o io_size (io unit size per device in sectors; must be 2^^n and > 8)
+ *   o recover_io_size (io unit size per device for recovery in sectors;
+ must be 2^^n, > SECTORS_PER_PAGE and <= region_size)
+ *   o %recovery_bandwith is the maximum amount spend for recovery during
+ *     application io (1-100%)
+ *   o recovery switch = [sync|nosync]
+ *   o #recovery_stripes is the number of recovery stripes used for
+ *     parallel recovery of the RAID set
+ * If raid_variable_params = 0, defaults will be used.
+ * Any raid_variable_param can be set to -1 to apply a default
+ *
+ * #raid_devs = N (N >= 3)
+ *
+ * #dev_to_initialize = N
+ * -1: initialize parity on all devices
+ * >= 0 and < #raid_devs: initialize raid_path; used to force reconstruction
+ * of a failed devices content after replacement
+ *
+ * <dev_path> = device_path (eg, /dev/sdd1)
+ * <offset>   = begin at offset on <dev_path>
+ *
+ */
+#define	MIN_PARMS	13
+static int raid_ctr(struct dm_target *ti, unsigned argc, char **argv)
+{
+	int dev_to_init, dl_parms, i, locking_parms,
+	    parity_parm, pi = -1, r, raid_devs;
+	unsigned speed;
+	sector_t tmp, sectors_per_dev;
+	struct dm_raid45_locking_type *locking;
+	struct raid_set *rs;
+	struct raid_type *raid_type;
+	struct variable_parms parms;
+
+	/* Ensure minimum number of parameters. */
+	if (argc < MIN_PARMS)
+		TI_ERR("Not enough parameters");
+
+	/* Fetch # of dirty log parameters. */
+	if (sscanf(argv[1], "%d", &dl_parms) != 1 ||
+	    !range_ok(dl_parms, 1, 4711)) /* ;-) */
+		TI_ERR("Bad dirty log parameters number");
+
+	/* Check raid_type. */
+	raid_type = get_raid_type(argv[dl_parms + 2]);
+	if (!raid_type)
+		TI_ERR("Bad raid type");
+
+	/* In case of RAID4, parity drive is selectable. */
+	parity_parm = !!(raid_type->level == raid4);
+
+	/* Handle variable number of RAID parameters. */
+	r = get_raid_variable_parms(ti, argv + dl_parms + parity_parm + 3,
+				    &parms);
+	if (r)
+		return r;
+
+	/* Handle any locking parameters. */
+	r = get_raid_locking_parms(ti,
+				   argv + dl_parms + parity_parm +
+				   parms.raid_parms + 4,
+				   &locking_parms, &locking);
+	if (r)
+		return r;
+
+	/* # of raid devices. */
+	i = dl_parms + parity_parm + parms.raid_parms + locking_parms + 4;
+	if (sscanf(argv[i], "%d", &raid_devs) != 1 ||
+	    raid_devs < raid_type->minimal_devs)
+		TI_ERR("Invalid number of raid devices");
+
+	/* In case of RAID4, check parity drive index is in limits. */
+	if (raid_type->level == raid4) {
+		/* Fetch index of parity device. */
+		if (sscanf(argv[dl_parms + 3], "%d", &pi) != 1 ||
+		    (pi != -1 && !range_ok(pi, 0, raid_devs - 1)))
+			TI_ERR("Invalid RAID4 parity device index");
+	}
+
+	/*
+	 * Index of device to initialize starts at 0
+	 *
+	 * o -1 -> don't initialize a selected device;
+	 *         initialize parity conforming to algorithm
+	 * o 0..raid_devs-1 -> initialize respective device
+	 *   (used for reconstruction of a replaced device)
+	 */
+	if (sscanf(argv[dl_parms + parity_parm + parms.raid_parms +
+		   locking_parms + 5], "%d", &dev_to_init) != 1 ||
+	    !range_ok(dev_to_init, -1, raid_devs - 1))
+		TI_ERR("Invalid number for raid device to initialize");
+
+	/* Check # of raid device arguments. */
+	if (argc - dl_parms - parity_parm - parms.raid_parms - 6 !=
+	    2 * raid_devs)
+		TI_ERR("Wrong number of raid device/offset arguments");
+
+	/*
+	 * Check that the table length is devisable
+	 * w/o rest by (raid_devs - parity_devs)
+	 */
+	if (!multiple(ti->len, raid_devs - raid_type->parity_devs,
+		      &sectors_per_dev))
+		TI_ERR("Target length not divisible by number of data devices");
+
+	/*
+	 * Check that the device size is
+	 * devisable w/o rest by chunk size
+	 */
+	if (!multiple(sectors_per_dev, parms.chunk_size, &tmp))
+		TI_ERR("Device length not divisible by chunk_size");
+
+	/****************************************************************
+	 * Now that we checked the constructor arguments ->
+	 * let's allocate the RAID set
+	 ****************************************************************/
+	rs = context_alloc(raid_type, &parms, raid_devs, sectors_per_dev,
+			   ti, dl_parms, argv);
+	if (IS_ERR(rs))
+		return PTR_ERR(rs);
+
+
+	rs->set.dev_to_init = rs->set.dev_to_init_parm = dev_to_init;
+	rs->set.pi = rs->set.pi_parm = pi;
+
+	/* Set RAID4 parity drive index. */
+	if (raid_type->level == raid4)
+		rs->set.pi = (pi == -1) ? rs->set.data_devs : pi;
+
+	recover_set_bandwidth(rs, parms.bandwidth);
+
+	/* Use locking type to lock stripe access. */
+	rs->locking = locking;
+
+	/* Get the device/offset tupels. */
+	argv += dl_parms + 6 + parity_parm + parms.raid_parms;
+	r = dev_parms(rs, argv, &i);
+	if (r)
+		goto err;
+
+	/* Set backing device information (eg. read ahead). */
+	rs_set_read_ahead(rs, 2 * rs->set.chunk_size, 4 /* stripes */);
+	rs_set_congested_fn(rs); /* Set congested function. */
+	SetRSCheckOverwrite(rs); /* Allow chunk overwrite checks. */
+	speed = xor_optimize(rs); /* Select best xor algorithm. */
+
+	/* Set for recovery of any nosync regions. */
+	if (parms.recovery)
+		SetRSRecover(rs);
+	else {
+		/*
+		 * Need to free recovery stripe(s) here in case
+		 * of nosync, because xor_optimize uses one.
+		 */
+		set_start_recovery(rs);
+		set_end_recovery(rs);
+		stripe_recover_free(rs);
+	}
+
+	/*
+	 * Make sure that dm core only hands maximum io size
+	 * length down and pays attention to io boundaries.
+	 */
+	ti->max_io_len = rs->set.io_size;
+	ti->private = rs;
+
+	/* Initialize work queue to handle this RAID set's io. */
+	r = rs_workqueue_init(rs);
+	if (r)
+		goto err;
+
+	rs_log(rs, speed); /* Log information about RAID set. */
+	return 0;
+
+err:
+	context_free(rs, i);
+	return r;
+}
+
+/*
+ * Destruct a raid mapping
+ */
+static void raid_dtr(struct dm_target *ti)
+{
+	struct raid_set *rs = ti->private;
+
+	destroy_workqueue(rs->io.wq);
+	context_free(rs, rs->set.raid_devs);
+}
+
+/* Raid mapping function. */
+static int raid_map(struct dm_target *ti, struct bio *bio)
+{
+	/* I don't want to waste stripe cache capacity. */
+	if (bio_rw(bio) == READA)
+		return -EIO;
+	else {
+		struct raid_set *rs = ti->private;
+
+		/*
+		 * Get io reference to be waiting for to drop
+		 * to zero on device suspension/destruction.
+		 */
+		io_get(rs);
+		bio->bi_sector -= ti->begin;	/* Remap sector. */
+
+		/* Queue io to RAID set. */
+		mutex_lock(&rs->io.in_lock);
+		bio_list_add(&rs->io.in, bio);
+		mutex_unlock(&rs->io.in_lock);
+
+		/* Wake daemon to process input list. */
+		wake_do_raid(rs);
+
+		/* REMOVEME: statistics. */
+		atomic_inc(rs->stats + (bio_data_dir(bio) == READ ?
+				        S_BIOS_READ : S_BIOS_WRITE));
+		return DM_MAPIO_SUBMITTED;	/* Handle later. */
+	}
+}
+
+/* Device suspend. */
+static void raid_presuspend(struct dm_target *ti)
+{
+	struct raid_set *rs = ti->private;
+	struct dm_dirty_log *dl = rs->recover.dl;
+
+	SetRSSuspend(rs);
+
+	if (RSRecover(rs))
+		dm_rh_stop_recovery(rs->recover.rh);
+
+	cancel_delayed_work(&rs->io.dws_do_raid);
+	flush_workqueue(rs->io.wq);
+	wait_ios(rs);	/* Wait for completion of all ios being processed. */
+
+	if (dl->type->presuspend && dl->type->presuspend(dl))
+		/* FIXME: need better error handling. */
+		DMWARN("log presuspend failed");
+}
+
+static void raid_postsuspend(struct dm_target *ti)
+{
+	struct raid_set *rs = ti->private;
+	struct dm_dirty_log *dl = rs->recover.dl;
+
+	if (dl->type->postsuspend && dl->type->postsuspend(dl))
+		/* FIXME: need better error handling. */
+		DMWARN("log postsuspend failed");
+
+}
+
+/* Device resume. */
+static void raid_resume(struct dm_target *ti)
+{
+	struct raid_set *rs = ti->private;
+	struct recover *rec = &rs->recover;
+	struct dm_dirty_log *dl = rec->dl;
+
+	if (dl->type->resume && dl->type->resume(dl))
+		/* Resume dirty log. */
+		/* FIXME: need better error handling. */
+		DMWARN("log resume failed");
+
+	rec->nr_regions_to_recover =
+		rec->nr_regions - dl->type->get_sync_count(dl);
+
+	/* Restart any unfinished recovery. */
+	if (RSRecover(rs)) {
+		set_start_recovery(rs);
+		dm_rh_start_recovery(rec->rh);
+	}
+
+	ClearRSSuspend(rs);
+	wake_do_raid(rs);
+}
+
+/* Return stripe cache size. */
+static unsigned sc_size(struct raid_set *rs)
+{
+	return to_sector(atomic_read(&rs->sc.stripes) *
+			 (sizeof(struct stripe) +
+			  (sizeof(struct stripe_chunk) +
+			   (sizeof(struct page_list) +
+			    to_bytes(rs->set.io_size) *
+			    rs->set.raid_devs)) +
+			  (rs->recover.end_jiffies ?
+			   0 : rs->recover.recovery_stripes *
+			   to_bytes(rs->set.raid_devs * rs->recover.io_size))));
+}
+
+/* REMOVEME: status output for development. */
+static void raid_devel_stats(struct dm_target *ti, char *result,
+			     unsigned *size, unsigned maxlen)
+{
+	unsigned sz = *size;
+	unsigned long j;
+	char buf[BDEVNAME_SIZE], *p;
+	struct stats_map *sm;
+	struct raid_set *rs = ti->private;
+	struct recover *rec = &rs->recover;
+	struct timespec ts;
+
+	DMEMIT("%s %s %u\n", version, rs->xor.f->name, rs->xor.chunks);
+	DMEMIT("act_ios=%d ", io_ref(rs));
+	DMEMIT("act_ios_max=%d\n", atomic_read(&rs->io.in_process_max));
+	DMEMIT("act_stripes=%d ", sc_active(&rs->sc));
+	DMEMIT("act_stripes_max=%d\n",
+	       atomic_read(&rs->sc.active_stripes_max));
+
+	for (sm = stats_map; sm < ARRAY_END(stats_map); sm++)
+		DMEMIT("%s%d", sm->str, atomic_read(rs->stats + sm->type));
+
+	DMEMIT(" checkovr=%s\n", RSCheckOverwrite(rs) ? "on" : "off");
+	DMEMIT("sc=%u/%u/%u/%u/%u/%u/%u\n", rs->set.chunk_size,
+	       atomic_read(&rs->sc.stripes), rs->set.io_size,
+	       rec->recovery_stripes, rec->io_size, rs->sc.hash.buckets,
+	       sc_size(rs));
+
+	j = (rec->end_jiffies ? rec->end_jiffies : jiffies) -
+	    rec->start_jiffies;
+	jiffies_to_timespec(j, &ts);
+	sprintf(buf, "%ld.%ld", ts.tv_sec, ts.tv_nsec);
+	p = strchr(buf, '.');
+	p[3] = 0;
+
+	DMEMIT("rg=%llu/%llu/%llu/%u %s\n",
+	       (unsigned long long) rec->nr_regions_recovered,
+	       (unsigned long long) rec->nr_regions_to_recover,
+	       (unsigned long long) rec->nr_regions, rec->bandwidth, buf);
+
+	*size = sz;
+}
+
+static void raid_status(struct dm_target *ti, status_type_t type,
+		       unsigned status_flags, char *result, unsigned maxlen)
+{
+	unsigned p, sz = 0;
+	char buf[BDEVNAME_SIZE];
+	struct raid_set *rs = ti->private;
+	int raid_parms[] = {
+		rs->set.chunk_size_parm,
+		rs->sc.stripes_parm,
+		rs->set.io_size_parm,
+		rs->recover.io_size_parm,
+		rs->recover.bandwidth_parm,
+		-2,
+		rs->recover.recovery_stripes,
+	};
+
+	switch (type) {
+	case STATUSTYPE_INFO:
+		/* REMOVEME: statistics. */
+		if (RSDevelStats(rs))
+			raid_devel_stats(ti, result, &sz, maxlen);
+
+		DMEMIT("%u ", rs->set.raid_devs);
+
+		for (p = 0; p < rs->set.raid_devs; p++)
+			DMEMIT("%s ",
+			       format_dev_t(buf, rs->dev[p].dev->bdev->bd_dev));
+
+		DMEMIT("1 ");
+		for (p = 0; p < rs->set.raid_devs; p++) {
+			DMEMIT("%c", !DevFailed(rs->dev + p) ? 'A' : 'D');
+
+			if (p == rs->set.pi)
+				DMEMIT("p");
+
+			if (rs->set.dev_to_init == p)
+				DMEMIT("i");
+		}
+
+		break;
+	case STATUSTYPE_TABLE:
+		sz = rs->recover.dl->type->status(rs->recover.dl, type,
+						  result, maxlen);
+		DMEMIT("%s %u ", rs->set.raid_type->name,
+		       rs->set.raid_parms);
+
+		for (p = 0; p < rs->set.raid_parms; p++) {
+			if (raid_parms[p] > -2)
+				DMEMIT("%d ", raid_parms[p]);
+			else
+				DMEMIT("%s ", rs->recover.recovery ?
+					      "sync" : "nosync");
+		}
+
+		DMEMIT("%u %d ", rs->set.raid_devs, rs->set.dev_to_init);
+
+		for (p = 0; p < rs->set.raid_devs; p++)
+			DMEMIT("%s %llu ",
+			       format_dev_t(buf, rs->dev[p].dev->bdev->bd_dev),
+			       (unsigned long long) rs->dev[p].start);
+	}
+}
+
+/*
+ * Message interface
+ */
+enum raid_msg_actions {
+	act_bw,			/* Recovery bandwidth switch. */
+	act_dev,		/* Device failure switch. */
+	act_overwrite,		/* Stripe overwrite check. */
+	act_stats,		/* Development statistics switch. */
+	act_sc,			/* Stripe cache switch. */
+
+	act_on,			/* Set entity on. */
+	act_off,		/* Set entity off. */
+	act_reset,		/* Reset entity. */
+
+	act_set = act_on,	/* Set # absolute. */
+	act_grow = act_off,	/* Grow # by an amount. */
+	act_shrink = act_reset,	/* Shrink # by an amount. */
+};
+
+/* Turn a delta into an absolute value. */
+static int _absolute(unsigned long action, int act, int r)
+{
+	/* Make delta absolute. */
+	if (test_bit(act_set, &action))
+		;
+	else if (test_bit(act_grow, &action))
+		r += act;
+	else if (test_bit(act_shrink, &action))
+		r = act - r;
+	else
+		r = -EINVAL;
+
+	return r;
+}
+
+ /* Change recovery io bandwidth. */
+static int bandwidth_change(struct dm_msg *msg, void *context)
+{
+	struct raid_set *rs = context;
+	int act = rs->recover.bandwidth;
+	int bandwidth = DM_MSG_INT_ARG(msg);
+
+	if (range_ok(bandwidth, BANDWIDTH_MIN, BANDWIDTH_MAX)) {
+		/* Make delta bandwidth absolute. */
+		bandwidth = _absolute(msg->action, act, bandwidth);
+
+		/* Check range. */
+		if (range_ok(bandwidth, BANDWIDTH_MIN, BANDWIDTH_MAX)) {
+			recover_set_bandwidth(rs, bandwidth);
+			return 0;
+		}
+	}
+
+	set_bit(dm_msg_ret_arg, &msg->ret);
+	set_bit(dm_msg_ret_inval, &msg->ret);
+	return -EINVAL;
+}
+
+/* Set/reset development feature flags. */
+static int devel_flags(struct dm_msg *msg, void *context)
+{
+	struct raid_set *rs = context;
+
+	if (test_bit(act_on, &msg->action))
+		return test_and_set_bit(msg->spec->parm,
+					&rs->io.flags) ? -EPERM : 0;
+	else if (test_bit(act_off, &msg->action))
+		return test_and_clear_bit(msg->spec->parm,
+					  &rs->io.flags) ? 0 : -EPERM;
+	else if (test_bit(act_reset, &msg->action)) {
+		if (test_bit(act_stats, &msg->action)) {
+			stats_reset(rs);
+			goto on;
+		} else if (test_bit(act_overwrite, &msg->action)) {
+on:
+			set_bit(msg->spec->parm, &rs->io.flags);
+			return 0;
+		}
+	}
+
+	return -EINVAL;
+}
+
+/* Resize the stripe cache. */
+static int sc_resize(struct dm_msg *msg, void *context)
+{
+	int act, stripes;
+	struct raid_set *rs = context;
+
+	/* Deny permission in case the daemon is still resizing!. */
+	if (atomic_read(&rs->sc.stripes_to_set))
+		return -EPERM;
+
+	stripes = DM_MSG_INT_ARG(msg);
+	if (stripes > 0) {
+		act = atomic_read(&rs->sc.stripes);
+
+		/* Make delta stripes absolute. */
+		stripes = _absolute(msg->action, act, stripes);
+
+		/*
+		 * Check range and that the # of stripes changes.
+		 * We leave the resizing to the wroker.
+		 */
+		if (range_ok(stripes, STRIPES_MIN, STRIPES_MAX) &&
+		    stripes != atomic_read(&rs->sc.stripes)) {
+			atomic_set(&rs->sc.stripes_to_set, stripes);
+			wake_do_raid(rs);
+			return 0;
+		}
+	}
+
+	set_bit(dm_msg_ret_arg, &msg->ret);
+	set_bit(dm_msg_ret_inval, &msg->ret);
+	return -EINVAL;
+}
+
+/* Parse the RAID message action. */
+/*
+ * 'ba[ndwidth] {se[t],g[row],sh[rink]} #'	# e.g 'ba se 50'
+ * "o[verwrite]  {on,of[f],r[eset]}'		# e.g. 'o of'
+ * 'sta[tistics] {on,of[f],r[eset]}'		# e.g. 'stat of'
+ * 'str[ipecache] {se[t],g[row],sh[rink]} #'	# e.g. 'stripe set 1024'
+ *
+ */
+static int raid_message(struct dm_target *ti, unsigned argc, char **argv)
+{
+	/* Variables to store the parsed parameters im. */
+	static int i[2];
+	static unsigned long *i_arg[] = {
+		(unsigned long *) i + 0,
+		(unsigned long *) i + 1,
+	};
+
+	/* Declare all message option strings. */
+	static char *str_sgs[] = { "set", "grow", "shrink" };
+	static char *str_oor[] = { "on", "off", "reset" };
+
+	/* Declare all actions. */
+	static unsigned long act_sgs[] = { act_set, act_grow, act_shrink };
+	static unsigned long act_oor[] = { act_on, act_off, act_reset };
+
+	/* Bandwidth option. */
+	static struct dm_message_option bw_opt = { 3, str_sgs, act_sgs };
+	static struct dm_message_argument bw_args = {
+		1, i_arg, { dm_msg_int_t }
+	};
+
+	static struct dm_message_argument null_args = {
+		0, NULL, { dm_msg_int_t }
+	};
+
+	/* Overwrite and statistics option. */
+	static struct dm_message_option ovr_stats_opt = { 3, str_oor, act_oor };
+
+	/* Sripecache option. */
+	static struct dm_message_option stripe_opt = { 3, str_sgs, act_sgs };
+
+	/* Declare messages. */
+	static struct dm_msg_spec specs[] = {
+		{ "bandwidth", act_bw, &bw_opt, &bw_args,
+		  0, bandwidth_change },
+		{ "overwrite", act_overwrite, &ovr_stats_opt, &null_args,
+		  RS_CHECK_OVERWRITE, devel_flags },
+		{ "statistics", act_stats, &ovr_stats_opt, &null_args,
+		  RS_DEVEL_STATS, devel_flags },
+		{ "stripecache", act_sc, &stripe_opt, &bw_args,
+		  0, sc_resize },
+	};
+
+	/* The message for the parser. */
+	struct dm_msg msg = {
+		.num_specs = ARRAY_SIZE(specs),
+		.specs = specs,
+	};
+
+	return dm_message_parse(TARGET, &msg, ti->private, argc, argv);
+}
+/*
+ * END message interface
+ */
+
+static struct target_type raid_target = {
+	.name = "raid45",
+	.version = {1, 0, 0},
+	.module = THIS_MODULE,
+	.ctr = raid_ctr,
+	.dtr = raid_dtr,
+	.map = raid_map,
+	.presuspend = raid_presuspend,
+	.postsuspend = raid_postsuspend,
+	.resume = raid_resume,
+	.status = raid_status,
+	.message = raid_message,
+};
+
+static void init_exit(const char *bad_msg, const char *good_msg, int r)
+{
+	if (r)
+		DMERR("Failed to %sregister target [%d]", bad_msg, r);
+	else
+		DMINFO("%s %s", good_msg, version);
+}
+
+static int __init dm_raid_init(void)
+{
+	int r = dm_register_target(&raid_target);
+
+	init_exit("", "initialized", r);
+	return r;
+}
+
+static void __exit dm_raid_exit(void)
+{
+	dm_unregister_target(&raid_target);
+	init_exit("un", "exit", 0);
+}
+
+/* Module hooks. */
+module_init(dm_raid_init);
+module_exit(dm_raid_exit);
+
+MODULE_DESCRIPTION(DM_NAME " raid4/5 target");
+MODULE_AUTHOR("Heinz Mauelshagen <hjm@redhat.com>");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("dm-raid4");
+MODULE_ALIAS("dm-raid5");
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/dm-raid4-5/dm-raid4-5.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2006  Red Hat GmbH
+ *
+ * Module Author: Heinz Mauelshagen (Mauelshagen@RedHat.com)
+ *
+ * This file is released under the GPL.
+ *
+ */
+
+#ifndef _DM_RAID45_H
+#define _DM_RAID45_H
+
+/* Factor out to dm.h! */
+#define	STR_LEN(ptr, str) ptr, str, strlen(ptr)
+
+enum lock_type { RAID45_EX, RAID45_SHARED };
+
+struct dmraid45_locking_type {
+        /* Request a lock on a stripe. */
+        void* (*lock)(sector_t key, enum lock_type type);
+
+        /* Release a lock on a stripe. */
+        void (*unlock)(void *lock_handle);
+
+};
+
+#endif
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/dm-raid4-5/dm-raid45.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2006-2008 Red Hat, Inc. All rights reserved.
+ *
+ * Module Author: Heinz Mauelshagen (Mauelshagen@RedHat.com)
+ *
+ * Locking definitions for the device-mapper RAID45 target.
+ *
+ * This file is released under the GPL.
+ *
+ */
+
+#ifndef _DM_RAID45_H
+#define _DM_RAID45_H
+
+/* Factor out to dm.h! */
+#define	STR_LEN(ptr, str)	(ptr), (str), strlen((ptr))
+
+enum dm_lock_type { DM_RAID45_EX, DM_RAID45_SHARED };
+
+struct dm_raid45_locking_type {
+	/* Request a lock on a stripe. */
+	void* (*lock)(sector_t key, enum dm_lock_type type);
+
+	/* Release a lock on a stripe. */
+	void (*unlock)(void *lock_handle);
+};
+
+#endif
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/dm-raid4-5/dm-region-hash.c
@@ -0,0 +1,719 @@
+/*
+ * Copyright (C) 2003 Sistina Software Limited.
+ * Copyright (C) 2004-2008 Red Hat, Inc. All rights reserved.
+ *
+ * This file is released under the GPL.
+ */
+
+#include <linux/dm-dirty-log.h>
+#include "dm-region-hash.h"
+
+#include <linux/ctype.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/vmalloc.h>
+
+#include "dm.h"
+
+#define	DM_MSG_PREFIX	"region hash"
+
+/*-----------------------------------------------------------------
+ * Region hash
+ *
+ * The mirror splits itself up into discrete regions.  Each
+ * region can be in one of three states: clean, dirty,
+ * nosync.  There is no need to put clean regions in the hash.
+ *
+ * In addition to being present in the hash table a region _may_
+ * be present on one of three lists.
+ *
+ *   clean_regions: Regions on this list have no io pending to
+ *   them, they are in sync, we are no longer interested in them,
+ *   they are dull.  dm_rh_update_states() will remove them from the
+ *   hash table.
+ *
+ *   quiesced_regions: These regions have been spun down, ready
+ *   for recovery.  rh_recovery_start() will remove regions from
+ *   this list and hand them to kmirrord, which will schedule the
+ *   recovery io with kcopyd.
+ *
+ *   recovered_regions: Regions that kcopyd has successfully
+ *   recovered.  dm_rh_update_states() will now schedule any delayed
+ *   io, up the recovery_count, and remove the region from the
+ *   hash.
+ *
+ * There are 2 locks:
+ *   A rw spin lock 'hash_lock' protects just the hash table,
+ *   this is never held in write mode from interrupt context,
+ *   which I believe means that we only have to disable irqs when
+ *   doing a write lock.
+ *
+ *   An ordinary spin lock 'region_lock' that protects the three
+ *   lists in the region_hash, with the 'state', 'list' and
+ *   'delayed_bios' fields of the regions.  This is used from irq
+ *   context, so all other uses will have to suspend local irqs.
+ *---------------------------------------------------------------*/
+struct dm_region_hash {
+	uint32_t region_size;
+	unsigned region_shift;
+
+	/* holds persistent region state */
+	struct dm_dirty_log *log;
+
+	/* hash table */
+	rwlock_t hash_lock;
+	mempool_t *region_pool;
+	unsigned mask;
+	unsigned nr_buckets;
+	unsigned prime;
+	unsigned shift;
+	struct list_head *buckets;
+
+	unsigned max_recovery; /* Max # of regions to recover in parallel */
+
+	spinlock_t region_lock;
+	atomic_t recovery_in_flight;
+	struct semaphore recovery_count;
+	struct list_head clean_regions;
+	struct list_head quiesced_regions;
+	struct list_head recovered_regions;
+	struct list_head failed_recovered_regions;
+
+	void *context;
+	sector_t target_begin;
+
+	/* Callback function to schedule bios writes */
+	void (*dispatch_bios)(void *context, struct bio_list *bios);
+
+	/* Callback function to wakeup callers worker thread. */
+	void (*wakeup_workers)(void *context);
+
+	/* Callback function to wakeup callers recovery waiters. */
+	void (*wakeup_all_recovery_waiters)(void *context);
+};
+
+struct dm_region {
+	struct dm_region_hash *rh;	/* FIXME: can we get rid of this ? */
+	region_t key;
+	int state;
+
+	struct list_head hash_list;
+	struct list_head list;
+
+	atomic_t pending;
+	struct bio_list delayed_bios;
+};
+
+/*
+ * Conversion fns
+ */
+region_t dm_rh_sector_to_region(struct dm_region_hash *rh, sector_t sector)
+{
+	return sector >> rh->region_shift;
+}
+// EXPORT_SYMBOL_GPL(dm_rh_sector_to_region);
+
+sector_t dm_rh_region_to_sector(struct dm_region_hash *rh, region_t region)
+{
+	return region << rh->region_shift;
+}
+// EXPORT_SYMBOL_GPL(dm_rh_region_to_sector);
+
+region_t dm_rh_bio_to_region(struct dm_region_hash *rh, struct bio *bio)
+{
+	return dm_rh_sector_to_region(rh, bio->bi_sector - rh->target_begin);
+}
+// EXPORT_SYMBOL_GPL(dm_rh_bio_to_region);
+
+void *dm_rh_region_context(struct dm_region *reg)
+{
+	return reg->rh->context;
+}
+// EXPORT_SYMBOL_GPL(dm_rh_region_context);
+
+region_t dm_rh_get_region_key(struct dm_region *reg)
+{
+	return reg->key;
+}
+// EXPORT_SYMBOL_GPL(dm_rh_get_region_key);
+
+sector_t dm_rh_get_region_size(struct dm_region_hash *rh)
+{
+	return rh->region_size;
+}
+// EXPORT_SYMBOL_GPL(dm_rh_get_region_size);
+
+/*
+ * FIXME: shall we pass in a structure instead of all these args to
+ * dm_region_hash_create()????
+ */
+#define RH_HASH_MULT 2654435387U
+#define RH_HASH_SHIFT 12
+
+#define MIN_REGIONS 64
+struct dm_region_hash *dm_region_hash_create(
+		void *context, void (*dispatch_bios)(void *context,
+						     struct bio_list *bios),
+		void (*wakeup_workers)(void *context),
+		void (*wakeup_all_recovery_waiters)(void *context),
+		sector_t target_begin, unsigned max_recovery,
+		struct dm_dirty_log *log, uint32_t region_size,
+		region_t nr_regions)
+{
+	struct dm_region_hash *rh;
+	unsigned nr_buckets, max_buckets;
+	size_t i;
+
+	/*
+	 * Calculate a suitable number of buckets for our hash
+	 * table.
+	 */
+	max_buckets = nr_regions >> 6;
+	for (nr_buckets = 128u; nr_buckets < max_buckets; nr_buckets <<= 1)
+		;
+	nr_buckets >>= 1;
+
+	rh = kmalloc(sizeof(*rh), GFP_KERNEL);
+	if (!rh) {
+		DMERR("unable to allocate region hash memory");
+		return ERR_PTR(-ENOMEM);
+	}
+
+	rh->context = context;
+	rh->dispatch_bios = dispatch_bios;
+	rh->wakeup_workers = wakeup_workers;
+	rh->wakeup_all_recovery_waiters = wakeup_all_recovery_waiters;
+	rh->target_begin = target_begin;
+	rh->max_recovery = max_recovery;
+	rh->log = log;
+	rh->region_size = region_size;
+	rh->region_shift = ffs(region_size) - 1;
+	rwlock_init(&rh->hash_lock);
+	rh->mask = nr_buckets - 1;
+	rh->nr_buckets = nr_buckets;
+
+	rh->shift = RH_HASH_SHIFT;
+	rh->prime = RH_HASH_MULT;
+
+	rh->buckets = vmalloc(nr_buckets * sizeof(*rh->buckets));
+	if (!rh->buckets) {
+		DMERR("unable to allocate region hash bucket memory");
+		kfree(rh);
+		return ERR_PTR(-ENOMEM);
+	}
+
+	for (i = 0; i < nr_buckets; i++)
+		INIT_LIST_HEAD(rh->buckets + i);
+
+	spin_lock_init(&rh->region_lock);
+	sema_init(&rh->recovery_count, 0);
+	atomic_set(&rh->recovery_in_flight, 0);
+	INIT_LIST_HEAD(&rh->clean_regions);
+	INIT_LIST_HEAD(&rh->quiesced_regions);
+	INIT_LIST_HEAD(&rh->recovered_regions);
+	INIT_LIST_HEAD(&rh->failed_recovered_regions);
+
+	rh->region_pool = mempool_create_kmalloc_pool(MIN_REGIONS,
+						      sizeof(struct dm_region));
+	if (!rh->region_pool) {
+		vfree(rh->buckets);
+		kfree(rh);
+		rh = ERR_PTR(-ENOMEM);
+	}
+
+	return rh;
+}
+// EXPORT_SYMBOL_GPL(dm_region_hash_create);
+
+void dm_region_hash_destroy(struct dm_region_hash *rh)
+{
+	unsigned h;
+	struct dm_region *reg, *nreg;
+
+	BUG_ON(!list_empty(&rh->quiesced_regions));
+	for (h = 0; h < rh->nr_buckets; h++) {
+		list_for_each_entry_safe(reg, nreg, rh->buckets + h,
+					 hash_list) {
+			BUG_ON(atomic_read(&reg->pending));
+			mempool_free(reg, rh->region_pool);
+		}
+	}
+
+	if (rh->log)
+		dm_dirty_log_destroy(rh->log);
+
+	if (rh->region_pool)
+		mempool_destroy(rh->region_pool);
+
+	vfree(rh->buckets);
+	kfree(rh);
+}
+// EXPORT_SYMBOL_GPL(dm_region_hash_destroy);
+
+struct dm_dirty_log *dm_rh_dirty_log(struct dm_region_hash *rh)
+{
+	return rh->log;
+}
+// EXPORT_SYMBOL_GPL(dm_rh_dirty_log);
+
+static unsigned rh_hash(struct dm_region_hash *rh, region_t region)
+{
+	return (unsigned) ((region * rh->prime) >> rh->shift) & rh->mask;
+}
+
+static struct dm_region *__rh_lookup(struct dm_region_hash *rh, region_t region)
+{
+	struct dm_region *reg;
+	struct list_head *bucket = rh->buckets + rh_hash(rh, region);
+
+	list_for_each_entry(reg, bucket, hash_list)
+		if (reg->key == region)
+			return reg;
+
+	return NULL;
+}
+
+static void __rh_insert(struct dm_region_hash *rh, struct dm_region *reg)
+{
+	list_add(&reg->hash_list, rh->buckets + rh_hash(rh, reg->key));
+}
+
+static struct dm_region *__rh_alloc(struct dm_region_hash *rh, region_t region)
+{
+	struct dm_region *reg, *nreg;
+
+	nreg = mempool_alloc(rh->region_pool, GFP_ATOMIC);
+	if (unlikely(!nreg))
+		nreg = kmalloc(sizeof(*nreg), GFP_NOIO | __GFP_NOFAIL);
+
+	nreg->state = rh->log->type->in_sync(rh->log, region, 1) ?
+		      DM_RH_CLEAN : DM_RH_NOSYNC;
+	nreg->rh = rh;
+	nreg->key = region;
+	INIT_LIST_HEAD(&nreg->list);
+	atomic_set(&nreg->pending, 0);
+	bio_list_init(&nreg->delayed_bios);
+
+	write_lock_irq(&rh->hash_lock);
+	reg = __rh_lookup(rh, region);
+	if (reg)
+		/* We lost the race. */
+		mempool_free(nreg, rh->region_pool);
+	else {
+		__rh_insert(rh, nreg);
+		if (nreg->state == DM_RH_CLEAN) {
+			spin_lock(&rh->region_lock);
+			list_add(&nreg->list, &rh->clean_regions);
+			spin_unlock(&rh->region_lock);
+		}
+
+		reg = nreg;
+	}
+	write_unlock_irq(&rh->hash_lock);
+
+	return reg;
+}
+
+static struct dm_region *__rh_find(struct dm_region_hash *rh, region_t region)
+{
+	struct dm_region *reg;
+
+	reg = __rh_lookup(rh, region);
+	if (!reg) {
+		read_unlock(&rh->hash_lock);
+		reg = __rh_alloc(rh, region);
+		read_lock(&rh->hash_lock);
+	}
+
+	return reg;
+}
+
+int dm_rh_get_state(struct dm_region_hash *rh, region_t region, int may_block)
+{
+	int r;
+	struct dm_region *reg;
+
+	read_lock(&rh->hash_lock);
+	reg = __rh_lookup(rh, region);
+	read_unlock(&rh->hash_lock);
+
+	if (reg)
+		return reg->state;
+
+	/*
+	 * The region wasn't in the hash, so we fall back to the
+	 * dirty log.
+	 */
+	r = rh->log->type->in_sync(rh->log, region, may_block);
+
+	/*
+	 * Any error from the dirty log (eg. -EWOULDBLOCK) gets
+	 * taken as a DM_RH_NOSYNC
+	 */
+	return r == 1 ? DM_RH_CLEAN : DM_RH_NOSYNC;
+}
+// EXPORT_SYMBOL_GPL(dm_rh_get_state);
+
+static void complete_resync_work(struct dm_region *reg, int success)
+{
+	struct dm_region_hash *rh = reg->rh;
+
+	rh->log->type->set_region_sync(rh->log, reg->key, success);
+
+	/*
+	 * Dispatch the bios before we call 'wake_up_all'.
+	 * This is important because if we are suspending,
+	 * we want to know that recovery is complete and
+	 * the work queue is flushed.  If we wake_up_all
+	 * before we dispatch_bios (queue bios and call wake()),
+	 * then we risk suspending before the work queue
+	 * has been properly flushed.
+	 */
+	rh->dispatch_bios(rh->context, &reg->delayed_bios);
+	if (atomic_dec_and_test(&rh->recovery_in_flight))
+		rh->wakeup_all_recovery_waiters(rh->context);
+	up(&rh->recovery_count);
+}
+
+/* dm_rh_mark_nosync
+ * @ms
+ * @bio
+ * @done
+ * @error
+ *
+ * The bio was written on some mirror(s) but failed on other mirror(s).
+ * We can successfully endio the bio but should avoid the region being
+ * marked clean by setting the state DM_RH_NOSYNC.
+ *
+ * This function is _not_ safe in interrupt context!
+ */
+void dm_rh_mark_nosync(struct dm_region_hash *rh,
+		       struct bio *bio, unsigned done, int error)
+{
+	unsigned long flags;
+	struct dm_dirty_log *log = rh->log;
+	struct dm_region *reg;
+	region_t region = dm_rh_bio_to_region(rh, bio);
+	int recovering = 0;
+
+	/* We must inform the log that the sync count has changed. */
+	log->type->set_region_sync(log, region, 0);
+
+	read_lock(&rh->hash_lock);
+	reg = __rh_find(rh, region);
+	read_unlock(&rh->hash_lock);
+
+	/* region hash entry should exist because write was in-flight */
+	BUG_ON(!reg);
+	BUG_ON(!list_empty(&reg->list));
+
+	spin_lock_irqsave(&rh->region_lock, flags);
+	/*
+	 * Possible cases:
+	 *   1) DM_RH_DIRTY
+	 *   2) DM_RH_NOSYNC: was dirty, other preceeding writes failed
+	 *   3) DM_RH_RECOVERING: flushing pending writes
+	 * Either case, the region should have not been connected to list.
+	 */
+	recovering = (reg->state == DM_RH_RECOVERING);
+	reg->state = DM_RH_NOSYNC;
+	BUG_ON(!list_empty(&reg->list));
+	spin_unlock_irqrestore(&rh->region_lock, flags);
+
+	bio_endio(bio, error);
+	if (recovering)
+		complete_resync_work(reg, 0);
+}
+// EXPORT_SYMBOL_GPL(dm_rh_mark_nosync);
+
+void dm_rh_update_states(struct dm_region_hash *rh, int errors_handled)
+{
+	struct dm_region *reg, *next;
+
+	LIST_HEAD(clean);
+	LIST_HEAD(recovered);
+	LIST_HEAD(failed_recovered);
+
+	/*
+	 * Quickly grab the lists.
+	 */
+	write_lock_irq(&rh->hash_lock);
+	spin_lock(&rh->region_lock);
+	if (!list_empty(&rh->clean_regions)) {
+		list_splice_init(&rh->clean_regions, &clean);
+
+		list_for_each_entry(reg, &clean, list)
+			list_del(&reg->hash_list);
+	}
+
+	if (!list_empty(&rh->recovered_regions)) {
+		list_splice_init(&rh->recovered_regions, &recovered);
+
+		list_for_each_entry(reg, &recovered, list)
+			list_del(&reg->hash_list);
+	}
+
+	if (!list_empty(&rh->failed_recovered_regions)) {
+		list_splice_init(&rh->failed_recovered_regions,
+				 &failed_recovered);
+
+		list_for_each_entry(reg, &failed_recovered, list)
+			list_del(&reg->hash_list);
+	}
+
+	spin_unlock(&rh->region_lock);
+	write_unlock_irq(&rh->hash_lock);
+
+	/*
+	 * All the regions on the recovered and clean lists have
+	 * now been pulled out of the system, so no need to do
+	 * any more locking.
+	 */
+	list_for_each_entry_safe(reg, next, &recovered, list) {
+		rh->log->type->clear_region(rh->log, reg->key);
+		complete_resync_work(reg, 1);
+		mempool_free(reg, rh->region_pool);
+	}
+
+	list_for_each_entry_safe(reg, next, &failed_recovered, list) {
+		complete_resync_work(reg, errors_handled ? 0 : 1);
+		mempool_free(reg, rh->region_pool);
+	}
+
+	list_for_each_entry_safe(reg, next, &clean, list) {
+		rh->log->type->clear_region(rh->log, reg->key);
+		mempool_free(reg, rh->region_pool);
+	}
+
+	rh->log->type->flush(rh->log);
+}
+// EXPORT_SYMBOL_GPL(dm_rh_update_states);
+
+void dm_rh_inc(struct dm_region_hash *rh, region_t region)
+{
+	struct dm_region *reg;
+
+	read_lock(&rh->hash_lock);
+	reg = __rh_find(rh, region);
+
+	spin_lock_irq(&rh->region_lock);
+	atomic_inc(&reg->pending);
+
+	if (reg->state == DM_RH_CLEAN) {
+		reg->state = DM_RH_DIRTY;
+		list_del_init(&reg->list);	/* take off the clean list */
+		spin_unlock_irq(&rh->region_lock);
+
+		rh->log->type->mark_region(rh->log, reg->key);
+	} else
+		spin_unlock_irq(&rh->region_lock);
+
+
+	read_unlock(&rh->hash_lock);
+}
+// EXPORT_SYMBOL_GPL(dm_rh_inc);
+
+void dm_rh_inc_pending(struct dm_region_hash *rh, struct bio_list *bios)
+{
+	struct bio *bio;
+
+	for (bio = bios->head; bio; bio = bio->bi_next)
+		dm_rh_inc(rh, dm_rh_bio_to_region(rh, bio));
+}
+// EXPORT_SYMBOL_GPL(dm_rh_inc_pending);
+
+void dm_rh_dec(struct dm_region_hash *rh, region_t region)
+{
+	unsigned long flags;
+	struct dm_region *reg;
+	int should_wake = 0;
+
+	read_lock(&rh->hash_lock);
+	reg = __rh_lookup(rh, region);
+	read_unlock(&rh->hash_lock);
+
+	spin_lock_irqsave(&rh->region_lock, flags);
+	if (atomic_dec_and_test(&reg->pending)) {
+		/*
+		 * There is no pending I/O for this region.
+		 * We can move the region to corresponding list for next action.
+		 * At this point, the region is not yet connected to any list.
+		 *
+		 * If the state is DM_RH_NOSYNC, the region should be kept off
+		 * from clean list.
+		 * The hash entry for DM_RH_NOSYNC will remain in memory
+		 * until the region is recovered or the map is reloaded.
+		 */
+
+		/* do nothing for DM_RH_NOSYNC */
+		if (reg->state == DM_RH_RECOVERING) {
+			list_add_tail(&reg->list, &rh->quiesced_regions);
+		} else if (reg->state == DM_RH_DIRTY) {
+			reg->state = DM_RH_CLEAN;
+			list_add(&reg->list, &rh->clean_regions);
+		}
+		should_wake = 1;
+	}
+	spin_unlock_irqrestore(&rh->region_lock, flags);
+
+	if (should_wake)
+		rh->wakeup_workers(rh->context);
+}
+// EXPORT_SYMBOL_GPL(dm_rh_dec);
+
+/*
+ * Starts quiescing a region in preparation for recovery.
+ */
+static int __rh_recovery_prepare(struct dm_region_hash *rh)
+{
+	int r;
+	region_t region;
+	struct dm_region *reg;
+
+	/*
+	 * Ask the dirty log what's next.
+	 */
+	r = rh->log->type->get_resync_work(rh->log, &region);
+	if (r <= 0)
+		return r;
+
+	/*
+	 * Get this region, and start it quiescing by setting the
+	 * recovering flag.
+	 */
+	read_lock(&rh->hash_lock);
+	reg = __rh_find(rh, region);
+	read_unlock(&rh->hash_lock);
+
+	spin_lock_irq(&rh->region_lock);
+	reg->state = DM_RH_RECOVERING;
+
+	/* Already quiesced ? */
+	if (atomic_read(&reg->pending))
+		list_del_init(&reg->list);
+	else
+		list_move(&reg->list, &rh->quiesced_regions);
+
+	spin_unlock_irq(&rh->region_lock);
+
+	return 1;
+}
+
+void dm_rh_recovery_prepare(struct dm_region_hash *rh)
+{
+	/* Extra reference to avoid race with dm_rh_stop_recovery */
+	atomic_inc(&rh->recovery_in_flight);
+
+	while (!down_trylock(&rh->recovery_count)) {
+		atomic_inc(&rh->recovery_in_flight);
+		if (__rh_recovery_prepare(rh) <= 0) {
+			atomic_dec(&rh->recovery_in_flight);
+			up(&rh->recovery_count);
+			break;
+		}
+	}
+
+	/* Drop the extra reference */
+	if (atomic_dec_and_test(&rh->recovery_in_flight))
+		rh->wakeup_all_recovery_waiters(rh->context);
+}
+// EXPORT_SYMBOL_GPL(dm_rh_recovery_prepare);
+
+/*
+ * Returns any quiesced regions.
+ */
+struct dm_region *dm_rh_recovery_start(struct dm_region_hash *rh)
+{
+	struct dm_region *reg = NULL;
+
+	spin_lock_irq(&rh->region_lock);
+	if (!list_empty(&rh->quiesced_regions)) {
+		reg = list_entry(rh->quiesced_regions.next,
+				 struct dm_region, list);
+		list_del_init(&reg->list);  /* remove from the quiesced list */
+	}
+	spin_unlock_irq(&rh->region_lock);
+
+	return reg;
+}
+// EXPORT_SYMBOL_GPL(dm_rh_recovery_start);
+
+void dm_rh_recovery_end(struct dm_region *reg, int success)
+{
+	struct dm_region_hash *rh = reg->rh;
+
+	spin_lock_irq(&rh->region_lock);
+	if (success)
+		list_add(&reg->list, &reg->rh->recovered_regions);
+	else {
+		reg->state = DM_RH_NOSYNC;
+		list_add(&reg->list, &reg->rh->failed_recovered_regions);
+	}
+	spin_unlock_irq(&rh->region_lock);
+
+	rh->wakeup_workers(rh->context);
+}
+// EXPORT_SYMBOL_GPL(dm_rh_recovery_end);
+
+/* Return recovery in flight count. */
+int dm_rh_recovery_in_flight(struct dm_region_hash *rh)
+{
+	return atomic_read(&rh->recovery_in_flight);
+}
+// EXPORT_SYMBOL_GPL(dm_rh_recovery_in_flight);
+
+int dm_rh_flush(struct dm_region_hash *rh)
+{
+	return rh->log->type->flush(rh->log);
+}
+// EXPORT_SYMBOL_GPL(dm_rh_flush);
+
+void dm_rh_delay(struct dm_region_hash *rh, struct bio *bio)
+{
+	struct dm_region *reg;
+
+	read_lock(&rh->hash_lock);
+	reg = __rh_find(rh, dm_rh_bio_to_region(rh, bio));
+	bio_list_add(&reg->delayed_bios, bio);
+	read_unlock(&rh->hash_lock);
+}
+// EXPORT_SYMBOL_GPL(dm_rh_delay);
+
+void dm_rh_delay_by_region(struct dm_region_hash *rh,
+			   struct bio *bio, region_t region)
+{
+	struct dm_region *reg;
+
+	/* FIXME: locking. */
+	read_lock(&rh->hash_lock);
+	reg = __rh_find(rh, region);
+	bio_list_add(&reg->delayed_bios, bio);
+	read_unlock(&rh->hash_lock);
+}
+// EXPORT_SYMBOL_GPL(dm_rh_delay_by_region);
+
+void dm_rh_stop_recovery(struct dm_region_hash *rh)
+{
+	int i;
+
+	/* wait for any recovering regions */
+	for (i = 0; i < rh->max_recovery; i++)
+		down(&rh->recovery_count);
+}
+// EXPORT_SYMBOL_GPL(dm_rh_stop_recovery);
+
+void dm_rh_start_recovery(struct dm_region_hash *rh)
+{
+	int i;
+
+	for (i = 0; i < rh->max_recovery; i++)
+		up(&rh->recovery_count);
+
+	rh->wakeup_workers(rh->context);
+}
+// EXPORT_SYMBOL_GPL(dm_rh_start_recovery);
+
+MODULE_DESCRIPTION(DM_NAME " region hash");
+MODULE_AUTHOR("Joe Thornber/Heinz Mauelshagen <dm-devel@redhat.com>");
+MODULE_LICENSE("GPL");
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/dm-raid4-5/dm-region-hash.h
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2003 Sistina Software Limited.
+ * Copyright (C) 2004-2008 Red Hat, Inc. All rights reserved.
+ *
+ * Device-Mapper dirty region hash interface.
+ *
+ * This file is released under the GPL.
+ */
+
+#ifndef DM_REGION_HASH_H
+#define DM_REGION_HASH_H
+
+#include <linux/dm-dirty-log.h>
+
+/*-----------------------------------------------------------------
+ * Region hash
+ *----------------------------------------------------------------*/
+struct dm_region_hash;
+struct dm_region;
+
+/*
+ * States a region can have.
+ */
+enum dm_rh_region_states {
+	DM_RH_CLEAN	 = 0x01,	/* No writes in flight. */
+	DM_RH_DIRTY	 = 0x02,	/* Writes in flight. */
+	DM_RH_NOSYNC	 = 0x04,	/* Out of sync. */
+	DM_RH_RECOVERING = 0x08,	/* Under resynchronization. */
+};
+
+/*
+ * Region hash create/destroy.
+ */
+struct bio_list;
+struct dm_region_hash *dm_region_hash_create(
+		void *context, void (*dispatch_bios)(void *context,
+						     struct bio_list *bios),
+		void (*wakeup_workers)(void *context),
+		void (*wakeup_all_recovery_waiters)(void *context),
+		sector_t target_begin, unsigned max_recovery,
+		struct dm_dirty_log *log, uint32_t region_size,
+		region_t nr_regions);
+void dm_region_hash_destroy(struct dm_region_hash *rh);
+
+struct dm_dirty_log *dm_rh_dirty_log(struct dm_region_hash *rh);
+
+/*
+ * Conversion functions.
+ */
+region_t dm_rh_bio_to_region(struct dm_region_hash *rh, struct bio *bio);
+sector_t dm_rh_region_to_sector(struct dm_region_hash *rh, region_t region);
+region_t dm_rh_sector_to_region(struct dm_region_hash *rh, sector_t sector);
+void *dm_rh_region_context(struct dm_region *reg);
+
+/*
+ * Get region size and key (ie. number of the region).
+ */
+sector_t dm_rh_get_region_size(struct dm_region_hash *rh);
+region_t dm_rh_get_region_key(struct dm_region *reg);
+
+/*
+ * Get/set/update region state (and dirty log).
+ *
+ */
+int dm_rh_get_state(struct dm_region_hash *rh, region_t region, int may_block);
+void dm_rh_set_state(struct dm_region_hash *rh, region_t region,
+		     enum dm_rh_region_states state, int may_block);
+
+/* Non-zero errors_handled leaves the state of the region NOSYNC */
+void dm_rh_update_states(struct dm_region_hash *rh, int errors_handled);
+
+/* Flush the region hash and dirty log. */
+int dm_rh_flush(struct dm_region_hash *rh);
+
+/* Inc/dec pending count on regions. */
+void dm_rh_inc(struct dm_region_hash *rh, region_t region);
+void dm_rh_inc_pending(struct dm_region_hash *rh, struct bio_list *bios);
+void dm_rh_dec(struct dm_region_hash *rh, region_t region);
+
+/* Delay bios on regions. */
+void dm_rh_delay(struct dm_region_hash *rh, struct bio *bio);
+void dm_rh_delay_by_region(struct dm_region_hash *rh, struct bio *bio,
+			   region_t region);
+
+void dm_rh_mark_nosync(struct dm_region_hash *rh,
+		       struct bio *bio, unsigned done, int error);
+
+/*
+ * Region recovery control.
+ */
+
+/* Prepare some regions for recovery by starting to quiesce them. */
+void dm_rh_recovery_prepare(struct dm_region_hash *rh);
+
+/* Try fetching a quiesced region for recovery. */
+struct dm_region *dm_rh_recovery_start(struct dm_region_hash *rh);
+
+/* Report recovery end on a region. */
+void dm_rh_recovery_end(struct dm_region *reg, int error);
+
+/* Returns number of regions with recovery work outstanding. */
+int dm_rh_recovery_in_flight(struct dm_region_hash *rh);
+
+/* Start/stop recovery. */
+void dm_rh_start_recovery(struct dm_region_hash *rh);
+void dm_rh_stop_recovery(struct dm_region_hash *rh);
+
+#endif /* DM_REGION_HASH_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/hio/Kconfig
@@ -0,0 +1,4 @@
+config HIO
+	tristate "ES3000 V2 High-Performance PCIe SSD"
+	---help---
+	Driver for ES3000 V2 High-Performance PCIe SSD.
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/hio/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_HIO) += hio.o
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/hio/hio.c
@@ -0,0 +1,12536 @@
+/*
+* Huawei SSD device driver
+* Copyright (c) 2016, Huawei Technologies Co., Ltd.
+*
+* This program is free software; you can redistribute it and/or modify it
+* under the terms and conditions of the GNU General Public License,
+* version 2, as published by the Free Software Foundation.
+*
+* This program is distributed in the hope it will be useful, but WITHOUT
+* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+* more details.
+*/
+
+#ifndef LINUX_VERSION_CODE
+#include <linux/version.h>
+#endif
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,16))
+#include <linux/config.h>
+#endif
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/bio.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/blkdev.h>
+#include <linux/sched.h>
+#include <linux/fcntl.h>
+#include <linux/interrupt.h>
+#include <linux/compiler.h>
+#include <linux/bitops.h>
+#include <linux/delay.h>
+#include <linux/time.h>
+#include <linux/stat.h>
+#include <linux/fs.h>
+#include <linux/dma-mapping.h>
+#include <linux/completion.h>
+#include <linux/workqueue.h>
+#include <linux/mm.h>
+#include <linux/ioctl.h>
+#include <linux/hdreg.h>	/* HDIO_GETGEO */
+#include <linux/list.h>
+#include <linux/reboot.h>
+#include <linux/kthread.h>
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,2,0))
+#include <linux/seq_file.h>
+#endif
+#include <asm/uaccess.h>
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,2,0))
+#include <linux/scatterlist.h>
+#include <linux/vmalloc.h>
+#else
+#include <asm/scatterlist.h>
+#endif
+#include <asm/io.h>
+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,17))
+#include <linux/devfs_fs_kernel.h>
+#endif
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,3,0))
+#define bio_endio(bio, errors) bio_endio(bio)
+#endif
+
+/* driver */
+#define MODULE_NAME		"hio"
+#define DRIVER_VERSION	"2.1.0.23"
+#define DRIVER_VERSION_LEN	16
+
+#define SSD_FW_MIN		0x1
+
+#define SSD_DEV_NAME	MODULE_NAME
+#define SSD_DEV_NAME_LEN	16
+#define SSD_CDEV_NAME	"c"SSD_DEV_NAME
+#define SSD_SDEV_NAME	"s"SSD_DEV_NAME
+
+
+#define SSD_CMAJOR		0
+#define SSD_MAJOR		0
+#define SSD_MAJOR_SL	0
+#define SSD_MINORS		16
+
+#define SSD_MAX_DEV		702
+#define SSD_ALPHABET_NUM	26
+
+#define hio_info(f, arg...) printk(KERN_INFO MODULE_NAME"info: " f , ## arg)
+#define hio_note(f, arg...) printk(KERN_NOTICE MODULE_NAME"note: " f , ## arg)
+#define hio_warn(f, arg...) printk(KERN_WARNING MODULE_NAME"warn: " f , ## arg)
+#define hio_err(f, arg...)  printk(KERN_ERR MODULE_NAME"err: " f , ## arg)
+
+/* slave port */
+#define SSD_SLAVE_PORT_DEVID	0x000a
+
+/* int mode */
+
+/* 2.6.9 msi affinity bug, should turn msi & msi-x off */
+//#define SSD_MSI
+#define SSD_ESCAPE_IRQ
+
+//#define SSD_MSIX
+#ifndef MODULE
+#define SSD_MSIX
+#endif
+#define SSD_MSIX_VEC	8
+#ifdef SSD_MSIX
+#undef SSD_MSI
+//#undef SSD_ESCAPE_IRQ
+#define SSD_MSIX_AFFINITY_FORCE
+#endif
+
+#define SSD_TRIM
+
+/* Over temperature protect */
+#define SSD_OT_PROTECT
+
+#ifdef SSD_QUEUE_PBIO
+#define BIO_SSD_PBIO		20
+#endif
+
+/* debug */
+//#define SSD_DEBUG_ERR
+
+/* cmd timer */
+#define SSD_CMD_TIMEOUT		(60*HZ)
+
+/* i2c & smbus */
+#define SSD_SPI_TIMEOUT		(5*HZ)
+#define SSD_I2C_TIMEOUT		(5*HZ)
+
+#define SSD_I2C_MAX_DATA	(127)
+#define SSD_SMBUS_BLOCK_MAX	(32)
+#define SSD_SMBUS_DATA_MAX	(SSD_SMBUS_BLOCK_MAX + 2)
+
+/* wait for init */
+#define SSD_INIT_WAIT		(1000) //1s
+#define SSD_CONTROLLER_WAIT	(20*1000/SSD_INIT_WAIT)	//20s
+#define SSD_INIT_MAX_WAIT	(500*1000/SSD_INIT_WAIT) //500s
+#define SSD_INIT_MAX_WAIT_V3_2	(1400*1000/SSD_INIT_WAIT) //1400s
+#define SSD_RAM_INIT_MAX_WAIT	(10*1000/SSD_INIT_WAIT) //10s
+#define SSD_CH_INFO_MAX_WAIT	(10*1000/SSD_INIT_WAIT) //10s
+
+/* blkdev busy wait */
+#define SSD_DEV_BUSY_WAIT	1000 //ms
+#define SSD_DEV_BUSY_MAX_WAIT	(8*1000/SSD_DEV_BUSY_WAIT) //8s
+
+/* smbus retry */
+#define SSD_SMBUS_RETRY_INTERVAL	(5) //ms
+#define SSD_SMBUS_RETRY_MAX			(1000/SSD_SMBUS_RETRY_INTERVAL)
+
+#define SSD_BM_RETRY_MAX			7
+
+/* bm routine interval */
+#define SSD_BM_CAP_LEARNING_DELAY	(10*60*1000)
+
+/* routine interval */
+#define SSD_ROUTINE_INTERVAL		(10*1000)	//10s
+#define SSD_HWMON_ROUTINE_TICK		(60*1000/SSD_ROUTINE_INTERVAL)
+#define SSD_CAPMON_ROUTINE_TICK		((3600*1000/SSD_ROUTINE_INTERVAL)*24*30)
+#define SSD_CAPMON2_ROUTINE_TICK	(10*60*1000/SSD_ROUTINE_INTERVAL)	//fault recover
+
+/* dma align */
+#define SSD_DMA_ALIGN		(16)
+
+/* some hw defalut */
+#define SSD_LOG_MAX_SZ		4096
+
+#define SSD_NAND_OOB_SZ		1024
+#define SSD_NAND_ID_SZ		8
+#define SSD_NAND_ID_BUFF_SZ	1024
+#define SSD_NAND_MAX_CE		2
+
+#define SSD_BBT_RESERVED	8
+
+#define SSD_ECC_MAX_FLIP	(64+1)
+
+#define SSD_RAM_ALIGN		16
+
+
+#define SSD_RELOAD_FLAG		0x3333CCCC
+#define SSD_RELOAD_FW		0xAA5555AA
+#define SSD_RESET_NOINIT	0xAA5555AA
+#define SSD_RESET			0x55AAAA55
+#define SSD_RESET_FULL		0x5A
+//#define SSD_RESET_WAIT		1000	//1s
+//#define SSD_RESET_MAX_WAIT	(200*1000/SSD_RESET_WAIT) //200s
+
+
+/* reverion 1 */
+#define SSD_PROTOCOL_V1			0x0
+
+#define SSD_ROM_SIZE			(16*1024*1024)
+#define SSD_ROM_BLK_SIZE		(256*1024)
+#define SSD_ROM_PAGE_SIZE		(256)
+#define SSD_ROM_NR_BRIDGE_FW	2
+#define SSD_ROM_NR_CTRL_FW		2
+#define SSD_ROM_BRIDGE_FW_BASE	0
+#define SSD_ROM_BRIDGE_FW_SIZE	(2*1024*1024)
+#define SSD_ROM_CTRL_FW_BASE	(SSD_ROM_NR_BRIDGE_FW*SSD_ROM_BRIDGE_FW_SIZE)
+#define SSD_ROM_CTRL_FW_SIZE	(5*1024*1024)
+#define SSD_ROM_LABEL_BASE		(SSD_ROM_CTRL_FW_BASE+SSD_ROM_CTRL_FW_SIZE*SSD_ROM_NR_CTRL_FW)
+#define SSD_ROM_VP_BASE			(SSD_ROM_LABEL_BASE+SSD_ROM_BLK_SIZE)
+
+/* reverion 3 */
+#define SSD_PROTOCOL_V3			0x3000000
+#define SSD_PROTOCOL_V3_1_1		0x3010001
+#define SSD_PROTOCOL_V3_1_3		0x3010003
+#define SSD_PROTOCOL_V3_2		0x3020000
+#define SSD_PROTOCOL_V3_2_1		0x3020001	/* <4KB improved */
+#define SSD_PROTOCOL_V3_2_2		0x3020002	/* ot protect */
+#define SSD_PROTOCOL_V3_2_4		0x3020004
+
+
+#define SSD_PV3_ROM_NR_BM_FW	1
+#define SSD_PV3_ROM_BM_FW_SZ	(64*1024*8)
+
+#define SSD_ROM_LOG_SZ			(64*1024*4)
+
+#define SSD_ROM_NR_SMART_MAX	2
+#define SSD_PV3_ROM_NR_SMART	SSD_ROM_NR_SMART_MAX
+#define SSD_PV3_ROM_SMART_SZ	(64*1024)
+
+/* reverion 3.2 */
+#define SSD_PV3_2_ROM_LOG_SZ	(64*1024*80) /* 5MB */
+#define SSD_PV3_2_ROM_SEC_SZ	(256*1024) /* 256KB */
+
+
+/* register */
+#define SSD_REQ_FIFO_REG		0x0000
+#define SSD_RESP_FIFO_REG		0x0008	//0x0010
+#define SSD_RESP_PTR_REG		0x0010	//0x0018
+#define SSD_INTR_INTERVAL_REG	0x0018
+#define SSD_READY_REG			0x001C
+#define SSD_BRIDGE_TEST_REG		0x0020
+#define SSD_STRIPE_SIZE_REG		0x0028
+#define SSD_CTRL_VER_REG		0x0030	//controller
+#define SSD_BRIDGE_VER_REG		0x0034	//bridge
+#define SSD_PCB_VER_REG			0x0038
+#define SSD_BURN_FLAG_REG		0x0040
+#define SSD_BRIDGE_INFO_REG		0x0044
+
+#define SSD_WL_VAL_REG			0x0048	//32-bit
+
+#define SSD_BB_INFO_REG			0x004C
+
+#define SSD_ECC_TEST_REG		0x0050 //test only
+#define SSD_ERASE_TEST_REG		0x0058 //test only
+#define SSD_WRITE_TEST_REG		0x0060 //test only
+
+#define SSD_RESET_REG 			0x0068
+#define SSD_RELOAD_FW_REG		0x0070
+
+#define SSD_RESERVED_BLKS_REG	0x0074
+#define SSD_VALID_PAGES_REG		0x0078
+#define SSD_CH_INFO_REG			0x007C
+
+#define SSD_CTRL_TEST_REG_SZ	0x8
+#define SSD_CTRL_TEST_REG0		0x0080
+#define SSD_CTRL_TEST_REG1		0x0088
+#define SSD_CTRL_TEST_REG2		0x0090
+#define SSD_CTRL_TEST_REG3		0x0098
+#define SSD_CTRL_TEST_REG4		0x00A0
+#define SSD_CTRL_TEST_REG5		0x00A8
+#define SSD_CTRL_TEST_REG6		0x00B0
+#define SSD_CTRL_TEST_REG7		0x00B8
+
+#define SSD_FLASH_INFO_REG0		0x00C0
+#define SSD_FLASH_INFO_REG1		0x00C8
+#define SSD_FLASH_INFO_REG2		0x00D0
+#define SSD_FLASH_INFO_REG3		0x00D8
+#define SSD_FLASH_INFO_REG4		0x00E0
+#define SSD_FLASH_INFO_REG5		0x00E8
+#define SSD_FLASH_INFO_REG6		0x00F0
+#define SSD_FLASH_INFO_REG7		0x00F8
+
+#define SSD_RESP_INFO_REG		0x01B8
+#define SSD_NAND_BUFF_BASE		0x01BC //for nand write
+
+#define SSD_CHIP_INFO_REG_SZ	0x10
+#define SSD_CHIP_INFO_REG0		0x0100	//128 bit
+#define SSD_CHIP_INFO_REG1		0x0110
+#define SSD_CHIP_INFO_REG2		0x0120
+#define SSD_CHIP_INFO_REG3		0x0130
+#define SSD_CHIP_INFO_REG4		0x0140
+#define SSD_CHIP_INFO_REG5		0x0150
+#define SSD_CHIP_INFO_REG6		0x0160
+#define SSD_CHIP_INFO_REG7		0x0170
+
+#define SSD_RAM_INFO_REG		0x01C4
+
+#define SSD_BBT_BASE_REG		0x01C8
+#define SSD_ECT_BASE_REG		0x01CC
+
+#define SSD_CLEAR_INTR_REG		0x01F0
+
+#define SSD_INIT_STATE_REG_SZ	0x8
+#define SSD_INIT_STATE_REG0		0x0200
+#define SSD_INIT_STATE_REG1		0x0208
+#define SSD_INIT_STATE_REG2		0x0210
+#define SSD_INIT_STATE_REG3		0x0218
+#define SSD_INIT_STATE_REG4		0x0220
+#define SSD_INIT_STATE_REG5		0x0228
+#define SSD_INIT_STATE_REG6		0x0230
+#define SSD_INIT_STATE_REG7		0x0238
+
+#define SSD_ROM_INFO_REG		0x0600
+#define SSD_ROM_BRIDGE_FW_INFO_REG	0x0604
+#define SSD_ROM_CTRL_FW_INFO_REG	0x0608
+#define SSD_ROM_VP_INFO_REG		0x060C
+
+#define SSD_LOG_INFO_REG		0x0610
+#define SSD_LED_REG				0x0614
+#define SSD_MSG_BASE_REG		0x06F8
+
+/*spi reg */
+#define SSD_SPI_REG_CMD			0x0180
+#define SSD_SPI_REG_CMD_HI		0x0184
+#define SSD_SPI_REG_WDATA		0x0188
+#define SSD_SPI_REG_ID			0x0190
+#define SSD_SPI_REG_STATUS		0x0198
+#define SSD_SPI_REG_RDATA		0x01A0
+#define SSD_SPI_REG_READY		0x01A8
+
+/* i2c register */
+#define SSD_I2C_CTRL_REG		0x06F0
+#define SSD_I2C_RDATA_REG		0x06F4
+
+/* temperature reg */
+#define SSD_BRIGE_TEMP_REG		0x0618
+
+#define SSD_CTRL_TEMP_REG0		0x0700
+#define SSD_CTRL_TEMP_REG1		0x0708
+#define SSD_CTRL_TEMP_REG2		0x0710
+#define SSD_CTRL_TEMP_REG3		0x0718
+#define SSD_CTRL_TEMP_REG4		0x0720
+#define SSD_CTRL_TEMP_REG5		0x0728
+#define SSD_CTRL_TEMP_REG6		0x0730
+#define SSD_CTRL_TEMP_REG7		0x0738
+
+/* reversion 3 reg */
+#define SSD_PROTOCOL_VER_REG	0x01B4
+
+#define SSD_FLUSH_TIMEOUT_REG	0x02A4
+#define SSD_BM_FAULT_REG		0x0660
+
+#define SSD_PV3_RAM_STATUS_REG_SZ	0x4
+#define SSD_PV3_RAM_STATUS_REG0	0x0260
+#define SSD_PV3_RAM_STATUS_REG1	0x0264
+#define SSD_PV3_RAM_STATUS_REG2	0x0268
+#define SSD_PV3_RAM_STATUS_REG3	0x026C
+#define SSD_PV3_RAM_STATUS_REG4	0x0270
+#define SSD_PV3_RAM_STATUS_REG5	0x0274
+#define SSD_PV3_RAM_STATUS_REG6	0x0278
+#define SSD_PV3_RAM_STATUS_REG7	0x027C
+
+#define SSD_PV3_CHIP_INFO_REG_SZ	0x40
+#define SSD_PV3_CHIP_INFO_REG0	0x0300
+#define SSD_PV3_CHIP_INFO_REG1	0x0340
+#define SSD_PV3_CHIP_INFO_REG2	0x0380
+#define SSD_PV3_CHIP_INFO_REG3	0x03B0
+#define SSD_PV3_CHIP_INFO_REG4	0x0400
+#define SSD_PV3_CHIP_INFO_REG5	0x0440
+#define SSD_PV3_CHIP_INFO_REG6	0x0480
+#define SSD_PV3_CHIP_INFO_REG7	0x04B0
+
+#define SSD_PV3_INIT_STATE_REG_SZ 0x20
+#define SSD_PV3_INIT_STATE_REG0	0x0500
+#define SSD_PV3_INIT_STATE_REG1	0x0520
+#define SSD_PV3_INIT_STATE_REG2	0x0540
+#define SSD_PV3_INIT_STATE_REG3	0x0560
+#define SSD_PV3_INIT_STATE_REG4	0x0580
+#define SSD_PV3_INIT_STATE_REG5	0x05A0
+#define SSD_PV3_INIT_STATE_REG6	0x05C0
+#define SSD_PV3_INIT_STATE_REG7	0x05E0
+
+/* reversion 3.1.1 reg */
+#define SSD_FULL_RESET_REG		0x01B0
+
+#define SSD_CTRL_REG_ZONE_SZ	0x800
+
+#define SSD_BB_THRESHOLD_L1_REG	0x2C0
+#define SSD_BB_THRESHOLD_L2_REG	0x2C4
+
+#define SSD_BB_ACC_REG_SZ		0x4
+#define SSD_BB_ACC_REG0			0x21C0
+#define SSD_BB_ACC_REG1			0x29C0
+#define SSD_BB_ACC_REG2			0x31C0
+
+#define SSD_EC_THRESHOLD_L1_REG	0x2C8
+#define SSD_EC_THRESHOLD_L2_REG	0x2CC
+
+#define SSD_EC_ACC_REG_SZ		0x4
+#define SSD_EC_ACC_REG0			0x21E0
+#define SSD_EC_ACC_REG1			0x29E0
+#define SSD_EC_ACC_REG2			0x31E0
+
+/* reversion 3.1.2 & 3.1.3 reg */
+#define SSD_HW_STATUS_REG		0x02AC
+
+#define SSD_PLP_INFO_REG		0x0664
+
+/*reversion 3.2 reg*/
+#define SSD_POWER_ON_REG		0x01EC
+#define SSD_PCIE_LINKSTATUS_REG	0x01F8
+#define SSD_PL_CAP_LEARN_REG	0x01FC
+
+#define SSD_FPGA_1V0_REG0		0x2070
+#define SSD_FPGA_1V8_REG0		0x2078
+#define SSD_FPGA_1V0_REG1		0x2870
+#define SSD_FPGA_1V8_REG1		0x2878
+
+/*reversion 3.2 reg*/
+#define SSD_READ_OT_REG0		0x2260
+#define SSD_WRITE_OT_REG0		0x2264
+#define SSD_READ_OT_REG1		0x2A60
+#define SSD_WRITE_OT_REG1		0x2A64
+
+
+/* function */
+#define SSD_FUNC_READ			0x01
+#define SSD_FUNC_WRITE			0x02
+#define SSD_FUNC_NAND_READ_WOOB	0x03
+#define SSD_FUNC_NAND_READ		0x04
+#define SSD_FUNC_NAND_WRITE		0x05
+#define SSD_FUNC_NAND_ERASE		0x06
+#define SSD_FUNC_NAND_READ_ID	0x07
+#define SSD_FUNC_READ_LOG		0x08
+#define SSD_FUNC_TRIM			0x09
+#define SSD_FUNC_RAM_READ		0x10
+#define SSD_FUNC_RAM_WRITE		0x11
+#define SSD_FUNC_FLUSH			0x12	//cache / bbt
+
+/* spi function */
+#define SSD_SPI_CMD_PROGRAM		0x02
+#define SSD_SPI_CMD_READ		0x03
+#define SSD_SPI_CMD_W_DISABLE	0x04
+#define SSD_SPI_CMD_READ_STATUS	0x05
+#define SSD_SPI_CMD_W_ENABLE	0x06
+#define SSD_SPI_CMD_ERASE		0xd8
+#define SSD_SPI_CMD_CLSR		0x30
+#define SSD_SPI_CMD_READ_ID		0x9f
+
+/* i2c */
+#define SSD_I2C_CTRL_READ		0x00
+#define SSD_I2C_CTRL_WRITE		0x01
+
+/* i2c internal register */
+#define SSD_I2C_CFG_REG			0x00
+#define SSD_I2C_DATA_REG		0x01
+#define SSD_I2C_CMD_REG			0x02
+#define SSD_I2C_STATUS_REG		0x03
+#define SSD_I2C_SADDR_REG		0x04
+#define SSD_I2C_LEN_REG			0x05
+#define SSD_I2C_RLEN_REG		0x06
+#define SSD_I2C_WLEN_REG		0x07
+#define SSD_I2C_RESET_REG		0x08	//write for reset
+#define SSD_I2C_PRER_REG		0x09
+
+
+/* hw mon */
+/* FPGA volt = ADC_value / 4096 * 3v */
+#define SSD_FPGA_1V0_ADC_MIN	1228 // 0.9v
+#define SSD_FPGA_1V0_ADC_MAX	1502 // 1.1v
+#define SSD_FPGA_1V8_ADC_MIN	2211 // 1.62v
+#define SSD_FPGA_1V8_ADC_MAX	2703 // 1.98
+
+/* ADC value */
+#define SSD_FPGA_VOLT_MAX(val)	(((val) & 0xffff) >> 4)
+#define SSD_FPGA_VOLT_MIN(val)	(((val >> 16) & 0xffff) >> 4)
+#define SSD_FPGA_VOLT_CUR(val)	(((val >> 32) & 0xffff) >> 4)
+#define SSD_FPGA_VOLT(val)		((val * 3000) >> 12)
+
+#define SSD_VOLT_LOG_DATA(idx, ctrl, volt)	(((uint32_t)idx << 24) | ((uint32_t)ctrl << 16) | ((uint32_t)volt))
+
+enum ssd_fpga_volt
+{
+	SSD_FPGA_1V0 = 0, 
+	SSD_FPGA_1V8, 
+	SSD_FPGA_VOLT_NR 
+};
+
+enum ssd_clock
+{
+	SSD_CLOCK_166M_LOST = 0, 
+	SSD_CLOCK_166M_SKEW, 
+	SSD_CLOCK_156M_LOST, 
+	SSD_CLOCK_156M_SKEW, 
+	SSD_CLOCK_NR
+};
+
+/* sensor */
+#define SSD_SENSOR_LM75_SADDRESS	(0x49 << 1)
+#define SSD_SENSOR_LM80_SADDRESS	(0x28 << 1)
+
+#define SSD_SENSOR_CONVERT_TEMP(val)	((int)(val >> 8))
+
+#define SSD_INLET_OT_TEMP			(55)	//55 DegC
+#define SSD_INLET_OT_HYST			(50)	//50 DegC
+#define SSD_FLASH_OT_TEMP			(70)	//70 DegC
+#define SSD_FLASH_OT_HYST			(65)	//65 DegC
+
+enum ssd_sensor
+{
+	SSD_SENSOR_LM80 = 0,
+	SSD_SENSOR_LM75,
+	SSD_SENSOR_NR
+};
+
+
+/* lm75 */
+enum ssd_lm75_reg
+{
+	SSD_LM75_REG_TEMP = 0, 
+	SSD_LM75_REG_CONF, 
+	SSD_LM75_REG_THYST, 
+	SSD_LM75_REG_TOS
+};
+
+/* lm96080 */
+#define SSD_LM80_REG_IN_MAX(nr)		(0x2a + (nr) * 2)
+#define SSD_LM80_REG_IN_MIN(nr)		(0x2b + (nr) * 2)
+#define SSD_LM80_REG_IN(nr)			(0x20 + (nr))
+
+#define SSD_LM80_REG_FAN1			0x28
+#define SSD_LM80_REG_FAN2			0x29
+#define SSD_LM80_REG_FAN_MIN(nr)	(0x3b + (nr))
+
+#define SSD_LM80_REG_TEMP			0x27
+#define SSD_LM80_REG_TEMP_HOT_MAX	0x38
+#define SSD_LM80_REG_TEMP_HOT_HYST	0x39
+#define SSD_LM80_REG_TEMP_OS_MAX	0x3a
+#define SSD_LM80_REG_TEMP_OS_HYST	0x3b
+
+#define SSD_LM80_REG_CONFIG			0x00
+#define SSD_LM80_REG_ALARM1			0x01
+#define SSD_LM80_REG_ALARM2			0x02
+#define SSD_LM80_REG_MASK1			0x03
+#define SSD_LM80_REG_MASK2			0x04
+#define SSD_LM80_REG_FANDIV			0x05
+#define SSD_LM80_REG_RES			0x06
+
+#define SSD_LM80_CONVERT_VOLT(val)	((val * 10) >> 8)
+
+#define SSD_LM80_3V3_VOLT(val)		((val)*33/19)
+
+#define SSD_LM80_CONV_INTERVAL		(1000)
+
+enum ssd_lm80_in
+{
+	SSD_LM80_IN_CAP = 0, 
+	SSD_LM80_IN_1V2, 
+	SSD_LM80_IN_1V2a, 
+	SSD_LM80_IN_1V5, 
+	SSD_LM80_IN_1V8, 
+	SSD_LM80_IN_FPGA_3V3, 
+	SSD_LM80_IN_3V3, 
+	SSD_LM80_IN_NR 
+};
+
+struct ssd_lm80_limit
+{
+	uint8_t low;
+	uint8_t high;
+};
+
+/* +/- 5% except cap in*/
+static struct ssd_lm80_limit ssd_lm80_limit[SSD_LM80_IN_NR] = {
+	{171, 217}, /* CAP in: 1710 ~ 2170 */
+	{114, 126}, 
+	{114, 126}, 
+	{142, 158}, 
+	{171, 189}, 
+	{180, 200}, 
+	{180, 200}, 
+};
+
+/* temperature sensors */
+enum ssd_temp_sensor
+{
+	SSD_TEMP_INLET = 0, 
+	SSD_TEMP_FLASH, 
+	SSD_TEMP_CTRL, 
+	SSD_TEMP_NR 
+};
+
+
+#ifdef SSD_OT_PROTECT
+#define SSD_OT_DELAY		(60) //ms
+
+#define SSD_OT_TEMP			(90) //90 DegC
+
+#define SSD_OT_TEMP_HYST	(85) //85 DegC
+#endif
+
+/* fpga temperature */
+//#define CONVERT_TEMP(val)	((float)(val)*503.975f/4096.0f-273.15f)
+#define CONVERT_TEMP(val)	((val)*504/4096-273)
+
+#define MAX_TEMP(val)		CONVERT_TEMP(((val & 0xffff) >> 4))
+#define MIN_TEMP(val)		CONVERT_TEMP((((val>>16) & 0xffff) >> 4))
+#define CUR_TEMP(val)		CONVERT_TEMP((((val>>32) & 0xffff) >> 4))
+
+
+/* CAP monitor */
+#define SSD_PL_CAP_U1				SSD_LM80_REG_IN(SSD_LM80_IN_CAP)
+#define SSD_PL_CAP_U2				SSD_LM80_REG_IN(SSD_LM80_IN_1V8)
+#define SSD_PL_CAP_LEARN(u1, u2, t)	((t*(u1+u2))/(2*162*(u1-u2)))
+#define SSD_PL_CAP_LEARN_WAIT		(20)	//20ms
+#define SSD_PL_CAP_LEARN_MAX_WAIT	(1000/SSD_PL_CAP_LEARN_WAIT)	//1s
+
+#define SSD_PL_CAP_CHARGE_WAIT		(1000)
+#define SSD_PL_CAP_CHARGE_MAX_WAIT	((120*1000)/SSD_PL_CAP_CHARGE_WAIT)	//120s
+
+#define SSD_PL_CAP_VOLT(val)		(val*7)
+
+#define SSD_PL_CAP_VOLT_FULL		(13700)
+#define SSD_PL_CAP_VOLT_READY		(12880)
+
+#define SSD_PL_CAP_THRESHOLD		(8900)
+#define SSD_PL_CAP_CP_THRESHOLD		(5800)
+#define SSD_PL_CAP_THRESHOLD_HYST	(100)
+
+enum ssd_pl_cap_status
+{
+	SSD_PL_CAP = 0, 
+	SSD_PL_CAP_NR
+};
+
+enum ssd_pl_cap_type
+{
+	SSD_PL_CAP_DEFAULT = 0,	/* 4 cap */
+	SSD_PL_CAP_CP	/* 3 cap */
+};
+
+
+/* hwmon offset */
+#define SSD_HWMON_OFFS_TEMP			(0)
+#define SSD_HWMON_OFFS_SENSOR		(SSD_HWMON_OFFS_TEMP + SSD_TEMP_NR)
+#define SSD_HWMON_OFFS_PL_CAP		(SSD_HWMON_OFFS_SENSOR + SSD_SENSOR_NR)
+#define SSD_HWMON_OFFS_LM80			(SSD_HWMON_OFFS_PL_CAP + SSD_PL_CAP_NR)
+#define SSD_HWMON_OFFS_CLOCK		(SSD_HWMON_OFFS_LM80 + SSD_LM80_IN_NR)
+#define SSD_HWMON_OFFS_FPGA 		(SSD_HWMON_OFFS_CLOCK + SSD_CLOCK_NR) 
+
+#define SSD_HWMON_TEMP(idx) 		(SSD_HWMON_OFFS_TEMP + idx)
+#define SSD_HWMON_SENSOR(idx) 		(SSD_HWMON_OFFS_SENSOR + idx)
+#define SSD_HWMON_PL_CAP(idx)		(SSD_HWMON_OFFS_PL_CAP + idx)
+#define SSD_HWMON_LM80(idx)			(SSD_HWMON_OFFS_LM80 + idx)
+#define SSD_HWMON_CLOCK(idx)		(SSD_HWMON_OFFS_CLOCK + idx)
+#define SSD_HWMON_FPGA(ctrl, idx)	(SSD_HWMON_OFFS_FPGA + (ctrl * SSD_FPGA_VOLT_NR) + idx)
+
+
+
+/* fifo */
+typedef struct sfifo
+{
+	uint32_t in;
+	uint32_t out;
+	uint32_t size;
+	uint32_t esize;
+	uint32_t mask;
+	spinlock_t lock;
+	void *data;
+} sfifo_t;
+
+static int sfifo_alloc(struct sfifo *fifo, uint32_t size, uint32_t esize)
+{
+	uint32_t __size = 1;
+
+	if (!fifo || size > INT_MAX || esize == 0) {
+		return -EINVAL;
+	}
+
+	while (__size < size) __size <<= 1;
+
+	if (__size < 2) {
+		return -EINVAL;
+	}
+
+	fifo->data = vmalloc(esize * __size);
+	if (!fifo->data) {
+		return -ENOMEM;
+	}
+
+	fifo->in = 0;
+	fifo->out = 0;
+	fifo->mask = __size - 1;
+	fifo->size = __size;
+	fifo->esize = esize;
+	spin_lock_init(&fifo->lock);
+
+	return 0;
+}
+
+static void sfifo_free(struct sfifo *fifo)
+{
+	if (!fifo) {
+		return;
+	}
+
+	vfree(fifo->data);
+	fifo->data = NULL;
+	fifo->in = 0;
+	fifo->out = 0;
+	fifo->mask = 0;
+	fifo->size = 0;
+	fifo->esize = 0;
+}
+
+static int __sfifo_put(struct sfifo *fifo, void *val)
+{
+	if (((fifo->in + 1) & fifo->mask) == fifo->out) {
+		return -1;
+	}
+
+	memcpy((fifo->data + (fifo->in * fifo->esize)), val, fifo->esize);
+	fifo->in = (fifo->in + 1) & fifo->mask;
+
+	return 0;
+}
+
+static int sfifo_put(struct sfifo *fifo, void *val)
+{
+	int ret = 0;
+
+	if (!fifo || !val) {
+		return -EINVAL;
+	}
+	
+	if (!in_interrupt()) {
+		spin_lock_irq(&fifo->lock);
+		ret = __sfifo_put(fifo, val);
+		spin_unlock_irq(&fifo->lock);
+	} else {
+		spin_lock(&fifo->lock);
+		ret = __sfifo_put(fifo, val);
+		spin_unlock(&fifo->lock);
+	}
+
+	return ret;
+}
+
+static int __sfifo_get(struct sfifo *fifo, void *val)
+{
+	if (fifo->out == fifo->in) {
+		return -1;
+	}
+
+	memcpy(val, (fifo->data + (fifo->out * fifo->esize)), fifo->esize);
+	fifo->out = (fifo->out + 1) & fifo->mask;
+
+	return 0;
+}
+
+static int sfifo_get(struct sfifo *fifo, void *val)
+{
+	int ret = 0;
+
+	if (!fifo || !val) {
+		return -EINVAL;
+	}
+
+	if (!in_interrupt()) {
+		spin_lock_irq(&fifo->lock);
+		ret = __sfifo_get(fifo, val);
+		spin_unlock_irq(&fifo->lock);
+	} else {
+		spin_lock(&fifo->lock);
+		ret = __sfifo_get(fifo, val);
+		spin_unlock(&fifo->lock);
+	}
+
+	return ret;
+}
+
+/* bio list */
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,30))
+struct ssd_blist {
+	struct bio *prev;
+	struct bio *next;
+};
+
+static inline void ssd_blist_init(struct ssd_blist *ssd_bl)
+{
+	ssd_bl->prev = NULL;
+	ssd_bl->next = NULL;
+}
+
+static inline struct bio *ssd_blist_get(struct ssd_blist *ssd_bl)
+{
+	struct bio *bio = ssd_bl->prev;
+
+	ssd_bl->prev = NULL;
+	ssd_bl->next = NULL;
+
+	return bio;
+}
+
+static inline void ssd_blist_add(struct ssd_blist *ssd_bl, struct bio *bio)
+{
+	bio->bi_next = NULL;
+
+	if (ssd_bl->next) {
+		ssd_bl->next->bi_next = bio;
+	} else {
+		ssd_bl->prev = bio;
+	}
+
+	ssd_bl->next = bio;
+}
+
+#else
+#define ssd_blist		bio_list
+#define ssd_blist_init	bio_list_init
+#define ssd_blist_get	bio_list_get
+#define ssd_blist_add	bio_list_add
+#endif
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,14,0))
+#define bio_start(bio)	(bio->bi_sector)
+#else
+#define bio_start(bio)	(bio->bi_iter.bi_sector)
+#endif
+
+/* mutex */
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,16))
+#define mutex_lock down
+#define mutex_unlock up
+#define mutex semaphore
+#define mutex_init init_MUTEX
+#endif
+
+/* i2c */
+typedef union ssd_i2c_ctrl {
+	uint32_t val;
+	struct {
+		uint8_t wdata;
+		uint8_t addr;
+		uint16_t rw:1;
+		uint16_t pad:15;
+	} bits;
+}__attribute__((packed)) ssd_i2c_ctrl_t;
+
+typedef union ssd_i2c_data {
+	uint32_t val;
+	struct {
+		uint32_t rdata:8;
+		uint32_t valid:1;
+		uint32_t pad:23;
+	} bits;
+}__attribute__((packed)) ssd_i2c_data_t;
+
+/* write mode */
+enum ssd_write_mode
+{
+	SSD_WMODE_BUFFER = 0,
+	SSD_WMODE_BUFFER_EX,
+	SSD_WMODE_FUA,
+	/* dummy */
+	SSD_WMODE_AUTO, 
+	SSD_WMODE_DEFAULT
+};
+
+/* reset type */
+enum ssd_reset_type
+{
+	SSD_RST_NOINIT = 0,
+	SSD_RST_NORMAL,
+	SSD_RST_FULL
+};
+
+/* ssd msg */
+typedef struct ssd_sg_entry
+{
+	uint64_t block:48;
+	uint64_t length:16;
+	uint64_t buf;
+}__attribute__((packed))ssd_sg_entry_t;
+
+typedef struct ssd_rw_msg
+{
+	uint8_t tag;
+	uint8_t flag;
+	uint8_t nsegs;
+	uint8_t fun;
+	uint32_t reserved;	//for 64-bit align
+	struct ssd_sg_entry sge[1]; //base
+}__attribute__((packed))ssd_rw_msg_t;
+
+typedef struct ssd_resp_msg
+{
+	uint8_t tag;
+	uint8_t status:2;
+	uint8_t bitflip:6;
+	uint8_t log;
+	uint8_t fun;
+	uint32_t reserved;
+}__attribute__((packed))ssd_resp_msg_t;
+
+typedef struct ssd_flush_msg
+{
+	uint8_t tag;
+	uint8_t flag:2;	//flash cache 0 or bbt 1
+	uint8_t flash:6;
+	uint8_t ctrl_idx;
+	uint8_t fun;
+	uint32_t reserved;	//align
+}__attribute__((packed))ssd_flush_msg_t;
+
+typedef struct ssd_nand_op_msg
+{
+	uint8_t tag;
+	uint8_t flag;
+	uint8_t ctrl_idx;
+	uint8_t fun;
+	uint32_t reserved;	//align
+	uint16_t page_count;
+	uint8_t chip_ce;
+	uint8_t chip_no;
+	uint32_t page_no;
+	uint64_t buf;
+}__attribute__((packed))ssd_nand_op_msg_t;
+
+typedef struct ssd_ram_op_msg
+{
+	uint8_t tag;
+	uint8_t flag;
+	uint8_t ctrl_idx;
+	uint8_t fun;
+	uint32_t reserved;	//align
+	uint32_t start;
+	uint32_t length;
+	uint64_t buf;
+}__attribute__((packed))ssd_ram_op_msg_t;
+
+
+/* log msg */
+typedef struct ssd_log_msg
+{
+	uint8_t tag;
+	uint8_t flag;
+	uint8_t ctrl_idx;
+	uint8_t fun;
+	uint32_t reserved;	//align
+	uint64_t buf;
+}__attribute__((packed))ssd_log_msg_t;
+
+typedef struct ssd_log_op_msg
+{
+	uint8_t tag;
+	uint8_t flag;
+	uint8_t ctrl_idx;
+	uint8_t fun;
+	uint32_t reserved;	//align
+	uint64_t reserved1;	//align
+	uint64_t buf;
+}__attribute__((packed))ssd_log_op_msg_t;
+
+typedef struct ssd_log_resp_msg
+{
+	uint8_t tag;
+	uint16_t status :2;
+	uint16_t reserved1 :2;	//align with the normal resp msg
+	uint16_t nr_log :12;
+	uint8_t fun;
+	uint32_t reserved;
+}__attribute__((packed))ssd_log_resp_msg_t;
+
+
+/* resp msg */
+typedef union ssd_response_msq
+{
+	ssd_resp_msg_t resp_msg;
+	ssd_log_resp_msg_t log_resp_msg;
+	uint64_t u64_msg;
+	uint32_t u32_msg[2];
+} ssd_response_msq_t;
+
+
+/* custom struct */
+typedef struct ssd_protocol_info
+{
+	uint32_t ver;
+	uint32_t init_state_reg;
+	uint32_t init_state_reg_sz;
+	uint32_t chip_info_reg;
+	uint32_t chip_info_reg_sz;
+} ssd_protocol_info_t;
+
+typedef struct ssd_hw_info
+{
+	uint32_t bridge_ver;
+	uint32_t ctrl_ver;
+
+	uint32_t cmd_fifo_sz;
+	uint32_t cmd_fifo_sz_mask;
+	uint32_t cmd_max_sg;
+	uint32_t sg_max_sec;
+	uint32_t resp_ptr_sz;
+	uint32_t resp_msg_sz;
+
+	uint16_t nr_ctrl;
+
+	uint16_t nr_data_ch;
+	uint16_t nr_ch;
+	uint16_t max_ch;
+	uint16_t nr_chip;
+
+	uint8_t  pcb_ver;
+	uint8_t  upper_pcb_ver;
+
+	uint8_t  nand_vendor_id;
+	uint8_t  nand_dev_id;
+
+	uint8_t  max_ce;
+	uint8_t  id_size;
+	uint16_t oob_size;
+
+	uint16_t bbf_pages;
+	uint16_t bbf_seek;	//
+
+	uint16_t page_count;	//per block
+	uint32_t page_size;
+	uint32_t block_count;	//per flash
+
+	uint64_t ram_size;
+	uint32_t ram_align;
+	uint32_t ram_max_len;
+
+	uint64_t bbt_base;
+	uint32_t bbt_size;
+	uint64_t md_base; //metadata
+	uint32_t md_size;
+	uint32_t md_entry_sz;
+
+	uint32_t log_sz;
+
+	uint64_t nand_wbuff_base;
+
+	uint32_t md_reserved_blks;
+	uint32_t reserved_blks;
+	uint32_t valid_pages;
+	uint32_t max_valid_pages;
+	uint64_t size;
+} ssd_hw_info_t;
+
+typedef struct ssd_hw_info_extend
+{
+	uint8_t board_type;
+	uint8_t cap_type;
+	uint8_t plp_type;
+	uint8_t work_mode;
+	uint8_t form_factor;
+
+	uint8_t pad[59];
+}ssd_hw_info_extend_t;
+
+typedef struct ssd_rom_info
+{
+	uint32_t size;
+	uint32_t block_size;
+	uint16_t page_size;
+	uint8_t  nr_bridge_fw;
+	uint8_t  nr_ctrl_fw;
+	uint8_t  nr_bm_fw;
+	uint8_t  nr_smart;
+	uint32_t bridge_fw_base;
+	uint32_t bridge_fw_sz;
+	uint32_t ctrl_fw_base;
+	uint32_t ctrl_fw_sz;
+	uint32_t bm_fw_base;
+	uint32_t bm_fw_sz;
+	uint32_t log_base;
+	uint32_t log_sz;
+	uint32_t smart_base;
+	uint32_t smart_sz;
+	uint32_t vp_base;
+	uint32_t label_base;
+} ssd_rom_info_t;
+
+/* debug info */
+enum ssd_debug_type
+{
+	SSD_DEBUG_NONE = 0, 
+	SSD_DEBUG_READ_ERR, 
+	SSD_DEBUG_WRITE_ERR, 
+	SSD_DEBUG_RW_ERR, 
+	SSD_DEBUG_READ_TO, 
+	SSD_DEBUG_WRITE_TO, 
+	SSD_DEBUG_RW_TO, 
+	SSD_DEBUG_LOG, 
+	SSD_DEBUG_OFFLINE, 
+	SSD_DEBUG_NR
+};
+
+typedef struct ssd_debug_info
+{
+	int type;
+	union {
+		struct {
+			uint64_t off;
+			uint32_t len;
+		} loc;
+		struct {
+			int event;
+			uint32_t extra;
+		} log;
+	} data;
+}ssd_debug_info_t;
+
+/* label */
+#define SSD_LABEL_FIELD_SZ	32
+#define SSD_SN_SZ			16
+
+typedef struct ssd_label
+{
+	char date[SSD_LABEL_FIELD_SZ];
+	char sn[SSD_LABEL_FIELD_SZ];
+	char part[SSD_LABEL_FIELD_SZ];
+	char desc[SSD_LABEL_FIELD_SZ];
+	char other[SSD_LABEL_FIELD_SZ];
+	char maf[SSD_LABEL_FIELD_SZ];
+} ssd_label_t;
+
+#define SSD_LABEL_DESC_SZ	256
+
+typedef struct ssd_labelv3
+{
+	char boardtype[SSD_LABEL_FIELD_SZ];
+	char barcode[SSD_LABEL_FIELD_SZ];
+	char item[SSD_LABEL_FIELD_SZ];
+	char description[SSD_LABEL_DESC_SZ];
+	char manufactured[SSD_LABEL_FIELD_SZ];
+	char vendorname[SSD_LABEL_FIELD_SZ];
+	char issuenumber[SSD_LABEL_FIELD_SZ];
+	char cleicode[SSD_LABEL_FIELD_SZ];
+	char bom[SSD_LABEL_FIELD_SZ];
+} ssd_labelv3_t;
+
+/* battery */
+typedef struct ssd_battery_info
+{
+	uint32_t fw_ver;
+} ssd_battery_info_t;
+
+/* ssd power stat */
+typedef struct ssd_power_stat
+{
+	uint64_t nr_poweron;
+	uint64_t nr_powerloss;
+	uint64_t init_failed;
+} ssd_power_stat_t;
+
+/* io stat */
+typedef struct ssd_io_stat
+{
+	uint64_t run_time;
+	uint64_t nr_to;
+	uint64_t nr_ioerr;
+	uint64_t nr_rwerr;
+	uint64_t nr_read;
+	uint64_t nr_write;
+	uint64_t rsectors;
+	uint64_t wsectors;
+} ssd_io_stat_t;
+
+/* ecc */
+typedef struct ssd_ecc_info
+{
+	uint64_t bitflip[SSD_ECC_MAX_FLIP];
+} ssd_ecc_info_t;
+
+/* log */
+enum ssd_log_level
+{
+	SSD_LOG_LEVEL_INFO = 0,
+	SSD_LOG_LEVEL_NOTICE,
+	SSD_LOG_LEVEL_WARNING,
+	SSD_LOG_LEVEL_ERR,
+	SSD_LOG_NR_LEVEL
+};
+
+typedef struct ssd_log_info
+{
+	uint64_t nr_log;
+	uint64_t stat[SSD_LOG_NR_LEVEL];
+} ssd_log_info_t;
+
+/* S.M.A.R.T. */
+#define SSD_SMART_MAGIC	(0x5452414D53445353ull)
+
+typedef struct ssd_smart
+{
+	struct ssd_power_stat pstat;
+	struct ssd_io_stat io_stat;
+	struct ssd_ecc_info ecc_info;
+	struct ssd_log_info log_info;
+	uint64_t version;
+	uint64_t magic;
+} ssd_smart_t;
+
+/* internal log */
+typedef struct ssd_internal_log
+{
+	uint32_t nr_log;
+	void *log;
+} ssd_internal_log_t;
+
+/* ssd cmd */
+typedef struct ssd_cmd
+{
+	struct bio *bio;
+	struct scatterlist *sgl;
+	struct list_head list;
+	void *dev;
+	int nsegs;
+	int flag;		/*pbio(1) or bio(0)*/
+
+	int tag;
+	void *msg;
+	dma_addr_t msg_dma;
+
+	unsigned long start_time;
+
+	int errors;
+	unsigned int nr_log;
+
+	struct timer_list cmd_timer;
+	struct completion *waiting;
+} ssd_cmd_t;
+
+typedef void (*send_cmd_func)(struct ssd_cmd *);
+typedef int (*ssd_event_call)(struct gendisk *, int, int);	/* gendisk, event id, event level */
+
+/* dcmd sz */
+#define SSD_DCMD_MAX_SZ 32
+
+typedef struct ssd_dcmd
+{
+	struct list_head list;
+	void *dev;
+	uint8_t msg[SSD_DCMD_MAX_SZ];
+} ssd_dcmd_t;
+
+
+enum ssd_state {
+	SSD_INIT_WORKQ, 
+	SSD_INIT_BD, 
+	SSD_ONLINE, 
+	/* full reset */
+	SSD_RESETING, 
+	/* hw log */
+	SSD_LOG_HW, 
+	/* log err */
+	SSD_LOG_ERR
+};
+
+#define SSD_QUEUE_NAME_LEN	16
+typedef struct ssd_queue {
+	char name[SSD_QUEUE_NAME_LEN];
+	void *dev;
+
+	int idx;
+
+	uint32_t resp_idx;
+	uint32_t resp_idx_mask;
+	uint32_t resp_msg_sz;
+
+	void *resp_msg;
+	void *resp_ptr;
+
+	struct ssd_cmd *cmd;
+
+	struct ssd_io_stat io_stat;
+	struct ssd_ecc_info ecc_info;
+} ssd_queue_t;
+
+typedef struct ssd_device {
+	char name[SSD_DEV_NAME_LEN];
+
+	int idx;
+	int major;
+	int readonly;
+
+	int int_mode;
+#ifdef SSD_ESCAPE_IRQ
+	int irq_cpu;
+#endif
+
+	int reload_fw;
+
+	int ot_delay; //in ms
+
+	atomic_t refcnt;
+	atomic_t tocnt;
+	atomic_t in_flight[2]; //r&w
+
+	uint64_t uptime;
+
+	struct list_head list;
+	struct pci_dev *pdev;
+
+	unsigned long mmio_base;
+	unsigned long mmio_len;
+	void __iomem *ctrlp;
+
+	struct mutex spi_mutex;
+	struct mutex i2c_mutex;
+
+	struct ssd_protocol_info protocol_info;
+	struct ssd_hw_info hw_info;
+	struct ssd_rom_info rom_info;
+	struct ssd_label label;
+
+	struct ssd_smart smart;
+
+	atomic_t in_sendq;
+	spinlock_t sendq_lock;
+	struct ssd_blist sendq;
+	struct task_struct *send_thread;
+	wait_queue_head_t send_waitq;
+
+	atomic_t in_doneq;
+	spinlock_t doneq_lock;
+	struct ssd_blist doneq;
+	struct task_struct *done_thread;
+	wait_queue_head_t done_waitq;
+
+	struct ssd_dcmd *dcmd;
+	spinlock_t dcmd_lock;
+	struct list_head dcmd_list; /* direct cmd list */
+	wait_queue_head_t dcmd_wq;
+
+	unsigned long *tag_map;
+	wait_queue_head_t tag_wq;
+
+	spinlock_t cmd_lock;
+	struct ssd_cmd *cmd;
+	send_cmd_func scmd;
+
+	ssd_event_call event_call;
+	void *msg_base;
+	dma_addr_t msg_base_dma;
+
+	uint32_t resp_idx;
+	void *resp_msg_base;
+	void *resp_ptr_base;
+	dma_addr_t resp_msg_base_dma;
+	dma_addr_t resp_ptr_base_dma;
+
+	int nr_queue;
+	struct msix_entry entry[SSD_MSIX_VEC];
+	struct ssd_queue queue[SSD_MSIX_VEC];
+
+	struct request_queue *rq; /* The device request queue */
+	struct gendisk *gd; /* The gendisk structure */
+
+	struct mutex internal_log_mutex;
+	struct ssd_internal_log internal_log;
+	struct workqueue_struct *workq;
+	struct work_struct log_work; /* get log */
+	void *log_buf;
+
+	unsigned long state; /* device state, for example, block device inited */
+
+	struct module *owner;
+
+	/* extend */
+
+	int slave;
+	int cmajor;
+	int save_md;
+	int ot_protect;
+
+	struct kref kref;
+
+	struct mutex gd_mutex;
+	struct ssd_log_info log_info; /* volatile */
+
+	atomic_t queue_depth;
+	struct mutex barrier_mutex;
+	struct mutex fw_mutex;
+
+	struct ssd_hw_info_extend hw_info_ext;
+	struct ssd_labelv3 labelv3;
+
+	int wmode;
+	int user_wmode;
+	struct mutex bm_mutex;
+	struct work_struct bm_work; /* check bm */
+	struct timer_list bm_timer;
+	struct sfifo log_fifo;
+
+	struct timer_list routine_timer;
+	unsigned long routine_tick;
+	unsigned long hwmon;
+
+	struct work_struct hwmon_work; /* check hw */
+	struct work_struct capmon_work; /* check battery */
+	struct work_struct tempmon_work; /* check temp */
+
+	/* debug info */
+	struct ssd_debug_info db_info;
+} ssd_device_t;
+
+
+/* Ioctl struct */
+typedef struct ssd_acc_info {
+	uint32_t threshold_l1;
+	uint32_t threshold_l2;
+	uint32_t val;
+} ssd_acc_info_t;
+
+typedef struct ssd_reg_op_info
+{
+	uint32_t offset;
+	uint32_t value;
+} ssd_reg_op_info_t;
+
+typedef struct ssd_spi_op_info
+{
+	void __user *buf;
+	uint32_t off;
+	uint32_t len;
+} ssd_spi_op_info_t;
+
+typedef struct ssd_i2c_op_info
+{
+	uint8_t saddr;
+	uint8_t wsize;
+	uint8_t rsize;
+	void __user *wbuf;
+	void __user *rbuf;
+} ssd_i2c_op_info_t;
+
+typedef struct ssd_smbus_op_info
+{
+	uint8_t saddr;
+	uint8_t cmd;
+	uint8_t size;
+	void __user *buf;
+} ssd_smbus_op_info_t;
+
+typedef struct ssd_ram_op_info {
+	uint8_t ctrl_idx;
+	uint32_t length;
+	uint64_t start;
+	uint8_t __user *buf;
+} ssd_ram_op_info_t;
+
+typedef struct ssd_flash_op_info {
+	uint32_t page;
+	uint16_t flash;
+	uint8_t chip;
+	uint8_t ctrl_idx;
+	uint8_t __user *buf;
+} ssd_flash_op_info_t;
+
+typedef struct ssd_sw_log_info {
+	uint16_t event;
+	uint16_t pad;
+	uint32_t data;
+} ssd_sw_log_info_t;
+
+typedef struct ssd_version_info
+{
+	uint32_t bridge_ver;	/* bridge fw version */
+	uint32_t ctrl_ver;		/* controller fw version */
+	uint32_t bm_ver;		/* battery manager fw version */
+	uint8_t  pcb_ver;		/* main pcb version */
+	uint8_t  upper_pcb_ver;
+	uint8_t  pad0;
+	uint8_t  pad1;
+} ssd_version_info_t;
+
+typedef struct pci_addr
+{
+	uint16_t domain;
+	uint8_t bus;
+	uint8_t slot;
+	uint8_t func;
+} pci_addr_t;
+
+typedef struct ssd_drv_param_info {
+	int mode;
+	int status_mask;
+	int int_mode;
+	int threaded_irq;
+	int log_level;
+	int wmode;
+	int ot_protect;
+	int finject;
+	int pad[8];
+} ssd_drv_param_info_t;
+
+
+/* form factor */
+enum ssd_form_factor
+{
+	SSD_FORM_FACTOR_HHHL = 0, 
+	SSD_FORM_FACTOR_FHHL
+};
+
+
+/* ssd power loss protect */
+enum ssd_plp_type
+{
+	SSD_PLP_SCAP = 0,
+	SSD_PLP_CAP,
+	SSD_PLP_NONE
+};
+
+/* ssd bm */
+#define SSD_BM_SLAVE_ADDRESS	0x16
+#define SSD_BM_CAP	5
+
+/* SBS cmd */
+#define SSD_BM_SAFETYSTATUS			0x51
+#define SSD_BM_OPERATIONSTATUS		0x54
+
+/* ManufacturerAccess */
+#define SSD_BM_MANUFACTURERACCESS	0x00		
+#define SSD_BM_ENTER_CAP_LEARNING	0x0023		/* cap learning */
+
+/* Data flash access */
+#define SSD_BM_DATA_FLASH_SUBCLASS_ID 0x77
+#define SSD_BM_DATA_FLASH_SUBCLASS_ID_PAGE1 0x78
+#define SSD_BM_SYSTEM_DATA_SUBCLASS_ID	56
+#define SSD_BM_CONFIGURATION_REGISTERS_ID	64
+
+/* min cap voltage */
+#define SSD_BM_CAP_VOLT_MIN			500
+
+/*
+enum ssd_bm_cap
+{
+	SSD_BM_CAP_VINA = 1, 
+	SSD_BM_CAP_JH = 3
+};*/
+
+enum ssd_bmstatus
+{
+	SSD_BMSTATUS_OK = 0,
+	SSD_BMSTATUS_CHARGING, 		/* not fully charged */
+	SSD_BMSTATUS_WARNING
+};
+
+enum sbs_unit {
+	SBS_UNIT_VALUE = 0,
+	SBS_UNIT_TEMPERATURE,
+	SBS_UNIT_VOLTAGE,
+	SBS_UNIT_CURRENT,
+	SBS_UNIT_ESR,
+	SBS_UNIT_PERCENT,
+	SBS_UNIT_CAPACITANCE
+};
+
+enum sbs_size {
+	SBS_SIZE_BYTE = 1,
+	SBS_SIZE_WORD,
+	SBS_SIZE_BLK,
+};
+
+struct sbs_cmd {
+	uint8_t cmd;
+	uint8_t size;
+	uint8_t unit;
+	uint8_t off;
+	uint16_t mask;
+	char *desc;
+};
+
+struct ssd_bm {
+	uint16_t temp;
+	uint16_t volt;
+	uint16_t curr;
+	uint16_t esr;
+	uint16_t rsoc;
+	uint16_t health;
+	uint16_t cap;
+	uint16_t chg_curr;
+	uint16_t chg_volt;
+	uint16_t cap_volt[SSD_BM_CAP];
+	uint16_t sf_alert;
+	uint16_t sf_status;
+	uint16_t op_status;
+	uint16_t sys_volt;
+};
+
+struct ssd_bm_manufacturer_data
+{
+	uint16_t pack_lot_code;
+	uint16_t pcb_lot_code;
+	uint16_t firmware_ver;
+	uint16_t hardware_ver;
+};
+
+struct ssd_bm_configuration_registers
+{
+	struct {
+		uint16_t cc:3;
+		uint16_t rsvd:5;
+		uint16_t stack:1;
+		uint16_t rsvd1:2;
+		uint16_t temp:2;
+		uint16_t rsvd2:1;
+		uint16_t lt_en:1;
+		uint16_t rsvd3:1;
+	} operation_cfg;
+	uint16_t pad;
+	uint16_t fet_action;
+	uint16_t pad1;
+	uint16_t fault;
+};
+
+#define SBS_VALUE_MASK	0xffff
+
+#define bm_var_offset(var)	((size_t) &((struct ssd_bm *)0)->var)
+#define bm_var(start, offset)	((void *) start + (offset))
+
+static struct sbs_cmd ssd_bm_sbs[] = {
+	{0x08, SBS_SIZE_WORD, SBS_UNIT_TEMPERATURE, bm_var_offset(temp), SBS_VALUE_MASK, "Temperature"}, 
+	{0x09, SBS_SIZE_WORD, SBS_UNIT_VOLTAGE, bm_var_offset(volt), SBS_VALUE_MASK, "Voltage"}, 
+	{0x0a, SBS_SIZE_WORD, SBS_UNIT_CURRENT, bm_var_offset(curr), SBS_VALUE_MASK, "Current"}, 
+	{0x0b, SBS_SIZE_WORD, SBS_UNIT_ESR, bm_var_offset(esr), SBS_VALUE_MASK, "ESR"}, 
+	{0x0d, SBS_SIZE_BYTE, SBS_UNIT_PERCENT, bm_var_offset(rsoc), SBS_VALUE_MASK, "RelativeStateOfCharge"}, 
+	{0x0e, SBS_SIZE_BYTE, SBS_UNIT_PERCENT, bm_var_offset(health), SBS_VALUE_MASK, "Health"}, 
+	{0x10, SBS_SIZE_WORD, SBS_UNIT_CAPACITANCE, bm_var_offset(cap), SBS_VALUE_MASK, "Capacitance"}, 
+	{0x14, SBS_SIZE_WORD, SBS_UNIT_CURRENT, bm_var_offset(chg_curr), SBS_VALUE_MASK, "ChargingCurrent"}, 
+	{0x15, SBS_SIZE_WORD, SBS_UNIT_VOLTAGE, bm_var_offset(chg_volt), SBS_VALUE_MASK, "ChargingVoltage"}, 
+	{0x3b, SBS_SIZE_WORD, SBS_UNIT_VOLTAGE, (uint8_t)bm_var_offset(cap_volt[4]), SBS_VALUE_MASK, "CapacitorVoltage5"}, 
+	{0x3c, SBS_SIZE_WORD, SBS_UNIT_VOLTAGE, (uint8_t)bm_var_offset(cap_volt[3]), SBS_VALUE_MASK, "CapacitorVoltage4"}, 
+	{0x3d, SBS_SIZE_WORD, SBS_UNIT_VOLTAGE, (uint8_t)bm_var_offset(cap_volt[2]), SBS_VALUE_MASK, "CapacitorVoltage3"}, 
+	{0x3e, SBS_SIZE_WORD, SBS_UNIT_VOLTAGE, (uint8_t)bm_var_offset(cap_volt[1]), SBS_VALUE_MASK, "CapacitorVoltage2"}, 
+	{0x3f, SBS_SIZE_WORD, SBS_UNIT_VOLTAGE, (uint8_t)bm_var_offset(cap_volt[0]), SBS_VALUE_MASK, "CapacitorVoltage1"}, 
+	{0x50, SBS_SIZE_WORD, SBS_UNIT_VALUE, bm_var_offset(sf_alert), 0x870F, "SafetyAlert"}, 
+	{0x51, SBS_SIZE_WORD, SBS_UNIT_VALUE, bm_var_offset(sf_status), 0xE7BF, "SafetyStatus"}, 
+	{0x54, SBS_SIZE_WORD, SBS_UNIT_VALUE, bm_var_offset(op_status), 0x79F4, "OperationStatus"}, 
+	{0x5a, SBS_SIZE_WORD, SBS_UNIT_VOLTAGE, bm_var_offset(sys_volt), SBS_VALUE_MASK, "SystemVoltage"}, 
+	{0, 0, 0, 0, 0, NULL}, 
+};
+
+/* ssd ioctl  */
+#define SSD_CMD_GET_PROTOCOL_INFO	_IOR('H', 100, struct ssd_protocol_info)
+#define SSD_CMD_GET_HW_INFO			_IOR('H', 101, struct ssd_hw_info)
+#define SSD_CMD_GET_ROM_INFO		_IOR('H', 102, struct ssd_rom_info)
+#define SSD_CMD_GET_SMART			_IOR('H', 103, struct ssd_smart)
+#define SSD_CMD_GET_IDX				_IOR('H', 105, int)
+#define SSD_CMD_GET_AMOUNT			_IOR('H', 106, int)
+#define SSD_CMD_GET_TO_INFO			_IOR('H', 107, int)
+#define SSD_CMD_GET_DRV_VER			_IOR('H', 108, char[DRIVER_VERSION_LEN])
+
+#define SSD_CMD_GET_BBACC_INFO		_IOR('H', 109, struct ssd_acc_info)
+#define SSD_CMD_GET_ECACC_INFO		_IOR('H', 110, struct ssd_acc_info)
+
+#define SSD_CMD_GET_HW_INFO_EXT		_IOR('H', 111, struct ssd_hw_info_extend)
+
+#define SSD_CMD_REG_READ			_IOWR('H', 120, struct ssd_reg_op_info)
+#define SSD_CMD_REG_WRITE			_IOWR('H', 121, struct ssd_reg_op_info)
+
+#define SSD_CMD_SPI_READ			_IOWR('H', 125, struct ssd_spi_op_info)
+#define SSD_CMD_SPI_WRITE			_IOWR('H', 126, struct ssd_spi_op_info)
+#define SSD_CMD_SPI_ERASE			_IOWR('H', 127, struct ssd_spi_op_info)
+
+#define SSD_CMD_I2C_READ			_IOWR('H', 128, struct ssd_i2c_op_info)
+#define SSD_CMD_I2C_WRITE			_IOWR('H', 129, struct ssd_i2c_op_info)
+#define SSD_CMD_I2C_WRITE_READ		_IOWR('H', 130, struct ssd_i2c_op_info)
+
+#define SSD_CMD_SMBUS_SEND_BYTE		_IOWR('H', 131, struct ssd_smbus_op_info)
+#define SSD_CMD_SMBUS_RECEIVE_BYTE	_IOWR('H', 132, struct ssd_smbus_op_info)
+#define SSD_CMD_SMBUS_WRITE_BYTE	_IOWR('H', 133, struct ssd_smbus_op_info)
+#define SSD_CMD_SMBUS_READ_BYTE		_IOWR('H', 135, struct ssd_smbus_op_info)
+#define SSD_CMD_SMBUS_WRITE_WORD	_IOWR('H', 136, struct ssd_smbus_op_info)
+#define SSD_CMD_SMBUS_READ_WORD		_IOWR('H', 137, struct ssd_smbus_op_info)
+#define SSD_CMD_SMBUS_WRITE_BLOCK	_IOWR('H', 138, struct ssd_smbus_op_info)
+#define SSD_CMD_SMBUS_READ_BLOCK	_IOWR('H', 139, struct ssd_smbus_op_info)
+
+#define SSD_CMD_BM_GET_VER			_IOR('H', 140, uint16_t)
+#define SSD_CMD_BM_GET_NR_CAP		_IOR('H', 141, int)
+#define SSD_CMD_BM_CAP_LEARNING		_IOW('H', 142, int)
+#define SSD_CMD_CAP_LEARN			_IOR('H', 143, uint32_t)
+#define SSD_CMD_GET_CAP_STATUS		_IOR('H', 144, int)
+
+#define SSD_CMD_RAM_READ			_IOWR('H', 150, struct ssd_ram_op_info)
+#define SSD_CMD_RAM_WRITE			_IOWR('H', 151, struct ssd_ram_op_info)
+
+#define SSD_CMD_NAND_READ_ID		_IOR('H', 160, struct ssd_flash_op_info)
+#define SSD_CMD_NAND_READ			_IOWR('H', 161, struct ssd_flash_op_info) //with oob
+#define SSD_CMD_NAND_WRITE			_IOWR('H', 162, struct ssd_flash_op_info)
+#define SSD_CMD_NAND_ERASE			_IOWR('H', 163, struct ssd_flash_op_info)
+#define SSD_CMD_NAND_READ_EXT		_IOWR('H', 164, struct ssd_flash_op_info) //ingore EIO
+
+#define SSD_CMD_UPDATE_BBT			_IOW('H', 180, struct ssd_flash_op_info)
+
+#define SSD_CMD_CLEAR_ALARM			_IOW('H', 190, int)
+#define SSD_CMD_SET_ALARM			_IOW('H', 191, int)
+
+#define SSD_CMD_RESET				_IOW('H', 200, int)
+#define SSD_CMD_RELOAD_FW			_IOW('H', 201, int)
+#define SSD_CMD_UNLOAD_DEV			_IOW('H', 202, int)
+#define SSD_CMD_LOAD_DEV			_IOW('H', 203, int)
+#define SSD_CMD_UPDATE_VP			_IOWR('H', 205, uint32_t)
+#define SSD_CMD_FULL_RESET			_IOW('H', 206, int)
+
+#define SSD_CMD_GET_NR_LOG			_IOR('H', 220, uint32_t)
+#define SSD_CMD_GET_LOG				_IOR('H', 221, void *)
+#define SSD_CMD_LOG_LEVEL			_IOW('H', 222, int)
+
+#define SSD_CMD_OT_PROTECT			_IOW('H', 223, int)
+#define SSD_CMD_GET_OT_STATUS		_IOR('H', 224, int)
+
+#define SSD_CMD_CLEAR_LOG			_IOW('H', 230, int)
+#define SSD_CMD_CLEAR_SMART			_IOW('H', 231, int)
+
+#define SSD_CMD_SW_LOG				_IOW('H', 232, struct ssd_sw_log_info)
+
+#define SSD_CMD_GET_LABEL			_IOR('H', 235, struct ssd_label)
+#define SSD_CMD_GET_VERSION			_IOR('H', 236, struct ssd_version_info)
+#define SSD_CMD_GET_TEMPERATURE		_IOR('H', 237, int)
+#define SSD_CMD_GET_BMSTATUS		_IOR('H', 238, int)
+#define SSD_CMD_GET_LABEL2			_IOR('H', 239, void *)
+
+
+#define SSD_CMD_FLUSH				_IOW('H', 240, int)
+#define SSD_CMD_SAVE_MD				_IOW('H', 241, int)
+
+#define SSD_CMD_SET_WMODE			_IOW('H', 242, int)
+#define SSD_CMD_GET_WMODE			_IOR('H', 243, int)
+#define SSD_CMD_GET_USER_WMODE		_IOR('H', 244, int)
+
+#define SSD_CMD_DEBUG				_IOW('H', 250, struct ssd_debug_info)
+#define SSD_CMD_DRV_PARAM_INFO		_IOR('H', 251, struct ssd_drv_param_info)
+
+
+/* log */
+#define SSD_LOG_MAX_SZ				4096
+#define SSD_LOG_LEVEL				SSD_LOG_LEVEL_NOTICE
+
+enum ssd_log_data
+{
+	SSD_LOG_DATA_NONE = 0,
+	SSD_LOG_DATA_LOC, 
+	SSD_LOG_DATA_HEX
+};
+
+typedef struct ssd_log_entry
+{
+	union {
+		struct {
+			uint32_t page:10;
+			uint32_t block:14;
+			uint32_t flash:8;
+		} loc;
+		struct {
+			uint32_t page:12;
+			uint32_t block:12;
+			uint32_t flash:8;
+		} loc1;
+		uint32_t val;
+	} data;
+	uint16_t event:10;
+	uint16_t mod:6;
+	uint16_t idx;
+}__attribute__((packed))ssd_log_entry_t;
+
+typedef struct ssd_log
+{
+	uint64_t time:56;
+	uint64_t ctrl_idx:8;
+	ssd_log_entry_t le;
+} __attribute__((packed)) ssd_log_t;
+
+typedef struct ssd_log_desc
+{
+	uint16_t event;
+	uint8_t level;
+	uint8_t data;
+	uint8_t sblock;
+	uint8_t spage;
+	char *desc;
+} __attribute__((packed)) ssd_log_desc_t;
+
+#define SSD_LOG_SW_IDX		0xF
+#define SSD_UNKNOWN_EVENT	((uint16_t)-1)
+static struct ssd_log_desc ssd_log_desc[] = {
+	/* event, level, show flash, show block, show page, desc */
+	{0x0,  SSD_LOG_LEVEL_WARNING, SSD_LOG_DATA_LOC,  0, 0, "Create BBT failure"}, //g3
+	{0x1,  SSD_LOG_LEVEL_WARNING, SSD_LOG_DATA_LOC,  0, 0, "Read BBT failure"}, //g3
+	{0x2,  SSD_LOG_LEVEL_NOTICE,  SSD_LOG_DATA_LOC,  1, 0, "Mark bad block"}, 
+	{0x3,  SSD_LOG_LEVEL_NOTICE,  SSD_LOG_DATA_LOC,  0, 0, "Flush BBT failure"}, 
+	{0x4,  SSD_LOG_LEVEL_NOTICE,  SSD_LOG_DATA_LOC,  1, 1, "Program failure"}, 
+	{0x7,  SSD_LOG_LEVEL_ERR,     SSD_LOG_DATA_LOC,  1, 1, "No available blocks"}, 
+	{0x8,  SSD_LOG_LEVEL_NOTICE,  SSD_LOG_DATA_LOC,  1, 0, "Bad EC header"}, 
+	{0x9,  SSD_LOG_LEVEL_WARNING, SSD_LOG_DATA_LOC,  1, 0, "Bad VID header"}, //g3
+	{0xa,  SSD_LOG_LEVEL_INFO,    SSD_LOG_DATA_LOC,  1, 0, "Wear leveling"}, 
+	{0xb,  SSD_LOG_LEVEL_NOTICE,  SSD_LOG_DATA_LOC,  1, 1, "WL read back failure"}, 
+	{0x11, SSD_LOG_LEVEL_ERR,     SSD_LOG_DATA_LOC,  1, 1, "Data recovery failure"}, // err
+	{0x20, SSD_LOG_LEVEL_ERR,     SSD_LOG_DATA_LOC,  1, 1, "Init: scan mapping table failure"}, // err g3
+	{0x21, SSD_LOG_LEVEL_NOTICE,  SSD_LOG_DATA_LOC,  1, 1, "Program failure"}, 
+	{0x22, SSD_LOG_LEVEL_NOTICE,  SSD_LOG_DATA_LOC,  1, 1, "Program failure"}, 
+	{0x23, SSD_LOG_LEVEL_NOTICE,  SSD_LOG_DATA_LOC,  1, 1, "Program failure"}, 
+	{0x24, SSD_LOG_LEVEL_NOTICE,  SSD_LOG_DATA_LOC,  1, 0, "Merge: read mapping page failure"}, 
+	{0x25, SSD_LOG_LEVEL_NOTICE,  SSD_LOG_DATA_LOC,  1, 1, "Merge: read back failure"}, 
+	{0x26, SSD_LOG_LEVEL_NOTICE,  SSD_LOG_DATA_LOC,  1, 1, "Program failure"}, 
+	{0x27, SSD_LOG_LEVEL_WARNING, SSD_LOG_DATA_LOC,  1, 1, "Data corrupted for abnormal power down"}, //g3
+	{0x28, SSD_LOG_LEVEL_NOTICE,  SSD_LOG_DATA_LOC,  1, 1, "Merge: mapping page corrupted"}, 
+	{0x29, SSD_LOG_LEVEL_NOTICE,  SSD_LOG_DATA_LOC,  1, 0, "Init: no mapping page"}, 
+	{0x2a, SSD_LOG_LEVEL_NOTICE,  SSD_LOG_DATA_LOC,  1, 1, "Init: mapping pages incomplete"}, 
+	{0x2b, SSD_LOG_LEVEL_ERR,     SSD_LOG_DATA_LOC,  1, 1, "Read back failure after programming failure"}, // err
+	{0xf1, SSD_LOG_LEVEL_ERR,     SSD_LOG_DATA_LOC,  1, 1, "Read failure without recovery"}, // err
+	{0xf2, SSD_LOG_LEVEL_ERR,     SSD_LOG_DATA_LOC,  0, 0, "No available blocks"}, // maybe err g3
+	{0xf3, SSD_LOG_LEVEL_ERR,     SSD_LOG_DATA_LOC,  1, 0, "Init: RAID incomplete"}, // err g3
+	{0xf4, SSD_LOG_LEVEL_NOTICE,  SSD_LOG_DATA_LOC,  1, 1, "Program failure"}, 
+	{0xf5, SSD_LOG_LEVEL_NOTICE,  SSD_LOG_DATA_LOC,  1, 1, "Read failure in moving data"}, 
+	{0xf6, SSD_LOG_LEVEL_NOTICE,  SSD_LOG_DATA_LOC,  1, 1, "Program failure"}, 
+	{0xf7, SSD_LOG_LEVEL_WARNING, SSD_LOG_DATA_LOC,  1, 1, "Init: RAID not complete"}, 
+	{0xf8, SSD_LOG_LEVEL_NOTICE,  SSD_LOG_DATA_LOC,  1, 0, "Init: data moving interrupted"}, 
+	{0xfe, SSD_LOG_LEVEL_NOTICE,  SSD_LOG_DATA_LOC,  0, 0, "Data inspection failure"}, 
+	{0xff, SSD_LOG_LEVEL_NOTICE,  SSD_LOG_DATA_LOC,  1, 1, "IO: ECC failed"}, 
+
+	/* new */
+	{0x2e, SSD_LOG_LEVEL_ERR,     SSD_LOG_DATA_LOC,  0, 0, "No available reserved blocks" }, // err
+	{0x30, SSD_LOG_LEVEL_NOTICE,  SSD_LOG_DATA_LOC,  0, 0, "Init: PMT membership not found"}, 
+	{0x31, SSD_LOG_LEVEL_NOTICE,  SSD_LOG_DATA_HEX,  0, 0, "Init: PMT corrupted"}, 
+	{0x32, SSD_LOG_LEVEL_NOTICE,  SSD_LOG_DATA_LOC,  0, 0, "Init: PBT membership not found"}, 
+	{0x33, SSD_LOG_LEVEL_NOTICE,  SSD_LOG_DATA_LOC,  0, 0, "Init: PBT not found"}, 
+	{0x34, SSD_LOG_LEVEL_NOTICE,  SSD_LOG_DATA_LOC,  0, 0, "Init: PBT corrupted"}, 
+	{0x35, SSD_LOG_LEVEL_NOTICE,  SSD_LOG_DATA_LOC,  1, 1, "Init: PMT page read failure"}, 
+	{0x36, SSD_LOG_LEVEL_NOTICE,  SSD_LOG_DATA_LOC,  1, 1, "Init: PBT page read failure"}, 
+	{0x37, SSD_LOG_LEVEL_NOTICE,  SSD_LOG_DATA_LOC,  1, 1, "Init: PBT backup page read failure"}, 
+	{0x38, SSD_LOG_LEVEL_NOTICE,  SSD_LOG_DATA_LOC,  1, 1, "Init: PBMT read failure"}, 
+	{0x39, SSD_LOG_LEVEL_ERR,     SSD_LOG_DATA_LOC,  1, 1, "Init: PBMT scan failure"}, // err
+	{0x3a, SSD_LOG_LEVEL_NOTICE,  SSD_LOG_DATA_LOC,  1, 1, "Init: first page read failure"}, 
+	{0x3b, SSD_LOG_LEVEL_ERR,     SSD_LOG_DATA_LOC,  1, 1, "Init: first page scan failure"}, // err
+	{0x3c, SSD_LOG_LEVEL_ERR,     SSD_LOG_DATA_LOC,  1, 1, "Init: scan unclosed block failure"}, // err
+	{0x3d, SSD_LOG_LEVEL_NOTICE,  SSD_LOG_DATA_LOC,  1, 1, "Init: write pointer mismatch"}, 
+	{0x3e, SSD_LOG_LEVEL_NOTICE,  SSD_LOG_DATA_LOC,  1, 1, "Init: PMT recovery: PBMT read failure"}, 
+	{0x3f, SSD_LOG_LEVEL_NOTICE,  SSD_LOG_DATA_LOC,  1, 0, "Init: PMT recovery: PBMT scan failure"}, 
+	{0x40, SSD_LOG_LEVEL_ERR,     SSD_LOG_DATA_LOC,  1, 1, "Init: PMT recovery: data page read failure"}, //err
+	{0x41, SSD_LOG_LEVEL_NOTICE,  SSD_LOG_DATA_LOC,  1, 1, "Init: PBT write pointer mismatch"}, 
+	{0x42, SSD_LOG_LEVEL_NOTICE,  SSD_LOG_DATA_LOC,  1, 1, "Init: PBT latest version corrupted"}, 
+	{0x43, SSD_LOG_LEVEL_ERR,     SSD_LOG_DATA_LOC,  1, 0, "Init: too many unclosed blocks"}, 
+	{0x44, SSD_LOG_LEVEL_NOTICE,  SSD_LOG_DATA_HEX,  0, 0, "Init: PDW block found"}, 
+	{0x45, SSD_LOG_LEVEL_ERR,     SSD_LOG_DATA_HEX,  0, 0, "Init: more than one PDW block found"}, //err
+	{0x46, SSD_LOG_LEVEL_NOTICE,  SSD_LOG_DATA_LOC,  1, 1, "Init: first page is blank or read failure"}, 
+	{0x47, SSD_LOG_LEVEL_NOTICE,  SSD_LOG_DATA_LOC,  0, 0, "Init: PDW block not found"}, 
+
+	{0x50, SSD_LOG_LEVEL_ERR,     SSD_LOG_DATA_LOC,  1, 0, "Cache: hit error data"}, // err
+	{0x51, SSD_LOG_LEVEL_ERR,     SSD_LOG_DATA_LOC,  1, 0, "Cache: read back failure"}, // err
+	{0x52, SSD_LOG_LEVEL_NOTICE,  SSD_LOG_DATA_NONE, 0, 0, "Cache: unknown command"}, //?
+	{0x53, SSD_LOG_LEVEL_ERR,     SSD_LOG_DATA_LOC,  1, 1, "GC/WL read back failure"}, // err
+
+	{0x60, SSD_LOG_LEVEL_NOTICE,  SSD_LOG_DATA_LOC,  1, 0, "Erase failure"}, 
+
+	{0x70, SSD_LOG_LEVEL_NOTICE,  SSD_LOG_DATA_LOC,  1, 1, "LPA not matched"}, 
+	{0x71, SSD_LOG_LEVEL_NOTICE,  SSD_LOG_DATA_LOC,  1, 1, "PBN not matched"}, 
+	{0x72, SSD_LOG_LEVEL_NOTICE,  SSD_LOG_DATA_LOC,  1, 1, "Read retry failure"}, 
+	{0x73, SSD_LOG_LEVEL_NOTICE,  SSD_LOG_DATA_LOC,  1, 1, "Need raid recovery"}, 
+	{0x74, SSD_LOG_LEVEL_INFO,    SSD_LOG_DATA_LOC,  1, 1, "Need read retry"}, 
+	{0x75, SSD_LOG_LEVEL_NOTICE,  SSD_LOG_DATA_LOC,  1, 1, "Read invalid data page"}, 
+	{0x76, SSD_LOG_LEVEL_INFO,    SSD_LOG_DATA_LOC,  1, 1, "ECC error, data in cache, PBN matched"}, 
+	{0x77, SSD_LOG_LEVEL_NOTICE,  SSD_LOG_DATA_LOC,  1, 1, "ECC error, data in cache, PBN not matched"}, 
+	{0x78, SSD_LOG_LEVEL_NOTICE,  SSD_LOG_DATA_LOC,  1, 1, "ECC error, data in flash, PBN not matched"}, 
+	{0x79, SSD_LOG_LEVEL_NOTICE,  SSD_LOG_DATA_LOC,  1, 1, "ECC ok, data in cache, LPA not matched"},
+	{0x7a, SSD_LOG_LEVEL_NOTICE,  SSD_LOG_DATA_LOC,  1, 1, "ECC ok, data in flash, LPA not matched"},
+	{0x7b, SSD_LOG_LEVEL_NOTICE,  SSD_LOG_DATA_LOC,  1, 1, "RAID data in cache, LPA not matched"}, 
+	{0x7c, SSD_LOG_LEVEL_NOTICE,  SSD_LOG_DATA_LOC,  1, 1, "RAID data in flash, LPA not matched"}, 
+	{0x7d, SSD_LOG_LEVEL_NOTICE,  SSD_LOG_DATA_LOC,  1, 1, "Read data page status error"}, 
+	{0x7e, SSD_LOG_LEVEL_NOTICE,  SSD_LOG_DATA_LOC,  1, 1, "Read blank page"}, 
+	{0x7f, SSD_LOG_LEVEL_NOTICE,  SSD_LOG_DATA_LOC,  1, 1, "Access flash timeout"}, 
+
+	{0x80, SSD_LOG_LEVEL_NOTICE,  SSD_LOG_DATA_LOC,  1, 0, "EC overflow"}, 
+	{0x81, SSD_LOG_LEVEL_INFO,    SSD_LOG_DATA_NONE, 0, 0, "Scrubbing completed"}, 
+	{0x82, SSD_LOG_LEVEL_INFO,    SSD_LOG_DATA_LOC,  1, 0, "Unstable block(too much bit flip)"}, 
+	{0x83, SSD_LOG_LEVEL_NOTICE,  SSD_LOG_DATA_LOC,  1, 0, "GC: ram error"}, //?
+	{0x84, SSD_LOG_LEVEL_NOTICE,  SSD_LOG_DATA_LOC,  1, 0, "GC: one PBMT read failure"}, 
+
+	{0x88, SSD_LOG_LEVEL_NOTICE,  SSD_LOG_DATA_LOC,  1, 0, "GC: mark bad block"}, 
+	{0x89, SSD_LOG_LEVEL_NOTICE,  SSD_LOG_DATA_LOC,  1, 0, "GC: invalid page count error"}, // maybe err
+	{0x8a, SSD_LOG_LEVEL_WARNING, SSD_LOG_DATA_NONE, 0, 0, "Warning: Bad Block close to limit"}, 
+	{0x8b, SSD_LOG_LEVEL_ERR,     SSD_LOG_DATA_NONE, 0, 0, "Error: Bad Block over limit"}, 
+	{0x8c, SSD_LOG_LEVEL_WARNING, SSD_LOG_DATA_NONE, 0, 0, "Warning: P/E cycles close to limit"}, 
+	{0x8d, SSD_LOG_LEVEL_ERR,     SSD_LOG_DATA_NONE, 0, 0, "Error: P/E cycles over limit"}, 
+
+	{0x90, SSD_LOG_LEVEL_NOTICE,  SSD_LOG_DATA_NONE, 0, 0, "Over temperature"}, //xx
+	{0x91, SSD_LOG_LEVEL_NOTICE,  SSD_LOG_DATA_NONE, 0, 0, "Temperature is OK"}, //xx
+	{0x92, SSD_LOG_LEVEL_WARNING, SSD_LOG_DATA_NONE, 0, 0, "Battery fault"}, 
+	{0x93, SSD_LOG_LEVEL_WARNING, SSD_LOG_DATA_NONE, 0, 0, "SEU fault"}, //err
+	{0x94, SSD_LOG_LEVEL_ERR,     SSD_LOG_DATA_NONE, 0, 0, "DDR error"}, //err
+	{0x95, SSD_LOG_LEVEL_ERR,     SSD_LOG_DATA_NONE, 0, 0, "Controller serdes error"}, //err
+	{0x96, SSD_LOG_LEVEL_ERR,     SSD_LOG_DATA_NONE, 0, 0, "Bridge serdes 1 error"}, //err
+	{0x97, SSD_LOG_LEVEL_ERR,     SSD_LOG_DATA_NONE, 0, 0, "Bridge serdes 2 error"}, //err
+	{0x98, SSD_LOG_LEVEL_NOTICE,  SSD_LOG_DATA_NONE, 0, 0, "SEU fault (corrected)"}, //err
+	{0x99, SSD_LOG_LEVEL_NOTICE,  SSD_LOG_DATA_NONE, 0, 0, "Battery is OK"}, 
+	{0x9a, SSD_LOG_LEVEL_NOTICE,  SSD_LOG_DATA_NONE, 0, 0, "Temperature close to limit"}, //xx
+	
+	{0x9b, SSD_LOG_LEVEL_NOTICE,  SSD_LOG_DATA_HEX,  0, 0, "SEU fault address (low)"}, 
+	{0x9c, SSD_LOG_LEVEL_NOTICE,  SSD_LOG_DATA_HEX,  0, 0, "SEU fault address (high)"}, 
+	{0x9d, SSD_LOG_LEVEL_NOTICE,  SSD_LOG_DATA_NONE, 0, 0, "I2C fault" }, 
+	{0x9e, SSD_LOG_LEVEL_NOTICE,  SSD_LOG_DATA_NONE, 0, 0, "DDR single bit error" }, 
+	{0x9f, SSD_LOG_LEVEL_NOTICE,  SSD_LOG_DATA_NONE, 0, 0, "Board voltage fault" },
+
+	{0xa0, SSD_LOG_LEVEL_NOTICE,  SSD_LOG_DATA_HEX,  0, 0, "LPA not matched"}, 
+	{0xa1, SSD_LOG_LEVEL_NOTICE,  SSD_LOG_DATA_LOC,  1, 1, "Re-read data in cache"}, 
+	{0xa2, SSD_LOG_LEVEL_NOTICE,  SSD_LOG_DATA_LOC,  1, 1, "Read blank page"}, 
+	{0xa3, SSD_LOG_LEVEL_NOTICE,  SSD_LOG_DATA_LOC,  1, 1, "RAID recovery: Read blank page"}, 
+	{0xa4, SSD_LOG_LEVEL_NOTICE,  SSD_LOG_DATA_LOC,  1, 1, "RAID recovery: new data in cache"}, 
+	{0xa5, SSD_LOG_LEVEL_NOTICE,  SSD_LOG_DATA_LOC,  1, 1, "RAID recovery: PBN not matched"}, 
+	{0xa6, SSD_LOG_LEVEL_NOTICE,  SSD_LOG_DATA_LOC,  1, 1, "Read data with error flag"}, 
+	{0xa7, SSD_LOG_LEVEL_NOTICE,  SSD_LOG_DATA_LOC,  1, 1, "RAID recovery: recoverd data with error flag"}, 
+	{0xa8, SSD_LOG_LEVEL_NOTICE,  SSD_LOG_DATA_LOC,  1, 1, "Blank page in cache, PBN matched"}, 
+	{0xa9, SSD_LOG_LEVEL_NOTICE,  SSD_LOG_DATA_LOC,  1, 1, "RAID recovery: Blank page in cache, PBN matched"}, 
+	{0xaa, SSD_LOG_LEVEL_NOTICE,  SSD_LOG_DATA_LOC,  0, 0, "Flash init failure"}, 
+	{0xab, SSD_LOG_LEVEL_NOTICE,  SSD_LOG_DATA_LOC,  1, 1, "Mapping table recovery failure"}, 
+	{0xac, SSD_LOG_LEVEL_NOTICE,  SSD_LOG_DATA_LOC,  1, 1, "RAID recovery: ECC failed"}, 
+	{0xb0, SSD_LOG_LEVEL_NOTICE,  SSD_LOG_DATA_NONE, 0, 0, "Temperature is up to degree 95"},
+	{0xb1, SSD_LOG_LEVEL_NOTICE,  SSD_LOG_DATA_NONE, 0, 0, "Temperature is up to degree 100"},
+
+	{0x300, SSD_LOG_LEVEL_ERR,    SSD_LOG_DATA_HEX,  0, 0, "CMD timeout"}, 
+	{0x301, SSD_LOG_LEVEL_NOTICE, SSD_LOG_DATA_HEX,  0, 0, "Power on"}, 
+	{0x302, SSD_LOG_LEVEL_NOTICE, SSD_LOG_DATA_NONE, 0, 0, "Power off"}, 
+	{0x303, SSD_LOG_LEVEL_NOTICE, SSD_LOG_DATA_NONE, 0, 0, "Clear log"}, 
+	{0x304, SSD_LOG_LEVEL_NOTICE, SSD_LOG_DATA_HEX,  0, 0, "Set capacity"}, 
+	{0x305, SSD_LOG_LEVEL_NOTICE, SSD_LOG_DATA_NONE, 0, 0, "Clear data"}, 
+	{0x306, SSD_LOG_LEVEL_NOTICE, SSD_LOG_DATA_HEX,  0, 0, "BM safety status"}, 
+	{0x307, SSD_LOG_LEVEL_ERR,    SSD_LOG_DATA_HEX,  0, 0, "I/O error"}, 
+	{0x308, SSD_LOG_LEVEL_NOTICE, SSD_LOG_DATA_HEX,  0, 0, "CMD error"}, 
+	{0x309, SSD_LOG_LEVEL_NOTICE, SSD_LOG_DATA_HEX,  0, 0, "Set wmode"}, 
+	{0x30a, SSD_LOG_LEVEL_ERR,    SSD_LOG_DATA_HEX,  0, 0, "DDR init failed" }, 
+	{0x30b, SSD_LOG_LEVEL_NOTICE, SSD_LOG_DATA_HEX,  0, 0, "PCIe link status" }, 
+	{0x30c, SSD_LOG_LEVEL_ERR,    SSD_LOG_DATA_HEX,  0, 0, "Controller reset sync error" }, 
+	{0x30d, SSD_LOG_LEVEL_ERR,    SSD_LOG_DATA_HEX,  0, 0, "Clock fault" }, 
+	{0x30e, SSD_LOG_LEVEL_NOTICE, SSD_LOG_DATA_HEX,  0, 0, "FPGA voltage fault status" }, 
+	{0x30f, SSD_LOG_LEVEL_NOTICE, SSD_LOG_DATA_HEX,  0, 0, "Set capacity finished"}, 
+	{0x310, SSD_LOG_LEVEL_NOTICE, SSD_LOG_DATA_NONE, 0, 0, "Clear data finished"}, 
+	{0x311, SSD_LOG_LEVEL_NOTICE, SSD_LOG_DATA_HEX,  0, 0, "Reset"}, 
+	{0x312, SSD_LOG_LEVEL_WARNING,SSD_LOG_DATA_HEX,  0, 0, "CAP: voltage fault"}, 
+	{0x313, SSD_LOG_LEVEL_WARNING,SSD_LOG_DATA_NONE, 0, 0, "CAP: learn fault"}, 
+	{0x314, SSD_LOG_LEVEL_NOTICE, SSD_LOG_DATA_HEX,  0, 0, "CAP status"}, 
+	{0x315, SSD_LOG_LEVEL_NOTICE, SSD_LOG_DATA_HEX,  0, 0, "Board voltage fault status"}, 
+	{0x316, SSD_LOG_LEVEL_NOTICE, SSD_LOG_DATA_NONE, 0, 0, "Inlet over temperature"}, 
+	{0x317, SSD_LOG_LEVEL_NOTICE, SSD_LOG_DATA_NONE, 0, 0, "Inlet temperature is OK"}, 
+	{0x318, SSD_LOG_LEVEL_NOTICE, SSD_LOG_DATA_NONE, 0, 0, "Flash over temperature"}, 
+	{0x319, SSD_LOG_LEVEL_NOTICE, SSD_LOG_DATA_NONE, 0, 0, "Flash temperature is OK"}, 
+	{0x31a, SSD_LOG_LEVEL_WARNING,SSD_LOG_DATA_NONE, 0, 0, "CAP: short circuit"}, 
+	{0x31b, SSD_LOG_LEVEL_WARNING,SSD_LOG_DATA_HEX,  0, 0, "Sensor fault"}, 
+	{0x31c, SSD_LOG_LEVEL_NOTICE, SSD_LOG_DATA_NONE, 0, 0, "Erase all data"}, 
+	{0x31d, SSD_LOG_LEVEL_NOTICE, SSD_LOG_DATA_NONE, 0, 0, "Erase all data finished"},
+
+	{SSD_UNKNOWN_EVENT, SSD_LOG_LEVEL_NOTICE,  SSD_LOG_DATA_HEX,  0, 0, "unknown event"}, 
+};
+/* */
+#define SSD_LOG_OVER_TEMP		0x90
+#define SSD_LOG_NORMAL_TEMP		0x91
+#define SSD_LOG_WARN_TEMP		0x9a
+#define SSD_LOG_SEU_FAULT		0x93
+#define SSD_LOG_SEU_FAULT1		0x98
+#define SSD_LOG_BATTERY_FAULT	0x92
+#define SSD_LOG_BATTERY_OK		0x99
+#define SSD_LOG_BOARD_VOLT_FAULT	0x9f
+
+/* software log */
+#define SSD_LOG_TIMEOUT			0x300
+#define SSD_LOG_POWER_ON		0x301
+#define SSD_LOG_POWER_OFF		0x302
+#define SSD_LOG_CLEAR_LOG		0x303
+#define SSD_LOG_SET_CAPACITY	0x304
+#define SSD_LOG_CLEAR_DATA		0x305
+#define SSD_LOG_BM_SFSTATUS		0x306
+#define SSD_LOG_EIO				0x307
+#define SSD_LOG_ECMD			0x308
+#define SSD_LOG_SET_WMODE		0x309
+#define SSD_LOG_DDR_INIT_ERR	0x30a
+#define SSD_LOG_PCIE_LINK_STATUS	0x30b
+#define SSD_LOG_CTRL_RST_SYNC	0x30c
+#define SSD_LOG_CLK_FAULT		0x30d
+#define SSD_LOG_VOLT_FAULT		0x30e
+#define SSD_LOG_SET_CAPACITY_END	0x30F
+#define SSD_LOG_CLEAR_DATA_END	0x310
+#define SSD_LOG_RESET			0x311
+#define SSD_LOG_CAP_VOLT_FAULT	0x312
+#define SSD_LOG_CAP_LEARN_FAULT	0x313
+#define SSD_LOG_CAP_STATUS		0x314
+#define SSD_LOG_VOLT_STATUS		0x315
+#define SSD_LOG_INLET_OVER_TEMP	0x316
+#define SSD_LOG_INLET_NORMAL_TEMP	0x317
+#define SSD_LOG_FLASH_OVER_TEMP	0x318
+#define SSD_LOG_FLASH_NORMAL_TEMP	0x319
+#define SSD_LOG_CAP_SHORT_CIRCUIT	0x31a
+#define SSD_LOG_SENSOR_FAULT	0x31b
+#define SSD_LOG_ERASE_ALL		0x31c
+#define SSD_LOG_ERASE_ALL_END	0x31d
+
+
+/* sw log fifo depth */
+#define SSD_LOG_FIFO_SZ		1024
+
+
+/* done queue */
+static DEFINE_PER_CPU(struct list_head, ssd_doneq);
+static DEFINE_PER_CPU(struct tasklet_struct, ssd_tasklet);
+
+
+/* unloading driver */
+static volatile int ssd_exiting = 0;
+
+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,12))
+static struct class_simple *ssd_class;
+#else
+static struct class *ssd_class;
+#endif
+
+static int ssd_cmajor = SSD_CMAJOR;
+
+/* ssd block device major, minors */
+static int ssd_major = SSD_MAJOR;
+static int ssd_major_sl = SSD_MAJOR_SL;
+static int ssd_minors = SSD_MINORS;
+
+/* ssd device list */
+static struct list_head	ssd_list;
+static unsigned long ssd_index_bits[SSD_MAX_DEV / BITS_PER_LONG + 1];
+static unsigned long ssd_index_bits_sl[SSD_MAX_DEV / BITS_PER_LONG + 1];
+static atomic_t ssd_nr;
+
+/* module param */
+enum ssd_drv_mode
+{
+	SSD_DRV_MODE_STANDARD = 0,	/* full */
+	SSD_DRV_MODE_DEBUG = 2,	/* debug */
+	SSD_DRV_MODE_BASE	/* base only */
+};
+
+enum ssd_int_mode
+{
+	SSD_INT_LEGACY = 0, 
+	SSD_INT_MSI, 
+	SSD_INT_MSIX
+};
+
+#if (defined SSD_MSIX)
+#define SSD_INT_MODE_DEFAULT SSD_INT_MSIX
+#elif (defined SSD_MSI)
+#define SSD_INT_MODE_DEFAULT SSD_INT_MSI
+#else
+/* auto select the defaut int mode according to the kernel version*/
+/* suse 11 sp1 irqbalance bug: use msi instead*/
+#if ((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35)) || (defined RHEL_MAJOR && RHEL_MAJOR >= 6) || (defined RHEL_MAJOR && RHEL_MAJOR == 5 && RHEL_MINOR >= 5))
+#define SSD_INT_MODE_DEFAULT SSD_INT_MSIX
+#else
+#define SSD_INT_MODE_DEFAULT SSD_INT_MSI
+#endif
+#endif
+
+static int mode = SSD_DRV_MODE_STANDARD;
+static int status_mask = 0xFF;
+static int int_mode = SSD_INT_MODE_DEFAULT;
+static int threaded_irq = 0;
+static int log_level = SSD_LOG_LEVEL_WARNING;
+static int ot_protect = 1;
+static int wmode = SSD_WMODE_DEFAULT;
+static int finject = 0;
+
+module_param(mode, int, 0);
+module_param(status_mask, int, 0);
+module_param(int_mode, int, 0);
+module_param(threaded_irq, int, 0);
+module_param(log_level, int, 0);
+module_param(ot_protect, int, 0);
+module_param(wmode, int, 0);
+module_param(finject, int, 0);
+
+
+MODULE_PARM_DESC(mode, "driver mode, 0 - standard, 1 - debug, 2 - debug without IO, 3 - basic debug mode");
+MODULE_PARM_DESC(status_mask, "command status mask, 0 - without command error, 0xff - with command error");
+MODULE_PARM_DESC(int_mode, "preferred interrupt mode, 0 - legacy, 1 - msi, 2 - msix");
+MODULE_PARM_DESC(threaded_irq, "threaded irq, 0 - normal irq, 1 - threaded irq");
+MODULE_PARM_DESC(log_level, "log level to display, 0 - info and above, 1 - notice and above, 2 - warning and above, 3 - error only");
+MODULE_PARM_DESC(ot_protect, "over temperature protect, 0 - disable, 1 - enable");
+MODULE_PARM_DESC(wmode, "write mode, 0 - write buffer (with risk for the 6xx firmware), 1 - write buffer ex, 2 - write through, 3 - auto, 4 - default");
+MODULE_PARM_DESC(finject, "enable fault simulation, 0 - off, 1 - on, for debug purpose only");
+
+
+#ifndef MODULE
+static int __init ssd_drv_mode(char *str)
+{
+	mode = (int)simple_strtoul(str, NULL, 0);
+
+	return 1;
+}
+
+static int __init ssd_status_mask(char *str)
+{
+	status_mask = (int)simple_strtoul(str, NULL, 16);
+
+	return 1;
+}
+
+static int __init ssd_int_mode(char *str)
+{
+	int_mode = (int)simple_strtoul(str, NULL, 0);
+
+	return 1;
+}
+
+static int __init ssd_threaded_irq(char *str)
+{
+	threaded_irq = (int)simple_strtoul(str, NULL, 0);
+
+	return 1;
+}
+
+static int __init ssd_log_level(char *str)
+{
+	log_level = (int)simple_strtoul(str, NULL, 0);
+
+	return 1;
+}
+
+static int __init ssd_ot_protect(char *str)
+{
+	ot_protect = (int)simple_strtoul(str, NULL, 0);
+
+	return 1;
+}
+
+static int __init ssd_wmode(char *str)
+{
+	wmode = (int)simple_strtoul(str, NULL, 0);
+
+	return 1;
+}
+
+static int __init ssd_finject(char *str)
+{
+	finject = (int)simple_strtoul(str, NULL, 0);
+
+	return 1;
+}
+
+__setup(MODULE_NAME"_mode=", ssd_drv_mode);
+__setup(MODULE_NAME"_status_mask=", ssd_status_mask);
+__setup(MODULE_NAME"_int_mode=", ssd_int_mode);
+__setup(MODULE_NAME"_threaded_irq=", ssd_threaded_irq);
+__setup(MODULE_NAME"_log_level=", ssd_log_level);
+__setup(MODULE_NAME"_ot_protect=", ssd_ot_protect);
+__setup(MODULE_NAME"_wmode=", ssd_wmode);
+__setup(MODULE_NAME"_finject=", ssd_finject);
+#endif
+
+
+#ifdef CONFIG_PROC_FS
+#include <linux/proc_fs.h>
+#include <asm/uaccess.h>
+
+#define SSD_PROC_DIR	MODULE_NAME
+#define SSD_PROC_INFO	"info"
+
+static struct proc_dir_entry *ssd_proc_dir = NULL;
+static struct proc_dir_entry *ssd_proc_info = NULL;
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,2,0))
+static int ssd_proc_read(char *page, char **start, 
+	off_t off, int count, int *eof, void *data)
+{
+	struct ssd_device *dev = NULL;
+	struct ssd_device *n = NULL;
+	uint64_t size;
+	int idx;
+	int len = 0;
+	//char type; //xx
+
+	if (ssd_exiting) {
+		return 0;
+	}
+
+	len += snprintf((page + len), (count - len), "Driver          Version:\t%s\n", DRIVER_VERSION);
+
+	list_for_each_entry_safe(dev, n, &ssd_list, list) {
+		idx = dev->idx + 1;
+		size = dev->hw_info.size ;
+		do_div(size, 1000000000);
+
+		len += snprintf((page + len), (count - len), "\n");
+
+		len += snprintf((page + len), (count - len), "HIO %d              Size:\t%uGB\n", idx, (uint32_t)size);
+
+		len += snprintf((page + len), (count - len), "HIO %d     Bridge FW VER:\t%03X\n", idx, dev->hw_info.bridge_ver);
+		if (dev->hw_info.ctrl_ver != 0) {
+			len += snprintf((page + len), (count - len), "HIO %d Controller FW VER:\t%03X\n", idx, dev->hw_info.ctrl_ver);
+		}
+
+		len += snprintf((page + len), (count - len), "HIO %d           PCB VER:\t.%c\n", idx, dev->hw_info.pcb_ver);
+
+		if (dev->hw_info.upper_pcb_ver >= 'A') {
+			len += snprintf((page + len), (count - len), "HIO %d     Upper PCB VER:\t.%c\n", idx, dev->hw_info.upper_pcb_ver);
+		}
+
+		len += snprintf((page + len), (count - len), "HIO %d            Device:\t%s\n", idx, dev->name);
+	}
+
+	return len;
+}
+
+#else
+
+static int ssd_proc_show(struct seq_file *m, void *v)
+{
+	struct ssd_device *dev = NULL;
+	struct ssd_device *n = NULL;
+	uint64_t size;
+	int idx;
+
+	if (ssd_exiting) {
+		return 0;
+	}
+
+	seq_printf(m, "Driver          Version:\t%s\n", DRIVER_VERSION);
+
+	list_for_each_entry_safe(dev, n, &ssd_list, list) {
+		idx = dev->idx + 1;
+		size = dev->hw_info.size ;
+		do_div(size, 1000000000);
+
+		seq_printf(m, "\n");
+
+		seq_printf(m, "HIO %d              Size:\t%uGB\n", idx, (uint32_t)size);
+
+		seq_printf(m, "HIO %d     Bridge FW VER:\t%03X\n", idx, dev->hw_info.bridge_ver);
+		if (dev->hw_info.ctrl_ver != 0) {
+			seq_printf(m, "HIO %d Controller FW VER:\t%03X\n", idx, dev->hw_info.ctrl_ver);
+		}
+
+		seq_printf(m, "HIO %d           PCB VER:\t.%c\n", idx, dev->hw_info.pcb_ver);
+
+		if (dev->hw_info.upper_pcb_ver >= 'A') {
+			seq_printf(m, "HIO %d     Upper PCB VER:\t.%c\n", idx, dev->hw_info.upper_pcb_ver);
+		}
+
+		seq_printf(m, "HIO %d            Device:\t%s\n", idx, dev->name);
+	}
+
+	return 0;
+}
+
+static int ssd_proc_open(struct inode *inode, struct file *file)
+{
+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(3,9,0))
+	return single_open(file, ssd_proc_show, PDE(inode)->data);
+#else
+	return single_open(file, ssd_proc_show, PDE_DATA(inode));
+#endif
+}
+
+static const struct file_operations ssd_proc_fops = {
+	.open		= ssd_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+#endif
+
+
+static void ssd_cleanup_proc(void)
+{
+	if (ssd_proc_info) {
+		remove_proc_entry(SSD_PROC_INFO, ssd_proc_dir);
+		ssd_proc_info = NULL;
+	}
+	if (ssd_proc_dir) {
+		remove_proc_entry(SSD_PROC_DIR, NULL);
+		ssd_proc_dir = NULL;
+	}
+}
+static int ssd_init_proc(void)
+{
+	ssd_proc_dir = proc_mkdir(SSD_PROC_DIR, NULL);
+	if (!ssd_proc_dir)
+		goto out_proc_mkdir;
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,2,0))
+	ssd_proc_info = create_proc_entry(SSD_PROC_INFO, S_IFREG | S_IRUGO | S_IWUSR, ssd_proc_dir);
+	if (!ssd_proc_info)
+		goto out_create_proc_entry;
+
+	ssd_proc_info->read_proc = ssd_proc_read;
+
+/* kernel bug */
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,30))
+	ssd_proc_info->owner = THIS_MODULE;
+#endif
+#else
+	ssd_proc_info = proc_create(SSD_PROC_INFO, 0600, ssd_proc_dir, &ssd_proc_fops);
+	if (!ssd_proc_info)
+		goto out_create_proc_entry;
+#endif
+
+	return 0;
+
+out_create_proc_entry:
+	remove_proc_entry(SSD_PROC_DIR, NULL);
+out_proc_mkdir:
+	return -ENOMEM;
+}
+
+#else
+static void ssd_cleanup_proc(void)
+{
+	return;
+}
+static int ssd_init_proc(void)
+{
+	return 0;
+}
+#endif /* CONFIG_PROC_FS */
+
+/* sysfs */
+static void ssd_unregister_sysfs(struct ssd_device *dev)
+{
+	return;
+}
+
+static int ssd_register_sysfs(struct ssd_device *dev)
+{
+	return 0;
+}
+
+static void ssd_cleanup_sysfs(void)
+{
+	return;
+}
+
+static int ssd_init_sysfs(void)
+{
+	return 0;
+}
+
+static inline void ssd_put_index(int slave, int index)
+{
+	unsigned long *index_bits = ssd_index_bits;
+
+	if (slave) {
+		index_bits = ssd_index_bits_sl;
+	}
+
+	if (test_and_clear_bit(index,  index_bits)) {
+		atomic_dec(&ssd_nr);
+	}
+}
+
+static inline int ssd_get_index(int slave)
+{
+	unsigned long *index_bits = ssd_index_bits;
+	int index;
+
+	if (slave) {
+		index_bits = ssd_index_bits_sl;
+	}
+
+find_index:
+	if ((index = find_first_zero_bit(index_bits, SSD_MAX_DEV)) >= SSD_MAX_DEV) {
+			return -1;
+	}
+
+	if (test_and_set_bit(index, index_bits)) {
+		goto find_index;
+	}
+
+	atomic_inc(&ssd_nr);
+
+	return index;
+}
+
+static void ssd_cleanup_index(void)
+{
+	return;
+}
+
+static int ssd_init_index(void)
+{
+	INIT_LIST_HEAD(&ssd_list);
+	atomic_set(&ssd_nr, 0);
+	memset(ssd_index_bits, 0, (SSD_MAX_DEV / BITS_PER_LONG + 1));
+	memset(ssd_index_bits_sl, 0, (SSD_MAX_DEV / BITS_PER_LONG + 1));
+
+	return 0;
+}
+
+static void ssd_set_dev_name(char *name, size_t size, int idx)
+{
+	if(idx < SSD_ALPHABET_NUM) {
+		snprintf(name, size, "%c", 'a'+idx);
+	} else {
+		idx -= SSD_ALPHABET_NUM;
+		snprintf(name, size, "%c%c", 'a'+(idx/SSD_ALPHABET_NUM), 'a'+(idx%SSD_ALPHABET_NUM));
+	}
+}
+
+/* pci register r&w */
+static inline void ssd_reg_write(void *addr, uint64_t val)
+{
+	iowrite32((uint32_t)val, addr);
+	iowrite32((uint32_t)(val >> 32), addr + 4);
+	wmb();
+}
+
+static inline uint64_t ssd_reg_read(void *addr)
+{
+	uint64_t val;
+	uint32_t val_lo, val_hi;
+
+	val_lo = ioread32(addr);
+	val_hi = ioread32(addr + 4);
+
+	rmb();
+	val = val_lo | ((uint64_t)val_hi << 32);
+
+	return val;
+}
+
+
+#define ssd_reg32_write(addr, val)	writel(val, addr)
+#define ssd_reg32_read(addr)		readl(addr)
+
+/* alarm led */
+static void ssd_clear_alarm(struct ssd_device *dev)
+{
+	uint32_t val;
+
+	if (dev->protocol_info.ver <= SSD_PROTOCOL_V3) {
+		return;
+	}
+
+	val = ssd_reg32_read(dev->ctrlp + SSD_LED_REG);
+
+	/* firmware control */
+	val &= ~0x2;
+
+	ssd_reg32_write(dev->ctrlp + SSD_LED_REG, val);
+}
+
+static void ssd_set_alarm(struct ssd_device *dev)
+{
+	uint32_t val;
+
+	if (dev->protocol_info.ver <= SSD_PROTOCOL_V3) {
+		return;
+	}
+
+	val = ssd_reg32_read(dev->ctrlp + SSD_LED_REG);
+
+	/* light up */
+	val &= ~0x1;
+	/* software control */
+	val |= 0x2;
+
+	ssd_reg32_write(dev->ctrlp + SSD_LED_REG, val);
+}
+
+#define u32_swap(x) \
+	((uint32_t)( \
+	(((uint32_t)(x) & (uint32_t)0x000000ffUL) << 24) | \
+	(((uint32_t)(x) & (uint32_t)0x0000ff00UL) <<  8) | \
+	(((uint32_t)(x) & (uint32_t)0x00ff0000UL) >>  8) | \
+	(((uint32_t)(x) & (uint32_t)0xff000000UL) >> 24)))
+
+#define u16_swap(x) \
+	((uint16_t)( \
+	(((uint16_t)(x) & (uint16_t)0x00ff) <<  8) | \
+	(((uint16_t)(x) & (uint16_t)0xff00) >>  8) ))
+
+
+#if 0
+/* No lock, for init only*/
+static int ssd_spi_read_id(struct ssd_device *dev, uint32_t *id)
+{
+	uint32_t val;
+	unsigned long st;
+	int ret = 0;
+
+	if (!dev || !id) {
+		return -EINVAL;
+	}
+
+	ssd_reg32_write(dev->ctrlp + SSD_SPI_REG_CMD, SSD_SPI_CMD_READ_ID);
+
+	val = ssd_reg32_read(dev->ctrlp + SSD_SPI_REG_READY);
+	val = ssd_reg32_read(dev->ctrlp + SSD_SPI_REG_READY);
+	val = ssd_reg32_read(dev->ctrlp + SSD_SPI_REG_READY);
+	val = ssd_reg32_read(dev->ctrlp + SSD_SPI_REG_READY);
+
+	st = jiffies;
+	for (;;) {
+		val = ssd_reg32_read(dev->ctrlp + SSD_SPI_REG_READY);
+		if (val == 0x1000000) {
+			break;
+		}
+
+		if (time_after(jiffies, (st + SSD_SPI_TIMEOUT))) {
+			ret = -ETIMEDOUT;
+			goto out;
+		}
+		cond_resched();
+	}
+
+	val = ssd_reg32_read(dev->ctrlp + SSD_SPI_REG_ID);
+	*id = val;
+
+out:
+	return ret;
+}
+#endif
+
+/* spi access */
+static int ssd_init_spi(struct ssd_device *dev)
+{
+	uint32_t val;
+	unsigned long st;
+	int ret = 0;
+
+	mutex_lock(&dev->spi_mutex);
+	st = jiffies;
+	for(;;) {
+		ssd_reg32_write(dev->ctrlp + SSD_SPI_REG_CMD, SSD_SPI_CMD_READ_STATUS);
+
+		do {
+			val = ssd_reg32_read(dev->ctrlp + SSD_SPI_REG_READY);
+
+			if (time_after(jiffies, (st + SSD_SPI_TIMEOUT))) {
+				ret = -ETIMEDOUT;
+				goto out;
+			}
+			cond_resched();
+		} while (val != 0x1000000);
+
+		val = ssd_reg32_read(dev->ctrlp + SSD_SPI_REG_STATUS);
+		if (!(val & 0x1)) {
+			break;
+		}
+
+		if (time_after(jiffies, (st + SSD_SPI_TIMEOUT))) {
+			ret = -ETIMEDOUT;
+			goto out;
+		}
+		cond_resched();
+	}
+
+out:
+	if (dev->protocol_info.ver >= SSD_PROTOCOL_V3_2) {
+		if (val & 0x1) {
+			ssd_reg32_write(dev->ctrlp + SSD_SPI_REG_CMD, SSD_SPI_CMD_CLSR);
+		}
+	}
+	ssd_reg32_write(dev->ctrlp + SSD_SPI_REG_CMD, SSD_SPI_CMD_W_DISABLE);
+	mutex_unlock(&dev->spi_mutex);
+
+	ret = 0;
+
+	return ret;
+}
+
+static int ssd_spi_page_read(struct ssd_device *dev, void *buf, uint32_t off, uint32_t size)
+{
+	uint32_t val;
+	uint32_t rlen = 0;
+	unsigned long st;
+	int ret = 0;
+
+	if (!dev || !buf) {
+		return -EINVAL;
+	}
+
+	if ((off % sizeof(uint32_t)) != 0 || (size % sizeof(uint32_t)) != 0 || size == 0 || 
+		((uint64_t)off + (uint64_t)size) > dev->rom_info.size || size > dev->rom_info.page_size) {
+		return -EINVAL;
+	}
+
+	mutex_lock(&dev->spi_mutex);
+	while (rlen < size) {
+		ssd_reg32_write(dev->ctrlp + SSD_SPI_REG_CMD_HI, ((off + rlen) >> 24));
+		wmb();
+		ssd_reg32_write(dev->ctrlp + SSD_SPI_REG_CMD, (((off + rlen) << 8) | SSD_SPI_CMD_READ));
+
+		(void)ssd_reg32_read(dev->ctrlp + SSD_SPI_REG_READY);
+		(void)ssd_reg32_read(dev->ctrlp + SSD_SPI_REG_READY);
+		(void)ssd_reg32_read(dev->ctrlp + SSD_SPI_REG_READY);
+		(void)ssd_reg32_read(dev->ctrlp + SSD_SPI_REG_READY);
+
+		st = jiffies;
+		for (;;) {
+			val = ssd_reg32_read(dev->ctrlp + SSD_SPI_REG_READY);
+			if (val == 0x1000000) {
+				break;
+			}
+
+			if (time_after(jiffies, (st + SSD_SPI_TIMEOUT))) {
+				ret = -ETIMEDOUT;
+				goto out;
+			}
+			cond_resched();
+		}
+
+		val = ssd_reg32_read(dev->ctrlp + SSD_SPI_REG_RDATA);
+		*(uint32_t *)(buf + rlen)= u32_swap(val);
+
+		rlen += sizeof(uint32_t);
+	}
+
+out:
+	mutex_unlock(&dev->spi_mutex);
+	return ret;
+}
+
+static int ssd_spi_page_write(struct ssd_device *dev, void *buf, uint32_t off, uint32_t size)
+{
+	uint32_t val;
+	uint32_t wlen;
+	unsigned long st;
+	int i;
+	int ret = 0;
+
+	if (!dev || !buf) {
+		return -EINVAL;
+	}
+
+	if ((off % sizeof(uint32_t)) != 0 || (size % sizeof(uint32_t)) != 0 || size == 0 || 
+		((uint64_t)off + (uint64_t)size) > dev->rom_info.size || size > dev->rom_info.page_size || 
+		(off / dev->rom_info.page_size) !=  ((off + size - 1) / dev->rom_info.page_size)) {
+		return -EINVAL;
+	}
+
+	mutex_lock(&dev->spi_mutex);
+
+	ssd_reg32_write(dev->ctrlp + SSD_SPI_REG_CMD, SSD_SPI_CMD_W_ENABLE);
+
+	wlen = size / sizeof(uint32_t);
+	for (i=0; i<(int)wlen; i++) {
+		ssd_reg32_write(dev->ctrlp + SSD_SPI_REG_WDATA, u32_swap(*((uint32_t *)buf + i)));
+	}
+
+	wmb();
+	ssd_reg32_write(dev->ctrlp + SSD_SPI_REG_CMD_HI, (off >> 24));
+	wmb();
+	ssd_reg32_write(dev->ctrlp + SSD_SPI_REG_CMD, ((off << 8) | SSD_SPI_CMD_PROGRAM));
+
+	udelay(1);
+
+	st = jiffies;
+	for (;;) {
+		ssd_reg32_write(dev->ctrlp + SSD_SPI_REG_CMD, SSD_SPI_CMD_READ_STATUS);
+		do {
+			val = ssd_reg32_read(dev->ctrlp + SSD_SPI_REG_READY);
+
+			if (time_after(jiffies, (st + SSD_SPI_TIMEOUT))) {
+				ret = -ETIMEDOUT;
+				goto out;
+			}
+			cond_resched();
+		} while (val != 0x1000000);
+
+		val = ssd_reg32_read(dev->ctrlp + SSD_SPI_REG_STATUS);
+		if (!(val & 0x1)) {
+			break;
+		}
+
+		if (time_after(jiffies, (st + SSD_SPI_TIMEOUT))) {
+			ret = -ETIMEDOUT;
+			goto out;
+		}
+		cond_resched();
+	}
+
+	if (dev->protocol_info.ver >= SSD_PROTOCOL_V3_2) {
+		if ((val >> 6) & 0x1) {
+			ret = -EIO;
+			goto out;
+		}
+	}
+
+out:
+	if (dev->protocol_info.ver >= SSD_PROTOCOL_V3_2) {
+		if (val & 0x1) {
+			ssd_reg32_write(dev->ctrlp + SSD_SPI_REG_CMD, SSD_SPI_CMD_CLSR);
+		}
+	}
+	ssd_reg32_write(dev->ctrlp + SSD_SPI_REG_CMD, SSD_SPI_CMD_W_DISABLE);
+
+	mutex_unlock(&dev->spi_mutex);
+
+	return ret;
+}
+
+static int ssd_spi_block_erase(struct ssd_device *dev, uint32_t off)
+{
+	uint32_t val;
+	unsigned long st;
+	int ret = 0;
+
+	if (!dev) {
+		return -EINVAL;
+	}
+
+	if ((off % dev->rom_info.block_size) != 0 || off >= dev->rom_info.size) {
+		return -EINVAL;
+	}
+
+	mutex_lock(&dev->spi_mutex);
+
+	ssd_reg32_write(dev->ctrlp + SSD_SPI_REG_CMD, SSD_SPI_CMD_W_ENABLE);
+	ssd_reg32_write(dev->ctrlp + SSD_SPI_REG_CMD, SSD_SPI_CMD_W_ENABLE);
+
+	wmb();
+	ssd_reg32_write(dev->ctrlp + SSD_SPI_REG_CMD_HI, (off >> 24));
+	wmb();
+	ssd_reg32_write(dev->ctrlp + SSD_SPI_REG_CMD, ((off << 8) | SSD_SPI_CMD_ERASE));
+
+	st = jiffies;
+	for (;;) {
+		ssd_reg32_write(dev->ctrlp + SSD_SPI_REG_CMD, SSD_SPI_CMD_READ_STATUS);
+
+		do {
+			val = ssd_reg32_read(dev->ctrlp + SSD_SPI_REG_READY);
+
+			if (time_after(jiffies, (st + SSD_SPI_TIMEOUT))) {
+				ret = -ETIMEDOUT;
+				goto out;
+			}
+			cond_resched();
+		} while (val != 0x1000000);
+
+		val = ssd_reg32_read(dev->ctrlp + SSD_SPI_REG_STATUS);
+		if (!(val & 0x1)) {
+			break;
+		}
+
+		if (time_after(jiffies, (st + SSD_SPI_TIMEOUT))) {
+			ret = -ETIMEDOUT;
+			goto out;
+		}
+		cond_resched();
+	}
+
+	if (dev->protocol_info.ver >= SSD_PROTOCOL_V3_2) {
+		if ((val >> 5) & 0x1) {
+			ret = -EIO;
+			goto out;
+		}
+	}
+
+out:
+	if (dev->protocol_info.ver >= SSD_PROTOCOL_V3_2) {
+		if (val & 0x1) {
+			ssd_reg32_write(dev->ctrlp + SSD_SPI_REG_CMD, SSD_SPI_CMD_CLSR);
+		}
+	}
+	ssd_reg32_write(dev->ctrlp + SSD_SPI_REG_CMD, SSD_SPI_CMD_W_DISABLE);
+
+	mutex_unlock(&dev->spi_mutex);
+
+	return ret;
+}
+
+static int ssd_spi_read(struct ssd_device *dev, void *buf, uint32_t off, uint32_t size)
+{
+	uint32_t len = 0;
+	uint32_t roff;
+	uint32_t rsize;
+	int ret = 0;
+
+	if (!dev || !buf) {
+		return -EINVAL;
+	}
+
+	if ((off % sizeof(uint32_t)) != 0 || (size % sizeof(uint32_t)) != 0 || size == 0 || 
+		((uint64_t)off + (uint64_t)size) > dev->rom_info.size) {
+		return -EINVAL;
+	}
+
+	while (len < size) {
+		roff = (off + len) % dev->rom_info.page_size;
+		rsize = dev->rom_info.page_size - roff;
+		if ((size - len) < rsize) {
+			rsize = (size - len);
+		}
+		roff = off + len;
+
+		ret = ssd_spi_page_read(dev, (buf + len), roff, rsize);
+		if (ret) {
+			goto out;
+		}
+
+		len += rsize;
+
+		cond_resched();
+	}
+
+out:
+	return ret;
+}
+
+static int ssd_spi_write(struct ssd_device *dev, void *buf, uint32_t off, uint32_t size)
+{
+	uint32_t len = 0;
+	uint32_t woff;
+	uint32_t wsize;
+	int ret = 0;
+
+	if (!dev || !buf) {
+		return -EINVAL;
+	}
+
+	if ((off % sizeof(uint32_t)) != 0 || (size % sizeof(uint32_t)) != 0 || size == 0 || 
+		((uint64_t)off + (uint64_t)size) > dev->rom_info.size) {
+		return -EINVAL;
+	}
+
+	while (len < size) {
+		woff = (off + len) % dev->rom_info.page_size;
+		wsize = dev->rom_info.page_size - woff;
+		if ((size - len) < wsize) {
+			wsize = (size - len);
+		}
+		woff = off + len;
+
+		ret = ssd_spi_page_write(dev, (buf + len), woff, wsize);
+		if (ret) {
+			goto out;
+		}
+
+		len += wsize;
+
+		cond_resched();
+	}
+
+out:
+	return ret;
+}
+
+static int ssd_spi_erase(struct ssd_device *dev, uint32_t off, uint32_t size)
+{
+	uint32_t len = 0;
+	uint32_t eoff;
+	int ret = 0;
+
+	if (!dev) {
+		return -EINVAL;
+	}
+
+	if (size == 0 || ((uint64_t)off + (uint64_t)size) > dev->rom_info.size ||
+		(off % dev->rom_info.block_size) != 0 || (size % dev->rom_info.block_size) != 0) {
+		return -EINVAL;
+	}
+
+	while (len < size) {
+		eoff = (off + len);
+
+		ret = ssd_spi_block_erase(dev, eoff);
+		if (ret) {
+			goto out;
+		}
+
+		len += dev->rom_info.block_size;
+
+		cond_resched();
+	}
+
+out:
+	return ret;
+}
+
+/* i2c access */
+static uint32_t __ssd_i2c_reg32_read(void *addr)
+{
+	return ssd_reg32_read(addr);
+}
+
+static void __ssd_i2c_reg32_write(void *addr, uint32_t val)
+{
+	ssd_reg32_write(addr, val);
+	ssd_reg32_read(addr);
+}
+
+static int __ssd_i2c_clear(struct ssd_device *dev, uint8_t saddr)
+{
+	ssd_i2c_ctrl_t ctrl;
+	ssd_i2c_data_t data;
+	uint8_t status = 0;
+	int nr_data = 0;
+	unsigned long st;
+	int ret = 0;
+
+check_status:
+	ctrl.bits.wdata	= 0;
+	ctrl.bits.addr	= SSD_I2C_STATUS_REG;
+	ctrl.bits.rw 	= SSD_I2C_CTRL_READ;
+	__ssd_i2c_reg32_write(dev->ctrlp + SSD_I2C_CTRL_REG, ctrl.val);
+
+	st = jiffies;
+	for (;;) {
+		data.val = __ssd_i2c_reg32_read(dev->ctrlp + SSD_I2C_RDATA_REG);
+		if (data.bits.valid == 0) {
+			break;
+		}
+
+		/* retry */
+		if (time_after(jiffies, (st + SSD_I2C_TIMEOUT))) {
+			ret = -ETIMEDOUT;
+			goto out;
+		}
+		cond_resched();
+	}
+	status = data.bits.rdata;
+
+	if (!(status & 0x4)) {
+		/* clear read fifo data */
+		ctrl.bits.wdata	= 0;
+		ctrl.bits.addr	= SSD_I2C_DATA_REG;
+		ctrl.bits.rw 	= SSD_I2C_CTRL_READ;
+		__ssd_i2c_reg32_write(dev->ctrlp + SSD_I2C_CTRL_REG, ctrl.val);
+
+		st = jiffies;
+		for (;;) {
+			data.val = __ssd_i2c_reg32_read(dev->ctrlp + SSD_I2C_RDATA_REG);
+			if (data.bits.valid == 0) {
+				break;
+			}
+
+			/* retry */
+			if (time_after(jiffies, (st + SSD_I2C_TIMEOUT))) {
+				ret = -ETIMEDOUT;
+				goto out;
+			}
+			cond_resched();
+		}
+
+		nr_data++;
+		if (nr_data <= SSD_I2C_MAX_DATA) {
+			goto check_status;
+		} else {
+			goto out_reset;
+		}
+	}
+
+	if (status & 0x3) {
+		/* clear int */
+		ctrl.bits.wdata	= 0x04;
+		ctrl.bits.addr	= SSD_I2C_CMD_REG;
+		ctrl.bits.rw 	= SSD_I2C_CTRL_WRITE;
+		__ssd_i2c_reg32_write(dev->ctrlp + SSD_I2C_CTRL_REG, ctrl.val);
+	}
+
+	if (!(status & 0x8)) {
+out_reset:
+		/* reset i2c controller */
+		ctrl.bits.wdata	= 0x0;
+		ctrl.bits.addr	= SSD_I2C_RESET_REG;
+		ctrl.bits.rw 	= SSD_I2C_CTRL_WRITE;
+		__ssd_i2c_reg32_write(dev->ctrlp + SSD_I2C_CTRL_REG, ctrl.val);
+	}
+
+out:
+	return ret;
+}
+
+static int ssd_i2c_write(struct ssd_device *dev, uint8_t saddr, uint8_t size, uint8_t *buf)
+{
+	ssd_i2c_ctrl_t ctrl;
+	ssd_i2c_data_t data;
+	uint8_t off = 0;
+	uint8_t status = 0;
+	unsigned long st;
+	int ret = 0;
+
+	mutex_lock(&dev->i2c_mutex);
+
+	ctrl.val = 0;
+
+	/* slave addr */
+	ctrl.bits.wdata	= saddr;
+	ctrl.bits.addr	= SSD_I2C_SADDR_REG;
+	ctrl.bits.rw 	= SSD_I2C_CTRL_WRITE;
+	__ssd_i2c_reg32_write(dev->ctrlp + SSD_I2C_CTRL_REG, ctrl.val);
+
+	/* data */
+	while (off < size) {
+		ctrl.bits.wdata	= buf[off];
+		ctrl.bits.addr	= SSD_I2C_DATA_REG;
+		ctrl.bits.rw 	= SSD_I2C_CTRL_WRITE;
+		__ssd_i2c_reg32_write(dev->ctrlp + SSD_I2C_CTRL_REG, ctrl.val);
+
+		off++;
+	}
+
+	/* write */
+	ctrl.bits.wdata	= 0x01;
+	ctrl.bits.addr	= SSD_I2C_CMD_REG;
+	ctrl.bits.rw 	= SSD_I2C_CTRL_WRITE;
+	__ssd_i2c_reg32_write(dev->ctrlp + SSD_I2C_CTRL_REG, ctrl.val);
+
+	/* wait */
+	st = jiffies;
+	for (;;) {
+		ctrl.bits.wdata	= 0;
+		ctrl.bits.addr	= SSD_I2C_STATUS_REG;
+		ctrl.bits.rw 	= SSD_I2C_CTRL_READ;
+		__ssd_i2c_reg32_write(dev->ctrlp + SSD_I2C_CTRL_REG, ctrl.val);
+
+		for (;;) {
+			data.val = __ssd_i2c_reg32_read(dev->ctrlp + SSD_I2C_RDATA_REG);
+			if (data.bits.valid == 0) {
+				break;
+			}
+
+			/* retry */
+			if (time_after(jiffies, (st + SSD_I2C_TIMEOUT))) {
+				ret = -ETIMEDOUT;
+				goto out_clear;
+			}
+			cond_resched();
+		}
+
+		status = data.bits.rdata;
+		if (status & 0x1) {
+			break;
+		}
+
+		if (time_after(jiffies, (st + SSD_I2C_TIMEOUT))) {
+			ret = -ETIMEDOUT;
+			goto out_clear;
+		}
+		cond_resched();
+	}
+
+	if (!(status & 0x1)) {
+		ret =  -1;
+		goto out_clear;
+	}
+
+	/* busy ? */
+	if (status & 0x20) {
+		ret =  -2;
+		goto out_clear;
+	}
+
+	/* ack ? */
+	if (status & 0x10) {
+		ret =  -3;
+		goto out_clear;
+	}
+
+	/* clear */
+out_clear:
+	if (__ssd_i2c_clear(dev, saddr)) {
+		if (!ret) ret = -4;
+	}
+
+	mutex_unlock(&dev->i2c_mutex);
+
+	return ret;
+}
+
+static int ssd_i2c_read(struct ssd_device *dev, uint8_t saddr, uint8_t size, uint8_t *buf)
+{
+	ssd_i2c_ctrl_t ctrl;
+	ssd_i2c_data_t data;
+	uint8_t off = 0;
+	uint8_t status = 0;
+	unsigned long st;
+	int ret = 0;
+
+	mutex_lock(&dev->i2c_mutex);
+
+	ctrl.val = 0;
+
+	/* slave addr */
+	ctrl.bits.wdata	= saddr;
+	ctrl.bits.addr	= SSD_I2C_SADDR_REG;
+	ctrl.bits.rw 	= SSD_I2C_CTRL_WRITE;
+	__ssd_i2c_reg32_write(dev->ctrlp + SSD_I2C_CTRL_REG, ctrl.val);
+
+	/* read len */
+	ctrl.bits.wdata	= size;
+	ctrl.bits.addr	= SSD_I2C_LEN_REG;
+	ctrl.bits.rw 	= SSD_I2C_CTRL_WRITE;
+	__ssd_i2c_reg32_write(dev->ctrlp + SSD_I2C_CTRL_REG, ctrl.val);
+
+	/* read */
+	ctrl.bits.wdata	= 0x02;
+	ctrl.bits.addr	= SSD_I2C_CMD_REG;
+	ctrl.bits.rw 	= SSD_I2C_CTRL_WRITE;
+	__ssd_i2c_reg32_write(dev->ctrlp + SSD_I2C_CTRL_REG, ctrl.val);
+
+	/* wait */
+	st = jiffies;
+	for (;;) {
+		ctrl.bits.wdata	= 0;
+		ctrl.bits.addr	= SSD_I2C_STATUS_REG;
+		ctrl.bits.rw 	= SSD_I2C_CTRL_READ;
+		__ssd_i2c_reg32_write(dev->ctrlp + SSD_I2C_CTRL_REG, ctrl.val);
+
+		for (;;) {
+			data.val = __ssd_i2c_reg32_read(dev->ctrlp + SSD_I2C_RDATA_REG);
+			if (data.bits.valid == 0) {
+				break;
+			}
+
+			/* retry */
+			if (time_after(jiffies, (st + SSD_I2C_TIMEOUT))) {
+				ret = -ETIMEDOUT;
+				goto out_clear;
+			}
+			cond_resched();
+		}
+
+		status = data.bits.rdata;
+		if (status & 0x2) {
+			break;
+		}
+
+		if (time_after(jiffies, (st + SSD_I2C_TIMEOUT))) {
+			ret = -ETIMEDOUT;
+			goto out_clear;
+		}
+		cond_resched();
+	}
+
+	if (!(status & 0x2)) {
+		ret =  -1;
+		goto out_clear;
+	}
+
+	/* busy ? */
+	if (status & 0x20) {
+		ret =  -2;
+		goto out_clear;
+	}
+
+	/* ack ? */
+	if (status & 0x10) {
+		ret =  -3;
+		goto out_clear;
+	}
+
+	/* data */
+	while (off < size) {
+		ctrl.bits.wdata	= 0;
+		ctrl.bits.addr	= SSD_I2C_DATA_REG;
+		ctrl.bits.rw 	= SSD_I2C_CTRL_READ;
+		__ssd_i2c_reg32_write(dev->ctrlp + SSD_I2C_CTRL_REG, ctrl.val);
+
+		st = jiffies;
+		for (;;) {
+			data.val = __ssd_i2c_reg32_read(dev->ctrlp + SSD_I2C_RDATA_REG);
+			if (data.bits.valid == 0) {
+				break;
+			}
+
+			/* retry */
+			if (time_after(jiffies, (st + SSD_I2C_TIMEOUT))) {
+				ret = -ETIMEDOUT;
+				goto out_clear;
+			}
+			cond_resched();
+		}
+
+		buf[off] = data.bits.rdata;
+
+		off++;
+	}
+
+	/* clear */
+out_clear:
+	if (__ssd_i2c_clear(dev, saddr)) {
+		if (!ret) ret = -4;
+	}
+
+	mutex_unlock(&dev->i2c_mutex);
+
+	return ret;
+}
+
+static int ssd_i2c_write_read(struct ssd_device *dev, uint8_t saddr, uint8_t wsize, uint8_t *wbuf, uint8_t rsize, uint8_t *rbuf)
+{
+	ssd_i2c_ctrl_t ctrl;
+	ssd_i2c_data_t data;
+	uint8_t off = 0;
+	uint8_t status = 0;
+	unsigned long st;
+	int ret = 0;
+
+	mutex_lock(&dev->i2c_mutex);
+
+	ctrl.val = 0;
+
+	/* slave addr */
+	ctrl.bits.wdata	= saddr;
+	ctrl.bits.addr	= SSD_I2C_SADDR_REG;
+	ctrl.bits.rw 	= SSD_I2C_CTRL_WRITE;
+	__ssd_i2c_reg32_write(dev->ctrlp + SSD_I2C_CTRL_REG, ctrl.val);
+
+	/* data */
+	off = 0;
+	while (off < wsize) {
+		ctrl.bits.wdata	= wbuf[off];
+		ctrl.bits.addr	= SSD_I2C_DATA_REG;
+		ctrl.bits.rw 	= SSD_I2C_CTRL_WRITE;
+		__ssd_i2c_reg32_write(dev->ctrlp + SSD_I2C_CTRL_REG, ctrl.val);
+
+		off++;
+	}
+
+	/* read len */
+	ctrl.bits.wdata	= rsize;
+	ctrl.bits.addr	= SSD_I2C_LEN_REG;
+	ctrl.bits.rw 	= SSD_I2C_CTRL_WRITE;
+	__ssd_i2c_reg32_write(dev->ctrlp + SSD_I2C_CTRL_REG, ctrl.val);
+
+	/* write -> read */
+	ctrl.bits.wdata	= 0x03;
+	ctrl.bits.addr	= SSD_I2C_CMD_REG;
+	ctrl.bits.rw 	= SSD_I2C_CTRL_WRITE;
+	__ssd_i2c_reg32_write(dev->ctrlp + SSD_I2C_CTRL_REG, ctrl.val);
+
+	/* wait */
+	st = jiffies;
+	for (;;) {
+		ctrl.bits.wdata	= 0;
+		ctrl.bits.addr	= SSD_I2C_STATUS_REG;
+		ctrl.bits.rw 	= SSD_I2C_CTRL_READ;
+		__ssd_i2c_reg32_write(dev->ctrlp + SSD_I2C_CTRL_REG, ctrl.val);
+
+		for (;;) {
+			data.val = __ssd_i2c_reg32_read(dev->ctrlp + SSD_I2C_RDATA_REG);
+			if (data.bits.valid == 0) {
+				break;
+			}
+
+			/* retry */
+			if (time_after(jiffies, (st + SSD_I2C_TIMEOUT))) {
+				ret = -ETIMEDOUT;
+				goto out_clear;
+			}
+			cond_resched();
+		}
+
+		status = data.bits.rdata;
+		if (status & 0x2) {
+			break;
+		}
+
+		if (time_after(jiffies, (st + SSD_I2C_TIMEOUT))) {
+			ret = -ETIMEDOUT;
+			goto out_clear;
+		}
+		cond_resched();
+	}
+
+	if (!(status & 0x2)) {
+		ret =  -1;
+		goto out_clear;
+	}
+
+	/* busy ? */
+	if (status & 0x20) {
+		ret =  -2;
+		goto out_clear;
+	}
+
+	/* ack ? */
+	if (status & 0x10) {
+		ret =  -3;
+		goto out_clear;
+	}
+
+	/* data */
+	off = 0;
+	while (off < rsize) {
+		ctrl.bits.wdata	= 0;
+		ctrl.bits.addr	= SSD_I2C_DATA_REG;
+		ctrl.bits.rw 	= SSD_I2C_CTRL_READ;
+		__ssd_i2c_reg32_write(dev->ctrlp + SSD_I2C_CTRL_REG, ctrl.val);
+
+		st = jiffies;
+		for (;;) {
+			data.val = __ssd_i2c_reg32_read(dev->ctrlp + SSD_I2C_RDATA_REG);
+			if (data.bits.valid == 0) {
+				break;
+			}
+
+			/* retry */
+			if (time_after(jiffies, (st + SSD_I2C_TIMEOUT))) {
+				ret = -ETIMEDOUT;
+				goto out_clear;
+			}
+			cond_resched();
+		}
+
+		rbuf[off] = data.bits.rdata;
+
+		off++;
+	}
+
+	/* clear */
+out_clear:
+	if (__ssd_i2c_clear(dev, saddr)) {
+		if (!ret) ret = -4;
+	}
+	mutex_unlock(&dev->i2c_mutex);
+
+	return ret;
+}
+
+static int ssd_smbus_send_byte(struct ssd_device *dev, uint8_t saddr, uint8_t *buf)
+{
+	int i = 0;
+	int ret = 0;
+
+	for (;;) {
+		ret = ssd_i2c_write(dev, saddr, 1, buf);
+		if (!ret || -ETIMEDOUT == ret) {
+			break;
+		}
+
+		i++;
+		if (i >= SSD_SMBUS_RETRY_MAX) {
+			break;
+		}
+		msleep(SSD_SMBUS_RETRY_INTERVAL);
+	}
+
+	return ret;
+}
+
+static int ssd_smbus_receive_byte(struct ssd_device *dev, uint8_t saddr, uint8_t *buf)
+{
+	int i = 0;
+	int ret = 0;
+
+	for (;;) {
+		ret = ssd_i2c_read(dev, saddr, 1, buf);
+		if (!ret || -ETIMEDOUT == ret) {
+			break;
+		}
+
+		i++;
+		if (i >= SSD_SMBUS_RETRY_MAX) {
+			break;
+		}
+		msleep(SSD_SMBUS_RETRY_INTERVAL);
+	}
+
+	return ret;
+}
+
+static int ssd_smbus_write_byte(struct ssd_device *dev, uint8_t saddr, uint8_t cmd, uint8_t *buf)
+{
+	uint8_t smb_data[SSD_SMBUS_DATA_MAX] = {0};
+	int i = 0;
+	int ret = 0;
+
+	smb_data[0] = cmd;
+	memcpy((smb_data + 1), buf, 1);
+
+	for (;;) {
+		ret = ssd_i2c_write(dev, saddr, 2, smb_data);
+		if (!ret || -ETIMEDOUT == ret) {
+			break;
+		}
+
+		i++;
+		if (i >= SSD_SMBUS_RETRY_MAX) {
+			break;
+		}
+		msleep(SSD_SMBUS_RETRY_INTERVAL);
+	}
+
+	return ret;
+}
+
+static int ssd_smbus_read_byte(struct ssd_device *dev, uint8_t saddr, uint8_t cmd, uint8_t *buf)
+{
+	uint8_t smb_data[SSD_SMBUS_DATA_MAX] = {0};
+	int i = 0;
+	int ret = 0;
+
+	smb_data[0] = cmd;
+
+	for (;;) {
+		ret = ssd_i2c_write_read(dev, saddr, 1, smb_data, 1, buf);
+		if (!ret || -ETIMEDOUT == ret) {
+			break;
+		}
+
+		i++;
+		if (i >= SSD_SMBUS_RETRY_MAX) {
+			break;
+		}
+		msleep(SSD_SMBUS_RETRY_INTERVAL);
+	}
+
+	return ret;
+}
+
+static int ssd_smbus_write_word(struct ssd_device *dev, uint8_t saddr, uint8_t cmd, uint8_t *buf)
+{
+	uint8_t smb_data[SSD_SMBUS_DATA_MAX] = {0};
+	int i = 0;
+	int ret = 0;
+
+	smb_data[0] = cmd;
+	memcpy((smb_data + 1), buf, 2);
+
+	for (;;) {
+		ret = ssd_i2c_write(dev, saddr, 3, smb_data);
+		if (!ret || -ETIMEDOUT == ret) {
+			break;
+		}
+
+		i++;
+		if (i >= SSD_SMBUS_RETRY_MAX) {
+			break;
+		}
+		msleep(SSD_SMBUS_RETRY_INTERVAL);
+	}
+
+	return ret;
+}
+
+static int ssd_smbus_read_word(struct ssd_device *dev, uint8_t saddr, uint8_t cmd, uint8_t *buf)
+{
+	uint8_t smb_data[SSD_SMBUS_DATA_MAX] = {0};
+	int i = 0;
+	int ret = 0;
+
+	smb_data[0] = cmd;
+
+	for (;;) {
+		ret = ssd_i2c_write_read(dev, saddr, 1, smb_data, 2, buf);
+		if (!ret || -ETIMEDOUT == ret) {
+			break;
+		}
+
+		i++;
+		if (i >= SSD_SMBUS_RETRY_MAX) {
+			break;
+		}
+		msleep(SSD_SMBUS_RETRY_INTERVAL);
+	}
+
+	return ret;
+}
+
+static int ssd_smbus_write_block(struct ssd_device *dev, uint8_t saddr, uint8_t cmd, uint8_t size, uint8_t *buf)
+{
+	uint8_t smb_data[SSD_SMBUS_DATA_MAX] = {0};
+	int i = 0;
+	int ret = 0;
+
+	smb_data[0] = cmd;
+	smb_data[1] = size;
+	memcpy((smb_data + 2), buf, size);
+
+	for (;;) {
+		ret = ssd_i2c_write(dev, saddr, (2 + size), smb_data);
+		if (!ret || -ETIMEDOUT == ret) {
+			break;
+		}
+
+		i++;
+		if (i >= SSD_SMBUS_RETRY_MAX) {
+			break;
+		}
+		msleep(SSD_SMBUS_RETRY_INTERVAL);
+	}
+
+	return ret;
+}
+
+static int ssd_smbus_read_block(struct ssd_device *dev, uint8_t saddr, uint8_t cmd, uint8_t size, uint8_t *buf)
+{
+	uint8_t smb_data[SSD_SMBUS_DATA_MAX] = {0};
+	uint8_t rsize;
+	int i = 0;
+	int ret = 0;
+
+	smb_data[0] = cmd;
+
+	for (;;) {
+		ret = ssd_i2c_write_read(dev, saddr, 1, smb_data, (SSD_SMBUS_BLOCK_MAX + 1), (smb_data + 1));
+		if (!ret || -ETIMEDOUT == ret) {
+			break;
+		}
+
+		i++;
+		if (i >= SSD_SMBUS_RETRY_MAX) {
+			break;
+		}
+		msleep(SSD_SMBUS_RETRY_INTERVAL);
+	}
+	if (ret) {
+		return ret;
+	}
+
+	rsize = smb_data[1];
+
+	if (rsize > size ) {
+		rsize = size;
+	}
+
+	memcpy(buf, (smb_data + 2), rsize);
+
+	return 0;
+}
+
+
+static int ssd_gen_swlog(struct ssd_device *dev, uint16_t event, uint32_t data);
+
+/* sensor */
+static int ssd_init_lm75(struct ssd_device *dev, uint8_t saddr)
+{
+	uint8_t conf = 0;
+	int ret = 0;
+
+	ret = ssd_smbus_read_byte(dev, saddr, SSD_LM75_REG_CONF, &conf);
+	if (ret) {
+		goto out;
+	}
+
+	conf &= (uint8_t)(~1u);
+
+	ret = ssd_smbus_write_byte(dev, saddr, SSD_LM75_REG_CONF, &conf);
+	if (ret) {
+		goto out;
+	}
+
+out:
+	return ret;
+}
+
+static int ssd_lm75_read(struct ssd_device *dev, uint8_t saddr, uint16_t *data)
+{
+	uint16_t val = 0;
+	int ret;
+
+	ret = ssd_smbus_read_word(dev, saddr, SSD_LM75_REG_TEMP, (uint8_t *)&val);
+	if (ret) {
+		return ret;
+	}
+
+	*data = u16_swap(val);
+
+	return 0;
+}
+
+static int ssd_init_lm80(struct ssd_device *dev, uint8_t saddr)
+{
+	uint8_t val;
+	uint8_t low, high;
+	int i;
+	int ret = 0;
+
+	/* init */
+	val = 0x80;
+	ret = ssd_smbus_write_byte(dev, saddr, SSD_LM80_REG_CONFIG, &val);
+	if (ret) {
+		goto out;
+	}
+
+	/* 11-bit temp */
+	val = 0x08;
+	ret = ssd_smbus_write_byte(dev, saddr, SSD_LM80_REG_RES, &val);
+	if (ret) {
+		goto out;
+	}
+
+	/* set volt limit */
+	for (i=0; i<SSD_LM80_IN_NR; i++) {
+		high = ssd_lm80_limit[i].high;
+		low = ssd_lm80_limit[i].low;
+
+		if (SSD_LM80_IN_CAP == i) {
+			low = 0;
+		}
+
+		if (dev->hw_info.nr_ctrl <= 1 && SSD_LM80_IN_1V2 == i) {
+			high = 0xFF;
+			low = 0;
+		}
+
+		/* high limit */
+		ret = ssd_smbus_write_byte(dev, saddr, SSD_LM80_REG_IN_MAX(i), &high);
+		if (ret) {
+			goto out;
+		}
+
+		/* low limit*/
+		ret = ssd_smbus_write_byte(dev, saddr, SSD_LM80_REG_IN_MIN(i), &low);
+		if (ret) {
+			goto out;
+		}
+	}
+
+	/* set interrupt mask: allow volt in interrupt except cap in*/
+	val = 0x81;
+	ret = ssd_smbus_write_byte(dev, saddr, SSD_LM80_REG_MASK1, &val);
+	if (ret) {
+		goto out;
+	}
+
+	/* set interrupt mask: disable others */
+	val = 0xFF;
+	ret = ssd_smbus_write_byte(dev, saddr, SSD_LM80_REG_MASK2, &val);
+	if (ret) {
+		goto out;
+	}
+
+	/* start */
+	val = 0x03;
+	ret = ssd_smbus_write_byte(dev, saddr, SSD_LM80_REG_CONFIG, &val);
+	if (ret) {
+		goto out;
+	}
+
+out:
+	return ret;
+}
+
+static int ssd_lm80_enable_in(struct ssd_device *dev, uint8_t saddr, int idx)
+{
+	uint8_t val = 0;
+	int ret = 0;
+
+	if (idx >= SSD_LM80_IN_NR || idx < 0) {
+		return -EINVAL;
+	}
+
+	ret = ssd_smbus_read_byte(dev, saddr, SSD_LM80_REG_MASK1, &val);
+	if (ret) {
+		goto out;
+	}
+
+	val &= ~(1UL << (uint32_t)idx);
+
+	ret = ssd_smbus_write_byte(dev, saddr, SSD_LM80_REG_MASK1, &val);
+	if (ret) {
+		goto out;
+	}
+
+out:
+	return ret;
+}
+
+static int ssd_lm80_disable_in(struct ssd_device *dev, uint8_t saddr, int idx)
+{
+	uint8_t val = 0;
+	int ret = 0;
+
+	if (idx >= SSD_LM80_IN_NR || idx < 0) {
+		return -EINVAL;
+	}
+
+	ret = ssd_smbus_read_byte(dev, saddr, SSD_LM80_REG_MASK1, &val);
+	if (ret) {
+		goto out;
+	}
+
+	val |= (1UL << (uint32_t)idx);
+
+	ret = ssd_smbus_write_byte(dev, saddr, SSD_LM80_REG_MASK1, &val);
+	if (ret) {
+		goto out;
+	}
+
+out:
+	return ret;
+}
+
+static int ssd_lm80_read_temp(struct ssd_device *dev, uint8_t saddr, uint16_t *data)
+{
+	uint16_t val = 0;
+	int ret;
+
+	ret = ssd_smbus_read_word(dev, saddr, SSD_LM80_REG_TEMP, (uint8_t *)&val);
+	if (ret) {
+		return ret;
+	}
+
+	*data = u16_swap(val);
+
+	return 0;
+}
+
+static int ssd_lm80_check_event(struct ssd_device *dev, uint8_t saddr)
+{
+	uint32_t volt;
+	uint16_t val = 0, status;
+	uint8_t alarm1 = 0, alarm2 = 0;
+	int i;
+	int ret = 0;
+
+	/* read interrupt status to clear interrupt */
+	ret = ssd_smbus_read_byte(dev, saddr, SSD_LM80_REG_ALARM1, &alarm1);
+	if (ret) {
+		goto out;
+	}
+
+	ret = ssd_smbus_read_byte(dev, saddr, SSD_LM80_REG_ALARM2, &alarm2);
+	if (ret) {
+		goto out;
+	}
+
+	status = (uint16_t)alarm1 | ((uint16_t)alarm2 << 8);
+
+	/* parse inetrrupt status */
+	for (i=0; i<SSD_LM80_IN_NR; i++) {
+		if (!((status >> (uint32_t)i) & 0x1)) {
+			if (test_and_clear_bit(SSD_HWMON_LM80(i), &dev->hwmon)) {
+				/* enable INx irq */
+				ret = ssd_lm80_enable_in(dev, saddr, i);
+				if (ret) {
+					goto out;
+				}
+			}
+
+			continue;
+		}
+
+		/* disable INx irq */
+		ret = ssd_lm80_disable_in(dev, saddr, i);
+		if (ret) {
+			goto out;
+		}
+
+		if (test_and_set_bit(SSD_HWMON_LM80(i), &dev->hwmon)) {
+			continue;
+		}
+
+		ret = ssd_smbus_read_word(dev, saddr, SSD_LM80_REG_IN(i), (uint8_t *)&val);
+		if (ret) {
+			goto out;
+		}
+
+		volt = SSD_LM80_CONVERT_VOLT(u16_swap(val));
+
+		switch (i) {
+			case SSD_LM80_IN_CAP: {
+				if (0 == volt) {
+					ssd_gen_swlog(dev, SSD_LOG_CAP_SHORT_CIRCUIT, 0);
+				} else {
+					ssd_gen_swlog(dev, SSD_LOG_CAP_VOLT_FAULT, SSD_PL_CAP_VOLT(volt));
+				}
+				break;
+			}
+
+			case SSD_LM80_IN_1V2:
+			case SSD_LM80_IN_1V2a:
+			case SSD_LM80_IN_1V5:
+			case SSD_LM80_IN_1V8: {
+				ssd_gen_swlog(dev, SSD_LOG_VOLT_STATUS, SSD_VOLT_LOG_DATA(i, 0, volt));
+				break;
+			}
+			case SSD_LM80_IN_FPGA_3V3:
+			case SSD_LM80_IN_3V3: {
+				ssd_gen_swlog(dev, SSD_LOG_VOLT_STATUS, SSD_VOLT_LOG_DATA(i, 0, SSD_LM80_3V3_VOLT(volt)));
+				break;
+			}
+			default:
+				break;
+		}
+	}
+
+out:
+	if (ret) {
+		if (!test_and_set_bit(SSD_HWMON_SENSOR(SSD_SENSOR_LM80), &dev->hwmon)) {
+			ssd_gen_swlog(dev, SSD_LOG_SENSOR_FAULT, (uint32_t)saddr);
+		}
+	} else {
+		test_and_clear_bit(SSD_HWMON_SENSOR(SSD_SENSOR_LM80), &dev->hwmon);
+	}
+	return ret;
+}
+
+static int ssd_init_sensor(struct ssd_device *dev)
+{
+	int ret = 0;
+
+	if (dev->protocol_info.ver < SSD_PROTOCOL_V3_2) {
+		goto out;
+	}
+
+	ret = ssd_init_lm75(dev, SSD_SENSOR_LM75_SADDRESS);
+	if (ret) {
+		hio_warn("%s: init lm75 failed\n", dev->name);
+		if (!test_and_set_bit(SSD_HWMON_SENSOR(SSD_SENSOR_LM75), &dev->hwmon)) {
+			ssd_gen_swlog(dev, SSD_LOG_SENSOR_FAULT, SSD_SENSOR_LM75_SADDRESS);
+		}
+		goto out;
+	}
+
+	if (dev->hw_info.pcb_ver >= 'B' || dev->hw_info_ext.form_factor == SSD_FORM_FACTOR_HHHL) {
+		ret = ssd_init_lm80(dev, SSD_SENSOR_LM80_SADDRESS);
+		if (ret) {
+			hio_warn("%s: init lm80 failed\n", dev->name);
+			if (!test_and_set_bit(SSD_HWMON_SENSOR(SSD_SENSOR_LM80), &dev->hwmon)) {
+				ssd_gen_swlog(dev, SSD_LOG_SENSOR_FAULT, SSD_SENSOR_LM80_SADDRESS);
+			}
+			goto out;
+		}
+	}
+
+out:
+	/* skip error if not in standard mode */
+	if (mode != SSD_DRV_MODE_STANDARD) {
+		ret = 0;
+	}
+	return ret;
+}
+
+/* board volt */
+static int ssd_mon_boardvolt(struct ssd_device *dev)
+{
+	if (dev->protocol_info.ver < SSD_PROTOCOL_V3_2) {
+		return 0;
+	}
+
+	if (dev->hw_info_ext.form_factor == SSD_FORM_FACTOR_FHHL && dev->hw_info.pcb_ver < 'B') {
+		return 0;
+	}
+
+	return ssd_lm80_check_event(dev, SSD_SENSOR_LM80_SADDRESS);
+}
+
+/* temperature */
+static int ssd_mon_temp(struct ssd_device *dev)
+{
+	int cur;
+	uint16_t val = 0;
+	int ret = 0;
+
+	if (dev->protocol_info.ver < SSD_PROTOCOL_V3_2) {
+		return 0;
+	}
+
+	if (dev->hw_info_ext.form_factor == SSD_FORM_FACTOR_FHHL && dev->hw_info.pcb_ver < 'B') {
+		return 0;
+	}
+
+	/* inlet */
+	ret = ssd_lm80_read_temp(dev, SSD_SENSOR_LM80_SADDRESS, &val);
+	if (ret) {
+		if (!test_and_set_bit(SSD_HWMON_SENSOR(SSD_SENSOR_LM80), &dev->hwmon)) {
+			ssd_gen_swlog(dev, SSD_LOG_SENSOR_FAULT, SSD_SENSOR_LM80_SADDRESS);
+		}
+		goto out;
+	}
+	test_and_clear_bit(SSD_HWMON_SENSOR(SSD_SENSOR_LM80), &dev->hwmon);
+
+	cur = SSD_SENSOR_CONVERT_TEMP(val);
+	if (cur >= SSD_INLET_OT_TEMP) {
+		if (!test_and_set_bit(SSD_HWMON_TEMP(SSD_TEMP_INLET), &dev->hwmon)) {
+			ssd_gen_swlog(dev, SSD_LOG_INLET_OVER_TEMP, (uint32_t)cur);
+		}
+	} else if(cur < SSD_INLET_OT_HYST) {
+		if (test_and_clear_bit(SSD_HWMON_TEMP(SSD_TEMP_INLET), &dev->hwmon)) {
+			ssd_gen_swlog(dev, SSD_LOG_INLET_NORMAL_TEMP, (uint32_t)cur);
+		}
+	}
+
+	/* flash */
+	ret = ssd_lm75_read(dev, SSD_SENSOR_LM75_SADDRESS, &val);
+	if (ret) {
+		if (!test_and_set_bit(SSD_HWMON_SENSOR(SSD_SENSOR_LM75), &dev->hwmon)) {
+			ssd_gen_swlog(dev, SSD_LOG_SENSOR_FAULT, SSD_SENSOR_LM75_SADDRESS);
+		}
+		goto out;
+	}
+	test_and_clear_bit(SSD_HWMON_SENSOR(SSD_SENSOR_LM75), &dev->hwmon);
+
+	cur = SSD_SENSOR_CONVERT_TEMP(val);
+	if (cur >= SSD_FLASH_OT_TEMP) {
+		if (!test_and_set_bit(SSD_HWMON_TEMP(SSD_TEMP_FLASH), &dev->hwmon)) {
+			ssd_gen_swlog(dev, SSD_LOG_FLASH_OVER_TEMP, (uint32_t)cur);
+		}
+	} else if(cur < SSD_FLASH_OT_HYST) {
+		if (test_and_clear_bit(SSD_HWMON_TEMP(SSD_TEMP_FLASH), &dev->hwmon)) {
+			ssd_gen_swlog(dev, SSD_LOG_FLASH_NORMAL_TEMP, (uint32_t)cur);
+		}
+	}
+
+out:
+	return ret;
+}
+
+/* cmd tag */
+static inline void ssd_put_tag(struct ssd_device *dev, int tag)
+{
+	test_and_clear_bit(tag,  dev->tag_map);
+	wake_up(&dev->tag_wq);
+}
+
+static inline int ssd_get_tag(struct ssd_device *dev, int wait)
+{
+	int tag;
+
+find_tag:
+	while ((tag = find_first_zero_bit(dev->tag_map, dev->hw_info.cmd_fifo_sz)) >= atomic_read(&dev->queue_depth)) {
+		DEFINE_WAIT(__wait);
+
+		if (!wait) {
+			return -1;
+		}
+
+		prepare_to_wait_exclusive(&dev->tag_wq, &__wait, TASK_UNINTERRUPTIBLE);
+		schedule();
+
+		finish_wait(&dev->tag_wq, &__wait);
+	}
+
+	if (test_and_set_bit(tag, dev->tag_map)) {
+		goto find_tag;
+	}
+
+	return tag;
+}
+
+static void ssd_barrier_put_tag(struct ssd_device *dev, int tag)
+{
+	test_and_clear_bit(tag,  dev->tag_map);
+}
+
+static int ssd_barrier_get_tag(struct ssd_device *dev)
+{
+	int tag = 0;
+
+	if (test_and_set_bit(tag, dev->tag_map)) {
+		return -1;
+	}
+
+	return tag;
+}
+
+static void ssd_barrier_end(struct ssd_device *dev)
+{
+	atomic_set(&dev->queue_depth, dev->hw_info.cmd_fifo_sz);
+	wake_up_all(&dev->tag_wq);
+
+	mutex_unlock(&dev->barrier_mutex);
+}
+
+static int ssd_barrier_start(struct ssd_device *dev)
+{
+	int i;
+
+	mutex_lock(&dev->barrier_mutex);
+
+	atomic_set(&dev->queue_depth, 0);
+
+	for (i=0; i<SSD_CMD_TIMEOUT; i++) {
+		if (find_first_bit(dev->tag_map, dev->hw_info.cmd_fifo_sz) >= dev->hw_info.cmd_fifo_sz) {
+			return 0;
+		}
+
+		__set_current_state(TASK_INTERRUPTIBLE);
+		schedule_timeout(1);
+	}
+
+	atomic_set(&dev->queue_depth, dev->hw_info.cmd_fifo_sz);
+	wake_up_all(&dev->tag_wq);
+
+	mutex_unlock(&dev->barrier_mutex);
+
+	return -EBUSY;
+}
+
+static int ssd_busy(struct ssd_device *dev)
+{
+	if (find_first_bit(dev->tag_map, dev->hw_info.cmd_fifo_sz) >= dev->hw_info.cmd_fifo_sz) {
+		return 0;
+	}
+
+	return 1;
+}
+
+static int ssd_wait_io(struct ssd_device *dev)
+{
+	int i;
+
+	for (i=0; i<SSD_CMD_TIMEOUT; i++) {
+		if (find_first_bit(dev->tag_map, dev->hw_info.cmd_fifo_sz) >= dev->hw_info.cmd_fifo_sz) {
+			return 0;
+		}
+
+		__set_current_state(TASK_INTERRUPTIBLE);
+		schedule_timeout(1);
+	}
+
+	return -EBUSY;
+}
+
+#if 0
+static int ssd_in_barrier(struct ssd_device *dev)
+{
+	return (0 == atomic_read(&dev->queue_depth));
+}
+#endif
+
+static void ssd_cleanup_tag(struct ssd_device *dev)
+{
+	kfree(dev->tag_map);
+}
+
+static int ssd_init_tag(struct ssd_device *dev)
+{
+	int nr_ulongs = ALIGN(dev->hw_info.cmd_fifo_sz, BITS_PER_LONG) / BITS_PER_LONG;
+
+	mutex_init(&dev->barrier_mutex);
+
+	atomic_set(&dev->queue_depth, dev->hw_info.cmd_fifo_sz);
+
+	dev->tag_map = kmalloc(nr_ulongs * sizeof(unsigned long), GFP_ATOMIC);
+	if (!dev->tag_map) {
+		return -ENOMEM;
+	}
+
+	memset(dev->tag_map, 0, nr_ulongs * sizeof(unsigned long));
+
+	init_waitqueue_head(&dev->tag_wq);
+
+	return 0;
+}
+
+/* io stat */
+static void ssd_end_io_acct(struct ssd_cmd *cmd)
+{
+	struct ssd_device *dev = cmd->dev;
+	struct bio *bio = cmd->bio;
+	unsigned long dur = jiffies - cmd->start_time;
+	int rw = bio_data_dir(bio);
+
+#if ((LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0)) || (defined RHEL_MAJOR && RHEL_MAJOR == 6 && RHEL_MINOR >= 7))
+	int cpu = part_stat_lock();
+	struct hd_struct *part = disk_map_sector_rcu(dev->gd, bio_start(bio));
+	part_round_stats(cpu, part);
+	part_stat_add(cpu, part, ticks[rw], dur);
+	part_dec_in_flight(part, rw);
+	part_stat_unlock();
+#elif (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,27))
+	int cpu = part_stat_lock();
+	struct hd_struct *part = &dev->gd->part0;
+	part_round_stats(cpu, part);
+	part_stat_add(cpu, part, ticks[rw], dur);
+	part_stat_unlock();
+	part->in_flight[rw] = atomic_dec_return(&dev->in_flight[rw]);
+#elif (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,14))
+	preempt_disable();
+	disk_round_stats(dev->gd);
+	preempt_enable();
+	disk_stat_add(dev->gd, ticks[rw], dur);
+	dev->gd->in_flight = atomic_dec_return(&dev->in_flight[0]);
+#else
+	preempt_disable();
+	disk_round_stats(dev->gd);
+	preempt_enable();
+	if (rw == WRITE) {
+		disk_stat_add(dev->gd, write_ticks, dur);
+	} else {
+		disk_stat_add(dev->gd, read_ticks, dur);
+	}
+	dev->gd->in_flight = atomic_dec_return(&dev->in_flight[0]);
+#endif
+}
+
+static void ssd_start_io_acct(struct ssd_cmd *cmd)
+{
+	struct ssd_device *dev = cmd->dev;
+	struct bio *bio = cmd->bio;
+	int rw = bio_data_dir(bio);
+
+#if ((LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0)) || (defined RHEL_MAJOR && RHEL_MAJOR == 6 && RHEL_MINOR >= 7))
+	int cpu = part_stat_lock();
+	struct hd_struct *part = disk_map_sector_rcu(dev->gd, bio_start(bio));
+	part_round_stats(cpu, part);
+	part_stat_inc(cpu, part, ios[rw]);
+	part_stat_add(cpu, part, sectors[rw], bio_sectors(bio));
+	part_inc_in_flight(part, rw);
+	part_stat_unlock();
+#elif (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,27))
+	int cpu = part_stat_lock();
+	struct hd_struct *part = &dev->gd->part0;
+	part_round_stats(cpu, part);
+	part_stat_inc(cpu, part, ios[rw]);
+	part_stat_add(cpu, part, sectors[rw], bio_sectors(bio));
+	part_stat_unlock();
+	part->in_flight[rw] = atomic_inc_return(&dev->in_flight[rw]);
+#elif (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,14))
+	preempt_disable();
+	disk_round_stats(dev->gd);
+	preempt_enable();
+	disk_stat_inc(dev->gd, ios[rw]);
+	disk_stat_add(dev->gd, sectors[rw], bio_sectors(bio));
+	dev->gd->in_flight = atomic_inc_return(&dev->in_flight[0]);
+#else
+	preempt_disable();
+	disk_round_stats(dev->gd);
+	preempt_enable();
+	if (rw == WRITE) {
+		disk_stat_inc(dev->gd, writes);
+		disk_stat_add(dev->gd, write_sectors, bio_sectors(bio));
+	} else {
+		disk_stat_inc(dev->gd, reads);
+		disk_stat_add(dev->gd, read_sectors, bio_sectors(bio));
+	}
+	dev->gd->in_flight = atomic_inc_return(&dev->in_flight[0]);
+#endif
+
+	cmd->start_time = jiffies;
+}
+
+/* io */
+static void ssd_queue_bio(struct ssd_device *dev, struct bio *bio)
+{
+	spin_lock(&dev->sendq_lock);
+	ssd_blist_add(&dev->sendq, bio);
+	spin_unlock(&dev->sendq_lock);
+
+	atomic_inc(&dev->in_sendq);
+	wake_up(&dev->send_waitq);
+}
+
+static inline void ssd_end_request(struct ssd_cmd *cmd)
+{
+	struct ssd_device *dev = cmd->dev;
+	struct bio *bio = cmd->bio;
+	int errors = cmd->errors;
+	int tag = cmd->tag;
+
+	if (bio) {
+#if (defined SSD_TRIM && (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36)))
+		if (!(bio->bi_rw & REQ_DISCARD)) {
+			ssd_end_io_acct(cmd);
+			if (!cmd->flag) {
+				pci_unmap_sg(dev->pdev, cmd->sgl, cmd->nsegs, 
+					bio_data_dir(bio) == READ ? PCI_DMA_FROMDEVICE : PCI_DMA_TODEVICE);
+			}
+		}
+#elif (defined SSD_TRIM && (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32)))
+		if (!bio_rw_flagged(bio, BIO_RW_DISCARD)) {
+			ssd_end_io_acct(cmd);
+			if (!cmd->flag) {
+				pci_unmap_sg(dev->pdev, cmd->sgl, cmd->nsegs, 
+					bio_data_dir(bio) == READ ? PCI_DMA_FROMDEVICE : PCI_DMA_TODEVICE);
+			}
+		}
+#else
+		ssd_end_io_acct(cmd);
+
+		if (!cmd->flag) {
+			pci_unmap_sg(dev->pdev, cmd->sgl, cmd->nsegs, 
+				bio_data_dir(bio) == READ ? PCI_DMA_FROMDEVICE : PCI_DMA_TODEVICE);
+		}
+#endif
+
+		cmd->bio = NULL;
+		ssd_put_tag(dev, tag);
+
+		if (SSD_INT_MSIX == dev->int_mode || tag < 16 || errors) {
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24))
+			bio_endio(bio, errors);
+#else
+			bio_endio(bio, bio->bi_size, errors);
+#endif
+		} else /* if (bio->bi_idx >= bio->bi_vcnt)*/ {
+			spin_lock(&dev->doneq_lock);
+			ssd_blist_add(&dev->doneq, bio);
+			spin_unlock(&dev->doneq_lock);
+
+			atomic_inc(&dev->in_doneq);
+			wake_up(&dev->done_waitq);
+		}
+	} else {
+		if (cmd->waiting) {
+			complete(cmd->waiting);
+		}
+	}
+}
+
+static void ssd_end_timeout_request(struct ssd_cmd *cmd)
+{
+	struct ssd_device *dev = cmd->dev;
+	struct ssd_rw_msg *msg = (struct ssd_rw_msg *)cmd->msg;
+	int i;
+
+	for (i=0; i<dev->nr_queue; i++) {
+		disable_irq(dev->entry[i].vector);
+	}
+
+	atomic_inc(&dev->tocnt);
+	//if (cmd->bio) {
+		hio_err("%s: cmd timeout: tag %d fun %#x\n", dev->name, msg->tag, msg->fun);
+		cmd->errors = -ETIMEDOUT;
+		ssd_end_request(cmd);
+	//}
+
+	for (i=0; i<dev->nr_queue; i++) {
+		enable_irq(dev->entry[i].vector);
+	}
+
+	/* alarm led */
+	ssd_set_alarm(dev);
+}
+
+/* cmd timer */
+static void ssd_cmd_add_timer(struct ssd_cmd *cmd, int timeout, void (*complt)(struct ssd_cmd *))
+{
+	init_timer(&cmd->cmd_timer);
+
+	cmd->cmd_timer.data = (unsigned long)cmd;
+	cmd->cmd_timer.expires = jiffies + timeout;
+	cmd->cmd_timer.function = (void (*)(unsigned long)) complt;
+
+	add_timer(&cmd->cmd_timer);
+}
+
+static int ssd_cmd_del_timer(struct ssd_cmd *cmd)
+{
+	return del_timer(&cmd->cmd_timer);
+}
+
+static void ssd_add_timer(struct timer_list *timer, int timeout, void (*complt)(void *), void *data)
+{
+	init_timer(timer);
+
+	timer->data = (unsigned long)data;
+	timer->expires = jiffies + timeout;
+	timer->function = (void (*)(unsigned long)) complt;
+
+	add_timer(timer);
+}
+
+static int ssd_del_timer(struct timer_list *timer)
+{
+	return del_timer(timer);
+}
+
+static void ssd_cmd_timeout(struct ssd_cmd *cmd)
+{
+	struct ssd_device *dev = cmd->dev;
+	uint32_t msg = *(uint32_t *)cmd->msg;
+
+	ssd_end_timeout_request(cmd);
+
+	ssd_gen_swlog(dev, SSD_LOG_TIMEOUT, msg);
+}
+
+
+static void __ssd_done(unsigned long data)
+{
+	struct ssd_cmd *cmd;
+	LIST_HEAD(localq);
+
+	local_irq_disable();
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,13,0))
+	list_splice_init(&__get_cpu_var(ssd_doneq), &localq);
+#else
+	list_splice_init(this_cpu_ptr(&ssd_doneq), &localq);
+#endif
+	local_irq_enable();
+
+	while (!list_empty(&localq)) {
+		cmd = list_entry(localq.next, struct ssd_cmd, list);
+		list_del_init(&cmd->list);
+
+		ssd_end_request(cmd);
+	}
+}
+
+static void __ssd_done_db(unsigned long data)
+{
+	struct ssd_cmd *cmd;
+	struct ssd_device *dev;
+	struct bio *bio;
+	LIST_HEAD(localq);
+
+	local_irq_disable();
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,13,0))
+	list_splice_init(&__get_cpu_var(ssd_doneq), &localq);
+#else
+	list_splice_init(this_cpu_ptr(&ssd_doneq), &localq);
+#endif
+	local_irq_enable();
+
+	while (!list_empty(&localq)) {
+		cmd = list_entry(localq.next, struct ssd_cmd, list);
+		list_del_init(&cmd->list);
+
+		dev = (struct ssd_device *)cmd->dev;
+		bio = cmd->bio;
+
+		if (bio) {
+			sector_t off = dev->db_info.data.loc.off;
+			uint32_t len = dev->db_info.data.loc.len;
+
+			switch (dev->db_info.type) {
+				case SSD_DEBUG_READ_ERR:
+					if (bio_data_dir(bio) == READ && 
+						!((off + len) <= bio_start(bio) || off >= (bio_start(bio) + bio_sectors(bio)))) {
+						cmd->errors = -EIO;
+					}
+					break;
+				case SSD_DEBUG_WRITE_ERR:
+					if (bio_data_dir(bio) == WRITE && 
+						!((off + len) <= bio_start(bio) || off >= (bio_start(bio) + bio_sectors(bio)))) {
+						cmd->errors = -EROFS;
+					}
+					break;
+				case SSD_DEBUG_RW_ERR:
+					if (!((off + len) <= bio_start(bio) || off >= (bio_start(bio) + bio_sectors(bio)))) {
+						if (bio_data_dir(bio) == READ) {
+							cmd->errors = -EIO;
+						} else {
+							cmd->errors = -EROFS;
+						}
+					}
+					break;
+				default:
+					break;
+			}
+		}
+
+		ssd_end_request(cmd);
+	}
+}
+
+static inline void ssd_done_bh(struct ssd_cmd *cmd)
+{
+	unsigned long flags = 0;
+
+	if (unlikely(!ssd_cmd_del_timer(cmd))) {
+		struct ssd_device *dev = cmd->dev;
+		struct ssd_rw_msg *msg = (struct ssd_rw_msg *)cmd->msg;
+		hio_err("%s: unknown cmd: tag %d fun %#x\n", dev->name, msg->tag, msg->fun);
+
+		/* alarm led */
+		ssd_set_alarm(dev);
+		return;
+	}
+
+	local_irq_save(flags);
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,13,0))
+	list_add_tail(&cmd->list, &__get_cpu_var(ssd_doneq));
+	tasklet_hi_schedule(&__get_cpu_var(ssd_tasklet));
+#else
+	list_add_tail(&cmd->list, this_cpu_ptr(&ssd_doneq));
+	tasklet_hi_schedule(this_cpu_ptr(&ssd_tasklet));
+#endif
+	local_irq_restore(flags);
+
+	return;
+}
+
+static inline void ssd_done(struct ssd_cmd *cmd)
+{
+	if (unlikely(!ssd_cmd_del_timer(cmd))) {
+		struct ssd_device *dev = cmd->dev;
+		struct ssd_rw_msg *msg = (struct ssd_rw_msg *)cmd->msg;
+		hio_err("%s: unknown cmd: tag %d fun %#x\n", dev->name, msg->tag, msg->fun);
+
+		/* alarm led */
+		ssd_set_alarm(dev);
+		return;
+	}
+
+	ssd_end_request(cmd);
+
+	return;
+}
+
+static inline void ssd_dispatch_cmd(struct ssd_cmd *cmd)
+{
+	struct ssd_device *dev = (struct ssd_device *)cmd->dev;
+
+	ssd_cmd_add_timer(cmd, SSD_CMD_TIMEOUT, ssd_cmd_timeout);
+
+	spin_lock(&dev->cmd_lock);
+	ssd_reg_write(dev->ctrlp + SSD_REQ_FIFO_REG, cmd->msg_dma);
+	spin_unlock(&dev->cmd_lock);
+}
+
+static inline void ssd_send_cmd(struct ssd_cmd *cmd)
+{
+	struct ssd_device *dev = (struct ssd_device *)cmd->dev;
+
+	ssd_cmd_add_timer(cmd, SSD_CMD_TIMEOUT, ssd_cmd_timeout);
+
+	ssd_reg32_write(dev->ctrlp + SSD_REQ_FIFO_REG, ((uint32_t)cmd->tag | ((uint32_t)cmd->nsegs << 16)));
+}
+
+static inline void ssd_send_cmd_db(struct ssd_cmd *cmd)
+{
+	struct ssd_device *dev = (struct ssd_device *)cmd->dev;
+	struct bio *bio = cmd->bio;
+
+	ssd_cmd_add_timer(cmd, SSD_CMD_TIMEOUT, ssd_cmd_timeout);
+
+	if (bio) {
+		switch (dev->db_info.type) {
+			case SSD_DEBUG_READ_TO:
+				if (bio_data_dir(bio) == READ) {
+					return;
+				}
+				break;
+			case SSD_DEBUG_WRITE_TO:
+				if (bio_data_dir(bio) == WRITE) {
+					return;
+				}
+				break;
+			case SSD_DEBUG_RW_TO:
+				return;
+				break;
+			default:
+				break;
+		}
+	}
+
+	ssd_reg32_write(dev->ctrlp + SSD_REQ_FIFO_REG, ((uint32_t)cmd->tag | ((uint32_t)cmd->nsegs << 16)));
+}
+
+
+/* fixed for BIOVEC_PHYS_MERGEABLE */
+#ifdef SSD_BIOVEC_PHYS_MERGEABLE_FIXED
+#include <linux/bio.h>
+#include <linux/io.h>
+#include <xen/page.h>
+
+static bool xen_biovec_phys_mergeable_fixed(const struct bio_vec *vec1,
+			       const struct bio_vec *vec2)
+{
+	unsigned long mfn1 = pfn_to_mfn(page_to_pfn(vec1->bv_page));
+	unsigned long mfn2 = pfn_to_mfn(page_to_pfn(vec2->bv_page));
+
+	return __BIOVEC_PHYS_MERGEABLE(vec1, vec2) &&
+		((mfn1 == mfn2) || ((mfn1+1) == mfn2));
+}
+
+#ifdef BIOVEC_PHYS_MERGEABLE
+#undef BIOVEC_PHYS_MERGEABLE
+#endif
+#define BIOVEC_PHYS_MERGEABLE(vec1, vec2)				\
+	(__BIOVEC_PHYS_MERGEABLE(vec1, vec2) &&				\
+	 (!xen_domain() || xen_biovec_phys_mergeable_fixed(vec1, vec2)))
+
+#endif
+
+static inline int ssd_bio_map_sg(struct ssd_device *dev, struct bio *bio, struct scatterlist *sgl)
+{
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,14,0))
+	struct bio_vec *bvec, *bvprv = NULL;
+	struct scatterlist *sg = NULL;
+	int i = 0, nsegs = 0;
+
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,23))
+	sg_init_table(sgl, dev->hw_info.cmd_max_sg);
+#endif
+
+	/*
+	* for each segment in bio
+	*/
+	bio_for_each_segment(bvec, bio, i) {
+		if (bvprv && BIOVEC_PHYS_MERGEABLE(bvprv, bvec)) {
+			sg->length += bvec->bv_len;
+		} else {
+			if (unlikely(nsegs >= (int)dev->hw_info.cmd_max_sg)) {
+				break;
+			}
+
+			sg = sg ? (sg + 1) : sgl;
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24))
+			sg_set_page(sg, bvec->bv_page, bvec->bv_len, bvec->bv_offset);
+#else
+			sg->page = bvec->bv_page;
+			sg->length = bvec->bv_len;
+			sg->offset = bvec->bv_offset;
+#endif
+			nsegs++;
+		}
+		bvprv = bvec;
+	}
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24))
+	if (sg) {
+		sg_mark_end(sg);
+	}
+#endif
+
+	bio->bi_idx = i;
+
+	return nsegs;
+#else
+	struct bio_vec bvec, bvprv;
+	struct bvec_iter iter;
+	struct scatterlist *sg = NULL;
+	int nsegs = 0;
+	int first = 1;
+
+	sg_init_table(sgl, dev->hw_info.cmd_max_sg);
+
+	/*
+	* for each segment in bio
+	*/
+	bio_for_each_segment(bvec, bio, iter) {
+		if (!first && BIOVEC_PHYS_MERGEABLE(&bvprv, &bvec)) {
+			sg->length += bvec.bv_len;
+		} else {
+			if (unlikely(nsegs >= (int)dev->hw_info.cmd_max_sg)) {
+				break;
+			}
+
+			sg = sg ? (sg + 1) : sgl;
+
+			sg_set_page(sg, bvec.bv_page, bvec.bv_len, bvec.bv_offset);
+
+			nsegs++;
+			first = 0;
+		}
+		bvprv = bvec;
+	}
+
+	if (sg) {
+		sg_mark_end(sg);
+	}
+
+	return nsegs;
+#endif
+}
+
+
+static int __ssd_submit_pbio(struct ssd_device *dev, struct bio *bio, int wait)
+{
+	struct ssd_cmd *cmd;
+	struct ssd_rw_msg *msg;
+	struct ssd_sg_entry *sge;
+	sector_t block = bio_start(bio);
+	int tag;
+	int i;
+
+	tag = ssd_get_tag(dev, wait);
+	if (tag < 0) {
+		return -EBUSY;
+	}
+
+	cmd = &dev->cmd[tag];
+	cmd->bio = bio;
+	cmd->flag = 1;
+
+	msg = (struct ssd_rw_msg *)cmd->msg;
+
+#if (defined SSD_TRIM && (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36)))
+	if (bio->bi_rw & REQ_DISCARD) {
+		unsigned int length = bio_sectors(bio);
+
+		//printk(KERN_WARNING "%s: discard len %u, block %llu\n", dev->name, bio_sectors(bio), block);
+		msg->tag = tag;
+		msg->fun = SSD_FUNC_TRIM;
+
+		sge = msg->sge;
+		for (i=0; i<(dev->hw_info.cmd_max_sg); i++) {
+			sge->block = block;
+			sge->length = (length >= dev->hw_info.sg_max_sec) ? dev->hw_info.sg_max_sec : length;
+			sge->buf = 0;
+
+			block += sge->length;
+			length -= sge->length;
+			sge++;
+
+			if (length <= 0) {
+				break;
+			}
+		}
+		msg->nsegs = cmd->nsegs = (i + 1);
+
+		dev->scmd(cmd);
+		return 0;
+	}
+#elif (defined SSD_TRIM && (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32)))
+	if (bio_rw_flagged(bio, BIO_RW_DISCARD)) {
+		unsigned int length = bio_sectors(bio);
+
+		//printk(KERN_WARNING "%s: discard len %u, block %llu\n", dev->name, bio_sectors(bio), block);
+		msg->tag = tag;
+		msg->fun = SSD_FUNC_TRIM;
+
+		sge = msg->sge;
+		for (i=0; i<(dev->hw_info.cmd_max_sg); i++) {
+			sge->block = block;
+			sge->length = (length >= dev->hw_info.sg_max_sec) ? dev->hw_info.sg_max_sec : length;
+			sge->buf = 0;
+
+			block += sge->length;
+			length -= sge->length;
+			sge++;
+
+			if (length <= 0) {
+				break;
+			}
+		}
+		msg->nsegs = cmd->nsegs = (i + 1);
+
+		dev->scmd(cmd);
+		return 0;
+	}
+#endif
+
+	//msg->nsegs = cmd->nsegs = ssd_bio_map_sg(dev, bio, sgl);
+	msg->nsegs = cmd->nsegs = bio->bi_vcnt;
+
+	//xx
+	if (bio_data_dir(bio) == READ) {
+		msg->fun = SSD_FUNC_READ;
+		msg->flag = 0;
+	} else {
+		msg->fun = SSD_FUNC_WRITE;
+		msg->flag = dev->wmode;
+	}
+
+	sge = msg->sge;
+	for (i=0; i<bio->bi_vcnt; i++) {
+		sge->block = block;
+		sge->length = bio->bi_io_vec[i].bv_len >> 9;
+		sge->buf = (uint64_t)((void *)bio->bi_io_vec[i].bv_page + bio->bi_io_vec[i].bv_offset);
+
+		block += sge->length;
+		sge++;
+	}
+
+	msg->tag = tag;
+
+#ifdef SSD_OT_PROTECT
+	if (unlikely(dev->ot_delay > 0 && dev->ot_protect != 0)) {
+		msleep_interruptible(dev->ot_delay);
+	}
+#endif
+
+	ssd_start_io_acct(cmd);
+	dev->scmd(cmd);
+
+	return 0;
+}
+
+static inline int ssd_submit_bio(struct ssd_device *dev, struct bio *bio, int wait)
+{
+	struct ssd_cmd *cmd;
+	struct ssd_rw_msg *msg;
+	struct ssd_sg_entry *sge;
+	struct scatterlist *sgl;
+	sector_t block = bio_start(bio);
+	int tag;
+	int i;
+
+	tag = ssd_get_tag(dev, wait);
+	if (tag < 0) {
+		return -EBUSY;
+	}
+
+	cmd = &dev->cmd[tag];
+	cmd->bio = bio;
+	cmd->flag = 0;
+
+	msg = (struct ssd_rw_msg *)cmd->msg;
+
+	sgl = cmd->sgl;
+
+#if (defined SSD_TRIM && (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36)))
+	if (bio->bi_rw & REQ_DISCARD) {
+		unsigned int length = bio_sectors(bio);
+
+		//printk(KERN_WARNING "%s: discard len %u, block %llu\n", dev->name, bio_sectors(bio), block);
+		msg->tag = tag;
+		msg->fun = SSD_FUNC_TRIM;
+
+		sge = msg->sge;
+		for (i=0; i<(dev->hw_info.cmd_max_sg); i++) {
+			sge->block = block;
+			sge->length = (length >= dev->hw_info.sg_max_sec) ? dev->hw_info.sg_max_sec : length;
+			sge->buf = 0;
+
+			block += sge->length;
+			length -= sge->length;
+			sge++;
+
+			if (length <= 0) {
+				break;
+			}
+		}
+		msg->nsegs = cmd->nsegs = (i + 1);
+
+		dev->scmd(cmd);
+		return 0;
+	}
+#elif (defined SSD_TRIM && (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32)))
+	if (bio_rw_flagged(bio, BIO_RW_DISCARD)) {
+		unsigned int length = bio_sectors(bio);
+
+		//printk(KERN_WARNING "%s: discard len %u, block %llu\n", dev->name, bio_sectors(bio), block);
+		msg->tag = tag;
+		msg->fun = SSD_FUNC_TRIM;
+
+		sge = msg->sge;
+		for (i=0; i<(dev->hw_info.cmd_max_sg); i++) {
+			sge->block = block;
+			sge->length = (length >= dev->hw_info.sg_max_sec) ? dev->hw_info.sg_max_sec : length;
+			sge->buf = 0;
+
+			block += sge->length;
+			length -= sge->length;
+			sge++;
+
+			if (length <= 0) {
+				break;
+			}
+		}
+		msg->nsegs = cmd->nsegs = (i + 1);
+
+		dev->scmd(cmd);
+		return 0;
+	}
+#endif
+
+	msg->nsegs = cmd->nsegs = ssd_bio_map_sg(dev, bio, sgl);
+
+	//xx
+	if (bio_data_dir(bio) == READ) {
+		msg->fun = SSD_FUNC_READ;
+		msg->flag = 0;
+		pci_map_sg(dev->pdev, sgl, cmd->nsegs, PCI_DMA_FROMDEVICE);
+	} else {
+		msg->fun = SSD_FUNC_WRITE;
+		msg->flag = dev->wmode;
+		pci_map_sg(dev->pdev, sgl, cmd->nsegs, PCI_DMA_TODEVICE);
+	}
+
+	sge = msg->sge;
+	for (i=0; i<cmd->nsegs; i++) {
+		sge->block = block;
+		sge->length = sg_dma_len(sgl) >> 9;
+		sge->buf = sg_dma_address(sgl);
+
+		block += sge->length;
+		sgl++;
+		sge++;
+	}
+
+	msg->tag = tag;
+
+#ifdef SSD_OT_PROTECT
+	if (unlikely(dev->ot_delay > 0 && dev->ot_protect != 0)) {
+		msleep_interruptible(dev->ot_delay);
+	}
+#endif
+
+	ssd_start_io_acct(cmd);
+	dev->scmd(cmd);
+
+	return 0;
+}
+
+/* threads */
+static int ssd_done_thread(void *data)
+{
+	struct ssd_device *dev;
+	struct bio *bio;
+	struct bio *next;
+
+	if (!data) {
+		return -EINVAL;
+	}
+	dev = data;
+
+	//set_user_nice(current, -5);
+
+	while (!kthread_should_stop()) {
+		wait_event_interruptible(dev->done_waitq, (atomic_read(&dev->in_doneq) || kthread_should_stop()));
+
+		while (atomic_read(&dev->in_doneq)) {
+			if (threaded_irq) {
+				spin_lock(&dev->doneq_lock);
+				bio = ssd_blist_get(&dev->doneq);
+				spin_unlock(&dev->doneq_lock);
+			} else {
+				spin_lock_irq(&dev->doneq_lock);
+				bio = ssd_blist_get(&dev->doneq);
+				spin_unlock_irq(&dev->doneq_lock);
+			}
+
+			while (bio) {
+				next = bio->bi_next;
+				bio->bi_next = NULL;
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24))
+				bio_endio(bio, 0);
+#else
+				bio_endio(bio, bio->bi_size, 0);
+#endif
+				atomic_dec(&dev->in_doneq);
+				bio = next;
+			}
+
+			cond_resched();
+
+#ifdef SSD_ESCAPE_IRQ
+			if (unlikely(smp_processor_id() == dev->irq_cpu)) {
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28))
+				cpumask_var_t new_mask;
+				alloc_cpumask_var(&new_mask, GFP_ATOMIC);
+				cpumask_setall(new_mask);
+				cpumask_clear_cpu(dev->irq_cpu, new_mask);
+				set_cpus_allowed_ptr(current, new_mask);
+				free_cpumask_var(new_mask);
+#else
+				cpumask_t new_mask;
+				cpus_setall(new_mask);
+				cpu_clear(dev->irq_cpu, new_mask);
+				set_cpus_allowed(current, new_mask);
+#endif
+			}
+#endif
+		}
+	}
+	return 0;
+}
+
+static int ssd_send_thread(void *data)
+{
+	struct ssd_device *dev;
+	struct bio *bio;
+	struct bio *next;
+
+	if (!data) {
+		return -EINVAL;
+	}
+	dev = data;
+
+	//set_user_nice(current, -5);
+
+	while (!kthread_should_stop()) {
+		wait_event_interruptible(dev->send_waitq, (atomic_read(&dev->in_sendq) || kthread_should_stop()));
+
+		while (atomic_read(&dev->in_sendq)) {
+			spin_lock(&dev->sendq_lock);
+			bio = ssd_blist_get(&dev->sendq);
+			spin_unlock(&dev->sendq_lock);
+
+			while (bio) {
+				next = bio->bi_next;
+				bio->bi_next = NULL;
+#ifdef SSD_QUEUE_PBIO
+				if (test_and_clear_bit(BIO_SSD_PBIO, &bio->bi_flags)) {
+					__ssd_submit_pbio(dev, bio, 1);
+				} else {
+					ssd_submit_bio(dev, bio, 1);
+				}
+#else
+				ssd_submit_bio(dev, bio, 1);
+#endif
+				atomic_dec(&dev->in_sendq);
+				bio = next;
+			}
+
+			cond_resched();
+
+#ifdef SSD_ESCAPE_IRQ
+			if (unlikely(smp_processor_id() == dev->irq_cpu)) {
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28))
+				cpumask_var_t new_mask;
+				alloc_cpumask_var(&new_mask, GFP_ATOMIC);
+				cpumask_setall(new_mask);
+				cpumask_clear_cpu(dev->irq_cpu, new_mask);
+				set_cpus_allowed_ptr(current, new_mask);
+				free_cpumask_var(new_mask);
+#else
+				cpumask_t new_mask;
+				cpus_setall(new_mask);
+				cpu_clear(dev->irq_cpu, new_mask);
+				set_cpus_allowed(current, new_mask);
+#endif
+			}
+#endif
+		}
+	}
+
+	return 0;
+}
+
+static void ssd_cleanup_thread(struct ssd_device *dev)
+{
+	kthread_stop(dev->send_thread);
+	kthread_stop(dev->done_thread);
+}
+
+static int ssd_init_thread(struct ssd_device *dev)
+{
+	int ret;
+
+	atomic_set(&dev->in_doneq, 0);
+	atomic_set(&dev->in_sendq, 0);
+
+	spin_lock_init(&dev->doneq_lock);
+	spin_lock_init(&dev->sendq_lock);
+
+	ssd_blist_init(&dev->doneq);
+	ssd_blist_init(&dev->sendq);
+
+	init_waitqueue_head(&dev->done_waitq);
+	init_waitqueue_head(&dev->send_waitq);
+
+	dev->done_thread = kthread_run(ssd_done_thread, dev, "%s/d", dev->name);
+	if (IS_ERR(dev->done_thread)) {
+		ret = PTR_ERR(dev->done_thread);
+		goto out_done_thread;
+	}
+
+	dev->send_thread = kthread_run(ssd_send_thread, dev, "%s/s", dev->name);
+	if (IS_ERR(dev->send_thread)) {
+		ret = PTR_ERR(dev->send_thread);
+		goto out_send_thread;
+	}
+
+	return 0;
+
+out_send_thread:
+	kthread_stop(dev->done_thread);
+out_done_thread:
+	return ret;
+}
+
+/* dcmd pool */
+static void ssd_put_dcmd(struct ssd_dcmd *dcmd)
+{
+	struct ssd_device *dev = (struct ssd_device *)dcmd->dev;
+
+	spin_lock(&dev->dcmd_lock);
+	list_add_tail(&dcmd->list, &dev->dcmd_list);
+	spin_unlock(&dev->dcmd_lock);
+}
+
+static struct ssd_dcmd *ssd_get_dcmd(struct ssd_device *dev)
+{
+	struct ssd_dcmd *dcmd = NULL;
+
+	spin_lock(&dev->dcmd_lock);
+	if (!list_empty(&dev->dcmd_list)) {
+		dcmd = list_entry(dev->dcmd_list.next, 
+				 struct ssd_dcmd, list);
+		list_del_init(&dcmd->list);
+	}
+	spin_unlock(&dev->dcmd_lock);
+
+	return dcmd;
+}
+
+static void ssd_cleanup_dcmd(struct ssd_device *dev)
+{
+	kfree(dev->dcmd);
+}
+
+static int ssd_init_dcmd(struct ssd_device *dev)
+{
+	struct ssd_dcmd *dcmd;
+	int dcmd_sz = sizeof(struct ssd_dcmd)*dev->hw_info.cmd_fifo_sz;
+	int i;
+
+	spin_lock_init(&dev->dcmd_lock);
+	INIT_LIST_HEAD(&dev->dcmd_list);
+	init_waitqueue_head(&dev->dcmd_wq);
+
+	dev->dcmd = kmalloc(dcmd_sz, GFP_KERNEL);
+	if (!dev->dcmd) {
+		hio_warn("%s: can not alloc dcmd\n", dev->name);
+		goto out_alloc_dcmd;
+	}
+	memset(dev->dcmd, 0, dcmd_sz);
+
+	for (i=0, dcmd=dev->dcmd; i<(int)dev->hw_info.cmd_fifo_sz; i++, dcmd++) {
+		dcmd->dev = dev;
+		INIT_LIST_HEAD(&dcmd->list);
+		list_add_tail(&dcmd->list, &dev->dcmd_list);
+	}
+
+	return 0;
+
+out_alloc_dcmd:
+	return -ENOMEM;
+}
+
+static void ssd_put_dmsg(void *msg)
+{
+	struct ssd_dcmd *dcmd = container_of(msg, struct ssd_dcmd, msg);
+	struct ssd_device *dev = (struct ssd_device *)dcmd->dev;
+
+	memset(dcmd->msg, 0, SSD_DCMD_MAX_SZ);
+	ssd_put_dcmd(dcmd);
+	wake_up(&dev->dcmd_wq);
+}
+
+static void *ssd_get_dmsg(struct ssd_device *dev)
+{
+	struct ssd_dcmd *dcmd = ssd_get_dcmd(dev);
+
+	while (!dcmd) {
+		DEFINE_WAIT(wait);
+		prepare_to_wait_exclusive(&dev->dcmd_wq, &wait, TASK_UNINTERRUPTIBLE);
+		schedule();
+
+		dcmd = ssd_get_dcmd(dev);
+
+		finish_wait(&dev->dcmd_wq, &wait);
+	}
+	return dcmd->msg;
+}
+
+/* do direct cmd */
+static int ssd_do_request(struct ssd_device *dev, int rw, void *msg, int *done)
+{
+	DECLARE_COMPLETION(wait);
+	struct ssd_cmd *cmd;
+	int tag;
+	int ret = 0;
+
+	tag = ssd_get_tag(dev, 1);
+	if (tag < 0) {
+		return -EBUSY;
+	}
+
+	cmd = &dev->cmd[tag];
+	cmd->nsegs = 1;
+	memcpy(cmd->msg, msg, SSD_DCMD_MAX_SZ);
+	((struct ssd_rw_msg *)cmd->msg)->tag = tag;
+
+	cmd->waiting = &wait;
+
+	dev->scmd(cmd);
+
+	wait_for_completion(cmd->waiting);
+	cmd->waiting = NULL;
+
+	if (cmd->errors == -ETIMEDOUT) {
+		ret = cmd->errors;
+	} else if (cmd->errors) {
+		ret = -EIO;
+	}
+
+	if (done != NULL) {
+		*done = cmd->nr_log;
+	}
+	ssd_put_tag(dev, cmd->tag);
+
+	return ret;
+}
+
+static int ssd_do_barrier_request(struct ssd_device *dev, int rw, void *msg, int *done)
+{
+	DECLARE_COMPLETION(wait);
+	struct ssd_cmd *cmd;
+	int tag;
+	int ret = 0;
+
+	tag = ssd_barrier_get_tag(dev);
+	if (tag < 0) {
+		return -EBUSY;
+	}
+
+	cmd = &dev->cmd[tag];
+	cmd->nsegs = 1;
+	memcpy(cmd->msg, msg, SSD_DCMD_MAX_SZ);
+	((struct ssd_rw_msg *)cmd->msg)->tag = tag;
+
+	cmd->waiting = &wait;
+
+	dev->scmd(cmd);
+
+	wait_for_completion(cmd->waiting);
+	cmd->waiting = NULL;
+
+	if (cmd->errors == -ETIMEDOUT) {
+		ret = cmd->errors;
+	} else if (cmd->errors) {
+		ret = -EIO;
+	}
+
+	if (done != NULL) {
+		*done = cmd->nr_log;
+	}
+	ssd_barrier_put_tag(dev, cmd->tag);
+
+	return ret;
+}
+
+#ifdef SSD_OT_PROTECT
+static void ssd_check_temperature(struct ssd_device *dev, int temp)
+{
+	uint64_t val;
+	uint32_t off;
+	int cur;
+	int i;
+
+	if (mode != SSD_DRV_MODE_STANDARD) {
+		return;
+	}
+
+	if (dev->protocol_info.ver <= SSD_PROTOCOL_V3) {
+	}
+
+	for (i=0; i<dev->hw_info.nr_ctrl; i++) {
+		off = SSD_CTRL_TEMP_REG0 + i * sizeof(uint64_t);
+
+		val = ssd_reg_read(dev->ctrlp + off);
+		if (val == 0xffffffffffffffffull) {
+			continue;
+		}
+
+		cur = (int)CUR_TEMP(val);
+		if (cur >= temp) {
+			if (!test_and_set_bit(SSD_HWMON_TEMP(SSD_TEMP_CTRL), &dev->hwmon)) {
+				if (dev->protocol_info.ver > SSD_PROTOCOL_V3 && dev->protocol_info.ver < SSD_PROTOCOL_V3_2_2) {
+					hio_warn("%s: Over temperature, please check the fans.\n", dev->name);
+					dev->ot_delay = SSD_OT_DELAY;
+				}
+			}
+			return;
+		}
+	}
+
+	if (test_and_clear_bit(SSD_HWMON_TEMP(SSD_TEMP_CTRL), &dev->hwmon)) {
+		if (dev->protocol_info.ver > SSD_PROTOCOL_V3 && dev->protocol_info.ver < SSD_PROTOCOL_V3_2_2) {
+			hio_warn("%s: Temperature is OK.\n", dev->name);
+			dev->ot_delay = 0;
+		}
+	}
+}
+#endif
+
+static int ssd_get_ot_status(struct ssd_device *dev, int *status)
+{
+	uint32_t off;
+	uint32_t val;
+	int i;
+
+	if (!dev || !status) {
+		return -EINVAL;
+	}
+
+	if (dev->protocol_info.ver >= SSD_PROTOCOL_V3_2_2) {
+		for (i=0; i<dev->hw_info.nr_ctrl; i++) {
+			off = SSD_READ_OT_REG0 + (i * SSD_CTRL_REG_ZONE_SZ);
+			val = ssd_reg32_read(dev->ctrlp + off);
+			if ((val >> 22) & 0x1) {
+				*status = 1;
+				goto out;
+			}
+
+			
+			off = SSD_WRITE_OT_REG0 + (i * SSD_CTRL_REG_ZONE_SZ);
+			val = ssd_reg32_read(dev->ctrlp + off);
+			if ((val >> 22) & 0x1) {
+				*status = 1;
+				goto out;
+			}
+		}
+	} else {
+		*status = !!dev->ot_delay;
+	}
+
+out:
+	return 0;
+}
+
+static void ssd_set_ot_protect(struct ssd_device *dev, int protect)
+{
+	uint32_t off;
+	uint32_t val;
+	int i;
+	
+	mutex_lock(&dev->fw_mutex);
+
+	dev->ot_protect = !!protect;
+
+	if (dev->protocol_info.ver >= SSD_PROTOCOL_V3_2_2) {
+		for (i=0; i<dev->hw_info.nr_ctrl; i++) {
+			off = SSD_READ_OT_REG0 + (i * SSD_CTRL_REG_ZONE_SZ);
+			val = ssd_reg32_read(dev->ctrlp + off);
+			if (dev->ot_protect) {
+				val |= (1U << 21);
+			} else {
+				val &= ~(1U << 21);
+			}
+			ssd_reg32_write(dev->ctrlp + off, val);
+
+			
+			off = SSD_WRITE_OT_REG0 + (i * SSD_CTRL_REG_ZONE_SZ);
+			val = ssd_reg32_read(dev->ctrlp + off);
+			if (dev->ot_protect) {
+				val |= (1U << 21);
+			} else {
+				val &= ~(1U << 21);
+			}
+			ssd_reg32_write(dev->ctrlp + off, val);
+		}
+	}
+
+	mutex_unlock(&dev->fw_mutex);
+}
+
+static int ssd_init_ot_protect(struct ssd_device *dev)
+{
+	ssd_set_ot_protect(dev, ot_protect);
+
+#ifdef SSD_OT_PROTECT
+	ssd_check_temperature(dev, SSD_OT_TEMP);
+#endif
+
+	return 0;
+}
+
+/* log */
+static int ssd_read_log(struct ssd_device *dev, int ctrl_idx, void *buf, int *nr_log)
+{
+	struct ssd_log_op_msg *msg;
+	struct ssd_log_msg *lmsg;
+	dma_addr_t buf_dma;
+	size_t length = dev->hw_info.log_sz;
+	int ret = 0;
+
+	if (ctrl_idx >= dev->hw_info.nr_ctrl) {
+		return -EINVAL;
+	}
+
+	buf_dma = pci_map_single(dev->pdev, buf, length, PCI_DMA_FROMDEVICE);
+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,26))
+	ret = dma_mapping_error(buf_dma);
+#else
+	ret = dma_mapping_error(&(dev->pdev->dev), buf_dma);
+#endif
+	if (ret) {
+		hio_warn("%s: unable to map read DMA buffer\n", dev->name);
+		goto out_dma_mapping;
+	}
+
+	msg = (struct ssd_log_op_msg *)ssd_get_dmsg(dev);
+
+	if (dev->protocol_info.ver < SSD_PROTOCOL_V3) {
+		lmsg = (struct ssd_log_msg *)msg;
+		lmsg->fun = SSD_FUNC_READ_LOG;
+		lmsg->ctrl_idx = ctrl_idx;
+		lmsg->buf = buf_dma;
+	} else {
+		msg->fun = SSD_FUNC_READ_LOG;
+		msg->ctrl_idx = ctrl_idx;
+		msg->buf = buf_dma;
+	}
+
+	ret = ssd_do_request(dev, READ, msg, nr_log);
+	ssd_put_dmsg(msg);
+
+	pci_unmap_single(dev->pdev, buf_dma, length, PCI_DMA_FROMDEVICE);
+
+out_dma_mapping:
+	 return ret;
+}
+
+#define SSD_LOG_PRINT_BUF_SZ	256
+static int ssd_parse_log(struct ssd_device *dev, struct ssd_log *log, int print)
+{
+	struct ssd_log_desc *log_desc = ssd_log_desc;
+	struct ssd_log_entry *le;
+	char *sn = NULL;
+	char print_buf[SSD_LOG_PRINT_BUF_SZ];
+	int print_len;
+
+	le = &log->le;
+
+	/* find desc */
+	while (log_desc->event != SSD_UNKNOWN_EVENT) {
+		if (log_desc->event == le->event) {
+			break;
+		}
+		log_desc++;
+	}
+
+	if (!print) {
+		goto out;
+	}
+
+	if (log_desc->level < log_level) {
+		goto out;
+	}
+
+	/* parse */
+	if (dev->protocol_info.ver < SSD_PROTOCOL_V3_2) {
+		sn = dev->label.sn;
+	} else {
+		sn = dev->labelv3.barcode;
+	}
+
+	print_len = snprintf(print_buf, SSD_LOG_PRINT_BUF_SZ, "%s (%s): <%#x>", dev->name, sn, le->event);
+
+	if (log->ctrl_idx != SSD_LOG_SW_IDX) {
+	 	print_len += snprintf((print_buf + print_len), (SSD_LOG_PRINT_BUF_SZ - print_len), " controller %d", log->ctrl_idx);
+	}
+
+	switch (log_desc->data) {
+		case SSD_LOG_DATA_NONE:
+			break;
+		case SSD_LOG_DATA_LOC:
+			if (dev->protocol_info.ver < SSD_PROTOCOL_V3_2) {
+				print_len += snprintf((print_buf + print_len), (SSD_LOG_PRINT_BUF_SZ - print_len), " flash %d", le->data.loc.flash);
+				if (log_desc->sblock) {
+					print_len += snprintf((print_buf + print_len), (SSD_LOG_PRINT_BUF_SZ - print_len), " block %d", le->data.loc.block);
+				}
+				if (log_desc->spage) {
+					print_len += snprintf((print_buf + print_len), (SSD_LOG_PRINT_BUF_SZ - print_len), " page %d", le->data.loc.page);
+				}
+			} else {
+				print_len += snprintf((print_buf + print_len), (SSD_LOG_PRINT_BUF_SZ - print_len), " flash %d", le->data.loc1.flash);
+				if (log_desc->sblock) {
+					print_len += snprintf((print_buf + print_len), (SSD_LOG_PRINT_BUF_SZ - print_len), " block %d", le->data.loc1.block);
+				}
+				if (log_desc->spage) {
+					print_len += snprintf((print_buf + print_len), (SSD_LOG_PRINT_BUF_SZ - print_len), " page %d", le->data.loc1.page);
+				}
+			}
+			break;
+		case SSD_LOG_DATA_HEX: 
+			print_len += snprintf((print_buf + print_len), (SSD_LOG_PRINT_BUF_SZ - print_len), " info %#x", le->data.val);
+			break;
+		default:
+			break;
+	}
+	/*print_len += */snprintf((print_buf + print_len), (SSD_LOG_PRINT_BUF_SZ - print_len), ": %s", log_desc->desc);
+
+	switch (log_desc->level) {
+		case SSD_LOG_LEVEL_INFO:
+			hio_info("%s\n", print_buf);
+			break;
+		case SSD_LOG_LEVEL_NOTICE:
+			hio_note("%s\n", print_buf);
+			break;
+		case SSD_LOG_LEVEL_WARNING:
+			hio_warn("%s\n", print_buf);
+			break;
+		case SSD_LOG_LEVEL_ERR:
+			hio_err("%s\n", print_buf);
+			//printk(KERN_ERR MODULE_NAME": some exception occurred, please check the data or refer to FAQ.");
+			break;
+		default:
+			hio_warn("%s\n", print_buf);
+			break;
+	}
+
+out:
+	return log_desc->level;
+}
+
+static int ssd_bm_get_sfstatus(struct ssd_device *dev, uint16_t *status);
+static int ssd_switch_wmode(struct ssd_device *dev, int wmode);
+
+
+static int ssd_handle_event(struct ssd_device *dev, uint16_t event, int level)
+{
+	int ret = 0;
+
+	switch (event) {
+		case SSD_LOG_OVER_TEMP: {
+#ifdef SSD_OT_PROTECT
+			if (!test_and_set_bit(SSD_HWMON_TEMP(SSD_TEMP_CTRL), &dev->hwmon)) {
+				if (dev->protocol_info.ver > SSD_PROTOCOL_V3 && dev->protocol_info.ver < SSD_PROTOCOL_V3_2_2) {
+					hio_warn("%s: Over temperature, please check the fans.\n", dev->name);
+					dev->ot_delay = SSD_OT_DELAY;
+				}
+			}
+#endif
+			break;
+		}
+
+		case SSD_LOG_NORMAL_TEMP: {
+#ifdef SSD_OT_PROTECT
+			/* need to check all controller's temperature */
+			ssd_check_temperature(dev, SSD_OT_TEMP_HYST);
+#endif
+			break;
+		}
+
+		case SSD_LOG_BATTERY_FAULT: {
+			uint16_t sfstatus;
+
+			if (dev->protocol_info.ver < SSD_PROTOCOL_V3_2) {
+				if (!ssd_bm_get_sfstatus(dev, &sfstatus)) {
+					ssd_gen_swlog(dev, SSD_LOG_BM_SFSTATUS, sfstatus);
+				}
+			}
+
+			if (!test_and_set_bit(SSD_HWMON_PL_CAP(SSD_PL_CAP), &dev->hwmon)) {
+				ssd_switch_wmode(dev, dev->user_wmode); 
+			}
+			break;
+		}
+
+		case SSD_LOG_BATTERY_OK: {
+			if (test_and_clear_bit(SSD_HWMON_PL_CAP(SSD_PL_CAP), &dev->hwmon)) {
+				ssd_switch_wmode(dev, dev->user_wmode); 
+			}
+			break;
+		}
+
+		case SSD_LOG_BOARD_VOLT_FAULT: {
+			ssd_mon_boardvolt(dev);
+			break;
+		}
+
+		case SSD_LOG_CLEAR_LOG: {
+			/* update smart */
+			memset(&dev->smart.log_info, 0, sizeof(struct ssd_log_info));
+			break;
+		}
+
+		case SSD_LOG_CAP_VOLT_FAULT: 
+		case SSD_LOG_CAP_LEARN_FAULT: 
+		case SSD_LOG_CAP_SHORT_CIRCUIT: {
+			if (!test_and_set_bit(SSD_HWMON_PL_CAP(SSD_PL_CAP), &dev->hwmon)) {
+				ssd_switch_wmode(dev, dev->user_wmode); 
+			}
+			break;
+		}
+
+		default:
+			break;
+	}
+
+	/* ssd event call */
+	if (dev->event_call) {
+		dev->event_call(dev->gd, event, level);
+
+		/* FIXME */
+		if (SSD_LOG_CAP_VOLT_FAULT == event || SSD_LOG_CAP_LEARN_FAULT == event || SSD_LOG_CAP_SHORT_CIRCUIT == event) {
+			dev->event_call(dev->gd, SSD_LOG_BATTERY_FAULT, level);
+		}
+	}
+
+	return ret;
+}
+
+static int ssd_save_log(struct ssd_device *dev, struct ssd_log *log)
+{
+	uint32_t off, size;
+	void *internal_log;
+	int ret = 0;
+
+	mutex_lock(&dev->internal_log_mutex);
+
+	size = sizeof(struct ssd_log);
+	off = dev->internal_log.nr_log * size;
+
+	if (off == dev->rom_info.log_sz) {
+		if (dev->internal_log.nr_log == dev->smart.log_info.nr_log) {
+			hio_warn("%s: internal log is full\n", dev->name);
+		}
+		goto out;
+	}
+
+	internal_log = dev->internal_log.log + off;
+	memcpy(internal_log, log, size);
+
+	if (dev->protocol_info.ver > SSD_PROTOCOL_V3) {
+		off += dev->rom_info.log_base;
+
+		ret = ssd_spi_write(dev, log, off, size);
+		if (ret) {
+			goto out;
+		}
+	}
+
+	dev->internal_log.nr_log++;
+
+out:
+	mutex_unlock(&dev->internal_log_mutex);
+	return ret;
+}
+
+static int ssd_save_swlog(struct ssd_device *dev, uint16_t event, uint32_t data)
+{
+	struct ssd_log log;
+	struct timeval tv;
+	int level;
+	int ret = 0;
+
+	if (unlikely(mode != SSD_DRV_MODE_STANDARD))
+		return 0;
+
+	memset(&log, 0, sizeof(struct ssd_log));
+
+	do_gettimeofday(&tv);
+	log.ctrl_idx = SSD_LOG_SW_IDX;
+	log.time = tv.tv_sec;
+	log.le.event = event;
+	log.le.data.val = data;
+
+	level = ssd_parse_log(dev, &log, 0);
+	if (level >= SSD_LOG_LEVEL) {
+		ret = ssd_save_log(dev, &log);
+	}
+
+	/* set alarm */
+	if (SSD_LOG_LEVEL_ERR == level) {
+		ssd_set_alarm(dev);
+	}
+
+	/* update smart */
+	dev->smart.log_info.nr_log++;
+	dev->smart.log_info.stat[level]++;
+
+	/* handle event */
+	ssd_handle_event(dev, event, level);
+
+	return ret;
+}
+
+static int ssd_gen_swlog(struct ssd_device *dev, uint16_t event, uint32_t data)
+{
+	struct ssd_log_entry le;
+	int ret;
+
+	if (unlikely(mode != SSD_DRV_MODE_STANDARD))
+		return 0;
+
+	/* slave port ? */
+	if (dev->slave) {
+		return 0;
+	}
+
+	memset(&le, 0, sizeof(struct ssd_log_entry));
+	le.event = event;
+	le.data.val = data;
+
+	ret = sfifo_put(&dev->log_fifo, &le);
+	if (ret) {
+		return ret;
+	}
+
+	if (test_bit(SSD_INIT_WORKQ, &dev->state)) {
+		queue_work(dev->workq, &dev->log_work);
+	}
+
+	return 0;
+}
+
+static int ssd_do_swlog(struct ssd_device *dev)
+{
+	struct ssd_log_entry le;
+	int ret = 0;
+
+	memset(&le, 0, sizeof(struct ssd_log_entry));
+	while (!sfifo_get(&dev->log_fifo, &le)) {
+		ret = ssd_save_swlog(dev, le.event, le.data.val);
+		if (ret) {
+			break;
+		}
+	}
+
+	return ret;
+}
+
+static int __ssd_clear_log(struct ssd_device *dev)
+{
+	uint32_t off, length;
+	int ret;
+
+	if (dev->protocol_info.ver <= SSD_PROTOCOL_V3) {
+		return 0;
+	}
+
+	if (dev->internal_log.nr_log == 0) {
+		return 0;
+	}
+
+	mutex_lock(&dev->internal_log_mutex);
+
+	off = dev->rom_info.log_base;
+	length = dev->rom_info.log_sz;
+
+	ret = ssd_spi_erase(dev, off, length);
+	if (ret) {
+		hio_warn("%s: log erase: failed\n", dev->name);
+		goto out;
+	}
+
+	dev->internal_log.nr_log = 0;
+
+out:
+	mutex_unlock(&dev->internal_log_mutex);
+	return ret;
+}
+
+static int ssd_clear_log(struct ssd_device *dev)
+{
+	int ret;
+
+	ret = __ssd_clear_log(dev);
+	if(!ret) {
+		ssd_gen_swlog(dev, SSD_LOG_CLEAR_LOG, 0);
+	}
+
+	return ret;
+}
+
+static int ssd_do_log(struct ssd_device *dev, int ctrl_idx, void *buf)
+{
+	struct ssd_log_entry *le;
+	struct ssd_log log;
+	struct timeval tv;
+	int nr_log = 0;
+	int level;
+	int ret = 0;
+
+	ret = ssd_read_log(dev, ctrl_idx, buf, &nr_log);
+	if (ret) {
+		return ret;
+	}
+
+	do_gettimeofday(&tv);
+
+	log.time = tv.tv_sec;
+	log.ctrl_idx = ctrl_idx;
+
+	le = (ssd_log_entry_t *)buf;
+	while (nr_log > 0) {
+		memcpy(&log.le, le, sizeof(struct ssd_log_entry));
+
+		level = ssd_parse_log(dev, &log, 1);
+		if (level >= SSD_LOG_LEVEL) {
+			ssd_save_log(dev, &log);
+		}
+
+		/* set alarm */
+		if (SSD_LOG_LEVEL_ERR == level) {
+			ssd_set_alarm(dev);
+		}
+		
+		dev->smart.log_info.nr_log++;
+		if (SSD_LOG_SEU_FAULT != le->event && SSD_LOG_SEU_FAULT1 != le->event) {
+			dev->smart.log_info.stat[level]++;
+		} else {
+			/* SEU fault */
+
+			/* log to the volatile log info */
+			dev->log_info.nr_log++;
+			dev->log_info.stat[level]++;
+
+			/* do something */
+			dev->reload_fw = 1;
+			ssd_reg32_write(dev->ctrlp + SSD_RELOAD_FW_REG, SSD_RELOAD_FLAG);
+
+			/*dev->readonly = 1;
+			set_disk_ro(dev->gd, 1);
+			hio_warn("%s: switched to read-only mode.\n", dev->name);*/
+		}
+
+		/* handle event */
+		ssd_handle_event(dev, le->event, level);
+
+		le++;
+		nr_log--;
+	}
+
+	return 0;
+}
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20))
+static void ssd_log_worker(void *data)
+{
+	struct ssd_device *dev = (struct ssd_device *)data;
+#else
+static void ssd_log_worker(struct work_struct *work)
+{
+	struct ssd_device *dev = container_of(work, struct ssd_device, log_work);
+#endif
+	int i;
+	int ret;
+
+	if (!test_bit(SSD_LOG_ERR, &dev->state) && test_bit(SSD_ONLINE, &dev->state)) {
+		/* alloc log buf */
+		if (!dev->log_buf) {
+			dev->log_buf = kmalloc(dev->hw_info.log_sz, GFP_KERNEL);
+			if (!dev->log_buf) {
+				hio_warn("%s: ssd_log_worker: no mem\n", dev->name);
+				return;
+			}
+		}
+
+		/* get log */
+		if (test_and_clear_bit(SSD_LOG_HW, &dev->state)) {
+			for (i=0; i<dev->hw_info.nr_ctrl; i++) {
+				ret = ssd_do_log(dev, i, dev->log_buf);
+				if (ret) {
+					(void)test_and_set_bit(SSD_LOG_ERR, &dev->state);
+					hio_warn("%s: do log fail\n", dev->name);
+				}
+			}
+		}
+	}
+
+	ret = ssd_do_swlog(dev);
+	if (ret) {
+		hio_warn("%s: do swlog fail\n", dev->name);
+	}
+}
+
+static void ssd_cleanup_log(struct ssd_device *dev)
+{
+	if (dev->log_buf) {
+		kfree(dev->log_buf);
+		dev->log_buf = NULL;
+	}
+
+	sfifo_free(&dev->log_fifo);
+
+	if (dev->internal_log.log) {
+		vfree(dev->internal_log.log);
+		dev->internal_log.log = NULL;
+	}
+}
+
+static int ssd_init_log(struct ssd_device *dev)
+{
+	struct ssd_log *log;
+	uint32_t off, size;
+	uint32_t len = 0;
+	int ret = 0;
+
+	mutex_init(&dev->internal_log_mutex);
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20))
+	INIT_WORK(&dev->log_work, ssd_log_worker, dev);
+#else
+	INIT_WORK(&dev->log_work, ssd_log_worker);
+#endif
+
+	off = dev->rom_info.log_base;
+	size = dev->rom_info.log_sz;
+
+	dev->internal_log.log = vmalloc(size);
+	if (!dev->internal_log.log) {
+		ret = -ENOMEM;
+		goto out_alloc_log;
+	}
+
+	ret = sfifo_alloc(&dev->log_fifo, SSD_LOG_FIFO_SZ, sizeof(struct ssd_log_entry));
+	if (ret < 0) {
+		goto out_alloc_log_fifo;
+	}
+
+	if (dev->protocol_info.ver <= SSD_PROTOCOL_V3) {
+		return 0;
+	}
+
+	log = (struct ssd_log *)dev->internal_log.log;
+	while (len < size) {
+		ret = ssd_spi_read(dev, log, off, sizeof(struct ssd_log));
+		if (ret) {
+			goto out_read_log;
+		}
+
+		if (log->ctrl_idx == 0xff) {
+			break;
+		}
+
+		dev->internal_log.nr_log++;
+		log++;
+		len += sizeof(struct ssd_log);
+		off += sizeof(struct ssd_log);
+	}
+
+	return 0;
+
+out_read_log:
+	sfifo_free(&dev->log_fifo);
+out_alloc_log_fifo:
+	vfree(dev->internal_log.log);
+	dev->internal_log.log = NULL;
+	dev->internal_log.nr_log = 0;
+out_alloc_log:
+	/* skip error if not in standard mode */
+	if (mode != SSD_DRV_MODE_STANDARD) {
+		ret = 0;
+	}
+	return ret;
+}
+
+/* work queue */
+static void ssd_stop_workq(struct ssd_device *dev)
+{
+	test_and_clear_bit(SSD_INIT_WORKQ, &dev->state);
+	flush_workqueue(dev->workq);
+}
+
+static void ssd_start_workq(struct ssd_device *dev)
+{
+	(void)test_and_set_bit(SSD_INIT_WORKQ, &dev->state);
+
+	/* log ? */
+	queue_work(dev->workq, &dev->log_work);
+}
+
+static void ssd_cleanup_workq(struct ssd_device *dev)
+{
+	flush_workqueue(dev->workq);
+	destroy_workqueue(dev->workq);
+	dev->workq = NULL;
+}
+
+static int ssd_init_workq(struct ssd_device *dev)
+{
+	int ret = 0;
+	
+	dev->workq = create_singlethread_workqueue(dev->name);
+	if (!dev->workq) {
+		ret = -ESRCH;
+		goto out;
+	}
+
+out:
+	return ret;
+}
+
+/* rom */
+static int ssd_init_rom_info(struct ssd_device *dev)
+{
+	uint32_t val;
+
+	mutex_init(&dev->spi_mutex);
+	mutex_init(&dev->i2c_mutex);
+
+	if (dev->protocol_info.ver < SSD_PROTOCOL_V3) {
+		/* fix bug: read data to clear status */
+		(void)ssd_reg32_read(dev->ctrlp + SSD_SPI_REG_RDATA);
+
+		dev->rom_info.size = SSD_ROM_SIZE;
+		dev->rom_info.block_size = SSD_ROM_BLK_SIZE;
+		dev->rom_info.page_size = SSD_ROM_PAGE_SIZE;
+
+		dev->rom_info.bridge_fw_base = SSD_ROM_BRIDGE_FW_BASE;
+		dev->rom_info.bridge_fw_sz = SSD_ROM_BRIDGE_FW_SIZE;
+		dev->rom_info.nr_bridge_fw = SSD_ROM_NR_BRIDGE_FW;
+
+		dev->rom_info.ctrl_fw_base = SSD_ROM_CTRL_FW_BASE;
+		dev->rom_info.ctrl_fw_sz = SSD_ROM_CTRL_FW_SIZE;
+		dev->rom_info.nr_ctrl_fw = SSD_ROM_NR_CTRL_FW;
+
+		dev->rom_info.log_sz = SSD_ROM_LOG_SZ;
+
+		dev->rom_info.vp_base = SSD_ROM_VP_BASE;
+		dev->rom_info.label_base = SSD_ROM_LABEL_BASE;
+	} else if (dev->protocol_info.ver < SSD_PROTOCOL_V3_2) {
+		val = ssd_reg32_read(dev->ctrlp + SSD_ROM_INFO_REG);
+		dev->rom_info.size = 0x100000 * (1U << (val & 0xFF));
+		dev->rom_info.block_size = 0x10000 * (1U << ((val>>8) & 0xFF));
+		dev->rom_info.page_size = (val>>16) & 0xFFFF;
+
+		val = ssd_reg32_read(dev->ctrlp + SSD_ROM_BRIDGE_FW_INFO_REG);
+		dev->rom_info.bridge_fw_base = dev->rom_info.block_size * (val & 0xFFFF);
+		dev->rom_info.bridge_fw_sz = dev->rom_info.block_size * ((val>>16) & 0x3FFF);
+		dev->rom_info.nr_bridge_fw = ((val >> 30) & 0x3) + 1;
+
+		val = ssd_reg32_read(dev->ctrlp + SSD_ROM_CTRL_FW_INFO_REG);
+		dev->rom_info.ctrl_fw_base = dev->rom_info.block_size * (val & 0xFFFF);
+		dev->rom_info.ctrl_fw_sz = dev->rom_info.block_size * ((val>>16) & 0x3FFF);
+		dev->rom_info.nr_ctrl_fw = ((val >> 30) & 0x3) + 1;
+
+		dev->rom_info.bm_fw_base = dev->rom_info.ctrl_fw_base + (dev->rom_info.nr_ctrl_fw * dev->rom_info.ctrl_fw_sz);
+		dev->rom_info.bm_fw_sz = SSD_PV3_ROM_BM_FW_SZ;
+		dev->rom_info.nr_bm_fw = SSD_PV3_ROM_NR_BM_FW;
+
+		dev->rom_info.log_base = dev->rom_info.bm_fw_base + (dev->rom_info.nr_bm_fw * dev->rom_info.bm_fw_sz);
+		dev->rom_info.log_sz = SSD_ROM_LOG_SZ;
+
+		dev->rom_info.smart_base = dev->rom_info.log_base + dev->rom_info.log_sz;
+		dev->rom_info.smart_sz = SSD_PV3_ROM_SMART_SZ;
+		dev->rom_info.nr_smart = SSD_PV3_ROM_NR_SMART;
+
+		val = ssd_reg32_read(dev->ctrlp + SSD_ROM_VP_INFO_REG);
+		dev->rom_info.vp_base = dev->rom_info.block_size * val;
+		dev->rom_info.label_base = dev->rom_info.vp_base + dev->rom_info.block_size;
+		if (dev->rom_info.label_base >= dev->rom_info.size) {
+			dev->rom_info.label_base = dev->rom_info.vp_base - dev->rom_info.block_size;
+		}
+	} else {
+		val = ssd_reg32_read(dev->ctrlp + SSD_ROM_INFO_REG);
+		dev->rom_info.size = 0x100000 * (1U << (val & 0xFF));
+		dev->rom_info.block_size = 0x10000 * (1U << ((val>>8) & 0xFF));
+		dev->rom_info.page_size = (val>>16) & 0xFFFF;
+
+		val = ssd_reg32_read(dev->ctrlp + SSD_ROM_BRIDGE_FW_INFO_REG);
+		dev->rom_info.bridge_fw_base = dev->rom_info.block_size * (val & 0xFFFF);
+		dev->rom_info.bridge_fw_sz = dev->rom_info.block_size * ((val>>16) & 0x3FFF);
+		dev->rom_info.nr_bridge_fw = ((val >> 30) & 0x3) + 1;
+
+		val = ssd_reg32_read(dev->ctrlp + SSD_ROM_CTRL_FW_INFO_REG);
+		dev->rom_info.ctrl_fw_base = dev->rom_info.block_size * (val & 0xFFFF);
+		dev->rom_info.ctrl_fw_sz = dev->rom_info.block_size * ((val>>16) & 0x3FFF);
+		dev->rom_info.nr_ctrl_fw = ((val >> 30) & 0x3) + 1;
+
+		val = ssd_reg32_read(dev->ctrlp + SSD_ROM_VP_INFO_REG);
+		dev->rom_info.vp_base = dev->rom_info.block_size * val;
+		dev->rom_info.label_base = dev->rom_info.vp_base - SSD_PV3_2_ROM_SEC_SZ;
+
+		dev->rom_info.nr_smart = SSD_PV3_ROM_NR_SMART;
+		dev->rom_info.smart_sz = SSD_PV3_2_ROM_SEC_SZ;
+		dev->rom_info.smart_base = dev->rom_info.label_base - (dev->rom_info.smart_sz * dev->rom_info.nr_smart);
+		if (dev->rom_info.smart_sz > dev->rom_info.block_size) {
+			dev->rom_info.smart_sz = dev->rom_info.block_size;
+		}
+
+		dev->rom_info.log_sz = SSD_PV3_2_ROM_LOG_SZ;
+		dev->rom_info.log_base = dev->rom_info.smart_base - dev->rom_info.log_sz;
+	}
+
+	return ssd_init_spi(dev);
+}
+
+/* smart */
+static int ssd_update_smart(struct ssd_device *dev, struct ssd_smart *smart)
+{
+	struct timeval tv;
+	uint64_t run_time;
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,27))
+	struct hd_struct *part;
+	int cpu;
+#endif
+	int i, j;
+	int ret = 0;
+
+	if (!test_bit(SSD_INIT_BD, &dev->state)) {
+		return 0;
+	}
+
+	do_gettimeofday(&tv);
+	if ((uint64_t)tv.tv_sec < dev->uptime) {
+		run_time = 0;
+	} else {
+		run_time = tv.tv_sec - dev->uptime;
+	}
+
+	/* avoid frequently update */
+	if (run_time >= 60) {
+		ret = 1;
+	}
+
+	/* io stat */
+	smart->io_stat.run_time += run_time;
+
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,27))
+	cpu = part_stat_lock();
+	part = &dev->gd->part0;
+	part_round_stats(cpu, part);
+	part_stat_unlock();
+
+	smart->io_stat.nr_read += part_stat_read(part, ios[READ]);
+	smart->io_stat.nr_write += part_stat_read(part, ios[WRITE]);
+	smart->io_stat.rsectors += part_stat_read(part, sectors[READ]);
+	smart->io_stat.wsectors += part_stat_read(part, sectors[WRITE]);
+#elif (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,14))
+	preempt_disable();
+	disk_round_stats(dev->gd);
+	preempt_enable();
+
+	smart->io_stat.nr_read += disk_stat_read(dev->gd, ios[READ]);
+	smart->io_stat.nr_write += disk_stat_read(dev->gd, ios[WRITE]);
+	smart->io_stat.rsectors += disk_stat_read(dev->gd, sectors[READ]);
+	smart->io_stat.wsectors += disk_stat_read(dev->gd, sectors[WRITE]);
+#else
+	preempt_disable();
+	disk_round_stats(dev->gd);
+	preempt_enable();
+
+	smart->io_stat.nr_read += disk_stat_read(dev->gd, reads);
+	smart->io_stat.nr_write += disk_stat_read(dev->gd, writes);
+	smart->io_stat.rsectors += disk_stat_read(dev->gd, read_sectors);
+	smart->io_stat.wsectors += disk_stat_read(dev->gd, write_sectors);
+#endif
+
+	smart->io_stat.nr_to += atomic_read(&dev->tocnt);
+
+	for (i=0; i<dev->nr_queue; i++) {
+		smart->io_stat.nr_rwerr += dev->queue[i].io_stat.nr_rwerr;
+		smart->io_stat.nr_ioerr += dev->queue[i].io_stat.nr_ioerr;
+	}
+
+	for (i=0; i<dev->nr_queue; i++) {
+		for (j=0; j<SSD_ECC_MAX_FLIP; j++) {
+			smart->ecc_info.bitflip[j] += dev->queue[i].ecc_info.bitflip[j];
+		}
+	}
+
+	//dev->uptime = tv.tv_sec;
+
+	return ret;
+}
+
+static int ssd_clear_smart(struct ssd_device *dev)
+{
+	struct timeval tv;
+	uint64_t sversion;
+	uint32_t off, length;
+	int i;
+	int ret;
+
+	if (dev->protocol_info.ver <= SSD_PROTOCOL_V3) {
+		return 0;
+	}
+
+	/* clear smart */
+	off = dev->rom_info.smart_base;
+	length = dev->rom_info.smart_sz * dev->rom_info.nr_smart;
+
+	ret = ssd_spi_erase(dev, off, length);
+	if (ret) {
+		hio_warn("%s: info erase: failed\n", dev->name);
+		goto out;
+	}
+
+	sversion = dev->smart.version;
+
+	memset(&dev->smart, 0, sizeof(struct ssd_smart));
+	dev->smart.version = sversion + 1;
+	dev->smart.magic = SSD_SMART_MAGIC;
+
+	/* clear all tmp acc */
+	for (i=0; i<dev->nr_queue; i++) {
+		memset(&(dev->queue[i].io_stat), 0, sizeof(struct ssd_io_stat));
+		memset(&(dev->queue[i].ecc_info), 0, sizeof(struct ssd_ecc_info));
+	}
+
+	atomic_set(&dev->tocnt, 0);
+
+	/* clear tmp log info */
+	memset(&dev->log_info, 0, sizeof(struct ssd_log_info));
+
+	do_gettimeofday(&tv);
+	dev->uptime = tv.tv_sec;
+
+	/* clear alarm ? */
+	//ssd_clear_alarm(dev);
+out:
+	return ret;
+}
+
+static int ssd_save_smart(struct ssd_device *dev)
+{
+	uint32_t off, size;
+	int i;
+	int ret = 0;
+
+	if (unlikely(mode != SSD_DRV_MODE_STANDARD))
+		return 0;
+
+	if (dev->protocol_info.ver <= SSD_PROTOCOL_V3) {
+		return 0;
+	}
+
+	if (!ssd_update_smart(dev, &dev->smart)) {
+		return 0;
+	}
+
+	dev->smart.version++;
+
+	for (i=0; i<dev->rom_info.nr_smart; i++) {
+		off = dev->rom_info.smart_base + (dev->rom_info.smart_sz * i);
+		size = dev->rom_info.smart_sz;
+
+		ret = ssd_spi_erase(dev, off, size);
+		if (ret) {
+			hio_warn("%s: info erase failed\n", dev->name);
+			goto out;
+		}
+
+		size = sizeof(struct ssd_smart);
+
+		ret = ssd_spi_write(dev, &dev->smart, off, size);
+		if (ret) {
+			hio_warn("%s: info write failed\n", dev->name);
+			goto out;
+		}
+
+		//xx
+	}
+
+out:
+	return ret;
+}
+
+static int ssd_init_smart(struct ssd_device *dev)
+{
+	struct ssd_smart *smart;
+	struct timeval tv;
+	uint32_t off, size;
+	int i;
+	int ret = 0;
+
+	do_gettimeofday(&tv);
+	dev->uptime = tv.tv_sec;
+
+	if (dev->protocol_info.ver <= SSD_PROTOCOL_V3) {
+		return 0;
+	}
+
+	smart = kmalloc(sizeof(struct ssd_smart) * SSD_ROM_NR_SMART_MAX, GFP_KERNEL);
+	if (!smart) {
+		ret = -ENOMEM;
+		goto out_nomem;
+	}
+
+	memset(&dev->smart, 0, sizeof(struct ssd_smart));
+
+	/* read smart */
+	for (i=0; i<dev->rom_info.nr_smart; i++) {
+		memset(&smart[i], 0, sizeof(struct ssd_smart));
+
+		off = dev->rom_info.smart_base + (dev->rom_info.smart_sz * i);
+		size = sizeof(struct ssd_smart);
+
+		ret = ssd_spi_read(dev, &smart[i], off, size);
+		if (ret) {
+			hio_warn("%s: info read failed\n", dev->name);
+			goto out;
+		}
+
+		if (smart[i].magic != SSD_SMART_MAGIC) {
+			smart[i].magic = 0;
+			smart[i].version = 0;
+			continue;
+		}
+
+		if (smart[i].version > dev->smart.version) {
+			memcpy(&dev->smart, &smart[i], sizeof(struct ssd_smart));
+		}
+	}
+
+	if (dev->smart.magic != SSD_SMART_MAGIC) {
+		/* first time power up */
+		dev->smart.magic = SSD_SMART_MAGIC;
+		dev->smart.version = 1;
+	}
+
+	/* check log info */
+	{
+		struct ssd_log_info log_info;
+		struct ssd_log *log = (struct ssd_log *)dev->internal_log.log;
+
+		memset(&log_info, 0, sizeof(struct ssd_log_info));
+
+		while (log_info.nr_log < dev->internal_log.nr_log) {
+			/* skip the volatile log info */
+			if (SSD_LOG_SEU_FAULT != log->le.event && SSD_LOG_SEU_FAULT1 != log->le.event) {
+				log_info.stat[ssd_parse_log(dev, log, 0)]++;
+			}
+
+			log_info.nr_log++;
+			log++;
+		}
+
+		/* check */
+		for (i=(SSD_LOG_NR_LEVEL-1); i>=0; i--) {
+			if (log_info.stat[i] > dev->smart.log_info.stat[i]) {
+				/* unclean */
+				memcpy(&dev->smart.log_info, &log_info, sizeof(struct ssd_log_info));
+				dev->smart.version++;
+				break;
+			}
+		}
+	}
+
+	for (i=0; i<dev->rom_info.nr_smart; i++) {
+		if (smart[i].magic == SSD_SMART_MAGIC && smart[i].version == dev->smart.version) {
+			continue;
+		}
+
+		off = dev->rom_info.smart_base + (dev->rom_info.smart_sz * i);
+		size = dev->rom_info.smart_sz;
+
+		ret = ssd_spi_erase(dev, off, size);
+		if (ret) {
+			hio_warn("%s: info erase failed\n", dev->name);
+			goto out;
+		}
+
+		size = sizeof(struct ssd_smart);
+		ret = ssd_spi_write(dev, &dev->smart, off, size);
+		if (ret) {
+			hio_warn("%s: info write failed\n", dev->name);
+			goto out;
+		}
+
+		//xx
+	}
+
+	/* sync smart with alarm led */
+	if (dev->smart.io_stat.nr_to || dev->smart.io_stat.nr_rwerr || dev->smart.log_info.stat[SSD_LOG_LEVEL_ERR]) {
+		hio_warn("%s: some fault found in the history info\n", dev->name);
+		ssd_set_alarm(dev);
+	}
+
+out:
+	kfree(smart);
+out_nomem:
+	/* skip error if not in standard mode */
+	if (mode != SSD_DRV_MODE_STANDARD) {
+		ret = 0;
+	}
+	return ret;
+}
+
+/* bm */
+static int __ssd_bm_get_version(struct ssd_device *dev, uint16_t *ver)
+{
+	struct ssd_bm_manufacturer_data bm_md = {0};
+	uint16_t sc_id = SSD_BM_SYSTEM_DATA_SUBCLASS_ID;
+	uint8_t cmd;
+	int ret = 0;
+
+	if (!dev || !ver) {
+		return -EINVAL;
+	}
+
+	mutex_lock(&dev->bm_mutex);
+
+	cmd = SSD_BM_DATA_FLASH_SUBCLASS_ID;
+	ret = ssd_smbus_write_word(dev, SSD_BM_SLAVE_ADDRESS, cmd, (uint8_t *)&sc_id);
+	if (ret) {
+		goto out;
+	}
+
+	cmd = SSD_BM_DATA_FLASH_SUBCLASS_ID_PAGE1;
+	ret = ssd_smbus_read_block(dev, SSD_BM_SLAVE_ADDRESS, cmd, sizeof(struct ssd_bm_manufacturer_data), (uint8_t *)&bm_md);
+	if (ret) {
+		goto out;
+	}
+
+	if (bm_md.firmware_ver & 0xF000) {
+		ret = -EIO;
+		goto out;
+	}
+
+	*ver = bm_md.firmware_ver;
+
+out:
+	mutex_unlock(&dev->bm_mutex);
+	return ret;
+}
+
+static int ssd_bm_get_version(struct ssd_device *dev, uint16_t *ver)
+{
+	uint16_t tmp = 0;
+	int i = SSD_BM_RETRY_MAX;
+	int ret = 0;
+
+	while (i-- > 0) {
+		ret = __ssd_bm_get_version(dev, &tmp);
+		if (!ret) {
+			break;
+		}
+	}
+	if (ret) {
+		return ret;
+	}
+
+	*ver = tmp;
+
+	return 0;
+}
+
+static int __ssd_bm_nr_cap(struct ssd_device *dev, int *nr_cap)
+{
+	struct ssd_bm_configuration_registers bm_cr;
+	uint16_t sc_id = SSD_BM_CONFIGURATION_REGISTERS_ID;
+	uint8_t cmd;
+	int ret;
+
+	mutex_lock(&dev->bm_mutex);
+
+	cmd = SSD_BM_DATA_FLASH_SUBCLASS_ID;
+	ret = ssd_smbus_write_word(dev, SSD_BM_SLAVE_ADDRESS, cmd, (uint8_t *)&sc_id);
+	if (ret) {
+		goto out;
+	}
+
+	cmd = SSD_BM_DATA_FLASH_SUBCLASS_ID_PAGE1;
+	ret = ssd_smbus_read_block(dev, SSD_BM_SLAVE_ADDRESS, cmd, sizeof(struct ssd_bm_configuration_registers), (uint8_t *)&bm_cr);
+	if (ret) {
+		goto out;
+	}
+
+	if (bm_cr.operation_cfg.cc == 0 || bm_cr.operation_cfg.cc > 4) {
+		ret = -EIO;
+		goto out;
+	}
+
+	*nr_cap = bm_cr.operation_cfg.cc + 1;
+
+out:
+	mutex_unlock(&dev->bm_mutex);
+	return ret;
+}
+
+static int ssd_bm_nr_cap(struct ssd_device *dev, int *nr_cap)
+{
+	int tmp = 0;
+	int i = SSD_BM_RETRY_MAX;
+	int ret = 0;
+
+	while (i-- > 0) {
+		ret = __ssd_bm_nr_cap(dev, &tmp);
+		if (!ret) {
+			break;
+		}
+	}
+	if (ret) {
+		return ret;
+	}
+
+	*nr_cap = tmp;
+
+	return 0;
+}
+
+static int ssd_bm_enter_cap_learning(struct ssd_device *dev)
+{
+	uint16_t buf = SSD_BM_ENTER_CAP_LEARNING;
+	uint8_t cmd = SSD_BM_MANUFACTURERACCESS;
+	int ret;
+
+	ret = ssd_smbus_write_word(dev, SSD_BM_SLAVE_ADDRESS, cmd, (uint8_t *)&buf);
+	if (ret) {
+		goto out;
+	}
+
+out:
+	return ret;
+}
+
+static int ssd_bm_get_sfstatus(struct ssd_device *dev, uint16_t *status)
+{
+	uint16_t val = 0;
+	uint8_t cmd = SSD_BM_SAFETYSTATUS;
+	int ret;
+
+	ret = ssd_smbus_read_word(dev, SSD_BM_SLAVE_ADDRESS, cmd, (uint8_t *)&val);
+	if (ret) {
+		goto out;
+	}
+
+	*status = val;
+out:
+	return ret;
+}
+
+static int ssd_bm_get_opstatus(struct ssd_device *dev, uint16_t *status)
+{
+	uint16_t val = 0;
+	uint8_t cmd = SSD_BM_OPERATIONSTATUS;
+	int ret;
+
+	ret = ssd_smbus_read_word(dev, SSD_BM_SLAVE_ADDRESS, cmd, (uint8_t *)&val);
+	if (ret) {
+		goto out;
+	}
+
+	*status = val;
+out:
+	return ret;
+}
+ 
+static int ssd_get_bmstruct(struct ssd_device *dev, struct ssd_bm *bm_status_out)
+{
+	struct sbs_cmd *bm_sbs = ssd_bm_sbs;
+	struct ssd_bm bm_status;
+	uint8_t buf[2] = {0, };
+	uint16_t val = 0;
+	uint16_t cval;
+	int ret = 0;
+
+	memset(&bm_status, 0, sizeof(struct ssd_bm));
+
+	while (bm_sbs->desc != NULL) {
+		switch (bm_sbs->size) {
+			case SBS_SIZE_BYTE:
+				ret = ssd_smbus_read_byte(dev, SSD_BM_SLAVE_ADDRESS, bm_sbs->cmd, buf);
+				if (ret) {
+					//printf("Error: smbus read byte %#x\n", bm_sbs->cmd);
+					goto out;
+				}
+				val = buf[0];
+				break;
+			case SBS_SIZE_WORD:
+				ret = ssd_smbus_read_word(dev, SSD_BM_SLAVE_ADDRESS, bm_sbs->cmd, (uint8_t *)&val);
+				if (ret) {
+					//printf("Error: smbus read word %#x\n", bm_sbs->cmd);
+					goto out;
+				}
+				//val = *(uint16_t *)buf;
+				break;
+			default:
+				ret = -1;
+				goto out;
+				break;
+		}
+
+		switch (bm_sbs->unit) {
+			case SBS_UNIT_VALUE:
+				*(uint16_t *)bm_var(&bm_status, bm_sbs->off) = val & bm_sbs->mask;
+				break;
+			case SBS_UNIT_TEMPERATURE:
+				cval = (uint16_t)(val - 2731) / 10;
+				*(uint16_t *)bm_var(&bm_status, bm_sbs->off) = cval;
+				break;
+			case SBS_UNIT_VOLTAGE:
+				*(uint16_t *)bm_var(&bm_status, bm_sbs->off) = val;
+				break;
+			case SBS_UNIT_CURRENT:
+				*(uint16_t *)bm_var(&bm_status, bm_sbs->off) = val;
+				break;
+			case SBS_UNIT_ESR:
+				*(uint16_t *)bm_var(&bm_status, bm_sbs->off) = val;
+				break;
+			case SBS_UNIT_PERCENT:
+				*(uint16_t *)bm_var(&bm_status, bm_sbs->off) = val;
+				break;
+			case SBS_UNIT_CAPACITANCE:
+				*(uint16_t *)bm_var(&bm_status, bm_sbs->off) = val;
+				break;
+			default:
+				ret = -1;
+				goto out;
+				break;
+		}
+
+		bm_sbs++;
+	}
+
+	memcpy(bm_status_out, &bm_status, sizeof(struct ssd_bm));
+
+out:
+	return ret;
+}
+
+static int __ssd_bm_status(struct ssd_device *dev, int *status)
+{
+	struct ssd_bm bm_status = {0};
+	int nr_cap = 0;
+	int i;
+	int ret = 0;
+
+	ret = ssd_get_bmstruct(dev, &bm_status);
+	if (ret) {
+		goto out;
+	}
+
+	/* capacitor voltage */
+	ret = ssd_bm_nr_cap(dev, &nr_cap);
+	if (ret) {
+		goto out;
+	}
+
+	for (i=0; i<nr_cap; i++) {
+		if (bm_status.cap_volt[i] < SSD_BM_CAP_VOLT_MIN) {
+			*status = SSD_BMSTATUS_WARNING;
+			goto out;
+		}
+	}
+
+	/* Safety Status */
+	if (bm_status.sf_status) {
+		*status = SSD_BMSTATUS_WARNING;
+		goto out;
+	}
+
+	/* charge status */
+	if (!((bm_status.op_status >> 12) & 0x1)) {
+		*status = SSD_BMSTATUS_CHARGING;
+	}else{
+		*status = SSD_BMSTATUS_OK;
+	}
+
+out:
+	return ret;
+}
+
+static void ssd_set_flush_timeout(struct ssd_device *dev, int mode);
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20))
+static void ssd_bm_worker(void *data)
+{
+	struct ssd_device *dev = (struct ssd_device *)data;
+#else
+static void ssd_bm_worker(struct work_struct *work)
+{
+	struct ssd_device *dev = container_of(work, struct ssd_device, bm_work);
+#endif
+
+	uint16_t opstatus;
+	int ret = 0;
+
+	if (mode != SSD_DRV_MODE_STANDARD) {
+		return;
+	}
+
+	if (dev->protocol_info.ver < SSD_PROTOCOL_V3_1_1) {
+		return;
+	}
+
+	if (dev->hw_info_ext.plp_type != SSD_PLP_SCAP) {
+		return;
+	}
+
+	ret = ssd_bm_get_opstatus(dev, &opstatus);
+	if (ret) {
+		hio_warn("%s: get bm operationstatus failed\n", dev->name);
+		return;
+	}
+
+	/* need cap learning ? */
+	if (!(opstatus & 0xF0)) {
+		ret = ssd_bm_enter_cap_learning(dev);
+		if (ret) {
+			hio_warn("%s: enter capacitance learning failed\n", dev->name);
+			return;
+		}
+	}
+}
+
+static void ssd_bm_routine_start(void *data)
+{
+	struct ssd_device *dev;
+
+	if (!data) {
+		return;
+	}
+	dev = data;
+
+	if (test_bit(SSD_INIT_WORKQ, &dev->state)) {
+		if (dev->protocol_info.ver < SSD_PROTOCOL_V3_2) {
+			queue_work(dev->workq, &dev->bm_work);
+		} else {
+			queue_work(dev->workq, &dev->capmon_work);
+		}
+	}
+}
+
+/* CAP */
+static int ssd_do_cap_learn(struct ssd_device *dev, uint32_t *cap)
+{
+	uint32_t u1, u2, t;
+	uint16_t val = 0;
+	int wait = 0;
+	int ret = 0;
+
+	if (dev->protocol_info.ver < SSD_PROTOCOL_V3_2) {
+		*cap = 0;
+		return 0;
+	}
+
+	if (dev->hw_info_ext.form_factor == SSD_FORM_FACTOR_FHHL && dev->hw_info.pcb_ver < 'B') {
+		*cap = 0;
+		return 0;
+	}
+
+	/* make sure the lm80 voltage value is updated */
+	msleep(SSD_LM80_CONV_INTERVAL);
+
+	/* check if full charged */
+	wait = 0;
+	for (;;) {
+		ret = ssd_smbus_read_word(dev, SSD_SENSOR_LM80_SADDRESS, SSD_PL_CAP_U1, (uint8_t *)&val);
+		if (ret) {
+			if (!test_and_set_bit(SSD_HWMON_SENSOR(SSD_SENSOR_LM80), &dev->hwmon)) {
+				ssd_gen_swlog(dev, SSD_LOG_SENSOR_FAULT, SSD_SENSOR_LM80_SADDRESS);
+			}
+			goto out;
+		}
+		u1 = SSD_LM80_CONVERT_VOLT(u16_swap(val));
+		if (SSD_PL_CAP_VOLT(u1) >= SSD_PL_CAP_VOLT_FULL) {
+			break;
+		}
+
+		wait++;
+		if (wait > SSD_PL_CAP_CHARGE_MAX_WAIT) {
+			ret = -ETIMEDOUT;
+			goto out;
+		}
+		msleep(SSD_PL_CAP_CHARGE_WAIT);
+	}
+
+	ret = ssd_smbus_read_word(dev, SSD_SENSOR_LM80_SADDRESS, SSD_PL_CAP_U2, (uint8_t *)&val);
+	if (ret) {
+		if (!test_and_set_bit(SSD_HWMON_SENSOR(SSD_SENSOR_LM80), &dev->hwmon)) {
+			ssd_gen_swlog(dev, SSD_LOG_SENSOR_FAULT, SSD_SENSOR_LM80_SADDRESS);
+		}
+		goto out;
+	}
+	u2 = SSD_LM80_CONVERT_VOLT(u16_swap(val));
+
+	if (u1 == u2) {
+		ret = -EINVAL;
+		goto out;
+	}
+
+	/* enter cap learn */
+	ssd_reg32_write(dev->ctrlp + SSD_PL_CAP_LEARN_REG, 0x1);
+	
+	wait = 0;
+	for (;;) {
+		msleep(SSD_PL_CAP_LEARN_WAIT);
+
+		t = ssd_reg32_read(dev->ctrlp + SSD_PL_CAP_LEARN_REG);
+		if (!((t >> 1) & 0x1)) {
+			break;
+		}
+
+		wait++;
+		if (wait > SSD_PL_CAP_LEARN_MAX_WAIT) {
+			ret = -ETIMEDOUT;
+			goto out;
+		}
+	}
+
+	if ((t >> 4) & 0x1) {
+		ret = -ETIMEDOUT;
+		goto out;
+	}
+
+	t = (t >> 8);
+	if (0 == t) {
+		ret = -EINVAL;
+		goto out;
+	}
+
+	*cap = SSD_PL_CAP_LEARN(u1, u2, t);
+
+out:
+	return ret;
+}
+
+static int ssd_cap_learn(struct ssd_device *dev, uint32_t *cap)
+{
+	int ret = 0;
+
+	if (!dev || !cap) {
+		return -EINVAL;
+	}
+
+	mutex_lock(&dev->bm_mutex);
+
+	ssd_stop_workq(dev);
+
+	ret = ssd_do_cap_learn(dev, cap);
+	if (ret) {
+		ssd_gen_swlog(dev, SSD_LOG_CAP_LEARN_FAULT, 0);
+		goto out;
+	}
+
+	ssd_gen_swlog(dev, SSD_LOG_CAP_STATUS, *cap);
+
+out:
+	ssd_start_workq(dev);
+	mutex_unlock(&dev->bm_mutex);
+
+	return ret;
+}
+
+static int ssd_check_pl_cap(struct ssd_device *dev)
+{
+	uint32_t u1;
+	uint16_t val = 0;
+	uint8_t low = 0;
+	int wait = 0;
+	int ret = 0;
+
+	if (dev->protocol_info.ver < SSD_PROTOCOL_V3_2) {
+		return 0;
+	}
+
+	if (dev->hw_info_ext.form_factor == SSD_FORM_FACTOR_FHHL && dev->hw_info.pcb_ver < 'B') {
+		return 0;
+	}
+
+	/* cap ready ? */
+	wait = 0;
+	for (;;) {
+		ret = ssd_smbus_read_word(dev, SSD_SENSOR_LM80_SADDRESS, SSD_PL_CAP_U1, (uint8_t *)&val);
+		if (ret) {
+			if (!test_and_set_bit(SSD_HWMON_SENSOR(SSD_SENSOR_LM80), &dev->hwmon)) {
+				ssd_gen_swlog(dev, SSD_LOG_SENSOR_FAULT, SSD_SENSOR_LM80_SADDRESS);
+			}
+			goto out;
+		}
+		u1 = SSD_LM80_CONVERT_VOLT(u16_swap(val));
+		if (SSD_PL_CAP_VOLT(u1) >= SSD_PL_CAP_VOLT_READY) {
+			break;
+		}
+
+		wait++;
+		if (wait > SSD_PL_CAP_CHARGE_MAX_WAIT) {
+			ret = -ETIMEDOUT;
+			ssd_gen_swlog(dev, SSD_LOG_CAP_VOLT_FAULT, SSD_PL_CAP_VOLT(u1));
+			goto out;
+		}
+		msleep(SSD_PL_CAP_CHARGE_WAIT);
+	}
+
+	low = ssd_lm80_limit[SSD_LM80_IN_CAP].low;
+	ret = ssd_smbus_write_byte(dev, SSD_SENSOR_LM80_SADDRESS, SSD_LM80_REG_IN_MIN(SSD_LM80_IN_CAP), &low);
+	if (ret) {
+		goto out;
+	}
+
+	/* enable cap INx */
+	ret = ssd_lm80_enable_in(dev, SSD_SENSOR_LM80_SADDRESS, SSD_LM80_IN_CAP);
+	if (ret) {
+		if (!test_and_set_bit(SSD_HWMON_SENSOR(SSD_SENSOR_LM80), &dev->hwmon)) {
+			ssd_gen_swlog(dev, SSD_LOG_SENSOR_FAULT, SSD_SENSOR_LM80_SADDRESS);
+		}
+		goto out;
+	}
+
+out:
+	/* skip error if not in standard mode */
+	if (mode != SSD_DRV_MODE_STANDARD) {
+		ret = 0;
+	}
+	return ret;
+}
+
+static int ssd_check_pl_cap_fast(struct ssd_device *dev)
+{
+	uint32_t u1;
+	uint16_t val = 0;
+	int ret = 0;
+
+	if (dev->protocol_info.ver < SSD_PROTOCOL_V3_2) {
+		return 0;
+	}
+
+	if (dev->hw_info_ext.form_factor == SSD_FORM_FACTOR_FHHL && dev->hw_info.pcb_ver < 'B') {
+		return 0;
+	}
+
+	/* cap ready ? */
+	ret = ssd_smbus_read_word(dev, SSD_SENSOR_LM80_SADDRESS, SSD_PL_CAP_U1, (uint8_t *)&val);
+	if (ret) {
+		goto out;
+	}
+	u1 = SSD_LM80_CONVERT_VOLT(u16_swap(val));
+	if (SSD_PL_CAP_VOLT(u1) < SSD_PL_CAP_VOLT_READY) {
+		ret = 1;
+	}
+
+out:
+	return ret;
+}
+
+static int ssd_init_pl_cap(struct ssd_device *dev)
+{
+	int ret = 0;
+
+	/* set here: user write mode */
+	dev->user_wmode = wmode;
+	
+	mutex_init(&dev->bm_mutex);
+
+	if (dev->protocol_info.ver < SSD_PROTOCOL_V3_2) {
+		uint32_t val;
+		val = ssd_reg32_read(dev->ctrlp + SSD_BM_FAULT_REG);
+		if ((val >> 1) & 0x1) {
+			(void)test_and_set_bit(SSD_HWMON_PL_CAP(SSD_PL_CAP), &dev->hwmon);
+		}
+	} else {
+		ret = ssd_check_pl_cap(dev);
+		if (ret) {
+			(void)test_and_set_bit(SSD_HWMON_PL_CAP(SSD_PL_CAP), &dev->hwmon);
+		}
+	}
+
+	return 0;
+}
+
+/* label */
+static void __end_str(char *str, int len)
+{
+	int i;
+
+	for(i=0; i<len; i++) {
+		if (*(str+i) == '\0')
+			return;
+	}
+	*str = '\0';
+}
+
+static int ssd_init_label(struct ssd_device *dev)
+{
+	uint32_t off;
+	uint32_t size;
+	int ret;
+
+	/* label location */
+	off = dev->rom_info.label_base;
+
+	if (dev->protocol_info.ver < SSD_PROTOCOL_V3_2) {
+		size = sizeof(struct ssd_label);
+
+		/* read label */
+		ret = ssd_spi_read(dev, &dev->label, off, size);
+		if (ret) {
+			memset(&dev->label, 0, size);
+			goto out;
+		}
+
+		__end_str(dev->label.date, SSD_LABEL_FIELD_SZ);
+		__end_str(dev->label.sn, SSD_LABEL_FIELD_SZ);
+		__end_str(dev->label.part, SSD_LABEL_FIELD_SZ);
+		__end_str(dev->label.desc, SSD_LABEL_FIELD_SZ);
+		__end_str(dev->label.other, SSD_LABEL_FIELD_SZ);
+		__end_str(dev->label.maf, SSD_LABEL_FIELD_SZ);
+	} else {
+		size = sizeof(struct ssd_labelv3);
+
+		/* read label */
+		ret = ssd_spi_read(dev, &dev->labelv3, off, size);
+		if (ret) {
+			memset(&dev->labelv3, 0, size);
+			goto out;
+		}
+
+		__end_str(dev->labelv3.boardtype, SSD_LABEL_FIELD_SZ);
+		__end_str(dev->labelv3.barcode, SSD_LABEL_FIELD_SZ);
+		__end_str(dev->labelv3.item, SSD_LABEL_FIELD_SZ);
+		__end_str(dev->labelv3.description, SSD_LABEL_DESC_SZ);
+		__end_str(dev->labelv3.manufactured, SSD_LABEL_FIELD_SZ);
+		__end_str(dev->labelv3.vendorname, SSD_LABEL_FIELD_SZ);
+		__end_str(dev->labelv3.issuenumber, SSD_LABEL_FIELD_SZ);
+		__end_str(dev->labelv3.cleicode, SSD_LABEL_FIELD_SZ);
+		__end_str(dev->labelv3.bom, SSD_LABEL_FIELD_SZ);
+	}
+
+out:
+	/* skip error if not in standard mode */
+	if (mode != SSD_DRV_MODE_STANDARD) {
+		ret = 0;
+	}
+	return ret;
+}
+
+int ssd_get_label(struct block_device *bdev, struct ssd_label *label)
+{
+	struct ssd_device *dev;
+
+	if (!bdev || !label || !(bdev->bd_disk)) {
+		return -EINVAL;
+	}
+
+	dev = bdev->bd_disk->private_data;
+
+	if (dev->protocol_info.ver >= SSD_PROTOCOL_V3_2) {
+		memset(label, 0, sizeof(struct ssd_label));
+		memcpy(label->date, dev->labelv3.manufactured, SSD_LABEL_FIELD_SZ);
+		memcpy(label->sn, dev->labelv3.barcode, SSD_LABEL_FIELD_SZ);
+		memcpy(label->desc, dev->labelv3.boardtype, SSD_LABEL_FIELD_SZ);
+		memcpy(label->maf, dev->labelv3.vendorname, SSD_LABEL_FIELD_SZ);
+	} else {
+		memcpy(label, &dev->label, sizeof(struct ssd_label));
+	}
+
+	return 0;
+}
+
+static int __ssd_get_version(struct ssd_device *dev, struct ssd_version_info *ver)
+{
+	uint16_t bm_ver = 0;
+	int ret = 0;
+
+	if (dev->protocol_info.ver > SSD_PROTOCOL_V3 && dev->protocol_info.ver < SSD_PROTOCOL_V3_2) {
+		ret = ssd_bm_get_version(dev, &bm_ver);
+		if(ret){
+			goto out;
+		}
+	}
+
+	ver->bridge_ver = dev->hw_info.bridge_ver;
+	ver->ctrl_ver = dev->hw_info.ctrl_ver;
+	ver->bm_ver = bm_ver;
+	ver->pcb_ver = dev->hw_info.pcb_ver;
+	ver->upper_pcb_ver = dev->hw_info.upper_pcb_ver;
+
+out:
+	return ret;
+
+}
+
+int ssd_get_version(struct block_device *bdev, struct ssd_version_info *ver)
+{
+	struct ssd_device *dev;
+	int ret;
+
+	if (!bdev || !ver || !(bdev->bd_disk)) {
+		return -EINVAL;
+	}
+
+	dev = bdev->bd_disk->private_data;
+
+	mutex_lock(&dev->fw_mutex);
+	ret = __ssd_get_version(dev, ver);
+	mutex_unlock(&dev->fw_mutex);
+
+	return ret;
+}
+
+static int __ssd_get_temperature(struct ssd_device *dev, int *temp)
+{
+	uint64_t val;
+	uint32_t off;
+	int max = -300;
+	int cur;
+	int i;
+
+	if (dev->protocol_info.ver <= SSD_PROTOCOL_V3) {
+		*temp = 0;
+		return 0;
+	}
+
+	if (finject) {
+		if (dev->db_info.type == SSD_DEBUG_LOG && 
+			(dev->db_info.data.log.event == SSD_LOG_OVER_TEMP || 
+			dev->db_info.data.log.event == SSD_LOG_NORMAL_TEMP || 
+			dev->db_info.data.log.event == SSD_LOG_WARN_TEMP)) {
+			*temp = (int)dev->db_info.data.log.extra;
+			return 0;
+		}
+	}
+
+	for (i=0; i<dev->hw_info.nr_ctrl; i++) {
+		off = SSD_CTRL_TEMP_REG0 + i * sizeof(uint64_t);
+
+		val = ssd_reg_read(dev->ctrlp + off);
+		if (val == 0xffffffffffffffffull) {
+			continue;
+		}
+
+		cur = (int)CUR_TEMP(val);
+		if (cur >= max) {
+			max = cur;
+		}
+	}
+
+	*temp = max;
+
+	return 0;
+}
+
+int ssd_get_temperature(struct block_device *bdev, int *temp)
+{
+	struct ssd_device *dev;
+	int ret;
+
+	if (!bdev || !temp || !(bdev->bd_disk)) {
+		return -EINVAL;
+	}
+
+	dev = bdev->bd_disk->private_data;
+
+
+	mutex_lock(&dev->fw_mutex);
+	ret = __ssd_get_temperature(dev, temp);
+	mutex_unlock(&dev->fw_mutex);
+
+	return ret;
+}
+
+int ssd_set_otprotect(struct block_device *bdev, int otprotect)
+ {
+ 	struct ssd_device *dev;
+
+	if (!bdev || !(bdev->bd_disk)) {
+		return -EINVAL;
+	}
+
+	dev = bdev->bd_disk->private_data; 
+	ssd_set_ot_protect(dev, !!otprotect);
+
+	return 0;
+ }
+
+int ssd_bm_status(struct block_device *bdev, int *status)
+{
+	struct ssd_device *dev;
+	int ret = 0;
+
+	if (!bdev || !status || !(bdev->bd_disk)) {
+		return -EINVAL;
+	}
+
+	dev = bdev->bd_disk->private_data;
+
+	mutex_lock(&dev->fw_mutex);
+	if (dev->protocol_info.ver >= SSD_PROTOCOL_V3_2) {
+		if (test_bit(SSD_HWMON_PL_CAP(SSD_PL_CAP), &dev->hwmon)) {
+			*status = SSD_BMSTATUS_WARNING;
+		} else {
+			*status = SSD_BMSTATUS_OK;
+		}
+	} else if(dev->protocol_info.ver > SSD_PROTOCOL_V3) {
+		ret = __ssd_bm_status(dev, status);
+	} else {
+		*status = SSD_BMSTATUS_OK;
+	}
+	mutex_unlock(&dev->fw_mutex);
+
+	return ret;
+}
+
+int ssd_get_pciaddr(struct block_device *bdev, struct pci_addr *paddr)
+{
+	struct ssd_device *dev;
+
+	if (!bdev || !paddr || !bdev->bd_disk) {
+		return -EINVAL;
+	}
+
+	dev = bdev->bd_disk->private_data;
+
+	paddr->domain = pci_domain_nr(dev->pdev->bus);
+	paddr->bus = dev->pdev->bus->number;
+	paddr->slot = PCI_SLOT(dev->pdev->devfn);
+	paddr->func= PCI_FUNC(dev->pdev->devfn);
+
+	return 0;
+}
+
+/* acc */
+static int ssd_bb_acc(struct ssd_device *dev, struct ssd_acc_info *acc)
+{
+	uint32_t val;
+	int ctrl, chip;
+	
+	if (dev->protocol_info.ver < SSD_PROTOCOL_V3_1_1) {
+		return -EOPNOTSUPP;
+	}
+
+	acc->threshold_l1 = ssd_reg32_read(dev->ctrlp + SSD_BB_THRESHOLD_L1_REG);
+	if (0xffffffffull == acc->threshold_l1) {
+		return -EIO;
+	}
+	acc->threshold_l2 = ssd_reg32_read(dev->ctrlp + SSD_BB_THRESHOLD_L2_REG);
+	if (0xffffffffull == acc->threshold_l2) {
+		return -EIO;
+	}
+	acc->val = 0;
+
+	for (ctrl=0; ctrl<dev->hw_info.nr_ctrl; ctrl++) {
+		for (chip=0; chip<dev->hw_info.nr_chip; chip++) {
+			val = ssd_reg32_read(dev->ctrlp + SSD_BB_ACC_REG0 + (SSD_CTRL_REG_ZONE_SZ * ctrl) + (SSD_BB_ACC_REG_SZ * chip));
+			if (0xffffffffull == acc->val) {
+				return -EIO;
+			}
+			if (val > acc->val) {
+				acc->val = val;
+			}
+		}
+	}
+
+	return 0;
+}
+
+static int ssd_ec_acc(struct ssd_device *dev, struct ssd_acc_info *acc)
+{
+	uint32_t val;
+	int ctrl, chip;
+	
+	if (dev->protocol_info.ver < SSD_PROTOCOL_V3_1_1) {
+		return -EOPNOTSUPP;
+	}
+
+	acc->threshold_l1 = ssd_reg32_read(dev->ctrlp + SSD_EC_THRESHOLD_L1_REG);
+	if (0xffffffffull == acc->threshold_l1) {
+		return -EIO;
+	}
+	acc->threshold_l2 = ssd_reg32_read(dev->ctrlp + SSD_EC_THRESHOLD_L2_REG);
+	if (0xffffffffull == acc->threshold_l2) {
+		return -EIO;
+	}
+	acc->val = 0;
+
+	for (ctrl=0; ctrl<dev->hw_info.nr_ctrl; ctrl++) {
+		for (chip=0; chip<dev->hw_info.nr_chip; chip++) {
+			val = ssd_reg32_read(dev->ctrlp + SSD_EC_ACC_REG0 + (SSD_CTRL_REG_ZONE_SZ * ctrl) + (SSD_EC_ACC_REG_SZ * chip));
+			if (0xffffffffull == acc->val) {
+				return -EIO;
+			}
+
+			if (val > acc->val) {
+				acc->val = val;
+			}
+		}
+	}
+
+	return 0;
+}
+
+
+/* ram r&w */
+static int ssd_ram_read_4k(struct ssd_device *dev, void *buf, size_t length, loff_t ofs, int ctrl_idx)
+{
+	struct ssd_ram_op_msg *msg;
+	dma_addr_t buf_dma;
+	size_t len = length;
+	loff_t ofs_w = ofs;
+	int ret = 0;
+
+	if (ctrl_idx >= dev->hw_info.nr_ctrl || (uint64_t)(ofs + length) > dev->hw_info.ram_size 
+		|| !length || length > dev->hw_info.ram_max_len 
+		|| (length & (dev->hw_info.ram_align - 1)) != 0 || ((uint64_t)ofs & (dev->hw_info.ram_align - 1)) != 0) {
+		return -EINVAL;
+	}
+
+	len /= dev->hw_info.ram_align;
+	do_div(ofs_w, dev->hw_info.ram_align);
+
+	buf_dma = pci_map_single(dev->pdev, buf, length, PCI_DMA_FROMDEVICE);
+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,26))
+	ret = dma_mapping_error(buf_dma);
+#else
+	ret = dma_mapping_error(&(dev->pdev->dev), buf_dma);
+#endif
+	if (ret) {
+		hio_warn("%s: unable to map read DMA buffer\n", dev->name);
+		goto out_dma_mapping;
+	}
+
+	msg = (struct ssd_ram_op_msg *)ssd_get_dmsg(dev);
+
+	msg->fun = SSD_FUNC_RAM_READ;
+	msg->ctrl_idx = ctrl_idx;
+	msg->start = (uint32_t)ofs_w;
+	msg->length = len;
+	msg->buf = buf_dma;
+
+	ret = ssd_do_request(dev, READ, msg, NULL);
+	ssd_put_dmsg(msg);
+
+	pci_unmap_single(dev->pdev, buf_dma, length, PCI_DMA_FROMDEVICE);
+
+out_dma_mapping:
+	 return ret;
+}
+
+static int ssd_ram_write_4k(struct ssd_device *dev, void *buf, size_t length, loff_t ofs, int ctrl_idx)
+{
+	struct ssd_ram_op_msg *msg;
+	dma_addr_t buf_dma;
+	size_t len = length;
+	loff_t ofs_w = ofs;
+	int ret = 0;
+
+	if (ctrl_idx >= dev->hw_info.nr_ctrl || (uint64_t)(ofs + length) > dev->hw_info.ram_size 
+		|| !length || length > dev->hw_info.ram_max_len 
+		|| (length & (dev->hw_info.ram_align - 1)) != 0 || ((uint64_t)ofs & (dev->hw_info.ram_align - 1)) != 0) {
+		return -EINVAL;
+	}
+
+	len /= dev->hw_info.ram_align;
+	do_div(ofs_w, dev->hw_info.ram_align);
+
+	buf_dma = pci_map_single(dev->pdev, buf, length, PCI_DMA_TODEVICE);
+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,26))
+	ret = dma_mapping_error(buf_dma);
+#else
+	ret = dma_mapping_error(&(dev->pdev->dev), buf_dma);
+#endif
+	if (ret) {
+		hio_warn("%s: unable to map write DMA buffer\n", dev->name);
+		goto out_dma_mapping;
+	}
+
+	msg = (struct ssd_ram_op_msg *)ssd_get_dmsg(dev);
+
+	msg->fun = SSD_FUNC_RAM_WRITE;
+	msg->ctrl_idx = ctrl_idx;
+	msg->start = (uint32_t)ofs_w;
+	msg->length = len;
+	msg->buf = buf_dma;
+
+	ret = ssd_do_request(dev, WRITE, msg, NULL);
+	ssd_put_dmsg(msg);
+
+	pci_unmap_single(dev->pdev, buf_dma, length, PCI_DMA_TODEVICE);
+
+out_dma_mapping:
+	 return ret;
+
+}
+
+static int ssd_ram_read(struct ssd_device *dev, void *buf, size_t length, loff_t ofs, int ctrl_idx)
+{
+	int left = length;
+	size_t len;
+	loff_t off = ofs;
+	int ret = 0;
+
+	if (ctrl_idx >= dev->hw_info.nr_ctrl || (uint64_t)(ofs + length) > dev->hw_info.ram_size || !length 
+		|| (length & (dev->hw_info.ram_align - 1)) != 0 || ((uint64_t)ofs & (dev->hw_info.ram_align - 1)) != 0) {
+		return -EINVAL;
+	}
+
+	while (left > 0) {
+		len = dev->hw_info.ram_max_len;
+		if (left < (int)dev->hw_info.ram_max_len) {
+			len = left;
+		}
+
+		ret = ssd_ram_read_4k(dev, buf, len, off, ctrl_idx);
+		if (ret) {
+			break;
+		}
+
+		left -= len;
+		off += len;
+		buf += len;
+	}
+
+	return ret;
+}
+
+static int ssd_ram_write(struct ssd_device *dev, void *buf, size_t length, loff_t ofs, int ctrl_idx)
+{
+	int left = length;
+	size_t len;
+	loff_t off = ofs;
+	int ret = 0;
+
+	if (ctrl_idx >= dev->hw_info.nr_ctrl || (uint64_t)(ofs + length) > dev->hw_info.ram_size || !length 
+		|| (length & (dev->hw_info.ram_align - 1)) != 0 || ((uint64_t)ofs & (dev->hw_info.ram_align - 1)) != 0) {
+		return -EINVAL;
+	}
+
+	while (left > 0) {
+		len = dev->hw_info.ram_max_len;
+		if (left < (int)dev->hw_info.ram_max_len) {
+			len = left;
+		}
+
+		ret = ssd_ram_write_4k(dev, buf, len, off, ctrl_idx);
+		if (ret) {
+			break;
+		}
+
+		left -= len;
+		off += len;
+		buf += len;
+	}
+
+	return ret;
+}
+
+
+/* flash op */
+static int ssd_check_flash(struct ssd_device *dev, int flash, int page, int ctrl_idx)
+{
+	int cur_ch = flash % dev->hw_info.max_ch;
+	int cur_chip = flash /dev->hw_info.max_ch;
+
+	if (ctrl_idx >= dev->hw_info.nr_ctrl) {
+		return -EINVAL;
+	}
+
+	if (cur_ch >= dev->hw_info.nr_ch || cur_chip >= dev->hw_info.nr_chip) {
+		return -EINVAL;
+	}
+
+	if (page >= (int)(dev->hw_info.block_count * dev->hw_info.page_count)) {
+		return -EINVAL;
+	}
+	return 0;
+}
+
+static int ssd_nand_read_id(struct ssd_device *dev, void *id, int flash, int chip, int ctrl_idx)
+{
+	struct ssd_nand_op_msg *msg;
+	dma_addr_t buf_dma;
+	int ret = 0;
+
+	if (unlikely(!id))
+		return -EINVAL;
+
+	buf_dma = pci_map_single(dev->pdev, id, SSD_NAND_ID_BUFF_SZ, PCI_DMA_FROMDEVICE);
+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,26))
+	ret = dma_mapping_error(buf_dma);
+#else
+	ret = dma_mapping_error(&(dev->pdev->dev), buf_dma);
+#endif
+	if (ret) {
+		hio_warn("%s: unable to map read DMA buffer\n", dev->name);
+		goto out_dma_mapping;
+	}
+
+	if (dev->protocol_info.ver < SSD_PROTOCOL_V3) {
+		flash = ((uint32_t)flash << 1) | (uint32_t)chip;
+		chip = 0;
+	}
+
+	msg = (struct ssd_nand_op_msg *)ssd_get_dmsg(dev);
+
+	msg->fun = SSD_FUNC_NAND_READ_ID;
+	msg->chip_no = flash;
+	msg->chip_ce = chip;
+	msg->ctrl_idx = ctrl_idx;
+	msg->buf = buf_dma;
+
+	ret = ssd_do_request(dev, READ, msg, NULL);
+	ssd_put_dmsg(msg);
+
+	pci_unmap_single(dev->pdev, buf_dma, SSD_NAND_ID_BUFF_SZ, PCI_DMA_FROMDEVICE);
+
+out_dma_mapping:
+	return ret;
+}
+
+#if 0
+static int ssd_nand_read(struct ssd_device *dev, void *buf,
+	int flash, int chip, int page, int page_count, int ctrl_idx)
+{
+	struct ssd_nand_op_msg *msg;
+	dma_addr_t buf_dma;
+	int length;
+	int ret = 0;
+
+	if (!buf) {
+		return -EINVAL;
+	}
+
+	if ((page + page_count) > dev->hw_info.block_count*dev->hw_info.page_count) {
+		return -EINVAL;
+	}
+
+	ret = ssd_check_flash(dev, flash, page, ctrl_idx);
+	if (ret) {
+		return ret;
+	}
+
+	length = page_count * dev->hw_info.page_size;
+
+	buf_dma = pci_map_single(dev->pdev, buf, length, PCI_DMA_FROMDEVICE);
+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,26))
+	ret = dma_mapping_error(buf_dma);
+#else
+	ret = dma_mapping_error(&(dev->pdev->dev), buf_dma);
+#endif
+	if (ret) {
+		hio_warn("%s: unable to map read DMA buffer\n", dev->name);
+		goto out_dma_mapping;
+	}
+
+	if (dev->protocol_info.ver < SSD_PROTOCOL_V3) {
+		flash = (flash << 1) | chip;
+		chip = 0;
+	}
+
+	msg = (struct ssd_nand_op_msg *)ssd_get_dmsg(dev);
+
+	msg->fun = SSD_FUNC_NAND_READ;
+	msg->ctrl_idx = ctrl_idx;
+	msg->chip_no = flash;
+	msg->chip_ce = chip;
+	msg->page_no = page;
+	msg->page_count = page_count;
+	msg->buf = buf_dma;
+
+	ret = ssd_do_request(dev, READ, msg, NULL);
+	ssd_put_dmsg(msg);
+
+	pci_unmap_single(dev->pdev, buf_dma, length, PCI_DMA_FROMDEVICE);
+
+out_dma_mapping:
+	return ret;
+}
+#endif
+
+static int ssd_nand_read_w_oob(struct ssd_device *dev, void *buf, 
+	int flash, int chip, int page, int count, int ctrl_idx)
+{
+	struct ssd_nand_op_msg *msg;
+	dma_addr_t buf_dma;
+	int length;
+	int ret = 0;
+
+	if (!buf) {
+		return -EINVAL;
+	}
+
+	if ((page + count) > (int)(dev->hw_info.block_count * dev->hw_info.page_count)) {
+		return -EINVAL;
+	}
+
+	ret = ssd_check_flash(dev, flash, page, ctrl_idx);
+	if (ret) {
+		return ret;
+	}
+
+	length = count * (dev->hw_info.page_size + dev->hw_info.oob_size);
+
+	buf_dma = pci_map_single(dev->pdev, buf, length, PCI_DMA_FROMDEVICE);
+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,26))
+	ret = dma_mapping_error(buf_dma);
+#else
+	ret = dma_mapping_error(&(dev->pdev->dev), buf_dma);
+#endif
+	if (ret) {
+		hio_warn("%s: unable to map read DMA buffer\n", dev->name);
+		goto out_dma_mapping;
+	}
+
+	if (dev->protocol_info.ver < SSD_PROTOCOL_V3) {
+		flash = ((uint32_t)flash << 1) | (uint32_t)chip;
+		chip = 0;
+	}
+
+	msg = (struct ssd_nand_op_msg *)ssd_get_dmsg(dev);
+
+	msg->fun = SSD_FUNC_NAND_READ_WOOB;
+	msg->ctrl_idx = ctrl_idx;
+	msg->chip_no = flash;
+	msg->chip_ce = chip;
+	msg->page_no = page;
+	msg->page_count = count;
+	msg->buf = buf_dma;
+
+	ret = ssd_do_request(dev, READ, msg, NULL);
+	ssd_put_dmsg(msg);
+
+	pci_unmap_single(dev->pdev, buf_dma, length, PCI_DMA_FROMDEVICE);
+
+out_dma_mapping:
+	return ret;
+}
+
+/* write 1 page */
+static int ssd_nand_write(struct ssd_device *dev, void *buf, 
+	int flash, int chip, int page, int count, int ctrl_idx)
+{
+	struct ssd_nand_op_msg *msg;
+	dma_addr_t buf_dma;
+	int length;
+	int ret = 0;
+
+	if (dev->protocol_info.ver < SSD_PROTOCOL_V3) {
+		return -EINVAL;
+	}
+
+	if (!buf) {
+		return -EINVAL;
+	}
+
+	if (count != 1) {
+		return -EINVAL;
+	}
+
+	ret = ssd_check_flash(dev, flash, page, ctrl_idx);
+	if (ret) {
+		return ret;
+	}
+
+	length = count * (dev->hw_info.page_size + dev->hw_info.oob_size);
+
+	/* write data to ram */
+	/*ret = ssd_ram_write(dev, buf, length, dev->hw_info.nand_wbuff_base, ctrl_idx);
+	if (ret) {
+		return ret;
+	}*/
+
+	buf_dma = pci_map_single(dev->pdev, buf, length, PCI_DMA_TODEVICE);
+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,26))
+	ret = dma_mapping_error(buf_dma);
+#else
+	ret = dma_mapping_error(&(dev->pdev->dev), buf_dma);
+#endif
+	if (ret) {
+		hio_warn("%s: unable to map write DMA buffer\n", dev->name);
+		goto out_dma_mapping;
+	}
+
+	if (dev->protocol_info.ver < SSD_PROTOCOL_V3) {
+		flash = ((uint32_t)flash << 1) | (uint32_t)chip;
+		chip = 0;
+	}
+
+	msg = (struct ssd_nand_op_msg *)ssd_get_dmsg(dev);
+
+	msg->fun = SSD_FUNC_NAND_WRITE;
+	msg->ctrl_idx = ctrl_idx;
+	msg->chip_no = flash;
+	msg->chip_ce = chip;
+
+	msg->page_no = page;
+	msg->page_count = count;
+	msg->buf = buf_dma;
+
+	ret = ssd_do_request(dev, WRITE, msg, NULL);
+	ssd_put_dmsg(msg);
+
+	pci_unmap_single(dev->pdev, buf_dma, length, PCI_DMA_TODEVICE);
+
+out_dma_mapping:
+	return ret;
+}
+
+static int ssd_nand_erase(struct ssd_device *dev, int flash, int chip, int page, int ctrl_idx)
+{
+	struct ssd_nand_op_msg *msg;
+	int ret = 0;
+
+	ret = ssd_check_flash(dev, flash, page, ctrl_idx);
+	if (ret) {
+		return ret;
+	}
+
+	if (dev->protocol_info.ver < SSD_PROTOCOL_V3) {
+		flash = ((uint32_t)flash << 1) | (uint32_t)chip;
+		chip = 0;
+	}
+
+	msg = (struct ssd_nand_op_msg *)ssd_get_dmsg(dev);
+
+	msg->fun = SSD_FUNC_NAND_ERASE;
+	msg->ctrl_idx = ctrl_idx;
+	msg->chip_no = flash;
+	msg->chip_ce = chip;
+	msg->page_no = page;
+
+	ret = ssd_do_request(dev, WRITE, msg, NULL);
+	ssd_put_dmsg(msg);
+
+	return ret;
+}
+
+static int ssd_update_bbt(struct ssd_device *dev, int flash, int ctrl_idx)
+{
+	struct ssd_nand_op_msg *msg;
+	struct ssd_flush_msg *fmsg;
+	int ret = 0;
+
+	ret = ssd_check_flash(dev, flash, 0, ctrl_idx);
+	if (ret) {
+		return ret;
+	}
+
+	msg = (struct ssd_nand_op_msg *)ssd_get_dmsg(dev);
+
+	if (dev->protocol_info.ver < SSD_PROTOCOL_V3) {
+		fmsg = (struct ssd_flush_msg *)msg;
+
+		fmsg->fun = SSD_FUNC_FLUSH;
+		fmsg->flag = 0x1;
+		fmsg->flash = flash;
+		fmsg->ctrl_idx = ctrl_idx;
+	} else {
+		msg->fun = SSD_FUNC_FLUSH;
+		msg->flag = 0x1;
+		msg->chip_no = flash;
+		msg->ctrl_idx = ctrl_idx;
+	}
+
+	ret = ssd_do_request(dev, WRITE, msg, NULL);
+	ssd_put_dmsg(msg);
+
+	return ret;
+}
+
+/* flash controller init state */
+static int __ssd_check_init_state(struct ssd_device *dev)
+{
+	uint32_t *init_state = NULL;
+	int reg_base, reg_sz;
+	int max_wait = SSD_INIT_MAX_WAIT;
+	int init_wait = 0;
+	int i, j, k;
+	int ch_start = 0;
+
+/*
+	for (i=0; i<dev->hw_info.nr_ctrl; i++) {
+		ssd_reg32_write(dev->ctrlp + SSD_CTRL_TEST_REG0 + i * 8, test_data);
+		read_data = ssd_reg32_read(dev->ctrlp + SSD_CTRL_TEST_REG0 + i * 8);
+		if (read_data == ~test_data) {
+			//dev->hw_info.nr_ctrl++;
+			dev->hw_info.nr_ctrl_map |= 1<<i;
+		}
+	}
+*/
+
+/*
+	read_data = ssd_reg32_read(dev->ctrlp + SSD_READY_REG);
+	j=0;
+	for (i=0; i<dev->hw_info.nr_ctrl; i++) {
+		if (((read_data>>i) & 0x1) == 0) {
+			j++;
+		}
+	}
+
+	if (dev->hw_info.nr_ctrl != j) {
+		printk(KERN_WARNING "%s: nr_ctrl mismatch: %d %d\n", dev->name, dev->hw_info.nr_ctrl, j);
+		return -1;
+	}
+*/
+
+/*
+	init_state = ssd_reg_read(dev->ctrlp + SSD_FLASH_INFO_REG0);
+	for (j=1; j<dev->hw_info.nr_ctrl;j++) {
+		if (init_state != ssd_reg_read(dev->ctrlp + SSD_FLASH_INFO_REG0 + j*8)) {
+			printk(KERN_WARNING "SSD_FLASH_INFO_REG[%d], not match\n", j);
+			return -1;
+			}
+		}
+*/
+
+/*	init_state = ssd_reg_read(dev->ctrlp + SSD_CHIP_INFO_REG0);
+	for (j=1; j<dev->hw_info.nr_ctrl; j++) {
+		if (init_state != ssd_reg_read(dev->ctrlp + SSD_CHIP_INFO_REG0 + j*16)) {
+			printk(KERN_WARNING "SSD_CHIP_INFO_REG Lo [%d], not match\n", j);
+			return -1;
+			}
+		}
+
+	init_state = ssd_reg_read(dev->ctrlp + SSD_CHIP_INFO_REG0 + 8);
+	for (j=1; j<dev->hw_info.nr_ctrl; j++) {
+		if (init_state != ssd_reg_read(dev->ctrlp + SSD_CHIP_INFO_REG0 + 8 + j*16)) {
+			printk(KERN_WARNING "SSD_CHIP_INFO_REG Hi [%d], not match\n", j);
+			return -1;
+			}
+		}
+*/
+
+	if (dev->protocol_info.ver >= SSD_PROTOCOL_V3_2) {
+		max_wait = SSD_INIT_MAX_WAIT_V3_2;
+	}
+
+	reg_base = dev->protocol_info.init_state_reg;
+	reg_sz = dev->protocol_info.init_state_reg_sz;
+
+	init_state = (uint32_t *)kmalloc(reg_sz, GFP_KERNEL);
+	if (!init_state) {
+		return -ENOMEM;
+	}
+
+	for (i=0; i<dev->hw_info.nr_ctrl; i++) {
+check_init:
+		for (j=0, k=0; j<reg_sz; j+=sizeof(uint32_t), k++) {
+			init_state[k] = ssd_reg32_read(dev->ctrlp + reg_base + j);
+		}
+
+		if (dev->protocol_info.ver > SSD_PROTOCOL_V3) {
+			/* just check the last bit, no need to check all channel */
+			ch_start = dev->hw_info.max_ch - 1;
+		} else {
+			ch_start = 0;
+		}
+
+		for (j=0; j<dev->hw_info.nr_chip; j++) {
+			for (k=ch_start; k<dev->hw_info.max_ch; k++) {
+				if (test_bit((j*dev->hw_info.max_ch + k), (void *)init_state)) {
+					continue;
+				}
+
+				init_wait++;
+				if (init_wait <= max_wait) {
+					msleep(SSD_INIT_WAIT);
+					goto check_init;
+				} else {
+					if (k < dev->hw_info.nr_ch) {
+						hio_warn("%s: controller %d chip %d ch %d init failed\n", 
+							dev->name, i, j, k);
+					} else {
+						hio_warn("%s: controller %d chip %d init failed\n", 
+							dev->name, i, j);
+					}
+
+					kfree(init_state);
+					return -1;
+				}
+			}
+		}
+		reg_base += reg_sz;
+	}
+	//printk(KERN_WARNING "%s: init wait %d\n", dev->name, init_wait);
+
+	kfree(init_state);
+	return 0;
+}
+
+static int ssd_check_init_state(struct ssd_device *dev)
+{
+	if (mode != SSD_DRV_MODE_STANDARD) {
+		return 0;
+	}
+
+	return __ssd_check_init_state(dev);
+}
+
+static void ssd_reset_resp_ptr(struct ssd_device *dev);
+
+/* reset flash controller etc */
+static int __ssd_reset(struct ssd_device *dev, int type)
+{
+	if (type < SSD_RST_NOINIT || type > SSD_RST_FULL) {
+		return -EINVAL;
+	}
+
+	mutex_lock(&dev->fw_mutex);
+
+	if (type == SSD_RST_NOINIT) {	//no init
+		ssd_reg32_write(dev->ctrlp + SSD_RESET_REG, SSD_RESET_NOINIT);
+	} else if (type == SSD_RST_NORMAL) {	//reset & init
+		ssd_reg32_write(dev->ctrlp + SSD_RESET_REG, SSD_RESET);
+	} else {	// full reset
+		if (dev->protocol_info.ver < SSD_PROTOCOL_V3_2) {
+			mutex_unlock(&dev->fw_mutex);
+			return -EINVAL;
+		}
+
+		ssd_reg32_write(dev->ctrlp + SSD_FULL_RESET_REG, SSD_RESET_FULL);
+
+		/* ?? */
+		ssd_reset_resp_ptr(dev);
+	}
+
+#ifdef SSD_OT_PROTECT
+	dev->ot_delay = 0;
+#endif
+
+	msleep(1000);
+
+	/* xx */
+	ssd_set_flush_timeout(dev, dev->wmode);
+
+	mutex_unlock(&dev->fw_mutex);
+	ssd_gen_swlog(dev, SSD_LOG_RESET, (uint32_t)type);
+
+	return __ssd_check_init_state(dev);
+}
+
+static int ssd_save_md(struct ssd_device *dev)
+{
+	struct ssd_nand_op_msg *msg;
+	int ret = 0;
+
+	if (unlikely(mode != SSD_DRV_MODE_STANDARD))
+		return 0;
+
+	if (dev->protocol_info.ver <= SSD_PROTOCOL_V3) {
+		return 0;
+	}
+
+	if (!dev->save_md) {
+		return 0;
+	}
+
+	msg = (struct ssd_nand_op_msg *)ssd_get_dmsg(dev);
+
+	msg->fun = SSD_FUNC_FLUSH;
+	msg->flag = 0x2;
+	msg->ctrl_idx = 0;
+	msg->chip_no = 0;
+
+	ret = ssd_do_request(dev, WRITE, msg, NULL);
+	ssd_put_dmsg(msg);
+
+	return ret;
+}
+
+static int ssd_barrier_save_md(struct ssd_device *dev)
+{
+	struct ssd_nand_op_msg *msg;
+	int ret = 0;
+
+	if (unlikely(mode != SSD_DRV_MODE_STANDARD))
+		return 0;
+
+	if (dev->protocol_info.ver <= SSD_PROTOCOL_V3) {
+		return 0;
+	}
+
+	if (!dev->save_md) {
+		return 0;
+	}
+
+	msg = (struct ssd_nand_op_msg *)ssd_get_dmsg(dev);
+
+	msg->fun = SSD_FUNC_FLUSH;
+	msg->flag = 0x2;
+	msg->ctrl_idx = 0;
+	msg->chip_no = 0;
+
+	ret = ssd_do_barrier_request(dev, WRITE, msg, NULL);
+	ssd_put_dmsg(msg);
+
+	return ret;
+}
+
+static int ssd_flush(struct ssd_device *dev)
+{
+	struct ssd_nand_op_msg *msg;
+	struct ssd_flush_msg *fmsg;
+	int ret = 0;
+
+	if (unlikely(mode != SSD_DRV_MODE_STANDARD))
+		return 0;
+
+	msg = (struct ssd_nand_op_msg *)ssd_get_dmsg(dev);
+
+	if (dev->protocol_info.ver < SSD_PROTOCOL_V3) {
+		fmsg = (struct ssd_flush_msg *)msg;
+
+		fmsg->fun = SSD_FUNC_FLUSH;
+		fmsg->flag = 0;
+		fmsg->ctrl_idx = 0;
+		fmsg->flash = 0;
+	} else {
+		msg->fun = SSD_FUNC_FLUSH;
+		msg->flag = 0;
+		msg->ctrl_idx = 0;
+		msg->chip_no = 0;
+	}
+
+	ret = ssd_do_request(dev, WRITE, msg, NULL);
+	ssd_put_dmsg(msg);
+
+	return ret;
+}
+
+static int ssd_barrier_flush(struct ssd_device *dev)
+{
+	struct ssd_nand_op_msg *msg;
+	struct ssd_flush_msg *fmsg;
+	int ret = 0;
+
+	if (unlikely(mode != SSD_DRV_MODE_STANDARD))
+		return 0;
+
+	msg = (struct ssd_nand_op_msg *)ssd_get_dmsg(dev);
+
+	if (dev->protocol_info.ver < SSD_PROTOCOL_V3) {
+		fmsg = (struct ssd_flush_msg *)msg;
+
+		fmsg->fun = SSD_FUNC_FLUSH;
+		fmsg->flag = 0;
+		fmsg->ctrl_idx = 0;
+		fmsg->flash = 0;
+	} else {
+		msg->fun = SSD_FUNC_FLUSH;
+		msg->flag = 0;
+		msg->ctrl_idx = 0;
+		msg->chip_no = 0;
+	}
+
+	ret = ssd_do_barrier_request(dev, WRITE, msg, NULL);
+	ssd_put_dmsg(msg);
+
+	return ret;
+}
+
+#define SSD_WMODE_BUFFER_TIMEOUT	0x00c82710
+#define SSD_WMODE_BUFFER_EX_TIMEOUT	0x000500c8
+#define SSD_WMODE_FUA_TIMEOUT		0x000503E8
+static void ssd_set_flush_timeout(struct ssd_device *dev, int m)
+{
+	uint32_t to;
+	uint32_t val = 0;
+
+	if (dev->protocol_info.ver < SSD_PROTOCOL_V3_1_1) {
+		return;
+	}
+
+	switch(m) {
+		case SSD_WMODE_BUFFER:
+			to = SSD_WMODE_BUFFER_TIMEOUT;
+			break;
+		case SSD_WMODE_BUFFER_EX:
+			if (dev->protocol_info.ver < SSD_PROTOCOL_V3_2_1) {
+				to = SSD_WMODE_BUFFER_EX_TIMEOUT;
+			} else {
+				to = SSD_WMODE_BUFFER_TIMEOUT;
+			}
+			break;
+		case SSD_WMODE_FUA:
+			to = SSD_WMODE_FUA_TIMEOUT;
+			break;
+		default:
+			return;
+	}
+
+	val = (((uint32_t)((uint32_t)m & 0x3) << 28) | to);
+
+	ssd_reg32_write(dev->ctrlp + SSD_FLUSH_TIMEOUT_REG, val);
+}
+
+static int ssd_do_switch_wmode(struct ssd_device *dev, int m)
+{
+	int ret = 0;
+
+	ret = ssd_barrier_start(dev);
+	if (ret) {
+		goto out;
+	}
+
+	ret = ssd_barrier_flush(dev);
+	if (ret) {
+		goto out_barrier_end;
+	}
+
+	/* set contoller flush timeout */
+	ssd_set_flush_timeout(dev, m);
+
+	dev->wmode = m;
+	mb();
+
+out_barrier_end:
+	ssd_barrier_end(dev);
+out:
+	return ret;
+}
+
+static int ssd_switch_wmode(struct ssd_device *dev, int m)
+{
+	int default_wmode;
+	int next_wmode;
+	int ret = 0;
+
+	if (!test_bit(SSD_ONLINE, &dev->state)) {
+		return -ENODEV;
+	}
+	
+	if (dev->protocol_info.ver < SSD_PROTOCOL_V3_2) {
+		default_wmode = SSD_WMODE_BUFFER;
+	} else {
+		default_wmode = SSD_WMODE_BUFFER_EX;
+	}
+
+	if (SSD_WMODE_AUTO == m) {
+		/* battery fault ? */
+		if (test_bit(SSD_HWMON_PL_CAP(SSD_PL_CAP), &dev->hwmon)) {
+			next_wmode = SSD_WMODE_FUA;
+		} else {
+			next_wmode = default_wmode;
+		}
+	} else if (SSD_WMODE_DEFAULT == m) {
+		next_wmode = default_wmode;
+	} else {
+		next_wmode = m;
+	}
+
+	if (next_wmode != dev->wmode) {
+		hio_warn("%s: switch write mode (%d -> %d)\n", dev->name, dev->wmode, next_wmode);
+		ret = ssd_do_switch_wmode(dev, next_wmode);
+		if (ret) {
+			hio_err("%s: can not switch write mode (%d -> %d)\n", dev->name, dev->wmode, next_wmode);
+		}
+	}
+
+	return ret;
+}
+
+static int ssd_init_wmode(struct ssd_device *dev)
+{
+	int default_wmode;
+	int ret = 0;
+	
+	if (dev->protocol_info.ver < SSD_PROTOCOL_V3_2) {
+		default_wmode = SSD_WMODE_BUFFER;
+	} else {
+		default_wmode = SSD_WMODE_BUFFER_EX;
+	}
+
+	/* dummy mode */
+	if (SSD_WMODE_AUTO == dev->user_wmode) {
+		/* battery fault ? */
+		if (test_bit(SSD_HWMON_PL_CAP(SSD_PL_CAP), &dev->hwmon)) {
+			dev->wmode = SSD_WMODE_FUA;
+		} else {
+			dev->wmode = default_wmode;
+		}
+	} else if (SSD_WMODE_DEFAULT == dev->user_wmode) {
+		dev->wmode = default_wmode;
+	} else {
+		dev->wmode = dev->user_wmode;
+	}
+	ssd_set_flush_timeout(dev, dev->wmode);
+
+	return ret;
+}
+
+static int __ssd_set_wmode(struct ssd_device *dev, int m)
+{
+	int ret = 0;
+
+	/* not support old fw*/
+	if (dev->protocol_info.ver < SSD_PROTOCOL_V3_1_1) {
+		ret = -EOPNOTSUPP;
+		goto out;
+	}
+
+	if (m < SSD_WMODE_BUFFER || m > SSD_WMODE_DEFAULT) {
+		ret = -EINVAL;
+		goto out;
+	}
+	
+	ssd_gen_swlog(dev, SSD_LOG_SET_WMODE, m);
+
+	dev->user_wmode = m;
+
+	ret = ssd_switch_wmode(dev, dev->user_wmode);
+	if (ret) {
+		goto out;
+	}
+
+out:
+	return ret;
+}
+
+int ssd_set_wmode(struct block_device *bdev, int m)
+{
+	struct ssd_device *dev;
+
+	if (!bdev || !(bdev->bd_disk)) {
+		return -EINVAL;
+	}
+
+	dev = bdev->bd_disk->private_data;
+
+	return __ssd_set_wmode(dev, m);
+}
+
+static int ssd_do_reset(struct ssd_device *dev)
+{
+	int ret = 0;
+
+	if (test_and_set_bit(SSD_RESETING, &dev->state)) {
+		return 0;
+	}
+
+	ssd_stop_workq(dev);
+
+	ret = ssd_barrier_start(dev);
+	if (ret) {
+		goto out;
+	}
+
+	if (dev->protocol_info.ver < SSD_PROTOCOL_V3_2) {
+		/* old reset */
+		ret = __ssd_reset(dev, SSD_RST_NORMAL);
+	} else {
+		/* full reset */
+		//ret = __ssd_reset(dev, SSD_RST_FULL);
+		ret = __ssd_reset(dev, SSD_RST_NORMAL);
+	}
+	if (ret) {
+		goto out_barrier_end;
+	}
+
+out_barrier_end:
+	ssd_barrier_end(dev);
+out:
+	ssd_start_workq(dev);
+	test_and_clear_bit(SSD_RESETING, &dev->state);
+	return ret;
+}
+
+static int ssd_full_reset(struct ssd_device *dev)
+{
+	int ret = 0;
+
+	if (test_and_set_bit(SSD_RESETING, &dev->state)) {
+		return 0;
+	}
+
+	ssd_stop_workq(dev);
+
+	ret = ssd_barrier_start(dev);
+	if (ret) {
+		goto out;
+	}
+
+	ret = ssd_barrier_flush(dev);
+	if (ret) {
+		goto out_barrier_end;
+	}
+
+	ret = ssd_barrier_save_md(dev);
+	if (ret) {
+		goto out_barrier_end;
+	}
+
+	if (dev->protocol_info.ver < SSD_PROTOCOL_V3_2) {
+		/* old reset */
+		ret = __ssd_reset(dev, SSD_RST_NORMAL);
+	} else {
+		/* full reset */
+		//ret = __ssd_reset(dev, SSD_RST_FULL);
+		ret = __ssd_reset(dev, SSD_RST_NORMAL);
+	}
+	if (ret) {
+		goto out_barrier_end;
+	}
+
+out_barrier_end:
+	ssd_barrier_end(dev);
+out:
+	ssd_start_workq(dev);
+	test_and_clear_bit(SSD_RESETING, &dev->state);
+	return ret;
+}
+
+int ssd_reset(struct block_device *bdev)
+{
+	struct ssd_device *dev;
+
+	if (!bdev || !(bdev->bd_disk)) {
+		return -EINVAL;
+	}
+
+	dev = bdev->bd_disk->private_data;
+
+	return ssd_full_reset(dev);
+}
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20))
+static int ssd_issue_flush_fn(struct request_queue *q, struct gendisk *disk, 
+		sector_t *error_sector)
+{
+	struct ssd_device *dev = q->queuedata;
+
+	return ssd_flush(dev);
+}
+#endif
+
+void ssd_submit_pbio(struct request_queue *q, struct bio *bio)
+{
+	struct ssd_device *dev = q->queuedata;
+#ifdef SSD_QUEUE_PBIO
+	int ret = -EBUSY;
+#endif
+
+	if (!test_bit(SSD_ONLINE, &dev->state)) {
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24))
+		bio_endio(bio, -ENODEV);
+#else
+		bio_endio(bio, bio->bi_size, -ENODEV);
+#endif
+		goto out;
+	}
+
+#ifdef SSD_DEBUG_ERR
+	if (atomic_read(&dev->tocnt)) {
+		hio_warn("%s: IO rejected because of IO timeout!\n", dev->name);
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24))
+		bio_endio(bio, -EIO);
+#else
+		bio_endio(bio, bio->bi_size, -EIO);
+#endif
+		goto out;
+	}
+#endif
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,32))
+	if (unlikely(bio_barrier(bio))) {
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24))
+		bio_endio(bio, -EOPNOTSUPP);
+#else
+		bio_endio(bio, bio->bi_size, -EOPNOTSUPP);
+#endif
+		goto out;
+	}
+#elif (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,36))
+	if (unlikely(bio_rw_flagged(bio, BIO_RW_BARRIER))) {
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24))
+		bio_endio(bio, -EOPNOTSUPP);
+#else
+		bio_endio(bio, bio->bi_size, -EOPNOTSUPP);
+#endif
+		goto out;
+	}
+#elif (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,37))
+	if (unlikely(bio->bi_rw & REQ_HARDBARRIER)) {
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24))
+		bio_endio(bio, -EOPNOTSUPP);
+#else
+		bio_endio(bio, bio->bi_size, -EOPNOTSUPP);
+#endif
+		goto out;
+	}
+#else
+	//xx
+	if (unlikely(bio->bi_rw & REQ_FUA)) {
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24))
+		bio_endio(bio, -EOPNOTSUPP);
+#else
+		bio_endio(bio, bio->bi_size, -EOPNOTSUPP);
+#endif
+		goto out;
+	}
+#endif
+
+	 if (unlikely(dev->readonly && bio_data_dir(bio) == WRITE)) {
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24))
+		bio_endio(bio, -EROFS);
+#else
+		bio_endio(bio, bio->bi_size, -EROFS);
+#endif
+		goto out;
+	}
+
+#ifdef SSD_QUEUE_PBIO
+	if (0 == atomic_read(&dev->in_sendq)) {
+		ret = __ssd_submit_pbio(dev, bio, 0);
+	}
+
+	if (ret) {
+		(void)test_and_set_bit(BIO_SSD_PBIO, &bio->bi_flags);
+		ssd_queue_bio(dev, bio);
+	}
+#else
+	__ssd_submit_pbio(dev, bio, 1);
+#endif
+
+out:
+	return;
+}
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,4,0))
+static blk_qc_t ssd_make_request(struct request_queue *q, struct bio *bio)
+#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,2,0))
+static void ssd_make_request(struct request_queue *q, struct bio *bio)
+#else
+static int ssd_make_request(struct request_queue *q, struct bio *bio)
+#endif
+{
+	struct ssd_device *dev = q->queuedata;
+	int ret = -EBUSY;
+
+	if (!test_bit(SSD_ONLINE, &dev->state)) {
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24))
+		bio_endio(bio, -ENODEV);
+#else
+		bio_endio(bio, bio->bi_size, -ENODEV);
+#endif
+		goto out;
+	}
+
+#ifdef SSD_DEBUG_ERR
+	if (atomic_read(&dev->tocnt)) {
+		hio_warn("%s: IO rejected because of IO timeout!\n", dev->name);
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24))
+		bio_endio(bio, -EIO);
+#else
+		bio_endio(bio, bio->bi_size, -EIO);
+#endif
+		goto out;
+	}
+#endif
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,32))
+	if (unlikely(bio_barrier(bio))) {
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24))
+		bio_endio(bio, -EOPNOTSUPP);
+#else
+		bio_endio(bio, bio->bi_size, -EOPNOTSUPP);
+#endif
+		goto out;
+	}
+#elif (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,36))
+	if (unlikely(bio_rw_flagged(bio, BIO_RW_BARRIER))) {
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24))
+		bio_endio(bio, -EOPNOTSUPP);
+#else
+		bio_endio(bio, bio->bi_size, -EOPNOTSUPP);
+#endif
+		goto out;
+	}
+#elif (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,37))
+	if (unlikely(bio->bi_rw & REQ_HARDBARRIER)) {
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24))
+		bio_endio(bio, -EOPNOTSUPP);
+#else
+		bio_endio(bio, bio->bi_size, -EOPNOTSUPP);
+#endif
+		goto out;
+	}
+#else
+	//xx
+	if (unlikely(bio->bi_rw & REQ_FUA)) {
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24))
+		bio_endio(bio, -EOPNOTSUPP);
+#else
+		bio_endio(bio, bio->bi_size, -EOPNOTSUPP);
+#endif
+		goto out;
+	}
+
+	/* writeback_cache_control.txt: REQ_FLUSH requests without data can be completed successfully without doing any work */
+	if (unlikely((bio->bi_rw & REQ_FLUSH) && !bio_sectors(bio))) {
+		bio_endio(bio, 0);
+		goto out;
+	}
+
+#endif
+
+	if (0 == atomic_read(&dev->in_sendq)) {
+		ret = ssd_submit_bio(dev, bio, 0);
+	}
+
+	if (ret) {
+		ssd_queue_bio(dev, bio);
+	}
+
+out:
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,4,0))
+	return BLK_QC_T_NONE;
+#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,2,0))
+	return;
+#else
+	return 0;
+#endif
+}
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16))
+static int ssd_block_getgeo(struct block_device *bdev, struct hd_geometry *geo)
+{
+	struct ssd_device *dev;
+
+	if (!bdev) {
+		return -EINVAL;
+	}
+
+	dev = bdev->bd_disk->private_data;
+	if (!dev) {
+		return -EINVAL;
+	}
+
+	geo->heads = 4;
+	geo->sectors = 16;
+	geo->cylinders = (dev->hw_info.size & ~0x3f) >> 6;
+	return 0;
+}
+#endif
+
+static void ssd_cleanup_blkdev(struct ssd_device *dev);
+static int ssd_init_blkdev(struct ssd_device *dev);
+static int ssd_ioctl_common(struct ssd_device *dev, unsigned int cmd, unsigned long arg)
+{
+	void __user *argp = (void __user *)arg;
+	void __user *buf = NULL;
+	void *kbuf = NULL;
+	int ret = 0;
+
+	switch (cmd) {
+		case SSD_CMD_GET_PROTOCOL_INFO:
+			if (copy_to_user(argp, &dev->protocol_info, sizeof(struct ssd_protocol_info))) {
+				hio_warn("%s: copy_to_user: failed\n", dev->name);
+				ret = -EFAULT;
+				break;
+			}
+			break;
+
+		case SSD_CMD_GET_HW_INFO:
+			if (copy_to_user(argp, &dev->hw_info, sizeof(struct ssd_hw_info))) {
+				hio_warn("%s: copy_to_user: failed\n", dev->name);
+				ret = -EFAULT;
+				break;
+			}
+			break;
+
+		case SSD_CMD_GET_ROM_INFO:
+			if (copy_to_user(argp, &dev->rom_info, sizeof(struct ssd_rom_info))) {
+				hio_warn("%s: copy_to_user: failed\n", dev->name);
+				ret = -EFAULT;
+				break;
+			}
+			break;
+
+		case SSD_CMD_GET_SMART: {
+			struct ssd_smart smart;
+			int i;
+
+			memcpy(&smart, &dev->smart, sizeof(struct ssd_smart));
+
+			mutex_lock(&dev->gd_mutex);
+			ssd_update_smart(dev, &smart);
+			mutex_unlock(&dev->gd_mutex);
+
+			/* combine the volatile log info */
+			if (dev->log_info.nr_log) {
+				for (i=0; i<SSD_LOG_NR_LEVEL; i++) {
+					smart.log_info.stat[i] += dev->log_info.stat[i];
+				}
+			}
+
+			if (copy_to_user(argp, &smart, sizeof(struct ssd_smart))) {
+				hio_warn("%s: copy_to_user: failed\n", dev->name);
+				ret = -EFAULT;
+				break;
+			}
+
+			break;
+		}
+
+		case SSD_CMD_GET_IDX:
+			if (copy_to_user(argp, &dev->idx, sizeof(int))) {
+				hio_warn("%s: copy_to_user: failed\n", dev->name);
+				ret = -EFAULT;
+				break;
+			}
+			break;
+
+		case SSD_CMD_GET_AMOUNT: {
+			int nr_ssd = atomic_read(&ssd_nr);
+			if (copy_to_user(argp, &nr_ssd, sizeof(int))) {
+				hio_warn("%s: copy_to_user: failed\n", dev->name);
+				ret = -EFAULT;
+				break;
+			}
+			break;
+		}
+
+		case SSD_CMD_GET_TO_INFO: {
+			int tocnt = atomic_read(&dev->tocnt);
+
+			if (copy_to_user(argp, &tocnt, sizeof(int))) {
+				hio_warn("%s: copy_to_user: failed\n", dev->name);
+				ret = -EFAULT;
+				break;
+			}
+			break;
+		}
+
+		case SSD_CMD_GET_DRV_VER: {
+			char ver[] = DRIVER_VERSION;
+			int len = sizeof(ver);
+
+			if (len > (DRIVER_VERSION_LEN - 1)) {
+				len = (DRIVER_VERSION_LEN - 1);
+			}
+			if (copy_to_user(argp, ver, len)) {
+				hio_warn("%s: copy_to_user: failed\n", dev->name);
+				ret = -EFAULT;
+				break;
+			}
+			break;
+		}
+
+		case SSD_CMD_GET_BBACC_INFO: {
+			struct ssd_acc_info acc;
+
+			mutex_lock(&dev->fw_mutex);
+			ret = ssd_bb_acc(dev, &acc);
+			mutex_unlock(&dev->fw_mutex);
+			if (ret) {
+				break;
+			}
+
+			if (copy_to_user(argp, &acc, sizeof(struct ssd_acc_info))) {
+				hio_warn("%s: copy_to_user: failed\n", dev->name);
+				ret = -EFAULT;
+				break;
+			}
+			break;
+		}
+
+		case SSD_CMD_GET_ECACC_INFO: {
+			struct ssd_acc_info acc;
+
+			mutex_lock(&dev->fw_mutex);
+			ret = ssd_ec_acc(dev, &acc);
+			mutex_unlock(&dev->fw_mutex);
+			if (ret) {
+				break;
+			}
+
+			if (copy_to_user(argp, &acc, sizeof(struct ssd_acc_info))) {
+				hio_warn("%s: copy_to_user: failed\n", dev->name);
+				ret = -EFAULT;
+				break;
+			}
+			break;
+		}
+
+		case SSD_CMD_GET_HW_INFO_EXT:
+			if (copy_to_user(argp, &dev->hw_info_ext, sizeof(struct ssd_hw_info_extend))) {
+				hio_warn("%s: copy_to_user: failed\n", dev->name);
+				ret = -EFAULT;
+				break;
+			}
+			break;
+
+		case SSD_CMD_REG_READ: {
+			struct ssd_reg_op_info reg_info;
+
+			if (copy_from_user(&reg_info, argp, sizeof(struct ssd_reg_op_info))) {
+				hio_warn("%s: copy_from_user: failed\n", dev->name);
+				ret = -EFAULT;
+				break;
+			}
+
+			if (reg_info.offset > dev->mmio_len-sizeof(uint32_t)) {
+				ret = -EINVAL;
+				break;
+			}
+
+			reg_info.value = ssd_reg32_read(dev->ctrlp + reg_info.offset);
+			if (copy_to_user(argp, &reg_info, sizeof(struct ssd_reg_op_info))) {
+				hio_warn("%s: copy_to_user: failed\n", dev->name);
+				ret = -EFAULT;
+				break;
+			}
+
+			break;
+		}
+
+		case SSD_CMD_REG_WRITE: {
+			struct ssd_reg_op_info reg_info;
+
+			if (copy_from_user(&reg_info, argp, sizeof(struct ssd_reg_op_info))) {
+				hio_warn("%s: copy_from_user: failed\n", dev->name);
+				ret = -EFAULT;
+				break;
+			}
+
+			if (reg_info.offset > dev->mmio_len-sizeof(uint32_t)) {
+				ret = -EINVAL;
+				break;
+			}
+
+			ssd_reg32_write(dev->ctrlp + reg_info.offset, reg_info.value);
+
+			break;
+		}
+
+		case SSD_CMD_SPI_READ: {
+			struct ssd_spi_op_info spi_info;
+			uint32_t off, size;
+
+			if (copy_from_user(&spi_info, argp, sizeof(struct ssd_spi_op_info))) {
+				hio_warn("%s: copy_from_user: failed\n", dev->name);
+				ret = -EFAULT;
+				break;
+			}
+
+			off = spi_info.off;
+			size = spi_info.len;
+			buf = spi_info.buf;
+
+			if (size > dev->rom_info.size || 0 == size || (off + size) > dev->rom_info.size) {
+				ret = -EINVAL;
+				break;
+			}
+
+			kbuf = kmalloc(size, GFP_KERNEL);
+			if (!kbuf) {
+				ret = -ENOMEM;
+				break;
+			}
+
+			ret = ssd_spi_page_read(dev, kbuf, off, size);
+			if (ret) {
+				kfree(kbuf);
+				break;
+			}
+
+			if (copy_to_user(buf, kbuf, size)) {
+				hio_warn("%s: copy_to_user: failed\n", dev->name);
+				kfree(kbuf);
+				ret = -EFAULT;
+				break;
+			}
+
+			kfree(kbuf);
+
+			break;
+		}
+
+		case SSD_CMD_SPI_WRITE: {
+			struct ssd_spi_op_info spi_info;
+			uint32_t off, size;
+
+			if (copy_from_user(&spi_info, argp, sizeof(struct ssd_spi_op_info))) {
+				hio_warn("%s: copy_from_user: failed\n", dev->name);
+				ret = -EFAULT;
+				break;
+			}
+
+			off = spi_info.off;
+			size = spi_info.len;
+			buf = spi_info.buf;
+
+			if (size > dev->rom_info.size || 0 == size || (off + size) > dev->rom_info.size) {
+				ret = -EINVAL;
+				break;
+			}
+
+			kbuf = kmalloc(size, GFP_KERNEL);
+			if (!kbuf) {
+				ret = -ENOMEM;
+				break;
+			}
+
+			if (copy_from_user(kbuf, buf, size)) {
+				hio_warn("%s: copy_from_user: failed\n", dev->name);
+				kfree(kbuf);
+				ret = -EFAULT;
+				break;
+			}
+
+			ret = ssd_spi_page_write(dev, kbuf, off, size);
+			if (ret) {
+				kfree(kbuf);
+				break;
+			}
+
+			kfree(kbuf);
+
+			break;
+		}
+
+		case SSD_CMD_SPI_ERASE: {
+			struct ssd_spi_op_info spi_info;
+			uint32_t off;
+
+			if (copy_from_user(&spi_info, argp, sizeof(struct ssd_spi_op_info))) {
+				hio_warn("%s: copy_from_user: failed\n", dev->name);
+				ret = -EFAULT;
+				break;
+			}
+
+			off = spi_info.off;
+
+			if ((off + dev->rom_info.block_size) > dev->rom_info.size) {
+				ret = -EINVAL;
+				break;
+			}
+
+			ret = ssd_spi_block_erase(dev, off);
+			if (ret) {
+				break;
+			}
+
+			break;
+		}
+
+		case SSD_CMD_I2C_READ: {
+			struct ssd_i2c_op_info i2c_info;
+			uint8_t saddr;
+			uint8_t rsize;
+
+			if (copy_from_user(&i2c_info, argp, sizeof(struct ssd_i2c_op_info))) {
+				hio_warn("%s: copy_from_user: failed\n", dev->name);
+				ret = -EFAULT;
+				break;
+			}
+
+			saddr = i2c_info.saddr;
+			rsize = i2c_info.rsize;
+			buf = i2c_info.rbuf;
+
+			if (rsize <= 0 || rsize > SSD_I2C_MAX_DATA) {
+				ret = -EINVAL;
+				break;
+			}
+
+			kbuf = kmalloc(rsize, GFP_KERNEL);
+			if (!kbuf) {
+				ret = -ENOMEM;
+				break;
+			}
+
+			ret = ssd_i2c_read(dev, saddr, rsize, kbuf);
+			if (ret) {
+				kfree(kbuf);
+				break;
+			}
+
+			if (copy_to_user(buf, kbuf, rsize)) {
+				hio_warn("%s: copy_to_user: failed\n", dev->name);
+				kfree(kbuf);
+				ret = -EFAULT;
+				break;
+			}
+
+			kfree(kbuf);
+
+			break;
+		}
+
+		case SSD_CMD_I2C_WRITE: {
+			struct ssd_i2c_op_info i2c_info;
+			uint8_t saddr;
+			uint8_t wsize;
+
+			if (copy_from_user(&i2c_info, argp, sizeof(struct ssd_i2c_op_info))) {
+				hio_warn("%s: copy_from_user: failed\n", dev->name);
+				ret = -EFAULT;
+				break;
+			}
+
+			saddr = i2c_info.saddr;
+			wsize = i2c_info.wsize;
+			buf = i2c_info.wbuf;
+
+			if (wsize <= 0 || wsize > SSD_I2C_MAX_DATA) {
+				ret = -EINVAL;
+				break;
+			}
+
+			kbuf = kmalloc(wsize, GFP_KERNEL);
+			if (!kbuf) {
+				ret = -ENOMEM;
+				break;
+			}
+
+			if (copy_from_user(kbuf, buf, wsize)) {
+				hio_warn("%s: copy_from_user: failed\n", dev->name);
+				kfree(kbuf);
+				ret = -EFAULT;
+				break;
+			}
+
+			ret = ssd_i2c_write(dev, saddr, wsize, kbuf);
+			if (ret) {
+				kfree(kbuf);
+				break;
+			}
+
+			kfree(kbuf);
+
+			break;
+		}
+
+		case SSD_CMD_I2C_WRITE_READ: {
+			struct ssd_i2c_op_info i2c_info;
+			uint8_t saddr;
+			uint8_t wsize;
+			uint8_t rsize;
+			uint8_t size;
+
+			if (copy_from_user(&i2c_info, argp, sizeof(struct ssd_i2c_op_info))) {
+				hio_warn("%s: copy_from_user: failed\n", dev->name);
+				ret = -EFAULT;
+				break;
+			}
+
+			saddr = i2c_info.saddr;
+			wsize = i2c_info.wsize;
+			rsize = i2c_info.rsize;
+			buf = i2c_info.wbuf;
+
+			if (wsize <= 0 || wsize > SSD_I2C_MAX_DATA) {
+				ret = -EINVAL;
+				break;
+			}
+
+			if (rsize <= 0 || rsize > SSD_I2C_MAX_DATA) {
+				ret = -EINVAL;
+				break;
+			}
+
+			size = wsize + rsize;
+
+			kbuf = kmalloc(size, GFP_KERNEL);
+			if (!kbuf) {
+				ret = -ENOMEM;
+				break;
+			}
+
+			if (copy_from_user((kbuf + rsize), buf, wsize)) {
+				hio_warn("%s: copy_from_user: failed\n", dev->name);
+				kfree(kbuf);
+				ret = -EFAULT;
+				break;
+			}
+
+			buf = i2c_info.rbuf;
+
+			ret = ssd_i2c_write_read(dev, saddr, wsize, (kbuf + rsize), rsize, kbuf);
+			if (ret) {
+				kfree(kbuf);
+				break;
+			}
+
+			if (copy_to_user(buf, kbuf, rsize)) {
+				hio_warn("%s: copy_to_user: failed\n", dev->name);
+				kfree(kbuf);
+				ret = -EFAULT;
+				break;
+			}
+
+			kfree(kbuf);
+
+			break;
+		}
+
+		case SSD_CMD_SMBUS_SEND_BYTE: {
+			struct ssd_smbus_op_info smbus_info;
+			uint8_t smb_data[SSD_SMBUS_BLOCK_MAX];
+			uint8_t saddr;
+			uint8_t size;
+
+			if (copy_from_user(&smbus_info, argp, sizeof(struct ssd_smbus_op_info))) {
+				hio_warn("%s: copy_from_user: failed\n", dev->name);
+				ret = -EFAULT;
+				break;
+			}
+
+			saddr = smbus_info.saddr;
+			buf = smbus_info.buf;
+			size = 1;
+
+			if (copy_from_user(smb_data, buf, size)) {
+				hio_warn("%s: copy_from_user: failed\n", dev->name);
+				ret = -EFAULT;
+				break;
+			}
+
+			ret = ssd_smbus_send_byte(dev, saddr, smb_data);
+			if (ret) {
+				break;
+			}
+
+			break;
+		}
+
+		case SSD_CMD_SMBUS_RECEIVE_BYTE: {
+			struct ssd_smbus_op_info smbus_info;
+			uint8_t smb_data[SSD_SMBUS_BLOCK_MAX];
+			uint8_t saddr;
+			uint8_t size;
+
+			if (copy_from_user(&smbus_info, argp, sizeof(struct ssd_smbus_op_info))) {
+				hio_warn("%s: copy_from_user: failed\n", dev->name);
+				ret = -EFAULT;
+				break;
+			}
+
+			saddr = smbus_info.saddr;
+			buf = smbus_info.buf;
+			size = 1;
+
+			ret = ssd_smbus_receive_byte(dev, saddr, smb_data);
+			if (ret) {
+				break;
+			}
+
+			if (copy_to_user(buf, smb_data, size)) {
+				hio_warn("%s: copy_to_user: failed\n", dev->name);
+				ret = -EFAULT;
+				break;
+			}
+
+			break;
+		}
+
+		case SSD_CMD_SMBUS_WRITE_BYTE: {
+			struct ssd_smbus_op_info smbus_info;
+			uint8_t smb_data[SSD_SMBUS_BLOCK_MAX];
+			uint8_t saddr;
+			uint8_t command;
+			uint8_t size;
+
+			if (copy_from_user(&smbus_info, argp, sizeof(struct ssd_smbus_op_info))) {
+				hio_warn("%s: copy_from_user: failed\n", dev->name);
+				ret = -EFAULT;
+				break;
+			}
+
+			saddr = smbus_info.saddr;
+			command = smbus_info.cmd;
+			buf = smbus_info.buf;
+			size = 1;
+
+			if (copy_from_user(smb_data, buf, size)) {
+				hio_warn("%s: copy_from_user: failed\n", dev->name);
+				ret = -EFAULT;
+				break;
+			}
+
+			ret = ssd_smbus_write_byte(dev, saddr, command, smb_data);
+			if (ret) {
+				break;
+			}
+
+			break;
+		}
+
+		case SSD_CMD_SMBUS_READ_BYTE: {
+			struct ssd_smbus_op_info smbus_info;
+			uint8_t smb_data[SSD_SMBUS_BLOCK_MAX];
+			uint8_t saddr;
+			uint8_t command;
+			uint8_t size;
+
+			if (copy_from_user(&smbus_info, argp, sizeof(struct ssd_smbus_op_info))) {
+				hio_warn("%s: copy_from_user: failed\n", dev->name);
+				ret = -EFAULT;
+				break;
+			}
+
+			saddr = smbus_info.saddr;
+			command = smbus_info.cmd;
+			buf = smbus_info.buf;
+			size = 1;
+
+			ret = ssd_smbus_read_byte(dev, saddr, command, smb_data);
+			if (ret) {
+				break;
+			}
+
+			if (copy_to_user(buf, smb_data, size)) {
+				hio_warn("%s: copy_to_user: failed\n", dev->name);
+				ret = -EFAULT;
+				break;
+			}
+
+			break;
+		}
+
+		case SSD_CMD_SMBUS_WRITE_WORD: {
+			struct ssd_smbus_op_info smbus_info;
+			uint8_t smb_data[SSD_SMBUS_BLOCK_MAX];
+			uint8_t saddr;
+			uint8_t command;
+			uint8_t size;
+
+			if (copy_from_user(&smbus_info, argp, sizeof(struct ssd_smbus_op_info))) {
+				hio_warn("%s: copy_from_user: failed\n", dev->name);
+				ret = -EFAULT;
+				break;
+			}
+
+			saddr = smbus_info.saddr;
+			command = smbus_info.cmd;
+			buf = smbus_info.buf;
+			size = 2;
+
+			if (copy_from_user(smb_data, buf, size)) {
+				hio_warn("%s: copy_from_user: failed\n", dev->name);
+				ret = -EFAULT;
+				break;
+			}
+
+			ret = ssd_smbus_write_word(dev, saddr, command, smb_data);
+			if (ret) {
+				break;
+			}
+
+			break;
+		}
+
+		case SSD_CMD_SMBUS_READ_WORD: {
+			struct ssd_smbus_op_info smbus_info;
+			uint8_t smb_data[SSD_SMBUS_BLOCK_MAX];
+			uint8_t saddr;
+			uint8_t command;
+			uint8_t size;
+
+			if (copy_from_user(&smbus_info, argp, sizeof(struct ssd_smbus_op_info))) {
+				hio_warn("%s: copy_from_user: failed\n", dev->name);
+				ret = -EFAULT;
+				break;
+			}
+
+			saddr = smbus_info.saddr;
+			command = smbus_info.cmd;
+			buf = smbus_info.buf;
+			size = 2;
+
+			ret = ssd_smbus_read_word(dev, saddr, command, smb_data);
+			if (ret) {
+				break;
+			}
+
+			if (copy_to_user(buf, smb_data, size)) {
+				hio_warn("%s: copy_to_user: failed\n", dev->name);
+				ret = -EFAULT;
+				break;
+			}
+
+			break;
+		}
+
+		case SSD_CMD_SMBUS_WRITE_BLOCK: {
+			struct ssd_smbus_op_info smbus_info;
+			uint8_t smb_data[SSD_SMBUS_BLOCK_MAX];
+			uint8_t saddr;
+			uint8_t command;
+			uint8_t size;
+
+			if (copy_from_user(&smbus_info, argp, sizeof(struct ssd_smbus_op_info))) {
+				hio_warn("%s: copy_from_user: failed\n", dev->name);
+				ret = -EFAULT;
+				break;
+			}
+
+			saddr = smbus_info.saddr;
+			command = smbus_info.cmd;
+			buf = smbus_info.buf;
+			size = smbus_info.size;
+
+			if (size > SSD_SMBUS_BLOCK_MAX) {
+				ret = -EINVAL;
+				break;
+			}
+
+			if (copy_from_user(smb_data, buf, size)) {
+				hio_warn("%s: copy_from_user: failed\n", dev->name);
+				ret = -EFAULT;
+				break;
+			}
+
+			ret = ssd_smbus_write_block(dev, saddr, command, size, smb_data);
+			if (ret) {
+				break;
+			}
+
+			break;
+		}
+
+		case SSD_CMD_SMBUS_READ_BLOCK: {
+			struct ssd_smbus_op_info smbus_info;
+			uint8_t smb_data[SSD_SMBUS_BLOCK_MAX];
+			uint8_t saddr;
+			uint8_t command;
+			uint8_t size;
+
+			if (copy_from_user(&smbus_info, argp, sizeof(struct ssd_smbus_op_info))) {
+				hio_warn("%s: copy_from_user: failed\n", dev->name);
+				ret = -EFAULT;
+				break;
+			}
+
+			saddr = smbus_info.saddr;
+			command = smbus_info.cmd;
+			buf = smbus_info.buf;
+			size = smbus_info.size;
+
+			if (size > SSD_SMBUS_BLOCK_MAX) {
+				ret = -EINVAL;
+				break;
+			}
+
+			ret = ssd_smbus_read_block(dev, saddr, command, size, smb_data);
+			if (ret) {
+				break;
+			}
+
+			if (copy_to_user(buf, smb_data, size)) {
+				hio_warn("%s: copy_to_user: failed\n", dev->name);
+				ret = -EFAULT;
+				break;
+			}
+
+			break;
+		}
+
+		case SSD_CMD_BM_GET_VER: {
+			uint16_t ver;
+
+			ret = ssd_bm_get_version(dev, &ver);
+			if (ret) {
+				break;
+			}
+
+			if (copy_to_user(argp, &ver, sizeof(uint16_t))) {
+				hio_warn("%s: copy_to_user: failed\n", dev->name);
+				ret = -EFAULT;
+				break;
+			}
+
+			break;
+		}
+
+		case SSD_CMD_BM_GET_NR_CAP: {
+			int nr_cap;
+
+			ret = ssd_bm_nr_cap(dev, &nr_cap);
+			if (ret) {
+				break;
+			}
+
+			if (copy_to_user(argp, &nr_cap, sizeof(int))) {
+				hio_warn("%s: copy_to_user: failed\n", dev->name);
+				ret = -EFAULT;
+				break;
+			}
+
+			break;
+		}
+
+		case SSD_CMD_BM_CAP_LEARNING: {
+			ret = ssd_bm_enter_cap_learning(dev);
+
+			if (ret) {
+				break;
+			}
+
+			break;
+		}
+
+		case SSD_CMD_CAP_LEARN: {
+			uint32_t cap = 0;
+
+			ret = ssd_cap_learn(dev, &cap);
+			if (ret) {
+				break;
+			}
+
+			if (copy_to_user(argp, &cap, sizeof(uint32_t))) {
+				hio_warn("%s: copy_to_user: failed\n", dev->name);
+				ret = -EFAULT;
+				break;
+			}
+
+			break;
+		}
+
+		case SSD_CMD_GET_CAP_STATUS: {
+			int cap_status = 0;
+
+			if (test_bit(SSD_HWMON_PL_CAP(SSD_PL_CAP), &dev->hwmon)) {
+				cap_status = 1;
+			}
+
+			if (copy_to_user(argp, &cap_status, sizeof(int))) {
+				hio_warn("%s: copy_to_user: failed\n", dev->name);
+				ret = -EFAULT;
+				break;
+			}
+
+			break;
+		}
+
+		case SSD_CMD_RAM_READ: {
+			struct ssd_ram_op_info ram_info;
+			uint64_t ofs;
+			uint32_t length;
+			size_t rlen, len = dev->hw_info.ram_max_len;
+			int ctrl_idx;
+
+			if (copy_from_user(&ram_info, argp, sizeof(struct ssd_ram_op_info))) {
+				hio_warn("%s: copy_from_user: failed\n", dev->name);
+				ret = -EFAULT;
+				break;
+			}
+
+			ofs = ram_info.start;
+			length = ram_info.length;
+			buf = ram_info.buf;
+			ctrl_idx = ram_info.ctrl_idx;
+
+			if (ofs >= dev->hw_info.ram_size || length > dev->hw_info.ram_size || 0 == length || (ofs + length) > dev->hw_info.ram_size) {
+				ret = -EINVAL;
+				break;
+			}
+
+			kbuf = kmalloc(len, GFP_KERNEL);
+			if (!kbuf) {
+				ret = -ENOMEM;
+				break;
+			}
+
+			for (rlen=0; rlen<length; rlen+=len, buf+=len, ofs+=len) {
+				if ((length - rlen) < len) {
+					len = length - rlen;
+				}
+
+				ret = ssd_ram_read(dev, kbuf, len, ofs, ctrl_idx);
+				if (ret) {
+					break;
+				}
+
+				if (copy_to_user(buf, kbuf, len)) {
+					ret = -EFAULT;
+					break;
+				}
+			}
+
+			kfree(kbuf);
+
+			break;
+		}
+
+		case SSD_CMD_RAM_WRITE: {
+			struct ssd_ram_op_info ram_info;
+			uint64_t ofs;
+			uint32_t length;
+			size_t wlen, len = dev->hw_info.ram_max_len;
+			int ctrl_idx;
+
+			if (copy_from_user(&ram_info, argp, sizeof(struct ssd_ram_op_info))) {
+				hio_warn("%s: copy_from_user: failed\n", dev->name);
+				ret = -EFAULT;
+				break;
+			}
+			ofs = ram_info.start;
+			length = ram_info.length;
+			buf = ram_info.buf;
+			ctrl_idx = ram_info.ctrl_idx;
+
+			if (ofs >= dev->hw_info.ram_size || length > dev->hw_info.ram_size || 0 == length || (ofs + length) > dev->hw_info.ram_size) {
+				ret = -EINVAL;
+				break;
+			}
+
+			kbuf = kmalloc(len, GFP_KERNEL);
+			if (!kbuf) {
+				ret = -ENOMEM;
+				break;
+			}
+
+			for (wlen=0; wlen<length; wlen+=len, buf+=len, ofs+=len) {
+				if ((length - wlen) < len) {
+					len = length - wlen;
+				}
+
+				if (copy_from_user(kbuf, buf, len)) {
+					ret = -EFAULT;
+					break;
+				}
+
+				ret = ssd_ram_write(dev, kbuf, len, ofs, ctrl_idx);
+				if (ret) {
+					break;
+				}
+			}
+
+			kfree(kbuf);
+
+			break;
+		}
+
+		case SSD_CMD_NAND_READ_ID: {
+			struct ssd_flash_op_info flash_info;
+			int chip_no, chip_ce, length, ctrl_idx;
+
+			if (copy_from_user(&flash_info, argp, sizeof(struct ssd_flash_op_info))) {
+				hio_warn("%s: copy_from_user: failed\n", dev->name);
+				ret = -EFAULT;
+				break;
+			}
+
+			chip_no = flash_info.flash;
+			chip_ce = flash_info.chip;
+			ctrl_idx = flash_info.ctrl_idx;
+			buf = flash_info.buf;
+			length = dev->hw_info.id_size;
+
+			//kbuf = kmalloc(length, GFP_KERNEL);
+			kbuf = kmalloc(SSD_NAND_ID_BUFF_SZ, GFP_KERNEL); //xx
+			if (!kbuf) {
+				ret = -ENOMEM;
+				break;
+			}
+			memset(kbuf, 0, length);
+
+			ret = ssd_nand_read_id(dev, kbuf, chip_no, chip_ce, ctrl_idx);
+ 			if (ret) {
+				kfree(kbuf);
+				break;
+			}
+
+			if (copy_to_user(buf, kbuf, length)) {
+				kfree(kbuf);
+				ret = -EFAULT;
+				break;
+			}
+
+			kfree(kbuf);
+
+			break;
+		}
+
+		case SSD_CMD_NAND_READ: {	//with oob
+			struct ssd_flash_op_info flash_info;
+			uint32_t length;
+			int flash, chip, page, ctrl_idx;
+			int err = 0;
+
+			if (copy_from_user(&flash_info, argp, sizeof(struct ssd_flash_op_info))) {
+				hio_warn("%s: copy_from_user: failed\n", dev->name);
+				ret = -EFAULT;
+				break;
+			}
+
+			flash = flash_info.flash;
+			chip = flash_info.chip;
+			page = flash_info.page;
+			buf = flash_info.buf;
+			ctrl_idx = flash_info.ctrl_idx;
+
+			length = dev->hw_info.page_size + dev->hw_info.oob_size;
+
+			kbuf = kmalloc(length, GFP_KERNEL);
+			if (!kbuf) {
+				ret = -ENOMEM;
+				break;
+			}
+
+			err = ret = ssd_nand_read_w_oob(dev, kbuf, flash, chip, page, 1, ctrl_idx);
+			if (ret && (-EIO != ret)) {
+				kfree(kbuf);
+				break;
+			}
+
+			if (copy_to_user(buf, kbuf, length)) {
+				kfree(kbuf);
+				ret = -EFAULT;
+				break;
+			}
+
+			ret = err;
+
+			kfree(kbuf);
+			break;
+		}
+
+		case SSD_CMD_NAND_WRITE: {
+			struct ssd_flash_op_info flash_info;
+			int flash, chip, page, ctrl_idx;
+			uint32_t length;
+
+			if (copy_from_user(&flash_info, argp, sizeof(struct ssd_flash_op_info))) {
+				hio_warn("%s: copy_from_user: failed\n", dev->name);
+				ret = -EFAULT;
+				break;
+			}
+
+			flash = flash_info.flash;
+			chip = flash_info.chip;
+			page = flash_info.page;
+			buf = flash_info.buf;
+			ctrl_idx = flash_info.ctrl_idx;
+
+			length = dev->hw_info.page_size + dev->hw_info.oob_size;
+
+			kbuf = kmalloc(length, GFP_KERNEL);
+			if (!kbuf) {
+				ret = -ENOMEM;
+				break;
+			}
+
+			if (copy_from_user(kbuf, buf, length)) {
+				kfree(kbuf);
+				ret = -EFAULT;
+				break;
+			}
+
+			ret = ssd_nand_write(dev, kbuf, flash, chip, page, 1, ctrl_idx);
+			if (ret) {
+				kfree(kbuf);
+				break;
+			}
+
+			kfree(kbuf);
+			break;
+		}
+
+		case SSD_CMD_NAND_ERASE: {
+			struct ssd_flash_op_info flash_info;
+			int flash, chip, page, ctrl_idx;
+
+			if (copy_from_user(&flash_info, argp, sizeof(struct ssd_flash_op_info))) {
+				hio_warn("%s: copy_from_user: failed\n", dev->name);
+				ret = -EFAULT;
+				break;
+			}
+
+			flash = flash_info.flash;
+			chip = flash_info.chip;
+			page = flash_info.page;
+			ctrl_idx = flash_info.ctrl_idx;
+
+			if ((page % dev->hw_info.page_count) != 0) {
+				ret = -EINVAL;
+				break;
+			}
+
+			//hio_warn("erase fs = %llx\n", ofs);
+			ret = ssd_nand_erase(dev, flash, chip, page, ctrl_idx);
+			if (ret) {
+				break;
+			}
+
+			break;
+		}
+
+		case SSD_CMD_NAND_READ_EXT: {	//ingore EIO
+			struct ssd_flash_op_info flash_info;
+			uint32_t length;
+			int flash, chip, page, ctrl_idx;
+
+			if (copy_from_user(&flash_info, argp, sizeof(struct ssd_flash_op_info))) {
+				hio_warn("%s: copy_from_user: failed\n", dev->name);
+				ret = -EFAULT;
+				break;
+			}
+
+			flash = flash_info.flash;
+			chip = flash_info.chip;
+			page = flash_info.page;
+			buf = flash_info.buf;
+			ctrl_idx = flash_info.ctrl_idx;
+
+			length = dev->hw_info.page_size + dev->hw_info.oob_size;
+
+			kbuf = kmalloc(length, GFP_KERNEL);
+			if (!kbuf) {
+				ret = -ENOMEM;
+				break;
+			}
+
+			ret = ssd_nand_read_w_oob(dev, kbuf, flash, chip, page, 1, ctrl_idx);
+			if (-EIO == ret) {	//ingore EIO
+				ret = 0;
+			}
+			if (ret) {
+				kfree(kbuf);
+				break;
+			}
+
+			if (copy_to_user(buf, kbuf, length)) {
+				kfree(kbuf);
+				ret = -EFAULT;
+				break;
+			}
+
+			kfree(kbuf);
+			break;
+		}
+
+		case SSD_CMD_UPDATE_BBT: {
+			struct ssd_flash_op_info flash_info;
+			int ctrl_idx, flash;
+
+			if (copy_from_user(&flash_info, argp, sizeof(struct ssd_flash_op_info))) {
+				hio_warn("%s: copy_from_user: failed\n", dev->name);
+				ret = -EFAULT;
+				break;
+			}
+
+			ctrl_idx = flash_info.ctrl_idx;
+			flash = flash_info.flash;
+			ret = ssd_update_bbt(dev, flash, ctrl_idx);
+			if (ret) {
+				break;
+			}
+
+			break;
+		}
+
+		case SSD_CMD_CLEAR_ALARM:
+			ssd_clear_alarm(dev);
+			break;
+
+		case SSD_CMD_SET_ALARM:
+			ssd_set_alarm(dev);
+			break;
+
+		case SSD_CMD_RESET:
+			ret = ssd_do_reset(dev);
+			break;
+
+		case SSD_CMD_RELOAD_FW:
+			dev->reload_fw = 1;
+			if (dev->protocol_info.ver >= SSD_PROTOCOL_V3_2) {
+				ssd_reg32_write(dev->ctrlp + SSD_RELOAD_FW_REG, SSD_RELOAD_FLAG);
+			} else if (dev->protocol_info.ver >= SSD_PROTOCOL_V3_1_1) {
+				ssd_reg32_write(dev->ctrlp + SSD_RELOAD_FW_REG, SSD_RELOAD_FW);
+				
+			}
+			break;
+
+		case SSD_CMD_UNLOAD_DEV: {
+			if (atomic_read(&dev->refcnt)) {
+				ret = -EBUSY;
+				break;
+			}
+
+			/* save smart */
+			ssd_save_smart(dev);
+
+			ret = ssd_flush(dev);
+			if (ret) {
+				break;
+			}
+
+			/* cleanup the block device */
+			if (test_and_clear_bit(SSD_INIT_BD, &dev->state)) {
+				mutex_lock(&dev->gd_mutex);
+				ssd_cleanup_blkdev(dev);
+				mutex_unlock(&dev->gd_mutex);
+			}
+
+			break;
+		}
+
+		case SSD_CMD_LOAD_DEV: {
+
+			if (test_bit(SSD_INIT_BD, &dev->state)) {
+				ret = -EINVAL;
+				break;
+			}
+
+			ret = ssd_init_smart(dev);
+			if (ret) {
+				hio_warn("%s: init info: failed\n", dev->name);
+				break;
+			}
+
+			ret = ssd_init_blkdev(dev);
+			if (ret) {
+				hio_warn("%s: register block device: failed\n", dev->name);
+				break;
+			}
+			(void)test_and_set_bit(SSD_INIT_BD, &dev->state);
+
+			break;
+		}
+
+		case SSD_CMD_UPDATE_VP: {
+			uint32_t val;
+			uint32_t new_vp, new_vp1 = 0;
+
+			if (test_bit(SSD_INIT_BD, &dev->state)) {
+				ret = -EINVAL;
+				break;
+			}
+
+			if (copy_from_user(&new_vp, argp, sizeof(uint32_t))) {
+				hio_warn("%s: copy_from_user: failed\n", dev->name);
+				ret = -EFAULT;
+				break;
+			}
+
+			if (new_vp > dev->hw_info.max_valid_pages || new_vp <= 0) {
+				ret = -EINVAL;
+				break;
+			}
+
+			while (new_vp <= dev->hw_info.max_valid_pages) {
+				ssd_reg32_write(dev->ctrlp + SSD_VALID_PAGES_REG, new_vp);
+				msleep(10);
+				val = ssd_reg32_read(dev->ctrlp + SSD_VALID_PAGES_REG);
+				if (dev->protocol_info.ver < SSD_PROTOCOL_V3_2) {
+					new_vp1 = val & 0x3FF;
+				} else {
+					new_vp1 = val & 0x7FFF;
+				}
+
+				if (new_vp1 == new_vp) {
+					break;
+				}
+
+				new_vp++;
+				/*if (new_vp == dev->hw_info.valid_pages) {
+					new_vp++;
+				}*/
+			}
+
+			if (new_vp1 != new_vp || new_vp > dev->hw_info.max_valid_pages) {
+				/* restore */
+				ssd_reg32_write(dev->ctrlp + SSD_VALID_PAGES_REG, dev->hw_info.valid_pages);
+				ret = -EINVAL;
+				break;
+			}
+
+			if (copy_to_user(argp, &new_vp, sizeof(uint32_t))) {
+				hio_warn("%s: copy_to_user: failed\n", dev->name);
+				ssd_reg32_write(dev->ctrlp + SSD_VALID_PAGES_REG, dev->hw_info.valid_pages);
+				ret = -EFAULT;
+				break;
+			}
+
+			/* new */
+			dev->hw_info.valid_pages = new_vp;
+			dev->hw_info.size = (uint64_t)dev->hw_info.valid_pages * dev->hw_info.page_size;
+			dev->hw_info.size *= (dev->hw_info.block_count - dev->hw_info.reserved_blks);
+			dev->hw_info.size *= ((uint64_t)dev->hw_info.nr_data_ch * (uint64_t)dev->hw_info.nr_chip * (uint64_t)dev->hw_info.nr_ctrl);
+
+			break;
+		}
+
+		case SSD_CMD_FULL_RESET: {
+			ret = ssd_full_reset(dev);
+			break;
+		}
+
+		case SSD_CMD_GET_NR_LOG: {
+			if (copy_to_user(argp, &dev->internal_log.nr_log, sizeof(dev->internal_log.nr_log))) {
+				ret = -EFAULT;
+				break;
+			}
+			break;
+		}
+
+		case SSD_CMD_GET_LOG: {
+			uint32_t length = dev->rom_info.log_sz;
+
+			buf = argp;
+
+			if (copy_to_user(buf, dev->internal_log.log, length)) {
+				ret = -EFAULT;
+				break;
+			}
+
+			break;
+		}
+
+		case SSD_CMD_LOG_LEVEL: {
+			int level = 0;
+			if (copy_from_user(&level, argp, sizeof(int))) {
+				hio_warn("%s: copy_from_user: failed\n", dev->name);
+				ret = -EFAULT;
+				break;
+			}
+
+			if (level >= SSD_LOG_NR_LEVEL || level < SSD_LOG_LEVEL_INFO) {
+				level = SSD_LOG_LEVEL_ERR;
+			}
+
+			//just for showing log, no need to protect
+			log_level = level;
+			break;
+		}
+
+		case SSD_CMD_OT_PROTECT: {
+			int protect = 0;
+
+			if (copy_from_user(&protect, argp, sizeof(int))) {
+				hio_warn("%s: copy_from_user: failed\n", dev->name);
+				ret = -EFAULT;
+				break;
+			}
+
+			ssd_set_ot_protect(dev, !!protect);
+			break;
+		}
+
+		case SSD_CMD_GET_OT_STATUS: {
+			int status = ssd_get_ot_status(dev, &status);
+
+			if (copy_to_user(argp, &status, sizeof(int))) {
+				hio_warn("%s: copy_to_user: failed\n", dev->name);
+				ret = -EFAULT;
+				break;
+			}
+			break;
+		}
+
+		case SSD_CMD_CLEAR_LOG: {
+			ret = ssd_clear_log(dev);
+			break;
+		}
+
+		case SSD_CMD_CLEAR_SMART: {
+			ret = ssd_clear_smart(dev);
+			break;
+		}
+
+		case SSD_CMD_SW_LOG: {
+			struct ssd_sw_log_info sw_log;
+
+			if (copy_from_user(&sw_log, argp, sizeof(struct ssd_sw_log_info))) {
+				hio_warn("%s: copy_from_user: failed\n", dev->name);
+				ret = -EFAULT;
+				break;
+			}
+
+			ret = ssd_gen_swlog(dev, sw_log.event, sw_log.data);
+			break;
+		}
+
+		case SSD_CMD_GET_LABEL: {
+
+			if (dev->protocol_info.ver >= SSD_PROTOCOL_V3_2) {
+				ret = -EINVAL;
+				break;
+			}
+			
+			if (copy_to_user(argp, &dev->label, sizeof(struct ssd_label))) {
+				hio_warn("%s: copy_to_user: failed\n", dev->name);
+				ret = -EFAULT;
+				break;
+			}
+			break;
+		}
+
+		case SSD_CMD_GET_VERSION: {
+			struct ssd_version_info ver;
+
+			mutex_lock(&dev->fw_mutex);
+			ret = __ssd_get_version(dev, &ver);
+			mutex_unlock(&dev->fw_mutex);
+			if (ret) {
+				break;
+			}
+
+			if (copy_to_user(argp, &ver, sizeof(struct ssd_version_info))) {
+				hio_warn("%s: copy_to_user: failed\n", dev->name);
+				ret = -EFAULT;
+				break;
+			}
+			break;
+		}
+
+		case SSD_CMD_GET_TEMPERATURE: {
+			int temp;
+
+			mutex_lock(&dev->fw_mutex);
+			ret = __ssd_get_temperature(dev, &temp);
+			mutex_unlock(&dev->fw_mutex);
+			if (ret) {
+				break;
+			}
+
+			if (copy_to_user(argp, &temp, sizeof(int))) {
+				hio_warn("%s: copy_to_user: failed\n", dev->name);
+				ret = -EFAULT;
+				break;
+			}
+			break;
+		}
+
+		case SSD_CMD_GET_BMSTATUS: {
+			int status;
+
+			mutex_lock(&dev->fw_mutex);
+			if (dev->protocol_info.ver >= SSD_PROTOCOL_V3_2) {
+				if (test_bit(SSD_HWMON_PL_CAP(SSD_PL_CAP), &dev->hwmon)) {
+					status = SSD_BMSTATUS_WARNING;
+				} else {
+					status = SSD_BMSTATUS_OK;
+				}
+			} else if(dev->protocol_info.ver > SSD_PROTOCOL_V3) {
+				ret = __ssd_bm_status(dev, &status);
+			} else {
+				status = SSD_BMSTATUS_OK;
+			}
+			mutex_unlock(&dev->fw_mutex);
+			if (ret) {
+				break;
+			}
+
+			if (copy_to_user(argp, &status, sizeof(int))) {
+				hio_warn("%s: copy_to_user: failed\n", dev->name);
+				ret = -EFAULT;
+				break;
+			}
+			break;
+		}
+
+		case SSD_CMD_GET_LABEL2: {
+			void *label;
+			int length;
+
+			if (dev->protocol_info.ver < SSD_PROTOCOL_V3_2) {
+				label = &dev->label;
+				length = sizeof(struct ssd_label);
+			} else {
+				label = &dev->labelv3;
+				length = sizeof(struct ssd_labelv3);
+			}
+
+			if (copy_to_user(argp, label, length)) {
+				ret = -EFAULT;
+				break;
+			}
+			break;
+		}
+
+		case SSD_CMD_FLUSH:
+			ret = ssd_flush(dev);
+			if (ret) {
+				hio_warn("%s: ssd_flush: failed\n", dev->name);
+				ret = -EFAULT;
+				break;
+			}
+			break;
+
+		case SSD_CMD_SAVE_MD: {
+			int save_md = 0;
+
+			if (copy_from_user(&save_md, argp, sizeof(int))) {
+				hio_warn("%s: copy_from_user: failed\n", dev->name);
+				ret = -EFAULT;
+				break;
+			}
+
+			dev->save_md = !!save_md;
+			break;
+		}
+
+		case SSD_CMD_SET_WMODE: {
+			int new_wmode = 0;
+			
+			if (copy_from_user(&new_wmode, argp, sizeof(int))) {
+				hio_warn("%s: copy_from_user: failed\n", dev->name);
+				ret = -EFAULT;
+				break;
+			}
+
+			ret = __ssd_set_wmode(dev, new_wmode);
+			if (ret) {
+				break;
+			}
+			
+			break;
+		}
+
+		case SSD_CMD_GET_WMODE: {
+			if (copy_to_user(argp, &dev->wmode, sizeof(int))) {
+				hio_warn("%s: copy_to_user: failed\n", dev->name);
+				ret = -EFAULT;
+				break;
+			}
+			
+			break;
+		}
+
+		case SSD_CMD_GET_USER_WMODE: {
+			if (copy_to_user(argp, &dev->user_wmode, sizeof(int))) {
+				hio_warn("%s: copy_to_user: failed\n", dev->name);
+				ret = -EFAULT;
+				break;
+			}
+			
+			break;
+		}
+
+		case SSD_CMD_DEBUG: {
+			struct ssd_debug_info db_info;
+
+			if (!finject) {
+				ret = -EOPNOTSUPP;
+				break;
+			}
+
+			if (copy_from_user(&db_info, argp, sizeof(struct ssd_debug_info))) {
+				hio_warn("%s: copy_from_user: failed\n", dev->name);
+				ret = -EFAULT;
+				break;
+			}
+
+			if (db_info.type < SSD_DEBUG_NONE || db_info.type >= SSD_DEBUG_NR) {
+				ret = -EINVAL;
+				break;
+			}
+
+			/* IO */
+			if (db_info.type >= SSD_DEBUG_READ_ERR && db_info.type <= SSD_DEBUG_RW_ERR && 
+				(db_info.data.loc.off + db_info.data.loc.len) > (dev->hw_info.size >> 9)) {
+				ret = -EINVAL;
+				break;
+			}
+
+			memcpy(&dev->db_info, &db_info, sizeof(struct ssd_debug_info));
+
+#ifdef SSD_OT_PROTECT
+			/* temperature */
+			if (db_info.type == SSD_DEBUG_NONE) {
+				ssd_check_temperature(dev, SSD_OT_TEMP);
+			} else if (db_info.type == SSD_DEBUG_LOG) {
+				if (db_info.data.log.event == SSD_LOG_OVER_TEMP) {
+					dev->ot_delay = SSD_OT_DELAY;
+				} else if (db_info.data.log.event == SSD_LOG_NORMAL_TEMP) {
+					dev->ot_delay = 0;
+				}
+			}
+#endif
+
+			/* offline */
+			if (db_info.type == SSD_DEBUG_OFFLINE) {
+				test_and_clear_bit(SSD_ONLINE, &dev->state);
+			} else if (db_info.type == SSD_DEBUG_NONE) {
+				(void)test_and_set_bit(SSD_ONLINE, &dev->state);
+			}
+
+			/* log */
+			if (db_info.type == SSD_DEBUG_LOG && dev->event_call && dev->gd) {
+				dev->event_call(dev->gd, db_info.data.log.event, 0);
+			}
+
+			break;
+		}
+
+		case SSD_CMD_DRV_PARAM_INFO: {
+			struct ssd_drv_param_info drv_param;
+
+			memset(&drv_param, 0, sizeof(struct ssd_drv_param_info));
+
+			drv_param.mode = mode;
+			drv_param.status_mask = status_mask;
+			drv_param.int_mode = int_mode;
+			drv_param.threaded_irq = threaded_irq;
+			drv_param.log_level = log_level;
+			drv_param.wmode = wmode;
+			drv_param.ot_protect = ot_protect;
+			drv_param.finject = finject;
+
+			if (copy_to_user(argp, &drv_param, sizeof(struct ssd_drv_param_info))) {
+				hio_warn("%s: copy_to_user: failed\n", dev->name);
+				ret = -EFAULT;
+				break;
+			}
+			break;
+		}
+
+		default:
+			ret = -EINVAL;
+			break;
+	}
+
+	return ret;
+}
+
+
+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,27))
+static int ssd_block_ioctl(struct inode *inode, struct file *file, 
+		unsigned int cmd, unsigned long arg)
+{
+	struct ssd_device *dev;
+	void __user *argp = (void __user *)arg;
+	int ret = 0;
+
+	if (!inode) {
+		return -EINVAL;
+	}
+	dev = inode->i_bdev->bd_disk->private_data;
+	if (!dev) {
+		return -EINVAL;
+	}
+#else
+static int ssd_block_ioctl(struct block_device *bdev, fmode_t mode, 
+		unsigned int cmd, unsigned long arg)
+{
+	struct ssd_device *dev;
+	void __user *argp = (void __user *)arg;
+	int ret = 0;
+
+	if (!bdev) {
+		return -EINVAL;
+	}
+
+	dev = bdev->bd_disk->private_data;
+	if (!dev) {
+		return -EINVAL;
+	}
+#endif
+
+	switch (cmd) {
+		case HDIO_GETGEO: {
+			struct hd_geometry geo;
+			geo.cylinders = (dev->hw_info.size & ~0x3f) >> 6;
+			geo.heads = 4;
+			geo.sectors = 16;
+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,27))
+			geo.start = get_start_sect(inode->i_bdev);
+#else
+			geo.start = get_start_sect(bdev);
+#endif
+			if (copy_to_user(argp, &geo, sizeof(geo))) {
+				ret = -EFAULT;
+				break;
+			}
+
+			break;
+		}
+
+		case BLKFLSBUF:
+			ret = ssd_flush(dev);
+			if (ret) {
+				hio_warn("%s: ssd_flush: failed\n", dev->name);
+				ret = -EFAULT;
+				break;
+			}
+			break;
+
+		default:
+			if (!dev->slave) {
+				ret = ssd_ioctl_common(dev, cmd, arg);
+			} else {
+				ret = -EFAULT;
+			}
+			break;
+	}
+
+	return ret;
+}
+
+
+static void ssd_free_dev(struct kref *kref)
+{
+	struct ssd_device *dev;
+
+	if (!kref) {
+		return;
+	}
+
+	dev = container_of(kref, struct ssd_device, kref);
+
+	put_disk(dev->gd);
+
+	ssd_put_index(dev->slave, dev->idx);
+
+	kfree(dev);
+}
+
+static void ssd_put(struct ssd_device *dev)
+{
+	kref_put(&dev->kref, ssd_free_dev);
+}
+
+static int ssd_get(struct ssd_device *dev)
+{
+	kref_get(&dev->kref);
+	return 0;
+}
+
+/* block device */
+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,27))
+static int ssd_block_open(struct inode *inode, struct file *filp)
+{
+	struct ssd_device *dev;
+
+	if (!inode) {
+		return -EINVAL;
+	}
+
+	dev = inode->i_bdev->bd_disk->private_data;
+	if (!dev) {
+		return -EINVAL;
+	}
+#else
+static int ssd_block_open(struct block_device *bdev, fmode_t mode)
+{
+	struct ssd_device *dev;
+
+	if (!bdev) {
+		return -EINVAL;
+	}
+
+	dev = bdev->bd_disk->private_data;
+	if (!dev) {
+		return -EINVAL;
+	}
+#endif
+
+	/*if (!try_module_get(dev->owner))
+		return -ENODEV;
+	*/
+
+	ssd_get(dev);
+
+	atomic_inc(&dev->refcnt);
+
+	return 0;
+}
+
+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,27))
+static int ssd_block_release(struct inode *inode, struct file *filp)
+{
+	struct ssd_device *dev;
+
+	if (!inode) {
+		return -EINVAL;
+	}
+
+	dev = inode->i_bdev->bd_disk->private_data;
+	if (!dev) {
+		return -EINVAL;
+	}
+#elif (LINUX_VERSION_CODE <= KERNEL_VERSION(3,9,0))
+static int ssd_block_release(struct gendisk *disk, fmode_t mode)
+{
+	struct ssd_device *dev;
+
+	if (!disk) {
+		return -EINVAL;
+	}
+
+	dev = disk->private_data;
+	if (!dev) {
+		return -EINVAL;
+	}
+#else
+static void ssd_block_release(struct gendisk *disk, fmode_t mode)
+{
+	struct ssd_device *dev;
+
+	if (!disk) {
+		return;
+	}
+
+	dev = disk->private_data;
+	if (!dev) {
+		return;
+	}
+#endif
+
+	atomic_dec(&dev->refcnt);
+
+	ssd_put(dev);
+
+	//module_put(dev->owner);
+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(3,9,0))
+	return 0;
+#endif
+}
+
+static struct block_device_operations ssd_fops = {
+	.owner		= THIS_MODULE,
+	.open		= ssd_block_open,
+	.release	= ssd_block_release,
+	.ioctl		= ssd_block_ioctl,
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16))
+	.getgeo		= ssd_block_getgeo,
+#endif
+};
+
+static void ssd_init_trim(ssd_device_t *dev)
+{
+#if (defined SSD_TRIM && (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32)))
+	if (dev->protocol_info.ver <= SSD_PROTOCOL_V3) {
+		return;
+	}
+	queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, dev->rq);
+
+#if ((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,33)) || (defined RHEL_MAJOR && RHEL_MAJOR >= 6))
+	dev->rq->limits.discard_zeroes_data = 1;
+	dev->rq->limits.discard_alignment = 4096;
+	dev->rq->limits.discard_granularity = 4096;
+#endif
+	if (dev->protocol_info.ver < SSD_PROTOCOL_V3_2_4) {
+		dev->rq->limits.max_discard_sectors = dev->hw_info.sg_max_sec;
+	} else {
+		dev->rq->limits.max_discard_sectors = (dev->hw_info.sg_max_sec) * (dev->hw_info.cmd_max_sg);
+	}
+#endif
+}
+
+static void ssd_cleanup_queue(struct ssd_device *dev)
+{
+	ssd_wait_io(dev);
+
+	blk_cleanup_queue(dev->rq);
+	dev->rq = NULL;
+}
+
+static int ssd_init_queue(struct ssd_device *dev)
+{
+	dev->rq = blk_alloc_queue(GFP_KERNEL);
+	if (dev->rq == NULL) {
+		hio_warn("%s: alloc queue: failed\n ", dev->name);
+		goto out_init_queue;
+	}
+
+	/* must be first */
+	blk_queue_make_request(dev->rq, ssd_make_request);
+
+#if ((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,34)) && !(defined RHEL_MAJOR && RHEL_MAJOR == 6))
+	blk_queue_max_hw_segments(dev->rq, dev->hw_info.cmd_max_sg);
+	blk_queue_max_phys_segments(dev->rq, dev->hw_info.cmd_max_sg);
+	blk_queue_max_sectors(dev->rq, dev->hw_info.sg_max_sec);
+#else
+	blk_queue_max_segments(dev->rq, dev->hw_info.cmd_max_sg);
+	blk_queue_max_hw_sectors(dev->rq, dev->hw_info.sg_max_sec);
+#endif
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,31))
+	blk_queue_hardsect_size(dev->rq, 512);
+#else
+	blk_queue_logical_block_size(dev->rq, 512);
+#endif
+	/* not work for make_request based drivers(bio) */
+	blk_queue_max_segment_size(dev->rq, dev->hw_info.sg_max_sec << 9);
+
+	blk_queue_bounce_limit(dev->rq, BLK_BOUNCE_HIGH);
+
+	dev->rq->queuedata = dev;
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20))
+	blk_queue_issue_flush_fn(dev->rq, ssd_issue_flush_fn);
+#endif
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28))
+	queue_flag_set_unlocked(QUEUE_FLAG_NONROT, dev->rq);
+#endif
+
+	ssd_init_trim(dev);
+
+	return 0;
+
+out_init_queue:
+	return -ENOMEM;
+}
+
+static void ssd_cleanup_blkdev(struct ssd_device *dev)
+{
+	del_gendisk(dev->gd);
+}
+
+static int ssd_init_blkdev(struct ssd_device *dev)
+{
+	if (dev->gd) {
+		put_disk(dev->gd);
+	}
+
+	dev->gd = alloc_disk(ssd_minors);
+	if (!dev->gd) {
+		hio_warn("%s: alloc_disk fail\n", dev->name);
+		goto out_alloc_gd;
+	}
+	dev->gd->major = dev->major;
+	dev->gd->first_minor = dev->idx * ssd_minors;
+	dev->gd->fops = &ssd_fops;
+	dev->gd->queue = dev->rq;
+	dev->gd->private_data = dev;
+	dev->gd->driverfs_dev = &dev->pdev->dev;
+	snprintf (dev->gd->disk_name, sizeof(dev->gd->disk_name), "%s", dev->name);
+
+	set_capacity(dev->gd, dev->hw_info.size >> 9);
+
+	add_disk(dev->gd);
+
+	return 0;
+
+out_alloc_gd:
+	return -ENOMEM;
+}
+
+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,10))
+static int ssd_ioctl(struct inode *inode, struct file *file, 
+		unsigned int cmd, unsigned long arg)
+#else
+static long ssd_ioctl(struct file *file, 
+		unsigned int cmd, unsigned long arg)
+#endif
+{
+	struct ssd_device *dev;
+
+	if (!file) {
+		return -EINVAL;
+	}
+
+	dev = file->private_data;
+	if (!dev) {
+		return -EINVAL;
+	}
+
+	return (long)ssd_ioctl_common(dev, cmd, arg);
+}
+
+static int ssd_open(struct inode *inode, struct file *file)
+{
+	struct ssd_device *dev = NULL;
+	struct ssd_device *n = NULL;
+	int idx;
+	int ret = -ENODEV;
+
+	if (!inode || !file) {
+		return -EINVAL;
+	}
+
+	idx = iminor(inode);
+
+	list_for_each_entry_safe(dev, n, &ssd_list, list) {
+		if (dev->idx == idx) {
+			ret = 0;
+			break;
+		}
+	}
+
+	if (ret) {
+		return ret;
+	}
+
+	file->private_data = dev;
+
+	ssd_get(dev);
+
+	return 0;
+}
+
+static int ssd_release(struct inode *inode, struct file *file)
+{
+	struct ssd_device *dev;
+
+	if (!file) {
+		return -EINVAL;
+	}
+
+	dev = file->private_data;
+	if (!dev) {
+		return -EINVAL;
+	}
+
+	ssd_put(dev);
+
+	file->private_data = NULL;
+
+	return 0;
+}
+
+static struct file_operations ssd_cfops = {
+	.owner		= THIS_MODULE, 
+	.open		= ssd_open, 
+	.release	= ssd_release, 
+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,10))
+	.ioctl		= ssd_ioctl,
+#else
+	.unlocked_ioctl = ssd_ioctl, 
+#endif
+};
+
+static void ssd_cleanup_chardev(struct ssd_device *dev)
+{
+	if (dev->slave) {
+		return;
+	}
+
+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,12))
+	class_simple_device_remove(MKDEV((dev_t)dev->cmajor, (dev_t)dev->idx));
+	devfs_remove("c%s", dev->name);
+#elif (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,14))
+	class_device_destroy(ssd_class, MKDEV((dev_t)dev->cmajor, (dev_t)dev->idx));
+	devfs_remove("c%s", dev->name);
+#elif (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,17))
+	class_device_destroy(ssd_class, MKDEV((dev_t)dev->cmajor, (dev_t)dev->idx));
+	devfs_remove("c%s", dev->name);
+#elif (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,24))
+	class_device_destroy(ssd_class, MKDEV((dev_t)dev->cmajor, (dev_t)dev->idx));
+#else
+	device_destroy(ssd_class, MKDEV((dev_t)dev->cmajor, (dev_t)dev->idx));
+#endif
+}
+
+static int ssd_init_chardev(struct ssd_device *dev)
+{
+	int ret = 0;
+
+	if (dev->slave) {
+		return 0;
+	}
+
+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,12))
+	ret = devfs_mk_cdev(MKDEV((dev_t)dev->cmajor, (dev_t)dev->idx), S_IFCHR|S_IRUSR|S_IWUSR, "c%s", dev->name);
+	if (ret) {
+		goto out;
+	}
+	class_simple_device_add(ssd_class, MKDEV((dev_t)dev->cmajor, (dev_t)dev->idx), NULL, "c%s", dev->name);
+out:
+#elif (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,14))
+	ret = devfs_mk_cdev(MKDEV((dev_t)dev->cmajor, (dev_t)dev->idx), S_IFCHR|S_IRUSR|S_IWUSR, "c%s", dev->name);
+	if (ret) {
+		goto out;
+	}
+	class_device_create(ssd_class, MKDEV((dev_t)dev->cmajor, (dev_t)dev->idx), NULL, "c%s", dev->name);
+out:
+#elif (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,17))
+	ret = devfs_mk_cdev(MKDEV((dev_t)dev->cmajor, (dev_t)dev->idx), S_IFCHR|S_IRUSR|S_IWUSR, "c%s", dev->name);
+	if (ret) {
+		goto out;
+	}
+	class_device_create(ssd_class, NULL, MKDEV((dev_t)dev->cmajor, (dev_t)dev->idx), NULL, "c%s", dev->name);
+out:
+#elif (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,24))
+	class_device_create(ssd_class, NULL, MKDEV((dev_t)dev->cmajor, (dev_t)dev->idx), NULL, "c%s", dev->name);
+#elif (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,26))
+	device_create(ssd_class, NULL, MKDEV((dev_t)dev->cmajor, (dev_t)dev->idx), "c%s", dev->name);
+#elif (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,27))
+	device_create_drvdata(ssd_class, NULL, MKDEV((dev_t)dev->cmajor, (dev_t)dev->idx), NULL, "c%s", dev->name);
+#else
+	device_create(ssd_class, NULL, MKDEV((dev_t)dev->cmajor, (dev_t)dev->idx), NULL, "c%s", dev->name);
+#endif
+
+	return ret;
+}
+
+static int ssd_check_hw(struct ssd_device *dev)
+{
+	uint32_t test_data = 0x55AA5AA5;
+	uint32_t read_data;
+
+	ssd_reg32_write(dev->ctrlp + SSD_BRIDGE_TEST_REG, test_data);
+	read_data = ssd_reg32_read(dev->ctrlp + SSD_BRIDGE_TEST_REG);
+	if (read_data != ~(test_data)) {
+		//hio_warn("%s: check bridge error: %#x\n", dev->name, read_data);
+		return -1;
+	}
+
+	return 0;
+}
+
+static int ssd_check_fw(struct ssd_device *dev)
+{
+	uint32_t val = 0;
+	int i;
+
+	if (dev->protocol_info.ver < SSD_PROTOCOL_V3_1_3) {
+		return 0;
+	}
+
+	for (i=0; i<SSD_CONTROLLER_WAIT; i++) {
+		val = ssd_reg32_read(dev->ctrlp + SSD_HW_STATUS_REG);
+		if ((val & 0x1) && ((val >> 8) & 0x1)) {
+			break;
+		}
+
+		msleep(SSD_INIT_WAIT);
+	}
+
+	if (!(val & 0x1)) {
+		/* controller fw status */
+		hio_warn("%s: controller firmware load failed: %#x\n", dev->name, val);
+		return -1;
+	} else if (!((val >> 8) & 0x1)) {
+		/* controller state */
+		hio_warn("%s: controller state error: %#x\n", dev->name, val);
+		return -1;
+	}
+
+	val = ssd_reg32_read(dev->ctrlp + SSD_RELOAD_FW_REG);
+	if (val) {
+		dev->reload_fw = 1;
+	}
+
+	return 0;
+}
+
+static int ssd_init_fw_info(struct ssd_device *dev)
+{
+	uint32_t val;
+	int ret = 0;
+
+	val = ssd_reg32_read(dev->ctrlp + SSD_BRIDGE_VER_REG);
+	dev->hw_info.bridge_ver = val & 0xFFF;
+	if (dev->hw_info.bridge_ver < SSD_FW_MIN) {
+		hio_warn("%s: bridge firmware version %03X is not supported\n", dev->name, dev->hw_info.bridge_ver);
+		return -EINVAL;
+	}
+	hio_info("%s: bridge firmware version: %03X\n", dev->name, dev->hw_info.bridge_ver);
+
+	ret = ssd_check_fw(dev);
+	if (ret) {
+		goto out;
+	}
+
+out:
+	/* skip error if not in standard mode */
+	if (mode != SSD_DRV_MODE_STANDARD) {
+		ret = 0;
+	}
+	return ret;
+}
+
+static int ssd_check_clock(struct ssd_device *dev)
+{
+	uint32_t val;
+	int ret = 0;
+
+	if (dev->protocol_info.ver < SSD_PROTOCOL_V3_1_3) {
+		return 0;
+	}
+
+	val = ssd_reg32_read(dev->ctrlp + SSD_HW_STATUS_REG);
+
+	/* clock status */
+	if (!((val >> 4 ) & 0x1)) {
+		if (!test_and_set_bit(SSD_HWMON_CLOCK(SSD_CLOCK_166M_LOST), &dev->hwmon)) {
+			hio_warn("%s: 166MHz clock losed: %#x\n", dev->name, val);
+			ssd_gen_swlog(dev, SSD_LOG_CLK_FAULT, val);
+		}
+		ret = -1;
+	}
+
+	if (dev->protocol_info.ver >= SSD_PROTOCOL_V3_2) {
+		if (!((val >> 5 ) & 0x1)) {
+			if (!test_and_set_bit(SSD_HWMON_CLOCK(SSD_CLOCK_166M_SKEW), &dev->hwmon)) {
+				hio_warn("%s: 166MHz clock is skew: %#x\n", dev->name, val);
+				ssd_gen_swlog(dev, SSD_LOG_CLK_FAULT, val);
+			}
+			ret = -1;
+		}
+		if (!((val >> 6 ) & 0x1)) {
+			if (!test_and_set_bit(SSD_HWMON_CLOCK(SSD_CLOCK_156M_LOST), &dev->hwmon)) {
+				hio_warn("%s: 156.25MHz clock lost: %#x\n", dev->name, val);
+				ssd_gen_swlog(dev, SSD_LOG_CLK_FAULT, val);
+			}
+			ret = -1;
+		}
+		if (!((val >> 7 ) & 0x1)) {
+			if (!test_and_set_bit(SSD_HWMON_CLOCK(SSD_CLOCK_156M_SKEW), &dev->hwmon)) {
+				hio_warn("%s: 156.25MHz clock is skew: %#x\n", dev->name, val);
+				ssd_gen_swlog(dev, SSD_LOG_CLK_FAULT, val);
+			}
+			ret = -1;
+		}
+	}
+
+	return ret;
+}
+
+static int ssd_check_volt(struct ssd_device *dev)
+{
+	int i = 0;
+	uint64_t val;
+	uint32_t adc_val;
+	int ret =0;
+	
+	if (dev->protocol_info.ver < SSD_PROTOCOL_V3_2) {
+		return 0;
+	}
+
+	for (i=0; i<dev->hw_info.nr_ctrl; i++) {
+		/* 1.0v */
+		if (!test_bit(SSD_HWMON_FPGA(i, SSD_FPGA_1V0), &dev->hwmon)) {
+			val = ssd_reg_read(dev->ctrlp + SSD_FPGA_1V0_REG0 + i * SSD_CTRL_REG_ZONE_SZ);
+			adc_val = SSD_FPGA_VOLT_MAX(val);
+			if (adc_val < SSD_FPGA_1V0_ADC_MIN || adc_val > SSD_FPGA_1V0_ADC_MAX) {
+				(void)test_and_set_bit(SSD_HWMON_FPGA(i, SSD_FPGA_1V0), &dev->hwmon);
+				hio_warn("%s: controller %d 1.0V fault: %d mV.\n", dev->name, i, SSD_FPGA_VOLT(adc_val));
+				ssd_gen_swlog(dev, SSD_LOG_VOLT_FAULT, SSD_VOLT_LOG_DATA(SSD_FPGA_1V0, i, adc_val));
+				ret = -1;
+			}
+
+			adc_val = SSD_FPGA_VOLT_MIN(val);
+			if (adc_val < SSD_FPGA_1V0_ADC_MIN || adc_val > SSD_FPGA_1V0_ADC_MAX) {
+				(void)test_and_set_bit(SSD_HWMON_FPGA(i, SSD_FPGA_1V0), &dev->hwmon);
+				hio_warn("%s: controller %d 1.0V fault: %d mV.\n", dev->name, i, SSD_FPGA_VOLT(adc_val));
+				ssd_gen_swlog(dev, SSD_LOG_VOLT_FAULT, SSD_VOLT_LOG_DATA(SSD_FPGA_1V0, i, adc_val));
+				ret = -2;
+			}
+		}
+
+		/* 1.8v */
+		if (!test_bit(SSD_HWMON_FPGA(i, SSD_FPGA_1V8), &dev->hwmon)) {
+			val = ssd_reg_read(dev->ctrlp + SSD_FPGA_1V8_REG0 + i * SSD_CTRL_REG_ZONE_SZ);
+			adc_val = SSD_FPGA_VOLT_MAX(val);
+			if (adc_val < SSD_FPGA_1V8_ADC_MIN || adc_val > SSD_FPGA_1V8_ADC_MAX) {
+				(void)test_and_set_bit(SSD_HWMON_FPGA(i, SSD_FPGA_1V8), &dev->hwmon);
+				hio_warn("%s: controller %d 1.8V fault: %d mV.\n", dev->name, i, SSD_FPGA_VOLT(adc_val));
+				ssd_gen_swlog(dev, SSD_LOG_VOLT_FAULT, SSD_VOLT_LOG_DATA(SSD_FPGA_1V8, i, adc_val));
+				ret = -3;
+			}
+
+			adc_val = SSD_FPGA_VOLT_MIN(val);
+			if (adc_val < SSD_FPGA_1V8_ADC_MIN || adc_val > SSD_FPGA_1V8_ADC_MAX) {
+				(void)test_and_set_bit(SSD_HWMON_FPGA(i, SSD_FPGA_1V8), &dev->hwmon);
+				hio_warn("%s: controller %d 1.8V fault: %d mV.\n", dev->name, i, SSD_FPGA_VOLT(adc_val));
+				ssd_gen_swlog(dev, SSD_LOG_VOLT_FAULT, SSD_VOLT_LOG_DATA(SSD_FPGA_1V8, i, adc_val));
+				ret = -4;
+			}
+		}
+	}
+
+	return ret;
+}
+
+static int ssd_check_reset_sync(struct ssd_device *dev)
+{
+	uint32_t val;
+
+	if (dev->protocol_info.ver < SSD_PROTOCOL_V3_1_3) {
+		return 0;
+	}
+
+	val = ssd_reg32_read(dev->ctrlp + SSD_HW_STATUS_REG);
+	if (!((val >> 8) & 0x1)) {
+		/* controller state */
+		hio_warn("%s: controller state error: %#x\n", dev->name, val);
+		return -1;
+	}
+
+	if (dev->protocol_info.ver < SSD_PROTOCOL_V3_2) {
+		return 0;
+	}
+
+	if (((val >> 9 ) & 0x1)) {
+		hio_warn("%s: controller reset asynchronously: %#x\n", dev->name, val);
+		ssd_gen_swlog(dev, SSD_LOG_CTRL_RST_SYNC, val);
+		return -1;
+	}
+
+	return 0;
+}
+
+static int ssd_check_hw_bh(struct ssd_device *dev)
+{
+	int ret;
+
+	if (dev->protocol_info.ver < SSD_PROTOCOL_V3_1_3) {
+		return 0;
+	}
+
+	/* clock status */
+	ret = ssd_check_clock(dev);
+	if (ret) {
+		goto out;
+	}
+
+out:
+	/* skip error if not in standard mode */
+	if (mode != SSD_DRV_MODE_STANDARD) {
+		ret = 0;
+	}
+	return ret;
+}
+
+static int ssd_check_controller(struct ssd_device *dev)
+{
+	int ret;
+
+	if (dev->protocol_info.ver < SSD_PROTOCOL_V3_1_3) {
+		return 0;
+	}
+
+	/* sync reset */
+	ret = ssd_check_reset_sync(dev);
+	if (ret) {
+		goto out;
+	}
+
+out:
+	/* skip error if not in standard mode */
+	if (mode != SSD_DRV_MODE_STANDARD) {
+		ret = 0;
+	}
+	return ret;
+}
+
+static int ssd_check_controller_bh(struct ssd_device *dev)
+{
+	uint32_t test_data = 0x55AA5AA5;
+	uint32_t val;
+	int reg_base, reg_sz;
+	int init_wait = 0;
+	int i;
+	int ret = 0;
+
+	if (mode != SSD_DRV_MODE_STANDARD) {
+		return 0;
+	}
+
+	/* controller */
+	val = ssd_reg32_read(dev->ctrlp + SSD_READY_REG);
+	if (val & 0x1) {
+		hio_warn("%s: controller 0 not ready\n", dev->name);
+		return -1;
+	}
+
+	for (i=0; i<dev->hw_info.nr_ctrl; i++) {
+		reg_base = SSD_CTRL_TEST_REG0 + i * SSD_CTRL_TEST_REG_SZ;
+		ssd_reg32_write(dev->ctrlp + reg_base, test_data);
+		val = ssd_reg32_read(dev->ctrlp + reg_base);
+		if (val != ~(test_data)) {
+			hio_warn("%s: check controller %d error: %#x\n", dev->name, i, val);
+			return -1;
+		}
+	}
+
+	/* clock */
+	ret = ssd_check_volt(dev);
+	if (ret) {
+		return ret;
+	}
+
+	/* ddr */
+	if (dev->protocol_info.ver > SSD_PROTOCOL_V3) {
+		reg_base = SSD_PV3_RAM_STATUS_REG0;
+		reg_sz = SSD_PV3_RAM_STATUS_REG_SZ;
+
+		for (i=0; i<dev->hw_info.nr_ctrl; i++) {
+check_ram_status:
+			val = ssd_reg32_read(dev->ctrlp + reg_base);
+
+			if (!((val >> 1) & 0x1)) {
+				init_wait++;
+				if (init_wait <= SSD_RAM_INIT_MAX_WAIT) {
+					msleep(SSD_INIT_WAIT);
+					goto check_ram_status;
+				} else {
+					hio_warn("%s: controller %d ram init failed: %#x\n", dev->name, i, val);
+					ssd_gen_swlog(dev, SSD_LOG_DDR_INIT_ERR, i);
+					return -1;
+				}
+			}
+
+			reg_base += reg_sz;
+		}
+	}
+
+	/* ch info */
+	for (i=0; i<SSD_CH_INFO_MAX_WAIT; i++) {
+		val = ssd_reg32_read(dev->ctrlp + SSD_CH_INFO_REG);
+		if (!((val >> 31) & 0x1)) {
+			break;
+		}
+
+		msleep(SSD_INIT_WAIT);
+	}
+	if ((val >> 31) & 0x1) {
+		hio_warn("%s: channel info init failed: %#x\n", dev->name, val);
+		return -1;
+	}
+
+	return 0;
+}
+
+static int ssd_init_protocol_info(struct ssd_device *dev)
+{
+	uint32_t val;
+
+	val = ssd_reg32_read(dev->ctrlp + SSD_PROTOCOL_VER_REG);
+	if (val == (uint32_t)-1) {
+		hio_warn("%s: protocol version error: %#x\n", dev->name, val);
+		return -EINVAL;
+	}
+	dev->protocol_info.ver = val;
+
+	if (dev->protocol_info.ver < SSD_PROTOCOL_V3) {
+		dev->protocol_info.init_state_reg = SSD_INIT_STATE_REG0;
+		dev->protocol_info.init_state_reg_sz = SSD_INIT_STATE_REG_SZ;
+
+		dev->protocol_info.chip_info_reg = SSD_CHIP_INFO_REG0;
+		dev->protocol_info.chip_info_reg_sz = SSD_CHIP_INFO_REG_SZ;
+	} else {
+		dev->protocol_info.init_state_reg = SSD_PV3_INIT_STATE_REG0;
+		dev->protocol_info.init_state_reg_sz = SSD_PV3_INIT_STATE_REG_SZ;
+
+		dev->protocol_info.chip_info_reg = SSD_PV3_CHIP_INFO_REG0;
+		dev->protocol_info.chip_info_reg_sz = SSD_PV3_CHIP_INFO_REG_SZ;
+	}
+
+	return 0;
+}
+
+static int ssd_init_hw_info(struct ssd_device *dev)
+{
+	uint64_t val64;
+	uint32_t val;
+	uint32_t nr_ctrl;
+	int ret = 0;
+
+	/* base info */
+	val = ssd_reg32_read(dev->ctrlp + SSD_RESP_INFO_REG);
+	dev->hw_info.resp_ptr_sz = 16 * (1U << (val & 0xFF));
+	dev->hw_info.resp_msg_sz = 16 * (1U << ((val >> 8) & 0xFF));
+
+	if (0 == dev->hw_info.resp_ptr_sz || 0 == dev->hw_info.resp_msg_sz) {
+		hio_warn("%s: response info error\n", dev->name);
+		ret = -EINVAL;
+		goto out;
+	}
+
+	val = ssd_reg32_read(dev->ctrlp + SSD_BRIDGE_INFO_REG);
+	dev->hw_info.cmd_fifo_sz = 1U << ((val >> 4) & 0xF);
+	dev->hw_info.cmd_max_sg = 1U << ((val >> 8) & 0xF);
+	dev->hw_info.sg_max_sec = 1U << ((val >> 12) & 0xF);
+	dev->hw_info.cmd_fifo_sz_mask = dev->hw_info.cmd_fifo_sz - 1;
+
+	if (0 == dev->hw_info.cmd_fifo_sz || 0 == dev->hw_info.cmd_max_sg || 0 == dev->hw_info.sg_max_sec) {
+		hio_warn("%s: cmd info error\n", dev->name);
+		ret = -EINVAL;
+		goto out;
+	}
+
+	/* check hw */
+	if (ssd_check_hw_bh(dev)) {
+		hio_warn("%s: check hardware status failed\n", dev->name);
+		ret = -EINVAL;
+		goto out;
+	}
+
+	if (ssd_check_controller(dev)) {
+		hio_warn("%s: check controller state failed\n", dev->name);
+		ret = -EINVAL;
+		goto out;
+	}
+
+	/* nr controller : read again*/
+	val = ssd_reg32_read(dev->ctrlp + SSD_BRIDGE_INFO_REG);
+	dev->hw_info.nr_ctrl = (val >> 16) & 0xF;
+
+	/* nr ctrl configured */
+	nr_ctrl = (val >> 20) & 0xF;
+	if (0 == dev->hw_info.nr_ctrl) {
+		hio_warn("%s: nr controller error: %u\n", dev->name, dev->hw_info.nr_ctrl);
+		ret = -EINVAL;
+		goto out;
+	} else if (0 != nr_ctrl && nr_ctrl != dev->hw_info.nr_ctrl) {
+		hio_warn("%s: nr controller error: configured %u but found %u\n", dev->name, nr_ctrl, dev->hw_info.nr_ctrl);
+		if (mode <= SSD_DRV_MODE_STANDARD) {
+			ret = -EINVAL;
+			goto out;
+		}
+	}
+
+	if (ssd_check_controller_bh(dev)) {
+		hio_warn("%s: check controller failed\n", dev->name);
+		ret = -EINVAL;
+		goto out;
+	}
+
+	val = ssd_reg32_read(dev->ctrlp + SSD_PCB_VER_REG);
+	dev->hw_info.pcb_ver = (uint8_t) ((val >> 4) & 0xF) + 'A' -1;
+	if ((val & 0xF) != 0xF) {
+		dev->hw_info.upper_pcb_ver = (uint8_t) (val & 0xF) + 'A' -1;
+	}
+
+	if (dev->hw_info.pcb_ver < 'A' || (0 != dev->hw_info.upper_pcb_ver && dev->hw_info.upper_pcb_ver < 'A')) {
+		hio_warn("%s: PCB version error: %#x %#x\n", dev->name, dev->hw_info.pcb_ver, dev->hw_info.upper_pcb_ver);
+		ret = -EINVAL;
+		goto out;
+	}
+
+	/* channel info */
+	if (mode <= SSD_DRV_MODE_DEBUG) {
+		val = ssd_reg32_read(dev->ctrlp + SSD_CH_INFO_REG);
+		dev->hw_info.nr_data_ch = val & 0xFF;
+		dev->hw_info.nr_ch = dev->hw_info.nr_data_ch + ((val >> 8) & 0xFF);
+		dev->hw_info.nr_chip = (val >> 16) & 0xFF;
+
+		if (dev->protocol_info.ver < SSD_PROTOCOL_V3_2) {
+			dev->hw_info.max_ch = 1;
+			while (dev->hw_info.max_ch < dev->hw_info.nr_ch) dev->hw_info.max_ch <<= 1;
+		} else {
+			/* set max channel 32  */
+			dev->hw_info.max_ch = 32;
+		}
+
+		if (0 == dev->hw_info.nr_chip) {
+			//for debug mode
+			dev->hw_info.nr_chip = 1;
+		}
+
+		//xx
+		dev->hw_info.id_size = SSD_NAND_ID_SZ;
+		dev->hw_info.max_ce = SSD_NAND_MAX_CE;
+
+		if (0 == dev->hw_info.nr_data_ch || 0 == dev->hw_info.nr_ch || 0 == dev->hw_info.nr_chip) {
+			hio_warn("%s: channel info error: data_ch %u ch %u chip %u\n", dev->name, dev->hw_info.nr_data_ch, dev->hw_info.nr_ch, dev->hw_info.nr_chip);
+			ret = -EINVAL;
+			goto out;
+		}
+	}
+
+	/* ram info */
+	if (mode <= SSD_DRV_MODE_DEBUG) {
+		val = ssd_reg32_read(dev->ctrlp + SSD_RAM_INFO_REG);
+		dev->hw_info.ram_size = 0x4000000ull * (1ULL << (val & 0xF));
+		dev->hw_info.ram_align = 1U << ((val >> 12) & 0xF);
+		if (dev->hw_info.ram_align < SSD_RAM_ALIGN) {
+			if (dev->protocol_info.ver < SSD_PROTOCOL_V3) {
+				dev->hw_info.ram_align = SSD_RAM_ALIGN;
+			} else {
+				hio_warn("%s: ram align error: %u\n", dev->name, dev->hw_info.ram_align);
+				ret = -EINVAL;
+				goto out;
+			}
+		}
+		dev->hw_info.ram_max_len = 0x1000 * (1U << ((val >> 16) & 0xF));
+
+		if (0 == dev->hw_info.ram_size || 0 == dev->hw_info.ram_align || 0 == dev->hw_info.ram_max_len || dev->hw_info.ram_align > dev->hw_info.ram_max_len) {
+			hio_warn("%s: ram info error\n", dev->name);
+			ret = -EINVAL;
+			goto out;
+		}
+
+		if (dev->protocol_info.ver < SSD_PROTOCOL_V3) {
+			dev->hw_info.log_sz = SSD_LOG_MAX_SZ;
+		} else {
+			val = ssd_reg32_read(dev->ctrlp + SSD_LOG_INFO_REG);
+			dev->hw_info.log_sz = 0x1000 * (1U << (val & 0xFF));
+		}
+		if (0 == dev->hw_info.log_sz) {
+			hio_warn("%s: log size error\n", dev->name);
+			ret = -EINVAL;
+			goto out;
+		}
+
+		val = ssd_reg32_read(dev->ctrlp + SSD_BBT_BASE_REG);
+		dev->hw_info.bbt_base = 0x40000ull * (val & 0xFFFF);
+		dev->hw_info.bbt_size = 0x40000 * (((val >> 16) & 0xFFFF) + 1) / (dev->hw_info.max_ch * dev->hw_info.nr_chip);
+		if (dev->protocol_info.ver < SSD_PROTOCOL_V3) {
+			if (dev->hw_info.bbt_base > dev->hw_info.ram_size || 0 == dev->hw_info.bbt_size) {
+				hio_warn("%s: bbt info error\n", dev->name);
+				ret = -EINVAL;
+				goto out;
+			}
+		}
+
+		val = ssd_reg32_read(dev->ctrlp + SSD_ECT_BASE_REG);
+		dev->hw_info.md_base = 0x40000ull * (val & 0xFFFF);
+		if (dev->protocol_info.ver <= SSD_PROTOCOL_V3) {
+			dev->hw_info.md_size = 0x40000 * (((val >> 16) & 0xFFF) + 1) / (dev->hw_info.max_ch * dev->hw_info.nr_chip);
+		} else {
+			dev->hw_info.md_size = 0x40000 * (((val >> 16) & 0xFFF) + 1) / (dev->hw_info.nr_chip);
+		}
+		dev->hw_info.md_entry_sz = 8 * (1U << ((val >> 28) & 0xF));
+		if (dev->protocol_info.ver >= SSD_PROTOCOL_V3) {
+			if (dev->hw_info.md_base > dev->hw_info.ram_size || 0 == dev->hw_info.md_size || 
+				0 == dev->hw_info.md_entry_sz || dev->hw_info.md_entry_sz > dev->hw_info.md_size) {
+				hio_warn("%s: md info error\n", dev->name);
+				ret = -EINVAL;
+				goto out;
+			}
+		}
+
+		if (dev->protocol_info.ver < SSD_PROTOCOL_V3) {
+			dev->hw_info.nand_wbuff_base = dev->hw_info.ram_size + 1;
+		} else {
+			val = ssd_reg32_read(dev->ctrlp + SSD_NAND_BUFF_BASE);
+			dev->hw_info.nand_wbuff_base = 0x8000ull * val;
+		}
+	}
+
+	/* flash info */
+	if (mode <= SSD_DRV_MODE_DEBUG) {
+		if (dev->hw_info.nr_ctrl > 1) {
+			val = ssd_reg32_read(dev->ctrlp + SSD_CTRL_VER_REG);
+			dev->hw_info.ctrl_ver = val & 0xFFF;
+			hio_info("%s: controller firmware version: %03X\n", dev->name, dev->hw_info.ctrl_ver);
+		}
+
+		val64 = ssd_reg_read(dev->ctrlp + SSD_FLASH_INFO_REG0);
+		dev->hw_info.nand_vendor_id = ((val64 >> 56) & 0xFF);
+		dev->hw_info.nand_dev_id = ((val64 >> 48) & 0xFF);
+
+		dev->hw_info.block_count = (((val64 >> 32) & 0xFFFF) + 1);
+		dev->hw_info.page_count = ((val64>>16) & 0xFFFF);
+		dev->hw_info.page_size = (val64 & 0xFFFF);
+
+		val = ssd_reg32_read(dev->ctrlp + SSD_BB_INFO_REG);
+		dev->hw_info.bbf_pages = val & 0xFF;
+		dev->hw_info.bbf_seek = (val >> 8) & 0x1;
+
+		if (0 == dev->hw_info.block_count || 0 == dev->hw_info.page_count || 0 == dev->hw_info.page_size || dev->hw_info.block_count > INT_MAX) {
+			hio_warn("%s: flash info error\n", dev->name);
+			ret = -EINVAL;
+			goto out;
+		}
+
+		//xx
+		dev->hw_info.oob_size = SSD_NAND_OOB_SZ;	//(dev->hw_info.page_size) >> 5;
+
+		val = ssd_reg32_read(dev->ctrlp + SSD_VALID_PAGES_REG);
+		if (dev->protocol_info.ver < SSD_PROTOCOL_V3_2) {
+			dev->hw_info.valid_pages = val & 0x3FF;
+			dev->hw_info.max_valid_pages = (val>>20) & 0x3FF;
+		} else {
+			dev->hw_info.valid_pages = val & 0x7FFF;
+			dev->hw_info.max_valid_pages = (val>>15) & 0x7FFF;
+		}
+		if (0 == dev->hw_info.valid_pages || 0 == dev->hw_info.max_valid_pages || 
+			dev->hw_info.valid_pages > dev->hw_info.max_valid_pages || dev->hw_info.max_valid_pages > dev->hw_info.page_count) {
+			hio_warn("%s: valid page info error: valid_pages %d, max_valid_pages %d\n", dev->name, dev->hw_info.valid_pages, dev->hw_info.max_valid_pages);
+			ret = -EINVAL;
+			goto out;
+		}
+
+		val = ssd_reg32_read(dev->ctrlp + SSD_RESERVED_BLKS_REG);
+		dev->hw_info.reserved_blks = val & 0xFFFF;
+		dev->hw_info.md_reserved_blks = (val >> 16) & 0xFF;
+		if (dev->protocol_info.ver <= SSD_PROTOCOL_V3) {
+			dev->hw_info.md_reserved_blks = SSD_BBT_RESERVED;
+		}
+		if (dev->hw_info.reserved_blks > dev->hw_info.block_count || dev->hw_info.md_reserved_blks > dev->hw_info.block_count) {
+			hio_warn("%s: reserved blocks info error: reserved_blks %d, md_reserved_blks %d\n", dev->name, dev->hw_info.reserved_blks, dev->hw_info.md_reserved_blks);
+			ret = -EINVAL;
+			goto out;
+		}
+	}
+
+	/* size */
+	if (mode < SSD_DRV_MODE_DEBUG) {
+		dev->hw_info.size = (uint64_t)dev->hw_info.valid_pages * dev->hw_info.page_size;
+		dev->hw_info.size *= (dev->hw_info.block_count - dev->hw_info.reserved_blks);
+		dev->hw_info.size *= ((uint64_t)dev->hw_info.nr_data_ch * (uint64_t)dev->hw_info.nr_chip * (uint64_t)dev->hw_info.nr_ctrl);
+	}
+
+	/* extend hardware info */
+	val = ssd_reg32_read(dev->ctrlp + SSD_PCB_VER_REG);
+	dev->hw_info_ext.board_type = (val >> 24) & 0xF;
+
+	dev->hw_info_ext.form_factor = SSD_FORM_FACTOR_FHHL;
+	if (dev->protocol_info.ver >= SSD_PROTOCOL_V3_2_1) {
+		dev->hw_info_ext.form_factor = (val >> 31) & 0x1;
+	}
+	/*
+	dev->hw_info_ext.cap_type = (val >> 28) & 0x3;
+	if (SSD_BM_CAP_VINA != dev->hw_info_ext.cap_type && SSD_BM_CAP_JH != dev->hw_info_ext.cap_type) {
+		dev->hw_info_ext.cap_type = SSD_BM_CAP_VINA;
+	}*/
+
+	/* power loss protect */
+	val = ssd_reg32_read(dev->ctrlp + SSD_PLP_INFO_REG);
+	dev->hw_info_ext.plp_type = (val & 0x3);
+	if (dev->protocol_info.ver >= SSD_PROTOCOL_V3_2) {
+		/* 3 or 4 cap */
+		dev->hw_info_ext.cap_type = ((val >> 2)& 0x1);
+	}
+
+	/* work mode */
+	val = ssd_reg32_read(dev->ctrlp + SSD_CH_INFO_REG);
+	dev->hw_info_ext.work_mode = (val >> 25) & 0x1;
+
+out:
+	/* skip error if not in standard mode */
+	if (mode != SSD_DRV_MODE_STANDARD) {
+		ret = 0;
+	}
+	return ret;
+}
+
+static void ssd_cleanup_response(struct ssd_device *dev)
+{
+	int resp_msg_sz = dev->hw_info.resp_msg_sz * dev->hw_info.cmd_fifo_sz * SSD_MSIX_VEC;
+	int resp_ptr_sz = dev->hw_info.resp_ptr_sz * SSD_MSIX_VEC;
+
+	pci_free_consistent(dev->pdev, resp_ptr_sz, dev->resp_ptr_base, dev->resp_ptr_base_dma);
+	pci_free_consistent(dev->pdev, resp_msg_sz, dev->resp_msg_base, dev->resp_msg_base_dma);
+}
+
+static int ssd_init_response(struct ssd_device *dev)
+{
+	int resp_msg_sz = dev->hw_info.resp_msg_sz * dev->hw_info.cmd_fifo_sz * SSD_MSIX_VEC;
+	int resp_ptr_sz = dev->hw_info.resp_ptr_sz * SSD_MSIX_VEC;
+
+	dev->resp_msg_base = pci_alloc_consistent(dev->pdev, resp_msg_sz, &(dev->resp_msg_base_dma));
+	if (!dev->resp_msg_base) {
+		hio_warn("%s: unable to allocate resp msg DMA buffer\n", dev->name);
+		goto out_alloc_resp_msg;
+	}
+	memset(dev->resp_msg_base, 0xFF, resp_msg_sz);
+
+	dev->resp_ptr_base = pci_alloc_consistent(dev->pdev, resp_ptr_sz, &(dev->resp_ptr_base_dma));
+	if (!dev->resp_ptr_base){
+		hio_warn("%s: unable to allocate resp ptr DMA buffer\n", dev->name);
+		goto out_alloc_resp_ptr;
+	}
+	memset(dev->resp_ptr_base, 0, resp_ptr_sz);
+	dev->resp_idx = *(uint32_t *)(dev->resp_ptr_base) = dev->hw_info.cmd_fifo_sz * 2 - 1;
+
+	ssd_reg_write(dev->ctrlp + SSD_RESP_FIFO_REG, dev->resp_msg_base_dma);
+	ssd_reg_write(dev->ctrlp + SSD_RESP_PTR_REG, dev->resp_ptr_base_dma);
+
+	return 0;
+
+out_alloc_resp_ptr:
+	pci_free_consistent(dev->pdev, resp_msg_sz, dev->resp_msg_base, dev->resp_msg_base_dma);
+out_alloc_resp_msg:
+	return -ENOMEM;
+}
+
+static int ssd_cleanup_cmd(struct ssd_device *dev)
+{
+	int msg_sz = ALIGN(sizeof(struct ssd_rw_msg) + (dev->hw_info.cmd_max_sg - 1) * sizeof(struct ssd_sg_entry), SSD_DMA_ALIGN);
+	int i;
+
+	for (i=0; i<(int)dev->hw_info.cmd_fifo_sz; i++) {
+		kfree(dev->cmd[i].sgl);
+	}
+	kfree(dev->cmd);
+	pci_free_consistent(dev->pdev, (msg_sz * dev->hw_info.cmd_fifo_sz), dev->msg_base, dev->msg_base_dma);
+	return 0;
+}
+
+static int ssd_init_cmd(struct ssd_device *dev)
+{
+	int sgl_sz = sizeof(struct scatterlist) * dev->hw_info.cmd_max_sg;
+	int cmd_sz = sizeof(struct ssd_cmd) * dev->hw_info.cmd_fifo_sz;
+	int msg_sz = ALIGN(sizeof(struct ssd_rw_msg) + (dev->hw_info.cmd_max_sg - 1) * sizeof(struct ssd_sg_entry), SSD_DMA_ALIGN);
+	int i;
+
+	spin_lock_init(&dev->cmd_lock);
+
+	dev->msg_base = pci_alloc_consistent(dev->pdev, (msg_sz * dev->hw_info.cmd_fifo_sz), &dev->msg_base_dma);
+	if (!dev->msg_base) {
+		hio_warn("%s: can not alloc cmd msg\n", dev->name);
+		goto out_alloc_msg;
+	}
+
+	dev->cmd = kmalloc(cmd_sz, GFP_KERNEL);
+	if (!dev->cmd) {
+		hio_warn("%s: can not alloc cmd\n", dev->name);
+		goto out_alloc_cmd;
+	}
+	memset(dev->cmd, 0, cmd_sz);
+
+	for (i=0; i<(int)dev->hw_info.cmd_fifo_sz; i++) {
+		dev->cmd[i].sgl = kmalloc(sgl_sz, GFP_KERNEL);
+		if (!dev->cmd[i].sgl) {
+			hio_warn("%s: can not alloc cmd sgl %d\n", dev->name, i);
+			goto out_alloc_sgl;
+		}
+
+		dev->cmd[i].msg = dev->msg_base + (msg_sz * i);
+		dev->cmd[i].msg_dma = dev->msg_base_dma + ((dma_addr_t)msg_sz * i);
+
+		dev->cmd[i].dev = dev;
+		dev->cmd[i].tag = i;
+		dev->cmd[i].flag = 0;
+
+		INIT_LIST_HEAD(&dev->cmd[i].list);
+	}
+
+	if (dev->protocol_info.ver < SSD_PROTOCOL_V3) {
+		dev->scmd = ssd_dispatch_cmd;
+	} else {
+		ssd_reg_write(dev->ctrlp + SSD_MSG_BASE_REG, dev->msg_base_dma);
+		if (finject) {
+			dev->scmd = ssd_send_cmd_db;
+		} else {
+			dev->scmd = ssd_send_cmd;
+		}
+	}
+
+	return 0;
+
+out_alloc_sgl:
+	for (i--; i>=0; i--) {
+		kfree(dev->cmd[i].sgl);
+	}
+	kfree(dev->cmd);
+out_alloc_cmd:
+	pci_free_consistent(dev->pdev, (msg_sz * dev->hw_info.cmd_fifo_sz), dev->msg_base, dev->msg_base_dma);
+out_alloc_msg:
+	return -ENOMEM;
+}
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,30))
+static irqreturn_t ssd_interrupt_check(int irq, void *dev_id)
+{
+	struct ssd_queue *queue = (struct ssd_queue *)dev_id;
+
+	if (*(uint32_t *)queue->resp_ptr == queue->resp_idx) {
+		return IRQ_NONE;
+	}
+
+	return IRQ_WAKE_THREAD;
+}
+
+static irqreturn_t ssd_interrupt_threaded(int irq, void *dev_id)
+{
+	struct ssd_queue *queue = (struct ssd_queue *)dev_id;
+	struct ssd_device *dev = (struct ssd_device *)queue->dev;
+	struct ssd_cmd *cmd;
+	union ssd_response_msq __msg;
+	union ssd_response_msq *msg = &__msg;
+	uint64_t *u64_msg;
+	uint32_t resp_idx = queue->resp_idx;
+	uint32_t new_resp_idx = *(uint32_t *)queue->resp_ptr;
+	uint32_t end_resp_idx;
+
+	if (unlikely(resp_idx == new_resp_idx)) {
+		return IRQ_NONE;
+	}
+
+	end_resp_idx = new_resp_idx & queue->resp_idx_mask;
+
+	do {
+		resp_idx = (resp_idx + 1) & queue->resp_idx_mask;
+
+		/* the resp msg */
+		u64_msg = (uint64_t *)(queue->resp_msg + queue->resp_msg_sz * resp_idx);
+		msg->u64_msg = *u64_msg;
+
+		if (unlikely(msg->u64_msg == (uint64_t)(-1))) {
+			hio_err("%s: empty resp msg: queue %d idx %u\n", dev->name, queue->idx, resp_idx);
+			continue;
+		}
+		/* clear the resp msg */
+		*u64_msg = (uint64_t)(-1);
+
+		cmd = &queue->cmd[msg->resp_msg.tag];
+		/*if (unlikely(!cmd->bio)) {
+			printk(KERN_WARNING "%s: unknown tag %d fun %#x\n", 
+				dev->name, msg->resp_msg.tag, msg->resp_msg.fun);
+			continue;
+		}*/
+
+		if(unlikely(msg->resp_msg.status & (uint32_t)status_mask)) {
+			cmd->errors = -EIO;
+		} else {
+			cmd->errors = 0;
+		}
+		cmd->nr_log = msg->log_resp_msg.nr_log;
+
+		ssd_done(cmd);
+
+		if (unlikely(msg->resp_msg.fun != SSD_FUNC_READ_LOG && msg->resp_msg.log > 0)) {
+			(void)test_and_set_bit(SSD_LOG_HW, &dev->state);
+			if (test_bit(SSD_INIT_WORKQ, &dev->state)) {
+				queue_work(dev->workq, &dev->log_work);
+			}
+		}
+
+		if (unlikely(msg->resp_msg.status)) {
+			if (msg->resp_msg.fun == SSD_FUNC_READ || msg->resp_msg.fun == SSD_FUNC_WRITE) {
+				hio_err("%s: I/O error %d: tag %d fun %#x\n", 
+					dev->name, msg->resp_msg.status, msg->resp_msg.tag, msg->resp_msg.fun);
+
+				/* alarm led */
+				ssd_set_alarm(dev);
+				queue->io_stat.nr_rwerr++;
+				ssd_gen_swlog(dev, SSD_LOG_EIO, msg->u32_msg[0]);
+			} else {
+				hio_info("%s: CMD error %d: tag %d fun %#x\n", 
+					dev->name, msg->resp_msg.status, msg->resp_msg.tag, msg->resp_msg.fun);
+
+				ssd_gen_swlog(dev, SSD_LOG_ECMD, msg->u32_msg[0]);
+			}
+			queue->io_stat.nr_ioerr++;
+		}
+
+		if (msg->resp_msg.fun == SSD_FUNC_READ || 
+			msg->resp_msg.fun == SSD_FUNC_NAND_READ_WOOB ||
+			msg->resp_msg.fun == SSD_FUNC_NAND_READ) {
+
+			queue->ecc_info.bitflip[msg->resp_msg.bitflip]++;
+		}
+	}while (resp_idx != end_resp_idx);
+
+	queue->resp_idx = new_resp_idx;
+
+	return IRQ_HANDLED;
+}
+#endif
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19))
+static irqreturn_t ssd_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+#else
+static irqreturn_t ssd_interrupt(int irq, void *dev_id)
+#endif
+{
+	struct ssd_queue *queue = (struct ssd_queue *)dev_id;
+	struct ssd_device *dev = (struct ssd_device *)queue->dev;
+	struct ssd_cmd *cmd;
+	union ssd_response_msq __msg;
+	union ssd_response_msq *msg = &__msg;
+	uint64_t *u64_msg;
+	uint32_t resp_idx = queue->resp_idx;
+	uint32_t new_resp_idx = *(uint32_t *)queue->resp_ptr;
+	uint32_t end_resp_idx;
+
+	if (unlikely(resp_idx == new_resp_idx)) {
+		return IRQ_NONE;
+	}
+
+#if (defined SSD_ESCAPE_IRQ)
+	if (SSD_INT_MSIX != dev->int_mode) {
+		dev->irq_cpu = smp_processor_id();
+	}
+#endif
+
+	end_resp_idx = new_resp_idx & queue->resp_idx_mask;
+
+	do {
+		resp_idx = (resp_idx + 1) & queue->resp_idx_mask;
+
+		/* the resp msg */
+		u64_msg = (uint64_t *)(queue->resp_msg + queue->resp_msg_sz * resp_idx);
+		msg->u64_msg = *u64_msg;
+
+		if (unlikely(msg->u64_msg == (uint64_t)(-1))) {
+			hio_err("%s: empty resp msg: queue %d idx %u\n", dev->name, queue->idx, resp_idx);
+			continue;
+		}
+		/* clear the resp msg */
+		*u64_msg = (uint64_t)(-1);
+
+		cmd = &queue->cmd[msg->resp_msg.tag];
+		/*if (unlikely(!cmd->bio)) {
+			printk(KERN_WARNING "%s: unknown tag %d fun %#x\n", 
+				dev->name, msg->resp_msg.tag, msg->resp_msg.fun);
+			continue;
+		}*/
+
+		if(unlikely(msg->resp_msg.status & (uint32_t)status_mask)) {
+			cmd->errors = -EIO;
+		} else {
+			cmd->errors = 0;
+		}
+		cmd->nr_log = msg->log_resp_msg.nr_log;
+
+		ssd_done_bh(cmd);
+
+		if (unlikely(msg->resp_msg.fun != SSD_FUNC_READ_LOG && msg->resp_msg.log > 0)) {
+			(void)test_and_set_bit(SSD_LOG_HW, &dev->state);
+			if (test_bit(SSD_INIT_WORKQ, &dev->state)) {
+				queue_work(dev->workq, &dev->log_work);
+			}
+		}
+
+		if (unlikely(msg->resp_msg.status)) {
+			if (msg->resp_msg.fun == SSD_FUNC_READ || msg->resp_msg.fun == SSD_FUNC_WRITE) {				
+				hio_err("%s: I/O error %d: tag %d fun %#x\n", 
+					dev->name, msg->resp_msg.status, msg->resp_msg.tag, msg->resp_msg.fun);
+
+				/* alarm led */
+				ssd_set_alarm(dev);
+				queue->io_stat.nr_rwerr++;
+				ssd_gen_swlog(dev, SSD_LOG_EIO, msg->u32_msg[0]);
+			} else {
+				hio_info("%s: CMD error %d: tag %d fun %#x\n", 
+					dev->name, msg->resp_msg.status, msg->resp_msg.tag, msg->resp_msg.fun);
+
+				ssd_gen_swlog(dev, SSD_LOG_ECMD, msg->u32_msg[0]);
+			}
+			queue->io_stat.nr_ioerr++;
+		}
+
+		if (msg->resp_msg.fun == SSD_FUNC_READ || 
+			msg->resp_msg.fun == SSD_FUNC_NAND_READ_WOOB ||
+			msg->resp_msg.fun == SSD_FUNC_NAND_READ) {
+
+			queue->ecc_info.bitflip[msg->resp_msg.bitflip]++;
+		}
+	}while (resp_idx != end_resp_idx);
+
+	queue->resp_idx = new_resp_idx;
+
+	return IRQ_HANDLED;
+}
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19))
+static irqreturn_t ssd_interrupt_legacy(int irq, void *dev_id, struct pt_regs *regs)
+#else
+static irqreturn_t ssd_interrupt_legacy(int irq, void *dev_id)
+#endif
+{
+	irqreturn_t ret;
+	struct ssd_queue *queue = (struct ssd_queue *)dev_id;
+	struct ssd_device *dev = (struct ssd_device *)queue->dev;
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19))
+	ret = ssd_interrupt(irq, dev_id, regs);
+#else
+	ret = ssd_interrupt(irq, dev_id);
+#endif
+
+	/* clear intr */ 
+	if (IRQ_HANDLED == ret) {
+		ssd_reg32_write(dev->ctrlp + SSD_CLEAR_INTR_REG, 1);
+	}
+
+	return ret;
+}
+
+static void ssd_reset_resp_ptr(struct ssd_device *dev)
+{
+	int i;
+
+	for (i=0; i<dev->nr_queue; i++) {
+		*(uint32_t *)dev->queue[i].resp_ptr = dev->queue[i].resp_idx = (dev->hw_info.cmd_fifo_sz * 2) - 1;
+	}
+}
+
+static void ssd_free_irq(struct ssd_device *dev)
+{
+	int i;
+
+#if ((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35)) || (defined RHEL_MAJOR && RHEL_MAJOR == 6))
+	if (SSD_INT_MSIX == dev->int_mode) {
+		for (i=0; i<dev->nr_queue; i++) {
+			irq_set_affinity_hint(dev->entry[i].vector, NULL);
+		}
+	}
+#endif
+
+	for (i=0; i<dev->nr_queue; i++) {
+		free_irq(dev->entry[i].vector, &dev->queue[i]);
+	}
+
+	if (SSD_INT_MSIX == dev->int_mode) {
+		pci_disable_msix(dev->pdev);
+	} else if (SSD_INT_MSI == dev->int_mode) {
+		pci_disable_msi(dev->pdev);
+	}
+
+}
+
+static int ssd_init_irq(struct ssd_device *dev)
+{
+#if (!defined MODULE) && (defined SSD_MSIX_AFFINITY_FORCE)
+	const struct cpumask *cpu_mask;
+	static int cpu_affinity = 0;
+#endif
+#if ((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35)) || (defined RHEL_MAJOR && RHEL_MAJOR == 6))
+	const struct cpumask *mask = NULL;
+	static int cpu = 0;
+	int j;
+#endif
+	int i;
+	unsigned long flags = 0;
+	int ret = 0;
+
+	ssd_reg32_write(dev->ctrlp + SSD_INTR_INTERVAL_REG, 0x800);
+
+#ifdef SSD_ESCAPE_IRQ
+	dev->irq_cpu = -1;
+#endif
+
+	if (int_mode >= SSD_INT_MSIX && pci_find_capability(dev->pdev, PCI_CAP_ID_MSIX)) {
+		dev->nr_queue = SSD_MSIX_VEC;
+		for (i=0; i<dev->nr_queue; i++) {
+			dev->entry[i].entry = i;
+		}
+		for (;;) {
+			ret = pci_enable_msix(dev->pdev, dev->entry, dev->nr_queue);
+			if (ret == 0) {
+				break;
+			} else if (ret > 0) {
+				dev->nr_queue = ret;
+			} else {
+				hio_warn("%s: can not enable msix\n", dev->name);
+				/* alarm led */
+				ssd_set_alarm(dev);
+				goto out;
+			}
+		}
+
+#if ((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35)) || (defined RHEL_MAJOR && RHEL_MAJOR == 6))
+		mask = (dev_to_node(&dev->pdev->dev) == -1) ? cpu_online_mask : cpumask_of_node(dev_to_node(&dev->pdev->dev));
+		if ((0 == cpu) || (!cpumask_intersects(mask, cpumask_of(cpu)))) {
+			cpu = cpumask_first(mask);
+		}
+		for (i=0; i<dev->nr_queue; i++) {
+			irq_set_affinity_hint(dev->entry[i].vector, cpumask_of(cpu));
+			cpu = cpumask_next(cpu, mask);
+			if (cpu >= nr_cpu_ids) {
+				cpu = cpumask_first(mask);
+			}
+		}
+#endif
+
+		dev->int_mode = SSD_INT_MSIX;
+	} else if (int_mode >= SSD_INT_MSI && pci_find_capability(dev->pdev, PCI_CAP_ID_MSI)) {
+		ret = pci_enable_msi(dev->pdev);
+		if (ret) {
+			hio_warn("%s: can not enable msi\n", dev->name);
+			/* alarm led */
+			ssd_set_alarm(dev);
+			goto out;
+		}
+
+		dev->nr_queue = 1;
+		dev->entry[0].vector = dev->pdev->irq;
+
+		dev->int_mode = SSD_INT_MSI;
+	} else {
+		dev->nr_queue = 1;
+		dev->entry[0].vector = dev->pdev->irq;
+
+		dev->int_mode = SSD_INT_LEGACY;
+	}
+
+	for (i=0; i<dev->nr_queue; i++) {
+		if (dev->nr_queue > 1) {
+			snprintf(dev->queue[i].name, SSD_QUEUE_NAME_LEN, "%s_e100-%d", dev->name, i);
+		} else {
+			snprintf(dev->queue[i].name, SSD_QUEUE_NAME_LEN, "%s_e100", dev->name);
+		}
+
+		dev->queue[i].dev = dev;
+		dev->queue[i].idx = i;
+
+		dev->queue[i].resp_idx = (dev->hw_info.cmd_fifo_sz * 2) - 1;
+		dev->queue[i].resp_idx_mask = dev->hw_info.cmd_fifo_sz - 1;
+
+		dev->queue[i].resp_msg_sz = dev->hw_info.resp_msg_sz;
+		dev->queue[i].resp_msg = dev->resp_msg_base + dev->hw_info.resp_msg_sz * dev->hw_info.cmd_fifo_sz * i;
+		dev->queue[i].resp_ptr = dev->resp_ptr_base + dev->hw_info.resp_ptr_sz * i;
+		*(uint32_t *)dev->queue[i].resp_ptr = dev->queue[i].resp_idx;
+
+		dev->queue[i].cmd = dev->cmd;
+	}
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
+	flags = IRQF_SHARED;
+#else
+	flags = SA_SHIRQ;
+#endif
+
+	for (i=0; i<dev->nr_queue; i++) {
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,30))
+		if (threaded_irq) {
+			ret = request_threaded_irq(dev->entry[i].vector, ssd_interrupt_check, ssd_interrupt_threaded, flags, dev->queue[i].name, &dev->queue[i]);
+		} else if (dev->int_mode == SSD_INT_LEGACY) {
+			ret = request_irq(dev->entry[i].vector, &ssd_interrupt_legacy, flags, dev->queue[i].name, &dev->queue[i]);
+		} else {
+			ret = request_irq(dev->entry[i].vector, &ssd_interrupt, flags, dev->queue[i].name, &dev->queue[i]);
+		}
+#else
+		if (dev->int_mode == SSD_INT_LEGACY) {
+			ret = request_irq(dev->entry[i].vector, &ssd_interrupt_legacy, flags, dev->queue[i].name, &dev->queue[i]);
+		} else {
+			ret = request_irq(dev->entry[i].vector, &ssd_interrupt, flags, dev->queue[i].name, &dev->queue[i]);
+		}
+#endif
+		if (ret) {
+			hio_warn("%s: request irq failed\n", dev->name);
+			/* alarm led */
+			ssd_set_alarm(dev);
+			goto out_request_irq;
+		}
+
+#if (!defined MODULE) && (defined SSD_MSIX_AFFINITY_FORCE)
+		cpu_mask = (dev_to_node(&dev->pdev->dev) == -1) ? cpu_online_mask : cpumask_of_node(dev_to_node(&dev->pdev->dev));
+		if (SSD_INT_MSIX == dev->int_mode) {
+			if ((0 == cpu_affinity) || (!cpumask_intersects(mask, cpumask_of(cpu_affinity)))) {
+				cpu_affinity = cpumask_first(cpu_mask);
+			}
+
+			irq_set_affinity(dev->entry[i].vector, cpumask_of(cpu_affinity));
+			cpu_affinity = cpumask_next(cpu_affinity, cpu_mask);
+			if (cpu_affinity >= nr_cpu_ids) {
+				cpu_affinity = cpumask_first(cpu_mask);
+			}
+		}
+#endif
+	}
+
+	return ret;
+
+out_request_irq:
+#if ((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35)) || (defined RHEL_MAJOR && RHEL_MAJOR == 6))
+	if (SSD_INT_MSIX == dev->int_mode) {
+		for (j=0; j<dev->nr_queue; j++) {
+			irq_set_affinity_hint(dev->entry[j].vector, NULL);
+		}
+	}
+#endif
+
+	for (i--; i>=0; i--) {
+		free_irq(dev->entry[i].vector, &dev->queue[i]);
+	}
+
+	if (SSD_INT_MSIX == dev->int_mode) {
+		pci_disable_msix(dev->pdev);
+	} else if (SSD_INT_MSI == dev->int_mode) {
+		pci_disable_msi(dev->pdev);
+	}
+
+out:
+	return ret;
+}
+
+static void ssd_initial_log(struct ssd_device *dev)
+{
+	uint32_t val;
+	uint32_t speed, width;
+	
+	if (dev->protocol_info.ver < SSD_PROTOCOL_V3_2) {
+		return;
+	}
+
+	val = ssd_reg32_read(dev->ctrlp + SSD_POWER_ON_REG);
+	if (val) {
+		ssd_gen_swlog(dev, SSD_LOG_POWER_ON, dev->hw_info.bridge_ver);
+	}
+
+	val = ssd_reg32_read(dev->ctrlp + SSD_PCIE_LINKSTATUS_REG);
+	speed = val & 0xF;
+	width = (val >> 4)& 0x3F;
+	if (0x1 == speed) {
+		hio_info("%s: PCIe: 2.5GT/s, x%u\n", dev->name, width);
+	} else if (0x2 == speed) {
+		hio_info("%s: PCIe: 5GT/s, x%u\n", dev->name, width);
+	} else {
+		hio_info("%s: PCIe: unknown GT/s, x%u\n", dev->name, width);
+	}
+	ssd_gen_swlog(dev, SSD_LOG_PCIE_LINK_STATUS, val);
+
+	return;
+}
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20))
+static void ssd_hwmon_worker(void *data)
+{
+	struct ssd_device *dev = (struct ssd_device *)data;
+#else
+static void ssd_hwmon_worker(struct work_struct *work)
+{
+	struct ssd_device *dev = container_of(work, struct ssd_device, hwmon_work);
+#endif
+
+	if (ssd_check_hw(dev)) {
+		//hio_err("%s: check hardware failed\n", dev->name);
+		return;
+	}
+
+	ssd_check_clock(dev);
+	ssd_check_volt(dev);
+
+	ssd_mon_boardvolt(dev);
+}
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20))
+static void ssd_tempmon_worker(void *data)
+{
+	struct ssd_device *dev = (struct ssd_device *)data;
+#else
+static void ssd_tempmon_worker(struct work_struct *work)
+{
+	struct ssd_device *dev = container_of(work, struct ssd_device, tempmon_work);
+#endif
+
+	if (ssd_check_hw(dev)) {
+		//hio_err("%s: check hardware failed\n", dev->name);
+		return;
+	}
+
+	ssd_mon_temp(dev);
+}
+
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20))
+static void ssd_capmon_worker(void *data)
+{
+	struct ssd_device *dev = (struct ssd_device *)data;
+#else
+static void ssd_capmon_worker(struct work_struct *work)
+{
+	struct ssd_device *dev = container_of(work, struct ssd_device, capmon_work);
+#endif
+	uint32_t cap = 0;
+	uint32_t cap_threshold = SSD_PL_CAP_THRESHOLD;
+	int ret = 0;
+
+	if (dev->protocol_info.ver < SSD_PROTOCOL_V3_2) {
+		return;
+	}
+
+	if (dev->hw_info_ext.form_factor == SSD_FORM_FACTOR_FHHL && dev->hw_info.pcb_ver < 'B') {
+		return;
+	}
+
+	/* fault before? */
+	if (test_bit(SSD_HWMON_PL_CAP(SSD_PL_CAP), &dev->hwmon)) {
+		ret = ssd_check_pl_cap_fast(dev);
+		if (ret) {
+			return;
+		}
+	}
+
+	/* learn */
+	ret = ssd_do_cap_learn(dev, &cap);
+	if (ret) {
+		hio_err("%s: cap learn failed\n", dev->name);
+		ssd_gen_swlog(dev, SSD_LOG_CAP_LEARN_FAULT, 0);
+		return;
+	}
+
+	ssd_gen_swlog(dev, SSD_LOG_CAP_STATUS, cap);
+
+	if (SSD_PL_CAP_CP == dev->hw_info_ext.cap_type) {
+		cap_threshold = SSD_PL_CAP_CP_THRESHOLD;
+	}
+
+	//use the fw event id?
+	if (cap < cap_threshold) {
+		if (!test_bit(SSD_HWMON_PL_CAP(SSD_PL_CAP), &dev->hwmon)) {
+			ssd_gen_swlog(dev, SSD_LOG_BATTERY_FAULT, 0);
+		}
+	} else if (cap >= (cap_threshold + SSD_PL_CAP_THRESHOLD_HYST)) {
+		if (test_bit(SSD_HWMON_PL_CAP(SSD_PL_CAP), &dev->hwmon)) {
+			ssd_gen_swlog(dev, SSD_LOG_BATTERY_OK, 0);
+		}
+	}
+}
+
+static void ssd_routine_start(void *data)
+{
+	struct ssd_device *dev;
+
+	if (!data) {
+		return;
+	}
+	dev = data;
+
+	dev->routine_tick++;
+
+	if (test_bit(SSD_INIT_WORKQ, &dev->state) && !ssd_busy(dev)) {
+		(void)test_and_set_bit(SSD_LOG_HW, &dev->state);
+		queue_work(dev->workq, &dev->log_work);
+	}
+
+	if ((dev->routine_tick % SSD_HWMON_ROUTINE_TICK) == 0 && test_bit(SSD_INIT_WORKQ, &dev->state)) {
+		queue_work(dev->workq, &dev->hwmon_work);
+	}
+
+	if ((dev->routine_tick % SSD_CAPMON_ROUTINE_TICK) == 0 && test_bit(SSD_INIT_WORKQ, &dev->state)) {
+		queue_work(dev->workq, &dev->capmon_work);
+	}
+
+	if ((dev->routine_tick % SSD_CAPMON2_ROUTINE_TICK) == 0 && test_bit(SSD_HWMON_PL_CAP(SSD_PL_CAP), &dev->hwmon) && test_bit(SSD_INIT_WORKQ, &dev->state)) {
+		/* CAP fault? check again */
+		queue_work(dev->workq, &dev->capmon_work);
+	}
+
+	if (test_bit(SSD_INIT_WORKQ, &dev->state)) {
+		queue_work(dev->workq, &dev->tempmon_work);
+	}
+
+	/* schedule routine */
+	mod_timer(&dev->routine_timer, jiffies + msecs_to_jiffies(SSD_ROUTINE_INTERVAL));
+}
+
+static void ssd_cleanup_routine(struct ssd_device *dev)
+{
+	if (unlikely(mode != SSD_DRV_MODE_STANDARD))
+		return;
+
+	(void)ssd_del_timer(&dev->routine_timer);
+
+	(void)ssd_del_timer(&dev->bm_timer);
+}
+
+static int ssd_init_routine(struct ssd_device *dev)
+{
+	if (unlikely(mode != SSD_DRV_MODE_STANDARD))
+		return 0;
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20))
+	INIT_WORK(&dev->bm_work, ssd_bm_worker, dev);
+	INIT_WORK(&dev->hwmon_work, ssd_hwmon_worker, dev);
+	INIT_WORK(&dev->capmon_work, ssd_capmon_worker, dev);
+	INIT_WORK(&dev->tempmon_work, ssd_tempmon_worker, dev);
+#else
+	INIT_WORK(&dev->bm_work, ssd_bm_worker);
+	INIT_WORK(&dev->hwmon_work, ssd_hwmon_worker);
+	INIT_WORK(&dev->capmon_work, ssd_capmon_worker);
+	INIT_WORK(&dev->tempmon_work, ssd_tempmon_worker);
+#endif
+
+	/* initial log */
+	ssd_initial_log(dev);
+
+	/* schedule bm routine */
+	ssd_add_timer(&dev->bm_timer, msecs_to_jiffies(SSD_BM_CAP_LEARNING_DELAY), ssd_bm_routine_start, dev);
+
+	/* schedule routine */
+	ssd_add_timer(&dev->routine_timer, msecs_to_jiffies(SSD_ROUTINE_INTERVAL), ssd_routine_start, dev);
+
+	return 0;
+}
+
+static void 
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38))
+__devexit 
+#endif
+ssd_remove_one (struct pci_dev *pdev)
+{
+	struct ssd_device *dev;
+
+	if (!pdev) {
+		return;
+	}
+
+	dev = pci_get_drvdata(pdev);
+	if (!dev) {
+		return;
+	}
+
+	list_del_init(&dev->list);
+
+	ssd_unregister_sysfs(dev);
+
+	/* offline firstly */
+	test_and_clear_bit(SSD_ONLINE, &dev->state);
+
+	/* clean work queue first */
+	if (!dev->slave) {
+		test_and_clear_bit(SSD_INIT_WORKQ, &dev->state);
+		ssd_cleanup_workq(dev);
+	}
+
+	/* flush cache */
+	(void)ssd_flush(dev);
+	(void)ssd_save_md(dev);
+
+	/* save smart */
+	if (!dev->slave) {
+		ssd_save_smart(dev);
+	}
+
+	if (test_and_clear_bit(SSD_INIT_BD, &dev->state)) {
+		ssd_cleanup_blkdev(dev);
+	}
+
+	if (!dev->slave) {
+		ssd_cleanup_chardev(dev);
+	}
+
+	/* clean routine */
+	if (!dev->slave) {
+		ssd_cleanup_routine(dev);
+	}
+
+	ssd_cleanup_queue(dev);
+
+	ssd_cleanup_tag(dev);
+	ssd_cleanup_thread(dev);
+
+	ssd_free_irq(dev);
+
+	ssd_cleanup_dcmd(dev);
+	ssd_cleanup_cmd(dev);
+	ssd_cleanup_response(dev);
+
+	if (!dev->slave) {
+		ssd_cleanup_log(dev);
+	}
+
+	if (dev->reload_fw) { //reload fw
+		ssd_reg32_write(dev->ctrlp + SSD_RELOAD_FW_REG, SSD_RELOAD_FW);
+	}
+
+	/* unmap physical adress */
+#ifdef LINUX_SUSE_OS
+	iounmap(dev->ctrlp);
+#else
+	pci_iounmap(pdev, dev->ctrlp);
+#endif
+
+	release_mem_region(dev->mmio_base, dev->mmio_len);
+
+	pci_disable_device(pdev);
+
+	pci_set_drvdata(pdev, NULL);
+
+	ssd_put(dev);
+}
+
+static int 
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38))
+__devinit 
+#endif
+ssd_init_one(struct pci_dev *pdev, 
+	const struct pci_device_id *ent)
+{
+	struct ssd_device *dev;
+	int ret = 0;
+
+	if (!pdev || !ent) {
+		ret = -EINVAL;
+		goto out;
+	}
+
+	dev = kmalloc(sizeof(struct ssd_device), GFP_KERNEL);
+	if (!dev) {
+		ret = -ENOMEM;
+		goto out_alloc_dev;
+	}
+	memset(dev, 0, sizeof(struct ssd_device));
+
+	dev->owner = THIS_MODULE;
+
+	if (SSD_SLAVE_PORT_DEVID == ent->device) {
+		dev->slave = 1;
+	}
+
+	dev->idx = ssd_get_index(dev->slave);
+	if (dev->idx < 0) {
+		ret = -ENOMEM;
+		goto out_get_index;
+	}
+
+	if (!dev->slave) {
+		snprintf(dev->name, SSD_DEV_NAME_LEN, SSD_DEV_NAME);
+		ssd_set_dev_name(&dev->name[strlen(SSD_DEV_NAME)], SSD_DEV_NAME_LEN-strlen(SSD_DEV_NAME), dev->idx);
+		
+		dev->major = ssd_major;
+		dev->cmajor = ssd_cmajor;
+	} else {
+		snprintf(dev->name, SSD_DEV_NAME_LEN, SSD_SDEV_NAME);
+		ssd_set_dev_name(&dev->name[strlen(SSD_SDEV_NAME)], SSD_DEV_NAME_LEN-strlen(SSD_SDEV_NAME), dev->idx);
+		dev->major = ssd_major_sl;
+		dev->cmajor = 0;
+	}
+
+	atomic_set(&(dev->refcnt), 0);
+	atomic_set(&(dev->tocnt), 0);
+
+	mutex_init(&dev->fw_mutex);
+
+	//xx
+	mutex_init(&dev->gd_mutex);
+
+	dev->pdev = pdev;
+	pci_set_drvdata(pdev, dev);
+
+	kref_init(&dev->kref);
+
+	ret = pci_enable_device(pdev);
+	if (ret) {
+		hio_warn("%s: can not enable device\n", dev->name);
+		goto out_enable_device;
+	}
+
+	pci_set_master(pdev);
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,31))
+	ret = pci_set_dma_mask(pdev, DMA_64BIT_MASK);
+#else
+	ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(64));
+#endif
+	if (ret) {
+		hio_warn("%s: set dma mask: failed\n", dev->name);
+		goto out_set_dma_mask;
+	}
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,31))
+	ret = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK);
+#else
+	ret = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64));
+#endif
+	if (ret) {
+		hio_warn("%s: set consistent dma mask: failed\n", dev->name);
+		goto out_set_dma_mask;
+	}
+
+	dev->mmio_base = pci_resource_start(pdev, 0);
+	dev->mmio_len = pci_resource_len(pdev, 0);
+
+	if (!request_mem_region(dev->mmio_base, dev->mmio_len, SSD_DEV_NAME)) {
+		hio_warn("%s: can not reserve MMIO region 0\n", dev->name);
+		ret = -EBUSY;
+		goto out_request_mem_region;
+	}
+
+	/* 2.6.9 kernel bug */
+	dev->ctrlp = pci_iomap(pdev, 0, 0);
+	if (!dev->ctrlp) {
+		hio_warn("%s: can not remap IO region 0\n", dev->name);
+		ret = -ENOMEM;
+		goto out_pci_iomap;
+	}
+
+	ret = ssd_check_hw(dev);
+	if (ret) {
+		hio_err("%s: check hardware failed\n", dev->name);
+		goto out_check_hw;
+	}
+
+	ret = ssd_init_protocol_info(dev);
+	if (ret) {
+		hio_err("%s: init protocol info failed\n", dev->name);
+		goto out_init_protocol_info;
+	}
+
+	/* alarm led ? */
+	ssd_clear_alarm(dev);
+
+	ret = ssd_init_fw_info(dev);
+	if (ret) {
+		hio_err("%s: init firmware info failed\n", dev->name);
+		/* alarm led */
+		ssd_set_alarm(dev);
+		goto out_init_fw_info;
+	}
+	
+	/* slave port ? */
+	if (dev->slave) {
+		goto init_next1;
+	}
+
+	ret = ssd_init_rom_info(dev);
+	if (ret) {
+		hio_err("%s: init rom info failed\n", dev->name);
+		/* alarm led */
+		ssd_set_alarm(dev);
+		goto out_init_rom_info;
+	}
+
+	ret = ssd_init_label(dev);
+	if (ret) {
+		hio_err("%s: init label failed\n", dev->name);
+		/* alarm led */
+		ssd_set_alarm(dev);
+		goto out_init_label;
+	}
+
+	ret = ssd_init_workq(dev);
+	if (ret) {
+		hio_warn("%s: init workq failed\n", dev->name);
+		goto out_init_workq;
+	}
+	(void)test_and_set_bit(SSD_INIT_WORKQ, &dev->state);
+
+	ret = ssd_init_log(dev);
+	if (ret) {
+		hio_err("%s: init log failed\n", dev->name);
+		/* alarm led */
+		ssd_set_alarm(dev);
+		goto out_init_log;
+	}
+
+	ret = ssd_init_smart(dev);
+	if (ret) {
+		hio_err("%s: init info failed\n", dev->name);
+		/* alarm led */
+		ssd_set_alarm(dev);
+		goto out_init_smart;
+	}
+
+init_next1:
+	ret = ssd_init_hw_info(dev);
+	if (ret) {
+		hio_err("%s: init hardware info failed\n", dev->name);
+		/* alarm led */
+		ssd_set_alarm(dev);
+		goto out_init_hw_info;
+	}
+
+	/* slave port ? */
+	if (dev->slave) {
+		goto init_next2;
+	}
+
+	ret = ssd_init_sensor(dev);
+	if (ret) {
+		hio_err("%s: init sensor failed\n", dev->name);
+		/* alarm led */
+		ssd_set_alarm(dev);
+		goto out_init_sensor;
+	}
+
+	ret = ssd_init_pl_cap(dev);
+	if (ret) {
+		hio_err("%s: int pl_cap failed\n", dev->name);
+		/* alarm led */
+		ssd_set_alarm(dev);
+		goto out_init_pl_cap;
+	}
+
+init_next2:
+	ret = ssd_check_init_state(dev);
+	if (ret) {
+		hio_err("%s: check init state failed\n", dev->name);
+		/* alarm led */
+		ssd_set_alarm(dev);
+		goto out_check_init_state;
+	}
+
+	ret = ssd_init_response(dev);
+	if (ret) {
+		hio_warn("%s: init resp_msg failed\n", dev->name);
+		goto out_init_response;
+	}
+
+	ret = ssd_init_cmd(dev);
+	if (ret) {
+		hio_warn("%s: init msg failed\n", dev->name);
+		goto out_init_cmd;
+	}
+
+	ret = ssd_init_dcmd(dev);
+	if (ret) {
+		hio_warn("%s: init cmd failed\n", dev->name);
+		goto out_init_dcmd;
+	}
+
+	ret = ssd_init_irq(dev);
+	if (ret) {
+		hio_warn("%s: init irq failed\n", dev->name);
+		goto out_init_irq;
+	}
+
+	ret = ssd_init_thread(dev);
+	if (ret) {
+		hio_warn("%s: init thread failed\n", dev->name);
+		goto out_init_thread;
+	}
+
+	ret = ssd_init_tag(dev);
+	if(ret) {
+		hio_warn("%s: init tags failed\n", dev->name);
+		goto out_init_tags;
+	}
+
+	/*  */
+	(void)test_and_set_bit(SSD_ONLINE, &dev->state);
+
+	ret = ssd_init_queue(dev);
+	if (ret) {
+		hio_warn("%s: init queue failed\n", dev->name);
+		goto out_init_queue;
+	}
+
+	/* slave port ? */
+	if (dev->slave) {
+		goto init_next3;
+	}
+
+	ret = ssd_init_ot_protect(dev);
+	if (ret) {
+		hio_err("%s: int ot_protect failed\n", dev->name);
+		/* alarm led */
+		ssd_set_alarm(dev);
+		goto out_int_ot_protect;
+	}
+
+	ret = ssd_init_wmode(dev);
+	if (ret) {
+		hio_warn("%s: init write mode\n", dev->name);
+		goto out_init_wmode;
+	}
+
+	/* init routine after hw is ready */
+	ret = ssd_init_routine(dev);
+	if (ret) {
+		hio_warn("%s: init routine\n", dev->name);
+		goto out_init_routine;
+	}
+
+	ret = ssd_init_chardev(dev);
+	if (ret) {
+		hio_warn("%s: register char device failed\n", dev->name);
+		goto out_init_chardev;
+	}
+
+init_next3:
+	ret = ssd_init_blkdev(dev);
+	if (ret) {
+		hio_warn("%s: register block device failed\n", dev->name);
+		goto out_init_blkdev;
+	}
+	(void)test_and_set_bit(SSD_INIT_BD, &dev->state);
+
+	ret = ssd_register_sysfs(dev);
+	if (ret) {
+		hio_warn("%s: register sysfs failed\n", dev->name);
+		goto out_register_sysfs;
+	}
+
+	dev->save_md = 1;
+
+	list_add_tail(&dev->list, &ssd_list);
+
+	return 0;
+
+out_register_sysfs:
+	test_and_clear_bit(SSD_INIT_BD, &dev->state);
+	ssd_cleanup_blkdev(dev);
+out_init_blkdev:
+	/* slave port ? */
+	if (!dev->slave) {
+		ssd_cleanup_chardev(dev);
+	}
+out_init_chardev:
+	/* slave port ? */
+	if (!dev->slave) {
+		ssd_cleanup_routine(dev);
+	}
+out_init_routine:
+out_init_wmode:
+out_int_ot_protect:
+	ssd_cleanup_queue(dev);
+out_init_queue:
+	test_and_clear_bit(SSD_ONLINE, &dev->state);
+	ssd_cleanup_tag(dev);
+out_init_tags:
+	ssd_cleanup_thread(dev);
+out_init_thread:
+	ssd_free_irq(dev);
+out_init_irq:
+	ssd_cleanup_dcmd(dev);
+out_init_dcmd:
+	ssd_cleanup_cmd(dev);
+out_init_cmd:
+	ssd_cleanup_response(dev);
+out_init_response:
+out_check_init_state:
+out_init_pl_cap:
+out_init_sensor:
+out_init_hw_info:
+out_init_smart:
+	/* slave port ? */
+	if (!dev->slave) {
+		ssd_cleanup_log(dev);
+	}
+out_init_log:
+	/* slave port ? */
+	if (!dev->slave) {
+		test_and_clear_bit(SSD_INIT_WORKQ, &dev->state);
+		ssd_cleanup_workq(dev);
+	}
+out_init_workq:
+out_init_label:
+out_init_rom_info:
+out_init_fw_info:
+out_init_protocol_info:
+out_check_hw:
+#ifdef LINUX_SUSE_OS
+	iounmap(dev->ctrlp);
+#else
+	pci_iounmap(pdev, dev->ctrlp);
+#endif
+out_pci_iomap:
+	release_mem_region(dev->mmio_base, dev->mmio_len);
+out_request_mem_region:
+out_set_dma_mask:
+	pci_disable_device(pdev);
+out_enable_device:
+	pci_set_drvdata(pdev, NULL);
+out_get_index:
+	kfree(dev);
+out_alloc_dev:
+out:
+	return ret;
+}
+
+static void ssd_cleanup_tasklet(void)
+{
+	int i;
+	for_each_online_cpu(i) {
+		tasklet_kill(&per_cpu(ssd_tasklet, i));
+	}
+}
+
+static int ssd_init_tasklet(void)
+{
+	int i;
+
+	for_each_online_cpu(i) {
+		INIT_LIST_HEAD(&per_cpu(ssd_doneq, i));
+
+		if (finject) {
+			tasklet_init(&per_cpu(ssd_tasklet, i), __ssd_done_db, 0);
+		} else {
+			tasklet_init(&per_cpu(ssd_tasklet, i), __ssd_done, 0);
+		}
+	}
+
+	return 0;
+}
+
+static struct pci_device_id ssd_pci_tbl[] = {
+	{ 0x10ee, 0x0007, PCI_ANY_ID, PCI_ANY_ID, }, /* g3 */
+	{ 0x19e5, 0x0007, PCI_ANY_ID, PCI_ANY_ID, }, /* v1 */
+	//{ 0x19e5, 0x0008, PCI_ANY_ID, PCI_ANY_ID, }, /* v1 sp*/
+	{ 0x19e5, 0x0009, PCI_ANY_ID, PCI_ANY_ID, }, /* v2 */
+	{ 0x19e5, 0x000a, PCI_ANY_ID, PCI_ANY_ID, }, /* v2 dp slave*/
+	{ 0, }
+};
+MODULE_DEVICE_TABLE(pci, ssd_pci_tbl);
+
+static struct pci_driver ssd_driver = {
+	.name		= MODULE_NAME, 
+	.id_table	= ssd_pci_tbl, 
+	.probe		= ssd_init_one, 
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38))	
+	.remove		= __devexit_p(ssd_remove_one), 
+#else
+	.remove		= ssd_remove_one, 
+#endif
+};
+
+/* notifier block to get a notify on system shutdown/halt/reboot */
+static int ssd_notify_reboot(struct notifier_block *nb, unsigned long event, void *buf)
+{
+	struct ssd_device *dev = NULL;
+	struct ssd_device *n = NULL;
+
+	list_for_each_entry_safe(dev, n, &ssd_list, list) {
+		ssd_gen_swlog(dev, SSD_LOG_POWER_OFF, 0);
+	
+		(void)ssd_flush(dev);
+		(void)ssd_save_md(dev);
+
+		/* slave port ? */
+		if (!dev->slave) {
+			ssd_save_smart(dev);
+
+			ssd_stop_workq(dev);
+
+			if (dev->reload_fw) {
+				ssd_reg32_write(dev->ctrlp + SSD_RELOAD_FW_REG, SSD_RELOAD_FW);
+			}
+		}
+	}
+
+	return NOTIFY_OK;
+}
+
+static struct notifier_block ssd_notifier = {
+	ssd_notify_reboot, NULL, 0
+};
+
+static int __init ssd_init_module(void)
+{
+	int ret = 0;
+
+	hio_info("driver version: %s\n", DRIVER_VERSION);
+
+	ret = ssd_init_index();
+	if (ret) {
+		hio_warn("init index failed\n");
+		goto out_init_index;
+	}
+
+	ret = ssd_init_proc();
+	if (ret) {
+		hio_warn("init proc failed\n");
+		goto out_init_proc;
+	}
+
+	ret = ssd_init_sysfs();
+	if (ret) {
+		hio_warn("init sysfs failed\n");
+		goto out_init_sysfs;
+	}
+
+	ret = ssd_init_tasklet();
+	if (ret) {
+		hio_warn("init tasklet failed\n");
+		goto out_init_tasklet;
+	}
+
+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,12))
+	ssd_class = class_simple_create(THIS_MODULE, SSD_DEV_NAME);
+#else
+	ssd_class = class_create(THIS_MODULE, SSD_DEV_NAME);
+#endif
+	if (IS_ERR(ssd_class)) {
+		ret = PTR_ERR(ssd_class);
+		goto out_class_create;
+	}
+
+	if (ssd_cmajor > 0) {
+		ret = register_chrdev(ssd_cmajor, SSD_CDEV_NAME, &ssd_cfops);
+	} else {
+		ret = ssd_cmajor = register_chrdev(ssd_cmajor, SSD_CDEV_NAME, &ssd_cfops);
+	}
+	if (ret < 0) {
+		hio_warn("unable to register chardev major number\n");
+		goto out_register_chardev;
+	}
+
+	if (ssd_major > 0) {
+		ret = register_blkdev(ssd_major, SSD_DEV_NAME);
+	} else {
+		ret = ssd_major = register_blkdev(ssd_major, SSD_DEV_NAME);
+	}
+	if (ret < 0) {
+		hio_warn("unable to register major number\n");
+		goto out_register_blkdev;
+	}
+
+	if (ssd_major_sl > 0) {
+		ret = register_blkdev(ssd_major_sl, SSD_SDEV_NAME);
+	} else {
+		ret = ssd_major_sl = register_blkdev(ssd_major_sl, SSD_SDEV_NAME);
+	}
+	if (ret < 0) {
+		hio_warn("unable to register slave major number\n");
+		goto out_register_blkdev_sl;
+	}
+
+	if (mode < SSD_DRV_MODE_STANDARD || mode > SSD_DRV_MODE_BASE) {
+		mode = SSD_DRV_MODE_STANDARD;
+	}
+
+	/* for debug */
+	if (mode != SSD_DRV_MODE_STANDARD) {
+		ssd_minors = 1;
+	}
+
+	if (int_mode < SSD_INT_LEGACY || int_mode > SSD_INT_MSIX) {
+		int_mode = SSD_INT_MODE_DEFAULT;
+	}
+
+	if (threaded_irq) {
+		int_mode = SSD_INT_MSI;
+	}
+
+	if (log_level >= SSD_LOG_NR_LEVEL || log_level < SSD_LOG_LEVEL_INFO) {
+		log_level = SSD_LOG_LEVEL_ERR;
+	}
+
+	if (wmode < SSD_WMODE_BUFFER || wmode > SSD_WMODE_DEFAULT) {
+		wmode = SSD_WMODE_DEFAULT;
+	}
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20))
+	ret = pci_module_init(&ssd_driver);
+#else
+	ret = pci_register_driver(&ssd_driver);
+#endif
+	if (ret) {
+		hio_warn("pci init failed\n");
+		goto out_pci_init;
+	}
+
+	ret = register_reboot_notifier(&ssd_notifier);
+	if (ret) {
+		hio_warn("register reboot notifier failed\n");
+		goto out_register_reboot_notifier;
+	}
+
+	return 0;
+
+out_register_reboot_notifier:
+out_pci_init:
+	pci_unregister_driver(&ssd_driver);
+	unregister_blkdev(ssd_major_sl, SSD_SDEV_NAME);
+out_register_blkdev_sl:
+	unregister_blkdev(ssd_major, SSD_DEV_NAME);
+out_register_blkdev:
+	unregister_chrdev(ssd_cmajor, SSD_CDEV_NAME);
+out_register_chardev:
+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,12))
+	class_simple_destroy(ssd_class);
+#else
+	class_destroy(ssd_class);
+#endif
+out_class_create:
+	ssd_cleanup_tasklet();
+out_init_tasklet:
+	ssd_cleanup_sysfs();
+out_init_sysfs:
+	ssd_cleanup_proc();
+out_init_proc:
+	ssd_cleanup_index();
+out_init_index:
+	return ret;
+
+}
+
+static void __exit ssd_cleanup_module(void)
+{
+
+	hio_info("unload driver: %s\n", DRIVER_VERSION);
+	/* exiting */
+	ssd_exiting = 1;
+
+	unregister_reboot_notifier(&ssd_notifier);
+
+	pci_unregister_driver(&ssd_driver);
+
+	unregister_blkdev(ssd_major_sl, SSD_SDEV_NAME);
+	unregister_blkdev(ssd_major, SSD_DEV_NAME);
+	unregister_chrdev(ssd_cmajor, SSD_CDEV_NAME);
+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,12))
+	class_simple_destroy(ssd_class);
+#else
+	class_destroy(ssd_class);
+#endif
+
+	ssd_cleanup_tasklet();
+	ssd_cleanup_sysfs();
+	ssd_cleanup_proc();
+	ssd_cleanup_index();
+}
+
+int ssd_register_event_notifier(struct block_device *bdev, ssd_event_call event_call)
+{
+	struct ssd_device *dev;
+	struct timeval tv;
+	struct ssd_log *le;
+	uint64_t cur;
+	int log_nr;
+
+	if (!bdev || !event_call || !(bdev->bd_disk)) {
+		return -EINVAL;
+	}
+
+	dev = bdev->bd_disk->private_data;
+	dev->event_call = event_call;
+
+	do_gettimeofday(&tv);
+	cur = tv.tv_sec;
+
+	le = (struct ssd_log *)(dev->internal_log.log);
+	log_nr = dev->internal_log.nr_log;
+
+	while (log_nr--) {
+		if (le->time <= cur && le->time >= dev->uptime) {
+			(void)dev->event_call(dev->gd, le->le.event, ssd_parse_log(dev, le, 0));
+		}
+		le++;
+	}
+
+	return 0;
+}
+
+int ssd_unregister_event_notifier(struct block_device *bdev)
+{
+	struct ssd_device *dev;
+
+	if (!bdev || !(bdev->bd_disk)) {
+		return -EINVAL;
+	}
+
+	dev = bdev->bd_disk->private_data;
+	dev->event_call = NULL;
+
+	return 0;
+}
+
+EXPORT_SYMBOL(ssd_get_label);
+EXPORT_SYMBOL(ssd_get_version);
+EXPORT_SYMBOL(ssd_set_otprotect);
+EXPORT_SYMBOL(ssd_bm_status);
+EXPORT_SYMBOL(ssd_submit_pbio);
+EXPORT_SYMBOL(ssd_get_pciaddr);
+EXPORT_SYMBOL(ssd_get_temperature);
+EXPORT_SYMBOL(ssd_register_event_notifier);
+EXPORT_SYMBOL(ssd_unregister_event_notifier);
+EXPORT_SYMBOL(ssd_reset);
+EXPORT_SYMBOL(ssd_set_wmode);
+
+
+
+module_init(ssd_init_module);
+module_exit(ssd_cleanup_module);
+MODULE_VERSION(DRIVER_VERSION);
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Huawei SSD DEV Team");
+MODULE_DESCRIPTION("Huawei SSD driver");
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/hio/hio.h
@@ -0,0 +1,104 @@
+/*
+* Huawei SSD device driver
+* Copyright (c) 2016, Huawei Technologies Co., Ltd.
+*
+* This program is free software; you can redistribute it and/or modify it
+* under the terms and conditions of the GNU General Public License,
+* version 2, as published by the Free Software Foundation.
+*
+* This program is distributed in the hope it will be useful, but WITHOUT
+* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+* more details.
+*/
+
+#ifndef _HIO_H
+#define _HIO_H
+
+#include <linux/types.h>
+#include <linux/genhd.h>
+#include <linux/blkdev.h>
+#include <linux/genhd.h>
+
+
+
+typedef int (*ssd_event_call)(struct gendisk *, int, int);	/* gendisk, event id, event level */
+extern int ssd_register_event_notifier(struct block_device *bdev, ssd_event_call event_call);
+/* unregister event notifier before module exit */
+extern int ssd_unregister_event_notifier(struct block_device *bdev);
+
+
+/* label */
+#define SSD_LABEL_FIELD_SZ	32
+#define SSD_SN_SZ			16
+
+typedef struct ssd_label
+{
+	char date[SSD_LABEL_FIELD_SZ];
+	char sn[SSD_LABEL_FIELD_SZ];
+	char part[SSD_LABEL_FIELD_SZ];
+	char desc[SSD_LABEL_FIELD_SZ];
+	char other[SSD_LABEL_FIELD_SZ];
+	char maf[SSD_LABEL_FIELD_SZ];
+} ssd_label_t;
+
+
+/* version */
+typedef struct ssd_version_info
+{
+	uint32_t bridge_ver;	/* bridge fw version: hex */
+	uint32_t ctrl_ver;		/* controller fw version: hex */
+	uint32_t bm_ver;		/* battery manager fw version: hex */
+	uint8_t  pcb_ver;		/* main pcb version: char */
+	uint8_t  upper_pcb_ver;
+	uint8_t  pad0;
+	uint8_t  pad1;
+} ssd_version_info_t;
+
+extern int ssd_get_label(struct block_device *bdev, struct ssd_label *label);
+extern int ssd_get_version(struct block_device *bdev, struct ssd_version_info *ver);
+extern int ssd_get_temperature(struct block_device *bdev, int *temp);
+
+
+enum ssd_bmstatus
+{
+	SSD_BMSTATUS_OK = 0,
+	SSD_BMSTATUS_CHARGING, 
+	SSD_BMSTATUS_WARNING
+};
+extern int ssd_bm_status(struct block_device *bdev, int *status);
+
+enum ssd_otprotect
+{
+	SSD_OTPROTECT_OFF = 0,
+	SSD_OTPROTECT_ON
+};
+extern int ssd_set_otprotect(struct block_device *bdev, int otprotect);
+
+typedef struct pci_addr
+{
+	uint16_t domain;
+	uint8_t bus;
+	uint8_t slot;
+	uint8_t func;
+} pci_addr_t;
+extern int ssd_get_pciaddr(struct block_device *bdev, struct pci_addr *paddr);
+
+/* submit phys bio: phys addr in iovec */
+extern void ssd_submit_pbio(struct request_queue *q, struct bio *bio);
+
+extern int ssd_reset(struct block_device *bdev);
+
+enum ssd_write_mode
+{
+	SSD_WMODE_BUFFER = 0,
+	SSD_WMODE_BUFFER_EX,
+	SSD_WMODE_FUA,
+	/* dummy */
+	SSD_WMODE_AUTO, 
+	SSD_WMODE_DEFAULT
+};
+extern int ssd_set_wmode(struct block_device *bdev, int wmode);
+
+#endif
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/i915/Kconfig
@@ -0,0 +1,64 @@
+config DRM_I915_BPO
+	tristate "Intel 8xx/9xx/G3x/G4x/HD Graphics"
+	depends on DRM
+	depends on X86 && PCI
+	select INTEL_GTT
+	select INTERVAL_TREE
+	# we need shmfs for the swappable backing store, and in particular
+	# the shmem_readpage() which depends upon tmpfs
+	select SHMEM
+	select TMPFS
+	select DRM_KMS_HELPER
+	select DRM_PANEL
+	select DRM_MIPI_DSI
+	# i915 depends on ACPI_VIDEO when ACPI is enabled
+	# but for select to work, need to select ACPI_VIDEO's dependencies, ick
+	select BACKLIGHT_LCD_SUPPORT if ACPI
+	select BACKLIGHT_CLASS_DEVICE if ACPI
+	select INPUT if ACPI
+	select ACPI_VIDEO if ACPI
+	select ACPI_BUTTON if ACPI
+	help
+	  Choose this option if you have a system that has "Intel Graphics
+	  Media Accelerator" or "HD Graphics" integrated graphics,
+	  including 830M, 845G, 852GM, 855GM, 865G, 915G, 945G, 965G,
+	  G35, G41, G43, G45 chipsets and Celeron, Pentium, Core i3,
+	  Core i5, Core i7 as well as Atom CPUs with integrated graphics.
+	  If M is selected, the module will be called i915.  AGP support
+	  is required for this driver to work. This driver is used by
+	  the Intel driver in X.org 6.8 and XFree86 4.4 and above. It
+	  replaces the older i830 module that supported a subset of the
+	  hardware in older X.org releases.
+
+	  Note that the older i810/i815 chipsets require the use of the
+	  i810 driver instead, and the Atom z5xx series has an entirely
+	  different implementation.
+
+config DRM_I915_BPO_PRELIMINARY_HW_SUPPORT
+	bool "Enable preliminary support for prerelease Intel hardware by default"
+	depends on DRM_I915
+	default n
+	help
+	  Choose this option if you have prerelease Intel hardware and want the
+	  i915 driver to support it by default.  You can enable such support at
+	  runtime with the module option i915.preliminary_hw_support=1; this
+	  option changes the default for that module option.
+
+	  If in doubt, say "N".
+
+config DRM_I915_BPO_USERPTR
+	bool "Always enable userptr support"
+	depends on DRM_I915
+	select MMU_NOTIFIER
+	default y
+	help
+	  This option selects CONFIG_MMU_NOTIFIER if it isn't already
+	  selected to enabled full userptr support.
+
+	  If in doubt, say "Y".
+
+menu "drm/i915 Debugging"
+depends on DRM_I915_BPO
+depends on EXPERT
+source ubuntu/i915/Kconfig.debug
+endmenu
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/i915/Kconfig.debug
@@ -0,0 +1,41 @@
+config DRM_I915_BPO_WERROR
+        bool "Force GCC to throw an error instead of a warning when compiling"
+        # As this may inadvertently break the build, only allow the user
+        # to shoot oneself in the foot iff they aim really hard
+        depends on EXPERT
+        # We use the dependency on !COMPILE_TEST to not be enabled in
+        # allmodconfig or allyesconfig configurations
+        depends on !COMPILE_TEST
+        default n
+        help
+          Add -Werror to the build flags for (and only for) i915.ko.
+          Do not enable this unless you are writing code for the i915.ko module.
+
+          Recommended for driver developers only.
+
+          If in doubt, say "N".
+
+config DRM_I915_BPO_DEBUG
+        bool "Enable additional driver debugging"
+        depends on DRM_I915_BPO
+        default n
+        help
+          Choose this option to turn on extra driver debugging that may affect
+          performance but will catch some internal issues.
+
+          Recommended for driver developers only.
+
+          If in doubt, say "N".
+
+config DRM_I915_BPO_DEBUG_GEM
+        bool "Insert extra checks into the GEM internals"
+        default n
+        depends on DRM_I915_BPO_WERROR
+        help
+          Enable extra sanity checks (including BUGs) along the GEM driver
+          paths that may slow the system down and if hit hang the machine.
+
+          Recommended for driver developers only.
+
+          If in doubt, say "N".
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/i915/Makefile
@@ -0,0 +1,106 @@
+#
+# Makefile for the drm device driver.  This driver provides support for the
+# Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher.
+
+subdir-ccflags-$(CONFIG_DRM_I915_WERROR) := -Werror
+
+# Please keep these build lists sorted!
+
+# core driver code
+i915_bpo-y := i915_drv.o \
+	  i915_irq.o \
+	  i915_params.o \
+          i915_suspend.o \
+	  i915_sysfs.o \
+	  intel_csr.o \
+	  intel_pm.o \
+	  intel_runtime_pm.o
+
+i915_bpo-$(CONFIG_COMPAT)   += i915_ioc32.o
+i915_bpo-$(CONFIG_DEBUG_FS) += i915_debugfs.o
+
+# GEM code
+i915_bpo-y += i915_cmd_parser.o \
+	  i915_gem_batch_pool.o \
+	  i915_gem_context.o \
+	  i915_gem_debug.o \
+	  i915_gem_dmabuf.o \
+	  i915_gem_evict.o \
+	  i915_gem_execbuffer.o \
+	  i915_gem_fence.o \
+	  i915_gem_gtt.o \
+	  i915_gem.o \
+	  i915_gem_render_state.o \
+	  i915_gem_shrinker.o \
+	  i915_gem_stolen.o \
+	  i915_gem_tiling.o \
+	  i915_gem_userptr.o \
+	  i915_gpu_error.o \
+	  i915_trace_points.o \
+	  intel_lrc.o \
+	  intel_mocs.o \
+	  intel_ringbuffer.o \
+	  intel_uncore.o
+
+# general-purpose microcontroller (GuC) support
+i915_bpo-y += intel_guc_loader.o \
+	  i915_guc_submission.o
+
+# autogenerated null render state
+i915_bpo-y += intel_renderstate_gen6.o \
+	  intel_renderstate_gen7.o \
+	  intel_renderstate_gen8.o \
+	  intel_renderstate_gen9.o
+
+# modesetting core code
+i915_bpo-y += intel_audio.o \
+	  intel_atomic.o \
+	  intel_atomic_plane.o \
+	  intel_bios.o \
+	  intel_color.o \
+	  intel_display.o \
+	  intel_dpll_mgr.o \
+	  intel_fbc.o \
+	  intel_fifo_underrun.o \
+	  intel_frontbuffer.o \
+	  intel_hotplug.o \
+	  intel_modes.o \
+	  intel_overlay.o \
+	  intel_psr.o \
+	  intel_sideband.o \
+	  intel_sprite.o
+i915_bpo-$(CONFIG_ACPI)		+= intel_acpi.o intel_opregion.o
+i915_bpo-$(CONFIG_DRM_FBDEV_EMULATION)	+= intel_fbdev.o
+
+# modesetting output/encoder code
+i915_bpo-y += dvo_ch7017.o \
+	  dvo_ch7xxx.o \
+	  dvo_ivch.o \
+	  dvo_ns2501.o \
+	  dvo_sil164.o \
+	  dvo_tfp410.o \
+	  intel_crt.o \
+	  intel_ddi.o \
+	  intel_dp_link_training.o \
+	  intel_dp_mst.o \
+	  intel_dp.o \
+	  intel_dsi.o \
+	  intel_dsi_panel_vbt.o \
+	  intel_dsi_pll.o \
+	  intel_dvo.o \
+	  intel_hdmi.o \
+	  intel_i2c.o \
+	  intel_lvds.o \
+	  intel_panel.o \
+	  intel_sdvo.o \
+	  intel_tv.o
+
+# virtual gpu code
+i915_bpo-y += i915_vgpu.o
+
+# legacy horrors
+i915_bpo-y += i915_dma.o
+
+obj-$(CONFIG_DRM_I915_BPO)  += i915_bpo.o
+
+CFLAGS_i915_trace_points.o := -I$(src)
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/i915/dvo.h
@@ -0,0 +1,139 @@
+/*
+ * Copyright © 2006 Eric Anholt
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  The copyright holders make no representations
+ * about the suitability of this software for any purpose.  It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+#ifndef _INTEL_DVO_H
+#define _INTEL_DVO_H
+
+#include <linux/i2c.h>
+#include <drm/drmP.h>
+#include <drm/drm_crtc.h>
+#include "intel_drv.h"
+
+struct intel_dvo_device {
+	const char *name;
+	int type;
+	/* DVOA/B/C output register */
+	i915_reg_t dvo_reg;
+	i915_reg_t dvo_srcdim_reg;
+	/* GPIO register used for i2c bus to control this device */
+	u32 gpio;
+	int slave_addr;
+
+	const struct intel_dvo_dev_ops *dev_ops;
+	void *dev_priv;
+	struct i2c_adapter *i2c_bus;
+};
+
+struct intel_dvo_dev_ops {
+	/*
+	 * Initialize the device at startup time.
+	 * Returns NULL if the device does not exist.
+	 */
+	bool (*init)(struct intel_dvo_device *dvo,
+		     struct i2c_adapter *i2cbus);
+
+	/*
+	 * Called to allow the output a chance to create properties after the
+	 * RandR objects have been created.
+	 */
+	void (*create_resources)(struct intel_dvo_device *dvo);
+
+	/*
+	 * Turn on/off output.
+	 *
+	 * Because none of our dvo drivers support an intermediate power levels,
+	 * we don't expose this in the interfac.
+	 */
+	void (*dpms)(struct intel_dvo_device *dvo, bool enable);
+
+	/*
+	 * Callback for testing a video mode for a given output.
+	 *
+	 * This function should only check for cases where a mode can't
+	 * be supported on the output specifically, and not represent
+	 * generic CRTC limitations.
+	 *
+	 * \return MODE_OK if the mode is valid, or another MODE_* otherwise.
+	 */
+	int (*mode_valid)(struct intel_dvo_device *dvo,
+			  struct drm_display_mode *mode);
+
+	/*
+	 * Callback for preparing mode changes on an output
+	 */
+	void (*prepare)(struct intel_dvo_device *dvo);
+
+	/*
+	 * Callback for committing mode changes on an output
+	 */
+	void (*commit)(struct intel_dvo_device *dvo);
+
+	/*
+	 * Callback for setting up a video mode after fixups have been made.
+	 *
+	 * This is only called while the output is disabled.  The dpms callback
+	 * must be all that's necessary for the output, to turn the output on
+	 * after this function is called.
+	 */
+	void (*mode_set)(struct intel_dvo_device *dvo,
+			 const struct drm_display_mode *mode,
+			 const struct drm_display_mode *adjusted_mode);
+
+	/*
+	 * Probe for a connected output, and return detect_status.
+	 */
+	enum drm_connector_status (*detect)(struct intel_dvo_device *dvo);
+
+	/*
+	 * Probe the current hw status, returning true if the connected output
+	 * is active.
+	 */
+	bool (*get_hw_state)(struct intel_dvo_device *dev);
+
+	/**
+	 * Query the device for the modes it provides.
+	 *
+	 * This function may also update MonInfo, mm_width, and mm_height.
+	 *
+	 * \return singly-linked list of modes or NULL if no modes found.
+	 */
+	struct drm_display_mode *(*get_modes)(struct intel_dvo_device *dvo);
+
+	/**
+	 * Clean up driver-specific bits of the output
+	 */
+	void (*destroy) (struct intel_dvo_device *dvo);
+
+	/**
+	 * Debugging hook to dump device registers to log file
+	 */
+	void (*dump_regs)(struct intel_dvo_device *dvo);
+};
+
+extern const struct intel_dvo_dev_ops sil164_ops;
+extern const struct intel_dvo_dev_ops ch7xxx_ops;
+extern const struct intel_dvo_dev_ops ivch_ops;
+extern const struct intel_dvo_dev_ops tfp410_ops;
+extern const struct intel_dvo_dev_ops ch7017_ops;
+extern const struct intel_dvo_dev_ops ns2501_ops;
+
+#endif /* _INTEL_DVO_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/i915/dvo_ch7017.c
@@ -0,0 +1,414 @@
+/*
+ * Copyright © 2006 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Eric Anholt <eric@anholt.net>
+ *
+ */
+
+#include "dvo.h"
+
+#define CH7017_TV_DISPLAY_MODE		0x00
+#define CH7017_FLICKER_FILTER		0x01
+#define CH7017_VIDEO_BANDWIDTH		0x02
+#define CH7017_TEXT_ENHANCEMENT		0x03
+#define CH7017_START_ACTIVE_VIDEO	0x04
+#define CH7017_HORIZONTAL_POSITION	0x05
+#define CH7017_VERTICAL_POSITION	0x06
+#define CH7017_BLACK_LEVEL		0x07
+#define CH7017_CONTRAST_ENHANCEMENT	0x08
+#define CH7017_TV_PLL			0x09
+#define CH7017_TV_PLL_M			0x0a
+#define CH7017_TV_PLL_N			0x0b
+#define CH7017_SUB_CARRIER_0		0x0c
+#define CH7017_CIV_CONTROL		0x10
+#define CH7017_CIV_0			0x11
+#define CH7017_CHROMA_BOOST		0x14
+#define CH7017_CLOCK_MODE		0x1c
+#define CH7017_INPUT_CLOCK		0x1d
+#define CH7017_GPIO_CONTROL		0x1e
+#define CH7017_INPUT_DATA_FORMAT	0x1f
+#define CH7017_CONNECTION_DETECT	0x20
+#define CH7017_DAC_CONTROL		0x21
+#define CH7017_BUFFERED_CLOCK_OUTPUT	0x22
+#define CH7017_DEFEAT_VSYNC		0x47
+#define CH7017_TEST_PATTERN		0x48
+
+#define CH7017_POWER_MANAGEMENT		0x49
+/** Enables the TV output path. */
+#define CH7017_TV_EN			(1 << 0)
+#define CH7017_DAC0_POWER_DOWN		(1 << 1)
+#define CH7017_DAC1_POWER_DOWN		(1 << 2)
+#define CH7017_DAC2_POWER_DOWN		(1 << 3)
+#define CH7017_DAC3_POWER_DOWN		(1 << 4)
+/** Powers down the TV out block, and DAC0-3 */
+#define CH7017_TV_POWER_DOWN_EN		(1 << 5)
+
+#define CH7017_VERSION_ID		0x4a
+
+#define CH7017_DEVICE_ID		0x4b
+#define CH7017_DEVICE_ID_VALUE		0x1b
+#define CH7018_DEVICE_ID_VALUE		0x1a
+#define CH7019_DEVICE_ID_VALUE		0x19
+
+#define CH7017_XCLK_D2_ADJUST		0x53
+#define CH7017_UP_SCALER_COEFF_0	0x55
+#define CH7017_UP_SCALER_COEFF_1	0x56
+#define CH7017_UP_SCALER_COEFF_2	0x57
+#define CH7017_UP_SCALER_COEFF_3	0x58
+#define CH7017_UP_SCALER_COEFF_4	0x59
+#define CH7017_UP_SCALER_VERTICAL_INC_0	0x5a
+#define CH7017_UP_SCALER_VERTICAL_INC_1	0x5b
+#define CH7017_GPIO_INVERT		0x5c
+#define CH7017_UP_SCALER_HORIZONTAL_INC_0	0x5d
+#define CH7017_UP_SCALER_HORIZONTAL_INC_1	0x5e
+
+#define CH7017_HORIZONTAL_ACTIVE_PIXEL_INPUT	0x5f
+/**< Low bits of horizontal active pixel input */
+
+#define CH7017_ACTIVE_INPUT_LINE_OUTPUT	0x60
+/** High bits of horizontal active pixel input */
+#define CH7017_LVDS_HAP_INPUT_MASK	(0x7 << 0)
+/** High bits of vertical active line output */
+#define CH7017_LVDS_VAL_HIGH_MASK	(0x7 << 3)
+
+#define CH7017_VERTICAL_ACTIVE_LINE_OUTPUT	0x61
+/**< Low bits of vertical active line output */
+
+#define CH7017_HORIZONTAL_ACTIVE_PIXEL_OUTPUT	0x62
+/**< Low bits of horizontal active pixel output */
+
+#define CH7017_LVDS_POWER_DOWN		0x63
+/** High bits of horizontal active pixel output */
+#define CH7017_LVDS_HAP_HIGH_MASK	(0x7 << 0)
+/** Enables the LVDS power down state transition */
+#define CH7017_LVDS_POWER_DOWN_EN	(1 << 6)
+/** Enables the LVDS upscaler */
+#define CH7017_LVDS_UPSCALER_EN		(1 << 7)
+#define CH7017_LVDS_POWER_DOWN_DEFAULT_RESERVED 0x08
+
+#define CH7017_LVDS_ENCODING		0x64
+#define CH7017_LVDS_DITHER_2D		(1 << 2)
+#define CH7017_LVDS_DITHER_DIS		(1 << 3)
+#define CH7017_LVDS_DUAL_CHANNEL_EN	(1 << 4)
+#define CH7017_LVDS_24_BIT		(1 << 5)
+
+#define CH7017_LVDS_ENCODING_2		0x65
+
+#define CH7017_LVDS_PLL_CONTROL		0x66
+/** Enables the LVDS panel output path */
+#define CH7017_LVDS_PANEN		(1 << 0)
+/** Enables the LVDS panel backlight */
+#define CH7017_LVDS_BKLEN		(1 << 3)
+
+#define CH7017_POWER_SEQUENCING_T1	0x67
+#define CH7017_POWER_SEQUENCING_T2	0x68
+#define CH7017_POWER_SEQUENCING_T3	0x69
+#define CH7017_POWER_SEQUENCING_T4	0x6a
+#define CH7017_POWER_SEQUENCING_T5	0x6b
+#define CH7017_GPIO_DRIVER_TYPE		0x6c
+#define CH7017_GPIO_DATA		0x6d
+#define CH7017_GPIO_DIRECTION_CONTROL	0x6e
+
+#define CH7017_LVDS_PLL_FEEDBACK_DIV	0x71
+# define CH7017_LVDS_PLL_FEED_BACK_DIVIDER_SHIFT 4
+# define CH7017_LVDS_PLL_FEED_FORWARD_DIVIDER_SHIFT 0
+# define CH7017_LVDS_PLL_FEEDBACK_DEFAULT_RESERVED 0x80
+
+#define CH7017_LVDS_PLL_VCO_CONTROL	0x72
+# define CH7017_LVDS_PLL_VCO_DEFAULT_RESERVED 0x80
+# define CH7017_LVDS_PLL_VCO_SHIFT	4
+# define CH7017_LVDS_PLL_POST_SCALE_DIV_SHIFT 0
+
+#define CH7017_OUTPUTS_ENABLE		0x73
+# define CH7017_CHARGE_PUMP_LOW		0x0
+# define CH7017_CHARGE_PUMP_HIGH	0x3
+# define CH7017_LVDS_CHANNEL_A		(1 << 3)
+# define CH7017_LVDS_CHANNEL_B		(1 << 4)
+# define CH7017_TV_DAC_A		(1 << 5)
+# define CH7017_TV_DAC_B		(1 << 6)
+# define CH7017_DDC_SELECT_DC2		(1 << 7)
+
+#define CH7017_LVDS_OUTPUT_AMPLITUDE	0x74
+#define CH7017_LVDS_PLL_EMI_REDUCTION	0x75
+#define CH7017_LVDS_POWER_DOWN_FLICKER	0x76
+
+#define CH7017_LVDS_CONTROL_2		0x78
+# define CH7017_LOOP_FILTER_SHIFT	5
+# define CH7017_PHASE_DETECTOR_SHIFT	0
+
+#define CH7017_BANG_LIMIT_CONTROL	0x7f
+
+struct ch7017_priv {
+	uint8_t dummy;
+};
+
+static void ch7017_dump_regs(struct intel_dvo_device *dvo);
+static void ch7017_dpms(struct intel_dvo_device *dvo, bool enable);
+
+static bool ch7017_read(struct intel_dvo_device *dvo, u8 addr, u8 *val)
+{
+	struct i2c_msg msgs[] = {
+		{
+			.addr = dvo->slave_addr,
+			.flags = 0,
+			.len = 1,
+			.buf = &addr,
+		},
+		{
+			.addr = dvo->slave_addr,
+			.flags = I2C_M_RD,
+			.len = 1,
+			.buf = val,
+		}
+	};
+	return i2c_transfer(dvo->i2c_bus, msgs, 2) == 2;
+}
+
+static bool ch7017_write(struct intel_dvo_device *dvo, u8 addr, u8 val)
+{
+	uint8_t buf[2] = { addr, val };
+	struct i2c_msg msg = {
+		.addr = dvo->slave_addr,
+		.flags = 0,
+		.len = 2,
+		.buf = buf,
+	};
+	return i2c_transfer(dvo->i2c_bus, &msg, 1) == 1;
+}
+
+/** Probes for a CH7017 on the given bus and slave address. */
+static bool ch7017_init(struct intel_dvo_device *dvo,
+			struct i2c_adapter *adapter)
+{
+	struct ch7017_priv *priv;
+	const char *str;
+	u8 val;
+
+	priv = kzalloc(sizeof(struct ch7017_priv), GFP_KERNEL);
+	if (priv == NULL)
+		return false;
+
+	dvo->i2c_bus = adapter;
+	dvo->dev_priv = priv;
+
+	if (!ch7017_read(dvo, CH7017_DEVICE_ID, &val))
+		goto fail;
+
+	switch (val) {
+	case CH7017_DEVICE_ID_VALUE:
+		str = "ch7017";
+		break;
+	case CH7018_DEVICE_ID_VALUE:
+		str = "ch7018";
+		break;
+	case CH7019_DEVICE_ID_VALUE:
+		str = "ch7019";
+		break;
+	default:
+		DRM_DEBUG_KMS("ch701x not detected, got %d: from %s "
+			      "slave %d.\n",
+			      val, adapter->name, dvo->slave_addr);
+		goto fail;
+	}
+
+	DRM_DEBUG_KMS("%s detected on %s, addr %d\n",
+		      str, adapter->name, dvo->slave_addr);
+	return true;
+
+fail:
+	kfree(priv);
+	return false;
+}
+
+static enum drm_connector_status ch7017_detect(struct intel_dvo_device *dvo)
+{
+	return connector_status_connected;
+}
+
+static enum drm_mode_status ch7017_mode_valid(struct intel_dvo_device *dvo,
+					      struct drm_display_mode *mode)
+{
+	if (mode->clock > 160000)
+		return MODE_CLOCK_HIGH;
+
+	return MODE_OK;
+}
+
+static void ch7017_mode_set(struct intel_dvo_device *dvo,
+			    const struct drm_display_mode *mode,
+			    const struct drm_display_mode *adjusted_mode)
+{
+	uint8_t lvds_pll_feedback_div, lvds_pll_vco_control;
+	uint8_t outputs_enable, lvds_control_2, lvds_power_down;
+	uint8_t horizontal_active_pixel_input;
+	uint8_t horizontal_active_pixel_output, vertical_active_line_output;
+	uint8_t active_input_line_output;
+
+	DRM_DEBUG_KMS("Registers before mode setting\n");
+	ch7017_dump_regs(dvo);
+
+	/* LVDS PLL settings from page 75 of 7017-7017ds.pdf*/
+	if (mode->clock < 100000) {
+		outputs_enable = CH7017_LVDS_CHANNEL_A | CH7017_CHARGE_PUMP_LOW;
+		lvds_pll_feedback_div = CH7017_LVDS_PLL_FEEDBACK_DEFAULT_RESERVED |
+			(2 << CH7017_LVDS_PLL_FEED_BACK_DIVIDER_SHIFT) |
+			(13 << CH7017_LVDS_PLL_FEED_FORWARD_DIVIDER_SHIFT);
+		lvds_pll_vco_control = CH7017_LVDS_PLL_VCO_DEFAULT_RESERVED |
+			(2 << CH7017_LVDS_PLL_VCO_SHIFT) |
+			(3 << CH7017_LVDS_PLL_POST_SCALE_DIV_SHIFT);
+		lvds_control_2 = (1 << CH7017_LOOP_FILTER_SHIFT) |
+			(0 << CH7017_PHASE_DETECTOR_SHIFT);
+	} else {
+		outputs_enable = CH7017_LVDS_CHANNEL_A | CH7017_CHARGE_PUMP_HIGH;
+		lvds_pll_feedback_div = CH7017_LVDS_PLL_FEEDBACK_DEFAULT_RESERVED |
+			(2 << CH7017_LVDS_PLL_FEED_BACK_DIVIDER_SHIFT) |
+			(3 << CH7017_LVDS_PLL_FEED_FORWARD_DIVIDER_SHIFT);
+		lvds_pll_feedback_div = 35;
+		lvds_control_2 = (3 << CH7017_LOOP_FILTER_SHIFT) |
+			(0 << CH7017_PHASE_DETECTOR_SHIFT);
+		if (1) { /* XXX: dual channel panel detection.  Assume yes for now. */
+			outputs_enable |= CH7017_LVDS_CHANNEL_B;
+			lvds_pll_vco_control = CH7017_LVDS_PLL_VCO_DEFAULT_RESERVED |
+				(2 << CH7017_LVDS_PLL_VCO_SHIFT) |
+				(13 << CH7017_LVDS_PLL_POST_SCALE_DIV_SHIFT);
+		} else {
+			lvds_pll_vco_control = CH7017_LVDS_PLL_VCO_DEFAULT_RESERVED |
+				(1 << CH7017_LVDS_PLL_VCO_SHIFT) |
+				(13 << CH7017_LVDS_PLL_POST_SCALE_DIV_SHIFT);
+		}
+	}
+
+	horizontal_active_pixel_input = mode->hdisplay & 0x00ff;
+
+	vertical_active_line_output = mode->vdisplay & 0x00ff;
+	horizontal_active_pixel_output = mode->hdisplay & 0x00ff;
+
+	active_input_line_output = ((mode->hdisplay & 0x0700) >> 8) |
+				   (((mode->vdisplay & 0x0700) >> 8) << 3);
+
+	lvds_power_down = CH7017_LVDS_POWER_DOWN_DEFAULT_RESERVED |
+			  (mode->hdisplay & 0x0700) >> 8;
+
+	ch7017_dpms(dvo, false);
+	ch7017_write(dvo, CH7017_HORIZONTAL_ACTIVE_PIXEL_INPUT,
+			horizontal_active_pixel_input);
+	ch7017_write(dvo, CH7017_HORIZONTAL_ACTIVE_PIXEL_OUTPUT,
+			horizontal_active_pixel_output);
+	ch7017_write(dvo, CH7017_VERTICAL_ACTIVE_LINE_OUTPUT,
+			vertical_active_line_output);
+	ch7017_write(dvo, CH7017_ACTIVE_INPUT_LINE_OUTPUT,
+			active_input_line_output);
+	ch7017_write(dvo, CH7017_LVDS_PLL_VCO_CONTROL, lvds_pll_vco_control);
+	ch7017_write(dvo, CH7017_LVDS_PLL_FEEDBACK_DIV, lvds_pll_feedback_div);
+	ch7017_write(dvo, CH7017_LVDS_CONTROL_2, lvds_control_2);
+	ch7017_write(dvo, CH7017_OUTPUTS_ENABLE, outputs_enable);
+
+	/* Turn the LVDS back on with new settings. */
+	ch7017_write(dvo, CH7017_LVDS_POWER_DOWN, lvds_power_down);
+
+	DRM_DEBUG_KMS("Registers after mode setting\n");
+	ch7017_dump_regs(dvo);
+}
+
+/* set the CH7017 power state */
+static void ch7017_dpms(struct intel_dvo_device *dvo, bool enable)
+{
+	uint8_t val;
+
+	ch7017_read(dvo, CH7017_LVDS_POWER_DOWN, &val);
+
+	/* Turn off TV/VGA, and never turn it on since we don't support it. */
+	ch7017_write(dvo, CH7017_POWER_MANAGEMENT,
+			CH7017_DAC0_POWER_DOWN |
+			CH7017_DAC1_POWER_DOWN |
+			CH7017_DAC2_POWER_DOWN |
+			CH7017_DAC3_POWER_DOWN |
+			CH7017_TV_POWER_DOWN_EN);
+
+	if (enable) {
+		/* Turn on the LVDS */
+		ch7017_write(dvo, CH7017_LVDS_POWER_DOWN,
+			     val & ~CH7017_LVDS_POWER_DOWN_EN);
+	} else {
+		/* Turn off the LVDS */
+		ch7017_write(dvo, CH7017_LVDS_POWER_DOWN,
+			     val | CH7017_LVDS_POWER_DOWN_EN);
+	}
+
+	/* XXX: Should actually wait for update power status somehow */
+	msleep(20);
+}
+
+static bool ch7017_get_hw_state(struct intel_dvo_device *dvo)
+{
+	uint8_t val;
+
+	ch7017_read(dvo, CH7017_LVDS_POWER_DOWN, &val);
+
+	if (val & CH7017_LVDS_POWER_DOWN_EN)
+		return false;
+	else
+		return true;
+}
+
+static void ch7017_dump_regs(struct intel_dvo_device *dvo)
+{
+	uint8_t val;
+
+#define DUMP(reg)					\
+do {							\
+	ch7017_read(dvo, reg, &val);			\
+	DRM_DEBUG_KMS(#reg ": %02x\n", val);		\
+} while (0)
+
+	DUMP(CH7017_HORIZONTAL_ACTIVE_PIXEL_INPUT);
+	DUMP(CH7017_HORIZONTAL_ACTIVE_PIXEL_OUTPUT);
+	DUMP(CH7017_VERTICAL_ACTIVE_LINE_OUTPUT);
+	DUMP(CH7017_ACTIVE_INPUT_LINE_OUTPUT);
+	DUMP(CH7017_LVDS_PLL_VCO_CONTROL);
+	DUMP(CH7017_LVDS_PLL_FEEDBACK_DIV);
+	DUMP(CH7017_LVDS_CONTROL_2);
+	DUMP(CH7017_OUTPUTS_ENABLE);
+	DUMP(CH7017_LVDS_POWER_DOWN);
+}
+
+static void ch7017_destroy(struct intel_dvo_device *dvo)
+{
+	struct ch7017_priv *priv = dvo->dev_priv;
+
+	if (priv) {
+		kfree(priv);
+		dvo->dev_priv = NULL;
+	}
+}
+
+const struct intel_dvo_dev_ops ch7017_ops = {
+	.init = ch7017_init,
+	.detect = ch7017_detect,
+	.mode_valid = ch7017_mode_valid,
+	.mode_set = ch7017_mode_set,
+	.dpms = ch7017_dpms,
+	.get_hw_state = ch7017_get_hw_state,
+	.dump_regs = ch7017_dump_regs,
+	.destroy = ch7017_destroy,
+};
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/i915/dvo_ch7xxx.c
@@ -0,0 +1,368 @@
+/**************************************************************************
+
+Copyright © 2006 Dave Airlie
+
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sub license, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice (including the
+next paragraph) shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+#include "dvo.h"
+
+#define CH7xxx_REG_VID		0x4a
+#define CH7xxx_REG_DID		0x4b
+
+#define CH7011_VID		0x83 /* 7010 as well */
+#define CH7010B_VID		0x05
+#define CH7009A_VID		0x84
+#define CH7009B_VID		0x85
+#define CH7301_VID		0x95
+
+#define CH7xxx_VID		0x84
+#define CH7xxx_DID		0x17
+#define CH7010_DID		0x16
+
+#define CH7xxx_NUM_REGS		0x4c
+
+#define CH7xxx_CM		0x1c
+#define CH7xxx_CM_XCM		(1<<0)
+#define CH7xxx_CM_MCP		(1<<2)
+#define CH7xxx_INPUT_CLOCK	0x1d
+#define CH7xxx_GPIO		0x1e
+#define CH7xxx_GPIO_HPIR	(1<<3)
+#define CH7xxx_IDF		0x1f
+
+#define CH7xxx_IDF_HSP		(1<<3)
+#define CH7xxx_IDF_VSP		(1<<4)
+
+#define CH7xxx_CONNECTION_DETECT 0x20
+#define CH7xxx_CDET_DVI		(1<<5)
+
+#define CH7301_DAC_CNTL		0x21
+#define CH7301_HOTPLUG		0x23
+#define CH7xxx_TCTL		0x31
+#define CH7xxx_TVCO		0x32
+#define CH7xxx_TPCP		0x33
+#define CH7xxx_TPD		0x34
+#define CH7xxx_TPVT		0x35
+#define CH7xxx_TLPF		0x36
+#define CH7xxx_TCT		0x37
+#define CH7301_TEST_PATTERN	0x48
+
+#define CH7xxx_PM		0x49
+#define CH7xxx_PM_FPD		(1<<0)
+#define CH7301_PM_DACPD0	(1<<1)
+#define CH7301_PM_DACPD1	(1<<2)
+#define CH7301_PM_DACPD2	(1<<3)
+#define CH7xxx_PM_DVIL		(1<<6)
+#define CH7xxx_PM_DVIP		(1<<7)
+
+#define CH7301_SYNC_POLARITY	0x56
+#define CH7301_SYNC_RGB_YUV	(1<<0)
+#define CH7301_SYNC_POL_DVI	(1<<5)
+
+/** @file
+ * driver for the Chrontel 7xxx DVI chip over DVO.
+ */
+
+static struct ch7xxx_id_struct {
+	uint8_t vid;
+	char *name;
+} ch7xxx_ids[] = {
+	{ CH7011_VID, "CH7011" },
+	{ CH7010B_VID, "CH7010B" },
+	{ CH7009A_VID, "CH7009A" },
+	{ CH7009B_VID, "CH7009B" },
+	{ CH7301_VID, "CH7301" },
+};
+
+static struct ch7xxx_did_struct {
+	uint8_t did;
+	char *name;
+} ch7xxx_dids[] = {
+	{ CH7xxx_DID, "CH7XXX" },
+	{ CH7010_DID, "CH7010B" },
+};
+
+struct ch7xxx_priv {
+	bool quiet;
+};
+
+static char *ch7xxx_get_id(uint8_t vid)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(ch7xxx_ids); i++) {
+		if (ch7xxx_ids[i].vid == vid)
+			return ch7xxx_ids[i].name;
+	}
+
+	return NULL;
+}
+
+static char *ch7xxx_get_did(uint8_t did)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(ch7xxx_dids); i++) {
+		if (ch7xxx_dids[i].did == did)
+			return ch7xxx_dids[i].name;
+	}
+
+	return NULL;
+}
+
+/** Reads an 8 bit register */
+static bool ch7xxx_readb(struct intel_dvo_device *dvo, int addr, uint8_t *ch)
+{
+	struct ch7xxx_priv *ch7xxx = dvo->dev_priv;
+	struct i2c_adapter *adapter = dvo->i2c_bus;
+	u8 out_buf[2];
+	u8 in_buf[2];
+
+	struct i2c_msg msgs[] = {
+		{
+			.addr = dvo->slave_addr,
+			.flags = 0,
+			.len = 1,
+			.buf = out_buf,
+		},
+		{
+			.addr = dvo->slave_addr,
+			.flags = I2C_M_RD,
+			.len = 1,
+			.buf = in_buf,
+		}
+	};
+
+	out_buf[0] = addr;
+	out_buf[1] = 0;
+
+	if (i2c_transfer(adapter, msgs, 2) == 2) {
+		*ch = in_buf[0];
+		return true;
+	}
+
+	if (!ch7xxx->quiet) {
+		DRM_DEBUG_KMS("Unable to read register 0x%02x from %s:%02x.\n",
+			  addr, adapter->name, dvo->slave_addr);
+	}
+	return false;
+}
+
+/** Writes an 8 bit register */
+static bool ch7xxx_writeb(struct intel_dvo_device *dvo, int addr, uint8_t ch)
+{
+	struct ch7xxx_priv *ch7xxx = dvo->dev_priv;
+	struct i2c_adapter *adapter = dvo->i2c_bus;
+	uint8_t out_buf[2];
+	struct i2c_msg msg = {
+		.addr = dvo->slave_addr,
+		.flags = 0,
+		.len = 2,
+		.buf = out_buf,
+	};
+
+	out_buf[0] = addr;
+	out_buf[1] = ch;
+
+	if (i2c_transfer(adapter, &msg, 1) == 1)
+		return true;
+
+	if (!ch7xxx->quiet) {
+		DRM_DEBUG_KMS("Unable to write register 0x%02x to %s:%d.\n",
+			  addr, adapter->name, dvo->slave_addr);
+	}
+
+	return false;
+}
+
+static bool ch7xxx_init(struct intel_dvo_device *dvo,
+			struct i2c_adapter *adapter)
+{
+	/* this will detect the CH7xxx chip on the specified i2c bus */
+	struct ch7xxx_priv *ch7xxx;
+	uint8_t vendor, device;
+	char *name, *devid;
+
+	ch7xxx = kzalloc(sizeof(struct ch7xxx_priv), GFP_KERNEL);
+	if (ch7xxx == NULL)
+		return false;
+
+	dvo->i2c_bus = adapter;
+	dvo->dev_priv = ch7xxx;
+	ch7xxx->quiet = true;
+
+	if (!ch7xxx_readb(dvo, CH7xxx_REG_VID, &vendor))
+		goto out;
+
+	name = ch7xxx_get_id(vendor);
+	if (!name) {
+		DRM_DEBUG_KMS("ch7xxx not detected; got 0x%02x from %s "
+				"slave %d.\n",
+			  vendor, adapter->name, dvo->slave_addr);
+		goto out;
+	}
+
+
+	if (!ch7xxx_readb(dvo, CH7xxx_REG_DID, &device))
+		goto out;
+
+	devid = ch7xxx_get_did(device);
+	if (!devid) {
+		DRM_DEBUG_KMS("ch7xxx not detected; got 0x%02x from %s "
+				"slave %d.\n",
+			  vendor, adapter->name, dvo->slave_addr);
+		goto out;
+	}
+
+	ch7xxx->quiet = false;
+	DRM_DEBUG_KMS("Detected %s chipset, vendor/device ID 0x%02x/0x%02x\n",
+		  name, vendor, device);
+	return true;
+out:
+	kfree(ch7xxx);
+	return false;
+}
+
+static enum drm_connector_status ch7xxx_detect(struct intel_dvo_device *dvo)
+{
+	uint8_t cdet, orig_pm, pm;
+
+	ch7xxx_readb(dvo, CH7xxx_PM, &orig_pm);
+
+	pm = orig_pm;
+	pm &= ~CH7xxx_PM_FPD;
+	pm |= CH7xxx_PM_DVIL | CH7xxx_PM_DVIP;
+
+	ch7xxx_writeb(dvo, CH7xxx_PM, pm);
+
+	ch7xxx_readb(dvo, CH7xxx_CONNECTION_DETECT, &cdet);
+
+	ch7xxx_writeb(dvo, CH7xxx_PM, orig_pm);
+
+	if (cdet & CH7xxx_CDET_DVI)
+		return connector_status_connected;
+	return connector_status_disconnected;
+}
+
+static enum drm_mode_status ch7xxx_mode_valid(struct intel_dvo_device *dvo,
+					      struct drm_display_mode *mode)
+{
+	if (mode->clock > 165000)
+		return MODE_CLOCK_HIGH;
+
+	return MODE_OK;
+}
+
+static void ch7xxx_mode_set(struct intel_dvo_device *dvo,
+			    const struct drm_display_mode *mode,
+			    const struct drm_display_mode *adjusted_mode)
+{
+	uint8_t tvco, tpcp, tpd, tlpf, idf;
+
+	if (mode->clock <= 65000) {
+		tvco = 0x23;
+		tpcp = 0x08;
+		tpd = 0x16;
+		tlpf = 0x60;
+	} else {
+		tvco = 0x2d;
+		tpcp = 0x06;
+		tpd = 0x26;
+		tlpf = 0xa0;
+	}
+
+	ch7xxx_writeb(dvo, CH7xxx_TCTL, 0x00);
+	ch7xxx_writeb(dvo, CH7xxx_TVCO, tvco);
+	ch7xxx_writeb(dvo, CH7xxx_TPCP, tpcp);
+	ch7xxx_writeb(dvo, CH7xxx_TPD, tpd);
+	ch7xxx_writeb(dvo, CH7xxx_TPVT, 0x30);
+	ch7xxx_writeb(dvo, CH7xxx_TLPF, tlpf);
+	ch7xxx_writeb(dvo, CH7xxx_TCT, 0x00);
+
+	ch7xxx_readb(dvo, CH7xxx_IDF, &idf);
+
+	idf &= ~(CH7xxx_IDF_HSP | CH7xxx_IDF_VSP);
+	if (mode->flags & DRM_MODE_FLAG_PHSYNC)
+		idf |= CH7xxx_IDF_HSP;
+
+	if (mode->flags & DRM_MODE_FLAG_PVSYNC)
+		idf |= CH7xxx_IDF_VSP;
+
+	ch7xxx_writeb(dvo, CH7xxx_IDF, idf);
+}
+
+/* set the CH7xxx power state */
+static void ch7xxx_dpms(struct intel_dvo_device *dvo, bool enable)
+{
+	if (enable)
+		ch7xxx_writeb(dvo, CH7xxx_PM, CH7xxx_PM_DVIL | CH7xxx_PM_DVIP);
+	else
+		ch7xxx_writeb(dvo, CH7xxx_PM, CH7xxx_PM_FPD);
+}
+
+static bool ch7xxx_get_hw_state(struct intel_dvo_device *dvo)
+{
+	u8 val;
+
+	ch7xxx_readb(dvo, CH7xxx_PM, &val);
+
+	if (val & (CH7xxx_PM_DVIL | CH7xxx_PM_DVIP))
+		return true;
+	else
+		return false;
+}
+
+static void ch7xxx_dump_regs(struct intel_dvo_device *dvo)
+{
+	int i;
+
+	for (i = 0; i < CH7xxx_NUM_REGS; i++) {
+		uint8_t val;
+		if ((i % 8) == 0)
+			DRM_DEBUG_KMS("\n %02X: ", i);
+		ch7xxx_readb(dvo, i, &val);
+		DRM_DEBUG_KMS("%02X ", val);
+	}
+}
+
+static void ch7xxx_destroy(struct intel_dvo_device *dvo)
+{
+	struct ch7xxx_priv *ch7xxx = dvo->dev_priv;
+
+	if (ch7xxx) {
+		kfree(ch7xxx);
+		dvo->dev_priv = NULL;
+	}
+}
+
+const struct intel_dvo_dev_ops ch7xxx_ops = {
+	.init = ch7xxx_init,
+	.detect = ch7xxx_detect,
+	.mode_valid = ch7xxx_mode_valid,
+	.mode_set = ch7xxx_mode_set,
+	.dpms = ch7xxx_dpms,
+	.get_hw_state = ch7xxx_get_hw_state,
+	.dump_regs = ch7xxx_dump_regs,
+	.destroy = ch7xxx_destroy,
+};
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/i915/dvo_ivch.c
@@ -0,0 +1,502 @@
+/*
+ * Copyright © 2006 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Eric Anholt <eric@anholt.net>
+ *    Thomas Richter <thor@math.tu-berlin.de>
+ *
+ * Minor modifications (Dithering enable):
+ *    Thomas Richter <thor@math.tu-berlin.de>
+ *
+ */
+
+#include "dvo.h"
+
+/*
+ * register definitions for the i82807aa.
+ *
+ * Documentation on this chipset can be found in datasheet #29069001 at
+ * intel.com.
+ */
+
+/*
+ * VCH Revision & GMBus Base Addr
+ */
+#define VR00		0x00
+# define VR00_BASE_ADDRESS_MASK		0x007f
+
+/*
+ * Functionality Enable
+ */
+#define VR01		0x01
+
+/*
+ * Enable the panel fitter
+ */
+# define VR01_PANEL_FIT_ENABLE		(1 << 3)
+/*
+ * Enables the LCD display.
+ *
+ * This must not be set while VR01_DVO_BYPASS_ENABLE is set.
+ */
+# define VR01_LCD_ENABLE		(1 << 2)
+/** Enables the DVO repeater. */
+# define VR01_DVO_BYPASS_ENABLE		(1 << 1)
+/** Enables the DVO clock */
+# define VR01_DVO_ENABLE		(1 << 0)
+/** Enable dithering for 18bpp panels. Not documented. */
+# define VR01_DITHER_ENABLE             (1 << 4)
+
+/*
+ * LCD Interface Format
+ */
+#define VR10		0x10
+/** Enables LVDS output instead of CMOS */
+# define VR10_LVDS_ENABLE		(1 << 4)
+/** Enables 18-bit LVDS output. */
+# define VR10_INTERFACE_1X18		(0 << 2)
+/** Enables 24-bit LVDS or CMOS output */
+# define VR10_INTERFACE_1X24		(1 << 2)
+/** Enables 2x18-bit LVDS or CMOS output. */
+# define VR10_INTERFACE_2X18		(2 << 2)
+/** Enables 2x24-bit LVDS output */
+# define VR10_INTERFACE_2X24		(3 << 2)
+/** Mask that defines the depth of the pipeline */
+# define VR10_INTERFACE_DEPTH_MASK      (3 << 2)
+
+/*
+ * VR20 LCD Horizontal Display Size
+ */
+#define VR20	0x20
+
+/*
+ * LCD Vertical Display Size
+ */
+#define VR21	0x21
+
+/*
+ * Panel power down status
+ */
+#define VR30		0x30
+/** Read only bit indicating that the panel is not in a safe poweroff state. */
+# define VR30_PANEL_ON			(1 << 15)
+
+#define VR40		0x40
+# define VR40_STALL_ENABLE		(1 << 13)
+# define VR40_VERTICAL_INTERP_ENABLE	(1 << 12)
+# define VR40_ENHANCED_PANEL_FITTING	(1 << 11)
+# define VR40_HORIZONTAL_INTERP_ENABLE	(1 << 10)
+# define VR40_AUTO_RATIO_ENABLE		(1 << 9)
+# define VR40_CLOCK_GATING_ENABLE	(1 << 8)
+
+/*
+ * Panel Fitting Vertical Ratio
+ * (((image_height - 1) << 16) / ((panel_height - 1))) >> 2
+ */
+#define VR41		0x41
+
+/*
+ * Panel Fitting Horizontal Ratio
+ * (((image_width - 1) << 16) / ((panel_width - 1))) >> 2
+ */
+#define VR42		0x42
+
+/*
+ * Horizontal Image Size
+ */
+#define VR43		0x43
+
+/* VR80 GPIO 0
+ */
+#define VR80	    0x80
+#define VR81	    0x81
+#define VR82	    0x82
+#define VR83	    0x83
+#define VR84	    0x84
+#define VR85	    0x85
+#define VR86	    0x86
+#define VR87	    0x87
+
+/* VR88 GPIO 8
+ */
+#define VR88	    0x88
+
+/* Graphics BIOS scratch 0
+ */
+#define VR8E	    0x8E
+# define VR8E_PANEL_TYPE_MASK		(0xf << 0)
+# define VR8E_PANEL_INTERFACE_CMOS	(0 << 4)
+# define VR8E_PANEL_INTERFACE_LVDS	(1 << 4)
+# define VR8E_FORCE_DEFAULT_PANEL	(1 << 5)
+
+/* Graphics BIOS scratch 1
+ */
+#define VR8F	    0x8F
+# define VR8F_VCH_PRESENT		(1 << 0)
+# define VR8F_DISPLAY_CONN		(1 << 1)
+# define VR8F_POWER_MASK		(0x3c)
+# define VR8F_POWER_POS			(2)
+
+/* Some Bios implementations do not restore the DVO state upon
+ * resume from standby. Thus, this driver has to handle it
+ * instead. The following list contains all registers that
+ * require saving.
+ */
+static const uint16_t backup_addresses[] = {
+	0x11, 0x12,
+	0x18, 0x19, 0x1a, 0x1f,
+	0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
+	0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+	0x8e, 0x8f,
+	0x10		/* this must come last */
+};
+
+
+struct ivch_priv {
+	bool quiet;
+
+	uint16_t width, height;
+
+	/* Register backup */
+
+	uint16_t reg_backup[ARRAY_SIZE(backup_addresses)];
+};
+
+
+static void ivch_dump_regs(struct intel_dvo_device *dvo);
+/**
+ * Reads a register on the ivch.
+ *
+ * Each of the 256 registers are 16 bits long.
+ */
+static bool ivch_read(struct intel_dvo_device *dvo, int addr, uint16_t *data)
+{
+	struct ivch_priv *priv = dvo->dev_priv;
+	struct i2c_adapter *adapter = dvo->i2c_bus;
+	u8 out_buf[1];
+	u8 in_buf[2];
+
+	struct i2c_msg msgs[] = {
+		{
+			.addr = dvo->slave_addr,
+			.flags = I2C_M_RD,
+			.len = 0,
+		},
+		{
+			.addr = 0,
+			.flags = I2C_M_NOSTART,
+			.len = 1,
+			.buf = out_buf,
+		},
+		{
+			.addr = dvo->slave_addr,
+			.flags = I2C_M_RD | I2C_M_NOSTART,
+			.len = 2,
+			.buf = in_buf,
+		}
+	};
+
+	out_buf[0] = addr;
+
+	if (i2c_transfer(adapter, msgs, 3) == 3) {
+		*data = (in_buf[1] << 8) | in_buf[0];
+		return true;
+	}
+
+	if (!priv->quiet) {
+		DRM_DEBUG_KMS("Unable to read register 0x%02x from "
+				"%s:%02x.\n",
+			  addr, adapter->name, dvo->slave_addr);
+	}
+	return false;
+}
+
+/** Writes a 16-bit register on the ivch */
+static bool ivch_write(struct intel_dvo_device *dvo, int addr, uint16_t data)
+{
+	struct ivch_priv *priv = dvo->dev_priv;
+	struct i2c_adapter *adapter = dvo->i2c_bus;
+	u8 out_buf[3];
+	struct i2c_msg msg = {
+		.addr = dvo->slave_addr,
+		.flags = 0,
+		.len = 3,
+		.buf = out_buf,
+	};
+
+	out_buf[0] = addr;
+	out_buf[1] = data & 0xff;
+	out_buf[2] = data >> 8;
+
+	if (i2c_transfer(adapter, &msg, 1) == 1)
+		return true;
+
+	if (!priv->quiet) {
+		DRM_DEBUG_KMS("Unable to write register 0x%02x to %s:%d.\n",
+			  addr, adapter->name, dvo->slave_addr);
+	}
+
+	return false;
+}
+
+/** Probes the given bus and slave address for an ivch */
+static bool ivch_init(struct intel_dvo_device *dvo,
+		      struct i2c_adapter *adapter)
+{
+	struct ivch_priv *priv;
+	uint16_t temp;
+	int i;
+
+	priv = kzalloc(sizeof(struct ivch_priv), GFP_KERNEL);
+	if (priv == NULL)
+		return false;
+
+	dvo->i2c_bus = adapter;
+	dvo->dev_priv = priv;
+	priv->quiet = true;
+
+	if (!ivch_read(dvo, VR00, &temp))
+		goto out;
+	priv->quiet = false;
+
+	/* Since the identification bits are probably zeroes, which doesn't seem
+	 * very unique, check that the value in the base address field matches
+	 * the address it's responding on.
+	 */
+	if ((temp & VR00_BASE_ADDRESS_MASK) != dvo->slave_addr) {
+		DRM_DEBUG_KMS("ivch detect failed due to address mismatch "
+			  "(%d vs %d)\n",
+			  (temp & VR00_BASE_ADDRESS_MASK), dvo->slave_addr);
+		goto out;
+	}
+
+	ivch_read(dvo, VR20, &priv->width);
+	ivch_read(dvo, VR21, &priv->height);
+
+	/* Make a backup of the registers to be able to restore them
+	 * upon suspend.
+	 */
+	for (i = 0; i < ARRAY_SIZE(backup_addresses); i++)
+		ivch_read(dvo, backup_addresses[i], priv->reg_backup + i);
+
+	ivch_dump_regs(dvo);
+
+	return true;
+
+out:
+	kfree(priv);
+	return false;
+}
+
+static enum drm_connector_status ivch_detect(struct intel_dvo_device *dvo)
+{
+	return connector_status_connected;
+}
+
+static enum drm_mode_status ivch_mode_valid(struct intel_dvo_device *dvo,
+					    struct drm_display_mode *mode)
+{
+	if (mode->clock > 112000)
+		return MODE_CLOCK_HIGH;
+
+	return MODE_OK;
+}
+
+/* Restore the DVO registers after a resume
+ * from RAM. Registers have been saved during
+ * the initialization.
+ */
+static void ivch_reset(struct intel_dvo_device *dvo)
+{
+	struct ivch_priv *priv = dvo->dev_priv;
+	int i;
+
+	DRM_DEBUG_KMS("Resetting the IVCH registers\n");
+
+	ivch_write(dvo, VR10, 0x0000);
+
+	for (i = 0; i < ARRAY_SIZE(backup_addresses); i++)
+		ivch_write(dvo, backup_addresses[i], priv->reg_backup[i]);
+}
+
+/** Sets the power state of the panel connected to the ivch */
+static void ivch_dpms(struct intel_dvo_device *dvo, bool enable)
+{
+	int i;
+	uint16_t vr01, vr30, backlight;
+
+	ivch_reset(dvo);
+
+	/* Set the new power state of the panel. */
+	if (!ivch_read(dvo, VR01, &vr01))
+		return;
+
+	if (enable)
+		backlight = 1;
+	else
+		backlight = 0;
+
+	ivch_write(dvo, VR80, backlight);
+
+	if (enable)
+		vr01 |= VR01_LCD_ENABLE | VR01_DVO_ENABLE;
+	else
+		vr01 &= ~(VR01_LCD_ENABLE | VR01_DVO_ENABLE);
+
+	ivch_write(dvo, VR01, vr01);
+
+	/* Wait for the panel to make its state transition */
+	for (i = 0; i < 100; i++) {
+		if (!ivch_read(dvo, VR30, &vr30))
+			break;
+
+		if (((vr30 & VR30_PANEL_ON) != 0) == enable)
+			break;
+		udelay(1000);
+	}
+	/* wait some more; vch may fail to resync sometimes without this */
+	udelay(16 * 1000);
+}
+
+static bool ivch_get_hw_state(struct intel_dvo_device *dvo)
+{
+	uint16_t vr01;
+
+	ivch_reset(dvo);
+
+	/* Set the new power state of the panel. */
+	if (!ivch_read(dvo, VR01, &vr01))
+		return false;
+
+	if (vr01 & VR01_LCD_ENABLE)
+		return true;
+	else
+		return false;
+}
+
+static void ivch_mode_set(struct intel_dvo_device *dvo,
+			  const struct drm_display_mode *mode,
+			  const struct drm_display_mode *adjusted_mode)
+{
+	struct ivch_priv *priv = dvo->dev_priv;
+	uint16_t vr40 = 0;
+	uint16_t vr01 = 0;
+	uint16_t vr10;
+
+	ivch_reset(dvo);
+
+	vr10 = priv->reg_backup[ARRAY_SIZE(backup_addresses) - 1];
+
+	/* Enable dithering for 18 bpp pipelines */
+	vr10 &= VR10_INTERFACE_DEPTH_MASK;
+	if (vr10 == VR10_INTERFACE_2X18 || vr10 == VR10_INTERFACE_1X18)
+		vr01 = VR01_DITHER_ENABLE;
+
+	vr40 = (VR40_STALL_ENABLE | VR40_VERTICAL_INTERP_ENABLE |
+		VR40_HORIZONTAL_INTERP_ENABLE);
+
+	if (mode->hdisplay != adjusted_mode->crtc_hdisplay ||
+	    mode->vdisplay != adjusted_mode->crtc_vdisplay) {
+		uint16_t x_ratio, y_ratio;
+
+		vr01 |= VR01_PANEL_FIT_ENABLE;
+		vr40 |= VR40_CLOCK_GATING_ENABLE;
+		x_ratio = (((mode->hdisplay - 1) << 16) /
+			   (adjusted_mode->crtc_hdisplay - 1)) >> 2;
+		y_ratio = (((mode->vdisplay - 1) << 16) /
+			   (adjusted_mode->crtc_vdisplay - 1)) >> 2;
+		ivch_write(dvo, VR42, x_ratio);
+		ivch_write(dvo, VR41, y_ratio);
+	} else {
+		vr01 &= ~VR01_PANEL_FIT_ENABLE;
+		vr40 &= ~VR40_CLOCK_GATING_ENABLE;
+	}
+	vr40 &= ~VR40_AUTO_RATIO_ENABLE;
+
+	ivch_write(dvo, VR01, vr01);
+	ivch_write(dvo, VR40, vr40);
+}
+
+static void ivch_dump_regs(struct intel_dvo_device *dvo)
+{
+	uint16_t val;
+
+	ivch_read(dvo, VR00, &val);
+	DRM_DEBUG_KMS("VR00: 0x%04x\n", val);
+	ivch_read(dvo, VR01, &val);
+	DRM_DEBUG_KMS("VR01: 0x%04x\n", val);
+	ivch_read(dvo, VR10, &val);
+	DRM_DEBUG_KMS("VR10: 0x%04x\n", val);
+	ivch_read(dvo, VR30, &val);
+	DRM_DEBUG_KMS("VR30: 0x%04x\n", val);
+	ivch_read(dvo, VR40, &val);
+	DRM_DEBUG_KMS("VR40: 0x%04x\n", val);
+
+	/* GPIO registers */
+	ivch_read(dvo, VR80, &val);
+	DRM_DEBUG_KMS("VR80: 0x%04x\n", val);
+	ivch_read(dvo, VR81, &val);
+	DRM_DEBUG_KMS("VR81: 0x%04x\n", val);
+	ivch_read(dvo, VR82, &val);
+	DRM_DEBUG_KMS("VR82: 0x%04x\n", val);
+	ivch_read(dvo, VR83, &val);
+	DRM_DEBUG_KMS("VR83: 0x%04x\n", val);
+	ivch_read(dvo, VR84, &val);
+	DRM_DEBUG_KMS("VR84: 0x%04x\n", val);
+	ivch_read(dvo, VR85, &val);
+	DRM_DEBUG_KMS("VR85: 0x%04x\n", val);
+	ivch_read(dvo, VR86, &val);
+	DRM_DEBUG_KMS("VR86: 0x%04x\n", val);
+	ivch_read(dvo, VR87, &val);
+	DRM_DEBUG_KMS("VR87: 0x%04x\n", val);
+	ivch_read(dvo, VR88, &val);
+	DRM_DEBUG_KMS("VR88: 0x%04x\n", val);
+
+	/* Scratch register 0 - AIM Panel type */
+	ivch_read(dvo, VR8E, &val);
+	DRM_DEBUG_KMS("VR8E: 0x%04x\n", val);
+
+	/* Scratch register 1 - Status register */
+	ivch_read(dvo, VR8F, &val);
+	DRM_DEBUG_KMS("VR8F: 0x%04x\n", val);
+}
+
+static void ivch_destroy(struct intel_dvo_device *dvo)
+{
+	struct ivch_priv *priv = dvo->dev_priv;
+
+	if (priv) {
+		kfree(priv);
+		dvo->dev_priv = NULL;
+	}
+}
+
+const struct intel_dvo_dev_ops ivch_ops = {
+	.init = ivch_init,
+	.dpms = ivch_dpms,
+	.get_hw_state = ivch_get_hw_state,
+	.mode_valid = ivch_mode_valid,
+	.mode_set = ivch_mode_set,
+	.detect = ivch_detect,
+	.dump_regs = ivch_dump_regs,
+	.destroy = ivch_destroy,
+};
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/i915/dvo_ns2501.c
@@ -0,0 +1,709 @@
+/*
+ *
+ * Copyright (c) 2012 Gilles Dartiguelongue, Thomas Richter
+ *
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#include "dvo.h"
+#include "i915_reg.h"
+#include "i915_drv.h"
+
+#define NS2501_VID 0x1305
+#define NS2501_DID 0x6726
+
+#define NS2501_VID_LO 0x00
+#define NS2501_VID_HI 0x01
+#define NS2501_DID_LO 0x02
+#define NS2501_DID_HI 0x03
+#define NS2501_REV 0x04
+#define NS2501_RSVD 0x05
+#define NS2501_FREQ_LO 0x06
+#define NS2501_FREQ_HI 0x07
+
+#define NS2501_REG8 0x08
+#define NS2501_8_VEN (1<<5)
+#define NS2501_8_HEN (1<<4)
+#define NS2501_8_DSEL (1<<3)
+#define NS2501_8_BPAS (1<<2)
+#define NS2501_8_RSVD (1<<1)
+#define NS2501_8_PD (1<<0)
+
+#define NS2501_REG9 0x09
+#define NS2501_9_VLOW (1<<7)
+#define NS2501_9_MSEL_MASK (0x7<<4)
+#define NS2501_9_TSEL (1<<3)
+#define NS2501_9_RSEN (1<<2)
+#define NS2501_9_RSVD (1<<1)
+#define NS2501_9_MDI (1<<0)
+
+#define NS2501_REGC 0x0c
+
+/*
+ * The following registers are not part of the official datasheet
+ * and are the result of reverse engineering.
+ */
+
+/*
+ * Register c0 controls how the DVO synchronizes with
+ * its input.
+ */
+#define NS2501_REGC0 0xc0
+#define NS2501_C0_ENABLE (1<<0)	/* enable the DVO sync in general */
+#define NS2501_C0_HSYNC (1<<1)	/* synchronize horizontal with input */
+#define NS2501_C0_VSYNC (1<<2)	/* synchronize vertical with input */
+#define NS2501_C0_RESET (1<<7)	/* reset the synchronization flip/flops */
+
+/*
+ * Register 41 is somehow related to the sync register and sync
+ * configuration. It should be 0x32 whenever regC0 is 0x05 (hsync off)
+ * and 0x00 otherwise.
+ */
+#define NS2501_REG41 0x41
+
+/*
+ * this register controls the dithering of the DVO
+ * One bit enables it, the other define the dithering depth.
+ * The higher the value, the lower the dithering depth.
+ */
+#define NS2501_F9_REG 0xf9
+#define NS2501_F9_ENABLE (1<<0)		/* if set, dithering is enabled */
+#define NS2501_F9_DITHER_MASK (0x7f<<1)	/* controls the dither depth */
+#define NS2501_F9_DITHER_SHIFT 1	/* shifts the dither mask */
+
+/*
+ * PLL configuration register. This is a pair of registers,
+ * one single byte register at 1B, and a pair at 1C,1D.
+ * These registers are counters/dividers.
+ */
+#define NS2501_REG1B 0x1b /* one byte PLL control register */
+#define NS2501_REG1C 0x1c /* low-part of the second register */
+#define NS2501_REG1D 0x1d /* high-part of the second register */
+
+/*
+ * Scaler control registers. Horizontal at b8,b9,
+ * vertical at 10,11. The scale factor is computed as
+ * 2^16/control-value. The low-byte comes first.
+ */
+#define NS2501_REG10 0x10 /* low-byte vertical scaler */
+#define NS2501_REG11 0x11 /* high-byte vertical scaler */
+#define NS2501_REGB8 0xb8 /* low-byte horizontal scaler */
+#define NS2501_REGB9 0xb9 /* high-byte horizontal scaler */
+
+/*
+ * Display window definition. This consists of four registers
+ * per dimension. One register pair defines the start of the
+ * display, one the end.
+ * As far as I understand, this defines the window within which
+ * the scaler samples the input.
+ */
+#define NS2501_REGC1 0xc1 /* low-byte horizontal display start */
+#define NS2501_REGC2 0xc2 /* high-byte horizontal display start */
+#define NS2501_REGC3 0xc3 /* low-byte horizontal display stop */
+#define NS2501_REGC4 0xc4 /* high-byte horizontal display stop */
+#define NS2501_REGC5 0xc5 /* low-byte vertical display start */
+#define NS2501_REGC6 0xc6 /* high-byte vertical display start */
+#define NS2501_REGC7 0xc7 /* low-byte vertical display stop */
+#define NS2501_REGC8 0xc8 /* high-byte vertical display stop */
+
+/*
+ * The following register pair seems to define the start of
+ * the vertical sync. If automatic syncing is enabled, and the
+ * register value defines a sync pulse that is later than the
+ * incoming sync, then the register value is ignored and the
+ * external hsync triggers the synchronization.
+ */
+#define NS2501_REG80 0x80 /* low-byte vsync-start */
+#define NS2501_REG81 0x81 /* high-byte vsync-start */
+
+/*
+ * The following register pair seems to define the total number
+ * of lines created at the output side of the scaler.
+ * This is again a low-high register pair.
+ */
+#define NS2501_REG82 0x82 /* output display height, low byte */
+#define NS2501_REG83 0x83 /* output display height, high byte */
+
+/*
+ * The following registers define the end of the front-porch
+ * in horizontal and vertical position and hence allow to shift
+ * the image left/right or up/down.
+ */
+#define NS2501_REG98 0x98 /* horizontal start of display + 256, low */
+#define NS2501_REG99 0x99 /* horizontal start of display + 256, high */
+#define NS2501_REG8E 0x8e /* vertical start of the display, low byte */
+#define NS2501_REG8F 0x8f /* vertical start of the display, high byte */
+
+/*
+ * The following register pair control the function of the
+ * backlight and the DVO output. To enable the corresponding
+ * function, the corresponding bit must be set in both registers.
+ */
+#define NS2501_REG34 0x34 /* DVO enable functions, first register */
+#define NS2501_REG35 0x35 /* DVO enable functions, second register */
+#define NS2501_34_ENABLE_OUTPUT (1<<0) /* enable DVO output */
+#define NS2501_34_ENABLE_BACKLIGHT (1<<1) /* enable backlight */
+
+/*
+ * Registers 9C and 9D define the vertical output offset
+ * of the visible region.
+ */
+#define NS2501_REG9C 0x9c
+#define NS2501_REG9D 0x9d
+
+/*
+ * The register 9F defines the dithering. This requires the
+ * scaler to be ON. Bit 0 enables dithering, the remaining
+ * bits control the depth of the dither. The higher the value,
+ * the LOWER the dithering amplitude. A good value seems to be
+ * 15 (total register value).
+ */
+#define NS2501_REGF9 0xf9
+#define NS2501_F9_ENABLE_DITHER (1<<0) /* enable dithering */
+#define NS2501_F9_DITHER_MASK (0x7f<<1) /* dither masking */
+#define NS2501_F9_DITHER_SHIFT 1	/* upshift of the dither mask */
+
+enum {
+	MODE_640x480,
+	MODE_800x600,
+	MODE_1024x768,
+};
+
+struct ns2501_reg {
+	 uint8_t offset;
+	 uint8_t value;
+};
+
+/*
+ * The following structure keeps the complete configuration of
+ * the DVO, given a specific output configuration.
+ * This is pretty much guess-work from reverse-engineering, so
+ * read all this with a grain of salt.
+ */
+struct ns2501_configuration {
+	uint8_t sync;		/* configuration of the C0 register */
+	uint8_t conf;		/* configuration register 8 */
+	uint8_t syncb;		/* configuration register 41 */
+	uint8_t	dither;		/* configuration of the dithering */
+	uint8_t pll_a;		/* PLL configuration, register A, 1B */
+	uint16_t pll_b;		/* PLL configuration, register B, 1C/1D */
+	uint16_t hstart;	/* horizontal start, registers C1/C2 */
+	uint16_t hstop;		/* horizontal total, registers C3/C4 */
+	uint16_t vstart;	/* vertical start, registers C5/C6 */
+	uint16_t vstop;		/* vertical total, registers C7/C8 */
+	uint16_t vsync;         /* manual vertical sync start, 80/81 */
+	uint16_t vtotal;        /* number of lines generated, 82/83 */
+	uint16_t hpos;		/* horizontal position + 256, 98/99  */
+	uint16_t vpos;		/* vertical position, 8e/8f */
+	uint16_t voffs;		/* vertical output offset, 9c/9d */
+	uint16_t hscale;	/* horizontal scaling factor, b8/b9 */
+	uint16_t vscale;	/* vertical scaling factor, 10/11 */
+};
+
+/*
+ * DVO configuration values, partially based on what the BIOS
+ * of the Fujitsu Lifebook S6010 writes into registers,
+ * partially found by manual tweaking. These configurations assume
+ * a 1024x768 panel.
+ */
+static const struct ns2501_configuration ns2501_modes[] = {
+	[MODE_640x480] = {
+		.sync	= NS2501_C0_ENABLE | NS2501_C0_VSYNC,
+		.conf	= NS2501_8_VEN | NS2501_8_HEN | NS2501_8_PD,
+		.syncb	= 0x32,
+		.dither	= 0x0f,
+		.pll_a	= 17,
+		.pll_b	= 852,
+		.hstart	= 144,
+		.hstop	= 783,
+		.vstart	= 22,
+		.vstop	= 514,
+		.vsync	= 2047, /* actually, ignored with this config */
+		.vtotal	= 1341,
+		.hpos	= 0,
+		.vpos	= 16,
+		.voffs	= 36,
+		.hscale	= 40960,
+		.vscale	= 40960
+	},
+	[MODE_800x600] = {
+		.sync	= NS2501_C0_ENABLE |
+			  NS2501_C0_HSYNC | NS2501_C0_VSYNC,
+		.conf   = NS2501_8_VEN | NS2501_8_HEN | NS2501_8_PD,
+		.syncb	= 0x00,
+		.dither	= 0x0f,
+		.pll_a	= 25,
+		.pll_b	= 612,
+		.hstart	= 215,
+		.hstop	= 1016,
+		.vstart	= 26,
+		.vstop	= 627,
+		.vsync	= 807,
+		.vtotal	= 1341,
+		.hpos	= 0,
+		.vpos	= 4,
+		.voffs	= 35,
+		.hscale	= 51248,
+		.vscale	= 51232
+	},
+	[MODE_1024x768] = {
+		.sync	= NS2501_C0_ENABLE | NS2501_C0_VSYNC,
+		.conf   = NS2501_8_VEN | NS2501_8_HEN | NS2501_8_PD,
+		.syncb	= 0x32,
+		.dither	= 0x0f,
+		.pll_a	= 11,
+		.pll_b	= 1350,
+		.hstart	= 276,
+		.hstop	= 1299,
+		.vstart	= 15,
+		.vstop	= 1056,
+		.vsync	= 2047,
+		.vtotal	= 1341,
+		.hpos	= 0,
+		.vpos	= 7,
+		.voffs	= 27,
+		.hscale	= 65535,
+		.vscale	= 65535
+	}
+};
+
+/*
+ * Other configuration values left by the BIOS of the
+ * Fujitsu S6010 in the DVO control registers. Their
+ * value does not depend on the BIOS and their meaning
+ * is unknown.
+ */
+
+static const struct ns2501_reg mode_agnostic_values[] = {
+	/* 08 is mode specific */
+	[0] = { .offset = 0x0a, .value = 0x81, },
+	/* 10,11 are part of the mode specific configuration */
+	[1] = { .offset = 0x12, .value = 0x02, },
+	[2] = { .offset = 0x18, .value = 0x07, },
+	[3] = { .offset = 0x19, .value = 0x00, },
+	[4] = { .offset = 0x1a, .value = 0x00, }, /* PLL?, ignored */
+	/* 1b,1c,1d are part of the mode specific configuration */
+	[5] = { .offset = 0x1e, .value = 0x02, },
+	[6] = { .offset = 0x1f, .value = 0x40, },
+	[7] = { .offset = 0x20, .value = 0x00, },
+	[8] = { .offset = 0x21, .value = 0x00, },
+	[9] = { .offset = 0x22, .value = 0x00, },
+	[10] = { .offset = 0x23, .value = 0x00, },
+	[11] = { .offset = 0x24, .value = 0x00, },
+	[12] = { .offset = 0x25, .value = 0x00, },
+	[13] = { .offset = 0x26, .value = 0x00, },
+	[14] = { .offset = 0x27, .value = 0x00, },
+	[15] = { .offset = 0x7e, .value = 0x18, },
+	/* 80-84 are part of the mode-specific configuration */
+	[16] = { .offset = 0x84, .value = 0x00, },
+	[17] = { .offset = 0x85, .value = 0x00, },
+	[18] = { .offset = 0x86, .value = 0x00, },
+	[19] = { .offset = 0x87, .value = 0x00, },
+	[20] = { .offset = 0x88, .value = 0x00, },
+	[21] = { .offset = 0x89, .value = 0x00, },
+	[22] = { .offset = 0x8a, .value = 0x00, },
+	[23] = { .offset = 0x8b, .value = 0x00, },
+	[24] = { .offset = 0x8c, .value = 0x10, },
+	[25] = { .offset = 0x8d, .value = 0x02, },
+	/* 8e,8f are part of the mode-specific configuration */
+	[26] = { .offset = 0x90, .value = 0xff, },
+	[27] = { .offset = 0x91, .value = 0x07, },
+	[28] = { .offset = 0x92, .value = 0xa0, },
+	[29] = { .offset = 0x93, .value = 0x02, },
+	[30] = { .offset = 0x94, .value = 0x00, },
+	[31] = { .offset = 0x95, .value = 0x00, },
+	[32] = { .offset = 0x96, .value = 0x05, },
+	[33] = { .offset = 0x97, .value = 0x00, },
+	/* 98,99 are part of the mode-specific configuration */
+	[34] = { .offset = 0x9a, .value = 0x88, },
+	[35] = { .offset = 0x9b, .value = 0x00, },
+	/* 9c,9d are part of the mode-specific configuration */
+	[36] = { .offset = 0x9e, .value = 0x25, },
+	[37] = { .offset = 0x9f, .value = 0x03, },
+	[38] = { .offset = 0xa0, .value = 0x28, },
+	[39] = { .offset = 0xa1, .value = 0x01, },
+	[40] = { .offset = 0xa2, .value = 0x28, },
+	[41] = { .offset = 0xa3, .value = 0x05, },
+	/* register 0xa4 is mode specific, but 0x80..0x84 works always */
+	[42] = { .offset = 0xa4, .value = 0x84, },
+	[43] = { .offset = 0xa5, .value = 0x00, },
+	[44] = { .offset = 0xa6, .value = 0x00, },
+	[45] = { .offset = 0xa7, .value = 0x00, },
+	[46] = { .offset = 0xa8, .value = 0x00, },
+	/* 0xa9 to 0xab are mode specific, but have no visible effect */
+	[47] = { .offset = 0xa9, .value = 0x04, },
+	[48] = { .offset = 0xaa, .value = 0x70, },
+	[49] = { .offset = 0xab, .value = 0x4f, },
+	[50] = { .offset = 0xac, .value = 0x00, },
+	[51] = { .offset = 0xad, .value = 0x00, },
+	[52] = { .offset = 0xb6, .value = 0x09, },
+	[53] = { .offset = 0xb7, .value = 0x03, },
+	/* b8,b9 are part of the mode-specific configuration */
+	[54] = { .offset = 0xba, .value = 0x00, },
+	[55] = { .offset = 0xbb, .value = 0x20, },
+	[56] = { .offset = 0xf3, .value = 0x90, },
+	[57] = { .offset = 0xf4, .value = 0x00, },
+	[58] = { .offset = 0xf7, .value = 0x88, },
+	/* f8 is mode specific, but the value does not matter */
+	[59] = { .offset = 0xf8, .value = 0x0a, },
+	[60] = { .offset = 0xf9, .value = 0x00, }
+};
+
+static const struct ns2501_reg regs_init[] = {
+	[0] = { .offset = 0x35, .value = 0xff, },
+	[1] = { .offset = 0x34, .value = 0x00, },
+	[2] = { .offset = 0x08, .value = 0x30, },
+};
+
+struct ns2501_priv {
+	bool quiet;
+	const struct ns2501_configuration *conf;
+};
+
+#define NSPTR(d) ((NS2501Ptr)(d->DriverPrivate.ptr))
+
+/*
+** Read a register from the ns2501.
+** Returns true if successful, false otherwise.
+** If it returns false, it might be wise to enable the
+** DVO with the above function.
+*/
+static bool ns2501_readb(struct intel_dvo_device *dvo, int addr, uint8_t * ch)
+{
+	struct ns2501_priv *ns = dvo->dev_priv;
+	struct i2c_adapter *adapter = dvo->i2c_bus;
+	u8 out_buf[2];
+	u8 in_buf[2];
+
+	struct i2c_msg msgs[] = {
+		{
+		 .addr = dvo->slave_addr,
+		 .flags = 0,
+		 .len = 1,
+		 .buf = out_buf,
+		 },
+		{
+		 .addr = dvo->slave_addr,
+		 .flags = I2C_M_RD,
+		 .len = 1,
+		 .buf = in_buf,
+		 }
+	};
+
+	out_buf[0] = addr;
+	out_buf[1] = 0;
+
+	if (i2c_transfer(adapter, msgs, 2) == 2) {
+		*ch = in_buf[0];
+		return true;
+	}
+
+	if (!ns->quiet) {
+		DRM_DEBUG_KMS
+		    ("Unable to read register 0x%02x from %s:0x%02x.\n", addr,
+		     adapter->name, dvo->slave_addr);
+	}
+
+	return false;
+}
+
+/*
+** Write a register to the ns2501.
+** Returns true if successful, false otherwise.
+** If it returns false, it might be wise to enable the
+** DVO with the above function.
+*/
+static bool ns2501_writeb(struct intel_dvo_device *dvo, int addr, uint8_t ch)
+{
+	struct ns2501_priv *ns = dvo->dev_priv;
+	struct i2c_adapter *adapter = dvo->i2c_bus;
+	uint8_t out_buf[2];
+
+	struct i2c_msg msg = {
+		.addr = dvo->slave_addr,
+		.flags = 0,
+		.len = 2,
+		.buf = out_buf,
+	};
+
+	out_buf[0] = addr;
+	out_buf[1] = ch;
+
+	if (i2c_transfer(adapter, &msg, 1) == 1) {
+		return true;
+	}
+
+	if (!ns->quiet) {
+		DRM_DEBUG_KMS("Unable to write register 0x%02x to %s:%d\n",
+			      addr, adapter->name, dvo->slave_addr);
+	}
+
+	return false;
+}
+
+/* National Semiconductor 2501 driver for chip on i2c bus
+ * scan for the chip on the bus.
+ * Hope the VBIOS initialized the PLL correctly so we can
+ * talk to it. If not, it will not be seen and not detected.
+ * Bummer!
+ */
+static bool ns2501_init(struct intel_dvo_device *dvo,
+			struct i2c_adapter *adapter)
+{
+	/* this will detect the NS2501 chip on the specified i2c bus */
+	struct ns2501_priv *ns;
+	unsigned char ch;
+
+	ns = kzalloc(sizeof(struct ns2501_priv), GFP_KERNEL);
+	if (ns == NULL)
+		return false;
+
+	dvo->i2c_bus = adapter;
+	dvo->dev_priv = ns;
+	ns->quiet = true;
+
+	if (!ns2501_readb(dvo, NS2501_VID_LO, &ch))
+		goto out;
+
+	if (ch != (NS2501_VID & 0xff)) {
+		DRM_DEBUG_KMS("ns2501 not detected got %d: from %s Slave %d.\n",
+			      ch, adapter->name, dvo->slave_addr);
+		goto out;
+	}
+
+	if (!ns2501_readb(dvo, NS2501_DID_LO, &ch))
+		goto out;
+
+	if (ch != (NS2501_DID & 0xff)) {
+		DRM_DEBUG_KMS("ns2501 not detected got %d: from %s Slave %d.\n",
+			      ch, adapter->name, dvo->slave_addr);
+		goto out;
+	}
+	ns->quiet = false;
+
+	DRM_DEBUG_KMS("init ns2501 dvo controller successfully!\n");
+
+	return true;
+
+out:
+	kfree(ns);
+	return false;
+}
+
+static enum drm_connector_status ns2501_detect(struct intel_dvo_device *dvo)
+{
+	/*
+	 * This is a Laptop display, it doesn't have hotplugging.
+	 * Even if not, the detection bit of the 2501 is unreliable as
+	 * it only works for some display types.
+	 * It is even more unreliable as the PLL must be active for
+	 * allowing reading from the chiop.
+	 */
+	return connector_status_connected;
+}
+
+static enum drm_mode_status ns2501_mode_valid(struct intel_dvo_device *dvo,
+					      struct drm_display_mode *mode)
+{
+	DRM_DEBUG_KMS
+	    ("is mode valid (hdisplay=%d,htotal=%d,vdisplay=%d,vtotal=%d)\n",
+	     mode->hdisplay, mode->htotal, mode->vdisplay, mode->vtotal);
+
+	/*
+	 * Currently, these are all the modes I have data from.
+	 * More might exist. Unclear how to find the native resolution
+	 * of the panel in here so we could always accept it
+	 * by disabling the scaler.
+	 */
+	if ((mode->hdisplay == 640 && mode->vdisplay == 480 && mode->clock == 25175) ||
+	    (mode->hdisplay == 800 && mode->vdisplay == 600 && mode->clock == 40000) ||
+	    (mode->hdisplay == 1024 && mode->vdisplay == 768 && mode->clock == 65000)) {
+		return MODE_OK;
+	} else {
+		return MODE_ONE_SIZE;	/* Is this a reasonable error? */
+	}
+}
+
+static void ns2501_mode_set(struct intel_dvo_device *dvo,
+			    const struct drm_display_mode *mode,
+			    const struct drm_display_mode *adjusted_mode)
+{
+	const struct ns2501_configuration *conf;
+	struct ns2501_priv *ns = (struct ns2501_priv *)(dvo->dev_priv);
+	int mode_idx, i;
+
+	DRM_DEBUG_KMS
+	    ("set mode (hdisplay=%d,htotal=%d,vdisplay=%d,vtotal=%d).\n",
+	     mode->hdisplay, mode->htotal, mode->vdisplay, mode->vtotal);
+
+	DRM_DEBUG_KMS("Detailed requested mode settings are:\n"
+			"clock		: %d kHz\n"
+			"hdisplay	: %d\n"
+			"hblank start	: %d\n"
+			"hblank end	: %d\n"
+			"hsync start	: %d\n"
+			"hsync end	: %d\n"
+			"htotal		: %d\n"
+			"hskew		: %d\n"
+			"vdisplay	: %d\n"
+			"vblank start	: %d\n"
+			"hblank end	: %d\n"
+			"vsync start	: %d\n"
+			"vsync end	: %d\n"
+			"vtotal		: %d\n",
+			adjusted_mode->crtc_clock,
+			adjusted_mode->crtc_hdisplay,
+			adjusted_mode->crtc_hblank_start,
+			adjusted_mode->crtc_hblank_end,
+			adjusted_mode->crtc_hsync_start,
+			adjusted_mode->crtc_hsync_end,
+			adjusted_mode->crtc_htotal,
+			adjusted_mode->crtc_hskew,
+			adjusted_mode->crtc_vdisplay,
+			adjusted_mode->crtc_vblank_start,
+			adjusted_mode->crtc_vblank_end,
+			adjusted_mode->crtc_vsync_start,
+			adjusted_mode->crtc_vsync_end,
+			adjusted_mode->crtc_vtotal);
+
+	if (mode->hdisplay == 640 && mode->vdisplay == 480)
+		mode_idx = MODE_640x480;
+	else if (mode->hdisplay == 800 && mode->vdisplay == 600)
+		mode_idx = MODE_800x600;
+	else if (mode->hdisplay == 1024 && mode->vdisplay == 768)
+		mode_idx = MODE_1024x768;
+	else
+		return;
+
+	/* Hopefully doing it every time won't hurt... */
+	for (i = 0; i < ARRAY_SIZE(regs_init); i++)
+		ns2501_writeb(dvo, regs_init[i].offset, regs_init[i].value);
+
+	/* Write the mode-agnostic values */
+	for (i = 0; i < ARRAY_SIZE(mode_agnostic_values); i++)
+		ns2501_writeb(dvo, mode_agnostic_values[i].offset,
+				mode_agnostic_values[i].value);
+
+	/* Write now the mode-specific configuration */
+	conf = ns2501_modes + mode_idx;
+	ns->conf = conf;
+
+	ns2501_writeb(dvo, NS2501_REG8, conf->conf);
+	ns2501_writeb(dvo, NS2501_REG1B, conf->pll_a);
+	ns2501_writeb(dvo, NS2501_REG1C, conf->pll_b & 0xff);
+	ns2501_writeb(dvo, NS2501_REG1D, conf->pll_b >> 8);
+	ns2501_writeb(dvo, NS2501_REGC1, conf->hstart & 0xff);
+	ns2501_writeb(dvo, NS2501_REGC2, conf->hstart >> 8);
+	ns2501_writeb(dvo, NS2501_REGC3, conf->hstop & 0xff);
+	ns2501_writeb(dvo, NS2501_REGC4, conf->hstop >> 8);
+	ns2501_writeb(dvo, NS2501_REGC5, conf->vstart & 0xff);
+	ns2501_writeb(dvo, NS2501_REGC6, conf->vstart >> 8);
+	ns2501_writeb(dvo, NS2501_REGC7, conf->vstop & 0xff);
+	ns2501_writeb(dvo, NS2501_REGC8, conf->vstop >> 8);
+	ns2501_writeb(dvo, NS2501_REG80, conf->vsync & 0xff);
+	ns2501_writeb(dvo, NS2501_REG81, conf->vsync >> 8);
+	ns2501_writeb(dvo, NS2501_REG82, conf->vtotal & 0xff);
+	ns2501_writeb(dvo, NS2501_REG83, conf->vtotal >> 8);
+	ns2501_writeb(dvo, NS2501_REG98, conf->hpos & 0xff);
+	ns2501_writeb(dvo, NS2501_REG99, conf->hpos >> 8);
+	ns2501_writeb(dvo, NS2501_REG8E, conf->vpos & 0xff);
+	ns2501_writeb(dvo, NS2501_REG8F, conf->vpos >> 8);
+	ns2501_writeb(dvo, NS2501_REG9C, conf->voffs & 0xff);
+	ns2501_writeb(dvo, NS2501_REG9D, conf->voffs >> 8);
+	ns2501_writeb(dvo, NS2501_REGB8, conf->hscale & 0xff);
+	ns2501_writeb(dvo, NS2501_REGB9, conf->hscale >> 8);
+	ns2501_writeb(dvo, NS2501_REG10, conf->vscale & 0xff);
+	ns2501_writeb(dvo, NS2501_REG11, conf->vscale >> 8);
+	ns2501_writeb(dvo, NS2501_REGF9, conf->dither);
+	ns2501_writeb(dvo, NS2501_REG41, conf->syncb);
+	ns2501_writeb(dvo, NS2501_REGC0, conf->sync);
+}
+
+/* set the NS2501 power state */
+static bool ns2501_get_hw_state(struct intel_dvo_device *dvo)
+{
+	unsigned char ch;
+
+	if (!ns2501_readb(dvo, NS2501_REG8, &ch))
+		return false;
+
+	return ch & NS2501_8_PD;
+}
+
+/* set the NS2501 power state */
+static void ns2501_dpms(struct intel_dvo_device *dvo, bool enable)
+{
+	struct ns2501_priv *ns = (struct ns2501_priv *)(dvo->dev_priv);
+
+	DRM_DEBUG_KMS("Trying set the dpms of the DVO to %i\n", enable);
+
+	if (enable) {
+		ns2501_writeb(dvo, NS2501_REGC0, ns->conf->sync | 0x08);
+
+		ns2501_writeb(dvo, NS2501_REG41, ns->conf->syncb);
+
+		ns2501_writeb(dvo, NS2501_REG34, NS2501_34_ENABLE_OUTPUT);
+		msleep(15);
+
+		ns2501_writeb(dvo, NS2501_REG8,
+				ns->conf->conf | NS2501_8_BPAS);
+		if (!(ns->conf->conf & NS2501_8_BPAS))
+			ns2501_writeb(dvo, NS2501_REG8, ns->conf->conf);
+		msleep(200);
+
+		ns2501_writeb(dvo, NS2501_REG34,
+			NS2501_34_ENABLE_OUTPUT | NS2501_34_ENABLE_BACKLIGHT);
+
+		ns2501_writeb(dvo, NS2501_REGC0, ns->conf->sync);
+	} else {
+		ns2501_writeb(dvo, NS2501_REG34, NS2501_34_ENABLE_OUTPUT);
+		msleep(200);
+
+		ns2501_writeb(dvo, NS2501_REG8, NS2501_8_VEN | NS2501_8_HEN |
+				NS2501_8_BPAS);
+		msleep(15);
+
+		ns2501_writeb(dvo, NS2501_REG34, 0x00);
+	}
+}
+
+static void ns2501_destroy(struct intel_dvo_device *dvo)
+{
+	struct ns2501_priv *ns = dvo->dev_priv;
+
+	if (ns) {
+		kfree(ns);
+		dvo->dev_priv = NULL;
+	}
+}
+
+const struct intel_dvo_dev_ops ns2501_ops = {
+	.init = ns2501_init,
+	.detect = ns2501_detect,
+	.mode_valid = ns2501_mode_valid,
+	.mode_set = ns2501_mode_set,
+	.dpms = ns2501_dpms,
+	.get_hw_state = ns2501_get_hw_state,
+	.destroy = ns2501_destroy,
+};
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/i915/dvo_sil164.c
@@ -0,0 +1,279 @@
+/**************************************************************************
+
+Copyright © 2006 Dave Airlie
+
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sub license, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice (including the
+next paragraph) shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+#include "dvo.h"
+
+#define SIL164_VID 0x0001
+#define SIL164_DID 0x0006
+
+#define SIL164_VID_LO 0x00
+#define SIL164_VID_HI 0x01
+#define SIL164_DID_LO 0x02
+#define SIL164_DID_HI 0x03
+#define SIL164_REV    0x04
+#define SIL164_RSVD   0x05
+#define SIL164_FREQ_LO 0x06
+#define SIL164_FREQ_HI 0x07
+
+#define SIL164_REG8 0x08
+#define SIL164_8_VEN (1<<5)
+#define SIL164_8_HEN (1<<4)
+#define SIL164_8_DSEL (1<<3)
+#define SIL164_8_BSEL (1<<2)
+#define SIL164_8_EDGE (1<<1)
+#define SIL164_8_PD   (1<<0)
+
+#define SIL164_REG9 0x09
+#define SIL164_9_VLOW (1<<7)
+#define SIL164_9_MSEL_MASK (0x7<<4)
+#define SIL164_9_TSEL (1<<3)
+#define SIL164_9_RSEN (1<<2)
+#define SIL164_9_HTPLG (1<<1)
+#define SIL164_9_MDI (1<<0)
+
+#define SIL164_REGC 0x0c
+
+struct sil164_priv {
+	//I2CDevRec d;
+	bool quiet;
+};
+
+#define SILPTR(d) ((SIL164Ptr)(d->DriverPrivate.ptr))
+
+static bool sil164_readb(struct intel_dvo_device *dvo, int addr, uint8_t *ch)
+{
+	struct sil164_priv *sil = dvo->dev_priv;
+	struct i2c_adapter *adapter = dvo->i2c_bus;
+	u8 out_buf[2];
+	u8 in_buf[2];
+
+	struct i2c_msg msgs[] = {
+		{
+			.addr = dvo->slave_addr,
+			.flags = 0,
+			.len = 1,
+			.buf = out_buf,
+		},
+		{
+			.addr = dvo->slave_addr,
+			.flags = I2C_M_RD,
+			.len = 1,
+			.buf = in_buf,
+		}
+	};
+
+	out_buf[0] = addr;
+	out_buf[1] = 0;
+
+	if (i2c_transfer(adapter, msgs, 2) == 2) {
+		*ch = in_buf[0];
+		return true;
+	}
+
+	if (!sil->quiet) {
+		DRM_DEBUG_KMS("Unable to read register 0x%02x from %s:%02x.\n",
+			  addr, adapter->name, dvo->slave_addr);
+	}
+	return false;
+}
+
+static bool sil164_writeb(struct intel_dvo_device *dvo, int addr, uint8_t ch)
+{
+	struct sil164_priv *sil = dvo->dev_priv;
+	struct i2c_adapter *adapter = dvo->i2c_bus;
+	uint8_t out_buf[2];
+	struct i2c_msg msg = {
+		.addr = dvo->slave_addr,
+		.flags = 0,
+		.len = 2,
+		.buf = out_buf,
+	};
+
+	out_buf[0] = addr;
+	out_buf[1] = ch;
+
+	if (i2c_transfer(adapter, &msg, 1) == 1)
+		return true;
+
+	if (!sil->quiet) {
+		DRM_DEBUG_KMS("Unable to write register 0x%02x to %s:%d.\n",
+			  addr, adapter->name, dvo->slave_addr);
+	}
+
+	return false;
+}
+
+/* Silicon Image 164 driver for chip on i2c bus */
+static bool sil164_init(struct intel_dvo_device *dvo,
+			struct i2c_adapter *adapter)
+{
+	/* this will detect the SIL164 chip on the specified i2c bus */
+	struct sil164_priv *sil;
+	unsigned char ch;
+
+	sil = kzalloc(sizeof(struct sil164_priv), GFP_KERNEL);
+	if (sil == NULL)
+		return false;
+
+	dvo->i2c_bus = adapter;
+	dvo->dev_priv = sil;
+	sil->quiet = true;
+
+	if (!sil164_readb(dvo, SIL164_VID_LO, &ch))
+		goto out;
+
+	if (ch != (SIL164_VID & 0xff)) {
+		DRM_DEBUG_KMS("sil164 not detected got %d: from %s Slave %d.\n",
+			  ch, adapter->name, dvo->slave_addr);
+		goto out;
+	}
+
+	if (!sil164_readb(dvo, SIL164_DID_LO, &ch))
+		goto out;
+
+	if (ch != (SIL164_DID & 0xff)) {
+		DRM_DEBUG_KMS("sil164 not detected got %d: from %s Slave %d.\n",
+			  ch, adapter->name, dvo->slave_addr);
+		goto out;
+	}
+	sil->quiet = false;
+
+	DRM_DEBUG_KMS("init sil164 dvo controller successfully!\n");
+	return true;
+
+out:
+	kfree(sil);
+	return false;
+}
+
+static enum drm_connector_status sil164_detect(struct intel_dvo_device *dvo)
+{
+	uint8_t reg9;
+
+	sil164_readb(dvo, SIL164_REG9, &reg9);
+
+	if (reg9 & SIL164_9_HTPLG)
+		return connector_status_connected;
+	else
+		return connector_status_disconnected;
+}
+
+static enum drm_mode_status sil164_mode_valid(struct intel_dvo_device *dvo,
+					      struct drm_display_mode *mode)
+{
+	return MODE_OK;
+}
+
+static void sil164_mode_set(struct intel_dvo_device *dvo,
+			    const struct drm_display_mode *mode,
+			    const struct drm_display_mode *adjusted_mode)
+{
+	/* As long as the basics are set up, since we don't have clock
+	 * dependencies in the mode setup, we can just leave the
+	 * registers alone and everything will work fine.
+	 */
+	/* recommended programming sequence from doc */
+	/*sil164_writeb(sil, 0x08, 0x30);
+	  sil164_writeb(sil, 0x09, 0x00);
+	  sil164_writeb(sil, 0x0a, 0x90);
+	  sil164_writeb(sil, 0x0c, 0x89);
+	  sil164_writeb(sil, 0x08, 0x31);*/
+	/* don't do much */
+	return;
+}
+
+/* set the SIL164 power state */
+static void sil164_dpms(struct intel_dvo_device *dvo, bool enable)
+{
+	int ret;
+	unsigned char ch;
+
+	ret = sil164_readb(dvo, SIL164_REG8, &ch);
+	if (ret == false)
+		return;
+
+	if (enable)
+		ch |= SIL164_8_PD;
+	else
+		ch &= ~SIL164_8_PD;
+
+	sil164_writeb(dvo, SIL164_REG8, ch);
+	return;
+}
+
+static bool sil164_get_hw_state(struct intel_dvo_device *dvo)
+{
+	int ret;
+	unsigned char ch;
+
+	ret = sil164_readb(dvo, SIL164_REG8, &ch);
+	if (ret == false)
+		return false;
+
+	if (ch & SIL164_8_PD)
+		return true;
+	else
+		return false;
+}
+
+static void sil164_dump_regs(struct intel_dvo_device *dvo)
+{
+	uint8_t val;
+
+	sil164_readb(dvo, SIL164_FREQ_LO, &val);
+	DRM_DEBUG_KMS("SIL164_FREQ_LO: 0x%02x\n", val);
+	sil164_readb(dvo, SIL164_FREQ_HI, &val);
+	DRM_DEBUG_KMS("SIL164_FREQ_HI: 0x%02x\n", val);
+	sil164_readb(dvo, SIL164_REG8, &val);
+	DRM_DEBUG_KMS("SIL164_REG8: 0x%02x\n", val);
+	sil164_readb(dvo, SIL164_REG9, &val);
+	DRM_DEBUG_KMS("SIL164_REG9: 0x%02x\n", val);
+	sil164_readb(dvo, SIL164_REGC, &val);
+	DRM_DEBUG_KMS("SIL164_REGC: 0x%02x\n", val);
+}
+
+static void sil164_destroy(struct intel_dvo_device *dvo)
+{
+	struct sil164_priv *sil = dvo->dev_priv;
+
+	if (sil) {
+		kfree(sil);
+		dvo->dev_priv = NULL;
+	}
+}
+
+const struct intel_dvo_dev_ops sil164_ops = {
+	.init = sil164_init,
+	.detect = sil164_detect,
+	.mode_valid = sil164_mode_valid,
+	.mode_set = sil164_mode_set,
+	.dpms = sil164_dpms,
+	.get_hw_state = sil164_get_hw_state,
+	.dump_regs = sil164_dump_regs,
+	.destroy = sil164_destroy,
+};
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/i915/dvo_tfp410.c
@@ -0,0 +1,318 @@
+/*
+ * Copyright © 2007 Dave Mueller
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Dave Mueller <dave.mueller@gmx.ch>
+ *
+ */
+
+#include "dvo.h"
+
+/* register definitions according to the TFP410 data sheet */
+#define TFP410_VID		0x014C
+#define TFP410_DID		0x0410
+
+#define TFP410_VID_LO		0x00
+#define TFP410_VID_HI		0x01
+#define TFP410_DID_LO		0x02
+#define TFP410_DID_HI		0x03
+#define TFP410_REV		0x04
+
+#define TFP410_CTL_1		0x08
+#define TFP410_CTL_1_TDIS	(1<<6)
+#define TFP410_CTL_1_VEN	(1<<5)
+#define TFP410_CTL_1_HEN	(1<<4)
+#define TFP410_CTL_1_DSEL	(1<<3)
+#define TFP410_CTL_1_BSEL	(1<<2)
+#define TFP410_CTL_1_EDGE	(1<<1)
+#define TFP410_CTL_1_PD		(1<<0)
+
+#define TFP410_CTL_2		0x09
+#define TFP410_CTL_2_VLOW	(1<<7)
+#define TFP410_CTL_2_MSEL_MASK	(0x7<<4)
+#define TFP410_CTL_2_MSEL	(1<<4)
+#define TFP410_CTL_2_TSEL	(1<<3)
+#define TFP410_CTL_2_RSEN	(1<<2)
+#define TFP410_CTL_2_HTPLG	(1<<1)
+#define TFP410_CTL_2_MDI	(1<<0)
+
+#define TFP410_CTL_3		0x0A
+#define TFP410_CTL_3_DK_MASK	(0x7<<5)
+#define TFP410_CTL_3_DK		(1<<5)
+#define TFP410_CTL_3_DKEN	(1<<4)
+#define TFP410_CTL_3_CTL_MASK	(0x7<<1)
+#define TFP410_CTL_3_CTL	(1<<1)
+
+#define TFP410_USERCFG		0x0B
+
+#define TFP410_DE_DLY		0x32
+
+#define TFP410_DE_CTL		0x33
+#define TFP410_DE_CTL_DEGEN	(1<<6)
+#define TFP410_DE_CTL_VSPOL	(1<<5)
+#define TFP410_DE_CTL_HSPOL	(1<<4)
+#define TFP410_DE_CTL_DEDLY8	(1<<0)
+
+#define TFP410_DE_TOP		0x34
+
+#define TFP410_DE_CNT_LO	0x36
+#define TFP410_DE_CNT_HI	0x37
+
+#define TFP410_DE_LIN_LO	0x38
+#define TFP410_DE_LIN_HI	0x39
+
+#define TFP410_H_RES_LO		0x3A
+#define TFP410_H_RES_HI		0x3B
+
+#define TFP410_V_RES_LO		0x3C
+#define TFP410_V_RES_HI		0x3D
+
+struct tfp410_priv {
+	bool quiet;
+};
+
+static bool tfp410_readb(struct intel_dvo_device *dvo, int addr, uint8_t *ch)
+{
+	struct tfp410_priv *tfp = dvo->dev_priv;
+	struct i2c_adapter *adapter = dvo->i2c_bus;
+	u8 out_buf[2];
+	u8 in_buf[2];
+
+	struct i2c_msg msgs[] = {
+		{
+			.addr = dvo->slave_addr,
+			.flags = 0,
+			.len = 1,
+			.buf = out_buf,
+		},
+		{
+			.addr = dvo->slave_addr,
+			.flags = I2C_M_RD,
+			.len = 1,
+			.buf = in_buf,
+		}
+	};
+
+	out_buf[0] = addr;
+	out_buf[1] = 0;
+
+	if (i2c_transfer(adapter, msgs, 2) == 2) {
+		*ch = in_buf[0];
+		return true;
+	}
+
+	if (!tfp->quiet) {
+		DRM_DEBUG_KMS("Unable to read register 0x%02x from %s:%02x.\n",
+			  addr, adapter->name, dvo->slave_addr);
+	}
+	return false;
+}
+
+static bool tfp410_writeb(struct intel_dvo_device *dvo, int addr, uint8_t ch)
+{
+	struct tfp410_priv *tfp = dvo->dev_priv;
+	struct i2c_adapter *adapter = dvo->i2c_bus;
+	uint8_t out_buf[2];
+	struct i2c_msg msg = {
+		.addr = dvo->slave_addr,
+		.flags = 0,
+		.len = 2,
+		.buf = out_buf,
+	};
+
+	out_buf[0] = addr;
+	out_buf[1] = ch;
+
+	if (i2c_transfer(adapter, &msg, 1) == 1)
+		return true;
+
+	if (!tfp->quiet) {
+		DRM_DEBUG_KMS("Unable to write register 0x%02x to %s:%d.\n",
+			  addr, adapter->name, dvo->slave_addr);
+	}
+
+	return false;
+}
+
+static int tfp410_getid(struct intel_dvo_device *dvo, int addr)
+{
+	uint8_t ch1, ch2;
+
+	if (tfp410_readb(dvo, addr+0, &ch1) &&
+	    tfp410_readb(dvo, addr+1, &ch2))
+		return ((ch2 << 8) & 0xFF00) | (ch1 & 0x00FF);
+
+	return -1;
+}
+
+/* Ti TFP410 driver for chip on i2c bus */
+static bool tfp410_init(struct intel_dvo_device *dvo,
+			struct i2c_adapter *adapter)
+{
+	/* this will detect the tfp410 chip on the specified i2c bus */
+	struct tfp410_priv *tfp;
+	int id;
+
+	tfp = kzalloc(sizeof(struct tfp410_priv), GFP_KERNEL);
+	if (tfp == NULL)
+		return false;
+
+	dvo->i2c_bus = adapter;
+	dvo->dev_priv = tfp;
+	tfp->quiet = true;
+
+	if ((id = tfp410_getid(dvo, TFP410_VID_LO)) != TFP410_VID) {
+		DRM_DEBUG_KMS("tfp410 not detected got VID %X: from %s "
+				"Slave %d.\n",
+			  id, adapter->name, dvo->slave_addr);
+		goto out;
+	}
+
+	if ((id = tfp410_getid(dvo, TFP410_DID_LO)) != TFP410_DID) {
+		DRM_DEBUG_KMS("tfp410 not detected got DID %X: from %s "
+				"Slave %d.\n",
+			  id, adapter->name, dvo->slave_addr);
+		goto out;
+	}
+	tfp->quiet = false;
+	return true;
+out:
+	kfree(tfp);
+	return false;
+}
+
+static enum drm_connector_status tfp410_detect(struct intel_dvo_device *dvo)
+{
+	enum drm_connector_status ret = connector_status_disconnected;
+	uint8_t ctl2;
+
+	if (tfp410_readb(dvo, TFP410_CTL_2, &ctl2)) {
+		if (ctl2 & TFP410_CTL_2_RSEN)
+			ret = connector_status_connected;
+		else
+			ret = connector_status_disconnected;
+	}
+
+	return ret;
+}
+
+static enum drm_mode_status tfp410_mode_valid(struct intel_dvo_device *dvo,
+					      struct drm_display_mode *mode)
+{
+	return MODE_OK;
+}
+
+static void tfp410_mode_set(struct intel_dvo_device *dvo,
+			    const struct drm_display_mode *mode,
+			    const struct drm_display_mode *adjusted_mode)
+{
+	/* As long as the basics are set up, since we don't have clock dependencies
+	* in the mode setup, we can just leave the registers alone and everything
+	* will work fine.
+	*/
+	/* don't do much */
+	return;
+}
+
+/* set the tfp410 power state */
+static void tfp410_dpms(struct intel_dvo_device *dvo, bool enable)
+{
+	uint8_t ctl1;
+
+	if (!tfp410_readb(dvo, TFP410_CTL_1, &ctl1))
+		return;
+
+	if (enable)
+		ctl1 |= TFP410_CTL_1_PD;
+	else
+		ctl1 &= ~TFP410_CTL_1_PD;
+
+	tfp410_writeb(dvo, TFP410_CTL_1, ctl1);
+}
+
+static bool tfp410_get_hw_state(struct intel_dvo_device *dvo)
+{
+	uint8_t ctl1;
+
+	if (!tfp410_readb(dvo, TFP410_CTL_1, &ctl1))
+		return false;
+
+	if (ctl1 & TFP410_CTL_1_PD)
+		return true;
+	else
+		return false;
+}
+
+static void tfp410_dump_regs(struct intel_dvo_device *dvo)
+{
+	uint8_t val, val2;
+
+	tfp410_readb(dvo, TFP410_REV, &val);
+	DRM_DEBUG_KMS("TFP410_REV: 0x%02X\n", val);
+	tfp410_readb(dvo, TFP410_CTL_1, &val);
+	DRM_DEBUG_KMS("TFP410_CTL1: 0x%02X\n", val);
+	tfp410_readb(dvo, TFP410_CTL_2, &val);
+	DRM_DEBUG_KMS("TFP410_CTL2: 0x%02X\n", val);
+	tfp410_readb(dvo, TFP410_CTL_3, &val);
+	DRM_DEBUG_KMS("TFP410_CTL3: 0x%02X\n", val);
+	tfp410_readb(dvo, TFP410_USERCFG, &val);
+	DRM_DEBUG_KMS("TFP410_USERCFG: 0x%02X\n", val);
+	tfp410_readb(dvo, TFP410_DE_DLY, &val);
+	DRM_DEBUG_KMS("TFP410_DE_DLY: 0x%02X\n", val);
+	tfp410_readb(dvo, TFP410_DE_CTL, &val);
+	DRM_DEBUG_KMS("TFP410_DE_CTL: 0x%02X\n", val);
+	tfp410_readb(dvo, TFP410_DE_TOP, &val);
+	DRM_DEBUG_KMS("TFP410_DE_TOP: 0x%02X\n", val);
+	tfp410_readb(dvo, TFP410_DE_CNT_LO, &val);
+	tfp410_readb(dvo, TFP410_DE_CNT_HI, &val2);
+	DRM_DEBUG_KMS("TFP410_DE_CNT: 0x%02X%02X\n", val2, val);
+	tfp410_readb(dvo, TFP410_DE_LIN_LO, &val);
+	tfp410_readb(dvo, TFP410_DE_LIN_HI, &val2);
+	DRM_DEBUG_KMS("TFP410_DE_LIN: 0x%02X%02X\n", val2, val);
+	tfp410_readb(dvo, TFP410_H_RES_LO, &val);
+	tfp410_readb(dvo, TFP410_H_RES_HI, &val2);
+	DRM_DEBUG_KMS("TFP410_H_RES: 0x%02X%02X\n", val2, val);
+	tfp410_readb(dvo, TFP410_V_RES_LO, &val);
+	tfp410_readb(dvo, TFP410_V_RES_HI, &val2);
+	DRM_DEBUG_KMS("TFP410_V_RES: 0x%02X%02X\n", val2, val);
+}
+
+static void tfp410_destroy(struct intel_dvo_device *dvo)
+{
+	struct tfp410_priv *tfp = dvo->dev_priv;
+
+	if (tfp) {
+		kfree(tfp);
+		dvo->dev_priv = NULL;
+	}
+}
+
+const struct intel_dvo_dev_ops tfp410_ops = {
+	.init = tfp410_init,
+	.detect = tfp410_detect,
+	.mode_valid = tfp410_mode_valid,
+	.mode_set = tfp410_mode_set,
+	.dpms = tfp410_dpms,
+	.get_hw_state = tfp410_get_hw_state,
+	.dump_regs = tfp410_dump_regs,
+	.destroy = tfp410_destroy,
+};
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/i915/i915_cmd_parser.c
@@ -0,0 +1,1293 @@
+/*
+ * Copyright © 2013 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Brad Volkin <bradley.d.volkin@intel.com>
+ *
+ */
+
+#include "i915_drv.h"
+
+/**
+ * DOC: batch buffer command parser
+ *
+ * Motivation:
+ * Certain OpenGL features (e.g. transform feedback, performance monitoring)
+ * require userspace code to submit batches containing commands such as
+ * MI_LOAD_REGISTER_IMM to access various registers. Unfortunately, some
+ * generations of the hardware will noop these commands in "unsecure" batches
+ * (which includes all userspace batches submitted via i915) even though the
+ * commands may be safe and represent the intended programming model of the
+ * device.
+ *
+ * The software command parser is similar in operation to the command parsing
+ * done in hardware for unsecure batches. However, the software parser allows
+ * some operations that would be noop'd by hardware, if the parser determines
+ * the operation is safe, and submits the batch as "secure" to prevent hardware
+ * parsing.
+ *
+ * Threats:
+ * At a high level, the hardware (and software) checks attempt to prevent
+ * granting userspace undue privileges. There are three categories of privilege.
+ *
+ * First, commands which are explicitly defined as privileged or which should
+ * only be used by the kernel driver. The parser generally rejects such
+ * commands, though it may allow some from the drm master process.
+ *
+ * Second, commands which access registers. To support correct/enhanced
+ * userspace functionality, particularly certain OpenGL extensions, the parser
+ * provides a whitelist of registers which userspace may safely access (for both
+ * normal and drm master processes).
+ *
+ * Third, commands which access privileged memory (i.e. GGTT, HWS page, etc).
+ * The parser always rejects such commands.
+ *
+ * The majority of the problematic commands fall in the MI_* range, with only a
+ * few specific commands on each ring (e.g. PIPE_CONTROL and MI_FLUSH_DW).
+ *
+ * Implementation:
+ * Each ring maintains tables of commands and registers which the parser uses in
+ * scanning batch buffers submitted to that ring.
+ *
+ * Since the set of commands that the parser must check for is significantly
+ * smaller than the number of commands supported, the parser tables contain only
+ * those commands required by the parser. This generally works because command
+ * opcode ranges have standard command length encodings. So for commands that
+ * the parser does not need to check, it can easily skip them. This is
+ * implemented via a per-ring length decoding vfunc.
+ *
+ * Unfortunately, there are a number of commands that do not follow the standard
+ * length encoding for their opcode range, primarily amongst the MI_* commands.
+ * To handle this, the parser provides a way to define explicit "skip" entries
+ * in the per-ring command tables.
+ *
+ * Other command table entries map fairly directly to high level categories
+ * mentioned above: rejected, master-only, register whitelist. The parser
+ * implements a number of checks, including the privileged memory checks, via a
+ * general bitmasking mechanism.
+ */
+
+#define STD_MI_OPCODE_MASK  0xFF800000
+#define STD_3D_OPCODE_MASK  0xFFFF0000
+#define STD_2D_OPCODE_MASK  0xFFC00000
+#define STD_MFX_OPCODE_MASK 0xFFFF0000
+
+#define CMD(op, opm, f, lm, fl, ...)				\
+	{							\
+		.flags = (fl) | ((f) ? CMD_DESC_FIXED : 0),	\
+		.cmd = { (op), (opm) },				\
+		.length = { (lm) },				\
+		__VA_ARGS__					\
+	}
+
+/* Convenience macros to compress the tables */
+#define SMI STD_MI_OPCODE_MASK
+#define S3D STD_3D_OPCODE_MASK
+#define S2D STD_2D_OPCODE_MASK
+#define SMFX STD_MFX_OPCODE_MASK
+#define F true
+#define S CMD_DESC_SKIP
+#define R CMD_DESC_REJECT
+#define W CMD_DESC_REGISTER
+#define B CMD_DESC_BITMASK
+#define M CMD_DESC_MASTER
+
+/*            Command                          Mask   Fixed Len   Action
+	      ---------------------------------------------------------- */
+static const struct drm_i915_cmd_descriptor common_cmds[] = {
+	CMD(  MI_NOOP,                          SMI,    F,  1,      S  ),
+	CMD(  MI_USER_INTERRUPT,                SMI,    F,  1,      R  ),
+	CMD(  MI_WAIT_FOR_EVENT,                SMI,    F,  1,      M  ),
+	CMD(  MI_ARB_CHECK,                     SMI,    F,  1,      S  ),
+	CMD(  MI_REPORT_HEAD,                   SMI,    F,  1,      S  ),
+	CMD(  MI_SUSPEND_FLUSH,                 SMI,    F,  1,      S  ),
+	CMD(  MI_SEMAPHORE_MBOX,                SMI,   !F,  0xFF,   R  ),
+	CMD(  MI_STORE_DWORD_INDEX,             SMI,   !F,  0xFF,   R  ),
+	CMD(  MI_LOAD_REGISTER_IMM(1),          SMI,   !F,  0xFF,   W,
+	      .reg = { .offset = 1, .mask = 0x007FFFFC, .step = 2 }    ),
+	CMD(  MI_STORE_REGISTER_MEM,            SMI,    F,  3,     W | B,
+	      .reg = { .offset = 1, .mask = 0x007FFFFC },
+	      .bits = {{
+			.offset = 0,
+			.mask = MI_GLOBAL_GTT,
+			.expected = 0,
+	      }},						       ),
+	CMD(  MI_LOAD_REGISTER_MEM,             SMI,    F,  3,     W | B,
+	      .reg = { .offset = 1, .mask = 0x007FFFFC },
+	      .bits = {{
+			.offset = 0,
+			.mask = MI_GLOBAL_GTT,
+			.expected = 0,
+	      }},						       ),
+	/*
+	 * MI_BATCH_BUFFER_START requires some special handling. It's not
+	 * really a 'skip' action but it doesn't seem like it's worth adding
+	 * a new action. See i915_parse_cmds().
+	 */
+	CMD(  MI_BATCH_BUFFER_START,            SMI,   !F,  0xFF,   S  ),
+};
+
+static const struct drm_i915_cmd_descriptor render_cmds[] = {
+	CMD(  MI_FLUSH,                         SMI,    F,  1,      S  ),
+	CMD(  MI_ARB_ON_OFF,                    SMI,    F,  1,      R  ),
+	CMD(  MI_PREDICATE,                     SMI,    F,  1,      S  ),
+	CMD(  MI_TOPOLOGY_FILTER,               SMI,    F,  1,      S  ),
+	CMD(  MI_SET_APPID,                     SMI,    F,  1,      S  ),
+	CMD(  MI_DISPLAY_FLIP,                  SMI,   !F,  0xFF,   R  ),
+	CMD(  MI_SET_CONTEXT,                   SMI,   !F,  0xFF,   R  ),
+	CMD(  MI_URB_CLEAR,                     SMI,   !F,  0xFF,   S  ),
+	CMD(  MI_STORE_DWORD_IMM,               SMI,   !F,  0x3F,   B,
+	      .bits = {{
+			.offset = 0,
+			.mask = MI_GLOBAL_GTT,
+			.expected = 0,
+	      }},						       ),
+	CMD(  MI_UPDATE_GTT,                    SMI,   !F,  0xFF,   R  ),
+	CMD(  MI_CLFLUSH,                       SMI,   !F,  0x3FF,  B,
+	      .bits = {{
+			.offset = 0,
+			.mask = MI_GLOBAL_GTT,
+			.expected = 0,
+	      }},						       ),
+	CMD(  MI_REPORT_PERF_COUNT,             SMI,   !F,  0x3F,   B,
+	      .bits = {{
+			.offset = 1,
+			.mask = MI_REPORT_PERF_COUNT_GGTT,
+			.expected = 0,
+	      }},						       ),
+	CMD(  MI_CONDITIONAL_BATCH_BUFFER_END,  SMI,   !F,  0xFF,   B,
+	      .bits = {{
+			.offset = 0,
+			.mask = MI_GLOBAL_GTT,
+			.expected = 0,
+	      }},						       ),
+	CMD(  GFX_OP_3DSTATE_VF_STATISTICS,     S3D,    F,  1,      S  ),
+	CMD(  PIPELINE_SELECT,                  S3D,    F,  1,      S  ),
+	CMD(  MEDIA_VFE_STATE,			S3D,   !F,  0xFFFF, B,
+	      .bits = {{
+			.offset = 2,
+			.mask = MEDIA_VFE_STATE_MMIO_ACCESS_MASK,
+			.expected = 0,
+	      }},						       ),
+	CMD(  GPGPU_OBJECT,                     S3D,   !F,  0xFF,   S  ),
+	CMD(  GPGPU_WALKER,                     S3D,   !F,  0xFF,   S  ),
+	CMD(  GFX_OP_3DSTATE_SO_DECL_LIST,      S3D,   !F,  0x1FF,  S  ),
+	CMD(  GFX_OP_PIPE_CONTROL(5),           S3D,   !F,  0xFF,   B,
+	      .bits = {{
+			.offset = 1,
+			.mask = (PIPE_CONTROL_MMIO_WRITE | PIPE_CONTROL_NOTIFY),
+			.expected = 0,
+	      },
+	      {
+			.offset = 1,
+		        .mask = (PIPE_CONTROL_GLOBAL_GTT_IVB |
+				 PIPE_CONTROL_STORE_DATA_INDEX),
+			.expected = 0,
+			.condition_offset = 1,
+			.condition_mask = PIPE_CONTROL_POST_SYNC_OP_MASK,
+	      }},						       ),
+};
+
+static const struct drm_i915_cmd_descriptor hsw_render_cmds[] = {
+	CMD(  MI_SET_PREDICATE,                 SMI,    F,  1,      S  ),
+	CMD(  MI_RS_CONTROL,                    SMI,    F,  1,      S  ),
+	CMD(  MI_URB_ATOMIC_ALLOC,              SMI,    F,  1,      S  ),
+	CMD(  MI_SET_APPID,                     SMI,    F,  1,      S  ),
+	CMD(  MI_RS_CONTEXT,                    SMI,    F,  1,      S  ),
+	CMD(  MI_LOAD_SCAN_LINES_INCL,          SMI,   !F,  0x3F,   M  ),
+	CMD(  MI_LOAD_SCAN_LINES_EXCL,          SMI,   !F,  0x3F,   R  ),
+	CMD(  MI_LOAD_REGISTER_REG,             SMI,   !F,  0xFF,   R  ),
+	CMD(  MI_RS_STORE_DATA_IMM,             SMI,   !F,  0xFF,   S  ),
+	CMD(  MI_LOAD_URB_MEM,                  SMI,   !F,  0xFF,   S  ),
+	CMD(  MI_STORE_URB_MEM,                 SMI,   !F,  0xFF,   S  ),
+	CMD(  GFX_OP_3DSTATE_DX9_CONSTANTF_VS,  S3D,   !F,  0x7FF,  S  ),
+	CMD(  GFX_OP_3DSTATE_DX9_CONSTANTF_PS,  S3D,   !F,  0x7FF,  S  ),
+
+	CMD(  GFX_OP_3DSTATE_BINDING_TABLE_EDIT_VS,  S3D,   !F,  0x1FF,  S  ),
+	CMD(  GFX_OP_3DSTATE_BINDING_TABLE_EDIT_GS,  S3D,   !F,  0x1FF,  S  ),
+	CMD(  GFX_OP_3DSTATE_BINDING_TABLE_EDIT_HS,  S3D,   !F,  0x1FF,  S  ),
+	CMD(  GFX_OP_3DSTATE_BINDING_TABLE_EDIT_DS,  S3D,   !F,  0x1FF,  S  ),
+	CMD(  GFX_OP_3DSTATE_BINDING_TABLE_EDIT_PS,  S3D,   !F,  0x1FF,  S  ),
+};
+
+static const struct drm_i915_cmd_descriptor video_cmds[] = {
+	CMD(  MI_ARB_ON_OFF,                    SMI,    F,  1,      R  ),
+	CMD(  MI_SET_APPID,                     SMI,    F,  1,      S  ),
+	CMD(  MI_STORE_DWORD_IMM,               SMI,   !F,  0xFF,   B,
+	      .bits = {{
+			.offset = 0,
+			.mask = MI_GLOBAL_GTT,
+			.expected = 0,
+	      }},						       ),
+	CMD(  MI_UPDATE_GTT,                    SMI,   !F,  0x3F,   R  ),
+	CMD(  MI_FLUSH_DW,                      SMI,   !F,  0x3F,   B,
+	      .bits = {{
+			.offset = 0,
+			.mask = MI_FLUSH_DW_NOTIFY,
+			.expected = 0,
+	      },
+	      {
+			.offset = 1,
+			.mask = MI_FLUSH_DW_USE_GTT,
+			.expected = 0,
+			.condition_offset = 0,
+			.condition_mask = MI_FLUSH_DW_OP_MASK,
+	      },
+	      {
+			.offset = 0,
+			.mask = MI_FLUSH_DW_STORE_INDEX,
+			.expected = 0,
+			.condition_offset = 0,
+			.condition_mask = MI_FLUSH_DW_OP_MASK,
+	      }},						       ),
+	CMD(  MI_CONDITIONAL_BATCH_BUFFER_END,  SMI,   !F,  0xFF,   B,
+	      .bits = {{
+			.offset = 0,
+			.mask = MI_GLOBAL_GTT,
+			.expected = 0,
+	      }},						       ),
+	/*
+	 * MFX_WAIT doesn't fit the way we handle length for most commands.
+	 * It has a length field but it uses a non-standard length bias.
+	 * It is always 1 dword though, so just treat it as fixed length.
+	 */
+	CMD(  MFX_WAIT,                         SMFX,   F,  1,      S  ),
+};
+
+static const struct drm_i915_cmd_descriptor vecs_cmds[] = {
+	CMD(  MI_ARB_ON_OFF,                    SMI,    F,  1,      R  ),
+	CMD(  MI_SET_APPID,                     SMI,    F,  1,      S  ),
+	CMD(  MI_STORE_DWORD_IMM,               SMI,   !F,  0xFF,   B,
+	      .bits = {{
+			.offset = 0,
+			.mask = MI_GLOBAL_GTT,
+			.expected = 0,
+	      }},						       ),
+	CMD(  MI_UPDATE_GTT,                    SMI,   !F,  0x3F,   R  ),
+	CMD(  MI_FLUSH_DW,                      SMI,   !F,  0x3F,   B,
+	      .bits = {{
+			.offset = 0,
+			.mask = MI_FLUSH_DW_NOTIFY,
+			.expected = 0,
+	      },
+	      {
+			.offset = 1,
+			.mask = MI_FLUSH_DW_USE_GTT,
+			.expected = 0,
+			.condition_offset = 0,
+			.condition_mask = MI_FLUSH_DW_OP_MASK,
+	      },
+	      {
+			.offset = 0,
+			.mask = MI_FLUSH_DW_STORE_INDEX,
+			.expected = 0,
+			.condition_offset = 0,
+			.condition_mask = MI_FLUSH_DW_OP_MASK,
+	      }},						       ),
+	CMD(  MI_CONDITIONAL_BATCH_BUFFER_END,  SMI,   !F,  0xFF,   B,
+	      .bits = {{
+			.offset = 0,
+			.mask = MI_GLOBAL_GTT,
+			.expected = 0,
+	      }},						       ),
+};
+
+static const struct drm_i915_cmd_descriptor blt_cmds[] = {
+	CMD(  MI_DISPLAY_FLIP,                  SMI,   !F,  0xFF,   R  ),
+	CMD(  MI_STORE_DWORD_IMM,               SMI,   !F,  0x3FF,  B,
+	      .bits = {{
+			.offset = 0,
+			.mask = MI_GLOBAL_GTT,
+			.expected = 0,
+	      }},						       ),
+	CMD(  MI_UPDATE_GTT,                    SMI,   !F,  0x3F,   R  ),
+	CMD(  MI_FLUSH_DW,                      SMI,   !F,  0x3F,   B,
+	      .bits = {{
+			.offset = 0,
+			.mask = MI_FLUSH_DW_NOTIFY,
+			.expected = 0,
+	      },
+	      {
+			.offset = 1,
+			.mask = MI_FLUSH_DW_USE_GTT,
+			.expected = 0,
+			.condition_offset = 0,
+			.condition_mask = MI_FLUSH_DW_OP_MASK,
+	      },
+	      {
+			.offset = 0,
+			.mask = MI_FLUSH_DW_STORE_INDEX,
+			.expected = 0,
+			.condition_offset = 0,
+			.condition_mask = MI_FLUSH_DW_OP_MASK,
+	      }},						       ),
+	CMD(  COLOR_BLT,                        S2D,   !F,  0x3F,   S  ),
+	CMD(  SRC_COPY_BLT,                     S2D,   !F,  0x3F,   S  ),
+};
+
+static const struct drm_i915_cmd_descriptor hsw_blt_cmds[] = {
+	CMD(  MI_LOAD_SCAN_LINES_INCL,          SMI,   !F,  0x3F,   M  ),
+	CMD(  MI_LOAD_SCAN_LINES_EXCL,          SMI,   !F,  0x3F,   R  ),
+};
+
+#undef CMD
+#undef SMI
+#undef S3D
+#undef S2D
+#undef SMFX
+#undef F
+#undef S
+#undef R
+#undef W
+#undef B
+#undef M
+
+static const struct drm_i915_cmd_table gen7_render_cmds[] = {
+	{ common_cmds, ARRAY_SIZE(common_cmds) },
+	{ render_cmds, ARRAY_SIZE(render_cmds) },
+};
+
+static const struct drm_i915_cmd_table hsw_render_ring_cmds[] = {
+	{ common_cmds, ARRAY_SIZE(common_cmds) },
+	{ render_cmds, ARRAY_SIZE(render_cmds) },
+	{ hsw_render_cmds, ARRAY_SIZE(hsw_render_cmds) },
+};
+
+static const struct drm_i915_cmd_table gen7_video_cmds[] = {
+	{ common_cmds, ARRAY_SIZE(common_cmds) },
+	{ video_cmds, ARRAY_SIZE(video_cmds) },
+};
+
+static const struct drm_i915_cmd_table hsw_vebox_cmds[] = {
+	{ common_cmds, ARRAY_SIZE(common_cmds) },
+	{ vecs_cmds, ARRAY_SIZE(vecs_cmds) },
+};
+
+static const struct drm_i915_cmd_table gen7_blt_cmds[] = {
+	{ common_cmds, ARRAY_SIZE(common_cmds) },
+	{ blt_cmds, ARRAY_SIZE(blt_cmds) },
+};
+
+static const struct drm_i915_cmd_table hsw_blt_ring_cmds[] = {
+	{ common_cmds, ARRAY_SIZE(common_cmds) },
+	{ blt_cmds, ARRAY_SIZE(blt_cmds) },
+	{ hsw_blt_cmds, ARRAY_SIZE(hsw_blt_cmds) },
+};
+
+/*
+ * Register whitelists, sorted by increasing register offset.
+ */
+
+/*
+ * An individual whitelist entry granting access to register addr.  If
+ * mask is non-zero the argument of immediate register writes will be
+ * AND-ed with mask, and the command will be rejected if the result
+ * doesn't match value.
+ *
+ * Registers with non-zero mask are only allowed to be written using
+ * LRI.
+ */
+struct drm_i915_reg_descriptor {
+	i915_reg_t addr;
+	u32 mask;
+	u32 value;
+};
+
+/* Convenience macro for adding 32-bit registers. */
+#define REG32(_reg, ...) \
+	{ .addr = (_reg), __VA_ARGS__ }
+
+/*
+ * Convenience macro for adding 64-bit registers.
+ *
+ * Some registers that userspace accesses are 64 bits. The register
+ * access commands only allow 32-bit accesses. Hence, we have to include
+ * entries for both halves of the 64-bit registers.
+ */
+#define REG64(_reg) \
+	{ .addr = _reg }, \
+	{ .addr = _reg ## _UDW }
+
+#define REG64_IDX(_reg, idx) \
+	{ .addr = _reg(idx) }, \
+	{ .addr = _reg ## _UDW(idx) }
+
+static const struct drm_i915_reg_descriptor gen7_render_regs[] = {
+	REG64(GPGPU_THREADS_DISPATCHED),
+	REG64(HS_INVOCATION_COUNT),
+	REG64(DS_INVOCATION_COUNT),
+	REG64(IA_VERTICES_COUNT),
+	REG64(IA_PRIMITIVES_COUNT),
+	REG64(VS_INVOCATION_COUNT),
+	REG64(GS_INVOCATION_COUNT),
+	REG64(GS_PRIMITIVES_COUNT),
+	REG64(CL_INVOCATION_COUNT),
+	REG64(CL_PRIMITIVES_COUNT),
+	REG64(PS_INVOCATION_COUNT),
+	REG64(PS_DEPTH_COUNT),
+	REG64_IDX(RING_TIMESTAMP, RENDER_RING_BASE),
+	REG32(OACONTROL), /* Only allowed for LRI and SRM. See below. */
+	REG64(MI_PREDICATE_SRC0),
+	REG64(MI_PREDICATE_SRC1),
+	REG32(GEN7_3DPRIM_END_OFFSET),
+	REG32(GEN7_3DPRIM_START_VERTEX),
+	REG32(GEN7_3DPRIM_VERTEX_COUNT),
+	REG32(GEN7_3DPRIM_INSTANCE_COUNT),
+	REG32(GEN7_3DPRIM_START_INSTANCE),
+	REG32(GEN7_3DPRIM_BASE_VERTEX),
+	REG32(GEN7_GPGPU_DISPATCHDIMX),
+	REG32(GEN7_GPGPU_DISPATCHDIMY),
+	REG32(GEN7_GPGPU_DISPATCHDIMZ),
+	REG64_IDX(GEN7_SO_NUM_PRIMS_WRITTEN, 0),
+	REG64_IDX(GEN7_SO_NUM_PRIMS_WRITTEN, 1),
+	REG64_IDX(GEN7_SO_NUM_PRIMS_WRITTEN, 2),
+	REG64_IDX(GEN7_SO_NUM_PRIMS_WRITTEN, 3),
+	REG64_IDX(GEN7_SO_PRIM_STORAGE_NEEDED, 0),
+	REG64_IDX(GEN7_SO_PRIM_STORAGE_NEEDED, 1),
+	REG64_IDX(GEN7_SO_PRIM_STORAGE_NEEDED, 2),
+	REG64_IDX(GEN7_SO_PRIM_STORAGE_NEEDED, 3),
+	REG32(GEN7_SO_WRITE_OFFSET(0)),
+	REG32(GEN7_SO_WRITE_OFFSET(1)),
+	REG32(GEN7_SO_WRITE_OFFSET(2)),
+	REG32(GEN7_SO_WRITE_OFFSET(3)),
+	REG32(GEN7_L3SQCREG1),
+	REG32(GEN7_L3CNTLREG2),
+	REG32(GEN7_L3CNTLREG3),
+};
+
+static const struct drm_i915_reg_descriptor hsw_render_regs[] = {
+	REG64_IDX(HSW_CS_GPR, 0),
+	REG64_IDX(HSW_CS_GPR, 1),
+	REG64_IDX(HSW_CS_GPR, 2),
+	REG64_IDX(HSW_CS_GPR, 3),
+	REG64_IDX(HSW_CS_GPR, 4),
+	REG64_IDX(HSW_CS_GPR, 5),
+	REG64_IDX(HSW_CS_GPR, 6),
+	REG64_IDX(HSW_CS_GPR, 7),
+	REG64_IDX(HSW_CS_GPR, 8),
+	REG64_IDX(HSW_CS_GPR, 9),
+	REG64_IDX(HSW_CS_GPR, 10),
+	REG64_IDX(HSW_CS_GPR, 11),
+	REG64_IDX(HSW_CS_GPR, 12),
+	REG64_IDX(HSW_CS_GPR, 13),
+	REG64_IDX(HSW_CS_GPR, 14),
+	REG64_IDX(HSW_CS_GPR, 15),
+	REG32(HSW_SCRATCH1,
+	      .mask = ~HSW_SCRATCH1_L3_DATA_ATOMICS_DISABLE,
+	      .value = 0),
+	REG32(HSW_ROW_CHICKEN3,
+	      .mask = ~(HSW_ROW_CHICKEN3_L3_GLOBAL_ATOMICS_DISABLE << 16 |
+                        HSW_ROW_CHICKEN3_L3_GLOBAL_ATOMICS_DISABLE),
+	      .value = 0),
+};
+
+static const struct drm_i915_reg_descriptor gen7_blt_regs[] = {
+	REG32(BCS_SWCTRL),
+};
+
+static const struct drm_i915_reg_descriptor ivb_master_regs[] = {
+	REG32(FORCEWAKE_MT),
+	REG32(DERRMR),
+	REG32(GEN7_PIPE_DE_LOAD_SL(PIPE_A)),
+	REG32(GEN7_PIPE_DE_LOAD_SL(PIPE_B)),
+	REG32(GEN7_PIPE_DE_LOAD_SL(PIPE_C)),
+};
+
+static const struct drm_i915_reg_descriptor hsw_master_regs[] = {
+	REG32(FORCEWAKE_MT),
+	REG32(DERRMR),
+};
+
+#undef REG64
+#undef REG32
+
+struct drm_i915_reg_table {
+	const struct drm_i915_reg_descriptor *regs;
+	int num_regs;
+	bool master;
+};
+
+static const struct drm_i915_reg_table ivb_render_reg_tables[] = {
+	{ gen7_render_regs, ARRAY_SIZE(gen7_render_regs), false },
+	{ ivb_master_regs, ARRAY_SIZE(ivb_master_regs), true },
+};
+
+static const struct drm_i915_reg_table ivb_blt_reg_tables[] = {
+	{ gen7_blt_regs, ARRAY_SIZE(gen7_blt_regs), false },
+	{ ivb_master_regs, ARRAY_SIZE(ivb_master_regs), true },
+};
+
+static const struct drm_i915_reg_table hsw_render_reg_tables[] = {
+	{ gen7_render_regs, ARRAY_SIZE(gen7_render_regs), false },
+	{ hsw_render_regs, ARRAY_SIZE(hsw_render_regs), false },
+	{ hsw_master_regs, ARRAY_SIZE(hsw_master_regs), true },
+};
+
+static const struct drm_i915_reg_table hsw_blt_reg_tables[] = {
+	{ gen7_blt_regs, ARRAY_SIZE(gen7_blt_regs), false },
+	{ hsw_master_regs, ARRAY_SIZE(hsw_master_regs), true },
+};
+
+static u32 gen7_render_get_cmd_length_mask(u32 cmd_header)
+{
+	u32 client = (cmd_header & INSTR_CLIENT_MASK) >> INSTR_CLIENT_SHIFT;
+	u32 subclient =
+		(cmd_header & INSTR_SUBCLIENT_MASK) >> INSTR_SUBCLIENT_SHIFT;
+
+	if (client == INSTR_MI_CLIENT)
+		return 0x3F;
+	else if (client == INSTR_RC_CLIENT) {
+		if (subclient == INSTR_MEDIA_SUBCLIENT)
+			return 0xFFFF;
+		else
+			return 0xFF;
+	}
+
+	DRM_DEBUG_DRIVER("CMD: Abnormal rcs cmd length! 0x%08X\n", cmd_header);
+	return 0;
+}
+
+static u32 gen7_bsd_get_cmd_length_mask(u32 cmd_header)
+{
+	u32 client = (cmd_header & INSTR_CLIENT_MASK) >> INSTR_CLIENT_SHIFT;
+	u32 subclient =
+		(cmd_header & INSTR_SUBCLIENT_MASK) >> INSTR_SUBCLIENT_SHIFT;
+	u32 op = (cmd_header & INSTR_26_TO_24_MASK) >> INSTR_26_TO_24_SHIFT;
+
+	if (client == INSTR_MI_CLIENT)
+		return 0x3F;
+	else if (client == INSTR_RC_CLIENT) {
+		if (subclient == INSTR_MEDIA_SUBCLIENT) {
+			if (op == 6)
+				return 0xFFFF;
+			else
+				return 0xFFF;
+		} else
+			return 0xFF;
+	}
+
+	DRM_DEBUG_DRIVER("CMD: Abnormal bsd cmd length! 0x%08X\n", cmd_header);
+	return 0;
+}
+
+static u32 gen7_blt_get_cmd_length_mask(u32 cmd_header)
+{
+	u32 client = (cmd_header & INSTR_CLIENT_MASK) >> INSTR_CLIENT_SHIFT;
+
+	if (client == INSTR_MI_CLIENT)
+		return 0x3F;
+	else if (client == INSTR_BC_CLIENT)
+		return 0xFF;
+
+	DRM_DEBUG_DRIVER("CMD: Abnormal blt cmd length! 0x%08X\n", cmd_header);
+	return 0;
+}
+
+static bool validate_cmds_sorted(struct intel_engine_cs *engine,
+				 const struct drm_i915_cmd_table *cmd_tables,
+				 int cmd_table_count)
+{
+	int i;
+	bool ret = true;
+
+	if (!cmd_tables || cmd_table_count == 0)
+		return true;
+
+	for (i = 0; i < cmd_table_count; i++) {
+		const struct drm_i915_cmd_table *table = &cmd_tables[i];
+		u32 previous = 0;
+		int j;
+
+		for (j = 0; j < table->count; j++) {
+			const struct drm_i915_cmd_descriptor *desc =
+				&table->table[j];
+			u32 curr = desc->cmd.value & desc->cmd.mask;
+
+			if (curr < previous) {
+				DRM_ERROR("CMD: table not sorted ring=%d table=%d entry=%d cmd=0x%08X prev=0x%08X\n",
+					  engine->id, i, j, curr, previous);
+				ret = false;
+			}
+
+			previous = curr;
+		}
+	}
+
+	return ret;
+}
+
+static bool check_sorted(int ring_id,
+			 const struct drm_i915_reg_descriptor *reg_table,
+			 int reg_count)
+{
+	int i;
+	u32 previous = 0;
+	bool ret = true;
+
+	for (i = 0; i < reg_count; i++) {
+		u32 curr = i915_mmio_reg_offset(reg_table[i].addr);
+
+		if (curr < previous) {
+			DRM_ERROR("CMD: table not sorted ring=%d entry=%d reg=0x%08X prev=0x%08X\n",
+				  ring_id, i, curr, previous);
+			ret = false;
+		}
+
+		previous = curr;
+	}
+
+	return ret;
+}
+
+static bool validate_regs_sorted(struct intel_engine_cs *engine)
+{
+	int i;
+	const struct drm_i915_reg_table *table;
+
+	for (i = 0; i < engine->reg_table_count; i++) {
+		table = &engine->reg_tables[i];
+		if (!check_sorted(engine->id, table->regs, table->num_regs))
+			return false;
+	}
+
+	return true;
+}
+
+struct cmd_node {
+	const struct drm_i915_cmd_descriptor *desc;
+	struct hlist_node node;
+};
+
+/*
+ * Different command ranges have different numbers of bits for the opcode. For
+ * example, MI commands use bits 31:23 while 3D commands use bits 31:16. The
+ * problem is that, for example, MI commands use bits 22:16 for other fields
+ * such as GGTT vs PPGTT bits. If we include those bits in the mask then when
+ * we mask a command from a batch it could hash to the wrong bucket due to
+ * non-opcode bits being set. But if we don't include those bits, some 3D
+ * commands may hash to the same bucket due to not including opcode bits that
+ * make the command unique. For now, we will risk hashing to the same bucket.
+ *
+ * If we attempt to generate a perfect hash, we should be able to look at bits
+ * 31:29 of a command from a batch buffer and use the full mask for that
+ * client. The existing INSTR_CLIENT_MASK/SHIFT defines can be used for this.
+ */
+#define CMD_HASH_MASK STD_MI_OPCODE_MASK
+
+static int init_hash_table(struct intel_engine_cs *engine,
+			   const struct drm_i915_cmd_table *cmd_tables,
+			   int cmd_table_count)
+{
+	int i, j;
+
+	hash_init(engine->cmd_hash);
+
+	for (i = 0; i < cmd_table_count; i++) {
+		const struct drm_i915_cmd_table *table = &cmd_tables[i];
+
+		for (j = 0; j < table->count; j++) {
+			const struct drm_i915_cmd_descriptor *desc =
+				&table->table[j];
+			struct cmd_node *desc_node =
+				kmalloc(sizeof(*desc_node), GFP_KERNEL);
+
+			if (!desc_node)
+				return -ENOMEM;
+
+			desc_node->desc = desc;
+			hash_add(engine->cmd_hash, &desc_node->node,
+				 desc->cmd.value & CMD_HASH_MASK);
+		}
+	}
+
+	return 0;
+}
+
+static void fini_hash_table(struct intel_engine_cs *engine)
+{
+	struct hlist_node *tmp;
+	struct cmd_node *desc_node;
+	int i;
+
+	hash_for_each_safe(engine->cmd_hash, i, tmp, desc_node, node) {
+		hash_del(&desc_node->node);
+		kfree(desc_node);
+	}
+}
+
+/**
+ * i915_cmd_parser_init_ring() - set cmd parser related fields for a ringbuffer
+ * @ring: the ringbuffer to initialize
+ *
+ * Optionally initializes fields related to batch buffer command parsing in the
+ * struct intel_engine_cs based on whether the platform requires software
+ * command parsing.
+ *
+ * Return: non-zero if initialization fails
+ */
+int i915_cmd_parser_init_ring(struct intel_engine_cs *engine)
+{
+	const struct drm_i915_cmd_table *cmd_tables;
+	int cmd_table_count;
+	int ret;
+
+	if (!IS_GEN7(engine->dev))
+		return 0;
+
+	switch (engine->id) {
+	case RCS:
+		if (IS_HASWELL(engine->dev)) {
+			cmd_tables = hsw_render_ring_cmds;
+			cmd_table_count =
+				ARRAY_SIZE(hsw_render_ring_cmds);
+		} else {
+			cmd_tables = gen7_render_cmds;
+			cmd_table_count = ARRAY_SIZE(gen7_render_cmds);
+		}
+
+		if (IS_HASWELL(engine->dev)) {
+			engine->reg_tables = hsw_render_reg_tables;
+			engine->reg_table_count = ARRAY_SIZE(hsw_render_reg_tables);
+		} else {
+			engine->reg_tables = ivb_render_reg_tables;
+			engine->reg_table_count = ARRAY_SIZE(ivb_render_reg_tables);
+		}
+
+		engine->get_cmd_length_mask = gen7_render_get_cmd_length_mask;
+		break;
+	case VCS:
+		cmd_tables = gen7_video_cmds;
+		cmd_table_count = ARRAY_SIZE(gen7_video_cmds);
+		engine->get_cmd_length_mask = gen7_bsd_get_cmd_length_mask;
+		break;
+	case BCS:
+		if (IS_HASWELL(engine->dev)) {
+			cmd_tables = hsw_blt_ring_cmds;
+			cmd_table_count = ARRAY_SIZE(hsw_blt_ring_cmds);
+		} else {
+			cmd_tables = gen7_blt_cmds;
+			cmd_table_count = ARRAY_SIZE(gen7_blt_cmds);
+		}
+
+		if (IS_HASWELL(engine->dev)) {
+			engine->reg_tables = hsw_blt_reg_tables;
+			engine->reg_table_count = ARRAY_SIZE(hsw_blt_reg_tables);
+		} else {
+			engine->reg_tables = ivb_blt_reg_tables;
+			engine->reg_table_count = ARRAY_SIZE(ivb_blt_reg_tables);
+		}
+
+		engine->get_cmd_length_mask = gen7_blt_get_cmd_length_mask;
+		break;
+	case VECS:
+		cmd_tables = hsw_vebox_cmds;
+		cmd_table_count = ARRAY_SIZE(hsw_vebox_cmds);
+		/* VECS can use the same length_mask function as VCS */
+		engine->get_cmd_length_mask = gen7_bsd_get_cmd_length_mask;
+		break;
+	default:
+		DRM_ERROR("CMD: cmd_parser_init with unknown ring: %d\n",
+			  engine->id);
+		BUG();
+	}
+
+	BUG_ON(!validate_cmds_sorted(engine, cmd_tables, cmd_table_count));
+	BUG_ON(!validate_regs_sorted(engine));
+
+	WARN_ON(!hash_empty(engine->cmd_hash));
+
+	ret = init_hash_table(engine, cmd_tables, cmd_table_count);
+	if (ret) {
+		DRM_ERROR("CMD: cmd_parser_init failed!\n");
+		fini_hash_table(engine);
+		return ret;
+	}
+
+	engine->needs_cmd_parser = true;
+
+	return 0;
+}
+
+/**
+ * i915_cmd_parser_fini_ring() - clean up cmd parser related fields
+ * @ring: the ringbuffer to clean up
+ *
+ * Releases any resources related to command parsing that may have been
+ * initialized for the specified ring.
+ */
+void i915_cmd_parser_fini_ring(struct intel_engine_cs *engine)
+{
+	if (!engine->needs_cmd_parser)
+		return;
+
+	fini_hash_table(engine);
+}
+
+static const struct drm_i915_cmd_descriptor*
+find_cmd_in_table(struct intel_engine_cs *engine,
+		  u32 cmd_header)
+{
+	struct cmd_node *desc_node;
+
+	hash_for_each_possible(engine->cmd_hash, desc_node, node,
+			       cmd_header & CMD_HASH_MASK) {
+		const struct drm_i915_cmd_descriptor *desc = desc_node->desc;
+		u32 masked_cmd = desc->cmd.mask & cmd_header;
+		u32 masked_value = desc->cmd.value & desc->cmd.mask;
+
+		if (masked_cmd == masked_value)
+			return desc;
+	}
+
+	return NULL;
+}
+
+/*
+ * Returns a pointer to a descriptor for the command specified by cmd_header.
+ *
+ * The caller must supply space for a default descriptor via the default_desc
+ * parameter. If no descriptor for the specified command exists in the ring's
+ * command parser tables, this function fills in default_desc based on the
+ * ring's default length encoding and returns default_desc.
+ */
+static const struct drm_i915_cmd_descriptor*
+find_cmd(struct intel_engine_cs *engine,
+	 u32 cmd_header,
+	 struct drm_i915_cmd_descriptor *default_desc)
+{
+	const struct drm_i915_cmd_descriptor *desc;
+	u32 mask;
+
+	desc = find_cmd_in_table(engine, cmd_header);
+	if (desc)
+		return desc;
+
+	mask = engine->get_cmd_length_mask(cmd_header);
+	if (!mask)
+		return NULL;
+
+	BUG_ON(!default_desc);
+	default_desc->flags = CMD_DESC_SKIP;
+	default_desc->length.mask = mask;
+
+	return default_desc;
+}
+
+static const struct drm_i915_reg_descriptor *
+find_reg(const struct drm_i915_reg_descriptor *table,
+	 int count, u32 addr)
+{
+	int i;
+
+	for (i = 0; i < count; i++) {
+		if (i915_mmio_reg_offset(table[i].addr) == addr)
+			return &table[i];
+	}
+
+	return NULL;
+}
+
+static const struct drm_i915_reg_descriptor *
+find_reg_in_tables(const struct drm_i915_reg_table *tables,
+		   int count, bool is_master, u32 addr)
+{
+	int i;
+	const struct drm_i915_reg_table *table;
+	const struct drm_i915_reg_descriptor *reg;
+
+	for (i = 0; i < count; i++) {
+		table = &tables[i];
+		if (!table->master || is_master) {
+			reg = find_reg(table->regs, table->num_regs,
+				       addr);
+			if (reg != NULL)
+				return reg;
+		}
+	}
+
+	return NULL;
+}
+
+static u32 *vmap_batch(struct drm_i915_gem_object *obj,
+		       unsigned start, unsigned len)
+{
+	int i;
+	void *addr = NULL;
+	struct sg_page_iter sg_iter;
+	int first_page = start >> PAGE_SHIFT;
+	int last_page = (len + start + 4095) >> PAGE_SHIFT;
+	int npages = last_page - first_page;
+	struct page **pages;
+
+	pages = drm_malloc_ab(npages, sizeof(*pages));
+	if (pages == NULL) {
+		DRM_DEBUG_DRIVER("Failed to get space for pages\n");
+		goto finish;
+	}
+
+	i = 0;
+	for_each_sg_page(obj->pages->sgl, &sg_iter, obj->pages->nents, first_page) {
+		pages[i++] = sg_page_iter_page(&sg_iter);
+		if (i == npages)
+			break;
+	}
+
+	addr = vmap(pages, i, 0, PAGE_KERNEL);
+	if (addr == NULL) {
+		DRM_DEBUG_DRIVER("Failed to vmap pages\n");
+		goto finish;
+	}
+
+finish:
+	if (pages)
+		drm_free_large(pages);
+	return (u32*)addr;
+}
+
+/* Returns a vmap'd pointer to dest_obj, which the caller must unmap */
+static u32 *copy_batch(struct drm_i915_gem_object *dest_obj,
+		       struct drm_i915_gem_object *src_obj,
+		       u32 batch_start_offset,
+		       u32 batch_len)
+{
+	int needs_clflush = 0;
+	void *src_base, *src;
+	void *dst = NULL;
+	int ret;
+
+	if (batch_len > dest_obj->base.size ||
+	    batch_len + batch_start_offset > src_obj->base.size)
+		return ERR_PTR(-E2BIG);
+
+	if (WARN_ON(dest_obj->pages_pin_count == 0))
+		return ERR_PTR(-ENODEV);
+
+	ret = i915_gem_obj_prepare_shmem_read(src_obj, &needs_clflush);
+	if (ret) {
+		DRM_DEBUG_DRIVER("CMD: failed to prepare shadow batch\n");
+		return ERR_PTR(ret);
+	}
+
+	src_base = vmap_batch(src_obj, batch_start_offset, batch_len);
+	if (!src_base) {
+		DRM_DEBUG_DRIVER("CMD: Failed to vmap batch\n");
+		ret = -ENOMEM;
+		goto unpin_src;
+	}
+
+	ret = i915_gem_object_set_to_cpu_domain(dest_obj, true);
+	if (ret) {
+		DRM_DEBUG_DRIVER("CMD: Failed to set shadow batch to CPU\n");
+		goto unmap_src;
+	}
+
+	dst = vmap_batch(dest_obj, 0, batch_len);
+	if (!dst) {
+		DRM_DEBUG_DRIVER("CMD: Failed to vmap shadow batch\n");
+		ret = -ENOMEM;
+		goto unmap_src;
+	}
+
+	src = src_base + offset_in_page(batch_start_offset);
+	if (needs_clflush)
+		drm_clflush_virt_range(src, batch_len);
+
+	memcpy(dst, src, batch_len);
+
+unmap_src:
+	vunmap(src_base);
+unpin_src:
+	i915_gem_object_unpin_pages(src_obj);
+
+	return ret ? ERR_PTR(ret) : dst;
+}
+
+/**
+ * i915_needs_cmd_parser() - should a given ring use software command parsing?
+ * @ring: the ring in question
+ *
+ * Only certain platforms require software batch buffer command parsing, and
+ * only when enabled via module parameter.
+ *
+ * Return: true if the ring requires software command parsing
+ */
+bool i915_needs_cmd_parser(struct intel_engine_cs *engine)
+{
+	if (!engine->needs_cmd_parser)
+		return false;
+
+	if (!USES_PPGTT(engine->dev))
+		return false;
+
+	return (i915.enable_cmd_parser == 1);
+}
+
+static bool check_cmd(const struct intel_engine_cs *engine,
+		      const struct drm_i915_cmd_descriptor *desc,
+		      const u32 *cmd, u32 length,
+		      const bool is_master,
+		      bool *oacontrol_set)
+{
+	if (desc->flags & CMD_DESC_REJECT) {
+		DRM_DEBUG_DRIVER("CMD: Rejected command: 0x%08X\n", *cmd);
+		return false;
+	}
+
+	if ((desc->flags & CMD_DESC_MASTER) && !is_master) {
+		DRM_DEBUG_DRIVER("CMD: Rejected master-only command: 0x%08X\n",
+				 *cmd);
+		return false;
+	}
+
+	if (desc->flags & CMD_DESC_REGISTER) {
+		/*
+		 * Get the distance between individual register offset
+		 * fields if the command can perform more than one
+		 * access at a time.
+		 */
+		const u32 step = desc->reg.step ? desc->reg.step : length;
+		u32 offset;
+
+		for (offset = desc->reg.offset; offset < length;
+		     offset += step) {
+			const u32 reg_addr = cmd[offset] & desc->reg.mask;
+			const struct drm_i915_reg_descriptor *reg =
+				find_reg_in_tables(engine->reg_tables,
+						   engine->reg_table_count,
+						   is_master,
+						   reg_addr);
+
+			if (!reg) {
+				DRM_DEBUG_DRIVER("CMD: Rejected register 0x%08X in command: 0x%08X (ring=%d)\n",
+						 reg_addr, *cmd, engine->id);
+				return false;
+			}
+
+			/*
+			 * OACONTROL requires some special handling for
+			 * writes. We want to make sure that any batch which
+			 * enables OA also disables it before the end of the
+			 * batch. The goal is to prevent one process from
+			 * snooping on the perf data from another process. To do
+			 * that, we need to check the value that will be written
+			 * to the register. Hence, limit OACONTROL writes to
+			 * only MI_LOAD_REGISTER_IMM commands.
+			 */
+			if (reg_addr == i915_mmio_reg_offset(OACONTROL)) {
+				if (desc->cmd.value == MI_LOAD_REGISTER_MEM) {
+					DRM_DEBUG_DRIVER("CMD: Rejected LRM to OACONTROL\n");
+					return false;
+				}
+
+				if (desc->cmd.value == MI_LOAD_REGISTER_IMM(1))
+					*oacontrol_set = (cmd[offset + 1] != 0);
+			}
+
+			/*
+			 * Check the value written to the register against the
+			 * allowed mask/value pair given in the whitelist entry.
+			 */
+			if (reg->mask) {
+				if (desc->cmd.value == MI_LOAD_REGISTER_MEM) {
+					DRM_DEBUG_DRIVER("CMD: Rejected LRM to masked register 0x%08X\n",
+							 reg_addr);
+					return false;
+				}
+
+				if (desc->cmd.value == MI_LOAD_REGISTER_IMM(1) &&
+				    (offset + 2 > length ||
+				     (cmd[offset + 1] & reg->mask) != reg->value)) {
+					DRM_DEBUG_DRIVER("CMD: Rejected LRI to masked register 0x%08X\n",
+							 reg_addr);
+					return false;
+				}
+			}
+		}
+	}
+
+	if (desc->flags & CMD_DESC_BITMASK) {
+		int i;
+
+		for (i = 0; i < MAX_CMD_DESC_BITMASKS; i++) {
+			u32 dword;
+
+			if (desc->bits[i].mask == 0)
+				break;
+
+			if (desc->bits[i].condition_mask != 0) {
+				u32 offset =
+					desc->bits[i].condition_offset;
+				u32 condition = cmd[offset] &
+					desc->bits[i].condition_mask;
+
+				if (condition == 0)
+					continue;
+			}
+
+			dword = cmd[desc->bits[i].offset] &
+				desc->bits[i].mask;
+
+			if (dword != desc->bits[i].expected) {
+				DRM_DEBUG_DRIVER("CMD: Rejected command 0x%08X for bitmask 0x%08X (exp=0x%08X act=0x%08X) (ring=%d)\n",
+						 *cmd,
+						 desc->bits[i].mask,
+						 desc->bits[i].expected,
+						 dword, engine->id);
+				return false;
+			}
+		}
+	}
+
+	return true;
+}
+
+#define LENGTH_BIAS 2
+
+/**
+ * i915_parse_cmds() - parse a submitted batch buffer for privilege violations
+ * @ring: the ring on which the batch is to execute
+ * @batch_obj: the batch buffer in question
+ * @shadow_batch_obj: copy of the batch buffer in question
+ * @batch_start_offset: byte offset in the batch at which execution starts
+ * @batch_len: length of the commands in batch_obj
+ * @is_master: is the submitting process the drm master?
+ *
+ * Parses the specified batch buffer looking for privilege violations as
+ * described in the overview.
+ *
+ * Return: non-zero if the parser finds violations or otherwise fails; -EACCES
+ * if the batch appears legal but should use hardware parsing
+ */
+int i915_parse_cmds(struct intel_engine_cs *engine,
+		    struct drm_i915_gem_object *batch_obj,
+		    struct drm_i915_gem_object *shadow_batch_obj,
+		    u32 batch_start_offset,
+		    u32 batch_len,
+		    bool is_master)
+{
+	u32 *cmd, *batch_base, *batch_end;
+	struct drm_i915_cmd_descriptor default_desc = { 0 };
+	bool oacontrol_set = false; /* OACONTROL tracking. See check_cmd() */
+	int ret = 0;
+
+	batch_base = copy_batch(shadow_batch_obj, batch_obj,
+				batch_start_offset, batch_len);
+	if (IS_ERR(batch_base)) {
+		DRM_DEBUG_DRIVER("CMD: Failed to copy batch\n");
+		return PTR_ERR(batch_base);
+	}
+
+	/*
+	 * We use the batch length as size because the shadow object is as
+	 * large or larger and copy_batch() will write MI_NOPs to the extra
+	 * space. Parsing should be faster in some cases this way.
+	 */
+	batch_end = batch_base + (batch_len / sizeof(*batch_end));
+
+	cmd = batch_base;
+	while (cmd < batch_end) {
+		const struct drm_i915_cmd_descriptor *desc;
+		u32 length;
+
+		if (*cmd == MI_BATCH_BUFFER_END)
+			break;
+
+		desc = find_cmd(engine, *cmd, &default_desc);
+		if (!desc) {
+			DRM_DEBUG_DRIVER("CMD: Unrecognized command: 0x%08X\n",
+					 *cmd);
+			ret = -EINVAL;
+			break;
+		}
+
+		/*
+		 * If the batch buffer contains a chained batch, return an
+		 * error that tells the caller to abort and dispatch the
+		 * workload as a non-secure batch.
+		 */
+		if (desc->cmd.value == MI_BATCH_BUFFER_START) {
+			ret = -EACCES;
+			break;
+		}
+
+		if (desc->flags & CMD_DESC_FIXED)
+			length = desc->length.fixed;
+		else
+			length = ((*cmd & desc->length.mask) + LENGTH_BIAS);
+
+		if ((batch_end - cmd) < length) {
+			DRM_DEBUG_DRIVER("CMD: Command length exceeds batch length: 0x%08X length=%u batchlen=%td\n",
+					 *cmd,
+					 length,
+					 batch_end - cmd);
+			ret = -EINVAL;
+			break;
+		}
+
+		if (!check_cmd(engine, desc, cmd, length, is_master,
+			       &oacontrol_set)) {
+			ret = -EINVAL;
+			break;
+		}
+
+		cmd += length;
+	}
+
+	if (oacontrol_set) {
+		DRM_DEBUG_DRIVER("CMD: batch set OACONTROL but did not clear it\n");
+		ret = -EINVAL;
+	}
+
+	if (cmd >= batch_end) {
+		DRM_DEBUG_DRIVER("CMD: Got to the end of the buffer w/o a BBE cmd!\n");
+		ret = -EINVAL;
+	}
+
+	vunmap(batch_base);
+
+	return ret;
+}
+
+/**
+ * i915_cmd_parser_get_version() - get the cmd parser version number
+ *
+ * The cmd parser maintains a simple increasing integer version number suitable
+ * for passing to userspace clients to determine what operations are permitted.
+ *
+ * Return: the current version number of the cmd parser
+ */
+int i915_cmd_parser_get_version(void)
+{
+	/*
+	 * Command parser version history
+	 *
+	 * 1. Initial version. Checks batches and reports violations, but leaves
+	 *    hardware parsing enabled (so does not allow new use cases).
+	 * 2. Allow access to the MI_PREDICATE_SRC0 and
+	 *    MI_PREDICATE_SRC1 registers.
+	 * 3. Allow access to the GPGPU_THREADS_DISPATCHED register.
+	 * 4. L3 atomic chicken bits of HSW_SCRATCH1 and HSW_ROW_CHICKEN3.
+	 * 5. GPGPU dispatch compute indirect registers.
+	 * 6. TIMESTAMP register and Haswell CS GPR registers
+	 */
+	return 6;
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/i915/i915_debugfs.c
@@ -0,0 +1,5614 @@
+/*
+ * Copyright © 2008 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Eric Anholt <eric@anholt.net>
+ *    Keith Packard <keithp@keithp.com>
+ *
+ */
+
+#include <linux/seq_file.h>
+#include <linux/circ_buf.h>
+#include <linux/ctype.h>
+#include <linux/debugfs.h>
+#include <linux/slab.h>
+#include <linux/export.h>
+#include <linux/list_sort.h>
+#include <asm/msr-index.h>
+#include <drm/drmP.h>
+#include "intel_drv.h"
+#include "intel_ringbuffer.h"
+#include <drm/i915_drm.h>
+#include "i915_drv.h"
+
+enum {
+	ACTIVE_LIST,
+	INACTIVE_LIST,
+	PINNED_LIST,
+};
+
+/* As the drm_debugfs_init() routines are called before dev->dev_private is
+ * allocated we need to hook into the minor for release. */
+static int
+drm_add_fake_info_node(struct drm_minor *minor,
+		       struct dentry *ent,
+		       const void *key)
+{
+	struct drm_info_node *node;
+
+	node = kmalloc(sizeof(*node), GFP_KERNEL);
+	if (node == NULL) {
+		debugfs_remove(ent);
+		return -ENOMEM;
+	}
+
+	node->minor = minor;
+	node->dent = ent;
+	node->info_ent = (void *) key;
+
+	mutex_lock(&minor->debugfs_lock);
+	list_add(&node->list, &minor->debugfs_list);
+	mutex_unlock(&minor->debugfs_lock);
+
+	return 0;
+}
+
+static int i915_capabilities(struct seq_file *m, void *data)
+{
+	struct drm_info_node *node = m->private;
+	struct drm_device *dev = node->minor->dev;
+	const struct intel_device_info *info = INTEL_INFO(dev);
+
+	seq_printf(m, "gen: %d\n", info->gen);
+	seq_printf(m, "pch: %d\n", INTEL_PCH_TYPE(dev));
+#define PRINT_FLAG(x)  seq_printf(m, #x ": %s\n", yesno(info->x))
+#define SEP_SEMICOLON ;
+	DEV_INFO_FOR_EACH_FLAG(PRINT_FLAG, SEP_SEMICOLON);
+#undef PRINT_FLAG
+#undef SEP_SEMICOLON
+
+	return 0;
+}
+
+static const char get_active_flag(struct drm_i915_gem_object *obj)
+{
+	return obj->active ? '*' : ' ';
+}
+
+static const char get_pin_flag(struct drm_i915_gem_object *obj)
+{
+	return obj->pin_display ? 'p' : ' ';
+}
+
+static const char get_tiling_flag(struct drm_i915_gem_object *obj)
+{
+	switch (obj->tiling_mode) {
+	default:
+	case I915_TILING_NONE: return ' ';
+	case I915_TILING_X: return 'X';
+	case I915_TILING_Y: return 'Y';
+	}
+}
+
+static inline const char get_global_flag(struct drm_i915_gem_object *obj)
+{
+	return i915_gem_obj_to_ggtt(obj) ? 'g' : ' ';
+}
+
+static inline const char get_pin_mapped_flag(struct drm_i915_gem_object *obj)
+{
+	return obj->mapping ? 'M' : ' ';
+}
+
+static u64 i915_gem_obj_total_ggtt_size(struct drm_i915_gem_object *obj)
+{
+	u64 size = 0;
+	struct i915_vma *vma;
+
+	list_for_each_entry(vma, &obj->vma_list, obj_link) {
+		if (vma->is_ggtt && drm_mm_node_allocated(&vma->node))
+			size += vma->node.size;
+	}
+
+	return size;
+}
+
+static void
+describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj)
+{
+	struct drm_i915_private *dev_priv = to_i915(obj->base.dev);
+	struct intel_engine_cs *engine;
+	struct i915_vma *vma;
+	int pin_count = 0;
+	enum intel_engine_id id;
+
+	lockdep_assert_held(&obj->base.dev->struct_mutex);
+
+	seq_printf(m, "%pK: %c%c%c%c%c %8zdKiB %02x %02x [ ",
+		   &obj->base,
+		   get_active_flag(obj),
+		   get_pin_flag(obj),
+		   get_tiling_flag(obj),
+		   get_global_flag(obj),
+		   get_pin_mapped_flag(obj),
+		   obj->base.size / 1024,
+		   obj->base.read_domains,
+		   obj->base.write_domain);
+	for_each_engine_id(engine, dev_priv, id)
+		seq_printf(m, "%x ",
+				i915_gem_request_get_seqno(obj->last_read_req[id]));
+	seq_printf(m, "] %x %x%s%s%s",
+		   i915_gem_request_get_seqno(obj->last_write_req),
+		   i915_gem_request_get_seqno(obj->last_fenced_req),
+		   i915_cache_level_str(to_i915(obj->base.dev), obj->cache_level),
+		   obj->dirty ? " dirty" : "",
+		   obj->madv == I915_MADV_DONTNEED ? " purgeable" : "");
+	if (obj->base.name)
+		seq_printf(m, " (name: %d)", obj->base.name);
+	list_for_each_entry(vma, &obj->vma_list, obj_link) {
+		if (vma->pin_count > 0)
+			pin_count++;
+	}
+	seq_printf(m, " (pinned x %d)", pin_count);
+	if (obj->pin_display)
+		seq_printf(m, " (display)");
+	if (obj->fence_reg != I915_FENCE_REG_NONE)
+		seq_printf(m, " (fence: %d)", obj->fence_reg);
+	list_for_each_entry(vma, &obj->vma_list, obj_link) {
+		seq_printf(m, " (%sgtt offset: %08llx, size: %08llx",
+			   vma->is_ggtt ? "g" : "pp",
+			   vma->node.start, vma->node.size);
+		if (vma->is_ggtt)
+			seq_printf(m, ", type: %u", vma->ggtt_view.type);
+		seq_puts(m, ")");
+	}
+	if (obj->stolen)
+		seq_printf(m, " (stolen: %08llx)", obj->stolen->start);
+	if (obj->pin_display || obj->fault_mappable) {
+		char s[3], *t = s;
+		if (obj->pin_display)
+			*t++ = 'p';
+		if (obj->fault_mappable)
+			*t++ = 'f';
+		*t = '\0';
+		seq_printf(m, " (%s mappable)", s);
+	}
+	if (obj->last_write_req != NULL)
+		seq_printf(m, " (%s)",
+			   i915_gem_request_get_engine(obj->last_write_req)->name);
+	if (obj->frontbuffer_bits)
+		seq_printf(m, " (frontbuffer: 0x%03x)", obj->frontbuffer_bits);
+}
+
+static void describe_ctx(struct seq_file *m, struct intel_context *ctx)
+{
+	seq_putc(m, ctx->legacy_hw_ctx.initialized ? 'I' : 'i');
+	seq_putc(m, ctx->remap_slice ? 'R' : 'r');
+	seq_putc(m, ' ');
+}
+
+static int i915_gem_object_list_info(struct seq_file *m, void *data)
+{
+	struct drm_info_node *node = m->private;
+	uintptr_t list = (uintptr_t) node->info_ent->data;
+	struct list_head *head;
+	struct drm_device *dev = node->minor->dev;
+	struct drm_i915_private *dev_priv = to_i915(dev);
+	struct i915_ggtt *ggtt = &dev_priv->ggtt;
+	struct i915_vma *vma;
+	u64 total_obj_size, total_gtt_size;
+	int count, ret;
+
+	ret = mutex_lock_interruptible(&dev->struct_mutex);
+	if (ret)
+		return ret;
+
+	/* FIXME: the user of this interface might want more than just GGTT */
+	switch (list) {
+	case ACTIVE_LIST:
+		seq_puts(m, "Active:\n");
+		head = &ggtt->base.active_list;
+		break;
+	case INACTIVE_LIST:
+		seq_puts(m, "Inactive:\n");
+		head = &ggtt->base.inactive_list;
+		break;
+	default:
+		mutex_unlock(&dev->struct_mutex);
+		return -EINVAL;
+	}
+
+	total_obj_size = total_gtt_size = count = 0;
+	list_for_each_entry(vma, head, vm_link) {
+		seq_printf(m, "   ");
+		describe_obj(m, vma->obj);
+		seq_printf(m, "\n");
+		total_obj_size += vma->obj->base.size;
+		total_gtt_size += vma->node.size;
+		count++;
+	}
+	mutex_unlock(&dev->struct_mutex);
+
+	seq_printf(m, "Total %d objects, %llu bytes, %llu GTT size\n",
+		   count, total_obj_size, total_gtt_size);
+	return 0;
+}
+
+static int obj_rank_by_stolen(void *priv,
+			      struct list_head *A, struct list_head *B)
+{
+	struct drm_i915_gem_object *a =
+		container_of(A, struct drm_i915_gem_object, obj_exec_link);
+	struct drm_i915_gem_object *b =
+		container_of(B, struct drm_i915_gem_object, obj_exec_link);
+
+	if (a->stolen->start < b->stolen->start)
+		return -1;
+	if (a->stolen->start > b->stolen->start)
+		return 1;
+	return 0;
+}
+
+static int i915_gem_stolen_list_info(struct seq_file *m, void *data)
+{
+	struct drm_info_node *node = m->private;
+	struct drm_device *dev = node->minor->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct drm_i915_gem_object *obj;
+	u64 total_obj_size, total_gtt_size;
+	LIST_HEAD(stolen);
+	int count, ret;
+
+	ret = mutex_lock_interruptible(&dev->struct_mutex);
+	if (ret)
+		return ret;
+
+	total_obj_size = total_gtt_size = count = 0;
+	list_for_each_entry(obj, &dev_priv->mm.bound_list, global_list) {
+		if (obj->stolen == NULL)
+			continue;
+
+		list_add(&obj->obj_exec_link, &stolen);
+
+		total_obj_size += obj->base.size;
+		total_gtt_size += i915_gem_obj_total_ggtt_size(obj);
+		count++;
+	}
+	list_for_each_entry(obj, &dev_priv->mm.unbound_list, global_list) {
+		if (obj->stolen == NULL)
+			continue;
+
+		list_add(&obj->obj_exec_link, &stolen);
+
+		total_obj_size += obj->base.size;
+		count++;
+	}
+	list_sort(NULL, &stolen, obj_rank_by_stolen);
+	seq_puts(m, "Stolen:\n");
+	while (!list_empty(&stolen)) {
+		obj = list_first_entry(&stolen, typeof(*obj), obj_exec_link);
+		seq_puts(m, "   ");
+		describe_obj(m, obj);
+		seq_putc(m, '\n');
+		list_del_init(&obj->obj_exec_link);
+	}
+	mutex_unlock(&dev->struct_mutex);
+
+	seq_printf(m, "Total %d objects, %llu bytes, %llu GTT size\n",
+		   count, total_obj_size, total_gtt_size);
+	return 0;
+}
+
+#define count_objects(list, member) do { \
+	list_for_each_entry(obj, list, member) { \
+		size += i915_gem_obj_total_ggtt_size(obj); \
+		++count; \
+		if (obj->map_and_fenceable) { \
+			mappable_size += i915_gem_obj_ggtt_size(obj); \
+			++mappable_count; \
+		} \
+	} \
+} while (0)
+
+struct file_stats {
+	struct drm_i915_file_private *file_priv;
+	unsigned long count;
+	u64 total, unbound;
+	u64 global, shared;
+	u64 active, inactive;
+};
+
+static int per_file_stats(int id, void *ptr, void *data)
+{
+	struct drm_i915_gem_object *obj = ptr;
+	struct file_stats *stats = data;
+	struct i915_vma *vma;
+
+	stats->count++;
+	stats->total += obj->base.size;
+
+	if (obj->base.name || obj->base.dma_buf)
+		stats->shared += obj->base.size;
+
+	if (USES_FULL_PPGTT(obj->base.dev)) {
+		list_for_each_entry(vma, &obj->vma_list, obj_link) {
+			struct i915_hw_ppgtt *ppgtt;
+
+			if (!drm_mm_node_allocated(&vma->node))
+				continue;
+
+			if (vma->is_ggtt) {
+				stats->global += obj->base.size;
+				continue;
+			}
+
+			ppgtt = container_of(vma->vm, struct i915_hw_ppgtt, base);
+			if (ppgtt->file_priv != stats->file_priv)
+				continue;
+
+			if (obj->active) /* XXX per-vma statistic */
+				stats->active += obj->base.size;
+			else
+				stats->inactive += obj->base.size;
+
+			return 0;
+		}
+	} else {
+		if (i915_gem_obj_ggtt_bound(obj)) {
+			stats->global += obj->base.size;
+			if (obj->active)
+				stats->active += obj->base.size;
+			else
+				stats->inactive += obj->base.size;
+			return 0;
+		}
+	}
+
+	if (!list_empty(&obj->global_list))
+		stats->unbound += obj->base.size;
+
+	return 0;
+}
+
+#define print_file_stats(m, name, stats) do { \
+	if (stats.count) \
+		seq_printf(m, "%s: %lu objects, %llu bytes (%llu active, %llu inactive, %llu global, %llu shared, %llu unbound)\n", \
+			   name, \
+			   stats.count, \
+			   stats.total, \
+			   stats.active, \
+			   stats.inactive, \
+			   stats.global, \
+			   stats.shared, \
+			   stats.unbound); \
+} while (0)
+
+static void print_batch_pool_stats(struct seq_file *m,
+				   struct drm_i915_private *dev_priv)
+{
+	struct drm_i915_gem_object *obj;
+	struct file_stats stats;
+	struct intel_engine_cs *engine;
+	int j;
+
+	memset(&stats, 0, sizeof(stats));
+
+	for_each_engine(engine, dev_priv) {
+		for (j = 0; j < ARRAY_SIZE(engine->batch_pool.cache_list); j++) {
+			list_for_each_entry(obj,
+					    &engine->batch_pool.cache_list[j],
+					    batch_pool_link)
+				per_file_stats(0, obj, &stats);
+		}
+	}
+
+	print_file_stats(m, "[k]batch pool", stats);
+}
+
+#define count_vmas(list, member) do { \
+	list_for_each_entry(vma, list, member) { \
+		size += i915_gem_obj_total_ggtt_size(vma->obj); \
+		++count; \
+		if (vma->obj->map_and_fenceable) { \
+			mappable_size += i915_gem_obj_ggtt_size(vma->obj); \
+			++mappable_count; \
+		} \
+	} \
+} while (0)
+
+static int i915_gem_object_info(struct seq_file *m, void* data)
+{
+	struct drm_info_node *node = m->private;
+	struct drm_device *dev = node->minor->dev;
+	struct drm_i915_private *dev_priv = to_i915(dev);
+	struct i915_ggtt *ggtt = &dev_priv->ggtt;
+	u32 count, mappable_count, purgeable_count;
+	u64 size, mappable_size, purgeable_size;
+	unsigned long pin_mapped_count = 0, pin_mapped_purgeable_count = 0;
+	u64 pin_mapped_size = 0, pin_mapped_purgeable_size = 0;
+	struct drm_i915_gem_object *obj;
+	struct drm_file *file;
+	struct i915_vma *vma;
+	int ret;
+
+	ret = mutex_lock_interruptible(&dev->struct_mutex);
+	if (ret)
+		return ret;
+
+	seq_printf(m, "%u objects, %zu bytes\n",
+		   dev_priv->mm.object_count,
+		   dev_priv->mm.object_memory);
+
+	size = count = mappable_size = mappable_count = 0;
+	count_objects(&dev_priv->mm.bound_list, global_list);
+	seq_printf(m, "%u [%u] objects, %llu [%llu] bytes in gtt\n",
+		   count, mappable_count, size, mappable_size);
+
+	size = count = mappable_size = mappable_count = 0;
+	count_vmas(&ggtt->base.active_list, vm_link);
+	seq_printf(m, "  %u [%u] active objects, %llu [%llu] bytes\n",
+		   count, mappable_count, size, mappable_size);
+
+	size = count = mappable_size = mappable_count = 0;
+	count_vmas(&ggtt->base.inactive_list, vm_link);
+	seq_printf(m, "  %u [%u] inactive objects, %llu [%llu] bytes\n",
+		   count, mappable_count, size, mappable_size);
+
+	size = count = purgeable_size = purgeable_count = 0;
+	list_for_each_entry(obj, &dev_priv->mm.unbound_list, global_list) {
+		size += obj->base.size, ++count;
+		if (obj->madv == I915_MADV_DONTNEED)
+			purgeable_size += obj->base.size, ++purgeable_count;
+		if (obj->mapping) {
+			pin_mapped_count++;
+			pin_mapped_size += obj->base.size;
+			if (obj->pages_pin_count == 0) {
+				pin_mapped_purgeable_count++;
+				pin_mapped_purgeable_size += obj->base.size;
+			}
+		}
+	}
+	seq_printf(m, "%u unbound objects, %llu bytes\n", count, size);
+
+	size = count = mappable_size = mappable_count = 0;
+	list_for_each_entry(obj, &dev_priv->mm.bound_list, global_list) {
+		if (obj->fault_mappable) {
+			size += i915_gem_obj_ggtt_size(obj);
+			++count;
+		}
+		if (obj->pin_display) {
+			mappable_size += i915_gem_obj_ggtt_size(obj);
+			++mappable_count;
+		}
+		if (obj->madv == I915_MADV_DONTNEED) {
+			purgeable_size += obj->base.size;
+			++purgeable_count;
+		}
+		if (obj->mapping) {
+			pin_mapped_count++;
+			pin_mapped_size += obj->base.size;
+			if (obj->pages_pin_count == 0) {
+				pin_mapped_purgeable_count++;
+				pin_mapped_purgeable_size += obj->base.size;
+			}
+		}
+	}
+	seq_printf(m, "%u purgeable objects, %llu bytes\n",
+		   purgeable_count, purgeable_size);
+	seq_printf(m, "%u pinned mappable objects, %llu bytes\n",
+		   mappable_count, mappable_size);
+	seq_printf(m, "%u fault mappable objects, %llu bytes\n",
+		   count, size);
+	seq_printf(m,
+		   "%lu [%lu] pin mapped objects, %llu [%llu] bytes [purgeable]\n",
+		   pin_mapped_count, pin_mapped_purgeable_count,
+		   pin_mapped_size, pin_mapped_purgeable_size);
+
+	seq_printf(m, "%llu [%llu] gtt total\n",
+		   ggtt->base.total, ggtt->mappable_end - ggtt->base.start);
+
+	seq_putc(m, '\n');
+	print_batch_pool_stats(m, dev_priv);
+	list_for_each_entry_reverse(file, &dev->filelist, lhead) {
+		struct file_stats stats;
+		struct task_struct *task;
+
+		memset(&stats, 0, sizeof(stats));
+		stats.file_priv = file->driver_priv;
+		spin_lock(&file->table_lock);
+		idr_for_each(&file->object_idr, per_file_stats, &stats);
+		spin_unlock(&file->table_lock);
+		/*
+		 * Although we have a valid reference on file->pid, that does
+		 * not guarantee that the task_struct who called get_pid() is
+		 * still alive (e.g. get_pid(current) => fork() => exit()).
+		 * Therefore, we need to protect this ->comm access using RCU.
+		 */
+		rcu_read_lock();
+		task = pid_task(file->pid, PIDTYPE_PID);
+		print_file_stats(m, task ? task->comm : "<unknown>", stats);
+		rcu_read_unlock();
+	}
+
+	mutex_unlock(&dev->struct_mutex);
+
+	return 0;
+}
+
+static int i915_gem_gtt_info(struct seq_file *m, void *data)
+{
+	struct drm_info_node *node = m->private;
+	struct drm_device *dev = node->minor->dev;
+	uintptr_t list = (uintptr_t) node->info_ent->data;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct drm_i915_gem_object *obj;
+	u64 total_obj_size, total_gtt_size;
+	int count, ret;
+
+	ret = mutex_lock_interruptible(&dev->struct_mutex);
+	if (ret)
+		return ret;
+
+	total_obj_size = total_gtt_size = count = 0;
+	list_for_each_entry(obj, &dev_priv->mm.bound_list, global_list) {
+		if (list == PINNED_LIST && !i915_gem_obj_is_pinned(obj))
+			continue;
+
+		seq_puts(m, "   ");
+		describe_obj(m, obj);
+		seq_putc(m, '\n');
+		total_obj_size += obj->base.size;
+		total_gtt_size += i915_gem_obj_total_ggtt_size(obj);
+		count++;
+	}
+
+	mutex_unlock(&dev->struct_mutex);
+
+	seq_printf(m, "Total %d objects, %llu bytes, %llu GTT size\n",
+		   count, total_obj_size, total_gtt_size);
+
+	return 0;
+}
+
+static int i915_gem_pageflip_info(struct seq_file *m, void *data)
+{
+	struct drm_info_node *node = m->private;
+	struct drm_device *dev = node->minor->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_crtc *crtc;
+	int ret;
+
+	ret = mutex_lock_interruptible(&dev->struct_mutex);
+	if (ret)
+		return ret;
+
+	for_each_intel_crtc(dev, crtc) {
+		const char pipe = pipe_name(crtc->pipe);
+		const char plane = plane_name(crtc->plane);
+		struct intel_unpin_work *work;
+
+		spin_lock_irq(&dev->event_lock);
+		work = crtc->unpin_work;
+		if (work == NULL) {
+			seq_printf(m, "No flip due on pipe %c (plane %c)\n",
+				   pipe, plane);
+		} else {
+			u32 addr;
+
+			if (atomic_read(&work->pending) < INTEL_FLIP_COMPLETE) {
+				seq_printf(m, "Flip queued on pipe %c (plane %c)\n",
+					   pipe, plane);
+			} else {
+				seq_printf(m, "Flip pending (waiting for vsync) on pipe %c (plane %c)\n",
+					   pipe, plane);
+			}
+			if (work->flip_queued_req) {
+				struct intel_engine_cs *engine = i915_gem_request_get_engine(work->flip_queued_req);
+
+				seq_printf(m, "Flip queued on %s at seqno %x, next seqno %x [current breadcrumb %x], completed? %d\n",
+					   engine->name,
+					   i915_gem_request_get_seqno(work->flip_queued_req),
+					   dev_priv->next_seqno,
+					   engine->get_seqno(engine),
+					   i915_gem_request_completed(work->flip_queued_req, true));
+			} else
+				seq_printf(m, "Flip not associated with any ring\n");
+			seq_printf(m, "Flip queued on frame %d, (was ready on frame %d), now %d\n",
+				   work->flip_queued_vblank,
+				   work->flip_ready_vblank,
+				   drm_crtc_vblank_count(&crtc->base));
+			if (work->enable_stall_check)
+				seq_puts(m, "Stall check enabled, ");
+			else
+				seq_puts(m, "Stall check waiting for page flip ioctl, ");
+			seq_printf(m, "%d prepares\n", atomic_read(&work->pending));
+
+			if (INTEL_INFO(dev)->gen >= 4)
+				addr = I915_HI_DISPBASE(I915_READ(DSPSURF(crtc->plane)));
+			else
+				addr = I915_READ(DSPADDR(crtc->plane));
+			seq_printf(m, "Current scanout address 0x%08x\n", addr);
+
+			if (work->pending_flip_obj) {
+				seq_printf(m, "New framebuffer address 0x%08lx\n", (long)work->gtt_offset);
+				seq_printf(m, "MMIO update completed? %d\n",  addr == work->gtt_offset);
+			}
+		}
+		spin_unlock_irq(&dev->event_lock);
+	}
+
+	mutex_unlock(&dev->struct_mutex);
+
+	return 0;
+}
+
+static int i915_gem_batch_pool_info(struct seq_file *m, void *data)
+{
+	struct drm_info_node *node = m->private;
+	struct drm_device *dev = node->minor->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct drm_i915_gem_object *obj;
+	struct intel_engine_cs *engine;
+	int total = 0;
+	int ret, j;
+
+	ret = mutex_lock_interruptible(&dev->struct_mutex);
+	if (ret)
+		return ret;
+
+	for_each_engine(engine, dev_priv) {
+		for (j = 0; j < ARRAY_SIZE(engine->batch_pool.cache_list); j++) {
+			int count;
+
+			count = 0;
+			list_for_each_entry(obj,
+					    &engine->batch_pool.cache_list[j],
+					    batch_pool_link)
+				count++;
+			seq_printf(m, "%s cache[%d]: %d objects\n",
+				   engine->name, j, count);
+
+			list_for_each_entry(obj,
+					    &engine->batch_pool.cache_list[j],
+					    batch_pool_link) {
+				seq_puts(m, "   ");
+				describe_obj(m, obj);
+				seq_putc(m, '\n');
+			}
+
+			total += count;
+		}
+	}
+
+	seq_printf(m, "total: %d\n", total);
+
+	mutex_unlock(&dev->struct_mutex);
+
+	return 0;
+}
+
+static int i915_gem_request_info(struct seq_file *m, void *data)
+{
+	struct drm_info_node *node = m->private;
+	struct drm_device *dev = node->minor->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_engine_cs *engine;
+	struct drm_i915_gem_request *req;
+	int ret, any;
+
+	ret = mutex_lock_interruptible(&dev->struct_mutex);
+	if (ret)
+		return ret;
+
+	any = 0;
+	for_each_engine(engine, dev_priv) {
+		int count;
+
+		count = 0;
+		list_for_each_entry(req, &engine->request_list, list)
+			count++;
+		if (count == 0)
+			continue;
+
+		seq_printf(m, "%s requests: %d\n", engine->name, count);
+		list_for_each_entry(req, &engine->request_list, list) {
+			struct task_struct *task;
+
+			rcu_read_lock();
+			task = NULL;
+			if (req->pid)
+				task = pid_task(req->pid, PIDTYPE_PID);
+			seq_printf(m, "    %x @ %d: %s [%d]\n",
+				   req->seqno,
+				   (int) (jiffies - req->emitted_jiffies),
+				   task ? task->comm : "<unknown>",
+				   task ? task->pid : -1);
+			rcu_read_unlock();
+		}
+
+		any++;
+	}
+	mutex_unlock(&dev->struct_mutex);
+
+	if (any == 0)
+		seq_puts(m, "No requests\n");
+
+	return 0;
+}
+
+static void i915_ring_seqno_info(struct seq_file *m,
+				 struct intel_engine_cs *engine)
+{
+	seq_printf(m, "Current sequence (%s): %x\n",
+		   engine->name, engine->get_seqno(engine));
+	seq_printf(m, "Current user interrupts (%s): %x\n",
+		   engine->name, READ_ONCE(engine->user_interrupts));
+}
+
+static int i915_gem_seqno_info(struct seq_file *m, void *data)
+{
+	struct drm_info_node *node = m->private;
+	struct drm_device *dev = node->minor->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_engine_cs *engine;
+	int ret;
+
+	ret = mutex_lock_interruptible(&dev->struct_mutex);
+	if (ret)
+		return ret;
+	intel_runtime_pm_get(dev_priv);
+
+	for_each_engine(engine, dev_priv)
+		i915_ring_seqno_info(m, engine);
+
+	intel_runtime_pm_put(dev_priv);
+	mutex_unlock(&dev->struct_mutex);
+
+	return 0;
+}
+
+
+static int i915_interrupt_info(struct seq_file *m, void *data)
+{
+	struct drm_info_node *node = m->private;
+	struct drm_device *dev = node->minor->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_engine_cs *engine;
+	int ret, i, pipe;
+
+	ret = mutex_lock_interruptible(&dev->struct_mutex);
+	if (ret)
+		return ret;
+	intel_runtime_pm_get(dev_priv);
+
+	if (IS_CHERRYVIEW(dev)) {
+		seq_printf(m, "Master Interrupt Control:\t%08x\n",
+			   I915_READ(GEN8_MASTER_IRQ));
+
+		seq_printf(m, "Display IER:\t%08x\n",
+			   I915_READ(VLV_IER));
+		seq_printf(m, "Display IIR:\t%08x\n",
+			   I915_READ(VLV_IIR));
+		seq_printf(m, "Display IIR_RW:\t%08x\n",
+			   I915_READ(VLV_IIR_RW));
+		seq_printf(m, "Display IMR:\t%08x\n",
+			   I915_READ(VLV_IMR));
+		for_each_pipe(dev_priv, pipe)
+			seq_printf(m, "Pipe %c stat:\t%08x\n",
+				   pipe_name(pipe),
+				   I915_READ(PIPESTAT(pipe)));
+
+		seq_printf(m, "Port hotplug:\t%08x\n",
+			   I915_READ(PORT_HOTPLUG_EN));
+		seq_printf(m, "DPFLIPSTAT:\t%08x\n",
+			   I915_READ(VLV_DPFLIPSTAT));
+		seq_printf(m, "DPINVGTT:\t%08x\n",
+			   I915_READ(DPINVGTT));
+
+		for (i = 0; i < 4; i++) {
+			seq_printf(m, "GT Interrupt IMR %d:\t%08x\n",
+				   i, I915_READ(GEN8_GT_IMR(i)));
+			seq_printf(m, "GT Interrupt IIR %d:\t%08x\n",
+				   i, I915_READ(GEN8_GT_IIR(i)));
+			seq_printf(m, "GT Interrupt IER %d:\t%08x\n",
+				   i, I915_READ(GEN8_GT_IER(i)));
+		}
+
+		seq_printf(m, "PCU interrupt mask:\t%08x\n",
+			   I915_READ(GEN8_PCU_IMR));
+		seq_printf(m, "PCU interrupt identity:\t%08x\n",
+			   I915_READ(GEN8_PCU_IIR));
+		seq_printf(m, "PCU interrupt enable:\t%08x\n",
+			   I915_READ(GEN8_PCU_IER));
+	} else if (INTEL_INFO(dev)->gen >= 8) {
+		seq_printf(m, "Master Interrupt Control:\t%08x\n",
+			   I915_READ(GEN8_MASTER_IRQ));
+
+		for (i = 0; i < 4; i++) {
+			seq_printf(m, "GT Interrupt IMR %d:\t%08x\n",
+				   i, I915_READ(GEN8_GT_IMR(i)));
+			seq_printf(m, "GT Interrupt IIR %d:\t%08x\n",
+				   i, I915_READ(GEN8_GT_IIR(i)));
+			seq_printf(m, "GT Interrupt IER %d:\t%08x\n",
+				   i, I915_READ(GEN8_GT_IER(i)));
+		}
+
+		for_each_pipe(dev_priv, pipe) {
+			enum intel_display_power_domain power_domain;
+
+			power_domain = POWER_DOMAIN_PIPE(pipe);
+			if (!intel_display_power_get_if_enabled(dev_priv,
+								power_domain)) {
+				seq_printf(m, "Pipe %c power disabled\n",
+					   pipe_name(pipe));
+				continue;
+			}
+			seq_printf(m, "Pipe %c IMR:\t%08x\n",
+				   pipe_name(pipe),
+				   I915_READ(GEN8_DE_PIPE_IMR(pipe)));
+			seq_printf(m, "Pipe %c IIR:\t%08x\n",
+				   pipe_name(pipe),
+				   I915_READ(GEN8_DE_PIPE_IIR(pipe)));
+			seq_printf(m, "Pipe %c IER:\t%08x\n",
+				   pipe_name(pipe),
+				   I915_READ(GEN8_DE_PIPE_IER(pipe)));
+
+			intel_display_power_put(dev_priv, power_domain);
+		}
+
+		seq_printf(m, "Display Engine port interrupt mask:\t%08x\n",
+			   I915_READ(GEN8_DE_PORT_IMR));
+		seq_printf(m, "Display Engine port interrupt identity:\t%08x\n",
+			   I915_READ(GEN8_DE_PORT_IIR));
+		seq_printf(m, "Display Engine port interrupt enable:\t%08x\n",
+			   I915_READ(GEN8_DE_PORT_IER));
+
+		seq_printf(m, "Display Engine misc interrupt mask:\t%08x\n",
+			   I915_READ(GEN8_DE_MISC_IMR));
+		seq_printf(m, "Display Engine misc interrupt identity:\t%08x\n",
+			   I915_READ(GEN8_DE_MISC_IIR));
+		seq_printf(m, "Display Engine misc interrupt enable:\t%08x\n",
+			   I915_READ(GEN8_DE_MISC_IER));
+
+		seq_printf(m, "PCU interrupt mask:\t%08x\n",
+			   I915_READ(GEN8_PCU_IMR));
+		seq_printf(m, "PCU interrupt identity:\t%08x\n",
+			   I915_READ(GEN8_PCU_IIR));
+		seq_printf(m, "PCU interrupt enable:\t%08x\n",
+			   I915_READ(GEN8_PCU_IER));
+	} else if (IS_VALLEYVIEW(dev)) {
+		seq_printf(m, "Display IER:\t%08x\n",
+			   I915_READ(VLV_IER));
+		seq_printf(m, "Display IIR:\t%08x\n",
+			   I915_READ(VLV_IIR));
+		seq_printf(m, "Display IIR_RW:\t%08x\n",
+			   I915_READ(VLV_IIR_RW));
+		seq_printf(m, "Display IMR:\t%08x\n",
+			   I915_READ(VLV_IMR));
+		for_each_pipe(dev_priv, pipe)
+			seq_printf(m, "Pipe %c stat:\t%08x\n",
+				   pipe_name(pipe),
+				   I915_READ(PIPESTAT(pipe)));
+
+		seq_printf(m, "Master IER:\t%08x\n",
+			   I915_READ(VLV_MASTER_IER));
+
+		seq_printf(m, "Render IER:\t%08x\n",
+			   I915_READ(GTIER));
+		seq_printf(m, "Render IIR:\t%08x\n",
+			   I915_READ(GTIIR));
+		seq_printf(m, "Render IMR:\t%08x\n",
+			   I915_READ(GTIMR));
+
+		seq_printf(m, "PM IER:\t\t%08x\n",
+			   I915_READ(GEN6_PMIER));
+		seq_printf(m, "PM IIR:\t\t%08x\n",
+			   I915_READ(GEN6_PMIIR));
+		seq_printf(m, "PM IMR:\t\t%08x\n",
+			   I915_READ(GEN6_PMIMR));
+
+		seq_printf(m, "Port hotplug:\t%08x\n",
+			   I915_READ(PORT_HOTPLUG_EN));
+		seq_printf(m, "DPFLIPSTAT:\t%08x\n",
+			   I915_READ(VLV_DPFLIPSTAT));
+		seq_printf(m, "DPINVGTT:\t%08x\n",
+			   I915_READ(DPINVGTT));
+
+	} else if (!HAS_PCH_SPLIT(dev)) {
+		seq_printf(m, "Interrupt enable:    %08x\n",
+			   I915_READ(IER));
+		seq_printf(m, "Interrupt identity:  %08x\n",
+			   I915_READ(IIR));
+		seq_printf(m, "Interrupt mask:      %08x\n",
+			   I915_READ(IMR));
+		for_each_pipe(dev_priv, pipe)
+			seq_printf(m, "Pipe %c stat:         %08x\n",
+				   pipe_name(pipe),
+				   I915_READ(PIPESTAT(pipe)));
+	} else {
+		seq_printf(m, "North Display Interrupt enable:		%08x\n",
+			   I915_READ(DEIER));
+		seq_printf(m, "North Display Interrupt identity:	%08x\n",
+			   I915_READ(DEIIR));
+		seq_printf(m, "North Display Interrupt mask:		%08x\n",
+			   I915_READ(DEIMR));
+		seq_printf(m, "South Display Interrupt enable:		%08x\n",
+			   I915_READ(SDEIER));
+		seq_printf(m, "South Display Interrupt identity:	%08x\n",
+			   I915_READ(SDEIIR));
+		seq_printf(m, "South Display Interrupt mask:		%08x\n",
+			   I915_READ(SDEIMR));
+		seq_printf(m, "Graphics Interrupt enable:		%08x\n",
+			   I915_READ(GTIER));
+		seq_printf(m, "Graphics Interrupt identity:		%08x\n",
+			   I915_READ(GTIIR));
+		seq_printf(m, "Graphics Interrupt mask:		%08x\n",
+			   I915_READ(GTIMR));
+	}
+	for_each_engine(engine, dev_priv) {
+		if (INTEL_INFO(dev)->gen >= 6) {
+			seq_printf(m,
+				   "Graphics Interrupt mask (%s):	%08x\n",
+				   engine->name, I915_READ_IMR(engine));
+		}
+		i915_ring_seqno_info(m, engine);
+	}
+	intel_runtime_pm_put(dev_priv);
+	mutex_unlock(&dev->struct_mutex);
+
+	return 0;
+}
+
+static int i915_gem_fence_regs_info(struct seq_file *m, void *data)
+{
+	struct drm_info_node *node = m->private;
+	struct drm_device *dev = node->minor->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	int i, ret;
+
+	ret = mutex_lock_interruptible(&dev->struct_mutex);
+	if (ret)
+		return ret;
+
+	seq_printf(m, "Total fences = %d\n", dev_priv->num_fence_regs);
+	for (i = 0; i < dev_priv->num_fence_regs; i++) {
+		struct drm_i915_gem_object *obj = dev_priv->fence_regs[i].obj;
+
+		seq_printf(m, "Fence %d, pin count = %d, object = ",
+			   i, dev_priv->fence_regs[i].pin_count);
+		if (obj == NULL)
+			seq_puts(m, "unused");
+		else
+			describe_obj(m, obj);
+		seq_putc(m, '\n');
+	}
+
+	mutex_unlock(&dev->struct_mutex);
+	return 0;
+}
+
+static int i915_hws_info(struct seq_file *m, void *data)
+{
+	struct drm_info_node *node = m->private;
+	struct drm_device *dev = node->minor->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_engine_cs *engine;
+	const u32 *hws;
+	int i;
+
+	engine = &dev_priv->engine[(uintptr_t)node->info_ent->data];
+	hws = engine->status_page.page_addr;
+	if (hws == NULL)
+		return 0;
+
+	for (i = 0; i < 4096 / sizeof(u32) / 4; i += 4) {
+		seq_printf(m, "0x%08x: 0x%08x 0x%08x 0x%08x 0x%08x\n",
+			   i * 4,
+			   hws[i], hws[i + 1], hws[i + 2], hws[i + 3]);
+	}
+	return 0;
+}
+
+static ssize_t
+i915_error_state_write(struct file *filp,
+		       const char __user *ubuf,
+		       size_t cnt,
+		       loff_t *ppos)
+{
+	struct i915_error_state_file_priv *error_priv = filp->private_data;
+	struct drm_device *dev = error_priv->dev;
+	int ret;
+
+	DRM_DEBUG_DRIVER("Resetting error state\n");
+
+	ret = mutex_lock_interruptible(&dev->struct_mutex);
+	if (ret)
+		return ret;
+
+	i915_destroy_error_state(dev);
+	mutex_unlock(&dev->struct_mutex);
+
+	return cnt;
+}
+
+static int i915_error_state_open(struct inode *inode, struct file *file)
+{
+	struct drm_device *dev = inode->i_private;
+	struct i915_error_state_file_priv *error_priv;
+
+	error_priv = kzalloc(sizeof(*error_priv), GFP_KERNEL);
+	if (!error_priv)
+		return -ENOMEM;
+
+	error_priv->dev = dev;
+
+	i915_error_state_get(dev, error_priv);
+
+	file->private_data = error_priv;
+
+	return 0;
+}
+
+static int i915_error_state_release(struct inode *inode, struct file *file)
+{
+	struct i915_error_state_file_priv *error_priv = file->private_data;
+
+	i915_error_state_put(error_priv);
+	kfree(error_priv);
+
+	return 0;
+}
+
+static ssize_t i915_error_state_read(struct file *file, char __user *userbuf,
+				     size_t count, loff_t *pos)
+{
+	struct i915_error_state_file_priv *error_priv = file->private_data;
+	struct drm_i915_error_state_buf error_str;
+	loff_t tmp_pos = 0;
+	ssize_t ret_count = 0;
+	int ret;
+
+	ret = i915_error_state_buf_init(&error_str, to_i915(error_priv->dev), count, *pos);
+	if (ret)
+		return ret;
+
+	ret = i915_error_state_to_str(&error_str, error_priv);
+	if (ret)
+		goto out;
+
+	ret_count = simple_read_from_buffer(userbuf, count, &tmp_pos,
+					    error_str.buf,
+					    error_str.bytes);
+
+	if (ret_count < 0)
+		ret = ret_count;
+	else
+		*pos = error_str.start + ret_count;
+out:
+	i915_error_state_buf_release(&error_str);
+	return ret ?: ret_count;
+}
+
+static const struct file_operations i915_error_state_fops = {
+	.owner = THIS_MODULE,
+	.open = i915_error_state_open,
+	.read = i915_error_state_read,
+	.write = i915_error_state_write,
+	.llseek = default_llseek,
+	.release = i915_error_state_release,
+};
+
+static int
+i915_next_seqno_get(void *data, u64 *val)
+{
+	struct drm_device *dev = data;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	int ret;
+
+	ret = mutex_lock_interruptible(&dev->struct_mutex);
+	if (ret)
+		return ret;
+
+	*val = dev_priv->next_seqno;
+	mutex_unlock(&dev->struct_mutex);
+
+	return 0;
+}
+
+static int
+i915_next_seqno_set(void *data, u64 val)
+{
+	struct drm_device *dev = data;
+	int ret;
+
+	ret = mutex_lock_interruptible(&dev->struct_mutex);
+	if (ret)
+		return ret;
+
+	ret = i915_gem_set_seqno(dev, val);
+	mutex_unlock(&dev->struct_mutex);
+
+	return ret;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(i915_next_seqno_fops,
+			i915_next_seqno_get, i915_next_seqno_set,
+			"0x%llx\n");
+
+static int i915_frequency_info(struct seq_file *m, void *unused)
+{
+	struct drm_info_node *node = m->private;
+	struct drm_device *dev = node->minor->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	int ret = 0;
+
+	intel_runtime_pm_get(dev_priv);
+
+	flush_delayed_work(&dev_priv->rps.delayed_resume_work);
+
+	if (IS_GEN5(dev)) {
+		u16 rgvswctl = I915_READ16(MEMSWCTL);
+		u16 rgvstat = I915_READ16(MEMSTAT_ILK);
+
+		seq_printf(m, "Requested P-state: %d\n", (rgvswctl >> 8) & 0xf);
+		seq_printf(m, "Requested VID: %d\n", rgvswctl & 0x3f);
+		seq_printf(m, "Current VID: %d\n", (rgvstat & MEMSTAT_VID_MASK) >>
+			   MEMSTAT_VID_SHIFT);
+		seq_printf(m, "Current P-state: %d\n",
+			   (rgvstat & MEMSTAT_PSTATE_MASK) >> MEMSTAT_PSTATE_SHIFT);
+	} else if (IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev)) {
+		u32 freq_sts;
+
+		mutex_lock(&dev_priv->rps.hw_lock);
+		freq_sts = vlv_punit_read(dev_priv, PUNIT_REG_GPU_FREQ_STS);
+		seq_printf(m, "PUNIT_REG_GPU_FREQ_STS: 0x%08x\n", freq_sts);
+		seq_printf(m, "DDR freq: %d MHz\n", dev_priv->mem_freq);
+
+		seq_printf(m, "actual GPU freq: %d MHz\n",
+			   intel_gpu_freq(dev_priv, (freq_sts >> 8) & 0xff));
+
+		seq_printf(m, "current GPU freq: %d MHz\n",
+			   intel_gpu_freq(dev_priv, dev_priv->rps.cur_freq));
+
+		seq_printf(m, "max GPU freq: %d MHz\n",
+			   intel_gpu_freq(dev_priv, dev_priv->rps.max_freq));
+
+		seq_printf(m, "min GPU freq: %d MHz\n",
+			   intel_gpu_freq(dev_priv, dev_priv->rps.min_freq));
+
+		seq_printf(m, "idle GPU freq: %d MHz\n",
+			   intel_gpu_freq(dev_priv, dev_priv->rps.idle_freq));
+
+		seq_printf(m,
+			   "efficient (RPe) frequency: %d MHz\n",
+			   intel_gpu_freq(dev_priv, dev_priv->rps.efficient_freq));
+		mutex_unlock(&dev_priv->rps.hw_lock);
+	} else if (INTEL_INFO(dev)->gen >= 6) {
+		u32 rp_state_limits;
+		u32 gt_perf_status;
+		u32 rp_state_cap;
+		u32 rpmodectl, rpinclimit, rpdeclimit;
+		u32 rpstat, cagf, reqf;
+		u32 rpupei, rpcurup, rpprevup;
+		u32 rpdownei, rpcurdown, rpprevdown;
+		u32 pm_ier, pm_imr, pm_isr, pm_iir, pm_mask;
+		int max_freq;
+
+		rp_state_limits = I915_READ(GEN6_RP_STATE_LIMITS);
+		if (IS_BROXTON(dev)) {
+			rp_state_cap = I915_READ(BXT_RP_STATE_CAP);
+			gt_perf_status = I915_READ(BXT_GT_PERF_STATUS);
+		} else {
+			rp_state_cap = I915_READ(GEN6_RP_STATE_CAP);
+			gt_perf_status = I915_READ(GEN6_GT_PERF_STATUS);
+		}
+
+		/* RPSTAT1 is in the GT power well */
+		ret = mutex_lock_interruptible(&dev->struct_mutex);
+		if (ret)
+			goto out;
+
+		intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL);
+
+		reqf = I915_READ(GEN6_RPNSWREQ);
+		if (IS_GEN9(dev))
+			reqf >>= 23;
+		else {
+			reqf &= ~GEN6_TURBO_DISABLE;
+			if (IS_HASWELL(dev) || IS_BROADWELL(dev))
+				reqf >>= 24;
+			else
+				reqf >>= 25;
+		}
+		reqf = intel_gpu_freq(dev_priv, reqf);
+
+		rpmodectl = I915_READ(GEN6_RP_CONTROL);
+		rpinclimit = I915_READ(GEN6_RP_UP_THRESHOLD);
+		rpdeclimit = I915_READ(GEN6_RP_DOWN_THRESHOLD);
+
+		rpstat = I915_READ(GEN6_RPSTAT1);
+		rpupei = I915_READ(GEN6_RP_CUR_UP_EI) & GEN6_CURICONT_MASK;
+		rpcurup = I915_READ(GEN6_RP_CUR_UP) & GEN6_CURBSYTAVG_MASK;
+		rpprevup = I915_READ(GEN6_RP_PREV_UP) & GEN6_CURBSYTAVG_MASK;
+		rpdownei = I915_READ(GEN6_RP_CUR_DOWN_EI) & GEN6_CURIAVG_MASK;
+		rpcurdown = I915_READ(GEN6_RP_CUR_DOWN) & GEN6_CURBSYTAVG_MASK;
+		rpprevdown = I915_READ(GEN6_RP_PREV_DOWN) & GEN6_CURBSYTAVG_MASK;
+		if (IS_GEN9(dev))
+			cagf = (rpstat & GEN9_CAGF_MASK) >> GEN9_CAGF_SHIFT;
+		else if (IS_HASWELL(dev) || IS_BROADWELL(dev))
+			cagf = (rpstat & HSW_CAGF_MASK) >> HSW_CAGF_SHIFT;
+		else
+			cagf = (rpstat & GEN6_CAGF_MASK) >> GEN6_CAGF_SHIFT;
+		cagf = intel_gpu_freq(dev_priv, cagf);
+
+		intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
+		mutex_unlock(&dev->struct_mutex);
+
+		if (IS_GEN6(dev) || IS_GEN7(dev)) {
+			pm_ier = I915_READ(GEN6_PMIER);
+			pm_imr = I915_READ(GEN6_PMIMR);
+			pm_isr = I915_READ(GEN6_PMISR);
+			pm_iir = I915_READ(GEN6_PMIIR);
+			pm_mask = I915_READ(GEN6_PMINTRMSK);
+		} else {
+			pm_ier = I915_READ(GEN8_GT_IER(2));
+			pm_imr = I915_READ(GEN8_GT_IMR(2));
+			pm_isr = I915_READ(GEN8_GT_ISR(2));
+			pm_iir = I915_READ(GEN8_GT_IIR(2));
+			pm_mask = I915_READ(GEN6_PMINTRMSK);
+		}
+		seq_printf(m, "PM IER=0x%08x IMR=0x%08x ISR=0x%08x IIR=0x%08x, MASK=0x%08x\n",
+			   pm_ier, pm_imr, pm_isr, pm_iir, pm_mask);
+		seq_printf(m, "GT_PERF_STATUS: 0x%08x\n", gt_perf_status);
+		seq_printf(m, "Render p-state ratio: %d\n",
+			   (gt_perf_status & (IS_GEN9(dev) ? 0x1ff00 : 0xff00)) >> 8);
+		seq_printf(m, "Render p-state VID: %d\n",
+			   gt_perf_status & 0xff);
+		seq_printf(m, "Render p-state limit: %d\n",
+			   rp_state_limits & 0xff);
+		seq_printf(m, "RPSTAT1: 0x%08x\n", rpstat);
+		seq_printf(m, "RPMODECTL: 0x%08x\n", rpmodectl);
+		seq_printf(m, "RPINCLIMIT: 0x%08x\n", rpinclimit);
+		seq_printf(m, "RPDECLIMIT: 0x%08x\n", rpdeclimit);
+		seq_printf(m, "RPNSWREQ: %dMHz\n", reqf);
+		seq_printf(m, "CAGF: %dMHz\n", cagf);
+		seq_printf(m, "RP CUR UP EI: %d (%dus)\n",
+			   rpupei, GT_PM_INTERVAL_TO_US(dev_priv, rpupei));
+		seq_printf(m, "RP CUR UP: %d (%dus)\n",
+			   rpcurup, GT_PM_INTERVAL_TO_US(dev_priv, rpcurup));
+		seq_printf(m, "RP PREV UP: %d (%dus)\n",
+			   rpprevup, GT_PM_INTERVAL_TO_US(dev_priv, rpprevup));
+		seq_printf(m, "Up threshold: %d%%\n",
+			   dev_priv->rps.up_threshold);
+
+		seq_printf(m, "RP CUR DOWN EI: %d (%dus)\n",
+			   rpdownei, GT_PM_INTERVAL_TO_US(dev_priv, rpdownei));
+		seq_printf(m, "RP CUR DOWN: %d (%dus)\n",
+			   rpcurdown, GT_PM_INTERVAL_TO_US(dev_priv, rpcurdown));
+		seq_printf(m, "RP PREV DOWN: %d (%dus)\n",
+			   rpprevdown, GT_PM_INTERVAL_TO_US(dev_priv, rpprevdown));
+		seq_printf(m, "Down threshold: %d%%\n",
+			   dev_priv->rps.down_threshold);
+
+		max_freq = (IS_BROXTON(dev) ? rp_state_cap >> 0 :
+			    rp_state_cap >> 16) & 0xff;
+		max_freq *= (IS_SKYLAKE(dev) || IS_KABYLAKE(dev) ?
+			     GEN9_FREQ_SCALER : 1);
+		seq_printf(m, "Lowest (RPN) frequency: %dMHz\n",
+			   intel_gpu_freq(dev_priv, max_freq));
+
+		max_freq = (rp_state_cap & 0xff00) >> 8;
+		max_freq *= (IS_SKYLAKE(dev) || IS_KABYLAKE(dev) ?
+			     GEN9_FREQ_SCALER : 1);
+		seq_printf(m, "Nominal (RP1) frequency: %dMHz\n",
+			   intel_gpu_freq(dev_priv, max_freq));
+
+		max_freq = (IS_BROXTON(dev) ? rp_state_cap >> 16 :
+			    rp_state_cap >> 0) & 0xff;
+		max_freq *= (IS_SKYLAKE(dev) || IS_KABYLAKE(dev) ?
+			     GEN9_FREQ_SCALER : 1);
+		seq_printf(m, "Max non-overclocked (RP0) frequency: %dMHz\n",
+			   intel_gpu_freq(dev_priv, max_freq));
+		seq_printf(m, "Max overclocked frequency: %dMHz\n",
+			   intel_gpu_freq(dev_priv, dev_priv->rps.max_freq));
+
+		seq_printf(m, "Current freq: %d MHz\n",
+			   intel_gpu_freq(dev_priv, dev_priv->rps.cur_freq));
+		seq_printf(m, "Actual freq: %d MHz\n", cagf);
+		seq_printf(m, "Idle freq: %d MHz\n",
+			   intel_gpu_freq(dev_priv, dev_priv->rps.idle_freq));
+		seq_printf(m, "Min freq: %d MHz\n",
+			   intel_gpu_freq(dev_priv, dev_priv->rps.min_freq));
+		seq_printf(m, "Max freq: %d MHz\n",
+			   intel_gpu_freq(dev_priv, dev_priv->rps.max_freq));
+		seq_printf(m,
+			   "efficient (RPe) frequency: %d MHz\n",
+			   intel_gpu_freq(dev_priv, dev_priv->rps.efficient_freq));
+	} else {
+		seq_puts(m, "no P-state info available\n");
+	}
+
+	seq_printf(m, "Current CD clock frequency: %d kHz\n", dev_priv->cdclk_freq);
+	seq_printf(m, "Max CD clock frequency: %d kHz\n", dev_priv->max_cdclk_freq);
+	seq_printf(m, "Max pixel clock frequency: %d kHz\n", dev_priv->max_dotclk_freq);
+
+out:
+	intel_runtime_pm_put(dev_priv);
+	return ret;
+}
+
+static int i915_hangcheck_info(struct seq_file *m, void *unused)
+{
+	struct drm_info_node *node = m->private;
+	struct drm_device *dev = node->minor->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_engine_cs *engine;
+	u64 acthd[I915_NUM_ENGINES];
+	u32 seqno[I915_NUM_ENGINES];
+	u32 instdone[I915_NUM_INSTDONE_REG];
+	enum intel_engine_id id;
+	int j;
+
+	if (!i915.enable_hangcheck) {
+		seq_printf(m, "Hangcheck disabled\n");
+		return 0;
+	}
+
+	intel_runtime_pm_get(dev_priv);
+
+	for_each_engine_id(engine, dev_priv, id) {
+		acthd[id] = intel_ring_get_active_head(engine);
+		seqno[id] = engine->get_seqno(engine);
+	}
+
+	i915_get_extra_instdone(dev, instdone);
+
+	intel_runtime_pm_put(dev_priv);
+
+	if (delayed_work_pending(&dev_priv->gpu_error.hangcheck_work)) {
+		seq_printf(m, "Hangcheck active, fires in %dms\n",
+			   jiffies_to_msecs(dev_priv->gpu_error.hangcheck_work.timer.expires -
+					    jiffies));
+	} else
+		seq_printf(m, "Hangcheck inactive\n");
+
+	for_each_engine_id(engine, dev_priv, id) {
+		seq_printf(m, "%s:\n", engine->name);
+		seq_printf(m, "\tseqno = %x [current %x, last %x]\n",
+			   engine->hangcheck.seqno,
+			   seqno[id],
+			   engine->last_submitted_seqno);
+		seq_printf(m, "\tuser interrupts = %x [current %x]\n",
+			   engine->hangcheck.user_interrupts,
+			   READ_ONCE(engine->user_interrupts));
+		seq_printf(m, "\tACTHD = 0x%08llx [current 0x%08llx]\n",
+			   (long long)engine->hangcheck.acthd,
+			   (long long)acthd[id]);
+		seq_printf(m, "\tscore = %d\n", engine->hangcheck.score);
+		seq_printf(m, "\taction = %d\n", engine->hangcheck.action);
+
+		if (engine->id == RCS) {
+			seq_puts(m, "\tinstdone read =");
+
+			for (j = 0; j < I915_NUM_INSTDONE_REG; j++)
+				seq_printf(m, " 0x%08x", instdone[j]);
+
+			seq_puts(m, "\n\tinstdone accu =");
+
+			for (j = 0; j < I915_NUM_INSTDONE_REG; j++)
+				seq_printf(m, " 0x%08x",
+					   engine->hangcheck.instdone[j]);
+
+			seq_puts(m, "\n");
+		}
+	}
+
+	return 0;
+}
+
+static int ironlake_drpc_info(struct seq_file *m)
+{
+	struct drm_info_node *node = m->private;
+	struct drm_device *dev = node->minor->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	u32 rgvmodectl, rstdbyctl;
+	u16 crstandvid;
+	int ret;
+
+	ret = mutex_lock_interruptible(&dev->struct_mutex);
+	if (ret)
+		return ret;
+	intel_runtime_pm_get(dev_priv);
+
+	rgvmodectl = I915_READ(MEMMODECTL);
+	rstdbyctl = I915_READ(RSTDBYCTL);
+	crstandvid = I915_READ16(CRSTANDVID);
+
+	intel_runtime_pm_put(dev_priv);
+	mutex_unlock(&dev->struct_mutex);
+
+	seq_printf(m, "HD boost: %s\n", yesno(rgvmodectl & MEMMODE_BOOST_EN));
+	seq_printf(m, "Boost freq: %d\n",
+		   (rgvmodectl & MEMMODE_BOOST_FREQ_MASK) >>
+		   MEMMODE_BOOST_FREQ_SHIFT);
+	seq_printf(m, "HW control enabled: %s\n",
+		   yesno(rgvmodectl & MEMMODE_HWIDLE_EN));
+	seq_printf(m, "SW control enabled: %s\n",
+		   yesno(rgvmodectl & MEMMODE_SWMODE_EN));
+	seq_printf(m, "Gated voltage change: %s\n",
+		   yesno(rgvmodectl & MEMMODE_RCLK_GATE));
+	seq_printf(m, "Starting frequency: P%d\n",
+		   (rgvmodectl & MEMMODE_FSTART_MASK) >> MEMMODE_FSTART_SHIFT);
+	seq_printf(m, "Max P-state: P%d\n",
+		   (rgvmodectl & MEMMODE_FMAX_MASK) >> MEMMODE_FMAX_SHIFT);
+	seq_printf(m, "Min P-state: P%d\n", (rgvmodectl & MEMMODE_FMIN_MASK));
+	seq_printf(m, "RS1 VID: %d\n", (crstandvid & 0x3f));
+	seq_printf(m, "RS2 VID: %d\n", ((crstandvid >> 8) & 0x3f));
+	seq_printf(m, "Render standby enabled: %s\n",
+		   yesno(!(rstdbyctl & RCX_SW_EXIT)));
+	seq_puts(m, "Current RS state: ");
+	switch (rstdbyctl & RSX_STATUS_MASK) {
+	case RSX_STATUS_ON:
+		seq_puts(m, "on\n");
+		break;
+	case RSX_STATUS_RC1:
+		seq_puts(m, "RC1\n");
+		break;
+	case RSX_STATUS_RC1E:
+		seq_puts(m, "RC1E\n");
+		break;
+	case RSX_STATUS_RS1:
+		seq_puts(m, "RS1\n");
+		break;
+	case RSX_STATUS_RS2:
+		seq_puts(m, "RS2 (RC6)\n");
+		break;
+	case RSX_STATUS_RS3:
+		seq_puts(m, "RC3 (RC6+)\n");
+		break;
+	default:
+		seq_puts(m, "unknown\n");
+		break;
+	}
+
+	return 0;
+}
+
+static int i915_forcewake_domains(struct seq_file *m, void *data)
+{
+	struct drm_info_node *node = m->private;
+	struct drm_device *dev = node->minor->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_uncore_forcewake_domain *fw_domain;
+
+	spin_lock_irq(&dev_priv->uncore.lock);
+	for_each_fw_domain(fw_domain, dev_priv) {
+		seq_printf(m, "%s.wake_count = %u\n",
+			   intel_uncore_forcewake_domain_to_str(fw_domain->id),
+			   fw_domain->wake_count);
+	}
+	spin_unlock_irq(&dev_priv->uncore.lock);
+
+	return 0;
+}
+
+static int vlv_drpc_info(struct seq_file *m)
+{
+	struct drm_info_node *node = m->private;
+	struct drm_device *dev = node->minor->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	u32 rpmodectl1, rcctl1, pw_status;
+
+	intel_runtime_pm_get(dev_priv);
+
+	pw_status = I915_READ(VLV_GTLC_PW_STATUS);
+	rpmodectl1 = I915_READ(GEN6_RP_CONTROL);
+	rcctl1 = I915_READ(GEN6_RC_CONTROL);
+
+	intel_runtime_pm_put(dev_priv);
+
+	seq_printf(m, "Video Turbo Mode: %s\n",
+		   yesno(rpmodectl1 & GEN6_RP_MEDIA_TURBO));
+	seq_printf(m, "Turbo enabled: %s\n",
+		   yesno(rpmodectl1 & GEN6_RP_ENABLE));
+	seq_printf(m, "HW control enabled: %s\n",
+		   yesno(rpmodectl1 & GEN6_RP_ENABLE));
+	seq_printf(m, "SW control enabled: %s\n",
+		   yesno((rpmodectl1 & GEN6_RP_MEDIA_MODE_MASK) ==
+			  GEN6_RP_MEDIA_SW_MODE));
+	seq_printf(m, "RC6 Enabled: %s\n",
+		   yesno(rcctl1 & (GEN7_RC_CTL_TO_MODE |
+					GEN6_RC_CTL_EI_MODE(1))));
+	seq_printf(m, "Render Power Well: %s\n",
+		   (pw_status & VLV_GTLC_PW_RENDER_STATUS_MASK) ? "Up" : "Down");
+	seq_printf(m, "Media Power Well: %s\n",
+		   (pw_status & VLV_GTLC_PW_MEDIA_STATUS_MASK) ? "Up" : "Down");
+
+	seq_printf(m, "Render RC6 residency since boot: %u\n",
+		   I915_READ(VLV_GT_RENDER_RC6));
+	seq_printf(m, "Media RC6 residency since boot: %u\n",
+		   I915_READ(VLV_GT_MEDIA_RC6));
+
+	return i915_forcewake_domains(m, NULL);
+}
+
+static int gen6_drpc_info(struct seq_file *m)
+{
+	struct drm_info_node *node = m->private;
+	struct drm_device *dev = node->minor->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	u32 rpmodectl1, gt_core_status, rcctl1, rc6vids = 0;
+	unsigned forcewake_count;
+	int count = 0, ret;
+
+	ret = mutex_lock_interruptible(&dev->struct_mutex);
+	if (ret)
+		return ret;
+	intel_runtime_pm_get(dev_priv);
+
+	spin_lock_irq(&dev_priv->uncore.lock);
+	forcewake_count = dev_priv->uncore.fw_domain[FW_DOMAIN_ID_RENDER].wake_count;
+	spin_unlock_irq(&dev_priv->uncore.lock);
+
+	if (forcewake_count) {
+		seq_puts(m, "RC information inaccurate because somebody "
+			    "holds a forcewake reference \n");
+	} else {
+		/* NB: we cannot use forcewake, else we read the wrong values */
+		while (count++ < 50 && (I915_READ_NOTRACE(FORCEWAKE_ACK) & 1))
+			udelay(10);
+		seq_printf(m, "RC information accurate: %s\n", yesno(count < 51));
+	}
+
+	gt_core_status = I915_READ_FW(GEN6_GT_CORE_STATUS);
+	trace_i915_reg_rw(false, GEN6_GT_CORE_STATUS, gt_core_status, 4, true);
+
+	rpmodectl1 = I915_READ(GEN6_RP_CONTROL);
+	rcctl1 = I915_READ(GEN6_RC_CONTROL);
+	mutex_unlock(&dev->struct_mutex);
+	mutex_lock(&dev_priv->rps.hw_lock);
+	sandybridge_pcode_read(dev_priv, GEN6_PCODE_READ_RC6VIDS, &rc6vids);
+	mutex_unlock(&dev_priv->rps.hw_lock);
+
+	intel_runtime_pm_put(dev_priv);
+
+	seq_printf(m, "Video Turbo Mode: %s\n",
+		   yesno(rpmodectl1 & GEN6_RP_MEDIA_TURBO));
+	seq_printf(m, "HW control enabled: %s\n",
+		   yesno(rpmodectl1 & GEN6_RP_ENABLE));
+	seq_printf(m, "SW control enabled: %s\n",
+		   yesno((rpmodectl1 & GEN6_RP_MEDIA_MODE_MASK) ==
+			  GEN6_RP_MEDIA_SW_MODE));
+	seq_printf(m, "RC1e Enabled: %s\n",
+		   yesno(rcctl1 & GEN6_RC_CTL_RC1e_ENABLE));
+	seq_printf(m, "RC6 Enabled: %s\n",
+		   yesno(rcctl1 & GEN6_RC_CTL_RC6_ENABLE));
+	seq_printf(m, "Deep RC6 Enabled: %s\n",
+		   yesno(rcctl1 & GEN6_RC_CTL_RC6p_ENABLE));
+	seq_printf(m, "Deepest RC6 Enabled: %s\n",
+		   yesno(rcctl1 & GEN6_RC_CTL_RC6pp_ENABLE));
+	seq_puts(m, "Current RC state: ");
+	switch (gt_core_status & GEN6_RCn_MASK) {
+	case GEN6_RC0:
+		if (gt_core_status & GEN6_CORE_CPD_STATE_MASK)
+			seq_puts(m, "Core Power Down\n");
+		else
+			seq_puts(m, "on\n");
+		break;
+	case GEN6_RC3:
+		seq_puts(m, "RC3\n");
+		break;
+	case GEN6_RC6:
+		seq_puts(m, "RC6\n");
+		break;
+	case GEN6_RC7:
+		seq_puts(m, "RC7\n");
+		break;
+	default:
+		seq_puts(m, "Unknown\n");
+		break;
+	}
+
+	seq_printf(m, "Core Power Down: %s\n",
+		   yesno(gt_core_status & GEN6_CORE_CPD_STATE_MASK));
+
+	/* Not exactly sure what this is */
+	seq_printf(m, "RC6 \"Locked to RPn\" residency since boot: %u\n",
+		   I915_READ(GEN6_GT_GFX_RC6_LOCKED));
+	seq_printf(m, "RC6 residency since boot: %u\n",
+		   I915_READ(GEN6_GT_GFX_RC6));
+	seq_printf(m, "RC6+ residency since boot: %u\n",
+		   I915_READ(GEN6_GT_GFX_RC6p));
+	seq_printf(m, "RC6++ residency since boot: %u\n",
+		   I915_READ(GEN6_GT_GFX_RC6pp));
+
+	seq_printf(m, "RC6   voltage: %dmV\n",
+		   GEN6_DECODE_RC6_VID(((rc6vids >> 0) & 0xff)));
+	seq_printf(m, "RC6+  voltage: %dmV\n",
+		   GEN6_DECODE_RC6_VID(((rc6vids >> 8) & 0xff)));
+	seq_printf(m, "RC6++ voltage: %dmV\n",
+		   GEN6_DECODE_RC6_VID(((rc6vids >> 16) & 0xff)));
+	return 0;
+}
+
+static int i915_drpc_info(struct seq_file *m, void *unused)
+{
+	struct drm_info_node *node = m->private;
+	struct drm_device *dev = node->minor->dev;
+
+	if (IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev))
+		return vlv_drpc_info(m);
+	else if (INTEL_INFO(dev)->gen >= 6)
+		return gen6_drpc_info(m);
+	else
+		return ironlake_drpc_info(m);
+}
+
+static int i915_frontbuffer_tracking(struct seq_file *m, void *unused)
+{
+	struct drm_info_node *node = m->private;
+	struct drm_device *dev = node->minor->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	seq_printf(m, "FB tracking busy bits: 0x%08x\n",
+		   dev_priv->fb_tracking.busy_bits);
+
+	seq_printf(m, "FB tracking flip bits: 0x%08x\n",
+		   dev_priv->fb_tracking.flip_bits);
+
+	return 0;
+}
+
+static int i915_fbc_status(struct seq_file *m, void *unused)
+{
+	struct drm_info_node *node = m->private;
+	struct drm_device *dev = node->minor->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	if (!HAS_FBC(dev)) {
+		seq_puts(m, "FBC unsupported on this chipset\n");
+		return 0;
+	}
+
+	intel_runtime_pm_get(dev_priv);
+	mutex_lock(&dev_priv->fbc.lock);
+
+	if (intel_fbc_is_active(dev_priv))
+		seq_puts(m, "FBC enabled\n");
+	else
+		seq_printf(m, "FBC disabled: %s\n",
+			   dev_priv->fbc.no_fbc_reason);
+
+	if (INTEL_INFO(dev_priv)->gen >= 7)
+		seq_printf(m, "Compressing: %s\n",
+			   yesno(I915_READ(FBC_STATUS2) &
+				 FBC_COMPRESSION_MASK));
+
+	mutex_unlock(&dev_priv->fbc.lock);
+	intel_runtime_pm_put(dev_priv);
+
+	return 0;
+}
+
+static int i915_fbc_fc_get(void *data, u64 *val)
+{
+	struct drm_device *dev = data;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	if (INTEL_INFO(dev)->gen < 7 || !HAS_FBC(dev))
+		return -ENODEV;
+
+	*val = dev_priv->fbc.false_color;
+
+	return 0;
+}
+
+static int i915_fbc_fc_set(void *data, u64 val)
+{
+	struct drm_device *dev = data;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	u32 reg;
+
+	if (INTEL_INFO(dev)->gen < 7 || !HAS_FBC(dev))
+		return -ENODEV;
+
+	mutex_lock(&dev_priv->fbc.lock);
+
+	reg = I915_READ(ILK_DPFC_CONTROL);
+	dev_priv->fbc.false_color = val;
+
+	I915_WRITE(ILK_DPFC_CONTROL, val ?
+		   (reg | FBC_CTL_FALSE_COLOR) :
+		   (reg & ~FBC_CTL_FALSE_COLOR));
+
+	mutex_unlock(&dev_priv->fbc.lock);
+	return 0;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(i915_fbc_fc_fops,
+			i915_fbc_fc_get, i915_fbc_fc_set,
+			"%llu\n");
+
+static int i915_ips_status(struct seq_file *m, void *unused)
+{
+	struct drm_info_node *node = m->private;
+	struct drm_device *dev = node->minor->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	if (!HAS_IPS(dev)) {
+		seq_puts(m, "not supported\n");
+		return 0;
+	}
+
+	intel_runtime_pm_get(dev_priv);
+
+	seq_printf(m, "Enabled by kernel parameter: %s\n",
+		   yesno(i915.enable_ips));
+
+	if (INTEL_INFO(dev)->gen >= 8) {
+		seq_puts(m, "Currently: unknown\n");
+	} else {
+		if (I915_READ(IPS_CTL) & IPS_ENABLE)
+			seq_puts(m, "Currently: enabled\n");
+		else
+			seq_puts(m, "Currently: disabled\n");
+	}
+
+	intel_runtime_pm_put(dev_priv);
+
+	return 0;
+}
+
+static int i915_sr_status(struct seq_file *m, void *unused)
+{
+	struct drm_info_node *node = m->private;
+	struct drm_device *dev = node->minor->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	bool sr_enabled = false;
+
+	intel_runtime_pm_get(dev_priv);
+
+	if (HAS_PCH_SPLIT(dev))
+		sr_enabled = I915_READ(WM1_LP_ILK) & WM1_LP_SR_EN;
+	else if (IS_CRESTLINE(dev) || IS_G4X(dev) ||
+		 IS_I945G(dev) || IS_I945GM(dev))
+		sr_enabled = I915_READ(FW_BLC_SELF) & FW_BLC_SELF_EN;
+	else if (IS_I915GM(dev))
+		sr_enabled = I915_READ(INSTPM) & INSTPM_SELF_EN;
+	else if (IS_PINEVIEW(dev))
+		sr_enabled = I915_READ(DSPFW3) & PINEVIEW_SELF_REFRESH_EN;
+	else if (IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev))
+		sr_enabled = I915_READ(FW_BLC_SELF_VLV) & FW_CSPWRDWNEN;
+
+	intel_runtime_pm_put(dev_priv);
+
+	seq_printf(m, "self-refresh: %s\n",
+		   sr_enabled ? "enabled" : "disabled");
+
+	return 0;
+}
+
+static int i915_emon_status(struct seq_file *m, void *unused)
+{
+	struct drm_info_node *node = m->private;
+	struct drm_device *dev = node->minor->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	unsigned long temp, chipset, gfx;
+	int ret;
+
+	if (!IS_GEN5(dev))
+		return -ENODEV;
+
+	ret = mutex_lock_interruptible(&dev->struct_mutex);
+	if (ret)
+		return ret;
+
+	temp = i915_mch_val(dev_priv);
+	chipset = i915_chipset_val(dev_priv);
+	gfx = i915_gfx_val(dev_priv);
+	mutex_unlock(&dev->struct_mutex);
+
+	seq_printf(m, "GMCH temp: %ld\n", temp);
+	seq_printf(m, "Chipset power: %ld\n", chipset);
+	seq_printf(m, "GFX power: %ld\n", gfx);
+	seq_printf(m, "Total power: %ld\n", chipset + gfx);
+
+	return 0;
+}
+
+static int i915_ring_freq_table(struct seq_file *m, void *unused)
+{
+	struct drm_info_node *node = m->private;
+	struct drm_device *dev = node->minor->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	int ret = 0;
+	int gpu_freq, ia_freq;
+	unsigned int max_gpu_freq, min_gpu_freq;
+
+	if (!HAS_CORE_RING_FREQ(dev)) {
+		seq_puts(m, "unsupported on this chipset\n");
+		return 0;
+	}
+
+	intel_runtime_pm_get(dev_priv);
+
+	flush_delayed_work(&dev_priv->rps.delayed_resume_work);
+
+	ret = mutex_lock_interruptible(&dev_priv->rps.hw_lock);
+	if (ret)
+		goto out;
+
+	if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev)) {
+		/* Convert GT frequency to 50 HZ units */
+		min_gpu_freq =
+			dev_priv->rps.min_freq_softlimit / GEN9_FREQ_SCALER;
+		max_gpu_freq =
+			dev_priv->rps.max_freq_softlimit / GEN9_FREQ_SCALER;
+	} else {
+		min_gpu_freq = dev_priv->rps.min_freq_softlimit;
+		max_gpu_freq = dev_priv->rps.max_freq_softlimit;
+	}
+
+	seq_puts(m, "GPU freq (MHz)\tEffective CPU freq (MHz)\tEffective Ring freq (MHz)\n");
+
+	for (gpu_freq = min_gpu_freq; gpu_freq <= max_gpu_freq; gpu_freq++) {
+		ia_freq = gpu_freq;
+		sandybridge_pcode_read(dev_priv,
+				       GEN6_PCODE_READ_MIN_FREQ_TABLE,
+				       &ia_freq);
+		seq_printf(m, "%d\t\t%d\t\t\t\t%d\n",
+			   intel_gpu_freq(dev_priv, (gpu_freq *
+				(IS_SKYLAKE(dev) || IS_KABYLAKE(dev) ?
+				 GEN9_FREQ_SCALER : 1))),
+			   ((ia_freq >> 0) & 0xff) * 100,
+			   ((ia_freq >> 8) & 0xff) * 100);
+	}
+
+	mutex_unlock(&dev_priv->rps.hw_lock);
+
+out:
+	intel_runtime_pm_put(dev_priv);
+	return ret;
+}
+
+static int i915_opregion(struct seq_file *m, void *unused)
+{
+	struct drm_info_node *node = m->private;
+	struct drm_device *dev = node->minor->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_opregion *opregion = &dev_priv->opregion;
+	int ret;
+
+	ret = mutex_lock_interruptible(&dev->struct_mutex);
+	if (ret)
+		goto out;
+
+	if (opregion->header)
+		seq_write(m, opregion->header, OPREGION_SIZE);
+
+	mutex_unlock(&dev->struct_mutex);
+
+out:
+	return 0;
+}
+
+static int i915_vbt(struct seq_file *m, void *unused)
+{
+	struct drm_info_node *node = m->private;
+	struct drm_device *dev = node->minor->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_opregion *opregion = &dev_priv->opregion;
+
+	if (opregion->vbt)
+		seq_write(m, opregion->vbt, opregion->vbt_size);
+
+	return 0;
+}
+
+static int i915_gem_framebuffer_info(struct seq_file *m, void *data)
+{
+	struct drm_info_node *node = m->private;
+	struct drm_device *dev = node->minor->dev;
+	struct intel_framebuffer *fbdev_fb = NULL;
+	struct drm_framebuffer *drm_fb;
+	int ret;
+
+	ret = mutex_lock_interruptible(&dev->struct_mutex);
+	if (ret)
+		return ret;
+
+#ifdef CONFIG_DRM_FBDEV_EMULATION
+       if (to_i915(dev)->fbdev) {
+               fbdev_fb = to_intel_framebuffer(to_i915(dev)->fbdev->helper.fb);
+
+               seq_printf(m, "fbcon size: %d x %d, depth %d, %d bpp, modifier 0x%llx, refcount %d, obj ",
+                         fbdev_fb->base.width,
+                         fbdev_fb->base.height,
+                         fbdev_fb->base.depth,
+                         fbdev_fb->base.bits_per_pixel,
+                         fbdev_fb->base.modifier[0],
+                         atomic_read(&fbdev_fb->base.refcount.refcount));
+               describe_obj(m, fbdev_fb->obj);
+               seq_putc(m, '\n');
+       }
+#endif
+
+	mutex_lock(&dev->mode_config.fb_lock);
+	drm_for_each_fb(drm_fb, dev) {
+		struct intel_framebuffer *fb = to_intel_framebuffer(drm_fb);
+		if (fb == fbdev_fb)
+			continue;
+
+		seq_printf(m, "user size: %d x %d, depth %d, %d bpp, modifier 0x%llx, refcount %d, obj ",
+			   fb->base.width,
+			   fb->base.height,
+			   fb->base.depth,
+			   fb->base.bits_per_pixel,
+			   fb->base.modifier[0],
+			   atomic_read(&fb->base.refcount.refcount));
+		describe_obj(m, fb->obj);
+		seq_putc(m, '\n');
+	}
+	mutex_unlock(&dev->mode_config.fb_lock);
+	mutex_unlock(&dev->struct_mutex);
+
+	return 0;
+}
+
+static void describe_ctx_ringbuf(struct seq_file *m,
+				 struct intel_ringbuffer *ringbuf)
+{
+	seq_printf(m, " (ringbuffer, space: %d, head: %u, tail: %u, last head: %d)",
+		   ringbuf->space, ringbuf->head, ringbuf->tail,
+		   ringbuf->last_retired_head);
+}
+
+static int i915_context_status(struct seq_file *m, void *unused)
+{
+	struct drm_info_node *node = m->private;
+	struct drm_device *dev = node->minor->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_engine_cs *engine;
+	struct intel_context *ctx;
+	enum intel_engine_id id;
+	int ret;
+
+	ret = mutex_lock_interruptible(&dev->struct_mutex);
+	if (ret)
+		return ret;
+
+	list_for_each_entry(ctx, &dev_priv->context_list, link) {
+		if (!i915.enable_execlists &&
+		    ctx->legacy_hw_ctx.rcs_state == NULL)
+			continue;
+
+		seq_puts(m, "HW context ");
+		describe_ctx(m, ctx);
+		if (ctx == dev_priv->kernel_context)
+			seq_printf(m, "(kernel context) ");
+
+		if (i915.enable_execlists) {
+			seq_putc(m, '\n');
+			for_each_engine_id(engine, dev_priv, id) {
+				struct drm_i915_gem_object *ctx_obj =
+					ctx->engine[id].state;
+				struct intel_ringbuffer *ringbuf =
+					ctx->engine[id].ringbuf;
+
+				seq_printf(m, "%s: ", engine->name);
+				if (ctx_obj)
+					describe_obj(m, ctx_obj);
+				if (ringbuf)
+					describe_ctx_ringbuf(m, ringbuf);
+				seq_putc(m, '\n');
+			}
+		} else {
+			describe_obj(m, ctx->legacy_hw_ctx.rcs_state);
+		}
+
+		seq_putc(m, '\n');
+	}
+
+	mutex_unlock(&dev->struct_mutex);
+
+	return 0;
+}
+
+static void i915_dump_lrc_obj(struct seq_file *m,
+			      struct intel_context *ctx,
+			      struct intel_engine_cs *engine)
+{
+	struct page *page;
+	uint32_t *reg_state;
+	int j;
+	struct drm_i915_gem_object *ctx_obj = ctx->engine[engine->id].state;
+	unsigned long ggtt_offset = 0;
+
+	if (ctx_obj == NULL) {
+		seq_printf(m, "Context on %s with no gem object\n",
+			   engine->name);
+		return;
+	}
+
+	seq_printf(m, "CONTEXT: %s %u\n", engine->name,
+		   intel_execlists_ctx_id(ctx, engine));
+
+	if (!i915_gem_obj_ggtt_bound(ctx_obj))
+		seq_puts(m, "\tNot bound in GGTT\n");
+	else
+		ggtt_offset = i915_gem_obj_ggtt_offset(ctx_obj);
+
+	if (i915_gem_object_get_pages(ctx_obj)) {
+		seq_puts(m, "\tFailed to get pages for context object\n");
+		return;
+	}
+
+	page = i915_gem_object_get_page(ctx_obj, LRC_STATE_PN);
+	if (!WARN_ON(page == NULL)) {
+		reg_state = kmap_atomic(page);
+
+		for (j = 0; j < 0x600 / sizeof(u32) / 4; j += 4) {
+			seq_printf(m, "\t[0x%08lx] 0x%08x 0x%08x 0x%08x 0x%08x\n",
+				   ggtt_offset + 4096 + (j * 4),
+				   reg_state[j], reg_state[j + 1],
+				   reg_state[j + 2], reg_state[j + 3]);
+		}
+		kunmap_atomic(reg_state);
+	}
+
+	seq_putc(m, '\n');
+}
+
+static int i915_dump_lrc(struct seq_file *m, void *unused)
+{
+	struct drm_info_node *node = (struct drm_info_node *) m->private;
+	struct drm_device *dev = node->minor->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_engine_cs *engine;
+	struct intel_context *ctx;
+	int ret;
+
+	if (!i915.enable_execlists) {
+		seq_printf(m, "Logical Ring Contexts are disabled\n");
+		return 0;
+	}
+
+	ret = mutex_lock_interruptible(&dev->struct_mutex);
+	if (ret)
+		return ret;
+
+	list_for_each_entry(ctx, &dev_priv->context_list, link)
+		if (ctx != dev_priv->kernel_context)
+			for_each_engine(engine, dev_priv)
+				i915_dump_lrc_obj(m, ctx, engine);
+
+	mutex_unlock(&dev->struct_mutex);
+
+	return 0;
+}
+
+static int i915_execlists(struct seq_file *m, void *data)
+{
+	struct drm_info_node *node = (struct drm_info_node *)m->private;
+	struct drm_device *dev = node->minor->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_engine_cs *engine;
+	u32 status_pointer;
+	u8 read_pointer;
+	u8 write_pointer;
+	u32 status;
+	u32 ctx_id;
+	struct list_head *cursor;
+	int i, ret;
+
+	if (!i915.enable_execlists) {
+		seq_puts(m, "Logical Ring Contexts are disabled\n");
+		return 0;
+	}
+
+	ret = mutex_lock_interruptible(&dev->struct_mutex);
+	if (ret)
+		return ret;
+
+	intel_runtime_pm_get(dev_priv);
+
+	for_each_engine(engine, dev_priv) {
+		struct drm_i915_gem_request *head_req = NULL;
+		int count = 0;
+
+		seq_printf(m, "%s\n", engine->name);
+
+		status = I915_READ(RING_EXECLIST_STATUS_LO(engine));
+		ctx_id = I915_READ(RING_EXECLIST_STATUS_HI(engine));
+		seq_printf(m, "\tExeclist status: 0x%08X, context: %u\n",
+			   status, ctx_id);
+
+		status_pointer = I915_READ(RING_CONTEXT_STATUS_PTR(engine));
+		seq_printf(m, "\tStatus pointer: 0x%08X\n", status_pointer);
+
+		read_pointer = engine->next_context_status_buffer;
+		write_pointer = GEN8_CSB_WRITE_PTR(status_pointer);
+		if (read_pointer > write_pointer)
+			write_pointer += GEN8_CSB_ENTRIES;
+		seq_printf(m, "\tRead pointer: 0x%08X, write pointer 0x%08X\n",
+			   read_pointer, write_pointer);
+
+		for (i = 0; i < GEN8_CSB_ENTRIES; i++) {
+			status = I915_READ(RING_CONTEXT_STATUS_BUF_LO(engine, i));
+			ctx_id = I915_READ(RING_CONTEXT_STATUS_BUF_HI(engine, i));
+
+			seq_printf(m, "\tStatus buffer %d: 0x%08X, context: %u\n",
+				   i, status, ctx_id);
+		}
+
+		spin_lock_bh(&engine->execlist_lock);
+		list_for_each(cursor, &engine->execlist_queue)
+			count++;
+		head_req = list_first_entry_or_null(&engine->execlist_queue,
+						    struct drm_i915_gem_request,
+						    execlist_link);
+		spin_unlock_bh(&engine->execlist_lock);
+
+		seq_printf(m, "\t%d requests in queue\n", count);
+		if (head_req) {
+			seq_printf(m, "\tHead request id: %u\n",
+				   intel_execlists_ctx_id(head_req->ctx, engine));
+			seq_printf(m, "\tHead request tail: %u\n",
+				   head_req->tail);
+		}
+
+		seq_putc(m, '\n');
+	}
+
+	intel_runtime_pm_put(dev_priv);
+	mutex_unlock(&dev->struct_mutex);
+
+	return 0;
+}
+
+static const char *swizzle_string(unsigned swizzle)
+{
+	switch (swizzle) {
+	case I915_BIT_6_SWIZZLE_NONE:
+		return "none";
+	case I915_BIT_6_SWIZZLE_9:
+		return "bit9";
+	case I915_BIT_6_SWIZZLE_9_10:
+		return "bit9/bit10";
+	case I915_BIT_6_SWIZZLE_9_11:
+		return "bit9/bit11";
+	case I915_BIT_6_SWIZZLE_9_10_11:
+		return "bit9/bit10/bit11";
+	case I915_BIT_6_SWIZZLE_9_17:
+		return "bit9/bit17";
+	case I915_BIT_6_SWIZZLE_9_10_17:
+		return "bit9/bit10/bit17";
+	case I915_BIT_6_SWIZZLE_UNKNOWN:
+		return "unknown";
+	}
+
+	return "bug";
+}
+
+static int i915_swizzle_info(struct seq_file *m, void *data)
+{
+	struct drm_info_node *node = m->private;
+	struct drm_device *dev = node->minor->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	int ret;
+
+	ret = mutex_lock_interruptible(&dev->struct_mutex);
+	if (ret)
+		return ret;
+	intel_runtime_pm_get(dev_priv);
+
+	seq_printf(m, "bit6 swizzle for X-tiling = %s\n",
+		   swizzle_string(dev_priv->mm.bit_6_swizzle_x));
+	seq_printf(m, "bit6 swizzle for Y-tiling = %s\n",
+		   swizzle_string(dev_priv->mm.bit_6_swizzle_y));
+
+	if (IS_GEN3(dev) || IS_GEN4(dev)) {
+		seq_printf(m, "DDC = 0x%08x\n",
+			   I915_READ(DCC));
+		seq_printf(m, "DDC2 = 0x%08x\n",
+			   I915_READ(DCC2));
+		seq_printf(m, "C0DRB3 = 0x%04x\n",
+			   I915_READ16(C0DRB3));
+		seq_printf(m, "C1DRB3 = 0x%04x\n",
+			   I915_READ16(C1DRB3));
+	} else if (INTEL_INFO(dev)->gen >= 6) {
+		seq_printf(m, "MAD_DIMM_C0 = 0x%08x\n",
+			   I915_READ(MAD_DIMM_C0));
+		seq_printf(m, "MAD_DIMM_C1 = 0x%08x\n",
+			   I915_READ(MAD_DIMM_C1));
+		seq_printf(m, "MAD_DIMM_C2 = 0x%08x\n",
+			   I915_READ(MAD_DIMM_C2));
+		seq_printf(m, "TILECTL = 0x%08x\n",
+			   I915_READ(TILECTL));
+		if (INTEL_INFO(dev)->gen >= 8)
+			seq_printf(m, "GAMTARBMODE = 0x%08x\n",
+				   I915_READ(GAMTARBMODE));
+		else
+			seq_printf(m, "ARB_MODE = 0x%08x\n",
+				   I915_READ(ARB_MODE));
+		seq_printf(m, "DISP_ARB_CTL = 0x%08x\n",
+			   I915_READ(DISP_ARB_CTL));
+	}
+
+	if (dev_priv->quirks & QUIRK_PIN_SWIZZLED_PAGES)
+		seq_puts(m, "L-shaped memory detected\n");
+
+	intel_runtime_pm_put(dev_priv);
+	mutex_unlock(&dev->struct_mutex);
+
+	return 0;
+}
+
+static int per_file_ctx(int id, void *ptr, void *data)
+{
+	struct intel_context *ctx = ptr;
+	struct seq_file *m = data;
+	struct i915_hw_ppgtt *ppgtt = ctx->ppgtt;
+
+	if (!ppgtt) {
+		seq_printf(m, "  no ppgtt for context %d\n",
+			   ctx->user_handle);
+		return 0;
+	}
+
+	if (i915_gem_context_is_default(ctx))
+		seq_puts(m, "  default context:\n");
+	else
+		seq_printf(m, "  context %d:\n", ctx->user_handle);
+	ppgtt->debug_dump(ppgtt, m);
+
+	return 0;
+}
+
+static void gen8_ppgtt_info(struct seq_file *m, struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_engine_cs *engine;
+	struct i915_hw_ppgtt *ppgtt = dev_priv->mm.aliasing_ppgtt;
+	int i;
+
+	if (!ppgtt)
+		return;
+
+	for_each_engine(engine, dev_priv) {
+		seq_printf(m, "%s\n", engine->name);
+		for (i = 0; i < 4; i++) {
+			u64 pdp = I915_READ(GEN8_RING_PDP_UDW(engine, i));
+			pdp <<= 32;
+			pdp |= I915_READ(GEN8_RING_PDP_LDW(engine, i));
+			seq_printf(m, "\tPDP%d 0x%016llx\n", i, pdp);
+		}
+	}
+}
+
+static void gen6_ppgtt_info(struct seq_file *m, struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_engine_cs *engine;
+
+	if (INTEL_INFO(dev)->gen == 6)
+		seq_printf(m, "GFX_MODE: 0x%08x\n", I915_READ(GFX_MODE));
+
+	for_each_engine(engine, dev_priv) {
+		seq_printf(m, "%s\n", engine->name);
+		if (INTEL_INFO(dev)->gen == 7)
+			seq_printf(m, "GFX_MODE: 0x%08x\n",
+				   I915_READ(RING_MODE_GEN7(engine)));
+		seq_printf(m, "PP_DIR_BASE: 0x%08x\n",
+			   I915_READ(RING_PP_DIR_BASE(engine)));
+		seq_printf(m, "PP_DIR_BASE_READ: 0x%08x\n",
+			   I915_READ(RING_PP_DIR_BASE_READ(engine)));
+		seq_printf(m, "PP_DIR_DCLV: 0x%08x\n",
+			   I915_READ(RING_PP_DIR_DCLV(engine)));
+	}
+	if (dev_priv->mm.aliasing_ppgtt) {
+		struct i915_hw_ppgtt *ppgtt = dev_priv->mm.aliasing_ppgtt;
+
+		seq_puts(m, "aliasing PPGTT:\n");
+		seq_printf(m, "pd gtt offset: 0x%08x\n", ppgtt->pd.base.ggtt_offset);
+
+		ppgtt->debug_dump(ppgtt, m);
+	}
+
+	seq_printf(m, "ECOCHK: 0x%08x\n", I915_READ(GAM_ECOCHK));
+}
+
+static int i915_ppgtt_info(struct seq_file *m, void *data)
+{
+	struct drm_info_node *node = m->private;
+	struct drm_device *dev = node->minor->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct drm_file *file;
+
+	int ret = mutex_lock_interruptible(&dev->struct_mutex);
+	if (ret)
+		return ret;
+	intel_runtime_pm_get(dev_priv);
+
+	if (INTEL_INFO(dev)->gen >= 8)
+		gen8_ppgtt_info(m, dev);
+	else if (INTEL_INFO(dev)->gen >= 6)
+		gen6_ppgtt_info(m, dev);
+
+	list_for_each_entry_reverse(file, &dev->filelist, lhead) {
+		struct drm_i915_file_private *file_priv = file->driver_priv;
+		struct task_struct *task;
+
+		task = get_pid_task(file->pid, PIDTYPE_PID);
+		if (!task) {
+			ret = -ESRCH;
+			goto out_put;
+		}
+		seq_printf(m, "\nproc: %s\n", task->comm);
+		put_task_struct(task);
+		idr_for_each(&file_priv->context_idr, per_file_ctx,
+			     (void *)(unsigned long)m);
+	}
+
+out_put:
+	intel_runtime_pm_put(dev_priv);
+	mutex_unlock(&dev->struct_mutex);
+
+	return ret;
+}
+
+static int count_irq_waiters(struct drm_i915_private *i915)
+{
+	struct intel_engine_cs *engine;
+	int count = 0;
+
+	for_each_engine(engine, i915)
+		count += engine->irq_refcount;
+
+	return count;
+}
+
+static int i915_rps_boost_info(struct seq_file *m, void *data)
+{
+	struct drm_info_node *node = m->private;
+	struct drm_device *dev = node->minor->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct drm_file *file;
+
+	seq_printf(m, "RPS enabled? %d\n", dev_priv->rps.enabled);
+	seq_printf(m, "GPU busy? %d\n", dev_priv->mm.busy);
+	seq_printf(m, "CPU waiting? %d\n", count_irq_waiters(dev_priv));
+	seq_printf(m, "Frequency requested %d; min hard:%d, soft:%d; max soft:%d, hard:%d\n",
+		   intel_gpu_freq(dev_priv, dev_priv->rps.cur_freq),
+		   intel_gpu_freq(dev_priv, dev_priv->rps.min_freq),
+		   intel_gpu_freq(dev_priv, dev_priv->rps.min_freq_softlimit),
+		   intel_gpu_freq(dev_priv, dev_priv->rps.max_freq_softlimit),
+		   intel_gpu_freq(dev_priv, dev_priv->rps.max_freq));
+	spin_lock(&dev_priv->rps.client_lock);
+	list_for_each_entry_reverse(file, &dev->filelist, lhead) {
+		struct drm_i915_file_private *file_priv = file->driver_priv;
+		struct task_struct *task;
+
+		rcu_read_lock();
+		task = pid_task(file->pid, PIDTYPE_PID);
+		seq_printf(m, "%s [%d]: %d boosts%s\n",
+			   task ? task->comm : "<unknown>",
+			   task ? task->pid : -1,
+			   file_priv->rps.boosts,
+			   list_empty(&file_priv->rps.link) ? "" : ", active");
+		rcu_read_unlock();
+	}
+	seq_printf(m, "Semaphore boosts: %d%s\n",
+		   dev_priv->rps.semaphores.boosts,
+		   list_empty(&dev_priv->rps.semaphores.link) ? "" : ", active");
+	seq_printf(m, "MMIO flip boosts: %d%s\n",
+		   dev_priv->rps.mmioflips.boosts,
+		   list_empty(&dev_priv->rps.mmioflips.link) ? "" : ", active");
+	seq_printf(m, "Kernel boosts: %d\n", dev_priv->rps.boosts);
+	spin_unlock(&dev_priv->rps.client_lock);
+
+	return 0;
+}
+
+static int i915_llc(struct seq_file *m, void *data)
+{
+	struct drm_info_node *node = m->private;
+	struct drm_device *dev = node->minor->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	const bool edram = INTEL_GEN(dev_priv) > 8;
+
+	seq_printf(m, "LLC: %s\n", yesno(HAS_LLC(dev)));
+	seq_printf(m, "%s: %lluMB\n", edram ? "eDRAM" : "eLLC",
+		   intel_uncore_edram_size(dev_priv)/1024/1024);
+
+	return 0;
+}
+
+static int i915_guc_load_status_info(struct seq_file *m, void *data)
+{
+	struct drm_info_node *node = m->private;
+	struct drm_i915_private *dev_priv = node->minor->dev->dev_private;
+	struct intel_guc_fw *guc_fw = &dev_priv->guc.guc_fw;
+	u32 tmp, i;
+
+	if (!HAS_GUC_UCODE(dev_priv))
+		return 0;
+
+	seq_printf(m, "GuC firmware status:\n");
+	seq_printf(m, "\tpath: %s\n",
+		guc_fw->guc_fw_path);
+	seq_printf(m, "\tfetch: %s\n",
+		intel_guc_fw_status_repr(guc_fw->guc_fw_fetch_status));
+	seq_printf(m, "\tload: %s\n",
+		intel_guc_fw_status_repr(guc_fw->guc_fw_load_status));
+	seq_printf(m, "\tversion wanted: %d.%d\n",
+		guc_fw->guc_fw_major_wanted, guc_fw->guc_fw_minor_wanted);
+	seq_printf(m, "\tversion found: %d.%d\n",
+		guc_fw->guc_fw_major_found, guc_fw->guc_fw_minor_found);
+	seq_printf(m, "\theader: offset is %d; size = %d\n",
+		guc_fw->header_offset, guc_fw->header_size);
+	seq_printf(m, "\tuCode: offset is %d; size = %d\n",
+		guc_fw->ucode_offset, guc_fw->ucode_size);
+	seq_printf(m, "\tRSA: offset is %d; size = %d\n",
+		guc_fw->rsa_offset, guc_fw->rsa_size);
+
+	tmp = I915_READ(GUC_STATUS);
+
+	seq_printf(m, "\nGuC status 0x%08x:\n", tmp);
+	seq_printf(m, "\tBootrom status = 0x%x\n",
+		(tmp & GS_BOOTROM_MASK) >> GS_BOOTROM_SHIFT);
+	seq_printf(m, "\tuKernel status = 0x%x\n",
+		(tmp & GS_UKERNEL_MASK) >> GS_UKERNEL_SHIFT);
+	seq_printf(m, "\tMIA Core status = 0x%x\n",
+		(tmp & GS_MIA_MASK) >> GS_MIA_SHIFT);
+	seq_puts(m, "\nScratch registers:\n");
+	for (i = 0; i < 16; i++)
+		seq_printf(m, "\t%2d: \t0x%x\n", i, I915_READ(SOFT_SCRATCH(i)));
+
+	return 0;
+}
+
+static void i915_guc_client_info(struct seq_file *m,
+				 struct drm_i915_private *dev_priv,
+				 struct i915_guc_client *client)
+{
+	struct intel_engine_cs *engine;
+	uint64_t tot = 0;
+
+	seq_printf(m, "\tPriority %d, GuC ctx index: %u, PD offset 0x%x\n",
+		client->priority, client->ctx_index, client->proc_desc_offset);
+	seq_printf(m, "\tDoorbell id %d, offset: 0x%x, cookie 0x%x\n",
+		client->doorbell_id, client->doorbell_offset, client->cookie);
+	seq_printf(m, "\tWQ size %d, offset: 0x%x, tail %d\n",
+		client->wq_size, client->wq_offset, client->wq_tail);
+
+	seq_printf(m, "\tFailed to queue: %u\n", client->q_fail);
+	seq_printf(m, "\tFailed doorbell: %u\n", client->b_fail);
+	seq_printf(m, "\tLast submission result: %d\n", client->retcode);
+
+	for_each_engine(engine, dev_priv) {
+		seq_printf(m, "\tSubmissions: %llu %s\n",
+				client->submissions[engine->guc_id],
+				engine->name);
+		tot += client->submissions[engine->guc_id];
+	}
+	seq_printf(m, "\tTotal: %llu\n", tot);
+}
+
+static int i915_guc_info(struct seq_file *m, void *data)
+{
+	struct drm_info_node *node = m->private;
+	struct drm_device *dev = node->minor->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_guc guc;
+	struct i915_guc_client client = {};
+	struct intel_engine_cs *engine;
+	u64 total = 0;
+
+	if (!HAS_GUC_SCHED(dev_priv))
+		return 0;
+
+	if (mutex_lock_interruptible(&dev->struct_mutex))
+		return 0;
+
+	/* Take a local copy of the GuC data, so we can dump it at leisure */
+	guc = dev_priv->guc;
+	if (guc.execbuf_client)
+		client = *guc.execbuf_client;
+
+	mutex_unlock(&dev->struct_mutex);
+
+	seq_printf(m, "GuC total action count: %llu\n", guc.action_count);
+	seq_printf(m, "GuC action failure count: %u\n", guc.action_fail);
+	seq_printf(m, "GuC last action command: 0x%x\n", guc.action_cmd);
+	seq_printf(m, "GuC last action status: 0x%x\n", guc.action_status);
+	seq_printf(m, "GuC last action error code: %d\n", guc.action_err);
+
+	seq_printf(m, "\nGuC submissions:\n");
+	for_each_engine(engine, dev_priv) {
+		seq_printf(m, "\t%-24s: %10llu, last seqno 0x%08x\n",
+			engine->name, guc.submissions[engine->guc_id],
+			guc.last_seqno[engine->guc_id]);
+		total += guc.submissions[engine->guc_id];
+	}
+	seq_printf(m, "\t%s: %llu\n", "Total", total);
+
+	seq_printf(m, "\nGuC execbuf client @ %p:\n", guc.execbuf_client);
+	i915_guc_client_info(m, dev_priv, &client);
+
+	/* Add more as required ... */
+
+	return 0;
+}
+
+static int i915_guc_log_dump(struct seq_file *m, void *data)
+{
+	struct drm_info_node *node = m->private;
+	struct drm_device *dev = node->minor->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct drm_i915_gem_object *log_obj = dev_priv->guc.log_obj;
+	u32 *log;
+	int i = 0, pg;
+
+	if (!log_obj)
+		return 0;
+
+	for (pg = 0; pg < log_obj->base.size / PAGE_SIZE; pg++) {
+		log = kmap_atomic(i915_gem_object_get_page(log_obj, pg));
+
+		for (i = 0; i < PAGE_SIZE / sizeof(u32); i += 4)
+			seq_printf(m, "0x%08x 0x%08x 0x%08x 0x%08x\n",
+				   *(log + i), *(log + i + 1),
+				   *(log + i + 2), *(log + i + 3));
+
+		kunmap_atomic(log);
+	}
+
+	seq_putc(m, '\n');
+
+	return 0;
+}
+
+static int i915_edp_psr_status(struct seq_file *m, void *data)
+{
+	struct drm_info_node *node = m->private;
+	struct drm_device *dev = node->minor->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	u32 psrperf = 0;
+	u32 stat[3];
+	enum pipe pipe;
+	bool enabled = false;
+
+	if (!HAS_PSR(dev)) {
+		seq_puts(m, "PSR not supported\n");
+		return 0;
+	}
+
+	intel_runtime_pm_get(dev_priv);
+
+	mutex_lock(&dev_priv->psr.lock);
+	seq_printf(m, "Sink_Support: %s\n", yesno(dev_priv->psr.sink_support));
+	seq_printf(m, "Source_OK: %s\n", yesno(dev_priv->psr.source_ok));
+	seq_printf(m, "Enabled: %s\n", yesno((bool)dev_priv->psr.enabled));
+	seq_printf(m, "Active: %s\n", yesno(dev_priv->psr.active));
+	seq_printf(m, "Busy frontbuffer bits: 0x%03x\n",
+		   dev_priv->psr.busy_frontbuffer_bits);
+	seq_printf(m, "Re-enable work scheduled: %s\n",
+		   yesno(work_busy(&dev_priv->psr.work.work)));
+
+	if (HAS_DDI(dev))
+		enabled = I915_READ(EDP_PSR_CTL) & EDP_PSR_ENABLE;
+	else {
+		for_each_pipe(dev_priv, pipe) {
+			stat[pipe] = I915_READ(VLV_PSRSTAT(pipe)) &
+				VLV_EDP_PSR_CURR_STATE_MASK;
+			if ((stat[pipe] == VLV_EDP_PSR_ACTIVE_NORFB_UP) ||
+			    (stat[pipe] == VLV_EDP_PSR_ACTIVE_SF_UPDATE))
+				enabled = true;
+		}
+	}
+
+	seq_printf(m, "Main link in standby mode: %s\n",
+		   yesno(dev_priv->psr.link_standby));
+
+	seq_printf(m, "HW Enabled & Active bit: %s", yesno(enabled));
+
+	if (!HAS_DDI(dev))
+		for_each_pipe(dev_priv, pipe) {
+			if ((stat[pipe] == VLV_EDP_PSR_ACTIVE_NORFB_UP) ||
+			    (stat[pipe] == VLV_EDP_PSR_ACTIVE_SF_UPDATE))
+				seq_printf(m, " pipe %c", pipe_name(pipe));
+		}
+	seq_puts(m, "\n");
+
+	/*
+	 * VLV/CHV PSR has no kind of performance counter
+	 * SKL+ Perf counter is reset to 0 everytime DC state is entered
+	 */
+	if (IS_HASWELL(dev) || IS_BROADWELL(dev)) {
+		psrperf = I915_READ(EDP_PSR_PERF_CNT) &
+			EDP_PSR_PERF_CNT_MASK;
+
+		seq_printf(m, "Performance_Counter: %u\n", psrperf);
+	}
+	mutex_unlock(&dev_priv->psr.lock);
+
+	intel_runtime_pm_put(dev_priv);
+	return 0;
+}
+
+static int i915_sink_crc(struct seq_file *m, void *data)
+{
+	struct drm_info_node *node = m->private;
+	struct drm_device *dev = node->minor->dev;
+	struct intel_encoder *encoder;
+	struct intel_connector *connector;
+	struct intel_dp *intel_dp = NULL;
+	int ret;
+	u8 crc[6];
+
+	drm_modeset_lock_all(dev);
+	for_each_intel_connector(dev, connector) {
+
+		if (connector->base.dpms != DRM_MODE_DPMS_ON)
+			continue;
+
+		if (!connector->base.encoder)
+			continue;
+
+		encoder = to_intel_encoder(connector->base.encoder);
+		if (encoder->type != INTEL_OUTPUT_EDP)
+			continue;
+
+		intel_dp = enc_to_intel_dp(&encoder->base);
+
+		ret = intel_dp_sink_crc(intel_dp, crc);
+		if (ret)
+			goto out;
+
+		seq_printf(m, "%02x%02x%02x%02x%02x%02x\n",
+			   crc[0], crc[1], crc[2],
+			   crc[3], crc[4], crc[5]);
+		goto out;
+	}
+	ret = -ENODEV;
+out:
+	drm_modeset_unlock_all(dev);
+	return ret;
+}
+
+static int i915_energy_uJ(struct seq_file *m, void *data)
+{
+	struct drm_info_node *node = m->private;
+	struct drm_device *dev = node->minor->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	u64 power;
+	u32 units;
+
+	if (INTEL_INFO(dev)->gen < 6)
+		return -ENODEV;
+
+	intel_runtime_pm_get(dev_priv);
+
+	rdmsrl(MSR_RAPL_POWER_UNIT, power);
+	power = (power & 0x1f00) >> 8;
+	units = 1000000 / (1 << power); /* convert to uJ */
+	power = I915_READ(MCH_SECP_NRG_STTS);
+	power *= units;
+
+	intel_runtime_pm_put(dev_priv);
+
+	seq_printf(m, "%llu", (long long unsigned)power);
+
+	return 0;
+}
+
+static int i915_runtime_pm_status(struct seq_file *m, void *unused)
+{
+	struct drm_info_node *node = m->private;
+	struct drm_device *dev = node->minor->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	if (!HAS_RUNTIME_PM(dev_priv))
+		seq_puts(m, "Runtime power management not supported\n");
+
+	seq_printf(m, "GPU idle: %s\n", yesno(!dev_priv->mm.busy));
+	seq_printf(m, "IRQs disabled: %s\n",
+		   yesno(!intel_irqs_enabled(dev_priv)));
+#ifdef CONFIG_PM
+	seq_printf(m, "Usage count: %d\n",
+		   atomic_read(&dev->dev->power.usage_count));
+#else
+	seq_printf(m, "Device Power Management (CONFIG_PM) disabled\n");
+#endif
+	seq_printf(m, "PCI device power state: %s [%d]\n",
+		   pci_power_name(dev_priv->dev->pdev->current_state),
+		   dev_priv->dev->pdev->current_state);
+
+	return 0;
+}
+
+static int i915_power_domain_info(struct seq_file *m, void *unused)
+{
+	struct drm_info_node *node = m->private;
+	struct drm_device *dev = node->minor->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct i915_power_domains *power_domains = &dev_priv->power_domains;
+	int i;
+
+	mutex_lock(&power_domains->lock);
+
+	seq_printf(m, "%-25s %s\n", "Power well/domain", "Use count");
+	for (i = 0; i < power_domains->power_well_count; i++) {
+		struct i915_power_well *power_well;
+		enum intel_display_power_domain power_domain;
+
+		power_well = &power_domains->power_wells[i];
+		seq_printf(m, "%-25s %d\n", power_well->name,
+			   power_well->count);
+
+		for (power_domain = 0; power_domain < POWER_DOMAIN_NUM;
+		     power_domain++) {
+			if (!(BIT(power_domain) & power_well->domains))
+				continue;
+
+			seq_printf(m, "  %-23s %d\n",
+				 intel_display_power_domain_str(power_domain),
+				 power_domains->domain_use_count[power_domain]);
+		}
+	}
+
+	mutex_unlock(&power_domains->lock);
+
+	return 0;
+}
+
+static int i915_dmc_info(struct seq_file *m, void *unused)
+{
+	struct drm_info_node *node = m->private;
+	struct drm_device *dev = node->minor->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_csr *csr;
+
+	if (!HAS_CSR(dev)) {
+		seq_puts(m, "not supported\n");
+		return 0;
+	}
+
+	csr = &dev_priv->csr;
+
+	intel_runtime_pm_get(dev_priv);
+
+	seq_printf(m, "fw loaded: %s\n", yesno(csr->dmc_payload != NULL));
+	seq_printf(m, "path: %s\n", csr->fw_path);
+
+	if (!csr->dmc_payload)
+		goto out;
+
+	seq_printf(m, "version: %d.%d\n", CSR_VERSION_MAJOR(csr->version),
+		   CSR_VERSION_MINOR(csr->version));
+
+	if (IS_SKYLAKE(dev) && csr->version >= CSR_VERSION(1, 6)) {
+		seq_printf(m, "DC3 -> DC5 count: %d\n",
+			   I915_READ(SKL_CSR_DC3_DC5_COUNT));
+		seq_printf(m, "DC5 -> DC6 count: %d\n",
+			   I915_READ(SKL_CSR_DC5_DC6_COUNT));
+	} else if (IS_BROXTON(dev) && csr->version >= CSR_VERSION(1, 4)) {
+		seq_printf(m, "DC3 -> DC5 count: %d\n",
+			   I915_READ(BXT_CSR_DC3_DC5_COUNT));
+	}
+
+out:
+	seq_printf(m, "program base: 0x%08x\n", I915_READ(CSR_PROGRAM(0)));
+	seq_printf(m, "ssp base: 0x%08x\n", I915_READ(CSR_SSP_BASE));
+	seq_printf(m, "htp: 0x%08x\n", I915_READ(CSR_HTP_SKL));
+
+	intel_runtime_pm_put(dev_priv);
+
+	return 0;
+}
+
+static void intel_seq_print_mode(struct seq_file *m, int tabs,
+				 struct drm_display_mode *mode)
+{
+	int i;
+
+	for (i = 0; i < tabs; i++)
+		seq_putc(m, '\t');
+
+	seq_printf(m, "id %d:\"%s\" freq %d clock %d hdisp %d hss %d hse %d htot %d vdisp %d vss %d vse %d vtot %d type 0x%x flags 0x%x\n",
+		   mode->base.id, mode->name,
+		   mode->vrefresh, mode->clock,
+		   mode->hdisplay, mode->hsync_start,
+		   mode->hsync_end, mode->htotal,
+		   mode->vdisplay, mode->vsync_start,
+		   mode->vsync_end, mode->vtotal,
+		   mode->type, mode->flags);
+}
+
+static void intel_encoder_info(struct seq_file *m,
+			       struct intel_crtc *intel_crtc,
+			       struct intel_encoder *intel_encoder)
+{
+	struct drm_info_node *node = m->private;
+	struct drm_device *dev = node->minor->dev;
+	struct drm_crtc *crtc = &intel_crtc->base;
+	struct intel_connector *intel_connector;
+	struct drm_encoder *encoder;
+
+	encoder = &intel_encoder->base;
+	seq_printf(m, "\tencoder %d: type: %s, connectors:\n",
+		   encoder->base.id, encoder->name);
+	for_each_connector_on_encoder(dev, encoder, intel_connector) {
+		struct drm_connector *connector = &intel_connector->base;
+		seq_printf(m, "\t\tconnector %d: type: %s, status: %s",
+			   connector->base.id,
+			   connector->name,
+			   drm_get_connector_status_name(connector->status));
+		if (connector->status == connector_status_connected) {
+			struct drm_display_mode *mode = &crtc->mode;
+			seq_printf(m, ", mode:\n");
+			intel_seq_print_mode(m, 2, mode);
+		} else {
+			seq_putc(m, '\n');
+		}
+	}
+}
+
+static void intel_crtc_info(struct seq_file *m, struct intel_crtc *intel_crtc)
+{
+	struct drm_info_node *node = m->private;
+	struct drm_device *dev = node->minor->dev;
+	struct drm_crtc *crtc = &intel_crtc->base;
+	struct intel_encoder *intel_encoder;
+	struct drm_plane_state *plane_state = crtc->primary->state;
+	struct drm_framebuffer *fb = plane_state->fb;
+
+	if (fb)
+		seq_printf(m, "\tfb: %d, pos: %dx%d, size: %dx%d\n",
+			   fb->base.id, plane_state->src_x >> 16,
+			   plane_state->src_y >> 16, fb->width, fb->height);
+	else
+		seq_puts(m, "\tprimary plane disabled\n");
+	for_each_encoder_on_crtc(dev, crtc, intel_encoder)
+		intel_encoder_info(m, intel_crtc, intel_encoder);
+}
+
+static void intel_panel_info(struct seq_file *m, struct intel_panel *panel)
+{
+	struct drm_display_mode *mode = panel->fixed_mode;
+
+	seq_printf(m, "\tfixed mode:\n");
+	intel_seq_print_mode(m, 2, mode);
+}
+
+static void intel_dp_info(struct seq_file *m,
+			  struct intel_connector *intel_connector)
+{
+	struct intel_encoder *intel_encoder = intel_connector->encoder;
+	struct intel_dp *intel_dp = enc_to_intel_dp(&intel_encoder->base);
+
+	seq_printf(m, "\tDPCD rev: %x\n", intel_dp->dpcd[DP_DPCD_REV]);
+	seq_printf(m, "\taudio support: %s\n", yesno(intel_dp->has_audio));
+	if (intel_encoder->type == INTEL_OUTPUT_EDP)
+		intel_panel_info(m, &intel_connector->panel);
+}
+
+static void intel_hdmi_info(struct seq_file *m,
+			    struct intel_connector *intel_connector)
+{
+	struct intel_encoder *intel_encoder = intel_connector->encoder;
+	struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&intel_encoder->base);
+
+	seq_printf(m, "\taudio support: %s\n", yesno(intel_hdmi->has_audio));
+}
+
+static void intel_lvds_info(struct seq_file *m,
+			    struct intel_connector *intel_connector)
+{
+	intel_panel_info(m, &intel_connector->panel);
+}
+
+static void intel_connector_info(struct seq_file *m,
+				 struct drm_connector *connector)
+{
+	struct intel_connector *intel_connector = to_intel_connector(connector);
+	struct intel_encoder *intel_encoder = intel_connector->encoder;
+	struct drm_display_mode *mode;
+
+	seq_printf(m, "connector %d: type %s, status: %s\n",
+		   connector->base.id, connector->name,
+		   drm_get_connector_status_name(connector->status));
+	if (connector->status == connector_status_connected) {
+		seq_printf(m, "\tname: %s\n", connector->display_info.name);
+		seq_printf(m, "\tphysical dimensions: %dx%dmm\n",
+			   connector->display_info.width_mm,
+			   connector->display_info.height_mm);
+		seq_printf(m, "\tsubpixel order: %s\n",
+			   drm_get_subpixel_order_name(connector->display_info.subpixel_order));
+		seq_printf(m, "\tCEA rev: %d\n",
+			   connector->display_info.cea_rev);
+	}
+	if (intel_encoder) {
+		if (intel_encoder->type == INTEL_OUTPUT_DISPLAYPORT ||
+		    intel_encoder->type == INTEL_OUTPUT_EDP)
+			intel_dp_info(m, intel_connector);
+		else if (intel_encoder->type == INTEL_OUTPUT_HDMI)
+			intel_hdmi_info(m, intel_connector);
+		else if (intel_encoder->type == INTEL_OUTPUT_LVDS)
+			intel_lvds_info(m, intel_connector);
+	}
+
+	seq_printf(m, "\tmodes:\n");
+	list_for_each_entry(mode, &connector->modes, head)
+		intel_seq_print_mode(m, 2, mode);
+}
+
+static bool cursor_active(struct drm_device *dev, int pipe)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	u32 state;
+
+	if (IS_845G(dev) || IS_I865G(dev))
+		state = I915_READ(CURCNTR(PIPE_A)) & CURSOR_ENABLE;
+	else
+		state = I915_READ(CURCNTR(pipe)) & CURSOR_MODE;
+
+	return state;
+}
+
+static bool cursor_position(struct drm_device *dev, int pipe, int *x, int *y)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	u32 pos;
+
+	pos = I915_READ(CURPOS(pipe));
+
+	*x = (pos >> CURSOR_X_SHIFT) & CURSOR_POS_MASK;
+	if (pos & (CURSOR_POS_SIGN << CURSOR_X_SHIFT))
+		*x = -*x;
+
+	*y = (pos >> CURSOR_Y_SHIFT) & CURSOR_POS_MASK;
+	if (pos & (CURSOR_POS_SIGN << CURSOR_Y_SHIFT))
+		*y = -*y;
+
+	return cursor_active(dev, pipe);
+}
+
+static const char *plane_type(enum drm_plane_type type)
+{
+	switch (type) {
+	case DRM_PLANE_TYPE_OVERLAY:
+		return "OVL";
+	case DRM_PLANE_TYPE_PRIMARY:
+		return "PRI";
+	case DRM_PLANE_TYPE_CURSOR:
+		return "CUR";
+	/*
+	 * Deliberately omitting default: to generate compiler warnings
+	 * when a new drm_plane_type gets added.
+	 */
+	}
+
+	return "unknown";
+}
+
+static const char *plane_rotation(unsigned int rotation)
+{
+	static char buf[48];
+	/*
+	 * According to doc only one DRM_ROTATE_ is allowed but this
+	 * will print them all to visualize if the values are misused
+	 */
+	snprintf(buf, sizeof(buf),
+		 "%s%s%s%s%s%s(0x%08x)",
+		 (rotation & BIT(DRM_ROTATE_0)) ? "0 " : "",
+		 (rotation & BIT(DRM_ROTATE_90)) ? "90 " : "",
+		 (rotation & BIT(DRM_ROTATE_180)) ? "180 " : "",
+		 (rotation & BIT(DRM_ROTATE_270)) ? "270 " : "",
+		 (rotation & BIT(DRM_REFLECT_X)) ? "FLIPX " : "",
+		 (rotation & BIT(DRM_REFLECT_Y)) ? "FLIPY " : "",
+		 rotation);
+
+	return buf;
+}
+
+static void intel_plane_info(struct seq_file *m, struct intel_crtc *intel_crtc)
+{
+	struct drm_info_node *node = m->private;
+	struct drm_device *dev = node->minor->dev;
+	struct intel_plane *intel_plane;
+
+	for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane) {
+		struct drm_plane_state *state;
+		struct drm_plane *plane = &intel_plane->base;
+
+		if (!plane->state) {
+			seq_puts(m, "plane->state is NULL!\n");
+			continue;
+		}
+
+		state = plane->state;
+
+		seq_printf(m, "\t--Plane id %d: type=%s, crtc_pos=%4dx%4d, crtc_size=%4dx%4d, src_pos=%d.%04ux%d.%04u, src_size=%d.%04ux%d.%04u, format=%s, rotation=%s\n",
+			   plane->base.id,
+			   plane_type(intel_plane->base.type),
+			   state->crtc_x, state->crtc_y,
+			   state->crtc_w, state->crtc_h,
+			   (state->src_x >> 16),
+			   ((state->src_x & 0xffff) * 15625) >> 10,
+			   (state->src_y >> 16),
+			   ((state->src_y & 0xffff) * 15625) >> 10,
+			   (state->src_w >> 16),
+			   ((state->src_w & 0xffff) * 15625) >> 10,
+			   (state->src_h >> 16),
+			   ((state->src_h & 0xffff) * 15625) >> 10,
+			   state->fb ? drm_get_format_name(state->fb->pixel_format) : "N/A",
+			   plane_rotation(state->rotation));
+	}
+}
+
+static void intel_scaler_info(struct seq_file *m, struct intel_crtc *intel_crtc)
+{
+	struct intel_crtc_state *pipe_config;
+	int num_scalers = intel_crtc->num_scalers;
+	int i;
+
+	pipe_config = to_intel_crtc_state(intel_crtc->base.state);
+
+	/* Not all platformas have a scaler */
+	if (num_scalers) {
+		seq_printf(m, "\tnum_scalers=%d, scaler_users=%x scaler_id=%d",
+			   num_scalers,
+			   pipe_config->scaler_state.scaler_users,
+			   pipe_config->scaler_state.scaler_id);
+
+		for (i = 0; i < SKL_NUM_SCALERS; i++) {
+			struct intel_scaler *sc =
+					&pipe_config->scaler_state.scalers[i];
+
+			seq_printf(m, ", scalers[%d]: use=%s, mode=%x",
+				   i, yesno(sc->in_use), sc->mode);
+		}
+		seq_puts(m, "\n");
+	} else {
+		seq_puts(m, "\tNo scalers available on this platform\n");
+	}
+}
+
+static int i915_display_info(struct seq_file *m, void *unused)
+{
+	struct drm_info_node *node = m->private;
+	struct drm_device *dev = node->minor->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_crtc *crtc;
+	struct drm_connector *connector;
+
+	intel_runtime_pm_get(dev_priv);
+	drm_modeset_lock_all(dev);
+	seq_printf(m, "CRTC info\n");
+	seq_printf(m, "---------\n");
+	for_each_intel_crtc(dev, crtc) {
+		bool active;
+		struct intel_crtc_state *pipe_config;
+		int x, y;
+
+		pipe_config = to_intel_crtc_state(crtc->base.state);
+
+		seq_printf(m, "CRTC %d: pipe: %c, active=%s, (size=%dx%d), dither=%s, bpp=%d\n",
+			   crtc->base.base.id, pipe_name(crtc->pipe),
+			   yesno(pipe_config->base.active),
+			   pipe_config->pipe_src_w, pipe_config->pipe_src_h,
+			   yesno(pipe_config->dither), pipe_config->pipe_bpp);
+
+		if (pipe_config->base.active) {
+			intel_crtc_info(m, crtc);
+
+			active = cursor_position(dev, crtc->pipe, &x, &y);
+			seq_printf(m, "\tcursor visible? %s, position (%d, %d), size %dx%d, addr 0x%08x, active? %s\n",
+				   yesno(crtc->cursor_base),
+				   x, y, crtc->base.cursor->state->crtc_w,
+				   crtc->base.cursor->state->crtc_h,
+				   crtc->cursor_addr, yesno(active));
+			intel_scaler_info(m, crtc);
+			intel_plane_info(m, crtc);
+		}
+
+		seq_printf(m, "\tunderrun reporting: cpu=%s pch=%s \n",
+			   yesno(!crtc->cpu_fifo_underrun_disabled),
+			   yesno(!crtc->pch_fifo_underrun_disabled));
+	}
+
+	seq_printf(m, "\n");
+	seq_printf(m, "Connector info\n");
+	seq_printf(m, "--------------\n");
+	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
+		intel_connector_info(m, connector);
+	}
+	drm_modeset_unlock_all(dev);
+	intel_runtime_pm_put(dev_priv);
+
+	return 0;
+}
+
+static int i915_semaphore_status(struct seq_file *m, void *unused)
+{
+	struct drm_info_node *node = (struct drm_info_node *) m->private;
+	struct drm_device *dev = node->minor->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_engine_cs *engine;
+	int num_rings = hweight32(INTEL_INFO(dev)->ring_mask);
+	enum intel_engine_id id;
+	int j, ret;
+
+	if (!i915_semaphore_is_enabled(dev)) {
+		seq_puts(m, "Semaphores are disabled\n");
+		return 0;
+	}
+
+	ret = mutex_lock_interruptible(&dev->struct_mutex);
+	if (ret)
+		return ret;
+	intel_runtime_pm_get(dev_priv);
+
+	if (IS_BROADWELL(dev)) {
+		struct page *page;
+		uint64_t *seqno;
+
+		page = i915_gem_object_get_page(dev_priv->semaphore_obj, 0);
+
+		seqno = (uint64_t *)kmap_atomic(page);
+		for_each_engine_id(engine, dev_priv, id) {
+			uint64_t offset;
+
+			seq_printf(m, "%s\n", engine->name);
+
+			seq_puts(m, "  Last signal:");
+			for (j = 0; j < num_rings; j++) {
+				offset = id * I915_NUM_ENGINES + j;
+				seq_printf(m, "0x%08llx (0x%02llx) ",
+					   seqno[offset], offset * 8);
+			}
+			seq_putc(m, '\n');
+
+			seq_puts(m, "  Last wait:  ");
+			for (j = 0; j < num_rings; j++) {
+				offset = id + (j * I915_NUM_ENGINES);
+				seq_printf(m, "0x%08llx (0x%02llx) ",
+					   seqno[offset], offset * 8);
+			}
+			seq_putc(m, '\n');
+
+		}
+		kunmap_atomic(seqno);
+	} else {
+		seq_puts(m, "  Last signal:");
+		for_each_engine(engine, dev_priv)
+			for (j = 0; j < num_rings; j++)
+				seq_printf(m, "0x%08x\n",
+					   I915_READ(engine->semaphore.mbox.signal[j]));
+		seq_putc(m, '\n');
+	}
+
+	seq_puts(m, "\nSync seqno:\n");
+	for_each_engine(engine, dev_priv) {
+		for (j = 0; j < num_rings; j++)
+			seq_printf(m, "  0x%08x ",
+				   engine->semaphore.sync_seqno[j]);
+		seq_putc(m, '\n');
+	}
+	seq_putc(m, '\n');
+
+	intel_runtime_pm_put(dev_priv);
+	mutex_unlock(&dev->struct_mutex);
+	return 0;
+}
+
+static int i915_shared_dplls_info(struct seq_file *m, void *unused)
+{
+	struct drm_info_node *node = (struct drm_info_node *) m->private;
+	struct drm_device *dev = node->minor->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	int i;
+
+	drm_modeset_lock_all(dev);
+	for (i = 0; i < dev_priv->num_shared_dpll; i++) {
+		struct intel_shared_dpll *pll = &dev_priv->shared_dplls[i];
+
+		seq_printf(m, "DPLL%i: %s, id: %i\n", i, pll->name, pll->id);
+		seq_printf(m, " crtc_mask: 0x%08x, active: 0x%x, on: %s\n",
+			   pll->config.crtc_mask, pll->active_mask, yesno(pll->on));
+		seq_printf(m, " tracked hardware state:\n");
+		seq_printf(m, " dpll:    0x%08x\n", pll->config.hw_state.dpll);
+		seq_printf(m, " dpll_md: 0x%08x\n",
+			   pll->config.hw_state.dpll_md);
+		seq_printf(m, " fp0:     0x%08x\n", pll->config.hw_state.fp0);
+		seq_printf(m, " fp1:     0x%08x\n", pll->config.hw_state.fp1);
+		seq_printf(m, " wrpll:   0x%08x\n", pll->config.hw_state.wrpll);
+	}
+	drm_modeset_unlock_all(dev);
+
+	return 0;
+}
+
+static int i915_wa_registers(struct seq_file *m, void *unused)
+{
+	int i;
+	int ret;
+	struct intel_engine_cs *engine;
+	struct drm_info_node *node = (struct drm_info_node *) m->private;
+	struct drm_device *dev = node->minor->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct i915_workarounds *workarounds = &dev_priv->workarounds;
+	enum intel_engine_id id;
+
+	ret = mutex_lock_interruptible(&dev->struct_mutex);
+	if (ret)
+		return ret;
+
+	intel_runtime_pm_get(dev_priv);
+
+	seq_printf(m, "Workarounds applied: %d\n", workarounds->count);
+	for_each_engine_id(engine, dev_priv, id)
+		seq_printf(m, "HW whitelist count for %s: %d\n",
+			   engine->name, workarounds->hw_whitelist_count[id]);
+	for (i = 0; i < workarounds->count; ++i) {
+		i915_reg_t addr;
+		u32 mask, value, read;
+		bool ok;
+
+		addr = workarounds->reg[i].addr;
+		mask = workarounds->reg[i].mask;
+		value = workarounds->reg[i].value;
+		read = I915_READ(addr);
+		ok = (value & mask) == (read & mask);
+		seq_printf(m, "0x%X: 0x%08X, mask: 0x%08X, read: 0x%08x, status: %s\n",
+			   i915_mmio_reg_offset(addr), value, mask, read, ok ? "OK" : "FAIL");
+	}
+
+	intel_runtime_pm_put(dev_priv);
+	mutex_unlock(&dev->struct_mutex);
+
+	return 0;
+}
+
+static int i915_ddb_info(struct seq_file *m, void *unused)
+{
+	struct drm_info_node *node = m->private;
+	struct drm_device *dev = node->minor->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct skl_ddb_allocation *ddb;
+	struct skl_ddb_entry *entry;
+	enum pipe pipe;
+	int plane;
+
+	if (INTEL_INFO(dev)->gen < 9)
+		return 0;
+
+	drm_modeset_lock_all(dev);
+
+	ddb = &dev_priv->wm.skl_hw.ddb;
+
+	seq_printf(m, "%-15s%8s%8s%8s\n", "", "Start", "End", "Size");
+
+	for_each_pipe(dev_priv, pipe) {
+		seq_printf(m, "Pipe %c\n", pipe_name(pipe));
+
+		for_each_plane(dev_priv, pipe, plane) {
+			entry = &ddb->plane[pipe][plane];
+			seq_printf(m, "  Plane%-8d%8u%8u%8u\n", plane + 1,
+				   entry->start, entry->end,
+				   skl_ddb_entry_size(entry));
+		}
+
+		entry = &ddb->plane[pipe][PLANE_CURSOR];
+		seq_printf(m, "  %-13s%8u%8u%8u\n", "Cursor", entry->start,
+			   entry->end, skl_ddb_entry_size(entry));
+	}
+
+	drm_modeset_unlock_all(dev);
+
+	return 0;
+}
+
+static void drrs_status_per_crtc(struct seq_file *m,
+		struct drm_device *dev, struct intel_crtc *intel_crtc)
+{
+	struct intel_encoder *intel_encoder;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct i915_drrs *drrs = &dev_priv->drrs;
+	int vrefresh = 0;
+
+	for_each_encoder_on_crtc(dev, &intel_crtc->base, intel_encoder) {
+		/* Encoder connected on this CRTC */
+		switch (intel_encoder->type) {
+		case INTEL_OUTPUT_EDP:
+			seq_puts(m, "eDP:\n");
+			break;
+		case INTEL_OUTPUT_DSI:
+			seq_puts(m, "DSI:\n");
+			break;
+		case INTEL_OUTPUT_HDMI:
+			seq_puts(m, "HDMI:\n");
+			break;
+		case INTEL_OUTPUT_DISPLAYPORT:
+			seq_puts(m, "DP:\n");
+			break;
+		default:
+			seq_printf(m, "Other encoder (id=%d).\n",
+						intel_encoder->type);
+			return;
+		}
+	}
+
+	if (dev_priv->vbt.drrs_type == STATIC_DRRS_SUPPORT)
+		seq_puts(m, "\tVBT: DRRS_type: Static");
+	else if (dev_priv->vbt.drrs_type == SEAMLESS_DRRS_SUPPORT)
+		seq_puts(m, "\tVBT: DRRS_type: Seamless");
+	else if (dev_priv->vbt.drrs_type == DRRS_NOT_SUPPORTED)
+		seq_puts(m, "\tVBT: DRRS_type: None");
+	else
+		seq_puts(m, "\tVBT: DRRS_type: FIXME: Unrecognized Value");
+
+	seq_puts(m, "\n\n");
+
+	if (to_intel_crtc_state(intel_crtc->base.state)->has_drrs) {
+		struct intel_panel *panel;
+
+		mutex_lock(&drrs->mutex);
+		/* DRRS Supported */
+		seq_puts(m, "\tDRRS Supported: Yes\n");
+
+		/* disable_drrs() will make drrs->dp NULL */
+		if (!drrs->dp) {
+			seq_puts(m, "Idleness DRRS: Disabled");
+			mutex_unlock(&drrs->mutex);
+			return;
+		}
+
+		panel = &drrs->dp->attached_connector->panel;
+		seq_printf(m, "\t\tBusy_frontbuffer_bits: 0x%X",
+					drrs->busy_frontbuffer_bits);
+
+		seq_puts(m, "\n\t\t");
+		if (drrs->refresh_rate_type == DRRS_HIGH_RR) {
+			seq_puts(m, "DRRS_State: DRRS_HIGH_RR\n");
+			vrefresh = panel->fixed_mode->vrefresh;
+		} else if (drrs->refresh_rate_type == DRRS_LOW_RR) {
+			seq_puts(m, "DRRS_State: DRRS_LOW_RR\n");
+			vrefresh = panel->downclock_mode->vrefresh;
+		} else {
+			seq_printf(m, "DRRS_State: Unknown(%d)\n",
+						drrs->refresh_rate_type);
+			mutex_unlock(&drrs->mutex);
+			return;
+		}
+		seq_printf(m, "\t\tVrefresh: %d", vrefresh);
+
+		seq_puts(m, "\n\t\t");
+		mutex_unlock(&drrs->mutex);
+	} else {
+		/* DRRS not supported. Print the VBT parameter*/
+		seq_puts(m, "\tDRRS Supported : No");
+	}
+	seq_puts(m, "\n");
+}
+
+static int i915_drrs_status(struct seq_file *m, void *unused)
+{
+	struct drm_info_node *node = m->private;
+	struct drm_device *dev = node->minor->dev;
+	struct intel_crtc *intel_crtc;
+	int active_crtc_cnt = 0;
+
+	for_each_intel_crtc(dev, intel_crtc) {
+		drm_modeset_lock(&intel_crtc->base.mutex, NULL);
+
+		if (intel_crtc->base.state->active) {
+			active_crtc_cnt++;
+			seq_printf(m, "\nCRTC %d:  ", active_crtc_cnt);
+
+			drrs_status_per_crtc(m, dev, intel_crtc);
+		}
+
+		drm_modeset_unlock(&intel_crtc->base.mutex);
+	}
+
+	if (!active_crtc_cnt)
+		seq_puts(m, "No active crtc found\n");
+
+	return 0;
+}
+
+struct pipe_crc_info {
+	const char *name;
+	struct drm_device *dev;
+	enum pipe pipe;
+};
+
+static int i915_dp_mst_info(struct seq_file *m, void *unused)
+{
+	struct drm_info_node *node = (struct drm_info_node *) m->private;
+	struct drm_device *dev = node->minor->dev;
+	struct drm_encoder *encoder;
+	struct intel_encoder *intel_encoder;
+	struct intel_digital_port *intel_dig_port;
+	drm_modeset_lock_all(dev);
+	list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
+		intel_encoder = to_intel_encoder(encoder);
+		if (intel_encoder->type != INTEL_OUTPUT_DISPLAYPORT)
+			continue;
+		intel_dig_port = enc_to_dig_port(encoder);
+		if (!intel_dig_port->dp.can_mst)
+			continue;
+		seq_printf(m, "MST Source Port %c\n",
+			   port_name(intel_dig_port->port));
+		drm_dp_mst_dump_topology(m, &intel_dig_port->dp.mst_mgr);
+	}
+	drm_modeset_unlock_all(dev);
+	return 0;
+}
+
+static int i915_pipe_crc_open(struct inode *inode, struct file *filep)
+{
+	struct pipe_crc_info *info = inode->i_private;
+	struct drm_i915_private *dev_priv = info->dev->dev_private;
+	struct intel_pipe_crc *pipe_crc = &dev_priv->pipe_crc[info->pipe];
+
+	if (info->pipe >= INTEL_INFO(info->dev)->num_pipes)
+		return -ENODEV;
+
+	spin_lock_irq(&pipe_crc->lock);
+
+	if (pipe_crc->opened) {
+		spin_unlock_irq(&pipe_crc->lock);
+		return -EBUSY; /* already open */
+	}
+
+	pipe_crc->opened = true;
+	filep->private_data = inode->i_private;
+
+	spin_unlock_irq(&pipe_crc->lock);
+
+	return 0;
+}
+
+static int i915_pipe_crc_release(struct inode *inode, struct file *filep)
+{
+	struct pipe_crc_info *info = inode->i_private;
+	struct drm_i915_private *dev_priv = info->dev->dev_private;
+	struct intel_pipe_crc *pipe_crc = &dev_priv->pipe_crc[info->pipe];
+
+	spin_lock_irq(&pipe_crc->lock);
+	pipe_crc->opened = false;
+	spin_unlock_irq(&pipe_crc->lock);
+
+	return 0;
+}
+
+/* (6 fields, 8 chars each, space separated (5) + '\n') */
+#define PIPE_CRC_LINE_LEN	(6 * 8 + 5 + 1)
+/* account for \'0' */
+#define PIPE_CRC_BUFFER_LEN	(PIPE_CRC_LINE_LEN + 1)
+
+static int pipe_crc_data_count(struct intel_pipe_crc *pipe_crc)
+{
+	assert_spin_locked(&pipe_crc->lock);
+	return CIRC_CNT(pipe_crc->head, pipe_crc->tail,
+			INTEL_PIPE_CRC_ENTRIES_NR);
+}
+
+static ssize_t
+i915_pipe_crc_read(struct file *filep, char __user *user_buf, size_t count,
+		   loff_t *pos)
+{
+	struct pipe_crc_info *info = filep->private_data;
+	struct drm_device *dev = info->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_pipe_crc *pipe_crc = &dev_priv->pipe_crc[info->pipe];
+	char buf[PIPE_CRC_BUFFER_LEN];
+	int n_entries;
+	ssize_t bytes_read;
+
+	/*
+	 * Don't allow user space to provide buffers not big enough to hold
+	 * a line of data.
+	 */
+	if (count < PIPE_CRC_LINE_LEN)
+		return -EINVAL;
+
+	if (pipe_crc->source == INTEL_PIPE_CRC_SOURCE_NONE)
+		return 0;
+
+	/* nothing to read */
+	spin_lock_irq(&pipe_crc->lock);
+	while (pipe_crc_data_count(pipe_crc) == 0) {
+		int ret;
+
+		if (filep->f_flags & O_NONBLOCK) {
+			spin_unlock_irq(&pipe_crc->lock);
+			return -EAGAIN;
+		}
+
+		ret = wait_event_interruptible_lock_irq(pipe_crc->wq,
+				pipe_crc_data_count(pipe_crc), pipe_crc->lock);
+		if (ret) {
+			spin_unlock_irq(&pipe_crc->lock);
+			return ret;
+		}
+	}
+
+	/* We now have one or more entries to read */
+	n_entries = count / PIPE_CRC_LINE_LEN;
+
+	bytes_read = 0;
+	while (n_entries > 0) {
+		struct intel_pipe_crc_entry *entry =
+			&pipe_crc->entries[pipe_crc->tail];
+		int ret;
+
+		if (CIRC_CNT(pipe_crc->head, pipe_crc->tail,
+			     INTEL_PIPE_CRC_ENTRIES_NR) < 1)
+			break;
+
+		BUILD_BUG_ON_NOT_POWER_OF_2(INTEL_PIPE_CRC_ENTRIES_NR);
+		pipe_crc->tail = (pipe_crc->tail + 1) & (INTEL_PIPE_CRC_ENTRIES_NR - 1);
+
+		bytes_read += snprintf(buf, PIPE_CRC_BUFFER_LEN,
+				       "%8u %8x %8x %8x %8x %8x\n",
+				       entry->frame, entry->crc[0],
+				       entry->crc[1], entry->crc[2],
+				       entry->crc[3], entry->crc[4]);
+
+		spin_unlock_irq(&pipe_crc->lock);
+
+		ret = copy_to_user(user_buf, buf, PIPE_CRC_LINE_LEN);
+		if (ret == PIPE_CRC_LINE_LEN)
+			return -EFAULT;
+
+		user_buf += PIPE_CRC_LINE_LEN;
+		n_entries--;
+
+		spin_lock_irq(&pipe_crc->lock);
+	}
+
+	spin_unlock_irq(&pipe_crc->lock);
+
+	return bytes_read;
+}
+
+static const struct file_operations i915_pipe_crc_fops = {
+	.owner = THIS_MODULE,
+	.open = i915_pipe_crc_open,
+	.read = i915_pipe_crc_read,
+	.release = i915_pipe_crc_release,
+};
+
+static struct pipe_crc_info i915_pipe_crc_data[I915_MAX_PIPES] = {
+	{
+		.name = "i915_pipe_A_crc",
+		.pipe = PIPE_A,
+	},
+	{
+		.name = "i915_pipe_B_crc",
+		.pipe = PIPE_B,
+	},
+	{
+		.name = "i915_pipe_C_crc",
+		.pipe = PIPE_C,
+	},
+};
+
+static int i915_pipe_crc_create(struct dentry *root, struct drm_minor *minor,
+				enum pipe pipe)
+{
+	struct drm_device *dev = minor->dev;
+	struct dentry *ent;
+	struct pipe_crc_info *info = &i915_pipe_crc_data[pipe];
+
+	info->dev = dev;
+	ent = debugfs_create_file(info->name, S_IRUGO, root, info,
+				  &i915_pipe_crc_fops);
+	if (!ent)
+		return -ENOMEM;
+
+	return drm_add_fake_info_node(minor, ent, info);
+}
+
+static const char * const pipe_crc_sources[] = {
+	"none",
+	"plane1",
+	"plane2",
+	"pf",
+	"pipe",
+	"TV",
+	"DP-B",
+	"DP-C",
+	"DP-D",
+	"auto",
+};
+
+static const char *pipe_crc_source_name(enum intel_pipe_crc_source source)
+{
+	BUILD_BUG_ON(ARRAY_SIZE(pipe_crc_sources) != INTEL_PIPE_CRC_SOURCE_MAX);
+	return pipe_crc_sources[source];
+}
+
+static int display_crc_ctl_show(struct seq_file *m, void *data)
+{
+	struct drm_device *dev = m->private;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	int i;
+
+	for (i = 0; i < I915_MAX_PIPES; i++)
+		seq_printf(m, "%c %s\n", pipe_name(i),
+			   pipe_crc_source_name(dev_priv->pipe_crc[i].source));
+
+	return 0;
+}
+
+static int display_crc_ctl_open(struct inode *inode, struct file *file)
+{
+	struct drm_device *dev = inode->i_private;
+
+	return single_open(file, display_crc_ctl_show, dev);
+}
+
+static int i8xx_pipe_crc_ctl_reg(enum intel_pipe_crc_source *source,
+				 uint32_t *val)
+{
+	if (*source == INTEL_PIPE_CRC_SOURCE_AUTO)
+		*source = INTEL_PIPE_CRC_SOURCE_PIPE;
+
+	switch (*source) {
+	case INTEL_PIPE_CRC_SOURCE_PIPE:
+		*val = PIPE_CRC_ENABLE | PIPE_CRC_INCLUDE_BORDER_I8XX;
+		break;
+	case INTEL_PIPE_CRC_SOURCE_NONE:
+		*val = 0;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int i9xx_pipe_crc_auto_source(struct drm_device *dev, enum pipe pipe,
+				     enum intel_pipe_crc_source *source)
+{
+	struct intel_encoder *encoder;
+	struct intel_crtc *crtc;
+	struct intel_digital_port *dig_port;
+	int ret = 0;
+
+	*source = INTEL_PIPE_CRC_SOURCE_PIPE;
+
+	drm_modeset_lock_all(dev);
+	for_each_intel_encoder(dev, encoder) {
+		if (!encoder->base.crtc)
+			continue;
+
+		crtc = to_intel_crtc(encoder->base.crtc);
+
+		if (crtc->pipe != pipe)
+			continue;
+
+		switch (encoder->type) {
+		case INTEL_OUTPUT_TVOUT:
+			*source = INTEL_PIPE_CRC_SOURCE_TV;
+			break;
+		case INTEL_OUTPUT_DISPLAYPORT:
+		case INTEL_OUTPUT_EDP:
+			dig_port = enc_to_dig_port(&encoder->base);
+			switch (dig_port->port) {
+			case PORT_B:
+				*source = INTEL_PIPE_CRC_SOURCE_DP_B;
+				break;
+			case PORT_C:
+				*source = INTEL_PIPE_CRC_SOURCE_DP_C;
+				break;
+			case PORT_D:
+				*source = INTEL_PIPE_CRC_SOURCE_DP_D;
+				break;
+			default:
+				WARN(1, "nonexisting DP port %c\n",
+				     port_name(dig_port->port));
+				break;
+			}
+			break;
+		default:
+			break;
+		}
+	}
+	drm_modeset_unlock_all(dev);
+
+	return ret;
+}
+
+static int vlv_pipe_crc_ctl_reg(struct drm_device *dev,
+				enum pipe pipe,
+				enum intel_pipe_crc_source *source,
+				uint32_t *val)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	bool need_stable_symbols = false;
+
+	if (*source == INTEL_PIPE_CRC_SOURCE_AUTO) {
+		int ret = i9xx_pipe_crc_auto_source(dev, pipe, source);
+		if (ret)
+			return ret;
+	}
+
+	switch (*source) {
+	case INTEL_PIPE_CRC_SOURCE_PIPE:
+		*val = PIPE_CRC_ENABLE | PIPE_CRC_SOURCE_PIPE_VLV;
+		break;
+	case INTEL_PIPE_CRC_SOURCE_DP_B:
+		*val = PIPE_CRC_ENABLE | PIPE_CRC_SOURCE_DP_B_VLV;
+		need_stable_symbols = true;
+		break;
+	case INTEL_PIPE_CRC_SOURCE_DP_C:
+		*val = PIPE_CRC_ENABLE | PIPE_CRC_SOURCE_DP_C_VLV;
+		need_stable_symbols = true;
+		break;
+	case INTEL_PIPE_CRC_SOURCE_DP_D:
+		if (!IS_CHERRYVIEW(dev))
+			return -EINVAL;
+		*val = PIPE_CRC_ENABLE | PIPE_CRC_SOURCE_DP_D_VLV;
+		need_stable_symbols = true;
+		break;
+	case INTEL_PIPE_CRC_SOURCE_NONE:
+		*val = 0;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	/*
+	 * When the pipe CRC tap point is after the transcoders we need
+	 * to tweak symbol-level features to produce a deterministic series of
+	 * symbols for a given frame. We need to reset those features only once
+	 * a frame (instead of every nth symbol):
+	 *   - DC-balance: used to ensure a better clock recovery from the data
+	 *     link (SDVO)
+	 *   - DisplayPort scrambling: used for EMI reduction
+	 */
+	if (need_stable_symbols) {
+		uint32_t tmp = I915_READ(PORT_DFT2_G4X);
+
+		tmp |= DC_BALANCE_RESET_VLV;
+		switch (pipe) {
+		case PIPE_A:
+			tmp |= PIPE_A_SCRAMBLE_RESET;
+			break;
+		case PIPE_B:
+			tmp |= PIPE_B_SCRAMBLE_RESET;
+			break;
+		case PIPE_C:
+			tmp |= PIPE_C_SCRAMBLE_RESET;
+			break;
+		default:
+			return -EINVAL;
+		}
+		I915_WRITE(PORT_DFT2_G4X, tmp);
+	}
+
+	return 0;
+}
+
+static int i9xx_pipe_crc_ctl_reg(struct drm_device *dev,
+				 enum pipe pipe,
+				 enum intel_pipe_crc_source *source,
+				 uint32_t *val)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	bool need_stable_symbols = false;
+
+	if (*source == INTEL_PIPE_CRC_SOURCE_AUTO) {
+		int ret = i9xx_pipe_crc_auto_source(dev, pipe, source);
+		if (ret)
+			return ret;
+	}
+
+	switch (*source) {
+	case INTEL_PIPE_CRC_SOURCE_PIPE:
+		*val = PIPE_CRC_ENABLE | PIPE_CRC_SOURCE_PIPE_I9XX;
+		break;
+	case INTEL_PIPE_CRC_SOURCE_TV:
+		if (!SUPPORTS_TV(dev))
+			return -EINVAL;
+		*val = PIPE_CRC_ENABLE | PIPE_CRC_SOURCE_TV_PRE;
+		break;
+	case INTEL_PIPE_CRC_SOURCE_DP_B:
+		if (!IS_G4X(dev))
+			return -EINVAL;
+		*val = PIPE_CRC_ENABLE | PIPE_CRC_SOURCE_DP_B_G4X;
+		need_stable_symbols = true;
+		break;
+	case INTEL_PIPE_CRC_SOURCE_DP_C:
+		if (!IS_G4X(dev))
+			return -EINVAL;
+		*val = PIPE_CRC_ENABLE | PIPE_CRC_SOURCE_DP_C_G4X;
+		need_stable_symbols = true;
+		break;
+	case INTEL_PIPE_CRC_SOURCE_DP_D:
+		if (!IS_G4X(dev))
+			return -EINVAL;
+		*val = PIPE_CRC_ENABLE | PIPE_CRC_SOURCE_DP_D_G4X;
+		need_stable_symbols = true;
+		break;
+	case INTEL_PIPE_CRC_SOURCE_NONE:
+		*val = 0;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	/*
+	 * When the pipe CRC tap point is after the transcoders we need
+	 * to tweak symbol-level features to produce a deterministic series of
+	 * symbols for a given frame. We need to reset those features only once
+	 * a frame (instead of every nth symbol):
+	 *   - DC-balance: used to ensure a better clock recovery from the data
+	 *     link (SDVO)
+	 *   - DisplayPort scrambling: used for EMI reduction
+	 */
+	if (need_stable_symbols) {
+		uint32_t tmp = I915_READ(PORT_DFT2_G4X);
+
+		WARN_ON(!IS_G4X(dev));
+
+		I915_WRITE(PORT_DFT_I9XX,
+			   I915_READ(PORT_DFT_I9XX) | DC_BALANCE_RESET);
+
+		if (pipe == PIPE_A)
+			tmp |= PIPE_A_SCRAMBLE_RESET;
+		else
+			tmp |= PIPE_B_SCRAMBLE_RESET;
+
+		I915_WRITE(PORT_DFT2_G4X, tmp);
+	}
+
+	return 0;
+}
+
+static void vlv_undo_pipe_scramble_reset(struct drm_device *dev,
+					 enum pipe pipe)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	uint32_t tmp = I915_READ(PORT_DFT2_G4X);
+
+	switch (pipe) {
+	case PIPE_A:
+		tmp &= ~PIPE_A_SCRAMBLE_RESET;
+		break;
+	case PIPE_B:
+		tmp &= ~PIPE_B_SCRAMBLE_RESET;
+		break;
+	case PIPE_C:
+		tmp &= ~PIPE_C_SCRAMBLE_RESET;
+		break;
+	default:
+		return;
+	}
+	if (!(tmp & PIPE_SCRAMBLE_RESET_MASK))
+		tmp &= ~DC_BALANCE_RESET_VLV;
+	I915_WRITE(PORT_DFT2_G4X, tmp);
+
+}
+
+static void g4x_undo_pipe_scramble_reset(struct drm_device *dev,
+					 enum pipe pipe)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	uint32_t tmp = I915_READ(PORT_DFT2_G4X);
+
+	if (pipe == PIPE_A)
+		tmp &= ~PIPE_A_SCRAMBLE_RESET;
+	else
+		tmp &= ~PIPE_B_SCRAMBLE_RESET;
+	I915_WRITE(PORT_DFT2_G4X, tmp);
+
+	if (!(tmp & PIPE_SCRAMBLE_RESET_MASK)) {
+		I915_WRITE(PORT_DFT_I9XX,
+			   I915_READ(PORT_DFT_I9XX) & ~DC_BALANCE_RESET);
+	}
+}
+
+static int ilk_pipe_crc_ctl_reg(enum intel_pipe_crc_source *source,
+				uint32_t *val)
+{
+	if (*source == INTEL_PIPE_CRC_SOURCE_AUTO)
+		*source = INTEL_PIPE_CRC_SOURCE_PIPE;
+
+	switch (*source) {
+	case INTEL_PIPE_CRC_SOURCE_PLANE1:
+		*val = PIPE_CRC_ENABLE | PIPE_CRC_SOURCE_PRIMARY_ILK;
+		break;
+	case INTEL_PIPE_CRC_SOURCE_PLANE2:
+		*val = PIPE_CRC_ENABLE | PIPE_CRC_SOURCE_SPRITE_ILK;
+		break;
+	case INTEL_PIPE_CRC_SOURCE_PIPE:
+		*val = PIPE_CRC_ENABLE | PIPE_CRC_SOURCE_PIPE_ILK;
+		break;
+	case INTEL_PIPE_CRC_SOURCE_NONE:
+		*val = 0;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static void hsw_trans_edp_pipe_A_crc_wa(struct drm_device *dev, bool enable)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_crtc *crtc =
+		to_intel_crtc(dev_priv->pipe_to_crtc_mapping[PIPE_A]);
+	struct intel_crtc_state *pipe_config;
+	struct drm_atomic_state *state;
+	int ret = 0;
+
+	drm_modeset_lock_all(dev);
+	state = drm_atomic_state_alloc(dev);
+	if (!state) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	state->acquire_ctx = drm_modeset_legacy_acquire_ctx(&crtc->base);
+	pipe_config = intel_atomic_get_crtc_state(state, crtc);
+	if (IS_ERR(pipe_config)) {
+		ret = PTR_ERR(pipe_config);
+		goto out;
+	}
+
+	pipe_config->pch_pfit.force_thru = enable;
+	if (pipe_config->cpu_transcoder == TRANSCODER_EDP &&
+	    pipe_config->pch_pfit.enabled != enable)
+		pipe_config->base.connectors_changed = true;
+
+	ret = drm_atomic_commit(state);
+out:
+	drm_modeset_unlock_all(dev);
+	WARN(ret, "Toggling workaround to %i returns %i\n", enable, ret);
+	if (ret)
+		drm_atomic_state_free(state);
+}
+
+static int ivb_pipe_crc_ctl_reg(struct drm_device *dev,
+				enum pipe pipe,
+				enum intel_pipe_crc_source *source,
+				uint32_t *val)
+{
+	if (*source == INTEL_PIPE_CRC_SOURCE_AUTO)
+		*source = INTEL_PIPE_CRC_SOURCE_PF;
+
+	switch (*source) {
+	case INTEL_PIPE_CRC_SOURCE_PLANE1:
+		*val = PIPE_CRC_ENABLE | PIPE_CRC_SOURCE_PRIMARY_IVB;
+		break;
+	case INTEL_PIPE_CRC_SOURCE_PLANE2:
+		*val = PIPE_CRC_ENABLE | PIPE_CRC_SOURCE_SPRITE_IVB;
+		break;
+	case INTEL_PIPE_CRC_SOURCE_PF:
+		if (IS_HASWELL(dev) && pipe == PIPE_A)
+			hsw_trans_edp_pipe_A_crc_wa(dev, true);
+
+		*val = PIPE_CRC_ENABLE | PIPE_CRC_SOURCE_PF_IVB;
+		break;
+	case INTEL_PIPE_CRC_SOURCE_NONE:
+		*val = 0;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int pipe_crc_set_source(struct drm_device *dev, enum pipe pipe,
+			       enum intel_pipe_crc_source source)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_pipe_crc *pipe_crc = &dev_priv->pipe_crc[pipe];
+	struct intel_crtc *crtc = to_intel_crtc(intel_get_crtc_for_pipe(dev,
+									pipe));
+	enum intel_display_power_domain power_domain;
+	u32 val = 0; /* shut up gcc */
+	int ret;
+
+	if (pipe_crc->source == source)
+		return 0;
+
+	/* forbid changing the source without going back to 'none' */
+	if (pipe_crc->source && source)
+		return -EINVAL;
+
+	power_domain = POWER_DOMAIN_PIPE(pipe);
+	if (!intel_display_power_get_if_enabled(dev_priv, power_domain)) {
+		DRM_DEBUG_KMS("Trying to capture CRC while pipe is off\n");
+		return -EIO;
+	}
+
+	if (IS_GEN2(dev))
+		ret = i8xx_pipe_crc_ctl_reg(&source, &val);
+	else if (INTEL_INFO(dev)->gen < 5)
+		ret = i9xx_pipe_crc_ctl_reg(dev, pipe, &source, &val);
+	else if (IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev))
+		ret = vlv_pipe_crc_ctl_reg(dev, pipe, &source, &val);
+	else if (IS_GEN5(dev) || IS_GEN6(dev))
+		ret = ilk_pipe_crc_ctl_reg(&source, &val);
+	else
+		ret = ivb_pipe_crc_ctl_reg(dev, pipe, &source, &val);
+
+	if (ret != 0)
+		goto out;
+
+	/* none -> real source transition */
+	if (source) {
+		struct intel_pipe_crc_entry *entries;
+
+		DRM_DEBUG_DRIVER("collecting CRCs for pipe %c, %s\n",
+				 pipe_name(pipe), pipe_crc_source_name(source));
+
+		entries = kcalloc(INTEL_PIPE_CRC_ENTRIES_NR,
+				  sizeof(pipe_crc->entries[0]),
+				  GFP_KERNEL);
+		if (!entries) {
+			ret = -ENOMEM;
+			goto out;
+		}
+
+		/*
+		 * When IPS gets enabled, the pipe CRC changes. Since IPS gets
+		 * enabled and disabled dynamically based on package C states,
+		 * user space can't make reliable use of the CRCs, so let's just
+		 * completely disable it.
+		 */
+		hsw_disable_ips(crtc);
+
+		spin_lock_irq(&pipe_crc->lock);
+		kfree(pipe_crc->entries);
+		pipe_crc->entries = entries;
+		pipe_crc->head = 0;
+		pipe_crc->tail = 0;
+		spin_unlock_irq(&pipe_crc->lock);
+	}
+
+	pipe_crc->source = source;
+
+	I915_WRITE(PIPE_CRC_CTL(pipe), val);
+	POSTING_READ(PIPE_CRC_CTL(pipe));
+
+	/* real source -> none transition */
+	if (source == INTEL_PIPE_CRC_SOURCE_NONE) {
+		struct intel_pipe_crc_entry *entries;
+		struct intel_crtc *crtc =
+			to_intel_crtc(dev_priv->pipe_to_crtc_mapping[pipe]);
+
+		DRM_DEBUG_DRIVER("stopping CRCs for pipe %c\n",
+				 pipe_name(pipe));
+
+		drm_modeset_lock(&crtc->base.mutex, NULL);
+		if (crtc->base.state->active)
+			intel_wait_for_vblank(dev, pipe);
+		drm_modeset_unlock(&crtc->base.mutex);
+
+		spin_lock_irq(&pipe_crc->lock);
+		entries = pipe_crc->entries;
+		pipe_crc->entries = NULL;
+		pipe_crc->head = 0;
+		pipe_crc->tail = 0;
+		spin_unlock_irq(&pipe_crc->lock);
+
+		kfree(entries);
+
+		if (IS_G4X(dev))
+			g4x_undo_pipe_scramble_reset(dev, pipe);
+		else if (IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev))
+			vlv_undo_pipe_scramble_reset(dev, pipe);
+		else if (IS_HASWELL(dev) && pipe == PIPE_A)
+			hsw_trans_edp_pipe_A_crc_wa(dev, false);
+
+		hsw_enable_ips(crtc);
+	}
+
+	ret = 0;
+
+out:
+	intel_display_power_put(dev_priv, power_domain);
+
+	return ret;
+}
+
+/*
+ * Parse pipe CRC command strings:
+ *   command: wsp* object wsp+ name wsp+ source wsp*
+ *   object: 'pipe'
+ *   name: (A | B | C)
+ *   source: (none | plane1 | plane2 | pf)
+ *   wsp: (#0x20 | #0x9 | #0xA)+
+ *
+ * eg.:
+ *  "pipe A plane1"  ->  Start CRC computations on plane1 of pipe A
+ *  "pipe A none"    ->  Stop CRC
+ */
+static int display_crc_ctl_tokenize(char *buf, char *words[], int max_words)
+{
+	int n_words = 0;
+
+	while (*buf) {
+		char *end;
+
+		/* skip leading white space */
+		buf = skip_spaces(buf);
+		if (!*buf)
+			break;	/* end of buffer */
+
+		/* find end of word */
+		for (end = buf; *end && !isspace(*end); end++)
+			;
+
+		if (n_words == max_words) {
+			DRM_DEBUG_DRIVER("too many words, allowed <= %d\n",
+					 max_words);
+			return -EINVAL;	/* ran out of words[] before bytes */
+		}
+
+		if (*end)
+			*end++ = '\0';
+		words[n_words++] = buf;
+		buf = end;
+	}
+
+	return n_words;
+}
+
+enum intel_pipe_crc_object {
+	PIPE_CRC_OBJECT_PIPE,
+};
+
+static const char * const pipe_crc_objects[] = {
+	"pipe",
+};
+
+static int
+display_crc_ctl_parse_object(const char *buf, enum intel_pipe_crc_object *o)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(pipe_crc_objects); i++)
+		if (!strcmp(buf, pipe_crc_objects[i])) {
+			*o = i;
+			return 0;
+		    }
+
+	return -EINVAL;
+}
+
+static int display_crc_ctl_parse_pipe(const char *buf, enum pipe *pipe)
+{
+	const char name = buf[0];
+
+	if (name < 'A' || name >= pipe_name(I915_MAX_PIPES))
+		return -EINVAL;
+
+	*pipe = name - 'A';
+
+	return 0;
+}
+
+static int
+display_crc_ctl_parse_source(const char *buf, enum intel_pipe_crc_source *s)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(pipe_crc_sources); i++)
+		if (!strcmp(buf, pipe_crc_sources[i])) {
+			*s = i;
+			return 0;
+		    }
+
+	return -EINVAL;
+}
+
+static int display_crc_ctl_parse(struct drm_device *dev, char *buf, size_t len)
+{
+#define N_WORDS 3
+	int n_words;
+	char *words[N_WORDS];
+	enum pipe pipe;
+	enum intel_pipe_crc_object object;
+	enum intel_pipe_crc_source source;
+
+	n_words = display_crc_ctl_tokenize(buf, words, N_WORDS);
+	if (n_words != N_WORDS) {
+		DRM_DEBUG_DRIVER("tokenize failed, a command is %d words\n",
+				 N_WORDS);
+		return -EINVAL;
+	}
+
+	if (display_crc_ctl_parse_object(words[0], &object) < 0) {
+		DRM_DEBUG_DRIVER("unknown object %s\n", words[0]);
+		return -EINVAL;
+	}
+
+	if (display_crc_ctl_parse_pipe(words[1], &pipe) < 0) {
+		DRM_DEBUG_DRIVER("unknown pipe %s\n", words[1]);
+		return -EINVAL;
+	}
+
+	if (display_crc_ctl_parse_source(words[2], &source) < 0) {
+		DRM_DEBUG_DRIVER("unknown source %s\n", words[2]);
+		return -EINVAL;
+	}
+
+	return pipe_crc_set_source(dev, pipe, source);
+}
+
+static ssize_t display_crc_ctl_write(struct file *file, const char __user *ubuf,
+				     size_t len, loff_t *offp)
+{
+	struct seq_file *m = file->private_data;
+	struct drm_device *dev = m->private;
+	char *tmpbuf;
+	int ret;
+
+	if (len == 0)
+		return 0;
+
+	if (len > PAGE_SIZE - 1) {
+		DRM_DEBUG_DRIVER("expected <%lu bytes into pipe crc control\n",
+				 PAGE_SIZE);
+		return -E2BIG;
+	}
+
+	tmpbuf = kmalloc(len + 1, GFP_KERNEL);
+	if (!tmpbuf)
+		return -ENOMEM;
+
+	if (copy_from_user(tmpbuf, ubuf, len)) {
+		ret = -EFAULT;
+		goto out;
+	}
+	tmpbuf[len] = '\0';
+
+	ret = display_crc_ctl_parse(dev, tmpbuf, len);
+
+out:
+	kfree(tmpbuf);
+	if (ret < 0)
+		return ret;
+
+	*offp += len;
+	return len;
+}
+
+static const struct file_operations i915_display_crc_ctl_fops = {
+	.owner = THIS_MODULE,
+	.open = display_crc_ctl_open,
+	.read = seq_read,
+	.llseek = seq_lseek,
+	.release = single_release,
+	.write = display_crc_ctl_write
+};
+
+static ssize_t i915_displayport_test_active_write(struct file *file,
+					    const char __user *ubuf,
+					    size_t len, loff_t *offp)
+{
+	char *input_buffer;
+	int status = 0;
+	struct drm_device *dev;
+	struct drm_connector *connector;
+	struct list_head *connector_list;
+	struct intel_dp *intel_dp;
+	int val = 0;
+
+	dev = ((struct seq_file *)file->private_data)->private;
+
+	connector_list = &dev->mode_config.connector_list;
+
+	if (len == 0)
+		return 0;
+
+	input_buffer = kmalloc(len + 1, GFP_KERNEL);
+	if (!input_buffer)
+		return -ENOMEM;
+
+	if (copy_from_user(input_buffer, ubuf, len)) {
+		status = -EFAULT;
+		goto out;
+	}
+
+	input_buffer[len] = '\0';
+	DRM_DEBUG_DRIVER("Copied %d bytes from user\n", (unsigned int)len);
+
+	list_for_each_entry(connector, connector_list, head) {
+
+		if (connector->connector_type !=
+		    DRM_MODE_CONNECTOR_DisplayPort)
+			continue;
+
+		if (connector->status == connector_status_connected &&
+		    connector->encoder != NULL) {
+			intel_dp = enc_to_intel_dp(connector->encoder);
+			status = kstrtoint(input_buffer, 10, &val);
+			if (status < 0)
+				goto out;
+			DRM_DEBUG_DRIVER("Got %d for test active\n", val);
+			/* To prevent erroneous activation of the compliance
+			 * testing code, only accept an actual value of 1 here
+			 */
+			if (val == 1)
+				intel_dp->compliance_test_active = 1;
+			else
+				intel_dp->compliance_test_active = 0;
+		}
+	}
+out:
+	kfree(input_buffer);
+	if (status < 0)
+		return status;
+
+	*offp += len;
+	return len;
+}
+
+static int i915_displayport_test_active_show(struct seq_file *m, void *data)
+{
+	struct drm_device *dev = m->private;
+	struct drm_connector *connector;
+	struct list_head *connector_list = &dev->mode_config.connector_list;
+	struct intel_dp *intel_dp;
+
+	list_for_each_entry(connector, connector_list, head) {
+
+		if (connector->connector_type !=
+		    DRM_MODE_CONNECTOR_DisplayPort)
+			continue;
+
+		if (connector->status == connector_status_connected &&
+		    connector->encoder != NULL) {
+			intel_dp = enc_to_intel_dp(connector->encoder);
+			if (intel_dp->compliance_test_active)
+				seq_puts(m, "1");
+			else
+				seq_puts(m, "0");
+		} else
+			seq_puts(m, "0");
+	}
+
+	return 0;
+}
+
+static int i915_displayport_test_active_open(struct inode *inode,
+				       struct file *file)
+{
+	struct drm_device *dev = inode->i_private;
+
+	return single_open(file, i915_displayport_test_active_show, dev);
+}
+
+static const struct file_operations i915_displayport_test_active_fops = {
+	.owner = THIS_MODULE,
+	.open = i915_displayport_test_active_open,
+	.read = seq_read,
+	.llseek = seq_lseek,
+	.release = single_release,
+	.write = i915_displayport_test_active_write
+};
+
+static int i915_displayport_test_data_show(struct seq_file *m, void *data)
+{
+	struct drm_device *dev = m->private;
+	struct drm_connector *connector;
+	struct list_head *connector_list = &dev->mode_config.connector_list;
+	struct intel_dp *intel_dp;
+
+	list_for_each_entry(connector, connector_list, head) {
+
+		if (connector->connector_type !=
+		    DRM_MODE_CONNECTOR_DisplayPort)
+			continue;
+
+		if (connector->status == connector_status_connected &&
+		    connector->encoder != NULL) {
+			intel_dp = enc_to_intel_dp(connector->encoder);
+			seq_printf(m, "%lx", intel_dp->compliance_test_data);
+		} else
+			seq_puts(m, "0");
+	}
+
+	return 0;
+}
+static int i915_displayport_test_data_open(struct inode *inode,
+				       struct file *file)
+{
+	struct drm_device *dev = inode->i_private;
+
+	return single_open(file, i915_displayport_test_data_show, dev);
+}
+
+static const struct file_operations i915_displayport_test_data_fops = {
+	.owner = THIS_MODULE,
+	.open = i915_displayport_test_data_open,
+	.read = seq_read,
+	.llseek = seq_lseek,
+	.release = single_release
+};
+
+static int i915_displayport_test_type_show(struct seq_file *m, void *data)
+{
+	struct drm_device *dev = m->private;
+	struct drm_connector *connector;
+	struct list_head *connector_list = &dev->mode_config.connector_list;
+	struct intel_dp *intel_dp;
+
+	list_for_each_entry(connector, connector_list, head) {
+
+		if (connector->connector_type !=
+		    DRM_MODE_CONNECTOR_DisplayPort)
+			continue;
+
+		if (connector->status == connector_status_connected &&
+		    connector->encoder != NULL) {
+			intel_dp = enc_to_intel_dp(connector->encoder);
+			seq_printf(m, "%02lx", intel_dp->compliance_test_type);
+		} else
+			seq_puts(m, "0");
+	}
+
+	return 0;
+}
+
+static int i915_displayport_test_type_open(struct inode *inode,
+				       struct file *file)
+{
+	struct drm_device *dev = inode->i_private;
+
+	return single_open(file, i915_displayport_test_type_show, dev);
+}
+
+static const struct file_operations i915_displayport_test_type_fops = {
+	.owner = THIS_MODULE,
+	.open = i915_displayport_test_type_open,
+	.read = seq_read,
+	.llseek = seq_lseek,
+	.release = single_release
+};
+
+static void wm_latency_show(struct seq_file *m, const uint16_t wm[8])
+{
+	struct drm_device *dev = m->private;
+	int level;
+	int num_levels;
+
+	if (IS_CHERRYVIEW(dev))
+		num_levels = 3;
+	else if (IS_VALLEYVIEW(dev))
+		num_levels = 1;
+	else
+		num_levels = ilk_wm_max_level(dev) + 1;
+
+	drm_modeset_lock_all(dev);
+
+	for (level = 0; level < num_levels; level++) {
+		unsigned int latency = wm[level];
+
+		/*
+		 * - WM1+ latency values in 0.5us units
+		 * - latencies are in us on gen9/vlv/chv
+		 */
+		if (INTEL_INFO(dev)->gen >= 9 || IS_VALLEYVIEW(dev) ||
+		    IS_CHERRYVIEW(dev))
+			latency *= 10;
+		else if (level > 0)
+			latency *= 5;
+
+		seq_printf(m, "WM%d %u (%u.%u usec)\n",
+			   level, wm[level], latency / 10, latency % 10);
+	}
+
+	drm_modeset_unlock_all(dev);
+}
+
+static int pri_wm_latency_show(struct seq_file *m, void *data)
+{
+	struct drm_device *dev = m->private;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	const uint16_t *latencies;
+
+	if (INTEL_INFO(dev)->gen >= 9)
+		latencies = dev_priv->wm.skl_latency;
+	else
+		latencies = to_i915(dev)->wm.pri_latency;
+
+	wm_latency_show(m, latencies);
+
+	return 0;
+}
+
+static int spr_wm_latency_show(struct seq_file *m, void *data)
+{
+	struct drm_device *dev = m->private;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	const uint16_t *latencies;
+
+	if (INTEL_INFO(dev)->gen >= 9)
+		latencies = dev_priv->wm.skl_latency;
+	else
+		latencies = to_i915(dev)->wm.spr_latency;
+
+	wm_latency_show(m, latencies);
+
+	return 0;
+}
+
+static int cur_wm_latency_show(struct seq_file *m, void *data)
+{
+	struct drm_device *dev = m->private;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	const uint16_t *latencies;
+
+	if (INTEL_INFO(dev)->gen >= 9)
+		latencies = dev_priv->wm.skl_latency;
+	else
+		latencies = to_i915(dev)->wm.cur_latency;
+
+	wm_latency_show(m, latencies);
+
+	return 0;
+}
+
+static int pri_wm_latency_open(struct inode *inode, struct file *file)
+{
+	struct drm_device *dev = inode->i_private;
+
+	if (INTEL_INFO(dev)->gen < 5)
+		return -ENODEV;
+
+	return single_open(file, pri_wm_latency_show, dev);
+}
+
+static int spr_wm_latency_open(struct inode *inode, struct file *file)
+{
+	struct drm_device *dev = inode->i_private;
+
+	if (HAS_GMCH_DISPLAY(dev))
+		return -ENODEV;
+
+	return single_open(file, spr_wm_latency_show, dev);
+}
+
+static int cur_wm_latency_open(struct inode *inode, struct file *file)
+{
+	struct drm_device *dev = inode->i_private;
+
+	if (HAS_GMCH_DISPLAY(dev))
+		return -ENODEV;
+
+	return single_open(file, cur_wm_latency_show, dev);
+}
+
+static ssize_t wm_latency_write(struct file *file, const char __user *ubuf,
+				size_t len, loff_t *offp, uint16_t wm[8])
+{
+	struct seq_file *m = file->private_data;
+	struct drm_device *dev = m->private;
+	uint16_t new[8] = { 0 };
+	int num_levels;
+	int level;
+	int ret;
+	char tmp[32];
+
+	if (IS_CHERRYVIEW(dev))
+		num_levels = 3;
+	else if (IS_VALLEYVIEW(dev))
+		num_levels = 1;
+	else
+		num_levels = ilk_wm_max_level(dev) + 1;
+
+	if (len >= sizeof(tmp))
+		return -EINVAL;
+
+	if (copy_from_user(tmp, ubuf, len))
+		return -EFAULT;
+
+	tmp[len] = '\0';
+
+	ret = sscanf(tmp, "%hu %hu %hu %hu %hu %hu %hu %hu",
+		     &new[0], &new[1], &new[2], &new[3],
+		     &new[4], &new[5], &new[6], &new[7]);
+	if (ret != num_levels)
+		return -EINVAL;
+
+	drm_modeset_lock_all(dev);
+
+	for (level = 0; level < num_levels; level++)
+		wm[level] = new[level];
+
+	drm_modeset_unlock_all(dev);
+
+	return len;
+}
+
+
+static ssize_t pri_wm_latency_write(struct file *file, const char __user *ubuf,
+				    size_t len, loff_t *offp)
+{
+	struct seq_file *m = file->private_data;
+	struct drm_device *dev = m->private;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	uint16_t *latencies;
+
+	if (INTEL_INFO(dev)->gen >= 9)
+		latencies = dev_priv->wm.skl_latency;
+	else
+		latencies = to_i915(dev)->wm.pri_latency;
+
+	return wm_latency_write(file, ubuf, len, offp, latencies);
+}
+
+static ssize_t spr_wm_latency_write(struct file *file, const char __user *ubuf,
+				    size_t len, loff_t *offp)
+{
+	struct seq_file *m = file->private_data;
+	struct drm_device *dev = m->private;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	uint16_t *latencies;
+
+	if (INTEL_INFO(dev)->gen >= 9)
+		latencies = dev_priv->wm.skl_latency;
+	else
+		latencies = to_i915(dev)->wm.spr_latency;
+
+	return wm_latency_write(file, ubuf, len, offp, latencies);
+}
+
+static ssize_t cur_wm_latency_write(struct file *file, const char __user *ubuf,
+				    size_t len, loff_t *offp)
+{
+	struct seq_file *m = file->private_data;
+	struct drm_device *dev = m->private;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	uint16_t *latencies;
+
+	if (INTEL_INFO(dev)->gen >= 9)
+		latencies = dev_priv->wm.skl_latency;
+	else
+		latencies = to_i915(dev)->wm.cur_latency;
+
+	return wm_latency_write(file, ubuf, len, offp, latencies);
+}
+
+static const struct file_operations i915_pri_wm_latency_fops = {
+	.owner = THIS_MODULE,
+	.open = pri_wm_latency_open,
+	.read = seq_read,
+	.llseek = seq_lseek,
+	.release = single_release,
+	.write = pri_wm_latency_write
+};
+
+static const struct file_operations i915_spr_wm_latency_fops = {
+	.owner = THIS_MODULE,
+	.open = spr_wm_latency_open,
+	.read = seq_read,
+	.llseek = seq_lseek,
+	.release = single_release,
+	.write = spr_wm_latency_write
+};
+
+static const struct file_operations i915_cur_wm_latency_fops = {
+	.owner = THIS_MODULE,
+	.open = cur_wm_latency_open,
+	.read = seq_read,
+	.llseek = seq_lseek,
+	.release = single_release,
+	.write = cur_wm_latency_write
+};
+
+static int
+i915_wedged_get(void *data, u64 *val)
+{
+	struct drm_device *dev = data;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	*val = i915_terminally_wedged(&dev_priv->gpu_error);
+
+	return 0;
+}
+
+static int
+i915_wedged_set(void *data, u64 val)
+{
+	struct drm_device *dev = data;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	/*
+	 * There is no safeguard against this debugfs entry colliding
+	 * with the hangcheck calling same i915_handle_error() in
+	 * parallel, causing an explosion. For now we assume that the
+	 * test harness is responsible enough not to inject gpu hangs
+	 * while it is writing to 'i915_wedged'
+	 */
+
+	if (i915_reset_in_progress(&dev_priv->gpu_error))
+		return -EAGAIN;
+
+	intel_runtime_pm_get(dev_priv);
+
+	i915_handle_error(dev, val,
+			  "Manually setting wedged to %llu", val);
+
+	intel_runtime_pm_put(dev_priv);
+
+	return 0;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(i915_wedged_fops,
+			i915_wedged_get, i915_wedged_set,
+			"%llu\n");
+
+static int
+i915_ring_stop_get(void *data, u64 *val)
+{
+	struct drm_device *dev = data;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	*val = dev_priv->gpu_error.stop_rings;
+
+	return 0;
+}
+
+static int
+i915_ring_stop_set(void *data, u64 val)
+{
+	struct drm_device *dev = data;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	int ret;
+
+	DRM_DEBUG_DRIVER("Stopping rings 0x%08llx\n", val);
+
+	ret = mutex_lock_interruptible(&dev->struct_mutex);
+	if (ret)
+		return ret;
+
+	dev_priv->gpu_error.stop_rings = val;
+	mutex_unlock(&dev->struct_mutex);
+
+	return 0;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(i915_ring_stop_fops,
+			i915_ring_stop_get, i915_ring_stop_set,
+			"0x%08llx\n");
+
+static int
+i915_ring_missed_irq_get(void *data, u64 *val)
+{
+	struct drm_device *dev = data;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	*val = dev_priv->gpu_error.missed_irq_rings;
+	return 0;
+}
+
+static int
+i915_ring_missed_irq_set(void *data, u64 val)
+{
+	struct drm_device *dev = data;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	int ret;
+
+	/* Lock against concurrent debugfs callers */
+	ret = mutex_lock_interruptible(&dev->struct_mutex);
+	if (ret)
+		return ret;
+	dev_priv->gpu_error.missed_irq_rings = val;
+	mutex_unlock(&dev->struct_mutex);
+
+	return 0;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(i915_ring_missed_irq_fops,
+			i915_ring_missed_irq_get, i915_ring_missed_irq_set,
+			"0x%08llx\n");
+
+static int
+i915_ring_test_irq_get(void *data, u64 *val)
+{
+	struct drm_device *dev = data;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	*val = dev_priv->gpu_error.test_irq_rings;
+
+	return 0;
+}
+
+static int
+i915_ring_test_irq_set(void *data, u64 val)
+{
+	struct drm_device *dev = data;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	int ret;
+
+	DRM_DEBUG_DRIVER("Masking interrupts on rings 0x%08llx\n", val);
+
+	/* Lock against concurrent debugfs callers */
+	ret = mutex_lock_interruptible(&dev->struct_mutex);
+	if (ret)
+		return ret;
+
+	dev_priv->gpu_error.test_irq_rings = val;
+	mutex_unlock(&dev->struct_mutex);
+
+	return 0;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(i915_ring_test_irq_fops,
+			i915_ring_test_irq_get, i915_ring_test_irq_set,
+			"0x%08llx\n");
+
+#define DROP_UNBOUND 0x1
+#define DROP_BOUND 0x2
+#define DROP_RETIRE 0x4
+#define DROP_ACTIVE 0x8
+#define DROP_ALL (DROP_UNBOUND | \
+		  DROP_BOUND | \
+		  DROP_RETIRE | \
+		  DROP_ACTIVE)
+static int
+i915_drop_caches_get(void *data, u64 *val)
+{
+	*val = DROP_ALL;
+
+	return 0;
+}
+
+static int
+i915_drop_caches_set(void *data, u64 val)
+{
+	struct drm_device *dev = data;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	int ret;
+
+	DRM_DEBUG("Dropping caches: 0x%08llx\n", val);
+
+	/* No need to check and wait for gpu resets, only libdrm auto-restarts
+	 * on ioctls on -EAGAIN. */
+	ret = mutex_lock_interruptible(&dev->struct_mutex);
+	if (ret)
+		return ret;
+
+	if (val & DROP_ACTIVE) {
+		ret = i915_gpu_idle(dev);
+		if (ret)
+			goto unlock;
+	}
+
+	if (val & (DROP_RETIRE | DROP_ACTIVE))
+		i915_gem_retire_requests(dev);
+
+	if (val & DROP_BOUND)
+		i915_gem_shrink(dev_priv, LONG_MAX, I915_SHRINK_BOUND);
+
+	if (val & DROP_UNBOUND)
+		i915_gem_shrink(dev_priv, LONG_MAX, I915_SHRINK_UNBOUND);
+
+unlock:
+	mutex_unlock(&dev->struct_mutex);
+
+	return ret;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(i915_drop_caches_fops,
+			i915_drop_caches_get, i915_drop_caches_set,
+			"0x%08llx\n");
+
+static int
+i915_max_freq_get(void *data, u64 *val)
+{
+	struct drm_device *dev = data;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	int ret;
+
+	if (INTEL_INFO(dev)->gen < 6)
+		return -ENODEV;
+
+	flush_delayed_work(&dev_priv->rps.delayed_resume_work);
+
+	ret = mutex_lock_interruptible(&dev_priv->rps.hw_lock);
+	if (ret)
+		return ret;
+
+	*val = intel_gpu_freq(dev_priv, dev_priv->rps.max_freq_softlimit);
+	mutex_unlock(&dev_priv->rps.hw_lock);
+
+	return 0;
+}
+
+static int
+i915_max_freq_set(void *data, u64 val)
+{
+	struct drm_device *dev = data;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	u32 hw_max, hw_min;
+	int ret;
+
+	if (INTEL_INFO(dev)->gen < 6)
+		return -ENODEV;
+
+	flush_delayed_work(&dev_priv->rps.delayed_resume_work);
+
+	DRM_DEBUG_DRIVER("Manually setting max freq to %llu\n", val);
+
+	ret = mutex_lock_interruptible(&dev_priv->rps.hw_lock);
+	if (ret)
+		return ret;
+
+	/*
+	 * Turbo will still be enabled, but won't go above the set value.
+	 */
+	val = intel_freq_opcode(dev_priv, val);
+
+	hw_max = dev_priv->rps.max_freq;
+	hw_min = dev_priv->rps.min_freq;
+
+	if (val < hw_min || val > hw_max || val < dev_priv->rps.min_freq_softlimit) {
+		mutex_unlock(&dev_priv->rps.hw_lock);
+		return -EINVAL;
+	}
+
+	dev_priv->rps.max_freq_softlimit = val;
+
+	intel_set_rps(dev, val);
+
+	mutex_unlock(&dev_priv->rps.hw_lock);
+
+	return 0;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(i915_max_freq_fops,
+			i915_max_freq_get, i915_max_freq_set,
+			"%llu\n");
+
+static int
+i915_min_freq_get(void *data, u64 *val)
+{
+	struct drm_device *dev = data;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	int ret;
+
+	if (INTEL_INFO(dev)->gen < 6)
+		return -ENODEV;
+
+	flush_delayed_work(&dev_priv->rps.delayed_resume_work);
+
+	ret = mutex_lock_interruptible(&dev_priv->rps.hw_lock);
+	if (ret)
+		return ret;
+
+	*val = intel_gpu_freq(dev_priv, dev_priv->rps.min_freq_softlimit);
+	mutex_unlock(&dev_priv->rps.hw_lock);
+
+	return 0;
+}
+
+static int
+i915_min_freq_set(void *data, u64 val)
+{
+	struct drm_device *dev = data;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	u32 hw_max, hw_min;
+	int ret;
+
+	if (INTEL_INFO(dev)->gen < 6)
+		return -ENODEV;
+
+	flush_delayed_work(&dev_priv->rps.delayed_resume_work);
+
+	DRM_DEBUG_DRIVER("Manually setting min freq to %llu\n", val);
+
+	ret = mutex_lock_interruptible(&dev_priv->rps.hw_lock);
+	if (ret)
+		return ret;
+
+	/*
+	 * Turbo will still be enabled, but won't go below the set value.
+	 */
+	val = intel_freq_opcode(dev_priv, val);
+
+	hw_max = dev_priv->rps.max_freq;
+	hw_min = dev_priv->rps.min_freq;
+
+	if (val < hw_min || val > hw_max || val > dev_priv->rps.max_freq_softlimit) {
+		mutex_unlock(&dev_priv->rps.hw_lock);
+		return -EINVAL;
+	}
+
+	dev_priv->rps.min_freq_softlimit = val;
+
+	intel_set_rps(dev, val);
+
+	mutex_unlock(&dev_priv->rps.hw_lock);
+
+	return 0;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(i915_min_freq_fops,
+			i915_min_freq_get, i915_min_freq_set,
+			"%llu\n");
+
+static int
+i915_cache_sharing_get(void *data, u64 *val)
+{
+	struct drm_device *dev = data;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	u32 snpcr;
+	int ret;
+
+	if (!(IS_GEN6(dev) || IS_GEN7(dev)))
+		return -ENODEV;
+
+	ret = mutex_lock_interruptible(&dev->struct_mutex);
+	if (ret)
+		return ret;
+	intel_runtime_pm_get(dev_priv);
+
+	snpcr = I915_READ(GEN6_MBCUNIT_SNPCR);
+
+	intel_runtime_pm_put(dev_priv);
+	mutex_unlock(&dev_priv->dev->struct_mutex);
+
+	*val = (snpcr & GEN6_MBC_SNPCR_MASK) >> GEN6_MBC_SNPCR_SHIFT;
+
+	return 0;
+}
+
+static int
+i915_cache_sharing_set(void *data, u64 val)
+{
+	struct drm_device *dev = data;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	u32 snpcr;
+
+	if (!(IS_GEN6(dev) || IS_GEN7(dev)))
+		return -ENODEV;
+
+	if (val > 3)
+		return -EINVAL;
+
+	intel_runtime_pm_get(dev_priv);
+	DRM_DEBUG_DRIVER("Manually setting uncore sharing to %llu\n", val);
+
+	/* Update the cache sharing policy here as well */
+	snpcr = I915_READ(GEN6_MBCUNIT_SNPCR);
+	snpcr &= ~GEN6_MBC_SNPCR_MASK;
+	snpcr |= (val << GEN6_MBC_SNPCR_SHIFT);
+	I915_WRITE(GEN6_MBCUNIT_SNPCR, snpcr);
+
+	intel_runtime_pm_put(dev_priv);
+	return 0;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(i915_cache_sharing_fops,
+			i915_cache_sharing_get, i915_cache_sharing_set,
+			"%llu\n");
+
+struct sseu_dev_status {
+	unsigned int slice_total;
+	unsigned int subslice_total;
+	unsigned int subslice_per_slice;
+	unsigned int eu_total;
+	unsigned int eu_per_subslice;
+};
+
+static void cherryview_sseu_device_status(struct drm_device *dev,
+					  struct sseu_dev_status *stat)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	int ss_max = 2;
+	int ss;
+	u32 sig1[ss_max], sig2[ss_max];
+
+	sig1[0] = I915_READ(CHV_POWER_SS0_SIG1);
+	sig1[1] = I915_READ(CHV_POWER_SS1_SIG1);
+	sig2[0] = I915_READ(CHV_POWER_SS0_SIG2);
+	sig2[1] = I915_READ(CHV_POWER_SS1_SIG2);
+
+	for (ss = 0; ss < ss_max; ss++) {
+		unsigned int eu_cnt;
+
+		if (sig1[ss] & CHV_SS_PG_ENABLE)
+			/* skip disabled subslice */
+			continue;
+
+		stat->slice_total = 1;
+		stat->subslice_per_slice++;
+		eu_cnt = ((sig1[ss] & CHV_EU08_PG_ENABLE) ? 0 : 2) +
+			 ((sig1[ss] & CHV_EU19_PG_ENABLE) ? 0 : 2) +
+			 ((sig1[ss] & CHV_EU210_PG_ENABLE) ? 0 : 2) +
+			 ((sig2[ss] & CHV_EU311_PG_ENABLE) ? 0 : 2);
+		stat->eu_total += eu_cnt;
+		stat->eu_per_subslice = max(stat->eu_per_subslice, eu_cnt);
+	}
+	stat->subslice_total = stat->subslice_per_slice;
+}
+
+static void gen9_sseu_device_status(struct drm_device *dev,
+				    struct sseu_dev_status *stat)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	int s_max = 3, ss_max = 4;
+	int s, ss;
+	u32 s_reg[s_max], eu_reg[2*s_max], eu_mask[2];
+
+	/* BXT has a single slice and at most 3 subslices. */
+	if (IS_BROXTON(dev)) {
+		s_max = 1;
+		ss_max = 3;
+	}
+
+	for (s = 0; s < s_max; s++) {
+		s_reg[s] = I915_READ(GEN9_SLICE_PGCTL_ACK(s));
+		eu_reg[2*s] = I915_READ(GEN9_SS01_EU_PGCTL_ACK(s));
+		eu_reg[2*s + 1] = I915_READ(GEN9_SS23_EU_PGCTL_ACK(s));
+	}
+
+	eu_mask[0] = GEN9_PGCTL_SSA_EU08_ACK |
+		     GEN9_PGCTL_SSA_EU19_ACK |
+		     GEN9_PGCTL_SSA_EU210_ACK |
+		     GEN9_PGCTL_SSA_EU311_ACK;
+	eu_mask[1] = GEN9_PGCTL_SSB_EU08_ACK |
+		     GEN9_PGCTL_SSB_EU19_ACK |
+		     GEN9_PGCTL_SSB_EU210_ACK |
+		     GEN9_PGCTL_SSB_EU311_ACK;
+
+	for (s = 0; s < s_max; s++) {
+		unsigned int ss_cnt = 0;
+
+		if ((s_reg[s] & GEN9_PGCTL_SLICE_ACK) == 0)
+			/* skip disabled slice */
+			continue;
+
+		stat->slice_total++;
+
+		if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev))
+			ss_cnt = INTEL_INFO(dev)->subslice_per_slice;
+
+		for (ss = 0; ss < ss_max; ss++) {
+			unsigned int eu_cnt;
+
+			if (IS_BROXTON(dev) &&
+			    !(s_reg[s] & (GEN9_PGCTL_SS_ACK(ss))))
+				/* skip disabled subslice */
+				continue;
+
+			if (IS_BROXTON(dev))
+				ss_cnt++;
+
+			eu_cnt = 2 * hweight32(eu_reg[2*s + ss/2] &
+					       eu_mask[ss%2]);
+			stat->eu_total += eu_cnt;
+			stat->eu_per_subslice = max(stat->eu_per_subslice,
+						    eu_cnt);
+		}
+
+		stat->subslice_total += ss_cnt;
+		stat->subslice_per_slice = max(stat->subslice_per_slice,
+					       ss_cnt);
+	}
+}
+
+static void broadwell_sseu_device_status(struct drm_device *dev,
+					 struct sseu_dev_status *stat)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	int s;
+	u32 slice_info = I915_READ(GEN8_GT_SLICE_INFO);
+
+	stat->slice_total = hweight32(slice_info & GEN8_LSLICESTAT_MASK);
+
+	if (stat->slice_total) {
+		stat->subslice_per_slice = INTEL_INFO(dev)->subslice_per_slice;
+		stat->subslice_total = stat->slice_total *
+				       stat->subslice_per_slice;
+		stat->eu_per_subslice = INTEL_INFO(dev)->eu_per_subslice;
+		stat->eu_total = stat->eu_per_subslice * stat->subslice_total;
+
+		/* subtract fused off EU(s) from enabled slice(s) */
+		for (s = 0; s < stat->slice_total; s++) {
+			u8 subslice_7eu = INTEL_INFO(dev)->subslice_7eu[s];
+
+			stat->eu_total -= hweight8(subslice_7eu);
+		}
+	}
+}
+
+static int i915_sseu_status(struct seq_file *m, void *unused)
+{
+	struct drm_info_node *node = (struct drm_info_node *) m->private;
+	struct drm_device *dev = node->minor->dev;
+	struct sseu_dev_status stat;
+
+	if (INTEL_INFO(dev)->gen < 8)
+		return -ENODEV;
+
+	seq_puts(m, "SSEU Device Info\n");
+	seq_printf(m, "  Available Slice Total: %u\n",
+		   INTEL_INFO(dev)->slice_total);
+	seq_printf(m, "  Available Subslice Total: %u\n",
+		   INTEL_INFO(dev)->subslice_total);
+	seq_printf(m, "  Available Subslice Per Slice: %u\n",
+		   INTEL_INFO(dev)->subslice_per_slice);
+	seq_printf(m, "  Available EU Total: %u\n",
+		   INTEL_INFO(dev)->eu_total);
+	seq_printf(m, "  Available EU Per Subslice: %u\n",
+		   INTEL_INFO(dev)->eu_per_subslice);
+	seq_printf(m, "  Has Slice Power Gating: %s\n",
+		   yesno(INTEL_INFO(dev)->has_slice_pg));
+	seq_printf(m, "  Has Subslice Power Gating: %s\n",
+		   yesno(INTEL_INFO(dev)->has_subslice_pg));
+	seq_printf(m, "  Has EU Power Gating: %s\n",
+		   yesno(INTEL_INFO(dev)->has_eu_pg));
+
+	seq_puts(m, "SSEU Device Status\n");
+	memset(&stat, 0, sizeof(stat));
+	if (IS_CHERRYVIEW(dev)) {
+		cherryview_sseu_device_status(dev, &stat);
+	} else if (IS_BROADWELL(dev)) {
+		broadwell_sseu_device_status(dev, &stat);
+	} else if (INTEL_INFO(dev)->gen >= 9) {
+		gen9_sseu_device_status(dev, &stat);
+	}
+	seq_printf(m, "  Enabled Slice Total: %u\n",
+		   stat.slice_total);
+	seq_printf(m, "  Enabled Subslice Total: %u\n",
+		   stat.subslice_total);
+	seq_printf(m, "  Enabled Subslice Per Slice: %u\n",
+		   stat.subslice_per_slice);
+	seq_printf(m, "  Enabled EU Total: %u\n",
+		   stat.eu_total);
+	seq_printf(m, "  Enabled EU Per Subslice: %u\n",
+		   stat.eu_per_subslice);
+
+	return 0;
+}
+
+static int i915_forcewake_open(struct inode *inode, struct file *file)
+{
+	struct drm_device *dev = inode->i_private;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	if (INTEL_INFO(dev)->gen < 6)
+		return 0;
+
+	intel_runtime_pm_get(dev_priv);
+	intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL);
+
+	return 0;
+}
+
+static int i915_forcewake_release(struct inode *inode, struct file *file)
+{
+	struct drm_device *dev = inode->i_private;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	if (INTEL_INFO(dev)->gen < 6)
+		return 0;
+
+	intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
+	intel_runtime_pm_put(dev_priv);
+
+	return 0;
+}
+
+static const struct file_operations i915_forcewake_fops = {
+	.owner = THIS_MODULE,
+	.open = i915_forcewake_open,
+	.release = i915_forcewake_release,
+};
+
+static int i915_forcewake_create(struct dentry *root, struct drm_minor *minor)
+{
+	struct drm_device *dev = minor->dev;
+	struct dentry *ent;
+
+	ent = debugfs_create_file("i915_forcewake_user",
+				  S_IRUSR,
+				  root, dev,
+				  &i915_forcewake_fops);
+	if (!ent)
+		return -ENOMEM;
+
+	return drm_add_fake_info_node(minor, ent, &i915_forcewake_fops);
+}
+
+static int i915_debugfs_create(struct dentry *root,
+			       struct drm_minor *minor,
+			       const char *name,
+			       const struct file_operations *fops)
+{
+	struct drm_device *dev = minor->dev;
+	struct dentry *ent;
+
+	ent = debugfs_create_file(name,
+				  S_IRUGO | S_IWUSR,
+				  root, dev,
+				  fops);
+	if (!ent)
+		return -ENOMEM;
+
+	return drm_add_fake_info_node(minor, ent, fops);
+}
+
+static const struct drm_info_list i915_debugfs_list[] = {
+	{"i915_capabilities", i915_capabilities, 0},
+	{"i915_gem_objects", i915_gem_object_info, 0},
+	{"i915_gem_gtt", i915_gem_gtt_info, 0},
+	{"i915_gem_pinned", i915_gem_gtt_info, 0, (void *) PINNED_LIST},
+	{"i915_gem_active", i915_gem_object_list_info, 0, (void *) ACTIVE_LIST},
+	{"i915_gem_inactive", i915_gem_object_list_info, 0, (void *) INACTIVE_LIST},
+	{"i915_gem_stolen", i915_gem_stolen_list_info },
+	{"i915_gem_pageflip", i915_gem_pageflip_info, 0},
+	{"i915_gem_request", i915_gem_request_info, 0},
+	{"i915_gem_seqno", i915_gem_seqno_info, 0},
+	{"i915_gem_fence_regs", i915_gem_fence_regs_info, 0},
+	{"i915_gem_interrupt", i915_interrupt_info, 0},
+	{"i915_gem_hws", i915_hws_info, 0, (void *)RCS},
+	{"i915_gem_hws_blt", i915_hws_info, 0, (void *)BCS},
+	{"i915_gem_hws_bsd", i915_hws_info, 0, (void *)VCS},
+	{"i915_gem_hws_vebox", i915_hws_info, 0, (void *)VECS},
+	{"i915_gem_batch_pool", i915_gem_batch_pool_info, 0},
+	{"i915_guc_info", i915_guc_info, 0},
+	{"i915_guc_load_status", i915_guc_load_status_info, 0},
+	{"i915_guc_log_dump", i915_guc_log_dump, 0},
+	{"i915_frequency_info", i915_frequency_info, 0},
+	{"i915_hangcheck_info", i915_hangcheck_info, 0},
+	{"i915_drpc_info", i915_drpc_info, 0},
+	{"i915_emon_status", i915_emon_status, 0},
+	{"i915_ring_freq_table", i915_ring_freq_table, 0},
+	{"i915_frontbuffer_tracking", i915_frontbuffer_tracking, 0},
+	{"i915_fbc_status", i915_fbc_status, 0},
+	{"i915_ips_status", i915_ips_status, 0},
+	{"i915_sr_status", i915_sr_status, 0},
+	{"i915_opregion", i915_opregion, 0},
+	{"i915_vbt", i915_vbt, 0},
+	{"i915_gem_framebuffer", i915_gem_framebuffer_info, 0},
+	{"i915_context_status", i915_context_status, 0},
+	{"i915_dump_lrc", i915_dump_lrc, 0},
+	{"i915_execlists", i915_execlists, 0},
+	{"i915_forcewake_domains", i915_forcewake_domains, 0},
+	{"i915_swizzle_info", i915_swizzle_info, 0},
+	{"i915_ppgtt_info", i915_ppgtt_info, 0},
+	{"i915_llc", i915_llc, 0},
+	{"i915_edp_psr_status", i915_edp_psr_status, 0},
+	{"i915_sink_crc_eDP1", i915_sink_crc, 0},
+	{"i915_energy_uJ", i915_energy_uJ, 0},
+	{"i915_runtime_pm_status", i915_runtime_pm_status, 0},
+	{"i915_power_domain_info", i915_power_domain_info, 0},
+	{"i915_dmc_info", i915_dmc_info, 0},
+	{"i915_display_info", i915_display_info, 0},
+	{"i915_semaphore_status", i915_semaphore_status, 0},
+	{"i915_shared_dplls_info", i915_shared_dplls_info, 0},
+	{"i915_dp_mst_info", i915_dp_mst_info, 0},
+	{"i915_wa_registers", i915_wa_registers, 0},
+	{"i915_ddb_info", i915_ddb_info, 0},
+	{"i915_sseu_status", i915_sseu_status, 0},
+	{"i915_drrs_status", i915_drrs_status, 0},
+	{"i915_rps_boost_info", i915_rps_boost_info, 0},
+};
+#define I915_DEBUGFS_ENTRIES ARRAY_SIZE(i915_debugfs_list)
+
+static const struct i915_debugfs_files {
+	const char *name;
+	const struct file_operations *fops;
+} i915_debugfs_files[] = {
+	{"i915_wedged", &i915_wedged_fops},
+	{"i915_max_freq", &i915_max_freq_fops},
+	{"i915_min_freq", &i915_min_freq_fops},
+	{"i915_cache_sharing", &i915_cache_sharing_fops},
+	{"i915_ring_stop", &i915_ring_stop_fops},
+	{"i915_ring_missed_irq", &i915_ring_missed_irq_fops},
+	{"i915_ring_test_irq", &i915_ring_test_irq_fops},
+	{"i915_gem_drop_caches", &i915_drop_caches_fops},
+	{"i915_error_state", &i915_error_state_fops},
+	{"i915_next_seqno", &i915_next_seqno_fops},
+	{"i915_display_crc_ctl", &i915_display_crc_ctl_fops},
+	{"i915_pri_wm_latency", &i915_pri_wm_latency_fops},
+	{"i915_spr_wm_latency", &i915_spr_wm_latency_fops},
+	{"i915_cur_wm_latency", &i915_cur_wm_latency_fops},
+	{"i915_fbc_false_color", &i915_fbc_fc_fops},
+	{"i915_dp_test_data", &i915_displayport_test_data_fops},
+	{"i915_dp_test_type", &i915_displayport_test_type_fops},
+	{"i915_dp_test_active", &i915_displayport_test_active_fops}
+};
+
+void intel_display_crc_init(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	enum pipe pipe;
+
+	for_each_pipe(dev_priv, pipe) {
+		struct intel_pipe_crc *pipe_crc = &dev_priv->pipe_crc[pipe];
+
+		pipe_crc->opened = false;
+		spin_lock_init(&pipe_crc->lock);
+		init_waitqueue_head(&pipe_crc->wq);
+	}
+}
+
+int i915_debugfs_init(struct drm_minor *minor)
+{
+	int ret, i;
+
+	ret = i915_forcewake_create(minor->debugfs_root, minor);
+	if (ret)
+		return ret;
+
+	for (i = 0; i < ARRAY_SIZE(i915_pipe_crc_data); i++) {
+		ret = i915_pipe_crc_create(minor->debugfs_root, minor, i);
+		if (ret)
+			return ret;
+	}
+
+	for (i = 0; i < ARRAY_SIZE(i915_debugfs_files); i++) {
+		ret = i915_debugfs_create(minor->debugfs_root, minor,
+					  i915_debugfs_files[i].name,
+					  i915_debugfs_files[i].fops);
+		if (ret)
+			return ret;
+	}
+
+	return drm_debugfs_create_files(i915_debugfs_list,
+					I915_DEBUGFS_ENTRIES,
+					minor->debugfs_root, minor);
+}
+
+void i915_debugfs_cleanup(struct drm_minor *minor)
+{
+	int i;
+
+	drm_debugfs_remove_files(i915_debugfs_list,
+				 I915_DEBUGFS_ENTRIES, minor);
+
+	drm_debugfs_remove_files((struct drm_info_list *) &i915_forcewake_fops,
+				 1, minor);
+
+	for (i = 0; i < ARRAY_SIZE(i915_pipe_crc_data); i++) {
+		struct drm_info_list *info_list =
+			(struct drm_info_list *)&i915_pipe_crc_data[i];
+
+		drm_debugfs_remove_files(info_list, 1, minor);
+	}
+
+	for (i = 0; i < ARRAY_SIZE(i915_debugfs_files); i++) {
+		struct drm_info_list *info_list =
+			(struct drm_info_list *) i915_debugfs_files[i].fops;
+
+		drm_debugfs_remove_files(info_list, 1, minor);
+	}
+}
+
+struct dpcd_block {
+	/* DPCD dump start address. */
+	unsigned int offset;
+	/* DPCD dump end address, inclusive. If unset, .size will be used. */
+	unsigned int end;
+	/* DPCD dump size. Used if .end is unset. If unset, defaults to 1. */
+	size_t size;
+	/* Only valid for eDP. */
+	bool edp;
+};
+
+static const struct dpcd_block i915_dpcd_debug[] = {
+	{ .offset = DP_DPCD_REV, .size = DP_RECEIVER_CAP_SIZE },
+	{ .offset = DP_PSR_SUPPORT, .end = DP_PSR_CAPS },
+	{ .offset = DP_DOWNSTREAM_PORT_0, .size = 16 },
+	{ .offset = DP_LINK_BW_SET, .end = DP_EDP_CONFIGURATION_SET },
+	{ .offset = DP_SINK_COUNT, .end = DP_ADJUST_REQUEST_LANE2_3 },
+	{ .offset = DP_SET_POWER },
+	{ .offset = DP_EDP_DPCD_REV },
+	{ .offset = DP_EDP_GENERAL_CAP_1, .end = DP_EDP_GENERAL_CAP_3 },
+	{ .offset = DP_EDP_DISPLAY_CONTROL_REGISTER, .end = DP_EDP_BACKLIGHT_FREQ_CAP_MAX_LSB },
+	{ .offset = DP_EDP_DBC_MINIMUM_BRIGHTNESS_SET, .end = DP_EDP_DBC_MAXIMUM_BRIGHTNESS_SET },
+};
+
+static int i915_dpcd_show(struct seq_file *m, void *data)
+{
+	struct drm_connector *connector = m->private;
+	struct intel_dp *intel_dp =
+		enc_to_intel_dp(&intel_attached_encoder(connector)->base);
+	uint8_t buf[16];
+	ssize_t err;
+	int i;
+
+	if (connector->status != connector_status_connected)
+		return -ENODEV;
+
+	for (i = 0; i < ARRAY_SIZE(i915_dpcd_debug); i++) {
+		const struct dpcd_block *b = &i915_dpcd_debug[i];
+		size_t size = b->end ? b->end - b->offset + 1 : (b->size ?: 1);
+
+		if (b->edp &&
+		    connector->connector_type != DRM_MODE_CONNECTOR_eDP)
+			continue;
+
+		/* low tech for now */
+		if (WARN_ON(size > sizeof(buf)))
+			continue;
+
+		err = drm_dp_dpcd_read(&intel_dp->aux, b->offset, buf, size);
+		if (err <= 0) {
+			DRM_ERROR("dpcd read (%zu bytes at %u) failed (%zd)\n",
+				  size, b->offset, err);
+			continue;
+		}
+
+		seq_printf(m, "%04x: %*ph\n", b->offset, (int) size, buf);
+	}
+
+	return 0;
+}
+
+static int i915_dpcd_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, i915_dpcd_show, inode->i_private);
+}
+
+static const struct file_operations i915_dpcd_fops = {
+	.owner = THIS_MODULE,
+	.open = i915_dpcd_open,
+	.read = seq_read,
+	.llseek = seq_lseek,
+	.release = single_release,
+};
+
+/**
+ * i915_debugfs_connector_add - add i915 specific connector debugfs files
+ * @connector: pointer to a registered drm_connector
+ *
+ * Cleanup will be done by drm_connector_unregister() through a call to
+ * drm_debugfs_connector_remove().
+ *
+ * Returns 0 on success, negative error codes on error.
+ */
+int i915_debugfs_connector_add(struct drm_connector *connector)
+{
+	struct dentry *root = connector->debugfs_entry;
+
+	/* The connector must have been registered beforehands. */
+	if (!root)
+		return -ENODEV;
+
+	if (connector->connector_type == DRM_MODE_CONNECTOR_DisplayPort ||
+	    connector->connector_type == DRM_MODE_CONNECTOR_eDP)
+		debugfs_create_file("i915_dpcd", S_IRUGO, root, connector,
+				    &i915_dpcd_fops);
+
+	return 0;
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/i915/i915_dma.c
@@ -0,0 +1,1587 @@
+/* i915_dma.c -- DMA support for the I915 -*- linux-c -*-
+ */
+/*
+ * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <drm/drmP.h>
+#include <drm/drm_crtc_helper.h>
+#include <drm/drm_fb_helper.h>
+#include <drm/drm_legacy.h>
+#include "intel_drv.h"
+#include <drm/i915_drm.h>
+#include "i915_drv.h"
+#include "i915_vgpu.h"
+#include "i915_trace.h"
+#include <linux/pci.h>
+#include <linux/console.h>
+#include <linux/vt.h>
+#include <linux/vgaarb.h>
+#include <linux/acpi.h>
+#include <linux/pnp.h>
+#include <linux/vga_switcheroo.h>
+#include <linux/slab.h>
+#include <acpi/video.h>
+#include <linux/pm.h>
+#include <linux/pm_runtime.h>
+#include <linux/oom.h>
+
+static unsigned int i915_load_fail_count;
+
+bool __i915_inject_load_failure(const char *func, int line)
+{
+	if (i915_load_fail_count >= i915.inject_load_failure)
+		return false;
+
+	if (++i915_load_fail_count == i915.inject_load_failure) {
+		DRM_INFO("Injecting failure at checkpoint %u [%s:%d]\n",
+			 i915.inject_load_failure, func, line);
+		return true;
+	}
+
+	return false;
+}
+
+#define FDO_BUG_URL "https://bugs.freedesktop.org/enter_bug.cgi?product=DRI"
+#define FDO_BUG_MSG "Please file a bug at " FDO_BUG_URL " against DRM/Intel " \
+		    "providing the dmesg log by booting with drm.debug=0xf"
+
+void
+__i915_printk(struct drm_i915_private *dev_priv, const char *level,
+	      const char *fmt, ...)
+{
+	static bool shown_bug_once;
+	struct device *dev = dev_priv->dev->dev;
+	bool is_error = level[1] <= KERN_ERR[1];
+	bool is_debug = level[1] == KERN_DEBUG[1];
+	struct va_format vaf;
+	va_list args;
+
+	if (is_debug && !(drm_debug & DRM_UT_DRIVER))
+		return;
+
+	va_start(args, fmt);
+
+	vaf.fmt = fmt;
+	vaf.va = &args;
+
+	dev_printk(level, dev, "[" DRM_NAME ":%ps] %pV",
+		   __builtin_return_address(0), &vaf);
+
+	if (is_error && !shown_bug_once) {
+		dev_notice(dev, "%s", FDO_BUG_MSG);
+		shown_bug_once = true;
+	}
+
+	va_end(args);
+}
+
+static bool i915_error_injected(struct drm_i915_private *dev_priv)
+{
+	return i915.inject_load_failure &&
+	       i915_load_fail_count == i915.inject_load_failure;
+}
+
+#define i915_load_error(dev_priv, fmt, ...)				     \
+	__i915_printk(dev_priv,						     \
+		      i915_error_injected(dev_priv) ? KERN_DEBUG : KERN_ERR, \
+		      fmt, ##__VA_ARGS__)
+
+static int i915_getparam(struct drm_device *dev, void *data,
+			 struct drm_file *file_priv)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	drm_i915_getparam_t *param = data;
+	int value;
+
+	switch (param->param) {
+	case I915_PARAM_IRQ_ACTIVE:
+	case I915_PARAM_ALLOW_BATCHBUFFER:
+	case I915_PARAM_LAST_DISPATCH:
+		/* Reject all old ums/dri params. */
+		return -ENODEV;
+	case I915_PARAM_CHIPSET_ID:
+		value = dev->pdev->device;
+		break;
+	case I915_PARAM_REVISION:
+		value = dev->pdev->revision;
+		break;
+	case I915_PARAM_HAS_GEM:
+		value = 1;
+		break;
+	case I915_PARAM_NUM_FENCES_AVAIL:
+		value = dev_priv->num_fence_regs;
+		break;
+	case I915_PARAM_HAS_OVERLAY:
+		value = dev_priv->overlay ? 1 : 0;
+		break;
+	case I915_PARAM_HAS_PAGEFLIPPING:
+		value = 1;
+		break;
+	case I915_PARAM_HAS_EXECBUF2:
+		/* depends on GEM */
+		value = 1;
+		break;
+	case I915_PARAM_HAS_BSD:
+		value = intel_engine_initialized(&dev_priv->engine[VCS]);
+		break;
+	case I915_PARAM_HAS_BLT:
+		value = intel_engine_initialized(&dev_priv->engine[BCS]);
+		break;
+	case I915_PARAM_HAS_VEBOX:
+		value = intel_engine_initialized(&dev_priv->engine[VECS]);
+		break;
+	case I915_PARAM_HAS_BSD2:
+		value = intel_engine_initialized(&dev_priv->engine[VCS2]);
+		break;
+	case I915_PARAM_HAS_RELAXED_FENCING:
+		value = 1;
+		break;
+	case I915_PARAM_HAS_COHERENT_RINGS:
+		value = 1;
+		break;
+	case I915_PARAM_HAS_EXEC_CONSTANTS:
+		value = INTEL_INFO(dev)->gen >= 4;
+		break;
+	case I915_PARAM_HAS_RELAXED_DELTA:
+		value = 1;
+		break;
+	case I915_PARAM_HAS_GEN7_SOL_RESET:
+		value = 1;
+		break;
+	case I915_PARAM_HAS_LLC:
+		value = HAS_LLC(dev);
+		break;
+	case I915_PARAM_HAS_WT:
+		value = HAS_WT(dev);
+		break;
+	case I915_PARAM_HAS_ALIASING_PPGTT:
+		value = USES_PPGTT(dev);
+		break;
+	case I915_PARAM_HAS_WAIT_TIMEOUT:
+		value = 1;
+		break;
+	case I915_PARAM_HAS_SEMAPHORES:
+		value = i915_semaphore_is_enabled(dev);
+		break;
+	case I915_PARAM_HAS_PRIME_VMAP_FLUSH:
+		value = 1;
+		break;
+	case I915_PARAM_HAS_SECURE_BATCHES:
+		value = capable(CAP_SYS_ADMIN);
+		break;
+	case I915_PARAM_HAS_PINNED_BATCHES:
+		value = 1;
+		break;
+	case I915_PARAM_HAS_EXEC_NO_RELOC:
+		value = 1;
+		break;
+	case I915_PARAM_HAS_EXEC_HANDLE_LUT:
+		value = 1;
+		break;
+	case I915_PARAM_CMD_PARSER_VERSION:
+		value = i915_cmd_parser_get_version();
+		break;
+	case I915_PARAM_HAS_COHERENT_PHYS_GTT:
+		value = 1;
+		break;
+	case I915_PARAM_MMAP_VERSION:
+		value = 1;
+		break;
+	case I915_PARAM_SUBSLICE_TOTAL:
+		value = INTEL_INFO(dev)->subslice_total;
+		if (!value)
+			return -ENODEV;
+		break;
+	case I915_PARAM_EU_TOTAL:
+		value = INTEL_INFO(dev)->eu_total;
+		if (!value)
+			return -ENODEV;
+		break;
+	case I915_PARAM_HAS_GPU_RESET:
+		value = i915.enable_hangcheck &&
+			intel_has_gpu_reset(dev);
+		break;
+	case I915_PARAM_HAS_RESOURCE_STREAMER:
+		value = HAS_RESOURCE_STREAMER(dev);
+		break;
+	case I915_PARAM_HAS_EXEC_SOFTPIN:
+		value = 1;
+		break;
+	default:
+		DRM_DEBUG("Unknown parameter %d\n", param->param);
+		return -EINVAL;
+	}
+
+	if (copy_to_user(param->value, &value, sizeof(int))) {
+		DRM_ERROR("copy_to_user failed\n");
+		return -EFAULT;
+	}
+
+	return 0;
+}
+
+static int i915_get_bridge_dev(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	dev_priv->bridge_dev = pci_get_bus_and_slot(0, PCI_DEVFN(0, 0));
+	if (!dev_priv->bridge_dev) {
+		DRM_ERROR("bridge device not found\n");
+		return -1;
+	}
+	return 0;
+}
+
+/* Allocate space for the MCH regs if needed, return nonzero on error */
+static int
+intel_alloc_mchbar_resource(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	int reg = INTEL_INFO(dev)->gen >= 4 ? MCHBAR_I965 : MCHBAR_I915;
+	u32 temp_lo, temp_hi = 0;
+	u64 mchbar_addr;
+	int ret;
+
+	if (INTEL_INFO(dev)->gen >= 4)
+		pci_read_config_dword(dev_priv->bridge_dev, reg + 4, &temp_hi);
+	pci_read_config_dword(dev_priv->bridge_dev, reg, &temp_lo);
+	mchbar_addr = ((u64)temp_hi << 32) | temp_lo;
+
+	/* If ACPI doesn't have it, assume we need to allocate it ourselves */
+#ifdef CONFIG_PNP
+	if (mchbar_addr &&
+	    pnp_range_reserved(mchbar_addr, mchbar_addr + MCHBAR_SIZE))
+		return 0;
+#endif
+
+	/* Get some space for it */
+	dev_priv->mch_res.name = "i915 MCHBAR";
+	dev_priv->mch_res.flags = IORESOURCE_MEM;
+	ret = pci_bus_alloc_resource(dev_priv->bridge_dev->bus,
+				     &dev_priv->mch_res,
+				     MCHBAR_SIZE, MCHBAR_SIZE,
+				     PCIBIOS_MIN_MEM,
+				     0, pcibios_align_resource,
+				     dev_priv->bridge_dev);
+	if (ret) {
+		DRM_DEBUG_DRIVER("failed bus alloc: %d\n", ret);
+		dev_priv->mch_res.start = 0;
+		return ret;
+	}
+
+	if (INTEL_INFO(dev)->gen >= 4)
+		pci_write_config_dword(dev_priv->bridge_dev, reg + 4,
+				       upper_32_bits(dev_priv->mch_res.start));
+
+	pci_write_config_dword(dev_priv->bridge_dev, reg,
+			       lower_32_bits(dev_priv->mch_res.start));
+	return 0;
+}
+
+/* Setup MCHBAR if possible, return true if we should disable it again */
+static void
+intel_setup_mchbar(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	int mchbar_reg = INTEL_INFO(dev)->gen >= 4 ? MCHBAR_I965 : MCHBAR_I915;
+	u32 temp;
+	bool enabled;
+
+	if (IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev))
+		return;
+
+	dev_priv->mchbar_need_disable = false;
+
+	if (IS_I915G(dev) || IS_I915GM(dev)) {
+		pci_read_config_dword(dev_priv->bridge_dev, DEVEN, &temp);
+		enabled = !!(temp & DEVEN_MCHBAR_EN);
+	} else {
+		pci_read_config_dword(dev_priv->bridge_dev, mchbar_reg, &temp);
+		enabled = temp & 1;
+	}
+
+	/* If it's already enabled, don't have to do anything */
+	if (enabled)
+		return;
+
+	if (intel_alloc_mchbar_resource(dev))
+		return;
+
+	dev_priv->mchbar_need_disable = true;
+
+	/* Space is allocated or reserved, so enable it. */
+	if (IS_I915G(dev) || IS_I915GM(dev)) {
+		pci_write_config_dword(dev_priv->bridge_dev, DEVEN,
+				       temp | DEVEN_MCHBAR_EN);
+	} else {
+		pci_read_config_dword(dev_priv->bridge_dev, mchbar_reg, &temp);
+		pci_write_config_dword(dev_priv->bridge_dev, mchbar_reg, temp | 1);
+	}
+}
+
+static void
+intel_teardown_mchbar(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	int mchbar_reg = INTEL_INFO(dev)->gen >= 4 ? MCHBAR_I965 : MCHBAR_I915;
+
+	if (dev_priv->mchbar_need_disable) {
+		if (IS_I915G(dev) || IS_I915GM(dev)) {
+			u32 deven_val;
+
+			pci_read_config_dword(dev_priv->bridge_dev, DEVEN,
+					      &deven_val);
+			deven_val &= ~DEVEN_MCHBAR_EN;
+			pci_write_config_dword(dev_priv->bridge_dev, DEVEN,
+					       deven_val);
+		} else {
+			u32 mchbar_val;
+
+			pci_read_config_dword(dev_priv->bridge_dev, mchbar_reg,
+					      &mchbar_val);
+			mchbar_val &= ~1;
+			pci_write_config_dword(dev_priv->bridge_dev, mchbar_reg,
+					       mchbar_val);
+		}
+	}
+
+	if (dev_priv->mch_res.start)
+		release_resource(&dev_priv->mch_res);
+}
+
+/* true = enable decode, false = disable decoder */
+static unsigned int i915_vga_set_decode(void *cookie, bool state)
+{
+	struct drm_device *dev = cookie;
+
+	intel_modeset_vga_set_state(dev, state);
+	if (state)
+		return VGA_RSRC_LEGACY_IO | VGA_RSRC_LEGACY_MEM |
+		       VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM;
+	else
+		return VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM;
+}
+
+static void i915_switcheroo_set_state(struct pci_dev *pdev, enum vga_switcheroo_state state)
+{
+	struct drm_device *dev = pci_get_drvdata(pdev);
+	pm_message_t pmm = { .event = PM_EVENT_SUSPEND };
+
+	if (state == VGA_SWITCHEROO_ON) {
+		pr_info("switched on\n");
+		dev->switch_power_state = DRM_SWITCH_POWER_CHANGING;
+		/* i915 resume handler doesn't set to D0 */
+		pci_set_power_state(dev->pdev, PCI_D0);
+		i915_resume_switcheroo(dev);
+		dev->switch_power_state = DRM_SWITCH_POWER_ON;
+	} else {
+		pr_info("switched off\n");
+		dev->switch_power_state = DRM_SWITCH_POWER_CHANGING;
+		i915_suspend_switcheroo(dev, pmm);
+		dev->switch_power_state = DRM_SWITCH_POWER_OFF;
+	}
+}
+
+static bool i915_switcheroo_can_switch(struct pci_dev *pdev)
+{
+	struct drm_device *dev = pci_get_drvdata(pdev);
+
+	/*
+	 * FIXME: open_count is protected by drm_global_mutex but that would lead to
+	 * locking inversion with the driver load path. And the access here is
+	 * completely racy anyway. So don't bother with locking for now.
+	 */
+	return dev->open_count == 0;
+}
+
+static const struct vga_switcheroo_client_ops i915_switcheroo_ops = {
+	.set_gpu_state = i915_switcheroo_set_state,
+	.reprobe = NULL,
+	.can_switch = i915_switcheroo_can_switch,
+};
+
+static int i915_load_modeset_init(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	int ret;
+
+	if (i915_inject_load_failure())
+		return -ENODEV;
+
+	ret = intel_bios_init(dev_priv);
+	if (ret)
+		DRM_INFO("failed to find VBIOS tables\n");
+
+	/* If we have > 1 VGA cards, then we need to arbitrate access
+	 * to the common VGA resources.
+	 *
+	 * If we are a secondary display controller (!PCI_DISPLAY_CLASS_VGA),
+	 * then we do not take part in VGA arbitration and the
+	 * vga_client_register() fails with -ENODEV.
+	 */
+	ret = vga_client_register(dev->pdev, dev, NULL, i915_vga_set_decode);
+	if (ret && ret != -ENODEV)
+		goto out;
+
+	intel_register_dsm_handler();
+
+	ret = vga_switcheroo_register_client(dev->pdev, &i915_switcheroo_ops, false);
+	if (ret)
+		goto cleanup_vga_client;
+
+	intel_power_domains_init_hw(dev_priv, false);
+
+	intel_csr_ucode_init(dev_priv);
+
+	ret = intel_irq_install(dev_priv);
+	if (ret)
+		goto cleanup_csr;
+
+	intel_setup_gmbus(dev);
+
+	/* Important: The output setup functions called by modeset_init need
+	 * working irqs for e.g. gmbus and dp aux transfers. */
+	intel_modeset_init(dev);
+
+	intel_guc_ucode_init(dev);
+
+	ret = i915_gem_init(dev);
+	if (ret)
+		goto cleanup_irq;
+
+	intel_modeset_gem_init(dev);
+
+	if (INTEL_INFO(dev)->num_pipes == 0)
+		return 0;
+
+	ret = intel_fbdev_init(dev);
+	if (ret)
+		goto cleanup_gem;
+
+	/* Only enable hotplug handling once the fbdev is fully set up. */
+	intel_hpd_init(dev_priv);
+
+	/*
+	 * Some ports require correctly set-up hpd registers for detection to
+	 * work properly (leading to ghost connected connector status), e.g. VGA
+	 * on gm45.  Hence we can only set up the initial fbdev config after hpd
+	 * irqs are fully enabled. Now we should scan for the initial config
+	 * only once hotplug handling is enabled, but due to screwed-up locking
+	 * around kms/fbdev init we can't protect the fdbev initial config
+	 * scanning against hotplug events. Hence do this first and ignore the
+	 * tiny window where we will loose hotplug notifactions.
+	 */
+	intel_fbdev_initial_config_async(dev);
+
+	drm_kms_helper_poll_init(dev);
+
+	return 0;
+
+cleanup_gem:
+	mutex_lock(&dev->struct_mutex);
+	i915_gem_cleanup_engines(dev);
+	i915_gem_context_fini(dev);
+	mutex_unlock(&dev->struct_mutex);
+cleanup_irq:
+	intel_guc_ucode_fini(dev);
+	drm_irq_uninstall(dev);
+	intel_teardown_gmbus(dev);
+cleanup_csr:
+	intel_csr_ucode_fini(dev_priv);
+	intel_power_domains_fini(dev_priv);
+	vga_switcheroo_unregister_client(dev->pdev);
+cleanup_vga_client:
+	vga_client_register(dev->pdev, NULL, NULL, NULL);
+out:
+	return ret;
+}
+
+#if IS_ENABLED(CONFIG_FB)
+static int i915_kick_out_firmware_fb(struct drm_i915_private *dev_priv)
+{
+	struct apertures_struct *ap;
+	struct pci_dev *pdev = dev_priv->dev->pdev;
+	struct i915_ggtt *ggtt = &dev_priv->ggtt;
+	bool primary;
+	int ret;
+
+	ap = alloc_apertures(1);
+	if (!ap)
+		return -ENOMEM;
+
+	ap->ranges[0].base = ggtt->mappable_base;
+	ap->ranges[0].size = ggtt->mappable_end;
+
+	primary =
+		pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW;
+
+	ret = remove_conflicting_framebuffers(ap, "inteldrmfb", primary);
+
+	kfree(ap);
+
+	return ret;
+}
+#else
+static int i915_kick_out_firmware_fb(struct drm_i915_private *dev_priv)
+{
+	return 0;
+}
+#endif
+
+#if !defined(CONFIG_VGA_CONSOLE)
+static int i915_kick_out_vgacon(struct drm_i915_private *dev_priv)
+{
+	return 0;
+}
+#elif !defined(CONFIG_DUMMY_CONSOLE)
+static int i915_kick_out_vgacon(struct drm_i915_private *dev_priv)
+{
+	return -ENODEV;
+}
+#else
+static int i915_kick_out_vgacon(struct drm_i915_private *dev_priv)
+{
+	int ret = 0;
+
+	DRM_INFO("Replacing VGA console driver\n");
+
+	console_lock();
+	if (con_is_bound(&vga_con))
+		ret = do_take_over_console(&dummy_con, 0, MAX_NR_CONSOLES - 1, 1);
+	if (ret == 0) {
+		ret = do_unregister_con_driver(&vga_con);
+
+		/* Ignore "already unregistered". */
+		if (ret == -ENODEV)
+			ret = 0;
+	}
+	console_unlock();
+
+	return ret;
+}
+#endif
+
+static void i915_dump_device_info(struct drm_i915_private *dev_priv)
+{
+	const struct intel_device_info *info = &dev_priv->info;
+
+#define PRINT_S(name) "%s"
+#define SEP_EMPTY
+#define PRINT_FLAG(name) info->name ? #name "," : ""
+#define SEP_COMMA ,
+	DRM_DEBUG_DRIVER("i915 device info: gen=%i, pciid=0x%04x rev=0x%02x flags="
+			 DEV_INFO_FOR_EACH_FLAG(PRINT_S, SEP_EMPTY),
+			 info->gen,
+			 dev_priv->dev->pdev->device,
+			 dev_priv->dev->pdev->revision,
+			 DEV_INFO_FOR_EACH_FLAG(PRINT_FLAG, SEP_COMMA));
+#undef PRINT_S
+#undef SEP_EMPTY
+#undef PRINT_FLAG
+#undef SEP_COMMA
+}
+
+static void cherryview_sseu_info_init(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_device_info *info;
+	u32 fuse, eu_dis;
+
+	info = (struct intel_device_info *)&dev_priv->info;
+	fuse = I915_READ(CHV_FUSE_GT);
+
+	info->slice_total = 1;
+
+	if (!(fuse & CHV_FGT_DISABLE_SS0)) {
+		info->subslice_per_slice++;
+		eu_dis = fuse & (CHV_FGT_EU_DIS_SS0_R0_MASK |
+				 CHV_FGT_EU_DIS_SS0_R1_MASK);
+		info->eu_total += 8 - hweight32(eu_dis);
+	}
+
+	if (!(fuse & CHV_FGT_DISABLE_SS1)) {
+		info->subslice_per_slice++;
+		eu_dis = fuse & (CHV_FGT_EU_DIS_SS1_R0_MASK |
+				 CHV_FGT_EU_DIS_SS1_R1_MASK);
+		info->eu_total += 8 - hweight32(eu_dis);
+	}
+
+	info->subslice_total = info->subslice_per_slice;
+	/*
+	 * CHV expected to always have a uniform distribution of EU
+	 * across subslices.
+	*/
+	info->eu_per_subslice = info->subslice_total ?
+				info->eu_total / info->subslice_total :
+				0;
+	/*
+	 * CHV supports subslice power gating on devices with more than
+	 * one subslice, and supports EU power gating on devices with
+	 * more than one EU pair per subslice.
+	*/
+	info->has_slice_pg = 0;
+	info->has_subslice_pg = (info->subslice_total > 1);
+	info->has_eu_pg = (info->eu_per_subslice > 2);
+}
+
+static void gen9_sseu_info_init(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_device_info *info;
+	int s_max = 3, ss_max = 4, eu_max = 8;
+	int s, ss;
+	u32 fuse2, s_enable, ss_disable, eu_disable;
+	u8 eu_mask = 0xff;
+
+	info = (struct intel_device_info *)&dev_priv->info;
+	fuse2 = I915_READ(GEN8_FUSE2);
+	s_enable = (fuse2 & GEN8_F2_S_ENA_MASK) >>
+		   GEN8_F2_S_ENA_SHIFT;
+	ss_disable = (fuse2 & GEN9_F2_SS_DIS_MASK) >>
+		     GEN9_F2_SS_DIS_SHIFT;
+
+	info->slice_total = hweight32(s_enable);
+	/*
+	 * The subslice disable field is global, i.e. it applies
+	 * to each of the enabled slices.
+	*/
+	info->subslice_per_slice = ss_max - hweight32(ss_disable);
+	info->subslice_total = info->slice_total *
+			       info->subslice_per_slice;
+
+	/*
+	 * Iterate through enabled slices and subslices to
+	 * count the total enabled EU.
+	*/
+	for (s = 0; s < s_max; s++) {
+		if (!(s_enable & (0x1 << s)))
+			/* skip disabled slice */
+			continue;
+
+		eu_disable = I915_READ(GEN9_EU_DISABLE(s));
+		for (ss = 0; ss < ss_max; ss++) {
+			int eu_per_ss;
+
+			if (ss_disable & (0x1 << ss))
+				/* skip disabled subslice */
+				continue;
+
+			eu_per_ss = eu_max - hweight8((eu_disable >> (ss*8)) &
+						      eu_mask);
+
+			/*
+			 * Record which subslice(s) has(have) 7 EUs. we
+			 * can tune the hash used to spread work among
+			 * subslices if they are unbalanced.
+			 */
+			if (eu_per_ss == 7)
+				info->subslice_7eu[s] |= 1 << ss;
+
+			info->eu_total += eu_per_ss;
+		}
+	}
+
+	/*
+	 * SKL is expected to always have a uniform distribution
+	 * of EU across subslices with the exception that any one
+	 * EU in any one subslice may be fused off for die
+	 * recovery. BXT is expected to be perfectly uniform in EU
+	 * distribution.
+	*/
+	info->eu_per_subslice = info->subslice_total ?
+				DIV_ROUND_UP(info->eu_total,
+					     info->subslice_total) : 0;
+	/*
+	 * SKL supports slice power gating on devices with more than
+	 * one slice, and supports EU power gating on devices with
+	 * more than one EU pair per subslice. BXT supports subslice
+	 * power gating on devices with more than one subslice, and
+	 * supports EU power gating on devices with more than one EU
+	 * pair per subslice.
+	*/
+	info->has_slice_pg = ((IS_SKYLAKE(dev) || IS_KABYLAKE(dev)) &&
+			       (info->slice_total > 1));
+	info->has_subslice_pg = (IS_BROXTON(dev) && (info->subslice_total > 1));
+	info->has_eu_pg = (info->eu_per_subslice > 2);
+}
+
+static void broadwell_sseu_info_init(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_device_info *info;
+	const int s_max = 3, ss_max = 3, eu_max = 8;
+	int s, ss;
+	u32 fuse2, eu_disable[s_max], s_enable, ss_disable;
+
+	fuse2 = I915_READ(GEN8_FUSE2);
+	s_enable = (fuse2 & GEN8_F2_S_ENA_MASK) >> GEN8_F2_S_ENA_SHIFT;
+	ss_disable = (fuse2 & GEN8_F2_SS_DIS_MASK) >> GEN8_F2_SS_DIS_SHIFT;
+
+	eu_disable[0] = I915_READ(GEN8_EU_DISABLE0) & GEN8_EU_DIS0_S0_MASK;
+	eu_disable[1] = (I915_READ(GEN8_EU_DISABLE0) >> GEN8_EU_DIS0_S1_SHIFT) |
+			((I915_READ(GEN8_EU_DISABLE1) & GEN8_EU_DIS1_S1_MASK) <<
+			 (32 - GEN8_EU_DIS0_S1_SHIFT));
+	eu_disable[2] = (I915_READ(GEN8_EU_DISABLE1) >> GEN8_EU_DIS1_S2_SHIFT) |
+			((I915_READ(GEN8_EU_DISABLE2) & GEN8_EU_DIS2_S2_MASK) <<
+			 (32 - GEN8_EU_DIS1_S2_SHIFT));
+
+
+	info = (struct intel_device_info *)&dev_priv->info;
+	info->slice_total = hweight32(s_enable);
+
+	/*
+	 * The subslice disable field is global, i.e. it applies
+	 * to each of the enabled slices.
+	 */
+	info->subslice_per_slice = ss_max - hweight32(ss_disable);
+	info->subslice_total = info->slice_total * info->subslice_per_slice;
+
+	/*
+	 * Iterate through enabled slices and subslices to
+	 * count the total enabled EU.
+	 */
+	for (s = 0; s < s_max; s++) {
+		if (!(s_enable & (0x1 << s)))
+			/* skip disabled slice */
+			continue;
+
+		for (ss = 0; ss < ss_max; ss++) {
+			u32 n_disabled;
+
+			if (ss_disable & (0x1 << ss))
+				/* skip disabled subslice */
+				continue;
+
+			n_disabled = hweight8(eu_disable[s] >> (ss * eu_max));
+
+			/*
+			 * Record which subslices have 7 EUs.
+			 */
+			if (eu_max - n_disabled == 7)
+				info->subslice_7eu[s] |= 1 << ss;
+
+			info->eu_total += eu_max - n_disabled;
+		}
+	}
+
+	/*
+	 * BDW is expected to always have a uniform distribution of EU across
+	 * subslices with the exception that any one EU in any one subslice may
+	 * be fused off for die recovery.
+	 */
+	info->eu_per_subslice = info->subslice_total ?
+		DIV_ROUND_UP(info->eu_total, info->subslice_total) : 0;
+
+	/*
+	 * BDW supports slice power gating on devices with more than
+	 * one slice.
+	 */
+	info->has_slice_pg = (info->slice_total > 1);
+	info->has_subslice_pg = 0;
+	info->has_eu_pg = 0;
+}
+
+/*
+ * Determine various intel_device_info fields at runtime.
+ *
+ * Use it when either:
+ *   - it's judged too laborious to fill n static structures with the limit
+ *     when a simple if statement does the job,
+ *   - run-time checks (eg read fuse/strap registers) are needed.
+ *
+ * This function needs to be called:
+ *   - after the MMIO has been setup as we are reading registers,
+ *   - after the PCH has been detected,
+ *   - before the first usage of the fields it can tweak.
+ */
+static void intel_device_info_runtime_init(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_device_info *info;
+	enum pipe pipe;
+
+	info = (struct intel_device_info *)&dev_priv->info;
+
+	/*
+	 * Skylake and Broxton currently don't expose the topmost plane as its
+	 * use is exclusive with the legacy cursor and we only want to expose
+	 * one of those, not both. Until we can safely expose the topmost plane
+	 * as a DRM_PLANE_TYPE_CURSOR with all the features exposed/supported,
+	 * we don't expose the topmost plane at all to prevent ABI breakage
+	 * down the line.
+	 */
+	if (IS_BROXTON(dev)) {
+		info->num_sprites[PIPE_A] = 2;
+		info->num_sprites[PIPE_B] = 2;
+		info->num_sprites[PIPE_C] = 1;
+	} else if (IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev))
+		for_each_pipe(dev_priv, pipe)
+			info->num_sprites[pipe] = 2;
+	else
+		for_each_pipe(dev_priv, pipe)
+			info->num_sprites[pipe] = 1;
+
+	if (i915.disable_display) {
+		DRM_INFO("Display disabled (module parameter)\n");
+		info->num_pipes = 0;
+	} else if (info->num_pipes > 0 &&
+		   (INTEL_INFO(dev)->gen == 7 || INTEL_INFO(dev)->gen == 8) &&
+		   HAS_PCH_SPLIT(dev)) {
+		u32 fuse_strap = I915_READ(FUSE_STRAP);
+		u32 sfuse_strap = I915_READ(SFUSE_STRAP);
+
+		/*
+		 * SFUSE_STRAP is supposed to have a bit signalling the display
+		 * is fused off. Unfortunately it seems that, at least in
+		 * certain cases, fused off display means that PCH display
+		 * reads don't land anywhere. In that case, we read 0s.
+		 *
+		 * On CPT/PPT, we can detect this case as SFUSE_STRAP_FUSE_LOCK
+		 * should be set when taking over after the firmware.
+		 */
+		if (fuse_strap & ILK_INTERNAL_DISPLAY_DISABLE ||
+		    sfuse_strap & SFUSE_STRAP_DISPLAY_DISABLED ||
+		    (dev_priv->pch_type == PCH_CPT &&
+		     !(sfuse_strap & SFUSE_STRAP_FUSE_LOCK))) {
+			DRM_INFO("Display fused off, disabling\n");
+			info->num_pipes = 0;
+		} else if (fuse_strap & IVB_PIPE_C_DISABLE) {
+			DRM_INFO("PipeC fused off\n");
+			info->num_pipes -= 1;
+		}
+	} else if (info->num_pipes > 0 && INTEL_INFO(dev)->gen == 9) {
+		u32 dfsm = I915_READ(SKL_DFSM);
+		u8 disabled_mask = 0;
+		bool invalid;
+		int num_bits;
+
+		if (dfsm & SKL_DFSM_PIPE_A_DISABLE)
+			disabled_mask |= BIT(PIPE_A);
+		if (dfsm & SKL_DFSM_PIPE_B_DISABLE)
+			disabled_mask |= BIT(PIPE_B);
+		if (dfsm & SKL_DFSM_PIPE_C_DISABLE)
+			disabled_mask |= BIT(PIPE_C);
+
+		num_bits = hweight8(disabled_mask);
+
+		switch (disabled_mask) {
+		case BIT(PIPE_A):
+		case BIT(PIPE_B):
+		case BIT(PIPE_A) | BIT(PIPE_B):
+		case BIT(PIPE_A) | BIT(PIPE_C):
+			invalid = true;
+			break;
+		default:
+			invalid = false;
+		}
+
+		if (num_bits > info->num_pipes || invalid)
+			DRM_ERROR("invalid pipe fuse configuration: 0x%x\n",
+				  disabled_mask);
+		else
+			info->num_pipes -= num_bits;
+	}
+
+	/* Initialize slice/subslice/EU info */
+	if (IS_CHERRYVIEW(dev))
+		cherryview_sseu_info_init(dev);
+	else if (IS_BROADWELL(dev))
+		broadwell_sseu_info_init(dev);
+	else if (INTEL_INFO(dev)->gen >= 9)
+		gen9_sseu_info_init(dev);
+
+	/* Snooping is broken on BXT A stepping. */
+	info->has_snoop = !info->has_llc;
+	info->has_snoop &= !IS_BXT_REVID(dev, 0, BXT_REVID_A1);
+
+	DRM_DEBUG_DRIVER("slice total: %u\n", info->slice_total);
+	DRM_DEBUG_DRIVER("subslice total: %u\n", info->subslice_total);
+	DRM_DEBUG_DRIVER("subslice per slice: %u\n", info->subslice_per_slice);
+	DRM_DEBUG_DRIVER("EU total: %u\n", info->eu_total);
+	DRM_DEBUG_DRIVER("EU per subslice: %u\n", info->eu_per_subslice);
+	DRM_DEBUG_DRIVER("has slice power gating: %s\n",
+			 info->has_slice_pg ? "y" : "n");
+	DRM_DEBUG_DRIVER("has subslice power gating: %s\n",
+			 info->has_subslice_pg ? "y" : "n");
+	DRM_DEBUG_DRIVER("has EU power gating: %s\n",
+			 info->has_eu_pg ? "y" : "n");
+}
+
+static void intel_init_dpio(struct drm_i915_private *dev_priv)
+{
+	/*
+	 * IOSF_PORT_DPIO is used for VLV x2 PHY (DP/HDMI B and C),
+	 * CHV x1 PHY (DP/HDMI D)
+	 * IOSF_PORT_DPIO_2 is used for CHV x2 PHY (DP/HDMI B and C)
+	 */
+	if (IS_CHERRYVIEW(dev_priv)) {
+		DPIO_PHY_IOSF_PORT(DPIO_PHY0) = IOSF_PORT_DPIO_2;
+		DPIO_PHY_IOSF_PORT(DPIO_PHY1) = IOSF_PORT_DPIO;
+	} else if (IS_VALLEYVIEW(dev_priv)) {
+		DPIO_PHY_IOSF_PORT(DPIO_PHY0) = IOSF_PORT_DPIO;
+	}
+}
+
+static int i915_workqueues_init(struct drm_i915_private *dev_priv)
+{
+	/*
+	 * The i915 workqueue is primarily used for batched retirement of
+	 * requests (and thus managing bo) once the task has been completed
+	 * by the GPU. i915_gem_retire_requests() is called directly when we
+	 * need high-priority retirement, such as waiting for an explicit
+	 * bo.
+	 *
+	 * It is also used for periodic low-priority events, such as
+	 * idle-timers and recording error state.
+	 *
+	 * All tasks on the workqueue are expected to acquire the dev mutex
+	 * so there is no point in running more than one instance of the
+	 * workqueue at any time.  Use an ordered one.
+	 */
+	dev_priv->wq = alloc_ordered_workqueue("i915", 0);
+	if (dev_priv->wq == NULL)
+		goto out_err;
+
+	dev_priv->hotplug.dp_wq = alloc_ordered_workqueue("i915-dp", 0);
+	if (dev_priv->hotplug.dp_wq == NULL)
+		goto out_free_wq;
+
+	dev_priv->gpu_error.hangcheck_wq =
+		alloc_ordered_workqueue("i915-hangcheck", 0);
+	if (dev_priv->gpu_error.hangcheck_wq == NULL)
+		goto out_free_dp_wq;
+
+	return 0;
+
+out_free_dp_wq:
+	destroy_workqueue(dev_priv->hotplug.dp_wq);
+out_free_wq:
+	destroy_workqueue(dev_priv->wq);
+out_err:
+	DRM_ERROR("Failed to allocate workqueues.\n");
+
+	return -ENOMEM;
+}
+
+static void i915_workqueues_cleanup(struct drm_i915_private *dev_priv)
+{
+	destroy_workqueue(dev_priv->gpu_error.hangcheck_wq);
+	destroy_workqueue(dev_priv->hotplug.dp_wq);
+	destroy_workqueue(dev_priv->wq);
+}
+
+/**
+ * i915_driver_init_early - setup state not requiring device access
+ * @dev_priv: device private
+ *
+ * Initialize everything that is a "SW-only" state, that is state not
+ * requiring accessing the device or exposing the driver via kernel internal
+ * or userspace interfaces. Example steps belonging here: lock initialization,
+ * system memory allocation, setting up device specific attributes and
+ * function hooks not requiring accessing the device.
+ */
+static int i915_driver_init_early(struct drm_i915_private *dev_priv,
+				  struct drm_device *dev,
+				  struct intel_device_info *info)
+{
+	struct intel_device_info *device_info;
+	int ret = 0;
+
+	if (i915_inject_load_failure())
+		return -ENODEV;
+
+	/* Setup the write-once "constant" device info */
+	device_info = (struct intel_device_info *)&dev_priv->info;
+	memcpy(device_info, info, sizeof(dev_priv->info));
+	device_info->device_id = dev->pdev->device;
+
+	spin_lock_init(&dev_priv->irq_lock);
+	spin_lock_init(&dev_priv->gpu_error.lock);
+	mutex_init(&dev_priv->backlight_lock);
+	spin_lock_init(&dev_priv->uncore.lock);
+	spin_lock_init(&dev_priv->mm.object_stat_lock);
+	spin_lock_init(&dev_priv->mmio_flip_lock);
+	mutex_init(&dev_priv->sb_lock);
+	mutex_init(&dev_priv->modeset_restore_lock);
+	mutex_init(&dev_priv->av_mutex);
+	mutex_init(&dev_priv->wm.wm_mutex);
+	mutex_init(&dev_priv->pps_mutex);
+
+	ret = i915_workqueues_init(dev_priv);
+	if (ret < 0)
+		return ret;
+
+	/* This must be called before any calls to HAS_PCH_* */
+	intel_detect_pch(dev);
+
+	intel_pm_setup(dev);
+	intel_init_dpio(dev_priv);
+	intel_power_domains_init(dev_priv);
+	intel_irq_init(dev_priv);
+	intel_init_display_hooks(dev_priv);
+	intel_init_clock_gating_hooks(dev_priv);
+	intel_init_audio_hooks(dev_priv);
+	i915_gem_load_init(dev);
+
+	intel_display_crc_init(dev);
+
+	i915_dump_device_info(dev_priv);
+
+	/* Not all pre-production machines fall into this category, only the
+	 * very first ones. Almost everything should work, except for maybe
+	 * suspend/resume. And we don't implement workarounds that affect only
+	 * pre-production machines. */
+	if (IS_HSW_EARLY_SDV(dev))
+		DRM_INFO("This is an early pre-production Haswell machine. "
+			 "It may not be fully functional.\n");
+
+	return 0;
+}
+
+/**
+ * i915_driver_cleanup_early - cleanup the setup done in i915_driver_init_early()
+ * @dev_priv: device private
+ */
+static void i915_driver_cleanup_early(struct drm_i915_private *dev_priv)
+{
+	i915_gem_load_cleanup(dev_priv->dev);
+	i915_workqueues_cleanup(dev_priv);
+}
+
+static int i915_mmio_setup(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = to_i915(dev);
+	int mmio_bar;
+	int mmio_size;
+
+	mmio_bar = IS_GEN2(dev) ? 1 : 0;
+	/*
+	 * Before gen4, the registers and the GTT are behind different BARs.
+	 * However, from gen4 onwards, the registers and the GTT are shared
+	 * in the same BAR, so we want to restrict this ioremap from
+	 * clobbering the GTT which we want ioremap_wc instead. Fortunately,
+	 * the register BAR remains the same size for all the earlier
+	 * generations up to Ironlake.
+	 */
+	if (INTEL_INFO(dev)->gen < 5)
+		mmio_size = 512 * 1024;
+	else
+		mmio_size = 2 * 1024 * 1024;
+	dev_priv->regs = pci_iomap(dev->pdev, mmio_bar, mmio_size);
+	if (dev_priv->regs == NULL) {
+		DRM_ERROR("failed to map registers\n");
+
+		return -EIO;
+	}
+
+	/* Try to make sure MCHBAR is enabled before poking at it */
+	intel_setup_mchbar(dev);
+
+	return 0;
+}
+
+static void i915_mmio_cleanup(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = to_i915(dev);
+
+	intel_teardown_mchbar(dev);
+	pci_iounmap(dev->pdev, dev_priv->regs);
+}
+
+/**
+ * i915_driver_init_mmio - setup device MMIO
+ * @dev_priv: device private
+ *
+ * Setup minimal device state necessary for MMIO accesses later in the
+ * initialization sequence. The setup here should avoid any other device-wide
+ * side effects or exposing the driver via kernel internal or user space
+ * interfaces.
+ */
+static int i915_driver_init_mmio(struct drm_i915_private *dev_priv)
+{
+	struct drm_device *dev = dev_priv->dev;
+	int ret;
+
+	if (i915_inject_load_failure())
+		return -ENODEV;
+
+	if (i915_get_bridge_dev(dev))
+		return -EIO;
+
+	ret = i915_mmio_setup(dev);
+	if (ret < 0)
+		goto put_bridge;
+
+	intel_uncore_init(dev);
+
+	return 0;
+
+put_bridge:
+	pci_dev_put(dev_priv->bridge_dev);
+
+	return ret;
+}
+
+/**
+ * i915_driver_cleanup_mmio - cleanup the setup done in i915_driver_init_mmio()
+ * @dev_priv: device private
+ */
+static void i915_driver_cleanup_mmio(struct drm_i915_private *dev_priv)
+{
+	struct drm_device *dev = dev_priv->dev;
+
+	intel_uncore_fini(dev);
+	i915_mmio_cleanup(dev);
+	pci_dev_put(dev_priv->bridge_dev);
+}
+
+/**
+ * i915_driver_init_hw - setup state requiring device access
+ * @dev_priv: device private
+ *
+ * Setup state that requires accessing the device, but doesn't require
+ * exposing the driver via kernel internal or userspace interfaces.
+ */
+static int i915_driver_init_hw(struct drm_i915_private *dev_priv)
+{
+	struct drm_device *dev = dev_priv->dev;
+	struct i915_ggtt *ggtt = &dev_priv->ggtt;
+	uint32_t aperture_size;
+	int ret;
+
+	if (i915_inject_load_failure())
+		return -ENODEV;
+
+	intel_device_info_runtime_init(dev);
+
+	ret = i915_ggtt_init_hw(dev);
+	if (ret)
+		return ret;
+
+	ret = i915_ggtt_enable_hw(dev);
+	if (ret) {
+		DRM_ERROR("failed to enable GGTT\n");
+		goto out_ggtt;
+	}
+
+	/* WARNING: Apparently we must kick fbdev drivers before vgacon,
+	 * otherwise the vga fbdev driver falls over. */
+	ret = i915_kick_out_firmware_fb(dev_priv);
+	if (ret) {
+		DRM_ERROR("failed to remove conflicting framebuffer drivers\n");
+		goto out_ggtt;
+	}
+
+	ret = i915_kick_out_vgacon(dev_priv);
+	if (ret) {
+		DRM_ERROR("failed to remove conflicting VGA console\n");
+		goto out_ggtt;
+	}
+
+	pci_set_master(dev->pdev);
+
+	/* overlay on gen2 is broken and can't address above 1G */
+	if (IS_GEN2(dev))
+		dma_set_coherent_mask(&dev->pdev->dev, DMA_BIT_MASK(30));
+
+	/* 965GM sometimes incorrectly writes to hardware status page (HWS)
+	 * using 32bit addressing, overwriting memory if HWS is located
+	 * above 4GB.
+	 *
+	 * The documentation also mentions an issue with undefined
+	 * behaviour if any general state is accessed within a page above 4GB,
+	 * which also needs to be handled carefully.
+	 */
+	if (IS_BROADWATER(dev) || IS_CRESTLINE(dev))
+		dma_set_coherent_mask(&dev->pdev->dev, DMA_BIT_MASK(32));
+
+	aperture_size = ggtt->mappable_end;
+
+	ggtt->mappable =
+		io_mapping_create_wc(ggtt->mappable_base,
+				     aperture_size);
+	if (!ggtt->mappable) {
+		ret = -EIO;
+		goto out_ggtt;
+	}
+
+	ggtt->mtrr = arch_phys_wc_add(ggtt->mappable_base,
+					      aperture_size);
+
+	pm_qos_add_request(&dev_priv->pm_qos, PM_QOS_CPU_DMA_LATENCY,
+			   PM_QOS_DEFAULT_VALUE);
+
+	intel_uncore_sanitize(dev);
+
+	intel_opregion_setup(dev);
+
+	i915_gem_load_init_fences(dev_priv);
+
+	/* On the 945G/GM, the chipset reports the MSI capability on the
+	 * integrated graphics even though the support isn't actually there
+	 * according to the published specs.  It doesn't appear to function
+	 * correctly in testing on 945G.
+	 * This may be a side effect of MSI having been made available for PEG
+	 * and the registers being closely associated.
+	 *
+	 * According to chipset errata, on the 965GM, MSI interrupts may
+	 * be lost or delayed, but we use them anyways to avoid
+	 * stuck interrupts on some machines.
+	 */
+	if (!IS_I945G(dev) && !IS_I945GM(dev)) {
+		if (pci_enable_msi(dev->pdev) < 0)
+			DRM_DEBUG_DRIVER("can't enable MSI");
+	}
+
+	return 0;
+
+out_ggtt:
+	i915_ggtt_cleanup_hw(dev);
+
+	return ret;
+}
+
+/**
+ * i915_driver_cleanup_hw - cleanup the setup done in i915_driver_init_hw()
+ * @dev_priv: device private
+ */
+static void i915_driver_cleanup_hw(struct drm_i915_private *dev_priv)
+{
+	struct drm_device *dev = dev_priv->dev;
+	struct i915_ggtt *ggtt = &dev_priv->ggtt;
+
+	if (dev->pdev->msi_enabled)
+		pci_disable_msi(dev->pdev);
+
+	pm_qos_remove_request(&dev_priv->pm_qos);
+	arch_phys_wc_del(ggtt->mtrr);
+	io_mapping_free(ggtt->mappable);
+	i915_ggtt_cleanup_hw(dev);
+}
+
+/**
+ * i915_driver_register - register the driver with the rest of the system
+ * @dev_priv: device private
+ *
+ * Perform any steps necessary to make the driver available via kernel
+ * internal or userspace interfaces.
+ */
+static void i915_driver_register(struct drm_i915_private *dev_priv)
+{
+	struct drm_device *dev = dev_priv->dev;
+
+	i915_gem_shrinker_init(dev_priv);
+	/*
+	 * Notify a valid surface after modesetting,
+	 * when running inside a VM.
+	 */
+	if (intel_vgpu_active(dev))
+		I915_WRITE(vgtif_reg(display_ready), VGT_DRV_DISPLAY_READY);
+
+	i915_setup_sysfs(dev);
+
+	if (INTEL_INFO(dev_priv)->num_pipes) {
+		/* Must be done after probing outputs */
+		intel_opregion_init(dev);
+		acpi_video_register();
+	}
+
+	if (IS_GEN5(dev_priv))
+		intel_gpu_ips_init(dev_priv);
+
+	i915_audio_component_init(dev_priv);
+}
+
+/**
+ * i915_driver_unregister - cleanup the registration done in i915_driver_regiser()
+ * @dev_priv: device private
+ */
+static void i915_driver_unregister(struct drm_i915_private *dev_priv)
+{
+	i915_audio_component_cleanup(dev_priv);
+	intel_gpu_ips_teardown();
+	acpi_video_unregister();
+	intel_opregion_fini(dev_priv->dev);
+	i915_teardown_sysfs(dev_priv->dev);
+	i915_gem_shrinker_cleanup(dev_priv);
+}
+
+/**
+ * i915_driver_load - setup chip and create an initial config
+ * @dev: DRM device
+ * @flags: startup flags
+ *
+ * The driver load routine has to do several things:
+ *   - drive output discovery via intel_modeset_init()
+ *   - initialize the memory manager
+ *   - allocate initial config memory
+ *   - setup the DRM framebuffer with the allocated memory
+ */
+int i915_driver_load(struct drm_device *dev, unsigned long flags)
+{
+	struct drm_i915_private *dev_priv;
+	int ret = 0;
+
+	dev_priv = kzalloc(sizeof(*dev_priv), GFP_KERNEL);
+	if (dev_priv == NULL)
+		return -ENOMEM;
+
+	dev->dev_private = dev_priv;
+	/* Must be set before calling __i915_printk */
+	dev_priv->dev = dev;
+
+	ret = i915_driver_init_early(dev_priv, dev,
+				     (struct intel_device_info *)flags);
+
+	if (ret < 0)
+		goto out_free_priv;
+
+	intel_runtime_pm_get(dev_priv);
+
+	ret = i915_driver_init_mmio(dev_priv);
+	if (ret < 0)
+		goto out_runtime_pm_put;
+
+	ret = i915_driver_init_hw(dev_priv);
+	if (ret < 0)
+		goto out_cleanup_mmio;
+
+	/*
+	 * TODO: move the vblank init and parts of modeset init steps into one
+	 * of the i915_driver_init_/i915_driver_register functions according
+	 * to the role/effect of the given init step.
+	 */
+	if (INTEL_INFO(dev)->num_pipes) {
+		ret = drm_vblank_init(dev, INTEL_INFO(dev)->num_pipes);
+		if (ret)
+			goto out_cleanup_hw;
+	}
+
+	ret = i915_load_modeset_init(dev);
+	if (ret < 0)
+		goto out_cleanup_vblank;
+
+	i915_driver_register(dev_priv);
+
+	intel_runtime_pm_enable(dev_priv);
+
+	intel_runtime_pm_put(dev_priv);
+
+	return 0;
+
+out_cleanup_vblank:
+	drm_vblank_cleanup(dev);
+out_cleanup_hw:
+	i915_driver_cleanup_hw(dev_priv);
+out_cleanup_mmio:
+	i915_driver_cleanup_mmio(dev_priv);
+out_runtime_pm_put:
+	intel_runtime_pm_put(dev_priv);
+	i915_driver_cleanup_early(dev_priv);
+out_free_priv:
+	i915_load_error(dev_priv, "Device initialization failed (%d)\n", ret);
+
+	kfree(dev_priv);
+
+	return ret;
+}
+
+int i915_driver_unload(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	int ret;
+
+	intel_fbdev_fini(dev);
+
+	ret = i915_gem_suspend(dev);
+	if (ret) {
+		DRM_ERROR("failed to idle hardware: %d\n", ret);
+		return ret;
+	}
+
+	intel_display_power_get(dev_priv, POWER_DOMAIN_INIT);
+
+	i915_driver_unregister(dev_priv);
+
+	drm_vblank_cleanup(dev);
+
+	intel_modeset_cleanup(dev);
+
+	/*
+	 * free the memory space allocated for the child device
+	 * config parsed from VBT
+	 */
+	if (dev_priv->vbt.child_dev && dev_priv->vbt.child_dev_num) {
+		kfree(dev_priv->vbt.child_dev);
+		dev_priv->vbt.child_dev = NULL;
+		dev_priv->vbt.child_dev_num = 0;
+	}
+	kfree(dev_priv->vbt.sdvo_lvds_vbt_mode);
+	dev_priv->vbt.sdvo_lvds_vbt_mode = NULL;
+	kfree(dev_priv->vbt.lfp_lvds_vbt_mode);
+	dev_priv->vbt.lfp_lvds_vbt_mode = NULL;
+
+	vga_switcheroo_unregister_client(dev->pdev);
+	vga_client_register(dev->pdev, NULL, NULL, NULL);
+
+	intel_csr_ucode_fini(dev_priv);
+
+	/* Free error state after interrupts are fully disabled. */
+	cancel_delayed_work_sync(&dev_priv->gpu_error.hangcheck_work);
+	i915_destroy_error_state(dev);
+
+	/* Flush any outstanding unpin_work. */
+	flush_workqueue(dev_priv->wq);
+
+	intel_guc_ucode_fini(dev);
+	mutex_lock(&dev->struct_mutex);
+	i915_gem_cleanup_engines(dev);
+	i915_gem_context_fini(dev);
+	mutex_unlock(&dev->struct_mutex);
+	intel_fbc_cleanup_cfb(dev_priv);
+
+	intel_power_domains_fini(dev_priv);
+
+	i915_driver_cleanup_hw(dev_priv);
+	i915_driver_cleanup_mmio(dev_priv);
+
+	intel_display_power_put(dev_priv, POWER_DOMAIN_INIT);
+
+	i915_driver_cleanup_early(dev_priv);
+	kfree(dev_priv);
+
+	return 0;
+}
+
+int i915_driver_open(struct drm_device *dev, struct drm_file *file)
+{
+	int ret;
+
+	ret = i915_gem_open(dev, file);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+/**
+ * i915_driver_lastclose - clean up after all DRM clients have exited
+ * @dev: DRM device
+ *
+ * Take care of cleaning up after all DRM clients have exited.  In the
+ * mode setting case, we want to restore the kernel's initial mode (just
+ * in case the last client left us in a bad state).
+ *
+ * Additionally, in the non-mode setting case, we'll tear down the GTT
+ * and DMA structures, since the kernel won't be using them, and clea
+ * up any GEM state.
+ */
+void i915_driver_lastclose(struct drm_device *dev)
+{
+	intel_fbdev_restore_mode(dev);
+	vga_switcheroo_process_delayed_switch();
+}
+
+void i915_driver_preclose(struct drm_device *dev, struct drm_file *file)
+{
+	mutex_lock(&dev->struct_mutex);
+	i915_gem_context_close(dev, file);
+	i915_gem_release(dev, file);
+	mutex_unlock(&dev->struct_mutex);
+}
+
+void i915_driver_postclose(struct drm_device *dev, struct drm_file *file)
+{
+	struct drm_i915_file_private *file_priv = file->driver_priv;
+
+	kfree(file_priv);
+}
+
+static int
+i915_gem_reject_pin_ioctl(struct drm_device *dev, void *data,
+			  struct drm_file *file)
+{
+	return -ENODEV;
+}
+
+const struct drm_ioctl_desc i915_ioctls[] = {
+	DRM_IOCTL_DEF_DRV(I915_INIT, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+	DRM_IOCTL_DEF_DRV(I915_FLUSH, drm_noop, DRM_AUTH),
+	DRM_IOCTL_DEF_DRV(I915_FLIP, drm_noop, DRM_AUTH),
+	DRM_IOCTL_DEF_DRV(I915_BATCHBUFFER, drm_noop, DRM_AUTH),
+	DRM_IOCTL_DEF_DRV(I915_IRQ_EMIT, drm_noop, DRM_AUTH),
+	DRM_IOCTL_DEF_DRV(I915_IRQ_WAIT, drm_noop, DRM_AUTH),
+	DRM_IOCTL_DEF_DRV(I915_GETPARAM, i915_getparam, DRM_AUTH|DRM_RENDER_ALLOW),
+	DRM_IOCTL_DEF_DRV(I915_SETPARAM, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+	DRM_IOCTL_DEF_DRV(I915_ALLOC, drm_noop, DRM_AUTH),
+	DRM_IOCTL_DEF_DRV(I915_FREE, drm_noop, DRM_AUTH),
+	DRM_IOCTL_DEF_DRV(I915_INIT_HEAP, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+	DRM_IOCTL_DEF_DRV(I915_CMDBUFFER, drm_noop, DRM_AUTH),
+	DRM_IOCTL_DEF_DRV(I915_DESTROY_HEAP,  drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+	DRM_IOCTL_DEF_DRV(I915_SET_VBLANK_PIPE,  drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+	DRM_IOCTL_DEF_DRV(I915_GET_VBLANK_PIPE,  drm_noop, DRM_AUTH),
+	DRM_IOCTL_DEF_DRV(I915_VBLANK_SWAP, drm_noop, DRM_AUTH),
+	DRM_IOCTL_DEF_DRV(I915_HWS_ADDR, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+	DRM_IOCTL_DEF_DRV(I915_GEM_INIT, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+	DRM_IOCTL_DEF_DRV(I915_GEM_EXECBUFFER, i915_gem_execbuffer, DRM_AUTH),
+	DRM_IOCTL_DEF_DRV(I915_GEM_EXECBUFFER2, i915_gem_execbuffer2, DRM_AUTH|DRM_RENDER_ALLOW),
+	DRM_IOCTL_DEF_DRV(I915_GEM_PIN, i915_gem_reject_pin_ioctl, DRM_AUTH|DRM_ROOT_ONLY),
+	DRM_IOCTL_DEF_DRV(I915_GEM_UNPIN, i915_gem_reject_pin_ioctl, DRM_AUTH|DRM_ROOT_ONLY),
+	DRM_IOCTL_DEF_DRV(I915_GEM_BUSY, i915_gem_busy_ioctl, DRM_AUTH|DRM_RENDER_ALLOW),
+	DRM_IOCTL_DEF_DRV(I915_GEM_SET_CACHING, i915_gem_set_caching_ioctl, DRM_RENDER_ALLOW),
+	DRM_IOCTL_DEF_DRV(I915_GEM_GET_CACHING, i915_gem_get_caching_ioctl, DRM_RENDER_ALLOW),
+	DRM_IOCTL_DEF_DRV(I915_GEM_THROTTLE, i915_gem_throttle_ioctl, DRM_AUTH|DRM_RENDER_ALLOW),
+	DRM_IOCTL_DEF_DRV(I915_GEM_ENTERVT, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+	DRM_IOCTL_DEF_DRV(I915_GEM_LEAVEVT, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+	DRM_IOCTL_DEF_DRV(I915_GEM_CREATE, i915_gem_create_ioctl, DRM_RENDER_ALLOW),
+	DRM_IOCTL_DEF_DRV(I915_GEM_PREAD, i915_gem_pread_ioctl, DRM_RENDER_ALLOW),
+	DRM_IOCTL_DEF_DRV(I915_GEM_PWRITE, i915_gem_pwrite_ioctl, DRM_RENDER_ALLOW),
+	DRM_IOCTL_DEF_DRV(I915_GEM_MMAP, i915_gem_mmap_ioctl, DRM_RENDER_ALLOW),
+	DRM_IOCTL_DEF_DRV(I915_GEM_MMAP_GTT, i915_gem_mmap_gtt_ioctl, DRM_RENDER_ALLOW),
+	DRM_IOCTL_DEF_DRV(I915_GEM_SET_DOMAIN, i915_gem_set_domain_ioctl, DRM_RENDER_ALLOW),
+	DRM_IOCTL_DEF_DRV(I915_GEM_SW_FINISH, i915_gem_sw_finish_ioctl, DRM_RENDER_ALLOW),
+	DRM_IOCTL_DEF_DRV(I915_GEM_SET_TILING, i915_gem_set_tiling, DRM_RENDER_ALLOW),
+	DRM_IOCTL_DEF_DRV(I915_GEM_GET_TILING, i915_gem_get_tiling, DRM_RENDER_ALLOW),
+	DRM_IOCTL_DEF_DRV(I915_GEM_GET_APERTURE, i915_gem_get_aperture_ioctl, DRM_RENDER_ALLOW),
+	DRM_IOCTL_DEF_DRV(I915_GET_PIPE_FROM_CRTC_ID, intel_get_pipe_from_crtc_id, 0),
+	DRM_IOCTL_DEF_DRV(I915_GEM_MADVISE, i915_gem_madvise_ioctl, DRM_RENDER_ALLOW),
+	DRM_IOCTL_DEF_DRV(I915_OVERLAY_PUT_IMAGE, intel_overlay_put_image, DRM_MASTER|DRM_CONTROL_ALLOW),
+	DRM_IOCTL_DEF_DRV(I915_OVERLAY_ATTRS, intel_overlay_attrs, DRM_MASTER|DRM_CONTROL_ALLOW),
+	DRM_IOCTL_DEF_DRV(I915_SET_SPRITE_COLORKEY, intel_sprite_set_colorkey, DRM_MASTER|DRM_CONTROL_ALLOW),
+	DRM_IOCTL_DEF_DRV(I915_GET_SPRITE_COLORKEY, drm_noop, DRM_MASTER|DRM_CONTROL_ALLOW),
+	DRM_IOCTL_DEF_DRV(I915_GEM_WAIT, i915_gem_wait_ioctl, DRM_AUTH|DRM_RENDER_ALLOW),
+	DRM_IOCTL_DEF_DRV(I915_GEM_CONTEXT_CREATE, i915_gem_context_create_ioctl, DRM_RENDER_ALLOW),
+	DRM_IOCTL_DEF_DRV(I915_GEM_CONTEXT_DESTROY, i915_gem_context_destroy_ioctl, DRM_RENDER_ALLOW),
+	DRM_IOCTL_DEF_DRV(I915_REG_READ, i915_reg_read_ioctl, DRM_RENDER_ALLOW),
+	DRM_IOCTL_DEF_DRV(I915_GET_RESET_STATS, i915_get_reset_stats_ioctl, DRM_RENDER_ALLOW),
+	DRM_IOCTL_DEF_DRV(I915_GEM_USERPTR, i915_gem_userptr_ioctl, DRM_RENDER_ALLOW),
+	DRM_IOCTL_DEF_DRV(I915_GEM_CONTEXT_GETPARAM, i915_gem_context_getparam_ioctl, DRM_RENDER_ALLOW),
+	DRM_IOCTL_DEF_DRV(I915_GEM_CONTEXT_SETPARAM, i915_gem_context_setparam_ioctl, DRM_RENDER_ALLOW),
+};
+
+int i915_max_ioctl = ARRAY_SIZE(i915_ioctls);
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/i915/i915_drv.c
@@ -0,0 +1,1765 @@
+/* i915_drv.c -- i830,i845,i855,i865,i915 driver -*- linux-c -*-
+ */
+/*
+ *
+ * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#include <linux/device.h>
+#include <linux/acpi.h>
+#include <drm/drmP.h>
+#include <drm/i915_drm.h>
+#include "i915_drv.h"
+#include "i915_trace.h"
+#include "intel_drv.h"
+
+#include <linux/console.h>
+#include <linux/module.h>
+#include <linux/pm_runtime.h>
+#include <drm/drm_crtc_helper.h>
+
+static struct drm_driver driver;
+
+extern int i915_bpo_enabled;
+
+#define GEN_DEFAULT_PIPEOFFSETS \
+	.pipe_offsets = { PIPE_A_OFFSET, PIPE_B_OFFSET, \
+			  PIPE_C_OFFSET, PIPE_EDP_OFFSET }, \
+	.trans_offsets = { TRANSCODER_A_OFFSET, TRANSCODER_B_OFFSET, \
+			   TRANSCODER_C_OFFSET, TRANSCODER_EDP_OFFSET }, \
+	.palette_offsets = { PALETTE_A_OFFSET, PALETTE_B_OFFSET }
+
+#define GEN_CHV_PIPEOFFSETS \
+	.pipe_offsets = { PIPE_A_OFFSET, PIPE_B_OFFSET, \
+			  CHV_PIPE_C_OFFSET }, \
+	.trans_offsets = { TRANSCODER_A_OFFSET, TRANSCODER_B_OFFSET, \
+			   CHV_TRANSCODER_C_OFFSET, }, \
+	.palette_offsets = { PALETTE_A_OFFSET, PALETTE_B_OFFSET, \
+			     CHV_PALETTE_C_OFFSET }
+
+#define CURSOR_OFFSETS \
+	.cursor_offsets = { CURSOR_A_OFFSET, CURSOR_B_OFFSET, CHV_CURSOR_C_OFFSET }
+
+#define IVB_CURSOR_OFFSETS \
+	.cursor_offsets = { CURSOR_A_OFFSET, IVB_CURSOR_B_OFFSET, IVB_CURSOR_C_OFFSET }
+
+#define BDW_COLORS \
+	.color = { .degamma_lut_size = 512, .gamma_lut_size = 512 }
+#define CHV_COLORS \
+	.color = { .degamma_lut_size = 65, .gamma_lut_size = 257 }
+
+static const struct intel_device_info intel_i830_info = {
+	.gen = 2, .is_mobile = 1, .cursor_needs_physical = 1, .num_pipes = 2,
+	.has_overlay = 1, .overlay_needs_physical = 1,
+	.ring_mask = RENDER_RING,
+	GEN_DEFAULT_PIPEOFFSETS,
+	CURSOR_OFFSETS,
+};
+
+static const struct intel_device_info intel_845g_info = {
+	.gen = 2, .num_pipes = 1,
+	.has_overlay = 1, .overlay_needs_physical = 1,
+	.ring_mask = RENDER_RING,
+	GEN_DEFAULT_PIPEOFFSETS,
+	CURSOR_OFFSETS,
+};
+
+static const struct intel_device_info intel_i85x_info = {
+	.gen = 2, .is_i85x = 1, .is_mobile = 1, .num_pipes = 2,
+	.cursor_needs_physical = 1,
+	.has_overlay = 1, .overlay_needs_physical = 1,
+	.has_fbc = 1,
+	.ring_mask = RENDER_RING,
+	GEN_DEFAULT_PIPEOFFSETS,
+	CURSOR_OFFSETS,
+};
+
+static const struct intel_device_info intel_i865g_info = {
+	.gen = 2, .num_pipes = 1,
+	.has_overlay = 1, .overlay_needs_physical = 1,
+	.ring_mask = RENDER_RING,
+	GEN_DEFAULT_PIPEOFFSETS,
+	CURSOR_OFFSETS,
+};
+
+static const struct intel_device_info intel_i915g_info = {
+	.gen = 3, .is_i915g = 1, .cursor_needs_physical = 1, .num_pipes = 2,
+	.has_overlay = 1, .overlay_needs_physical = 1,
+	.ring_mask = RENDER_RING,
+	GEN_DEFAULT_PIPEOFFSETS,
+	CURSOR_OFFSETS,
+};
+static const struct intel_device_info intel_i915gm_info = {
+	.gen = 3, .is_mobile = 1, .num_pipes = 2,
+	.cursor_needs_physical = 1,
+	.has_overlay = 1, .overlay_needs_physical = 1,
+	.supports_tv = 1,
+	.has_fbc = 1,
+	.ring_mask = RENDER_RING,
+	GEN_DEFAULT_PIPEOFFSETS,
+	CURSOR_OFFSETS,
+};
+static const struct intel_device_info intel_i945g_info = {
+	.gen = 3, .has_hotplug = 1, .cursor_needs_physical = 1, .num_pipes = 2,
+	.has_overlay = 1, .overlay_needs_physical = 1,
+	.ring_mask = RENDER_RING,
+	GEN_DEFAULT_PIPEOFFSETS,
+	CURSOR_OFFSETS,
+};
+static const struct intel_device_info intel_i945gm_info = {
+	.gen = 3, .is_i945gm = 1, .is_mobile = 1, .num_pipes = 2,
+	.has_hotplug = 1, .cursor_needs_physical = 1,
+	.has_overlay = 1, .overlay_needs_physical = 1,
+	.supports_tv = 1,
+	.has_fbc = 1,
+	.ring_mask = RENDER_RING,
+	GEN_DEFAULT_PIPEOFFSETS,
+	CURSOR_OFFSETS,
+};
+
+static const struct intel_device_info intel_i965g_info = {
+	.gen = 4, .is_broadwater = 1, .num_pipes = 2,
+	.has_hotplug = 1,
+	.has_overlay = 1,
+	.ring_mask = RENDER_RING,
+	GEN_DEFAULT_PIPEOFFSETS,
+	CURSOR_OFFSETS,
+};
+
+static const struct intel_device_info intel_i965gm_info = {
+	.gen = 4, .is_crestline = 1, .num_pipes = 2,
+	.is_mobile = 1, .has_fbc = 1, .has_hotplug = 1,
+	.has_overlay = 1,
+	.supports_tv = 1,
+	.ring_mask = RENDER_RING,
+	GEN_DEFAULT_PIPEOFFSETS,
+	CURSOR_OFFSETS,
+};
+
+static const struct intel_device_info intel_g33_info = {
+	.gen = 3, .is_g33 = 1, .num_pipes = 2,
+	.need_gfx_hws = 1, .has_hotplug = 1,
+	.has_overlay = 1,
+	.ring_mask = RENDER_RING,
+	GEN_DEFAULT_PIPEOFFSETS,
+	CURSOR_OFFSETS,
+};
+
+static const struct intel_device_info intel_g45_info = {
+	.gen = 4, .is_g4x = 1, .need_gfx_hws = 1, .num_pipes = 2,
+	.has_pipe_cxsr = 1, .has_hotplug = 1,
+	.ring_mask = RENDER_RING | BSD_RING,
+	GEN_DEFAULT_PIPEOFFSETS,
+	CURSOR_OFFSETS,
+};
+
+static const struct intel_device_info intel_gm45_info = {
+	.gen = 4, .is_g4x = 1, .num_pipes = 2,
+	.is_mobile = 1, .need_gfx_hws = 1, .has_fbc = 1,
+	.has_pipe_cxsr = 1, .has_hotplug = 1,
+	.supports_tv = 1,
+	.ring_mask = RENDER_RING | BSD_RING,
+	GEN_DEFAULT_PIPEOFFSETS,
+	CURSOR_OFFSETS,
+};
+
+static const struct intel_device_info intel_pineview_info = {
+	.gen = 3, .is_g33 = 1, .is_pineview = 1, .is_mobile = 1, .num_pipes = 2,
+	.need_gfx_hws = 1, .has_hotplug = 1,
+	.has_overlay = 1,
+	GEN_DEFAULT_PIPEOFFSETS,
+	CURSOR_OFFSETS,
+};
+
+static const struct intel_device_info intel_ironlake_d_info = {
+	.gen = 5, .num_pipes = 2,
+	.need_gfx_hws = 1, .has_hotplug = 1,
+	.ring_mask = RENDER_RING | BSD_RING,
+	GEN_DEFAULT_PIPEOFFSETS,
+	CURSOR_OFFSETS,
+};
+
+static const struct intel_device_info intel_ironlake_m_info = {
+	.gen = 5, .is_mobile = 1, .num_pipes = 2,
+	.need_gfx_hws = 1, .has_hotplug = 1,
+	.has_fbc = 1,
+	.ring_mask = RENDER_RING | BSD_RING,
+	GEN_DEFAULT_PIPEOFFSETS,
+	CURSOR_OFFSETS,
+};
+
+static const struct intel_device_info intel_sandybridge_d_info = {
+	.gen = 6, .num_pipes = 2,
+	.need_gfx_hws = 1, .has_hotplug = 1,
+	.has_fbc = 1,
+	.ring_mask = RENDER_RING | BSD_RING | BLT_RING,
+	.has_llc = 1,
+	GEN_DEFAULT_PIPEOFFSETS,
+	CURSOR_OFFSETS,
+};
+
+static const struct intel_device_info intel_sandybridge_m_info = {
+	.gen = 6, .is_mobile = 1, .num_pipes = 2,
+	.need_gfx_hws = 1, .has_hotplug = 1,
+	.has_fbc = 1,
+	.ring_mask = RENDER_RING | BSD_RING | BLT_RING,
+	.has_llc = 1,
+	GEN_DEFAULT_PIPEOFFSETS,
+	CURSOR_OFFSETS,
+};
+
+#define GEN7_FEATURES  \
+	.gen = 7, .num_pipes = 3, \
+	.need_gfx_hws = 1, .has_hotplug = 1, \
+	.has_fbc = 1, \
+	.ring_mask = RENDER_RING | BSD_RING | BLT_RING, \
+	.has_llc = 1, \
+	GEN_DEFAULT_PIPEOFFSETS, \
+	IVB_CURSOR_OFFSETS
+
+static const struct intel_device_info intel_ivybridge_d_info = {
+	GEN7_FEATURES,
+	.is_ivybridge = 1,
+};
+
+static const struct intel_device_info intel_ivybridge_m_info = {
+	GEN7_FEATURES,
+	.is_ivybridge = 1,
+	.is_mobile = 1,
+};
+
+static const struct intel_device_info intel_ivybridge_q_info = {
+	GEN7_FEATURES,
+	.is_ivybridge = 1,
+	.num_pipes = 0, /* legal, last one wins */
+};
+
+#define VLV_FEATURES  \
+	.gen = 7, .num_pipes = 2, \
+	.need_gfx_hws = 1, .has_hotplug = 1, \
+	.ring_mask = RENDER_RING | BSD_RING | BLT_RING, \
+	.display_mmio_offset = VLV_DISPLAY_BASE, \
+	GEN_DEFAULT_PIPEOFFSETS, \
+	CURSOR_OFFSETS
+
+static const struct intel_device_info intel_valleyview_m_info = {
+	VLV_FEATURES,
+	.is_valleyview = 1,
+	.is_mobile = 1,
+};
+
+static const struct intel_device_info intel_valleyview_d_info = {
+	VLV_FEATURES,
+	.is_valleyview = 1,
+};
+
+#define HSW_FEATURES  \
+	GEN7_FEATURES, \
+	.ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING, \
+	.has_ddi = 1, \
+	.has_fpga_dbg = 1
+
+static const struct intel_device_info intel_haswell_d_info = {
+	HSW_FEATURES,
+	.is_haswell = 1,
+};
+
+static const struct intel_device_info intel_haswell_m_info = {
+	HSW_FEATURES,
+	.is_haswell = 1,
+	.is_mobile = 1,
+};
+
+#define BDW_FEATURES \
+	HSW_FEATURES, \
+	BDW_COLORS
+
+static const struct intel_device_info intel_broadwell_d_info = {
+	BDW_FEATURES,
+	.gen = 8,
+};
+
+static const struct intel_device_info intel_broadwell_m_info = {
+	BDW_FEATURES,
+	.gen = 8, .is_mobile = 1,
+};
+
+static const struct intel_device_info intel_broadwell_gt3d_info = {
+	BDW_FEATURES,
+	.gen = 8,
+	.ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING | BSD2_RING,
+};
+
+static const struct intel_device_info intel_broadwell_gt3m_info = {
+	BDW_FEATURES,
+	.gen = 8, .is_mobile = 1,
+	.ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING | BSD2_RING,
+};
+
+static const struct intel_device_info intel_cherryview_info = {
+	.gen = 8, .num_pipes = 3,
+	.need_gfx_hws = 1, .has_hotplug = 1,
+	.ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING,
+	.is_cherryview = 1,
+	.display_mmio_offset = VLV_DISPLAY_BASE,
+	GEN_CHV_PIPEOFFSETS,
+	CURSOR_OFFSETS,
+	CHV_COLORS,
+};
+
+static const struct intel_device_info intel_skylake_info = {
+	BDW_FEATURES,
+	.is_skylake = 1,
+	.gen = 9,
+};
+
+static const struct intel_device_info intel_skylake_gt3_info = {
+	BDW_FEATURES,
+	.is_skylake = 1,
+	.gen = 9,
+	.ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING | BSD2_RING,
+};
+
+static const struct intel_device_info intel_broxton_info = {
+	.is_broxton = 1,
+	.gen = 9,
+	.need_gfx_hws = 1, .has_hotplug = 1,
+	.ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING,
+	.num_pipes = 3,
+	.has_ddi = 1,
+	.has_fpga_dbg = 1,
+	.has_fbc = 1,
+	GEN_DEFAULT_PIPEOFFSETS,
+	IVB_CURSOR_OFFSETS,
+	BDW_COLORS,
+};
+
+static const struct intel_device_info intel_kabylake_info = {
+	BDW_FEATURES,
+	.is_kabylake = 1,
+	.gen = 9,
+};
+
+static const struct intel_device_info intel_kabylake_gt3_info = {
+	BDW_FEATURES,
+	.is_kabylake = 1,
+	.gen = 9,
+	.ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING | BSD2_RING,
+};
+
+/*
+ * Make sure any device matches here are from most specific to most
+ * general.  For example, since the Quanta match is based on the subsystem
+ * and subvendor IDs, we need it to come before the more general IVB
+ * PCI ID matches, otherwise we'll use the wrong info struct above.
+ */
+static const struct pci_device_id pciidlist[] = {
+	INTEL_SKL_GT1_IDS(&intel_skylake_info),
+	INTEL_SKL_GT2_IDS(&intel_skylake_info),
+	INTEL_SKL_GT3_IDS(&intel_skylake_gt3_info),
+	INTEL_SKL_GT4_IDS(&intel_skylake_gt3_info),
+	INTEL_BXT_IDS(&intel_broxton_info),
+	INTEL_KBL_GT1_IDS(&intel_kabylake_info),
+	INTEL_KBL_GT2_IDS(&intel_kabylake_info),
+	INTEL_KBL_GT3_IDS(&intel_kabylake_gt3_info),
+	INTEL_KBL_GT4_IDS(&intel_kabylake_gt3_info),
+	{0, 0, 0}
+};
+
+MODULE_DEVICE_TABLE(pci, pciidlist);
+
+static enum intel_pch intel_virt_detect_pch(struct drm_device *dev)
+{
+	enum intel_pch ret = PCH_NOP;
+
+	/*
+	 * In a virtualized passthrough environment we can be in a
+	 * setup where the ISA bridge is not able to be passed through.
+	 * In this case, a south bridge can be emulated and we have to
+	 * make an educated guess as to which PCH is really there.
+	 */
+
+	if (IS_GEN5(dev)) {
+		ret = PCH_IBX;
+		DRM_DEBUG_KMS("Assuming Ibex Peak PCH\n");
+	} else if (IS_GEN6(dev) || IS_IVYBRIDGE(dev)) {
+		ret = PCH_CPT;
+		DRM_DEBUG_KMS("Assuming CouarPoint PCH\n");
+	} else if (IS_HASWELL(dev) || IS_BROADWELL(dev)) {
+		ret = PCH_LPT;
+		DRM_DEBUG_KMS("Assuming LynxPoint PCH\n");
+	} else if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev)) {
+		ret = PCH_SPT;
+		DRM_DEBUG_KMS("Assuming SunrisePoint PCH\n");
+	}
+
+	return ret;
+}
+
+void intel_detect_pch(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct pci_dev *pch = NULL;
+
+	/* In all current cases, num_pipes is equivalent to the PCH_NOP setting
+	 * (which really amounts to a PCH but no South Display).
+	 */
+	if (INTEL_INFO(dev)->num_pipes == 0) {
+		dev_priv->pch_type = PCH_NOP;
+		return;
+	}
+
+	/*
+	 * The reason to probe ISA bridge instead of Dev31:Fun0 is to
+	 * make graphics device passthrough work easy for VMM, that only
+	 * need to expose ISA bridge to let driver know the real hardware
+	 * underneath. This is a requirement from virtualization team.
+	 *
+	 * In some virtualized environments (e.g. XEN), there is irrelevant
+	 * ISA bridge in the system. To work reliably, we should scan trhough
+	 * all the ISA bridge devices and check for the first match, instead
+	 * of only checking the first one.
+	 */
+	while ((pch = pci_get_class(PCI_CLASS_BRIDGE_ISA << 8, pch))) {
+		if (pch->vendor == PCI_VENDOR_ID_INTEL) {
+			unsigned short id = pch->device & INTEL_PCH_DEVICE_ID_MASK;
+			dev_priv->pch_id = id;
+
+			if (id == INTEL_PCH_IBX_DEVICE_ID_TYPE) {
+				dev_priv->pch_type = PCH_IBX;
+				DRM_DEBUG_KMS("Found Ibex Peak PCH\n");
+				WARN_ON(!IS_GEN5(dev));
+			} else if (id == INTEL_PCH_CPT_DEVICE_ID_TYPE) {
+				dev_priv->pch_type = PCH_CPT;
+				DRM_DEBUG_KMS("Found CougarPoint PCH\n");
+				WARN_ON(!(IS_GEN6(dev) || IS_IVYBRIDGE(dev)));
+			} else if (id == INTEL_PCH_PPT_DEVICE_ID_TYPE) {
+				/* PantherPoint is CPT compatible */
+				dev_priv->pch_type = PCH_CPT;
+				DRM_DEBUG_KMS("Found PantherPoint PCH\n");
+				WARN_ON(!(IS_GEN6(dev) || IS_IVYBRIDGE(dev)));
+			} else if (id == INTEL_PCH_LPT_DEVICE_ID_TYPE) {
+				dev_priv->pch_type = PCH_LPT;
+				DRM_DEBUG_KMS("Found LynxPoint PCH\n");
+				WARN_ON(!IS_HASWELL(dev) && !IS_BROADWELL(dev));
+				WARN_ON(IS_HSW_ULT(dev) || IS_BDW_ULT(dev));
+			} else if (id == INTEL_PCH_LPT_LP_DEVICE_ID_TYPE) {
+				dev_priv->pch_type = PCH_LPT;
+				DRM_DEBUG_KMS("Found LynxPoint LP PCH\n");
+				WARN_ON(!IS_HASWELL(dev) && !IS_BROADWELL(dev));
+				WARN_ON(!IS_HSW_ULT(dev) && !IS_BDW_ULT(dev));
+			} else if (id == INTEL_PCH_SPT_DEVICE_ID_TYPE) {
+				dev_priv->pch_type = PCH_SPT;
+				DRM_DEBUG_KMS("Found SunrisePoint PCH\n");
+				WARN_ON(!IS_SKYLAKE(dev) &&
+					!IS_KABYLAKE(dev));
+			} else if (id == INTEL_PCH_SPT_LP_DEVICE_ID_TYPE) {
+				dev_priv->pch_type = PCH_SPT;
+				DRM_DEBUG_KMS("Found SunrisePoint LP PCH\n");
+				WARN_ON(!IS_SKYLAKE(dev) &&
+					!IS_KABYLAKE(dev));
+			} else if (id == INTEL_PCH_KBP_DEVICE_ID_TYPE) {
+				dev_priv->pch_type = PCH_KBP;
+				DRM_DEBUG_KMS("Found KabyPoint PCH\n");
+				WARN_ON(!IS_KABYLAKE(dev));
+			} else if ((id == INTEL_PCH_P2X_DEVICE_ID_TYPE) ||
+				   (id == INTEL_PCH_P3X_DEVICE_ID_TYPE) ||
+				   ((id == INTEL_PCH_QEMU_DEVICE_ID_TYPE) &&
+				    pch->subsystem_vendor == 0x1af4 &&
+				    pch->subsystem_device == 0x1100)) {
+				dev_priv->pch_type = intel_virt_detect_pch(dev);
+			} else
+				continue;
+
+			break;
+		}
+	}
+	if (!pch)
+		DRM_DEBUG_KMS("No PCH found.\n");
+
+	pci_dev_put(pch);
+}
+
+bool i915_semaphore_is_enabled(struct drm_device *dev)
+{
+	if (INTEL_INFO(dev)->gen < 6)
+		return false;
+
+	if (i915.semaphores >= 0)
+		return i915.semaphores;
+
+	/* TODO: make semaphores and Execlists play nicely together */
+	if (i915.enable_execlists)
+		return false;
+
+	/* Until we get further testing... */
+	if (IS_GEN8(dev))
+		return false;
+
+#ifdef CONFIG_INTEL_IOMMU
+	/* Enable semaphores on SNB when IO remapping is off */
+	if (INTEL_INFO(dev)->gen == 6 && intel_iommu_gfx_mapped)
+		return false;
+#endif
+
+	return true;
+}
+
+static void intel_suspend_encoders(struct drm_i915_private *dev_priv)
+{
+	struct drm_device *dev = dev_priv->dev;
+	struct intel_encoder *encoder;
+
+	drm_modeset_lock_all(dev);
+	for_each_intel_encoder(dev, encoder)
+		if (encoder->suspend)
+			encoder->suspend(encoder);
+	drm_modeset_unlock_all(dev);
+}
+
+static int vlv_resume_prepare(struct drm_i915_private *dev_priv,
+			      bool rpm_resume);
+static int vlv_suspend_complete(struct drm_i915_private *dev_priv);
+
+static bool suspend_to_idle(struct drm_i915_private *dev_priv)
+{
+#if IS_ENABLED(CONFIG_ACPI_SLEEP)
+	if (acpi_target_system_state() < ACPI_STATE_S3)
+		return true;
+#endif
+	return false;
+}
+
+static int i915_drm_suspend(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	pci_power_t opregion_target_state;
+	int error;
+
+	/* ignore lid events during suspend */
+	mutex_lock(&dev_priv->modeset_restore_lock);
+	dev_priv->modeset_restore = MODESET_SUSPENDED;
+	mutex_unlock(&dev_priv->modeset_restore_lock);
+
+	disable_rpm_wakeref_asserts(dev_priv);
+
+	/* We do a lot of poking in a lot of registers, make sure they work
+	 * properly. */
+	intel_display_set_init_power(dev_priv, true);
+
+	drm_kms_helper_poll_disable(dev);
+
+	pci_save_state(dev->pdev);
+
+	error = i915_gem_suspend(dev);
+	if (error) {
+		dev_err(&dev->pdev->dev,
+			"GEM idle failed, resume might fail\n");
+		goto out;
+	}
+
+	intel_guc_suspend(dev);
+
+	intel_suspend_gt_powersave(dev);
+
+	intel_display_suspend(dev);
+
+	intel_dp_mst_suspend(dev);
+
+	intel_runtime_pm_disable_interrupts(dev_priv);
+	intel_hpd_cancel_work(dev_priv);
+
+	intel_suspend_encoders(dev_priv);
+
+	intel_suspend_hw(dev);
+
+	i915_gem_suspend_gtt_mappings(dev);
+
+	i915_save_state(dev);
+
+	opregion_target_state = suspend_to_idle(dev_priv) ? PCI_D1 : PCI_D3cold;
+	intel_opregion_notify_adapter(dev, opregion_target_state);
+
+	intel_uncore_forcewake_reset(dev, false);
+	intel_opregion_fini(dev);
+
+	intel_fbdev_set_suspend(dev, FBINFO_STATE_SUSPENDED, true);
+
+	dev_priv->suspend_count++;
+
+	intel_display_set_init_power(dev_priv, false);
+
+	intel_csr_ucode_suspend(dev_priv);
+
+out:
+	enable_rpm_wakeref_asserts(dev_priv);
+
+	return error;
+}
+
+static int i915_drm_suspend_late(struct drm_device *drm_dev, bool hibernation)
+{
+	struct drm_i915_private *dev_priv = drm_dev->dev_private;
+	bool fw_csr;
+	int ret;
+
+	disable_rpm_wakeref_asserts(dev_priv);
+
+	fw_csr = !IS_BROXTON(dev_priv) &&
+		suspend_to_idle(dev_priv) && dev_priv->csr.dmc_payload;
+	/*
+	 * In case of firmware assisted context save/restore don't manually
+	 * deinit the power domains. This also means the CSR/DMC firmware will
+	 * stay active, it will power down any HW resources as required and
+	 * also enable deeper system power states that would be blocked if the
+	 * firmware was inactive.
+	 */
+	if (!fw_csr)
+		intel_power_domains_suspend(dev_priv);
+
+	ret = 0;
+	if (IS_BROXTON(dev_priv))
+		bxt_enable_dc9(dev_priv);
+	else if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv))
+		hsw_enable_pc8(dev_priv);
+	else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
+		ret = vlv_suspend_complete(dev_priv);
+
+	if (ret) {
+		DRM_ERROR("Suspend complete failed: %d\n", ret);
+		if (!fw_csr)
+			intel_power_domains_init_hw(dev_priv, true);
+
+		goto out;
+	}
+
+	pci_disable_device(drm_dev->pdev);
+	/*
+	 * During hibernation on some platforms the BIOS may try to access
+	 * the device even though it's already in D3 and hang the machine. So
+	 * leave the device in D0 on those platforms and hope the BIOS will
+	 * power down the device properly. The issue was seen on multiple old
+	 * GENs with different BIOS vendors, so having an explicit blacklist
+	 * is inpractical; apply the workaround on everything pre GEN6. The
+	 * platforms where the issue was seen:
+	 * Lenovo Thinkpad X301, X61s, X60, T60, X41
+	 * Fujitsu FSC S7110
+	 * Acer Aspire 1830T
+	 */
+	if (!(hibernation && INTEL_INFO(dev_priv)->gen < 6))
+		pci_set_power_state(drm_dev->pdev, PCI_D3hot);
+
+	dev_priv->suspended_to_idle = suspend_to_idle(dev_priv);
+
+out:
+	enable_rpm_wakeref_asserts(dev_priv);
+
+	return ret;
+}
+
+int i915_suspend_switcheroo(struct drm_device *dev, pm_message_t state)
+{
+	int error;
+
+	if (!dev || !dev->dev_private) {
+		DRM_ERROR("dev: %p\n", dev);
+		DRM_ERROR("DRM not initialized, aborting suspend.\n");
+		return -ENODEV;
+	}
+
+	if (WARN_ON_ONCE(state.event != PM_EVENT_SUSPEND &&
+			 state.event != PM_EVENT_FREEZE))
+		return -EINVAL;
+
+	if (dev->switch_power_state == DRM_SWITCH_POWER_OFF)
+		return 0;
+
+	error = i915_drm_suspend(dev);
+	if (error)
+		return error;
+
+	return i915_drm_suspend_late(dev, false);
+}
+
+static int i915_drm_resume(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	int ret;
+
+	disable_rpm_wakeref_asserts(dev_priv);
+
+	ret = i915_ggtt_enable_hw(dev);
+	if (ret)
+		DRM_ERROR("failed to re-enable GGTT\n");
+
+	intel_csr_ucode_resume(dev_priv);
+
+	mutex_lock(&dev->struct_mutex);
+	i915_gem_restore_gtt_mappings(dev);
+	mutex_unlock(&dev->struct_mutex);
+
+	i915_restore_state(dev);
+	intel_opregion_setup(dev);
+
+	intel_init_pch_refclk(dev);
+	drm_mode_config_reset(dev);
+
+	/*
+	 * Interrupts have to be enabled before any batches are run. If not the
+	 * GPU will hang. i915_gem_init_hw() will initiate batches to
+	 * update/restore the context.
+	 *
+	 * Modeset enabling in intel_modeset_init_hw() also needs working
+	 * interrupts.
+	 */
+	intel_runtime_pm_enable_interrupts(dev_priv);
+
+	mutex_lock(&dev->struct_mutex);
+	if (i915_gem_init_hw(dev)) {
+		DRM_ERROR("failed to re-initialize GPU, declaring wedged!\n");
+			atomic_or(I915_WEDGED, &dev_priv->gpu_error.reset_counter);
+	}
+	mutex_unlock(&dev->struct_mutex);
+
+	intel_guc_resume(dev);
+
+	intel_modeset_init_hw(dev);
+
+	spin_lock_irq(&dev_priv->irq_lock);
+	if (dev_priv->display.hpd_irq_setup)
+		dev_priv->display.hpd_irq_setup(dev);
+	spin_unlock_irq(&dev_priv->irq_lock);
+
+	intel_dp_mst_resume(dev);
+
+	intel_display_resume(dev);
+
+	/*
+	 * ... but also need to make sure that hotplug processing
+	 * doesn't cause havoc. Like in the driver load code we don't
+	 * bother with the tiny race here where we might loose hotplug
+	 * notifications.
+	 * */
+	intel_hpd_init(dev_priv);
+	/* Config may have changed between suspend and resume */
+	drm_helper_hpd_irq_event(dev);
+
+	intel_opregion_init(dev);
+
+	intel_fbdev_set_suspend(dev, FBINFO_STATE_RUNNING, false);
+
+	mutex_lock(&dev_priv->modeset_restore_lock);
+	dev_priv->modeset_restore = MODESET_DONE;
+	mutex_unlock(&dev_priv->modeset_restore_lock);
+
+	intel_opregion_notify_adapter(dev, PCI_D0);
+
+	drm_kms_helper_poll_enable(dev);
+
+	enable_rpm_wakeref_asserts(dev_priv);
+
+	return 0;
+}
+
+static int i915_drm_resume_early(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	int ret;
+
+	/*
+	 * We have a resume ordering issue with the snd-hda driver also
+	 * requiring our device to be power up. Due to the lack of a
+	 * parent/child relationship we currently solve this with an early
+	 * resume hook.
+	 *
+	 * FIXME: This should be solved with a special hdmi sink device or
+	 * similar so that power domains can be employed.
+	 */
+
+	/*
+	 * Note that we need to set the power state explicitly, since we
+	 * powered off the device during freeze and the PCI core won't power
+	 * it back up for us during thaw. Powering off the device during
+	 * freeze is not a hard requirement though, and during the
+	 * suspend/resume phases the PCI core makes sure we get here with the
+	 * device powered on. So in case we change our freeze logic and keep
+	 * the device powered we can also remove the following set power state
+	 * call.
+	 */
+	ret = pci_set_power_state(dev->pdev, PCI_D0);
+	if (ret) {
+		DRM_ERROR("failed to set PCI D0 power state (%d)\n", ret);
+		goto out;
+	}
+
+	/*
+	 * Note that pci_enable_device() first enables any parent bridge
+	 * device and only then sets the power state for this device. The
+	 * bridge enabling is a nop though, since bridge devices are resumed
+	 * first. The order of enabling power and enabling the device is
+	 * imposed by the PCI core as described above, so here we preserve the
+	 * same order for the freeze/thaw phases.
+	 *
+	 * TODO: eventually we should remove pci_disable_device() /
+	 * pci_enable_enable_device() from suspend/resume. Due to how they
+	 * depend on the device enable refcount we can't anyway depend on them
+	 * disabling/enabling the device.
+	 */
+	if (pci_enable_device(dev->pdev)) {
+		ret = -EIO;
+		goto out;
+	}
+
+	pci_set_master(dev->pdev);
+
+	disable_rpm_wakeref_asserts(dev_priv);
+
+	if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
+		ret = vlv_resume_prepare(dev_priv, false);
+	if (ret)
+		DRM_ERROR("Resume prepare failed: %d, continuing anyway\n",
+			  ret);
+
+	intel_uncore_early_sanitize(dev, true);
+
+	if (IS_BROXTON(dev)) {
+		if (!dev_priv->suspended_to_idle)
+			gen9_sanitize_dc_state(dev_priv);
+		bxt_disable_dc9(dev_priv);
+	} else if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) {
+		hsw_disable_pc8(dev_priv);
+	}
+
+	intel_uncore_sanitize(dev);
+
+	if (IS_BROXTON(dev_priv) ||
+	    !(dev_priv->suspended_to_idle && dev_priv->csr.dmc_payload))
+		intel_power_domains_init_hw(dev_priv, true);
+
+	enable_rpm_wakeref_asserts(dev_priv);
+
+out:
+	dev_priv->suspended_to_idle = false;
+
+	return ret;
+}
+
+int i915_resume_switcheroo(struct drm_device *dev)
+{
+	int ret;
+
+	if (dev->switch_power_state == DRM_SWITCH_POWER_OFF)
+		return 0;
+
+	ret = i915_drm_resume_early(dev);
+	if (ret)
+		return ret;
+
+	return i915_drm_resume(dev);
+}
+
+/**
+ * i915_reset - reset chip after a hang
+ * @dev: drm device to reset
+ *
+ * Reset the chip.  Useful if a hang is detected. Returns zero on successful
+ * reset or otherwise an error code.
+ *
+ * Procedure is fairly simple:
+ *   - reset the chip using the reset reg
+ *   - re-init context state
+ *   - re-init hardware status page
+ *   - re-init ring buffer
+ *   - re-init interrupt state
+ *   - re-init display
+ */
+int i915_reset(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct i915_gpu_error *error = &dev_priv->gpu_error;
+	unsigned reset_counter;
+	int ret;
+
+	intel_reset_gt_powersave(dev);
+
+	mutex_lock(&dev->struct_mutex);
+
+	/* Clear any previous failed attempts at recovery. Time to try again. */
+	atomic_andnot(I915_WEDGED, &error->reset_counter);
+
+	/* Clear the reset-in-progress flag and increment the reset epoch. */
+	reset_counter = atomic_inc_return(&error->reset_counter);
+	if (WARN_ON(__i915_reset_in_progress(reset_counter))) {
+		ret = -EIO;
+		goto error;
+	}
+
+	i915_gem_reset(dev);
+
+	ret = intel_gpu_reset(dev, ALL_ENGINES);
+
+	/* Also reset the gpu hangman. */
+	if (error->stop_rings != 0) {
+		DRM_INFO("Simulated gpu hang, resetting stop_rings\n");
+		error->stop_rings = 0;
+		if (ret == -ENODEV) {
+			DRM_INFO("Reset not implemented, but ignoring "
+				 "error for simulated gpu hangs\n");
+			ret = 0;
+		}
+	}
+
+	if (i915_stop_ring_allow_warn(dev_priv))
+		pr_notice("drm/i915: Resetting chip after gpu hang\n");
+
+	if (ret) {
+		if (ret != -ENODEV)
+			DRM_ERROR("Failed to reset chip: %i\n", ret);
+		else
+			DRM_DEBUG_DRIVER("GPU reset disabled\n");
+		goto error;
+	}
+
+	intel_overlay_reset(dev_priv);
+
+	/* Ok, now get things going again... */
+
+	/*
+	 * Everything depends on having the GTT running, so we need to start
+	 * there.  Fortunately we don't need to do this unless we reset the
+	 * chip at a PCI level.
+	 *
+	 * Next we need to restore the context, but we don't use those
+	 * yet either...
+	 *
+	 * Ring buffer needs to be re-initialized in the KMS case, or if X
+	 * was running at the time of the reset (i.e. we weren't VT
+	 * switched away).
+	 */
+	ret = i915_gem_init_hw(dev);
+	if (ret) {
+		DRM_ERROR("Failed hw init on reset %d\n", ret);
+		goto error;
+	}
+
+	mutex_unlock(&dev->struct_mutex);
+
+	/*
+	 * rps/rc6 re-init is necessary to restore state lost after the
+	 * reset and the re-install of gt irqs. Skip for ironlake per
+	 * previous concerns that it doesn't respond well to some forms
+	 * of re-init after reset.
+	 */
+	if (INTEL_INFO(dev)->gen > 5)
+		intel_enable_gt_powersave(dev);
+
+	return 0;
+
+error:
+	atomic_or(I915_WEDGED, &error->reset_counter);
+	mutex_unlock(&dev->struct_mutex);
+	return ret;
+}
+
+static int i915_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+{
+	int ret;
+	struct intel_device_info *intel_info =
+		(struct intel_device_info *) ent->driver_data;
+
+	if (IS_PRELIMINARY_HW(intel_info) && !i915.preliminary_hw_support) {
+		DRM_INFO("This hardware requires preliminary hardware support.\n"
+			 "See CONFIG_DRM_I915_PRELIMINARY_HW_SUPPORT, and/or modparam preliminary_hw_support\n");
+		return -ENODEV;
+	}
+
+	/* Only bind to function 0 of the device. Early generations
+	 * used function 1 as a placeholder for multi-head. This causes
+	 * us confusion instead, especially on the systems where both
+	 * functions have the same PCI-ID!
+	 */
+	if (PCI_FUNC(pdev->devfn))
+		return -ENODEV;
+
+	ret = drm_get_pci_dev(pdev, ent, &driver);
+
+	if (!ret)
+		i915_bpo_enabled = 1;
+	return ret;
+}
+
+static void
+i915_pci_remove(struct pci_dev *pdev)
+{
+	struct drm_device *dev = pci_get_drvdata(pdev);
+
+	drm_put_dev(dev);
+}
+
+static int i915_pm_suspend(struct device *dev)
+{
+	struct pci_dev *pdev = to_pci_dev(dev);
+	struct drm_device *drm_dev = pci_get_drvdata(pdev);
+
+	if (!drm_dev || !drm_dev->dev_private) {
+		dev_err(dev, "DRM not initialized, aborting suspend.\n");
+		return -ENODEV;
+	}
+
+	if (drm_dev->switch_power_state == DRM_SWITCH_POWER_OFF)
+		return 0;
+
+	return i915_drm_suspend(drm_dev);
+}
+
+static int i915_pm_suspend_late(struct device *dev)
+{
+	struct drm_device *drm_dev = dev_to_i915(dev)->dev;
+
+	/*
+	 * We have a suspend ordering issue with the snd-hda driver also
+	 * requiring our device to be power up. Due to the lack of a
+	 * parent/child relationship we currently solve this with an late
+	 * suspend hook.
+	 *
+	 * FIXME: This should be solved with a special hdmi sink device or
+	 * similar so that power domains can be employed.
+	 */
+	if (drm_dev->switch_power_state == DRM_SWITCH_POWER_OFF)
+		return 0;
+
+	return i915_drm_suspend_late(drm_dev, false);
+}
+
+static int i915_pm_poweroff_late(struct device *dev)
+{
+	struct drm_device *drm_dev = dev_to_i915(dev)->dev;
+
+	if (drm_dev->switch_power_state == DRM_SWITCH_POWER_OFF)
+		return 0;
+
+	return i915_drm_suspend_late(drm_dev, true);
+}
+
+static int i915_pm_resume_early(struct device *dev)
+{
+	struct drm_device *drm_dev = dev_to_i915(dev)->dev;
+
+	if (drm_dev->switch_power_state == DRM_SWITCH_POWER_OFF)
+		return 0;
+
+	return i915_drm_resume_early(drm_dev);
+}
+
+static int i915_pm_resume(struct device *dev)
+{
+	struct drm_device *drm_dev = dev_to_i915(dev)->dev;
+
+	if (drm_dev->switch_power_state == DRM_SWITCH_POWER_OFF)
+		return 0;
+
+	return i915_drm_resume(drm_dev);
+}
+
+/*
+ * Save all Gunit registers that may be lost after a D3 and a subsequent
+ * S0i[R123] transition. The list of registers needing a save/restore is
+ * defined in the VLV2_S0IXRegs document. This documents marks all Gunit
+ * registers in the following way:
+ * - Driver: saved/restored by the driver
+ * - Punit : saved/restored by the Punit firmware
+ * - No, w/o marking: no need to save/restore, since the register is R/O or
+ *                    used internally by the HW in a way that doesn't depend
+ *                    keeping the content across a suspend/resume.
+ * - Debug : used for debugging
+ *
+ * We save/restore all registers marked with 'Driver', with the following
+ * exceptions:
+ * - Registers out of use, including also registers marked with 'Debug'.
+ *   These have no effect on the driver's operation, so we don't save/restore
+ *   them to reduce the overhead.
+ * - Registers that are fully setup by an initialization function called from
+ *   the resume path. For example many clock gating and RPS/RC6 registers.
+ * - Registers that provide the right functionality with their reset defaults.
+ *
+ * TODO: Except for registers that based on the above 3 criteria can be safely
+ * ignored, we save/restore all others, practically treating the HW context as
+ * a black-box for the driver. Further investigation is needed to reduce the
+ * saved/restored registers even further, by following the same 3 criteria.
+ */
+static void vlv_save_gunit_s0ix_state(struct drm_i915_private *dev_priv)
+{
+	struct vlv_s0ix_state *s = &dev_priv->vlv_s0ix_state;
+	int i;
+
+	/* GAM 0x4000-0x4770 */
+	s->wr_watermark		= I915_READ(GEN7_WR_WATERMARK);
+	s->gfx_prio_ctrl	= I915_READ(GEN7_GFX_PRIO_CTRL);
+	s->arb_mode		= I915_READ(ARB_MODE);
+	s->gfx_pend_tlb0	= I915_READ(GEN7_GFX_PEND_TLB0);
+	s->gfx_pend_tlb1	= I915_READ(GEN7_GFX_PEND_TLB1);
+
+	for (i = 0; i < ARRAY_SIZE(s->lra_limits); i++)
+		s->lra_limits[i] = I915_READ(GEN7_LRA_LIMITS(i));
+
+	s->media_max_req_count	= I915_READ(GEN7_MEDIA_MAX_REQ_COUNT);
+	s->gfx_max_req_count	= I915_READ(GEN7_GFX_MAX_REQ_COUNT);
+
+	s->render_hwsp		= I915_READ(RENDER_HWS_PGA_GEN7);
+	s->ecochk		= I915_READ(GAM_ECOCHK);
+	s->bsd_hwsp		= I915_READ(BSD_HWS_PGA_GEN7);
+	s->blt_hwsp		= I915_READ(BLT_HWS_PGA_GEN7);
+
+	s->tlb_rd_addr		= I915_READ(GEN7_TLB_RD_ADDR);
+
+	/* MBC 0x9024-0x91D0, 0x8500 */
+	s->g3dctl		= I915_READ(VLV_G3DCTL);
+	s->gsckgctl		= I915_READ(VLV_GSCKGCTL);
+	s->mbctl		= I915_READ(GEN6_MBCTL);
+
+	/* GCP 0x9400-0x9424, 0x8100-0x810C */
+	s->ucgctl1		= I915_READ(GEN6_UCGCTL1);
+	s->ucgctl3		= I915_READ(GEN6_UCGCTL3);
+	s->rcgctl1		= I915_READ(GEN6_RCGCTL1);
+	s->rcgctl2		= I915_READ(GEN6_RCGCTL2);
+	s->rstctl		= I915_READ(GEN6_RSTCTL);
+	s->misccpctl		= I915_READ(GEN7_MISCCPCTL);
+
+	/* GPM 0xA000-0xAA84, 0x8000-0x80FC */
+	s->gfxpause		= I915_READ(GEN6_GFXPAUSE);
+	s->rpdeuhwtc		= I915_READ(GEN6_RPDEUHWTC);
+	s->rpdeuc		= I915_READ(GEN6_RPDEUC);
+	s->ecobus		= I915_READ(ECOBUS);
+	s->pwrdwnupctl		= I915_READ(VLV_PWRDWNUPCTL);
+	s->rp_down_timeout	= I915_READ(GEN6_RP_DOWN_TIMEOUT);
+	s->rp_deucsw		= I915_READ(GEN6_RPDEUCSW);
+	s->rcubmabdtmr		= I915_READ(GEN6_RCUBMABDTMR);
+	s->rcedata		= I915_READ(VLV_RCEDATA);
+	s->spare2gh		= I915_READ(VLV_SPAREG2H);
+
+	/* Display CZ domain, 0x4400C-0x4402C, 0x4F000-0x4F11F */
+	s->gt_imr		= I915_READ(GTIMR);
+	s->gt_ier		= I915_READ(GTIER);
+	s->pm_imr		= I915_READ(GEN6_PMIMR);
+	s->pm_ier		= I915_READ(GEN6_PMIER);
+
+	for (i = 0; i < ARRAY_SIZE(s->gt_scratch); i++)
+		s->gt_scratch[i] = I915_READ(GEN7_GT_SCRATCH(i));
+
+	/* GT SA CZ domain, 0x100000-0x138124 */
+	s->tilectl		= I915_READ(TILECTL);
+	s->gt_fifoctl		= I915_READ(GTFIFOCTL);
+	s->gtlc_wake_ctrl	= I915_READ(VLV_GTLC_WAKE_CTRL);
+	s->gtlc_survive		= I915_READ(VLV_GTLC_SURVIVABILITY_REG);
+	s->pmwgicz		= I915_READ(VLV_PMWGICZ);
+
+	/* Gunit-Display CZ domain, 0x182028-0x1821CF */
+	s->gu_ctl0		= I915_READ(VLV_GU_CTL0);
+	s->gu_ctl1		= I915_READ(VLV_GU_CTL1);
+	s->pcbr			= I915_READ(VLV_PCBR);
+	s->clock_gate_dis2	= I915_READ(VLV_GUNIT_CLOCK_GATE2);
+
+	/*
+	 * Not saving any of:
+	 * DFT,		0x9800-0x9EC0
+	 * SARB,	0xB000-0xB1FC
+	 * GAC,		0x5208-0x524C, 0x14000-0x14C000
+	 * PCI CFG
+	 */
+}
+
+static void vlv_restore_gunit_s0ix_state(struct drm_i915_private *dev_priv)
+{
+	struct vlv_s0ix_state *s = &dev_priv->vlv_s0ix_state;
+	u32 val;
+	int i;
+
+	/* GAM 0x4000-0x4770 */
+	I915_WRITE(GEN7_WR_WATERMARK,	s->wr_watermark);
+	I915_WRITE(GEN7_GFX_PRIO_CTRL,	s->gfx_prio_ctrl);
+	I915_WRITE(ARB_MODE,		s->arb_mode | (0xffff << 16));
+	I915_WRITE(GEN7_GFX_PEND_TLB0,	s->gfx_pend_tlb0);
+	I915_WRITE(GEN7_GFX_PEND_TLB1,	s->gfx_pend_tlb1);
+
+	for (i = 0; i < ARRAY_SIZE(s->lra_limits); i++)
+		I915_WRITE(GEN7_LRA_LIMITS(i), s->lra_limits[i]);
+
+	I915_WRITE(GEN7_MEDIA_MAX_REQ_COUNT, s->media_max_req_count);
+	I915_WRITE(GEN7_GFX_MAX_REQ_COUNT, s->gfx_max_req_count);
+
+	I915_WRITE(RENDER_HWS_PGA_GEN7,	s->render_hwsp);
+	I915_WRITE(GAM_ECOCHK,		s->ecochk);
+	I915_WRITE(BSD_HWS_PGA_GEN7,	s->bsd_hwsp);
+	I915_WRITE(BLT_HWS_PGA_GEN7,	s->blt_hwsp);
+
+	I915_WRITE(GEN7_TLB_RD_ADDR,	s->tlb_rd_addr);
+
+	/* MBC 0x9024-0x91D0, 0x8500 */
+	I915_WRITE(VLV_G3DCTL,		s->g3dctl);
+	I915_WRITE(VLV_GSCKGCTL,	s->gsckgctl);
+	I915_WRITE(GEN6_MBCTL,		s->mbctl);
+
+	/* GCP 0x9400-0x9424, 0x8100-0x810C */
+	I915_WRITE(GEN6_UCGCTL1,	s->ucgctl1);
+	I915_WRITE(GEN6_UCGCTL3,	s->ucgctl3);
+	I915_WRITE(GEN6_RCGCTL1,	s->rcgctl1);
+	I915_WRITE(GEN6_RCGCTL2,	s->rcgctl2);
+	I915_WRITE(GEN6_RSTCTL,		s->rstctl);
+	I915_WRITE(GEN7_MISCCPCTL,	s->misccpctl);
+
+	/* GPM 0xA000-0xAA84, 0x8000-0x80FC */
+	I915_WRITE(GEN6_GFXPAUSE,	s->gfxpause);
+	I915_WRITE(GEN6_RPDEUHWTC,	s->rpdeuhwtc);
+	I915_WRITE(GEN6_RPDEUC,		s->rpdeuc);
+	I915_WRITE(ECOBUS,		s->ecobus);
+	I915_WRITE(VLV_PWRDWNUPCTL,	s->pwrdwnupctl);
+	I915_WRITE(GEN6_RP_DOWN_TIMEOUT,s->rp_down_timeout);
+	I915_WRITE(GEN6_RPDEUCSW,	s->rp_deucsw);
+	I915_WRITE(GEN6_RCUBMABDTMR,	s->rcubmabdtmr);
+	I915_WRITE(VLV_RCEDATA,		s->rcedata);
+	I915_WRITE(VLV_SPAREG2H,	s->spare2gh);
+
+	/* Display CZ domain, 0x4400C-0x4402C, 0x4F000-0x4F11F */
+	I915_WRITE(GTIMR,		s->gt_imr);
+	I915_WRITE(GTIER,		s->gt_ier);
+	I915_WRITE(GEN6_PMIMR,		s->pm_imr);
+	I915_WRITE(GEN6_PMIER,		s->pm_ier);
+
+	for (i = 0; i < ARRAY_SIZE(s->gt_scratch); i++)
+		I915_WRITE(GEN7_GT_SCRATCH(i), s->gt_scratch[i]);
+
+	/* GT SA CZ domain, 0x100000-0x138124 */
+	I915_WRITE(TILECTL,			s->tilectl);
+	I915_WRITE(GTFIFOCTL,			s->gt_fifoctl);
+	/*
+	 * Preserve the GT allow wake and GFX force clock bit, they are not
+	 * be restored, as they are used to control the s0ix suspend/resume
+	 * sequence by the caller.
+	 */
+	val = I915_READ(VLV_GTLC_WAKE_CTRL);
+	val &= VLV_GTLC_ALLOWWAKEREQ;
+	val |= s->gtlc_wake_ctrl & ~VLV_GTLC_ALLOWWAKEREQ;
+	I915_WRITE(VLV_GTLC_WAKE_CTRL, val);
+
+	val = I915_READ(VLV_GTLC_SURVIVABILITY_REG);
+	val &= VLV_GFX_CLK_FORCE_ON_BIT;
+	val |= s->gtlc_survive & ~VLV_GFX_CLK_FORCE_ON_BIT;
+	I915_WRITE(VLV_GTLC_SURVIVABILITY_REG, val);
+
+	I915_WRITE(VLV_PMWGICZ,			s->pmwgicz);
+
+	/* Gunit-Display CZ domain, 0x182028-0x1821CF */
+	I915_WRITE(VLV_GU_CTL0,			s->gu_ctl0);
+	I915_WRITE(VLV_GU_CTL1,			s->gu_ctl1);
+	I915_WRITE(VLV_PCBR,			s->pcbr);
+	I915_WRITE(VLV_GUNIT_CLOCK_GATE2,	s->clock_gate_dis2);
+}
+
+int vlv_force_gfx_clock(struct drm_i915_private *dev_priv, bool force_on)
+{
+	u32 val;
+	int err;
+
+#define COND (I915_READ(VLV_GTLC_SURVIVABILITY_REG) & VLV_GFX_CLK_STATUS_BIT)
+
+	val = I915_READ(VLV_GTLC_SURVIVABILITY_REG);
+	val &= ~VLV_GFX_CLK_FORCE_ON_BIT;
+	if (force_on)
+		val |= VLV_GFX_CLK_FORCE_ON_BIT;
+	I915_WRITE(VLV_GTLC_SURVIVABILITY_REG, val);
+
+	if (!force_on)
+		return 0;
+
+	err = wait_for(COND, 20);
+	if (err)
+		DRM_ERROR("timeout waiting for GFX clock force-on (%08x)\n",
+			  I915_READ(VLV_GTLC_SURVIVABILITY_REG));
+
+	return err;
+#undef COND
+}
+
+static int vlv_allow_gt_wake(struct drm_i915_private *dev_priv, bool allow)
+{
+	u32 val;
+	int err = 0;
+
+	val = I915_READ(VLV_GTLC_WAKE_CTRL);
+	val &= ~VLV_GTLC_ALLOWWAKEREQ;
+	if (allow)
+		val |= VLV_GTLC_ALLOWWAKEREQ;
+	I915_WRITE(VLV_GTLC_WAKE_CTRL, val);
+	POSTING_READ(VLV_GTLC_WAKE_CTRL);
+
+#define COND (!!(I915_READ(VLV_GTLC_PW_STATUS) & VLV_GTLC_ALLOWWAKEACK) == \
+	      allow)
+	err = wait_for(COND, 1);
+	if (err)
+		DRM_ERROR("timeout disabling GT waking\n");
+	return err;
+#undef COND
+}
+
+static int vlv_wait_for_gt_wells(struct drm_i915_private *dev_priv,
+				 bool wait_for_on)
+{
+	u32 mask;
+	u32 val;
+	int err;
+
+	mask = VLV_GTLC_PW_MEDIA_STATUS_MASK | VLV_GTLC_PW_RENDER_STATUS_MASK;
+	val = wait_for_on ? mask : 0;
+#define COND ((I915_READ(VLV_GTLC_PW_STATUS) & mask) == val)
+	if (COND)
+		return 0;
+
+	DRM_DEBUG_KMS("waiting for GT wells to go %s (%08x)\n",
+		      onoff(wait_for_on),
+		      I915_READ(VLV_GTLC_PW_STATUS));
+
+	/*
+	 * RC6 transitioning can be delayed up to 2 msec (see
+	 * valleyview_enable_rps), use 3 msec for safety.
+	 */
+	err = wait_for(COND, 3);
+	if (err)
+		DRM_ERROR("timeout waiting for GT wells to go %s\n",
+			  onoff(wait_for_on));
+
+	return err;
+#undef COND
+}
+
+static void vlv_check_no_gt_access(struct drm_i915_private *dev_priv)
+{
+	if (!(I915_READ(VLV_GTLC_PW_STATUS) & VLV_GTLC_ALLOWWAKEERR))
+		return;
+
+	DRM_DEBUG_DRIVER("GT register access while GT waking disabled\n");
+	I915_WRITE(VLV_GTLC_PW_STATUS, VLV_GTLC_ALLOWWAKEERR);
+}
+
+static int vlv_suspend_complete(struct drm_i915_private *dev_priv)
+{
+	u32 mask;
+	int err;
+
+	/*
+	 * Bspec defines the following GT well on flags as debug only, so
+	 * don't treat them as hard failures.
+	 */
+	(void)vlv_wait_for_gt_wells(dev_priv, false);
+
+	mask = VLV_GTLC_RENDER_CTX_EXISTS | VLV_GTLC_MEDIA_CTX_EXISTS;
+	WARN_ON((I915_READ(VLV_GTLC_WAKE_CTRL) & mask) != mask);
+
+	vlv_check_no_gt_access(dev_priv);
+
+	err = vlv_force_gfx_clock(dev_priv, true);
+	if (err)
+		goto err1;
+
+	err = vlv_allow_gt_wake(dev_priv, false);
+	if (err)
+		goto err2;
+
+	if (!IS_CHERRYVIEW(dev_priv))
+		vlv_save_gunit_s0ix_state(dev_priv);
+
+	err = vlv_force_gfx_clock(dev_priv, false);
+	if (err)
+		goto err2;
+
+	return 0;
+
+err2:
+	/* For safety always re-enable waking and disable gfx clock forcing */
+	vlv_allow_gt_wake(dev_priv, true);
+err1:
+	vlv_force_gfx_clock(dev_priv, false);
+
+	return err;
+}
+
+static int vlv_resume_prepare(struct drm_i915_private *dev_priv,
+				bool rpm_resume)
+{
+	struct drm_device *dev = dev_priv->dev;
+	int err;
+	int ret;
+
+	/*
+	 * If any of the steps fail just try to continue, that's the best we
+	 * can do at this point. Return the first error code (which will also
+	 * leave RPM permanently disabled).
+	 */
+	ret = vlv_force_gfx_clock(dev_priv, true);
+
+	if (!IS_CHERRYVIEW(dev_priv))
+		vlv_restore_gunit_s0ix_state(dev_priv);
+
+	err = vlv_allow_gt_wake(dev_priv, true);
+	if (!ret)
+		ret = err;
+
+	err = vlv_force_gfx_clock(dev_priv, false);
+	if (!ret)
+		ret = err;
+
+	vlv_check_no_gt_access(dev_priv);
+
+	if (rpm_resume) {
+		intel_init_clock_gating(dev);
+		i915_gem_restore_fences(dev);
+	}
+
+	return ret;
+}
+
+static int intel_runtime_suspend(struct device *device)
+{
+	struct pci_dev *pdev = to_pci_dev(device);
+	struct drm_device *dev = pci_get_drvdata(pdev);
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	int ret;
+
+	if (WARN_ON_ONCE(!(dev_priv->rps.enabled && intel_enable_rc6(dev))))
+		return -ENODEV;
+
+	if (WARN_ON_ONCE(!HAS_RUNTIME_PM(dev)))
+		return -ENODEV;
+
+	DRM_DEBUG_KMS("Suspending device\n");
+
+	/*
+	 * We could deadlock here in case another thread holding struct_mutex
+	 * calls RPM suspend concurrently, since the RPM suspend will wait
+	 * first for this RPM suspend to finish. In this case the concurrent
+	 * RPM resume will be followed by its RPM suspend counterpart. Still
+	 * for consistency return -EAGAIN, which will reschedule this suspend.
+	 */
+	if (!mutex_trylock(&dev->struct_mutex)) {
+		DRM_DEBUG_KMS("device lock contention, deffering suspend\n");
+		/*
+		 * Bump the expiration timestamp, otherwise the suspend won't
+		 * be rescheduled.
+		 */
+		pm_runtime_mark_last_busy(device);
+
+		return -EAGAIN;
+	}
+
+	disable_rpm_wakeref_asserts(dev_priv);
+
+	/*
+	 * We are safe here against re-faults, since the fault handler takes
+	 * an RPM reference.
+	 */
+	i915_gem_release_all_mmaps(dev_priv);
+	mutex_unlock(&dev->struct_mutex);
+
+	cancel_delayed_work_sync(&dev_priv->gpu_error.hangcheck_work);
+
+	intel_guc_suspend(dev);
+
+	intel_suspend_gt_powersave(dev);
+	intel_runtime_pm_disable_interrupts(dev_priv);
+
+	ret = 0;
+	if (IS_BROXTON(dev_priv)) {
+		bxt_display_core_uninit(dev_priv);
+		bxt_enable_dc9(dev_priv);
+	} else if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) {
+		hsw_enable_pc8(dev_priv);
+	} else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
+		ret = vlv_suspend_complete(dev_priv);
+	}
+
+	if (ret) {
+		DRM_ERROR("Runtime suspend failed, disabling it (%d)\n", ret);
+		intel_runtime_pm_enable_interrupts(dev_priv);
+
+		enable_rpm_wakeref_asserts(dev_priv);
+
+		return ret;
+	}
+
+	intel_uncore_forcewake_reset(dev, false);
+
+	enable_rpm_wakeref_asserts(dev_priv);
+	WARN_ON_ONCE(atomic_read(&dev_priv->pm.wakeref_count));
+
+	if (intel_uncore_arm_unclaimed_mmio_detection(dev_priv))
+		DRM_ERROR("Unclaimed access detected prior to suspending\n");
+
+	dev_priv->pm.suspended = true;
+
+	/*
+	 * FIXME: We really should find a document that references the arguments
+	 * used below!
+	 */
+	if (IS_BROADWELL(dev)) {
+		/*
+		 * On Broadwell, if we use PCI_D1 the PCH DDI ports will stop
+		 * being detected, and the call we do at intel_runtime_resume()
+		 * won't be able to restore them. Since PCI_D3hot matches the
+		 * actual specification and appears to be working, use it.
+		 */
+		intel_opregion_notify_adapter(dev, PCI_D3hot);
+	} else {
+		/*
+		 * current versions of firmware which depend on this opregion
+		 * notification have repurposed the D1 definition to mean
+		 * "runtime suspended" vs. what you would normally expect (D3)
+		 * to distinguish it from notifications that might be sent via
+		 * the suspend path.
+		 */
+		intel_opregion_notify_adapter(dev, PCI_D1);
+	}
+
+	assert_forcewakes_inactive(dev_priv);
+
+	DRM_DEBUG_KMS("Device suspended\n");
+	return 0;
+}
+
+static int intel_runtime_resume(struct device *device)
+{
+	struct pci_dev *pdev = to_pci_dev(device);
+	struct drm_device *dev = pci_get_drvdata(pdev);
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	int ret = 0;
+
+	if (WARN_ON_ONCE(!HAS_RUNTIME_PM(dev)))
+		return -ENODEV;
+
+	DRM_DEBUG_KMS("Resuming device\n");
+
+	WARN_ON_ONCE(atomic_read(&dev_priv->pm.wakeref_count));
+	disable_rpm_wakeref_asserts(dev_priv);
+
+	intel_opregion_notify_adapter(dev, PCI_D0);
+	dev_priv->pm.suspended = false;
+	if (intel_uncore_unclaimed_mmio(dev_priv))
+		DRM_DEBUG_DRIVER("Unclaimed access during suspend, bios?\n");
+
+	intel_guc_resume(dev);
+
+	if (IS_GEN6(dev_priv))
+		intel_init_pch_refclk(dev);
+
+	if (IS_BROXTON(dev)) {
+		bxt_disable_dc9(dev_priv);
+		bxt_display_core_init(dev_priv, true);
+		if (dev_priv->csr.dmc_payload &&
+		    (dev_priv->csr.allowed_dc_mask & DC_STATE_EN_UPTO_DC5))
+			gen9_enable_dc5(dev_priv);
+	} else if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) {
+		hsw_disable_pc8(dev_priv);
+	} else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
+		ret = vlv_resume_prepare(dev_priv, true);
+	}
+
+	/*
+	 * No point of rolling back things in case of an error, as the best
+	 * we can do is to hope that things will still work (and disable RPM).
+	 */
+	i915_gem_init_swizzling(dev);
+	gen6_update_ring_freq(dev);
+
+	intel_runtime_pm_enable_interrupts(dev_priv);
+
+	/*
+	 * On VLV/CHV display interrupts are part of the display
+	 * power well, so hpd is reinitialized from there. For
+	 * everyone else do it here.
+	 */
+	if (!IS_VALLEYVIEW(dev_priv) && !IS_CHERRYVIEW(dev_priv))
+		intel_hpd_init(dev_priv);
+
+	intel_enable_gt_powersave(dev);
+
+	enable_rpm_wakeref_asserts(dev_priv);
+
+	if (ret)
+		DRM_ERROR("Runtime resume failed, disabling it (%d)\n", ret);
+	else
+		DRM_DEBUG_KMS("Device resumed\n");
+
+	return ret;
+}
+
+static const struct dev_pm_ops i915_pm_ops = {
+	/*
+	 * S0ix (via system suspend) and S3 event handlers [PMSG_SUSPEND,
+	 * PMSG_RESUME]
+	 */
+	.suspend = i915_pm_suspend,
+	.suspend_late = i915_pm_suspend_late,
+	.resume_early = i915_pm_resume_early,
+	.resume = i915_pm_resume,
+
+	/*
+	 * S4 event handlers
+	 * @freeze, @freeze_late    : called (1) before creating the
+	 *                            hibernation image [PMSG_FREEZE] and
+	 *                            (2) after rebooting, before restoring
+	 *                            the image [PMSG_QUIESCE]
+	 * @thaw, @thaw_early       : called (1) after creating the hibernation
+	 *                            image, before writing it [PMSG_THAW]
+	 *                            and (2) after failing to create or
+	 *                            restore the image [PMSG_RECOVER]
+	 * @poweroff, @poweroff_late: called after writing the hibernation
+	 *                            image, before rebooting [PMSG_HIBERNATE]
+	 * @restore, @restore_early : called after rebooting and restoring the
+	 *                            hibernation image [PMSG_RESTORE]
+	 */
+	.freeze = i915_pm_suspend,
+	.freeze_late = i915_pm_suspend_late,
+	.thaw_early = i915_pm_resume_early,
+	.thaw = i915_pm_resume,
+	.poweroff = i915_pm_suspend,
+	.poweroff_late = i915_pm_poweroff_late,
+	.restore_early = i915_pm_resume_early,
+	.restore = i915_pm_resume,
+
+	/* S0ix (via runtime suspend) event handlers */
+	.runtime_suspend = intel_runtime_suspend,
+	.runtime_resume = intel_runtime_resume,
+};
+
+static const struct vm_operations_struct i915_gem_vm_ops = {
+	.fault = i915_gem_fault,
+	.open = drm_gem_vm_open,
+	.close = drm_gem_vm_close,
+};
+
+static const struct file_operations i915_driver_fops = {
+	.owner = THIS_MODULE,
+	.open = drm_open,
+	.release = drm_release,
+	.unlocked_ioctl = drm_ioctl,
+	.mmap = drm_gem_mmap,
+	.poll = drm_poll,
+	.read = drm_read,
+#ifdef CONFIG_COMPAT
+	.compat_ioctl = i915_compat_ioctl,
+#endif
+	.llseek = noop_llseek,
+};
+
+static struct drm_driver driver = {
+	/* Don't use MTRRs here; the Xserver or userspace app should
+	 * deal with them for Intel hardware.
+	 */
+	.driver_features =
+	    DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_GEM | DRIVER_PRIME |
+	    DRIVER_RENDER | DRIVER_MODESET,
+	.load = i915_driver_load,
+	.unload = i915_driver_unload,
+	.open = i915_driver_open,
+	.lastclose = i915_driver_lastclose,
+	.preclose = i915_driver_preclose,
+	.postclose = i915_driver_postclose,
+	.set_busid = drm_pci_set_busid,
+
+#if defined(CONFIG_DEBUG_FS)
+	.debugfs_init = i915_debugfs_init,
+	.debugfs_cleanup = i915_debugfs_cleanup,
+#endif
+	.gem_free_object = i915_gem_free_object,
+	.gem_vm_ops = &i915_gem_vm_ops,
+
+	.prime_handle_to_fd = drm_gem_prime_handle_to_fd,
+	.prime_fd_to_handle = drm_gem_prime_fd_to_handle,
+	.gem_prime_export = i915_gem_prime_export,
+	.gem_prime_import = i915_gem_prime_import,
+
+	.dumb_create = i915_gem_dumb_create,
+	.dumb_map_offset = i915_gem_mmap_gtt,
+	.dumb_destroy = drm_gem_dumb_destroy,
+	.ioctls = i915_ioctls,
+	.fops = &i915_driver_fops,
+	.name = DRIVER_NAME,
+	.desc = DRIVER_DESC,
+	.date = DRIVER_DATE,
+	.major = DRIVER_MAJOR,
+	.minor = DRIVER_MINOR,
+	.patchlevel = DRIVER_PATCHLEVEL,
+};
+
+static struct pci_driver i915_pci_driver = {
+	.name = DRIVER_NAME,
+	.id_table = pciidlist,
+	.probe = i915_pci_probe,
+	.remove = i915_pci_remove,
+	.driver.pm = &i915_pm_ops,
+};
+
+static int __init i915_init(void)
+{
+	driver.num_ioctls = i915_max_ioctl;
+
+	/*
+	 * Enable KMS by default, unless explicitly overriden by
+	 * either the i915.modeset prarameter or by the
+	 * vga_text_mode_force boot option.
+	 */
+
+	if (i915.modeset == 0)
+		driver.driver_features &= ~DRIVER_MODESET;
+
+	if (vgacon_text_force() && i915.modeset == -1)
+		driver.driver_features &= ~DRIVER_MODESET;
+
+	if (!(driver.driver_features & DRIVER_MODESET)) {
+		/* Silently fail loading to not upset userspace. */
+		DRM_DEBUG_DRIVER("KMS and UMS disabled.\n");
+		return 0;
+	}
+
+	if (i915.nuclear_pageflip)
+		driver.driver_features |= DRIVER_ATOMIC;
+
+	return drm_pci_init(&driver, &i915_pci_driver);
+}
+
+static void __exit i915_exit(void)
+{
+	if (!(driver.driver_features & DRIVER_MODESET))
+		return; /* Never loaded a driver. */
+
+	drm_pci_exit(&driver, &i915_pci_driver);
+}
+
+module_init(i915_init);
+module_exit(i915_exit);
+
+MODULE_AUTHOR("Tungsten Graphics, Inc.");
+MODULE_AUTHOR("Intel Corporation");
+
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL and additional rights");
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/i915/i915_drv.h
@@ -0,0 +1,3749 @@
+/* i915_drv.h -- Private header for the I915 driver -*- linux-c -*-
+ */
+/*
+ *
+ * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#ifndef _I915_DRV_H_
+#define _I915_DRV_H_
+
+#include <uapi/drm/i915_drm.h>
+#include <uapi/drm/drm_fourcc.h>
+
+#include <linux/io-mapping.h>
+#include <linux/i2c.h>
+#include <linux/i2c-algo-bit.h>
+#include <linux/backlight.h>
+#include <linux/hashtable.h>
+#include <linux/intel-iommu.h>
+#include <linux/kref.h>
+#include <linux/pm_qos.h>
+#include <linux/shmem_fs.h>
+
+#include <drm/drmP.h>
+#include <drm/intel-gtt.h>
+#include <drm/drm_legacy.h> /* for struct drm_dma_handle */
+#include <drm/drm_gem.h>
+
+#include "i915_params.h"
+#include "i915_reg.h"
+
+#include "intel_bios.h"
+#include "intel_dpll_mgr.h"
+#include "intel_guc.h"
+#include "intel_lrc.h"
+#include "intel_ringbuffer.h"
+
+#include "i915_gem.h"
+#include "i915_gem_gtt.h"
+#include "i915_gem_render_state.h"
+
+/* General customization:
+ */
+
+#define DRIVER_NAME		"i915_bpo"
+#define DRIVER_DESC		"Intel Graphics"
+#define DRIVER_DATE		"20160425"
+
+#undef WARN_ON
+/* Many gcc seem to no see through this and fall over :( */
+#if 0
+#define WARN_ON(x) ({ \
+	bool __i915_warn_cond = (x); \
+	if (__builtin_constant_p(__i915_warn_cond)) \
+		BUILD_BUG_ON(__i915_warn_cond); \
+	WARN(__i915_warn_cond, "WARN_ON(" #x ")"); })
+#else
+#define WARN_ON(x) WARN((x), "%s", "WARN_ON(" __stringify(x) ")")
+#endif
+
+#undef WARN_ON_ONCE
+#define WARN_ON_ONCE(x) WARN_ONCE((x), "%s", "WARN_ON_ONCE(" __stringify(x) ")")
+
+#define MISSING_CASE(x) WARN(1, "Missing switch case (%lu) in %s\n", \
+			     (long) (x), __func__);
+
+/* Use I915_STATE_WARN(x) and I915_STATE_WARN_ON() (rather than WARN() and
+ * WARN_ON()) for hw state sanity checks to check for unexpected conditions
+ * which may not necessarily be a user visible problem.  This will either
+ * WARN() or DRM_ERROR() depending on the verbose_checks moduleparam, to
+ * enable distros and users to tailor their preferred amount of i915 abrt
+ * spam.
+ */
+#define I915_STATE_WARN(condition, format...) ({			\
+	int __ret_warn_on = !!(condition);				\
+	if (unlikely(__ret_warn_on))					\
+		if (!WARN(i915.verbose_state_checks, format))		\
+			DRM_ERROR(format);				\
+	unlikely(__ret_warn_on);					\
+})
+
+#define I915_STATE_WARN_ON(x)						\
+	I915_STATE_WARN((x), "%s", "WARN_ON(" __stringify(x) ")")
+
+bool __i915_inject_load_failure(const char *func, int line);
+#define i915_inject_load_failure() \
+	__i915_inject_load_failure(__func__, __LINE__)
+
+static inline const char *yesno(bool v)
+{
+	return v ? "yes" : "no";
+}
+
+static inline const char *onoff(bool v)
+{
+	return v ? "on" : "off";
+}
+
+enum pipe {
+	INVALID_PIPE = -1,
+	PIPE_A = 0,
+	PIPE_B,
+	PIPE_C,
+	_PIPE_EDP,
+	I915_MAX_PIPES = _PIPE_EDP
+};
+#define pipe_name(p) ((p) + 'A')
+
+enum transcoder {
+	TRANSCODER_A = 0,
+	TRANSCODER_B,
+	TRANSCODER_C,
+	TRANSCODER_EDP,
+	TRANSCODER_DSI_A,
+	TRANSCODER_DSI_C,
+	I915_MAX_TRANSCODERS
+};
+
+static inline const char *transcoder_name(enum transcoder transcoder)
+{
+	switch (transcoder) {
+	case TRANSCODER_A:
+		return "A";
+	case TRANSCODER_B:
+		return "B";
+	case TRANSCODER_C:
+		return "C";
+	case TRANSCODER_EDP:
+		return "EDP";
+	case TRANSCODER_DSI_A:
+		return "DSI A";
+	case TRANSCODER_DSI_C:
+		return "DSI C";
+	default:
+		return "<invalid>";
+	}
+}
+
+static inline bool transcoder_is_dsi(enum transcoder transcoder)
+{
+	return transcoder == TRANSCODER_DSI_A || transcoder == TRANSCODER_DSI_C;
+}
+
+/*
+ * I915_MAX_PLANES in the enum below is the maximum (across all platforms)
+ * number of planes per CRTC.  Not all platforms really have this many planes,
+ * which means some arrays of size I915_MAX_PLANES may have unused entries
+ * between the topmost sprite plane and the cursor plane.
+ */
+enum plane {
+	PLANE_A = 0,
+	PLANE_B,
+	PLANE_C,
+	PLANE_CURSOR,
+	I915_MAX_PLANES,
+};
+#define plane_name(p) ((p) + 'A')
+
+#define sprite_name(p, s) ((p) * INTEL_INFO(dev)->num_sprites[(p)] + (s) + 'A')
+
+enum port {
+	PORT_A = 0,
+	PORT_B,
+	PORT_C,
+	PORT_D,
+	PORT_E,
+	I915_MAX_PORTS
+};
+#define port_name(p) ((p) + 'A')
+
+#define I915_NUM_PHYS_VLV 2
+
+enum dpio_channel {
+	DPIO_CH0,
+	DPIO_CH1
+};
+
+enum dpio_phy {
+	DPIO_PHY0,
+	DPIO_PHY1
+};
+
+enum intel_display_power_domain {
+	POWER_DOMAIN_PIPE_A,
+	POWER_DOMAIN_PIPE_B,
+	POWER_DOMAIN_PIPE_C,
+	POWER_DOMAIN_PIPE_A_PANEL_FITTER,
+	POWER_DOMAIN_PIPE_B_PANEL_FITTER,
+	POWER_DOMAIN_PIPE_C_PANEL_FITTER,
+	POWER_DOMAIN_TRANSCODER_A,
+	POWER_DOMAIN_TRANSCODER_B,
+	POWER_DOMAIN_TRANSCODER_C,
+	POWER_DOMAIN_TRANSCODER_EDP,
+	POWER_DOMAIN_TRANSCODER_DSI_A,
+	POWER_DOMAIN_TRANSCODER_DSI_C,
+	POWER_DOMAIN_PORT_DDI_A_LANES,
+	POWER_DOMAIN_PORT_DDI_B_LANES,
+	POWER_DOMAIN_PORT_DDI_C_LANES,
+	POWER_DOMAIN_PORT_DDI_D_LANES,
+	POWER_DOMAIN_PORT_DDI_E_LANES,
+	POWER_DOMAIN_PORT_DSI,
+	POWER_DOMAIN_PORT_CRT,
+	POWER_DOMAIN_PORT_OTHER,
+	POWER_DOMAIN_VGA,
+	POWER_DOMAIN_AUDIO,
+	POWER_DOMAIN_PLLS,
+	POWER_DOMAIN_AUX_A,
+	POWER_DOMAIN_AUX_B,
+	POWER_DOMAIN_AUX_C,
+	POWER_DOMAIN_AUX_D,
+	POWER_DOMAIN_GMBUS,
+	POWER_DOMAIN_MODESET,
+	POWER_DOMAIN_INIT,
+
+	POWER_DOMAIN_NUM,
+};
+
+#define POWER_DOMAIN_PIPE(pipe) ((pipe) + POWER_DOMAIN_PIPE_A)
+#define POWER_DOMAIN_PIPE_PANEL_FITTER(pipe) \
+		((pipe) + POWER_DOMAIN_PIPE_A_PANEL_FITTER)
+#define POWER_DOMAIN_TRANSCODER(tran) \
+	((tran) == TRANSCODER_EDP ? POWER_DOMAIN_TRANSCODER_EDP : \
+	 (tran) + POWER_DOMAIN_TRANSCODER_A)
+
+enum hpd_pin {
+	HPD_NONE = 0,
+	HPD_TV = HPD_NONE,     /* TV is known to be unreliable */
+	HPD_CRT,
+	HPD_SDVO_B,
+	HPD_SDVO_C,
+	HPD_PORT_A,
+	HPD_PORT_B,
+	HPD_PORT_C,
+	HPD_PORT_D,
+	HPD_PORT_E,
+	HPD_NUM_PINS
+};
+
+#define for_each_hpd_pin(__pin) \
+	for ((__pin) = (HPD_NONE + 1); (__pin) < HPD_NUM_PINS; (__pin)++)
+
+struct i915_hotplug {
+	struct work_struct hotplug_work;
+
+	struct {
+		unsigned long last_jiffies;
+		int count;
+		enum {
+			HPD_ENABLED = 0,
+			HPD_DISABLED = 1,
+			HPD_MARK_DISABLED = 2
+		} state;
+	} stats[HPD_NUM_PINS];
+	u32 event_bits;
+	struct delayed_work reenable_work;
+
+	struct intel_digital_port *irq_port[I915_MAX_PORTS];
+	u32 long_port_mask;
+	u32 short_port_mask;
+	struct work_struct dig_port_work;
+
+	/*
+	 * if we get a HPD irq from DP and a HPD irq from non-DP
+	 * the non-DP HPD could block the workqueue on a mode config
+	 * mutex getting, that userspace may have taken. However
+	 * userspace is waiting on the DP workqueue to run which is
+	 * blocked behind the non-DP one.
+	 */
+	struct workqueue_struct *dp_wq;
+};
+
+#define I915_GEM_GPU_DOMAINS \
+	(I915_GEM_DOMAIN_RENDER | \
+	 I915_GEM_DOMAIN_SAMPLER | \
+	 I915_GEM_DOMAIN_COMMAND | \
+	 I915_GEM_DOMAIN_INSTRUCTION | \
+	 I915_GEM_DOMAIN_VERTEX)
+
+#define for_each_pipe(__dev_priv, __p) \
+	for ((__p) = 0; (__p) < INTEL_INFO(__dev_priv)->num_pipes; (__p)++)
+#define for_each_pipe_masked(__dev_priv, __p, __mask) \
+	for ((__p) = 0; (__p) < INTEL_INFO(__dev_priv)->num_pipes; (__p)++) \
+		for_each_if ((__mask) & (1 << (__p)))
+#define for_each_plane(__dev_priv, __pipe, __p)				\
+	for ((__p) = 0;							\
+	     (__p) < INTEL_INFO(__dev_priv)->num_sprites[(__pipe)] + 1;	\
+	     (__p)++)
+#define for_each_sprite(__dev_priv, __p, __s)				\
+	for ((__s) = 0;							\
+	     (__s) < INTEL_INFO(__dev_priv)->num_sprites[(__p)];	\
+	     (__s)++)
+
+#define for_each_port_masked(__port, __ports_mask) \
+	for ((__port) = PORT_A; (__port) < I915_MAX_PORTS; (__port)++)	\
+		for_each_if ((__ports_mask) & (1 << (__port)))
+
+#define for_each_crtc(dev, crtc) \
+	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
+
+#define for_each_intel_plane(dev, intel_plane) \
+	list_for_each_entry(intel_plane,			\
+			    &dev->mode_config.plane_list,	\
+			    base.head)
+
+#define for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane)	\
+	list_for_each_entry(intel_plane,				\
+			    &(dev)->mode_config.plane_list,		\
+			    base.head)					\
+		for_each_if ((intel_plane)->pipe == (intel_crtc)->pipe)
+
+#define for_each_intel_crtc(dev, intel_crtc) \
+	list_for_each_entry(intel_crtc, &dev->mode_config.crtc_list, base.head)
+
+#define for_each_intel_encoder(dev, intel_encoder)		\
+	list_for_each_entry(intel_encoder,			\
+			    &(dev)->mode_config.encoder_list,	\
+			    base.head)
+
+#define for_each_intel_connector(dev, intel_connector)		\
+	list_for_each_entry(intel_connector,			\
+			    &dev->mode_config.connector_list,	\
+			    base.head)
+
+#define for_each_encoder_on_crtc(dev, __crtc, intel_encoder) \
+	list_for_each_entry((intel_encoder), &(dev)->mode_config.encoder_list, base.head) \
+		for_each_if ((intel_encoder)->base.crtc == (__crtc))
+
+#define for_each_connector_on_encoder(dev, __encoder, intel_connector) \
+	list_for_each_entry((intel_connector), &(dev)->mode_config.connector_list, base.head) \
+		for_each_if ((intel_connector)->base.encoder == (__encoder))
+
+#define for_each_power_domain(domain, mask)				\
+	for ((domain) = 0; (domain) < POWER_DOMAIN_NUM; (domain)++)	\
+		for_each_if ((1 << (domain)) & (mask))
+
+struct drm_i915_private;
+struct i915_mm_struct;
+struct i915_mmu_object;
+
+struct drm_i915_file_private {
+	struct drm_i915_private *dev_priv;
+	struct drm_file *file;
+
+	struct {
+		spinlock_t lock;
+		struct list_head request_list;
+/* 20ms is a fairly arbitrary limit (greater than the average frame time)
+ * chosen to prevent the CPU getting more than a frame ahead of the GPU
+ * (when using lax throttling for the frontbuffer). We also use it to
+ * offer free GPU waitboosts for severely congested workloads.
+ */
+#define DRM_I915_THROTTLE_JIFFIES msecs_to_jiffies(20)
+	} mm;
+	struct idr context_idr;
+
+	struct intel_rps_client {
+		struct list_head link;
+		unsigned boosts;
+	} rps;
+
+	unsigned int bsd_ring;
+};
+
+/* Used by dp and fdi links */
+struct intel_link_m_n {
+	uint32_t	tu;
+	uint32_t	gmch_m;
+	uint32_t	gmch_n;
+	uint32_t	link_m;
+	uint32_t	link_n;
+};
+
+void intel_link_compute_m_n(int bpp, int nlanes,
+			    int pixel_clock, int link_clock,
+			    struct intel_link_m_n *m_n);
+
+/* Interface history:
+ *
+ * 1.1: Original.
+ * 1.2: Add Power Management
+ * 1.3: Add vblank support
+ * 1.4: Fix cmdbuffer path, add heap destroy
+ * 1.5: Add vblank pipe configuration
+ * 1.6: - New ioctl for scheduling buffer swaps on vertical blank
+ *      - Support vertical blank on secondary display pipe
+ */
+#define DRIVER_MAJOR		1
+#define DRIVER_MINOR		6
+#define DRIVER_PATCHLEVEL	0
+
+#define WATCH_LISTS	0
+
+struct opregion_header;
+struct opregion_acpi;
+struct opregion_swsci;
+struct opregion_asle;
+
+struct intel_opregion {
+	struct opregion_header *header;
+	struct opregion_acpi *acpi;
+	struct opregion_swsci *swsci;
+	u32 swsci_gbda_sub_functions;
+	u32 swsci_sbcb_sub_functions;
+	struct opregion_asle *asle;
+	void *rvda;
+	const void *vbt;
+	u32 vbt_size;
+	u32 *lid_state;
+	struct work_struct asle_work;
+};
+#define OPREGION_SIZE            (8*1024)
+
+struct intel_overlay;
+struct intel_overlay_error_state;
+
+#define I915_FENCE_REG_NONE -1
+#define I915_MAX_NUM_FENCES 32
+/* 32 fences + sign bit for FENCE_REG_NONE */
+#define I915_MAX_NUM_FENCE_BITS 6
+
+struct drm_i915_fence_reg {
+	struct list_head lru_list;
+	struct drm_i915_gem_object *obj;
+	int pin_count;
+};
+
+struct sdvo_device_mapping {
+	u8 initialized;
+	u8 dvo_port;
+	u8 slave_addr;
+	u8 dvo_wiring;
+	u8 i2c_pin;
+	u8 ddc_pin;
+};
+
+struct intel_display_error_state;
+
+struct drm_i915_error_state {
+	struct kref ref;
+	struct timeval time;
+
+	char error_msg[128];
+	int iommu;
+	u32 reset_count;
+	u32 suspend_count;
+
+	/* Generic register state */
+	u32 eir;
+	u32 pgtbl_er;
+	u32 ier;
+	u32 gtier[4];
+	u32 ccid;
+	u32 derrmr;
+	u32 forcewake;
+	u32 error; /* gen6+ */
+	u32 err_int; /* gen7 */
+	u32 fault_data0; /* gen8, gen9 */
+	u32 fault_data1; /* gen8, gen9 */
+	u32 done_reg;
+	u32 gac_eco;
+	u32 gam_ecochk;
+	u32 gab_ctl;
+	u32 gfx_mode;
+	u32 extra_instdone[I915_NUM_INSTDONE_REG];
+	u64 fence[I915_MAX_NUM_FENCES];
+	struct intel_overlay_error_state *overlay;
+	struct intel_display_error_state *display;
+	struct drm_i915_error_object *semaphore_obj;
+
+	struct drm_i915_error_ring {
+		bool valid;
+		/* Software tracked state */
+		bool waiting;
+		int hangcheck_score;
+		enum intel_ring_hangcheck_action hangcheck_action;
+		int num_requests;
+
+		/* our own tracking of ring head and tail */
+		u32 cpu_ring_head;
+		u32 cpu_ring_tail;
+
+		u32 last_seqno;
+		u32 semaphore_seqno[I915_NUM_ENGINES - 1];
+
+		/* Register state */
+		u32 start;
+		u32 tail;
+		u32 head;
+		u32 ctl;
+		u32 hws;
+		u32 ipeir;
+		u32 ipehr;
+		u32 instdone;
+		u32 bbstate;
+		u32 instpm;
+		u32 instps;
+		u32 seqno;
+		u64 bbaddr;
+		u64 acthd;
+		u32 fault_reg;
+		u64 faddr;
+		u32 rc_psmi; /* sleep state */
+		u32 semaphore_mboxes[I915_NUM_ENGINES - 1];
+
+		struct drm_i915_error_object {
+			int page_count;
+			u64 gtt_offset;
+			u32 *pages[0];
+		} *ringbuffer, *batchbuffer, *wa_batchbuffer, *ctx, *hws_page;
+
+		struct drm_i915_error_object *wa_ctx;
+
+		struct drm_i915_error_request {
+			long jiffies;
+			u32 seqno;
+			u32 tail;
+		} *requests;
+
+		struct {
+			u32 gfx_mode;
+			union {
+				u64 pdp[4];
+				u32 pp_dir_base;
+			};
+		} vm_info;
+
+		pid_t pid;
+		char comm[TASK_COMM_LEN];
+	} ring[I915_NUM_ENGINES];
+
+	struct drm_i915_error_buffer {
+		u32 size;
+		u32 name;
+		u32 rseqno[I915_NUM_ENGINES], wseqno;
+		u64 gtt_offset;
+		u32 read_domains;
+		u32 write_domain;
+		s32 fence_reg:I915_MAX_NUM_FENCE_BITS;
+		s32 pinned:2;
+		u32 tiling:2;
+		u32 dirty:1;
+		u32 purgeable:1;
+		u32 userptr:1;
+		s32 ring:4;
+		u32 cache_level:3;
+	} **active_bo, **pinned_bo;
+
+	u32 *active_bo_count, *pinned_bo_count;
+	u32 vm_count;
+};
+
+struct intel_connector;
+struct intel_encoder;
+struct intel_crtc_state;
+struct intel_initial_plane_config;
+struct intel_crtc;
+struct intel_limit;
+struct dpll;
+
+struct drm_i915_display_funcs {
+	int (*get_display_clock_speed)(struct drm_device *dev);
+	int (*get_fifo_size)(struct drm_device *dev, int plane);
+	int (*compute_pipe_wm)(struct intel_crtc_state *cstate);
+	int (*compute_intermediate_wm)(struct drm_device *dev,
+				       struct intel_crtc *intel_crtc,
+				       struct intel_crtc_state *newstate);
+	void (*initial_watermarks)(struct intel_crtc_state *cstate);
+	void (*optimize_watermarks)(struct intel_crtc_state *cstate);
+	void (*update_wm)(struct drm_crtc *crtc);
+	int (*modeset_calc_cdclk)(struct drm_atomic_state *state);
+	void (*modeset_commit_cdclk)(struct drm_atomic_state *state);
+	/* Returns the active state of the crtc, and if the crtc is active,
+	 * fills out the pipe-config with the hw state. */
+	bool (*get_pipe_config)(struct intel_crtc *,
+				struct intel_crtc_state *);
+	void (*get_initial_plane_config)(struct intel_crtc *,
+					 struct intel_initial_plane_config *);
+	int (*crtc_compute_clock)(struct intel_crtc *crtc,
+				  struct intel_crtc_state *crtc_state);
+	void (*crtc_enable)(struct drm_crtc *crtc);
+	void (*crtc_disable)(struct drm_crtc *crtc);
+	void (*audio_codec_enable)(struct drm_connector *connector,
+				   struct intel_encoder *encoder,
+				   const struct drm_display_mode *adjusted_mode);
+	void (*audio_codec_disable)(struct intel_encoder *encoder);
+	void (*fdi_link_train)(struct drm_crtc *crtc);
+	void (*init_clock_gating)(struct drm_device *dev);
+	int (*queue_flip)(struct drm_device *dev, struct drm_crtc *crtc,
+			  struct drm_framebuffer *fb,
+			  struct drm_i915_gem_object *obj,
+			  struct drm_i915_gem_request *req,
+			  uint32_t flags);
+	void (*hpd_irq_setup)(struct drm_device *dev);
+	/* clock updates for mode set */
+	/* cursor updates */
+	/* render clock increase/decrease */
+	/* display clock increase/decrease */
+	/* pll clock increase/decrease */
+
+	void (*load_csc_matrix)(struct drm_crtc_state *crtc_state);
+	void (*load_luts)(struct drm_crtc_state *crtc_state);
+};
+
+enum forcewake_domain_id {
+	FW_DOMAIN_ID_RENDER = 0,
+	FW_DOMAIN_ID_BLITTER,
+	FW_DOMAIN_ID_MEDIA,
+
+	FW_DOMAIN_ID_COUNT
+};
+
+enum forcewake_domains {
+	FORCEWAKE_RENDER = (1 << FW_DOMAIN_ID_RENDER),
+	FORCEWAKE_BLITTER = (1 << FW_DOMAIN_ID_BLITTER),
+	FORCEWAKE_MEDIA	= (1 << FW_DOMAIN_ID_MEDIA),
+	FORCEWAKE_ALL = (FORCEWAKE_RENDER |
+			 FORCEWAKE_BLITTER |
+			 FORCEWAKE_MEDIA)
+};
+
+#define FW_REG_READ  (1)
+#define FW_REG_WRITE (2)
+
+enum forcewake_domains
+intel_uncore_forcewake_for_reg(struct drm_i915_private *dev_priv,
+			       i915_reg_t reg, unsigned int op);
+
+struct intel_uncore_funcs {
+	void (*force_wake_get)(struct drm_i915_private *dev_priv,
+							enum forcewake_domains domains);
+	void (*force_wake_put)(struct drm_i915_private *dev_priv,
+							enum forcewake_domains domains);
+
+	uint8_t  (*mmio_readb)(struct drm_i915_private *dev_priv, i915_reg_t r, bool trace);
+	uint16_t (*mmio_readw)(struct drm_i915_private *dev_priv, i915_reg_t r, bool trace);
+	uint32_t (*mmio_readl)(struct drm_i915_private *dev_priv, i915_reg_t r, bool trace);
+	uint64_t (*mmio_readq)(struct drm_i915_private *dev_priv, i915_reg_t r, bool trace);
+
+	void (*mmio_writeb)(struct drm_i915_private *dev_priv, i915_reg_t r,
+				uint8_t val, bool trace);
+	void (*mmio_writew)(struct drm_i915_private *dev_priv, i915_reg_t r,
+				uint16_t val, bool trace);
+	void (*mmio_writel)(struct drm_i915_private *dev_priv, i915_reg_t r,
+				uint32_t val, bool trace);
+	void (*mmio_writeq)(struct drm_i915_private *dev_priv, i915_reg_t r,
+				uint64_t val, bool trace);
+};
+
+struct intel_uncore {
+	spinlock_t lock; /** lock is also taken in irq contexts. */
+
+	struct intel_uncore_funcs funcs;
+
+	unsigned fifo_count;
+	enum forcewake_domains fw_domains;
+
+	struct intel_uncore_forcewake_domain {
+		struct drm_i915_private *i915;
+		enum forcewake_domain_id id;
+		enum forcewake_domains mask;
+		unsigned wake_count;
+		struct hrtimer timer;
+		i915_reg_t reg_set;
+		u32 val_set;
+		u32 val_clear;
+		i915_reg_t reg_ack;
+		i915_reg_t reg_post;
+		u32 val_reset;
+	} fw_domain[FW_DOMAIN_ID_COUNT];
+
+	int unclaimed_mmio_check;
+};
+
+/* Iterate over initialised fw domains */
+#define for_each_fw_domain_masked(domain__, mask__, dev_priv__) \
+	for ((domain__) = &(dev_priv__)->uncore.fw_domain[0]; \
+	     (domain__) < &(dev_priv__)->uncore.fw_domain[FW_DOMAIN_ID_COUNT]; \
+	     (domain__)++) \
+		for_each_if ((mask__) & (domain__)->mask)
+
+#define for_each_fw_domain(domain__, dev_priv__) \
+	for_each_fw_domain_masked(domain__, FORCEWAKE_ALL, dev_priv__)
+
+#define CSR_VERSION(major, minor)	((major) << 16 | (minor))
+#define CSR_VERSION_MAJOR(version)	((version) >> 16)
+#define CSR_VERSION_MINOR(version)	((version) & 0xffff)
+
+struct intel_csr {
+	struct work_struct work;
+	const char *fw_path;
+	uint32_t *dmc_payload;
+	uint32_t dmc_fw_size;
+	uint32_t version;
+	uint32_t mmio_count;
+	i915_reg_t mmioaddr[8];
+	uint32_t mmiodata[8];
+	uint32_t dc_state;
+	uint32_t allowed_dc_mask;
+};
+
+#define DEV_INFO_FOR_EACH_FLAG(func, sep) \
+	func(is_mobile) sep \
+	func(is_i85x) sep \
+	func(is_i915g) sep \
+	func(is_i945gm) sep \
+	func(is_g33) sep \
+	func(need_gfx_hws) sep \
+	func(is_g4x) sep \
+	func(is_pineview) sep \
+	func(is_broadwater) sep \
+	func(is_crestline) sep \
+	func(is_ivybridge) sep \
+	func(is_valleyview) sep \
+	func(is_cherryview) sep \
+	func(is_haswell) sep \
+	func(is_skylake) sep \
+	func(is_broxton) sep \
+	func(is_kabylake) sep \
+	func(is_preliminary) sep \
+	func(has_fbc) sep \
+	func(has_pipe_cxsr) sep \
+	func(has_hotplug) sep \
+	func(cursor_needs_physical) sep \
+	func(has_overlay) sep \
+	func(overlay_needs_physical) sep \
+	func(supports_tv) sep \
+	func(has_llc) sep \
+	func(has_snoop) sep \
+	func(has_ddi) sep \
+	func(has_fpga_dbg)
+
+#define DEFINE_FLAG(name) u8 name:1
+#define SEP_SEMICOLON ;
+
+struct intel_device_info {
+	u32 display_mmio_offset;
+	u16 device_id;
+	u8 num_pipes:3;
+	u8 num_sprites[I915_MAX_PIPES];
+	u8 gen;
+	u8 ring_mask; /* Rings supported by the HW */
+	DEV_INFO_FOR_EACH_FLAG(DEFINE_FLAG, SEP_SEMICOLON);
+	/* Register offsets for the various display pipes and transcoders */
+	int pipe_offsets[I915_MAX_TRANSCODERS];
+	int trans_offsets[I915_MAX_TRANSCODERS];
+	int palette_offsets[I915_MAX_PIPES];
+	int cursor_offsets[I915_MAX_PIPES];
+
+	/* Slice/subslice/EU info */
+	u8 slice_total;
+	u8 subslice_total;
+	u8 subslice_per_slice;
+	u8 eu_total;
+	u8 eu_per_subslice;
+	/* For each slice, which subslice(s) has(have) 7 EUs (bitfield)? */
+	u8 subslice_7eu[3];
+	u8 has_slice_pg:1;
+	u8 has_subslice_pg:1;
+	u8 has_eu_pg:1;
+
+	struct color_luts {
+		u16 degamma_lut_size;
+		u16 gamma_lut_size;
+	} color;
+};
+
+#undef DEFINE_FLAG
+#undef SEP_SEMICOLON
+
+enum i915_cache_level {
+	I915_CACHE_NONE = 0,
+	I915_CACHE_LLC, /* also used for snoopable memory on non-LLC */
+	I915_CACHE_L3_LLC, /* gen7+, L3 sits between the domain specifc
+			      caches, eg sampler/render caches, and the
+			      large Last-Level-Cache. LLC is coherent with
+			      the CPU, but L3 is only visible to the GPU. */
+	I915_CACHE_WT, /* hsw:gt3e WriteThrough for scanouts */
+};
+
+struct i915_ctx_hang_stats {
+	/* This context had batch pending when hang was declared */
+	unsigned batch_pending;
+
+	/* This context had batch active when hang was declared */
+	unsigned batch_active;
+
+	/* Time when this context was last blamed for a GPU reset */
+	unsigned long guilty_ts;
+
+	/* If the contexts causes a second GPU hang within this time,
+	 * it is permanently banned from submitting any more work.
+	 */
+	unsigned long ban_period_seconds;
+
+	/* This context is banned to submit more work */
+	bool banned;
+};
+
+/* This must match up with the value previously used for execbuf2.rsvd1. */
+#define DEFAULT_CONTEXT_HANDLE 0
+
+#define CONTEXT_NO_ZEROMAP (1<<0)
+/**
+ * struct intel_context - as the name implies, represents a context.
+ * @ref: reference count.
+ * @user_handle: userspace tracking identity for this context.
+ * @remap_slice: l3 row remapping information.
+ * @flags: context specific flags:
+ *         CONTEXT_NO_ZEROMAP: do not allow mapping things to page 0.
+ * @file_priv: filp associated with this context (NULL for global default
+ *	       context).
+ * @hang_stats: information about the role of this context in possible GPU
+ *		hangs.
+ * @ppgtt: virtual memory space used by this context.
+ * @legacy_hw_ctx: render context backing object and whether it is correctly
+ *                initialized (legacy ring submission mechanism only).
+ * @link: link in the global list of contexts.
+ *
+ * Contexts are memory images used by the hardware to store copies of their
+ * internal state.
+ */
+struct intel_context {
+	struct kref ref;
+	int user_handle;
+	uint8_t remap_slice;
+	struct drm_i915_private *i915;
+	int flags;
+	struct drm_i915_file_private *file_priv;
+	struct i915_ctx_hang_stats hang_stats;
+	struct i915_hw_ppgtt *ppgtt;
+
+	/* Legacy ring buffer submission */
+	struct {
+		struct drm_i915_gem_object *rcs_state;
+		bool initialized;
+	} legacy_hw_ctx;
+
+	/* Execlists */
+	struct {
+		struct drm_i915_gem_object *state;
+		struct intel_ringbuffer *ringbuf;
+		int pin_count;
+		struct i915_vma *lrc_vma;
+		u64 lrc_desc;
+		uint32_t *lrc_reg_state;
+	} engine[I915_NUM_ENGINES];
+
+	struct list_head link;
+};
+
+enum fb_op_origin {
+	ORIGIN_GTT,
+	ORIGIN_CPU,
+	ORIGIN_CS,
+	ORIGIN_FLIP,
+	ORIGIN_DIRTYFB,
+};
+
+struct intel_fbc {
+	/* This is always the inner lock when overlapping with struct_mutex and
+	 * it's the outer lock when overlapping with stolen_lock. */
+	struct mutex lock;
+	unsigned threshold;
+	unsigned int possible_framebuffer_bits;
+	unsigned int busy_bits;
+	unsigned int visible_pipes_mask;
+	struct intel_crtc *crtc;
+
+	struct drm_mm_node compressed_fb;
+	struct drm_mm_node *compressed_llb;
+
+	bool false_color;
+
+	bool enabled;
+	bool active;
+
+	struct intel_fbc_state_cache {
+		struct {
+			unsigned int mode_flags;
+			uint32_t hsw_bdw_pixel_rate;
+		} crtc;
+
+		struct {
+			unsigned int rotation;
+			int src_w;
+			int src_h;
+			bool visible;
+		} plane;
+
+		struct {
+			u64 ilk_ggtt_offset;
+			uint32_t pixel_format;
+			unsigned int stride;
+			int fence_reg;
+			unsigned int tiling_mode;
+		} fb;
+	} state_cache;
+
+	struct intel_fbc_reg_params {
+		struct {
+			enum pipe pipe;
+			enum plane plane;
+			unsigned int fence_y_offset;
+		} crtc;
+
+		struct {
+			u64 ggtt_offset;
+			uint32_t pixel_format;
+			unsigned int stride;
+			int fence_reg;
+		} fb;
+
+		int cfb_size;
+	} params;
+
+	struct intel_fbc_work {
+		bool scheduled;
+		u32 scheduled_vblank;
+		struct work_struct work;
+	} work;
+
+	const char *no_fbc_reason;
+};
+
+/**
+ * HIGH_RR is the highest eDP panel refresh rate read from EDID
+ * LOW_RR is the lowest eDP panel refresh rate found from EDID
+ * parsing for same resolution.
+ */
+enum drrs_refresh_rate_type {
+	DRRS_HIGH_RR,
+	DRRS_LOW_RR,
+	DRRS_MAX_RR, /* RR count */
+};
+
+enum drrs_support_type {
+	DRRS_NOT_SUPPORTED = 0,
+	STATIC_DRRS_SUPPORT = 1,
+	SEAMLESS_DRRS_SUPPORT = 2
+};
+
+struct intel_dp;
+struct i915_drrs {
+	struct mutex mutex;
+	struct delayed_work work;
+	struct intel_dp *dp;
+	unsigned busy_frontbuffer_bits;
+	enum drrs_refresh_rate_type refresh_rate_type;
+	enum drrs_support_type type;
+};
+
+struct i915_psr {
+	struct mutex lock;
+	bool sink_support;
+	bool source_ok;
+	struct intel_dp *enabled;
+	bool active;
+	struct delayed_work work;
+	unsigned busy_frontbuffer_bits;
+	bool psr2_support;
+	bool aux_frame_sync;
+	bool link_standby;
+};
+
+enum intel_pch {
+	PCH_NONE = 0,	/* No PCH present */
+	PCH_IBX,	/* Ibexpeak PCH */
+	PCH_CPT,	/* Cougarpoint PCH */
+	PCH_LPT,	/* Lynxpoint PCH */
+	PCH_SPT,        /* Sunrisepoint PCH */
+	PCH_KBP,        /* Kabypoint PCH */
+	PCH_NOP,
+};
+
+enum intel_sbi_destination {
+	SBI_ICLK,
+	SBI_MPHY,
+};
+
+#define QUIRK_PIPEA_FORCE (1<<0)
+#define QUIRK_LVDS_SSC_DISABLE (1<<1)
+#define QUIRK_INVERT_BRIGHTNESS (1<<2)
+#define QUIRK_BACKLIGHT_PRESENT (1<<3)
+#define QUIRK_PIPEB_FORCE (1<<4)
+#define QUIRK_PIN_SWIZZLED_PAGES (1<<5)
+
+struct intel_fbdev;
+struct intel_fbc_work;
+
+struct intel_gmbus {
+	struct i2c_adapter adapter;
+#define GMBUS_FORCE_BIT_RETRY (1U << 31)
+	u32 force_bit;
+	u32 reg0;
+	i915_reg_t gpio_reg;
+	struct i2c_algo_bit_data bit_algo;
+	struct drm_i915_private *dev_priv;
+};
+
+struct i915_suspend_saved_registers {
+	u32 saveDSPARB;
+	u32 saveLVDS;
+	u32 savePP_ON_DELAYS;
+	u32 savePP_OFF_DELAYS;
+	u32 savePP_ON;
+	u32 savePP_OFF;
+	u32 savePP_CONTROL;
+	u32 savePP_DIVISOR;
+	u32 saveFBC_CONTROL;
+	u32 saveCACHE_MODE_0;
+	u32 saveMI_ARB_STATE;
+	u32 saveSWF0[16];
+	u32 saveSWF1[16];
+	u32 saveSWF3[3];
+	uint64_t saveFENCE[I915_MAX_NUM_FENCES];
+	u32 savePCH_PORT_HOTPLUG;
+	u16 saveGCDGMBUS;
+};
+
+struct vlv_s0ix_state {
+	/* GAM */
+	u32 wr_watermark;
+	u32 gfx_prio_ctrl;
+	u32 arb_mode;
+	u32 gfx_pend_tlb0;
+	u32 gfx_pend_tlb1;
+	u32 lra_limits[GEN7_LRA_LIMITS_REG_NUM];
+	u32 media_max_req_count;
+	u32 gfx_max_req_count;
+	u32 render_hwsp;
+	u32 ecochk;
+	u32 bsd_hwsp;
+	u32 blt_hwsp;
+	u32 tlb_rd_addr;
+
+	/* MBC */
+	u32 g3dctl;
+	u32 gsckgctl;
+	u32 mbctl;
+
+	/* GCP */
+	u32 ucgctl1;
+	u32 ucgctl3;
+	u32 rcgctl1;
+	u32 rcgctl2;
+	u32 rstctl;
+	u32 misccpctl;
+
+	/* GPM */
+	u32 gfxpause;
+	u32 rpdeuhwtc;
+	u32 rpdeuc;
+	u32 ecobus;
+	u32 pwrdwnupctl;
+	u32 rp_down_timeout;
+	u32 rp_deucsw;
+	u32 rcubmabdtmr;
+	u32 rcedata;
+	u32 spare2gh;
+
+	/* Display 1 CZ domain */
+	u32 gt_imr;
+	u32 gt_ier;
+	u32 pm_imr;
+	u32 pm_ier;
+	u32 gt_scratch[GEN7_GT_SCRATCH_REG_NUM];
+
+	/* GT SA CZ domain */
+	u32 tilectl;
+	u32 gt_fifoctl;
+	u32 gtlc_wake_ctrl;
+	u32 gtlc_survive;
+	u32 pmwgicz;
+
+	/* Display 2 CZ domain */
+	u32 gu_ctl0;
+	u32 gu_ctl1;
+	u32 pcbr;
+	u32 clock_gate_dis2;
+};
+
+struct intel_rps_ei {
+	u32 cz_clock;
+	u32 render_c0;
+	u32 media_c0;
+};
+
+struct intel_gen6_power_mgmt {
+	/*
+	 * work, interrupts_enabled and pm_iir are protected by
+	 * dev_priv->irq_lock
+	 */
+	struct work_struct work;
+	bool interrupts_enabled;
+	u32 pm_iir;
+
+	/* Frequencies are stored in potentially platform dependent multiples.
+	 * In other words, *_freq needs to be multiplied by X to be interesting.
+	 * Soft limits are those which are used for the dynamic reclocking done
+	 * by the driver (raise frequencies under heavy loads, and lower for
+	 * lighter loads). Hard limits are those imposed by the hardware.
+	 *
+	 * A distinction is made for overclocking, which is never enabled by
+	 * default, and is considered to be above the hard limit if it's
+	 * possible at all.
+	 */
+	u8 cur_freq;		/* Current frequency (cached, may not == HW) */
+	u8 min_freq_softlimit;	/* Minimum frequency permitted by the driver */
+	u8 max_freq_softlimit;	/* Max frequency permitted by the driver */
+	u8 max_freq;		/* Maximum frequency, RP0 if not overclocking */
+	u8 min_freq;		/* AKA RPn. Minimum frequency */
+	u8 idle_freq;		/* Frequency to request when we are idle */
+	u8 efficient_freq;	/* AKA RPe. Pre-determined balanced frequency */
+	u8 rp1_freq;		/* "less than" RP0 power/freqency */
+	u8 rp0_freq;		/* Non-overclocked max frequency. */
+	u16 gpll_ref_freq;	/* vlv/chv GPLL reference frequency */
+
+	u8 up_threshold; /* Current %busy required to uplock */
+	u8 down_threshold; /* Current %busy required to downclock */
+
+	int last_adj;
+	enum { LOW_POWER, BETWEEN, HIGH_POWER } power;
+
+	spinlock_t client_lock;
+	struct list_head clients;
+	bool client_boost;
+
+	bool enabled;
+	struct delayed_work delayed_resume_work;
+	unsigned boosts;
+
+	struct intel_rps_client semaphores, mmioflips;
+
+	/* manual wa residency calculations */
+	struct intel_rps_ei up_ei, down_ei;
+
+	/*
+	 * Protects RPS/RC6 register access and PCU communication.
+	 * Must be taken after struct_mutex if nested. Note that
+	 * this lock may be held for long periods of time when
+	 * talking to hw - so only take it when talking to hw!
+	 */
+	struct mutex hw_lock;
+};
+
+/* defined intel_pm.c */
+extern spinlock_t mchdev_lock;
+
+struct intel_ilk_power_mgmt {
+	u8 cur_delay;
+	u8 min_delay;
+	u8 max_delay;
+	u8 fmax;
+	u8 fstart;
+
+	u64 last_count1;
+	unsigned long last_time1;
+	unsigned long chipset_power;
+	u64 last_count2;
+	u64 last_time2;
+	unsigned long gfx_power;
+	u8 corr;
+
+	int c_m;
+	int r_t;
+};
+
+struct drm_i915_private;
+struct i915_power_well;
+
+struct i915_power_well_ops {
+	/*
+	 * Synchronize the well's hw state to match the current sw state, for
+	 * example enable/disable it based on the current refcount. Called
+	 * during driver init and resume time, possibly after first calling
+	 * the enable/disable handlers.
+	 */
+	void (*sync_hw)(struct drm_i915_private *dev_priv,
+			struct i915_power_well *power_well);
+	/*
+	 * Enable the well and resources that depend on it (for example
+	 * interrupts located on the well). Called after the 0->1 refcount
+	 * transition.
+	 */
+	void (*enable)(struct drm_i915_private *dev_priv,
+		       struct i915_power_well *power_well);
+	/*
+	 * Disable the well and resources that depend on it. Called after
+	 * the 1->0 refcount transition.
+	 */
+	void (*disable)(struct drm_i915_private *dev_priv,
+			struct i915_power_well *power_well);
+	/* Returns the hw enabled state. */
+	bool (*is_enabled)(struct drm_i915_private *dev_priv,
+			   struct i915_power_well *power_well);
+};
+
+/* Power well structure for haswell */
+struct i915_power_well {
+	const char *name;
+	bool always_on;
+	/* power well enable/disable usage count */
+	int count;
+	/* cached hw enabled state */
+	bool hw_enabled;
+	unsigned long domains;
+	unsigned long data;
+	const struct i915_power_well_ops *ops;
+};
+
+struct i915_power_domains {
+	/*
+	 * Power wells needed for initialization at driver init and suspend
+	 * time are on. They are kept on until after the first modeset.
+	 */
+	bool init_power_on;
+	bool initializing;
+	int power_well_count;
+
+	struct mutex lock;
+	int domain_use_count[POWER_DOMAIN_NUM];
+	struct i915_power_well *power_wells;
+};
+
+#define MAX_L3_SLICES 2
+struct intel_l3_parity {
+	u32 *remap_info[MAX_L3_SLICES];
+	struct work_struct error_work;
+	int which_slice;
+};
+
+struct i915_gem_mm {
+	/** Memory allocator for GTT stolen memory */
+	struct drm_mm stolen;
+	/** Protects the usage of the GTT stolen memory allocator. This is
+	 * always the inner lock when overlapping with struct_mutex. */
+	struct mutex stolen_lock;
+
+	/** List of all objects in gtt_space. Used to restore gtt
+	 * mappings on resume */
+	struct list_head bound_list;
+	/**
+	 * List of objects which are not bound to the GTT (thus
+	 * are idle and not used by the GPU) but still have
+	 * (presumably uncached) pages still attached.
+	 */
+	struct list_head unbound_list;
+
+	/** Usable portion of the GTT for GEM */
+	unsigned long stolen_base; /* limited to low memory (32-bit) */
+
+	/** PPGTT used for aliasing the PPGTT with the GTT */
+	struct i915_hw_ppgtt *aliasing_ppgtt;
+
+	struct notifier_block oom_notifier;
+	struct shrinker shrinker;
+	bool shrinker_no_lock_stealing;
+
+	/** LRU list of objects with fence regs on them. */
+	struct list_head fence_list;
+
+	/**
+	 * We leave the user IRQ off as much as possible,
+	 * but this means that requests will finish and never
+	 * be retired once the system goes idle. Set a timer to
+	 * fire periodically while the ring is running. When it
+	 * fires, go retire requests.
+	 */
+	struct delayed_work retire_work;
+
+	/**
+	 * When we detect an idle GPU, we want to turn on
+	 * powersaving features. So once we see that there
+	 * are no more requests outstanding and no more
+	 * arrive within a small period of time, we fire
+	 * off the idle_work.
+	 */
+	struct delayed_work idle_work;
+
+	/**
+	 * Are we in a non-interruptible section of code like
+	 * modesetting?
+	 */
+	bool interruptible;
+
+	/**
+	 * Is the GPU currently considered idle, or busy executing userspace
+	 * requests?  Whilst idle, we attempt to power down the hardware and
+	 * display clocks. In order to reduce the effect on performance, there
+	 * is a slight delay before we do so.
+	 */
+	bool busy;
+
+	/* the indicator for dispatch video commands on two BSD rings */
+	unsigned int bsd_ring_dispatch_index;
+
+	/** Bit 6 swizzling required for X tiling */
+	uint32_t bit_6_swizzle_x;
+	/** Bit 6 swizzling required for Y tiling */
+	uint32_t bit_6_swizzle_y;
+
+	/* accounting, useful for userland debugging */
+	spinlock_t object_stat_lock;
+	size_t object_memory;
+	u32 object_count;
+};
+
+struct drm_i915_error_state_buf {
+	struct drm_i915_private *i915;
+	unsigned bytes;
+	unsigned size;
+	int err;
+	u8 *buf;
+	loff_t start;
+	loff_t pos;
+};
+
+struct i915_error_state_file_priv {
+	struct drm_device *dev;
+	struct drm_i915_error_state *error;
+};
+
+struct i915_gpu_error {
+	/* For hangcheck timer */
+#define DRM_I915_HANGCHECK_PERIOD 1500 /* in ms */
+#define DRM_I915_HANGCHECK_JIFFIES msecs_to_jiffies(DRM_I915_HANGCHECK_PERIOD)
+	/* Hang gpu twice in this window and your context gets banned */
+#define DRM_I915_CTX_BAN_PERIOD DIV_ROUND_UP(8*DRM_I915_HANGCHECK_PERIOD, 1000)
+
+	struct workqueue_struct *hangcheck_wq;
+	struct delayed_work hangcheck_work;
+
+	/* For reset and error_state handling. */
+	spinlock_t lock;
+	/* Protected by the above dev->gpu_error.lock. */
+	struct drm_i915_error_state *first_error;
+
+	unsigned long missed_irq_rings;
+
+	/**
+	 * State variable controlling the reset flow and count
+	 *
+	 * This is a counter which gets incremented when reset is triggered,
+	 * and again when reset has been handled. So odd values (lowest bit set)
+	 * means that reset is in progress and even values that
+	 * (reset_counter >> 1):th reset was successfully completed.
+	 *
+	 * If reset is not completed succesfully, the I915_WEDGE bit is
+	 * set meaning that hardware is terminally sour and there is no
+	 * recovery. All waiters on the reset_queue will be woken when
+	 * that happens.
+	 *
+	 * This counter is used by the wait_seqno code to notice that reset
+	 * event happened and it needs to restart the entire ioctl (since most
+	 * likely the seqno it waited for won't ever signal anytime soon).
+	 *
+	 * This is important for lock-free wait paths, where no contended lock
+	 * naturally enforces the correct ordering between the bail-out of the
+	 * waiter and the gpu reset work code.
+	 */
+	atomic_t reset_counter;
+
+#define I915_RESET_IN_PROGRESS_FLAG	1
+#define I915_WEDGED			(1 << 31)
+
+	/**
+	 * Waitqueue to signal when the reset has completed. Used by clients
+	 * that wait for dev_priv->mm.wedged to settle.
+	 */
+	wait_queue_head_t reset_queue;
+
+	/* Userspace knobs for gpu hang simulation;
+	 * combines both a ring mask, and extra flags
+	 */
+	u32 stop_rings;
+#define I915_STOP_RING_ALLOW_BAN       (1 << 31)
+#define I915_STOP_RING_ALLOW_WARN      (1 << 30)
+
+	/* For missed irq/seqno simulation. */
+	unsigned int test_irq_rings;
+};
+
+enum modeset_restore {
+	MODESET_ON_LID_OPEN,
+	MODESET_DONE,
+	MODESET_SUSPENDED,
+};
+
+#define DP_AUX_A 0x40
+#define DP_AUX_B 0x10
+#define DP_AUX_C 0x20
+#define DP_AUX_D 0x30
+
+#define DDC_PIN_B  0x05
+#define DDC_PIN_C  0x04
+#define DDC_PIN_D  0x06
+
+struct ddi_vbt_port_info {
+	/*
+	 * This is an index in the HDMI/DVI DDI buffer translation table.
+	 * The special value HDMI_LEVEL_SHIFT_UNKNOWN means the VBT didn't
+	 * populate this field.
+	 */
+#define HDMI_LEVEL_SHIFT_UNKNOWN	0xff
+	uint8_t hdmi_level_shift;
+
+	uint8_t supports_dvi:1;
+	uint8_t supports_hdmi:1;
+	uint8_t supports_dp:1;
+
+	uint8_t alternate_aux_channel;
+	uint8_t alternate_ddc_pin;
+
+	uint8_t dp_boost_level;
+	uint8_t hdmi_boost_level;
+};
+
+enum psr_lines_to_wait {
+	PSR_0_LINES_TO_WAIT = 0,
+	PSR_1_LINE_TO_WAIT,
+	PSR_4_LINES_TO_WAIT,
+	PSR_8_LINES_TO_WAIT
+};
+
+struct intel_vbt_data {
+	struct drm_display_mode *lfp_lvds_vbt_mode; /* if any */
+	struct drm_display_mode *sdvo_lvds_vbt_mode; /* if any */
+
+	/* Feature bits */
+	unsigned int int_tv_support:1;
+	unsigned int lvds_dither:1;
+	unsigned int lvds_vbt:1;
+	unsigned int int_crt_support:1;
+	unsigned int lvds_use_ssc:1;
+	unsigned int display_clock_mode:1;
+	unsigned int fdi_rx_polarity_inverted:1;
+	unsigned int panel_type:4;
+	int lvds_ssc_freq;
+	unsigned int bios_lvds_val; /* initial [PCH_]LVDS reg val in VBIOS */
+
+	enum drrs_support_type drrs_type;
+
+	struct {
+		int rate;
+		int lanes;
+		int preemphasis;
+		int vswing;
+		bool low_vswing;
+		bool initialized;
+		bool support;
+		int bpp;
+		struct edp_power_seq pps;
+	} edp;
+
+	struct {
+		bool full_link;
+		bool require_aux_wakeup;
+		int idle_frames;
+		enum psr_lines_to_wait lines_to_wait;
+		int tp1_wakeup_time;
+		int tp2_tp3_wakeup_time;
+	} psr;
+
+	struct {
+		u16 pwm_freq_hz;
+		bool present;
+		bool active_low_pwm;
+		u8 min_brightness;	/* min_brightness/255 of max */
+	} backlight;
+
+	/* MIPI DSI */
+	struct {
+		u16 panel_id;
+		struct mipi_config *config;
+		struct mipi_pps_data *pps;
+		u8 seq_version;
+		u32 size;
+		u8 *data;
+		const u8 *sequence[MIPI_SEQ_MAX];
+	} dsi;
+
+	int crt_ddc_pin;
+
+	int child_dev_num;
+	union child_device_config *child_dev;
+
+	struct ddi_vbt_port_info ddi_port_info[I915_MAX_PORTS];
+	struct sdvo_device_mapping sdvo_mappings[2];
+};
+
+enum intel_ddb_partitioning {
+	INTEL_DDB_PART_1_2,
+	INTEL_DDB_PART_5_6, /* IVB+ */
+};
+
+struct intel_wm_level {
+	bool enable;
+	uint32_t pri_val;
+	uint32_t spr_val;
+	uint32_t cur_val;
+	uint32_t fbc_val;
+};
+
+struct ilk_wm_values {
+	uint32_t wm_pipe[3];
+	uint32_t wm_lp[3];
+	uint32_t wm_lp_spr[3];
+	uint32_t wm_linetime[3];
+	bool enable_fbc_wm;
+	enum intel_ddb_partitioning partitioning;
+};
+
+struct vlv_pipe_wm {
+	uint16_t primary;
+	uint16_t sprite[2];
+	uint8_t cursor;
+};
+
+struct vlv_sr_wm {
+	uint16_t plane;
+	uint8_t cursor;
+};
+
+struct vlv_wm_values {
+	struct vlv_pipe_wm pipe[3];
+	struct vlv_sr_wm sr;
+	struct {
+		uint8_t cursor;
+		uint8_t sprite[2];
+		uint8_t primary;
+	} ddl[3];
+	uint8_t level;
+	bool cxsr;
+};
+
+struct skl_ddb_entry {
+	uint16_t start, end;	/* in number of blocks, 'end' is exclusive */
+};
+
+static inline uint16_t skl_ddb_entry_size(const struct skl_ddb_entry *entry)
+{
+	return entry->end - entry->start;
+}
+
+static inline bool skl_ddb_entry_equal(const struct skl_ddb_entry *e1,
+				       const struct skl_ddb_entry *e2)
+{
+	if (e1->start == e2->start && e1->end == e2->end)
+		return true;
+
+	return false;
+}
+
+struct skl_ddb_allocation {
+	struct skl_ddb_entry pipe[I915_MAX_PIPES];
+	struct skl_ddb_entry plane[I915_MAX_PIPES][I915_MAX_PLANES]; /* packed/uv */
+	struct skl_ddb_entry y_plane[I915_MAX_PIPES][I915_MAX_PLANES];
+};
+
+struct skl_wm_values {
+	bool dirty[I915_MAX_PIPES];
+	struct skl_ddb_allocation ddb;
+	uint32_t wm_linetime[I915_MAX_PIPES];
+	uint32_t plane[I915_MAX_PIPES][I915_MAX_PLANES][8];
+	uint32_t plane_trans[I915_MAX_PIPES][I915_MAX_PLANES];
+};
+
+struct skl_wm_level {
+	bool plane_en[I915_MAX_PLANES];
+	uint16_t plane_res_b[I915_MAX_PLANES];
+	uint8_t plane_res_l[I915_MAX_PLANES];
+};
+
+/*
+ * This struct helps tracking the state needed for runtime PM, which puts the
+ * device in PCI D3 state. Notice that when this happens, nothing on the
+ * graphics device works, even register access, so we don't get interrupts nor
+ * anything else.
+ *
+ * Every piece of our code that needs to actually touch the hardware needs to
+ * either call intel_runtime_pm_get or call intel_display_power_get with the
+ * appropriate power domain.
+ *
+ * Our driver uses the autosuspend delay feature, which means we'll only really
+ * suspend if we stay with zero refcount for a certain amount of time. The
+ * default value is currently very conservative (see intel_runtime_pm_enable), but
+ * it can be changed with the standard runtime PM files from sysfs.
+ *
+ * The irqs_disabled variable becomes true exactly after we disable the IRQs and
+ * goes back to false exactly before we reenable the IRQs. We use this variable
+ * to check if someone is trying to enable/disable IRQs while they're supposed
+ * to be disabled. This shouldn't happen and we'll print some error messages in
+ * case it happens.
+ *
+ * For more, read the Documentation/power/runtime_pm.txt.
+ */
+struct i915_runtime_pm {
+	atomic_t wakeref_count;
+	atomic_t atomic_seq;
+	bool suspended;
+	bool irqs_enabled;
+};
+
+enum intel_pipe_crc_source {
+	INTEL_PIPE_CRC_SOURCE_NONE,
+	INTEL_PIPE_CRC_SOURCE_PLANE1,
+	INTEL_PIPE_CRC_SOURCE_PLANE2,
+	INTEL_PIPE_CRC_SOURCE_PF,
+	INTEL_PIPE_CRC_SOURCE_PIPE,
+	/* TV/DP on pre-gen5/vlv can't use the pipe source. */
+	INTEL_PIPE_CRC_SOURCE_TV,
+	INTEL_PIPE_CRC_SOURCE_DP_B,
+	INTEL_PIPE_CRC_SOURCE_DP_C,
+	INTEL_PIPE_CRC_SOURCE_DP_D,
+	INTEL_PIPE_CRC_SOURCE_AUTO,
+	INTEL_PIPE_CRC_SOURCE_MAX,
+};
+
+struct intel_pipe_crc_entry {
+	uint32_t frame;
+	uint32_t crc[5];
+};
+
+#define INTEL_PIPE_CRC_ENTRIES_NR	128
+struct intel_pipe_crc {
+	spinlock_t lock;
+	bool opened;		/* exclusive access to the result file */
+	struct intel_pipe_crc_entry *entries;
+	enum intel_pipe_crc_source source;
+	int head, tail;
+	wait_queue_head_t wq;
+};
+
+struct i915_frontbuffer_tracking {
+	struct mutex lock;
+
+	/*
+	 * Tracking bits for delayed frontbuffer flushing du to gpu activity or
+	 * scheduled flips.
+	 */
+	unsigned busy_bits;
+	unsigned flip_bits;
+};
+
+struct i915_wa_reg {
+	i915_reg_t addr;
+	u32 value;
+	/* bitmask representing WA bits */
+	u32 mask;
+};
+
+/*
+ * RING_MAX_NONPRIV_SLOTS is per-engine but at this point we are only
+ * allowing it for RCS as we don't foresee any requirement of having
+ * a whitelist for other engines. When it is really required for
+ * other engines then the limit need to be increased.
+ */
+#define I915_MAX_WA_REGS (16 + RING_MAX_NONPRIV_SLOTS)
+
+struct i915_workarounds {
+	struct i915_wa_reg reg[I915_MAX_WA_REGS];
+	u32 count;
+	u32 hw_whitelist_count[I915_NUM_ENGINES];
+};
+
+struct i915_virtual_gpu {
+	bool active;
+};
+
+struct i915_execbuffer_params {
+	struct drm_device               *dev;
+	struct drm_file                 *file;
+	uint32_t                        dispatch_flags;
+	uint32_t                        args_batch_start_offset;
+	uint64_t                        batch_obj_vm_offset;
+	struct intel_engine_cs *engine;
+	struct drm_i915_gem_object      *batch_obj;
+	struct intel_context            *ctx;
+	struct drm_i915_gem_request     *request;
+};
+
+/* used in computing the new watermarks state */
+struct intel_wm_config {
+	unsigned int num_pipes_active;
+	bool sprites_enabled;
+	bool sprites_scaled;
+};
+
+struct drm_i915_private {
+	struct drm_device *dev;
+	struct kmem_cache *objects;
+	struct kmem_cache *vmas;
+	struct kmem_cache *requests;
+
+	const struct intel_device_info info;
+
+	int relative_constants_mode;
+
+	void __iomem *regs;
+
+	struct intel_uncore uncore;
+
+	struct i915_virtual_gpu vgpu;
+
+	struct intel_guc guc;
+
+	struct intel_csr csr;
+
+	struct intel_gmbus gmbus[GMBUS_NUM_PINS];
+
+	/** gmbus_mutex protects against concurrent usage of the single hw gmbus
+	 * controller on different i2c buses. */
+	struct mutex gmbus_mutex;
+
+	/**
+	 * Base address of the gmbus and gpio block.
+	 */
+	uint32_t gpio_mmio_base;
+
+	/* MMIO base address for MIPI regs */
+	uint32_t mipi_mmio_base;
+
+	uint32_t psr_mmio_base;
+
+	wait_queue_head_t gmbus_wait_queue;
+
+	struct pci_dev *bridge_dev;
+	struct intel_engine_cs engine[I915_NUM_ENGINES];
+	struct drm_i915_gem_object *semaphore_obj;
+	uint32_t last_seqno, next_seqno;
+
+	struct drm_dma_handle *status_page_dmah;
+	struct resource mch_res;
+
+	/* protects the irq masks */
+	spinlock_t irq_lock;
+
+	/* protects the mmio flip data */
+	spinlock_t mmio_flip_lock;
+
+	bool display_irqs_enabled;
+
+	/* To control wakeup latency, e.g. for irq-driven dp aux transfers. */
+	struct pm_qos_request pm_qos;
+
+	/* Sideband mailbox protection */
+	struct mutex sb_lock;
+
+	/** Cached value of IMR to avoid reads in updating the bitfield */
+	union {
+		u32 irq_mask;
+		u32 de_irq_mask[I915_MAX_PIPES];
+	};
+	u32 gt_irq_mask;
+	u32 pm_irq_mask;
+	u32 pm_rps_events;
+	u32 pipestat_irq_mask[I915_MAX_PIPES];
+
+	struct i915_hotplug hotplug;
+	struct intel_fbc fbc;
+	struct i915_drrs drrs;
+	struct intel_opregion opregion;
+	struct intel_vbt_data vbt;
+
+	bool preserve_bios_swizzle;
+
+	/* overlay */
+	struct intel_overlay *overlay;
+
+	/* backlight registers and fields in struct intel_panel */
+	struct mutex backlight_lock;
+
+	/* LVDS info */
+	bool no_aux_handshake;
+
+	/* protects panel power sequencer state */
+	struct mutex pps_mutex;
+
+	struct drm_i915_fence_reg fence_regs[I915_MAX_NUM_FENCES]; /* assume 965 */
+	int num_fence_regs; /* 8 on pre-965, 16 otherwise */
+
+	unsigned int fsb_freq, mem_freq, is_ddr3;
+	unsigned int skl_boot_cdclk;
+	unsigned int cdclk_freq, max_cdclk_freq, atomic_cdclk_freq;
+	unsigned int max_dotclk_freq;
+	unsigned int rawclk_freq;
+	unsigned int hpll_freq;
+	unsigned int czclk_freq;
+
+	/**
+	 * wq - Driver workqueue for GEM.
+	 *
+	 * NOTE: Work items scheduled here are not allowed to grab any modeset
+	 * locks, for otherwise the flushing done in the pageflip code will
+	 * result in deadlocks.
+	 */
+	struct workqueue_struct *wq;
+
+	/* Display functions */
+	struct drm_i915_display_funcs display;
+
+	/* PCH chipset type */
+	enum intel_pch pch_type;
+	unsigned short pch_id;
+
+	unsigned long quirks;
+
+	enum modeset_restore modeset_restore;
+	struct mutex modeset_restore_lock;
+	struct drm_atomic_state *modeset_restore_state;
+
+	struct list_head vm_list; /* Global list of all address spaces */
+	struct i915_ggtt ggtt; /* VM representing the global address space */
+
+	struct i915_gem_mm mm;
+	DECLARE_HASHTABLE(mm_structs, 7);
+	struct mutex mm_lock;
+
+	/* Kernel Modesetting */
+
+	struct drm_crtc *plane_to_crtc_mapping[I915_MAX_PIPES];
+	struct drm_crtc *pipe_to_crtc_mapping[I915_MAX_PIPES];
+	wait_queue_head_t pending_flip_queue;
+
+#ifdef CONFIG_DEBUG_FS
+	struct intel_pipe_crc pipe_crc[I915_MAX_PIPES];
+#endif
+
+	/* dpll and cdclk state is protected by connection_mutex */
+	int num_shared_dpll;
+	struct intel_shared_dpll shared_dplls[I915_NUM_PLLS];
+	const struct intel_dpll_mgr *dpll_mgr;
+
+	/*
+	 * dpll_lock serializes intel_{prepare,enable,disable}_shared_dpll.
+	 * Must be global rather than per dpll, because on some platforms
+	 * plls share registers.
+	 */
+	struct mutex dpll_lock;
+
+	unsigned int active_crtcs;
+	unsigned int min_pixclk[I915_MAX_PIPES];
+
+	int dpio_phy_iosf_port[I915_NUM_PHYS_VLV];
+
+	struct i915_workarounds workarounds;
+
+	struct i915_frontbuffer_tracking fb_tracking;
+
+	u16 orig_clock;
+
+	bool mchbar_need_disable;
+
+	struct intel_l3_parity l3_parity;
+
+	/* Cannot be determined by PCIID. You must always read a register. */
+	u32 edram_cap;
+
+	/* gen6+ rps state */
+	struct intel_gen6_power_mgmt rps;
+
+	/* ilk-only ips/rps state. Everything in here is protected by the global
+	 * mchdev_lock in intel_pm.c */
+	struct intel_ilk_power_mgmt ips;
+
+	struct i915_power_domains power_domains;
+
+	struct i915_psr psr;
+
+	struct i915_gpu_error gpu_error;
+
+	struct drm_i915_gem_object *vlv_pctx;
+
+#ifdef CONFIG_DRM_FBDEV_EMULATION
+	/* list of fbdev register on this device */
+	struct intel_fbdev *fbdev;
+	struct work_struct fbdev_suspend_work;
+#endif
+
+	struct drm_property *broadcast_rgb_property;
+	struct drm_property *force_audio_property;
+
+	/* hda/i915 audio component */
+	struct i915_audio_component *audio_component;
+	bool audio_component_registered;
+	/**
+	 * av_mutex - mutex for audio/video sync
+	 *
+	 */
+	struct mutex av_mutex;
+
+	uint32_t hw_context_size;
+	struct list_head context_list;
+
+	u32 fdi_rx_config;
+
+	/* Shadow for DISPLAY_PHY_CONTROL which can't be safely read */
+	u32 chv_phy_control;
+	/*
+	 * Shadows for CHV DPLL_MD regs to keep the state
+	 * checker somewhat working in the presence hardware
+	 * crappiness (can't read out DPLL_MD for pipes B & C).
+	 */
+	u32 chv_dpll_md[I915_MAX_PIPES];
+	u32 bxt_phy_grc;
+
+	u32 suspend_count;
+	bool suspended_to_idle;
+	struct i915_suspend_saved_registers regfile;
+	struct vlv_s0ix_state vlv_s0ix_state;
+
+	struct {
+		/*
+		 * Raw watermark latency values:
+		 * in 0.1us units for WM0,
+		 * in 0.5us units for WM1+.
+		 */
+		/* primary */
+		uint16_t pri_latency[5];
+		/* sprite */
+		uint16_t spr_latency[5];
+		/* cursor */
+		uint16_t cur_latency[5];
+		/*
+		 * Raw watermark memory latency values
+		 * for SKL for all 8 levels
+		 * in 1us units.
+		 */
+		uint16_t skl_latency[8];
+
+		/* Committed wm config */
+		struct intel_wm_config config;
+
+		/*
+		 * The skl_wm_values structure is a bit too big for stack
+		 * allocation, so we keep the staging struct where we store
+		 * intermediate results here instead.
+		 */
+		struct skl_wm_values skl_results;
+
+		/* current hardware state */
+		union {
+			struct ilk_wm_values hw;
+			struct skl_wm_values skl_hw;
+			struct vlv_wm_values vlv;
+		};
+
+		uint8_t max_level;
+
+		/*
+		 * Should be held around atomic WM register writing; also
+		 * protects * intel_crtc->wm.active and
+		 * cstate->wm.need_postvbl_update.
+		 */
+		struct mutex wm_mutex;
+	} wm;
+
+	struct i915_runtime_pm pm;
+
+	/* Abstract the submission mechanism (legacy ringbuffer or execlists) away */
+	struct {
+		int (*execbuf_submit)(struct i915_execbuffer_params *params,
+				      struct drm_i915_gem_execbuffer2 *args,
+				      struct list_head *vmas);
+		int (*init_engines)(struct drm_device *dev);
+		void (*cleanup_engine)(struct intel_engine_cs *engine);
+		void (*stop_engine)(struct intel_engine_cs *engine);
+	} gt;
+
+	struct intel_context *kernel_context;
+
+	/* perform PHY state sanity checks? */
+	bool chv_phy_assert[2];
+
+	struct intel_encoder *dig_port_map[I915_MAX_PORTS];
+
+	/*
+	 * NOTE: This is the dri1/ums dungeon, don't add stuff here. Your patch
+	 * will be rejected. Instead look for a better place.
+	 */
+};
+
+static inline struct drm_i915_private *to_i915(const struct drm_device *dev)
+{
+	return dev->dev_private;
+}
+
+static inline struct drm_i915_private *dev_to_i915(struct device *dev)
+{
+	return to_i915(dev_get_drvdata(dev));
+}
+
+static inline struct drm_i915_private *guc_to_i915(struct intel_guc *guc)
+{
+	return container_of(guc, struct drm_i915_private, guc);
+}
+
+/* Simple iterator over all initialised engines */
+#define for_each_engine(engine__, dev_priv__) \
+	for ((engine__) = &(dev_priv__)->engine[0]; \
+	     (engine__) < &(dev_priv__)->engine[I915_NUM_ENGINES]; \
+	     (engine__)++) \
+		for_each_if (intel_engine_initialized(engine__))
+
+/* Iterator with engine_id */
+#define for_each_engine_id(engine__, dev_priv__, id__) \
+	for ((engine__) = &(dev_priv__)->engine[0], (id__) = 0; \
+	     (engine__) < &(dev_priv__)->engine[I915_NUM_ENGINES]; \
+	     (engine__)++) \
+		for_each_if (((id__) = (engine__)->id, \
+			      intel_engine_initialized(engine__)))
+
+/* Iterator over subset of engines selected by mask */
+#define for_each_engine_masked(engine__, dev_priv__, mask__) \
+	for ((engine__) = &(dev_priv__)->engine[0]; \
+	     (engine__) < &(dev_priv__)->engine[I915_NUM_ENGINES]; \
+	     (engine__)++) \
+		for_each_if (((mask__) & intel_engine_flag(engine__)) && \
+			     intel_engine_initialized(engine__))
+
+enum hdmi_force_audio {
+	HDMI_AUDIO_OFF_DVI = -2,	/* no aux data for HDMI-DVI converter */
+	HDMI_AUDIO_OFF,			/* force turn off HDMI audio */
+	HDMI_AUDIO_AUTO,		/* trust EDID */
+	HDMI_AUDIO_ON,			/* force turn on HDMI audio */
+};
+
+#define I915_GTT_OFFSET_NONE ((u32)-1)
+
+struct drm_i915_gem_object_ops {
+	unsigned int flags;
+#define I915_GEM_OBJECT_HAS_STRUCT_PAGE 0x1
+
+	/* Interface between the GEM object and its backing storage.
+	 * get_pages() is called once prior to the use of the associated set
+	 * of pages before to binding them into the GTT, and put_pages() is
+	 * called after we no longer need them. As we expect there to be
+	 * associated cost with migrating pages between the backing storage
+	 * and making them available for the GPU (e.g. clflush), we may hold
+	 * onto the pages after they are no longer referenced by the GPU
+	 * in case they may be used again shortly (for example migrating the
+	 * pages to a different memory domain within the GTT). put_pages()
+	 * will therefore most likely be called when the object itself is
+	 * being released or under memory pressure (where we attempt to
+	 * reap pages for the shrinker).
+	 */
+	int (*get_pages)(struct drm_i915_gem_object *);
+	void (*put_pages)(struct drm_i915_gem_object *);
+
+	int (*dmabuf_export)(struct drm_i915_gem_object *);
+	void (*release)(struct drm_i915_gem_object *);
+};
+
+/*
+ * Frontbuffer tracking bits. Set in obj->frontbuffer_bits while a gem bo is
+ * considered to be the frontbuffer for the given plane interface-wise. This
+ * doesn't mean that the hw necessarily already scans it out, but that any
+ * rendering (by the cpu or gpu) will land in the frontbuffer eventually.
+ *
+ * We have one bit per pipe and per scanout plane type.
+ */
+#define INTEL_MAX_SPRITE_BITS_PER_PIPE 5
+#define INTEL_FRONTBUFFER_BITS_PER_PIPE 8
+#define INTEL_FRONTBUFFER_BITS \
+	(INTEL_FRONTBUFFER_BITS_PER_PIPE * I915_MAX_PIPES)
+#define INTEL_FRONTBUFFER_PRIMARY(pipe) \
+	(1 << (INTEL_FRONTBUFFER_BITS_PER_PIPE * (pipe)))
+#define INTEL_FRONTBUFFER_CURSOR(pipe) \
+	(1 << (1 + (INTEL_FRONTBUFFER_BITS_PER_PIPE * (pipe))))
+#define INTEL_FRONTBUFFER_SPRITE(pipe, plane) \
+	(1 << (2 + plane + (INTEL_FRONTBUFFER_BITS_PER_PIPE * (pipe))))
+#define INTEL_FRONTBUFFER_OVERLAY(pipe) \
+	(1 << (2 + INTEL_MAX_SPRITE_BITS_PER_PIPE + (INTEL_FRONTBUFFER_BITS_PER_PIPE * (pipe))))
+#define INTEL_FRONTBUFFER_ALL_MASK(pipe) \
+	(0xff << (INTEL_FRONTBUFFER_BITS_PER_PIPE * (pipe)))
+
+struct drm_i915_gem_object {
+	struct drm_gem_object base;
+
+	const struct drm_i915_gem_object_ops *ops;
+
+	/** List of VMAs backed by this object */
+	struct list_head vma_list;
+
+	/** Stolen memory for this object, instead of being backed by shmem. */
+	struct drm_mm_node *stolen;
+	struct list_head global_list;
+
+	struct list_head engine_list[I915_NUM_ENGINES];
+	/** Used in execbuf to temporarily hold a ref */
+	struct list_head obj_exec_link;
+
+	struct list_head batch_pool_link;
+
+	/**
+	 * This is set if the object is on the active lists (has pending
+	 * rendering and so a non-zero seqno), and is not set if it i s on
+	 * inactive (ready to be unbound) list.
+	 */
+	unsigned int active:I915_NUM_ENGINES;
+
+	/**
+	 * This is set if the object has been written to since last bound
+	 * to the GTT
+	 */
+	unsigned int dirty:1;
+
+	/**
+	 * Fence register bits (if any) for this object.  Will be set
+	 * as needed when mapped into the GTT.
+	 * Protected by dev->struct_mutex.
+	 */
+	signed int fence_reg:I915_MAX_NUM_FENCE_BITS;
+
+	/**
+	 * Advice: are the backing pages purgeable?
+	 */
+	unsigned int madv:2;
+
+	/**
+	 * Current tiling mode for the object.
+	 */
+	unsigned int tiling_mode:2;
+	/**
+	 * Whether the tiling parameters for the currently associated fence
+	 * register have changed. Note that for the purposes of tracking
+	 * tiling changes we also treat the unfenced register, the register
+	 * slot that the object occupies whilst it executes a fenced
+	 * command (such as BLT on gen2/3), as a "fence".
+	 */
+	unsigned int fence_dirty:1;
+
+	/**
+	 * Is the object at the current location in the gtt mappable and
+	 * fenceable? Used to avoid costly recalculations.
+	 */
+	unsigned int map_and_fenceable:1;
+
+	/**
+	 * Whether the current gtt mapping needs to be mappable (and isn't just
+	 * mappable by accident). Track pin and fault separate for a more
+	 * accurate mappable working set.
+	 */
+	unsigned int fault_mappable:1;
+
+	/*
+	 * Is the object to be mapped as read-only to the GPU
+	 * Only honoured if hardware has relevant pte bit
+	 */
+	unsigned long gt_ro:1;
+	unsigned int cache_level:3;
+	unsigned int cache_dirty:1;
+
+	unsigned int frontbuffer_bits:INTEL_FRONTBUFFER_BITS;
+
+	unsigned int pin_display;
+
+	struct sg_table *pages;
+	int pages_pin_count;
+	struct get_page {
+		struct scatterlist *sg;
+		int last;
+	} get_page;
+	void *mapping;
+
+	/** Breadcrumb of last rendering to the buffer.
+	 * There can only be one writer, but we allow for multiple readers.
+	 * If there is a writer that necessarily implies that all other
+	 * read requests are complete - but we may only be lazily clearing
+	 * the read requests. A read request is naturally the most recent
+	 * request on a ring, so we may have two different write and read
+	 * requests on one ring where the write request is older than the
+	 * read request. This allows for the CPU to read from an active
+	 * buffer by only waiting for the write to complete.
+	 * */
+	struct drm_i915_gem_request *last_read_req[I915_NUM_ENGINES];
+	struct drm_i915_gem_request *last_write_req;
+	/** Breadcrumb of last fenced GPU access to the buffer. */
+	struct drm_i915_gem_request *last_fenced_req;
+
+	/** Current tiling stride for the object, if it's tiled. */
+	uint32_t stride;
+
+	/** References from framebuffers, locks out tiling changes. */
+	unsigned long framebuffer_references;
+
+	/** Record of address bit 17 of each page at last unbind. */
+	unsigned long *bit_17;
+
+	union {
+		/** for phy allocated objects */
+		struct drm_dma_handle *phys_handle;
+
+		struct i915_gem_userptr {
+			uintptr_t ptr;
+			unsigned read_only :1;
+			unsigned workers :4;
+#define I915_GEM_USERPTR_MAX_WORKERS 15
+
+			struct i915_mm_struct *mm;
+			struct i915_mmu_object *mmu_object;
+			struct work_struct *work;
+		} userptr;
+	};
+};
+#define to_intel_bo(x) container_of(x, struct drm_i915_gem_object, base)
+
+void i915_gem_track_fb(struct drm_i915_gem_object *old,
+		       struct drm_i915_gem_object *new,
+		       unsigned frontbuffer_bits);
+
+/**
+ * Request queue structure.
+ *
+ * The request queue allows us to note sequence numbers that have been emitted
+ * and may be associated with active buffers to be retired.
+ *
+ * By keeping this list, we can avoid having to do questionable sequence
+ * number comparisons on buffer last_read|write_seqno. It also allows an
+ * emission time to be associated with the request for tracking how far ahead
+ * of the GPU the submission is.
+ *
+ * The requests are reference counted, so upon creation they should have an
+ * initial reference taken using kref_init
+ */
+struct drm_i915_gem_request {
+	struct kref ref;
+
+	/** On Which ring this request was generated */
+	struct drm_i915_private *i915;
+	struct intel_engine_cs *engine;
+	unsigned reset_counter;
+
+	 /** GEM sequence number associated with the previous request,
+	  * when the HWS breadcrumb is equal to this the GPU is processing
+	  * this request.
+	  */
+	u32 previous_seqno;
+
+	 /** GEM sequence number associated with this request,
+	  * when the HWS breadcrumb is equal or greater than this the GPU
+	  * has finished processing this request.
+	  */
+	u32 seqno;
+
+	/** Position in the ringbuffer of the start of the request */
+	u32 head;
+
+	/**
+	 * Position in the ringbuffer of the start of the postfix.
+	 * This is required to calculate the maximum available ringbuffer
+	 * space without overwriting the postfix.
+	 */
+	 u32 postfix;
+
+	/** Position in the ringbuffer of the end of the whole request */
+	u32 tail;
+
+	/**
+	 * Context and ring buffer related to this request
+	 * Contexts are refcounted, so when this request is associated with a
+	 * context, we must increment the context's refcount, to guarantee that
+	 * it persists while any request is linked to it. Requests themselves
+	 * are also refcounted, so the request will only be freed when the last
+	 * reference to it is dismissed, and the code in
+	 * i915_gem_request_free() will then decrement the refcount on the
+	 * context.
+	 */
+	struct intel_context *ctx;
+	struct intel_ringbuffer *ringbuf;
+
+	/** Batch buffer related to this request if any (used for
+	    error state dump only) */
+	struct drm_i915_gem_object *batch_obj;
+
+	/** Time at which this request was emitted, in jiffies. */
+	unsigned long emitted_jiffies;
+
+	/** global list entry for this request */
+	struct list_head list;
+
+	struct drm_i915_file_private *file_priv;
+	/** file_priv list entry for this request */
+	struct list_head client_list;
+
+	/** process identifier submitting this request */
+	struct pid *pid;
+
+	/**
+	 * The ELSP only accepts two elements at a time, so we queue
+	 * context/tail pairs on a given queue (ring->execlist_queue) until the
+	 * hardware is available. The queue serves a double purpose: we also use
+	 * it to keep track of the up to 2 contexts currently in the hardware
+	 * (usually one in execution and the other queued up by the GPU): We
+	 * only remove elements from the head of the queue when the hardware
+	 * informs us that an element has been completed.
+	 *
+	 * All accesses to the queue are mediated by a spinlock
+	 * (ring->execlist_lock).
+	 */
+
+	/** Execlist link in the submission queue.*/
+	struct list_head execlist_link;
+
+	/** Execlists no. of times this request has been sent to the ELSP */
+	int elsp_submitted;
+
+};
+
+struct drm_i915_gem_request * __must_check
+i915_gem_request_alloc(struct intel_engine_cs *engine,
+		       struct intel_context *ctx);
+void i915_gem_request_free(struct kref *req_ref);
+int i915_gem_request_add_to_client(struct drm_i915_gem_request *req,
+				   struct drm_file *file);
+
+static inline uint32_t
+i915_gem_request_get_seqno(struct drm_i915_gem_request *req)
+{
+	return req ? req->seqno : 0;
+}
+
+static inline struct intel_engine_cs *
+i915_gem_request_get_engine(struct drm_i915_gem_request *req)
+{
+	return req ? req->engine : NULL;
+}
+
+static inline struct drm_i915_gem_request *
+i915_gem_request_reference(struct drm_i915_gem_request *req)
+{
+	if (req)
+		kref_get(&req->ref);
+	return req;
+}
+
+static inline void
+i915_gem_request_unreference(struct drm_i915_gem_request *req)
+{
+	WARN_ON(!mutex_is_locked(&req->engine->dev->struct_mutex));
+	kref_put(&req->ref, i915_gem_request_free);
+}
+
+static inline void
+i915_gem_request_unreference__unlocked(struct drm_i915_gem_request *req)
+{
+	struct drm_device *dev;
+
+	if (!req)
+		return;
+
+	dev = req->engine->dev;
+	if (kref_put_mutex(&req->ref, i915_gem_request_free, &dev->struct_mutex))
+		mutex_unlock(&dev->struct_mutex);
+}
+
+static inline void i915_gem_request_assign(struct drm_i915_gem_request **pdst,
+					   struct drm_i915_gem_request *src)
+{
+	if (src)
+		i915_gem_request_reference(src);
+
+	if (*pdst)
+		i915_gem_request_unreference(*pdst);
+
+	*pdst = src;
+}
+
+/*
+ * XXX: i915_gem_request_completed should be here but currently needs the
+ * definition of i915_seqno_passed() which is below. It will be moved in
+ * a later patch when the call to i915_seqno_passed() is obsoleted...
+ */
+
+/*
+ * A command that requires special handling by the command parser.
+ */
+struct drm_i915_cmd_descriptor {
+	/*
+	 * Flags describing how the command parser processes the command.
+	 *
+	 * CMD_DESC_FIXED: The command has a fixed length if this is set,
+	 *                 a length mask if not set
+	 * CMD_DESC_SKIP: The command is allowed but does not follow the
+	 *                standard length encoding for the opcode range in
+	 *                which it falls
+	 * CMD_DESC_REJECT: The command is never allowed
+	 * CMD_DESC_REGISTER: The command should be checked against the
+	 *                    register whitelist for the appropriate ring
+	 * CMD_DESC_MASTER: The command is allowed if the submitting process
+	 *                  is the DRM master
+	 */
+	u32 flags;
+#define CMD_DESC_FIXED    (1<<0)
+#define CMD_DESC_SKIP     (1<<1)
+#define CMD_DESC_REJECT   (1<<2)
+#define CMD_DESC_REGISTER (1<<3)
+#define CMD_DESC_BITMASK  (1<<4)
+#define CMD_DESC_MASTER   (1<<5)
+
+	/*
+	 * The command's unique identification bits and the bitmask to get them.
+	 * This isn't strictly the opcode field as defined in the spec and may
+	 * also include type, subtype, and/or subop fields.
+	 */
+	struct {
+		u32 value;
+		u32 mask;
+	} cmd;
+
+	/*
+	 * The command's length. The command is either fixed length (i.e. does
+	 * not include a length field) or has a length field mask. The flag
+	 * CMD_DESC_FIXED indicates a fixed length. Otherwise, the command has
+	 * a length mask. All command entries in a command table must include
+	 * length information.
+	 */
+	union {
+		u32 fixed;
+		u32 mask;
+	} length;
+
+	/*
+	 * Describes where to find a register address in the command to check
+	 * against the ring's register whitelist. Only valid if flags has the
+	 * CMD_DESC_REGISTER bit set.
+	 *
+	 * A non-zero step value implies that the command may access multiple
+	 * registers in sequence (e.g. LRI), in that case step gives the
+	 * distance in dwords between individual offset fields.
+	 */
+	struct {
+		u32 offset;
+		u32 mask;
+		u32 step;
+	} reg;
+
+#define MAX_CMD_DESC_BITMASKS 3
+	/*
+	 * Describes command checks where a particular dword is masked and
+	 * compared against an expected value. If the command does not match
+	 * the expected value, the parser rejects it. Only valid if flags has
+	 * the CMD_DESC_BITMASK bit set. Only entries where mask is non-zero
+	 * are valid.
+	 *
+	 * If the check specifies a non-zero condition_mask then the parser
+	 * only performs the check when the bits specified by condition_mask
+	 * are non-zero.
+	 */
+	struct {
+		u32 offset;
+		u32 mask;
+		u32 expected;
+		u32 condition_offset;
+		u32 condition_mask;
+	} bits[MAX_CMD_DESC_BITMASKS];
+};
+
+/*
+ * A table of commands requiring special handling by the command parser.
+ *
+ * Each ring has an array of tables. Each table consists of an array of command
+ * descriptors, which must be sorted with command opcodes in ascending order.
+ */
+struct drm_i915_cmd_table {
+	const struct drm_i915_cmd_descriptor *table;
+	int count;
+};
+
+/* Note that the (struct drm_i915_private *) cast is just to shut up gcc. */
+#define __I915__(p) ({ \
+	struct drm_i915_private *__p; \
+	if (__builtin_types_compatible_p(typeof(*p), struct drm_i915_private)) \
+		__p = (struct drm_i915_private *)p; \
+	else if (__builtin_types_compatible_p(typeof(*p), struct drm_device)) \
+		__p = to_i915((struct drm_device *)p); \
+	else \
+		BUILD_BUG(); \
+	__p; \
+})
+#define INTEL_INFO(p) 	(&__I915__(p)->info)
+#define INTEL_GEN(p)	(INTEL_INFO(p)->gen)
+#define INTEL_DEVID(p)	(INTEL_INFO(p)->device_id)
+#define INTEL_REVID(p)	(__I915__(p)->dev->pdev->revision)
+
+#define REVID_FOREVER		0xff
+/*
+ * Return true if revision is in range [since,until] inclusive.
+ *
+ * Use 0 for open-ended since, and REVID_FOREVER for open-ended until.
+ */
+#define IS_REVID(p, since, until) \
+	(INTEL_REVID(p) >= (since) && INTEL_REVID(p) <= (until))
+
+#define IS_I830(dev)		(INTEL_DEVID(dev) == 0x3577)
+#define IS_845G(dev)		(INTEL_DEVID(dev) == 0x2562)
+#define IS_I85X(dev)		(INTEL_INFO(dev)->is_i85x)
+#define IS_I865G(dev)		(INTEL_DEVID(dev) == 0x2572)
+#define IS_I915G(dev)		(INTEL_INFO(dev)->is_i915g)
+#define IS_I915GM(dev)		(INTEL_DEVID(dev) == 0x2592)
+#define IS_I945G(dev)		(INTEL_DEVID(dev) == 0x2772)
+#define IS_I945GM(dev)		(INTEL_INFO(dev)->is_i945gm)
+#define IS_BROADWATER(dev)	(INTEL_INFO(dev)->is_broadwater)
+#define IS_CRESTLINE(dev)	(INTEL_INFO(dev)->is_crestline)
+#define IS_GM45(dev)		(INTEL_DEVID(dev) == 0x2A42)
+#define IS_G4X(dev)		(INTEL_INFO(dev)->is_g4x)
+#define IS_PINEVIEW_G(dev)	(INTEL_DEVID(dev) == 0xa001)
+#define IS_PINEVIEW_M(dev)	(INTEL_DEVID(dev) == 0xa011)
+#define IS_PINEVIEW(dev)	(INTEL_INFO(dev)->is_pineview)
+#define IS_G33(dev)		(INTEL_INFO(dev)->is_g33)
+#define IS_IRONLAKE_M(dev)	(INTEL_DEVID(dev) == 0x0046)
+#define IS_IVYBRIDGE(dev)	(INTEL_INFO(dev)->is_ivybridge)
+#define IS_IVB_GT1(dev)		(INTEL_DEVID(dev) == 0x0156 || \
+				 INTEL_DEVID(dev) == 0x0152 || \
+				 INTEL_DEVID(dev) == 0x015a)
+#define IS_VALLEYVIEW(dev)	(INTEL_INFO(dev)->is_valleyview)
+#define IS_CHERRYVIEW(dev)	(INTEL_INFO(dev)->is_cherryview)
+#define IS_HASWELL(dev)	(INTEL_INFO(dev)->is_haswell)
+#define IS_BROADWELL(dev)	(!INTEL_INFO(dev)->is_cherryview && IS_GEN8(dev))
+#define IS_SKYLAKE(dev)	(INTEL_INFO(dev)->is_skylake)
+#define IS_BROXTON(dev)		(INTEL_INFO(dev)->is_broxton)
+#define IS_KABYLAKE(dev)	(INTEL_INFO(dev)->is_kabylake)
+#define IS_MOBILE(dev)		(INTEL_INFO(dev)->is_mobile)
+#define IS_HSW_EARLY_SDV(dev)	(IS_HASWELL(dev) && \
+				 (INTEL_DEVID(dev) & 0xFF00) == 0x0C00)
+#define IS_BDW_ULT(dev)		(IS_BROADWELL(dev) && \
+				 ((INTEL_DEVID(dev) & 0xf) == 0x6 ||	\
+				 (INTEL_DEVID(dev) & 0xf) == 0xb ||	\
+				 (INTEL_DEVID(dev) & 0xf) == 0xe))
+/* ULX machines are also considered ULT. */
+#define IS_BDW_ULX(dev)		(IS_BROADWELL(dev) && \
+				 (INTEL_DEVID(dev) & 0xf) == 0xe)
+#define IS_BDW_GT3(dev)		(IS_BROADWELL(dev) && \
+				 (INTEL_DEVID(dev) & 0x00F0) == 0x0020)
+#define IS_HSW_ULT(dev)		(IS_HASWELL(dev) && \
+				 (INTEL_DEVID(dev) & 0xFF00) == 0x0A00)
+#define IS_HSW_GT3(dev)		(IS_HASWELL(dev) && \
+				 (INTEL_DEVID(dev) & 0x00F0) == 0x0020)
+/* ULX machines are also considered ULT. */
+#define IS_HSW_ULX(dev)		(INTEL_DEVID(dev) == 0x0A0E || \
+				 INTEL_DEVID(dev) == 0x0A1E)
+#define IS_SKL_ULT(dev)		(INTEL_DEVID(dev) == 0x1906 || \
+				 INTEL_DEVID(dev) == 0x1913 || \
+				 INTEL_DEVID(dev) == 0x1916 || \
+				 INTEL_DEVID(dev) == 0x1921 || \
+				 INTEL_DEVID(dev) == 0x1926)
+#define IS_SKL_ULX(dev)		(INTEL_DEVID(dev) == 0x190E || \
+				 INTEL_DEVID(dev) == 0x1915 || \
+				 INTEL_DEVID(dev) == 0x191E)
+#define IS_KBL_ULT(dev)		(INTEL_DEVID(dev) == 0x5906 || \
+				 INTEL_DEVID(dev) == 0x5913 || \
+				 INTEL_DEVID(dev) == 0x5916 || \
+				 INTEL_DEVID(dev) == 0x5921 || \
+				 INTEL_DEVID(dev) == 0x5926)
+#define IS_KBL_ULX(dev)		(INTEL_DEVID(dev) == 0x590E || \
+				 INTEL_DEVID(dev) == 0x5915 || \
+				 INTEL_DEVID(dev) == 0x591E)
+#define IS_SKL_GT3(dev)		(IS_SKYLAKE(dev) && \
+				 (INTEL_DEVID(dev) & 0x00F0) == 0x0020)
+#define IS_SKL_GT4(dev)		(IS_SKYLAKE(dev) && \
+				 (INTEL_DEVID(dev) & 0x00F0) == 0x0030)
+
+#define IS_PRELIMINARY_HW(intel_info) ((intel_info)->is_preliminary)
+
+#define SKL_REVID_A0		0x0
+#define SKL_REVID_B0		0x1
+#define SKL_REVID_C0		0x2
+#define SKL_REVID_D0		0x3
+#define SKL_REVID_E0		0x4
+#define SKL_REVID_F0		0x5
+
+#define IS_SKL_REVID(p, since, until) (IS_SKYLAKE(p) && IS_REVID(p, since, until))
+
+#define BXT_REVID_A0		0x0
+#define BXT_REVID_A1		0x1
+#define BXT_REVID_B0		0x3
+#define BXT_REVID_C0		0x9
+
+#define IS_BXT_REVID(p, since, until) (IS_BROXTON(p) && IS_REVID(p, since, until))
+
+#define KBL_REVID_A0		0x0
+#define KBL_REVID_B0		0x1
+#define KBL_REVID_C0		0x2
+#define KBL_REVID_D0		0x3
+#define KBL_REVID_E0		0x4
+
+#define IS_KBL_REVID(p, since, until) \
+	(IS_KABYLAKE(p) && IS_REVID(p, since, until))
+
+/*
+ * The genX designation typically refers to the render engine, so render
+ * capability related checks should use IS_GEN, while display and other checks
+ * have their own (e.g. HAS_PCH_SPLIT for ILK+ display, IS_foo for particular
+ * chips, etc.).
+ */
+#define IS_GEN2(dev)	(INTEL_INFO(dev)->gen == 2)
+#define IS_GEN3(dev)	(INTEL_INFO(dev)->gen == 3)
+#define IS_GEN4(dev)	(INTEL_INFO(dev)->gen == 4)
+#define IS_GEN5(dev)	(INTEL_INFO(dev)->gen == 5)
+#define IS_GEN6(dev)	(INTEL_INFO(dev)->gen == 6)
+#define IS_GEN7(dev)	(INTEL_INFO(dev)->gen == 7)
+#define IS_GEN8(dev)	(INTEL_INFO(dev)->gen == 8)
+#define IS_GEN9(dev)	(INTEL_INFO(dev)->gen == 9)
+
+#define RENDER_RING		(1<<RCS)
+#define BSD_RING		(1<<VCS)
+#define BLT_RING		(1<<BCS)
+#define VEBOX_RING		(1<<VECS)
+#define BSD2_RING		(1<<VCS2)
+#define ALL_ENGINES		(~0)
+
+#define HAS_BSD(dev)		(INTEL_INFO(dev)->ring_mask & BSD_RING)
+#define HAS_BSD2(dev)		(INTEL_INFO(dev)->ring_mask & BSD2_RING)
+#define HAS_BLT(dev)		(INTEL_INFO(dev)->ring_mask & BLT_RING)
+#define HAS_VEBOX(dev)		(INTEL_INFO(dev)->ring_mask & VEBOX_RING)
+#define HAS_LLC(dev)		(INTEL_INFO(dev)->has_llc)
+#define HAS_SNOOP(dev)		(INTEL_INFO(dev)->has_snoop)
+#define HAS_EDRAM(dev)		(__I915__(dev)->edram_cap & EDRAM_ENABLED)
+#define HAS_WT(dev)		((IS_HASWELL(dev) || IS_BROADWELL(dev)) && \
+				 HAS_EDRAM(dev))
+#define I915_NEED_GFX_HWS(dev)	(INTEL_INFO(dev)->need_gfx_hws)
+
+#define HAS_HW_CONTEXTS(dev)	(INTEL_INFO(dev)->gen >= 6)
+#define HAS_LOGICAL_RING_CONTEXTS(dev)	(INTEL_INFO(dev)->gen >= 8)
+#define USES_PPGTT(dev)		(i915.enable_ppgtt)
+#define USES_FULL_PPGTT(dev)	(i915.enable_ppgtt >= 2)
+#define USES_FULL_48BIT_PPGTT(dev)	(i915.enable_ppgtt == 3)
+
+#define HAS_OVERLAY(dev)		(INTEL_INFO(dev)->has_overlay)
+#define OVERLAY_NEEDS_PHYSICAL(dev)	(INTEL_INFO(dev)->overlay_needs_physical)
+
+/* Early gen2 have a totally busted CS tlb and require pinned batches. */
+#define HAS_BROKEN_CS_TLB(dev)		(IS_I830(dev) || IS_845G(dev))
+
+/* WaRsDisableCoarsePowerGating:skl,bxt */
+#define NEEDS_WaRsDisableCoarsePowerGating(dev) (IS_BXT_REVID(dev, 0, BXT_REVID_A1) || \
+						 IS_SKL_GT3(dev) || \
+						 IS_SKL_GT4(dev))
+
+/*
+ * dp aux and gmbus irq on gen4 seems to be able to generate legacy interrupts
+ * even when in MSI mode. This results in spurious interrupt warnings if the
+ * legacy irq no. is shared with another device. The kernel then disables that
+ * interrupt source and so prevents the other device from working properly.
+ */
+#define HAS_AUX_IRQ(dev) (INTEL_INFO(dev)->gen >= 5)
+#define HAS_GMBUS_IRQ(dev) (INTEL_INFO(dev)->gen >= 5)
+
+/* With the 945 and later, Y tiling got adjusted so that it was 32 128-byte
+ * rows, which changed the alignment requirements and fence programming.
+ */
+#define HAS_128_BYTE_Y_TILING(dev) (!IS_GEN2(dev) && !(IS_I915G(dev) || \
+						      IS_I915GM(dev)))
+#define SUPPORTS_TV(dev)		(INTEL_INFO(dev)->supports_tv)
+#define I915_HAS_HOTPLUG(dev)		 (INTEL_INFO(dev)->has_hotplug)
+
+#define HAS_FW_BLC(dev) (INTEL_INFO(dev)->gen > 2)
+#define HAS_PIPE_CXSR(dev) (INTEL_INFO(dev)->has_pipe_cxsr)
+#define HAS_FBC(dev) (INTEL_INFO(dev)->has_fbc)
+
+#define HAS_IPS(dev)		(IS_HSW_ULT(dev) || IS_BROADWELL(dev))
+
+#define HAS_DP_MST(dev)		(IS_HASWELL(dev) || IS_BROADWELL(dev) || \
+				 INTEL_INFO(dev)->gen >= 9)
+
+#define HAS_DDI(dev)		(INTEL_INFO(dev)->has_ddi)
+#define HAS_FPGA_DBG_UNCLAIMED(dev)	(INTEL_INFO(dev)->has_fpga_dbg)
+#define HAS_PSR(dev)		(IS_HASWELL(dev) || IS_BROADWELL(dev) || \
+				 IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev) || \
+				 IS_SKYLAKE(dev) || IS_KABYLAKE(dev))
+#define HAS_RUNTIME_PM(dev)	(IS_GEN6(dev) || IS_HASWELL(dev) || \
+				 IS_BROADWELL(dev) || IS_VALLEYVIEW(dev) || \
+				 IS_CHERRYVIEW(dev) || IS_SKYLAKE(dev) || \
+				 IS_KABYLAKE(dev) || IS_BROXTON(dev))
+#define HAS_RC6(dev)		(INTEL_INFO(dev)->gen >= 6)
+#define HAS_RC6p(dev)		(INTEL_INFO(dev)->gen == 6 || IS_IVYBRIDGE(dev))
+
+#define HAS_CSR(dev)	(IS_GEN9(dev))
+
+#define HAS_GUC_UCODE(dev)	(IS_GEN9(dev) && !IS_KABYLAKE(dev))
+#define HAS_GUC_SCHED(dev)	(IS_GEN9(dev) && !IS_KABYLAKE(dev))
+
+#define HAS_RESOURCE_STREAMER(dev) (IS_HASWELL(dev) || \
+				    INTEL_INFO(dev)->gen >= 8)
+
+#define HAS_CORE_RING_FREQ(dev)	(INTEL_INFO(dev)->gen >= 6 && \
+				 !IS_VALLEYVIEW(dev) && !IS_CHERRYVIEW(dev) && \
+				 !IS_BROXTON(dev))
+
+#define INTEL_PCH_DEVICE_ID_MASK		0xff00
+#define INTEL_PCH_IBX_DEVICE_ID_TYPE		0x3b00
+#define INTEL_PCH_CPT_DEVICE_ID_TYPE		0x1c00
+#define INTEL_PCH_PPT_DEVICE_ID_TYPE		0x1e00
+#define INTEL_PCH_LPT_DEVICE_ID_TYPE		0x8c00
+#define INTEL_PCH_LPT_LP_DEVICE_ID_TYPE		0x9c00
+#define INTEL_PCH_SPT_DEVICE_ID_TYPE		0xA100
+#define INTEL_PCH_SPT_LP_DEVICE_ID_TYPE		0x9D00
+#define INTEL_PCH_KBP_DEVICE_ID_TYPE		0xA200
+#define INTEL_PCH_P2X_DEVICE_ID_TYPE		0x7100
+#define INTEL_PCH_P3X_DEVICE_ID_TYPE		0x7000
+#define INTEL_PCH_QEMU_DEVICE_ID_TYPE		0x2900 /* qemu q35 has 2918 */
+
+#define INTEL_PCH_TYPE(dev) (__I915__(dev)->pch_type)
+#define HAS_PCH_KBP(dev) (INTEL_PCH_TYPE(dev) == PCH_KBP)
+#define HAS_PCH_SPT(dev) (INTEL_PCH_TYPE(dev) == PCH_SPT)
+#define HAS_PCH_LPT(dev) (INTEL_PCH_TYPE(dev) == PCH_LPT)
+#define HAS_PCH_LPT_LP(dev) (__I915__(dev)->pch_id == INTEL_PCH_LPT_LP_DEVICE_ID_TYPE)
+#define HAS_PCH_LPT_H(dev) (__I915__(dev)->pch_id == INTEL_PCH_LPT_DEVICE_ID_TYPE)
+#define HAS_PCH_CPT(dev) (INTEL_PCH_TYPE(dev) == PCH_CPT)
+#define HAS_PCH_IBX(dev) (INTEL_PCH_TYPE(dev) == PCH_IBX)
+#define HAS_PCH_NOP(dev) (INTEL_PCH_TYPE(dev) == PCH_NOP)
+#define HAS_PCH_SPLIT(dev) (INTEL_PCH_TYPE(dev) != PCH_NONE)
+
+#define HAS_GMCH_DISPLAY(dev) (INTEL_INFO(dev)->gen < 5 || \
+			       IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev))
+
+/* DPF == dynamic parity feature */
+#define HAS_L3_DPF(dev) (IS_IVYBRIDGE(dev) || IS_HASWELL(dev))
+#define NUM_L3_SLICES(dev) (IS_HSW_GT3(dev) ? 2 : HAS_L3_DPF(dev))
+
+#define GT_FREQUENCY_MULTIPLIER 50
+#define GEN9_FREQ_SCALER 3
+
+#include "i915_trace.h"
+
+extern const struct drm_ioctl_desc i915_ioctls[];
+extern int i915_max_ioctl;
+
+extern int i915_suspend_switcheroo(struct drm_device *dev, pm_message_t state);
+extern int i915_resume_switcheroo(struct drm_device *dev);
+
+/* i915_dma.c */
+void __printf(3, 4)
+__i915_printk(struct drm_i915_private *dev_priv, const char *level,
+	      const char *fmt, ...);
+
+#define i915_report_error(dev_priv, fmt, ...)				   \
+	__i915_printk(dev_priv, KERN_ERR, fmt, ##__VA_ARGS__)
+
+extern int i915_driver_load(struct drm_device *, unsigned long flags);
+extern int i915_driver_unload(struct drm_device *);
+extern int i915_driver_open(struct drm_device *dev, struct drm_file *file);
+extern void i915_driver_lastclose(struct drm_device * dev);
+extern void i915_driver_preclose(struct drm_device *dev,
+				 struct drm_file *file);
+extern void i915_driver_postclose(struct drm_device *dev,
+				  struct drm_file *file);
+#ifdef CONFIG_COMPAT
+extern long i915_compat_ioctl(struct file *filp, unsigned int cmd,
+			      unsigned long arg);
+#endif
+extern int intel_gpu_reset(struct drm_device *dev, u32 engine_mask);
+extern bool intel_has_gpu_reset(struct drm_device *dev);
+extern int i915_reset(struct drm_device *dev);
+extern int intel_guc_reset(struct drm_i915_private *dev_priv);
+extern void intel_engine_init_hangcheck(struct intel_engine_cs *engine);
+extern unsigned long i915_chipset_val(struct drm_i915_private *dev_priv);
+extern unsigned long i915_mch_val(struct drm_i915_private *dev_priv);
+extern unsigned long i915_gfx_val(struct drm_i915_private *dev_priv);
+extern void i915_update_gfx_val(struct drm_i915_private *dev_priv);
+int vlv_force_gfx_clock(struct drm_i915_private *dev_priv, bool on);
+
+/* intel_hotplug.c */
+void intel_hpd_irq_handler(struct drm_device *dev, u32 pin_mask, u32 long_mask);
+void intel_hpd_init(struct drm_i915_private *dev_priv);
+void intel_hpd_init_work(struct drm_i915_private *dev_priv);
+void intel_hpd_cancel_work(struct drm_i915_private *dev_priv);
+bool intel_hpd_pin_to_port(enum hpd_pin pin, enum port *port);
+
+/* i915_irq.c */
+void i915_queue_hangcheck(struct drm_device *dev);
+__printf(3, 4)
+void i915_handle_error(struct drm_device *dev, u32 engine_mask,
+		       const char *fmt, ...);
+
+extern void intel_irq_init(struct drm_i915_private *dev_priv);
+int intel_irq_install(struct drm_i915_private *dev_priv);
+void intel_irq_uninstall(struct drm_i915_private *dev_priv);
+
+extern void intel_uncore_sanitize(struct drm_device *dev);
+extern void intel_uncore_early_sanitize(struct drm_device *dev,
+					bool restore_forcewake);
+extern void intel_uncore_init(struct drm_device *dev);
+extern bool intel_uncore_unclaimed_mmio(struct drm_i915_private *dev_priv);
+extern bool intel_uncore_arm_unclaimed_mmio_detection(struct drm_i915_private *dev_priv);
+extern void intel_uncore_fini(struct drm_device *dev);
+extern void intel_uncore_forcewake_reset(struct drm_device *dev, bool restore);
+const char *intel_uncore_forcewake_domain_to_str(const enum forcewake_domain_id id);
+void intel_uncore_forcewake_get(struct drm_i915_private *dev_priv,
+				enum forcewake_domains domains);
+void intel_uncore_forcewake_put(struct drm_i915_private *dev_priv,
+				enum forcewake_domains domains);
+/* Like above but the caller must manage the uncore.lock itself.
+ * Must be used with I915_READ_FW and friends.
+ */
+void intel_uncore_forcewake_get__locked(struct drm_i915_private *dev_priv,
+					enum forcewake_domains domains);
+void intel_uncore_forcewake_put__locked(struct drm_i915_private *dev_priv,
+					enum forcewake_domains domains);
+u64 intel_uncore_edram_size(struct drm_i915_private *dev_priv);
+
+void assert_forcewakes_inactive(struct drm_i915_private *dev_priv);
+static inline bool intel_vgpu_active(struct drm_device *dev)
+{
+	return to_i915(dev)->vgpu.active;
+}
+
+void
+i915_enable_pipestat(struct drm_i915_private *dev_priv, enum pipe pipe,
+		     u32 status_mask);
+
+void
+i915_disable_pipestat(struct drm_i915_private *dev_priv, enum pipe pipe,
+		      u32 status_mask);
+
+void valleyview_enable_display_irqs(struct drm_i915_private *dev_priv);
+void valleyview_disable_display_irqs(struct drm_i915_private *dev_priv);
+void i915_hotplug_interrupt_update(struct drm_i915_private *dev_priv,
+				   uint32_t mask,
+				   uint32_t bits);
+void ilk_update_display_irq(struct drm_i915_private *dev_priv,
+			    uint32_t interrupt_mask,
+			    uint32_t enabled_irq_mask);
+static inline void
+ilk_enable_display_irq(struct drm_i915_private *dev_priv, uint32_t bits)
+{
+	ilk_update_display_irq(dev_priv, bits, bits);
+}
+static inline void
+ilk_disable_display_irq(struct drm_i915_private *dev_priv, uint32_t bits)
+{
+	ilk_update_display_irq(dev_priv, bits, 0);
+}
+void bdw_update_pipe_irq(struct drm_i915_private *dev_priv,
+			 enum pipe pipe,
+			 uint32_t interrupt_mask,
+			 uint32_t enabled_irq_mask);
+static inline void bdw_enable_pipe_irq(struct drm_i915_private *dev_priv,
+				       enum pipe pipe, uint32_t bits)
+{
+	bdw_update_pipe_irq(dev_priv, pipe, bits, bits);
+}
+static inline void bdw_disable_pipe_irq(struct drm_i915_private *dev_priv,
+					enum pipe pipe, uint32_t bits)
+{
+	bdw_update_pipe_irq(dev_priv, pipe, bits, 0);
+}
+void ibx_display_interrupt_update(struct drm_i915_private *dev_priv,
+				  uint32_t interrupt_mask,
+				  uint32_t enabled_irq_mask);
+static inline void
+ibx_enable_display_interrupt(struct drm_i915_private *dev_priv, uint32_t bits)
+{
+	ibx_display_interrupt_update(dev_priv, bits, bits);
+}
+static inline void
+ibx_disable_display_interrupt(struct drm_i915_private *dev_priv, uint32_t bits)
+{
+	ibx_display_interrupt_update(dev_priv, bits, 0);
+}
+
+
+/* i915_gem.c */
+int i915_gem_create_ioctl(struct drm_device *dev, void *data,
+			  struct drm_file *file_priv);
+int i915_gem_pread_ioctl(struct drm_device *dev, void *data,
+			 struct drm_file *file_priv);
+int i915_gem_pwrite_ioctl(struct drm_device *dev, void *data,
+			  struct drm_file *file_priv);
+int i915_gem_mmap_ioctl(struct drm_device *dev, void *data,
+			struct drm_file *file_priv);
+int i915_gem_mmap_gtt_ioctl(struct drm_device *dev, void *data,
+			struct drm_file *file_priv);
+int i915_gem_set_domain_ioctl(struct drm_device *dev, void *data,
+			      struct drm_file *file_priv);
+int i915_gem_sw_finish_ioctl(struct drm_device *dev, void *data,
+			     struct drm_file *file_priv);
+void i915_gem_execbuffer_move_to_active(struct list_head *vmas,
+					struct drm_i915_gem_request *req);
+int i915_gem_ringbuffer_submission(struct i915_execbuffer_params *params,
+				   struct drm_i915_gem_execbuffer2 *args,
+				   struct list_head *vmas);
+int i915_gem_execbuffer(struct drm_device *dev, void *data,
+			struct drm_file *file_priv);
+int i915_gem_execbuffer2(struct drm_device *dev, void *data,
+			 struct drm_file *file_priv);
+int i915_gem_busy_ioctl(struct drm_device *dev, void *data,
+			struct drm_file *file_priv);
+int i915_gem_get_caching_ioctl(struct drm_device *dev, void *data,
+			       struct drm_file *file);
+int i915_gem_set_caching_ioctl(struct drm_device *dev, void *data,
+			       struct drm_file *file);
+int i915_gem_throttle_ioctl(struct drm_device *dev, void *data,
+			    struct drm_file *file_priv);
+int i915_gem_madvise_ioctl(struct drm_device *dev, void *data,
+			   struct drm_file *file_priv);
+int i915_gem_set_tiling(struct drm_device *dev, void *data,
+			struct drm_file *file_priv);
+int i915_gem_get_tiling(struct drm_device *dev, void *data,
+			struct drm_file *file_priv);
+int i915_gem_init_userptr(struct drm_device *dev);
+int i915_gem_userptr_ioctl(struct drm_device *dev, void *data,
+			   struct drm_file *file);
+int i915_gem_get_aperture_ioctl(struct drm_device *dev, void *data,
+				struct drm_file *file_priv);
+int i915_gem_wait_ioctl(struct drm_device *dev, void *data,
+			struct drm_file *file_priv);
+void i915_gem_load_init(struct drm_device *dev);
+void i915_gem_load_cleanup(struct drm_device *dev);
+void i915_gem_load_init_fences(struct drm_i915_private *dev_priv);
+void *i915_gem_object_alloc(struct drm_device *dev);
+void i915_gem_object_free(struct drm_i915_gem_object *obj);
+void i915_gem_object_init(struct drm_i915_gem_object *obj,
+			 const struct drm_i915_gem_object_ops *ops);
+struct drm_i915_gem_object *i915_gem_alloc_object(struct drm_device *dev,
+						  size_t size);
+struct drm_i915_gem_object *i915_gem_object_create_from_data(
+		struct drm_device *dev, const void *data, size_t size);
+void i915_gem_free_object(struct drm_gem_object *obj);
+void i915_gem_vma_destroy(struct i915_vma *vma);
+
+/* Flags used by pin/bind&friends. */
+#define PIN_MAPPABLE	(1<<0)
+#define PIN_NONBLOCK	(1<<1)
+#define PIN_GLOBAL	(1<<2)
+#define PIN_OFFSET_BIAS	(1<<3)
+#define PIN_USER	(1<<4)
+#define PIN_UPDATE	(1<<5)
+#define PIN_ZONE_4G	(1<<6)
+#define PIN_HIGH	(1<<7)
+#define PIN_OFFSET_FIXED	(1<<8)
+#define PIN_OFFSET_MASK (~4095)
+int __must_check
+i915_gem_object_pin(struct drm_i915_gem_object *obj,
+		    struct i915_address_space *vm,
+		    uint32_t alignment,
+		    uint64_t flags);
+int __must_check
+i915_gem_object_ggtt_pin(struct drm_i915_gem_object *obj,
+			 const struct i915_ggtt_view *view,
+			 uint32_t alignment,
+			 uint64_t flags);
+
+int i915_vma_bind(struct i915_vma *vma, enum i915_cache_level cache_level,
+		  u32 flags);
+void __i915_vma_set_map_and_fenceable(struct i915_vma *vma);
+int __must_check i915_vma_unbind(struct i915_vma *vma);
+/*
+ * BEWARE: Do not use the function below unless you can _absolutely_
+ * _guarantee_ VMA in question is _not in use_ anywhere.
+ */
+int __must_check __i915_vma_unbind_no_wait(struct i915_vma *vma);
+int i915_gem_object_put_pages(struct drm_i915_gem_object *obj);
+void i915_gem_release_all_mmaps(struct drm_i915_private *dev_priv);
+void i915_gem_release_mmap(struct drm_i915_gem_object *obj);
+
+int i915_gem_obj_prepare_shmem_read(struct drm_i915_gem_object *obj,
+				    int *needs_clflush);
+
+int __must_check i915_gem_object_get_pages(struct drm_i915_gem_object *obj);
+
+static inline int __sg_page_count(struct scatterlist *sg)
+{
+	return sg->length >> PAGE_SHIFT;
+}
+
+struct page *
+i915_gem_object_get_dirty_page(struct drm_i915_gem_object *obj, int n);
+
+static inline struct page *
+i915_gem_object_get_page(struct drm_i915_gem_object *obj, int n)
+{
+	if (WARN_ON(n >= obj->base.size >> PAGE_SHIFT))
+		return NULL;
+
+	if (n < obj->get_page.last) {
+		obj->get_page.sg = obj->pages->sgl;
+		obj->get_page.last = 0;
+	}
+
+	while (obj->get_page.last + __sg_page_count(obj->get_page.sg) <= n) {
+		obj->get_page.last += __sg_page_count(obj->get_page.sg++);
+		if (unlikely(sg_is_chain(obj->get_page.sg)))
+			obj->get_page.sg = sg_chain_ptr(obj->get_page.sg);
+	}
+
+	return nth_page(sg_page(obj->get_page.sg), n - obj->get_page.last);
+}
+
+static inline void i915_gem_object_pin_pages(struct drm_i915_gem_object *obj)
+{
+	BUG_ON(obj->pages == NULL);
+	obj->pages_pin_count++;
+}
+
+static inline void i915_gem_object_unpin_pages(struct drm_i915_gem_object *obj)
+{
+	BUG_ON(obj->pages_pin_count == 0);
+	obj->pages_pin_count--;
+}
+
+/**
+ * i915_gem_object_pin_map - return a contiguous mapping of the entire object
+ * @obj - the object to map into kernel address space
+ *
+ * Calls i915_gem_object_pin_pages() to prevent reaping of the object's
+ * pages and then returns a contiguous mapping of the backing storage into
+ * the kernel address space.
+ *
+ * The caller must hold the struct_mutex, and is responsible for calling
+ * i915_gem_object_unpin_map() when the mapping is no longer required.
+ *
+ * Returns the pointer through which to access the mapped object, or an
+ * ERR_PTR() on error.
+ */
+void *__must_check i915_gem_object_pin_map(struct drm_i915_gem_object *obj);
+
+/**
+ * i915_gem_object_unpin_map - releases an earlier mapping
+ * @obj - the object to unmap
+ *
+ * After pinning the object and mapping its pages, once you are finished
+ * with your access, call i915_gem_object_unpin_map() to release the pin
+ * upon the mapping. Once the pin count reaches zero, that mapping may be
+ * removed.
+ *
+ * The caller must hold the struct_mutex.
+ */
+static inline void i915_gem_object_unpin_map(struct drm_i915_gem_object *obj)
+{
+	lockdep_assert_held(&obj->base.dev->struct_mutex);
+	i915_gem_object_unpin_pages(obj);
+}
+
+int __must_check i915_mutex_lock_interruptible(struct drm_device *dev);
+int i915_gem_object_sync(struct drm_i915_gem_object *obj,
+			 struct intel_engine_cs *to,
+			 struct drm_i915_gem_request **to_req);
+void i915_vma_move_to_active(struct i915_vma *vma,
+			     struct drm_i915_gem_request *req);
+int i915_gem_dumb_create(struct drm_file *file_priv,
+			 struct drm_device *dev,
+			 struct drm_mode_create_dumb *args);
+int i915_gem_mmap_gtt(struct drm_file *file_priv, struct drm_device *dev,
+		      uint32_t handle, uint64_t *offset);
+/**
+ * Returns true if seq1 is later than seq2.
+ */
+static inline bool
+i915_seqno_passed(uint32_t seq1, uint32_t seq2)
+{
+	return (int32_t)(seq1 - seq2) >= 0;
+}
+
+static inline bool i915_gem_request_started(struct drm_i915_gem_request *req,
+					   bool lazy_coherency)
+{
+	if (!lazy_coherency && req->engine->irq_seqno_barrier)
+		req->engine->irq_seqno_barrier(req->engine);
+	return i915_seqno_passed(req->engine->get_seqno(req->engine),
+				 req->previous_seqno);
+}
+
+static inline bool i915_gem_request_completed(struct drm_i915_gem_request *req,
+					      bool lazy_coherency)
+{
+	if (!lazy_coherency && req->engine->irq_seqno_barrier)
+		req->engine->irq_seqno_barrier(req->engine);
+	return i915_seqno_passed(req->engine->get_seqno(req->engine),
+				 req->seqno);
+}
+
+int __must_check i915_gem_get_seqno(struct drm_device *dev, u32 *seqno);
+int __must_check i915_gem_set_seqno(struct drm_device *dev, u32 seqno);
+
+struct drm_i915_gem_request *
+i915_gem_find_active_request(struct intel_engine_cs *engine);
+
+bool i915_gem_retire_requests(struct drm_device *dev);
+void i915_gem_retire_requests_ring(struct intel_engine_cs *engine);
+
+static inline u32 i915_reset_counter(struct i915_gpu_error *error)
+{
+	return atomic_read(&error->reset_counter);
+}
+
+static inline bool __i915_reset_in_progress(u32 reset)
+{
+	return unlikely(reset & I915_RESET_IN_PROGRESS_FLAG);
+}
+
+static inline bool __i915_reset_in_progress_or_wedged(u32 reset)
+{
+	return unlikely(reset & (I915_RESET_IN_PROGRESS_FLAG | I915_WEDGED));
+}
+
+static inline bool __i915_terminally_wedged(u32 reset)
+{
+	return unlikely(reset & I915_WEDGED);
+}
+
+static inline bool i915_reset_in_progress(struct i915_gpu_error *error)
+{
+	return __i915_reset_in_progress(i915_reset_counter(error));
+}
+
+static inline bool i915_reset_in_progress_or_wedged(struct i915_gpu_error *error)
+{
+	return __i915_reset_in_progress_or_wedged(i915_reset_counter(error));
+}
+
+static inline bool i915_terminally_wedged(struct i915_gpu_error *error)
+{
+	return __i915_terminally_wedged(i915_reset_counter(error));
+}
+
+static inline u32 i915_reset_count(struct i915_gpu_error *error)
+{
+	return ((i915_reset_counter(error) & ~I915_WEDGED) + 1) / 2;
+}
+
+static inline bool i915_stop_ring_allow_ban(struct drm_i915_private *dev_priv)
+{
+	return dev_priv->gpu_error.stop_rings == 0 ||
+		dev_priv->gpu_error.stop_rings & I915_STOP_RING_ALLOW_BAN;
+}
+
+static inline bool i915_stop_ring_allow_warn(struct drm_i915_private *dev_priv)
+{
+	return dev_priv->gpu_error.stop_rings == 0 ||
+		dev_priv->gpu_error.stop_rings & I915_STOP_RING_ALLOW_WARN;
+}
+
+void i915_gem_reset(struct drm_device *dev);
+bool i915_gem_clflush_object(struct drm_i915_gem_object *obj, bool force);
+int __must_check i915_gem_init(struct drm_device *dev);
+int i915_gem_init_engines(struct drm_device *dev);
+int __must_check i915_gem_init_hw(struct drm_device *dev);
+int i915_gem_l3_remap(struct drm_i915_gem_request *req, int slice);
+void i915_gem_init_swizzling(struct drm_device *dev);
+void i915_gem_cleanup_engines(struct drm_device *dev);
+int __must_check i915_gpu_idle(struct drm_device *dev);
+int __must_check i915_gem_suspend(struct drm_device *dev);
+void __i915_add_request(struct drm_i915_gem_request *req,
+			struct drm_i915_gem_object *batch_obj,
+			bool flush_caches);
+#define i915_add_request(req) \
+	__i915_add_request(req, NULL, true)
+#define i915_add_request_no_flush(req) \
+	__i915_add_request(req, NULL, false)
+int __i915_wait_request(struct drm_i915_gem_request *req,
+			bool interruptible,
+			s64 *timeout,
+			struct intel_rps_client *rps);
+int __must_check i915_wait_request(struct drm_i915_gem_request *req);
+int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf);
+int __must_check
+i915_gem_object_wait_rendering(struct drm_i915_gem_object *obj,
+			       bool readonly);
+int __must_check
+i915_gem_object_set_to_gtt_domain(struct drm_i915_gem_object *obj,
+				  bool write);
+int __must_check
+i915_gem_object_set_to_cpu_domain(struct drm_i915_gem_object *obj, bool write);
+int __must_check
+i915_gem_object_pin_to_display_plane(struct drm_i915_gem_object *obj,
+				     u32 alignment,
+				     const struct i915_ggtt_view *view);
+void i915_gem_object_unpin_from_display_plane(struct drm_i915_gem_object *obj,
+					      const struct i915_ggtt_view *view);
+int i915_gem_object_attach_phys(struct drm_i915_gem_object *obj,
+				int align);
+int i915_gem_open(struct drm_device *dev, struct drm_file *file);
+void i915_gem_release(struct drm_device *dev, struct drm_file *file);
+
+uint32_t
+i915_gem_get_gtt_size(struct drm_device *dev, uint32_t size, int tiling_mode);
+uint32_t
+i915_gem_get_gtt_alignment(struct drm_device *dev, uint32_t size,
+			    int tiling_mode, bool fenced);
+
+int i915_gem_object_set_cache_level(struct drm_i915_gem_object *obj,
+				    enum i915_cache_level cache_level);
+
+struct drm_gem_object *i915_gem_prime_import(struct drm_device *dev,
+				struct dma_buf *dma_buf);
+
+struct dma_buf *i915_gem_prime_export(struct drm_device *dev,
+				struct drm_gem_object *gem_obj, int flags);
+
+u64 i915_gem_obj_ggtt_offset_view(struct drm_i915_gem_object *o,
+				  const struct i915_ggtt_view *view);
+u64 i915_gem_obj_offset(struct drm_i915_gem_object *o,
+			struct i915_address_space *vm);
+static inline u64
+i915_gem_obj_ggtt_offset(struct drm_i915_gem_object *o)
+{
+	return i915_gem_obj_ggtt_offset_view(o, &i915_ggtt_view_normal);
+}
+
+bool i915_gem_obj_bound_any(struct drm_i915_gem_object *o);
+bool i915_gem_obj_ggtt_bound_view(struct drm_i915_gem_object *o,
+				  const struct i915_ggtt_view *view);
+bool i915_gem_obj_bound(struct drm_i915_gem_object *o,
+			struct i915_address_space *vm);
+
+unsigned long i915_gem_obj_size(struct drm_i915_gem_object *o,
+				struct i915_address_space *vm);
+struct i915_vma *
+i915_gem_obj_to_vma(struct drm_i915_gem_object *obj,
+		    struct i915_address_space *vm);
+struct i915_vma *
+i915_gem_obj_to_ggtt_view(struct drm_i915_gem_object *obj,
+			  const struct i915_ggtt_view *view);
+
+struct i915_vma *
+i915_gem_obj_lookup_or_create_vma(struct drm_i915_gem_object *obj,
+				  struct i915_address_space *vm);
+struct i915_vma *
+i915_gem_obj_lookup_or_create_ggtt_vma(struct drm_i915_gem_object *obj,
+				       const struct i915_ggtt_view *view);
+
+static inline struct i915_vma *
+i915_gem_obj_to_ggtt(struct drm_i915_gem_object *obj)
+{
+	return i915_gem_obj_to_ggtt_view(obj, &i915_ggtt_view_normal);
+}
+bool i915_gem_obj_is_pinned(struct drm_i915_gem_object *obj);
+
+/* Some GGTT VM helpers */
+static inline struct i915_hw_ppgtt *
+i915_vm_to_ppgtt(struct i915_address_space *vm)
+{
+	return container_of(vm, struct i915_hw_ppgtt, base);
+}
+
+
+static inline bool i915_gem_obj_ggtt_bound(struct drm_i915_gem_object *obj)
+{
+	return i915_gem_obj_ggtt_bound_view(obj, &i915_ggtt_view_normal);
+}
+
+static inline unsigned long
+i915_gem_obj_ggtt_size(struct drm_i915_gem_object *obj)
+{
+	struct drm_i915_private *dev_priv = to_i915(obj->base.dev);
+	struct i915_ggtt *ggtt = &dev_priv->ggtt;
+
+	return i915_gem_obj_size(obj, &ggtt->base);
+}
+
+static inline int __must_check
+i915_gem_obj_ggtt_pin(struct drm_i915_gem_object *obj,
+		      uint32_t alignment,
+		      unsigned flags)
+{
+	struct drm_i915_private *dev_priv = to_i915(obj->base.dev);
+	struct i915_ggtt *ggtt = &dev_priv->ggtt;
+
+	return i915_gem_object_pin(obj, &ggtt->base,
+				   alignment, flags | PIN_GLOBAL);
+}
+
+static inline int
+i915_gem_object_ggtt_unbind(struct drm_i915_gem_object *obj)
+{
+	return i915_vma_unbind(i915_gem_obj_to_ggtt(obj));
+}
+
+void i915_gem_object_ggtt_unpin_view(struct drm_i915_gem_object *obj,
+				     const struct i915_ggtt_view *view);
+static inline void
+i915_gem_object_ggtt_unpin(struct drm_i915_gem_object *obj)
+{
+	i915_gem_object_ggtt_unpin_view(obj, &i915_ggtt_view_normal);
+}
+
+/* i915_gem_fence.c */
+int __must_check i915_gem_object_get_fence(struct drm_i915_gem_object *obj);
+int __must_check i915_gem_object_put_fence(struct drm_i915_gem_object *obj);
+
+bool i915_gem_object_pin_fence(struct drm_i915_gem_object *obj);
+void i915_gem_object_unpin_fence(struct drm_i915_gem_object *obj);
+
+void i915_gem_restore_fences(struct drm_device *dev);
+
+void i915_gem_detect_bit_6_swizzle(struct drm_device *dev);
+void i915_gem_object_do_bit_17_swizzle(struct drm_i915_gem_object *obj);
+void i915_gem_object_save_bit_17_swizzle(struct drm_i915_gem_object *obj);
+
+/* i915_gem_context.c */
+int __must_check i915_gem_context_init(struct drm_device *dev);
+void i915_gem_context_fini(struct drm_device *dev);
+void i915_gem_context_reset(struct drm_device *dev);
+int i915_gem_context_open(struct drm_device *dev, struct drm_file *file);
+int i915_gem_context_enable(struct drm_i915_gem_request *req);
+void i915_gem_context_close(struct drm_device *dev, struct drm_file *file);
+int i915_switch_context(struct drm_i915_gem_request *req);
+struct intel_context *
+i915_gem_context_get(struct drm_i915_file_private *file_priv, u32 id);
+void i915_gem_context_free(struct kref *ctx_ref);
+struct drm_i915_gem_object *
+i915_gem_alloc_context_obj(struct drm_device *dev, size_t size);
+static inline void i915_gem_context_reference(struct intel_context *ctx)
+{
+	kref_get(&ctx->ref);
+}
+
+static inline void i915_gem_context_unreference(struct intel_context *ctx)
+{
+	kref_put(&ctx->ref, i915_gem_context_free);
+}
+
+static inline bool i915_gem_context_is_default(const struct intel_context *c)
+{
+	return c->user_handle == DEFAULT_CONTEXT_HANDLE;
+}
+
+int i915_gem_context_create_ioctl(struct drm_device *dev, void *data,
+				  struct drm_file *file);
+int i915_gem_context_destroy_ioctl(struct drm_device *dev, void *data,
+				   struct drm_file *file);
+int i915_gem_context_getparam_ioctl(struct drm_device *dev, void *data,
+				    struct drm_file *file_priv);
+int i915_gem_context_setparam_ioctl(struct drm_device *dev, void *data,
+				    struct drm_file *file_priv);
+
+/* i915_gem_evict.c */
+int __must_check i915_gem_evict_something(struct drm_device *dev,
+					  struct i915_address_space *vm,
+					  int min_size,
+					  unsigned alignment,
+					  unsigned cache_level,
+					  unsigned long start,
+					  unsigned long end,
+					  unsigned flags);
+int __must_check i915_gem_evict_for_vma(struct i915_vma *target);
+int i915_gem_evict_vm(struct i915_address_space *vm, bool do_idle);
+
+/* belongs in i915_gem_gtt.h */
+static inline void i915_gem_chipset_flush(struct drm_device *dev)
+{
+	if (INTEL_INFO(dev)->gen < 6)
+		intel_gtt_chipset_flush();
+}
+
+/* i915_gem_stolen.c */
+int i915_gem_stolen_insert_node(struct drm_i915_private *dev_priv,
+				struct drm_mm_node *node, u64 size,
+				unsigned alignment);
+int i915_gem_stolen_insert_node_in_range(struct drm_i915_private *dev_priv,
+					 struct drm_mm_node *node, u64 size,
+					 unsigned alignment, u64 start,
+					 u64 end);
+void i915_gem_stolen_remove_node(struct drm_i915_private *dev_priv,
+				 struct drm_mm_node *node);
+int i915_gem_init_stolen(struct drm_device *dev);
+void i915_gem_cleanup_stolen(struct drm_device *dev);
+struct drm_i915_gem_object *
+i915_gem_object_create_stolen(struct drm_device *dev, u32 size);
+struct drm_i915_gem_object *
+i915_gem_object_create_stolen_for_preallocated(struct drm_device *dev,
+					       u32 stolen_offset,
+					       u32 gtt_offset,
+					       u32 size);
+
+/* i915_gem_shrinker.c */
+unsigned long i915_gem_shrink(struct drm_i915_private *dev_priv,
+			      unsigned long target,
+			      unsigned flags);
+#define I915_SHRINK_PURGEABLE 0x1
+#define I915_SHRINK_UNBOUND 0x2
+#define I915_SHRINK_BOUND 0x4
+#define I915_SHRINK_ACTIVE 0x8
+unsigned long i915_gem_shrink_all(struct drm_i915_private *dev_priv);
+void i915_gem_shrinker_init(struct drm_i915_private *dev_priv);
+void i915_gem_shrinker_cleanup(struct drm_i915_private *dev_priv);
+
+
+/* i915_gem_tiling.c */
+static inline bool i915_gem_object_needs_bit17_swizzle(struct drm_i915_gem_object *obj)
+{
+	struct drm_i915_private *dev_priv = obj->base.dev->dev_private;
+
+	return dev_priv->mm.bit_6_swizzle_x == I915_BIT_6_SWIZZLE_9_10_17 &&
+		obj->tiling_mode != I915_TILING_NONE;
+}
+
+/* i915_gem_debug.c */
+#if WATCH_LISTS
+int i915_verify_lists(struct drm_device *dev);
+#else
+#define i915_verify_lists(dev) 0
+#endif
+
+/* i915_debugfs.c */
+int i915_debugfs_init(struct drm_minor *minor);
+void i915_debugfs_cleanup(struct drm_minor *minor);
+#ifdef CONFIG_DEBUG_FS
+int i915_debugfs_connector_add(struct drm_connector *connector);
+void intel_display_crc_init(struct drm_device *dev);
+#else
+static inline int i915_debugfs_connector_add(struct drm_connector *connector)
+{ return 0; }
+static inline void intel_display_crc_init(struct drm_device *dev) {}
+#endif
+
+/* i915_gpu_error.c */
+__printf(2, 3)
+void i915_error_printf(struct drm_i915_error_state_buf *e, const char *f, ...);
+int i915_error_state_to_str(struct drm_i915_error_state_buf *estr,
+			    const struct i915_error_state_file_priv *error);
+int i915_error_state_buf_init(struct drm_i915_error_state_buf *eb,
+			      struct drm_i915_private *i915,
+			      size_t count, loff_t pos);
+static inline void i915_error_state_buf_release(
+	struct drm_i915_error_state_buf *eb)
+{
+	kfree(eb->buf);
+}
+void i915_capture_error_state(struct drm_device *dev, u32 engine_mask,
+			      const char *error_msg);
+void i915_error_state_get(struct drm_device *dev,
+			  struct i915_error_state_file_priv *error_priv);
+void i915_error_state_put(struct i915_error_state_file_priv *error_priv);
+void i915_destroy_error_state(struct drm_device *dev);
+
+void i915_get_extra_instdone(struct drm_device *dev, uint32_t *instdone);
+const char *i915_cache_level_str(struct drm_i915_private *i915, int type);
+
+/* i915_cmd_parser.c */
+int i915_cmd_parser_get_version(void);
+int i915_cmd_parser_init_ring(struct intel_engine_cs *engine);
+void i915_cmd_parser_fini_ring(struct intel_engine_cs *engine);
+bool i915_needs_cmd_parser(struct intel_engine_cs *engine);
+int i915_parse_cmds(struct intel_engine_cs *engine,
+		    struct drm_i915_gem_object *batch_obj,
+		    struct drm_i915_gem_object *shadow_batch_obj,
+		    u32 batch_start_offset,
+		    u32 batch_len,
+		    bool is_master);
+
+/* i915_suspend.c */
+extern int i915_save_state(struct drm_device *dev);
+extern int i915_restore_state(struct drm_device *dev);
+
+/* i915_sysfs.c */
+void i915_setup_sysfs(struct drm_device *dev_priv);
+void i915_teardown_sysfs(struct drm_device *dev_priv);
+
+/* intel_i2c.c */
+extern int intel_setup_gmbus(struct drm_device *dev);
+extern void intel_teardown_gmbus(struct drm_device *dev);
+extern bool intel_gmbus_is_valid_pin(struct drm_i915_private *dev_priv,
+				     unsigned int pin);
+
+extern struct i2c_adapter *
+intel_gmbus_get_adapter(struct drm_i915_private *dev_priv, unsigned int pin);
+extern void intel_gmbus_set_speed(struct i2c_adapter *adapter, int speed);
+extern void intel_gmbus_force_bit(struct i2c_adapter *adapter, bool force_bit);
+static inline bool intel_gmbus_is_forced_bit(struct i2c_adapter *adapter)
+{
+	return container_of(adapter, struct intel_gmbus, adapter)->force_bit;
+}
+extern void intel_i2c_reset(struct drm_device *dev);
+
+/* intel_bios.c */
+int intel_bios_init(struct drm_i915_private *dev_priv);
+bool intel_bios_is_valid_vbt(const void *buf, size_t size);
+bool intel_bios_is_tv_present(struct drm_i915_private *dev_priv);
+bool intel_bios_is_lvds_present(struct drm_i915_private *dev_priv, u8 *i2c_pin);
+bool intel_bios_is_port_present(struct drm_i915_private *dev_priv, enum port port);
+bool intel_bios_is_port_edp(struct drm_i915_private *dev_priv, enum port port);
+bool intel_bios_is_port_dp_dual_mode(struct drm_i915_private *dev_priv, enum port port);
+bool intel_bios_is_dsi_present(struct drm_i915_private *dev_priv, enum port *port);
+bool intel_bios_is_port_hpd_inverted(struct drm_i915_private *dev_priv,
+				     enum port port);
+
+/* intel_opregion.c */
+#ifdef CONFIG_ACPI
+extern int intel_opregion_setup(struct drm_device *dev);
+extern void intel_opregion_init(struct drm_device *dev);
+extern void intel_opregion_fini(struct drm_device *dev);
+extern void intel_opregion_asle_intr(struct drm_device *dev);
+extern int intel_opregion_notify_encoder(struct intel_encoder *intel_encoder,
+					 bool enable);
+extern int intel_opregion_notify_adapter(struct drm_device *dev,
+					 pci_power_t state);
+extern int intel_opregion_get_panel_type(struct drm_device *dev);
+#else
+static inline int intel_opregion_setup(struct drm_device *dev) { return 0; }
+static inline void intel_opregion_init(struct drm_device *dev) { return; }
+static inline void intel_opregion_fini(struct drm_device *dev) { return; }
+static inline void intel_opregion_asle_intr(struct drm_device *dev) { return; }
+static inline int
+intel_opregion_notify_encoder(struct intel_encoder *intel_encoder, bool enable)
+{
+	return 0;
+}
+static inline int
+intel_opregion_notify_adapter(struct drm_device *dev, pci_power_t state)
+{
+	return 0;
+}
+static inline int intel_opregion_get_panel_type(struct drm_device *dev)
+{
+	return -ENODEV;
+}
+#endif
+
+/* intel_acpi.c */
+#ifdef CONFIG_ACPI
+extern void intel_register_dsm_handler(void);
+extern void intel_unregister_dsm_handler(void);
+#else
+static inline void intel_register_dsm_handler(void) { return; }
+static inline void intel_unregister_dsm_handler(void) { return; }
+#endif /* CONFIG_ACPI */
+
+/* modesetting */
+extern void intel_modeset_init_hw(struct drm_device *dev);
+extern void intel_modeset_init(struct drm_device *dev);
+extern void intel_modeset_gem_init(struct drm_device *dev);
+extern void intel_modeset_cleanup(struct drm_device *dev);
+extern void intel_connector_unregister(struct intel_connector *);
+extern int intel_modeset_vga_set_state(struct drm_device *dev, bool state);
+extern void intel_display_resume(struct drm_device *dev);
+extern void i915_redisable_vga(struct drm_device *dev);
+extern void i915_redisable_vga_power_on(struct drm_device *dev);
+extern bool ironlake_set_drps(struct drm_device *dev, u8 val);
+extern void intel_init_pch_refclk(struct drm_device *dev);
+extern void intel_set_rps(struct drm_device *dev, u8 val);
+extern void intel_set_memory_cxsr(struct drm_i915_private *dev_priv,
+				  bool enable);
+extern void intel_detect_pch(struct drm_device *dev);
+extern int intel_enable_rc6(const struct drm_device *dev);
+
+extern bool i915_semaphore_is_enabled(struct drm_device *dev);
+int i915_reg_read_ioctl(struct drm_device *dev, void *data,
+			struct drm_file *file);
+int i915_get_reset_stats_ioctl(struct drm_device *dev, void *data,
+			       struct drm_file *file);
+
+/* overlay */
+extern struct intel_overlay_error_state *intel_overlay_capture_error_state(struct drm_device *dev);
+extern void intel_overlay_print_error_state(struct drm_i915_error_state_buf *e,
+					    struct intel_overlay_error_state *error);
+
+extern struct intel_display_error_state *intel_display_capture_error_state(struct drm_device *dev);
+extern void intel_display_print_error_state(struct drm_i915_error_state_buf *e,
+					    struct drm_device *dev,
+					    struct intel_display_error_state *error);
+
+int sandybridge_pcode_read(struct drm_i915_private *dev_priv, u32 mbox, u32 *val);
+int sandybridge_pcode_write(struct drm_i915_private *dev_priv, u32 mbox, u32 val);
+
+/* intel_sideband.c */
+u32 vlv_punit_read(struct drm_i915_private *dev_priv, u32 addr);
+void vlv_punit_write(struct drm_i915_private *dev_priv, u32 addr, u32 val);
+u32 vlv_nc_read(struct drm_i915_private *dev_priv, u8 addr);
+u32 vlv_iosf_sb_read(struct drm_i915_private *dev_priv, u8 port, u32 reg);
+void vlv_iosf_sb_write(struct drm_i915_private *dev_priv, u8 port, u32 reg, u32 val);
+u32 vlv_cck_read(struct drm_i915_private *dev_priv, u32 reg);
+void vlv_cck_write(struct drm_i915_private *dev_priv, u32 reg, u32 val);
+u32 vlv_ccu_read(struct drm_i915_private *dev_priv, u32 reg);
+void vlv_ccu_write(struct drm_i915_private *dev_priv, u32 reg, u32 val);
+u32 vlv_bunit_read(struct drm_i915_private *dev_priv, u32 reg);
+void vlv_bunit_write(struct drm_i915_private *dev_priv, u32 reg, u32 val);
+u32 vlv_dpio_read(struct drm_i915_private *dev_priv, enum pipe pipe, int reg);
+void vlv_dpio_write(struct drm_i915_private *dev_priv, enum pipe pipe, int reg, u32 val);
+u32 intel_sbi_read(struct drm_i915_private *dev_priv, u16 reg,
+		   enum intel_sbi_destination destination);
+void intel_sbi_write(struct drm_i915_private *dev_priv, u16 reg, u32 value,
+		     enum intel_sbi_destination destination);
+u32 vlv_flisdsi_read(struct drm_i915_private *dev_priv, u32 reg);
+void vlv_flisdsi_write(struct drm_i915_private *dev_priv, u32 reg, u32 val);
+
+int intel_gpu_freq(struct drm_i915_private *dev_priv, int val);
+int intel_freq_opcode(struct drm_i915_private *dev_priv, int val);
+
+#define I915_READ8(reg)		dev_priv->uncore.funcs.mmio_readb(dev_priv, (reg), true)
+#define I915_WRITE8(reg, val)	dev_priv->uncore.funcs.mmio_writeb(dev_priv, (reg), (val), true)
+
+#define I915_READ16(reg)	dev_priv->uncore.funcs.mmio_readw(dev_priv, (reg), true)
+#define I915_WRITE16(reg, val)	dev_priv->uncore.funcs.mmio_writew(dev_priv, (reg), (val), true)
+#define I915_READ16_NOTRACE(reg)	dev_priv->uncore.funcs.mmio_readw(dev_priv, (reg), false)
+#define I915_WRITE16_NOTRACE(reg, val)	dev_priv->uncore.funcs.mmio_writew(dev_priv, (reg), (val), false)
+
+#define I915_READ(reg)		dev_priv->uncore.funcs.mmio_readl(dev_priv, (reg), true)
+#define I915_WRITE(reg, val)	dev_priv->uncore.funcs.mmio_writel(dev_priv, (reg), (val), true)
+#define I915_READ_NOTRACE(reg)		dev_priv->uncore.funcs.mmio_readl(dev_priv, (reg), false)
+#define I915_WRITE_NOTRACE(reg, val)	dev_priv->uncore.funcs.mmio_writel(dev_priv, (reg), (val), false)
+
+/* Be very careful with read/write 64-bit values. On 32-bit machines, they
+ * will be implemented using 2 32-bit writes in an arbitrary order with
+ * an arbitrary delay between them. This can cause the hardware to
+ * act upon the intermediate value, possibly leading to corruption and
+ * machine death. You have been warned.
+ */
+#define I915_WRITE64(reg, val)	dev_priv->uncore.funcs.mmio_writeq(dev_priv, (reg), (val), true)
+#define I915_READ64(reg)	dev_priv->uncore.funcs.mmio_readq(dev_priv, (reg), true)
+
+#define I915_READ64_2x32(lower_reg, upper_reg) ({			\
+	u32 upper, lower, old_upper, loop = 0;				\
+	upper = I915_READ(upper_reg);					\
+	do {								\
+		old_upper = upper;					\
+		lower = I915_READ(lower_reg);				\
+		upper = I915_READ(upper_reg);				\
+	} while (upper != old_upper && loop++ < 2);			\
+	(u64)upper << 32 | lower; })
+
+#define POSTING_READ(reg)	(void)I915_READ_NOTRACE(reg)
+#define POSTING_READ16(reg)	(void)I915_READ16_NOTRACE(reg)
+
+#define __raw_read(x, s) \
+static inline uint##x##_t __raw_i915_read##x(struct drm_i915_private *dev_priv, \
+					     i915_reg_t reg) \
+{ \
+	return read##s(dev_priv->regs + i915_mmio_reg_offset(reg)); \
+}
+
+#define __raw_write(x, s) \
+static inline void __raw_i915_write##x(struct drm_i915_private *dev_priv, \
+				       i915_reg_t reg, uint##x##_t val) \
+{ \
+	write##s(val, dev_priv->regs + i915_mmio_reg_offset(reg)); \
+}
+__raw_read(8, b)
+__raw_read(16, w)
+__raw_read(32, l)
+__raw_read(64, q)
+
+__raw_write(8, b)
+__raw_write(16, w)
+__raw_write(32, l)
+__raw_write(64, q)
+
+#undef __raw_read
+#undef __raw_write
+
+/* These are untraced mmio-accessors that are only valid to be used inside
+ * criticial sections inside IRQ handlers where forcewake is explicitly
+ * controlled.
+ * Think twice, and think again, before using these.
+ * Note: Should only be used between intel_uncore_forcewake_irqlock() and
+ * intel_uncore_forcewake_irqunlock().
+ */
+#define I915_READ_FW(reg__) __raw_i915_read32(dev_priv, (reg__))
+#define I915_WRITE_FW(reg__, val__) __raw_i915_write32(dev_priv, (reg__), (val__))
+#define POSTING_READ_FW(reg__) (void)I915_READ_FW(reg__)
+
+/* "Broadcast RGB" property */
+#define INTEL_BROADCAST_RGB_AUTO 0
+#define INTEL_BROADCAST_RGB_FULL 1
+#define INTEL_BROADCAST_RGB_LIMITED 2
+
+static inline i915_reg_t i915_vgacntrl_reg(struct drm_device *dev)
+{
+	if (IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev))
+		return VLV_VGACNTRL;
+	else if (INTEL_INFO(dev)->gen >= 5)
+		return CPU_VGACNTRL;
+	else
+		return VGACNTRL;
+}
+
+static inline void __user *to_user_ptr(u64 address)
+{
+	return (void __user *)(uintptr_t)address;
+}
+
+static inline unsigned long msecs_to_jiffies_timeout(const unsigned int m)
+{
+	unsigned long j = msecs_to_jiffies(m);
+
+	return min_t(unsigned long, MAX_JIFFY_OFFSET, j + 1);
+}
+
+static inline unsigned long nsecs_to_jiffies_timeout(const u64 n)
+{
+        return min_t(u64, MAX_JIFFY_OFFSET, nsecs_to_jiffies64(n) + 1);
+}
+
+static inline unsigned long
+timespec_to_jiffies_timeout(const struct timespec *value)
+{
+	unsigned long j = timespec_to_jiffies(value);
+
+	return min_t(unsigned long, MAX_JIFFY_OFFSET, j + 1);
+}
+
+/*
+ * If you need to wait X milliseconds between events A and B, but event B
+ * doesn't happen exactly after event A, you record the timestamp (jiffies) of
+ * when event A happened, then just before event B you call this function and
+ * pass the timestamp as the first argument, and X as the second argument.
+ */
+static inline void
+wait_remaining_ms_from_jiffies(unsigned long timestamp_jiffies, int to_wait_ms)
+{
+	unsigned long target_jiffies, tmp_jiffies, remaining_jiffies;
+
+	/*
+	 * Don't re-read the value of "jiffies" every time since it may change
+	 * behind our back and break the math.
+	 */
+	tmp_jiffies = jiffies;
+	target_jiffies = timestamp_jiffies +
+			 msecs_to_jiffies_timeout(to_wait_ms);
+
+	if (time_after(target_jiffies, tmp_jiffies)) {
+		remaining_jiffies = target_jiffies - tmp_jiffies;
+		while (remaining_jiffies)
+			remaining_jiffies =
+			    schedule_timeout_uninterruptible(remaining_jiffies);
+	}
+}
+
+static inline void i915_trace_irq_get(struct intel_engine_cs *engine,
+				      struct drm_i915_gem_request *req)
+{
+	if (engine->trace_irq_req == NULL && engine->irq_get(engine))
+		i915_gem_request_assign(&engine->trace_irq_req, req);
+}
+
+#endif
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/i915/i915_gem.c
@@ -0,0 +1,5394 @@
+/*
+ * Copyright © 2008-2015 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Eric Anholt <eric@anholt.net>
+ *
+ */
+
+#include <drm/drmP.h>
+#include <drm/drm_vma_manager.h>
+#include <drm/i915_drm.h>
+#include "i915_drv.h"
+#include "i915_vgpu.h"
+#include "i915_trace.h"
+#include "intel_drv.h"
+#include "intel_mocs.h"
+#include <linux/shmem_fs.h>
+#include <linux/slab.h>
+#include <linux/swap.h>
+#include <linux/pci.h>
+#include <linux/dma-buf.h>
+
+static void i915_gem_object_flush_gtt_write_domain(struct drm_i915_gem_object *obj);
+static void i915_gem_object_flush_cpu_write_domain(struct drm_i915_gem_object *obj);
+static void
+i915_gem_object_retire__write(struct drm_i915_gem_object *obj);
+static void
+i915_gem_object_retire__read(struct drm_i915_gem_object *obj, int ring);
+
+static bool cpu_cache_is_coherent(struct drm_device *dev,
+				  enum i915_cache_level level)
+{
+	return HAS_LLC(dev) || level != I915_CACHE_NONE;
+}
+
+static bool cpu_write_needs_clflush(struct drm_i915_gem_object *obj)
+{
+	if (!cpu_cache_is_coherent(obj->base.dev, obj->cache_level))
+		return true;
+
+	return obj->pin_display;
+}
+
+/* some bookkeeping */
+static void i915_gem_info_add_obj(struct drm_i915_private *dev_priv,
+				  size_t size)
+{
+	spin_lock(&dev_priv->mm.object_stat_lock);
+	dev_priv->mm.object_count++;
+	dev_priv->mm.object_memory += size;
+	spin_unlock(&dev_priv->mm.object_stat_lock);
+}
+
+static void i915_gem_info_remove_obj(struct drm_i915_private *dev_priv,
+				     size_t size)
+{
+	spin_lock(&dev_priv->mm.object_stat_lock);
+	dev_priv->mm.object_count--;
+	dev_priv->mm.object_memory -= size;
+	spin_unlock(&dev_priv->mm.object_stat_lock);
+}
+
+static int
+i915_gem_wait_for_error(struct i915_gpu_error *error)
+{
+	int ret;
+
+	if (!i915_reset_in_progress(error))
+		return 0;
+
+	/*
+	 * Only wait 10 seconds for the gpu reset to complete to avoid hanging
+	 * userspace. If it takes that long something really bad is going on and
+	 * we should simply try to bail out and fail as gracefully as possible.
+	 */
+	ret = wait_event_interruptible_timeout(error->reset_queue,
+					       !i915_reset_in_progress(error),
+					       10*HZ);
+	if (ret == 0) {
+		DRM_ERROR("Timed out waiting for the gpu reset to complete\n");
+		return -EIO;
+	} else if (ret < 0) {
+		return ret;
+	} else {
+		return 0;
+	}
+}
+
+int i915_mutex_lock_interruptible(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	int ret;
+
+	ret = i915_gem_wait_for_error(&dev_priv->gpu_error);
+	if (ret)
+		return ret;
+
+	ret = mutex_lock_interruptible(&dev->struct_mutex);
+	if (ret)
+		return ret;
+
+	WARN_ON(i915_verify_lists(dev));
+	return 0;
+}
+
+int
+i915_gem_get_aperture_ioctl(struct drm_device *dev, void *data,
+			    struct drm_file *file)
+{
+	struct drm_i915_private *dev_priv = to_i915(dev);
+	struct i915_ggtt *ggtt = &dev_priv->ggtt;
+	struct drm_i915_gem_get_aperture *args = data;
+	struct i915_vma *vma;
+	size_t pinned;
+
+	pinned = 0;
+	mutex_lock(&dev->struct_mutex);
+	list_for_each_entry(vma, &ggtt->base.active_list, vm_link)
+		if (vma->pin_count)
+			pinned += vma->node.size;
+	list_for_each_entry(vma, &ggtt->base.inactive_list, vm_link)
+		if (vma->pin_count)
+			pinned += vma->node.size;
+	mutex_unlock(&dev->struct_mutex);
+
+	args->aper_size = ggtt->base.total;
+	args->aper_available_size = args->aper_size - pinned;
+
+	return 0;
+}
+
+static int
+i915_gem_object_get_pages_phys(struct drm_i915_gem_object *obj)
+{
+	struct address_space *mapping = file_inode(obj->base.filp)->i_mapping;
+	char *vaddr = obj->phys_handle->vaddr;
+	struct sg_table *st;
+	struct scatterlist *sg;
+	int i;
+
+	if (WARN_ON(i915_gem_object_needs_bit17_swizzle(obj)))
+		return -EINVAL;
+
+	for (i = 0; i < obj->base.size / PAGE_SIZE; i++) {
+		struct page *page;
+		char *src;
+
+		page = shmem_read_mapping_page(mapping, i);
+		if (IS_ERR(page))
+			return PTR_ERR(page);
+
+		src = kmap_atomic(page);
+		memcpy(vaddr, src, PAGE_SIZE);
+		drm_clflush_virt_range(vaddr, PAGE_SIZE);
+		kunmap_atomic(src);
+
+		put_page(page);
+		vaddr += PAGE_SIZE;
+	}
+
+	i915_gem_chipset_flush(obj->base.dev);
+
+	st = kmalloc(sizeof(*st), GFP_KERNEL);
+	if (st == NULL)
+		return -ENOMEM;
+
+	if (sg_alloc_table(st, 1, GFP_KERNEL)) {
+		kfree(st);
+		return -ENOMEM;
+	}
+
+	sg = st->sgl;
+	sg->offset = 0;
+	sg->length = obj->base.size;
+
+	sg_dma_address(sg) = obj->phys_handle->busaddr;
+	sg_dma_len(sg) = obj->base.size;
+
+	obj->pages = st;
+	return 0;
+}
+
+static void
+i915_gem_object_put_pages_phys(struct drm_i915_gem_object *obj)
+{
+	int ret;
+
+	BUG_ON(obj->madv == __I915_MADV_PURGED);
+
+	ret = i915_gem_object_set_to_cpu_domain(obj, true);
+	if (WARN_ON(ret)) {
+		/* In the event of a disaster, abandon all caches and
+		 * hope for the best.
+		 */
+		obj->base.read_domains = obj->base.write_domain = I915_GEM_DOMAIN_CPU;
+	}
+
+	if (obj->madv == I915_MADV_DONTNEED)
+		obj->dirty = 0;
+
+	if (obj->dirty) {
+		struct address_space *mapping = file_inode(obj->base.filp)->i_mapping;
+		char *vaddr = obj->phys_handle->vaddr;
+		int i;
+
+		for (i = 0; i < obj->base.size / PAGE_SIZE; i++) {
+			struct page *page;
+			char *dst;
+
+			page = shmem_read_mapping_page(mapping, i);
+			if (IS_ERR(page))
+				continue;
+
+			dst = kmap_atomic(page);
+			drm_clflush_virt_range(vaddr, PAGE_SIZE);
+			memcpy(dst, vaddr, PAGE_SIZE);
+			kunmap_atomic(dst);
+
+			set_page_dirty(page);
+			if (obj->madv == I915_MADV_WILLNEED)
+				mark_page_accessed(page);
+			put_page(page);
+			vaddr += PAGE_SIZE;
+		}
+		obj->dirty = 0;
+	}
+
+	sg_free_table(obj->pages);
+	kfree(obj->pages);
+}
+
+static void
+i915_gem_object_release_phys(struct drm_i915_gem_object *obj)
+{
+	drm_pci_free(obj->base.dev, obj->phys_handle);
+}
+
+static const struct drm_i915_gem_object_ops i915_gem_phys_ops = {
+	.get_pages = i915_gem_object_get_pages_phys,
+	.put_pages = i915_gem_object_put_pages_phys,
+	.release = i915_gem_object_release_phys,
+};
+
+static int
+drop_pages(struct drm_i915_gem_object *obj)
+{
+	struct i915_vma *vma, *next;
+	int ret;
+
+	drm_gem_object_reference(&obj->base);
+	list_for_each_entry_safe(vma, next, &obj->vma_list, obj_link)
+		if (i915_vma_unbind(vma))
+			break;
+
+	ret = i915_gem_object_put_pages(obj);
+	drm_gem_object_unreference(&obj->base);
+
+	return ret;
+}
+
+int
+i915_gem_object_attach_phys(struct drm_i915_gem_object *obj,
+			    int align)
+{
+	drm_dma_handle_t *phys;
+	int ret;
+
+	if (obj->phys_handle) {
+		if ((unsigned long)obj->phys_handle->vaddr & (align -1))
+			return -EBUSY;
+
+		return 0;
+	}
+
+	if (obj->madv != I915_MADV_WILLNEED)
+		return -EFAULT;
+
+	if (obj->base.filp == NULL)
+		return -EINVAL;
+
+	ret = drop_pages(obj);
+	if (ret)
+		return ret;
+
+	/* create a new object */
+	phys = drm_pci_alloc(obj->base.dev, obj->base.size, align);
+	if (!phys)
+		return -ENOMEM;
+
+	obj->phys_handle = phys;
+	obj->ops = &i915_gem_phys_ops;
+
+	return i915_gem_object_get_pages(obj);
+}
+
+static int
+i915_gem_phys_pwrite(struct drm_i915_gem_object *obj,
+		     struct drm_i915_gem_pwrite *args,
+		     struct drm_file *file_priv)
+{
+	struct drm_device *dev = obj->base.dev;
+	void *vaddr = obj->phys_handle->vaddr + args->offset;
+	char __user *user_data = to_user_ptr(args->data_ptr);
+	int ret = 0;
+
+	/* We manually control the domain here and pretend that it
+	 * remains coherent i.e. in the GTT domain, like shmem_pwrite.
+	 */
+	ret = i915_gem_object_wait_rendering(obj, false);
+	if (ret)
+		return ret;
+
+	intel_fb_obj_invalidate(obj, ORIGIN_CPU);
+	if (__copy_from_user_inatomic_nocache(vaddr, user_data, args->size)) {
+		unsigned long unwritten;
+
+		/* The physical object once assigned is fixed for the lifetime
+		 * of the obj, so we can safely drop the lock and continue
+		 * to access vaddr.
+		 */
+		mutex_unlock(&dev->struct_mutex);
+		unwritten = copy_from_user(vaddr, user_data, args->size);
+		mutex_lock(&dev->struct_mutex);
+		if (unwritten) {
+			ret = -EFAULT;
+			goto out;
+		}
+	}
+
+	drm_clflush_virt_range(vaddr, args->size);
+	i915_gem_chipset_flush(dev);
+
+out:
+	intel_fb_obj_flush(obj, false, ORIGIN_CPU);
+	return ret;
+}
+
+void *i915_gem_object_alloc(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	return kmem_cache_zalloc(dev_priv->objects, GFP_KERNEL);
+}
+
+void i915_gem_object_free(struct drm_i915_gem_object *obj)
+{
+	struct drm_i915_private *dev_priv = obj->base.dev->dev_private;
+	kmem_cache_free(dev_priv->objects, obj);
+}
+
+static int
+i915_gem_create(struct drm_file *file,
+		struct drm_device *dev,
+		uint64_t size,
+		uint32_t *handle_p)
+{
+	struct drm_i915_gem_object *obj;
+	int ret;
+	u32 handle;
+
+	size = roundup(size, PAGE_SIZE);
+	if (size == 0)
+		return -EINVAL;
+
+	/* Allocate the new object */
+	obj = i915_gem_alloc_object(dev, size);
+	if (obj == NULL)
+		return -ENOMEM;
+
+	ret = drm_gem_handle_create(file, &obj->base, &handle);
+	/* drop reference from allocate - handle holds it now */
+	drm_gem_object_unreference_unlocked(&obj->base);
+	if (ret)
+		return ret;
+
+	*handle_p = handle;
+	return 0;
+}
+
+int
+i915_gem_dumb_create(struct drm_file *file,
+		     struct drm_device *dev,
+		     struct drm_mode_create_dumb *args)
+{
+	/* have to work out size/pitch and return them */
+	args->pitch = ALIGN(args->width * DIV_ROUND_UP(args->bpp, 8), 64);
+	args->size = args->pitch * args->height;
+	return i915_gem_create(file, dev,
+			       args->size, &args->handle);
+}
+
+/**
+ * Creates a new mm object and returns a handle to it.
+ */
+int
+i915_gem_create_ioctl(struct drm_device *dev, void *data,
+		      struct drm_file *file)
+{
+	struct drm_i915_gem_create *args = data;
+
+	return i915_gem_create(file, dev,
+			       args->size, &args->handle);
+}
+
+static inline int
+__copy_to_user_swizzled(char __user *cpu_vaddr,
+			const char *gpu_vaddr, int gpu_offset,
+			int length)
+{
+	int ret, cpu_offset = 0;
+
+	while (length > 0) {
+		int cacheline_end = ALIGN(gpu_offset + 1, 64);
+		int this_length = min(cacheline_end - gpu_offset, length);
+		int swizzled_gpu_offset = gpu_offset ^ 64;
+
+		ret = __copy_to_user(cpu_vaddr + cpu_offset,
+				     gpu_vaddr + swizzled_gpu_offset,
+				     this_length);
+		if (ret)
+			return ret + length;
+
+		cpu_offset += this_length;
+		gpu_offset += this_length;
+		length -= this_length;
+	}
+
+	return 0;
+}
+
+static inline int
+__copy_from_user_swizzled(char *gpu_vaddr, int gpu_offset,
+			  const char __user *cpu_vaddr,
+			  int length)
+{
+	int ret, cpu_offset = 0;
+
+	while (length > 0) {
+		int cacheline_end = ALIGN(gpu_offset + 1, 64);
+		int this_length = min(cacheline_end - gpu_offset, length);
+		int swizzled_gpu_offset = gpu_offset ^ 64;
+
+		ret = __copy_from_user(gpu_vaddr + swizzled_gpu_offset,
+				       cpu_vaddr + cpu_offset,
+				       this_length);
+		if (ret)
+			return ret + length;
+
+		cpu_offset += this_length;
+		gpu_offset += this_length;
+		length -= this_length;
+	}
+
+	return 0;
+}
+
+/*
+ * Pins the specified object's pages and synchronizes the object with
+ * GPU accesses. Sets needs_clflush to non-zero if the caller should
+ * flush the object from the CPU cache.
+ */
+int i915_gem_obj_prepare_shmem_read(struct drm_i915_gem_object *obj,
+				    int *needs_clflush)
+{
+	int ret;
+
+	*needs_clflush = 0;
+
+	if (WARN_ON((obj->ops->flags & I915_GEM_OBJECT_HAS_STRUCT_PAGE) == 0))
+		return -EINVAL;
+
+	if (!(obj->base.read_domains & I915_GEM_DOMAIN_CPU)) {
+		/* If we're not in the cpu read domain, set ourself into the gtt
+		 * read domain and manually flush cachelines (if required). This
+		 * optimizes for the case when the gpu will dirty the data
+		 * anyway again before the next pread happens. */
+		*needs_clflush = !cpu_cache_is_coherent(obj->base.dev,
+							obj->cache_level);
+		ret = i915_gem_object_wait_rendering(obj, true);
+		if (ret)
+			return ret;
+	}
+
+	ret = i915_gem_object_get_pages(obj);
+	if (ret)
+		return ret;
+
+	i915_gem_object_pin_pages(obj);
+
+	return ret;
+}
+
+/* Per-page copy function for the shmem pread fastpath.
+ * Flushes invalid cachelines before reading the target if
+ * needs_clflush is set. */
+static int
+shmem_pread_fast(struct page *page, int shmem_page_offset, int page_length,
+		 char __user *user_data,
+		 bool page_do_bit17_swizzling, bool needs_clflush)
+{
+	char *vaddr;
+	int ret;
+
+	if (unlikely(page_do_bit17_swizzling))
+		return -EINVAL;
+
+	vaddr = kmap_atomic(page);
+	if (needs_clflush)
+		drm_clflush_virt_range(vaddr + shmem_page_offset,
+				       page_length);
+	ret = __copy_to_user_inatomic(user_data,
+				      vaddr + shmem_page_offset,
+				      page_length);
+	kunmap_atomic(vaddr);
+
+	return ret ? -EFAULT : 0;
+}
+
+static void
+shmem_clflush_swizzled_range(char *addr, unsigned long length,
+			     bool swizzled)
+{
+	if (unlikely(swizzled)) {
+		unsigned long start = (unsigned long) addr;
+		unsigned long end = (unsigned long) addr + length;
+
+		/* For swizzling simply ensure that we always flush both
+		 * channels. Lame, but simple and it works. Swizzled
+		 * pwrite/pread is far from a hotpath - current userspace
+		 * doesn't use it at all. */
+		start = round_down(start, 128);
+		end = round_up(end, 128);
+
+		drm_clflush_virt_range((void *)start, end - start);
+	} else {
+		drm_clflush_virt_range(addr, length);
+	}
+
+}
+
+/* Only difference to the fast-path function is that this can handle bit17
+ * and uses non-atomic copy and kmap functions. */
+static int
+shmem_pread_slow(struct page *page, int shmem_page_offset, int page_length,
+		 char __user *user_data,
+		 bool page_do_bit17_swizzling, bool needs_clflush)
+{
+	char *vaddr;
+	int ret;
+
+	vaddr = kmap(page);
+	if (needs_clflush)
+		shmem_clflush_swizzled_range(vaddr + shmem_page_offset,
+					     page_length,
+					     page_do_bit17_swizzling);
+
+	if (page_do_bit17_swizzling)
+		ret = __copy_to_user_swizzled(user_data,
+					      vaddr, shmem_page_offset,
+					      page_length);
+	else
+		ret = __copy_to_user(user_data,
+				     vaddr + shmem_page_offset,
+				     page_length);
+	kunmap(page);
+
+	return ret ? - EFAULT : 0;
+}
+
+static int
+i915_gem_shmem_pread(struct drm_device *dev,
+		     struct drm_i915_gem_object *obj,
+		     struct drm_i915_gem_pread *args,
+		     struct drm_file *file)
+{
+	char __user *user_data;
+	ssize_t remain;
+	loff_t offset;
+	int shmem_page_offset, page_length, ret = 0;
+	int obj_do_bit17_swizzling, page_do_bit17_swizzling;
+	int prefaulted = 0;
+	int needs_clflush = 0;
+	struct sg_page_iter sg_iter;
+
+	user_data = to_user_ptr(args->data_ptr);
+	remain = args->size;
+
+	obj_do_bit17_swizzling = i915_gem_object_needs_bit17_swizzle(obj);
+
+	ret = i915_gem_obj_prepare_shmem_read(obj, &needs_clflush);
+	if (ret)
+		return ret;
+
+	offset = args->offset;
+
+	for_each_sg_page(obj->pages->sgl, &sg_iter, obj->pages->nents,
+			 offset >> PAGE_SHIFT) {
+		struct page *page = sg_page_iter_page(&sg_iter);
+
+		if (remain <= 0)
+			break;
+
+		/* Operation in this page
+		 *
+		 * shmem_page_offset = offset within page in shmem file
+		 * page_length = bytes to copy for this page
+		 */
+		shmem_page_offset = offset_in_page(offset);
+		page_length = remain;
+		if ((shmem_page_offset + page_length) > PAGE_SIZE)
+			page_length = PAGE_SIZE - shmem_page_offset;
+
+		page_do_bit17_swizzling = obj_do_bit17_swizzling &&
+			(page_to_phys(page) & (1 << 17)) != 0;
+
+		ret = shmem_pread_fast(page, shmem_page_offset, page_length,
+				       user_data, page_do_bit17_swizzling,
+				       needs_clflush);
+		if (ret == 0)
+			goto next_page;
+
+		mutex_unlock(&dev->struct_mutex);
+
+		if (likely(!i915.prefault_disable) && !prefaulted) {
+			ret = fault_in_multipages_writeable(user_data, remain);
+			/* Userspace is tricking us, but we've already clobbered
+			 * its pages with the prefault and promised to write the
+			 * data up to the first fault. Hence ignore any errors
+			 * and just continue. */
+			(void)ret;
+			prefaulted = 1;
+		}
+
+		ret = shmem_pread_slow(page, shmem_page_offset, page_length,
+				       user_data, page_do_bit17_swizzling,
+				       needs_clflush);
+
+		mutex_lock(&dev->struct_mutex);
+
+		if (ret)
+			goto out;
+
+next_page:
+		remain -= page_length;
+		user_data += page_length;
+		offset += page_length;
+	}
+
+out:
+	i915_gem_object_unpin_pages(obj);
+
+	return ret;
+}
+
+/**
+ * Reads data from the object referenced by handle.
+ *
+ * On error, the contents of *data are undefined.
+ */
+int
+i915_gem_pread_ioctl(struct drm_device *dev, void *data,
+		     struct drm_file *file)
+{
+	struct drm_i915_gem_pread *args = data;
+	struct drm_i915_gem_object *obj;
+	int ret = 0;
+
+	if (args->size == 0)
+		return 0;
+
+	if (!access_ok(VERIFY_WRITE,
+		       to_user_ptr(args->data_ptr),
+		       args->size))
+		return -EFAULT;
+
+	ret = i915_mutex_lock_interruptible(dev);
+	if (ret)
+		return ret;
+
+	obj = to_intel_bo(drm_gem_object_lookup(dev, file, args->handle));
+	if (&obj->base == NULL) {
+		ret = -ENOENT;
+		goto unlock;
+	}
+
+	/* Bounds check source.  */
+	if (args->offset > obj->base.size ||
+	    args->size > obj->base.size - args->offset) {
+		ret = -EINVAL;
+		goto out;
+	}
+
+	/* prime objects have no backing filp to GEM pread/pwrite
+	 * pages from.
+	 */
+	if (!obj->base.filp) {
+		ret = -EINVAL;
+		goto out;
+	}
+
+	trace_i915_gem_object_pread(obj, args->offset, args->size);
+
+	ret = i915_gem_shmem_pread(dev, obj, args, file);
+
+out:
+	drm_gem_object_unreference(&obj->base);
+unlock:
+	mutex_unlock(&dev->struct_mutex);
+	return ret;
+}
+
+/* This is the fast write path which cannot handle
+ * page faults in the source data
+ */
+
+static inline int
+fast_user_write(struct io_mapping *mapping,
+		loff_t page_base, int page_offset,
+		char __user *user_data,
+		int length)
+{
+	void __iomem *vaddr_atomic;
+	void *vaddr;
+	unsigned long unwritten;
+
+	vaddr_atomic = io_mapping_map_atomic_wc(mapping, page_base);
+	/* We can use the cpu mem copy function because this is X86. */
+	vaddr = (void __force*)vaddr_atomic + page_offset;
+	unwritten = __copy_from_user_inatomic_nocache(vaddr,
+						      user_data, length);
+	io_mapping_unmap_atomic(vaddr_atomic);
+	return unwritten;
+}
+
+/**
+ * This is the fast pwrite path, where we copy the data directly from the
+ * user into the GTT, uncached.
+ */
+static int
+i915_gem_gtt_pwrite_fast(struct drm_device *dev,
+			 struct drm_i915_gem_object *obj,
+			 struct drm_i915_gem_pwrite *args,
+			 struct drm_file *file)
+{
+	struct drm_i915_private *dev_priv = to_i915(dev);
+	struct i915_ggtt *ggtt = &dev_priv->ggtt;
+	ssize_t remain;
+	loff_t offset, page_base;
+	char __user *user_data;
+	int page_offset, page_length, ret;
+
+	ret = i915_gem_obj_ggtt_pin(obj, 0, PIN_MAPPABLE | PIN_NONBLOCK);
+	if (ret)
+		goto out;
+
+	ret = i915_gem_object_set_to_gtt_domain(obj, true);
+	if (ret)
+		goto out_unpin;
+
+	ret = i915_gem_object_put_fence(obj);
+	if (ret)
+		goto out_unpin;
+
+	user_data = to_user_ptr(args->data_ptr);
+	remain = args->size;
+
+	offset = i915_gem_obj_ggtt_offset(obj) + args->offset;
+
+	intel_fb_obj_invalidate(obj, ORIGIN_GTT);
+
+	while (remain > 0) {
+		/* Operation in this page
+		 *
+		 * page_base = page offset within aperture
+		 * page_offset = offset within page
+		 * page_length = bytes to copy for this page
+		 */
+		page_base = offset & PAGE_MASK;
+		page_offset = offset_in_page(offset);
+		page_length = remain;
+		if ((page_offset + remain) > PAGE_SIZE)
+			page_length = PAGE_SIZE - page_offset;
+
+		/* If we get a fault while copying data, then (presumably) our
+		 * source page isn't available.  Return the error and we'll
+		 * retry in the slow path.
+		 */
+		if (fast_user_write(ggtt->mappable, page_base,
+				    page_offset, user_data, page_length)) {
+			ret = -EFAULT;
+			goto out_flush;
+		}
+
+		remain -= page_length;
+		user_data += page_length;
+		offset += page_length;
+	}
+
+out_flush:
+	intel_fb_obj_flush(obj, false, ORIGIN_GTT);
+out_unpin:
+	i915_gem_object_ggtt_unpin(obj);
+out:
+	return ret;
+}
+
+/* Per-page copy function for the shmem pwrite fastpath.
+ * Flushes invalid cachelines before writing to the target if
+ * needs_clflush_before is set and flushes out any written cachelines after
+ * writing if needs_clflush is set. */
+static int
+shmem_pwrite_fast(struct page *page, int shmem_page_offset, int page_length,
+		  char __user *user_data,
+		  bool page_do_bit17_swizzling,
+		  bool needs_clflush_before,
+		  bool needs_clflush_after)
+{
+	char *vaddr;
+	int ret;
+
+	if (unlikely(page_do_bit17_swizzling))
+		return -EINVAL;
+
+	vaddr = kmap_atomic(page);
+	if (needs_clflush_before)
+		drm_clflush_virt_range(vaddr + shmem_page_offset,
+				       page_length);
+	ret = __copy_from_user_inatomic(vaddr + shmem_page_offset,
+					user_data, page_length);
+	if (needs_clflush_after)
+		drm_clflush_virt_range(vaddr + shmem_page_offset,
+				       page_length);
+	kunmap_atomic(vaddr);
+
+	return ret ? -EFAULT : 0;
+}
+
+/* Only difference to the fast-path function is that this can handle bit17
+ * and uses non-atomic copy and kmap functions. */
+static int
+shmem_pwrite_slow(struct page *page, int shmem_page_offset, int page_length,
+		  char __user *user_data,
+		  bool page_do_bit17_swizzling,
+		  bool needs_clflush_before,
+		  bool needs_clflush_after)
+{
+	char *vaddr;
+	int ret;
+
+	vaddr = kmap(page);
+	if (unlikely(needs_clflush_before || page_do_bit17_swizzling))
+		shmem_clflush_swizzled_range(vaddr + shmem_page_offset,
+					     page_length,
+					     page_do_bit17_swizzling);
+	if (page_do_bit17_swizzling)
+		ret = __copy_from_user_swizzled(vaddr, shmem_page_offset,
+						user_data,
+						page_length);
+	else
+		ret = __copy_from_user(vaddr + shmem_page_offset,
+				       user_data,
+				       page_length);
+	if (needs_clflush_after)
+		shmem_clflush_swizzled_range(vaddr + shmem_page_offset,
+					     page_length,
+					     page_do_bit17_swizzling);
+	kunmap(page);
+
+	return ret ? -EFAULT : 0;
+}
+
+static int
+i915_gem_shmem_pwrite(struct drm_device *dev,
+		      struct drm_i915_gem_object *obj,
+		      struct drm_i915_gem_pwrite *args,
+		      struct drm_file *file)
+{
+	ssize_t remain;
+	loff_t offset;
+	char __user *user_data;
+	int shmem_page_offset, page_length, ret = 0;
+	int obj_do_bit17_swizzling, page_do_bit17_swizzling;
+	int hit_slowpath = 0;
+	int needs_clflush_after = 0;
+	int needs_clflush_before = 0;
+	struct sg_page_iter sg_iter;
+
+	user_data = to_user_ptr(args->data_ptr);
+	remain = args->size;
+
+	obj_do_bit17_swizzling = i915_gem_object_needs_bit17_swizzle(obj);
+
+	if (obj->base.write_domain != I915_GEM_DOMAIN_CPU) {
+		/* If we're not in the cpu write domain, set ourself into the gtt
+		 * write domain and manually flush cachelines (if required). This
+		 * optimizes for the case when the gpu will use the data
+		 * right away and we therefore have to clflush anyway. */
+		needs_clflush_after = cpu_write_needs_clflush(obj);
+		ret = i915_gem_object_wait_rendering(obj, false);
+		if (ret)
+			return ret;
+	}
+	/* Same trick applies to invalidate partially written cachelines read
+	 * before writing. */
+	if ((obj->base.read_domains & I915_GEM_DOMAIN_CPU) == 0)
+		needs_clflush_before =
+			!cpu_cache_is_coherent(dev, obj->cache_level);
+
+	ret = i915_gem_object_get_pages(obj);
+	if (ret)
+		return ret;
+
+	intel_fb_obj_invalidate(obj, ORIGIN_CPU);
+
+	i915_gem_object_pin_pages(obj);
+
+	offset = args->offset;
+	obj->dirty = 1;
+
+	for_each_sg_page(obj->pages->sgl, &sg_iter, obj->pages->nents,
+			 offset >> PAGE_SHIFT) {
+		struct page *page = sg_page_iter_page(&sg_iter);
+		int partial_cacheline_write;
+
+		if (remain <= 0)
+			break;
+
+		/* Operation in this page
+		 *
+		 * shmem_page_offset = offset within page in shmem file
+		 * page_length = bytes to copy for this page
+		 */
+		shmem_page_offset = offset_in_page(offset);
+
+		page_length = remain;
+		if ((shmem_page_offset + page_length) > PAGE_SIZE)
+			page_length = PAGE_SIZE - shmem_page_offset;
+
+		/* If we don't overwrite a cacheline completely we need to be
+		 * careful to have up-to-date data by first clflushing. Don't
+		 * overcomplicate things and flush the entire patch. */
+		partial_cacheline_write = needs_clflush_before &&
+			((shmem_page_offset | page_length)
+				& (boot_cpu_data.x86_clflush_size - 1));
+
+		page_do_bit17_swizzling = obj_do_bit17_swizzling &&
+			(page_to_phys(page) & (1 << 17)) != 0;
+
+		ret = shmem_pwrite_fast(page, shmem_page_offset, page_length,
+					user_data, page_do_bit17_swizzling,
+					partial_cacheline_write,
+					needs_clflush_after);
+		if (ret == 0)
+			goto next_page;
+
+		hit_slowpath = 1;
+		mutex_unlock(&dev->struct_mutex);
+		ret = shmem_pwrite_slow(page, shmem_page_offset, page_length,
+					user_data, page_do_bit17_swizzling,
+					partial_cacheline_write,
+					needs_clflush_after);
+
+		mutex_lock(&dev->struct_mutex);
+
+		if (ret)
+			goto out;
+
+next_page:
+		remain -= page_length;
+		user_data += page_length;
+		offset += page_length;
+	}
+
+out:
+	i915_gem_object_unpin_pages(obj);
+
+	if (hit_slowpath) {
+		/*
+		 * Fixup: Flush cpu caches in case we didn't flush the dirty
+		 * cachelines in-line while writing and the object moved
+		 * out of the cpu write domain while we've dropped the lock.
+		 */
+		if (!needs_clflush_after &&
+		    obj->base.write_domain != I915_GEM_DOMAIN_CPU) {
+			if (i915_gem_clflush_object(obj, obj->pin_display))
+				needs_clflush_after = true;
+		}
+	}
+
+	if (needs_clflush_after)
+		i915_gem_chipset_flush(dev);
+	else
+		obj->cache_dirty = true;
+
+	intel_fb_obj_flush(obj, false, ORIGIN_CPU);
+	return ret;
+}
+
+/**
+ * Writes data to the object referenced by handle.
+ *
+ * On error, the contents of the buffer that were to be modified are undefined.
+ */
+int
+i915_gem_pwrite_ioctl(struct drm_device *dev, void *data,
+		      struct drm_file *file)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct drm_i915_gem_pwrite *args = data;
+	struct drm_i915_gem_object *obj;
+	int ret;
+
+	if (args->size == 0)
+		return 0;
+
+	if (!access_ok(VERIFY_READ,
+		       to_user_ptr(args->data_ptr),
+		       args->size))
+		return -EFAULT;
+
+	if (likely(!i915.prefault_disable)) {
+		ret = fault_in_multipages_readable(to_user_ptr(args->data_ptr),
+						   args->size);
+		if (ret)
+			return -EFAULT;
+	}
+
+	intel_runtime_pm_get(dev_priv);
+
+	ret = i915_mutex_lock_interruptible(dev);
+	if (ret)
+		goto put_rpm;
+
+	obj = to_intel_bo(drm_gem_object_lookup(dev, file, args->handle));
+	if (&obj->base == NULL) {
+		ret = -ENOENT;
+		goto unlock;
+	}
+
+	/* Bounds check destination. */
+	if (args->offset > obj->base.size ||
+	    args->size > obj->base.size - args->offset) {
+		ret = -EINVAL;
+		goto out;
+	}
+
+	/* prime objects have no backing filp to GEM pread/pwrite
+	 * pages from.
+	 */
+	if (!obj->base.filp) {
+		ret = -EINVAL;
+		goto out;
+	}
+
+	trace_i915_gem_object_pwrite(obj, args->offset, args->size);
+
+	ret = -EFAULT;
+	/* We can only do the GTT pwrite on untiled buffers, as otherwise
+	 * it would end up going through the fenced access, and we'll get
+	 * different detiling behavior between reading and writing.
+	 * pread/pwrite currently are reading and writing from the CPU
+	 * perspective, requiring manual detiling by the client.
+	 */
+	if (obj->tiling_mode == I915_TILING_NONE &&
+	    obj->base.write_domain != I915_GEM_DOMAIN_CPU &&
+	    cpu_write_needs_clflush(obj)) {
+		ret = i915_gem_gtt_pwrite_fast(dev, obj, args, file);
+		/* Note that the gtt paths might fail with non-page-backed user
+		 * pointers (e.g. gtt mappings when moving data between
+		 * textures). Fallback to the shmem path in that case. */
+	}
+
+	if (ret == -EFAULT || ret == -ENOSPC) {
+		if (obj->phys_handle)
+			ret = i915_gem_phys_pwrite(obj, args, file);
+		else
+			ret = i915_gem_shmem_pwrite(dev, obj, args, file);
+	}
+
+out:
+	drm_gem_object_unreference(&obj->base);
+unlock:
+	mutex_unlock(&dev->struct_mutex);
+put_rpm:
+	intel_runtime_pm_put(dev_priv);
+
+	return ret;
+}
+
+static int
+i915_gem_check_wedge(unsigned reset_counter, bool interruptible)
+{
+	if (__i915_terminally_wedged(reset_counter))
+		return -EIO;
+
+	if (__i915_reset_in_progress(reset_counter)) {
+		/* Non-interruptible callers can't handle -EAGAIN, hence return
+		 * -EIO unconditionally for these. */
+		if (!interruptible)
+			return -EIO;
+
+		return -EAGAIN;
+	}
+
+	return 0;
+}
+
+static void fake_irq(unsigned long data)
+{
+	wake_up_process((struct task_struct *)data);
+}
+
+static bool missed_irq(struct drm_i915_private *dev_priv,
+		       struct intel_engine_cs *engine)
+{
+	return test_bit(engine->id, &dev_priv->gpu_error.missed_irq_rings);
+}
+
+static unsigned long local_clock_us(unsigned *cpu)
+{
+	unsigned long t;
+
+	/* Cheaply and approximately convert from nanoseconds to microseconds.
+	 * The result and subsequent calculations are also defined in the same
+	 * approximate microseconds units. The principal source of timing
+	 * error here is from the simple truncation.
+	 *
+	 * Note that local_clock() is only defined wrt to the current CPU;
+	 * the comparisons are no longer valid if we switch CPUs. Instead of
+	 * blocking preemption for the entire busywait, we can detect the CPU
+	 * switch and use that as indicator of system load and a reason to
+	 * stop busywaiting, see busywait_stop().
+	 */
+	*cpu = get_cpu();
+	t = local_clock() >> 10;
+	put_cpu();
+
+	return t;
+}
+
+static bool busywait_stop(unsigned long timeout, unsigned cpu)
+{
+	unsigned this_cpu;
+
+	if (time_after(local_clock_us(&this_cpu), timeout))
+		return true;
+
+	return this_cpu != cpu;
+}
+
+static int __i915_spin_request(struct drm_i915_gem_request *req, int state)
+{
+	unsigned long timeout;
+	unsigned cpu;
+
+	/* When waiting for high frequency requests, e.g. during synchronous
+	 * rendering split between the CPU and GPU, the finite amount of time
+	 * required to set up the irq and wait upon it limits the response
+	 * rate. By busywaiting on the request completion for a short while we
+	 * can service the high frequency waits as quick as possible. However,
+	 * if it is a slow request, we want to sleep as quickly as possible.
+	 * The tradeoff between waiting and sleeping is roughly the time it
+	 * takes to sleep on a request, on the order of a microsecond.
+	 */
+
+	if (req->engine->irq_refcount)
+		return -EBUSY;
+
+	/* Only spin if we know the GPU is processing this request */
+	if (!i915_gem_request_started(req, true))
+		return -EAGAIN;
+
+	timeout = local_clock_us(&cpu) + 5;
+	while (!need_resched()) {
+		if (i915_gem_request_completed(req, true))
+			return 0;
+
+		if (signal_pending_state(state, current))
+			break;
+
+		if (busywait_stop(timeout, cpu))
+			break;
+
+		cpu_relax_lowlatency();
+	}
+
+	if (i915_gem_request_completed(req, false))
+		return 0;
+
+	return -EAGAIN;
+}
+
+/**
+ * __i915_wait_request - wait until execution of request has finished
+ * @req: duh!
+ * @interruptible: do an interruptible wait (normally yes)
+ * @timeout: in - how long to wait (NULL forever); out - how much time remaining
+ *
+ * Note: It is of utmost importance that the passed in seqno and reset_counter
+ * values have been read by the caller in an smp safe manner. Where read-side
+ * locks are involved, it is sufficient to read the reset_counter before
+ * unlocking the lock that protects the seqno. For lockless tricks, the
+ * reset_counter _must_ be read before, and an appropriate smp_rmb must be
+ * inserted.
+ *
+ * Returns 0 if the request was found within the alloted time. Else returns the
+ * errno with remaining time filled in timeout argument.
+ */
+int __i915_wait_request(struct drm_i915_gem_request *req,
+			bool interruptible,
+			s64 *timeout,
+			struct intel_rps_client *rps)
+{
+	struct intel_engine_cs *engine = i915_gem_request_get_engine(req);
+	struct drm_device *dev = engine->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	const bool irq_test_in_progress =
+		ACCESS_ONCE(dev_priv->gpu_error.test_irq_rings) & intel_engine_flag(engine);
+	int state = interruptible ? TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE;
+	DEFINE_WAIT(wait);
+	unsigned long timeout_expire;
+	s64 before = 0; /* Only to silence a compiler warning. */
+	int ret;
+
+	WARN(!intel_irqs_enabled(dev_priv), "IRQs disabled");
+
+	if (list_empty(&req->list))
+		return 0;
+
+	if (i915_gem_request_completed(req, true))
+		return 0;
+
+	timeout_expire = 0;
+	if (timeout) {
+		if (WARN_ON(*timeout < 0))
+			return -EINVAL;
+
+		if (*timeout == 0)
+			return -ETIME;
+
+		timeout_expire = jiffies + nsecs_to_jiffies_timeout(*timeout);
+
+		/*
+		 * Record current time in case interrupted by signal, or wedged.
+		 */
+		before = ktime_get_raw_ns();
+	}
+
+	if (INTEL_INFO(dev_priv)->gen >= 6)
+		gen6_rps_boost(dev_priv, rps, req->emitted_jiffies);
+
+	trace_i915_gem_request_wait_begin(req);
+
+	/* Optimistic spin for the next jiffie before touching IRQs */
+	ret = __i915_spin_request(req, state);
+	if (ret == 0)
+		goto out;
+
+	if (!irq_test_in_progress && WARN_ON(!engine->irq_get(engine))) {
+		ret = -ENODEV;
+		goto out;
+	}
+
+	for (;;) {
+		struct timer_list timer;
+
+		prepare_to_wait(&engine->irq_queue, &wait, state);
+
+		/* We need to check whether any gpu reset happened in between
+		 * the request being submitted and now. If a reset has occurred,
+		 * the request is effectively complete (we either are in the
+		 * process of or have discarded the rendering and completely
+		 * reset the GPU. The results of the request are lost and we
+		 * are free to continue on with the original operation.
+		 */
+		if (req->reset_counter != i915_reset_counter(&dev_priv->gpu_error)) {
+			ret = 0;
+			break;
+		}
+
+		if (i915_gem_request_completed(req, false)) {
+			ret = 0;
+			break;
+		}
+
+		if (signal_pending_state(state, current)) {
+			ret = -ERESTARTSYS;
+			break;
+		}
+
+		if (timeout && time_after_eq(jiffies, timeout_expire)) {
+			ret = -ETIME;
+			break;
+		}
+
+		timer.function = NULL;
+		if (timeout || missed_irq(dev_priv, engine)) {
+			unsigned long expire;
+
+			setup_timer_on_stack(&timer, fake_irq, (unsigned long)current);
+			expire = missed_irq(dev_priv, engine) ? jiffies + 1 : timeout_expire;
+			mod_timer(&timer, expire);
+		}
+
+		io_schedule();
+
+		if (timer.function) {
+			del_singleshot_timer_sync(&timer);
+			destroy_timer_on_stack(&timer);
+		}
+	}
+	if (!irq_test_in_progress)
+		engine->irq_put(engine);
+
+	finish_wait(&engine->irq_queue, &wait);
+
+out:
+	trace_i915_gem_request_wait_end(req);
+
+	if (timeout) {
+		s64 tres = *timeout - (ktime_get_raw_ns() - before);
+
+		*timeout = tres < 0 ? 0 : tres;
+
+		/*
+		 * Apparently ktime isn't accurate enough and occasionally has a
+		 * bit of mismatch in the jiffies<->nsecs<->ktime loop. So patch
+		 * things up to make the test happy. We allow up to 1 jiffy.
+		 *
+		 * This is a regrssion from the timespec->ktime conversion.
+		 */
+		if (ret == -ETIME && *timeout < jiffies_to_usecs(1)*1000)
+			*timeout = 0;
+	}
+
+	return ret;
+}
+
+int i915_gem_request_add_to_client(struct drm_i915_gem_request *req,
+				   struct drm_file *file)
+{
+	struct drm_i915_file_private *file_priv;
+
+	WARN_ON(!req || !file || req->file_priv);
+
+	if (!req || !file)
+		return -EINVAL;
+
+	if (req->file_priv)
+		return -EINVAL;
+
+	file_priv = file->driver_priv;
+
+	spin_lock(&file_priv->mm.lock);
+	req->file_priv = file_priv;
+	list_add_tail(&req->client_list, &file_priv->mm.request_list);
+	spin_unlock(&file_priv->mm.lock);
+
+	req->pid = get_pid(task_pid(current));
+
+	return 0;
+}
+
+static inline void
+i915_gem_request_remove_from_client(struct drm_i915_gem_request *request)
+{
+	struct drm_i915_file_private *file_priv = request->file_priv;
+
+	if (!file_priv)
+		return;
+
+	spin_lock(&file_priv->mm.lock);
+	list_del(&request->client_list);
+	request->file_priv = NULL;
+	spin_unlock(&file_priv->mm.lock);
+
+	put_pid(request->pid);
+	request->pid = NULL;
+}
+
+static void i915_gem_request_retire(struct drm_i915_gem_request *request)
+{
+	trace_i915_gem_request_retire(request);
+
+	/* We know the GPU must have read the request to have
+	 * sent us the seqno + interrupt, so use the position
+	 * of tail of the request to update the last known position
+	 * of the GPU head.
+	 *
+	 * Note this requires that we are always called in request
+	 * completion order.
+	 */
+	request->ringbuf->last_retired_head = request->postfix;
+
+	list_del_init(&request->list);
+	i915_gem_request_remove_from_client(request);
+
+	i915_gem_request_unreference(request);
+}
+
+static void
+__i915_gem_request_retire__upto(struct drm_i915_gem_request *req)
+{
+	struct intel_engine_cs *engine = req->engine;
+	struct drm_i915_gem_request *tmp;
+
+	lockdep_assert_held(&engine->dev->struct_mutex);
+
+	if (list_empty(&req->list))
+		return;
+
+	do {
+		tmp = list_first_entry(&engine->request_list,
+				       typeof(*tmp), list);
+
+		i915_gem_request_retire(tmp);
+	} while (tmp != req);
+
+	WARN_ON(i915_verify_lists(engine->dev));
+}
+
+/**
+ * Waits for a request to be signaled, and cleans up the
+ * request and object lists appropriately for that event.
+ */
+int
+i915_wait_request(struct drm_i915_gem_request *req)
+{
+	struct drm_i915_private *dev_priv = req->i915;
+	bool interruptible;
+	int ret;
+
+	interruptible = dev_priv->mm.interruptible;
+
+	BUG_ON(!mutex_is_locked(&dev_priv->dev->struct_mutex));
+
+	ret = __i915_wait_request(req, interruptible, NULL, NULL);
+	if (ret)
+		return ret;
+
+	/* If the GPU hung, we want to keep the requests to find the guilty. */
+	if (req->reset_counter == i915_reset_counter(&dev_priv->gpu_error))
+		__i915_gem_request_retire__upto(req);
+
+	return 0;
+}
+
+/**
+ * Ensures that all rendering to the object has completed and the object is
+ * safe to unbind from the GTT or access from the CPU.
+ */
+int
+i915_gem_object_wait_rendering(struct drm_i915_gem_object *obj,
+			       bool readonly)
+{
+	int ret, i;
+
+	if (!obj->active)
+		return 0;
+
+	if (readonly) {
+		if (obj->last_write_req != NULL) {
+			ret = i915_wait_request(obj->last_write_req);
+			if (ret)
+				return ret;
+
+			i = obj->last_write_req->engine->id;
+			if (obj->last_read_req[i] == obj->last_write_req)
+				i915_gem_object_retire__read(obj, i);
+			else
+				i915_gem_object_retire__write(obj);
+		}
+	} else {
+		for (i = 0; i < I915_NUM_ENGINES; i++) {
+			if (obj->last_read_req[i] == NULL)
+				continue;
+
+			ret = i915_wait_request(obj->last_read_req[i]);
+			if (ret)
+				return ret;
+
+			i915_gem_object_retire__read(obj, i);
+		}
+		GEM_BUG_ON(obj->active);
+	}
+
+	return 0;
+}
+
+static void
+i915_gem_object_retire_request(struct drm_i915_gem_object *obj,
+			       struct drm_i915_gem_request *req)
+{
+	int ring = req->engine->id;
+
+	if (obj->last_read_req[ring] == req)
+		i915_gem_object_retire__read(obj, ring);
+	else if (obj->last_write_req == req)
+		i915_gem_object_retire__write(obj);
+
+	if (req->reset_counter == i915_reset_counter(&req->i915->gpu_error))
+		__i915_gem_request_retire__upto(req);
+}
+
+/* A nonblocking variant of the above wait. This is a highly dangerous routine
+ * as the object state may change during this call.
+ */
+static __must_check int
+i915_gem_object_wait_rendering__nonblocking(struct drm_i915_gem_object *obj,
+					    struct intel_rps_client *rps,
+					    bool readonly)
+{
+	struct drm_device *dev = obj->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct drm_i915_gem_request *requests[I915_NUM_ENGINES];
+	int ret, i, n = 0;
+
+	BUG_ON(!mutex_is_locked(&dev->struct_mutex));
+	BUG_ON(!dev_priv->mm.interruptible);
+
+	if (!obj->active)
+		return 0;
+
+	if (readonly) {
+		struct drm_i915_gem_request *req;
+
+		req = obj->last_write_req;
+		if (req == NULL)
+			return 0;
+
+		requests[n++] = i915_gem_request_reference(req);
+	} else {
+		for (i = 0; i < I915_NUM_ENGINES; i++) {
+			struct drm_i915_gem_request *req;
+
+			req = obj->last_read_req[i];
+			if (req == NULL)
+				continue;
+
+			requests[n++] = i915_gem_request_reference(req);
+		}
+	}
+
+	mutex_unlock(&dev->struct_mutex);
+	ret = 0;
+	for (i = 0; ret == 0 && i < n; i++)
+		ret = __i915_wait_request(requests[i], true, NULL, rps);
+	mutex_lock(&dev->struct_mutex);
+
+	for (i = 0; i < n; i++) {
+		if (ret == 0)
+			i915_gem_object_retire_request(obj, requests[i]);
+		i915_gem_request_unreference(requests[i]);
+	}
+
+	return ret;
+}
+
+static struct intel_rps_client *to_rps_client(struct drm_file *file)
+{
+	struct drm_i915_file_private *fpriv = file->driver_priv;
+	return &fpriv->rps;
+}
+
+/**
+ * Called when user space prepares to use an object with the CPU, either
+ * through the mmap ioctl's mapping or a GTT mapping.
+ */
+int
+i915_gem_set_domain_ioctl(struct drm_device *dev, void *data,
+			  struct drm_file *file)
+{
+	struct drm_i915_gem_set_domain *args = data;
+	struct drm_i915_gem_object *obj;
+	uint32_t read_domains = args->read_domains;
+	uint32_t write_domain = args->write_domain;
+	int ret;
+
+	/* Only handle setting domains to types used by the CPU. */
+	if (write_domain & I915_GEM_GPU_DOMAINS)
+		return -EINVAL;
+
+	if (read_domains & I915_GEM_GPU_DOMAINS)
+		return -EINVAL;
+
+	/* Having something in the write domain implies it's in the read
+	 * domain, and only that read domain.  Enforce that in the request.
+	 */
+	if (write_domain != 0 && read_domains != write_domain)
+		return -EINVAL;
+
+	ret = i915_mutex_lock_interruptible(dev);
+	if (ret)
+		return ret;
+
+	obj = to_intel_bo(drm_gem_object_lookup(dev, file, args->handle));
+	if (&obj->base == NULL) {
+		ret = -ENOENT;
+		goto unlock;
+	}
+
+	/* Try to flush the object off the GPU without holding the lock.
+	 * We will repeat the flush holding the lock in the normal manner
+	 * to catch cases where we are gazumped.
+	 */
+	ret = i915_gem_object_wait_rendering__nonblocking(obj,
+							  to_rps_client(file),
+							  !write_domain);
+	if (ret)
+		goto unref;
+
+	if (read_domains & I915_GEM_DOMAIN_GTT)
+		ret = i915_gem_object_set_to_gtt_domain(obj, write_domain != 0);
+	else
+		ret = i915_gem_object_set_to_cpu_domain(obj, write_domain != 0);
+
+	if (write_domain != 0)
+		intel_fb_obj_invalidate(obj,
+					write_domain == I915_GEM_DOMAIN_GTT ?
+					ORIGIN_GTT : ORIGIN_CPU);
+
+unref:
+	drm_gem_object_unreference(&obj->base);
+unlock:
+	mutex_unlock(&dev->struct_mutex);
+	return ret;
+}
+
+/**
+ * Called when user space has done writes to this buffer
+ */
+int
+i915_gem_sw_finish_ioctl(struct drm_device *dev, void *data,
+			 struct drm_file *file)
+{
+	struct drm_i915_gem_sw_finish *args = data;
+	struct drm_i915_gem_object *obj;
+	int ret = 0;
+
+	ret = i915_mutex_lock_interruptible(dev);
+	if (ret)
+		return ret;
+
+	obj = to_intel_bo(drm_gem_object_lookup(dev, file, args->handle));
+	if (&obj->base == NULL) {
+		ret = -ENOENT;
+		goto unlock;
+	}
+
+	/* Pinned buffers may be scanout, so flush the cache */
+	if (obj->pin_display)
+		i915_gem_object_flush_cpu_write_domain(obj);
+
+	drm_gem_object_unreference(&obj->base);
+unlock:
+	mutex_unlock(&dev->struct_mutex);
+	return ret;
+}
+
+/**
+ * Maps the contents of an object, returning the address it is mapped
+ * into.
+ *
+ * While the mapping holds a reference on the contents of the object, it doesn't
+ * imply a ref on the object itself.
+ *
+ * IMPORTANT:
+ *
+ * DRM driver writers who look a this function as an example for how to do GEM
+ * mmap support, please don't implement mmap support like here. The modern way
+ * to implement DRM mmap support is with an mmap offset ioctl (like
+ * i915_gem_mmap_gtt) and then using the mmap syscall on the DRM fd directly.
+ * That way debug tooling like valgrind will understand what's going on, hiding
+ * the mmap call in a driver private ioctl will break that. The i915 driver only
+ * does cpu mmaps this way because we didn't know better.
+ */
+int
+i915_gem_mmap_ioctl(struct drm_device *dev, void *data,
+		    struct drm_file *file)
+{
+	struct drm_i915_gem_mmap *args = data;
+	struct drm_gem_object *obj;
+	unsigned long addr;
+
+	if (args->flags & ~(I915_MMAP_WC))
+		return -EINVAL;
+
+	if (args->flags & I915_MMAP_WC && !boot_cpu_has(X86_FEATURE_PAT))
+		return -ENODEV;
+
+	obj = drm_gem_object_lookup(dev, file, args->handle);
+	if (obj == NULL)
+		return -ENOENT;
+
+	/* prime objects have no backing filp to GEM mmap
+	 * pages from.
+	 */
+	if (!obj->filp) {
+		drm_gem_object_unreference_unlocked(obj);
+		return -EINVAL;
+	}
+
+	addr = vm_mmap(obj->filp, 0, args->size,
+		       PROT_READ | PROT_WRITE, MAP_SHARED,
+		       args->offset);
+	if (args->flags & I915_MMAP_WC) {
+		struct mm_struct *mm = current->mm;
+		struct vm_area_struct *vma;
+
+		down_write(&mm->mmap_sem);
+		vma = find_vma(mm, addr);
+		if (vma)
+			vma->vm_page_prot =
+				pgprot_writecombine(vm_get_page_prot(vma->vm_flags));
+		else
+			addr = -ENOMEM;
+		up_write(&mm->mmap_sem);
+	}
+	drm_gem_object_unreference_unlocked(obj);
+	if (IS_ERR((void *)addr))
+		return addr;
+
+	args->addr_ptr = (uint64_t) addr;
+
+	return 0;
+}
+
+/**
+ * i915_gem_fault - fault a page into the GTT
+ * @vma: VMA in question
+ * @vmf: fault info
+ *
+ * The fault handler is set up by drm_gem_mmap() when a object is GTT mapped
+ * from userspace.  The fault handler takes care of binding the object to
+ * the GTT (if needed), allocating and programming a fence register (again,
+ * only if needed based on whether the old reg is still valid or the object
+ * is tiled) and inserting a new PTE into the faulting process.
+ *
+ * Note that the faulting process may involve evicting existing objects
+ * from the GTT and/or fence registers to make room.  So performance may
+ * suffer if the GTT working set is large or there are few fence registers
+ * left.
+ */
+int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
+{
+	struct drm_i915_gem_object *obj = to_intel_bo(vma->vm_private_data);
+	struct drm_device *dev = obj->base.dev;
+	struct drm_i915_private *dev_priv = to_i915(dev);
+	struct i915_ggtt *ggtt = &dev_priv->ggtt;
+	struct i915_ggtt_view view = i915_ggtt_view_normal;
+	pgoff_t page_offset;
+	unsigned long pfn;
+	int ret = 0;
+	bool write = !!(vmf->flags & FAULT_FLAG_WRITE);
+
+	intel_runtime_pm_get(dev_priv);
+
+	/* We don't use vmf->pgoff since that has the fake offset */
+	page_offset = ((unsigned long)vmf->virtual_address - vma->vm_start) >>
+		PAGE_SHIFT;
+
+	ret = i915_mutex_lock_interruptible(dev);
+	if (ret)
+		goto out;
+
+	trace_i915_gem_object_fault(obj, page_offset, true, write);
+
+	/* Try to flush the object off the GPU first without holding the lock.
+	 * Upon reacquiring the lock, we will perform our sanity checks and then
+	 * repeat the flush holding the lock in the normal manner to catch cases
+	 * where we are gazumped.
+	 */
+	ret = i915_gem_object_wait_rendering__nonblocking(obj, NULL, !write);
+	if (ret)
+		goto unlock;
+
+	/* Access to snoopable pages through the GTT is incoherent. */
+	if (obj->cache_level != I915_CACHE_NONE && !HAS_LLC(dev)) {
+		ret = -EFAULT;
+		goto unlock;
+	}
+
+	/* Use a partial view if the object is bigger than the aperture. */
+	if (obj->base.size >= ggtt->mappable_end &&
+	    obj->tiling_mode == I915_TILING_NONE) {
+		static const unsigned int chunk_size = 256; // 1 MiB
+
+		memset(&view, 0, sizeof(view));
+		view.type = I915_GGTT_VIEW_PARTIAL;
+		view.params.partial.offset = rounddown(page_offset, chunk_size);
+		view.params.partial.size =
+			min_t(unsigned int,
+			      chunk_size,
+			      (vma->vm_end - vma->vm_start)/PAGE_SIZE -
+			      view.params.partial.offset);
+	}
+
+	/* Now pin it into the GTT if needed */
+	ret = i915_gem_object_ggtt_pin(obj, &view, 0, PIN_MAPPABLE);
+	if (ret)
+		goto unlock;
+
+	ret = i915_gem_object_set_to_gtt_domain(obj, write);
+	if (ret)
+		goto unpin;
+
+	ret = i915_gem_object_get_fence(obj);
+	if (ret)
+		goto unpin;
+
+	/* Finally, remap it using the new GTT offset */
+	pfn = ggtt->mappable_base +
+		i915_gem_obj_ggtt_offset_view(obj, &view);
+	pfn >>= PAGE_SHIFT;
+
+	if (unlikely(view.type == I915_GGTT_VIEW_PARTIAL)) {
+		/* Overriding existing pages in partial view does not cause
+		 * us any trouble as TLBs are still valid because the fault
+		 * is due to userspace losing part of the mapping or never
+		 * having accessed it before (at this partials' range).
+		 */
+		unsigned long base = vma->vm_start +
+				     (view.params.partial.offset << PAGE_SHIFT);
+		unsigned int i;
+
+		for (i = 0; i < view.params.partial.size; i++) {
+			ret = vm_insert_pfn(vma, base + i * PAGE_SIZE, pfn + i);
+			if (ret)
+				break;
+		}
+
+		obj->fault_mappable = true;
+	} else {
+		if (!obj->fault_mappable) {
+			unsigned long size = min_t(unsigned long,
+						   vma->vm_end - vma->vm_start,
+						   obj->base.size);
+			int i;
+
+			for (i = 0; i < size >> PAGE_SHIFT; i++) {
+				ret = vm_insert_pfn(vma,
+						    (unsigned long)vma->vm_start + i * PAGE_SIZE,
+						    pfn + i);
+				if (ret)
+					break;
+			}
+
+			obj->fault_mappable = true;
+		} else
+			ret = vm_insert_pfn(vma,
+					    (unsigned long)vmf->virtual_address,
+					    pfn + page_offset);
+	}
+unpin:
+	i915_gem_object_ggtt_unpin_view(obj, &view);
+unlock:
+	mutex_unlock(&dev->struct_mutex);
+out:
+	switch (ret) {
+	case -EIO:
+		/*
+		 * We eat errors when the gpu is terminally wedged to avoid
+		 * userspace unduly crashing (gl has no provisions for mmaps to
+		 * fail). But any other -EIO isn't ours (e.g. swap in failure)
+		 * and so needs to be reported.
+		 */
+		if (!i915_terminally_wedged(&dev_priv->gpu_error)) {
+			ret = VM_FAULT_SIGBUS;
+			break;
+		}
+	case -EAGAIN:
+		/*
+		 * EAGAIN means the gpu is hung and we'll wait for the error
+		 * handler to reset everything when re-faulting in
+		 * i915_mutex_lock_interruptible.
+		 */
+	case 0:
+	case -ERESTARTSYS:
+	case -EINTR:
+	case -EBUSY:
+		/*
+		 * EBUSY is ok: this just means that another thread
+		 * already did the job.
+		 */
+		ret = VM_FAULT_NOPAGE;
+		break;
+	case -ENOMEM:
+		ret = VM_FAULT_OOM;
+		break;
+	case -ENOSPC:
+	case -EFAULT:
+		ret = VM_FAULT_SIGBUS;
+		break;
+	default:
+		WARN_ONCE(ret, "unhandled error in i915_gem_fault: %i\n", ret);
+		ret = VM_FAULT_SIGBUS;
+		break;
+	}
+
+	intel_runtime_pm_put(dev_priv);
+	return ret;
+}
+
+/**
+ * i915_gem_release_mmap - remove physical page mappings
+ * @obj: obj in question
+ *
+ * Preserve the reservation of the mmapping with the DRM core code, but
+ * relinquish ownership of the pages back to the system.
+ *
+ * It is vital that we remove the page mapping if we have mapped a tiled
+ * object through the GTT and then lose the fence register due to
+ * resource pressure. Similarly if the object has been moved out of the
+ * aperture, than pages mapped into userspace must be revoked. Removing the
+ * mapping will then trigger a page fault on the next user access, allowing
+ * fixup by i915_gem_fault().
+ */
+void
+i915_gem_release_mmap(struct drm_i915_gem_object *obj)
+{
+	/* Serialisation between user GTT access and our code depends upon
+	 * revoking the CPU's PTE whilst the mutex is held. The next user
+	 * pagefault then has to wait until we release the mutex.
+	 */
+	lockdep_assert_held(&obj->base.dev->struct_mutex);
+
+	if (!obj->fault_mappable)
+		return;
+
+	drm_vma_node_unmap(&obj->base.vma_node,
+			   obj->base.dev->anon_inode->i_mapping);
+
+	/* Ensure that the CPU's PTE are revoked and there are not outstanding
+	 * memory transactions from userspace before we return. The TLB
+	 * flushing implied above by changing the PTE above *should* be
+	 * sufficient, an extra barrier here just provides us with a bit
+	 * of paranoid documentation about our requirement to serialise
+	 * memory writes before touching registers / GSM.
+	 */
+	wmb();
+
+	obj->fault_mappable = false;
+}
+
+void
+i915_gem_release_all_mmaps(struct drm_i915_private *dev_priv)
+{
+	struct drm_i915_gem_object *obj;
+
+	list_for_each_entry(obj, &dev_priv->mm.bound_list, global_list)
+		i915_gem_release_mmap(obj);
+}
+
+uint32_t
+i915_gem_get_gtt_size(struct drm_device *dev, uint32_t size, int tiling_mode)
+{
+	uint32_t gtt_size;
+
+	if (INTEL_INFO(dev)->gen >= 4 ||
+	    tiling_mode == I915_TILING_NONE)
+		return size;
+
+	/* Previous chips need a power-of-two fence region when tiling */
+	if (INTEL_INFO(dev)->gen == 3)
+		gtt_size = 1024*1024;
+	else
+		gtt_size = 512*1024;
+
+	while (gtt_size < size)
+		gtt_size <<= 1;
+
+	return gtt_size;
+}
+
+/**
+ * i915_gem_get_gtt_alignment - return required GTT alignment for an object
+ * @obj: object to check
+ *
+ * Return the required GTT alignment for an object, taking into account
+ * potential fence register mapping.
+ */
+uint32_t
+i915_gem_get_gtt_alignment(struct drm_device *dev, uint32_t size,
+			   int tiling_mode, bool fenced)
+{
+	/*
+	 * Minimum alignment is 4k (GTT page size), but might be greater
+	 * if a fence register is needed for the object.
+	 */
+	if (INTEL_INFO(dev)->gen >= 4 || (!fenced && IS_G33(dev)) ||
+	    tiling_mode == I915_TILING_NONE)
+		return 4096;
+
+	/*
+	 * Previous chips need to be aligned to the size of the smallest
+	 * fence register that can contain the object.
+	 */
+	return i915_gem_get_gtt_size(dev, size, tiling_mode);
+}
+
+static int i915_gem_object_create_mmap_offset(struct drm_i915_gem_object *obj)
+{
+	struct drm_i915_private *dev_priv = obj->base.dev->dev_private;
+	int ret;
+
+	dev_priv->mm.shrinker_no_lock_stealing = true;
+
+	ret = drm_gem_create_mmap_offset(&obj->base);
+	if (ret != -ENOSPC)
+		goto out;
+
+	/* Badly fragmented mmap space? The only way we can recover
+	 * space is by destroying unwanted objects. We can't randomly release
+	 * mmap_offsets as userspace expects them to be persistent for the
+	 * lifetime of the objects. The closest we can is to release the
+	 * offsets on purgeable objects by truncating it and marking it purged,
+	 * which prevents userspace from ever using that object again.
+	 */
+	i915_gem_shrink(dev_priv,
+			obj->base.size >> PAGE_SHIFT,
+			I915_SHRINK_BOUND |
+			I915_SHRINK_UNBOUND |
+			I915_SHRINK_PURGEABLE);
+	ret = drm_gem_create_mmap_offset(&obj->base);
+	if (ret != -ENOSPC)
+		goto out;
+
+	i915_gem_shrink_all(dev_priv);
+	ret = drm_gem_create_mmap_offset(&obj->base);
+out:
+	dev_priv->mm.shrinker_no_lock_stealing = false;
+
+	return ret;
+}
+
+static void i915_gem_object_free_mmap_offset(struct drm_i915_gem_object *obj)
+{
+	drm_gem_free_mmap_offset(&obj->base);
+}
+
+int
+i915_gem_mmap_gtt(struct drm_file *file,
+		  struct drm_device *dev,
+		  uint32_t handle,
+		  uint64_t *offset)
+{
+	struct drm_i915_gem_object *obj;
+	int ret;
+
+	ret = i915_mutex_lock_interruptible(dev);
+	if (ret)
+		return ret;
+
+	obj = to_intel_bo(drm_gem_object_lookup(dev, file, handle));
+	if (&obj->base == NULL) {
+		ret = -ENOENT;
+		goto unlock;
+	}
+
+	if (obj->madv != I915_MADV_WILLNEED) {
+		DRM_DEBUG("Attempting to mmap a purgeable buffer\n");
+		ret = -EFAULT;
+		goto out;
+	}
+
+	ret = i915_gem_object_create_mmap_offset(obj);
+	if (ret)
+		goto out;
+
+	*offset = drm_vma_node_offset_addr(&obj->base.vma_node);
+
+out:
+	drm_gem_object_unreference(&obj->base);
+unlock:
+	mutex_unlock(&dev->struct_mutex);
+	return ret;
+}
+
+/**
+ * i915_gem_mmap_gtt_ioctl - prepare an object for GTT mmap'ing
+ * @dev: DRM device
+ * @data: GTT mapping ioctl data
+ * @file: GEM object info
+ *
+ * Simply returns the fake offset to userspace so it can mmap it.
+ * The mmap call will end up in drm_gem_mmap(), which will set things
+ * up so we can get faults in the handler above.
+ *
+ * The fault handler will take care of binding the object into the GTT
+ * (since it may have been evicted to make room for something), allocating
+ * a fence register, and mapping the appropriate aperture address into
+ * userspace.
+ */
+int
+i915_gem_mmap_gtt_ioctl(struct drm_device *dev, void *data,
+			struct drm_file *file)
+{
+	struct drm_i915_gem_mmap_gtt *args = data;
+
+	return i915_gem_mmap_gtt(file, dev, args->handle, &args->offset);
+}
+
+/* Immediately discard the backing storage */
+static void
+i915_gem_object_truncate(struct drm_i915_gem_object *obj)
+{
+	i915_gem_object_free_mmap_offset(obj);
+
+	if (obj->base.filp == NULL)
+		return;
+
+	/* Our goal here is to return as much of the memory as
+	 * is possible back to the system as we are called from OOM.
+	 * To do this we must instruct the shmfs to drop all of its
+	 * backing pages, *now*.
+	 */
+	shmem_truncate_range(file_inode(obj->base.filp), 0, (loff_t)-1);
+	obj->madv = __I915_MADV_PURGED;
+}
+
+/* Try to discard unwanted pages */
+static void
+i915_gem_object_invalidate(struct drm_i915_gem_object *obj)
+{
+	struct address_space *mapping;
+
+	switch (obj->madv) {
+	case I915_MADV_DONTNEED:
+		i915_gem_object_truncate(obj);
+	case __I915_MADV_PURGED:
+		return;
+	}
+
+	if (obj->base.filp == NULL)
+		return;
+
+	mapping = file_inode(obj->base.filp)->i_mapping,
+	invalidate_mapping_pages(mapping, 0, (loff_t)-1);
+}
+
+static void
+i915_gem_object_put_pages_gtt(struct drm_i915_gem_object *obj)
+{
+	struct sg_page_iter sg_iter;
+	int ret;
+
+	BUG_ON(obj->madv == __I915_MADV_PURGED);
+
+	ret = i915_gem_object_set_to_cpu_domain(obj, true);
+	if (WARN_ON(ret)) {
+		/* In the event of a disaster, abandon all caches and
+		 * hope for the best.
+		 */
+		i915_gem_clflush_object(obj, true);
+		obj->base.read_domains = obj->base.write_domain = I915_GEM_DOMAIN_CPU;
+	}
+
+	i915_gem_gtt_finish_object(obj);
+
+	if (i915_gem_object_needs_bit17_swizzle(obj))
+		i915_gem_object_save_bit_17_swizzle(obj);
+
+	if (obj->madv == I915_MADV_DONTNEED)
+		obj->dirty = 0;
+
+	for_each_sg_page(obj->pages->sgl, &sg_iter, obj->pages->nents, 0) {
+		struct page *page = sg_page_iter_page(&sg_iter);
+
+		if (obj->dirty)
+			set_page_dirty(page);
+
+		if (obj->madv == I915_MADV_WILLNEED)
+			mark_page_accessed(page);
+
+		put_page(page);
+	}
+	obj->dirty = 0;
+
+	sg_free_table(obj->pages);
+	kfree(obj->pages);
+}
+
+int
+i915_gem_object_put_pages(struct drm_i915_gem_object *obj)
+{
+	const struct drm_i915_gem_object_ops *ops = obj->ops;
+
+	if (obj->pages == NULL)
+		return 0;
+
+	if (obj->pages_pin_count)
+		return -EBUSY;
+
+	BUG_ON(i915_gem_obj_bound_any(obj));
+
+	/* ->put_pages might need to allocate memory for the bit17 swizzle
+	 * array, hence protect them from being reaped by removing them from gtt
+	 * lists early. */
+	list_del(&obj->global_list);
+
+	if (obj->mapping) {
+		if (is_vmalloc_addr(obj->mapping))
+			vunmap(obj->mapping);
+		else
+			kunmap(kmap_to_page(obj->mapping));
+		obj->mapping = NULL;
+	}
+
+	ops->put_pages(obj);
+	obj->pages = NULL;
+
+	i915_gem_object_invalidate(obj);
+
+	return 0;
+}
+
+static int
+i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj)
+{
+	struct drm_i915_private *dev_priv = obj->base.dev->dev_private;
+	int page_count, i;
+	struct address_space *mapping;
+	struct sg_table *st;
+	struct scatterlist *sg;
+	struct sg_page_iter sg_iter;
+	struct page *page;
+	unsigned long last_pfn = 0;	/* suppress gcc warning */
+	int ret;
+	gfp_t gfp;
+
+	/* Assert that the object is not currently in any GPU domain. As it
+	 * wasn't in the GTT, there shouldn't be any way it could have been in
+	 * a GPU cache
+	 */
+	BUG_ON(obj->base.read_domains & I915_GEM_GPU_DOMAINS);
+	BUG_ON(obj->base.write_domain & I915_GEM_GPU_DOMAINS);
+
+	st = kmalloc(sizeof(*st), GFP_KERNEL);
+	if (st == NULL)
+		return -ENOMEM;
+
+	page_count = obj->base.size / PAGE_SIZE;
+	if (sg_alloc_table(st, page_count, GFP_KERNEL)) {
+		kfree(st);
+		return -ENOMEM;
+	}
+
+	/* Get the list of pages out of our struct file.  They'll be pinned
+	 * at this point until we release them.
+	 *
+	 * Fail silently without starting the shrinker
+	 */
+	mapping = file_inode(obj->base.filp)->i_mapping;
+	gfp = mapping_gfp_constraint(mapping, ~(__GFP_IO | __GFP_RECLAIM));
+	gfp |= __GFP_NORETRY | __GFP_NOWARN;
+	sg = st->sgl;
+	st->nents = 0;
+	for (i = 0; i < page_count; i++) {
+		page = shmem_read_mapping_page_gfp(mapping, i, gfp);
+		if (IS_ERR(page)) {
+			i915_gem_shrink(dev_priv,
+					page_count,
+					I915_SHRINK_BOUND |
+					I915_SHRINK_UNBOUND |
+					I915_SHRINK_PURGEABLE);
+			page = shmem_read_mapping_page_gfp(mapping, i, gfp);
+		}
+		if (IS_ERR(page)) {
+			/* We've tried hard to allocate the memory by reaping
+			 * our own buffer, now let the real VM do its job and
+			 * go down in flames if truly OOM.
+			 */
+			i915_gem_shrink_all(dev_priv);
+			page = shmem_read_mapping_page(mapping, i);
+			if (IS_ERR(page)) {
+				ret = PTR_ERR(page);
+				goto err_pages;
+			}
+		}
+#ifdef CONFIG_SWIOTLB
+		if (swiotlb_nr_tbl()) {
+			st->nents++;
+			sg_set_page(sg, page, PAGE_SIZE, 0);
+			sg = sg_next(sg);
+			continue;
+		}
+#endif
+		if (!i || page_to_pfn(page) != last_pfn + 1) {
+			if (i)
+				sg = sg_next(sg);
+			st->nents++;
+			sg_set_page(sg, page, PAGE_SIZE, 0);
+		} else {
+			sg->length += PAGE_SIZE;
+		}
+		last_pfn = page_to_pfn(page);
+
+		/* Check that the i965g/gm workaround works. */
+		WARN_ON((gfp & __GFP_DMA32) && (last_pfn >= 0x00100000UL));
+	}
+#ifdef CONFIG_SWIOTLB
+	if (!swiotlb_nr_tbl())
+#endif
+		sg_mark_end(sg);
+	obj->pages = st;
+
+	ret = i915_gem_gtt_prepare_object(obj);
+	if (ret)
+		goto err_pages;
+
+	if (i915_gem_object_needs_bit17_swizzle(obj))
+		i915_gem_object_do_bit_17_swizzle(obj);
+
+	if (obj->tiling_mode != I915_TILING_NONE &&
+	    dev_priv->quirks & QUIRK_PIN_SWIZZLED_PAGES)
+		i915_gem_object_pin_pages(obj);
+
+	return 0;
+
+err_pages:
+	sg_mark_end(sg);
+	for_each_sg_page(st->sgl, &sg_iter, st->nents, 0)
+		put_page(sg_page_iter_page(&sg_iter));
+	sg_free_table(st);
+	kfree(st);
+
+	/* shmemfs first checks if there is enough memory to allocate the page
+	 * and reports ENOSPC should there be insufficient, along with the usual
+	 * ENOMEM for a genuine allocation failure.
+	 *
+	 * We use ENOSPC in our driver to mean that we have run out of aperture
+	 * space and so want to translate the error from shmemfs back to our
+	 * usual understanding of ENOMEM.
+	 */
+	if (ret == -ENOSPC)
+		ret = -ENOMEM;
+
+	return ret;
+}
+
+/* Ensure that the associated pages are gathered from the backing storage
+ * and pinned into our object. i915_gem_object_get_pages() may be called
+ * multiple times before they are released by a single call to
+ * i915_gem_object_put_pages() - once the pages are no longer referenced
+ * either as a result of memory pressure (reaping pages under the shrinker)
+ * or as the object is itself released.
+ */
+int
+i915_gem_object_get_pages(struct drm_i915_gem_object *obj)
+{
+	struct drm_i915_private *dev_priv = obj->base.dev->dev_private;
+	const struct drm_i915_gem_object_ops *ops = obj->ops;
+	int ret;
+
+	if (obj->pages)
+		return 0;
+
+	if (obj->madv != I915_MADV_WILLNEED) {
+		DRM_DEBUG("Attempting to obtain a purgeable object\n");
+		return -EFAULT;
+	}
+
+	BUG_ON(obj->pages_pin_count);
+
+	ret = ops->get_pages(obj);
+	if (ret)
+		return ret;
+
+	list_add_tail(&obj->global_list, &dev_priv->mm.unbound_list);
+
+	obj->get_page.sg = obj->pages->sgl;
+	obj->get_page.last = 0;
+
+	return 0;
+}
+
+void *i915_gem_object_pin_map(struct drm_i915_gem_object *obj)
+{
+	int ret;
+
+	lockdep_assert_held(&obj->base.dev->struct_mutex);
+
+	ret = i915_gem_object_get_pages(obj);
+	if (ret)
+		return ERR_PTR(ret);
+
+	i915_gem_object_pin_pages(obj);
+
+	if (obj->mapping == NULL) {
+		struct page **pages;
+
+		pages = NULL;
+		if (obj->base.size == PAGE_SIZE)
+			obj->mapping = kmap(sg_page(obj->pages->sgl));
+		else
+			pages = drm_malloc_gfp(obj->base.size >> PAGE_SHIFT,
+					       sizeof(*pages),
+					       GFP_TEMPORARY);
+		if (pages != NULL) {
+			struct sg_page_iter sg_iter;
+			int n;
+
+			n = 0;
+			for_each_sg_page(obj->pages->sgl, &sg_iter,
+					 obj->pages->nents, 0)
+				pages[n++] = sg_page_iter_page(&sg_iter);
+
+			obj->mapping = vmap(pages, n, 0, PAGE_KERNEL);
+			drm_free_large(pages);
+		}
+		if (obj->mapping == NULL) {
+			i915_gem_object_unpin_pages(obj);
+			return ERR_PTR(-ENOMEM);
+		}
+	}
+
+	return obj->mapping;
+}
+
+void i915_vma_move_to_active(struct i915_vma *vma,
+			     struct drm_i915_gem_request *req)
+{
+	struct drm_i915_gem_object *obj = vma->obj;
+	struct intel_engine_cs *engine;
+
+	engine = i915_gem_request_get_engine(req);
+
+	/* Add a reference if we're newly entering the active list. */
+	if (obj->active == 0)
+		drm_gem_object_reference(&obj->base);
+	obj->active |= intel_engine_flag(engine);
+
+	list_move_tail(&obj->engine_list[engine->id], &engine->active_list);
+	i915_gem_request_assign(&obj->last_read_req[engine->id], req);
+
+	list_move_tail(&vma->vm_link, &vma->vm->active_list);
+}
+
+static void
+i915_gem_object_retire__write(struct drm_i915_gem_object *obj)
+{
+	GEM_BUG_ON(obj->last_write_req == NULL);
+	GEM_BUG_ON(!(obj->active & intel_engine_flag(obj->last_write_req->engine)));
+
+	i915_gem_request_assign(&obj->last_write_req, NULL);
+	intel_fb_obj_flush(obj, true, ORIGIN_CS);
+}
+
+static void
+i915_gem_object_retire__read(struct drm_i915_gem_object *obj, int ring)
+{
+	struct i915_vma *vma;
+
+	GEM_BUG_ON(obj->last_read_req[ring] == NULL);
+	GEM_BUG_ON(!(obj->active & (1 << ring)));
+
+	list_del_init(&obj->engine_list[ring]);
+	i915_gem_request_assign(&obj->last_read_req[ring], NULL);
+
+	if (obj->last_write_req && obj->last_write_req->engine->id == ring)
+		i915_gem_object_retire__write(obj);
+
+	obj->active &= ~(1 << ring);
+	if (obj->active)
+		return;
+
+	/* Bump our place on the bound list to keep it roughly in LRU order
+	 * so that we don't steal from recently used but inactive objects
+	 * (unless we are forced to ofc!)
+	 */
+	list_move_tail(&obj->global_list,
+		       &to_i915(obj->base.dev)->mm.bound_list);
+
+	list_for_each_entry(vma, &obj->vma_list, obj_link) {
+		if (!list_empty(&vma->vm_link))
+			list_move_tail(&vma->vm_link, &vma->vm->inactive_list);
+	}
+
+	i915_gem_request_assign(&obj->last_fenced_req, NULL);
+	drm_gem_object_unreference(&obj->base);
+}
+
+static int
+i915_gem_init_seqno(struct drm_device *dev, u32 seqno)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_engine_cs *engine;
+	int ret;
+
+	/* Carefully retire all requests without writing to the rings */
+	for_each_engine(engine, dev_priv) {
+		ret = intel_engine_idle(engine);
+		if (ret)
+			return ret;
+	}
+	i915_gem_retire_requests(dev);
+
+	/* Finally reset hw state */
+	for_each_engine(engine, dev_priv)
+		intel_ring_init_seqno(engine, seqno);
+
+	return 0;
+}
+
+int i915_gem_set_seqno(struct drm_device *dev, u32 seqno)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	int ret;
+
+	if (seqno == 0)
+		return -EINVAL;
+
+	/* HWS page needs to be set less than what we
+	 * will inject to ring
+	 */
+	ret = i915_gem_init_seqno(dev, seqno - 1);
+	if (ret)
+		return ret;
+
+	/* Carefully set the last_seqno value so that wrap
+	 * detection still works
+	 */
+	dev_priv->next_seqno = seqno;
+	dev_priv->last_seqno = seqno - 1;
+	if (dev_priv->last_seqno == 0)
+		dev_priv->last_seqno--;
+
+	return 0;
+}
+
+int
+i915_gem_get_seqno(struct drm_device *dev, u32 *seqno)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	/* reserve 0 for non-seqno */
+	if (dev_priv->next_seqno == 0) {
+		int ret = i915_gem_init_seqno(dev, 0);
+		if (ret)
+			return ret;
+
+		dev_priv->next_seqno = 1;
+	}
+
+	*seqno = dev_priv->last_seqno = dev_priv->next_seqno++;
+	return 0;
+}
+
+/*
+ * NB: This function is not allowed to fail. Doing so would mean the the
+ * request is not being tracked for completion but the work itself is
+ * going to happen on the hardware. This would be a Bad Thing(tm).
+ */
+void __i915_add_request(struct drm_i915_gem_request *request,
+			struct drm_i915_gem_object *obj,
+			bool flush_caches)
+{
+	struct intel_engine_cs *engine;
+	struct drm_i915_private *dev_priv;
+	struct intel_ringbuffer *ringbuf;
+	u32 request_start;
+	int ret;
+
+	if (WARN_ON(request == NULL))
+		return;
+
+	engine = request->engine;
+	dev_priv = request->i915;
+	ringbuf = request->ringbuf;
+
+	/*
+	 * To ensure that this call will not fail, space for its emissions
+	 * should already have been reserved in the ring buffer. Let the ring
+	 * know that it is time to use that space up.
+	 */
+	intel_ring_reserved_space_use(ringbuf);
+
+	request_start = intel_ring_get_tail(ringbuf);
+	/*
+	 * Emit any outstanding flushes - execbuf can fail to emit the flush
+	 * after having emitted the batchbuffer command. Hence we need to fix
+	 * things up similar to emitting the lazy request. The difference here
+	 * is that the flush _must_ happen before the next request, no matter
+	 * what.
+	 */
+	if (flush_caches) {
+		if (i915.enable_execlists)
+			ret = logical_ring_flush_all_caches(request);
+		else
+			ret = intel_ring_flush_all_caches(request);
+		/* Not allowed to fail! */
+		WARN(ret, "*_ring_flush_all_caches failed: %d!\n", ret);
+	}
+
+	trace_i915_gem_request_add(request);
+
+	request->head = request_start;
+
+	/* Whilst this request exists, batch_obj will be on the
+	 * active_list, and so will hold the active reference. Only when this
+	 * request is retired will the the batch_obj be moved onto the
+	 * inactive_list and lose its active reference. Hence we do not need
+	 * to explicitly hold another reference here.
+	 */
+	request->batch_obj = obj;
+
+	/* Seal the request and mark it as pending execution. Note that
+	 * we may inspect this state, without holding any locks, during
+	 * hangcheck. Hence we apply the barrier to ensure that we do not
+	 * see a more recent value in the hws than we are tracking.
+	 */
+	request->emitted_jiffies = jiffies;
+	request->previous_seqno = engine->last_submitted_seqno;
+	smp_store_mb(engine->last_submitted_seqno, request->seqno);
+	list_add_tail(&request->list, &engine->request_list);
+
+	/* Record the position of the start of the request so that
+	 * should we detect the updated seqno part-way through the
+	 * GPU processing the request, we never over-estimate the
+	 * position of the head.
+	 */
+	request->postfix = intel_ring_get_tail(ringbuf);
+
+	if (i915.enable_execlists)
+		ret = engine->emit_request(request);
+	else {
+		ret = engine->add_request(request);
+
+		request->tail = intel_ring_get_tail(ringbuf);
+	}
+	/* Not allowed to fail! */
+	WARN(ret, "emit|add_request failed: %d!\n", ret);
+
+	i915_queue_hangcheck(engine->dev);
+
+	queue_delayed_work(dev_priv->wq,
+			   &dev_priv->mm.retire_work,
+			   round_jiffies_up_relative(HZ));
+	intel_mark_busy(dev_priv->dev);
+
+	/* Sanity check that the reserved size was large enough. */
+	intel_ring_reserved_space_end(ringbuf);
+}
+
+static bool i915_context_is_banned(struct drm_i915_private *dev_priv,
+				   const struct intel_context *ctx)
+{
+	unsigned long elapsed;
+
+	elapsed = get_seconds() - ctx->hang_stats.guilty_ts;
+
+	if (ctx->hang_stats.banned)
+		return true;
+
+	if (ctx->hang_stats.ban_period_seconds &&
+	    elapsed <= ctx->hang_stats.ban_period_seconds) {
+		if (!i915_gem_context_is_default(ctx)) {
+			DRM_DEBUG("context hanging too fast, banning!\n");
+			return true;
+		} else if (i915_stop_ring_allow_ban(dev_priv)) {
+			if (i915_stop_ring_allow_warn(dev_priv))
+				DRM_ERROR("gpu hanging too fast, banning!\n");
+			return true;
+		}
+	}
+
+	return false;
+}
+
+static void i915_set_reset_status(struct drm_i915_private *dev_priv,
+				  struct intel_context *ctx,
+				  const bool guilty)
+{
+	struct i915_ctx_hang_stats *hs;
+
+	if (WARN_ON(!ctx))
+		return;
+
+	hs = &ctx->hang_stats;
+
+	if (guilty) {
+		hs->banned = i915_context_is_banned(dev_priv, ctx);
+		hs->batch_active++;
+		hs->guilty_ts = get_seconds();
+	} else {
+		hs->batch_pending++;
+	}
+}
+
+void i915_gem_request_free(struct kref *req_ref)
+{
+	struct drm_i915_gem_request *req = container_of(req_ref,
+						 typeof(*req), ref);
+	struct intel_context *ctx = req->ctx;
+
+	if (req->file_priv)
+		i915_gem_request_remove_from_client(req);
+
+	if (ctx) {
+		if (i915.enable_execlists && ctx != req->i915->kernel_context)
+			intel_lr_context_unpin(ctx, req->engine);
+
+		i915_gem_context_unreference(ctx);
+	}
+
+	kmem_cache_free(req->i915->requests, req);
+}
+
+static inline int
+__i915_gem_request_alloc(struct intel_engine_cs *engine,
+			 struct intel_context *ctx,
+			 struct drm_i915_gem_request **req_out)
+{
+	struct drm_i915_private *dev_priv = to_i915(engine->dev);
+	unsigned reset_counter = i915_reset_counter(&dev_priv->gpu_error);
+	struct drm_i915_gem_request *req;
+	int ret;
+
+	if (!req_out)
+		return -EINVAL;
+
+	*req_out = NULL;
+
+	/* ABI: Before userspace accesses the GPU (e.g. execbuffer), report
+	 * EIO if the GPU is already wedged, or EAGAIN to drop the struct_mutex
+	 * and restart.
+	 */
+	ret = i915_gem_check_wedge(reset_counter, dev_priv->mm.interruptible);
+	if (ret)
+		return ret;
+
+	req = kmem_cache_zalloc(dev_priv->requests, GFP_KERNEL);
+	if (req == NULL)
+		return -ENOMEM;
+
+	ret = i915_gem_get_seqno(engine->dev, &req->seqno);
+	if (ret)
+		goto err;
+
+	kref_init(&req->ref);
+	req->i915 = dev_priv;
+	req->engine = engine;
+	req->reset_counter = reset_counter;
+	req->ctx  = ctx;
+	i915_gem_context_reference(req->ctx);
+
+	if (i915.enable_execlists)
+		ret = intel_logical_ring_alloc_request_extras(req);
+	else
+		ret = intel_ring_alloc_request_extras(req);
+	if (ret) {
+		i915_gem_context_unreference(req->ctx);
+		goto err;
+	}
+
+	/*
+	 * Reserve space in the ring buffer for all the commands required to
+	 * eventually emit this request. This is to guarantee that the
+	 * i915_add_request() call can't fail. Note that the reserve may need
+	 * to be redone if the request is not actually submitted straight
+	 * away, e.g. because a GPU scheduler has deferred it.
+	 */
+	if (i915.enable_execlists)
+		ret = intel_logical_ring_reserve_space(req);
+	else
+		ret = intel_ring_reserve_space(req);
+	if (ret) {
+		/*
+		 * At this point, the request is fully allocated even if not
+		 * fully prepared. Thus it can be cleaned up using the proper
+		 * free code.
+		 */
+		intel_ring_reserved_space_cancel(req->ringbuf);
+		i915_gem_request_unreference(req);
+		return ret;
+	}
+
+	*req_out = req;
+	return 0;
+
+err:
+	kmem_cache_free(dev_priv->requests, req);
+	return ret;
+}
+
+/**
+ * i915_gem_request_alloc - allocate a request structure
+ *
+ * @engine: engine that we wish to issue the request on.
+ * @ctx: context that the request will be associated with.
+ *       This can be NULL if the request is not directly related to
+ *       any specific user context, in which case this function will
+ *       choose an appropriate context to use.
+ *
+ * Returns a pointer to the allocated request if successful,
+ * or an error code if not.
+ */
+struct drm_i915_gem_request *
+i915_gem_request_alloc(struct intel_engine_cs *engine,
+		       struct intel_context *ctx)
+{
+	struct drm_i915_gem_request *req;
+	int err;
+
+	if (ctx == NULL)
+		ctx = to_i915(engine->dev)->kernel_context;
+	err = __i915_gem_request_alloc(engine, ctx, &req);
+	return err ? ERR_PTR(err) : req;
+}
+
+struct drm_i915_gem_request *
+i915_gem_find_active_request(struct intel_engine_cs *engine)
+{
+	struct drm_i915_gem_request *request;
+
+	list_for_each_entry(request, &engine->request_list, list) {
+		if (i915_gem_request_completed(request, false))
+			continue;
+
+		return request;
+	}
+
+	return NULL;
+}
+
+static void i915_gem_reset_engine_status(struct drm_i915_private *dev_priv,
+				       struct intel_engine_cs *engine)
+{
+	struct drm_i915_gem_request *request;
+	bool ring_hung;
+
+	request = i915_gem_find_active_request(engine);
+
+	if (request == NULL)
+		return;
+
+	ring_hung = engine->hangcheck.score >= HANGCHECK_SCORE_RING_HUNG;
+
+	i915_set_reset_status(dev_priv, request->ctx, ring_hung);
+
+	list_for_each_entry_continue(request, &engine->request_list, list)
+		i915_set_reset_status(dev_priv, request->ctx, false);
+}
+
+static void i915_gem_reset_engine_cleanup(struct drm_i915_private *dev_priv,
+					struct intel_engine_cs *engine)
+{
+	struct intel_ringbuffer *buffer;
+
+	while (!list_empty(&engine->active_list)) {
+		struct drm_i915_gem_object *obj;
+
+		obj = list_first_entry(&engine->active_list,
+				       struct drm_i915_gem_object,
+				       engine_list[engine->id]);
+
+		i915_gem_object_retire__read(obj, engine->id);
+	}
+
+	/*
+	 * Clear the execlists queue up before freeing the requests, as those
+	 * are the ones that keep the context and ringbuffer backing objects
+	 * pinned in place.
+	 */
+
+	if (i915.enable_execlists) {
+		/* Ensure irq handler finishes or is cancelled. */
+		tasklet_kill(&engine->irq_tasklet);
+
+		spin_lock_bh(&engine->execlist_lock);
+		/* list_splice_tail_init checks for empty lists */
+		list_splice_tail_init(&engine->execlist_queue,
+				      &engine->execlist_retired_req_list);
+		spin_unlock_bh(&engine->execlist_lock);
+
+		intel_execlists_retire_requests(engine);
+	}
+
+	/*
+	 * We must free the requests after all the corresponding objects have
+	 * been moved off active lists. Which is the same order as the normal
+	 * retire_requests function does. This is important if object hold
+	 * implicit references on things like e.g. ppgtt address spaces through
+	 * the request.
+	 */
+	while (!list_empty(&engine->request_list)) {
+		struct drm_i915_gem_request *request;
+
+		request = list_first_entry(&engine->request_list,
+					   struct drm_i915_gem_request,
+					   list);
+
+		i915_gem_request_retire(request);
+	}
+
+	/* Having flushed all requests from all queues, we know that all
+	 * ringbuffers must now be empty. However, since we do not reclaim
+	 * all space when retiring the request (to prevent HEADs colliding
+	 * with rapid ringbuffer wraparound) the amount of available space
+	 * upon reset is less than when we start. Do one more pass over
+	 * all the ringbuffers to reset last_retired_head.
+	 */
+	list_for_each_entry(buffer, &engine->buffers, link) {
+		buffer->last_retired_head = buffer->tail;
+		intel_ring_update_space(buffer);
+	}
+
+	intel_ring_init_seqno(engine, engine->last_submitted_seqno);
+}
+
+void i915_gem_reset(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_engine_cs *engine;
+
+	/*
+	 * Before we free the objects from the requests, we need to inspect
+	 * them for finding the guilty party. As the requests only borrow
+	 * their reference to the objects, the inspection must be done first.
+	 */
+	for_each_engine(engine, dev_priv)
+		i915_gem_reset_engine_status(dev_priv, engine);
+
+	for_each_engine(engine, dev_priv)
+		i915_gem_reset_engine_cleanup(dev_priv, engine);
+
+	i915_gem_context_reset(dev);
+
+	i915_gem_restore_fences(dev);
+
+	WARN_ON(i915_verify_lists(dev));
+}
+
+/**
+ * This function clears the request list as sequence numbers are passed.
+ */
+void
+i915_gem_retire_requests_ring(struct intel_engine_cs *engine)
+{
+	WARN_ON(i915_verify_lists(engine->dev));
+
+	/* Retire requests first as we use it above for the early return.
+	 * If we retire requests last, we may use a later seqno and so clear
+	 * the requests lists without clearing the active list, leading to
+	 * confusion.
+	 */
+	while (!list_empty(&engine->request_list)) {
+		struct drm_i915_gem_request *request;
+
+		request = list_first_entry(&engine->request_list,
+					   struct drm_i915_gem_request,
+					   list);
+
+		if (!i915_gem_request_completed(request, true))
+			break;
+
+		i915_gem_request_retire(request);
+	}
+
+	/* Move any buffers on the active list that are no longer referenced
+	 * by the ringbuffer to the flushing/inactive lists as appropriate,
+	 * before we free the context associated with the requests.
+	 */
+	while (!list_empty(&engine->active_list)) {
+		struct drm_i915_gem_object *obj;
+
+		obj = list_first_entry(&engine->active_list,
+				       struct drm_i915_gem_object,
+				       engine_list[engine->id]);
+
+		if (!list_empty(&obj->last_read_req[engine->id]->list))
+			break;
+
+		i915_gem_object_retire__read(obj, engine->id);
+	}
+
+	if (unlikely(engine->trace_irq_req &&
+		     i915_gem_request_completed(engine->trace_irq_req, true))) {
+		engine->irq_put(engine);
+		i915_gem_request_assign(&engine->trace_irq_req, NULL);
+	}
+
+	WARN_ON(i915_verify_lists(engine->dev));
+}
+
+bool
+i915_gem_retire_requests(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_engine_cs *engine;
+	bool idle = true;
+
+	for_each_engine(engine, dev_priv) {
+		i915_gem_retire_requests_ring(engine);
+		idle &= list_empty(&engine->request_list);
+		if (i915.enable_execlists) {
+			spin_lock_bh(&engine->execlist_lock);
+			idle &= list_empty(&engine->execlist_queue);
+			spin_unlock_bh(&engine->execlist_lock);
+
+			intel_execlists_retire_requests(engine);
+		}
+	}
+
+	if (idle)
+		mod_delayed_work(dev_priv->wq,
+				   &dev_priv->mm.idle_work,
+				   msecs_to_jiffies(100));
+
+	return idle;
+}
+
+static void
+i915_gem_retire_work_handler(struct work_struct *work)
+{
+	struct drm_i915_private *dev_priv =
+		container_of(work, typeof(*dev_priv), mm.retire_work.work);
+	struct drm_device *dev = dev_priv->dev;
+	bool idle;
+
+	/* Come back later if the device is busy... */
+	idle = false;
+	if (mutex_trylock(&dev->struct_mutex)) {
+		idle = i915_gem_retire_requests(dev);
+		mutex_unlock(&dev->struct_mutex);
+	}
+	if (!idle)
+		queue_delayed_work(dev_priv->wq, &dev_priv->mm.retire_work,
+				   round_jiffies_up_relative(HZ));
+}
+
+static void
+i915_gem_idle_work_handler(struct work_struct *work)
+{
+	struct drm_i915_private *dev_priv =
+		container_of(work, typeof(*dev_priv), mm.idle_work.work);
+	struct drm_device *dev = dev_priv->dev;
+	struct intel_engine_cs *engine;
+
+	for_each_engine(engine, dev_priv)
+		if (!list_empty(&engine->request_list))
+			return;
+
+	/* we probably should sync with hangcheck here, using cancel_work_sync.
+	 * Also locking seems to be fubar here, engine->request_list is protected
+	 * by dev->struct_mutex. */
+
+	intel_mark_idle(dev);
+
+	if (mutex_trylock(&dev->struct_mutex)) {
+		for_each_engine(engine, dev_priv)
+			i915_gem_batch_pool_fini(&engine->batch_pool);
+
+		mutex_unlock(&dev->struct_mutex);
+	}
+}
+
+/**
+ * Ensures that an object will eventually get non-busy by flushing any required
+ * write domains, emitting any outstanding lazy request and retiring and
+ * completed requests.
+ */
+static int
+i915_gem_object_flush_active(struct drm_i915_gem_object *obj)
+{
+	int i;
+
+	if (!obj->active)
+		return 0;
+
+	for (i = 0; i < I915_NUM_ENGINES; i++) {
+		struct drm_i915_gem_request *req;
+
+		req = obj->last_read_req[i];
+		if (req == NULL)
+			continue;
+
+		if (list_empty(&req->list))
+			goto retire;
+
+		if (i915_gem_request_completed(req, true)) {
+			__i915_gem_request_retire__upto(req);
+retire:
+			i915_gem_object_retire__read(obj, i);
+		}
+	}
+
+	return 0;
+}
+
+/**
+ * i915_gem_wait_ioctl - implements DRM_IOCTL_I915_GEM_WAIT
+ * @DRM_IOCTL_ARGS: standard ioctl arguments
+ *
+ * Returns 0 if successful, else an error is returned with the remaining time in
+ * the timeout parameter.
+ *  -ETIME: object is still busy after timeout
+ *  -ERESTARTSYS: signal interrupted the wait
+ *  -ENONENT: object doesn't exist
+ * Also possible, but rare:
+ *  -EAGAIN: GPU wedged
+ *  -ENOMEM: damn
+ *  -ENODEV: Internal IRQ fail
+ *  -E?: The add request failed
+ *
+ * The wait ioctl with a timeout of 0 reimplements the busy ioctl. With any
+ * non-zero timeout parameter the wait ioctl will wait for the given number of
+ * nanoseconds on an object becoming unbusy. Since the wait itself does so
+ * without holding struct_mutex the object may become re-busied before this
+ * function completes. A similar but shorter * race condition exists in the busy
+ * ioctl
+ */
+int
+i915_gem_wait_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
+{
+	struct drm_i915_gem_wait *args = data;
+	struct drm_i915_gem_object *obj;
+	struct drm_i915_gem_request *req[I915_NUM_ENGINES];
+	int i, n = 0;
+	int ret;
+
+	if (args->flags != 0)
+		return -EINVAL;
+
+	ret = i915_mutex_lock_interruptible(dev);
+	if (ret)
+		return ret;
+
+	obj = to_intel_bo(drm_gem_object_lookup(dev, file, args->bo_handle));
+	if (&obj->base == NULL) {
+		mutex_unlock(&dev->struct_mutex);
+		return -ENOENT;
+	}
+
+	/* Need to make sure the object gets inactive eventually. */
+	ret = i915_gem_object_flush_active(obj);
+	if (ret)
+		goto out;
+
+	if (!obj->active)
+		goto out;
+
+	/* Do this after OLR check to make sure we make forward progress polling
+	 * on this IOCTL with a timeout == 0 (like busy ioctl)
+	 */
+	if (args->timeout_ns == 0) {
+		ret = -ETIME;
+		goto out;
+	}
+
+	drm_gem_object_unreference(&obj->base);
+
+	for (i = 0; i < I915_NUM_ENGINES; i++) {
+		if (obj->last_read_req[i] == NULL)
+			continue;
+
+		req[n++] = i915_gem_request_reference(obj->last_read_req[i]);
+	}
+
+	mutex_unlock(&dev->struct_mutex);
+
+	for (i = 0; i < n; i++) {
+		if (ret == 0)
+			ret = __i915_wait_request(req[i], true,
+						  args->timeout_ns > 0 ? &args->timeout_ns : NULL,
+						  to_rps_client(file));
+		i915_gem_request_unreference__unlocked(req[i]);
+	}
+	return ret;
+
+out:
+	drm_gem_object_unreference(&obj->base);
+	mutex_unlock(&dev->struct_mutex);
+	return ret;
+}
+
+static int
+__i915_gem_object_sync(struct drm_i915_gem_object *obj,
+		       struct intel_engine_cs *to,
+		       struct drm_i915_gem_request *from_req,
+		       struct drm_i915_gem_request **to_req)
+{
+	struct intel_engine_cs *from;
+	int ret;
+
+	from = i915_gem_request_get_engine(from_req);
+	if (to == from)
+		return 0;
+
+	if (i915_gem_request_completed(from_req, true))
+		return 0;
+
+	if (!i915_semaphore_is_enabled(obj->base.dev)) {
+		struct drm_i915_private *i915 = to_i915(obj->base.dev);
+		ret = __i915_wait_request(from_req,
+					  i915->mm.interruptible,
+					  NULL,
+					  &i915->rps.semaphores);
+		if (ret)
+			return ret;
+
+		i915_gem_object_retire_request(obj, from_req);
+	} else {
+		int idx = intel_ring_sync_index(from, to);
+		u32 seqno = i915_gem_request_get_seqno(from_req);
+
+		WARN_ON(!to_req);
+
+		if (seqno <= from->semaphore.sync_seqno[idx])
+			return 0;
+
+		if (*to_req == NULL) {
+			struct drm_i915_gem_request *req;
+
+			req = i915_gem_request_alloc(to, NULL);
+			if (IS_ERR(req))
+				return PTR_ERR(req);
+
+			*to_req = req;
+		}
+
+		trace_i915_gem_ring_sync_to(*to_req, from, from_req);
+		ret = to->semaphore.sync_to(*to_req, from, seqno);
+		if (ret)
+			return ret;
+
+		/* We use last_read_req because sync_to()
+		 * might have just caused seqno wrap under
+		 * the radar.
+		 */
+		from->semaphore.sync_seqno[idx] =
+			i915_gem_request_get_seqno(obj->last_read_req[from->id]);
+	}
+
+	return 0;
+}
+
+/**
+ * i915_gem_object_sync - sync an object to a ring.
+ *
+ * @obj: object which may be in use on another ring.
+ * @to: ring we wish to use the object on. May be NULL.
+ * @to_req: request we wish to use the object for. See below.
+ *          This will be allocated and returned if a request is
+ *          required but not passed in.
+ *
+ * This code is meant to abstract object synchronization with the GPU.
+ * Calling with NULL implies synchronizing the object with the CPU
+ * rather than a particular GPU ring. Conceptually we serialise writes
+ * between engines inside the GPU. We only allow one engine to write
+ * into a buffer at any time, but multiple readers. To ensure each has
+ * a coherent view of memory, we must:
+ *
+ * - If there is an outstanding write request to the object, the new
+ *   request must wait for it to complete (either CPU or in hw, requests
+ *   on the same ring will be naturally ordered).
+ *
+ * - If we are a write request (pending_write_domain is set), the new
+ *   request must wait for outstanding read requests to complete.
+ *
+ * For CPU synchronisation (NULL to) no request is required. For syncing with
+ * rings to_req must be non-NULL. However, a request does not have to be
+ * pre-allocated. If *to_req is NULL and sync commands will be emitted then a
+ * request will be allocated automatically and returned through *to_req. Note
+ * that it is not guaranteed that commands will be emitted (because the system
+ * might already be idle). Hence there is no need to create a request that
+ * might never have any work submitted. Note further that if a request is
+ * returned in *to_req, it is the responsibility of the caller to submit
+ * that request (after potentially adding more work to it).
+ *
+ * Returns 0 if successful, else propagates up the lower layer error.
+ */
+int
+i915_gem_object_sync(struct drm_i915_gem_object *obj,
+		     struct intel_engine_cs *to,
+		     struct drm_i915_gem_request **to_req)
+{
+	const bool readonly = obj->base.pending_write_domain == 0;
+	struct drm_i915_gem_request *req[I915_NUM_ENGINES];
+	int ret, i, n;
+
+	if (!obj->active)
+		return 0;
+
+	if (to == NULL)
+		return i915_gem_object_wait_rendering(obj, readonly);
+
+	n = 0;
+	if (readonly) {
+		if (obj->last_write_req)
+			req[n++] = obj->last_write_req;
+	} else {
+		for (i = 0; i < I915_NUM_ENGINES; i++)
+			if (obj->last_read_req[i])
+				req[n++] = obj->last_read_req[i];
+	}
+	for (i = 0; i < n; i++) {
+		ret = __i915_gem_object_sync(obj, to, req[i], to_req);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
+static void i915_gem_object_finish_gtt(struct drm_i915_gem_object *obj)
+{
+	u32 old_write_domain, old_read_domains;
+
+	/* Force a pagefault for domain tracking on next user access */
+	i915_gem_release_mmap(obj);
+
+	if ((obj->base.read_domains & I915_GEM_DOMAIN_GTT) == 0)
+		return;
+
+	old_read_domains = obj->base.read_domains;
+	old_write_domain = obj->base.write_domain;
+
+	obj->base.read_domains &= ~I915_GEM_DOMAIN_GTT;
+	obj->base.write_domain &= ~I915_GEM_DOMAIN_GTT;
+
+	trace_i915_gem_object_change_domain(obj,
+					    old_read_domains,
+					    old_write_domain);
+}
+
+static int __i915_vma_unbind(struct i915_vma *vma, bool wait)
+{
+	struct drm_i915_gem_object *obj = vma->obj;
+	struct drm_i915_private *dev_priv = obj->base.dev->dev_private;
+	int ret;
+
+	if (list_empty(&vma->obj_link))
+		return 0;
+
+	if (!drm_mm_node_allocated(&vma->node)) {
+		i915_gem_vma_destroy(vma);
+		return 0;
+	}
+
+	if (vma->pin_count)
+		return -EBUSY;
+
+	BUG_ON(obj->pages == NULL);
+
+	if (wait) {
+		ret = i915_gem_object_wait_rendering(obj, false);
+		if (ret)
+			return ret;
+	}
+
+	if (vma->is_ggtt && vma->ggtt_view.type == I915_GGTT_VIEW_NORMAL) {
+		i915_gem_object_finish_gtt(obj);
+
+		/* release the fence reg _after_ flushing */
+		ret = i915_gem_object_put_fence(obj);
+		if (ret)
+			return ret;
+	}
+
+	trace_i915_vma_unbind(vma);
+
+	vma->vm->unbind_vma(vma);
+	vma->bound = 0;
+
+	list_del_init(&vma->vm_link);
+	if (vma->is_ggtt) {
+		if (vma->ggtt_view.type == I915_GGTT_VIEW_NORMAL) {
+			obj->map_and_fenceable = false;
+		} else if (vma->ggtt_view.pages) {
+			sg_free_table(vma->ggtt_view.pages);
+			kfree(vma->ggtt_view.pages);
+		}
+		vma->ggtt_view.pages = NULL;
+	}
+
+	drm_mm_remove_node(&vma->node);
+	i915_gem_vma_destroy(vma);
+
+	/* Since the unbound list is global, only move to that list if
+	 * no more VMAs exist. */
+	if (list_empty(&obj->vma_list))
+		list_move_tail(&obj->global_list, &dev_priv->mm.unbound_list);
+
+	/* And finally now the object is completely decoupled from this vma,
+	 * we can drop its hold on the backing storage and allow it to be
+	 * reaped by the shrinker.
+	 */
+	i915_gem_object_unpin_pages(obj);
+
+	return 0;
+}
+
+int i915_vma_unbind(struct i915_vma *vma)
+{
+	return __i915_vma_unbind(vma, true);
+}
+
+int __i915_vma_unbind_no_wait(struct i915_vma *vma)
+{
+	return __i915_vma_unbind(vma, false);
+}
+
+int i915_gpu_idle(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_engine_cs *engine;
+	int ret;
+
+	/* Flush everything onto the inactive list. */
+	for_each_engine(engine, dev_priv) {
+		if (!i915.enable_execlists) {
+			struct drm_i915_gem_request *req;
+
+			req = i915_gem_request_alloc(engine, NULL);
+			if (IS_ERR(req))
+				return PTR_ERR(req);
+
+			ret = i915_switch_context(req);
+			i915_add_request_no_flush(req);
+			if (ret)
+				return ret;
+		}
+
+		ret = intel_engine_idle(engine);
+		if (ret)
+			return ret;
+	}
+
+	WARN_ON(i915_verify_lists(dev));
+	return 0;
+}
+
+static bool i915_gem_valid_gtt_space(struct i915_vma *vma,
+				     unsigned long cache_level)
+{
+	struct drm_mm_node *gtt_space = &vma->node;
+	struct drm_mm_node *other;
+
+	/*
+	 * On some machines we have to be careful when putting differing types
+	 * of snoopable memory together to avoid the prefetcher crossing memory
+	 * domains and dying. During vm initialisation, we decide whether or not
+	 * these constraints apply and set the drm_mm.color_adjust
+	 * appropriately.
+	 */
+	if (vma->vm->mm.color_adjust == NULL)
+		return true;
+
+	if (!drm_mm_node_allocated(gtt_space))
+		return true;
+
+	if (list_empty(&gtt_space->node_list))
+		return true;
+
+	other = list_entry(gtt_space->node_list.prev, struct drm_mm_node, node_list);
+	if (other->allocated && !other->hole_follows && other->color != cache_level)
+		return false;
+
+	other = list_entry(gtt_space->node_list.next, struct drm_mm_node, node_list);
+	if (other->allocated && !gtt_space->hole_follows && other->color != cache_level)
+		return false;
+
+	return true;
+}
+
+/**
+ * Finds free space in the GTT aperture and binds the object or a view of it
+ * there.
+ */
+static struct i915_vma *
+i915_gem_object_bind_to_vm(struct drm_i915_gem_object *obj,
+			   struct i915_address_space *vm,
+			   const struct i915_ggtt_view *ggtt_view,
+			   unsigned alignment,
+			   uint64_t flags)
+{
+	struct drm_device *dev = obj->base.dev;
+	struct drm_i915_private *dev_priv = to_i915(dev);
+	struct i915_ggtt *ggtt = &dev_priv->ggtt;
+	u32 fence_alignment, unfenced_alignment;
+	u32 search_flag, alloc_flag;
+	u64 start, end;
+	u64 size, fence_size;
+	struct i915_vma *vma;
+	int ret;
+
+	if (i915_is_ggtt(vm)) {
+		u32 view_size;
+
+		if (WARN_ON(!ggtt_view))
+			return ERR_PTR(-EINVAL);
+
+		view_size = i915_ggtt_view_size(obj, ggtt_view);
+
+		fence_size = i915_gem_get_gtt_size(dev,
+						   view_size,
+						   obj->tiling_mode);
+		fence_alignment = i915_gem_get_gtt_alignment(dev,
+							     view_size,
+							     obj->tiling_mode,
+							     true);
+		unfenced_alignment = i915_gem_get_gtt_alignment(dev,
+								view_size,
+								obj->tiling_mode,
+								false);
+		size = flags & PIN_MAPPABLE ? fence_size : view_size;
+	} else {
+		fence_size = i915_gem_get_gtt_size(dev,
+						   obj->base.size,
+						   obj->tiling_mode);
+		fence_alignment = i915_gem_get_gtt_alignment(dev,
+							     obj->base.size,
+							     obj->tiling_mode,
+							     true);
+		unfenced_alignment =
+			i915_gem_get_gtt_alignment(dev,
+						   obj->base.size,
+						   obj->tiling_mode,
+						   false);
+		size = flags & PIN_MAPPABLE ? fence_size : obj->base.size;
+	}
+
+	start = flags & PIN_OFFSET_BIAS ? flags & PIN_OFFSET_MASK : 0;
+	end = vm->total;
+	if (flags & PIN_MAPPABLE)
+		end = min_t(u64, end, ggtt->mappable_end);
+	if (flags & PIN_ZONE_4G)
+		end = min_t(u64, end, (1ULL << 32) - PAGE_SIZE);
+
+	if (alignment == 0)
+		alignment = flags & PIN_MAPPABLE ? fence_alignment :
+						unfenced_alignment;
+	if (flags & PIN_MAPPABLE && alignment & (fence_alignment - 1)) {
+		DRM_DEBUG("Invalid object (view type=%u) alignment requested %u\n",
+			  ggtt_view ? ggtt_view->type : 0,
+			  alignment);
+		return ERR_PTR(-EINVAL);
+	}
+
+	/* If binding the object/GGTT view requires more space than the entire
+	 * aperture has, reject it early before evicting everything in a vain
+	 * attempt to find space.
+	 */
+	if (size > end) {
+		DRM_DEBUG("Attempting to bind an object (view type=%u) larger than the aperture: size=%llu > %s aperture=%llu\n",
+			  ggtt_view ? ggtt_view->type : 0,
+			  size,
+			  flags & PIN_MAPPABLE ? "mappable" : "total",
+			  end);
+		return ERR_PTR(-E2BIG);
+	}
+
+	ret = i915_gem_object_get_pages(obj);
+	if (ret)
+		return ERR_PTR(ret);
+
+	i915_gem_object_pin_pages(obj);
+
+	vma = ggtt_view ? i915_gem_obj_lookup_or_create_ggtt_vma(obj, ggtt_view) :
+			  i915_gem_obj_lookup_or_create_vma(obj, vm);
+
+	if (IS_ERR(vma))
+		goto err_unpin;
+
+	if (flags & PIN_OFFSET_FIXED) {
+		uint64_t offset = flags & PIN_OFFSET_MASK;
+
+		if (offset & (alignment - 1) || offset + size > end) {
+			ret = -EINVAL;
+			goto err_free_vma;
+		}
+		vma->node.start = offset;
+		vma->node.size = size;
+		vma->node.color = obj->cache_level;
+		ret = drm_mm_reserve_node(&vm->mm, &vma->node);
+		if (ret) {
+			ret = i915_gem_evict_for_vma(vma);
+			if (ret == 0)
+				ret = drm_mm_reserve_node(&vm->mm, &vma->node);
+		}
+		if (ret)
+			goto err_free_vma;
+	} else {
+		if (flags & PIN_HIGH) {
+			search_flag = DRM_MM_SEARCH_BELOW;
+			alloc_flag = DRM_MM_CREATE_TOP;
+		} else {
+			search_flag = DRM_MM_SEARCH_DEFAULT;
+			alloc_flag = DRM_MM_CREATE_DEFAULT;
+		}
+
+search_free:
+		ret = drm_mm_insert_node_in_range_generic(&vm->mm, &vma->node,
+							  size, alignment,
+							  obj->cache_level,
+							  start, end,
+							  search_flag,
+							  alloc_flag);
+		if (ret) {
+			ret = i915_gem_evict_something(dev, vm, size, alignment,
+						       obj->cache_level,
+						       start, end,
+						       flags);
+			if (ret == 0)
+				goto search_free;
+
+			goto err_free_vma;
+		}
+	}
+	if (WARN_ON(!i915_gem_valid_gtt_space(vma, obj->cache_level))) {
+		ret = -EINVAL;
+		goto err_remove_node;
+	}
+
+	trace_i915_vma_bind(vma, flags);
+	ret = i915_vma_bind(vma, obj->cache_level, flags);
+	if (ret)
+		goto err_remove_node;
+
+	list_move_tail(&obj->global_list, &dev_priv->mm.bound_list);
+	list_add_tail(&vma->vm_link, &vm->inactive_list);
+
+	return vma;
+
+err_remove_node:
+	drm_mm_remove_node(&vma->node);
+err_free_vma:
+	i915_gem_vma_destroy(vma);
+	vma = ERR_PTR(ret);
+err_unpin:
+	i915_gem_object_unpin_pages(obj);
+	return vma;
+}
+
+bool
+i915_gem_clflush_object(struct drm_i915_gem_object *obj,
+			bool force)
+{
+	/* If we don't have a page list set up, then we're not pinned
+	 * to GPU, and we can ignore the cache flush because it'll happen
+	 * again at bind time.
+	 */
+	if (obj->pages == NULL)
+		return false;
+
+	/*
+	 * Stolen memory is always coherent with the GPU as it is explicitly
+	 * marked as wc by the system, or the system is cache-coherent.
+	 */
+	if (obj->stolen || obj->phys_handle)
+		return false;
+
+	/* If the GPU is snooping the contents of the CPU cache,
+	 * we do not need to manually clear the CPU cache lines.  However,
+	 * the caches are only snooped when the render cache is
+	 * flushed/invalidated.  As we always have to emit invalidations
+	 * and flushes when moving into and out of the RENDER domain, correct
+	 * snooping behaviour occurs naturally as the result of our domain
+	 * tracking.
+	 */
+	if (!force && cpu_cache_is_coherent(obj->base.dev, obj->cache_level)) {
+		obj->cache_dirty = true;
+		return false;
+	}
+
+	trace_i915_gem_object_clflush(obj);
+	drm_clflush_sg(obj->pages);
+	obj->cache_dirty = false;
+
+	return true;
+}
+
+/** Flushes the GTT write domain for the object if it's dirty. */
+static void
+i915_gem_object_flush_gtt_write_domain(struct drm_i915_gem_object *obj)
+{
+	uint32_t old_write_domain;
+
+	if (obj->base.write_domain != I915_GEM_DOMAIN_GTT)
+		return;
+
+	/* No actual flushing is required for the GTT write domain.  Writes
+	 * to it immediately go to main memory as far as we know, so there's
+	 * no chipset flush.  It also doesn't land in render cache.
+	 *
+	 * However, we do have to enforce the order so that all writes through
+	 * the GTT land before any writes to the device, such as updates to
+	 * the GATT itself.
+	 */
+	wmb();
+
+	old_write_domain = obj->base.write_domain;
+	obj->base.write_domain = 0;
+
+	intel_fb_obj_flush(obj, false, ORIGIN_GTT);
+
+	trace_i915_gem_object_change_domain(obj,
+					    obj->base.read_domains,
+					    old_write_domain);
+}
+
+/** Flushes the CPU write domain for the object if it's dirty. */
+static void
+i915_gem_object_flush_cpu_write_domain(struct drm_i915_gem_object *obj)
+{
+	uint32_t old_write_domain;
+
+	if (obj->base.write_domain != I915_GEM_DOMAIN_CPU)
+		return;
+
+	if (i915_gem_clflush_object(obj, obj->pin_display))
+		i915_gem_chipset_flush(obj->base.dev);
+
+	old_write_domain = obj->base.write_domain;
+	obj->base.write_domain = 0;
+
+	intel_fb_obj_flush(obj, false, ORIGIN_CPU);
+
+	trace_i915_gem_object_change_domain(obj,
+					    obj->base.read_domains,
+					    old_write_domain);
+}
+
+/**
+ * Moves a single object to the GTT read, and possibly write domain.
+ *
+ * This function returns when the move is complete, including waiting on
+ * flushes to occur.
+ */
+int
+i915_gem_object_set_to_gtt_domain(struct drm_i915_gem_object *obj, bool write)
+{
+	struct drm_device *dev = obj->base.dev;
+	struct drm_i915_private *dev_priv = to_i915(dev);
+	struct i915_ggtt *ggtt = &dev_priv->ggtt;
+	uint32_t old_write_domain, old_read_domains;
+	struct i915_vma *vma;
+	int ret;
+
+	if (obj->base.write_domain == I915_GEM_DOMAIN_GTT)
+		return 0;
+
+	ret = i915_gem_object_wait_rendering(obj, !write);
+	if (ret)
+		return ret;
+
+	/* Flush and acquire obj->pages so that we are coherent through
+	 * direct access in memory with previous cached writes through
+	 * shmemfs and that our cache domain tracking remains valid.
+	 * For example, if the obj->filp was moved to swap without us
+	 * being notified and releasing the pages, we would mistakenly
+	 * continue to assume that the obj remained out of the CPU cached
+	 * domain.
+	 */
+	ret = i915_gem_object_get_pages(obj);
+	if (ret)
+		return ret;
+
+	i915_gem_object_flush_cpu_write_domain(obj);
+
+	/* Serialise direct access to this object with the barriers for
+	 * coherent writes from the GPU, by effectively invalidating the
+	 * GTT domain upon first access.
+	 */
+	if ((obj->base.read_domains & I915_GEM_DOMAIN_GTT) == 0)
+		mb();
+
+	old_write_domain = obj->base.write_domain;
+	old_read_domains = obj->base.read_domains;
+
+	/* It should now be out of any other write domains, and we can update
+	 * the domain values for our changes.
+	 */
+	BUG_ON((obj->base.write_domain & ~I915_GEM_DOMAIN_GTT) != 0);
+	obj->base.read_domains |= I915_GEM_DOMAIN_GTT;
+	if (write) {
+		obj->base.read_domains = I915_GEM_DOMAIN_GTT;
+		obj->base.write_domain = I915_GEM_DOMAIN_GTT;
+		obj->dirty = 1;
+	}
+
+	trace_i915_gem_object_change_domain(obj,
+					    old_read_domains,
+					    old_write_domain);
+
+	/* And bump the LRU for this access */
+	vma = i915_gem_obj_to_ggtt(obj);
+	if (vma && drm_mm_node_allocated(&vma->node) && !obj->active)
+		list_move_tail(&vma->vm_link,
+			       &ggtt->base.inactive_list);
+
+	return 0;
+}
+
+/**
+ * Changes the cache-level of an object across all VMA.
+ *
+ * After this function returns, the object will be in the new cache-level
+ * across all GTT and the contents of the backing storage will be coherent,
+ * with respect to the new cache-level. In order to keep the backing storage
+ * coherent for all users, we only allow a single cache level to be set
+ * globally on the object and prevent it from being changed whilst the
+ * hardware is reading from the object. That is if the object is currently
+ * on the scanout it will be set to uncached (or equivalent display
+ * cache coherency) and all non-MOCS GPU access will also be uncached so
+ * that all direct access to the scanout remains coherent.
+ */
+int i915_gem_object_set_cache_level(struct drm_i915_gem_object *obj,
+				    enum i915_cache_level cache_level)
+{
+	struct drm_device *dev = obj->base.dev;
+	struct i915_vma *vma, *next;
+	bool bound = false;
+	int ret = 0;
+
+	if (obj->cache_level == cache_level)
+		goto out;
+
+	/* Inspect the list of currently bound VMA and unbind any that would
+	 * be invalid given the new cache-level. This is principally to
+	 * catch the issue of the CS prefetch crossing page boundaries and
+	 * reading an invalid PTE on older architectures.
+	 */
+	list_for_each_entry_safe(vma, next, &obj->vma_list, obj_link) {
+		if (!drm_mm_node_allocated(&vma->node))
+			continue;
+
+		if (vma->pin_count) {
+			DRM_DEBUG("can not change the cache level of pinned objects\n");
+			return -EBUSY;
+		}
+
+		if (!i915_gem_valid_gtt_space(vma, cache_level)) {
+			ret = i915_vma_unbind(vma);
+			if (ret)
+				return ret;
+		} else
+			bound = true;
+	}
+
+	/* We can reuse the existing drm_mm nodes but need to change the
+	 * cache-level on the PTE. We could simply unbind them all and
+	 * rebind with the correct cache-level on next use. However since
+	 * we already have a valid slot, dma mapping, pages etc, we may as
+	 * rewrite the PTE in the belief that doing so tramples upon less
+	 * state and so involves less work.
+	 */
+	if (bound) {
+		/* Before we change the PTE, the GPU must not be accessing it.
+		 * If we wait upon the object, we know that all the bound
+		 * VMA are no longer active.
+		 */
+		ret = i915_gem_object_wait_rendering(obj, false);
+		if (ret)
+			return ret;
+
+		if (!HAS_LLC(dev) && cache_level != I915_CACHE_NONE) {
+			/* Access to snoopable pages through the GTT is
+			 * incoherent and on some machines causes a hard
+			 * lockup. Relinquish the CPU mmaping to force
+			 * userspace to refault in the pages and we can
+			 * then double check if the GTT mapping is still
+			 * valid for that pointer access.
+			 */
+			i915_gem_release_mmap(obj);
+
+			/* As we no longer need a fence for GTT access,
+			 * we can relinquish it now (and so prevent having
+			 * to steal a fence from someone else on the next
+			 * fence request). Note GPU activity would have
+			 * dropped the fence as all snoopable access is
+			 * supposed to be linear.
+			 */
+			ret = i915_gem_object_put_fence(obj);
+			if (ret)
+				return ret;
+		} else {
+			/* We either have incoherent backing store and
+			 * so no GTT access or the architecture is fully
+			 * coherent. In such cases, existing GTT mmaps
+			 * ignore the cache bit in the PTE and we can
+			 * rewrite it without confusing the GPU or having
+			 * to force userspace to fault back in its mmaps.
+			 */
+		}
+
+		list_for_each_entry(vma, &obj->vma_list, obj_link) {
+			if (!drm_mm_node_allocated(&vma->node))
+				continue;
+
+			ret = i915_vma_bind(vma, cache_level, PIN_UPDATE);
+			if (ret)
+				return ret;
+		}
+	}
+
+	list_for_each_entry(vma, &obj->vma_list, obj_link)
+		vma->node.color = cache_level;
+	obj->cache_level = cache_level;
+
+out:
+	/* Flush the dirty CPU caches to the backing storage so that the
+	 * object is now coherent at its new cache level (with respect
+	 * to the access domain).
+	 */
+	if (obj->cache_dirty &&
+	    obj->base.write_domain != I915_GEM_DOMAIN_CPU &&
+	    cpu_write_needs_clflush(obj)) {
+		if (i915_gem_clflush_object(obj, true))
+			i915_gem_chipset_flush(obj->base.dev);
+	}
+
+	return 0;
+}
+
+int i915_gem_get_caching_ioctl(struct drm_device *dev, void *data,
+			       struct drm_file *file)
+{
+	struct drm_i915_gem_caching *args = data;
+	struct drm_i915_gem_object *obj;
+
+	obj = to_intel_bo(drm_gem_object_lookup(dev, file, args->handle));
+	if (&obj->base == NULL)
+		return -ENOENT;
+
+	switch (obj->cache_level) {
+	case I915_CACHE_LLC:
+	case I915_CACHE_L3_LLC:
+		args->caching = I915_CACHING_CACHED;
+		break;
+
+	case I915_CACHE_WT:
+		args->caching = I915_CACHING_DISPLAY;
+		break;
+
+	default:
+		args->caching = I915_CACHING_NONE;
+		break;
+	}
+
+	drm_gem_object_unreference_unlocked(&obj->base);
+	return 0;
+}
+
+int i915_gem_set_caching_ioctl(struct drm_device *dev, void *data,
+			       struct drm_file *file)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct drm_i915_gem_caching *args = data;
+	struct drm_i915_gem_object *obj;
+	enum i915_cache_level level;
+	int ret;
+
+	switch (args->caching) {
+	case I915_CACHING_NONE:
+		level = I915_CACHE_NONE;
+		break;
+	case I915_CACHING_CACHED:
+		/*
+		 * Due to a HW issue on BXT A stepping, GPU stores via a
+		 * snooped mapping may leave stale data in a corresponding CPU
+		 * cacheline, whereas normally such cachelines would get
+		 * invalidated.
+		 */
+		if (!HAS_LLC(dev) && !HAS_SNOOP(dev))
+			return -ENODEV;
+
+		level = I915_CACHE_LLC;
+		break;
+	case I915_CACHING_DISPLAY:
+		level = HAS_WT(dev) ? I915_CACHE_WT : I915_CACHE_NONE;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	intel_runtime_pm_get(dev_priv);
+
+	ret = i915_mutex_lock_interruptible(dev);
+	if (ret)
+		goto rpm_put;
+
+	obj = to_intel_bo(drm_gem_object_lookup(dev, file, args->handle));
+	if (&obj->base == NULL) {
+		ret = -ENOENT;
+		goto unlock;
+	}
+
+	ret = i915_gem_object_set_cache_level(obj, level);
+
+	drm_gem_object_unreference(&obj->base);
+unlock:
+	mutex_unlock(&dev->struct_mutex);
+rpm_put:
+	intel_runtime_pm_put(dev_priv);
+
+	return ret;
+}
+
+/*
+ * Prepare buffer for display plane (scanout, cursors, etc).
+ * Can be called from an uninterruptible phase (modesetting) and allows
+ * any flushes to be pipelined (for pageflips).
+ */
+int
+i915_gem_object_pin_to_display_plane(struct drm_i915_gem_object *obj,
+				     u32 alignment,
+				     const struct i915_ggtt_view *view)
+{
+	u32 old_read_domains, old_write_domain;
+	int ret;
+
+	/* Mark the pin_display early so that we account for the
+	 * display coherency whilst setting up the cache domains.
+	 */
+	obj->pin_display++;
+
+	/* The display engine is not coherent with the LLC cache on gen6.  As
+	 * a result, we make sure that the pinning that is about to occur is
+	 * done with uncached PTEs. This is lowest common denominator for all
+	 * chipsets.
+	 *
+	 * However for gen6+, we could do better by using the GFDT bit instead
+	 * of uncaching, which would allow us to flush all the LLC-cached data
+	 * with that bit in the PTE to main memory with just one PIPE_CONTROL.
+	 */
+	ret = i915_gem_object_set_cache_level(obj,
+					      HAS_WT(obj->base.dev) ? I915_CACHE_WT : I915_CACHE_NONE);
+	if (ret)
+		goto err_unpin_display;
+
+	/* As the user may map the buffer once pinned in the display plane
+	 * (e.g. libkms for the bootup splash), we have to ensure that we
+	 * always use map_and_fenceable for all scanout buffers.
+	 */
+	ret = i915_gem_object_ggtt_pin(obj, view, alignment,
+				       view->type == I915_GGTT_VIEW_NORMAL ?
+				       PIN_MAPPABLE : 0);
+	if (ret)
+		goto err_unpin_display;
+
+	i915_gem_object_flush_cpu_write_domain(obj);
+
+	old_write_domain = obj->base.write_domain;
+	old_read_domains = obj->base.read_domains;
+
+	/* It should now be out of any other write domains, and we can update
+	 * the domain values for our changes.
+	 */
+	obj->base.write_domain = 0;
+	obj->base.read_domains |= I915_GEM_DOMAIN_GTT;
+
+	trace_i915_gem_object_change_domain(obj,
+					    old_read_domains,
+					    old_write_domain);
+
+	return 0;
+
+err_unpin_display:
+	obj->pin_display--;
+	return ret;
+}
+
+void
+i915_gem_object_unpin_from_display_plane(struct drm_i915_gem_object *obj,
+					 const struct i915_ggtt_view *view)
+{
+	if (WARN_ON(obj->pin_display == 0))
+		return;
+
+	i915_gem_object_ggtt_unpin_view(obj, view);
+
+	obj->pin_display--;
+}
+
+/**
+ * Moves a single object to the CPU read, and possibly write domain.
+ *
+ * This function returns when the move is complete, including waiting on
+ * flushes to occur.
+ */
+int
+i915_gem_object_set_to_cpu_domain(struct drm_i915_gem_object *obj, bool write)
+{
+	uint32_t old_write_domain, old_read_domains;
+	int ret;
+
+	if (obj->base.write_domain == I915_GEM_DOMAIN_CPU)
+		return 0;
+
+	ret = i915_gem_object_wait_rendering(obj, !write);
+	if (ret)
+		return ret;
+
+	i915_gem_object_flush_gtt_write_domain(obj);
+
+	old_write_domain = obj->base.write_domain;
+	old_read_domains = obj->base.read_domains;
+
+	/* Flush the CPU cache if it's still invalid. */
+	if ((obj->base.read_domains & I915_GEM_DOMAIN_CPU) == 0) {
+		i915_gem_clflush_object(obj, false);
+
+		obj->base.read_domains |= I915_GEM_DOMAIN_CPU;
+	}
+
+	/* It should now be out of any other write domains, and we can update
+	 * the domain values for our changes.
+	 */
+	BUG_ON((obj->base.write_domain & ~I915_GEM_DOMAIN_CPU) != 0);
+
+	/* If we're writing through the CPU, then the GPU read domains will
+	 * need to be invalidated at next use.
+	 */
+	if (write) {
+		obj->base.read_domains = I915_GEM_DOMAIN_CPU;
+		obj->base.write_domain = I915_GEM_DOMAIN_CPU;
+	}
+
+	trace_i915_gem_object_change_domain(obj,
+					    old_read_domains,
+					    old_write_domain);
+
+	return 0;
+}
+
+/* Throttle our rendering by waiting until the ring has completed our requests
+ * emitted over 20 msec ago.
+ *
+ * Note that if we were to use the current jiffies each time around the loop,
+ * we wouldn't escape the function with any frames outstanding if the time to
+ * render a frame was over 20ms.
+ *
+ * This should get us reasonable parallelism between CPU and GPU but also
+ * relatively low latency when blocking on a particular request to finish.
+ */
+static int
+i915_gem_ring_throttle(struct drm_device *dev, struct drm_file *file)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct drm_i915_file_private *file_priv = file->driver_priv;
+	unsigned long recent_enough = jiffies - DRM_I915_THROTTLE_JIFFIES;
+	struct drm_i915_gem_request *request, *target = NULL;
+	int ret;
+
+	ret = i915_gem_wait_for_error(&dev_priv->gpu_error);
+	if (ret)
+		return ret;
+
+	/* ABI: return -EIO if already wedged */
+	if (i915_terminally_wedged(&dev_priv->gpu_error))
+		return -EIO;
+
+	spin_lock(&file_priv->mm.lock);
+	list_for_each_entry(request, &file_priv->mm.request_list, client_list) {
+		if (time_after_eq(request->emitted_jiffies, recent_enough))
+			break;
+
+		/*
+		 * Note that the request might not have been submitted yet.
+		 * In which case emitted_jiffies will be zero.
+		 */
+		if (!request->emitted_jiffies)
+			continue;
+
+		target = request;
+	}
+	if (target)
+		i915_gem_request_reference(target);
+	spin_unlock(&file_priv->mm.lock);
+
+	if (target == NULL)
+		return 0;
+
+	ret = __i915_wait_request(target, true, NULL, NULL);
+	if (ret == 0)
+		queue_delayed_work(dev_priv->wq, &dev_priv->mm.retire_work, 0);
+
+	i915_gem_request_unreference__unlocked(target);
+
+	return ret;
+}
+
+static bool
+i915_vma_misplaced(struct i915_vma *vma, uint32_t alignment, uint64_t flags)
+{
+	struct drm_i915_gem_object *obj = vma->obj;
+
+	if (alignment &&
+	    vma->node.start & (alignment - 1))
+		return true;
+
+	if (flags & PIN_MAPPABLE && !obj->map_and_fenceable)
+		return true;
+
+	if (flags & PIN_OFFSET_BIAS &&
+	    vma->node.start < (flags & PIN_OFFSET_MASK))
+		return true;
+
+	if (flags & PIN_OFFSET_FIXED &&
+	    vma->node.start != (flags & PIN_OFFSET_MASK))
+		return true;
+
+	return false;
+}
+
+void __i915_vma_set_map_and_fenceable(struct i915_vma *vma)
+{
+	struct drm_i915_gem_object *obj = vma->obj;
+	bool mappable, fenceable;
+	u32 fence_size, fence_alignment;
+
+	fence_size = i915_gem_get_gtt_size(obj->base.dev,
+					   obj->base.size,
+					   obj->tiling_mode);
+	fence_alignment = i915_gem_get_gtt_alignment(obj->base.dev,
+						     obj->base.size,
+						     obj->tiling_mode,
+						     true);
+
+	fenceable = (vma->node.size == fence_size &&
+		     (vma->node.start & (fence_alignment - 1)) == 0);
+
+	mappable = (vma->node.start + fence_size <=
+		    to_i915(obj->base.dev)->ggtt.mappable_end);
+
+	obj->map_and_fenceable = mappable && fenceable;
+}
+
+static int
+i915_gem_object_do_pin(struct drm_i915_gem_object *obj,
+		       struct i915_address_space *vm,
+		       const struct i915_ggtt_view *ggtt_view,
+		       uint32_t alignment,
+		       uint64_t flags)
+{
+	struct drm_i915_private *dev_priv = obj->base.dev->dev_private;
+	struct i915_vma *vma;
+	unsigned bound;
+	int ret;
+
+	if (WARN_ON(vm == &dev_priv->mm.aliasing_ppgtt->base))
+		return -ENODEV;
+
+	if (WARN_ON(flags & (PIN_GLOBAL | PIN_MAPPABLE) && !i915_is_ggtt(vm)))
+		return -EINVAL;
+
+	if (WARN_ON((flags & (PIN_MAPPABLE | PIN_GLOBAL)) == PIN_MAPPABLE))
+		return -EINVAL;
+
+	if (WARN_ON(i915_is_ggtt(vm) != !!ggtt_view))
+		return -EINVAL;
+
+	vma = ggtt_view ? i915_gem_obj_to_ggtt_view(obj, ggtt_view) :
+			  i915_gem_obj_to_vma(obj, vm);
+
+	if (vma) {
+		if (WARN_ON(vma->pin_count == DRM_I915_GEM_OBJECT_MAX_PIN_COUNT))
+			return -EBUSY;
+
+		if (i915_vma_misplaced(vma, alignment, flags)) {
+			WARN(vma->pin_count,
+			     "bo is already pinned in %s with incorrect alignment:"
+			     " offset=%08x %08x, req.alignment=%x, req.map_and_fenceable=%d,"
+			     " obj->map_and_fenceable=%d\n",
+			     ggtt_view ? "ggtt" : "ppgtt",
+			     upper_32_bits(vma->node.start),
+			     lower_32_bits(vma->node.start),
+			     alignment,
+			     !!(flags & PIN_MAPPABLE),
+			     obj->map_and_fenceable);
+			ret = i915_vma_unbind(vma);
+			if (ret)
+				return ret;
+
+			vma = NULL;
+		}
+	}
+
+	bound = vma ? vma->bound : 0;
+	if (vma == NULL || !drm_mm_node_allocated(&vma->node)) {
+		vma = i915_gem_object_bind_to_vm(obj, vm, ggtt_view, alignment,
+						 flags);
+		if (IS_ERR(vma))
+			return PTR_ERR(vma);
+	} else {
+		ret = i915_vma_bind(vma, obj->cache_level, flags);
+		if (ret)
+			return ret;
+	}
+
+	if (ggtt_view && ggtt_view->type == I915_GGTT_VIEW_NORMAL &&
+	    (bound ^ vma->bound) & GLOBAL_BIND) {
+		__i915_vma_set_map_and_fenceable(vma);
+		WARN_ON(flags & PIN_MAPPABLE && !obj->map_and_fenceable);
+	}
+
+	vma->pin_count++;
+	return 0;
+}
+
+int
+i915_gem_object_pin(struct drm_i915_gem_object *obj,
+		    struct i915_address_space *vm,
+		    uint32_t alignment,
+		    uint64_t flags)
+{
+	return i915_gem_object_do_pin(obj, vm,
+				      i915_is_ggtt(vm) ? &i915_ggtt_view_normal : NULL,
+				      alignment, flags);
+}
+
+int
+i915_gem_object_ggtt_pin(struct drm_i915_gem_object *obj,
+			 const struct i915_ggtt_view *view,
+			 uint32_t alignment,
+			 uint64_t flags)
+{
+	struct drm_device *dev = obj->base.dev;
+	struct drm_i915_private *dev_priv = to_i915(dev);
+	struct i915_ggtt *ggtt = &dev_priv->ggtt;
+
+	BUG_ON(!view);
+
+	return i915_gem_object_do_pin(obj, &ggtt->base, view,
+				      alignment, flags | PIN_GLOBAL);
+}
+
+void
+i915_gem_object_ggtt_unpin_view(struct drm_i915_gem_object *obj,
+				const struct i915_ggtt_view *view)
+{
+	struct i915_vma *vma = i915_gem_obj_to_ggtt_view(obj, view);
+
+	WARN_ON(vma->pin_count == 0);
+	WARN_ON(!i915_gem_obj_ggtt_bound_view(obj, view));
+
+	--vma->pin_count;
+}
+
+int
+i915_gem_busy_ioctl(struct drm_device *dev, void *data,
+		    struct drm_file *file)
+{
+	struct drm_i915_gem_busy *args = data;
+	struct drm_i915_gem_object *obj;
+	int ret;
+
+	ret = i915_mutex_lock_interruptible(dev);
+	if (ret)
+		return ret;
+
+	obj = to_intel_bo(drm_gem_object_lookup(dev, file, args->handle));
+	if (&obj->base == NULL) {
+		ret = -ENOENT;
+		goto unlock;
+	}
+
+	/* Count all active objects as busy, even if they are currently not used
+	 * by the gpu. Users of this interface expect objects to eventually
+	 * become non-busy without any further actions, therefore emit any
+	 * necessary flushes here.
+	 */
+	ret = i915_gem_object_flush_active(obj);
+	if (ret)
+		goto unref;
+
+	args->busy = 0;
+	if (obj->active) {
+		int i;
+
+		for (i = 0; i < I915_NUM_ENGINES; i++) {
+			struct drm_i915_gem_request *req;
+
+			req = obj->last_read_req[i];
+			if (req)
+				args->busy |= 1 << (16 + req->engine->exec_id);
+		}
+		if (obj->last_write_req)
+			args->busy |= obj->last_write_req->engine->exec_id;
+	}
+
+unref:
+	drm_gem_object_unreference(&obj->base);
+unlock:
+	mutex_unlock(&dev->struct_mutex);
+	return ret;
+}
+
+int
+i915_gem_throttle_ioctl(struct drm_device *dev, void *data,
+			struct drm_file *file_priv)
+{
+	return i915_gem_ring_throttle(dev, file_priv);
+}
+
+int
+i915_gem_madvise_ioctl(struct drm_device *dev, void *data,
+		       struct drm_file *file_priv)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct drm_i915_gem_madvise *args = data;
+	struct drm_i915_gem_object *obj;
+	int ret;
+
+	switch (args->madv) {
+	case I915_MADV_DONTNEED:
+	case I915_MADV_WILLNEED:
+	    break;
+	default:
+	    return -EINVAL;
+	}
+
+	ret = i915_mutex_lock_interruptible(dev);
+	if (ret)
+		return ret;
+
+	obj = to_intel_bo(drm_gem_object_lookup(dev, file_priv, args->handle));
+	if (&obj->base == NULL) {
+		ret = -ENOENT;
+		goto unlock;
+	}
+
+	if (i915_gem_obj_is_pinned(obj)) {
+		ret = -EINVAL;
+		goto out;
+	}
+
+	if (obj->pages &&
+	    obj->tiling_mode != I915_TILING_NONE &&
+	    dev_priv->quirks & QUIRK_PIN_SWIZZLED_PAGES) {
+		if (obj->madv == I915_MADV_WILLNEED)
+			i915_gem_object_unpin_pages(obj);
+		if (args->madv == I915_MADV_WILLNEED)
+			i915_gem_object_pin_pages(obj);
+	}
+
+	if (obj->madv != __I915_MADV_PURGED)
+		obj->madv = args->madv;
+
+	/* if the object is no longer attached, discard its backing storage */
+	if (obj->madv == I915_MADV_DONTNEED && obj->pages == NULL)
+		i915_gem_object_truncate(obj);
+
+	args->retained = obj->madv != __I915_MADV_PURGED;
+
+out:
+	drm_gem_object_unreference(&obj->base);
+unlock:
+	mutex_unlock(&dev->struct_mutex);
+	return ret;
+}
+
+void i915_gem_object_init(struct drm_i915_gem_object *obj,
+			  const struct drm_i915_gem_object_ops *ops)
+{
+	int i;
+
+	INIT_LIST_HEAD(&obj->global_list);
+	for (i = 0; i < I915_NUM_ENGINES; i++)
+		INIT_LIST_HEAD(&obj->engine_list[i]);
+	INIT_LIST_HEAD(&obj->obj_exec_link);
+	INIT_LIST_HEAD(&obj->vma_list);
+	INIT_LIST_HEAD(&obj->batch_pool_link);
+
+	obj->ops = ops;
+
+	obj->fence_reg = I915_FENCE_REG_NONE;
+	obj->madv = I915_MADV_WILLNEED;
+
+	i915_gem_info_add_obj(obj->base.dev->dev_private, obj->base.size);
+}
+
+static const struct drm_i915_gem_object_ops i915_gem_object_ops = {
+	.flags = I915_GEM_OBJECT_HAS_STRUCT_PAGE,
+	.get_pages = i915_gem_object_get_pages_gtt,
+	.put_pages = i915_gem_object_put_pages_gtt,
+};
+
+struct drm_i915_gem_object *i915_gem_alloc_object(struct drm_device *dev,
+						  size_t size)
+{
+	struct drm_i915_gem_object *obj;
+	struct address_space *mapping;
+	gfp_t mask;
+
+	obj = i915_gem_object_alloc(dev);
+	if (obj == NULL)
+		return NULL;
+
+	if (drm_gem_object_init(dev, &obj->base, size) != 0) {
+		i915_gem_object_free(obj);
+		return NULL;
+	}
+
+	mask = GFP_HIGHUSER | __GFP_RECLAIMABLE;
+	if (IS_CRESTLINE(dev) || IS_BROADWATER(dev)) {
+		/* 965gm cannot relocate objects above 4GiB. */
+		mask &= ~__GFP_HIGHMEM;
+		mask |= __GFP_DMA32;
+	}
+
+	mapping = file_inode(obj->base.filp)->i_mapping;
+	mapping_set_gfp_mask(mapping, mask);
+
+	i915_gem_object_init(obj, &i915_gem_object_ops);
+
+	obj->base.write_domain = I915_GEM_DOMAIN_CPU;
+	obj->base.read_domains = I915_GEM_DOMAIN_CPU;
+
+	if (HAS_LLC(dev)) {
+		/* On some devices, we can have the GPU use the LLC (the CPU
+		 * cache) for about a 10% performance improvement
+		 * compared to uncached.  Graphics requests other than
+		 * display scanout are coherent with the CPU in
+		 * accessing this cache.  This means in this mode we
+		 * don't need to clflush on the CPU side, and on the
+		 * GPU side we only need to flush internal caches to
+		 * get data visible to the CPU.
+		 *
+		 * However, we maintain the display planes as UC, and so
+		 * need to rebind when first used as such.
+		 */
+		obj->cache_level = I915_CACHE_LLC;
+	} else
+		obj->cache_level = I915_CACHE_NONE;
+
+	trace_i915_gem_object_create(obj);
+
+	return obj;
+}
+
+static bool discard_backing_storage(struct drm_i915_gem_object *obj)
+{
+	/* If we are the last user of the backing storage (be it shmemfs
+	 * pages or stolen etc), we know that the pages are going to be
+	 * immediately released. In this case, we can then skip copying
+	 * back the contents from the GPU.
+	 */
+
+	if (obj->madv != I915_MADV_WILLNEED)
+		return false;
+
+	if (obj->base.filp == NULL)
+		return true;
+
+	/* At first glance, this looks racy, but then again so would be
+	 * userspace racing mmap against close. However, the first external
+	 * reference to the filp can only be obtained through the
+	 * i915_gem_mmap_ioctl() which safeguards us against the user
+	 * acquiring such a reference whilst we are in the middle of
+	 * freeing the object.
+	 */
+	return atomic_long_read(&obj->base.filp->f_count) == 1;
+}
+
+void i915_gem_free_object(struct drm_gem_object *gem_obj)
+{
+	struct drm_i915_gem_object *obj = to_intel_bo(gem_obj);
+	struct drm_device *dev = obj->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct i915_vma *vma, *next;
+
+	intel_runtime_pm_get(dev_priv);
+
+	trace_i915_gem_object_destroy(obj);
+
+	list_for_each_entry_safe(vma, next, &obj->vma_list, obj_link) {
+		int ret;
+
+		vma->pin_count = 0;
+		ret = i915_vma_unbind(vma);
+		if (WARN_ON(ret == -ERESTARTSYS)) {
+			bool was_interruptible;
+
+			was_interruptible = dev_priv->mm.interruptible;
+			dev_priv->mm.interruptible = false;
+
+			WARN_ON(i915_vma_unbind(vma));
+
+			dev_priv->mm.interruptible = was_interruptible;
+		}
+	}
+
+	/* Stolen objects don't hold a ref, but do hold pin count. Fix that up
+	 * before progressing. */
+	if (obj->stolen)
+		i915_gem_object_unpin_pages(obj);
+
+	WARN_ON(obj->frontbuffer_bits);
+
+	if (obj->pages && obj->madv == I915_MADV_WILLNEED &&
+	    dev_priv->quirks & QUIRK_PIN_SWIZZLED_PAGES &&
+	    obj->tiling_mode != I915_TILING_NONE)
+		i915_gem_object_unpin_pages(obj);
+
+	if (WARN_ON(obj->pages_pin_count))
+		obj->pages_pin_count = 0;
+	if (discard_backing_storage(obj))
+		obj->madv = I915_MADV_DONTNEED;
+	i915_gem_object_put_pages(obj);
+	i915_gem_object_free_mmap_offset(obj);
+
+	BUG_ON(obj->pages);
+
+	if (obj->base.import_attach)
+		drm_prime_gem_destroy(&obj->base, NULL);
+
+	if (obj->ops->release)
+		obj->ops->release(obj);
+
+	drm_gem_object_release(&obj->base);
+	i915_gem_info_remove_obj(dev_priv, obj->base.size);
+
+	kfree(obj->bit_17);
+	i915_gem_object_free(obj);
+
+	intel_runtime_pm_put(dev_priv);
+}
+
+struct i915_vma *i915_gem_obj_to_vma(struct drm_i915_gem_object *obj,
+				     struct i915_address_space *vm)
+{
+	struct i915_vma *vma;
+	list_for_each_entry(vma, &obj->vma_list, obj_link) {
+		if (vma->ggtt_view.type == I915_GGTT_VIEW_NORMAL &&
+		    vma->vm == vm)
+			return vma;
+	}
+	return NULL;
+}
+
+struct i915_vma *i915_gem_obj_to_ggtt_view(struct drm_i915_gem_object *obj,
+					   const struct i915_ggtt_view *view)
+{
+	struct drm_device *dev = obj->base.dev;
+	struct drm_i915_private *dev_priv = to_i915(dev);
+	struct i915_ggtt *ggtt = &dev_priv->ggtt;
+	struct i915_vma *vma;
+
+	BUG_ON(!view);
+
+	list_for_each_entry(vma, &obj->vma_list, obj_link)
+		if (vma->vm == &ggtt->base &&
+		    i915_ggtt_view_equal(&vma->ggtt_view, view))
+			return vma;
+	return NULL;
+}
+
+void i915_gem_vma_destroy(struct i915_vma *vma)
+{
+	WARN_ON(vma->node.allocated);
+
+	/* Keep the vma as a placeholder in the execbuffer reservation lists */
+	if (!list_empty(&vma->exec_list))
+		return;
+
+	if (!vma->is_ggtt)
+		i915_ppgtt_put(i915_vm_to_ppgtt(vma->vm));
+
+	list_del(&vma->obj_link);
+
+	kmem_cache_free(to_i915(vma->obj->base.dev)->vmas, vma);
+}
+
+static void
+i915_gem_stop_engines(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_engine_cs *engine;
+
+	for_each_engine(engine, dev_priv)
+		dev_priv->gt.stop_engine(engine);
+}
+
+int
+i915_gem_suspend(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	int ret = 0;
+
+	mutex_lock(&dev->struct_mutex);
+	ret = i915_gpu_idle(dev);
+	if (ret)
+		goto err;
+
+	i915_gem_retire_requests(dev);
+
+	i915_gem_stop_engines(dev);
+	mutex_unlock(&dev->struct_mutex);
+
+	cancel_delayed_work_sync(&dev_priv->gpu_error.hangcheck_work);
+	cancel_delayed_work_sync(&dev_priv->mm.retire_work);
+	flush_delayed_work(&dev_priv->mm.idle_work);
+
+	/* Assert that we sucessfully flushed all the work and
+	 * reset the GPU back to its idle, low power state.
+	 */
+	WARN_ON(dev_priv->mm.busy);
+
+	return 0;
+
+err:
+	mutex_unlock(&dev->struct_mutex);
+	return ret;
+}
+
+int i915_gem_l3_remap(struct drm_i915_gem_request *req, int slice)
+{
+	struct intel_engine_cs *engine = req->engine;
+	struct drm_device *dev = engine->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	u32 *remap_info = dev_priv->l3_parity.remap_info[slice];
+	int i, ret;
+
+	if (!HAS_L3_DPF(dev) || !remap_info)
+		return 0;
+
+	ret = intel_ring_begin(req, GEN7_L3LOG_SIZE / 4 * 3);
+	if (ret)
+		return ret;
+
+	/*
+	 * Note: We do not worry about the concurrent register cacheline hang
+	 * here because no other code should access these registers other than
+	 * at initialization time.
+	 */
+	for (i = 0; i < GEN7_L3LOG_SIZE / 4; i++) {
+		intel_ring_emit(engine, MI_LOAD_REGISTER_IMM(1));
+		intel_ring_emit_reg(engine, GEN7_L3LOG(slice, i));
+		intel_ring_emit(engine, remap_info[i]);
+	}
+
+	intel_ring_advance(engine);
+
+	return ret;
+}
+
+void i915_gem_init_swizzling(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	if (INTEL_INFO(dev)->gen < 5 ||
+	    dev_priv->mm.bit_6_swizzle_x == I915_BIT_6_SWIZZLE_NONE)
+		return;
+
+	I915_WRITE(DISP_ARB_CTL, I915_READ(DISP_ARB_CTL) |
+				 DISP_TILE_SURFACE_SWIZZLING);
+
+	if (IS_GEN5(dev))
+		return;
+
+	I915_WRITE(TILECTL, I915_READ(TILECTL) | TILECTL_SWZCTL);
+	if (IS_GEN6(dev))
+		I915_WRITE(ARB_MODE, _MASKED_BIT_ENABLE(ARB_MODE_SWIZZLE_SNB));
+	else if (IS_GEN7(dev))
+		I915_WRITE(ARB_MODE, _MASKED_BIT_ENABLE(ARB_MODE_SWIZZLE_IVB));
+	else if (IS_GEN8(dev))
+		I915_WRITE(GAMTARBMODE, _MASKED_BIT_ENABLE(ARB_MODE_SWIZZLE_BDW));
+	else
+		BUG();
+}
+
+static void init_unused_ring(struct drm_device *dev, u32 base)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	I915_WRITE(RING_CTL(base), 0);
+	I915_WRITE(RING_HEAD(base), 0);
+	I915_WRITE(RING_TAIL(base), 0);
+	I915_WRITE(RING_START(base), 0);
+}
+
+static void init_unused_rings(struct drm_device *dev)
+{
+	if (IS_I830(dev)) {
+		init_unused_ring(dev, PRB1_BASE);
+		init_unused_ring(dev, SRB0_BASE);
+		init_unused_ring(dev, SRB1_BASE);
+		init_unused_ring(dev, SRB2_BASE);
+		init_unused_ring(dev, SRB3_BASE);
+	} else if (IS_GEN2(dev)) {
+		init_unused_ring(dev, SRB0_BASE);
+		init_unused_ring(dev, SRB1_BASE);
+	} else if (IS_GEN3(dev)) {
+		init_unused_ring(dev, PRB1_BASE);
+		init_unused_ring(dev, PRB2_BASE);
+	}
+}
+
+int i915_gem_init_engines(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	int ret;
+
+	ret = intel_init_render_ring_buffer(dev);
+	if (ret)
+		return ret;
+
+	if (HAS_BSD(dev)) {
+		ret = intel_init_bsd_ring_buffer(dev);
+		if (ret)
+			goto cleanup_render_ring;
+	}
+
+	if (HAS_BLT(dev)) {
+		ret = intel_init_blt_ring_buffer(dev);
+		if (ret)
+			goto cleanup_bsd_ring;
+	}
+
+	if (HAS_VEBOX(dev)) {
+		ret = intel_init_vebox_ring_buffer(dev);
+		if (ret)
+			goto cleanup_blt_ring;
+	}
+
+	if (HAS_BSD2(dev)) {
+		ret = intel_init_bsd2_ring_buffer(dev);
+		if (ret)
+			goto cleanup_vebox_ring;
+	}
+
+	return 0;
+
+cleanup_vebox_ring:
+	intel_cleanup_engine(&dev_priv->engine[VECS]);
+cleanup_blt_ring:
+	intel_cleanup_engine(&dev_priv->engine[BCS]);
+cleanup_bsd_ring:
+	intel_cleanup_engine(&dev_priv->engine[VCS]);
+cleanup_render_ring:
+	intel_cleanup_engine(&dev_priv->engine[RCS]);
+
+	return ret;
+}
+
+int
+i915_gem_init_hw(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_engine_cs *engine;
+	int ret, j;
+
+	/* Double layer security blanket, see i915_gem_init() */
+	intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL);
+
+	if (HAS_EDRAM(dev) && INTEL_GEN(dev_priv) < 9)
+		I915_WRITE(HSW_IDICR, I915_READ(HSW_IDICR) | IDIHASHMSK(0xf));
+
+	if (IS_HASWELL(dev))
+		I915_WRITE(MI_PREDICATE_RESULT_2, IS_HSW_GT3(dev) ?
+			   LOWER_SLICE_ENABLED : LOWER_SLICE_DISABLED);
+
+	if (HAS_PCH_NOP(dev)) {
+		if (IS_IVYBRIDGE(dev)) {
+			u32 temp = I915_READ(GEN7_MSG_CTL);
+			temp &= ~(WAIT_FOR_PCH_FLR_ACK | WAIT_FOR_PCH_RESET_ACK);
+			I915_WRITE(GEN7_MSG_CTL, temp);
+		} else if (INTEL_INFO(dev)->gen >= 7) {
+			u32 temp = I915_READ(HSW_NDE_RSTWRN_OPT);
+			temp &= ~RESET_PCH_HANDSHAKE_ENABLE;
+			I915_WRITE(HSW_NDE_RSTWRN_OPT, temp);
+		}
+	}
+
+	i915_gem_init_swizzling(dev);
+
+	/*
+	 * At least 830 can leave some of the unused rings
+	 * "active" (ie. head != tail) after resume which
+	 * will prevent c3 entry. Makes sure all unused rings
+	 * are totally idle.
+	 */
+	init_unused_rings(dev);
+
+	BUG_ON(!dev_priv->kernel_context);
+
+	ret = i915_ppgtt_init_hw(dev);
+	if (ret) {
+		DRM_ERROR("PPGTT enable HW failed %d\n", ret);
+		goto out;
+	}
+
+	/* Need to do basic initialisation of all rings first: */
+	for_each_engine(engine, dev_priv) {
+		ret = engine->init_hw(engine);
+		if (ret)
+			goto out;
+	}
+
+	intel_mocs_init_l3cc_table(dev);
+
+	/* We can't enable contexts until all firmware is loaded */
+	if (HAS_GUC_UCODE(dev)) {
+		ret = intel_guc_ucode_load(dev);
+		if (ret) {
+			DRM_ERROR("Failed to initialize GuC, error %d\n", ret);
+			ret = -EIO;
+			goto out;
+		}
+	}
+
+	/*
+	 * Increment the next seqno by 0x100 so we have a visible break
+	 * on re-initialisation
+	 */
+	ret = i915_gem_set_seqno(dev, dev_priv->next_seqno+0x100);
+	if (ret)
+		goto out;
+
+	/* Now it is safe to go back round and do everything else: */
+	for_each_engine(engine, dev_priv) {
+		struct drm_i915_gem_request *req;
+
+		req = i915_gem_request_alloc(engine, NULL);
+		if (IS_ERR(req)) {
+			ret = PTR_ERR(req);
+			break;
+		}
+
+		if (engine->id == RCS) {
+			for (j = 0; j < NUM_L3_SLICES(dev); j++) {
+				ret = i915_gem_l3_remap(req, j);
+				if (ret)
+					goto err_request;
+			}
+		}
+
+		ret = i915_ppgtt_init_ring(req);
+		if (ret)
+			goto err_request;
+
+		ret = i915_gem_context_enable(req);
+		if (ret)
+			goto err_request;
+
+err_request:
+		i915_add_request_no_flush(req);
+		if (ret) {
+			DRM_ERROR("Failed to enable %s, error=%d\n",
+				  engine->name, ret);
+			i915_gem_cleanup_engines(dev);
+			break;
+		}
+	}
+
+out:
+	intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
+	return ret;
+}
+
+int i915_gem_init(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	int ret;
+
+	i915.enable_execlists = intel_sanitize_enable_execlists(dev,
+			i915.enable_execlists);
+
+	mutex_lock(&dev->struct_mutex);
+
+	if (!i915.enable_execlists) {
+		dev_priv->gt.execbuf_submit = i915_gem_ringbuffer_submission;
+		dev_priv->gt.init_engines = i915_gem_init_engines;
+		dev_priv->gt.cleanup_engine = intel_cleanup_engine;
+		dev_priv->gt.stop_engine = intel_stop_engine;
+	} else {
+		dev_priv->gt.execbuf_submit = intel_execlists_submission;
+		dev_priv->gt.init_engines = intel_logical_rings_init;
+		dev_priv->gt.cleanup_engine = intel_logical_ring_cleanup;
+		dev_priv->gt.stop_engine = intel_logical_ring_stop;
+	}
+
+	/* This is just a security blanket to placate dragons.
+	 * On some systems, we very sporadically observe that the first TLBs
+	 * used by the CS may be stale, despite us poking the TLB reset. If
+	 * we hold the forcewake during initialisation these problems
+	 * just magically go away.
+	 */
+	intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL);
+
+	ret = i915_gem_init_userptr(dev);
+	if (ret)
+		goto out_unlock;
+
+	i915_gem_init_ggtt(dev);
+
+	ret = i915_gem_context_init(dev);
+	if (ret)
+		goto out_unlock;
+
+	ret = dev_priv->gt.init_engines(dev);
+	if (ret)
+		goto out_unlock;
+
+	ret = i915_gem_init_hw(dev);
+	if (ret == -EIO) {
+		/* Allow ring initialisation to fail by marking the GPU as
+		 * wedged. But we only want to do this where the GPU is angry,
+		 * for all other failure, such as an allocation failure, bail.
+		 */
+		DRM_ERROR("Failed to initialize GPU, declaring it wedged\n");
+		atomic_or(I915_WEDGED, &dev_priv->gpu_error.reset_counter);
+		ret = 0;
+	}
+
+out_unlock:
+	intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
+	mutex_unlock(&dev->struct_mutex);
+
+	return ret;
+}
+
+void
+i915_gem_cleanup_engines(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_engine_cs *engine;
+
+	for_each_engine(engine, dev_priv)
+		dev_priv->gt.cleanup_engine(engine);
+
+	if (i915.enable_execlists)
+		/*
+		 * Neither the BIOS, ourselves or any other kernel
+		 * expects the system to be in execlists mode on startup,
+		 * so we need to reset the GPU back to legacy mode.
+		 */
+		intel_gpu_reset(dev, ALL_ENGINES);
+}
+
+static void
+init_engine_lists(struct intel_engine_cs *engine)
+{
+	INIT_LIST_HEAD(&engine->active_list);
+	INIT_LIST_HEAD(&engine->request_list);
+}
+
+void
+i915_gem_load_init_fences(struct drm_i915_private *dev_priv)
+{
+	struct drm_device *dev = dev_priv->dev;
+
+	if (INTEL_INFO(dev_priv)->gen >= 7 && !IS_VALLEYVIEW(dev_priv) &&
+	    !IS_CHERRYVIEW(dev_priv))
+		dev_priv->num_fence_regs = 32;
+	else if (INTEL_INFO(dev_priv)->gen >= 4 || IS_I945G(dev_priv) ||
+		 IS_I945GM(dev_priv) || IS_G33(dev_priv))
+		dev_priv->num_fence_regs = 16;
+	else
+		dev_priv->num_fence_regs = 8;
+
+	if (intel_vgpu_active(dev))
+		dev_priv->num_fence_regs =
+				I915_READ(vgtif_reg(avail_rs.fence_num));
+
+	/* Initialize fence registers to zero */
+	i915_gem_restore_fences(dev);
+
+	i915_gem_detect_bit_6_swizzle(dev);
+}
+
+void
+i915_gem_load_init(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	int i;
+
+	dev_priv->objects =
+		kmem_cache_create("i915_gem_object",
+				  sizeof(struct drm_i915_gem_object), 0,
+				  SLAB_HWCACHE_ALIGN,
+				  NULL);
+	dev_priv->vmas =
+		kmem_cache_create("i915_gem_vma",
+				  sizeof(struct i915_vma), 0,
+				  SLAB_HWCACHE_ALIGN,
+				  NULL);
+	dev_priv->requests =
+		kmem_cache_create("i915_gem_request",
+				  sizeof(struct drm_i915_gem_request), 0,
+				  SLAB_HWCACHE_ALIGN,
+				  NULL);
+
+	INIT_LIST_HEAD(&dev_priv->vm_list);
+	INIT_LIST_HEAD(&dev_priv->context_list);
+	INIT_LIST_HEAD(&dev_priv->mm.unbound_list);
+	INIT_LIST_HEAD(&dev_priv->mm.bound_list);
+	INIT_LIST_HEAD(&dev_priv->mm.fence_list);
+	for (i = 0; i < I915_NUM_ENGINES; i++)
+		init_engine_lists(&dev_priv->engine[i]);
+	for (i = 0; i < I915_MAX_NUM_FENCES; i++)
+		INIT_LIST_HEAD(&dev_priv->fence_regs[i].lru_list);
+	INIT_DELAYED_WORK(&dev_priv->mm.retire_work,
+			  i915_gem_retire_work_handler);
+	INIT_DELAYED_WORK(&dev_priv->mm.idle_work,
+			  i915_gem_idle_work_handler);
+	init_waitqueue_head(&dev_priv->gpu_error.reset_queue);
+
+	dev_priv->relative_constants_mode = I915_EXEC_CONSTANTS_REL_GENERAL;
+
+	/*
+	 * Set initial sequence number for requests.
+	 * Using this number allows the wraparound to happen early,
+	 * catching any obvious problems.
+	 */
+	dev_priv->next_seqno = ((u32)~0 - 0x1100);
+	dev_priv->last_seqno = ((u32)~0 - 0x1101);
+
+	INIT_LIST_HEAD(&dev_priv->mm.fence_list);
+
+	init_waitqueue_head(&dev_priv->pending_flip_queue);
+
+	dev_priv->mm.interruptible = true;
+
+	mutex_init(&dev_priv->fb_tracking.lock);
+}
+
+void i915_gem_load_cleanup(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = to_i915(dev);
+
+	kmem_cache_destroy(dev_priv->requests);
+	kmem_cache_destroy(dev_priv->vmas);
+	kmem_cache_destroy(dev_priv->objects);
+}
+
+void i915_gem_release(struct drm_device *dev, struct drm_file *file)
+{
+	struct drm_i915_file_private *file_priv = file->driver_priv;
+
+	/* Clean up our request list when the client is going away, so that
+	 * later retire_requests won't dereference our soon-to-be-gone
+	 * file_priv.
+	 */
+	spin_lock(&file_priv->mm.lock);
+	while (!list_empty(&file_priv->mm.request_list)) {
+		struct drm_i915_gem_request *request;
+
+		request = list_first_entry(&file_priv->mm.request_list,
+					   struct drm_i915_gem_request,
+					   client_list);
+		list_del(&request->client_list);
+		request->file_priv = NULL;
+	}
+	spin_unlock(&file_priv->mm.lock);
+
+	if (!list_empty(&file_priv->rps.link)) {
+		spin_lock(&to_i915(dev)->rps.client_lock);
+		list_del(&file_priv->rps.link);
+		spin_unlock(&to_i915(dev)->rps.client_lock);
+	}
+}
+
+int i915_gem_open(struct drm_device *dev, struct drm_file *file)
+{
+	struct drm_i915_file_private *file_priv;
+	int ret;
+
+	DRM_DEBUG_DRIVER("\n");
+
+	file_priv = kzalloc(sizeof(*file_priv), GFP_KERNEL);
+	if (!file_priv)
+		return -ENOMEM;
+
+	file->driver_priv = file_priv;
+	file_priv->dev_priv = dev->dev_private;
+	file_priv->file = file;
+	INIT_LIST_HEAD(&file_priv->rps.link);
+
+	spin_lock_init(&file_priv->mm.lock);
+	INIT_LIST_HEAD(&file_priv->mm.request_list);
+
+	file_priv->bsd_ring = -1;
+
+	ret = i915_gem_context_open(dev, file);
+	if (ret)
+		kfree(file_priv);
+
+	return ret;
+}
+
+/**
+ * i915_gem_track_fb - update frontbuffer tracking
+ * @old: current GEM buffer for the frontbuffer slots
+ * @new: new GEM buffer for the frontbuffer slots
+ * @frontbuffer_bits: bitmask of frontbuffer slots
+ *
+ * This updates the frontbuffer tracking bits @frontbuffer_bits by clearing them
+ * from @old and setting them in @new. Both @old and @new can be NULL.
+ */
+void i915_gem_track_fb(struct drm_i915_gem_object *old,
+		       struct drm_i915_gem_object *new,
+		       unsigned frontbuffer_bits)
+{
+	if (old) {
+		WARN_ON(!mutex_is_locked(&old->base.dev->struct_mutex));
+		WARN_ON(!(old->frontbuffer_bits & frontbuffer_bits));
+		old->frontbuffer_bits &= ~frontbuffer_bits;
+	}
+
+	if (new) {
+		WARN_ON(!mutex_is_locked(&new->base.dev->struct_mutex));
+		WARN_ON(new->frontbuffer_bits & frontbuffer_bits);
+		new->frontbuffer_bits |= frontbuffer_bits;
+	}
+}
+
+/* All the new VM stuff */
+u64 i915_gem_obj_offset(struct drm_i915_gem_object *o,
+			struct i915_address_space *vm)
+{
+	struct drm_i915_private *dev_priv = o->base.dev->dev_private;
+	struct i915_vma *vma;
+
+	WARN_ON(vm == &dev_priv->mm.aliasing_ppgtt->base);
+
+	list_for_each_entry(vma, &o->vma_list, obj_link) {
+		if (vma->is_ggtt &&
+		    vma->ggtt_view.type != I915_GGTT_VIEW_NORMAL)
+			continue;
+		if (vma->vm == vm)
+			return vma->node.start;
+	}
+
+	WARN(1, "%s vma for this object not found.\n",
+	     i915_is_ggtt(vm) ? "global" : "ppgtt");
+	return -1;
+}
+
+u64 i915_gem_obj_ggtt_offset_view(struct drm_i915_gem_object *o,
+				  const struct i915_ggtt_view *view)
+{
+	struct drm_i915_private *dev_priv = to_i915(o->base.dev);
+	struct i915_ggtt *ggtt = &dev_priv->ggtt;
+	struct i915_vma *vma;
+
+	list_for_each_entry(vma, &o->vma_list, obj_link)
+		if (vma->vm == &ggtt->base &&
+		    i915_ggtt_view_equal(&vma->ggtt_view, view))
+			return vma->node.start;
+
+	WARN(1, "global vma for this object not found. (view=%u)\n", view->type);
+	return -1;
+}
+
+bool i915_gem_obj_bound(struct drm_i915_gem_object *o,
+			struct i915_address_space *vm)
+{
+	struct i915_vma *vma;
+
+	list_for_each_entry(vma, &o->vma_list, obj_link) {
+		if (vma->is_ggtt &&
+		    vma->ggtt_view.type != I915_GGTT_VIEW_NORMAL)
+			continue;
+		if (vma->vm == vm && drm_mm_node_allocated(&vma->node))
+			return true;
+	}
+
+	return false;
+}
+
+bool i915_gem_obj_ggtt_bound_view(struct drm_i915_gem_object *o,
+				  const struct i915_ggtt_view *view)
+{
+	struct drm_i915_private *dev_priv = to_i915(o->base.dev);
+	struct i915_ggtt *ggtt = &dev_priv->ggtt;
+	struct i915_vma *vma;
+
+	list_for_each_entry(vma, &o->vma_list, obj_link)
+		if (vma->vm == &ggtt->base &&
+		    i915_ggtt_view_equal(&vma->ggtt_view, view) &&
+		    drm_mm_node_allocated(&vma->node))
+			return true;
+
+	return false;
+}
+
+bool i915_gem_obj_bound_any(struct drm_i915_gem_object *o)
+{
+	struct i915_vma *vma;
+
+	list_for_each_entry(vma, &o->vma_list, obj_link)
+		if (drm_mm_node_allocated(&vma->node))
+			return true;
+
+	return false;
+}
+
+unsigned long i915_gem_obj_size(struct drm_i915_gem_object *o,
+				struct i915_address_space *vm)
+{
+	struct drm_i915_private *dev_priv = o->base.dev->dev_private;
+	struct i915_vma *vma;
+
+	WARN_ON(vm == &dev_priv->mm.aliasing_ppgtt->base);
+
+	BUG_ON(list_empty(&o->vma_list));
+
+	list_for_each_entry(vma, &o->vma_list, obj_link) {
+		if (vma->is_ggtt &&
+		    vma->ggtt_view.type != I915_GGTT_VIEW_NORMAL)
+			continue;
+		if (vma->vm == vm)
+			return vma->node.size;
+	}
+	return 0;
+}
+
+bool i915_gem_obj_is_pinned(struct drm_i915_gem_object *obj)
+{
+	struct i915_vma *vma;
+	list_for_each_entry(vma, &obj->vma_list, obj_link)
+		if (vma->pin_count > 0)
+			return true;
+
+	return false;
+}
+
+/* Like i915_gem_object_get_page(), but mark the returned page dirty */
+struct page *
+i915_gem_object_get_dirty_page(struct drm_i915_gem_object *obj, int n)
+{
+	struct page *page;
+
+	/* Only default objects have per-page dirty tracking */
+	if (WARN_ON((obj->ops->flags & I915_GEM_OBJECT_HAS_STRUCT_PAGE) == 0))
+		return NULL;
+
+	page = i915_gem_object_get_page(obj, n);
+	set_page_dirty(page);
+	return page;
+}
+
+/* Allocate a new GEM object and fill it with the supplied data */
+struct drm_i915_gem_object *
+i915_gem_object_create_from_data(struct drm_device *dev,
+			         const void *data, size_t size)
+{
+	struct drm_i915_gem_object *obj;
+	struct sg_table *sg;
+	size_t bytes;
+	int ret;
+
+	obj = i915_gem_alloc_object(dev, round_up(size, PAGE_SIZE));
+	if (IS_ERR_OR_NULL(obj))
+		return obj;
+
+	ret = i915_gem_object_set_to_cpu_domain(obj, true);
+	if (ret)
+		goto fail;
+
+	ret = i915_gem_object_get_pages(obj);
+	if (ret)
+		goto fail;
+
+	i915_gem_object_pin_pages(obj);
+	sg = obj->pages;
+	bytes = sg_copy_from_buffer(sg->sgl, sg->nents, (void *)data, size);
+	obj->dirty = 1;		/* Backing store is now out of date */
+	i915_gem_object_unpin_pages(obj);
+
+	if (WARN_ON(bytes != size)) {
+		DRM_ERROR("Incomplete copy, wrote %zu of %zu", bytes, size);
+		ret = -EFAULT;
+		goto fail;
+	}
+
+	return obj;
+
+fail:
+	drm_gem_object_unreference(&obj->base);
+	return ERR_PTR(ret);
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/i915/i915_gem.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright © 2016 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ */
+
+#ifndef __I915_GEM_H__
+#define __I915_GEM_H__
+
+#ifdef CONFIG_DRM_I915_DEBUG_GEM
+#define GEM_BUG_ON(expr) BUG_ON(expr)
+#else
+#define GEM_BUG_ON(expr)
+#endif
+
+#endif /* __I915_GEM_H__ */
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/i915/i915_gem_batch_pool.c
@@ -0,0 +1,151 @@
+/*
+ * Copyright © 2014 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ */
+
+#include "i915_drv.h"
+#include "i915_gem_batch_pool.h"
+
+/**
+ * DOC: batch pool
+ *
+ * In order to submit batch buffers as 'secure', the software command parser
+ * must ensure that a batch buffer cannot be modified after parsing. It does
+ * this by copying the user provided batch buffer contents to a kernel owned
+ * buffer from which the hardware will actually execute, and by carefully
+ * managing the address space bindings for such buffers.
+ *
+ * The batch pool framework provides a mechanism for the driver to manage a
+ * set of scratch buffers to use for this purpose. The framework can be
+ * extended to support other uses cases should they arise.
+ */
+
+/**
+ * i915_gem_batch_pool_init() - initialize a batch buffer pool
+ * @dev: the drm device
+ * @pool: the batch buffer pool
+ */
+void i915_gem_batch_pool_init(struct drm_device *dev,
+			      struct i915_gem_batch_pool *pool)
+{
+	int n;
+
+	pool->dev = dev;
+
+	for (n = 0; n < ARRAY_SIZE(pool->cache_list); n++)
+		INIT_LIST_HEAD(&pool->cache_list[n]);
+}
+
+/**
+ * i915_gem_batch_pool_fini() - clean up a batch buffer pool
+ * @pool: the pool to clean up
+ *
+ * Note: Callers must hold the struct_mutex.
+ */
+void i915_gem_batch_pool_fini(struct i915_gem_batch_pool *pool)
+{
+	int n;
+
+	WARN_ON(!mutex_is_locked(&pool->dev->struct_mutex));
+
+	for (n = 0; n < ARRAY_SIZE(pool->cache_list); n++) {
+		while (!list_empty(&pool->cache_list[n])) {
+			struct drm_i915_gem_object *obj =
+				list_first_entry(&pool->cache_list[n],
+						 struct drm_i915_gem_object,
+						 batch_pool_link);
+
+			list_del(&obj->batch_pool_link);
+			drm_gem_object_unreference(&obj->base);
+		}
+	}
+}
+
+/**
+ * i915_gem_batch_pool_get() - allocate a buffer from the pool
+ * @pool: the batch buffer pool
+ * @size: the minimum desired size of the returned buffer
+ *
+ * Returns an inactive buffer from @pool with at least @size bytes,
+ * with the pages pinned. The caller must i915_gem_object_unpin_pages()
+ * on the returned object.
+ *
+ * Note: Callers must hold the struct_mutex
+ *
+ * Return: the buffer object or an error pointer
+ */
+struct drm_i915_gem_object *
+i915_gem_batch_pool_get(struct i915_gem_batch_pool *pool,
+			size_t size)
+{
+	struct drm_i915_gem_object *obj = NULL;
+	struct drm_i915_gem_object *tmp, *next;
+	struct list_head *list;
+	int n;
+
+	WARN_ON(!mutex_is_locked(&pool->dev->struct_mutex));
+
+	/* Compute a power-of-two bucket, but throw everything greater than
+	 * 16KiB into the same bucket: i.e. the the buckets hold objects of
+	 * (1 page, 2 pages, 4 pages, 8+ pages).
+	 */
+	n = fls(size >> PAGE_SHIFT) - 1;
+	if (n >= ARRAY_SIZE(pool->cache_list))
+		n = ARRAY_SIZE(pool->cache_list) - 1;
+	list = &pool->cache_list[n];
+
+	list_for_each_entry_safe(tmp, next, list, batch_pool_link) {
+		/* The batches are strictly LRU ordered */
+		if (tmp->active)
+			break;
+
+		/* While we're looping, do some clean up */
+		if (tmp->madv == __I915_MADV_PURGED) {
+			list_del(&tmp->batch_pool_link);
+			drm_gem_object_unreference(&tmp->base);
+			continue;
+		}
+
+		if (tmp->base.size >= size) {
+			obj = tmp;
+			break;
+		}
+	}
+
+	if (obj == NULL) {
+		int ret;
+
+		obj = i915_gem_alloc_object(pool->dev, size);
+		if (obj == NULL)
+			return ERR_PTR(-ENOMEM);
+
+		ret = i915_gem_object_get_pages(obj);
+		if (ret)
+			return ERR_PTR(ret);
+
+		obj->madv = I915_MADV_DONTNEED;
+	}
+
+	list_move_tail(&obj->batch_pool_link, list);
+	i915_gem_object_pin_pages(obj);
+	return obj;
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/i915/i915_gem_batch_pool.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright © 2014 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ */
+
+#ifndef I915_GEM_BATCH_POOL_H
+#define I915_GEM_BATCH_POOL_H
+
+#include "i915_drv.h"
+
+struct i915_gem_batch_pool {
+	struct drm_device *dev;
+	struct list_head cache_list[4];
+};
+
+/* i915_gem_batch_pool.c */
+void i915_gem_batch_pool_init(struct drm_device *dev,
+			      struct i915_gem_batch_pool *pool);
+void i915_gem_batch_pool_fini(struct i915_gem_batch_pool *pool);
+struct drm_i915_gem_object*
+i915_gem_batch_pool_get(struct i915_gem_batch_pool *pool, size_t size);
+
+#endif /* I915_GEM_BATCH_POOL_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/i915/i915_gem_context.c
@@ -0,0 +1,1006 @@
+/*
+ * Copyright © 2011-2012 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Ben Widawsky <ben@bwidawsk.net>
+ *
+ */
+
+/*
+ * This file implements HW context support. On gen5+ a HW context consists of an
+ * opaque GPU object which is referenced at times of context saves and restores.
+ * With RC6 enabled, the context is also referenced as the GPU enters and exists
+ * from RC6 (GPU has it's own internal power context, except on gen5). Though
+ * something like a context does exist for the media ring, the code only
+ * supports contexts for the render ring.
+ *
+ * In software, there is a distinction between contexts created by the user,
+ * and the default HW context. The default HW context is used by GPU clients
+ * that do not request setup of their own hardware context. The default
+ * context's state is never restored to help prevent programming errors. This
+ * would happen if a client ran and piggy-backed off another clients GPU state.
+ * The default context only exists to give the GPU some offset to load as the
+ * current to invoke a save of the context we actually care about. In fact, the
+ * code could likely be constructed, albeit in a more complicated fashion, to
+ * never use the default context, though that limits the driver's ability to
+ * swap out, and/or destroy other contexts.
+ *
+ * All other contexts are created as a request by the GPU client. These contexts
+ * store GPU state, and thus allow GPU clients to not re-emit state (and
+ * potentially query certain state) at any time. The kernel driver makes
+ * certain that the appropriate commands are inserted.
+ *
+ * The context life cycle is semi-complicated in that context BOs may live
+ * longer than the context itself because of the way the hardware, and object
+ * tracking works. Below is a very crude representation of the state machine
+ * describing the context life.
+ *                                         refcount     pincount     active
+ * S0: initial state                          0            0           0
+ * S1: context created                        1            0           0
+ * S2: context is currently running           2            1           X
+ * S3: GPU referenced, but not current        2            0           1
+ * S4: context is current, but destroyed      1            1           0
+ * S5: like S3, but destroyed                 1            0           1
+ *
+ * The most common (but not all) transitions:
+ * S0->S1: client creates a context
+ * S1->S2: client submits execbuf with context
+ * S2->S3: other clients submits execbuf with context
+ * S3->S1: context object was retired
+ * S3->S2: clients submits another execbuf
+ * S2->S4: context destroy called with current context
+ * S3->S5->S0: destroy path
+ * S4->S5->S0: destroy path on current context
+ *
+ * There are two confusing terms used above:
+ *  The "current context" means the context which is currently running on the
+ *  GPU. The GPU has loaded its state already and has stored away the gtt
+ *  offset of the BO. The GPU is not actively referencing the data at this
+ *  offset, but it will on the next context switch. The only way to avoid this
+ *  is to do a GPU reset.
+ *
+ *  An "active context' is one which was previously the "current context" and is
+ *  on the active list waiting for the next context switch to occur. Until this
+ *  happens, the object must remain at the same gtt offset. It is therefore
+ *  possible to destroy a context, but it is still active.
+ *
+ */
+
+#include <drm/drmP.h>
+#include <drm/i915_drm.h>
+#include "i915_drv.h"
+#include "i915_trace.h"
+
+/* This is a HW constraint. The value below is the largest known requirement
+ * I've seen in a spec to date, and that was a workaround for a non-shipping
+ * part. It should be safe to decrease this, but it's more future proof as is.
+ */
+#define GEN6_CONTEXT_ALIGN (64<<10)
+#define GEN7_CONTEXT_ALIGN 4096
+
+static size_t get_context_alignment(struct drm_device *dev)
+{
+	if (IS_GEN6(dev))
+		return GEN6_CONTEXT_ALIGN;
+
+	return GEN7_CONTEXT_ALIGN;
+}
+
+static int get_context_size(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	int ret;
+	u32 reg;
+
+	switch (INTEL_INFO(dev)->gen) {
+	case 6:
+		reg = I915_READ(CXT_SIZE);
+		ret = GEN6_CXT_TOTAL_SIZE(reg) * 64;
+		break;
+	case 7:
+		reg = I915_READ(GEN7_CXT_SIZE);
+		if (IS_HASWELL(dev))
+			ret = HSW_CXT_TOTAL_SIZE;
+		else
+			ret = GEN7_CXT_TOTAL_SIZE(reg) * 64;
+		break;
+	case 8:
+		ret = GEN8_CXT_TOTAL_SIZE;
+		break;
+	default:
+		BUG();
+	}
+
+	return ret;
+}
+
+static void i915_gem_context_clean(struct intel_context *ctx)
+{
+	struct i915_hw_ppgtt *ppgtt = ctx->ppgtt;
+	struct i915_vma *vma, *next;
+
+	if (!ppgtt)
+		return;
+
+	list_for_each_entry_safe(vma, next, &ppgtt->base.inactive_list,
+				 vm_link) {
+		if (WARN_ON(__i915_vma_unbind_no_wait(vma)))
+			break;
+	}
+}
+
+void i915_gem_context_free(struct kref *ctx_ref)
+{
+	struct intel_context *ctx = container_of(ctx_ref, typeof(*ctx), ref);
+
+	trace_i915_context_free(ctx);
+
+	if (i915.enable_execlists)
+		intel_lr_context_free(ctx);
+
+	/*
+	 * This context is going away and we need to remove all VMAs still
+	 * around. This is to handle imported shared objects for which
+	 * destructor did not run when their handles were closed.
+	 */
+	i915_gem_context_clean(ctx);
+
+	i915_ppgtt_put(ctx->ppgtt);
+
+	if (ctx->legacy_hw_ctx.rcs_state)
+		drm_gem_object_unreference(&ctx->legacy_hw_ctx.rcs_state->base);
+	list_del(&ctx->link);
+	kfree(ctx);
+}
+
+struct drm_i915_gem_object *
+i915_gem_alloc_context_obj(struct drm_device *dev, size_t size)
+{
+	struct drm_i915_gem_object *obj;
+	int ret;
+
+	obj = i915_gem_alloc_object(dev, size);
+	if (obj == NULL)
+		return ERR_PTR(-ENOMEM);
+
+	/*
+	 * Try to make the context utilize L3 as well as LLC.
+	 *
+	 * On VLV we don't have L3 controls in the PTEs so we
+	 * shouldn't touch the cache level, especially as that
+	 * would make the object snooped which might have a
+	 * negative performance impact.
+	 *
+	 * Snooping is required on non-llc platforms in execlist
+	 * mode, but since all GGTT accesses use PAT entry 0 we
+	 * get snooping anyway regardless of cache_level.
+	 *
+	 * This is only applicable for Ivy Bridge devices since
+	 * later platforms don't have L3 control bits in the PTE.
+	 */
+	if (IS_IVYBRIDGE(dev)) {
+		ret = i915_gem_object_set_cache_level(obj, I915_CACHE_L3_LLC);
+		/* Failure shouldn't ever happen this early */
+		if (WARN_ON(ret)) {
+			drm_gem_object_unreference(&obj->base);
+			return ERR_PTR(ret);
+		}
+	}
+
+	return obj;
+}
+
+static struct intel_context *
+__create_hw_context(struct drm_device *dev,
+		    struct drm_i915_file_private *file_priv)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_context *ctx;
+	int ret;
+
+	ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
+	if (ctx == NULL)
+		return ERR_PTR(-ENOMEM);
+
+	kref_init(&ctx->ref);
+	list_add_tail(&ctx->link, &dev_priv->context_list);
+	ctx->i915 = dev_priv;
+
+	if (dev_priv->hw_context_size) {
+		struct drm_i915_gem_object *obj =
+				i915_gem_alloc_context_obj(dev, dev_priv->hw_context_size);
+		if (IS_ERR(obj)) {
+			ret = PTR_ERR(obj);
+			goto err_out;
+		}
+		ctx->legacy_hw_ctx.rcs_state = obj;
+	}
+
+	/* Default context will never have a file_priv */
+	if (file_priv != NULL) {
+		ret = idr_alloc(&file_priv->context_idr, ctx,
+				DEFAULT_CONTEXT_HANDLE, 0, GFP_KERNEL);
+		if (ret < 0)
+			goto err_out;
+	} else
+		ret = DEFAULT_CONTEXT_HANDLE;
+
+	ctx->file_priv = file_priv;
+	ctx->user_handle = ret;
+	/* NB: Mark all slices as needing a remap so that when the context first
+	 * loads it will restore whatever remap state already exists. If there
+	 * is no remap info, it will be a NOP. */
+	ctx->remap_slice = (1 << NUM_L3_SLICES(dev)) - 1;
+
+	ctx->hang_stats.ban_period_seconds = DRM_I915_CTX_BAN_PERIOD;
+
+	return ctx;
+
+err_out:
+	i915_gem_context_unreference(ctx);
+	return ERR_PTR(ret);
+}
+
+/**
+ * The default context needs to exist per ring that uses contexts. It stores the
+ * context state of the GPU for applications that don't utilize HW contexts, as
+ * well as an idle case.
+ */
+static struct intel_context *
+i915_gem_create_context(struct drm_device *dev,
+			struct drm_i915_file_private *file_priv)
+{
+	const bool is_global_default_ctx = file_priv == NULL;
+	struct intel_context *ctx;
+	int ret = 0;
+
+	BUG_ON(!mutex_is_locked(&dev->struct_mutex));
+
+	ctx = __create_hw_context(dev, file_priv);
+	if (IS_ERR(ctx))
+		return ctx;
+
+	if (is_global_default_ctx && ctx->legacy_hw_ctx.rcs_state) {
+		/* We may need to do things with the shrinker which
+		 * require us to immediately switch back to the default
+		 * context. This can cause a problem as pinning the
+		 * default context also requires GTT space which may not
+		 * be available. To avoid this we always pin the default
+		 * context.
+		 */
+		ret = i915_gem_obj_ggtt_pin(ctx->legacy_hw_ctx.rcs_state,
+					    get_context_alignment(dev), 0);
+		if (ret) {
+			DRM_DEBUG_DRIVER("Couldn't pin %d\n", ret);
+			goto err_destroy;
+		}
+	}
+
+	if (USES_FULL_PPGTT(dev)) {
+		struct i915_hw_ppgtt *ppgtt = i915_ppgtt_create(dev, file_priv);
+
+		if (IS_ERR_OR_NULL(ppgtt)) {
+			DRM_DEBUG_DRIVER("PPGTT setup failed (%ld)\n",
+					 PTR_ERR(ppgtt));
+			ret = PTR_ERR(ppgtt);
+			goto err_unpin;
+		}
+
+		ctx->ppgtt = ppgtt;
+	}
+
+	trace_i915_context_create(ctx);
+
+	return ctx;
+
+err_unpin:
+	if (is_global_default_ctx && ctx->legacy_hw_ctx.rcs_state)
+		i915_gem_object_ggtt_unpin(ctx->legacy_hw_ctx.rcs_state);
+err_destroy:
+	idr_remove(&file_priv->context_idr, ctx->user_handle);
+	i915_gem_context_unreference(ctx);
+	return ERR_PTR(ret);
+}
+
+static void i915_gem_context_unpin(struct intel_context *ctx,
+				   struct intel_engine_cs *engine)
+{
+	if (i915.enable_execlists) {
+		intel_lr_context_unpin(ctx, engine);
+	} else {
+		if (engine->id == RCS && ctx->legacy_hw_ctx.rcs_state)
+			i915_gem_object_ggtt_unpin(ctx->legacy_hw_ctx.rcs_state);
+		i915_gem_context_unreference(ctx);
+	}
+}
+
+void i915_gem_context_reset(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	int i;
+
+	if (i915.enable_execlists) {
+		struct intel_context *ctx;
+
+		list_for_each_entry(ctx, &dev_priv->context_list, link)
+			intel_lr_context_reset(dev_priv, ctx);
+	}
+
+	for (i = 0; i < I915_NUM_ENGINES; i++) {
+		struct intel_engine_cs *engine = &dev_priv->engine[i];
+
+		if (engine->last_context) {
+			i915_gem_context_unpin(engine->last_context, engine);
+			engine->last_context = NULL;
+		}
+	}
+
+	/* Force the GPU state to be reinitialised on enabling */
+	dev_priv->kernel_context->legacy_hw_ctx.initialized = false;
+}
+
+int i915_gem_context_init(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_context *ctx;
+
+	/* Init should only be called once per module load. Eventually the
+	 * restriction on the context_disabled check can be loosened. */
+	if (WARN_ON(dev_priv->kernel_context))
+		return 0;
+
+	if (intel_vgpu_active(dev) && HAS_LOGICAL_RING_CONTEXTS(dev)) {
+		if (!i915.enable_execlists) {
+			DRM_INFO("Only EXECLIST mode is supported in vgpu.\n");
+			return -EINVAL;
+		}
+	}
+
+	if (i915.enable_execlists) {
+		/* NB: intentionally left blank. We will allocate our own
+		 * backing objects as we need them, thank you very much */
+		dev_priv->hw_context_size = 0;
+	} else if (HAS_HW_CONTEXTS(dev)) {
+		dev_priv->hw_context_size = round_up(get_context_size(dev), 4096);
+		if (dev_priv->hw_context_size > (1<<20)) {
+			DRM_DEBUG_DRIVER("Disabling HW Contexts; invalid size %d\n",
+					 dev_priv->hw_context_size);
+			dev_priv->hw_context_size = 0;
+		}
+	}
+
+	ctx = i915_gem_create_context(dev, NULL);
+	if (IS_ERR(ctx)) {
+		DRM_ERROR("Failed to create default global context (error %ld)\n",
+			  PTR_ERR(ctx));
+		return PTR_ERR(ctx);
+	}
+
+	dev_priv->kernel_context = ctx;
+
+	DRM_DEBUG_DRIVER("%s context support initialized\n",
+			i915.enable_execlists ? "LR" :
+			dev_priv->hw_context_size ? "HW" : "fake");
+	return 0;
+}
+
+void i915_gem_context_fini(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_context *dctx = dev_priv->kernel_context;
+	int i;
+
+	if (dctx->legacy_hw_ctx.rcs_state) {
+		/* The only known way to stop the gpu from accessing the hw context is
+		 * to reset it. Do this as the very last operation to avoid confusing
+		 * other code, leading to spurious errors. */
+		intel_gpu_reset(dev, ALL_ENGINES);
+
+		/* When default context is created and switched to, base object refcount
+		 * will be 2 (+1 from object creation and +1 from do_switch()).
+		 * i915_gem_context_fini() will be called after gpu_idle() has switched
+		 * to default context. So we need to unreference the base object once
+		 * to offset the do_switch part, so that i915_gem_context_unreference()
+		 * can then free the base object correctly. */
+		WARN_ON(!dev_priv->engine[RCS].last_context);
+
+		i915_gem_object_ggtt_unpin(dctx->legacy_hw_ctx.rcs_state);
+	}
+
+	for (i = I915_NUM_ENGINES; --i >= 0;) {
+		struct intel_engine_cs *engine = &dev_priv->engine[i];
+
+		if (engine->last_context) {
+			i915_gem_context_unpin(engine->last_context, engine);
+			engine->last_context = NULL;
+		}
+	}
+
+	i915_gem_context_unreference(dctx);
+	dev_priv->kernel_context = NULL;
+}
+
+int i915_gem_context_enable(struct drm_i915_gem_request *req)
+{
+	struct intel_engine_cs *engine = req->engine;
+	int ret;
+
+	if (i915.enable_execlists) {
+		if (engine->init_context == NULL)
+			return 0;
+
+		ret = engine->init_context(req);
+	} else
+		ret = i915_switch_context(req);
+
+	if (ret) {
+		DRM_ERROR("ring init context: %d\n", ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+static int context_idr_cleanup(int id, void *p, void *data)
+{
+	struct intel_context *ctx = p;
+
+	i915_gem_context_unreference(ctx);
+	return 0;
+}
+
+int i915_gem_context_open(struct drm_device *dev, struct drm_file *file)
+{
+	struct drm_i915_file_private *file_priv = file->driver_priv;
+	struct intel_context *ctx;
+
+	idr_init(&file_priv->context_idr);
+
+	mutex_lock(&dev->struct_mutex);
+	ctx = i915_gem_create_context(dev, file_priv);
+	mutex_unlock(&dev->struct_mutex);
+
+	if (IS_ERR(ctx)) {
+		idr_destroy(&file_priv->context_idr);
+		return PTR_ERR(ctx);
+	}
+
+	return 0;
+}
+
+void i915_gem_context_close(struct drm_device *dev, struct drm_file *file)
+{
+	struct drm_i915_file_private *file_priv = file->driver_priv;
+
+	idr_for_each(&file_priv->context_idr, context_idr_cleanup, NULL);
+	idr_destroy(&file_priv->context_idr);
+}
+
+struct intel_context *
+i915_gem_context_get(struct drm_i915_file_private *file_priv, u32 id)
+{
+	struct intel_context *ctx;
+
+	ctx = (struct intel_context *)idr_find(&file_priv->context_idr, id);
+	if (!ctx)
+		return ERR_PTR(-ENOENT);
+
+	return ctx;
+}
+
+static inline int
+mi_set_context(struct drm_i915_gem_request *req, u32 hw_flags)
+{
+	struct intel_engine_cs *engine = req->engine;
+	u32 flags = hw_flags | MI_MM_SPACE_GTT;
+	const int num_rings =
+		/* Use an extended w/a on ivb+ if signalling from other rings */
+		i915_semaphore_is_enabled(engine->dev) ?
+		hweight32(INTEL_INFO(engine->dev)->ring_mask) - 1 :
+		0;
+	int len, ret;
+
+	/* w/a: If Flush TLB Invalidation Mode is enabled, driver must do a TLB
+	 * invalidation prior to MI_SET_CONTEXT. On GEN6 we don't set the value
+	 * explicitly, so we rely on the value at ring init, stored in
+	 * itlb_before_ctx_switch.
+	 */
+	if (IS_GEN6(engine->dev)) {
+		ret = engine->flush(req, I915_GEM_GPU_DOMAINS, 0);
+		if (ret)
+			return ret;
+	}
+
+	/* These flags are for resource streamer on HSW+ */
+	if (IS_HASWELL(engine->dev) || INTEL_INFO(engine->dev)->gen >= 8)
+		flags |= (HSW_MI_RS_SAVE_STATE_EN | HSW_MI_RS_RESTORE_STATE_EN);
+	else if (INTEL_INFO(engine->dev)->gen < 8)
+		flags |= (MI_SAVE_EXT_STATE_EN | MI_RESTORE_EXT_STATE_EN);
+
+
+	len = 4;
+	if (INTEL_INFO(engine->dev)->gen >= 7)
+		len += 2 + (num_rings ? 4*num_rings + 6 : 0);
+
+	ret = intel_ring_begin(req, len);
+	if (ret)
+		return ret;
+
+	/* WaProgramMiArbOnOffAroundMiSetContext:ivb,vlv,hsw,bdw,chv */
+	if (INTEL_INFO(engine->dev)->gen >= 7) {
+		intel_ring_emit(engine, MI_ARB_ON_OFF | MI_ARB_DISABLE);
+		if (num_rings) {
+			struct intel_engine_cs *signaller;
+
+			intel_ring_emit(engine,
+					MI_LOAD_REGISTER_IMM(num_rings));
+			for_each_engine(signaller, to_i915(engine->dev)) {
+				if (signaller == engine)
+					continue;
+
+				intel_ring_emit_reg(engine,
+						    RING_PSMI_CTL(signaller->mmio_base));
+				intel_ring_emit(engine,
+						_MASKED_BIT_ENABLE(GEN6_PSMI_SLEEP_MSG_DISABLE));
+			}
+		}
+	}
+
+	intel_ring_emit(engine, MI_NOOP);
+	intel_ring_emit(engine, MI_SET_CONTEXT);
+	intel_ring_emit(engine,
+			i915_gem_obj_ggtt_offset(req->ctx->legacy_hw_ctx.rcs_state) |
+			flags);
+	/*
+	 * w/a: MI_SET_CONTEXT must always be followed by MI_NOOP
+	 * WaMiSetContext_Hang:snb,ivb,vlv
+	 */
+	intel_ring_emit(engine, MI_NOOP);
+
+	if (INTEL_INFO(engine->dev)->gen >= 7) {
+		if (num_rings) {
+			struct intel_engine_cs *signaller;
+			i915_reg_t last_reg = {}; /* keep gcc quiet */
+
+			intel_ring_emit(engine,
+					MI_LOAD_REGISTER_IMM(num_rings));
+			for_each_engine(signaller, to_i915(engine->dev)) {
+				if (signaller == engine)
+					continue;
+
+				last_reg = RING_PSMI_CTL(signaller->mmio_base);
+				intel_ring_emit_reg(engine, last_reg);
+				intel_ring_emit(engine,
+						_MASKED_BIT_DISABLE(GEN6_PSMI_SLEEP_MSG_DISABLE));
+			}
+
+			/* Insert a delay before the next switch! */
+			intel_ring_emit(engine,
+					MI_STORE_REGISTER_MEM |
+					MI_SRM_LRM_GLOBAL_GTT);
+			intel_ring_emit_reg(engine, last_reg);
+			intel_ring_emit(engine, engine->scratch.gtt_offset);
+			intel_ring_emit(engine, MI_NOOP);
+		}
+		intel_ring_emit(engine, MI_ARB_ON_OFF | MI_ARB_ENABLE);
+	}
+
+	intel_ring_advance(engine);
+
+	return ret;
+}
+
+static inline bool skip_rcs_switch(struct intel_engine_cs *engine,
+				   struct intel_context *to)
+{
+	if (to->remap_slice)
+		return false;
+
+	if (!to->legacy_hw_ctx.initialized)
+		return false;
+
+	if (to->ppgtt &&
+	    !(intel_engine_flag(engine) & to->ppgtt->pd_dirty_rings))
+		return false;
+
+	return to == engine->last_context;
+}
+
+static bool
+needs_pd_load_pre(struct intel_engine_cs *engine, struct intel_context *to)
+{
+	if (!to->ppgtt)
+		return false;
+
+	if (engine->last_context == to &&
+	    !(intel_engine_flag(engine) & to->ppgtt->pd_dirty_rings))
+		return false;
+
+	if (engine->id != RCS)
+		return true;
+
+	if (INTEL_INFO(engine->dev)->gen < 8)
+		return true;
+
+	return false;
+}
+
+static bool
+needs_pd_load_post(struct intel_context *to, u32 hw_flags)
+{
+	if (!to->ppgtt)
+		return false;
+
+	if (!IS_GEN8(to->i915))
+		return false;
+
+	if (hw_flags & MI_RESTORE_INHIBIT)
+		return true;
+
+	return false;
+}
+
+static int do_rcs_switch(struct drm_i915_gem_request *req)
+{
+	struct intel_context *to = req->ctx;
+	struct intel_engine_cs *engine = req->engine;
+	struct intel_context *from;
+	u32 hw_flags;
+	int ret, i;
+
+	if (skip_rcs_switch(engine, to))
+		return 0;
+
+	/* Trying to pin first makes error handling easier. */
+	ret = i915_gem_obj_ggtt_pin(to->legacy_hw_ctx.rcs_state,
+				    get_context_alignment(engine->dev),
+				    0);
+	if (ret)
+		return ret;
+
+	/*
+	 * Pin can switch back to the default context if we end up calling into
+	 * evict_everything - as a last ditch gtt defrag effort that also
+	 * switches to the default context. Hence we need to reload from here.
+	 *
+	 * XXX: Doing so is painfully broken!
+	 */
+	from = engine->last_context;
+
+	/*
+	 * Clear this page out of any CPU caches for coherent swap-in/out. Note
+	 * that thanks to write = false in this call and us not setting any gpu
+	 * write domains when putting a context object onto the active list
+	 * (when switching away from it), this won't block.
+	 *
+	 * XXX: We need a real interface to do this instead of trickery.
+	 */
+	ret = i915_gem_object_set_to_gtt_domain(to->legacy_hw_ctx.rcs_state, false);
+	if (ret)
+		goto unpin_out;
+
+	if (needs_pd_load_pre(engine, to)) {
+		/* Older GENs and non render rings still want the load first,
+		 * "PP_DCLV followed by PP_DIR_BASE register through Load
+		 * Register Immediate commands in Ring Buffer before submitting
+		 * a context."*/
+		trace_switch_mm(engine, to);
+		ret = to->ppgtt->switch_mm(to->ppgtt, req);
+		if (ret)
+			goto unpin_out;
+	}
+
+	if (!to->legacy_hw_ctx.initialized || i915_gem_context_is_default(to))
+		/* NB: If we inhibit the restore, the context is not allowed to
+		 * die because future work may end up depending on valid address
+		 * space. This means we must enforce that a page table load
+		 * occur when this occurs. */
+		hw_flags = MI_RESTORE_INHIBIT;
+	else if (to->ppgtt &&
+		 intel_engine_flag(engine) & to->ppgtt->pd_dirty_rings)
+		hw_flags = MI_FORCE_RESTORE;
+	else
+		hw_flags = 0;
+
+	/* We should never emit switch_mm more than once */
+	WARN_ON(needs_pd_load_pre(engine, to) &&
+		needs_pd_load_post(to, hw_flags));
+
+	if (to != from || (hw_flags & MI_FORCE_RESTORE)) {
+		ret = mi_set_context(req, hw_flags);
+		if (ret)
+			goto unpin_out;
+	}
+
+	/* The backing object for the context is done after switching to the
+	 * *next* context. Therefore we cannot retire the previous context until
+	 * the next context has already started running. In fact, the below code
+	 * is a bit suboptimal because the retiring can occur simply after the
+	 * MI_SET_CONTEXT instead of when the next seqno has completed.
+	 */
+	if (from != NULL) {
+		from->legacy_hw_ctx.rcs_state->base.read_domains = I915_GEM_DOMAIN_INSTRUCTION;
+		i915_vma_move_to_active(i915_gem_obj_to_ggtt(from->legacy_hw_ctx.rcs_state), req);
+		/* As long as MI_SET_CONTEXT is serializing, ie. it flushes the
+		 * whole damn pipeline, we don't need to explicitly mark the
+		 * object dirty. The only exception is that the context must be
+		 * correct in case the object gets swapped out. Ideally we'd be
+		 * able to defer doing this until we know the object would be
+		 * swapped, but there is no way to do that yet.
+		 */
+		from->legacy_hw_ctx.rcs_state->dirty = 1;
+
+		/* obj is kept alive until the next request by its active ref */
+		i915_gem_object_ggtt_unpin(from->legacy_hw_ctx.rcs_state);
+		i915_gem_context_unreference(from);
+	}
+	i915_gem_context_reference(to);
+	engine->last_context = to;
+
+	/* GEN8 does *not* require an explicit reload if the PDPs have been
+	 * setup, and we do not wish to move them.
+	 */
+	if (needs_pd_load_post(to, hw_flags)) {
+		trace_switch_mm(engine, to);
+		ret = to->ppgtt->switch_mm(to->ppgtt, req);
+		/* The hardware context switch is emitted, but we haven't
+		 * actually changed the state - so it's probably safe to bail
+		 * here. Still, let the user know something dangerous has
+		 * happened.
+		 */
+		if (ret)
+			return ret;
+	}
+
+	if (to->ppgtt)
+		to->ppgtt->pd_dirty_rings &= ~intel_engine_flag(engine);
+
+	for (i = 0; i < MAX_L3_SLICES; i++) {
+		if (!(to->remap_slice & (1<<i)))
+			continue;
+
+		ret = i915_gem_l3_remap(req, i);
+		if (ret)
+			return ret;
+
+		to->remap_slice &= ~(1<<i);
+	}
+
+	if (!to->legacy_hw_ctx.initialized) {
+		if (engine->init_context) {
+			ret = engine->init_context(req);
+			if (ret)
+				return ret;
+		}
+		to->legacy_hw_ctx.initialized = true;
+	}
+
+	return 0;
+
+unpin_out:
+	i915_gem_object_ggtt_unpin(to->legacy_hw_ctx.rcs_state);
+	return ret;
+}
+
+/**
+ * i915_switch_context() - perform a GPU context switch.
+ * @req: request for which we'll execute the context switch
+ *
+ * The context life cycle is simple. The context refcount is incremented and
+ * decremented by 1 and create and destroy. If the context is in use by the GPU,
+ * it will have a refcount > 1. This allows us to destroy the context abstract
+ * object while letting the normal object tracking destroy the backing BO.
+ *
+ * This function should not be used in execlists mode.  Instead the context is
+ * switched by writing to the ELSP and requests keep a reference to their
+ * context.
+ */
+int i915_switch_context(struct drm_i915_gem_request *req)
+{
+	struct intel_engine_cs *engine = req->engine;
+	struct drm_i915_private *dev_priv = req->i915;
+
+	WARN_ON(i915.enable_execlists);
+	WARN_ON(!mutex_is_locked(&dev_priv->dev->struct_mutex));
+
+	if (engine->id != RCS ||
+	    req->ctx->legacy_hw_ctx.rcs_state == NULL) {
+		struct intel_context *to = req->ctx;
+
+		if (needs_pd_load_pre(engine, to)) {
+			int ret;
+
+			trace_switch_mm(engine, to);
+			ret = to->ppgtt->switch_mm(to->ppgtt, req);
+			if (ret)
+				return ret;
+
+			/* Doing a PD load always reloads the page dirs */
+			to->ppgtt->pd_dirty_rings &= ~intel_engine_flag(engine);
+		}
+
+		if (to != engine->last_context) {
+			i915_gem_context_reference(to);
+			if (engine->last_context)
+				i915_gem_context_unreference(engine->last_context);
+			engine->last_context = to;
+		}
+
+		return 0;
+	}
+
+	return do_rcs_switch(req);
+}
+
+static bool contexts_enabled(struct drm_device *dev)
+{
+	return i915.enable_execlists || to_i915(dev)->hw_context_size;
+}
+
+int i915_gem_context_create_ioctl(struct drm_device *dev, void *data,
+				  struct drm_file *file)
+{
+	struct drm_i915_gem_context_create *args = data;
+	struct drm_i915_file_private *file_priv = file->driver_priv;
+	struct intel_context *ctx;
+	int ret;
+
+	if (!contexts_enabled(dev))
+		return -ENODEV;
+
+	if (args->pad != 0)
+		return -EINVAL;
+
+	ret = i915_mutex_lock_interruptible(dev);
+	if (ret)
+		return ret;
+
+	ctx = i915_gem_create_context(dev, file_priv);
+	mutex_unlock(&dev->struct_mutex);
+	if (IS_ERR(ctx))
+		return PTR_ERR(ctx);
+
+	args->ctx_id = ctx->user_handle;
+	DRM_DEBUG_DRIVER("HW context %d created\n", args->ctx_id);
+
+	return 0;
+}
+
+int i915_gem_context_destroy_ioctl(struct drm_device *dev, void *data,
+				   struct drm_file *file)
+{
+	struct drm_i915_gem_context_destroy *args = data;
+	struct drm_i915_file_private *file_priv = file->driver_priv;
+	struct intel_context *ctx;
+	int ret;
+
+	if (args->pad != 0)
+		return -EINVAL;
+
+	if (args->ctx_id == DEFAULT_CONTEXT_HANDLE)
+		return -ENOENT;
+
+	ret = i915_mutex_lock_interruptible(dev);
+	if (ret)
+		return ret;
+
+	ctx = i915_gem_context_get(file_priv, args->ctx_id);
+	if (IS_ERR(ctx)) {
+		mutex_unlock(&dev->struct_mutex);
+		return PTR_ERR(ctx);
+	}
+
+	idr_remove(&ctx->file_priv->context_idr, ctx->user_handle);
+	i915_gem_context_unreference(ctx);
+	mutex_unlock(&dev->struct_mutex);
+
+	DRM_DEBUG_DRIVER("HW context %d destroyed\n", args->ctx_id);
+	return 0;
+}
+
+int i915_gem_context_getparam_ioctl(struct drm_device *dev, void *data,
+				    struct drm_file *file)
+{
+	struct drm_i915_file_private *file_priv = file->driver_priv;
+	struct drm_i915_gem_context_param *args = data;
+	struct intel_context *ctx;
+	int ret;
+
+	ret = i915_mutex_lock_interruptible(dev);
+	if (ret)
+		return ret;
+
+	ctx = i915_gem_context_get(file_priv, args->ctx_id);
+	if (IS_ERR(ctx)) {
+		mutex_unlock(&dev->struct_mutex);
+		return PTR_ERR(ctx);
+	}
+
+	args->size = 0;
+	switch (args->param) {
+	case I915_CONTEXT_PARAM_BAN_PERIOD:
+		args->value = ctx->hang_stats.ban_period_seconds;
+		break;
+	case I915_CONTEXT_PARAM_NO_ZEROMAP:
+		args->value = ctx->flags & CONTEXT_NO_ZEROMAP;
+		break;
+	case I915_CONTEXT_PARAM_GTT_SIZE:
+		if (ctx->ppgtt)
+			args->value = ctx->ppgtt->base.total;
+		else if (to_i915(dev)->mm.aliasing_ppgtt)
+			args->value = to_i915(dev)->mm.aliasing_ppgtt->base.total;
+		else
+			args->value = to_i915(dev)->ggtt.base.total;
+		break;
+	default:
+		ret = -EINVAL;
+		break;
+	}
+	mutex_unlock(&dev->struct_mutex);
+
+	return ret;
+}
+
+int i915_gem_context_setparam_ioctl(struct drm_device *dev, void *data,
+				    struct drm_file *file)
+{
+	struct drm_i915_file_private *file_priv = file->driver_priv;
+	struct drm_i915_gem_context_param *args = data;
+	struct intel_context *ctx;
+	int ret;
+
+	ret = i915_mutex_lock_interruptible(dev);
+	if (ret)
+		return ret;
+
+	ctx = i915_gem_context_get(file_priv, args->ctx_id);
+	if (IS_ERR(ctx)) {
+		mutex_unlock(&dev->struct_mutex);
+		return PTR_ERR(ctx);
+	}
+
+	switch (args->param) {
+	case I915_CONTEXT_PARAM_BAN_PERIOD:
+		if (args->size)
+			ret = -EINVAL;
+		else if (args->value < ctx->hang_stats.ban_period_seconds &&
+			 !capable(CAP_SYS_ADMIN))
+			ret = -EPERM;
+		else
+			ctx->hang_stats.ban_period_seconds = args->value;
+		break;
+	case I915_CONTEXT_PARAM_NO_ZEROMAP:
+		if (args->size) {
+			ret = -EINVAL;
+		} else {
+			ctx->flags &= ~CONTEXT_NO_ZEROMAP;
+			ctx->flags |= args->value ? CONTEXT_NO_ZEROMAP : 0;
+		}
+		break;
+	default:
+		ret = -EINVAL;
+		break;
+	}
+	mutex_unlock(&dev->struct_mutex);
+
+	return ret;
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/i915/i915_gem_debug.c
@@ -0,0 +1,70 @@
+/*
+ * Copyright © 2008 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Keith Packard <keithp@keithp.com>
+ *
+ */
+
+#include <drm/drmP.h>
+#include <drm/i915_drm.h>
+#include "i915_drv.h"
+
+#if WATCH_LISTS
+int
+i915_verify_lists(struct drm_device *dev)
+{
+	static int warned;
+	struct drm_i915_private *dev_priv = to_i915(dev);
+	struct drm_i915_gem_object *obj;
+	struct intel_engine_cs *engine;
+	int err = 0;
+
+	if (warned)
+		return 0;
+
+	for_each_engine(engine, dev_priv) {
+		list_for_each_entry(obj, &engine->active_list,
+				    engine_list[engine->id]) {
+			if (obj->base.dev != dev ||
+			    !atomic_read(&obj->base.refcount.refcount)) {
+				DRM_ERROR("%s: freed active obj %p\n",
+					  engine->name, obj);
+				err++;
+				break;
+			} else if (!obj->active ||
+				   obj->last_read_req[engine->id] == NULL) {
+				DRM_ERROR("%s: invalid active obj %p\n",
+					  engine->name, obj);
+				err++;
+			} else if (obj->base.write_domain) {
+				DRM_ERROR("%s: invalid write obj %p (w %x)\n",
+					  engine->name,
+					  obj, obj->base.write_domain);
+				err++;
+			}
+		}
+	}
+
+	return warned = err;
+}
+#endif /* WATCH_LIST */
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/i915/i915_gem_dmabuf.c
@@ -0,0 +1,310 @@
+/*
+ * Copyright 2012 Red Hat Inc
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *	Dave Airlie <airlied@redhat.com>
+ */
+#include <drm/drmP.h>
+#include "i915_drv.h"
+#include <linux/dma-buf.h>
+
+static struct drm_i915_gem_object *dma_buf_to_obj(struct dma_buf *buf)
+{
+	return to_intel_bo(buf->priv);
+}
+
+static struct sg_table *i915_gem_map_dma_buf(struct dma_buf_attachment *attachment,
+					     enum dma_data_direction dir)
+{
+	struct drm_i915_gem_object *obj = dma_buf_to_obj(attachment->dmabuf);
+	struct sg_table *st;
+	struct scatterlist *src, *dst;
+	int ret, i;
+
+	ret = i915_mutex_lock_interruptible(obj->base.dev);
+	if (ret)
+		goto err;
+
+	ret = i915_gem_object_get_pages(obj);
+	if (ret)
+		goto err_unlock;
+
+	i915_gem_object_pin_pages(obj);
+
+	/* Copy sg so that we make an independent mapping */
+	st = kmalloc(sizeof(struct sg_table), GFP_KERNEL);
+	if (st == NULL) {
+		ret = -ENOMEM;
+		goto err_unpin;
+	}
+
+	ret = sg_alloc_table(st, obj->pages->nents, GFP_KERNEL);
+	if (ret)
+		goto err_free;
+
+	src = obj->pages->sgl;
+	dst = st->sgl;
+	for (i = 0; i < obj->pages->nents; i++) {
+		sg_set_page(dst, sg_page(src), src->length, 0);
+		dst = sg_next(dst);
+		src = sg_next(src);
+	}
+
+	if (!dma_map_sg(attachment->dev, st->sgl, st->nents, dir)) {
+		ret =-ENOMEM;
+		goto err_free_sg;
+	}
+
+	mutex_unlock(&obj->base.dev->struct_mutex);
+	return st;
+
+err_free_sg:
+	sg_free_table(st);
+err_free:
+	kfree(st);
+err_unpin:
+	i915_gem_object_unpin_pages(obj);
+err_unlock:
+	mutex_unlock(&obj->base.dev->struct_mutex);
+err:
+	return ERR_PTR(ret);
+}
+
+static void i915_gem_unmap_dma_buf(struct dma_buf_attachment *attachment,
+				   struct sg_table *sg,
+				   enum dma_data_direction dir)
+{
+	struct drm_i915_gem_object *obj = dma_buf_to_obj(attachment->dmabuf);
+
+	dma_unmap_sg(attachment->dev, sg->sgl, sg->nents, dir);
+	sg_free_table(sg);
+	kfree(sg);
+
+	mutex_lock(&obj->base.dev->struct_mutex);
+	i915_gem_object_unpin_pages(obj);
+	mutex_unlock(&obj->base.dev->struct_mutex);
+}
+
+static void *i915_gem_dmabuf_vmap(struct dma_buf *dma_buf)
+{
+	struct drm_i915_gem_object *obj = dma_buf_to_obj(dma_buf);
+	struct drm_device *dev = obj->base.dev;
+	void *addr;
+	int ret;
+
+	ret = i915_mutex_lock_interruptible(dev);
+	if (ret)
+		return ERR_PTR(ret);
+
+	addr = i915_gem_object_pin_map(obj);
+	mutex_unlock(&dev->struct_mutex);
+
+	return addr;
+}
+
+static void i915_gem_dmabuf_vunmap(struct dma_buf *dma_buf, void *vaddr)
+{
+	struct drm_i915_gem_object *obj = dma_buf_to_obj(dma_buf);
+	struct drm_device *dev = obj->base.dev;
+
+	mutex_lock(&dev->struct_mutex);
+	i915_gem_object_unpin_map(obj);
+	mutex_unlock(&dev->struct_mutex);
+}
+
+static void *i915_gem_dmabuf_kmap_atomic(struct dma_buf *dma_buf, unsigned long page_num)
+{
+	return NULL;
+}
+
+static void i915_gem_dmabuf_kunmap_atomic(struct dma_buf *dma_buf, unsigned long page_num, void *addr)
+{
+
+}
+static void *i915_gem_dmabuf_kmap(struct dma_buf *dma_buf, unsigned long page_num)
+{
+	return NULL;
+}
+
+static void i915_gem_dmabuf_kunmap(struct dma_buf *dma_buf, unsigned long page_num, void *addr)
+{
+
+}
+
+static int i915_gem_dmabuf_mmap(struct dma_buf *dma_buf, struct vm_area_struct *vma)
+{
+	struct drm_i915_gem_object *obj = dma_buf_to_obj(dma_buf);
+	int ret;
+
+	if (obj->base.size < vma->vm_end - vma->vm_start)
+		return -EINVAL;
+
+	if (!obj->base.filp)
+		return -ENODEV;
+
+	ret = obj->base.filp->f_op->mmap(obj->base.filp, vma);
+	if (ret)
+		return ret;
+
+	fput(vma->vm_file);
+	vma->vm_file = get_file(obj->base.filp);
+
+	return 0;
+}
+
+static int i915_gem_begin_cpu_access(struct dma_buf *dma_buf, enum dma_data_direction direction)
+{
+	struct drm_i915_gem_object *obj = dma_buf_to_obj(dma_buf);
+	struct drm_device *dev = obj->base.dev;
+	int ret;
+	bool write = (direction == DMA_BIDIRECTIONAL || direction == DMA_TO_DEVICE);
+
+	ret = i915_mutex_lock_interruptible(dev);
+	if (ret)
+		return ret;
+
+	ret = i915_gem_object_set_to_cpu_domain(obj, write);
+	mutex_unlock(&dev->struct_mutex);
+	return ret;
+}
+
+static int i915_gem_end_cpu_access(struct dma_buf *dma_buf, enum dma_data_direction direction)
+{
+	struct drm_i915_gem_object *obj = dma_buf_to_obj(dma_buf);
+	struct drm_device *dev = obj->base.dev;
+	int ret;
+
+	ret = i915_mutex_lock_interruptible(dev);
+	if (ret)
+		return ret;
+
+	ret = i915_gem_object_set_to_gtt_domain(obj, false);
+	mutex_unlock(&dev->struct_mutex);
+
+	return ret;
+}
+
+static const struct dma_buf_ops i915_dmabuf_ops =  {
+	.map_dma_buf = i915_gem_map_dma_buf,
+	.unmap_dma_buf = i915_gem_unmap_dma_buf,
+	.release = drm_gem_dmabuf_release,
+	.kmap = i915_gem_dmabuf_kmap,
+	.kmap_atomic = i915_gem_dmabuf_kmap_atomic,
+	.kunmap = i915_gem_dmabuf_kunmap,
+	.kunmap_atomic = i915_gem_dmabuf_kunmap_atomic,
+	.mmap = i915_gem_dmabuf_mmap,
+	.vmap = i915_gem_dmabuf_vmap,
+	.vunmap = i915_gem_dmabuf_vunmap,
+	.begin_cpu_access = i915_gem_begin_cpu_access,
+	.end_cpu_access = i915_gem_end_cpu_access,
+};
+
+struct dma_buf *i915_gem_prime_export(struct drm_device *dev,
+				      struct drm_gem_object *gem_obj, int flags)
+{
+	struct drm_i915_gem_object *obj = to_intel_bo(gem_obj);
+	DEFINE_DMA_BUF_EXPORT_INFO(exp_info);
+
+	exp_info.ops = &i915_dmabuf_ops;
+	exp_info.size = gem_obj->size;
+	exp_info.flags = flags;
+	exp_info.priv = gem_obj;
+
+
+	if (obj->ops->dmabuf_export) {
+		int ret = obj->ops->dmabuf_export(obj);
+		if (ret)
+			return ERR_PTR(ret);
+	}
+
+	return dma_buf_export(&exp_info);
+}
+
+static int i915_gem_object_get_pages_dmabuf(struct drm_i915_gem_object *obj)
+{
+	struct sg_table *sg;
+
+	sg = dma_buf_map_attachment(obj->base.import_attach, DMA_BIDIRECTIONAL);
+	if (IS_ERR(sg))
+		return PTR_ERR(sg);
+
+	obj->pages = sg;
+	return 0;
+}
+
+static void i915_gem_object_put_pages_dmabuf(struct drm_i915_gem_object *obj)
+{
+	dma_buf_unmap_attachment(obj->base.import_attach,
+				 obj->pages, DMA_BIDIRECTIONAL);
+}
+
+static const struct drm_i915_gem_object_ops i915_gem_object_dmabuf_ops = {
+	.get_pages = i915_gem_object_get_pages_dmabuf,
+	.put_pages = i915_gem_object_put_pages_dmabuf,
+};
+
+struct drm_gem_object *i915_gem_prime_import(struct drm_device *dev,
+					     struct dma_buf *dma_buf)
+{
+	struct dma_buf_attachment *attach;
+	struct drm_i915_gem_object *obj;
+	int ret;
+
+	/* is this one of own objects? */
+	if (dma_buf->ops == &i915_dmabuf_ops) {
+		obj = dma_buf_to_obj(dma_buf);
+		/* is it from our device? */
+		if (obj->base.dev == dev) {
+			/*
+			 * Importing dmabuf exported from out own gem increases
+			 * refcount on gem itself instead of f_count of dmabuf.
+			 */
+			drm_gem_object_reference(&obj->base);
+			return &obj->base;
+		}
+	}
+
+	/* need to attach */
+	attach = dma_buf_attach(dma_buf, dev->dev);
+	if (IS_ERR(attach))
+		return ERR_CAST(attach);
+
+	get_dma_buf(dma_buf);
+
+	obj = i915_gem_object_alloc(dev);
+	if (obj == NULL) {
+		ret = -ENOMEM;
+		goto fail_detach;
+	}
+
+	drm_gem_private_object_init(dev, &obj->base, dma_buf->size);
+	i915_gem_object_init(obj, &i915_gem_object_dmabuf_ops);
+	obj->base.import_attach = attach;
+
+	return &obj->base;
+
+fail_detach:
+	dma_buf_detach(dma_buf, attach);
+	dma_buf_put(dma_buf);
+
+	return ERR_PTR(ret);
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/i915/i915_gem_evict.c
@@ -0,0 +1,278 @@
+/*
+ * Copyright © 2008-2010 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Eric Anholt <eric@anholt.net>
+ *    Chris Wilson <chris@chris-wilson.co.uuk>
+ *
+ */
+
+#include <drm/drmP.h>
+#include <drm/i915_drm.h>
+
+#include "i915_drv.h"
+#include "intel_drv.h"
+#include "i915_trace.h"
+
+static bool
+mark_free(struct i915_vma *vma, struct list_head *unwind)
+{
+	if (vma->pin_count)
+		return false;
+
+	if (WARN_ON(!list_empty(&vma->exec_list)))
+		return false;
+
+	list_add(&vma->exec_list, unwind);
+	return drm_mm_scan_add_block(&vma->node);
+}
+
+/**
+ * i915_gem_evict_something - Evict vmas to make room for binding a new one
+ * @dev: drm_device
+ * @vm: address space to evict from
+ * @min_size: size of the desired free space
+ * @alignment: alignment constraint of the desired free space
+ * @cache_level: cache_level for the desired space
+ * @start: start (inclusive) of the range from which to evict objects
+ * @end: end (exclusive) of the range from which to evict objects
+ * @flags: additional flags to control the eviction algorithm
+ *
+ * This function will try to evict vmas until a free space satisfying the
+ * requirements is found. Callers must check first whether any such hole exists
+ * already before calling this function.
+ *
+ * This function is used by the object/vma binding code.
+ *
+ * Since this function is only used to free up virtual address space it only
+ * ignores pinned vmas, and not object where the backing storage itself is
+ * pinned. Hence obj->pages_pin_count does not protect against eviction.
+ *
+ * To clarify: This is for freeing up virtual address space, not for freeing
+ * memory in e.g. the shrinker.
+ */
+int
+i915_gem_evict_something(struct drm_device *dev, struct i915_address_space *vm,
+			 int min_size, unsigned alignment, unsigned cache_level,
+			 unsigned long start, unsigned long end,
+			 unsigned flags)
+{
+	struct list_head eviction_list, unwind_list;
+	struct i915_vma *vma;
+	int ret = 0;
+	int pass = 0;
+
+	trace_i915_gem_evict(dev, min_size, alignment, flags);
+
+	/*
+	 * The goal is to evict objects and amalgamate space in LRU order.
+	 * The oldest idle objects reside on the inactive list, which is in
+	 * retirement order. The next objects to retire are those on the (per
+	 * ring) active list that do not have an outstanding flush. Once the
+	 * hardware reports completion (the seqno is updated after the
+	 * batchbuffer has been finished) the clean buffer objects would
+	 * be retired to the inactive list. Any dirty objects would be added
+	 * to the tail of the flushing list. So after processing the clean
+	 * active objects we need to emit a MI_FLUSH to retire the flushing
+	 * list, hence the retirement order of the flushing list is in
+	 * advance of the dirty objects on the active lists.
+	 *
+	 * The retirement sequence is thus:
+	 *   1. Inactive objects (already retired)
+	 *   2. Clean active objects
+	 *   3. Flushing list
+	 *   4. Dirty active objects.
+	 *
+	 * On each list, the oldest objects lie at the HEAD with the freshest
+	 * object on the TAIL.
+	 */
+
+	INIT_LIST_HEAD(&unwind_list);
+	if (start != 0 || end != vm->total) {
+		drm_mm_init_scan_with_range(&vm->mm, min_size,
+					    alignment, cache_level,
+					    start, end);
+	} else
+		drm_mm_init_scan(&vm->mm, min_size, alignment, cache_level);
+
+search_again:
+	/* First see if there is a large enough contiguous idle region... */
+	list_for_each_entry(vma, &vm->inactive_list, vm_link) {
+		if (mark_free(vma, &unwind_list))
+			goto found;
+	}
+
+	if (flags & PIN_NONBLOCK)
+		goto none;
+
+	/* Now merge in the soon-to-be-expired objects... */
+	list_for_each_entry(vma, &vm->active_list, vm_link) {
+		if (mark_free(vma, &unwind_list))
+			goto found;
+	}
+
+none:
+	/* Nothing found, clean up and bail out! */
+	while (!list_empty(&unwind_list)) {
+		vma = list_first_entry(&unwind_list,
+				       struct i915_vma,
+				       exec_list);
+		ret = drm_mm_scan_remove_block(&vma->node);
+		BUG_ON(ret);
+
+		list_del_init(&vma->exec_list);
+	}
+
+	/* Can we unpin some objects such as idle hw contents,
+	 * or pending flips?
+	 */
+	if (flags & PIN_NONBLOCK)
+		return -ENOSPC;
+
+	/* Only idle the GPU and repeat the search once */
+	if (pass++ == 0) {
+		ret = i915_gpu_idle(dev);
+		if (ret)
+			return ret;
+
+		i915_gem_retire_requests(dev);
+		goto search_again;
+	}
+
+	/* If we still have pending pageflip completions, drop
+	 * back to userspace to give our workqueues time to
+	 * acquire our locks and unpin the old scanouts.
+	 */
+	return intel_has_pending_fb_unpin(dev) ? -EAGAIN : -ENOSPC;
+
+found:
+	/* drm_mm doesn't allow any other other operations while
+	 * scanning, therefore store to be evicted objects on a
+	 * temporary list. */
+	INIT_LIST_HEAD(&eviction_list);
+	while (!list_empty(&unwind_list)) {
+		vma = list_first_entry(&unwind_list,
+				       struct i915_vma,
+				       exec_list);
+		if (drm_mm_scan_remove_block(&vma->node)) {
+			list_move(&vma->exec_list, &eviction_list);
+			drm_gem_object_reference(&vma->obj->base);
+			continue;
+		}
+		list_del_init(&vma->exec_list);
+	}
+
+	/* Unbinding will emit any required flushes */
+	while (!list_empty(&eviction_list)) {
+		struct drm_gem_object *obj;
+		vma = list_first_entry(&eviction_list,
+				       struct i915_vma,
+				       exec_list);
+
+		obj =  &vma->obj->base;
+		list_del_init(&vma->exec_list);
+		if (ret == 0)
+			ret = i915_vma_unbind(vma);
+
+		drm_gem_object_unreference(obj);
+	}
+
+	return ret;
+}
+
+int
+i915_gem_evict_for_vma(struct i915_vma *target)
+{
+	struct drm_mm_node *node, *next;
+
+	list_for_each_entry_safe(node, next,
+			&target->vm->mm.head_node.node_list,
+			node_list) {
+		struct i915_vma *vma;
+		int ret;
+
+		if (node->start + node->size <= target->node.start)
+			continue;
+		if (node->start >= target->node.start + target->node.size)
+			break;
+
+		vma = container_of(node, typeof(*vma), node);
+
+		if (vma->pin_count) {
+			if (!vma->exec_entry || (vma->pin_count > 1))
+				/* Object is pinned for some other use */
+				return -EBUSY;
+
+			/* We need to evict a buffer in the same batch */
+			if (vma->exec_entry->flags & EXEC_OBJECT_PINNED)
+				/* Overlapping fixed objects in the same batch */
+				return -EINVAL;
+
+			return -ENOSPC;
+		}
+
+		ret = i915_vma_unbind(vma);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
+/**
+ * i915_gem_evict_vm - Evict all idle vmas from a vm
+ * @vm: Address space to cleanse
+ * @do_idle: Boolean directing whether to idle first.
+ *
+ * This function evicts all idles vmas from a vm. If all unpinned vmas should be
+ * evicted the @do_idle needs to be set to true.
+ *
+ * This is used by the execbuf code as a last-ditch effort to defragment the
+ * address space.
+ *
+ * To clarify: This is for freeing up virtual address space, not for freeing
+ * memory in e.g. the shrinker.
+ */
+int i915_gem_evict_vm(struct i915_address_space *vm, bool do_idle)
+{
+	struct i915_vma *vma, *next;
+	int ret;
+
+	WARN_ON(!mutex_is_locked(&vm->dev->struct_mutex));
+	trace_i915_gem_evict_vm(vm);
+
+	if (do_idle) {
+		ret = i915_gpu_idle(vm->dev);
+		if (ret)
+			return ret;
+
+		i915_gem_retire_requests(vm->dev);
+
+		WARN_ON(!list_empty(&vm->active_list));
+	}
+
+	list_for_each_entry_safe(vma, next, &vm->inactive_list, vm_link)
+		if (vma->pin_count == 0)
+			WARN_ON(i915_vma_unbind(vma));
+
+	return 0;
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/i915/i915_gem_execbuffer.c
@@ -0,0 +1,1820 @@
+/*
+ * Copyright © 2008,2010 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Eric Anholt <eric@anholt.net>
+ *    Chris Wilson <chris@chris-wilson.co.uk>
+ *
+ */
+
+#include <drm/drmP.h>
+#include <drm/i915_drm.h>
+#include "i915_drv.h"
+#include "i915_trace.h"
+#include "intel_drv.h"
+#include <linux/dma_remapping.h>
+#include <linux/uaccess.h>
+
+#define  __EXEC_OBJECT_HAS_PIN (1<<31)
+#define  __EXEC_OBJECT_HAS_FENCE (1<<30)
+#define  __EXEC_OBJECT_NEEDS_MAP (1<<29)
+#define  __EXEC_OBJECT_NEEDS_BIAS (1<<28)
+
+#define BATCH_OFFSET_BIAS (256*1024)
+
+struct eb_vmas {
+	struct list_head vmas;
+	int and;
+	union {
+		struct i915_vma *lut[0];
+		struct hlist_head buckets[0];
+	};
+};
+
+static struct eb_vmas *
+eb_create(struct drm_i915_gem_execbuffer2 *args)
+{
+	struct eb_vmas *eb = NULL;
+
+	if (args->flags & I915_EXEC_HANDLE_LUT) {
+		unsigned size = args->buffer_count;
+		size *= sizeof(struct i915_vma *);
+		size += sizeof(struct eb_vmas);
+		eb = kmalloc(size, GFP_TEMPORARY | __GFP_NOWARN | __GFP_NORETRY);
+	}
+
+	if (eb == NULL) {
+		unsigned size = args->buffer_count;
+		unsigned count = PAGE_SIZE / sizeof(struct hlist_head) / 2;
+		BUILD_BUG_ON_NOT_POWER_OF_2(PAGE_SIZE / sizeof(struct hlist_head));
+		while (count > 2*size)
+			count >>= 1;
+		eb = kzalloc(count*sizeof(struct hlist_head) +
+			     sizeof(struct eb_vmas),
+			     GFP_TEMPORARY);
+		if (eb == NULL)
+			return eb;
+
+		eb->and = count - 1;
+	} else
+		eb->and = -args->buffer_count;
+
+	INIT_LIST_HEAD(&eb->vmas);
+	return eb;
+}
+
+static void
+eb_reset(struct eb_vmas *eb)
+{
+	if (eb->and >= 0)
+		memset(eb->buckets, 0, (eb->and+1)*sizeof(struct hlist_head));
+}
+
+static int
+eb_lookup_vmas(struct eb_vmas *eb,
+	       struct drm_i915_gem_exec_object2 *exec,
+	       const struct drm_i915_gem_execbuffer2 *args,
+	       struct i915_address_space *vm,
+	       struct drm_file *file)
+{
+	struct drm_i915_gem_object *obj;
+	struct list_head objects;
+	int i, ret;
+
+	INIT_LIST_HEAD(&objects);
+	spin_lock(&file->table_lock);
+	/* Grab a reference to the object and release the lock so we can lookup
+	 * or create the VMA without using GFP_ATOMIC */
+	for (i = 0; i < args->buffer_count; i++) {
+		obj = to_intel_bo(idr_find(&file->object_idr, exec[i].handle));
+		if (obj == NULL) {
+			spin_unlock(&file->table_lock);
+			DRM_DEBUG("Invalid object handle %d at index %d\n",
+				   exec[i].handle, i);
+			ret = -ENOENT;
+			goto err;
+		}
+
+		if (!list_empty(&obj->obj_exec_link)) {
+			spin_unlock(&file->table_lock);
+			DRM_DEBUG("Object %p [handle %d, index %d] appears more than once in object list\n",
+				   obj, exec[i].handle, i);
+			ret = -EINVAL;
+			goto err;
+		}
+
+		drm_gem_object_reference(&obj->base);
+		list_add_tail(&obj->obj_exec_link, &objects);
+	}
+	spin_unlock(&file->table_lock);
+
+	i = 0;
+	while (!list_empty(&objects)) {
+		struct i915_vma *vma;
+
+		obj = list_first_entry(&objects,
+				       struct drm_i915_gem_object,
+				       obj_exec_link);
+
+		/*
+		 * NOTE: We can leak any vmas created here when something fails
+		 * later on. But that's no issue since vma_unbind can deal with
+		 * vmas which are not actually bound. And since only
+		 * lookup_or_create exists as an interface to get at the vma
+		 * from the (obj, vm) we don't run the risk of creating
+		 * duplicated vmas for the same vm.
+		 */
+		vma = i915_gem_obj_lookup_or_create_vma(obj, vm);
+		if (IS_ERR(vma)) {
+			DRM_DEBUG("Failed to lookup VMA\n");
+			ret = PTR_ERR(vma);
+			goto err;
+		}
+
+		/* Transfer ownership from the objects list to the vmas list. */
+		list_add_tail(&vma->exec_list, &eb->vmas);
+		list_del_init(&obj->obj_exec_link);
+
+		vma->exec_entry = &exec[i];
+		if (eb->and < 0) {
+			eb->lut[i] = vma;
+		} else {
+			uint32_t handle = args->flags & I915_EXEC_HANDLE_LUT ? i : exec[i].handle;
+			vma->exec_handle = handle;
+			hlist_add_head(&vma->exec_node,
+				       &eb->buckets[handle & eb->and]);
+		}
+		++i;
+	}
+
+	return 0;
+
+
+err:
+	while (!list_empty(&objects)) {
+		obj = list_first_entry(&objects,
+				       struct drm_i915_gem_object,
+				       obj_exec_link);
+		list_del_init(&obj->obj_exec_link);
+		drm_gem_object_unreference(&obj->base);
+	}
+	/*
+	 * Objects already transfered to the vmas list will be unreferenced by
+	 * eb_destroy.
+	 */
+
+	return ret;
+}
+
+static struct i915_vma *eb_get_vma(struct eb_vmas *eb, unsigned long handle)
+{
+	if (eb->and < 0) {
+		if (handle >= -eb->and)
+			return NULL;
+		return eb->lut[handle];
+	} else {
+		struct hlist_head *head;
+		struct i915_vma *vma;
+
+		head = &eb->buckets[handle & eb->and];
+		hlist_for_each_entry(vma, head, exec_node) {
+			if (vma->exec_handle == handle)
+				return vma;
+		}
+		return NULL;
+	}
+}
+
+static void
+i915_gem_execbuffer_unreserve_vma(struct i915_vma *vma)
+{
+	struct drm_i915_gem_exec_object2 *entry;
+	struct drm_i915_gem_object *obj = vma->obj;
+
+	if (!drm_mm_node_allocated(&vma->node))
+		return;
+
+	entry = vma->exec_entry;
+
+	if (entry->flags & __EXEC_OBJECT_HAS_FENCE)
+		i915_gem_object_unpin_fence(obj);
+
+	if (entry->flags & __EXEC_OBJECT_HAS_PIN)
+		vma->pin_count--;
+
+	entry->flags &= ~(__EXEC_OBJECT_HAS_FENCE | __EXEC_OBJECT_HAS_PIN);
+}
+
+static void eb_destroy(struct eb_vmas *eb)
+{
+	while (!list_empty(&eb->vmas)) {
+		struct i915_vma *vma;
+
+		vma = list_first_entry(&eb->vmas,
+				       struct i915_vma,
+				       exec_list);
+		list_del_init(&vma->exec_list);
+		i915_gem_execbuffer_unreserve_vma(vma);
+		drm_gem_object_unreference(&vma->obj->base);
+	}
+	kfree(eb);
+}
+
+static inline int use_cpu_reloc(struct drm_i915_gem_object *obj)
+{
+	return (HAS_LLC(obj->base.dev) ||
+		obj->base.write_domain == I915_GEM_DOMAIN_CPU ||
+		obj->cache_level != I915_CACHE_NONE);
+}
+
+/* Used to convert any address to canonical form.
+ * Starting from gen8, some commands (e.g. STATE_BASE_ADDRESS,
+ * MI_LOAD_REGISTER_MEM and others, see Broadwell PRM Vol2a) require the
+ * addresses to be in a canonical form:
+ * "GraphicsAddress[63:48] are ignored by the HW and assumed to be in correct
+ * canonical form [63:48] == [47]."
+ */
+#define GEN8_HIGH_ADDRESS_BIT 47
+static inline uint64_t gen8_canonical_addr(uint64_t address)
+{
+	return sign_extend64(address, GEN8_HIGH_ADDRESS_BIT);
+}
+
+static inline uint64_t gen8_noncanonical_addr(uint64_t address)
+{
+	return address & ((1ULL << (GEN8_HIGH_ADDRESS_BIT + 1)) - 1);
+}
+
+static inline uint64_t
+relocation_target(struct drm_i915_gem_relocation_entry *reloc,
+		  uint64_t target_offset)
+{
+	return gen8_canonical_addr((int)reloc->delta + target_offset);
+}
+
+static int
+relocate_entry_cpu(struct drm_i915_gem_object *obj,
+		   struct drm_i915_gem_relocation_entry *reloc,
+		   uint64_t target_offset)
+{
+	struct drm_device *dev = obj->base.dev;
+	uint32_t page_offset = offset_in_page(reloc->offset);
+	uint64_t delta = relocation_target(reloc, target_offset);
+	char *vaddr;
+	int ret;
+
+	ret = i915_gem_object_set_to_cpu_domain(obj, true);
+	if (ret)
+		return ret;
+
+	vaddr = kmap_atomic(i915_gem_object_get_dirty_page(obj,
+				reloc->offset >> PAGE_SHIFT));
+	*(uint32_t *)(vaddr + page_offset) = lower_32_bits(delta);
+
+	if (INTEL_INFO(dev)->gen >= 8) {
+		page_offset = offset_in_page(page_offset + sizeof(uint32_t));
+
+		if (page_offset == 0) {
+			kunmap_atomic(vaddr);
+			vaddr = kmap_atomic(i915_gem_object_get_dirty_page(obj,
+			    (reloc->offset + sizeof(uint32_t)) >> PAGE_SHIFT));
+		}
+
+		*(uint32_t *)(vaddr + page_offset) = upper_32_bits(delta);
+	}
+
+	kunmap_atomic(vaddr);
+
+	return 0;
+}
+
+static int
+relocate_entry_gtt(struct drm_i915_gem_object *obj,
+		   struct drm_i915_gem_relocation_entry *reloc,
+		   uint64_t target_offset)
+{
+	struct drm_device *dev = obj->base.dev;
+	struct drm_i915_private *dev_priv = to_i915(dev);
+	struct i915_ggtt *ggtt = &dev_priv->ggtt;
+	uint64_t delta = relocation_target(reloc, target_offset);
+	uint64_t offset;
+	void __iomem *reloc_page;
+	int ret;
+
+	ret = i915_gem_object_set_to_gtt_domain(obj, true);
+	if (ret)
+		return ret;
+
+	ret = i915_gem_object_put_fence(obj);
+	if (ret)
+		return ret;
+
+	/* Map the page containing the relocation we're going to perform.  */
+	offset = i915_gem_obj_ggtt_offset(obj);
+	offset += reloc->offset;
+	reloc_page = io_mapping_map_atomic_wc(ggtt->mappable,
+					      offset & PAGE_MASK);
+	iowrite32(lower_32_bits(delta), reloc_page + offset_in_page(offset));
+
+	if (INTEL_INFO(dev)->gen >= 8) {
+		offset += sizeof(uint32_t);
+
+		if (offset_in_page(offset) == 0) {
+			io_mapping_unmap_atomic(reloc_page);
+			reloc_page =
+				io_mapping_map_atomic_wc(ggtt->mappable,
+							 offset);
+		}
+
+		iowrite32(upper_32_bits(delta),
+			  reloc_page + offset_in_page(offset));
+	}
+
+	io_mapping_unmap_atomic(reloc_page);
+
+	return 0;
+}
+
+static void
+clflush_write32(void *addr, uint32_t value)
+{
+	/* This is not a fast path, so KISS. */
+	drm_clflush_virt_range(addr, sizeof(uint32_t));
+	*(uint32_t *)addr = value;
+	drm_clflush_virt_range(addr, sizeof(uint32_t));
+}
+
+static int
+relocate_entry_clflush(struct drm_i915_gem_object *obj,
+		       struct drm_i915_gem_relocation_entry *reloc,
+		       uint64_t target_offset)
+{
+	struct drm_device *dev = obj->base.dev;
+	uint32_t page_offset = offset_in_page(reloc->offset);
+	uint64_t delta = relocation_target(reloc, target_offset);
+	char *vaddr;
+	int ret;
+
+	ret = i915_gem_object_set_to_gtt_domain(obj, true);
+	if (ret)
+		return ret;
+
+	vaddr = kmap_atomic(i915_gem_object_get_dirty_page(obj,
+				reloc->offset >> PAGE_SHIFT));
+	clflush_write32(vaddr + page_offset, lower_32_bits(delta));
+
+	if (INTEL_INFO(dev)->gen >= 8) {
+		page_offset = offset_in_page(page_offset + sizeof(uint32_t));
+
+		if (page_offset == 0) {
+			kunmap_atomic(vaddr);
+			vaddr = kmap_atomic(i915_gem_object_get_dirty_page(obj,
+			    (reloc->offset + sizeof(uint32_t)) >> PAGE_SHIFT));
+		}
+
+		clflush_write32(vaddr + page_offset, upper_32_bits(delta));
+	}
+
+	kunmap_atomic(vaddr);
+
+	return 0;
+}
+
+static int
+i915_gem_execbuffer_relocate_entry(struct drm_i915_gem_object *obj,
+				   struct eb_vmas *eb,
+				   struct drm_i915_gem_relocation_entry *reloc)
+{
+	struct drm_device *dev = obj->base.dev;
+	struct drm_gem_object *target_obj;
+	struct drm_i915_gem_object *target_i915_obj;
+	struct i915_vma *target_vma;
+	uint64_t target_offset;
+	int ret;
+
+	/* we've already hold a reference to all valid objects */
+	target_vma = eb_get_vma(eb, reloc->target_handle);
+	if (unlikely(target_vma == NULL))
+		return -ENOENT;
+	target_i915_obj = target_vma->obj;
+	target_obj = &target_vma->obj->base;
+
+	target_offset = gen8_canonical_addr(target_vma->node.start);
+
+	/* Sandybridge PPGTT errata: We need a global gtt mapping for MI and
+	 * pipe_control writes because the gpu doesn't properly redirect them
+	 * through the ppgtt for non_secure batchbuffers. */
+	if (unlikely(IS_GEN6(dev) &&
+	    reloc->write_domain == I915_GEM_DOMAIN_INSTRUCTION)) {
+		ret = i915_vma_bind(target_vma, target_i915_obj->cache_level,
+				    PIN_GLOBAL);
+		if (WARN_ONCE(ret, "Unexpected failure to bind target VMA!"))
+			return ret;
+	}
+
+	/* Validate that the target is in a valid r/w GPU domain */
+	if (unlikely(reloc->write_domain & (reloc->write_domain - 1))) {
+		DRM_DEBUG("reloc with multiple write domains: "
+			  "obj %p target %d offset %d "
+			  "read %08x write %08x",
+			  obj, reloc->target_handle,
+			  (int) reloc->offset,
+			  reloc->read_domains,
+			  reloc->write_domain);
+		return -EINVAL;
+	}
+	if (unlikely((reloc->write_domain | reloc->read_domains)
+		     & ~I915_GEM_GPU_DOMAINS)) {
+		DRM_DEBUG("reloc with read/write non-GPU domains: "
+			  "obj %p target %d offset %d "
+			  "read %08x write %08x",
+			  obj, reloc->target_handle,
+			  (int) reloc->offset,
+			  reloc->read_domains,
+			  reloc->write_domain);
+		return -EINVAL;
+	}
+
+	target_obj->pending_read_domains |= reloc->read_domains;
+	target_obj->pending_write_domain |= reloc->write_domain;
+
+	/* If the relocation already has the right value in it, no
+	 * more work needs to be done.
+	 */
+	if (target_offset == reloc->presumed_offset)
+		return 0;
+
+	/* Check that the relocation address is valid... */
+	if (unlikely(reloc->offset >
+		obj->base.size - (INTEL_INFO(dev)->gen >= 8 ? 8 : 4))) {
+		DRM_DEBUG("Relocation beyond object bounds: "
+			  "obj %p target %d offset %d size %d.\n",
+			  obj, reloc->target_handle,
+			  (int) reloc->offset,
+			  (int) obj->base.size);
+		return -EINVAL;
+	}
+	if (unlikely(reloc->offset & 3)) {
+		DRM_DEBUG("Relocation not 4-byte aligned: "
+			  "obj %p target %d offset %d.\n",
+			  obj, reloc->target_handle,
+			  (int) reloc->offset);
+		return -EINVAL;
+	}
+
+	/* We can't wait for rendering with pagefaults disabled */
+	if (obj->active && pagefault_disabled())
+		return -EFAULT;
+
+	if (use_cpu_reloc(obj))
+		ret = relocate_entry_cpu(obj, reloc, target_offset);
+	else if (obj->map_and_fenceable)
+		ret = relocate_entry_gtt(obj, reloc, target_offset);
+	else if (static_cpu_has(X86_FEATURE_CLFLUSH))
+		ret = relocate_entry_clflush(obj, reloc, target_offset);
+	else {
+		WARN_ONCE(1, "Impossible case in relocation handling\n");
+		ret = -ENODEV;
+	}
+
+	if (ret)
+		return ret;
+
+	/* and update the user's relocation entry */
+	reloc->presumed_offset = target_offset;
+
+	return 0;
+}
+
+static int
+i915_gem_execbuffer_relocate_vma(struct i915_vma *vma,
+				 struct eb_vmas *eb)
+{
+#define N_RELOC(x) ((x) / sizeof(struct drm_i915_gem_relocation_entry))
+	struct drm_i915_gem_relocation_entry stack_reloc[N_RELOC(512)];
+	struct drm_i915_gem_relocation_entry __user *user_relocs;
+	struct drm_i915_gem_exec_object2 *entry = vma->exec_entry;
+	int remain, ret;
+
+	user_relocs = to_user_ptr(entry->relocs_ptr);
+
+	remain = entry->relocation_count;
+	while (remain) {
+		struct drm_i915_gem_relocation_entry *r = stack_reloc;
+		int count = remain;
+		if (count > ARRAY_SIZE(stack_reloc))
+			count = ARRAY_SIZE(stack_reloc);
+		remain -= count;
+
+		if (__copy_from_user_inatomic(r, user_relocs, count*sizeof(r[0])))
+			return -EFAULT;
+
+		do {
+			u64 offset = r->presumed_offset;
+
+			ret = i915_gem_execbuffer_relocate_entry(vma->obj, eb, r);
+			if (ret)
+				return ret;
+
+			if (r->presumed_offset != offset &&
+			    __put_user(r->presumed_offset, &user_relocs->presumed_offset)) {
+				return -EFAULT;
+			}
+
+			user_relocs++;
+			r++;
+		} while (--count);
+	}
+
+	return 0;
+#undef N_RELOC
+}
+
+static int
+i915_gem_execbuffer_relocate_vma_slow(struct i915_vma *vma,
+				      struct eb_vmas *eb,
+				      struct drm_i915_gem_relocation_entry *relocs)
+{
+	const struct drm_i915_gem_exec_object2 *entry = vma->exec_entry;
+	int i, ret;
+
+	for (i = 0; i < entry->relocation_count; i++) {
+		ret = i915_gem_execbuffer_relocate_entry(vma->obj, eb, &relocs[i]);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
+static int
+i915_gem_execbuffer_relocate(struct eb_vmas *eb)
+{
+	struct i915_vma *vma;
+	int ret = 0;
+
+	/* This is the fast path and we cannot handle a pagefault whilst
+	 * holding the struct mutex lest the user pass in the relocations
+	 * contained within a mmaped bo. For in such a case we, the page
+	 * fault handler would call i915_gem_fault() and we would try to
+	 * acquire the struct mutex again. Obviously this is bad and so
+	 * lockdep complains vehemently.
+	 */
+	pagefault_disable();
+	list_for_each_entry(vma, &eb->vmas, exec_list) {
+		ret = i915_gem_execbuffer_relocate_vma(vma, eb);
+		if (ret)
+			break;
+	}
+	pagefault_enable();
+
+	return ret;
+}
+
+static bool only_mappable_for_reloc(unsigned int flags)
+{
+	return (flags & (EXEC_OBJECT_NEEDS_FENCE | __EXEC_OBJECT_NEEDS_MAP)) ==
+		__EXEC_OBJECT_NEEDS_MAP;
+}
+
+static int
+i915_gem_execbuffer_reserve_vma(struct i915_vma *vma,
+				struct intel_engine_cs *engine,
+				bool *need_reloc)
+{
+	struct drm_i915_gem_object *obj = vma->obj;
+	struct drm_i915_gem_exec_object2 *entry = vma->exec_entry;
+	uint64_t flags;
+	int ret;
+
+	flags = PIN_USER;
+	if (entry->flags & EXEC_OBJECT_NEEDS_GTT)
+		flags |= PIN_GLOBAL;
+
+	if (!drm_mm_node_allocated(&vma->node)) {
+		/* Wa32bitGeneralStateOffset & Wa32bitInstructionBaseOffset,
+		 * limit address to the first 4GBs for unflagged objects.
+		 */
+		if ((entry->flags & EXEC_OBJECT_SUPPORTS_48B_ADDRESS) == 0)
+			flags |= PIN_ZONE_4G;
+		if (entry->flags & __EXEC_OBJECT_NEEDS_MAP)
+			flags |= PIN_GLOBAL | PIN_MAPPABLE;
+		if (entry->flags & __EXEC_OBJECT_NEEDS_BIAS)
+			flags |= BATCH_OFFSET_BIAS | PIN_OFFSET_BIAS;
+		if (entry->flags & EXEC_OBJECT_PINNED)
+			flags |= entry->offset | PIN_OFFSET_FIXED;
+		if ((flags & PIN_MAPPABLE) == 0)
+			flags |= PIN_HIGH;
+	}
+
+	ret = i915_gem_object_pin(obj, vma->vm, entry->alignment, flags);
+	if ((ret == -ENOSPC  || ret == -E2BIG) &&
+	    only_mappable_for_reloc(entry->flags))
+		ret = i915_gem_object_pin(obj, vma->vm,
+					  entry->alignment,
+					  flags & ~PIN_MAPPABLE);
+	if (ret)
+		return ret;
+
+	entry->flags |= __EXEC_OBJECT_HAS_PIN;
+
+	if (entry->flags & EXEC_OBJECT_NEEDS_FENCE) {
+		ret = i915_gem_object_get_fence(obj);
+		if (ret)
+			return ret;
+
+		if (i915_gem_object_pin_fence(obj))
+			entry->flags |= __EXEC_OBJECT_HAS_FENCE;
+	}
+
+	if (entry->offset != vma->node.start) {
+		entry->offset = vma->node.start;
+		*need_reloc = true;
+	}
+
+	if (entry->flags & EXEC_OBJECT_WRITE) {
+		obj->base.pending_read_domains = I915_GEM_DOMAIN_RENDER;
+		obj->base.pending_write_domain = I915_GEM_DOMAIN_RENDER;
+	}
+
+	return 0;
+}
+
+static bool
+need_reloc_mappable(struct i915_vma *vma)
+{
+	struct drm_i915_gem_exec_object2 *entry = vma->exec_entry;
+
+	if (entry->relocation_count == 0)
+		return false;
+
+	if (!vma->is_ggtt)
+		return false;
+
+	/* See also use_cpu_reloc() */
+	if (HAS_LLC(vma->obj->base.dev))
+		return false;
+
+	if (vma->obj->base.write_domain == I915_GEM_DOMAIN_CPU)
+		return false;
+
+	return true;
+}
+
+static bool
+eb_vma_misplaced(struct i915_vma *vma)
+{
+	struct drm_i915_gem_exec_object2 *entry = vma->exec_entry;
+	struct drm_i915_gem_object *obj = vma->obj;
+
+	WARN_ON(entry->flags & __EXEC_OBJECT_NEEDS_MAP && !vma->is_ggtt);
+
+	if (entry->alignment &&
+	    vma->node.start & (entry->alignment - 1))
+		return true;
+
+	if (entry->flags & EXEC_OBJECT_PINNED &&
+	    vma->node.start != entry->offset)
+		return true;
+
+	if (entry->flags & __EXEC_OBJECT_NEEDS_BIAS &&
+	    vma->node.start < BATCH_OFFSET_BIAS)
+		return true;
+
+	/* avoid costly ping-pong once a batch bo ended up non-mappable */
+	if (entry->flags & __EXEC_OBJECT_NEEDS_MAP && !obj->map_and_fenceable)
+		return !only_mappable_for_reloc(entry->flags);
+
+	if ((entry->flags & EXEC_OBJECT_SUPPORTS_48B_ADDRESS) == 0 &&
+	    (vma->node.start + vma->node.size - 1) >> 32)
+		return true;
+
+	return false;
+}
+
+static int
+i915_gem_execbuffer_reserve(struct intel_engine_cs *engine,
+			    struct list_head *vmas,
+			    struct intel_context *ctx,
+			    bool *need_relocs)
+{
+	struct drm_i915_gem_object *obj;
+	struct i915_vma *vma;
+	struct i915_address_space *vm;
+	struct list_head ordered_vmas;
+	struct list_head pinned_vmas;
+	bool has_fenced_gpu_access = INTEL_INFO(engine->dev)->gen < 4;
+	int retry;
+
+	i915_gem_retire_requests_ring(engine);
+
+	vm = list_first_entry(vmas, struct i915_vma, exec_list)->vm;
+
+	INIT_LIST_HEAD(&ordered_vmas);
+	INIT_LIST_HEAD(&pinned_vmas);
+	while (!list_empty(vmas)) {
+		struct drm_i915_gem_exec_object2 *entry;
+		bool need_fence, need_mappable;
+
+		vma = list_first_entry(vmas, struct i915_vma, exec_list);
+		obj = vma->obj;
+		entry = vma->exec_entry;
+
+		if (ctx->flags & CONTEXT_NO_ZEROMAP)
+			entry->flags |= __EXEC_OBJECT_NEEDS_BIAS;
+
+		if (!has_fenced_gpu_access)
+			entry->flags &= ~EXEC_OBJECT_NEEDS_FENCE;
+		need_fence =
+			entry->flags & EXEC_OBJECT_NEEDS_FENCE &&
+			obj->tiling_mode != I915_TILING_NONE;
+		need_mappable = need_fence || need_reloc_mappable(vma);
+
+		if (entry->flags & EXEC_OBJECT_PINNED)
+			list_move_tail(&vma->exec_list, &pinned_vmas);
+		else if (need_mappable) {
+			entry->flags |= __EXEC_OBJECT_NEEDS_MAP;
+			list_move(&vma->exec_list, &ordered_vmas);
+		} else
+			list_move_tail(&vma->exec_list, &ordered_vmas);
+
+		obj->base.pending_read_domains = I915_GEM_GPU_DOMAINS & ~I915_GEM_DOMAIN_COMMAND;
+		obj->base.pending_write_domain = 0;
+	}
+	list_splice(&ordered_vmas, vmas);
+	list_splice(&pinned_vmas, vmas);
+
+	/* Attempt to pin all of the buffers into the GTT.
+	 * This is done in 3 phases:
+	 *
+	 * 1a. Unbind all objects that do not match the GTT constraints for
+	 *     the execbuffer (fenceable, mappable, alignment etc).
+	 * 1b. Increment pin count for already bound objects.
+	 * 2.  Bind new objects.
+	 * 3.  Decrement pin count.
+	 *
+	 * This avoid unnecessary unbinding of later objects in order to make
+	 * room for the earlier objects *unless* we need to defragment.
+	 */
+	retry = 0;
+	do {
+		int ret = 0;
+
+		/* Unbind any ill-fitting objects or pin. */
+		list_for_each_entry(vma, vmas, exec_list) {
+			if (!drm_mm_node_allocated(&vma->node))
+				continue;
+
+			if (eb_vma_misplaced(vma))
+				ret = i915_vma_unbind(vma);
+			else
+				ret = i915_gem_execbuffer_reserve_vma(vma,
+								      engine,
+								      need_relocs);
+			if (ret)
+				goto err;
+		}
+
+		/* Bind fresh objects */
+		list_for_each_entry(vma, vmas, exec_list) {
+			if (drm_mm_node_allocated(&vma->node))
+				continue;
+
+			ret = i915_gem_execbuffer_reserve_vma(vma, engine,
+							      need_relocs);
+			if (ret)
+				goto err;
+		}
+
+err:
+		if (ret != -ENOSPC || retry++)
+			return ret;
+
+		/* Decrement pin count for bound objects */
+		list_for_each_entry(vma, vmas, exec_list)
+			i915_gem_execbuffer_unreserve_vma(vma);
+
+		ret = i915_gem_evict_vm(vm, true);
+		if (ret)
+			return ret;
+	} while (1);
+}
+
+static int
+i915_gem_execbuffer_relocate_slow(struct drm_device *dev,
+				  struct drm_i915_gem_execbuffer2 *args,
+				  struct drm_file *file,
+				  struct intel_engine_cs *engine,
+				  struct eb_vmas *eb,
+				  struct drm_i915_gem_exec_object2 *exec,
+				  struct intel_context *ctx)
+{
+	struct drm_i915_gem_relocation_entry *reloc;
+	struct i915_address_space *vm;
+	struct i915_vma *vma;
+	bool need_relocs;
+	int *reloc_offset;
+	int i, total, ret;
+	unsigned count = args->buffer_count;
+
+	vm = list_first_entry(&eb->vmas, struct i915_vma, exec_list)->vm;
+
+	/* We may process another execbuffer during the unlock... */
+	while (!list_empty(&eb->vmas)) {
+		vma = list_first_entry(&eb->vmas, struct i915_vma, exec_list);
+		list_del_init(&vma->exec_list);
+		i915_gem_execbuffer_unreserve_vma(vma);
+		drm_gem_object_unreference(&vma->obj->base);
+	}
+
+	mutex_unlock(&dev->struct_mutex);
+
+	total = 0;
+	for (i = 0; i < count; i++)
+		total += exec[i].relocation_count;
+
+	reloc_offset = drm_malloc_ab(count, sizeof(*reloc_offset));
+	reloc = drm_malloc_ab(total, sizeof(*reloc));
+	if (reloc == NULL || reloc_offset == NULL) {
+		drm_free_large(reloc);
+		drm_free_large(reloc_offset);
+		mutex_lock(&dev->struct_mutex);
+		return -ENOMEM;
+	}
+
+	total = 0;
+	for (i = 0; i < count; i++) {
+		struct drm_i915_gem_relocation_entry __user *user_relocs;
+		u64 invalid_offset = (u64)-1;
+		int j;
+
+		user_relocs = to_user_ptr(exec[i].relocs_ptr);
+
+		if (copy_from_user(reloc+total, user_relocs,
+				   exec[i].relocation_count * sizeof(*reloc))) {
+			ret = -EFAULT;
+			mutex_lock(&dev->struct_mutex);
+			goto err;
+		}
+
+		/* As we do not update the known relocation offsets after
+		 * relocating (due to the complexities in lock handling),
+		 * we need to mark them as invalid now so that we force the
+		 * relocation processing next time. Just in case the target
+		 * object is evicted and then rebound into its old
+		 * presumed_offset before the next execbuffer - if that
+		 * happened we would make the mistake of assuming that the
+		 * relocations were valid.
+		 */
+		for (j = 0; j < exec[i].relocation_count; j++) {
+			if (__copy_to_user(&user_relocs[j].presumed_offset,
+					   &invalid_offset,
+					   sizeof(invalid_offset))) {
+				ret = -EFAULT;
+				mutex_lock(&dev->struct_mutex);
+				goto err;
+			}
+		}
+
+		reloc_offset[i] = total;
+		total += exec[i].relocation_count;
+	}
+
+	ret = i915_mutex_lock_interruptible(dev);
+	if (ret) {
+		mutex_lock(&dev->struct_mutex);
+		goto err;
+	}
+
+	/* reacquire the objects */
+	eb_reset(eb);
+	ret = eb_lookup_vmas(eb, exec, args, vm, file);
+	if (ret)
+		goto err;
+
+	need_relocs = (args->flags & I915_EXEC_NO_RELOC) == 0;
+	ret = i915_gem_execbuffer_reserve(engine, &eb->vmas, ctx,
+					  &need_relocs);
+	if (ret)
+		goto err;
+
+	list_for_each_entry(vma, &eb->vmas, exec_list) {
+		int offset = vma->exec_entry - exec;
+		ret = i915_gem_execbuffer_relocate_vma_slow(vma, eb,
+							    reloc + reloc_offset[offset]);
+		if (ret)
+			goto err;
+	}
+
+	/* Leave the user relocations as are, this is the painfully slow path,
+	 * and we want to avoid the complication of dropping the lock whilst
+	 * having buffers reserved in the aperture and so causing spurious
+	 * ENOSPC for random operations.
+	 */
+
+err:
+	drm_free_large(reloc);
+	drm_free_large(reloc_offset);
+	return ret;
+}
+
+static int
+i915_gem_execbuffer_move_to_gpu(struct drm_i915_gem_request *req,
+				struct list_head *vmas)
+{
+	const unsigned other_rings = ~intel_engine_flag(req->engine);
+	struct i915_vma *vma;
+	uint32_t flush_domains = 0;
+	bool flush_chipset = false;
+	int ret;
+
+	list_for_each_entry(vma, vmas, exec_list) {
+		struct drm_i915_gem_object *obj = vma->obj;
+
+		if (obj->active & other_rings) {
+			ret = i915_gem_object_sync(obj, req->engine, &req);
+			if (ret)
+				return ret;
+		}
+
+		if (obj->base.write_domain & I915_GEM_DOMAIN_CPU)
+			flush_chipset |= i915_gem_clflush_object(obj, false);
+
+		flush_domains |= obj->base.write_domain;
+	}
+
+	if (flush_chipset)
+		i915_gem_chipset_flush(req->engine->dev);
+
+	if (flush_domains & I915_GEM_DOMAIN_GTT)
+		wmb();
+
+	/* Unconditionally invalidate gpu caches and ensure that we do flush
+	 * any residual writes from the previous batch.
+	 */
+	return intel_ring_invalidate_all_caches(req);
+}
+
+static bool
+i915_gem_check_execbuffer(struct drm_i915_gem_execbuffer2 *exec)
+{
+	if (exec->flags & __I915_EXEC_UNKNOWN_FLAGS)
+		return false;
+
+	/* Kernel clipping was a DRI1 misfeature */
+	if (exec->num_cliprects || exec->cliprects_ptr)
+		return false;
+
+	if (exec->DR4 == 0xffffffff) {
+		DRM_DEBUG("UXA submitting garbage DR4, fixing up\n");
+		exec->DR4 = 0;
+	}
+	if (exec->DR1 || exec->DR4)
+		return false;
+
+	if ((exec->batch_start_offset | exec->batch_len) & 0x7)
+		return false;
+
+	return true;
+}
+
+static int
+validate_exec_list(struct drm_device *dev,
+		   struct drm_i915_gem_exec_object2 *exec,
+		   int count)
+{
+	unsigned relocs_total = 0;
+	unsigned relocs_max = UINT_MAX / sizeof(struct drm_i915_gem_relocation_entry);
+	unsigned invalid_flags;
+	int i;
+
+	invalid_flags = __EXEC_OBJECT_UNKNOWN_FLAGS;
+	if (USES_FULL_PPGTT(dev))
+		invalid_flags |= EXEC_OBJECT_NEEDS_GTT;
+
+	for (i = 0; i < count; i++) {
+		char __user *ptr = to_user_ptr(exec[i].relocs_ptr);
+		int length; /* limited by fault_in_pages_readable() */
+
+		if (exec[i].flags & invalid_flags)
+			return -EINVAL;
+
+		/* Offset can be used as input (EXEC_OBJECT_PINNED), reject
+		 * any non-page-aligned or non-canonical addresses.
+		 */
+		if (exec[i].flags & EXEC_OBJECT_PINNED) {
+			if (exec[i].offset !=
+			    gen8_canonical_addr(exec[i].offset & PAGE_MASK))
+				return -EINVAL;
+
+			/* From drm_mm perspective address space is continuous,
+			 * so from this point we're always using non-canonical
+			 * form internally.
+			 */
+			exec[i].offset = gen8_noncanonical_addr(exec[i].offset);
+		}
+
+		if (exec[i].alignment && !is_power_of_2(exec[i].alignment))
+			return -EINVAL;
+
+		/* First check for malicious input causing overflow in
+		 * the worst case where we need to allocate the entire
+		 * relocation tree as a single array.
+		 */
+		if (exec[i].relocation_count > relocs_max - relocs_total)
+			return -EINVAL;
+		relocs_total += exec[i].relocation_count;
+
+		length = exec[i].relocation_count *
+			sizeof(struct drm_i915_gem_relocation_entry);
+		/*
+		 * We must check that the entire relocation array is safe
+		 * to read, but since we may need to update the presumed
+		 * offsets during execution, check for full write access.
+		 */
+		if (!access_ok(VERIFY_WRITE, ptr, length))
+			return -EFAULT;
+
+		if (likely(!i915.prefault_disable)) {
+			if (fault_in_multipages_readable(ptr, length))
+				return -EFAULT;
+		}
+	}
+
+	return 0;
+}
+
+static struct intel_context *
+i915_gem_validate_context(struct drm_device *dev, struct drm_file *file,
+			  struct intel_engine_cs *engine, const u32 ctx_id)
+{
+	struct intel_context *ctx = NULL;
+	struct i915_ctx_hang_stats *hs;
+
+	if (engine->id != RCS && ctx_id != DEFAULT_CONTEXT_HANDLE)
+		return ERR_PTR(-EINVAL);
+
+	ctx = i915_gem_context_get(file->driver_priv, ctx_id);
+	if (IS_ERR(ctx))
+		return ctx;
+
+	hs = &ctx->hang_stats;
+	if (hs->banned) {
+		DRM_DEBUG("Context %u tried to submit while banned\n", ctx_id);
+		return ERR_PTR(-EIO);
+	}
+
+	if (i915.enable_execlists && !ctx->engine[engine->id].state) {
+		int ret = intel_lr_context_deferred_alloc(ctx, engine);
+		if (ret) {
+			DRM_DEBUG("Could not create LRC %u: %d\n", ctx_id, ret);
+			return ERR_PTR(ret);
+		}
+	}
+
+	return ctx;
+}
+
+void
+i915_gem_execbuffer_move_to_active(struct list_head *vmas,
+				   struct drm_i915_gem_request *req)
+{
+	struct intel_engine_cs *engine = i915_gem_request_get_engine(req);
+	struct i915_vma *vma;
+
+	list_for_each_entry(vma, vmas, exec_list) {
+		struct drm_i915_gem_exec_object2 *entry = vma->exec_entry;
+		struct drm_i915_gem_object *obj = vma->obj;
+		u32 old_read = obj->base.read_domains;
+		u32 old_write = obj->base.write_domain;
+
+		obj->dirty = 1; /* be paranoid  */
+		obj->base.write_domain = obj->base.pending_write_domain;
+		if (obj->base.write_domain == 0)
+			obj->base.pending_read_domains |= obj->base.read_domains;
+		obj->base.read_domains = obj->base.pending_read_domains;
+
+		i915_vma_move_to_active(vma, req);
+		if (obj->base.write_domain) {
+			i915_gem_request_assign(&obj->last_write_req, req);
+
+			intel_fb_obj_invalidate(obj, ORIGIN_CS);
+
+			/* update for the implicit flush after a batch */
+			obj->base.write_domain &= ~I915_GEM_GPU_DOMAINS;
+		}
+		if (entry->flags & EXEC_OBJECT_NEEDS_FENCE) {
+			i915_gem_request_assign(&obj->last_fenced_req, req);
+			if (entry->flags & __EXEC_OBJECT_HAS_FENCE) {
+				struct drm_i915_private *dev_priv = to_i915(engine->dev);
+				list_move_tail(&dev_priv->fence_regs[obj->fence_reg].lru_list,
+					       &dev_priv->mm.fence_list);
+			}
+		}
+
+		trace_i915_gem_object_change_domain(obj, old_read, old_write);
+	}
+}
+
+static void
+i915_gem_execbuffer_retire_commands(struct i915_execbuffer_params *params)
+{
+	/* Unconditionally force add_request to emit a full flush. */
+	params->engine->gpu_caches_dirty = true;
+
+	/* Add a breadcrumb for the completion of the batch buffer */
+	__i915_add_request(params->request, params->batch_obj, true);
+}
+
+static int
+i915_reset_gen7_sol_offsets(struct drm_device *dev,
+			    struct drm_i915_gem_request *req)
+{
+	struct intel_engine_cs *engine = req->engine;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	int ret, i;
+
+	if (!IS_GEN7(dev) || engine != &dev_priv->engine[RCS]) {
+		DRM_DEBUG("sol reset is gen7/rcs only\n");
+		return -EINVAL;
+	}
+
+	ret = intel_ring_begin(req, 4 * 3);
+	if (ret)
+		return ret;
+
+	for (i = 0; i < 4; i++) {
+		intel_ring_emit(engine, MI_LOAD_REGISTER_IMM(1));
+		intel_ring_emit_reg(engine, GEN7_SO_WRITE_OFFSET(i));
+		intel_ring_emit(engine, 0);
+	}
+
+	intel_ring_advance(engine);
+
+	return 0;
+}
+
+static struct drm_i915_gem_object*
+i915_gem_execbuffer_parse(struct intel_engine_cs *engine,
+			  struct drm_i915_gem_exec_object2 *shadow_exec_entry,
+			  struct eb_vmas *eb,
+			  struct drm_i915_gem_object *batch_obj,
+			  u32 batch_start_offset,
+			  u32 batch_len,
+			  bool is_master)
+{
+	struct drm_i915_gem_object *shadow_batch_obj;
+	struct i915_vma *vma;
+	int ret;
+
+	shadow_batch_obj = i915_gem_batch_pool_get(&engine->batch_pool,
+						   PAGE_ALIGN(batch_len));
+	if (IS_ERR(shadow_batch_obj))
+		return shadow_batch_obj;
+
+	ret = i915_parse_cmds(engine,
+			      batch_obj,
+			      shadow_batch_obj,
+			      batch_start_offset,
+			      batch_len,
+			      is_master);
+	if (ret)
+		goto err;
+
+	ret = i915_gem_obj_ggtt_pin(shadow_batch_obj, 0, 0);
+	if (ret)
+		goto err;
+
+	i915_gem_object_unpin_pages(shadow_batch_obj);
+
+	memset(shadow_exec_entry, 0, sizeof(*shadow_exec_entry));
+
+	vma = i915_gem_obj_to_ggtt(shadow_batch_obj);
+	vma->exec_entry = shadow_exec_entry;
+	vma->exec_entry->flags = __EXEC_OBJECT_HAS_PIN;
+	drm_gem_object_reference(&shadow_batch_obj->base);
+	list_add_tail(&vma->exec_list, &eb->vmas);
+
+	shadow_batch_obj->base.pending_read_domains = I915_GEM_DOMAIN_COMMAND;
+
+	return shadow_batch_obj;
+
+err:
+	i915_gem_object_unpin_pages(shadow_batch_obj);
+	if (ret == -EACCES) /* unhandled chained batch */
+		return batch_obj;
+	else
+		return ERR_PTR(ret);
+}
+
+int
+i915_gem_ringbuffer_submission(struct i915_execbuffer_params *params,
+			       struct drm_i915_gem_execbuffer2 *args,
+			       struct list_head *vmas)
+{
+	struct drm_device *dev = params->dev;
+	struct intel_engine_cs *engine = params->engine;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	u64 exec_start, exec_len;
+	int instp_mode;
+	u32 instp_mask;
+	int ret;
+
+	ret = i915_gem_execbuffer_move_to_gpu(params->request, vmas);
+	if (ret)
+		return ret;
+
+	ret = i915_switch_context(params->request);
+	if (ret)
+		return ret;
+
+	WARN(params->ctx->ppgtt && params->ctx->ppgtt->pd_dirty_rings & (1<<engine->id),
+	     "%s didn't clear reload\n", engine->name);
+
+	instp_mode = args->flags & I915_EXEC_CONSTANTS_MASK;
+	instp_mask = I915_EXEC_CONSTANTS_MASK;
+	switch (instp_mode) {
+	case I915_EXEC_CONSTANTS_REL_GENERAL:
+	case I915_EXEC_CONSTANTS_ABSOLUTE:
+	case I915_EXEC_CONSTANTS_REL_SURFACE:
+		if (instp_mode != 0 && engine != &dev_priv->engine[RCS]) {
+			DRM_DEBUG("non-0 rel constants mode on non-RCS\n");
+			return -EINVAL;
+		}
+
+		if (instp_mode != dev_priv->relative_constants_mode) {
+			if (INTEL_INFO(dev)->gen < 4) {
+				DRM_DEBUG("no rel constants on pre-gen4\n");
+				return -EINVAL;
+			}
+
+			if (INTEL_INFO(dev)->gen > 5 &&
+			    instp_mode == I915_EXEC_CONSTANTS_REL_SURFACE) {
+				DRM_DEBUG("rel surface constants mode invalid on gen5+\n");
+				return -EINVAL;
+			}
+
+			/* The HW changed the meaning on this bit on gen6 */
+			if (INTEL_INFO(dev)->gen >= 6)
+				instp_mask &= ~I915_EXEC_CONSTANTS_REL_SURFACE;
+		}
+		break;
+	default:
+		DRM_DEBUG("execbuf with unknown constants: %d\n", instp_mode);
+		return -EINVAL;
+	}
+
+	if (engine == &dev_priv->engine[RCS] &&
+	    instp_mode != dev_priv->relative_constants_mode) {
+		ret = intel_ring_begin(params->request, 4);
+		if (ret)
+			return ret;
+
+		intel_ring_emit(engine, MI_NOOP);
+		intel_ring_emit(engine, MI_LOAD_REGISTER_IMM(1));
+		intel_ring_emit_reg(engine, INSTPM);
+		intel_ring_emit(engine, instp_mask << 16 | instp_mode);
+		intel_ring_advance(engine);
+
+		dev_priv->relative_constants_mode = instp_mode;
+	}
+
+	if (args->flags & I915_EXEC_GEN7_SOL_RESET) {
+		ret = i915_reset_gen7_sol_offsets(dev, params->request);
+		if (ret)
+			return ret;
+	}
+
+	exec_len   = args->batch_len;
+	exec_start = params->batch_obj_vm_offset +
+		     params->args_batch_start_offset;
+
+	if (exec_len == 0)
+		exec_len = params->batch_obj->base.size;
+
+	ret = engine->dispatch_execbuffer(params->request,
+					exec_start, exec_len,
+					params->dispatch_flags);
+	if (ret)
+		return ret;
+
+	trace_i915_gem_ring_dispatch(params->request, params->dispatch_flags);
+
+	i915_gem_execbuffer_move_to_active(vmas, params->request);
+
+	return 0;
+}
+
+/**
+ * Find one BSD ring to dispatch the corresponding BSD command.
+ * The ring index is returned.
+ */
+static unsigned int
+gen8_dispatch_bsd_ring(struct drm_i915_private *dev_priv, struct drm_file *file)
+{
+	struct drm_i915_file_private *file_priv = file->driver_priv;
+
+	/* Check whether the file_priv has already selected one ring. */
+	if ((int)file_priv->bsd_ring < 0) {
+		/* If not, use the ping-pong mechanism to select one. */
+		mutex_lock(&dev_priv->dev->struct_mutex);
+		file_priv->bsd_ring = dev_priv->mm.bsd_ring_dispatch_index;
+		dev_priv->mm.bsd_ring_dispatch_index ^= 1;
+		mutex_unlock(&dev_priv->dev->struct_mutex);
+	}
+
+	return file_priv->bsd_ring;
+}
+
+static struct drm_i915_gem_object *
+eb_get_batch(struct eb_vmas *eb)
+{
+	struct i915_vma *vma = list_entry(eb->vmas.prev, typeof(*vma), exec_list);
+
+	/*
+	 * SNA is doing fancy tricks with compressing batch buffers, which leads
+	 * to negative relocation deltas. Usually that works out ok since the
+	 * relocate address is still positive, except when the batch is placed
+	 * very low in the GTT. Ensure this doesn't happen.
+	 *
+	 * Note that actual hangs have only been observed on gen7, but for
+	 * paranoia do it everywhere.
+	 */
+	if ((vma->exec_entry->flags & EXEC_OBJECT_PINNED) == 0)
+		vma->exec_entry->flags |= __EXEC_OBJECT_NEEDS_BIAS;
+
+	return vma->obj;
+}
+
+#define I915_USER_RINGS (4)
+
+static const enum intel_engine_id user_ring_map[I915_USER_RINGS + 1] = {
+	[I915_EXEC_DEFAULT]	= RCS,
+	[I915_EXEC_RENDER]	= RCS,
+	[I915_EXEC_BLT]		= BCS,
+	[I915_EXEC_BSD]		= VCS,
+	[I915_EXEC_VEBOX]	= VECS
+};
+
+static int
+eb_select_ring(struct drm_i915_private *dev_priv,
+	       struct drm_file *file,
+	       struct drm_i915_gem_execbuffer2 *args,
+	       struct intel_engine_cs **ring)
+{
+	unsigned int user_ring_id = args->flags & I915_EXEC_RING_MASK;
+
+	if (user_ring_id > I915_USER_RINGS) {
+		DRM_DEBUG("execbuf with unknown ring: %u\n", user_ring_id);
+		return -EINVAL;
+	}
+
+	if ((user_ring_id != I915_EXEC_BSD) &&
+	    ((args->flags & I915_EXEC_BSD_MASK) != 0)) {
+		DRM_DEBUG("execbuf with non bsd ring but with invalid "
+			  "bsd dispatch flags: %d\n", (int)(args->flags));
+		return -EINVAL;
+	}
+
+	if (user_ring_id == I915_EXEC_BSD && HAS_BSD2(dev_priv)) {
+		unsigned int bsd_idx = args->flags & I915_EXEC_BSD_MASK;
+
+		if (bsd_idx == I915_EXEC_BSD_DEFAULT) {
+			bsd_idx = gen8_dispatch_bsd_ring(dev_priv, file);
+		} else if (bsd_idx >= I915_EXEC_BSD_RING1 &&
+			   bsd_idx <= I915_EXEC_BSD_RING2) {
+			bsd_idx >>= I915_EXEC_BSD_SHIFT;
+			bsd_idx--;
+		} else {
+			DRM_DEBUG("execbuf with unknown bsd ring: %u\n",
+				  bsd_idx);
+			return -EINVAL;
+		}
+
+		*ring = &dev_priv->engine[_VCS(bsd_idx)];
+	} else {
+		*ring = &dev_priv->engine[user_ring_map[user_ring_id]];
+	}
+
+	if (!intel_engine_initialized(*ring)) {
+		DRM_DEBUG("execbuf with invalid ring: %u\n", user_ring_id);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int
+i915_gem_do_execbuffer(struct drm_device *dev, void *data,
+		       struct drm_file *file,
+		       struct drm_i915_gem_execbuffer2 *args,
+		       struct drm_i915_gem_exec_object2 *exec)
+{
+	struct drm_i915_private *dev_priv = to_i915(dev);
+	struct i915_ggtt *ggtt = &dev_priv->ggtt;
+	struct drm_i915_gem_request *req = NULL;
+	struct eb_vmas *eb;
+	struct drm_i915_gem_object *batch_obj;
+	struct drm_i915_gem_exec_object2 shadow_exec_entry;
+	struct intel_engine_cs *engine;
+	struct intel_context *ctx;
+	struct i915_address_space *vm;
+	struct i915_execbuffer_params params_master; /* XXX: will be removed later */
+	struct i915_execbuffer_params *params = &params_master;
+	const u32 ctx_id = i915_execbuffer2_get_context_id(*args);
+	u32 dispatch_flags;
+	int ret;
+	bool need_relocs;
+
+	if (!i915_gem_check_execbuffer(args))
+		return -EINVAL;
+
+	ret = validate_exec_list(dev, exec, args->buffer_count);
+	if (ret)
+		return ret;
+
+	dispatch_flags = 0;
+	if (args->flags & I915_EXEC_SECURE) {
+		if (!file->is_master || !capable(CAP_SYS_ADMIN))
+		    return -EPERM;
+
+		dispatch_flags |= I915_DISPATCH_SECURE;
+	}
+	if (args->flags & I915_EXEC_IS_PINNED)
+		dispatch_flags |= I915_DISPATCH_PINNED;
+
+	ret = eb_select_ring(dev_priv, file, args, &engine);
+	if (ret)
+		return ret;
+
+	if (args->buffer_count < 1) {
+		DRM_DEBUG("execbuf with %d buffers\n", args->buffer_count);
+		return -EINVAL;
+	}
+
+	if (args->flags & I915_EXEC_RESOURCE_STREAMER) {
+		if (!HAS_RESOURCE_STREAMER(dev)) {
+			DRM_DEBUG("RS is only allowed for Haswell, Gen8 and above\n");
+			return -EINVAL;
+		}
+		if (engine->id != RCS) {
+			DRM_DEBUG("RS is not available on %s\n",
+				 engine->name);
+			return -EINVAL;
+		}
+
+		dispatch_flags |= I915_DISPATCH_RS;
+	}
+
+	intel_runtime_pm_get(dev_priv);
+
+	ret = i915_mutex_lock_interruptible(dev);
+	if (ret)
+		goto pre_mutex_err;
+
+	ctx = i915_gem_validate_context(dev, file, engine, ctx_id);
+	if (IS_ERR(ctx)) {
+		mutex_unlock(&dev->struct_mutex);
+		ret = PTR_ERR(ctx);
+		goto pre_mutex_err;
+	}
+
+	i915_gem_context_reference(ctx);
+
+	if (ctx->ppgtt)
+		vm = &ctx->ppgtt->base;
+	else
+		vm = &ggtt->base;
+
+	memset(&params_master, 0x00, sizeof(params_master));
+
+	eb = eb_create(args);
+	if (eb == NULL) {
+		i915_gem_context_unreference(ctx);
+		mutex_unlock(&dev->struct_mutex);
+		ret = -ENOMEM;
+		goto pre_mutex_err;
+	}
+
+	/* Look up object handles */
+	ret = eb_lookup_vmas(eb, exec, args, vm, file);
+	if (ret)
+		goto err;
+
+	/* take note of the batch buffer before we might reorder the lists */
+	batch_obj = eb_get_batch(eb);
+
+	/* Move the objects en-masse into the GTT, evicting if necessary. */
+	need_relocs = (args->flags & I915_EXEC_NO_RELOC) == 0;
+	ret = i915_gem_execbuffer_reserve(engine, &eb->vmas, ctx,
+					  &need_relocs);
+	if (ret)
+		goto err;
+
+	/* The objects are in their final locations, apply the relocations. */
+	if (need_relocs)
+		ret = i915_gem_execbuffer_relocate(eb);
+	if (ret) {
+		if (ret == -EFAULT) {
+			ret = i915_gem_execbuffer_relocate_slow(dev, args, file,
+								engine,
+								eb, exec, ctx);
+			BUG_ON(!mutex_is_locked(&dev->struct_mutex));
+		}
+		if (ret)
+			goto err;
+	}
+
+	/* Set the pending read domains for the batch buffer to COMMAND */
+	if (batch_obj->base.pending_write_domain) {
+		DRM_DEBUG("Attempting to use self-modifying batch buffer\n");
+		ret = -EINVAL;
+		goto err;
+	}
+
+	params->args_batch_start_offset = args->batch_start_offset;
+	if (i915_needs_cmd_parser(engine) && args->batch_len) {
+		struct drm_i915_gem_object *parsed_batch_obj;
+
+		parsed_batch_obj = i915_gem_execbuffer_parse(engine,
+							     &shadow_exec_entry,
+							     eb,
+							     batch_obj,
+							     args->batch_start_offset,
+							     args->batch_len,
+							     file->is_master);
+		if (IS_ERR(parsed_batch_obj)) {
+			ret = PTR_ERR(parsed_batch_obj);
+			goto err;
+		}
+
+		/*
+		 * parsed_batch_obj == batch_obj means batch not fully parsed:
+		 * Accept, but don't promote to secure.
+		 */
+
+		if (parsed_batch_obj != batch_obj) {
+			/*
+			 * Batch parsed and accepted:
+			 *
+			 * Set the DISPATCH_SECURE bit to remove the NON_SECURE
+			 * bit from MI_BATCH_BUFFER_START commands issued in
+			 * the dispatch_execbuffer implementations. We
+			 * specifically don't want that set on batches the
+			 * command parser has accepted.
+			 */
+			dispatch_flags |= I915_DISPATCH_SECURE;
+			params->args_batch_start_offset = 0;
+			batch_obj = parsed_batch_obj;
+		}
+	}
+
+	batch_obj->base.pending_read_domains |= I915_GEM_DOMAIN_COMMAND;
+
+	/* snb/ivb/vlv conflate the "batch in ppgtt" bit with the "non-secure
+	 * batch" bit. Hence we need to pin secure batches into the global gtt.
+	 * hsw should have this fixed, but bdw mucks it up again. */
+	if (dispatch_flags & I915_DISPATCH_SECURE) {
+		/*
+		 * So on first glance it looks freaky that we pin the batch here
+		 * outside of the reservation loop. But:
+		 * - The batch is already pinned into the relevant ppgtt, so we
+		 *   already have the backing storage fully allocated.
+		 * - No other BO uses the global gtt (well contexts, but meh),
+		 *   so we don't really have issues with multiple objects not
+		 *   fitting due to fragmentation.
+		 * So this is actually safe.
+		 */
+		ret = i915_gem_obj_ggtt_pin(batch_obj, 0, 0);
+		if (ret)
+			goto err;
+
+		params->batch_obj_vm_offset = i915_gem_obj_ggtt_offset(batch_obj);
+	} else
+		params->batch_obj_vm_offset = i915_gem_obj_offset(batch_obj, vm);
+
+	/* Allocate a request for this batch buffer nice and early. */
+	req = i915_gem_request_alloc(engine, ctx);
+	if (IS_ERR(req)) {
+		ret = PTR_ERR(req);
+		goto err_batch_unpin;
+	}
+
+	ret = i915_gem_request_add_to_client(req, file);
+	if (ret)
+		goto err_request;
+
+	/*
+	 * Save assorted stuff away to pass through to *_submission().
+	 * NB: This data should be 'persistent' and not local as it will
+	 * kept around beyond the duration of the IOCTL once the GPU
+	 * scheduler arrives.
+	 */
+	params->dev                     = dev;
+	params->file                    = file;
+	params->engine                    = engine;
+	params->dispatch_flags          = dispatch_flags;
+	params->batch_obj               = batch_obj;
+	params->ctx                     = ctx;
+	params->request                 = req;
+
+	ret = dev_priv->gt.execbuf_submit(params, args, &eb->vmas);
+err_request:
+	i915_gem_execbuffer_retire_commands(params);
+
+err_batch_unpin:
+	/*
+	 * FIXME: We crucially rely upon the active tracking for the (ppgtt)
+	 * batch vma for correctness. For less ugly and less fragility this
+	 * needs to be adjusted to also track the ggtt batch vma properly as
+	 * active.
+	 */
+	if (dispatch_flags & I915_DISPATCH_SECURE)
+		i915_gem_object_ggtt_unpin(batch_obj);
+
+err:
+	/* the request owns the ref now */
+	i915_gem_context_unreference(ctx);
+	eb_destroy(eb);
+
+	mutex_unlock(&dev->struct_mutex);
+
+pre_mutex_err:
+	/* intel_gpu_busy should also get a ref, so it will free when the device
+	 * is really idle. */
+	intel_runtime_pm_put(dev_priv);
+	return ret;
+}
+
+/*
+ * Legacy execbuffer just creates an exec2 list from the original exec object
+ * list array and passes it to the real function.
+ */
+int
+i915_gem_execbuffer(struct drm_device *dev, void *data,
+		    struct drm_file *file)
+{
+	struct drm_i915_gem_execbuffer *args = data;
+	struct drm_i915_gem_execbuffer2 exec2;
+	struct drm_i915_gem_exec_object *exec_list = NULL;
+	struct drm_i915_gem_exec_object2 *exec2_list = NULL;
+	int ret, i;
+
+	if (args->buffer_count < 1) {
+		DRM_DEBUG("execbuf with %d buffers\n", args->buffer_count);
+		return -EINVAL;
+	}
+
+	/* Copy in the exec list from userland */
+	exec_list = drm_malloc_ab(sizeof(*exec_list), args->buffer_count);
+	exec2_list = drm_malloc_ab(sizeof(*exec2_list), args->buffer_count);
+	if (exec_list == NULL || exec2_list == NULL) {
+		DRM_DEBUG("Failed to allocate exec list for %d buffers\n",
+			  args->buffer_count);
+		drm_free_large(exec_list);
+		drm_free_large(exec2_list);
+		return -ENOMEM;
+	}
+	ret = copy_from_user(exec_list,
+			     to_user_ptr(args->buffers_ptr),
+			     sizeof(*exec_list) * args->buffer_count);
+	if (ret != 0) {
+		DRM_DEBUG("copy %d exec entries failed %d\n",
+			  args->buffer_count, ret);
+		drm_free_large(exec_list);
+		drm_free_large(exec2_list);
+		return -EFAULT;
+	}
+
+	for (i = 0; i < args->buffer_count; i++) {
+		exec2_list[i].handle = exec_list[i].handle;
+		exec2_list[i].relocation_count = exec_list[i].relocation_count;
+		exec2_list[i].relocs_ptr = exec_list[i].relocs_ptr;
+		exec2_list[i].alignment = exec_list[i].alignment;
+		exec2_list[i].offset = exec_list[i].offset;
+		if (INTEL_INFO(dev)->gen < 4)
+			exec2_list[i].flags = EXEC_OBJECT_NEEDS_FENCE;
+		else
+			exec2_list[i].flags = 0;
+	}
+
+	exec2.buffers_ptr = args->buffers_ptr;
+	exec2.buffer_count = args->buffer_count;
+	exec2.batch_start_offset = args->batch_start_offset;
+	exec2.batch_len = args->batch_len;
+	exec2.DR1 = args->DR1;
+	exec2.DR4 = args->DR4;
+	exec2.num_cliprects = args->num_cliprects;
+	exec2.cliprects_ptr = args->cliprects_ptr;
+	exec2.flags = I915_EXEC_RENDER;
+	i915_execbuffer2_set_context_id(exec2, 0);
+
+	ret = i915_gem_do_execbuffer(dev, data, file, &exec2, exec2_list);
+	if (!ret) {
+		struct drm_i915_gem_exec_object __user *user_exec_list =
+			to_user_ptr(args->buffers_ptr);
+
+		/* Copy the new buffer offsets back to the user's exec list. */
+		for (i = 0; i < args->buffer_count; i++) {
+			exec2_list[i].offset =
+				gen8_canonical_addr(exec2_list[i].offset);
+			ret = __copy_to_user(&user_exec_list[i].offset,
+					     &exec2_list[i].offset,
+					     sizeof(user_exec_list[i].offset));
+			if (ret) {
+				ret = -EFAULT;
+				DRM_DEBUG("failed to copy %d exec entries "
+					  "back to user (%d)\n",
+					  args->buffer_count, ret);
+				break;
+			}
+		}
+	}
+
+	drm_free_large(exec_list);
+	drm_free_large(exec2_list);
+	return ret;
+}
+
+int
+i915_gem_execbuffer2(struct drm_device *dev, void *data,
+		     struct drm_file *file)
+{
+	struct drm_i915_gem_execbuffer2 *args = data;
+	struct drm_i915_gem_exec_object2 *exec2_list = NULL;
+	int ret;
+
+	if (args->buffer_count < 1 ||
+	    args->buffer_count > UINT_MAX / sizeof(*exec2_list)) {
+		DRM_DEBUG("execbuf2 with %d buffers\n", args->buffer_count);
+		return -EINVAL;
+	}
+
+	if (args->rsvd2 != 0) {
+		DRM_DEBUG("dirty rvsd2 field\n");
+		return -EINVAL;
+	}
+
+	exec2_list = drm_malloc_gfp(args->buffer_count,
+				    sizeof(*exec2_list),
+				    GFP_TEMPORARY);
+	if (exec2_list == NULL) {
+		DRM_DEBUG("Failed to allocate exec list for %d buffers\n",
+			  args->buffer_count);
+		return -ENOMEM;
+	}
+	ret = copy_from_user(exec2_list,
+			     to_user_ptr(args->buffers_ptr),
+			     sizeof(*exec2_list) * args->buffer_count);
+	if (ret != 0) {
+		DRM_DEBUG("copy %d exec entries failed %d\n",
+			  args->buffer_count, ret);
+		drm_free_large(exec2_list);
+		return -EFAULT;
+	}
+
+	ret = i915_gem_do_execbuffer(dev, data, file, args, exec2_list);
+	if (!ret) {
+		/* Copy the new buffer offsets back to the user's exec list. */
+		struct drm_i915_gem_exec_object2 __user *user_exec_list =
+				   to_user_ptr(args->buffers_ptr);
+		int i;
+
+		for (i = 0; i < args->buffer_count; i++) {
+			exec2_list[i].offset =
+				gen8_canonical_addr(exec2_list[i].offset);
+			ret = __copy_to_user(&user_exec_list[i].offset,
+					     &exec2_list[i].offset,
+					     sizeof(user_exec_list[i].offset));
+			if (ret) {
+				ret = -EFAULT;
+				DRM_DEBUG("failed to copy %d exec entries "
+					  "back to user\n",
+					  args->buffer_count);
+				break;
+			}
+		}
+	}
+
+	drm_free_large(exec2_list);
+	return ret;
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/i915/i915_gem_fence.c
@@ -0,0 +1,800 @@
+/*
+ * Copyright © 2008-2015 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include <drm/drmP.h>
+#include <drm/i915_drm.h>
+#include "i915_drv.h"
+
+/**
+ * DOC: fence register handling
+ *
+ * Important to avoid confusions: "fences" in the i915 driver are not execution
+ * fences used to track command completion but hardware detiler objects which
+ * wrap a given range of the global GTT. Each platform has only a fairly limited
+ * set of these objects.
+ *
+ * Fences are used to detile GTT memory mappings. They're also connected to the
+ * hardware frontbuffer render tracking and hence interact with frontbuffer
+ * compression. Furthermore on older platforms fences are required for tiled
+ * objects used by the display engine. They can also be used by the render
+ * engine - they're required for blitter commands and are optional for render
+ * commands. But on gen4+ both display (with the exception of fbc) and rendering
+ * have their own tiling state bits and don't need fences.
+ *
+ * Also note that fences only support X and Y tiling and hence can't be used for
+ * the fancier new tiling formats like W, Ys and Yf.
+ *
+ * Finally note that because fences are such a restricted resource they're
+ * dynamically associated with objects. Furthermore fence state is committed to
+ * the hardware lazily to avoid unnecessary stalls on gen2/3. Therefore code must
+ * explicitly call i915_gem_object_get_fence() to synchronize fencing status
+ * for cpu access. Also note that some code wants an unfenced view, for those
+ * cases the fence can be removed forcefully with i915_gem_object_put_fence().
+ *
+ * Internally these functions will synchronize with userspace access by removing
+ * CPU ptes into GTT mmaps (not the GTT ptes themselves) as needed.
+ */
+
+static void i965_write_fence_reg(struct drm_device *dev, int reg,
+				 struct drm_i915_gem_object *obj)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	i915_reg_t fence_reg_lo, fence_reg_hi;
+	int fence_pitch_shift;
+
+	if (INTEL_INFO(dev)->gen >= 6) {
+		fence_reg_lo = FENCE_REG_GEN6_LO(reg);
+		fence_reg_hi = FENCE_REG_GEN6_HI(reg);
+		fence_pitch_shift = GEN6_FENCE_PITCH_SHIFT;
+	} else {
+		fence_reg_lo = FENCE_REG_965_LO(reg);
+		fence_reg_hi = FENCE_REG_965_HI(reg);
+		fence_pitch_shift = I965_FENCE_PITCH_SHIFT;
+	}
+
+	/* To w/a incoherency with non-atomic 64-bit register updates,
+	 * we split the 64-bit update into two 32-bit writes. In order
+	 * for a partial fence not to be evaluated between writes, we
+	 * precede the update with write to turn off the fence register,
+	 * and only enable the fence as the last step.
+	 *
+	 * For extra levels of paranoia, we make sure each step lands
+	 * before applying the next step.
+	 */
+	I915_WRITE(fence_reg_lo, 0);
+	POSTING_READ(fence_reg_lo);
+
+	if (obj) {
+		u32 size = i915_gem_obj_ggtt_size(obj);
+		uint64_t val;
+
+		/* Adjust fence size to match tiled area */
+		if (obj->tiling_mode != I915_TILING_NONE) {
+			uint32_t row_size = obj->stride *
+				(obj->tiling_mode == I915_TILING_Y ? 32 : 8);
+			size = (size / row_size) * row_size;
+		}
+
+		val = (uint64_t)((i915_gem_obj_ggtt_offset(obj) + size - 4096) &
+				 0xfffff000) << 32;
+		val |= i915_gem_obj_ggtt_offset(obj) & 0xfffff000;
+		val |= (uint64_t)((obj->stride / 128) - 1) << fence_pitch_shift;
+		if (obj->tiling_mode == I915_TILING_Y)
+			val |= 1 << I965_FENCE_TILING_Y_SHIFT;
+		val |= I965_FENCE_REG_VALID;
+
+		I915_WRITE(fence_reg_hi, val >> 32);
+		POSTING_READ(fence_reg_hi);
+
+		I915_WRITE(fence_reg_lo, val);
+		POSTING_READ(fence_reg_lo);
+	} else {
+		I915_WRITE(fence_reg_hi, 0);
+		POSTING_READ(fence_reg_hi);
+	}
+}
+
+static void i915_write_fence_reg(struct drm_device *dev, int reg,
+				 struct drm_i915_gem_object *obj)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	u32 val;
+
+	if (obj) {
+		u32 size = i915_gem_obj_ggtt_size(obj);
+		int pitch_val;
+		int tile_width;
+
+		WARN((i915_gem_obj_ggtt_offset(obj) & ~I915_FENCE_START_MASK) ||
+		     (size & -size) != size ||
+		     (i915_gem_obj_ggtt_offset(obj) & (size - 1)),
+		     "object 0x%08llx [fenceable? %d] not 1M or pot-size (0x%08x) aligned\n",
+		     i915_gem_obj_ggtt_offset(obj), obj->map_and_fenceable, size);
+
+		if (obj->tiling_mode == I915_TILING_Y && HAS_128_BYTE_Y_TILING(dev))
+			tile_width = 128;
+		else
+			tile_width = 512;
+
+		/* Note: pitch better be a power of two tile widths */
+		pitch_val = obj->stride / tile_width;
+		pitch_val = ffs(pitch_val) - 1;
+
+		val = i915_gem_obj_ggtt_offset(obj);
+		if (obj->tiling_mode == I915_TILING_Y)
+			val |= 1 << I830_FENCE_TILING_Y_SHIFT;
+		val |= I915_FENCE_SIZE_BITS(size);
+		val |= pitch_val << I830_FENCE_PITCH_SHIFT;
+		val |= I830_FENCE_REG_VALID;
+	} else
+		val = 0;
+
+	I915_WRITE(FENCE_REG(reg), val);
+	POSTING_READ(FENCE_REG(reg));
+}
+
+static void i830_write_fence_reg(struct drm_device *dev, int reg,
+				struct drm_i915_gem_object *obj)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	uint32_t val;
+
+	if (obj) {
+		u32 size = i915_gem_obj_ggtt_size(obj);
+		uint32_t pitch_val;
+
+		WARN((i915_gem_obj_ggtt_offset(obj) & ~I830_FENCE_START_MASK) ||
+		     (size & -size) != size ||
+		     (i915_gem_obj_ggtt_offset(obj) & (size - 1)),
+		     "object 0x%08llx not 512K or pot-size 0x%08x aligned\n",
+		     i915_gem_obj_ggtt_offset(obj), size);
+
+		pitch_val = obj->stride / 128;
+		pitch_val = ffs(pitch_val) - 1;
+
+		val = i915_gem_obj_ggtt_offset(obj);
+		if (obj->tiling_mode == I915_TILING_Y)
+			val |= 1 << I830_FENCE_TILING_Y_SHIFT;
+		val |= I830_FENCE_SIZE_BITS(size);
+		val |= pitch_val << I830_FENCE_PITCH_SHIFT;
+		val |= I830_FENCE_REG_VALID;
+	} else
+		val = 0;
+
+	I915_WRITE(FENCE_REG(reg), val);
+	POSTING_READ(FENCE_REG(reg));
+}
+
+inline static bool i915_gem_object_needs_mb(struct drm_i915_gem_object *obj)
+{
+	return obj && obj->base.read_domains & I915_GEM_DOMAIN_GTT;
+}
+
+static void i915_gem_write_fence(struct drm_device *dev, int reg,
+				 struct drm_i915_gem_object *obj)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	/* Ensure that all CPU reads are completed before installing a fence
+	 * and all writes before removing the fence.
+	 */
+	if (i915_gem_object_needs_mb(dev_priv->fence_regs[reg].obj))
+		mb();
+
+	WARN(obj && (!obj->stride || !obj->tiling_mode),
+	     "bogus fence setup with stride: 0x%x, tiling mode: %i\n",
+	     obj->stride, obj->tiling_mode);
+
+	if (IS_GEN2(dev))
+		i830_write_fence_reg(dev, reg, obj);
+	else if (IS_GEN3(dev))
+		i915_write_fence_reg(dev, reg, obj);
+	else if (INTEL_INFO(dev)->gen >= 4)
+		i965_write_fence_reg(dev, reg, obj);
+
+	/* And similarly be paranoid that no direct access to this region
+	 * is reordered to before the fence is installed.
+	 */
+	if (i915_gem_object_needs_mb(obj))
+		mb();
+}
+
+static inline int fence_number(struct drm_i915_private *dev_priv,
+			       struct drm_i915_fence_reg *fence)
+{
+	return fence - dev_priv->fence_regs;
+}
+
+static void i915_gem_object_update_fence(struct drm_i915_gem_object *obj,
+					 struct drm_i915_fence_reg *fence,
+					 bool enable)
+{
+	struct drm_i915_private *dev_priv = obj->base.dev->dev_private;
+	int reg = fence_number(dev_priv, fence);
+
+	i915_gem_write_fence(obj->base.dev, reg, enable ? obj : NULL);
+
+	if (enable) {
+		obj->fence_reg = reg;
+		fence->obj = obj;
+		list_move_tail(&fence->lru_list, &dev_priv->mm.fence_list);
+	} else {
+		obj->fence_reg = I915_FENCE_REG_NONE;
+		fence->obj = NULL;
+		list_del_init(&fence->lru_list);
+	}
+	obj->fence_dirty = false;
+}
+
+static inline void i915_gem_object_fence_lost(struct drm_i915_gem_object *obj)
+{
+	if (obj->tiling_mode)
+		i915_gem_release_mmap(obj);
+
+	/* As we do not have an associated fence register, we will force
+	 * a tiling change if we ever need to acquire one.
+	 */
+	obj->fence_dirty = false;
+	obj->fence_reg = I915_FENCE_REG_NONE;
+}
+
+static int
+i915_gem_object_wait_fence(struct drm_i915_gem_object *obj)
+{
+	if (obj->last_fenced_req) {
+		int ret = i915_wait_request(obj->last_fenced_req);
+		if (ret)
+			return ret;
+
+		i915_gem_request_assign(&obj->last_fenced_req, NULL);
+	}
+
+	return 0;
+}
+
+/**
+ * i915_gem_object_put_fence - force-remove fence for an object
+ * @obj: object to map through a fence reg
+ *
+ * This function force-removes any fence from the given object, which is useful
+ * if the kernel wants to do untiled GTT access.
+ *
+ * Returns:
+ *
+ * 0 on success, negative error code on failure.
+ */
+int
+i915_gem_object_put_fence(struct drm_i915_gem_object *obj)
+{
+	struct drm_i915_private *dev_priv = obj->base.dev->dev_private;
+	struct drm_i915_fence_reg *fence;
+	int ret;
+
+	ret = i915_gem_object_wait_fence(obj);
+	if (ret)
+		return ret;
+
+	if (obj->fence_reg == I915_FENCE_REG_NONE)
+		return 0;
+
+	fence = &dev_priv->fence_regs[obj->fence_reg];
+
+	if (WARN_ON(fence->pin_count))
+		return -EBUSY;
+
+	i915_gem_object_fence_lost(obj);
+	i915_gem_object_update_fence(obj, fence, false);
+
+	return 0;
+}
+
+static struct drm_i915_fence_reg *
+i915_find_fence_reg(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct drm_i915_fence_reg *reg, *avail;
+	int i;
+
+	/* First try to find a free reg */
+	avail = NULL;
+	for (i = 0; i < dev_priv->num_fence_regs; i++) {
+		reg = &dev_priv->fence_regs[i];
+		if (!reg->obj)
+			return reg;
+
+		if (!reg->pin_count)
+			avail = reg;
+	}
+
+	if (avail == NULL)
+		goto deadlock;
+
+	/* None available, try to steal one or wait for a user to finish */
+	list_for_each_entry(reg, &dev_priv->mm.fence_list, lru_list) {
+		if (reg->pin_count)
+			continue;
+
+		return reg;
+	}
+
+deadlock:
+	/* Wait for completion of pending flips which consume fences */
+	if (intel_has_pending_fb_unpin(dev))
+		return ERR_PTR(-EAGAIN);
+
+	return ERR_PTR(-EDEADLK);
+}
+
+/**
+ * i915_gem_object_get_fence - set up fencing for an object
+ * @obj: object to map through a fence reg
+ *
+ * When mapping objects through the GTT, userspace wants to be able to write
+ * to them without having to worry about swizzling if the object is tiled.
+ * This function walks the fence regs looking for a free one for @obj,
+ * stealing one if it can't find any.
+ *
+ * It then sets up the reg based on the object's properties: address, pitch
+ * and tiling format.
+ *
+ * For an untiled surface, this removes any existing fence.
+ *
+ * Returns:
+ *
+ * 0 on success, negative error code on failure.
+ */
+int
+i915_gem_object_get_fence(struct drm_i915_gem_object *obj)
+{
+	struct drm_device *dev = obj->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	bool enable = obj->tiling_mode != I915_TILING_NONE;
+	struct drm_i915_fence_reg *reg;
+	int ret;
+
+	/* Have we updated the tiling parameters upon the object and so
+	 * will need to serialise the write to the associated fence register?
+	 */
+	if (obj->fence_dirty) {
+		ret = i915_gem_object_wait_fence(obj);
+		if (ret)
+			return ret;
+	}
+
+	/* Just update our place in the LRU if our fence is getting reused. */
+	if (obj->fence_reg != I915_FENCE_REG_NONE) {
+		reg = &dev_priv->fence_regs[obj->fence_reg];
+		if (!obj->fence_dirty) {
+			list_move_tail(&reg->lru_list,
+				       &dev_priv->mm.fence_list);
+			return 0;
+		}
+	} else if (enable) {
+		if (WARN_ON(!obj->map_and_fenceable))
+			return -EINVAL;
+
+		reg = i915_find_fence_reg(dev);
+		if (IS_ERR(reg))
+			return PTR_ERR(reg);
+
+		if (reg->obj) {
+			struct drm_i915_gem_object *old = reg->obj;
+
+			ret = i915_gem_object_wait_fence(old);
+			if (ret)
+				return ret;
+
+			i915_gem_object_fence_lost(old);
+		}
+	} else
+		return 0;
+
+	i915_gem_object_update_fence(obj, reg, enable);
+
+	return 0;
+}
+
+/**
+ * i915_gem_object_pin_fence - pin fencing state
+ * @obj: object to pin fencing for
+ *
+ * This pins the fencing state (whether tiled or untiled) to make sure the
+ * object is ready to be used as a scanout target. Fencing status must be
+ * synchronize first by calling i915_gem_object_get_fence():
+ *
+ * The resulting fence pin reference must be released again with
+ * i915_gem_object_unpin_fence().
+ *
+ * Returns:
+ *
+ * True if the object has a fence, false otherwise.
+ */
+bool
+i915_gem_object_pin_fence(struct drm_i915_gem_object *obj)
+{
+	if (obj->fence_reg != I915_FENCE_REG_NONE) {
+		struct drm_i915_private *dev_priv = obj->base.dev->dev_private;
+		struct i915_vma *ggtt_vma = i915_gem_obj_to_ggtt(obj);
+
+		WARN_ON(!ggtt_vma ||
+			dev_priv->fence_regs[obj->fence_reg].pin_count >
+			ggtt_vma->pin_count);
+		dev_priv->fence_regs[obj->fence_reg].pin_count++;
+		return true;
+	} else
+		return false;
+}
+
+/**
+ * i915_gem_object_unpin_fence - unpin fencing state
+ * @obj: object to unpin fencing for
+ *
+ * This releases the fence pin reference acquired through
+ * i915_gem_object_pin_fence. It will handle both objects with and without an
+ * attached fence correctly, callers do not need to distinguish this.
+ */
+void
+i915_gem_object_unpin_fence(struct drm_i915_gem_object *obj)
+{
+	if (obj->fence_reg != I915_FENCE_REG_NONE) {
+		struct drm_i915_private *dev_priv = obj->base.dev->dev_private;
+		WARN_ON(dev_priv->fence_regs[obj->fence_reg].pin_count <= 0);
+		dev_priv->fence_regs[obj->fence_reg].pin_count--;
+	}
+}
+
+/**
+ * i915_gem_restore_fences - restore fence state
+ * @dev: DRM device
+ *
+ * Restore the hw fence state to match the software tracking again, to be called
+ * after a gpu reset and on resume.
+ */
+void i915_gem_restore_fences(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	int i;
+
+	for (i = 0; i < dev_priv->num_fence_regs; i++) {
+		struct drm_i915_fence_reg *reg = &dev_priv->fence_regs[i];
+
+		/*
+		 * Commit delayed tiling changes if we have an object still
+		 * attached to the fence, otherwise just clear the fence.
+		 */
+		if (reg->obj) {
+			i915_gem_object_update_fence(reg->obj, reg,
+						     reg->obj->tiling_mode);
+		} else {
+			i915_gem_write_fence(dev, i, NULL);
+		}
+	}
+}
+
+/**
+ * DOC: tiling swizzling details
+ *
+ * The idea behind tiling is to increase cache hit rates by rearranging
+ * pixel data so that a group of pixel accesses are in the same cacheline.
+ * Performance improvement from doing this on the back/depth buffer are on
+ * the order of 30%.
+ *
+ * Intel architectures make this somewhat more complicated, though, by
+ * adjustments made to addressing of data when the memory is in interleaved
+ * mode (matched pairs of DIMMS) to improve memory bandwidth.
+ * For interleaved memory, the CPU sends every sequential 64 bytes
+ * to an alternate memory channel so it can get the bandwidth from both.
+ *
+ * The GPU also rearranges its accesses for increased bandwidth to interleaved
+ * memory, and it matches what the CPU does for non-tiled.  However, when tiled
+ * it does it a little differently, since one walks addresses not just in the
+ * X direction but also Y.  So, along with alternating channels when bit
+ * 6 of the address flips, it also alternates when other bits flip --  Bits 9
+ * (every 512 bytes, an X tile scanline) and 10 (every two X tile scanlines)
+ * are common to both the 915 and 965-class hardware.
+ *
+ * The CPU also sometimes XORs in higher bits as well, to improve
+ * bandwidth doing strided access like we do so frequently in graphics.  This
+ * is called "Channel XOR Randomization" in the MCH documentation.  The result
+ * is that the CPU is XORing in either bit 11 or bit 17 to bit 6 of its address
+ * decode.
+ *
+ * All of this bit 6 XORing has an effect on our memory management,
+ * as we need to make sure that the 3d driver can correctly address object
+ * contents.
+ *
+ * If we don't have interleaved memory, all tiling is safe and no swizzling is
+ * required.
+ *
+ * When bit 17 is XORed in, we simply refuse to tile at all.  Bit
+ * 17 is not just a page offset, so as we page an object out and back in,
+ * individual pages in it will have different bit 17 addresses, resulting in
+ * each 64 bytes being swapped with its neighbor!
+ *
+ * Otherwise, if interleaved, we have to tell the 3d driver what the address
+ * swizzling it needs to do is, since it's writing with the CPU to the pages
+ * (bit 6 and potentially bit 11 XORed in), and the GPU is reading from the
+ * pages (bit 6, 9, and 10 XORed in), resulting in a cumulative bit swizzling
+ * required by the CPU of XORing in bit 6, 9, 10, and potentially 11, in order
+ * to match what the GPU expects.
+ */
+
+/**
+ * i915_gem_detect_bit_6_swizzle - detect bit 6 swizzling pattern
+ * @dev: DRM device
+ *
+ * Detects bit 6 swizzling of address lookup between IGD access and CPU
+ * access through main memory.
+ */
+void
+i915_gem_detect_bit_6_swizzle(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	uint32_t swizzle_x = I915_BIT_6_SWIZZLE_UNKNOWN;
+	uint32_t swizzle_y = I915_BIT_6_SWIZZLE_UNKNOWN;
+
+	if (INTEL_INFO(dev)->gen >= 8 || IS_VALLEYVIEW(dev)) {
+		/*
+		 * On BDW+, swizzling is not used. We leave the CPU memory
+		 * controller in charge of optimizing memory accesses without
+		 * the extra address manipulation GPU side.
+		 *
+		 * VLV and CHV don't have GPU swizzling.
+		 */
+		swizzle_x = I915_BIT_6_SWIZZLE_NONE;
+		swizzle_y = I915_BIT_6_SWIZZLE_NONE;
+	} else if (INTEL_INFO(dev)->gen >= 6) {
+		if (dev_priv->preserve_bios_swizzle) {
+			if (I915_READ(DISP_ARB_CTL) &
+			    DISP_TILE_SURFACE_SWIZZLING) {
+				swizzle_x = I915_BIT_6_SWIZZLE_9_10;
+				swizzle_y = I915_BIT_6_SWIZZLE_9;
+			} else {
+				swizzle_x = I915_BIT_6_SWIZZLE_NONE;
+				swizzle_y = I915_BIT_6_SWIZZLE_NONE;
+			}
+		} else {
+			uint32_t dimm_c0, dimm_c1;
+			dimm_c0 = I915_READ(MAD_DIMM_C0);
+			dimm_c1 = I915_READ(MAD_DIMM_C1);
+			dimm_c0 &= MAD_DIMM_A_SIZE_MASK | MAD_DIMM_B_SIZE_MASK;
+			dimm_c1 &= MAD_DIMM_A_SIZE_MASK | MAD_DIMM_B_SIZE_MASK;
+			/* Enable swizzling when the channels are populated
+			 * with identically sized dimms. We don't need to check
+			 * the 3rd channel because no cpu with gpu attached
+			 * ships in that configuration. Also, swizzling only
+			 * makes sense for 2 channels anyway. */
+			if (dimm_c0 == dimm_c1) {
+				swizzle_x = I915_BIT_6_SWIZZLE_9_10;
+				swizzle_y = I915_BIT_6_SWIZZLE_9;
+			} else {
+				swizzle_x = I915_BIT_6_SWIZZLE_NONE;
+				swizzle_y = I915_BIT_6_SWIZZLE_NONE;
+			}
+		}
+	} else if (IS_GEN5(dev)) {
+		/* On Ironlake whatever DRAM config, GPU always do
+		 * same swizzling setup.
+		 */
+		swizzle_x = I915_BIT_6_SWIZZLE_9_10;
+		swizzle_y = I915_BIT_6_SWIZZLE_9;
+	} else if (IS_GEN2(dev)) {
+		/* As far as we know, the 865 doesn't have these bit 6
+		 * swizzling issues.
+		 */
+		swizzle_x = I915_BIT_6_SWIZZLE_NONE;
+		swizzle_y = I915_BIT_6_SWIZZLE_NONE;
+	} else if (IS_MOBILE(dev) || (IS_GEN3(dev) && !IS_G33(dev))) {
+		uint32_t dcc;
+
+		/* On 9xx chipsets, channel interleave by the CPU is
+		 * determined by DCC.  For single-channel, neither the CPU
+		 * nor the GPU do swizzling.  For dual channel interleaved,
+		 * the GPU's interleave is bit 9 and 10 for X tiled, and bit
+		 * 9 for Y tiled.  The CPU's interleave is independent, and
+		 * can be based on either bit 11 (haven't seen this yet) or
+		 * bit 17 (common).
+		 */
+		dcc = I915_READ(DCC);
+		switch (dcc & DCC_ADDRESSING_MODE_MASK) {
+		case DCC_ADDRESSING_MODE_SINGLE_CHANNEL:
+		case DCC_ADDRESSING_MODE_DUAL_CHANNEL_ASYMMETRIC:
+			swizzle_x = I915_BIT_6_SWIZZLE_NONE;
+			swizzle_y = I915_BIT_6_SWIZZLE_NONE;
+			break;
+		case DCC_ADDRESSING_MODE_DUAL_CHANNEL_INTERLEAVED:
+			if (dcc & DCC_CHANNEL_XOR_DISABLE) {
+				/* This is the base swizzling by the GPU for
+				 * tiled buffers.
+				 */
+				swizzle_x = I915_BIT_6_SWIZZLE_9_10;
+				swizzle_y = I915_BIT_6_SWIZZLE_9;
+			} else if ((dcc & DCC_CHANNEL_XOR_BIT_17) == 0) {
+				/* Bit 11 swizzling by the CPU in addition. */
+				swizzle_x = I915_BIT_6_SWIZZLE_9_10_11;
+				swizzle_y = I915_BIT_6_SWIZZLE_9_11;
+			} else {
+				/* Bit 17 swizzling by the CPU in addition. */
+				swizzle_x = I915_BIT_6_SWIZZLE_9_10_17;
+				swizzle_y = I915_BIT_6_SWIZZLE_9_17;
+			}
+			break;
+		}
+
+		/* check for L-shaped memory aka modified enhanced addressing */
+		if (IS_GEN4(dev) &&
+		    !(I915_READ(DCC2) & DCC2_MODIFIED_ENHANCED_DISABLE)) {
+			swizzle_x = I915_BIT_6_SWIZZLE_UNKNOWN;
+			swizzle_y = I915_BIT_6_SWIZZLE_UNKNOWN;
+		}
+
+		if (dcc == 0xffffffff) {
+			DRM_ERROR("Couldn't read from MCHBAR.  "
+				  "Disabling tiling.\n");
+			swizzle_x = I915_BIT_6_SWIZZLE_UNKNOWN;
+			swizzle_y = I915_BIT_6_SWIZZLE_UNKNOWN;
+		}
+	} else {
+		/* The 965, G33, and newer, have a very flexible memory
+		 * configuration.  It will enable dual-channel mode
+		 * (interleaving) on as much memory as it can, and the GPU
+		 * will additionally sometimes enable different bit 6
+		 * swizzling for tiled objects from the CPU.
+		 *
+		 * Here's what I found on the G965:
+		 *    slot fill         memory size  swizzling
+		 * 0A   0B   1A   1B    1-ch   2-ch
+		 * 512  0    0    0     512    0     O
+		 * 512  0    512  0     16     1008  X
+		 * 512  0    0    512   16     1008  X
+		 * 0    512  0    512   16     1008  X
+		 * 1024 1024 1024 0     2048   1024  O
+		 *
+		 * We could probably detect this based on either the DRB
+		 * matching, which was the case for the swizzling required in
+		 * the table above, or from the 1-ch value being less than
+		 * the minimum size of a rank.
+		 *
+		 * Reports indicate that the swizzling actually
+		 * varies depending upon page placement inside the
+		 * channels, i.e. we see swizzled pages where the
+		 * banks of memory are paired and unswizzled on the
+		 * uneven portion, so leave that as unknown.
+		 */
+		if (I915_READ16(C0DRB3) == I915_READ16(C1DRB3)) {
+			swizzle_x = I915_BIT_6_SWIZZLE_9_10;
+			swizzle_y = I915_BIT_6_SWIZZLE_9;
+		}
+	}
+
+	if (swizzle_x == I915_BIT_6_SWIZZLE_UNKNOWN ||
+	    swizzle_y == I915_BIT_6_SWIZZLE_UNKNOWN) {
+		/* Userspace likes to explode if it sees unknown swizzling,
+		 * so lie. We will finish the lie when reporting through
+		 * the get-tiling-ioctl by reporting the physical swizzle
+		 * mode as unknown instead.
+		 *
+		 * As we don't strictly know what the swizzling is, it may be
+		 * bit17 dependent, and so we need to also prevent the pages
+		 * from being moved.
+		 */
+		dev_priv->quirks |= QUIRK_PIN_SWIZZLED_PAGES;
+		swizzle_x = I915_BIT_6_SWIZZLE_NONE;
+		swizzle_y = I915_BIT_6_SWIZZLE_NONE;
+	}
+
+	dev_priv->mm.bit_6_swizzle_x = swizzle_x;
+	dev_priv->mm.bit_6_swizzle_y = swizzle_y;
+}
+
+/*
+ * Swap every 64 bytes of this page around, to account for it having a new
+ * bit 17 of its physical address and therefore being interpreted differently
+ * by the GPU.
+ */
+static void
+i915_gem_swizzle_page(struct page *page)
+{
+	char temp[64];
+	char *vaddr;
+	int i;
+
+	vaddr = kmap(page);
+
+	for (i = 0; i < PAGE_SIZE; i += 128) {
+		memcpy(temp, &vaddr[i], 64);
+		memcpy(&vaddr[i], &vaddr[i + 64], 64);
+		memcpy(&vaddr[i + 64], temp, 64);
+	}
+
+	kunmap(page);
+}
+
+/**
+ * i915_gem_object_do_bit_17_swizzle - fixup bit 17 swizzling
+ * @obj: i915 GEM buffer object
+ *
+ * This function fixes up the swizzling in case any page frame number for this
+ * object has changed in bit 17 since that state has been saved with
+ * i915_gem_object_save_bit_17_swizzle().
+ *
+ * This is called when pinning backing storage again, since the kernel is free
+ * to move unpinned backing storage around (either by directly moving pages or
+ * by swapping them out and back in again).
+ */
+void
+i915_gem_object_do_bit_17_swizzle(struct drm_i915_gem_object *obj)
+{
+	struct sg_page_iter sg_iter;
+	int i;
+
+	if (obj->bit_17 == NULL)
+		return;
+
+	i = 0;
+	for_each_sg_page(obj->pages->sgl, &sg_iter, obj->pages->nents, 0) {
+		struct page *page = sg_page_iter_page(&sg_iter);
+		char new_bit_17 = page_to_phys(page) >> 17;
+		if ((new_bit_17 & 0x1) !=
+		    (test_bit(i, obj->bit_17) != 0)) {
+			i915_gem_swizzle_page(page);
+			set_page_dirty(page);
+		}
+		i++;
+	}
+}
+
+/**
+ * i915_gem_object_save_bit_17_swizzle - save bit 17 swizzling
+ * @obj: i915 GEM buffer object
+ *
+ * This function saves the bit 17 of each page frame number so that swizzling
+ * can be fixed up later on with i915_gem_object_do_bit_17_swizzle(). This must
+ * be called before the backing storage can be unpinned.
+ */
+void
+i915_gem_object_save_bit_17_swizzle(struct drm_i915_gem_object *obj)
+{
+	struct sg_page_iter sg_iter;
+	int page_count = obj->base.size >> PAGE_SHIFT;
+	int i;
+
+	if (obj->bit_17 == NULL) {
+		obj->bit_17 = kcalloc(BITS_TO_LONGS(page_count),
+				      sizeof(long), GFP_KERNEL);
+		if (obj->bit_17 == NULL) {
+			DRM_ERROR("Failed to allocate memory for bit 17 "
+				  "record\n");
+			return;
+		}
+	}
+
+	i = 0;
+	for_each_sg_page(obj->pages->sgl, &sg_iter, obj->pages->nents, 0) {
+		if (page_to_phys(sg_page_iter_page(&sg_iter)) & (1 << 17))
+			__set_bit(i, obj->bit_17);
+		else
+			__clear_bit(i, obj->bit_17);
+		i++;
+	}
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/i915/i915_gem_gtt.c
@@ -0,0 +1,3636 @@
+/*
+ * Copyright © 2010 Daniel Vetter
+ * Copyright © 2011-2014 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ */
+
+#include <linux/seq_file.h>
+#include <linux/stop_machine.h>
+#include <drm/drmP.h>
+#include <drm/i915_drm.h>
+#include "i915_drv.h"
+#include "i915_vgpu.h"
+#include "i915_trace.h"
+#include "intel_drv.h"
+
+/**
+ * DOC: Global GTT views
+ *
+ * Background and previous state
+ *
+ * Historically objects could exists (be bound) in global GTT space only as
+ * singular instances with a view representing all of the object's backing pages
+ * in a linear fashion. This view will be called a normal view.
+ *
+ * To support multiple views of the same object, where the number of mapped
+ * pages is not equal to the backing store, or where the layout of the pages
+ * is not linear, concept of a GGTT view was added.
+ *
+ * One example of an alternative view is a stereo display driven by a single
+ * image. In this case we would have a framebuffer looking like this
+ * (2x2 pages):
+ *
+ *    12
+ *    34
+ *
+ * Above would represent a normal GGTT view as normally mapped for GPU or CPU
+ * rendering. In contrast, fed to the display engine would be an alternative
+ * view which could look something like this:
+ *
+ *   1212
+ *   3434
+ *
+ * In this example both the size and layout of pages in the alternative view is
+ * different from the normal view.
+ *
+ * Implementation and usage
+ *
+ * GGTT views are implemented using VMAs and are distinguished via enum
+ * i915_ggtt_view_type and struct i915_ggtt_view.
+ *
+ * A new flavour of core GEM functions which work with GGTT bound objects were
+ * added with the _ggtt_ infix, and sometimes with _view postfix to avoid
+ * renaming  in large amounts of code. They take the struct i915_ggtt_view
+ * parameter encapsulating all metadata required to implement a view.
+ *
+ * As a helper for callers which are only interested in the normal view,
+ * globally const i915_ggtt_view_normal singleton instance exists. All old core
+ * GEM API functions, the ones not taking the view parameter, are operating on,
+ * or with the normal GGTT view.
+ *
+ * Code wanting to add or use a new GGTT view needs to:
+ *
+ * 1. Add a new enum with a suitable name.
+ * 2. Extend the metadata in the i915_ggtt_view structure if required.
+ * 3. Add support to i915_get_vma_pages().
+ *
+ * New views are required to build a scatter-gather table from within the
+ * i915_get_vma_pages function. This table is stored in the vma.ggtt_view and
+ * exists for the lifetime of an VMA.
+ *
+ * Core API is designed to have copy semantics which means that passed in
+ * struct i915_ggtt_view does not need to be persistent (left around after
+ * calling the core API functions).
+ *
+ */
+
+static int
+i915_get_ggtt_vma_pages(struct i915_vma *vma);
+
+const struct i915_ggtt_view i915_ggtt_view_normal = {
+	.type = I915_GGTT_VIEW_NORMAL,
+};
+const struct i915_ggtt_view i915_ggtt_view_rotated = {
+	.type = I915_GGTT_VIEW_ROTATED,
+};
+
+static int sanitize_enable_ppgtt(struct drm_device *dev, int enable_ppgtt)
+{
+	bool has_aliasing_ppgtt;
+	bool has_full_ppgtt;
+	bool has_full_48bit_ppgtt;
+
+	has_aliasing_ppgtt = INTEL_INFO(dev)->gen >= 6;
+	has_full_ppgtt = INTEL_INFO(dev)->gen >= 7;
+	has_full_48bit_ppgtt = IS_BROADWELL(dev) || INTEL_INFO(dev)->gen >= 9;
+
+	if (intel_vgpu_active(dev))
+		has_full_ppgtt = false; /* emulation is too hard */
+
+	/*
+	 * We don't allow disabling PPGTT for gen9+ as it's a requirement for
+	 * execlists, the sole mechanism available to submit work.
+	 */
+	if (INTEL_INFO(dev)->gen < 9 &&
+	    (enable_ppgtt == 0 || !has_aliasing_ppgtt))
+		return 0;
+
+	if (enable_ppgtt == 1)
+		return 1;
+
+	if (enable_ppgtt == 2 && has_full_ppgtt)
+		return 2;
+
+	if (enable_ppgtt == 3 && has_full_48bit_ppgtt)
+		return 3;
+
+#ifdef CONFIG_INTEL_IOMMU
+	/* Disable ppgtt on SNB if VT-d is on. */
+	if (INTEL_INFO(dev)->gen == 6 && intel_iommu_gfx_mapped) {
+		DRM_INFO("Disabling PPGTT because VT-d is on\n");
+		return 0;
+	}
+#endif
+
+	/* Early VLV doesn't have this */
+	if (IS_VALLEYVIEW(dev) && dev->pdev->revision < 0xb) {
+		DRM_DEBUG_DRIVER("disabling PPGTT on pre-B3 step VLV\n");
+		return 0;
+	}
+
+	if (INTEL_INFO(dev)->gen >= 8 && i915.enable_execlists)
+		return has_full_48bit_ppgtt ? 3 : 2;
+	else
+		return has_aliasing_ppgtt ? 1 : 0;
+}
+
+static int ppgtt_bind_vma(struct i915_vma *vma,
+			  enum i915_cache_level cache_level,
+			  u32 unused)
+{
+	u32 pte_flags = 0;
+
+	/* Currently applicable only to VLV */
+	if (vma->obj->gt_ro)
+		pte_flags |= PTE_READ_ONLY;
+
+	vma->vm->insert_entries(vma->vm, vma->obj->pages, vma->node.start,
+				cache_level, pte_flags);
+
+	return 0;
+}
+
+static void ppgtt_unbind_vma(struct i915_vma *vma)
+{
+	vma->vm->clear_range(vma->vm,
+			     vma->node.start,
+			     vma->obj->base.size,
+			     true);
+}
+
+static gen8_pte_t gen8_pte_encode(dma_addr_t addr,
+				  enum i915_cache_level level,
+				  bool valid)
+{
+	gen8_pte_t pte = valid ? _PAGE_PRESENT | _PAGE_RW : 0;
+	pte |= addr;
+
+	switch (level) {
+	case I915_CACHE_NONE:
+		pte |= PPAT_UNCACHED_INDEX;
+		break;
+	case I915_CACHE_WT:
+		pte |= PPAT_DISPLAY_ELLC_INDEX;
+		break;
+	default:
+		pte |= PPAT_CACHED_INDEX;
+		break;
+	}
+
+	return pte;
+}
+
+static gen8_pde_t gen8_pde_encode(const dma_addr_t addr,
+				  const enum i915_cache_level level)
+{
+	gen8_pde_t pde = _PAGE_PRESENT | _PAGE_RW;
+	pde |= addr;
+	if (level != I915_CACHE_NONE)
+		pde |= PPAT_CACHED_PDE_INDEX;
+	else
+		pde |= PPAT_UNCACHED_INDEX;
+	return pde;
+}
+
+#define gen8_pdpe_encode gen8_pde_encode
+#define gen8_pml4e_encode gen8_pde_encode
+
+static gen6_pte_t snb_pte_encode(dma_addr_t addr,
+				 enum i915_cache_level level,
+				 bool valid, u32 unused)
+{
+	gen6_pte_t pte = valid ? GEN6_PTE_VALID : 0;
+	pte |= GEN6_PTE_ADDR_ENCODE(addr);
+
+	switch (level) {
+	case I915_CACHE_L3_LLC:
+	case I915_CACHE_LLC:
+		pte |= GEN6_PTE_CACHE_LLC;
+		break;
+	case I915_CACHE_NONE:
+		pte |= GEN6_PTE_UNCACHED;
+		break;
+	default:
+		MISSING_CASE(level);
+	}
+
+	return pte;
+}
+
+static gen6_pte_t ivb_pte_encode(dma_addr_t addr,
+				 enum i915_cache_level level,
+				 bool valid, u32 unused)
+{
+	gen6_pte_t pte = valid ? GEN6_PTE_VALID : 0;
+	pte |= GEN6_PTE_ADDR_ENCODE(addr);
+
+	switch (level) {
+	case I915_CACHE_L3_LLC:
+		pte |= GEN7_PTE_CACHE_L3_LLC;
+		break;
+	case I915_CACHE_LLC:
+		pte |= GEN6_PTE_CACHE_LLC;
+		break;
+	case I915_CACHE_NONE:
+		pte |= GEN6_PTE_UNCACHED;
+		break;
+	default:
+		MISSING_CASE(level);
+	}
+
+	return pte;
+}
+
+static gen6_pte_t byt_pte_encode(dma_addr_t addr,
+				 enum i915_cache_level level,
+				 bool valid, u32 flags)
+{
+	gen6_pte_t pte = valid ? GEN6_PTE_VALID : 0;
+	pte |= GEN6_PTE_ADDR_ENCODE(addr);
+
+	if (!(flags & PTE_READ_ONLY))
+		pte |= BYT_PTE_WRITEABLE;
+
+	if (level != I915_CACHE_NONE)
+		pte |= BYT_PTE_SNOOPED_BY_CPU_CACHES;
+
+	return pte;
+}
+
+static gen6_pte_t hsw_pte_encode(dma_addr_t addr,
+				 enum i915_cache_level level,
+				 bool valid, u32 unused)
+{
+	gen6_pte_t pte = valid ? GEN6_PTE_VALID : 0;
+	pte |= HSW_PTE_ADDR_ENCODE(addr);
+
+	if (level != I915_CACHE_NONE)
+		pte |= HSW_WB_LLC_AGE3;
+
+	return pte;
+}
+
+static gen6_pte_t iris_pte_encode(dma_addr_t addr,
+				  enum i915_cache_level level,
+				  bool valid, u32 unused)
+{
+	gen6_pte_t pte = valid ? GEN6_PTE_VALID : 0;
+	pte |= HSW_PTE_ADDR_ENCODE(addr);
+
+	switch (level) {
+	case I915_CACHE_NONE:
+		break;
+	case I915_CACHE_WT:
+		pte |= HSW_WT_ELLC_LLC_AGE3;
+		break;
+	default:
+		pte |= HSW_WB_ELLC_LLC_AGE3;
+		break;
+	}
+
+	return pte;
+}
+
+static int __setup_page_dma(struct drm_device *dev,
+			    struct i915_page_dma *p, gfp_t flags)
+{
+	struct device *device = &dev->pdev->dev;
+
+	p->page = alloc_page(flags);
+	if (!p->page)
+		return -ENOMEM;
+
+	p->daddr = dma_map_page(device,
+				p->page, 0, 4096, PCI_DMA_BIDIRECTIONAL);
+
+	if (dma_mapping_error(device, p->daddr)) {
+		__free_page(p->page);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int setup_page_dma(struct drm_device *dev, struct i915_page_dma *p)
+{
+	return __setup_page_dma(dev, p, GFP_KERNEL);
+}
+
+static void cleanup_page_dma(struct drm_device *dev, struct i915_page_dma *p)
+{
+	if (WARN_ON(!p->page))
+		return;
+
+	dma_unmap_page(&dev->pdev->dev, p->daddr, 4096, PCI_DMA_BIDIRECTIONAL);
+	__free_page(p->page);
+	memset(p, 0, sizeof(*p));
+}
+
+static void *kmap_page_dma(struct i915_page_dma *p)
+{
+	return kmap_atomic(p->page);
+}
+
+/* We use the flushing unmap only with ppgtt structures:
+ * page directories, page tables and scratch pages.
+ */
+static void kunmap_page_dma(struct drm_device *dev, void *vaddr)
+{
+	/* There are only few exceptions for gen >=6. chv and bxt.
+	 * And we are not sure about the latter so play safe for now.
+	 */
+	if (IS_CHERRYVIEW(dev) || IS_BROXTON(dev))
+		drm_clflush_virt_range(vaddr, PAGE_SIZE);
+
+	kunmap_atomic(vaddr);
+}
+
+#define kmap_px(px) kmap_page_dma(px_base(px))
+#define kunmap_px(ppgtt, vaddr) kunmap_page_dma((ppgtt)->base.dev, (vaddr))
+
+#define setup_px(dev, px) setup_page_dma((dev), px_base(px))
+#define cleanup_px(dev, px) cleanup_page_dma((dev), px_base(px))
+#define fill_px(dev, px, v) fill_page_dma((dev), px_base(px), (v))
+#define fill32_px(dev, px, v) fill_page_dma_32((dev), px_base(px), (v))
+
+static void fill_page_dma(struct drm_device *dev, struct i915_page_dma *p,
+			  const uint64_t val)
+{
+	int i;
+	uint64_t * const vaddr = kmap_page_dma(p);
+
+	for (i = 0; i < 512; i++)
+		vaddr[i] = val;
+
+	kunmap_page_dma(dev, vaddr);
+}
+
+static void fill_page_dma_32(struct drm_device *dev, struct i915_page_dma *p,
+			     const uint32_t val32)
+{
+	uint64_t v = val32;
+
+	v = v << 32 | val32;
+
+	fill_page_dma(dev, p, v);
+}
+
+static struct i915_page_scratch *alloc_scratch_page(struct drm_device *dev)
+{
+	struct i915_page_scratch *sp;
+	int ret;
+
+	sp = kzalloc(sizeof(*sp), GFP_KERNEL);
+	if (sp == NULL)
+		return ERR_PTR(-ENOMEM);
+
+	ret = __setup_page_dma(dev, px_base(sp), GFP_DMA32 | __GFP_ZERO);
+	if (ret) {
+		kfree(sp);
+		return ERR_PTR(ret);
+	}
+
+	set_pages_uc(px_page(sp), 1);
+
+	return sp;
+}
+
+static void free_scratch_page(struct drm_device *dev,
+			      struct i915_page_scratch *sp)
+{
+	set_pages_wb(px_page(sp), 1);
+
+	cleanup_px(dev, sp);
+	kfree(sp);
+}
+
+static struct i915_page_table *alloc_pt(struct drm_device *dev)
+{
+	struct i915_page_table *pt;
+	const size_t count = INTEL_INFO(dev)->gen >= 8 ?
+		GEN8_PTES : GEN6_PTES;
+	int ret = -ENOMEM;
+
+	pt = kzalloc(sizeof(*pt), GFP_KERNEL);
+	if (!pt)
+		return ERR_PTR(-ENOMEM);
+
+	pt->used_ptes = kcalloc(BITS_TO_LONGS(count), sizeof(*pt->used_ptes),
+				GFP_KERNEL);
+
+	if (!pt->used_ptes)
+		goto fail_bitmap;
+
+	ret = setup_px(dev, pt);
+	if (ret)
+		goto fail_page_m;
+
+	return pt;
+
+fail_page_m:
+	kfree(pt->used_ptes);
+fail_bitmap:
+	kfree(pt);
+
+	return ERR_PTR(ret);
+}
+
+static void free_pt(struct drm_device *dev, struct i915_page_table *pt)
+{
+	cleanup_px(dev, pt);
+	kfree(pt->used_ptes);
+	kfree(pt);
+}
+
+static void gen8_initialize_pt(struct i915_address_space *vm,
+			       struct i915_page_table *pt)
+{
+	gen8_pte_t scratch_pte;
+
+	scratch_pte = gen8_pte_encode(px_dma(vm->scratch_page),
+				      I915_CACHE_LLC, true);
+
+	fill_px(vm->dev, pt, scratch_pte);
+}
+
+static void gen6_initialize_pt(struct i915_address_space *vm,
+			       struct i915_page_table *pt)
+{
+	gen6_pte_t scratch_pte;
+
+	WARN_ON(px_dma(vm->scratch_page) == 0);
+
+	scratch_pte = vm->pte_encode(px_dma(vm->scratch_page),
+				     I915_CACHE_LLC, true, 0);
+
+	fill32_px(vm->dev, pt, scratch_pte);
+}
+
+static struct i915_page_directory *alloc_pd(struct drm_device *dev)
+{
+	struct i915_page_directory *pd;
+	int ret = -ENOMEM;
+
+	pd = kzalloc(sizeof(*pd), GFP_KERNEL);
+	if (!pd)
+		return ERR_PTR(-ENOMEM);
+
+	pd->used_pdes = kcalloc(BITS_TO_LONGS(I915_PDES),
+				sizeof(*pd->used_pdes), GFP_KERNEL);
+	if (!pd->used_pdes)
+		goto fail_bitmap;
+
+	ret = setup_px(dev, pd);
+	if (ret)
+		goto fail_page_m;
+
+	return pd;
+
+fail_page_m:
+	kfree(pd->used_pdes);
+fail_bitmap:
+	kfree(pd);
+
+	return ERR_PTR(ret);
+}
+
+static void free_pd(struct drm_device *dev, struct i915_page_directory *pd)
+{
+	if (px_page(pd)) {
+		cleanup_px(dev, pd);
+		kfree(pd->used_pdes);
+		kfree(pd);
+	}
+}
+
+static void gen8_initialize_pd(struct i915_address_space *vm,
+			       struct i915_page_directory *pd)
+{
+	gen8_pde_t scratch_pde;
+
+	scratch_pde = gen8_pde_encode(px_dma(vm->scratch_pt), I915_CACHE_LLC);
+
+	fill_px(vm->dev, pd, scratch_pde);
+}
+
+static int __pdp_init(struct drm_device *dev,
+		      struct i915_page_directory_pointer *pdp)
+{
+	size_t pdpes = I915_PDPES_PER_PDP(dev);
+
+	pdp->used_pdpes = kcalloc(BITS_TO_LONGS(pdpes),
+				  sizeof(unsigned long),
+				  GFP_KERNEL);
+	if (!pdp->used_pdpes)
+		return -ENOMEM;
+
+	pdp->page_directory = kcalloc(pdpes, sizeof(*pdp->page_directory),
+				      GFP_KERNEL);
+	if (!pdp->page_directory) {
+		kfree(pdp->used_pdpes);
+		/* the PDP might be the statically allocated top level. Keep it
+		 * as clean as possible */
+		pdp->used_pdpes = NULL;
+		return -ENOMEM;
+	}
+
+	return 0;
+}
+
+static void __pdp_fini(struct i915_page_directory_pointer *pdp)
+{
+	kfree(pdp->used_pdpes);
+	kfree(pdp->page_directory);
+	pdp->page_directory = NULL;
+}
+
+static struct
+i915_page_directory_pointer *alloc_pdp(struct drm_device *dev)
+{
+	struct i915_page_directory_pointer *pdp;
+	int ret = -ENOMEM;
+
+	WARN_ON(!USES_FULL_48BIT_PPGTT(dev));
+
+	pdp = kzalloc(sizeof(*pdp), GFP_KERNEL);
+	if (!pdp)
+		return ERR_PTR(-ENOMEM);
+
+	ret = __pdp_init(dev, pdp);
+	if (ret)
+		goto fail_bitmap;
+
+	ret = setup_px(dev, pdp);
+	if (ret)
+		goto fail_page_m;
+
+	return pdp;
+
+fail_page_m:
+	__pdp_fini(pdp);
+fail_bitmap:
+	kfree(pdp);
+
+	return ERR_PTR(ret);
+}
+
+static void free_pdp(struct drm_device *dev,
+		     struct i915_page_directory_pointer *pdp)
+{
+	__pdp_fini(pdp);
+	if (USES_FULL_48BIT_PPGTT(dev)) {
+		cleanup_px(dev, pdp);
+		kfree(pdp);
+	}
+}
+
+static void gen8_initialize_pdp(struct i915_address_space *vm,
+				struct i915_page_directory_pointer *pdp)
+{
+	gen8_ppgtt_pdpe_t scratch_pdpe;
+
+	scratch_pdpe = gen8_pdpe_encode(px_dma(vm->scratch_pd), I915_CACHE_LLC);
+
+	fill_px(vm->dev, pdp, scratch_pdpe);
+}
+
+static void gen8_initialize_pml4(struct i915_address_space *vm,
+				 struct i915_pml4 *pml4)
+{
+	gen8_ppgtt_pml4e_t scratch_pml4e;
+
+	scratch_pml4e = gen8_pml4e_encode(px_dma(vm->scratch_pdp),
+					  I915_CACHE_LLC);
+
+	fill_px(vm->dev, pml4, scratch_pml4e);
+}
+
+static void
+gen8_setup_page_directory(struct i915_hw_ppgtt *ppgtt,
+			  struct i915_page_directory_pointer *pdp,
+			  struct i915_page_directory *pd,
+			  int index)
+{
+	gen8_ppgtt_pdpe_t *page_directorypo;
+
+	if (!USES_FULL_48BIT_PPGTT(ppgtt->base.dev))
+		return;
+
+	page_directorypo = kmap_px(pdp);
+	page_directorypo[index] = gen8_pdpe_encode(px_dma(pd), I915_CACHE_LLC);
+	kunmap_px(ppgtt, page_directorypo);
+}
+
+static void
+gen8_setup_page_directory_pointer(struct i915_hw_ppgtt *ppgtt,
+				  struct i915_pml4 *pml4,
+				  struct i915_page_directory_pointer *pdp,
+				  int index)
+{
+	gen8_ppgtt_pml4e_t *pagemap = kmap_px(pml4);
+
+	WARN_ON(!USES_FULL_48BIT_PPGTT(ppgtt->base.dev));
+	pagemap[index] = gen8_pml4e_encode(px_dma(pdp), I915_CACHE_LLC);
+	kunmap_px(ppgtt, pagemap);
+}
+
+/* Broadwell Page Directory Pointer Descriptors */
+static int gen8_write_pdp(struct drm_i915_gem_request *req,
+			  unsigned entry,
+			  dma_addr_t addr)
+{
+	struct intel_engine_cs *engine = req->engine;
+	int ret;
+
+	BUG_ON(entry >= 4);
+
+	ret = intel_ring_begin(req, 6);
+	if (ret)
+		return ret;
+
+	intel_ring_emit(engine, MI_LOAD_REGISTER_IMM(1));
+	intel_ring_emit_reg(engine, GEN8_RING_PDP_UDW(engine, entry));
+	intel_ring_emit(engine, upper_32_bits(addr));
+	intel_ring_emit(engine, MI_LOAD_REGISTER_IMM(1));
+	intel_ring_emit_reg(engine, GEN8_RING_PDP_LDW(engine, entry));
+	intel_ring_emit(engine, lower_32_bits(addr));
+	intel_ring_advance(engine);
+
+	return 0;
+}
+
+static int gen8_legacy_mm_switch(struct i915_hw_ppgtt *ppgtt,
+				 struct drm_i915_gem_request *req)
+{
+	int i, ret;
+
+	for (i = GEN8_LEGACY_PDPES - 1; i >= 0; i--) {
+		const dma_addr_t pd_daddr = i915_page_dir_dma_addr(ppgtt, i);
+
+		ret = gen8_write_pdp(req, i, pd_daddr);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
+static int gen8_48b_mm_switch(struct i915_hw_ppgtt *ppgtt,
+			      struct drm_i915_gem_request *req)
+{
+	return gen8_write_pdp(req, 0, px_dma(&ppgtt->pml4));
+}
+
+static void gen8_ppgtt_clear_pte_range(struct i915_address_space *vm,
+				       struct i915_page_directory_pointer *pdp,
+				       uint64_t start,
+				       uint64_t length,
+				       gen8_pte_t scratch_pte)
+{
+	struct i915_hw_ppgtt *ppgtt = i915_vm_to_ppgtt(vm);
+	gen8_pte_t *pt_vaddr;
+	unsigned pdpe = gen8_pdpe_index(start);
+	unsigned pde = gen8_pde_index(start);
+	unsigned pte = gen8_pte_index(start);
+	unsigned num_entries = length >> PAGE_SHIFT;
+	unsigned last_pte, i;
+
+	if (WARN_ON(!pdp))
+		return;
+
+	while (num_entries) {
+		struct i915_page_directory *pd;
+		struct i915_page_table *pt;
+
+		if (WARN_ON(!pdp->page_directory[pdpe]))
+			break;
+
+		pd = pdp->page_directory[pdpe];
+
+		if (WARN_ON(!pd->page_table[pde]))
+			break;
+
+		pt = pd->page_table[pde];
+
+		if (WARN_ON(!px_page(pt)))
+			break;
+
+		last_pte = pte + num_entries;
+		if (last_pte > GEN8_PTES)
+			last_pte = GEN8_PTES;
+
+		pt_vaddr = kmap_px(pt);
+
+		for (i = pte; i < last_pte; i++) {
+			pt_vaddr[i] = scratch_pte;
+			num_entries--;
+		}
+
+		kunmap_px(ppgtt, pt_vaddr);
+
+		pte = 0;
+		if (++pde == I915_PDES) {
+			if (++pdpe == I915_PDPES_PER_PDP(vm->dev))
+				break;
+			pde = 0;
+		}
+	}
+}
+
+static void gen8_ppgtt_clear_range(struct i915_address_space *vm,
+				   uint64_t start,
+				   uint64_t length,
+				   bool use_scratch)
+{
+	struct i915_hw_ppgtt *ppgtt = i915_vm_to_ppgtt(vm);
+	gen8_pte_t scratch_pte = gen8_pte_encode(px_dma(vm->scratch_page),
+						 I915_CACHE_LLC, use_scratch);
+
+	if (!USES_FULL_48BIT_PPGTT(vm->dev)) {
+		gen8_ppgtt_clear_pte_range(vm, &ppgtt->pdp, start, length,
+					   scratch_pte);
+	} else {
+		uint64_t pml4e;
+		struct i915_page_directory_pointer *pdp;
+
+		gen8_for_each_pml4e(pdp, &ppgtt->pml4, start, length, pml4e) {
+			gen8_ppgtt_clear_pte_range(vm, pdp, start, length,
+						   scratch_pte);
+		}
+	}
+}
+
+static void
+gen8_ppgtt_insert_pte_entries(struct i915_address_space *vm,
+			      struct i915_page_directory_pointer *pdp,
+			      struct sg_page_iter *sg_iter,
+			      uint64_t start,
+			      enum i915_cache_level cache_level)
+{
+	struct i915_hw_ppgtt *ppgtt = i915_vm_to_ppgtt(vm);
+	gen8_pte_t *pt_vaddr;
+	unsigned pdpe = gen8_pdpe_index(start);
+	unsigned pde = gen8_pde_index(start);
+	unsigned pte = gen8_pte_index(start);
+
+	pt_vaddr = NULL;
+
+	while (__sg_page_iter_next(sg_iter)) {
+		if (pt_vaddr == NULL) {
+			struct i915_page_directory *pd = pdp->page_directory[pdpe];
+			struct i915_page_table *pt = pd->page_table[pde];
+			pt_vaddr = kmap_px(pt);
+		}
+
+		pt_vaddr[pte] =
+			gen8_pte_encode(sg_page_iter_dma_address(sg_iter),
+					cache_level, true);
+		if (++pte == GEN8_PTES) {
+			kunmap_px(ppgtt, pt_vaddr);
+			pt_vaddr = NULL;
+			if (++pde == I915_PDES) {
+				if (++pdpe == I915_PDPES_PER_PDP(vm->dev))
+					break;
+				pde = 0;
+			}
+			pte = 0;
+		}
+	}
+
+	if (pt_vaddr)
+		kunmap_px(ppgtt, pt_vaddr);
+}
+
+static void gen8_ppgtt_insert_entries(struct i915_address_space *vm,
+				      struct sg_table *pages,
+				      uint64_t start,
+				      enum i915_cache_level cache_level,
+				      u32 unused)
+{
+	struct i915_hw_ppgtt *ppgtt = i915_vm_to_ppgtt(vm);
+	struct sg_page_iter sg_iter;
+
+	__sg_page_iter_start(&sg_iter, pages->sgl, sg_nents(pages->sgl), 0);
+
+	if (!USES_FULL_48BIT_PPGTT(vm->dev)) {
+		gen8_ppgtt_insert_pte_entries(vm, &ppgtt->pdp, &sg_iter, start,
+					      cache_level);
+	} else {
+		struct i915_page_directory_pointer *pdp;
+		uint64_t pml4e;
+		uint64_t length = (uint64_t)pages->orig_nents << PAGE_SHIFT;
+
+		gen8_for_each_pml4e(pdp, &ppgtt->pml4, start, length, pml4e) {
+			gen8_ppgtt_insert_pte_entries(vm, pdp, &sg_iter,
+						      start, cache_level);
+		}
+	}
+}
+
+static void gen8_free_page_tables(struct drm_device *dev,
+				  struct i915_page_directory *pd)
+{
+	int i;
+
+	if (!px_page(pd))
+		return;
+
+	for_each_set_bit(i, pd->used_pdes, I915_PDES) {
+		if (WARN_ON(!pd->page_table[i]))
+			continue;
+
+		free_pt(dev, pd->page_table[i]);
+		pd->page_table[i] = NULL;
+	}
+}
+
+static int gen8_init_scratch(struct i915_address_space *vm)
+{
+	struct drm_device *dev = vm->dev;
+
+	vm->scratch_page = alloc_scratch_page(dev);
+	if (IS_ERR(vm->scratch_page))
+		return PTR_ERR(vm->scratch_page);
+
+	vm->scratch_pt = alloc_pt(dev);
+	if (IS_ERR(vm->scratch_pt)) {
+		free_scratch_page(dev, vm->scratch_page);
+		return PTR_ERR(vm->scratch_pt);
+	}
+
+	vm->scratch_pd = alloc_pd(dev);
+	if (IS_ERR(vm->scratch_pd)) {
+		free_pt(dev, vm->scratch_pt);
+		free_scratch_page(dev, vm->scratch_page);
+		return PTR_ERR(vm->scratch_pd);
+	}
+
+	if (USES_FULL_48BIT_PPGTT(dev)) {
+		vm->scratch_pdp = alloc_pdp(dev);
+		if (IS_ERR(vm->scratch_pdp)) {
+			free_pd(dev, vm->scratch_pd);
+			free_pt(dev, vm->scratch_pt);
+			free_scratch_page(dev, vm->scratch_page);
+			return PTR_ERR(vm->scratch_pdp);
+		}
+	}
+
+	gen8_initialize_pt(vm, vm->scratch_pt);
+	gen8_initialize_pd(vm, vm->scratch_pd);
+	if (USES_FULL_48BIT_PPGTT(dev))
+		gen8_initialize_pdp(vm, vm->scratch_pdp);
+
+	return 0;
+}
+
+static int gen8_ppgtt_notify_vgt(struct i915_hw_ppgtt *ppgtt, bool create)
+{
+	enum vgt_g2v_type msg;
+	struct drm_i915_private *dev_priv = to_i915(ppgtt->base.dev);
+	int i;
+
+	if (USES_FULL_48BIT_PPGTT(dev_priv)) {
+		u64 daddr = px_dma(&ppgtt->pml4);
+
+		I915_WRITE(vgtif_reg(pdp[0].lo), lower_32_bits(daddr));
+		I915_WRITE(vgtif_reg(pdp[0].hi), upper_32_bits(daddr));
+
+		msg = (create ? VGT_G2V_PPGTT_L4_PAGE_TABLE_CREATE :
+				VGT_G2V_PPGTT_L4_PAGE_TABLE_DESTROY);
+	} else {
+		for (i = 0; i < GEN8_LEGACY_PDPES; i++) {
+			u64 daddr = i915_page_dir_dma_addr(ppgtt, i);
+
+			I915_WRITE(vgtif_reg(pdp[i].lo), lower_32_bits(daddr));
+			I915_WRITE(vgtif_reg(pdp[i].hi), upper_32_bits(daddr));
+		}
+
+		msg = (create ? VGT_G2V_PPGTT_L3_PAGE_TABLE_CREATE :
+				VGT_G2V_PPGTT_L3_PAGE_TABLE_DESTROY);
+	}
+
+	I915_WRITE(vgtif_reg(g2v_notify), msg);
+
+	return 0;
+}
+
+static void gen8_free_scratch(struct i915_address_space *vm)
+{
+	struct drm_device *dev = vm->dev;
+
+	if (USES_FULL_48BIT_PPGTT(dev))
+		free_pdp(dev, vm->scratch_pdp);
+	free_pd(dev, vm->scratch_pd);
+	free_pt(dev, vm->scratch_pt);
+	free_scratch_page(dev, vm->scratch_page);
+}
+
+static void gen8_ppgtt_cleanup_3lvl(struct drm_device *dev,
+				    struct i915_page_directory_pointer *pdp)
+{
+	int i;
+
+	for_each_set_bit(i, pdp->used_pdpes, I915_PDPES_PER_PDP(dev)) {
+		if (WARN_ON(!pdp->page_directory[i]))
+			continue;
+
+		gen8_free_page_tables(dev, pdp->page_directory[i]);
+		free_pd(dev, pdp->page_directory[i]);
+	}
+
+	free_pdp(dev, pdp);
+}
+
+static void gen8_ppgtt_cleanup_4lvl(struct i915_hw_ppgtt *ppgtt)
+{
+	int i;
+
+	for_each_set_bit(i, ppgtt->pml4.used_pml4es, GEN8_PML4ES_PER_PML4) {
+		if (WARN_ON(!ppgtt->pml4.pdps[i]))
+			continue;
+
+		gen8_ppgtt_cleanup_3lvl(ppgtt->base.dev, ppgtt->pml4.pdps[i]);
+	}
+
+	cleanup_px(ppgtt->base.dev, &ppgtt->pml4);
+}
+
+static void gen8_ppgtt_cleanup(struct i915_address_space *vm)
+{
+	struct i915_hw_ppgtt *ppgtt = i915_vm_to_ppgtt(vm);
+
+	if (intel_vgpu_active(vm->dev))
+		gen8_ppgtt_notify_vgt(ppgtt, false);
+
+	if (!USES_FULL_48BIT_PPGTT(ppgtt->base.dev))
+		gen8_ppgtt_cleanup_3lvl(ppgtt->base.dev, &ppgtt->pdp);
+	else
+		gen8_ppgtt_cleanup_4lvl(ppgtt);
+
+	gen8_free_scratch(vm);
+}
+
+/**
+ * gen8_ppgtt_alloc_pagetabs() - Allocate page tables for VA range.
+ * @vm:	Master vm structure.
+ * @pd:	Page directory for this address range.
+ * @start:	Starting virtual address to begin allocations.
+ * @length:	Size of the allocations.
+ * @new_pts:	Bitmap set by function with new allocations. Likely used by the
+ *		caller to free on error.
+ *
+ * Allocate the required number of page tables. Extremely similar to
+ * gen8_ppgtt_alloc_page_directories(). The main difference is here we are limited by
+ * the page directory boundary (instead of the page directory pointer). That
+ * boundary is 1GB virtual. Therefore, unlike gen8_ppgtt_alloc_page_directories(), it is
+ * possible, and likely that the caller will need to use multiple calls of this
+ * function to achieve the appropriate allocation.
+ *
+ * Return: 0 if success; negative error code otherwise.
+ */
+static int gen8_ppgtt_alloc_pagetabs(struct i915_address_space *vm,
+				     struct i915_page_directory *pd,
+				     uint64_t start,
+				     uint64_t length,
+				     unsigned long *new_pts)
+{
+	struct drm_device *dev = vm->dev;
+	struct i915_page_table *pt;
+	uint32_t pde;
+
+	gen8_for_each_pde(pt, pd, start, length, pde) {
+		/* Don't reallocate page tables */
+		if (test_bit(pde, pd->used_pdes)) {
+			/* Scratch is never allocated this way */
+			WARN_ON(pt == vm->scratch_pt);
+			continue;
+		}
+
+		pt = alloc_pt(dev);
+		if (IS_ERR(pt))
+			goto unwind_out;
+
+		gen8_initialize_pt(vm, pt);
+		pd->page_table[pde] = pt;
+		__set_bit(pde, new_pts);
+		trace_i915_page_table_entry_alloc(vm, pde, start, GEN8_PDE_SHIFT);
+	}
+
+	return 0;
+
+unwind_out:
+	for_each_set_bit(pde, new_pts, I915_PDES)
+		free_pt(dev, pd->page_table[pde]);
+
+	return -ENOMEM;
+}
+
+/**
+ * gen8_ppgtt_alloc_page_directories() - Allocate page directories for VA range.
+ * @vm:	Master vm structure.
+ * @pdp:	Page directory pointer for this address range.
+ * @start:	Starting virtual address to begin allocations.
+ * @length:	Size of the allocations.
+ * @new_pds:	Bitmap set by function with new allocations. Likely used by the
+ *		caller to free on error.
+ *
+ * Allocate the required number of page directories starting at the pde index of
+ * @start, and ending at the pde index @start + @length. This function will skip
+ * over already allocated page directories within the range, and only allocate
+ * new ones, setting the appropriate pointer within the pdp as well as the
+ * correct position in the bitmap @new_pds.
+ *
+ * The function will only allocate the pages within the range for a give page
+ * directory pointer. In other words, if @start + @length straddles a virtually
+ * addressed PDP boundary (512GB for 4k pages), there will be more allocations
+ * required by the caller, This is not currently possible, and the BUG in the
+ * code will prevent it.
+ *
+ * Return: 0 if success; negative error code otherwise.
+ */
+static int
+gen8_ppgtt_alloc_page_directories(struct i915_address_space *vm,
+				  struct i915_page_directory_pointer *pdp,
+				  uint64_t start,
+				  uint64_t length,
+				  unsigned long *new_pds)
+{
+	struct drm_device *dev = vm->dev;
+	struct i915_page_directory *pd;
+	uint32_t pdpe;
+	uint32_t pdpes = I915_PDPES_PER_PDP(dev);
+
+	WARN_ON(!bitmap_empty(new_pds, pdpes));
+
+	gen8_for_each_pdpe(pd, pdp, start, length, pdpe) {
+		if (test_bit(pdpe, pdp->used_pdpes))
+			continue;
+
+		pd = alloc_pd(dev);
+		if (IS_ERR(pd))
+			goto unwind_out;
+
+		gen8_initialize_pd(vm, pd);
+		pdp->page_directory[pdpe] = pd;
+		__set_bit(pdpe, new_pds);
+		trace_i915_page_directory_entry_alloc(vm, pdpe, start, GEN8_PDPE_SHIFT);
+	}
+
+	return 0;
+
+unwind_out:
+	for_each_set_bit(pdpe, new_pds, pdpes)
+		free_pd(dev, pdp->page_directory[pdpe]);
+
+	return -ENOMEM;
+}
+
+/**
+ * gen8_ppgtt_alloc_page_dirpointers() - Allocate pdps for VA range.
+ * @vm:	Master vm structure.
+ * @pml4:	Page map level 4 for this address range.
+ * @start:	Starting virtual address to begin allocations.
+ * @length:	Size of the allocations.
+ * @new_pdps:	Bitmap set by function with new allocations. Likely used by the
+ *		caller to free on error.
+ *
+ * Allocate the required number of page directory pointers. Extremely similar to
+ * gen8_ppgtt_alloc_page_directories() and gen8_ppgtt_alloc_pagetabs().
+ * The main difference is here we are limited by the pml4 boundary (instead of
+ * the page directory pointer).
+ *
+ * Return: 0 if success; negative error code otherwise.
+ */
+static int
+gen8_ppgtt_alloc_page_dirpointers(struct i915_address_space *vm,
+				  struct i915_pml4 *pml4,
+				  uint64_t start,
+				  uint64_t length,
+				  unsigned long *new_pdps)
+{
+	struct drm_device *dev = vm->dev;
+	struct i915_page_directory_pointer *pdp;
+	uint32_t pml4e;
+
+	WARN_ON(!bitmap_empty(new_pdps, GEN8_PML4ES_PER_PML4));
+
+	gen8_for_each_pml4e(pdp, pml4, start, length, pml4e) {
+		if (!test_bit(pml4e, pml4->used_pml4es)) {
+			pdp = alloc_pdp(dev);
+			if (IS_ERR(pdp))
+				goto unwind_out;
+
+			gen8_initialize_pdp(vm, pdp);
+			pml4->pdps[pml4e] = pdp;
+			__set_bit(pml4e, new_pdps);
+			trace_i915_page_directory_pointer_entry_alloc(vm,
+								      pml4e,
+								      start,
+								      GEN8_PML4E_SHIFT);
+		}
+	}
+
+	return 0;
+
+unwind_out:
+	for_each_set_bit(pml4e, new_pdps, GEN8_PML4ES_PER_PML4)
+		free_pdp(dev, pml4->pdps[pml4e]);
+
+	return -ENOMEM;
+}
+
+static void
+free_gen8_temp_bitmaps(unsigned long *new_pds, unsigned long *new_pts)
+{
+	kfree(new_pts);
+	kfree(new_pds);
+}
+
+/* Fills in the page directory bitmap, and the array of page tables bitmap. Both
+ * of these are based on the number of PDPEs in the system.
+ */
+static
+int __must_check alloc_gen8_temp_bitmaps(unsigned long **new_pds,
+					 unsigned long **new_pts,
+					 uint32_t pdpes)
+{
+	unsigned long *pds;
+	unsigned long *pts;
+
+	pds = kcalloc(BITS_TO_LONGS(pdpes), sizeof(unsigned long), GFP_TEMPORARY);
+	if (!pds)
+		return -ENOMEM;
+
+	pts = kcalloc(pdpes, BITS_TO_LONGS(I915_PDES) * sizeof(unsigned long),
+		      GFP_TEMPORARY);
+	if (!pts)
+		goto err_out;
+
+	*new_pds = pds;
+	*new_pts = pts;
+
+	return 0;
+
+err_out:
+	free_gen8_temp_bitmaps(pds, pts);
+	return -ENOMEM;
+}
+
+/* PDE TLBs are a pain to invalidate on GEN8+. When we modify
+ * the page table structures, we mark them dirty so that
+ * context switching/execlist queuing code takes extra steps
+ * to ensure that tlbs are flushed.
+ */
+static void mark_tlbs_dirty(struct i915_hw_ppgtt *ppgtt)
+{
+	ppgtt->pd_dirty_rings = INTEL_INFO(ppgtt->base.dev)->ring_mask;
+}
+
+static int gen8_alloc_va_range_3lvl(struct i915_address_space *vm,
+				    struct i915_page_directory_pointer *pdp,
+				    uint64_t start,
+				    uint64_t length)
+{
+	struct i915_hw_ppgtt *ppgtt = i915_vm_to_ppgtt(vm);
+	unsigned long *new_page_dirs, *new_page_tables;
+	struct drm_device *dev = vm->dev;
+	struct i915_page_directory *pd;
+	const uint64_t orig_start = start;
+	const uint64_t orig_length = length;
+	uint32_t pdpe;
+	uint32_t pdpes = I915_PDPES_PER_PDP(dev);
+	int ret;
+
+	/* Wrap is never okay since we can only represent 48b, and we don't
+	 * actually use the other side of the canonical address space.
+	 */
+	if (WARN_ON(start + length < start))
+		return -ENODEV;
+
+	if (WARN_ON(start + length > vm->total))
+		return -ENODEV;
+
+	ret = alloc_gen8_temp_bitmaps(&new_page_dirs, &new_page_tables, pdpes);
+	if (ret)
+		return ret;
+
+	/* Do the allocations first so we can easily bail out */
+	ret = gen8_ppgtt_alloc_page_directories(vm, pdp, start, length,
+						new_page_dirs);
+	if (ret) {
+		free_gen8_temp_bitmaps(new_page_dirs, new_page_tables);
+		return ret;
+	}
+
+	/* For every page directory referenced, allocate page tables */
+	gen8_for_each_pdpe(pd, pdp, start, length, pdpe) {
+		ret = gen8_ppgtt_alloc_pagetabs(vm, pd, start, length,
+						new_page_tables + pdpe * BITS_TO_LONGS(I915_PDES));
+		if (ret)
+			goto err_out;
+	}
+
+	start = orig_start;
+	length = orig_length;
+
+	/* Allocations have completed successfully, so set the bitmaps, and do
+	 * the mappings. */
+	gen8_for_each_pdpe(pd, pdp, start, length, pdpe) {
+		gen8_pde_t *const page_directory = kmap_px(pd);
+		struct i915_page_table *pt;
+		uint64_t pd_len = length;
+		uint64_t pd_start = start;
+		uint32_t pde;
+
+		/* Every pd should be allocated, we just did that above. */
+		WARN_ON(!pd);
+
+		gen8_for_each_pde(pt, pd, pd_start, pd_len, pde) {
+			/* Same reasoning as pd */
+			WARN_ON(!pt);
+			WARN_ON(!pd_len);
+			WARN_ON(!gen8_pte_count(pd_start, pd_len));
+
+			/* Set our used ptes within the page table */
+			bitmap_set(pt->used_ptes,
+				   gen8_pte_index(pd_start),
+				   gen8_pte_count(pd_start, pd_len));
+
+			/* Our pde is now pointing to the pagetable, pt */
+			__set_bit(pde, pd->used_pdes);
+
+			/* Map the PDE to the page table */
+			page_directory[pde] = gen8_pde_encode(px_dma(pt),
+							      I915_CACHE_LLC);
+			trace_i915_page_table_entry_map(&ppgtt->base, pde, pt,
+							gen8_pte_index(start),
+							gen8_pte_count(start, length),
+							GEN8_PTES);
+
+			/* NB: We haven't yet mapped ptes to pages. At this
+			 * point we're still relying on insert_entries() */
+		}
+
+		kunmap_px(ppgtt, page_directory);
+		__set_bit(pdpe, pdp->used_pdpes);
+		gen8_setup_page_directory(ppgtt, pdp, pd, pdpe);
+	}
+
+	free_gen8_temp_bitmaps(new_page_dirs, new_page_tables);
+	mark_tlbs_dirty(ppgtt);
+	return 0;
+
+err_out:
+	while (pdpe--) {
+		unsigned long temp;
+
+		for_each_set_bit(temp, new_page_tables + pdpe *
+				BITS_TO_LONGS(I915_PDES), I915_PDES)
+			free_pt(dev, pdp->page_directory[pdpe]->page_table[temp]);
+	}
+
+	for_each_set_bit(pdpe, new_page_dirs, pdpes)
+		free_pd(dev, pdp->page_directory[pdpe]);
+
+	free_gen8_temp_bitmaps(new_page_dirs, new_page_tables);
+	mark_tlbs_dirty(ppgtt);
+	return ret;
+}
+
+static int gen8_alloc_va_range_4lvl(struct i915_address_space *vm,
+				    struct i915_pml4 *pml4,
+				    uint64_t start,
+				    uint64_t length)
+{
+	DECLARE_BITMAP(new_pdps, GEN8_PML4ES_PER_PML4);
+	struct i915_hw_ppgtt *ppgtt = i915_vm_to_ppgtt(vm);
+	struct i915_page_directory_pointer *pdp;
+	uint64_t pml4e;
+	int ret = 0;
+
+	/* Do the pml4 allocations first, so we don't need to track the newly
+	 * allocated tables below the pdp */
+	bitmap_zero(new_pdps, GEN8_PML4ES_PER_PML4);
+
+	/* The pagedirectory and pagetable allocations are done in the shared 3
+	 * and 4 level code. Just allocate the pdps.
+	 */
+	ret = gen8_ppgtt_alloc_page_dirpointers(vm, pml4, start, length,
+						new_pdps);
+	if (ret)
+		return ret;
+
+	WARN(bitmap_weight(new_pdps, GEN8_PML4ES_PER_PML4) > 2,
+	     "The allocation has spanned more than 512GB. "
+	     "It is highly likely this is incorrect.");
+
+	gen8_for_each_pml4e(pdp, pml4, start, length, pml4e) {
+		WARN_ON(!pdp);
+
+		ret = gen8_alloc_va_range_3lvl(vm, pdp, start, length);
+		if (ret)
+			goto err_out;
+
+		gen8_setup_page_directory_pointer(ppgtt, pml4, pdp, pml4e);
+	}
+
+	bitmap_or(pml4->used_pml4es, new_pdps, pml4->used_pml4es,
+		  GEN8_PML4ES_PER_PML4);
+
+	return 0;
+
+err_out:
+	for_each_set_bit(pml4e, new_pdps, GEN8_PML4ES_PER_PML4)
+		gen8_ppgtt_cleanup_3lvl(vm->dev, pml4->pdps[pml4e]);
+
+	return ret;
+}
+
+static int gen8_alloc_va_range(struct i915_address_space *vm,
+			       uint64_t start, uint64_t length)
+{
+	struct i915_hw_ppgtt *ppgtt = i915_vm_to_ppgtt(vm);
+
+	if (USES_FULL_48BIT_PPGTT(vm->dev))
+		return gen8_alloc_va_range_4lvl(vm, &ppgtt->pml4, start, length);
+	else
+		return gen8_alloc_va_range_3lvl(vm, &ppgtt->pdp, start, length);
+}
+
+static void gen8_dump_pdp(struct i915_page_directory_pointer *pdp,
+			  uint64_t start, uint64_t length,
+			  gen8_pte_t scratch_pte,
+			  struct seq_file *m)
+{
+	struct i915_page_directory *pd;
+	uint32_t pdpe;
+
+	gen8_for_each_pdpe(pd, pdp, start, length, pdpe) {
+		struct i915_page_table *pt;
+		uint64_t pd_len = length;
+		uint64_t pd_start = start;
+		uint32_t pde;
+
+		if (!test_bit(pdpe, pdp->used_pdpes))
+			continue;
+
+		seq_printf(m, "\tPDPE #%d\n", pdpe);
+		gen8_for_each_pde(pt, pd, pd_start, pd_len, pde) {
+			uint32_t  pte;
+			gen8_pte_t *pt_vaddr;
+
+			if (!test_bit(pde, pd->used_pdes))
+				continue;
+
+			pt_vaddr = kmap_px(pt);
+			for (pte = 0; pte < GEN8_PTES; pte += 4) {
+				uint64_t va =
+					(pdpe << GEN8_PDPE_SHIFT) |
+					(pde << GEN8_PDE_SHIFT) |
+					(pte << GEN8_PTE_SHIFT);
+				int i;
+				bool found = false;
+
+				for (i = 0; i < 4; i++)
+					if (pt_vaddr[pte + i] != scratch_pte)
+						found = true;
+				if (!found)
+					continue;
+
+				seq_printf(m, "\t\t0x%llx [%03d,%03d,%04d]: =", va, pdpe, pde, pte);
+				for (i = 0; i < 4; i++) {
+					if (pt_vaddr[pte + i] != scratch_pte)
+						seq_printf(m, " %llx", pt_vaddr[pte + i]);
+					else
+						seq_puts(m, "  SCRATCH ");
+				}
+				seq_puts(m, "\n");
+			}
+			/* don't use kunmap_px, it could trigger
+			 * an unnecessary flush.
+			 */
+			kunmap_atomic(pt_vaddr);
+		}
+	}
+}
+
+static void gen8_dump_ppgtt(struct i915_hw_ppgtt *ppgtt, struct seq_file *m)
+{
+	struct i915_address_space *vm = &ppgtt->base;
+	uint64_t start = ppgtt->base.start;
+	uint64_t length = ppgtt->base.total;
+	gen8_pte_t scratch_pte = gen8_pte_encode(px_dma(vm->scratch_page),
+						 I915_CACHE_LLC, true);
+
+	if (!USES_FULL_48BIT_PPGTT(vm->dev)) {
+		gen8_dump_pdp(&ppgtt->pdp, start, length, scratch_pte, m);
+	} else {
+		uint64_t pml4e;
+		struct i915_pml4 *pml4 = &ppgtt->pml4;
+		struct i915_page_directory_pointer *pdp;
+
+		gen8_for_each_pml4e(pdp, pml4, start, length, pml4e) {
+			if (!test_bit(pml4e, pml4->used_pml4es))
+				continue;
+
+			seq_printf(m, "    PML4E #%llu\n", pml4e);
+			gen8_dump_pdp(pdp, start, length, scratch_pte, m);
+		}
+	}
+}
+
+static int gen8_preallocate_top_level_pdps(struct i915_hw_ppgtt *ppgtt)
+{
+	unsigned long *new_page_dirs, *new_page_tables;
+	uint32_t pdpes = I915_PDPES_PER_PDP(dev);
+	int ret;
+
+	/* We allocate temp bitmap for page tables for no gain
+	 * but as this is for init only, lets keep the things simple
+	 */
+	ret = alloc_gen8_temp_bitmaps(&new_page_dirs, &new_page_tables, pdpes);
+	if (ret)
+		return ret;
+
+	/* Allocate for all pdps regardless of how the ppgtt
+	 * was defined.
+	 */
+	ret = gen8_ppgtt_alloc_page_directories(&ppgtt->base, &ppgtt->pdp,
+						0, 1ULL << 32,
+						new_page_dirs);
+	if (!ret)
+		*ppgtt->pdp.used_pdpes = *new_page_dirs;
+
+	free_gen8_temp_bitmaps(new_page_dirs, new_page_tables);
+
+	return ret;
+}
+
+/*
+ * GEN8 legacy ppgtt programming is accomplished through a max 4 PDP registers
+ * with a net effect resembling a 2-level page table in normal x86 terms. Each
+ * PDP represents 1GB of memory 4 * 512 * 512 * 4096 = 4GB legacy 32b address
+ * space.
+ *
+ */
+static int gen8_ppgtt_init(struct i915_hw_ppgtt *ppgtt)
+{
+	int ret;
+
+	ret = gen8_init_scratch(&ppgtt->base);
+	if (ret)
+		return ret;
+
+	ppgtt->base.start = 0;
+	ppgtt->base.cleanup = gen8_ppgtt_cleanup;
+	ppgtt->base.allocate_va_range = gen8_alloc_va_range;
+	ppgtt->base.insert_entries = gen8_ppgtt_insert_entries;
+	ppgtt->base.clear_range = gen8_ppgtt_clear_range;
+	ppgtt->base.unbind_vma = ppgtt_unbind_vma;
+	ppgtt->base.bind_vma = ppgtt_bind_vma;
+	ppgtt->debug_dump = gen8_dump_ppgtt;
+
+	if (USES_FULL_48BIT_PPGTT(ppgtt->base.dev)) {
+		ret = setup_px(ppgtt->base.dev, &ppgtt->pml4);
+		if (ret)
+			goto free_scratch;
+
+		gen8_initialize_pml4(&ppgtt->base, &ppgtt->pml4);
+
+		ppgtt->base.total = 1ULL << 48;
+		ppgtt->switch_mm = gen8_48b_mm_switch;
+	} else {
+		ret = __pdp_init(ppgtt->base.dev, &ppgtt->pdp);
+		if (ret)
+			goto free_scratch;
+
+		ppgtt->base.total = 1ULL << 32;
+		ppgtt->switch_mm = gen8_legacy_mm_switch;
+		trace_i915_page_directory_pointer_entry_alloc(&ppgtt->base,
+							      0, 0,
+							      GEN8_PML4E_SHIFT);
+
+		if (intel_vgpu_active(ppgtt->base.dev)) {
+			ret = gen8_preallocate_top_level_pdps(ppgtt);
+			if (ret)
+				goto free_scratch;
+		}
+	}
+
+	if (intel_vgpu_active(ppgtt->base.dev))
+		gen8_ppgtt_notify_vgt(ppgtt, true);
+
+	return 0;
+
+free_scratch:
+	gen8_free_scratch(&ppgtt->base);
+	return ret;
+}
+
+static void gen6_dump_ppgtt(struct i915_hw_ppgtt *ppgtt, struct seq_file *m)
+{
+	struct i915_address_space *vm = &ppgtt->base;
+	struct i915_page_table *unused;
+	gen6_pte_t scratch_pte;
+	uint32_t pd_entry;
+	uint32_t  pte, pde, temp;
+	uint32_t start = ppgtt->base.start, length = ppgtt->base.total;
+
+	scratch_pte = vm->pte_encode(px_dma(vm->scratch_page),
+				     I915_CACHE_LLC, true, 0);
+
+	gen6_for_each_pde(unused, &ppgtt->pd, start, length, temp, pde) {
+		u32 expected;
+		gen6_pte_t *pt_vaddr;
+		const dma_addr_t pt_addr = px_dma(ppgtt->pd.page_table[pde]);
+		pd_entry = readl(ppgtt->pd_addr + pde);
+		expected = (GEN6_PDE_ADDR_ENCODE(pt_addr) | GEN6_PDE_VALID);
+
+		if (pd_entry != expected)
+			seq_printf(m, "\tPDE #%d mismatch: Actual PDE: %x Expected PDE: %x\n",
+				   pde,
+				   pd_entry,
+				   expected);
+		seq_printf(m, "\tPDE: %x\n", pd_entry);
+
+		pt_vaddr = kmap_px(ppgtt->pd.page_table[pde]);
+
+		for (pte = 0; pte < GEN6_PTES; pte+=4) {
+			unsigned long va =
+				(pde * PAGE_SIZE * GEN6_PTES) +
+				(pte * PAGE_SIZE);
+			int i;
+			bool found = false;
+			for (i = 0; i < 4; i++)
+				if (pt_vaddr[pte + i] != scratch_pte)
+					found = true;
+			if (!found)
+				continue;
+
+			seq_printf(m, "\t\t0x%lx [%03d,%04d]: =", va, pde, pte);
+			for (i = 0; i < 4; i++) {
+				if (pt_vaddr[pte + i] != scratch_pte)
+					seq_printf(m, " %08x", pt_vaddr[pte + i]);
+				else
+					seq_puts(m, "  SCRATCH ");
+			}
+			seq_puts(m, "\n");
+		}
+		kunmap_px(ppgtt, pt_vaddr);
+	}
+}
+
+/* Write pde (index) from the page directory @pd to the page table @pt */
+static void gen6_write_pde(struct i915_page_directory *pd,
+			    const int pde, struct i915_page_table *pt)
+{
+	/* Caller needs to make sure the write completes if necessary */
+	struct i915_hw_ppgtt *ppgtt =
+		container_of(pd, struct i915_hw_ppgtt, pd);
+	u32 pd_entry;
+
+	pd_entry = GEN6_PDE_ADDR_ENCODE(px_dma(pt));
+	pd_entry |= GEN6_PDE_VALID;
+
+	writel(pd_entry, ppgtt->pd_addr + pde);
+}
+
+/* Write all the page tables found in the ppgtt structure to incrementing page
+ * directories. */
+static void gen6_write_page_range(struct drm_i915_private *dev_priv,
+				  struct i915_page_directory *pd,
+				  uint32_t start, uint32_t length)
+{
+	struct i915_ggtt *ggtt = &dev_priv->ggtt;
+	struct i915_page_table *pt;
+	uint32_t pde, temp;
+
+	gen6_for_each_pde(pt, pd, start, length, temp, pde)
+		gen6_write_pde(pd, pde, pt);
+
+	/* Make sure write is complete before other code can use this page
+	 * table. Also require for WC mapped PTEs */
+	readl(ggtt->gsm);
+}
+
+static uint32_t get_pd_offset(struct i915_hw_ppgtt *ppgtt)
+{
+	BUG_ON(ppgtt->pd.base.ggtt_offset & 0x3f);
+
+	return (ppgtt->pd.base.ggtt_offset / 64) << 16;
+}
+
+static int hsw_mm_switch(struct i915_hw_ppgtt *ppgtt,
+			 struct drm_i915_gem_request *req)
+{
+	struct intel_engine_cs *engine = req->engine;
+	int ret;
+
+	/* NB: TLBs must be flushed and invalidated before a switch */
+	ret = engine->flush(req, I915_GEM_GPU_DOMAINS, I915_GEM_GPU_DOMAINS);
+	if (ret)
+		return ret;
+
+	ret = intel_ring_begin(req, 6);
+	if (ret)
+		return ret;
+
+	intel_ring_emit(engine, MI_LOAD_REGISTER_IMM(2));
+	intel_ring_emit_reg(engine, RING_PP_DIR_DCLV(engine));
+	intel_ring_emit(engine, PP_DIR_DCLV_2G);
+	intel_ring_emit_reg(engine, RING_PP_DIR_BASE(engine));
+	intel_ring_emit(engine, get_pd_offset(ppgtt));
+	intel_ring_emit(engine, MI_NOOP);
+	intel_ring_advance(engine);
+
+	return 0;
+}
+
+static int vgpu_mm_switch(struct i915_hw_ppgtt *ppgtt,
+			  struct drm_i915_gem_request *req)
+{
+	struct intel_engine_cs *engine = req->engine;
+	struct drm_i915_private *dev_priv = to_i915(ppgtt->base.dev);
+
+	I915_WRITE(RING_PP_DIR_DCLV(engine), PP_DIR_DCLV_2G);
+	I915_WRITE(RING_PP_DIR_BASE(engine), get_pd_offset(ppgtt));
+	return 0;
+}
+
+static int gen7_mm_switch(struct i915_hw_ppgtt *ppgtt,
+			  struct drm_i915_gem_request *req)
+{
+	struct intel_engine_cs *engine = req->engine;
+	int ret;
+
+	/* NB: TLBs must be flushed and invalidated before a switch */
+	ret = engine->flush(req, I915_GEM_GPU_DOMAINS, I915_GEM_GPU_DOMAINS);
+	if (ret)
+		return ret;
+
+	ret = intel_ring_begin(req, 6);
+	if (ret)
+		return ret;
+
+	intel_ring_emit(engine, MI_LOAD_REGISTER_IMM(2));
+	intel_ring_emit_reg(engine, RING_PP_DIR_DCLV(engine));
+	intel_ring_emit(engine, PP_DIR_DCLV_2G);
+	intel_ring_emit_reg(engine, RING_PP_DIR_BASE(engine));
+	intel_ring_emit(engine, get_pd_offset(ppgtt));
+	intel_ring_emit(engine, MI_NOOP);
+	intel_ring_advance(engine);
+
+	/* XXX: RCS is the only one to auto invalidate the TLBs? */
+	if (engine->id != RCS) {
+		ret = engine->flush(req, I915_GEM_GPU_DOMAINS, I915_GEM_GPU_DOMAINS);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
+static int gen6_mm_switch(struct i915_hw_ppgtt *ppgtt,
+			  struct drm_i915_gem_request *req)
+{
+	struct intel_engine_cs *engine = req->engine;
+	struct drm_device *dev = ppgtt->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+
+	I915_WRITE(RING_PP_DIR_DCLV(engine), PP_DIR_DCLV_2G);
+	I915_WRITE(RING_PP_DIR_BASE(engine), get_pd_offset(ppgtt));
+
+	POSTING_READ(RING_PP_DIR_DCLV(engine));
+
+	return 0;
+}
+
+static void gen8_ppgtt_enable(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_engine_cs *engine;
+
+	for_each_engine(engine, dev_priv) {
+		u32 four_level = USES_FULL_48BIT_PPGTT(dev) ? GEN8_GFX_PPGTT_48B : 0;
+		I915_WRITE(RING_MODE_GEN7(engine),
+			   _MASKED_BIT_ENABLE(GFX_PPGTT_ENABLE | four_level));
+	}
+}
+
+static void gen7_ppgtt_enable(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_engine_cs *engine;
+	uint32_t ecochk, ecobits;
+
+	ecobits = I915_READ(GAC_ECO_BITS);
+	I915_WRITE(GAC_ECO_BITS, ecobits | ECOBITS_PPGTT_CACHE64B);
+
+	ecochk = I915_READ(GAM_ECOCHK);
+	if (IS_HASWELL(dev)) {
+		ecochk |= ECOCHK_PPGTT_WB_HSW;
+	} else {
+		ecochk |= ECOCHK_PPGTT_LLC_IVB;
+		ecochk &= ~ECOCHK_PPGTT_GFDT_IVB;
+	}
+	I915_WRITE(GAM_ECOCHK, ecochk);
+
+	for_each_engine(engine, dev_priv) {
+		/* GFX_MODE is per-ring on gen7+ */
+		I915_WRITE(RING_MODE_GEN7(engine),
+			   _MASKED_BIT_ENABLE(GFX_PPGTT_ENABLE));
+	}
+}
+
+static void gen6_ppgtt_enable(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	uint32_t ecochk, gab_ctl, ecobits;
+
+	ecobits = I915_READ(GAC_ECO_BITS);
+	I915_WRITE(GAC_ECO_BITS, ecobits | ECOBITS_SNB_BIT |
+		   ECOBITS_PPGTT_CACHE64B);
+
+	gab_ctl = I915_READ(GAB_CTL);
+	I915_WRITE(GAB_CTL, gab_ctl | GAB_CTL_CONT_AFTER_PAGEFAULT);
+
+	ecochk = I915_READ(GAM_ECOCHK);
+	I915_WRITE(GAM_ECOCHK, ecochk | ECOCHK_SNB_BIT | ECOCHK_PPGTT_CACHE64B);
+
+	I915_WRITE(GFX_MODE, _MASKED_BIT_ENABLE(GFX_PPGTT_ENABLE));
+}
+
+/* PPGTT support for Sandybdrige/Gen6 and later */
+static void gen6_ppgtt_clear_range(struct i915_address_space *vm,
+				   uint64_t start,
+				   uint64_t length,
+				   bool use_scratch)
+{
+	struct i915_hw_ppgtt *ppgtt = i915_vm_to_ppgtt(vm);
+	gen6_pte_t *pt_vaddr, scratch_pte;
+	unsigned first_entry = start >> PAGE_SHIFT;
+	unsigned num_entries = length >> PAGE_SHIFT;
+	unsigned act_pt = first_entry / GEN6_PTES;
+	unsigned first_pte = first_entry % GEN6_PTES;
+	unsigned last_pte, i;
+
+	scratch_pte = vm->pte_encode(px_dma(vm->scratch_page),
+				     I915_CACHE_LLC, true, 0);
+
+	while (num_entries) {
+		last_pte = first_pte + num_entries;
+		if (last_pte > GEN6_PTES)
+			last_pte = GEN6_PTES;
+
+		pt_vaddr = kmap_px(ppgtt->pd.page_table[act_pt]);
+
+		for (i = first_pte; i < last_pte; i++)
+			pt_vaddr[i] = scratch_pte;
+
+		kunmap_px(ppgtt, pt_vaddr);
+
+		num_entries -= last_pte - first_pte;
+		first_pte = 0;
+		act_pt++;
+	}
+}
+
+static void gen6_ppgtt_insert_entries(struct i915_address_space *vm,
+				      struct sg_table *pages,
+				      uint64_t start,
+				      enum i915_cache_level cache_level, u32 flags)
+{
+	struct i915_hw_ppgtt *ppgtt = i915_vm_to_ppgtt(vm);
+	gen6_pte_t *pt_vaddr;
+	unsigned first_entry = start >> PAGE_SHIFT;
+	unsigned act_pt = first_entry / GEN6_PTES;
+	unsigned act_pte = first_entry % GEN6_PTES;
+	struct sg_page_iter sg_iter;
+
+	pt_vaddr = NULL;
+	for_each_sg_page(pages->sgl, &sg_iter, pages->nents, 0) {
+		if (pt_vaddr == NULL)
+			pt_vaddr = kmap_px(ppgtt->pd.page_table[act_pt]);
+
+		pt_vaddr[act_pte] =
+			vm->pte_encode(sg_page_iter_dma_address(&sg_iter),
+				       cache_level, true, flags);
+
+		if (++act_pte == GEN6_PTES) {
+			kunmap_px(ppgtt, pt_vaddr);
+			pt_vaddr = NULL;
+			act_pt++;
+			act_pte = 0;
+		}
+	}
+	if (pt_vaddr)
+		kunmap_px(ppgtt, pt_vaddr);
+}
+
+static int gen6_alloc_va_range(struct i915_address_space *vm,
+			       uint64_t start_in, uint64_t length_in)
+{
+	DECLARE_BITMAP(new_page_tables, I915_PDES);
+	struct drm_device *dev = vm->dev;
+	struct drm_i915_private *dev_priv = to_i915(dev);
+	struct i915_ggtt *ggtt = &dev_priv->ggtt;
+	struct i915_hw_ppgtt *ppgtt = i915_vm_to_ppgtt(vm);
+	struct i915_page_table *pt;
+	uint32_t start, length, start_save, length_save;
+	uint32_t pde, temp;
+	int ret;
+
+	if (WARN_ON(start_in + length_in > ppgtt->base.total))
+		return -ENODEV;
+
+	start = start_save = start_in;
+	length = length_save = length_in;
+
+	bitmap_zero(new_page_tables, I915_PDES);
+
+	/* The allocation is done in two stages so that we can bail out with
+	 * minimal amount of pain. The first stage finds new page tables that
+	 * need allocation. The second stage marks use ptes within the page
+	 * tables.
+	 */
+	gen6_for_each_pde(pt, &ppgtt->pd, start, length, temp, pde) {
+		if (pt != vm->scratch_pt) {
+			WARN_ON(bitmap_empty(pt->used_ptes, GEN6_PTES));
+			continue;
+		}
+
+		/* We've already allocated a page table */
+		WARN_ON(!bitmap_empty(pt->used_ptes, GEN6_PTES));
+
+		pt = alloc_pt(dev);
+		if (IS_ERR(pt)) {
+			ret = PTR_ERR(pt);
+			goto unwind_out;
+		}
+
+		gen6_initialize_pt(vm, pt);
+
+		ppgtt->pd.page_table[pde] = pt;
+		__set_bit(pde, new_page_tables);
+		trace_i915_page_table_entry_alloc(vm, pde, start, GEN6_PDE_SHIFT);
+	}
+
+	start = start_save;
+	length = length_save;
+
+	gen6_for_each_pde(pt, &ppgtt->pd, start, length, temp, pde) {
+		DECLARE_BITMAP(tmp_bitmap, GEN6_PTES);
+
+		bitmap_zero(tmp_bitmap, GEN6_PTES);
+		bitmap_set(tmp_bitmap, gen6_pte_index(start),
+			   gen6_pte_count(start, length));
+
+		if (__test_and_clear_bit(pde, new_page_tables))
+			gen6_write_pde(&ppgtt->pd, pde, pt);
+
+		trace_i915_page_table_entry_map(vm, pde, pt,
+					 gen6_pte_index(start),
+					 gen6_pte_count(start, length),
+					 GEN6_PTES);
+		bitmap_or(pt->used_ptes, tmp_bitmap, pt->used_ptes,
+				GEN6_PTES);
+	}
+
+	WARN_ON(!bitmap_empty(new_page_tables, I915_PDES));
+
+	/* Make sure write is complete before other code can use this page
+	 * table. Also require for WC mapped PTEs */
+	readl(ggtt->gsm);
+
+	mark_tlbs_dirty(ppgtt);
+	return 0;
+
+unwind_out:
+	for_each_set_bit(pde, new_page_tables, I915_PDES) {
+		struct i915_page_table *pt = ppgtt->pd.page_table[pde];
+
+		ppgtt->pd.page_table[pde] = vm->scratch_pt;
+		free_pt(vm->dev, pt);
+	}
+
+	mark_tlbs_dirty(ppgtt);
+	return ret;
+}
+
+static int gen6_init_scratch(struct i915_address_space *vm)
+{
+	struct drm_device *dev = vm->dev;
+
+	vm->scratch_page = alloc_scratch_page(dev);
+	if (IS_ERR(vm->scratch_page))
+		return PTR_ERR(vm->scratch_page);
+
+	vm->scratch_pt = alloc_pt(dev);
+	if (IS_ERR(vm->scratch_pt)) {
+		free_scratch_page(dev, vm->scratch_page);
+		return PTR_ERR(vm->scratch_pt);
+	}
+
+	gen6_initialize_pt(vm, vm->scratch_pt);
+
+	return 0;
+}
+
+static void gen6_free_scratch(struct i915_address_space *vm)
+{
+	struct drm_device *dev = vm->dev;
+
+	free_pt(dev, vm->scratch_pt);
+	free_scratch_page(dev, vm->scratch_page);
+}
+
+static void gen6_ppgtt_cleanup(struct i915_address_space *vm)
+{
+	struct i915_hw_ppgtt *ppgtt = i915_vm_to_ppgtt(vm);
+	struct i915_page_table *pt;
+	uint32_t pde;
+
+	drm_mm_remove_node(&ppgtt->node);
+
+	gen6_for_all_pdes(pt, ppgtt, pde) {
+		if (pt != vm->scratch_pt)
+			free_pt(ppgtt->base.dev, pt);
+	}
+
+	gen6_free_scratch(vm);
+}
+
+static int gen6_ppgtt_allocate_page_directories(struct i915_hw_ppgtt *ppgtt)
+{
+	struct i915_address_space *vm = &ppgtt->base;
+	struct drm_device *dev = ppgtt->base.dev;
+	struct drm_i915_private *dev_priv = to_i915(dev);
+	struct i915_ggtt *ggtt = &dev_priv->ggtt;
+	bool retried = false;
+	int ret;
+
+	/* PPGTT PDEs reside in the GGTT and consists of 512 entries. The
+	 * allocator works in address space sizes, so it's multiplied by page
+	 * size. We allocate at the top of the GTT to avoid fragmentation.
+	 */
+	BUG_ON(!drm_mm_initialized(&ggtt->base.mm));
+
+	ret = gen6_init_scratch(vm);
+	if (ret)
+		return ret;
+
+alloc:
+	ret = drm_mm_insert_node_in_range_generic(&ggtt->base.mm,
+						  &ppgtt->node, GEN6_PD_SIZE,
+						  GEN6_PD_ALIGN, 0,
+						  0, ggtt->base.total,
+						  DRM_MM_TOPDOWN);
+	if (ret == -ENOSPC && !retried) {
+		ret = i915_gem_evict_something(dev, &ggtt->base,
+					       GEN6_PD_SIZE, GEN6_PD_ALIGN,
+					       I915_CACHE_NONE,
+					       0, ggtt->base.total,
+					       0);
+		if (ret)
+			goto err_out;
+
+		retried = true;
+		goto alloc;
+	}
+
+	if (ret)
+		goto err_out;
+
+
+	if (ppgtt->node.start < ggtt->mappable_end)
+		DRM_DEBUG("Forced to use aperture for PDEs\n");
+
+	return 0;
+
+err_out:
+	gen6_free_scratch(vm);
+	return ret;
+}
+
+static int gen6_ppgtt_alloc(struct i915_hw_ppgtt *ppgtt)
+{
+	return gen6_ppgtt_allocate_page_directories(ppgtt);
+}
+
+static void gen6_scratch_va_range(struct i915_hw_ppgtt *ppgtt,
+				  uint64_t start, uint64_t length)
+{
+	struct i915_page_table *unused;
+	uint32_t pde, temp;
+
+	gen6_for_each_pde(unused, &ppgtt->pd, start, length, temp, pde)
+		ppgtt->pd.page_table[pde] = ppgtt->base.scratch_pt;
+}
+
+static int gen6_ppgtt_init(struct i915_hw_ppgtt *ppgtt)
+{
+	struct drm_device *dev = ppgtt->base.dev;
+	struct drm_i915_private *dev_priv = to_i915(dev);
+	struct i915_ggtt *ggtt = &dev_priv->ggtt;
+	int ret;
+
+	ppgtt->base.pte_encode = ggtt->base.pte_encode;
+	if (IS_GEN6(dev)) {
+		ppgtt->switch_mm = gen6_mm_switch;
+	} else if (IS_HASWELL(dev)) {
+		ppgtt->switch_mm = hsw_mm_switch;
+	} else if (IS_GEN7(dev)) {
+		ppgtt->switch_mm = gen7_mm_switch;
+	} else
+		BUG();
+
+	if (intel_vgpu_active(dev))
+		ppgtt->switch_mm = vgpu_mm_switch;
+
+	ret = gen6_ppgtt_alloc(ppgtt);
+	if (ret)
+		return ret;
+
+	ppgtt->base.allocate_va_range = gen6_alloc_va_range;
+	ppgtt->base.clear_range = gen6_ppgtt_clear_range;
+	ppgtt->base.insert_entries = gen6_ppgtt_insert_entries;
+	ppgtt->base.unbind_vma = ppgtt_unbind_vma;
+	ppgtt->base.bind_vma = ppgtt_bind_vma;
+	ppgtt->base.cleanup = gen6_ppgtt_cleanup;
+	ppgtt->base.start = 0;
+	ppgtt->base.total = I915_PDES * GEN6_PTES * PAGE_SIZE;
+	ppgtt->debug_dump = gen6_dump_ppgtt;
+
+	ppgtt->pd.base.ggtt_offset =
+		ppgtt->node.start / PAGE_SIZE * sizeof(gen6_pte_t);
+
+	ppgtt->pd_addr = (gen6_pte_t __iomem *)ggtt->gsm +
+		ppgtt->pd.base.ggtt_offset / sizeof(gen6_pte_t);
+
+	gen6_scratch_va_range(ppgtt, 0, ppgtt->base.total);
+
+	gen6_write_page_range(dev_priv, &ppgtt->pd, 0, ppgtt->base.total);
+
+	DRM_DEBUG_DRIVER("Allocated pde space (%lldM) at GTT entry: %llx\n",
+			 ppgtt->node.size >> 20,
+			 ppgtt->node.start / PAGE_SIZE);
+
+	DRM_DEBUG("Adding PPGTT at offset %x\n",
+		  ppgtt->pd.base.ggtt_offset << 10);
+
+	return 0;
+}
+
+static int __hw_ppgtt_init(struct drm_device *dev, struct i915_hw_ppgtt *ppgtt)
+{
+	ppgtt->base.dev = dev;
+
+	if (INTEL_INFO(dev)->gen < 8)
+		return gen6_ppgtt_init(ppgtt);
+	else
+		return gen8_ppgtt_init(ppgtt);
+}
+
+static void i915_address_space_init(struct i915_address_space *vm,
+				    struct drm_i915_private *dev_priv)
+{
+	drm_mm_init(&vm->mm, vm->start, vm->total);
+	vm->dev = dev_priv->dev;
+	INIT_LIST_HEAD(&vm->active_list);
+	INIT_LIST_HEAD(&vm->inactive_list);
+	list_add_tail(&vm->global_link, &dev_priv->vm_list);
+}
+
+static void gtt_write_workarounds(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	/* This function is for gtt related workarounds. This function is
+	 * called on driver load and after a GPU reset, so you can place
+	 * workarounds here even if they get overwritten by GPU reset.
+	 */
+	/* WaIncreaseDefaultTLBEntries:chv,bdw,skl,bxt */
+	if (IS_BROADWELL(dev))
+		I915_WRITE(GEN8_L3_LRA_1_GPGPU, GEN8_L3_LRA_1_GPGPU_DEFAULT_VALUE_BDW);
+	else if (IS_CHERRYVIEW(dev))
+		I915_WRITE(GEN8_L3_LRA_1_GPGPU, GEN8_L3_LRA_1_GPGPU_DEFAULT_VALUE_CHV);
+	else if (IS_SKYLAKE(dev))
+		I915_WRITE(GEN8_L3_LRA_1_GPGPU, GEN9_L3_LRA_1_GPGPU_DEFAULT_VALUE_SKL);
+	else if (IS_BROXTON(dev))
+		I915_WRITE(GEN8_L3_LRA_1_GPGPU, GEN9_L3_LRA_1_GPGPU_DEFAULT_VALUE_BXT);
+}
+
+int i915_ppgtt_init(struct drm_device *dev, struct i915_hw_ppgtt *ppgtt)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	int ret = 0;
+
+	ret = __hw_ppgtt_init(dev, ppgtt);
+	if (ret == 0) {
+		kref_init(&ppgtt->ref);
+		i915_address_space_init(&ppgtt->base, dev_priv);
+	}
+
+	return ret;
+}
+
+int i915_ppgtt_init_hw(struct drm_device *dev)
+{
+	gtt_write_workarounds(dev);
+
+	/* In the case of execlists, PPGTT is enabled by the context descriptor
+	 * and the PDPs are contained within the context itself.  We don't
+	 * need to do anything here. */
+	if (i915.enable_execlists)
+		return 0;
+
+	if (!USES_PPGTT(dev))
+		return 0;
+
+	if (IS_GEN6(dev))
+		gen6_ppgtt_enable(dev);
+	else if (IS_GEN7(dev))
+		gen7_ppgtt_enable(dev);
+	else if (INTEL_INFO(dev)->gen >= 8)
+		gen8_ppgtt_enable(dev);
+	else
+		MISSING_CASE(INTEL_INFO(dev)->gen);
+
+	return 0;
+}
+
+int i915_ppgtt_init_ring(struct drm_i915_gem_request *req)
+{
+	struct drm_i915_private *dev_priv = req->i915;
+	struct i915_hw_ppgtt *ppgtt = dev_priv->mm.aliasing_ppgtt;
+
+	if (i915.enable_execlists)
+		return 0;
+
+	if (!ppgtt)
+		return 0;
+
+	return ppgtt->switch_mm(ppgtt, req);
+}
+
+struct i915_hw_ppgtt *
+i915_ppgtt_create(struct drm_device *dev, struct drm_i915_file_private *fpriv)
+{
+	struct i915_hw_ppgtt *ppgtt;
+	int ret;
+
+	ppgtt = kzalloc(sizeof(*ppgtt), GFP_KERNEL);
+	if (!ppgtt)
+		return ERR_PTR(-ENOMEM);
+
+	ret = i915_ppgtt_init(dev, ppgtt);
+	if (ret) {
+		kfree(ppgtt);
+		return ERR_PTR(ret);
+	}
+
+	ppgtt->file_priv = fpriv;
+
+	trace_i915_ppgtt_create(&ppgtt->base);
+
+	return ppgtt;
+}
+
+void  i915_ppgtt_release(struct kref *kref)
+{
+	struct i915_hw_ppgtt *ppgtt =
+		container_of(kref, struct i915_hw_ppgtt, ref);
+
+	trace_i915_ppgtt_release(&ppgtt->base);
+
+	/* vmas should already be unbound */
+	WARN_ON(!list_empty(&ppgtt->base.active_list));
+	WARN_ON(!list_empty(&ppgtt->base.inactive_list));
+
+	list_del(&ppgtt->base.global_link);
+	drm_mm_takedown(&ppgtt->base.mm);
+
+	ppgtt->base.cleanup(&ppgtt->base);
+	kfree(ppgtt);
+}
+
+extern int intel_iommu_gfx_mapped;
+/* Certain Gen5 chipsets require require idling the GPU before
+ * unmapping anything from the GTT when VT-d is enabled.
+ */
+static bool needs_idle_maps(struct drm_device *dev)
+{
+#ifdef CONFIG_INTEL_IOMMU
+	/* Query intel_iommu to see if we need the workaround. Presumably that
+	 * was loaded first.
+	 */
+	if (IS_GEN5(dev) && IS_MOBILE(dev) && intel_iommu_gfx_mapped)
+		return true;
+#endif
+	return false;
+}
+
+static bool do_idling(struct drm_i915_private *dev_priv)
+{
+	struct i915_ggtt *ggtt = &dev_priv->ggtt;
+	bool ret = dev_priv->mm.interruptible;
+
+	if (unlikely(ggtt->do_idle_maps)) {
+		dev_priv->mm.interruptible = false;
+		if (i915_gpu_idle(dev_priv->dev)) {
+			DRM_ERROR("Couldn't idle GPU\n");
+			/* Wait a bit, in hopes it avoids the hang */
+			udelay(10);
+		}
+	}
+
+	return ret;
+}
+
+static void undo_idling(struct drm_i915_private *dev_priv, bool interruptible)
+{
+	struct i915_ggtt *ggtt = &dev_priv->ggtt;
+
+	if (unlikely(ggtt->do_idle_maps))
+		dev_priv->mm.interruptible = interruptible;
+}
+
+void i915_check_and_clear_faults(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_engine_cs *engine;
+
+	if (INTEL_INFO(dev)->gen < 6)
+		return;
+
+	for_each_engine(engine, dev_priv) {
+		u32 fault_reg;
+		fault_reg = I915_READ(RING_FAULT_REG(engine));
+		if (fault_reg & RING_FAULT_VALID) {
+			DRM_DEBUG_DRIVER("Unexpected fault\n"
+					 "\tAddr: 0x%08lx\n"
+					 "\tAddress space: %s\n"
+					 "\tSource ID: %d\n"
+					 "\tType: %d\n",
+					 fault_reg & PAGE_MASK,
+					 fault_reg & RING_FAULT_GTTSEL_MASK ? "GGTT" : "PPGTT",
+					 RING_FAULT_SRCID(fault_reg),
+					 RING_FAULT_FAULT_TYPE(fault_reg));
+			I915_WRITE(RING_FAULT_REG(engine),
+				   fault_reg & ~RING_FAULT_VALID);
+		}
+	}
+	POSTING_READ(RING_FAULT_REG(&dev_priv->engine[RCS]));
+}
+
+static void i915_ggtt_flush(struct drm_i915_private *dev_priv)
+{
+	if (INTEL_INFO(dev_priv)->gen < 6) {
+		intel_gtt_chipset_flush();
+	} else {
+		I915_WRITE(GFX_FLSH_CNTL_GEN6, GFX_FLSH_CNTL_EN);
+		POSTING_READ(GFX_FLSH_CNTL_GEN6);
+	}
+}
+
+void i915_gem_suspend_gtt_mappings(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = to_i915(dev);
+	struct i915_ggtt *ggtt = &dev_priv->ggtt;
+
+	/* Don't bother messing with faults pre GEN6 as we have little
+	 * documentation supporting that it's a good idea.
+	 */
+	if (INTEL_INFO(dev)->gen < 6)
+		return;
+
+	i915_check_and_clear_faults(dev);
+
+	ggtt->base.clear_range(&ggtt->base, ggtt->base.start, ggtt->base.total,
+			     true);
+
+	i915_ggtt_flush(dev_priv);
+}
+
+int i915_gem_gtt_prepare_object(struct drm_i915_gem_object *obj)
+{
+	if (!dma_map_sg(&obj->base.dev->pdev->dev,
+			obj->pages->sgl, obj->pages->nents,
+			PCI_DMA_BIDIRECTIONAL))
+		return -ENOSPC;
+
+	return 0;
+}
+
+static void gen8_set_pte(void __iomem *addr, gen8_pte_t pte)
+{
+#ifdef writeq
+	writeq(pte, addr);
+#else
+	iowrite32((u32)pte, addr);
+	iowrite32(pte >> 32, addr + 4);
+#endif
+}
+
+static void gen8_ggtt_insert_entries(struct i915_address_space *vm,
+				     struct sg_table *st,
+				     uint64_t start,
+				     enum i915_cache_level level, u32 unused)
+{
+	struct drm_i915_private *dev_priv = to_i915(vm->dev);
+	struct i915_ggtt *ggtt = &dev_priv->ggtt;
+	unsigned first_entry = start >> PAGE_SHIFT;
+	gen8_pte_t __iomem *gtt_entries =
+		(gen8_pte_t __iomem *)ggtt->gsm + first_entry;
+	int i = 0;
+	struct sg_page_iter sg_iter;
+	dma_addr_t addr = 0; /* shut up gcc */
+	int rpm_atomic_seq;
+
+	rpm_atomic_seq = assert_rpm_atomic_begin(dev_priv);
+
+	for_each_sg_page(st->sgl, &sg_iter, st->nents, 0) {
+		addr = sg_dma_address(sg_iter.sg) +
+			(sg_iter.sg_pgoffset << PAGE_SHIFT);
+		gen8_set_pte(&gtt_entries[i],
+			     gen8_pte_encode(addr, level, true));
+		i++;
+	}
+
+	/*
+	 * XXX: This serves as a posting read to make sure that the PTE has
+	 * actually been updated. There is some concern that even though
+	 * registers and PTEs are within the same BAR that they are potentially
+	 * of NUMA access patterns. Therefore, even with the way we assume
+	 * hardware should work, we must keep this posting read for paranoia.
+	 */
+	if (i != 0)
+		WARN_ON(readq(&gtt_entries[i-1])
+			!= gen8_pte_encode(addr, level, true));
+
+	/* This next bit makes the above posting read even more important. We
+	 * want to flush the TLBs only after we're certain all the PTE updates
+	 * have finished.
+	 */
+	I915_WRITE(GFX_FLSH_CNTL_GEN6, GFX_FLSH_CNTL_EN);
+	POSTING_READ(GFX_FLSH_CNTL_GEN6);
+
+	assert_rpm_atomic_end(dev_priv, rpm_atomic_seq);
+}
+
+struct insert_entries {
+	struct i915_address_space *vm;
+	struct sg_table *st;
+	uint64_t start;
+	enum i915_cache_level level;
+	u32 flags;
+};
+
+static int gen8_ggtt_insert_entries__cb(void *_arg)
+{
+	struct insert_entries *arg = _arg;
+	gen8_ggtt_insert_entries(arg->vm, arg->st,
+				 arg->start, arg->level, arg->flags);
+	return 0;
+}
+
+static void gen8_ggtt_insert_entries__BKL(struct i915_address_space *vm,
+					  struct sg_table *st,
+					  uint64_t start,
+					  enum i915_cache_level level,
+					  u32 flags)
+{
+	struct insert_entries arg = { vm, st, start, level, flags };
+	stop_machine(gen8_ggtt_insert_entries__cb, &arg, NULL);
+}
+
+/*
+ * Binds an object into the global gtt with the specified cache level. The object
+ * will be accessible to the GPU via commands whose operands reference offsets
+ * within the global GTT as well as accessible by the GPU through the GMADR
+ * mapped BAR (dev_priv->mm.gtt->gtt).
+ */
+static void gen6_ggtt_insert_entries(struct i915_address_space *vm,
+				     struct sg_table *st,
+				     uint64_t start,
+				     enum i915_cache_level level, u32 flags)
+{
+	struct drm_i915_private *dev_priv = to_i915(vm->dev);
+	struct i915_ggtt *ggtt = &dev_priv->ggtt;
+	unsigned first_entry = start >> PAGE_SHIFT;
+	gen6_pte_t __iomem *gtt_entries =
+		(gen6_pte_t __iomem *)ggtt->gsm + first_entry;
+	int i = 0;
+	struct sg_page_iter sg_iter;
+	dma_addr_t addr = 0;
+	int rpm_atomic_seq;
+
+	rpm_atomic_seq = assert_rpm_atomic_begin(dev_priv);
+
+	for_each_sg_page(st->sgl, &sg_iter, st->nents, 0) {
+		addr = sg_page_iter_dma_address(&sg_iter);
+		iowrite32(vm->pte_encode(addr, level, true, flags), &gtt_entries[i]);
+		i++;
+	}
+
+	/* XXX: This serves as a posting read to make sure that the PTE has
+	 * actually been updated. There is some concern that even though
+	 * registers and PTEs are within the same BAR that they are potentially
+	 * of NUMA access patterns. Therefore, even with the way we assume
+	 * hardware should work, we must keep this posting read for paranoia.
+	 */
+	if (i != 0) {
+		unsigned long gtt = readl(&gtt_entries[i-1]);
+		WARN_ON(gtt != vm->pte_encode(addr, level, true, flags));
+	}
+
+	/* This next bit makes the above posting read even more important. We
+	 * want to flush the TLBs only after we're certain all the PTE updates
+	 * have finished.
+	 */
+	I915_WRITE(GFX_FLSH_CNTL_GEN6, GFX_FLSH_CNTL_EN);
+	POSTING_READ(GFX_FLSH_CNTL_GEN6);
+
+	assert_rpm_atomic_end(dev_priv, rpm_atomic_seq);
+}
+
+static void gen8_ggtt_clear_range(struct i915_address_space *vm,
+				  uint64_t start,
+				  uint64_t length,
+				  bool use_scratch)
+{
+	struct drm_i915_private *dev_priv = to_i915(vm->dev);
+	struct i915_ggtt *ggtt = &dev_priv->ggtt;
+	unsigned first_entry = start >> PAGE_SHIFT;
+	unsigned num_entries = length >> PAGE_SHIFT;
+	gen8_pte_t scratch_pte, __iomem *gtt_base =
+		(gen8_pte_t __iomem *)ggtt->gsm + first_entry;
+	const int max_entries = ggtt_total_entries(ggtt) - first_entry;
+	int i;
+	int rpm_atomic_seq;
+
+	rpm_atomic_seq = assert_rpm_atomic_begin(dev_priv);
+
+	if (WARN(num_entries > max_entries,
+		 "First entry = %d; Num entries = %d (max=%d)\n",
+		 first_entry, num_entries, max_entries))
+		num_entries = max_entries;
+
+	scratch_pte = gen8_pte_encode(px_dma(vm->scratch_page),
+				      I915_CACHE_LLC,
+				      use_scratch);
+	for (i = 0; i < num_entries; i++)
+		gen8_set_pte(&gtt_base[i], scratch_pte);
+	readl(gtt_base);
+
+	assert_rpm_atomic_end(dev_priv, rpm_atomic_seq);
+}
+
+static void gen6_ggtt_clear_range(struct i915_address_space *vm,
+				  uint64_t start,
+				  uint64_t length,
+				  bool use_scratch)
+{
+	struct drm_i915_private *dev_priv = to_i915(vm->dev);
+	struct i915_ggtt *ggtt = &dev_priv->ggtt;
+	unsigned first_entry = start >> PAGE_SHIFT;
+	unsigned num_entries = length >> PAGE_SHIFT;
+	gen6_pte_t scratch_pte, __iomem *gtt_base =
+		(gen6_pte_t __iomem *)ggtt->gsm + first_entry;
+	const int max_entries = ggtt_total_entries(ggtt) - first_entry;
+	int i;
+	int rpm_atomic_seq;
+
+	rpm_atomic_seq = assert_rpm_atomic_begin(dev_priv);
+
+	if (WARN(num_entries > max_entries,
+		 "First entry = %d; Num entries = %d (max=%d)\n",
+		 first_entry, num_entries, max_entries))
+		num_entries = max_entries;
+
+	scratch_pte = vm->pte_encode(px_dma(vm->scratch_page),
+				     I915_CACHE_LLC, use_scratch, 0);
+
+	for (i = 0; i < num_entries; i++)
+		iowrite32(scratch_pte, &gtt_base[i]);
+	readl(gtt_base);
+
+	assert_rpm_atomic_end(dev_priv, rpm_atomic_seq);
+}
+
+static void i915_ggtt_insert_entries(struct i915_address_space *vm,
+				     struct sg_table *pages,
+				     uint64_t start,
+				     enum i915_cache_level cache_level, u32 unused)
+{
+	struct drm_i915_private *dev_priv = vm->dev->dev_private;
+	unsigned int flags = (cache_level == I915_CACHE_NONE) ?
+		AGP_USER_MEMORY : AGP_USER_CACHED_MEMORY;
+	int rpm_atomic_seq;
+
+	rpm_atomic_seq = assert_rpm_atomic_begin(dev_priv);
+
+	intel_gtt_insert_sg_entries(pages, start >> PAGE_SHIFT, flags);
+
+	assert_rpm_atomic_end(dev_priv, rpm_atomic_seq);
+
+}
+
+static void i915_ggtt_clear_range(struct i915_address_space *vm,
+				  uint64_t start,
+				  uint64_t length,
+				  bool unused)
+{
+	struct drm_i915_private *dev_priv = vm->dev->dev_private;
+	unsigned first_entry = start >> PAGE_SHIFT;
+	unsigned num_entries = length >> PAGE_SHIFT;
+	int rpm_atomic_seq;
+
+	rpm_atomic_seq = assert_rpm_atomic_begin(dev_priv);
+
+	intel_gtt_clear_range(first_entry, num_entries);
+
+	assert_rpm_atomic_end(dev_priv, rpm_atomic_seq);
+}
+
+static int ggtt_bind_vma(struct i915_vma *vma,
+			 enum i915_cache_level cache_level,
+			 u32 flags)
+{
+	struct drm_i915_gem_object *obj = vma->obj;
+	u32 pte_flags = 0;
+	int ret;
+
+	ret = i915_get_ggtt_vma_pages(vma);
+	if (ret)
+		return ret;
+
+	/* Currently applicable only to VLV */
+	if (obj->gt_ro)
+		pte_flags |= PTE_READ_ONLY;
+
+	vma->vm->insert_entries(vma->vm, vma->ggtt_view.pages,
+				vma->node.start,
+				cache_level, pte_flags);
+
+	/*
+	 * Without aliasing PPGTT there's no difference between
+	 * GLOBAL/LOCAL_BIND, it's all the same ptes. Hence unconditionally
+	 * upgrade to both bound if we bind either to avoid double-binding.
+	 */
+	vma->bound |= GLOBAL_BIND | LOCAL_BIND;
+
+	return 0;
+}
+
+static int aliasing_gtt_bind_vma(struct i915_vma *vma,
+				 enum i915_cache_level cache_level,
+				 u32 flags)
+{
+	u32 pte_flags;
+	int ret;
+
+	ret = i915_get_ggtt_vma_pages(vma);
+	if (ret)
+		return ret;
+
+	/* Currently applicable only to VLV */
+	pte_flags = 0;
+	if (vma->obj->gt_ro)
+		pte_flags |= PTE_READ_ONLY;
+
+
+	if (flags & GLOBAL_BIND) {
+		vma->vm->insert_entries(vma->vm,
+					vma->ggtt_view.pages,
+					vma->node.start,
+					cache_level, pte_flags);
+	}
+
+	if (flags & LOCAL_BIND) {
+		struct i915_hw_ppgtt *appgtt =
+			to_i915(vma->vm->dev)->mm.aliasing_ppgtt;
+		appgtt->base.insert_entries(&appgtt->base,
+					    vma->ggtt_view.pages,
+					    vma->node.start,
+					    cache_level, pte_flags);
+	}
+
+	return 0;
+}
+
+static void ggtt_unbind_vma(struct i915_vma *vma)
+{
+	struct drm_device *dev = vma->vm->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct drm_i915_gem_object *obj = vma->obj;
+	const uint64_t size = min_t(uint64_t,
+				    obj->base.size,
+				    vma->node.size);
+
+	if (vma->bound & GLOBAL_BIND) {
+		vma->vm->clear_range(vma->vm,
+				     vma->node.start,
+				     size,
+				     true);
+	}
+
+	if (dev_priv->mm.aliasing_ppgtt && vma->bound & LOCAL_BIND) {
+		struct i915_hw_ppgtt *appgtt = dev_priv->mm.aliasing_ppgtt;
+
+		appgtt->base.clear_range(&appgtt->base,
+					 vma->node.start,
+					 size,
+					 true);
+	}
+}
+
+void i915_gem_gtt_finish_object(struct drm_i915_gem_object *obj)
+{
+	struct drm_device *dev = obj->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	bool interruptible;
+
+	interruptible = do_idling(dev_priv);
+
+	dma_unmap_sg(&dev->pdev->dev, obj->pages->sgl, obj->pages->nents,
+		     PCI_DMA_BIDIRECTIONAL);
+
+	undo_idling(dev_priv, interruptible);
+}
+
+static void i915_gtt_color_adjust(struct drm_mm_node *node,
+				  unsigned long color,
+				  u64 *start,
+				  u64 *end)
+{
+	if (node->color != color)
+		*start += 4096;
+
+	if (!list_empty(&node->node_list)) {
+		node = list_entry(node->node_list.next,
+				  struct drm_mm_node,
+				  node_list);
+		if (node->allocated && node->color != color)
+			*end -= 4096;
+	}
+}
+
+static int i915_gem_setup_global_gtt(struct drm_device *dev,
+				     u64 start,
+				     u64 mappable_end,
+				     u64 end)
+{
+	/* Let GEM Manage all of the aperture.
+	 *
+	 * However, leave one page at the end still bound to the scratch page.
+	 * There are a number of places where the hardware apparently prefetches
+	 * past the end of the object, and we've seen multiple hangs with the
+	 * GPU head pointer stuck in a batchbuffer bound at the last page of the
+	 * aperture.  One page should be enough to keep any prefetching inside
+	 * of the aperture.
+	 */
+	struct drm_i915_private *dev_priv = to_i915(dev);
+	struct i915_ggtt *ggtt = &dev_priv->ggtt;
+	struct drm_mm_node *entry;
+	struct drm_i915_gem_object *obj;
+	unsigned long hole_start, hole_end;
+	int ret;
+
+	BUG_ON(mappable_end > end);
+
+	ggtt->base.start = start;
+
+	/* Subtract the guard page before address space initialization to
+	 * shrink the range used by drm_mm */
+	ggtt->base.total = end - start - PAGE_SIZE;
+	i915_address_space_init(&ggtt->base, dev_priv);
+	ggtt->base.total += PAGE_SIZE;
+
+	if (intel_vgpu_active(dev)) {
+		ret = intel_vgt_balloon(dev);
+		if (ret)
+			return ret;
+	}
+
+	if (!HAS_LLC(dev))
+		ggtt->base.mm.color_adjust = i915_gtt_color_adjust;
+
+	/* Mark any preallocated objects as occupied */
+	list_for_each_entry(obj, &dev_priv->mm.bound_list, global_list) {
+		struct i915_vma *vma = i915_gem_obj_to_vma(obj, &ggtt->base);
+
+		DRM_DEBUG_KMS("reserving preallocated space: %llx + %zx\n",
+			      i915_gem_obj_ggtt_offset(obj), obj->base.size);
+
+		WARN_ON(i915_gem_obj_ggtt_bound(obj));
+		ret = drm_mm_reserve_node(&ggtt->base.mm, &vma->node);
+		if (ret) {
+			DRM_DEBUG_KMS("Reservation failed: %i\n", ret);
+			return ret;
+		}
+		vma->bound |= GLOBAL_BIND;
+		__i915_vma_set_map_and_fenceable(vma);
+		list_add_tail(&vma->vm_link, &ggtt->base.inactive_list);
+	}
+
+	/* Clear any non-preallocated blocks */
+	drm_mm_for_each_hole(entry, &ggtt->base.mm, hole_start, hole_end) {
+		DRM_DEBUG_KMS("clearing unused GTT space: [%lx, %lx]\n",
+			      hole_start, hole_end);
+		ggtt->base.clear_range(&ggtt->base, hole_start,
+				     hole_end - hole_start, true);
+	}
+
+	/* And finally clear the reserved guard page */
+	ggtt->base.clear_range(&ggtt->base, end - PAGE_SIZE, PAGE_SIZE, true);
+
+	if (USES_PPGTT(dev) && !USES_FULL_PPGTT(dev)) {
+		struct i915_hw_ppgtt *ppgtt;
+
+		ppgtt = kzalloc(sizeof(*ppgtt), GFP_KERNEL);
+		if (!ppgtt)
+			return -ENOMEM;
+
+		ret = __hw_ppgtt_init(dev, ppgtt);
+		if (ret) {
+			ppgtt->base.cleanup(&ppgtt->base);
+			kfree(ppgtt);
+			return ret;
+		}
+
+		if (ppgtt->base.allocate_va_range)
+			ret = ppgtt->base.allocate_va_range(&ppgtt->base, 0,
+							    ppgtt->base.total);
+		if (ret) {
+			ppgtt->base.cleanup(&ppgtt->base);
+			kfree(ppgtt);
+			return ret;
+		}
+
+		ppgtt->base.clear_range(&ppgtt->base,
+					ppgtt->base.start,
+					ppgtt->base.total,
+					true);
+
+		dev_priv->mm.aliasing_ppgtt = ppgtt;
+		WARN_ON(ggtt->base.bind_vma != ggtt_bind_vma);
+		ggtt->base.bind_vma = aliasing_gtt_bind_vma;
+	}
+
+	return 0;
+}
+
+/**
+ * i915_gem_init_ggtt - Initialize GEM for Global GTT
+ * @dev: DRM device
+ */
+void i915_gem_init_ggtt(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = to_i915(dev);
+	struct i915_ggtt *ggtt = &dev_priv->ggtt;
+
+	i915_gem_setup_global_gtt(dev, 0, ggtt->mappable_end, ggtt->base.total);
+}
+
+/**
+ * i915_ggtt_cleanup_hw - Clean up GGTT hardware initialization
+ * @dev: DRM device
+ */
+void i915_ggtt_cleanup_hw(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = to_i915(dev);
+	struct i915_ggtt *ggtt = &dev_priv->ggtt;
+
+	if (dev_priv->mm.aliasing_ppgtt) {
+		struct i915_hw_ppgtt *ppgtt = dev_priv->mm.aliasing_ppgtt;
+
+		ppgtt->base.cleanup(&ppgtt->base);
+	}
+
+	i915_gem_cleanup_stolen(dev);
+
+	if (drm_mm_initialized(&ggtt->base.mm)) {
+		if (intel_vgpu_active(dev))
+			intel_vgt_deballoon();
+
+		drm_mm_takedown(&ggtt->base.mm);
+		list_del(&ggtt->base.global_link);
+	}
+
+	ggtt->base.cleanup(&ggtt->base);
+}
+
+static unsigned int gen6_get_total_gtt_size(u16 snb_gmch_ctl)
+{
+	snb_gmch_ctl >>= SNB_GMCH_GGMS_SHIFT;
+	snb_gmch_ctl &= SNB_GMCH_GGMS_MASK;
+	return snb_gmch_ctl << 20;
+}
+
+static unsigned int gen8_get_total_gtt_size(u16 bdw_gmch_ctl)
+{
+	bdw_gmch_ctl >>= BDW_GMCH_GGMS_SHIFT;
+	bdw_gmch_ctl &= BDW_GMCH_GGMS_MASK;
+	if (bdw_gmch_ctl)
+		bdw_gmch_ctl = 1 << bdw_gmch_ctl;
+
+#ifdef CONFIG_X86_32
+	/* Limit 32b platforms to a 2GB GGTT: 4 << 20 / pte size * PAGE_SIZE */
+	if (bdw_gmch_ctl > 4)
+		bdw_gmch_ctl = 4;
+#endif
+
+	return bdw_gmch_ctl << 20;
+}
+
+static unsigned int chv_get_total_gtt_size(u16 gmch_ctrl)
+{
+	gmch_ctrl >>= SNB_GMCH_GGMS_SHIFT;
+	gmch_ctrl &= SNB_GMCH_GGMS_MASK;
+
+	if (gmch_ctrl)
+		return 1 << (20 + gmch_ctrl);
+
+	return 0;
+}
+
+static size_t gen6_get_stolen_size(u16 snb_gmch_ctl)
+{
+	snb_gmch_ctl >>= SNB_GMCH_GMS_SHIFT;
+	snb_gmch_ctl &= SNB_GMCH_GMS_MASK;
+	return snb_gmch_ctl << 25; /* 32 MB units */
+}
+
+static size_t gen8_get_stolen_size(u16 bdw_gmch_ctl)
+{
+	bdw_gmch_ctl >>= BDW_GMCH_GMS_SHIFT;
+	bdw_gmch_ctl &= BDW_GMCH_GMS_MASK;
+	return bdw_gmch_ctl << 25; /* 32 MB units */
+}
+
+static size_t chv_get_stolen_size(u16 gmch_ctrl)
+{
+	gmch_ctrl >>= SNB_GMCH_GMS_SHIFT;
+	gmch_ctrl &= SNB_GMCH_GMS_MASK;
+
+	/*
+	 * 0x0  to 0x10: 32MB increments starting at 0MB
+	 * 0x11 to 0x16: 4MB increments starting at 8MB
+	 * 0x17 to 0x1d: 4MB increments start at 36MB
+	 */
+	if (gmch_ctrl < 0x11)
+		return gmch_ctrl << 25;
+	else if (gmch_ctrl < 0x17)
+		return (gmch_ctrl - 0x11 + 2) << 22;
+	else
+		return (gmch_ctrl - 0x17 + 9) << 22;
+}
+
+static size_t gen9_get_stolen_size(u16 gen9_gmch_ctl)
+{
+	gen9_gmch_ctl >>= BDW_GMCH_GMS_SHIFT;
+	gen9_gmch_ctl &= BDW_GMCH_GMS_MASK;
+
+	if (gen9_gmch_ctl < 0xf0)
+		return gen9_gmch_ctl << 25; /* 32 MB units */
+	else
+		/* 4MB increments starting at 0xf0 for 4MB */
+		return (gen9_gmch_ctl - 0xf0 + 1) << 22;
+}
+
+static int ggtt_probe_common(struct drm_device *dev,
+			     size_t gtt_size)
+{
+	struct drm_i915_private *dev_priv = to_i915(dev);
+	struct i915_ggtt *ggtt = &dev_priv->ggtt;
+	struct i915_page_scratch *scratch_page;
+	phys_addr_t ggtt_phys_addr;
+
+	/* For Modern GENs the PTEs and register space are split in the BAR */
+	ggtt_phys_addr = pci_resource_start(dev->pdev, 0) +
+			 (pci_resource_len(dev->pdev, 0) / 2);
+
+	/*
+	 * On BXT writes larger than 64 bit to the GTT pagetable range will be
+	 * dropped. For WC mappings in general we have 64 byte burst writes
+	 * when the WC buffer is flushed, so we can't use it, but have to
+	 * resort to an uncached mapping. The WC issue is easily caught by the
+	 * readback check when writing GTT PTE entries.
+	 */
+	if (IS_BROXTON(dev))
+		ggtt->gsm = ioremap_nocache(ggtt_phys_addr, gtt_size);
+	else
+		ggtt->gsm = ioremap_wc(ggtt_phys_addr, gtt_size);
+	if (!ggtt->gsm) {
+		DRM_ERROR("Failed to map the gtt page table\n");
+		return -ENOMEM;
+	}
+
+	scratch_page = alloc_scratch_page(dev);
+	if (IS_ERR(scratch_page)) {
+		DRM_ERROR("Scratch setup failed\n");
+		/* iounmap will also get called at remove, but meh */
+		iounmap(ggtt->gsm);
+		return PTR_ERR(scratch_page);
+	}
+
+	ggtt->base.scratch_page = scratch_page;
+
+	return 0;
+}
+
+/* The GGTT and PPGTT need a private PPAT setup in order to handle cacheability
+ * bits. When using advanced contexts each context stores its own PAT, but
+ * writing this data shouldn't be harmful even in those cases. */
+static void bdw_setup_private_ppat(struct drm_i915_private *dev_priv)
+{
+	uint64_t pat;
+
+	pat = GEN8_PPAT(0, GEN8_PPAT_WB | GEN8_PPAT_LLC)     | /* for normal objects, no eLLC */
+	      GEN8_PPAT(1, GEN8_PPAT_WC | GEN8_PPAT_LLCELLC) | /* for something pointing to ptes? */
+	      GEN8_PPAT(2, GEN8_PPAT_WT | GEN8_PPAT_LLCELLC) | /* for scanout with eLLC */
+	      GEN8_PPAT(3, GEN8_PPAT_UC)                     | /* Uncached objects, mostly for scanout */
+	      GEN8_PPAT(4, GEN8_PPAT_WB | GEN8_PPAT_LLCELLC | GEN8_PPAT_AGE(0)) |
+	      GEN8_PPAT(5, GEN8_PPAT_WB | GEN8_PPAT_LLCELLC | GEN8_PPAT_AGE(1)) |
+	      GEN8_PPAT(6, GEN8_PPAT_WB | GEN8_PPAT_LLCELLC | GEN8_PPAT_AGE(2)) |
+	      GEN8_PPAT(7, GEN8_PPAT_WB | GEN8_PPAT_LLCELLC | GEN8_PPAT_AGE(3));
+
+	if (!USES_PPGTT(dev_priv))
+		/* Spec: "For GGTT, there is NO pat_sel[2:0] from the entry,
+		 * so RTL will always use the value corresponding to
+		 * pat_sel = 000".
+		 * So let's disable cache for GGTT to avoid screen corruptions.
+		 * MOCS still can be used though.
+		 * - System agent ggtt writes (i.e. cpu gtt mmaps) already work
+		 * before this patch, i.e. the same uncached + snooping access
+		 * like on gen6/7 seems to be in effect.
+		 * - So this just fixes blitter/render access. Again it looks
+		 * like it's not just uncached access, but uncached + snooping.
+		 * So we can still hold onto all our assumptions wrt cpu
+		 * clflushing on LLC machines.
+		 */
+		pat = GEN8_PPAT(0, GEN8_PPAT_UC);
+
+	/* XXX: spec defines this as 2 distinct registers. It's unclear if a 64b
+	 * write would work. */
+	I915_WRITE(GEN8_PRIVATE_PAT_LO, pat);
+	I915_WRITE(GEN8_PRIVATE_PAT_HI, pat >> 32);
+}
+
+static void chv_setup_private_ppat(struct drm_i915_private *dev_priv)
+{
+	uint64_t pat;
+
+	/*
+	 * Map WB on BDW to snooped on CHV.
+	 *
+	 * Only the snoop bit has meaning for CHV, the rest is
+	 * ignored.
+	 *
+	 * The hardware will never snoop for certain types of accesses:
+	 * - CPU GTT (GMADR->GGTT->no snoop->memory)
+	 * - PPGTT page tables
+	 * - some other special cycles
+	 *
+	 * As with BDW, we also need to consider the following for GT accesses:
+	 * "For GGTT, there is NO pat_sel[2:0] from the entry,
+	 * so RTL will always use the value corresponding to
+	 * pat_sel = 000".
+	 * Which means we must set the snoop bit in PAT entry 0
+	 * in order to keep the global status page working.
+	 */
+	pat = GEN8_PPAT(0, CHV_PPAT_SNOOP) |
+	      GEN8_PPAT(1, 0) |
+	      GEN8_PPAT(2, 0) |
+	      GEN8_PPAT(3, 0) |
+	      GEN8_PPAT(4, CHV_PPAT_SNOOP) |
+	      GEN8_PPAT(5, CHV_PPAT_SNOOP) |
+	      GEN8_PPAT(6, CHV_PPAT_SNOOP) |
+	      GEN8_PPAT(7, CHV_PPAT_SNOOP);
+
+	I915_WRITE(GEN8_PRIVATE_PAT_LO, pat);
+	I915_WRITE(GEN8_PRIVATE_PAT_HI, pat >> 32);
+}
+
+static int gen8_gmch_probe(struct i915_ggtt *ggtt)
+{
+	struct drm_device *dev = ggtt->base.dev;
+	struct drm_i915_private *dev_priv = to_i915(dev);
+	u16 snb_gmch_ctl;
+	int ret;
+
+	/* TODO: We're not aware of mappable constraints on gen8 yet */
+	ggtt->mappable_base = pci_resource_start(dev->pdev, 2);
+	ggtt->mappable_end = pci_resource_len(dev->pdev, 2);
+
+	if (!pci_set_dma_mask(dev->pdev, DMA_BIT_MASK(39)))
+		pci_set_consistent_dma_mask(dev->pdev, DMA_BIT_MASK(39));
+
+	pci_read_config_word(dev->pdev, SNB_GMCH_CTRL, &snb_gmch_ctl);
+
+	if (INTEL_INFO(dev)->gen >= 9) {
+		ggtt->stolen_size = gen9_get_stolen_size(snb_gmch_ctl);
+		ggtt->size = gen8_get_total_gtt_size(snb_gmch_ctl);
+	} else if (IS_CHERRYVIEW(dev)) {
+		ggtt->stolen_size = chv_get_stolen_size(snb_gmch_ctl);
+		ggtt->size = chv_get_total_gtt_size(snb_gmch_ctl);
+	} else {
+		ggtt->stolen_size = gen8_get_stolen_size(snb_gmch_ctl);
+		ggtt->size = gen8_get_total_gtt_size(snb_gmch_ctl);
+	}
+
+	ggtt->base.total = (ggtt->size / sizeof(gen8_pte_t)) << PAGE_SHIFT;
+
+	if (IS_CHERRYVIEW(dev) || IS_BROXTON(dev))
+		chv_setup_private_ppat(dev_priv);
+	else
+		bdw_setup_private_ppat(dev_priv);
+
+	ret = ggtt_probe_common(dev, ggtt->size);
+
+	ggtt->base.clear_range = gen8_ggtt_clear_range;
+	if (IS_CHERRYVIEW(dev_priv))
+		ggtt->base.insert_entries = gen8_ggtt_insert_entries__BKL;
+	else
+		ggtt->base.insert_entries = gen8_ggtt_insert_entries;
+	ggtt->base.bind_vma = ggtt_bind_vma;
+	ggtt->base.unbind_vma = ggtt_unbind_vma;
+
+	return ret;
+}
+
+static int gen6_gmch_probe(struct i915_ggtt *ggtt)
+{
+	struct drm_device *dev = ggtt->base.dev;
+	u16 snb_gmch_ctl;
+	int ret;
+
+	ggtt->mappable_base = pci_resource_start(dev->pdev, 2);
+	ggtt->mappable_end = pci_resource_len(dev->pdev, 2);
+
+	/* 64/512MB is the current min/max we actually know of, but this is just
+	 * a coarse sanity check.
+	 */
+	if ((ggtt->mappable_end < (64<<20) || (ggtt->mappable_end > (512<<20)))) {
+		DRM_ERROR("Unknown GMADR size (%llx)\n", ggtt->mappable_end);
+		return -ENXIO;
+	}
+
+	if (!pci_set_dma_mask(dev->pdev, DMA_BIT_MASK(40)))
+		pci_set_consistent_dma_mask(dev->pdev, DMA_BIT_MASK(40));
+	pci_read_config_word(dev->pdev, SNB_GMCH_CTRL, &snb_gmch_ctl);
+
+	ggtt->stolen_size = gen6_get_stolen_size(snb_gmch_ctl);
+	ggtt->size = gen6_get_total_gtt_size(snb_gmch_ctl);
+	ggtt->base.total = (ggtt->size / sizeof(gen6_pte_t)) << PAGE_SHIFT;
+
+	ret = ggtt_probe_common(dev, ggtt->size);
+
+	ggtt->base.clear_range = gen6_ggtt_clear_range;
+	ggtt->base.insert_entries = gen6_ggtt_insert_entries;
+	ggtt->base.bind_vma = ggtt_bind_vma;
+	ggtt->base.unbind_vma = ggtt_unbind_vma;
+
+	return ret;
+}
+
+static void gen6_gmch_remove(struct i915_address_space *vm)
+{
+	struct i915_ggtt *ggtt = container_of(vm, struct i915_ggtt, base);
+
+	iounmap(ggtt->gsm);
+	free_scratch_page(vm->dev, vm->scratch_page);
+}
+
+static int i915_gmch_probe(struct i915_ggtt *ggtt)
+{
+	struct drm_device *dev = ggtt->base.dev;
+	struct drm_i915_private *dev_priv = to_i915(dev);
+	int ret;
+
+	ret = intel_gmch_probe(dev_priv->bridge_dev, dev_priv->dev->pdev, NULL);
+	if (!ret) {
+		DRM_ERROR("failed to set up gmch\n");
+		return -EIO;
+	}
+
+	intel_gtt_get(&ggtt->base.total, &ggtt->stolen_size,
+		      &ggtt->mappable_base, &ggtt->mappable_end);
+
+	ggtt->do_idle_maps = needs_idle_maps(dev_priv->dev);
+	ggtt->base.insert_entries = i915_ggtt_insert_entries;
+	ggtt->base.clear_range = i915_ggtt_clear_range;
+	ggtt->base.bind_vma = ggtt_bind_vma;
+	ggtt->base.unbind_vma = ggtt_unbind_vma;
+
+	if (unlikely(ggtt->do_idle_maps))
+		DRM_INFO("applying Ironlake quirks for intel_iommu\n");
+
+	return 0;
+}
+
+static void i915_gmch_remove(struct i915_address_space *vm)
+{
+	intel_gmch_remove();
+}
+
+/**
+ * i915_ggtt_init_hw - Initialize GGTT hardware
+ * @dev: DRM device
+ */
+int i915_ggtt_init_hw(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = to_i915(dev);
+	struct i915_ggtt *ggtt = &dev_priv->ggtt;
+	int ret;
+
+	if (INTEL_INFO(dev)->gen <= 5) {
+		ggtt->probe = i915_gmch_probe;
+		ggtt->base.cleanup = i915_gmch_remove;
+	} else if (INTEL_INFO(dev)->gen < 8) {
+		ggtt->probe = gen6_gmch_probe;
+		ggtt->base.cleanup = gen6_gmch_remove;
+
+		if (HAS_EDRAM(dev))
+			ggtt->base.pte_encode = iris_pte_encode;
+		else if (IS_HASWELL(dev))
+			ggtt->base.pte_encode = hsw_pte_encode;
+		else if (IS_VALLEYVIEW(dev))
+			ggtt->base.pte_encode = byt_pte_encode;
+		else if (INTEL_INFO(dev)->gen >= 7)
+			ggtt->base.pte_encode = ivb_pte_encode;
+		else
+			ggtt->base.pte_encode = snb_pte_encode;
+	} else {
+		ggtt->probe = gen8_gmch_probe;
+		ggtt->base.cleanup = gen6_gmch_remove;
+	}
+
+	ggtt->base.dev = dev;
+	ggtt->base.is_ggtt = true;
+
+	ret = ggtt->probe(ggtt);
+	if (ret)
+		return ret;
+
+	if ((ggtt->base.total - 1) >> 32) {
+		DRM_ERROR("We never expected a Global GTT with more than 32bits"
+			  "of address space! Found %lldM!\n",
+			  ggtt->base.total >> 20);
+		ggtt->base.total = 1ULL << 32;
+		ggtt->mappable_end = min(ggtt->mappable_end, ggtt->base.total);
+	}
+
+	/*
+	 * Initialise stolen early so that we may reserve preallocated
+	 * objects for the BIOS to KMS transition.
+	 */
+	ret = i915_gem_init_stolen(dev);
+	if (ret)
+		goto out_gtt_cleanup;
+
+	/* GMADR is the PCI mmio aperture into the global GTT. */
+	DRM_INFO("Memory usable by graphics device = %lluM\n",
+		 ggtt->base.total >> 20);
+	DRM_DEBUG_DRIVER("GMADR size = %lldM\n", ggtt->mappable_end >> 20);
+	DRM_DEBUG_DRIVER("GTT stolen size = %zdM\n", ggtt->stolen_size >> 20);
+#ifdef CONFIG_INTEL_IOMMU
+	if (intel_iommu_gfx_mapped)
+		DRM_INFO("VT-d active for gfx access\n");
+#endif
+	/*
+	 * i915.enable_ppgtt is read-only, so do an early pass to validate the
+	 * user's requested state against the hardware/driver capabilities.  We
+	 * do this now so that we can print out any log messages once rather
+	 * than every time we check intel_enable_ppgtt().
+	 */
+	i915.enable_ppgtt = sanitize_enable_ppgtt(dev, i915.enable_ppgtt);
+	DRM_DEBUG_DRIVER("ppgtt mode: %i\n", i915.enable_ppgtt);
+
+	return 0;
+
+out_gtt_cleanup:
+	ggtt->base.cleanup(&ggtt->base);
+
+	return ret;
+}
+
+int i915_ggtt_enable_hw(struct drm_device *dev)
+{
+	if (INTEL_INFO(dev)->gen < 6 && !intel_enable_gtt())
+		return -EIO;
+
+	return 0;
+}
+
+void i915_gem_restore_gtt_mappings(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = to_i915(dev);
+	struct i915_ggtt *ggtt = &dev_priv->ggtt;
+	struct drm_i915_gem_object *obj;
+	struct i915_vma *vma;
+	bool flush;
+
+	i915_check_and_clear_faults(dev);
+
+	/* First fill our portion of the GTT with scratch pages */
+	ggtt->base.clear_range(&ggtt->base, ggtt->base.start, ggtt->base.total,
+			       true);
+
+	/* Cache flush objects bound into GGTT and rebind them. */
+	list_for_each_entry(obj, &dev_priv->mm.bound_list, global_list) {
+		flush = false;
+		list_for_each_entry(vma, &obj->vma_list, obj_link) {
+			if (vma->vm != &ggtt->base)
+				continue;
+
+			WARN_ON(i915_vma_bind(vma, obj->cache_level,
+					      PIN_UPDATE));
+
+			flush = true;
+		}
+
+		if (flush)
+			i915_gem_clflush_object(obj, obj->pin_display);
+	}
+
+	if (INTEL_INFO(dev)->gen >= 8) {
+		if (IS_CHERRYVIEW(dev) || IS_BROXTON(dev))
+			chv_setup_private_ppat(dev_priv);
+		else
+			bdw_setup_private_ppat(dev_priv);
+
+		return;
+	}
+
+	if (USES_PPGTT(dev)) {
+		struct i915_address_space *vm;
+
+		list_for_each_entry(vm, &dev_priv->vm_list, global_link) {
+			/* TODO: Perhaps it shouldn't be gen6 specific */
+
+			struct i915_hw_ppgtt *ppgtt;
+
+			if (vm->is_ggtt)
+				ppgtt = dev_priv->mm.aliasing_ppgtt;
+			else
+				ppgtt = i915_vm_to_ppgtt(vm);
+
+			gen6_write_page_range(dev_priv, &ppgtt->pd,
+					      0, ppgtt->base.total);
+		}
+	}
+
+	i915_ggtt_flush(dev_priv);
+}
+
+static struct i915_vma *
+__i915_gem_vma_create(struct drm_i915_gem_object *obj,
+		      struct i915_address_space *vm,
+		      const struct i915_ggtt_view *ggtt_view)
+{
+	struct i915_vma *vma;
+
+	if (WARN_ON(i915_is_ggtt(vm) != !!ggtt_view))
+		return ERR_PTR(-EINVAL);
+
+	vma = kmem_cache_zalloc(to_i915(obj->base.dev)->vmas, GFP_KERNEL);
+	if (vma == NULL)
+		return ERR_PTR(-ENOMEM);
+
+	INIT_LIST_HEAD(&vma->vm_link);
+	INIT_LIST_HEAD(&vma->obj_link);
+	INIT_LIST_HEAD(&vma->exec_list);
+	vma->vm = vm;
+	vma->obj = obj;
+	vma->is_ggtt = i915_is_ggtt(vm);
+
+	if (i915_is_ggtt(vm))
+		vma->ggtt_view = *ggtt_view;
+	else
+		i915_ppgtt_get(i915_vm_to_ppgtt(vm));
+
+	list_add_tail(&vma->obj_link, &obj->vma_list);
+
+	return vma;
+}
+
+struct i915_vma *
+i915_gem_obj_lookup_or_create_vma(struct drm_i915_gem_object *obj,
+				  struct i915_address_space *vm)
+{
+	struct i915_vma *vma;
+
+	vma = i915_gem_obj_to_vma(obj, vm);
+	if (!vma)
+		vma = __i915_gem_vma_create(obj, vm,
+					    i915_is_ggtt(vm) ? &i915_ggtt_view_normal : NULL);
+
+	return vma;
+}
+
+struct i915_vma *
+i915_gem_obj_lookup_or_create_ggtt_vma(struct drm_i915_gem_object *obj,
+				       const struct i915_ggtt_view *view)
+{
+	struct drm_device *dev = obj->base.dev;
+	struct drm_i915_private *dev_priv = to_i915(dev);
+	struct i915_ggtt *ggtt = &dev_priv->ggtt;
+	struct i915_vma *vma = i915_gem_obj_to_ggtt_view(obj, view);
+
+	if (!vma)
+		vma = __i915_gem_vma_create(obj, &ggtt->base, view);
+
+	return vma;
+
+}
+
+static struct scatterlist *
+rotate_pages(const dma_addr_t *in, unsigned int offset,
+	     unsigned int width, unsigned int height,
+	     unsigned int stride,
+	     struct sg_table *st, struct scatterlist *sg)
+{
+	unsigned int column, row;
+	unsigned int src_idx;
+
+	for (column = 0; column < width; column++) {
+		src_idx = stride * (height - 1) + column;
+		for (row = 0; row < height; row++) {
+			st->nents++;
+			/* We don't need the pages, but need to initialize
+			 * the entries so the sg list can be happily traversed.
+			 * The only thing we need are DMA addresses.
+			 */
+			sg_set_page(sg, NULL, PAGE_SIZE, 0);
+			sg_dma_address(sg) = in[offset + src_idx];
+			sg_dma_len(sg) = PAGE_SIZE;
+			sg = sg_next(sg);
+			src_idx -= stride;
+		}
+	}
+
+	return sg;
+}
+
+static struct sg_table *
+intel_rotate_fb_obj_pages(struct intel_rotation_info *rot_info,
+			  struct drm_i915_gem_object *obj)
+{
+	unsigned int size_pages = rot_info->plane[0].width * rot_info->plane[0].height;
+	unsigned int size_pages_uv;
+	struct sg_page_iter sg_iter;
+	unsigned long i;
+	dma_addr_t *page_addr_list;
+	struct sg_table *st;
+	unsigned int uv_start_page;
+	struct scatterlist *sg;
+	int ret = -ENOMEM;
+
+	/* Allocate a temporary list of source pages for random access. */
+	page_addr_list = drm_malloc_gfp(obj->base.size / PAGE_SIZE,
+					sizeof(dma_addr_t),
+					GFP_TEMPORARY);
+	if (!page_addr_list)
+		return ERR_PTR(ret);
+
+	/* Account for UV plane with NV12. */
+	if (rot_info->pixel_format == DRM_FORMAT_NV12)
+		size_pages_uv = rot_info->plane[1].width * rot_info->plane[1].height;
+	else
+		size_pages_uv = 0;
+
+	/* Allocate target SG list. */
+	st = kmalloc(sizeof(*st), GFP_KERNEL);
+	if (!st)
+		goto err_st_alloc;
+
+	ret = sg_alloc_table(st, size_pages + size_pages_uv, GFP_KERNEL);
+	if (ret)
+		goto err_sg_alloc;
+
+	/* Populate source page list from the object. */
+	i = 0;
+	for_each_sg_page(obj->pages->sgl, &sg_iter, obj->pages->nents, 0) {
+		page_addr_list[i] = sg_page_iter_dma_address(&sg_iter);
+		i++;
+	}
+
+	st->nents = 0;
+	sg = st->sgl;
+
+	/* Rotate the pages. */
+	sg = rotate_pages(page_addr_list, 0,
+			  rot_info->plane[0].width, rot_info->plane[0].height,
+			  rot_info->plane[0].width,
+			  st, sg);
+
+	/* Append the UV plane if NV12. */
+	if (rot_info->pixel_format == DRM_FORMAT_NV12) {
+		uv_start_page = size_pages;
+
+		/* Check for tile-row un-alignment. */
+		if (offset_in_page(rot_info->uv_offset))
+			uv_start_page--;
+
+		rot_info->uv_start_page = uv_start_page;
+
+		sg = rotate_pages(page_addr_list, rot_info->uv_start_page,
+				  rot_info->plane[1].width, rot_info->plane[1].height,
+				  rot_info->plane[1].width,
+				  st, sg);
+	}
+
+	DRM_DEBUG_KMS("Created rotated page mapping for object size %zu (%ux%u tiles, %u pages (%u plane 0)).\n",
+		      obj->base.size, rot_info->plane[0].width,
+		      rot_info->plane[0].height, size_pages + size_pages_uv,
+		      size_pages);
+
+	drm_free_large(page_addr_list);
+
+	return st;
+
+err_sg_alloc:
+	kfree(st);
+err_st_alloc:
+	drm_free_large(page_addr_list);
+
+	DRM_DEBUG_KMS("Failed to create rotated mapping for object size %zu! (%d) (%ux%u tiles, %u pages (%u plane 0))\n",
+		      obj->base.size, ret, rot_info->plane[0].width,
+		      rot_info->plane[0].height, size_pages + size_pages_uv,
+		      size_pages);
+	return ERR_PTR(ret);
+}
+
+static struct sg_table *
+intel_partial_pages(const struct i915_ggtt_view *view,
+		    struct drm_i915_gem_object *obj)
+{
+	struct sg_table *st;
+	struct scatterlist *sg;
+	struct sg_page_iter obj_sg_iter;
+	int ret = -ENOMEM;
+
+	st = kmalloc(sizeof(*st), GFP_KERNEL);
+	if (!st)
+		goto err_st_alloc;
+
+	ret = sg_alloc_table(st, view->params.partial.size, GFP_KERNEL);
+	if (ret)
+		goto err_sg_alloc;
+
+	sg = st->sgl;
+	st->nents = 0;
+	for_each_sg_page(obj->pages->sgl, &obj_sg_iter, obj->pages->nents,
+		view->params.partial.offset)
+	{
+		if (st->nents >= view->params.partial.size)
+			break;
+
+		sg_set_page(sg, NULL, PAGE_SIZE, 0);
+		sg_dma_address(sg) = sg_page_iter_dma_address(&obj_sg_iter);
+		sg_dma_len(sg) = PAGE_SIZE;
+
+		sg = sg_next(sg);
+		st->nents++;
+	}
+
+	return st;
+
+err_sg_alloc:
+	kfree(st);
+err_st_alloc:
+	return ERR_PTR(ret);
+}
+
+static int
+i915_get_ggtt_vma_pages(struct i915_vma *vma)
+{
+	int ret = 0;
+
+	if (vma->ggtt_view.pages)
+		return 0;
+
+	if (vma->ggtt_view.type == I915_GGTT_VIEW_NORMAL)
+		vma->ggtt_view.pages = vma->obj->pages;
+	else if (vma->ggtt_view.type == I915_GGTT_VIEW_ROTATED)
+		vma->ggtt_view.pages =
+			intel_rotate_fb_obj_pages(&vma->ggtt_view.params.rotated, vma->obj);
+	else if (vma->ggtt_view.type == I915_GGTT_VIEW_PARTIAL)
+		vma->ggtt_view.pages =
+			intel_partial_pages(&vma->ggtt_view, vma->obj);
+	else
+		WARN_ONCE(1, "GGTT view %u not implemented!\n",
+			  vma->ggtt_view.type);
+
+	if (!vma->ggtt_view.pages) {
+		DRM_ERROR("Failed to get pages for GGTT view type %u!\n",
+			  vma->ggtt_view.type);
+		ret = -EINVAL;
+	} else if (IS_ERR(vma->ggtt_view.pages)) {
+		ret = PTR_ERR(vma->ggtt_view.pages);
+		vma->ggtt_view.pages = NULL;
+		DRM_ERROR("Failed to get pages for VMA view type %u (%d)!\n",
+			  vma->ggtt_view.type, ret);
+	}
+
+	return ret;
+}
+
+/**
+ * i915_vma_bind - Sets up PTEs for an VMA in it's corresponding address space.
+ * @vma: VMA to map
+ * @cache_level: mapping cache level
+ * @flags: flags like global or local mapping
+ *
+ * DMA addresses are taken from the scatter-gather table of this object (or of
+ * this VMA in case of non-default GGTT views) and PTE entries set up.
+ * Note that DMA addresses are also the only part of the SG table we care about.
+ */
+int i915_vma_bind(struct i915_vma *vma, enum i915_cache_level cache_level,
+		  u32 flags)
+{
+	int ret;
+	u32 bind_flags;
+
+	if (WARN_ON(flags == 0))
+		return -EINVAL;
+
+	bind_flags = 0;
+	if (flags & PIN_GLOBAL)
+		bind_flags |= GLOBAL_BIND;
+	if (flags & PIN_USER)
+		bind_flags |= LOCAL_BIND;
+
+	if (flags & PIN_UPDATE)
+		bind_flags |= vma->bound;
+	else
+		bind_flags &= ~vma->bound;
+
+	if (bind_flags == 0)
+		return 0;
+
+	if (vma->bound == 0 && vma->vm->allocate_va_range) {
+		/* XXX: i915_vma_pin() will fix this +- hack */
+		vma->pin_count++;
+		trace_i915_va_alloc(vma);
+		ret = vma->vm->allocate_va_range(vma->vm,
+						 vma->node.start,
+						 vma->node.size);
+		vma->pin_count--;
+		if (ret)
+			return ret;
+	}
+
+	ret = vma->vm->bind_vma(vma, cache_level, bind_flags);
+	if (ret)
+		return ret;
+
+	vma->bound |= bind_flags;
+
+	return 0;
+}
+
+/**
+ * i915_ggtt_view_size - Get the size of a GGTT view.
+ * @obj: Object the view is of.
+ * @view: The view in question.
+ *
+ * @return The size of the GGTT view in bytes.
+ */
+size_t
+i915_ggtt_view_size(struct drm_i915_gem_object *obj,
+		    const struct i915_ggtt_view *view)
+{
+	if (view->type == I915_GGTT_VIEW_NORMAL) {
+		return obj->base.size;
+	} else if (view->type == I915_GGTT_VIEW_ROTATED) {
+		return intel_rotation_info_size(&view->params.rotated) << PAGE_SHIFT;
+	} else if (view->type == I915_GGTT_VIEW_PARTIAL) {
+		return view->params.partial.size << PAGE_SHIFT;
+	} else {
+		WARN_ONCE(1, "GGTT view %u not implemented!\n", view->type);
+		return obj->base.size;
+	}
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/i915/i915_gem_gtt.h
@@ -0,0 +1,563 @@
+/*
+ * Copyright © 2014 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Please try to maintain the following order within this file unless it makes
+ * sense to do otherwise. From top to bottom:
+ * 1. typedefs
+ * 2. #defines, and macros
+ * 3. structure definitions
+ * 4. function prototypes
+ *
+ * Within each section, please try to order by generation in ascending order,
+ * from top to bottom (ie. gen6 on the top, gen8 on the bottom).
+ */
+
+#ifndef __I915_GEM_GTT_H__
+#define __I915_GEM_GTT_H__
+
+struct drm_i915_file_private;
+
+typedef uint32_t gen6_pte_t;
+typedef uint64_t gen8_pte_t;
+typedef uint64_t gen8_pde_t;
+typedef uint64_t gen8_ppgtt_pdpe_t;
+typedef uint64_t gen8_ppgtt_pml4e_t;
+
+#define ggtt_total_entries(ggtt) ((ggtt)->base.total >> PAGE_SHIFT)
+
+/* gen6-hsw has bit 11-4 for physical addr bit 39-32 */
+#define GEN6_GTT_ADDR_ENCODE(addr)	((addr) | (((addr) >> 28) & 0xff0))
+#define GEN6_PTE_ADDR_ENCODE(addr)	GEN6_GTT_ADDR_ENCODE(addr)
+#define GEN6_PDE_ADDR_ENCODE(addr)	GEN6_GTT_ADDR_ENCODE(addr)
+#define GEN6_PTE_CACHE_LLC		(2 << 1)
+#define GEN6_PTE_UNCACHED		(1 << 1)
+#define GEN6_PTE_VALID			(1 << 0)
+
+#define I915_PTES(pte_len)		(PAGE_SIZE / (pte_len))
+#define I915_PTE_MASK(pte_len)		(I915_PTES(pte_len) - 1)
+#define I915_PDES			512
+#define I915_PDE_MASK			(I915_PDES - 1)
+#define NUM_PTE(pde_shift)     (1 << (pde_shift - PAGE_SHIFT))
+
+#define GEN6_PTES			I915_PTES(sizeof(gen6_pte_t))
+#define GEN6_PD_SIZE		        (I915_PDES * PAGE_SIZE)
+#define GEN6_PD_ALIGN			(PAGE_SIZE * 16)
+#define GEN6_PDE_SHIFT			22
+#define GEN6_PDE_VALID			(1 << 0)
+
+#define GEN7_PTE_CACHE_L3_LLC		(3 << 1)
+
+#define BYT_PTE_SNOOPED_BY_CPU_CACHES	(1 << 2)
+#define BYT_PTE_WRITEABLE		(1 << 1)
+
+/* Cacheability Control is a 4-bit value. The low three bits are stored in bits
+ * 3:1 of the PTE, while the fourth bit is stored in bit 11 of the PTE.
+ */
+#define HSW_CACHEABILITY_CONTROL(bits)	((((bits) & 0x7) << 1) | \
+					 (((bits) & 0x8) << (11 - 3)))
+#define HSW_WB_LLC_AGE3			HSW_CACHEABILITY_CONTROL(0x2)
+#define HSW_WB_LLC_AGE0			HSW_CACHEABILITY_CONTROL(0x3)
+#define HSW_WB_ELLC_LLC_AGE3		HSW_CACHEABILITY_CONTROL(0x8)
+#define HSW_WB_ELLC_LLC_AGE0		HSW_CACHEABILITY_CONTROL(0xb)
+#define HSW_WT_ELLC_LLC_AGE3		HSW_CACHEABILITY_CONTROL(0x7)
+#define HSW_WT_ELLC_LLC_AGE0		HSW_CACHEABILITY_CONTROL(0x6)
+#define HSW_PTE_UNCACHED		(0)
+#define HSW_GTT_ADDR_ENCODE(addr)	((addr) | (((addr) >> 28) & 0x7f0))
+#define HSW_PTE_ADDR_ENCODE(addr)	HSW_GTT_ADDR_ENCODE(addr)
+
+/* GEN8 legacy style address is defined as a 3 level page table:
+ * 31:30 | 29:21 | 20:12 |  11:0
+ * PDPE  |  PDE  |  PTE  | offset
+ * The difference as compared to normal x86 3 level page table is the PDPEs are
+ * programmed via register.
+ *
+ * GEN8 48b legacy style address is defined as a 4 level page table:
+ * 47:39 | 38:30 | 29:21 | 20:12 |  11:0
+ * PML4E | PDPE  |  PDE  |  PTE  | offset
+ */
+#define GEN8_PML4ES_PER_PML4		512
+#define GEN8_PML4E_SHIFT		39
+#define GEN8_PML4E_MASK			(GEN8_PML4ES_PER_PML4 - 1)
+#define GEN8_PDPE_SHIFT			30
+/* NB: GEN8_PDPE_MASK is untrue for 32b platforms, but it has no impact on 32b page
+ * tables */
+#define GEN8_PDPE_MASK			0x1ff
+#define GEN8_PDE_SHIFT			21
+#define GEN8_PDE_MASK			0x1ff
+#define GEN8_PTE_SHIFT			12
+#define GEN8_PTE_MASK			0x1ff
+#define GEN8_LEGACY_PDPES		4
+#define GEN8_PTES			I915_PTES(sizeof(gen8_pte_t))
+
+#define I915_PDPES_PER_PDP(dev) (USES_FULL_48BIT_PPGTT(dev) ?\
+				 GEN8_PML4ES_PER_PML4 : GEN8_LEGACY_PDPES)
+
+#define PPAT_UNCACHED_INDEX		(_PAGE_PWT | _PAGE_PCD)
+#define PPAT_CACHED_PDE_INDEX		0 /* WB LLC */
+#define PPAT_CACHED_INDEX		_PAGE_PAT /* WB LLCeLLC */
+#define PPAT_DISPLAY_ELLC_INDEX		_PAGE_PCD /* WT eLLC */
+
+#define CHV_PPAT_SNOOP			(1<<6)
+#define GEN8_PPAT_AGE(x)		(x<<4)
+#define GEN8_PPAT_LLCeLLC		(3<<2)
+#define GEN8_PPAT_LLCELLC		(2<<2)
+#define GEN8_PPAT_LLC			(1<<2)
+#define GEN8_PPAT_WB			(3<<0)
+#define GEN8_PPAT_WT			(2<<0)
+#define GEN8_PPAT_WC			(1<<0)
+#define GEN8_PPAT_UC			(0<<0)
+#define GEN8_PPAT_ELLC_OVERRIDE		(0<<2)
+#define GEN8_PPAT(i, x)			((uint64_t) (x) << ((i) * 8))
+
+enum i915_ggtt_view_type {
+	I915_GGTT_VIEW_NORMAL = 0,
+	I915_GGTT_VIEW_ROTATED,
+	I915_GGTT_VIEW_PARTIAL,
+};
+
+struct intel_rotation_info {
+	unsigned int uv_offset;
+	uint32_t pixel_format;
+	unsigned int uv_start_page;
+	struct {
+		/* tiles */
+		unsigned int width, height;
+	} plane[2];
+};
+
+struct i915_ggtt_view {
+	enum i915_ggtt_view_type type;
+
+	union {
+		struct {
+			u64 offset;
+			unsigned int size;
+		} partial;
+		struct intel_rotation_info rotated;
+	} params;
+
+	struct sg_table *pages;
+};
+
+extern const struct i915_ggtt_view i915_ggtt_view_normal;
+extern const struct i915_ggtt_view i915_ggtt_view_rotated;
+
+enum i915_cache_level;
+
+/**
+ * A VMA represents a GEM BO that is bound into an address space. Therefore, a
+ * VMA's presence cannot be guaranteed before binding, or after unbinding the
+ * object into/from the address space.
+ *
+ * To make things as simple as possible (ie. no refcounting), a VMA's lifetime
+ * will always be <= an objects lifetime. So object refcounting should cover us.
+ */
+struct i915_vma {
+	struct drm_mm_node node;
+	struct drm_i915_gem_object *obj;
+	struct i915_address_space *vm;
+
+	/** Flags and address space this VMA is bound to */
+#define GLOBAL_BIND	(1<<0)
+#define LOCAL_BIND	(1<<1)
+	unsigned int bound : 4;
+	bool is_ggtt : 1;
+
+	/**
+	 * Support different GGTT views into the same object.
+	 * This means there can be multiple VMA mappings per object and per VM.
+	 * i915_ggtt_view_type is used to distinguish between those entries.
+	 * The default one of zero (I915_GGTT_VIEW_NORMAL) is default and also
+	 * assumed in GEM functions which take no ggtt view parameter.
+	 */
+	struct i915_ggtt_view ggtt_view;
+
+	/** This object's place on the active/inactive lists */
+	struct list_head vm_link;
+
+	struct list_head obj_link; /* Link in the object's VMA list */
+
+	/** This vma's place in the batchbuffer or on the eviction list */
+	struct list_head exec_list;
+
+	/**
+	 * Used for performing relocations during execbuffer insertion.
+	 */
+	struct hlist_node exec_node;
+	unsigned long exec_handle;
+	struct drm_i915_gem_exec_object2 *exec_entry;
+
+	/**
+	 * How many users have pinned this object in GTT space. The following
+	 * users can each hold at most one reference: pwrite/pread, execbuffer
+	 * (objects are not allowed multiple times for the same batchbuffer),
+	 * and the framebuffer code. When switching/pageflipping, the
+	 * framebuffer code has at most two buffers pinned per crtc.
+	 *
+	 * In the worst case this is 1 + 1 + 1 + 2*2 = 7. That would fit into 3
+	 * bits with absolutely no headroom. So use 4 bits. */
+	unsigned int pin_count:4;
+#define DRM_I915_GEM_OBJECT_MAX_PIN_COUNT 0xf
+};
+
+struct i915_page_dma {
+	struct page *page;
+	union {
+		dma_addr_t daddr;
+
+		/* For gen6/gen7 only. This is the offset in the GGTT
+		 * where the page directory entries for PPGTT begin
+		 */
+		uint32_t ggtt_offset;
+	};
+};
+
+#define px_base(px) (&(px)->base)
+#define px_page(px) (px_base(px)->page)
+#define px_dma(px) (px_base(px)->daddr)
+
+struct i915_page_scratch {
+	struct i915_page_dma base;
+};
+
+struct i915_page_table {
+	struct i915_page_dma base;
+
+	unsigned long *used_ptes;
+};
+
+struct i915_page_directory {
+	struct i915_page_dma base;
+
+	unsigned long *used_pdes;
+	struct i915_page_table *page_table[I915_PDES]; /* PDEs */
+};
+
+struct i915_page_directory_pointer {
+	struct i915_page_dma base;
+
+	unsigned long *used_pdpes;
+	struct i915_page_directory **page_directory;
+};
+
+struct i915_pml4 {
+	struct i915_page_dma base;
+
+	DECLARE_BITMAP(used_pml4es, GEN8_PML4ES_PER_PML4);
+	struct i915_page_directory_pointer *pdps[GEN8_PML4ES_PER_PML4];
+};
+
+struct i915_address_space {
+	struct drm_mm mm;
+	struct drm_device *dev;
+	struct list_head global_link;
+	u64 start;		/* Start offset always 0 for dri2 */
+	u64 total;		/* size addr space maps (ex. 2GB for ggtt) */
+
+	bool is_ggtt;
+
+	struct i915_page_scratch *scratch_page;
+	struct i915_page_table *scratch_pt;
+	struct i915_page_directory *scratch_pd;
+	struct i915_page_directory_pointer *scratch_pdp; /* GEN8+ & 48b PPGTT */
+
+	/**
+	 * List of objects currently involved in rendering.
+	 *
+	 * Includes buffers having the contents of their GPU caches
+	 * flushed, not necessarily primitives. last_read_req
+	 * represents when the rendering involved will be completed.
+	 *
+	 * A reference is held on the buffer while on this list.
+	 */
+	struct list_head active_list;
+
+	/**
+	 * LRU list of objects which are not in the ringbuffer and
+	 * are ready to unbind, but are still in the GTT.
+	 *
+	 * last_read_req is NULL while an object is in this list.
+	 *
+	 * A reference is not held on the buffer while on this list,
+	 * as merely being GTT-bound shouldn't prevent its being
+	 * freed, and we'll pull it off the list in the free path.
+	 */
+	struct list_head inactive_list;
+
+	/* FIXME: Need a more generic return type */
+	gen6_pte_t (*pte_encode)(dma_addr_t addr,
+				 enum i915_cache_level level,
+				 bool valid, u32 flags); /* Create a valid PTE */
+	/* flags for pte_encode */
+#define PTE_READ_ONLY	(1<<0)
+	int (*allocate_va_range)(struct i915_address_space *vm,
+				 uint64_t start,
+				 uint64_t length);
+	void (*clear_range)(struct i915_address_space *vm,
+			    uint64_t start,
+			    uint64_t length,
+			    bool use_scratch);
+	void (*insert_entries)(struct i915_address_space *vm,
+			       struct sg_table *st,
+			       uint64_t start,
+			       enum i915_cache_level cache_level, u32 flags);
+	void (*cleanup)(struct i915_address_space *vm);
+	/** Unmap an object from an address space. This usually consists of
+	 * setting the valid PTE entries to a reserved scratch page. */
+	void (*unbind_vma)(struct i915_vma *vma);
+	/* Map an object into an address space with the given cache flags. */
+	int (*bind_vma)(struct i915_vma *vma,
+			enum i915_cache_level cache_level,
+			u32 flags);
+};
+
+#define i915_is_ggtt(V) ((V)->is_ggtt)
+
+/* The Graphics Translation Table is the way in which GEN hardware translates a
+ * Graphics Virtual Address into a Physical Address. In addition to the normal
+ * collateral associated with any va->pa translations GEN hardware also has a
+ * portion of the GTT which can be mapped by the CPU and remain both coherent
+ * and correct (in cases like swizzling). That region is referred to as GMADR in
+ * the spec.
+ */
+struct i915_ggtt {
+	struct i915_address_space base;
+
+	size_t stolen_size;		/* Total size of stolen memory */
+	size_t stolen_usable_size;	/* Total size minus BIOS reserved */
+	size_t stolen_reserved_base;
+	size_t stolen_reserved_size;
+	size_t size;			/* Total size of Global GTT */
+	u64 mappable_end;		/* End offset that we can CPU map */
+	struct io_mapping *mappable;	/* Mapping to our CPU mappable region */
+	phys_addr_t mappable_base;	/* PA of our GMADR */
+
+	/** "Graphics Stolen Memory" holds the global PTEs */
+	void __iomem *gsm;
+
+	bool do_idle_maps;
+
+	int mtrr;
+
+	int (*probe)(struct i915_ggtt *ggtt);
+};
+
+struct i915_hw_ppgtt {
+	struct i915_address_space base;
+	struct kref ref;
+	struct drm_mm_node node;
+	unsigned long pd_dirty_rings;
+	union {
+		struct i915_pml4 pml4;		/* GEN8+ & 48b PPGTT */
+		struct i915_page_directory_pointer pdp;	/* GEN8+ */
+		struct i915_page_directory pd;		/* GEN6-7 */
+	};
+
+	struct drm_i915_file_private *file_priv;
+
+	gen6_pte_t __iomem *pd_addr;
+
+	int (*enable)(struct i915_hw_ppgtt *ppgtt);
+	int (*switch_mm)(struct i915_hw_ppgtt *ppgtt,
+			 struct drm_i915_gem_request *req);
+	void (*debug_dump)(struct i915_hw_ppgtt *ppgtt, struct seq_file *m);
+};
+
+/* For each pde iterates over every pde between from start until start + length.
+ * If start, and start+length are not perfectly divisible, the macro will round
+ * down, and up as needed. The macro modifies pde, start, and length. Dev is
+ * only used to differentiate shift values. Temp is temp.  On gen6/7, start = 0,
+ * and length = 2G effectively iterates over every PDE in the system.
+ *
+ * XXX: temp is not actually needed, but it saves doing the ALIGN operation.
+ */
+#define gen6_for_each_pde(pt, pd, start, length, temp, iter) \
+	for (iter = gen6_pde_index(start); \
+	     length > 0 && iter < I915_PDES ? \
+			(pt = (pd)->page_table[iter]), 1 : 0; \
+	     iter++, \
+	     temp = ALIGN(start+1, 1 << GEN6_PDE_SHIFT) - start, \
+	     temp = min_t(unsigned, temp, length), \
+	     start += temp, length -= temp)
+
+#define gen6_for_all_pdes(pt, ppgtt, iter)  \
+	for (iter = 0;		\
+	     pt = ppgtt->pd.page_table[iter], iter < I915_PDES;	\
+	     iter++)
+
+static inline uint32_t i915_pte_index(uint64_t address, uint32_t pde_shift)
+{
+	const uint32_t mask = NUM_PTE(pde_shift) - 1;
+
+	return (address >> PAGE_SHIFT) & mask;
+}
+
+/* Helper to counts the number of PTEs within the given length. This count
+ * does not cross a page table boundary, so the max value would be
+ * GEN6_PTES for GEN6, and GEN8_PTES for GEN8.
+*/
+static inline uint32_t i915_pte_count(uint64_t addr, size_t length,
+				      uint32_t pde_shift)
+{
+	const uint64_t mask = ~((1ULL << pde_shift) - 1);
+	uint64_t end;
+
+	WARN_ON(length == 0);
+	WARN_ON(offset_in_page(addr|length));
+
+	end = addr + length;
+
+	if ((addr & mask) != (end & mask))
+		return NUM_PTE(pde_shift) - i915_pte_index(addr, pde_shift);
+
+	return i915_pte_index(end, pde_shift) - i915_pte_index(addr, pde_shift);
+}
+
+static inline uint32_t i915_pde_index(uint64_t addr, uint32_t shift)
+{
+	return (addr >> shift) & I915_PDE_MASK;
+}
+
+static inline uint32_t gen6_pte_index(uint32_t addr)
+{
+	return i915_pte_index(addr, GEN6_PDE_SHIFT);
+}
+
+static inline size_t gen6_pte_count(uint32_t addr, uint32_t length)
+{
+	return i915_pte_count(addr, length, GEN6_PDE_SHIFT);
+}
+
+static inline uint32_t gen6_pde_index(uint32_t addr)
+{
+	return i915_pde_index(addr, GEN6_PDE_SHIFT);
+}
+
+/* Equivalent to the gen6 version, For each pde iterates over every pde
+ * between from start until start + length. On gen8+ it simply iterates
+ * over every page directory entry in a page directory.
+ */
+#define gen8_for_each_pde(pt, pd, start, length, iter)			\
+	for (iter = gen8_pde_index(start);				\
+	     length > 0 && iter < I915_PDES &&				\
+		(pt = (pd)->page_table[iter], true);			\
+	     ({ u64 temp = ALIGN(start+1, 1 << GEN8_PDE_SHIFT);		\
+		    temp = min(temp - start, length);			\
+		    start += temp, length -= temp; }), ++iter)
+
+#define gen8_for_each_pdpe(pd, pdp, start, length, iter)		\
+	for (iter = gen8_pdpe_index(start);				\
+	     length > 0 && iter < I915_PDPES_PER_PDP(dev) &&		\
+		(pd = (pdp)->page_directory[iter], true);		\
+	     ({ u64 temp = ALIGN(start+1, 1 << GEN8_PDPE_SHIFT);	\
+		    temp = min(temp - start, length);			\
+		    start += temp, length -= temp; }), ++iter)
+
+#define gen8_for_each_pml4e(pdp, pml4, start, length, iter)		\
+	for (iter = gen8_pml4e_index(start);				\
+	     length > 0 && iter < GEN8_PML4ES_PER_PML4 &&		\
+		(pdp = (pml4)->pdps[iter], true);			\
+	     ({ u64 temp = ALIGN(start+1, 1ULL << GEN8_PML4E_SHIFT);	\
+		    temp = min(temp - start, length);			\
+		    start += temp, length -= temp; }), ++iter)
+
+static inline uint32_t gen8_pte_index(uint64_t address)
+{
+	return i915_pte_index(address, GEN8_PDE_SHIFT);
+}
+
+static inline uint32_t gen8_pde_index(uint64_t address)
+{
+	return i915_pde_index(address, GEN8_PDE_SHIFT);
+}
+
+static inline uint32_t gen8_pdpe_index(uint64_t address)
+{
+	return (address >> GEN8_PDPE_SHIFT) & GEN8_PDPE_MASK;
+}
+
+static inline uint32_t gen8_pml4e_index(uint64_t address)
+{
+	return (address >> GEN8_PML4E_SHIFT) & GEN8_PML4E_MASK;
+}
+
+static inline size_t gen8_pte_count(uint64_t address, uint64_t length)
+{
+	return i915_pte_count(address, length, GEN8_PDE_SHIFT);
+}
+
+static inline dma_addr_t
+i915_page_dir_dma_addr(const struct i915_hw_ppgtt *ppgtt, const unsigned n)
+{
+	return test_bit(n, ppgtt->pdp.used_pdpes) ?
+		px_dma(ppgtt->pdp.page_directory[n]) :
+		px_dma(ppgtt->base.scratch_pd);
+}
+
+int i915_ggtt_init_hw(struct drm_device *dev);
+int i915_ggtt_enable_hw(struct drm_device *dev);
+void i915_gem_init_ggtt(struct drm_device *dev);
+void i915_ggtt_cleanup_hw(struct drm_device *dev);
+
+int i915_ppgtt_init(struct drm_device *dev, struct i915_hw_ppgtt *ppgtt);
+int i915_ppgtt_init_hw(struct drm_device *dev);
+int i915_ppgtt_init_ring(struct drm_i915_gem_request *req);
+void i915_ppgtt_release(struct kref *kref);
+struct i915_hw_ppgtt *i915_ppgtt_create(struct drm_device *dev,
+					struct drm_i915_file_private *fpriv);
+static inline void i915_ppgtt_get(struct i915_hw_ppgtt *ppgtt)
+{
+	if (ppgtt)
+		kref_get(&ppgtt->ref);
+}
+static inline void i915_ppgtt_put(struct i915_hw_ppgtt *ppgtt)
+{
+	if (ppgtt)
+		kref_put(&ppgtt->ref, i915_ppgtt_release);
+}
+
+void i915_check_and_clear_faults(struct drm_device *dev);
+void i915_gem_suspend_gtt_mappings(struct drm_device *dev);
+void i915_gem_restore_gtt_mappings(struct drm_device *dev);
+
+int __must_check i915_gem_gtt_prepare_object(struct drm_i915_gem_object *obj);
+void i915_gem_gtt_finish_object(struct drm_i915_gem_object *obj);
+
+static inline bool
+i915_ggtt_view_equal(const struct i915_ggtt_view *a,
+                     const struct i915_ggtt_view *b)
+{
+	if (WARN_ON(!a || !b))
+		return false;
+
+	if (a->type != b->type)
+		return false;
+	if (a->type != I915_GGTT_VIEW_NORMAL)
+		return !memcmp(&a->params, &b->params, sizeof(a->params));
+	return true;
+}
+
+size_t
+i915_ggtt_view_size(struct drm_i915_gem_object *obj,
+		    const struct i915_ggtt_view *view);
+
+#endif
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/i915/i915_gem_render_state.c
@@ -0,0 +1,229 @@
+/*
+ * Copyright © 2014 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Mika Kuoppala <mika.kuoppala@intel.com>
+ *
+ */
+
+#include "i915_drv.h"
+#include "intel_renderstate.h"
+
+static const struct intel_renderstate_rodata *
+render_state_get_rodata(struct drm_device *dev, const int gen)
+{
+	switch (gen) {
+	case 6:
+		return &gen6_null_state;
+	case 7:
+		return &gen7_null_state;
+	case 8:
+		return &gen8_null_state;
+	case 9:
+		return &gen9_null_state;
+	}
+
+	return NULL;
+}
+
+static int render_state_init(struct render_state *so, struct drm_device *dev)
+{
+	int ret;
+
+	so->gen = INTEL_INFO(dev)->gen;
+	so->rodata = render_state_get_rodata(dev, so->gen);
+	if (so->rodata == NULL)
+		return 0;
+
+	if (so->rodata->batch_items * 4 > 4096)
+		return -EINVAL;
+
+	so->obj = i915_gem_alloc_object(dev, 4096);
+	if (so->obj == NULL)
+		return -ENOMEM;
+
+	ret = i915_gem_obj_ggtt_pin(so->obj, 4096, 0);
+	if (ret)
+		goto free_gem;
+
+	so->ggtt_offset = i915_gem_obj_ggtt_offset(so->obj);
+	return 0;
+
+free_gem:
+	drm_gem_object_unreference(&so->obj->base);
+	return ret;
+}
+
+/*
+ * Macro to add commands to auxiliary batch.
+ * This macro only checks for page overflow before inserting the commands,
+ * this is sufficient as the null state generator makes the final batch
+ * with two passes to build command and state separately. At this point
+ * the size of both are known and it compacts them by relocating the state
+ * right after the commands taking care of aligment so we should sufficient
+ * space below them for adding new commands.
+ */
+#define OUT_BATCH(batch, i, val)				\
+	do {							\
+		if (WARN_ON((i) >= PAGE_SIZE / sizeof(u32))) {	\
+			ret = -ENOSPC;				\
+			goto err_out;				\
+		}						\
+		(batch)[(i)++] = (val);				\
+	} while(0)
+
+static int render_state_setup(struct render_state *so)
+{
+	const struct intel_renderstate_rodata *rodata = so->rodata;
+	unsigned int i = 0, reloc_index = 0;
+	struct page *page;
+	u32 *d;
+	int ret;
+
+	ret = i915_gem_object_set_to_cpu_domain(so->obj, true);
+	if (ret)
+		return ret;
+
+	page = i915_gem_object_get_dirty_page(so->obj, 0);
+	d = kmap(page);
+
+	while (i < rodata->batch_items) {
+		u32 s = rodata->batch[i];
+
+		if (i * 4  == rodata->reloc[reloc_index]) {
+			u64 r = s + so->ggtt_offset;
+			s = lower_32_bits(r);
+			if (so->gen >= 8) {
+				if (i + 1 >= rodata->batch_items ||
+				    rodata->batch[i + 1] != 0) {
+					ret = -EINVAL;
+					goto err_out;
+				}
+
+				d[i++] = s;
+				s = upper_32_bits(r);
+			}
+
+			reloc_index++;
+		}
+
+		d[i++] = s;
+	}
+
+	while (i % CACHELINE_DWORDS)
+		OUT_BATCH(d, i, MI_NOOP);
+
+	so->aux_batch_offset = i * sizeof(u32);
+
+	OUT_BATCH(d, i, MI_BATCH_BUFFER_END);
+	so->aux_batch_size = (i * sizeof(u32)) - so->aux_batch_offset;
+
+	/*
+	 * Since we are sending length, we need to strictly conform to
+	 * all requirements. For Gen2 this must be a multiple of 8.
+	 */
+	so->aux_batch_size = ALIGN(so->aux_batch_size, 8);
+
+	kunmap(page);
+
+	ret = i915_gem_object_set_to_gtt_domain(so->obj, false);
+	if (ret)
+		return ret;
+
+	if (rodata->reloc[reloc_index] != -1) {
+		DRM_ERROR("only %d relocs resolved\n", reloc_index);
+		return -EINVAL;
+	}
+
+	return 0;
+
+err_out:
+	kunmap(page);
+	return ret;
+}
+
+#undef OUT_BATCH
+
+void i915_gem_render_state_fini(struct render_state *so)
+{
+	i915_gem_object_ggtt_unpin(so->obj);
+	drm_gem_object_unreference(&so->obj->base);
+}
+
+int i915_gem_render_state_prepare(struct intel_engine_cs *engine,
+				  struct render_state *so)
+{
+	int ret;
+
+	if (WARN_ON(engine->id != RCS))
+		return -ENOENT;
+
+	ret = render_state_init(so, engine->dev);
+	if (ret)
+		return ret;
+
+	if (so->rodata == NULL)
+		return 0;
+
+	ret = render_state_setup(so);
+	if (ret) {
+		i915_gem_render_state_fini(so);
+		return ret;
+	}
+
+	return 0;
+}
+
+int i915_gem_render_state_init(struct drm_i915_gem_request *req)
+{
+	struct render_state so;
+	int ret;
+
+	ret = i915_gem_render_state_prepare(req->engine, &so);
+	if (ret)
+		return ret;
+
+	if (so.rodata == NULL)
+		return 0;
+
+	ret = req->engine->dispatch_execbuffer(req, so.ggtt_offset,
+					     so.rodata->batch_items * 4,
+					     I915_DISPATCH_SECURE);
+	if (ret)
+		goto out;
+
+	if (so.aux_batch_size > 8) {
+		ret = req->engine->dispatch_execbuffer(req,
+						     (so.ggtt_offset +
+						      so.aux_batch_offset),
+						     so.aux_batch_size,
+						     I915_DISPATCH_SECURE);
+		if (ret)
+			goto out;
+	}
+
+	i915_vma_move_to_active(i915_gem_obj_to_ggtt(so.obj), req);
+
+out:
+	i915_gem_render_state_fini(&so);
+	return ret;
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/i915/i915_gem_render_state.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright © 2014 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef _I915_GEM_RENDER_STATE_H_
+#define _I915_GEM_RENDER_STATE_H_
+
+#include <linux/types.h>
+
+struct intel_renderstate_rodata {
+	const u32 *reloc;
+	const u32 *batch;
+	const u32 batch_items;
+};
+
+struct render_state {
+	const struct intel_renderstate_rodata *rodata;
+	struct drm_i915_gem_object *obj;
+	u64 ggtt_offset;
+	int gen;
+	u32 aux_batch_size;
+	u32 aux_batch_offset;
+};
+
+int i915_gem_render_state_init(struct drm_i915_gem_request *req);
+void i915_gem_render_state_fini(struct render_state *so);
+int i915_gem_render_state_prepare(struct intel_engine_cs *engine,
+				  struct render_state *so);
+
+#endif /* _I915_GEM_RENDER_STATE_H_ */
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/i915/i915_gem_shrinker.c
@@ -0,0 +1,386 @@
+/*
+ * Copyright © 2008-2015 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ */
+
+#include <linux/oom.h>
+#include <linux/shmem_fs.h>
+#include <linux/slab.h>
+#include <linux/swap.h>
+#include <linux/pci.h>
+#include <linux/dma-buf.h>
+#include <drm/drmP.h>
+#include <drm/i915_drm.h>
+
+#include "i915_drv.h"
+#include "i915_trace.h"
+
+static bool mutex_is_locked_by(struct mutex *mutex, struct task_struct *task)
+{
+	if (!mutex_is_locked(mutex))
+		return false;
+
+#if defined(CONFIG_DEBUG_MUTEXES) || defined(CONFIG_MUTEX_SPIN_ON_OWNER)
+	return mutex->owner == task;
+#else
+	/* Since UP may be pre-empted, we cannot assume that we own the lock */
+	return false;
+#endif
+}
+
+static int num_vma_bound(struct drm_i915_gem_object *obj)
+{
+	struct i915_vma *vma;
+	int count = 0;
+
+	list_for_each_entry(vma, &obj->vma_list, obj_link) {
+		if (drm_mm_node_allocated(&vma->node))
+			count++;
+		if (vma->pin_count)
+			count++;
+	}
+
+	return count;
+}
+
+static bool swap_available(void)
+{
+	return get_nr_swap_pages() > 0;
+}
+
+static bool can_release_pages(struct drm_i915_gem_object *obj)
+{
+	/* Only report true if by unbinding the object and putting its pages
+	 * we can actually make forward progress towards freeing physical
+	 * pages.
+	 *
+	 * If the pages are pinned for any other reason than being bound
+	 * to the GPU, simply unbinding from the GPU is not going to succeed
+	 * in releasing our pin count on the pages themselves.
+	 */
+	if (obj->pages_pin_count != num_vma_bound(obj))
+		return false;
+
+	/* We can only return physical pages to the system if we can either
+	 * discard the contents (because the user has marked them as being
+	 * purgeable) or if we can move their contents out to swap.
+	 */
+	return swap_available() || obj->madv == I915_MADV_DONTNEED;
+}
+
+/**
+ * i915_gem_shrink - Shrink buffer object caches
+ * @dev_priv: i915 device
+ * @target: amount of memory to make available, in pages
+ * @flags: control flags for selecting cache types
+ *
+ * This function is the main interface to the shrinker. It will try to release
+ * up to @target pages of main memory backing storage from buffer objects.
+ * Selection of the specific caches can be done with @flags. This is e.g. useful
+ * when purgeable objects should be removed from caches preferentially.
+ *
+ * Note that it's not guaranteed that released amount is actually available as
+ * free system memory - the pages might still be in-used to due to other reasons
+ * (like cpu mmaps) or the mm core has reused them before we could grab them.
+ * Therefore code that needs to explicitly shrink buffer objects caches (e.g. to
+ * avoid deadlocks in memory reclaim) must fall back to i915_gem_shrink_all().
+ *
+ * Also note that any kind of pinning (both per-vma address space pins and
+ * backing storage pins at the buffer object level) result in the shrinker code
+ * having to skip the object.
+ *
+ * Returns:
+ * The number of pages of backing storage actually released.
+ */
+unsigned long
+i915_gem_shrink(struct drm_i915_private *dev_priv,
+		unsigned long target, unsigned flags)
+{
+	const struct {
+		struct list_head *list;
+		unsigned int bit;
+	} phases[] = {
+		{ &dev_priv->mm.unbound_list, I915_SHRINK_UNBOUND },
+		{ &dev_priv->mm.bound_list, I915_SHRINK_BOUND },
+		{ NULL, 0 },
+	}, *phase;
+	unsigned long count = 0;
+
+	trace_i915_gem_shrink(dev_priv, target, flags);
+	i915_gem_retire_requests(dev_priv->dev);
+
+	/*
+	 * As we may completely rewrite the (un)bound list whilst unbinding
+	 * (due to retiring requests) we have to strictly process only
+	 * one element of the list at the time, and recheck the list
+	 * on every iteration.
+	 *
+	 * In particular, we must hold a reference whilst removing the
+	 * object as we may end up waiting for and/or retiring the objects.
+	 * This might release the final reference (held by the active list)
+	 * and result in the object being freed from under us. This is
+	 * similar to the precautions the eviction code must take whilst
+	 * removing objects.
+	 *
+	 * Also note that although these lists do not hold a reference to
+	 * the object we can safely grab one here: The final object
+	 * unreferencing and the bound_list are both protected by the
+	 * dev->struct_mutex and so we won't ever be able to observe an
+	 * object on the bound_list with a reference count equals 0.
+	 */
+	for (phase = phases; phase->list; phase++) {
+		struct list_head still_in_list;
+
+		if ((flags & phase->bit) == 0)
+			continue;
+
+		INIT_LIST_HEAD(&still_in_list);
+		while (count < target && !list_empty(phase->list)) {
+			struct drm_i915_gem_object *obj;
+			struct i915_vma *vma, *v;
+
+			obj = list_first_entry(phase->list,
+					       typeof(*obj), global_list);
+			list_move_tail(&obj->global_list, &still_in_list);
+
+			if (flags & I915_SHRINK_PURGEABLE &&
+			    obj->madv != I915_MADV_DONTNEED)
+				continue;
+
+			if ((flags & I915_SHRINK_ACTIVE) == 0 && obj->active)
+				continue;
+
+			if (!can_release_pages(obj))
+				continue;
+
+			drm_gem_object_reference(&obj->base);
+
+			/* For the unbound phase, this should be a no-op! */
+			list_for_each_entry_safe(vma, v,
+						 &obj->vma_list, obj_link)
+				if (i915_vma_unbind(vma))
+					break;
+
+			if (i915_gem_object_put_pages(obj) == 0)
+				count += obj->base.size >> PAGE_SHIFT;
+
+			drm_gem_object_unreference(&obj->base);
+		}
+		list_splice(&still_in_list, phase->list);
+	}
+
+	i915_gem_retire_requests(dev_priv->dev);
+
+	return count;
+}
+
+/**
+ * i915_gem_shrink_all - Shrink buffer object caches completely
+ * @dev_priv: i915 device
+ *
+ * This is a simple wraper around i915_gem_shrink() to aggressively shrink all
+ * caches completely. It also first waits for and retires all outstanding
+ * requests to also be able to release backing storage for active objects.
+ *
+ * This should only be used in code to intentionally quiescent the gpu or as a
+ * last-ditch effort when memory seems to have run out.
+ *
+ * Returns:
+ * The number of pages of backing storage actually released.
+ */
+unsigned long i915_gem_shrink_all(struct drm_i915_private *dev_priv)
+{
+	return i915_gem_shrink(dev_priv, -1UL,
+			       I915_SHRINK_BOUND |
+			       I915_SHRINK_UNBOUND |
+			       I915_SHRINK_ACTIVE);
+}
+
+static bool i915_gem_shrinker_lock(struct drm_device *dev, bool *unlock)
+{
+	if (!mutex_trylock(&dev->struct_mutex)) {
+		if (!mutex_is_locked_by(&dev->struct_mutex, current))
+			return false;
+
+		if (to_i915(dev)->mm.shrinker_no_lock_stealing)
+			return false;
+
+		*unlock = false;
+	} else
+		*unlock = true;
+
+	return true;
+}
+
+static unsigned long
+i915_gem_shrinker_count(struct shrinker *shrinker, struct shrink_control *sc)
+{
+	struct drm_i915_private *dev_priv =
+		container_of(shrinker, struct drm_i915_private, mm.shrinker);
+	struct drm_device *dev = dev_priv->dev;
+	struct drm_i915_gem_object *obj;
+	unsigned long count;
+	bool unlock;
+
+	if (!i915_gem_shrinker_lock(dev, &unlock))
+		return 0;
+
+	count = 0;
+	list_for_each_entry(obj, &dev_priv->mm.unbound_list, global_list)
+		if (can_release_pages(obj))
+			count += obj->base.size >> PAGE_SHIFT;
+
+	list_for_each_entry(obj, &dev_priv->mm.bound_list, global_list) {
+		if (!obj->active && can_release_pages(obj))
+			count += obj->base.size >> PAGE_SHIFT;
+	}
+
+	if (unlock)
+		mutex_unlock(&dev->struct_mutex);
+
+	return count;
+}
+
+static unsigned long
+i915_gem_shrinker_scan(struct shrinker *shrinker, struct shrink_control *sc)
+{
+	struct drm_i915_private *dev_priv =
+		container_of(shrinker, struct drm_i915_private, mm.shrinker);
+	struct drm_device *dev = dev_priv->dev;
+	unsigned long freed;
+	bool unlock;
+
+	if (!i915_gem_shrinker_lock(dev, &unlock))
+		return SHRINK_STOP;
+
+	freed = i915_gem_shrink(dev_priv,
+				sc->nr_to_scan,
+				I915_SHRINK_BOUND |
+				I915_SHRINK_UNBOUND |
+				I915_SHRINK_PURGEABLE);
+	if (freed < sc->nr_to_scan)
+		freed += i915_gem_shrink(dev_priv,
+					 sc->nr_to_scan - freed,
+					 I915_SHRINK_BOUND |
+					 I915_SHRINK_UNBOUND);
+	if (unlock)
+		mutex_unlock(&dev->struct_mutex);
+
+	return freed;
+}
+
+static int
+i915_gem_shrinker_oom(struct notifier_block *nb, unsigned long event, void *ptr)
+{
+	struct drm_i915_private *dev_priv =
+		container_of(nb, struct drm_i915_private, mm.oom_notifier);
+	struct drm_device *dev = dev_priv->dev;
+	struct drm_i915_gem_object *obj;
+	unsigned long timeout = msecs_to_jiffies(5000) + 1;
+	unsigned long pinned, bound, unbound, freed_pages;
+	bool was_interruptible;
+	bool unlock;
+
+	while (!i915_gem_shrinker_lock(dev, &unlock) && --timeout) {
+		schedule_timeout_killable(1);
+		if (fatal_signal_pending(current))
+			return NOTIFY_DONE;
+	}
+	if (timeout == 0) {
+		pr_err("Unable to purge GPU memory due lock contention.\n");
+		return NOTIFY_DONE;
+	}
+
+	was_interruptible = dev_priv->mm.interruptible;
+	dev_priv->mm.interruptible = false;
+
+	freed_pages = i915_gem_shrink_all(dev_priv);
+
+	dev_priv->mm.interruptible = was_interruptible;
+
+	/* Because we may be allocating inside our own driver, we cannot
+	 * assert that there are no objects with pinned pages that are not
+	 * being pointed to by hardware.
+	 */
+	unbound = bound = pinned = 0;
+	list_for_each_entry(obj, &dev_priv->mm.unbound_list, global_list) {
+		if (!obj->base.filp) /* not backed by a freeable object */
+			continue;
+
+		if (obj->pages_pin_count)
+			pinned += obj->base.size;
+		else
+			unbound += obj->base.size;
+	}
+	list_for_each_entry(obj, &dev_priv->mm.bound_list, global_list) {
+		if (!obj->base.filp)
+			continue;
+
+		if (obj->pages_pin_count > num_vma_bound(obj))
+			pinned += obj->base.size;
+		else
+			bound += obj->base.size;
+	}
+
+	if (unlock)
+		mutex_unlock(&dev->struct_mutex);
+
+	if (freed_pages || unbound || bound)
+		pr_info("Purging GPU memory, %lu bytes freed, %lu bytes still pinned.\n",
+			freed_pages << PAGE_SHIFT, pinned);
+	if (unbound || bound)
+		pr_err("%lu and %lu bytes still available in the "
+		       "bound and unbound GPU page lists.\n",
+		       bound, unbound);
+
+	*(unsigned long *)ptr += freed_pages;
+	return NOTIFY_DONE;
+}
+
+/**
+ * i915_gem_shrinker_init - Initialize i915 shrinker
+ * @dev_priv: i915 device
+ *
+ * This function registers and sets up the i915 shrinker and OOM handler.
+ */
+void i915_gem_shrinker_init(struct drm_i915_private *dev_priv)
+{
+	dev_priv->mm.shrinker.scan_objects = i915_gem_shrinker_scan;
+	dev_priv->mm.shrinker.count_objects = i915_gem_shrinker_count;
+	dev_priv->mm.shrinker.seeks = DEFAULT_SEEKS;
+	WARN_ON(register_shrinker(&dev_priv->mm.shrinker));
+
+	dev_priv->mm.oom_notifier.notifier_call = i915_gem_shrinker_oom;
+	WARN_ON(register_oom_notifier(&dev_priv->mm.oom_notifier));
+}
+
+/**
+ * i915_gem_shrinker_cleanup - Clean up i915 shrinker
+ * @dev_priv: i915 device
+ *
+ * This function unregisters the i915 shrinker and OOM handler.
+ */
+void i915_gem_shrinker_cleanup(struct drm_i915_private *dev_priv)
+{
+	WARN_ON(unregister_oom_notifier(&dev_priv->mm.oom_notifier));
+	unregister_shrinker(&dev_priv->mm.shrinker);
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/i915/i915_gem_stolen.c
@@ -0,0 +1,721 @@
+/*
+ * Copyright © 2008-2012 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Eric Anholt <eric@anholt.net>
+ *    Chris Wilson <chris@chris-wilson.co.uk>
+ *
+ */
+
+#include <drm/drmP.h>
+#include <drm/i915_drm.h>
+#include "i915_drv.h"
+
+#define KB(x) ((x) * 1024)
+#define MB(x) (KB(x) * 1024)
+
+/*
+ * The BIOS typically reserves some of the system's memory for the exclusive
+ * use of the integrated graphics. This memory is no longer available for
+ * use by the OS and so the user finds that his system has less memory
+ * available than he put in. We refer to this memory as stolen.
+ *
+ * The BIOS will allocate its framebuffer from the stolen memory. Our
+ * goal is try to reuse that object for our own fbcon which must always
+ * be available for panics. Anything else we can reuse the stolen memory
+ * for is a boon.
+ */
+
+int i915_gem_stolen_insert_node_in_range(struct drm_i915_private *dev_priv,
+					 struct drm_mm_node *node, u64 size,
+					 unsigned alignment, u64 start, u64 end)
+{
+	int ret;
+
+	if (!drm_mm_initialized(&dev_priv->mm.stolen))
+		return -ENODEV;
+
+	/* See the comment at the drm_mm_init() call for more about this check.
+	 * WaSkipStolenMemoryFirstPage:bdw,chv,kbl (incomplete)
+	 */
+	if (start < 4096 && (IS_GEN8(dev_priv) ||
+			     IS_KBL_REVID(dev_priv, 0, KBL_REVID_A0)))
+		start = 4096;
+
+	mutex_lock(&dev_priv->mm.stolen_lock);
+	ret = drm_mm_insert_node_in_range(&dev_priv->mm.stolen, node, size,
+					  alignment, start, end,
+					  DRM_MM_SEARCH_DEFAULT);
+	mutex_unlock(&dev_priv->mm.stolen_lock);
+
+	return ret;
+}
+
+int i915_gem_stolen_insert_node(struct drm_i915_private *dev_priv,
+				struct drm_mm_node *node, u64 size,
+				unsigned alignment)
+{
+	struct i915_ggtt *ggtt = &dev_priv->ggtt;
+
+	return i915_gem_stolen_insert_node_in_range(dev_priv, node, size,
+						    alignment, 0,
+						    ggtt->stolen_usable_size);
+}
+
+void i915_gem_stolen_remove_node(struct drm_i915_private *dev_priv,
+				 struct drm_mm_node *node)
+{
+	mutex_lock(&dev_priv->mm.stolen_lock);
+	drm_mm_remove_node(node);
+	mutex_unlock(&dev_priv->mm.stolen_lock);
+}
+
+static unsigned long i915_stolen_to_physical(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = to_i915(dev);
+	struct i915_ggtt *ggtt = &dev_priv->ggtt;
+	struct resource *r;
+	u32 base;
+
+	/* Almost universally we can find the Graphics Base of Stolen Memory
+	 * at register BSM (0x5c) in the igfx configuration space. On a few
+	 * (desktop) machines this is also mirrored in the bridge device at
+	 * different locations, or in the MCHBAR.
+	 *
+	 * On 865 we just check the TOUD register.
+	 *
+	 * On 830/845/85x the stolen memory base isn't available in any
+	 * register. We need to calculate it as TOM-TSEG_SIZE-stolen_size.
+	 *
+	 */
+	base = 0;
+	if (INTEL_INFO(dev)->gen >= 3) {
+		u32 bsm;
+
+		pci_read_config_dword(dev->pdev, BSM, &bsm);
+
+		base = bsm & BSM_MASK;
+	} else if (IS_I865G(dev)) {
+		u16 toud = 0;
+
+		/*
+		 * FIXME is the graphics stolen memory region
+		 * always at TOUD? Ie. is it always the last
+		 * one to be allocated by the BIOS?
+		 */
+		pci_bus_read_config_word(dev->pdev->bus, PCI_DEVFN(0, 0),
+					 I865_TOUD, &toud);
+
+		base = toud << 16;
+	} else if (IS_I85X(dev)) {
+		u32 tseg_size = 0;
+		u32 tom;
+		u8 tmp;
+
+		pci_bus_read_config_byte(dev->pdev->bus, PCI_DEVFN(0, 0),
+					 I85X_ESMRAMC, &tmp);
+
+		if (tmp & TSEG_ENABLE)
+			tseg_size = MB(1);
+
+		pci_bus_read_config_byte(dev->pdev->bus, PCI_DEVFN(0, 1),
+					 I85X_DRB3, &tmp);
+		tom = tmp * MB(32);
+
+		base = tom - tseg_size - ggtt->stolen_size;
+	} else if (IS_845G(dev)) {
+		u32 tseg_size = 0;
+		u32 tom;
+		u8 tmp;
+
+		pci_bus_read_config_byte(dev->pdev->bus, PCI_DEVFN(0, 0),
+					 I845_ESMRAMC, &tmp);
+
+		if (tmp & TSEG_ENABLE) {
+			switch (tmp & I845_TSEG_SIZE_MASK) {
+			case I845_TSEG_SIZE_512K:
+				tseg_size = KB(512);
+				break;
+			case I845_TSEG_SIZE_1M:
+				tseg_size = MB(1);
+				break;
+			}
+		}
+
+		pci_bus_read_config_byte(dev->pdev->bus, PCI_DEVFN(0, 0),
+					 I830_DRB3, &tmp);
+		tom = tmp * MB(32);
+
+		base = tom - tseg_size - ggtt->stolen_size;
+	} else if (IS_I830(dev)) {
+		u32 tseg_size = 0;
+		u32 tom;
+		u8 tmp;
+
+		pci_bus_read_config_byte(dev->pdev->bus, PCI_DEVFN(0, 0),
+					 I830_ESMRAMC, &tmp);
+
+		if (tmp & TSEG_ENABLE) {
+			if (tmp & I830_TSEG_SIZE_1M)
+				tseg_size = MB(1);
+			else
+				tseg_size = KB(512);
+		}
+
+		pci_bus_read_config_byte(dev->pdev->bus, PCI_DEVFN(0, 0),
+					 I830_DRB3, &tmp);
+		tom = tmp * MB(32);
+
+		base = tom - tseg_size - ggtt->stolen_size;
+	}
+
+	if (base == 0)
+		return 0;
+
+	/* make sure we don't clobber the GTT if it's within stolen memory */
+	if (INTEL_INFO(dev)->gen <= 4 && !IS_G33(dev) && !IS_G4X(dev)) {
+		struct {
+			u32 start, end;
+		} stolen[2] = {
+			{ .start = base, .end = base + ggtt->stolen_size, },
+			{ .start = base, .end = base + ggtt->stolen_size, },
+		};
+		u64 ggtt_start, ggtt_end;
+
+		ggtt_start = I915_READ(PGTBL_CTL);
+		if (IS_GEN4(dev))
+			ggtt_start = (ggtt_start & PGTBL_ADDRESS_LO_MASK) |
+				     (ggtt_start & PGTBL_ADDRESS_HI_MASK) << 28;
+		else
+			ggtt_start &= PGTBL_ADDRESS_LO_MASK;
+		ggtt_end = ggtt_start + ggtt_total_entries(ggtt) * 4;
+
+		if (ggtt_start >= stolen[0].start && ggtt_start < stolen[0].end)
+			stolen[0].end = ggtt_start;
+		if (ggtt_end > stolen[1].start && ggtt_end <= stolen[1].end)
+			stolen[1].start = ggtt_end;
+
+		/* pick the larger of the two chunks */
+		if (stolen[0].end - stolen[0].start >
+		    stolen[1].end - stolen[1].start) {
+			base = stolen[0].start;
+			ggtt->stolen_size = stolen[0].end - stolen[0].start;
+		} else {
+			base = stolen[1].start;
+			ggtt->stolen_size = stolen[1].end - stolen[1].start;
+		}
+
+		if (stolen[0].start != stolen[1].start ||
+		    stolen[0].end != stolen[1].end) {
+			DRM_DEBUG_KMS("GTT within stolen memory at 0x%llx-0x%llx\n",
+				      (unsigned long long)ggtt_start,
+				      (unsigned long long)ggtt_end - 1);
+			DRM_DEBUG_KMS("Stolen memory adjusted to 0x%x-0x%x\n",
+				      base, base + (u32)ggtt->stolen_size - 1);
+		}
+	}
+
+
+	/* Verify that nothing else uses this physical address. Stolen
+	 * memory should be reserved by the BIOS and hidden from the
+	 * kernel. So if the region is already marked as busy, something
+	 * is seriously wrong.
+	 */
+	r = devm_request_mem_region(dev->dev, base, ggtt->stolen_size,
+				    "Graphics Stolen Memory");
+	if (r == NULL) {
+		/*
+		 * One more attempt but this time requesting region from
+		 * base + 1, as we have seen that this resolves the region
+		 * conflict with the PCI Bus.
+		 * This is a BIOS w/a: Some BIOS wrap stolen in the root
+		 * PCI bus, but have an off-by-one error. Hence retry the
+		 * reservation starting from 1 instead of 0.
+		 */
+		r = devm_request_mem_region(dev->dev, base + 1,
+					    ggtt->stolen_size - 1,
+					    "Graphics Stolen Memory");
+		/*
+		 * GEN3 firmware likes to smash pci bridges into the stolen
+		 * range. Apparently this works.
+		 */
+		if (r == NULL && !IS_GEN3(dev)) {
+			DRM_ERROR("conflict detected with stolen region: [0x%08x - 0x%08x]\n",
+				  base, base + (uint32_t)ggtt->stolen_size);
+			base = 0;
+		}
+	}
+
+	return base;
+}
+
+void i915_gem_cleanup_stolen(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	if (!drm_mm_initialized(&dev_priv->mm.stolen))
+		return;
+
+	drm_mm_takedown(&dev_priv->mm.stolen);
+}
+
+static void g4x_get_stolen_reserved(struct drm_i915_private *dev_priv,
+				    unsigned long *base, unsigned long *size)
+{
+	struct i915_ggtt *ggtt = &dev_priv->ggtt;
+	uint32_t reg_val = I915_READ(IS_GM45(dev_priv) ?
+				     CTG_STOLEN_RESERVED :
+				     ELK_STOLEN_RESERVED);
+	unsigned long stolen_top = dev_priv->mm.stolen_base +
+				   ggtt->stolen_size;
+
+	*base = (reg_val & G4X_STOLEN_RESERVED_ADDR2_MASK) << 16;
+
+	WARN_ON((reg_val & G4X_STOLEN_RESERVED_ADDR1_MASK) < *base);
+
+	/* On these platforms, the register doesn't have a size field, so the
+	 * size is the distance between the base and the top of the stolen
+	 * memory. We also have the genuine case where base is zero and there's
+	 * nothing reserved. */
+	if (*base == 0)
+		*size = 0;
+	else
+		*size = stolen_top - *base;
+}
+
+static void gen6_get_stolen_reserved(struct drm_i915_private *dev_priv,
+				     unsigned long *base, unsigned long *size)
+{
+	uint32_t reg_val = I915_READ(GEN6_STOLEN_RESERVED);
+
+	*base = reg_val & GEN6_STOLEN_RESERVED_ADDR_MASK;
+
+	switch (reg_val & GEN6_STOLEN_RESERVED_SIZE_MASK) {
+	case GEN6_STOLEN_RESERVED_1M:
+		*size = 1024 * 1024;
+		break;
+	case GEN6_STOLEN_RESERVED_512K:
+		*size = 512 * 1024;
+		break;
+	case GEN6_STOLEN_RESERVED_256K:
+		*size = 256 * 1024;
+		break;
+	case GEN6_STOLEN_RESERVED_128K:
+		*size = 128 * 1024;
+		break;
+	default:
+		*size = 1024 * 1024;
+		MISSING_CASE(reg_val & GEN6_STOLEN_RESERVED_SIZE_MASK);
+	}
+}
+
+static void gen7_get_stolen_reserved(struct drm_i915_private *dev_priv,
+				     unsigned long *base, unsigned long *size)
+{
+	uint32_t reg_val = I915_READ(GEN6_STOLEN_RESERVED);
+
+	*base = reg_val & GEN7_STOLEN_RESERVED_ADDR_MASK;
+
+	switch (reg_val & GEN7_STOLEN_RESERVED_SIZE_MASK) {
+	case GEN7_STOLEN_RESERVED_1M:
+		*size = 1024 * 1024;
+		break;
+	case GEN7_STOLEN_RESERVED_256K:
+		*size = 256 * 1024;
+		break;
+	default:
+		*size = 1024 * 1024;
+		MISSING_CASE(reg_val & GEN7_STOLEN_RESERVED_SIZE_MASK);
+	}
+}
+
+static void gen8_get_stolen_reserved(struct drm_i915_private *dev_priv,
+				     unsigned long *base, unsigned long *size)
+{
+	uint32_t reg_val = I915_READ(GEN6_STOLEN_RESERVED);
+
+	*base = reg_val & GEN6_STOLEN_RESERVED_ADDR_MASK;
+
+	switch (reg_val & GEN8_STOLEN_RESERVED_SIZE_MASK) {
+	case GEN8_STOLEN_RESERVED_1M:
+		*size = 1024 * 1024;
+		break;
+	case GEN8_STOLEN_RESERVED_2M:
+		*size = 2 * 1024 * 1024;
+		break;
+	case GEN8_STOLEN_RESERVED_4M:
+		*size = 4 * 1024 * 1024;
+		break;
+	case GEN8_STOLEN_RESERVED_8M:
+		*size = 8 * 1024 * 1024;
+		break;
+	default:
+		*size = 8 * 1024 * 1024;
+		MISSING_CASE(reg_val & GEN8_STOLEN_RESERVED_SIZE_MASK);
+	}
+}
+
+static void bdw_get_stolen_reserved(struct drm_i915_private *dev_priv,
+				    unsigned long *base, unsigned long *size)
+{
+	struct i915_ggtt *ggtt = &dev_priv->ggtt;
+	uint32_t reg_val = I915_READ(GEN6_STOLEN_RESERVED);
+	unsigned long stolen_top;
+
+	stolen_top = dev_priv->mm.stolen_base + ggtt->stolen_size;
+
+	*base = reg_val & GEN6_STOLEN_RESERVED_ADDR_MASK;
+
+	/* On these platforms, the register doesn't have a size field, so the
+	 * size is the distance between the base and the top of the stolen
+	 * memory. We also have the genuine case where base is zero and there's
+	 * nothing reserved. */
+	if (*base == 0)
+		*size = 0;
+	else
+		*size = stolen_top - *base;
+}
+
+int i915_gem_init_stolen(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = to_i915(dev);
+	struct i915_ggtt *ggtt = &dev_priv->ggtt;
+	unsigned long reserved_total, reserved_base = 0, reserved_size;
+	unsigned long stolen_top;
+
+	mutex_init(&dev_priv->mm.stolen_lock);
+
+#ifdef CONFIG_INTEL_IOMMU
+	if (intel_iommu_gfx_mapped && INTEL_INFO(dev)->gen < 8) {
+		DRM_INFO("DMAR active, disabling use of stolen memory\n");
+		return 0;
+	}
+#endif
+
+	if (ggtt->stolen_size == 0)
+		return 0;
+
+	dev_priv->mm.stolen_base = i915_stolen_to_physical(dev);
+	if (dev_priv->mm.stolen_base == 0)
+		return 0;
+
+	stolen_top = dev_priv->mm.stolen_base + ggtt->stolen_size;
+
+	switch (INTEL_INFO(dev_priv)->gen) {
+	case 2:
+	case 3:
+		break;
+	case 4:
+		if (IS_G4X(dev))
+			g4x_get_stolen_reserved(dev_priv, &reserved_base,
+						&reserved_size);
+		break;
+	case 5:
+		/* Assume the gen6 maximum for the older platforms. */
+		reserved_size = 1024 * 1024;
+		reserved_base = stolen_top - reserved_size;
+		break;
+	case 6:
+		gen6_get_stolen_reserved(dev_priv, &reserved_base,
+					 &reserved_size);
+		break;
+	case 7:
+		gen7_get_stolen_reserved(dev_priv, &reserved_base,
+					 &reserved_size);
+		break;
+	default:
+		if (IS_BROADWELL(dev_priv) ||
+		    IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev))
+			bdw_get_stolen_reserved(dev_priv, &reserved_base,
+						&reserved_size);
+		else
+			gen8_get_stolen_reserved(dev_priv, &reserved_base,
+						 &reserved_size);
+		break;
+	}
+
+	/* It is possible for the reserved base to be zero, but the register
+	 * field for size doesn't have a zero option. */
+	if (reserved_base == 0) {
+		reserved_size = 0;
+		reserved_base = stolen_top;
+	}
+
+	if (reserved_base < dev_priv->mm.stolen_base ||
+	    reserved_base + reserved_size > stolen_top) {
+		DRM_DEBUG_KMS("Stolen reserved area [0x%08lx - 0x%08lx] outside stolen memory [0x%08lx - 0x%08lx]\n",
+			      reserved_base, reserved_base + reserved_size,
+			      dev_priv->mm.stolen_base, stolen_top);
+		return 0;
+	}
+
+	ggtt->stolen_reserved_base = reserved_base;
+	ggtt->stolen_reserved_size = reserved_size;
+
+	/* It is possible for the reserved area to end before the end of stolen
+	 * memory, so just consider the start. */
+	reserved_total = stolen_top - reserved_base;
+
+	DRM_DEBUG_KMS("Memory reserved for graphics device: %zuK, usable: %luK\n",
+		      ggtt->stolen_size >> 10,
+		      (ggtt->stolen_size - reserved_total) >> 10);
+
+	ggtt->stolen_usable_size = ggtt->stolen_size - reserved_total;
+
+	/*
+	 * Basic memrange allocator for stolen space.
+	 *
+	 * TODO: Notice that some platforms require us to not use the first page
+	 * of the stolen memory but their BIOSes may still put the framebuffer
+	 * on the first page. So we don't reserve this page for now because of
+	 * that. Our current solution is to just prevent new nodes from being
+	 * inserted on the first page - see the check we have at
+	 * i915_gem_stolen_insert_node_in_range(). We may want to fix the fbcon
+	 * problem later.
+	 */
+	drm_mm_init(&dev_priv->mm.stolen, 0, ggtt->stolen_usable_size);
+
+	return 0;
+}
+
+static struct sg_table *
+i915_pages_create_for_stolen(struct drm_device *dev,
+			     u32 offset, u32 size)
+{
+	struct drm_i915_private *dev_priv = to_i915(dev);
+	struct i915_ggtt *ggtt = &dev_priv->ggtt;
+	struct sg_table *st;
+	struct scatterlist *sg;
+
+	DRM_DEBUG_DRIVER("offset=0x%x, size=%d\n", offset, size);
+	BUG_ON(offset > ggtt->stolen_size - size);
+
+	/* We hide that we have no struct page backing our stolen object
+	 * by wrapping the contiguous physical allocation with a fake
+	 * dma mapping in a single scatterlist.
+	 */
+
+	st = kmalloc(sizeof(*st), GFP_KERNEL);
+	if (st == NULL)
+		return NULL;
+
+	if (sg_alloc_table(st, 1, GFP_KERNEL)) {
+		kfree(st);
+		return NULL;
+	}
+
+	sg = st->sgl;
+	sg->offset = 0;
+	sg->length = size;
+
+	sg_dma_address(sg) = (dma_addr_t)dev_priv->mm.stolen_base + offset;
+	sg_dma_len(sg) = size;
+
+	return st;
+}
+
+static int i915_gem_object_get_pages_stolen(struct drm_i915_gem_object *obj)
+{
+	BUG();
+	return -EINVAL;
+}
+
+static void i915_gem_object_put_pages_stolen(struct drm_i915_gem_object *obj)
+{
+	/* Should only be called during free */
+	sg_free_table(obj->pages);
+	kfree(obj->pages);
+}
+
+
+static void
+i915_gem_object_release_stolen(struct drm_i915_gem_object *obj)
+{
+	struct drm_i915_private *dev_priv = obj->base.dev->dev_private;
+
+	if (obj->stolen) {
+		i915_gem_stolen_remove_node(dev_priv, obj->stolen);
+		kfree(obj->stolen);
+		obj->stolen = NULL;
+	}
+}
+static const struct drm_i915_gem_object_ops i915_gem_object_stolen_ops = {
+	.get_pages = i915_gem_object_get_pages_stolen,
+	.put_pages = i915_gem_object_put_pages_stolen,
+	.release = i915_gem_object_release_stolen,
+};
+
+static struct drm_i915_gem_object *
+_i915_gem_object_create_stolen(struct drm_device *dev,
+			       struct drm_mm_node *stolen)
+{
+	struct drm_i915_gem_object *obj;
+
+	obj = i915_gem_object_alloc(dev);
+	if (obj == NULL)
+		return NULL;
+
+	drm_gem_private_object_init(dev, &obj->base, stolen->size);
+	i915_gem_object_init(obj, &i915_gem_object_stolen_ops);
+
+	obj->pages = i915_pages_create_for_stolen(dev,
+						  stolen->start, stolen->size);
+	if (obj->pages == NULL)
+		goto cleanup;
+
+	obj->get_page.sg = obj->pages->sgl;
+	obj->get_page.last = 0;
+
+	i915_gem_object_pin_pages(obj);
+	obj->stolen = stolen;
+
+	obj->base.read_domains = I915_GEM_DOMAIN_CPU | I915_GEM_DOMAIN_GTT;
+	obj->cache_level = HAS_LLC(dev) ? I915_CACHE_LLC : I915_CACHE_NONE;
+
+	return obj;
+
+cleanup:
+	i915_gem_object_free(obj);
+	return NULL;
+}
+
+struct drm_i915_gem_object *
+i915_gem_object_create_stolen(struct drm_device *dev, u32 size)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct drm_i915_gem_object *obj;
+	struct drm_mm_node *stolen;
+	int ret;
+
+	if (!drm_mm_initialized(&dev_priv->mm.stolen))
+		return NULL;
+
+	DRM_DEBUG_KMS("creating stolen object: size=%x\n", size);
+	if (size == 0)
+		return NULL;
+
+	stolen = kzalloc(sizeof(*stolen), GFP_KERNEL);
+	if (!stolen)
+		return NULL;
+
+	ret = i915_gem_stolen_insert_node(dev_priv, stolen, size, 4096);
+	if (ret) {
+		kfree(stolen);
+		return NULL;
+	}
+
+	obj = _i915_gem_object_create_stolen(dev, stolen);
+	if (obj)
+		return obj;
+
+	i915_gem_stolen_remove_node(dev_priv, stolen);
+	kfree(stolen);
+	return NULL;
+}
+
+struct drm_i915_gem_object *
+i915_gem_object_create_stolen_for_preallocated(struct drm_device *dev,
+					       u32 stolen_offset,
+					       u32 gtt_offset,
+					       u32 size)
+{
+	struct drm_i915_private *dev_priv = to_i915(dev);
+	struct i915_ggtt *ggtt = &dev_priv->ggtt;
+	struct drm_i915_gem_object *obj;
+	struct drm_mm_node *stolen;
+	struct i915_vma *vma;
+	int ret;
+
+	if (!drm_mm_initialized(&dev_priv->mm.stolen))
+		return NULL;
+
+	lockdep_assert_held(&dev->struct_mutex);
+
+	DRM_DEBUG_KMS("creating preallocated stolen object: stolen_offset=%x, gtt_offset=%x, size=%x\n",
+			stolen_offset, gtt_offset, size);
+
+	/* KISS and expect everything to be page-aligned */
+	if (WARN_ON(size == 0) || WARN_ON(size & 4095) ||
+	    WARN_ON(stolen_offset & 4095))
+		return NULL;
+
+	stolen = kzalloc(sizeof(*stolen), GFP_KERNEL);
+	if (!stolen)
+		return NULL;
+
+	stolen->start = stolen_offset;
+	stolen->size = size;
+	mutex_lock(&dev_priv->mm.stolen_lock);
+	ret = drm_mm_reserve_node(&dev_priv->mm.stolen, stolen);
+	mutex_unlock(&dev_priv->mm.stolen_lock);
+	if (ret) {
+		DRM_DEBUG_KMS("failed to allocate stolen space\n");
+		kfree(stolen);
+		return NULL;
+	}
+
+	obj = _i915_gem_object_create_stolen(dev, stolen);
+	if (obj == NULL) {
+		DRM_DEBUG_KMS("failed to allocate stolen object\n");
+		i915_gem_stolen_remove_node(dev_priv, stolen);
+		kfree(stolen);
+		return NULL;
+	}
+
+	/* Some objects just need physical mem from stolen space */
+	if (gtt_offset == I915_GTT_OFFSET_NONE)
+		return obj;
+
+	vma = i915_gem_obj_lookup_or_create_vma(obj, &ggtt->base);
+	if (IS_ERR(vma)) {
+		ret = PTR_ERR(vma);
+		goto err;
+	}
+
+	/* To simplify the initialisation sequence between KMS and GTT,
+	 * we allow construction of the stolen object prior to
+	 * setting up the GTT space. The actual reservation will occur
+	 * later.
+	 */
+	vma->node.start = gtt_offset;
+	vma->node.size = size;
+	if (drm_mm_initialized(&ggtt->base.mm)) {
+		ret = drm_mm_reserve_node(&ggtt->base.mm, &vma->node);
+		if (ret) {
+			DRM_DEBUG_KMS("failed to allocate stolen GTT space\n");
+			goto err;
+		}
+
+		vma->bound |= GLOBAL_BIND;
+		__i915_vma_set_map_and_fenceable(vma);
+		list_add_tail(&vma->vm_link, &ggtt->base.inactive_list);
+	}
+
+	list_add_tail(&obj->global_list, &dev_priv->mm.bound_list);
+	i915_gem_object_pin_pages(obj);
+
+	return obj;
+
+err:
+	drm_gem_object_unreference(&obj->base);
+	return NULL;
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/i915/i915_gem_tiling.c
@@ -0,0 +1,335 @@
+/*
+ * Copyright © 2008 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Eric Anholt <eric@anholt.net>
+ *
+ */
+
+#include <linux/string.h>
+#include <linux/bitops.h>
+#include <drm/drmP.h>
+#include <drm/i915_drm.h>
+#include "i915_drv.h"
+
+/**
+ * DOC: buffer object tiling
+ *
+ * i915_gem_set_tiling() and i915_gem_get_tiling() is the userspace interface to
+ * declare fence register requirements.
+ *
+ * In principle GEM doesn't care at all about the internal data layout of an
+ * object, and hence it also doesn't care about tiling or swizzling. There's two
+ * exceptions:
+ *
+ * - For X and Y tiling the hardware provides detilers for CPU access, so called
+ *   fences. Since there's only a limited amount of them the kernel must manage
+ *   these, and therefore userspace must tell the kernel the object tiling if it
+ *   wants to use fences for detiling.
+ * - On gen3 and gen4 platforms have a swizzling pattern for tiled objects which
+ *   depends upon the physical page frame number. When swapping such objects the
+ *   page frame number might change and the kernel must be able to fix this up
+ *   and hence now the tiling. Note that on a subset of platforms with
+ *   asymmetric memory channel population the swizzling pattern changes in an
+ *   unknown way, and for those the kernel simply forbids swapping completely.
+ *
+ * Since neither of this applies for new tiling layouts on modern platforms like
+ * W, Ys and Yf tiling GEM only allows object tiling to be set to X or Y tiled.
+ * Anything else can be handled in userspace entirely without the kernel's
+ * invovlement.
+ */
+
+/* Check pitch constriants for all chips & tiling formats */
+static bool
+i915_tiling_ok(struct drm_device *dev, int stride, int size, int tiling_mode)
+{
+	int tile_width;
+
+	/* Linear is always fine */
+	if (tiling_mode == I915_TILING_NONE)
+		return true;
+
+	if (IS_GEN2(dev) ||
+	    (tiling_mode == I915_TILING_Y && HAS_128_BYTE_Y_TILING(dev)))
+		tile_width = 128;
+	else
+		tile_width = 512;
+
+	/* check maximum stride & object size */
+	/* i965+ stores the end address of the gtt mapping in the fence
+	 * reg, so dont bother to check the size */
+	if (INTEL_INFO(dev)->gen >= 7) {
+		if (stride / 128 > GEN7_FENCE_MAX_PITCH_VAL)
+			return false;
+	} else if (INTEL_INFO(dev)->gen >= 4) {
+		if (stride / 128 > I965_FENCE_MAX_PITCH_VAL)
+			return false;
+	} else {
+		if (stride > 8192)
+			return false;
+
+		if (IS_GEN3(dev)) {
+			if (size > I830_FENCE_MAX_SIZE_VAL << 20)
+				return false;
+		} else {
+			if (size > I830_FENCE_MAX_SIZE_VAL << 19)
+				return false;
+		}
+	}
+
+	if (stride < tile_width)
+		return false;
+
+	/* 965+ just needs multiples of tile width */
+	if (INTEL_INFO(dev)->gen >= 4) {
+		if (stride & (tile_width - 1))
+			return false;
+		return true;
+	}
+
+	/* Pre-965 needs power of two tile widths */
+	if (stride & (stride - 1))
+		return false;
+
+	return true;
+}
+
+/* Is the current GTT allocation valid for the change in tiling? */
+static bool
+i915_gem_object_fence_ok(struct drm_i915_gem_object *obj, int tiling_mode)
+{
+	u32 size;
+
+	if (tiling_mode == I915_TILING_NONE)
+		return true;
+
+	if (INTEL_INFO(obj->base.dev)->gen >= 4)
+		return true;
+
+	if (INTEL_INFO(obj->base.dev)->gen == 3) {
+		if (i915_gem_obj_ggtt_offset(obj) & ~I915_FENCE_START_MASK)
+			return false;
+	} else {
+		if (i915_gem_obj_ggtt_offset(obj) & ~I830_FENCE_START_MASK)
+			return false;
+	}
+
+	size = i915_gem_get_gtt_size(obj->base.dev, obj->base.size, tiling_mode);
+	if (i915_gem_obj_ggtt_size(obj) != size)
+		return false;
+
+	if (i915_gem_obj_ggtt_offset(obj) & (size - 1))
+		return false;
+
+	return true;
+}
+
+/**
+ * i915_gem_set_tiling - IOCTL handler to set tiling mode
+ * @dev: DRM device
+ * @data: data pointer for the ioctl
+ * @file: DRM file for the ioctl call
+ *
+ * Sets the tiling mode of an object, returning the required swizzling of
+ * bit 6 of addresses in the object.
+ *
+ * Called by the user via ioctl.
+ *
+ * Returns:
+ * Zero on success, negative errno on failure.
+ */
+int
+i915_gem_set_tiling(struct drm_device *dev, void *data,
+		   struct drm_file *file)
+{
+	struct drm_i915_gem_set_tiling *args = data;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct drm_i915_gem_object *obj;
+	int ret = 0;
+
+	obj = to_intel_bo(drm_gem_object_lookup(dev, file, args->handle));
+	if (&obj->base == NULL)
+		return -ENOENT;
+
+	if (!i915_tiling_ok(dev,
+			    args->stride, obj->base.size, args->tiling_mode)) {
+		drm_gem_object_unreference_unlocked(&obj->base);
+		return -EINVAL;
+	}
+
+	intel_runtime_pm_get(dev_priv);
+
+	mutex_lock(&dev->struct_mutex);
+	if (obj->pin_display || obj->framebuffer_references) {
+		ret = -EBUSY;
+		goto err;
+	}
+
+	if (args->tiling_mode == I915_TILING_NONE) {
+		args->swizzle_mode = I915_BIT_6_SWIZZLE_NONE;
+		args->stride = 0;
+	} else {
+		if (args->tiling_mode == I915_TILING_X)
+			args->swizzle_mode = dev_priv->mm.bit_6_swizzle_x;
+		else
+			args->swizzle_mode = dev_priv->mm.bit_6_swizzle_y;
+
+		/* Hide bit 17 swizzling from the user.  This prevents old Mesa
+		 * from aborting the application on sw fallbacks to bit 17,
+		 * and we use the pread/pwrite bit17 paths to swizzle for it.
+		 * If there was a user that was relying on the swizzle
+		 * information for drm_intel_bo_map()ed reads/writes this would
+		 * break it, but we don't have any of those.
+		 */
+		if (args->swizzle_mode == I915_BIT_6_SWIZZLE_9_17)
+			args->swizzle_mode = I915_BIT_6_SWIZZLE_9;
+		if (args->swizzle_mode == I915_BIT_6_SWIZZLE_9_10_17)
+			args->swizzle_mode = I915_BIT_6_SWIZZLE_9_10;
+
+		/* If we can't handle the swizzling, make it untiled. */
+		if (args->swizzle_mode == I915_BIT_6_SWIZZLE_UNKNOWN) {
+			args->tiling_mode = I915_TILING_NONE;
+			args->swizzle_mode = I915_BIT_6_SWIZZLE_NONE;
+			args->stride = 0;
+		}
+	}
+
+	if (args->tiling_mode != obj->tiling_mode ||
+	    args->stride != obj->stride) {
+		/* We need to rebind the object if its current allocation
+		 * no longer meets the alignment restrictions for its new
+		 * tiling mode. Otherwise we can just leave it alone, but
+		 * need to ensure that any fence register is updated before
+		 * the next fenced (either through the GTT or by the BLT unit
+		 * on older GPUs) access.
+		 *
+		 * After updating the tiling parameters, we then flag whether
+		 * we need to update an associated fence register. Note this
+		 * has to also include the unfenced register the GPU uses
+		 * whilst executing a fenced command for an untiled object.
+		 */
+		if (obj->map_and_fenceable &&
+		    !i915_gem_object_fence_ok(obj, args->tiling_mode))
+			ret = i915_gem_object_ggtt_unbind(obj);
+
+		if (ret == 0) {
+			if (obj->pages &&
+			    obj->madv == I915_MADV_WILLNEED &&
+			    dev_priv->quirks & QUIRK_PIN_SWIZZLED_PAGES) {
+				if (args->tiling_mode == I915_TILING_NONE)
+					i915_gem_object_unpin_pages(obj);
+				if (obj->tiling_mode == I915_TILING_NONE)
+					i915_gem_object_pin_pages(obj);
+			}
+
+			obj->fence_dirty =
+				obj->last_fenced_req ||
+				obj->fence_reg != I915_FENCE_REG_NONE;
+
+			obj->tiling_mode = args->tiling_mode;
+			obj->stride = args->stride;
+
+			/* Force the fence to be reacquired for GTT access */
+			i915_gem_release_mmap(obj);
+		}
+	}
+	/* we have to maintain this existing ABI... */
+	args->stride = obj->stride;
+	args->tiling_mode = obj->tiling_mode;
+
+	/* Try to preallocate memory required to save swizzling on put-pages */
+	if (i915_gem_object_needs_bit17_swizzle(obj)) {
+		if (obj->bit_17 == NULL) {
+			obj->bit_17 = kcalloc(BITS_TO_LONGS(obj->base.size >> PAGE_SHIFT),
+					      sizeof(long), GFP_KERNEL);
+		}
+	} else {
+		kfree(obj->bit_17);
+		obj->bit_17 = NULL;
+	}
+
+err:
+	drm_gem_object_unreference(&obj->base);
+	mutex_unlock(&dev->struct_mutex);
+
+	intel_runtime_pm_put(dev_priv);
+
+	return ret;
+}
+
+/**
+ * i915_gem_get_tiling - IOCTL handler to get tiling mode
+ * @dev: DRM device
+ * @data: data pointer for the ioctl
+ * @file: DRM file for the ioctl call
+ *
+ * Returns the current tiling mode and required bit 6 swizzling for the object.
+ *
+ * Called by the user via ioctl.
+ *
+ * Returns:
+ * Zero on success, negative errno on failure.
+ */
+int
+i915_gem_get_tiling(struct drm_device *dev, void *data,
+		   struct drm_file *file)
+{
+	struct drm_i915_gem_get_tiling *args = data;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct drm_i915_gem_object *obj;
+
+	obj = to_intel_bo(drm_gem_object_lookup(dev, file, args->handle));
+	if (&obj->base == NULL)
+		return -ENOENT;
+
+	mutex_lock(&dev->struct_mutex);
+
+	args->tiling_mode = obj->tiling_mode;
+	switch (obj->tiling_mode) {
+	case I915_TILING_X:
+		args->swizzle_mode = dev_priv->mm.bit_6_swizzle_x;
+		break;
+	case I915_TILING_Y:
+		args->swizzle_mode = dev_priv->mm.bit_6_swizzle_y;
+		break;
+	case I915_TILING_NONE:
+		args->swizzle_mode = I915_BIT_6_SWIZZLE_NONE;
+		break;
+	default:
+		DRM_ERROR("unknown tiling mode\n");
+	}
+
+	/* Hide bit 17 from the user -- see comment in i915_gem_set_tiling */
+	if (dev_priv->quirks & QUIRK_PIN_SWIZZLED_PAGES)
+		args->phys_swizzle_mode = I915_BIT_6_SWIZZLE_UNKNOWN;
+	else
+		args->phys_swizzle_mode = args->swizzle_mode;
+	if (args->swizzle_mode == I915_BIT_6_SWIZZLE_9_17)
+		args->swizzle_mode = I915_BIT_6_SWIZZLE_9;
+	if (args->swizzle_mode == I915_BIT_6_SWIZZLE_9_10_17)
+		args->swizzle_mode = I915_BIT_6_SWIZZLE_9_10;
+
+	drm_gem_object_unreference(&obj->base);
+	mutex_unlock(&dev->struct_mutex);
+
+	return 0;
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/i915/i915_gem_userptr.c
@@ -0,0 +1,865 @@
+/*
+ * Copyright © 2012-2014 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ */
+
+#include <drm/drmP.h>
+#include <drm/i915_drm.h>
+#include "i915_drv.h"
+#include "i915_trace.h"
+#include "intel_drv.h"
+#include <linux/mmu_context.h>
+#include <linux/mmu_notifier.h>
+#include <linux/mempolicy.h>
+#include <linux/swap.h>
+
+struct i915_mm_struct {
+	struct mm_struct *mm;
+	struct drm_i915_private *i915;
+	struct i915_mmu_notifier *mn;
+	struct hlist_node node;
+	struct kref kref;
+	struct work_struct work;
+};
+
+#if defined(CONFIG_MMU_NOTIFIER)
+#include <linux/interval_tree.h>
+
+struct i915_mmu_notifier {
+	spinlock_t lock;
+	struct hlist_node node;
+	struct mmu_notifier mn;
+	struct rb_root objects;
+	struct workqueue_struct *wq;
+};
+
+struct i915_mmu_object {
+	struct i915_mmu_notifier *mn;
+	struct drm_i915_gem_object *obj;
+	struct interval_tree_node it;
+	struct list_head link;
+	struct work_struct work;
+	bool attached;
+};
+
+static void wait_rendering(struct drm_i915_gem_object *obj)
+{
+	struct drm_device *dev = obj->base.dev;
+	struct drm_i915_gem_request *requests[I915_NUM_ENGINES];
+	int i, n;
+
+	if (!obj->active)
+		return;
+
+	n = 0;
+	for (i = 0; i < I915_NUM_ENGINES; i++) {
+		struct drm_i915_gem_request *req;
+
+		req = obj->last_read_req[i];
+		if (req == NULL)
+			continue;
+
+		requests[n++] = i915_gem_request_reference(req);
+	}
+
+	mutex_unlock(&dev->struct_mutex);
+
+	for (i = 0; i < n; i++)
+		__i915_wait_request(requests[i], false, NULL, NULL);
+
+	mutex_lock(&dev->struct_mutex);
+
+	for (i = 0; i < n; i++)
+		i915_gem_request_unreference(requests[i]);
+}
+
+static void cancel_userptr(struct work_struct *work)
+{
+	struct i915_mmu_object *mo = container_of(work, typeof(*mo), work);
+	struct drm_i915_gem_object *obj = mo->obj;
+	struct drm_device *dev = obj->base.dev;
+
+	mutex_lock(&dev->struct_mutex);
+	/* Cancel any active worker and force us to re-evaluate gup */
+	obj->userptr.work = NULL;
+
+	if (obj->pages != NULL) {
+		struct drm_i915_private *dev_priv = to_i915(dev);
+		struct i915_vma *vma, *tmp;
+		bool was_interruptible;
+
+		wait_rendering(obj);
+
+		was_interruptible = dev_priv->mm.interruptible;
+		dev_priv->mm.interruptible = false;
+
+		list_for_each_entry_safe(vma, tmp, &obj->vma_list, obj_link)
+			WARN_ON(i915_vma_unbind(vma));
+		WARN_ON(i915_gem_object_put_pages(obj));
+
+		dev_priv->mm.interruptible = was_interruptible;
+	}
+
+	drm_gem_object_unreference(&obj->base);
+	mutex_unlock(&dev->struct_mutex);
+}
+
+static void add_object(struct i915_mmu_object *mo)
+{
+	if (mo->attached)
+		return;
+
+	interval_tree_insert(&mo->it, &mo->mn->objects);
+	mo->attached = true;
+}
+
+static void del_object(struct i915_mmu_object *mo)
+{
+	if (!mo->attached)
+		return;
+
+	interval_tree_remove(&mo->it, &mo->mn->objects);
+	mo->attached = false;
+}
+
+static void i915_gem_userptr_mn_invalidate_range_start(struct mmu_notifier *_mn,
+						       struct mm_struct *mm,
+						       unsigned long start,
+						       unsigned long end)
+{
+	struct i915_mmu_notifier *mn =
+		container_of(_mn, struct i915_mmu_notifier, mn);
+	struct i915_mmu_object *mo;
+	struct interval_tree_node *it;
+	LIST_HEAD(cancelled);
+
+	if (RB_EMPTY_ROOT(&mn->objects))
+		return;
+
+	/* interval ranges are inclusive, but invalidate range is exclusive */
+	end--;
+
+	spin_lock(&mn->lock);
+	it = interval_tree_iter_first(&mn->objects, start, end);
+	while (it) {
+		/* The mmu_object is released late when destroying the
+		 * GEM object so it is entirely possible to gain a
+		 * reference on an object in the process of being freed
+		 * since our serialisation is via the spinlock and not
+		 * the struct_mutex - and consequently use it after it
+		 * is freed and then double free it. To prevent that
+		 * use-after-free we only acquire a reference on the
+		 * object if it is not in the process of being destroyed.
+		 */
+		mo = container_of(it, struct i915_mmu_object, it);
+		if (kref_get_unless_zero(&mo->obj->base.refcount))
+			queue_work(mn->wq, &mo->work);
+
+		list_add(&mo->link, &cancelled);
+		it = interval_tree_iter_next(it, start, end);
+	}
+	list_for_each_entry(mo, &cancelled, link)
+		del_object(mo);
+	spin_unlock(&mn->lock);
+
+	flush_workqueue(mn->wq);
+}
+
+static const struct mmu_notifier_ops i915_gem_userptr_notifier = {
+	.invalidate_range_start = i915_gem_userptr_mn_invalidate_range_start,
+};
+
+static struct i915_mmu_notifier *
+i915_mmu_notifier_create(struct mm_struct *mm)
+{
+	struct i915_mmu_notifier *mn;
+	int ret;
+
+	mn = kmalloc(sizeof(*mn), GFP_KERNEL);
+	if (mn == NULL)
+		return ERR_PTR(-ENOMEM);
+
+	spin_lock_init(&mn->lock);
+	mn->mn.ops = &i915_gem_userptr_notifier;
+	mn->objects = RB_ROOT;
+	mn->wq = alloc_workqueue("i915-userptr-release", WQ_UNBOUND, 0);
+	if (mn->wq == NULL) {
+		kfree(mn);
+		return ERR_PTR(-ENOMEM);
+	}
+
+	 /* Protected by mmap_sem (write-lock) */
+	ret = __mmu_notifier_register(&mn->mn, mm);
+	if (ret) {
+		destroy_workqueue(mn->wq);
+		kfree(mn);
+		return ERR_PTR(ret);
+	}
+
+	return mn;
+}
+
+static void
+i915_gem_userptr_release__mmu_notifier(struct drm_i915_gem_object *obj)
+{
+	struct i915_mmu_object *mo;
+
+	mo = obj->userptr.mmu_object;
+	if (mo == NULL)
+		return;
+
+	spin_lock(&mo->mn->lock);
+	del_object(mo);
+	spin_unlock(&mo->mn->lock);
+	kfree(mo);
+
+	obj->userptr.mmu_object = NULL;
+}
+
+static struct i915_mmu_notifier *
+i915_mmu_notifier_find(struct i915_mm_struct *mm)
+{
+	struct i915_mmu_notifier *mn = mm->mn;
+
+	mn = mm->mn;
+	if (mn)
+		return mn;
+
+	down_write(&mm->mm->mmap_sem);
+	mutex_lock(&mm->i915->mm_lock);
+	if ((mn = mm->mn) == NULL) {
+		mn = i915_mmu_notifier_create(mm->mm);
+		if (!IS_ERR(mn))
+			mm->mn = mn;
+	}
+	mutex_unlock(&mm->i915->mm_lock);
+	up_write(&mm->mm->mmap_sem);
+
+	return mn;
+}
+
+static int
+i915_gem_userptr_init__mmu_notifier(struct drm_i915_gem_object *obj,
+				    unsigned flags)
+{
+	struct i915_mmu_notifier *mn;
+	struct i915_mmu_object *mo;
+
+	if (flags & I915_USERPTR_UNSYNCHRONIZED)
+		return capable(CAP_SYS_ADMIN) ? 0 : -EPERM;
+
+	if (WARN_ON(obj->userptr.mm == NULL))
+		return -EINVAL;
+
+	mn = i915_mmu_notifier_find(obj->userptr.mm);
+	if (IS_ERR(mn))
+		return PTR_ERR(mn);
+
+	mo = kzalloc(sizeof(*mo), GFP_KERNEL);
+	if (mo == NULL)
+		return -ENOMEM;
+
+	mo->mn = mn;
+	mo->obj = obj;
+	mo->it.start = obj->userptr.ptr;
+	mo->it.last = obj->userptr.ptr + obj->base.size - 1;
+	INIT_WORK(&mo->work, cancel_userptr);
+
+	obj->userptr.mmu_object = mo;
+	return 0;
+}
+
+static void
+i915_mmu_notifier_free(struct i915_mmu_notifier *mn,
+		       struct mm_struct *mm)
+{
+	if (mn == NULL)
+		return;
+
+	mmu_notifier_unregister(&mn->mn, mm);
+	destroy_workqueue(mn->wq);
+	kfree(mn);
+}
+
+#else
+
+static void
+i915_gem_userptr_release__mmu_notifier(struct drm_i915_gem_object *obj)
+{
+}
+
+static int
+i915_gem_userptr_init__mmu_notifier(struct drm_i915_gem_object *obj,
+				    unsigned flags)
+{
+	if ((flags & I915_USERPTR_UNSYNCHRONIZED) == 0)
+		return -ENODEV;
+
+	if (!capable(CAP_SYS_ADMIN))
+		return -EPERM;
+
+	return 0;
+}
+
+static void
+i915_mmu_notifier_free(struct i915_mmu_notifier *mn,
+		       struct mm_struct *mm)
+{
+}
+
+#endif
+
+static struct i915_mm_struct *
+__i915_mm_struct_find(struct drm_i915_private *dev_priv, struct mm_struct *real)
+{
+	struct i915_mm_struct *mm;
+
+	/* Protected by dev_priv->mm_lock */
+	hash_for_each_possible(dev_priv->mm_structs, mm, node, (unsigned long)real)
+		if (mm->mm == real)
+			return mm;
+
+	return NULL;
+}
+
+static int
+i915_gem_userptr_init__mm_struct(struct drm_i915_gem_object *obj)
+{
+	struct drm_i915_private *dev_priv = to_i915(obj->base.dev);
+	struct i915_mm_struct *mm;
+	int ret = 0;
+
+	/* During release of the GEM object we hold the struct_mutex. This
+	 * precludes us from calling mmput() at that time as that may be
+	 * the last reference and so call exit_mmap(). exit_mmap() will
+	 * attempt to reap the vma, and if we were holding a GTT mmap
+	 * would then call drm_gem_vm_close() and attempt to reacquire
+	 * the struct mutex. So in order to avoid that recursion, we have
+	 * to defer releasing the mm reference until after we drop the
+	 * struct_mutex, i.e. we need to schedule a worker to do the clean
+	 * up.
+	 */
+	mutex_lock(&dev_priv->mm_lock);
+	mm = __i915_mm_struct_find(dev_priv, current->mm);
+	if (mm == NULL) {
+		mm = kmalloc(sizeof(*mm), GFP_KERNEL);
+		if (mm == NULL) {
+			ret = -ENOMEM;
+			goto out;
+		}
+
+		kref_init(&mm->kref);
+		mm->i915 = to_i915(obj->base.dev);
+
+		mm->mm = current->mm;
+		atomic_inc(&current->mm->mm_count);
+
+		mm->mn = NULL;
+
+		/* Protected by dev_priv->mm_lock */
+		hash_add(dev_priv->mm_structs,
+			 &mm->node, (unsigned long)mm->mm);
+	} else
+		kref_get(&mm->kref);
+
+	obj->userptr.mm = mm;
+out:
+	mutex_unlock(&dev_priv->mm_lock);
+	return ret;
+}
+
+static void
+__i915_mm_struct_free__worker(struct work_struct *work)
+{
+	struct i915_mm_struct *mm = container_of(work, typeof(*mm), work);
+	i915_mmu_notifier_free(mm->mn, mm->mm);
+	mmdrop(mm->mm);
+	kfree(mm);
+}
+
+static void
+__i915_mm_struct_free(struct kref *kref)
+{
+	struct i915_mm_struct *mm = container_of(kref, typeof(*mm), kref);
+
+	/* Protected by dev_priv->mm_lock */
+	hash_del(&mm->node);
+	mutex_unlock(&mm->i915->mm_lock);
+
+	INIT_WORK(&mm->work, __i915_mm_struct_free__worker);
+	schedule_work(&mm->work);
+}
+
+static void
+i915_gem_userptr_release__mm_struct(struct drm_i915_gem_object *obj)
+{
+	if (obj->userptr.mm == NULL)
+		return;
+
+	kref_put_mutex(&obj->userptr.mm->kref,
+		       __i915_mm_struct_free,
+		       &to_i915(obj->base.dev)->mm_lock);
+	obj->userptr.mm = NULL;
+}
+
+struct get_pages_work {
+	struct work_struct work;
+	struct drm_i915_gem_object *obj;
+	struct task_struct *task;
+};
+
+#if IS_ENABLED(CONFIG_SWIOTLB)
+#define swiotlb_active() swiotlb_nr_tbl()
+#else
+#define swiotlb_active() 0
+#endif
+
+static int
+st_set_pages(struct sg_table **st, struct page **pvec, int num_pages)
+{
+	struct scatterlist *sg;
+	int ret, n;
+
+	*st = kmalloc(sizeof(**st), GFP_KERNEL);
+	if (*st == NULL)
+		return -ENOMEM;
+
+	if (swiotlb_active()) {
+		ret = sg_alloc_table(*st, num_pages, GFP_KERNEL);
+		if (ret)
+			goto err;
+
+		for_each_sg((*st)->sgl, sg, num_pages, n)
+			sg_set_page(sg, pvec[n], PAGE_SIZE, 0);
+	} else {
+		ret = sg_alloc_table_from_pages(*st, pvec, num_pages,
+						0, num_pages << PAGE_SHIFT,
+						GFP_KERNEL);
+		if (ret)
+			goto err;
+	}
+
+	return 0;
+
+err:
+	kfree(*st);
+	*st = NULL;
+	return ret;
+}
+
+static int
+__i915_gem_userptr_set_pages(struct drm_i915_gem_object *obj,
+			     struct page **pvec, int num_pages)
+{
+	int ret;
+
+	ret = st_set_pages(&obj->pages, pvec, num_pages);
+	if (ret)
+		return ret;
+
+	ret = i915_gem_gtt_prepare_object(obj);
+	if (ret) {
+		sg_free_table(obj->pages);
+		kfree(obj->pages);
+		obj->pages = NULL;
+	}
+
+	return ret;
+}
+
+static int
+__i915_gem_userptr_set_active(struct drm_i915_gem_object *obj,
+			      bool value)
+{
+	int ret = 0;
+
+	/* During mm_invalidate_range we need to cancel any userptr that
+	 * overlaps the range being invalidated. Doing so requires the
+	 * struct_mutex, and that risks recursion. In order to cause
+	 * recursion, the user must alias the userptr address space with
+	 * a GTT mmapping (possible with a MAP_FIXED) - then when we have
+	 * to invalidate that mmaping, mm_invalidate_range is called with
+	 * the userptr address *and* the struct_mutex held.  To prevent that
+	 * we set a flag under the i915_mmu_notifier spinlock to indicate
+	 * whether this object is valid.
+	 */
+#if defined(CONFIG_MMU_NOTIFIER)
+	if (obj->userptr.mmu_object == NULL)
+		return 0;
+
+	spin_lock(&obj->userptr.mmu_object->mn->lock);
+	/* In order to serialise get_pages with an outstanding
+	 * cancel_userptr, we must drop the struct_mutex and try again.
+	 */
+	if (!value)
+		del_object(obj->userptr.mmu_object);
+	else if (!work_pending(&obj->userptr.mmu_object->work))
+		add_object(obj->userptr.mmu_object);
+	else
+		ret = -EAGAIN;
+	spin_unlock(&obj->userptr.mmu_object->mn->lock);
+#endif
+
+	return ret;
+}
+
+static void
+__i915_gem_userptr_get_pages_worker(struct work_struct *_work)
+{
+	struct get_pages_work *work = container_of(_work, typeof(*work), work);
+	struct drm_i915_gem_object *obj = work->obj;
+	struct drm_device *dev = obj->base.dev;
+	const int npages = obj->base.size >> PAGE_SHIFT;
+	struct page **pvec;
+	int pinned, ret;
+
+	ret = -ENOMEM;
+	pinned = 0;
+
+	pvec = drm_malloc_gfp(npages, sizeof(struct page *), GFP_TEMPORARY);
+	if (pvec != NULL) {
+		struct mm_struct *mm = obj->userptr.mm->mm;
+
+		ret = -EFAULT;
+		if (atomic_inc_not_zero(&mm->mm_users)) {
+			down_read(&mm->mmap_sem);
+			while (pinned < npages) {
+				ret = get_user_pages
+					(work->task, mm,
+					 obj->userptr.ptr + pinned * PAGE_SIZE,
+					 npages - pinned,
+					 !obj->userptr.read_only, 0,
+					 pvec + pinned, NULL);
+				if (ret < 0)
+					break;
+
+				pinned += ret;
+			}
+			up_read(&mm->mmap_sem);
+			mmput(mm);
+		}
+	}
+
+	mutex_lock(&dev->struct_mutex);
+	if (obj->userptr.work == &work->work) {
+		if (pinned == npages) {
+			ret = __i915_gem_userptr_set_pages(obj, pvec, npages);
+			if (ret == 0) {
+				list_add_tail(&obj->global_list,
+					      &to_i915(dev)->mm.unbound_list);
+				obj->get_page.sg = obj->pages->sgl;
+				obj->get_page.last = 0;
+				pinned = 0;
+			}
+		}
+		obj->userptr.work = ERR_PTR(ret);
+		if (ret)
+			__i915_gem_userptr_set_active(obj, false);
+	}
+
+	obj->userptr.workers--;
+	drm_gem_object_unreference(&obj->base);
+	mutex_unlock(&dev->struct_mutex);
+
+	release_pages(pvec, pinned, 0);
+	drm_free_large(pvec);
+
+	put_task_struct(work->task);
+	kfree(work);
+}
+
+static int
+__i915_gem_userptr_get_pages_schedule(struct drm_i915_gem_object *obj,
+				      bool *active)
+{
+	struct get_pages_work *work;
+
+	/* Spawn a worker so that we can acquire the
+	 * user pages without holding our mutex. Access
+	 * to the user pages requires mmap_sem, and we have
+	 * a strict lock ordering of mmap_sem, struct_mutex -
+	 * we already hold struct_mutex here and so cannot
+	 * call gup without encountering a lock inversion.
+	 *
+	 * Userspace will keep on repeating the operation
+	 * (thanks to EAGAIN) until either we hit the fast
+	 * path or the worker completes. If the worker is
+	 * cancelled or superseded, the task is still run
+	 * but the results ignored. (This leads to
+	 * complications that we may have a stray object
+	 * refcount that we need to be wary of when
+	 * checking for existing objects during creation.)
+	 * If the worker encounters an error, it reports
+	 * that error back to this function through
+	 * obj->userptr.work = ERR_PTR.
+	 */
+	if (obj->userptr.workers >= I915_GEM_USERPTR_MAX_WORKERS)
+		return -EAGAIN;
+
+	work = kmalloc(sizeof(*work), GFP_KERNEL);
+	if (work == NULL)
+		return -ENOMEM;
+
+	obj->userptr.work = &work->work;
+	obj->userptr.workers++;
+
+	work->obj = obj;
+	drm_gem_object_reference(&obj->base);
+
+	work->task = current;
+	get_task_struct(work->task);
+
+	INIT_WORK(&work->work, __i915_gem_userptr_get_pages_worker);
+	schedule_work(&work->work);
+
+	*active = true;
+	return -EAGAIN;
+}
+
+static int
+i915_gem_userptr_get_pages(struct drm_i915_gem_object *obj)
+{
+	const int num_pages = obj->base.size >> PAGE_SHIFT;
+	struct page **pvec;
+	int pinned, ret;
+	bool active;
+
+	/* If userspace should engineer that these pages are replaced in
+	 * the vma between us binding this page into the GTT and completion
+	 * of rendering... Their loss. If they change the mapping of their
+	 * pages they need to create a new bo to point to the new vma.
+	 *
+	 * However, that still leaves open the possibility of the vma
+	 * being copied upon fork. Which falls under the same userspace
+	 * synchronisation issue as a regular bo, except that this time
+	 * the process may not be expecting that a particular piece of
+	 * memory is tied to the GPU.
+	 *
+	 * Fortunately, we can hook into the mmu_notifier in order to
+	 * discard the page references prior to anything nasty happening
+	 * to the vma (discard or cloning) which should prevent the more
+	 * egregious cases from causing harm.
+	 */
+	if (IS_ERR(obj->userptr.work)) {
+		/* active flag will have been dropped already by the worker */
+		ret = PTR_ERR(obj->userptr.work);
+		obj->userptr.work = NULL;
+		return ret;
+	}
+	if (obj->userptr.work)
+		/* active flag should still be held for the pending work */
+		return -EAGAIN;
+
+	/* Let the mmu-notifier know that we have begun and need cancellation */
+	ret = __i915_gem_userptr_set_active(obj, true);
+	if (ret)
+		return ret;
+
+	pvec = NULL;
+	pinned = 0;
+	if (obj->userptr.mm->mm == current->mm) {
+		pvec = drm_malloc_gfp(num_pages, sizeof(struct page *),
+				      GFP_TEMPORARY);
+		if (pvec == NULL) {
+			__i915_gem_userptr_set_active(obj, false);
+			return -ENOMEM;
+		}
+
+		pinned = __get_user_pages_fast(obj->userptr.ptr, num_pages,
+					       !obj->userptr.read_only, pvec);
+	}
+
+	active = false;
+	if (pinned < 0)
+		ret = pinned, pinned = 0;
+	else if (pinned < num_pages)
+		ret = __i915_gem_userptr_get_pages_schedule(obj, &active);
+	else
+		ret = __i915_gem_userptr_set_pages(obj, pvec, num_pages);
+	if (ret) {
+		__i915_gem_userptr_set_active(obj, active);
+		release_pages(pvec, pinned, 0);
+	}
+	drm_free_large(pvec);
+	return ret;
+}
+
+static void
+i915_gem_userptr_put_pages(struct drm_i915_gem_object *obj)
+{
+	struct sg_page_iter sg_iter;
+
+	BUG_ON(obj->userptr.work != NULL);
+	__i915_gem_userptr_set_active(obj, false);
+
+	if (obj->madv != I915_MADV_WILLNEED)
+		obj->dirty = 0;
+
+	i915_gem_gtt_finish_object(obj);
+
+	for_each_sg_page(obj->pages->sgl, &sg_iter, obj->pages->nents, 0) {
+		struct page *page = sg_page_iter_page(&sg_iter);
+
+		if (obj->dirty)
+			set_page_dirty(page);
+
+		mark_page_accessed(page);
+		put_page(page);
+	}
+	obj->dirty = 0;
+
+	sg_free_table(obj->pages);
+	kfree(obj->pages);
+}
+
+static void
+i915_gem_userptr_release(struct drm_i915_gem_object *obj)
+{
+	i915_gem_userptr_release__mmu_notifier(obj);
+	i915_gem_userptr_release__mm_struct(obj);
+}
+
+static int
+i915_gem_userptr_dmabuf_export(struct drm_i915_gem_object *obj)
+{
+	if (obj->userptr.mmu_object)
+		return 0;
+
+	return i915_gem_userptr_init__mmu_notifier(obj, 0);
+}
+
+static const struct drm_i915_gem_object_ops i915_gem_userptr_ops = {
+	.flags = I915_GEM_OBJECT_HAS_STRUCT_PAGE,
+	.get_pages = i915_gem_userptr_get_pages,
+	.put_pages = i915_gem_userptr_put_pages,
+	.dmabuf_export = i915_gem_userptr_dmabuf_export,
+	.release = i915_gem_userptr_release,
+};
+
+/**
+ * Creates a new mm object that wraps some normal memory from the process
+ * context - user memory.
+ *
+ * We impose several restrictions upon the memory being mapped
+ * into the GPU.
+ * 1. It must be page aligned (both start/end addresses, i.e ptr and size).
+ * 2. It must be normal system memory, not a pointer into another map of IO
+ *    space (e.g. it must not be a GTT mmapping of another object).
+ * 3. We only allow a bo as large as we could in theory map into the GTT,
+ *    that is we limit the size to the total size of the GTT.
+ * 4. The bo is marked as being snoopable. The backing pages are left
+ *    accessible directly by the CPU, but reads and writes by the GPU may
+ *    incur the cost of a snoop (unless you have an LLC architecture).
+ *
+ * Synchronisation between multiple users and the GPU is left to userspace
+ * through the normal set-domain-ioctl. The kernel will enforce that the
+ * GPU relinquishes the VMA before it is returned back to the system
+ * i.e. upon free(), munmap() or process termination. However, the userspace
+ * malloc() library may not immediately relinquish the VMA after free() and
+ * instead reuse it whilst the GPU is still reading and writing to the VMA.
+ * Caveat emptor.
+ *
+ * Also note, that the object created here is not currently a "first class"
+ * object, in that several ioctls are banned. These are the CPU access
+ * ioctls: mmap(), pwrite and pread. In practice, you are expected to use
+ * direct access via your pointer rather than use those ioctls. Another
+ * restriction is that we do not allow userptr surfaces to be pinned to the
+ * hardware and so we reject any attempt to create a framebuffer out of a
+ * userptr.
+ *
+ * If you think this is a good interface to use to pass GPU memory between
+ * drivers, please use dma-buf instead. In fact, wherever possible use
+ * dma-buf instead.
+ */
+int
+i915_gem_userptr_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
+{
+	struct drm_i915_gem_userptr *args = data;
+	struct drm_i915_gem_object *obj;
+	int ret;
+	u32 handle;
+
+	if (!HAS_LLC(dev) && !HAS_SNOOP(dev)) {
+		/* We cannot support coherent userptr objects on hw without
+		 * LLC and broken snooping.
+		 */
+		return -ENODEV;
+	}
+
+	if (args->flags & ~(I915_USERPTR_READ_ONLY |
+			    I915_USERPTR_UNSYNCHRONIZED))
+		return -EINVAL;
+
+	if (offset_in_page(args->user_ptr | args->user_size))
+		return -EINVAL;
+
+	if (!access_ok(args->flags & I915_USERPTR_READ_ONLY ? VERIFY_READ : VERIFY_WRITE,
+		       (char __user *)(unsigned long)args->user_ptr, args->user_size))
+		return -EFAULT;
+
+	if (args->flags & I915_USERPTR_READ_ONLY) {
+		/* On almost all of the current hw, we cannot tell the GPU that a
+		 * page is readonly, so this is just a placeholder in the uAPI.
+		 */
+		return -ENODEV;
+	}
+
+	obj = i915_gem_object_alloc(dev);
+	if (obj == NULL)
+		return -ENOMEM;
+
+	drm_gem_private_object_init(dev, &obj->base, args->user_size);
+	i915_gem_object_init(obj, &i915_gem_userptr_ops);
+	obj->cache_level = I915_CACHE_LLC;
+	obj->base.write_domain = I915_GEM_DOMAIN_CPU;
+	obj->base.read_domains = I915_GEM_DOMAIN_CPU;
+
+	obj->userptr.ptr = args->user_ptr;
+	obj->userptr.read_only = !!(args->flags & I915_USERPTR_READ_ONLY);
+
+	/* And keep a pointer to the current->mm for resolving the user pages
+	 * at binding. This means that we need to hook into the mmu_notifier
+	 * in order to detect if the mmu is destroyed.
+	 */
+	ret = i915_gem_userptr_init__mm_struct(obj);
+	if (ret == 0)
+		ret = i915_gem_userptr_init__mmu_notifier(obj, args->flags);
+	if (ret == 0)
+		ret = drm_gem_handle_create(file, &obj->base, &handle);
+
+	/* drop reference from allocate - handle holds it now */
+	drm_gem_object_unreference_unlocked(&obj->base);
+	if (ret)
+		return ret;
+
+	args->handle = handle;
+	return 0;
+}
+
+int
+i915_gem_init_userptr(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = to_i915(dev);
+	mutex_init(&dev_priv->mm_lock);
+	hash_init(dev_priv->mm_structs);
+	return 0;
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/i915/i915_gpu_error.c
@@ -0,0 +1,1469 @@
+/*
+ * Copyright (c) 2008 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Eric Anholt <eric@anholt.net>
+ *    Keith Packard <keithp@keithp.com>
+ *    Mika Kuoppala <mika.kuoppala@intel.com>
+ *
+ */
+
+#include <generated/utsrelease.h>
+#include "i915_drv.h"
+
+static const char *ring_str(int ring)
+{
+	switch (ring) {
+	case RCS: return "render";
+	case VCS: return "bsd";
+	case BCS: return "blt";
+	case VECS: return "vebox";
+	case VCS2: return "bsd2";
+	default: return "";
+	}
+}
+
+static const char *pin_flag(int pinned)
+{
+	if (pinned > 0)
+		return " P";
+	else if (pinned < 0)
+		return " p";
+	else
+		return "";
+}
+
+static const char *tiling_flag(int tiling)
+{
+	switch (tiling) {
+	default:
+	case I915_TILING_NONE: return "";
+	case I915_TILING_X: return " X";
+	case I915_TILING_Y: return " Y";
+	}
+}
+
+static const char *dirty_flag(int dirty)
+{
+	return dirty ? " dirty" : "";
+}
+
+static const char *purgeable_flag(int purgeable)
+{
+	return purgeable ? " purgeable" : "";
+}
+
+static bool __i915_error_ok(struct drm_i915_error_state_buf *e)
+{
+
+	if (!e->err && WARN(e->bytes > (e->size - 1), "overflow")) {
+		e->err = -ENOSPC;
+		return false;
+	}
+
+	if (e->bytes == e->size - 1 || e->err)
+		return false;
+
+	return true;
+}
+
+static bool __i915_error_seek(struct drm_i915_error_state_buf *e,
+			      unsigned len)
+{
+	if (e->pos + len <= e->start) {
+		e->pos += len;
+		return false;
+	}
+
+	/* First vsnprintf needs to fit in its entirety for memmove */
+	if (len >= e->size) {
+		e->err = -EIO;
+		return false;
+	}
+
+	return true;
+}
+
+static void __i915_error_advance(struct drm_i915_error_state_buf *e,
+				 unsigned len)
+{
+	/* If this is first printf in this window, adjust it so that
+	 * start position matches start of the buffer
+	 */
+
+	if (e->pos < e->start) {
+		const size_t off = e->start - e->pos;
+
+		/* Should not happen but be paranoid */
+		if (off > len || e->bytes) {
+			e->err = -EIO;
+			return;
+		}
+
+		memmove(e->buf, e->buf + off, len - off);
+		e->bytes = len - off;
+		e->pos = e->start;
+		return;
+	}
+
+	e->bytes += len;
+	e->pos += len;
+}
+
+static void i915_error_vprintf(struct drm_i915_error_state_buf *e,
+			       const char *f, va_list args)
+{
+	unsigned len;
+
+	if (!__i915_error_ok(e))
+		return;
+
+	/* Seek the first printf which is hits start position */
+	if (e->pos < e->start) {
+		va_list tmp;
+
+		va_copy(tmp, args);
+		len = vsnprintf(NULL, 0, f, tmp);
+		va_end(tmp);
+
+		if (!__i915_error_seek(e, len))
+			return;
+	}
+
+	len = vsnprintf(e->buf + e->bytes, e->size - e->bytes, f, args);
+	if (len >= e->size - e->bytes)
+		len = e->size - e->bytes - 1;
+
+	__i915_error_advance(e, len);
+}
+
+static void i915_error_puts(struct drm_i915_error_state_buf *e,
+			    const char *str)
+{
+	unsigned len;
+
+	if (!__i915_error_ok(e))
+		return;
+
+	len = strlen(str);
+
+	/* Seek the first printf which is hits start position */
+	if (e->pos < e->start) {
+		if (!__i915_error_seek(e, len))
+			return;
+	}
+
+	if (len >= e->size - e->bytes)
+		len = e->size - e->bytes - 1;
+	memcpy(e->buf + e->bytes, str, len);
+
+	__i915_error_advance(e, len);
+}
+
+#define err_printf(e, ...) i915_error_printf(e, __VA_ARGS__)
+#define err_puts(e, s) i915_error_puts(e, s)
+
+static void print_error_buffers(struct drm_i915_error_state_buf *m,
+				const char *name,
+				struct drm_i915_error_buffer *err,
+				int count)
+{
+	int i;
+
+	err_printf(m, "  %s [%d]:\n", name, count);
+
+	while (count--) {
+		err_printf(m, "    %08x_%08x %8u %02x %02x [ ",
+			   upper_32_bits(err->gtt_offset),
+			   lower_32_bits(err->gtt_offset),
+			   err->size,
+			   err->read_domains,
+			   err->write_domain);
+		for (i = 0; i < I915_NUM_ENGINES; i++)
+			err_printf(m, "%02x ", err->rseqno[i]);
+
+		err_printf(m, "] %02x", err->wseqno);
+		err_puts(m, pin_flag(err->pinned));
+		err_puts(m, tiling_flag(err->tiling));
+		err_puts(m, dirty_flag(err->dirty));
+		err_puts(m, purgeable_flag(err->purgeable));
+		err_puts(m, err->userptr ? " userptr" : "");
+		err_puts(m, err->ring != -1 ? " " : "");
+		err_puts(m, ring_str(err->ring));
+		err_puts(m, i915_cache_level_str(m->i915, err->cache_level));
+
+		if (err->name)
+			err_printf(m, " (name: %d)", err->name);
+		if (err->fence_reg != I915_FENCE_REG_NONE)
+			err_printf(m, " (fence: %d)", err->fence_reg);
+
+		err_puts(m, "\n");
+		err++;
+	}
+}
+
+static const char *hangcheck_action_to_str(enum intel_ring_hangcheck_action a)
+{
+	switch (a) {
+	case HANGCHECK_IDLE:
+		return "idle";
+	case HANGCHECK_WAIT:
+		return "wait";
+	case HANGCHECK_ACTIVE:
+		return "active";
+	case HANGCHECK_KICK:
+		return "kick";
+	case HANGCHECK_HUNG:
+		return "hung";
+	}
+
+	return "unknown";
+}
+
+static void i915_ring_error_state(struct drm_i915_error_state_buf *m,
+				  struct drm_device *dev,
+				  struct drm_i915_error_state *error,
+				  int ring_idx)
+{
+	struct drm_i915_error_ring *ring = &error->ring[ring_idx];
+
+	if (!ring->valid)
+		return;
+
+	err_printf(m, "%s command stream:\n", ring_str(ring_idx));
+	err_printf(m, "  START: 0x%08x\n", ring->start);
+	err_printf(m, "  HEAD:  0x%08x\n", ring->head);
+	err_printf(m, "  TAIL:  0x%08x\n", ring->tail);
+	err_printf(m, "  CTL:   0x%08x\n", ring->ctl);
+	err_printf(m, "  HWS:   0x%08x\n", ring->hws);
+	err_printf(m, "  ACTHD: 0x%08x %08x\n", (u32)(ring->acthd>>32), (u32)ring->acthd);
+	err_printf(m, "  IPEIR: 0x%08x\n", ring->ipeir);
+	err_printf(m, "  IPEHR: 0x%08x\n", ring->ipehr);
+	err_printf(m, "  INSTDONE: 0x%08x\n", ring->instdone);
+	if (INTEL_INFO(dev)->gen >= 4) {
+		err_printf(m, "  BBADDR: 0x%08x %08x\n", (u32)(ring->bbaddr>>32), (u32)ring->bbaddr);
+		err_printf(m, "  BB_STATE: 0x%08x\n", ring->bbstate);
+		err_printf(m, "  INSTPS: 0x%08x\n", ring->instps);
+	}
+	err_printf(m, "  INSTPM: 0x%08x\n", ring->instpm);
+	err_printf(m, "  FADDR: 0x%08x %08x\n", upper_32_bits(ring->faddr),
+		   lower_32_bits(ring->faddr));
+	if (INTEL_INFO(dev)->gen >= 6) {
+		err_printf(m, "  RC PSMI: 0x%08x\n", ring->rc_psmi);
+		err_printf(m, "  FAULT_REG: 0x%08x\n", ring->fault_reg);
+		err_printf(m, "  SYNC_0: 0x%08x [last synced 0x%08x]\n",
+			   ring->semaphore_mboxes[0],
+			   ring->semaphore_seqno[0]);
+		err_printf(m, "  SYNC_1: 0x%08x [last synced 0x%08x]\n",
+			   ring->semaphore_mboxes[1],
+			   ring->semaphore_seqno[1]);
+		if (HAS_VEBOX(dev)) {
+			err_printf(m, "  SYNC_2: 0x%08x [last synced 0x%08x]\n",
+				   ring->semaphore_mboxes[2],
+				   ring->semaphore_seqno[2]);
+		}
+	}
+	if (USES_PPGTT(dev)) {
+		err_printf(m, "  GFX_MODE: 0x%08x\n", ring->vm_info.gfx_mode);
+
+		if (INTEL_INFO(dev)->gen >= 8) {
+			int i;
+			for (i = 0; i < 4; i++)
+				err_printf(m, "  PDP%d: 0x%016llx\n",
+					   i, ring->vm_info.pdp[i]);
+		} else {
+			err_printf(m, "  PP_DIR_BASE: 0x%08x\n",
+				   ring->vm_info.pp_dir_base);
+		}
+	}
+	err_printf(m, "  seqno: 0x%08x\n", ring->seqno);
+	err_printf(m, "  last_seqno: 0x%08x\n", ring->last_seqno);
+	err_printf(m, "  waiting: %s\n", yesno(ring->waiting));
+	err_printf(m, "  ring->head: 0x%08x\n", ring->cpu_ring_head);
+	err_printf(m, "  ring->tail: 0x%08x\n", ring->cpu_ring_tail);
+	err_printf(m, "  hangcheck: %s [%d]\n",
+		   hangcheck_action_to_str(ring->hangcheck_action),
+		   ring->hangcheck_score);
+}
+
+void i915_error_printf(struct drm_i915_error_state_buf *e, const char *f, ...)
+{
+	va_list args;
+
+	va_start(args, f);
+	i915_error_vprintf(e, f, args);
+	va_end(args);
+}
+
+static void print_error_obj(struct drm_i915_error_state_buf *m,
+			    struct drm_i915_error_object *obj)
+{
+	int page, offset, elt;
+
+	for (page = offset = 0; page < obj->page_count; page++) {
+		for (elt = 0; elt < PAGE_SIZE/4; elt++) {
+			err_printf(m, "%08x :  %08x\n", offset,
+				   obj->pages[page][elt]);
+			offset += 4;
+		}
+	}
+}
+
+int i915_error_state_to_str(struct drm_i915_error_state_buf *m,
+			    const struct i915_error_state_file_priv *error_priv)
+{
+	struct drm_device *dev = error_priv->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct drm_i915_error_state *error = error_priv->error;
+	struct drm_i915_error_object *obj;
+	int i, j, offset, elt;
+	int max_hangcheck_score;
+
+	if (!error) {
+		err_printf(m, "no error state collected\n");
+		goto out;
+	}
+
+	err_printf(m, "%s\n", error->error_msg);
+	err_printf(m, "Time: %ld s %ld us\n", error->time.tv_sec,
+		   error->time.tv_usec);
+	err_printf(m, "Kernel: " UTS_RELEASE "\n");
+	max_hangcheck_score = 0;
+	for (i = 0; i < ARRAY_SIZE(error->ring); i++) {
+		if (error->ring[i].hangcheck_score > max_hangcheck_score)
+			max_hangcheck_score = error->ring[i].hangcheck_score;
+	}
+	for (i = 0; i < ARRAY_SIZE(error->ring); i++) {
+		if (error->ring[i].hangcheck_score == max_hangcheck_score &&
+		    error->ring[i].pid != -1) {
+			err_printf(m, "Active process (on ring %s): %s [%d]\n",
+				   ring_str(i),
+				   error->ring[i].comm,
+				   error->ring[i].pid);
+		}
+	}
+	err_printf(m, "Reset count: %u\n", error->reset_count);
+	err_printf(m, "Suspend count: %u\n", error->suspend_count);
+	err_printf(m, "PCI ID: 0x%04x\n", dev->pdev->device);
+	err_printf(m, "PCI Revision: 0x%02x\n", dev->pdev->revision);
+	err_printf(m, "PCI Subsystem: %04x:%04x\n",
+		   dev->pdev->subsystem_vendor,
+		   dev->pdev->subsystem_device);
+	err_printf(m, "IOMMU enabled?: %d\n", error->iommu);
+
+	if (HAS_CSR(dev)) {
+		struct intel_csr *csr = &dev_priv->csr;
+
+		err_printf(m, "DMC loaded: %s\n",
+			   yesno(csr->dmc_payload != NULL));
+		err_printf(m, "DMC fw version: %d.%d\n",
+			   CSR_VERSION_MAJOR(csr->version),
+			   CSR_VERSION_MINOR(csr->version));
+	}
+
+	err_printf(m, "EIR: 0x%08x\n", error->eir);
+	err_printf(m, "IER: 0x%08x\n", error->ier);
+	if (INTEL_INFO(dev)->gen >= 8) {
+		for (i = 0; i < 4; i++)
+			err_printf(m, "GTIER gt %d: 0x%08x\n", i,
+				   error->gtier[i]);
+	} else if (HAS_PCH_SPLIT(dev) || IS_VALLEYVIEW(dev))
+		err_printf(m, "GTIER: 0x%08x\n", error->gtier[0]);
+	err_printf(m, "PGTBL_ER: 0x%08x\n", error->pgtbl_er);
+	err_printf(m, "FORCEWAKE: 0x%08x\n", error->forcewake);
+	err_printf(m, "DERRMR: 0x%08x\n", error->derrmr);
+	err_printf(m, "CCID: 0x%08x\n", error->ccid);
+	err_printf(m, "Missed interrupts: 0x%08lx\n", dev_priv->gpu_error.missed_irq_rings);
+
+	for (i = 0; i < dev_priv->num_fence_regs; i++)
+		err_printf(m, "  fence[%d] = %08llx\n", i, error->fence[i]);
+
+	for (i = 0; i < ARRAY_SIZE(error->extra_instdone); i++)
+		err_printf(m, "  INSTDONE_%d: 0x%08x\n", i,
+			   error->extra_instdone[i]);
+
+	if (INTEL_INFO(dev)->gen >= 6) {
+		err_printf(m, "ERROR: 0x%08x\n", error->error);
+
+		if (INTEL_INFO(dev)->gen >= 8)
+			err_printf(m, "FAULT_TLB_DATA: 0x%08x 0x%08x\n",
+				   error->fault_data1, error->fault_data0);
+
+		err_printf(m, "DONE_REG: 0x%08x\n", error->done_reg);
+	}
+
+	if (INTEL_INFO(dev)->gen == 7)
+		err_printf(m, "ERR_INT: 0x%08x\n", error->err_int);
+
+	for (i = 0; i < ARRAY_SIZE(error->ring); i++)
+		i915_ring_error_state(m, dev, error, i);
+
+	for (i = 0; i < error->vm_count; i++) {
+		err_printf(m, "vm[%d]\n", i);
+
+		print_error_buffers(m, "Active",
+				    error->active_bo[i],
+				    error->active_bo_count[i]);
+
+		print_error_buffers(m, "Pinned",
+				    error->pinned_bo[i],
+				    error->pinned_bo_count[i]);
+	}
+
+	for (i = 0; i < ARRAY_SIZE(error->ring); i++) {
+		obj = error->ring[i].batchbuffer;
+		if (obj) {
+			err_puts(m, dev_priv->engine[i].name);
+			if (error->ring[i].pid != -1)
+				err_printf(m, " (submitted by %s [%d])",
+					   error->ring[i].comm,
+					   error->ring[i].pid);
+			err_printf(m, " --- gtt_offset = 0x%08x %08x\n",
+				   upper_32_bits(obj->gtt_offset),
+				   lower_32_bits(obj->gtt_offset));
+			print_error_obj(m, obj);
+		}
+
+		obj = error->ring[i].wa_batchbuffer;
+		if (obj) {
+			err_printf(m, "%s (w/a) --- gtt_offset = 0x%08x\n",
+				   dev_priv->engine[i].name,
+				   lower_32_bits(obj->gtt_offset));
+			print_error_obj(m, obj);
+		}
+
+		if (error->ring[i].num_requests) {
+			err_printf(m, "%s --- %d requests\n",
+				   dev_priv->engine[i].name,
+				   error->ring[i].num_requests);
+			for (j = 0; j < error->ring[i].num_requests; j++) {
+				err_printf(m, "  seqno 0x%08x, emitted %ld, tail 0x%08x\n",
+					   error->ring[i].requests[j].seqno,
+					   error->ring[i].requests[j].jiffies,
+					   error->ring[i].requests[j].tail);
+			}
+		}
+
+		if ((obj = error->ring[i].ringbuffer)) {
+			err_printf(m, "%s --- ringbuffer = 0x%08x\n",
+				   dev_priv->engine[i].name,
+				   lower_32_bits(obj->gtt_offset));
+			print_error_obj(m, obj);
+		}
+
+		if ((obj = error->ring[i].hws_page)) {
+			u64 hws_offset = obj->gtt_offset;
+			u32 *hws_page = &obj->pages[0][0];
+
+			if (i915.enable_execlists) {
+				hws_offset += LRC_PPHWSP_PN * PAGE_SIZE;
+				hws_page = &obj->pages[LRC_PPHWSP_PN][0];
+			}
+			err_printf(m, "%s --- HW Status = 0x%08llx\n",
+				   dev_priv->engine[i].name, hws_offset);
+			offset = 0;
+			for (elt = 0; elt < PAGE_SIZE/16; elt += 4) {
+				err_printf(m, "[%04x] %08x %08x %08x %08x\n",
+					   offset,
+					   hws_page[elt],
+					   hws_page[elt+1],
+					   hws_page[elt+2],
+					   hws_page[elt+3]);
+					offset += 16;
+			}
+		}
+
+		obj = error->ring[i].wa_ctx;
+		if (obj) {
+			u64 wa_ctx_offset = obj->gtt_offset;
+			u32 *wa_ctx_page = &obj->pages[0][0];
+			struct intel_engine_cs *engine = &dev_priv->engine[RCS];
+			u32 wa_ctx_size = (engine->wa_ctx.indirect_ctx.size +
+					   engine->wa_ctx.per_ctx.size);
+
+			err_printf(m, "%s --- WA ctx batch buffer = 0x%08llx\n",
+				   dev_priv->engine[i].name, wa_ctx_offset);
+			offset = 0;
+			for (elt = 0; elt < wa_ctx_size; elt += 4) {
+				err_printf(m, "[%04x] %08x %08x %08x %08x\n",
+					   offset,
+					   wa_ctx_page[elt + 0],
+					   wa_ctx_page[elt + 1],
+					   wa_ctx_page[elt + 2],
+					   wa_ctx_page[elt + 3]);
+				offset += 16;
+			}
+		}
+
+		if ((obj = error->ring[i].ctx)) {
+			err_printf(m, "%s --- HW Context = 0x%08x\n",
+				   dev_priv->engine[i].name,
+				   lower_32_bits(obj->gtt_offset));
+			print_error_obj(m, obj);
+		}
+	}
+
+	if ((obj = error->semaphore_obj)) {
+		err_printf(m, "Semaphore page = 0x%08x\n",
+			   lower_32_bits(obj->gtt_offset));
+		for (elt = 0; elt < PAGE_SIZE/16; elt += 4) {
+			err_printf(m, "[%04x] %08x %08x %08x %08x\n",
+				   elt * 4,
+				   obj->pages[0][elt],
+				   obj->pages[0][elt+1],
+				   obj->pages[0][elt+2],
+				   obj->pages[0][elt+3]);
+		}
+	}
+
+	if (error->overlay)
+		intel_overlay_print_error_state(m, error->overlay);
+
+	if (error->display)
+		intel_display_print_error_state(m, dev, error->display);
+
+out:
+	if (m->bytes == 0 && m->err)
+		return m->err;
+
+	return 0;
+}
+
+int i915_error_state_buf_init(struct drm_i915_error_state_buf *ebuf,
+			      struct drm_i915_private *i915,
+			      size_t count, loff_t pos)
+{
+	memset(ebuf, 0, sizeof(*ebuf));
+	ebuf->i915 = i915;
+
+	/* We need to have enough room to store any i915_error_state printf
+	 * so that we can move it to start position.
+	 */
+	ebuf->size = count + 1 > PAGE_SIZE ? count + 1 : PAGE_SIZE;
+	ebuf->buf = kmalloc(ebuf->size,
+				GFP_TEMPORARY | __GFP_NORETRY | __GFP_NOWARN);
+
+	if (ebuf->buf == NULL) {
+		ebuf->size = PAGE_SIZE;
+		ebuf->buf = kmalloc(ebuf->size, GFP_TEMPORARY);
+	}
+
+	if (ebuf->buf == NULL) {
+		ebuf->size = 128;
+		ebuf->buf = kmalloc(ebuf->size, GFP_TEMPORARY);
+	}
+
+	if (ebuf->buf == NULL)
+		return -ENOMEM;
+
+	ebuf->start = pos;
+
+	return 0;
+}
+
+static void i915_error_object_free(struct drm_i915_error_object *obj)
+{
+	int page;
+
+	if (obj == NULL)
+		return;
+
+	for (page = 0; page < obj->page_count; page++)
+		kfree(obj->pages[page]);
+
+	kfree(obj);
+}
+
+static void i915_error_state_free(struct kref *error_ref)
+{
+	struct drm_i915_error_state *error = container_of(error_ref,
+							  typeof(*error), ref);
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(error->ring); i++) {
+		i915_error_object_free(error->ring[i].batchbuffer);
+		i915_error_object_free(error->ring[i].wa_batchbuffer);
+		i915_error_object_free(error->ring[i].ringbuffer);
+		i915_error_object_free(error->ring[i].hws_page);
+		i915_error_object_free(error->ring[i].ctx);
+		kfree(error->ring[i].requests);
+		i915_error_object_free(error->ring[i].wa_ctx);
+	}
+
+	i915_error_object_free(error->semaphore_obj);
+
+	for (i = 0; i < error->vm_count; i++)
+		kfree(error->active_bo[i]);
+
+	kfree(error->active_bo);
+	kfree(error->active_bo_count);
+	kfree(error->pinned_bo);
+	kfree(error->pinned_bo_count);
+	kfree(error->overlay);
+	kfree(error->display);
+	kfree(error);
+}
+
+static struct drm_i915_error_object *
+i915_error_object_create(struct drm_i915_private *dev_priv,
+			 struct drm_i915_gem_object *src,
+			 struct i915_address_space *vm)
+{
+	struct i915_ggtt *ggtt = &dev_priv->ggtt;
+	struct drm_i915_error_object *dst;
+	struct i915_vma *vma = NULL;
+	int num_pages;
+	bool use_ggtt;
+	int i = 0;
+	u64 reloc_offset;
+
+	if (src == NULL || src->pages == NULL)
+		return NULL;
+
+	num_pages = src->base.size >> PAGE_SHIFT;
+
+	dst = kmalloc(sizeof(*dst) + num_pages * sizeof(u32 *), GFP_ATOMIC);
+	if (dst == NULL)
+		return NULL;
+
+	if (i915_gem_obj_bound(src, vm))
+		dst->gtt_offset = i915_gem_obj_offset(src, vm);
+	else
+		dst->gtt_offset = -1;
+
+	reloc_offset = dst->gtt_offset;
+	if (i915_is_ggtt(vm))
+		vma = i915_gem_obj_to_ggtt(src);
+	use_ggtt = (src->cache_level == I915_CACHE_NONE &&
+		   vma && (vma->bound & GLOBAL_BIND) &&
+		   reloc_offset + num_pages * PAGE_SIZE <= ggtt->mappable_end);
+
+	/* Cannot access stolen address directly, try to use the aperture */
+	if (src->stolen) {
+		use_ggtt = true;
+
+		if (!(vma && vma->bound & GLOBAL_BIND))
+			goto unwind;
+
+		reloc_offset = i915_gem_obj_ggtt_offset(src);
+		if (reloc_offset + num_pages * PAGE_SIZE > ggtt->mappable_end)
+			goto unwind;
+	}
+
+	/* Cannot access snooped pages through the aperture */
+	if (use_ggtt && src->cache_level != I915_CACHE_NONE &&
+	    !HAS_LLC(dev_priv))
+		goto unwind;
+
+	dst->page_count = num_pages;
+	while (num_pages--) {
+		unsigned long flags;
+		void *d;
+
+		d = kmalloc(PAGE_SIZE, GFP_ATOMIC);
+		if (d == NULL)
+			goto unwind;
+
+		local_irq_save(flags);
+		if (use_ggtt) {
+			void __iomem *s;
+
+			/* Simply ignore tiling or any overlapping fence.
+			 * It's part of the error state, and this hopefully
+			 * captures what the GPU read.
+			 */
+
+			s = io_mapping_map_atomic_wc(ggtt->mappable,
+						     reloc_offset);
+			memcpy_fromio(d, s, PAGE_SIZE);
+			io_mapping_unmap_atomic(s);
+		} else {
+			struct page *page;
+			void *s;
+
+			page = i915_gem_object_get_page(src, i);
+
+			drm_clflush_pages(&page, 1);
+
+			s = kmap_atomic(page);
+			memcpy(d, s, PAGE_SIZE);
+			kunmap_atomic(s);
+
+			drm_clflush_pages(&page, 1);
+		}
+		local_irq_restore(flags);
+
+		dst->pages[i++] = d;
+		reloc_offset += PAGE_SIZE;
+	}
+
+	return dst;
+
+unwind:
+	while (i--)
+		kfree(dst->pages[i]);
+	kfree(dst);
+	return NULL;
+}
+#define i915_error_ggtt_object_create(dev_priv, src) \
+	i915_error_object_create((dev_priv), (src), &(dev_priv)->ggtt.base)
+
+static void capture_bo(struct drm_i915_error_buffer *err,
+		       struct i915_vma *vma)
+{
+	struct drm_i915_gem_object *obj = vma->obj;
+	int i;
+
+	err->size = obj->base.size;
+	err->name = obj->base.name;
+	for (i = 0; i < I915_NUM_ENGINES; i++)
+		err->rseqno[i] = i915_gem_request_get_seqno(obj->last_read_req[i]);
+	err->wseqno = i915_gem_request_get_seqno(obj->last_write_req);
+	err->gtt_offset = vma->node.start;
+	err->read_domains = obj->base.read_domains;
+	err->write_domain = obj->base.write_domain;
+	err->fence_reg = obj->fence_reg;
+	err->pinned = 0;
+	if (i915_gem_obj_is_pinned(obj))
+		err->pinned = 1;
+	err->tiling = obj->tiling_mode;
+	err->dirty = obj->dirty;
+	err->purgeable = obj->madv != I915_MADV_WILLNEED;
+	err->userptr = obj->userptr.mm != NULL;
+	err->ring = obj->last_write_req ?
+			i915_gem_request_get_engine(obj->last_write_req)->id : -1;
+	err->cache_level = obj->cache_level;
+}
+
+static u32 capture_active_bo(struct drm_i915_error_buffer *err,
+			     int count, struct list_head *head)
+{
+	struct i915_vma *vma;
+	int i = 0;
+
+	list_for_each_entry(vma, head, vm_link) {
+		capture_bo(err++, vma);
+		if (++i == count)
+			break;
+	}
+
+	return i;
+}
+
+static u32 capture_pinned_bo(struct drm_i915_error_buffer *err,
+			     int count, struct list_head *head,
+			     struct i915_address_space *vm)
+{
+	struct drm_i915_gem_object *obj;
+	struct drm_i915_error_buffer * const first = err;
+	struct drm_i915_error_buffer * const last = err + count;
+
+	list_for_each_entry(obj, head, global_list) {
+		struct i915_vma *vma;
+
+		if (err == last)
+			break;
+
+		list_for_each_entry(vma, &obj->vma_list, obj_link)
+			if (vma->vm == vm && vma->pin_count > 0)
+				capture_bo(err++, vma);
+	}
+
+	return err - first;
+}
+
+/* Generate a semi-unique error code. The code is not meant to have meaning, The
+ * code's only purpose is to try to prevent false duplicated bug reports by
+ * grossly estimating a GPU error state.
+ *
+ * TODO Ideally, hashing the batchbuffer would be a very nice way to determine
+ * the hang if we could strip the GTT offset information from it.
+ *
+ * It's only a small step better than a random number in its current form.
+ */
+static uint32_t i915_error_generate_code(struct drm_i915_private *dev_priv,
+					 struct drm_i915_error_state *error,
+					 int *ring_id)
+{
+	uint32_t error_code = 0;
+	int i;
+
+	/* IPEHR would be an ideal way to detect errors, as it's the gross
+	 * measure of "the command that hung." However, has some very common
+	 * synchronization commands which almost always appear in the case
+	 * strictly a client bug. Use instdone to differentiate those some.
+	 */
+	for (i = 0; i < I915_NUM_ENGINES; i++) {
+		if (error->ring[i].hangcheck_action == HANGCHECK_HUNG) {
+			if (ring_id)
+				*ring_id = i;
+
+			return error->ring[i].ipehr ^ error->ring[i].instdone;
+		}
+	}
+
+	return error_code;
+}
+
+static void i915_gem_record_fences(struct drm_device *dev,
+				   struct drm_i915_error_state *error)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	int i;
+
+	if (IS_GEN3(dev) || IS_GEN2(dev)) {
+		for (i = 0; i < dev_priv->num_fence_regs; i++)
+			error->fence[i] = I915_READ(FENCE_REG(i));
+	} else if (IS_GEN5(dev) || IS_GEN4(dev)) {
+		for (i = 0; i < dev_priv->num_fence_regs; i++)
+			error->fence[i] = I915_READ64(FENCE_REG_965_LO(i));
+	} else if (INTEL_INFO(dev)->gen >= 6) {
+		for (i = 0; i < dev_priv->num_fence_regs; i++)
+			error->fence[i] = I915_READ64(FENCE_REG_GEN6_LO(i));
+	}
+}
+
+
+static void gen8_record_semaphore_state(struct drm_i915_private *dev_priv,
+					struct drm_i915_error_state *error,
+					struct intel_engine_cs *engine,
+					struct drm_i915_error_ring *ering)
+{
+	struct intel_engine_cs *to;
+	enum intel_engine_id id;
+
+	if (!i915_semaphore_is_enabled(dev_priv->dev))
+		return;
+
+	if (!error->semaphore_obj)
+		error->semaphore_obj =
+			i915_error_ggtt_object_create(dev_priv,
+						      dev_priv->semaphore_obj);
+
+	for_each_engine_id(to, dev_priv, id) {
+		int idx;
+		u16 signal_offset;
+		u32 *tmp;
+
+		if (engine == to)
+			continue;
+
+		signal_offset = (GEN8_SIGNAL_OFFSET(engine, id) & (PAGE_SIZE - 1))
+				/ 4;
+		tmp = error->semaphore_obj->pages[0];
+		idx = intel_ring_sync_index(engine, to);
+
+		ering->semaphore_mboxes[idx] = tmp[signal_offset];
+		ering->semaphore_seqno[idx] = engine->semaphore.sync_seqno[idx];
+	}
+}
+
+static void gen6_record_semaphore_state(struct drm_i915_private *dev_priv,
+					struct intel_engine_cs *engine,
+					struct drm_i915_error_ring *ering)
+{
+	ering->semaphore_mboxes[0] = I915_READ(RING_SYNC_0(engine->mmio_base));
+	ering->semaphore_mboxes[1] = I915_READ(RING_SYNC_1(engine->mmio_base));
+	ering->semaphore_seqno[0] = engine->semaphore.sync_seqno[0];
+	ering->semaphore_seqno[1] = engine->semaphore.sync_seqno[1];
+
+	if (HAS_VEBOX(dev_priv)) {
+		ering->semaphore_mboxes[2] =
+			I915_READ(RING_SYNC_2(engine->mmio_base));
+		ering->semaphore_seqno[2] = engine->semaphore.sync_seqno[2];
+	}
+}
+
+static void i915_record_ring_state(struct drm_device *dev,
+				   struct drm_i915_error_state *error,
+				   struct intel_engine_cs *engine,
+				   struct drm_i915_error_ring *ering)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	if (INTEL_INFO(dev)->gen >= 6) {
+		ering->rc_psmi = I915_READ(RING_PSMI_CTL(engine->mmio_base));
+		ering->fault_reg = I915_READ(RING_FAULT_REG(engine));
+		if (INTEL_INFO(dev)->gen >= 8)
+			gen8_record_semaphore_state(dev_priv, error, engine,
+						    ering);
+		else
+			gen6_record_semaphore_state(dev_priv, engine, ering);
+	}
+
+	if (INTEL_INFO(dev)->gen >= 4) {
+		ering->faddr = I915_READ(RING_DMA_FADD(engine->mmio_base));
+		ering->ipeir = I915_READ(RING_IPEIR(engine->mmio_base));
+		ering->ipehr = I915_READ(RING_IPEHR(engine->mmio_base));
+		ering->instdone = I915_READ(RING_INSTDONE(engine->mmio_base));
+		ering->instps = I915_READ(RING_INSTPS(engine->mmio_base));
+		ering->bbaddr = I915_READ(RING_BBADDR(engine->mmio_base));
+		if (INTEL_INFO(dev)->gen >= 8) {
+			ering->faddr |= (u64) I915_READ(RING_DMA_FADD_UDW(engine->mmio_base)) << 32;
+			ering->bbaddr |= (u64) I915_READ(RING_BBADDR_UDW(engine->mmio_base)) << 32;
+		}
+		ering->bbstate = I915_READ(RING_BBSTATE(engine->mmio_base));
+	} else {
+		ering->faddr = I915_READ(DMA_FADD_I8XX);
+		ering->ipeir = I915_READ(IPEIR);
+		ering->ipehr = I915_READ(IPEHR);
+		ering->instdone = I915_READ(GEN2_INSTDONE);
+	}
+
+	ering->waiting = waitqueue_active(&engine->irq_queue);
+	ering->instpm = I915_READ(RING_INSTPM(engine->mmio_base));
+	ering->acthd = intel_ring_get_active_head(engine);
+	ering->seqno = engine->get_seqno(engine);
+	ering->last_seqno = engine->last_submitted_seqno;
+	ering->start = I915_READ_START(engine);
+	ering->head = I915_READ_HEAD(engine);
+	ering->tail = I915_READ_TAIL(engine);
+	ering->ctl = I915_READ_CTL(engine);
+
+	if (I915_NEED_GFX_HWS(dev)) {
+		i915_reg_t mmio;
+
+		if (IS_GEN7(dev)) {
+			switch (engine->id) {
+			default:
+			case RCS:
+				mmio = RENDER_HWS_PGA_GEN7;
+				break;
+			case BCS:
+				mmio = BLT_HWS_PGA_GEN7;
+				break;
+			case VCS:
+				mmio = BSD_HWS_PGA_GEN7;
+				break;
+			case VECS:
+				mmio = VEBOX_HWS_PGA_GEN7;
+				break;
+			}
+		} else if (IS_GEN6(engine->dev)) {
+			mmio = RING_HWS_PGA_GEN6(engine->mmio_base);
+		} else {
+			/* XXX: gen8 returns to sanity */
+			mmio = RING_HWS_PGA(engine->mmio_base);
+		}
+
+		ering->hws = I915_READ(mmio);
+	}
+
+	ering->hangcheck_score = engine->hangcheck.score;
+	ering->hangcheck_action = engine->hangcheck.action;
+
+	if (USES_PPGTT(dev)) {
+		int i;
+
+		ering->vm_info.gfx_mode = I915_READ(RING_MODE_GEN7(engine));
+
+		if (IS_GEN6(dev))
+			ering->vm_info.pp_dir_base =
+				I915_READ(RING_PP_DIR_BASE_READ(engine));
+		else if (IS_GEN7(dev))
+			ering->vm_info.pp_dir_base =
+				I915_READ(RING_PP_DIR_BASE(engine));
+		else if (INTEL_INFO(dev)->gen >= 8)
+			for (i = 0; i < 4; i++) {
+				ering->vm_info.pdp[i] =
+					I915_READ(GEN8_RING_PDP_UDW(engine, i));
+				ering->vm_info.pdp[i] <<= 32;
+				ering->vm_info.pdp[i] |=
+					I915_READ(GEN8_RING_PDP_LDW(engine, i));
+			}
+	}
+}
+
+
+static void i915_gem_record_active_context(struct intel_engine_cs *engine,
+					   struct drm_i915_error_state *error,
+					   struct drm_i915_error_ring *ering)
+{
+	struct drm_i915_private *dev_priv = engine->dev->dev_private;
+	struct drm_i915_gem_object *obj;
+
+	/* Currently render ring is the only HW context user */
+	if (engine->id != RCS || !error->ccid)
+		return;
+
+	list_for_each_entry(obj, &dev_priv->mm.bound_list, global_list) {
+		if (!i915_gem_obj_ggtt_bound(obj))
+			continue;
+
+		if ((error->ccid & PAGE_MASK) == i915_gem_obj_ggtt_offset(obj)) {
+			ering->ctx = i915_error_ggtt_object_create(dev_priv, obj);
+			break;
+		}
+	}
+}
+
+static void i915_gem_record_rings(struct drm_device *dev,
+				  struct drm_i915_error_state *error)
+{
+	struct drm_i915_private *dev_priv = to_i915(dev);
+	struct i915_ggtt *ggtt = &dev_priv->ggtt;
+	struct drm_i915_gem_request *request;
+	int i, count;
+
+	for (i = 0; i < I915_NUM_ENGINES; i++) {
+		struct intel_engine_cs *engine = &dev_priv->engine[i];
+		struct intel_ringbuffer *rbuf;
+
+		error->ring[i].pid = -1;
+
+		if (engine->dev == NULL)
+			continue;
+
+		error->ring[i].valid = true;
+
+		i915_record_ring_state(dev, error, engine, &error->ring[i]);
+
+		request = i915_gem_find_active_request(engine);
+		if (request) {
+			struct i915_address_space *vm;
+
+			vm = request->ctx && request->ctx->ppgtt ?
+				&request->ctx->ppgtt->base :
+				&ggtt->base;
+
+			/* We need to copy these to an anonymous buffer
+			 * as the simplest method to avoid being overwritten
+			 * by userspace.
+			 */
+			error->ring[i].batchbuffer =
+				i915_error_object_create(dev_priv,
+							 request->batch_obj,
+							 vm);
+
+			if (HAS_BROKEN_CS_TLB(dev_priv))
+				error->ring[i].wa_batchbuffer =
+					i915_error_ggtt_object_create(dev_priv,
+							     engine->scratch.obj);
+
+			if (request->pid) {
+				struct task_struct *task;
+
+				rcu_read_lock();
+				task = pid_task(request->pid, PIDTYPE_PID);
+				if (task) {
+					strcpy(error->ring[i].comm, task->comm);
+					error->ring[i].pid = task->pid;
+				}
+				rcu_read_unlock();
+			}
+		}
+
+		if (i915.enable_execlists) {
+			/* TODO: This is only a small fix to keep basic error
+			 * capture working, but we need to add more information
+			 * for it to be useful (e.g. dump the context being
+			 * executed).
+			 */
+			if (request)
+				rbuf = request->ctx->engine[engine->id].ringbuf;
+			else
+				rbuf = dev_priv->kernel_context->engine[engine->id].ringbuf;
+		} else
+			rbuf = engine->buffer;
+
+		error->ring[i].cpu_ring_head = rbuf->head;
+		error->ring[i].cpu_ring_tail = rbuf->tail;
+
+		error->ring[i].ringbuffer =
+			i915_error_ggtt_object_create(dev_priv, rbuf->obj);
+
+		error->ring[i].hws_page =
+			i915_error_ggtt_object_create(dev_priv,
+						      engine->status_page.obj);
+
+		if (engine->wa_ctx.obj) {
+			error->ring[i].wa_ctx =
+				i915_error_ggtt_object_create(dev_priv,
+							      engine->wa_ctx.obj);
+		}
+
+		i915_gem_record_active_context(engine, error, &error->ring[i]);
+
+		count = 0;
+		list_for_each_entry(request, &engine->request_list, list)
+			count++;
+
+		error->ring[i].num_requests = count;
+		error->ring[i].requests =
+			kcalloc(count, sizeof(*error->ring[i].requests),
+				GFP_ATOMIC);
+		if (error->ring[i].requests == NULL) {
+			error->ring[i].num_requests = 0;
+			continue;
+		}
+
+		count = 0;
+		list_for_each_entry(request, &engine->request_list, list) {
+			struct drm_i915_error_request *erq;
+
+			if (count >= error->ring[i].num_requests) {
+				/*
+				 * If the ring request list was changed in
+				 * between the point where the error request
+				 * list was created and dimensioned and this
+				 * point then just exit early to avoid crashes.
+				 *
+				 * We don't need to communicate that the
+				 * request list changed state during error
+				 * state capture and that the error state is
+				 * slightly incorrect as a consequence since we
+				 * are typically only interested in the request
+				 * list state at the point of error state
+				 * capture, not in any changes happening during
+				 * the capture.
+				 */
+				break;
+			}
+
+			erq = &error->ring[i].requests[count++];
+			erq->seqno = request->seqno;
+			erq->jiffies = request->emitted_jiffies;
+			erq->tail = request->postfix;
+		}
+	}
+}
+
+/* FIXME: Since pin count/bound list is global, we duplicate what we capture per
+ * VM.
+ */
+static void i915_gem_capture_vm(struct drm_i915_private *dev_priv,
+				struct drm_i915_error_state *error,
+				struct i915_address_space *vm,
+				const int ndx)
+{
+	struct drm_i915_error_buffer *active_bo = NULL, *pinned_bo = NULL;
+	struct drm_i915_gem_object *obj;
+	struct i915_vma *vma;
+	int i;
+
+	i = 0;
+	list_for_each_entry(vma, &vm->active_list, vm_link)
+		i++;
+	error->active_bo_count[ndx] = i;
+
+	list_for_each_entry(obj, &dev_priv->mm.bound_list, global_list) {
+		list_for_each_entry(vma, &obj->vma_list, obj_link)
+			if (vma->vm == vm && vma->pin_count > 0)
+				i++;
+	}
+	error->pinned_bo_count[ndx] = i - error->active_bo_count[ndx];
+
+	if (i) {
+		active_bo = kcalloc(i, sizeof(*active_bo), GFP_ATOMIC);
+		if (active_bo)
+			pinned_bo = active_bo + error->active_bo_count[ndx];
+	}
+
+	if (active_bo)
+		error->active_bo_count[ndx] =
+			capture_active_bo(active_bo,
+					  error->active_bo_count[ndx],
+					  &vm->active_list);
+
+	if (pinned_bo)
+		error->pinned_bo_count[ndx] =
+			capture_pinned_bo(pinned_bo,
+					  error->pinned_bo_count[ndx],
+					  &dev_priv->mm.bound_list, vm);
+	error->active_bo[ndx] = active_bo;
+	error->pinned_bo[ndx] = pinned_bo;
+}
+
+static void i915_gem_capture_buffers(struct drm_i915_private *dev_priv,
+				     struct drm_i915_error_state *error)
+{
+	struct i915_address_space *vm;
+	int cnt = 0, i = 0;
+
+	list_for_each_entry(vm, &dev_priv->vm_list, global_link)
+		cnt++;
+
+	error->active_bo = kcalloc(cnt, sizeof(*error->active_bo), GFP_ATOMIC);
+	error->pinned_bo = kcalloc(cnt, sizeof(*error->pinned_bo), GFP_ATOMIC);
+	error->active_bo_count = kcalloc(cnt, sizeof(*error->active_bo_count),
+					 GFP_ATOMIC);
+	error->pinned_bo_count = kcalloc(cnt, sizeof(*error->pinned_bo_count),
+					 GFP_ATOMIC);
+
+	if (error->active_bo == NULL ||
+	    error->pinned_bo == NULL ||
+	    error->active_bo_count == NULL ||
+	    error->pinned_bo_count == NULL) {
+		kfree(error->active_bo);
+		kfree(error->active_bo_count);
+		kfree(error->pinned_bo);
+		kfree(error->pinned_bo_count);
+
+		error->active_bo = NULL;
+		error->active_bo_count = NULL;
+		error->pinned_bo = NULL;
+		error->pinned_bo_count = NULL;
+	} else {
+		list_for_each_entry(vm, &dev_priv->vm_list, global_link)
+			i915_gem_capture_vm(dev_priv, error, vm, i++);
+
+		error->vm_count = cnt;
+	}
+}
+
+/* Capture all registers which don't fit into another category. */
+static void i915_capture_reg_state(struct drm_i915_private *dev_priv,
+				   struct drm_i915_error_state *error)
+{
+	struct drm_device *dev = dev_priv->dev;
+	int i;
+
+	/* General organization
+	 * 1. Registers specific to a single generation
+	 * 2. Registers which belong to multiple generations
+	 * 3. Feature specific registers.
+	 * 4. Everything else
+	 * Please try to follow the order.
+	 */
+
+	/* 1: Registers specific to a single generation */
+	if (IS_VALLEYVIEW(dev)) {
+		error->gtier[0] = I915_READ(GTIER);
+		error->ier = I915_READ(VLV_IER);
+		error->forcewake = I915_READ_FW(FORCEWAKE_VLV);
+	}
+
+	if (IS_GEN7(dev))
+		error->err_int = I915_READ(GEN7_ERR_INT);
+
+	if (INTEL_INFO(dev)->gen >= 8) {
+		error->fault_data0 = I915_READ(GEN8_FAULT_TLB_DATA0);
+		error->fault_data1 = I915_READ(GEN8_FAULT_TLB_DATA1);
+	}
+
+	if (IS_GEN6(dev)) {
+		error->forcewake = I915_READ_FW(FORCEWAKE);
+		error->gab_ctl = I915_READ(GAB_CTL);
+		error->gfx_mode = I915_READ(GFX_MODE);
+	}
+
+	/* 2: Registers which belong to multiple generations */
+	if (INTEL_INFO(dev)->gen >= 7)
+		error->forcewake = I915_READ_FW(FORCEWAKE_MT);
+
+	if (INTEL_INFO(dev)->gen >= 6) {
+		error->derrmr = I915_READ(DERRMR);
+		error->error = I915_READ(ERROR_GEN6);
+		error->done_reg = I915_READ(DONE_REG);
+	}
+
+	/* 3: Feature specific registers */
+	if (IS_GEN6(dev) || IS_GEN7(dev)) {
+		error->gam_ecochk = I915_READ(GAM_ECOCHK);
+		error->gac_eco = I915_READ(GAC_ECO_BITS);
+	}
+
+	/* 4: Everything else */
+	if (HAS_HW_CONTEXTS(dev))
+		error->ccid = I915_READ(CCID);
+
+	if (INTEL_INFO(dev)->gen >= 8) {
+		error->ier = I915_READ(GEN8_DE_MISC_IER);
+		for (i = 0; i < 4; i++)
+			error->gtier[i] = I915_READ(GEN8_GT_IER(i));
+	} else if (HAS_PCH_SPLIT(dev)) {
+		error->ier = I915_READ(DEIER);
+		error->gtier[0] = I915_READ(GTIER);
+	} else if (IS_GEN2(dev)) {
+		error->ier = I915_READ16(IER);
+	} else if (!IS_VALLEYVIEW(dev)) {
+		error->ier = I915_READ(IER);
+	}
+	error->eir = I915_READ(EIR);
+	error->pgtbl_er = I915_READ(PGTBL_ER);
+
+	i915_get_extra_instdone(dev, error->extra_instdone);
+}
+
+static void i915_error_capture_msg(struct drm_device *dev,
+				   struct drm_i915_error_state *error,
+				   u32 engine_mask,
+				   const char *error_msg)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	u32 ecode;
+	int ring_id = -1, len;
+
+	ecode = i915_error_generate_code(dev_priv, error, &ring_id);
+
+	len = scnprintf(error->error_msg, sizeof(error->error_msg),
+			"GPU HANG: ecode %d:%d:0x%08x",
+			INTEL_INFO(dev)->gen, ring_id, ecode);
+
+	if (ring_id != -1 && error->ring[ring_id].pid != -1)
+		len += scnprintf(error->error_msg + len,
+				 sizeof(error->error_msg) - len,
+				 ", in %s [%d]",
+				 error->ring[ring_id].comm,
+				 error->ring[ring_id].pid);
+
+	scnprintf(error->error_msg + len, sizeof(error->error_msg) - len,
+		  ", reason: %s, action: %s",
+		  error_msg,
+		  engine_mask ? "reset" : "continue");
+}
+
+static void i915_capture_gen_state(struct drm_i915_private *dev_priv,
+				   struct drm_i915_error_state *error)
+{
+	error->iommu = -1;
+#ifdef CONFIG_INTEL_IOMMU
+	error->iommu = intel_iommu_gfx_mapped;
+#endif
+	error->reset_count = i915_reset_count(&dev_priv->gpu_error);
+	error->suspend_count = dev_priv->suspend_count;
+}
+
+/**
+ * i915_capture_error_state - capture an error record for later analysis
+ * @dev: drm device
+ *
+ * Should be called when an error is detected (either a hang or an error
+ * interrupt) to capture error state from the time of the error.  Fills
+ * out a structure which becomes available in debugfs for user level tools
+ * to pick up.
+ */
+void i915_capture_error_state(struct drm_device *dev, u32 engine_mask,
+			      const char *error_msg)
+{
+	static bool warned;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct drm_i915_error_state *error;
+	unsigned long flags;
+
+	/* Account for pipe specific data like PIPE*STAT */
+	error = kzalloc(sizeof(*error), GFP_ATOMIC);
+	if (!error) {
+		DRM_DEBUG_DRIVER("out of memory, not capturing error state\n");
+		return;
+	}
+
+	kref_init(&error->ref);
+
+	i915_capture_gen_state(dev_priv, error);
+	i915_capture_reg_state(dev_priv, error);
+	i915_gem_capture_buffers(dev_priv, error);
+	i915_gem_record_fences(dev, error);
+	i915_gem_record_rings(dev, error);
+
+	do_gettimeofday(&error->time);
+
+	error->overlay = intel_overlay_capture_error_state(dev);
+	error->display = intel_display_capture_error_state(dev);
+
+	i915_error_capture_msg(dev, error, engine_mask, error_msg);
+	DRM_INFO("%s\n", error->error_msg);
+
+	spin_lock_irqsave(&dev_priv->gpu_error.lock, flags);
+	if (dev_priv->gpu_error.first_error == NULL) {
+		dev_priv->gpu_error.first_error = error;
+		error = NULL;
+	}
+	spin_unlock_irqrestore(&dev_priv->gpu_error.lock, flags);
+
+	if (error) {
+		i915_error_state_free(&error->ref);
+		return;
+	}
+
+	if (!warned) {
+		DRM_INFO("GPU hangs can indicate a bug anywhere in the entire gfx stack, including userspace.\n");
+		DRM_INFO("Please file a _new_ bug report on bugs.freedesktop.org against DRI -> DRM/Intel\n");
+		DRM_INFO("drm/i915 developers can then reassign to the right component if it's not a kernel issue.\n");
+		DRM_INFO("The gpu crash dump is required to analyze gpu hangs, so please always attach it.\n");
+		DRM_INFO("GPU crash dump saved to /sys/class/drm/card%d/error\n", dev->primary->index);
+		warned = true;
+	}
+}
+
+void i915_error_state_get(struct drm_device *dev,
+			  struct i915_error_state_file_priv *error_priv)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	spin_lock_irq(&dev_priv->gpu_error.lock);
+	error_priv->error = dev_priv->gpu_error.first_error;
+	if (error_priv->error)
+		kref_get(&error_priv->error->ref);
+	spin_unlock_irq(&dev_priv->gpu_error.lock);
+
+}
+
+void i915_error_state_put(struct i915_error_state_file_priv *error_priv)
+{
+	if (error_priv->error)
+		kref_put(&error_priv->error->ref, i915_error_state_free);
+}
+
+void i915_destroy_error_state(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct drm_i915_error_state *error;
+
+	spin_lock_irq(&dev_priv->gpu_error.lock);
+	error = dev_priv->gpu_error.first_error;
+	dev_priv->gpu_error.first_error = NULL;
+	spin_unlock_irq(&dev_priv->gpu_error.lock);
+
+	if (error)
+		kref_put(&error->ref, i915_error_state_free);
+}
+
+const char *i915_cache_level_str(struct drm_i915_private *i915, int type)
+{
+	switch (type) {
+	case I915_CACHE_NONE: return " uncached";
+	case I915_CACHE_LLC: return HAS_LLC(i915) ? " LLC" : " snooped";
+	case I915_CACHE_L3_LLC: return " L3+LLC";
+	case I915_CACHE_WT: return " WT";
+	default: return "";
+	}
+}
+
+/* NB: please notice the memset */
+void i915_get_extra_instdone(struct drm_device *dev, uint32_t *instdone)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	memset(instdone, 0, sizeof(*instdone) * I915_NUM_INSTDONE_REG);
+
+	if (IS_GEN2(dev) || IS_GEN3(dev))
+		instdone[0] = I915_READ(GEN2_INSTDONE);
+	else if (IS_GEN4(dev) || IS_GEN5(dev) || IS_GEN6(dev)) {
+		instdone[0] = I915_READ(RING_INSTDONE(RENDER_RING_BASE));
+		instdone[1] = I915_READ(GEN4_INSTDONE1);
+	} else if (INTEL_INFO(dev)->gen >= 7) {
+		instdone[0] = I915_READ(RING_INSTDONE(RENDER_RING_BASE));
+		instdone[1] = I915_READ(GEN7_SC_INSTDONE);
+		instdone[2] = I915_READ(GEN7_SAMPLER_INSTDONE);
+		instdone[3] = I915_READ(GEN7_ROW_INSTDONE);
+	}
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/i915/i915_guc_reg.h
@@ -0,0 +1,120 @@
+/*
+ * Copyright © 2014 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ */
+#ifndef _I915_GUC_REG_H_
+#define _I915_GUC_REG_H_
+
+/* Definitions of GuC H/W registers, bits, etc */
+
+#define GUC_STATUS			_MMIO(0xc000)
+#define   GS_RESET_SHIFT		0
+#define   GS_MIA_IN_RESET		  (0x01 << GS_RESET_SHIFT)
+#define   GS_BOOTROM_SHIFT		1
+#define   GS_BOOTROM_MASK		  (0x7F << GS_BOOTROM_SHIFT)
+#define   GS_BOOTROM_RSA_FAILED		  (0x50 << GS_BOOTROM_SHIFT)
+#define   GS_BOOTROM_JUMP_PASSED	  (0x76 << GS_BOOTROM_SHIFT)
+#define   GS_UKERNEL_SHIFT		8
+#define   GS_UKERNEL_MASK		  (0xFF << GS_UKERNEL_SHIFT)
+#define   GS_UKERNEL_LAPIC_DONE		  (0x30 << GS_UKERNEL_SHIFT)
+#define   GS_UKERNEL_DPC_ERROR		  (0x60 << GS_UKERNEL_SHIFT)
+#define   GS_UKERNEL_READY		  (0xF0 << GS_UKERNEL_SHIFT)
+#define   GS_MIA_SHIFT			16
+#define   GS_MIA_MASK			  (0x07 << GS_MIA_SHIFT)
+#define   GS_MIA_CORE_STATE		  (0x01 << GS_MIA_SHIFT)
+#define   GS_MIA_HALT_REQUESTED		  (0x02 << GS_MIA_SHIFT)
+#define   GS_MIA_ISR_ENTRY		  (0x04 << GS_MIA_SHIFT)
+#define   GS_AUTH_STATUS_SHIFT		30
+#define   GS_AUTH_STATUS_MASK		  (0x03 << GS_AUTH_STATUS_SHIFT)
+#define   GS_AUTH_STATUS_BAD		  (0x01 << GS_AUTH_STATUS_SHIFT)
+#define   GS_AUTH_STATUS_GOOD		  (0x02 << GS_AUTH_STATUS_SHIFT)
+
+#define SOFT_SCRATCH(n)			_MMIO(0xc180 + (n) * 4)
+#define SOFT_SCRATCH_COUNT		16
+
+#define UOS_RSA_SCRATCH(i)		_MMIO(0xc200 + (i) * 4)
+#define   UOS_RSA_SCRATCH_MAX_COUNT	  64
+#define DMA_ADDR_0_LOW			_MMIO(0xc300)
+#define DMA_ADDR_0_HIGH			_MMIO(0xc304)
+#define DMA_ADDR_1_LOW			_MMIO(0xc308)
+#define DMA_ADDR_1_HIGH			_MMIO(0xc30c)
+#define   DMA_ADDRESS_SPACE_WOPCM	  (7 << 16)
+#define   DMA_ADDRESS_SPACE_GTT		  (8 << 16)
+#define DMA_COPY_SIZE			_MMIO(0xc310)
+#define DMA_CTRL			_MMIO(0xc314)
+#define   UOS_MOVE			  (1<<4)
+#define   START_DMA			  (1<<0)
+#define DMA_GUC_WOPCM_OFFSET		_MMIO(0xc340)
+#define   GUC_WOPCM_OFFSET_VALUE	  0x80000	/* 512KB */
+#define GUC_MAX_IDLE_COUNT		_MMIO(0xC3E4)
+
+#define GUC_WOPCM_SIZE			_MMIO(0xc050)
+#define   GUC_WOPCM_SIZE_VALUE  	  (0x80 << 12)	/* 512KB */
+
+/* GuC addresses below GUC_WOPCM_TOP don't map through the GTT */
+#define	GUC_WOPCM_TOP			(GUC_WOPCM_SIZE_VALUE)
+
+#define GEN8_GT_PM_CONFIG		_MMIO(0x138140)
+#define GEN9LP_GT_PM_CONFIG		_MMIO(0x138140)
+#define GEN9_GT_PM_CONFIG		_MMIO(0x13816c)
+#define   GT_DOORBELL_ENABLE		  (1<<0)
+
+#define GEN8_GTCR			_MMIO(0x4274)
+#define   GEN8_GTCR_INVALIDATE		  (1<<0)
+
+#define GUC_ARAT_C6DIS			_MMIO(0xA178)
+
+#define GUC_SHIM_CONTROL		_MMIO(0xc064)
+#define   GUC_DISABLE_SRAM_INIT_TO_ZEROES	(1<<0)
+#define   GUC_ENABLE_READ_CACHE_LOGIC		(1<<1)
+#define   GUC_ENABLE_MIA_CACHING		(1<<2)
+#define   GUC_GEN10_MSGCH_ENABLE		(1<<4)
+#define   GUC_ENABLE_READ_CACHE_FOR_SRAM_DATA	(1<<9)
+#define   GUC_ENABLE_READ_CACHE_FOR_WOPCM_DATA	(1<<10)
+#define   GUC_ENABLE_MIA_CLOCK_GATING		(1<<15)
+#define   GUC_GEN10_SHIM_WC_ENABLE		(1<<21)
+
+#define GUC_SHIM_CONTROL_VALUE	(GUC_DISABLE_SRAM_INIT_TO_ZEROES	| \
+				 GUC_ENABLE_READ_CACHE_LOGIC		| \
+				 GUC_ENABLE_MIA_CACHING			| \
+				 GUC_ENABLE_READ_CACHE_FOR_SRAM_DATA	| \
+				 GUC_ENABLE_READ_CACHE_FOR_WOPCM_DATA	| \
+				 GUC_ENABLE_MIA_CLOCK_GATING)
+
+#define HOST2GUC_INTERRUPT		_MMIO(0xc4c8)
+#define   HOST2GUC_TRIGGER		  (1<<0)
+
+#define DRBMISC1			0x1984
+#define   DOORBELL_ENABLE		  (1<<0)
+
+#define GEN8_DRBREGL(x)			_MMIO(0x1000 + (x) * 8)
+#define   GEN8_DRB_VALID		  (1<<0)
+#define GEN8_DRBREGU(x)			_MMIO(0x1000 + (x) * 8 + 4)
+
+#define DE_GUCRMR			_MMIO(0x44054)
+
+#define GUC_BCS_RCS_IER			_MMIO(0xC550)
+#define GUC_VCS2_VCS1_IER		_MMIO(0xC554)
+#define GUC_WD_VECS_IER			_MMIO(0xC558)
+#define GUC_PM_P24C_IER			_MMIO(0xC55C)
+
+#endif
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/i915/i915_guc_submission.c
@@ -0,0 +1,1010 @@
+/*
+ * Copyright © 2014 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ */
+#include <linux/firmware.h>
+#include <linux/circ_buf.h>
+#include "i915_drv.h"
+#include "intel_guc.h"
+
+/**
+ * DOC: GuC-based command submission
+ *
+ * i915_guc_client:
+ * We use the term client to avoid confusion with contexts. A i915_guc_client is
+ * equivalent to GuC object guc_context_desc. This context descriptor is
+ * allocated from a pool of 1024 entries. Kernel driver will allocate doorbell
+ * and workqueue for it. Also the process descriptor (guc_process_desc), which
+ * is mapped to client space. So the client can write Work Item then ring the
+ * doorbell.
+ *
+ * To simplify the implementation, we allocate one gem object that contains all
+ * pages for doorbell, process descriptor and workqueue.
+ *
+ * The Scratch registers:
+ * There are 16 MMIO-based registers start from 0xC180. The kernel driver writes
+ * a value to the action register (SOFT_SCRATCH_0) along with any data. It then
+ * triggers an interrupt on the GuC via another register write (0xC4C8).
+ * Firmware writes a success/fail code back to the action register after
+ * processes the request. The kernel driver polls waiting for this update and
+ * then proceeds.
+ * See host2guc_action()
+ *
+ * Doorbells:
+ * Doorbells are interrupts to uKernel. A doorbell is a single cache line (QW)
+ * mapped into process space.
+ *
+ * Work Items:
+ * There are several types of work items that the host may place into a
+ * workqueue, each with its own requirements and limitations. Currently only
+ * WQ_TYPE_INORDER is needed to support legacy submission via GuC, which
+ * represents in-order queue. The kernel driver packs ring tail pointer and an
+ * ELSP context descriptor dword into Work Item.
+ * See guc_add_workqueue_item()
+ *
+ */
+
+/*
+ * Read GuC command/status register (SOFT_SCRATCH_0)
+ * Return true if it contains a response rather than a command
+ */
+static inline bool host2guc_action_response(struct drm_i915_private *dev_priv,
+					    u32 *status)
+{
+	u32 val = I915_READ(SOFT_SCRATCH(0));
+	*status = val;
+	return GUC2HOST_IS_RESPONSE(val);
+}
+
+static int host2guc_action(struct intel_guc *guc, u32 *data, u32 len)
+{
+	struct drm_i915_private *dev_priv = guc_to_i915(guc);
+	u32 status;
+	int i;
+	int ret;
+
+	if (WARN_ON(len < 1 || len > 15))
+		return -EINVAL;
+
+	intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL);
+
+	dev_priv->guc.action_count += 1;
+	dev_priv->guc.action_cmd = data[0];
+
+	for (i = 0; i < len; i++)
+		I915_WRITE(SOFT_SCRATCH(i), data[i]);
+
+	POSTING_READ(SOFT_SCRATCH(i - 1));
+
+	I915_WRITE(HOST2GUC_INTERRUPT, HOST2GUC_TRIGGER);
+
+	/* No HOST2GUC command should take longer than 10ms */
+	ret = wait_for_atomic(host2guc_action_response(dev_priv, &status), 10);
+	if (status != GUC2HOST_STATUS_SUCCESS) {
+		/*
+		 * Either the GuC explicitly returned an error (which
+		 * we convert to -EIO here) or no response at all was
+		 * received within the timeout limit (-ETIMEDOUT)
+		 */
+		if (ret != -ETIMEDOUT)
+			ret = -EIO;
+
+		DRM_ERROR("GUC: host2guc action 0x%X failed. ret=%d "
+				"status=0x%08X response=0x%08X\n",
+				data[0], ret, status,
+				I915_READ(SOFT_SCRATCH(15)));
+
+		dev_priv->guc.action_fail += 1;
+		dev_priv->guc.action_err = ret;
+	}
+	dev_priv->guc.action_status = status;
+
+	intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
+
+	return ret;
+}
+
+/*
+ * Tell the GuC to allocate or deallocate a specific doorbell
+ */
+
+static int host2guc_allocate_doorbell(struct intel_guc *guc,
+				      struct i915_guc_client *client)
+{
+	u32 data[2];
+
+	data[0] = HOST2GUC_ACTION_ALLOCATE_DOORBELL;
+	data[1] = client->ctx_index;
+
+	return host2guc_action(guc, data, 2);
+}
+
+static int host2guc_release_doorbell(struct intel_guc *guc,
+				     struct i915_guc_client *client)
+{
+	u32 data[2];
+
+	data[0] = HOST2GUC_ACTION_DEALLOCATE_DOORBELL;
+	data[1] = client->ctx_index;
+
+	return host2guc_action(guc, data, 2);
+}
+
+static int host2guc_sample_forcewake(struct intel_guc *guc,
+				     struct i915_guc_client *client)
+{
+	struct drm_i915_private *dev_priv = guc_to_i915(guc);
+	struct drm_device *dev = dev_priv->dev;
+	u32 data[2];
+
+	data[0] = HOST2GUC_ACTION_SAMPLE_FORCEWAKE;
+	/* WaRsDisableCoarsePowerGating:skl,bxt */
+	if (!intel_enable_rc6(dev) ||
+	    NEEDS_WaRsDisableCoarsePowerGating(dev))
+		data[1] = 0;
+	else
+		/* bit 0 and 1 are for Render and Media domain separately */
+		data[1] = GUC_FORCEWAKE_RENDER | GUC_FORCEWAKE_MEDIA;
+
+	return host2guc_action(guc, data, ARRAY_SIZE(data));
+}
+
+/*
+ * Initialise, update, or clear doorbell data shared with the GuC
+ *
+ * These functions modify shared data and so need access to the mapped
+ * client object which contains the page being used for the doorbell
+ */
+
+static void guc_init_doorbell(struct intel_guc *guc,
+			      struct i915_guc_client *client)
+{
+	struct guc_doorbell_info *doorbell;
+
+	doorbell = client->client_base + client->doorbell_offset;
+
+	doorbell->db_status = GUC_DOORBELL_ENABLED;
+	doorbell->cookie = 0;
+}
+
+static int guc_ring_doorbell(struct i915_guc_client *gc)
+{
+	struct guc_process_desc *desc;
+	union guc_doorbell_qw db_cmp, db_exc, db_ret;
+	union guc_doorbell_qw *db;
+	int attempt = 2, ret = -EAGAIN;
+
+	desc = gc->client_base + gc->proc_desc_offset;
+
+	/* Update the tail so it is visible to GuC */
+	desc->tail = gc->wq_tail;
+
+	/* current cookie */
+	db_cmp.db_status = GUC_DOORBELL_ENABLED;
+	db_cmp.cookie = gc->cookie;
+
+	/* cookie to be updated */
+	db_exc.db_status = GUC_DOORBELL_ENABLED;
+	db_exc.cookie = gc->cookie + 1;
+	if (db_exc.cookie == 0)
+		db_exc.cookie = 1;
+
+	/* pointer of current doorbell cacheline */
+	db = gc->client_base + gc->doorbell_offset;
+
+	while (attempt--) {
+		/* lets ring the doorbell */
+		db_ret.value_qw = atomic64_cmpxchg((atomic64_t *)db,
+			db_cmp.value_qw, db_exc.value_qw);
+
+		/* if the exchange was successfully executed */
+		if (db_ret.value_qw == db_cmp.value_qw) {
+			/* db was successfully rung */
+			gc->cookie = db_exc.cookie;
+			ret = 0;
+			break;
+		}
+
+		/* XXX: doorbell was lost and need to acquire it again */
+		if (db_ret.db_status == GUC_DOORBELL_DISABLED)
+			break;
+
+		DRM_ERROR("Cookie mismatch. Expected %d, returned %d\n",
+			  db_cmp.cookie, db_ret.cookie);
+
+		/* update the cookie to newly read cookie from GuC */
+		db_cmp.cookie = db_ret.cookie;
+		db_exc.cookie = db_ret.cookie + 1;
+		if (db_exc.cookie == 0)
+			db_exc.cookie = 1;
+	}
+
+	return ret;
+}
+
+static void guc_disable_doorbell(struct intel_guc *guc,
+				 struct i915_guc_client *client)
+{
+	struct drm_i915_private *dev_priv = guc_to_i915(guc);
+	struct guc_doorbell_info *doorbell;
+	i915_reg_t drbreg = GEN8_DRBREGL(client->doorbell_id);
+	int value;
+
+	doorbell = client->client_base + client->doorbell_offset;
+
+	doorbell->db_status = GUC_DOORBELL_DISABLED;
+
+	I915_WRITE(drbreg, I915_READ(drbreg) & ~GEN8_DRB_VALID);
+
+	value = I915_READ(drbreg);
+	WARN_ON((value & GEN8_DRB_VALID) != 0);
+
+	I915_WRITE(GEN8_DRBREGU(client->doorbell_id), 0);
+	I915_WRITE(drbreg, 0);
+
+	/* XXX: wait for any interrupts */
+	/* XXX: wait for workqueue to drain */
+}
+
+/*
+ * Select, assign and relase doorbell cachelines
+ *
+ * These functions track which doorbell cachelines are in use.
+ * The data they manipulate is protected by the host2guc lock.
+ */
+
+static uint32_t select_doorbell_cacheline(struct intel_guc *guc)
+{
+	const uint32_t cacheline_size = cache_line_size();
+	uint32_t offset;
+
+	/* Doorbell uses a single cache line within a page */
+	offset = offset_in_page(guc->db_cacheline);
+
+	/* Moving to next cache line to reduce contention */
+	guc->db_cacheline += cacheline_size;
+
+	DRM_DEBUG_DRIVER("selected doorbell cacheline 0x%x, next 0x%x, linesize %u\n",
+			offset, guc->db_cacheline, cacheline_size);
+
+	return offset;
+}
+
+static uint16_t assign_doorbell(struct intel_guc *guc, uint32_t priority)
+{
+	/*
+	 * The bitmap is split into two halves; the first half is used for
+	 * normal priority contexts, the second half for high-priority ones.
+	 * Note that logically higher priorities are numerically less than
+	 * normal ones, so the test below means "is it high-priority?"
+	 */
+	const bool hi_pri = (priority <= GUC_CTX_PRIORITY_HIGH);
+	const uint16_t half = GUC_MAX_DOORBELLS / 2;
+	const uint16_t start = hi_pri ? half : 0;
+	const uint16_t end = start + half;
+	uint16_t id;
+
+	id = find_next_zero_bit(guc->doorbell_bitmap, end, start);
+	if (id == end)
+		id = GUC_INVALID_DOORBELL_ID;
+	else
+		bitmap_set(guc->doorbell_bitmap, id, 1);
+
+	DRM_DEBUG_DRIVER("assigned %s priority doorbell id 0x%x\n",
+			hi_pri ? "high" : "normal", id);
+
+	return id;
+}
+
+static void release_doorbell(struct intel_guc *guc, uint16_t id)
+{
+	bitmap_clear(guc->doorbell_bitmap, id, 1);
+}
+
+/*
+ * Initialise the process descriptor shared with the GuC firmware.
+ */
+static void guc_init_proc_desc(struct intel_guc *guc,
+			       struct i915_guc_client *client)
+{
+	struct guc_process_desc *desc;
+
+	desc = client->client_base + client->proc_desc_offset;
+
+	memset(desc, 0, sizeof(*desc));
+
+	/*
+	 * XXX: pDoorbell and WQVBaseAddress are pointers in process address
+	 * space for ring3 clients (set them as in mmap_ioctl) or kernel
+	 * space for kernel clients (map on demand instead? May make debug
+	 * easier to have it mapped).
+	 */
+	desc->wq_base_addr = 0;
+	desc->db_base_addr = 0;
+
+	desc->context_id = client->ctx_index;
+	desc->wq_size_bytes = client->wq_size;
+	desc->wq_status = WQ_STATUS_ACTIVE;
+	desc->priority = client->priority;
+}
+
+/*
+ * Initialise/clear the context descriptor shared with the GuC firmware.
+ *
+ * This descriptor tells the GuC where (in GGTT space) to find the important
+ * data structures relating to this client (doorbell, process descriptor,
+ * write queue, etc).
+ */
+
+static void guc_init_ctx_desc(struct intel_guc *guc,
+			      struct i915_guc_client *client)
+{
+	struct drm_i915_gem_object *client_obj = client->client_obj;
+	struct drm_i915_private *dev_priv = guc_to_i915(guc);
+	struct intel_engine_cs *engine;
+	struct intel_context *ctx = client->owner;
+	struct guc_context_desc desc;
+	struct sg_table *sg;
+	enum intel_engine_id id;
+	u32 gfx_addr;
+
+	memset(&desc, 0, sizeof(desc));
+
+	desc.attribute = GUC_CTX_DESC_ATTR_ACTIVE | GUC_CTX_DESC_ATTR_KERNEL;
+	desc.context_id = client->ctx_index;
+	desc.priority = client->priority;
+	desc.db_id = client->doorbell_id;
+
+	for_each_engine_id(engine, dev_priv, id) {
+		struct guc_execlist_context *lrc = &desc.lrc[engine->guc_id];
+		struct drm_i915_gem_object *obj;
+		uint64_t ctx_desc;
+
+		/* TODO: We have a design issue to be solved here. Only when we
+		 * receive the first batch, we know which engine is used by the
+		 * user. But here GuC expects the lrc and ring to be pinned. It
+		 * is not an issue for default context, which is the only one
+		 * for now who owns a GuC client. But for future owner of GuC
+		 * client, need to make sure lrc is pinned prior to enter here.
+		 */
+		obj = ctx->engine[id].state;
+		if (!obj)
+			break;	/* XXX: continue? */
+
+		ctx_desc = intel_lr_context_descriptor(ctx, engine);
+		lrc->context_desc = (u32)ctx_desc;
+
+		/* The state page is after PPHWSP */
+		gfx_addr = i915_gem_obj_ggtt_offset(obj);
+		lrc->ring_lcra = gfx_addr + LRC_STATE_PN * PAGE_SIZE;
+		lrc->context_id = (client->ctx_index << GUC_ELC_CTXID_OFFSET) |
+				(engine->guc_id << GUC_ELC_ENGINE_OFFSET);
+
+		obj = ctx->engine[id].ringbuf->obj;
+		gfx_addr = i915_gem_obj_ggtt_offset(obj);
+
+		lrc->ring_begin = gfx_addr;
+		lrc->ring_end = gfx_addr + obj->base.size - 1;
+		lrc->ring_next_free_location = gfx_addr;
+		lrc->ring_current_tail_pointer_value = 0;
+
+		desc.engines_used |= (1 << engine->guc_id);
+	}
+
+	WARN_ON(desc.engines_used == 0);
+
+	/*
+	 * The doorbell, process descriptor, and workqueue are all parts
+	 * of the client object, which the GuC will reference via the GGTT
+	 */
+	gfx_addr = i915_gem_obj_ggtt_offset(client_obj);
+	desc.db_trigger_phy = sg_dma_address(client_obj->pages->sgl) +
+				client->doorbell_offset;
+	desc.db_trigger_cpu = (uintptr_t)client->client_base +
+				client->doorbell_offset;
+	desc.db_trigger_uk = gfx_addr + client->doorbell_offset;
+	desc.process_desc = gfx_addr + client->proc_desc_offset;
+	desc.wq_addr = gfx_addr + client->wq_offset;
+	desc.wq_size = client->wq_size;
+
+	/*
+	 * XXX: Take LRCs from an existing intel_context if this is not an
+	 * IsKMDCreatedContext client
+	 */
+	desc.desc_private = (uintptr_t)client;
+
+	/* Pool context is pinned already */
+	sg = guc->ctx_pool_obj->pages;
+	sg_pcopy_from_buffer(sg->sgl, sg->nents, &desc, sizeof(desc),
+			     sizeof(desc) * client->ctx_index);
+}
+
+static void guc_fini_ctx_desc(struct intel_guc *guc,
+			      struct i915_guc_client *client)
+{
+	struct guc_context_desc desc;
+	struct sg_table *sg;
+
+	memset(&desc, 0, sizeof(desc));
+
+	sg = guc->ctx_pool_obj->pages;
+	sg_pcopy_from_buffer(sg->sgl, sg->nents, &desc, sizeof(desc),
+			     sizeof(desc) * client->ctx_index);
+}
+
+int i915_guc_wq_check_space(struct i915_guc_client *gc)
+{
+	struct guc_process_desc *desc;
+	u32 size = sizeof(struct guc_wq_item);
+	int ret = -ETIMEDOUT, timeout_counter = 200;
+
+	if (!gc)
+		return 0;
+
+	desc = gc->client_base + gc->proc_desc_offset;
+
+	while (timeout_counter-- > 0) {
+		if (CIRC_SPACE(gc->wq_tail, desc->head, gc->wq_size) >= size) {
+			ret = 0;
+			break;
+		}
+
+		if (timeout_counter)
+			usleep_range(1000, 2000);
+	};
+
+	return ret;
+}
+
+static int guc_add_workqueue_item(struct i915_guc_client *gc,
+				  struct drm_i915_gem_request *rq)
+{
+	struct guc_process_desc *desc;
+	struct guc_wq_item *wqi;
+	void *base;
+	u32 tail, wq_len, wq_off, space;
+
+	desc = gc->client_base + gc->proc_desc_offset;
+	space = CIRC_SPACE(gc->wq_tail, desc->head, gc->wq_size);
+	if (WARN_ON(space < sizeof(struct guc_wq_item)))
+		return -ENOSPC; /* shouldn't happen */
+
+	/* postincrement WQ tail for next time */
+	wq_off = gc->wq_tail;
+	gc->wq_tail += sizeof(struct guc_wq_item);
+	gc->wq_tail &= gc->wq_size - 1;
+
+	/* For now workqueue item is 4 DWs; workqueue buffer is 2 pages. So we
+	 * should not have the case where structure wqi is across page, neither
+	 * wrapped to the beginning. This simplifies the implementation below.
+	 *
+	 * XXX: if not the case, we need save data to a temp wqi and copy it to
+	 * workqueue buffer dw by dw.
+	 */
+	WARN_ON(sizeof(struct guc_wq_item) != 16);
+	WARN_ON(wq_off & 3);
+
+	/* wq starts from the page after doorbell / process_desc */
+	base = kmap_atomic(i915_gem_object_get_page(gc->client_obj,
+			(wq_off + GUC_DB_SIZE) >> PAGE_SHIFT));
+	wq_off &= PAGE_SIZE - 1;
+	wqi = (struct guc_wq_item *)((char *)base + wq_off);
+
+	/* len does not include the header */
+	wq_len = sizeof(struct guc_wq_item) / sizeof(u32) - 1;
+	wqi->header = WQ_TYPE_INORDER |
+			(wq_len << WQ_LEN_SHIFT) |
+			(rq->engine->guc_id << WQ_TARGET_SHIFT) |
+			WQ_NO_WCFLUSH_WAIT;
+
+	/* The GuC wants only the low-order word of the context descriptor */
+	wqi->context_desc = (u32)intel_lr_context_descriptor(rq->ctx,
+							     rq->engine);
+
+	/* The GuC firmware wants the tail index in QWords, not bytes */
+	tail = rq->ringbuf->tail >> 3;
+	wqi->ring_tail = tail << WQ_RING_TAIL_SHIFT;
+	wqi->fence_id = 0; /*XXX: what fence to be here */
+
+	kunmap_atomic(base);
+
+	return 0;
+}
+
+/**
+ * i915_guc_submit() - Submit commands through GuC
+ * @client:	the guc client where commands will go through
+ * @rq:		request associated with the commands
+ *
+ * Return:	0 if succeed
+ */
+int i915_guc_submit(struct i915_guc_client *client,
+		    struct drm_i915_gem_request *rq)
+{
+	struct intel_guc *guc = client->guc;
+	unsigned int engine_id = rq->engine->guc_id;
+	int q_ret, b_ret;
+
+	q_ret = guc_add_workqueue_item(client, rq);
+	if (q_ret == 0)
+		b_ret = guc_ring_doorbell(client);
+
+	client->submissions[engine_id] += 1;
+	if (q_ret) {
+		client->q_fail += 1;
+		client->retcode = q_ret;
+	} else if (b_ret) {
+		client->b_fail += 1;
+		client->retcode = q_ret = b_ret;
+	} else {
+		client->retcode = 0;
+	}
+	guc->submissions[engine_id] += 1;
+	guc->last_seqno[engine_id] = rq->seqno;
+
+	return q_ret;
+}
+
+/*
+ * Everything below here is concerned with setup & teardown, and is
+ * therefore not part of the somewhat time-critical batch-submission
+ * path of i915_guc_submit() above.
+ */
+
+/**
+ * gem_allocate_guc_obj() - Allocate gem object for GuC usage
+ * @dev:	drm device
+ * @size:	size of object
+ *
+ * This is a wrapper to create a gem obj. In order to use it inside GuC, the
+ * object needs to be pinned lifetime. Also we must pin it to gtt space other
+ * than [0, GUC_WOPCM_TOP) because this range is reserved inside GuC.
+ *
+ * Return:	A drm_i915_gem_object if successful, otherwise NULL.
+ */
+static struct drm_i915_gem_object *gem_allocate_guc_obj(struct drm_device *dev,
+							u32 size)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct drm_i915_gem_object *obj;
+
+	obj = i915_gem_alloc_object(dev, size);
+	if (!obj)
+		return NULL;
+
+	if (i915_gem_object_get_pages(obj)) {
+		drm_gem_object_unreference(&obj->base);
+		return NULL;
+	}
+
+	if (i915_gem_obj_ggtt_pin(obj, PAGE_SIZE,
+			PIN_OFFSET_BIAS | GUC_WOPCM_TOP)) {
+		drm_gem_object_unreference(&obj->base);
+		return NULL;
+	}
+
+	/* Invalidate GuC TLB to let GuC take the latest updates to GTT. */
+	I915_WRITE(GEN8_GTCR, GEN8_GTCR_INVALIDATE);
+
+	return obj;
+}
+
+/**
+ * gem_release_guc_obj() - Release gem object allocated for GuC usage
+ * @obj:	gem obj to be released
+ */
+static void gem_release_guc_obj(struct drm_i915_gem_object *obj)
+{
+	if (!obj)
+		return;
+
+	if (i915_gem_obj_is_pinned(obj))
+		i915_gem_object_ggtt_unpin(obj);
+
+	drm_gem_object_unreference(&obj->base);
+}
+
+static void guc_client_free(struct drm_device *dev,
+			    struct i915_guc_client *client)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_guc *guc = &dev_priv->guc;
+
+	if (!client)
+		return;
+
+	/*
+	 * XXX: wait for any outstanding submissions before freeing memory.
+	 * Be sure to drop any locks
+	 */
+
+	if (client->client_base) {
+		/*
+		 * If we got as far as setting up a doorbell, make sure
+		 * we shut it down before unmapping & deallocating the
+		 * memory. So first disable the doorbell, then tell the
+		 * GuC that we've finished with it, finally deallocate
+		 * it in our bitmap
+		 */
+		if (client->doorbell_id != GUC_INVALID_DOORBELL_ID) {
+			guc_disable_doorbell(guc, client);
+			host2guc_release_doorbell(guc, client);
+			release_doorbell(guc, client->doorbell_id);
+		}
+
+		kunmap(kmap_to_page(client->client_base));
+	}
+
+	gem_release_guc_obj(client->client_obj);
+
+	if (client->ctx_index != GUC_INVALID_CTX_ID) {
+		guc_fini_ctx_desc(guc, client);
+		ida_simple_remove(&guc->ctx_ids, client->ctx_index);
+	}
+
+	kfree(client);
+}
+
+/**
+ * guc_client_alloc() - Allocate an i915_guc_client
+ * @dev:	drm device
+ * @priority:	four levels priority _CRITICAL, _HIGH, _NORMAL and _LOW
+ * 		The kernel client to replace ExecList submission is created with
+ * 		NORMAL priority. Priority of a client for scheduler can be HIGH,
+ * 		while a preemption context can use CRITICAL.
+ * @ctx:	the context that owns the client (we use the default render
+ * 		context)
+ *
+ * Return:	An i915_guc_client object if success, else NULL.
+ */
+static struct i915_guc_client *guc_client_alloc(struct drm_device *dev,
+						uint32_t priority,
+						struct intel_context *ctx)
+{
+	struct i915_guc_client *client;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_guc *guc = &dev_priv->guc;
+	struct drm_i915_gem_object *obj;
+
+	client = kzalloc(sizeof(*client), GFP_KERNEL);
+	if (!client)
+		return NULL;
+
+	client->doorbell_id = GUC_INVALID_DOORBELL_ID;
+	client->priority = priority;
+	client->owner = ctx;
+	client->guc = guc;
+
+	client->ctx_index = (uint32_t)ida_simple_get(&guc->ctx_ids, 0,
+			GUC_MAX_GPU_CONTEXTS, GFP_KERNEL);
+	if (client->ctx_index >= GUC_MAX_GPU_CONTEXTS) {
+		client->ctx_index = GUC_INVALID_CTX_ID;
+		goto err;
+	}
+
+	/* The first page is doorbell/proc_desc. Two followed pages are wq. */
+	obj = gem_allocate_guc_obj(dev, GUC_DB_SIZE + GUC_WQ_SIZE);
+	if (!obj)
+		goto err;
+
+	/* We'll keep just the first (doorbell/proc) page permanently kmap'd. */
+	client->client_obj = obj;
+	client->client_base = kmap(i915_gem_object_get_page(obj, 0));
+	client->wq_offset = GUC_DB_SIZE;
+	client->wq_size = GUC_WQ_SIZE;
+
+	client->doorbell_offset = select_doorbell_cacheline(guc);
+
+	/*
+	 * Since the doorbell only requires a single cacheline, we can save
+	 * space by putting the application process descriptor in the same
+	 * page. Use the half of the page that doesn't include the doorbell.
+	 */
+	if (client->doorbell_offset >= (GUC_DB_SIZE / 2))
+		client->proc_desc_offset = 0;
+	else
+		client->proc_desc_offset = (GUC_DB_SIZE / 2);
+
+	client->doorbell_id = assign_doorbell(guc, client->priority);
+	if (client->doorbell_id == GUC_INVALID_DOORBELL_ID)
+		/* XXX: evict a doorbell instead */
+		goto err;
+
+	guc_init_proc_desc(guc, client);
+	guc_init_ctx_desc(guc, client);
+	guc_init_doorbell(guc, client);
+
+	/* XXX: Any cache flushes needed? General domain mgmt calls? */
+
+	if (host2guc_allocate_doorbell(guc, client))
+		goto err;
+
+	DRM_DEBUG_DRIVER("new priority %u client %p: ctx_index %u db_id %u\n",
+		priority, client, client->ctx_index, client->doorbell_id);
+
+	return client;
+
+err:
+	DRM_ERROR("FAILED to create priority %u GuC client!\n", priority);
+
+	guc_client_free(dev, client);
+	return NULL;
+}
+
+static void guc_create_log(struct intel_guc *guc)
+{
+	struct drm_i915_private *dev_priv = guc_to_i915(guc);
+	struct drm_i915_gem_object *obj;
+	unsigned long offset;
+	uint32_t size, flags;
+
+	if (i915.guc_log_level < GUC_LOG_VERBOSITY_MIN)
+		return;
+
+	if (i915.guc_log_level > GUC_LOG_VERBOSITY_MAX)
+		i915.guc_log_level = GUC_LOG_VERBOSITY_MAX;
+
+	/* The first page is to save log buffer state. Allocate one
+	 * extra page for others in case for overlap */
+	size = (1 + GUC_LOG_DPC_PAGES + 1 +
+		GUC_LOG_ISR_PAGES + 1 +
+		GUC_LOG_CRASH_PAGES + 1) << PAGE_SHIFT;
+
+	obj = guc->log_obj;
+	if (!obj) {
+		obj = gem_allocate_guc_obj(dev_priv->dev, size);
+		if (!obj) {
+			/* logging will be off */
+			i915.guc_log_level = -1;
+			return;
+		}
+
+		guc->log_obj = obj;
+	}
+
+	/* each allocated unit is a page */
+	flags = GUC_LOG_VALID | GUC_LOG_NOTIFY_ON_HALF_FULL |
+		(GUC_LOG_DPC_PAGES << GUC_LOG_DPC_SHIFT) |
+		(GUC_LOG_ISR_PAGES << GUC_LOG_ISR_SHIFT) |
+		(GUC_LOG_CRASH_PAGES << GUC_LOG_CRASH_SHIFT);
+
+	offset = i915_gem_obj_ggtt_offset(obj) >> PAGE_SHIFT; /* in pages */
+	guc->log_flags = (offset << GUC_LOG_BUF_ADDR_SHIFT) | flags;
+}
+
+static void init_guc_policies(struct guc_policies *policies)
+{
+	struct guc_policy *policy;
+	u32 p, i;
+
+	policies->dpc_promote_time = 500000;
+	policies->max_num_work_items = POLICY_MAX_NUM_WI;
+
+	for (p = 0; p < GUC_CTX_PRIORITY_NUM; p++) {
+		for (i = GUC_RENDER_ENGINE; i < GUC_MAX_ENGINES_NUM; i++) {
+			policy = &policies->policy[p][i];
+
+			policy->execution_quantum = 1000000;
+			policy->preemption_time = 500000;
+			policy->fault_time = 250000;
+			policy->policy_flags = 0;
+		}
+	}
+
+	policies->is_valid = 1;
+}
+
+static void guc_create_ads(struct intel_guc *guc)
+{
+	struct drm_i915_private *dev_priv = guc_to_i915(guc);
+	struct drm_i915_gem_object *obj;
+	struct guc_ads *ads;
+	struct guc_policies *policies;
+	struct guc_mmio_reg_state *reg_state;
+	struct intel_engine_cs *engine;
+	struct page *page;
+	u32 size;
+
+	/* The ads obj includes the struct itself and buffers passed to GuC */
+	size = sizeof(struct guc_ads) + sizeof(struct guc_policies) +
+			sizeof(struct guc_mmio_reg_state) +
+			GUC_S3_SAVE_SPACE_PAGES * PAGE_SIZE;
+
+	obj = guc->ads_obj;
+	if (!obj) {
+		obj = gem_allocate_guc_obj(dev_priv->dev, PAGE_ALIGN(size));
+		if (!obj)
+			return;
+
+		guc->ads_obj = obj;
+	}
+
+	page = i915_gem_object_get_page(obj, 0);
+	ads = kmap(page);
+
+	/*
+	 * The GuC requires a "Golden Context" when it reinitialises
+	 * engines after a reset. Here we use the Render ring default
+	 * context, which must already exist and be pinned in the GGTT,
+	 * so its address won't change after we've told the GuC where
+	 * to find it.
+	 */
+	engine = &dev_priv->engine[RCS];
+	ads->golden_context_lrca = engine->status_page.gfx_addr;
+
+	for_each_engine(engine, dev_priv)
+		ads->eng_state_size[engine->guc_id] = intel_lr_context_size(engine);
+
+	/* GuC scheduling policies */
+	policies = (void *)ads + sizeof(struct guc_ads);
+	init_guc_policies(policies);
+
+	ads->scheduler_policies = i915_gem_obj_ggtt_offset(obj) +
+			sizeof(struct guc_ads);
+
+	/* MMIO reg state */
+	reg_state = (void *)policies + sizeof(struct guc_policies);
+
+	for_each_engine(engine, dev_priv) {
+		reg_state->mmio_white_list[engine->guc_id].mmio_start =
+			engine->mmio_base + GUC_MMIO_WHITE_LIST_START;
+
+		/* Nothing to be saved or restored for now. */
+		reg_state->mmio_white_list[engine->guc_id].count = 0;
+	}
+
+	ads->reg_state_addr = ads->scheduler_policies +
+			sizeof(struct guc_policies);
+
+	ads->reg_state_buffer = ads->reg_state_addr +
+			sizeof(struct guc_mmio_reg_state);
+
+	kunmap(page);
+}
+
+/*
+ * Set up the memory resources to be shared with the GuC.  At this point,
+ * we require just one object that can be mapped through the GGTT.
+ */
+int i915_guc_submission_init(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	const size_t ctxsize = sizeof(struct guc_context_desc);
+	const size_t poolsize = GUC_MAX_GPU_CONTEXTS * ctxsize;
+	const size_t gemsize = round_up(poolsize, PAGE_SIZE);
+	struct intel_guc *guc = &dev_priv->guc;
+
+	if (!i915.enable_guc_submission)
+		return 0; /* not enabled  */
+
+	if (guc->ctx_pool_obj)
+		return 0; /* already allocated */
+
+	guc->ctx_pool_obj = gem_allocate_guc_obj(dev_priv->dev, gemsize);
+	if (!guc->ctx_pool_obj)
+		return -ENOMEM;
+
+	ida_init(&guc->ctx_ids);
+
+	guc_create_log(guc);
+
+	guc_create_ads(guc);
+
+	return 0;
+}
+
+int i915_guc_submission_enable(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_guc *guc = &dev_priv->guc;
+	struct intel_context *ctx = dev_priv->kernel_context;
+	struct i915_guc_client *client;
+
+	/* client for execbuf submission */
+	client = guc_client_alloc(dev, GUC_CTX_PRIORITY_KMD_NORMAL, ctx);
+	if (!client) {
+		DRM_ERROR("Failed to create execbuf guc_client\n");
+		return -ENOMEM;
+	}
+
+	guc->execbuf_client = client;
+
+	host2guc_sample_forcewake(guc, client);
+
+	return 0;
+}
+
+void i915_guc_submission_disable(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_guc *guc = &dev_priv->guc;
+
+	guc_client_free(dev, guc->execbuf_client);
+	guc->execbuf_client = NULL;
+}
+
+void i915_guc_submission_fini(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_guc *guc = &dev_priv->guc;
+
+	gem_release_guc_obj(dev_priv->guc.ads_obj);
+	guc->ads_obj = NULL;
+
+	gem_release_guc_obj(dev_priv->guc.log_obj);
+	guc->log_obj = NULL;
+
+	if (guc->ctx_pool_obj)
+		ida_destroy(&guc->ctx_ids);
+	gem_release_guc_obj(guc->ctx_pool_obj);
+	guc->ctx_pool_obj = NULL;
+}
+
+/**
+ * intel_guc_suspend() - notify GuC entering suspend state
+ * @dev:	drm device
+ */
+int intel_guc_suspend(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_guc *guc = &dev_priv->guc;
+	struct intel_context *ctx;
+	u32 data[3];
+
+	if (!i915.enable_guc_submission)
+		return 0;
+
+	ctx = dev_priv->kernel_context;
+
+	data[0] = HOST2GUC_ACTION_ENTER_S_STATE;
+	/* any value greater than GUC_POWER_D0 */
+	data[1] = GUC_POWER_D1;
+	/* first page is shared data with GuC */
+	data[2] = i915_gem_obj_ggtt_offset(ctx->engine[RCS].state);
+
+	return host2guc_action(guc, data, ARRAY_SIZE(data));
+}
+
+
+/**
+ * intel_guc_resume() - notify GuC resuming from suspend state
+ * @dev:	drm device
+ */
+int intel_guc_resume(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_guc *guc = &dev_priv->guc;
+	struct intel_context *ctx;
+	u32 data[3];
+
+	if (!i915.enable_guc_submission)
+		return 0;
+
+	ctx = dev_priv->kernel_context;
+
+	data[0] = HOST2GUC_ACTION_EXIT_S_STATE;
+	data[1] = GUC_POWER_D0;
+	/* first page is shared data with GuC */
+	data[2] = i915_gem_obj_ggtt_offset(ctx->engine[RCS].state);
+
+	return host2guc_action(guc, data, ARRAY_SIZE(data));
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/i915/i915_ioc32.c
@@ -0,0 +1,99 @@
+/**
+ * \file i915_ioc32.c
+ *
+ * 32-bit ioctl compatibility routines for the i915 DRM.
+ *
+ * \author Alan Hourihane <alanh@fairlite.demon.co.uk>
+ *
+ *
+ * Copyright (C) Paul Mackerras 2005
+ * Copyright (C) Alan Hourihane 2005
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+#include <linux/compat.h>
+
+#include <drm/drmP.h>
+#include <drm/i915_drm.h>
+#include "i915_drv.h"
+
+struct drm_i915_getparam32 {
+	s32 param;
+	/*
+	 * We screwed up the generic ioctl struct here and used a variable-sized
+	 * pointer. Use u32 in the compat struct to match the 32bit pointer
+	 * userspace expects.
+	 */
+	u32 value;
+};
+
+static int compat_i915_getparam(struct file *file, unsigned int cmd,
+				unsigned long arg)
+{
+	struct drm_i915_getparam32 req32;
+	drm_i915_getparam_t __user *request;
+
+	if (copy_from_user(&req32, (void __user *)arg, sizeof(req32)))
+		return -EFAULT;
+
+	request = compat_alloc_user_space(sizeof(*request));
+	if (!access_ok(VERIFY_WRITE, request, sizeof(*request))
+	    || __put_user(req32.param, &request->param)
+	    || __put_user((void __user *)(unsigned long)req32.value,
+			  &request->value))
+		return -EFAULT;
+
+	return drm_ioctl(file, DRM_IOCTL_I915_GETPARAM,
+			 (unsigned long)request);
+}
+
+static drm_ioctl_compat_t *i915_compat_ioctls[] = {
+	[DRM_I915_GETPARAM] = compat_i915_getparam,
+};
+
+/**
+ * Called whenever a 32-bit process running under a 64-bit kernel
+ * performs an ioctl on /dev/dri/card<n>.
+ *
+ * \param filp file pointer.
+ * \param cmd command.
+ * \param arg user argument.
+ * \return zero on success or negative number on failure.
+ */
+long i915_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
+{
+	unsigned int nr = DRM_IOCTL_NR(cmd);
+	drm_ioctl_compat_t *fn = NULL;
+	int ret;
+
+	if (nr < DRM_COMMAND_BASE || nr >= DRM_COMMAND_END)
+		return drm_compat_ioctl(filp, cmd, arg);
+
+	if (nr < DRM_COMMAND_BASE + ARRAY_SIZE(i915_compat_ioctls))
+		fn = i915_compat_ioctls[nr - DRM_COMMAND_BASE];
+
+	if (fn != NULL)
+		ret = (*fn) (filp, cmd, arg);
+	else
+		ret = drm_ioctl(filp, cmd, arg);
+
+	return ret;
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/i915/i915_irq.c
@@ -0,0 +1,4763 @@
+/* i915_irq.c -- IRQ support for the I915 -*- linux-c -*-
+ */
+/*
+ * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/sysrq.h>
+#include <linux/slab.h>
+#include <linux/circ_buf.h>
+#include <drm/drmP.h>
+#include <drm/i915_drm.h>
+#include "i915_drv.h"
+#include "i915_trace.h"
+#include "intel_drv.h"
+
+/**
+ * DOC: interrupt handling
+ *
+ * These functions provide the basic support for enabling and disabling the
+ * interrupt handling support. There's a lot more functionality in i915_irq.c
+ * and related files, but that will be described in separate chapters.
+ */
+
+static const u32 hpd_ilk[HPD_NUM_PINS] = {
+	[HPD_PORT_A] = DE_DP_A_HOTPLUG,
+};
+
+static const u32 hpd_ivb[HPD_NUM_PINS] = {
+	[HPD_PORT_A] = DE_DP_A_HOTPLUG_IVB,
+};
+
+static const u32 hpd_bdw[HPD_NUM_PINS] = {
+	[HPD_PORT_A] = GEN8_PORT_DP_A_HOTPLUG,
+};
+
+static const u32 hpd_ibx[HPD_NUM_PINS] = {
+	[HPD_CRT] = SDE_CRT_HOTPLUG,
+	[HPD_SDVO_B] = SDE_SDVOB_HOTPLUG,
+	[HPD_PORT_B] = SDE_PORTB_HOTPLUG,
+	[HPD_PORT_C] = SDE_PORTC_HOTPLUG,
+	[HPD_PORT_D] = SDE_PORTD_HOTPLUG
+};
+
+static const u32 hpd_cpt[HPD_NUM_PINS] = {
+	[HPD_CRT] = SDE_CRT_HOTPLUG_CPT,
+	[HPD_SDVO_B] = SDE_SDVOB_HOTPLUG_CPT,
+	[HPD_PORT_B] = SDE_PORTB_HOTPLUG_CPT,
+	[HPD_PORT_C] = SDE_PORTC_HOTPLUG_CPT,
+	[HPD_PORT_D] = SDE_PORTD_HOTPLUG_CPT
+};
+
+static const u32 hpd_spt[HPD_NUM_PINS] = {
+	[HPD_PORT_A] = SDE_PORTA_HOTPLUG_SPT,
+	[HPD_PORT_B] = SDE_PORTB_HOTPLUG_CPT,
+	[HPD_PORT_C] = SDE_PORTC_HOTPLUG_CPT,
+	[HPD_PORT_D] = SDE_PORTD_HOTPLUG_CPT,
+	[HPD_PORT_E] = SDE_PORTE_HOTPLUG_SPT
+};
+
+static const u32 hpd_mask_i915[HPD_NUM_PINS] = {
+	[HPD_CRT] = CRT_HOTPLUG_INT_EN,
+	[HPD_SDVO_B] = SDVOB_HOTPLUG_INT_EN,
+	[HPD_SDVO_C] = SDVOC_HOTPLUG_INT_EN,
+	[HPD_PORT_B] = PORTB_HOTPLUG_INT_EN,
+	[HPD_PORT_C] = PORTC_HOTPLUG_INT_EN,
+	[HPD_PORT_D] = PORTD_HOTPLUG_INT_EN
+};
+
+static const u32 hpd_status_g4x[HPD_NUM_PINS] = {
+	[HPD_CRT] = CRT_HOTPLUG_INT_STATUS,
+	[HPD_SDVO_B] = SDVOB_HOTPLUG_INT_STATUS_G4X,
+	[HPD_SDVO_C] = SDVOC_HOTPLUG_INT_STATUS_G4X,
+	[HPD_PORT_B] = PORTB_HOTPLUG_INT_STATUS,
+	[HPD_PORT_C] = PORTC_HOTPLUG_INT_STATUS,
+	[HPD_PORT_D] = PORTD_HOTPLUG_INT_STATUS
+};
+
+static const u32 hpd_status_i915[HPD_NUM_PINS] = {
+	[HPD_CRT] = CRT_HOTPLUG_INT_STATUS,
+	[HPD_SDVO_B] = SDVOB_HOTPLUG_INT_STATUS_I915,
+	[HPD_SDVO_C] = SDVOC_HOTPLUG_INT_STATUS_I915,
+	[HPD_PORT_B] = PORTB_HOTPLUG_INT_STATUS,
+	[HPD_PORT_C] = PORTC_HOTPLUG_INT_STATUS,
+	[HPD_PORT_D] = PORTD_HOTPLUG_INT_STATUS
+};
+
+/* BXT hpd list */
+static const u32 hpd_bxt[HPD_NUM_PINS] = {
+	[HPD_PORT_A] = BXT_DE_PORT_HP_DDIA,
+	[HPD_PORT_B] = BXT_DE_PORT_HP_DDIB,
+	[HPD_PORT_C] = BXT_DE_PORT_HP_DDIC
+};
+
+/* IIR can theoretically queue up two events. Be paranoid. */
+#define GEN8_IRQ_RESET_NDX(type, which) do { \
+	I915_WRITE(GEN8_##type##_IMR(which), 0xffffffff); \
+	POSTING_READ(GEN8_##type##_IMR(which)); \
+	I915_WRITE(GEN8_##type##_IER(which), 0); \
+	I915_WRITE(GEN8_##type##_IIR(which), 0xffffffff); \
+	POSTING_READ(GEN8_##type##_IIR(which)); \
+	I915_WRITE(GEN8_##type##_IIR(which), 0xffffffff); \
+	POSTING_READ(GEN8_##type##_IIR(which)); \
+} while (0)
+
+#define GEN5_IRQ_RESET(type) do { \
+	I915_WRITE(type##IMR, 0xffffffff); \
+	POSTING_READ(type##IMR); \
+	I915_WRITE(type##IER, 0); \
+	I915_WRITE(type##IIR, 0xffffffff); \
+	POSTING_READ(type##IIR); \
+	I915_WRITE(type##IIR, 0xffffffff); \
+	POSTING_READ(type##IIR); \
+} while (0)
+
+/*
+ * We should clear IMR at preinstall/uninstall, and just check at postinstall.
+ */
+static void gen5_assert_iir_is_zero(struct drm_i915_private *dev_priv,
+				    i915_reg_t reg)
+{
+	u32 val = I915_READ(reg);
+
+	if (val == 0)
+		return;
+
+	WARN(1, "Interrupt register 0x%x is not zero: 0x%08x\n",
+	     i915_mmio_reg_offset(reg), val);
+	I915_WRITE(reg, 0xffffffff);
+	POSTING_READ(reg);
+	I915_WRITE(reg, 0xffffffff);
+	POSTING_READ(reg);
+}
+
+#define GEN8_IRQ_INIT_NDX(type, which, imr_val, ier_val) do { \
+	gen5_assert_iir_is_zero(dev_priv, GEN8_##type##_IIR(which)); \
+	I915_WRITE(GEN8_##type##_IER(which), (ier_val)); \
+	I915_WRITE(GEN8_##type##_IMR(which), (imr_val)); \
+	POSTING_READ(GEN8_##type##_IMR(which)); \
+} while (0)
+
+#define GEN5_IRQ_INIT(type, imr_val, ier_val) do { \
+	gen5_assert_iir_is_zero(dev_priv, type##IIR); \
+	I915_WRITE(type##IER, (ier_val)); \
+	I915_WRITE(type##IMR, (imr_val)); \
+	POSTING_READ(type##IMR); \
+} while (0)
+
+static void gen6_rps_irq_handler(struct drm_i915_private *dev_priv, u32 pm_iir);
+
+/* For display hotplug interrupt */
+static inline void
+i915_hotplug_interrupt_update_locked(struct drm_i915_private *dev_priv,
+				     uint32_t mask,
+				     uint32_t bits)
+{
+	uint32_t val;
+
+	assert_spin_locked(&dev_priv->irq_lock);
+	WARN_ON(bits & ~mask);
+
+	val = I915_READ(PORT_HOTPLUG_EN);
+	val &= ~mask;
+	val |= bits;
+	I915_WRITE(PORT_HOTPLUG_EN, val);
+}
+
+/**
+ * i915_hotplug_interrupt_update - update hotplug interrupt enable
+ * @dev_priv: driver private
+ * @mask: bits to update
+ * @bits: bits to enable
+ * NOTE: the HPD enable bits are modified both inside and outside
+ * of an interrupt context. To avoid that read-modify-write cycles
+ * interfer, these bits are protected by a spinlock. Since this
+ * function is usually not called from a context where the lock is
+ * held already, this function acquires the lock itself. A non-locking
+ * version is also available.
+ */
+void i915_hotplug_interrupt_update(struct drm_i915_private *dev_priv,
+				   uint32_t mask,
+				   uint32_t bits)
+{
+	spin_lock_irq(&dev_priv->irq_lock);
+	i915_hotplug_interrupt_update_locked(dev_priv, mask, bits);
+	spin_unlock_irq(&dev_priv->irq_lock);
+}
+
+/**
+ * ilk_update_display_irq - update DEIMR
+ * @dev_priv: driver private
+ * @interrupt_mask: mask of interrupt bits to update
+ * @enabled_irq_mask: mask of interrupt bits to enable
+ */
+void ilk_update_display_irq(struct drm_i915_private *dev_priv,
+			    uint32_t interrupt_mask,
+			    uint32_t enabled_irq_mask)
+{
+	uint32_t new_val;
+
+	assert_spin_locked(&dev_priv->irq_lock);
+
+	WARN_ON(enabled_irq_mask & ~interrupt_mask);
+
+	if (WARN_ON(!intel_irqs_enabled(dev_priv)))
+		return;
+
+	new_val = dev_priv->irq_mask;
+	new_val &= ~interrupt_mask;
+	new_val |= (~enabled_irq_mask & interrupt_mask);
+
+	if (new_val != dev_priv->irq_mask) {
+		dev_priv->irq_mask = new_val;
+		I915_WRITE(DEIMR, dev_priv->irq_mask);
+		POSTING_READ(DEIMR);
+	}
+}
+
+/**
+ * ilk_update_gt_irq - update GTIMR
+ * @dev_priv: driver private
+ * @interrupt_mask: mask of interrupt bits to update
+ * @enabled_irq_mask: mask of interrupt bits to enable
+ */
+static void ilk_update_gt_irq(struct drm_i915_private *dev_priv,
+			      uint32_t interrupt_mask,
+			      uint32_t enabled_irq_mask)
+{
+	assert_spin_locked(&dev_priv->irq_lock);
+
+	WARN_ON(enabled_irq_mask & ~interrupt_mask);
+
+	if (WARN_ON(!intel_irqs_enabled(dev_priv)))
+		return;
+
+	dev_priv->gt_irq_mask &= ~interrupt_mask;
+	dev_priv->gt_irq_mask |= (~enabled_irq_mask & interrupt_mask);
+	I915_WRITE(GTIMR, dev_priv->gt_irq_mask);
+	POSTING_READ(GTIMR);
+}
+
+void gen5_enable_gt_irq(struct drm_i915_private *dev_priv, uint32_t mask)
+{
+	ilk_update_gt_irq(dev_priv, mask, mask);
+}
+
+void gen5_disable_gt_irq(struct drm_i915_private *dev_priv, uint32_t mask)
+{
+	ilk_update_gt_irq(dev_priv, mask, 0);
+}
+
+static i915_reg_t gen6_pm_iir(struct drm_i915_private *dev_priv)
+{
+	return INTEL_INFO(dev_priv)->gen >= 8 ? GEN8_GT_IIR(2) : GEN6_PMIIR;
+}
+
+static i915_reg_t gen6_pm_imr(struct drm_i915_private *dev_priv)
+{
+	return INTEL_INFO(dev_priv)->gen >= 8 ? GEN8_GT_IMR(2) : GEN6_PMIMR;
+}
+
+static i915_reg_t gen6_pm_ier(struct drm_i915_private *dev_priv)
+{
+	return INTEL_INFO(dev_priv)->gen >= 8 ? GEN8_GT_IER(2) : GEN6_PMIER;
+}
+
+/**
+ * snb_update_pm_irq - update GEN6_PMIMR
+ * @dev_priv: driver private
+ * @interrupt_mask: mask of interrupt bits to update
+ * @enabled_irq_mask: mask of interrupt bits to enable
+ */
+static void snb_update_pm_irq(struct drm_i915_private *dev_priv,
+			      uint32_t interrupt_mask,
+			      uint32_t enabled_irq_mask)
+{
+	uint32_t new_val;
+
+	WARN_ON(enabled_irq_mask & ~interrupt_mask);
+
+	assert_spin_locked(&dev_priv->irq_lock);
+
+	new_val = dev_priv->pm_irq_mask;
+	new_val &= ~interrupt_mask;
+	new_val |= (~enabled_irq_mask & interrupt_mask);
+
+	if (new_val != dev_priv->pm_irq_mask) {
+		dev_priv->pm_irq_mask = new_val;
+		I915_WRITE(gen6_pm_imr(dev_priv), dev_priv->pm_irq_mask);
+		POSTING_READ(gen6_pm_imr(dev_priv));
+	}
+}
+
+void gen6_enable_pm_irq(struct drm_i915_private *dev_priv, uint32_t mask)
+{
+	if (WARN_ON(!intel_irqs_enabled(dev_priv)))
+		return;
+
+	snb_update_pm_irq(dev_priv, mask, mask);
+}
+
+static void __gen6_disable_pm_irq(struct drm_i915_private *dev_priv,
+				  uint32_t mask)
+{
+	snb_update_pm_irq(dev_priv, mask, 0);
+}
+
+void gen6_disable_pm_irq(struct drm_i915_private *dev_priv, uint32_t mask)
+{
+	if (WARN_ON(!intel_irqs_enabled(dev_priv)))
+		return;
+
+	__gen6_disable_pm_irq(dev_priv, mask);
+}
+
+void gen6_reset_rps_interrupts(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	i915_reg_t reg = gen6_pm_iir(dev_priv);
+
+	spin_lock_irq(&dev_priv->irq_lock);
+	I915_WRITE(reg, dev_priv->pm_rps_events);
+	I915_WRITE(reg, dev_priv->pm_rps_events);
+	POSTING_READ(reg);
+	dev_priv->rps.pm_iir = 0;
+	spin_unlock_irq(&dev_priv->irq_lock);
+}
+
+void gen6_enable_rps_interrupts(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	spin_lock_irq(&dev_priv->irq_lock);
+
+	WARN_ON(dev_priv->rps.pm_iir);
+	WARN_ON(I915_READ(gen6_pm_iir(dev_priv)) & dev_priv->pm_rps_events);
+	dev_priv->rps.interrupts_enabled = true;
+	I915_WRITE(gen6_pm_ier(dev_priv), I915_READ(gen6_pm_ier(dev_priv)) |
+				dev_priv->pm_rps_events);
+	gen6_enable_pm_irq(dev_priv, dev_priv->pm_rps_events);
+
+	spin_unlock_irq(&dev_priv->irq_lock);
+}
+
+u32 gen6_sanitize_rps_pm_mask(struct drm_i915_private *dev_priv, u32 mask)
+{
+	/*
+	 * SNB,IVB can while VLV,CHV may hard hang on looping batchbuffer
+	 * if GEN6_PM_UP_EI_EXPIRED is masked.
+	 *
+	 * TODO: verify if this can be reproduced on VLV,CHV.
+	 */
+	if (INTEL_INFO(dev_priv)->gen <= 7 && !IS_HASWELL(dev_priv))
+		mask &= ~GEN6_PM_RP_UP_EI_EXPIRED;
+
+	if (INTEL_INFO(dev_priv)->gen >= 8)
+		mask &= ~GEN8_PMINTR_REDIRECT_TO_NON_DISP;
+
+	return mask;
+}
+
+void gen6_disable_rps_interrupts(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	spin_lock_irq(&dev_priv->irq_lock);
+	dev_priv->rps.interrupts_enabled = false;
+	spin_unlock_irq(&dev_priv->irq_lock);
+
+	cancel_work_sync(&dev_priv->rps.work);
+
+	spin_lock_irq(&dev_priv->irq_lock);
+
+	I915_WRITE(GEN6_PMINTRMSK, gen6_sanitize_rps_pm_mask(dev_priv, ~0));
+
+	__gen6_disable_pm_irq(dev_priv, dev_priv->pm_rps_events);
+	I915_WRITE(gen6_pm_ier(dev_priv), I915_READ(gen6_pm_ier(dev_priv)) &
+				~dev_priv->pm_rps_events);
+
+	spin_unlock_irq(&dev_priv->irq_lock);
+
+	synchronize_irq(dev->irq);
+}
+
+/**
+ * bdw_update_port_irq - update DE port interrupt
+ * @dev_priv: driver private
+ * @interrupt_mask: mask of interrupt bits to update
+ * @enabled_irq_mask: mask of interrupt bits to enable
+ */
+static void bdw_update_port_irq(struct drm_i915_private *dev_priv,
+				uint32_t interrupt_mask,
+				uint32_t enabled_irq_mask)
+{
+	uint32_t new_val;
+	uint32_t old_val;
+
+	assert_spin_locked(&dev_priv->irq_lock);
+
+	WARN_ON(enabled_irq_mask & ~interrupt_mask);
+
+	if (WARN_ON(!intel_irqs_enabled(dev_priv)))
+		return;
+
+	old_val = I915_READ(GEN8_DE_PORT_IMR);
+
+	new_val = old_val;
+	new_val &= ~interrupt_mask;
+	new_val |= (~enabled_irq_mask & interrupt_mask);
+
+	if (new_val != old_val) {
+		I915_WRITE(GEN8_DE_PORT_IMR, new_val);
+		POSTING_READ(GEN8_DE_PORT_IMR);
+	}
+}
+
+/**
+ * bdw_update_pipe_irq - update DE pipe interrupt
+ * @dev_priv: driver private
+ * @pipe: pipe whose interrupt to update
+ * @interrupt_mask: mask of interrupt bits to update
+ * @enabled_irq_mask: mask of interrupt bits to enable
+ */
+void bdw_update_pipe_irq(struct drm_i915_private *dev_priv,
+			 enum pipe pipe,
+			 uint32_t interrupt_mask,
+			 uint32_t enabled_irq_mask)
+{
+	uint32_t new_val;
+
+	assert_spin_locked(&dev_priv->irq_lock);
+
+	WARN_ON(enabled_irq_mask & ~interrupt_mask);
+
+	if (WARN_ON(!intel_irqs_enabled(dev_priv)))
+		return;
+
+	new_val = dev_priv->de_irq_mask[pipe];
+	new_val &= ~interrupt_mask;
+	new_val |= (~enabled_irq_mask & interrupt_mask);
+
+	if (new_val != dev_priv->de_irq_mask[pipe]) {
+		dev_priv->de_irq_mask[pipe] = new_val;
+		I915_WRITE(GEN8_DE_PIPE_IMR(pipe), dev_priv->de_irq_mask[pipe]);
+		POSTING_READ(GEN8_DE_PIPE_IMR(pipe));
+	}
+}
+
+/**
+ * ibx_display_interrupt_update - update SDEIMR
+ * @dev_priv: driver private
+ * @interrupt_mask: mask of interrupt bits to update
+ * @enabled_irq_mask: mask of interrupt bits to enable
+ */
+void ibx_display_interrupt_update(struct drm_i915_private *dev_priv,
+				  uint32_t interrupt_mask,
+				  uint32_t enabled_irq_mask)
+{
+	uint32_t sdeimr = I915_READ(SDEIMR);
+	sdeimr &= ~interrupt_mask;
+	sdeimr |= (~enabled_irq_mask & interrupt_mask);
+
+	WARN_ON(enabled_irq_mask & ~interrupt_mask);
+
+	assert_spin_locked(&dev_priv->irq_lock);
+
+	if (WARN_ON(!intel_irqs_enabled(dev_priv)))
+		return;
+
+	I915_WRITE(SDEIMR, sdeimr);
+	POSTING_READ(SDEIMR);
+}
+
+static void
+__i915_enable_pipestat(struct drm_i915_private *dev_priv, enum pipe pipe,
+		       u32 enable_mask, u32 status_mask)
+{
+	i915_reg_t reg = PIPESTAT(pipe);
+	u32 pipestat = I915_READ(reg) & PIPESTAT_INT_ENABLE_MASK;
+
+	assert_spin_locked(&dev_priv->irq_lock);
+	WARN_ON(!intel_irqs_enabled(dev_priv));
+
+	if (WARN_ONCE(enable_mask & ~PIPESTAT_INT_ENABLE_MASK ||
+		      status_mask & ~PIPESTAT_INT_STATUS_MASK,
+		      "pipe %c: enable_mask=0x%x, status_mask=0x%x\n",
+		      pipe_name(pipe), enable_mask, status_mask))
+		return;
+
+	if ((pipestat & enable_mask) == enable_mask)
+		return;
+
+	dev_priv->pipestat_irq_mask[pipe] |= status_mask;
+
+	/* Enable the interrupt, clear any pending status */
+	pipestat |= enable_mask | status_mask;
+	I915_WRITE(reg, pipestat);
+	POSTING_READ(reg);
+}
+
+static void
+__i915_disable_pipestat(struct drm_i915_private *dev_priv, enum pipe pipe,
+		        u32 enable_mask, u32 status_mask)
+{
+	i915_reg_t reg = PIPESTAT(pipe);
+	u32 pipestat = I915_READ(reg) & PIPESTAT_INT_ENABLE_MASK;
+
+	assert_spin_locked(&dev_priv->irq_lock);
+	WARN_ON(!intel_irqs_enabled(dev_priv));
+
+	if (WARN_ONCE(enable_mask & ~PIPESTAT_INT_ENABLE_MASK ||
+		      status_mask & ~PIPESTAT_INT_STATUS_MASK,
+		      "pipe %c: enable_mask=0x%x, status_mask=0x%x\n",
+		      pipe_name(pipe), enable_mask, status_mask))
+		return;
+
+	if ((pipestat & enable_mask) == 0)
+		return;
+
+	dev_priv->pipestat_irq_mask[pipe] &= ~status_mask;
+
+	pipestat &= ~enable_mask;
+	I915_WRITE(reg, pipestat);
+	POSTING_READ(reg);
+}
+
+static u32 vlv_get_pipestat_enable_mask(struct drm_device *dev, u32 status_mask)
+{
+	u32 enable_mask = status_mask << 16;
+
+	/*
+	 * On pipe A we don't support the PSR interrupt yet,
+	 * on pipe B and C the same bit MBZ.
+	 */
+	if (WARN_ON_ONCE(status_mask & PIPE_A_PSR_STATUS_VLV))
+		return 0;
+	/*
+	 * On pipe B and C we don't support the PSR interrupt yet, on pipe
+	 * A the same bit is for perf counters which we don't use either.
+	 */
+	if (WARN_ON_ONCE(status_mask & PIPE_B_PSR_STATUS_VLV))
+		return 0;
+
+	enable_mask &= ~(PIPE_FIFO_UNDERRUN_STATUS |
+			 SPRITE0_FLIP_DONE_INT_EN_VLV |
+			 SPRITE1_FLIP_DONE_INT_EN_VLV);
+	if (status_mask & SPRITE0_FLIP_DONE_INT_STATUS_VLV)
+		enable_mask |= SPRITE0_FLIP_DONE_INT_EN_VLV;
+	if (status_mask & SPRITE1_FLIP_DONE_INT_STATUS_VLV)
+		enable_mask |= SPRITE1_FLIP_DONE_INT_EN_VLV;
+
+	return enable_mask;
+}
+
+void
+i915_enable_pipestat(struct drm_i915_private *dev_priv, enum pipe pipe,
+		     u32 status_mask)
+{
+	u32 enable_mask;
+
+	if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
+		enable_mask = vlv_get_pipestat_enable_mask(dev_priv->dev,
+							   status_mask);
+	else
+		enable_mask = status_mask << 16;
+	__i915_enable_pipestat(dev_priv, pipe, enable_mask, status_mask);
+}
+
+void
+i915_disable_pipestat(struct drm_i915_private *dev_priv, enum pipe pipe,
+		      u32 status_mask)
+{
+	u32 enable_mask;
+
+	if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
+		enable_mask = vlv_get_pipestat_enable_mask(dev_priv->dev,
+							   status_mask);
+	else
+		enable_mask = status_mask << 16;
+	__i915_disable_pipestat(dev_priv, pipe, enable_mask, status_mask);
+}
+
+/**
+ * i915_enable_asle_pipestat - enable ASLE pipestat for OpRegion
+ * @dev: drm device
+ */
+static void i915_enable_asle_pipestat(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	if (!dev_priv->opregion.asle || !IS_MOBILE(dev))
+		return;
+
+	spin_lock_irq(&dev_priv->irq_lock);
+
+	i915_enable_pipestat(dev_priv, PIPE_B, PIPE_LEGACY_BLC_EVENT_STATUS);
+	if (INTEL_INFO(dev)->gen >= 4)
+		i915_enable_pipestat(dev_priv, PIPE_A,
+				     PIPE_LEGACY_BLC_EVENT_STATUS);
+
+	spin_unlock_irq(&dev_priv->irq_lock);
+}
+
+/*
+ * This timing diagram depicts the video signal in and
+ * around the vertical blanking period.
+ *
+ * Assumptions about the fictitious mode used in this example:
+ *  vblank_start >= 3
+ *  vsync_start = vblank_start + 1
+ *  vsync_end = vblank_start + 2
+ *  vtotal = vblank_start + 3
+ *
+ *           start of vblank:
+ *           latch double buffered registers
+ *           increment frame counter (ctg+)
+ *           generate start of vblank interrupt (gen4+)
+ *           |
+ *           |          frame start:
+ *           |          generate frame start interrupt (aka. vblank interrupt) (gmch)
+ *           |          may be shifted forward 1-3 extra lines via PIPECONF
+ *           |          |
+ *           |          |  start of vsync:
+ *           |          |  generate vsync interrupt
+ *           |          |  |
+ * ___xxxx___    ___xxxx___    ___xxxx___    ___xxxx___    ___xxxx___    ___xxxx
+ *       .   \hs/   .      \hs/          \hs/          \hs/   .      \hs/
+ * ----va---> <-----------------vb--------------------> <--------va-------------
+ *       |          |       <----vs----->                     |
+ * -vbs-----> <---vbs+1---> <---vbs+2---> <-----0-----> <-----1-----> <-----2--- (scanline counter gen2)
+ * -vbs-2---> <---vbs-1---> <---vbs-----> <---vbs+1---> <---vbs+2---> <-----0--- (scanline counter gen3+)
+ * -vbs-2---> <---vbs-2---> <---vbs-1---> <---vbs-----> <---vbs+1---> <---vbs+2- (scanline counter hsw+ hdmi)
+ *       |          |                                         |
+ *       last visible pixel                                   first visible pixel
+ *                  |                                         increment frame counter (gen3/4)
+ *                  pixel counter = vblank_start * htotal     pixel counter = 0 (gen3/4)
+ *
+ * x  = horizontal active
+ * _  = horizontal blanking
+ * hs = horizontal sync
+ * va = vertical active
+ * vb = vertical blanking
+ * vs = vertical sync
+ * vbs = vblank_start (number)
+ *
+ * Summary:
+ * - most events happen at the start of horizontal sync
+ * - frame start happens at the start of horizontal blank, 1-4 lines
+ *   (depending on PIPECONF settings) after the start of vblank
+ * - gen3/4 pixel and frame counter are synchronized with the start
+ *   of horizontal active on the first line of vertical active
+ */
+
+static u32 i8xx_get_vblank_counter(struct drm_device *dev, unsigned int pipe)
+{
+	/* Gen2 doesn't have a hardware frame counter */
+	return 0;
+}
+
+/* Called from drm generic code, passed a 'crtc', which
+ * we use as a pipe index
+ */
+static u32 i915_get_vblank_counter(struct drm_device *dev, unsigned int pipe)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	i915_reg_t high_frame, low_frame;
+	u32 high1, high2, low, pixel, vbl_start, hsync_start, htotal;
+	struct intel_crtc *intel_crtc =
+		to_intel_crtc(dev_priv->pipe_to_crtc_mapping[pipe]);
+	const struct drm_display_mode *mode = &intel_crtc->base.hwmode;
+
+	htotal = mode->crtc_htotal;
+	hsync_start = mode->crtc_hsync_start;
+	vbl_start = mode->crtc_vblank_start;
+	if (mode->flags & DRM_MODE_FLAG_INTERLACE)
+		vbl_start = DIV_ROUND_UP(vbl_start, 2);
+
+	/* Convert to pixel count */
+	vbl_start *= htotal;
+
+	/* Start of vblank event occurs at start of hsync */
+	vbl_start -= htotal - hsync_start;
+
+	high_frame = PIPEFRAME(pipe);
+	low_frame = PIPEFRAMEPIXEL(pipe);
+
+	/*
+	 * High & low register fields aren't synchronized, so make sure
+	 * we get a low value that's stable across two reads of the high
+	 * register.
+	 */
+	do {
+		high1 = I915_READ(high_frame) & PIPE_FRAME_HIGH_MASK;
+		low   = I915_READ(low_frame);
+		high2 = I915_READ(high_frame) & PIPE_FRAME_HIGH_MASK;
+	} while (high1 != high2);
+
+	high1 >>= PIPE_FRAME_HIGH_SHIFT;
+	pixel = low & PIPE_PIXEL_MASK;
+	low >>= PIPE_FRAME_LOW_SHIFT;
+
+	/*
+	 * The frame counter increments at beginning of active.
+	 * Cook up a vblank counter by also checking the pixel
+	 * counter against vblank start.
+	 */
+	return (((high1 << 8) | low) + (pixel >= vbl_start)) & 0xffffff;
+}
+
+static u32 g4x_get_vblank_counter(struct drm_device *dev, unsigned int pipe)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	return I915_READ(PIPE_FRMCOUNT_G4X(pipe));
+}
+
+/* I915_READ_FW, only for fast reads of display block, no need for forcewake etc. */
+static int __intel_get_crtc_scanline(struct intel_crtc *crtc)
+{
+	struct drm_device *dev = crtc->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	const struct drm_display_mode *mode = &crtc->base.hwmode;
+	enum pipe pipe = crtc->pipe;
+	int position, vtotal;
+
+	vtotal = mode->crtc_vtotal;
+	if (mode->flags & DRM_MODE_FLAG_INTERLACE)
+		vtotal /= 2;
+
+	if (IS_GEN2(dev))
+		position = I915_READ_FW(PIPEDSL(pipe)) & DSL_LINEMASK_GEN2;
+	else
+		position = I915_READ_FW(PIPEDSL(pipe)) & DSL_LINEMASK_GEN3;
+
+	/*
+	 * On HSW, the DSL reg (0x70000) appears to return 0 if we
+	 * read it just before the start of vblank.  So try it again
+	 * so we don't accidentally end up spanning a vblank frame
+	 * increment, causing the pipe_update_end() code to squak at us.
+	 *
+	 * The nature of this problem means we can't simply check the ISR
+	 * bit and return the vblank start value; nor can we use the scanline
+	 * debug register in the transcoder as it appears to have the same
+	 * problem.  We may need to extend this to include other platforms,
+	 * but so far testing only shows the problem on HSW.
+	 */
+	if (HAS_DDI(dev) && !position) {
+		int i, temp;
+
+		for (i = 0; i < 100; i++) {
+			udelay(1);
+			temp = __raw_i915_read32(dev_priv, PIPEDSL(pipe)) &
+				DSL_LINEMASK_GEN3;
+			if (temp != position) {
+				position = temp;
+				break;
+			}
+		}
+	}
+
+	/*
+	 * See update_scanline_offset() for the details on the
+	 * scanline_offset adjustment.
+	 */
+	return (position + crtc->scanline_offset) % vtotal;
+}
+
+static int i915_get_crtc_scanoutpos(struct drm_device *dev, unsigned int pipe,
+				    unsigned int flags, int *vpos, int *hpos,
+				    ktime_t *stime, ktime_t *etime,
+				    const struct drm_display_mode *mode)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe];
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	int position;
+	int vbl_start, vbl_end, hsync_start, htotal, vtotal;
+	bool in_vbl = true;
+	int ret = 0;
+	unsigned long irqflags;
+
+	if (WARN_ON(!mode->crtc_clock)) {
+		DRM_DEBUG_DRIVER("trying to get scanoutpos for disabled "
+				 "pipe %c\n", pipe_name(pipe));
+		return 0;
+	}
+
+	htotal = mode->crtc_htotal;
+	hsync_start = mode->crtc_hsync_start;
+	vtotal = mode->crtc_vtotal;
+	vbl_start = mode->crtc_vblank_start;
+	vbl_end = mode->crtc_vblank_end;
+
+	if (mode->flags & DRM_MODE_FLAG_INTERLACE) {
+		vbl_start = DIV_ROUND_UP(vbl_start, 2);
+		vbl_end /= 2;
+		vtotal /= 2;
+	}
+
+	ret |= DRM_SCANOUTPOS_VALID | DRM_SCANOUTPOS_ACCURATE;
+
+	/*
+	 * Lock uncore.lock, as we will do multiple timing critical raw
+	 * register reads, potentially with preemption disabled, so the
+	 * following code must not block on uncore.lock.
+	 */
+	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
+
+	/* preempt_disable_rt() should go right here in PREEMPT_RT patchset. */
+
+	/* Get optional system timestamp before query. */
+	if (stime)
+		*stime = ktime_get();
+
+	if (IS_GEN2(dev) || IS_G4X(dev) || INTEL_INFO(dev)->gen >= 5) {
+		/* No obvious pixelcount register. Only query vertical
+		 * scanout position from Display scan line register.
+		 */
+		position = __intel_get_crtc_scanline(intel_crtc);
+	} else {
+		/* Have access to pixelcount since start of frame.
+		 * We can split this into vertical and horizontal
+		 * scanout position.
+		 */
+		position = (I915_READ_FW(PIPEFRAMEPIXEL(pipe)) & PIPE_PIXEL_MASK) >> PIPE_PIXEL_SHIFT;
+
+		/* convert to pixel counts */
+		vbl_start *= htotal;
+		vbl_end *= htotal;
+		vtotal *= htotal;
+
+		/*
+		 * In interlaced modes, the pixel counter counts all pixels,
+		 * so one field will have htotal more pixels. In order to avoid
+		 * the reported position from jumping backwards when the pixel
+		 * counter is beyond the length of the shorter field, just
+		 * clamp the position the length of the shorter field. This
+		 * matches how the scanline counter based position works since
+		 * the scanline counter doesn't count the two half lines.
+		 */
+		if (position >= vtotal)
+			position = vtotal - 1;
+
+		/*
+		 * Start of vblank interrupt is triggered at start of hsync,
+		 * just prior to the first active line of vblank. However we
+		 * consider lines to start at the leading edge of horizontal
+		 * active. So, should we get here before we've crossed into
+		 * the horizontal active of the first line in vblank, we would
+		 * not set the DRM_SCANOUTPOS_INVBL flag. In order to fix that,
+		 * always add htotal-hsync_start to the current pixel position.
+		 */
+		position = (position + htotal - hsync_start) % vtotal;
+	}
+
+	/* Get optional system timestamp after query. */
+	if (etime)
+		*etime = ktime_get();
+
+	/* preempt_enable_rt() should go right here in PREEMPT_RT patchset. */
+
+	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
+
+	in_vbl = position >= vbl_start && position < vbl_end;
+
+	/*
+	 * While in vblank, position will be negative
+	 * counting up towards 0 at vbl_end. And outside
+	 * vblank, position will be positive counting
+	 * up since vbl_end.
+	 */
+	if (position >= vbl_start)
+		position -= vbl_end;
+	else
+		position += vtotal - vbl_end;
+
+	if (IS_GEN2(dev) || IS_G4X(dev) || INTEL_INFO(dev)->gen >= 5) {
+		*vpos = position;
+		*hpos = 0;
+	} else {
+		*vpos = position / htotal;
+		*hpos = position - (*vpos * htotal);
+	}
+
+	/* In vblank? */
+	if (in_vbl)
+		ret |= DRM_SCANOUTPOS_IN_VBLANK;
+
+	return ret;
+}
+
+int intel_get_crtc_scanline(struct intel_crtc *crtc)
+{
+	struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
+	unsigned long irqflags;
+	int position;
+
+	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
+	position = __intel_get_crtc_scanline(crtc);
+	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
+
+	return position;
+}
+
+static int i915_get_vblank_timestamp(struct drm_device *dev, unsigned int pipe,
+			      int *max_error,
+			      struct timeval *vblank_time,
+			      unsigned flags)
+{
+	struct drm_crtc *crtc;
+
+	if (pipe >= INTEL_INFO(dev)->num_pipes) {
+		DRM_ERROR("Invalid crtc %u\n", pipe);
+		return -EINVAL;
+	}
+
+	/* Get drm_crtc to timestamp: */
+	crtc = intel_get_crtc_for_pipe(dev, pipe);
+	if (crtc == NULL) {
+		DRM_ERROR("Invalid crtc %u\n", pipe);
+		return -EINVAL;
+	}
+
+	if (!crtc->hwmode.crtc_clock) {
+		DRM_DEBUG_KMS("crtc %u is disabled\n", pipe);
+		return -EBUSY;
+	}
+
+	/* Helper routine in DRM core does all the work: */
+	return drm_calc_vbltimestamp_from_scanoutpos(dev, pipe, max_error,
+						     vblank_time, flags,
+						     &crtc->hwmode);
+}
+
+static void ironlake_rps_change_irq_handler(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	u32 busy_up, busy_down, max_avg, min_avg;
+	u8 new_delay;
+
+	spin_lock(&mchdev_lock);
+
+	I915_WRITE16(MEMINTRSTS, I915_READ(MEMINTRSTS));
+
+	new_delay = dev_priv->ips.cur_delay;
+
+	I915_WRITE16(MEMINTRSTS, MEMINT_EVAL_CHG);
+	busy_up = I915_READ(RCPREVBSYTUPAVG);
+	busy_down = I915_READ(RCPREVBSYTDNAVG);
+	max_avg = I915_READ(RCBMAXAVG);
+	min_avg = I915_READ(RCBMINAVG);
+
+	/* Handle RCS change request from hw */
+	if (busy_up > max_avg) {
+		if (dev_priv->ips.cur_delay != dev_priv->ips.max_delay)
+			new_delay = dev_priv->ips.cur_delay - 1;
+		if (new_delay < dev_priv->ips.max_delay)
+			new_delay = dev_priv->ips.max_delay;
+	} else if (busy_down < min_avg) {
+		if (dev_priv->ips.cur_delay != dev_priv->ips.min_delay)
+			new_delay = dev_priv->ips.cur_delay + 1;
+		if (new_delay > dev_priv->ips.min_delay)
+			new_delay = dev_priv->ips.min_delay;
+	}
+
+	if (ironlake_set_drps(dev, new_delay))
+		dev_priv->ips.cur_delay = new_delay;
+
+	spin_unlock(&mchdev_lock);
+
+	return;
+}
+
+static void notify_ring(struct intel_engine_cs *engine)
+{
+	if (!intel_engine_initialized(engine))
+		return;
+
+	trace_i915_gem_request_notify(engine);
+	engine->user_interrupts++;
+
+	wake_up_all(&engine->irq_queue);
+}
+
+static void vlv_c0_read(struct drm_i915_private *dev_priv,
+			struct intel_rps_ei *ei)
+{
+	ei->cz_clock = vlv_punit_read(dev_priv, PUNIT_REG_CZ_TIMESTAMP);
+	ei->render_c0 = I915_READ(VLV_RENDER_C0_COUNT);
+	ei->media_c0 = I915_READ(VLV_MEDIA_C0_COUNT);
+}
+
+static bool vlv_c0_above(struct drm_i915_private *dev_priv,
+			 const struct intel_rps_ei *old,
+			 const struct intel_rps_ei *now,
+			 int threshold)
+{
+	u64 time, c0;
+	unsigned int mul = 100;
+
+	if (old->cz_clock == 0)
+		return false;
+
+	if (I915_READ(VLV_COUNTER_CONTROL) & VLV_COUNT_RANGE_HIGH)
+		mul <<= 8;
+
+	time = now->cz_clock - old->cz_clock;
+	time *= threshold * dev_priv->czclk_freq;
+
+	/* Workload can be split between render + media, e.g. SwapBuffers
+	 * being blitted in X after being rendered in mesa. To account for
+	 * this we need to combine both engines into our activity counter.
+	 */
+	c0 = now->render_c0 - old->render_c0;
+	c0 += now->media_c0 - old->media_c0;
+	c0 *= mul * VLV_CZ_CLOCK_TO_MILLI_SEC;
+
+	return c0 >= time;
+}
+
+void gen6_rps_reset_ei(struct drm_i915_private *dev_priv)
+{
+	vlv_c0_read(dev_priv, &dev_priv->rps.down_ei);
+	dev_priv->rps.up_ei = dev_priv->rps.down_ei;
+}
+
+static u32 vlv_wa_c0_ei(struct drm_i915_private *dev_priv, u32 pm_iir)
+{
+	struct intel_rps_ei now;
+	u32 events = 0;
+
+	if ((pm_iir & (GEN6_PM_RP_DOWN_EI_EXPIRED | GEN6_PM_RP_UP_EI_EXPIRED)) == 0)
+		return 0;
+
+	vlv_c0_read(dev_priv, &now);
+	if (now.cz_clock == 0)
+		return 0;
+
+	if (pm_iir & GEN6_PM_RP_DOWN_EI_EXPIRED) {
+		if (!vlv_c0_above(dev_priv,
+				  &dev_priv->rps.down_ei, &now,
+				  dev_priv->rps.down_threshold))
+			events |= GEN6_PM_RP_DOWN_THRESHOLD;
+		dev_priv->rps.down_ei = now;
+	}
+
+	if (pm_iir & GEN6_PM_RP_UP_EI_EXPIRED) {
+		if (vlv_c0_above(dev_priv,
+				 &dev_priv->rps.up_ei, &now,
+				 dev_priv->rps.up_threshold))
+			events |= GEN6_PM_RP_UP_THRESHOLD;
+		dev_priv->rps.up_ei = now;
+	}
+
+	return events;
+}
+
+static bool any_waiters(struct drm_i915_private *dev_priv)
+{
+	struct intel_engine_cs *engine;
+
+	for_each_engine(engine, dev_priv)
+		if (engine->irq_refcount)
+			return true;
+
+	return false;
+}
+
+static void gen6_pm_rps_work(struct work_struct *work)
+{
+	struct drm_i915_private *dev_priv =
+		container_of(work, struct drm_i915_private, rps.work);
+	bool client_boost;
+	int new_delay, adj, min, max;
+	u32 pm_iir;
+
+	spin_lock_irq(&dev_priv->irq_lock);
+	/* Speed up work cancelation during disabling rps interrupts. */
+	if (!dev_priv->rps.interrupts_enabled) {
+		spin_unlock_irq(&dev_priv->irq_lock);
+		return;
+	}
+
+	/*
+	 * The RPS work is synced during runtime suspend, we don't require a
+	 * wakeref. TODO: instead of disabling the asserts make sure that we
+	 * always hold an RPM reference while the work is running.
+	 */
+	DISABLE_RPM_WAKEREF_ASSERTS(dev_priv);
+
+	pm_iir = dev_priv->rps.pm_iir;
+	dev_priv->rps.pm_iir = 0;
+	/* Make sure not to corrupt PMIMR state used by ringbuffer on GEN6 */
+	gen6_enable_pm_irq(dev_priv, dev_priv->pm_rps_events);
+	client_boost = dev_priv->rps.client_boost;
+	dev_priv->rps.client_boost = false;
+	spin_unlock_irq(&dev_priv->irq_lock);
+
+	/* Make sure we didn't queue anything we're not going to process. */
+	WARN_ON(pm_iir & ~dev_priv->pm_rps_events);
+
+	if ((pm_iir & dev_priv->pm_rps_events) == 0 && !client_boost)
+		goto out;
+
+	mutex_lock(&dev_priv->rps.hw_lock);
+
+	pm_iir |= vlv_wa_c0_ei(dev_priv, pm_iir);
+
+	adj = dev_priv->rps.last_adj;
+	new_delay = dev_priv->rps.cur_freq;
+	min = dev_priv->rps.min_freq_softlimit;
+	max = dev_priv->rps.max_freq_softlimit;
+
+	if (client_boost) {
+		new_delay = dev_priv->rps.max_freq_softlimit;
+		adj = 0;
+	} else if (pm_iir & GEN6_PM_RP_UP_THRESHOLD) {
+		if (adj > 0)
+			adj *= 2;
+		else /* CHV needs even encode values */
+			adj = IS_CHERRYVIEW(dev_priv) ? 2 : 1;
+		/*
+		 * For better performance, jump directly
+		 * to RPe if we're below it.
+		 */
+		if (new_delay < dev_priv->rps.efficient_freq - adj) {
+			new_delay = dev_priv->rps.efficient_freq;
+			adj = 0;
+		}
+	} else if (any_waiters(dev_priv)) {
+		adj = 0;
+	} else if (pm_iir & GEN6_PM_RP_DOWN_TIMEOUT) {
+		if (dev_priv->rps.cur_freq > dev_priv->rps.efficient_freq)
+			new_delay = dev_priv->rps.efficient_freq;
+		else
+			new_delay = dev_priv->rps.min_freq_softlimit;
+		adj = 0;
+	} else if (pm_iir & GEN6_PM_RP_DOWN_THRESHOLD) {
+		if (adj < 0)
+			adj *= 2;
+		else /* CHV needs even encode values */
+			adj = IS_CHERRYVIEW(dev_priv) ? -2 : -1;
+	} else { /* unknown event */
+		adj = 0;
+	}
+
+	dev_priv->rps.last_adj = adj;
+
+	/* sysfs frequency interfaces may have snuck in while servicing the
+	 * interrupt
+	 */
+	new_delay += adj;
+	new_delay = clamp_t(int, new_delay, min, max);
+
+	intel_set_rps(dev_priv->dev, new_delay);
+
+	mutex_unlock(&dev_priv->rps.hw_lock);
+out:
+	ENABLE_RPM_WAKEREF_ASSERTS(dev_priv);
+}
+
+
+/**
+ * ivybridge_parity_work - Workqueue called when a parity error interrupt
+ * occurred.
+ * @work: workqueue struct
+ *
+ * Doesn't actually do anything except notify userspace. As a consequence of
+ * this event, userspace should try to remap the bad rows since statistically
+ * it is likely the same row is more likely to go bad again.
+ */
+static void ivybridge_parity_work(struct work_struct *work)
+{
+	struct drm_i915_private *dev_priv =
+		container_of(work, struct drm_i915_private, l3_parity.error_work);
+	u32 error_status, row, bank, subbank;
+	char *parity_event[6];
+	uint32_t misccpctl;
+	uint8_t slice = 0;
+
+	/* We must turn off DOP level clock gating to access the L3 registers.
+	 * In order to prevent a get/put style interface, acquire struct mutex
+	 * any time we access those registers.
+	 */
+	mutex_lock(&dev_priv->dev->struct_mutex);
+
+	/* If we've screwed up tracking, just let the interrupt fire again */
+	if (WARN_ON(!dev_priv->l3_parity.which_slice))
+		goto out;
+
+	misccpctl = I915_READ(GEN7_MISCCPCTL);
+	I915_WRITE(GEN7_MISCCPCTL, misccpctl & ~GEN7_DOP_CLOCK_GATE_ENABLE);
+	POSTING_READ(GEN7_MISCCPCTL);
+
+	while ((slice = ffs(dev_priv->l3_parity.which_slice)) != 0) {
+		i915_reg_t reg;
+
+		slice--;
+		if (WARN_ON_ONCE(slice >= NUM_L3_SLICES(dev_priv)))
+			break;
+
+		dev_priv->l3_parity.which_slice &= ~(1<<slice);
+
+		reg = GEN7_L3CDERRST1(slice);
+
+		error_status = I915_READ(reg);
+		row = GEN7_PARITY_ERROR_ROW(error_status);
+		bank = GEN7_PARITY_ERROR_BANK(error_status);
+		subbank = GEN7_PARITY_ERROR_SUBBANK(error_status);
+
+		I915_WRITE(reg, GEN7_PARITY_ERROR_VALID | GEN7_L3CDERRST1_ENABLE);
+		POSTING_READ(reg);
+
+		parity_event[0] = I915_L3_PARITY_UEVENT "=1";
+		parity_event[1] = kasprintf(GFP_KERNEL, "ROW=%d", row);
+		parity_event[2] = kasprintf(GFP_KERNEL, "BANK=%d", bank);
+		parity_event[3] = kasprintf(GFP_KERNEL, "SUBBANK=%d", subbank);
+		parity_event[4] = kasprintf(GFP_KERNEL, "SLICE=%d", slice);
+		parity_event[5] = NULL;
+
+		kobject_uevent_env(&dev_priv->dev->primary->kdev->kobj,
+				   KOBJ_CHANGE, parity_event);
+
+		DRM_DEBUG("Parity error: Slice = %d, Row = %d, Bank = %d, Sub bank = %d.\n",
+			  slice, row, bank, subbank);
+
+		kfree(parity_event[4]);
+		kfree(parity_event[3]);
+		kfree(parity_event[2]);
+		kfree(parity_event[1]);
+	}
+
+	I915_WRITE(GEN7_MISCCPCTL, misccpctl);
+
+out:
+	WARN_ON(dev_priv->l3_parity.which_slice);
+	spin_lock_irq(&dev_priv->irq_lock);
+	gen5_enable_gt_irq(dev_priv, GT_PARITY_ERROR(dev_priv));
+	spin_unlock_irq(&dev_priv->irq_lock);
+
+	mutex_unlock(&dev_priv->dev->struct_mutex);
+}
+
+static void ivybridge_parity_error_irq_handler(struct drm_i915_private *dev_priv,
+					       u32 iir)
+{
+	if (!HAS_L3_DPF(dev_priv))
+		return;
+
+	spin_lock(&dev_priv->irq_lock);
+	gen5_disable_gt_irq(dev_priv, GT_PARITY_ERROR(dev_priv));
+	spin_unlock(&dev_priv->irq_lock);
+
+	iir &= GT_PARITY_ERROR(dev_priv);
+	if (iir & GT_RENDER_L3_PARITY_ERROR_INTERRUPT_S1)
+		dev_priv->l3_parity.which_slice |= 1 << 1;
+
+	if (iir & GT_RENDER_L3_PARITY_ERROR_INTERRUPT)
+		dev_priv->l3_parity.which_slice |= 1 << 0;
+
+	queue_work(dev_priv->wq, &dev_priv->l3_parity.error_work);
+}
+
+static void ilk_gt_irq_handler(struct drm_i915_private *dev_priv,
+			       u32 gt_iir)
+{
+	if (gt_iir &
+	    (GT_RENDER_USER_INTERRUPT | GT_RENDER_PIPECTL_NOTIFY_INTERRUPT))
+		notify_ring(&dev_priv->engine[RCS]);
+	if (gt_iir & ILK_BSD_USER_INTERRUPT)
+		notify_ring(&dev_priv->engine[VCS]);
+}
+
+static void snb_gt_irq_handler(struct drm_i915_private *dev_priv,
+			       u32 gt_iir)
+{
+
+	if (gt_iir &
+	    (GT_RENDER_USER_INTERRUPT | GT_RENDER_PIPECTL_NOTIFY_INTERRUPT))
+		notify_ring(&dev_priv->engine[RCS]);
+	if (gt_iir & GT_BSD_USER_INTERRUPT)
+		notify_ring(&dev_priv->engine[VCS]);
+	if (gt_iir & GT_BLT_USER_INTERRUPT)
+		notify_ring(&dev_priv->engine[BCS]);
+
+	if (gt_iir & (GT_BLT_CS_ERROR_INTERRUPT |
+		      GT_BSD_CS_ERROR_INTERRUPT |
+		      GT_RENDER_CS_MASTER_ERROR_INTERRUPT))
+		DRM_DEBUG("Command parser error, gt_iir 0x%08x\n", gt_iir);
+
+	if (gt_iir & GT_PARITY_ERROR(dev_priv))
+		ivybridge_parity_error_irq_handler(dev_priv, gt_iir);
+}
+
+static __always_inline void
+gen8_cs_irq_handler(struct intel_engine_cs *engine, u32 iir, int test_shift)
+{
+	if (iir & (GT_RENDER_USER_INTERRUPT << test_shift))
+		notify_ring(engine);
+	if (iir & (GT_CONTEXT_SWITCH_INTERRUPT << test_shift))
+		tasklet_schedule(&engine->irq_tasklet);
+}
+
+static irqreturn_t gen8_gt_irq_ack(struct drm_i915_private *dev_priv,
+				   u32 master_ctl,
+				   u32 gt_iir[4])
+{
+	irqreturn_t ret = IRQ_NONE;
+
+	if (master_ctl & (GEN8_GT_RCS_IRQ | GEN8_GT_BCS_IRQ)) {
+		gt_iir[0] = I915_READ_FW(GEN8_GT_IIR(0));
+		if (gt_iir[0]) {
+			I915_WRITE_FW(GEN8_GT_IIR(0), gt_iir[0]);
+			ret = IRQ_HANDLED;
+		} else
+			DRM_ERROR("The master control interrupt lied (GT0)!\n");
+	}
+
+	if (master_ctl & (GEN8_GT_VCS1_IRQ | GEN8_GT_VCS2_IRQ)) {
+		gt_iir[1] = I915_READ_FW(GEN8_GT_IIR(1));
+		if (gt_iir[1]) {
+			I915_WRITE_FW(GEN8_GT_IIR(1), gt_iir[1]);
+			ret = IRQ_HANDLED;
+		} else
+			DRM_ERROR("The master control interrupt lied (GT1)!\n");
+	}
+
+	if (master_ctl & GEN8_GT_VECS_IRQ) {
+		gt_iir[3] = I915_READ_FW(GEN8_GT_IIR(3));
+		if (gt_iir[3]) {
+			I915_WRITE_FW(GEN8_GT_IIR(3), gt_iir[3]);
+			ret = IRQ_HANDLED;
+		} else
+			DRM_ERROR("The master control interrupt lied (GT3)!\n");
+	}
+
+	if (master_ctl & GEN8_GT_PM_IRQ) {
+		gt_iir[2] = I915_READ_FW(GEN8_GT_IIR(2));
+		if (gt_iir[2] & dev_priv->pm_rps_events) {
+			I915_WRITE_FW(GEN8_GT_IIR(2),
+				      gt_iir[2] & dev_priv->pm_rps_events);
+			ret = IRQ_HANDLED;
+		} else
+			DRM_ERROR("The master control interrupt lied (PM)!\n");
+	}
+
+	return ret;
+}
+
+static void gen8_gt_irq_handler(struct drm_i915_private *dev_priv,
+				u32 gt_iir[4])
+{
+	if (gt_iir[0]) {
+		gen8_cs_irq_handler(&dev_priv->engine[RCS],
+				    gt_iir[0], GEN8_RCS_IRQ_SHIFT);
+		gen8_cs_irq_handler(&dev_priv->engine[BCS],
+				    gt_iir[0], GEN8_BCS_IRQ_SHIFT);
+	}
+
+	if (gt_iir[1]) {
+		gen8_cs_irq_handler(&dev_priv->engine[VCS],
+				    gt_iir[1], GEN8_VCS1_IRQ_SHIFT);
+		gen8_cs_irq_handler(&dev_priv->engine[VCS2],
+				    gt_iir[1], GEN8_VCS2_IRQ_SHIFT);
+	}
+
+	if (gt_iir[3])
+		gen8_cs_irq_handler(&dev_priv->engine[VECS],
+				    gt_iir[3], GEN8_VECS_IRQ_SHIFT);
+
+	if (gt_iir[2] & dev_priv->pm_rps_events)
+		gen6_rps_irq_handler(dev_priv, gt_iir[2]);
+}
+
+static bool bxt_port_hotplug_long_detect(enum port port, u32 val)
+{
+	switch (port) {
+	case PORT_A:
+		return val & PORTA_HOTPLUG_LONG_DETECT;
+	case PORT_B:
+		return val & PORTB_HOTPLUG_LONG_DETECT;
+	case PORT_C:
+		return val & PORTC_HOTPLUG_LONG_DETECT;
+	default:
+		return false;
+	}
+}
+
+static bool spt_port_hotplug2_long_detect(enum port port, u32 val)
+{
+	switch (port) {
+	case PORT_E:
+		return val & PORTE_HOTPLUG_LONG_DETECT;
+	default:
+		return false;
+	}
+}
+
+static bool spt_port_hotplug_long_detect(enum port port, u32 val)
+{
+	switch (port) {
+	case PORT_A:
+		return val & PORTA_HOTPLUG_LONG_DETECT;
+	case PORT_B:
+		return val & PORTB_HOTPLUG_LONG_DETECT;
+	case PORT_C:
+		return val & PORTC_HOTPLUG_LONG_DETECT;
+	case PORT_D:
+		return val & PORTD_HOTPLUG_LONG_DETECT;
+	default:
+		return false;
+	}
+}
+
+static bool ilk_port_hotplug_long_detect(enum port port, u32 val)
+{
+	switch (port) {
+	case PORT_A:
+		return val & DIGITAL_PORTA_HOTPLUG_LONG_DETECT;
+	default:
+		return false;
+	}
+}
+
+static bool pch_port_hotplug_long_detect(enum port port, u32 val)
+{
+	switch (port) {
+	case PORT_B:
+		return val & PORTB_HOTPLUG_LONG_DETECT;
+	case PORT_C:
+		return val & PORTC_HOTPLUG_LONG_DETECT;
+	case PORT_D:
+		return val & PORTD_HOTPLUG_LONG_DETECT;
+	default:
+		return false;
+	}
+}
+
+static bool i9xx_port_hotplug_long_detect(enum port port, u32 val)
+{
+	switch (port) {
+	case PORT_B:
+		return val & PORTB_HOTPLUG_INT_LONG_PULSE;
+	case PORT_C:
+		return val & PORTC_HOTPLUG_INT_LONG_PULSE;
+	case PORT_D:
+		return val & PORTD_HOTPLUG_INT_LONG_PULSE;
+	default:
+		return false;
+	}
+}
+
+/*
+ * Get a bit mask of pins that have triggered, and which ones may be long.
+ * This can be called multiple times with the same masks to accumulate
+ * hotplug detection results from several registers.
+ *
+ * Note that the caller is expected to zero out the masks initially.
+ */
+static void intel_get_hpd_pins(u32 *pin_mask, u32 *long_mask,
+			     u32 hotplug_trigger, u32 dig_hotplug_reg,
+			     const u32 hpd[HPD_NUM_PINS],
+			     bool long_pulse_detect(enum port port, u32 val))
+{
+	enum port port;
+	int i;
+
+	for_each_hpd_pin(i) {
+		if ((hpd[i] & hotplug_trigger) == 0)
+			continue;
+
+		*pin_mask |= BIT(i);
+
+		if (!intel_hpd_pin_to_port(i, &port))
+			continue;
+
+		if (long_pulse_detect(port, dig_hotplug_reg))
+			*long_mask |= BIT(i);
+	}
+
+	DRM_DEBUG_DRIVER("hotplug event received, stat 0x%08x, dig 0x%08x, pins 0x%08x\n",
+			 hotplug_trigger, dig_hotplug_reg, *pin_mask);
+
+}
+
+static void gmbus_irq_handler(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	wake_up_all(&dev_priv->gmbus_wait_queue);
+}
+
+static void dp_aux_irq_handler(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	wake_up_all(&dev_priv->gmbus_wait_queue);
+}
+
+#if defined(CONFIG_DEBUG_FS)
+static void display_pipe_crc_irq_handler(struct drm_device *dev, enum pipe pipe,
+					 uint32_t crc0, uint32_t crc1,
+					 uint32_t crc2, uint32_t crc3,
+					 uint32_t crc4)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_pipe_crc *pipe_crc = &dev_priv->pipe_crc[pipe];
+	struct intel_pipe_crc_entry *entry;
+	int head, tail;
+
+	spin_lock(&pipe_crc->lock);
+
+	if (!pipe_crc->entries) {
+		spin_unlock(&pipe_crc->lock);
+		DRM_DEBUG_KMS("spurious interrupt\n");
+		return;
+	}
+
+	head = pipe_crc->head;
+	tail = pipe_crc->tail;
+
+	if (CIRC_SPACE(head, tail, INTEL_PIPE_CRC_ENTRIES_NR) < 1) {
+		spin_unlock(&pipe_crc->lock);
+		DRM_ERROR("CRC buffer overflowing\n");
+		return;
+	}
+
+	entry = &pipe_crc->entries[head];
+
+	entry->frame = dev->driver->get_vblank_counter(dev, pipe);
+	entry->crc[0] = crc0;
+	entry->crc[1] = crc1;
+	entry->crc[2] = crc2;
+	entry->crc[3] = crc3;
+	entry->crc[4] = crc4;
+
+	head = (head + 1) & (INTEL_PIPE_CRC_ENTRIES_NR - 1);
+	pipe_crc->head = head;
+
+	spin_unlock(&pipe_crc->lock);
+
+	wake_up_interruptible(&pipe_crc->wq);
+}
+#else
+static inline void
+display_pipe_crc_irq_handler(struct drm_device *dev, enum pipe pipe,
+			     uint32_t crc0, uint32_t crc1,
+			     uint32_t crc2, uint32_t crc3,
+			     uint32_t crc4) {}
+#endif
+
+
+static void hsw_pipe_crc_irq_handler(struct drm_device *dev, enum pipe pipe)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	display_pipe_crc_irq_handler(dev, pipe,
+				     I915_READ(PIPE_CRC_RES_1_IVB(pipe)),
+				     0, 0, 0, 0);
+}
+
+static void ivb_pipe_crc_irq_handler(struct drm_device *dev, enum pipe pipe)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	display_pipe_crc_irq_handler(dev, pipe,
+				     I915_READ(PIPE_CRC_RES_1_IVB(pipe)),
+				     I915_READ(PIPE_CRC_RES_2_IVB(pipe)),
+				     I915_READ(PIPE_CRC_RES_3_IVB(pipe)),
+				     I915_READ(PIPE_CRC_RES_4_IVB(pipe)),
+				     I915_READ(PIPE_CRC_RES_5_IVB(pipe)));
+}
+
+static void i9xx_pipe_crc_irq_handler(struct drm_device *dev, enum pipe pipe)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	uint32_t res1, res2;
+
+	if (INTEL_INFO(dev)->gen >= 3)
+		res1 = I915_READ(PIPE_CRC_RES_RES1_I915(pipe));
+	else
+		res1 = 0;
+
+	if (INTEL_INFO(dev)->gen >= 5 || IS_G4X(dev))
+		res2 = I915_READ(PIPE_CRC_RES_RES2_G4X(pipe));
+	else
+		res2 = 0;
+
+	display_pipe_crc_irq_handler(dev, pipe,
+				     I915_READ(PIPE_CRC_RES_RED(pipe)),
+				     I915_READ(PIPE_CRC_RES_GREEN(pipe)),
+				     I915_READ(PIPE_CRC_RES_BLUE(pipe)),
+				     res1, res2);
+}
+
+/* The RPS events need forcewake, so we add them to a work queue and mask their
+ * IMR bits until the work is done. Other interrupts can be processed without
+ * the work queue. */
+static void gen6_rps_irq_handler(struct drm_i915_private *dev_priv, u32 pm_iir)
+{
+	if (pm_iir & dev_priv->pm_rps_events) {
+		spin_lock(&dev_priv->irq_lock);
+		gen6_disable_pm_irq(dev_priv, pm_iir & dev_priv->pm_rps_events);
+		if (dev_priv->rps.interrupts_enabled) {
+			dev_priv->rps.pm_iir |= pm_iir & dev_priv->pm_rps_events;
+			queue_work(dev_priv->wq, &dev_priv->rps.work);
+		}
+		spin_unlock(&dev_priv->irq_lock);
+	}
+
+	if (INTEL_INFO(dev_priv)->gen >= 8)
+		return;
+
+	if (HAS_VEBOX(dev_priv)) {
+		if (pm_iir & PM_VEBOX_USER_INTERRUPT)
+			notify_ring(&dev_priv->engine[VECS]);
+
+		if (pm_iir & PM_VEBOX_CS_ERROR_INTERRUPT)
+			DRM_DEBUG("Command parser error, pm_iir 0x%08x\n", pm_iir);
+	}
+}
+
+static bool intel_pipe_handle_vblank(struct drm_device *dev, enum pipe pipe)
+{
+	if (!drm_handle_vblank(dev, pipe))
+		return false;
+
+	return true;
+}
+
+static void valleyview_pipestat_irq_ack(struct drm_device *dev, u32 iir,
+					u32 pipe_stats[I915_MAX_PIPES])
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	int pipe;
+
+	spin_lock(&dev_priv->irq_lock);
+
+	if (!dev_priv->display_irqs_enabled) {
+		spin_unlock(&dev_priv->irq_lock);
+		return;
+	}
+
+	for_each_pipe(dev_priv, pipe) {
+		i915_reg_t reg;
+		u32 mask, iir_bit = 0;
+
+		/*
+		 * PIPESTAT bits get signalled even when the interrupt is
+		 * disabled with the mask bits, and some of the status bits do
+		 * not generate interrupts at all (like the underrun bit). Hence
+		 * we need to be careful that we only handle what we want to
+		 * handle.
+		 */
+
+		/* fifo underruns are filterered in the underrun handler. */
+		mask = PIPE_FIFO_UNDERRUN_STATUS;
+
+		switch (pipe) {
+		case PIPE_A:
+			iir_bit = I915_DISPLAY_PIPE_A_EVENT_INTERRUPT;
+			break;
+		case PIPE_B:
+			iir_bit = I915_DISPLAY_PIPE_B_EVENT_INTERRUPT;
+			break;
+		case PIPE_C:
+			iir_bit = I915_DISPLAY_PIPE_C_EVENT_INTERRUPT;
+			break;
+		}
+		if (iir & iir_bit)
+			mask |= dev_priv->pipestat_irq_mask[pipe];
+
+		if (!mask)
+			continue;
+
+		reg = PIPESTAT(pipe);
+		mask |= PIPESTAT_INT_ENABLE_MASK;
+		pipe_stats[pipe] = I915_READ(reg) & mask;
+
+		/*
+		 * Clear the PIPE*STAT regs before the IIR
+		 */
+		if (pipe_stats[pipe] & (PIPE_FIFO_UNDERRUN_STATUS |
+					PIPESTAT_INT_STATUS_MASK))
+			I915_WRITE(reg, pipe_stats[pipe]);
+	}
+	spin_unlock(&dev_priv->irq_lock);
+}
+
+static void valleyview_pipestat_irq_handler(struct drm_device *dev,
+					    u32 pipe_stats[I915_MAX_PIPES])
+{
+	struct drm_i915_private *dev_priv = to_i915(dev);
+	enum pipe pipe;
+
+	for_each_pipe(dev_priv, pipe) {
+		if (pipe_stats[pipe] & PIPE_START_VBLANK_INTERRUPT_STATUS &&
+		    intel_pipe_handle_vblank(dev, pipe))
+			intel_check_page_flip(dev, pipe);
+
+		if (pipe_stats[pipe] & PLANE_FLIP_DONE_INT_STATUS_VLV) {
+			intel_prepare_page_flip(dev, pipe);
+			intel_finish_page_flip(dev, pipe);
+		}
+
+		if (pipe_stats[pipe] & PIPE_CRC_DONE_INTERRUPT_STATUS)
+			i9xx_pipe_crc_irq_handler(dev, pipe);
+
+		if (pipe_stats[pipe] & PIPE_FIFO_UNDERRUN_STATUS)
+			intel_cpu_fifo_underrun_irq_handler(dev_priv, pipe);
+	}
+
+	if (pipe_stats[0] & PIPE_GMBUS_INTERRUPT_STATUS)
+		gmbus_irq_handler(dev);
+}
+
+static u32 i9xx_hpd_irq_ack(struct drm_i915_private *dev_priv)
+{
+	u32 hotplug_status = I915_READ(PORT_HOTPLUG_STAT);
+
+	if (hotplug_status)
+		I915_WRITE(PORT_HOTPLUG_STAT, hotplug_status);
+
+	return hotplug_status;
+}
+
+static void i9xx_hpd_irq_handler(struct drm_device *dev,
+				 u32 hotplug_status)
+{
+	u32 pin_mask = 0, long_mask = 0;
+
+	if (IS_G4X(dev) || IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev)) {
+		u32 hotplug_trigger = hotplug_status & HOTPLUG_INT_STATUS_G4X;
+
+		if (hotplug_trigger) {
+			intel_get_hpd_pins(&pin_mask, &long_mask, hotplug_trigger,
+					   hotplug_trigger, hpd_status_g4x,
+					   i9xx_port_hotplug_long_detect);
+
+			intel_hpd_irq_handler(dev, pin_mask, long_mask);
+		}
+
+		if (hotplug_status & DP_AUX_CHANNEL_MASK_INT_STATUS_G4X)
+			dp_aux_irq_handler(dev);
+	} else {
+		u32 hotplug_trigger = hotplug_status & HOTPLUG_INT_STATUS_I915;
+
+		if (hotplug_trigger) {
+			intel_get_hpd_pins(&pin_mask, &long_mask, hotplug_trigger,
+					   hotplug_trigger, hpd_status_i915,
+					   i9xx_port_hotplug_long_detect);
+			intel_hpd_irq_handler(dev, pin_mask, long_mask);
+		}
+	}
+}
+
+static irqreturn_t valleyview_irq_handler(int irq, void *arg)
+{
+	struct drm_device *dev = arg;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	irqreturn_t ret = IRQ_NONE;
+
+	if (!intel_irqs_enabled(dev_priv))
+		return IRQ_NONE;
+
+	/* IRQs are synced during runtime_suspend, we don't require a wakeref */
+	disable_rpm_wakeref_asserts(dev_priv);
+
+	do {
+		u32 iir, gt_iir, pm_iir;
+		u32 pipe_stats[I915_MAX_PIPES] = {};
+		u32 hotplug_status = 0;
+		u32 ier = 0;
+
+		gt_iir = I915_READ(GTIIR);
+		pm_iir = I915_READ(GEN6_PMIIR);
+		iir = I915_READ(VLV_IIR);
+
+		if (gt_iir == 0 && pm_iir == 0 && iir == 0)
+			break;
+
+		ret = IRQ_HANDLED;
+
+		/*
+		 * Theory on interrupt generation, based on empirical evidence:
+		 *
+		 * x = ((VLV_IIR & VLV_IER) ||
+		 *      (((GT_IIR & GT_IER) || (GEN6_PMIIR & GEN6_PMIER)) &&
+		 *       (VLV_MASTER_IER & MASTER_INTERRUPT_ENABLE)));
+		 *
+		 * A CPU interrupt will only be raised when 'x' has a 0->1 edge.
+		 * Hence we clear MASTER_INTERRUPT_ENABLE and VLV_IER to
+		 * guarantee the CPU interrupt will be raised again even if we
+		 * don't end up clearing all the VLV_IIR, GT_IIR, GEN6_PMIIR
+		 * bits this time around.
+		 */
+		I915_WRITE(VLV_MASTER_IER, 0);
+		ier = I915_READ(VLV_IER);
+		I915_WRITE(VLV_IER, 0);
+
+		if (gt_iir)
+			I915_WRITE(GTIIR, gt_iir);
+		if (pm_iir)
+			I915_WRITE(GEN6_PMIIR, pm_iir);
+
+		if (iir & I915_DISPLAY_PORT_INTERRUPT)
+			hotplug_status = i9xx_hpd_irq_ack(dev_priv);
+
+		/* Call regardless, as some status bits might not be
+		 * signalled in iir */
+		valleyview_pipestat_irq_ack(dev, iir, pipe_stats);
+
+		/*
+		 * VLV_IIR is single buffered, and reflects the level
+		 * from PIPESTAT/PORT_HOTPLUG_STAT, hence clear it last.
+		 */
+		if (iir)
+			I915_WRITE(VLV_IIR, iir);
+
+		I915_WRITE(VLV_IER, ier);
+		I915_WRITE(VLV_MASTER_IER, MASTER_INTERRUPT_ENABLE);
+		POSTING_READ(VLV_MASTER_IER);
+
+		if (gt_iir)
+			snb_gt_irq_handler(dev_priv, gt_iir);
+		if (pm_iir)
+			gen6_rps_irq_handler(dev_priv, pm_iir);
+
+		if (hotplug_status)
+			i9xx_hpd_irq_handler(dev, hotplug_status);
+
+		valleyview_pipestat_irq_handler(dev, pipe_stats);
+	} while (0);
+
+	enable_rpm_wakeref_asserts(dev_priv);
+
+	return ret;
+}
+
+static irqreturn_t cherryview_irq_handler(int irq, void *arg)
+{
+	struct drm_device *dev = arg;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	irqreturn_t ret = IRQ_NONE;
+
+	if (!intel_irqs_enabled(dev_priv))
+		return IRQ_NONE;
+
+	/* IRQs are synced during runtime_suspend, we don't require a wakeref */
+	disable_rpm_wakeref_asserts(dev_priv);
+
+	do {
+		u32 master_ctl, iir;
+		u32 gt_iir[4] = {};
+		u32 pipe_stats[I915_MAX_PIPES] = {};
+		u32 hotplug_status = 0;
+		u32 ier = 0;
+
+		master_ctl = I915_READ(GEN8_MASTER_IRQ) & ~GEN8_MASTER_IRQ_CONTROL;
+		iir = I915_READ(VLV_IIR);
+
+		if (master_ctl == 0 && iir == 0)
+			break;
+
+		ret = IRQ_HANDLED;
+
+		/*
+		 * Theory on interrupt generation, based on empirical evidence:
+		 *
+		 * x = ((VLV_IIR & VLV_IER) ||
+		 *      ((GEN8_MASTER_IRQ & ~GEN8_MASTER_IRQ_CONTROL) &&
+		 *       (GEN8_MASTER_IRQ & GEN8_MASTER_IRQ_CONTROL)));
+		 *
+		 * A CPU interrupt will only be raised when 'x' has a 0->1 edge.
+		 * Hence we clear GEN8_MASTER_IRQ_CONTROL and VLV_IER to
+		 * guarantee the CPU interrupt will be raised again even if we
+		 * don't end up clearing all the VLV_IIR and GEN8_MASTER_IRQ_CONTROL
+		 * bits this time around.
+		 */
+		I915_WRITE(GEN8_MASTER_IRQ, 0);
+		ier = I915_READ(VLV_IER);
+		I915_WRITE(VLV_IER, 0);
+
+		gen8_gt_irq_ack(dev_priv, master_ctl, gt_iir);
+
+		if (iir & I915_DISPLAY_PORT_INTERRUPT)
+			hotplug_status = i9xx_hpd_irq_ack(dev_priv);
+
+		/* Call regardless, as some status bits might not be
+		 * signalled in iir */
+		valleyview_pipestat_irq_ack(dev, iir, pipe_stats);
+
+		/*
+		 * VLV_IIR is single buffered, and reflects the level
+		 * from PIPESTAT/PORT_HOTPLUG_STAT, hence clear it last.
+		 */
+		if (iir)
+			I915_WRITE(VLV_IIR, iir);
+
+		I915_WRITE(VLV_IER, ier);
+		I915_WRITE(GEN8_MASTER_IRQ, GEN8_MASTER_IRQ_CONTROL);
+		POSTING_READ(GEN8_MASTER_IRQ);
+
+		gen8_gt_irq_handler(dev_priv, gt_iir);
+
+		if (hotplug_status)
+			i9xx_hpd_irq_handler(dev, hotplug_status);
+
+		valleyview_pipestat_irq_handler(dev, pipe_stats);
+	} while (0);
+
+	enable_rpm_wakeref_asserts(dev_priv);
+
+	return ret;
+}
+
+static void ibx_hpd_irq_handler(struct drm_device *dev, u32 hotplug_trigger,
+				const u32 hpd[HPD_NUM_PINS])
+{
+	struct drm_i915_private *dev_priv = to_i915(dev);
+	u32 dig_hotplug_reg, pin_mask = 0, long_mask = 0;
+
+	/*
+	 * Somehow the PCH doesn't seem to really ack the interrupt to the CPU
+	 * unless we touch the hotplug register, even if hotplug_trigger is
+	 * zero. Not acking leads to "The master control interrupt lied (SDE)!"
+	 * errors.
+	 */
+	dig_hotplug_reg = I915_READ(PCH_PORT_HOTPLUG);
+	if (!hotplug_trigger) {
+		u32 mask = PORTA_HOTPLUG_STATUS_MASK |
+			PORTD_HOTPLUG_STATUS_MASK |
+			PORTC_HOTPLUG_STATUS_MASK |
+			PORTB_HOTPLUG_STATUS_MASK;
+		dig_hotplug_reg &= ~mask;
+	}
+
+	I915_WRITE(PCH_PORT_HOTPLUG, dig_hotplug_reg);
+	if (!hotplug_trigger)
+		return;
+
+	intel_get_hpd_pins(&pin_mask, &long_mask, hotplug_trigger,
+			   dig_hotplug_reg, hpd,
+			   pch_port_hotplug_long_detect);
+
+	intel_hpd_irq_handler(dev, pin_mask, long_mask);
+}
+
+static void ibx_irq_handler(struct drm_device *dev, u32 pch_iir)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	int pipe;
+	u32 hotplug_trigger = pch_iir & SDE_HOTPLUG_MASK;
+
+	ibx_hpd_irq_handler(dev, hotplug_trigger, hpd_ibx);
+
+	if (pch_iir & SDE_AUDIO_POWER_MASK) {
+		int port = ffs((pch_iir & SDE_AUDIO_POWER_MASK) >>
+			       SDE_AUDIO_POWER_SHIFT);
+		DRM_DEBUG_DRIVER("PCH audio power change on port %d\n",
+				 port_name(port));
+	}
+
+	if (pch_iir & SDE_AUX_MASK)
+		dp_aux_irq_handler(dev);
+
+	if (pch_iir & SDE_GMBUS)
+		gmbus_irq_handler(dev);
+
+	if (pch_iir & SDE_AUDIO_HDCP_MASK)
+		DRM_DEBUG_DRIVER("PCH HDCP audio interrupt\n");
+
+	if (pch_iir & SDE_AUDIO_TRANS_MASK)
+		DRM_DEBUG_DRIVER("PCH transcoder audio interrupt\n");
+
+	if (pch_iir & SDE_POISON)
+		DRM_ERROR("PCH poison interrupt\n");
+
+	if (pch_iir & SDE_FDI_MASK)
+		for_each_pipe(dev_priv, pipe)
+			DRM_DEBUG_DRIVER("  pipe %c FDI IIR: 0x%08x\n",
+					 pipe_name(pipe),
+					 I915_READ(FDI_RX_IIR(pipe)));
+
+	if (pch_iir & (SDE_TRANSB_CRC_DONE | SDE_TRANSA_CRC_DONE))
+		DRM_DEBUG_DRIVER("PCH transcoder CRC done interrupt\n");
+
+	if (pch_iir & (SDE_TRANSB_CRC_ERR | SDE_TRANSA_CRC_ERR))
+		DRM_DEBUG_DRIVER("PCH transcoder CRC error interrupt\n");
+
+	if (pch_iir & SDE_TRANSA_FIFO_UNDER)
+		intel_pch_fifo_underrun_irq_handler(dev_priv, TRANSCODER_A);
+
+	if (pch_iir & SDE_TRANSB_FIFO_UNDER)
+		intel_pch_fifo_underrun_irq_handler(dev_priv, TRANSCODER_B);
+}
+
+static void ivb_err_int_handler(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	u32 err_int = I915_READ(GEN7_ERR_INT);
+	enum pipe pipe;
+
+	if (err_int & ERR_INT_POISON)
+		DRM_ERROR("Poison interrupt\n");
+
+	for_each_pipe(dev_priv, pipe) {
+		if (err_int & ERR_INT_FIFO_UNDERRUN(pipe))
+			intel_cpu_fifo_underrun_irq_handler(dev_priv, pipe);
+
+		if (err_int & ERR_INT_PIPE_CRC_DONE(pipe)) {
+			if (IS_IVYBRIDGE(dev))
+				ivb_pipe_crc_irq_handler(dev, pipe);
+			else
+				hsw_pipe_crc_irq_handler(dev, pipe);
+		}
+	}
+
+	I915_WRITE(GEN7_ERR_INT, err_int);
+}
+
+static void cpt_serr_int_handler(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	u32 serr_int = I915_READ(SERR_INT);
+
+	if (serr_int & SERR_INT_POISON)
+		DRM_ERROR("PCH poison interrupt\n");
+
+	if (serr_int & SERR_INT_TRANS_A_FIFO_UNDERRUN)
+		intel_pch_fifo_underrun_irq_handler(dev_priv, TRANSCODER_A);
+
+	if (serr_int & SERR_INT_TRANS_B_FIFO_UNDERRUN)
+		intel_pch_fifo_underrun_irq_handler(dev_priv, TRANSCODER_B);
+
+	if (serr_int & SERR_INT_TRANS_C_FIFO_UNDERRUN)
+		intel_pch_fifo_underrun_irq_handler(dev_priv, TRANSCODER_C);
+
+	I915_WRITE(SERR_INT, serr_int);
+}
+
+static void cpt_irq_handler(struct drm_device *dev, u32 pch_iir)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	int pipe;
+	u32 hotplug_trigger = pch_iir & SDE_HOTPLUG_MASK_CPT;
+
+	ibx_hpd_irq_handler(dev, hotplug_trigger, hpd_cpt);
+
+	if (pch_iir & SDE_AUDIO_POWER_MASK_CPT) {
+		int port = ffs((pch_iir & SDE_AUDIO_POWER_MASK_CPT) >>
+			       SDE_AUDIO_POWER_SHIFT_CPT);
+		DRM_DEBUG_DRIVER("PCH audio power change on port %c\n",
+				 port_name(port));
+	}
+
+	if (pch_iir & SDE_AUX_MASK_CPT)
+		dp_aux_irq_handler(dev);
+
+	if (pch_iir & SDE_GMBUS_CPT)
+		gmbus_irq_handler(dev);
+
+	if (pch_iir & SDE_AUDIO_CP_REQ_CPT)
+		DRM_DEBUG_DRIVER("Audio CP request interrupt\n");
+
+	if (pch_iir & SDE_AUDIO_CP_CHG_CPT)
+		DRM_DEBUG_DRIVER("Audio CP change interrupt\n");
+
+	if (pch_iir & SDE_FDI_MASK_CPT)
+		for_each_pipe(dev_priv, pipe)
+			DRM_DEBUG_DRIVER("  pipe %c FDI IIR: 0x%08x\n",
+					 pipe_name(pipe),
+					 I915_READ(FDI_RX_IIR(pipe)));
+
+	if (pch_iir & SDE_ERROR_CPT)
+		cpt_serr_int_handler(dev);
+}
+
+static void spt_irq_handler(struct drm_device *dev, u32 pch_iir)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	u32 hotplug_trigger = pch_iir & SDE_HOTPLUG_MASK_SPT &
+		~SDE_PORTE_HOTPLUG_SPT;
+	u32 hotplug2_trigger = pch_iir & SDE_PORTE_HOTPLUG_SPT;
+	u32 pin_mask = 0, long_mask = 0;
+
+	if (hotplug_trigger) {
+		u32 dig_hotplug_reg;
+
+		dig_hotplug_reg = I915_READ(PCH_PORT_HOTPLUG);
+		I915_WRITE(PCH_PORT_HOTPLUG, dig_hotplug_reg);
+
+		intel_get_hpd_pins(&pin_mask, &long_mask, hotplug_trigger,
+				   dig_hotplug_reg, hpd_spt,
+				   spt_port_hotplug_long_detect);
+	}
+
+	if (hotplug2_trigger) {
+		u32 dig_hotplug_reg;
+
+		dig_hotplug_reg = I915_READ(PCH_PORT_HOTPLUG2);
+		I915_WRITE(PCH_PORT_HOTPLUG2, dig_hotplug_reg);
+
+		intel_get_hpd_pins(&pin_mask, &long_mask, hotplug2_trigger,
+				   dig_hotplug_reg, hpd_spt,
+				   spt_port_hotplug2_long_detect);
+	}
+
+	if (pin_mask)
+		intel_hpd_irq_handler(dev, pin_mask, long_mask);
+
+	if (pch_iir & SDE_GMBUS_CPT)
+		gmbus_irq_handler(dev);
+}
+
+static void ilk_hpd_irq_handler(struct drm_device *dev, u32 hotplug_trigger,
+				const u32 hpd[HPD_NUM_PINS])
+{
+	struct drm_i915_private *dev_priv = to_i915(dev);
+	u32 dig_hotplug_reg, pin_mask = 0, long_mask = 0;
+
+	dig_hotplug_reg = I915_READ(DIGITAL_PORT_HOTPLUG_CNTRL);
+	I915_WRITE(DIGITAL_PORT_HOTPLUG_CNTRL, dig_hotplug_reg);
+
+	intel_get_hpd_pins(&pin_mask, &long_mask, hotplug_trigger,
+			   dig_hotplug_reg, hpd,
+			   ilk_port_hotplug_long_detect);
+
+	intel_hpd_irq_handler(dev, pin_mask, long_mask);
+}
+
+static void ilk_display_irq_handler(struct drm_device *dev, u32 de_iir)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	enum pipe pipe;
+	u32 hotplug_trigger = de_iir & DE_DP_A_HOTPLUG;
+
+	if (hotplug_trigger)
+		ilk_hpd_irq_handler(dev, hotplug_trigger, hpd_ilk);
+
+	if (de_iir & DE_AUX_CHANNEL_A)
+		dp_aux_irq_handler(dev);
+
+	if (de_iir & DE_GSE)
+		intel_opregion_asle_intr(dev);
+
+	if (de_iir & DE_POISON)
+		DRM_ERROR("Poison interrupt\n");
+
+	for_each_pipe(dev_priv, pipe) {
+		if (de_iir & DE_PIPE_VBLANK(pipe) &&
+		    intel_pipe_handle_vblank(dev, pipe))
+			intel_check_page_flip(dev, pipe);
+
+		if (de_iir & DE_PIPE_FIFO_UNDERRUN(pipe))
+			intel_cpu_fifo_underrun_irq_handler(dev_priv, pipe);
+
+		if (de_iir & DE_PIPE_CRC_DONE(pipe))
+			i9xx_pipe_crc_irq_handler(dev, pipe);
+
+		/* plane/pipes map 1:1 on ilk+ */
+		if (de_iir & DE_PLANE_FLIP_DONE(pipe)) {
+			intel_prepare_page_flip(dev, pipe);
+			intel_finish_page_flip_plane(dev, pipe);
+		}
+	}
+
+	/* check event from PCH */
+	if (de_iir & DE_PCH_EVENT) {
+		u32 pch_iir = I915_READ(SDEIIR);
+
+		if (HAS_PCH_CPT(dev))
+			cpt_irq_handler(dev, pch_iir);
+		else
+			ibx_irq_handler(dev, pch_iir);
+
+		/* should clear PCH hotplug event before clear CPU irq */
+		I915_WRITE(SDEIIR, pch_iir);
+	}
+
+	if (IS_GEN5(dev) && de_iir & DE_PCU_EVENT)
+		ironlake_rps_change_irq_handler(dev);
+}
+
+static void ivb_display_irq_handler(struct drm_device *dev, u32 de_iir)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	enum pipe pipe;
+	u32 hotplug_trigger = de_iir & DE_DP_A_HOTPLUG_IVB;
+
+	if (hotplug_trigger)
+		ilk_hpd_irq_handler(dev, hotplug_trigger, hpd_ivb);
+
+	if (de_iir & DE_ERR_INT_IVB)
+		ivb_err_int_handler(dev);
+
+	if (de_iir & DE_AUX_CHANNEL_A_IVB)
+		dp_aux_irq_handler(dev);
+
+	if (de_iir & DE_GSE_IVB)
+		intel_opregion_asle_intr(dev);
+
+	for_each_pipe(dev_priv, pipe) {
+		if (de_iir & (DE_PIPE_VBLANK_IVB(pipe)) &&
+		    intel_pipe_handle_vblank(dev, pipe))
+			intel_check_page_flip(dev, pipe);
+
+		/* plane/pipes map 1:1 on ilk+ */
+		if (de_iir & DE_PLANE_FLIP_DONE_IVB(pipe)) {
+			intel_prepare_page_flip(dev, pipe);
+			intel_finish_page_flip_plane(dev, pipe);
+		}
+	}
+
+	/* check event from PCH */
+	if (!HAS_PCH_NOP(dev) && (de_iir & DE_PCH_EVENT_IVB)) {
+		u32 pch_iir = I915_READ(SDEIIR);
+
+		cpt_irq_handler(dev, pch_iir);
+
+		/* clear PCH hotplug event before clear CPU irq */
+		I915_WRITE(SDEIIR, pch_iir);
+	}
+}
+
+/*
+ * To handle irqs with the minimum potential races with fresh interrupts, we:
+ * 1 - Disable Master Interrupt Control.
+ * 2 - Find the source(s) of the interrupt.
+ * 3 - Clear the Interrupt Identity bits (IIR).
+ * 4 - Process the interrupt(s) that had bits set in the IIRs.
+ * 5 - Re-enable Master Interrupt Control.
+ */
+static irqreturn_t ironlake_irq_handler(int irq, void *arg)
+{
+	struct drm_device *dev = arg;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	u32 de_iir, gt_iir, de_ier, sde_ier = 0;
+	irqreturn_t ret = IRQ_NONE;
+
+	if (!intel_irqs_enabled(dev_priv))
+		return IRQ_NONE;
+
+	/* IRQs are synced during runtime_suspend, we don't require a wakeref */
+	disable_rpm_wakeref_asserts(dev_priv);
+
+	/* disable master interrupt before clearing iir  */
+	de_ier = I915_READ(DEIER);
+	I915_WRITE(DEIER, de_ier & ~DE_MASTER_IRQ_CONTROL);
+	POSTING_READ(DEIER);
+
+	/* Disable south interrupts. We'll only write to SDEIIR once, so further
+	 * interrupts will will be stored on its back queue, and then we'll be
+	 * able to process them after we restore SDEIER (as soon as we restore
+	 * it, we'll get an interrupt if SDEIIR still has something to process
+	 * due to its back queue). */
+	if (!HAS_PCH_NOP(dev)) {
+		sde_ier = I915_READ(SDEIER);
+		I915_WRITE(SDEIER, 0);
+		POSTING_READ(SDEIER);
+	}
+
+	/* Find, clear, then process each source of interrupt */
+
+	gt_iir = I915_READ(GTIIR);
+	if (gt_iir) {
+		I915_WRITE(GTIIR, gt_iir);
+		ret = IRQ_HANDLED;
+		if (INTEL_INFO(dev)->gen >= 6)
+			snb_gt_irq_handler(dev_priv, gt_iir);
+		else
+			ilk_gt_irq_handler(dev_priv, gt_iir);
+	}
+
+	de_iir = I915_READ(DEIIR);
+	if (de_iir) {
+		I915_WRITE(DEIIR, de_iir);
+		ret = IRQ_HANDLED;
+		if (INTEL_INFO(dev)->gen >= 7)
+			ivb_display_irq_handler(dev, de_iir);
+		else
+			ilk_display_irq_handler(dev, de_iir);
+	}
+
+	if (INTEL_INFO(dev)->gen >= 6) {
+		u32 pm_iir = I915_READ(GEN6_PMIIR);
+		if (pm_iir) {
+			I915_WRITE(GEN6_PMIIR, pm_iir);
+			ret = IRQ_HANDLED;
+			gen6_rps_irq_handler(dev_priv, pm_iir);
+		}
+	}
+
+	I915_WRITE(DEIER, de_ier);
+	POSTING_READ(DEIER);
+	if (!HAS_PCH_NOP(dev)) {
+		I915_WRITE(SDEIER, sde_ier);
+		POSTING_READ(SDEIER);
+	}
+
+	/* IRQs are synced during runtime_suspend, we don't require a wakeref */
+	enable_rpm_wakeref_asserts(dev_priv);
+
+	return ret;
+}
+
+static void bxt_hpd_irq_handler(struct drm_device *dev, u32 hotplug_trigger,
+				const u32 hpd[HPD_NUM_PINS])
+{
+	struct drm_i915_private *dev_priv = to_i915(dev);
+	u32 dig_hotplug_reg, pin_mask = 0, long_mask = 0;
+
+	dig_hotplug_reg = I915_READ(PCH_PORT_HOTPLUG);
+	I915_WRITE(PCH_PORT_HOTPLUG, dig_hotplug_reg);
+
+	intel_get_hpd_pins(&pin_mask, &long_mask, hotplug_trigger,
+			   dig_hotplug_reg, hpd,
+			   bxt_port_hotplug_long_detect);
+
+	intel_hpd_irq_handler(dev, pin_mask, long_mask);
+}
+
+static irqreturn_t
+gen8_de_irq_handler(struct drm_i915_private *dev_priv, u32 master_ctl)
+{
+	struct drm_device *dev = dev_priv->dev;
+	irqreturn_t ret = IRQ_NONE;
+	u32 iir;
+	enum pipe pipe;
+
+	if (master_ctl & GEN8_DE_MISC_IRQ) {
+		iir = I915_READ(GEN8_DE_MISC_IIR);
+		if (iir) {
+			I915_WRITE(GEN8_DE_MISC_IIR, iir);
+			ret = IRQ_HANDLED;
+			if (iir & GEN8_DE_MISC_GSE)
+				intel_opregion_asle_intr(dev);
+			else
+				DRM_ERROR("Unexpected DE Misc interrupt\n");
+		}
+		else
+			DRM_ERROR("The master control interrupt lied (DE MISC)!\n");
+	}
+
+	if (master_ctl & GEN8_DE_PORT_IRQ) {
+		iir = I915_READ(GEN8_DE_PORT_IIR);
+		if (iir) {
+			u32 tmp_mask;
+			bool found = false;
+
+			I915_WRITE(GEN8_DE_PORT_IIR, iir);
+			ret = IRQ_HANDLED;
+
+			tmp_mask = GEN8_AUX_CHANNEL_A;
+			if (INTEL_INFO(dev_priv)->gen >= 9)
+				tmp_mask |= GEN9_AUX_CHANNEL_B |
+					    GEN9_AUX_CHANNEL_C |
+					    GEN9_AUX_CHANNEL_D;
+
+			if (iir & tmp_mask) {
+				dp_aux_irq_handler(dev);
+				found = true;
+			}
+
+			if (IS_BROXTON(dev_priv)) {
+				tmp_mask = iir & BXT_DE_PORT_HOTPLUG_MASK;
+				if (tmp_mask) {
+					bxt_hpd_irq_handler(dev, tmp_mask, hpd_bxt);
+					found = true;
+				}
+			} else if (IS_BROADWELL(dev_priv)) {
+				tmp_mask = iir & GEN8_PORT_DP_A_HOTPLUG;
+				if (tmp_mask) {
+					ilk_hpd_irq_handler(dev, tmp_mask, hpd_bdw);
+					found = true;
+				}
+			}
+
+			if (IS_BROXTON(dev) && (iir & BXT_DE_PORT_GMBUS)) {
+				gmbus_irq_handler(dev);
+				found = true;
+			}
+
+			if (!found)
+				DRM_ERROR("Unexpected DE Port interrupt\n");
+		}
+		else
+			DRM_ERROR("The master control interrupt lied (DE PORT)!\n");
+	}
+
+	for_each_pipe(dev_priv, pipe) {
+		u32 flip_done, fault_errors;
+
+		if (!(master_ctl & GEN8_DE_PIPE_IRQ(pipe)))
+			continue;
+
+		iir = I915_READ(GEN8_DE_PIPE_IIR(pipe));
+		if (!iir) {
+			DRM_ERROR("The master control interrupt lied (DE PIPE)!\n");
+			continue;
+		}
+
+		ret = IRQ_HANDLED;
+		I915_WRITE(GEN8_DE_PIPE_IIR(pipe), iir);
+
+		if (iir & GEN8_PIPE_VBLANK &&
+		    intel_pipe_handle_vblank(dev, pipe))
+			intel_check_page_flip(dev, pipe);
+
+		flip_done = iir;
+		if (INTEL_INFO(dev_priv)->gen >= 9)
+			flip_done &= GEN9_PIPE_PLANE1_FLIP_DONE;
+		else
+			flip_done &= GEN8_PIPE_PRIMARY_FLIP_DONE;
+
+		if (flip_done) {
+			intel_prepare_page_flip(dev, pipe);
+			intel_finish_page_flip_plane(dev, pipe);
+		}
+
+		if (iir & GEN8_PIPE_CDCLK_CRC_DONE)
+			hsw_pipe_crc_irq_handler(dev, pipe);
+
+		if (iir & GEN8_PIPE_FIFO_UNDERRUN)
+			intel_cpu_fifo_underrun_irq_handler(dev_priv, pipe);
+
+		fault_errors = iir;
+		if (INTEL_INFO(dev_priv)->gen >= 9)
+			fault_errors &= GEN9_DE_PIPE_IRQ_FAULT_ERRORS;
+		else
+			fault_errors &= GEN8_DE_PIPE_IRQ_FAULT_ERRORS;
+
+		if (fault_errors)
+			DRM_ERROR("Fault errors on pipe %c\n: 0x%08x",
+				  pipe_name(pipe),
+				  fault_errors);
+	}
+
+	if (HAS_PCH_SPLIT(dev) && !HAS_PCH_NOP(dev) &&
+	    master_ctl & GEN8_DE_PCH_IRQ) {
+		/*
+		 * FIXME(BDW): Assume for now that the new interrupt handling
+		 * scheme also closed the SDE interrupt handling race we've seen
+		 * on older pch-split platforms. But this needs testing.
+		 */
+		iir = I915_READ(SDEIIR);
+		if (iir) {
+			I915_WRITE(SDEIIR, iir);
+			ret = IRQ_HANDLED;
+
+			if (HAS_PCH_SPT(dev_priv) || HAS_PCH_KBP(dev_priv))
+				spt_irq_handler(dev, iir);
+			else
+				cpt_irq_handler(dev, iir);
+		} else {
+			/*
+			 * Like on previous PCH there seems to be something
+			 * fishy going on with forwarding PCH interrupts.
+			 */
+			DRM_DEBUG_DRIVER("The master control interrupt lied (SDE)!\n");
+		}
+	}
+
+	return ret;
+}
+
+static irqreturn_t gen8_irq_handler(int irq, void *arg)
+{
+	struct drm_device *dev = arg;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	u32 master_ctl;
+	u32 gt_iir[4] = {};
+	irqreturn_t ret;
+
+	if (!intel_irqs_enabled(dev_priv))
+		return IRQ_NONE;
+
+	master_ctl = I915_READ_FW(GEN8_MASTER_IRQ);
+	master_ctl &= ~GEN8_MASTER_IRQ_CONTROL;
+	if (!master_ctl)
+		return IRQ_NONE;
+
+	I915_WRITE_FW(GEN8_MASTER_IRQ, 0);
+
+	/* IRQs are synced during runtime_suspend, we don't require a wakeref */
+	disable_rpm_wakeref_asserts(dev_priv);
+
+	/* Find, clear, then process each source of interrupt */
+	ret = gen8_gt_irq_ack(dev_priv, master_ctl, gt_iir);
+	gen8_gt_irq_handler(dev_priv, gt_iir);
+	ret |= gen8_de_irq_handler(dev_priv, master_ctl);
+
+	I915_WRITE_FW(GEN8_MASTER_IRQ, GEN8_MASTER_IRQ_CONTROL);
+	POSTING_READ_FW(GEN8_MASTER_IRQ);
+
+	enable_rpm_wakeref_asserts(dev_priv);
+
+	return ret;
+}
+
+static void i915_error_wake_up(struct drm_i915_private *dev_priv,
+			       bool reset_completed)
+{
+	struct intel_engine_cs *engine;
+
+	/*
+	 * Notify all waiters for GPU completion events that reset state has
+	 * been changed, and that they need to restart their wait after
+	 * checking for potential errors (and bail out to drop locks if there is
+	 * a gpu reset pending so that i915_error_work_func can acquire them).
+	 */
+
+	/* Wake up __wait_seqno, potentially holding dev->struct_mutex. */
+	for_each_engine(engine, dev_priv)
+		wake_up_all(&engine->irq_queue);
+
+	/* Wake up intel_crtc_wait_for_pending_flips, holding crtc->mutex. */
+	wake_up_all(&dev_priv->pending_flip_queue);
+
+	/*
+	 * Signal tasks blocked in i915_gem_wait_for_error that the pending
+	 * reset state is cleared.
+	 */
+	if (reset_completed)
+		wake_up_all(&dev_priv->gpu_error.reset_queue);
+}
+
+/**
+ * i915_reset_and_wakeup - do process context error handling work
+ * @dev: drm device
+ *
+ * Fire an error uevent so userspace can see that a hang or error
+ * was detected.
+ */
+static void i915_reset_and_wakeup(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = to_i915(dev);
+	char *error_event[] = { I915_ERROR_UEVENT "=1", NULL };
+	char *reset_event[] = { I915_RESET_UEVENT "=1", NULL };
+	char *reset_done_event[] = { I915_ERROR_UEVENT "=0", NULL };
+	int ret;
+
+	kobject_uevent_env(&dev->primary->kdev->kobj, KOBJ_CHANGE, error_event);
+
+	/*
+	 * Note that there's only one work item which does gpu resets, so we
+	 * need not worry about concurrent gpu resets potentially incrementing
+	 * error->reset_counter twice. We only need to take care of another
+	 * racing irq/hangcheck declaring the gpu dead for a second time. A
+	 * quick check for that is good enough: schedule_work ensures the
+	 * correct ordering between hang detection and this work item, and since
+	 * the reset in-progress bit is only ever set by code outside of this
+	 * work we don't need to worry about any other races.
+	 */
+	if (i915_reset_in_progress(&dev_priv->gpu_error)) {
+		DRM_DEBUG_DRIVER("resetting chip\n");
+		kobject_uevent_env(&dev->primary->kdev->kobj, KOBJ_CHANGE,
+				   reset_event);
+
+		/*
+		 * In most cases it's guaranteed that we get here with an RPM
+		 * reference held, for example because there is a pending GPU
+		 * request that won't finish until the reset is done. This
+		 * isn't the case at least when we get here by doing a
+		 * simulated reset via debugs, so get an RPM reference.
+		 */
+		intel_runtime_pm_get(dev_priv);
+
+		intel_prepare_reset(dev);
+
+		/*
+		 * All state reset _must_ be completed before we update the
+		 * reset counter, for otherwise waiters might miss the reset
+		 * pending state and not properly drop locks, resulting in
+		 * deadlocks with the reset work.
+		 */
+		ret = i915_reset(dev);
+
+		intel_finish_reset(dev);
+
+		intel_runtime_pm_put(dev_priv);
+
+		if (ret == 0)
+			kobject_uevent_env(&dev->primary->kdev->kobj,
+					   KOBJ_CHANGE, reset_done_event);
+
+		/*
+		 * Note: The wake_up also serves as a memory barrier so that
+		 * waiters see the update value of the reset counter atomic_t.
+		 */
+		i915_error_wake_up(dev_priv, true);
+	}
+}
+
+static void i915_report_and_clear_eir(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	uint32_t instdone[I915_NUM_INSTDONE_REG];
+	u32 eir = I915_READ(EIR);
+	int pipe, i;
+
+	if (!eir)
+		return;
+
+	pr_err("render error detected, EIR: 0x%08x\n", eir);
+
+	i915_get_extra_instdone(dev, instdone);
+
+	if (IS_G4X(dev)) {
+		if (eir & (GM45_ERROR_MEM_PRIV | GM45_ERROR_CP_PRIV)) {
+			u32 ipeir = I915_READ(IPEIR_I965);
+
+			pr_err("  IPEIR: 0x%08x\n", I915_READ(IPEIR_I965));
+			pr_err("  IPEHR: 0x%08x\n", I915_READ(IPEHR_I965));
+			for (i = 0; i < ARRAY_SIZE(instdone); i++)
+				pr_err("  INSTDONE_%d: 0x%08x\n", i, instdone[i]);
+			pr_err("  INSTPS: 0x%08x\n", I915_READ(INSTPS));
+			pr_err("  ACTHD: 0x%08x\n", I915_READ(ACTHD_I965));
+			I915_WRITE(IPEIR_I965, ipeir);
+			POSTING_READ(IPEIR_I965);
+		}
+		if (eir & GM45_ERROR_PAGE_TABLE) {
+			u32 pgtbl_err = I915_READ(PGTBL_ER);
+			pr_err("page table error\n");
+			pr_err("  PGTBL_ER: 0x%08x\n", pgtbl_err);
+			I915_WRITE(PGTBL_ER, pgtbl_err);
+			POSTING_READ(PGTBL_ER);
+		}
+	}
+
+	if (!IS_GEN2(dev)) {
+		if (eir & I915_ERROR_PAGE_TABLE) {
+			u32 pgtbl_err = I915_READ(PGTBL_ER);
+			pr_err("page table error\n");
+			pr_err("  PGTBL_ER: 0x%08x\n", pgtbl_err);
+			I915_WRITE(PGTBL_ER, pgtbl_err);
+			POSTING_READ(PGTBL_ER);
+		}
+	}
+
+	if (eir & I915_ERROR_MEMORY_REFRESH) {
+		pr_err("memory refresh error:\n");
+		for_each_pipe(dev_priv, pipe)
+			pr_err("pipe %c stat: 0x%08x\n",
+			       pipe_name(pipe), I915_READ(PIPESTAT(pipe)));
+		/* pipestat has already been acked */
+	}
+	if (eir & I915_ERROR_INSTRUCTION) {
+		pr_err("instruction error\n");
+		pr_err("  INSTPM: 0x%08x\n", I915_READ(INSTPM));
+		for (i = 0; i < ARRAY_SIZE(instdone); i++)
+			pr_err("  INSTDONE_%d: 0x%08x\n", i, instdone[i]);
+		if (INTEL_INFO(dev)->gen < 4) {
+			u32 ipeir = I915_READ(IPEIR);
+
+			pr_err("  IPEIR: 0x%08x\n", I915_READ(IPEIR));
+			pr_err("  IPEHR: 0x%08x\n", I915_READ(IPEHR));
+			pr_err("  ACTHD: 0x%08x\n", I915_READ(ACTHD));
+			I915_WRITE(IPEIR, ipeir);
+			POSTING_READ(IPEIR);
+		} else {
+			u32 ipeir = I915_READ(IPEIR_I965);
+
+			pr_err("  IPEIR: 0x%08x\n", I915_READ(IPEIR_I965));
+			pr_err("  IPEHR: 0x%08x\n", I915_READ(IPEHR_I965));
+			pr_err("  INSTPS: 0x%08x\n", I915_READ(INSTPS));
+			pr_err("  ACTHD: 0x%08x\n", I915_READ(ACTHD_I965));
+			I915_WRITE(IPEIR_I965, ipeir);
+			POSTING_READ(IPEIR_I965);
+		}
+	}
+
+	I915_WRITE(EIR, eir);
+	POSTING_READ(EIR);
+	eir = I915_READ(EIR);
+	if (eir) {
+		/*
+		 * some errors might have become stuck,
+		 * mask them.
+		 */
+		DRM_ERROR("EIR stuck: 0x%08x, masking\n", eir);
+		I915_WRITE(EMR, I915_READ(EMR) | eir);
+		I915_WRITE(IIR, I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT);
+	}
+}
+
+/**
+ * i915_handle_error - handle a gpu error
+ * @dev: drm device
+ * @engine_mask: mask representing engines that are hung
+ * Do some basic checking of register state at error time and
+ * dump it to the syslog.  Also call i915_capture_error_state() to make
+ * sure we get a record and make it available in debugfs.  Fire a uevent
+ * so userspace knows something bad happened (should trigger collection
+ * of a ring dump etc.).
+ */
+void i915_handle_error(struct drm_device *dev, u32 engine_mask,
+		       const char *fmt, ...)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	va_list args;
+	char error_msg[80];
+
+	va_start(args, fmt);
+	vscnprintf(error_msg, sizeof(error_msg), fmt, args);
+	va_end(args);
+
+	i915_capture_error_state(dev, engine_mask, error_msg);
+	i915_report_and_clear_eir(dev);
+
+	if (engine_mask) {
+		atomic_or(I915_RESET_IN_PROGRESS_FLAG,
+				&dev_priv->gpu_error.reset_counter);
+
+		/*
+		 * Wakeup waiting processes so that the reset function
+		 * i915_reset_and_wakeup doesn't deadlock trying to grab
+		 * various locks. By bumping the reset counter first, the woken
+		 * processes will see a reset in progress and back off,
+		 * releasing their locks and then wait for the reset completion.
+		 * We must do this for _all_ gpu waiters that might hold locks
+		 * that the reset work needs to acquire.
+		 *
+		 * Note: The wake_up serves as the required memory barrier to
+		 * ensure that the waiters see the updated value of the reset
+		 * counter atomic_t.
+		 */
+		i915_error_wake_up(dev_priv, false);
+	}
+
+	i915_reset_and_wakeup(dev);
+}
+
+/* Called from drm generic code, passed 'crtc' which
+ * we use as a pipe index
+ */
+static int i915_enable_vblank(struct drm_device *dev, unsigned int pipe)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	unsigned long irqflags;
+
+	spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
+	if (INTEL_INFO(dev)->gen >= 4)
+		i915_enable_pipestat(dev_priv, pipe,
+				     PIPE_START_VBLANK_INTERRUPT_STATUS);
+	else
+		i915_enable_pipestat(dev_priv, pipe,
+				     PIPE_VBLANK_INTERRUPT_STATUS);
+	spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
+
+	return 0;
+}
+
+static int ironlake_enable_vblank(struct drm_device *dev, unsigned int pipe)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	unsigned long irqflags;
+	uint32_t bit = (INTEL_INFO(dev)->gen >= 7) ? DE_PIPE_VBLANK_IVB(pipe) :
+						     DE_PIPE_VBLANK(pipe);
+
+	spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
+	ilk_enable_display_irq(dev_priv, bit);
+	spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
+
+	return 0;
+}
+
+static int valleyview_enable_vblank(struct drm_device *dev, unsigned int pipe)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	unsigned long irqflags;
+
+	spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
+	i915_enable_pipestat(dev_priv, pipe,
+			     PIPE_START_VBLANK_INTERRUPT_STATUS);
+	spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
+
+	return 0;
+}
+
+static int gen8_enable_vblank(struct drm_device *dev, unsigned int pipe)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	unsigned long irqflags;
+
+	spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
+	bdw_enable_pipe_irq(dev_priv, pipe, GEN8_PIPE_VBLANK);
+	spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
+
+	return 0;
+}
+
+/* Called from drm generic code, passed 'crtc' which
+ * we use as a pipe index
+ */
+static void i915_disable_vblank(struct drm_device *dev, unsigned int pipe)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	unsigned long irqflags;
+
+	spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
+	i915_disable_pipestat(dev_priv, pipe,
+			      PIPE_VBLANK_INTERRUPT_STATUS |
+			      PIPE_START_VBLANK_INTERRUPT_STATUS);
+	spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
+}
+
+static void ironlake_disable_vblank(struct drm_device *dev, unsigned int pipe)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	unsigned long irqflags;
+	uint32_t bit = (INTEL_INFO(dev)->gen >= 7) ? DE_PIPE_VBLANK_IVB(pipe) :
+						     DE_PIPE_VBLANK(pipe);
+
+	spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
+	ilk_disable_display_irq(dev_priv, bit);
+	spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
+}
+
+static void valleyview_disable_vblank(struct drm_device *dev, unsigned int pipe)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	unsigned long irqflags;
+
+	spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
+	i915_disable_pipestat(dev_priv, pipe,
+			      PIPE_START_VBLANK_INTERRUPT_STATUS);
+	spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
+}
+
+static void gen8_disable_vblank(struct drm_device *dev, unsigned int pipe)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	unsigned long irqflags;
+
+	spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
+	bdw_disable_pipe_irq(dev_priv, pipe, GEN8_PIPE_VBLANK);
+	spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
+}
+
+static bool
+ring_idle(struct intel_engine_cs *engine, u32 seqno)
+{
+	return i915_seqno_passed(seqno,
+				 READ_ONCE(engine->last_submitted_seqno));
+}
+
+static bool
+ipehr_is_semaphore_wait(struct drm_device *dev, u32 ipehr)
+{
+	if (INTEL_INFO(dev)->gen >= 8) {
+		return (ipehr >> 23) == 0x1c;
+	} else {
+		ipehr &= ~MI_SEMAPHORE_SYNC_MASK;
+		return ipehr == (MI_SEMAPHORE_MBOX | MI_SEMAPHORE_COMPARE |
+				 MI_SEMAPHORE_REGISTER);
+	}
+}
+
+static struct intel_engine_cs *
+semaphore_wait_to_signaller_ring(struct intel_engine_cs *engine, u32 ipehr,
+				 u64 offset)
+{
+	struct drm_i915_private *dev_priv = engine->dev->dev_private;
+	struct intel_engine_cs *signaller;
+
+	if (INTEL_INFO(dev_priv)->gen >= 8) {
+		for_each_engine(signaller, dev_priv) {
+			if (engine == signaller)
+				continue;
+
+			if (offset == signaller->semaphore.signal_ggtt[engine->id])
+				return signaller;
+		}
+	} else {
+		u32 sync_bits = ipehr & MI_SEMAPHORE_SYNC_MASK;
+
+		for_each_engine(signaller, dev_priv) {
+			if(engine == signaller)
+				continue;
+
+			if (sync_bits == signaller->semaphore.mbox.wait[engine->id])
+				return signaller;
+		}
+	}
+
+	DRM_ERROR("No signaller ring found for ring %i, ipehr 0x%08x, offset 0x%016llx\n",
+		  engine->id, ipehr, offset);
+
+	return NULL;
+}
+
+static struct intel_engine_cs *
+semaphore_waits_for(struct intel_engine_cs *engine, u32 *seqno)
+{
+	struct drm_i915_private *dev_priv = engine->dev->dev_private;
+	u32 cmd, ipehr, head;
+	u64 offset = 0;
+	int i, backwards;
+
+	/*
+	 * This function does not support execlist mode - any attempt to
+	 * proceed further into this function will result in a kernel panic
+	 * when dereferencing ring->buffer, which is not set up in execlist
+	 * mode.
+	 *
+	 * The correct way of doing it would be to derive the currently
+	 * executing ring buffer from the current context, which is derived
+	 * from the currently running request. Unfortunately, to get the
+	 * current request we would have to grab the struct_mutex before doing
+	 * anything else, which would be ill-advised since some other thread
+	 * might have grabbed it already and managed to hang itself, causing
+	 * the hang checker to deadlock.
+	 *
+	 * Therefore, this function does not support execlist mode in its
+	 * current form. Just return NULL and move on.
+	 */
+	if (engine->buffer == NULL)
+		return NULL;
+
+	ipehr = I915_READ(RING_IPEHR(engine->mmio_base));
+	if (!ipehr_is_semaphore_wait(engine->dev, ipehr))
+		return NULL;
+
+	/*
+	 * HEAD is likely pointing to the dword after the actual command,
+	 * so scan backwards until we find the MBOX. But limit it to just 3
+	 * or 4 dwords depending on the semaphore wait command size.
+	 * Note that we don't care about ACTHD here since that might
+	 * point at at batch, and semaphores are always emitted into the
+	 * ringbuffer itself.
+	 */
+	head = I915_READ_HEAD(engine) & HEAD_ADDR;
+	backwards = (INTEL_INFO(engine->dev)->gen >= 8) ? 5 : 4;
+
+	for (i = backwards; i; --i) {
+		/*
+		 * Be paranoid and presume the hw has gone off into the wild -
+		 * our ring is smaller than what the hardware (and hence
+		 * HEAD_ADDR) allows. Also handles wrap-around.
+		 */
+		head &= engine->buffer->size - 1;
+
+		/* This here seems to blow up */
+		cmd = ioread32(engine->buffer->virtual_start + head);
+		if (cmd == ipehr)
+			break;
+
+		head -= 4;
+	}
+
+	if (!i)
+		return NULL;
+
+	*seqno = ioread32(engine->buffer->virtual_start + head + 4) + 1;
+	if (INTEL_INFO(engine->dev)->gen >= 8) {
+		offset = ioread32(engine->buffer->virtual_start + head + 12);
+		offset <<= 32;
+		offset = ioread32(engine->buffer->virtual_start + head + 8);
+	}
+	return semaphore_wait_to_signaller_ring(engine, ipehr, offset);
+}
+
+static int semaphore_passed(struct intel_engine_cs *engine)
+{
+	struct drm_i915_private *dev_priv = engine->dev->dev_private;
+	struct intel_engine_cs *signaller;
+	u32 seqno;
+
+	engine->hangcheck.deadlock++;
+
+	signaller = semaphore_waits_for(engine, &seqno);
+	if (signaller == NULL)
+		return -1;
+
+	/* Prevent pathological recursion due to driver bugs */
+	if (signaller->hangcheck.deadlock >= I915_NUM_ENGINES)
+		return -1;
+
+	if (i915_seqno_passed(signaller->get_seqno(signaller), seqno))
+		return 1;
+
+	/* cursory check for an unkickable deadlock */
+	if (I915_READ_CTL(signaller) & RING_WAIT_SEMAPHORE &&
+	    semaphore_passed(signaller) < 0)
+		return -1;
+
+	return 0;
+}
+
+static void semaphore_clear_deadlocks(struct drm_i915_private *dev_priv)
+{
+	struct intel_engine_cs *engine;
+
+	for_each_engine(engine, dev_priv)
+		engine->hangcheck.deadlock = 0;
+}
+
+static bool subunits_stuck(struct intel_engine_cs *engine)
+{
+	u32 instdone[I915_NUM_INSTDONE_REG];
+	bool stuck;
+	int i;
+
+	if (engine->id != RCS)
+		return true;
+
+	i915_get_extra_instdone(engine->dev, instdone);
+
+	/* There might be unstable subunit states even when
+	 * actual head is not moving. Filter out the unstable ones by
+	 * accumulating the undone -> done transitions and only
+	 * consider those as progress.
+	 */
+	stuck = true;
+	for (i = 0; i < I915_NUM_INSTDONE_REG; i++) {
+		const u32 tmp = instdone[i] | engine->hangcheck.instdone[i];
+
+		if (tmp != engine->hangcheck.instdone[i])
+			stuck = false;
+
+		engine->hangcheck.instdone[i] |= tmp;
+	}
+
+	return stuck;
+}
+
+static enum intel_ring_hangcheck_action
+head_stuck(struct intel_engine_cs *engine, u64 acthd)
+{
+	if (acthd != engine->hangcheck.acthd) {
+
+		/* Clear subunit states on head movement */
+		memset(engine->hangcheck.instdone, 0,
+		       sizeof(engine->hangcheck.instdone));
+
+		return HANGCHECK_ACTIVE;
+	}
+
+	if (!subunits_stuck(engine))
+		return HANGCHECK_ACTIVE;
+
+	return HANGCHECK_HUNG;
+}
+
+static enum intel_ring_hangcheck_action
+ring_stuck(struct intel_engine_cs *engine, u64 acthd)
+{
+	struct drm_device *dev = engine->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	enum intel_ring_hangcheck_action ha;
+	u32 tmp;
+
+	ha = head_stuck(engine, acthd);
+	if (ha != HANGCHECK_HUNG)
+		return ha;
+
+	if (IS_GEN2(dev))
+		return HANGCHECK_HUNG;
+
+	/* Is the chip hanging on a WAIT_FOR_EVENT?
+	 * If so we can simply poke the RB_WAIT bit
+	 * and break the hang. This should work on
+	 * all but the second generation chipsets.
+	 */
+	tmp = I915_READ_CTL(engine);
+	if (tmp & RING_WAIT) {
+		i915_handle_error(dev, 0,
+				  "Kicking stuck wait on %s",
+				  engine->name);
+		I915_WRITE_CTL(engine, tmp);
+		return HANGCHECK_KICK;
+	}
+
+	if (INTEL_INFO(dev)->gen >= 6 && tmp & RING_WAIT_SEMAPHORE) {
+		switch (semaphore_passed(engine)) {
+		default:
+			return HANGCHECK_HUNG;
+		case 1:
+			i915_handle_error(dev, 0,
+					  "Kicking stuck semaphore on %s",
+					  engine->name);
+			I915_WRITE_CTL(engine, tmp);
+			return HANGCHECK_KICK;
+		case 0:
+			return HANGCHECK_WAIT;
+		}
+	}
+
+	return HANGCHECK_HUNG;
+}
+
+static unsigned kick_waiters(struct intel_engine_cs *engine)
+{
+	struct drm_i915_private *i915 = to_i915(engine->dev);
+	unsigned user_interrupts = READ_ONCE(engine->user_interrupts);
+
+	if (engine->hangcheck.user_interrupts == user_interrupts &&
+	    !test_and_set_bit(engine->id, &i915->gpu_error.missed_irq_rings)) {
+		if (!(i915->gpu_error.test_irq_rings & intel_engine_flag(engine)))
+			DRM_ERROR("Hangcheck timer elapsed... %s idle\n",
+				  engine->name);
+		else
+			DRM_INFO("Fake missed irq on %s\n",
+				 engine->name);
+		wake_up_all(&engine->irq_queue);
+	}
+
+	return user_interrupts;
+}
+/*
+ * This is called when the chip hasn't reported back with completed
+ * batchbuffers in a long time. We keep track per ring seqno progress and
+ * if there are no progress, hangcheck score for that ring is increased.
+ * Further, acthd is inspected to see if the ring is stuck. On stuck case
+ * we kick the ring. If we see no progress on three subsequent calls
+ * we assume chip is wedged and try to fix it by resetting the chip.
+ */
+static void i915_hangcheck_elapsed(struct work_struct *work)
+{
+	struct drm_i915_private *dev_priv =
+		container_of(work, typeof(*dev_priv),
+			     gpu_error.hangcheck_work.work);
+	struct drm_device *dev = dev_priv->dev;
+	struct intel_engine_cs *engine;
+	enum intel_engine_id id;
+	int busy_count = 0, rings_hung = 0;
+	bool stuck[I915_NUM_ENGINES] = { 0 };
+#define BUSY 1
+#define KICK 5
+#define HUNG 20
+#define ACTIVE_DECAY 15
+
+	if (!i915.enable_hangcheck)
+		return;
+
+	/*
+	 * The hangcheck work is synced during runtime suspend, we don't
+	 * require a wakeref. TODO: instead of disabling the asserts make
+	 * sure that we hold a reference when this work is running.
+	 */
+	DISABLE_RPM_WAKEREF_ASSERTS(dev_priv);
+
+	/* As enabling the GPU requires fairly extensive mmio access,
+	 * periodically arm the mmio checker to see if we are triggering
+	 * any invalid access.
+	 */
+	intel_uncore_arm_unclaimed_mmio_detection(dev_priv);
+
+	for_each_engine_id(engine, dev_priv, id) {
+		u64 acthd;
+		u32 seqno;
+		unsigned user_interrupts;
+		bool busy = true;
+
+		semaphore_clear_deadlocks(dev_priv);
+
+		/* We don't strictly need an irq-barrier here, as we are not
+		 * serving an interrupt request, be paranoid in case the
+		 * barrier has side-effects (such as preventing a broken
+		 * cacheline snoop) and so be sure that we can see the seqno
+		 * advance. If the seqno should stick, due to a stale
+		 * cacheline, we would erroneously declare the GPU hung.
+		 */
+		if (engine->irq_seqno_barrier)
+			engine->irq_seqno_barrier(engine);
+
+		acthd = intel_ring_get_active_head(engine);
+		seqno = engine->get_seqno(engine);
+
+		/* Reset stuck interrupts between batch advances */
+		user_interrupts = 0;
+
+		if (engine->hangcheck.seqno == seqno) {
+			if (ring_idle(engine, seqno)) {
+				engine->hangcheck.action = HANGCHECK_IDLE;
+				if (waitqueue_active(&engine->irq_queue)) {
+					/* Safeguard against driver failure */
+					user_interrupts = kick_waiters(engine);
+					engine->hangcheck.score += BUSY;
+				} else
+					busy = false;
+			} else {
+				/* We always increment the hangcheck score
+				 * if the ring is busy and still processing
+				 * the same request, so that no single request
+				 * can run indefinitely (such as a chain of
+				 * batches). The only time we do not increment
+				 * the hangcheck score on this ring, if this
+				 * ring is in a legitimate wait for another
+				 * ring. In that case the waiting ring is a
+				 * victim and we want to be sure we catch the
+				 * right culprit. Then every time we do kick
+				 * the ring, add a small increment to the
+				 * score so that we can catch a batch that is
+				 * being repeatedly kicked and so responsible
+				 * for stalling the machine.
+				 */
+				engine->hangcheck.action = ring_stuck(engine,
+								      acthd);
+
+				switch (engine->hangcheck.action) {
+				case HANGCHECK_IDLE:
+				case HANGCHECK_WAIT:
+					break;
+				case HANGCHECK_ACTIVE:
+					engine->hangcheck.score += BUSY;
+					break;
+				case HANGCHECK_KICK:
+					engine->hangcheck.score += KICK;
+					break;
+				case HANGCHECK_HUNG:
+					engine->hangcheck.score += HUNG;
+					stuck[id] = true;
+					break;
+				}
+			}
+		} else {
+			engine->hangcheck.action = HANGCHECK_ACTIVE;
+
+			/* Gradually reduce the count so that we catch DoS
+			 * attempts across multiple batches.
+			 */
+			if (engine->hangcheck.score > 0)
+				engine->hangcheck.score -= ACTIVE_DECAY;
+			if (engine->hangcheck.score < 0)
+				engine->hangcheck.score = 0;
+
+			/* Clear head and subunit states on seqno movement */
+			acthd = 0;
+
+			memset(engine->hangcheck.instdone, 0,
+			       sizeof(engine->hangcheck.instdone));
+		}
+
+		engine->hangcheck.seqno = seqno;
+		engine->hangcheck.acthd = acthd;
+		engine->hangcheck.user_interrupts = user_interrupts;
+		busy_count += busy;
+	}
+
+	for_each_engine_id(engine, dev_priv, id) {
+		if (engine->hangcheck.score >= HANGCHECK_SCORE_RING_HUNG) {
+			DRM_INFO("%s on %s\n",
+				 stuck[id] ? "stuck" : "no progress",
+				 engine->name);
+			rings_hung |= intel_engine_flag(engine);
+		}
+	}
+
+	if (rings_hung) {
+		i915_handle_error(dev, rings_hung, "Engine(s) hung");
+		goto out;
+	}
+
+	if (busy_count)
+		/* Reset timer case chip hangs without another request
+		 * being added */
+		i915_queue_hangcheck(dev);
+
+out:
+	ENABLE_RPM_WAKEREF_ASSERTS(dev_priv);
+}
+
+void i915_queue_hangcheck(struct drm_device *dev)
+{
+	struct i915_gpu_error *e = &to_i915(dev)->gpu_error;
+
+	if (!i915.enable_hangcheck)
+		return;
+
+	/* Don't continually defer the hangcheck so that it is always run at
+	 * least once after work has been scheduled on any ring. Otherwise,
+	 * we will ignore a hung ring if a second ring is kept busy.
+	 */
+
+	queue_delayed_work(e->hangcheck_wq, &e->hangcheck_work,
+			   round_jiffies_up_relative(DRM_I915_HANGCHECK_JIFFIES));
+}
+
+static void ibx_irq_reset(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	if (HAS_PCH_NOP(dev))
+		return;
+
+	GEN5_IRQ_RESET(SDE);
+
+	if (HAS_PCH_CPT(dev) || HAS_PCH_LPT(dev))
+		I915_WRITE(SERR_INT, 0xffffffff);
+}
+
+/*
+ * SDEIER is also touched by the interrupt handler to work around missed PCH
+ * interrupts. Hence we can't update it after the interrupt handler is enabled -
+ * instead we unconditionally enable all PCH interrupt sources here, but then
+ * only unmask them as needed with SDEIMR.
+ *
+ * This function needs to be called before interrupts are enabled.
+ */
+static void ibx_irq_pre_postinstall(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	if (HAS_PCH_NOP(dev))
+		return;
+
+	WARN_ON(I915_READ(SDEIER) != 0);
+	I915_WRITE(SDEIER, 0xffffffff);
+	POSTING_READ(SDEIER);
+}
+
+static void gen5_gt_irq_reset(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	GEN5_IRQ_RESET(GT);
+	if (INTEL_INFO(dev)->gen >= 6)
+		GEN5_IRQ_RESET(GEN6_PM);
+}
+
+static void vlv_display_irq_reset(struct drm_i915_private *dev_priv)
+{
+	enum pipe pipe;
+
+	if (IS_CHERRYVIEW(dev_priv))
+		I915_WRITE(DPINVGTT, DPINVGTT_STATUS_MASK_CHV);
+	else
+		I915_WRITE(DPINVGTT, DPINVGTT_STATUS_MASK);
+
+	i915_hotplug_interrupt_update_locked(dev_priv, 0xffffffff, 0);
+	I915_WRITE(PORT_HOTPLUG_STAT, I915_READ(PORT_HOTPLUG_STAT));
+
+	for_each_pipe(dev_priv, pipe) {
+		I915_WRITE(PIPESTAT(pipe),
+			   PIPE_FIFO_UNDERRUN_STATUS |
+			   PIPESTAT_INT_STATUS_MASK);
+		dev_priv->pipestat_irq_mask[pipe] = 0;
+	}
+
+	GEN5_IRQ_RESET(VLV_);
+	dev_priv->irq_mask = ~0;
+}
+
+static void vlv_display_irq_postinstall(struct drm_i915_private *dev_priv)
+{
+	u32 pipestat_mask;
+	u32 enable_mask;
+	enum pipe pipe;
+
+	pipestat_mask = PLANE_FLIP_DONE_INT_STATUS_VLV |
+			PIPE_CRC_DONE_INTERRUPT_STATUS;
+
+	i915_enable_pipestat(dev_priv, PIPE_A, PIPE_GMBUS_INTERRUPT_STATUS);
+	for_each_pipe(dev_priv, pipe)
+		i915_enable_pipestat(dev_priv, pipe, pipestat_mask);
+
+	enable_mask = I915_DISPLAY_PORT_INTERRUPT |
+		I915_DISPLAY_PIPE_A_EVENT_INTERRUPT |
+		I915_DISPLAY_PIPE_B_EVENT_INTERRUPT;
+	if (IS_CHERRYVIEW(dev_priv))
+		enable_mask |= I915_DISPLAY_PIPE_C_EVENT_INTERRUPT;
+
+	WARN_ON(dev_priv->irq_mask != ~0);
+
+	dev_priv->irq_mask = ~enable_mask;
+
+	GEN5_IRQ_INIT(VLV_, dev_priv->irq_mask, enable_mask);
+}
+
+/* drm_dma.h hooks
+*/
+static void ironlake_irq_reset(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	I915_WRITE(HWSTAM, 0xffffffff);
+
+	GEN5_IRQ_RESET(DE);
+	if (IS_GEN7(dev))
+		I915_WRITE(GEN7_ERR_INT, 0xffffffff);
+
+	gen5_gt_irq_reset(dev);
+
+	ibx_irq_reset(dev);
+}
+
+static void valleyview_irq_preinstall(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	I915_WRITE(VLV_MASTER_IER, 0);
+	POSTING_READ(VLV_MASTER_IER);
+
+	gen5_gt_irq_reset(dev);
+
+	spin_lock_irq(&dev_priv->irq_lock);
+	if (dev_priv->display_irqs_enabled)
+		vlv_display_irq_reset(dev_priv);
+	spin_unlock_irq(&dev_priv->irq_lock);
+}
+
+static void gen8_gt_irq_reset(struct drm_i915_private *dev_priv)
+{
+	GEN8_IRQ_RESET_NDX(GT, 0);
+	GEN8_IRQ_RESET_NDX(GT, 1);
+	GEN8_IRQ_RESET_NDX(GT, 2);
+	GEN8_IRQ_RESET_NDX(GT, 3);
+}
+
+static void gen8_irq_reset(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	int pipe;
+
+	I915_WRITE(GEN8_MASTER_IRQ, 0);
+	POSTING_READ(GEN8_MASTER_IRQ);
+
+	gen8_gt_irq_reset(dev_priv);
+
+	for_each_pipe(dev_priv, pipe)
+		if (intel_display_power_is_enabled(dev_priv,
+						   POWER_DOMAIN_PIPE(pipe)))
+			GEN8_IRQ_RESET_NDX(DE_PIPE, pipe);
+
+	GEN5_IRQ_RESET(GEN8_DE_PORT_);
+	GEN5_IRQ_RESET(GEN8_DE_MISC_);
+	GEN5_IRQ_RESET(GEN8_PCU_);
+
+	if (HAS_PCH_SPLIT(dev))
+		ibx_irq_reset(dev);
+}
+
+void gen8_irq_power_well_post_enable(struct drm_i915_private *dev_priv,
+				     unsigned int pipe_mask)
+{
+	uint32_t extra_ier = GEN8_PIPE_VBLANK | GEN8_PIPE_FIFO_UNDERRUN;
+	enum pipe pipe;
+
+	spin_lock_irq(&dev_priv->irq_lock);
+	for_each_pipe_masked(dev_priv, pipe, pipe_mask)
+		GEN8_IRQ_INIT_NDX(DE_PIPE, pipe,
+				  dev_priv->de_irq_mask[pipe],
+				  ~dev_priv->de_irq_mask[pipe] | extra_ier);
+	spin_unlock_irq(&dev_priv->irq_lock);
+}
+
+void gen8_irq_power_well_pre_disable(struct drm_i915_private *dev_priv,
+				     unsigned int pipe_mask)
+{
+	enum pipe pipe;
+
+	spin_lock_irq(&dev_priv->irq_lock);
+	for_each_pipe_masked(dev_priv, pipe, pipe_mask)
+		GEN8_IRQ_RESET_NDX(DE_PIPE, pipe);
+	spin_unlock_irq(&dev_priv->irq_lock);
+
+	/* make sure we're done processing display irqs */
+	synchronize_irq(dev_priv->dev->irq);
+}
+
+static void cherryview_irq_preinstall(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	I915_WRITE(GEN8_MASTER_IRQ, 0);
+	POSTING_READ(GEN8_MASTER_IRQ);
+
+	gen8_gt_irq_reset(dev_priv);
+
+	GEN5_IRQ_RESET(GEN8_PCU_);
+
+	spin_lock_irq(&dev_priv->irq_lock);
+	if (dev_priv->display_irqs_enabled)
+		vlv_display_irq_reset(dev_priv);
+	spin_unlock_irq(&dev_priv->irq_lock);
+}
+
+static u32 intel_hpd_enabled_irqs(struct drm_device *dev,
+				  const u32 hpd[HPD_NUM_PINS])
+{
+	struct drm_i915_private *dev_priv = to_i915(dev);
+	struct intel_encoder *encoder;
+	u32 enabled_irqs = 0;
+
+	for_each_intel_encoder(dev, encoder)
+		if (dev_priv->hotplug.stats[encoder->hpd_pin].state == HPD_ENABLED)
+			enabled_irqs |= hpd[encoder->hpd_pin];
+
+	return enabled_irqs;
+}
+
+static void ibx_hpd_irq_setup(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	u32 hotplug_irqs, hotplug, enabled_irqs;
+
+	if (HAS_PCH_IBX(dev)) {
+		hotplug_irqs = SDE_HOTPLUG_MASK;
+		enabled_irqs = intel_hpd_enabled_irqs(dev, hpd_ibx);
+	} else {
+		hotplug_irqs = SDE_HOTPLUG_MASK_CPT;
+		enabled_irqs = intel_hpd_enabled_irqs(dev, hpd_cpt);
+	}
+
+	ibx_display_interrupt_update(dev_priv, hotplug_irqs, enabled_irqs);
+
+	/*
+	 * Enable digital hotplug on the PCH, and configure the DP short pulse
+	 * duration to 2ms (which is the minimum in the Display Port spec).
+	 * The pulse duration bits are reserved on LPT+.
+	 */
+	hotplug = I915_READ(PCH_PORT_HOTPLUG);
+	hotplug &= ~(PORTD_PULSE_DURATION_MASK|PORTC_PULSE_DURATION_MASK|PORTB_PULSE_DURATION_MASK);
+	hotplug |= PORTD_HOTPLUG_ENABLE | PORTD_PULSE_DURATION_2ms;
+	hotplug |= PORTC_HOTPLUG_ENABLE | PORTC_PULSE_DURATION_2ms;
+	hotplug |= PORTB_HOTPLUG_ENABLE | PORTB_PULSE_DURATION_2ms;
+	/*
+	 * When CPU and PCH are on the same package, port A
+	 * HPD must be enabled in both north and south.
+	 */
+	if (HAS_PCH_LPT_LP(dev))
+		hotplug |= PORTA_HOTPLUG_ENABLE;
+	I915_WRITE(PCH_PORT_HOTPLUG, hotplug);
+}
+
+static void spt_hpd_irq_setup(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	u32 hotplug_irqs, hotplug, enabled_irqs;
+
+	hotplug_irqs = SDE_HOTPLUG_MASK_SPT;
+	enabled_irqs = intel_hpd_enabled_irqs(dev, hpd_spt);
+
+	ibx_display_interrupt_update(dev_priv, hotplug_irqs, enabled_irqs);
+
+	/* Enable digital hotplug on the PCH */
+	hotplug = I915_READ(PCH_PORT_HOTPLUG);
+	hotplug |= PORTD_HOTPLUG_ENABLE | PORTC_HOTPLUG_ENABLE |
+		PORTB_HOTPLUG_ENABLE | PORTA_HOTPLUG_ENABLE;
+	I915_WRITE(PCH_PORT_HOTPLUG, hotplug);
+
+	hotplug = I915_READ(PCH_PORT_HOTPLUG2);
+	hotplug |= PORTE_HOTPLUG_ENABLE;
+	I915_WRITE(PCH_PORT_HOTPLUG2, hotplug);
+}
+
+static void ilk_hpd_irq_setup(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	u32 hotplug_irqs, hotplug, enabled_irqs;
+
+	if (INTEL_INFO(dev)->gen >= 8) {
+		hotplug_irqs = GEN8_PORT_DP_A_HOTPLUG;
+		enabled_irqs = intel_hpd_enabled_irqs(dev, hpd_bdw);
+
+		bdw_update_port_irq(dev_priv, hotplug_irqs, enabled_irqs);
+	} else if (INTEL_INFO(dev)->gen >= 7) {
+		hotplug_irqs = DE_DP_A_HOTPLUG_IVB;
+		enabled_irqs = intel_hpd_enabled_irqs(dev, hpd_ivb);
+
+		ilk_update_display_irq(dev_priv, hotplug_irqs, enabled_irqs);
+	} else {
+		hotplug_irqs = DE_DP_A_HOTPLUG;
+		enabled_irqs = intel_hpd_enabled_irqs(dev, hpd_ilk);
+
+		ilk_update_display_irq(dev_priv, hotplug_irqs, enabled_irqs);
+	}
+
+	/*
+	 * Enable digital hotplug on the CPU, and configure the DP short pulse
+	 * duration to 2ms (which is the minimum in the Display Port spec)
+	 * The pulse duration bits are reserved on HSW+.
+	 */
+	hotplug = I915_READ(DIGITAL_PORT_HOTPLUG_CNTRL);
+	hotplug &= ~DIGITAL_PORTA_PULSE_DURATION_MASK;
+	hotplug |= DIGITAL_PORTA_HOTPLUG_ENABLE | DIGITAL_PORTA_PULSE_DURATION_2ms;
+	I915_WRITE(DIGITAL_PORT_HOTPLUG_CNTRL, hotplug);
+
+	ibx_hpd_irq_setup(dev);
+}
+
+static void bxt_hpd_irq_setup(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	u32 hotplug_irqs, hotplug, enabled_irqs;
+
+	enabled_irqs = intel_hpd_enabled_irqs(dev, hpd_bxt);
+	hotplug_irqs = BXT_DE_PORT_HOTPLUG_MASK;
+
+	bdw_update_port_irq(dev_priv, hotplug_irqs, enabled_irqs);
+
+	hotplug = I915_READ(PCH_PORT_HOTPLUG);
+	hotplug |= PORTC_HOTPLUG_ENABLE | PORTB_HOTPLUG_ENABLE |
+		PORTA_HOTPLUG_ENABLE;
+
+	DRM_DEBUG_KMS("Invert bit setting: hp_ctl:%x hp_port:%x\n",
+		      hotplug, enabled_irqs);
+	hotplug &= ~BXT_DDI_HPD_INVERT_MASK;
+
+	/*
+	 * For BXT invert bit has to be set based on AOB design
+	 * for HPD detection logic, update it based on VBT fields.
+	 */
+
+	if ((enabled_irqs & BXT_DE_PORT_HP_DDIA) &&
+	    intel_bios_is_port_hpd_inverted(dev_priv, PORT_A))
+		hotplug |= BXT_DDIA_HPD_INVERT;
+	if ((enabled_irqs & BXT_DE_PORT_HP_DDIB) &&
+	    intel_bios_is_port_hpd_inverted(dev_priv, PORT_B))
+		hotplug |= BXT_DDIB_HPD_INVERT;
+	if ((enabled_irqs & BXT_DE_PORT_HP_DDIC) &&
+	    intel_bios_is_port_hpd_inverted(dev_priv, PORT_C))
+		hotplug |= BXT_DDIC_HPD_INVERT;
+
+	I915_WRITE(PCH_PORT_HOTPLUG, hotplug);
+}
+
+static void ibx_irq_postinstall(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	u32 mask;
+
+	if (HAS_PCH_NOP(dev))
+		return;
+
+	if (HAS_PCH_IBX(dev))
+		mask = SDE_GMBUS | SDE_AUX_MASK | SDE_POISON;
+	else
+		mask = SDE_GMBUS_CPT | SDE_AUX_MASK_CPT;
+
+	gen5_assert_iir_is_zero(dev_priv, SDEIIR);
+	I915_WRITE(SDEIMR, ~mask);
+}
+
+static void gen5_gt_irq_postinstall(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	u32 pm_irqs, gt_irqs;
+
+	pm_irqs = gt_irqs = 0;
+
+	dev_priv->gt_irq_mask = ~0;
+	if (HAS_L3_DPF(dev)) {
+		/* L3 parity interrupt is always unmasked. */
+		dev_priv->gt_irq_mask = ~GT_PARITY_ERROR(dev);
+		gt_irqs |= GT_PARITY_ERROR(dev);
+	}
+
+	gt_irqs |= GT_RENDER_USER_INTERRUPT;
+	if (IS_GEN5(dev)) {
+		gt_irqs |= GT_RENDER_PIPECTL_NOTIFY_INTERRUPT |
+			   ILK_BSD_USER_INTERRUPT;
+	} else {
+		gt_irqs |= GT_BLT_USER_INTERRUPT | GT_BSD_USER_INTERRUPT;
+	}
+
+	GEN5_IRQ_INIT(GT, dev_priv->gt_irq_mask, gt_irqs);
+
+	if (INTEL_INFO(dev)->gen >= 6) {
+		/*
+		 * RPS interrupts will get enabled/disabled on demand when RPS
+		 * itself is enabled/disabled.
+		 */
+		if (HAS_VEBOX(dev))
+			pm_irqs |= PM_VEBOX_USER_INTERRUPT;
+
+		dev_priv->pm_irq_mask = 0xffffffff;
+		GEN5_IRQ_INIT(GEN6_PM, dev_priv->pm_irq_mask, pm_irqs);
+	}
+}
+
+static int ironlake_irq_postinstall(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	u32 display_mask, extra_mask;
+
+	if (INTEL_INFO(dev)->gen >= 7) {
+		display_mask = (DE_MASTER_IRQ_CONTROL | DE_GSE_IVB |
+				DE_PCH_EVENT_IVB | DE_PLANEC_FLIP_DONE_IVB |
+				DE_PLANEB_FLIP_DONE_IVB |
+				DE_PLANEA_FLIP_DONE_IVB | DE_AUX_CHANNEL_A_IVB);
+		extra_mask = (DE_PIPEC_VBLANK_IVB | DE_PIPEB_VBLANK_IVB |
+			      DE_PIPEA_VBLANK_IVB | DE_ERR_INT_IVB |
+			      DE_DP_A_HOTPLUG_IVB);
+	} else {
+		display_mask = (DE_MASTER_IRQ_CONTROL | DE_GSE | DE_PCH_EVENT |
+				DE_PLANEA_FLIP_DONE | DE_PLANEB_FLIP_DONE |
+				DE_AUX_CHANNEL_A |
+				DE_PIPEB_CRC_DONE | DE_PIPEA_CRC_DONE |
+				DE_POISON);
+		extra_mask = (DE_PIPEA_VBLANK | DE_PIPEB_VBLANK | DE_PCU_EVENT |
+			      DE_PIPEB_FIFO_UNDERRUN | DE_PIPEA_FIFO_UNDERRUN |
+			      DE_DP_A_HOTPLUG);
+	}
+
+	dev_priv->irq_mask = ~display_mask;
+
+	I915_WRITE(HWSTAM, 0xeffe);
+
+	ibx_irq_pre_postinstall(dev);
+
+	GEN5_IRQ_INIT(DE, dev_priv->irq_mask, display_mask | extra_mask);
+
+	gen5_gt_irq_postinstall(dev);
+
+	ibx_irq_postinstall(dev);
+
+	if (IS_IRONLAKE_M(dev)) {
+		/* Enable PCU event interrupts
+		 *
+		 * spinlocking not required here for correctness since interrupt
+		 * setup is guaranteed to run in single-threaded context. But we
+		 * need it to make the assert_spin_locked happy. */
+		spin_lock_irq(&dev_priv->irq_lock);
+		ilk_enable_display_irq(dev_priv, DE_PCU_EVENT);
+		spin_unlock_irq(&dev_priv->irq_lock);
+	}
+
+	return 0;
+}
+
+void valleyview_enable_display_irqs(struct drm_i915_private *dev_priv)
+{
+	assert_spin_locked(&dev_priv->irq_lock);
+
+	if (dev_priv->display_irqs_enabled)
+		return;
+
+	dev_priv->display_irqs_enabled = true;
+
+	if (intel_irqs_enabled(dev_priv)) {
+		vlv_display_irq_reset(dev_priv);
+		vlv_display_irq_postinstall(dev_priv);
+	}
+}
+
+void valleyview_disable_display_irqs(struct drm_i915_private *dev_priv)
+{
+	assert_spin_locked(&dev_priv->irq_lock);
+
+	if (!dev_priv->display_irqs_enabled)
+		return;
+
+	dev_priv->display_irqs_enabled = false;
+
+	if (intel_irqs_enabled(dev_priv))
+		vlv_display_irq_reset(dev_priv);
+}
+
+
+static int valleyview_irq_postinstall(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	gen5_gt_irq_postinstall(dev);
+
+	spin_lock_irq(&dev_priv->irq_lock);
+	if (dev_priv->display_irqs_enabled)
+		vlv_display_irq_postinstall(dev_priv);
+	spin_unlock_irq(&dev_priv->irq_lock);
+
+	I915_WRITE(VLV_MASTER_IER, MASTER_INTERRUPT_ENABLE);
+	POSTING_READ(VLV_MASTER_IER);
+
+	return 0;
+}
+
+static void gen8_gt_irq_postinstall(struct drm_i915_private *dev_priv)
+{
+	/* These are interrupts we'll toggle with the ring mask register */
+	uint32_t gt_interrupts[] = {
+		GT_RENDER_USER_INTERRUPT << GEN8_RCS_IRQ_SHIFT |
+			GT_CONTEXT_SWITCH_INTERRUPT << GEN8_RCS_IRQ_SHIFT |
+			GT_RENDER_USER_INTERRUPT << GEN8_BCS_IRQ_SHIFT |
+			GT_CONTEXT_SWITCH_INTERRUPT << GEN8_BCS_IRQ_SHIFT,
+		GT_RENDER_USER_INTERRUPT << GEN8_VCS1_IRQ_SHIFT |
+			GT_CONTEXT_SWITCH_INTERRUPT << GEN8_VCS1_IRQ_SHIFT |
+			GT_RENDER_USER_INTERRUPT << GEN8_VCS2_IRQ_SHIFT |
+			GT_CONTEXT_SWITCH_INTERRUPT << GEN8_VCS2_IRQ_SHIFT,
+		0,
+		GT_RENDER_USER_INTERRUPT << GEN8_VECS_IRQ_SHIFT |
+			GT_CONTEXT_SWITCH_INTERRUPT << GEN8_VECS_IRQ_SHIFT
+		};
+
+	if (HAS_L3_DPF(dev_priv))
+		gt_interrupts[0] |= GT_RENDER_L3_PARITY_ERROR_INTERRUPT;
+
+	dev_priv->pm_irq_mask = 0xffffffff;
+	GEN8_IRQ_INIT_NDX(GT, 0, ~gt_interrupts[0], gt_interrupts[0]);
+	GEN8_IRQ_INIT_NDX(GT, 1, ~gt_interrupts[1], gt_interrupts[1]);
+	/*
+	 * RPS interrupts will get enabled/disabled on demand when RPS itself
+	 * is enabled/disabled.
+	 */
+	GEN8_IRQ_INIT_NDX(GT, 2, dev_priv->pm_irq_mask, 0);
+	GEN8_IRQ_INIT_NDX(GT, 3, ~gt_interrupts[3], gt_interrupts[3]);
+}
+
+static void gen8_de_irq_postinstall(struct drm_i915_private *dev_priv)
+{
+	uint32_t de_pipe_masked = GEN8_PIPE_CDCLK_CRC_DONE;
+	uint32_t de_pipe_enables;
+	u32 de_port_masked = GEN8_AUX_CHANNEL_A;
+	u32 de_port_enables;
+	enum pipe pipe;
+
+	if (INTEL_INFO(dev_priv)->gen >= 9) {
+		de_pipe_masked |= GEN9_PIPE_PLANE1_FLIP_DONE |
+				  GEN9_DE_PIPE_IRQ_FAULT_ERRORS;
+		de_port_masked |= GEN9_AUX_CHANNEL_B | GEN9_AUX_CHANNEL_C |
+				  GEN9_AUX_CHANNEL_D;
+		if (IS_BROXTON(dev_priv))
+			de_port_masked |= BXT_DE_PORT_GMBUS;
+	} else {
+		de_pipe_masked |= GEN8_PIPE_PRIMARY_FLIP_DONE |
+				  GEN8_DE_PIPE_IRQ_FAULT_ERRORS;
+	}
+
+	de_pipe_enables = de_pipe_masked | GEN8_PIPE_VBLANK |
+					   GEN8_PIPE_FIFO_UNDERRUN;
+
+	de_port_enables = de_port_masked;
+	if (IS_BROXTON(dev_priv))
+		de_port_enables |= BXT_DE_PORT_HOTPLUG_MASK;
+	else if (IS_BROADWELL(dev_priv))
+		de_port_enables |= GEN8_PORT_DP_A_HOTPLUG;
+
+	dev_priv->de_irq_mask[PIPE_A] = ~de_pipe_masked;
+	dev_priv->de_irq_mask[PIPE_B] = ~de_pipe_masked;
+	dev_priv->de_irq_mask[PIPE_C] = ~de_pipe_masked;
+
+	for_each_pipe(dev_priv, pipe)
+		if (intel_display_power_is_enabled(dev_priv,
+				POWER_DOMAIN_PIPE(pipe)))
+			GEN8_IRQ_INIT_NDX(DE_PIPE, pipe,
+					  dev_priv->de_irq_mask[pipe],
+					  de_pipe_enables);
+
+	GEN5_IRQ_INIT(GEN8_DE_PORT_, ~de_port_masked, de_port_enables);
+}
+
+static int gen8_irq_postinstall(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	if (HAS_PCH_SPLIT(dev))
+		ibx_irq_pre_postinstall(dev);
+
+	gen8_gt_irq_postinstall(dev_priv);
+	gen8_de_irq_postinstall(dev_priv);
+
+	if (HAS_PCH_SPLIT(dev))
+		ibx_irq_postinstall(dev);
+
+	I915_WRITE(GEN8_MASTER_IRQ, GEN8_MASTER_IRQ_CONTROL);
+	POSTING_READ(GEN8_MASTER_IRQ);
+
+	return 0;
+}
+
+static int cherryview_irq_postinstall(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	gen8_gt_irq_postinstall(dev_priv);
+
+	spin_lock_irq(&dev_priv->irq_lock);
+	if (dev_priv->display_irqs_enabled)
+		vlv_display_irq_postinstall(dev_priv);
+	spin_unlock_irq(&dev_priv->irq_lock);
+
+	I915_WRITE(GEN8_MASTER_IRQ, GEN8_MASTER_IRQ_CONTROL);
+	POSTING_READ(GEN8_MASTER_IRQ);
+
+	return 0;
+}
+
+static void gen8_irq_uninstall(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	if (!dev_priv)
+		return;
+
+	gen8_irq_reset(dev);
+}
+
+static void valleyview_irq_uninstall(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	if (!dev_priv)
+		return;
+
+	I915_WRITE(VLV_MASTER_IER, 0);
+	POSTING_READ(VLV_MASTER_IER);
+
+	gen5_gt_irq_reset(dev);
+
+	I915_WRITE(HWSTAM, 0xffffffff);
+
+	spin_lock_irq(&dev_priv->irq_lock);
+	if (dev_priv->display_irqs_enabled)
+		vlv_display_irq_reset(dev_priv);
+	spin_unlock_irq(&dev_priv->irq_lock);
+}
+
+static void cherryview_irq_uninstall(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	if (!dev_priv)
+		return;
+
+	I915_WRITE(GEN8_MASTER_IRQ, 0);
+	POSTING_READ(GEN8_MASTER_IRQ);
+
+	gen8_gt_irq_reset(dev_priv);
+
+	GEN5_IRQ_RESET(GEN8_PCU_);
+
+	spin_lock_irq(&dev_priv->irq_lock);
+	if (dev_priv->display_irqs_enabled)
+		vlv_display_irq_reset(dev_priv);
+	spin_unlock_irq(&dev_priv->irq_lock);
+}
+
+static void ironlake_irq_uninstall(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	if (!dev_priv)
+		return;
+
+	ironlake_irq_reset(dev);
+}
+
+static void i8xx_irq_preinstall(struct drm_device * dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	int pipe;
+
+	for_each_pipe(dev_priv, pipe)
+		I915_WRITE(PIPESTAT(pipe), 0);
+	I915_WRITE16(IMR, 0xffff);
+	I915_WRITE16(IER, 0x0);
+	POSTING_READ16(IER);
+}
+
+static int i8xx_irq_postinstall(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	I915_WRITE16(EMR,
+		     ~(I915_ERROR_PAGE_TABLE | I915_ERROR_MEMORY_REFRESH));
+
+	/* Unmask the interrupts that we always want on. */
+	dev_priv->irq_mask =
+		~(I915_DISPLAY_PIPE_A_EVENT_INTERRUPT |
+		  I915_DISPLAY_PIPE_B_EVENT_INTERRUPT |
+		  I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT |
+		  I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT);
+	I915_WRITE16(IMR, dev_priv->irq_mask);
+
+	I915_WRITE16(IER,
+		     I915_DISPLAY_PIPE_A_EVENT_INTERRUPT |
+		     I915_DISPLAY_PIPE_B_EVENT_INTERRUPT |
+		     I915_USER_INTERRUPT);
+	POSTING_READ16(IER);
+
+	/* Interrupt setup is already guaranteed to be single-threaded, this is
+	 * just to make the assert_spin_locked check happy. */
+	spin_lock_irq(&dev_priv->irq_lock);
+	i915_enable_pipestat(dev_priv, PIPE_A, PIPE_CRC_DONE_INTERRUPT_STATUS);
+	i915_enable_pipestat(dev_priv, PIPE_B, PIPE_CRC_DONE_INTERRUPT_STATUS);
+	spin_unlock_irq(&dev_priv->irq_lock);
+
+	return 0;
+}
+
+/*
+ * Returns true when a page flip has completed.
+ */
+static bool i8xx_handle_vblank(struct drm_device *dev,
+			       int plane, int pipe, u32 iir)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	u16 flip_pending = DISPLAY_PLANE_FLIP_PENDING(plane);
+
+	if (!intel_pipe_handle_vblank(dev, pipe))
+		return false;
+
+	if ((iir & flip_pending) == 0)
+		goto check_page_flip;
+
+	/* We detect FlipDone by looking for the change in PendingFlip from '1'
+	 * to '0' on the following vblank, i.e. IIR has the Pendingflip
+	 * asserted following the MI_DISPLAY_FLIP, but ISR is deasserted, hence
+	 * the flip is completed (no longer pending). Since this doesn't raise
+	 * an interrupt per se, we watch for the change at vblank.
+	 */
+	if (I915_READ16(ISR) & flip_pending)
+		goto check_page_flip;
+
+	intel_prepare_page_flip(dev, plane);
+	intel_finish_page_flip(dev, pipe);
+	return true;
+
+check_page_flip:
+	intel_check_page_flip(dev, pipe);
+	return false;
+}
+
+static irqreturn_t i8xx_irq_handler(int irq, void *arg)
+{
+	struct drm_device *dev = arg;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	u16 iir, new_iir;
+	u32 pipe_stats[2];
+	int pipe;
+	u16 flip_mask =
+		I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT |
+		I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT;
+	irqreturn_t ret;
+
+	if (!intel_irqs_enabled(dev_priv))
+		return IRQ_NONE;
+
+	/* IRQs are synced during runtime_suspend, we don't require a wakeref */
+	disable_rpm_wakeref_asserts(dev_priv);
+
+	ret = IRQ_NONE;
+	iir = I915_READ16(IIR);
+	if (iir == 0)
+		goto out;
+
+	while (iir & ~flip_mask) {
+		/* Can't rely on pipestat interrupt bit in iir as it might
+		 * have been cleared after the pipestat interrupt was received.
+		 * It doesn't set the bit in iir again, but it still produces
+		 * interrupts (for non-MSI).
+		 */
+		spin_lock(&dev_priv->irq_lock);
+		if (iir & I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT)
+			DRM_DEBUG("Command parser error, iir 0x%08x\n", iir);
+
+		for_each_pipe(dev_priv, pipe) {
+			i915_reg_t reg = PIPESTAT(pipe);
+			pipe_stats[pipe] = I915_READ(reg);
+
+			/*
+			 * Clear the PIPE*STAT regs before the IIR
+			 */
+			if (pipe_stats[pipe] & 0x8000ffff)
+				I915_WRITE(reg, pipe_stats[pipe]);
+		}
+		spin_unlock(&dev_priv->irq_lock);
+
+		I915_WRITE16(IIR, iir & ~flip_mask);
+		new_iir = I915_READ16(IIR); /* Flush posted writes */
+
+		if (iir & I915_USER_INTERRUPT)
+			notify_ring(&dev_priv->engine[RCS]);
+
+		for_each_pipe(dev_priv, pipe) {
+			int plane = pipe;
+			if (HAS_FBC(dev))
+				plane = !plane;
+
+			if (pipe_stats[pipe] & PIPE_VBLANK_INTERRUPT_STATUS &&
+			    i8xx_handle_vblank(dev, plane, pipe, iir))
+				flip_mask &= ~DISPLAY_PLANE_FLIP_PENDING(plane);
+
+			if (pipe_stats[pipe] & PIPE_CRC_DONE_INTERRUPT_STATUS)
+				i9xx_pipe_crc_irq_handler(dev, pipe);
+
+			if (pipe_stats[pipe] & PIPE_FIFO_UNDERRUN_STATUS)
+				intel_cpu_fifo_underrun_irq_handler(dev_priv,
+								    pipe);
+		}
+
+		iir = new_iir;
+	}
+	ret = IRQ_HANDLED;
+
+out:
+	enable_rpm_wakeref_asserts(dev_priv);
+
+	return ret;
+}
+
+static void i8xx_irq_uninstall(struct drm_device * dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	int pipe;
+
+	for_each_pipe(dev_priv, pipe) {
+		/* Clear enable bits; then clear status bits */
+		I915_WRITE(PIPESTAT(pipe), 0);
+		I915_WRITE(PIPESTAT(pipe), I915_READ(PIPESTAT(pipe)));
+	}
+	I915_WRITE16(IMR, 0xffff);
+	I915_WRITE16(IER, 0x0);
+	I915_WRITE16(IIR, I915_READ16(IIR));
+}
+
+static void i915_irq_preinstall(struct drm_device * dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	int pipe;
+
+	if (I915_HAS_HOTPLUG(dev)) {
+		i915_hotplug_interrupt_update(dev_priv, 0xffffffff, 0);
+		I915_WRITE(PORT_HOTPLUG_STAT, I915_READ(PORT_HOTPLUG_STAT));
+	}
+
+	I915_WRITE16(HWSTAM, 0xeffe);
+	for_each_pipe(dev_priv, pipe)
+		I915_WRITE(PIPESTAT(pipe), 0);
+	I915_WRITE(IMR, 0xffffffff);
+	I915_WRITE(IER, 0x0);
+	POSTING_READ(IER);
+}
+
+static int i915_irq_postinstall(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	u32 enable_mask;
+
+	I915_WRITE(EMR, ~(I915_ERROR_PAGE_TABLE | I915_ERROR_MEMORY_REFRESH));
+
+	/* Unmask the interrupts that we always want on. */
+	dev_priv->irq_mask =
+		~(I915_ASLE_INTERRUPT |
+		  I915_DISPLAY_PIPE_A_EVENT_INTERRUPT |
+		  I915_DISPLAY_PIPE_B_EVENT_INTERRUPT |
+		  I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT |
+		  I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT);
+
+	enable_mask =
+		I915_ASLE_INTERRUPT |
+		I915_DISPLAY_PIPE_A_EVENT_INTERRUPT |
+		I915_DISPLAY_PIPE_B_EVENT_INTERRUPT |
+		I915_USER_INTERRUPT;
+
+	if (I915_HAS_HOTPLUG(dev)) {
+		i915_hotplug_interrupt_update(dev_priv, 0xffffffff, 0);
+		POSTING_READ(PORT_HOTPLUG_EN);
+
+		/* Enable in IER... */
+		enable_mask |= I915_DISPLAY_PORT_INTERRUPT;
+		/* and unmask in IMR */
+		dev_priv->irq_mask &= ~I915_DISPLAY_PORT_INTERRUPT;
+	}
+
+	I915_WRITE(IMR, dev_priv->irq_mask);
+	I915_WRITE(IER, enable_mask);
+	POSTING_READ(IER);
+
+	i915_enable_asle_pipestat(dev);
+
+	/* Interrupt setup is already guaranteed to be single-threaded, this is
+	 * just to make the assert_spin_locked check happy. */
+	spin_lock_irq(&dev_priv->irq_lock);
+	i915_enable_pipestat(dev_priv, PIPE_A, PIPE_CRC_DONE_INTERRUPT_STATUS);
+	i915_enable_pipestat(dev_priv, PIPE_B, PIPE_CRC_DONE_INTERRUPT_STATUS);
+	spin_unlock_irq(&dev_priv->irq_lock);
+
+	return 0;
+}
+
+/*
+ * Returns true when a page flip has completed.
+ */
+static bool i915_handle_vblank(struct drm_device *dev,
+			       int plane, int pipe, u32 iir)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	u32 flip_pending = DISPLAY_PLANE_FLIP_PENDING(plane);
+
+	if (!intel_pipe_handle_vblank(dev, pipe))
+		return false;
+
+	if ((iir & flip_pending) == 0)
+		goto check_page_flip;
+
+	/* We detect FlipDone by looking for the change in PendingFlip from '1'
+	 * to '0' on the following vblank, i.e. IIR has the Pendingflip
+	 * asserted following the MI_DISPLAY_FLIP, but ISR is deasserted, hence
+	 * the flip is completed (no longer pending). Since this doesn't raise
+	 * an interrupt per se, we watch for the change at vblank.
+	 */
+	if (I915_READ(ISR) & flip_pending)
+		goto check_page_flip;
+
+	intel_prepare_page_flip(dev, plane);
+	intel_finish_page_flip(dev, pipe);
+	return true;
+
+check_page_flip:
+	intel_check_page_flip(dev, pipe);
+	return false;
+}
+
+static irqreturn_t i915_irq_handler(int irq, void *arg)
+{
+	struct drm_device *dev = arg;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	u32 iir, new_iir, pipe_stats[I915_MAX_PIPES];
+	u32 flip_mask =
+		I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT |
+		I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT;
+	int pipe, ret = IRQ_NONE;
+
+	if (!intel_irqs_enabled(dev_priv))
+		return IRQ_NONE;
+
+	/* IRQs are synced during runtime_suspend, we don't require a wakeref */
+	disable_rpm_wakeref_asserts(dev_priv);
+
+	iir = I915_READ(IIR);
+	do {
+		bool irq_received = (iir & ~flip_mask) != 0;
+		bool blc_event = false;
+
+		/* Can't rely on pipestat interrupt bit in iir as it might
+		 * have been cleared after the pipestat interrupt was received.
+		 * It doesn't set the bit in iir again, but it still produces
+		 * interrupts (for non-MSI).
+		 */
+		spin_lock(&dev_priv->irq_lock);
+		if (iir & I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT)
+			DRM_DEBUG("Command parser error, iir 0x%08x\n", iir);
+
+		for_each_pipe(dev_priv, pipe) {
+			i915_reg_t reg = PIPESTAT(pipe);
+			pipe_stats[pipe] = I915_READ(reg);
+
+			/* Clear the PIPE*STAT regs before the IIR */
+			if (pipe_stats[pipe] & 0x8000ffff) {
+				I915_WRITE(reg, pipe_stats[pipe]);
+				irq_received = true;
+			}
+		}
+		spin_unlock(&dev_priv->irq_lock);
+
+		if (!irq_received)
+			break;
+
+		/* Consume port.  Then clear IIR or we'll miss events */
+		if (I915_HAS_HOTPLUG(dev) &&
+		    iir & I915_DISPLAY_PORT_INTERRUPT) {
+			u32 hotplug_status = i9xx_hpd_irq_ack(dev_priv);
+			if (hotplug_status)
+				i9xx_hpd_irq_handler(dev, hotplug_status);
+		}
+
+		I915_WRITE(IIR, iir & ~flip_mask);
+		new_iir = I915_READ(IIR); /* Flush posted writes */
+
+		if (iir & I915_USER_INTERRUPT)
+			notify_ring(&dev_priv->engine[RCS]);
+
+		for_each_pipe(dev_priv, pipe) {
+			int plane = pipe;
+			if (HAS_FBC(dev))
+				plane = !plane;
+
+			if (pipe_stats[pipe] & PIPE_VBLANK_INTERRUPT_STATUS &&
+			    i915_handle_vblank(dev, plane, pipe, iir))
+				flip_mask &= ~DISPLAY_PLANE_FLIP_PENDING(plane);
+
+			if (pipe_stats[pipe] & PIPE_LEGACY_BLC_EVENT_STATUS)
+				blc_event = true;
+
+			if (pipe_stats[pipe] & PIPE_CRC_DONE_INTERRUPT_STATUS)
+				i9xx_pipe_crc_irq_handler(dev, pipe);
+
+			if (pipe_stats[pipe] & PIPE_FIFO_UNDERRUN_STATUS)
+				intel_cpu_fifo_underrun_irq_handler(dev_priv,
+								    pipe);
+		}
+
+		if (blc_event || (iir & I915_ASLE_INTERRUPT))
+			intel_opregion_asle_intr(dev);
+
+		/* With MSI, interrupts are only generated when iir
+		 * transitions from zero to nonzero.  If another bit got
+		 * set while we were handling the existing iir bits, then
+		 * we would never get another interrupt.
+		 *
+		 * This is fine on non-MSI as well, as if we hit this path
+		 * we avoid exiting the interrupt handler only to generate
+		 * another one.
+		 *
+		 * Note that for MSI this could cause a stray interrupt report
+		 * if an interrupt landed in the time between writing IIR and
+		 * the posting read.  This should be rare enough to never
+		 * trigger the 99% of 100,000 interrupts test for disabling
+		 * stray interrupts.
+		 */
+		ret = IRQ_HANDLED;
+		iir = new_iir;
+	} while (iir & ~flip_mask);
+
+	enable_rpm_wakeref_asserts(dev_priv);
+
+	return ret;
+}
+
+static void i915_irq_uninstall(struct drm_device * dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	int pipe;
+
+	if (I915_HAS_HOTPLUG(dev)) {
+		i915_hotplug_interrupt_update(dev_priv, 0xffffffff, 0);
+		I915_WRITE(PORT_HOTPLUG_STAT, I915_READ(PORT_HOTPLUG_STAT));
+	}
+
+	I915_WRITE16(HWSTAM, 0xffff);
+	for_each_pipe(dev_priv, pipe) {
+		/* Clear enable bits; then clear status bits */
+		I915_WRITE(PIPESTAT(pipe), 0);
+		I915_WRITE(PIPESTAT(pipe), I915_READ(PIPESTAT(pipe)));
+	}
+	I915_WRITE(IMR, 0xffffffff);
+	I915_WRITE(IER, 0x0);
+
+	I915_WRITE(IIR, I915_READ(IIR));
+}
+
+static void i965_irq_preinstall(struct drm_device * dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	int pipe;
+
+	i915_hotplug_interrupt_update(dev_priv, 0xffffffff, 0);
+	I915_WRITE(PORT_HOTPLUG_STAT, I915_READ(PORT_HOTPLUG_STAT));
+
+	I915_WRITE(HWSTAM, 0xeffe);
+	for_each_pipe(dev_priv, pipe)
+		I915_WRITE(PIPESTAT(pipe), 0);
+	I915_WRITE(IMR, 0xffffffff);
+	I915_WRITE(IER, 0x0);
+	POSTING_READ(IER);
+}
+
+static int i965_irq_postinstall(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	u32 enable_mask;
+	u32 error_mask;
+
+	/* Unmask the interrupts that we always want on. */
+	dev_priv->irq_mask = ~(I915_ASLE_INTERRUPT |
+			       I915_DISPLAY_PORT_INTERRUPT |
+			       I915_DISPLAY_PIPE_A_EVENT_INTERRUPT |
+			       I915_DISPLAY_PIPE_B_EVENT_INTERRUPT |
+			       I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT |
+			       I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT |
+			       I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT);
+
+	enable_mask = ~dev_priv->irq_mask;
+	enable_mask &= ~(I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT |
+			 I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT);
+	enable_mask |= I915_USER_INTERRUPT;
+
+	if (IS_G4X(dev))
+		enable_mask |= I915_BSD_USER_INTERRUPT;
+
+	/* Interrupt setup is already guaranteed to be single-threaded, this is
+	 * just to make the assert_spin_locked check happy. */
+	spin_lock_irq(&dev_priv->irq_lock);
+	i915_enable_pipestat(dev_priv, PIPE_A, PIPE_GMBUS_INTERRUPT_STATUS);
+	i915_enable_pipestat(dev_priv, PIPE_A, PIPE_CRC_DONE_INTERRUPT_STATUS);
+	i915_enable_pipestat(dev_priv, PIPE_B, PIPE_CRC_DONE_INTERRUPT_STATUS);
+	spin_unlock_irq(&dev_priv->irq_lock);
+
+	/*
+	 * Enable some error detection, note the instruction error mask
+	 * bit is reserved, so we leave it masked.
+	 */
+	if (IS_G4X(dev)) {
+		error_mask = ~(GM45_ERROR_PAGE_TABLE |
+			       GM45_ERROR_MEM_PRIV |
+			       GM45_ERROR_CP_PRIV |
+			       I915_ERROR_MEMORY_REFRESH);
+	} else {
+		error_mask = ~(I915_ERROR_PAGE_TABLE |
+			       I915_ERROR_MEMORY_REFRESH);
+	}
+	I915_WRITE(EMR, error_mask);
+
+	I915_WRITE(IMR, dev_priv->irq_mask);
+	I915_WRITE(IER, enable_mask);
+	POSTING_READ(IER);
+
+	i915_hotplug_interrupt_update(dev_priv, 0xffffffff, 0);
+	POSTING_READ(PORT_HOTPLUG_EN);
+
+	i915_enable_asle_pipestat(dev);
+
+	return 0;
+}
+
+static void i915_hpd_irq_setup(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	u32 hotplug_en;
+
+	assert_spin_locked(&dev_priv->irq_lock);
+
+	/* Note HDMI and DP share hotplug bits */
+	/* enable bits are the same for all generations */
+	hotplug_en = intel_hpd_enabled_irqs(dev, hpd_mask_i915);
+	/* Programming the CRT detection parameters tends
+	   to generate a spurious hotplug event about three
+	   seconds later.  So just do it once.
+	*/
+	if (IS_G4X(dev))
+		hotplug_en |= CRT_HOTPLUG_ACTIVATION_PERIOD_64;
+	hotplug_en |= CRT_HOTPLUG_VOLTAGE_COMPARE_50;
+
+	/* Ignore TV since it's buggy */
+	i915_hotplug_interrupt_update_locked(dev_priv,
+					     HOTPLUG_INT_EN_MASK |
+					     CRT_HOTPLUG_VOLTAGE_COMPARE_MASK |
+					     CRT_HOTPLUG_ACTIVATION_PERIOD_64,
+					     hotplug_en);
+}
+
+static irqreturn_t i965_irq_handler(int irq, void *arg)
+{
+	struct drm_device *dev = arg;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	u32 iir, new_iir;
+	u32 pipe_stats[I915_MAX_PIPES];
+	int ret = IRQ_NONE, pipe;
+	u32 flip_mask =
+		I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT |
+		I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT;
+
+	if (!intel_irqs_enabled(dev_priv))
+		return IRQ_NONE;
+
+	/* IRQs are synced during runtime_suspend, we don't require a wakeref */
+	disable_rpm_wakeref_asserts(dev_priv);
+
+	iir = I915_READ(IIR);
+
+	for (;;) {
+		bool irq_received = (iir & ~flip_mask) != 0;
+		bool blc_event = false;
+
+		/* Can't rely on pipestat interrupt bit in iir as it might
+		 * have been cleared after the pipestat interrupt was received.
+		 * It doesn't set the bit in iir again, but it still produces
+		 * interrupts (for non-MSI).
+		 */
+		spin_lock(&dev_priv->irq_lock);
+		if (iir & I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT)
+			DRM_DEBUG("Command parser error, iir 0x%08x\n", iir);
+
+		for_each_pipe(dev_priv, pipe) {
+			i915_reg_t reg = PIPESTAT(pipe);
+			pipe_stats[pipe] = I915_READ(reg);
+
+			/*
+			 * Clear the PIPE*STAT regs before the IIR
+			 */
+			if (pipe_stats[pipe] & 0x8000ffff) {
+				I915_WRITE(reg, pipe_stats[pipe]);
+				irq_received = true;
+			}
+		}
+		spin_unlock(&dev_priv->irq_lock);
+
+		if (!irq_received)
+			break;
+
+		ret = IRQ_HANDLED;
+
+		/* Consume port.  Then clear IIR or we'll miss events */
+		if (iir & I915_DISPLAY_PORT_INTERRUPT) {
+			u32 hotplug_status = i9xx_hpd_irq_ack(dev_priv);
+			if (hotplug_status)
+				i9xx_hpd_irq_handler(dev, hotplug_status);
+		}
+
+		I915_WRITE(IIR, iir & ~flip_mask);
+		new_iir = I915_READ(IIR); /* Flush posted writes */
+
+		if (iir & I915_USER_INTERRUPT)
+			notify_ring(&dev_priv->engine[RCS]);
+		if (iir & I915_BSD_USER_INTERRUPT)
+			notify_ring(&dev_priv->engine[VCS]);
+
+		for_each_pipe(dev_priv, pipe) {
+			if (pipe_stats[pipe] & PIPE_START_VBLANK_INTERRUPT_STATUS &&
+			    i915_handle_vblank(dev, pipe, pipe, iir))
+				flip_mask &= ~DISPLAY_PLANE_FLIP_PENDING(pipe);
+
+			if (pipe_stats[pipe] & PIPE_LEGACY_BLC_EVENT_STATUS)
+				blc_event = true;
+
+			if (pipe_stats[pipe] & PIPE_CRC_DONE_INTERRUPT_STATUS)
+				i9xx_pipe_crc_irq_handler(dev, pipe);
+
+			if (pipe_stats[pipe] & PIPE_FIFO_UNDERRUN_STATUS)
+				intel_cpu_fifo_underrun_irq_handler(dev_priv, pipe);
+		}
+
+		if (blc_event || (iir & I915_ASLE_INTERRUPT))
+			intel_opregion_asle_intr(dev);
+
+		if (pipe_stats[0] & PIPE_GMBUS_INTERRUPT_STATUS)
+			gmbus_irq_handler(dev);
+
+		/* With MSI, interrupts are only generated when iir
+		 * transitions from zero to nonzero.  If another bit got
+		 * set while we were handling the existing iir bits, then
+		 * we would never get another interrupt.
+		 *
+		 * This is fine on non-MSI as well, as if we hit this path
+		 * we avoid exiting the interrupt handler only to generate
+		 * another one.
+		 *
+		 * Note that for MSI this could cause a stray interrupt report
+		 * if an interrupt landed in the time between writing IIR and
+		 * the posting read.  This should be rare enough to never
+		 * trigger the 99% of 100,000 interrupts test for disabling
+		 * stray interrupts.
+		 */
+		iir = new_iir;
+	}
+
+	enable_rpm_wakeref_asserts(dev_priv);
+
+	return ret;
+}
+
+static void i965_irq_uninstall(struct drm_device * dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	int pipe;
+
+	if (!dev_priv)
+		return;
+
+	i915_hotplug_interrupt_update(dev_priv, 0xffffffff, 0);
+	I915_WRITE(PORT_HOTPLUG_STAT, I915_READ(PORT_HOTPLUG_STAT));
+
+	I915_WRITE(HWSTAM, 0xffffffff);
+	for_each_pipe(dev_priv, pipe)
+		I915_WRITE(PIPESTAT(pipe), 0);
+	I915_WRITE(IMR, 0xffffffff);
+	I915_WRITE(IER, 0x0);
+
+	for_each_pipe(dev_priv, pipe)
+		I915_WRITE(PIPESTAT(pipe),
+			   I915_READ(PIPESTAT(pipe)) & 0x8000ffff);
+	I915_WRITE(IIR, I915_READ(IIR));
+}
+
+/**
+ * intel_irq_init - initializes irq support
+ * @dev_priv: i915 device instance
+ *
+ * This function initializes all the irq support including work items, timers
+ * and all the vtables. It does not setup the interrupt itself though.
+ */
+void intel_irq_init(struct drm_i915_private *dev_priv)
+{
+	struct drm_device *dev = dev_priv->dev;
+
+	intel_hpd_init_work(dev_priv);
+
+	INIT_WORK(&dev_priv->rps.work, gen6_pm_rps_work);
+	INIT_WORK(&dev_priv->l3_parity.error_work, ivybridge_parity_work);
+
+	/* Let's track the enabled rps events */
+	if (IS_VALLEYVIEW(dev_priv))
+		/* WaGsvRC0ResidencyMethod:vlv */
+		dev_priv->pm_rps_events = GEN6_PM_RP_DOWN_EI_EXPIRED | GEN6_PM_RP_UP_EI_EXPIRED;
+	else
+		dev_priv->pm_rps_events = GEN6_PM_RPS_EVENTS;
+
+	INIT_DELAYED_WORK(&dev_priv->gpu_error.hangcheck_work,
+			  i915_hangcheck_elapsed);
+
+	if (IS_GEN2(dev_priv)) {
+		dev->max_vblank_count = 0;
+		dev->driver->get_vblank_counter = i8xx_get_vblank_counter;
+	} else if (IS_G4X(dev_priv) || INTEL_INFO(dev_priv)->gen >= 5) {
+		dev->max_vblank_count = 0xffffffff; /* full 32 bit counter */
+		dev->driver->get_vblank_counter = g4x_get_vblank_counter;
+	} else {
+		dev->driver->get_vblank_counter = i915_get_vblank_counter;
+		dev->max_vblank_count = 0xffffff; /* only 24 bits of frame count */
+	}
+
+	/*
+	 * Opt out of the vblank disable timer on everything except gen2.
+	 * Gen2 doesn't have a hardware frame counter and so depends on
+	 * vblank interrupts to produce sane vblank seuquence numbers.
+	 */
+	if (!IS_GEN2(dev_priv))
+		dev->vblank_disable_immediate = true;
+
+	dev->driver->get_vblank_timestamp = i915_get_vblank_timestamp;
+	dev->driver->get_scanout_position = i915_get_crtc_scanoutpos;
+
+	if (IS_CHERRYVIEW(dev_priv)) {
+		dev->driver->irq_handler = cherryview_irq_handler;
+		dev->driver->irq_preinstall = cherryview_irq_preinstall;
+		dev->driver->irq_postinstall = cherryview_irq_postinstall;
+		dev->driver->irq_uninstall = cherryview_irq_uninstall;
+		dev->driver->enable_vblank = valleyview_enable_vblank;
+		dev->driver->disable_vblank = valleyview_disable_vblank;
+		dev_priv->display.hpd_irq_setup = i915_hpd_irq_setup;
+	} else if (IS_VALLEYVIEW(dev_priv)) {
+		dev->driver->irq_handler = valleyview_irq_handler;
+		dev->driver->irq_preinstall = valleyview_irq_preinstall;
+		dev->driver->irq_postinstall = valleyview_irq_postinstall;
+		dev->driver->irq_uninstall = valleyview_irq_uninstall;
+		dev->driver->enable_vblank = valleyview_enable_vblank;
+		dev->driver->disable_vblank = valleyview_disable_vblank;
+		dev_priv->display.hpd_irq_setup = i915_hpd_irq_setup;
+	} else if (INTEL_INFO(dev_priv)->gen >= 8) {
+		dev->driver->irq_handler = gen8_irq_handler;
+		dev->driver->irq_preinstall = gen8_irq_reset;
+		dev->driver->irq_postinstall = gen8_irq_postinstall;
+		dev->driver->irq_uninstall = gen8_irq_uninstall;
+		dev->driver->enable_vblank = gen8_enable_vblank;
+		dev->driver->disable_vblank = gen8_disable_vblank;
+		if (IS_BROXTON(dev))
+			dev_priv->display.hpd_irq_setup = bxt_hpd_irq_setup;
+		else if (HAS_PCH_SPT(dev) || HAS_PCH_KBP(dev))
+			dev_priv->display.hpd_irq_setup = spt_hpd_irq_setup;
+		else
+			dev_priv->display.hpd_irq_setup = ilk_hpd_irq_setup;
+	} else if (HAS_PCH_SPLIT(dev)) {
+		dev->driver->irq_handler = ironlake_irq_handler;
+		dev->driver->irq_preinstall = ironlake_irq_reset;
+		dev->driver->irq_postinstall = ironlake_irq_postinstall;
+		dev->driver->irq_uninstall = ironlake_irq_uninstall;
+		dev->driver->enable_vblank = ironlake_enable_vblank;
+		dev->driver->disable_vblank = ironlake_disable_vblank;
+		dev_priv->display.hpd_irq_setup = ilk_hpd_irq_setup;
+	} else {
+		if (INTEL_INFO(dev_priv)->gen == 2) {
+			dev->driver->irq_preinstall = i8xx_irq_preinstall;
+			dev->driver->irq_postinstall = i8xx_irq_postinstall;
+			dev->driver->irq_handler = i8xx_irq_handler;
+			dev->driver->irq_uninstall = i8xx_irq_uninstall;
+		} else if (INTEL_INFO(dev_priv)->gen == 3) {
+			dev->driver->irq_preinstall = i915_irq_preinstall;
+			dev->driver->irq_postinstall = i915_irq_postinstall;
+			dev->driver->irq_uninstall = i915_irq_uninstall;
+			dev->driver->irq_handler = i915_irq_handler;
+		} else {
+			dev->driver->irq_preinstall = i965_irq_preinstall;
+			dev->driver->irq_postinstall = i965_irq_postinstall;
+			dev->driver->irq_uninstall = i965_irq_uninstall;
+			dev->driver->irq_handler = i965_irq_handler;
+		}
+		if (I915_HAS_HOTPLUG(dev_priv))
+			dev_priv->display.hpd_irq_setup = i915_hpd_irq_setup;
+		dev->driver->enable_vblank = i915_enable_vblank;
+		dev->driver->disable_vblank = i915_disable_vblank;
+	}
+}
+
+/**
+ * intel_irq_install - enables the hardware interrupt
+ * @dev_priv: i915 device instance
+ *
+ * This function enables the hardware interrupt handling, but leaves the hotplug
+ * handling still disabled. It is called after intel_irq_init().
+ *
+ * In the driver load and resume code we need working interrupts in a few places
+ * but don't want to deal with the hassle of concurrent probe and hotplug
+ * workers. Hence the split into this two-stage approach.
+ */
+int intel_irq_install(struct drm_i915_private *dev_priv)
+{
+	/*
+	 * We enable some interrupt sources in our postinstall hooks, so mark
+	 * interrupts as enabled _before_ actually enabling them to avoid
+	 * special cases in our ordering checks.
+	 */
+	dev_priv->pm.irqs_enabled = true;
+
+	return drm_irq_install(dev_priv->dev, dev_priv->dev->pdev->irq);
+}
+
+/**
+ * intel_irq_uninstall - finilizes all irq handling
+ * @dev_priv: i915 device instance
+ *
+ * This stops interrupt and hotplug handling and unregisters and frees all
+ * resources acquired in the init functions.
+ */
+void intel_irq_uninstall(struct drm_i915_private *dev_priv)
+{
+	drm_irq_uninstall(dev_priv->dev);
+	intel_hpd_cancel_work(dev_priv);
+	dev_priv->pm.irqs_enabled = false;
+}
+
+/**
+ * intel_runtime_pm_disable_interrupts - runtime interrupt disabling
+ * @dev_priv: i915 device instance
+ *
+ * This function is used to disable interrupts at runtime, both in the runtime
+ * pm and the system suspend/resume code.
+ */
+void intel_runtime_pm_disable_interrupts(struct drm_i915_private *dev_priv)
+{
+	dev_priv->dev->driver->irq_uninstall(dev_priv->dev);
+	dev_priv->pm.irqs_enabled = false;
+	synchronize_irq(dev_priv->dev->irq);
+}
+
+/**
+ * intel_runtime_pm_enable_interrupts - runtime interrupt enabling
+ * @dev_priv: i915 device instance
+ *
+ * This function is used to enable interrupts at runtime, both in the runtime
+ * pm and the system suspend/resume code.
+ */
+void intel_runtime_pm_enable_interrupts(struct drm_i915_private *dev_priv)
+{
+	dev_priv->pm.irqs_enabled = true;
+	dev_priv->dev->driver->irq_preinstall(dev_priv->dev);
+	dev_priv->dev->driver->irq_postinstall(dev_priv->dev);
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/i915/i915_params.c
@@ -0,0 +1,212 @@
+/*
+ * Copyright © 2014 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include "i915_params.h"
+#include "i915_drv.h"
+
+struct i915_params i915 __read_mostly = {
+	.modeset = -1,
+	.panel_ignore_lid = 1,
+	.semaphores = -1,
+	.lvds_channel_mode = 0,
+	.panel_use_ssc = -1,
+	.vbt_sdvo_panel_type = -1,
+	.enable_rc6 = -1,
+	.enable_dc = -1,
+	.enable_fbc = -1,
+	.enable_execlists = -1,
+	.enable_hangcheck = true,
+	.enable_ppgtt = -1,
+	.enable_psr = -1,
+	.preliminary_hw_support = IS_ENABLED(CONFIG_DRM_I915_PRELIMINARY_HW_SUPPORT),
+	.disable_power_well = -1,
+	.enable_ips = 1,
+	.fastboot = 0,
+	.prefault_disable = 0,
+	.load_detect_test = 0,
+	.reset = true,
+	.invert_brightness = 0,
+	.disable_display = 0,
+	.enable_cmd_parser = 1,
+	.use_mmio_flip = 0,
+	.mmio_debug = 0,
+	.verbose_state_checks = 1,
+	.nuclear_pageflip = 0,
+	.edp_vswing = 0,
+	.enable_guc_submission = false,
+	.guc_log_level = -1,
+	.enable_dp_mst = true,
+	.inject_load_failure = 0,
+};
+
+module_param_named(modeset, i915.modeset, int, 0400);
+MODULE_PARM_DESC(modeset,
+	"Use kernel modesetting [KMS] (0=disable, "
+	"1=on, -1=force vga console preference [default])");
+
+module_param_named_unsafe(panel_ignore_lid, i915.panel_ignore_lid, int, 0600);
+MODULE_PARM_DESC(panel_ignore_lid,
+	"Override lid status (0=autodetect, 1=autodetect disabled [default], "
+	"-1=force lid closed, -2=force lid open)");
+
+module_param_named_unsafe(semaphores, i915.semaphores, int, 0400);
+MODULE_PARM_DESC(semaphores,
+	"Use semaphores for inter-ring sync "
+	"(default: -1 (use per-chip defaults))");
+
+module_param_named_unsafe(enable_rc6, i915.enable_rc6, int, 0400);
+MODULE_PARM_DESC(enable_rc6,
+	"Enable power-saving render C-state 6. "
+	"Different stages can be selected via bitmask values "
+	"(0 = disable; 1 = enable rc6; 2 = enable deep rc6; 4 = enable deepest rc6). "
+	"For example, 3 would enable rc6 and deep rc6, and 7 would enable everything. "
+	"default: -1 (use per-chip default)");
+
+module_param_named_unsafe(enable_dc, i915.enable_dc, int, 0400);
+MODULE_PARM_DESC(enable_dc,
+	"Enable power-saving display C-states. "
+	"(-1=auto [default]; 0=disable; 1=up to DC5; 2=up to DC6)");
+
+module_param_named_unsafe(enable_fbc, i915.enable_fbc, int, 0600);
+MODULE_PARM_DESC(enable_fbc,
+	"Enable frame buffer compression for power savings "
+	"(default: -1 (use per-chip default))");
+
+module_param_named_unsafe(lvds_channel_mode, i915.lvds_channel_mode, int, 0400);
+MODULE_PARM_DESC(lvds_channel_mode,
+	 "Specify LVDS channel mode "
+	 "(0=probe BIOS [default], 1=single-channel, 2=dual-channel)");
+
+module_param_named_unsafe(lvds_use_ssc, i915.panel_use_ssc, int, 0600);
+MODULE_PARM_DESC(lvds_use_ssc,
+	"Use Spread Spectrum Clock with panels [LVDS/eDP] "
+	"(default: auto from VBT)");
+
+module_param_named_unsafe(vbt_sdvo_panel_type, i915.vbt_sdvo_panel_type, int, 0400);
+MODULE_PARM_DESC(vbt_sdvo_panel_type,
+	"Override/Ignore selection of SDVO panel mode in the VBT "
+	"(-2=ignore, -1=auto [default], index in VBT BIOS table)");
+
+module_param_named_unsafe(reset, i915.reset, bool, 0600);
+MODULE_PARM_DESC(reset, "Attempt GPU resets (default: true)");
+
+module_param_named_unsafe(enable_hangcheck, i915.enable_hangcheck, bool, 0644);
+MODULE_PARM_DESC(enable_hangcheck,
+	"Periodically check GPU activity for detecting hangs. "
+	"WARNING: Disabling this can cause system wide hangs. "
+	"(default: true)");
+
+module_param_named_unsafe(enable_ppgtt, i915.enable_ppgtt, int, 0400);
+MODULE_PARM_DESC(enable_ppgtt,
+	"Override PPGTT usage. "
+	"(-1=auto [default], 0=disabled, 1=aliasing, 2=full, 3=full with extended address space)");
+
+module_param_named_unsafe(enable_execlists, i915.enable_execlists, int, 0400);
+MODULE_PARM_DESC(enable_execlists,
+	"Override execlists usage. "
+	"(-1=auto [default], 0=disabled, 1=enabled)");
+
+module_param_named_unsafe(enable_psr, i915.enable_psr, int, 0600);
+MODULE_PARM_DESC(enable_psr, "Enable PSR "
+		 "(0=disabled, 1=enabled - link mode chosen per-platform, 2=force link-standby mode, 3=force link-off mode) "
+		 "Default: -1 (use per-chip default)");
+
+module_param_named_unsafe(preliminary_hw_support, i915.preliminary_hw_support, int, 0400);
+MODULE_PARM_DESC(preliminary_hw_support,
+	"Enable preliminary hardware support.");
+
+module_param_named_unsafe(disable_power_well, i915.disable_power_well, int, 0400);
+MODULE_PARM_DESC(disable_power_well,
+	"Disable display power wells when possible "
+	"(-1=auto [default], 0=power wells always on, 1=power wells disabled when possible)");
+
+module_param_named_unsafe(enable_ips, i915.enable_ips, int, 0600);
+MODULE_PARM_DESC(enable_ips, "Enable IPS (default: true)");
+
+module_param_named(fastboot, i915.fastboot, bool, 0600);
+MODULE_PARM_DESC(fastboot,
+	"Try to skip unnecessary mode sets at boot time (default: false)");
+
+module_param_named_unsafe(prefault_disable, i915.prefault_disable, bool, 0600);
+MODULE_PARM_DESC(prefault_disable,
+	"Disable page prefaulting for pread/pwrite/reloc (default:false). "
+	"For developers only.");
+
+module_param_named_unsafe(load_detect_test, i915.load_detect_test, bool, 0600);
+MODULE_PARM_DESC(load_detect_test,
+	"Force-enable the VGA load detect code for testing (default:false). "
+	"For developers only.");
+
+module_param_named_unsafe(invert_brightness, i915.invert_brightness, int, 0600);
+MODULE_PARM_DESC(invert_brightness,
+	"Invert backlight brightness "
+	"(-1 force normal, 0 machine defaults, 1 force inversion), please "
+	"report PCI device ID, subsystem vendor and subsystem device ID "
+	"to dri-devel@lists.freedesktop.org, if your machine needs it. "
+	"It will then be included in an upcoming module version.");
+
+module_param_named(disable_display, i915.disable_display, bool, 0400);
+MODULE_PARM_DESC(disable_display, "Disable display (default: false)");
+
+module_param_named_unsafe(enable_cmd_parser, i915.enable_cmd_parser, int, 0600);
+MODULE_PARM_DESC(enable_cmd_parser,
+		 "Enable command parsing (1=enabled [default], 0=disabled)");
+
+module_param_named_unsafe(use_mmio_flip, i915.use_mmio_flip, int, 0600);
+MODULE_PARM_DESC(use_mmio_flip,
+		 "use MMIO flips (-1=never, 0=driver discretion [default], 1=always)");
+
+module_param_named(mmio_debug, i915.mmio_debug, int, 0600);
+MODULE_PARM_DESC(mmio_debug,
+	"Enable the MMIO debug code for the first N failures (default: off). "
+	"This may negatively affect performance.");
+
+module_param_named(verbose_state_checks, i915.verbose_state_checks, bool, 0600);
+MODULE_PARM_DESC(verbose_state_checks,
+	"Enable verbose logs (ie. WARN_ON()) in case of unexpected hw state conditions.");
+
+module_param_named_unsafe(nuclear_pageflip, i915.nuclear_pageflip, bool, 0600);
+MODULE_PARM_DESC(nuclear_pageflip,
+		 "Force atomic modeset functionality; asynchronous mode is not yet supported. (default: false).");
+
+/* WA to get away with the default setting in VBT for early platforms.Will be removed */
+module_param_named_unsafe(edp_vswing, i915.edp_vswing, int, 0400);
+MODULE_PARM_DESC(edp_vswing,
+		 "Ignore/Override vswing pre-emph table selection from VBT "
+		 "(0=use value from vbt [default], 1=low power swing(200mV),"
+		 "2=default swing(400mV))");
+
+module_param_named_unsafe(enable_guc_submission, i915.enable_guc_submission, bool, 0400);
+MODULE_PARM_DESC(enable_guc_submission, "Enable GuC submission (default:false)");
+
+module_param_named(guc_log_level, i915.guc_log_level, int, 0400);
+MODULE_PARM_DESC(guc_log_level,
+	"GuC firmware logging level (-1:disabled (default), 0-3:enabled)");
+
+module_param_named_unsafe(enable_dp_mst, i915.enable_dp_mst, bool, 0600);
+MODULE_PARM_DESC(enable_dp_mst,
+	"Enable multi-stream transport (MST) for new DisplayPort sinks. (default: true)");
+module_param_named_unsafe(inject_load_failure, i915.inject_load_failure, uint, 0400);
+MODULE_PARM_DESC(inject_load_failure,
+	"Force an error after a number of failure check points (0:disabled (default), N:force failure at the Nth failure check point)");
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/i915/i915_params.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright © 2015 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ */
+
+#ifndef _I915_PARAMS_H_
+#define _I915_PARAMS_H_
+
+#include <linux/cache.h> /* for __read_mostly */
+
+struct i915_params {
+	int modeset;
+	int panel_ignore_lid;
+	int semaphores;
+	int lvds_channel_mode;
+	int panel_use_ssc;
+	int vbt_sdvo_panel_type;
+	int enable_rc6;
+	int enable_dc;
+	int enable_fbc;
+	int enable_ppgtt;
+	int enable_execlists;
+	int enable_psr;
+	unsigned int preliminary_hw_support;
+	int disable_power_well;
+	int enable_ips;
+	int invert_brightness;
+	int enable_cmd_parser;
+	int guc_log_level;
+	int use_mmio_flip;
+	int mmio_debug;
+	int edp_vswing;
+	unsigned int inject_load_failure;
+	/* leave bools at the end to not create holes */
+	bool enable_hangcheck;
+	bool fastboot;
+	bool prefault_disable;
+	bool load_detect_test;
+	bool reset;
+	bool disable_display;
+	bool enable_guc_submission;
+	bool verbose_state_checks;
+	bool nuclear_pageflip;
+	bool enable_dp_mst;
+};
+
+extern struct i915_params i915 __read_mostly;
+
+#endif
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/i915/i915_reg.h
@@ -0,0 +1,8359 @@
+/* Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef _I915_REG_H_
+#define _I915_REG_H_
+
+typedef struct {
+	uint32_t reg;
+} i915_reg_t;
+
+#define _MMIO(r) ((const i915_reg_t){ .reg = (r) })
+
+#define INVALID_MMIO_REG _MMIO(0)
+
+static inline uint32_t i915_mmio_reg_offset(i915_reg_t reg)
+{
+	return reg.reg;
+}
+
+static inline bool i915_mmio_reg_equal(i915_reg_t a, i915_reg_t b)
+{
+	return i915_mmio_reg_offset(a) == i915_mmio_reg_offset(b);
+}
+
+static inline bool i915_mmio_reg_valid(i915_reg_t reg)
+{
+	return !i915_mmio_reg_equal(reg, INVALID_MMIO_REG);
+}
+
+#define _PIPE(pipe, a, b) ((a) + (pipe)*((b)-(a)))
+#define _MMIO_PIPE(pipe, a, b) _MMIO(_PIPE(pipe, a, b))
+#define _PLANE(plane, a, b) _PIPE(plane, a, b)
+#define _MMIO_PLANE(plane, a, b) _MMIO_PIPE(plane, a, b)
+#define _TRANS(tran, a, b) ((a) + (tran)*((b)-(a)))
+#define _MMIO_TRANS(tran, a, b) _MMIO(_TRANS(tran, a, b))
+#define _PORT(port, a, b) ((a) + (port)*((b)-(a)))
+#define _MMIO_PORT(port, a, b) _MMIO(_PORT(port, a, b))
+#define _PIPE3(pipe, a, b, c) ((pipe) == PIPE_A ? (a) : \
+			       (pipe) == PIPE_B ? (b) : (c))
+#define _MMIO_PIPE3(pipe, a, b, c) _MMIO(_PIPE3(pipe, a, b, c))
+#define _PORT3(port, a, b, c) ((port) == PORT_A ? (a) : \
+			       (port) == PORT_B ? (b) : (c))
+#define _MMIO_PORT3(pipe, a, b, c) _MMIO(_PORT3(pipe, a, b, c))
+
+#define _MASKED_FIELD(mask, value) ({					   \
+	if (__builtin_constant_p(mask))					   \
+		BUILD_BUG_ON_MSG(((mask) & 0xffff0000), "Incorrect mask"); \
+	if (__builtin_constant_p(value))				   \
+		BUILD_BUG_ON_MSG((value) & 0xffff0000, "Incorrect value"); \
+	if (__builtin_constant_p(mask) && __builtin_constant_p(value))	   \
+		BUILD_BUG_ON_MSG((value) & ~(mask),			   \
+				 "Incorrect value for mask");		   \
+	(mask) << 16 | (value); })
+#define _MASKED_BIT_ENABLE(a)	({ typeof(a) _a = (a); _MASKED_FIELD(_a, _a); })
+#define _MASKED_BIT_DISABLE(a)	(_MASKED_FIELD((a), 0))
+
+
+
+/* PCI config space */
+
+#define MCHBAR_I915 0x44
+#define MCHBAR_I965 0x48
+#define MCHBAR_SIZE (4 * 4096)
+
+#define DEVEN 0x54
+#define   DEVEN_MCHBAR_EN (1 << 28)
+
+#define BSM 0x5c
+#define   BSM_MASK (0xFFFF << 20)
+
+#define HPLLCC	0xc0 /* 85x only */
+#define   GC_CLOCK_CONTROL_MASK		(0x7 << 0)
+#define   GC_CLOCK_133_200		(0 << 0)
+#define   GC_CLOCK_100_200		(1 << 0)
+#define   GC_CLOCK_100_133		(2 << 0)
+#define   GC_CLOCK_133_266		(3 << 0)
+#define   GC_CLOCK_133_200_2		(4 << 0)
+#define   GC_CLOCK_133_266_2		(5 << 0)
+#define   GC_CLOCK_166_266		(6 << 0)
+#define   GC_CLOCK_166_250		(7 << 0)
+
+#define I915_GDRST 0xc0 /* PCI config register */
+#define   GRDOM_FULL		(0 << 2)
+#define   GRDOM_RENDER		(1 << 2)
+#define   GRDOM_MEDIA		(3 << 2)
+#define   GRDOM_MASK		(3 << 2)
+#define   GRDOM_RESET_STATUS	(1 << 1)
+#define   GRDOM_RESET_ENABLE	(1 << 0)
+
+#define GCDGMBUS 0xcc
+
+#define GCFGC2	0xda
+#define GCFGC	0xf0 /* 915+ only */
+#define   GC_LOW_FREQUENCY_ENABLE	(1 << 7)
+#define   GC_DISPLAY_CLOCK_190_200_MHZ	(0 << 4)
+#define   GC_DISPLAY_CLOCK_333_MHZ	(4 << 4)
+#define   GC_DISPLAY_CLOCK_267_MHZ_PNV	(0 << 4)
+#define   GC_DISPLAY_CLOCK_333_MHZ_PNV	(1 << 4)
+#define   GC_DISPLAY_CLOCK_444_MHZ_PNV	(2 << 4)
+#define   GC_DISPLAY_CLOCK_200_MHZ_PNV	(5 << 4)
+#define   GC_DISPLAY_CLOCK_133_MHZ_PNV	(6 << 4)
+#define   GC_DISPLAY_CLOCK_167_MHZ_PNV	(7 << 4)
+#define   GC_DISPLAY_CLOCK_MASK		(7 << 4)
+#define   GM45_GC_RENDER_CLOCK_MASK	(0xf << 0)
+#define   GM45_GC_RENDER_CLOCK_266_MHZ	(8 << 0)
+#define   GM45_GC_RENDER_CLOCK_320_MHZ	(9 << 0)
+#define   GM45_GC_RENDER_CLOCK_400_MHZ	(0xb << 0)
+#define   GM45_GC_RENDER_CLOCK_533_MHZ	(0xc << 0)
+#define   I965_GC_RENDER_CLOCK_MASK	(0xf << 0)
+#define   I965_GC_RENDER_CLOCK_267_MHZ	(2 << 0)
+#define   I965_GC_RENDER_CLOCK_333_MHZ	(3 << 0)
+#define   I965_GC_RENDER_CLOCK_444_MHZ	(4 << 0)
+#define   I965_GC_RENDER_CLOCK_533_MHZ	(5 << 0)
+#define   I945_GC_RENDER_CLOCK_MASK	(7 << 0)
+#define   I945_GC_RENDER_CLOCK_166_MHZ	(0 << 0)
+#define   I945_GC_RENDER_CLOCK_200_MHZ	(1 << 0)
+#define   I945_GC_RENDER_CLOCK_250_MHZ	(3 << 0)
+#define   I945_GC_RENDER_CLOCK_400_MHZ	(5 << 0)
+#define   I915_GC_RENDER_CLOCK_MASK	(7 << 0)
+#define   I915_GC_RENDER_CLOCK_166_MHZ	(0 << 0)
+#define   I915_GC_RENDER_CLOCK_200_MHZ	(1 << 0)
+#define   I915_GC_RENDER_CLOCK_333_MHZ	(4 << 0)
+
+#define ASLE	0xe4
+#define ASLS	0xfc
+
+#define SWSCI	0xe8
+#define   SWSCI_SCISEL	(1 << 15)
+#define   SWSCI_GSSCIE	(1 << 0)
+
+#define LBPC 0xf4 /* legacy/combination backlight modes, also called LBB */
+
+
+#define ILK_GDSR _MMIO(MCHBAR_MIRROR_BASE + 0x2ca4)
+#define  ILK_GRDOM_FULL		(0<<1)
+#define  ILK_GRDOM_RENDER	(1<<1)
+#define  ILK_GRDOM_MEDIA	(3<<1)
+#define  ILK_GRDOM_MASK		(3<<1)
+#define  ILK_GRDOM_RESET_ENABLE (1<<0)
+
+#define GEN6_MBCUNIT_SNPCR	_MMIO(0x900c) /* for LLC config */
+#define   GEN6_MBC_SNPCR_SHIFT	21
+#define   GEN6_MBC_SNPCR_MASK	(3<<21)
+#define   GEN6_MBC_SNPCR_MAX	(0<<21)
+#define   GEN6_MBC_SNPCR_MED	(1<<21)
+#define   GEN6_MBC_SNPCR_LOW	(2<<21)
+#define   GEN6_MBC_SNPCR_MIN	(3<<21) /* only 1/16th of the cache is shared */
+
+#define VLV_G3DCTL		_MMIO(0x9024)
+#define VLV_GSCKGCTL		_MMIO(0x9028)
+
+#define GEN6_MBCTL		_MMIO(0x0907c)
+#define   GEN6_MBCTL_ENABLE_BOOT_FETCH	(1 << 4)
+#define   GEN6_MBCTL_CTX_FETCH_NEEDED	(1 << 3)
+#define   GEN6_MBCTL_BME_UPDATE_ENABLE	(1 << 2)
+#define   GEN6_MBCTL_MAE_UPDATE_ENABLE	(1 << 1)
+#define   GEN6_MBCTL_BOOT_FETCH_MECH	(1 << 0)
+
+#define GEN6_GDRST	_MMIO(0x941c)
+#define  GEN6_GRDOM_FULL		(1 << 0)
+#define  GEN6_GRDOM_RENDER		(1 << 1)
+#define  GEN6_GRDOM_MEDIA		(1 << 2)
+#define  GEN6_GRDOM_BLT			(1 << 3)
+#define  GEN6_GRDOM_VECS		(1 << 4)
+#define  GEN9_GRDOM_GUC			(1 << 5)
+#define  GEN8_GRDOM_MEDIA2		(1 << 7)
+
+#define RING_PP_DIR_BASE(ring)		_MMIO((ring)->mmio_base+0x228)
+#define RING_PP_DIR_BASE_READ(ring)	_MMIO((ring)->mmio_base+0x518)
+#define RING_PP_DIR_DCLV(ring)		_MMIO((ring)->mmio_base+0x220)
+#define   PP_DIR_DCLV_2G		0xffffffff
+
+#define GEN8_RING_PDP_UDW(ring, n)	_MMIO((ring)->mmio_base+0x270 + (n) * 8 + 4)
+#define GEN8_RING_PDP_LDW(ring, n)	_MMIO((ring)->mmio_base+0x270 + (n) * 8)
+
+#define GEN8_R_PWR_CLK_STATE		_MMIO(0x20C8)
+#define   GEN8_RPCS_ENABLE		(1 << 31)
+#define   GEN8_RPCS_S_CNT_ENABLE	(1 << 18)
+#define   GEN8_RPCS_S_CNT_SHIFT		15
+#define   GEN8_RPCS_S_CNT_MASK		(0x7 << GEN8_RPCS_S_CNT_SHIFT)
+#define   GEN8_RPCS_SS_CNT_ENABLE	(1 << 11)
+#define   GEN8_RPCS_SS_CNT_SHIFT	8
+#define   GEN8_RPCS_SS_CNT_MASK		(0x7 << GEN8_RPCS_SS_CNT_SHIFT)
+#define   GEN8_RPCS_EU_MAX_SHIFT	4
+#define   GEN8_RPCS_EU_MAX_MASK		(0xf << GEN8_RPCS_EU_MAX_SHIFT)
+#define   GEN8_RPCS_EU_MIN_SHIFT	0
+#define   GEN8_RPCS_EU_MIN_MASK		(0xf << GEN8_RPCS_EU_MIN_SHIFT)
+
+#define GAM_ECOCHK			_MMIO(0x4090)
+#define   BDW_DISABLE_HDC_INVALIDATION	(1<<25)
+#define   ECOCHK_SNB_BIT		(1<<10)
+#define   ECOCHK_DIS_TLB		(1<<8)
+#define   HSW_ECOCHK_ARB_PRIO_SOL	(1<<6)
+#define   ECOCHK_PPGTT_CACHE64B		(0x3<<3)
+#define   ECOCHK_PPGTT_CACHE4B		(0x0<<3)
+#define   ECOCHK_PPGTT_GFDT_IVB		(0x1<<4)
+#define   ECOCHK_PPGTT_LLC_IVB		(0x1<<3)
+#define   ECOCHK_PPGTT_UC_HSW		(0x1<<3)
+#define   ECOCHK_PPGTT_WT_HSW		(0x2<<3)
+#define   ECOCHK_PPGTT_WB_HSW		(0x3<<3)
+
+#define GEN8_CONFIG0			_MMIO(0xD00)
+#define  GEN9_DEFAULT_FIXES		(1 << 3 | 1 << 2 | 1 << 1)
+
+#define GAC_ECO_BITS			_MMIO(0x14090)
+#define   ECOBITS_SNB_BIT		(1<<13)
+#define   ECOBITS_PPGTT_CACHE64B	(3<<8)
+#define   ECOBITS_PPGTT_CACHE4B		(0<<8)
+
+#define GAB_CTL				_MMIO(0x24000)
+#define   GAB_CTL_CONT_AFTER_PAGEFAULT	(1<<8)
+
+#define GEN6_STOLEN_RESERVED		_MMIO(0x1082C0)
+#define GEN6_STOLEN_RESERVED_ADDR_MASK	(0xFFF << 20)
+#define GEN7_STOLEN_RESERVED_ADDR_MASK	(0x3FFF << 18)
+#define GEN6_STOLEN_RESERVED_SIZE_MASK	(3 << 4)
+#define GEN6_STOLEN_RESERVED_1M		(0 << 4)
+#define GEN6_STOLEN_RESERVED_512K	(1 << 4)
+#define GEN6_STOLEN_RESERVED_256K	(2 << 4)
+#define GEN6_STOLEN_RESERVED_128K	(3 << 4)
+#define GEN7_STOLEN_RESERVED_SIZE_MASK	(1 << 5)
+#define GEN7_STOLEN_RESERVED_1M		(0 << 5)
+#define GEN7_STOLEN_RESERVED_256K	(1 << 5)
+#define GEN8_STOLEN_RESERVED_SIZE_MASK	(3 << 7)
+#define GEN8_STOLEN_RESERVED_1M		(0 << 7)
+#define GEN8_STOLEN_RESERVED_2M		(1 << 7)
+#define GEN8_STOLEN_RESERVED_4M		(2 << 7)
+#define GEN8_STOLEN_RESERVED_8M		(3 << 7)
+
+/* VGA stuff */
+
+#define VGA_ST01_MDA 0x3ba
+#define VGA_ST01_CGA 0x3da
+
+#define _VGA_MSR_WRITE _MMIO(0x3c2)
+#define VGA_MSR_WRITE 0x3c2
+#define VGA_MSR_READ 0x3cc
+#define   VGA_MSR_MEM_EN (1<<1)
+#define   VGA_MSR_CGA_MODE (1<<0)
+
+#define VGA_SR_INDEX 0x3c4
+#define SR01			1
+#define VGA_SR_DATA 0x3c5
+
+#define VGA_AR_INDEX 0x3c0
+#define   VGA_AR_VID_EN (1<<5)
+#define VGA_AR_DATA_WRITE 0x3c0
+#define VGA_AR_DATA_READ 0x3c1
+
+#define VGA_GR_INDEX 0x3ce
+#define VGA_GR_DATA 0x3cf
+/* GR05 */
+#define   VGA_GR_MEM_READ_MODE_SHIFT 3
+#define     VGA_GR_MEM_READ_MODE_PLANE 1
+/* GR06 */
+#define   VGA_GR_MEM_MODE_MASK 0xc
+#define   VGA_GR_MEM_MODE_SHIFT 2
+#define   VGA_GR_MEM_A0000_AFFFF 0
+#define   VGA_GR_MEM_A0000_BFFFF 1
+#define   VGA_GR_MEM_B0000_B7FFF 2
+#define   VGA_GR_MEM_B0000_BFFFF 3
+
+#define VGA_DACMASK 0x3c6
+#define VGA_DACRX 0x3c7
+#define VGA_DACWX 0x3c8
+#define VGA_DACDATA 0x3c9
+
+#define VGA_CR_INDEX_MDA 0x3b4
+#define VGA_CR_DATA_MDA 0x3b5
+#define VGA_CR_INDEX_CGA 0x3d4
+#define VGA_CR_DATA_CGA 0x3d5
+
+/*
+ * Instruction field definitions used by the command parser
+ */
+#define INSTR_CLIENT_SHIFT      29
+#define INSTR_CLIENT_MASK       0xE0000000
+#define   INSTR_MI_CLIENT       0x0
+#define   INSTR_BC_CLIENT       0x2
+#define   INSTR_RC_CLIENT       0x3
+#define INSTR_SUBCLIENT_SHIFT   27
+#define INSTR_SUBCLIENT_MASK    0x18000000
+#define   INSTR_MEDIA_SUBCLIENT 0x2
+#define INSTR_26_TO_24_MASK	0x7000000
+#define   INSTR_26_TO_24_SHIFT	24
+
+/*
+ * Memory interface instructions used by the kernel
+ */
+#define MI_INSTR(opcode, flags) (((opcode) << 23) | (flags))
+/* Many MI commands use bit 22 of the header dword for GGTT vs PPGTT */
+#define  MI_GLOBAL_GTT    (1<<22)
+
+#define MI_NOOP			MI_INSTR(0, 0)
+#define MI_USER_INTERRUPT	MI_INSTR(0x02, 0)
+#define MI_WAIT_FOR_EVENT       MI_INSTR(0x03, 0)
+#define   MI_WAIT_FOR_OVERLAY_FLIP	(1<<16)
+#define   MI_WAIT_FOR_PLANE_B_FLIP      (1<<6)
+#define   MI_WAIT_FOR_PLANE_A_FLIP      (1<<2)
+#define   MI_WAIT_FOR_PLANE_A_SCANLINES (1<<1)
+#define MI_FLUSH		MI_INSTR(0x04, 0)
+#define   MI_READ_FLUSH		(1 << 0)
+#define   MI_EXE_FLUSH		(1 << 1)
+#define   MI_NO_WRITE_FLUSH	(1 << 2)
+#define   MI_SCENE_COUNT	(1 << 3) /* just increment scene count */
+#define   MI_END_SCENE		(1 << 4) /* flush binner and incr scene count */
+#define   MI_INVALIDATE_ISP	(1 << 5) /* invalidate indirect state pointers */
+#define MI_REPORT_HEAD		MI_INSTR(0x07, 0)
+#define MI_ARB_ON_OFF		MI_INSTR(0x08, 0)
+#define   MI_ARB_ENABLE			(1<<0)
+#define   MI_ARB_DISABLE		(0<<0)
+#define MI_BATCH_BUFFER_END	MI_INSTR(0x0a, 0)
+#define MI_SUSPEND_FLUSH	MI_INSTR(0x0b, 0)
+#define   MI_SUSPEND_FLUSH_EN	(1<<0)
+#define MI_SET_APPID		MI_INSTR(0x0e, 0)
+#define MI_OVERLAY_FLIP		MI_INSTR(0x11, 0)
+#define   MI_OVERLAY_CONTINUE	(0x0<<21)
+#define   MI_OVERLAY_ON		(0x1<<21)
+#define   MI_OVERLAY_OFF	(0x2<<21)
+#define MI_LOAD_SCAN_LINES_INCL MI_INSTR(0x12, 0)
+#define MI_DISPLAY_FLIP		MI_INSTR(0x14, 2)
+#define MI_DISPLAY_FLIP_I915	MI_INSTR(0x14, 1)
+#define   MI_DISPLAY_FLIP_PLANE(n) ((n) << 20)
+/* IVB has funny definitions for which plane to flip. */
+#define   MI_DISPLAY_FLIP_IVB_PLANE_A  (0 << 19)
+#define   MI_DISPLAY_FLIP_IVB_PLANE_B  (1 << 19)
+#define   MI_DISPLAY_FLIP_IVB_SPRITE_A (2 << 19)
+#define   MI_DISPLAY_FLIP_IVB_SPRITE_B (3 << 19)
+#define   MI_DISPLAY_FLIP_IVB_PLANE_C  (4 << 19)
+#define   MI_DISPLAY_FLIP_IVB_SPRITE_C (5 << 19)
+/* SKL ones */
+#define   MI_DISPLAY_FLIP_SKL_PLANE_1_A	(0 << 8)
+#define   MI_DISPLAY_FLIP_SKL_PLANE_1_B	(1 << 8)
+#define   MI_DISPLAY_FLIP_SKL_PLANE_1_C	(2 << 8)
+#define   MI_DISPLAY_FLIP_SKL_PLANE_2_A	(4 << 8)
+#define   MI_DISPLAY_FLIP_SKL_PLANE_2_B	(5 << 8)
+#define   MI_DISPLAY_FLIP_SKL_PLANE_2_C	(6 << 8)
+#define   MI_DISPLAY_FLIP_SKL_PLANE_3_A	(7 << 8)
+#define   MI_DISPLAY_FLIP_SKL_PLANE_3_B	(8 << 8)
+#define   MI_DISPLAY_FLIP_SKL_PLANE_3_C	(9 << 8)
+#define MI_SEMAPHORE_MBOX	MI_INSTR(0x16, 1) /* gen6, gen7 */
+#define   MI_SEMAPHORE_GLOBAL_GTT    (1<<22)
+#define   MI_SEMAPHORE_UPDATE	    (1<<21)
+#define   MI_SEMAPHORE_COMPARE	    (1<<20)
+#define   MI_SEMAPHORE_REGISTER	    (1<<18)
+#define   MI_SEMAPHORE_SYNC_VR	    (0<<16) /* RCS  wait for VCS  (RVSYNC) */
+#define   MI_SEMAPHORE_SYNC_VER	    (1<<16) /* RCS  wait for VECS (RVESYNC) */
+#define   MI_SEMAPHORE_SYNC_BR	    (2<<16) /* RCS  wait for BCS  (RBSYNC) */
+#define   MI_SEMAPHORE_SYNC_BV	    (0<<16) /* VCS  wait for BCS  (VBSYNC) */
+#define   MI_SEMAPHORE_SYNC_VEV	    (1<<16) /* VCS  wait for VECS (VVESYNC) */
+#define   MI_SEMAPHORE_SYNC_RV	    (2<<16) /* VCS  wait for RCS  (VRSYNC) */
+#define   MI_SEMAPHORE_SYNC_RB	    (0<<16) /* BCS  wait for RCS  (BRSYNC) */
+#define   MI_SEMAPHORE_SYNC_VEB	    (1<<16) /* BCS  wait for VECS (BVESYNC) */
+#define   MI_SEMAPHORE_SYNC_VB	    (2<<16) /* BCS  wait for VCS  (BVSYNC) */
+#define   MI_SEMAPHORE_SYNC_BVE	    (0<<16) /* VECS wait for BCS  (VEBSYNC) */
+#define   MI_SEMAPHORE_SYNC_VVE	    (1<<16) /* VECS wait for VCS  (VEVSYNC) */
+#define   MI_SEMAPHORE_SYNC_RVE	    (2<<16) /* VECS wait for RCS  (VERSYNC) */
+#define   MI_SEMAPHORE_SYNC_INVALID (3<<16)
+#define   MI_SEMAPHORE_SYNC_MASK    (3<<16)
+#define MI_SET_CONTEXT		MI_INSTR(0x18, 0)
+#define   MI_MM_SPACE_GTT		(1<<8)
+#define   MI_MM_SPACE_PHYSICAL		(0<<8)
+#define   MI_SAVE_EXT_STATE_EN		(1<<3)
+#define   MI_RESTORE_EXT_STATE_EN	(1<<2)
+#define   MI_FORCE_RESTORE		(1<<1)
+#define   MI_RESTORE_INHIBIT		(1<<0)
+#define   HSW_MI_RS_SAVE_STATE_EN       (1<<3)
+#define   HSW_MI_RS_RESTORE_STATE_EN    (1<<2)
+#define MI_SEMAPHORE_SIGNAL	MI_INSTR(0x1b, 0) /* GEN8+ */
+#define   MI_SEMAPHORE_TARGET(engine)	((engine)<<15)
+#define MI_SEMAPHORE_WAIT	MI_INSTR(0x1c, 2) /* GEN8+ */
+#define   MI_SEMAPHORE_POLL		(1<<15)
+#define   MI_SEMAPHORE_SAD_GTE_SDD	(1<<12)
+#define MI_STORE_DWORD_IMM	MI_INSTR(0x20, 1)
+#define MI_STORE_DWORD_IMM_GEN4	MI_INSTR(0x20, 2)
+#define   MI_MEM_VIRTUAL	(1 << 22) /* 945,g33,965 */
+#define   MI_USE_GGTT		(1 << 22) /* g4x+ */
+#define MI_STORE_DWORD_INDEX	MI_INSTR(0x21, 1)
+#define   MI_STORE_DWORD_INDEX_SHIFT 2
+/* Official intel docs are somewhat sloppy concerning MI_LOAD_REGISTER_IMM:
+ * - Always issue a MI_NOOP _before_ the MI_LOAD_REGISTER_IMM - otherwise hw
+ *   simply ignores the register load under certain conditions.
+ * - One can actually load arbitrary many arbitrary registers: Simply issue x
+ *   address/value pairs. Don't overdue it, though, x <= 2^4 must hold!
+ */
+#define MI_LOAD_REGISTER_IMM(x)	MI_INSTR(0x22, 2*(x)-1)
+#define   MI_LRI_FORCE_POSTED		(1<<12)
+#define MI_STORE_REGISTER_MEM        MI_INSTR(0x24, 1)
+#define MI_STORE_REGISTER_MEM_GEN8   MI_INSTR(0x24, 2)
+#define   MI_SRM_LRM_GLOBAL_GTT		(1<<22)
+#define MI_FLUSH_DW		MI_INSTR(0x26, 1) /* for GEN6 */
+#define   MI_FLUSH_DW_STORE_INDEX	(1<<21)
+#define   MI_INVALIDATE_TLB		(1<<18)
+#define   MI_FLUSH_DW_OP_STOREDW	(1<<14)
+#define   MI_FLUSH_DW_OP_MASK		(3<<14)
+#define   MI_FLUSH_DW_NOTIFY		(1<<8)
+#define   MI_INVALIDATE_BSD		(1<<7)
+#define   MI_FLUSH_DW_USE_GTT		(1<<2)
+#define   MI_FLUSH_DW_USE_PPGTT		(0<<2)
+#define MI_LOAD_REGISTER_MEM	   MI_INSTR(0x29, 1)
+#define MI_LOAD_REGISTER_MEM_GEN8  MI_INSTR(0x29, 2)
+#define MI_BATCH_BUFFER		MI_INSTR(0x30, 1)
+#define   MI_BATCH_NON_SECURE		(1)
+/* for snb/ivb/vlv this also means "batch in ppgtt" when ppgtt is enabled. */
+#define   MI_BATCH_NON_SECURE_I965	(1<<8)
+#define   MI_BATCH_PPGTT_HSW		(1<<8)
+#define   MI_BATCH_NON_SECURE_HSW	(1<<13)
+#define MI_BATCH_BUFFER_START	MI_INSTR(0x31, 0)
+#define   MI_BATCH_GTT		    (2<<6) /* aliased with (1<<7) on gen4 */
+#define MI_BATCH_BUFFER_START_GEN8	MI_INSTR(0x31, 1)
+#define   MI_BATCH_RESOURCE_STREAMER (1<<10)
+
+#define MI_PREDICATE_SRC0	_MMIO(0x2400)
+#define MI_PREDICATE_SRC0_UDW	_MMIO(0x2400 + 4)
+#define MI_PREDICATE_SRC1	_MMIO(0x2408)
+#define MI_PREDICATE_SRC1_UDW	_MMIO(0x2408 + 4)
+
+#define MI_PREDICATE_RESULT_2	_MMIO(0x2214)
+#define  LOWER_SLICE_ENABLED	(1<<0)
+#define  LOWER_SLICE_DISABLED	(0<<0)
+
+/*
+ * 3D instructions used by the kernel
+ */
+#define GFX_INSTR(opcode, flags) ((0x3 << 29) | ((opcode) << 24) | (flags))
+
+#define GFX_OP_RASTER_RULES    ((0x3<<29)|(0x7<<24))
+#define GFX_OP_SCISSOR         ((0x3<<29)|(0x1c<<24)|(0x10<<19))
+#define   SC_UPDATE_SCISSOR       (0x1<<1)
+#define   SC_ENABLE_MASK          (0x1<<0)
+#define   SC_ENABLE               (0x1<<0)
+#define GFX_OP_LOAD_INDIRECT   ((0x3<<29)|(0x1d<<24)|(0x7<<16))
+#define GFX_OP_SCISSOR_INFO    ((0x3<<29)|(0x1d<<24)|(0x81<<16)|(0x1))
+#define   SCI_YMIN_MASK      (0xffff<<16)
+#define   SCI_XMIN_MASK      (0xffff<<0)
+#define   SCI_YMAX_MASK      (0xffff<<16)
+#define   SCI_XMAX_MASK      (0xffff<<0)
+#define GFX_OP_SCISSOR_ENABLE	 ((0x3<<29)|(0x1c<<24)|(0x10<<19))
+#define GFX_OP_SCISSOR_RECT	 ((0x3<<29)|(0x1d<<24)|(0x81<<16)|1)
+#define GFX_OP_COLOR_FACTOR      ((0x3<<29)|(0x1d<<24)|(0x1<<16)|0x0)
+#define GFX_OP_STIPPLE           ((0x3<<29)|(0x1d<<24)|(0x83<<16))
+#define GFX_OP_MAP_INFO          ((0x3<<29)|(0x1d<<24)|0x4)
+#define GFX_OP_DESTBUFFER_VARS   ((0x3<<29)|(0x1d<<24)|(0x85<<16)|0x0)
+#define GFX_OP_DESTBUFFER_INFO	 ((0x3<<29)|(0x1d<<24)|(0x8e<<16)|1)
+#define GFX_OP_DRAWRECT_INFO     ((0x3<<29)|(0x1d<<24)|(0x80<<16)|(0x3))
+#define GFX_OP_DRAWRECT_INFO_I965  ((0x7900<<16)|0x2)
+
+#define COLOR_BLT_CMD			(2<<29 | 0x40<<22 | (5-2))
+#define SRC_COPY_BLT_CMD		((2<<29)|(0x43<<22)|4)
+#define XY_SRC_COPY_BLT_CMD		((2<<29)|(0x53<<22)|6)
+#define XY_MONO_SRC_COPY_IMM_BLT	((2<<29)|(0x71<<22)|5)
+#define   BLT_WRITE_A			(2<<20)
+#define   BLT_WRITE_RGB			(1<<20)
+#define   BLT_WRITE_RGBA		(BLT_WRITE_RGB | BLT_WRITE_A)
+#define   BLT_DEPTH_8			(0<<24)
+#define   BLT_DEPTH_16_565		(1<<24)
+#define   BLT_DEPTH_16_1555		(2<<24)
+#define   BLT_DEPTH_32			(3<<24)
+#define   BLT_ROP_SRC_COPY		(0xcc<<16)
+#define   BLT_ROP_COLOR_COPY		(0xf0<<16)
+#define XY_SRC_COPY_BLT_SRC_TILED	(1<<15) /* 965+ only */
+#define XY_SRC_COPY_BLT_DST_TILED	(1<<11) /* 965+ only */
+#define CMD_OP_DISPLAYBUFFER_INFO ((0x0<<29)|(0x14<<23)|2)
+#define   ASYNC_FLIP                (1<<22)
+#define   DISPLAY_PLANE_A           (0<<20)
+#define   DISPLAY_PLANE_B           (1<<20)
+#define GFX_OP_PIPE_CONTROL(len)	((0x3<<29)|(0x3<<27)|(0x2<<24)|((len)-2))
+#define   PIPE_CONTROL_FLUSH_L3				(1<<27)
+#define   PIPE_CONTROL_GLOBAL_GTT_IVB			(1<<24) /* gen7+ */
+#define   PIPE_CONTROL_MMIO_WRITE			(1<<23)
+#define   PIPE_CONTROL_STORE_DATA_INDEX			(1<<21)
+#define   PIPE_CONTROL_CS_STALL				(1<<20)
+#define   PIPE_CONTROL_TLB_INVALIDATE			(1<<18)
+#define   PIPE_CONTROL_MEDIA_STATE_CLEAR		(1<<16)
+#define   PIPE_CONTROL_QW_WRITE				(1<<14)
+#define   PIPE_CONTROL_POST_SYNC_OP_MASK                (3<<14)
+#define   PIPE_CONTROL_DEPTH_STALL			(1<<13)
+#define   PIPE_CONTROL_WRITE_FLUSH			(1<<12)
+#define   PIPE_CONTROL_RENDER_TARGET_CACHE_FLUSH	(1<<12) /* gen6+ */
+#define   PIPE_CONTROL_INSTRUCTION_CACHE_INVALIDATE	(1<<11) /* MBZ on Ironlake */
+#define   PIPE_CONTROL_TEXTURE_CACHE_INVALIDATE		(1<<10) /* GM45+ only */
+#define   PIPE_CONTROL_INDIRECT_STATE_DISABLE		(1<<9)
+#define   PIPE_CONTROL_NOTIFY				(1<<8)
+#define   PIPE_CONTROL_FLUSH_ENABLE			(1<<7) /* gen7+ */
+#define   PIPE_CONTROL_DC_FLUSH_ENABLE			(1<<5)
+#define   PIPE_CONTROL_VF_CACHE_INVALIDATE		(1<<4)
+#define   PIPE_CONTROL_CONST_CACHE_INVALIDATE		(1<<3)
+#define   PIPE_CONTROL_STATE_CACHE_INVALIDATE		(1<<2)
+#define   PIPE_CONTROL_STALL_AT_SCOREBOARD		(1<<1)
+#define   PIPE_CONTROL_DEPTH_CACHE_FLUSH		(1<<0)
+#define   PIPE_CONTROL_GLOBAL_GTT (1<<2) /* in addr dword */
+
+/*
+ * Commands used only by the command parser
+ */
+#define MI_SET_PREDICATE        MI_INSTR(0x01, 0)
+#define MI_ARB_CHECK            MI_INSTR(0x05, 0)
+#define MI_RS_CONTROL           MI_INSTR(0x06, 0)
+#define MI_URB_ATOMIC_ALLOC     MI_INSTR(0x09, 0)
+#define MI_PREDICATE            MI_INSTR(0x0C, 0)
+#define MI_RS_CONTEXT           MI_INSTR(0x0F, 0)
+#define MI_TOPOLOGY_FILTER      MI_INSTR(0x0D, 0)
+#define MI_LOAD_SCAN_LINES_EXCL MI_INSTR(0x13, 0)
+#define MI_URB_CLEAR            MI_INSTR(0x19, 0)
+#define MI_UPDATE_GTT           MI_INSTR(0x23, 0)
+#define MI_CLFLUSH              MI_INSTR(0x27, 0)
+#define MI_REPORT_PERF_COUNT    MI_INSTR(0x28, 0)
+#define   MI_REPORT_PERF_COUNT_GGTT (1<<0)
+#define MI_LOAD_REGISTER_REG    MI_INSTR(0x2A, 0)
+#define MI_RS_STORE_DATA_IMM    MI_INSTR(0x2B, 0)
+#define MI_LOAD_URB_MEM         MI_INSTR(0x2C, 0)
+#define MI_STORE_URB_MEM        MI_INSTR(0x2D, 0)
+#define MI_CONDITIONAL_BATCH_BUFFER_END MI_INSTR(0x36, 0)
+
+#define PIPELINE_SELECT                ((0x3<<29)|(0x1<<27)|(0x1<<24)|(0x4<<16))
+#define GFX_OP_3DSTATE_VF_STATISTICS   ((0x3<<29)|(0x1<<27)|(0x0<<24)|(0xB<<16))
+#define MEDIA_VFE_STATE                ((0x3<<29)|(0x2<<27)|(0x0<<24)|(0x0<<16))
+#define  MEDIA_VFE_STATE_MMIO_ACCESS_MASK (0x18)
+#define GPGPU_OBJECT                   ((0x3<<29)|(0x2<<27)|(0x1<<24)|(0x4<<16))
+#define GPGPU_WALKER                   ((0x3<<29)|(0x2<<27)|(0x1<<24)|(0x5<<16))
+#define GFX_OP_3DSTATE_DX9_CONSTANTF_VS \
+	((0x3<<29)|(0x3<<27)|(0x0<<24)|(0x39<<16))
+#define GFX_OP_3DSTATE_DX9_CONSTANTF_PS \
+	((0x3<<29)|(0x3<<27)|(0x0<<24)|(0x3A<<16))
+#define GFX_OP_3DSTATE_SO_DECL_LIST \
+	((0x3<<29)|(0x3<<27)|(0x1<<24)|(0x17<<16))
+
+#define GFX_OP_3DSTATE_BINDING_TABLE_EDIT_VS \
+	((0x3<<29)|(0x3<<27)|(0x0<<24)|(0x43<<16))
+#define GFX_OP_3DSTATE_BINDING_TABLE_EDIT_GS \
+	((0x3<<29)|(0x3<<27)|(0x0<<24)|(0x44<<16))
+#define GFX_OP_3DSTATE_BINDING_TABLE_EDIT_HS \
+	((0x3<<29)|(0x3<<27)|(0x0<<24)|(0x45<<16))
+#define GFX_OP_3DSTATE_BINDING_TABLE_EDIT_DS \
+	((0x3<<29)|(0x3<<27)|(0x0<<24)|(0x46<<16))
+#define GFX_OP_3DSTATE_BINDING_TABLE_EDIT_PS \
+	((0x3<<29)|(0x3<<27)|(0x0<<24)|(0x47<<16))
+
+#define MFX_WAIT  ((0x3<<29)|(0x1<<27)|(0x0<<16))
+
+#define COLOR_BLT     ((0x2<<29)|(0x40<<22))
+#define SRC_COPY_BLT  ((0x2<<29)|(0x43<<22))
+
+/*
+ * Registers used only by the command parser
+ */
+#define BCS_SWCTRL _MMIO(0x22200)
+
+#define GPGPU_THREADS_DISPATCHED        _MMIO(0x2290)
+#define GPGPU_THREADS_DISPATCHED_UDW	_MMIO(0x2290 + 4)
+#define HS_INVOCATION_COUNT             _MMIO(0x2300)
+#define HS_INVOCATION_COUNT_UDW		_MMIO(0x2300 + 4)
+#define DS_INVOCATION_COUNT             _MMIO(0x2308)
+#define DS_INVOCATION_COUNT_UDW		_MMIO(0x2308 + 4)
+#define IA_VERTICES_COUNT               _MMIO(0x2310)
+#define IA_VERTICES_COUNT_UDW		_MMIO(0x2310 + 4)
+#define IA_PRIMITIVES_COUNT             _MMIO(0x2318)
+#define IA_PRIMITIVES_COUNT_UDW		_MMIO(0x2318 + 4)
+#define VS_INVOCATION_COUNT             _MMIO(0x2320)
+#define VS_INVOCATION_COUNT_UDW		_MMIO(0x2320 + 4)
+#define GS_INVOCATION_COUNT             _MMIO(0x2328)
+#define GS_INVOCATION_COUNT_UDW		_MMIO(0x2328 + 4)
+#define GS_PRIMITIVES_COUNT             _MMIO(0x2330)
+#define GS_PRIMITIVES_COUNT_UDW		_MMIO(0x2330 + 4)
+#define CL_INVOCATION_COUNT             _MMIO(0x2338)
+#define CL_INVOCATION_COUNT_UDW		_MMIO(0x2338 + 4)
+#define CL_PRIMITIVES_COUNT             _MMIO(0x2340)
+#define CL_PRIMITIVES_COUNT_UDW		_MMIO(0x2340 + 4)
+#define PS_INVOCATION_COUNT             _MMIO(0x2348)
+#define PS_INVOCATION_COUNT_UDW		_MMIO(0x2348 + 4)
+#define PS_DEPTH_COUNT                  _MMIO(0x2350)
+#define PS_DEPTH_COUNT_UDW		_MMIO(0x2350 + 4)
+
+/* There are the 4 64-bit counter registers, one for each stream output */
+#define GEN7_SO_NUM_PRIMS_WRITTEN(n)		_MMIO(0x5200 + (n) * 8)
+#define GEN7_SO_NUM_PRIMS_WRITTEN_UDW(n)	_MMIO(0x5200 + (n) * 8 + 4)
+
+#define GEN7_SO_PRIM_STORAGE_NEEDED(n)		_MMIO(0x5240 + (n) * 8)
+#define GEN7_SO_PRIM_STORAGE_NEEDED_UDW(n)	_MMIO(0x5240 + (n) * 8 + 4)
+
+#define GEN7_3DPRIM_END_OFFSET          _MMIO(0x2420)
+#define GEN7_3DPRIM_START_VERTEX        _MMIO(0x2430)
+#define GEN7_3DPRIM_VERTEX_COUNT        _MMIO(0x2434)
+#define GEN7_3DPRIM_INSTANCE_COUNT      _MMIO(0x2438)
+#define GEN7_3DPRIM_START_INSTANCE      _MMIO(0x243C)
+#define GEN7_3DPRIM_BASE_VERTEX         _MMIO(0x2440)
+
+#define GEN7_GPGPU_DISPATCHDIMX         _MMIO(0x2500)
+#define GEN7_GPGPU_DISPATCHDIMY         _MMIO(0x2504)
+#define GEN7_GPGPU_DISPATCHDIMZ         _MMIO(0x2508)
+
+/* There are the 16 64-bit CS General Purpose Registers */
+#define HSW_CS_GPR(n)                   _MMIO(0x2600 + (n) * 8)
+#define HSW_CS_GPR_UDW(n)               _MMIO(0x2600 + (n) * 8 + 4)
+
+#define OACONTROL _MMIO(0x2360)
+
+#define _GEN7_PIPEA_DE_LOAD_SL	0x70068
+#define _GEN7_PIPEB_DE_LOAD_SL	0x71068
+#define GEN7_PIPE_DE_LOAD_SL(pipe) _MMIO_PIPE(pipe, _GEN7_PIPEA_DE_LOAD_SL, _GEN7_PIPEB_DE_LOAD_SL)
+
+/*
+ * Reset registers
+ */
+#define DEBUG_RESET_I830		_MMIO(0x6070)
+#define  DEBUG_RESET_FULL		(1<<7)
+#define  DEBUG_RESET_RENDER		(1<<8)
+#define  DEBUG_RESET_DISPLAY		(1<<9)
+
+/*
+ * IOSF sideband
+ */
+#define VLV_IOSF_DOORBELL_REQ			_MMIO(VLV_DISPLAY_BASE + 0x2100)
+#define   IOSF_DEVFN_SHIFT			24
+#define   IOSF_OPCODE_SHIFT			16
+#define   IOSF_PORT_SHIFT			8
+#define   IOSF_BYTE_ENABLES_SHIFT		4
+#define   IOSF_BAR_SHIFT			1
+#define   IOSF_SB_BUSY				(1<<0)
+#define   IOSF_PORT_BUNIT			0x03
+#define   IOSF_PORT_PUNIT			0x04
+#define   IOSF_PORT_NC				0x11
+#define   IOSF_PORT_DPIO			0x12
+#define   IOSF_PORT_GPIO_NC			0x13
+#define   IOSF_PORT_CCK				0x14
+#define   IOSF_PORT_DPIO_2			0x1a
+#define   IOSF_PORT_FLISDSI			0x1b
+#define   IOSF_PORT_GPIO_SC			0x48
+#define   IOSF_PORT_GPIO_SUS			0xa8
+#define   IOSF_PORT_CCU				0xa9
+#define   CHV_IOSF_PORT_GPIO_N			0x13
+#define   CHV_IOSF_PORT_GPIO_SE			0x48
+#define   CHV_IOSF_PORT_GPIO_E			0xa8
+#define   CHV_IOSF_PORT_GPIO_SW			0xb2
+#define VLV_IOSF_DATA				_MMIO(VLV_DISPLAY_BASE + 0x2104)
+#define VLV_IOSF_ADDR				_MMIO(VLV_DISPLAY_BASE + 0x2108)
+
+/* See configdb bunit SB addr map */
+#define BUNIT_REG_BISOC				0x11
+
+#define PUNIT_REG_DSPFREQ			0x36
+#define   DSPFREQSTAT_SHIFT_CHV			24
+#define   DSPFREQSTAT_MASK_CHV			(0x1f << DSPFREQSTAT_SHIFT_CHV)
+#define   DSPFREQGUAR_SHIFT_CHV			8
+#define   DSPFREQGUAR_MASK_CHV			(0x1f << DSPFREQGUAR_SHIFT_CHV)
+#define   DSPFREQSTAT_SHIFT			30
+#define   DSPFREQSTAT_MASK			(0x3 << DSPFREQSTAT_SHIFT)
+#define   DSPFREQGUAR_SHIFT			14
+#define   DSPFREQGUAR_MASK			(0x3 << DSPFREQGUAR_SHIFT)
+#define   DSP_MAXFIFO_PM5_STATUS		(1 << 22) /* chv */
+#define   DSP_AUTO_CDCLK_GATE_DISABLE		(1 << 7) /* chv */
+#define   DSP_MAXFIFO_PM5_ENABLE		(1 << 6) /* chv */
+#define   _DP_SSC(val, pipe)			((val) << (2 * (pipe)))
+#define   DP_SSC_MASK(pipe)			_DP_SSC(0x3, (pipe))
+#define   DP_SSC_PWR_ON(pipe)			_DP_SSC(0x0, (pipe))
+#define   DP_SSC_CLK_GATE(pipe)			_DP_SSC(0x1, (pipe))
+#define   DP_SSC_RESET(pipe)			_DP_SSC(0x2, (pipe))
+#define   DP_SSC_PWR_GATE(pipe)			_DP_SSC(0x3, (pipe))
+#define   _DP_SSS(val, pipe)			((val) << (2 * (pipe) + 16))
+#define   DP_SSS_MASK(pipe)			_DP_SSS(0x3, (pipe))
+#define   DP_SSS_PWR_ON(pipe)			_DP_SSS(0x0, (pipe))
+#define   DP_SSS_CLK_GATE(pipe)			_DP_SSS(0x1, (pipe))
+#define   DP_SSS_RESET(pipe)			_DP_SSS(0x2, (pipe))
+#define   DP_SSS_PWR_GATE(pipe)			_DP_SSS(0x3, (pipe))
+
+/* See the PUNIT HAS v0.8 for the below bits */
+enum punit_power_well {
+	/* These numbers are fixed and must match the position of the pw bits */
+	PUNIT_POWER_WELL_RENDER			= 0,
+	PUNIT_POWER_WELL_MEDIA			= 1,
+	PUNIT_POWER_WELL_DISP2D			= 3,
+	PUNIT_POWER_WELL_DPIO_CMN_BC		= 5,
+	PUNIT_POWER_WELL_DPIO_TX_B_LANES_01	= 6,
+	PUNIT_POWER_WELL_DPIO_TX_B_LANES_23	= 7,
+	PUNIT_POWER_WELL_DPIO_TX_C_LANES_01	= 8,
+	PUNIT_POWER_WELL_DPIO_TX_C_LANES_23	= 9,
+	PUNIT_POWER_WELL_DPIO_RX0		= 10,
+	PUNIT_POWER_WELL_DPIO_RX1		= 11,
+	PUNIT_POWER_WELL_DPIO_CMN_D		= 12,
+
+	/* Not actual bit groups. Used as IDs for lookup_power_well() */
+	PUNIT_POWER_WELL_ALWAYS_ON,
+};
+
+enum skl_disp_power_wells {
+	/* These numbers are fixed and must match the position of the pw bits */
+	SKL_DISP_PW_MISC_IO,
+	SKL_DISP_PW_DDI_A_E,
+	SKL_DISP_PW_DDI_B,
+	SKL_DISP_PW_DDI_C,
+	SKL_DISP_PW_DDI_D,
+	SKL_DISP_PW_1 = 14,
+	SKL_DISP_PW_2,
+
+	/* Not actual bit groups. Used as IDs for lookup_power_well() */
+	SKL_DISP_PW_ALWAYS_ON,
+	SKL_DISP_PW_DC_OFF,
+};
+
+#define SKL_POWER_WELL_STATE(pw) (1 << ((pw) * 2))
+#define SKL_POWER_WELL_REQ(pw) (1 << (((pw) * 2) + 1))
+
+#define PUNIT_REG_PWRGT_CTRL			0x60
+#define PUNIT_REG_PWRGT_STATUS			0x61
+#define   PUNIT_PWRGT_MASK(power_well)		(3 << ((power_well) * 2))
+#define   PUNIT_PWRGT_PWR_ON(power_well)	(0 << ((power_well) * 2))
+#define   PUNIT_PWRGT_CLK_GATE(power_well)	(1 << ((power_well) * 2))
+#define   PUNIT_PWRGT_RESET(power_well)		(2 << ((power_well) * 2))
+#define   PUNIT_PWRGT_PWR_GATE(power_well)	(3 << ((power_well) * 2))
+
+#define PUNIT_REG_GPU_LFM			0xd3
+#define PUNIT_REG_GPU_FREQ_REQ			0xd4
+#define PUNIT_REG_GPU_FREQ_STS			0xd8
+#define   GPLLENABLE				(1<<4)
+#define   GENFREQSTATUS				(1<<0)
+#define PUNIT_REG_MEDIA_TURBO_FREQ_REQ		0xdc
+#define PUNIT_REG_CZ_TIMESTAMP			0xce
+
+#define PUNIT_FUSE_BUS2				0xf6 /* bits 47:40 */
+#define PUNIT_FUSE_BUS1				0xf5 /* bits 55:48 */
+
+#define FB_GFX_FMAX_AT_VMAX_FUSE		0x136
+#define FB_GFX_FREQ_FUSE_MASK			0xff
+#define FB_GFX_FMAX_AT_VMAX_2SS4EU_FUSE_SHIFT	24
+#define FB_GFX_FMAX_AT_VMAX_2SS6EU_FUSE_SHIFT	16
+#define FB_GFX_FMAX_AT_VMAX_2SS8EU_FUSE_SHIFT	8
+
+#define FB_GFX_FMIN_AT_VMIN_FUSE		0x137
+#define FB_GFX_FMIN_AT_VMIN_FUSE_SHIFT		8
+
+#define PUNIT_REG_DDR_SETUP2			0x139
+#define   FORCE_DDR_FREQ_REQ_ACK		(1 << 8)
+#define   FORCE_DDR_LOW_FREQ			(1 << 1)
+#define   FORCE_DDR_HIGH_FREQ			(1 << 0)
+
+#define PUNIT_GPU_STATUS_REG			0xdb
+#define PUNIT_GPU_STATUS_MAX_FREQ_SHIFT	16
+#define PUNIT_GPU_STATUS_MAX_FREQ_MASK		0xff
+#define PUNIT_GPU_STATIS_GFX_MIN_FREQ_SHIFT	8
+#define PUNIT_GPU_STATUS_GFX_MIN_FREQ_MASK	0xff
+
+#define PUNIT_GPU_DUTYCYCLE_REG		0xdf
+#define PUNIT_GPU_DUTYCYCLE_RPE_FREQ_SHIFT	8
+#define PUNIT_GPU_DUTYCYCLE_RPE_FREQ_MASK	0xff
+
+#define IOSF_NC_FB_GFX_FREQ_FUSE		0x1c
+#define   FB_GFX_MAX_FREQ_FUSE_SHIFT		3
+#define   FB_GFX_MAX_FREQ_FUSE_MASK		0x000007f8
+#define   FB_GFX_FGUARANTEED_FREQ_FUSE_SHIFT	11
+#define   FB_GFX_FGUARANTEED_FREQ_FUSE_MASK	0x0007f800
+#define IOSF_NC_FB_GFX_FMAX_FUSE_HI		0x34
+#define   FB_FMAX_VMIN_FREQ_HI_MASK		0x00000007
+#define IOSF_NC_FB_GFX_FMAX_FUSE_LO		0x30
+#define   FB_FMAX_VMIN_FREQ_LO_SHIFT		27
+#define   FB_FMAX_VMIN_FREQ_LO_MASK		0xf8000000
+
+#define VLV_TURBO_SOC_OVERRIDE	0x04
+#define 	VLV_OVERRIDE_EN	1
+#define 	VLV_SOC_TDP_EN	(1 << 1)
+#define 	VLV_BIAS_CPU_125_SOC_875 (6 << 2)
+#define 	CHV_BIAS_CPU_50_SOC_50 (3 << 2)
+
+#define VLV_CZ_CLOCK_TO_MILLI_SEC		100000
+
+/* vlv2 north clock has */
+#define CCK_FUSE_REG				0x8
+#define  CCK_FUSE_HPLL_FREQ_MASK		0x3
+#define CCK_REG_DSI_PLL_FUSE			0x44
+#define CCK_REG_DSI_PLL_CONTROL			0x48
+#define  DSI_PLL_VCO_EN				(1 << 31)
+#define  DSI_PLL_LDO_GATE			(1 << 30)
+#define  DSI_PLL_P1_POST_DIV_SHIFT		17
+#define  DSI_PLL_P1_POST_DIV_MASK		(0x1ff << 17)
+#define  DSI_PLL_P2_MUX_DSI0_DIV2		(1 << 13)
+#define  DSI_PLL_P3_MUX_DSI1_DIV2		(1 << 12)
+#define  DSI_PLL_MUX_MASK			(3 << 9)
+#define  DSI_PLL_MUX_DSI0_DSIPLL		(0 << 10)
+#define  DSI_PLL_MUX_DSI0_CCK			(1 << 10)
+#define  DSI_PLL_MUX_DSI1_DSIPLL		(0 << 9)
+#define  DSI_PLL_MUX_DSI1_CCK			(1 << 9)
+#define  DSI_PLL_CLK_GATE_MASK			(0xf << 5)
+#define  DSI_PLL_CLK_GATE_DSI0_DSIPLL		(1 << 8)
+#define  DSI_PLL_CLK_GATE_DSI1_DSIPLL		(1 << 7)
+#define  DSI_PLL_CLK_GATE_DSI0_CCK		(1 << 6)
+#define  DSI_PLL_CLK_GATE_DSI1_CCK		(1 << 5)
+#define  DSI_PLL_LOCK				(1 << 0)
+#define CCK_REG_DSI_PLL_DIVIDER			0x4c
+#define  DSI_PLL_LFSR				(1 << 31)
+#define  DSI_PLL_FRACTION_EN			(1 << 30)
+#define  DSI_PLL_FRAC_COUNTER_SHIFT		27
+#define  DSI_PLL_FRAC_COUNTER_MASK		(7 << 27)
+#define  DSI_PLL_USYNC_CNT_SHIFT		18
+#define  DSI_PLL_USYNC_CNT_MASK			(0x1ff << 18)
+#define  DSI_PLL_N1_DIV_SHIFT			16
+#define  DSI_PLL_N1_DIV_MASK			(3 << 16)
+#define  DSI_PLL_M1_DIV_SHIFT			0
+#define  DSI_PLL_M1_DIV_MASK			(0x1ff << 0)
+#define CCK_CZ_CLOCK_CONTROL			0x62
+#define CCK_GPLL_CLOCK_CONTROL			0x67
+#define CCK_DISPLAY_CLOCK_CONTROL		0x6b
+#define CCK_DISPLAY_REF_CLOCK_CONTROL		0x6c
+#define  CCK_TRUNK_FORCE_ON			(1 << 17)
+#define  CCK_TRUNK_FORCE_OFF			(1 << 16)
+#define  CCK_FREQUENCY_STATUS			(0x1f << 8)
+#define  CCK_FREQUENCY_STATUS_SHIFT		8
+#define  CCK_FREQUENCY_VALUES			(0x1f << 0)
+
+/**
+ * DOC: DPIO
+ *
+ * VLV, CHV and BXT have slightly peculiar display PHYs for driving DP/HDMI
+ * ports. DPIO is the name given to such a display PHY. These PHYs
+ * don't follow the standard programming model using direct MMIO
+ * registers, and instead their registers must be accessed trough IOSF
+ * sideband. VLV has one such PHY for driving ports B and C, and CHV
+ * adds another PHY for driving port D. Each PHY responds to specific
+ * IOSF-SB port.
+ *
+ * Each display PHY is made up of one or two channels. Each channel
+ * houses a common lane part which contains the PLL and other common
+ * logic. CH0 common lane also contains the IOSF-SB logic for the
+ * Common Register Interface (CRI) ie. the DPIO registers. CRI clock
+ * must be running when any DPIO registers are accessed.
+ *
+ * In addition to having their own registers, the PHYs are also
+ * controlled through some dedicated signals from the display
+ * controller. These include PLL reference clock enable, PLL enable,
+ * and CRI clock selection, for example.
+ *
+ * Eeach channel also has two splines (also called data lanes), and
+ * each spline is made up of one Physical Access Coding Sub-Layer
+ * (PCS) block and two TX lanes. So each channel has two PCS blocks
+ * and four TX lanes. The TX lanes are used as DP lanes or TMDS
+ * data/clock pairs depending on the output type.
+ *
+ * Additionally the PHY also contains an AUX lane with AUX blocks
+ * for each channel. This is used for DP AUX communication, but
+ * this fact isn't really relevant for the driver since AUX is
+ * controlled from the display controller side. No DPIO registers
+ * need to be accessed during AUX communication,
+ *
+ * Generally on VLV/CHV the common lane corresponds to the pipe and
+ * the spline (PCS/TX) corresponds to the port.
+ *
+ * For dual channel PHY (VLV/CHV):
+ *
+ *  pipe A == CMN/PLL/REF CH0
+ *
+ *  pipe B == CMN/PLL/REF CH1
+ *
+ *  port B == PCS/TX CH0
+ *
+ *  port C == PCS/TX CH1
+ *
+ * This is especially important when we cross the streams
+ * ie. drive port B with pipe B, or port C with pipe A.
+ *
+ * For single channel PHY (CHV):
+ *
+ *  pipe C == CMN/PLL/REF CH0
+ *
+ *  port D == PCS/TX CH0
+ *
+ * On BXT the entire PHY channel corresponds to the port. That means
+ * the PLL is also now associated with the port rather than the pipe,
+ * and so the clock needs to be routed to the appropriate transcoder.
+ * Port A PLL is directly connected to transcoder EDP and port B/C
+ * PLLs can be routed to any transcoder A/B/C.
+ *
+ * Note: DDI0 is digital port B, DD1 is digital port C, and DDI2 is
+ * digital port D (CHV) or port A (BXT).
+ *
+ *
+ *     Dual channel PHY (VLV/CHV/BXT)
+ *     ---------------------------------
+ *     |      CH0      |      CH1      |
+ *     |  CMN/PLL/REF  |  CMN/PLL/REF  |
+ *     |---------------|---------------| Display PHY
+ *     | PCS01 | PCS23 | PCS01 | PCS23 |
+ *     |-------|-------|-------|-------|
+ *     |TX0|TX1|TX2|TX3|TX0|TX1|TX2|TX3|
+ *     ---------------------------------
+ *     |     DDI0      |     DDI1      | DP/HDMI ports
+ *     ---------------------------------
+ *
+ *     Single channel PHY (CHV/BXT)
+ *     -----------------
+ *     |      CH0      |
+ *     |  CMN/PLL/REF  |
+ *     |---------------| Display PHY
+ *     | PCS01 | PCS23 |
+ *     |-------|-------|
+ *     |TX0|TX1|TX2|TX3|
+ *     -----------------
+ *     |     DDI2      | DP/HDMI port
+ *     -----------------
+ */
+#define DPIO_DEVFN			0
+
+#define DPIO_CTL			_MMIO(VLV_DISPLAY_BASE + 0x2110)
+#define  DPIO_MODSEL1			(1<<3) /* if ref clk b == 27 */
+#define  DPIO_MODSEL0			(1<<2) /* if ref clk a == 27 */
+#define  DPIO_SFR_BYPASS		(1<<1)
+#define  DPIO_CMNRST			(1<<0)
+
+#define DPIO_PHY(pipe)			((pipe) >> 1)
+#define DPIO_PHY_IOSF_PORT(phy)		(dev_priv->dpio_phy_iosf_port[phy])
+
+/*
+ * Per pipe/PLL DPIO regs
+ */
+#define _VLV_PLL_DW3_CH0		0x800c
+#define   DPIO_POST_DIV_SHIFT		(28) /* 3 bits */
+#define   DPIO_POST_DIV_DAC		0
+#define   DPIO_POST_DIV_HDMIDP		1 /* DAC 225-400M rate */
+#define   DPIO_POST_DIV_LVDS1		2
+#define   DPIO_POST_DIV_LVDS2		3
+#define   DPIO_K_SHIFT			(24) /* 4 bits */
+#define   DPIO_P1_SHIFT			(21) /* 3 bits */
+#define   DPIO_P2_SHIFT			(16) /* 5 bits */
+#define   DPIO_N_SHIFT			(12) /* 4 bits */
+#define   DPIO_ENABLE_CALIBRATION	(1<<11)
+#define   DPIO_M1DIV_SHIFT		(8) /* 3 bits */
+#define   DPIO_M2DIV_MASK		0xff
+#define _VLV_PLL_DW3_CH1		0x802c
+#define VLV_PLL_DW3(ch) _PIPE(ch, _VLV_PLL_DW3_CH0, _VLV_PLL_DW3_CH1)
+
+#define _VLV_PLL_DW5_CH0		0x8014
+#define   DPIO_REFSEL_OVERRIDE		27
+#define   DPIO_PLL_MODESEL_SHIFT	24 /* 3 bits */
+#define   DPIO_BIAS_CURRENT_CTL_SHIFT	21 /* 3 bits, always 0x7 */
+#define   DPIO_PLL_REFCLK_SEL_SHIFT	16 /* 2 bits */
+#define   DPIO_PLL_REFCLK_SEL_MASK	3
+#define   DPIO_DRIVER_CTL_SHIFT		12 /* always set to 0x8 */
+#define   DPIO_CLK_BIAS_CTL_SHIFT	8 /* always set to 0x5 */
+#define _VLV_PLL_DW5_CH1		0x8034
+#define VLV_PLL_DW5(ch) _PIPE(ch, _VLV_PLL_DW5_CH0, _VLV_PLL_DW5_CH1)
+
+#define _VLV_PLL_DW7_CH0		0x801c
+#define _VLV_PLL_DW7_CH1		0x803c
+#define VLV_PLL_DW7(ch) _PIPE(ch, _VLV_PLL_DW7_CH0, _VLV_PLL_DW7_CH1)
+
+#define _VLV_PLL_DW8_CH0		0x8040
+#define _VLV_PLL_DW8_CH1		0x8060
+#define VLV_PLL_DW8(ch) _PIPE(ch, _VLV_PLL_DW8_CH0, _VLV_PLL_DW8_CH1)
+
+#define VLV_PLL_DW9_BCAST		0xc044
+#define _VLV_PLL_DW9_CH0		0x8044
+#define _VLV_PLL_DW9_CH1		0x8064
+#define VLV_PLL_DW9(ch) _PIPE(ch, _VLV_PLL_DW9_CH0, _VLV_PLL_DW9_CH1)
+
+#define _VLV_PLL_DW10_CH0		0x8048
+#define _VLV_PLL_DW10_CH1		0x8068
+#define VLV_PLL_DW10(ch) _PIPE(ch, _VLV_PLL_DW10_CH0, _VLV_PLL_DW10_CH1)
+
+#define _VLV_PLL_DW11_CH0		0x804c
+#define _VLV_PLL_DW11_CH1		0x806c
+#define VLV_PLL_DW11(ch) _PIPE(ch, _VLV_PLL_DW11_CH0, _VLV_PLL_DW11_CH1)
+
+/* Spec for ref block start counts at DW10 */
+#define VLV_REF_DW13			0x80ac
+
+#define VLV_CMN_DW0			0x8100
+
+/*
+ * Per DDI channel DPIO regs
+ */
+
+#define _VLV_PCS_DW0_CH0		0x8200
+#define _VLV_PCS_DW0_CH1		0x8400
+#define   DPIO_PCS_TX_LANE2_RESET	(1<<16)
+#define   DPIO_PCS_TX_LANE1_RESET	(1<<7)
+#define   DPIO_LEFT_TXFIFO_RST_MASTER2	(1<<4)
+#define   DPIO_RIGHT_TXFIFO_RST_MASTER2	(1<<3)
+#define VLV_PCS_DW0(ch) _PORT(ch, _VLV_PCS_DW0_CH0, _VLV_PCS_DW0_CH1)
+
+#define _VLV_PCS01_DW0_CH0		0x200
+#define _VLV_PCS23_DW0_CH0		0x400
+#define _VLV_PCS01_DW0_CH1		0x2600
+#define _VLV_PCS23_DW0_CH1		0x2800
+#define VLV_PCS01_DW0(ch) _PORT(ch, _VLV_PCS01_DW0_CH0, _VLV_PCS01_DW0_CH1)
+#define VLV_PCS23_DW0(ch) _PORT(ch, _VLV_PCS23_DW0_CH0, _VLV_PCS23_DW0_CH1)
+
+#define _VLV_PCS_DW1_CH0		0x8204
+#define _VLV_PCS_DW1_CH1		0x8404
+#define   CHV_PCS_REQ_SOFTRESET_EN	(1<<23)
+#define   DPIO_PCS_CLK_CRI_RXEB_EIOS_EN	(1<<22)
+#define   DPIO_PCS_CLK_CRI_RXDIGFILTSG_EN (1<<21)
+#define   DPIO_PCS_CLK_DATAWIDTH_SHIFT	(6)
+#define   DPIO_PCS_CLK_SOFT_RESET	(1<<5)
+#define VLV_PCS_DW1(ch) _PORT(ch, _VLV_PCS_DW1_CH0, _VLV_PCS_DW1_CH1)
+
+#define _VLV_PCS01_DW1_CH0		0x204
+#define _VLV_PCS23_DW1_CH0		0x404
+#define _VLV_PCS01_DW1_CH1		0x2604
+#define _VLV_PCS23_DW1_CH1		0x2804
+#define VLV_PCS01_DW1(ch) _PORT(ch, _VLV_PCS01_DW1_CH0, _VLV_PCS01_DW1_CH1)
+#define VLV_PCS23_DW1(ch) _PORT(ch, _VLV_PCS23_DW1_CH0, _VLV_PCS23_DW1_CH1)
+
+#define _VLV_PCS_DW8_CH0		0x8220
+#define _VLV_PCS_DW8_CH1		0x8420
+#define   CHV_PCS_USEDCLKCHANNEL_OVRRIDE	(1 << 20)
+#define   CHV_PCS_USEDCLKCHANNEL		(1 << 21)
+#define VLV_PCS_DW8(ch) _PORT(ch, _VLV_PCS_DW8_CH0, _VLV_PCS_DW8_CH1)
+
+#define _VLV_PCS01_DW8_CH0		0x0220
+#define _VLV_PCS23_DW8_CH0		0x0420
+#define _VLV_PCS01_DW8_CH1		0x2620
+#define _VLV_PCS23_DW8_CH1		0x2820
+#define VLV_PCS01_DW8(port) _PORT(port, _VLV_PCS01_DW8_CH0, _VLV_PCS01_DW8_CH1)
+#define VLV_PCS23_DW8(port) _PORT(port, _VLV_PCS23_DW8_CH0, _VLV_PCS23_DW8_CH1)
+
+#define _VLV_PCS_DW9_CH0		0x8224
+#define _VLV_PCS_DW9_CH1		0x8424
+#define   DPIO_PCS_TX2MARGIN_MASK	(0x7<<13)
+#define   DPIO_PCS_TX2MARGIN_000	(0<<13)
+#define   DPIO_PCS_TX2MARGIN_101	(1<<13)
+#define   DPIO_PCS_TX1MARGIN_MASK	(0x7<<10)
+#define   DPIO_PCS_TX1MARGIN_000	(0<<10)
+#define   DPIO_PCS_TX1MARGIN_101	(1<<10)
+#define	VLV_PCS_DW9(ch) _PORT(ch, _VLV_PCS_DW9_CH0, _VLV_PCS_DW9_CH1)
+
+#define _VLV_PCS01_DW9_CH0		0x224
+#define _VLV_PCS23_DW9_CH0		0x424
+#define _VLV_PCS01_DW9_CH1		0x2624
+#define _VLV_PCS23_DW9_CH1		0x2824
+#define VLV_PCS01_DW9(ch) _PORT(ch, _VLV_PCS01_DW9_CH0, _VLV_PCS01_DW9_CH1)
+#define VLV_PCS23_DW9(ch) _PORT(ch, _VLV_PCS23_DW9_CH0, _VLV_PCS23_DW9_CH1)
+
+#define _CHV_PCS_DW10_CH0		0x8228
+#define _CHV_PCS_DW10_CH1		0x8428
+#define   DPIO_PCS_SWING_CALC_TX0_TX2	(1<<30)
+#define   DPIO_PCS_SWING_CALC_TX1_TX3	(1<<31)
+#define   DPIO_PCS_TX2DEEMP_MASK	(0xf<<24)
+#define   DPIO_PCS_TX2DEEMP_9P5		(0<<24)
+#define   DPIO_PCS_TX2DEEMP_6P0		(2<<24)
+#define   DPIO_PCS_TX1DEEMP_MASK	(0xf<<16)
+#define   DPIO_PCS_TX1DEEMP_9P5		(0<<16)
+#define   DPIO_PCS_TX1DEEMP_6P0		(2<<16)
+#define CHV_PCS_DW10(ch) _PORT(ch, _CHV_PCS_DW10_CH0, _CHV_PCS_DW10_CH1)
+
+#define _VLV_PCS01_DW10_CH0		0x0228
+#define _VLV_PCS23_DW10_CH0		0x0428
+#define _VLV_PCS01_DW10_CH1		0x2628
+#define _VLV_PCS23_DW10_CH1		0x2828
+#define VLV_PCS01_DW10(port) _PORT(port, _VLV_PCS01_DW10_CH0, _VLV_PCS01_DW10_CH1)
+#define VLV_PCS23_DW10(port) _PORT(port, _VLV_PCS23_DW10_CH0, _VLV_PCS23_DW10_CH1)
+
+#define _VLV_PCS_DW11_CH0		0x822c
+#define _VLV_PCS_DW11_CH1		0x842c
+#define   DPIO_TX2_STAGGER_MASK(x)	((x)<<24)
+#define   DPIO_LANEDESKEW_STRAP_OVRD	(1<<3)
+#define   DPIO_LEFT_TXFIFO_RST_MASTER	(1<<1)
+#define   DPIO_RIGHT_TXFIFO_RST_MASTER	(1<<0)
+#define VLV_PCS_DW11(ch) _PORT(ch, _VLV_PCS_DW11_CH0, _VLV_PCS_DW11_CH1)
+
+#define _VLV_PCS01_DW11_CH0		0x022c
+#define _VLV_PCS23_DW11_CH0		0x042c
+#define _VLV_PCS01_DW11_CH1		0x262c
+#define _VLV_PCS23_DW11_CH1		0x282c
+#define VLV_PCS01_DW11(ch) _PORT(ch, _VLV_PCS01_DW11_CH0, _VLV_PCS01_DW11_CH1)
+#define VLV_PCS23_DW11(ch) _PORT(ch, _VLV_PCS23_DW11_CH0, _VLV_PCS23_DW11_CH1)
+
+#define _VLV_PCS01_DW12_CH0		0x0230
+#define _VLV_PCS23_DW12_CH0		0x0430
+#define _VLV_PCS01_DW12_CH1		0x2630
+#define _VLV_PCS23_DW12_CH1		0x2830
+#define VLV_PCS01_DW12(ch) _PORT(ch, _VLV_PCS01_DW12_CH0, _VLV_PCS01_DW12_CH1)
+#define VLV_PCS23_DW12(ch) _PORT(ch, _VLV_PCS23_DW12_CH0, _VLV_PCS23_DW12_CH1)
+
+#define _VLV_PCS_DW12_CH0		0x8230
+#define _VLV_PCS_DW12_CH1		0x8430
+#define   DPIO_TX2_STAGGER_MULT(x)	((x)<<20)
+#define   DPIO_TX1_STAGGER_MULT(x)	((x)<<16)
+#define   DPIO_TX1_STAGGER_MASK(x)	((x)<<8)
+#define   DPIO_LANESTAGGER_STRAP_OVRD	(1<<6)
+#define   DPIO_LANESTAGGER_STRAP(x)	((x)<<0)
+#define VLV_PCS_DW12(ch) _PORT(ch, _VLV_PCS_DW12_CH0, _VLV_PCS_DW12_CH1)
+
+#define _VLV_PCS_DW14_CH0		0x8238
+#define _VLV_PCS_DW14_CH1		0x8438
+#define	VLV_PCS_DW14(ch) _PORT(ch, _VLV_PCS_DW14_CH0, _VLV_PCS_DW14_CH1)
+
+#define _VLV_PCS_DW23_CH0		0x825c
+#define _VLV_PCS_DW23_CH1		0x845c
+#define VLV_PCS_DW23(ch) _PORT(ch, _VLV_PCS_DW23_CH0, _VLV_PCS_DW23_CH1)
+
+#define _VLV_TX_DW2_CH0			0x8288
+#define _VLV_TX_DW2_CH1			0x8488
+#define   DPIO_SWING_MARGIN000_SHIFT	16
+#define   DPIO_SWING_MARGIN000_MASK	(0xff << DPIO_SWING_MARGIN000_SHIFT)
+#define   DPIO_UNIQ_TRANS_SCALE_SHIFT	8
+#define VLV_TX_DW2(ch) _PORT(ch, _VLV_TX_DW2_CH0, _VLV_TX_DW2_CH1)
+
+#define _VLV_TX_DW3_CH0			0x828c
+#define _VLV_TX_DW3_CH1			0x848c
+/* The following bit for CHV phy */
+#define   DPIO_TX_UNIQ_TRANS_SCALE_EN	(1<<27)
+#define   DPIO_SWING_MARGIN101_SHIFT	16
+#define   DPIO_SWING_MARGIN101_MASK	(0xff << DPIO_SWING_MARGIN101_SHIFT)
+#define VLV_TX_DW3(ch) _PORT(ch, _VLV_TX_DW3_CH0, _VLV_TX_DW3_CH1)
+
+#define _VLV_TX_DW4_CH0			0x8290
+#define _VLV_TX_DW4_CH1			0x8490
+#define   DPIO_SWING_DEEMPH9P5_SHIFT	24
+#define   DPIO_SWING_DEEMPH9P5_MASK	(0xff << DPIO_SWING_DEEMPH9P5_SHIFT)
+#define   DPIO_SWING_DEEMPH6P0_SHIFT	16
+#define   DPIO_SWING_DEEMPH6P0_MASK	(0xff << DPIO_SWING_DEEMPH6P0_SHIFT)
+#define VLV_TX_DW4(ch) _PORT(ch, _VLV_TX_DW4_CH0, _VLV_TX_DW4_CH1)
+
+#define _VLV_TX3_DW4_CH0		0x690
+#define _VLV_TX3_DW4_CH1		0x2a90
+#define VLV_TX3_DW4(ch) _PORT(ch, _VLV_TX3_DW4_CH0, _VLV_TX3_DW4_CH1)
+
+#define _VLV_TX_DW5_CH0			0x8294
+#define _VLV_TX_DW5_CH1			0x8494
+#define   DPIO_TX_OCALINIT_EN		(1<<31)
+#define VLV_TX_DW5(ch) _PORT(ch, _VLV_TX_DW5_CH0, _VLV_TX_DW5_CH1)
+
+#define _VLV_TX_DW11_CH0		0x82ac
+#define _VLV_TX_DW11_CH1		0x84ac
+#define VLV_TX_DW11(ch) _PORT(ch, _VLV_TX_DW11_CH0, _VLV_TX_DW11_CH1)
+
+#define _VLV_TX_DW14_CH0		0x82b8
+#define _VLV_TX_DW14_CH1		0x84b8
+#define VLV_TX_DW14(ch) _PORT(ch, _VLV_TX_DW14_CH0, _VLV_TX_DW14_CH1)
+
+/* CHV dpPhy registers */
+#define _CHV_PLL_DW0_CH0		0x8000
+#define _CHV_PLL_DW0_CH1		0x8180
+#define CHV_PLL_DW0(ch) _PIPE(ch, _CHV_PLL_DW0_CH0, _CHV_PLL_DW0_CH1)
+
+#define _CHV_PLL_DW1_CH0		0x8004
+#define _CHV_PLL_DW1_CH1		0x8184
+#define   DPIO_CHV_N_DIV_SHIFT		8
+#define   DPIO_CHV_M1_DIV_BY_2		(0 << 0)
+#define CHV_PLL_DW1(ch) _PIPE(ch, _CHV_PLL_DW1_CH0, _CHV_PLL_DW1_CH1)
+
+#define _CHV_PLL_DW2_CH0		0x8008
+#define _CHV_PLL_DW2_CH1		0x8188
+#define CHV_PLL_DW2(ch) _PIPE(ch, _CHV_PLL_DW2_CH0, _CHV_PLL_DW2_CH1)
+
+#define _CHV_PLL_DW3_CH0		0x800c
+#define _CHV_PLL_DW3_CH1		0x818c
+#define  DPIO_CHV_FRAC_DIV_EN		(1 << 16)
+#define  DPIO_CHV_FIRST_MOD		(0 << 8)
+#define  DPIO_CHV_SECOND_MOD		(1 << 8)
+#define  DPIO_CHV_FEEDFWD_GAIN_SHIFT	0
+#define  DPIO_CHV_FEEDFWD_GAIN_MASK		(0xF << 0)
+#define CHV_PLL_DW3(ch) _PIPE(ch, _CHV_PLL_DW3_CH0, _CHV_PLL_DW3_CH1)
+
+#define _CHV_PLL_DW6_CH0		0x8018
+#define _CHV_PLL_DW6_CH1		0x8198
+#define   DPIO_CHV_GAIN_CTRL_SHIFT	16
+#define	  DPIO_CHV_INT_COEFF_SHIFT	8
+#define   DPIO_CHV_PROP_COEFF_SHIFT	0
+#define CHV_PLL_DW6(ch) _PIPE(ch, _CHV_PLL_DW6_CH0, _CHV_PLL_DW6_CH1)
+
+#define _CHV_PLL_DW8_CH0		0x8020
+#define _CHV_PLL_DW8_CH1		0x81A0
+#define   DPIO_CHV_TDC_TARGET_CNT_SHIFT 0
+#define   DPIO_CHV_TDC_TARGET_CNT_MASK  (0x3FF << 0)
+#define CHV_PLL_DW8(ch) _PIPE(ch, _CHV_PLL_DW8_CH0, _CHV_PLL_DW8_CH1)
+
+#define _CHV_PLL_DW9_CH0		0x8024
+#define _CHV_PLL_DW9_CH1		0x81A4
+#define  DPIO_CHV_INT_LOCK_THRESHOLD_SHIFT		1 /* 3 bits */
+#define  DPIO_CHV_INT_LOCK_THRESHOLD_MASK		(7 << 1)
+#define  DPIO_CHV_INT_LOCK_THRESHOLD_SEL_COARSE	1 /* 1: coarse & 0 : fine  */
+#define CHV_PLL_DW9(ch) _PIPE(ch, _CHV_PLL_DW9_CH0, _CHV_PLL_DW9_CH1)
+
+#define _CHV_CMN_DW0_CH0               0x8100
+#define   DPIO_ALLDL_POWERDOWN_SHIFT_CH0	19
+#define   DPIO_ANYDL_POWERDOWN_SHIFT_CH0	18
+#define   DPIO_ALLDL_POWERDOWN			(1 << 1)
+#define   DPIO_ANYDL_POWERDOWN			(1 << 0)
+
+#define _CHV_CMN_DW5_CH0               0x8114
+#define   CHV_BUFRIGHTENA1_DISABLE	(0 << 20)
+#define   CHV_BUFRIGHTENA1_NORMAL	(1 << 20)
+#define   CHV_BUFRIGHTENA1_FORCE	(3 << 20)
+#define   CHV_BUFRIGHTENA1_MASK		(3 << 20)
+#define   CHV_BUFLEFTENA1_DISABLE	(0 << 22)
+#define   CHV_BUFLEFTENA1_NORMAL	(1 << 22)
+#define   CHV_BUFLEFTENA1_FORCE		(3 << 22)
+#define   CHV_BUFLEFTENA1_MASK		(3 << 22)
+
+#define _CHV_CMN_DW13_CH0		0x8134
+#define _CHV_CMN_DW0_CH1		0x8080
+#define   DPIO_CHV_S1_DIV_SHIFT		21
+#define   DPIO_CHV_P1_DIV_SHIFT		13 /* 3 bits */
+#define   DPIO_CHV_P2_DIV_SHIFT		8  /* 5 bits */
+#define   DPIO_CHV_K_DIV_SHIFT		4
+#define   DPIO_PLL_FREQLOCK		(1 << 1)
+#define   DPIO_PLL_LOCK			(1 << 0)
+#define CHV_CMN_DW13(ch) _PIPE(ch, _CHV_CMN_DW13_CH0, _CHV_CMN_DW0_CH1)
+
+#define _CHV_CMN_DW14_CH0		0x8138
+#define _CHV_CMN_DW1_CH1		0x8084
+#define   DPIO_AFC_RECAL		(1 << 14)
+#define   DPIO_DCLKP_EN			(1 << 13)
+#define   CHV_BUFLEFTENA2_DISABLE	(0 << 17) /* CL2 DW1 only */
+#define   CHV_BUFLEFTENA2_NORMAL	(1 << 17) /* CL2 DW1 only */
+#define   CHV_BUFLEFTENA2_FORCE		(3 << 17) /* CL2 DW1 only */
+#define   CHV_BUFLEFTENA2_MASK		(3 << 17) /* CL2 DW1 only */
+#define   CHV_BUFRIGHTENA2_DISABLE	(0 << 19) /* CL2 DW1 only */
+#define   CHV_BUFRIGHTENA2_NORMAL	(1 << 19) /* CL2 DW1 only */
+#define   CHV_BUFRIGHTENA2_FORCE	(3 << 19) /* CL2 DW1 only */
+#define   CHV_BUFRIGHTENA2_MASK		(3 << 19) /* CL2 DW1 only */
+#define CHV_CMN_DW14(ch) _PIPE(ch, _CHV_CMN_DW14_CH0, _CHV_CMN_DW1_CH1)
+
+#define _CHV_CMN_DW19_CH0		0x814c
+#define _CHV_CMN_DW6_CH1		0x8098
+#define   DPIO_ALLDL_POWERDOWN_SHIFT_CH1	30 /* CL2 DW6 only */
+#define   DPIO_ANYDL_POWERDOWN_SHIFT_CH1	29 /* CL2 DW6 only */
+#define   DPIO_DYNPWRDOWNEN_CH1		(1 << 28) /* CL2 DW6 only */
+#define   CHV_CMN_USEDCLKCHANNEL	(1 << 13)
+
+#define CHV_CMN_DW19(ch) _PIPE(ch, _CHV_CMN_DW19_CH0, _CHV_CMN_DW6_CH1)
+
+#define CHV_CMN_DW28			0x8170
+#define   DPIO_CL1POWERDOWNEN		(1 << 23)
+#define   DPIO_DYNPWRDOWNEN_CH0		(1 << 22)
+#define   DPIO_SUS_CLK_CONFIG_ON		(0 << 0)
+#define   DPIO_SUS_CLK_CONFIG_CLKREQ		(1 << 0)
+#define   DPIO_SUS_CLK_CONFIG_GATE		(2 << 0)
+#define   DPIO_SUS_CLK_CONFIG_GATE_CLKREQ	(3 << 0)
+
+#define CHV_CMN_DW30			0x8178
+#define   DPIO_CL2_LDOFUSE_PWRENB	(1 << 6)
+#define   DPIO_LRC_BYPASS		(1 << 3)
+
+#define _TXLANE(ch, lane, offset) ((ch ? 0x2400 : 0) + \
+					(lane) * 0x200 + (offset))
+
+#define CHV_TX_DW0(ch, lane) _TXLANE(ch, lane, 0x80)
+#define CHV_TX_DW1(ch, lane) _TXLANE(ch, lane, 0x84)
+#define CHV_TX_DW2(ch, lane) _TXLANE(ch, lane, 0x88)
+#define CHV_TX_DW3(ch, lane) _TXLANE(ch, lane, 0x8c)
+#define CHV_TX_DW4(ch, lane) _TXLANE(ch, lane, 0x90)
+#define CHV_TX_DW5(ch, lane) _TXLANE(ch, lane, 0x94)
+#define CHV_TX_DW6(ch, lane) _TXLANE(ch, lane, 0x98)
+#define CHV_TX_DW7(ch, lane) _TXLANE(ch, lane, 0x9c)
+#define CHV_TX_DW8(ch, lane) _TXLANE(ch, lane, 0xa0)
+#define CHV_TX_DW9(ch, lane) _TXLANE(ch, lane, 0xa4)
+#define CHV_TX_DW10(ch, lane) _TXLANE(ch, lane, 0xa8)
+#define CHV_TX_DW11(ch, lane) _TXLANE(ch, lane, 0xac)
+#define   DPIO_FRC_LATENCY_SHFIT	8
+#define CHV_TX_DW14(ch, lane) _TXLANE(ch, lane, 0xb8)
+#define   DPIO_UPAR_SHIFT		30
+
+/* BXT PHY registers */
+#define _BXT_PHY(phy, a, b)		_MMIO_PIPE((phy), (a), (b))
+
+#define BXT_P_CR_GT_DISP_PWRON		_MMIO(0x138090)
+#define   GT_DISPLAY_POWER_ON(phy)	(1 << (phy))
+
+#define _PHY_CTL_FAMILY_EDP		0x64C80
+#define _PHY_CTL_FAMILY_DDI		0x64C90
+#define   COMMON_RESET_DIS		(1 << 31)
+#define BXT_PHY_CTL_FAMILY(phy)		_BXT_PHY((phy), _PHY_CTL_FAMILY_DDI, \
+							_PHY_CTL_FAMILY_EDP)
+
+/* BXT PHY PLL registers */
+#define _PORT_PLL_A			0x46074
+#define _PORT_PLL_B			0x46078
+#define _PORT_PLL_C			0x4607c
+#define   PORT_PLL_ENABLE		(1 << 31)
+#define   PORT_PLL_LOCK			(1 << 30)
+#define   PORT_PLL_REF_SEL		(1 << 27)
+#define BXT_PORT_PLL_ENABLE(port)	_MMIO_PORT(port, _PORT_PLL_A, _PORT_PLL_B)
+
+#define _PORT_PLL_EBB_0_A		0x162034
+#define _PORT_PLL_EBB_0_B		0x6C034
+#define _PORT_PLL_EBB_0_C		0x6C340
+#define   PORT_PLL_P1_SHIFT		13
+#define   PORT_PLL_P1_MASK		(0x07 << PORT_PLL_P1_SHIFT)
+#define   PORT_PLL_P1(x)		((x)  << PORT_PLL_P1_SHIFT)
+#define   PORT_PLL_P2_SHIFT		8
+#define   PORT_PLL_P2_MASK		(0x1f << PORT_PLL_P2_SHIFT)
+#define   PORT_PLL_P2(x)		((x)  << PORT_PLL_P2_SHIFT)
+#define BXT_PORT_PLL_EBB_0(port)	_MMIO_PORT3(port, _PORT_PLL_EBB_0_A, \
+						_PORT_PLL_EBB_0_B,	\
+						_PORT_PLL_EBB_0_C)
+
+#define _PORT_PLL_EBB_4_A		0x162038
+#define _PORT_PLL_EBB_4_B		0x6C038
+#define _PORT_PLL_EBB_4_C		0x6C344
+#define   PORT_PLL_10BIT_CLK_ENABLE	(1 << 13)
+#define   PORT_PLL_RECALIBRATE		(1 << 14)
+#define BXT_PORT_PLL_EBB_4(port)	_MMIO_PORT3(port, _PORT_PLL_EBB_4_A, \
+						_PORT_PLL_EBB_4_B,	\
+						_PORT_PLL_EBB_4_C)
+
+#define _PORT_PLL_0_A			0x162100
+#define _PORT_PLL_0_B			0x6C100
+#define _PORT_PLL_0_C			0x6C380
+/* PORT_PLL_0_A */
+#define   PORT_PLL_M2_MASK		0xFF
+/* PORT_PLL_1_A */
+#define   PORT_PLL_N_SHIFT		8
+#define   PORT_PLL_N_MASK		(0x0F << PORT_PLL_N_SHIFT)
+#define   PORT_PLL_N(x)			((x) << PORT_PLL_N_SHIFT)
+/* PORT_PLL_2_A */
+#define   PORT_PLL_M2_FRAC_MASK		0x3FFFFF
+/* PORT_PLL_3_A */
+#define   PORT_PLL_M2_FRAC_ENABLE	(1 << 16)
+/* PORT_PLL_6_A */
+#define   PORT_PLL_PROP_COEFF_MASK	0xF
+#define   PORT_PLL_INT_COEFF_MASK	(0x1F << 8)
+#define   PORT_PLL_INT_COEFF(x)		((x)  << 8)
+#define   PORT_PLL_GAIN_CTL_MASK	(0x07 << 16)
+#define   PORT_PLL_GAIN_CTL(x)		((x)  << 16)
+/* PORT_PLL_8_A */
+#define   PORT_PLL_TARGET_CNT_MASK	0x3FF
+/* PORT_PLL_9_A */
+#define  PORT_PLL_LOCK_THRESHOLD_SHIFT	1
+#define  PORT_PLL_LOCK_THRESHOLD_MASK	(0x7 << PORT_PLL_LOCK_THRESHOLD_SHIFT)
+/* PORT_PLL_10_A */
+#define  PORT_PLL_DCO_AMP_OVR_EN_H	(1<<27)
+#define  PORT_PLL_DCO_AMP_DEFAULT	15
+#define  PORT_PLL_DCO_AMP_MASK		0x3c00
+#define  PORT_PLL_DCO_AMP(x)		((x)<<10)
+#define _PORT_PLL_BASE(port)		_PORT3(port, _PORT_PLL_0_A,	\
+						_PORT_PLL_0_B,		\
+						_PORT_PLL_0_C)
+#define BXT_PORT_PLL(port, idx)		_MMIO(_PORT_PLL_BASE(port) + (idx) * 4)
+
+/* BXT PHY common lane registers */
+#define _PORT_CL1CM_DW0_A		0x162000
+#define _PORT_CL1CM_DW0_BC		0x6C000
+#define   PHY_POWER_GOOD		(1 << 16)
+#define   PHY_RESERVED			(1 << 7)
+#define BXT_PORT_CL1CM_DW0(phy)		_BXT_PHY((phy), _PORT_CL1CM_DW0_BC, \
+							_PORT_CL1CM_DW0_A)
+
+#define _PORT_CL1CM_DW9_A		0x162024
+#define _PORT_CL1CM_DW9_BC		0x6C024
+#define   IREF0RC_OFFSET_SHIFT		8
+#define   IREF0RC_OFFSET_MASK		(0xFF << IREF0RC_OFFSET_SHIFT)
+#define BXT_PORT_CL1CM_DW9(phy)		_BXT_PHY((phy), _PORT_CL1CM_DW9_BC, \
+							_PORT_CL1CM_DW9_A)
+
+#define _PORT_CL1CM_DW10_A		0x162028
+#define _PORT_CL1CM_DW10_BC		0x6C028
+#define   IREF1RC_OFFSET_SHIFT		8
+#define   IREF1RC_OFFSET_MASK		(0xFF << IREF1RC_OFFSET_SHIFT)
+#define BXT_PORT_CL1CM_DW10(phy)	_BXT_PHY((phy), _PORT_CL1CM_DW10_BC, \
+							_PORT_CL1CM_DW10_A)
+
+#define _PORT_CL1CM_DW28_A		0x162070
+#define _PORT_CL1CM_DW28_BC		0x6C070
+#define   OCL1_POWER_DOWN_EN		(1 << 23)
+#define   DW28_OLDO_DYN_PWR_DOWN_EN	(1 << 22)
+#define   SUS_CLK_CONFIG		0x3
+#define BXT_PORT_CL1CM_DW28(phy)	_BXT_PHY((phy), _PORT_CL1CM_DW28_BC, \
+							_PORT_CL1CM_DW28_A)
+
+#define _PORT_CL1CM_DW30_A		0x162078
+#define _PORT_CL1CM_DW30_BC		0x6C078
+#define   OCL2_LDOFUSE_PWR_DIS		(1 << 6)
+#define BXT_PORT_CL1CM_DW30(phy)	_BXT_PHY((phy), _PORT_CL1CM_DW30_BC, \
+							_PORT_CL1CM_DW30_A)
+
+/* Defined for PHY0 only */
+#define BXT_PORT_CL2CM_DW6_BC		_MMIO(0x6C358)
+#define   DW6_OLDO_DYN_PWR_DOWN_EN	(1 << 28)
+
+/* BXT PHY Ref registers */
+#define _PORT_REF_DW3_A			0x16218C
+#define _PORT_REF_DW3_BC		0x6C18C
+#define   GRC_DONE			(1 << 22)
+#define BXT_PORT_REF_DW3(phy)		_BXT_PHY((phy), _PORT_REF_DW3_BC, \
+							_PORT_REF_DW3_A)
+
+#define _PORT_REF_DW6_A			0x162198
+#define _PORT_REF_DW6_BC		0x6C198
+#define   GRC_CODE_SHIFT		24
+#define   GRC_CODE_MASK			(0xFF << GRC_CODE_SHIFT)
+#define   GRC_CODE_FAST_SHIFT		16
+#define   GRC_CODE_FAST_MASK		(0xFF << GRC_CODE_FAST_SHIFT)
+#define   GRC_CODE_SLOW_SHIFT		8
+#define   GRC_CODE_SLOW_MASK		(0xFF << GRC_CODE_SLOW_SHIFT)
+#define   GRC_CODE_NOM_MASK		0xFF
+#define BXT_PORT_REF_DW6(phy)		_BXT_PHY((phy), _PORT_REF_DW6_BC,	\
+						      _PORT_REF_DW6_A)
+
+#define _PORT_REF_DW8_A			0x1621A0
+#define _PORT_REF_DW8_BC		0x6C1A0
+#define   GRC_DIS			(1 << 15)
+#define   GRC_RDY_OVRD			(1 << 1)
+#define BXT_PORT_REF_DW8(phy)		_BXT_PHY((phy), _PORT_REF_DW8_BC,	\
+						      _PORT_REF_DW8_A)
+
+/* BXT PHY PCS registers */
+#define _PORT_PCS_DW10_LN01_A		0x162428
+#define _PORT_PCS_DW10_LN01_B		0x6C428
+#define _PORT_PCS_DW10_LN01_C		0x6C828
+#define _PORT_PCS_DW10_GRP_A		0x162C28
+#define _PORT_PCS_DW10_GRP_B		0x6CC28
+#define _PORT_PCS_DW10_GRP_C		0x6CE28
+#define BXT_PORT_PCS_DW10_LN01(port)	_MMIO_PORT3(port, _PORT_PCS_DW10_LN01_A, \
+						     _PORT_PCS_DW10_LN01_B, \
+						     _PORT_PCS_DW10_LN01_C)
+#define BXT_PORT_PCS_DW10_GRP(port)	_MMIO_PORT3(port, _PORT_PCS_DW10_GRP_A,  \
+						     _PORT_PCS_DW10_GRP_B,  \
+						     _PORT_PCS_DW10_GRP_C)
+#define   TX2_SWING_CALC_INIT		(1 << 31)
+#define   TX1_SWING_CALC_INIT		(1 << 30)
+
+#define _PORT_PCS_DW12_LN01_A		0x162430
+#define _PORT_PCS_DW12_LN01_B		0x6C430
+#define _PORT_PCS_DW12_LN01_C		0x6C830
+#define _PORT_PCS_DW12_LN23_A		0x162630
+#define _PORT_PCS_DW12_LN23_B		0x6C630
+#define _PORT_PCS_DW12_LN23_C		0x6CA30
+#define _PORT_PCS_DW12_GRP_A		0x162c30
+#define _PORT_PCS_DW12_GRP_B		0x6CC30
+#define _PORT_PCS_DW12_GRP_C		0x6CE30
+#define   LANESTAGGER_STRAP_OVRD	(1 << 6)
+#define   LANE_STAGGER_MASK		0x1F
+#define BXT_PORT_PCS_DW12_LN01(port)	_MMIO_PORT3(port, _PORT_PCS_DW12_LN01_A, \
+						     _PORT_PCS_DW12_LN01_B, \
+						     _PORT_PCS_DW12_LN01_C)
+#define BXT_PORT_PCS_DW12_LN23(port)	_MMIO_PORT3(port, _PORT_PCS_DW12_LN23_A, \
+						     _PORT_PCS_DW12_LN23_B, \
+						     _PORT_PCS_DW12_LN23_C)
+#define BXT_PORT_PCS_DW12_GRP(port)	_MMIO_PORT3(port, _PORT_PCS_DW12_GRP_A, \
+						     _PORT_PCS_DW12_GRP_B, \
+						     _PORT_PCS_DW12_GRP_C)
+
+/* BXT PHY TX registers */
+#define _BXT_LANE_OFFSET(lane)           (((lane) >> 1) * 0x200 +	\
+					  ((lane) & 1) * 0x80)
+
+#define _PORT_TX_DW2_LN0_A		0x162508
+#define _PORT_TX_DW2_LN0_B		0x6C508
+#define _PORT_TX_DW2_LN0_C		0x6C908
+#define _PORT_TX_DW2_GRP_A		0x162D08
+#define _PORT_TX_DW2_GRP_B		0x6CD08
+#define _PORT_TX_DW2_GRP_C		0x6CF08
+#define BXT_PORT_TX_DW2_GRP(port)	_MMIO_PORT3(port, _PORT_TX_DW2_GRP_A,  \
+						     _PORT_TX_DW2_GRP_B,  \
+						     _PORT_TX_DW2_GRP_C)
+#define BXT_PORT_TX_DW2_LN0(port)	_MMIO_PORT3(port, _PORT_TX_DW2_LN0_A,  \
+						     _PORT_TX_DW2_LN0_B,  \
+						     _PORT_TX_DW2_LN0_C)
+#define   MARGIN_000_SHIFT		16
+#define   MARGIN_000			(0xFF << MARGIN_000_SHIFT)
+#define   UNIQ_TRANS_SCALE_SHIFT	8
+#define   UNIQ_TRANS_SCALE		(0xFF << UNIQ_TRANS_SCALE_SHIFT)
+
+#define _PORT_TX_DW3_LN0_A		0x16250C
+#define _PORT_TX_DW3_LN0_B		0x6C50C
+#define _PORT_TX_DW3_LN0_C		0x6C90C
+#define _PORT_TX_DW3_GRP_A		0x162D0C
+#define _PORT_TX_DW3_GRP_B		0x6CD0C
+#define _PORT_TX_DW3_GRP_C		0x6CF0C
+#define BXT_PORT_TX_DW3_GRP(port)	_MMIO_PORT3(port, _PORT_TX_DW3_GRP_A,  \
+						     _PORT_TX_DW3_GRP_B,  \
+						     _PORT_TX_DW3_GRP_C)
+#define BXT_PORT_TX_DW3_LN0(port)	_MMIO_PORT3(port, _PORT_TX_DW3_LN0_A,  \
+						     _PORT_TX_DW3_LN0_B,  \
+						     _PORT_TX_DW3_LN0_C)
+#define   SCALE_DCOMP_METHOD		(1 << 26)
+#define   UNIQUE_TRANGE_EN_METHOD	(1 << 27)
+
+#define _PORT_TX_DW4_LN0_A		0x162510
+#define _PORT_TX_DW4_LN0_B		0x6C510
+#define _PORT_TX_DW4_LN0_C		0x6C910
+#define _PORT_TX_DW4_GRP_A		0x162D10
+#define _PORT_TX_DW4_GRP_B		0x6CD10
+#define _PORT_TX_DW4_GRP_C		0x6CF10
+#define BXT_PORT_TX_DW4_LN0(port)	_MMIO_PORT3(port, _PORT_TX_DW4_LN0_A,  \
+						     _PORT_TX_DW4_LN0_B,  \
+						     _PORT_TX_DW4_LN0_C)
+#define BXT_PORT_TX_DW4_GRP(port)	_MMIO_PORT3(port, _PORT_TX_DW4_GRP_A,  \
+						     _PORT_TX_DW4_GRP_B,  \
+						     _PORT_TX_DW4_GRP_C)
+#define   DEEMPH_SHIFT			24
+#define   DE_EMPHASIS			(0xFF << DEEMPH_SHIFT)
+
+#define _PORT_TX_DW14_LN0_A		0x162538
+#define _PORT_TX_DW14_LN0_B		0x6C538
+#define _PORT_TX_DW14_LN0_C		0x6C938
+#define   LATENCY_OPTIM_SHIFT		30
+#define   LATENCY_OPTIM			(1 << LATENCY_OPTIM_SHIFT)
+#define BXT_PORT_TX_DW14_LN(port, lane)	_MMIO(_PORT3((port), _PORT_TX_DW14_LN0_A,   \
+							_PORT_TX_DW14_LN0_B,   \
+							_PORT_TX_DW14_LN0_C) + \
+					 _BXT_LANE_OFFSET(lane))
+
+/* UAIMI scratch pad register 1 */
+#define UAIMI_SPR1			_MMIO(0x4F074)
+/* SKL VccIO mask */
+#define SKL_VCCIO_MASK			0x1
+/* SKL balance leg register */
+#define DISPIO_CR_TX_BMU_CR0		_MMIO(0x6C00C)
+/* I_boost values */
+#define BALANCE_LEG_SHIFT(port)		(8+3*(port))
+#define BALANCE_LEG_MASK(port)		(7<<(8+3*(port)))
+/* Balance leg disable bits */
+#define BALANCE_LEG_DISABLE_SHIFT	23
+
+/*
+ * Fence registers
+ * [0-7]  @ 0x2000 gen2,gen3
+ * [8-15] @ 0x3000 945,g33,pnv
+ *
+ * [0-15] @ 0x3000 gen4,gen5
+ *
+ * [0-15] @ 0x100000 gen6,vlv,chv
+ * [0-31] @ 0x100000 gen7+
+ */
+#define FENCE_REG(i)			_MMIO(0x2000 + (((i) & 8) << 9) + ((i) & 7) * 4)
+#define   I830_FENCE_START_MASK		0x07f80000
+#define   I830_FENCE_TILING_Y_SHIFT	12
+#define   I830_FENCE_SIZE_BITS(size)	((ffs((size) >> 19) - 1) << 8)
+#define   I830_FENCE_PITCH_SHIFT	4
+#define   I830_FENCE_REG_VALID		(1<<0)
+#define   I915_FENCE_MAX_PITCH_VAL	4
+#define   I830_FENCE_MAX_PITCH_VAL	6
+#define   I830_FENCE_MAX_SIZE_VAL	(1<<8)
+
+#define   I915_FENCE_START_MASK		0x0ff00000
+#define   I915_FENCE_SIZE_BITS(size)	((ffs((size) >> 20) - 1) << 8)
+
+#define FENCE_REG_965_LO(i)		_MMIO(0x03000 + (i) * 8)
+#define FENCE_REG_965_HI(i)		_MMIO(0x03000 + (i) * 8 + 4)
+#define   I965_FENCE_PITCH_SHIFT	2
+#define   I965_FENCE_TILING_Y_SHIFT	1
+#define   I965_FENCE_REG_VALID		(1<<0)
+#define   I965_FENCE_MAX_PITCH_VAL	0x0400
+
+#define FENCE_REG_GEN6_LO(i)		_MMIO(0x100000 + (i) * 8)
+#define FENCE_REG_GEN6_HI(i)		_MMIO(0x100000 + (i) * 8 + 4)
+#define   GEN6_FENCE_PITCH_SHIFT	32
+#define   GEN7_FENCE_MAX_PITCH_VAL	0x0800
+
+
+/* control register for cpu gtt access */
+#define TILECTL				_MMIO(0x101000)
+#define   TILECTL_SWZCTL			(1 << 0)
+#define   TILECTL_TLBPF			(1 << 1)
+#define   TILECTL_TLB_PREFETCH_DIS	(1 << 2)
+#define   TILECTL_BACKSNOOP_DIS		(1 << 3)
+
+/*
+ * Instruction and interrupt control regs
+ */
+#define PGTBL_CTL	_MMIO(0x02020)
+#define   PGTBL_ADDRESS_LO_MASK	0xfffff000 /* bits [31:12] */
+#define   PGTBL_ADDRESS_HI_MASK	0x000000f0 /* bits [35:32] (gen4) */
+#define PGTBL_ER	_MMIO(0x02024)
+#define PRB0_BASE	(0x2030-0x30)
+#define PRB1_BASE	(0x2040-0x30) /* 830,gen3 */
+#define PRB2_BASE	(0x2050-0x30) /* gen3 */
+#define SRB0_BASE	(0x2100-0x30) /* gen2 */
+#define SRB1_BASE	(0x2110-0x30) /* gen2 */
+#define SRB2_BASE	(0x2120-0x30) /* 830 */
+#define SRB3_BASE	(0x2130-0x30) /* 830 */
+#define RENDER_RING_BASE	0x02000
+#define BSD_RING_BASE		0x04000
+#define GEN6_BSD_RING_BASE	0x12000
+#define GEN8_BSD2_RING_BASE	0x1c000
+#define VEBOX_RING_BASE		0x1a000
+#define BLT_RING_BASE		0x22000
+#define RING_TAIL(base)		_MMIO((base)+0x30)
+#define RING_HEAD(base)		_MMIO((base)+0x34)
+#define RING_START(base)	_MMIO((base)+0x38)
+#define RING_CTL(base)		_MMIO((base)+0x3c)
+#define RING_SYNC_0(base)	_MMIO((base)+0x40)
+#define RING_SYNC_1(base)	_MMIO((base)+0x44)
+#define RING_SYNC_2(base)	_MMIO((base)+0x48)
+#define GEN6_RVSYNC	(RING_SYNC_0(RENDER_RING_BASE))
+#define GEN6_RBSYNC	(RING_SYNC_1(RENDER_RING_BASE))
+#define GEN6_RVESYNC	(RING_SYNC_2(RENDER_RING_BASE))
+#define GEN6_VBSYNC	(RING_SYNC_0(GEN6_BSD_RING_BASE))
+#define GEN6_VRSYNC	(RING_SYNC_1(GEN6_BSD_RING_BASE))
+#define GEN6_VVESYNC	(RING_SYNC_2(GEN6_BSD_RING_BASE))
+#define GEN6_BRSYNC	(RING_SYNC_0(BLT_RING_BASE))
+#define GEN6_BVSYNC	(RING_SYNC_1(BLT_RING_BASE))
+#define GEN6_BVESYNC	(RING_SYNC_2(BLT_RING_BASE))
+#define GEN6_VEBSYNC	(RING_SYNC_0(VEBOX_RING_BASE))
+#define GEN6_VERSYNC	(RING_SYNC_1(VEBOX_RING_BASE))
+#define GEN6_VEVSYNC	(RING_SYNC_2(VEBOX_RING_BASE))
+#define GEN6_NOSYNC	INVALID_MMIO_REG
+#define RING_PSMI_CTL(base)	_MMIO((base)+0x50)
+#define RING_MAX_IDLE(base)	_MMIO((base)+0x54)
+#define RING_HWS_PGA(base)	_MMIO((base)+0x80)
+#define RING_HWS_PGA_GEN6(base)	_MMIO((base)+0x2080)
+#define RING_RESET_CTL(base)	_MMIO((base)+0xd0)
+#define   RESET_CTL_REQUEST_RESET  (1 << 0)
+#define   RESET_CTL_READY_TO_RESET (1 << 1)
+
+#define HSW_GTT_CACHE_EN	_MMIO(0x4024)
+#define   GTT_CACHE_EN_ALL	0xF0007FFF
+#define GEN7_WR_WATERMARK	_MMIO(0x4028)
+#define GEN7_GFX_PRIO_CTRL	_MMIO(0x402C)
+#define ARB_MODE		_MMIO(0x4030)
+#define   ARB_MODE_SWIZZLE_SNB	(1<<4)
+#define   ARB_MODE_SWIZZLE_IVB	(1<<5)
+#define GEN7_GFX_PEND_TLB0	_MMIO(0x4034)
+#define GEN7_GFX_PEND_TLB1	_MMIO(0x4038)
+/* L3, CVS, ZTLB, RCC, CASC LRA min, max values */
+#define GEN7_LRA_LIMITS(i)	_MMIO(0x403C + (i) * 4)
+#define GEN7_LRA_LIMITS_REG_NUM	13
+#define GEN7_MEDIA_MAX_REQ_COUNT	_MMIO(0x4070)
+#define GEN7_GFX_MAX_REQ_COUNT		_MMIO(0x4074)
+
+#define GAMTARBMODE		_MMIO(0x04a08)
+#define   ARB_MODE_BWGTLB_DISABLE (1<<9)
+#define   ARB_MODE_SWIZZLE_BDW	(1<<1)
+#define RENDER_HWS_PGA_GEN7	_MMIO(0x04080)
+#define RING_FAULT_REG(ring)	_MMIO(0x4094 + 0x100*(ring)->id)
+#define   RING_FAULT_GTTSEL_MASK (1<<11)
+#define   RING_FAULT_SRCID(x)	(((x) >> 3) & 0xff)
+#define   RING_FAULT_FAULT_TYPE(x) (((x) >> 1) & 0x3)
+#define   RING_FAULT_VALID	(1<<0)
+#define DONE_REG		_MMIO(0x40b0)
+#define GEN8_PRIVATE_PAT_LO	_MMIO(0x40e0)
+#define GEN8_PRIVATE_PAT_HI	_MMIO(0x40e0 + 4)
+#define BSD_HWS_PGA_GEN7	_MMIO(0x04180)
+#define BLT_HWS_PGA_GEN7	_MMIO(0x04280)
+#define VEBOX_HWS_PGA_GEN7	_MMIO(0x04380)
+#define RING_ACTHD(base)	_MMIO((base)+0x74)
+#define RING_ACTHD_UDW(base)	_MMIO((base)+0x5c)
+#define RING_NOPID(base)	_MMIO((base)+0x94)
+#define RING_IMR(base)		_MMIO((base)+0xa8)
+#define RING_HWSTAM(base)	_MMIO((base)+0x98)
+#define RING_TIMESTAMP(base)		_MMIO((base)+0x358)
+#define RING_TIMESTAMP_UDW(base)	_MMIO((base)+0x358 + 4)
+#define   TAIL_ADDR		0x001FFFF8
+#define   HEAD_WRAP_COUNT	0xFFE00000
+#define   HEAD_WRAP_ONE		0x00200000
+#define   HEAD_ADDR		0x001FFFFC
+#define   RING_NR_PAGES		0x001FF000
+#define   RING_REPORT_MASK	0x00000006
+#define   RING_REPORT_64K	0x00000002
+#define   RING_REPORT_128K	0x00000004
+#define   RING_NO_REPORT	0x00000000
+#define   RING_VALID_MASK	0x00000001
+#define   RING_VALID		0x00000001
+#define   RING_INVALID		0x00000000
+#define   RING_WAIT_I8XX	(1<<0) /* gen2, PRBx_HEAD */
+#define   RING_WAIT		(1<<11) /* gen3+, PRBx_CTL */
+#define   RING_WAIT_SEMAPHORE	(1<<10) /* gen6+ */
+
+#define RING_FORCE_TO_NONPRIV(base, i) _MMIO(((base)+0x4D0) + (i)*4)
+#define   RING_MAX_NONPRIV_SLOTS  12
+
+#define GEN7_TLB_RD_ADDR	_MMIO(0x4700)
+
+#define GAMT_CHKN_BIT_REG	_MMIO(0x4ab8)
+#define   GAMT_CHKN_DISABLE_DYNAMIC_CREDIT_SHARING	(1<<28)
+
+#if 0
+#define PRB0_TAIL	_MMIO(0x2030)
+#define PRB0_HEAD	_MMIO(0x2034)
+#define PRB0_START	_MMIO(0x2038)
+#define PRB0_CTL	_MMIO(0x203c)
+#define PRB1_TAIL	_MMIO(0x2040) /* 915+ only */
+#define PRB1_HEAD	_MMIO(0x2044) /* 915+ only */
+#define PRB1_START	_MMIO(0x2048) /* 915+ only */
+#define PRB1_CTL	_MMIO(0x204c) /* 915+ only */
+#endif
+#define IPEIR_I965	_MMIO(0x2064)
+#define IPEHR_I965	_MMIO(0x2068)
+#define GEN7_SC_INSTDONE	_MMIO(0x7100)
+#define GEN7_SAMPLER_INSTDONE	_MMIO(0xe160)
+#define GEN7_ROW_INSTDONE	_MMIO(0xe164)
+#define I915_NUM_INSTDONE_REG	4
+#define RING_IPEIR(base)	_MMIO((base)+0x64)
+#define RING_IPEHR(base)	_MMIO((base)+0x68)
+/*
+ * On GEN4, only the render ring INSTDONE exists and has a different
+ * layout than the GEN7+ version.
+ * The GEN2 counterpart of this register is GEN2_INSTDONE.
+ */
+#define RING_INSTDONE(base)	_MMIO((base)+0x6c)
+#define RING_INSTPS(base)	_MMIO((base)+0x70)
+#define RING_DMA_FADD(base)	_MMIO((base)+0x78)
+#define RING_DMA_FADD_UDW(base)	_MMIO((base)+0x60) /* gen8+ */
+#define RING_INSTPM(base)	_MMIO((base)+0xc0)
+#define RING_MI_MODE(base)	_MMIO((base)+0x9c)
+#define INSTPS		_MMIO(0x2070) /* 965+ only */
+#define GEN4_INSTDONE1	_MMIO(0x207c) /* 965+ only, aka INSTDONE_2 on SNB */
+#define ACTHD_I965	_MMIO(0x2074)
+#define HWS_PGA		_MMIO(0x2080)
+#define HWS_ADDRESS_MASK	0xfffff000
+#define HWS_START_ADDRESS_SHIFT	4
+#define PWRCTXA		_MMIO(0x2088) /* 965GM+ only */
+#define   PWRCTX_EN	(1<<0)
+#define IPEIR		_MMIO(0x2088)
+#define IPEHR		_MMIO(0x208c)
+#define GEN2_INSTDONE	_MMIO(0x2090)
+#define NOPID		_MMIO(0x2094)
+#define HWSTAM		_MMIO(0x2098)
+#define DMA_FADD_I8XX	_MMIO(0x20d0)
+#define RING_BBSTATE(base)	_MMIO((base)+0x110)
+#define   RING_BB_PPGTT		(1 << 5)
+#define RING_SBBADDR(base)	_MMIO((base)+0x114) /* hsw+ */
+#define RING_SBBSTATE(base)	_MMIO((base)+0x118) /* hsw+ */
+#define RING_SBBADDR_UDW(base)	_MMIO((base)+0x11c) /* gen8+ */
+#define RING_BBADDR(base)	_MMIO((base)+0x140)
+#define RING_BBADDR_UDW(base)	_MMIO((base)+0x168) /* gen8+ */
+#define RING_BB_PER_CTX_PTR(base)	_MMIO((base)+0x1c0) /* gen8+ */
+#define RING_INDIRECT_CTX(base)		_MMIO((base)+0x1c4) /* gen8+ */
+#define RING_INDIRECT_CTX_OFFSET(base)	_MMIO((base)+0x1c8) /* gen8+ */
+#define RING_CTX_TIMESTAMP(base)	_MMIO((base)+0x3a8) /* gen8+ */
+
+#define ERROR_GEN6	_MMIO(0x40a0)
+#define GEN7_ERR_INT	_MMIO(0x44040)
+#define   ERR_INT_POISON		(1<<31)
+#define   ERR_INT_MMIO_UNCLAIMED	(1<<13)
+#define   ERR_INT_PIPE_CRC_DONE_C	(1<<8)
+#define   ERR_INT_FIFO_UNDERRUN_C	(1<<6)
+#define   ERR_INT_PIPE_CRC_DONE_B	(1<<5)
+#define   ERR_INT_FIFO_UNDERRUN_B	(1<<3)
+#define   ERR_INT_PIPE_CRC_DONE_A	(1<<2)
+#define   ERR_INT_PIPE_CRC_DONE(pipe)	(1<<(2 + (pipe)*3))
+#define   ERR_INT_FIFO_UNDERRUN_A	(1<<0)
+#define   ERR_INT_FIFO_UNDERRUN(pipe)	(1<<((pipe)*3))
+
+#define GEN8_FAULT_TLB_DATA0		_MMIO(0x4b10)
+#define GEN8_FAULT_TLB_DATA1		_MMIO(0x4b14)
+
+#define FPGA_DBG		_MMIO(0x42300)
+#define   FPGA_DBG_RM_NOCLAIM	(1<<31)
+
+#define CLAIM_ER		_MMIO(VLV_DISPLAY_BASE + 0x2028)
+#define   CLAIM_ER_CLR		(1 << 31)
+#define   CLAIM_ER_OVERFLOW	(1 << 16)
+#define   CLAIM_ER_CTR_MASK	0xffff
+
+#define DERRMR		_MMIO(0x44050)
+/* Note that HBLANK events are reserved on bdw+ */
+#define   DERRMR_PIPEA_SCANLINE		(1<<0)
+#define   DERRMR_PIPEA_PRI_FLIP_DONE	(1<<1)
+#define   DERRMR_PIPEA_SPR_FLIP_DONE	(1<<2)
+#define   DERRMR_PIPEA_VBLANK		(1<<3)
+#define   DERRMR_PIPEA_HBLANK		(1<<5)
+#define   DERRMR_PIPEB_SCANLINE 	(1<<8)
+#define   DERRMR_PIPEB_PRI_FLIP_DONE	(1<<9)
+#define   DERRMR_PIPEB_SPR_FLIP_DONE	(1<<10)
+#define   DERRMR_PIPEB_VBLANK		(1<<11)
+#define   DERRMR_PIPEB_HBLANK		(1<<13)
+/* Note that PIPEC is not a simple translation of PIPEA/PIPEB */
+#define   DERRMR_PIPEC_SCANLINE		(1<<14)
+#define   DERRMR_PIPEC_PRI_FLIP_DONE	(1<<15)
+#define   DERRMR_PIPEC_SPR_FLIP_DONE	(1<<20)
+#define   DERRMR_PIPEC_VBLANK		(1<<21)
+#define   DERRMR_PIPEC_HBLANK		(1<<22)
+
+
+/* GM45+ chicken bits -- debug workaround bits that may be required
+ * for various sorts of correct behavior.  The top 16 bits of each are
+ * the enables for writing to the corresponding low bit.
+ */
+#define _3D_CHICKEN	_MMIO(0x2084)
+#define  _3D_CHICKEN_HIZ_PLANE_DISABLE_MSAA_4X_SNB	(1 << 10)
+#define _3D_CHICKEN2	_MMIO(0x208c)
+/* Disables pipelining of read flushes past the SF-WIZ interface.
+ * Required on all Ironlake steppings according to the B-Spec, but the
+ * particular danger of not doing so is not specified.
+ */
+# define _3D_CHICKEN2_WM_READ_PIPELINED			(1 << 14)
+#define _3D_CHICKEN3	_MMIO(0x2090)
+#define  _3D_CHICKEN_SF_DISABLE_OBJEND_CULL		(1 << 10)
+#define  _3D_CHICKEN3_SF_DISABLE_FASTCLIP_CULL		(1 << 5)
+#define  _3D_CHICKEN_SDE_LIMIT_FIFO_POLY_DEPTH(x)	((x)<<1) /* gen8+ */
+#define  _3D_CHICKEN3_SF_DISABLE_PIPELINED_ATTR_FETCH	(1 << 1) /* gen6 */
+
+#define MI_MODE		_MMIO(0x209c)
+# define VS_TIMER_DISPATCH				(1 << 6)
+# define MI_FLUSH_ENABLE				(1 << 12)
+# define ASYNC_FLIP_PERF_DISABLE			(1 << 14)
+# define MODE_IDLE					(1 << 9)
+# define STOP_RING					(1 << 8)
+
+#define GEN6_GT_MODE	_MMIO(0x20d0)
+#define GEN7_GT_MODE	_MMIO(0x7008)
+#define   GEN6_WIZ_HASHING(hi, lo)			(((hi) << 9) | ((lo) << 7))
+#define   GEN6_WIZ_HASHING_8x8				GEN6_WIZ_HASHING(0, 0)
+#define   GEN6_WIZ_HASHING_8x4				GEN6_WIZ_HASHING(0, 1)
+#define   GEN6_WIZ_HASHING_16x4				GEN6_WIZ_HASHING(1, 0)
+#define   GEN6_WIZ_HASHING_MASK				GEN6_WIZ_HASHING(1, 1)
+#define   GEN6_TD_FOUR_ROW_DISPATCH_DISABLE		(1 << 5)
+#define   GEN9_IZ_HASHING_MASK(slice)			(0x3 << ((slice) * 2))
+#define   GEN9_IZ_HASHING(slice, val)			((val) << ((slice) * 2))
+
+/* chicken reg for WaConextSwitchWithConcurrentTLBInvalidate */
+#define GEN9_CSFE_CHICKEN1_RCS _MMIO(0x20D4)
+#define   GEN9_PREEMPT_GPGPU_SYNC_SWITCH_DISABLE (1 << 2)
+
+/* WaClearTdlStateAckDirtyBits */
+#define GEN8_STATE_ACK		_MMIO(0x20F0)
+#define GEN9_STATE_ACK_SLICE1	_MMIO(0x20F8)
+#define GEN9_STATE_ACK_SLICE2	_MMIO(0x2100)
+#define   GEN9_STATE_ACK_TDL0 (1 << 12)
+#define   GEN9_STATE_ACK_TDL1 (1 << 13)
+#define   GEN9_STATE_ACK_TDL2 (1 << 14)
+#define   GEN9_STATE_ACK_TDL3 (1 << 15)
+#define   GEN9_SUBSLICE_TDL_ACK_BITS \
+	(GEN9_STATE_ACK_TDL3 | GEN9_STATE_ACK_TDL2 | \
+	 GEN9_STATE_ACK_TDL1 | GEN9_STATE_ACK_TDL0)
+
+#define GFX_MODE	_MMIO(0x2520)
+#define GFX_MODE_GEN7	_MMIO(0x229c)
+#define RING_MODE_GEN7(ring)	_MMIO((ring)->mmio_base+0x29c)
+#define   GFX_RUN_LIST_ENABLE		(1<<15)
+#define   GFX_INTERRUPT_STEERING	(1<<14)
+#define   GFX_TLB_INVALIDATE_EXPLICIT	(1<<13)
+#define   GFX_SURFACE_FAULT_ENABLE	(1<<12)
+#define   GFX_REPLAY_MODE		(1<<11)
+#define   GFX_PSMI_GRANULARITY		(1<<10)
+#define   GFX_PPGTT_ENABLE		(1<<9)
+#define   GEN8_GFX_PPGTT_48B		(1<<7)
+
+#define   GFX_FORWARD_VBLANK_MASK	(3<<5)
+#define   GFX_FORWARD_VBLANK_NEVER	(0<<5)
+#define   GFX_FORWARD_VBLANK_ALWAYS	(1<<5)
+#define   GFX_FORWARD_VBLANK_COND	(2<<5)
+
+#define VLV_DISPLAY_BASE 0x180000
+#define VLV_MIPI_BASE VLV_DISPLAY_BASE
+#define BXT_MIPI_BASE 0x60000
+
+#define VLV_GU_CTL0	_MMIO(VLV_DISPLAY_BASE + 0x2030)
+#define VLV_GU_CTL1	_MMIO(VLV_DISPLAY_BASE + 0x2034)
+#define SCPD0		_MMIO(0x209c) /* 915+ only */
+#define IER		_MMIO(0x20a0)
+#define IIR		_MMIO(0x20a4)
+#define IMR		_MMIO(0x20a8)
+#define ISR		_MMIO(0x20ac)
+#define VLV_GUNIT_CLOCK_GATE	_MMIO(VLV_DISPLAY_BASE + 0x2060)
+#define   GINT_DIS		(1<<22)
+#define   GCFG_DIS		(1<<8)
+#define VLV_GUNIT_CLOCK_GATE2	_MMIO(VLV_DISPLAY_BASE + 0x2064)
+#define VLV_IIR_RW	_MMIO(VLV_DISPLAY_BASE + 0x2084)
+#define VLV_IER		_MMIO(VLV_DISPLAY_BASE + 0x20a0)
+#define VLV_IIR		_MMIO(VLV_DISPLAY_BASE + 0x20a4)
+#define VLV_IMR		_MMIO(VLV_DISPLAY_BASE + 0x20a8)
+#define VLV_ISR		_MMIO(VLV_DISPLAY_BASE + 0x20ac)
+#define VLV_PCBR	_MMIO(VLV_DISPLAY_BASE + 0x2120)
+#define VLV_PCBR_ADDR_SHIFT	12
+
+#define   DISPLAY_PLANE_FLIP_PENDING(plane) (1<<(11-(plane))) /* A and B only */
+#define EIR		_MMIO(0x20b0)
+#define EMR		_MMIO(0x20b4)
+#define ESR		_MMIO(0x20b8)
+#define   GM45_ERROR_PAGE_TABLE				(1<<5)
+#define   GM45_ERROR_MEM_PRIV				(1<<4)
+#define   I915_ERROR_PAGE_TABLE				(1<<4)
+#define   GM45_ERROR_CP_PRIV				(1<<3)
+#define   I915_ERROR_MEMORY_REFRESH			(1<<1)
+#define   I915_ERROR_INSTRUCTION			(1<<0)
+#define INSTPM	        _MMIO(0x20c0)
+#define   INSTPM_SELF_EN (1<<12) /* 915GM only */
+#define   INSTPM_AGPBUSY_INT_EN (1<<11) /* gen3: when disabled, pending interrupts
+					will not assert AGPBUSY# and will only
+					be delivered when out of C3. */
+#define   INSTPM_FORCE_ORDERING				(1<<7) /* GEN6+ */
+#define   INSTPM_TLB_INVALIDATE	(1<<9)
+#define   INSTPM_SYNC_FLUSH	(1<<5)
+#define ACTHD	        _MMIO(0x20c8)
+#define MEM_MODE	_MMIO(0x20cc)
+#define   MEM_DISPLAY_B_TRICKLE_FEED_DISABLE (1<<3) /* 830 only */
+#define   MEM_DISPLAY_A_TRICKLE_FEED_DISABLE (1<<2) /* 830/845 only */
+#define   MEM_DISPLAY_TRICKLE_FEED_DISABLE (1<<2) /* 85x only */
+#define FW_BLC		_MMIO(0x20d8)
+#define FW_BLC2		_MMIO(0x20dc)
+#define FW_BLC_SELF	_MMIO(0x20e0) /* 915+ only */
+#define   FW_BLC_SELF_EN_MASK      (1<<31)
+#define   FW_BLC_SELF_FIFO_MASK    (1<<16) /* 945 only */
+#define   FW_BLC_SELF_EN           (1<<15) /* 945 only */
+#define MM_BURST_LENGTH     0x00700000
+#define MM_FIFO_WATERMARK   0x0001F000
+#define LM_BURST_LENGTH     0x00000700
+#define LM_FIFO_WATERMARK   0x0000001F
+#define MI_ARB_STATE	_MMIO(0x20e4) /* 915+ only */
+
+/* Make render/texture TLB fetches lower priorty than associated data
+ *   fetches. This is not turned on by default
+ */
+#define   MI_ARB_RENDER_TLB_LOW_PRIORITY	(1 << 15)
+
+/* Isoch request wait on GTT enable (Display A/B/C streams).
+ * Make isoch requests stall on the TLB update. May cause
+ * display underruns (test mode only)
+ */
+#define   MI_ARB_ISOCH_WAIT_GTT			(1 << 14)
+
+/* Block grant count for isoch requests when block count is
+ * set to a finite value.
+ */
+#define   MI_ARB_BLOCK_GRANT_MASK		(3 << 12)
+#define   MI_ARB_BLOCK_GRANT_8			(0 << 12)	/* for 3 display planes */
+#define   MI_ARB_BLOCK_GRANT_4			(1 << 12)	/* for 2 display planes */
+#define   MI_ARB_BLOCK_GRANT_2			(2 << 12)	/* for 1 display plane */
+#define   MI_ARB_BLOCK_GRANT_0			(3 << 12)	/* don't use */
+
+/* Enable render writes to complete in C2/C3/C4 power states.
+ * If this isn't enabled, render writes are prevented in low
+ * power states. That seems bad to me.
+ */
+#define   MI_ARB_C3_LP_WRITE_ENABLE		(1 << 11)
+
+/* This acknowledges an async flip immediately instead
+ * of waiting for 2TLB fetches.
+ */
+#define   MI_ARB_ASYNC_FLIP_ACK_IMMEDIATE	(1 << 10)
+
+/* Enables non-sequential data reads through arbiter
+ */
+#define   MI_ARB_DUAL_DATA_PHASE_DISABLE	(1 << 9)
+
+/* Disable FSB snooping of cacheable write cycles from binner/render
+ * command stream
+ */
+#define   MI_ARB_CACHE_SNOOP_DISABLE		(1 << 8)
+
+/* Arbiter time slice for non-isoch streams */
+#define   MI_ARB_TIME_SLICE_MASK		(7 << 5)
+#define   MI_ARB_TIME_SLICE_1			(0 << 5)
+#define   MI_ARB_TIME_SLICE_2			(1 << 5)
+#define   MI_ARB_TIME_SLICE_4			(2 << 5)
+#define   MI_ARB_TIME_SLICE_6			(3 << 5)
+#define   MI_ARB_TIME_SLICE_8			(4 << 5)
+#define   MI_ARB_TIME_SLICE_10			(5 << 5)
+#define   MI_ARB_TIME_SLICE_14			(6 << 5)
+#define   MI_ARB_TIME_SLICE_16			(7 << 5)
+
+/* Low priority grace period page size */
+#define   MI_ARB_LOW_PRIORITY_GRACE_4KB		(0 << 4)	/* default */
+#define   MI_ARB_LOW_PRIORITY_GRACE_8KB		(1 << 4)
+
+/* Disable display A/B trickle feed */
+#define   MI_ARB_DISPLAY_TRICKLE_FEED_DISABLE	(1 << 2)
+
+/* Set display plane priority */
+#define   MI_ARB_DISPLAY_PRIORITY_A_B		(0 << 0)	/* display A > display B */
+#define   MI_ARB_DISPLAY_PRIORITY_B_A		(1 << 0)	/* display B > display A */
+
+#define MI_STATE	_MMIO(0x20e4) /* gen2 only */
+#define   MI_AGPBUSY_INT_EN			(1 << 1) /* 85x only */
+#define   MI_AGPBUSY_830_MODE			(1 << 0) /* 85x only */
+
+#define CACHE_MODE_0	_MMIO(0x2120) /* 915+ only */
+#define   CM0_PIPELINED_RENDER_FLUSH_DISABLE (1<<8)
+#define   CM0_IZ_OPT_DISABLE      (1<<6)
+#define   CM0_ZR_OPT_DISABLE      (1<<5)
+#define	  CM0_STC_EVICT_DISABLE_LRA_SNB	(1<<5)
+#define   CM0_DEPTH_EVICT_DISABLE (1<<4)
+#define   CM0_COLOR_EVICT_DISABLE (1<<3)
+#define   CM0_DEPTH_WRITE_DISABLE (1<<1)
+#define   CM0_RC_OP_FLUSH_DISABLE (1<<0)
+#define GFX_FLSH_CNTL	_MMIO(0x2170) /* 915+ only */
+#define GFX_FLSH_CNTL_GEN6	_MMIO(0x101008)
+#define   GFX_FLSH_CNTL_EN	(1<<0)
+#define ECOSKPD		_MMIO(0x21d0)
+#define   ECO_GATING_CX_ONLY	(1<<3)
+#define   ECO_FLIP_DONE		(1<<0)
+
+#define CACHE_MODE_0_GEN7	_MMIO(0x7000) /* IVB+ */
+#define RC_OP_FLUSH_ENABLE (1<<0)
+#define   HIZ_RAW_STALL_OPT_DISABLE (1<<2)
+#define CACHE_MODE_1		_MMIO(0x7004) /* IVB+ */
+#define   PIXEL_SUBSPAN_COLLECT_OPT_DISABLE	(1<<6)
+#define   GEN8_4x4_STC_OPTIMIZATION_DISABLE	(1<<6)
+#define   GEN9_PARTIAL_RESOLVE_IN_VC_DISABLE	(1<<1)
+
+#define GEN6_BLITTER_ECOSKPD	_MMIO(0x221d0)
+#define   GEN6_BLITTER_LOCK_SHIFT			16
+#define   GEN6_BLITTER_FBC_NOTIFY			(1<<3)
+
+#define GEN6_RC_SLEEP_PSMI_CONTROL	_MMIO(0x2050)
+#define   GEN6_PSMI_SLEEP_MSG_DISABLE	(1 << 0)
+#define   GEN8_RC_SEMA_IDLE_MSG_DISABLE	(1 << 12)
+#define   GEN8_FF_DOP_CLOCK_GATE_DISABLE	(1<<10)
+
+/* Fuse readout registers for GT */
+#define CHV_FUSE_GT			_MMIO(VLV_DISPLAY_BASE + 0x2168)
+#define   CHV_FGT_DISABLE_SS0		(1 << 10)
+#define   CHV_FGT_DISABLE_SS1		(1 << 11)
+#define   CHV_FGT_EU_DIS_SS0_R0_SHIFT	16
+#define   CHV_FGT_EU_DIS_SS0_R0_MASK	(0xf << CHV_FGT_EU_DIS_SS0_R0_SHIFT)
+#define   CHV_FGT_EU_DIS_SS0_R1_SHIFT	20
+#define   CHV_FGT_EU_DIS_SS0_R1_MASK	(0xf << CHV_FGT_EU_DIS_SS0_R1_SHIFT)
+#define   CHV_FGT_EU_DIS_SS1_R0_SHIFT	24
+#define   CHV_FGT_EU_DIS_SS1_R0_MASK	(0xf << CHV_FGT_EU_DIS_SS1_R0_SHIFT)
+#define   CHV_FGT_EU_DIS_SS1_R1_SHIFT	28
+#define   CHV_FGT_EU_DIS_SS1_R1_MASK	(0xf << CHV_FGT_EU_DIS_SS1_R1_SHIFT)
+
+#define GEN8_FUSE2			_MMIO(0x9120)
+#define   GEN8_F2_SS_DIS_SHIFT		21
+#define   GEN8_F2_SS_DIS_MASK		(0x7 << GEN8_F2_SS_DIS_SHIFT)
+#define   GEN8_F2_S_ENA_SHIFT		25
+#define   GEN8_F2_S_ENA_MASK		(0x7 << GEN8_F2_S_ENA_SHIFT)
+
+#define   GEN9_F2_SS_DIS_SHIFT		20
+#define   GEN9_F2_SS_DIS_MASK		(0xf << GEN9_F2_SS_DIS_SHIFT)
+
+#define GEN8_EU_DISABLE0		_MMIO(0x9134)
+#define   GEN8_EU_DIS0_S0_MASK		0xffffff
+#define   GEN8_EU_DIS0_S1_SHIFT		24
+#define   GEN8_EU_DIS0_S1_MASK		(0xff << GEN8_EU_DIS0_S1_SHIFT)
+
+#define GEN8_EU_DISABLE1		_MMIO(0x9138)
+#define   GEN8_EU_DIS1_S1_MASK		0xffff
+#define   GEN8_EU_DIS1_S2_SHIFT		16
+#define   GEN8_EU_DIS1_S2_MASK		(0xffff << GEN8_EU_DIS1_S2_SHIFT)
+
+#define GEN8_EU_DISABLE2		_MMIO(0x913c)
+#define   GEN8_EU_DIS2_S2_MASK		0xff
+
+#define GEN9_EU_DISABLE(slice)		_MMIO(0x9134 + (slice)*0x4)
+
+#define GEN6_BSD_SLEEP_PSMI_CONTROL	_MMIO(0x12050)
+#define   GEN6_BSD_SLEEP_MSG_DISABLE	(1 << 0)
+#define   GEN6_BSD_SLEEP_FLUSH_DISABLE	(1 << 2)
+#define   GEN6_BSD_SLEEP_INDICATOR	(1 << 3)
+#define   GEN6_BSD_GO_INDICATOR		(1 << 4)
+
+/* On modern GEN architectures interrupt control consists of two sets
+ * of registers. The first set pertains to the ring generating the
+ * interrupt. The second control is for the functional block generating the
+ * interrupt. These are PM, GT, DE, etc.
+ *
+ * Luckily *knocks on wood* all the ring interrupt bits match up with the
+ * GT interrupt bits, so we don't need to duplicate the defines.
+ *
+ * These defines should cover us well from SNB->HSW with minor exceptions
+ * it can also work on ILK.
+ */
+#define GT_BLT_FLUSHDW_NOTIFY_INTERRUPT		(1 << 26)
+#define GT_BLT_CS_ERROR_INTERRUPT		(1 << 25)
+#define GT_BLT_USER_INTERRUPT			(1 << 22)
+#define GT_BSD_CS_ERROR_INTERRUPT		(1 << 15)
+#define GT_BSD_USER_INTERRUPT			(1 << 12)
+#define GT_RENDER_L3_PARITY_ERROR_INTERRUPT_S1	(1 << 11) /* hsw+; rsvd on snb, ivb, vlv */
+#define GT_CONTEXT_SWITCH_INTERRUPT		(1 <<  8)
+#define GT_RENDER_L3_PARITY_ERROR_INTERRUPT	(1 <<  5) /* !snb */
+#define GT_RENDER_PIPECTL_NOTIFY_INTERRUPT	(1 <<  4)
+#define GT_RENDER_CS_MASTER_ERROR_INTERRUPT	(1 <<  3)
+#define GT_RENDER_SYNC_STATUS_INTERRUPT		(1 <<  2)
+#define GT_RENDER_DEBUG_INTERRUPT		(1 <<  1)
+#define GT_RENDER_USER_INTERRUPT		(1 <<  0)
+
+#define PM_VEBOX_CS_ERROR_INTERRUPT		(1 << 12) /* hsw+ */
+#define PM_VEBOX_USER_INTERRUPT			(1 << 10) /* hsw+ */
+
+#define GT_PARITY_ERROR(dev) \
+	(GT_RENDER_L3_PARITY_ERROR_INTERRUPT | \
+	 (IS_HASWELL(dev) ? GT_RENDER_L3_PARITY_ERROR_INTERRUPT_S1 : 0))
+
+/* These are all the "old" interrupts */
+#define ILK_BSD_USER_INTERRUPT				(1<<5)
+
+#define I915_PM_INTERRUPT				(1<<31)
+#define I915_ISP_INTERRUPT				(1<<22)
+#define I915_LPE_PIPE_B_INTERRUPT			(1<<21)
+#define I915_LPE_PIPE_A_INTERRUPT			(1<<20)
+#define I915_MIPIC_INTERRUPT				(1<<19)
+#define I915_MIPIA_INTERRUPT				(1<<18)
+#define I915_PIPE_CONTROL_NOTIFY_INTERRUPT		(1<<18)
+#define I915_DISPLAY_PORT_INTERRUPT			(1<<17)
+#define I915_DISPLAY_PIPE_C_HBLANK_INTERRUPT		(1<<16)
+#define I915_MASTER_ERROR_INTERRUPT			(1<<15)
+#define I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT	(1<<15)
+#define I915_DISPLAY_PIPE_B_HBLANK_INTERRUPT		(1<<14)
+#define I915_GMCH_THERMAL_SENSOR_EVENT_INTERRUPT	(1<<14) /* p-state */
+#define I915_DISPLAY_PIPE_A_HBLANK_INTERRUPT		(1<<13)
+#define I915_HWB_OOM_INTERRUPT				(1<<13)
+#define I915_LPE_PIPE_C_INTERRUPT			(1<<12)
+#define I915_SYNC_STATUS_INTERRUPT			(1<<12)
+#define I915_MISC_INTERRUPT				(1<<11)
+#define I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT	(1<<11)
+#define I915_DISPLAY_PIPE_C_VBLANK_INTERRUPT		(1<<10)
+#define I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT	(1<<10)
+#define I915_DISPLAY_PIPE_C_EVENT_INTERRUPT		(1<<9)
+#define I915_OVERLAY_PLANE_FLIP_PENDING_INTERRUPT	(1<<9)
+#define I915_DISPLAY_PIPE_C_DPBM_INTERRUPT		(1<<8)
+#define I915_DISPLAY_PLANE_C_FLIP_PENDING_INTERRUPT	(1<<8)
+#define I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT		(1<<7)
+#define I915_DISPLAY_PIPE_A_EVENT_INTERRUPT		(1<<6)
+#define I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT		(1<<5)
+#define I915_DISPLAY_PIPE_B_EVENT_INTERRUPT		(1<<4)
+#define I915_DISPLAY_PIPE_A_DPBM_INTERRUPT		(1<<3)
+#define I915_DISPLAY_PIPE_B_DPBM_INTERRUPT		(1<<2)
+#define I915_DEBUG_INTERRUPT				(1<<2)
+#define I915_WINVALID_INTERRUPT				(1<<1)
+#define I915_USER_INTERRUPT				(1<<1)
+#define I915_ASLE_INTERRUPT				(1<<0)
+#define I915_BSD_USER_INTERRUPT				(1<<25)
+
+#define GEN6_BSD_RNCID			_MMIO(0x12198)
+
+#define GEN7_FF_THREAD_MODE		_MMIO(0x20a0)
+#define   GEN7_FF_SCHED_MASK		0x0077070
+#define   GEN8_FF_DS_REF_CNT_FFME	(1 << 19)
+#define   GEN7_FF_TS_SCHED_HS1		(0x5<<16)
+#define   GEN7_FF_TS_SCHED_HS0		(0x3<<16)
+#define   GEN7_FF_TS_SCHED_LOAD_BALANCE	(0x1<<16)
+#define   GEN7_FF_TS_SCHED_HW		(0x0<<16) /* Default */
+#define   GEN7_FF_VS_REF_CNT_FFME	(1 << 15)
+#define   GEN7_FF_VS_SCHED_HS1		(0x5<<12)
+#define   GEN7_FF_VS_SCHED_HS0		(0x3<<12)
+#define   GEN7_FF_VS_SCHED_LOAD_BALANCE	(0x1<<12) /* Default */
+#define   GEN7_FF_VS_SCHED_HW		(0x0<<12)
+#define   GEN7_FF_DS_SCHED_HS1		(0x5<<4)
+#define   GEN7_FF_DS_SCHED_HS0		(0x3<<4)
+#define   GEN7_FF_DS_SCHED_LOAD_BALANCE	(0x1<<4)  /* Default */
+#define   GEN7_FF_DS_SCHED_HW		(0x0<<4)
+
+/*
+ * Framebuffer compression (915+ only)
+ */
+
+#define FBC_CFB_BASE		_MMIO(0x3200) /* 4k page aligned */
+#define FBC_LL_BASE		_MMIO(0x3204) /* 4k page aligned */
+#define FBC_CONTROL		_MMIO(0x3208)
+#define   FBC_CTL_EN		(1<<31)
+#define   FBC_CTL_PERIODIC	(1<<30)
+#define   FBC_CTL_INTERVAL_SHIFT (16)
+#define   FBC_CTL_UNCOMPRESSIBLE (1<<14)
+#define   FBC_CTL_C3_IDLE	(1<<13)
+#define   FBC_CTL_STRIDE_SHIFT	(5)
+#define   FBC_CTL_FENCENO_SHIFT	(0)
+#define FBC_COMMAND		_MMIO(0x320c)
+#define   FBC_CMD_COMPRESS	(1<<0)
+#define FBC_STATUS		_MMIO(0x3210)
+#define   FBC_STAT_COMPRESSING	(1<<31)
+#define   FBC_STAT_COMPRESSED	(1<<30)
+#define   FBC_STAT_MODIFIED	(1<<29)
+#define   FBC_STAT_CURRENT_LINE_SHIFT	(0)
+#define FBC_CONTROL2		_MMIO(0x3214)
+#define   FBC_CTL_FENCE_DBL	(0<<4)
+#define   FBC_CTL_IDLE_IMM	(0<<2)
+#define   FBC_CTL_IDLE_FULL	(1<<2)
+#define   FBC_CTL_IDLE_LINE	(2<<2)
+#define   FBC_CTL_IDLE_DEBUG	(3<<2)
+#define   FBC_CTL_CPU_FENCE	(1<<1)
+#define   FBC_CTL_PLANE(plane)	((plane)<<0)
+#define FBC_FENCE_OFF		_MMIO(0x3218) /* BSpec typo has 321Bh */
+#define FBC_TAG(i)		_MMIO(0x3300 + (i) * 4)
+
+#define FBC_STATUS2		_MMIO(0x43214)
+#define  FBC_COMPRESSION_MASK	0x7ff
+
+#define FBC_LL_SIZE		(1536)
+
+/* Framebuffer compression for GM45+ */
+#define DPFC_CB_BASE		_MMIO(0x3200)
+#define DPFC_CONTROL		_MMIO(0x3208)
+#define   DPFC_CTL_EN		(1<<31)
+#define   DPFC_CTL_PLANE(plane)	((plane)<<30)
+#define   IVB_DPFC_CTL_PLANE(plane)	((plane)<<29)
+#define   DPFC_CTL_FENCE_EN	(1<<29)
+#define   IVB_DPFC_CTL_FENCE_EN	(1<<28)
+#define   DPFC_CTL_PERSISTENT_MODE	(1<<25)
+#define   DPFC_SR_EN		(1<<10)
+#define   DPFC_CTL_LIMIT_1X	(0<<6)
+#define   DPFC_CTL_LIMIT_2X	(1<<6)
+#define   DPFC_CTL_LIMIT_4X	(2<<6)
+#define DPFC_RECOMP_CTL		_MMIO(0x320c)
+#define   DPFC_RECOMP_STALL_EN	(1<<27)
+#define   DPFC_RECOMP_STALL_WM_SHIFT (16)
+#define   DPFC_RECOMP_STALL_WM_MASK (0x07ff0000)
+#define   DPFC_RECOMP_TIMER_COUNT_SHIFT (0)
+#define   DPFC_RECOMP_TIMER_COUNT_MASK (0x0000003f)
+#define DPFC_STATUS		_MMIO(0x3210)
+#define   DPFC_INVAL_SEG_SHIFT  (16)
+#define   DPFC_INVAL_SEG_MASK	(0x07ff0000)
+#define   DPFC_COMP_SEG_SHIFT	(0)
+#define   DPFC_COMP_SEG_MASK	(0x000003ff)
+#define DPFC_STATUS2		_MMIO(0x3214)
+#define DPFC_FENCE_YOFF		_MMIO(0x3218)
+#define DPFC_CHICKEN		_MMIO(0x3224)
+#define   DPFC_HT_MODIFY	(1<<31)
+
+/* Framebuffer compression for Ironlake */
+#define ILK_DPFC_CB_BASE	_MMIO(0x43200)
+#define ILK_DPFC_CONTROL	_MMIO(0x43208)
+#define   FBC_CTL_FALSE_COLOR	(1<<10)
+/* The bit 28-8 is reserved */
+#define   DPFC_RESERVED		(0x1FFFFF00)
+#define ILK_DPFC_RECOMP_CTL	_MMIO(0x4320c)
+#define ILK_DPFC_STATUS		_MMIO(0x43210)
+#define ILK_DPFC_FENCE_YOFF	_MMIO(0x43218)
+#define ILK_DPFC_CHICKEN	_MMIO(0x43224)
+#define   ILK_DPFC_DISABLE_DUMMY0 (1<<8)
+#define   ILK_DPFC_NUKE_ON_ANY_MODIFICATION	(1<<23)
+#define ILK_FBC_RT_BASE		_MMIO(0x2128)
+#define   ILK_FBC_RT_VALID	(1<<0)
+#define   SNB_FBC_FRONT_BUFFER	(1<<1)
+
+#define ILK_DISPLAY_CHICKEN1	_MMIO(0x42000)
+#define   ILK_FBCQ_DIS		(1<<22)
+#define	  ILK_PABSTRETCH_DIS	(1<<21)
+
+
+/*
+ * Framebuffer compression for Sandybridge
+ *
+ * The following two registers are of type GTTMMADR
+ */
+#define SNB_DPFC_CTL_SA		_MMIO(0x100100)
+#define   SNB_CPU_FENCE_ENABLE	(1<<29)
+#define DPFC_CPU_FENCE_OFFSET	_MMIO(0x100104)
+
+/* Framebuffer compression for Ivybridge */
+#define IVB_FBC_RT_BASE			_MMIO(0x7020)
+
+#define IPS_CTL		_MMIO(0x43408)
+#define   IPS_ENABLE	(1 << 31)
+
+#define MSG_FBC_REND_STATE	_MMIO(0x50380)
+#define   FBC_REND_NUKE		(1<<2)
+#define   FBC_REND_CACHE_CLEAN	(1<<1)
+
+/*
+ * GPIO regs
+ */
+#define GPIOA			_MMIO(0x5010)
+#define GPIOB			_MMIO(0x5014)
+#define GPIOC			_MMIO(0x5018)
+#define GPIOD			_MMIO(0x501c)
+#define GPIOE			_MMIO(0x5020)
+#define GPIOF			_MMIO(0x5024)
+#define GPIOG			_MMIO(0x5028)
+#define GPIOH			_MMIO(0x502c)
+# define GPIO_CLOCK_DIR_MASK		(1 << 0)
+# define GPIO_CLOCK_DIR_IN		(0 << 1)
+# define GPIO_CLOCK_DIR_OUT		(1 << 1)
+# define GPIO_CLOCK_VAL_MASK		(1 << 2)
+# define GPIO_CLOCK_VAL_OUT		(1 << 3)
+# define GPIO_CLOCK_VAL_IN		(1 << 4)
+# define GPIO_CLOCK_PULLUP_DISABLE	(1 << 5)
+# define GPIO_DATA_DIR_MASK		(1 << 8)
+# define GPIO_DATA_DIR_IN		(0 << 9)
+# define GPIO_DATA_DIR_OUT		(1 << 9)
+# define GPIO_DATA_VAL_MASK		(1 << 10)
+# define GPIO_DATA_VAL_OUT		(1 << 11)
+# define GPIO_DATA_VAL_IN		(1 << 12)
+# define GPIO_DATA_PULLUP_DISABLE	(1 << 13)
+
+#define GMBUS0			_MMIO(dev_priv->gpio_mmio_base + 0x5100) /* clock/port select */
+#define   GMBUS_RATE_100KHZ	(0<<8)
+#define   GMBUS_RATE_50KHZ	(1<<8)
+#define   GMBUS_RATE_400KHZ	(2<<8) /* reserved on Pineview */
+#define   GMBUS_RATE_1MHZ	(3<<8) /* reserved on Pineview */
+#define   GMBUS_HOLD_EXT	(1<<7) /* 300ns hold time, rsvd on Pineview */
+#define   GMBUS_PIN_DISABLED	0
+#define   GMBUS_PIN_SSC		1
+#define   GMBUS_PIN_VGADDC	2
+#define   GMBUS_PIN_PANEL	3
+#define   GMBUS_PIN_DPD_CHV	3 /* HDMID_CHV */
+#define   GMBUS_PIN_DPC		4 /* HDMIC */
+#define   GMBUS_PIN_DPB		5 /* SDVO, HDMIB */
+#define   GMBUS_PIN_DPD		6 /* HDMID */
+#define   GMBUS_PIN_RESERVED	7 /* 7 reserved */
+#define   GMBUS_PIN_1_BXT	1
+#define   GMBUS_PIN_2_BXT	2
+#define   GMBUS_PIN_3_BXT	3
+#define   GMBUS_NUM_PINS	7 /* including 0 */
+#define GMBUS1			_MMIO(dev_priv->gpio_mmio_base + 0x5104) /* command/status */
+#define   GMBUS_SW_CLR_INT	(1<<31)
+#define   GMBUS_SW_RDY		(1<<30)
+#define   GMBUS_ENT		(1<<29) /* enable timeout */
+#define   GMBUS_CYCLE_NONE	(0<<25)
+#define   GMBUS_CYCLE_WAIT	(1<<25)
+#define   GMBUS_CYCLE_INDEX	(2<<25)
+#define   GMBUS_CYCLE_STOP	(4<<25)
+#define   GMBUS_BYTE_COUNT_SHIFT 16
+#define   GMBUS_BYTE_COUNT_MAX   256U
+#define   GMBUS_SLAVE_INDEX_SHIFT 8
+#define   GMBUS_SLAVE_ADDR_SHIFT 1
+#define   GMBUS_SLAVE_READ	(1<<0)
+#define   GMBUS_SLAVE_WRITE	(0<<0)
+#define GMBUS2			_MMIO(dev_priv->gpio_mmio_base + 0x5108) /* status */
+#define   GMBUS_INUSE		(1<<15)
+#define   GMBUS_HW_WAIT_PHASE	(1<<14)
+#define   GMBUS_STALL_TIMEOUT	(1<<13)
+#define   GMBUS_INT		(1<<12)
+#define   GMBUS_HW_RDY		(1<<11)
+#define   GMBUS_SATOER		(1<<10)
+#define   GMBUS_ACTIVE		(1<<9)
+#define GMBUS3			_MMIO(dev_priv->gpio_mmio_base + 0x510c) /* data buffer bytes 3-0 */
+#define GMBUS4			_MMIO(dev_priv->gpio_mmio_base + 0x5110) /* interrupt mask (Pineview+) */
+#define   GMBUS_SLAVE_TIMEOUT_EN (1<<4)
+#define   GMBUS_NAK_EN		(1<<3)
+#define   GMBUS_IDLE_EN		(1<<2)
+#define   GMBUS_HW_WAIT_EN	(1<<1)
+#define   GMBUS_HW_RDY_EN	(1<<0)
+#define GMBUS5			_MMIO(dev_priv->gpio_mmio_base + 0x5120) /* byte index */
+#define   GMBUS_2BYTE_INDEX_EN	(1<<31)
+
+/*
+ * Clock control & power management
+ */
+#define _DPLL_A (dev_priv->info.display_mmio_offset + 0x6014)
+#define _DPLL_B (dev_priv->info.display_mmio_offset + 0x6018)
+#define _CHV_DPLL_C (dev_priv->info.display_mmio_offset + 0x6030)
+#define DPLL(pipe) _MMIO_PIPE3((pipe), _DPLL_A, _DPLL_B, _CHV_DPLL_C)
+
+#define VGA0	_MMIO(0x6000)
+#define VGA1	_MMIO(0x6004)
+#define VGA_PD	_MMIO(0x6010)
+#define   VGA0_PD_P2_DIV_4	(1 << 7)
+#define   VGA0_PD_P1_DIV_2	(1 << 5)
+#define   VGA0_PD_P1_SHIFT	0
+#define   VGA0_PD_P1_MASK	(0x1f << 0)
+#define   VGA1_PD_P2_DIV_4	(1 << 15)
+#define   VGA1_PD_P1_DIV_2	(1 << 13)
+#define   VGA1_PD_P1_SHIFT	8
+#define   VGA1_PD_P1_MASK	(0x1f << 8)
+#define   DPLL_VCO_ENABLE		(1 << 31)
+#define   DPLL_SDVO_HIGH_SPEED		(1 << 30)
+#define   DPLL_DVO_2X_MODE		(1 << 30)
+#define   DPLL_EXT_BUFFER_ENABLE_VLV	(1 << 30)
+#define   DPLL_SYNCLOCK_ENABLE		(1 << 29)
+#define   DPLL_REF_CLK_ENABLE_VLV	(1 << 29)
+#define   DPLL_VGA_MODE_DIS		(1 << 28)
+#define   DPLLB_MODE_DAC_SERIAL		(1 << 26) /* i915 */
+#define   DPLLB_MODE_LVDS		(2 << 26) /* i915 */
+#define   DPLL_MODE_MASK		(3 << 26)
+#define   DPLL_DAC_SERIAL_P2_CLOCK_DIV_10 (0 << 24) /* i915 */
+#define   DPLL_DAC_SERIAL_P2_CLOCK_DIV_5 (1 << 24) /* i915 */
+#define   DPLLB_LVDS_P2_CLOCK_DIV_14	(0 << 24) /* i915 */
+#define   DPLLB_LVDS_P2_CLOCK_DIV_7	(1 << 24) /* i915 */
+#define   DPLL_P2_CLOCK_DIV_MASK	0x03000000 /* i915 */
+#define   DPLL_FPA01_P1_POST_DIV_MASK	0x00ff0000 /* i915 */
+#define   DPLL_FPA01_P1_POST_DIV_MASK_PINEVIEW	0x00ff8000 /* Pineview */
+#define   DPLL_LOCK_VLV			(1<<15)
+#define   DPLL_INTEGRATED_CRI_CLK_VLV	(1<<14)
+#define   DPLL_INTEGRATED_REF_CLK_VLV	(1<<13)
+#define   DPLL_SSC_REF_CLK_CHV		(1<<13)
+#define   DPLL_PORTC_READY_MASK		(0xf << 4)
+#define   DPLL_PORTB_READY_MASK		(0xf)
+
+#define   DPLL_FPA01_P1_POST_DIV_MASK_I830	0x001f0000
+
+/* Additional CHV pll/phy registers */
+#define DPIO_PHY_STATUS			_MMIO(VLV_DISPLAY_BASE + 0x6240)
+#define   DPLL_PORTD_READY_MASK		(0xf)
+#define DISPLAY_PHY_CONTROL _MMIO(VLV_DISPLAY_BASE + 0x60100)
+#define   PHY_CH_POWER_DOWN_OVRD_EN(phy, ch)	(1 << (2*(phy)+(ch)+27))
+#define   PHY_LDO_DELAY_0NS			0x0
+#define   PHY_LDO_DELAY_200NS			0x1
+#define   PHY_LDO_DELAY_600NS			0x2
+#define   PHY_LDO_SEQ_DELAY(delay, phy)		((delay) << (2*(phy)+23))
+#define   PHY_CH_POWER_DOWN_OVRD(mask, phy, ch)	((mask) << (8*(phy)+4*(ch)+11))
+#define   PHY_CH_SU_PSR				0x1
+#define   PHY_CH_DEEP_PSR			0x7
+#define   PHY_CH_POWER_MODE(mode, phy, ch)	((mode) << (6*(phy)+3*(ch)+2))
+#define   PHY_COM_LANE_RESET_DEASSERT(phy)	(1 << (phy))
+#define DISPLAY_PHY_STATUS _MMIO(VLV_DISPLAY_BASE + 0x60104)
+#define   PHY_POWERGOOD(phy)	(((phy) == DPIO_PHY0) ? (1<<31) : (1<<30))
+#define   PHY_STATUS_CMN_LDO(phy, ch)                   (1 << (6-(6*(phy)+3*(ch))))
+#define   PHY_STATUS_SPLINE_LDO(phy, ch, spline)        (1 << (8-(6*(phy)+3*(ch)+(spline))))
+
+/*
+ * The i830 generation, in LVDS mode, defines P1 as the bit number set within
+ * this field (only one bit may be set).
+ */
+#define   DPLL_FPA01_P1_POST_DIV_MASK_I830_LVDS	0x003f0000
+#define   DPLL_FPA01_P1_POST_DIV_SHIFT	16
+#define   DPLL_FPA01_P1_POST_DIV_SHIFT_PINEVIEW 15
+/* i830, required in DVO non-gang */
+#define   PLL_P2_DIVIDE_BY_4		(1 << 23)
+#define   PLL_P1_DIVIDE_BY_TWO		(1 << 21) /* i830 */
+#define   PLL_REF_INPUT_DREFCLK		(0 << 13)
+#define   PLL_REF_INPUT_TVCLKINA	(1 << 13) /* i830 */
+#define   PLL_REF_INPUT_TVCLKINBC	(2 << 13) /* SDVO TVCLKIN */
+#define   PLLB_REF_INPUT_SPREADSPECTRUMIN (3 << 13)
+#define   PLL_REF_INPUT_MASK		(3 << 13)
+#define   PLL_LOAD_PULSE_PHASE_SHIFT		9
+/* Ironlake */
+# define PLL_REF_SDVO_HDMI_MULTIPLIER_SHIFT     9
+# define PLL_REF_SDVO_HDMI_MULTIPLIER_MASK      (7 << 9)
+# define PLL_REF_SDVO_HDMI_MULTIPLIER(x)	(((x)-1) << 9)
+# define DPLL_FPA1_P1_POST_DIV_SHIFT            0
+# define DPLL_FPA1_P1_POST_DIV_MASK             0xff
+
+/*
+ * Parallel to Serial Load Pulse phase selection.
+ * Selects the phase for the 10X DPLL clock for the PCIe
+ * digital display port. The range is 4 to 13; 10 or more
+ * is just a flip delay. The default is 6
+ */
+#define   PLL_LOAD_PULSE_PHASE_MASK		(0xf << PLL_LOAD_PULSE_PHASE_SHIFT)
+#define   DISPLAY_RATE_SELECT_FPA1		(1 << 8)
+/*
+ * SDVO multiplier for 945G/GM. Not used on 965.
+ */
+#define   SDVO_MULTIPLIER_MASK			0x000000ff
+#define   SDVO_MULTIPLIER_SHIFT_HIRES		4
+#define   SDVO_MULTIPLIER_SHIFT_VGA		0
+
+#define _DPLL_A_MD (dev_priv->info.display_mmio_offset + 0x601c)
+#define _DPLL_B_MD (dev_priv->info.display_mmio_offset + 0x6020)
+#define _CHV_DPLL_C_MD (dev_priv->info.display_mmio_offset + 0x603c)
+#define DPLL_MD(pipe) _MMIO_PIPE3((pipe), _DPLL_A_MD, _DPLL_B_MD, _CHV_DPLL_C_MD)
+
+/*
+ * UDI pixel divider, controlling how many pixels are stuffed into a packet.
+ *
+ * Value is pixels minus 1.  Must be set to 1 pixel for SDVO.
+ */
+#define   DPLL_MD_UDI_DIVIDER_MASK		0x3f000000
+#define   DPLL_MD_UDI_DIVIDER_SHIFT		24
+/* UDI pixel divider for VGA, same as DPLL_MD_UDI_DIVIDER_MASK. */
+#define   DPLL_MD_VGA_UDI_DIVIDER_MASK		0x003f0000
+#define   DPLL_MD_VGA_UDI_DIVIDER_SHIFT		16
+/*
+ * SDVO/UDI pixel multiplier.
+ *
+ * SDVO requires that the bus clock rate be between 1 and 2 Ghz, and the bus
+ * clock rate is 10 times the DPLL clock.  At low resolution/refresh rate
+ * modes, the bus rate would be below the limits, so SDVO allows for stuffing
+ * dummy bytes in the datastream at an increased clock rate, with both sides of
+ * the link knowing how many bytes are fill.
+ *
+ * So, for a mode with a dotclock of 65Mhz, we would want to double the clock
+ * rate to 130Mhz to get a bus rate of 1.30Ghz.  The DPLL clock rate would be
+ * set to 130Mhz, and the SDVO multiplier set to 2x in this register and
+ * through an SDVO command.
+ *
+ * This register field has values of multiplication factor minus 1, with
+ * a maximum multiplier of 5 for SDVO.
+ */
+#define   DPLL_MD_UDI_MULTIPLIER_MASK		0x00003f00
+#define   DPLL_MD_UDI_MULTIPLIER_SHIFT		8
+/*
+ * SDVO/UDI pixel multiplier for VGA, same as DPLL_MD_UDI_MULTIPLIER_MASK.
+ * This best be set to the default value (3) or the CRT won't work. No,
+ * I don't entirely understand what this does...
+ */
+#define   DPLL_MD_VGA_UDI_MULTIPLIER_MASK	0x0000003f
+#define   DPLL_MD_VGA_UDI_MULTIPLIER_SHIFT	0
+
+#define _FPA0	0x6040
+#define _FPA1	0x6044
+#define _FPB0	0x6048
+#define _FPB1	0x604c
+#define FP0(pipe) _MMIO_PIPE(pipe, _FPA0, _FPB0)
+#define FP1(pipe) _MMIO_PIPE(pipe, _FPA1, _FPB1)
+#define   FP_N_DIV_MASK		0x003f0000
+#define   FP_N_PINEVIEW_DIV_MASK	0x00ff0000
+#define   FP_N_DIV_SHIFT		16
+#define   FP_M1_DIV_MASK	0x00003f00
+#define   FP_M1_DIV_SHIFT		 8
+#define   FP_M2_DIV_MASK	0x0000003f
+#define   FP_M2_PINEVIEW_DIV_MASK	0x000000ff
+#define   FP_M2_DIV_SHIFT		 0
+#define DPLL_TEST	_MMIO(0x606c)
+#define   DPLLB_TEST_SDVO_DIV_1		(0 << 22)
+#define   DPLLB_TEST_SDVO_DIV_2		(1 << 22)
+#define   DPLLB_TEST_SDVO_DIV_4		(2 << 22)
+#define   DPLLB_TEST_SDVO_DIV_MASK	(3 << 22)
+#define   DPLLB_TEST_N_BYPASS		(1 << 19)
+#define   DPLLB_TEST_M_BYPASS		(1 << 18)
+#define   DPLLB_INPUT_BUFFER_ENABLE	(1 << 16)
+#define   DPLLA_TEST_N_BYPASS		(1 << 3)
+#define   DPLLA_TEST_M_BYPASS		(1 << 2)
+#define   DPLLA_INPUT_BUFFER_ENABLE	(1 << 0)
+#define D_STATE		_MMIO(0x6104)
+#define  DSTATE_GFX_RESET_I830			(1<<6)
+#define  DSTATE_PLL_D3_OFF			(1<<3)
+#define  DSTATE_GFX_CLOCK_GATING		(1<<1)
+#define  DSTATE_DOT_CLOCK_GATING		(1<<0)
+#define DSPCLK_GATE_D	_MMIO(dev_priv->info.display_mmio_offset + 0x6200)
+# define DPUNIT_B_CLOCK_GATE_DISABLE		(1 << 30) /* 965 */
+# define VSUNIT_CLOCK_GATE_DISABLE		(1 << 29) /* 965 */
+# define VRHUNIT_CLOCK_GATE_DISABLE		(1 << 28) /* 965 */
+# define VRDUNIT_CLOCK_GATE_DISABLE		(1 << 27) /* 965 */
+# define AUDUNIT_CLOCK_GATE_DISABLE		(1 << 26) /* 965 */
+# define DPUNIT_A_CLOCK_GATE_DISABLE		(1 << 25) /* 965 */
+# define DPCUNIT_CLOCK_GATE_DISABLE		(1 << 24) /* 965 */
+# define TVRUNIT_CLOCK_GATE_DISABLE		(1 << 23) /* 915-945 */
+# define TVCUNIT_CLOCK_GATE_DISABLE		(1 << 22) /* 915-945 */
+# define TVFUNIT_CLOCK_GATE_DISABLE		(1 << 21) /* 915-945 */
+# define TVEUNIT_CLOCK_GATE_DISABLE		(1 << 20) /* 915-945 */
+# define DVSUNIT_CLOCK_GATE_DISABLE		(1 << 19) /* 915-945 */
+# define DSSUNIT_CLOCK_GATE_DISABLE		(1 << 18) /* 915-945 */
+# define DDBUNIT_CLOCK_GATE_DISABLE		(1 << 17) /* 915-945 */
+# define DPRUNIT_CLOCK_GATE_DISABLE		(1 << 16) /* 915-945 */
+# define DPFUNIT_CLOCK_GATE_DISABLE		(1 << 15) /* 915-945 */
+# define DPBMUNIT_CLOCK_GATE_DISABLE		(1 << 14) /* 915-945 */
+# define DPLSUNIT_CLOCK_GATE_DISABLE		(1 << 13) /* 915-945 */
+# define DPLUNIT_CLOCK_GATE_DISABLE		(1 << 12) /* 915-945 */
+# define DPOUNIT_CLOCK_GATE_DISABLE		(1 << 11)
+# define DPBUNIT_CLOCK_GATE_DISABLE		(1 << 10)
+# define DCUNIT_CLOCK_GATE_DISABLE		(1 << 9)
+# define DPUNIT_CLOCK_GATE_DISABLE		(1 << 8)
+# define VRUNIT_CLOCK_GATE_DISABLE		(1 << 7) /* 915+: reserved */
+# define OVHUNIT_CLOCK_GATE_DISABLE		(1 << 6) /* 830-865 */
+# define DPIOUNIT_CLOCK_GATE_DISABLE		(1 << 6) /* 915-945 */
+# define OVFUNIT_CLOCK_GATE_DISABLE		(1 << 5)
+# define OVBUNIT_CLOCK_GATE_DISABLE		(1 << 4)
+/*
+ * This bit must be set on the 830 to prevent hangs when turning off the
+ * overlay scaler.
+ */
+# define OVRUNIT_CLOCK_GATE_DISABLE		(1 << 3)
+# define OVCUNIT_CLOCK_GATE_DISABLE		(1 << 2)
+# define OVUUNIT_CLOCK_GATE_DISABLE		(1 << 1)
+# define ZVUNIT_CLOCK_GATE_DISABLE		(1 << 0) /* 830 */
+# define OVLUNIT_CLOCK_GATE_DISABLE		(1 << 0) /* 845,865 */
+
+#define RENCLK_GATE_D1		_MMIO(0x6204)
+# define BLITTER_CLOCK_GATE_DISABLE		(1 << 13) /* 945GM only */
+# define MPEG_CLOCK_GATE_DISABLE		(1 << 12) /* 945GM only */
+# define PC_FE_CLOCK_GATE_DISABLE		(1 << 11)
+# define PC_BE_CLOCK_GATE_DISABLE		(1 << 10)
+# define WINDOWER_CLOCK_GATE_DISABLE		(1 << 9)
+# define INTERPOLATOR_CLOCK_GATE_DISABLE	(1 << 8)
+# define COLOR_CALCULATOR_CLOCK_GATE_DISABLE	(1 << 7)
+# define MOTION_COMP_CLOCK_GATE_DISABLE		(1 << 6)
+# define MAG_CLOCK_GATE_DISABLE			(1 << 5)
+/* This bit must be unset on 855,865 */
+# define MECI_CLOCK_GATE_DISABLE		(1 << 4)
+# define DCMP_CLOCK_GATE_DISABLE		(1 << 3)
+# define MEC_CLOCK_GATE_DISABLE			(1 << 2)
+# define MECO_CLOCK_GATE_DISABLE		(1 << 1)
+/* This bit must be set on 855,865. */
+# define SV_CLOCK_GATE_DISABLE			(1 << 0)
+# define I915_MPEG_CLOCK_GATE_DISABLE		(1 << 16)
+# define I915_VLD_IP_PR_CLOCK_GATE_DISABLE	(1 << 15)
+# define I915_MOTION_COMP_CLOCK_GATE_DISABLE	(1 << 14)
+# define I915_BD_BF_CLOCK_GATE_DISABLE		(1 << 13)
+# define I915_SF_SE_CLOCK_GATE_DISABLE		(1 << 12)
+# define I915_WM_CLOCK_GATE_DISABLE		(1 << 11)
+# define I915_IZ_CLOCK_GATE_DISABLE		(1 << 10)
+# define I915_PI_CLOCK_GATE_DISABLE		(1 << 9)
+# define I915_DI_CLOCK_GATE_DISABLE		(1 << 8)
+# define I915_SH_SV_CLOCK_GATE_DISABLE		(1 << 7)
+# define I915_PL_DG_QC_FT_CLOCK_GATE_DISABLE	(1 << 6)
+# define I915_SC_CLOCK_GATE_DISABLE		(1 << 5)
+# define I915_FL_CLOCK_GATE_DISABLE		(1 << 4)
+# define I915_DM_CLOCK_GATE_DISABLE		(1 << 3)
+# define I915_PS_CLOCK_GATE_DISABLE		(1 << 2)
+# define I915_CC_CLOCK_GATE_DISABLE		(1 << 1)
+# define I915_BY_CLOCK_GATE_DISABLE		(1 << 0)
+
+# define I965_RCZ_CLOCK_GATE_DISABLE		(1 << 30)
+/* This bit must always be set on 965G/965GM */
+# define I965_RCC_CLOCK_GATE_DISABLE		(1 << 29)
+# define I965_RCPB_CLOCK_GATE_DISABLE		(1 << 28)
+# define I965_DAP_CLOCK_GATE_DISABLE		(1 << 27)
+# define I965_ROC_CLOCK_GATE_DISABLE		(1 << 26)
+# define I965_GW_CLOCK_GATE_DISABLE		(1 << 25)
+# define I965_TD_CLOCK_GATE_DISABLE		(1 << 24)
+/* This bit must always be set on 965G */
+# define I965_ISC_CLOCK_GATE_DISABLE		(1 << 23)
+# define I965_IC_CLOCK_GATE_DISABLE		(1 << 22)
+# define I965_EU_CLOCK_GATE_DISABLE		(1 << 21)
+# define I965_IF_CLOCK_GATE_DISABLE		(1 << 20)
+# define I965_TC_CLOCK_GATE_DISABLE		(1 << 19)
+# define I965_SO_CLOCK_GATE_DISABLE		(1 << 17)
+# define I965_FBC_CLOCK_GATE_DISABLE		(1 << 16)
+# define I965_MARI_CLOCK_GATE_DISABLE		(1 << 15)
+# define I965_MASF_CLOCK_GATE_DISABLE		(1 << 14)
+# define I965_MAWB_CLOCK_GATE_DISABLE		(1 << 13)
+# define I965_EM_CLOCK_GATE_DISABLE		(1 << 12)
+# define I965_UC_CLOCK_GATE_DISABLE		(1 << 11)
+# define I965_SI_CLOCK_GATE_DISABLE		(1 << 6)
+# define I965_MT_CLOCK_GATE_DISABLE		(1 << 5)
+# define I965_PL_CLOCK_GATE_DISABLE		(1 << 4)
+# define I965_DG_CLOCK_GATE_DISABLE		(1 << 3)
+# define I965_QC_CLOCK_GATE_DISABLE		(1 << 2)
+# define I965_FT_CLOCK_GATE_DISABLE		(1 << 1)
+# define I965_DM_CLOCK_GATE_DISABLE		(1 << 0)
+
+#define RENCLK_GATE_D2		_MMIO(0x6208)
+#define VF_UNIT_CLOCK_GATE_DISABLE		(1 << 9)
+#define GS_UNIT_CLOCK_GATE_DISABLE		(1 << 7)
+#define CL_UNIT_CLOCK_GATE_DISABLE		(1 << 6)
+
+#define VDECCLK_GATE_D		_MMIO(0x620C)		/* g4x only */
+#define  VCP_UNIT_CLOCK_GATE_DISABLE		(1 << 4)
+
+#define RAMCLK_GATE_D		_MMIO(0x6210)		/* CRL only */
+#define DEUC			_MMIO(0x6214)          /* CRL only */
+
+#define FW_BLC_SELF_VLV		_MMIO(VLV_DISPLAY_BASE + 0x6500)
+#define  FW_CSPWRDWNEN		(1<<15)
+
+#define MI_ARB_VLV		_MMIO(VLV_DISPLAY_BASE + 0x6504)
+
+#define CZCLK_CDCLK_FREQ_RATIO	_MMIO(VLV_DISPLAY_BASE + 0x6508)
+#define   CDCLK_FREQ_SHIFT	4
+#define   CDCLK_FREQ_MASK	(0x1f << CDCLK_FREQ_SHIFT)
+#define   CZCLK_FREQ_MASK	0xf
+
+#define GCI_CONTROL		_MMIO(VLV_DISPLAY_BASE + 0x650C)
+#define   PFI_CREDIT_63		(9 << 28)		/* chv only */
+#define   PFI_CREDIT_31		(8 << 28)		/* chv only */
+#define   PFI_CREDIT(x)		(((x) - 8) << 28)	/* 8-15 */
+#define   PFI_CREDIT_RESEND	(1 << 27)
+#define   VGA_FAST_MODE_DISABLE	(1 << 14)
+
+#define GMBUSFREQ_VLV		_MMIO(VLV_DISPLAY_BASE + 0x6510)
+
+/*
+ * Palette regs
+ */
+#define PALETTE_A_OFFSET 0xa000
+#define PALETTE_B_OFFSET 0xa800
+#define CHV_PALETTE_C_OFFSET 0xc000
+#define PALETTE(pipe, i) _MMIO(dev_priv->info.palette_offsets[pipe] +	\
+			      dev_priv->info.display_mmio_offset + (i) * 4)
+
+/* MCH MMIO space */
+
+/*
+ * MCHBAR mirror.
+ *
+ * This mirrors the MCHBAR MMIO space whose location is determined by
+ * device 0 function 0's pci config register 0x44 or 0x48 and matches it in
+ * every way.  It is not accessible from the CP register read instructions.
+ *
+ * Starting from Haswell, you can't write registers using the MCHBAR mirror,
+ * just read.
+ */
+#define MCHBAR_MIRROR_BASE	0x10000
+
+#define MCHBAR_MIRROR_BASE_SNB	0x140000
+
+#define CTG_STOLEN_RESERVED		_MMIO(MCHBAR_MIRROR_BASE + 0x34)
+#define ELK_STOLEN_RESERVED		_MMIO(MCHBAR_MIRROR_BASE + 0x48)
+#define G4X_STOLEN_RESERVED_ADDR1_MASK	(0xFFFF << 16)
+#define G4X_STOLEN_RESERVED_ADDR2_MASK	(0xFFF << 4)
+
+/* Memory controller frequency in MCHBAR for Haswell (possible SNB+) */
+#define DCLK _MMIO(MCHBAR_MIRROR_BASE_SNB + 0x5e04)
+
+/* 915-945 and GM965 MCH register controlling DRAM channel access */
+#define DCC			_MMIO(MCHBAR_MIRROR_BASE + 0x200)
+#define DCC_ADDRESSING_MODE_SINGLE_CHANNEL		(0 << 0)
+#define DCC_ADDRESSING_MODE_DUAL_CHANNEL_ASYMMETRIC	(1 << 0)
+#define DCC_ADDRESSING_MODE_DUAL_CHANNEL_INTERLEAVED	(2 << 0)
+#define DCC_ADDRESSING_MODE_MASK			(3 << 0)
+#define DCC_CHANNEL_XOR_DISABLE				(1 << 10)
+#define DCC_CHANNEL_XOR_BIT_17				(1 << 9)
+#define DCC2			_MMIO(MCHBAR_MIRROR_BASE + 0x204)
+#define DCC2_MODIFIED_ENHANCED_DISABLE			(1 << 20)
+
+/* Pineview MCH register contains DDR3 setting */
+#define CSHRDDR3CTL            _MMIO(MCHBAR_MIRROR_BASE + 0x1a8)
+#define CSHRDDR3CTL_DDR3       (1 << 2)
+
+/* 965 MCH register controlling DRAM channel configuration */
+#define C0DRB3			_MMIO(MCHBAR_MIRROR_BASE + 0x206)
+#define C1DRB3			_MMIO(MCHBAR_MIRROR_BASE + 0x606)
+
+/* snb MCH registers for reading the DRAM channel configuration */
+#define MAD_DIMM_C0			_MMIO(MCHBAR_MIRROR_BASE_SNB + 0x5004)
+#define MAD_DIMM_C1			_MMIO(MCHBAR_MIRROR_BASE_SNB + 0x5008)
+#define MAD_DIMM_C2			_MMIO(MCHBAR_MIRROR_BASE_SNB + 0x500C)
+#define   MAD_DIMM_ECC_MASK		(0x3 << 24)
+#define   MAD_DIMM_ECC_OFF		(0x0 << 24)
+#define   MAD_DIMM_ECC_IO_ON_LOGIC_OFF	(0x1 << 24)
+#define   MAD_DIMM_ECC_IO_OFF_LOGIC_ON	(0x2 << 24)
+#define   MAD_DIMM_ECC_ON		(0x3 << 24)
+#define   MAD_DIMM_ENH_INTERLEAVE	(0x1 << 22)
+#define   MAD_DIMM_RANK_INTERLEAVE	(0x1 << 21)
+#define   MAD_DIMM_B_WIDTH_X16		(0x1 << 20) /* X8 chips if unset */
+#define   MAD_DIMM_A_WIDTH_X16		(0x1 << 19) /* X8 chips if unset */
+#define   MAD_DIMM_B_DUAL_RANK		(0x1 << 18)
+#define   MAD_DIMM_A_DUAL_RANK		(0x1 << 17)
+#define   MAD_DIMM_A_SELECT		(0x1 << 16)
+/* DIMM sizes are in multiples of 256mb. */
+#define   MAD_DIMM_B_SIZE_SHIFT		8
+#define   MAD_DIMM_B_SIZE_MASK		(0xff << MAD_DIMM_B_SIZE_SHIFT)
+#define   MAD_DIMM_A_SIZE_SHIFT		0
+#define   MAD_DIMM_A_SIZE_MASK		(0xff << MAD_DIMM_A_SIZE_SHIFT)
+
+/* snb MCH registers for priority tuning */
+#define MCH_SSKPD			_MMIO(MCHBAR_MIRROR_BASE_SNB + 0x5d10)
+#define   MCH_SSKPD_WM0_MASK		0x3f
+#define   MCH_SSKPD_WM0_VAL		0xc
+
+#define MCH_SECP_NRG_STTS		_MMIO(MCHBAR_MIRROR_BASE_SNB + 0x592c)
+
+/* Clocking configuration register */
+#define CLKCFG			_MMIO(MCHBAR_MIRROR_BASE + 0xc00)
+#define CLKCFG_FSB_400					(5 << 0)	/* hrawclk 100 */
+#define CLKCFG_FSB_533					(1 << 0)	/* hrawclk 133 */
+#define CLKCFG_FSB_667					(3 << 0)	/* hrawclk 166 */
+#define CLKCFG_FSB_800					(2 << 0)	/* hrawclk 200 */
+#define CLKCFG_FSB_1067					(6 << 0)	/* hrawclk 266 */
+#define CLKCFG_FSB_1333					(7 << 0)	/* hrawclk 333 */
+/* Note, below two are guess */
+#define CLKCFG_FSB_1600					(4 << 0)	/* hrawclk 400 */
+#define CLKCFG_FSB_1600_ALT				(0 << 0)	/* hrawclk 400 */
+#define CLKCFG_FSB_MASK					(7 << 0)
+#define CLKCFG_MEM_533					(1 << 4)
+#define CLKCFG_MEM_667					(2 << 4)
+#define CLKCFG_MEM_800					(3 << 4)
+#define CLKCFG_MEM_MASK					(7 << 4)
+
+#define HPLLVCO                 _MMIO(MCHBAR_MIRROR_BASE + 0xc38)
+#define HPLLVCO_MOBILE          _MMIO(MCHBAR_MIRROR_BASE + 0xc0f)
+
+#define TSC1			_MMIO(0x11001)
+#define   TSE			(1<<0)
+#define TR1			_MMIO(0x11006)
+#define TSFS			_MMIO(0x11020)
+#define   TSFS_SLOPE_MASK	0x0000ff00
+#define   TSFS_SLOPE_SHIFT	8
+#define   TSFS_INTR_MASK	0x000000ff
+
+#define CRSTANDVID		_MMIO(0x11100)
+#define PXVFREQ(fstart)		_MMIO(0x11110 + (fstart) * 4)  /* P[0-15]VIDFREQ (0x1114c) (Ironlake) */
+#define   PXVFREQ_PX_MASK	0x7f000000
+#define   PXVFREQ_PX_SHIFT	24
+#define VIDFREQ_BASE		_MMIO(0x11110)
+#define VIDFREQ1		_MMIO(0x11110) /* VIDFREQ1-4 (0x1111c) (Cantiga) */
+#define VIDFREQ2		_MMIO(0x11114)
+#define VIDFREQ3		_MMIO(0x11118)
+#define VIDFREQ4		_MMIO(0x1111c)
+#define   VIDFREQ_P0_MASK	0x1f000000
+#define   VIDFREQ_P0_SHIFT	24
+#define   VIDFREQ_P0_CSCLK_MASK	0x00f00000
+#define   VIDFREQ_P0_CSCLK_SHIFT 20
+#define   VIDFREQ_P0_CRCLK_MASK	0x000f0000
+#define   VIDFREQ_P0_CRCLK_SHIFT 16
+#define   VIDFREQ_P1_MASK	0x00001f00
+#define   VIDFREQ_P1_SHIFT	8
+#define   VIDFREQ_P1_CSCLK_MASK	0x000000f0
+#define   VIDFREQ_P1_CSCLK_SHIFT 4
+#define   VIDFREQ_P1_CRCLK_MASK	0x0000000f
+#define INTTOEXT_BASE_ILK	_MMIO(0x11300)
+#define INTTOEXT_BASE		_MMIO(0x11120) /* INTTOEXT1-8 (0x1113c) */
+#define   INTTOEXT_MAP3_SHIFT	24
+#define   INTTOEXT_MAP3_MASK	(0x1f << INTTOEXT_MAP3_SHIFT)
+#define   INTTOEXT_MAP2_SHIFT	16
+#define   INTTOEXT_MAP2_MASK	(0x1f << INTTOEXT_MAP2_SHIFT)
+#define   INTTOEXT_MAP1_SHIFT	8
+#define   INTTOEXT_MAP1_MASK	(0x1f << INTTOEXT_MAP1_SHIFT)
+#define   INTTOEXT_MAP0_SHIFT	0
+#define   INTTOEXT_MAP0_MASK	(0x1f << INTTOEXT_MAP0_SHIFT)
+#define MEMSWCTL		_MMIO(0x11170) /* Ironlake only */
+#define   MEMCTL_CMD_MASK	0xe000
+#define   MEMCTL_CMD_SHIFT	13
+#define   MEMCTL_CMD_RCLK_OFF	0
+#define   MEMCTL_CMD_RCLK_ON	1
+#define   MEMCTL_CMD_CHFREQ	2
+#define   MEMCTL_CMD_CHVID	3
+#define   MEMCTL_CMD_VMMOFF	4
+#define   MEMCTL_CMD_VMMON	5
+#define   MEMCTL_CMD_STS	(1<<12) /* write 1 triggers command, clears
+					   when command complete */
+#define   MEMCTL_FREQ_MASK	0x0f00 /* jitter, from 0-15 */
+#define   MEMCTL_FREQ_SHIFT	8
+#define   MEMCTL_SFCAVM		(1<<7)
+#define   MEMCTL_TGT_VID_MASK	0x007f
+#define MEMIHYST		_MMIO(0x1117c)
+#define MEMINTREN		_MMIO(0x11180) /* 16 bits */
+#define   MEMINT_RSEXIT_EN	(1<<8)
+#define   MEMINT_CX_SUPR_EN	(1<<7)
+#define   MEMINT_CONT_BUSY_EN	(1<<6)
+#define   MEMINT_AVG_BUSY_EN	(1<<5)
+#define   MEMINT_EVAL_CHG_EN	(1<<4)
+#define   MEMINT_MON_IDLE_EN	(1<<3)
+#define   MEMINT_UP_EVAL_EN	(1<<2)
+#define   MEMINT_DOWN_EVAL_EN	(1<<1)
+#define   MEMINT_SW_CMD_EN	(1<<0)
+#define MEMINTRSTR		_MMIO(0x11182) /* 16 bits */
+#define   MEM_RSEXIT_MASK	0xc000
+#define   MEM_RSEXIT_SHIFT	14
+#define   MEM_CONT_BUSY_MASK	0x3000
+#define   MEM_CONT_BUSY_SHIFT	12
+#define   MEM_AVG_BUSY_MASK	0x0c00
+#define   MEM_AVG_BUSY_SHIFT	10
+#define   MEM_EVAL_CHG_MASK	0x0300
+#define   MEM_EVAL_BUSY_SHIFT	8
+#define   MEM_MON_IDLE_MASK	0x00c0
+#define   MEM_MON_IDLE_SHIFT	6
+#define   MEM_UP_EVAL_MASK	0x0030
+#define   MEM_UP_EVAL_SHIFT	4
+#define   MEM_DOWN_EVAL_MASK	0x000c
+#define   MEM_DOWN_EVAL_SHIFT	2
+#define   MEM_SW_CMD_MASK	0x0003
+#define   MEM_INT_STEER_GFX	0
+#define   MEM_INT_STEER_CMR	1
+#define   MEM_INT_STEER_SMI	2
+#define   MEM_INT_STEER_SCI	3
+#define MEMINTRSTS		_MMIO(0x11184)
+#define   MEMINT_RSEXIT		(1<<7)
+#define   MEMINT_CONT_BUSY	(1<<6)
+#define   MEMINT_AVG_BUSY	(1<<5)
+#define   MEMINT_EVAL_CHG	(1<<4)
+#define   MEMINT_MON_IDLE	(1<<3)
+#define   MEMINT_UP_EVAL	(1<<2)
+#define   MEMINT_DOWN_EVAL	(1<<1)
+#define   MEMINT_SW_CMD		(1<<0)
+#define MEMMODECTL		_MMIO(0x11190)
+#define   MEMMODE_BOOST_EN	(1<<31)
+#define   MEMMODE_BOOST_FREQ_MASK 0x0f000000 /* jitter for boost, 0-15 */
+#define   MEMMODE_BOOST_FREQ_SHIFT 24
+#define   MEMMODE_IDLE_MODE_MASK 0x00030000
+#define   MEMMODE_IDLE_MODE_SHIFT 16
+#define   MEMMODE_IDLE_MODE_EVAL 0
+#define   MEMMODE_IDLE_MODE_CONT 1
+#define   MEMMODE_HWIDLE_EN	(1<<15)
+#define   MEMMODE_SWMODE_EN	(1<<14)
+#define   MEMMODE_RCLK_GATE	(1<<13)
+#define   MEMMODE_HW_UPDATE	(1<<12)
+#define   MEMMODE_FSTART_MASK	0x00000f00 /* starting jitter, 0-15 */
+#define   MEMMODE_FSTART_SHIFT	8
+#define   MEMMODE_FMAX_MASK	0x000000f0 /* max jitter, 0-15 */
+#define   MEMMODE_FMAX_SHIFT	4
+#define   MEMMODE_FMIN_MASK	0x0000000f /* min jitter, 0-15 */
+#define RCBMAXAVG		_MMIO(0x1119c)
+#define MEMSWCTL2		_MMIO(0x1119e) /* Cantiga only */
+#define   SWMEMCMD_RENDER_OFF	(0 << 13)
+#define   SWMEMCMD_RENDER_ON	(1 << 13)
+#define   SWMEMCMD_SWFREQ	(2 << 13)
+#define   SWMEMCMD_TARVID	(3 << 13)
+#define   SWMEMCMD_VRM_OFF	(4 << 13)
+#define   SWMEMCMD_VRM_ON	(5 << 13)
+#define   CMDSTS		(1<<12)
+#define   SFCAVM		(1<<11)
+#define   SWFREQ_MASK		0x0380 /* P0-7 */
+#define   SWFREQ_SHIFT		7
+#define   TARVID_MASK		0x001f
+#define MEMSTAT_CTG		_MMIO(0x111a0)
+#define RCBMINAVG		_MMIO(0x111a0)
+#define RCUPEI			_MMIO(0x111b0)
+#define RCDNEI			_MMIO(0x111b4)
+#define RSTDBYCTL		_MMIO(0x111b8)
+#define   RS1EN			(1<<31)
+#define   RS2EN			(1<<30)
+#define   RS3EN			(1<<29)
+#define   D3RS3EN		(1<<28) /* Display D3 imlies RS3 */
+#define   SWPROMORSX		(1<<27) /* RSx promotion timers ignored */
+#define   RCWAKERW		(1<<26) /* Resetwarn from PCH causes wakeup */
+#define   DPRSLPVREN		(1<<25) /* Fast voltage ramp enable */
+#define   GFXTGHYST		(1<<24) /* Hysteresis to allow trunk gating */
+#define   RCX_SW_EXIT		(1<<23) /* Leave RSx and prevent re-entry */
+#define   RSX_STATUS_MASK	(7<<20)
+#define   RSX_STATUS_ON		(0<<20)
+#define   RSX_STATUS_RC1	(1<<20)
+#define   RSX_STATUS_RC1E	(2<<20)
+#define   RSX_STATUS_RS1	(3<<20)
+#define   RSX_STATUS_RS2	(4<<20) /* aka rc6 */
+#define   RSX_STATUS_RSVD	(5<<20) /* deep rc6 unsupported on ilk */
+#define   RSX_STATUS_RS3	(6<<20) /* rs3 unsupported on ilk */
+#define   RSX_STATUS_RSVD2	(7<<20)
+#define   UWRCRSXE		(1<<19) /* wake counter limit prevents rsx */
+#define   RSCRP			(1<<18) /* rs requests control on rs1/2 reqs */
+#define   JRSC			(1<<17) /* rsx coupled to cpu c-state */
+#define   RS2INC0		(1<<16) /* allow rs2 in cpu c0 */
+#define   RS1CONTSAV_MASK	(3<<14)
+#define   RS1CONTSAV_NO_RS1	(0<<14) /* rs1 doesn't save/restore context */
+#define   RS1CONTSAV_RSVD	(1<<14)
+#define   RS1CONTSAV_SAVE_RS1	(2<<14) /* rs1 saves context */
+#define   RS1CONTSAV_FULL_RS1	(3<<14) /* rs1 saves and restores context */
+#define   NORMSLEXLAT_MASK	(3<<12)
+#define   SLOW_RS123		(0<<12)
+#define   SLOW_RS23		(1<<12)
+#define   SLOW_RS3		(2<<12)
+#define   NORMAL_RS123		(3<<12)
+#define   RCMODE_TIMEOUT	(1<<11) /* 0 is eval interval method */
+#define   IMPROMOEN		(1<<10) /* promo is immediate or delayed until next idle interval (only for timeout method above) */
+#define   RCENTSYNC		(1<<9) /* rs coupled to cpu c-state (3/6/7) */
+#define   STATELOCK		(1<<7) /* locked to rs_cstate if 0 */
+#define   RS_CSTATE_MASK	(3<<4)
+#define   RS_CSTATE_C367_RS1	(0<<4)
+#define   RS_CSTATE_C36_RS1_C7_RS2 (1<<4)
+#define   RS_CSTATE_RSVD	(2<<4)
+#define   RS_CSTATE_C367_RS2	(3<<4)
+#define   REDSAVES		(1<<3) /* no context save if was idle during rs0 */
+#define   REDRESTORES		(1<<2) /* no restore if was idle during rs0 */
+#define VIDCTL			_MMIO(0x111c0)
+#define VIDSTS			_MMIO(0x111c8)
+#define VIDSTART		_MMIO(0x111cc) /* 8 bits */
+#define MEMSTAT_ILK		_MMIO(0x111f8)
+#define   MEMSTAT_VID_MASK	0x7f00
+#define   MEMSTAT_VID_SHIFT	8
+#define   MEMSTAT_PSTATE_MASK	0x00f8
+#define   MEMSTAT_PSTATE_SHIFT  3
+#define   MEMSTAT_MON_ACTV	(1<<2)
+#define   MEMSTAT_SRC_CTL_MASK	0x0003
+#define   MEMSTAT_SRC_CTL_CORE	0
+#define   MEMSTAT_SRC_CTL_TRB	1
+#define   MEMSTAT_SRC_CTL_THM	2
+#define   MEMSTAT_SRC_CTL_STDBY 3
+#define RCPREVBSYTUPAVG		_MMIO(0x113b8)
+#define RCPREVBSYTDNAVG		_MMIO(0x113bc)
+#define PMMISC			_MMIO(0x11214)
+#define   MCPPCE_EN		(1<<0) /* enable PM_MSG from PCH->MPC */
+#define SDEW			_MMIO(0x1124c)
+#define CSIEW0			_MMIO(0x11250)
+#define CSIEW1			_MMIO(0x11254)
+#define CSIEW2			_MMIO(0x11258)
+#define PEW(i)			_MMIO(0x1125c + (i) * 4) /* 5 registers */
+#define DEW(i)			_MMIO(0x11270 + (i) * 4) /* 3 registers */
+#define MCHAFE			_MMIO(0x112c0)
+#define CSIEC			_MMIO(0x112e0)
+#define DMIEC			_MMIO(0x112e4)
+#define DDREC			_MMIO(0x112e8)
+#define PEG0EC			_MMIO(0x112ec)
+#define PEG1EC			_MMIO(0x112f0)
+#define GFXEC			_MMIO(0x112f4)
+#define RPPREVBSYTUPAVG		_MMIO(0x113b8)
+#define RPPREVBSYTDNAVG		_MMIO(0x113bc)
+#define ECR			_MMIO(0x11600)
+#define   ECR_GPFE		(1<<31)
+#define   ECR_IMONE		(1<<30)
+#define   ECR_CAP_MASK		0x0000001f /* Event range, 0-31 */
+#define OGW0			_MMIO(0x11608)
+#define OGW1			_MMIO(0x1160c)
+#define EG0			_MMIO(0x11610)
+#define EG1			_MMIO(0x11614)
+#define EG2			_MMIO(0x11618)
+#define EG3			_MMIO(0x1161c)
+#define EG4			_MMIO(0x11620)
+#define EG5			_MMIO(0x11624)
+#define EG6			_MMIO(0x11628)
+#define EG7			_MMIO(0x1162c)
+#define PXW(i)			_MMIO(0x11664 + (i) * 4) /* 4 registers */
+#define PXWL(i)			_MMIO(0x11680 + (i) * 8) /* 8 registers */
+#define LCFUSE02		_MMIO(0x116c0)
+#define   LCFUSE_HIV_MASK	0x000000ff
+#define CSIPLL0			_MMIO(0x12c10)
+#define DDRMPLL1		_MMIO(0X12c20)
+#define PEG_BAND_GAP_DATA	_MMIO(0x14d68)
+
+#define GEN6_GT_THREAD_STATUS_REG _MMIO(0x13805c)
+#define GEN6_GT_THREAD_STATUS_CORE_MASK 0x7
+
+#define GEN6_GT_PERF_STATUS	_MMIO(MCHBAR_MIRROR_BASE_SNB + 0x5948)
+#define BXT_GT_PERF_STATUS      _MMIO(MCHBAR_MIRROR_BASE_SNB + 0x7070)
+#define GEN6_RP_STATE_LIMITS	_MMIO(MCHBAR_MIRROR_BASE_SNB + 0x5994)
+#define GEN6_RP_STATE_CAP	_MMIO(MCHBAR_MIRROR_BASE_SNB + 0x5998)
+#define BXT_RP_STATE_CAP        _MMIO(0x138170)
+
+/*
+ * Make these a multiple of magic 25 to avoid SNB (eg. Dell XPS
+ * 8300) freezing up around GPU hangs. Looks as if even
+ * scheduling/timer interrupts start misbehaving if the RPS
+ * EI/thresholds are "bad", leading to a very sluggish or even
+ * frozen machine.
+ */
+#define INTERVAL_1_28_US(us)	roundup(((us) * 100) >> 7, 25)
+#define INTERVAL_1_33_US(us)	(((us) * 3)   >> 2)
+#define INTERVAL_0_833_US(us)	(((us) * 6) / 5)
+#define GT_INTERVAL_FROM_US(dev_priv, us) (IS_GEN9(dev_priv) ? \
+				(IS_BROXTON(dev_priv) ? \
+				INTERVAL_0_833_US(us) : \
+				INTERVAL_1_33_US(us)) : \
+				INTERVAL_1_28_US(us))
+
+#define INTERVAL_1_28_TO_US(interval)  (((interval) << 7) / 100)
+#define INTERVAL_1_33_TO_US(interval)  (((interval) << 2) / 3)
+#define INTERVAL_0_833_TO_US(interval) (((interval) * 5)  / 6)
+#define GT_PM_INTERVAL_TO_US(dev_priv, interval) (IS_GEN9(dev_priv) ? \
+                           (IS_BROXTON(dev_priv) ? \
+                           INTERVAL_0_833_TO_US(interval) : \
+                           INTERVAL_1_33_TO_US(interval)) : \
+                           INTERVAL_1_28_TO_US(interval))
+
+/*
+ * Logical Context regs
+ */
+#define CCID			_MMIO(0x2180)
+#define   CCID_EN		(1<<0)
+/*
+ * Notes on SNB/IVB/VLV context size:
+ * - Power context is saved elsewhere (LLC or stolen)
+ * - Ring/execlist context is saved on SNB, not on IVB
+ * - Extended context size already includes render context size
+ * - We always need to follow the extended context size.
+ *   SNB BSpec has comments indicating that we should use the
+ *   render context size instead if execlists are disabled, but
+ *   based on empirical testing that's just nonsense.
+ * - Pipelined/VF state is saved on SNB/IVB respectively
+ * - GT1 size just indicates how much of render context
+ *   doesn't need saving on GT1
+ */
+#define CXT_SIZE		_MMIO(0x21a0)
+#define GEN6_CXT_POWER_SIZE(cxt_reg)	(((cxt_reg) >> 24) & 0x3f)
+#define GEN6_CXT_RING_SIZE(cxt_reg)	(((cxt_reg) >> 18) & 0x3f)
+#define GEN6_CXT_RENDER_SIZE(cxt_reg)	(((cxt_reg) >> 12) & 0x3f)
+#define GEN6_CXT_EXTENDED_SIZE(cxt_reg)	(((cxt_reg) >> 6) & 0x3f)
+#define GEN6_CXT_PIPELINE_SIZE(cxt_reg)	(((cxt_reg) >> 0) & 0x3f)
+#define GEN6_CXT_TOTAL_SIZE(cxt_reg)	(GEN6_CXT_RING_SIZE(cxt_reg) + \
+					GEN6_CXT_EXTENDED_SIZE(cxt_reg) + \
+					GEN6_CXT_PIPELINE_SIZE(cxt_reg))
+#define GEN7_CXT_SIZE		_MMIO(0x21a8)
+#define GEN7_CXT_POWER_SIZE(ctx_reg)	(((ctx_reg) >> 25) & 0x7f)
+#define GEN7_CXT_RING_SIZE(ctx_reg)	(((ctx_reg) >> 22) & 0x7)
+#define GEN7_CXT_RENDER_SIZE(ctx_reg)	(((ctx_reg) >> 16) & 0x3f)
+#define GEN7_CXT_EXTENDED_SIZE(ctx_reg)	(((ctx_reg) >> 9) & 0x7f)
+#define GEN7_CXT_GT1_SIZE(ctx_reg)	(((ctx_reg) >> 6) & 0x7)
+#define GEN7_CXT_VFSTATE_SIZE(ctx_reg)	(((ctx_reg) >> 0) & 0x3f)
+#define GEN7_CXT_TOTAL_SIZE(ctx_reg)	(GEN7_CXT_EXTENDED_SIZE(ctx_reg) + \
+					 GEN7_CXT_VFSTATE_SIZE(ctx_reg))
+/* Haswell does have the CXT_SIZE register however it does not appear to be
+ * valid. Now, docs explain in dwords what is in the context object. The full
+ * size is 70720 bytes, however, the power context and execlist context will
+ * never be saved (power context is stored elsewhere, and execlists don't work
+ * on HSW) - so the final size, including the extra state required for the
+ * Resource Streamer, is 66944 bytes, which rounds to 17 pages.
+ */
+#define HSW_CXT_TOTAL_SIZE		(17 * PAGE_SIZE)
+/* Same as Haswell, but 72064 bytes now. */
+#define GEN8_CXT_TOTAL_SIZE		(18 * PAGE_SIZE)
+
+#define CHV_CLK_CTL1			_MMIO(0x101100)
+#define VLV_CLK_CTL2			_MMIO(0x101104)
+#define   CLK_CTL2_CZCOUNT_30NS_SHIFT	28
+
+/*
+ * Overlay regs
+ */
+
+#define OVADD			_MMIO(0x30000)
+#define DOVSTA			_MMIO(0x30008)
+#define OC_BUF			(0x3<<20)
+#define OGAMC5			_MMIO(0x30010)
+#define OGAMC4			_MMIO(0x30014)
+#define OGAMC3			_MMIO(0x30018)
+#define OGAMC2			_MMIO(0x3001c)
+#define OGAMC1			_MMIO(0x30020)
+#define OGAMC0			_MMIO(0x30024)
+
+/*
+ * GEN9 clock gating regs
+ */
+#define GEN9_CLKGATE_DIS_0		_MMIO(0x46530)
+#define   PWM2_GATING_DIS		(1 << 14)
+#define   PWM1_GATING_DIS		(1 << 13)
+
+/*
+ * Display engine regs
+ */
+
+/* Pipe A CRC regs */
+#define _PIPE_CRC_CTL_A			0x60050
+#define   PIPE_CRC_ENABLE		(1 << 31)
+/* ivb+ source selection */
+#define   PIPE_CRC_SOURCE_PRIMARY_IVB	(0 << 29)
+#define   PIPE_CRC_SOURCE_SPRITE_IVB	(1 << 29)
+#define   PIPE_CRC_SOURCE_PF_IVB	(2 << 29)
+/* ilk+ source selection */
+#define   PIPE_CRC_SOURCE_PRIMARY_ILK	(0 << 28)
+#define   PIPE_CRC_SOURCE_SPRITE_ILK	(1 << 28)
+#define   PIPE_CRC_SOURCE_PIPE_ILK	(2 << 28)
+/* embedded DP port on the north display block, reserved on ivb */
+#define   PIPE_CRC_SOURCE_PORT_A_ILK	(4 << 28)
+#define   PIPE_CRC_SOURCE_FDI_ILK	(5 << 28) /* reserved on ivb */
+/* vlv source selection */
+#define   PIPE_CRC_SOURCE_PIPE_VLV	(0 << 27)
+#define   PIPE_CRC_SOURCE_HDMIB_VLV	(1 << 27)
+#define   PIPE_CRC_SOURCE_HDMIC_VLV	(2 << 27)
+/* with DP port the pipe source is invalid */
+#define   PIPE_CRC_SOURCE_DP_D_VLV	(3 << 27)
+#define   PIPE_CRC_SOURCE_DP_B_VLV	(6 << 27)
+#define   PIPE_CRC_SOURCE_DP_C_VLV	(7 << 27)
+/* gen3+ source selection */
+#define   PIPE_CRC_SOURCE_PIPE_I9XX	(0 << 28)
+#define   PIPE_CRC_SOURCE_SDVOB_I9XX	(1 << 28)
+#define   PIPE_CRC_SOURCE_SDVOC_I9XX	(2 << 28)
+/* with DP/TV port the pipe source is invalid */
+#define   PIPE_CRC_SOURCE_DP_D_G4X	(3 << 28)
+#define   PIPE_CRC_SOURCE_TV_PRE	(4 << 28)
+#define   PIPE_CRC_SOURCE_TV_POST	(5 << 28)
+#define   PIPE_CRC_SOURCE_DP_B_G4X	(6 << 28)
+#define   PIPE_CRC_SOURCE_DP_C_G4X	(7 << 28)
+/* gen2 doesn't have source selection bits */
+#define   PIPE_CRC_INCLUDE_BORDER_I8XX	(1 << 30)
+
+#define _PIPE_CRC_RES_1_A_IVB		0x60064
+#define _PIPE_CRC_RES_2_A_IVB		0x60068
+#define _PIPE_CRC_RES_3_A_IVB		0x6006c
+#define _PIPE_CRC_RES_4_A_IVB		0x60070
+#define _PIPE_CRC_RES_5_A_IVB		0x60074
+
+#define _PIPE_CRC_RES_RED_A		0x60060
+#define _PIPE_CRC_RES_GREEN_A		0x60064
+#define _PIPE_CRC_RES_BLUE_A		0x60068
+#define _PIPE_CRC_RES_RES1_A_I915	0x6006c
+#define _PIPE_CRC_RES_RES2_A_G4X	0x60080
+
+/* Pipe B CRC regs */
+#define _PIPE_CRC_RES_1_B_IVB		0x61064
+#define _PIPE_CRC_RES_2_B_IVB		0x61068
+#define _PIPE_CRC_RES_3_B_IVB		0x6106c
+#define _PIPE_CRC_RES_4_B_IVB		0x61070
+#define _PIPE_CRC_RES_5_B_IVB		0x61074
+
+#define PIPE_CRC_CTL(pipe)		_MMIO_TRANS2(pipe, _PIPE_CRC_CTL_A)
+#define PIPE_CRC_RES_1_IVB(pipe)	_MMIO_TRANS2(pipe, _PIPE_CRC_RES_1_A_IVB)
+#define PIPE_CRC_RES_2_IVB(pipe)	_MMIO_TRANS2(pipe, _PIPE_CRC_RES_2_A_IVB)
+#define PIPE_CRC_RES_3_IVB(pipe)	_MMIO_TRANS2(pipe, _PIPE_CRC_RES_3_A_IVB)
+#define PIPE_CRC_RES_4_IVB(pipe)	_MMIO_TRANS2(pipe, _PIPE_CRC_RES_4_A_IVB)
+#define PIPE_CRC_RES_5_IVB(pipe)	_MMIO_TRANS2(pipe, _PIPE_CRC_RES_5_A_IVB)
+
+#define PIPE_CRC_RES_RED(pipe)		_MMIO_TRANS2(pipe, _PIPE_CRC_RES_RED_A)
+#define PIPE_CRC_RES_GREEN(pipe)	_MMIO_TRANS2(pipe, _PIPE_CRC_RES_GREEN_A)
+#define PIPE_CRC_RES_BLUE(pipe)		_MMIO_TRANS2(pipe, _PIPE_CRC_RES_BLUE_A)
+#define PIPE_CRC_RES_RES1_I915(pipe)	_MMIO_TRANS2(pipe, _PIPE_CRC_RES_RES1_A_I915)
+#define PIPE_CRC_RES_RES2_G4X(pipe)	_MMIO_TRANS2(pipe, _PIPE_CRC_RES_RES2_A_G4X)
+
+/* Pipe A timing regs */
+#define _HTOTAL_A	0x60000
+#define _HBLANK_A	0x60004
+#define _HSYNC_A	0x60008
+#define _VTOTAL_A	0x6000c
+#define _VBLANK_A	0x60010
+#define _VSYNC_A	0x60014
+#define _PIPEASRC	0x6001c
+#define _BCLRPAT_A	0x60020
+#define _VSYNCSHIFT_A	0x60028
+#define _PIPE_MULT_A	0x6002c
+
+/* Pipe B timing regs */
+#define _HTOTAL_B	0x61000
+#define _HBLANK_B	0x61004
+#define _HSYNC_B	0x61008
+#define _VTOTAL_B	0x6100c
+#define _VBLANK_B	0x61010
+#define _VSYNC_B	0x61014
+#define _PIPEBSRC	0x6101c
+#define _BCLRPAT_B	0x61020
+#define _VSYNCSHIFT_B	0x61028
+#define _PIPE_MULT_B	0x6102c
+
+#define TRANSCODER_A_OFFSET 0x60000
+#define TRANSCODER_B_OFFSET 0x61000
+#define TRANSCODER_C_OFFSET 0x62000
+#define CHV_TRANSCODER_C_OFFSET 0x63000
+#define TRANSCODER_EDP_OFFSET 0x6f000
+
+#define _MMIO_TRANS2(pipe, reg) _MMIO(dev_priv->info.trans_offsets[(pipe)] - \
+	dev_priv->info.trans_offsets[TRANSCODER_A] + (reg) + \
+	dev_priv->info.display_mmio_offset)
+
+#define HTOTAL(trans)		_MMIO_TRANS2(trans, _HTOTAL_A)
+#define HBLANK(trans)		_MMIO_TRANS2(trans, _HBLANK_A)
+#define HSYNC(trans)		_MMIO_TRANS2(trans, _HSYNC_A)
+#define VTOTAL(trans)		_MMIO_TRANS2(trans, _VTOTAL_A)
+#define VBLANK(trans)		_MMIO_TRANS2(trans, _VBLANK_A)
+#define VSYNC(trans)		_MMIO_TRANS2(trans, _VSYNC_A)
+#define BCLRPAT(trans)		_MMIO_TRANS2(trans, _BCLRPAT_A)
+#define VSYNCSHIFT(trans)	_MMIO_TRANS2(trans, _VSYNCSHIFT_A)
+#define PIPESRC(trans)		_MMIO_TRANS2(trans, _PIPEASRC)
+#define PIPE_MULT(trans)	_MMIO_TRANS2(trans, _PIPE_MULT_A)
+
+/* VLV eDP PSR registers */
+#define _PSRCTLA				(VLV_DISPLAY_BASE + 0x60090)
+#define _PSRCTLB				(VLV_DISPLAY_BASE + 0x61090)
+#define  VLV_EDP_PSR_ENABLE			(1<<0)
+#define  VLV_EDP_PSR_RESET			(1<<1)
+#define  VLV_EDP_PSR_MODE_MASK			(7<<2)
+#define  VLV_EDP_PSR_MODE_HW_TIMER		(1<<3)
+#define  VLV_EDP_PSR_MODE_SW_TIMER		(1<<2)
+#define  VLV_EDP_PSR_SINGLE_FRAME_UPDATE	(1<<7)
+#define  VLV_EDP_PSR_ACTIVE_ENTRY		(1<<8)
+#define  VLV_EDP_PSR_SRC_TRANSMITTER_STATE	(1<<9)
+#define  VLV_EDP_PSR_DBL_FRAME			(1<<10)
+#define  VLV_EDP_PSR_FRAME_COUNT_MASK		(0xff<<16)
+#define  VLV_EDP_PSR_IDLE_FRAME_SHIFT		16
+#define VLV_PSRCTL(pipe)	_MMIO_PIPE(pipe, _PSRCTLA, _PSRCTLB)
+
+#define _VSCSDPA			(VLV_DISPLAY_BASE + 0x600a0)
+#define _VSCSDPB			(VLV_DISPLAY_BASE + 0x610a0)
+#define  VLV_EDP_PSR_SDP_FREQ_MASK	(3<<30)
+#define  VLV_EDP_PSR_SDP_FREQ_ONCE	(1<<31)
+#define  VLV_EDP_PSR_SDP_FREQ_EVFRAME	(1<<30)
+#define VLV_VSCSDP(pipe)	_MMIO_PIPE(pipe, _VSCSDPA, _VSCSDPB)
+
+#define _PSRSTATA			(VLV_DISPLAY_BASE + 0x60094)
+#define _PSRSTATB			(VLV_DISPLAY_BASE + 0x61094)
+#define  VLV_EDP_PSR_LAST_STATE_MASK	(7<<3)
+#define  VLV_EDP_PSR_CURR_STATE_MASK	7
+#define  VLV_EDP_PSR_DISABLED		(0<<0)
+#define  VLV_EDP_PSR_INACTIVE		(1<<0)
+#define  VLV_EDP_PSR_IN_TRANS_TO_ACTIVE	(2<<0)
+#define  VLV_EDP_PSR_ACTIVE_NORFB_UP	(3<<0)
+#define  VLV_EDP_PSR_ACTIVE_SF_UPDATE	(4<<0)
+#define  VLV_EDP_PSR_EXIT		(5<<0)
+#define  VLV_EDP_PSR_IN_TRANS		(1<<7)
+#define VLV_PSRSTAT(pipe)	_MMIO_PIPE(pipe, _PSRSTATA, _PSRSTATB)
+
+/* HSW+ eDP PSR registers */
+#define HSW_EDP_PSR_BASE	0x64800
+#define BDW_EDP_PSR_BASE	0x6f800
+#define EDP_PSR_CTL				_MMIO(dev_priv->psr_mmio_base + 0)
+#define   EDP_PSR_ENABLE			(1<<31)
+#define   BDW_PSR_SINGLE_FRAME			(1<<30)
+#define   EDP_PSR_LINK_STANDBY			(1<<27)
+#define   EDP_PSR_MIN_LINK_ENTRY_TIME_MASK	(3<<25)
+#define   EDP_PSR_MIN_LINK_ENTRY_TIME_8_LINES	(0<<25)
+#define   EDP_PSR_MIN_LINK_ENTRY_TIME_4_LINES	(1<<25)
+#define   EDP_PSR_MIN_LINK_ENTRY_TIME_2_LINES	(2<<25)
+#define   EDP_PSR_MIN_LINK_ENTRY_TIME_0_LINES	(3<<25)
+#define   EDP_PSR_MAX_SLEEP_TIME_SHIFT		20
+#define   EDP_PSR_SKIP_AUX_EXIT			(1<<12)
+#define   EDP_PSR_TP1_TP2_SEL			(0<<11)
+#define   EDP_PSR_TP1_TP3_SEL			(1<<11)
+#define   EDP_PSR_TP2_TP3_TIME_500us		(0<<8)
+#define   EDP_PSR_TP2_TP3_TIME_100us		(1<<8)
+#define   EDP_PSR_TP2_TP3_TIME_2500us		(2<<8)
+#define   EDP_PSR_TP2_TP3_TIME_0us		(3<<8)
+#define   EDP_PSR_TP1_TIME_500us		(0<<4)
+#define   EDP_PSR_TP1_TIME_100us		(1<<4)
+#define   EDP_PSR_TP1_TIME_2500us		(2<<4)
+#define   EDP_PSR_TP1_TIME_0us			(3<<4)
+#define   EDP_PSR_IDLE_FRAME_SHIFT		0
+
+#define EDP_PSR_AUX_CTL				_MMIO(dev_priv->psr_mmio_base + 0x10)
+#define EDP_PSR_AUX_DATA(i)			_MMIO(dev_priv->psr_mmio_base + 0x14 + (i) * 4) /* 5 registers */
+
+#define EDP_PSR_STATUS_CTL			_MMIO(dev_priv->psr_mmio_base + 0x40)
+#define   EDP_PSR_STATUS_STATE_MASK		(7<<29)
+#define   EDP_PSR_STATUS_STATE_IDLE		(0<<29)
+#define   EDP_PSR_STATUS_STATE_SRDONACK		(1<<29)
+#define   EDP_PSR_STATUS_STATE_SRDENT		(2<<29)
+#define   EDP_PSR_STATUS_STATE_BUFOFF		(3<<29)
+#define   EDP_PSR_STATUS_STATE_BUFON		(4<<29)
+#define   EDP_PSR_STATUS_STATE_AUXACK		(5<<29)
+#define   EDP_PSR_STATUS_STATE_SRDOFFACK	(6<<29)
+#define   EDP_PSR_STATUS_LINK_MASK		(3<<26)
+#define   EDP_PSR_STATUS_LINK_FULL_OFF		(0<<26)
+#define   EDP_PSR_STATUS_LINK_FULL_ON		(1<<26)
+#define   EDP_PSR_STATUS_LINK_STANDBY		(2<<26)
+#define   EDP_PSR_STATUS_MAX_SLEEP_TIMER_SHIFT	20
+#define   EDP_PSR_STATUS_MAX_SLEEP_TIMER_MASK	0x1f
+#define   EDP_PSR_STATUS_COUNT_SHIFT		16
+#define   EDP_PSR_STATUS_COUNT_MASK		0xf
+#define   EDP_PSR_STATUS_AUX_ERROR		(1<<15)
+#define   EDP_PSR_STATUS_AUX_SENDING		(1<<12)
+#define   EDP_PSR_STATUS_SENDING_IDLE		(1<<9)
+#define   EDP_PSR_STATUS_SENDING_TP2_TP3	(1<<8)
+#define   EDP_PSR_STATUS_SENDING_TP1		(1<<4)
+#define   EDP_PSR_STATUS_IDLE_MASK		0xf
+
+#define EDP_PSR_PERF_CNT		_MMIO(dev_priv->psr_mmio_base + 0x44)
+#define   EDP_PSR_PERF_CNT_MASK		0xffffff
+
+#define EDP_PSR_DEBUG_CTL		_MMIO(dev_priv->psr_mmio_base + 0x60)
+#define   EDP_PSR_DEBUG_MASK_LPSP	(1<<27)
+#define   EDP_PSR_DEBUG_MASK_MEMUP	(1<<26)
+#define   EDP_PSR_DEBUG_MASK_HPD	(1<<25)
+
+#define EDP_PSR2_CTL			_MMIO(0x6f900)
+#define   EDP_PSR2_ENABLE		(1<<31)
+#define   EDP_SU_TRACK_ENABLE		(1<<30)
+#define   EDP_MAX_SU_DISABLE_TIME(t)	((t)<<20)
+#define   EDP_MAX_SU_DISABLE_TIME_MASK	(0x1f<<20)
+#define   EDP_PSR2_TP2_TIME_500		(0<<8)
+#define   EDP_PSR2_TP2_TIME_100		(1<<8)
+#define   EDP_PSR2_TP2_TIME_2500	(2<<8)
+#define   EDP_PSR2_TP2_TIME_50		(3<<8)
+#define   EDP_PSR2_TP2_TIME_MASK	(3<<8)
+#define   EDP_PSR2_FRAME_BEFORE_SU_SHIFT 4
+#define   EDP_PSR2_FRAME_BEFORE_SU_MASK	(0xf<<4)
+#define   EDP_PSR2_IDLE_MASK		0xf
+
+/* VGA port control */
+#define ADPA			_MMIO(0x61100)
+#define PCH_ADPA                _MMIO(0xe1100)
+#define VLV_ADPA		_MMIO(VLV_DISPLAY_BASE + 0x61100)
+
+#define   ADPA_DAC_ENABLE	(1<<31)
+#define   ADPA_DAC_DISABLE	0
+#define   ADPA_PIPE_SELECT_MASK	(1<<30)
+#define   ADPA_PIPE_A_SELECT	0
+#define   ADPA_PIPE_B_SELECT	(1<<30)
+#define   ADPA_PIPE_SELECT(pipe) ((pipe) << 30)
+/* CPT uses bits 29:30 for pch transcoder select */
+#define   ADPA_CRT_HOTPLUG_MASK  0x03ff0000 /* bit 25-16 */
+#define   ADPA_CRT_HOTPLUG_MONITOR_NONE  (0<<24)
+#define   ADPA_CRT_HOTPLUG_MONITOR_MASK  (3<<24)
+#define   ADPA_CRT_HOTPLUG_MONITOR_COLOR (3<<24)
+#define   ADPA_CRT_HOTPLUG_MONITOR_MONO  (2<<24)
+#define   ADPA_CRT_HOTPLUG_ENABLE        (1<<23)
+#define   ADPA_CRT_HOTPLUG_PERIOD_64     (0<<22)
+#define   ADPA_CRT_HOTPLUG_PERIOD_128    (1<<22)
+#define   ADPA_CRT_HOTPLUG_WARMUP_5MS    (0<<21)
+#define   ADPA_CRT_HOTPLUG_WARMUP_10MS   (1<<21)
+#define   ADPA_CRT_HOTPLUG_SAMPLE_2S     (0<<20)
+#define   ADPA_CRT_HOTPLUG_SAMPLE_4S     (1<<20)
+#define   ADPA_CRT_HOTPLUG_VOLTAGE_40    (0<<18)
+#define   ADPA_CRT_HOTPLUG_VOLTAGE_50    (1<<18)
+#define   ADPA_CRT_HOTPLUG_VOLTAGE_60    (2<<18)
+#define   ADPA_CRT_HOTPLUG_VOLTAGE_70    (3<<18)
+#define   ADPA_CRT_HOTPLUG_VOLREF_325MV  (0<<17)
+#define   ADPA_CRT_HOTPLUG_VOLREF_475MV  (1<<17)
+#define   ADPA_CRT_HOTPLUG_FORCE_TRIGGER (1<<16)
+#define   ADPA_USE_VGA_HVPOLARITY (1<<15)
+#define   ADPA_SETS_HVPOLARITY	0
+#define   ADPA_VSYNC_CNTL_DISABLE (1<<10)
+#define   ADPA_VSYNC_CNTL_ENABLE 0
+#define   ADPA_HSYNC_CNTL_DISABLE (1<<11)
+#define   ADPA_HSYNC_CNTL_ENABLE 0
+#define   ADPA_VSYNC_ACTIVE_HIGH (1<<4)
+#define   ADPA_VSYNC_ACTIVE_LOW	0
+#define   ADPA_HSYNC_ACTIVE_HIGH (1<<3)
+#define   ADPA_HSYNC_ACTIVE_LOW	0
+#define   ADPA_DPMS_MASK	(~(3<<10))
+#define   ADPA_DPMS_ON		(0<<10)
+#define   ADPA_DPMS_SUSPEND	(1<<10)
+#define   ADPA_DPMS_STANDBY	(2<<10)
+#define   ADPA_DPMS_OFF		(3<<10)
+
+
+/* Hotplug control (945+ only) */
+#define PORT_HOTPLUG_EN		_MMIO(dev_priv->info.display_mmio_offset + 0x61110)
+#define   PORTB_HOTPLUG_INT_EN			(1 << 29)
+#define   PORTC_HOTPLUG_INT_EN			(1 << 28)
+#define   PORTD_HOTPLUG_INT_EN			(1 << 27)
+#define   SDVOB_HOTPLUG_INT_EN			(1 << 26)
+#define   SDVOC_HOTPLUG_INT_EN			(1 << 25)
+#define   TV_HOTPLUG_INT_EN			(1 << 18)
+#define   CRT_HOTPLUG_INT_EN			(1 << 9)
+#define HOTPLUG_INT_EN_MASK			(PORTB_HOTPLUG_INT_EN | \
+						 PORTC_HOTPLUG_INT_EN | \
+						 PORTD_HOTPLUG_INT_EN | \
+						 SDVOC_HOTPLUG_INT_EN | \
+						 SDVOB_HOTPLUG_INT_EN | \
+						 CRT_HOTPLUG_INT_EN)
+#define   CRT_HOTPLUG_FORCE_DETECT		(1 << 3)
+#define CRT_HOTPLUG_ACTIVATION_PERIOD_32	(0 << 8)
+/* must use period 64 on GM45 according to docs */
+#define CRT_HOTPLUG_ACTIVATION_PERIOD_64	(1 << 8)
+#define CRT_HOTPLUG_DAC_ON_TIME_2M		(0 << 7)
+#define CRT_HOTPLUG_DAC_ON_TIME_4M		(1 << 7)
+#define CRT_HOTPLUG_VOLTAGE_COMPARE_40		(0 << 5)
+#define CRT_HOTPLUG_VOLTAGE_COMPARE_50		(1 << 5)
+#define CRT_HOTPLUG_VOLTAGE_COMPARE_60		(2 << 5)
+#define CRT_HOTPLUG_VOLTAGE_COMPARE_70		(3 << 5)
+#define CRT_HOTPLUG_VOLTAGE_COMPARE_MASK	(3 << 5)
+#define CRT_HOTPLUG_DETECT_DELAY_1G		(0 << 4)
+#define CRT_HOTPLUG_DETECT_DELAY_2G		(1 << 4)
+#define CRT_HOTPLUG_DETECT_VOLTAGE_325MV	(0 << 2)
+#define CRT_HOTPLUG_DETECT_VOLTAGE_475MV	(1 << 2)
+
+#define PORT_HOTPLUG_STAT	_MMIO(dev_priv->info.display_mmio_offset + 0x61114)
+/*
+ * HDMI/DP bits are g4x+
+ *
+ * WARNING: Bspec for hpd status bits on gen4 seems to be completely confused.
+ * Please check the detailed lore in the commit message for for experimental
+ * evidence.
+ */
+/* Bspec says GM45 should match G4X/VLV/CHV, but reality disagrees */
+#define   PORTD_HOTPLUG_LIVE_STATUS_GM45	(1 << 29)
+#define   PORTC_HOTPLUG_LIVE_STATUS_GM45	(1 << 28)
+#define   PORTB_HOTPLUG_LIVE_STATUS_GM45	(1 << 27)
+/* G4X/VLV/CHV DP/HDMI bits again match Bspec */
+#define   PORTD_HOTPLUG_LIVE_STATUS_G4X		(1 << 27)
+#define   PORTC_HOTPLUG_LIVE_STATUS_G4X		(1 << 28)
+#define   PORTB_HOTPLUG_LIVE_STATUS_G4X		(1 << 29)
+#define   PORTD_HOTPLUG_INT_STATUS		(3 << 21)
+#define   PORTD_HOTPLUG_INT_LONG_PULSE		(2 << 21)
+#define   PORTD_HOTPLUG_INT_SHORT_PULSE		(1 << 21)
+#define   PORTC_HOTPLUG_INT_STATUS		(3 << 19)
+#define   PORTC_HOTPLUG_INT_LONG_PULSE		(2 << 19)
+#define   PORTC_HOTPLUG_INT_SHORT_PULSE		(1 << 19)
+#define   PORTB_HOTPLUG_INT_STATUS		(3 << 17)
+#define   PORTB_HOTPLUG_INT_LONG_PULSE		(2 << 17)
+#define   PORTB_HOTPLUG_INT_SHORT_PLUSE		(1 << 17)
+/* CRT/TV common between gen3+ */
+#define   CRT_HOTPLUG_INT_STATUS		(1 << 11)
+#define   TV_HOTPLUG_INT_STATUS			(1 << 10)
+#define   CRT_HOTPLUG_MONITOR_MASK		(3 << 8)
+#define   CRT_HOTPLUG_MONITOR_COLOR		(3 << 8)
+#define   CRT_HOTPLUG_MONITOR_MONO		(2 << 8)
+#define   CRT_HOTPLUG_MONITOR_NONE		(0 << 8)
+#define   DP_AUX_CHANNEL_D_INT_STATUS_G4X	(1 << 6)
+#define   DP_AUX_CHANNEL_C_INT_STATUS_G4X	(1 << 5)
+#define   DP_AUX_CHANNEL_B_INT_STATUS_G4X	(1 << 4)
+#define   DP_AUX_CHANNEL_MASK_INT_STATUS_G4X	(7 << 4)
+
+/* SDVO is different across gen3/4 */
+#define   SDVOC_HOTPLUG_INT_STATUS_G4X		(1 << 3)
+#define   SDVOB_HOTPLUG_INT_STATUS_G4X		(1 << 2)
+/*
+ * Bspec seems to be seriously misleaded about the SDVO hpd bits on i965g/gm,
+ * since reality corrobates that they're the same as on gen3. But keep these
+ * bits here (and the comment!) to help any other lost wanderers back onto the
+ * right tracks.
+ */
+#define   SDVOC_HOTPLUG_INT_STATUS_I965		(3 << 4)
+#define   SDVOB_HOTPLUG_INT_STATUS_I965		(3 << 2)
+#define   SDVOC_HOTPLUG_INT_STATUS_I915		(1 << 7)
+#define   SDVOB_HOTPLUG_INT_STATUS_I915		(1 << 6)
+#define   HOTPLUG_INT_STATUS_G4X		(CRT_HOTPLUG_INT_STATUS | \
+						 SDVOB_HOTPLUG_INT_STATUS_G4X | \
+						 SDVOC_HOTPLUG_INT_STATUS_G4X | \
+						 PORTB_HOTPLUG_INT_STATUS | \
+						 PORTC_HOTPLUG_INT_STATUS | \
+						 PORTD_HOTPLUG_INT_STATUS)
+
+#define HOTPLUG_INT_STATUS_I915			(CRT_HOTPLUG_INT_STATUS | \
+						 SDVOB_HOTPLUG_INT_STATUS_I915 | \
+						 SDVOC_HOTPLUG_INT_STATUS_I915 | \
+						 PORTB_HOTPLUG_INT_STATUS | \
+						 PORTC_HOTPLUG_INT_STATUS | \
+						 PORTD_HOTPLUG_INT_STATUS)
+
+/* SDVO and HDMI port control.
+ * The same register may be used for SDVO or HDMI */
+#define _GEN3_SDVOB	0x61140
+#define _GEN3_SDVOC	0x61160
+#define GEN3_SDVOB	_MMIO(_GEN3_SDVOB)
+#define GEN3_SDVOC	_MMIO(_GEN3_SDVOC)
+#define GEN4_HDMIB	GEN3_SDVOB
+#define GEN4_HDMIC	GEN3_SDVOC
+#define VLV_HDMIB	_MMIO(VLV_DISPLAY_BASE + 0x61140)
+#define VLV_HDMIC	_MMIO(VLV_DISPLAY_BASE + 0x61160)
+#define CHV_HDMID	_MMIO(VLV_DISPLAY_BASE + 0x6116C)
+#define PCH_SDVOB	_MMIO(0xe1140)
+#define PCH_HDMIB	PCH_SDVOB
+#define PCH_HDMIC	_MMIO(0xe1150)
+#define PCH_HDMID	_MMIO(0xe1160)
+
+#define PORT_DFT_I9XX				_MMIO(0x61150)
+#define   DC_BALANCE_RESET			(1 << 25)
+#define PORT_DFT2_G4X		_MMIO(dev_priv->info.display_mmio_offset + 0x61154)
+#define   DC_BALANCE_RESET_VLV			(1 << 31)
+#define   PIPE_SCRAMBLE_RESET_MASK		((1 << 14) | (0x3 << 0))
+#define   PIPE_C_SCRAMBLE_RESET			(1 << 14) /* chv */
+#define   PIPE_B_SCRAMBLE_RESET			(1 << 1)
+#define   PIPE_A_SCRAMBLE_RESET			(1 << 0)
+
+/* Gen 3 SDVO bits: */
+#define   SDVO_ENABLE				(1 << 31)
+#define   SDVO_PIPE_SEL(pipe)			((pipe) << 30)
+#define   SDVO_PIPE_SEL_MASK			(1 << 30)
+#define   SDVO_PIPE_B_SELECT			(1 << 30)
+#define   SDVO_STALL_SELECT			(1 << 29)
+#define   SDVO_INTERRUPT_ENABLE			(1 << 26)
+/*
+ * 915G/GM SDVO pixel multiplier.
+ * Programmed value is multiplier - 1, up to 5x.
+ * \sa DPLL_MD_UDI_MULTIPLIER_MASK
+ */
+#define   SDVO_PORT_MULTIPLY_MASK		(7 << 23)
+#define   SDVO_PORT_MULTIPLY_SHIFT		23
+#define   SDVO_PHASE_SELECT_MASK		(15 << 19)
+#define   SDVO_PHASE_SELECT_DEFAULT		(6 << 19)
+#define   SDVO_CLOCK_OUTPUT_INVERT		(1 << 18)
+#define   SDVOC_GANG_MODE			(1 << 16) /* Port C only */
+#define   SDVO_BORDER_ENABLE			(1 << 7) /* SDVO only */
+#define   SDVOB_PCIE_CONCURRENCY		(1 << 3) /* Port B only */
+#define   SDVO_DETECTED				(1 << 2)
+/* Bits to be preserved when writing */
+#define   SDVOB_PRESERVE_MASK ((1 << 17) | (1 << 16) | (1 << 14) | \
+			       SDVO_INTERRUPT_ENABLE)
+#define   SDVOC_PRESERVE_MASK ((1 << 17) | SDVO_INTERRUPT_ENABLE)
+
+/* Gen 4 SDVO/HDMI bits: */
+#define   SDVO_COLOR_FORMAT_8bpc		(0 << 26)
+#define   SDVO_COLOR_FORMAT_MASK		(7 << 26)
+#define   SDVO_ENCODING_SDVO			(0 << 10)
+#define   SDVO_ENCODING_HDMI			(2 << 10)
+#define   HDMI_MODE_SELECT_HDMI			(1 << 9) /* HDMI only */
+#define   HDMI_MODE_SELECT_DVI			(0 << 9) /* HDMI only */
+#define   HDMI_COLOR_RANGE_16_235		(1 << 8) /* HDMI only */
+#define   SDVO_AUDIO_ENABLE			(1 << 6)
+/* VSYNC/HSYNC bits new with 965, default is to be set */
+#define   SDVO_VSYNC_ACTIVE_HIGH		(1 << 4)
+#define   SDVO_HSYNC_ACTIVE_HIGH		(1 << 3)
+
+/* Gen 5 (IBX) SDVO/HDMI bits: */
+#define   HDMI_COLOR_FORMAT_12bpc		(3 << 26) /* HDMI only */
+#define   SDVOB_HOTPLUG_ENABLE			(1 << 23) /* SDVO only */
+
+/* Gen 6 (CPT) SDVO/HDMI bits: */
+#define   SDVO_PIPE_SEL_CPT(pipe)		((pipe) << 29)
+#define   SDVO_PIPE_SEL_MASK_CPT		(3 << 29)
+
+/* CHV SDVO/HDMI bits: */
+#define   SDVO_PIPE_SEL_CHV(pipe)		((pipe) << 24)
+#define   SDVO_PIPE_SEL_MASK_CHV		(3 << 24)
+
+
+/* DVO port control */
+#define _DVOA			0x61120
+#define DVOA			_MMIO(_DVOA)
+#define _DVOB			0x61140
+#define DVOB			_MMIO(_DVOB)
+#define _DVOC			0x61160
+#define DVOC			_MMIO(_DVOC)
+#define   DVO_ENABLE			(1 << 31)
+#define   DVO_PIPE_B_SELECT		(1 << 30)
+#define   DVO_PIPE_STALL_UNUSED		(0 << 28)
+#define   DVO_PIPE_STALL		(1 << 28)
+#define   DVO_PIPE_STALL_TV		(2 << 28)
+#define   DVO_PIPE_STALL_MASK		(3 << 28)
+#define   DVO_USE_VGA_SYNC		(1 << 15)
+#define   DVO_DATA_ORDER_I740		(0 << 14)
+#define   DVO_DATA_ORDER_FP		(1 << 14)
+#define   DVO_VSYNC_DISABLE		(1 << 11)
+#define   DVO_HSYNC_DISABLE		(1 << 10)
+#define   DVO_VSYNC_TRISTATE		(1 << 9)
+#define   DVO_HSYNC_TRISTATE		(1 << 8)
+#define   DVO_BORDER_ENABLE		(1 << 7)
+#define   DVO_DATA_ORDER_GBRG		(1 << 6)
+#define   DVO_DATA_ORDER_RGGB		(0 << 6)
+#define   DVO_DATA_ORDER_GBRG_ERRATA	(0 << 6)
+#define   DVO_DATA_ORDER_RGGB_ERRATA	(1 << 6)
+#define   DVO_VSYNC_ACTIVE_HIGH		(1 << 4)
+#define   DVO_HSYNC_ACTIVE_HIGH		(1 << 3)
+#define   DVO_BLANK_ACTIVE_HIGH		(1 << 2)
+#define   DVO_OUTPUT_CSTATE_PIXELS	(1 << 1)	/* SDG only */
+#define   DVO_OUTPUT_SOURCE_SIZE_PIXELS	(1 << 0)	/* SDG only */
+#define   DVO_PRESERVE_MASK		(0x7<<24)
+#define DVOA_SRCDIM		_MMIO(0x61124)
+#define DVOB_SRCDIM		_MMIO(0x61144)
+#define DVOC_SRCDIM		_MMIO(0x61164)
+#define   DVO_SRCDIM_HORIZONTAL_SHIFT	12
+#define   DVO_SRCDIM_VERTICAL_SHIFT	0
+
+/* LVDS port control */
+#define LVDS			_MMIO(0x61180)
+/*
+ * Enables the LVDS port.  This bit must be set before DPLLs are enabled, as
+ * the DPLL semantics change when the LVDS is assigned to that pipe.
+ */
+#define   LVDS_PORT_EN			(1 << 31)
+/* Selects pipe B for LVDS data.  Must be set on pre-965. */
+#define   LVDS_PIPEB_SELECT		(1 << 30)
+#define   LVDS_PIPE_MASK		(1 << 30)
+#define   LVDS_PIPE(pipe)		((pipe) << 30)
+/* LVDS dithering flag on 965/g4x platform */
+#define   LVDS_ENABLE_DITHER		(1 << 25)
+/* LVDS sync polarity flags. Set to invert (i.e. negative) */
+#define   LVDS_VSYNC_POLARITY		(1 << 21)
+#define   LVDS_HSYNC_POLARITY		(1 << 20)
+
+/* Enable border for unscaled (or aspect-scaled) display */
+#define   LVDS_BORDER_ENABLE		(1 << 15)
+/*
+ * Enables the A0-A2 data pairs and CLKA, containing 18 bits of color data per
+ * pixel.
+ */
+#define   LVDS_A0A2_CLKA_POWER_MASK	(3 << 8)
+#define   LVDS_A0A2_CLKA_POWER_DOWN	(0 << 8)
+#define   LVDS_A0A2_CLKA_POWER_UP	(3 << 8)
+/*
+ * Controls the A3 data pair, which contains the additional LSBs for 24 bit
+ * mode.  Only enabled if LVDS_A0A2_CLKA_POWER_UP also indicates it should be
+ * on.
+ */
+#define   LVDS_A3_POWER_MASK		(3 << 6)
+#define   LVDS_A3_POWER_DOWN		(0 << 6)
+#define   LVDS_A3_POWER_UP		(3 << 6)
+/*
+ * Controls the CLKB pair.  This should only be set when LVDS_B0B3_POWER_UP
+ * is set.
+ */
+#define   LVDS_CLKB_POWER_MASK		(3 << 4)
+#define   LVDS_CLKB_POWER_DOWN		(0 << 4)
+#define   LVDS_CLKB_POWER_UP		(3 << 4)
+/*
+ * Controls the B0-B3 data pairs.  This must be set to match the DPLL p2
+ * setting for whether we are in dual-channel mode.  The B3 pair will
+ * additionally only be powered up when LVDS_A3_POWER_UP is set.
+ */
+#define   LVDS_B0B3_POWER_MASK		(3 << 2)
+#define   LVDS_B0B3_POWER_DOWN		(0 << 2)
+#define   LVDS_B0B3_POWER_UP		(3 << 2)
+
+/* Video Data Island Packet control */
+#define VIDEO_DIP_DATA		_MMIO(0x61178)
+/* Read the description of VIDEO_DIP_DATA (before Haswell) or VIDEO_DIP_ECC
+ * (Haswell and newer) to see which VIDEO_DIP_DATA byte corresponds to each byte
+ * of the infoframe structure specified by CEA-861. */
+#define   VIDEO_DIP_DATA_SIZE	32
+#define   VIDEO_DIP_VSC_DATA_SIZE	36
+#define VIDEO_DIP_CTL		_MMIO(0x61170)
+/* Pre HSW: */
+#define   VIDEO_DIP_ENABLE		(1 << 31)
+#define   VIDEO_DIP_PORT(port)		((port) << 29)
+#define   VIDEO_DIP_PORT_MASK		(3 << 29)
+#define   VIDEO_DIP_ENABLE_GCP		(1 << 25)
+#define   VIDEO_DIP_ENABLE_AVI		(1 << 21)
+#define   VIDEO_DIP_ENABLE_VENDOR	(2 << 21)
+#define   VIDEO_DIP_ENABLE_GAMUT	(4 << 21)
+#define   VIDEO_DIP_ENABLE_SPD		(8 << 21)
+#define   VIDEO_DIP_SELECT_AVI		(0 << 19)
+#define   VIDEO_DIP_SELECT_VENDOR	(1 << 19)
+#define   VIDEO_DIP_SELECT_SPD		(3 << 19)
+#define   VIDEO_DIP_SELECT_MASK		(3 << 19)
+#define   VIDEO_DIP_FREQ_ONCE		(0 << 16)
+#define   VIDEO_DIP_FREQ_VSYNC		(1 << 16)
+#define   VIDEO_DIP_FREQ_2VSYNC		(2 << 16)
+#define   VIDEO_DIP_FREQ_MASK		(3 << 16)
+/* HSW and later: */
+#define   VIDEO_DIP_ENABLE_VSC_HSW	(1 << 20)
+#define   VIDEO_DIP_ENABLE_GCP_HSW	(1 << 16)
+#define   VIDEO_DIP_ENABLE_AVI_HSW	(1 << 12)
+#define   VIDEO_DIP_ENABLE_VS_HSW	(1 << 8)
+#define   VIDEO_DIP_ENABLE_GMP_HSW	(1 << 4)
+#define   VIDEO_DIP_ENABLE_SPD_HSW	(1 << 0)
+
+/* Panel power sequencing */
+#define PP_STATUS	_MMIO(0x61200)
+#define   PP_ON		(1 << 31)
+/*
+ * Indicates that all dependencies of the panel are on:
+ *
+ * - PLL enabled
+ * - pipe enabled
+ * - LVDS/DVOB/DVOC on
+ */
+#define   PP_READY		(1 << 30)
+#define   PP_SEQUENCE_NONE	(0 << 28)
+#define   PP_SEQUENCE_POWER_UP	(1 << 28)
+#define   PP_SEQUENCE_POWER_DOWN (2 << 28)
+#define   PP_SEQUENCE_MASK	(3 << 28)
+#define   PP_SEQUENCE_SHIFT	28
+#define   PP_CYCLE_DELAY_ACTIVE	(1 << 27)
+#define   PP_SEQUENCE_STATE_MASK 0x0000000f
+#define   PP_SEQUENCE_STATE_OFF_IDLE	(0x0 << 0)
+#define   PP_SEQUENCE_STATE_OFF_S0_1	(0x1 << 0)
+#define   PP_SEQUENCE_STATE_OFF_S0_2	(0x2 << 0)
+#define   PP_SEQUENCE_STATE_OFF_S0_3	(0x3 << 0)
+#define   PP_SEQUENCE_STATE_ON_IDLE	(0x8 << 0)
+#define   PP_SEQUENCE_STATE_ON_S1_0	(0x9 << 0)
+#define   PP_SEQUENCE_STATE_ON_S1_2	(0xa << 0)
+#define   PP_SEQUENCE_STATE_ON_S1_3	(0xb << 0)
+#define   PP_SEQUENCE_STATE_RESET	(0xf << 0)
+#define PP_CONTROL	_MMIO(0x61204)
+#define   POWER_TARGET_ON	(1 << 0)
+#define PP_ON_DELAYS	_MMIO(0x61208)
+#define PP_OFF_DELAYS	_MMIO(0x6120c)
+#define PP_DIVISOR	_MMIO(0x61210)
+
+/* Panel fitting */
+#define PFIT_CONTROL	_MMIO(dev_priv->info.display_mmio_offset + 0x61230)
+#define   PFIT_ENABLE		(1 << 31)
+#define   PFIT_PIPE_MASK	(3 << 29)
+#define   PFIT_PIPE_SHIFT	29
+#define   VERT_INTERP_DISABLE	(0 << 10)
+#define   VERT_INTERP_BILINEAR	(1 << 10)
+#define   VERT_INTERP_MASK	(3 << 10)
+#define   VERT_AUTO_SCALE	(1 << 9)
+#define   HORIZ_INTERP_DISABLE	(0 << 6)
+#define   HORIZ_INTERP_BILINEAR	(1 << 6)
+#define   HORIZ_INTERP_MASK	(3 << 6)
+#define   HORIZ_AUTO_SCALE	(1 << 5)
+#define   PANEL_8TO6_DITHER_ENABLE (1 << 3)
+#define   PFIT_FILTER_FUZZY	(0 << 24)
+#define   PFIT_SCALING_AUTO	(0 << 26)
+#define   PFIT_SCALING_PROGRAMMED (1 << 26)
+#define   PFIT_SCALING_PILLAR	(2 << 26)
+#define   PFIT_SCALING_LETTER	(3 << 26)
+#define PFIT_PGM_RATIOS _MMIO(dev_priv->info.display_mmio_offset + 0x61234)
+/* Pre-965 */
+#define		PFIT_VERT_SCALE_SHIFT		20
+#define		PFIT_VERT_SCALE_MASK		0xfff00000
+#define		PFIT_HORIZ_SCALE_SHIFT		4
+#define		PFIT_HORIZ_SCALE_MASK		0x0000fff0
+/* 965+ */
+#define		PFIT_VERT_SCALE_SHIFT_965	16
+#define		PFIT_VERT_SCALE_MASK_965	0x1fff0000
+#define		PFIT_HORIZ_SCALE_SHIFT_965	0
+#define		PFIT_HORIZ_SCALE_MASK_965	0x00001fff
+
+#define PFIT_AUTO_RATIOS _MMIO(dev_priv->info.display_mmio_offset + 0x61238)
+
+#define _VLV_BLC_PWM_CTL2_A (dev_priv->info.display_mmio_offset + 0x61250)
+#define _VLV_BLC_PWM_CTL2_B (dev_priv->info.display_mmio_offset + 0x61350)
+#define VLV_BLC_PWM_CTL2(pipe) _MMIO_PIPE(pipe, _VLV_BLC_PWM_CTL2_A, \
+					 _VLV_BLC_PWM_CTL2_B)
+
+#define _VLV_BLC_PWM_CTL_A (dev_priv->info.display_mmio_offset + 0x61254)
+#define _VLV_BLC_PWM_CTL_B (dev_priv->info.display_mmio_offset + 0x61354)
+#define VLV_BLC_PWM_CTL(pipe) _MMIO_PIPE(pipe, _VLV_BLC_PWM_CTL_A, \
+					_VLV_BLC_PWM_CTL_B)
+
+#define _VLV_BLC_HIST_CTL_A (dev_priv->info.display_mmio_offset + 0x61260)
+#define _VLV_BLC_HIST_CTL_B (dev_priv->info.display_mmio_offset + 0x61360)
+#define VLV_BLC_HIST_CTL(pipe) _MMIO_PIPE(pipe, _VLV_BLC_HIST_CTL_A, \
+					 _VLV_BLC_HIST_CTL_B)
+
+/* Backlight control */
+#define BLC_PWM_CTL2	_MMIO(dev_priv->info.display_mmio_offset + 0x61250) /* 965+ only */
+#define   BLM_PWM_ENABLE		(1 << 31)
+#define   BLM_COMBINATION_MODE		(1 << 30) /* gen4 only */
+#define   BLM_PIPE_SELECT		(1 << 29)
+#define   BLM_PIPE_SELECT_IVB		(3 << 29)
+#define   BLM_PIPE_A			(0 << 29)
+#define   BLM_PIPE_B			(1 << 29)
+#define   BLM_PIPE_C			(2 << 29) /* ivb + */
+#define   BLM_TRANSCODER_A		BLM_PIPE_A /* hsw */
+#define   BLM_TRANSCODER_B		BLM_PIPE_B
+#define   BLM_TRANSCODER_C		BLM_PIPE_C
+#define   BLM_TRANSCODER_EDP		(3 << 29)
+#define   BLM_PIPE(pipe)		((pipe) << 29)
+#define   BLM_POLARITY_I965		(1 << 28) /* gen4 only */
+#define   BLM_PHASE_IN_INTERUPT_STATUS	(1 << 26)
+#define   BLM_PHASE_IN_ENABLE		(1 << 25)
+#define   BLM_PHASE_IN_INTERUPT_ENABL	(1 << 24)
+#define   BLM_PHASE_IN_TIME_BASE_SHIFT	(16)
+#define   BLM_PHASE_IN_TIME_BASE_MASK	(0xff << 16)
+#define   BLM_PHASE_IN_COUNT_SHIFT	(8)
+#define   BLM_PHASE_IN_COUNT_MASK	(0xff << 8)
+#define   BLM_PHASE_IN_INCR_SHIFT	(0)
+#define   BLM_PHASE_IN_INCR_MASK	(0xff << 0)
+#define BLC_PWM_CTL	_MMIO(dev_priv->info.display_mmio_offset + 0x61254)
+/*
+ * This is the most significant 15 bits of the number of backlight cycles in a
+ * complete cycle of the modulated backlight control.
+ *
+ * The actual value is this field multiplied by two.
+ */
+#define   BACKLIGHT_MODULATION_FREQ_SHIFT	(17)
+#define   BACKLIGHT_MODULATION_FREQ_MASK	(0x7fff << 17)
+#define   BLM_LEGACY_MODE			(1 << 16) /* gen2 only */
+/*
+ * This is the number of cycles out of the backlight modulation cycle for which
+ * the backlight is on.
+ *
+ * This field must be no greater than the number of cycles in the complete
+ * backlight modulation cycle.
+ */
+#define   BACKLIGHT_DUTY_CYCLE_SHIFT		(0)
+#define   BACKLIGHT_DUTY_CYCLE_MASK		(0xffff)
+#define   BACKLIGHT_DUTY_CYCLE_MASK_PNV		(0xfffe)
+#define   BLM_POLARITY_PNV			(1 << 0) /* pnv only */
+
+#define BLC_HIST_CTL	_MMIO(dev_priv->info.display_mmio_offset + 0x61260)
+#define  BLM_HISTOGRAM_ENABLE			(1 << 31)
+
+/* New registers for PCH-split platforms. Safe where new bits show up, the
+ * register layout machtes with gen4 BLC_PWM_CTL[12]. */
+#define BLC_PWM_CPU_CTL2	_MMIO(0x48250)
+#define BLC_PWM_CPU_CTL		_MMIO(0x48254)
+
+#define HSW_BLC_PWM2_CTL	_MMIO(0x48350)
+
+/* PCH CTL1 is totally different, all but the below bits are reserved. CTL2 is
+ * like the normal CTL from gen4 and earlier. Hooray for confusing naming. */
+#define BLC_PWM_PCH_CTL1	_MMIO(0xc8250)
+#define   BLM_PCH_PWM_ENABLE			(1 << 31)
+#define   BLM_PCH_OVERRIDE_ENABLE		(1 << 30)
+#define   BLM_PCH_POLARITY			(1 << 29)
+#define BLC_PWM_PCH_CTL2	_MMIO(0xc8254)
+
+#define UTIL_PIN_CTL		_MMIO(0x48400)
+#define   UTIL_PIN_ENABLE	(1 << 31)
+
+#define   UTIL_PIN_PIPE(x)     ((x) << 29)
+#define   UTIL_PIN_PIPE_MASK   (3 << 29)
+#define   UTIL_PIN_MODE_PWM    (1 << 24)
+#define   UTIL_PIN_MODE_MASK   (0xf << 24)
+#define   UTIL_PIN_POLARITY    (1 << 22)
+
+/* BXT backlight register definition. */
+#define _BXT_BLC_PWM_CTL1			0xC8250
+#define   BXT_BLC_PWM_ENABLE			(1 << 31)
+#define   BXT_BLC_PWM_POLARITY			(1 << 29)
+#define _BXT_BLC_PWM_FREQ1			0xC8254
+#define _BXT_BLC_PWM_DUTY1			0xC8258
+
+#define _BXT_BLC_PWM_CTL2			0xC8350
+#define _BXT_BLC_PWM_FREQ2			0xC8354
+#define _BXT_BLC_PWM_DUTY2			0xC8358
+
+#define BXT_BLC_PWM_CTL(controller)    _MMIO_PIPE(controller,		\
+					_BXT_BLC_PWM_CTL1, _BXT_BLC_PWM_CTL2)
+#define BXT_BLC_PWM_FREQ(controller)   _MMIO_PIPE(controller, \
+					_BXT_BLC_PWM_FREQ1, _BXT_BLC_PWM_FREQ2)
+#define BXT_BLC_PWM_DUTY(controller)   _MMIO_PIPE(controller, \
+					_BXT_BLC_PWM_DUTY1, _BXT_BLC_PWM_DUTY2)
+
+#define PCH_GTC_CTL		_MMIO(0xe7000)
+#define   PCH_GTC_ENABLE	(1 << 31)
+
+/* TV port control */
+#define TV_CTL			_MMIO(0x68000)
+/* Enables the TV encoder */
+# define TV_ENC_ENABLE			(1 << 31)
+/* Sources the TV encoder input from pipe B instead of A. */
+# define TV_ENC_PIPEB_SELECT		(1 << 30)
+/* Outputs composite video (DAC A only) */
+# define TV_ENC_OUTPUT_COMPOSITE	(0 << 28)
+/* Outputs SVideo video (DAC B/C) */
+# define TV_ENC_OUTPUT_SVIDEO		(1 << 28)
+/* Outputs Component video (DAC A/B/C) */
+# define TV_ENC_OUTPUT_COMPONENT	(2 << 28)
+/* Outputs Composite and SVideo (DAC A/B/C) */
+# define TV_ENC_OUTPUT_SVIDEO_COMPOSITE	(3 << 28)
+# define TV_TRILEVEL_SYNC		(1 << 21)
+/* Enables slow sync generation (945GM only) */
+# define TV_SLOW_SYNC			(1 << 20)
+/* Selects 4x oversampling for 480i and 576p */
+# define TV_OVERSAMPLE_4X		(0 << 18)
+/* Selects 2x oversampling for 720p and 1080i */
+# define TV_OVERSAMPLE_2X		(1 << 18)
+/* Selects no oversampling for 1080p */
+# define TV_OVERSAMPLE_NONE		(2 << 18)
+/* Selects 8x oversampling */
+# define TV_OVERSAMPLE_8X		(3 << 18)
+/* Selects progressive mode rather than interlaced */
+# define TV_PROGRESSIVE			(1 << 17)
+/* Sets the colorburst to PAL mode.  Required for non-M PAL modes. */
+# define TV_PAL_BURST			(1 << 16)
+/* Field for setting delay of Y compared to C */
+# define TV_YC_SKEW_MASK		(7 << 12)
+/* Enables a fix for 480p/576p standard definition modes on the 915GM only */
+# define TV_ENC_SDP_FIX			(1 << 11)
+/*
+ * Enables a fix for the 915GM only.
+ *
+ * Not sure what it does.
+ */
+# define TV_ENC_C0_FIX			(1 << 10)
+/* Bits that must be preserved by software */
+# define TV_CTL_SAVE			((1 << 11) | (3 << 9) | (7 << 6) | 0xf)
+# define TV_FUSE_STATE_MASK		(3 << 4)
+/* Read-only state that reports all features enabled */
+# define TV_FUSE_STATE_ENABLED		(0 << 4)
+/* Read-only state that reports that Macrovision is disabled in hardware*/
+# define TV_FUSE_STATE_NO_MACROVISION	(1 << 4)
+/* Read-only state that reports that TV-out is disabled in hardware. */
+# define TV_FUSE_STATE_DISABLED		(2 << 4)
+/* Normal operation */
+# define TV_TEST_MODE_NORMAL		(0 << 0)
+/* Encoder test pattern 1 - combo pattern */
+# define TV_TEST_MODE_PATTERN_1		(1 << 0)
+/* Encoder test pattern 2 - full screen vertical 75% color bars */
+# define TV_TEST_MODE_PATTERN_2		(2 << 0)
+/* Encoder test pattern 3 - full screen horizontal 75% color bars */
+# define TV_TEST_MODE_PATTERN_3		(3 << 0)
+/* Encoder test pattern 4 - random noise */
+# define TV_TEST_MODE_PATTERN_4		(4 << 0)
+/* Encoder test pattern 5 - linear color ramps */
+# define TV_TEST_MODE_PATTERN_5		(5 << 0)
+/*
+ * This test mode forces the DACs to 50% of full output.
+ *
+ * This is used for load detection in combination with TVDAC_SENSE_MASK
+ */
+# define TV_TEST_MODE_MONITOR_DETECT	(7 << 0)
+# define TV_TEST_MODE_MASK		(7 << 0)
+
+#define TV_DAC			_MMIO(0x68004)
+# define TV_DAC_SAVE		0x00ffff00
+/*
+ * Reports that DAC state change logic has reported change (RO).
+ *
+ * This gets cleared when TV_DAC_STATE_EN is cleared
+*/
+# define TVDAC_STATE_CHG		(1 << 31)
+# define TVDAC_SENSE_MASK		(7 << 28)
+/* Reports that DAC A voltage is above the detect threshold */
+# define TVDAC_A_SENSE			(1 << 30)
+/* Reports that DAC B voltage is above the detect threshold */
+# define TVDAC_B_SENSE			(1 << 29)
+/* Reports that DAC C voltage is above the detect threshold */
+# define TVDAC_C_SENSE			(1 << 28)
+/*
+ * Enables DAC state detection logic, for load-based TV detection.
+ *
+ * The PLL of the chosen pipe (in TV_CTL) must be running, and the encoder set
+ * to off, for load detection to work.
+ */
+# define TVDAC_STATE_CHG_EN		(1 << 27)
+/* Sets the DAC A sense value to high */
+# define TVDAC_A_SENSE_CTL		(1 << 26)
+/* Sets the DAC B sense value to high */
+# define TVDAC_B_SENSE_CTL		(1 << 25)
+/* Sets the DAC C sense value to high */
+# define TVDAC_C_SENSE_CTL		(1 << 24)
+/* Overrides the ENC_ENABLE and DAC voltage levels */
+# define DAC_CTL_OVERRIDE		(1 << 7)
+/* Sets the slew rate.  Must be preserved in software */
+# define ENC_TVDAC_SLEW_FAST		(1 << 6)
+# define DAC_A_1_3_V			(0 << 4)
+# define DAC_A_1_1_V			(1 << 4)
+# define DAC_A_0_7_V			(2 << 4)
+# define DAC_A_MASK			(3 << 4)
+# define DAC_B_1_3_V			(0 << 2)
+# define DAC_B_1_1_V			(1 << 2)
+# define DAC_B_0_7_V			(2 << 2)
+# define DAC_B_MASK			(3 << 2)
+# define DAC_C_1_3_V			(0 << 0)
+# define DAC_C_1_1_V			(1 << 0)
+# define DAC_C_0_7_V			(2 << 0)
+# define DAC_C_MASK			(3 << 0)
+
+/*
+ * CSC coefficients are stored in a floating point format with 9 bits of
+ * mantissa and 2 or 3 bits of exponent.  The exponent is represented as 2**-n,
+ * where 2-bit exponents are unsigned n, and 3-bit exponents are signed n with
+ * -1 (0x3) being the only legal negative value.
+ */
+#define TV_CSC_Y		_MMIO(0x68010)
+# define TV_RY_MASK			0x07ff0000
+# define TV_RY_SHIFT			16
+# define TV_GY_MASK			0x00000fff
+# define TV_GY_SHIFT			0
+
+#define TV_CSC_Y2		_MMIO(0x68014)
+# define TV_BY_MASK			0x07ff0000
+# define TV_BY_SHIFT			16
+/*
+ * Y attenuation for component video.
+ *
+ * Stored in 1.9 fixed point.
+ */
+# define TV_AY_MASK			0x000003ff
+# define TV_AY_SHIFT			0
+
+#define TV_CSC_U		_MMIO(0x68018)
+# define TV_RU_MASK			0x07ff0000
+# define TV_RU_SHIFT			16
+# define TV_GU_MASK			0x000007ff
+# define TV_GU_SHIFT			0
+
+#define TV_CSC_U2		_MMIO(0x6801c)
+# define TV_BU_MASK			0x07ff0000
+# define TV_BU_SHIFT			16
+/*
+ * U attenuation for component video.
+ *
+ * Stored in 1.9 fixed point.
+ */
+# define TV_AU_MASK			0x000003ff
+# define TV_AU_SHIFT			0
+
+#define TV_CSC_V		_MMIO(0x68020)
+# define TV_RV_MASK			0x0fff0000
+# define TV_RV_SHIFT			16
+# define TV_GV_MASK			0x000007ff
+# define TV_GV_SHIFT			0
+
+#define TV_CSC_V2		_MMIO(0x68024)
+# define TV_BV_MASK			0x07ff0000
+# define TV_BV_SHIFT			16
+/*
+ * V attenuation for component video.
+ *
+ * Stored in 1.9 fixed point.
+ */
+# define TV_AV_MASK			0x000007ff
+# define TV_AV_SHIFT			0
+
+#define TV_CLR_KNOBS		_MMIO(0x68028)
+/* 2s-complement brightness adjustment */
+# define TV_BRIGHTNESS_MASK		0xff000000
+# define TV_BRIGHTNESS_SHIFT		24
+/* Contrast adjustment, as a 2.6 unsigned floating point number */
+# define TV_CONTRAST_MASK		0x00ff0000
+# define TV_CONTRAST_SHIFT		16
+/* Saturation adjustment, as a 2.6 unsigned floating point number */
+# define TV_SATURATION_MASK		0x0000ff00
+# define TV_SATURATION_SHIFT		8
+/* Hue adjustment, as an integer phase angle in degrees */
+# define TV_HUE_MASK			0x000000ff
+# define TV_HUE_SHIFT			0
+
+#define TV_CLR_LEVEL		_MMIO(0x6802c)
+/* Controls the DAC level for black */
+# define TV_BLACK_LEVEL_MASK		0x01ff0000
+# define TV_BLACK_LEVEL_SHIFT		16
+/* Controls the DAC level for blanking */
+# define TV_BLANK_LEVEL_MASK		0x000001ff
+# define TV_BLANK_LEVEL_SHIFT		0
+
+#define TV_H_CTL_1		_MMIO(0x68030)
+/* Number of pixels in the hsync. */
+# define TV_HSYNC_END_MASK		0x1fff0000
+# define TV_HSYNC_END_SHIFT		16
+/* Total number of pixels minus one in the line (display and blanking). */
+# define TV_HTOTAL_MASK			0x00001fff
+# define TV_HTOTAL_SHIFT		0
+
+#define TV_H_CTL_2		_MMIO(0x68034)
+/* Enables the colorburst (needed for non-component color) */
+# define TV_BURST_ENA			(1 << 31)
+/* Offset of the colorburst from the start of hsync, in pixels minus one. */
+# define TV_HBURST_START_SHIFT		16
+# define TV_HBURST_START_MASK		0x1fff0000
+/* Length of the colorburst */
+# define TV_HBURST_LEN_SHIFT		0
+# define TV_HBURST_LEN_MASK		0x0001fff
+
+#define TV_H_CTL_3		_MMIO(0x68038)
+/* End of hblank, measured in pixels minus one from start of hsync */
+# define TV_HBLANK_END_SHIFT		16
+# define TV_HBLANK_END_MASK		0x1fff0000
+/* Start of hblank, measured in pixels minus one from start of hsync */
+# define TV_HBLANK_START_SHIFT		0
+# define TV_HBLANK_START_MASK		0x0001fff
+
+#define TV_V_CTL_1		_MMIO(0x6803c)
+/* XXX */
+# define TV_NBR_END_SHIFT		16
+# define TV_NBR_END_MASK		0x07ff0000
+/* XXX */
+# define TV_VI_END_F1_SHIFT		8
+# define TV_VI_END_F1_MASK		0x00003f00
+/* XXX */
+# define TV_VI_END_F2_SHIFT		0
+# define TV_VI_END_F2_MASK		0x0000003f
+
+#define TV_V_CTL_2		_MMIO(0x68040)
+/* Length of vsync, in half lines */
+# define TV_VSYNC_LEN_MASK		0x07ff0000
+# define TV_VSYNC_LEN_SHIFT		16
+/* Offset of the start of vsync in field 1, measured in one less than the
+ * number of half lines.
+ */
+# define TV_VSYNC_START_F1_MASK		0x00007f00
+# define TV_VSYNC_START_F1_SHIFT	8
+/*
+ * Offset of the start of vsync in field 2, measured in one less than the
+ * number of half lines.
+ */
+# define TV_VSYNC_START_F2_MASK		0x0000007f
+# define TV_VSYNC_START_F2_SHIFT	0
+
+#define TV_V_CTL_3		_MMIO(0x68044)
+/* Enables generation of the equalization signal */
+# define TV_EQUAL_ENA			(1 << 31)
+/* Length of vsync, in half lines */
+# define TV_VEQ_LEN_MASK		0x007f0000
+# define TV_VEQ_LEN_SHIFT		16
+/* Offset of the start of equalization in field 1, measured in one less than
+ * the number of half lines.
+ */
+# define TV_VEQ_START_F1_MASK		0x0007f00
+# define TV_VEQ_START_F1_SHIFT		8
+/*
+ * Offset of the start of equalization in field 2, measured in one less than
+ * the number of half lines.
+ */
+# define TV_VEQ_START_F2_MASK		0x000007f
+# define TV_VEQ_START_F2_SHIFT		0
+
+#define TV_V_CTL_4		_MMIO(0x68048)
+/*
+ * Offset to start of vertical colorburst, measured in one less than the
+ * number of lines from vertical start.
+ */
+# define TV_VBURST_START_F1_MASK	0x003f0000
+# define TV_VBURST_START_F1_SHIFT	16
+/*
+ * Offset to the end of vertical colorburst, measured in one less than the
+ * number of lines from the start of NBR.
+ */
+# define TV_VBURST_END_F1_MASK		0x000000ff
+# define TV_VBURST_END_F1_SHIFT		0
+
+#define TV_V_CTL_5		_MMIO(0x6804c)
+/*
+ * Offset to start of vertical colorburst, measured in one less than the
+ * number of lines from vertical start.
+ */
+# define TV_VBURST_START_F2_MASK	0x003f0000
+# define TV_VBURST_START_F2_SHIFT	16
+/*
+ * Offset to the end of vertical colorburst, measured in one less than the
+ * number of lines from the start of NBR.
+ */
+# define TV_VBURST_END_F2_MASK		0x000000ff
+# define TV_VBURST_END_F2_SHIFT		0
+
+#define TV_V_CTL_6		_MMIO(0x68050)
+/*
+ * Offset to start of vertical colorburst, measured in one less than the
+ * number of lines from vertical start.
+ */
+# define TV_VBURST_START_F3_MASK	0x003f0000
+# define TV_VBURST_START_F3_SHIFT	16
+/*
+ * Offset to the end of vertical colorburst, measured in one less than the
+ * number of lines from the start of NBR.
+ */
+# define TV_VBURST_END_F3_MASK		0x000000ff
+# define TV_VBURST_END_F3_SHIFT		0
+
+#define TV_V_CTL_7		_MMIO(0x68054)
+/*
+ * Offset to start of vertical colorburst, measured in one less than the
+ * number of lines from vertical start.
+ */
+# define TV_VBURST_START_F4_MASK	0x003f0000
+# define TV_VBURST_START_F4_SHIFT	16
+/*
+ * Offset to the end of vertical colorburst, measured in one less than the
+ * number of lines from the start of NBR.
+ */
+# define TV_VBURST_END_F4_MASK		0x000000ff
+# define TV_VBURST_END_F4_SHIFT		0
+
+#define TV_SC_CTL_1		_MMIO(0x68060)
+/* Turns on the first subcarrier phase generation DDA */
+# define TV_SC_DDA1_EN			(1 << 31)
+/* Turns on the first subcarrier phase generation DDA */
+# define TV_SC_DDA2_EN			(1 << 30)
+/* Turns on the first subcarrier phase generation DDA */
+# define TV_SC_DDA3_EN			(1 << 29)
+/* Sets the subcarrier DDA to reset frequency every other field */
+# define TV_SC_RESET_EVERY_2		(0 << 24)
+/* Sets the subcarrier DDA to reset frequency every fourth field */
+# define TV_SC_RESET_EVERY_4		(1 << 24)
+/* Sets the subcarrier DDA to reset frequency every eighth field */
+# define TV_SC_RESET_EVERY_8		(2 << 24)
+/* Sets the subcarrier DDA to never reset the frequency */
+# define TV_SC_RESET_NEVER		(3 << 24)
+/* Sets the peak amplitude of the colorburst.*/
+# define TV_BURST_LEVEL_MASK		0x00ff0000
+# define TV_BURST_LEVEL_SHIFT		16
+/* Sets the increment of the first subcarrier phase generation DDA */
+# define TV_SCDDA1_INC_MASK		0x00000fff
+# define TV_SCDDA1_INC_SHIFT		0
+
+#define TV_SC_CTL_2		_MMIO(0x68064)
+/* Sets the rollover for the second subcarrier phase generation DDA */
+# define TV_SCDDA2_SIZE_MASK		0x7fff0000
+# define TV_SCDDA2_SIZE_SHIFT		16
+/* Sets the increent of the second subcarrier phase generation DDA */
+# define TV_SCDDA2_INC_MASK		0x00007fff
+# define TV_SCDDA2_INC_SHIFT		0
+
+#define TV_SC_CTL_3		_MMIO(0x68068)
+/* Sets the rollover for the third subcarrier phase generation DDA */
+# define TV_SCDDA3_SIZE_MASK		0x7fff0000
+# define TV_SCDDA3_SIZE_SHIFT		16
+/* Sets the increent of the third subcarrier phase generation DDA */
+# define TV_SCDDA3_INC_MASK		0x00007fff
+# define TV_SCDDA3_INC_SHIFT		0
+
+#define TV_WIN_POS		_MMIO(0x68070)
+/* X coordinate of the display from the start of horizontal active */
+# define TV_XPOS_MASK			0x1fff0000
+# define TV_XPOS_SHIFT			16
+/* Y coordinate of the display from the start of vertical active (NBR) */
+# define TV_YPOS_MASK			0x00000fff
+# define TV_YPOS_SHIFT			0
+
+#define TV_WIN_SIZE		_MMIO(0x68074)
+/* Horizontal size of the display window, measured in pixels*/
+# define TV_XSIZE_MASK			0x1fff0000
+# define TV_XSIZE_SHIFT			16
+/*
+ * Vertical size of the display window, measured in pixels.
+ *
+ * Must be even for interlaced modes.
+ */
+# define TV_YSIZE_MASK			0x00000fff
+# define TV_YSIZE_SHIFT			0
+
+#define TV_FILTER_CTL_1		_MMIO(0x68080)
+/*
+ * Enables automatic scaling calculation.
+ *
+ * If set, the rest of the registers are ignored, and the calculated values can
+ * be read back from the register.
+ */
+# define TV_AUTO_SCALE			(1 << 31)
+/*
+ * Disables the vertical filter.
+ *
+ * This is required on modes more than 1024 pixels wide */
+# define TV_V_FILTER_BYPASS		(1 << 29)
+/* Enables adaptive vertical filtering */
+# define TV_VADAPT			(1 << 28)
+# define TV_VADAPT_MODE_MASK		(3 << 26)
+/* Selects the least adaptive vertical filtering mode */
+# define TV_VADAPT_MODE_LEAST		(0 << 26)
+/* Selects the moderately adaptive vertical filtering mode */
+# define TV_VADAPT_MODE_MODERATE	(1 << 26)
+/* Selects the most adaptive vertical filtering mode */
+# define TV_VADAPT_MODE_MOST		(3 << 26)
+/*
+ * Sets the horizontal scaling factor.
+ *
+ * This should be the fractional part of the horizontal scaling factor divided
+ * by the oversampling rate.  TV_HSCALE should be less than 1, and set to:
+ *
+ * (src width - 1) / ((oversample * dest width) - 1)
+ */
+# define TV_HSCALE_FRAC_MASK		0x00003fff
+# define TV_HSCALE_FRAC_SHIFT		0
+
+#define TV_FILTER_CTL_2		_MMIO(0x68084)
+/*
+ * Sets the integer part of the 3.15 fixed-point vertical scaling factor.
+ *
+ * TV_VSCALE should be (src height - 1) / ((interlace * dest height) - 1)
+ */
+# define TV_VSCALE_INT_MASK		0x00038000
+# define TV_VSCALE_INT_SHIFT		15
+/*
+ * Sets the fractional part of the 3.15 fixed-point vertical scaling factor.
+ *
+ * \sa TV_VSCALE_INT_MASK
+ */
+# define TV_VSCALE_FRAC_MASK		0x00007fff
+# define TV_VSCALE_FRAC_SHIFT		0
+
+#define TV_FILTER_CTL_3		_MMIO(0x68088)
+/*
+ * Sets the integer part of the 3.15 fixed-point vertical scaling factor.
+ *
+ * TV_VSCALE should be (src height - 1) / (1/4 * (dest height - 1))
+ *
+ * For progressive modes, TV_VSCALE_IP_INT should be set to zeroes.
+ */
+# define TV_VSCALE_IP_INT_MASK		0x00038000
+# define TV_VSCALE_IP_INT_SHIFT		15
+/*
+ * Sets the fractional part of the 3.15 fixed-point vertical scaling factor.
+ *
+ * For progressive modes, TV_VSCALE_IP_INT should be set to zeroes.
+ *
+ * \sa TV_VSCALE_IP_INT_MASK
+ */
+# define TV_VSCALE_IP_FRAC_MASK		0x00007fff
+# define TV_VSCALE_IP_FRAC_SHIFT		0
+
+#define TV_CC_CONTROL		_MMIO(0x68090)
+# define TV_CC_ENABLE			(1 << 31)
+/*
+ * Specifies which field to send the CC data in.
+ *
+ * CC data is usually sent in field 0.
+ */
+# define TV_CC_FID_MASK			(1 << 27)
+# define TV_CC_FID_SHIFT		27
+/* Sets the horizontal position of the CC data.  Usually 135. */
+# define TV_CC_HOFF_MASK		0x03ff0000
+# define TV_CC_HOFF_SHIFT		16
+/* Sets the vertical position of the CC data.  Usually 21 */
+# define TV_CC_LINE_MASK		0x0000003f
+# define TV_CC_LINE_SHIFT		0
+
+#define TV_CC_DATA		_MMIO(0x68094)
+# define TV_CC_RDY			(1 << 31)
+/* Second word of CC data to be transmitted. */
+# define TV_CC_DATA_2_MASK		0x007f0000
+# define TV_CC_DATA_2_SHIFT		16
+/* First word of CC data to be transmitted. */
+# define TV_CC_DATA_1_MASK		0x0000007f
+# define TV_CC_DATA_1_SHIFT		0
+
+#define TV_H_LUMA(i)		_MMIO(0x68100 + (i) * 4) /* 60 registers */
+#define TV_H_CHROMA(i)		_MMIO(0x68200 + (i) * 4) /* 60 registers */
+#define TV_V_LUMA(i)		_MMIO(0x68300 + (i) * 4) /* 43 registers */
+#define TV_V_CHROMA(i)		_MMIO(0x68400 + (i) * 4) /* 43 registers */
+
+/* Display Port */
+#define DP_A			_MMIO(0x64000) /* eDP */
+#define DP_B			_MMIO(0x64100)
+#define DP_C			_MMIO(0x64200)
+#define DP_D			_MMIO(0x64300)
+
+#define VLV_DP_B		_MMIO(VLV_DISPLAY_BASE + 0x64100)
+#define VLV_DP_C		_MMIO(VLV_DISPLAY_BASE + 0x64200)
+#define CHV_DP_D		_MMIO(VLV_DISPLAY_BASE + 0x64300)
+
+#define   DP_PORT_EN			(1 << 31)
+#define   DP_PIPEB_SELECT		(1 << 30)
+#define   DP_PIPE_MASK			(1 << 30)
+#define   DP_PIPE_SELECT_CHV(pipe)	((pipe) << 16)
+#define   DP_PIPE_MASK_CHV		(3 << 16)
+
+/* Link training mode - select a suitable mode for each stage */
+#define   DP_LINK_TRAIN_PAT_1		(0 << 28)
+#define   DP_LINK_TRAIN_PAT_2		(1 << 28)
+#define   DP_LINK_TRAIN_PAT_IDLE	(2 << 28)
+#define   DP_LINK_TRAIN_OFF		(3 << 28)
+#define   DP_LINK_TRAIN_MASK		(3 << 28)
+#define   DP_LINK_TRAIN_SHIFT		28
+#define   DP_LINK_TRAIN_PAT_3_CHV	(1 << 14)
+#define   DP_LINK_TRAIN_MASK_CHV	((3 << 28)|(1<<14))
+
+/* CPT Link training mode */
+#define   DP_LINK_TRAIN_PAT_1_CPT	(0 << 8)
+#define   DP_LINK_TRAIN_PAT_2_CPT	(1 << 8)
+#define   DP_LINK_TRAIN_PAT_IDLE_CPT	(2 << 8)
+#define   DP_LINK_TRAIN_OFF_CPT		(3 << 8)
+#define   DP_LINK_TRAIN_MASK_CPT	(7 << 8)
+#define   DP_LINK_TRAIN_SHIFT_CPT	8
+
+/* Signal voltages. These are mostly controlled by the other end */
+#define   DP_VOLTAGE_0_4		(0 << 25)
+#define   DP_VOLTAGE_0_6		(1 << 25)
+#define   DP_VOLTAGE_0_8		(2 << 25)
+#define   DP_VOLTAGE_1_2		(3 << 25)
+#define   DP_VOLTAGE_MASK		(7 << 25)
+#define   DP_VOLTAGE_SHIFT		25
+
+/* Signal pre-emphasis levels, like voltages, the other end tells us what
+ * they want
+ */
+#define   DP_PRE_EMPHASIS_0		(0 << 22)
+#define   DP_PRE_EMPHASIS_3_5		(1 << 22)
+#define   DP_PRE_EMPHASIS_6		(2 << 22)
+#define   DP_PRE_EMPHASIS_9_5		(3 << 22)
+#define   DP_PRE_EMPHASIS_MASK		(7 << 22)
+#define   DP_PRE_EMPHASIS_SHIFT		22
+
+/* How many wires to use. I guess 3 was too hard */
+#define   DP_PORT_WIDTH(width)		(((width) - 1) << 19)
+#define   DP_PORT_WIDTH_MASK		(7 << 19)
+#define   DP_PORT_WIDTH_SHIFT		19
+
+/* Mystic DPCD version 1.1 special mode */
+#define   DP_ENHANCED_FRAMING		(1 << 18)
+
+/* eDP */
+#define   DP_PLL_FREQ_270MHZ		(0 << 16)
+#define   DP_PLL_FREQ_162MHZ		(1 << 16)
+#define   DP_PLL_FREQ_MASK		(3 << 16)
+
+/* locked once port is enabled */
+#define   DP_PORT_REVERSAL		(1 << 15)
+
+/* eDP */
+#define   DP_PLL_ENABLE			(1 << 14)
+
+/* sends the clock on lane 15 of the PEG for debug */
+#define   DP_CLOCK_OUTPUT_ENABLE	(1 << 13)
+
+#define   DP_SCRAMBLING_DISABLE		(1 << 12)
+#define   DP_SCRAMBLING_DISABLE_IRONLAKE	(1 << 7)
+
+/* limit RGB values to avoid confusing TVs */
+#define   DP_COLOR_RANGE_16_235		(1 << 8)
+
+/* Turn on the audio link */
+#define   DP_AUDIO_OUTPUT_ENABLE	(1 << 6)
+
+/* vs and hs sync polarity */
+#define   DP_SYNC_VS_HIGH		(1 << 4)
+#define   DP_SYNC_HS_HIGH		(1 << 3)
+
+/* A fantasy */
+#define   DP_DETECTED			(1 << 2)
+
+/* The aux channel provides a way to talk to the
+ * signal sink for DDC etc. Max packet size supported
+ * is 20 bytes in each direction, hence the 5 fixed
+ * data registers
+ */
+#define _DPA_AUX_CH_CTL		(dev_priv->info.display_mmio_offset + 0x64010)
+#define _DPA_AUX_CH_DATA1	(dev_priv->info.display_mmio_offset + 0x64014)
+#define _DPA_AUX_CH_DATA2	(dev_priv->info.display_mmio_offset + 0x64018)
+#define _DPA_AUX_CH_DATA3	(dev_priv->info.display_mmio_offset + 0x6401c)
+#define _DPA_AUX_CH_DATA4	(dev_priv->info.display_mmio_offset + 0x64020)
+#define _DPA_AUX_CH_DATA5	(dev_priv->info.display_mmio_offset + 0x64024)
+
+#define _DPB_AUX_CH_CTL		(dev_priv->info.display_mmio_offset + 0x64110)
+#define _DPB_AUX_CH_DATA1	(dev_priv->info.display_mmio_offset + 0x64114)
+#define _DPB_AUX_CH_DATA2	(dev_priv->info.display_mmio_offset + 0x64118)
+#define _DPB_AUX_CH_DATA3	(dev_priv->info.display_mmio_offset + 0x6411c)
+#define _DPB_AUX_CH_DATA4	(dev_priv->info.display_mmio_offset + 0x64120)
+#define _DPB_AUX_CH_DATA5	(dev_priv->info.display_mmio_offset + 0x64124)
+
+#define _DPC_AUX_CH_CTL		(dev_priv->info.display_mmio_offset + 0x64210)
+#define _DPC_AUX_CH_DATA1	(dev_priv->info.display_mmio_offset + 0x64214)
+#define _DPC_AUX_CH_DATA2	(dev_priv->info.display_mmio_offset + 0x64218)
+#define _DPC_AUX_CH_DATA3	(dev_priv->info.display_mmio_offset + 0x6421c)
+#define _DPC_AUX_CH_DATA4	(dev_priv->info.display_mmio_offset + 0x64220)
+#define _DPC_AUX_CH_DATA5	(dev_priv->info.display_mmio_offset + 0x64224)
+
+#define _DPD_AUX_CH_CTL		(dev_priv->info.display_mmio_offset + 0x64310)
+#define _DPD_AUX_CH_DATA1	(dev_priv->info.display_mmio_offset + 0x64314)
+#define _DPD_AUX_CH_DATA2	(dev_priv->info.display_mmio_offset + 0x64318)
+#define _DPD_AUX_CH_DATA3	(dev_priv->info.display_mmio_offset + 0x6431c)
+#define _DPD_AUX_CH_DATA4	(dev_priv->info.display_mmio_offset + 0x64320)
+#define _DPD_AUX_CH_DATA5	(dev_priv->info.display_mmio_offset + 0x64324)
+
+#define DP_AUX_CH_CTL(port)	_MMIO_PORT(port, _DPA_AUX_CH_CTL, _DPB_AUX_CH_CTL)
+#define DP_AUX_CH_DATA(port, i)	_MMIO(_PORT(port, _DPA_AUX_CH_DATA1, _DPB_AUX_CH_DATA1) + (i) * 4) /* 5 registers */
+
+#define   DP_AUX_CH_CTL_SEND_BUSY	    (1 << 31)
+#define   DP_AUX_CH_CTL_DONE		    (1 << 30)
+#define   DP_AUX_CH_CTL_INTERRUPT	    (1 << 29)
+#define   DP_AUX_CH_CTL_TIME_OUT_ERROR	    (1 << 28)
+#define   DP_AUX_CH_CTL_TIME_OUT_400us	    (0 << 26)
+#define   DP_AUX_CH_CTL_TIME_OUT_600us	    (1 << 26)
+#define   DP_AUX_CH_CTL_TIME_OUT_800us	    (2 << 26)
+#define   DP_AUX_CH_CTL_TIME_OUT_1600us	    (3 << 26)
+#define   DP_AUX_CH_CTL_TIME_OUT_MASK	    (3 << 26)
+#define   DP_AUX_CH_CTL_RECEIVE_ERROR	    (1 << 25)
+#define   DP_AUX_CH_CTL_MESSAGE_SIZE_MASK    (0x1f << 20)
+#define   DP_AUX_CH_CTL_MESSAGE_SIZE_SHIFT   20
+#define   DP_AUX_CH_CTL_PRECHARGE_2US_MASK   (0xf << 16)
+#define   DP_AUX_CH_CTL_PRECHARGE_2US_SHIFT  16
+#define   DP_AUX_CH_CTL_AUX_AKSV_SELECT	    (1 << 15)
+#define   DP_AUX_CH_CTL_MANCHESTER_TEST	    (1 << 14)
+#define   DP_AUX_CH_CTL_SYNC_TEST	    (1 << 13)
+#define   DP_AUX_CH_CTL_DEGLITCH_TEST	    (1 << 12)
+#define   DP_AUX_CH_CTL_PRECHARGE_TEST	    (1 << 11)
+#define   DP_AUX_CH_CTL_BIT_CLOCK_2X_MASK    (0x7ff)
+#define   DP_AUX_CH_CTL_BIT_CLOCK_2X_SHIFT   0
+#define   DP_AUX_CH_CTL_PSR_DATA_AUX_REG_SKL	(1 << 14)
+#define   DP_AUX_CH_CTL_FS_DATA_AUX_REG_SKL	(1 << 13)
+#define   DP_AUX_CH_CTL_GTC_DATA_AUX_REG_SKL	(1 << 12)
+#define   DP_AUX_CH_CTL_FW_SYNC_PULSE_SKL_MASK (0x1f << 5)
+#define   DP_AUX_CH_CTL_FW_SYNC_PULSE_SKL(c) (((c) - 1) << 5)
+#define   DP_AUX_CH_CTL_SYNC_PULSE_SKL(c)   ((c) - 1)
+
+/*
+ * Computing GMCH M and N values for the Display Port link
+ *
+ * GMCH M/N = dot clock * bytes per pixel / ls_clk * # of lanes
+ *
+ * ls_clk (we assume) is the DP link clock (1.62 or 2.7 GHz)
+ *
+ * The GMCH value is used internally
+ *
+ * bytes_per_pixel is the number of bytes coming out of the plane,
+ * which is after the LUTs, so we want the bytes for our color format.
+ * For our current usage, this is always 3, one byte for R, G and B.
+ */
+#define _PIPEA_DATA_M_G4X	0x70050
+#define _PIPEB_DATA_M_G4X	0x71050
+
+/* Transfer unit size for display port - 1, default is 0x3f (for TU size 64) */
+#define  TU_SIZE(x)             (((x)-1) << 25) /* default size 64 */
+#define  TU_SIZE_SHIFT		25
+#define  TU_SIZE_MASK           (0x3f << 25)
+
+#define  DATA_LINK_M_N_MASK	(0xffffff)
+#define  DATA_LINK_N_MAX	(0x800000)
+
+#define _PIPEA_DATA_N_G4X	0x70054
+#define _PIPEB_DATA_N_G4X	0x71054
+#define   PIPE_GMCH_DATA_N_MASK			(0xffffff)
+
+/*
+ * Computing Link M and N values for the Display Port link
+ *
+ * Link M / N = pixel_clock / ls_clk
+ *
+ * (the DP spec calls pixel_clock the 'strm_clk')
+ *
+ * The Link value is transmitted in the Main Stream
+ * Attributes and VB-ID.
+ */
+
+#define _PIPEA_LINK_M_G4X	0x70060
+#define _PIPEB_LINK_M_G4X	0x71060
+#define   PIPEA_DP_LINK_M_MASK			(0xffffff)
+
+#define _PIPEA_LINK_N_G4X	0x70064
+#define _PIPEB_LINK_N_G4X	0x71064
+#define   PIPEA_DP_LINK_N_MASK			(0xffffff)
+
+#define PIPE_DATA_M_G4X(pipe) _MMIO_PIPE(pipe, _PIPEA_DATA_M_G4X, _PIPEB_DATA_M_G4X)
+#define PIPE_DATA_N_G4X(pipe) _MMIO_PIPE(pipe, _PIPEA_DATA_N_G4X, _PIPEB_DATA_N_G4X)
+#define PIPE_LINK_M_G4X(pipe) _MMIO_PIPE(pipe, _PIPEA_LINK_M_G4X, _PIPEB_LINK_M_G4X)
+#define PIPE_LINK_N_G4X(pipe) _MMIO_PIPE(pipe, _PIPEA_LINK_N_G4X, _PIPEB_LINK_N_G4X)
+
+/* Display & cursor control */
+
+/* Pipe A */
+#define _PIPEADSL		0x70000
+#define   DSL_LINEMASK_GEN2	0x00000fff
+#define   DSL_LINEMASK_GEN3	0x00001fff
+#define _PIPEACONF		0x70008
+#define   PIPECONF_ENABLE	(1<<31)
+#define   PIPECONF_DISABLE	0
+#define   PIPECONF_DOUBLE_WIDE	(1<<30)
+#define   I965_PIPECONF_ACTIVE	(1<<30)
+#define   PIPECONF_DSI_PLL_LOCKED	(1<<29) /* vlv & pipe A only */
+#define   PIPECONF_FRAME_START_DELAY_MASK (3<<27)
+#define   PIPECONF_SINGLE_WIDE	0
+#define   PIPECONF_PIPE_UNLOCKED 0
+#define   PIPECONF_PIPE_LOCKED	(1<<25)
+#define   PIPECONF_PALETTE	0
+#define   PIPECONF_GAMMA		(1<<24)
+#define   PIPECONF_FORCE_BORDER	(1<<25)
+#define   PIPECONF_INTERLACE_MASK	(7 << 21)
+#define   PIPECONF_INTERLACE_MASK_HSW	(3 << 21)
+/* Note that pre-gen3 does not support interlaced display directly. Panel
+ * fitting must be disabled on pre-ilk for interlaced. */
+#define   PIPECONF_PROGRESSIVE			(0 << 21)
+#define   PIPECONF_INTERLACE_W_SYNC_SHIFT_PANEL	(4 << 21) /* gen4 only */
+#define   PIPECONF_INTERLACE_W_SYNC_SHIFT	(5 << 21) /* gen4 only */
+#define   PIPECONF_INTERLACE_W_FIELD_INDICATION	(6 << 21)
+#define   PIPECONF_INTERLACE_FIELD_0_ONLY	(7 << 21) /* gen3 only */
+/* Ironlake and later have a complete new set of values for interlaced. PFIT
+ * means panel fitter required, PF means progressive fetch, DBL means power
+ * saving pixel doubling. */
+#define   PIPECONF_PFIT_PF_INTERLACED_ILK	(1 << 21)
+#define   PIPECONF_INTERLACED_ILK		(3 << 21)
+#define   PIPECONF_INTERLACED_DBL_ILK		(4 << 21) /* ilk/snb only */
+#define   PIPECONF_PFIT_PF_INTERLACED_DBL_ILK	(5 << 21) /* ilk/snb only */
+#define   PIPECONF_INTERLACE_MODE_MASK		(7 << 21)
+#define   PIPECONF_EDP_RR_MODE_SWITCH		(1 << 20)
+#define   PIPECONF_CXSR_DOWNCLOCK	(1<<16)
+#define   PIPECONF_EDP_RR_MODE_SWITCH_VLV	(1 << 14)
+#define   PIPECONF_COLOR_RANGE_SELECT	(1 << 13)
+#define   PIPECONF_BPC_MASK	(0x7 << 5)
+#define   PIPECONF_8BPC		(0<<5)
+#define   PIPECONF_10BPC	(1<<5)
+#define   PIPECONF_6BPC		(2<<5)
+#define   PIPECONF_12BPC	(3<<5)
+#define   PIPECONF_DITHER_EN	(1<<4)
+#define   PIPECONF_DITHER_TYPE_MASK (0x0000000c)
+#define   PIPECONF_DITHER_TYPE_SP (0<<2)
+#define   PIPECONF_DITHER_TYPE_ST1 (1<<2)
+#define   PIPECONF_DITHER_TYPE_ST2 (2<<2)
+#define   PIPECONF_DITHER_TYPE_TEMP (3<<2)
+#define _PIPEASTAT		0x70024
+#define   PIPE_FIFO_UNDERRUN_STATUS		(1UL<<31)
+#define   SPRITE1_FLIP_DONE_INT_EN_VLV		(1UL<<30)
+#define   PIPE_CRC_ERROR_ENABLE			(1UL<<29)
+#define   PIPE_CRC_DONE_ENABLE			(1UL<<28)
+#define   PERF_COUNTER2_INTERRUPT_EN		(1UL<<27)
+#define   PIPE_GMBUS_EVENT_ENABLE		(1UL<<27)
+#define   PLANE_FLIP_DONE_INT_EN_VLV		(1UL<<26)
+#define   PIPE_HOTPLUG_INTERRUPT_ENABLE		(1UL<<26)
+#define   PIPE_VSYNC_INTERRUPT_ENABLE		(1UL<<25)
+#define   PIPE_DISPLAY_LINE_COMPARE_ENABLE	(1UL<<24)
+#define   PIPE_DPST_EVENT_ENABLE		(1UL<<23)
+#define   SPRITE0_FLIP_DONE_INT_EN_VLV		(1UL<<22)
+#define   PIPE_LEGACY_BLC_EVENT_ENABLE		(1UL<<22)
+#define   PIPE_ODD_FIELD_INTERRUPT_ENABLE	(1UL<<21)
+#define   PIPE_EVEN_FIELD_INTERRUPT_ENABLE	(1UL<<20)
+#define   PIPE_B_PSR_INTERRUPT_ENABLE_VLV	(1UL<<19)
+#define   PERF_COUNTER_INTERRUPT_EN		(1UL<<19)
+#define   PIPE_HOTPLUG_TV_INTERRUPT_ENABLE	(1UL<<18) /* pre-965 */
+#define   PIPE_START_VBLANK_INTERRUPT_ENABLE	(1UL<<18) /* 965 or later */
+#define   PIPE_FRAMESTART_INTERRUPT_ENABLE	(1UL<<17)
+#define   PIPE_VBLANK_INTERRUPT_ENABLE		(1UL<<17)
+#define   PIPEA_HBLANK_INT_EN_VLV		(1UL<<16)
+#define   PIPE_OVERLAY_UPDATED_ENABLE		(1UL<<16)
+#define   SPRITE1_FLIP_DONE_INT_STATUS_VLV	(1UL<<15)
+#define   SPRITE0_FLIP_DONE_INT_STATUS_VLV	(1UL<<14)
+#define   PIPE_CRC_ERROR_INTERRUPT_STATUS	(1UL<<13)
+#define   PIPE_CRC_DONE_INTERRUPT_STATUS	(1UL<<12)
+#define   PERF_COUNTER2_INTERRUPT_STATUS	(1UL<<11)
+#define   PIPE_GMBUS_INTERRUPT_STATUS		(1UL<<11)
+#define   PLANE_FLIP_DONE_INT_STATUS_VLV	(1UL<<10)
+#define   PIPE_HOTPLUG_INTERRUPT_STATUS		(1UL<<10)
+#define   PIPE_VSYNC_INTERRUPT_STATUS		(1UL<<9)
+#define   PIPE_DISPLAY_LINE_COMPARE_STATUS	(1UL<<8)
+#define   PIPE_DPST_EVENT_STATUS		(1UL<<7)
+#define   PIPE_A_PSR_STATUS_VLV			(1UL<<6)
+#define   PIPE_LEGACY_BLC_EVENT_STATUS		(1UL<<6)
+#define   PIPE_ODD_FIELD_INTERRUPT_STATUS	(1UL<<5)
+#define   PIPE_EVEN_FIELD_INTERRUPT_STATUS	(1UL<<4)
+#define   PIPE_B_PSR_STATUS_VLV			(1UL<<3)
+#define   PERF_COUNTER_INTERRUPT_STATUS		(1UL<<3)
+#define   PIPE_HOTPLUG_TV_INTERRUPT_STATUS	(1UL<<2) /* pre-965 */
+#define   PIPE_START_VBLANK_INTERRUPT_STATUS	(1UL<<2) /* 965 or later */
+#define   PIPE_FRAMESTART_INTERRUPT_STATUS	(1UL<<1)
+#define   PIPE_VBLANK_INTERRUPT_STATUS		(1UL<<1)
+#define   PIPE_HBLANK_INT_STATUS		(1UL<<0)
+#define   PIPE_OVERLAY_UPDATED_STATUS		(1UL<<0)
+
+#define PIPESTAT_INT_ENABLE_MASK		0x7fff0000
+#define PIPESTAT_INT_STATUS_MASK		0x0000ffff
+
+#define PIPE_A_OFFSET		0x70000
+#define PIPE_B_OFFSET		0x71000
+#define PIPE_C_OFFSET		0x72000
+#define CHV_PIPE_C_OFFSET	0x74000
+/*
+ * There's actually no pipe EDP. Some pipe registers have
+ * simply shifted from the pipe to the transcoder, while
+ * keeping their original offset. Thus we need PIPE_EDP_OFFSET
+ * to access such registers in transcoder EDP.
+ */
+#define PIPE_EDP_OFFSET	0x7f000
+
+#define _MMIO_PIPE2(pipe, reg) _MMIO(dev_priv->info.pipe_offsets[pipe] - \
+	dev_priv->info.pipe_offsets[PIPE_A] + (reg) + \
+	dev_priv->info.display_mmio_offset)
+
+#define PIPECONF(pipe)		_MMIO_PIPE2(pipe, _PIPEACONF)
+#define PIPEDSL(pipe)		_MMIO_PIPE2(pipe, _PIPEADSL)
+#define PIPEFRAME(pipe)		_MMIO_PIPE2(pipe, _PIPEAFRAMEHIGH)
+#define PIPEFRAMEPIXEL(pipe)	_MMIO_PIPE2(pipe, _PIPEAFRAMEPIXEL)
+#define PIPESTAT(pipe)		_MMIO_PIPE2(pipe, _PIPEASTAT)
+
+#define _PIPE_MISC_A			0x70030
+#define _PIPE_MISC_B			0x71030
+#define   PIPEMISC_DITHER_BPC_MASK	(7<<5)
+#define   PIPEMISC_DITHER_8_BPC		(0<<5)
+#define   PIPEMISC_DITHER_10_BPC	(1<<5)
+#define   PIPEMISC_DITHER_6_BPC		(2<<5)
+#define   PIPEMISC_DITHER_12_BPC	(3<<5)
+#define   PIPEMISC_DITHER_ENABLE	(1<<4)
+#define   PIPEMISC_DITHER_TYPE_MASK	(3<<2)
+#define   PIPEMISC_DITHER_TYPE_SP	(0<<2)
+#define PIPEMISC(pipe)			_MMIO_PIPE2(pipe, _PIPE_MISC_A)
+
+#define VLV_DPFLIPSTAT				_MMIO(VLV_DISPLAY_BASE + 0x70028)
+#define   PIPEB_LINE_COMPARE_INT_EN		(1<<29)
+#define   PIPEB_HLINE_INT_EN			(1<<28)
+#define   PIPEB_VBLANK_INT_EN			(1<<27)
+#define   SPRITED_FLIP_DONE_INT_EN		(1<<26)
+#define   SPRITEC_FLIP_DONE_INT_EN		(1<<25)
+#define   PLANEB_FLIP_DONE_INT_EN		(1<<24)
+#define   PIPE_PSR_INT_EN			(1<<22)
+#define   PIPEA_LINE_COMPARE_INT_EN		(1<<21)
+#define   PIPEA_HLINE_INT_EN			(1<<20)
+#define   PIPEA_VBLANK_INT_EN			(1<<19)
+#define   SPRITEB_FLIP_DONE_INT_EN		(1<<18)
+#define   SPRITEA_FLIP_DONE_INT_EN		(1<<17)
+#define   PLANEA_FLIPDONE_INT_EN		(1<<16)
+#define   PIPEC_LINE_COMPARE_INT_EN		(1<<13)
+#define   PIPEC_HLINE_INT_EN			(1<<12)
+#define   PIPEC_VBLANK_INT_EN			(1<<11)
+#define   SPRITEF_FLIPDONE_INT_EN		(1<<10)
+#define   SPRITEE_FLIPDONE_INT_EN		(1<<9)
+#define   PLANEC_FLIPDONE_INT_EN		(1<<8)
+
+#define DPINVGTT				_MMIO(VLV_DISPLAY_BASE + 0x7002c) /* VLV/CHV only */
+#define   SPRITEF_INVALID_GTT_INT_EN		(1<<27)
+#define   SPRITEE_INVALID_GTT_INT_EN		(1<<26)
+#define   PLANEC_INVALID_GTT_INT_EN		(1<<25)
+#define   CURSORC_INVALID_GTT_INT_EN		(1<<24)
+#define   CURSORB_INVALID_GTT_INT_EN		(1<<23)
+#define   CURSORA_INVALID_GTT_INT_EN		(1<<22)
+#define   SPRITED_INVALID_GTT_INT_EN		(1<<21)
+#define   SPRITEC_INVALID_GTT_INT_EN		(1<<20)
+#define   PLANEB_INVALID_GTT_INT_EN		(1<<19)
+#define   SPRITEB_INVALID_GTT_INT_EN		(1<<18)
+#define   SPRITEA_INVALID_GTT_INT_EN		(1<<17)
+#define   PLANEA_INVALID_GTT_INT_EN		(1<<16)
+#define   DPINVGTT_EN_MASK			0xff0000
+#define   DPINVGTT_EN_MASK_CHV			0xfff0000
+#define   SPRITEF_INVALID_GTT_STATUS		(1<<11)
+#define   SPRITEE_INVALID_GTT_STATUS		(1<<10)
+#define   PLANEC_INVALID_GTT_STATUS		(1<<9)
+#define   CURSORC_INVALID_GTT_STATUS		(1<<8)
+#define   CURSORB_INVALID_GTT_STATUS		(1<<7)
+#define   CURSORA_INVALID_GTT_STATUS		(1<<6)
+#define   SPRITED_INVALID_GTT_STATUS		(1<<5)
+#define   SPRITEC_INVALID_GTT_STATUS		(1<<4)
+#define   PLANEB_INVALID_GTT_STATUS		(1<<3)
+#define   SPRITEB_INVALID_GTT_STATUS		(1<<2)
+#define   SPRITEA_INVALID_GTT_STATUS		(1<<1)
+#define   PLANEA_INVALID_GTT_STATUS		(1<<0)
+#define   DPINVGTT_STATUS_MASK			0xff
+#define   DPINVGTT_STATUS_MASK_CHV		0xfff
+
+#define DSPARB			_MMIO(dev_priv->info.display_mmio_offset + 0x70030)
+#define   DSPARB_CSTART_MASK	(0x7f << 7)
+#define   DSPARB_CSTART_SHIFT	7
+#define   DSPARB_BSTART_MASK	(0x7f)
+#define   DSPARB_BSTART_SHIFT	0
+#define   DSPARB_BEND_SHIFT	9 /* on 855 */
+#define   DSPARB_AEND_SHIFT	0
+#define   DSPARB_SPRITEA_SHIFT_VLV	0
+#define   DSPARB_SPRITEA_MASK_VLV	(0xff << 0)
+#define   DSPARB_SPRITEB_SHIFT_VLV	8
+#define   DSPARB_SPRITEB_MASK_VLV	(0xff << 8)
+#define   DSPARB_SPRITEC_SHIFT_VLV	16
+#define   DSPARB_SPRITEC_MASK_VLV	(0xff << 16)
+#define   DSPARB_SPRITED_SHIFT_VLV	24
+#define   DSPARB_SPRITED_MASK_VLV	(0xff << 24)
+#define DSPARB2				_MMIO(VLV_DISPLAY_BASE + 0x70060) /* vlv/chv */
+#define   DSPARB_SPRITEA_HI_SHIFT_VLV	0
+#define   DSPARB_SPRITEA_HI_MASK_VLV	(0x1 << 0)
+#define   DSPARB_SPRITEB_HI_SHIFT_VLV	4
+#define   DSPARB_SPRITEB_HI_MASK_VLV	(0x1 << 4)
+#define   DSPARB_SPRITEC_HI_SHIFT_VLV	8
+#define   DSPARB_SPRITEC_HI_MASK_VLV	(0x1 << 8)
+#define   DSPARB_SPRITED_HI_SHIFT_VLV	12
+#define   DSPARB_SPRITED_HI_MASK_VLV	(0x1 << 12)
+#define   DSPARB_SPRITEE_HI_SHIFT_VLV	16
+#define   DSPARB_SPRITEE_HI_MASK_VLV	(0x1 << 16)
+#define   DSPARB_SPRITEF_HI_SHIFT_VLV	20
+#define   DSPARB_SPRITEF_HI_MASK_VLV	(0x1 << 20)
+#define DSPARB3				_MMIO(VLV_DISPLAY_BASE + 0x7006c) /* chv */
+#define   DSPARB_SPRITEE_SHIFT_VLV	0
+#define   DSPARB_SPRITEE_MASK_VLV	(0xff << 0)
+#define   DSPARB_SPRITEF_SHIFT_VLV	8
+#define   DSPARB_SPRITEF_MASK_VLV	(0xff << 8)
+
+/* pnv/gen4/g4x/vlv/chv */
+#define DSPFW1		_MMIO(dev_priv->info.display_mmio_offset + 0x70034)
+#define   DSPFW_SR_SHIFT		23
+#define   DSPFW_SR_MASK			(0x1ff<<23)
+#define   DSPFW_CURSORB_SHIFT		16
+#define   DSPFW_CURSORB_MASK		(0x3f<<16)
+#define   DSPFW_PLANEB_SHIFT		8
+#define   DSPFW_PLANEB_MASK		(0x7f<<8)
+#define   DSPFW_PLANEB_MASK_VLV		(0xff<<8) /* vlv/chv */
+#define   DSPFW_PLANEA_SHIFT		0
+#define   DSPFW_PLANEA_MASK		(0x7f<<0)
+#define   DSPFW_PLANEA_MASK_VLV		(0xff<<0) /* vlv/chv */
+#define DSPFW2		_MMIO(dev_priv->info.display_mmio_offset + 0x70038)
+#define   DSPFW_FBC_SR_EN		(1<<31)	  /* g4x */
+#define   DSPFW_FBC_SR_SHIFT		28
+#define   DSPFW_FBC_SR_MASK		(0x7<<28) /* g4x */
+#define   DSPFW_FBC_HPLL_SR_SHIFT	24
+#define   DSPFW_FBC_HPLL_SR_MASK	(0xf<<24) /* g4x */
+#define   DSPFW_SPRITEB_SHIFT		(16)
+#define   DSPFW_SPRITEB_MASK		(0x7f<<16) /* g4x */
+#define   DSPFW_SPRITEB_MASK_VLV	(0xff<<16) /* vlv/chv */
+#define   DSPFW_CURSORA_SHIFT		8
+#define   DSPFW_CURSORA_MASK		(0x3f<<8)
+#define   DSPFW_PLANEC_OLD_SHIFT	0
+#define   DSPFW_PLANEC_OLD_MASK		(0x7f<<0) /* pre-gen4 sprite C */
+#define   DSPFW_SPRITEA_SHIFT		0
+#define   DSPFW_SPRITEA_MASK		(0x7f<<0) /* g4x */
+#define   DSPFW_SPRITEA_MASK_VLV	(0xff<<0) /* vlv/chv */
+#define DSPFW3		_MMIO(dev_priv->info.display_mmio_offset + 0x7003c)
+#define   DSPFW_HPLL_SR_EN		(1<<31)
+#define   PINEVIEW_SELF_REFRESH_EN	(1<<30)
+#define   DSPFW_CURSOR_SR_SHIFT		24
+#define   DSPFW_CURSOR_SR_MASK		(0x3f<<24)
+#define   DSPFW_HPLL_CURSOR_SHIFT	16
+#define   DSPFW_HPLL_CURSOR_MASK	(0x3f<<16)
+#define   DSPFW_HPLL_SR_SHIFT		0
+#define   DSPFW_HPLL_SR_MASK		(0x1ff<<0)
+
+/* vlv/chv */
+#define DSPFW4		_MMIO(VLV_DISPLAY_BASE + 0x70070)
+#define   DSPFW_SPRITEB_WM1_SHIFT	16
+#define   DSPFW_SPRITEB_WM1_MASK	(0xff<<16)
+#define   DSPFW_CURSORA_WM1_SHIFT	8
+#define   DSPFW_CURSORA_WM1_MASK	(0x3f<<8)
+#define   DSPFW_SPRITEA_WM1_SHIFT	0
+#define   DSPFW_SPRITEA_WM1_MASK	(0xff<<0)
+#define DSPFW5		_MMIO(VLV_DISPLAY_BASE + 0x70074)
+#define   DSPFW_PLANEB_WM1_SHIFT	24
+#define   DSPFW_PLANEB_WM1_MASK		(0xff<<24)
+#define   DSPFW_PLANEA_WM1_SHIFT	16
+#define   DSPFW_PLANEA_WM1_MASK		(0xff<<16)
+#define   DSPFW_CURSORB_WM1_SHIFT	8
+#define   DSPFW_CURSORB_WM1_MASK	(0x3f<<8)
+#define   DSPFW_CURSOR_SR_WM1_SHIFT	0
+#define   DSPFW_CURSOR_SR_WM1_MASK	(0x3f<<0)
+#define DSPFW6		_MMIO(VLV_DISPLAY_BASE + 0x70078)
+#define   DSPFW_SR_WM1_SHIFT		0
+#define   DSPFW_SR_WM1_MASK		(0x1ff<<0)
+#define DSPFW7		_MMIO(VLV_DISPLAY_BASE + 0x7007c)
+#define DSPFW7_CHV	_MMIO(VLV_DISPLAY_BASE + 0x700b4) /* wtf #1? */
+#define   DSPFW_SPRITED_WM1_SHIFT	24
+#define   DSPFW_SPRITED_WM1_MASK	(0xff<<24)
+#define   DSPFW_SPRITED_SHIFT		16
+#define   DSPFW_SPRITED_MASK_VLV	(0xff<<16)
+#define   DSPFW_SPRITEC_WM1_SHIFT	8
+#define   DSPFW_SPRITEC_WM1_MASK	(0xff<<8)
+#define   DSPFW_SPRITEC_SHIFT		0
+#define   DSPFW_SPRITEC_MASK_VLV	(0xff<<0)
+#define DSPFW8_CHV	_MMIO(VLV_DISPLAY_BASE + 0x700b8)
+#define   DSPFW_SPRITEF_WM1_SHIFT	24
+#define   DSPFW_SPRITEF_WM1_MASK	(0xff<<24)
+#define   DSPFW_SPRITEF_SHIFT		16
+#define   DSPFW_SPRITEF_MASK_VLV	(0xff<<16)
+#define   DSPFW_SPRITEE_WM1_SHIFT	8
+#define   DSPFW_SPRITEE_WM1_MASK	(0xff<<8)
+#define   DSPFW_SPRITEE_SHIFT		0
+#define   DSPFW_SPRITEE_MASK_VLV	(0xff<<0)
+#define DSPFW9_CHV	_MMIO(VLV_DISPLAY_BASE + 0x7007c) /* wtf #2? */
+#define   DSPFW_PLANEC_WM1_SHIFT	24
+#define   DSPFW_PLANEC_WM1_MASK		(0xff<<24)
+#define   DSPFW_PLANEC_SHIFT		16
+#define   DSPFW_PLANEC_MASK_VLV		(0xff<<16)
+#define   DSPFW_CURSORC_WM1_SHIFT	8
+#define   DSPFW_CURSORC_WM1_MASK	(0x3f<<16)
+#define   DSPFW_CURSORC_SHIFT		0
+#define   DSPFW_CURSORC_MASK		(0x3f<<0)
+
+/* vlv/chv high order bits */
+#define DSPHOWM		_MMIO(VLV_DISPLAY_BASE + 0x70064)
+#define   DSPFW_SR_HI_SHIFT		24
+#define   DSPFW_SR_HI_MASK		(3<<24) /* 2 bits for chv, 1 for vlv */
+#define   DSPFW_SPRITEF_HI_SHIFT	23
+#define   DSPFW_SPRITEF_HI_MASK		(1<<23)
+#define   DSPFW_SPRITEE_HI_SHIFT	22
+#define   DSPFW_SPRITEE_HI_MASK		(1<<22)
+#define   DSPFW_PLANEC_HI_SHIFT		21
+#define   DSPFW_PLANEC_HI_MASK		(1<<21)
+#define   DSPFW_SPRITED_HI_SHIFT	20
+#define   DSPFW_SPRITED_HI_MASK		(1<<20)
+#define   DSPFW_SPRITEC_HI_SHIFT	16
+#define   DSPFW_SPRITEC_HI_MASK		(1<<16)
+#define   DSPFW_PLANEB_HI_SHIFT		12
+#define   DSPFW_PLANEB_HI_MASK		(1<<12)
+#define   DSPFW_SPRITEB_HI_SHIFT	8
+#define   DSPFW_SPRITEB_HI_MASK		(1<<8)
+#define   DSPFW_SPRITEA_HI_SHIFT	4
+#define   DSPFW_SPRITEA_HI_MASK		(1<<4)
+#define   DSPFW_PLANEA_HI_SHIFT		0
+#define   DSPFW_PLANEA_HI_MASK		(1<<0)
+#define DSPHOWM1	_MMIO(VLV_DISPLAY_BASE + 0x70068)
+#define   DSPFW_SR_WM1_HI_SHIFT		24
+#define   DSPFW_SR_WM1_HI_MASK		(3<<24) /* 2 bits for chv, 1 for vlv */
+#define   DSPFW_SPRITEF_WM1_HI_SHIFT	23
+#define   DSPFW_SPRITEF_WM1_HI_MASK	(1<<23)
+#define   DSPFW_SPRITEE_WM1_HI_SHIFT	22
+#define   DSPFW_SPRITEE_WM1_HI_MASK	(1<<22)
+#define   DSPFW_PLANEC_WM1_HI_SHIFT	21
+#define   DSPFW_PLANEC_WM1_HI_MASK	(1<<21)
+#define   DSPFW_SPRITED_WM1_HI_SHIFT	20
+#define   DSPFW_SPRITED_WM1_HI_MASK	(1<<20)
+#define   DSPFW_SPRITEC_WM1_HI_SHIFT	16
+#define   DSPFW_SPRITEC_WM1_HI_MASK	(1<<16)
+#define   DSPFW_PLANEB_WM1_HI_SHIFT	12
+#define   DSPFW_PLANEB_WM1_HI_MASK	(1<<12)
+#define   DSPFW_SPRITEB_WM1_HI_SHIFT	8
+#define   DSPFW_SPRITEB_WM1_HI_MASK	(1<<8)
+#define   DSPFW_SPRITEA_WM1_HI_SHIFT	4
+#define   DSPFW_SPRITEA_WM1_HI_MASK	(1<<4)
+#define   DSPFW_PLANEA_WM1_HI_SHIFT	0
+#define   DSPFW_PLANEA_WM1_HI_MASK	(1<<0)
+
+/* drain latency register values*/
+#define VLV_DDL(pipe)			_MMIO(VLV_DISPLAY_BASE + 0x70050 + 4 * (pipe))
+#define DDL_CURSOR_SHIFT		24
+#define DDL_SPRITE_SHIFT(sprite)	(8+8*(sprite))
+#define DDL_PLANE_SHIFT			0
+#define DDL_PRECISION_HIGH		(1<<7)
+#define DDL_PRECISION_LOW		(0<<7)
+#define DRAIN_LATENCY_MASK		0x7f
+
+#define CBR1_VLV			_MMIO(VLV_DISPLAY_BASE + 0x70400)
+#define  CBR_PND_DEADLINE_DISABLE	(1<<31)
+#define  CBR_PWM_CLOCK_MUX_SELECT	(1<<30)
+
+#define CBR4_VLV			_MMIO(VLV_DISPLAY_BASE + 0x70450)
+#define  CBR_DPLLBMD_PIPE_C		(1<<29)
+#define  CBR_DPLLBMD_PIPE_B		(1<<18)
+
+/* FIFO watermark sizes etc */
+#define G4X_FIFO_LINE_SIZE	64
+#define I915_FIFO_LINE_SIZE	64
+#define I830_FIFO_LINE_SIZE	32
+
+#define VALLEYVIEW_FIFO_SIZE	255
+#define G4X_FIFO_SIZE		127
+#define I965_FIFO_SIZE		512
+#define I945_FIFO_SIZE		127
+#define I915_FIFO_SIZE		95
+#define I855GM_FIFO_SIZE	127 /* In cachelines */
+#define I830_FIFO_SIZE		95
+
+#define VALLEYVIEW_MAX_WM	0xff
+#define G4X_MAX_WM		0x3f
+#define I915_MAX_WM		0x3f
+
+#define PINEVIEW_DISPLAY_FIFO	512 /* in 64byte unit */
+#define PINEVIEW_FIFO_LINE_SIZE	64
+#define PINEVIEW_MAX_WM		0x1ff
+#define PINEVIEW_DFT_WM		0x3f
+#define PINEVIEW_DFT_HPLLOFF_WM	0
+#define PINEVIEW_GUARD_WM		10
+#define PINEVIEW_CURSOR_FIFO		64
+#define PINEVIEW_CURSOR_MAX_WM	0x3f
+#define PINEVIEW_CURSOR_DFT_WM	0
+#define PINEVIEW_CURSOR_GUARD_WM	5
+
+#define VALLEYVIEW_CURSOR_MAX_WM 64
+#define I965_CURSOR_FIFO	64
+#define I965_CURSOR_MAX_WM	32
+#define I965_CURSOR_DFT_WM	8
+
+/* Watermark register definitions for SKL */
+#define _CUR_WM_A_0		0x70140
+#define _CUR_WM_B_0		0x71140
+#define _PLANE_WM_1_A_0		0x70240
+#define _PLANE_WM_1_B_0		0x71240
+#define _PLANE_WM_2_A_0		0x70340
+#define _PLANE_WM_2_B_0		0x71340
+#define _PLANE_WM_TRANS_1_A_0	0x70268
+#define _PLANE_WM_TRANS_1_B_0	0x71268
+#define _PLANE_WM_TRANS_2_A_0	0x70368
+#define _PLANE_WM_TRANS_2_B_0	0x71368
+#define _CUR_WM_TRANS_A_0	0x70168
+#define _CUR_WM_TRANS_B_0	0x71168
+#define   PLANE_WM_EN		(1 << 31)
+#define   PLANE_WM_LINES_SHIFT	14
+#define   PLANE_WM_LINES_MASK	0x1f
+#define   PLANE_WM_BLOCKS_MASK	0x3ff
+
+#define _CUR_WM_0(pipe) _PIPE(pipe, _CUR_WM_A_0, _CUR_WM_B_0)
+#define CUR_WM(pipe, level) _MMIO(_CUR_WM_0(pipe) + ((4) * (level)))
+#define CUR_WM_TRANS(pipe) _MMIO_PIPE(pipe, _CUR_WM_TRANS_A_0, _CUR_WM_TRANS_B_0)
+
+#define _PLANE_WM_1(pipe) _PIPE(pipe, _PLANE_WM_1_A_0, _PLANE_WM_1_B_0)
+#define _PLANE_WM_2(pipe) _PIPE(pipe, _PLANE_WM_2_A_0, _PLANE_WM_2_B_0)
+#define _PLANE_WM_BASE(pipe, plane)	\
+			_PLANE(plane, _PLANE_WM_1(pipe), _PLANE_WM_2(pipe))
+#define PLANE_WM(pipe, plane, level)	\
+			_MMIO(_PLANE_WM_BASE(pipe, plane) + ((4) * (level)))
+#define _PLANE_WM_TRANS_1(pipe)	\
+			_PIPE(pipe, _PLANE_WM_TRANS_1_A_0, _PLANE_WM_TRANS_1_B_0)
+#define _PLANE_WM_TRANS_2(pipe)	\
+			_PIPE(pipe, _PLANE_WM_TRANS_2_A_0, _PLANE_WM_TRANS_2_B_0)
+#define PLANE_WM_TRANS(pipe, plane)	\
+	_MMIO(_PLANE(plane, _PLANE_WM_TRANS_1(pipe), _PLANE_WM_TRANS_2(pipe)))
+
+/* define the Watermark register on Ironlake */
+#define WM0_PIPEA_ILK		_MMIO(0x45100)
+#define  WM0_PIPE_PLANE_MASK	(0xffff<<16)
+#define  WM0_PIPE_PLANE_SHIFT	16
+#define  WM0_PIPE_SPRITE_MASK	(0xff<<8)
+#define  WM0_PIPE_SPRITE_SHIFT	8
+#define  WM0_PIPE_CURSOR_MASK	(0xff)
+
+#define WM0_PIPEB_ILK		_MMIO(0x45104)
+#define WM0_PIPEC_IVB		_MMIO(0x45200)
+#define WM1_LP_ILK		_MMIO(0x45108)
+#define  WM1_LP_SR_EN		(1<<31)
+#define  WM1_LP_LATENCY_SHIFT	24
+#define  WM1_LP_LATENCY_MASK	(0x7f<<24)
+#define  WM1_LP_FBC_MASK	(0xf<<20)
+#define  WM1_LP_FBC_SHIFT	20
+#define  WM1_LP_FBC_SHIFT_BDW	19
+#define  WM1_LP_SR_MASK		(0x7ff<<8)
+#define  WM1_LP_SR_SHIFT	8
+#define  WM1_LP_CURSOR_MASK	(0xff)
+#define WM2_LP_ILK		_MMIO(0x4510c)
+#define  WM2_LP_EN		(1<<31)
+#define WM3_LP_ILK		_MMIO(0x45110)
+#define  WM3_LP_EN		(1<<31)
+#define WM1S_LP_ILK		_MMIO(0x45120)
+#define WM2S_LP_IVB		_MMIO(0x45124)
+#define WM3S_LP_IVB		_MMIO(0x45128)
+#define  WM1S_LP_EN		(1<<31)
+
+#define HSW_WM_LP_VAL(lat, fbc, pri, cur) \
+	(WM3_LP_EN | ((lat) << WM1_LP_LATENCY_SHIFT) | \
+	 ((fbc) << WM1_LP_FBC_SHIFT) | ((pri) << WM1_LP_SR_SHIFT) | (cur))
+
+/* Memory latency timer register */
+#define MLTR_ILK		_MMIO(0x11222)
+#define  MLTR_WM1_SHIFT		0
+#define  MLTR_WM2_SHIFT		8
+/* the unit of memory self-refresh latency time is 0.5us */
+#define  ILK_SRLT_MASK		0x3f
+
+
+/* the address where we get all kinds of latency value */
+#define SSKPD			_MMIO(0x5d10)
+#define SSKPD_WM_MASK		0x3f
+#define SSKPD_WM0_SHIFT		0
+#define SSKPD_WM1_SHIFT		8
+#define SSKPD_WM2_SHIFT		16
+#define SSKPD_WM3_SHIFT		24
+
+/*
+ * The two pipe frame counter registers are not synchronized, so
+ * reading a stable value is somewhat tricky. The following code
+ * should work:
+ *
+ *  do {
+ *    high1 = ((INREG(PIPEAFRAMEHIGH) & PIPE_FRAME_HIGH_MASK) >>
+ *             PIPE_FRAME_HIGH_SHIFT;
+ *    low1 =  ((INREG(PIPEAFRAMEPIXEL) & PIPE_FRAME_LOW_MASK) >>
+ *             PIPE_FRAME_LOW_SHIFT);
+ *    high2 = ((INREG(PIPEAFRAMEHIGH) & PIPE_FRAME_HIGH_MASK) >>
+ *             PIPE_FRAME_HIGH_SHIFT);
+ *  } while (high1 != high2);
+ *  frame = (high1 << 8) | low1;
+ */
+#define _PIPEAFRAMEHIGH          0x70040
+#define   PIPE_FRAME_HIGH_MASK    0x0000ffff
+#define   PIPE_FRAME_HIGH_SHIFT   0
+#define _PIPEAFRAMEPIXEL         0x70044
+#define   PIPE_FRAME_LOW_MASK     0xff000000
+#define   PIPE_FRAME_LOW_SHIFT    24
+#define   PIPE_PIXEL_MASK         0x00ffffff
+#define   PIPE_PIXEL_SHIFT        0
+/* GM45+ just has to be different */
+#define _PIPEA_FRMCOUNT_G4X	0x70040
+#define _PIPEA_FLIPCOUNT_G4X	0x70044
+#define PIPE_FRMCOUNT_G4X(pipe) _MMIO_PIPE2(pipe, _PIPEA_FRMCOUNT_G4X)
+#define PIPE_FLIPCOUNT_G4X(pipe) _MMIO_PIPE2(pipe, _PIPEA_FLIPCOUNT_G4X)
+
+/* Cursor A & B regs */
+#define _CURACNTR		0x70080
+/* Old style CUR*CNTR flags (desktop 8xx) */
+#define   CURSOR_ENABLE		0x80000000
+#define   CURSOR_GAMMA_ENABLE	0x40000000
+#define   CURSOR_STRIDE_SHIFT	28
+#define   CURSOR_STRIDE(x)	((ffs(x)-9) << CURSOR_STRIDE_SHIFT) /* 256,512,1k,2k */
+#define   CURSOR_PIPE_CSC_ENABLE (1<<24)
+#define   CURSOR_FORMAT_SHIFT	24
+#define   CURSOR_FORMAT_MASK	(0x07 << CURSOR_FORMAT_SHIFT)
+#define   CURSOR_FORMAT_2C	(0x00 << CURSOR_FORMAT_SHIFT)
+#define   CURSOR_FORMAT_3C	(0x01 << CURSOR_FORMAT_SHIFT)
+#define   CURSOR_FORMAT_4C	(0x02 << CURSOR_FORMAT_SHIFT)
+#define   CURSOR_FORMAT_ARGB	(0x04 << CURSOR_FORMAT_SHIFT)
+#define   CURSOR_FORMAT_XRGB	(0x05 << CURSOR_FORMAT_SHIFT)
+/* New style CUR*CNTR flags */
+#define   CURSOR_MODE		0x27
+#define   CURSOR_MODE_DISABLE   0x00
+#define   CURSOR_MODE_128_32B_AX 0x02
+#define   CURSOR_MODE_256_32B_AX 0x03
+#define   CURSOR_MODE_64_32B_AX 0x07
+#define   CURSOR_MODE_128_ARGB_AX ((1 << 5) | CURSOR_MODE_128_32B_AX)
+#define   CURSOR_MODE_256_ARGB_AX ((1 << 5) | CURSOR_MODE_256_32B_AX)
+#define   CURSOR_MODE_64_ARGB_AX ((1 << 5) | CURSOR_MODE_64_32B_AX)
+#define   MCURSOR_PIPE_SELECT	(1 << 28)
+#define   MCURSOR_PIPE_A	0x00
+#define   MCURSOR_PIPE_B	(1 << 28)
+#define   MCURSOR_GAMMA_ENABLE  (1 << 26)
+#define   CURSOR_ROTATE_180	(1<<15)
+#define   CURSOR_TRICKLE_FEED_DISABLE	(1 << 14)
+#define _CURABASE		0x70084
+#define _CURAPOS		0x70088
+#define   CURSOR_POS_MASK       0x007FF
+#define   CURSOR_POS_SIGN       0x8000
+#define   CURSOR_X_SHIFT        0
+#define   CURSOR_Y_SHIFT        16
+#define CURSIZE			_MMIO(0x700a0)
+#define _CURBCNTR		0x700c0
+#define _CURBBASE		0x700c4
+#define _CURBPOS		0x700c8
+
+#define _CURBCNTR_IVB		0x71080
+#define _CURBBASE_IVB		0x71084
+#define _CURBPOS_IVB		0x71088
+
+#define _CURSOR2(pipe, reg) _MMIO(dev_priv->info.cursor_offsets[(pipe)] - \
+	dev_priv->info.cursor_offsets[PIPE_A] + (reg) + \
+	dev_priv->info.display_mmio_offset)
+
+#define CURCNTR(pipe) _CURSOR2(pipe, _CURACNTR)
+#define CURBASE(pipe) _CURSOR2(pipe, _CURABASE)
+#define CURPOS(pipe) _CURSOR2(pipe, _CURAPOS)
+
+#define CURSOR_A_OFFSET 0x70080
+#define CURSOR_B_OFFSET 0x700c0
+#define CHV_CURSOR_C_OFFSET 0x700e0
+#define IVB_CURSOR_B_OFFSET 0x71080
+#define IVB_CURSOR_C_OFFSET 0x72080
+
+/* Display A control */
+#define _DSPACNTR				0x70180
+#define   DISPLAY_PLANE_ENABLE			(1<<31)
+#define   DISPLAY_PLANE_DISABLE			0
+#define   DISPPLANE_GAMMA_ENABLE		(1<<30)
+#define   DISPPLANE_GAMMA_DISABLE		0
+#define   DISPPLANE_PIXFORMAT_MASK		(0xf<<26)
+#define   DISPPLANE_YUV422			(0x0<<26)
+#define   DISPPLANE_8BPP			(0x2<<26)
+#define   DISPPLANE_BGRA555			(0x3<<26)
+#define   DISPPLANE_BGRX555			(0x4<<26)
+#define   DISPPLANE_BGRX565			(0x5<<26)
+#define   DISPPLANE_BGRX888			(0x6<<26)
+#define   DISPPLANE_BGRA888			(0x7<<26)
+#define   DISPPLANE_RGBX101010			(0x8<<26)
+#define   DISPPLANE_RGBA101010			(0x9<<26)
+#define   DISPPLANE_BGRX101010			(0xa<<26)
+#define   DISPPLANE_RGBX161616			(0xc<<26)
+#define   DISPPLANE_RGBX888			(0xe<<26)
+#define   DISPPLANE_RGBA888			(0xf<<26)
+#define   DISPPLANE_STEREO_ENABLE		(1<<25)
+#define   DISPPLANE_STEREO_DISABLE		0
+#define   DISPPLANE_PIPE_CSC_ENABLE		(1<<24)
+#define   DISPPLANE_SEL_PIPE_SHIFT		24
+#define   DISPPLANE_SEL_PIPE_MASK		(3<<DISPPLANE_SEL_PIPE_SHIFT)
+#define   DISPPLANE_SEL_PIPE_A			0
+#define   DISPPLANE_SEL_PIPE_B			(1<<DISPPLANE_SEL_PIPE_SHIFT)
+#define   DISPPLANE_SRC_KEY_ENABLE		(1<<22)
+#define   DISPPLANE_SRC_KEY_DISABLE		0
+#define   DISPPLANE_LINE_DOUBLE			(1<<20)
+#define   DISPPLANE_NO_LINE_DOUBLE		0
+#define   DISPPLANE_STEREO_POLARITY_FIRST	0
+#define   DISPPLANE_STEREO_POLARITY_SECOND	(1<<18)
+#define   DISPPLANE_ALPHA_PREMULTIPLY		(1<<16) /* CHV pipe B */
+#define   DISPPLANE_ROTATE_180			(1<<15)
+#define   DISPPLANE_TRICKLE_FEED_DISABLE	(1<<14) /* Ironlake */
+#define   DISPPLANE_TILED			(1<<10)
+#define   DISPPLANE_MIRROR			(1<<8) /* CHV pipe B */
+#define _DSPAADDR				0x70184
+#define _DSPASTRIDE				0x70188
+#define _DSPAPOS				0x7018C /* reserved */
+#define _DSPASIZE				0x70190
+#define _DSPASURF				0x7019C /* 965+ only */
+#define _DSPATILEOFF				0x701A4 /* 965+ only */
+#define _DSPAOFFSET				0x701A4 /* HSW */
+#define _DSPASURFLIVE				0x701AC
+
+#define DSPCNTR(plane)		_MMIO_PIPE2(plane, _DSPACNTR)
+#define DSPADDR(plane)		_MMIO_PIPE2(plane, _DSPAADDR)
+#define DSPSTRIDE(plane)	_MMIO_PIPE2(plane, _DSPASTRIDE)
+#define DSPPOS(plane)		_MMIO_PIPE2(plane, _DSPAPOS)
+#define DSPSIZE(plane)		_MMIO_PIPE2(plane, _DSPASIZE)
+#define DSPSURF(plane)		_MMIO_PIPE2(plane, _DSPASURF)
+#define DSPTILEOFF(plane)	_MMIO_PIPE2(plane, _DSPATILEOFF)
+#define DSPLINOFF(plane)	DSPADDR(plane)
+#define DSPOFFSET(plane)	_MMIO_PIPE2(plane, _DSPAOFFSET)
+#define DSPSURFLIVE(plane)	_MMIO_PIPE2(plane, _DSPASURFLIVE)
+
+/* CHV pipe B blender and primary plane */
+#define _CHV_BLEND_A		0x60a00
+#define   CHV_BLEND_LEGACY		(0<<30)
+#define   CHV_BLEND_ANDROID		(1<<30)
+#define   CHV_BLEND_MPO			(2<<30)
+#define   CHV_BLEND_MASK		(3<<30)
+#define _CHV_CANVAS_A		0x60a04
+#define _PRIMPOS_A		0x60a08
+#define _PRIMSIZE_A		0x60a0c
+#define _PRIMCNSTALPHA_A	0x60a10
+#define   PRIM_CONST_ALPHA_ENABLE	(1<<31)
+
+#define CHV_BLEND(pipe)		_MMIO_TRANS2(pipe, _CHV_BLEND_A)
+#define CHV_CANVAS(pipe)	_MMIO_TRANS2(pipe, _CHV_CANVAS_A)
+#define PRIMPOS(plane)		_MMIO_TRANS2(plane, _PRIMPOS_A)
+#define PRIMSIZE(plane)		_MMIO_TRANS2(plane, _PRIMSIZE_A)
+#define PRIMCNSTALPHA(plane)	_MMIO_TRANS2(plane, _PRIMCNSTALPHA_A)
+
+/* Display/Sprite base address macros */
+#define DISP_BASEADDR_MASK	(0xfffff000)
+#define I915_LO_DISPBASE(val)	(val & ~DISP_BASEADDR_MASK)
+#define I915_HI_DISPBASE(val)	(val & DISP_BASEADDR_MASK)
+
+/*
+ * VBIOS flags
+ * gen2:
+ * [00:06] alm,mgm
+ * [10:16] all
+ * [30:32] alm,mgm
+ * gen3+:
+ * [00:0f] all
+ * [10:1f] all
+ * [30:32] all
+ */
+#define SWF0(i)	_MMIO(dev_priv->info.display_mmio_offset + 0x70410 + (i) * 4)
+#define SWF1(i)	_MMIO(dev_priv->info.display_mmio_offset + 0x71410 + (i) * 4)
+#define SWF3(i)	_MMIO(dev_priv->info.display_mmio_offset + 0x72414 + (i) * 4)
+#define SWF_ILK(i)	_MMIO(0x4F000 + (i) * 4)
+
+/* Pipe B */
+#define _PIPEBDSL		(dev_priv->info.display_mmio_offset + 0x71000)
+#define _PIPEBCONF		(dev_priv->info.display_mmio_offset + 0x71008)
+#define _PIPEBSTAT		(dev_priv->info.display_mmio_offset + 0x71024)
+#define _PIPEBFRAMEHIGH		0x71040
+#define _PIPEBFRAMEPIXEL	0x71044
+#define _PIPEB_FRMCOUNT_G4X	(dev_priv->info.display_mmio_offset + 0x71040)
+#define _PIPEB_FLIPCOUNT_G4X	(dev_priv->info.display_mmio_offset + 0x71044)
+
+
+/* Display B control */
+#define _DSPBCNTR		(dev_priv->info.display_mmio_offset + 0x71180)
+#define   DISPPLANE_ALPHA_TRANS_ENABLE		(1<<15)
+#define   DISPPLANE_ALPHA_TRANS_DISABLE		0
+#define   DISPPLANE_SPRITE_ABOVE_DISPLAY	0
+#define   DISPPLANE_SPRITE_ABOVE_OVERLAY	(1)
+#define _DSPBADDR		(dev_priv->info.display_mmio_offset + 0x71184)
+#define _DSPBSTRIDE		(dev_priv->info.display_mmio_offset + 0x71188)
+#define _DSPBPOS		(dev_priv->info.display_mmio_offset + 0x7118C)
+#define _DSPBSIZE		(dev_priv->info.display_mmio_offset + 0x71190)
+#define _DSPBSURF		(dev_priv->info.display_mmio_offset + 0x7119C)
+#define _DSPBTILEOFF		(dev_priv->info.display_mmio_offset + 0x711A4)
+#define _DSPBOFFSET		(dev_priv->info.display_mmio_offset + 0x711A4)
+#define _DSPBSURFLIVE		(dev_priv->info.display_mmio_offset + 0x711AC)
+
+/* Sprite A control */
+#define _DVSACNTR		0x72180
+#define   DVS_ENABLE		(1<<31)
+#define   DVS_GAMMA_ENABLE	(1<<30)
+#define   DVS_PIXFORMAT_MASK	(3<<25)
+#define   DVS_FORMAT_YUV422	(0<<25)
+#define   DVS_FORMAT_RGBX101010	(1<<25)
+#define   DVS_FORMAT_RGBX888	(2<<25)
+#define   DVS_FORMAT_RGBX161616	(3<<25)
+#define   DVS_PIPE_CSC_ENABLE   (1<<24)
+#define   DVS_SOURCE_KEY	(1<<22)
+#define   DVS_RGB_ORDER_XBGR	(1<<20)
+#define   DVS_YUV_BYTE_ORDER_MASK (3<<16)
+#define   DVS_YUV_ORDER_YUYV	(0<<16)
+#define   DVS_YUV_ORDER_UYVY	(1<<16)
+#define   DVS_YUV_ORDER_YVYU	(2<<16)
+#define   DVS_YUV_ORDER_VYUY	(3<<16)
+#define   DVS_ROTATE_180	(1<<15)
+#define   DVS_DEST_KEY		(1<<2)
+#define   DVS_TRICKLE_FEED_DISABLE (1<<14)
+#define   DVS_TILED		(1<<10)
+#define _DVSALINOFF		0x72184
+#define _DVSASTRIDE		0x72188
+#define _DVSAPOS		0x7218c
+#define _DVSASIZE		0x72190
+#define _DVSAKEYVAL		0x72194
+#define _DVSAKEYMSK		0x72198
+#define _DVSASURF		0x7219c
+#define _DVSAKEYMAXVAL		0x721a0
+#define _DVSATILEOFF		0x721a4
+#define _DVSASURFLIVE		0x721ac
+#define _DVSASCALE		0x72204
+#define   DVS_SCALE_ENABLE	(1<<31)
+#define   DVS_FILTER_MASK	(3<<29)
+#define   DVS_FILTER_MEDIUM	(0<<29)
+#define   DVS_FILTER_ENHANCING	(1<<29)
+#define   DVS_FILTER_SOFTENING	(2<<29)
+#define   DVS_VERTICAL_OFFSET_HALF (1<<28) /* must be enabled below */
+#define   DVS_VERTICAL_OFFSET_ENABLE (1<<27)
+#define _DVSAGAMC		0x72300
+
+#define _DVSBCNTR		0x73180
+#define _DVSBLINOFF		0x73184
+#define _DVSBSTRIDE		0x73188
+#define _DVSBPOS		0x7318c
+#define _DVSBSIZE		0x73190
+#define _DVSBKEYVAL		0x73194
+#define _DVSBKEYMSK		0x73198
+#define _DVSBSURF		0x7319c
+#define _DVSBKEYMAXVAL		0x731a0
+#define _DVSBTILEOFF		0x731a4
+#define _DVSBSURFLIVE		0x731ac
+#define _DVSBSCALE		0x73204
+#define _DVSBGAMC		0x73300
+
+#define DVSCNTR(pipe) _MMIO_PIPE(pipe, _DVSACNTR, _DVSBCNTR)
+#define DVSLINOFF(pipe) _MMIO_PIPE(pipe, _DVSALINOFF, _DVSBLINOFF)
+#define DVSSTRIDE(pipe) _MMIO_PIPE(pipe, _DVSASTRIDE, _DVSBSTRIDE)
+#define DVSPOS(pipe) _MMIO_PIPE(pipe, _DVSAPOS, _DVSBPOS)
+#define DVSSURF(pipe) _MMIO_PIPE(pipe, _DVSASURF, _DVSBSURF)
+#define DVSKEYMAX(pipe) _MMIO_PIPE(pipe, _DVSAKEYMAXVAL, _DVSBKEYMAXVAL)
+#define DVSSIZE(pipe) _MMIO_PIPE(pipe, _DVSASIZE, _DVSBSIZE)
+#define DVSSCALE(pipe) _MMIO_PIPE(pipe, _DVSASCALE, _DVSBSCALE)
+#define DVSTILEOFF(pipe) _MMIO_PIPE(pipe, _DVSATILEOFF, _DVSBTILEOFF)
+#define DVSKEYVAL(pipe) _MMIO_PIPE(pipe, _DVSAKEYVAL, _DVSBKEYVAL)
+#define DVSKEYMSK(pipe) _MMIO_PIPE(pipe, _DVSAKEYMSK, _DVSBKEYMSK)
+#define DVSSURFLIVE(pipe) _MMIO_PIPE(pipe, _DVSASURFLIVE, _DVSBSURFLIVE)
+
+#define _SPRA_CTL		0x70280
+#define   SPRITE_ENABLE			(1<<31)
+#define   SPRITE_GAMMA_ENABLE		(1<<30)
+#define   SPRITE_PIXFORMAT_MASK		(7<<25)
+#define   SPRITE_FORMAT_YUV422		(0<<25)
+#define   SPRITE_FORMAT_RGBX101010	(1<<25)
+#define   SPRITE_FORMAT_RGBX888		(2<<25)
+#define   SPRITE_FORMAT_RGBX161616	(3<<25)
+#define   SPRITE_FORMAT_YUV444		(4<<25)
+#define   SPRITE_FORMAT_XR_BGR101010	(5<<25) /* Extended range */
+#define   SPRITE_PIPE_CSC_ENABLE	(1<<24)
+#define   SPRITE_SOURCE_KEY		(1<<22)
+#define   SPRITE_RGB_ORDER_RGBX		(1<<20) /* only for 888 and 161616 */
+#define   SPRITE_YUV_TO_RGB_CSC_DISABLE	(1<<19)
+#define   SPRITE_YUV_CSC_FORMAT_BT709	(1<<18) /* 0 is BT601 */
+#define   SPRITE_YUV_BYTE_ORDER_MASK	(3<<16)
+#define   SPRITE_YUV_ORDER_YUYV		(0<<16)
+#define   SPRITE_YUV_ORDER_UYVY		(1<<16)
+#define   SPRITE_YUV_ORDER_YVYU		(2<<16)
+#define   SPRITE_YUV_ORDER_VYUY		(3<<16)
+#define   SPRITE_ROTATE_180		(1<<15)
+#define   SPRITE_TRICKLE_FEED_DISABLE	(1<<14)
+#define   SPRITE_INT_GAMMA_ENABLE	(1<<13)
+#define   SPRITE_TILED			(1<<10)
+#define   SPRITE_DEST_KEY		(1<<2)
+#define _SPRA_LINOFF		0x70284
+#define _SPRA_STRIDE		0x70288
+#define _SPRA_POS		0x7028c
+#define _SPRA_SIZE		0x70290
+#define _SPRA_KEYVAL		0x70294
+#define _SPRA_KEYMSK		0x70298
+#define _SPRA_SURF		0x7029c
+#define _SPRA_KEYMAX		0x702a0
+#define _SPRA_TILEOFF		0x702a4
+#define _SPRA_OFFSET		0x702a4
+#define _SPRA_SURFLIVE		0x702ac
+#define _SPRA_SCALE		0x70304
+#define   SPRITE_SCALE_ENABLE	(1<<31)
+#define   SPRITE_FILTER_MASK	(3<<29)
+#define   SPRITE_FILTER_MEDIUM	(0<<29)
+#define   SPRITE_FILTER_ENHANCING	(1<<29)
+#define   SPRITE_FILTER_SOFTENING	(2<<29)
+#define   SPRITE_VERTICAL_OFFSET_HALF	(1<<28) /* must be enabled below */
+#define   SPRITE_VERTICAL_OFFSET_ENABLE	(1<<27)
+#define _SPRA_GAMC		0x70400
+
+#define _SPRB_CTL		0x71280
+#define _SPRB_LINOFF		0x71284
+#define _SPRB_STRIDE		0x71288
+#define _SPRB_POS		0x7128c
+#define _SPRB_SIZE		0x71290
+#define _SPRB_KEYVAL		0x71294
+#define _SPRB_KEYMSK		0x71298
+#define _SPRB_SURF		0x7129c
+#define _SPRB_KEYMAX		0x712a0
+#define _SPRB_TILEOFF		0x712a4
+#define _SPRB_OFFSET		0x712a4
+#define _SPRB_SURFLIVE		0x712ac
+#define _SPRB_SCALE		0x71304
+#define _SPRB_GAMC		0x71400
+
+#define SPRCTL(pipe) _MMIO_PIPE(pipe, _SPRA_CTL, _SPRB_CTL)
+#define SPRLINOFF(pipe) _MMIO_PIPE(pipe, _SPRA_LINOFF, _SPRB_LINOFF)
+#define SPRSTRIDE(pipe) _MMIO_PIPE(pipe, _SPRA_STRIDE, _SPRB_STRIDE)
+#define SPRPOS(pipe) _MMIO_PIPE(pipe, _SPRA_POS, _SPRB_POS)
+#define SPRSIZE(pipe) _MMIO_PIPE(pipe, _SPRA_SIZE, _SPRB_SIZE)
+#define SPRKEYVAL(pipe) _MMIO_PIPE(pipe, _SPRA_KEYVAL, _SPRB_KEYVAL)
+#define SPRKEYMSK(pipe) _MMIO_PIPE(pipe, _SPRA_KEYMSK, _SPRB_KEYMSK)
+#define SPRSURF(pipe) _MMIO_PIPE(pipe, _SPRA_SURF, _SPRB_SURF)
+#define SPRKEYMAX(pipe) _MMIO_PIPE(pipe, _SPRA_KEYMAX, _SPRB_KEYMAX)
+#define SPRTILEOFF(pipe) _MMIO_PIPE(pipe, _SPRA_TILEOFF, _SPRB_TILEOFF)
+#define SPROFFSET(pipe) _MMIO_PIPE(pipe, _SPRA_OFFSET, _SPRB_OFFSET)
+#define SPRSCALE(pipe) _MMIO_PIPE(pipe, _SPRA_SCALE, _SPRB_SCALE)
+#define SPRGAMC(pipe) _MMIO_PIPE(pipe, _SPRA_GAMC, _SPRB_GAMC)
+#define SPRSURFLIVE(pipe) _MMIO_PIPE(pipe, _SPRA_SURFLIVE, _SPRB_SURFLIVE)
+
+#define _SPACNTR		(VLV_DISPLAY_BASE + 0x72180)
+#define   SP_ENABLE			(1<<31)
+#define   SP_GAMMA_ENABLE		(1<<30)
+#define   SP_PIXFORMAT_MASK		(0xf<<26)
+#define   SP_FORMAT_YUV422		(0<<26)
+#define   SP_FORMAT_BGR565		(5<<26)
+#define   SP_FORMAT_BGRX8888		(6<<26)
+#define   SP_FORMAT_BGRA8888		(7<<26)
+#define   SP_FORMAT_RGBX1010102		(8<<26)
+#define   SP_FORMAT_RGBA1010102		(9<<26)
+#define   SP_FORMAT_RGBX8888		(0xe<<26)
+#define   SP_FORMAT_RGBA8888		(0xf<<26)
+#define   SP_ALPHA_PREMULTIPLY		(1<<23) /* CHV pipe B */
+#define   SP_SOURCE_KEY			(1<<22)
+#define   SP_YUV_BYTE_ORDER_MASK	(3<<16)
+#define   SP_YUV_ORDER_YUYV		(0<<16)
+#define   SP_YUV_ORDER_UYVY		(1<<16)
+#define   SP_YUV_ORDER_YVYU		(2<<16)
+#define   SP_YUV_ORDER_VYUY		(3<<16)
+#define   SP_ROTATE_180			(1<<15)
+#define   SP_TILED			(1<<10)
+#define   SP_MIRROR			(1<<8) /* CHV pipe B */
+#define _SPALINOFF		(VLV_DISPLAY_BASE + 0x72184)
+#define _SPASTRIDE		(VLV_DISPLAY_BASE + 0x72188)
+#define _SPAPOS			(VLV_DISPLAY_BASE + 0x7218c)
+#define _SPASIZE		(VLV_DISPLAY_BASE + 0x72190)
+#define _SPAKEYMINVAL		(VLV_DISPLAY_BASE + 0x72194)
+#define _SPAKEYMSK		(VLV_DISPLAY_BASE + 0x72198)
+#define _SPASURF		(VLV_DISPLAY_BASE + 0x7219c)
+#define _SPAKEYMAXVAL		(VLV_DISPLAY_BASE + 0x721a0)
+#define _SPATILEOFF		(VLV_DISPLAY_BASE + 0x721a4)
+#define _SPACONSTALPHA		(VLV_DISPLAY_BASE + 0x721a8)
+#define   SP_CONST_ALPHA_ENABLE		(1<<31)
+#define _SPAGAMC		(VLV_DISPLAY_BASE + 0x721f4)
+
+#define _SPBCNTR		(VLV_DISPLAY_BASE + 0x72280)
+#define _SPBLINOFF		(VLV_DISPLAY_BASE + 0x72284)
+#define _SPBSTRIDE		(VLV_DISPLAY_BASE + 0x72288)
+#define _SPBPOS			(VLV_DISPLAY_BASE + 0x7228c)
+#define _SPBSIZE		(VLV_DISPLAY_BASE + 0x72290)
+#define _SPBKEYMINVAL		(VLV_DISPLAY_BASE + 0x72294)
+#define _SPBKEYMSK		(VLV_DISPLAY_BASE + 0x72298)
+#define _SPBSURF		(VLV_DISPLAY_BASE + 0x7229c)
+#define _SPBKEYMAXVAL		(VLV_DISPLAY_BASE + 0x722a0)
+#define _SPBTILEOFF		(VLV_DISPLAY_BASE + 0x722a4)
+#define _SPBCONSTALPHA		(VLV_DISPLAY_BASE + 0x722a8)
+#define _SPBGAMC		(VLV_DISPLAY_BASE + 0x722f4)
+
+#define SPCNTR(pipe, plane) _MMIO_PIPE((pipe) * 2 + (plane), _SPACNTR, _SPBCNTR)
+#define SPLINOFF(pipe, plane) _MMIO_PIPE((pipe) * 2 + (plane), _SPALINOFF, _SPBLINOFF)
+#define SPSTRIDE(pipe, plane) _MMIO_PIPE((pipe) * 2 + (plane), _SPASTRIDE, _SPBSTRIDE)
+#define SPPOS(pipe, plane) _MMIO_PIPE((pipe) * 2 + (plane), _SPAPOS, _SPBPOS)
+#define SPSIZE(pipe, plane) _MMIO_PIPE((pipe) * 2 + (plane), _SPASIZE, _SPBSIZE)
+#define SPKEYMINVAL(pipe, plane) _MMIO_PIPE((pipe) * 2 + (plane), _SPAKEYMINVAL, _SPBKEYMINVAL)
+#define SPKEYMSK(pipe, plane) _MMIO_PIPE((pipe) * 2 + (plane), _SPAKEYMSK, _SPBKEYMSK)
+#define SPSURF(pipe, plane) _MMIO_PIPE((pipe) * 2 + (plane), _SPASURF, _SPBSURF)
+#define SPKEYMAXVAL(pipe, plane) _MMIO_PIPE((pipe) * 2 + (plane), _SPAKEYMAXVAL, _SPBKEYMAXVAL)
+#define SPTILEOFF(pipe, plane) _MMIO_PIPE((pipe) * 2 + (plane), _SPATILEOFF, _SPBTILEOFF)
+#define SPCONSTALPHA(pipe, plane) _MMIO_PIPE((pipe) * 2 + (plane), _SPACONSTALPHA, _SPBCONSTALPHA)
+#define SPGAMC(pipe, plane) _MMIO_PIPE((pipe) * 2 + (plane), _SPAGAMC, _SPBGAMC)
+
+/*
+ * CHV pipe B sprite CSC
+ *
+ * |cr|   |c0 c1 c2|   |cr + cr_ioff|   |cr_ooff|
+ * |yg| = |c3 c4 c5| x |yg + yg_ioff| + |yg_ooff|
+ * |cb|   |c6 c7 c8|   |cb + cr_ioff|   |cb_ooff|
+ */
+#define SPCSCYGOFF(sprite)	_MMIO(VLV_DISPLAY_BASE + 0x6d900 + (sprite) * 0x1000)
+#define SPCSCCBOFF(sprite)	_MMIO(VLV_DISPLAY_BASE + 0x6d904 + (sprite) * 0x1000)
+#define SPCSCCROFF(sprite)	_MMIO(VLV_DISPLAY_BASE + 0x6d908 + (sprite) * 0x1000)
+#define  SPCSC_OOFF(x)		(((x) & 0x7ff) << 16) /* s11 */
+#define  SPCSC_IOFF(x)		(((x) & 0x7ff) << 0) /* s11 */
+
+#define SPCSCC01(sprite)	_MMIO(VLV_DISPLAY_BASE + 0x6d90c + (sprite) * 0x1000)
+#define SPCSCC23(sprite)	_MMIO(VLV_DISPLAY_BASE + 0x6d910 + (sprite) * 0x1000)
+#define SPCSCC45(sprite)	_MMIO(VLV_DISPLAY_BASE + 0x6d914 + (sprite) * 0x1000)
+#define SPCSCC67(sprite)	_MMIO(VLV_DISPLAY_BASE + 0x6d918 + (sprite) * 0x1000)
+#define SPCSCC8(sprite)		_MMIO(VLV_DISPLAY_BASE + 0x6d91c + (sprite) * 0x1000)
+#define  SPCSC_C1(x)		(((x) & 0x7fff) << 16) /* s3.12 */
+#define  SPCSC_C0(x)		(((x) & 0x7fff) << 0) /* s3.12 */
+
+#define SPCSCYGICLAMP(sprite)	_MMIO(VLV_DISPLAY_BASE + 0x6d920 + (sprite) * 0x1000)
+#define SPCSCCBICLAMP(sprite)	_MMIO(VLV_DISPLAY_BASE + 0x6d924 + (sprite) * 0x1000)
+#define SPCSCCRICLAMP(sprite)	_MMIO(VLV_DISPLAY_BASE + 0x6d928 + (sprite) * 0x1000)
+#define  SPCSC_IMAX(x)		(((x) & 0x7ff) << 16) /* s11 */
+#define  SPCSC_IMIN(x)		(((x) & 0x7ff) << 0) /* s11 */
+
+#define SPCSCYGOCLAMP(sprite)	_MMIO(VLV_DISPLAY_BASE + 0x6d92c + (sprite) * 0x1000)
+#define SPCSCCBOCLAMP(sprite)	_MMIO(VLV_DISPLAY_BASE + 0x6d930 + (sprite) * 0x1000)
+#define SPCSCCROCLAMP(sprite)	_MMIO(VLV_DISPLAY_BASE + 0x6d934 + (sprite) * 0x1000)
+#define  SPCSC_OMAX(x)		((x) << 16) /* u10 */
+#define  SPCSC_OMIN(x)		((x) << 0) /* u10 */
+
+/* Skylake plane registers */
+
+#define _PLANE_CTL_1_A				0x70180
+#define _PLANE_CTL_2_A				0x70280
+#define _PLANE_CTL_3_A				0x70380
+#define   PLANE_CTL_ENABLE			(1 << 31)
+#define   PLANE_CTL_PIPE_GAMMA_ENABLE		(1 << 30)
+#define   PLANE_CTL_FORMAT_MASK			(0xf << 24)
+#define   PLANE_CTL_FORMAT_YUV422		(  0 << 24)
+#define   PLANE_CTL_FORMAT_NV12			(  1 << 24)
+#define   PLANE_CTL_FORMAT_XRGB_2101010		(  2 << 24)
+#define   PLANE_CTL_FORMAT_XRGB_8888		(  4 << 24)
+#define   PLANE_CTL_FORMAT_XRGB_16161616F	(  6 << 24)
+#define   PLANE_CTL_FORMAT_AYUV			(  8 << 24)
+#define   PLANE_CTL_FORMAT_INDEXED		( 12 << 24)
+#define   PLANE_CTL_FORMAT_RGB_565		( 14 << 24)
+#define   PLANE_CTL_PIPE_CSC_ENABLE		(1 << 23)
+#define   PLANE_CTL_KEY_ENABLE_MASK		(0x3 << 21)
+#define   PLANE_CTL_KEY_ENABLE_SOURCE		(  1 << 21)
+#define   PLANE_CTL_KEY_ENABLE_DESTINATION	(  2 << 21)
+#define   PLANE_CTL_ORDER_BGRX			(0 << 20)
+#define   PLANE_CTL_ORDER_RGBX			(1 << 20)
+#define   PLANE_CTL_YUV422_ORDER_MASK		(0x3 << 16)
+#define   PLANE_CTL_YUV422_YUYV			(  0 << 16)
+#define   PLANE_CTL_YUV422_UYVY			(  1 << 16)
+#define   PLANE_CTL_YUV422_YVYU			(  2 << 16)
+#define   PLANE_CTL_YUV422_VYUY			(  3 << 16)
+#define   PLANE_CTL_DECOMPRESSION_ENABLE	(1 << 15)
+#define   PLANE_CTL_TRICKLE_FEED_DISABLE	(1 << 14)
+#define   PLANE_CTL_PLANE_GAMMA_DISABLE		(1 << 13)
+#define   PLANE_CTL_TILED_MASK			(0x7 << 10)
+#define   PLANE_CTL_TILED_LINEAR		(  0 << 10)
+#define   PLANE_CTL_TILED_X			(  1 << 10)
+#define   PLANE_CTL_TILED_Y			(  4 << 10)
+#define   PLANE_CTL_TILED_YF			(  5 << 10)
+#define   PLANE_CTL_ALPHA_MASK			(0x3 << 4)
+#define   PLANE_CTL_ALPHA_DISABLE		(  0 << 4)
+#define   PLANE_CTL_ALPHA_SW_PREMULTIPLY	(  2 << 4)
+#define   PLANE_CTL_ALPHA_HW_PREMULTIPLY	(  3 << 4)
+#define   PLANE_CTL_ROTATE_MASK			0x3
+#define   PLANE_CTL_ROTATE_0			0x0
+#define   PLANE_CTL_ROTATE_90			0x1
+#define   PLANE_CTL_ROTATE_180			0x2
+#define   PLANE_CTL_ROTATE_270			0x3
+#define _PLANE_STRIDE_1_A			0x70188
+#define _PLANE_STRIDE_2_A			0x70288
+#define _PLANE_STRIDE_3_A			0x70388
+#define _PLANE_POS_1_A				0x7018c
+#define _PLANE_POS_2_A				0x7028c
+#define _PLANE_POS_3_A				0x7038c
+#define _PLANE_SIZE_1_A				0x70190
+#define _PLANE_SIZE_2_A				0x70290
+#define _PLANE_SIZE_3_A				0x70390
+#define _PLANE_SURF_1_A				0x7019c
+#define _PLANE_SURF_2_A				0x7029c
+#define _PLANE_SURF_3_A				0x7039c
+#define _PLANE_OFFSET_1_A			0x701a4
+#define _PLANE_OFFSET_2_A			0x702a4
+#define _PLANE_OFFSET_3_A			0x703a4
+#define _PLANE_KEYVAL_1_A			0x70194
+#define _PLANE_KEYVAL_2_A			0x70294
+#define _PLANE_KEYMSK_1_A			0x70198
+#define _PLANE_KEYMSK_2_A			0x70298
+#define _PLANE_KEYMAX_1_A			0x701a0
+#define _PLANE_KEYMAX_2_A			0x702a0
+#define _PLANE_BUF_CFG_1_A			0x7027c
+#define _PLANE_BUF_CFG_2_A			0x7037c
+#define _PLANE_NV12_BUF_CFG_1_A		0x70278
+#define _PLANE_NV12_BUF_CFG_2_A		0x70378
+
+#define _PLANE_CTL_1_B				0x71180
+#define _PLANE_CTL_2_B				0x71280
+#define _PLANE_CTL_3_B				0x71380
+#define _PLANE_CTL_1(pipe)	_PIPE(pipe, _PLANE_CTL_1_A, _PLANE_CTL_1_B)
+#define _PLANE_CTL_2(pipe)	_PIPE(pipe, _PLANE_CTL_2_A, _PLANE_CTL_2_B)
+#define _PLANE_CTL_3(pipe)	_PIPE(pipe, _PLANE_CTL_3_A, _PLANE_CTL_3_B)
+#define PLANE_CTL(pipe, plane)	\
+	_MMIO_PLANE(plane, _PLANE_CTL_1(pipe), _PLANE_CTL_2(pipe))
+
+#define _PLANE_STRIDE_1_B			0x71188
+#define _PLANE_STRIDE_2_B			0x71288
+#define _PLANE_STRIDE_3_B			0x71388
+#define _PLANE_STRIDE_1(pipe)	\
+	_PIPE(pipe, _PLANE_STRIDE_1_A, _PLANE_STRIDE_1_B)
+#define _PLANE_STRIDE_2(pipe)	\
+	_PIPE(pipe, _PLANE_STRIDE_2_A, _PLANE_STRIDE_2_B)
+#define _PLANE_STRIDE_3(pipe)	\
+	_PIPE(pipe, _PLANE_STRIDE_3_A, _PLANE_STRIDE_3_B)
+#define PLANE_STRIDE(pipe, plane)	\
+	_MMIO_PLANE(plane, _PLANE_STRIDE_1(pipe), _PLANE_STRIDE_2(pipe))
+
+#define _PLANE_POS_1_B				0x7118c
+#define _PLANE_POS_2_B				0x7128c
+#define _PLANE_POS_3_B				0x7138c
+#define _PLANE_POS_1(pipe)	_PIPE(pipe, _PLANE_POS_1_A, _PLANE_POS_1_B)
+#define _PLANE_POS_2(pipe)	_PIPE(pipe, _PLANE_POS_2_A, _PLANE_POS_2_B)
+#define _PLANE_POS_3(pipe)	_PIPE(pipe, _PLANE_POS_3_A, _PLANE_POS_3_B)
+#define PLANE_POS(pipe, plane)	\
+	_MMIO_PLANE(plane, _PLANE_POS_1(pipe), _PLANE_POS_2(pipe))
+
+#define _PLANE_SIZE_1_B				0x71190
+#define _PLANE_SIZE_2_B				0x71290
+#define _PLANE_SIZE_3_B				0x71390
+#define _PLANE_SIZE_1(pipe)	_PIPE(pipe, _PLANE_SIZE_1_A, _PLANE_SIZE_1_B)
+#define _PLANE_SIZE_2(pipe)	_PIPE(pipe, _PLANE_SIZE_2_A, _PLANE_SIZE_2_B)
+#define _PLANE_SIZE_3(pipe)	_PIPE(pipe, _PLANE_SIZE_3_A, _PLANE_SIZE_3_B)
+#define PLANE_SIZE(pipe, plane)	\
+	_MMIO_PLANE(plane, _PLANE_SIZE_1(pipe), _PLANE_SIZE_2(pipe))
+
+#define _PLANE_SURF_1_B				0x7119c
+#define _PLANE_SURF_2_B				0x7129c
+#define _PLANE_SURF_3_B				0x7139c
+#define _PLANE_SURF_1(pipe)	_PIPE(pipe, _PLANE_SURF_1_A, _PLANE_SURF_1_B)
+#define _PLANE_SURF_2(pipe)	_PIPE(pipe, _PLANE_SURF_2_A, _PLANE_SURF_2_B)
+#define _PLANE_SURF_3(pipe)	_PIPE(pipe, _PLANE_SURF_3_A, _PLANE_SURF_3_B)
+#define PLANE_SURF(pipe, plane)	\
+	_MMIO_PLANE(plane, _PLANE_SURF_1(pipe), _PLANE_SURF_2(pipe))
+
+#define _PLANE_OFFSET_1_B			0x711a4
+#define _PLANE_OFFSET_2_B			0x712a4
+#define _PLANE_OFFSET_1(pipe) _PIPE(pipe, _PLANE_OFFSET_1_A, _PLANE_OFFSET_1_B)
+#define _PLANE_OFFSET_2(pipe) _PIPE(pipe, _PLANE_OFFSET_2_A, _PLANE_OFFSET_2_B)
+#define PLANE_OFFSET(pipe, plane)	\
+	_MMIO_PLANE(plane, _PLANE_OFFSET_1(pipe), _PLANE_OFFSET_2(pipe))
+
+#define _PLANE_KEYVAL_1_B			0x71194
+#define _PLANE_KEYVAL_2_B			0x71294
+#define _PLANE_KEYVAL_1(pipe) _PIPE(pipe, _PLANE_KEYVAL_1_A, _PLANE_KEYVAL_1_B)
+#define _PLANE_KEYVAL_2(pipe) _PIPE(pipe, _PLANE_KEYVAL_2_A, _PLANE_KEYVAL_2_B)
+#define PLANE_KEYVAL(pipe, plane)	\
+	_MMIO_PLANE(plane, _PLANE_KEYVAL_1(pipe), _PLANE_KEYVAL_2(pipe))
+
+#define _PLANE_KEYMSK_1_B			0x71198
+#define _PLANE_KEYMSK_2_B			0x71298
+#define _PLANE_KEYMSK_1(pipe) _PIPE(pipe, _PLANE_KEYMSK_1_A, _PLANE_KEYMSK_1_B)
+#define _PLANE_KEYMSK_2(pipe) _PIPE(pipe, _PLANE_KEYMSK_2_A, _PLANE_KEYMSK_2_B)
+#define PLANE_KEYMSK(pipe, plane)	\
+	_MMIO_PLANE(plane, _PLANE_KEYMSK_1(pipe), _PLANE_KEYMSK_2(pipe))
+
+#define _PLANE_KEYMAX_1_B			0x711a0
+#define _PLANE_KEYMAX_2_B			0x712a0
+#define _PLANE_KEYMAX_1(pipe) _PIPE(pipe, _PLANE_KEYMAX_1_A, _PLANE_KEYMAX_1_B)
+#define _PLANE_KEYMAX_2(pipe) _PIPE(pipe, _PLANE_KEYMAX_2_A, _PLANE_KEYMAX_2_B)
+#define PLANE_KEYMAX(pipe, plane)	\
+	_MMIO_PLANE(plane, _PLANE_KEYMAX_1(pipe), _PLANE_KEYMAX_2(pipe))
+
+#define _PLANE_BUF_CFG_1_B			0x7127c
+#define _PLANE_BUF_CFG_2_B			0x7137c
+#define _PLANE_BUF_CFG_1(pipe)	\
+	_PIPE(pipe, _PLANE_BUF_CFG_1_A, _PLANE_BUF_CFG_1_B)
+#define _PLANE_BUF_CFG_2(pipe)	\
+	_PIPE(pipe, _PLANE_BUF_CFG_2_A, _PLANE_BUF_CFG_2_B)
+#define PLANE_BUF_CFG(pipe, plane)	\
+	_MMIO_PLANE(plane, _PLANE_BUF_CFG_1(pipe), _PLANE_BUF_CFG_2(pipe))
+
+#define _PLANE_NV12_BUF_CFG_1_B		0x71278
+#define _PLANE_NV12_BUF_CFG_2_B		0x71378
+#define _PLANE_NV12_BUF_CFG_1(pipe)	\
+	_PIPE(pipe, _PLANE_NV12_BUF_CFG_1_A, _PLANE_NV12_BUF_CFG_1_B)
+#define _PLANE_NV12_BUF_CFG_2(pipe)	\
+	_PIPE(pipe, _PLANE_NV12_BUF_CFG_2_A, _PLANE_NV12_BUF_CFG_2_B)
+#define PLANE_NV12_BUF_CFG(pipe, plane)	\
+	_MMIO_PLANE(plane, _PLANE_NV12_BUF_CFG_1(pipe), _PLANE_NV12_BUF_CFG_2(pipe))
+
+/* SKL new cursor registers */
+#define _CUR_BUF_CFG_A				0x7017c
+#define _CUR_BUF_CFG_B				0x7117c
+#define CUR_BUF_CFG(pipe)	_MMIO_PIPE(pipe, _CUR_BUF_CFG_A, _CUR_BUF_CFG_B)
+
+/* VBIOS regs */
+#define VGACNTRL		_MMIO(0x71400)
+# define VGA_DISP_DISABLE			(1 << 31)
+# define VGA_2X_MODE				(1 << 30)
+# define VGA_PIPE_B_SELECT			(1 << 29)
+
+#define VLV_VGACNTRL		_MMIO(VLV_DISPLAY_BASE + 0x71400)
+
+/* Ironlake */
+
+#define CPU_VGACNTRL	_MMIO(0x41000)
+
+#define DIGITAL_PORT_HOTPLUG_CNTRL	_MMIO(0x44030)
+#define  DIGITAL_PORTA_HOTPLUG_ENABLE		(1 << 4)
+#define  DIGITAL_PORTA_PULSE_DURATION_2ms	(0 << 2) /* pre-HSW */
+#define  DIGITAL_PORTA_PULSE_DURATION_4_5ms	(1 << 2) /* pre-HSW */
+#define  DIGITAL_PORTA_PULSE_DURATION_6ms	(2 << 2) /* pre-HSW */
+#define  DIGITAL_PORTA_PULSE_DURATION_100ms	(3 << 2) /* pre-HSW */
+#define  DIGITAL_PORTA_PULSE_DURATION_MASK	(3 << 2) /* pre-HSW */
+#define  DIGITAL_PORTA_HOTPLUG_STATUS_MASK	(3 << 0)
+#define  DIGITAL_PORTA_HOTPLUG_NO_DETECT	(0 << 0)
+#define  DIGITAL_PORTA_HOTPLUG_SHORT_DETECT	(1 << 0)
+#define  DIGITAL_PORTA_HOTPLUG_LONG_DETECT	(2 << 0)
+
+/* refresh rate hardware control */
+#define RR_HW_CTL       _MMIO(0x45300)
+#define  RR_HW_LOW_POWER_FRAMES_MASK    0xff
+#define  RR_HW_HIGH_POWER_FRAMES_MASK   0xff00
+
+#define FDI_PLL_BIOS_0  _MMIO(0x46000)
+#define  FDI_PLL_FB_CLOCK_MASK  0xff
+#define FDI_PLL_BIOS_1  _MMIO(0x46004)
+#define FDI_PLL_BIOS_2  _MMIO(0x46008)
+#define DISPLAY_PORT_PLL_BIOS_0         _MMIO(0x4600c)
+#define DISPLAY_PORT_PLL_BIOS_1         _MMIO(0x46010)
+#define DISPLAY_PORT_PLL_BIOS_2         _MMIO(0x46014)
+
+#define PCH_3DCGDIS0		_MMIO(0x46020)
+# define MARIUNIT_CLOCK_GATE_DISABLE		(1 << 18)
+# define SVSMUNIT_CLOCK_GATE_DISABLE		(1 << 1)
+
+#define PCH_3DCGDIS1		_MMIO(0x46024)
+# define VFMUNIT_CLOCK_GATE_DISABLE		(1 << 11)
+
+#define FDI_PLL_FREQ_CTL        _MMIO(0x46030)
+#define  FDI_PLL_FREQ_CHANGE_REQUEST    (1<<24)
+#define  FDI_PLL_FREQ_LOCK_LIMIT_MASK   0xfff00
+#define  FDI_PLL_FREQ_DISABLE_COUNT_LIMIT_MASK  0xff
+
+
+#define _PIPEA_DATA_M1		0x60030
+#define  PIPE_DATA_M1_OFFSET    0
+#define _PIPEA_DATA_N1		0x60034
+#define  PIPE_DATA_N1_OFFSET    0
+
+#define _PIPEA_DATA_M2		0x60038
+#define  PIPE_DATA_M2_OFFSET    0
+#define _PIPEA_DATA_N2		0x6003c
+#define  PIPE_DATA_N2_OFFSET    0
+
+#define _PIPEA_LINK_M1		0x60040
+#define  PIPE_LINK_M1_OFFSET    0
+#define _PIPEA_LINK_N1		0x60044
+#define  PIPE_LINK_N1_OFFSET    0
+
+#define _PIPEA_LINK_M2		0x60048
+#define  PIPE_LINK_M2_OFFSET    0
+#define _PIPEA_LINK_N2		0x6004c
+#define  PIPE_LINK_N2_OFFSET    0
+
+/* PIPEB timing regs are same start from 0x61000 */
+
+#define _PIPEB_DATA_M1		0x61030
+#define _PIPEB_DATA_N1		0x61034
+#define _PIPEB_DATA_M2		0x61038
+#define _PIPEB_DATA_N2		0x6103c
+#define _PIPEB_LINK_M1		0x61040
+#define _PIPEB_LINK_N1		0x61044
+#define _PIPEB_LINK_M2		0x61048
+#define _PIPEB_LINK_N2		0x6104c
+
+#define PIPE_DATA_M1(tran) _MMIO_TRANS2(tran, _PIPEA_DATA_M1)
+#define PIPE_DATA_N1(tran) _MMIO_TRANS2(tran, _PIPEA_DATA_N1)
+#define PIPE_DATA_M2(tran) _MMIO_TRANS2(tran, _PIPEA_DATA_M2)
+#define PIPE_DATA_N2(tran) _MMIO_TRANS2(tran, _PIPEA_DATA_N2)
+#define PIPE_LINK_M1(tran) _MMIO_TRANS2(tran, _PIPEA_LINK_M1)
+#define PIPE_LINK_N1(tran) _MMIO_TRANS2(tran, _PIPEA_LINK_N1)
+#define PIPE_LINK_M2(tran) _MMIO_TRANS2(tran, _PIPEA_LINK_M2)
+#define PIPE_LINK_N2(tran) _MMIO_TRANS2(tran, _PIPEA_LINK_N2)
+
+/* CPU panel fitter */
+/* IVB+ has 3 fitters, 0 is 7x5 capable, the other two only 3x3 */
+#define _PFA_CTL_1               0x68080
+#define _PFB_CTL_1               0x68880
+#define  PF_ENABLE              (1<<31)
+#define  PF_PIPE_SEL_MASK_IVB	(3<<29)
+#define  PF_PIPE_SEL_IVB(pipe)	((pipe)<<29)
+#define  PF_FILTER_MASK		(3<<23)
+#define  PF_FILTER_PROGRAMMED	(0<<23)
+#define  PF_FILTER_MED_3x3	(1<<23)
+#define  PF_FILTER_EDGE_ENHANCE	(2<<23)
+#define  PF_FILTER_EDGE_SOFTEN	(3<<23)
+#define _PFA_WIN_SZ		0x68074
+#define _PFB_WIN_SZ		0x68874
+#define _PFA_WIN_POS		0x68070
+#define _PFB_WIN_POS		0x68870
+#define _PFA_VSCALE		0x68084
+#define _PFB_VSCALE		0x68884
+#define _PFA_HSCALE		0x68090
+#define _PFB_HSCALE		0x68890
+
+#define PF_CTL(pipe)		_MMIO_PIPE(pipe, _PFA_CTL_1, _PFB_CTL_1)
+#define PF_WIN_SZ(pipe)		_MMIO_PIPE(pipe, _PFA_WIN_SZ, _PFB_WIN_SZ)
+#define PF_WIN_POS(pipe)	_MMIO_PIPE(pipe, _PFA_WIN_POS, _PFB_WIN_POS)
+#define PF_VSCALE(pipe)		_MMIO_PIPE(pipe, _PFA_VSCALE, _PFB_VSCALE)
+#define PF_HSCALE(pipe)		_MMIO_PIPE(pipe, _PFA_HSCALE, _PFB_HSCALE)
+
+#define _PSA_CTL		0x68180
+#define _PSB_CTL		0x68980
+#define PS_ENABLE		(1<<31)
+#define _PSA_WIN_SZ		0x68174
+#define _PSB_WIN_SZ		0x68974
+#define _PSA_WIN_POS		0x68170
+#define _PSB_WIN_POS		0x68970
+
+#define PS_CTL(pipe)		_MMIO_PIPE(pipe, _PSA_CTL, _PSB_CTL)
+#define PS_WIN_SZ(pipe)		_MMIO_PIPE(pipe, _PSA_WIN_SZ, _PSB_WIN_SZ)
+#define PS_WIN_POS(pipe)	_MMIO_PIPE(pipe, _PSA_WIN_POS, _PSB_WIN_POS)
+
+/*
+ * Skylake scalers
+ */
+#define _PS_1A_CTRL      0x68180
+#define _PS_2A_CTRL      0x68280
+#define _PS_1B_CTRL      0x68980
+#define _PS_2B_CTRL      0x68A80
+#define _PS_1C_CTRL      0x69180
+#define PS_SCALER_EN        (1 << 31)
+#define PS_SCALER_MODE_MASK (3 << 28)
+#define PS_SCALER_MODE_DYN  (0 << 28)
+#define PS_SCALER_MODE_HQ  (1 << 28)
+#define PS_PLANE_SEL_MASK  (7 << 25)
+#define PS_PLANE_SEL(plane) (((plane) + 1) << 25)
+#define PS_FILTER_MASK         (3 << 23)
+#define PS_FILTER_MEDIUM       (0 << 23)
+#define PS_FILTER_EDGE_ENHANCE (2 << 23)
+#define PS_FILTER_BILINEAR     (3 << 23)
+#define PS_VERT3TAP            (1 << 21)
+#define PS_VERT_INT_INVERT_FIELD1 (0 << 20)
+#define PS_VERT_INT_INVERT_FIELD0 (1 << 20)
+#define PS_PWRUP_PROGRESS         (1 << 17)
+#define PS_V_FILTER_BYPASS        (1 << 8)
+#define PS_VADAPT_EN              (1 << 7)
+#define PS_VADAPT_MODE_MASK        (3 << 5)
+#define PS_VADAPT_MODE_LEAST_ADAPT (0 << 5)
+#define PS_VADAPT_MODE_MOD_ADAPT   (1 << 5)
+#define PS_VADAPT_MODE_MOST_ADAPT  (3 << 5)
+
+#define _PS_PWR_GATE_1A     0x68160
+#define _PS_PWR_GATE_2A     0x68260
+#define _PS_PWR_GATE_1B     0x68960
+#define _PS_PWR_GATE_2B     0x68A60
+#define _PS_PWR_GATE_1C     0x69160
+#define PS_PWR_GATE_DIS_OVERRIDE       (1 << 31)
+#define PS_PWR_GATE_SETTLING_TIME_32   (0 << 3)
+#define PS_PWR_GATE_SETTLING_TIME_64   (1 << 3)
+#define PS_PWR_GATE_SETTLING_TIME_96   (2 << 3)
+#define PS_PWR_GATE_SETTLING_TIME_128  (3 << 3)
+#define PS_PWR_GATE_SLPEN_8             0
+#define PS_PWR_GATE_SLPEN_16            1
+#define PS_PWR_GATE_SLPEN_24            2
+#define PS_PWR_GATE_SLPEN_32            3
+
+#define _PS_WIN_POS_1A      0x68170
+#define _PS_WIN_POS_2A      0x68270
+#define _PS_WIN_POS_1B      0x68970
+#define _PS_WIN_POS_2B      0x68A70
+#define _PS_WIN_POS_1C      0x69170
+
+#define _PS_WIN_SZ_1A       0x68174
+#define _PS_WIN_SZ_2A       0x68274
+#define _PS_WIN_SZ_1B       0x68974
+#define _PS_WIN_SZ_2B       0x68A74
+#define _PS_WIN_SZ_1C       0x69174
+
+#define _PS_VSCALE_1A       0x68184
+#define _PS_VSCALE_2A       0x68284
+#define _PS_VSCALE_1B       0x68984
+#define _PS_VSCALE_2B       0x68A84
+#define _PS_VSCALE_1C       0x69184
+
+#define _PS_HSCALE_1A       0x68190
+#define _PS_HSCALE_2A       0x68290
+#define _PS_HSCALE_1B       0x68990
+#define _PS_HSCALE_2B       0x68A90
+#define _PS_HSCALE_1C       0x69190
+
+#define _PS_VPHASE_1A       0x68188
+#define _PS_VPHASE_2A       0x68288
+#define _PS_VPHASE_1B       0x68988
+#define _PS_VPHASE_2B       0x68A88
+#define _PS_VPHASE_1C       0x69188
+
+#define _PS_HPHASE_1A       0x68194
+#define _PS_HPHASE_2A       0x68294
+#define _PS_HPHASE_1B       0x68994
+#define _PS_HPHASE_2B       0x68A94
+#define _PS_HPHASE_1C       0x69194
+
+#define _PS_ECC_STAT_1A     0x681D0
+#define _PS_ECC_STAT_2A     0x682D0
+#define _PS_ECC_STAT_1B     0x689D0
+#define _PS_ECC_STAT_2B     0x68AD0
+#define _PS_ECC_STAT_1C     0x691D0
+
+#define _ID(id, a, b) ((a) + (id)*((b)-(a)))
+#define SKL_PS_CTRL(pipe, id) _MMIO_PIPE(pipe,        \
+			_ID(id, _PS_1A_CTRL, _PS_2A_CTRL),       \
+			_ID(id, _PS_1B_CTRL, _PS_2B_CTRL))
+#define SKL_PS_PWR_GATE(pipe, id) _MMIO_PIPE(pipe,    \
+			_ID(id, _PS_PWR_GATE_1A, _PS_PWR_GATE_2A), \
+			_ID(id, _PS_PWR_GATE_1B, _PS_PWR_GATE_2B))
+#define SKL_PS_WIN_POS(pipe, id) _MMIO_PIPE(pipe,     \
+			_ID(id, _PS_WIN_POS_1A, _PS_WIN_POS_2A), \
+			_ID(id, _PS_WIN_POS_1B, _PS_WIN_POS_2B))
+#define SKL_PS_WIN_SZ(pipe, id)  _MMIO_PIPE(pipe,     \
+			_ID(id, _PS_WIN_SZ_1A, _PS_WIN_SZ_2A),   \
+			_ID(id, _PS_WIN_SZ_1B, _PS_WIN_SZ_2B))
+#define SKL_PS_VSCALE(pipe, id)  _MMIO_PIPE(pipe,     \
+			_ID(id, _PS_VSCALE_1A, _PS_VSCALE_2A),   \
+			_ID(id, _PS_VSCALE_1B, _PS_VSCALE_2B))
+#define SKL_PS_HSCALE(pipe, id)  _MMIO_PIPE(pipe,     \
+			_ID(id, _PS_HSCALE_1A, _PS_HSCALE_2A),   \
+			_ID(id, _PS_HSCALE_1B, _PS_HSCALE_2B))
+#define SKL_PS_VPHASE(pipe, id)  _MMIO_PIPE(pipe,     \
+			_ID(id, _PS_VPHASE_1A, _PS_VPHASE_2A),   \
+			_ID(id, _PS_VPHASE_1B, _PS_VPHASE_2B))
+#define SKL_PS_HPHASE(pipe, id)  _MMIO_PIPE(pipe,     \
+			_ID(id, _PS_HPHASE_1A, _PS_HPHASE_2A),   \
+			_ID(id, _PS_HPHASE_1B, _PS_HPHASE_2B))
+#define SKL_PS_ECC_STAT(pipe, id)  _MMIO_PIPE(pipe,     \
+			_ID(id, _PS_ECC_STAT_1A, _PS_ECC_STAT_2A),   \
+			_ID(id, _PS_ECC_STAT_1B, _PS_ECC_STAT_2B))
+
+/* legacy palette */
+#define _LGC_PALETTE_A           0x4a000
+#define _LGC_PALETTE_B           0x4a800
+#define LGC_PALETTE(pipe, i) _MMIO(_PIPE(pipe, _LGC_PALETTE_A, _LGC_PALETTE_B) + (i) * 4)
+
+#define _GAMMA_MODE_A		0x4a480
+#define _GAMMA_MODE_B		0x4ac80
+#define GAMMA_MODE(pipe) _MMIO_PIPE(pipe, _GAMMA_MODE_A, _GAMMA_MODE_B)
+#define GAMMA_MODE_MODE_MASK	(3 << 0)
+#define GAMMA_MODE_MODE_8BIT	(0 << 0)
+#define GAMMA_MODE_MODE_10BIT	(1 << 0)
+#define GAMMA_MODE_MODE_12BIT	(2 << 0)
+#define GAMMA_MODE_MODE_SPLIT	(3 << 0)
+
+/* DMC/CSR */
+#define CSR_PROGRAM(i)		_MMIO(0x80000 + (i) * 4)
+#define CSR_SSP_BASE_ADDR_GEN9	0x00002FC0
+#define CSR_HTP_ADDR_SKL	0x00500034
+#define CSR_SSP_BASE		_MMIO(0x8F074)
+#define CSR_HTP_SKL		_MMIO(0x8F004)
+#define CSR_LAST_WRITE		_MMIO(0x8F034)
+#define CSR_LAST_WRITE_VALUE	0xc003b400
+/* MMIO address range for CSR program (0x80000 - 0x82FFF) */
+#define CSR_MMIO_START_RANGE	0x80000
+#define CSR_MMIO_END_RANGE	0x8FFFF
+#define SKL_CSR_DC3_DC5_COUNT	_MMIO(0x80030)
+#define SKL_CSR_DC5_DC6_COUNT	_MMIO(0x8002C)
+#define BXT_CSR_DC3_DC5_COUNT	_MMIO(0x80038)
+
+/* interrupts */
+#define DE_MASTER_IRQ_CONTROL   (1 << 31)
+#define DE_SPRITEB_FLIP_DONE    (1 << 29)
+#define DE_SPRITEA_FLIP_DONE    (1 << 28)
+#define DE_PLANEB_FLIP_DONE     (1 << 27)
+#define DE_PLANEA_FLIP_DONE     (1 << 26)
+#define DE_PLANE_FLIP_DONE(plane) (1 << (26 + (plane)))
+#define DE_PCU_EVENT            (1 << 25)
+#define DE_GTT_FAULT            (1 << 24)
+#define DE_POISON               (1 << 23)
+#define DE_PERFORM_COUNTER      (1 << 22)
+#define DE_PCH_EVENT            (1 << 21)
+#define DE_AUX_CHANNEL_A        (1 << 20)
+#define DE_DP_A_HOTPLUG         (1 << 19)
+#define DE_GSE                  (1 << 18)
+#define DE_PIPEB_VBLANK         (1 << 15)
+#define DE_PIPEB_EVEN_FIELD     (1 << 14)
+#define DE_PIPEB_ODD_FIELD      (1 << 13)
+#define DE_PIPEB_LINE_COMPARE   (1 << 12)
+#define DE_PIPEB_VSYNC          (1 << 11)
+#define DE_PIPEB_CRC_DONE	(1 << 10)
+#define DE_PIPEB_FIFO_UNDERRUN  (1 << 8)
+#define DE_PIPEA_VBLANK         (1 << 7)
+#define DE_PIPE_VBLANK(pipe)    (1 << (7 + 8*(pipe)))
+#define DE_PIPEA_EVEN_FIELD     (1 << 6)
+#define DE_PIPEA_ODD_FIELD      (1 << 5)
+#define DE_PIPEA_LINE_COMPARE   (1 << 4)
+#define DE_PIPEA_VSYNC          (1 << 3)
+#define DE_PIPEA_CRC_DONE	(1 << 2)
+#define DE_PIPE_CRC_DONE(pipe)	(1 << (2 + 8*(pipe)))
+#define DE_PIPEA_FIFO_UNDERRUN  (1 << 0)
+#define DE_PIPE_FIFO_UNDERRUN(pipe)  (1 << (8*(pipe)))
+
+/* More Ivybridge lolz */
+#define DE_ERR_INT_IVB			(1<<30)
+#define DE_GSE_IVB			(1<<29)
+#define DE_PCH_EVENT_IVB		(1<<28)
+#define DE_DP_A_HOTPLUG_IVB		(1<<27)
+#define DE_AUX_CHANNEL_A_IVB		(1<<26)
+#define DE_SPRITEC_FLIP_DONE_IVB	(1<<14)
+#define DE_PLANEC_FLIP_DONE_IVB		(1<<13)
+#define DE_PIPEC_VBLANK_IVB		(1<<10)
+#define DE_SPRITEB_FLIP_DONE_IVB	(1<<9)
+#define DE_PLANEB_FLIP_DONE_IVB		(1<<8)
+#define DE_PIPEB_VBLANK_IVB		(1<<5)
+#define DE_SPRITEA_FLIP_DONE_IVB	(1<<4)
+#define DE_PLANEA_FLIP_DONE_IVB		(1<<3)
+#define DE_PLANE_FLIP_DONE_IVB(plane)	(1<< (3 + 5*(plane)))
+#define DE_PIPEA_VBLANK_IVB		(1<<0)
+#define DE_PIPE_VBLANK_IVB(pipe)	(1 << ((pipe) * 5))
+
+#define VLV_MASTER_IER			_MMIO(0x4400c) /* Gunit master IER */
+#define   MASTER_INTERRUPT_ENABLE	(1<<31)
+
+#define DEISR   _MMIO(0x44000)
+#define DEIMR   _MMIO(0x44004)
+#define DEIIR   _MMIO(0x44008)
+#define DEIER   _MMIO(0x4400c)
+
+#define GTISR   _MMIO(0x44010)
+#define GTIMR   _MMIO(0x44014)
+#define GTIIR   _MMIO(0x44018)
+#define GTIER   _MMIO(0x4401c)
+
+#define GEN8_MASTER_IRQ			_MMIO(0x44200)
+#define  GEN8_MASTER_IRQ_CONTROL	(1<<31)
+#define  GEN8_PCU_IRQ			(1<<30)
+#define  GEN8_DE_PCH_IRQ		(1<<23)
+#define  GEN8_DE_MISC_IRQ		(1<<22)
+#define  GEN8_DE_PORT_IRQ		(1<<20)
+#define  GEN8_DE_PIPE_C_IRQ		(1<<18)
+#define  GEN8_DE_PIPE_B_IRQ		(1<<17)
+#define  GEN8_DE_PIPE_A_IRQ		(1<<16)
+#define  GEN8_DE_PIPE_IRQ(pipe)		(1<<(16+(pipe)))
+#define  GEN8_GT_VECS_IRQ		(1<<6)
+#define  GEN8_GT_PM_IRQ			(1<<4)
+#define  GEN8_GT_VCS2_IRQ		(1<<3)
+#define  GEN8_GT_VCS1_IRQ		(1<<2)
+#define  GEN8_GT_BCS_IRQ		(1<<1)
+#define  GEN8_GT_RCS_IRQ		(1<<0)
+
+#define GEN8_GT_ISR(which) _MMIO(0x44300 + (0x10 * (which)))
+#define GEN8_GT_IMR(which) _MMIO(0x44304 + (0x10 * (which)))
+#define GEN8_GT_IIR(which) _MMIO(0x44308 + (0x10 * (which)))
+#define GEN8_GT_IER(which) _MMIO(0x4430c + (0x10 * (which)))
+
+#define GEN8_RCS_IRQ_SHIFT 0
+#define GEN8_BCS_IRQ_SHIFT 16
+#define GEN8_VCS1_IRQ_SHIFT 0
+#define GEN8_VCS2_IRQ_SHIFT 16
+#define GEN8_VECS_IRQ_SHIFT 0
+#define GEN8_WD_IRQ_SHIFT 16
+
+#define GEN8_DE_PIPE_ISR(pipe) _MMIO(0x44400 + (0x10 * (pipe)))
+#define GEN8_DE_PIPE_IMR(pipe) _MMIO(0x44404 + (0x10 * (pipe)))
+#define GEN8_DE_PIPE_IIR(pipe) _MMIO(0x44408 + (0x10 * (pipe)))
+#define GEN8_DE_PIPE_IER(pipe) _MMIO(0x4440c + (0x10 * (pipe)))
+#define  GEN8_PIPE_FIFO_UNDERRUN	(1 << 31)
+#define  GEN8_PIPE_CDCLK_CRC_ERROR	(1 << 29)
+#define  GEN8_PIPE_CDCLK_CRC_DONE	(1 << 28)
+#define  GEN8_PIPE_CURSOR_FAULT		(1 << 10)
+#define  GEN8_PIPE_SPRITE_FAULT		(1 << 9)
+#define  GEN8_PIPE_PRIMARY_FAULT	(1 << 8)
+#define  GEN8_PIPE_SPRITE_FLIP_DONE	(1 << 5)
+#define  GEN8_PIPE_PRIMARY_FLIP_DONE	(1 << 4)
+#define  GEN8_PIPE_SCAN_LINE_EVENT	(1 << 2)
+#define  GEN8_PIPE_VSYNC		(1 << 1)
+#define  GEN8_PIPE_VBLANK		(1 << 0)
+#define  GEN9_PIPE_CURSOR_FAULT		(1 << 11)
+#define  GEN9_PIPE_PLANE4_FAULT		(1 << 10)
+#define  GEN9_PIPE_PLANE3_FAULT		(1 << 9)
+#define  GEN9_PIPE_PLANE2_FAULT		(1 << 8)
+#define  GEN9_PIPE_PLANE1_FAULT		(1 << 7)
+#define  GEN9_PIPE_PLANE4_FLIP_DONE	(1 << 6)
+#define  GEN9_PIPE_PLANE3_FLIP_DONE	(1 << 5)
+#define  GEN9_PIPE_PLANE2_FLIP_DONE	(1 << 4)
+#define  GEN9_PIPE_PLANE1_FLIP_DONE	(1 << 3)
+#define  GEN9_PIPE_PLANE_FLIP_DONE(p)	(1 << (3 + (p)))
+#define GEN8_DE_PIPE_IRQ_FAULT_ERRORS \
+	(GEN8_PIPE_CURSOR_FAULT | \
+	 GEN8_PIPE_SPRITE_FAULT | \
+	 GEN8_PIPE_PRIMARY_FAULT)
+#define GEN9_DE_PIPE_IRQ_FAULT_ERRORS \
+	(GEN9_PIPE_CURSOR_FAULT | \
+	 GEN9_PIPE_PLANE4_FAULT | \
+	 GEN9_PIPE_PLANE3_FAULT | \
+	 GEN9_PIPE_PLANE2_FAULT | \
+	 GEN9_PIPE_PLANE1_FAULT)
+
+#define GEN8_DE_PORT_ISR _MMIO(0x44440)
+#define GEN8_DE_PORT_IMR _MMIO(0x44444)
+#define GEN8_DE_PORT_IIR _MMIO(0x44448)
+#define GEN8_DE_PORT_IER _MMIO(0x4444c)
+#define  GEN9_AUX_CHANNEL_D		(1 << 27)
+#define  GEN9_AUX_CHANNEL_C		(1 << 26)
+#define  GEN9_AUX_CHANNEL_B		(1 << 25)
+#define  BXT_DE_PORT_HP_DDIC		(1 << 5)
+#define  BXT_DE_PORT_HP_DDIB		(1 << 4)
+#define  BXT_DE_PORT_HP_DDIA		(1 << 3)
+#define  BXT_DE_PORT_HOTPLUG_MASK	(BXT_DE_PORT_HP_DDIA | \
+					 BXT_DE_PORT_HP_DDIB | \
+					 BXT_DE_PORT_HP_DDIC)
+#define  GEN8_PORT_DP_A_HOTPLUG		(1 << 3)
+#define  BXT_DE_PORT_GMBUS		(1 << 1)
+#define  GEN8_AUX_CHANNEL_A		(1 << 0)
+
+#define GEN8_DE_MISC_ISR _MMIO(0x44460)
+#define GEN8_DE_MISC_IMR _MMIO(0x44464)
+#define GEN8_DE_MISC_IIR _MMIO(0x44468)
+#define GEN8_DE_MISC_IER _MMIO(0x4446c)
+#define  GEN8_DE_MISC_GSE		(1 << 27)
+
+#define GEN8_PCU_ISR _MMIO(0x444e0)
+#define GEN8_PCU_IMR _MMIO(0x444e4)
+#define GEN8_PCU_IIR _MMIO(0x444e8)
+#define GEN8_PCU_IER _MMIO(0x444ec)
+
+#define ILK_DISPLAY_CHICKEN2	_MMIO(0x42004)
+/* Required on all Ironlake and Sandybridge according to the B-Spec. */
+#define  ILK_ELPIN_409_SELECT	(1 << 25)
+#define  ILK_DPARB_GATE	(1<<22)
+#define  ILK_VSDPFD_FULL	(1<<21)
+#define FUSE_STRAP			_MMIO(0x42014)
+#define  ILK_INTERNAL_GRAPHICS_DISABLE	(1 << 31)
+#define  ILK_INTERNAL_DISPLAY_DISABLE	(1 << 30)
+#define  ILK_DISPLAY_DEBUG_DISABLE	(1 << 29)
+#define  IVB_PIPE_C_DISABLE		(1 << 28)
+#define  ILK_HDCP_DISABLE		(1 << 25)
+#define  ILK_eDP_A_DISABLE		(1 << 24)
+#define  HSW_CDCLK_LIMIT		(1 << 24)
+#define  ILK_DESKTOP			(1 << 23)
+
+#define ILK_DSPCLK_GATE_D			_MMIO(0x42020)
+#define   ILK_VRHUNIT_CLOCK_GATE_DISABLE	(1 << 28)
+#define   ILK_DPFCUNIT_CLOCK_GATE_DISABLE	(1 << 9)
+#define   ILK_DPFCRUNIT_CLOCK_GATE_DISABLE	(1 << 8)
+#define   ILK_DPFDUNIT_CLOCK_GATE_ENABLE	(1 << 7)
+#define   ILK_DPARBUNIT_CLOCK_GATE_ENABLE	(1 << 5)
+
+#define IVB_CHICKEN3	_MMIO(0x4200c)
+# define CHICKEN3_DGMG_REQ_OUT_FIX_DISABLE	(1 << 5)
+# define CHICKEN3_DGMG_DONE_FIX_DISABLE		(1 << 2)
+
+#define CHICKEN_PAR1_1		_MMIO(0x42080)
+#define  DPA_MASK_VBLANK_SRD	(1 << 15)
+#define  FORCE_ARB_IDLE_PLANES	(1 << 14)
+#define  SKL_EDP_PSR_FIX_RDWRAP	(1 << 3)
+
+#define _CHICKEN_PIPESL_1_A	0x420b0
+#define _CHICKEN_PIPESL_1_B	0x420b4
+#define  HSW_FBCQ_DIS			(1 << 22)
+#define  BDW_DPRS_MASK_VBLANK_SRD	(1 << 0)
+#define CHICKEN_PIPESL_1(pipe) _MMIO_PIPE(pipe, _CHICKEN_PIPESL_1_A, _CHICKEN_PIPESL_1_B)
+
+#define DISP_ARB_CTL	_MMIO(0x45000)
+#define  DISP_FBC_MEMORY_WAKE		(1<<31)
+#define  DISP_TILE_SURFACE_SWIZZLING	(1<<13)
+#define  DISP_FBC_WM_DIS		(1<<15)
+#define DISP_ARB_CTL2	_MMIO(0x45004)
+#define  DISP_DATA_PARTITION_5_6	(1<<6)
+#define DBUF_CTL	_MMIO(0x45008)
+#define  DBUF_POWER_REQUEST		(1<<31)
+#define  DBUF_POWER_STATE		(1<<30)
+#define GEN7_MSG_CTL	_MMIO(0x45010)
+#define  WAIT_FOR_PCH_RESET_ACK		(1<<1)
+#define  WAIT_FOR_PCH_FLR_ACK		(1<<0)
+#define HSW_NDE_RSTWRN_OPT	_MMIO(0x46408)
+#define  RESET_PCH_HANDSHAKE_ENABLE	(1<<4)
+
+#define GEN8_CHICKEN_DCPR_1		_MMIO(0x46430)
+#define   MASK_WAKEMEM			(1<<13)
+
+#define SKL_DFSM			_MMIO(0x51000)
+#define SKL_DFSM_CDCLK_LIMIT_MASK	(3 << 23)
+#define SKL_DFSM_CDCLK_LIMIT_675	(0 << 23)
+#define SKL_DFSM_CDCLK_LIMIT_540	(1 << 23)
+#define SKL_DFSM_CDCLK_LIMIT_450	(2 << 23)
+#define SKL_DFSM_CDCLK_LIMIT_337_5	(3 << 23)
+#define SKL_DFSM_PIPE_A_DISABLE		(1 << 30)
+#define SKL_DFSM_PIPE_B_DISABLE		(1 << 21)
+#define SKL_DFSM_PIPE_C_DISABLE		(1 << 28)
+
+#define GEN7_FF_SLICE_CS_CHICKEN1	_MMIO(0x20e0)
+#define   GEN9_FFSC_PERCTX_PREEMPT_CTRL	(1<<14)
+
+#define FF_SLICE_CS_CHICKEN2			_MMIO(0x20e4)
+#define  GEN9_TSG_BARRIER_ACK_DISABLE		(1<<8)
+
+#define GEN9_CS_DEBUG_MODE1		_MMIO(0x20ec)
+#define GEN9_CTX_PREEMPT_REG		_MMIO(0x2248)
+#define GEN8_CS_CHICKEN1		_MMIO(0x2580)
+
+/* GEN7 chicken */
+#define GEN7_COMMON_SLICE_CHICKEN1		_MMIO(0x7010)
+# define GEN7_CSC1_RHWO_OPT_DISABLE_IN_RCC	((1<<10) | (1<<26))
+# define GEN9_RHWO_OPTIMIZATION_DISABLE		(1<<14)
+#define COMMON_SLICE_CHICKEN2			_MMIO(0x7014)
+# define GEN8_SBE_DISABLE_REPLAY_BUF_OPTIMIZATION (1<<8)
+# define GEN8_CSC2_SBE_VUE_CACHE_CONSERVATIVE	(1<<0)
+
+#define HIZ_CHICKEN					_MMIO(0x7018)
+# define CHV_HZ_8X8_MODE_IN_1X				(1<<15)
+# define BDW_HIZ_POWER_COMPILER_CLOCK_GATING_DISABLE	(1<<3)
+
+#define GEN9_SLICE_COMMON_ECO_CHICKEN0		_MMIO(0x7308)
+#define  DISABLE_PIXEL_MASK_CAMMING		(1<<14)
+
+#define GEN7_L3SQCREG1				_MMIO(0xB010)
+#define  VLV_B0_WA_L3SQCREG1_VALUE		0x00D30000
+
+#define GEN8_L3SQCREG1				_MMIO(0xB100)
+#define  BDW_WA_L3SQCREG1_DEFAULT		0x784000
+
+#define GEN7_L3CNTLREG1				_MMIO(0xB01C)
+#define  GEN7_WA_FOR_GEN7_L3_CONTROL			0x3C47FF8C
+#define  GEN7_L3AGDIS				(1<<19)
+#define GEN7_L3CNTLREG2				_MMIO(0xB020)
+#define GEN7_L3CNTLREG3				_MMIO(0xB024)
+
+#define GEN7_L3_CHICKEN_MODE_REGISTER		_MMIO(0xB030)
+#define  GEN7_WA_L3_CHICKEN_MODE				0x20000000
+
+#define GEN7_L3SQCREG4				_MMIO(0xb034)
+#define  L3SQ_URB_READ_CAM_MATCH_DISABLE	(1<<27)
+
+#define GEN8_L3SQCREG4				_MMIO(0xb118)
+#define  GEN8_LQSC_RO_PERF_DIS			(1<<27)
+#define  GEN8_LQSC_FLUSH_COHERENT_LINES		(1<<21)
+
+/* GEN8 chicken */
+#define HDC_CHICKEN0				_MMIO(0x7300)
+#define  HDC_FORCE_CSR_NON_COHERENT_OVR_DISABLE	(1<<15)
+#define  HDC_FENCE_DEST_SLM_DISABLE		(1<<14)
+#define  HDC_DONOT_FETCH_MEM_WHEN_MASKED	(1<<11)
+#define  HDC_FORCE_CONTEXT_SAVE_RESTORE_NON_COHERENT	(1<<5)
+#define  HDC_FORCE_NON_COHERENT			(1<<4)
+#define  HDC_BARRIER_PERFORMANCE_DISABLE	(1<<10)
+
+#define GEN8_HDC_CHICKEN1			_MMIO(0x7304)
+
+/* GEN9 chicken */
+#define SLICE_ECO_CHICKEN0			_MMIO(0x7308)
+#define   PIXEL_MASK_CAMMING_DISABLE		(1 << 14)
+
+/* WaCatErrorRejectionIssue */
+#define GEN7_SQ_CHICKEN_MBCUNIT_CONFIG		_MMIO(0x9030)
+#define  GEN7_SQ_CHICKEN_MBCUNIT_SQINTMOB	(1<<11)
+
+#define HSW_SCRATCH1				_MMIO(0xb038)
+#define  HSW_SCRATCH1_L3_DATA_ATOMICS_DISABLE	(1<<27)
+
+#define BDW_SCRATCH1					_MMIO(0xb11c)
+#define  GEN9_LBS_SLA_RETRY_TIMER_DECREMENT_ENABLE	(1<<2)
+
+/* PCH */
+
+/* south display engine interrupt: IBX */
+#define SDE_AUDIO_POWER_D	(1 << 27)
+#define SDE_AUDIO_POWER_C	(1 << 26)
+#define SDE_AUDIO_POWER_B	(1 << 25)
+#define SDE_AUDIO_POWER_SHIFT	(25)
+#define SDE_AUDIO_POWER_MASK	(7 << SDE_AUDIO_POWER_SHIFT)
+#define SDE_GMBUS		(1 << 24)
+#define SDE_AUDIO_HDCP_TRANSB	(1 << 23)
+#define SDE_AUDIO_HDCP_TRANSA	(1 << 22)
+#define SDE_AUDIO_HDCP_MASK	(3 << 22)
+#define SDE_AUDIO_TRANSB	(1 << 21)
+#define SDE_AUDIO_TRANSA	(1 << 20)
+#define SDE_AUDIO_TRANS_MASK	(3 << 20)
+#define SDE_POISON		(1 << 19)
+/* 18 reserved */
+#define SDE_FDI_RXB		(1 << 17)
+#define SDE_FDI_RXA		(1 << 16)
+#define SDE_FDI_MASK		(3 << 16)
+#define SDE_AUXD		(1 << 15)
+#define SDE_AUXC		(1 << 14)
+#define SDE_AUXB		(1 << 13)
+#define SDE_AUX_MASK		(7 << 13)
+/* 12 reserved */
+#define SDE_CRT_HOTPLUG         (1 << 11)
+#define SDE_PORTD_HOTPLUG       (1 << 10)
+#define SDE_PORTC_HOTPLUG       (1 << 9)
+#define SDE_PORTB_HOTPLUG       (1 << 8)
+#define SDE_SDVOB_HOTPLUG       (1 << 6)
+#define SDE_HOTPLUG_MASK        (SDE_CRT_HOTPLUG | \
+				 SDE_SDVOB_HOTPLUG |	\
+				 SDE_PORTB_HOTPLUG |	\
+				 SDE_PORTC_HOTPLUG |	\
+				 SDE_PORTD_HOTPLUG)
+#define SDE_TRANSB_CRC_DONE	(1 << 5)
+#define SDE_TRANSB_CRC_ERR	(1 << 4)
+#define SDE_TRANSB_FIFO_UNDER	(1 << 3)
+#define SDE_TRANSA_CRC_DONE	(1 << 2)
+#define SDE_TRANSA_CRC_ERR	(1 << 1)
+#define SDE_TRANSA_FIFO_UNDER	(1 << 0)
+#define SDE_TRANS_MASK		(0x3f)
+
+/* south display engine interrupt: CPT/PPT */
+#define SDE_AUDIO_POWER_D_CPT	(1 << 31)
+#define SDE_AUDIO_POWER_C_CPT	(1 << 30)
+#define SDE_AUDIO_POWER_B_CPT	(1 << 29)
+#define SDE_AUDIO_POWER_SHIFT_CPT   29
+#define SDE_AUDIO_POWER_MASK_CPT    (7 << 29)
+#define SDE_AUXD_CPT		(1 << 27)
+#define SDE_AUXC_CPT		(1 << 26)
+#define SDE_AUXB_CPT		(1 << 25)
+#define SDE_AUX_MASK_CPT	(7 << 25)
+#define SDE_PORTE_HOTPLUG_SPT	(1 << 25)
+#define SDE_PORTA_HOTPLUG_SPT	(1 << 24)
+#define SDE_PORTD_HOTPLUG_CPT	(1 << 23)
+#define SDE_PORTC_HOTPLUG_CPT	(1 << 22)
+#define SDE_PORTB_HOTPLUG_CPT	(1 << 21)
+#define SDE_CRT_HOTPLUG_CPT	(1 << 19)
+#define SDE_SDVOB_HOTPLUG_CPT	(1 << 18)
+#define SDE_HOTPLUG_MASK_CPT	(SDE_CRT_HOTPLUG_CPT |		\
+				 SDE_SDVOB_HOTPLUG_CPT |	\
+				 SDE_PORTD_HOTPLUG_CPT |	\
+				 SDE_PORTC_HOTPLUG_CPT |	\
+				 SDE_PORTB_HOTPLUG_CPT)
+#define SDE_HOTPLUG_MASK_SPT	(SDE_PORTE_HOTPLUG_SPT |	\
+				 SDE_PORTD_HOTPLUG_CPT |	\
+				 SDE_PORTC_HOTPLUG_CPT |	\
+				 SDE_PORTB_HOTPLUG_CPT |	\
+				 SDE_PORTA_HOTPLUG_SPT)
+#define SDE_GMBUS_CPT		(1 << 17)
+#define SDE_ERROR_CPT		(1 << 16)
+#define SDE_AUDIO_CP_REQ_C_CPT	(1 << 10)
+#define SDE_AUDIO_CP_CHG_C_CPT	(1 << 9)
+#define SDE_FDI_RXC_CPT		(1 << 8)
+#define SDE_AUDIO_CP_REQ_B_CPT	(1 << 6)
+#define SDE_AUDIO_CP_CHG_B_CPT	(1 << 5)
+#define SDE_FDI_RXB_CPT		(1 << 4)
+#define SDE_AUDIO_CP_REQ_A_CPT	(1 << 2)
+#define SDE_AUDIO_CP_CHG_A_CPT	(1 << 1)
+#define SDE_FDI_RXA_CPT		(1 << 0)
+#define SDE_AUDIO_CP_REQ_CPT	(SDE_AUDIO_CP_REQ_C_CPT | \
+				 SDE_AUDIO_CP_REQ_B_CPT | \
+				 SDE_AUDIO_CP_REQ_A_CPT)
+#define SDE_AUDIO_CP_CHG_CPT	(SDE_AUDIO_CP_CHG_C_CPT | \
+				 SDE_AUDIO_CP_CHG_B_CPT | \
+				 SDE_AUDIO_CP_CHG_A_CPT)
+#define SDE_FDI_MASK_CPT	(SDE_FDI_RXC_CPT | \
+				 SDE_FDI_RXB_CPT | \
+				 SDE_FDI_RXA_CPT)
+
+#define SDEISR  _MMIO(0xc4000)
+#define SDEIMR  _MMIO(0xc4004)
+#define SDEIIR  _MMIO(0xc4008)
+#define SDEIER  _MMIO(0xc400c)
+
+#define SERR_INT			_MMIO(0xc4040)
+#define  SERR_INT_POISON		(1<<31)
+#define  SERR_INT_TRANS_C_FIFO_UNDERRUN	(1<<6)
+#define  SERR_INT_TRANS_B_FIFO_UNDERRUN	(1<<3)
+#define  SERR_INT_TRANS_A_FIFO_UNDERRUN	(1<<0)
+#define  SERR_INT_TRANS_FIFO_UNDERRUN(pipe)	(1<<((pipe)*3))
+
+/* digital port hotplug */
+#define PCH_PORT_HOTPLUG		_MMIO(0xc4030)	/* SHOTPLUG_CTL */
+#define  PORTA_HOTPLUG_ENABLE		(1 << 28) /* LPT:LP+ & BXT */
+#define  BXT_DDIA_HPD_INVERT            (1 << 27)
+#define  PORTA_HOTPLUG_STATUS_MASK	(3 << 24) /* SPT+ & BXT */
+#define  PORTA_HOTPLUG_NO_DETECT	(0 << 24) /* SPT+ & BXT */
+#define  PORTA_HOTPLUG_SHORT_DETECT	(1 << 24) /* SPT+ & BXT */
+#define  PORTA_HOTPLUG_LONG_DETECT	(2 << 24) /* SPT+ & BXT */
+#define  PORTD_HOTPLUG_ENABLE		(1 << 20)
+#define  PORTD_PULSE_DURATION_2ms	(0 << 18) /* pre-LPT */
+#define  PORTD_PULSE_DURATION_4_5ms	(1 << 18) /* pre-LPT */
+#define  PORTD_PULSE_DURATION_6ms	(2 << 18) /* pre-LPT */
+#define  PORTD_PULSE_DURATION_100ms	(3 << 18) /* pre-LPT */
+#define  PORTD_PULSE_DURATION_MASK	(3 << 18) /* pre-LPT */
+#define  PORTD_HOTPLUG_STATUS_MASK	(3 << 16)
+#define  PORTD_HOTPLUG_NO_DETECT	(0 << 16)
+#define  PORTD_HOTPLUG_SHORT_DETECT	(1 << 16)
+#define  PORTD_HOTPLUG_LONG_DETECT	(2 << 16)
+#define  PORTC_HOTPLUG_ENABLE		(1 << 12)
+#define  BXT_DDIC_HPD_INVERT            (1 << 11)
+#define  PORTC_PULSE_DURATION_2ms	(0 << 10) /* pre-LPT */
+#define  PORTC_PULSE_DURATION_4_5ms	(1 << 10) /* pre-LPT */
+#define  PORTC_PULSE_DURATION_6ms	(2 << 10) /* pre-LPT */
+#define  PORTC_PULSE_DURATION_100ms	(3 << 10) /* pre-LPT */
+#define  PORTC_PULSE_DURATION_MASK	(3 << 10) /* pre-LPT */
+#define  PORTC_HOTPLUG_STATUS_MASK	(3 << 8)
+#define  PORTC_HOTPLUG_NO_DETECT	(0 << 8)
+#define  PORTC_HOTPLUG_SHORT_DETECT	(1 << 8)
+#define  PORTC_HOTPLUG_LONG_DETECT	(2 << 8)
+#define  PORTB_HOTPLUG_ENABLE		(1 << 4)
+#define  BXT_DDIB_HPD_INVERT            (1 << 3)
+#define  PORTB_PULSE_DURATION_2ms	(0 << 2) /* pre-LPT */
+#define  PORTB_PULSE_DURATION_4_5ms	(1 << 2) /* pre-LPT */
+#define  PORTB_PULSE_DURATION_6ms	(2 << 2) /* pre-LPT */
+#define  PORTB_PULSE_DURATION_100ms	(3 << 2) /* pre-LPT */
+#define  PORTB_PULSE_DURATION_MASK	(3 << 2) /* pre-LPT */
+#define  PORTB_HOTPLUG_STATUS_MASK	(3 << 0)
+#define  PORTB_HOTPLUG_NO_DETECT	(0 << 0)
+#define  PORTB_HOTPLUG_SHORT_DETECT	(1 << 0)
+#define  PORTB_HOTPLUG_LONG_DETECT	(2 << 0)
+#define  BXT_DDI_HPD_INVERT_MASK	(BXT_DDIA_HPD_INVERT | \
+					BXT_DDIB_HPD_INVERT | \
+					BXT_DDIC_HPD_INVERT)
+
+#define PCH_PORT_HOTPLUG2		_MMIO(0xc403C)	/* SHOTPLUG_CTL2 SPT+ */
+#define  PORTE_HOTPLUG_ENABLE		(1 << 4)
+#define  PORTE_HOTPLUG_STATUS_MASK	(3 << 0)
+#define  PORTE_HOTPLUG_NO_DETECT	(0 << 0)
+#define  PORTE_HOTPLUG_SHORT_DETECT	(1 << 0)
+#define  PORTE_HOTPLUG_LONG_DETECT	(2 << 0)
+
+#define PCH_GPIOA               _MMIO(0xc5010)
+#define PCH_GPIOB               _MMIO(0xc5014)
+#define PCH_GPIOC               _MMIO(0xc5018)
+#define PCH_GPIOD               _MMIO(0xc501c)
+#define PCH_GPIOE               _MMIO(0xc5020)
+#define PCH_GPIOF               _MMIO(0xc5024)
+
+#define PCH_GMBUS0		_MMIO(0xc5100)
+#define PCH_GMBUS1		_MMIO(0xc5104)
+#define PCH_GMBUS2		_MMIO(0xc5108)
+#define PCH_GMBUS3		_MMIO(0xc510c)
+#define PCH_GMBUS4		_MMIO(0xc5110)
+#define PCH_GMBUS5		_MMIO(0xc5120)
+
+#define _PCH_DPLL_A              0xc6014
+#define _PCH_DPLL_B              0xc6018
+#define PCH_DPLL(pll) _MMIO(pll == 0 ? _PCH_DPLL_A : _PCH_DPLL_B)
+
+#define _PCH_FPA0                0xc6040
+#define  FP_CB_TUNE		(0x3<<22)
+#define _PCH_FPA1                0xc6044
+#define _PCH_FPB0                0xc6048
+#define _PCH_FPB1                0xc604c
+#define PCH_FP0(pll) _MMIO(pll == 0 ? _PCH_FPA0 : _PCH_FPB0)
+#define PCH_FP1(pll) _MMIO(pll == 0 ? _PCH_FPA1 : _PCH_FPB1)
+
+#define PCH_DPLL_TEST           _MMIO(0xc606c)
+
+#define PCH_DREF_CONTROL        _MMIO(0xC6200)
+#define  DREF_CONTROL_MASK      0x7fc3
+#define  DREF_CPU_SOURCE_OUTPUT_DISABLE         (0<<13)
+#define  DREF_CPU_SOURCE_OUTPUT_DOWNSPREAD      (2<<13)
+#define  DREF_CPU_SOURCE_OUTPUT_NONSPREAD       (3<<13)
+#define  DREF_CPU_SOURCE_OUTPUT_MASK		(3<<13)
+#define  DREF_SSC_SOURCE_DISABLE                (0<<11)
+#define  DREF_SSC_SOURCE_ENABLE                 (2<<11)
+#define  DREF_SSC_SOURCE_MASK			(3<<11)
+#define  DREF_NONSPREAD_SOURCE_DISABLE          (0<<9)
+#define  DREF_NONSPREAD_CK505_ENABLE		(1<<9)
+#define  DREF_NONSPREAD_SOURCE_ENABLE           (2<<9)
+#define  DREF_NONSPREAD_SOURCE_MASK		(3<<9)
+#define  DREF_SUPERSPREAD_SOURCE_DISABLE        (0<<7)
+#define  DREF_SUPERSPREAD_SOURCE_ENABLE         (2<<7)
+#define  DREF_SUPERSPREAD_SOURCE_MASK		(3<<7)
+#define  DREF_SSC4_DOWNSPREAD                   (0<<6)
+#define  DREF_SSC4_CENTERSPREAD                 (1<<6)
+#define  DREF_SSC1_DISABLE                      (0<<1)
+#define  DREF_SSC1_ENABLE                       (1<<1)
+#define  DREF_SSC4_DISABLE                      (0)
+#define  DREF_SSC4_ENABLE                       (1)
+
+#define PCH_RAWCLK_FREQ         _MMIO(0xc6204)
+#define  FDL_TP1_TIMER_SHIFT    12
+#define  FDL_TP1_TIMER_MASK     (3<<12)
+#define  FDL_TP2_TIMER_SHIFT    10
+#define  FDL_TP2_TIMER_MASK     (3<<10)
+#define  RAWCLK_FREQ_MASK       0x3ff
+
+#define PCH_DPLL_TMR_CFG        _MMIO(0xc6208)
+
+#define PCH_SSC4_PARMS          _MMIO(0xc6210)
+#define PCH_SSC4_AUX_PARMS      _MMIO(0xc6214)
+
+#define PCH_DPLL_SEL		_MMIO(0xc7000)
+#define	 TRANS_DPLLB_SEL(pipe)		(1 << ((pipe) * 4))
+#define	 TRANS_DPLLA_SEL(pipe)		0
+#define  TRANS_DPLL_ENABLE(pipe)	(1 << ((pipe) * 4 + 3))
+
+/* transcoder */
+
+#define _PCH_TRANS_HTOTAL_A		0xe0000
+#define  TRANS_HTOTAL_SHIFT		16
+#define  TRANS_HACTIVE_SHIFT		0
+#define _PCH_TRANS_HBLANK_A		0xe0004
+#define  TRANS_HBLANK_END_SHIFT		16
+#define  TRANS_HBLANK_START_SHIFT	0
+#define _PCH_TRANS_HSYNC_A		0xe0008
+#define  TRANS_HSYNC_END_SHIFT		16
+#define  TRANS_HSYNC_START_SHIFT	0
+#define _PCH_TRANS_VTOTAL_A		0xe000c
+#define  TRANS_VTOTAL_SHIFT		16
+#define  TRANS_VACTIVE_SHIFT		0
+#define _PCH_TRANS_VBLANK_A		0xe0010
+#define  TRANS_VBLANK_END_SHIFT		16
+#define  TRANS_VBLANK_START_SHIFT	0
+#define _PCH_TRANS_VSYNC_A		0xe0014
+#define  TRANS_VSYNC_END_SHIFT	 	16
+#define  TRANS_VSYNC_START_SHIFT	0
+#define _PCH_TRANS_VSYNCSHIFT_A		0xe0028
+
+#define _PCH_TRANSA_DATA_M1	0xe0030
+#define _PCH_TRANSA_DATA_N1	0xe0034
+#define _PCH_TRANSA_DATA_M2	0xe0038
+#define _PCH_TRANSA_DATA_N2	0xe003c
+#define _PCH_TRANSA_LINK_M1	0xe0040
+#define _PCH_TRANSA_LINK_N1	0xe0044
+#define _PCH_TRANSA_LINK_M2	0xe0048
+#define _PCH_TRANSA_LINK_N2	0xe004c
+
+/* Per-transcoder DIP controls (PCH) */
+#define _VIDEO_DIP_CTL_A         0xe0200
+#define _VIDEO_DIP_DATA_A        0xe0208
+#define _VIDEO_DIP_GCP_A         0xe0210
+#define  GCP_COLOR_INDICATION		(1 << 2)
+#define  GCP_DEFAULT_PHASE_ENABLE	(1 << 1)
+#define  GCP_AV_MUTE			(1 << 0)
+
+#define _VIDEO_DIP_CTL_B         0xe1200
+#define _VIDEO_DIP_DATA_B        0xe1208
+#define _VIDEO_DIP_GCP_B         0xe1210
+
+#define TVIDEO_DIP_CTL(pipe) _MMIO_PIPE(pipe, _VIDEO_DIP_CTL_A, _VIDEO_DIP_CTL_B)
+#define TVIDEO_DIP_DATA(pipe) _MMIO_PIPE(pipe, _VIDEO_DIP_DATA_A, _VIDEO_DIP_DATA_B)
+#define TVIDEO_DIP_GCP(pipe) _MMIO_PIPE(pipe, _VIDEO_DIP_GCP_A, _VIDEO_DIP_GCP_B)
+
+/* Per-transcoder DIP controls (VLV) */
+#define _VLV_VIDEO_DIP_CTL_A		(VLV_DISPLAY_BASE + 0x60200)
+#define _VLV_VIDEO_DIP_DATA_A		(VLV_DISPLAY_BASE + 0x60208)
+#define _VLV_VIDEO_DIP_GDCP_PAYLOAD_A	(VLV_DISPLAY_BASE + 0x60210)
+
+#define _VLV_VIDEO_DIP_CTL_B		(VLV_DISPLAY_BASE + 0x61170)
+#define _VLV_VIDEO_DIP_DATA_B		(VLV_DISPLAY_BASE + 0x61174)
+#define _VLV_VIDEO_DIP_GDCP_PAYLOAD_B	(VLV_DISPLAY_BASE + 0x61178)
+
+#define _CHV_VIDEO_DIP_CTL_C		(VLV_DISPLAY_BASE + 0x611f0)
+#define _CHV_VIDEO_DIP_DATA_C		(VLV_DISPLAY_BASE + 0x611f4)
+#define _CHV_VIDEO_DIP_GDCP_PAYLOAD_C	(VLV_DISPLAY_BASE + 0x611f8)
+
+#define VLV_TVIDEO_DIP_CTL(pipe) \
+	_MMIO_PIPE3((pipe), _VLV_VIDEO_DIP_CTL_A, \
+	       _VLV_VIDEO_DIP_CTL_B, _CHV_VIDEO_DIP_CTL_C)
+#define VLV_TVIDEO_DIP_DATA(pipe) \
+	_MMIO_PIPE3((pipe), _VLV_VIDEO_DIP_DATA_A, \
+	       _VLV_VIDEO_DIP_DATA_B, _CHV_VIDEO_DIP_DATA_C)
+#define VLV_TVIDEO_DIP_GCP(pipe) \
+	_MMIO_PIPE3((pipe), _VLV_VIDEO_DIP_GDCP_PAYLOAD_A, \
+		_VLV_VIDEO_DIP_GDCP_PAYLOAD_B, _CHV_VIDEO_DIP_GDCP_PAYLOAD_C)
+
+/* Haswell DIP controls */
+
+#define _HSW_VIDEO_DIP_CTL_A		0x60200
+#define _HSW_VIDEO_DIP_AVI_DATA_A	0x60220
+#define _HSW_VIDEO_DIP_VS_DATA_A	0x60260
+#define _HSW_VIDEO_DIP_SPD_DATA_A	0x602A0
+#define _HSW_VIDEO_DIP_GMP_DATA_A	0x602E0
+#define _HSW_VIDEO_DIP_VSC_DATA_A	0x60320
+#define _HSW_VIDEO_DIP_AVI_ECC_A	0x60240
+#define _HSW_VIDEO_DIP_VS_ECC_A		0x60280
+#define _HSW_VIDEO_DIP_SPD_ECC_A	0x602C0
+#define _HSW_VIDEO_DIP_GMP_ECC_A	0x60300
+#define _HSW_VIDEO_DIP_VSC_ECC_A	0x60344
+#define _HSW_VIDEO_DIP_GCP_A		0x60210
+
+#define _HSW_VIDEO_DIP_CTL_B		0x61200
+#define _HSW_VIDEO_DIP_AVI_DATA_B	0x61220
+#define _HSW_VIDEO_DIP_VS_DATA_B	0x61260
+#define _HSW_VIDEO_DIP_SPD_DATA_B	0x612A0
+#define _HSW_VIDEO_DIP_GMP_DATA_B	0x612E0
+#define _HSW_VIDEO_DIP_VSC_DATA_B	0x61320
+#define _HSW_VIDEO_DIP_BVI_ECC_B	0x61240
+#define _HSW_VIDEO_DIP_VS_ECC_B		0x61280
+#define _HSW_VIDEO_DIP_SPD_ECC_B	0x612C0
+#define _HSW_VIDEO_DIP_GMP_ECC_B	0x61300
+#define _HSW_VIDEO_DIP_VSC_ECC_B	0x61344
+#define _HSW_VIDEO_DIP_GCP_B		0x61210
+
+#define HSW_TVIDEO_DIP_CTL(trans)		_MMIO_TRANS2(trans, _HSW_VIDEO_DIP_CTL_A)
+#define HSW_TVIDEO_DIP_AVI_DATA(trans, i)	_MMIO_TRANS2(trans, _HSW_VIDEO_DIP_AVI_DATA_A + (i) * 4)
+#define HSW_TVIDEO_DIP_VS_DATA(trans, i)	_MMIO_TRANS2(trans, _HSW_VIDEO_DIP_VS_DATA_A + (i) * 4)
+#define HSW_TVIDEO_DIP_SPD_DATA(trans, i)	_MMIO_TRANS2(trans, _HSW_VIDEO_DIP_SPD_DATA_A + (i) * 4)
+#define HSW_TVIDEO_DIP_GCP(trans)		_MMIO_TRANS2(trans, _HSW_VIDEO_DIP_GCP_A)
+#define HSW_TVIDEO_DIP_VSC_DATA(trans, i)	_MMIO_TRANS2(trans, _HSW_VIDEO_DIP_VSC_DATA_A + (i) * 4)
+
+#define _HSW_STEREO_3D_CTL_A		0x70020
+#define   S3D_ENABLE			(1<<31)
+#define _HSW_STEREO_3D_CTL_B		0x71020
+
+#define HSW_STEREO_3D_CTL(trans)	_MMIO_PIPE2(trans, _HSW_STEREO_3D_CTL_A)
+
+#define _PCH_TRANS_HTOTAL_B          0xe1000
+#define _PCH_TRANS_HBLANK_B          0xe1004
+#define _PCH_TRANS_HSYNC_B           0xe1008
+#define _PCH_TRANS_VTOTAL_B          0xe100c
+#define _PCH_TRANS_VBLANK_B          0xe1010
+#define _PCH_TRANS_VSYNC_B           0xe1014
+#define _PCH_TRANS_VSYNCSHIFT_B 0xe1028
+
+#define PCH_TRANS_HTOTAL(pipe)		_MMIO_PIPE(pipe, _PCH_TRANS_HTOTAL_A, _PCH_TRANS_HTOTAL_B)
+#define PCH_TRANS_HBLANK(pipe)		_MMIO_PIPE(pipe, _PCH_TRANS_HBLANK_A, _PCH_TRANS_HBLANK_B)
+#define PCH_TRANS_HSYNC(pipe)		_MMIO_PIPE(pipe, _PCH_TRANS_HSYNC_A, _PCH_TRANS_HSYNC_B)
+#define PCH_TRANS_VTOTAL(pipe)		_MMIO_PIPE(pipe, _PCH_TRANS_VTOTAL_A, _PCH_TRANS_VTOTAL_B)
+#define PCH_TRANS_VBLANK(pipe)		_MMIO_PIPE(pipe, _PCH_TRANS_VBLANK_A, _PCH_TRANS_VBLANK_B)
+#define PCH_TRANS_VSYNC(pipe)		_MMIO_PIPE(pipe, _PCH_TRANS_VSYNC_A, _PCH_TRANS_VSYNC_B)
+#define PCH_TRANS_VSYNCSHIFT(pipe)	_MMIO_PIPE(pipe, _PCH_TRANS_VSYNCSHIFT_A, _PCH_TRANS_VSYNCSHIFT_B)
+
+#define _PCH_TRANSB_DATA_M1	0xe1030
+#define _PCH_TRANSB_DATA_N1	0xe1034
+#define _PCH_TRANSB_DATA_M2	0xe1038
+#define _PCH_TRANSB_DATA_N2	0xe103c
+#define _PCH_TRANSB_LINK_M1	0xe1040
+#define _PCH_TRANSB_LINK_N1	0xe1044
+#define _PCH_TRANSB_LINK_M2	0xe1048
+#define _PCH_TRANSB_LINK_N2	0xe104c
+
+#define PCH_TRANS_DATA_M1(pipe)	_MMIO_PIPE(pipe, _PCH_TRANSA_DATA_M1, _PCH_TRANSB_DATA_M1)
+#define PCH_TRANS_DATA_N1(pipe)	_MMIO_PIPE(pipe, _PCH_TRANSA_DATA_N1, _PCH_TRANSB_DATA_N1)
+#define PCH_TRANS_DATA_M2(pipe)	_MMIO_PIPE(pipe, _PCH_TRANSA_DATA_M2, _PCH_TRANSB_DATA_M2)
+#define PCH_TRANS_DATA_N2(pipe)	_MMIO_PIPE(pipe, _PCH_TRANSA_DATA_N2, _PCH_TRANSB_DATA_N2)
+#define PCH_TRANS_LINK_M1(pipe)	_MMIO_PIPE(pipe, _PCH_TRANSA_LINK_M1, _PCH_TRANSB_LINK_M1)
+#define PCH_TRANS_LINK_N1(pipe)	_MMIO_PIPE(pipe, _PCH_TRANSA_LINK_N1, _PCH_TRANSB_LINK_N1)
+#define PCH_TRANS_LINK_M2(pipe)	_MMIO_PIPE(pipe, _PCH_TRANSA_LINK_M2, _PCH_TRANSB_LINK_M2)
+#define PCH_TRANS_LINK_N2(pipe)	_MMIO_PIPE(pipe, _PCH_TRANSA_LINK_N2, _PCH_TRANSB_LINK_N2)
+
+#define _PCH_TRANSACONF              0xf0008
+#define _PCH_TRANSBCONF              0xf1008
+#define PCH_TRANSCONF(pipe)	_MMIO_PIPE(pipe, _PCH_TRANSACONF, _PCH_TRANSBCONF)
+#define LPT_TRANSCONF		PCH_TRANSCONF(PIPE_A) /* lpt has only one transcoder */
+#define  TRANS_DISABLE          (0<<31)
+#define  TRANS_ENABLE           (1<<31)
+#define  TRANS_STATE_MASK       (1<<30)
+#define  TRANS_STATE_DISABLE    (0<<30)
+#define  TRANS_STATE_ENABLE     (1<<30)
+#define  TRANS_FSYNC_DELAY_HB1  (0<<27)
+#define  TRANS_FSYNC_DELAY_HB2  (1<<27)
+#define  TRANS_FSYNC_DELAY_HB3  (2<<27)
+#define  TRANS_FSYNC_DELAY_HB4  (3<<27)
+#define  TRANS_INTERLACE_MASK   (7<<21)
+#define  TRANS_PROGRESSIVE      (0<<21)
+#define  TRANS_INTERLACED       (3<<21)
+#define  TRANS_LEGACY_INTERLACED_ILK (2<<21)
+#define  TRANS_8BPC             (0<<5)
+#define  TRANS_10BPC            (1<<5)
+#define  TRANS_6BPC             (2<<5)
+#define  TRANS_12BPC            (3<<5)
+
+#define _TRANSA_CHICKEN1	 0xf0060
+#define _TRANSB_CHICKEN1	 0xf1060
+#define TRANS_CHICKEN1(pipe)	_MMIO_PIPE(pipe, _TRANSA_CHICKEN1, _TRANSB_CHICKEN1)
+#define  TRANS_CHICKEN1_HDMIUNIT_GC_DISABLE	(1<<10)
+#define  TRANS_CHICKEN1_DP0UNIT_GC_DISABLE	(1<<4)
+#define _TRANSA_CHICKEN2	 0xf0064
+#define _TRANSB_CHICKEN2	 0xf1064
+#define TRANS_CHICKEN2(pipe)	_MMIO_PIPE(pipe, _TRANSA_CHICKEN2, _TRANSB_CHICKEN2)
+#define  TRANS_CHICKEN2_TIMING_OVERRIDE			(1<<31)
+#define  TRANS_CHICKEN2_FDI_POLARITY_REVERSED		(1<<29)
+#define  TRANS_CHICKEN2_FRAME_START_DELAY_MASK		(3<<27)
+#define  TRANS_CHICKEN2_DISABLE_DEEP_COLOR_COUNTER	(1<<26)
+#define  TRANS_CHICKEN2_DISABLE_DEEP_COLOR_MODESWITCH	(1<<25)
+
+#define SOUTH_CHICKEN1		_MMIO(0xc2000)
+#define  FDIA_PHASE_SYNC_SHIFT_OVR	19
+#define  FDIA_PHASE_SYNC_SHIFT_EN	18
+#define  FDI_PHASE_SYNC_OVR(pipe) (1<<(FDIA_PHASE_SYNC_SHIFT_OVR - ((pipe) * 2)))
+#define  FDI_PHASE_SYNC_EN(pipe) (1<<(FDIA_PHASE_SYNC_SHIFT_EN - ((pipe) * 2)))
+#define  FDI_BC_BIFURCATION_SELECT	(1 << 12)
+#define  SPT_PWM_GRANULARITY		(1<<0)
+#define SOUTH_CHICKEN2		_MMIO(0xc2004)
+#define  FDI_MPHY_IOSFSB_RESET_STATUS	(1<<13)
+#define  FDI_MPHY_IOSFSB_RESET_CTL	(1<<12)
+#define  LPT_PWM_GRANULARITY		(1<<5)
+#define  DPLS_EDP_PPS_FIX_DIS		(1<<0)
+
+#define _FDI_RXA_CHICKEN        0xc200c
+#define _FDI_RXB_CHICKEN        0xc2010
+#define  FDI_RX_PHASE_SYNC_POINTER_OVR	(1<<1)
+#define  FDI_RX_PHASE_SYNC_POINTER_EN	(1<<0)
+#define FDI_RX_CHICKEN(pipe)	_MMIO_PIPE(pipe, _FDI_RXA_CHICKEN, _FDI_RXB_CHICKEN)
+
+#define SOUTH_DSPCLK_GATE_D	_MMIO(0xc2020)
+#define  PCH_DPLUNIT_CLOCK_GATE_DISABLE (1<<30)
+#define  PCH_DPLSUNIT_CLOCK_GATE_DISABLE (1<<29)
+#define  PCH_CPUNIT_CLOCK_GATE_DISABLE (1<<14)
+#define  PCH_LP_PARTITION_LEVEL_DISABLE  (1<<12)
+
+/* CPU: FDI_TX */
+#define _FDI_TXA_CTL            0x60100
+#define _FDI_TXB_CTL            0x61100
+#define FDI_TX_CTL(pipe)	_MMIO_PIPE(pipe, _FDI_TXA_CTL, _FDI_TXB_CTL)
+#define  FDI_TX_DISABLE         (0<<31)
+#define  FDI_TX_ENABLE          (1<<31)
+#define  FDI_LINK_TRAIN_PATTERN_1       (0<<28)
+#define  FDI_LINK_TRAIN_PATTERN_2       (1<<28)
+#define  FDI_LINK_TRAIN_PATTERN_IDLE    (2<<28)
+#define  FDI_LINK_TRAIN_NONE            (3<<28)
+#define  FDI_LINK_TRAIN_VOLTAGE_0_4V    (0<<25)
+#define  FDI_LINK_TRAIN_VOLTAGE_0_6V    (1<<25)
+#define  FDI_LINK_TRAIN_VOLTAGE_0_8V    (2<<25)
+#define  FDI_LINK_TRAIN_VOLTAGE_1_2V    (3<<25)
+#define  FDI_LINK_TRAIN_PRE_EMPHASIS_NONE (0<<22)
+#define  FDI_LINK_TRAIN_PRE_EMPHASIS_1_5X (1<<22)
+#define  FDI_LINK_TRAIN_PRE_EMPHASIS_2X   (2<<22)
+#define  FDI_LINK_TRAIN_PRE_EMPHASIS_3X   (3<<22)
+/* ILK always use 400mV 0dB for voltage swing and pre-emphasis level.
+   SNB has different settings. */
+/* SNB A-stepping */
+#define  FDI_LINK_TRAIN_400MV_0DB_SNB_A		(0x38<<22)
+#define  FDI_LINK_TRAIN_400MV_6DB_SNB_A		(0x02<<22)
+#define  FDI_LINK_TRAIN_600MV_3_5DB_SNB_A	(0x01<<22)
+#define  FDI_LINK_TRAIN_800MV_0DB_SNB_A		(0x0<<22)
+/* SNB B-stepping */
+#define  FDI_LINK_TRAIN_400MV_0DB_SNB_B		(0x0<<22)
+#define  FDI_LINK_TRAIN_400MV_6DB_SNB_B		(0x3a<<22)
+#define  FDI_LINK_TRAIN_600MV_3_5DB_SNB_B	(0x39<<22)
+#define  FDI_LINK_TRAIN_800MV_0DB_SNB_B		(0x38<<22)
+#define  FDI_LINK_TRAIN_VOL_EMP_MASK		(0x3f<<22)
+#define  FDI_DP_PORT_WIDTH_SHIFT		19
+#define  FDI_DP_PORT_WIDTH_MASK			(7 << FDI_DP_PORT_WIDTH_SHIFT)
+#define  FDI_DP_PORT_WIDTH(width)           (((width) - 1) << FDI_DP_PORT_WIDTH_SHIFT)
+#define  FDI_TX_ENHANCE_FRAME_ENABLE    (1<<18)
+/* Ironlake: hardwired to 1 */
+#define  FDI_TX_PLL_ENABLE              (1<<14)
+
+/* Ivybridge has different bits for lolz */
+#define  FDI_LINK_TRAIN_PATTERN_1_IVB       (0<<8)
+#define  FDI_LINK_TRAIN_PATTERN_2_IVB       (1<<8)
+#define  FDI_LINK_TRAIN_PATTERN_IDLE_IVB    (2<<8)
+#define  FDI_LINK_TRAIN_NONE_IVB            (3<<8)
+
+/* both Tx and Rx */
+#define  FDI_COMPOSITE_SYNC		(1<<11)
+#define  FDI_LINK_TRAIN_AUTO		(1<<10)
+#define  FDI_SCRAMBLING_ENABLE          (0<<7)
+#define  FDI_SCRAMBLING_DISABLE         (1<<7)
+
+/* FDI_RX, FDI_X is hard-wired to Transcoder_X */
+#define _FDI_RXA_CTL             0xf000c
+#define _FDI_RXB_CTL             0xf100c
+#define FDI_RX_CTL(pipe)	_MMIO_PIPE(pipe, _FDI_RXA_CTL, _FDI_RXB_CTL)
+#define  FDI_RX_ENABLE          (1<<31)
+/* train, dp width same as FDI_TX */
+#define  FDI_FS_ERRC_ENABLE		(1<<27)
+#define  FDI_FE_ERRC_ENABLE		(1<<26)
+#define  FDI_RX_POLARITY_REVERSED_LPT	(1<<16)
+#define  FDI_8BPC                       (0<<16)
+#define  FDI_10BPC                      (1<<16)
+#define  FDI_6BPC                       (2<<16)
+#define  FDI_12BPC                      (3<<16)
+#define  FDI_RX_LINK_REVERSAL_OVERRIDE  (1<<15)
+#define  FDI_DMI_LINK_REVERSE_MASK      (1<<14)
+#define  FDI_RX_PLL_ENABLE              (1<<13)
+#define  FDI_FS_ERR_CORRECT_ENABLE      (1<<11)
+#define  FDI_FE_ERR_CORRECT_ENABLE      (1<<10)
+#define  FDI_FS_ERR_REPORT_ENABLE       (1<<9)
+#define  FDI_FE_ERR_REPORT_ENABLE       (1<<8)
+#define  FDI_RX_ENHANCE_FRAME_ENABLE    (1<<6)
+#define  FDI_PCDCLK	                (1<<4)
+/* CPT */
+#define  FDI_AUTO_TRAINING			(1<<10)
+#define  FDI_LINK_TRAIN_PATTERN_1_CPT		(0<<8)
+#define  FDI_LINK_TRAIN_PATTERN_2_CPT		(1<<8)
+#define  FDI_LINK_TRAIN_PATTERN_IDLE_CPT	(2<<8)
+#define  FDI_LINK_TRAIN_NORMAL_CPT		(3<<8)
+#define  FDI_LINK_TRAIN_PATTERN_MASK_CPT	(3<<8)
+
+#define _FDI_RXA_MISC			0xf0010
+#define _FDI_RXB_MISC			0xf1010
+#define  FDI_RX_PWRDN_LANE1_MASK	(3<<26)
+#define  FDI_RX_PWRDN_LANE1_VAL(x)	((x)<<26)
+#define  FDI_RX_PWRDN_LANE0_MASK	(3<<24)
+#define  FDI_RX_PWRDN_LANE0_VAL(x)	((x)<<24)
+#define  FDI_RX_TP1_TO_TP2_48		(2<<20)
+#define  FDI_RX_TP1_TO_TP2_64		(3<<20)
+#define  FDI_RX_FDI_DELAY_90		(0x90<<0)
+#define FDI_RX_MISC(pipe)	_MMIO_PIPE(pipe, _FDI_RXA_MISC, _FDI_RXB_MISC)
+
+#define _FDI_RXA_TUSIZE1        0xf0030
+#define _FDI_RXA_TUSIZE2        0xf0038
+#define _FDI_RXB_TUSIZE1        0xf1030
+#define _FDI_RXB_TUSIZE2        0xf1038
+#define FDI_RX_TUSIZE1(pipe)	_MMIO_PIPE(pipe, _FDI_RXA_TUSIZE1, _FDI_RXB_TUSIZE1)
+#define FDI_RX_TUSIZE2(pipe)	_MMIO_PIPE(pipe, _FDI_RXA_TUSIZE2, _FDI_RXB_TUSIZE2)
+
+/* FDI_RX interrupt register format */
+#define FDI_RX_INTER_LANE_ALIGN         (1<<10)
+#define FDI_RX_SYMBOL_LOCK              (1<<9) /* train 2 */
+#define FDI_RX_BIT_LOCK                 (1<<8) /* train 1 */
+#define FDI_RX_TRAIN_PATTERN_2_FAIL     (1<<7)
+#define FDI_RX_FS_CODE_ERR              (1<<6)
+#define FDI_RX_FE_CODE_ERR              (1<<5)
+#define FDI_RX_SYMBOL_ERR_RATE_ABOVE    (1<<4)
+#define FDI_RX_HDCP_LINK_FAIL           (1<<3)
+#define FDI_RX_PIXEL_FIFO_OVERFLOW      (1<<2)
+#define FDI_RX_CROSS_CLOCK_OVERFLOW     (1<<1)
+#define FDI_RX_SYMBOL_QUEUE_OVERFLOW    (1<<0)
+
+#define _FDI_RXA_IIR            0xf0014
+#define _FDI_RXA_IMR            0xf0018
+#define _FDI_RXB_IIR            0xf1014
+#define _FDI_RXB_IMR            0xf1018
+#define FDI_RX_IIR(pipe)	_MMIO_PIPE(pipe, _FDI_RXA_IIR, _FDI_RXB_IIR)
+#define FDI_RX_IMR(pipe)	_MMIO_PIPE(pipe, _FDI_RXA_IMR, _FDI_RXB_IMR)
+
+#define FDI_PLL_CTL_1           _MMIO(0xfe000)
+#define FDI_PLL_CTL_2           _MMIO(0xfe004)
+
+#define PCH_LVDS	_MMIO(0xe1180)
+#define  LVDS_DETECTED	(1 << 1)
+
+/* vlv has 2 sets of panel control regs. */
+#define _PIPEA_PP_STATUS         (VLV_DISPLAY_BASE + 0x61200)
+#define _PIPEA_PP_CONTROL        (VLV_DISPLAY_BASE + 0x61204)
+#define _PIPEA_PP_ON_DELAYS      (VLV_DISPLAY_BASE + 0x61208)
+#define  PANEL_PORT_SELECT_VLV(port)	((port) << 30)
+#define _PIPEA_PP_OFF_DELAYS     (VLV_DISPLAY_BASE + 0x6120c)
+#define _PIPEA_PP_DIVISOR        (VLV_DISPLAY_BASE + 0x61210)
+
+#define _PIPEB_PP_STATUS         (VLV_DISPLAY_BASE + 0x61300)
+#define _PIPEB_PP_CONTROL        (VLV_DISPLAY_BASE + 0x61304)
+#define _PIPEB_PP_ON_DELAYS      (VLV_DISPLAY_BASE + 0x61308)
+#define _PIPEB_PP_OFF_DELAYS     (VLV_DISPLAY_BASE + 0x6130c)
+#define _PIPEB_PP_DIVISOR        (VLV_DISPLAY_BASE + 0x61310)
+
+#define VLV_PIPE_PP_STATUS(pipe)	_MMIO_PIPE(pipe, _PIPEA_PP_STATUS, _PIPEB_PP_STATUS)
+#define VLV_PIPE_PP_CONTROL(pipe)	_MMIO_PIPE(pipe, _PIPEA_PP_CONTROL, _PIPEB_PP_CONTROL)
+#define VLV_PIPE_PP_ON_DELAYS(pipe)	_MMIO_PIPE(pipe, _PIPEA_PP_ON_DELAYS, _PIPEB_PP_ON_DELAYS)
+#define VLV_PIPE_PP_OFF_DELAYS(pipe)	_MMIO_PIPE(pipe, _PIPEA_PP_OFF_DELAYS, _PIPEB_PP_OFF_DELAYS)
+#define VLV_PIPE_PP_DIVISOR(pipe)	_MMIO_PIPE(pipe, _PIPEA_PP_DIVISOR, _PIPEB_PP_DIVISOR)
+
+#define _PCH_PP_STATUS		0xc7200
+#define _PCH_PP_CONTROL		0xc7204
+#define  PANEL_UNLOCK_REGS	(0xabcd << 16)
+#define  PANEL_UNLOCK_MASK	(0xffff << 16)
+#define  BXT_POWER_CYCLE_DELAY_MASK	(0x1f0)
+#define  BXT_POWER_CYCLE_DELAY_SHIFT	4
+#define  EDP_FORCE_VDD		(1 << 3)
+#define  EDP_BLC_ENABLE		(1 << 2)
+#define  PANEL_POWER_RESET	(1 << 1)
+#define  PANEL_POWER_OFF	(0 << 0)
+#define  PANEL_POWER_ON		(1 << 0)
+#define _PCH_PP_ON_DELAYS	0xc7208
+#define  PANEL_PORT_SELECT_MASK	(3 << 30)
+#define  PANEL_PORT_SELECT_LVDS	(0 << 30)
+#define  PANEL_PORT_SELECT_DPA	(1 << 30)
+#define  PANEL_PORT_SELECT_DPC	(2 << 30)
+#define  PANEL_PORT_SELECT_DPD	(3 << 30)
+#define  PANEL_POWER_UP_DELAY_MASK	(0x1fff0000)
+#define  PANEL_POWER_UP_DELAY_SHIFT	16
+#define  PANEL_LIGHT_ON_DELAY_MASK	(0x1fff)
+#define  PANEL_LIGHT_ON_DELAY_SHIFT	0
+
+#define _PCH_PP_OFF_DELAYS		0xc720c
+#define  PANEL_POWER_DOWN_DELAY_MASK	(0x1fff0000)
+#define  PANEL_POWER_DOWN_DELAY_SHIFT	16
+#define  PANEL_LIGHT_OFF_DELAY_MASK	(0x1fff)
+#define  PANEL_LIGHT_OFF_DELAY_SHIFT	0
+
+#define _PCH_PP_DIVISOR			0xc7210
+#define  PP_REFERENCE_DIVIDER_MASK	(0xffffff00)
+#define  PP_REFERENCE_DIVIDER_SHIFT	8
+#define  PANEL_POWER_CYCLE_DELAY_MASK	(0x1f)
+#define  PANEL_POWER_CYCLE_DELAY_SHIFT	0
+
+#define PCH_PP_STATUS			_MMIO(_PCH_PP_STATUS)
+#define PCH_PP_CONTROL			_MMIO(_PCH_PP_CONTROL)
+#define PCH_PP_ON_DELAYS		_MMIO(_PCH_PP_ON_DELAYS)
+#define PCH_PP_OFF_DELAYS		_MMIO(_PCH_PP_OFF_DELAYS)
+#define PCH_PP_DIVISOR			_MMIO(_PCH_PP_DIVISOR)
+
+/* BXT PPS changes - 2nd set of PPS registers */
+#define _BXT_PP_STATUS2 	0xc7300
+#define _BXT_PP_CONTROL2 	0xc7304
+#define _BXT_PP_ON_DELAYS2	0xc7308
+#define _BXT_PP_OFF_DELAYS2	0xc730c
+
+#define BXT_PP_STATUS(n)	_MMIO_PIPE(n, _PCH_PP_STATUS, _BXT_PP_STATUS2)
+#define BXT_PP_CONTROL(n)	_MMIO_PIPE(n, _PCH_PP_CONTROL, _BXT_PP_CONTROL2)
+#define BXT_PP_ON_DELAYS(n)	_MMIO_PIPE(n, _PCH_PP_ON_DELAYS, _BXT_PP_ON_DELAYS2)
+#define BXT_PP_OFF_DELAYS(n)	_MMIO_PIPE(n, _PCH_PP_OFF_DELAYS, _BXT_PP_OFF_DELAYS2)
+
+#define _PCH_DP_B		0xe4100
+#define PCH_DP_B		_MMIO(_PCH_DP_B)
+#define _PCH_DPB_AUX_CH_CTL	0xe4110
+#define _PCH_DPB_AUX_CH_DATA1	0xe4114
+#define _PCH_DPB_AUX_CH_DATA2	0xe4118
+#define _PCH_DPB_AUX_CH_DATA3	0xe411c
+#define _PCH_DPB_AUX_CH_DATA4	0xe4120
+#define _PCH_DPB_AUX_CH_DATA5	0xe4124
+
+#define _PCH_DP_C		0xe4200
+#define PCH_DP_C		_MMIO(_PCH_DP_C)
+#define _PCH_DPC_AUX_CH_CTL	0xe4210
+#define _PCH_DPC_AUX_CH_DATA1	0xe4214
+#define _PCH_DPC_AUX_CH_DATA2	0xe4218
+#define _PCH_DPC_AUX_CH_DATA3	0xe421c
+#define _PCH_DPC_AUX_CH_DATA4	0xe4220
+#define _PCH_DPC_AUX_CH_DATA5	0xe4224
+
+#define _PCH_DP_D		0xe4300
+#define PCH_DP_D		_MMIO(_PCH_DP_D)
+#define _PCH_DPD_AUX_CH_CTL	0xe4310
+#define _PCH_DPD_AUX_CH_DATA1	0xe4314
+#define _PCH_DPD_AUX_CH_DATA2	0xe4318
+#define _PCH_DPD_AUX_CH_DATA3	0xe431c
+#define _PCH_DPD_AUX_CH_DATA4	0xe4320
+#define _PCH_DPD_AUX_CH_DATA5	0xe4324
+
+#define PCH_DP_AUX_CH_CTL(port)		_MMIO_PORT((port) - PORT_B, _PCH_DPB_AUX_CH_CTL, _PCH_DPC_AUX_CH_CTL)
+#define PCH_DP_AUX_CH_DATA(port, i)	_MMIO(_PORT((port) - PORT_B, _PCH_DPB_AUX_CH_DATA1, _PCH_DPC_AUX_CH_DATA1) + (i) * 4) /* 5 registers */
+
+/* CPT */
+#define  PORT_TRANS_A_SEL_CPT	0
+#define  PORT_TRANS_B_SEL_CPT	(1<<29)
+#define  PORT_TRANS_C_SEL_CPT	(2<<29)
+#define  PORT_TRANS_SEL_MASK	(3<<29)
+#define  PORT_TRANS_SEL_CPT(pipe)	((pipe) << 29)
+#define  PORT_TO_PIPE(val)	(((val) & (1<<30)) >> 30)
+#define  PORT_TO_PIPE_CPT(val)	(((val) & PORT_TRANS_SEL_MASK) >> 29)
+#define  SDVO_PORT_TO_PIPE_CHV(val)	(((val) & (3<<24)) >> 24)
+#define  DP_PORT_TO_PIPE_CHV(val)	(((val) & (3<<16)) >> 16)
+
+#define _TRANS_DP_CTL_A		0xe0300
+#define _TRANS_DP_CTL_B		0xe1300
+#define _TRANS_DP_CTL_C		0xe2300
+#define TRANS_DP_CTL(pipe)	_MMIO_PIPE(pipe, _TRANS_DP_CTL_A, _TRANS_DP_CTL_B)
+#define  TRANS_DP_OUTPUT_ENABLE	(1<<31)
+#define  TRANS_DP_PORT_SEL_B	(0<<29)
+#define  TRANS_DP_PORT_SEL_C	(1<<29)
+#define  TRANS_DP_PORT_SEL_D	(2<<29)
+#define  TRANS_DP_PORT_SEL_NONE	(3<<29)
+#define  TRANS_DP_PORT_SEL_MASK	(3<<29)
+#define  TRANS_DP_PIPE_TO_PORT(val)	((((val) & TRANS_DP_PORT_SEL_MASK) >> 29) + PORT_B)
+#define  TRANS_DP_AUDIO_ONLY	(1<<26)
+#define  TRANS_DP_ENH_FRAMING	(1<<18)
+#define  TRANS_DP_8BPC		(0<<9)
+#define  TRANS_DP_10BPC		(1<<9)
+#define  TRANS_DP_6BPC		(2<<9)
+#define  TRANS_DP_12BPC		(3<<9)
+#define  TRANS_DP_BPC_MASK	(3<<9)
+#define  TRANS_DP_VSYNC_ACTIVE_HIGH	(1<<4)
+#define  TRANS_DP_VSYNC_ACTIVE_LOW	0
+#define  TRANS_DP_HSYNC_ACTIVE_HIGH	(1<<3)
+#define  TRANS_DP_HSYNC_ACTIVE_LOW	0
+#define  TRANS_DP_SYNC_MASK	(3<<3)
+
+/* SNB eDP training params */
+/* SNB A-stepping */
+#define  EDP_LINK_TRAIN_400MV_0DB_SNB_A		(0x38<<22)
+#define  EDP_LINK_TRAIN_400MV_6DB_SNB_A		(0x02<<22)
+#define  EDP_LINK_TRAIN_600MV_3_5DB_SNB_A	(0x01<<22)
+#define  EDP_LINK_TRAIN_800MV_0DB_SNB_A		(0x0<<22)
+/* SNB B-stepping */
+#define  EDP_LINK_TRAIN_400_600MV_0DB_SNB_B	(0x0<<22)
+#define  EDP_LINK_TRAIN_400MV_3_5DB_SNB_B	(0x1<<22)
+#define  EDP_LINK_TRAIN_400_600MV_6DB_SNB_B	(0x3a<<22)
+#define  EDP_LINK_TRAIN_600_800MV_3_5DB_SNB_B	(0x39<<22)
+#define  EDP_LINK_TRAIN_800_1200MV_0DB_SNB_B	(0x38<<22)
+#define  EDP_LINK_TRAIN_VOL_EMP_MASK_SNB	(0x3f<<22)
+
+/* IVB */
+#define EDP_LINK_TRAIN_400MV_0DB_IVB		(0x24 <<22)
+#define EDP_LINK_TRAIN_400MV_3_5DB_IVB		(0x2a <<22)
+#define EDP_LINK_TRAIN_400MV_6DB_IVB		(0x2f <<22)
+#define EDP_LINK_TRAIN_600MV_0DB_IVB		(0x30 <<22)
+#define EDP_LINK_TRAIN_600MV_3_5DB_IVB		(0x36 <<22)
+#define EDP_LINK_TRAIN_800MV_0DB_IVB		(0x38 <<22)
+#define EDP_LINK_TRAIN_800MV_3_5DB_IVB		(0x3e <<22)
+
+/* legacy values */
+#define EDP_LINK_TRAIN_500MV_0DB_IVB		(0x00 <<22)
+#define EDP_LINK_TRAIN_1000MV_0DB_IVB		(0x20 <<22)
+#define EDP_LINK_TRAIN_500MV_3_5DB_IVB		(0x02 <<22)
+#define EDP_LINK_TRAIN_1000MV_3_5DB_IVB		(0x22 <<22)
+#define EDP_LINK_TRAIN_1000MV_6DB_IVB		(0x23 <<22)
+
+#define  EDP_LINK_TRAIN_VOL_EMP_MASK_IVB	(0x3f<<22)
+
+#define  VLV_PMWGICZ				_MMIO(0x1300a4)
+
+#define  RC6_LOCATION				_MMIO(0xD40)
+#define	   RC6_CTX_IN_DRAM			(1 << 0)
+#define  RC6_CTX_BASE				_MMIO(0xD48)
+#define    RC6_CTX_BASE_MASK			0xFFFFFFF0
+#define  PWRCTX_MAXCNT_RCSUNIT			_MMIO(0x2054)
+#define  PWRCTX_MAXCNT_VCSUNIT0			_MMIO(0x12054)
+#define  PWRCTX_MAXCNT_BCSUNIT			_MMIO(0x22054)
+#define  PWRCTX_MAXCNT_VECSUNIT			_MMIO(0x1A054)
+#define  PWRCTX_MAXCNT_VCSUNIT1			_MMIO(0x1C054)
+#define    IDLE_TIME_MASK			0xFFFFF
+#define  FORCEWAKE				_MMIO(0xA18C)
+#define  FORCEWAKE_VLV				_MMIO(0x1300b0)
+#define  FORCEWAKE_ACK_VLV			_MMIO(0x1300b4)
+#define  FORCEWAKE_MEDIA_VLV			_MMIO(0x1300b8)
+#define  FORCEWAKE_ACK_MEDIA_VLV		_MMIO(0x1300bc)
+#define  FORCEWAKE_ACK_HSW			_MMIO(0x130044)
+#define  FORCEWAKE_ACK				_MMIO(0x130090)
+#define  VLV_GTLC_WAKE_CTRL			_MMIO(0x130090)
+#define   VLV_GTLC_RENDER_CTX_EXISTS		(1 << 25)
+#define   VLV_GTLC_MEDIA_CTX_EXISTS		(1 << 24)
+#define   VLV_GTLC_ALLOWWAKEREQ			(1 << 0)
+
+#define  VLV_GTLC_PW_STATUS			_MMIO(0x130094)
+#define   VLV_GTLC_ALLOWWAKEACK			(1 << 0)
+#define   VLV_GTLC_ALLOWWAKEERR			(1 << 1)
+#define   VLV_GTLC_PW_MEDIA_STATUS_MASK		(1 << 5)
+#define   VLV_GTLC_PW_RENDER_STATUS_MASK	(1 << 7)
+#define  FORCEWAKE_MT				_MMIO(0xa188) /* multi-threaded */
+#define  FORCEWAKE_MEDIA_GEN9			_MMIO(0xa270)
+#define  FORCEWAKE_RENDER_GEN9			_MMIO(0xa278)
+#define  FORCEWAKE_BLITTER_GEN9			_MMIO(0xa188)
+#define  FORCEWAKE_ACK_MEDIA_GEN9		_MMIO(0x0D88)
+#define  FORCEWAKE_ACK_RENDER_GEN9		_MMIO(0x0D84)
+#define  FORCEWAKE_ACK_BLITTER_GEN9		_MMIO(0x130044)
+#define   FORCEWAKE_KERNEL			0x1
+#define   FORCEWAKE_USER			0x2
+#define  FORCEWAKE_MT_ACK			_MMIO(0x130040)
+#define  ECOBUS					_MMIO(0xa180)
+#define    FORCEWAKE_MT_ENABLE			(1<<5)
+#define  VLV_SPAREG2H				_MMIO(0xA194)
+
+#define  GTFIFODBG				_MMIO(0x120000)
+#define    GT_FIFO_SBDEDICATE_FREE_ENTRY_CHV	(0x1f << 20)
+#define    GT_FIFO_FREE_ENTRIES_CHV		(0x7f << 13)
+#define    GT_FIFO_SBDROPERR			(1<<6)
+#define    GT_FIFO_BLOBDROPERR			(1<<5)
+#define    GT_FIFO_SB_READ_ABORTERR		(1<<4)
+#define    GT_FIFO_DROPERR			(1<<3)
+#define    GT_FIFO_OVFERR			(1<<2)
+#define    GT_FIFO_IAWRERR			(1<<1)
+#define    GT_FIFO_IARDERR			(1<<0)
+
+#define  GTFIFOCTL				_MMIO(0x120008)
+#define    GT_FIFO_FREE_ENTRIES_MASK		0x7f
+#define    GT_FIFO_NUM_RESERVED_ENTRIES		20
+#define    GT_FIFO_CTL_BLOCK_ALL_POLICY_STALL	(1 << 12)
+#define    GT_FIFO_CTL_RC6_POLICY_STALL		(1 << 11)
+
+#define  HSW_IDICR				_MMIO(0x9008)
+#define    IDIHASHMSK(x)			(((x) & 0x3f) << 16)
+#define  HSW_EDRAM_CAP				_MMIO(0x120010)
+#define    EDRAM_ENABLED			0x1
+#define    EDRAM_NUM_BANKS(cap)			(((cap) >> 1) & 0xf)
+#define    EDRAM_WAYS_IDX(cap)			(((cap) >> 5) & 0x7)
+#define    EDRAM_SETS_IDX(cap)			(((cap) >> 8) & 0x3)
+
+#define GEN6_UCGCTL1				_MMIO(0x9400)
+# define GEN6_GAMUNIT_CLOCK_GATE_DISABLE		(1 << 22)
+# define GEN6_EU_TCUNIT_CLOCK_GATE_DISABLE		(1 << 16)
+# define GEN6_BLBUNIT_CLOCK_GATE_DISABLE		(1 << 5)
+# define GEN6_CSUNIT_CLOCK_GATE_DISABLE			(1 << 7)
+
+#define GEN6_UCGCTL2				_MMIO(0x9404)
+# define GEN6_VFUNIT_CLOCK_GATE_DISABLE			(1 << 31)
+# define GEN7_VDSUNIT_CLOCK_GATE_DISABLE		(1 << 30)
+# define GEN7_TDLUNIT_CLOCK_GATE_DISABLE		(1 << 22)
+# define GEN6_RCZUNIT_CLOCK_GATE_DISABLE		(1 << 13)
+# define GEN6_RCPBUNIT_CLOCK_GATE_DISABLE		(1 << 12)
+# define GEN6_RCCUNIT_CLOCK_GATE_DISABLE		(1 << 11)
+
+#define GEN6_UCGCTL3				_MMIO(0x9408)
+
+#define GEN7_UCGCTL4				_MMIO(0x940c)
+#define  GEN7_L3BANK2X_CLOCK_GATE_DISABLE	(1<<25)
+#define  GEN8_EU_GAUNIT_CLOCK_GATE_DISABLE	(1<<14)
+
+#define GEN6_RCGCTL1				_MMIO(0x9410)
+#define GEN6_RCGCTL2				_MMIO(0x9414)
+#define GEN6_RSTCTL				_MMIO(0x9420)
+
+#define GEN8_UCGCTL6				_MMIO(0x9430)
+#define   GEN8_GAPSUNIT_CLOCK_GATE_DISABLE	(1<<24)
+#define   GEN8_SDEUNIT_CLOCK_GATE_DISABLE	(1<<14)
+#define   GEN8_HDCUNIT_CLOCK_GATE_DISABLE_HDCREQ (1<<28)
+
+#define GEN6_GFXPAUSE				_MMIO(0xA000)
+#define GEN6_RPNSWREQ				_MMIO(0xA008)
+#define   GEN6_TURBO_DISABLE			(1<<31)
+#define   GEN6_FREQUENCY(x)			((x)<<25)
+#define   HSW_FREQUENCY(x)			((x)<<24)
+#define   GEN9_FREQUENCY(x)			((x)<<23)
+#define   GEN6_OFFSET(x)			((x)<<19)
+#define   GEN6_AGGRESSIVE_TURBO			(0<<15)
+#define GEN6_RC_VIDEO_FREQ			_MMIO(0xA00C)
+#define GEN6_RC_CONTROL				_MMIO(0xA090)
+#define   GEN6_RC_CTL_RC6pp_ENABLE		(1<<16)
+#define   GEN6_RC_CTL_RC6p_ENABLE		(1<<17)
+#define   GEN6_RC_CTL_RC6_ENABLE		(1<<18)
+#define   GEN6_RC_CTL_RC1e_ENABLE		(1<<20)
+#define   GEN6_RC_CTL_RC7_ENABLE		(1<<22)
+#define   VLV_RC_CTL_CTX_RST_PARALLEL		(1<<24)
+#define   GEN7_RC_CTL_TO_MODE			(1<<28)
+#define   GEN6_RC_CTL_EI_MODE(x)		((x)<<27)
+#define   GEN6_RC_CTL_HW_ENABLE			(1<<31)
+#define GEN6_RP_DOWN_TIMEOUT			_MMIO(0xA010)
+#define GEN6_RP_INTERRUPT_LIMITS		_MMIO(0xA014)
+#define GEN6_RPSTAT1				_MMIO(0xA01C)
+#define   GEN6_CAGF_SHIFT			8
+#define   HSW_CAGF_SHIFT			7
+#define   GEN9_CAGF_SHIFT			23
+#define   GEN6_CAGF_MASK			(0x7f << GEN6_CAGF_SHIFT)
+#define   HSW_CAGF_MASK				(0x7f << HSW_CAGF_SHIFT)
+#define   GEN9_CAGF_MASK			(0x1ff << GEN9_CAGF_SHIFT)
+#define GEN6_RP_CONTROL				_MMIO(0xA024)
+#define   GEN6_RP_MEDIA_TURBO			(1<<11)
+#define   GEN6_RP_MEDIA_MODE_MASK		(3<<9)
+#define   GEN6_RP_MEDIA_HW_TURBO_MODE		(3<<9)
+#define   GEN6_RP_MEDIA_HW_NORMAL_MODE		(2<<9)
+#define   GEN6_RP_MEDIA_HW_MODE			(1<<9)
+#define   GEN6_RP_MEDIA_SW_MODE			(0<<9)
+#define   GEN6_RP_MEDIA_IS_GFX			(1<<8)
+#define   GEN6_RP_ENABLE			(1<<7)
+#define   GEN6_RP_UP_IDLE_MIN			(0x1<<3)
+#define   GEN6_RP_UP_BUSY_AVG			(0x2<<3)
+#define   GEN6_RP_UP_BUSY_CONT			(0x4<<3)
+#define   GEN6_RP_DOWN_IDLE_AVG			(0x2<<0)
+#define   GEN6_RP_DOWN_IDLE_CONT		(0x1<<0)
+#define GEN6_RP_UP_THRESHOLD			_MMIO(0xA02C)
+#define GEN6_RP_DOWN_THRESHOLD			_MMIO(0xA030)
+#define GEN6_RP_CUR_UP_EI			_MMIO(0xA050)
+#define   GEN6_CURICONT_MASK			0xffffff
+#define GEN6_RP_CUR_UP				_MMIO(0xA054)
+#define   GEN6_CURBSYTAVG_MASK			0xffffff
+#define GEN6_RP_PREV_UP				_MMIO(0xA058)
+#define GEN6_RP_CUR_DOWN_EI			_MMIO(0xA05C)
+#define   GEN6_CURIAVG_MASK			0xffffff
+#define GEN6_RP_CUR_DOWN			_MMIO(0xA060)
+#define GEN6_RP_PREV_DOWN			_MMIO(0xA064)
+#define GEN6_RP_UP_EI				_MMIO(0xA068)
+#define GEN6_RP_DOWN_EI				_MMIO(0xA06C)
+#define GEN6_RP_IDLE_HYSTERSIS			_MMIO(0xA070)
+#define GEN6_RPDEUHWTC				_MMIO(0xA080)
+#define GEN6_RPDEUC				_MMIO(0xA084)
+#define GEN6_RPDEUCSW				_MMIO(0xA088)
+#define GEN6_RC_STATE				_MMIO(0xA094)
+#define   RC6_STATE				(1 << 18)
+#define GEN6_RC1_WAKE_RATE_LIMIT		_MMIO(0xA098)
+#define GEN6_RC6_WAKE_RATE_LIMIT		_MMIO(0xA09C)
+#define GEN6_RC6pp_WAKE_RATE_LIMIT		_MMIO(0xA0A0)
+#define GEN6_RC_EVALUATION_INTERVAL		_MMIO(0xA0A8)
+#define GEN6_RC_IDLE_HYSTERSIS			_MMIO(0xA0AC)
+#define GEN6_RC_SLEEP				_MMIO(0xA0B0)
+#define GEN6_RCUBMABDTMR			_MMIO(0xA0B0)
+#define GEN6_RC1e_THRESHOLD			_MMIO(0xA0B4)
+#define GEN6_RC6_THRESHOLD			_MMIO(0xA0B8)
+#define GEN6_RC6p_THRESHOLD			_MMIO(0xA0BC)
+#define VLV_RCEDATA				_MMIO(0xA0BC)
+#define GEN6_RC6pp_THRESHOLD			_MMIO(0xA0C0)
+#define GEN6_PMINTRMSK				_MMIO(0xA168)
+#define GEN8_PMINTR_REDIRECT_TO_NON_DISP	(1<<31)
+#define VLV_PWRDWNUPCTL				_MMIO(0xA294)
+#define GEN9_MEDIA_PG_IDLE_HYSTERESIS		_MMIO(0xA0C4)
+#define GEN9_RENDER_PG_IDLE_HYSTERESIS		_MMIO(0xA0C8)
+#define GEN9_PG_ENABLE				_MMIO(0xA210)
+#define GEN9_RENDER_PG_ENABLE			(1<<0)
+#define GEN9_MEDIA_PG_ENABLE			(1<<1)
+
+#define VLV_CHICKEN_3				_MMIO(VLV_DISPLAY_BASE + 0x7040C)
+#define  PIXEL_OVERLAP_CNT_MASK			(3 << 30)
+#define  PIXEL_OVERLAP_CNT_SHIFT		30
+
+#define GEN6_PMISR				_MMIO(0x44020)
+#define GEN6_PMIMR				_MMIO(0x44024) /* rps_lock */
+#define GEN6_PMIIR				_MMIO(0x44028)
+#define GEN6_PMIER				_MMIO(0x4402C)
+#define  GEN6_PM_MBOX_EVENT			(1<<25)
+#define  GEN6_PM_THERMAL_EVENT			(1<<24)
+#define  GEN6_PM_RP_DOWN_TIMEOUT		(1<<6)
+#define  GEN6_PM_RP_UP_THRESHOLD		(1<<5)
+#define  GEN6_PM_RP_DOWN_THRESHOLD		(1<<4)
+#define  GEN6_PM_RP_UP_EI_EXPIRED		(1<<2)
+#define  GEN6_PM_RP_DOWN_EI_EXPIRED		(1<<1)
+#define  GEN6_PM_RPS_EVENTS			(GEN6_PM_RP_UP_THRESHOLD | \
+						 GEN6_PM_RP_DOWN_THRESHOLD | \
+						 GEN6_PM_RP_DOWN_TIMEOUT)
+
+#define GEN7_GT_SCRATCH(i)			_MMIO(0x4F100 + (i) * 4)
+#define GEN7_GT_SCRATCH_REG_NUM			8
+
+#define VLV_GTLC_SURVIVABILITY_REG              _MMIO(0x130098)
+#define VLV_GFX_CLK_STATUS_BIT			(1<<3)
+#define VLV_GFX_CLK_FORCE_ON_BIT		(1<<2)
+
+#define GEN6_GT_GFX_RC6_LOCKED			_MMIO(0x138104)
+#define VLV_COUNTER_CONTROL			_MMIO(0x138104)
+#define   VLV_COUNT_RANGE_HIGH			(1<<15)
+#define   VLV_MEDIA_RC0_COUNT_EN		(1<<5)
+#define   VLV_RENDER_RC0_COUNT_EN		(1<<4)
+#define   VLV_MEDIA_RC6_COUNT_EN		(1<<1)
+#define   VLV_RENDER_RC6_COUNT_EN		(1<<0)
+#define GEN6_GT_GFX_RC6				_MMIO(0x138108)
+#define VLV_GT_RENDER_RC6			_MMIO(0x138108)
+#define VLV_GT_MEDIA_RC6			_MMIO(0x13810C)
+
+#define GEN6_GT_GFX_RC6p			_MMIO(0x13810C)
+#define GEN6_GT_GFX_RC6pp			_MMIO(0x138110)
+#define VLV_RENDER_C0_COUNT			_MMIO(0x138118)
+#define VLV_MEDIA_C0_COUNT			_MMIO(0x13811C)
+
+#define GEN6_PCODE_MAILBOX			_MMIO(0x138124)
+#define   GEN6_PCODE_READY			(1<<31)
+#define	  GEN6_PCODE_WRITE_RC6VIDS		0x4
+#define	  GEN6_PCODE_READ_RC6VIDS		0x5
+#define     GEN6_ENCODE_RC6_VID(mv)		(((mv) - 245) / 5)
+#define     GEN6_DECODE_RC6_VID(vids)		(((vids) * 5) + 245)
+#define   BDW_PCODE_DISPLAY_FREQ_CHANGE_REQ	0x18
+#define   GEN9_PCODE_READ_MEM_LATENCY		0x6
+#define     GEN9_MEM_LATENCY_LEVEL_MASK		0xFF
+#define     GEN9_MEM_LATENCY_LEVEL_1_5_SHIFT	8
+#define     GEN9_MEM_LATENCY_LEVEL_2_6_SHIFT	16
+#define     GEN9_MEM_LATENCY_LEVEL_3_7_SHIFT	24
+#define   SKL_PCODE_CDCLK_CONTROL		0x7
+#define     SKL_CDCLK_PREPARE_FOR_CHANGE	0x3
+#define     SKL_CDCLK_READY_FOR_CHANGE		0x1
+#define   GEN6_PCODE_WRITE_MIN_FREQ_TABLE	0x8
+#define   GEN6_PCODE_READ_MIN_FREQ_TABLE	0x9
+#define   GEN6_READ_OC_PARAMS			0xc
+#define   GEN6_PCODE_READ_D_COMP		0x10
+#define   GEN6_PCODE_WRITE_D_COMP		0x11
+#define   HSW_PCODE_DE_WRITE_FREQ_REQ		0x17
+#define   DISPLAY_IPS_CONTROL			0x19
+#define	  HSW_PCODE_DYNAMIC_DUTY_CYCLE_CONTROL	0x1A
+#define GEN6_PCODE_DATA				_MMIO(0x138128)
+#define   GEN6_PCODE_FREQ_IA_RATIO_SHIFT	8
+#define   GEN6_PCODE_FREQ_RING_RATIO_SHIFT	16
+#define GEN6_PCODE_DATA1			_MMIO(0x13812C)
+
+#define GEN6_GT_CORE_STATUS		_MMIO(0x138060)
+#define   GEN6_CORE_CPD_STATE_MASK	(7<<4)
+#define   GEN6_RCn_MASK			7
+#define   GEN6_RC0			0
+#define   GEN6_RC3			2
+#define   GEN6_RC6			3
+#define   GEN6_RC7			4
+
+#define GEN8_GT_SLICE_INFO		_MMIO(0x138064)
+#define   GEN8_LSLICESTAT_MASK		0x7
+
+#define CHV_POWER_SS0_SIG1		_MMIO(0xa720)
+#define CHV_POWER_SS1_SIG1		_MMIO(0xa728)
+#define   CHV_SS_PG_ENABLE		(1<<1)
+#define   CHV_EU08_PG_ENABLE		(1<<9)
+#define   CHV_EU19_PG_ENABLE		(1<<17)
+#define   CHV_EU210_PG_ENABLE		(1<<25)
+
+#define CHV_POWER_SS0_SIG2		_MMIO(0xa724)
+#define CHV_POWER_SS1_SIG2		_MMIO(0xa72c)
+#define   CHV_EU311_PG_ENABLE		(1<<1)
+
+#define GEN9_SLICE_PGCTL_ACK(slice)	_MMIO(0x804c + (slice)*0x4)
+#define   GEN9_PGCTL_SLICE_ACK		(1 << 0)
+#define   GEN9_PGCTL_SS_ACK(subslice)	(1 << (2 + (subslice)*2))
+
+#define GEN9_SS01_EU_PGCTL_ACK(slice)	_MMIO(0x805c + (slice)*0x8)
+#define GEN9_SS23_EU_PGCTL_ACK(slice)	_MMIO(0x8060 + (slice)*0x8)
+#define   GEN9_PGCTL_SSA_EU08_ACK	(1 << 0)
+#define   GEN9_PGCTL_SSA_EU19_ACK	(1 << 2)
+#define   GEN9_PGCTL_SSA_EU210_ACK	(1 << 4)
+#define   GEN9_PGCTL_SSA_EU311_ACK	(1 << 6)
+#define   GEN9_PGCTL_SSB_EU08_ACK	(1 << 8)
+#define   GEN9_PGCTL_SSB_EU19_ACK	(1 << 10)
+#define   GEN9_PGCTL_SSB_EU210_ACK	(1 << 12)
+#define   GEN9_PGCTL_SSB_EU311_ACK	(1 << 14)
+
+#define GEN7_MISCCPCTL				_MMIO(0x9424)
+#define   GEN7_DOP_CLOCK_GATE_ENABLE		(1<<0)
+#define   GEN8_DOP_CLOCK_GATE_CFCLK_ENABLE	(1<<2)
+#define   GEN8_DOP_CLOCK_GATE_GUC_ENABLE	(1<<4)
+#define   GEN8_DOP_CLOCK_GATE_MEDIA_ENABLE     (1<<6)
+
+#define GEN8_GARBCNTL                   _MMIO(0xB004)
+#define   GEN9_GAPS_TSV_CREDIT_DISABLE  (1<<7)
+
+/* IVYBRIDGE DPF */
+#define GEN7_L3CDERRST1(slice)		_MMIO(0xB008 + (slice) * 0x200) /* L3CD Error Status 1 */
+#define   GEN7_L3CDERRST1_ROW_MASK	(0x7ff<<14)
+#define   GEN7_PARITY_ERROR_VALID	(1<<13)
+#define   GEN7_L3CDERRST1_BANK_MASK	(3<<11)
+#define   GEN7_L3CDERRST1_SUBBANK_MASK	(7<<8)
+#define GEN7_PARITY_ERROR_ROW(reg) \
+		((reg & GEN7_L3CDERRST1_ROW_MASK) >> 14)
+#define GEN7_PARITY_ERROR_BANK(reg) \
+		((reg & GEN7_L3CDERRST1_BANK_MASK) >> 11)
+#define GEN7_PARITY_ERROR_SUBBANK(reg) \
+		((reg & GEN7_L3CDERRST1_SUBBANK_MASK) >> 8)
+#define   GEN7_L3CDERRST1_ENABLE	(1<<7)
+
+#define GEN7_L3LOG(slice, i)		_MMIO(0xB070 + (slice) * 0x200 + (i) * 4)
+#define GEN7_L3LOG_SIZE			0x80
+
+#define GEN7_HALF_SLICE_CHICKEN1	_MMIO(0xe100) /* IVB GT1 + VLV */
+#define GEN7_HALF_SLICE_CHICKEN1_GT2	_MMIO(0xf100)
+#define   GEN7_MAX_PS_THREAD_DEP		(8<<12)
+#define   GEN7_SINGLE_SUBSCAN_DISPATCH_ENABLE	(1<<10)
+#define   GEN7_SBE_SS_CACHE_DISPATCH_PORT_SHARING_DISABLE	(1<<4)
+#define   GEN7_PSD_SINGLE_PORT_DISPATCH_ENABLE	(1<<3)
+
+#define GEN9_HALF_SLICE_CHICKEN5	_MMIO(0xe188)
+#define   GEN9_DG_MIRROR_FIX_ENABLE	(1<<5)
+#define   GEN9_CCS_TLB_PREFETCH_ENABLE	(1<<3)
+
+#define GEN8_ROW_CHICKEN		_MMIO(0xe4f0)
+#define   FLOW_CONTROL_ENABLE		(1<<15)
+#define   PARTIAL_INSTRUCTION_SHOOTDOWN_DISABLE	(1<<8)
+#define   STALL_DOP_GATING_DISABLE		(1<<5)
+
+#define GEN7_ROW_CHICKEN2		_MMIO(0xe4f4)
+#define GEN7_ROW_CHICKEN2_GT2		_MMIO(0xf4f4)
+#define   DOP_CLOCK_GATING_DISABLE	(1<<0)
+
+#define HSW_ROW_CHICKEN3		_MMIO(0xe49c)
+#define  HSW_ROW_CHICKEN3_L3_GLOBAL_ATOMICS_DISABLE    (1 << 6)
+
+#define HALF_SLICE_CHICKEN2		_MMIO(0xe180)
+#define   GEN8_ST_PO_DISABLE		(1<<13)
+
+#define HALF_SLICE_CHICKEN3		_MMIO(0xe184)
+#define   HSW_SAMPLE_C_PERFORMANCE	(1<<9)
+#define   GEN8_CENTROID_PIXEL_OPT_DIS	(1<<8)
+#define   GEN9_DISABLE_OCL_OOB_SUPPRESS_LOGIC	(1<<5)
+#define   GEN8_SAMPLER_POWER_BYPASS_DIS	(1<<1)
+
+#define GEN9_HALF_SLICE_CHICKEN7	_MMIO(0xe194)
+#define   GEN9_ENABLE_YV12_BUGFIX	(1<<4)
+#define   GEN9_ENABLE_GPGPU_PREEMPTION	(1<<2)
+
+/* Audio */
+#define G4X_AUD_VID_DID			_MMIO(dev_priv->info.display_mmio_offset + 0x62020)
+#define   INTEL_AUDIO_DEVCL		0x808629FB
+#define   INTEL_AUDIO_DEVBLC		0x80862801
+#define   INTEL_AUDIO_DEVCTG		0x80862802
+
+#define G4X_AUD_CNTL_ST			_MMIO(0x620B4)
+#define   G4X_ELDV_DEVCL_DEVBLC		(1 << 13)
+#define   G4X_ELDV_DEVCTG		(1 << 14)
+#define   G4X_ELD_ADDR_MASK		(0xf << 5)
+#define   G4X_ELD_ACK			(1 << 4)
+#define G4X_HDMIW_HDMIEDID		_MMIO(0x6210C)
+
+#define _IBX_HDMIW_HDMIEDID_A		0xE2050
+#define _IBX_HDMIW_HDMIEDID_B		0xE2150
+#define IBX_HDMIW_HDMIEDID(pipe)	_MMIO_PIPE(pipe, _IBX_HDMIW_HDMIEDID_A, \
+						  _IBX_HDMIW_HDMIEDID_B)
+#define _IBX_AUD_CNTL_ST_A		0xE20B4
+#define _IBX_AUD_CNTL_ST_B		0xE21B4
+#define IBX_AUD_CNTL_ST(pipe)		_MMIO_PIPE(pipe, _IBX_AUD_CNTL_ST_A, \
+						  _IBX_AUD_CNTL_ST_B)
+#define   IBX_ELD_BUFFER_SIZE_MASK	(0x1f << 10)
+#define   IBX_ELD_ADDRESS_MASK		(0x1f << 5)
+#define   IBX_ELD_ACK			(1 << 4)
+#define IBX_AUD_CNTL_ST2		_MMIO(0xE20C0)
+#define   IBX_CP_READY(port)		((1 << 1) << (((port) - 1) * 4))
+#define   IBX_ELD_VALID(port)		((1 << 0) << (((port) - 1) * 4))
+
+#define _CPT_HDMIW_HDMIEDID_A		0xE5050
+#define _CPT_HDMIW_HDMIEDID_B		0xE5150
+#define CPT_HDMIW_HDMIEDID(pipe)	_MMIO_PIPE(pipe, _CPT_HDMIW_HDMIEDID_A, _CPT_HDMIW_HDMIEDID_B)
+#define _CPT_AUD_CNTL_ST_A		0xE50B4
+#define _CPT_AUD_CNTL_ST_B		0xE51B4
+#define CPT_AUD_CNTL_ST(pipe)		_MMIO_PIPE(pipe, _CPT_AUD_CNTL_ST_A, _CPT_AUD_CNTL_ST_B)
+#define CPT_AUD_CNTRL_ST2		_MMIO(0xE50C0)
+
+#define _VLV_HDMIW_HDMIEDID_A		(VLV_DISPLAY_BASE + 0x62050)
+#define _VLV_HDMIW_HDMIEDID_B		(VLV_DISPLAY_BASE + 0x62150)
+#define VLV_HDMIW_HDMIEDID(pipe)	_MMIO_PIPE(pipe, _VLV_HDMIW_HDMIEDID_A, _VLV_HDMIW_HDMIEDID_B)
+#define _VLV_AUD_CNTL_ST_A		(VLV_DISPLAY_BASE + 0x620B4)
+#define _VLV_AUD_CNTL_ST_B		(VLV_DISPLAY_BASE + 0x621B4)
+#define VLV_AUD_CNTL_ST(pipe)		_MMIO_PIPE(pipe, _VLV_AUD_CNTL_ST_A, _VLV_AUD_CNTL_ST_B)
+#define VLV_AUD_CNTL_ST2		_MMIO(VLV_DISPLAY_BASE + 0x620C0)
+
+/* These are the 4 32-bit write offset registers for each stream
+ * output buffer.  It determines the offset from the
+ * 3DSTATE_SO_BUFFERs that the next streamed vertex output goes to.
+ */
+#define GEN7_SO_WRITE_OFFSET(n)		_MMIO(0x5280 + (n) * 4)
+
+#define _IBX_AUD_CONFIG_A		0xe2000
+#define _IBX_AUD_CONFIG_B		0xe2100
+#define IBX_AUD_CFG(pipe)		_MMIO_PIPE(pipe, _IBX_AUD_CONFIG_A, _IBX_AUD_CONFIG_B)
+#define _CPT_AUD_CONFIG_A		0xe5000
+#define _CPT_AUD_CONFIG_B		0xe5100
+#define CPT_AUD_CFG(pipe)		_MMIO_PIPE(pipe, _CPT_AUD_CONFIG_A, _CPT_AUD_CONFIG_B)
+#define _VLV_AUD_CONFIG_A		(VLV_DISPLAY_BASE + 0x62000)
+#define _VLV_AUD_CONFIG_B		(VLV_DISPLAY_BASE + 0x62100)
+#define VLV_AUD_CFG(pipe)		_MMIO_PIPE(pipe, _VLV_AUD_CONFIG_A, _VLV_AUD_CONFIG_B)
+
+#define   AUD_CONFIG_N_VALUE_INDEX		(1 << 29)
+#define   AUD_CONFIG_N_PROG_ENABLE		(1 << 28)
+#define   AUD_CONFIG_UPPER_N_SHIFT		20
+#define   AUD_CONFIG_UPPER_N_MASK		(0xff << 20)
+#define   AUD_CONFIG_LOWER_N_SHIFT		4
+#define   AUD_CONFIG_LOWER_N_MASK		(0xfff << 4)
+#define   AUD_CONFIG_PIXEL_CLOCK_HDMI_SHIFT	16
+#define   AUD_CONFIG_PIXEL_CLOCK_HDMI_MASK	(0xf << 16)
+#define   AUD_CONFIG_PIXEL_CLOCK_HDMI_25175	(0 << 16)
+#define   AUD_CONFIG_PIXEL_CLOCK_HDMI_25200	(1 << 16)
+#define   AUD_CONFIG_PIXEL_CLOCK_HDMI_27000	(2 << 16)
+#define   AUD_CONFIG_PIXEL_CLOCK_HDMI_27027	(3 << 16)
+#define   AUD_CONFIG_PIXEL_CLOCK_HDMI_54000	(4 << 16)
+#define   AUD_CONFIG_PIXEL_CLOCK_HDMI_54054	(5 << 16)
+#define   AUD_CONFIG_PIXEL_CLOCK_HDMI_74176	(6 << 16)
+#define   AUD_CONFIG_PIXEL_CLOCK_HDMI_74250	(7 << 16)
+#define   AUD_CONFIG_PIXEL_CLOCK_HDMI_148352	(8 << 16)
+#define   AUD_CONFIG_PIXEL_CLOCK_HDMI_148500	(9 << 16)
+#define   AUD_CONFIG_DISABLE_NCTS		(1 << 3)
+
+/* HSW Audio */
+#define _HSW_AUD_CONFIG_A		0x65000
+#define _HSW_AUD_CONFIG_B		0x65100
+#define HSW_AUD_CFG(pipe)		_MMIO_PIPE(pipe, _HSW_AUD_CONFIG_A, _HSW_AUD_CONFIG_B)
+
+#define _HSW_AUD_MISC_CTRL_A		0x65010
+#define _HSW_AUD_MISC_CTRL_B		0x65110
+#define HSW_AUD_MISC_CTRL(pipe)		_MMIO_PIPE(pipe, _HSW_AUD_MISC_CTRL_A, _HSW_AUD_MISC_CTRL_B)
+
+#define _HSW_AUD_DIP_ELD_CTRL_ST_A	0x650b4
+#define _HSW_AUD_DIP_ELD_CTRL_ST_B	0x651b4
+#define HSW_AUD_DIP_ELD_CTRL(pipe)	_MMIO_PIPE(pipe, _HSW_AUD_DIP_ELD_CTRL_ST_A, _HSW_AUD_DIP_ELD_CTRL_ST_B)
+
+/* Audio Digital Converter */
+#define _HSW_AUD_DIG_CNVT_1		0x65080
+#define _HSW_AUD_DIG_CNVT_2		0x65180
+#define AUD_DIG_CNVT(pipe)		_MMIO_PIPE(pipe, _HSW_AUD_DIG_CNVT_1, _HSW_AUD_DIG_CNVT_2)
+#define DIP_PORT_SEL_MASK		0x3
+
+#define _HSW_AUD_EDID_DATA_A		0x65050
+#define _HSW_AUD_EDID_DATA_B		0x65150
+#define HSW_AUD_EDID_DATA(pipe)		_MMIO_PIPE(pipe, _HSW_AUD_EDID_DATA_A, _HSW_AUD_EDID_DATA_B)
+
+#define HSW_AUD_PIPE_CONV_CFG		_MMIO(0x6507c)
+#define HSW_AUD_PIN_ELD_CP_VLD		_MMIO(0x650c0)
+#define   AUDIO_INACTIVE(trans)		((1 << 3) << ((trans) * 4))
+#define   AUDIO_OUTPUT_ENABLE(trans)	((1 << 2) << ((trans) * 4))
+#define   AUDIO_CP_READY(trans)		((1 << 1) << ((trans) * 4))
+#define   AUDIO_ELD_VALID(trans)	((1 << 0) << ((trans) * 4))
+
+#define HSW_AUD_CHICKENBIT			_MMIO(0x65f10)
+#define   SKL_AUD_CODEC_WAKE_SIGNAL		(1 << 15)
+
+/* HSW Power Wells */
+#define HSW_PWR_WELL_BIOS			_MMIO(0x45400) /* CTL1 */
+#define HSW_PWR_WELL_DRIVER			_MMIO(0x45404) /* CTL2 */
+#define HSW_PWR_WELL_KVMR			_MMIO(0x45408) /* CTL3 */
+#define HSW_PWR_WELL_DEBUG			_MMIO(0x4540C) /* CTL4 */
+#define   HSW_PWR_WELL_ENABLE_REQUEST		(1<<31)
+#define   HSW_PWR_WELL_STATE_ENABLED		(1<<30)
+#define HSW_PWR_WELL_CTL5			_MMIO(0x45410)
+#define   HSW_PWR_WELL_ENABLE_SINGLE_STEP	(1<<31)
+#define   HSW_PWR_WELL_PWR_GATE_OVERRIDE	(1<<20)
+#define   HSW_PWR_WELL_FORCE_ON			(1<<19)
+#define HSW_PWR_WELL_CTL6			_MMIO(0x45414)
+
+/* SKL Fuse Status */
+#define SKL_FUSE_STATUS				_MMIO(0x42000)
+#define  SKL_FUSE_DOWNLOAD_STATUS              (1<<31)
+#define  SKL_FUSE_PG0_DIST_STATUS              (1<<27)
+#define  SKL_FUSE_PG1_DIST_STATUS              (1<<26)
+#define  SKL_FUSE_PG2_DIST_STATUS              (1<<25)
+
+/* Per-pipe DDI Function Control */
+#define _TRANS_DDI_FUNC_CTL_A		0x60400
+#define _TRANS_DDI_FUNC_CTL_B		0x61400
+#define _TRANS_DDI_FUNC_CTL_C		0x62400
+#define _TRANS_DDI_FUNC_CTL_EDP		0x6F400
+#define TRANS_DDI_FUNC_CTL(tran) _MMIO_TRANS2(tran, _TRANS_DDI_FUNC_CTL_A)
+
+#define  TRANS_DDI_FUNC_ENABLE		(1<<31)
+/* Those bits are ignored by pipe EDP since it can only connect to DDI A */
+#define  TRANS_DDI_PORT_MASK		(7<<28)
+#define  TRANS_DDI_PORT_SHIFT		28
+#define  TRANS_DDI_SELECT_PORT(x)	((x)<<28)
+#define  TRANS_DDI_PORT_NONE		(0<<28)
+#define  TRANS_DDI_MODE_SELECT_MASK	(7<<24)
+#define  TRANS_DDI_MODE_SELECT_HDMI	(0<<24)
+#define  TRANS_DDI_MODE_SELECT_DVI	(1<<24)
+#define  TRANS_DDI_MODE_SELECT_DP_SST	(2<<24)
+#define  TRANS_DDI_MODE_SELECT_DP_MST	(3<<24)
+#define  TRANS_DDI_MODE_SELECT_FDI	(4<<24)
+#define  TRANS_DDI_BPC_MASK		(7<<20)
+#define  TRANS_DDI_BPC_8		(0<<20)
+#define  TRANS_DDI_BPC_10		(1<<20)
+#define  TRANS_DDI_BPC_6		(2<<20)
+#define  TRANS_DDI_BPC_12		(3<<20)
+#define  TRANS_DDI_PVSYNC		(1<<17)
+#define  TRANS_DDI_PHSYNC		(1<<16)
+#define  TRANS_DDI_EDP_INPUT_MASK	(7<<12)
+#define  TRANS_DDI_EDP_INPUT_A_ON	(0<<12)
+#define  TRANS_DDI_EDP_INPUT_A_ONOFF	(4<<12)
+#define  TRANS_DDI_EDP_INPUT_B_ONOFF	(5<<12)
+#define  TRANS_DDI_EDP_INPUT_C_ONOFF	(6<<12)
+#define  TRANS_DDI_DP_VC_PAYLOAD_ALLOC	(1<<8)
+#define  TRANS_DDI_BFI_ENABLE		(1<<4)
+
+/* DisplayPort Transport Control */
+#define _DP_TP_CTL_A			0x64040
+#define _DP_TP_CTL_B			0x64140
+#define DP_TP_CTL(port) _MMIO_PORT(port, _DP_TP_CTL_A, _DP_TP_CTL_B)
+#define  DP_TP_CTL_ENABLE			(1<<31)
+#define  DP_TP_CTL_MODE_SST			(0<<27)
+#define  DP_TP_CTL_MODE_MST			(1<<27)
+#define  DP_TP_CTL_FORCE_ACT			(1<<25)
+#define  DP_TP_CTL_ENHANCED_FRAME_ENABLE	(1<<18)
+#define  DP_TP_CTL_FDI_AUTOTRAIN		(1<<15)
+#define  DP_TP_CTL_LINK_TRAIN_MASK		(7<<8)
+#define  DP_TP_CTL_LINK_TRAIN_PAT1		(0<<8)
+#define  DP_TP_CTL_LINK_TRAIN_PAT2		(1<<8)
+#define  DP_TP_CTL_LINK_TRAIN_PAT3		(4<<8)
+#define  DP_TP_CTL_LINK_TRAIN_IDLE		(2<<8)
+#define  DP_TP_CTL_LINK_TRAIN_NORMAL		(3<<8)
+#define  DP_TP_CTL_SCRAMBLE_DISABLE		(1<<7)
+
+/* DisplayPort Transport Status */
+#define _DP_TP_STATUS_A			0x64044
+#define _DP_TP_STATUS_B			0x64144
+#define DP_TP_STATUS(port) _MMIO_PORT(port, _DP_TP_STATUS_A, _DP_TP_STATUS_B)
+#define  DP_TP_STATUS_IDLE_DONE			(1<<25)
+#define  DP_TP_STATUS_ACT_SENT			(1<<24)
+#define  DP_TP_STATUS_MODE_STATUS_MST		(1<<23)
+#define  DP_TP_STATUS_AUTOTRAIN_DONE		(1<<12)
+#define  DP_TP_STATUS_PAYLOAD_MAPPING_VC2	(3 << 8)
+#define  DP_TP_STATUS_PAYLOAD_MAPPING_VC1	(3 << 4)
+#define  DP_TP_STATUS_PAYLOAD_MAPPING_VC0	(3 << 0)
+
+/* DDI Buffer Control */
+#define _DDI_BUF_CTL_A				0x64000
+#define _DDI_BUF_CTL_B				0x64100
+#define DDI_BUF_CTL(port) _MMIO_PORT(port, _DDI_BUF_CTL_A, _DDI_BUF_CTL_B)
+#define  DDI_BUF_CTL_ENABLE			(1<<31)
+#define  DDI_BUF_TRANS_SELECT(n)	((n) << 24)
+#define  DDI_BUF_EMP_MASK			(0xf<<24)
+#define  DDI_BUF_PORT_REVERSAL			(1<<16)
+#define  DDI_BUF_IS_IDLE			(1<<7)
+#define  DDI_A_4_LANES				(1<<4)
+#define  DDI_PORT_WIDTH(width)			(((width) - 1) << 1)
+#define  DDI_PORT_WIDTH_MASK			(7 << 1)
+#define  DDI_PORT_WIDTH_SHIFT			1
+#define  DDI_INIT_DISPLAY_DETECTED		(1<<0)
+
+/* DDI Buffer Translations */
+#define _DDI_BUF_TRANS_A		0x64E00
+#define _DDI_BUF_TRANS_B		0x64E60
+#define DDI_BUF_TRANS_LO(port, i)	_MMIO(_PORT(port, _DDI_BUF_TRANS_A, _DDI_BUF_TRANS_B) + (i) * 8)
+#define DDI_BUF_TRANS_HI(port, i)	_MMIO(_PORT(port, _DDI_BUF_TRANS_A, _DDI_BUF_TRANS_B) + (i) * 8 + 4)
+
+/* Sideband Interface (SBI) is programmed indirectly, via
+ * SBI_ADDR, which contains the register offset; and SBI_DATA,
+ * which contains the payload */
+#define SBI_ADDR			_MMIO(0xC6000)
+#define SBI_DATA			_MMIO(0xC6004)
+#define SBI_CTL_STAT			_MMIO(0xC6008)
+#define  SBI_CTL_DEST_ICLK		(0x0<<16)
+#define  SBI_CTL_DEST_MPHY		(0x1<<16)
+#define  SBI_CTL_OP_IORD		(0x2<<8)
+#define  SBI_CTL_OP_IOWR		(0x3<<8)
+#define  SBI_CTL_OP_CRRD		(0x6<<8)
+#define  SBI_CTL_OP_CRWR		(0x7<<8)
+#define  SBI_RESPONSE_FAIL		(0x1<<1)
+#define  SBI_RESPONSE_SUCCESS		(0x0<<1)
+#define  SBI_BUSY			(0x1<<0)
+#define  SBI_READY			(0x0<<0)
+
+/* SBI offsets */
+#define  SBI_SSCDIVINTPHASE			0x0200
+#define  SBI_SSCDIVINTPHASE6			0x0600
+#define   SBI_SSCDIVINTPHASE_DIVSEL_SHIFT	1
+#define   SBI_SSCDIVINTPHASE_DIVSEL_MASK	(0x7f<<1)
+#define   SBI_SSCDIVINTPHASE_DIVSEL(x)		((x)<<1)
+#define   SBI_SSCDIVINTPHASE_INCVAL_SHIFT	8
+#define   SBI_SSCDIVINTPHASE_INCVAL_MASK	(0x7f<<8)
+#define   SBI_SSCDIVINTPHASE_INCVAL(x)		((x)<<8)
+#define   SBI_SSCDIVINTPHASE_DIR(x)		((x)<<15)
+#define   SBI_SSCDIVINTPHASE_PROPAGATE		(1<<0)
+#define  SBI_SSCDITHPHASE			0x0204
+#define  SBI_SSCCTL				0x020c
+#define  SBI_SSCCTL6				0x060C
+#define   SBI_SSCCTL_PATHALT			(1<<3)
+#define   SBI_SSCCTL_DISABLE			(1<<0)
+#define  SBI_SSCAUXDIV6				0x0610
+#define   SBI_SSCAUXDIV_FINALDIV2SEL_SHIFT	4
+#define   SBI_SSCAUXDIV_FINALDIV2SEL_MASK	(1<<4)
+#define   SBI_SSCAUXDIV_FINALDIV2SEL(x)		((x)<<4)
+#define  SBI_DBUFF0				0x2a00
+#define  SBI_GEN0				0x1f00
+#define   SBI_GEN0_CFG_BUFFENABLE_DISABLE	(1<<0)
+
+/* LPT PIXCLK_GATE */
+#define PIXCLK_GATE			_MMIO(0xC6020)
+#define  PIXCLK_GATE_UNGATE		(1<<0)
+#define  PIXCLK_GATE_GATE		(0<<0)
+
+/* SPLL */
+#define SPLL_CTL			_MMIO(0x46020)
+#define  SPLL_PLL_ENABLE		(1<<31)
+#define  SPLL_PLL_SSC			(1<<28)
+#define  SPLL_PLL_NON_SSC		(2<<28)
+#define  SPLL_PLL_LCPLL			(3<<28)
+#define  SPLL_PLL_REF_MASK		(3<<28)
+#define  SPLL_PLL_FREQ_810MHz		(0<<26)
+#define  SPLL_PLL_FREQ_1350MHz		(1<<26)
+#define  SPLL_PLL_FREQ_2700MHz		(2<<26)
+#define  SPLL_PLL_FREQ_MASK		(3<<26)
+
+/* WRPLL */
+#define _WRPLL_CTL1			0x46040
+#define _WRPLL_CTL2			0x46060
+#define WRPLL_CTL(pll)			_MMIO_PIPE(pll, _WRPLL_CTL1, _WRPLL_CTL2)
+#define  WRPLL_PLL_ENABLE		(1<<31)
+#define  WRPLL_PLL_SSC			(1<<28)
+#define  WRPLL_PLL_NON_SSC		(2<<28)
+#define  WRPLL_PLL_LCPLL		(3<<28)
+#define  WRPLL_PLL_REF_MASK		(3<<28)
+/* WRPLL divider programming */
+#define  WRPLL_DIVIDER_REFERENCE(x)	((x)<<0)
+#define  WRPLL_DIVIDER_REF_MASK		(0xff)
+#define  WRPLL_DIVIDER_POST(x)		((x)<<8)
+#define  WRPLL_DIVIDER_POST_MASK	(0x3f<<8)
+#define  WRPLL_DIVIDER_POST_SHIFT	8
+#define  WRPLL_DIVIDER_FEEDBACK(x)	((x)<<16)
+#define  WRPLL_DIVIDER_FB_SHIFT		16
+#define  WRPLL_DIVIDER_FB_MASK		(0xff<<16)
+
+/* Port clock selection */
+#define _PORT_CLK_SEL_A			0x46100
+#define _PORT_CLK_SEL_B			0x46104
+#define PORT_CLK_SEL(port) _MMIO_PORT(port, _PORT_CLK_SEL_A, _PORT_CLK_SEL_B)
+#define  PORT_CLK_SEL_LCPLL_2700	(0<<29)
+#define  PORT_CLK_SEL_LCPLL_1350	(1<<29)
+#define  PORT_CLK_SEL_LCPLL_810		(2<<29)
+#define  PORT_CLK_SEL_SPLL		(3<<29)
+#define  PORT_CLK_SEL_WRPLL(pll)	(((pll)+4)<<29)
+#define  PORT_CLK_SEL_WRPLL1		(4<<29)
+#define  PORT_CLK_SEL_WRPLL2		(5<<29)
+#define  PORT_CLK_SEL_NONE		(7<<29)
+#define  PORT_CLK_SEL_MASK		(7<<29)
+
+/* Transcoder clock selection */
+#define _TRANS_CLK_SEL_A		0x46140
+#define _TRANS_CLK_SEL_B		0x46144
+#define TRANS_CLK_SEL(tran) _MMIO_TRANS(tran, _TRANS_CLK_SEL_A, _TRANS_CLK_SEL_B)
+/* For each transcoder, we need to select the corresponding port clock */
+#define  TRANS_CLK_SEL_DISABLED		(0x0<<29)
+#define  TRANS_CLK_SEL_PORT(x)		(((x)+1)<<29)
+
+#define CDCLK_FREQ			_MMIO(0x46200)
+
+#define _TRANSA_MSA_MISC		0x60410
+#define _TRANSB_MSA_MISC		0x61410
+#define _TRANSC_MSA_MISC		0x62410
+#define _TRANS_EDP_MSA_MISC		0x6f410
+#define TRANS_MSA_MISC(tran) _MMIO_TRANS2(tran, _TRANSA_MSA_MISC)
+
+#define  TRANS_MSA_SYNC_CLK		(1<<0)
+#define  TRANS_MSA_6_BPC		(0<<5)
+#define  TRANS_MSA_8_BPC		(1<<5)
+#define  TRANS_MSA_10_BPC		(2<<5)
+#define  TRANS_MSA_12_BPC		(3<<5)
+#define  TRANS_MSA_16_BPC		(4<<5)
+
+/* LCPLL Control */
+#define LCPLL_CTL			_MMIO(0x130040)
+#define  LCPLL_PLL_DISABLE		(1<<31)
+#define  LCPLL_PLL_LOCK			(1<<30)
+#define  LCPLL_CLK_FREQ_MASK		(3<<26)
+#define  LCPLL_CLK_FREQ_450		(0<<26)
+#define  LCPLL_CLK_FREQ_54O_BDW		(1<<26)
+#define  LCPLL_CLK_FREQ_337_5_BDW	(2<<26)
+#define  LCPLL_CLK_FREQ_675_BDW		(3<<26)
+#define  LCPLL_CD_CLOCK_DISABLE		(1<<25)
+#define  LCPLL_ROOT_CD_CLOCK_DISABLE	(1<<24)
+#define  LCPLL_CD2X_CLOCK_DISABLE	(1<<23)
+#define  LCPLL_POWER_DOWN_ALLOW		(1<<22)
+#define  LCPLL_CD_SOURCE_FCLK		(1<<21)
+#define  LCPLL_CD_SOURCE_FCLK_DONE	(1<<19)
+
+/*
+ * SKL Clocks
+ */
+
+/* CDCLK_CTL */
+#define CDCLK_CTL			_MMIO(0x46000)
+#define  CDCLK_FREQ_SEL_MASK		(3<<26)
+#define  CDCLK_FREQ_450_432		(0<<26)
+#define  CDCLK_FREQ_540			(1<<26)
+#define  CDCLK_FREQ_337_308		(2<<26)
+#define  CDCLK_FREQ_675_617		(3<<26)
+#define  CDCLK_FREQ_DECIMAL_MASK	(0x7ff)
+
+#define  BXT_CDCLK_CD2X_DIV_SEL_MASK	(3<<22)
+#define  BXT_CDCLK_CD2X_DIV_SEL_1	(0<<22)
+#define  BXT_CDCLK_CD2X_DIV_SEL_1_5	(1<<22)
+#define  BXT_CDCLK_CD2X_DIV_SEL_2	(2<<22)
+#define  BXT_CDCLK_CD2X_DIV_SEL_4	(3<<22)
+#define  BXT_CDCLK_SSA_PRECHARGE_ENABLE	(1<<16)
+
+/* LCPLL_CTL */
+#define LCPLL1_CTL		_MMIO(0x46010)
+#define LCPLL2_CTL		_MMIO(0x46014)
+#define  LCPLL_PLL_ENABLE	(1<<31)
+
+/* DPLL control1 */
+#define DPLL_CTRL1		_MMIO(0x6C058)
+#define  DPLL_CTRL1_HDMI_MODE(id)		(1<<((id)*6+5))
+#define  DPLL_CTRL1_SSC(id)			(1<<((id)*6+4))
+#define  DPLL_CTRL1_LINK_RATE_MASK(id)		(7<<((id)*6+1))
+#define  DPLL_CTRL1_LINK_RATE_SHIFT(id)		((id)*6+1)
+#define  DPLL_CTRL1_LINK_RATE(linkrate, id)	((linkrate)<<((id)*6+1))
+#define  DPLL_CTRL1_OVERRIDE(id)		(1<<((id)*6))
+#define  DPLL_CTRL1_LINK_RATE_2700		0
+#define  DPLL_CTRL1_LINK_RATE_1350		1
+#define  DPLL_CTRL1_LINK_RATE_810		2
+#define  DPLL_CTRL1_LINK_RATE_1620		3
+#define  DPLL_CTRL1_LINK_RATE_1080		4
+#define  DPLL_CTRL1_LINK_RATE_2160		5
+
+/* DPLL control2 */
+#define DPLL_CTRL2				_MMIO(0x6C05C)
+#define  DPLL_CTRL2_DDI_CLK_OFF(port)		(1<<((port)+15))
+#define  DPLL_CTRL2_DDI_CLK_SEL_MASK(port)	(3<<((port)*3+1))
+#define  DPLL_CTRL2_DDI_CLK_SEL_SHIFT(port)    ((port)*3+1)
+#define  DPLL_CTRL2_DDI_CLK_SEL(clk, port)	((clk)<<((port)*3+1))
+#define  DPLL_CTRL2_DDI_SEL_OVERRIDE(port)     (1<<((port)*3))
+
+/* DPLL Status */
+#define DPLL_STATUS	_MMIO(0x6C060)
+#define  DPLL_LOCK(id) (1<<((id)*8))
+
+/* DPLL cfg */
+#define _DPLL1_CFGCR1	0x6C040
+#define _DPLL2_CFGCR1	0x6C048
+#define _DPLL3_CFGCR1	0x6C050
+#define  DPLL_CFGCR1_FREQ_ENABLE	(1<<31)
+#define  DPLL_CFGCR1_DCO_FRACTION_MASK	(0x7fff<<9)
+#define  DPLL_CFGCR1_DCO_FRACTION(x)	((x)<<9)
+#define  DPLL_CFGCR1_DCO_INTEGER_MASK	(0x1ff)
+
+#define _DPLL1_CFGCR2	0x6C044
+#define _DPLL2_CFGCR2	0x6C04C
+#define _DPLL3_CFGCR2	0x6C054
+#define  DPLL_CFGCR2_QDIV_RATIO_MASK	(0xff<<8)
+#define  DPLL_CFGCR2_QDIV_RATIO(x)	((x)<<8)
+#define  DPLL_CFGCR2_QDIV_MODE(x)	((x)<<7)
+#define  DPLL_CFGCR2_KDIV_MASK		(3<<5)
+#define  DPLL_CFGCR2_KDIV(x)		((x)<<5)
+#define  DPLL_CFGCR2_KDIV_5 (0<<5)
+#define  DPLL_CFGCR2_KDIV_2 (1<<5)
+#define  DPLL_CFGCR2_KDIV_3 (2<<5)
+#define  DPLL_CFGCR2_KDIV_1 (3<<5)
+#define  DPLL_CFGCR2_PDIV_MASK		(7<<2)
+#define  DPLL_CFGCR2_PDIV(x)		((x)<<2)
+#define  DPLL_CFGCR2_PDIV_1 (0<<2)
+#define  DPLL_CFGCR2_PDIV_2 (1<<2)
+#define  DPLL_CFGCR2_PDIV_3 (2<<2)
+#define  DPLL_CFGCR2_PDIV_7 (4<<2)
+#define  DPLL_CFGCR2_CENTRAL_FREQ_MASK	(3)
+
+#define DPLL_CFGCR1(id)	_MMIO_PIPE((id) - SKL_DPLL1, _DPLL1_CFGCR1, _DPLL2_CFGCR1)
+#define DPLL_CFGCR2(id)	_MMIO_PIPE((id) - SKL_DPLL1, _DPLL1_CFGCR2, _DPLL2_CFGCR2)
+
+/* BXT display engine PLL */
+#define BXT_DE_PLL_CTL			_MMIO(0x6d000)
+#define   BXT_DE_PLL_RATIO(x)		(x)	/* {60,65,100} * 19.2MHz */
+#define   BXT_DE_PLL_RATIO_MASK		0xff
+
+#define BXT_DE_PLL_ENABLE		_MMIO(0x46070)
+#define   BXT_DE_PLL_PLL_ENABLE		(1 << 31)
+#define   BXT_DE_PLL_LOCK		(1 << 30)
+
+/* GEN9 DC */
+#define DC_STATE_EN			_MMIO(0x45504)
+#define  DC_STATE_DISABLE		0
+#define  DC_STATE_EN_UPTO_DC5		(1<<0)
+#define  DC_STATE_EN_DC9		(1<<3)
+#define  DC_STATE_EN_UPTO_DC6		(2<<0)
+#define  DC_STATE_EN_UPTO_DC5_DC6_MASK   0x3
+
+#define  DC_STATE_DEBUG                  _MMIO(0x45520)
+#define  DC_STATE_DEBUG_MASK_CORES	(1<<0)
+#define  DC_STATE_DEBUG_MASK_MEMORY_UP	(1<<1)
+
+/* Please see hsw_read_dcomp() and hsw_write_dcomp() before using this register,
+ * since on HSW we can't write to it using I915_WRITE. */
+#define D_COMP_HSW			_MMIO(MCHBAR_MIRROR_BASE_SNB + 0x5F0C)
+#define D_COMP_BDW			_MMIO(0x138144)
+#define  D_COMP_RCOMP_IN_PROGRESS	(1<<9)
+#define  D_COMP_COMP_FORCE		(1<<8)
+#define  D_COMP_COMP_DISABLE		(1<<0)
+
+/* Pipe WM_LINETIME - watermark line time */
+#define _PIPE_WM_LINETIME_A		0x45270
+#define _PIPE_WM_LINETIME_B		0x45274
+#define PIPE_WM_LINETIME(pipe) _MMIO_PIPE(pipe, _PIPE_WM_LINETIME_A, _PIPE_WM_LINETIME_B)
+#define   PIPE_WM_LINETIME_MASK			(0x1ff)
+#define   PIPE_WM_LINETIME_TIME(x)		((x))
+#define   PIPE_WM_LINETIME_IPS_LINETIME_MASK	(0x1ff<<16)
+#define   PIPE_WM_LINETIME_IPS_LINETIME(x)	((x)<<16)
+
+/* SFUSE_STRAP */
+#define SFUSE_STRAP			_MMIO(0xc2014)
+#define  SFUSE_STRAP_FUSE_LOCK		(1<<13)
+#define  SFUSE_STRAP_DISPLAY_DISABLED	(1<<7)
+#define  SFUSE_STRAP_CRT_DISABLED	(1<<6)
+#define  SFUSE_STRAP_DDIB_DETECTED	(1<<2)
+#define  SFUSE_STRAP_DDIC_DETECTED	(1<<1)
+#define  SFUSE_STRAP_DDID_DETECTED	(1<<0)
+
+#define WM_MISC				_MMIO(0x45260)
+#define  WM_MISC_DATA_PARTITION_5_6	(1 << 0)
+
+#define WM_DBG				_MMIO(0x45280)
+#define  WM_DBG_DISALLOW_MULTIPLE_LP	(1<<0)
+#define  WM_DBG_DISALLOW_MAXFIFO	(1<<1)
+#define  WM_DBG_DISALLOW_SPRITE		(1<<2)
+
+/* pipe CSC */
+#define _PIPE_A_CSC_COEFF_RY_GY	0x49010
+#define _PIPE_A_CSC_COEFF_BY	0x49014
+#define _PIPE_A_CSC_COEFF_RU_GU	0x49018
+#define _PIPE_A_CSC_COEFF_BU	0x4901c
+#define _PIPE_A_CSC_COEFF_RV_GV	0x49020
+#define _PIPE_A_CSC_COEFF_BV	0x49024
+#define _PIPE_A_CSC_MODE	0x49028
+#define   CSC_BLACK_SCREEN_OFFSET	(1 << 2)
+#define   CSC_POSITION_BEFORE_GAMMA	(1 << 1)
+#define   CSC_MODE_YUV_TO_RGB		(1 << 0)
+#define _PIPE_A_CSC_PREOFF_HI	0x49030
+#define _PIPE_A_CSC_PREOFF_ME	0x49034
+#define _PIPE_A_CSC_PREOFF_LO	0x49038
+#define _PIPE_A_CSC_POSTOFF_HI	0x49040
+#define _PIPE_A_CSC_POSTOFF_ME	0x49044
+#define _PIPE_A_CSC_POSTOFF_LO	0x49048
+
+#define _PIPE_B_CSC_COEFF_RY_GY	0x49110
+#define _PIPE_B_CSC_COEFF_BY	0x49114
+#define _PIPE_B_CSC_COEFF_RU_GU	0x49118
+#define _PIPE_B_CSC_COEFF_BU	0x4911c
+#define _PIPE_B_CSC_COEFF_RV_GV	0x49120
+#define _PIPE_B_CSC_COEFF_BV	0x49124
+#define _PIPE_B_CSC_MODE	0x49128
+#define _PIPE_B_CSC_PREOFF_HI	0x49130
+#define _PIPE_B_CSC_PREOFF_ME	0x49134
+#define _PIPE_B_CSC_PREOFF_LO	0x49138
+#define _PIPE_B_CSC_POSTOFF_HI	0x49140
+#define _PIPE_B_CSC_POSTOFF_ME	0x49144
+#define _PIPE_B_CSC_POSTOFF_LO	0x49148
+
+#define PIPE_CSC_COEFF_RY_GY(pipe)	_MMIO_PIPE(pipe, _PIPE_A_CSC_COEFF_RY_GY, _PIPE_B_CSC_COEFF_RY_GY)
+#define PIPE_CSC_COEFF_BY(pipe)		_MMIO_PIPE(pipe, _PIPE_A_CSC_COEFF_BY, _PIPE_B_CSC_COEFF_BY)
+#define PIPE_CSC_COEFF_RU_GU(pipe)	_MMIO_PIPE(pipe, _PIPE_A_CSC_COEFF_RU_GU, _PIPE_B_CSC_COEFF_RU_GU)
+#define PIPE_CSC_COEFF_BU(pipe)		_MMIO_PIPE(pipe, _PIPE_A_CSC_COEFF_BU, _PIPE_B_CSC_COEFF_BU)
+#define PIPE_CSC_COEFF_RV_GV(pipe)	_MMIO_PIPE(pipe, _PIPE_A_CSC_COEFF_RV_GV, _PIPE_B_CSC_COEFF_RV_GV)
+#define PIPE_CSC_COEFF_BV(pipe)		_MMIO_PIPE(pipe, _PIPE_A_CSC_COEFF_BV, _PIPE_B_CSC_COEFF_BV)
+#define PIPE_CSC_MODE(pipe)		_MMIO_PIPE(pipe, _PIPE_A_CSC_MODE, _PIPE_B_CSC_MODE)
+#define PIPE_CSC_PREOFF_HI(pipe)	_MMIO_PIPE(pipe, _PIPE_A_CSC_PREOFF_HI, _PIPE_B_CSC_PREOFF_HI)
+#define PIPE_CSC_PREOFF_ME(pipe)	_MMIO_PIPE(pipe, _PIPE_A_CSC_PREOFF_ME, _PIPE_B_CSC_PREOFF_ME)
+#define PIPE_CSC_PREOFF_LO(pipe)	_MMIO_PIPE(pipe, _PIPE_A_CSC_PREOFF_LO, _PIPE_B_CSC_PREOFF_LO)
+#define PIPE_CSC_POSTOFF_HI(pipe)	_MMIO_PIPE(pipe, _PIPE_A_CSC_POSTOFF_HI, _PIPE_B_CSC_POSTOFF_HI)
+#define PIPE_CSC_POSTOFF_ME(pipe)	_MMIO_PIPE(pipe, _PIPE_A_CSC_POSTOFF_ME, _PIPE_B_CSC_POSTOFF_ME)
+#define PIPE_CSC_POSTOFF_LO(pipe)	_MMIO_PIPE(pipe, _PIPE_A_CSC_POSTOFF_LO, _PIPE_B_CSC_POSTOFF_LO)
+
+/* pipe degamma/gamma LUTs on IVB+ */
+#define _PAL_PREC_INDEX_A	0x4A400
+#define _PAL_PREC_INDEX_B	0x4AC00
+#define _PAL_PREC_INDEX_C	0x4B400
+#define   PAL_PREC_10_12_BIT		(0 << 31)
+#define   PAL_PREC_SPLIT_MODE		(1 << 31)
+#define   PAL_PREC_AUTO_INCREMENT	(1 << 15)
+#define _PAL_PREC_DATA_A	0x4A404
+#define _PAL_PREC_DATA_B	0x4AC04
+#define _PAL_PREC_DATA_C	0x4B404
+#define _PAL_PREC_GC_MAX_A	0x4A410
+#define _PAL_PREC_GC_MAX_B	0x4AC10
+#define _PAL_PREC_GC_MAX_C	0x4B410
+#define _PAL_PREC_EXT_GC_MAX_A	0x4A420
+#define _PAL_PREC_EXT_GC_MAX_B	0x4AC20
+#define _PAL_PREC_EXT_GC_MAX_C	0x4B420
+
+#define PREC_PAL_INDEX(pipe)		_MMIO_PIPE(pipe, _PAL_PREC_INDEX_A, _PAL_PREC_INDEX_B)
+#define PREC_PAL_DATA(pipe)		_MMIO_PIPE(pipe, _PAL_PREC_DATA_A, _PAL_PREC_DATA_B)
+#define PREC_PAL_GC_MAX(pipe, i)	_MMIO(_PIPE(pipe, _PAL_PREC_GC_MAX_A, _PAL_PREC_GC_MAX_B) + (i) * 4)
+#define PREC_PAL_EXT_GC_MAX(pipe, i)	_MMIO(_PIPE(pipe, _PAL_PREC_EXT_GC_MAX_A, _PAL_PREC_EXT_GC_MAX_B) + (i) * 4)
+
+/* pipe CSC & degamma/gamma LUTs on CHV */
+#define _CGM_PIPE_A_CSC_COEFF01	(VLV_DISPLAY_BASE + 0x67900)
+#define _CGM_PIPE_A_CSC_COEFF23	(VLV_DISPLAY_BASE + 0x67904)
+#define _CGM_PIPE_A_CSC_COEFF45	(VLV_DISPLAY_BASE + 0x67908)
+#define _CGM_PIPE_A_CSC_COEFF67	(VLV_DISPLAY_BASE + 0x6790C)
+#define _CGM_PIPE_A_CSC_COEFF8	(VLV_DISPLAY_BASE + 0x67910)
+#define _CGM_PIPE_A_DEGAMMA	(VLV_DISPLAY_BASE + 0x66000)
+#define _CGM_PIPE_A_GAMMA	(VLV_DISPLAY_BASE + 0x67000)
+#define _CGM_PIPE_A_MODE	(VLV_DISPLAY_BASE + 0x67A00)
+#define   CGM_PIPE_MODE_GAMMA	(1 << 2)
+#define   CGM_PIPE_MODE_CSC	(1 << 1)
+#define   CGM_PIPE_MODE_DEGAMMA	(1 << 0)
+
+#define _CGM_PIPE_B_CSC_COEFF01	(VLV_DISPLAY_BASE + 0x69900)
+#define _CGM_PIPE_B_CSC_COEFF23	(VLV_DISPLAY_BASE + 0x69904)
+#define _CGM_PIPE_B_CSC_COEFF45	(VLV_DISPLAY_BASE + 0x69908)
+#define _CGM_PIPE_B_CSC_COEFF67	(VLV_DISPLAY_BASE + 0x6990C)
+#define _CGM_PIPE_B_CSC_COEFF8	(VLV_DISPLAY_BASE + 0x69910)
+#define _CGM_PIPE_B_DEGAMMA	(VLV_DISPLAY_BASE + 0x68000)
+#define _CGM_PIPE_B_GAMMA	(VLV_DISPLAY_BASE + 0x69000)
+#define _CGM_PIPE_B_MODE	(VLV_DISPLAY_BASE + 0x69A00)
+
+#define CGM_PIPE_CSC_COEFF01(pipe)	_MMIO_PIPE(pipe, _CGM_PIPE_A_CSC_COEFF01, _CGM_PIPE_B_CSC_COEFF01)
+#define CGM_PIPE_CSC_COEFF23(pipe)	_MMIO_PIPE(pipe, _CGM_PIPE_A_CSC_COEFF23, _CGM_PIPE_B_CSC_COEFF23)
+#define CGM_PIPE_CSC_COEFF45(pipe)	_MMIO_PIPE(pipe, _CGM_PIPE_A_CSC_COEFF45, _CGM_PIPE_B_CSC_COEFF45)
+#define CGM_PIPE_CSC_COEFF67(pipe)	_MMIO_PIPE(pipe, _CGM_PIPE_A_CSC_COEFF67, _CGM_PIPE_B_CSC_COEFF67)
+#define CGM_PIPE_CSC_COEFF8(pipe)	_MMIO_PIPE(pipe, _CGM_PIPE_A_CSC_COEFF8, _CGM_PIPE_B_CSC_COEFF8)
+#define CGM_PIPE_DEGAMMA(pipe, i, w)	_MMIO(_PIPE(pipe, _CGM_PIPE_A_DEGAMMA, _CGM_PIPE_B_DEGAMMA) + (i) * 8 + (w) * 4)
+#define CGM_PIPE_GAMMA(pipe, i, w)	_MMIO(_PIPE(pipe, _CGM_PIPE_A_GAMMA, _CGM_PIPE_B_GAMMA) + (i) * 8 + (w) * 4)
+#define CGM_PIPE_MODE(pipe)		_MMIO_PIPE(pipe, _CGM_PIPE_A_MODE, _CGM_PIPE_B_MODE)
+
+/* MIPI DSI registers */
+
+#define _MIPI_PORT(port, a, c)	_PORT3(port, a, 0, c)	/* ports A and C only */
+#define _MMIO_MIPI(port, a, c)	_MMIO(_MIPI_PORT(port, a, c))
+
+/* BXT MIPI clock controls */
+#define BXT_MAX_VAR_OUTPUT_KHZ			39500
+
+#define BXT_MIPI_CLOCK_CTL			_MMIO(0x46090)
+#define  BXT_MIPI1_DIV_SHIFT			26
+#define  BXT_MIPI2_DIV_SHIFT			10
+#define  BXT_MIPI_DIV_SHIFT(port)		\
+			_MIPI_PORT(port, BXT_MIPI1_DIV_SHIFT, \
+					BXT_MIPI2_DIV_SHIFT)
+
+/* TX control divider to select actual TX clock output from (8x/var) */
+#define  BXT_MIPI1_TX_ESCLK_SHIFT		26
+#define  BXT_MIPI2_TX_ESCLK_SHIFT		10
+#define  BXT_MIPI_TX_ESCLK_SHIFT(port)		\
+			_MIPI_PORT(port, BXT_MIPI1_TX_ESCLK_SHIFT, \
+					BXT_MIPI2_TX_ESCLK_SHIFT)
+#define  BXT_MIPI1_TX_ESCLK_FIXDIV_MASK		(0x3F << 26)
+#define  BXT_MIPI2_TX_ESCLK_FIXDIV_MASK		(0x3F << 10)
+#define  BXT_MIPI_TX_ESCLK_FIXDIV_MASK(port)	\
+			_MIPI_PORT(port, BXT_MIPI1_TX_ESCLK_FIXDIV_MASK, \
+					BXT_MIPI2_TX_ESCLK_FIXDIV_MASK)
+#define  BXT_MIPI_TX_ESCLK_DIVIDER(port, val)	\
+		((val & 0x3F) << BXT_MIPI_TX_ESCLK_SHIFT(port))
+/* RX upper control divider to select actual RX clock output from 8x */
+#define  BXT_MIPI1_RX_ESCLK_UPPER_SHIFT		21
+#define  BXT_MIPI2_RX_ESCLK_UPPER_SHIFT		5
+#define  BXT_MIPI_RX_ESCLK_UPPER_SHIFT(port)		\
+			_MIPI_PORT(port, BXT_MIPI1_RX_ESCLK_UPPER_SHIFT, \
+					BXT_MIPI2_RX_ESCLK_UPPER_SHIFT)
+#define  BXT_MIPI1_RX_ESCLK_UPPER_FIXDIV_MASK		(3 << 21)
+#define  BXT_MIPI2_RX_ESCLK_UPPER_FIXDIV_MASK		(3 << 5)
+#define  BXT_MIPI_RX_ESCLK_UPPER_FIXDIV_MASK(port)	\
+			_MIPI_PORT(port, BXT_MIPI1_RX_ESCLK_UPPER_FIXDIV_MASK, \
+					BXT_MIPI2_RX_ESCLK_UPPER_FIXDIV_MASK)
+#define  BXT_MIPI_RX_ESCLK_UPPER_DIVIDER(port, val)	\
+		((val & 3) << BXT_MIPI_RX_ESCLK_UPPER_SHIFT(port))
+/* 8/3X divider to select the actual 8/3X clock output from 8x */
+#define  BXT_MIPI1_8X_BY3_SHIFT                19
+#define  BXT_MIPI2_8X_BY3_SHIFT                3
+#define  BXT_MIPI_8X_BY3_SHIFT(port)          \
+			_MIPI_PORT(port, BXT_MIPI1_8X_BY3_SHIFT, \
+					BXT_MIPI2_8X_BY3_SHIFT)
+#define  BXT_MIPI1_8X_BY3_DIVIDER_MASK         (3 << 19)
+#define  BXT_MIPI2_8X_BY3_DIVIDER_MASK         (3 << 3)
+#define  BXT_MIPI_8X_BY3_DIVIDER_MASK(port)    \
+			_MIPI_PORT(port, BXT_MIPI1_8X_BY3_DIVIDER_MASK, \
+						BXT_MIPI2_8X_BY3_DIVIDER_MASK)
+#define  BXT_MIPI_8X_BY3_DIVIDER(port, val)    \
+			((val & 3) << BXT_MIPI_8X_BY3_SHIFT(port))
+/* RX lower control divider to select actual RX clock output from 8x */
+#define  BXT_MIPI1_RX_ESCLK_LOWER_SHIFT		16
+#define  BXT_MIPI2_RX_ESCLK_LOWER_SHIFT		0
+#define  BXT_MIPI_RX_ESCLK_LOWER_SHIFT(port)		\
+			_MIPI_PORT(port, BXT_MIPI1_RX_ESCLK_LOWER_SHIFT, \
+					BXT_MIPI2_RX_ESCLK_LOWER_SHIFT)
+#define  BXT_MIPI1_RX_ESCLK_LOWER_FIXDIV_MASK		(3 << 16)
+#define  BXT_MIPI2_RX_ESCLK_LOWER_FIXDIV_MASK		(3 << 0)
+#define  BXT_MIPI_RX_ESCLK_LOWER_FIXDIV_MASK(port)	\
+			_MIPI_PORT(port, BXT_MIPI1_RX_ESCLK_LOWER_FIXDIV_MASK, \
+					BXT_MIPI2_RX_ESCLK_LOWER_FIXDIV_MASK)
+#define  BXT_MIPI_RX_ESCLK_LOWER_DIVIDER(port, val)	\
+		((val & 3) << BXT_MIPI_RX_ESCLK_LOWER_SHIFT(port))
+
+#define RX_DIVIDER_BIT_1_2                     0x3
+#define RX_DIVIDER_BIT_3_4                     0xC
+
+/* BXT MIPI mode configure */
+#define  _BXT_MIPIA_TRANS_HACTIVE			0x6B0F8
+#define  _BXT_MIPIC_TRANS_HACTIVE			0x6B8F8
+#define  BXT_MIPI_TRANS_HACTIVE(tc)	_MMIO_MIPI(tc, \
+		_BXT_MIPIA_TRANS_HACTIVE, _BXT_MIPIC_TRANS_HACTIVE)
+
+#define  _BXT_MIPIA_TRANS_VACTIVE			0x6B0FC
+#define  _BXT_MIPIC_TRANS_VACTIVE			0x6B8FC
+#define  BXT_MIPI_TRANS_VACTIVE(tc)	_MMIO_MIPI(tc, \
+		_BXT_MIPIA_TRANS_VACTIVE, _BXT_MIPIC_TRANS_VACTIVE)
+
+#define  _BXT_MIPIA_TRANS_VTOTAL			0x6B100
+#define  _BXT_MIPIC_TRANS_VTOTAL			0x6B900
+#define  BXT_MIPI_TRANS_VTOTAL(tc)	_MMIO_MIPI(tc, \
+		_BXT_MIPIA_TRANS_VTOTAL, _BXT_MIPIC_TRANS_VTOTAL)
+
+#define BXT_DSI_PLL_CTL			_MMIO(0x161000)
+#define  BXT_DSI_PLL_PVD_RATIO_SHIFT	16
+#define  BXT_DSI_PLL_PVD_RATIO_MASK	(3 << BXT_DSI_PLL_PVD_RATIO_SHIFT)
+#define  BXT_DSI_PLL_PVD_RATIO_1	(1 << BXT_DSI_PLL_PVD_RATIO_SHIFT)
+#define  BXT_DSIC_16X_BY2		(1 << 10)
+#define  BXT_DSIC_16X_BY3		(2 << 10)
+#define  BXT_DSIC_16X_BY4		(3 << 10)
+#define  BXT_DSIC_16X_MASK		(3 << 10)
+#define  BXT_DSIA_16X_BY2		(1 << 8)
+#define  BXT_DSIA_16X_BY3		(2 << 8)
+#define  BXT_DSIA_16X_BY4		(3 << 8)
+#define  BXT_DSIA_16X_MASK		(3 << 8)
+#define  BXT_DSI_FREQ_SEL_SHIFT		8
+#define  BXT_DSI_FREQ_SEL_MASK		(0xF << BXT_DSI_FREQ_SEL_SHIFT)
+
+#define BXT_DSI_PLL_RATIO_MAX		0x7D
+#define BXT_DSI_PLL_RATIO_MIN		0x22
+#define BXT_DSI_PLL_RATIO_MASK		0xFF
+#define BXT_REF_CLOCK_KHZ		19200
+
+#define BXT_DSI_PLL_ENABLE		_MMIO(0x46080)
+#define  BXT_DSI_PLL_DO_ENABLE		(1 << 31)
+#define  BXT_DSI_PLL_LOCKED		(1 << 30)
+
+#define _MIPIA_PORT_CTRL			(VLV_DISPLAY_BASE + 0x61190)
+#define _MIPIC_PORT_CTRL			(VLV_DISPLAY_BASE + 0x61700)
+#define MIPI_PORT_CTRL(port)	_MMIO_MIPI(port, _MIPIA_PORT_CTRL, _MIPIC_PORT_CTRL)
+
+ /* BXT port control */
+#define _BXT_MIPIA_PORT_CTRL				0x6B0C0
+#define _BXT_MIPIC_PORT_CTRL				0x6B8C0
+#define BXT_MIPI_PORT_CTRL(tc)	_MMIO_MIPI(tc, _BXT_MIPIA_PORT_CTRL, _BXT_MIPIC_PORT_CTRL)
+
+#define  DPI_ENABLE					(1 << 31) /* A + C */
+#define  MIPIA_MIPI4DPHY_DELAY_COUNT_SHIFT		27
+#define  MIPIA_MIPI4DPHY_DELAY_COUNT_MASK		(0xf << 27)
+#define  DUAL_LINK_MODE_SHIFT				26
+#define  DUAL_LINK_MODE_MASK				(1 << 26)
+#define  DUAL_LINK_MODE_FRONT_BACK			(0 << 26)
+#define  DUAL_LINK_MODE_PIXEL_ALTERNATIVE		(1 << 26)
+#define  DITHERING_ENABLE				(1 << 25) /* A + C */
+#define  FLOPPED_HSTX					(1 << 23)
+#define  DE_INVERT					(1 << 19) /* XXX */
+#define  MIPIA_FLISDSI_DELAY_COUNT_SHIFT		18
+#define  MIPIA_FLISDSI_DELAY_COUNT_MASK			(0xf << 18)
+#define  AFE_LATCHOUT					(1 << 17)
+#define  LP_OUTPUT_HOLD					(1 << 16)
+#define  MIPIC_FLISDSI_DELAY_COUNT_HIGH_SHIFT		15
+#define  MIPIC_FLISDSI_DELAY_COUNT_HIGH_MASK		(1 << 15)
+#define  MIPIC_MIPI4DPHY_DELAY_COUNT_SHIFT		11
+#define  MIPIC_MIPI4DPHY_DELAY_COUNT_MASK		(0xf << 11)
+#define  CSB_SHIFT					9
+#define  CSB_MASK					(3 << 9)
+#define  CSB_20MHZ					(0 << 9)
+#define  CSB_10MHZ					(1 << 9)
+#define  CSB_40MHZ					(2 << 9)
+#define  BANDGAP_MASK					(1 << 8)
+#define  BANDGAP_PNW_CIRCUIT				(0 << 8)
+#define  BANDGAP_LNC_CIRCUIT				(1 << 8)
+#define  MIPIC_FLISDSI_DELAY_COUNT_LOW_SHIFT		5
+#define  MIPIC_FLISDSI_DELAY_COUNT_LOW_MASK		(7 << 5)
+#define  TEARING_EFFECT_DELAY				(1 << 4) /* A + C */
+#define  TEARING_EFFECT_SHIFT				2 /* A + C */
+#define  TEARING_EFFECT_MASK				(3 << 2)
+#define  TEARING_EFFECT_OFF				(0 << 2)
+#define  TEARING_EFFECT_DSI				(1 << 2)
+#define  TEARING_EFFECT_GPIO				(2 << 2)
+#define  LANE_CONFIGURATION_SHIFT			0
+#define  LANE_CONFIGURATION_MASK			(3 << 0)
+#define  LANE_CONFIGURATION_4LANE			(0 << 0)
+#define  LANE_CONFIGURATION_DUAL_LINK_A			(1 << 0)
+#define  LANE_CONFIGURATION_DUAL_LINK_B			(2 << 0)
+
+#define _MIPIA_TEARING_CTRL			(VLV_DISPLAY_BASE + 0x61194)
+#define _MIPIC_TEARING_CTRL			(VLV_DISPLAY_BASE + 0x61704)
+#define MIPI_TEARING_CTRL(port)			_MMIO_MIPI(port, _MIPIA_TEARING_CTRL, _MIPIC_TEARING_CTRL)
+#define  TEARING_EFFECT_DELAY_SHIFT			0
+#define  TEARING_EFFECT_DELAY_MASK			(0xffff << 0)
+
+/* XXX: all bits reserved */
+#define _MIPIA_AUTOPWG			(VLV_DISPLAY_BASE + 0x611a0)
+
+/* MIPI DSI Controller and D-PHY registers */
+
+#define _MIPIA_DEVICE_READY		(dev_priv->mipi_mmio_base + 0xb000)
+#define _MIPIC_DEVICE_READY		(dev_priv->mipi_mmio_base + 0xb800)
+#define MIPI_DEVICE_READY(port)		_MMIO_MIPI(port, _MIPIA_DEVICE_READY, _MIPIC_DEVICE_READY)
+#define  BUS_POSSESSION					(1 << 3) /* set to give bus to receiver */
+#define  ULPS_STATE_MASK				(3 << 1)
+#define  ULPS_STATE_ENTER				(2 << 1)
+#define  ULPS_STATE_EXIT				(1 << 1)
+#define  ULPS_STATE_NORMAL_OPERATION			(0 << 1)
+#define  DEVICE_READY					(1 << 0)
+
+#define _MIPIA_INTR_STAT		(dev_priv->mipi_mmio_base + 0xb004)
+#define _MIPIC_INTR_STAT		(dev_priv->mipi_mmio_base + 0xb804)
+#define MIPI_INTR_STAT(port)		_MMIO_MIPI(port, _MIPIA_INTR_STAT, _MIPIC_INTR_STAT)
+#define _MIPIA_INTR_EN			(dev_priv->mipi_mmio_base + 0xb008)
+#define _MIPIC_INTR_EN			(dev_priv->mipi_mmio_base + 0xb808)
+#define MIPI_INTR_EN(port)		_MMIO_MIPI(port, _MIPIA_INTR_EN, _MIPIC_INTR_EN)
+#define  TEARING_EFFECT					(1 << 31)
+#define  SPL_PKT_SENT_INTERRUPT				(1 << 30)
+#define  GEN_READ_DATA_AVAIL				(1 << 29)
+#define  LP_GENERIC_WR_FIFO_FULL			(1 << 28)
+#define  HS_GENERIC_WR_FIFO_FULL			(1 << 27)
+#define  RX_PROT_VIOLATION				(1 << 26)
+#define  RX_INVALID_TX_LENGTH				(1 << 25)
+#define  ACK_WITH_NO_ERROR				(1 << 24)
+#define  TURN_AROUND_ACK_TIMEOUT			(1 << 23)
+#define  LP_RX_TIMEOUT					(1 << 22)
+#define  HS_TX_TIMEOUT					(1 << 21)
+#define  DPI_FIFO_UNDERRUN				(1 << 20)
+#define  LOW_CONTENTION					(1 << 19)
+#define  HIGH_CONTENTION				(1 << 18)
+#define  TXDSI_VC_ID_INVALID				(1 << 17)
+#define  TXDSI_DATA_TYPE_NOT_RECOGNISED			(1 << 16)
+#define  TXCHECKSUM_ERROR				(1 << 15)
+#define  TXECC_MULTIBIT_ERROR				(1 << 14)
+#define  TXECC_SINGLE_BIT_ERROR				(1 << 13)
+#define  TXFALSE_CONTROL_ERROR				(1 << 12)
+#define  RXDSI_VC_ID_INVALID				(1 << 11)
+#define  RXDSI_DATA_TYPE_NOT_REGOGNISED			(1 << 10)
+#define  RXCHECKSUM_ERROR				(1 << 9)
+#define  RXECC_MULTIBIT_ERROR				(1 << 8)
+#define  RXECC_SINGLE_BIT_ERROR				(1 << 7)
+#define  RXFALSE_CONTROL_ERROR				(1 << 6)
+#define  RXHS_RECEIVE_TIMEOUT_ERROR			(1 << 5)
+#define  RX_LP_TX_SYNC_ERROR				(1 << 4)
+#define  RXEXCAPE_MODE_ENTRY_ERROR			(1 << 3)
+#define  RXEOT_SYNC_ERROR				(1 << 2)
+#define  RXSOT_SYNC_ERROR				(1 << 1)
+#define  RXSOT_ERROR					(1 << 0)
+
+#define _MIPIA_DSI_FUNC_PRG		(dev_priv->mipi_mmio_base + 0xb00c)
+#define _MIPIC_DSI_FUNC_PRG		(dev_priv->mipi_mmio_base + 0xb80c)
+#define MIPI_DSI_FUNC_PRG(port)		_MMIO_MIPI(port, _MIPIA_DSI_FUNC_PRG, _MIPIC_DSI_FUNC_PRG)
+#define  CMD_MODE_DATA_WIDTH_MASK			(7 << 13)
+#define  CMD_MODE_NOT_SUPPORTED				(0 << 13)
+#define  CMD_MODE_DATA_WIDTH_16_BIT			(1 << 13)
+#define  CMD_MODE_DATA_WIDTH_9_BIT			(2 << 13)
+#define  CMD_MODE_DATA_WIDTH_8_BIT			(3 << 13)
+#define  CMD_MODE_DATA_WIDTH_OPTION1			(4 << 13)
+#define  CMD_MODE_DATA_WIDTH_OPTION2			(5 << 13)
+#define  VID_MODE_FORMAT_MASK				(0xf << 7)
+#define  VID_MODE_NOT_SUPPORTED				(0 << 7)
+#define  VID_MODE_FORMAT_RGB565				(1 << 7)
+#define  VID_MODE_FORMAT_RGB666_PACKED			(2 << 7)
+#define  VID_MODE_FORMAT_RGB666				(3 << 7)
+#define  VID_MODE_FORMAT_RGB888				(4 << 7)
+#define  CMD_MODE_CHANNEL_NUMBER_SHIFT			5
+#define  CMD_MODE_CHANNEL_NUMBER_MASK			(3 << 5)
+#define  VID_MODE_CHANNEL_NUMBER_SHIFT			3
+#define  VID_MODE_CHANNEL_NUMBER_MASK			(3 << 3)
+#define  DATA_LANES_PRG_REG_SHIFT			0
+#define  DATA_LANES_PRG_REG_MASK			(7 << 0)
+
+#define _MIPIA_HS_TX_TIMEOUT		(dev_priv->mipi_mmio_base + 0xb010)
+#define _MIPIC_HS_TX_TIMEOUT		(dev_priv->mipi_mmio_base + 0xb810)
+#define MIPI_HS_TX_TIMEOUT(port)	_MMIO_MIPI(port, _MIPIA_HS_TX_TIMEOUT, _MIPIC_HS_TX_TIMEOUT)
+#define  HIGH_SPEED_TX_TIMEOUT_COUNTER_MASK		0xffffff
+
+#define _MIPIA_LP_RX_TIMEOUT		(dev_priv->mipi_mmio_base + 0xb014)
+#define _MIPIC_LP_RX_TIMEOUT		(dev_priv->mipi_mmio_base + 0xb814)
+#define MIPI_LP_RX_TIMEOUT(port)	_MMIO_MIPI(port, _MIPIA_LP_RX_TIMEOUT, _MIPIC_LP_RX_TIMEOUT)
+#define  LOW_POWER_RX_TIMEOUT_COUNTER_MASK		0xffffff
+
+#define _MIPIA_TURN_AROUND_TIMEOUT	(dev_priv->mipi_mmio_base + 0xb018)
+#define _MIPIC_TURN_AROUND_TIMEOUT	(dev_priv->mipi_mmio_base + 0xb818)
+#define MIPI_TURN_AROUND_TIMEOUT(port)	_MMIO_MIPI(port, _MIPIA_TURN_AROUND_TIMEOUT, _MIPIC_TURN_AROUND_TIMEOUT)
+#define  TURN_AROUND_TIMEOUT_MASK			0x3f
+
+#define _MIPIA_DEVICE_RESET_TIMER	(dev_priv->mipi_mmio_base + 0xb01c)
+#define _MIPIC_DEVICE_RESET_TIMER	(dev_priv->mipi_mmio_base + 0xb81c)
+#define MIPI_DEVICE_RESET_TIMER(port)	_MMIO_MIPI(port, _MIPIA_DEVICE_RESET_TIMER, _MIPIC_DEVICE_RESET_TIMER)
+#define  DEVICE_RESET_TIMER_MASK			0xffff
+
+#define _MIPIA_DPI_RESOLUTION		(dev_priv->mipi_mmio_base + 0xb020)
+#define _MIPIC_DPI_RESOLUTION		(dev_priv->mipi_mmio_base + 0xb820)
+#define MIPI_DPI_RESOLUTION(port)	_MMIO_MIPI(port, _MIPIA_DPI_RESOLUTION, _MIPIC_DPI_RESOLUTION)
+#define  VERTICAL_ADDRESS_SHIFT				16
+#define  VERTICAL_ADDRESS_MASK				(0xffff << 16)
+#define  HORIZONTAL_ADDRESS_SHIFT			0
+#define  HORIZONTAL_ADDRESS_MASK			0xffff
+
+#define _MIPIA_DBI_FIFO_THROTTLE	(dev_priv->mipi_mmio_base + 0xb024)
+#define _MIPIC_DBI_FIFO_THROTTLE	(dev_priv->mipi_mmio_base + 0xb824)
+#define MIPI_DBI_FIFO_THROTTLE(port)	_MMIO_MIPI(port, _MIPIA_DBI_FIFO_THROTTLE, _MIPIC_DBI_FIFO_THROTTLE)
+#define  DBI_FIFO_EMPTY_HALF				(0 << 0)
+#define  DBI_FIFO_EMPTY_QUARTER				(1 << 0)
+#define  DBI_FIFO_EMPTY_7_LOCATIONS			(2 << 0)
+
+/* regs below are bits 15:0 */
+#define _MIPIA_HSYNC_PADDING_COUNT	(dev_priv->mipi_mmio_base + 0xb028)
+#define _MIPIC_HSYNC_PADDING_COUNT	(dev_priv->mipi_mmio_base + 0xb828)
+#define MIPI_HSYNC_PADDING_COUNT(port)	_MMIO_MIPI(port, _MIPIA_HSYNC_PADDING_COUNT, _MIPIC_HSYNC_PADDING_COUNT)
+
+#define _MIPIA_HBP_COUNT		(dev_priv->mipi_mmio_base + 0xb02c)
+#define _MIPIC_HBP_COUNT		(dev_priv->mipi_mmio_base + 0xb82c)
+#define MIPI_HBP_COUNT(port)		_MMIO_MIPI(port, _MIPIA_HBP_COUNT, _MIPIC_HBP_COUNT)
+
+#define _MIPIA_HFP_COUNT		(dev_priv->mipi_mmio_base + 0xb030)
+#define _MIPIC_HFP_COUNT		(dev_priv->mipi_mmio_base + 0xb830)
+#define MIPI_HFP_COUNT(port)		_MMIO_MIPI(port, _MIPIA_HFP_COUNT, _MIPIC_HFP_COUNT)
+
+#define _MIPIA_HACTIVE_AREA_COUNT	(dev_priv->mipi_mmio_base + 0xb034)
+#define _MIPIC_HACTIVE_AREA_COUNT	(dev_priv->mipi_mmio_base + 0xb834)
+#define MIPI_HACTIVE_AREA_COUNT(port)	_MMIO_MIPI(port, _MIPIA_HACTIVE_AREA_COUNT, _MIPIC_HACTIVE_AREA_COUNT)
+
+#define _MIPIA_VSYNC_PADDING_COUNT	(dev_priv->mipi_mmio_base + 0xb038)
+#define _MIPIC_VSYNC_PADDING_COUNT	(dev_priv->mipi_mmio_base + 0xb838)
+#define MIPI_VSYNC_PADDING_COUNT(port)	_MMIO_MIPI(port, _MIPIA_VSYNC_PADDING_COUNT, _MIPIC_VSYNC_PADDING_COUNT)
+
+#define _MIPIA_VBP_COUNT		(dev_priv->mipi_mmio_base + 0xb03c)
+#define _MIPIC_VBP_COUNT		(dev_priv->mipi_mmio_base + 0xb83c)
+#define MIPI_VBP_COUNT(port)		_MMIO_MIPI(port, _MIPIA_VBP_COUNT, _MIPIC_VBP_COUNT)
+
+#define _MIPIA_VFP_COUNT		(dev_priv->mipi_mmio_base + 0xb040)
+#define _MIPIC_VFP_COUNT		(dev_priv->mipi_mmio_base + 0xb840)
+#define MIPI_VFP_COUNT(port)		_MMIO_MIPI(port, _MIPIA_VFP_COUNT, _MIPIC_VFP_COUNT)
+
+#define _MIPIA_HIGH_LOW_SWITCH_COUNT	(dev_priv->mipi_mmio_base + 0xb044)
+#define _MIPIC_HIGH_LOW_SWITCH_COUNT	(dev_priv->mipi_mmio_base + 0xb844)
+#define MIPI_HIGH_LOW_SWITCH_COUNT(port)	_MMIO_MIPI(port,	_MIPIA_HIGH_LOW_SWITCH_COUNT, _MIPIC_HIGH_LOW_SWITCH_COUNT)
+
+/* regs above are bits 15:0 */
+
+#define _MIPIA_DPI_CONTROL		(dev_priv->mipi_mmio_base + 0xb048)
+#define _MIPIC_DPI_CONTROL		(dev_priv->mipi_mmio_base + 0xb848)
+#define MIPI_DPI_CONTROL(port)		_MMIO_MIPI(port, _MIPIA_DPI_CONTROL, _MIPIC_DPI_CONTROL)
+#define  DPI_LP_MODE					(1 << 6)
+#define  BACKLIGHT_OFF					(1 << 5)
+#define  BACKLIGHT_ON					(1 << 4)
+#define  COLOR_MODE_OFF					(1 << 3)
+#define  COLOR_MODE_ON					(1 << 2)
+#define  TURN_ON					(1 << 1)
+#define  SHUTDOWN					(1 << 0)
+
+#define _MIPIA_DPI_DATA			(dev_priv->mipi_mmio_base + 0xb04c)
+#define _MIPIC_DPI_DATA			(dev_priv->mipi_mmio_base + 0xb84c)
+#define MIPI_DPI_DATA(port)		_MMIO_MIPI(port, _MIPIA_DPI_DATA, _MIPIC_DPI_DATA)
+#define  COMMAND_BYTE_SHIFT				0
+#define  COMMAND_BYTE_MASK				(0x3f << 0)
+
+#define _MIPIA_INIT_COUNT		(dev_priv->mipi_mmio_base + 0xb050)
+#define _MIPIC_INIT_COUNT		(dev_priv->mipi_mmio_base + 0xb850)
+#define MIPI_INIT_COUNT(port)		_MMIO_MIPI(port, _MIPIA_INIT_COUNT, _MIPIC_INIT_COUNT)
+#define  MASTER_INIT_TIMER_SHIFT			0
+#define  MASTER_INIT_TIMER_MASK				(0xffff << 0)
+
+#define _MIPIA_MAX_RETURN_PKT_SIZE	(dev_priv->mipi_mmio_base + 0xb054)
+#define _MIPIC_MAX_RETURN_PKT_SIZE	(dev_priv->mipi_mmio_base + 0xb854)
+#define MIPI_MAX_RETURN_PKT_SIZE(port)	_MMIO_MIPI(port, \
+			_MIPIA_MAX_RETURN_PKT_SIZE, _MIPIC_MAX_RETURN_PKT_SIZE)
+#define  MAX_RETURN_PKT_SIZE_SHIFT			0
+#define  MAX_RETURN_PKT_SIZE_MASK			(0x3ff << 0)
+
+#define _MIPIA_VIDEO_MODE_FORMAT	(dev_priv->mipi_mmio_base + 0xb058)
+#define _MIPIC_VIDEO_MODE_FORMAT	(dev_priv->mipi_mmio_base + 0xb858)
+#define MIPI_VIDEO_MODE_FORMAT(port)	_MMIO_MIPI(port, _MIPIA_VIDEO_MODE_FORMAT, _MIPIC_VIDEO_MODE_FORMAT)
+#define  RANDOM_DPI_DISPLAY_RESOLUTION			(1 << 4)
+#define  DISABLE_VIDEO_BTA				(1 << 3)
+#define  IP_TG_CONFIG					(1 << 2)
+#define  VIDEO_MODE_NON_BURST_WITH_SYNC_PULSE		(1 << 0)
+#define  VIDEO_MODE_NON_BURST_WITH_SYNC_EVENTS		(2 << 0)
+#define  VIDEO_MODE_BURST				(3 << 0)
+
+#define _MIPIA_EOT_DISABLE		(dev_priv->mipi_mmio_base + 0xb05c)
+#define _MIPIC_EOT_DISABLE		(dev_priv->mipi_mmio_base + 0xb85c)
+#define MIPI_EOT_DISABLE(port)		_MMIO_MIPI(port, _MIPIA_EOT_DISABLE, _MIPIC_EOT_DISABLE)
+#define  LP_RX_TIMEOUT_ERROR_RECOVERY_DISABLE		(1 << 7)
+#define  HS_RX_TIMEOUT_ERROR_RECOVERY_DISABLE		(1 << 6)
+#define  LOW_CONTENTION_RECOVERY_DISABLE		(1 << 5)
+#define  HIGH_CONTENTION_RECOVERY_DISABLE		(1 << 4)
+#define  TXDSI_TYPE_NOT_RECOGNISED_ERROR_RECOVERY_DISABLE (1 << 3)
+#define  TXECC_MULTIBIT_ERROR_RECOVERY_DISABLE		(1 << 2)
+#define  CLOCKSTOP					(1 << 1)
+#define  EOT_DISABLE					(1 << 0)
+
+#define _MIPIA_LP_BYTECLK		(dev_priv->mipi_mmio_base + 0xb060)
+#define _MIPIC_LP_BYTECLK		(dev_priv->mipi_mmio_base + 0xb860)
+#define MIPI_LP_BYTECLK(port)		_MMIO_MIPI(port, _MIPIA_LP_BYTECLK, _MIPIC_LP_BYTECLK)
+#define  LP_BYTECLK_SHIFT				0
+#define  LP_BYTECLK_MASK				(0xffff << 0)
+
+/* bits 31:0 */
+#define _MIPIA_LP_GEN_DATA		(dev_priv->mipi_mmio_base + 0xb064)
+#define _MIPIC_LP_GEN_DATA		(dev_priv->mipi_mmio_base + 0xb864)
+#define MIPI_LP_GEN_DATA(port)		_MMIO_MIPI(port, _MIPIA_LP_GEN_DATA, _MIPIC_LP_GEN_DATA)
+
+/* bits 31:0 */
+#define _MIPIA_HS_GEN_DATA		(dev_priv->mipi_mmio_base + 0xb068)
+#define _MIPIC_HS_GEN_DATA		(dev_priv->mipi_mmio_base + 0xb868)
+#define MIPI_HS_GEN_DATA(port)		_MMIO_MIPI(port, _MIPIA_HS_GEN_DATA, _MIPIC_HS_GEN_DATA)
+
+#define _MIPIA_LP_GEN_CTRL		(dev_priv->mipi_mmio_base + 0xb06c)
+#define _MIPIC_LP_GEN_CTRL		(dev_priv->mipi_mmio_base + 0xb86c)
+#define MIPI_LP_GEN_CTRL(port)		_MMIO_MIPI(port, _MIPIA_LP_GEN_CTRL, _MIPIC_LP_GEN_CTRL)
+#define _MIPIA_HS_GEN_CTRL		(dev_priv->mipi_mmio_base + 0xb070)
+#define _MIPIC_HS_GEN_CTRL		(dev_priv->mipi_mmio_base + 0xb870)
+#define MIPI_HS_GEN_CTRL(port)		_MMIO_MIPI(port, _MIPIA_HS_GEN_CTRL, _MIPIC_HS_GEN_CTRL)
+#define  LONG_PACKET_WORD_COUNT_SHIFT			8
+#define  LONG_PACKET_WORD_COUNT_MASK			(0xffff << 8)
+#define  SHORT_PACKET_PARAM_SHIFT			8
+#define  SHORT_PACKET_PARAM_MASK			(0xffff << 8)
+#define  VIRTUAL_CHANNEL_SHIFT				6
+#define  VIRTUAL_CHANNEL_MASK				(3 << 6)
+#define  DATA_TYPE_SHIFT				0
+#define  DATA_TYPE_MASK					(0x3f << 0)
+/* data type values, see include/video/mipi_display.h */
+
+#define _MIPIA_GEN_FIFO_STAT		(dev_priv->mipi_mmio_base + 0xb074)
+#define _MIPIC_GEN_FIFO_STAT		(dev_priv->mipi_mmio_base + 0xb874)
+#define MIPI_GEN_FIFO_STAT(port)	_MMIO_MIPI(port, _MIPIA_GEN_FIFO_STAT, _MIPIC_GEN_FIFO_STAT)
+#define  DPI_FIFO_EMPTY					(1 << 28)
+#define  DBI_FIFO_EMPTY					(1 << 27)
+#define  LP_CTRL_FIFO_EMPTY				(1 << 26)
+#define  LP_CTRL_FIFO_HALF_EMPTY			(1 << 25)
+#define  LP_CTRL_FIFO_FULL				(1 << 24)
+#define  HS_CTRL_FIFO_EMPTY				(1 << 18)
+#define  HS_CTRL_FIFO_HALF_EMPTY			(1 << 17)
+#define  HS_CTRL_FIFO_FULL				(1 << 16)
+#define  LP_DATA_FIFO_EMPTY				(1 << 10)
+#define  LP_DATA_FIFO_HALF_EMPTY			(1 << 9)
+#define  LP_DATA_FIFO_FULL				(1 << 8)
+#define  HS_DATA_FIFO_EMPTY				(1 << 2)
+#define  HS_DATA_FIFO_HALF_EMPTY			(1 << 1)
+#define  HS_DATA_FIFO_FULL				(1 << 0)
+
+#define _MIPIA_HS_LS_DBI_ENABLE		(dev_priv->mipi_mmio_base + 0xb078)
+#define _MIPIC_HS_LS_DBI_ENABLE		(dev_priv->mipi_mmio_base + 0xb878)
+#define MIPI_HS_LP_DBI_ENABLE(port)	_MMIO_MIPI(port, _MIPIA_HS_LS_DBI_ENABLE, _MIPIC_HS_LS_DBI_ENABLE)
+#define  DBI_HS_LP_MODE_MASK				(1 << 0)
+#define  DBI_LP_MODE					(1 << 0)
+#define  DBI_HS_MODE					(0 << 0)
+
+#define _MIPIA_DPHY_PARAM		(dev_priv->mipi_mmio_base + 0xb080)
+#define _MIPIC_DPHY_PARAM		(dev_priv->mipi_mmio_base + 0xb880)
+#define MIPI_DPHY_PARAM(port)		_MMIO_MIPI(port, _MIPIA_DPHY_PARAM, _MIPIC_DPHY_PARAM)
+#define  EXIT_ZERO_COUNT_SHIFT				24
+#define  EXIT_ZERO_COUNT_MASK				(0x3f << 24)
+#define  TRAIL_COUNT_SHIFT				16
+#define  TRAIL_COUNT_MASK				(0x1f << 16)
+#define  CLK_ZERO_COUNT_SHIFT				8
+#define  CLK_ZERO_COUNT_MASK				(0xff << 8)
+#define  PREPARE_COUNT_SHIFT				0
+#define  PREPARE_COUNT_MASK				(0x3f << 0)
+
+/* bits 31:0 */
+#define _MIPIA_DBI_BW_CTRL		(dev_priv->mipi_mmio_base + 0xb084)
+#define _MIPIC_DBI_BW_CTRL		(dev_priv->mipi_mmio_base + 0xb884)
+#define MIPI_DBI_BW_CTRL(port)		_MMIO_MIPI(port, _MIPIA_DBI_BW_CTRL, _MIPIC_DBI_BW_CTRL)
+
+#define _MIPIA_CLK_LANE_SWITCH_TIME_CNT		(dev_priv->mipi_mmio_base + 0xb088)
+#define _MIPIC_CLK_LANE_SWITCH_TIME_CNT		(dev_priv->mipi_mmio_base + 0xb888)
+#define MIPI_CLK_LANE_SWITCH_TIME_CNT(port)	_MMIO_MIPI(port, _MIPIA_CLK_LANE_SWITCH_TIME_CNT, _MIPIC_CLK_LANE_SWITCH_TIME_CNT)
+#define  LP_HS_SSW_CNT_SHIFT				16
+#define  LP_HS_SSW_CNT_MASK				(0xffff << 16)
+#define  HS_LP_PWR_SW_CNT_SHIFT				0
+#define  HS_LP_PWR_SW_CNT_MASK				(0xffff << 0)
+
+#define _MIPIA_STOP_STATE_STALL		(dev_priv->mipi_mmio_base + 0xb08c)
+#define _MIPIC_STOP_STATE_STALL		(dev_priv->mipi_mmio_base + 0xb88c)
+#define MIPI_STOP_STATE_STALL(port)	_MMIO_MIPI(port, _MIPIA_STOP_STATE_STALL, _MIPIC_STOP_STATE_STALL)
+#define  STOP_STATE_STALL_COUNTER_SHIFT			0
+#define  STOP_STATE_STALL_COUNTER_MASK			(0xff << 0)
+
+#define _MIPIA_INTR_STAT_REG_1		(dev_priv->mipi_mmio_base + 0xb090)
+#define _MIPIC_INTR_STAT_REG_1		(dev_priv->mipi_mmio_base + 0xb890)
+#define MIPI_INTR_STAT_REG_1(port)	_MMIO_MIPI(port, _MIPIA_INTR_STAT_REG_1, _MIPIC_INTR_STAT_REG_1)
+#define _MIPIA_INTR_EN_REG_1		(dev_priv->mipi_mmio_base + 0xb094)
+#define _MIPIC_INTR_EN_REG_1		(dev_priv->mipi_mmio_base + 0xb894)
+#define MIPI_INTR_EN_REG_1(port)	_MMIO_MIPI(port, _MIPIA_INTR_EN_REG_1, _MIPIC_INTR_EN_REG_1)
+#define  RX_CONTENTION_DETECTED				(1 << 0)
+
+/* XXX: only pipe A ?!? */
+#define MIPIA_DBI_TYPEC_CTRL		(dev_priv->mipi_mmio_base + 0xb100)
+#define  DBI_TYPEC_ENABLE				(1 << 31)
+#define  DBI_TYPEC_WIP					(1 << 30)
+#define  DBI_TYPEC_OPTION_SHIFT				28
+#define  DBI_TYPEC_OPTION_MASK				(3 << 28)
+#define  DBI_TYPEC_FREQ_SHIFT				24
+#define  DBI_TYPEC_FREQ_MASK				(0xf << 24)
+#define  DBI_TYPEC_OVERRIDE				(1 << 8)
+#define  DBI_TYPEC_OVERRIDE_COUNTER_SHIFT		0
+#define  DBI_TYPEC_OVERRIDE_COUNTER_MASK		(0xff << 0)
+
+
+/* MIPI adapter registers */
+
+#define _MIPIA_CTRL			(dev_priv->mipi_mmio_base + 0xb104)
+#define _MIPIC_CTRL			(dev_priv->mipi_mmio_base + 0xb904)
+#define MIPI_CTRL(port)			_MMIO_MIPI(port, _MIPIA_CTRL, _MIPIC_CTRL)
+#define  ESCAPE_CLOCK_DIVIDER_SHIFT			5 /* A only */
+#define  ESCAPE_CLOCK_DIVIDER_MASK			(3 << 5)
+#define  ESCAPE_CLOCK_DIVIDER_1				(0 << 5)
+#define  ESCAPE_CLOCK_DIVIDER_2				(1 << 5)
+#define  ESCAPE_CLOCK_DIVIDER_4				(2 << 5)
+#define  READ_REQUEST_PRIORITY_SHIFT			3
+#define  READ_REQUEST_PRIORITY_MASK			(3 << 3)
+#define  READ_REQUEST_PRIORITY_LOW			(0 << 3)
+#define  READ_REQUEST_PRIORITY_HIGH			(3 << 3)
+#define  RGB_FLIP_TO_BGR				(1 << 2)
+
+#define  BXT_PIPE_SELECT_SHIFT				7
+#define  BXT_PIPE_SELECT_MASK				(7 << 7)
+#define  BXT_PIPE_SELECT(pipe)				((pipe) << 7)
+
+#define _MIPIA_DATA_ADDRESS		(dev_priv->mipi_mmio_base + 0xb108)
+#define _MIPIC_DATA_ADDRESS		(dev_priv->mipi_mmio_base + 0xb908)
+#define MIPI_DATA_ADDRESS(port)		_MMIO_MIPI(port, _MIPIA_DATA_ADDRESS, _MIPIC_DATA_ADDRESS)
+#define  DATA_MEM_ADDRESS_SHIFT				5
+#define  DATA_MEM_ADDRESS_MASK				(0x7ffffff << 5)
+#define  DATA_VALID					(1 << 0)
+
+#define _MIPIA_DATA_LENGTH		(dev_priv->mipi_mmio_base + 0xb10c)
+#define _MIPIC_DATA_LENGTH		(dev_priv->mipi_mmio_base + 0xb90c)
+#define MIPI_DATA_LENGTH(port)		_MMIO_MIPI(port, _MIPIA_DATA_LENGTH, _MIPIC_DATA_LENGTH)
+#define  DATA_LENGTH_SHIFT				0
+#define  DATA_LENGTH_MASK				(0xfffff << 0)
+
+#define _MIPIA_COMMAND_ADDRESS		(dev_priv->mipi_mmio_base + 0xb110)
+#define _MIPIC_COMMAND_ADDRESS		(dev_priv->mipi_mmio_base + 0xb910)
+#define MIPI_COMMAND_ADDRESS(port)	_MMIO_MIPI(port, _MIPIA_COMMAND_ADDRESS, _MIPIC_COMMAND_ADDRESS)
+#define  COMMAND_MEM_ADDRESS_SHIFT			5
+#define  COMMAND_MEM_ADDRESS_MASK			(0x7ffffff << 5)
+#define  AUTO_PWG_ENABLE				(1 << 2)
+#define  MEMORY_WRITE_DATA_FROM_PIPE_RENDERING		(1 << 1)
+#define  COMMAND_VALID					(1 << 0)
+
+#define _MIPIA_COMMAND_LENGTH		(dev_priv->mipi_mmio_base + 0xb114)
+#define _MIPIC_COMMAND_LENGTH		(dev_priv->mipi_mmio_base + 0xb914)
+#define MIPI_COMMAND_LENGTH(port)	_MMIO_MIPI(port, _MIPIA_COMMAND_LENGTH, _MIPIC_COMMAND_LENGTH)
+#define  COMMAND_LENGTH_SHIFT(n)			(8 * (n)) /* n: 0...3 */
+#define  COMMAND_LENGTH_MASK(n)				(0xff << (8 * (n)))
+
+#define _MIPIA_READ_DATA_RETURN0	(dev_priv->mipi_mmio_base + 0xb118)
+#define _MIPIC_READ_DATA_RETURN0	(dev_priv->mipi_mmio_base + 0xb918)
+#define MIPI_READ_DATA_RETURN(port, n) _MMIO(_MIPI(port, _MIPIA_READ_DATA_RETURN0, _MIPIC_READ_DATA_RETURN0) + 4 * (n)) /* n: 0...7 */
+
+#define _MIPIA_READ_DATA_VALID		(dev_priv->mipi_mmio_base + 0xb138)
+#define _MIPIC_READ_DATA_VALID		(dev_priv->mipi_mmio_base + 0xb938)
+#define MIPI_READ_DATA_VALID(port)	_MMIO_MIPI(port, _MIPIA_READ_DATA_VALID, _MIPIC_READ_DATA_VALID)
+#define  READ_DATA_VALID(n)				(1 << (n))
+
+/* For UMS only (deprecated): */
+#define _PALETTE_A (dev_priv->info.display_mmio_offset + 0xa000)
+#define _PALETTE_B (dev_priv->info.display_mmio_offset + 0xa800)
+
+/* MOCS (Memory Object Control State) registers */
+#define GEN9_LNCFCMOCS(i)	_MMIO(0xb020 + (i) * 4)	/* L3 Cache Control */
+
+#define GEN9_GFX_MOCS(i)	_MMIO(0xc800 + (i) * 4)	/* Graphics MOCS registers */
+#define GEN9_MFX0_MOCS(i)	_MMIO(0xc900 + (i) * 4)	/* Media 0 MOCS registers */
+#define GEN9_MFX1_MOCS(i)	_MMIO(0xca00 + (i) * 4)	/* Media 1 MOCS registers */
+#define GEN9_VEBOX_MOCS(i)	_MMIO(0xcb00 + (i) * 4)	/* Video MOCS registers */
+#define GEN9_BLT_MOCS(i)	_MMIO(0xcc00 + (i) * 4)	/* Blitter MOCS registers */
+
+/* gamt regs */
+#define GEN8_L3_LRA_1_GPGPU _MMIO(0x4dd4)
+#define   GEN8_L3_LRA_1_GPGPU_DEFAULT_VALUE_BDW  0x67F1427F /* max/min for LRA1/2 */
+#define   GEN8_L3_LRA_1_GPGPU_DEFAULT_VALUE_CHV  0x5FF101FF /* max/min for LRA1/2 */
+#define   GEN9_L3_LRA_1_GPGPU_DEFAULT_VALUE_SKL  0x67F1427F /*    "        " */
+#define   GEN9_L3_LRA_1_GPGPU_DEFAULT_VALUE_BXT  0x5FF101FF /*    "        " */
+
+#endif /* _I915_REG_H_ */
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/i915/i915_suspend.c
@@ -0,0 +1,196 @@
+/*
+ *
+ * Copyright 2008 (c) Intel Corporation
+ *   Jesse Barnes <jbarnes@virtuousgeek.org>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include <drm/drmP.h>
+#include <drm/i915_drm.h>
+#include "intel_drv.h"
+#include "i915_reg.h"
+
+static void i915_save_display(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	/* Display arbitration control */
+	if (INTEL_INFO(dev)->gen <= 4)
+		dev_priv->regfile.saveDSPARB = I915_READ(DSPARB);
+
+	/* LVDS state */
+	if (HAS_PCH_IBX(dev) || HAS_PCH_CPT(dev))
+		dev_priv->regfile.saveLVDS = I915_READ(PCH_LVDS);
+	else if (INTEL_INFO(dev)->gen <= 4 && IS_MOBILE(dev) && !IS_I830(dev))
+		dev_priv->regfile.saveLVDS = I915_READ(LVDS);
+
+	/* Panel power sequencer */
+	if (HAS_PCH_SPLIT(dev)) {
+		dev_priv->regfile.savePP_CONTROL = I915_READ(PCH_PP_CONTROL);
+		dev_priv->regfile.savePP_ON_DELAYS = I915_READ(PCH_PP_ON_DELAYS);
+		dev_priv->regfile.savePP_OFF_DELAYS = I915_READ(PCH_PP_OFF_DELAYS);
+		dev_priv->regfile.savePP_DIVISOR = I915_READ(PCH_PP_DIVISOR);
+	} else if (INTEL_INFO(dev)->gen <= 4) {
+		dev_priv->regfile.savePP_CONTROL = I915_READ(PP_CONTROL);
+		dev_priv->regfile.savePP_ON_DELAYS = I915_READ(PP_ON_DELAYS);
+		dev_priv->regfile.savePP_OFF_DELAYS = I915_READ(PP_OFF_DELAYS);
+		dev_priv->regfile.savePP_DIVISOR = I915_READ(PP_DIVISOR);
+	}
+
+	/* save FBC interval */
+	if (HAS_FBC(dev) && INTEL_INFO(dev)->gen <= 4 && !IS_G4X(dev))
+		dev_priv->regfile.saveFBC_CONTROL = I915_READ(FBC_CONTROL);
+}
+
+static void i915_restore_display(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	u32 mask = 0xffffffff;
+
+	/* Display arbitration */
+	if (INTEL_INFO(dev)->gen <= 4)
+		I915_WRITE(DSPARB, dev_priv->regfile.saveDSPARB);
+
+	mask = ~LVDS_PORT_EN;
+
+	/* LVDS state */
+	if (HAS_PCH_IBX(dev) || HAS_PCH_CPT(dev))
+		I915_WRITE(PCH_LVDS, dev_priv->regfile.saveLVDS & mask);
+	else if (INTEL_INFO(dev)->gen <= 4 && IS_MOBILE(dev) && !IS_I830(dev))
+		I915_WRITE(LVDS, dev_priv->regfile.saveLVDS & mask);
+
+	/* Panel power sequencer */
+	if (HAS_PCH_SPLIT(dev)) {
+		I915_WRITE(PCH_PP_ON_DELAYS, dev_priv->regfile.savePP_ON_DELAYS);
+		I915_WRITE(PCH_PP_OFF_DELAYS, dev_priv->regfile.savePP_OFF_DELAYS);
+		I915_WRITE(PCH_PP_DIVISOR, dev_priv->regfile.savePP_DIVISOR);
+		I915_WRITE(PCH_PP_CONTROL, dev_priv->regfile.savePP_CONTROL);
+	} else if (INTEL_INFO(dev)->gen <= 4) {
+		I915_WRITE(PP_ON_DELAYS, dev_priv->regfile.savePP_ON_DELAYS);
+		I915_WRITE(PP_OFF_DELAYS, dev_priv->regfile.savePP_OFF_DELAYS);
+		I915_WRITE(PP_DIVISOR, dev_priv->regfile.savePP_DIVISOR);
+		I915_WRITE(PP_CONTROL, dev_priv->regfile.savePP_CONTROL);
+	}
+
+	/* only restore FBC info on the platform that supports FBC*/
+	intel_fbc_global_disable(dev_priv);
+
+	/* restore FBC interval */
+	if (HAS_FBC(dev) && INTEL_INFO(dev)->gen <= 4 && !IS_G4X(dev))
+		I915_WRITE(FBC_CONTROL, dev_priv->regfile.saveFBC_CONTROL);
+
+	i915_redisable_vga(dev);
+}
+
+int i915_save_state(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	int i;
+
+	mutex_lock(&dev->struct_mutex);
+
+	i915_save_display(dev);
+
+	if (IS_GEN4(dev))
+		pci_read_config_word(dev->pdev, GCDGMBUS,
+				     &dev_priv->regfile.saveGCDGMBUS);
+
+	/* Cache mode state */
+	if (INTEL_INFO(dev)->gen < 7)
+		dev_priv->regfile.saveCACHE_MODE_0 = I915_READ(CACHE_MODE_0);
+
+	/* Memory Arbitration state */
+	dev_priv->regfile.saveMI_ARB_STATE = I915_READ(MI_ARB_STATE);
+
+	/* Scratch space */
+	if (IS_GEN2(dev_priv) && IS_MOBILE(dev_priv)) {
+		for (i = 0; i < 7; i++) {
+			dev_priv->regfile.saveSWF0[i] = I915_READ(SWF0(i));
+			dev_priv->regfile.saveSWF1[i] = I915_READ(SWF1(i));
+		}
+		for (i = 0; i < 3; i++)
+			dev_priv->regfile.saveSWF3[i] = I915_READ(SWF3(i));
+	} else if (IS_GEN2(dev_priv)) {
+		for (i = 0; i < 7; i++)
+			dev_priv->regfile.saveSWF1[i] = I915_READ(SWF1(i));
+	} else if (HAS_GMCH_DISPLAY(dev_priv)) {
+		for (i = 0; i < 16; i++) {
+			dev_priv->regfile.saveSWF0[i] = I915_READ(SWF0(i));
+			dev_priv->regfile.saveSWF1[i] = I915_READ(SWF1(i));
+		}
+		for (i = 0; i < 3; i++)
+			dev_priv->regfile.saveSWF3[i] = I915_READ(SWF3(i));
+	}
+
+	mutex_unlock(&dev->struct_mutex);
+
+	return 0;
+}
+
+int i915_restore_state(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	int i;
+
+	mutex_lock(&dev->struct_mutex);
+
+	i915_gem_restore_fences(dev);
+
+	if (IS_GEN4(dev))
+		pci_write_config_word(dev->pdev, GCDGMBUS,
+				      dev_priv->regfile.saveGCDGMBUS);
+	i915_restore_display(dev);
+
+	/* Cache mode state */
+	if (INTEL_INFO(dev)->gen < 7)
+		I915_WRITE(CACHE_MODE_0, dev_priv->regfile.saveCACHE_MODE_0 |
+			   0xffff0000);
+
+	/* Memory arbitration state */
+	I915_WRITE(MI_ARB_STATE, dev_priv->regfile.saveMI_ARB_STATE | 0xffff0000);
+
+	/* Scratch space */
+	if (IS_GEN2(dev_priv) && IS_MOBILE(dev_priv)) {
+		for (i = 0; i < 7; i++) {
+			I915_WRITE(SWF0(i), dev_priv->regfile.saveSWF0[i]);
+			I915_WRITE(SWF1(i), dev_priv->regfile.saveSWF1[i]);
+		}
+		for (i = 0; i < 3; i++)
+			I915_WRITE(SWF3(i), dev_priv->regfile.saveSWF3[i]);
+	} else if (IS_GEN2(dev_priv)) {
+		for (i = 0; i < 7; i++)
+			I915_WRITE(SWF1(i), dev_priv->regfile.saveSWF1[i]);
+	} else if (HAS_GMCH_DISPLAY(dev_priv)) {
+		for (i = 0; i < 16; i++) {
+			I915_WRITE(SWF0(i), dev_priv->regfile.saveSWF0[i]);
+			I915_WRITE(SWF1(i), dev_priv->regfile.saveSWF1[i]);
+		}
+		for (i = 0; i < 3; i++)
+			I915_WRITE(SWF3(i), dev_priv->regfile.saveSWF3[i]);
+	}
+
+	mutex_unlock(&dev->struct_mutex);
+
+	intel_i2c_reset(dev);
+
+	return 0;
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/i915/i915_sysfs.c
@@ -0,0 +1,658 @@
+/*
+ * Copyright © 2012 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Ben Widawsky <ben@bwidawsk.net>
+ *
+ */
+
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/stat.h>
+#include <linux/sysfs.h>
+#include "intel_drv.h"
+#include "i915_drv.h"
+
+#define dev_to_drm_minor(d) dev_get_drvdata((d))
+
+#ifdef CONFIG_PM
+static u32 calc_residency(struct drm_device *dev,
+			  i915_reg_t reg)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	u64 raw_time; /* 32b value may overflow during fixed point math */
+	u64 units = 128ULL, div = 100000ULL;
+	u32 ret;
+
+	if (!intel_enable_rc6(dev))
+		return 0;
+
+	intel_runtime_pm_get(dev_priv);
+
+	/* On VLV and CHV, residency time is in CZ units rather than 1.28us */
+	if (IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev)) {
+		units = 1;
+		div = dev_priv->czclk_freq;
+
+		if (I915_READ(VLV_COUNTER_CONTROL) & VLV_COUNT_RANGE_HIGH)
+			units <<= 8;
+	} else if (IS_BROXTON(dev)) {
+		units = 1;
+		div = 1200;		/* 833.33ns */
+	}
+
+	raw_time = I915_READ(reg) * units;
+	ret = DIV_ROUND_UP_ULL(raw_time, div);
+
+	intel_runtime_pm_put(dev_priv);
+	return ret;
+}
+
+static ssize_t
+show_rc6_mask(struct device *kdev, struct device_attribute *attr, char *buf)
+{
+	struct drm_minor *dminor = dev_to_drm_minor(kdev);
+	return snprintf(buf, PAGE_SIZE, "%x\n", intel_enable_rc6(dminor->dev));
+}
+
+static ssize_t
+show_rc6_ms(struct device *kdev, struct device_attribute *attr, char *buf)
+{
+	struct drm_minor *dminor = dev_get_drvdata(kdev);
+	u32 rc6_residency = calc_residency(dminor->dev, GEN6_GT_GFX_RC6);
+	return snprintf(buf, PAGE_SIZE, "%u\n", rc6_residency);
+}
+
+static ssize_t
+show_rc6p_ms(struct device *kdev, struct device_attribute *attr, char *buf)
+{
+	struct drm_minor *dminor = dev_to_drm_minor(kdev);
+	u32 rc6p_residency = calc_residency(dminor->dev, GEN6_GT_GFX_RC6p);
+	return snprintf(buf, PAGE_SIZE, "%u\n", rc6p_residency);
+}
+
+static ssize_t
+show_rc6pp_ms(struct device *kdev, struct device_attribute *attr, char *buf)
+{
+	struct drm_minor *dminor = dev_to_drm_minor(kdev);
+	u32 rc6pp_residency = calc_residency(dminor->dev, GEN6_GT_GFX_RC6pp);
+	return snprintf(buf, PAGE_SIZE, "%u\n", rc6pp_residency);
+}
+
+static ssize_t
+show_media_rc6_ms(struct device *kdev, struct device_attribute *attr, char *buf)
+{
+	struct drm_minor *dminor = dev_get_drvdata(kdev);
+	u32 rc6_residency = calc_residency(dminor->dev, VLV_GT_MEDIA_RC6);
+	return snprintf(buf, PAGE_SIZE, "%u\n", rc6_residency);
+}
+
+static DEVICE_ATTR(rc6_enable, S_IRUGO, show_rc6_mask, NULL);
+static DEVICE_ATTR(rc6_residency_ms, S_IRUGO, show_rc6_ms, NULL);
+static DEVICE_ATTR(rc6p_residency_ms, S_IRUGO, show_rc6p_ms, NULL);
+static DEVICE_ATTR(rc6pp_residency_ms, S_IRUGO, show_rc6pp_ms, NULL);
+static DEVICE_ATTR(media_rc6_residency_ms, S_IRUGO, show_media_rc6_ms, NULL);
+
+static struct attribute *rc6_attrs[] = {
+	&dev_attr_rc6_enable.attr,
+	&dev_attr_rc6_residency_ms.attr,
+	NULL
+};
+
+static struct attribute_group rc6_attr_group = {
+	.name = power_group_name,
+	.attrs =  rc6_attrs
+};
+
+static struct attribute *rc6p_attrs[] = {
+	&dev_attr_rc6p_residency_ms.attr,
+	&dev_attr_rc6pp_residency_ms.attr,
+	NULL
+};
+
+static struct attribute_group rc6p_attr_group = {
+	.name = power_group_name,
+	.attrs =  rc6p_attrs
+};
+
+static struct attribute *media_rc6_attrs[] = {
+	&dev_attr_media_rc6_residency_ms.attr,
+	NULL
+};
+
+static struct attribute_group media_rc6_attr_group = {
+	.name = power_group_name,
+	.attrs =  media_rc6_attrs
+};
+#endif
+
+static int l3_access_valid(struct drm_device *dev, loff_t offset)
+{
+	if (!HAS_L3_DPF(dev))
+		return -EPERM;
+
+	if (offset % 4 != 0)
+		return -EINVAL;
+
+	if (offset >= GEN7_L3LOG_SIZE)
+		return -ENXIO;
+
+	return 0;
+}
+
+static ssize_t
+i915_l3_read(struct file *filp, struct kobject *kobj,
+	     struct bin_attribute *attr, char *buf,
+	     loff_t offset, size_t count)
+{
+	struct device *dev = kobj_to_dev(kobj);
+	struct drm_minor *dminor = dev_to_drm_minor(dev);
+	struct drm_device *drm_dev = dminor->dev;
+	struct drm_i915_private *dev_priv = drm_dev->dev_private;
+	int slice = (int)(uintptr_t)attr->private;
+	int ret;
+
+	count = round_down(count, 4);
+
+	ret = l3_access_valid(drm_dev, offset);
+	if (ret)
+		return ret;
+
+	count = min_t(size_t, GEN7_L3LOG_SIZE - offset, count);
+
+	ret = i915_mutex_lock_interruptible(drm_dev);
+	if (ret)
+		return ret;
+
+	if (dev_priv->l3_parity.remap_info[slice])
+		memcpy(buf,
+		       dev_priv->l3_parity.remap_info[slice] + (offset/4),
+		       count);
+	else
+		memset(buf, 0, count);
+
+	mutex_unlock(&drm_dev->struct_mutex);
+
+	return count;
+}
+
+static ssize_t
+i915_l3_write(struct file *filp, struct kobject *kobj,
+	      struct bin_attribute *attr, char *buf,
+	      loff_t offset, size_t count)
+{
+	struct device *dev = kobj_to_dev(kobj);
+	struct drm_minor *dminor = dev_to_drm_minor(dev);
+	struct drm_device *drm_dev = dminor->dev;
+	struct drm_i915_private *dev_priv = drm_dev->dev_private;
+	struct intel_context *ctx;
+	u32 *temp = NULL; /* Just here to make handling failures easy */
+	int slice = (int)(uintptr_t)attr->private;
+	int ret;
+
+	if (!HAS_HW_CONTEXTS(drm_dev))
+		return -ENXIO;
+
+	ret = l3_access_valid(drm_dev, offset);
+	if (ret)
+		return ret;
+
+	ret = i915_mutex_lock_interruptible(drm_dev);
+	if (ret)
+		return ret;
+
+	if (!dev_priv->l3_parity.remap_info[slice]) {
+		temp = kzalloc(GEN7_L3LOG_SIZE, GFP_KERNEL);
+		if (!temp) {
+			mutex_unlock(&drm_dev->struct_mutex);
+			return -ENOMEM;
+		}
+	}
+
+	ret = i915_gpu_idle(drm_dev);
+	if (ret) {
+		kfree(temp);
+		mutex_unlock(&drm_dev->struct_mutex);
+		return ret;
+	}
+
+	/* TODO: Ideally we really want a GPU reset here to make sure errors
+	 * aren't propagated. Since I cannot find a stable way to reset the GPU
+	 * at this point it is left as a TODO.
+	*/
+	if (temp)
+		dev_priv->l3_parity.remap_info[slice] = temp;
+
+	memcpy(dev_priv->l3_parity.remap_info[slice] + (offset/4), buf, count);
+
+	/* NB: We defer the remapping until we switch to the context */
+	list_for_each_entry(ctx, &dev_priv->context_list, link)
+		ctx->remap_slice |= (1<<slice);
+
+	mutex_unlock(&drm_dev->struct_mutex);
+
+	return count;
+}
+
+static struct bin_attribute dpf_attrs = {
+	.attr = {.name = "l3_parity", .mode = (S_IRUSR | S_IWUSR)},
+	.size = GEN7_L3LOG_SIZE,
+	.read = i915_l3_read,
+	.write = i915_l3_write,
+	.mmap = NULL,
+	.private = (void *)0
+};
+
+static struct bin_attribute dpf_attrs_1 = {
+	.attr = {.name = "l3_parity_slice_1", .mode = (S_IRUSR | S_IWUSR)},
+	.size = GEN7_L3LOG_SIZE,
+	.read = i915_l3_read,
+	.write = i915_l3_write,
+	.mmap = NULL,
+	.private = (void *)1
+};
+
+static ssize_t gt_act_freq_mhz_show(struct device *kdev,
+				    struct device_attribute *attr, char *buf)
+{
+	struct drm_minor *minor = dev_to_drm_minor(kdev);
+	struct drm_device *dev = minor->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	int ret;
+
+	flush_delayed_work(&dev_priv->rps.delayed_resume_work);
+
+	intel_runtime_pm_get(dev_priv);
+
+	mutex_lock(&dev_priv->rps.hw_lock);
+	if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
+		u32 freq;
+		freq = vlv_punit_read(dev_priv, PUNIT_REG_GPU_FREQ_STS);
+		ret = intel_gpu_freq(dev_priv, (freq >> 8) & 0xff);
+	} else {
+		u32 rpstat = I915_READ(GEN6_RPSTAT1);
+		if (IS_GEN9(dev_priv))
+			ret = (rpstat & GEN9_CAGF_MASK) >> GEN9_CAGF_SHIFT;
+		else if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv))
+			ret = (rpstat & HSW_CAGF_MASK) >> HSW_CAGF_SHIFT;
+		else
+			ret = (rpstat & GEN6_CAGF_MASK) >> GEN6_CAGF_SHIFT;
+		ret = intel_gpu_freq(dev_priv, ret);
+	}
+	mutex_unlock(&dev_priv->rps.hw_lock);
+
+	intel_runtime_pm_put(dev_priv);
+
+	return snprintf(buf, PAGE_SIZE, "%d\n", ret);
+}
+
+static ssize_t gt_cur_freq_mhz_show(struct device *kdev,
+				    struct device_attribute *attr, char *buf)
+{
+	struct drm_minor *minor = dev_to_drm_minor(kdev);
+	struct drm_device *dev = minor->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	int ret;
+
+	flush_delayed_work(&dev_priv->rps.delayed_resume_work);
+
+	intel_runtime_pm_get(dev_priv);
+
+	mutex_lock(&dev_priv->rps.hw_lock);
+	ret = intel_gpu_freq(dev_priv, dev_priv->rps.cur_freq);
+	mutex_unlock(&dev_priv->rps.hw_lock);
+
+	intel_runtime_pm_put(dev_priv);
+
+	return snprintf(buf, PAGE_SIZE, "%d\n", ret);
+}
+
+static ssize_t vlv_rpe_freq_mhz_show(struct device *kdev,
+				     struct device_attribute *attr, char *buf)
+{
+	struct drm_minor *minor = dev_to_drm_minor(kdev);
+	struct drm_device *dev = minor->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	return snprintf(buf, PAGE_SIZE,
+			"%d\n",
+			intel_gpu_freq(dev_priv, dev_priv->rps.efficient_freq));
+}
+
+static ssize_t gt_max_freq_mhz_show(struct device *kdev, struct device_attribute *attr, char *buf)
+{
+	struct drm_minor *minor = dev_to_drm_minor(kdev);
+	struct drm_device *dev = minor->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	int ret;
+
+	flush_delayed_work(&dev_priv->rps.delayed_resume_work);
+
+	mutex_lock(&dev_priv->rps.hw_lock);
+	ret = intel_gpu_freq(dev_priv, dev_priv->rps.max_freq_softlimit);
+	mutex_unlock(&dev_priv->rps.hw_lock);
+
+	return snprintf(buf, PAGE_SIZE, "%d\n", ret);
+}
+
+static ssize_t gt_max_freq_mhz_store(struct device *kdev,
+				     struct device_attribute *attr,
+				     const char *buf, size_t count)
+{
+	struct drm_minor *minor = dev_to_drm_minor(kdev);
+	struct drm_device *dev = minor->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	u32 val;
+	ssize_t ret;
+
+	ret = kstrtou32(buf, 0, &val);
+	if (ret)
+		return ret;
+
+	flush_delayed_work(&dev_priv->rps.delayed_resume_work);
+
+	intel_runtime_pm_get(dev_priv);
+
+	mutex_lock(&dev_priv->rps.hw_lock);
+
+	val = intel_freq_opcode(dev_priv, val);
+
+	if (val < dev_priv->rps.min_freq ||
+	    val > dev_priv->rps.max_freq ||
+	    val < dev_priv->rps.min_freq_softlimit) {
+		mutex_unlock(&dev_priv->rps.hw_lock);
+		intel_runtime_pm_put(dev_priv);
+		return -EINVAL;
+	}
+
+	if (val > dev_priv->rps.rp0_freq)
+		DRM_DEBUG("User requested overclocking to %d\n",
+			  intel_gpu_freq(dev_priv, val));
+
+	dev_priv->rps.max_freq_softlimit = val;
+
+	val = clamp_t(int, dev_priv->rps.cur_freq,
+		      dev_priv->rps.min_freq_softlimit,
+		      dev_priv->rps.max_freq_softlimit);
+
+	/* We still need *_set_rps to process the new max_delay and
+	 * update the interrupt limits and PMINTRMSK even though
+	 * frequency request may be unchanged. */
+	intel_set_rps(dev, val);
+
+	mutex_unlock(&dev_priv->rps.hw_lock);
+
+	intel_runtime_pm_put(dev_priv);
+
+	return count;
+}
+
+static ssize_t gt_min_freq_mhz_show(struct device *kdev, struct device_attribute *attr, char *buf)
+{
+	struct drm_minor *minor = dev_to_drm_minor(kdev);
+	struct drm_device *dev = minor->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	int ret;
+
+	flush_delayed_work(&dev_priv->rps.delayed_resume_work);
+
+	mutex_lock(&dev_priv->rps.hw_lock);
+	ret = intel_gpu_freq(dev_priv, dev_priv->rps.min_freq_softlimit);
+	mutex_unlock(&dev_priv->rps.hw_lock);
+
+	return snprintf(buf, PAGE_SIZE, "%d\n", ret);
+}
+
+static ssize_t gt_min_freq_mhz_store(struct device *kdev,
+				     struct device_attribute *attr,
+				     const char *buf, size_t count)
+{
+	struct drm_minor *minor = dev_to_drm_minor(kdev);
+	struct drm_device *dev = minor->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	u32 val;
+	ssize_t ret;
+
+	ret = kstrtou32(buf, 0, &val);
+	if (ret)
+		return ret;
+
+	flush_delayed_work(&dev_priv->rps.delayed_resume_work);
+
+	intel_runtime_pm_get(dev_priv);
+
+	mutex_lock(&dev_priv->rps.hw_lock);
+
+	val = intel_freq_opcode(dev_priv, val);
+
+	if (val < dev_priv->rps.min_freq ||
+	    val > dev_priv->rps.max_freq ||
+	    val > dev_priv->rps.max_freq_softlimit) {
+		mutex_unlock(&dev_priv->rps.hw_lock);
+		intel_runtime_pm_put(dev_priv);
+		return -EINVAL;
+	}
+
+	dev_priv->rps.min_freq_softlimit = val;
+
+	val = clamp_t(int, dev_priv->rps.cur_freq,
+		      dev_priv->rps.min_freq_softlimit,
+		      dev_priv->rps.max_freq_softlimit);
+
+	/* We still need *_set_rps to process the new min_delay and
+	 * update the interrupt limits and PMINTRMSK even though
+	 * frequency request may be unchanged. */
+	intel_set_rps(dev, val);
+
+	mutex_unlock(&dev_priv->rps.hw_lock);
+
+	intel_runtime_pm_put(dev_priv);
+
+	return count;
+
+}
+
+static DEVICE_ATTR(gt_act_freq_mhz, S_IRUGO, gt_act_freq_mhz_show, NULL);
+static DEVICE_ATTR(gt_cur_freq_mhz, S_IRUGO, gt_cur_freq_mhz_show, NULL);
+static DEVICE_ATTR(gt_max_freq_mhz, S_IRUGO | S_IWUSR, gt_max_freq_mhz_show, gt_max_freq_mhz_store);
+static DEVICE_ATTR(gt_min_freq_mhz, S_IRUGO | S_IWUSR, gt_min_freq_mhz_show, gt_min_freq_mhz_store);
+
+static DEVICE_ATTR(vlv_rpe_freq_mhz, S_IRUGO, vlv_rpe_freq_mhz_show, NULL);
+
+static ssize_t gt_rp_mhz_show(struct device *kdev, struct device_attribute *attr, char *buf);
+static DEVICE_ATTR(gt_RP0_freq_mhz, S_IRUGO, gt_rp_mhz_show, NULL);
+static DEVICE_ATTR(gt_RP1_freq_mhz, S_IRUGO, gt_rp_mhz_show, NULL);
+static DEVICE_ATTR(gt_RPn_freq_mhz, S_IRUGO, gt_rp_mhz_show, NULL);
+
+/* For now we have a static number of RP states */
+static ssize_t gt_rp_mhz_show(struct device *kdev, struct device_attribute *attr, char *buf)
+{
+	struct drm_minor *minor = dev_to_drm_minor(kdev);
+	struct drm_device *dev = minor->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	u32 val;
+
+	if (attr == &dev_attr_gt_RP0_freq_mhz)
+		val = intel_gpu_freq(dev_priv, dev_priv->rps.rp0_freq);
+	else if (attr == &dev_attr_gt_RP1_freq_mhz)
+		val = intel_gpu_freq(dev_priv, dev_priv->rps.rp1_freq);
+	else if (attr == &dev_attr_gt_RPn_freq_mhz)
+		val = intel_gpu_freq(dev_priv, dev_priv->rps.min_freq);
+	else
+		BUG();
+
+	return snprintf(buf, PAGE_SIZE, "%d\n", val);
+}
+
+static const struct attribute *gen6_attrs[] = {
+	&dev_attr_gt_act_freq_mhz.attr,
+	&dev_attr_gt_cur_freq_mhz.attr,
+	&dev_attr_gt_max_freq_mhz.attr,
+	&dev_attr_gt_min_freq_mhz.attr,
+	&dev_attr_gt_RP0_freq_mhz.attr,
+	&dev_attr_gt_RP1_freq_mhz.attr,
+	&dev_attr_gt_RPn_freq_mhz.attr,
+	NULL,
+};
+
+static const struct attribute *vlv_attrs[] = {
+	&dev_attr_gt_act_freq_mhz.attr,
+	&dev_attr_gt_cur_freq_mhz.attr,
+	&dev_attr_gt_max_freq_mhz.attr,
+	&dev_attr_gt_min_freq_mhz.attr,
+	&dev_attr_gt_RP0_freq_mhz.attr,
+	&dev_attr_gt_RP1_freq_mhz.attr,
+	&dev_attr_gt_RPn_freq_mhz.attr,
+	&dev_attr_vlv_rpe_freq_mhz.attr,
+	NULL,
+};
+
+static ssize_t error_state_read(struct file *filp, struct kobject *kobj,
+				struct bin_attribute *attr, char *buf,
+				loff_t off, size_t count)
+{
+
+	struct device *kdev = kobj_to_dev(kobj);
+	struct drm_minor *minor = dev_to_drm_minor(kdev);
+	struct drm_device *dev = minor->dev;
+	struct i915_error_state_file_priv error_priv;
+	struct drm_i915_error_state_buf error_str;
+	ssize_t ret_count = 0;
+	int ret;
+
+	memset(&error_priv, 0, sizeof(error_priv));
+
+	ret = i915_error_state_buf_init(&error_str, to_i915(dev), count, off);
+	if (ret)
+		return ret;
+
+	error_priv.dev = dev;
+	i915_error_state_get(dev, &error_priv);
+
+	ret = i915_error_state_to_str(&error_str, &error_priv);
+	if (ret)
+		goto out;
+
+	ret_count = count < error_str.bytes ? count : error_str.bytes;
+
+	memcpy(buf, error_str.buf, ret_count);
+out:
+	i915_error_state_put(&error_priv);
+	i915_error_state_buf_release(&error_str);
+
+	return ret ?: ret_count;
+}
+
+static ssize_t error_state_write(struct file *file, struct kobject *kobj,
+				 struct bin_attribute *attr, char *buf,
+				 loff_t off, size_t count)
+{
+	struct device *kdev = kobj_to_dev(kobj);
+	struct drm_minor *minor = dev_to_drm_minor(kdev);
+	struct drm_device *dev = minor->dev;
+	int ret;
+
+	DRM_DEBUG_DRIVER("Resetting error state\n");
+
+	ret = mutex_lock_interruptible(&dev->struct_mutex);
+	if (ret)
+		return ret;
+
+	i915_destroy_error_state(dev);
+	mutex_unlock(&dev->struct_mutex);
+
+	return count;
+}
+
+static struct bin_attribute error_state_attr = {
+	.attr.name = "error",
+	.attr.mode = S_IRUSR | S_IWUSR,
+	.size = 0,
+	.read = error_state_read,
+	.write = error_state_write,
+};
+
+void i915_setup_sysfs(struct drm_device *dev)
+{
+	int ret;
+
+#ifdef CONFIG_PM
+	if (HAS_RC6(dev)) {
+		ret = sysfs_merge_group(&dev->primary->kdev->kobj,
+					&rc6_attr_group);
+		if (ret)
+			DRM_ERROR("RC6 residency sysfs setup failed\n");
+	}
+	if (HAS_RC6p(dev)) {
+		ret = sysfs_merge_group(&dev->primary->kdev->kobj,
+					&rc6p_attr_group);
+		if (ret)
+			DRM_ERROR("RC6p residency sysfs setup failed\n");
+	}
+	if (IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev)) {
+		ret = sysfs_merge_group(&dev->primary->kdev->kobj,
+					&media_rc6_attr_group);
+		if (ret)
+			DRM_ERROR("Media RC6 residency sysfs setup failed\n");
+	}
+#endif
+	if (HAS_L3_DPF(dev)) {
+		ret = device_create_bin_file(dev->primary->kdev, &dpf_attrs);
+		if (ret)
+			DRM_ERROR("l3 parity sysfs setup failed\n");
+
+		if (NUM_L3_SLICES(dev) > 1) {
+			ret = device_create_bin_file(dev->primary->kdev,
+						     &dpf_attrs_1);
+			if (ret)
+				DRM_ERROR("l3 parity slice 1 setup failed\n");
+		}
+	}
+
+	ret = 0;
+	if (IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev))
+		ret = sysfs_create_files(&dev->primary->kdev->kobj, vlv_attrs);
+	else if (INTEL_INFO(dev)->gen >= 6)
+		ret = sysfs_create_files(&dev->primary->kdev->kobj, gen6_attrs);
+	if (ret)
+		DRM_ERROR("RPS sysfs setup failed\n");
+
+	ret = sysfs_create_bin_file(&dev->primary->kdev->kobj,
+				    &error_state_attr);
+	if (ret)
+		DRM_ERROR("error_state sysfs setup failed\n");
+}
+
+void i915_teardown_sysfs(struct drm_device *dev)
+{
+	sysfs_remove_bin_file(&dev->primary->kdev->kobj, &error_state_attr);
+	if (IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev))
+		sysfs_remove_files(&dev->primary->kdev->kobj, vlv_attrs);
+	else
+		sysfs_remove_files(&dev->primary->kdev->kobj, gen6_attrs);
+	device_remove_bin_file(dev->primary->kdev,  &dpf_attrs_1);
+	device_remove_bin_file(dev->primary->kdev,  &dpf_attrs);
+#ifdef CONFIG_PM
+	sysfs_unmerge_group(&dev->primary->kdev->kobj, &rc6_attr_group);
+	sysfs_unmerge_group(&dev->primary->kdev->kobj, &rc6p_attr_group);
+#endif
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/i915/i915_trace.h
@@ -0,0 +1,807 @@
+#if !defined(_I915_TRACE_H_) || defined(TRACE_HEADER_MULTI_READ)
+#define _I915_TRACE_H_
+
+#include <linux/stringify.h>
+#include <linux/types.h>
+#include <linux/tracepoint.h>
+
+#include <drm/drmP.h>
+#include "i915_drv.h"
+#include "intel_drv.h"
+#include "intel_ringbuffer.h"
+
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM i915
+#define TRACE_INCLUDE_FILE i915_trace
+
+/* pipe updates */
+
+TRACE_EVENT(i915_pipe_update_start,
+	    TP_PROTO(struct intel_crtc *crtc),
+	    TP_ARGS(crtc),
+
+	    TP_STRUCT__entry(
+			     __field(enum pipe, pipe)
+			     __field(u32, frame)
+			     __field(u32, scanline)
+			     __field(u32, min)
+			     __field(u32, max)
+			     ),
+
+	    TP_fast_assign(
+			   __entry->pipe = crtc->pipe;
+			   __entry->frame = crtc->base.dev->driver->get_vblank_counter(crtc->base.dev,
+										       crtc->pipe);
+			   __entry->scanline = intel_get_crtc_scanline(crtc);
+			   __entry->min = crtc->debug.min_vbl;
+			   __entry->max = crtc->debug.max_vbl;
+			   ),
+
+	    TP_printk("pipe %c, frame=%u, scanline=%u, min=%u, max=%u",
+		      pipe_name(__entry->pipe), __entry->frame,
+		       __entry->scanline, __entry->min, __entry->max)
+);
+
+TRACE_EVENT(i915_pipe_update_vblank_evaded,
+	    TP_PROTO(struct intel_crtc *crtc),
+	    TP_ARGS(crtc),
+
+	    TP_STRUCT__entry(
+			     __field(enum pipe, pipe)
+			     __field(u32, frame)
+			     __field(u32, scanline)
+			     __field(u32, min)
+			     __field(u32, max)
+			     ),
+
+	    TP_fast_assign(
+			   __entry->pipe = crtc->pipe;
+			   __entry->frame = crtc->debug.start_vbl_count;
+			   __entry->scanline = crtc->debug.scanline_start;
+			   __entry->min = crtc->debug.min_vbl;
+			   __entry->max = crtc->debug.max_vbl;
+			   ),
+
+	    TP_printk("pipe %c, frame=%u, scanline=%u, min=%u, max=%u",
+		      pipe_name(__entry->pipe), __entry->frame,
+		       __entry->scanline, __entry->min, __entry->max)
+);
+
+TRACE_EVENT(i915_pipe_update_end,
+	    TP_PROTO(struct intel_crtc *crtc, u32 frame, int scanline_end),
+	    TP_ARGS(crtc, frame, scanline_end),
+
+	    TP_STRUCT__entry(
+			     __field(enum pipe, pipe)
+			     __field(u32, frame)
+			     __field(u32, scanline)
+			     ),
+
+	    TP_fast_assign(
+			   __entry->pipe = crtc->pipe;
+			   __entry->frame = frame;
+			   __entry->scanline = scanline_end;
+			   ),
+
+	    TP_printk("pipe %c, frame=%u, scanline=%u",
+		      pipe_name(__entry->pipe), __entry->frame,
+		      __entry->scanline)
+);
+
+/* object tracking */
+
+TRACE_EVENT(i915_gem_object_create,
+	    TP_PROTO(struct drm_i915_gem_object *obj),
+	    TP_ARGS(obj),
+
+	    TP_STRUCT__entry(
+			     __field(struct drm_i915_gem_object *, obj)
+			     __field(u32, size)
+			     ),
+
+	    TP_fast_assign(
+			   __entry->obj = obj;
+			   __entry->size = obj->base.size;
+			   ),
+
+	    TP_printk("obj=%p, size=%u", __entry->obj, __entry->size)
+);
+
+TRACE_EVENT(i915_gem_shrink,
+	    TP_PROTO(struct drm_i915_private *i915, unsigned long target, unsigned flags),
+	    TP_ARGS(i915, target, flags),
+
+	    TP_STRUCT__entry(
+			     __field(int, dev)
+			     __field(unsigned long, target)
+			     __field(unsigned, flags)
+			     ),
+
+	    TP_fast_assign(
+			   __entry->dev = i915->dev->primary->index;
+			   __entry->target = target;
+			   __entry->flags = flags;
+			   ),
+
+	    TP_printk("dev=%d, target=%lu, flags=%x",
+		      __entry->dev, __entry->target, __entry->flags)
+);
+
+TRACE_EVENT(i915_vma_bind,
+	    TP_PROTO(struct i915_vma *vma, unsigned flags),
+	    TP_ARGS(vma, flags),
+
+	    TP_STRUCT__entry(
+			     __field(struct drm_i915_gem_object *, obj)
+			     __field(struct i915_address_space *, vm)
+			     __field(u64, offset)
+			     __field(u32, size)
+			     __field(unsigned, flags)
+			     ),
+
+	    TP_fast_assign(
+			   __entry->obj = vma->obj;
+			   __entry->vm = vma->vm;
+			   __entry->offset = vma->node.start;
+			   __entry->size = vma->node.size;
+			   __entry->flags = flags;
+			   ),
+
+	    TP_printk("obj=%p, offset=%016llx size=%x%s vm=%p",
+		      __entry->obj, __entry->offset, __entry->size,
+		      __entry->flags & PIN_MAPPABLE ? ", mappable" : "",
+		      __entry->vm)
+);
+
+TRACE_EVENT(i915_vma_unbind,
+	    TP_PROTO(struct i915_vma *vma),
+	    TP_ARGS(vma),
+
+	    TP_STRUCT__entry(
+			     __field(struct drm_i915_gem_object *, obj)
+			     __field(struct i915_address_space *, vm)
+			     __field(u64, offset)
+			     __field(u32, size)
+			     ),
+
+	    TP_fast_assign(
+			   __entry->obj = vma->obj;
+			   __entry->vm = vma->vm;
+			   __entry->offset = vma->node.start;
+			   __entry->size = vma->node.size;
+			   ),
+
+	    TP_printk("obj=%p, offset=%016llx size=%x vm=%p",
+		      __entry->obj, __entry->offset, __entry->size, __entry->vm)
+);
+
+TRACE_EVENT(i915_va_alloc,
+	TP_PROTO(struct i915_vma *vma),
+	TP_ARGS(vma),
+
+	TP_STRUCT__entry(
+		__field(struct i915_address_space *, vm)
+		__field(u64, start)
+		__field(u64, end)
+	),
+
+	TP_fast_assign(
+		__entry->vm = vma->vm;
+		__entry->start = vma->node.start;
+		__entry->end = vma->node.start + vma->node.size - 1;
+	),
+
+	TP_printk("vm=%p (%c), 0x%llx-0x%llx",
+		  __entry->vm, i915_is_ggtt(__entry->vm) ? 'G' : 'P',  __entry->start, __entry->end)
+);
+
+DECLARE_EVENT_CLASS(i915_px_entry,
+	TP_PROTO(struct i915_address_space *vm, u32 px, u64 start, u64 px_shift),
+	TP_ARGS(vm, px, start, px_shift),
+
+	TP_STRUCT__entry(
+		__field(struct i915_address_space *, vm)
+		__field(u32, px)
+		__field(u64, start)
+		__field(u64, end)
+	),
+
+	TP_fast_assign(
+		__entry->vm = vm;
+		__entry->px = px;
+		__entry->start = start;
+		__entry->end = ((start + (1ULL << px_shift)) & ~((1ULL << px_shift)-1)) - 1;
+	),
+
+	TP_printk("vm=%p, pde=%d (0x%llx-0x%llx)",
+		  __entry->vm, __entry->px, __entry->start, __entry->end)
+);
+
+DEFINE_EVENT(i915_px_entry, i915_page_table_entry_alloc,
+	     TP_PROTO(struct i915_address_space *vm, u32 pde, u64 start, u64 pde_shift),
+	     TP_ARGS(vm, pde, start, pde_shift)
+);
+
+DEFINE_EVENT_PRINT(i915_px_entry, i915_page_directory_entry_alloc,
+		   TP_PROTO(struct i915_address_space *vm, u32 pdpe, u64 start, u64 pdpe_shift),
+		   TP_ARGS(vm, pdpe, start, pdpe_shift),
+
+		   TP_printk("vm=%p, pdpe=%d (0x%llx-0x%llx)",
+			     __entry->vm, __entry->px, __entry->start, __entry->end)
+);
+
+DEFINE_EVENT_PRINT(i915_px_entry, i915_page_directory_pointer_entry_alloc,
+		   TP_PROTO(struct i915_address_space *vm, u32 pml4e, u64 start, u64 pml4e_shift),
+		   TP_ARGS(vm, pml4e, start, pml4e_shift),
+
+		   TP_printk("vm=%p, pml4e=%d (0x%llx-0x%llx)",
+			     __entry->vm, __entry->px, __entry->start, __entry->end)
+);
+
+/* Avoid extra math because we only support two sizes. The format is defined by
+ * bitmap_scnprintf. Each 32 bits is 8 HEX digits followed by comma */
+#define TRACE_PT_SIZE(bits) \
+	((((bits) == 1024) ? 288 : 144) + 1)
+
+DECLARE_EVENT_CLASS(i915_page_table_entry_update,
+	TP_PROTO(struct i915_address_space *vm, u32 pde,
+		 struct i915_page_table *pt, u32 first, u32 count, u32 bits),
+	TP_ARGS(vm, pde, pt, first, count, bits),
+
+	TP_STRUCT__entry(
+		__field(struct i915_address_space *, vm)
+		__field(u32, pde)
+		__field(u32, first)
+		__field(u32, last)
+		__dynamic_array(char, cur_ptes, TRACE_PT_SIZE(bits))
+	),
+
+	TP_fast_assign(
+		__entry->vm = vm;
+		__entry->pde = pde;
+		__entry->first = first;
+		__entry->last = first + count - 1;
+		scnprintf(__get_str(cur_ptes),
+			  TRACE_PT_SIZE(bits),
+			  "%*pb",
+			  bits,
+			  pt->used_ptes);
+	),
+
+	TP_printk("vm=%p, pde=%d, updating %u:%u\t%s",
+		  __entry->vm, __entry->pde, __entry->last, __entry->first,
+		  __get_str(cur_ptes))
+);
+
+DEFINE_EVENT(i915_page_table_entry_update, i915_page_table_entry_map,
+	TP_PROTO(struct i915_address_space *vm, u32 pde,
+		 struct i915_page_table *pt, u32 first, u32 count, u32 bits),
+	TP_ARGS(vm, pde, pt, first, count, bits)
+);
+
+TRACE_EVENT(i915_gem_object_change_domain,
+	    TP_PROTO(struct drm_i915_gem_object *obj, u32 old_read, u32 old_write),
+	    TP_ARGS(obj, old_read, old_write),
+
+	    TP_STRUCT__entry(
+			     __field(struct drm_i915_gem_object *, obj)
+			     __field(u32, read_domains)
+			     __field(u32, write_domain)
+			     ),
+
+	    TP_fast_assign(
+			   __entry->obj = obj;
+			   __entry->read_domains = obj->base.read_domains | (old_read << 16);
+			   __entry->write_domain = obj->base.write_domain | (old_write << 16);
+			   ),
+
+	    TP_printk("obj=%p, read=%02x=>%02x, write=%02x=>%02x",
+		      __entry->obj,
+		      __entry->read_domains >> 16,
+		      __entry->read_domains & 0xffff,
+		      __entry->write_domain >> 16,
+		      __entry->write_domain & 0xffff)
+);
+
+TRACE_EVENT(i915_gem_object_pwrite,
+	    TP_PROTO(struct drm_i915_gem_object *obj, u32 offset, u32 len),
+	    TP_ARGS(obj, offset, len),
+
+	    TP_STRUCT__entry(
+			     __field(struct drm_i915_gem_object *, obj)
+			     __field(u32, offset)
+			     __field(u32, len)
+			     ),
+
+	    TP_fast_assign(
+			   __entry->obj = obj;
+			   __entry->offset = offset;
+			   __entry->len = len;
+			   ),
+
+	    TP_printk("obj=%p, offset=%u, len=%u",
+		      __entry->obj, __entry->offset, __entry->len)
+);
+
+TRACE_EVENT(i915_gem_object_pread,
+	    TP_PROTO(struct drm_i915_gem_object *obj, u32 offset, u32 len),
+	    TP_ARGS(obj, offset, len),
+
+	    TP_STRUCT__entry(
+			     __field(struct drm_i915_gem_object *, obj)
+			     __field(u32, offset)
+			     __field(u32, len)
+			     ),
+
+	    TP_fast_assign(
+			   __entry->obj = obj;
+			   __entry->offset = offset;
+			   __entry->len = len;
+			   ),
+
+	    TP_printk("obj=%p, offset=%u, len=%u",
+		      __entry->obj, __entry->offset, __entry->len)
+);
+
+TRACE_EVENT(i915_gem_object_fault,
+	    TP_PROTO(struct drm_i915_gem_object *obj, u32 index, bool gtt, bool write),
+	    TP_ARGS(obj, index, gtt, write),
+
+	    TP_STRUCT__entry(
+			     __field(struct drm_i915_gem_object *, obj)
+			     __field(u32, index)
+			     __field(bool, gtt)
+			     __field(bool, write)
+			     ),
+
+	    TP_fast_assign(
+			   __entry->obj = obj;
+			   __entry->index = index;
+			   __entry->gtt = gtt;
+			   __entry->write = write;
+			   ),
+
+	    TP_printk("obj=%p, %s index=%u %s",
+		      __entry->obj,
+		      __entry->gtt ? "GTT" : "CPU",
+		      __entry->index,
+		      __entry->write ? ", writable" : "")
+);
+
+DECLARE_EVENT_CLASS(i915_gem_object,
+	    TP_PROTO(struct drm_i915_gem_object *obj),
+	    TP_ARGS(obj),
+
+	    TP_STRUCT__entry(
+			     __field(struct drm_i915_gem_object *, obj)
+			     ),
+
+	    TP_fast_assign(
+			   __entry->obj = obj;
+			   ),
+
+	    TP_printk("obj=%p", __entry->obj)
+);
+
+DEFINE_EVENT(i915_gem_object, i915_gem_object_clflush,
+	     TP_PROTO(struct drm_i915_gem_object *obj),
+	     TP_ARGS(obj)
+);
+
+DEFINE_EVENT(i915_gem_object, i915_gem_object_destroy,
+	    TP_PROTO(struct drm_i915_gem_object *obj),
+	    TP_ARGS(obj)
+);
+
+TRACE_EVENT(i915_gem_evict,
+	    TP_PROTO(struct drm_device *dev, u32 size, u32 align, unsigned flags),
+	    TP_ARGS(dev, size, align, flags),
+
+	    TP_STRUCT__entry(
+			     __field(u32, dev)
+			     __field(u32, size)
+			     __field(u32, align)
+			     __field(unsigned, flags)
+			    ),
+
+	    TP_fast_assign(
+			   __entry->dev = dev->primary->index;
+			   __entry->size = size;
+			   __entry->align = align;
+			   __entry->flags = flags;
+			  ),
+
+	    TP_printk("dev=%d, size=%d, align=%d %s",
+		      __entry->dev, __entry->size, __entry->align,
+		      __entry->flags & PIN_MAPPABLE ? ", mappable" : "")
+);
+
+TRACE_EVENT(i915_gem_evict_everything,
+	    TP_PROTO(struct drm_device *dev),
+	    TP_ARGS(dev),
+
+	    TP_STRUCT__entry(
+			     __field(u32, dev)
+			    ),
+
+	    TP_fast_assign(
+			   __entry->dev = dev->primary->index;
+			  ),
+
+	    TP_printk("dev=%d", __entry->dev)
+);
+
+TRACE_EVENT(i915_gem_evict_vm,
+	    TP_PROTO(struct i915_address_space *vm),
+	    TP_ARGS(vm),
+
+	    TP_STRUCT__entry(
+			     __field(u32, dev)
+			     __field(struct i915_address_space *, vm)
+			    ),
+
+	    TP_fast_assign(
+			   __entry->dev = vm->dev->primary->index;
+			   __entry->vm = vm;
+			  ),
+
+	    TP_printk("dev=%d, vm=%p", __entry->dev, __entry->vm)
+);
+
+TRACE_EVENT(i915_gem_ring_sync_to,
+	    TP_PROTO(struct drm_i915_gem_request *to_req,
+		     struct intel_engine_cs *from,
+		     struct drm_i915_gem_request *req),
+	    TP_ARGS(to_req, from, req),
+
+	    TP_STRUCT__entry(
+			     __field(u32, dev)
+			     __field(u32, sync_from)
+			     __field(u32, sync_to)
+			     __field(u32, seqno)
+			     ),
+
+	    TP_fast_assign(
+			   __entry->dev = from->dev->primary->index;
+			   __entry->sync_from = from->id;
+			   __entry->sync_to = to_req->engine->id;
+			   __entry->seqno = i915_gem_request_get_seqno(req);
+			   ),
+
+	    TP_printk("dev=%u, sync-from=%u, sync-to=%u, seqno=%u",
+		      __entry->dev,
+		      __entry->sync_from, __entry->sync_to,
+		      __entry->seqno)
+);
+
+TRACE_EVENT(i915_gem_ring_dispatch,
+	    TP_PROTO(struct drm_i915_gem_request *req, u32 flags),
+	    TP_ARGS(req, flags),
+
+	    TP_STRUCT__entry(
+			     __field(u32, dev)
+			     __field(u32, ring)
+			     __field(u32, seqno)
+			     __field(u32, flags)
+			     ),
+
+	    TP_fast_assign(
+			   struct intel_engine_cs *engine =
+						i915_gem_request_get_engine(req);
+			   __entry->dev = engine->dev->primary->index;
+			   __entry->ring = engine->id;
+			   __entry->seqno = i915_gem_request_get_seqno(req);
+			   __entry->flags = flags;
+			   i915_trace_irq_get(engine, req);
+			   ),
+
+	    TP_printk("dev=%u, ring=%u, seqno=%u, flags=%x",
+		      __entry->dev, __entry->ring, __entry->seqno, __entry->flags)
+);
+
+TRACE_EVENT(i915_gem_ring_flush,
+	    TP_PROTO(struct drm_i915_gem_request *req, u32 invalidate, u32 flush),
+	    TP_ARGS(req, invalidate, flush),
+
+	    TP_STRUCT__entry(
+			     __field(u32, dev)
+			     __field(u32, ring)
+			     __field(u32, invalidate)
+			     __field(u32, flush)
+			     ),
+
+	    TP_fast_assign(
+			   __entry->dev = req->engine->dev->primary->index;
+			   __entry->ring = req->engine->id;
+			   __entry->invalidate = invalidate;
+			   __entry->flush = flush;
+			   ),
+
+	    TP_printk("dev=%u, ring=%x, invalidate=%04x, flush=%04x",
+		      __entry->dev, __entry->ring,
+		      __entry->invalidate, __entry->flush)
+);
+
+DECLARE_EVENT_CLASS(i915_gem_request,
+	    TP_PROTO(struct drm_i915_gem_request *req),
+	    TP_ARGS(req),
+
+	    TP_STRUCT__entry(
+			     __field(u32, dev)
+			     __field(u32, ring)
+			     __field(u32, seqno)
+			     ),
+
+	    TP_fast_assign(
+			   struct intel_engine_cs *engine =
+						i915_gem_request_get_engine(req);
+			   __entry->dev = engine->dev->primary->index;
+			   __entry->ring = engine->id;
+			   __entry->seqno = i915_gem_request_get_seqno(req);
+			   ),
+
+	    TP_printk("dev=%u, ring=%u, seqno=%u",
+		      __entry->dev, __entry->ring, __entry->seqno)
+);
+
+DEFINE_EVENT(i915_gem_request, i915_gem_request_add,
+	    TP_PROTO(struct drm_i915_gem_request *req),
+	    TP_ARGS(req)
+);
+
+TRACE_EVENT(i915_gem_request_notify,
+	    TP_PROTO(struct intel_engine_cs *engine),
+	    TP_ARGS(engine),
+
+	    TP_STRUCT__entry(
+			     __field(u32, dev)
+			     __field(u32, ring)
+			     __field(u32, seqno)
+			     ),
+
+	    TP_fast_assign(
+			   __entry->dev = engine->dev->primary->index;
+			   __entry->ring = engine->id;
+			   __entry->seqno = engine->get_seqno(engine);
+			   ),
+
+	    TP_printk("dev=%u, ring=%u, seqno=%u",
+		      __entry->dev, __entry->ring, __entry->seqno)
+);
+
+DEFINE_EVENT(i915_gem_request, i915_gem_request_retire,
+	    TP_PROTO(struct drm_i915_gem_request *req),
+	    TP_ARGS(req)
+);
+
+DEFINE_EVENT(i915_gem_request, i915_gem_request_complete,
+	    TP_PROTO(struct drm_i915_gem_request *req),
+	    TP_ARGS(req)
+);
+
+TRACE_EVENT(i915_gem_request_wait_begin,
+	    TP_PROTO(struct drm_i915_gem_request *req),
+	    TP_ARGS(req),
+
+	    TP_STRUCT__entry(
+			     __field(u32, dev)
+			     __field(u32, ring)
+			     __field(u32, seqno)
+			     __field(bool, blocking)
+			     ),
+
+	    /* NB: the blocking information is racy since mutex_is_locked
+	     * doesn't check that the current thread holds the lock. The only
+	     * other option would be to pass the boolean information of whether
+	     * or not the class was blocking down through the stack which is
+	     * less desirable.
+	     */
+	    TP_fast_assign(
+			   struct intel_engine_cs *engine =
+						i915_gem_request_get_engine(req);
+			   __entry->dev = engine->dev->primary->index;
+			   __entry->ring = engine->id;
+			   __entry->seqno = i915_gem_request_get_seqno(req);
+			   __entry->blocking =
+				     mutex_is_locked(&engine->dev->struct_mutex);
+			   ),
+
+	    TP_printk("dev=%u, ring=%u, seqno=%u, blocking=%s",
+		      __entry->dev, __entry->ring,
+		      __entry->seqno, __entry->blocking ?  "yes (NB)" : "no")
+);
+
+DEFINE_EVENT(i915_gem_request, i915_gem_request_wait_end,
+	    TP_PROTO(struct drm_i915_gem_request *req),
+	    TP_ARGS(req)
+);
+
+TRACE_EVENT(i915_flip_request,
+	    TP_PROTO(int plane, struct drm_i915_gem_object *obj),
+
+	    TP_ARGS(plane, obj),
+
+	    TP_STRUCT__entry(
+		    __field(int, plane)
+		    __field(struct drm_i915_gem_object *, obj)
+		    ),
+
+	    TP_fast_assign(
+		    __entry->plane = plane;
+		    __entry->obj = obj;
+		    ),
+
+	    TP_printk("plane=%d, obj=%p", __entry->plane, __entry->obj)
+);
+
+TRACE_EVENT(i915_flip_complete,
+	    TP_PROTO(int plane, struct drm_i915_gem_object *obj),
+
+	    TP_ARGS(plane, obj),
+
+	    TP_STRUCT__entry(
+		    __field(int, plane)
+		    __field(struct drm_i915_gem_object *, obj)
+		    ),
+
+	    TP_fast_assign(
+		    __entry->plane = plane;
+		    __entry->obj = obj;
+		    ),
+
+	    TP_printk("plane=%d, obj=%p", __entry->plane, __entry->obj)
+);
+
+TRACE_EVENT_CONDITION(i915_reg_rw,
+	TP_PROTO(bool write, i915_reg_t reg, u64 val, int len, bool trace),
+
+	TP_ARGS(write, reg, val, len, trace),
+
+	TP_CONDITION(trace),
+
+	TP_STRUCT__entry(
+		__field(u64, val)
+		__field(u32, reg)
+		__field(u16, write)
+		__field(u16, len)
+		),
+
+	TP_fast_assign(
+		__entry->val = (u64)val;
+		__entry->reg = i915_mmio_reg_offset(reg);
+		__entry->write = write;
+		__entry->len = len;
+		),
+
+	TP_printk("%s reg=0x%x, len=%d, val=(0x%x, 0x%x)",
+		__entry->write ? "write" : "read",
+		__entry->reg, __entry->len,
+		(u32)(__entry->val & 0xffffffff),
+		(u32)(__entry->val >> 32))
+);
+
+TRACE_EVENT(intel_gpu_freq_change,
+	    TP_PROTO(u32 freq),
+	    TP_ARGS(freq),
+
+	    TP_STRUCT__entry(
+			     __field(u32, freq)
+			     ),
+
+	    TP_fast_assign(
+			   __entry->freq = freq;
+			   ),
+
+	    TP_printk("new_freq=%u", __entry->freq)
+);
+
+/**
+ * DOC: i915_ppgtt_create and i915_ppgtt_release tracepoints
+ *
+ * With full ppgtt enabled each process using drm will allocate at least one
+ * translation table. With these traces it is possible to keep track of the
+ * allocation and of the lifetime of the tables; this can be used during
+ * testing/debug to verify that we are not leaking ppgtts.
+ * These traces identify the ppgtt through the vm pointer, which is also printed
+ * by the i915_vma_bind and i915_vma_unbind tracepoints.
+ */
+DECLARE_EVENT_CLASS(i915_ppgtt,
+	TP_PROTO(struct i915_address_space *vm),
+	TP_ARGS(vm),
+
+	TP_STRUCT__entry(
+			__field(struct i915_address_space *, vm)
+			__field(u32, dev)
+	),
+
+	TP_fast_assign(
+			__entry->vm = vm;
+			__entry->dev = vm->dev->primary->index;
+	),
+
+	TP_printk("dev=%u, vm=%p", __entry->dev, __entry->vm)
+)
+
+DEFINE_EVENT(i915_ppgtt, i915_ppgtt_create,
+	TP_PROTO(struct i915_address_space *vm),
+	TP_ARGS(vm)
+);
+
+DEFINE_EVENT(i915_ppgtt, i915_ppgtt_release,
+	TP_PROTO(struct i915_address_space *vm),
+	TP_ARGS(vm)
+);
+
+/**
+ * DOC: i915_context_create and i915_context_free tracepoints
+ *
+ * These tracepoints are used to track creation and deletion of contexts.
+ * If full ppgtt is enabled, they also print the address of the vm assigned to
+ * the context.
+ */
+DECLARE_EVENT_CLASS(i915_context,
+	TP_PROTO(struct intel_context *ctx),
+	TP_ARGS(ctx),
+
+	TP_STRUCT__entry(
+			__field(u32, dev)
+			__field(struct intel_context *, ctx)
+			__field(struct i915_address_space *, vm)
+	),
+
+	TP_fast_assign(
+			__entry->ctx = ctx;
+			__entry->vm = ctx->ppgtt ? &ctx->ppgtt->base : NULL;
+			__entry->dev = ctx->i915->dev->primary->index;
+	),
+
+	TP_printk("dev=%u, ctx=%p, ctx_vm=%p",
+		  __entry->dev, __entry->ctx, __entry->vm)
+)
+
+DEFINE_EVENT(i915_context, i915_context_create,
+	TP_PROTO(struct intel_context *ctx),
+	TP_ARGS(ctx)
+);
+
+DEFINE_EVENT(i915_context, i915_context_free,
+	TP_PROTO(struct intel_context *ctx),
+	TP_ARGS(ctx)
+);
+
+/**
+ * DOC: switch_mm tracepoint
+ *
+ * This tracepoint allows tracking of the mm switch, which is an important point
+ * in the lifetime of the vm in the legacy submission path. This tracepoint is
+ * called only if full ppgtt is enabled.
+ */
+TRACE_EVENT(switch_mm,
+	TP_PROTO(struct intel_engine_cs *engine, struct intel_context *to),
+
+	TP_ARGS(engine, to),
+
+	TP_STRUCT__entry(
+			__field(u32, ring)
+			__field(struct intel_context *, to)
+			__field(struct i915_address_space *, vm)
+			__field(u32, dev)
+	),
+
+	TP_fast_assign(
+			__entry->ring = engine->id;
+			__entry->to = to;
+			__entry->vm = to->ppgtt? &to->ppgtt->base : NULL;
+			__entry->dev = engine->dev->primary->index;
+	),
+
+	TP_printk("dev=%u, ring=%u, ctx=%p, ctx_vm=%p",
+		  __entry->dev, __entry->ring, __entry->to, __entry->vm)
+);
+
+#endif /* _I915_TRACE_H_ */
+
+/* This part must be outside protection */
+#undef TRACE_INCLUDE_PATH
+#define TRACE_INCLUDE_PATH .
+#include <trace/define_trace.h>
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/i915/i915_trace_points.c
@@ -0,0 +1,13 @@
+/*
+ * Copyright © 2009 Intel Corporation
+ *
+ * Authors:
+ *    Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "i915_drv.h"
+
+#ifndef __CHECKER__
+#define CREATE_TRACE_POINTS
+#include "i915_trace.h"
+#endif
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/i915/i915_vgpu.c
@@ -0,0 +1,264 @@
+/*
+ * Copyright(c) 2011-2015 Intel Corporation. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include "intel_drv.h"
+#include "i915_vgpu.h"
+
+/**
+ * DOC: Intel GVT-g guest support
+ *
+ * Intel GVT-g is a graphics virtualization technology which shares the
+ * GPU among multiple virtual machines on a time-sharing basis. Each
+ * virtual machine is presented a virtual GPU (vGPU), which has equivalent
+ * features as the underlying physical GPU (pGPU), so i915 driver can run
+ * seamlessly in a virtual machine. This file provides vGPU specific
+ * optimizations when running in a virtual machine, to reduce the complexity
+ * of vGPU emulation and to improve the overall performance.
+ *
+ * A primary function introduced here is so-called "address space ballooning"
+ * technique. Intel GVT-g partitions global graphics memory among multiple VMs,
+ * so each VM can directly access a portion of the memory without hypervisor's
+ * intervention, e.g. filling textures or queuing commands. However with the
+ * partitioning an unmodified i915 driver would assume a smaller graphics
+ * memory starting from address ZERO, then requires vGPU emulation module to
+ * translate the graphics address between 'guest view' and 'host view', for
+ * all registers and command opcodes which contain a graphics memory address.
+ * To reduce the complexity, Intel GVT-g introduces "address space ballooning",
+ * by telling the exact partitioning knowledge to each guest i915 driver, which
+ * then reserves and prevents non-allocated portions from allocation. Thus vGPU
+ * emulation module only needs to scan and validate graphics addresses without
+ * complexity of address translation.
+ *
+ */
+
+/**
+ * i915_check_vgpu - detect virtual GPU
+ * @dev: drm device *
+ *
+ * This function is called at the initialization stage, to detect whether
+ * running on a vGPU.
+ */
+void i915_check_vgpu(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = to_i915(dev);
+	uint64_t magic;
+	uint32_t version;
+
+	BUILD_BUG_ON(sizeof(struct vgt_if) != VGT_PVINFO_SIZE);
+
+	if (!IS_HASWELL(dev))
+		return;
+
+	magic = __raw_i915_read64(dev_priv, vgtif_reg(magic));
+	if (magic != VGT_MAGIC)
+		return;
+
+	version = INTEL_VGT_IF_VERSION_ENCODE(
+		__raw_i915_read16(dev_priv, vgtif_reg(version_major)),
+		__raw_i915_read16(dev_priv, vgtif_reg(version_minor)));
+	if (version != INTEL_VGT_IF_VERSION) {
+		DRM_INFO("VGT interface version mismatch!\n");
+		return;
+	}
+
+	dev_priv->vgpu.active = true;
+	DRM_INFO("Virtual GPU for Intel GVT-g detected.\n");
+}
+
+struct _balloon_info_ {
+	/*
+	 * There are up to 2 regions per mappable/unmappable graphic
+	 * memory that might be ballooned. Here, index 0/1 is for mappable
+	 * graphic memory, 2/3 for unmappable graphic memory.
+	 */
+	struct drm_mm_node space[4];
+};
+
+static struct _balloon_info_ bl_info;
+
+/**
+ * intel_vgt_deballoon - deballoon reserved graphics address trunks
+ *
+ * This function is called to deallocate the ballooned-out graphic memory, when
+ * driver is unloaded or when ballooning fails.
+ */
+void intel_vgt_deballoon(void)
+{
+	int i;
+
+	DRM_DEBUG("VGT deballoon.\n");
+
+	for (i = 0; i < 4; i++) {
+		if (bl_info.space[i].allocated)
+			drm_mm_remove_node(&bl_info.space[i]);
+	}
+
+	memset(&bl_info, 0, sizeof(bl_info));
+}
+
+static int vgt_balloon_space(struct drm_mm *mm,
+			     struct drm_mm_node *node,
+			     unsigned long start, unsigned long end)
+{
+	unsigned long size = end - start;
+
+	if (start == end)
+		return -EINVAL;
+
+	DRM_INFO("balloon space: range [ 0x%lx - 0x%lx ] %lu KiB.\n",
+		 start, end, size / 1024);
+
+	node->start = start;
+	node->size = size;
+
+	return drm_mm_reserve_node(mm, node);
+}
+
+/**
+ * intel_vgt_balloon - balloon out reserved graphics address trunks
+ * @dev: drm device
+ *
+ * This function is called at the initialization stage, to balloon out the
+ * graphic address space allocated to other vGPUs, by marking these spaces as
+ * reserved. The ballooning related knowledge(starting address and size of
+ * the mappable/unmappable graphic memory) is described in the vgt_if structure
+ * in a reserved mmio range.
+ *
+ * To give an example, the drawing below depicts one typical scenario after
+ * ballooning. Here the vGPU1 has 2 pieces of graphic address spaces ballooned
+ * out each for the mappable and the non-mappable part. From the vGPU1 point of
+ * view, the total size is the same as the physical one, with the start address
+ * of its graphic space being zero. Yet there are some portions ballooned out(
+ * the shadow part, which are marked as reserved by drm allocator). From the
+ * host point of view, the graphic address space is partitioned by multiple
+ * vGPUs in different VMs.
+ *
+ *                        vGPU1 view         Host view
+ *             0 ------> +-----------+     +-----------+
+ *               ^       |///////////|     |   vGPU3   |
+ *               |       |///////////|     +-----------+
+ *               |       |///////////|     |   vGPU2   |
+ *               |       +-----------+     +-----------+
+ *        mappable GM    | available | ==> |   vGPU1   |
+ *               |       +-----------+     +-----------+
+ *               |       |///////////|     |           |
+ *               v       |///////////|     |   Host    |
+ *               +=======+===========+     +===========+
+ *               ^       |///////////|     |   vGPU3   |
+ *               |       |///////////|     +-----------+
+ *               |       |///////////|     |   vGPU2   |
+ *               |       +-----------+     +-----------+
+ *      unmappable GM    | available | ==> |   vGPU1   |
+ *               |       +-----------+     +-----------+
+ *               |       |///////////|     |           |
+ *               |       |///////////|     |   Host    |
+ *               v       |///////////|     |           |
+ * total GM size ------> +-----------+     +-----------+
+ *
+ * Returns:
+ * zero on success, non-zero if configuration invalid or ballooning failed
+ */
+int intel_vgt_balloon(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = to_i915(dev);
+	struct i915_ggtt *ggtt = &dev_priv->ggtt;
+	unsigned long ggtt_end = ggtt->base.start + ggtt->base.total;
+
+	unsigned long mappable_base, mappable_size, mappable_end;
+	unsigned long unmappable_base, unmappable_size, unmappable_end;
+	int ret;
+
+	mappable_base = I915_READ(vgtif_reg(avail_rs.mappable_gmadr.base));
+	mappable_size = I915_READ(vgtif_reg(avail_rs.mappable_gmadr.size));
+	unmappable_base = I915_READ(vgtif_reg(avail_rs.nonmappable_gmadr.base));
+	unmappable_size = I915_READ(vgtif_reg(avail_rs.nonmappable_gmadr.size));
+
+	mappable_end = mappable_base + mappable_size;
+	unmappable_end = unmappable_base + unmappable_size;
+
+	DRM_INFO("VGT ballooning configuration:\n");
+	DRM_INFO("Mappable graphic memory: base 0x%lx size %ldKiB\n",
+		 mappable_base, mappable_size / 1024);
+	DRM_INFO("Unmappable graphic memory: base 0x%lx size %ldKiB\n",
+		 unmappable_base, unmappable_size / 1024);
+
+	if (mappable_base < ggtt->base.start ||
+	    mappable_end > ggtt->mappable_end ||
+	    unmappable_base < ggtt->mappable_end ||
+	    unmappable_end > ggtt_end) {
+		DRM_ERROR("Invalid ballooning configuration!\n");
+		return -EINVAL;
+	}
+
+	/* Unmappable graphic memory ballooning */
+	if (unmappable_base > ggtt->mappable_end) {
+		ret = vgt_balloon_space(&ggtt->base.mm,
+					&bl_info.space[2],
+					ggtt->mappable_end,
+					unmappable_base);
+
+		if (ret)
+			goto err;
+	}
+
+	/*
+	 * No need to partition out the last physical page,
+	 * because it is reserved to the guard page.
+	 */
+	if (unmappable_end < ggtt_end - PAGE_SIZE) {
+		ret = vgt_balloon_space(&ggtt->base.mm,
+					&bl_info.space[3],
+					unmappable_end,
+					ggtt_end - PAGE_SIZE);
+		if (ret)
+			goto err;
+	}
+
+	/* Mappable graphic memory ballooning */
+	if (mappable_base > ggtt->base.start) {
+		ret = vgt_balloon_space(&ggtt->base.mm,
+					&bl_info.space[0],
+					ggtt->base.start, mappable_base);
+
+		if (ret)
+			goto err;
+	}
+
+	if (mappable_end < ggtt->mappable_end) {
+		ret = vgt_balloon_space(&ggtt->base.mm,
+					&bl_info.space[1],
+					mappable_end,
+					ggtt->mappable_end);
+
+		if (ret)
+			goto err;
+	}
+
+	DRM_INFO("VGT balloon successfully\n");
+	return 0;
+
+err:
+	DRM_ERROR("VGT balloon fail\n");
+	intel_vgt_deballoon();
+	return ret;
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/i915/i915_vgpu.h
@@ -0,0 +1,117 @@
+/*
+ * Copyright(c) 2011-2015 Intel Corporation. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef _I915_VGPU_H_
+#define _I915_VGPU_H_
+
+/* The MMIO offset of the shared info between guest and host emulator */
+#define VGT_PVINFO_PAGE	0x78000
+#define VGT_PVINFO_SIZE	0x1000
+
+/*
+ * The following structure pages are defined in GEN MMIO space
+ * for virtualization. (One page for now)
+ */
+#define VGT_MAGIC         0x4776544776544776ULL	/* 'vGTvGTvG' */
+#define VGT_VERSION_MAJOR 1
+#define VGT_VERSION_MINOR 0
+
+#define INTEL_VGT_IF_VERSION_ENCODE(major, minor) ((major) << 16 | (minor))
+#define INTEL_VGT_IF_VERSION \
+	INTEL_VGT_IF_VERSION_ENCODE(VGT_VERSION_MAJOR, VGT_VERSION_MINOR)
+
+/*
+ * notifications from guest to vgpu device model
+ */
+enum vgt_g2v_type {
+	VGT_G2V_PPGTT_L3_PAGE_TABLE_CREATE = 2,
+	VGT_G2V_PPGTT_L3_PAGE_TABLE_DESTROY,
+	VGT_G2V_PPGTT_L4_PAGE_TABLE_CREATE,
+	VGT_G2V_PPGTT_L4_PAGE_TABLE_DESTROY,
+	VGT_G2V_EXECLIST_CONTEXT_CREATE,
+	VGT_G2V_EXECLIST_CONTEXT_DESTROY,
+	VGT_G2V_MAX,
+};
+
+struct vgt_if {
+	uint64_t magic;		/* VGT_MAGIC */
+	uint16_t version_major;
+	uint16_t version_minor;
+	uint32_t vgt_id;	/* ID of vGT instance */
+	uint32_t rsv1[12];	/* pad to offset 0x40 */
+	/*
+	 *  Data structure to describe the balooning info of resources.
+	 *  Each VM can only have one portion of continuous area for now.
+	 *  (May support scattered resource in future)
+	 *  (starting from offset 0x40)
+	 */
+	struct {
+		/* Aperture register balooning */
+		struct {
+			uint32_t base;
+			uint32_t size;
+		} mappable_gmadr;	/* aperture */
+		/* GMADR register balooning */
+		struct {
+			uint32_t base;
+			uint32_t size;
+		} nonmappable_gmadr;	/* non aperture */
+		/* allowed fence registers */
+		uint32_t fence_num;
+		uint32_t rsv2[3];
+	} avail_rs;		/* available/assigned resource */
+	uint32_t rsv3[0x200 - 24];	/* pad to half page */
+	/*
+	 * The bottom half page is for response from Gfx driver to hypervisor.
+	 */
+	uint32_t rsv4;
+	uint32_t display_ready;	/* ready for display owner switch */
+
+	uint32_t rsv5[4];
+
+	uint32_t g2v_notify;
+	uint32_t rsv6[7];
+
+	struct {
+		uint32_t lo;
+		uint32_t hi;
+	} pdp[4];
+
+	uint32_t execlist_context_descriptor_lo;
+	uint32_t execlist_context_descriptor_hi;
+
+	uint32_t  rsv7[0x200 - 24];    /* pad to one page */
+} __packed;
+
+#define vgtif_reg(x) \
+	_MMIO((VGT_PVINFO_PAGE + (long)&((struct vgt_if *)NULL)->x))
+
+/* vGPU display status to be used by the host side */
+#define VGT_DRV_DISPLAY_NOT_READY 0
+#define VGT_DRV_DISPLAY_READY     1  /* ready for display switch */
+
+extern void i915_check_vgpu(struct drm_device *dev);
+extern int intel_vgt_balloon(struct drm_device *dev);
+extern void intel_vgt_deballoon(void);
+
+#endif /* _I915_VGPU_H_ */
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/i915/intel_acpi.c
@@ -0,0 +1,164 @@
+/*
+ * Intel ACPI functions
+ *
+ * _DSM related code stolen from nouveau_acpi.c.
+ */
+#include <linux/pci.h>
+#include <linux/acpi.h>
+#include <drm/drmP.h>
+#include "i915_drv.h"
+
+#define INTEL_DSM_REVISION_ID 1 /* For Calpella anyway... */
+#define INTEL_DSM_FN_PLATFORM_MUX_INFO 1 /* No args */
+
+static struct intel_dsm_priv {
+	acpi_handle dhandle;
+} intel_dsm_priv;
+
+static const u8 intel_dsm_guid[] = {
+	0xd3, 0x73, 0xd8, 0x7e,
+	0xd0, 0xc2,
+	0x4f, 0x4e,
+	0xa8, 0x54,
+	0x0f, 0x13, 0x17, 0xb0, 0x1c, 0x2c
+};
+
+static char *intel_dsm_port_name(u8 id)
+{
+	switch (id) {
+	case 0:
+		return "Reserved";
+	case 1:
+		return "Analog VGA";
+	case 2:
+		return "LVDS";
+	case 3:
+		return "Reserved";
+	case 4:
+		return "HDMI/DVI_B";
+	case 5:
+		return "HDMI/DVI_C";
+	case 6:
+		return "HDMI/DVI_D";
+	case 7:
+		return "DisplayPort_A";
+	case 8:
+		return "DisplayPort_B";
+	case 9:
+		return "DisplayPort_C";
+	case 0xa:
+		return "DisplayPort_D";
+	case 0xb:
+	case 0xc:
+	case 0xd:
+		return "Reserved";
+	case 0xe:
+		return "WiDi";
+	default:
+		return "bad type";
+	}
+}
+
+static char *intel_dsm_mux_type(u8 type)
+{
+	switch (type) {
+	case 0:
+		return "unknown";
+	case 1:
+		return "No MUX, iGPU only";
+	case 2:
+		return "No MUX, dGPU only";
+	case 3:
+		return "MUXed between iGPU and dGPU";
+	default:
+		return "bad type";
+	}
+}
+
+static void intel_dsm_platform_mux_info(void)
+{
+	int i;
+	union acpi_object *pkg, *connector_count;
+
+	pkg = acpi_evaluate_dsm_typed(intel_dsm_priv.dhandle, intel_dsm_guid,
+			INTEL_DSM_REVISION_ID, INTEL_DSM_FN_PLATFORM_MUX_INFO,
+			NULL, ACPI_TYPE_PACKAGE);
+	if (!pkg) {
+		DRM_DEBUG_DRIVER("failed to evaluate _DSM\n");
+		return;
+	}
+
+	connector_count = &pkg->package.elements[0];
+	DRM_DEBUG_DRIVER("MUX info connectors: %lld\n",
+		  (unsigned long long)connector_count->integer.value);
+	for (i = 1; i < pkg->package.count; i++) {
+		union acpi_object *obj = &pkg->package.elements[i];
+		union acpi_object *connector_id = &obj->package.elements[0];
+		union acpi_object *info = &obj->package.elements[1];
+		DRM_DEBUG_DRIVER("Connector id: 0x%016llx\n",
+			  (unsigned long long)connector_id->integer.value);
+		DRM_DEBUG_DRIVER("  port id: %s\n",
+		       intel_dsm_port_name(info->buffer.pointer[0]));
+		DRM_DEBUG_DRIVER("  display mux info: %s\n",
+		       intel_dsm_mux_type(info->buffer.pointer[1]));
+		DRM_DEBUG_DRIVER("  aux/dc mux info: %s\n",
+		       intel_dsm_mux_type(info->buffer.pointer[2]));
+		DRM_DEBUG_DRIVER("  hpd mux info: %s\n",
+		       intel_dsm_mux_type(info->buffer.pointer[3]));
+	}
+
+	ACPI_FREE(pkg);
+}
+
+static bool intel_dsm_pci_probe(struct pci_dev *pdev)
+{
+	acpi_handle dhandle;
+
+	dhandle = ACPI_HANDLE(&pdev->dev);
+	if (!dhandle)
+		return false;
+
+	if (!acpi_check_dsm(dhandle, intel_dsm_guid, INTEL_DSM_REVISION_ID,
+			    1 << INTEL_DSM_FN_PLATFORM_MUX_INFO)) {
+		DRM_DEBUG_KMS("no _DSM method for intel device\n");
+		return false;
+	}
+
+	intel_dsm_priv.dhandle = dhandle;
+	intel_dsm_platform_mux_info();
+
+	return true;
+}
+
+static bool intel_dsm_detect(void)
+{
+	char acpi_method_name[255] = { 0 };
+	struct acpi_buffer buffer = {sizeof(acpi_method_name), acpi_method_name};
+	struct pci_dev *pdev = NULL;
+	bool has_dsm = false;
+	int vga_count = 0;
+
+	while ((pdev = pci_get_class(PCI_CLASS_DISPLAY_VGA << 8, pdev)) != NULL) {
+		vga_count++;
+		has_dsm |= intel_dsm_pci_probe(pdev);
+	}
+
+	if (vga_count == 2 && has_dsm) {
+		acpi_get_name(intel_dsm_priv.dhandle, ACPI_FULL_PATHNAME, &buffer);
+		DRM_DEBUG_DRIVER("vga_switcheroo: detected DSM switching method %s handle\n",
+				 acpi_method_name);
+		return true;
+	}
+
+	return false;
+}
+
+void intel_register_dsm_handler(void)
+{
+	if (!intel_dsm_detect())
+		return;
+}
+
+void intel_unregister_dsm_handler(void)
+{
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/i915/intel_atomic.c
@@ -0,0 +1,316 @@
+/*
+ * Copyright © 2015 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+ * DOC: atomic modeset support
+ *
+ * The functions here implement the state management and hardware programming
+ * dispatch required by the atomic modeset infrastructure.
+ * See intel_atomic_plane.c for the plane-specific atomic functionality.
+ */
+
+#include <drm/drmP.h>
+#include <drm/drm_atomic.h>
+#include <drm/drm_atomic_helper.h>
+#include <drm/drm_plane_helper.h>
+#include "intel_drv.h"
+
+/**
+ * intel_connector_atomic_get_property - fetch connector property value
+ * @connector: connector to fetch property for
+ * @state: state containing the property value
+ * @property: property to look up
+ * @val: pointer to write property value into
+ *
+ * The DRM core does not store shadow copies of properties for
+ * atomic-capable drivers.  This entrypoint is used to fetch
+ * the current value of a driver-specific connector property.
+ */
+int
+intel_connector_atomic_get_property(struct drm_connector *connector,
+				    const struct drm_connector_state *state,
+				    struct drm_property *property,
+				    uint64_t *val)
+{
+	int i;
+
+	/*
+	 * TODO: We only have atomic modeset for planes at the moment, so the
+	 * crtc/connector code isn't quite ready yet.  Until it's ready,
+	 * continue to look up all property values in the DRM's shadow copy
+	 * in obj->properties->values[].
+	 *
+	 * When the crtc/connector state work matures, this function should
+	 * be updated to read the values out of the state structure instead.
+	 */
+	for (i = 0; i < connector->base.properties->count; i++) {
+		if (connector->base.properties->properties[i] == property) {
+			*val = connector->base.properties->values[i];
+			return 0;
+		}
+	}
+
+	return -EINVAL;
+}
+
+/*
+ * intel_crtc_duplicate_state - duplicate crtc state
+ * @crtc: drm crtc
+ *
+ * Allocates and returns a copy of the crtc state (both common and
+ * Intel-specific) for the specified crtc.
+ *
+ * Returns: The newly allocated crtc state, or NULL on failure.
+ */
+struct drm_crtc_state *
+intel_crtc_duplicate_state(struct drm_crtc *crtc)
+{
+	struct intel_crtc_state *crtc_state;
+
+	crtc_state = kmemdup(crtc->state, sizeof(*crtc_state), GFP_KERNEL);
+	if (!crtc_state)
+		return NULL;
+
+	__drm_atomic_helper_crtc_duplicate_state(crtc, &crtc_state->base);
+
+	crtc_state->update_pipe = false;
+	crtc_state->disable_lp_wm = false;
+	crtc_state->disable_cxsr = false;
+	crtc_state->update_wm_pre = false;
+	crtc_state->update_wm_post = false;
+	crtc_state->fb_changed = false;
+	crtc_state->wm.need_postvbl_update = false;
+	crtc_state->fb_bits = 0;
+
+	return &crtc_state->base;
+}
+
+/**
+ * intel_crtc_destroy_state - destroy crtc state
+ * @crtc: drm crtc
+ *
+ * Destroys the crtc state (both common and Intel-specific) for the
+ * specified crtc.
+ */
+void
+intel_crtc_destroy_state(struct drm_crtc *crtc,
+			  struct drm_crtc_state *state)
+{
+	drm_atomic_helper_crtc_destroy_state(crtc, state);
+}
+
+/**
+ * intel_atomic_setup_scalers() - setup scalers for crtc per staged requests
+ * @dev: DRM device
+ * @crtc: intel crtc
+ * @crtc_state: incoming crtc_state to validate and setup scalers
+ *
+ * This function sets up scalers based on staged scaling requests for
+ * a @crtc and its planes. It is called from crtc level check path. If request
+ * is a supportable request, it attaches scalers to requested planes and crtc.
+ *
+ * This function takes into account the current scaler(s) in use by any planes
+ * not being part of this atomic state
+ *
+ *  Returns:
+ *         0 - scalers were setup succesfully
+ *         error code - otherwise
+ */
+int intel_atomic_setup_scalers(struct drm_device *dev,
+	struct intel_crtc *intel_crtc,
+	struct intel_crtc_state *crtc_state)
+{
+	struct drm_plane *plane = NULL;
+	struct intel_plane *intel_plane;
+	struct intel_plane_state *plane_state = NULL;
+	struct intel_crtc_scaler_state *scaler_state =
+		&crtc_state->scaler_state;
+	struct drm_atomic_state *drm_state = crtc_state->base.state;
+	int num_scalers_need;
+	int i, j;
+
+	num_scalers_need = hweight32(scaler_state->scaler_users);
+
+	/*
+	 * High level flow:
+	 * - staged scaler requests are already in scaler_state->scaler_users
+	 * - check whether staged scaling requests can be supported
+	 * - add planes using scalers that aren't in current transaction
+	 * - assign scalers to requested users
+	 * - as part of plane commit, scalers will be committed
+	 *   (i.e., either attached or detached) to respective planes in hw
+	 * - as part of crtc_commit, scaler will be either attached or detached
+	 *   to crtc in hw
+	 */
+
+	/* fail if required scalers > available scalers */
+	if (num_scalers_need > intel_crtc->num_scalers){
+		DRM_DEBUG_KMS("Too many scaling requests %d > %d\n",
+			num_scalers_need, intel_crtc->num_scalers);
+		return -EINVAL;
+	}
+
+	/* walkthrough scaler_users bits and start assigning scalers */
+	for (i = 0; i < sizeof(scaler_state->scaler_users) * 8; i++) {
+		int *scaler_id;
+		const char *name;
+		int idx;
+
+		/* skip if scaler not required */
+		if (!(scaler_state->scaler_users & (1 << i)))
+			continue;
+
+		if (i == SKL_CRTC_INDEX) {
+			name = "CRTC";
+			idx = intel_crtc->base.base.id;
+
+			/* panel fitter case: assign as a crtc scaler */
+			scaler_id = &scaler_state->scaler_id;
+		} else {
+			name = "PLANE";
+
+			/* plane scaler case: assign as a plane scaler */
+			/* find the plane that set the bit as scaler_user */
+			plane = drm_state->planes[i];
+
+			/*
+			 * to enable/disable hq mode, add planes that are using scaler
+			 * into this transaction
+			 */
+			if (!plane) {
+				struct drm_plane_state *state;
+				plane = drm_plane_from_index(dev, i);
+				state = drm_atomic_get_plane_state(drm_state, plane);
+				if (IS_ERR(state)) {
+					DRM_DEBUG_KMS("Failed to add [PLANE:%d] to drm_state\n",
+						plane->base.id);
+					return PTR_ERR(state);
+				}
+
+				/*
+				 * the plane is added after plane checks are run,
+				 * but since this plane is unchanged just do the
+				 * minimum required validation.
+				 */
+				crtc_state->base.planes_changed = true;
+			}
+
+			intel_plane = to_intel_plane(plane);
+			idx = plane->base.id;
+
+			/* plane on different crtc cannot be a scaler user of this crtc */
+			if (WARN_ON(intel_plane->pipe != intel_crtc->pipe)) {
+				continue;
+			}
+
+			plane_state = to_intel_plane_state(drm_state->plane_states[i]);
+			scaler_id = &plane_state->scaler_id;
+		}
+
+		if (*scaler_id < 0) {
+			/* find a free scaler */
+			for (j = 0; j < intel_crtc->num_scalers; j++) {
+				if (!scaler_state->scalers[j].in_use) {
+					scaler_state->scalers[j].in_use = 1;
+					*scaler_id = j;
+					DRM_DEBUG_KMS("Attached scaler id %u.%u to %s:%d\n",
+						intel_crtc->pipe, *scaler_id, name, idx);
+					break;
+				}
+			}
+		}
+
+		if (WARN_ON(*scaler_id < 0)) {
+			DRM_DEBUG_KMS("Cannot find scaler for %s:%d\n", name, idx);
+			continue;
+		}
+
+		/* set scaler mode */
+		if (num_scalers_need == 1 && intel_crtc->pipe != PIPE_C) {
+			/*
+			 * when only 1 scaler is in use on either pipe A or B,
+			 * scaler 0 operates in high quality (HQ) mode.
+			 * In this case use scaler 0 to take advantage of HQ mode
+			 */
+			*scaler_id = 0;
+			scaler_state->scalers[0].in_use = 1;
+			scaler_state->scalers[0].mode = PS_SCALER_MODE_HQ;
+			scaler_state->scalers[1].in_use = 0;
+		} else {
+			scaler_state->scalers[*scaler_id].mode = PS_SCALER_MODE_DYN;
+		}
+	}
+
+	return 0;
+}
+
+static void
+intel_atomic_duplicate_dpll_state(struct drm_i915_private *dev_priv,
+				  struct intel_shared_dpll_config *shared_dpll)
+{
+	enum intel_dpll_id i;
+
+	/* Copy shared dpll state */
+	for (i = 0; i < dev_priv->num_shared_dpll; i++) {
+		struct intel_shared_dpll *pll = &dev_priv->shared_dplls[i];
+
+		shared_dpll[i] = pll->config;
+	}
+}
+
+struct intel_shared_dpll_config *
+intel_atomic_get_shared_dpll_state(struct drm_atomic_state *s)
+{
+	struct intel_atomic_state *state = to_intel_atomic_state(s);
+
+	WARN_ON(!drm_modeset_is_locked(&s->dev->mode_config.connection_mutex));
+
+	if (!state->dpll_set) {
+		state->dpll_set = true;
+
+		intel_atomic_duplicate_dpll_state(to_i915(s->dev),
+						  state->shared_dpll);
+	}
+
+	return state->shared_dpll;
+}
+
+struct drm_atomic_state *
+intel_atomic_state_alloc(struct drm_device *dev)
+{
+	struct intel_atomic_state *state = kzalloc(sizeof(*state), GFP_KERNEL);
+
+	if (!state || drm_atomic_state_init(dev, &state->base) < 0) {
+		kfree(state);
+		return NULL;
+	}
+
+	return &state->base;
+}
+
+void intel_atomic_state_clear(struct drm_atomic_state *s)
+{
+	struct intel_atomic_state *state = to_intel_atomic_state(s);
+	drm_atomic_state_default_clear(&state->base);
+	state->dpll_set = state->modeset = false;
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/i915/intel_atomic_plane.c
@@ -0,0 +1,255 @@
+/*
+ * Copyright © 2014 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+ * DOC: atomic plane helpers
+ *
+ * The functions here are used by the atomic plane helper functions to
+ * implement legacy plane updates (i.e., drm_plane->update_plane() and
+ * drm_plane->disable_plane()).  This allows plane updates to use the
+ * atomic state infrastructure and perform plane updates as separate
+ * prepare/check/commit/cleanup steps.
+ */
+
+#include <drm/drmP.h>
+#include <drm/drm_atomic_helper.h>
+#include <drm/drm_plane_helper.h>
+#include "intel_drv.h"
+
+/**
+ * intel_create_plane_state - create plane state object
+ * @plane: drm plane
+ *
+ * Allocates a fresh plane state for the given plane and sets some of
+ * the state values to sensible initial values.
+ *
+ * Returns: A newly allocated plane state, or NULL on failure
+ */
+struct intel_plane_state *
+intel_create_plane_state(struct drm_plane *plane)
+{
+	struct intel_plane_state *state;
+
+	state = kzalloc(sizeof(*state), GFP_KERNEL);
+	if (!state)
+		return NULL;
+
+	state->base.plane = plane;
+	state->base.rotation = BIT(DRM_ROTATE_0);
+	state->ckey.flags = I915_SET_COLORKEY_NONE;
+
+	return state;
+}
+
+/**
+ * intel_plane_duplicate_state - duplicate plane state
+ * @plane: drm plane
+ *
+ * Allocates and returns a copy of the plane state (both common and
+ * Intel-specific) for the specified plane.
+ *
+ * Returns: The newly allocated plane state, or NULL on failure.
+ */
+struct drm_plane_state *
+intel_plane_duplicate_state(struct drm_plane *plane)
+{
+	struct drm_plane_state *state;
+	struct intel_plane_state *intel_state;
+
+	intel_state = kmemdup(plane->state, sizeof(*intel_state), GFP_KERNEL);
+
+	if (!intel_state)
+		return NULL;
+
+	state = &intel_state->base;
+
+	__drm_atomic_helper_plane_duplicate_state(plane, state);
+	intel_state->wait_req = NULL;
+
+	return state;
+}
+
+/**
+ * intel_plane_destroy_state - destroy plane state
+ * @plane: drm plane
+ * @state: state object to destroy
+ *
+ * Destroys the plane state (both common and Intel-specific) for the
+ * specified plane.
+ */
+void
+intel_plane_destroy_state(struct drm_plane *plane,
+			  struct drm_plane_state *state)
+{
+	WARN_ON(state && to_intel_plane_state(state)->wait_req);
+	drm_atomic_helper_plane_destroy_state(plane, state);
+}
+
+static int intel_plane_atomic_check(struct drm_plane *plane,
+				    struct drm_plane_state *state)
+{
+	struct drm_crtc *crtc = state->crtc;
+	struct intel_crtc *intel_crtc;
+	struct intel_crtc_state *crtc_state;
+	struct intel_plane *intel_plane = to_intel_plane(plane);
+	struct intel_plane_state *intel_state = to_intel_plane_state(state);
+	struct drm_crtc_state *drm_crtc_state;
+	int ret;
+
+	crtc = crtc ? crtc : plane->state->crtc;
+	intel_crtc = to_intel_crtc(crtc);
+
+	/*
+	 * Both crtc and plane->crtc could be NULL if we're updating a
+	 * property while the plane is disabled.  We don't actually have
+	 * anything driver-specific we need to test in that case, so
+	 * just return success.
+	 */
+	if (!crtc)
+		return 0;
+
+	drm_crtc_state = drm_atomic_get_existing_crtc_state(state->state, crtc);
+	if (WARN_ON(!drm_crtc_state))
+		return -EINVAL;
+
+	crtc_state = to_intel_crtc_state(drm_crtc_state);
+
+	/*
+	 * The original src/dest coordinates are stored in state->base, but
+	 * we want to keep another copy internal to our driver that we can
+	 * clip/modify ourselves.
+	 */
+	intel_state->src.x1 = state->src_x;
+	intel_state->src.y1 = state->src_y;
+	intel_state->src.x2 = state->src_x + state->src_w;
+	intel_state->src.y2 = state->src_y + state->src_h;
+	intel_state->dst.x1 = state->crtc_x;
+	intel_state->dst.y1 = state->crtc_y;
+	intel_state->dst.x2 = state->crtc_x + state->crtc_w;
+	intel_state->dst.y2 = state->crtc_y + state->crtc_h;
+
+	/* Clip all planes to CRTC size, or 0x0 if CRTC is disabled */
+	intel_state->clip.x1 = 0;
+	intel_state->clip.y1 = 0;
+	intel_state->clip.x2 =
+		crtc_state->base.enable ? crtc_state->pipe_src_w : 0;
+	intel_state->clip.y2 =
+		crtc_state->base.enable ? crtc_state->pipe_src_h : 0;
+
+	if (state->fb && intel_rotation_90_or_270(state->rotation)) {
+		if (!(state->fb->modifier[0] == I915_FORMAT_MOD_Y_TILED ||
+			state->fb->modifier[0] == I915_FORMAT_MOD_Yf_TILED)) {
+			DRM_DEBUG_KMS("Y/Yf tiling required for 90/270!\n");
+			return -EINVAL;
+		}
+
+		/*
+		 * 90/270 is not allowed with RGB64 16:16:16:16,
+		 * RGB 16-bit 5:6:5, and Indexed 8-bit.
+		 * TBD: Add RGB64 case once its added in supported format list.
+		 */
+		switch (state->fb->pixel_format) {
+		case DRM_FORMAT_C8:
+		case DRM_FORMAT_RGB565:
+			DRM_DEBUG_KMS("Unsupported pixel format %s for 90/270!\n",
+					drm_get_format_name(state->fb->pixel_format));
+			return -EINVAL;
+
+		default:
+			break;
+		}
+	}
+
+	intel_state->visible = false;
+	ret = intel_plane->check_plane(plane, crtc_state, intel_state);
+	if (ret)
+		return ret;
+
+	return intel_plane_atomic_calc_changes(&crtc_state->base, state);
+}
+
+static void intel_plane_atomic_update(struct drm_plane *plane,
+				      struct drm_plane_state *old_state)
+{
+	struct intel_plane *intel_plane = to_intel_plane(plane);
+	struct intel_plane_state *intel_state =
+		to_intel_plane_state(plane->state);
+	struct drm_crtc *crtc = plane->state->crtc ?: old_state->crtc;
+
+	if (intel_state->visible)
+		intel_plane->update_plane(plane,
+					  to_intel_crtc_state(crtc->state),
+					  intel_state);
+	else
+		intel_plane->disable_plane(plane, crtc);
+}
+
+const struct drm_plane_helper_funcs intel_plane_helper_funcs = {
+	.prepare_fb = intel_prepare_plane_fb,
+	.cleanup_fb = intel_cleanup_plane_fb,
+	.atomic_check = intel_plane_atomic_check,
+	.atomic_update = intel_plane_atomic_update,
+};
+
+/**
+ * intel_plane_atomic_get_property - fetch plane property value
+ * @plane: plane to fetch property for
+ * @state: state containing the property value
+ * @property: property to look up
+ * @val: pointer to write property value into
+ *
+ * The DRM core does not store shadow copies of properties for
+ * atomic-capable drivers.  This entrypoint is used to fetch
+ * the current value of a driver-specific plane property.
+ */
+int
+intel_plane_atomic_get_property(struct drm_plane *plane,
+				const struct drm_plane_state *state,
+				struct drm_property *property,
+				uint64_t *val)
+{
+	DRM_DEBUG_KMS("Unknown plane property '%s'\n", property->name);
+	return -EINVAL;
+}
+
+/**
+ * intel_plane_atomic_set_property - set plane property value
+ * @plane: plane to set property for
+ * @state: state to update property value in
+ * @property: property to set
+ * @val: value to set property to
+ *
+ * Writes the specified property value for a plane into the provided atomic
+ * state object.
+ *
+ * Returns 0 on success, -EINVAL on unrecognized properties
+ */
+int
+intel_plane_atomic_set_property(struct drm_plane *plane,
+				struct drm_plane_state *state,
+				struct drm_property *property,
+				uint64_t val)
+{
+	DRM_DEBUG_KMS("Unknown plane property '%s'\n", property->name);
+	return -EINVAL;
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/i915/intel_audio.c
@@ -0,0 +1,832 @@
+/*
+ * Copyright © 2014 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#include <linux/kernel.h>
+#include <linux/component.h>
+#include <drm/i915_component.h>
+#include "intel_drv.h"
+
+#include <drm/drmP.h>
+#include <drm/drm_edid.h>
+#include "i915_drv.h"
+
+/**
+ * DOC: High Definition Audio over HDMI and Display Port
+ *
+ * The graphics and audio drivers together support High Definition Audio over
+ * HDMI and Display Port. The audio programming sequences are divided into audio
+ * codec and controller enable and disable sequences. The graphics driver
+ * handles the audio codec sequences, while the audio driver handles the audio
+ * controller sequences.
+ *
+ * The disable sequences must be performed before disabling the transcoder or
+ * port. The enable sequences may only be performed after enabling the
+ * transcoder and port, and after completed link training. Therefore the audio
+ * enable/disable sequences are part of the modeset sequence.
+ *
+ * The codec and controller sequences could be done either parallel or serial,
+ * but generally the ELDV/PD change in the codec sequence indicates to the audio
+ * driver that the controller sequence should start. Indeed, most of the
+ * co-operation between the graphics and audio drivers is handled via audio
+ * related registers. (The notable exception is the power management, not
+ * covered here.)
+ *
+ * The struct i915_audio_component is used to interact between the graphics
+ * and audio drivers. The struct i915_audio_component_ops *ops in it is
+ * defined in graphics driver and called in audio driver. The
+ * struct i915_audio_component_audio_ops *audio_ops is called from i915 driver.
+ */
+
+static const struct {
+	int clock;
+	u32 config;
+} hdmi_audio_clock[] = {
+	{ 25175, AUD_CONFIG_PIXEL_CLOCK_HDMI_25175 },
+	{ 25200, AUD_CONFIG_PIXEL_CLOCK_HDMI_25200 }, /* default per bspec */
+	{ 27000, AUD_CONFIG_PIXEL_CLOCK_HDMI_27000 },
+	{ 27027, AUD_CONFIG_PIXEL_CLOCK_HDMI_27027 },
+	{ 54000, AUD_CONFIG_PIXEL_CLOCK_HDMI_54000 },
+	{ 54054, AUD_CONFIG_PIXEL_CLOCK_HDMI_54054 },
+	{ 74176, AUD_CONFIG_PIXEL_CLOCK_HDMI_74176 },
+	{ 74250, AUD_CONFIG_PIXEL_CLOCK_HDMI_74250 },
+	{ 148352, AUD_CONFIG_PIXEL_CLOCK_HDMI_148352 },
+	{ 148500, AUD_CONFIG_PIXEL_CLOCK_HDMI_148500 },
+};
+
+/* HDMI N/CTS table */
+#define TMDS_297M 297000
+#define TMDS_296M 296703
+static const struct {
+	int sample_rate;
+	int clock;
+	int n;
+	int cts;
+} aud_ncts[] = {
+	{ 44100, TMDS_296M, 4459, 234375 },
+	{ 44100, TMDS_297M, 4704, 247500 },
+	{ 48000, TMDS_296M, 5824, 281250 },
+	{ 48000, TMDS_297M, 5120, 247500 },
+	{ 32000, TMDS_296M, 5824, 421875 },
+	{ 32000, TMDS_297M, 3072, 222750 },
+	{ 88200, TMDS_296M, 8918, 234375 },
+	{ 88200, TMDS_297M, 9408, 247500 },
+	{ 96000, TMDS_296M, 11648, 281250 },
+	{ 96000, TMDS_297M, 10240, 247500 },
+	{ 176400, TMDS_296M, 17836, 234375 },
+	{ 176400, TMDS_297M, 18816, 247500 },
+	{ 192000, TMDS_296M, 23296, 281250 },
+	{ 192000, TMDS_297M, 20480, 247500 },
+};
+
+/* get AUD_CONFIG_PIXEL_CLOCK_HDMI_* value for mode */
+static u32 audio_config_hdmi_pixel_clock(const struct drm_display_mode *adjusted_mode)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(hdmi_audio_clock); i++) {
+		if (adjusted_mode->crtc_clock == hdmi_audio_clock[i].clock)
+			break;
+	}
+
+	if (i == ARRAY_SIZE(hdmi_audio_clock)) {
+		DRM_DEBUG_KMS("HDMI audio pixel clock setting for %d not found, falling back to defaults\n",
+			      adjusted_mode->crtc_clock);
+		i = 1;
+	}
+
+	DRM_DEBUG_KMS("Configuring HDMI audio for pixel clock %d (0x%08x)\n",
+		      hdmi_audio_clock[i].clock,
+		      hdmi_audio_clock[i].config);
+
+	return hdmi_audio_clock[i].config;
+}
+
+static int audio_config_get_n(const struct drm_display_mode *mode, int rate)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(aud_ncts); i++) {
+		if ((rate == aud_ncts[i].sample_rate) &&
+			(mode->clock == aud_ncts[i].clock)) {
+			return aud_ncts[i].n;
+		}
+	}
+	return 0;
+}
+
+static uint32_t audio_config_setup_n_reg(int n, uint32_t val)
+{
+	int n_low, n_up;
+	uint32_t tmp = val;
+
+	n_low = n & 0xfff;
+	n_up = (n >> 12) & 0xff;
+	tmp &= ~(AUD_CONFIG_UPPER_N_MASK | AUD_CONFIG_LOWER_N_MASK);
+	tmp |= ((n_up << AUD_CONFIG_UPPER_N_SHIFT) |
+			(n_low << AUD_CONFIG_LOWER_N_SHIFT) |
+			AUD_CONFIG_N_PROG_ENABLE);
+	return tmp;
+}
+
+/* check whether N/CTS/M need be set manually */
+static bool audio_rate_need_prog(struct intel_crtc *crtc,
+				 const struct drm_display_mode *mode)
+{
+	if (((mode->clock == TMDS_297M) ||
+		 (mode->clock == TMDS_296M)) &&
+		intel_pipe_has_type(crtc, INTEL_OUTPUT_HDMI))
+		return true;
+	else
+		return false;
+}
+
+static bool intel_eld_uptodate(struct drm_connector *connector,
+			       i915_reg_t reg_eldv, uint32_t bits_eldv,
+			       i915_reg_t reg_elda, uint32_t bits_elda,
+			       i915_reg_t reg_edid)
+{
+	struct drm_i915_private *dev_priv = connector->dev->dev_private;
+	uint8_t *eld = connector->eld;
+	uint32_t tmp;
+	int i;
+
+	tmp = I915_READ(reg_eldv);
+	tmp &= bits_eldv;
+
+	if (!tmp)
+		return false;
+
+	tmp = I915_READ(reg_elda);
+	tmp &= ~bits_elda;
+	I915_WRITE(reg_elda, tmp);
+
+	for (i = 0; i < drm_eld_size(eld) / 4; i++)
+		if (I915_READ(reg_edid) != *((uint32_t *)eld + i))
+			return false;
+
+	return true;
+}
+
+static void g4x_audio_codec_disable(struct intel_encoder *encoder)
+{
+	struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
+	uint32_t eldv, tmp;
+
+	DRM_DEBUG_KMS("Disable audio codec\n");
+
+	tmp = I915_READ(G4X_AUD_VID_DID);
+	if (tmp == INTEL_AUDIO_DEVBLC || tmp == INTEL_AUDIO_DEVCL)
+		eldv = G4X_ELDV_DEVCL_DEVBLC;
+	else
+		eldv = G4X_ELDV_DEVCTG;
+
+	/* Invalidate ELD */
+	tmp = I915_READ(G4X_AUD_CNTL_ST);
+	tmp &= ~eldv;
+	I915_WRITE(G4X_AUD_CNTL_ST, tmp);
+}
+
+static void g4x_audio_codec_enable(struct drm_connector *connector,
+				   struct intel_encoder *encoder,
+				   const struct drm_display_mode *adjusted_mode)
+{
+	struct drm_i915_private *dev_priv = connector->dev->dev_private;
+	uint8_t *eld = connector->eld;
+	uint32_t eldv;
+	uint32_t tmp;
+	int len, i;
+
+	DRM_DEBUG_KMS("Enable audio codec, %u bytes ELD\n", eld[2]);
+
+	tmp = I915_READ(G4X_AUD_VID_DID);
+	if (tmp == INTEL_AUDIO_DEVBLC || tmp == INTEL_AUDIO_DEVCL)
+		eldv = G4X_ELDV_DEVCL_DEVBLC;
+	else
+		eldv = G4X_ELDV_DEVCTG;
+
+	if (intel_eld_uptodate(connector,
+			       G4X_AUD_CNTL_ST, eldv,
+			       G4X_AUD_CNTL_ST, G4X_ELD_ADDR_MASK,
+			       G4X_HDMIW_HDMIEDID))
+		return;
+
+	tmp = I915_READ(G4X_AUD_CNTL_ST);
+	tmp &= ~(eldv | G4X_ELD_ADDR_MASK);
+	len = (tmp >> 9) & 0x1f;		/* ELD buffer size */
+	I915_WRITE(G4X_AUD_CNTL_ST, tmp);
+
+	len = min(drm_eld_size(eld) / 4, len);
+	DRM_DEBUG_DRIVER("ELD size %d\n", len);
+	for (i = 0; i < len; i++)
+		I915_WRITE(G4X_HDMIW_HDMIEDID, *((uint32_t *)eld + i));
+
+	tmp = I915_READ(G4X_AUD_CNTL_ST);
+	tmp |= eldv;
+	I915_WRITE(G4X_AUD_CNTL_ST, tmp);
+}
+
+static void hsw_audio_codec_disable(struct intel_encoder *encoder)
+{
+	struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
+	struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc);
+	enum pipe pipe = intel_crtc->pipe;
+	uint32_t tmp;
+
+	DRM_DEBUG_KMS("Disable audio codec on pipe %c\n", pipe_name(pipe));
+
+	mutex_lock(&dev_priv->av_mutex);
+
+	/* Disable timestamps */
+	tmp = I915_READ(HSW_AUD_CFG(pipe));
+	tmp &= ~AUD_CONFIG_N_VALUE_INDEX;
+	tmp |= AUD_CONFIG_N_PROG_ENABLE;
+	tmp &= ~AUD_CONFIG_UPPER_N_MASK;
+	tmp &= ~AUD_CONFIG_LOWER_N_MASK;
+	if (intel_pipe_has_type(intel_crtc, INTEL_OUTPUT_DISPLAYPORT))
+		tmp |= AUD_CONFIG_N_VALUE_INDEX;
+	I915_WRITE(HSW_AUD_CFG(pipe), tmp);
+
+	/* Invalidate ELD */
+	tmp = I915_READ(HSW_AUD_PIN_ELD_CP_VLD);
+	tmp &= ~AUDIO_ELD_VALID(pipe);
+	tmp &= ~AUDIO_OUTPUT_ENABLE(pipe);
+	I915_WRITE(HSW_AUD_PIN_ELD_CP_VLD, tmp);
+
+	mutex_unlock(&dev_priv->av_mutex);
+}
+
+static void hsw_audio_codec_enable(struct drm_connector *connector,
+				   struct intel_encoder *encoder,
+				   const struct drm_display_mode *adjusted_mode)
+{
+	struct drm_i915_private *dev_priv = connector->dev->dev_private;
+	struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc);
+	enum pipe pipe = intel_crtc->pipe;
+	struct i915_audio_component *acomp = dev_priv->audio_component;
+	const uint8_t *eld = connector->eld;
+	struct intel_digital_port *intel_dig_port =
+		enc_to_dig_port(&encoder->base);
+	enum port port = intel_dig_port->port;
+	uint32_t tmp;
+	int len, i;
+	int n, rate;
+
+	DRM_DEBUG_KMS("Enable audio codec on pipe %c, %u bytes ELD\n",
+		      pipe_name(pipe), drm_eld_size(eld));
+
+	mutex_lock(&dev_priv->av_mutex);
+
+	/* Enable audio presence detect, invalidate ELD */
+	tmp = I915_READ(HSW_AUD_PIN_ELD_CP_VLD);
+	tmp |= AUDIO_OUTPUT_ENABLE(pipe);
+	tmp &= ~AUDIO_ELD_VALID(pipe);
+	I915_WRITE(HSW_AUD_PIN_ELD_CP_VLD, tmp);
+
+	/*
+	 * FIXME: We're supposed to wait for vblank here, but we have vblanks
+	 * disabled during the mode set. The proper fix would be to push the
+	 * rest of the setup into a vblank work item, queued here, but the
+	 * infrastructure is not there yet.
+	 */
+
+	/* Reset ELD write address */
+	tmp = I915_READ(HSW_AUD_DIP_ELD_CTRL(pipe));
+	tmp &= ~IBX_ELD_ADDRESS_MASK;
+	I915_WRITE(HSW_AUD_DIP_ELD_CTRL(pipe), tmp);
+
+	/* Up to 84 bytes of hw ELD buffer */
+	len = min(drm_eld_size(eld), 84);
+	for (i = 0; i < len / 4; i++)
+		I915_WRITE(HSW_AUD_EDID_DATA(pipe), *((uint32_t *)eld + i));
+
+	/* ELD valid */
+	tmp = I915_READ(HSW_AUD_PIN_ELD_CP_VLD);
+	tmp |= AUDIO_ELD_VALID(pipe);
+	I915_WRITE(HSW_AUD_PIN_ELD_CP_VLD, tmp);
+
+	/* Enable timestamps */
+	tmp = I915_READ(HSW_AUD_CFG(pipe));
+	tmp &= ~AUD_CONFIG_N_VALUE_INDEX;
+	tmp &= ~AUD_CONFIG_PIXEL_CLOCK_HDMI_MASK;
+	if (intel_pipe_has_type(intel_crtc, INTEL_OUTPUT_DISPLAYPORT))
+		tmp |= AUD_CONFIG_N_VALUE_INDEX;
+	else
+		tmp |= audio_config_hdmi_pixel_clock(adjusted_mode);
+
+	tmp &= ~AUD_CONFIG_N_PROG_ENABLE;
+	if (audio_rate_need_prog(intel_crtc, adjusted_mode)) {
+		if (!acomp)
+			rate = 0;
+		else if (port >= PORT_A && port <= PORT_E)
+			rate = acomp->aud_sample_rate[port];
+		else {
+			DRM_ERROR("invalid port: %d\n", port);
+			rate = 0;
+		}
+		n = audio_config_get_n(adjusted_mode, rate);
+		if (n != 0)
+			tmp = audio_config_setup_n_reg(n, tmp);
+		else
+			DRM_DEBUG_KMS("no suitable N value is found\n");
+	}
+
+	I915_WRITE(HSW_AUD_CFG(pipe), tmp);
+
+	mutex_unlock(&dev_priv->av_mutex);
+}
+
+static void ilk_audio_codec_disable(struct intel_encoder *encoder)
+{
+	struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
+	struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc);
+	struct intel_digital_port *intel_dig_port =
+		enc_to_dig_port(&encoder->base);
+	enum port port = intel_dig_port->port;
+	enum pipe pipe = intel_crtc->pipe;
+	uint32_t tmp, eldv;
+	i915_reg_t aud_config, aud_cntrl_st2;
+
+	DRM_DEBUG_KMS("Disable audio codec on port %c, pipe %c\n",
+		      port_name(port), pipe_name(pipe));
+
+	if (WARN_ON(port == PORT_A))
+		return;
+
+	if (HAS_PCH_IBX(dev_priv)) {
+		aud_config = IBX_AUD_CFG(pipe);
+		aud_cntrl_st2 = IBX_AUD_CNTL_ST2;
+	} else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
+		aud_config = VLV_AUD_CFG(pipe);
+		aud_cntrl_st2 = VLV_AUD_CNTL_ST2;
+	} else {
+		aud_config = CPT_AUD_CFG(pipe);
+		aud_cntrl_st2 = CPT_AUD_CNTRL_ST2;
+	}
+
+	/* Disable timestamps */
+	tmp = I915_READ(aud_config);
+	tmp &= ~AUD_CONFIG_N_VALUE_INDEX;
+	tmp |= AUD_CONFIG_N_PROG_ENABLE;
+	tmp &= ~AUD_CONFIG_UPPER_N_MASK;
+	tmp &= ~AUD_CONFIG_LOWER_N_MASK;
+	if (intel_pipe_has_type(intel_crtc, INTEL_OUTPUT_DISPLAYPORT))
+		tmp |= AUD_CONFIG_N_VALUE_INDEX;
+	I915_WRITE(aud_config, tmp);
+
+	eldv = IBX_ELD_VALID(port);
+
+	/* Invalidate ELD */
+	tmp = I915_READ(aud_cntrl_st2);
+	tmp &= ~eldv;
+	I915_WRITE(aud_cntrl_st2, tmp);
+}
+
+static void ilk_audio_codec_enable(struct drm_connector *connector,
+				   struct intel_encoder *encoder,
+				   const struct drm_display_mode *adjusted_mode)
+{
+	struct drm_i915_private *dev_priv = connector->dev->dev_private;
+	struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc);
+	struct intel_digital_port *intel_dig_port =
+		enc_to_dig_port(&encoder->base);
+	enum port port = intel_dig_port->port;
+	enum pipe pipe = intel_crtc->pipe;
+	uint8_t *eld = connector->eld;
+	uint32_t eldv;
+	uint32_t tmp;
+	int len, i;
+	i915_reg_t hdmiw_hdmiedid, aud_config, aud_cntl_st, aud_cntrl_st2;
+
+	DRM_DEBUG_KMS("Enable audio codec on port %c, pipe %c, %u bytes ELD\n",
+		      port_name(port), pipe_name(pipe), drm_eld_size(eld));
+
+	if (WARN_ON(port == PORT_A))
+		return;
+
+	/*
+	 * FIXME: We're supposed to wait for vblank here, but we have vblanks
+	 * disabled during the mode set. The proper fix would be to push the
+	 * rest of the setup into a vblank work item, queued here, but the
+	 * infrastructure is not there yet.
+	 */
+
+	if (HAS_PCH_IBX(connector->dev)) {
+		hdmiw_hdmiedid = IBX_HDMIW_HDMIEDID(pipe);
+		aud_config = IBX_AUD_CFG(pipe);
+		aud_cntl_st = IBX_AUD_CNTL_ST(pipe);
+		aud_cntrl_st2 = IBX_AUD_CNTL_ST2;
+	} else if (IS_VALLEYVIEW(connector->dev) ||
+		   IS_CHERRYVIEW(connector->dev)) {
+		hdmiw_hdmiedid = VLV_HDMIW_HDMIEDID(pipe);
+		aud_config = VLV_AUD_CFG(pipe);
+		aud_cntl_st = VLV_AUD_CNTL_ST(pipe);
+		aud_cntrl_st2 = VLV_AUD_CNTL_ST2;
+	} else {
+		hdmiw_hdmiedid = CPT_HDMIW_HDMIEDID(pipe);
+		aud_config = CPT_AUD_CFG(pipe);
+		aud_cntl_st = CPT_AUD_CNTL_ST(pipe);
+		aud_cntrl_st2 = CPT_AUD_CNTRL_ST2;
+	}
+
+	eldv = IBX_ELD_VALID(port);
+
+	/* Invalidate ELD */
+	tmp = I915_READ(aud_cntrl_st2);
+	tmp &= ~eldv;
+	I915_WRITE(aud_cntrl_st2, tmp);
+
+	/* Reset ELD write address */
+	tmp = I915_READ(aud_cntl_st);
+	tmp &= ~IBX_ELD_ADDRESS_MASK;
+	I915_WRITE(aud_cntl_st, tmp);
+
+	/* Up to 84 bytes of hw ELD buffer */
+	len = min(drm_eld_size(eld), 84);
+	for (i = 0; i < len / 4; i++)
+		I915_WRITE(hdmiw_hdmiedid, *((uint32_t *)eld + i));
+
+	/* ELD valid */
+	tmp = I915_READ(aud_cntrl_st2);
+	tmp |= eldv;
+	I915_WRITE(aud_cntrl_st2, tmp);
+
+	/* Enable timestamps */
+	tmp = I915_READ(aud_config);
+	tmp &= ~AUD_CONFIG_N_VALUE_INDEX;
+	tmp &= ~AUD_CONFIG_N_PROG_ENABLE;
+	tmp &= ~AUD_CONFIG_PIXEL_CLOCK_HDMI_MASK;
+	if (intel_pipe_has_type(intel_crtc, INTEL_OUTPUT_DISPLAYPORT))
+		tmp |= AUD_CONFIG_N_VALUE_INDEX;
+	else
+		tmp |= audio_config_hdmi_pixel_clock(adjusted_mode);
+	I915_WRITE(aud_config, tmp);
+}
+
+/**
+ * intel_audio_codec_enable - Enable the audio codec for HD audio
+ * @intel_encoder: encoder on which to enable audio
+ *
+ * The enable sequences may only be performed after enabling the transcoder and
+ * port, and after completed link training.
+ */
+void intel_audio_codec_enable(struct intel_encoder *intel_encoder)
+{
+	struct drm_encoder *encoder = &intel_encoder->base;
+	struct intel_crtc *crtc = to_intel_crtc(encoder->crtc);
+	const struct drm_display_mode *adjusted_mode = &crtc->config->base.adjusted_mode;
+	struct drm_connector *connector;
+	struct drm_device *dev = encoder->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct i915_audio_component *acomp = dev_priv->audio_component;
+	struct intel_digital_port *intel_dig_port = enc_to_dig_port(encoder);
+	enum port port = intel_dig_port->port;
+
+	connector = drm_select_eld(encoder);
+	if (!connector)
+		return;
+
+	DRM_DEBUG_DRIVER("ELD on [CONNECTOR:%d:%s], [ENCODER:%d:%s]\n",
+			 connector->base.id,
+			 connector->name,
+			 connector->encoder->base.id,
+			 connector->encoder->name);
+
+	/* ELD Conn_Type */
+	connector->eld[5] &= ~(3 << 2);
+	if (intel_pipe_has_type(crtc, INTEL_OUTPUT_DISPLAYPORT))
+		connector->eld[5] |= (1 << 2);
+
+	connector->eld[6] = drm_av_sync_delay(connector, adjusted_mode) / 2;
+
+	if (dev_priv->display.audio_codec_enable)
+		dev_priv->display.audio_codec_enable(connector, intel_encoder,
+						     adjusted_mode);
+
+	mutex_lock(&dev_priv->av_mutex);
+	intel_dig_port->audio_connector = connector;
+	/* referred in audio callbacks */
+	dev_priv->dig_port_map[port] = intel_encoder;
+	mutex_unlock(&dev_priv->av_mutex);
+
+	if (acomp && acomp->audio_ops && acomp->audio_ops->pin_eld_notify)
+		acomp->audio_ops->pin_eld_notify(acomp->audio_ops->audio_ptr, (int) port);
+}
+
+/**
+ * intel_audio_codec_disable - Disable the audio codec for HD audio
+ * @intel_encoder: encoder on which to disable audio
+ *
+ * The disable sequences must be performed before disabling the transcoder or
+ * port.
+ */
+void intel_audio_codec_disable(struct intel_encoder *intel_encoder)
+{
+	struct drm_encoder *encoder = &intel_encoder->base;
+	struct drm_device *dev = encoder->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct i915_audio_component *acomp = dev_priv->audio_component;
+	struct intel_digital_port *intel_dig_port = enc_to_dig_port(encoder);
+	enum port port = intel_dig_port->port;
+
+	if (dev_priv->display.audio_codec_disable)
+		dev_priv->display.audio_codec_disable(intel_encoder);
+
+	mutex_lock(&dev_priv->av_mutex);
+	intel_dig_port->audio_connector = NULL;
+	dev_priv->dig_port_map[port] = NULL;
+	mutex_unlock(&dev_priv->av_mutex);
+
+	if (acomp && acomp->audio_ops && acomp->audio_ops->pin_eld_notify)
+		acomp->audio_ops->pin_eld_notify(acomp->audio_ops->audio_ptr, (int) port);
+}
+
+/**
+ * intel_init_audio_hooks - Set up chip specific audio hooks
+ * @dev_priv: device private
+ */
+void intel_init_audio_hooks(struct drm_i915_private *dev_priv)
+{
+	if (IS_G4X(dev_priv)) {
+		dev_priv->display.audio_codec_enable = g4x_audio_codec_enable;
+		dev_priv->display.audio_codec_disable = g4x_audio_codec_disable;
+	} else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
+		dev_priv->display.audio_codec_enable = ilk_audio_codec_enable;
+		dev_priv->display.audio_codec_disable = ilk_audio_codec_disable;
+	} else if (IS_HASWELL(dev_priv) || INTEL_INFO(dev_priv)->gen >= 8) {
+		dev_priv->display.audio_codec_enable = hsw_audio_codec_enable;
+		dev_priv->display.audio_codec_disable = hsw_audio_codec_disable;
+	} else if (HAS_PCH_SPLIT(dev_priv)) {
+		dev_priv->display.audio_codec_enable = ilk_audio_codec_enable;
+		dev_priv->display.audio_codec_disable = ilk_audio_codec_disable;
+	}
+}
+
+static void i915_audio_component_get_power(struct device *dev)
+{
+	intel_display_power_get(dev_to_i915(dev), POWER_DOMAIN_AUDIO);
+}
+
+static void i915_audio_component_put_power(struct device *dev)
+{
+	intel_display_power_put(dev_to_i915(dev), POWER_DOMAIN_AUDIO);
+}
+
+static void i915_audio_component_codec_wake_override(struct device *dev,
+						     bool enable)
+{
+	struct drm_i915_private *dev_priv = dev_to_i915(dev);
+	u32 tmp;
+
+	if (!IS_SKYLAKE(dev_priv) && !IS_KABYLAKE(dev_priv))
+		return;
+
+	/*
+	 * Enable/disable generating the codec wake signal, overriding the
+	 * internal logic to generate the codec wake to controller.
+	 */
+	tmp = I915_READ(HSW_AUD_CHICKENBIT);
+	tmp &= ~SKL_AUD_CODEC_WAKE_SIGNAL;
+	I915_WRITE(HSW_AUD_CHICKENBIT, tmp);
+	usleep_range(1000, 1500);
+
+	if (enable) {
+		tmp = I915_READ(HSW_AUD_CHICKENBIT);
+		tmp |= SKL_AUD_CODEC_WAKE_SIGNAL;
+		I915_WRITE(HSW_AUD_CHICKENBIT, tmp);
+		usleep_range(1000, 1500);
+	}
+}
+
+/* Get CDCLK in kHz  */
+static int i915_audio_component_get_cdclk_freq(struct device *dev)
+{
+	struct drm_i915_private *dev_priv = dev_to_i915(dev);
+	int ret;
+
+	if (WARN_ON_ONCE(!HAS_DDI(dev_priv)))
+		return -ENODEV;
+
+	intel_display_power_get(dev_priv, POWER_DOMAIN_AUDIO);
+	ret = dev_priv->display.get_display_clock_speed(dev_priv->dev);
+
+	intel_display_power_put(dev_priv, POWER_DOMAIN_AUDIO);
+
+	return ret;
+}
+
+static int i915_audio_component_sync_audio_rate(struct device *dev,
+						int port, int rate)
+{
+	struct drm_i915_private *dev_priv = dev_to_i915(dev);
+	struct intel_encoder *intel_encoder;
+	struct intel_crtc *crtc;
+	struct drm_display_mode *mode;
+	struct i915_audio_component *acomp = dev_priv->audio_component;
+	enum pipe pipe = INVALID_PIPE;
+	u32 tmp;
+	int n;
+	int err = 0;
+
+	/* HSW, BDW, SKL, KBL need this fix */
+	if (!IS_SKYLAKE(dev_priv) &&
+	    !IS_KABYLAKE(dev_priv) &&
+	    !IS_BROADWELL(dev_priv) &&
+	    !IS_HASWELL(dev_priv))
+		return 0;
+
+	mutex_lock(&dev_priv->av_mutex);
+	/* 1. get the pipe */
+	intel_encoder = dev_priv->dig_port_map[port];
+	/* intel_encoder might be NULL for DP MST */
+	if (!intel_encoder || !intel_encoder->base.crtc ||
+	    intel_encoder->type != INTEL_OUTPUT_HDMI) {
+		DRM_DEBUG_KMS("no valid port %c\n", port_name(port));
+		err = -ENODEV;
+		goto unlock;
+	}
+	crtc = to_intel_crtc(intel_encoder->base.crtc);
+	pipe = crtc->pipe;
+	if (pipe == INVALID_PIPE) {
+		DRM_DEBUG_KMS("no pipe for the port %c\n", port_name(port));
+		err = -ENODEV;
+		goto unlock;
+	}
+
+	DRM_DEBUG_KMS("pipe %c connects port %c\n",
+				  pipe_name(pipe), port_name(port));
+	mode = &crtc->config->base.adjusted_mode;
+
+	/* port must be valid now, otherwise the pipe will be invalid */
+	acomp->aud_sample_rate[port] = rate;
+
+	/* 2. check whether to set the N/CTS/M manually or not */
+	if (!audio_rate_need_prog(crtc, mode)) {
+		tmp = I915_READ(HSW_AUD_CFG(pipe));
+		tmp &= ~AUD_CONFIG_N_PROG_ENABLE;
+		I915_WRITE(HSW_AUD_CFG(pipe), tmp);
+		goto unlock;
+	}
+
+	n = audio_config_get_n(mode, rate);
+	if (n == 0) {
+		DRM_DEBUG_KMS("Using automatic mode for N value on port %c\n",
+					  port_name(port));
+		tmp = I915_READ(HSW_AUD_CFG(pipe));
+		tmp &= ~AUD_CONFIG_N_PROG_ENABLE;
+		I915_WRITE(HSW_AUD_CFG(pipe), tmp);
+		goto unlock;
+	}
+
+	/* 3. set the N/CTS/M */
+	tmp = I915_READ(HSW_AUD_CFG(pipe));
+	tmp = audio_config_setup_n_reg(n, tmp);
+	I915_WRITE(HSW_AUD_CFG(pipe), tmp);
+
+ unlock:
+	mutex_unlock(&dev_priv->av_mutex);
+	return err;
+}
+
+static int i915_audio_component_get_eld(struct device *dev, int port,
+					bool *enabled,
+					unsigned char *buf, int max_bytes)
+{
+	struct drm_i915_private *dev_priv = dev_to_i915(dev);
+	struct intel_encoder *intel_encoder;
+	struct intel_digital_port *intel_dig_port;
+	const u8 *eld;
+	int ret = -EINVAL;
+
+	mutex_lock(&dev_priv->av_mutex);
+	intel_encoder = dev_priv->dig_port_map[port];
+	/* intel_encoder might be NULL for DP MST */
+	if (intel_encoder) {
+		ret = 0;
+		intel_dig_port = enc_to_dig_port(&intel_encoder->base);
+		*enabled = intel_dig_port->audio_connector != NULL;
+		if (*enabled) {
+			eld = intel_dig_port->audio_connector->eld;
+			ret = drm_eld_size(eld);
+			memcpy(buf, eld, min(max_bytes, ret));
+		}
+	}
+
+	mutex_unlock(&dev_priv->av_mutex);
+	return ret;
+}
+
+static const struct i915_audio_component_ops i915_audio_component_ops = {
+	.owner		= THIS_MODULE,
+	.get_power	= i915_audio_component_get_power,
+	.put_power	= i915_audio_component_put_power,
+	.codec_wake_override = i915_audio_component_codec_wake_override,
+	.get_cdclk_freq	= i915_audio_component_get_cdclk_freq,
+	.sync_audio_rate = i915_audio_component_sync_audio_rate,
+	.get_eld	= i915_audio_component_get_eld,
+};
+
+static int i915_audio_component_bind(struct device *i915_dev,
+				     struct device *hda_dev, void *data)
+{
+	struct i915_audio_component *acomp = data;
+	struct drm_i915_private *dev_priv = dev_to_i915(i915_dev);
+	int i;
+
+	if (WARN_ON(acomp->ops || acomp->dev))
+		return -EEXIST;
+
+	drm_modeset_lock_all(dev_priv->dev);
+	acomp->ops = &i915_audio_component_ops;
+	acomp->dev = i915_dev;
+	BUILD_BUG_ON(MAX_PORTS != I915_MAX_PORTS);
+	for (i = 0; i < ARRAY_SIZE(acomp->aud_sample_rate); i++)
+		acomp->aud_sample_rate[i] = 0;
+	dev_priv->audio_component = acomp;
+	drm_modeset_unlock_all(dev_priv->dev);
+
+	return 0;
+}
+
+static void i915_audio_component_unbind(struct device *i915_dev,
+					struct device *hda_dev, void *data)
+{
+	struct i915_audio_component *acomp = data;
+	struct drm_i915_private *dev_priv = dev_to_i915(i915_dev);
+
+	drm_modeset_lock_all(dev_priv->dev);
+	acomp->ops = NULL;
+	acomp->dev = NULL;
+	dev_priv->audio_component = NULL;
+	drm_modeset_unlock_all(dev_priv->dev);
+}
+
+static const struct component_ops i915_audio_component_bind_ops = {
+	.bind	= i915_audio_component_bind,
+	.unbind	= i915_audio_component_unbind,
+};
+
+/**
+ * i915_audio_component_init - initialize and register the audio component
+ * @dev_priv: i915 device instance
+ *
+ * This will register with the component framework a child component which
+ * will bind dynamically to the snd_hda_intel driver's corresponding master
+ * component when the latter is registered. During binding the child
+ * initializes an instance of struct i915_audio_component which it receives
+ * from the master. The master can then start to use the interface defined by
+ * this struct. Each side can break the binding at any point by deregistering
+ * its own component after which each side's component unbind callback is
+ * called.
+ *
+ * We ignore any error during registration and continue with reduced
+ * functionality (i.e. without HDMI audio).
+ */
+void i915_audio_component_init(struct drm_i915_private *dev_priv)
+{
+	int ret;
+
+	ret = component_add(dev_priv->dev->dev, &i915_audio_component_bind_ops);
+	if (ret < 0) {
+		DRM_ERROR("failed to add audio component (%d)\n", ret);
+		/* continue with reduced functionality */
+		return;
+	}
+
+	dev_priv->audio_component_registered = true;
+}
+
+/**
+ * i915_audio_component_cleanup - deregister the audio component
+ * @dev_priv: i915 device instance
+ *
+ * Deregisters the audio component, breaking any existing binding to the
+ * corresponding snd_hda_intel driver's master component.
+ */
+void i915_audio_component_cleanup(struct drm_i915_private *dev_priv)
+{
+	if (!dev_priv->audio_component_registered)
+		return;
+
+	component_del(dev_priv->dev->dev, &i915_audio_component_bind_ops);
+	dev_priv->audio_component_registered = false;
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/i915/intel_bios.c
@@ -0,0 +1,1742 @@
+/*
+ * Copyright © 2006 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Authors:
+ *    Eric Anholt <eric@anholt.net>
+ *
+ */
+
+#include <drm/drm_dp_helper.h>
+#include <drm/drmP.h>
+#include <drm/i915_drm.h>
+#include "i915_drv.h"
+
+#define _INTEL_BIOS_PRIVATE
+#include "intel_vbt_defs.h"
+
+/**
+ * DOC: Video BIOS Table (VBT)
+ *
+ * The Video BIOS Table, or VBT, provides platform and board specific
+ * configuration information to the driver that is not discoverable or available
+ * through other means. The configuration is mostly related to display
+ * hardware. The VBT is available via the ACPI OpRegion or, on older systems, in
+ * the PCI ROM.
+ *
+ * The VBT consists of a VBT Header (defined as &struct vbt_header), a BDB
+ * Header (&struct bdb_header), and a number of BIOS Data Blocks (BDB) that
+ * contain the actual configuration information. The VBT Header, and thus the
+ * VBT, begins with "$VBT" signature. The VBT Header contains the offset of the
+ * BDB Header. The data blocks are concatenated after the BDB Header. The data
+ * blocks have a 1-byte Block ID, 2-byte Block Size, and Block Size bytes of
+ * data. (Block 53, the MIPI Sequence Block is an exception.)
+ *
+ * The driver parses the VBT during load. The relevant information is stored in
+ * driver private data for ease of use, and the actual VBT is not read after
+ * that.
+ */
+
+#define	SLAVE_ADDR1	0x70
+#define	SLAVE_ADDR2	0x72
+
+/* Get BDB block size given a pointer to Block ID. */
+static u32 _get_blocksize(const u8 *block_base)
+{
+	/* The MIPI Sequence Block v3+ has a separate size field. */
+	if (*block_base == BDB_MIPI_SEQUENCE && *(block_base + 3) >= 3)
+		return *((const u32 *)(block_base + 4));
+	else
+		return *((const u16 *)(block_base + 1));
+}
+
+/* Get BDB block size give a pointer to data after Block ID and Block Size. */
+static u32 get_blocksize(const void *block_data)
+{
+	return _get_blocksize(block_data - 3);
+}
+
+static const void *
+find_section(const void *_bdb, int section_id)
+{
+	const struct bdb_header *bdb = _bdb;
+	const u8 *base = _bdb;
+	int index = 0;
+	u32 total, current_size;
+	u8 current_id;
+
+	/* skip to first section */
+	index += bdb->header_size;
+	total = bdb->bdb_size;
+
+	/* walk the sections looking for section_id */
+	while (index + 3 < total) {
+		current_id = *(base + index);
+		current_size = _get_blocksize(base + index);
+		index += 3;
+
+		if (index + current_size > total)
+			return NULL;
+
+		if (current_id == section_id)
+			return base + index;
+
+		index += current_size;
+	}
+
+	return NULL;
+}
+
+static void
+fill_detail_timing_data(struct drm_display_mode *panel_fixed_mode,
+			const struct lvds_dvo_timing *dvo_timing)
+{
+	panel_fixed_mode->hdisplay = (dvo_timing->hactive_hi << 8) |
+		dvo_timing->hactive_lo;
+	panel_fixed_mode->hsync_start = panel_fixed_mode->hdisplay +
+		((dvo_timing->hsync_off_hi << 8) | dvo_timing->hsync_off_lo);
+	panel_fixed_mode->hsync_end = panel_fixed_mode->hsync_start +
+		dvo_timing->hsync_pulse_width;
+	panel_fixed_mode->htotal = panel_fixed_mode->hdisplay +
+		((dvo_timing->hblank_hi << 8) | dvo_timing->hblank_lo);
+
+	panel_fixed_mode->vdisplay = (dvo_timing->vactive_hi << 8) |
+		dvo_timing->vactive_lo;
+	panel_fixed_mode->vsync_start = panel_fixed_mode->vdisplay +
+		dvo_timing->vsync_off;
+	panel_fixed_mode->vsync_end = panel_fixed_mode->vsync_start +
+		dvo_timing->vsync_pulse_width;
+	panel_fixed_mode->vtotal = panel_fixed_mode->vdisplay +
+		((dvo_timing->vblank_hi << 8) | dvo_timing->vblank_lo);
+	panel_fixed_mode->clock = dvo_timing->clock * 10;
+	panel_fixed_mode->type = DRM_MODE_TYPE_PREFERRED;
+
+	if (dvo_timing->hsync_positive)
+		panel_fixed_mode->flags |= DRM_MODE_FLAG_PHSYNC;
+	else
+		panel_fixed_mode->flags |= DRM_MODE_FLAG_NHSYNC;
+
+	if (dvo_timing->vsync_positive)
+		panel_fixed_mode->flags |= DRM_MODE_FLAG_PVSYNC;
+	else
+		panel_fixed_mode->flags |= DRM_MODE_FLAG_NVSYNC;
+
+	panel_fixed_mode->width_mm = (dvo_timing->himage_hi << 8) |
+		dvo_timing->himage_lo;
+	panel_fixed_mode->height_mm = (dvo_timing->vimage_hi << 8) |
+		dvo_timing->vimage_lo;
+
+	/* Some VBTs have bogus h/vtotal values */
+	if (panel_fixed_mode->hsync_end > panel_fixed_mode->htotal)
+		panel_fixed_mode->htotal = panel_fixed_mode->hsync_end + 1;
+	if (panel_fixed_mode->vsync_end > panel_fixed_mode->vtotal)
+		panel_fixed_mode->vtotal = panel_fixed_mode->vsync_end + 1;
+
+	drm_mode_set_name(panel_fixed_mode);
+}
+
+static const struct lvds_dvo_timing *
+get_lvds_dvo_timing(const struct bdb_lvds_lfp_data *lvds_lfp_data,
+		    const struct bdb_lvds_lfp_data_ptrs *lvds_lfp_data_ptrs,
+		    int index)
+{
+	/*
+	 * the size of fp_timing varies on the different platform.
+	 * So calculate the DVO timing relative offset in LVDS data
+	 * entry to get the DVO timing entry
+	 */
+
+	int lfp_data_size =
+		lvds_lfp_data_ptrs->ptr[1].dvo_timing_offset -
+		lvds_lfp_data_ptrs->ptr[0].dvo_timing_offset;
+	int dvo_timing_offset =
+		lvds_lfp_data_ptrs->ptr[0].dvo_timing_offset -
+		lvds_lfp_data_ptrs->ptr[0].fp_timing_offset;
+	char *entry = (char *)lvds_lfp_data->data + lfp_data_size * index;
+
+	return (struct lvds_dvo_timing *)(entry + dvo_timing_offset);
+}
+
+/* get lvds_fp_timing entry
+ * this function may return NULL if the corresponding entry is invalid
+ */
+static const struct lvds_fp_timing *
+get_lvds_fp_timing(const struct bdb_header *bdb,
+		   const struct bdb_lvds_lfp_data *data,
+		   const struct bdb_lvds_lfp_data_ptrs *ptrs,
+		   int index)
+{
+	size_t data_ofs = (const u8 *)data - (const u8 *)bdb;
+	u16 data_size = ((const u16 *)data)[-1]; /* stored in header */
+	size_t ofs;
+
+	if (index >= ARRAY_SIZE(ptrs->ptr))
+		return NULL;
+	ofs = ptrs->ptr[index].fp_timing_offset;
+	if (ofs < data_ofs ||
+	    ofs + sizeof(struct lvds_fp_timing) > data_ofs + data_size)
+		return NULL;
+	return (const struct lvds_fp_timing *)((const u8 *)bdb + ofs);
+}
+
+/* Try to find integrated panel data */
+static void
+parse_lfp_panel_data(struct drm_i915_private *dev_priv,
+		     const struct bdb_header *bdb)
+{
+	const struct bdb_lvds_options *lvds_options;
+	const struct bdb_lvds_lfp_data *lvds_lfp_data;
+	const struct bdb_lvds_lfp_data_ptrs *lvds_lfp_data_ptrs;
+	const struct lvds_dvo_timing *panel_dvo_timing;
+	const struct lvds_fp_timing *fp_timing;
+	struct drm_display_mode *panel_fixed_mode;
+	int panel_type;
+	int drrs_mode;
+	int ret;
+
+	lvds_options = find_section(bdb, BDB_LVDS_OPTIONS);
+	if (!lvds_options)
+		return;
+
+	dev_priv->vbt.lvds_dither = lvds_options->pixel_dither;
+
+	ret = intel_opregion_get_panel_type(dev_priv->dev);
+	if (ret >= 0) {
+		WARN_ON(ret > 0xf);
+		panel_type = ret;
+		DRM_DEBUG_KMS("Panel type: %d (OpRegion)\n", panel_type);
+	} else {
+		if (lvds_options->panel_type > 0xf) {
+			DRM_DEBUG_KMS("Invalid VBT panel type 0x%x\n",
+				      lvds_options->panel_type);
+			return;
+		}
+		panel_type = lvds_options->panel_type;
+		DRM_DEBUG_KMS("Panel type: %d (VBT)\n", panel_type);
+	}
+
+	dev_priv->vbt.panel_type = panel_type;
+
+	drrs_mode = (lvds_options->dps_panel_type_bits
+				>> (panel_type * 2)) & MODE_MASK;
+	/*
+	 * VBT has static DRRS = 0 and seamless DRRS = 2.
+	 * The below piece of code is required to adjust vbt.drrs_type
+	 * to match the enum drrs_support_type.
+	 */
+	switch (drrs_mode) {
+	case 0:
+		dev_priv->vbt.drrs_type = STATIC_DRRS_SUPPORT;
+		DRM_DEBUG_KMS("DRRS supported mode is static\n");
+		break;
+	case 2:
+		dev_priv->vbt.drrs_type = SEAMLESS_DRRS_SUPPORT;
+		DRM_DEBUG_KMS("DRRS supported mode is seamless\n");
+		break;
+	default:
+		dev_priv->vbt.drrs_type = DRRS_NOT_SUPPORTED;
+		DRM_DEBUG_KMS("DRRS not supported (VBT input)\n");
+		break;
+	}
+
+	lvds_lfp_data = find_section(bdb, BDB_LVDS_LFP_DATA);
+	if (!lvds_lfp_data)
+		return;
+
+	lvds_lfp_data_ptrs = find_section(bdb, BDB_LVDS_LFP_DATA_PTRS);
+	if (!lvds_lfp_data_ptrs)
+		return;
+
+	dev_priv->vbt.lvds_vbt = 1;
+
+	panel_dvo_timing = get_lvds_dvo_timing(lvds_lfp_data,
+					       lvds_lfp_data_ptrs,
+					       panel_type);
+
+	panel_fixed_mode = kzalloc(sizeof(*panel_fixed_mode), GFP_KERNEL);
+	if (!panel_fixed_mode)
+		return;
+
+	fill_detail_timing_data(panel_fixed_mode, panel_dvo_timing);
+
+	dev_priv->vbt.lfp_lvds_vbt_mode = panel_fixed_mode;
+
+	DRM_DEBUG_KMS("Found panel mode in BIOS VBT tables:\n");
+	drm_mode_debug_printmodeline(panel_fixed_mode);
+
+	fp_timing = get_lvds_fp_timing(bdb, lvds_lfp_data,
+				       lvds_lfp_data_ptrs,
+				       panel_type);
+	if (fp_timing) {
+		/* check the resolution, just to be sure */
+		if (fp_timing->x_res == panel_fixed_mode->hdisplay &&
+		    fp_timing->y_res == panel_fixed_mode->vdisplay) {
+			dev_priv->vbt.bios_lvds_val = fp_timing->lvds_reg_val;
+			DRM_DEBUG_KMS("VBT initial LVDS value %x\n",
+				      dev_priv->vbt.bios_lvds_val);
+		}
+	}
+}
+
+static void
+parse_lfp_backlight(struct drm_i915_private *dev_priv,
+		    const struct bdb_header *bdb)
+{
+	const struct bdb_lfp_backlight_data *backlight_data;
+	const struct bdb_lfp_backlight_data_entry *entry;
+	int panel_type = dev_priv->vbt.panel_type;
+
+	backlight_data = find_section(bdb, BDB_LVDS_BACKLIGHT);
+	if (!backlight_data)
+		return;
+
+	if (backlight_data->entry_size != sizeof(backlight_data->data[0])) {
+		DRM_DEBUG_KMS("Unsupported backlight data entry size %u\n",
+			      backlight_data->entry_size);
+		return;
+	}
+
+	entry = &backlight_data->data[panel_type];
+
+	dev_priv->vbt.backlight.present = entry->type == BDB_BACKLIGHT_TYPE_PWM;
+	if (!dev_priv->vbt.backlight.present) {
+		DRM_DEBUG_KMS("PWM backlight not present in VBT (type %u)\n",
+			      entry->type);
+		return;
+	}
+
+	dev_priv->vbt.backlight.pwm_freq_hz = entry->pwm_freq_hz;
+	dev_priv->vbt.backlight.active_low_pwm = entry->active_low_pwm;
+	dev_priv->vbt.backlight.min_brightness = entry->min_brightness;
+	DRM_DEBUG_KMS("VBT backlight PWM modulation frequency %u Hz, "
+		      "active %s, min brightness %u, level %u\n",
+		      dev_priv->vbt.backlight.pwm_freq_hz,
+		      dev_priv->vbt.backlight.active_low_pwm ? "low" : "high",
+		      dev_priv->vbt.backlight.min_brightness,
+		      backlight_data->level[panel_type]);
+}
+
+/* Try to find sdvo panel data */
+static void
+parse_sdvo_panel_data(struct drm_i915_private *dev_priv,
+		      const struct bdb_header *bdb)
+{
+	const struct lvds_dvo_timing *dvo_timing;
+	struct drm_display_mode *panel_fixed_mode;
+	int index;
+
+	index = i915.vbt_sdvo_panel_type;
+	if (index == -2) {
+		DRM_DEBUG_KMS("Ignore SDVO panel mode from BIOS VBT tables.\n");
+		return;
+	}
+
+	if (index == -1) {
+		const struct bdb_sdvo_lvds_options *sdvo_lvds_options;
+
+		sdvo_lvds_options = find_section(bdb, BDB_SDVO_LVDS_OPTIONS);
+		if (!sdvo_lvds_options)
+			return;
+
+		index = sdvo_lvds_options->panel_type;
+	}
+
+	dvo_timing = find_section(bdb, BDB_SDVO_PANEL_DTDS);
+	if (!dvo_timing)
+		return;
+
+	panel_fixed_mode = kzalloc(sizeof(*panel_fixed_mode), GFP_KERNEL);
+	if (!panel_fixed_mode)
+		return;
+
+	fill_detail_timing_data(panel_fixed_mode, dvo_timing + index);
+
+	dev_priv->vbt.sdvo_lvds_vbt_mode = panel_fixed_mode;
+
+	DRM_DEBUG_KMS("Found SDVO panel mode in BIOS VBT tables:\n");
+	drm_mode_debug_printmodeline(panel_fixed_mode);
+}
+
+static int intel_bios_ssc_frequency(struct drm_i915_private *dev_priv,
+				    bool alternate)
+{
+	switch (INTEL_INFO(dev_priv)->gen) {
+	case 2:
+		return alternate ? 66667 : 48000;
+	case 3:
+	case 4:
+		return alternate ? 100000 : 96000;
+	default:
+		return alternate ? 100000 : 120000;
+	}
+}
+
+static void
+parse_general_features(struct drm_i915_private *dev_priv,
+		       const struct bdb_header *bdb)
+{
+	const struct bdb_general_features *general;
+
+	general = find_section(bdb, BDB_GENERAL_FEATURES);
+	if (!general)
+		return;
+
+	dev_priv->vbt.int_tv_support = general->int_tv_support;
+	/* int_crt_support can't be trusted on earlier platforms */
+	if (bdb->version >= 155 &&
+	    (HAS_DDI(dev_priv) || IS_VALLEYVIEW(dev_priv)))
+		dev_priv->vbt.int_crt_support = general->int_crt_support;
+	dev_priv->vbt.lvds_use_ssc = general->enable_ssc;
+	dev_priv->vbt.lvds_ssc_freq =
+		intel_bios_ssc_frequency(dev_priv, general->ssc_freq);
+	dev_priv->vbt.display_clock_mode = general->display_clock_mode;
+	dev_priv->vbt.fdi_rx_polarity_inverted = general->fdi_rx_polarity_inverted;
+	DRM_DEBUG_KMS("BDB_GENERAL_FEATURES int_tv_support %d int_crt_support %d lvds_use_ssc %d lvds_ssc_freq %d display_clock_mode %d fdi_rx_polarity_inverted %d\n",
+		      dev_priv->vbt.int_tv_support,
+		      dev_priv->vbt.int_crt_support,
+		      dev_priv->vbt.lvds_use_ssc,
+		      dev_priv->vbt.lvds_ssc_freq,
+		      dev_priv->vbt.display_clock_mode,
+		      dev_priv->vbt.fdi_rx_polarity_inverted);
+}
+
+static void
+parse_general_definitions(struct drm_i915_private *dev_priv,
+			  const struct bdb_header *bdb)
+{
+	const struct bdb_general_definitions *general;
+
+	general = find_section(bdb, BDB_GENERAL_DEFINITIONS);
+	if (general) {
+		u16 block_size = get_blocksize(general);
+		if (block_size >= sizeof(*general)) {
+			int bus_pin = general->crt_ddc_gmbus_pin;
+			DRM_DEBUG_KMS("crt_ddc_bus_pin: %d\n", bus_pin);
+			if (intel_gmbus_is_valid_pin(dev_priv, bus_pin))
+				dev_priv->vbt.crt_ddc_pin = bus_pin;
+		} else {
+			DRM_DEBUG_KMS("BDB_GD too small (%d). Invalid.\n",
+				      block_size);
+		}
+	}
+}
+
+static const union child_device_config *
+child_device_ptr(const struct bdb_general_definitions *p_defs, int i)
+{
+	return (const void *) &p_defs->devices[i * p_defs->child_dev_size];
+}
+
+static void
+parse_sdvo_device_mapping(struct drm_i915_private *dev_priv,
+			  const struct bdb_header *bdb)
+{
+	struct sdvo_device_mapping *p_mapping;
+	const struct bdb_general_definitions *p_defs;
+	const struct old_child_dev_config *child; /* legacy */
+	int i, child_device_num, count;
+	u16	block_size;
+
+	p_defs = find_section(bdb, BDB_GENERAL_DEFINITIONS);
+	if (!p_defs) {
+		DRM_DEBUG_KMS("No general definition block is found, unable to construct sdvo mapping.\n");
+		return;
+	}
+
+	/*
+	 * Only parse SDVO mappings when the general definitions block child
+	 * device size matches that of the *legacy* child device config
+	 * struct. Thus, SDVO mapping will be skipped for newer VBT.
+	 */
+	if (p_defs->child_dev_size != sizeof(*child)) {
+		DRM_DEBUG_KMS("Unsupported child device size for SDVO mapping.\n");
+		return;
+	}
+	/* get the block size of general definitions */
+	block_size = get_blocksize(p_defs);
+	/* get the number of child device */
+	child_device_num = (block_size - sizeof(*p_defs)) /
+		p_defs->child_dev_size;
+	count = 0;
+	for (i = 0; i < child_device_num; i++) {
+		child = &child_device_ptr(p_defs, i)->old;
+		if (!child->device_type) {
+			/* skip the device block if device type is invalid */
+			continue;
+		}
+		if (child->slave_addr != SLAVE_ADDR1 &&
+		    child->slave_addr != SLAVE_ADDR2) {
+			/*
+			 * If the slave address is neither 0x70 nor 0x72,
+			 * it is not a SDVO device. Skip it.
+			 */
+			continue;
+		}
+		if (child->dvo_port != DEVICE_PORT_DVOB &&
+		    child->dvo_port != DEVICE_PORT_DVOC) {
+			/* skip the incorrect SDVO port */
+			DRM_DEBUG_KMS("Incorrect SDVO port. Skip it\n");
+			continue;
+		}
+		DRM_DEBUG_KMS("the SDVO device with slave addr %2x is found on"
+			      " %s port\n",
+			      child->slave_addr,
+			      (child->dvo_port == DEVICE_PORT_DVOB) ?
+			      "SDVOB" : "SDVOC");
+		p_mapping = &dev_priv->vbt.sdvo_mappings[child->dvo_port - 1];
+		if (!p_mapping->initialized) {
+			p_mapping->dvo_port = child->dvo_port;
+			p_mapping->slave_addr = child->slave_addr;
+			p_mapping->dvo_wiring = child->dvo_wiring;
+			p_mapping->ddc_pin = child->ddc_pin;
+			p_mapping->i2c_pin = child->i2c_pin;
+			p_mapping->initialized = 1;
+			DRM_DEBUG_KMS("SDVO device: dvo=%x, addr=%x, wiring=%d, ddc_pin=%d, i2c_pin=%d\n",
+				      p_mapping->dvo_port,
+				      p_mapping->slave_addr,
+				      p_mapping->dvo_wiring,
+				      p_mapping->ddc_pin,
+				      p_mapping->i2c_pin);
+		} else {
+			DRM_DEBUG_KMS("Maybe one SDVO port is shared by "
+					 "two SDVO device.\n");
+		}
+		if (child->slave2_addr) {
+			/* Maybe this is a SDVO device with multiple inputs */
+			/* And the mapping info is not added */
+			DRM_DEBUG_KMS("there exists the slave2_addr. Maybe this"
+				" is a SDVO device with multiple inputs.\n");
+		}
+		count++;
+	}
+
+	if (!count) {
+		/* No SDVO device info is found */
+		DRM_DEBUG_KMS("No SDVO device info is found in VBT\n");
+	}
+	return;
+}
+
+static void
+parse_driver_features(struct drm_i915_private *dev_priv,
+		      const struct bdb_header *bdb)
+{
+	const struct bdb_driver_features *driver;
+
+	driver = find_section(bdb, BDB_DRIVER_FEATURES);
+	if (!driver)
+		return;
+
+	if (driver->lvds_config == BDB_DRIVER_FEATURE_EDP)
+		dev_priv->vbt.edp.support = 1;
+
+	DRM_DEBUG_KMS("DRRS State Enabled:%d\n", driver->drrs_enabled);
+	/*
+	 * If DRRS is not supported, drrs_type has to be set to 0.
+	 * This is because, VBT is configured in such a way that
+	 * static DRRS is 0 and DRRS not supported is represented by
+	 * driver->drrs_enabled=false
+	 */
+	if (!driver->drrs_enabled)
+		dev_priv->vbt.drrs_type = DRRS_NOT_SUPPORTED;
+}
+
+static void
+parse_edp(struct drm_i915_private *dev_priv, const struct bdb_header *bdb)
+{
+	const struct bdb_edp *edp;
+	const struct edp_power_seq *edp_pps;
+	const struct edp_link_params *edp_link_params;
+	int panel_type = dev_priv->vbt.panel_type;
+
+	edp = find_section(bdb, BDB_EDP);
+	if (!edp) {
+		if (dev_priv->vbt.edp.support)
+			DRM_DEBUG_KMS("No eDP BDB found but eDP panel supported.\n");
+		return;
+	}
+
+	switch ((edp->color_depth >> (panel_type * 2)) & 3) {
+	case EDP_18BPP:
+		dev_priv->vbt.edp.bpp = 18;
+		break;
+	case EDP_24BPP:
+		dev_priv->vbt.edp.bpp = 24;
+		break;
+	case EDP_30BPP:
+		dev_priv->vbt.edp.bpp = 30;
+		break;
+	}
+
+	/* Get the eDP sequencing and link info */
+	edp_pps = &edp->power_seqs[panel_type];
+	edp_link_params = &edp->link_params[panel_type];
+
+	dev_priv->vbt.edp.pps = *edp_pps;
+
+	switch (edp_link_params->rate) {
+	case EDP_RATE_1_62:
+		dev_priv->vbt.edp.rate = DP_LINK_BW_1_62;
+		break;
+	case EDP_RATE_2_7:
+		dev_priv->vbt.edp.rate = DP_LINK_BW_2_7;
+		break;
+	default:
+		DRM_DEBUG_KMS("VBT has unknown eDP link rate value %u\n",
+			      edp_link_params->rate);
+		break;
+	}
+
+	switch (edp_link_params->lanes) {
+	case EDP_LANE_1:
+		dev_priv->vbt.edp.lanes = 1;
+		break;
+	case EDP_LANE_2:
+		dev_priv->vbt.edp.lanes = 2;
+		break;
+	case EDP_LANE_4:
+		dev_priv->vbt.edp.lanes = 4;
+		break;
+	default:
+		DRM_DEBUG_KMS("VBT has unknown eDP lane count value %u\n",
+			      edp_link_params->lanes);
+		break;
+	}
+
+	switch (edp_link_params->preemphasis) {
+	case EDP_PREEMPHASIS_NONE:
+		dev_priv->vbt.edp.preemphasis = DP_TRAIN_PRE_EMPH_LEVEL_0;
+		break;
+	case EDP_PREEMPHASIS_3_5dB:
+		dev_priv->vbt.edp.preemphasis = DP_TRAIN_PRE_EMPH_LEVEL_1;
+		break;
+	case EDP_PREEMPHASIS_6dB:
+		dev_priv->vbt.edp.preemphasis = DP_TRAIN_PRE_EMPH_LEVEL_2;
+		break;
+	case EDP_PREEMPHASIS_9_5dB:
+		dev_priv->vbt.edp.preemphasis = DP_TRAIN_PRE_EMPH_LEVEL_3;
+		break;
+	default:
+		DRM_DEBUG_KMS("VBT has unknown eDP pre-emphasis value %u\n",
+			      edp_link_params->preemphasis);
+		break;
+	}
+
+	switch (edp_link_params->vswing) {
+	case EDP_VSWING_0_4V:
+		dev_priv->vbt.edp.vswing = DP_TRAIN_VOLTAGE_SWING_LEVEL_0;
+		break;
+	case EDP_VSWING_0_6V:
+		dev_priv->vbt.edp.vswing = DP_TRAIN_VOLTAGE_SWING_LEVEL_1;
+		break;
+	case EDP_VSWING_0_8V:
+		dev_priv->vbt.edp.vswing = DP_TRAIN_VOLTAGE_SWING_LEVEL_2;
+		break;
+	case EDP_VSWING_1_2V:
+		dev_priv->vbt.edp.vswing = DP_TRAIN_VOLTAGE_SWING_LEVEL_3;
+		break;
+	default:
+		DRM_DEBUG_KMS("VBT has unknown eDP voltage swing value %u\n",
+			      edp_link_params->vswing);
+		break;
+	}
+
+	if (bdb->version >= 173) {
+		uint8_t vswing;
+
+		/* Don't read from VBT if module parameter has valid value*/
+		if (i915.edp_vswing) {
+			dev_priv->vbt.edp.low_vswing = i915.edp_vswing == 1;
+		} else {
+			vswing = (edp->edp_vswing_preemph >> (panel_type * 4)) & 0xF;
+			dev_priv->vbt.edp.low_vswing = vswing == 0;
+		}
+	}
+}
+
+static void
+parse_psr(struct drm_i915_private *dev_priv, const struct bdb_header *bdb)
+{
+	const struct bdb_psr *psr;
+	const struct psr_table *psr_table;
+	int panel_type = dev_priv->vbt.panel_type;
+
+	psr = find_section(bdb, BDB_PSR);
+	if (!psr) {
+		DRM_DEBUG_KMS("No PSR BDB found.\n");
+		return;
+	}
+
+	psr_table = &psr->psr_table[panel_type];
+
+	dev_priv->vbt.psr.full_link = psr_table->full_link;
+	dev_priv->vbt.psr.require_aux_wakeup = psr_table->require_aux_to_wakeup;
+
+	/* Allowed VBT values goes from 0 to 15 */
+	dev_priv->vbt.psr.idle_frames = psr_table->idle_frames < 0 ? 0 :
+		psr_table->idle_frames > 15 ? 15 : psr_table->idle_frames;
+
+	switch (psr_table->lines_to_wait) {
+	case 0:
+		dev_priv->vbt.psr.lines_to_wait = PSR_0_LINES_TO_WAIT;
+		break;
+	case 1:
+		dev_priv->vbt.psr.lines_to_wait = PSR_1_LINE_TO_WAIT;
+		break;
+	case 2:
+		dev_priv->vbt.psr.lines_to_wait = PSR_4_LINES_TO_WAIT;
+		break;
+	case 3:
+		dev_priv->vbt.psr.lines_to_wait = PSR_8_LINES_TO_WAIT;
+		break;
+	default:
+		DRM_DEBUG_KMS("VBT has unknown PSR lines to wait %u\n",
+			      psr_table->lines_to_wait);
+		break;
+	}
+
+	dev_priv->vbt.psr.tp1_wakeup_time = psr_table->tp1_wakeup_time;
+	dev_priv->vbt.psr.tp2_tp3_wakeup_time = psr_table->tp2_tp3_wakeup_time;
+}
+
+static void
+parse_mipi_config(struct drm_i915_private *dev_priv,
+		  const struct bdb_header *bdb)
+{
+	const struct bdb_mipi_config *start;
+	const struct mipi_config *config;
+	const struct mipi_pps_data *pps;
+	int panel_type = dev_priv->vbt.panel_type;
+
+	/* parse MIPI blocks only if LFP type is MIPI */
+	if (!intel_bios_is_dsi_present(dev_priv, NULL))
+		return;
+
+	/* Initialize this to undefined indicating no generic MIPI support */
+	dev_priv->vbt.dsi.panel_id = MIPI_DSI_UNDEFINED_PANEL_ID;
+
+	/* Block #40 is already parsed and panel_fixed_mode is
+	 * stored in dev_priv->lfp_lvds_vbt_mode
+	 * resuse this when needed
+	 */
+
+	/* Parse #52 for panel index used from panel_type already
+	 * parsed
+	 */
+	start = find_section(bdb, BDB_MIPI_CONFIG);
+	if (!start) {
+		DRM_DEBUG_KMS("No MIPI config BDB found");
+		return;
+	}
+
+	DRM_DEBUG_DRIVER("Found MIPI Config block, panel index = %d\n",
+								panel_type);
+
+	/*
+	 * get hold of the correct configuration block and pps data as per
+	 * the panel_type as index
+	 */
+	config = &start->config[panel_type];
+	pps = &start->pps[panel_type];
+
+	/* store as of now full data. Trim when we realise all is not needed */
+	dev_priv->vbt.dsi.config = kmemdup(config, sizeof(struct mipi_config), GFP_KERNEL);
+	if (!dev_priv->vbt.dsi.config)
+		return;
+
+	dev_priv->vbt.dsi.pps = kmemdup(pps, sizeof(struct mipi_pps_data), GFP_KERNEL);
+	if (!dev_priv->vbt.dsi.pps) {
+		kfree(dev_priv->vbt.dsi.config);
+		return;
+	}
+
+	/* We have mandatory mipi config blocks. Initialize as generic panel */
+	dev_priv->vbt.dsi.panel_id = MIPI_DSI_GENERIC_PANEL_ID;
+}
+
+/* Find the sequence block and size for the given panel. */
+static const u8 *
+find_panel_sequence_block(const struct bdb_mipi_sequence *sequence,
+			  u16 panel_id, u32 *seq_size)
+{
+	u32 total = get_blocksize(sequence);
+	const u8 *data = &sequence->data[0];
+	u8 current_id;
+	u32 current_size;
+	int header_size = sequence->version >= 3 ? 5 : 3;
+	int index = 0;
+	int i;
+
+	/* skip new block size */
+	if (sequence->version >= 3)
+		data += 4;
+
+	for (i = 0; i < MAX_MIPI_CONFIGURATIONS && index < total; i++) {
+		if (index + header_size > total) {
+			DRM_ERROR("Invalid sequence block (header)\n");
+			return NULL;
+		}
+
+		current_id = *(data + index);
+		if (sequence->version >= 3)
+			current_size = *((const u32 *)(data + index + 1));
+		else
+			current_size = *((const u16 *)(data + index + 1));
+
+		index += header_size;
+
+		if (index + current_size > total) {
+			DRM_ERROR("Invalid sequence block\n");
+			return NULL;
+		}
+
+		if (current_id == panel_id) {
+			*seq_size = current_size;
+			return data + index;
+		}
+
+		index += current_size;
+	}
+
+	DRM_ERROR("Sequence block detected but no valid configuration\n");
+
+	return NULL;
+}
+
+static int goto_next_sequence(const u8 *data, int index, int total)
+{
+	u16 len;
+
+	/* Skip Sequence Byte. */
+	for (index = index + 1; index < total; index += len) {
+		u8 operation_byte = *(data + index);
+		index++;
+
+		switch (operation_byte) {
+		case MIPI_SEQ_ELEM_END:
+			return index;
+		case MIPI_SEQ_ELEM_SEND_PKT:
+			if (index + 4 > total)
+				return 0;
+
+			len = *((const u16 *)(data + index + 2)) + 4;
+			break;
+		case MIPI_SEQ_ELEM_DELAY:
+			len = 4;
+			break;
+		case MIPI_SEQ_ELEM_GPIO:
+			len = 2;
+			break;
+		case MIPI_SEQ_ELEM_I2C:
+			if (index + 7 > total)
+				return 0;
+			len = *(data + index + 6) + 7;
+			break;
+		default:
+			DRM_ERROR("Unknown operation byte\n");
+			return 0;
+		}
+	}
+
+	return 0;
+}
+
+static int goto_next_sequence_v3(const u8 *data, int index, int total)
+{
+	int seq_end;
+	u16 len;
+	u32 size_of_sequence;
+
+	/*
+	 * Could skip sequence based on Size of Sequence alone, but also do some
+	 * checking on the structure.
+	 */
+	if (total < 5) {
+		DRM_ERROR("Too small sequence size\n");
+		return 0;
+	}
+
+	/* Skip Sequence Byte. */
+	index++;
+
+	/*
+	 * Size of Sequence. Excludes the Sequence Byte and the size itself,
+	 * includes MIPI_SEQ_ELEM_END byte, excludes the final MIPI_SEQ_END
+	 * byte.
+	 */
+	size_of_sequence = *((const uint32_t *)(data + index));
+	index += 4;
+
+	seq_end = index + size_of_sequence;
+	if (seq_end > total) {
+		DRM_ERROR("Invalid sequence size\n");
+		return 0;
+	}
+
+	for (; index < total; index += len) {
+		u8 operation_byte = *(data + index);
+		index++;
+
+		if (operation_byte == MIPI_SEQ_ELEM_END) {
+			if (index != seq_end) {
+				DRM_ERROR("Invalid element structure\n");
+				return 0;
+			}
+			return index;
+		}
+
+		len = *(data + index);
+		index++;
+
+		/*
+		 * FIXME: Would be nice to check elements like for v1/v2 in
+		 * goto_next_sequence() above.
+		 */
+		switch (operation_byte) {
+		case MIPI_SEQ_ELEM_SEND_PKT:
+		case MIPI_SEQ_ELEM_DELAY:
+		case MIPI_SEQ_ELEM_GPIO:
+		case MIPI_SEQ_ELEM_I2C:
+		case MIPI_SEQ_ELEM_SPI:
+		case MIPI_SEQ_ELEM_PMIC:
+			break;
+		default:
+			DRM_ERROR("Unknown operation byte %u\n",
+				  operation_byte);
+			break;
+		}
+	}
+
+	return 0;
+}
+
+static void
+parse_mipi_sequence(struct drm_i915_private *dev_priv,
+		    const struct bdb_header *bdb)
+{
+	int panel_type = dev_priv->vbt.panel_type;
+	const struct bdb_mipi_sequence *sequence;
+	const u8 *seq_data;
+	u32 seq_size;
+	u8 *data;
+	int index = 0;
+
+	/* Only our generic panel driver uses the sequence block. */
+	if (dev_priv->vbt.dsi.panel_id != MIPI_DSI_GENERIC_PANEL_ID)
+		return;
+
+	sequence = find_section(bdb, BDB_MIPI_SEQUENCE);
+	if (!sequence) {
+		DRM_DEBUG_KMS("No MIPI Sequence found, parsing complete\n");
+		return;
+	}
+
+	/* Fail gracefully for forward incompatible sequence block. */
+	if (sequence->version >= 4) {
+		DRM_ERROR("Unable to parse MIPI Sequence Block v%u\n",
+			  sequence->version);
+		return;
+	}
+
+	DRM_DEBUG_DRIVER("Found MIPI sequence block v%u\n", sequence->version);
+
+	seq_data = find_panel_sequence_block(sequence, panel_type, &seq_size);
+	if (!seq_data)
+		return;
+
+	data = kmemdup(seq_data, seq_size, GFP_KERNEL);
+	if (!data)
+		return;
+
+	/* Parse the sequences, store pointers to each sequence. */
+	for (;;) {
+		u8 seq_id = *(data + index);
+		if (seq_id == MIPI_SEQ_END)
+			break;
+
+		if (seq_id >= MIPI_SEQ_MAX) {
+			DRM_ERROR("Unknown sequence %u\n", seq_id);
+			goto err;
+		}
+
+		dev_priv->vbt.dsi.sequence[seq_id] = data + index;
+
+		if (sequence->version >= 3)
+			index = goto_next_sequence_v3(data, index, seq_size);
+		else
+			index = goto_next_sequence(data, index, seq_size);
+		if (!index) {
+			DRM_ERROR("Invalid sequence %u\n", seq_id);
+			goto err;
+		}
+	}
+
+	dev_priv->vbt.dsi.data = data;
+	dev_priv->vbt.dsi.size = seq_size;
+	dev_priv->vbt.dsi.seq_version = sequence->version;
+
+	DRM_DEBUG_DRIVER("MIPI related VBT parsing complete\n");
+	return;
+
+err:
+	kfree(data);
+	memset(dev_priv->vbt.dsi.sequence, 0, sizeof(dev_priv->vbt.dsi.sequence));
+}
+
+static u8 translate_iboost(u8 val)
+{
+	static const u8 mapping[] = { 1, 3, 7 }; /* See VBT spec */
+
+	if (val >= ARRAY_SIZE(mapping)) {
+		DRM_DEBUG_KMS("Unsupported I_boost value found in VBT (%d), display may not work properly\n", val);
+		return 0;
+	}
+	return mapping[val];
+}
+
+static void parse_ddi_port(struct drm_i915_private *dev_priv, enum port port,
+			   const struct bdb_header *bdb)
+{
+	union child_device_config *it, *child = NULL;
+	struct ddi_vbt_port_info *info = &dev_priv->vbt.ddi_port_info[port];
+	uint8_t hdmi_level_shift;
+	int i, j;
+	bool is_dvi, is_hdmi, is_dp, is_edp, is_crt;
+	uint8_t aux_channel, ddc_pin;
+	/* Each DDI port can have more than one value on the "DVO Port" field,
+	 * so look for all the possible values for each port and abort if more
+	 * than one is found. */
+	int dvo_ports[][3] = {
+		{DVO_PORT_HDMIA, DVO_PORT_DPA, -1},
+		{DVO_PORT_HDMIB, DVO_PORT_DPB, -1},
+		{DVO_PORT_HDMIC, DVO_PORT_DPC, -1},
+		{DVO_PORT_HDMID, DVO_PORT_DPD, -1},
+		{DVO_PORT_CRT, DVO_PORT_HDMIE, DVO_PORT_DPE},
+	};
+
+	/* Find the child device to use, abort if more than one found. */
+	for (i = 0; i < dev_priv->vbt.child_dev_num; i++) {
+		it = dev_priv->vbt.child_dev + i;
+
+		for (j = 0; j < 3; j++) {
+			if (dvo_ports[port][j] == -1)
+				break;
+
+			if (it->common.dvo_port == dvo_ports[port][j]) {
+				if (child) {
+					DRM_DEBUG_KMS("More than one child device for port %c in VBT.\n",
+						      port_name(port));
+					return;
+				}
+				child = it;
+			}
+		}
+	}
+	if (!child)
+		return;
+
+	aux_channel = child->raw[25];
+	ddc_pin = child->common.ddc_pin;
+
+	is_dvi = child->common.device_type & DEVICE_TYPE_TMDS_DVI_SIGNALING;
+	is_dp = child->common.device_type & DEVICE_TYPE_DISPLAYPORT_OUTPUT;
+	is_crt = child->common.device_type & DEVICE_TYPE_ANALOG_OUTPUT;
+	is_hdmi = is_dvi && (child->common.device_type & DEVICE_TYPE_NOT_HDMI_OUTPUT) == 0;
+	is_edp = is_dp && (child->common.device_type & DEVICE_TYPE_INTERNAL_CONNECTOR);
+
+	info->supports_dvi = is_dvi;
+	info->supports_hdmi = is_hdmi;
+	info->supports_dp = is_dp;
+
+	DRM_DEBUG_KMS("Port %c VBT info: DP:%d HDMI:%d DVI:%d EDP:%d CRT:%d\n",
+		      port_name(port), is_dp, is_hdmi, is_dvi, is_edp, is_crt);
+
+	if (is_edp && is_dvi)
+		DRM_DEBUG_KMS("Internal DP port %c is TMDS compatible\n",
+			      port_name(port));
+	if (is_crt && port != PORT_E)
+		DRM_DEBUG_KMS("Port %c is analog\n", port_name(port));
+	if (is_crt && (is_dvi || is_dp))
+		DRM_DEBUG_KMS("Analog port %c is also DP or TMDS compatible\n",
+			      port_name(port));
+	if (is_dvi && (port == PORT_A || port == PORT_E))
+		DRM_DEBUG_KMS("Port %c is TMDS compatible\n", port_name(port));
+	if (!is_dvi && !is_dp && !is_crt)
+		DRM_DEBUG_KMS("Port %c is not DP/TMDS/CRT compatible\n",
+			      port_name(port));
+	if (is_edp && (port == PORT_B || port == PORT_C || port == PORT_E))
+		DRM_DEBUG_KMS("Port %c is internal DP\n", port_name(port));
+
+	if (is_dvi) {
+		if (port == PORT_E) {
+			info->alternate_ddc_pin = ddc_pin;
+			/* if DDIE share ddc pin with other port, then
+			 * dvi/hdmi couldn't exist on the shared port.
+			 * Otherwise they share the same ddc bin and system
+			 * couldn't communicate with them seperately. */
+			if (ddc_pin == DDC_PIN_B) {
+				dev_priv->vbt.ddi_port_info[PORT_B].supports_dvi = 0;
+				dev_priv->vbt.ddi_port_info[PORT_B].supports_hdmi = 0;
+			} else if (ddc_pin == DDC_PIN_C) {
+				dev_priv->vbt.ddi_port_info[PORT_C].supports_dvi = 0;
+				dev_priv->vbt.ddi_port_info[PORT_C].supports_hdmi = 0;
+			} else if (ddc_pin == DDC_PIN_D) {
+				dev_priv->vbt.ddi_port_info[PORT_D].supports_dvi = 0;
+				dev_priv->vbt.ddi_port_info[PORT_D].supports_hdmi = 0;
+			}
+		} else if (ddc_pin == DDC_PIN_B && port != PORT_B)
+			DRM_DEBUG_KMS("Unexpected DDC pin for port B\n");
+		else if (ddc_pin == DDC_PIN_C && port != PORT_C)
+			DRM_DEBUG_KMS("Unexpected DDC pin for port C\n");
+		else if (ddc_pin == DDC_PIN_D && port != PORT_D)
+			DRM_DEBUG_KMS("Unexpected DDC pin for port D\n");
+	}
+
+	if (is_dp) {
+		if (port == PORT_E) {
+			info->alternate_aux_channel = aux_channel;
+			/* if DDIE share aux channel with other port, then
+			 * DP couldn't exist on the shared port. Otherwise
+			 * they share the same aux channel and system
+			 * couldn't communicate with them seperately. */
+			if (aux_channel == DP_AUX_A)
+				dev_priv->vbt.ddi_port_info[PORT_A].supports_dp = 0;
+			else if (aux_channel == DP_AUX_B)
+				dev_priv->vbt.ddi_port_info[PORT_B].supports_dp = 0;
+			else if (aux_channel == DP_AUX_C)
+				dev_priv->vbt.ddi_port_info[PORT_C].supports_dp = 0;
+			else if (aux_channel == DP_AUX_D)
+				dev_priv->vbt.ddi_port_info[PORT_D].supports_dp = 0;
+		}
+		else if (aux_channel == DP_AUX_A && port != PORT_A)
+			DRM_DEBUG_KMS("Unexpected AUX channel for port A\n");
+		else if (aux_channel == DP_AUX_B && port != PORT_B)
+			DRM_DEBUG_KMS("Unexpected AUX channel for port B\n");
+		else if (aux_channel == DP_AUX_C && port != PORT_C)
+			DRM_DEBUG_KMS("Unexpected AUX channel for port C\n");
+		else if (aux_channel == DP_AUX_D && port != PORT_D)
+			DRM_DEBUG_KMS("Unexpected AUX channel for port D\n");
+	}
+
+	if (bdb->version >= 158) {
+		/* The VBT HDMI level shift values match the table we have. */
+		hdmi_level_shift = child->raw[7] & 0xF;
+		DRM_DEBUG_KMS("VBT HDMI level shift for port %c: %d\n",
+			      port_name(port),
+			      hdmi_level_shift);
+		info->hdmi_level_shift = hdmi_level_shift;
+	}
+
+	/* Parse the I_boost config for SKL and above */
+	if (bdb->version >= 196 && child->common.iboost) {
+		info->dp_boost_level = translate_iboost(child->common.iboost_level & 0xF);
+		DRM_DEBUG_KMS("VBT (e)DP boost level for port %c: %d\n",
+			      port_name(port), info->dp_boost_level);
+		info->hdmi_boost_level = translate_iboost(child->common.iboost_level >> 4);
+		DRM_DEBUG_KMS("VBT HDMI boost level for port %c: %d\n",
+			      port_name(port), info->hdmi_boost_level);
+	}
+}
+
+static void parse_ddi_ports(struct drm_i915_private *dev_priv,
+			    const struct bdb_header *bdb)
+{
+	enum port port;
+
+	if (!HAS_DDI(dev_priv))
+		return;
+
+	if (!dev_priv->vbt.child_dev_num)
+		return;
+
+	if (bdb->version < 155)
+		return;
+
+	for (port = PORT_A; port < I915_MAX_PORTS; port++)
+		parse_ddi_port(dev_priv, port, bdb);
+}
+
+static void
+parse_device_mapping(struct drm_i915_private *dev_priv,
+		     const struct bdb_header *bdb)
+{
+	const struct bdb_general_definitions *p_defs;
+	const union child_device_config *p_child;
+	union child_device_config *child_dev_ptr;
+	int i, child_device_num, count;
+	u8 expected_size;
+	u16 block_size;
+
+	p_defs = find_section(bdb, BDB_GENERAL_DEFINITIONS);
+	if (!p_defs) {
+		DRM_DEBUG_KMS("No general definition block is found, no devices defined.\n");
+		return;
+	}
+	if (bdb->version < 106) {
+		expected_size = 22;
+	} else if (bdb->version < 111) {
+		expected_size = 27;
+	} else if (bdb->version < 195) {
+		BUILD_BUG_ON(sizeof(struct old_child_dev_config) != 33);
+		expected_size = sizeof(struct old_child_dev_config);
+	} else if (bdb->version == 195) {
+		expected_size = 37;
+	} else if (bdb->version <= 197) {
+		expected_size = 38;
+	} else {
+		expected_size = 38;
+		BUILD_BUG_ON(sizeof(*p_child) < 38);
+		DRM_DEBUG_DRIVER("Expected child device config size for VBT version %u not known; assuming %u\n",
+				 bdb->version, expected_size);
+	}
+
+	/* Flag an error for unexpected size, but continue anyway. */
+	if (p_defs->child_dev_size != expected_size)
+		DRM_ERROR("Unexpected child device config size %u (expected %u for VBT version %u)\n",
+			  p_defs->child_dev_size, expected_size, bdb->version);
+
+	/* The legacy sized child device config is the minimum we need. */
+	if (p_defs->child_dev_size < sizeof(struct old_child_dev_config)) {
+		DRM_DEBUG_KMS("Child device config size %u is too small.\n",
+			      p_defs->child_dev_size);
+		return;
+	}
+
+	/* get the block size of general definitions */
+	block_size = get_blocksize(p_defs);
+	/* get the number of child device */
+	child_device_num = (block_size - sizeof(*p_defs)) /
+				p_defs->child_dev_size;
+	count = 0;
+	/* get the number of child device that is present */
+	for (i = 0; i < child_device_num; i++) {
+		p_child = child_device_ptr(p_defs, i);
+		if (!p_child->common.device_type) {
+			/* skip the device block if device type is invalid */
+			continue;
+		}
+		count++;
+	}
+	if (!count) {
+		DRM_DEBUG_KMS("no child dev is parsed from VBT\n");
+		return;
+	}
+	dev_priv->vbt.child_dev = kcalloc(count, sizeof(*p_child), GFP_KERNEL);
+	if (!dev_priv->vbt.child_dev) {
+		DRM_DEBUG_KMS("No memory space for child device\n");
+		return;
+	}
+
+	dev_priv->vbt.child_dev_num = count;
+	count = 0;
+	for (i = 0; i < child_device_num; i++) {
+		p_child = child_device_ptr(p_defs, i);
+		if (!p_child->common.device_type) {
+			/* skip the device block if device type is invalid */
+			continue;
+		}
+
+		child_dev_ptr = dev_priv->vbt.child_dev + count;
+		count++;
+
+		/*
+		 * Copy as much as we know (sizeof) and is available
+		 * (child_dev_size) of the child device. Accessing the data must
+		 * depend on VBT version.
+		 */
+		memcpy(child_dev_ptr, p_child,
+		       min_t(size_t, p_defs->child_dev_size, sizeof(*p_child)));
+
+		/*
+		 * copied full block, now init values when they are not
+		 * available in current version
+		 */
+		if (bdb->version < 196) {
+			/* Set default values for bits added from v196 */
+			child_dev_ptr->common.iboost = 0;
+			child_dev_ptr->common.hpd_invert = 0;
+		}
+
+		if (bdb->version < 192)
+			child_dev_ptr->common.lspcon = 0;
+	}
+	return;
+}
+
+static void
+init_vbt_defaults(struct drm_i915_private *dev_priv)
+{
+	enum port port;
+
+	dev_priv->vbt.crt_ddc_pin = GMBUS_PIN_VGADDC;
+
+	/* Default to having backlight */
+	dev_priv->vbt.backlight.present = true;
+
+	/* LFP panel data */
+	dev_priv->vbt.lvds_dither = 1;
+	dev_priv->vbt.lvds_vbt = 0;
+
+	/* SDVO panel data */
+	dev_priv->vbt.sdvo_lvds_vbt_mode = NULL;
+
+	/* general features */
+	dev_priv->vbt.int_tv_support = 1;
+	dev_priv->vbt.int_crt_support = 1;
+
+	/* Default to using SSC */
+	dev_priv->vbt.lvds_use_ssc = 1;
+	/*
+	 * Core/SandyBridge/IvyBridge use alternative (120MHz) reference
+	 * clock for LVDS.
+	 */
+	dev_priv->vbt.lvds_ssc_freq = intel_bios_ssc_frequency(dev_priv,
+			!HAS_PCH_SPLIT(dev_priv));
+	DRM_DEBUG_KMS("Set default to SSC at %d kHz\n", dev_priv->vbt.lvds_ssc_freq);
+
+	for (port = PORT_A; port < I915_MAX_PORTS; port++) {
+		struct ddi_vbt_port_info *info =
+			&dev_priv->vbt.ddi_port_info[port];
+
+		info->hdmi_level_shift = HDMI_LEVEL_SHIFT_UNKNOWN;
+
+		info->supports_dvi = (port != PORT_A && port != PORT_E);
+		info->supports_hdmi = info->supports_dvi;
+		info->supports_dp = (port != PORT_E);
+	}
+}
+
+static const struct bdb_header *get_bdb_header(const struct vbt_header *vbt)
+{
+	const void *_vbt = vbt;
+
+	return _vbt + vbt->bdb_offset;
+}
+
+/**
+ * intel_bios_is_valid_vbt - does the given buffer contain a valid VBT
+ * @buf:	pointer to a buffer to validate
+ * @size:	size of the buffer
+ *
+ * Returns true on valid VBT.
+ */
+bool intel_bios_is_valid_vbt(const void *buf, size_t size)
+{
+	const struct vbt_header *vbt = buf;
+	const struct bdb_header *bdb;
+
+	if (!vbt)
+		return false;
+
+	if (sizeof(struct vbt_header) > size) {
+		DRM_DEBUG_DRIVER("VBT header incomplete\n");
+		return false;
+	}
+
+	if (memcmp(vbt->signature, "$VBT", 4)) {
+		DRM_DEBUG_DRIVER("VBT invalid signature\n");
+		return false;
+	}
+
+	if (vbt->bdb_offset + sizeof(struct bdb_header) > size) {
+		DRM_DEBUG_DRIVER("BDB header incomplete\n");
+		return false;
+	}
+
+	bdb = get_bdb_header(vbt);
+	if (vbt->bdb_offset + bdb->bdb_size > size) {
+		DRM_DEBUG_DRIVER("BDB incomplete\n");
+		return false;
+	}
+
+	return vbt;
+}
+
+static const struct vbt_header *find_vbt(void __iomem *bios, size_t size)
+{
+	size_t i;
+
+	/* Scour memory looking for the VBT signature. */
+	for (i = 0; i + 4 < size; i++) {
+		void *vbt;
+
+		if (ioread32(bios + i) != *((const u32 *) "$VBT"))
+			continue;
+
+		/*
+		 * This is the one place where we explicitly discard the address
+		 * space (__iomem) of the BIOS/VBT.
+		 */
+		vbt = (void __force *) bios + i;
+		if (intel_bios_is_valid_vbt(vbt, size - i))
+			return vbt;
+
+		break;
+	}
+
+	return NULL;
+}
+
+/**
+ * intel_bios_init - find VBT and initialize settings from the BIOS
+ * @dev_priv: i915 device instance
+ *
+ * Loads the Video BIOS and checks that the VBT exists.  Sets scratch registers
+ * to appropriate values.
+ *
+ * Returns 0 on success, nonzero on failure.
+ */
+int
+intel_bios_init(struct drm_i915_private *dev_priv)
+{
+	struct pci_dev *pdev = dev_priv->dev->pdev;
+	const struct vbt_header *vbt = dev_priv->opregion.vbt;
+	const struct bdb_header *bdb;
+	u8 __iomem *bios = NULL;
+
+	if (HAS_PCH_NOP(dev_priv))
+		return -ENODEV;
+
+	init_vbt_defaults(dev_priv);
+
+	if (!vbt) {
+		size_t size;
+
+		bios = pci_map_rom(pdev, &size);
+		if (!bios)
+			return -1;
+
+		vbt = find_vbt(bios, size);
+		if (!vbt) {
+			pci_unmap_rom(pdev, bios);
+			return -1;
+		}
+
+		DRM_DEBUG_KMS("Found valid VBT in PCI ROM\n");
+	}
+
+	bdb = get_bdb_header(vbt);
+
+	DRM_DEBUG_KMS("VBT signature \"%.*s\", BDB version %d\n",
+		      (int)sizeof(vbt->signature), vbt->signature, bdb->version);
+
+	/* Grab useful general definitions */
+	parse_general_features(dev_priv, bdb);
+	parse_general_definitions(dev_priv, bdb);
+	parse_lfp_panel_data(dev_priv, bdb);
+	parse_lfp_backlight(dev_priv, bdb);
+	parse_sdvo_panel_data(dev_priv, bdb);
+	parse_sdvo_device_mapping(dev_priv, bdb);
+	parse_device_mapping(dev_priv, bdb);
+	parse_driver_features(dev_priv, bdb);
+	parse_edp(dev_priv, bdb);
+	parse_psr(dev_priv, bdb);
+	parse_mipi_config(dev_priv, bdb);
+	parse_mipi_sequence(dev_priv, bdb);
+	parse_ddi_ports(dev_priv, bdb);
+
+	if (bios)
+		pci_unmap_rom(pdev, bios);
+
+	return 0;
+}
+
+/**
+ * intel_bios_is_tv_present - is integrated TV present in VBT
+ * @dev_priv:	i915 device instance
+ *
+ * Return true if TV is present. If no child devices were parsed from VBT,
+ * assume TV is present.
+ */
+bool intel_bios_is_tv_present(struct drm_i915_private *dev_priv)
+{
+	union child_device_config *p_child;
+	int i;
+
+	if (!dev_priv->vbt.int_tv_support)
+		return false;
+
+	if (!dev_priv->vbt.child_dev_num)
+		return true;
+
+	for (i = 0; i < dev_priv->vbt.child_dev_num; i++) {
+		p_child = dev_priv->vbt.child_dev + i;
+		/*
+		 * If the device type is not TV, continue.
+		 */
+		switch (p_child->old.device_type) {
+		case DEVICE_TYPE_INT_TV:
+		case DEVICE_TYPE_TV:
+		case DEVICE_TYPE_TV_SVIDEO_COMPOSITE:
+			break;
+		default:
+			continue;
+		}
+		/* Only when the addin_offset is non-zero, it is regarded
+		 * as present.
+		 */
+		if (p_child->old.addin_offset)
+			return true;
+	}
+
+	return false;
+}
+
+/**
+ * intel_bios_is_lvds_present - is LVDS present in VBT
+ * @dev_priv:	i915 device instance
+ * @i2c_pin:	i2c pin for LVDS if present
+ *
+ * Return true if LVDS is present. If no child devices were parsed from VBT,
+ * assume LVDS is present.
+ */
+bool intel_bios_is_lvds_present(struct drm_i915_private *dev_priv, u8 *i2c_pin)
+{
+	int i;
+
+	if (!dev_priv->vbt.child_dev_num)
+		return true;
+
+	for (i = 0; i < dev_priv->vbt.child_dev_num; i++) {
+		union child_device_config *uchild = dev_priv->vbt.child_dev + i;
+		struct old_child_dev_config *child = &uchild->old;
+
+		/* If the device type is not LFP, continue.
+		 * We have to check both the new identifiers as well as the
+		 * old for compatibility with some BIOSes.
+		 */
+		if (child->device_type != DEVICE_TYPE_INT_LFP &&
+		    child->device_type != DEVICE_TYPE_LFP)
+			continue;
+
+		if (intel_gmbus_is_valid_pin(dev_priv, child->i2c_pin))
+			*i2c_pin = child->i2c_pin;
+
+		/* However, we cannot trust the BIOS writers to populate
+		 * the VBT correctly.  Since LVDS requires additional
+		 * information from AIM blocks, a non-zero addin offset is
+		 * a good indicator that the LVDS is actually present.
+		 */
+		if (child->addin_offset)
+			return true;
+
+		/* But even then some BIOS writers perform some black magic
+		 * and instantiate the device without reference to any
+		 * additional data.  Trust that if the VBT was written into
+		 * the OpRegion then they have validated the LVDS's existence.
+		 */
+		if (dev_priv->opregion.vbt)
+			return true;
+	}
+
+	return false;
+}
+
+/**
+ * intel_bios_is_port_present - is the specified digital port present
+ * @dev_priv:	i915 device instance
+ * @port:	port to check
+ *
+ * Return true if the device in %port is present.
+ */
+bool intel_bios_is_port_present(struct drm_i915_private *dev_priv, enum port port)
+{
+	static const struct {
+		u16 dp, hdmi;
+	} port_mapping[] = {
+		[PORT_B] = { DVO_PORT_DPB, DVO_PORT_HDMIB, },
+		[PORT_C] = { DVO_PORT_DPC, DVO_PORT_HDMIC, },
+		[PORT_D] = { DVO_PORT_DPD, DVO_PORT_HDMID, },
+		[PORT_E] = { DVO_PORT_DPE, DVO_PORT_HDMIE, },
+	};
+	int i;
+
+	/* FIXME maybe deal with port A as well? */
+	if (WARN_ON(port == PORT_A) || port >= ARRAY_SIZE(port_mapping))
+		return false;
+
+	if (!dev_priv->vbt.child_dev_num)
+		return false;
+
+	for (i = 0; i < dev_priv->vbt.child_dev_num; i++) {
+		const union child_device_config *p_child =
+			&dev_priv->vbt.child_dev[i];
+		if ((p_child->common.dvo_port == port_mapping[port].dp ||
+		     p_child->common.dvo_port == port_mapping[port].hdmi) &&
+		    (p_child->common.device_type & (DEVICE_TYPE_TMDS_DVI_SIGNALING |
+						    DEVICE_TYPE_DISPLAYPORT_OUTPUT)))
+			return true;
+	}
+
+	return false;
+}
+
+/**
+ * intel_bios_is_port_edp - is the device in given port eDP
+ * @dev_priv:	i915 device instance
+ * @port:	port to check
+ *
+ * Return true if the device in %port is eDP.
+ */
+bool intel_bios_is_port_edp(struct drm_i915_private *dev_priv, enum port port)
+{
+	union child_device_config *p_child;
+	static const short port_mapping[] = {
+		[PORT_B] = DVO_PORT_DPB,
+		[PORT_C] = DVO_PORT_DPC,
+		[PORT_D] = DVO_PORT_DPD,
+		[PORT_E] = DVO_PORT_DPE,
+	};
+	int i;
+
+	if (!dev_priv->vbt.child_dev_num)
+		return false;
+
+	for (i = 0; i < dev_priv->vbt.child_dev_num; i++) {
+		p_child = dev_priv->vbt.child_dev + i;
+
+		if (p_child->common.dvo_port == port_mapping[port] &&
+		    (p_child->common.device_type & DEVICE_TYPE_eDP_BITS) ==
+		    (DEVICE_TYPE_eDP & DEVICE_TYPE_eDP_BITS))
+			return true;
+	}
+
+	return false;
+}
+
+bool intel_bios_is_port_dp_dual_mode(struct drm_i915_private *dev_priv, enum port port)
+{
+	static const struct {
+		u16 dp, hdmi;
+	} port_mapping[] = {
+		/*
+		 * Buggy VBTs may declare DP ports as having
+		 * HDMI type dvo_port :( So let's check both.
+		 */
+		[PORT_B] = { DVO_PORT_DPB, DVO_PORT_HDMIB, },
+		[PORT_C] = { DVO_PORT_DPC, DVO_PORT_HDMIC, },
+		[PORT_D] = { DVO_PORT_DPD, DVO_PORT_HDMID, },
+		[PORT_E] = { DVO_PORT_DPE, DVO_PORT_HDMIE, },
+	};
+	int i;
+
+	if (port == PORT_A || port >= ARRAY_SIZE(port_mapping))
+		return false;
+
+	if (!dev_priv->vbt.child_dev_num)
+		return false;
+
+	for (i = 0; i < dev_priv->vbt.child_dev_num; i++) {
+		const union child_device_config *p_child =
+			&dev_priv->vbt.child_dev[i];
+
+		if ((p_child->common.dvo_port == port_mapping[port].dp ||
+		     p_child->common.dvo_port == port_mapping[port].hdmi) &&
+		    (p_child->common.device_type & DEVICE_TYPE_DP_DUAL_MODE_BITS) ==
+		    (DEVICE_TYPE_DP_DUAL_MODE & DEVICE_TYPE_DP_DUAL_MODE_BITS))
+			return true;
+	}
+
+	return false;
+}
+
+/**
+ * intel_bios_is_dsi_present - is DSI present in VBT
+ * @dev_priv:	i915 device instance
+ * @port:	port for DSI if present
+ *
+ * Return true if DSI is present, and return the port in %port.
+ */
+bool intel_bios_is_dsi_present(struct drm_i915_private *dev_priv,
+			       enum port *port)
+{
+	union child_device_config *p_child;
+	u8 dvo_port;
+	int i;
+
+	for (i = 0; i < dev_priv->vbt.child_dev_num; i++) {
+		p_child = dev_priv->vbt.child_dev + i;
+
+		if (!(p_child->common.device_type & DEVICE_TYPE_MIPI_OUTPUT))
+			continue;
+
+		dvo_port = p_child->common.dvo_port;
+
+		switch (dvo_port) {
+		case DVO_PORT_MIPIA:
+		case DVO_PORT_MIPIC:
+			if (port)
+				*port = dvo_port - DVO_PORT_MIPIA;
+			return true;
+		case DVO_PORT_MIPIB:
+		case DVO_PORT_MIPID:
+			DRM_DEBUG_KMS("VBT has unsupported DSI port %c\n",
+				      port_name(dvo_port - DVO_PORT_MIPIA));
+			break;
+		}
+	}
+
+	return false;
+}
+
+/**
+ * intel_bios_is_port_hpd_inverted - is HPD inverted for %port
+ * @dev_priv:	i915 device instance
+ * @port:	port to check
+ *
+ * Return true if HPD should be inverted for %port.
+ */
+bool
+intel_bios_is_port_hpd_inverted(struct drm_i915_private *dev_priv,
+				enum port port)
+{
+	int i;
+
+	if (WARN_ON_ONCE(!IS_BROXTON(dev_priv)))
+		return false;
+
+	for (i = 0; i < dev_priv->vbt.child_dev_num; i++) {
+		if (!dev_priv->vbt.child_dev[i].common.hpd_invert)
+			continue;
+
+		switch (dev_priv->vbt.child_dev[i].common.dvo_port) {
+		case DVO_PORT_DPA:
+		case DVO_PORT_HDMIA:
+			if (port == PORT_A)
+				return true;
+			break;
+		case DVO_PORT_DPB:
+		case DVO_PORT_HDMIB:
+			if (port == PORT_B)
+				return true;
+			break;
+		case DVO_PORT_DPC:
+		case DVO_PORT_HDMIC:
+			if (port == PORT_C)
+				return true;
+			break;
+		default:
+			break;
+		}
+	}
+
+	return false;
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/i915/intel_bios.h
@@ -0,0 +1,203 @@
+/*
+ * Copyright © 2016 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+/*
+ * Please use intel_vbt_defs.h for VBT private data, to hide and abstract away
+ * the VBT from the rest of the driver. Add the parsed, clean data to struct
+ * intel_vbt_data within struct drm_i915_private.
+ */
+
+#ifndef _INTEL_BIOS_H_
+#define _INTEL_BIOS_H_
+
+struct edp_power_seq {
+	u16 t1_t3;
+	u16 t8;
+	u16 t9;
+	u16 t10;
+	u16 t11_t12;
+} __packed;
+
+/* MIPI Sequence Block definitions */
+enum mipi_seq {
+	MIPI_SEQ_END = 0,
+	MIPI_SEQ_ASSERT_RESET,
+	MIPI_SEQ_INIT_OTP,
+	MIPI_SEQ_DISPLAY_ON,
+	MIPI_SEQ_DISPLAY_OFF,
+	MIPI_SEQ_DEASSERT_RESET,
+	MIPI_SEQ_BACKLIGHT_ON,		/* sequence block v2+ */
+	MIPI_SEQ_BACKLIGHT_OFF,		/* sequence block v2+ */
+	MIPI_SEQ_TEAR_ON,		/* sequence block v2+ */
+	MIPI_SEQ_TEAR_OFF,		/* sequence block v3+ */
+	MIPI_SEQ_POWER_ON,		/* sequence block v3+ */
+	MIPI_SEQ_POWER_OFF,		/* sequence block v3+ */
+	MIPI_SEQ_MAX
+};
+
+enum mipi_seq_element {
+	MIPI_SEQ_ELEM_END = 0,
+	MIPI_SEQ_ELEM_SEND_PKT,
+	MIPI_SEQ_ELEM_DELAY,
+	MIPI_SEQ_ELEM_GPIO,
+	MIPI_SEQ_ELEM_I2C,		/* sequence block v2+ */
+	MIPI_SEQ_ELEM_SPI,		/* sequence block v3+ */
+	MIPI_SEQ_ELEM_PMIC,		/* sequence block v3+ */
+	MIPI_SEQ_ELEM_MAX
+};
+
+#define MIPI_DSI_UNDEFINED_PANEL_ID	0
+#define MIPI_DSI_GENERIC_PANEL_ID	1
+
+struct mipi_config {
+	u16 panel_id;
+
+	/* General Params */
+	u32 enable_dithering:1;
+	u32 rsvd1:1;
+	u32 is_bridge:1;
+
+	u32 panel_arch_type:2;
+	u32 is_cmd_mode:1;
+
+#define NON_BURST_SYNC_PULSE	0x1
+#define NON_BURST_SYNC_EVENTS	0x2
+#define BURST_MODE		0x3
+	u32 video_transfer_mode:2;
+
+	u32 cabc_supported:1;
+#define PPS_BLC_PMIC   0
+#define PPS_BLC_SOC    1
+	u32 pwm_blc:1;
+
+	/* Bit 13:10 */
+#define PIXEL_FORMAT_RGB565			0x1
+#define PIXEL_FORMAT_RGB666			0x2
+#define PIXEL_FORMAT_RGB666_LOOSELY_PACKED	0x3
+#define PIXEL_FORMAT_RGB888			0x4
+	u32 videomode_color_format:4;
+
+	/* Bit 15:14 */
+#define ENABLE_ROTATION_0	0x0
+#define ENABLE_ROTATION_90	0x1
+#define ENABLE_ROTATION_180	0x2
+#define ENABLE_ROTATION_270	0x3
+	u32 rotation:2;
+	u32 bta_enabled:1;
+	u32 rsvd2:15;
+
+	/* 2 byte Port Description */
+#define DUAL_LINK_NOT_SUPPORTED	0
+#define DUAL_LINK_FRONT_BACK	1
+#define DUAL_LINK_PIXEL_ALT	2
+	u16 dual_link:2;
+	u16 lane_cnt:2;
+	u16 pixel_overlap:3;
+	u16 rsvd3:9;
+
+	u16 rsvd4;
+
+	u8 rsvd5;
+	u32 target_burst_mode_freq;
+	u32 dsi_ddr_clk;
+	u32 bridge_ref_clk;
+
+#define  BYTE_CLK_SEL_20MHZ		0
+#define  BYTE_CLK_SEL_10MHZ		1
+#define  BYTE_CLK_SEL_5MHZ		2
+	u8 byte_clk_sel:2;
+
+	u8 rsvd6:6;
+
+	/* DPHY Flags */
+	u16 dphy_param_valid:1;
+	u16 eot_pkt_disabled:1;
+	u16 enable_clk_stop:1;
+	u16 rsvd7:13;
+
+	u32 hs_tx_timeout;
+	u32 lp_rx_timeout;
+	u32 turn_around_timeout;
+	u32 device_reset_timer;
+	u32 master_init_timer;
+	u32 dbi_bw_timer;
+	u32 lp_byte_clk_val;
+
+	/*  4 byte Dphy Params */
+	u32 prepare_cnt:6;
+	u32 rsvd8:2;
+	u32 clk_zero_cnt:8;
+	u32 trail_cnt:5;
+	u32 rsvd9:3;
+	u32 exit_zero_cnt:6;
+	u32 rsvd10:2;
+
+	u32 clk_lane_switch_cnt;
+	u32 hl_switch_cnt;
+
+	u32 rsvd11[6];
+
+	/* timings based on dphy spec */
+	u8 tclk_miss;
+	u8 tclk_post;
+	u8 rsvd12;
+	u8 tclk_pre;
+	u8 tclk_prepare;
+	u8 tclk_settle;
+	u8 tclk_term_enable;
+	u8 tclk_trail;
+	u16 tclk_prepare_clkzero;
+	u8 rsvd13;
+	u8 td_term_enable;
+	u8 teot;
+	u8 ths_exit;
+	u8 ths_prepare;
+	u16 ths_prepare_hszero;
+	u8 rsvd14;
+	u8 ths_settle;
+	u8 ths_skip;
+	u8 ths_trail;
+	u8 tinit;
+	u8 tlpx;
+	u8 rsvd15[3];
+
+	/* GPIOs */
+	u8 panel_enable;
+	u8 bl_enable;
+	u8 pwm_enable;
+	u8 reset_r_n;
+	u8 pwr_down_r;
+	u8 stdby_r_n;
+
+} __packed;
+
+/* all delays have a unit of 100us */
+struct mipi_pps_data {
+	u16 panel_on_delay;
+	u16 bl_enable_delay;
+	u16 bl_disable_delay;
+	u16 panel_off_delay;
+	u16 panel_power_cycle_delay;
+} __packed;
+
+#endif /* _INTEL_BIOS_H_ */
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/i915/intel_color.c
@@ -0,0 +1,553 @@
+/*
+ * Copyright © 2016 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#include "intel_drv.h"
+
+#define CTM_COEFF_SIGN	(1ULL << 63)
+
+#define CTM_COEFF_1_0	(1ULL << 32)
+#define CTM_COEFF_2_0	(CTM_COEFF_1_0 << 1)
+#define CTM_COEFF_4_0	(CTM_COEFF_2_0 << 1)
+#define CTM_COEFF_8_0	(CTM_COEFF_4_0 << 1)
+#define CTM_COEFF_0_5	(CTM_COEFF_1_0 >> 1)
+#define CTM_COEFF_0_25	(CTM_COEFF_0_5 >> 1)
+#define CTM_COEFF_0_125	(CTM_COEFF_0_25 >> 1)
+
+#define CTM_COEFF_LIMITED_RANGE ((235ULL - 16ULL) * CTM_COEFF_1_0 / 255)
+
+#define CTM_COEFF_NEGATIVE(coeff)	(((coeff) & CTM_COEFF_SIGN) != 0)
+#define CTM_COEFF_ABS(coeff)		((coeff) & (CTM_COEFF_SIGN - 1))
+
+#define LEGACY_LUT_LENGTH		(sizeof(struct drm_color_lut) * 256)
+
+/*
+ * Extract the CSC coefficient from a CTM coefficient (in U32.32 fixed point
+ * format). This macro takes the coefficient we want transformed and the
+ * number of fractional bits.
+ *
+ * We only have a 9 bits precision window which slides depending on the value
+ * of the CTM coefficient and we write the value from bit 3. We also round the
+ * value.
+ */
+#define I9XX_CSC_COEFF_FP(coeff, fbits)	\
+	(clamp_val(((coeff) >> (32 - (fbits) - 3)) + 4, 0, 0xfff) & 0xff8)
+
+#define I9XX_CSC_COEFF_LIMITED_RANGE	\
+	I9XX_CSC_COEFF_FP(CTM_COEFF_LIMITED_RANGE, 9)
+#define I9XX_CSC_COEFF_1_0		\
+	((7 << 12) | I9XX_CSC_COEFF_FP(CTM_COEFF_1_0, 8))
+
+static bool crtc_state_is_legacy(struct drm_crtc_state *state)
+{
+	return !state->degamma_lut &&
+		!state->ctm &&
+		state->gamma_lut &&
+		state->gamma_lut->length == LEGACY_LUT_LENGTH;
+}
+
+/*
+ * When using limited range, multiply the matrix given by userspace by
+ * the matrix that we would use for the limited range. We do the
+ * multiplication in U2.30 format.
+ */
+static void ctm_mult_by_limited(uint64_t *result, int64_t *input)
+{
+	int i;
+
+	for (i = 0; i < 9; i++)
+		result[i] = 0;
+
+	for (i = 0; i < 3; i++) {
+		int64_t user_coeff = input[i * 3 + i];
+		uint64_t limited_coeff = CTM_COEFF_LIMITED_RANGE >> 2;
+		uint64_t abs_coeff = clamp_val(CTM_COEFF_ABS(user_coeff),
+					       0,
+					       CTM_COEFF_4_0 - 1) >> 2;
+
+		result[i * 3 + i] = (limited_coeff * abs_coeff) >> 27;
+		if (CTM_COEFF_NEGATIVE(user_coeff))
+			result[i * 3 + i] |= CTM_COEFF_SIGN;
+	}
+}
+
+/* Set up the pipe CSC unit. */
+static void i9xx_load_csc_matrix(struct drm_crtc_state *crtc_state)
+{
+	struct drm_crtc *crtc = crtc_state->crtc;
+	struct drm_device *dev = crtc->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	int i, pipe = intel_crtc->pipe;
+	uint16_t coeffs[9] = { 0, };
+
+	if (crtc_state->ctm) {
+		struct drm_color_ctm *ctm =
+			(struct drm_color_ctm *)crtc_state->ctm->data;
+		uint64_t input[9] = { 0, };
+
+		if (intel_crtc->config->limited_color_range) {
+			ctm_mult_by_limited(input, ctm->matrix);
+		} else {
+			for (i = 0; i < ARRAY_SIZE(input); i++)
+				input[i] = ctm->matrix[i];
+		}
+
+		/*
+		 * Convert fixed point S31.32 input to format supported by the
+		 * hardware.
+		 */
+		for (i = 0; i < ARRAY_SIZE(coeffs); i++) {
+			uint64_t abs_coeff = ((1ULL << 63) - 1) & input[i];
+
+			/*
+			 * Clamp input value to min/max supported by
+			 * hardware.
+			 */
+			abs_coeff = clamp_val(abs_coeff, 0, CTM_COEFF_4_0 - 1);
+
+			/* sign bit */
+			if (CTM_COEFF_NEGATIVE(input[i]))
+				coeffs[i] |= 1 << 15;
+
+			if (abs_coeff < CTM_COEFF_0_125)
+				coeffs[i] |= (3 << 12) |
+					I9XX_CSC_COEFF_FP(abs_coeff, 12);
+			else if (abs_coeff < CTM_COEFF_0_25)
+				coeffs[i] |= (2 << 12) |
+					I9XX_CSC_COEFF_FP(abs_coeff, 11);
+			else if (abs_coeff < CTM_COEFF_0_5)
+				coeffs[i] |= (1 << 12) |
+					I9XX_CSC_COEFF_FP(abs_coeff, 10);
+			else if (abs_coeff < CTM_COEFF_1_0)
+				coeffs[i] |= I9XX_CSC_COEFF_FP(abs_coeff, 9);
+			else if (abs_coeff < CTM_COEFF_2_0)
+				coeffs[i] |= (7 << 12) |
+					I9XX_CSC_COEFF_FP(abs_coeff, 8);
+			else
+				coeffs[i] |= (6 << 12) |
+					I9XX_CSC_COEFF_FP(abs_coeff, 7);
+		}
+	} else {
+		/*
+		 * Load an identity matrix if no coefficients are provided.
+		 *
+		 * TODO: Check what kind of values actually come out of the
+		 * pipe with these coeff/postoff values and adjust to get the
+		 * best accuracy. Perhaps we even need to take the bpc value
+		 * into consideration.
+		 */
+		for (i = 0; i < 3; i++) {
+			if (intel_crtc->config->limited_color_range)
+				coeffs[i * 3 + i] =
+					I9XX_CSC_COEFF_LIMITED_RANGE;
+			else
+				coeffs[i * 3 + i] = I9XX_CSC_COEFF_1_0;
+		}
+	}
+
+	I915_WRITE(PIPE_CSC_COEFF_RY_GY(pipe), coeffs[0] << 16 | coeffs[1]);
+	I915_WRITE(PIPE_CSC_COEFF_BY(pipe), coeffs[2] << 16);
+
+	I915_WRITE(PIPE_CSC_COEFF_RU_GU(pipe), coeffs[3] << 16 | coeffs[4]);
+	I915_WRITE(PIPE_CSC_COEFF_BU(pipe), coeffs[5] << 16);
+
+	I915_WRITE(PIPE_CSC_COEFF_RV_GV(pipe), coeffs[6] << 16 | coeffs[7]);
+	I915_WRITE(PIPE_CSC_COEFF_BV(pipe), coeffs[8] << 16);
+
+	I915_WRITE(PIPE_CSC_PREOFF_HI(pipe), 0);
+	I915_WRITE(PIPE_CSC_PREOFF_ME(pipe), 0);
+	I915_WRITE(PIPE_CSC_PREOFF_LO(pipe), 0);
+
+	if (INTEL_INFO(dev)->gen > 6) {
+		uint16_t postoff = 0;
+
+		if (intel_crtc->config->limited_color_range)
+			postoff = (16 * (1 << 12) / 255) & 0x1fff;
+
+		I915_WRITE(PIPE_CSC_POSTOFF_HI(pipe), postoff);
+		I915_WRITE(PIPE_CSC_POSTOFF_ME(pipe), postoff);
+		I915_WRITE(PIPE_CSC_POSTOFF_LO(pipe), postoff);
+
+		I915_WRITE(PIPE_CSC_MODE(pipe), 0);
+	} else {
+		uint32_t mode = CSC_MODE_YUV_TO_RGB;
+
+		if (intel_crtc->config->limited_color_range)
+			mode |= CSC_BLACK_SCREEN_OFFSET;
+
+		I915_WRITE(PIPE_CSC_MODE(pipe), mode);
+	}
+}
+
+/*
+ * Set up the pipe CSC unit on CherryView.
+ */
+static void cherryview_load_csc_matrix(struct drm_crtc_state *state)
+{
+	struct drm_crtc *crtc = state->crtc;
+	struct drm_device *dev = crtc->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	int pipe = to_intel_crtc(crtc)->pipe;
+	uint32_t mode;
+
+	if (state->ctm) {
+		struct drm_color_ctm *ctm =
+			(struct drm_color_ctm *) state->ctm->data;
+		uint16_t coeffs[9] = { 0, };
+		int i;
+
+		for (i = 0; i < ARRAY_SIZE(coeffs); i++) {
+			uint64_t abs_coeff =
+				((1ULL << 63) - 1) & ctm->matrix[i];
+
+			/* Round coefficient. */
+			abs_coeff += 1 << (32 - 13);
+			/* Clamp to hardware limits. */
+			abs_coeff = clamp_val(abs_coeff, 0, CTM_COEFF_8_0 - 1);
+
+			/* Write coefficients in S3.12 format. */
+			if (ctm->matrix[i] & (1ULL << 63))
+				coeffs[i] = 1 << 15;
+			coeffs[i] |= ((abs_coeff >> 32) & 7) << 12;
+			coeffs[i] |= (abs_coeff >> 20) & 0xfff;
+		}
+
+		I915_WRITE(CGM_PIPE_CSC_COEFF01(pipe),
+			   coeffs[1] << 16 | coeffs[0]);
+		I915_WRITE(CGM_PIPE_CSC_COEFF23(pipe),
+			   coeffs[3] << 16 | coeffs[2]);
+		I915_WRITE(CGM_PIPE_CSC_COEFF45(pipe),
+			   coeffs[5] << 16 | coeffs[4]);
+		I915_WRITE(CGM_PIPE_CSC_COEFF67(pipe),
+			   coeffs[7] << 16 | coeffs[6]);
+		I915_WRITE(CGM_PIPE_CSC_COEFF8(pipe), coeffs[8]);
+	}
+
+	mode = (state->ctm ? CGM_PIPE_MODE_CSC : 0);
+	if (!crtc_state_is_legacy(state)) {
+		mode |= (state->degamma_lut ? CGM_PIPE_MODE_DEGAMMA : 0) |
+			(state->gamma_lut ? CGM_PIPE_MODE_GAMMA : 0);
+	}
+	I915_WRITE(CGM_PIPE_MODE(pipe), mode);
+}
+
+void intel_color_set_csc(struct drm_crtc_state *crtc_state)
+{
+	struct drm_device *dev = crtc_state->crtc->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	if (dev_priv->display.load_csc_matrix)
+		dev_priv->display.load_csc_matrix(crtc_state);
+}
+
+/* Loads the legacy palette/gamma unit for the CRTC. */
+static void i9xx_load_luts_internal(struct drm_crtc *crtc,
+				    struct drm_property_blob *blob)
+{
+	struct drm_device *dev = crtc->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	enum pipe pipe = intel_crtc->pipe;
+	int i;
+
+	if (HAS_GMCH_DISPLAY(dev)) {
+		if (intel_crtc->config->has_dsi_encoder)
+			assert_dsi_pll_enabled(dev_priv);
+		else
+			assert_pll_enabled(dev_priv, pipe);
+	}
+
+	if (blob) {
+		struct drm_color_lut *lut = (struct drm_color_lut *) blob->data;
+		for (i = 0; i < 256; i++) {
+			uint32_t word =
+				(drm_color_lut_extract(lut[i].red, 8) << 16) |
+				(drm_color_lut_extract(lut[i].green, 8) << 8) |
+				drm_color_lut_extract(lut[i].blue, 8);
+
+			if (HAS_GMCH_DISPLAY(dev))
+				I915_WRITE(PALETTE(pipe, i), word);
+			else
+				I915_WRITE(LGC_PALETTE(pipe, i), word);
+		}
+	} else {
+		for (i = 0; i < 256; i++) {
+			uint32_t word = (i << 16) | (i << 8) | i;
+
+			if (HAS_GMCH_DISPLAY(dev))
+				I915_WRITE(PALETTE(pipe, i), word);
+			else
+				I915_WRITE(LGC_PALETTE(pipe, i), word);
+		}
+	}
+}
+
+static void i9xx_load_luts(struct drm_crtc_state *crtc_state)
+{
+	i9xx_load_luts_internal(crtc_state->crtc, crtc_state->gamma_lut);
+}
+
+/* Loads the legacy palette/gamma unit for the CRTC on Haswell. */
+static void haswell_load_luts(struct drm_crtc_state *crtc_state)
+{
+	struct drm_crtc *crtc = crtc_state->crtc;
+	struct drm_device *dev = crtc->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	struct intel_crtc_state *intel_crtc_state =
+		to_intel_crtc_state(crtc_state);
+	bool reenable_ips = false;
+
+	/*
+	 * Workaround : Do not read or write the pipe palette/gamma data while
+	 * GAMMA_MODE is configured for split gamma and IPS_CTL has IPS enabled.
+	 */
+	if (IS_HASWELL(dev) && intel_crtc->config->ips_enabled &&
+	    (intel_crtc_state->gamma_mode == GAMMA_MODE_MODE_SPLIT)) {
+		hsw_disable_ips(intel_crtc);
+		reenable_ips = true;
+	}
+
+	intel_crtc_state->gamma_mode = GAMMA_MODE_MODE_8BIT;
+	I915_WRITE(GAMMA_MODE(intel_crtc->pipe), GAMMA_MODE_MODE_8BIT);
+
+	i9xx_load_luts(crtc_state);
+
+	if (reenable_ips)
+		hsw_enable_ips(intel_crtc);
+}
+
+/* Loads the palette/gamma unit for the CRTC on Broadwell+. */
+static void broadwell_load_luts(struct drm_crtc_state *state)
+{
+	struct drm_crtc *crtc = state->crtc;
+	struct drm_device *dev = crtc->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_crtc_state *intel_state = to_intel_crtc_state(state);
+	enum pipe pipe = to_intel_crtc(crtc)->pipe;
+	uint32_t i, lut_size = INTEL_INFO(dev)->color.degamma_lut_size;
+
+	if (crtc_state_is_legacy(state)) {
+		haswell_load_luts(state);
+		return;
+	}
+
+	I915_WRITE(PREC_PAL_INDEX(pipe),
+		   PAL_PREC_SPLIT_MODE | PAL_PREC_AUTO_INCREMENT);
+
+	if (state->degamma_lut) {
+		struct drm_color_lut *lut =
+			(struct drm_color_lut *) state->degamma_lut->data;
+
+		for (i = 0; i < lut_size; i++) {
+			uint32_t word =
+			drm_color_lut_extract(lut[i].red, 10) << 20 |
+			drm_color_lut_extract(lut[i].green, 10) << 10 |
+			drm_color_lut_extract(lut[i].blue, 10);
+
+			I915_WRITE(PREC_PAL_DATA(pipe), word);
+		}
+	} else {
+		for (i = 0; i < lut_size; i++) {
+			uint32_t v = (i * ((1 << 10) - 1)) / (lut_size - 1);
+
+			I915_WRITE(PREC_PAL_DATA(pipe),
+				   (v << 20) | (v << 10) | v);
+		}
+	}
+
+	if (state->gamma_lut) {
+		struct drm_color_lut *lut =
+			(struct drm_color_lut *) state->gamma_lut->data;
+
+		for (i = 0; i < lut_size; i++) {
+			uint32_t word =
+			(drm_color_lut_extract(lut[i].red, 10) << 20) |
+			(drm_color_lut_extract(lut[i].green, 10) << 10) |
+			drm_color_lut_extract(lut[i].blue, 10);
+
+			I915_WRITE(PREC_PAL_DATA(pipe), word);
+		}
+
+		/* Program the max register to clamp values > 1.0. */
+		I915_WRITE(PREC_PAL_GC_MAX(pipe, 0),
+			   drm_color_lut_extract(lut[i].red, 16));
+		I915_WRITE(PREC_PAL_GC_MAX(pipe, 1),
+			   drm_color_lut_extract(lut[i].green, 16));
+		I915_WRITE(PREC_PAL_GC_MAX(pipe, 2),
+			   drm_color_lut_extract(lut[i].blue, 16));
+	} else {
+		for (i = 0; i < lut_size; i++) {
+			uint32_t v = (i * ((1 << 10) - 1)) / (lut_size - 1);
+
+			I915_WRITE(PREC_PAL_DATA(pipe),
+				   (v << 20) | (v << 10) | v);
+		}
+
+		I915_WRITE(PREC_PAL_GC_MAX(pipe, 0), (1 << 16) - 1);
+		I915_WRITE(PREC_PAL_GC_MAX(pipe, 1), (1 << 16) - 1);
+		I915_WRITE(PREC_PAL_GC_MAX(pipe, 2), (1 << 16) - 1);
+	}
+
+	intel_state->gamma_mode = GAMMA_MODE_MODE_SPLIT;
+	I915_WRITE(GAMMA_MODE(pipe), GAMMA_MODE_MODE_SPLIT);
+	POSTING_READ(GAMMA_MODE(pipe));
+
+	/*
+	 * Reset the index, otherwise it prevents the legacy palette to be
+	 * written properly.
+	 */
+	I915_WRITE(PREC_PAL_INDEX(pipe), 0);
+}
+
+/* Loads the palette/gamma unit for the CRTC on CherryView. */
+static void cherryview_load_luts(struct drm_crtc_state *state)
+{
+	struct drm_crtc *crtc = state->crtc;
+	struct drm_device *dev = crtc->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	enum pipe pipe = to_intel_crtc(crtc)->pipe;
+	struct drm_color_lut *lut;
+	uint32_t i, lut_size;
+	uint32_t word0, word1;
+
+	if (crtc_state_is_legacy(state)) {
+		/* Turn off degamma/gamma on CGM block. */
+		I915_WRITE(CGM_PIPE_MODE(pipe),
+			   (state->ctm ? CGM_PIPE_MODE_CSC : 0));
+		i9xx_load_luts_internal(crtc, state->gamma_lut);
+		return;
+	}
+
+	if (state->degamma_lut) {
+		lut = (struct drm_color_lut *) state->degamma_lut->data;
+		lut_size = INTEL_INFO(dev)->color.degamma_lut_size;
+		for (i = 0; i < lut_size; i++) {
+			/* Write LUT in U0.14 format. */
+			word0 =
+			(drm_color_lut_extract(lut[i].green, 14) << 16) |
+			drm_color_lut_extract(lut[i].blue, 14);
+			word1 = drm_color_lut_extract(lut[i].red, 14);
+
+			I915_WRITE(CGM_PIPE_DEGAMMA(pipe, i, 0), word0);
+			I915_WRITE(CGM_PIPE_DEGAMMA(pipe, i, 1), word1);
+		}
+	}
+
+	if (state->gamma_lut) {
+		lut = (struct drm_color_lut *) state->gamma_lut->data;
+		lut_size = INTEL_INFO(dev)->color.gamma_lut_size;
+		for (i = 0; i < lut_size; i++) {
+			/* Write LUT in U0.10 format. */
+			word0 =
+			(drm_color_lut_extract(lut[i].green, 10) << 16) |
+			drm_color_lut_extract(lut[i].blue, 10);
+			word1 = drm_color_lut_extract(lut[i].red, 10);
+
+			I915_WRITE(CGM_PIPE_GAMMA(pipe, i, 0), word0);
+			I915_WRITE(CGM_PIPE_GAMMA(pipe, i, 1), word1);
+		}
+	}
+
+	I915_WRITE(CGM_PIPE_MODE(pipe),
+		   (state->ctm ? CGM_PIPE_MODE_CSC : 0) |
+		   (state->degamma_lut ? CGM_PIPE_MODE_DEGAMMA : 0) |
+		   (state->gamma_lut ? CGM_PIPE_MODE_GAMMA : 0));
+
+	/*
+	 * Also program a linear LUT in the legacy block (behind the
+	 * CGM block).
+	 */
+	i9xx_load_luts_internal(crtc, NULL);
+}
+
+void intel_color_load_luts(struct drm_crtc_state *crtc_state)
+{
+	struct drm_device *dev = crtc_state->crtc->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	dev_priv->display.load_luts(crtc_state);
+}
+
+int intel_color_check(struct drm_crtc *crtc,
+		      struct drm_crtc_state *crtc_state)
+{
+	struct drm_device *dev = crtc->dev;
+	size_t gamma_length, degamma_length;
+
+	degamma_length = INTEL_INFO(dev)->color.degamma_lut_size *
+		sizeof(struct drm_color_lut);
+	gamma_length = INTEL_INFO(dev)->color.gamma_lut_size *
+		sizeof(struct drm_color_lut);
+
+	/*
+	 * We allow both degamma & gamma luts at the right size or
+	 * NULL.
+	 */
+	if ((!crtc_state->degamma_lut ||
+	     crtc_state->degamma_lut->length == degamma_length) &&
+	    (!crtc_state->gamma_lut ||
+	     crtc_state->gamma_lut->length == gamma_length))
+		return 0;
+
+	/*
+	 * We also allow no degamma lut and a gamma lut at the legacy
+	 * size (256 entries).
+	 */
+	if (!crtc_state->degamma_lut &&
+	    crtc_state->gamma_lut &&
+	    crtc_state->gamma_lut->length == LEGACY_LUT_LENGTH)
+		return 0;
+
+	return -EINVAL;
+}
+
+void intel_color_init(struct drm_crtc *crtc)
+{
+	struct drm_device *dev = crtc->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	drm_mode_crtc_set_gamma_size(crtc, 256);
+
+	if (IS_CHERRYVIEW(dev)) {
+		dev_priv->display.load_csc_matrix = cherryview_load_csc_matrix;
+		dev_priv->display.load_luts = cherryview_load_luts;
+	} else if (IS_HASWELL(dev)) {
+		dev_priv->display.load_csc_matrix = i9xx_load_csc_matrix;
+		dev_priv->display.load_luts = haswell_load_luts;
+	} else if (IS_BROADWELL(dev) || IS_SKYLAKE(dev) ||
+		   IS_BROXTON(dev) || IS_KABYLAKE(dev)) {
+		dev_priv->display.load_csc_matrix = i9xx_load_csc_matrix;
+		dev_priv->display.load_luts = broadwell_load_luts;
+	} else {
+		dev_priv->display.load_luts = i9xx_load_luts;
+	}
+
+	/* Enable color management support when we have degamma & gamma LUTs. */
+	if (INTEL_INFO(dev)->color.degamma_lut_size != 0 &&
+	    INTEL_INFO(dev)->color.gamma_lut_size != 0)
+		drm_helper_crtc_enable_color_mgmt(crtc,
+					INTEL_INFO(dev)->color.degamma_lut_size,
+					INTEL_INFO(dev)->color.gamma_lut_size);
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/i915/intel_crt.c
@@ -0,0 +1,906 @@
+/*
+ * Copyright © 2006-2007 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *	Eric Anholt <eric@anholt.net>
+ */
+
+#include <linux/dmi.h>
+#include <linux/i2c.h>
+#include <linux/slab.h>
+#include <drm/drmP.h>
+#include <drm/drm_atomic_helper.h>
+#include <drm/drm_crtc.h>
+#include <drm/drm_crtc_helper.h>
+#include <drm/drm_edid.h>
+#include "intel_drv.h"
+#include <drm/i915_drm.h>
+#include "i915_drv.h"
+
+/* Here's the desired hotplug mode */
+#define ADPA_HOTPLUG_BITS (ADPA_CRT_HOTPLUG_PERIOD_128 |		\
+			   ADPA_CRT_HOTPLUG_WARMUP_10MS |		\
+			   ADPA_CRT_HOTPLUG_SAMPLE_4S |			\
+			   ADPA_CRT_HOTPLUG_VOLTAGE_50 |		\
+			   ADPA_CRT_HOTPLUG_VOLREF_325MV |		\
+			   ADPA_CRT_HOTPLUG_ENABLE)
+
+struct intel_crt {
+	struct intel_encoder base;
+	/* DPMS state is stored in the connector, which we need in the
+	 * encoder's enable/disable callbacks */
+	struct intel_connector *connector;
+	bool force_hotplug_required;
+	i915_reg_t adpa_reg;
+};
+
+static struct intel_crt *intel_encoder_to_crt(struct intel_encoder *encoder)
+{
+	return container_of(encoder, struct intel_crt, base);
+}
+
+static struct intel_crt *intel_attached_crt(struct drm_connector *connector)
+{
+	return intel_encoder_to_crt(intel_attached_encoder(connector));
+}
+
+static bool intel_crt_get_hw_state(struct intel_encoder *encoder,
+				   enum pipe *pipe)
+{
+	struct drm_device *dev = encoder->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_crt *crt = intel_encoder_to_crt(encoder);
+	enum intel_display_power_domain power_domain;
+	u32 tmp;
+	bool ret;
+
+	power_domain = intel_display_port_power_domain(encoder);
+	if (!intel_display_power_get_if_enabled(dev_priv, power_domain))
+		return false;
+
+	ret = false;
+
+	tmp = I915_READ(crt->adpa_reg);
+
+	if (!(tmp & ADPA_DAC_ENABLE))
+		goto out;
+
+	if (HAS_PCH_CPT(dev))
+		*pipe = PORT_TO_PIPE_CPT(tmp);
+	else
+		*pipe = PORT_TO_PIPE(tmp);
+
+	ret = true;
+out:
+	intel_display_power_put(dev_priv, power_domain);
+
+	return ret;
+}
+
+static unsigned int intel_crt_get_flags(struct intel_encoder *encoder)
+{
+	struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
+	struct intel_crt *crt = intel_encoder_to_crt(encoder);
+	u32 tmp, flags = 0;
+
+	tmp = I915_READ(crt->adpa_reg);
+
+	if (tmp & ADPA_HSYNC_ACTIVE_HIGH)
+		flags |= DRM_MODE_FLAG_PHSYNC;
+	else
+		flags |= DRM_MODE_FLAG_NHSYNC;
+
+	if (tmp & ADPA_VSYNC_ACTIVE_HIGH)
+		flags |= DRM_MODE_FLAG_PVSYNC;
+	else
+		flags |= DRM_MODE_FLAG_NVSYNC;
+
+	return flags;
+}
+
+static void intel_crt_get_config(struct intel_encoder *encoder,
+				 struct intel_crtc_state *pipe_config)
+{
+	pipe_config->base.adjusted_mode.flags |= intel_crt_get_flags(encoder);
+
+	pipe_config->base.adjusted_mode.crtc_clock = pipe_config->port_clock;
+}
+
+static void hsw_crt_get_config(struct intel_encoder *encoder,
+			       struct intel_crtc_state *pipe_config)
+{
+	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
+
+	intel_ddi_get_config(encoder, pipe_config);
+
+	pipe_config->base.adjusted_mode.flags &= ~(DRM_MODE_FLAG_PHSYNC |
+					      DRM_MODE_FLAG_NHSYNC |
+					      DRM_MODE_FLAG_PVSYNC |
+					      DRM_MODE_FLAG_NVSYNC);
+	pipe_config->base.adjusted_mode.flags |= intel_crt_get_flags(encoder);
+
+	pipe_config->base.adjusted_mode.crtc_clock = lpt_get_iclkip(dev_priv);
+}
+
+/* Note: The caller is required to filter out dpms modes not supported by the
+ * platform. */
+static void intel_crt_set_dpms(struct intel_encoder *encoder, int mode)
+{
+	struct drm_device *dev = encoder->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_crt *crt = intel_encoder_to_crt(encoder);
+	struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc);
+	const struct drm_display_mode *adjusted_mode = &crtc->config->base.adjusted_mode;
+	u32 adpa;
+
+	if (INTEL_INFO(dev)->gen >= 5)
+		adpa = ADPA_HOTPLUG_BITS;
+	else
+		adpa = 0;
+
+	if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC)
+		adpa |= ADPA_HSYNC_ACTIVE_HIGH;
+	if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC)
+		adpa |= ADPA_VSYNC_ACTIVE_HIGH;
+
+	/* For CPT allow 3 pipe config, for others just use A or B */
+	if (HAS_PCH_LPT(dev))
+		; /* Those bits don't exist here */
+	else if (HAS_PCH_CPT(dev))
+		adpa |= PORT_TRANS_SEL_CPT(crtc->pipe);
+	else if (crtc->pipe == 0)
+		adpa |= ADPA_PIPE_A_SELECT;
+	else
+		adpa |= ADPA_PIPE_B_SELECT;
+
+	if (!HAS_PCH_SPLIT(dev))
+		I915_WRITE(BCLRPAT(crtc->pipe), 0);
+
+	switch (mode) {
+	case DRM_MODE_DPMS_ON:
+		adpa |= ADPA_DAC_ENABLE;
+		break;
+	case DRM_MODE_DPMS_STANDBY:
+		adpa |= ADPA_DAC_ENABLE | ADPA_HSYNC_CNTL_DISABLE;
+		break;
+	case DRM_MODE_DPMS_SUSPEND:
+		adpa |= ADPA_DAC_ENABLE | ADPA_VSYNC_CNTL_DISABLE;
+		break;
+	case DRM_MODE_DPMS_OFF:
+		adpa |= ADPA_HSYNC_CNTL_DISABLE | ADPA_VSYNC_CNTL_DISABLE;
+		break;
+	}
+
+	I915_WRITE(crt->adpa_reg, adpa);
+}
+
+static void intel_disable_crt(struct intel_encoder *encoder)
+{
+	intel_crt_set_dpms(encoder, DRM_MODE_DPMS_OFF);
+}
+
+static void pch_disable_crt(struct intel_encoder *encoder)
+{
+}
+
+static void pch_post_disable_crt(struct intel_encoder *encoder)
+{
+	intel_disable_crt(encoder);
+}
+
+static void intel_enable_crt(struct intel_encoder *encoder)
+{
+	intel_crt_set_dpms(encoder, DRM_MODE_DPMS_ON);
+}
+
+static enum drm_mode_status
+intel_crt_mode_valid(struct drm_connector *connector,
+		     struct drm_display_mode *mode)
+{
+	struct drm_device *dev = connector->dev;
+	int max_dotclk = to_i915(dev)->max_dotclk_freq;
+	int max_clock;
+
+	if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
+		return MODE_NO_DBLESCAN;
+
+	if (mode->clock < 25000)
+		return MODE_CLOCK_LOW;
+
+	if (HAS_PCH_LPT(dev))
+		max_clock = 180000;
+	else if (IS_VALLEYVIEW(dev))
+		/*
+		 * 270 MHz due to current DPLL limits,
+		 * DAC limit supposedly 355 MHz.
+		 */
+		max_clock = 270000;
+	else if (IS_GEN3(dev) || IS_GEN4(dev))
+		max_clock = 400000;
+	else
+		max_clock = 350000;
+	if (mode->clock > max_clock)
+		return MODE_CLOCK_HIGH;
+
+	if (mode->clock > max_dotclk)
+		return MODE_CLOCK_HIGH;
+
+	/* The FDI receiver on LPT only supports 8bpc and only has 2 lanes. */
+	if (HAS_PCH_LPT(dev) &&
+	    (ironlake_get_lanes_required(mode->clock, 270000, 24) > 2))
+		return MODE_CLOCK_HIGH;
+
+	return MODE_OK;
+}
+
+static bool intel_crt_compute_config(struct intel_encoder *encoder,
+				     struct intel_crtc_state *pipe_config)
+{
+	struct drm_device *dev = encoder->base.dev;
+
+	if (HAS_PCH_SPLIT(dev))
+		pipe_config->has_pch_encoder = true;
+
+	/* LPT FDI RX only supports 8bpc. */
+	if (HAS_PCH_LPT(dev)) {
+		if (pipe_config->bw_constrained && pipe_config->pipe_bpp < 24) {
+			DRM_DEBUG_KMS("LPT only supports 24bpp\n");
+			return false;
+		}
+
+		pipe_config->pipe_bpp = 24;
+	}
+
+	/* FDI must always be 2.7 GHz */
+	if (HAS_DDI(dev))
+		pipe_config->port_clock = 135000 * 2;
+
+	return true;
+}
+
+static bool intel_ironlake_crt_detect_hotplug(struct drm_connector *connector)
+{
+	struct drm_device *dev = connector->dev;
+	struct intel_crt *crt = intel_attached_crt(connector);
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	u32 adpa;
+	bool ret;
+
+	/* The first time through, trigger an explicit detection cycle */
+	if (crt->force_hotplug_required) {
+		bool turn_off_dac = HAS_PCH_SPLIT(dev);
+		u32 save_adpa;
+
+		crt->force_hotplug_required = 0;
+
+		save_adpa = adpa = I915_READ(crt->adpa_reg);
+		DRM_DEBUG_KMS("trigger hotplug detect cycle: adpa=0x%x\n", adpa);
+
+		adpa |= ADPA_CRT_HOTPLUG_FORCE_TRIGGER;
+		if (turn_off_dac)
+			adpa &= ~ADPA_DAC_ENABLE;
+
+		I915_WRITE(crt->adpa_reg, adpa);
+
+		if (wait_for((I915_READ(crt->adpa_reg) & ADPA_CRT_HOTPLUG_FORCE_TRIGGER) == 0,
+			     1000))
+			DRM_DEBUG_KMS("timed out waiting for FORCE_TRIGGER");
+
+		if (turn_off_dac) {
+			I915_WRITE(crt->adpa_reg, save_adpa);
+			POSTING_READ(crt->adpa_reg);
+		}
+	}
+
+	/* Check the status to see if both blue and green are on now */
+	adpa = I915_READ(crt->adpa_reg);
+	if ((adpa & ADPA_CRT_HOTPLUG_MONITOR_MASK) != 0)
+		ret = true;
+	else
+		ret = false;
+	DRM_DEBUG_KMS("ironlake hotplug adpa=0x%x, result %d\n", adpa, ret);
+
+	return ret;
+}
+
+static bool valleyview_crt_detect_hotplug(struct drm_connector *connector)
+{
+	struct drm_device *dev = connector->dev;
+	struct intel_crt *crt = intel_attached_crt(connector);
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	u32 adpa;
+	bool ret;
+	u32 save_adpa;
+
+	save_adpa = adpa = I915_READ(crt->adpa_reg);
+	DRM_DEBUG_KMS("trigger hotplug detect cycle: adpa=0x%x\n", adpa);
+
+	adpa |= ADPA_CRT_HOTPLUG_FORCE_TRIGGER;
+
+	I915_WRITE(crt->adpa_reg, adpa);
+
+	if (wait_for((I915_READ(crt->adpa_reg) & ADPA_CRT_HOTPLUG_FORCE_TRIGGER) == 0,
+		     1000)) {
+		DRM_DEBUG_KMS("timed out waiting for FORCE_TRIGGER");
+		I915_WRITE(crt->adpa_reg, save_adpa);
+	}
+
+	/* Check the status to see if both blue and green are on now */
+	adpa = I915_READ(crt->adpa_reg);
+	if ((adpa & ADPA_CRT_HOTPLUG_MONITOR_MASK) != 0)
+		ret = true;
+	else
+		ret = false;
+
+	DRM_DEBUG_KMS("valleyview hotplug adpa=0x%x, result %d\n", adpa, ret);
+
+	return ret;
+}
+
+/**
+ * Uses CRT_HOTPLUG_EN and CRT_HOTPLUG_STAT to detect CRT presence.
+ *
+ * Not for i915G/i915GM
+ *
+ * \return true if CRT is connected.
+ * \return false if CRT is disconnected.
+ */
+static bool intel_crt_detect_hotplug(struct drm_connector *connector)
+{
+	struct drm_device *dev = connector->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	u32 stat;
+	bool ret = false;
+	int i, tries = 0;
+
+	if (HAS_PCH_SPLIT(dev))
+		return intel_ironlake_crt_detect_hotplug(connector);
+
+	if (IS_VALLEYVIEW(dev))
+		return valleyview_crt_detect_hotplug(connector);
+
+	/*
+	 * On 4 series desktop, CRT detect sequence need to be done twice
+	 * to get a reliable result.
+	 */
+
+	if (IS_G4X(dev) && !IS_GM45(dev))
+		tries = 2;
+	else
+		tries = 1;
+
+	for (i = 0; i < tries ; i++) {
+		/* turn on the FORCE_DETECT */
+		i915_hotplug_interrupt_update(dev_priv,
+					      CRT_HOTPLUG_FORCE_DETECT,
+					      CRT_HOTPLUG_FORCE_DETECT);
+		/* wait for FORCE_DETECT to go off */
+		if (wait_for((I915_READ(PORT_HOTPLUG_EN) &
+			      CRT_HOTPLUG_FORCE_DETECT) == 0,
+			     1000))
+			DRM_DEBUG_KMS("timed out waiting for FORCE_DETECT to go off");
+	}
+
+	stat = I915_READ(PORT_HOTPLUG_STAT);
+	if ((stat & CRT_HOTPLUG_MONITOR_MASK) != CRT_HOTPLUG_MONITOR_NONE)
+		ret = true;
+
+	/* clear the interrupt we just generated, if any */
+	I915_WRITE(PORT_HOTPLUG_STAT, CRT_HOTPLUG_INT_STATUS);
+
+	i915_hotplug_interrupt_update(dev_priv, CRT_HOTPLUG_FORCE_DETECT, 0);
+
+	return ret;
+}
+
+static struct edid *intel_crt_get_edid(struct drm_connector *connector,
+				struct i2c_adapter *i2c)
+{
+	struct edid *edid;
+
+	edid = drm_get_edid(connector, i2c);
+
+	if (!edid && !intel_gmbus_is_forced_bit(i2c)) {
+		DRM_DEBUG_KMS("CRT GMBUS EDID read failed, retry using GPIO bit-banging\n");
+		intel_gmbus_force_bit(i2c, true);
+		edid = drm_get_edid(connector, i2c);
+		intel_gmbus_force_bit(i2c, false);
+	}
+
+	return edid;
+}
+
+/* local version of intel_ddc_get_modes() to use intel_crt_get_edid() */
+static int intel_crt_ddc_get_modes(struct drm_connector *connector,
+				struct i2c_adapter *adapter)
+{
+	struct edid *edid;
+	int ret;
+
+	edid = intel_crt_get_edid(connector, adapter);
+	if (!edid)
+		return 0;
+
+	ret = intel_connector_update_modes(connector, edid);
+	kfree(edid);
+
+	return ret;
+}
+
+static bool intel_crt_detect_ddc(struct drm_connector *connector)
+{
+	struct intel_crt *crt = intel_attached_crt(connector);
+	struct drm_i915_private *dev_priv = crt->base.base.dev->dev_private;
+	struct edid *edid;
+	struct i2c_adapter *i2c;
+
+	BUG_ON(crt->base.type != INTEL_OUTPUT_ANALOG);
+
+	i2c = intel_gmbus_get_adapter(dev_priv, dev_priv->vbt.crt_ddc_pin);
+	edid = intel_crt_get_edid(connector, i2c);
+
+	if (edid) {
+		bool is_digital = edid->input & DRM_EDID_INPUT_DIGITAL;
+
+		/*
+		 * This may be a DVI-I connector with a shared DDC
+		 * link between analog and digital outputs, so we
+		 * have to check the EDID input spec of the attached device.
+		 */
+		if (!is_digital) {
+			DRM_DEBUG_KMS("CRT detected via DDC:0x50 [EDID]\n");
+			return true;
+		}
+
+		DRM_DEBUG_KMS("CRT not detected via DDC:0x50 [EDID reports a digital panel]\n");
+	} else {
+		DRM_DEBUG_KMS("CRT not detected via DDC:0x50 [no valid EDID found]\n");
+	}
+
+	kfree(edid);
+
+	return false;
+}
+
+static enum drm_connector_status
+intel_crt_load_detect(struct intel_crt *crt, uint32_t pipe)
+{
+	struct drm_device *dev = crt->base.base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	uint32_t save_bclrpat;
+	uint32_t save_vtotal;
+	uint32_t vtotal, vactive;
+	uint32_t vsample;
+	uint32_t vblank, vblank_start, vblank_end;
+	uint32_t dsl;
+	i915_reg_t bclrpat_reg, vtotal_reg,
+		vblank_reg, vsync_reg, pipeconf_reg, pipe_dsl_reg;
+	uint8_t	st00;
+	enum drm_connector_status status;
+
+	DRM_DEBUG_KMS("starting load-detect on CRT\n");
+
+	bclrpat_reg = BCLRPAT(pipe);
+	vtotal_reg = VTOTAL(pipe);
+	vblank_reg = VBLANK(pipe);
+	vsync_reg = VSYNC(pipe);
+	pipeconf_reg = PIPECONF(pipe);
+	pipe_dsl_reg = PIPEDSL(pipe);
+
+	save_bclrpat = I915_READ(bclrpat_reg);
+	save_vtotal = I915_READ(vtotal_reg);
+	vblank = I915_READ(vblank_reg);
+
+	vtotal = ((save_vtotal >> 16) & 0xfff) + 1;
+	vactive = (save_vtotal & 0x7ff) + 1;
+
+	vblank_start = (vblank & 0xfff) + 1;
+	vblank_end = ((vblank >> 16) & 0xfff) + 1;
+
+	/* Set the border color to purple. */
+	I915_WRITE(bclrpat_reg, 0x500050);
+
+	if (!IS_GEN2(dev)) {
+		uint32_t pipeconf = I915_READ(pipeconf_reg);
+		I915_WRITE(pipeconf_reg, pipeconf | PIPECONF_FORCE_BORDER);
+		POSTING_READ(pipeconf_reg);
+		/* Wait for next Vblank to substitue
+		 * border color for Color info */
+		intel_wait_for_vblank(dev, pipe);
+		st00 = I915_READ8(_VGA_MSR_WRITE);
+		status = ((st00 & (1 << 4)) != 0) ?
+			connector_status_connected :
+			connector_status_disconnected;
+
+		I915_WRITE(pipeconf_reg, pipeconf);
+	} else {
+		bool restore_vblank = false;
+		int count, detect;
+
+		/*
+		* If there isn't any border, add some.
+		* Yes, this will flicker
+		*/
+		if (vblank_start <= vactive && vblank_end >= vtotal) {
+			uint32_t vsync = I915_READ(vsync_reg);
+			uint32_t vsync_start = (vsync & 0xffff) + 1;
+
+			vblank_start = vsync_start;
+			I915_WRITE(vblank_reg,
+				   (vblank_start - 1) |
+				   ((vblank_end - 1) << 16));
+			restore_vblank = true;
+		}
+		/* sample in the vertical border, selecting the larger one */
+		if (vblank_start - vactive >= vtotal - vblank_end)
+			vsample = (vblank_start + vactive) >> 1;
+		else
+			vsample = (vtotal + vblank_end) >> 1;
+
+		/*
+		 * Wait for the border to be displayed
+		 */
+		while (I915_READ(pipe_dsl_reg) >= vactive)
+			;
+		while ((dsl = I915_READ(pipe_dsl_reg)) <= vsample)
+			;
+		/*
+		 * Watch ST00 for an entire scanline
+		 */
+		detect = 0;
+		count = 0;
+		do {
+			count++;
+			/* Read the ST00 VGA status register */
+			st00 = I915_READ8(_VGA_MSR_WRITE);
+			if (st00 & (1 << 4))
+				detect++;
+		} while ((I915_READ(pipe_dsl_reg) == dsl));
+
+		/* restore vblank if necessary */
+		if (restore_vblank)
+			I915_WRITE(vblank_reg, vblank);
+		/*
+		 * If more than 3/4 of the scanline detected a monitor,
+		 * then it is assumed to be present. This works even on i830,
+		 * where there isn't any way to force the border color across
+		 * the screen
+		 */
+		status = detect * 4 > count * 3 ?
+			 connector_status_connected :
+			 connector_status_disconnected;
+	}
+
+	/* Restore previous settings */
+	I915_WRITE(bclrpat_reg, save_bclrpat);
+
+	return status;
+}
+
+static enum drm_connector_status
+intel_crt_detect(struct drm_connector *connector, bool force)
+{
+	struct drm_device *dev = connector->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_crt *crt = intel_attached_crt(connector);
+	struct intel_encoder *intel_encoder = &crt->base;
+	enum intel_display_power_domain power_domain;
+	enum drm_connector_status status;
+	struct intel_load_detect_pipe tmp;
+	struct drm_modeset_acquire_ctx ctx;
+
+	DRM_DEBUG_KMS("[CONNECTOR:%d:%s] force=%d\n",
+		      connector->base.id, connector->name,
+		      force);
+
+	power_domain = intel_display_port_power_domain(intel_encoder);
+	intel_display_power_get(dev_priv, power_domain);
+
+	if (I915_HAS_HOTPLUG(dev)) {
+		/* We can not rely on the HPD pin always being correctly wired
+		 * up, for example many KVM do not pass it through, and so
+		 * only trust an assertion that the monitor is connected.
+		 */
+		if (intel_crt_detect_hotplug(connector)) {
+			DRM_DEBUG_KMS("CRT detected via hotplug\n");
+			status = connector_status_connected;
+			goto out;
+		} else
+			DRM_DEBUG_KMS("CRT not detected via hotplug\n");
+	}
+
+	if (intel_crt_detect_ddc(connector)) {
+		status = connector_status_connected;
+		goto out;
+	}
+
+	/* Load detection is broken on HPD capable machines. Whoever wants a
+	 * broken monitor (without edid) to work behind a broken kvm (that fails
+	 * to have the right resistors for HP detection) needs to fix this up.
+	 * For now just bail out. */
+	if (I915_HAS_HOTPLUG(dev) && !i915.load_detect_test) {
+		status = connector_status_disconnected;
+		goto out;
+	}
+
+	if (!force) {
+		status = connector->status;
+		goto out;
+	}
+
+	drm_modeset_acquire_init(&ctx, 0);
+
+	/* for pre-945g platforms use load detect */
+	if (intel_get_load_detect_pipe(connector, NULL, &tmp, &ctx)) {
+		if (intel_crt_detect_ddc(connector))
+			status = connector_status_connected;
+		else if (INTEL_INFO(dev)->gen < 4)
+			status = intel_crt_load_detect(crt,
+				to_intel_crtc(connector->state->crtc)->pipe);
+		else if (i915.load_detect_test)
+			status = connector_status_disconnected;
+		else
+			status = connector_status_unknown;
+		intel_release_load_detect_pipe(connector, &tmp, &ctx);
+	} else
+		status = connector_status_unknown;
+
+	drm_modeset_drop_locks(&ctx);
+	drm_modeset_acquire_fini(&ctx);
+
+out:
+	intel_display_power_put(dev_priv, power_domain);
+	return status;
+}
+
+static void intel_crt_destroy(struct drm_connector *connector)
+{
+	drm_connector_cleanup(connector);
+	kfree(connector);
+}
+
+static int intel_crt_get_modes(struct drm_connector *connector)
+{
+	struct drm_device *dev = connector->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_crt *crt = intel_attached_crt(connector);
+	struct intel_encoder *intel_encoder = &crt->base;
+	enum intel_display_power_domain power_domain;
+	int ret;
+	struct i2c_adapter *i2c;
+
+	power_domain = intel_display_port_power_domain(intel_encoder);
+	intel_display_power_get(dev_priv, power_domain);
+
+	i2c = intel_gmbus_get_adapter(dev_priv, dev_priv->vbt.crt_ddc_pin);
+	ret = intel_crt_ddc_get_modes(connector, i2c);
+	if (ret || !IS_G4X(dev))
+		goto out;
+
+	/* Try to probe digital port for output in DVI-I -> VGA mode. */
+	i2c = intel_gmbus_get_adapter(dev_priv, GMBUS_PIN_DPB);
+	ret = intel_crt_ddc_get_modes(connector, i2c);
+
+out:
+	intel_display_power_put(dev_priv, power_domain);
+
+	return ret;
+}
+
+static int intel_crt_set_property(struct drm_connector *connector,
+				  struct drm_property *property,
+				  uint64_t value)
+{
+	return 0;
+}
+
+static void intel_crt_reset(struct drm_connector *connector)
+{
+	struct drm_device *dev = connector->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_crt *crt = intel_attached_crt(connector);
+
+	if (INTEL_INFO(dev)->gen >= 5) {
+		u32 adpa;
+
+		adpa = I915_READ(crt->adpa_reg);
+		adpa &= ~ADPA_CRT_HOTPLUG_MASK;
+		adpa |= ADPA_HOTPLUG_BITS;
+		I915_WRITE(crt->adpa_reg, adpa);
+		POSTING_READ(crt->adpa_reg);
+
+		DRM_DEBUG_KMS("crt adpa set to 0x%x\n", adpa);
+		crt->force_hotplug_required = 1;
+	}
+
+}
+
+/*
+ * Routines for controlling stuff on the analog port
+ */
+
+static const struct drm_connector_funcs intel_crt_connector_funcs = {
+	.reset = intel_crt_reset,
+	.dpms = drm_atomic_helper_connector_dpms,
+	.detect = intel_crt_detect,
+	.fill_modes = drm_helper_probe_single_connector_modes,
+	.destroy = intel_crt_destroy,
+	.set_property = intel_crt_set_property,
+	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
+	.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
+	.atomic_get_property = intel_connector_atomic_get_property,
+};
+
+static const struct drm_connector_helper_funcs intel_crt_connector_helper_funcs = {
+	.mode_valid = intel_crt_mode_valid,
+	.get_modes = intel_crt_get_modes,
+	.best_encoder = intel_best_encoder,
+};
+
+static const struct drm_encoder_funcs intel_crt_enc_funcs = {
+	.destroy = intel_encoder_destroy,
+};
+
+static int intel_no_crt_dmi_callback(const struct dmi_system_id *id)
+{
+	DRM_INFO("Skipping CRT initialization for %s\n", id->ident);
+	return 1;
+}
+
+static const struct dmi_system_id intel_no_crt[] = {
+	{
+		.callback = intel_no_crt_dmi_callback,
+		.ident = "ACER ZGB",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "ACER"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "ZGB"),
+		},
+	},
+	{
+		.callback = intel_no_crt_dmi_callback,
+		.ident = "DELL XPS 8700",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+			DMI_MATCH(DMI_PRODUCT_NAME, "XPS 8700"),
+		},
+	},
+	{ }
+};
+
+void intel_crt_init(struct drm_device *dev)
+{
+	struct drm_connector *connector;
+	struct intel_crt *crt;
+	struct intel_connector *intel_connector;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	i915_reg_t adpa_reg;
+	u32 adpa;
+
+	/* Skip machines without VGA that falsely report hotplug events */
+	if (dmi_check_system(intel_no_crt))
+		return;
+
+	if (HAS_PCH_SPLIT(dev))
+		adpa_reg = PCH_ADPA;
+	else if (IS_VALLEYVIEW(dev))
+		adpa_reg = VLV_ADPA;
+	else
+		adpa_reg = ADPA;
+
+	adpa = I915_READ(adpa_reg);
+	if ((adpa & ADPA_DAC_ENABLE) == 0) {
+		/*
+		 * On some machines (some IVB at least) CRT can be
+		 * fused off, but there's no known fuse bit to
+		 * indicate that. On these machine the ADPA register
+		 * works normally, except the DAC enable bit won't
+		 * take. So the only way to tell is attempt to enable
+		 * it and see what happens.
+		 */
+		I915_WRITE(adpa_reg, adpa | ADPA_DAC_ENABLE |
+			   ADPA_HSYNC_CNTL_DISABLE | ADPA_VSYNC_CNTL_DISABLE);
+		if ((I915_READ(adpa_reg) & ADPA_DAC_ENABLE) == 0)
+			return;
+		I915_WRITE(adpa_reg, adpa);
+	}
+
+	crt = kzalloc(sizeof(struct intel_crt), GFP_KERNEL);
+	if (!crt)
+		return;
+
+	intel_connector = intel_connector_alloc();
+	if (!intel_connector) {
+		kfree(crt);
+		return;
+	}
+
+	connector = &intel_connector->base;
+	crt->connector = intel_connector;
+	drm_connector_init(dev, &intel_connector->base,
+			   &intel_crt_connector_funcs, DRM_MODE_CONNECTOR_VGA);
+
+	drm_encoder_init(dev, &crt->base.base, &intel_crt_enc_funcs,
+			 DRM_MODE_ENCODER_DAC);
+
+	intel_connector_attach_encoder(intel_connector, &crt->base);
+
+	crt->base.type = INTEL_OUTPUT_ANALOG;
+	crt->base.cloneable = (1 << INTEL_OUTPUT_DVO) | (1 << INTEL_OUTPUT_HDMI);
+	if (IS_I830(dev))
+		crt->base.crtc_mask = (1 << 0);
+	else
+		crt->base.crtc_mask = (1 << 0) | (1 << 1) | (1 << 2);
+
+	if (IS_GEN2(dev))
+		connector->interlace_allowed = 0;
+	else
+		connector->interlace_allowed = 1;
+	connector->doublescan_allowed = 0;
+
+	crt->adpa_reg = adpa_reg;
+
+	crt->base.compute_config = intel_crt_compute_config;
+	if (HAS_PCH_SPLIT(dev)) {
+		crt->base.disable = pch_disable_crt;
+		crt->base.post_disable = pch_post_disable_crt;
+	} else {
+		crt->base.disable = intel_disable_crt;
+	}
+	crt->base.enable = intel_enable_crt;
+	if (I915_HAS_HOTPLUG(dev))
+		crt->base.hpd_pin = HPD_CRT;
+	if (HAS_DDI(dev)) {
+		crt->base.get_config = hsw_crt_get_config;
+		crt->base.get_hw_state = intel_ddi_get_hw_state;
+	} else {
+		crt->base.get_config = intel_crt_get_config;
+		crt->base.get_hw_state = intel_crt_get_hw_state;
+	}
+	intel_connector->get_hw_state = intel_connector_get_hw_state;
+	intel_connector->unregister = intel_connector_unregister;
+
+	drm_connector_helper_add(connector, &intel_crt_connector_helper_funcs);
+
+	drm_connector_register(connector);
+
+	if (!I915_HAS_HOTPLUG(dev))
+		intel_connector->polled = DRM_CONNECTOR_POLL_CONNECT;
+
+	/*
+	 * Configure the automatic hotplug detection stuff
+	 */
+	crt->force_hotplug_required = 0;
+
+	/*
+	 * TODO: find a proper way to discover whether we need to set the the
+	 * polarity and link reversal bits or not, instead of relying on the
+	 * BIOS.
+	 */
+	if (HAS_PCH_LPT(dev)) {
+		u32 fdi_config = FDI_RX_POLARITY_REVERSED_LPT |
+				 FDI_RX_LINK_REVERSAL_OVERRIDE;
+
+		dev_priv->fdi_rx_config = I915_READ(FDI_RX_CTL(PIPE_A)) & fdi_config;
+	}
+
+	intel_crt_reset(connector);
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/i915/intel_csr.c
@@ -0,0 +1,532 @@
+/*
+ * Copyright © 2014 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ */
+#include <linux/firmware.h>
+#include "i915_drv.h"
+#include "i915_reg.h"
+
+/**
+ * DOC: csr support for dmc
+ *
+ * Display Context Save and Restore (CSR) firmware support added from gen9
+ * onwards to drive newly added DMC (Display microcontroller) in display
+ * engine to save and restore the state of display engine when it enter into
+ * low-power state and comes back to normal.
+ *
+ * Firmware loading status will be one of the below states: FW_UNINITIALIZED,
+ * FW_LOADED, FW_FAILED.
+ *
+ * Once the firmware is written into the registers status will be moved from
+ * FW_UNINITIALIZED to FW_LOADED and for any erroneous condition status will
+ * be moved to FW_FAILED.
+ */
+
+#define I915_CSR_KBL "i915/kbl_dmc_ver1.bin"
+MODULE_FIRMWARE(I915_CSR_KBL);
+#define KBL_CSR_VERSION_REQUIRED	CSR_VERSION(1, 1)
+
+#define I915_CSR_SKL "i915/skl_dmc_ver1.bin"
+MODULE_FIRMWARE(I915_CSR_SKL);
+#define SKL_CSR_VERSION_REQUIRED	CSR_VERSION(1, 23)
+
+#define I915_CSR_BXT "i915/bxt_dmc_ver1.bin"
+MODULE_FIRMWARE(I915_CSR_BXT);
+#define BXT_CSR_VERSION_REQUIRED	CSR_VERSION(1, 7)
+
+#define FIRMWARE_URL  "https://01.org/linuxgraphics/intel-linux-graphics-firmwares"
+
+
+
+
+#define CSR_MAX_FW_SIZE			0x2FFF
+#define CSR_DEFAULT_FW_OFFSET		0xFFFFFFFF
+
+struct intel_css_header {
+	/* 0x09 for DMC */
+	uint32_t module_type;
+
+	/* Includes the DMC specific header in dwords */
+	uint32_t header_len;
+
+	/* always value would be 0x10000 */
+	uint32_t header_ver;
+
+	/* Not used */
+	uint32_t module_id;
+
+	/* Not used */
+	uint32_t module_vendor;
+
+	/* in YYYYMMDD format */
+	uint32_t date;
+
+	/* Size in dwords (CSS_Headerlen + PackageHeaderLen + dmc FWsLen)/4 */
+	uint32_t size;
+
+	/* Not used */
+	uint32_t key_size;
+
+	/* Not used */
+	uint32_t modulus_size;
+
+	/* Not used */
+	uint32_t exponent_size;
+
+	/* Not used */
+	uint32_t reserved1[12];
+
+	/* Major Minor */
+	uint32_t version;
+
+	/* Not used */
+	uint32_t reserved2[8];
+
+	/* Not used */
+	uint32_t kernel_header_info;
+} __packed;
+
+struct intel_fw_info {
+	uint16_t reserved1;
+
+	/* Stepping (A, B, C, ..., *). * is a wildcard */
+	char stepping;
+
+	/* Sub-stepping (0, 1, ..., *). * is a wildcard */
+	char substepping;
+
+	uint32_t offset;
+	uint32_t reserved2;
+} __packed;
+
+struct intel_package_header {
+	/* DMC container header length in dwords */
+	unsigned char header_len;
+
+	/* always value would be 0x01 */
+	unsigned char header_ver;
+
+	unsigned char reserved[10];
+
+	/* Number of valid entries in the FWInfo array below */
+	uint32_t num_entries;
+
+	struct intel_fw_info fw_info[20];
+} __packed;
+
+struct intel_dmc_header {
+	/* always value would be 0x40403E3E */
+	uint32_t signature;
+
+	/* DMC binary header length */
+	unsigned char header_len;
+
+	/* 0x01 */
+	unsigned char header_ver;
+
+	/* Reserved */
+	uint16_t dmcc_ver;
+
+	/* Major, Minor */
+	uint32_t	project;
+
+	/* Firmware program size (excluding header) in dwords */
+	uint32_t	fw_size;
+
+	/* Major Minor version */
+	uint32_t fw_version;
+
+	/* Number of valid MMIO cycles present. */
+	uint32_t mmio_count;
+
+	/* MMIO address */
+	uint32_t mmioaddr[8];
+
+	/* MMIO data */
+	uint32_t mmiodata[8];
+
+	/* FW filename  */
+	unsigned char dfile[32];
+
+	uint32_t reserved1[2];
+} __packed;
+
+struct stepping_info {
+	char stepping;
+	char substepping;
+};
+
+static const struct stepping_info kbl_stepping_info[] = {
+	{'A', '0'}, {'B', '0'}, {'C', '0'},
+	{'D', '0'}, {'E', '0'}, {'F', '0'},
+	{'G', '0'}, {'H', '0'}, {'I', '0'},
+};
+
+static const struct stepping_info skl_stepping_info[] = {
+	{'A', '0'}, {'B', '0'}, {'C', '0'},
+	{'D', '0'}, {'E', '0'}, {'F', '0'},
+	{'G', '0'}, {'H', '0'}, {'I', '0'},
+	{'J', '0'}, {'K', '0'}
+};
+
+static const struct stepping_info bxt_stepping_info[] = {
+	{'A', '0'}, {'A', '1'}, {'A', '2'},
+	{'B', '0'}, {'B', '1'}, {'B', '2'}
+};
+
+static const struct stepping_info no_stepping_info = { '*', '*' };
+
+static const struct stepping_info *
+intel_get_stepping_info(struct drm_i915_private *dev_priv)
+{
+	const struct stepping_info *si;
+	unsigned int size;
+
+	if (IS_KABYLAKE(dev_priv)) {
+		size = ARRAY_SIZE(kbl_stepping_info);
+		si = kbl_stepping_info;
+	} else if (IS_SKYLAKE(dev_priv)) {
+		size = ARRAY_SIZE(skl_stepping_info);
+		si = skl_stepping_info;
+	} else if (IS_BROXTON(dev_priv)) {
+		size = ARRAY_SIZE(bxt_stepping_info);
+		si = bxt_stepping_info;
+	} else {
+		size = 0;
+	}
+
+	if (INTEL_REVID(dev_priv) < size)
+		return si + INTEL_REVID(dev_priv);
+
+	return &no_stepping_info;
+}
+
+static void gen9_set_dc_state_debugmask(struct drm_i915_private *dev_priv)
+{
+	uint32_t val, mask;
+
+	mask = DC_STATE_DEBUG_MASK_MEMORY_UP;
+
+	if (IS_BROXTON(dev_priv))
+		mask |= DC_STATE_DEBUG_MASK_CORES;
+
+	/* The below bit doesn't need to be cleared ever afterwards */
+	val = I915_READ(DC_STATE_DEBUG);
+	if ((val & mask) != mask) {
+		val |= mask;
+		I915_WRITE(DC_STATE_DEBUG, val);
+		POSTING_READ(DC_STATE_DEBUG);
+	}
+}
+
+/**
+ * intel_csr_load_program() - write the firmware from memory to register.
+ * @dev_priv: i915 drm device.
+ *
+ * CSR firmware is read from a .bin file and kept in internal memory one time.
+ * Everytime display comes back from low power state this function is called to
+ * copy the firmware from internal memory to registers.
+ */
+void intel_csr_load_program(struct drm_i915_private *dev_priv)
+{
+	u32 *payload = dev_priv->csr.dmc_payload;
+	uint32_t i, fw_size;
+
+	if (!IS_GEN9(dev_priv)) {
+		DRM_ERROR("No CSR support available for this platform\n");
+		return;
+	}
+
+	if (!dev_priv->csr.dmc_payload) {
+		DRM_ERROR("Tried to program CSR with empty payload\n");
+		return;
+	}
+
+	fw_size = dev_priv->csr.dmc_fw_size;
+	for (i = 0; i < fw_size; i++)
+		I915_WRITE(CSR_PROGRAM(i), payload[i]);
+
+	for (i = 0; i < dev_priv->csr.mmio_count; i++) {
+		I915_WRITE(dev_priv->csr.mmioaddr[i],
+			   dev_priv->csr.mmiodata[i]);
+	}
+
+	dev_priv->csr.dc_state = 0;
+
+	gen9_set_dc_state_debugmask(dev_priv);
+}
+
+static uint32_t *parse_csr_fw(struct drm_i915_private *dev_priv,
+			      const struct firmware *fw)
+{
+	struct intel_css_header *css_header;
+	struct intel_package_header *package_header;
+	struct intel_dmc_header *dmc_header;
+	struct intel_csr *csr = &dev_priv->csr;
+	const struct stepping_info *si = intel_get_stepping_info(dev_priv);
+	uint32_t dmc_offset = CSR_DEFAULT_FW_OFFSET, readcount = 0, nbytes;
+	uint32_t i;
+	uint32_t *dmc_payload;
+	uint32_t required_min_version;
+
+	if (!fw)
+		return NULL;
+
+	/* Extract CSS Header information*/
+	css_header = (struct intel_css_header *)fw->data;
+	if (sizeof(struct intel_css_header) !=
+	    (css_header->header_len * 4)) {
+		DRM_ERROR("Firmware has wrong CSS header length %u bytes\n",
+			  (css_header->header_len * 4));
+		return NULL;
+	}
+
+	csr->version = css_header->version;
+
+	if (IS_KABYLAKE(dev_priv)) {
+		required_min_version = KBL_CSR_VERSION_REQUIRED;
+	} else if (IS_SKYLAKE(dev_priv)) {
+		required_min_version = SKL_CSR_VERSION_REQUIRED;
+	} else if (IS_BROXTON(dev_priv)) {
+		required_min_version = BXT_CSR_VERSION_REQUIRED;
+	} else {
+		MISSING_CASE(INTEL_REVID(dev_priv));
+		required_min_version = 0;
+	}
+
+	if (csr->version < required_min_version) {
+		DRM_INFO("Refusing to load old DMC firmware v%u.%u,"
+			 " please upgrade to v%u.%u or later"
+			   " [" FIRMWARE_URL "].\n",
+			 CSR_VERSION_MAJOR(csr->version),
+			 CSR_VERSION_MINOR(csr->version),
+			 CSR_VERSION_MAJOR(required_min_version),
+			 CSR_VERSION_MINOR(required_min_version));
+		return NULL;
+	}
+
+	readcount += sizeof(struct intel_css_header);
+
+	/* Extract Package Header information*/
+	package_header = (struct intel_package_header *)
+		&fw->data[readcount];
+	if (sizeof(struct intel_package_header) !=
+	    (package_header->header_len * 4)) {
+		DRM_ERROR("Firmware has wrong package header length %u bytes\n",
+			  (package_header->header_len * 4));
+		return NULL;
+	}
+	readcount += sizeof(struct intel_package_header);
+
+	/* Search for dmc_offset to find firware binary. */
+	for (i = 0; i < package_header->num_entries; i++) {
+		if (package_header->fw_info[i].substepping == '*' &&
+		    si->stepping == package_header->fw_info[i].stepping) {
+			dmc_offset = package_header->fw_info[i].offset;
+			break;
+		} else if (si->stepping == package_header->fw_info[i].stepping &&
+			   si->substepping == package_header->fw_info[i].substepping) {
+			dmc_offset = package_header->fw_info[i].offset;
+			break;
+		} else if (package_header->fw_info[i].stepping == '*' &&
+			   package_header->fw_info[i].substepping == '*')
+			dmc_offset = package_header->fw_info[i].offset;
+	}
+	if (dmc_offset == CSR_DEFAULT_FW_OFFSET) {
+		DRM_ERROR("Firmware not supported for %c stepping\n",
+			  si->stepping);
+		return NULL;
+	}
+	readcount += dmc_offset;
+
+	/* Extract dmc_header information. */
+	dmc_header = (struct intel_dmc_header *)&fw->data[readcount];
+	if (sizeof(struct intel_dmc_header) != (dmc_header->header_len)) {
+		DRM_ERROR("Firmware has wrong dmc header length %u bytes\n",
+			  (dmc_header->header_len));
+		return NULL;
+	}
+	readcount += sizeof(struct intel_dmc_header);
+
+	/* Cache the dmc header info. */
+	if (dmc_header->mmio_count > ARRAY_SIZE(csr->mmioaddr)) {
+		DRM_ERROR("Firmware has wrong mmio count %u\n",
+			  dmc_header->mmio_count);
+		return NULL;
+	}
+	csr->mmio_count = dmc_header->mmio_count;
+	for (i = 0; i < dmc_header->mmio_count; i++) {
+		if (dmc_header->mmioaddr[i] < CSR_MMIO_START_RANGE ||
+		    dmc_header->mmioaddr[i] > CSR_MMIO_END_RANGE) {
+			DRM_ERROR(" Firmware has wrong mmio address 0x%x\n",
+				  dmc_header->mmioaddr[i]);
+			return NULL;
+		}
+		csr->mmioaddr[i] = _MMIO(dmc_header->mmioaddr[i]);
+		csr->mmiodata[i] = dmc_header->mmiodata[i];
+	}
+
+	/* fw_size is in dwords, so multiplied by 4 to convert into bytes. */
+	nbytes = dmc_header->fw_size * 4;
+	if (nbytes > CSR_MAX_FW_SIZE) {
+		DRM_ERROR("CSR firmware too big (%u) bytes\n", nbytes);
+		return NULL;
+	}
+	csr->dmc_fw_size = dmc_header->fw_size;
+
+	dmc_payload = kmalloc(nbytes, GFP_KERNEL);
+	if (!dmc_payload) {
+		DRM_ERROR("Memory allocation failed for dmc payload\n");
+		return NULL;
+	}
+
+	return memcpy(dmc_payload, &fw->data[readcount], nbytes);
+}
+
+static void csr_load_work_fn(struct work_struct *work)
+{
+	struct drm_i915_private *dev_priv;
+	struct intel_csr *csr;
+	const struct firmware *fw;
+	int ret;
+
+	dev_priv = container_of(work, typeof(*dev_priv), csr.work);
+	csr = &dev_priv->csr;
+
+	ret = request_firmware(&fw, dev_priv->csr.fw_path,
+			       &dev_priv->dev->pdev->dev);
+	if (fw)
+		dev_priv->csr.dmc_payload = parse_csr_fw(dev_priv, fw);
+
+	if (dev_priv->csr.dmc_payload) {
+		intel_csr_load_program(dev_priv);
+
+		intel_display_power_put(dev_priv, POWER_DOMAIN_INIT);
+
+		DRM_INFO("Finished loading %s (v%u.%u)\n",
+			 dev_priv->csr.fw_path,
+			 CSR_VERSION_MAJOR(csr->version),
+			 CSR_VERSION_MINOR(csr->version));
+	} else {
+		dev_notice(dev_priv->dev->dev,
+			   "Failed to load DMC firmware"
+			   " [" FIRMWARE_URL "],"
+			   " disabling runtime power management.\n");
+	}
+
+	release_firmware(fw);
+}
+
+/**
+ * intel_csr_ucode_init() - initialize the firmware loading.
+ * @dev_priv: i915 drm device.
+ *
+ * This function is called at the time of loading the display driver to read
+ * firmware from a .bin file and copied into a internal memory.
+ */
+void intel_csr_ucode_init(struct drm_i915_private *dev_priv)
+{
+	struct intel_csr *csr = &dev_priv->csr;
+
+	INIT_WORK(&dev_priv->csr.work, csr_load_work_fn);
+
+	if (!HAS_CSR(dev_priv))
+		return;
+
+	if (IS_KABYLAKE(dev_priv))
+		csr->fw_path = I915_CSR_KBL;
+	else if (IS_SKYLAKE(dev_priv))
+		csr->fw_path = I915_CSR_SKL;
+	else if (IS_BROXTON(dev_priv))
+		csr->fw_path = I915_CSR_BXT;
+	else {
+		DRM_ERROR("Unexpected: no known CSR firmware for platform\n");
+		return;
+	}
+
+	DRM_DEBUG_KMS("Loading %s\n", csr->fw_path);
+
+	/*
+	 * Obtain a runtime pm reference, until CSR is loaded,
+	 * to avoid entering runtime-suspend.
+	 */
+	intel_display_power_get(dev_priv, POWER_DOMAIN_INIT);
+
+	schedule_work(&dev_priv->csr.work);
+}
+
+/**
+ * intel_csr_ucode_suspend() - prepare CSR firmware before system suspend
+ * @dev_priv: i915 drm device
+ *
+ * Prepare the DMC firmware before entering system suspend. This includes
+ * flushing pending work items and releasing any resources acquired during
+ * init.
+ */
+void intel_csr_ucode_suspend(struct drm_i915_private *dev_priv)
+{
+	if (!HAS_CSR(dev_priv))
+		return;
+
+	flush_work(&dev_priv->csr.work);
+
+	/* Drop the reference held in case DMC isn't loaded. */
+	if (!dev_priv->csr.dmc_payload)
+		intel_display_power_put(dev_priv, POWER_DOMAIN_INIT);
+}
+
+/**
+ * intel_csr_ucode_resume() - init CSR firmware during system resume
+ * @dev_priv: i915 drm device
+ *
+ * Reinitialize the DMC firmware during system resume, reacquiring any
+ * resources released in intel_csr_ucode_suspend().
+ */
+void intel_csr_ucode_resume(struct drm_i915_private *dev_priv)
+{
+	if (!HAS_CSR(dev_priv))
+		return;
+
+	/*
+	 * Reacquire the reference to keep RPM disabled in case DMC isn't
+	 * loaded.
+	 */
+	if (!dev_priv->csr.dmc_payload)
+		intel_display_power_get(dev_priv, POWER_DOMAIN_INIT);
+}
+
+/**
+ * intel_csr_ucode_fini() - unload the CSR firmware.
+ * @dev_priv: i915 drm device.
+ *
+ * Firmmware unloading includes freeing the internal memory and reset the
+ * firmware loading status.
+ */
+void intel_csr_ucode_fini(struct drm_i915_private *dev_priv)
+{
+	if (!HAS_CSR(dev_priv))
+		return;
+
+	intel_csr_ucode_suspend(dev_priv);
+
+	kfree(dev_priv->csr.dmc_payload);
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/i915/intel_ddi.c
@@ -0,0 +1,2414 @@
+/*
+ * Copyright © 2012 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Eugeni Dodonov <eugeni.dodonov@intel.com>
+ *
+ */
+
+#include "i915_drv.h"
+#include "intel_drv.h"
+
+struct ddi_buf_trans {
+	u32 trans1;	/* balance leg enable, de-emph level */
+	u32 trans2;	/* vref sel, vswing */
+	u8 i_boost;	/* SKL: I_boost; valid: 0x0, 0x1, 0x3, 0x7 */
+};
+
+/* HDMI/DVI modes ignore everything but the last 2 items. So we share
+ * them for both DP and FDI transports, allowing those ports to
+ * automatically adapt to HDMI connections as well
+ */
+static const struct ddi_buf_trans hsw_ddi_translations_dp[] = {
+	{ 0x00FFFFFF, 0x0006000E, 0x0 },
+	{ 0x00D75FFF, 0x0005000A, 0x0 },
+	{ 0x00C30FFF, 0x00040006, 0x0 },
+	{ 0x80AAAFFF, 0x000B0000, 0x0 },
+	{ 0x00FFFFFF, 0x0005000A, 0x0 },
+	{ 0x00D75FFF, 0x000C0004, 0x0 },
+	{ 0x80C30FFF, 0x000B0000, 0x0 },
+	{ 0x00FFFFFF, 0x00040006, 0x0 },
+	{ 0x80D75FFF, 0x000B0000, 0x0 },
+};
+
+static const struct ddi_buf_trans hsw_ddi_translations_fdi[] = {
+	{ 0x00FFFFFF, 0x0007000E, 0x0 },
+	{ 0x00D75FFF, 0x000F000A, 0x0 },
+	{ 0x00C30FFF, 0x00060006, 0x0 },
+	{ 0x00AAAFFF, 0x001E0000, 0x0 },
+	{ 0x00FFFFFF, 0x000F000A, 0x0 },
+	{ 0x00D75FFF, 0x00160004, 0x0 },
+	{ 0x00C30FFF, 0x001E0000, 0x0 },
+	{ 0x00FFFFFF, 0x00060006, 0x0 },
+	{ 0x00D75FFF, 0x001E0000, 0x0 },
+};
+
+static const struct ddi_buf_trans hsw_ddi_translations_hdmi[] = {
+					/* Idx	NT mV d	T mV d	db	*/
+	{ 0x00FFFFFF, 0x0006000E, 0x0 },/* 0:	400	400	0	*/
+	{ 0x00E79FFF, 0x000E000C, 0x0 },/* 1:	400	500	2	*/
+	{ 0x00D75FFF, 0x0005000A, 0x0 },/* 2:	400	600	3.5	*/
+	{ 0x00FFFFFF, 0x0005000A, 0x0 },/* 3:	600	600	0	*/
+	{ 0x00E79FFF, 0x001D0007, 0x0 },/* 4:	600	750	2	*/
+	{ 0x00D75FFF, 0x000C0004, 0x0 },/* 5:	600	900	3.5	*/
+	{ 0x00FFFFFF, 0x00040006, 0x0 },/* 6:	800	800	0	*/
+	{ 0x80E79FFF, 0x00030002, 0x0 },/* 7:	800	1000	2	*/
+	{ 0x00FFFFFF, 0x00140005, 0x0 },/* 8:	850	850	0	*/
+	{ 0x00FFFFFF, 0x000C0004, 0x0 },/* 9:	900	900	0	*/
+	{ 0x00FFFFFF, 0x001C0003, 0x0 },/* 10:	950	950	0	*/
+	{ 0x80FFFFFF, 0x00030002, 0x0 },/* 11:	1000	1000	0	*/
+};
+
+static const struct ddi_buf_trans bdw_ddi_translations_edp[] = {
+	{ 0x00FFFFFF, 0x00000012, 0x0 },
+	{ 0x00EBAFFF, 0x00020011, 0x0 },
+	{ 0x00C71FFF, 0x0006000F, 0x0 },
+	{ 0x00AAAFFF, 0x000E000A, 0x0 },
+	{ 0x00FFFFFF, 0x00020011, 0x0 },
+	{ 0x00DB6FFF, 0x0005000F, 0x0 },
+	{ 0x00BEEFFF, 0x000A000C, 0x0 },
+	{ 0x00FFFFFF, 0x0005000F, 0x0 },
+	{ 0x00DB6FFF, 0x000A000C, 0x0 },
+};
+
+static const struct ddi_buf_trans bdw_ddi_translations_dp[] = {
+	{ 0x00FFFFFF, 0x0007000E, 0x0 },
+	{ 0x00D75FFF, 0x000E000A, 0x0 },
+	{ 0x00BEFFFF, 0x00140006, 0x0 },
+	{ 0x80B2CFFF, 0x001B0002, 0x0 },
+	{ 0x00FFFFFF, 0x000E000A, 0x0 },
+	{ 0x00DB6FFF, 0x00160005, 0x0 },
+	{ 0x80C71FFF, 0x001A0002, 0x0 },
+	{ 0x00F7DFFF, 0x00180004, 0x0 },
+	{ 0x80D75FFF, 0x001B0002, 0x0 },
+};
+
+static const struct ddi_buf_trans bdw_ddi_translations_fdi[] = {
+	{ 0x00FFFFFF, 0x0001000E, 0x0 },
+	{ 0x00D75FFF, 0x0004000A, 0x0 },
+	{ 0x00C30FFF, 0x00070006, 0x0 },
+	{ 0x00AAAFFF, 0x000C0000, 0x0 },
+	{ 0x00FFFFFF, 0x0004000A, 0x0 },
+	{ 0x00D75FFF, 0x00090004, 0x0 },
+	{ 0x00C30FFF, 0x000C0000, 0x0 },
+	{ 0x00FFFFFF, 0x00070006, 0x0 },
+	{ 0x00D75FFF, 0x000C0000, 0x0 },
+};
+
+static const struct ddi_buf_trans bdw_ddi_translations_hdmi[] = {
+					/* Idx	NT mV d	T mV df	db	*/
+	{ 0x00FFFFFF, 0x0007000E, 0x0 },/* 0:	400	400	0	*/
+	{ 0x00D75FFF, 0x000E000A, 0x0 },/* 1:	400	600	3.5	*/
+	{ 0x00BEFFFF, 0x00140006, 0x0 },/* 2:	400	800	6	*/
+	{ 0x00FFFFFF, 0x0009000D, 0x0 },/* 3:	450	450	0	*/
+	{ 0x00FFFFFF, 0x000E000A, 0x0 },/* 4:	600	600	0	*/
+	{ 0x00D7FFFF, 0x00140006, 0x0 },/* 5:	600	800	2.5	*/
+	{ 0x80CB2FFF, 0x001B0002, 0x0 },/* 6:	600	1000	4.5	*/
+	{ 0x00FFFFFF, 0x00140006, 0x0 },/* 7:	800	800	0	*/
+	{ 0x80E79FFF, 0x001B0002, 0x0 },/* 8:	800	1000	2	*/
+	{ 0x80FFFFFF, 0x001B0002, 0x0 },/* 9:	1000	1000	0	*/
+};
+
+/* Skylake H and S */
+static const struct ddi_buf_trans skl_ddi_translations_dp[] = {
+	{ 0x00002016, 0x000000A0, 0x0 },
+	{ 0x00005012, 0x0000009B, 0x0 },
+	{ 0x00007011, 0x00000088, 0x0 },
+	{ 0x80009010, 0x000000C0, 0x1 },
+	{ 0x00002016, 0x0000009B, 0x0 },
+	{ 0x00005012, 0x00000088, 0x0 },
+	{ 0x80007011, 0x000000C0, 0x1 },
+	{ 0x00002016, 0x000000DF, 0x0 },
+	{ 0x80005012, 0x000000C0, 0x1 },
+};
+
+/* Skylake U */
+static const struct ddi_buf_trans skl_u_ddi_translations_dp[] = {
+	{ 0x0000201B, 0x000000A2, 0x0 },
+	{ 0x00005012, 0x00000088, 0x0 },
+	{ 0x80007011, 0x000000CD, 0x0 },
+	{ 0x80009010, 0x000000C0, 0x1 },
+	{ 0x0000201B, 0x0000009D, 0x0 },
+	{ 0x80005012, 0x000000C0, 0x1 },
+	{ 0x80007011, 0x000000C0, 0x1 },
+	{ 0x00002016, 0x00000088, 0x0 },
+	{ 0x80005012, 0x000000C0, 0x1 },
+};
+
+/* Skylake Y */
+static const struct ddi_buf_trans skl_y_ddi_translations_dp[] = {
+	{ 0x00000018, 0x000000A2, 0x0 },
+	{ 0x00005012, 0x00000088, 0x0 },
+	{ 0x80007011, 0x000000CD, 0x0 },
+	{ 0x80009010, 0x000000C0, 0x3 },
+	{ 0x00000018, 0x0000009D, 0x0 },
+	{ 0x80005012, 0x000000C0, 0x3 },
+	{ 0x80007011, 0x000000C0, 0x3 },
+	{ 0x00000018, 0x00000088, 0x0 },
+	{ 0x80005012, 0x000000C0, 0x3 },
+};
+
+/*
+ * Skylake H and S
+ * eDP 1.4 low vswing translation parameters
+ */
+static const struct ddi_buf_trans skl_ddi_translations_edp[] = {
+	{ 0x00000018, 0x000000A8, 0x0 },
+	{ 0x00004013, 0x000000A9, 0x0 },
+	{ 0x00007011, 0x000000A2, 0x0 },
+	{ 0x00009010, 0x0000009C, 0x0 },
+	{ 0x00000018, 0x000000A9, 0x0 },
+	{ 0x00006013, 0x000000A2, 0x0 },
+	{ 0x00007011, 0x000000A6, 0x0 },
+	{ 0x00000018, 0x000000AB, 0x0 },
+	{ 0x00007013, 0x0000009F, 0x0 },
+	{ 0x00000018, 0x000000DF, 0x0 },
+};
+
+/*
+ * Skylake U
+ * eDP 1.4 low vswing translation parameters
+ */
+static const struct ddi_buf_trans skl_u_ddi_translations_edp[] = {
+	{ 0x00000018, 0x000000A8, 0x0 },
+	{ 0x00004013, 0x000000A9, 0x0 },
+	{ 0x00007011, 0x000000A2, 0x0 },
+	{ 0x00009010, 0x0000009C, 0x0 },
+	{ 0x00000018, 0x000000A9, 0x0 },
+	{ 0x00006013, 0x000000A2, 0x0 },
+	{ 0x00007011, 0x000000A6, 0x0 },
+	{ 0x00002016, 0x000000AB, 0x0 },
+	{ 0x00005013, 0x0000009F, 0x0 },
+	{ 0x00000018, 0x000000DF, 0x0 },
+};
+
+/*
+ * Skylake Y
+ * eDP 1.4 low vswing translation parameters
+ */
+static const struct ddi_buf_trans skl_y_ddi_translations_edp[] = {
+	{ 0x00000018, 0x000000A8, 0x0 },
+	{ 0x00004013, 0x000000AB, 0x0 },
+	{ 0x00007011, 0x000000A4, 0x0 },
+	{ 0x00009010, 0x000000DF, 0x0 },
+	{ 0x00000018, 0x000000AA, 0x0 },
+	{ 0x00006013, 0x000000A4, 0x0 },
+	{ 0x00007011, 0x0000009D, 0x0 },
+	{ 0x00000018, 0x000000A0, 0x0 },
+	{ 0x00006012, 0x000000DF, 0x0 },
+	{ 0x00000018, 0x0000008A, 0x0 },
+};
+
+/* Skylake U, H and S */
+static const struct ddi_buf_trans skl_ddi_translations_hdmi[] = {
+	{ 0x00000018, 0x000000AC, 0x0 },
+	{ 0x00005012, 0x0000009D, 0x0 },
+	{ 0x00007011, 0x00000088, 0x0 },
+	{ 0x00000018, 0x000000A1, 0x0 },
+	{ 0x00000018, 0x00000098, 0x0 },
+	{ 0x00004013, 0x00000088, 0x0 },
+	{ 0x80006012, 0x000000CD, 0x1 },
+	{ 0x00000018, 0x000000DF, 0x0 },
+	{ 0x80003015, 0x000000CD, 0x1 },	/* Default */
+	{ 0x80003015, 0x000000C0, 0x1 },
+	{ 0x80000018, 0x000000C0, 0x1 },
+};
+
+/* Skylake Y */
+static const struct ddi_buf_trans skl_y_ddi_translations_hdmi[] = {
+	{ 0x00000018, 0x000000A1, 0x0 },
+	{ 0x00005012, 0x000000DF, 0x0 },
+	{ 0x80007011, 0x000000CB, 0x3 },
+	{ 0x00000018, 0x000000A4, 0x0 },
+	{ 0x00000018, 0x0000009D, 0x0 },
+	{ 0x00004013, 0x00000080, 0x0 },
+	{ 0x80006013, 0x000000C0, 0x3 },
+	{ 0x00000018, 0x0000008A, 0x0 },
+	{ 0x80003015, 0x000000C0, 0x3 },	/* Default */
+	{ 0x80003015, 0x000000C0, 0x3 },
+	{ 0x80000018, 0x000000C0, 0x3 },
+};
+
+struct bxt_ddi_buf_trans {
+	u32 margin;	/* swing value */
+	u32 scale;	/* scale value */
+	u32 enable;	/* scale enable */
+	u32 deemphasis;
+	bool default_index; /* true if the entry represents default value */
+};
+
+static const struct bxt_ddi_buf_trans bxt_ddi_translations_dp[] = {
+					/* Idx	NT mV diff	db  */
+	{ 52,  0x9A, 0, 128, true  },	/* 0:	400		0   */
+	{ 78,  0x9A, 0, 85,  false },	/* 1:	400		3.5 */
+	{ 104, 0x9A, 0, 64,  false },	/* 2:	400		6   */
+	{ 154, 0x9A, 0, 43,  false },	/* 3:	400		9.5 */
+	{ 77,  0x9A, 0, 128, false },	/* 4:	600		0   */
+	{ 116, 0x9A, 0, 85,  false },	/* 5:	600		3.5 */
+	{ 154, 0x9A, 0, 64,  false },	/* 6:	600		6   */
+	{ 102, 0x9A, 0, 128, false },	/* 7:	800		0   */
+	{ 154, 0x9A, 0, 85,  false },	/* 8:	800		3.5 */
+	{ 154, 0x9A, 1, 128, false },	/* 9:	1200		0   */
+};
+
+static const struct bxt_ddi_buf_trans bxt_ddi_translations_edp[] = {
+					/* Idx	NT mV diff	db  */
+	{ 26, 0, 0, 128, false },	/* 0:	200		0   */
+	{ 38, 0, 0, 112, false },	/* 1:	200		1.5 */
+	{ 48, 0, 0, 96,  false },	/* 2:	200		4   */
+	{ 54, 0, 0, 69,  false },	/* 3:	200		6   */
+	{ 32, 0, 0, 128, false },	/* 4:	250		0   */
+	{ 48, 0, 0, 104, false },	/* 5:	250		1.5 */
+	{ 54, 0, 0, 85,  false },	/* 6:	250		4   */
+	{ 43, 0, 0, 128, false },	/* 7:	300		0   */
+	{ 54, 0, 0, 101, false },	/* 8:	300		1.5 */
+	{ 48, 0, 0, 128, false },	/* 9:	300		0   */
+};
+
+/* BSpec has 2 recommended values - entries 0 and 8.
+ * Using the entry with higher vswing.
+ */
+static const struct bxt_ddi_buf_trans bxt_ddi_translations_hdmi[] = {
+					/* Idx	NT mV diff	db  */
+	{ 52,  0x9A, 0, 128, false },	/* 0:	400		0   */
+	{ 52,  0x9A, 0, 85,  false },	/* 1:	400		3.5 */
+	{ 52,  0x9A, 0, 64,  false },	/* 2:	400		6   */
+	{ 42,  0x9A, 0, 43,  false },	/* 3:	400		9.5 */
+	{ 77,  0x9A, 0, 128, false },	/* 4:	600		0   */
+	{ 77,  0x9A, 0, 85,  false },	/* 5:	600		3.5 */
+	{ 77,  0x9A, 0, 64,  false },	/* 6:	600		6   */
+	{ 102, 0x9A, 0, 128, false },	/* 7:	800		0   */
+	{ 102, 0x9A, 0, 85,  false },	/* 8:	800		3.5 */
+	{ 154, 0x9A, 1, 128, true },	/* 9:	1200		0   */
+};
+
+static void bxt_ddi_vswing_sequence(struct drm_i915_private *dev_priv,
+				    u32 level, enum port port, int type);
+
+static void ddi_get_encoder_port(struct intel_encoder *intel_encoder,
+				 struct intel_digital_port **dig_port,
+				 enum port *port)
+{
+	struct drm_encoder *encoder = &intel_encoder->base;
+
+	switch (intel_encoder->type) {
+	case INTEL_OUTPUT_DP_MST:
+		*dig_port = enc_to_mst(encoder)->primary;
+		*port = (*dig_port)->port;
+		break;
+	default:
+		WARN(1, "Invalid DDI encoder type %d\n", intel_encoder->type);
+		/* fallthrough and treat as unknown */
+	case INTEL_OUTPUT_DISPLAYPORT:
+	case INTEL_OUTPUT_EDP:
+	case INTEL_OUTPUT_HDMI:
+	case INTEL_OUTPUT_UNKNOWN:
+		*dig_port = enc_to_dig_port(encoder);
+		*port = (*dig_port)->port;
+		break;
+	case INTEL_OUTPUT_ANALOG:
+		*dig_port = NULL;
+		*port = PORT_E;
+		break;
+	}
+}
+
+enum port intel_ddi_get_encoder_port(struct intel_encoder *intel_encoder)
+{
+	struct intel_digital_port *dig_port;
+	enum port port;
+
+	ddi_get_encoder_port(intel_encoder, &dig_port, &port);
+
+	return port;
+}
+
+static const struct ddi_buf_trans *
+skl_get_buf_trans_dp(struct drm_i915_private *dev_priv, int *n_entries)
+{
+	if (IS_SKL_ULX(dev_priv) || IS_KBL_ULX(dev_priv)) {
+		*n_entries = ARRAY_SIZE(skl_y_ddi_translations_dp);
+		return skl_y_ddi_translations_dp;
+	} else if (IS_SKL_ULT(dev_priv) || IS_KBL_ULT(dev_priv)) {
+		*n_entries = ARRAY_SIZE(skl_u_ddi_translations_dp);
+		return skl_u_ddi_translations_dp;
+	} else {
+		*n_entries = ARRAY_SIZE(skl_ddi_translations_dp);
+		return skl_ddi_translations_dp;
+	}
+}
+
+static const struct ddi_buf_trans *
+skl_get_buf_trans_edp(struct drm_i915_private *dev_priv, int *n_entries)
+{
+	if (dev_priv->vbt.edp.low_vswing) {
+		if (IS_SKL_ULX(dev_priv) || IS_KBL_ULX(dev_priv)) {
+			*n_entries = ARRAY_SIZE(skl_y_ddi_translations_edp);
+			return skl_y_ddi_translations_edp;
+		} else if (IS_SKL_ULT(dev_priv) || IS_KBL_ULT(dev_priv)) {
+			*n_entries = ARRAY_SIZE(skl_u_ddi_translations_edp);
+			return skl_u_ddi_translations_edp;
+		} else {
+			*n_entries = ARRAY_SIZE(skl_ddi_translations_edp);
+			return skl_ddi_translations_edp;
+		}
+	}
+
+	return skl_get_buf_trans_dp(dev_priv, n_entries);
+}
+
+static const struct ddi_buf_trans *
+skl_get_buf_trans_hdmi(struct drm_i915_private *dev_priv, int *n_entries)
+{
+	if (IS_SKL_ULX(dev_priv) || IS_KBL_ULX(dev_priv)) {
+		*n_entries = ARRAY_SIZE(skl_y_ddi_translations_hdmi);
+		return skl_y_ddi_translations_hdmi;
+	} else {
+		*n_entries = ARRAY_SIZE(skl_ddi_translations_hdmi);
+		return skl_ddi_translations_hdmi;
+	}
+}
+
+/*
+ * Starting with Haswell, DDI port buffers must be programmed with correct
+ * values in advance. The buffer values are different for FDI and DP modes,
+ * but the HDMI/DVI fields are shared among those. So we program the DDI
+ * in either FDI or DP modes only, as HDMI connections will work with both
+ * of those
+ */
+void intel_prepare_ddi_buffer(struct intel_encoder *encoder)
+{
+	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
+	u32 iboost_bit = 0;
+	int i, n_hdmi_entries, n_dp_entries, n_edp_entries, hdmi_default_entry,
+	    size;
+	int hdmi_level;
+	enum port port;
+	const struct ddi_buf_trans *ddi_translations_fdi;
+	const struct ddi_buf_trans *ddi_translations_dp;
+	const struct ddi_buf_trans *ddi_translations_edp;
+	const struct ddi_buf_trans *ddi_translations_hdmi;
+	const struct ddi_buf_trans *ddi_translations;
+
+	port = intel_ddi_get_encoder_port(encoder);
+	hdmi_level = dev_priv->vbt.ddi_port_info[port].hdmi_level_shift;
+
+	if (IS_BROXTON(dev_priv)) {
+		if (encoder->type != INTEL_OUTPUT_HDMI)
+			return;
+
+		/* Vswing programming for HDMI */
+		bxt_ddi_vswing_sequence(dev_priv, hdmi_level, port,
+					INTEL_OUTPUT_HDMI);
+		return;
+	}
+
+	if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv)) {
+		ddi_translations_fdi = NULL;
+		ddi_translations_dp =
+				skl_get_buf_trans_dp(dev_priv, &n_dp_entries);
+		ddi_translations_edp =
+				skl_get_buf_trans_edp(dev_priv, &n_edp_entries);
+		ddi_translations_hdmi =
+				skl_get_buf_trans_hdmi(dev_priv, &n_hdmi_entries);
+		hdmi_default_entry = 8;
+		/* If we're boosting the current, set bit 31 of trans1 */
+		if (dev_priv->vbt.ddi_port_info[port].hdmi_boost_level ||
+		    dev_priv->vbt.ddi_port_info[port].dp_boost_level)
+			iboost_bit = 1<<31;
+
+		if (WARN_ON(encoder->type == INTEL_OUTPUT_EDP &&
+			    port != PORT_A && port != PORT_E &&
+			    n_edp_entries > 9))
+			n_edp_entries = 9;
+	} else if (IS_BROADWELL(dev_priv)) {
+		ddi_translations_fdi = bdw_ddi_translations_fdi;
+		ddi_translations_dp = bdw_ddi_translations_dp;
+
+		if (dev_priv->vbt.edp.low_vswing) {
+			ddi_translations_edp = bdw_ddi_translations_edp;
+			n_edp_entries = ARRAY_SIZE(bdw_ddi_translations_edp);
+		} else {
+			ddi_translations_edp = bdw_ddi_translations_dp;
+			n_edp_entries = ARRAY_SIZE(bdw_ddi_translations_dp);
+		}
+
+		ddi_translations_hdmi = bdw_ddi_translations_hdmi;
+
+		n_dp_entries = ARRAY_SIZE(bdw_ddi_translations_dp);
+		n_hdmi_entries = ARRAY_SIZE(bdw_ddi_translations_hdmi);
+		hdmi_default_entry = 7;
+	} else if (IS_HASWELL(dev_priv)) {
+		ddi_translations_fdi = hsw_ddi_translations_fdi;
+		ddi_translations_dp = hsw_ddi_translations_dp;
+		ddi_translations_edp = hsw_ddi_translations_dp;
+		ddi_translations_hdmi = hsw_ddi_translations_hdmi;
+		n_dp_entries = n_edp_entries = ARRAY_SIZE(hsw_ddi_translations_dp);
+		n_hdmi_entries = ARRAY_SIZE(hsw_ddi_translations_hdmi);
+		hdmi_default_entry = 6;
+	} else {
+		WARN(1, "ddi translation table missing\n");
+		ddi_translations_edp = bdw_ddi_translations_dp;
+		ddi_translations_fdi = bdw_ddi_translations_fdi;
+		ddi_translations_dp = bdw_ddi_translations_dp;
+		ddi_translations_hdmi = bdw_ddi_translations_hdmi;
+		n_edp_entries = ARRAY_SIZE(bdw_ddi_translations_edp);
+		n_dp_entries = ARRAY_SIZE(bdw_ddi_translations_dp);
+		n_hdmi_entries = ARRAY_SIZE(bdw_ddi_translations_hdmi);
+		hdmi_default_entry = 7;
+	}
+
+	switch (encoder->type) {
+	case INTEL_OUTPUT_EDP:
+		ddi_translations = ddi_translations_edp;
+		size = n_edp_entries;
+		break;
+	case INTEL_OUTPUT_DISPLAYPORT:
+	case INTEL_OUTPUT_HDMI:
+		ddi_translations = ddi_translations_dp;
+		size = n_dp_entries;
+		break;
+	case INTEL_OUTPUT_ANALOG:
+		ddi_translations = ddi_translations_fdi;
+		size = n_dp_entries;
+		break;
+	default:
+		BUG();
+	}
+
+	for (i = 0; i < size; i++) {
+		I915_WRITE(DDI_BUF_TRANS_LO(port, i),
+			   ddi_translations[i].trans1 | iboost_bit);
+		I915_WRITE(DDI_BUF_TRANS_HI(port, i),
+			   ddi_translations[i].trans2);
+	}
+
+	if (encoder->type != INTEL_OUTPUT_HDMI)
+		return;
+
+	/* Choose a good default if VBT is badly populated */
+	if (hdmi_level == HDMI_LEVEL_SHIFT_UNKNOWN ||
+	    hdmi_level >= n_hdmi_entries)
+		hdmi_level = hdmi_default_entry;
+
+	/* Entry 9 is for HDMI: */
+	I915_WRITE(DDI_BUF_TRANS_LO(port, i),
+		   ddi_translations_hdmi[hdmi_level].trans1 | iboost_bit);
+	I915_WRITE(DDI_BUF_TRANS_HI(port, i),
+		   ddi_translations_hdmi[hdmi_level].trans2);
+}
+
+static void intel_wait_ddi_buf_idle(struct drm_i915_private *dev_priv,
+				    enum port port)
+{
+	i915_reg_t reg = DDI_BUF_CTL(port);
+	int i;
+
+	for (i = 0; i < 16; i++) {
+		udelay(1);
+		if (I915_READ(reg) & DDI_BUF_IS_IDLE)
+			return;
+	}
+	DRM_ERROR("Timeout waiting for DDI BUF %c idle bit\n", port_name(port));
+}
+
+/* Starting with Haswell, different DDI ports can work in FDI mode for
+ * connection to the PCH-located connectors. For this, it is necessary to train
+ * both the DDI port and PCH receiver for the desired DDI buffer settings.
+ *
+ * The recommended port to work in FDI mode is DDI E, which we use here. Also,
+ * please note that when FDI mode is active on DDI E, it shares 2 lines with
+ * DDI A (which is used for eDP)
+ */
+
+void hsw_fdi_link_train(struct drm_crtc *crtc)
+{
+	struct drm_device *dev = crtc->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	struct intel_encoder *encoder;
+	u32 temp, i, rx_ctl_val;
+
+	for_each_encoder_on_crtc(dev, crtc, encoder) {
+		WARN_ON(encoder->type != INTEL_OUTPUT_ANALOG);
+		intel_prepare_ddi_buffer(encoder);
+	}
+
+	/* Set the FDI_RX_MISC pwrdn lanes and the 2 workarounds listed at the
+	 * mode set "sequence for CRT port" document:
+	 * - TP1 to TP2 time with the default value
+	 * - FDI delay to 90h
+	 *
+	 * WaFDIAutoLinkSetTimingOverrride:hsw
+	 */
+	I915_WRITE(FDI_RX_MISC(PIPE_A), FDI_RX_PWRDN_LANE1_VAL(2) |
+				  FDI_RX_PWRDN_LANE0_VAL(2) |
+				  FDI_RX_TP1_TO_TP2_48 | FDI_RX_FDI_DELAY_90);
+
+	/* Enable the PCH Receiver FDI PLL */
+	rx_ctl_val = dev_priv->fdi_rx_config | FDI_RX_ENHANCE_FRAME_ENABLE |
+		     FDI_RX_PLL_ENABLE |
+		     FDI_DP_PORT_WIDTH(intel_crtc->config->fdi_lanes);
+	I915_WRITE(FDI_RX_CTL(PIPE_A), rx_ctl_val);
+	POSTING_READ(FDI_RX_CTL(PIPE_A));
+	udelay(220);
+
+	/* Switch from Rawclk to PCDclk */
+	rx_ctl_val |= FDI_PCDCLK;
+	I915_WRITE(FDI_RX_CTL(PIPE_A), rx_ctl_val);
+
+	/* Configure Port Clock Select */
+	I915_WRITE(PORT_CLK_SEL(PORT_E), intel_crtc->config->ddi_pll_sel);
+	WARN_ON(intel_crtc->config->ddi_pll_sel != PORT_CLK_SEL_SPLL);
+
+	/* Start the training iterating through available voltages and emphasis,
+	 * testing each value twice. */
+	for (i = 0; i < ARRAY_SIZE(hsw_ddi_translations_fdi) * 2; i++) {
+		/* Configure DP_TP_CTL with auto-training */
+		I915_WRITE(DP_TP_CTL(PORT_E),
+					DP_TP_CTL_FDI_AUTOTRAIN |
+					DP_TP_CTL_ENHANCED_FRAME_ENABLE |
+					DP_TP_CTL_LINK_TRAIN_PAT1 |
+					DP_TP_CTL_ENABLE);
+
+		/* Configure and enable DDI_BUF_CTL for DDI E with next voltage.
+		 * DDI E does not support port reversal, the functionality is
+		 * achieved on the PCH side in FDI_RX_CTL, so no need to set the
+		 * port reversal bit */
+		I915_WRITE(DDI_BUF_CTL(PORT_E),
+			   DDI_BUF_CTL_ENABLE |
+			   ((intel_crtc->config->fdi_lanes - 1) << 1) |
+			   DDI_BUF_TRANS_SELECT(i / 2));
+		POSTING_READ(DDI_BUF_CTL(PORT_E));
+
+		udelay(600);
+
+		/* Program PCH FDI Receiver TU */
+		I915_WRITE(FDI_RX_TUSIZE1(PIPE_A), TU_SIZE(64));
+
+		/* Enable PCH FDI Receiver with auto-training */
+		rx_ctl_val |= FDI_RX_ENABLE | FDI_LINK_TRAIN_AUTO;
+		I915_WRITE(FDI_RX_CTL(PIPE_A), rx_ctl_val);
+		POSTING_READ(FDI_RX_CTL(PIPE_A));
+
+		/* Wait for FDI receiver lane calibration */
+		udelay(30);
+
+		/* Unset FDI_RX_MISC pwrdn lanes */
+		temp = I915_READ(FDI_RX_MISC(PIPE_A));
+		temp &= ~(FDI_RX_PWRDN_LANE1_MASK | FDI_RX_PWRDN_LANE0_MASK);
+		I915_WRITE(FDI_RX_MISC(PIPE_A), temp);
+		POSTING_READ(FDI_RX_MISC(PIPE_A));
+
+		/* Wait for FDI auto training time */
+		udelay(5);
+
+		temp = I915_READ(DP_TP_STATUS(PORT_E));
+		if (temp & DP_TP_STATUS_AUTOTRAIN_DONE) {
+			DRM_DEBUG_KMS("FDI link training done on step %d\n", i);
+			break;
+		}
+
+		/*
+		 * Leave things enabled even if we failed to train FDI.
+		 * Results in less fireworks from the state checker.
+		 */
+		if (i == ARRAY_SIZE(hsw_ddi_translations_fdi) * 2 - 1) {
+			DRM_ERROR("FDI link training failed!\n");
+			break;
+		}
+
+		rx_ctl_val &= ~FDI_RX_ENABLE;
+		I915_WRITE(FDI_RX_CTL(PIPE_A), rx_ctl_val);
+		POSTING_READ(FDI_RX_CTL(PIPE_A));
+
+		temp = I915_READ(DDI_BUF_CTL(PORT_E));
+		temp &= ~DDI_BUF_CTL_ENABLE;
+		I915_WRITE(DDI_BUF_CTL(PORT_E), temp);
+		POSTING_READ(DDI_BUF_CTL(PORT_E));
+
+		/* Disable DP_TP_CTL and FDI_RX_CTL and retry */
+		temp = I915_READ(DP_TP_CTL(PORT_E));
+		temp &= ~(DP_TP_CTL_ENABLE | DP_TP_CTL_LINK_TRAIN_MASK);
+		temp |= DP_TP_CTL_LINK_TRAIN_PAT1;
+		I915_WRITE(DP_TP_CTL(PORT_E), temp);
+		POSTING_READ(DP_TP_CTL(PORT_E));
+
+		intel_wait_ddi_buf_idle(dev_priv, PORT_E);
+
+		/* Reset FDI_RX_MISC pwrdn lanes */
+		temp = I915_READ(FDI_RX_MISC(PIPE_A));
+		temp &= ~(FDI_RX_PWRDN_LANE1_MASK | FDI_RX_PWRDN_LANE0_MASK);
+		temp |= FDI_RX_PWRDN_LANE1_VAL(2) | FDI_RX_PWRDN_LANE0_VAL(2);
+		I915_WRITE(FDI_RX_MISC(PIPE_A), temp);
+		POSTING_READ(FDI_RX_MISC(PIPE_A));
+	}
+
+	/* Enable normal pixel sending for FDI */
+	I915_WRITE(DP_TP_CTL(PORT_E),
+		   DP_TP_CTL_FDI_AUTOTRAIN |
+		   DP_TP_CTL_LINK_TRAIN_NORMAL |
+		   DP_TP_CTL_ENHANCED_FRAME_ENABLE |
+		   DP_TP_CTL_ENABLE);
+}
+
+void intel_ddi_init_dp_buf_reg(struct intel_encoder *encoder)
+{
+	struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
+	struct intel_digital_port *intel_dig_port =
+		enc_to_dig_port(&encoder->base);
+
+	intel_dp->DP = intel_dig_port->saved_port_bits |
+		DDI_BUF_CTL_ENABLE | DDI_BUF_TRANS_SELECT(0);
+	intel_dp->DP |= DDI_PORT_WIDTH(intel_dp->lane_count);
+}
+
+static struct intel_encoder *
+intel_ddi_get_crtc_encoder(struct drm_crtc *crtc)
+{
+	struct drm_device *dev = crtc->dev;
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	struct intel_encoder *intel_encoder, *ret = NULL;
+	int num_encoders = 0;
+
+	for_each_encoder_on_crtc(dev, crtc, intel_encoder) {
+		ret = intel_encoder;
+		num_encoders++;
+	}
+
+	if (num_encoders != 1)
+		WARN(1, "%d encoders on crtc for pipe %c\n", num_encoders,
+		     pipe_name(intel_crtc->pipe));
+
+	BUG_ON(ret == NULL);
+	return ret;
+}
+
+struct intel_encoder *
+intel_ddi_get_crtc_new_encoder(struct intel_crtc_state *crtc_state)
+{
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
+	struct intel_encoder *ret = NULL;
+	struct drm_atomic_state *state;
+	struct drm_connector *connector;
+	struct drm_connector_state *connector_state;
+	int num_encoders = 0;
+	int i;
+
+	state = crtc_state->base.state;
+
+	for_each_connector_in_state(state, connector, connector_state, i) {
+		if (connector_state->crtc != crtc_state->base.crtc)
+			continue;
+
+		ret = to_intel_encoder(connector_state->best_encoder);
+		num_encoders++;
+	}
+
+	WARN(num_encoders != 1, "%d encoders on crtc for pipe %c\n", num_encoders,
+	     pipe_name(crtc->pipe));
+
+	BUG_ON(ret == NULL);
+	return ret;
+}
+
+#define LC_FREQ 2700
+
+static int hsw_ddi_calc_wrpll_link(struct drm_i915_private *dev_priv,
+				   i915_reg_t reg)
+{
+	int refclk = LC_FREQ;
+	int n, p, r;
+	u32 wrpll;
+
+	wrpll = I915_READ(reg);
+	switch (wrpll & WRPLL_PLL_REF_MASK) {
+	case WRPLL_PLL_SSC:
+	case WRPLL_PLL_NON_SSC:
+		/*
+		 * We could calculate spread here, but our checking
+		 * code only cares about 5% accuracy, and spread is a max of
+		 * 0.5% downspread.
+		 */
+		refclk = 135;
+		break;
+	case WRPLL_PLL_LCPLL:
+		refclk = LC_FREQ;
+		break;
+	default:
+		WARN(1, "bad wrpll refclk\n");
+		return 0;
+	}
+
+	r = wrpll & WRPLL_DIVIDER_REF_MASK;
+	p = (wrpll & WRPLL_DIVIDER_POST_MASK) >> WRPLL_DIVIDER_POST_SHIFT;
+	n = (wrpll & WRPLL_DIVIDER_FB_MASK) >> WRPLL_DIVIDER_FB_SHIFT;
+
+	/* Convert to KHz, p & r have a fixed point portion */
+	return (refclk * n * 100) / (p * r);
+}
+
+static int skl_calc_wrpll_link(struct drm_i915_private *dev_priv,
+			       uint32_t dpll)
+{
+	i915_reg_t cfgcr1_reg, cfgcr2_reg;
+	uint32_t cfgcr1_val, cfgcr2_val;
+	uint32_t p0, p1, p2, dco_freq;
+
+	cfgcr1_reg = DPLL_CFGCR1(dpll);
+	cfgcr2_reg = DPLL_CFGCR2(dpll);
+
+	cfgcr1_val = I915_READ(cfgcr1_reg);
+	cfgcr2_val = I915_READ(cfgcr2_reg);
+
+	p0 = cfgcr2_val & DPLL_CFGCR2_PDIV_MASK;
+	p2 = cfgcr2_val & DPLL_CFGCR2_KDIV_MASK;
+
+	if (cfgcr2_val &  DPLL_CFGCR2_QDIV_MODE(1))
+		p1 = (cfgcr2_val & DPLL_CFGCR2_QDIV_RATIO_MASK) >> 8;
+	else
+		p1 = 1;
+
+
+	switch (p0) {
+	case DPLL_CFGCR2_PDIV_1:
+		p0 = 1;
+		break;
+	case DPLL_CFGCR2_PDIV_2:
+		p0 = 2;
+		break;
+	case DPLL_CFGCR2_PDIV_3:
+		p0 = 3;
+		break;
+	case DPLL_CFGCR2_PDIV_7:
+		p0 = 7;
+		break;
+	}
+
+	switch (p2) {
+	case DPLL_CFGCR2_KDIV_5:
+		p2 = 5;
+		break;
+	case DPLL_CFGCR2_KDIV_2:
+		p2 = 2;
+		break;
+	case DPLL_CFGCR2_KDIV_3:
+		p2 = 3;
+		break;
+	case DPLL_CFGCR2_KDIV_1:
+		p2 = 1;
+		break;
+	}
+
+	dco_freq = (cfgcr1_val & DPLL_CFGCR1_DCO_INTEGER_MASK) * 24 * 1000;
+
+	dco_freq += (((cfgcr1_val & DPLL_CFGCR1_DCO_FRACTION_MASK) >> 9) * 24 *
+		1000) / 0x8000;
+
+	return dco_freq / (p0 * p1 * p2 * 5);
+}
+
+static void ddi_dotclock_get(struct intel_crtc_state *pipe_config)
+{
+	int dotclock;
+
+	if (pipe_config->has_pch_encoder)
+		dotclock = intel_dotclock_calculate(pipe_config->port_clock,
+						    &pipe_config->fdi_m_n);
+	else if (pipe_config->has_dp_encoder)
+		dotclock = intel_dotclock_calculate(pipe_config->port_clock,
+						    &pipe_config->dp_m_n);
+	else if (pipe_config->has_hdmi_sink && pipe_config->pipe_bpp == 36)
+		dotclock = pipe_config->port_clock * 2 / 3;
+	else
+		dotclock = pipe_config->port_clock;
+
+	if (pipe_config->pixel_multiplier)
+		dotclock /= pipe_config->pixel_multiplier;
+
+	pipe_config->base.adjusted_mode.crtc_clock = dotclock;
+}
+
+static void skl_ddi_clock_get(struct intel_encoder *encoder,
+				struct intel_crtc_state *pipe_config)
+{
+	struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
+	int link_clock = 0;
+	uint32_t dpll_ctl1, dpll;
+
+	dpll = pipe_config->ddi_pll_sel;
+
+	dpll_ctl1 = I915_READ(DPLL_CTRL1);
+
+	if (dpll_ctl1 & DPLL_CTRL1_HDMI_MODE(dpll)) {
+		link_clock = skl_calc_wrpll_link(dev_priv, dpll);
+	} else {
+		link_clock = dpll_ctl1 & DPLL_CTRL1_LINK_RATE_MASK(dpll);
+		link_clock >>= DPLL_CTRL1_LINK_RATE_SHIFT(dpll);
+
+		switch (link_clock) {
+		case DPLL_CTRL1_LINK_RATE_810:
+			link_clock = 81000;
+			break;
+		case DPLL_CTRL1_LINK_RATE_1080:
+			link_clock = 108000;
+			break;
+		case DPLL_CTRL1_LINK_RATE_1350:
+			link_clock = 135000;
+			break;
+		case DPLL_CTRL1_LINK_RATE_1620:
+			link_clock = 162000;
+			break;
+		case DPLL_CTRL1_LINK_RATE_2160:
+			link_clock = 216000;
+			break;
+		case DPLL_CTRL1_LINK_RATE_2700:
+			link_clock = 270000;
+			break;
+		default:
+			WARN(1, "Unsupported link rate\n");
+			break;
+		}
+		link_clock *= 2;
+	}
+
+	pipe_config->port_clock = link_clock;
+
+	ddi_dotclock_get(pipe_config);
+}
+
+static void hsw_ddi_clock_get(struct intel_encoder *encoder,
+			      struct intel_crtc_state *pipe_config)
+{
+	struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
+	int link_clock = 0;
+	u32 val, pll;
+
+	val = pipe_config->ddi_pll_sel;
+	switch (val & PORT_CLK_SEL_MASK) {
+	case PORT_CLK_SEL_LCPLL_810:
+		link_clock = 81000;
+		break;
+	case PORT_CLK_SEL_LCPLL_1350:
+		link_clock = 135000;
+		break;
+	case PORT_CLK_SEL_LCPLL_2700:
+		link_clock = 270000;
+		break;
+	case PORT_CLK_SEL_WRPLL1:
+		link_clock = hsw_ddi_calc_wrpll_link(dev_priv, WRPLL_CTL(0));
+		break;
+	case PORT_CLK_SEL_WRPLL2:
+		link_clock = hsw_ddi_calc_wrpll_link(dev_priv, WRPLL_CTL(1));
+		break;
+	case PORT_CLK_SEL_SPLL:
+		pll = I915_READ(SPLL_CTL) & SPLL_PLL_FREQ_MASK;
+		if (pll == SPLL_PLL_FREQ_810MHz)
+			link_clock = 81000;
+		else if (pll == SPLL_PLL_FREQ_1350MHz)
+			link_clock = 135000;
+		else if (pll == SPLL_PLL_FREQ_2700MHz)
+			link_clock = 270000;
+		else {
+			WARN(1, "bad spll freq\n");
+			return;
+		}
+		break;
+	default:
+		WARN(1, "bad port clock sel\n");
+		return;
+	}
+
+	pipe_config->port_clock = link_clock * 2;
+
+	ddi_dotclock_get(pipe_config);
+}
+
+static int bxt_calc_pll_link(struct drm_i915_private *dev_priv,
+				enum intel_dpll_id dpll)
+{
+	struct intel_shared_dpll *pll;
+	struct intel_dpll_hw_state *state;
+	intel_clock_t clock;
+
+	/* For DDI ports we always use a shared PLL. */
+	if (WARN_ON(dpll == DPLL_ID_PRIVATE))
+		return 0;
+
+	pll = &dev_priv->shared_dplls[dpll];
+	state = &pll->config.hw_state;
+
+	clock.m1 = 2;
+	clock.m2 = (state->pll0 & PORT_PLL_M2_MASK) << 22;
+	if (state->pll3 & PORT_PLL_M2_FRAC_ENABLE)
+		clock.m2 |= state->pll2 & PORT_PLL_M2_FRAC_MASK;
+	clock.n = (state->pll1 & PORT_PLL_N_MASK) >> PORT_PLL_N_SHIFT;
+	clock.p1 = (state->ebb0 & PORT_PLL_P1_MASK) >> PORT_PLL_P1_SHIFT;
+	clock.p2 = (state->ebb0 & PORT_PLL_P2_MASK) >> PORT_PLL_P2_SHIFT;
+
+	return chv_calc_dpll_params(100000, &clock);
+}
+
+static void bxt_ddi_clock_get(struct intel_encoder *encoder,
+				struct intel_crtc_state *pipe_config)
+{
+	struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
+	enum port port = intel_ddi_get_encoder_port(encoder);
+	uint32_t dpll = port;
+
+	pipe_config->port_clock = bxt_calc_pll_link(dev_priv, dpll);
+
+	ddi_dotclock_get(pipe_config);
+}
+
+void intel_ddi_clock_get(struct intel_encoder *encoder,
+			 struct intel_crtc_state *pipe_config)
+{
+	struct drm_device *dev = encoder->base.dev;
+
+	if (INTEL_INFO(dev)->gen <= 8)
+		hsw_ddi_clock_get(encoder, pipe_config);
+	else if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev))
+		skl_ddi_clock_get(encoder, pipe_config);
+	else if (IS_BROXTON(dev))
+		bxt_ddi_clock_get(encoder, pipe_config);
+}
+
+static bool
+hsw_ddi_pll_select(struct intel_crtc *intel_crtc,
+		   struct intel_crtc_state *crtc_state,
+		   struct intel_encoder *intel_encoder)
+{
+	struct intel_shared_dpll *pll;
+
+	pll = intel_get_shared_dpll(intel_crtc, crtc_state,
+				    intel_encoder);
+	if (!pll)
+		DRM_DEBUG_DRIVER("failed to find PLL for pipe %c\n",
+				 pipe_name(intel_crtc->pipe));
+
+	return pll;
+}
+
+static bool
+skl_ddi_pll_select(struct intel_crtc *intel_crtc,
+		   struct intel_crtc_state *crtc_state,
+		   struct intel_encoder *intel_encoder)
+{
+	struct intel_shared_dpll *pll;
+
+	pll = intel_get_shared_dpll(intel_crtc, crtc_state, intel_encoder);
+	if (pll == NULL) {
+		DRM_DEBUG_DRIVER("failed to find PLL for pipe %c\n",
+				 pipe_name(intel_crtc->pipe));
+		return false;
+	}
+
+	return true;
+}
+
+static bool
+bxt_ddi_pll_select(struct intel_crtc *intel_crtc,
+		   struct intel_crtc_state *crtc_state,
+		   struct intel_encoder *intel_encoder)
+{
+	return !!intel_get_shared_dpll(intel_crtc, crtc_state, intel_encoder);
+}
+
+/*
+ * Tries to find a *shared* PLL for the CRTC and store it in
+ * intel_crtc->ddi_pll_sel.
+ *
+ * For private DPLLs, compute_config() should do the selection for us. This
+ * function should be folded into compute_config() eventually.
+ */
+bool intel_ddi_pll_select(struct intel_crtc *intel_crtc,
+			  struct intel_crtc_state *crtc_state)
+{
+	struct drm_device *dev = intel_crtc->base.dev;
+	struct intel_encoder *intel_encoder =
+		intel_ddi_get_crtc_new_encoder(crtc_state);
+
+	if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev))
+		return skl_ddi_pll_select(intel_crtc, crtc_state,
+					  intel_encoder);
+	else if (IS_BROXTON(dev))
+		return bxt_ddi_pll_select(intel_crtc, crtc_state,
+					  intel_encoder);
+	else
+		return hsw_ddi_pll_select(intel_crtc, crtc_state,
+					  intel_encoder);
+}
+
+void intel_ddi_set_pipe_settings(struct drm_crtc *crtc)
+{
+	struct drm_i915_private *dev_priv = crtc->dev->dev_private;
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc);
+	enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
+	int type = intel_encoder->type;
+	uint32_t temp;
+
+	if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP || type == INTEL_OUTPUT_DP_MST) {
+		WARN_ON(transcoder_is_dsi(cpu_transcoder));
+
+		temp = TRANS_MSA_SYNC_CLK;
+		switch (intel_crtc->config->pipe_bpp) {
+		case 18:
+			temp |= TRANS_MSA_6_BPC;
+			break;
+		case 24:
+			temp |= TRANS_MSA_8_BPC;
+			break;
+		case 30:
+			temp |= TRANS_MSA_10_BPC;
+			break;
+		case 36:
+			temp |= TRANS_MSA_12_BPC;
+			break;
+		default:
+			BUG();
+		}
+		I915_WRITE(TRANS_MSA_MISC(cpu_transcoder), temp);
+	}
+}
+
+void intel_ddi_set_vc_payload_alloc(struct drm_crtc *crtc, bool state)
+{
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	struct drm_device *dev = crtc->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
+	uint32_t temp;
+	temp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder));
+	if (state == true)
+		temp |= TRANS_DDI_DP_VC_PAYLOAD_ALLOC;
+	else
+		temp &= ~TRANS_DDI_DP_VC_PAYLOAD_ALLOC;
+	I915_WRITE(TRANS_DDI_FUNC_CTL(cpu_transcoder), temp);
+}
+
+void intel_ddi_enable_transcoder_func(struct drm_crtc *crtc)
+{
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc);
+	struct drm_encoder *encoder = &intel_encoder->base;
+	struct drm_device *dev = crtc->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	enum pipe pipe = intel_crtc->pipe;
+	enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
+	enum port port = intel_ddi_get_encoder_port(intel_encoder);
+	int type = intel_encoder->type;
+	uint32_t temp;
+
+	/* Enable TRANS_DDI_FUNC_CTL for the pipe to work in HDMI mode */
+	temp = TRANS_DDI_FUNC_ENABLE;
+	temp |= TRANS_DDI_SELECT_PORT(port);
+
+	switch (intel_crtc->config->pipe_bpp) {
+	case 18:
+		temp |= TRANS_DDI_BPC_6;
+		break;
+	case 24:
+		temp |= TRANS_DDI_BPC_8;
+		break;
+	case 30:
+		temp |= TRANS_DDI_BPC_10;
+		break;
+	case 36:
+		temp |= TRANS_DDI_BPC_12;
+		break;
+	default:
+		BUG();
+	}
+
+	if (intel_crtc->config->base.adjusted_mode.flags & DRM_MODE_FLAG_PVSYNC)
+		temp |= TRANS_DDI_PVSYNC;
+	if (intel_crtc->config->base.adjusted_mode.flags & DRM_MODE_FLAG_PHSYNC)
+		temp |= TRANS_DDI_PHSYNC;
+
+	if (cpu_transcoder == TRANSCODER_EDP) {
+		switch (pipe) {
+		case PIPE_A:
+			/* On Haswell, can only use the always-on power well for
+			 * eDP when not using the panel fitter, and when not
+			 * using motion blur mitigation (which we don't
+			 * support). */
+			if (IS_HASWELL(dev) &&
+			    (intel_crtc->config->pch_pfit.enabled ||
+			     intel_crtc->config->pch_pfit.force_thru))
+				temp |= TRANS_DDI_EDP_INPUT_A_ONOFF;
+			else
+				temp |= TRANS_DDI_EDP_INPUT_A_ON;
+			break;
+		case PIPE_B:
+			temp |= TRANS_DDI_EDP_INPUT_B_ONOFF;
+			break;
+		case PIPE_C:
+			temp |= TRANS_DDI_EDP_INPUT_C_ONOFF;
+			break;
+		default:
+			BUG();
+			break;
+		}
+	}
+
+	if (type == INTEL_OUTPUT_HDMI) {
+		if (intel_crtc->config->has_hdmi_sink)
+			temp |= TRANS_DDI_MODE_SELECT_HDMI;
+		else
+			temp |= TRANS_DDI_MODE_SELECT_DVI;
+
+	} else if (type == INTEL_OUTPUT_ANALOG) {
+		temp |= TRANS_DDI_MODE_SELECT_FDI;
+		temp |= (intel_crtc->config->fdi_lanes - 1) << 1;
+
+	} else if (type == INTEL_OUTPUT_DISPLAYPORT ||
+		   type == INTEL_OUTPUT_EDP) {
+		struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
+
+		if (intel_dp->is_mst) {
+			temp |= TRANS_DDI_MODE_SELECT_DP_MST;
+		} else
+			temp |= TRANS_DDI_MODE_SELECT_DP_SST;
+
+		temp |= DDI_PORT_WIDTH(intel_crtc->config->lane_count);
+	} else if (type == INTEL_OUTPUT_DP_MST) {
+		struct intel_dp *intel_dp = &enc_to_mst(encoder)->primary->dp;
+
+		if (intel_dp->is_mst) {
+			temp |= TRANS_DDI_MODE_SELECT_DP_MST;
+		} else
+			temp |= TRANS_DDI_MODE_SELECT_DP_SST;
+
+		temp |= DDI_PORT_WIDTH(intel_crtc->config->lane_count);
+	} else {
+		WARN(1, "Invalid encoder type %d for pipe %c\n",
+		     intel_encoder->type, pipe_name(pipe));
+	}
+
+	I915_WRITE(TRANS_DDI_FUNC_CTL(cpu_transcoder), temp);
+}
+
+void intel_ddi_disable_transcoder_func(struct drm_i915_private *dev_priv,
+				       enum transcoder cpu_transcoder)
+{
+	i915_reg_t reg = TRANS_DDI_FUNC_CTL(cpu_transcoder);
+	uint32_t val = I915_READ(reg);
+
+	val &= ~(TRANS_DDI_FUNC_ENABLE | TRANS_DDI_PORT_MASK | TRANS_DDI_DP_VC_PAYLOAD_ALLOC);
+	val |= TRANS_DDI_PORT_NONE;
+	I915_WRITE(reg, val);
+}
+
+bool intel_ddi_connector_get_hw_state(struct intel_connector *intel_connector)
+{
+	struct drm_device *dev = intel_connector->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_encoder *intel_encoder = intel_connector->encoder;
+	int type = intel_connector->base.connector_type;
+	enum port port = intel_ddi_get_encoder_port(intel_encoder);
+	enum pipe pipe = 0;
+	enum transcoder cpu_transcoder;
+	enum intel_display_power_domain power_domain;
+	uint32_t tmp;
+	bool ret;
+
+	power_domain = intel_display_port_power_domain(intel_encoder);
+	if (!intel_display_power_get_if_enabled(dev_priv, power_domain))
+		return false;
+
+	if (!intel_encoder->get_hw_state(intel_encoder, &pipe)) {
+		ret = false;
+		goto out;
+	}
+
+	if (port == PORT_A)
+		cpu_transcoder = TRANSCODER_EDP;
+	else
+		cpu_transcoder = (enum transcoder) pipe;
+
+	tmp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder));
+
+	switch (tmp & TRANS_DDI_MODE_SELECT_MASK) {
+	case TRANS_DDI_MODE_SELECT_HDMI:
+	case TRANS_DDI_MODE_SELECT_DVI:
+		ret = type == DRM_MODE_CONNECTOR_HDMIA;
+		break;
+
+	case TRANS_DDI_MODE_SELECT_DP_SST:
+		ret = type == DRM_MODE_CONNECTOR_eDP ||
+		      type == DRM_MODE_CONNECTOR_DisplayPort;
+		break;
+
+	case TRANS_DDI_MODE_SELECT_DP_MST:
+		/* if the transcoder is in MST state then
+		 * connector isn't connected */
+		ret = false;
+		break;
+
+	case TRANS_DDI_MODE_SELECT_FDI:
+		ret = type == DRM_MODE_CONNECTOR_VGA;
+		break;
+
+	default:
+		ret = false;
+		break;
+	}
+
+out:
+	intel_display_power_put(dev_priv, power_domain);
+
+	return ret;
+}
+
+bool intel_ddi_get_hw_state(struct intel_encoder *encoder,
+			    enum pipe *pipe)
+{
+	struct drm_device *dev = encoder->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	enum port port = intel_ddi_get_encoder_port(encoder);
+	enum intel_display_power_domain power_domain;
+	u32 tmp;
+	int i;
+	bool ret;
+
+	power_domain = intel_display_port_power_domain(encoder);
+	if (!intel_display_power_get_if_enabled(dev_priv, power_domain))
+		return false;
+
+	ret = false;
+
+	tmp = I915_READ(DDI_BUF_CTL(port));
+
+	if (!(tmp & DDI_BUF_CTL_ENABLE))
+		goto out;
+
+	if (port == PORT_A) {
+		tmp = I915_READ(TRANS_DDI_FUNC_CTL(TRANSCODER_EDP));
+
+		switch (tmp & TRANS_DDI_EDP_INPUT_MASK) {
+		case TRANS_DDI_EDP_INPUT_A_ON:
+		case TRANS_DDI_EDP_INPUT_A_ONOFF:
+			*pipe = PIPE_A;
+			break;
+		case TRANS_DDI_EDP_INPUT_B_ONOFF:
+			*pipe = PIPE_B;
+			break;
+		case TRANS_DDI_EDP_INPUT_C_ONOFF:
+			*pipe = PIPE_C;
+			break;
+		}
+
+		ret = true;
+
+		goto out;
+	}
+
+	for (i = TRANSCODER_A; i <= TRANSCODER_C; i++) {
+		tmp = I915_READ(TRANS_DDI_FUNC_CTL(i));
+
+		if ((tmp & TRANS_DDI_PORT_MASK) == TRANS_DDI_SELECT_PORT(port)) {
+			if ((tmp & TRANS_DDI_MODE_SELECT_MASK) ==
+			    TRANS_DDI_MODE_SELECT_DP_MST)
+				goto out;
+
+			*pipe = i;
+			ret = true;
+
+			goto out;
+		}
+	}
+
+	DRM_DEBUG_KMS("No pipe for ddi port %c found\n", port_name(port));
+
+out:
+	intel_display_power_put(dev_priv, power_domain);
+
+	return ret;
+}
+
+void intel_ddi_enable_pipe_clock(struct intel_crtc *intel_crtc)
+{
+	struct drm_crtc *crtc = &intel_crtc->base;
+	struct drm_device *dev = crtc->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc);
+	enum port port = intel_ddi_get_encoder_port(intel_encoder);
+	enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
+
+	if (cpu_transcoder != TRANSCODER_EDP)
+		I915_WRITE(TRANS_CLK_SEL(cpu_transcoder),
+			   TRANS_CLK_SEL_PORT(port));
+}
+
+void intel_ddi_disable_pipe_clock(struct intel_crtc *intel_crtc)
+{
+	struct drm_i915_private *dev_priv = intel_crtc->base.dev->dev_private;
+	enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
+
+	if (cpu_transcoder != TRANSCODER_EDP)
+		I915_WRITE(TRANS_CLK_SEL(cpu_transcoder),
+			   TRANS_CLK_SEL_DISABLED);
+}
+
+static void skl_ddi_set_iboost(struct drm_i915_private *dev_priv,
+			       u32 level, enum port port, int type)
+{
+	const struct ddi_buf_trans *ddi_translations;
+	uint8_t iboost;
+	uint8_t dp_iboost, hdmi_iboost;
+	int n_entries;
+	u32 reg;
+
+	/* VBT may override standard boost values */
+	dp_iboost = dev_priv->vbt.ddi_port_info[port].dp_boost_level;
+	hdmi_iboost = dev_priv->vbt.ddi_port_info[port].hdmi_boost_level;
+
+	if (type == INTEL_OUTPUT_DISPLAYPORT) {
+		if (dp_iboost) {
+			iboost = dp_iboost;
+		} else {
+			ddi_translations = skl_get_buf_trans_dp(dev_priv, &n_entries);
+			iboost = ddi_translations[level].i_boost;
+		}
+	} else if (type == INTEL_OUTPUT_EDP) {
+		if (dp_iboost) {
+			iboost = dp_iboost;
+		} else {
+			ddi_translations = skl_get_buf_trans_edp(dev_priv, &n_entries);
+
+			if (WARN_ON(port != PORT_A &&
+				    port != PORT_E && n_entries > 9))
+				n_entries = 9;
+
+			iboost = ddi_translations[level].i_boost;
+		}
+	} else if (type == INTEL_OUTPUT_HDMI) {
+		if (hdmi_iboost) {
+			iboost = hdmi_iboost;
+		} else {
+			ddi_translations = skl_get_buf_trans_hdmi(dev_priv, &n_entries);
+			iboost = ddi_translations[level].i_boost;
+		}
+	} else {
+		return;
+	}
+
+	/* Make sure that the requested I_boost is valid */
+	if (iboost && iboost != 0x1 && iboost != 0x3 && iboost != 0x7) {
+		DRM_ERROR("Invalid I_boost value %u\n", iboost);
+		return;
+	}
+
+	reg = I915_READ(DISPIO_CR_TX_BMU_CR0);
+	reg &= ~BALANCE_LEG_MASK(port);
+	reg &= ~(1 << (BALANCE_LEG_DISABLE_SHIFT + port));
+
+	if (iboost)
+		reg |= iboost << BALANCE_LEG_SHIFT(port);
+	else
+		reg |= 1 << (BALANCE_LEG_DISABLE_SHIFT + port);
+
+	I915_WRITE(DISPIO_CR_TX_BMU_CR0, reg);
+}
+
+static void bxt_ddi_vswing_sequence(struct drm_i915_private *dev_priv,
+				    u32 level, enum port port, int type)
+{
+	const struct bxt_ddi_buf_trans *ddi_translations;
+	u32 n_entries, i;
+	uint32_t val;
+
+	if (type == INTEL_OUTPUT_EDP && dev_priv->vbt.edp.low_vswing) {
+		n_entries = ARRAY_SIZE(bxt_ddi_translations_edp);
+		ddi_translations = bxt_ddi_translations_edp;
+	} else if (type == INTEL_OUTPUT_DISPLAYPORT
+			|| type == INTEL_OUTPUT_EDP) {
+		n_entries = ARRAY_SIZE(bxt_ddi_translations_dp);
+		ddi_translations = bxt_ddi_translations_dp;
+	} else if (type == INTEL_OUTPUT_HDMI) {
+		n_entries = ARRAY_SIZE(bxt_ddi_translations_hdmi);
+		ddi_translations = bxt_ddi_translations_hdmi;
+	} else {
+		DRM_DEBUG_KMS("Vswing programming not done for encoder %d\n",
+				type);
+		return;
+	}
+
+	/* Check if default value has to be used */
+	if (level >= n_entries ||
+	    (type == INTEL_OUTPUT_HDMI && level == HDMI_LEVEL_SHIFT_UNKNOWN)) {
+		for (i = 0; i < n_entries; i++) {
+			if (ddi_translations[i].default_index) {
+				level = i;
+				break;
+			}
+		}
+	}
+
+	/*
+	 * While we write to the group register to program all lanes at once we
+	 * can read only lane registers and we pick lanes 0/1 for that.
+	 */
+	val = I915_READ(BXT_PORT_PCS_DW10_LN01(port));
+	val &= ~(TX2_SWING_CALC_INIT | TX1_SWING_CALC_INIT);
+	I915_WRITE(BXT_PORT_PCS_DW10_GRP(port), val);
+
+	val = I915_READ(BXT_PORT_TX_DW2_LN0(port));
+	val &= ~(MARGIN_000 | UNIQ_TRANS_SCALE);
+	val |= ddi_translations[level].margin << MARGIN_000_SHIFT |
+	       ddi_translations[level].scale << UNIQ_TRANS_SCALE_SHIFT;
+	I915_WRITE(BXT_PORT_TX_DW2_GRP(port), val);
+
+	val = I915_READ(BXT_PORT_TX_DW3_LN0(port));
+	val &= ~SCALE_DCOMP_METHOD;
+	if (ddi_translations[level].enable)
+		val |= SCALE_DCOMP_METHOD;
+
+	if ((val & UNIQUE_TRANGE_EN_METHOD) && !(val & SCALE_DCOMP_METHOD))
+		DRM_ERROR("Disabled scaling while ouniqetrangenmethod was set");
+
+	I915_WRITE(BXT_PORT_TX_DW3_GRP(port), val);
+
+	val = I915_READ(BXT_PORT_TX_DW4_LN0(port));
+	val &= ~DE_EMPHASIS;
+	val |= ddi_translations[level].deemphasis << DEEMPH_SHIFT;
+	I915_WRITE(BXT_PORT_TX_DW4_GRP(port), val);
+
+	val = I915_READ(BXT_PORT_PCS_DW10_LN01(port));
+	val |= TX2_SWING_CALC_INIT | TX1_SWING_CALC_INIT;
+	I915_WRITE(BXT_PORT_PCS_DW10_GRP(port), val);
+}
+
+static uint32_t translate_signal_level(int signal_levels)
+{
+	uint32_t level;
+
+	switch (signal_levels) {
+	default:
+		DRM_DEBUG_KMS("Unsupported voltage swing/pre-emphasis level: 0x%x\n",
+			      signal_levels);
+	case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_0:
+		level = 0;
+		break;
+	case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_1:
+		level = 1;
+		break;
+	case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_2:
+		level = 2;
+		break;
+	case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_3:
+		level = 3;
+		break;
+
+	case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_0:
+		level = 4;
+		break;
+	case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_1:
+		level = 5;
+		break;
+	case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_2:
+		level = 6;
+		break;
+
+	case DP_TRAIN_VOLTAGE_SWING_LEVEL_2 | DP_TRAIN_PRE_EMPH_LEVEL_0:
+		level = 7;
+		break;
+	case DP_TRAIN_VOLTAGE_SWING_LEVEL_2 | DP_TRAIN_PRE_EMPH_LEVEL_1:
+		level = 8;
+		break;
+
+	case DP_TRAIN_VOLTAGE_SWING_LEVEL_3 | DP_TRAIN_PRE_EMPH_LEVEL_0:
+		level = 9;
+		break;
+	}
+
+	return level;
+}
+
+uint32_t ddi_signal_levels(struct intel_dp *intel_dp)
+{
+	struct intel_digital_port *dport = dp_to_dig_port(intel_dp);
+	struct drm_i915_private *dev_priv = to_i915(dport->base.base.dev);
+	struct intel_encoder *encoder = &dport->base;
+	uint8_t train_set = intel_dp->train_set[0];
+	int signal_levels = train_set & (DP_TRAIN_VOLTAGE_SWING_MASK |
+					 DP_TRAIN_PRE_EMPHASIS_MASK);
+	enum port port = dport->port;
+	uint32_t level;
+
+	level = translate_signal_level(signal_levels);
+
+	if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv))
+		skl_ddi_set_iboost(dev_priv, level, port, encoder->type);
+	else if (IS_BROXTON(dev_priv))
+		bxt_ddi_vswing_sequence(dev_priv, level, port, encoder->type);
+
+	return DDI_BUF_TRANS_SELECT(level);
+}
+
+void intel_ddi_clk_select(struct intel_encoder *encoder,
+			  const struct intel_crtc_state *pipe_config)
+{
+	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
+	enum port port = intel_ddi_get_encoder_port(encoder);
+
+	if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv)) {
+		uint32_t dpll = pipe_config->ddi_pll_sel;
+		uint32_t val;
+
+		/* DDI -> PLL mapping  */
+		val = I915_READ(DPLL_CTRL2);
+
+		val &= ~(DPLL_CTRL2_DDI_CLK_OFF(port) |
+			DPLL_CTRL2_DDI_CLK_SEL_MASK(port));
+		val |= (DPLL_CTRL2_DDI_CLK_SEL(dpll, port) |
+			DPLL_CTRL2_DDI_SEL_OVERRIDE(port));
+
+		I915_WRITE(DPLL_CTRL2, val);
+
+	} else if (INTEL_INFO(dev_priv)->gen < 9) {
+		WARN_ON(pipe_config->ddi_pll_sel == PORT_CLK_SEL_NONE);
+		I915_WRITE(PORT_CLK_SEL(port), pipe_config->ddi_pll_sel);
+	}
+}
+
+static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder)
+{
+	struct drm_encoder *encoder = &intel_encoder->base;
+	struct drm_i915_private *dev_priv = to_i915(encoder->dev);
+	struct intel_crtc *crtc = to_intel_crtc(encoder->crtc);
+	enum port port = intel_ddi_get_encoder_port(intel_encoder);
+	int type = intel_encoder->type;
+
+	if (type == INTEL_OUTPUT_HDMI) {
+		struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
+
+		intel_dp_dual_mode_set_tmds_output(intel_hdmi, true);
+	}
+
+	intel_prepare_ddi_buffer(intel_encoder);
+
+	if (type == INTEL_OUTPUT_EDP) {
+		struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
+		intel_edp_panel_on(intel_dp);
+	}
+
+	intel_ddi_clk_select(intel_encoder, crtc->config);
+
+	if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP) {
+		struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
+
+		intel_dp_set_link_params(intel_dp, crtc->config);
+
+		intel_ddi_init_dp_buf_reg(intel_encoder);
+
+		intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON);
+		intel_dp_start_link_train(intel_dp);
+		if (port != PORT_A || INTEL_INFO(dev_priv)->gen >= 9)
+			intel_dp_stop_link_train(intel_dp);
+	} else if (type == INTEL_OUTPUT_HDMI) {
+		struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
+
+		intel_hdmi->set_infoframes(encoder,
+					   crtc->config->has_hdmi_sink,
+					   &crtc->config->base.adjusted_mode);
+	}
+}
+
+static void intel_ddi_post_disable(struct intel_encoder *intel_encoder)
+{
+	struct drm_encoder *encoder = &intel_encoder->base;
+	struct drm_device *dev = encoder->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	enum port port = intel_ddi_get_encoder_port(intel_encoder);
+	int type = intel_encoder->type;
+	uint32_t val;
+	bool wait = false;
+
+	val = I915_READ(DDI_BUF_CTL(port));
+	if (val & DDI_BUF_CTL_ENABLE) {
+		val &= ~DDI_BUF_CTL_ENABLE;
+		I915_WRITE(DDI_BUF_CTL(port), val);
+		wait = true;
+	}
+
+	val = I915_READ(DP_TP_CTL(port));
+	val &= ~(DP_TP_CTL_ENABLE | DP_TP_CTL_LINK_TRAIN_MASK);
+	val |= DP_TP_CTL_LINK_TRAIN_PAT1;
+	I915_WRITE(DP_TP_CTL(port), val);
+
+	if (wait)
+		intel_wait_ddi_buf_idle(dev_priv, port);
+
+	if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP) {
+		struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
+		intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF);
+		intel_edp_panel_vdd_on(intel_dp);
+		intel_edp_panel_off(intel_dp);
+	}
+
+	if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev))
+		I915_WRITE(DPLL_CTRL2, (I915_READ(DPLL_CTRL2) |
+					DPLL_CTRL2_DDI_CLK_OFF(port)));
+	else if (INTEL_INFO(dev)->gen < 9)
+		I915_WRITE(PORT_CLK_SEL(port), PORT_CLK_SEL_NONE);
+
+	if (type == INTEL_OUTPUT_HDMI) {
+		struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
+
+		intel_dp_dual_mode_set_tmds_output(intel_hdmi, false);
+	}
+}
+
+static void intel_enable_ddi(struct intel_encoder *intel_encoder)
+{
+	struct drm_encoder *encoder = &intel_encoder->base;
+	struct drm_crtc *crtc = encoder->crtc;
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	struct drm_device *dev = encoder->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	enum port port = intel_ddi_get_encoder_port(intel_encoder);
+	int type = intel_encoder->type;
+
+	if (type == INTEL_OUTPUT_HDMI) {
+		struct intel_digital_port *intel_dig_port =
+			enc_to_dig_port(encoder);
+
+		/* In HDMI/DVI mode, the port width, and swing/emphasis values
+		 * are ignored so nothing special needs to be done besides
+		 * enabling the port.
+		 */
+		I915_WRITE(DDI_BUF_CTL(port),
+			   intel_dig_port->saved_port_bits |
+			   DDI_BUF_CTL_ENABLE);
+	} else if (type == INTEL_OUTPUT_EDP) {
+		struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
+
+		if (port == PORT_A && INTEL_INFO(dev)->gen < 9)
+			intel_dp_stop_link_train(intel_dp);
+
+		intel_edp_backlight_on(intel_dp);
+		intel_psr_enable(intel_dp);
+		intel_edp_drrs_enable(intel_dp);
+	}
+
+	if (intel_crtc->config->has_audio) {
+		intel_display_power_get(dev_priv, POWER_DOMAIN_AUDIO);
+		intel_audio_codec_enable(intel_encoder);
+	}
+}
+
+static void intel_disable_ddi(struct intel_encoder *intel_encoder)
+{
+	struct drm_encoder *encoder = &intel_encoder->base;
+	struct drm_crtc *crtc = encoder->crtc;
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	int type = intel_encoder->type;
+	struct drm_device *dev = encoder->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	if (intel_crtc->config->has_audio) {
+		intel_audio_codec_disable(intel_encoder);
+		intel_display_power_put(dev_priv, POWER_DOMAIN_AUDIO);
+	}
+
+	if (type == INTEL_OUTPUT_EDP) {
+		struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
+
+		intel_edp_drrs_disable(intel_dp);
+		intel_psr_disable(intel_dp);
+		intel_edp_backlight_off(intel_dp);
+	}
+}
+
+static bool broxton_phy_is_enabled(struct drm_i915_private *dev_priv,
+				   enum dpio_phy phy)
+{
+	if (!(I915_READ(BXT_P_CR_GT_DISP_PWRON) & GT_DISPLAY_POWER_ON(phy)))
+		return false;
+
+	if ((I915_READ(BXT_PORT_CL1CM_DW0(phy)) &
+	     (PHY_POWER_GOOD | PHY_RESERVED)) != PHY_POWER_GOOD) {
+		DRM_DEBUG_DRIVER("DDI PHY %d powered, but power hasn't settled\n",
+				 phy);
+
+		return false;
+	}
+
+	if (phy == DPIO_PHY1 &&
+	    !(I915_READ(BXT_PORT_REF_DW3(DPIO_PHY1)) & GRC_DONE)) {
+		DRM_DEBUG_DRIVER("DDI PHY 1 powered, but GRC isn't done\n");
+
+		return false;
+	}
+
+	if (!(I915_READ(BXT_PHY_CTL_FAMILY(phy)) & COMMON_RESET_DIS)) {
+		DRM_DEBUG_DRIVER("DDI PHY %d powered, but still in reset\n",
+				 phy);
+
+		return false;
+	}
+
+	return true;
+}
+
+static u32 broxton_get_grc(struct drm_i915_private *dev_priv, enum dpio_phy phy)
+{
+	u32 val = I915_READ(BXT_PORT_REF_DW6(phy));
+
+	return (val & GRC_CODE_MASK) >> GRC_CODE_SHIFT;
+}
+
+static void broxton_phy_wait_grc_done(struct drm_i915_private *dev_priv,
+				      enum dpio_phy phy)
+{
+	if (wait_for(I915_READ(BXT_PORT_REF_DW3(phy)) & GRC_DONE, 10))
+		DRM_ERROR("timeout waiting for PHY%d GRC\n", phy);
+}
+
+static bool broxton_phy_verify_state(struct drm_i915_private *dev_priv,
+				     enum dpio_phy phy);
+
+static void broxton_phy_init(struct drm_i915_private *dev_priv,
+			     enum dpio_phy phy)
+{
+	enum port port;
+	u32 ports, val;
+
+	if (broxton_phy_is_enabled(dev_priv, phy)) {
+		/* Still read out the GRC value for state verification */
+		if (phy == DPIO_PHY0)
+			dev_priv->bxt_phy_grc = broxton_get_grc(dev_priv, phy);
+
+		if (broxton_phy_verify_state(dev_priv, phy)) {
+			DRM_DEBUG_DRIVER("DDI PHY %d already enabled, "
+					 "won't reprogram it\n", phy);
+
+			return;
+		}
+
+		DRM_DEBUG_DRIVER("DDI PHY %d enabled with invalid state, "
+				 "force reprogramming it\n", phy);
+	} else {
+		DRM_DEBUG_DRIVER("DDI PHY %d not enabled, enabling it\n", phy);
+	}
+
+	val = I915_READ(BXT_P_CR_GT_DISP_PWRON);
+	val |= GT_DISPLAY_POWER_ON(phy);
+	I915_WRITE(BXT_P_CR_GT_DISP_PWRON, val);
+
+	/*
+	 * The PHY registers start out inaccessible and respond to reads with
+	 * all 1s.  Eventually they become accessible as they power up, then
+	 * the reserved bit will give the default 0.  Poll on the reserved bit
+	 * becoming 0 to find when the PHY is accessible.
+	 * HW team confirmed that the time to reach phypowergood status is
+	 * anywhere between 50 us and 100us.
+	 */
+	if (wait_for_us(((I915_READ(BXT_PORT_CL1CM_DW0(phy)) &
+		(PHY_RESERVED | PHY_POWER_GOOD)) == PHY_POWER_GOOD), 100)) {
+		DRM_ERROR("timeout during PHY%d power on\n", phy);
+	}
+
+	if (phy == DPIO_PHY0)
+		ports = BIT(PORT_B) | BIT(PORT_C);
+	else
+		ports = BIT(PORT_A);
+
+	for_each_port_masked(port, ports) {
+		int lane;
+
+		for (lane = 0; lane < 4; lane++) {
+			val = I915_READ(BXT_PORT_TX_DW14_LN(port, lane));
+			/*
+			 * Note that on CHV this flag is called UPAR, but has
+			 * the same function.
+			 */
+			val &= ~LATENCY_OPTIM;
+			if (lane != 1)
+				val |= LATENCY_OPTIM;
+
+			I915_WRITE(BXT_PORT_TX_DW14_LN(port, lane), val);
+		}
+	}
+
+	/* Program PLL Rcomp code offset */
+	val = I915_READ(BXT_PORT_CL1CM_DW9(phy));
+	val &= ~IREF0RC_OFFSET_MASK;
+	val |= 0xE4 << IREF0RC_OFFSET_SHIFT;
+	I915_WRITE(BXT_PORT_CL1CM_DW9(phy), val);
+
+	val = I915_READ(BXT_PORT_CL1CM_DW10(phy));
+	val &= ~IREF1RC_OFFSET_MASK;
+	val |= 0xE4 << IREF1RC_OFFSET_SHIFT;
+	I915_WRITE(BXT_PORT_CL1CM_DW10(phy), val);
+
+	/* Program power gating */
+	val = I915_READ(BXT_PORT_CL1CM_DW28(phy));
+	val |= OCL1_POWER_DOWN_EN | DW28_OLDO_DYN_PWR_DOWN_EN |
+		SUS_CLK_CONFIG;
+	I915_WRITE(BXT_PORT_CL1CM_DW28(phy), val);
+
+	if (phy == DPIO_PHY0) {
+		val = I915_READ(BXT_PORT_CL2CM_DW6_BC);
+		val |= DW6_OLDO_DYN_PWR_DOWN_EN;
+		I915_WRITE(BXT_PORT_CL2CM_DW6_BC, val);
+	}
+
+	val = I915_READ(BXT_PORT_CL1CM_DW30(phy));
+	val &= ~OCL2_LDOFUSE_PWR_DIS;
+	/*
+	 * On PHY1 disable power on the second channel, since no port is
+	 * connected there. On PHY0 both channels have a port, so leave it
+	 * enabled.
+	 * TODO: port C is only connected on BXT-P, so on BXT0/1 we should
+	 * power down the second channel on PHY0 as well.
+	 *
+	 * FIXME: Clarify programming of the following, the register is
+	 * read-only with bit 6 fixed at 0 at least in stepping A.
+	 */
+	if (phy == DPIO_PHY1)
+		val |= OCL2_LDOFUSE_PWR_DIS;
+	I915_WRITE(BXT_PORT_CL1CM_DW30(phy), val);
+
+	if (phy == DPIO_PHY0) {
+		uint32_t grc_code;
+		/*
+		 * PHY0 isn't connected to an RCOMP resistor so copy over
+		 * the corresponding calibrated value from PHY1, and disable
+		 * the automatic calibration on PHY0.
+		 */
+		broxton_phy_wait_grc_done(dev_priv, DPIO_PHY1);
+
+		val = dev_priv->bxt_phy_grc = broxton_get_grc(dev_priv,
+							      DPIO_PHY1);
+		grc_code = val << GRC_CODE_FAST_SHIFT |
+			   val << GRC_CODE_SLOW_SHIFT |
+			   val;
+		I915_WRITE(BXT_PORT_REF_DW6(DPIO_PHY0), grc_code);
+
+		val = I915_READ(BXT_PORT_REF_DW8(DPIO_PHY0));
+		val |= GRC_DIS | GRC_RDY_OVRD;
+		I915_WRITE(BXT_PORT_REF_DW8(DPIO_PHY0), val);
+	}
+	/*
+	 * During PHY1 init delay waiting for GRC calibration to finish, since
+	 * it can happen in parallel with the subsequent PHY0 init.
+	 */
+
+	val = I915_READ(BXT_PHY_CTL_FAMILY(phy));
+	val |= COMMON_RESET_DIS;
+	I915_WRITE(BXT_PHY_CTL_FAMILY(phy), val);
+}
+
+void broxton_ddi_phy_init(struct drm_i915_private *dev_priv)
+{
+	/* Enable PHY1 first since it provides Rcomp for PHY0 */
+	broxton_phy_init(dev_priv, DPIO_PHY1);
+	broxton_phy_init(dev_priv, DPIO_PHY0);
+
+	/*
+	 * If BIOS enabled only PHY0 and not PHY1, we skipped waiting for the
+	 * PHY1 GRC calibration to finish, so wait for it here.
+	 */
+	broxton_phy_wait_grc_done(dev_priv, DPIO_PHY1);
+}
+
+static void broxton_phy_uninit(struct drm_i915_private *dev_priv,
+			       enum dpio_phy phy)
+{
+	uint32_t val;
+
+	val = I915_READ(BXT_PHY_CTL_FAMILY(phy));
+	val &= ~COMMON_RESET_DIS;
+	I915_WRITE(BXT_PHY_CTL_FAMILY(phy), val);
+
+	val = I915_READ(BXT_P_CR_GT_DISP_PWRON);
+	val &= ~GT_DISPLAY_POWER_ON(phy);
+	I915_WRITE(BXT_P_CR_GT_DISP_PWRON, val);
+}
+
+void broxton_ddi_phy_uninit(struct drm_i915_private *dev_priv)
+{
+	broxton_phy_uninit(dev_priv, DPIO_PHY1);
+	broxton_phy_uninit(dev_priv, DPIO_PHY0);
+}
+
+static bool __printf(6, 7)
+__phy_reg_verify_state(struct drm_i915_private *dev_priv, enum dpio_phy phy,
+		       i915_reg_t reg, u32 mask, u32 expected,
+		       const char *reg_fmt, ...)
+{
+	struct va_format vaf;
+	va_list args;
+	u32 val;
+
+	val = I915_READ(reg);
+	if ((val & mask) == expected)
+		return true;
+
+	va_start(args, reg_fmt);
+	vaf.fmt = reg_fmt;
+	vaf.va = &args;
+
+	DRM_DEBUG_DRIVER("DDI PHY %d reg %pV [%08x] state mismatch: "
+			 "current %08x, expected %08x (mask %08x)\n",
+			 phy, &vaf, reg.reg, val, (val & ~mask) | expected,
+			 mask);
+
+	va_end(args);
+
+	return false;
+}
+
+static bool broxton_phy_verify_state(struct drm_i915_private *dev_priv,
+				     enum dpio_phy phy)
+{
+	enum port port;
+	u32 ports;
+	uint32_t mask;
+	bool ok;
+
+#define _CHK(reg, mask, exp, fmt, ...)					\
+	__phy_reg_verify_state(dev_priv, phy, reg, mask, exp, fmt,	\
+			       ## __VA_ARGS__)
+
+	/* We expect the PHY to be always enabled */
+	if (!broxton_phy_is_enabled(dev_priv, phy))
+		return false;
+
+	ok = true;
+
+	if (phy == DPIO_PHY0)
+		ports = BIT(PORT_B) | BIT(PORT_C);
+	else
+		ports = BIT(PORT_A);
+
+	for_each_port_masked(port, ports) {
+		int lane;
+
+		for (lane = 0; lane < 4; lane++)
+			ok &= _CHK(BXT_PORT_TX_DW14_LN(port, lane),
+				    LATENCY_OPTIM,
+				    lane != 1 ? LATENCY_OPTIM : 0,
+				    "BXT_PORT_TX_DW14_LN(%d, %d)", port, lane);
+	}
+
+	/* PLL Rcomp code offset */
+	ok &= _CHK(BXT_PORT_CL1CM_DW9(phy),
+		    IREF0RC_OFFSET_MASK, 0xe4 << IREF0RC_OFFSET_SHIFT,
+		    "BXT_PORT_CL1CM_DW9(%d)", phy);
+	ok &= _CHK(BXT_PORT_CL1CM_DW10(phy),
+		    IREF1RC_OFFSET_MASK, 0xe4 << IREF1RC_OFFSET_SHIFT,
+		    "BXT_PORT_CL1CM_DW10(%d)", phy);
+
+	/* Power gating */
+	mask = OCL1_POWER_DOWN_EN | DW28_OLDO_DYN_PWR_DOWN_EN | SUS_CLK_CONFIG;
+	ok &= _CHK(BXT_PORT_CL1CM_DW28(phy), mask, mask,
+		    "BXT_PORT_CL1CM_DW28(%d)", phy);
+
+	if (phy == DPIO_PHY0)
+		ok &= _CHK(BXT_PORT_CL2CM_DW6_BC,
+			   DW6_OLDO_DYN_PWR_DOWN_EN, DW6_OLDO_DYN_PWR_DOWN_EN,
+			   "BXT_PORT_CL2CM_DW6_BC");
+
+	/*
+	 * TODO: Verify BXT_PORT_CL1CM_DW30 bit OCL2_LDOFUSE_PWR_DIS,
+	 * at least on stepping A this bit is read-only and fixed at 0.
+	 */
+
+	if (phy == DPIO_PHY0) {
+		u32 grc_code = dev_priv->bxt_phy_grc;
+
+		grc_code = grc_code << GRC_CODE_FAST_SHIFT |
+			   grc_code << GRC_CODE_SLOW_SHIFT |
+			   grc_code;
+		mask = GRC_CODE_FAST_MASK | GRC_CODE_SLOW_MASK |
+		       GRC_CODE_NOM_MASK;
+		ok &= _CHK(BXT_PORT_REF_DW6(DPIO_PHY0), mask, grc_code,
+			    "BXT_PORT_REF_DW6(%d)", DPIO_PHY0);
+
+		mask = GRC_DIS | GRC_RDY_OVRD;
+		ok &= _CHK(BXT_PORT_REF_DW8(DPIO_PHY0), mask, mask,
+			    "BXT_PORT_REF_DW8(%d)", DPIO_PHY0);
+	}
+
+	return ok;
+#undef _CHK
+}
+
+void broxton_ddi_phy_verify_state(struct drm_i915_private *dev_priv)
+{
+	if (!broxton_phy_verify_state(dev_priv, DPIO_PHY0) ||
+	    !broxton_phy_verify_state(dev_priv, DPIO_PHY1))
+		i915_report_error(dev_priv, "DDI PHY state mismatch\n");
+}
+
+void intel_ddi_prepare_link_retrain(struct intel_dp *intel_dp)
+{
+	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
+	struct drm_i915_private *dev_priv =
+		to_i915(intel_dig_port->base.base.dev);
+	enum port port = intel_dig_port->port;
+	uint32_t val;
+	bool wait = false;
+
+	if (I915_READ(DP_TP_CTL(port)) & DP_TP_CTL_ENABLE) {
+		val = I915_READ(DDI_BUF_CTL(port));
+		if (val & DDI_BUF_CTL_ENABLE) {
+			val &= ~DDI_BUF_CTL_ENABLE;
+			I915_WRITE(DDI_BUF_CTL(port), val);
+			wait = true;
+		}
+
+		val = I915_READ(DP_TP_CTL(port));
+		val &= ~(DP_TP_CTL_ENABLE | DP_TP_CTL_LINK_TRAIN_MASK);
+		val |= DP_TP_CTL_LINK_TRAIN_PAT1;
+		I915_WRITE(DP_TP_CTL(port), val);
+		POSTING_READ(DP_TP_CTL(port));
+
+		if (wait)
+			intel_wait_ddi_buf_idle(dev_priv, port);
+	}
+
+	val = DP_TP_CTL_ENABLE |
+	      DP_TP_CTL_LINK_TRAIN_PAT1 | DP_TP_CTL_SCRAMBLE_DISABLE;
+	if (intel_dp->is_mst)
+		val |= DP_TP_CTL_MODE_MST;
+	else {
+		val |= DP_TP_CTL_MODE_SST;
+		if (drm_dp_enhanced_frame_cap(intel_dp->dpcd))
+			val |= DP_TP_CTL_ENHANCED_FRAME_ENABLE;
+	}
+	I915_WRITE(DP_TP_CTL(port), val);
+	POSTING_READ(DP_TP_CTL(port));
+
+	intel_dp->DP |= DDI_BUF_CTL_ENABLE;
+	I915_WRITE(DDI_BUF_CTL(port), intel_dp->DP);
+	POSTING_READ(DDI_BUF_CTL(port));
+
+	udelay(600);
+}
+
+void intel_ddi_fdi_disable(struct drm_crtc *crtc)
+{
+	struct drm_i915_private *dev_priv = crtc->dev->dev_private;
+	struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc);
+	uint32_t val;
+
+	/*
+	 * Bspec lists this as both step 13 (before DDI_BUF_CTL disable)
+	 * and step 18 (after clearing PORT_CLK_SEL). Based on a BUN,
+	 * step 13 is the correct place for it. Step 18 is where it was
+	 * originally before the BUN.
+	 */
+	val = I915_READ(FDI_RX_CTL(PIPE_A));
+	val &= ~FDI_RX_ENABLE;
+	I915_WRITE(FDI_RX_CTL(PIPE_A), val);
+
+	intel_ddi_post_disable(intel_encoder);
+
+	val = I915_READ(FDI_RX_MISC(PIPE_A));
+	val &= ~(FDI_RX_PWRDN_LANE1_MASK | FDI_RX_PWRDN_LANE0_MASK);
+	val |= FDI_RX_PWRDN_LANE1_VAL(2) | FDI_RX_PWRDN_LANE0_VAL(2);
+	I915_WRITE(FDI_RX_MISC(PIPE_A), val);
+
+	val = I915_READ(FDI_RX_CTL(PIPE_A));
+	val &= ~FDI_PCDCLK;
+	I915_WRITE(FDI_RX_CTL(PIPE_A), val);
+
+	val = I915_READ(FDI_RX_CTL(PIPE_A));
+	val &= ~FDI_RX_PLL_ENABLE;
+	I915_WRITE(FDI_RX_CTL(PIPE_A), val);
+}
+
+void intel_ddi_get_config(struct intel_encoder *encoder,
+			  struct intel_crtc_state *pipe_config)
+{
+	struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
+	struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc);
+	enum transcoder cpu_transcoder = pipe_config->cpu_transcoder;
+	struct intel_hdmi *intel_hdmi;
+	u32 temp, flags = 0;
+
+	/* XXX: DSI transcoder paranoia */
+	if (WARN_ON(transcoder_is_dsi(cpu_transcoder)))
+		return;
+
+	temp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder));
+	if (temp & TRANS_DDI_PHSYNC)
+		flags |= DRM_MODE_FLAG_PHSYNC;
+	else
+		flags |= DRM_MODE_FLAG_NHSYNC;
+	if (temp & TRANS_DDI_PVSYNC)
+		flags |= DRM_MODE_FLAG_PVSYNC;
+	else
+		flags |= DRM_MODE_FLAG_NVSYNC;
+
+	pipe_config->base.adjusted_mode.flags |= flags;
+
+	switch (temp & TRANS_DDI_BPC_MASK) {
+	case TRANS_DDI_BPC_6:
+		pipe_config->pipe_bpp = 18;
+		break;
+	case TRANS_DDI_BPC_8:
+		pipe_config->pipe_bpp = 24;
+		break;
+	case TRANS_DDI_BPC_10:
+		pipe_config->pipe_bpp = 30;
+		break;
+	case TRANS_DDI_BPC_12:
+		pipe_config->pipe_bpp = 36;
+		break;
+	default:
+		break;
+	}
+
+	switch (temp & TRANS_DDI_MODE_SELECT_MASK) {
+	case TRANS_DDI_MODE_SELECT_HDMI:
+		pipe_config->has_hdmi_sink = true;
+		intel_hdmi = enc_to_intel_hdmi(&encoder->base);
+
+		if (intel_hdmi->infoframe_enabled(&encoder->base, pipe_config))
+			pipe_config->has_infoframe = true;
+		/* fall through */
+	case TRANS_DDI_MODE_SELECT_DVI:
+		pipe_config->lane_count = 4;
+		break;
+	case TRANS_DDI_MODE_SELECT_FDI:
+		break;
+	case TRANS_DDI_MODE_SELECT_DP_SST:
+	case TRANS_DDI_MODE_SELECT_DP_MST:
+		pipe_config->has_dp_encoder = true;
+		pipe_config->lane_count =
+			((temp & DDI_PORT_WIDTH_MASK) >> DDI_PORT_WIDTH_SHIFT) + 1;
+		intel_dp_get_m_n(intel_crtc, pipe_config);
+		break;
+	default:
+		break;
+	}
+
+	if (intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_AUDIO)) {
+		temp = I915_READ(HSW_AUD_PIN_ELD_CP_VLD);
+		if (temp & AUDIO_OUTPUT_ENABLE(intel_crtc->pipe))
+			pipe_config->has_audio = true;
+	}
+
+	if (encoder->type == INTEL_OUTPUT_EDP && dev_priv->vbt.edp.bpp &&
+	    pipe_config->pipe_bpp > dev_priv->vbt.edp.bpp) {
+		/*
+		 * This is a big fat ugly hack.
+		 *
+		 * Some machines in UEFI boot mode provide us a VBT that has 18
+		 * bpp and 1.62 GHz link bandwidth for eDP, which for reasons
+		 * unknown we fail to light up. Yet the same BIOS boots up with
+		 * 24 bpp and 2.7 GHz link. Use the same bpp as the BIOS uses as
+		 * max, not what it tells us to use.
+		 *
+		 * Note: This will still be broken if the eDP panel is not lit
+		 * up by the BIOS, and thus we can't get the mode at module
+		 * load.
+		 */
+		DRM_DEBUG_KMS("pipe has %d bpp for eDP panel, overriding BIOS-provided max %d bpp\n",
+			      pipe_config->pipe_bpp, dev_priv->vbt.edp.bpp);
+		dev_priv->vbt.edp.bpp = pipe_config->pipe_bpp;
+	}
+
+	intel_ddi_clock_get(encoder, pipe_config);
+}
+
+static bool intel_ddi_compute_config(struct intel_encoder *encoder,
+				     struct intel_crtc_state *pipe_config)
+{
+	int type = encoder->type;
+	int port = intel_ddi_get_encoder_port(encoder);
+
+	WARN(type == INTEL_OUTPUT_UNKNOWN, "compute_config() on unknown output!\n");
+
+	if (port == PORT_A)
+		pipe_config->cpu_transcoder = TRANSCODER_EDP;
+
+	if (type == INTEL_OUTPUT_HDMI)
+		return intel_hdmi_compute_config(encoder, pipe_config);
+	else
+		return intel_dp_compute_config(encoder, pipe_config);
+}
+
+static const struct drm_encoder_funcs intel_ddi_funcs = {
+	.reset = intel_dp_encoder_reset,
+	.destroy = intel_dp_encoder_destroy,
+};
+
+static struct intel_connector *
+intel_ddi_init_dp_connector(struct intel_digital_port *intel_dig_port)
+{
+	struct intel_connector *connector;
+	enum port port = intel_dig_port->port;
+
+	connector = intel_connector_alloc();
+	if (!connector)
+		return NULL;
+
+	intel_dig_port->dp.output_reg = DDI_BUF_CTL(port);
+	if (!intel_dp_init_connector(intel_dig_port, connector)) {
+		kfree(connector);
+		return NULL;
+	}
+
+	return connector;
+}
+
+static struct intel_connector *
+intel_ddi_init_hdmi_connector(struct intel_digital_port *intel_dig_port)
+{
+	struct intel_connector *connector;
+	enum port port = intel_dig_port->port;
+
+	connector = intel_connector_alloc();
+	if (!connector)
+		return NULL;
+
+	intel_dig_port->hdmi.hdmi_reg = DDI_BUF_CTL(port);
+	intel_hdmi_init_connector(intel_dig_port, connector);
+
+	return connector;
+}
+
+void intel_ddi_init(struct drm_device *dev, enum port port)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_digital_port *intel_dig_port;
+	struct intel_encoder *intel_encoder;
+	struct drm_encoder *encoder;
+	bool init_hdmi, init_dp;
+	int max_lanes;
+
+	if (I915_READ(DDI_BUF_CTL(PORT_A)) & DDI_A_4_LANES) {
+		switch (port) {
+		case PORT_A:
+			max_lanes = 4;
+			break;
+		case PORT_E:
+			max_lanes = 0;
+			break;
+		default:
+			max_lanes = 4;
+			break;
+		}
+	} else {
+		switch (port) {
+		case PORT_A:
+			max_lanes = 2;
+			break;
+		case PORT_E:
+			max_lanes = 2;
+			break;
+		default:
+			max_lanes = 4;
+			break;
+		}
+	}
+
+	init_hdmi = (dev_priv->vbt.ddi_port_info[port].supports_dvi ||
+		     dev_priv->vbt.ddi_port_info[port].supports_hdmi);
+	init_dp = dev_priv->vbt.ddi_port_info[port].supports_dp;
+	if (!init_dp && !init_hdmi) {
+		DRM_DEBUG_KMS("VBT says port %c is not DVI/HDMI/DP compatible, respect it\n",
+			      port_name(port));
+		return;
+	}
+
+	intel_dig_port = kzalloc(sizeof(*intel_dig_port), GFP_KERNEL);
+	if (!intel_dig_port)
+		return;
+
+	intel_encoder = &intel_dig_port->base;
+	encoder = &intel_encoder->base;
+
+	drm_encoder_init(dev, encoder, &intel_ddi_funcs,
+			 DRM_MODE_ENCODER_TMDS);
+
+	intel_encoder->compute_config = intel_ddi_compute_config;
+	intel_encoder->enable = intel_enable_ddi;
+	intel_encoder->pre_enable = intel_ddi_pre_enable;
+	intel_encoder->disable = intel_disable_ddi;
+	intel_encoder->post_disable = intel_ddi_post_disable;
+	intel_encoder->get_hw_state = intel_ddi_get_hw_state;
+	intel_encoder->get_config = intel_ddi_get_config;
+	intel_encoder->suspend = intel_dp_encoder_suspend;
+
+	intel_dig_port->port = port;
+	intel_dig_port->saved_port_bits = I915_READ(DDI_BUF_CTL(port)) &
+					  (DDI_BUF_PORT_REVERSAL |
+					   DDI_A_4_LANES);
+
+	/*
+	 * Bspec says that DDI_A_4_LANES is the only supported configuration
+	 * for Broxton.  Yet some BIOS fail to set this bit on port A if eDP
+	 * wasn't lit up at boot.  Force this bit on in our internal
+	 * configuration so that we use the proper lane count for our
+	 * calculations.
+	 */
+	if (IS_BROXTON(dev) && port == PORT_A) {
+		if (!(intel_dig_port->saved_port_bits & DDI_A_4_LANES)) {
+			DRM_DEBUG_KMS("BXT BIOS forgot to set DDI_A_4_LANES for port A; fixing\n");
+			intel_dig_port->saved_port_bits |= DDI_A_4_LANES;
+			max_lanes = 4;
+		}
+	}
+
+	intel_dig_port->max_lanes = max_lanes;
+
+	intel_encoder->type = INTEL_OUTPUT_UNKNOWN;
+	intel_encoder->crtc_mask = (1 << 0) | (1 << 1) | (1 << 2);
+	intel_encoder->cloneable = 0;
+
+	if (init_dp) {
+		if (!intel_ddi_init_dp_connector(intel_dig_port))
+			goto err;
+
+		intel_dig_port->hpd_pulse = intel_dp_hpd_pulse;
+		/*
+		 * On BXT A0/A1, sw needs to activate DDIA HPD logic and
+		 * interrupts to check the external panel connection.
+		 */
+		if (IS_BXT_REVID(dev, 0, BXT_REVID_A1) && port == PORT_B)
+			dev_priv->hotplug.irq_port[PORT_A] = intel_dig_port;
+		else
+			dev_priv->hotplug.irq_port[port] = intel_dig_port;
+	}
+
+	/* In theory we don't need the encoder->type check, but leave it just in
+	 * case we have some really bad VBTs... */
+	if (intel_encoder->type != INTEL_OUTPUT_EDP && init_hdmi) {
+		if (!intel_ddi_init_hdmi_connector(intel_dig_port))
+			goto err;
+	}
+
+	return;
+
+err:
+	drm_encoder_cleanup(encoder);
+	kfree(intel_dig_port);
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/i915/intel_display.c
@@ -0,0 +1,16378 @@
+/*
+ * Copyright © 2006-2007 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *	Eric Anholt <eric@anholt.net>
+ */
+
+#include <linux/dmi.h>
+#include <linux/module.h>
+#include <linux/input.h>
+#include <linux/i2c.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/vgaarb.h>
+#include <drm/drm_edid.h>
+#include <drm/drmP.h>
+#include "intel_drv.h"
+#include <drm/i915_drm.h>
+#include "i915_drv.h"
+#include "intel_dsi.h"
+#include "i915_trace.h"
+#include <drm/drm_atomic.h>
+#include <drm/drm_atomic_helper.h>
+#include <drm/drm_dp_helper.h>
+#include <drm/drm_crtc_helper.h>
+#include <drm/drm_plane_helper.h>
+#include <drm/drm_rect.h>
+#include <linux/dma_remapping.h>
+#include <linux/reservation.h>
+#include <linux/dma-buf.h>
+
+/* Primary plane formats for gen <= 3 */
+static const uint32_t i8xx_primary_formats[] = {
+	DRM_FORMAT_C8,
+	DRM_FORMAT_RGB565,
+	DRM_FORMAT_XRGB1555,
+	DRM_FORMAT_XRGB8888,
+};
+
+/* Primary plane formats for gen >= 4 */
+static const uint32_t i965_primary_formats[] = {
+	DRM_FORMAT_C8,
+	DRM_FORMAT_RGB565,
+	DRM_FORMAT_XRGB8888,
+	DRM_FORMAT_XBGR8888,
+	DRM_FORMAT_XRGB2101010,
+	DRM_FORMAT_XBGR2101010,
+};
+
+static const uint32_t skl_primary_formats[] = {
+	DRM_FORMAT_C8,
+	DRM_FORMAT_RGB565,
+	DRM_FORMAT_XRGB8888,
+	DRM_FORMAT_XBGR8888,
+	DRM_FORMAT_ARGB8888,
+	DRM_FORMAT_ABGR8888,
+	DRM_FORMAT_XRGB2101010,
+	DRM_FORMAT_XBGR2101010,
+	DRM_FORMAT_YUYV,
+	DRM_FORMAT_YVYU,
+	DRM_FORMAT_UYVY,
+	DRM_FORMAT_VYUY,
+};
+
+/* Cursor formats */
+static const uint32_t intel_cursor_formats[] = {
+	DRM_FORMAT_ARGB8888,
+};
+
+static void i9xx_crtc_clock_get(struct intel_crtc *crtc,
+				struct intel_crtc_state *pipe_config);
+static void ironlake_pch_clock_get(struct intel_crtc *crtc,
+				   struct intel_crtc_state *pipe_config);
+
+static int intel_framebuffer_init(struct drm_device *dev,
+				  struct intel_framebuffer *ifb,
+				  struct drm_mode_fb_cmd2 *mode_cmd,
+				  struct drm_i915_gem_object *obj);
+static void i9xx_set_pipeconf(struct intel_crtc *intel_crtc);
+static void intel_set_pipe_timings(struct intel_crtc *intel_crtc);
+static void intel_set_pipe_src_size(struct intel_crtc *intel_crtc);
+static void intel_cpu_transcoder_set_m_n(struct intel_crtc *crtc,
+					 struct intel_link_m_n *m_n,
+					 struct intel_link_m_n *m2_n2);
+static void ironlake_set_pipeconf(struct drm_crtc *crtc);
+static void haswell_set_pipeconf(struct drm_crtc *crtc);
+static void haswell_set_pipemisc(struct drm_crtc *crtc);
+static void vlv_prepare_pll(struct intel_crtc *crtc,
+			    const struct intel_crtc_state *pipe_config);
+static void chv_prepare_pll(struct intel_crtc *crtc,
+			    const struct intel_crtc_state *pipe_config);
+static void intel_begin_crtc_commit(struct drm_crtc *, struct drm_crtc_state *);
+static void intel_finish_crtc_commit(struct drm_crtc *, struct drm_crtc_state *);
+static void skl_init_scalers(struct drm_device *dev, struct intel_crtc *intel_crtc,
+	struct intel_crtc_state *crtc_state);
+static void skylake_pfit_enable(struct intel_crtc *crtc);
+static void ironlake_pfit_disable(struct intel_crtc *crtc, bool force);
+static void ironlake_pfit_enable(struct intel_crtc *crtc);
+static void intel_modeset_setup_hw_state(struct drm_device *dev);
+static void intel_pre_disable_primary_noatomic(struct drm_crtc *crtc);
+
+typedef struct {
+	int	min, max;
+} intel_range_t;
+
+typedef struct {
+	int	dot_limit;
+	int	p2_slow, p2_fast;
+} intel_p2_t;
+
+typedef struct intel_limit intel_limit_t;
+struct intel_limit {
+	intel_range_t   dot, vco, n, m, m1, m2, p, p1;
+	intel_p2_t	    p2;
+};
+
+/* returns HPLL frequency in kHz */
+static int valleyview_get_vco(struct drm_i915_private *dev_priv)
+{
+	int hpll_freq, vco_freq[] = { 800, 1600, 2000, 2400 };
+
+	/* Obtain SKU information */
+	mutex_lock(&dev_priv->sb_lock);
+	hpll_freq = vlv_cck_read(dev_priv, CCK_FUSE_REG) &
+		CCK_FUSE_HPLL_FREQ_MASK;
+	mutex_unlock(&dev_priv->sb_lock);
+
+	return vco_freq[hpll_freq] * 1000;
+}
+
+int vlv_get_cck_clock(struct drm_i915_private *dev_priv,
+		      const char *name, u32 reg, int ref_freq)
+{
+	u32 val;
+	int divider;
+
+	mutex_lock(&dev_priv->sb_lock);
+	val = vlv_cck_read(dev_priv, reg);
+	mutex_unlock(&dev_priv->sb_lock);
+
+	divider = val & CCK_FREQUENCY_VALUES;
+
+	WARN((val & CCK_FREQUENCY_STATUS) !=
+	     (divider << CCK_FREQUENCY_STATUS_SHIFT),
+	     "%s change in progress\n", name);
+
+	return DIV_ROUND_CLOSEST(ref_freq << 1, divider + 1);
+}
+
+static int vlv_get_cck_clock_hpll(struct drm_i915_private *dev_priv,
+				  const char *name, u32 reg)
+{
+	if (dev_priv->hpll_freq == 0)
+		dev_priv->hpll_freq = valleyview_get_vco(dev_priv);
+
+	return vlv_get_cck_clock(dev_priv, name, reg,
+				 dev_priv->hpll_freq);
+}
+
+static int
+intel_pch_rawclk(struct drm_i915_private *dev_priv)
+{
+	return (I915_READ(PCH_RAWCLK_FREQ) & RAWCLK_FREQ_MASK) * 1000;
+}
+
+static int
+intel_vlv_hrawclk(struct drm_i915_private *dev_priv)
+{
+	return vlv_get_cck_clock_hpll(dev_priv, "hrawclk",
+				      CCK_DISPLAY_REF_CLOCK_CONTROL);
+}
+
+static int
+intel_g4x_hrawclk(struct drm_i915_private *dev_priv)
+{
+	uint32_t clkcfg;
+
+	/* hrawclock is 1/4 the FSB frequency */
+	clkcfg = I915_READ(CLKCFG);
+	switch (clkcfg & CLKCFG_FSB_MASK) {
+	case CLKCFG_FSB_400:
+		return 100000;
+	case CLKCFG_FSB_533:
+		return 133333;
+	case CLKCFG_FSB_667:
+		return 166667;
+	case CLKCFG_FSB_800:
+		return 200000;
+	case CLKCFG_FSB_1067:
+		return 266667;
+	case CLKCFG_FSB_1333:
+		return 333333;
+	/* these two are just a guess; one of them might be right */
+	case CLKCFG_FSB_1600:
+	case CLKCFG_FSB_1600_ALT:
+		return 400000;
+	default:
+		return 133333;
+	}
+}
+
+static void intel_update_rawclk(struct drm_i915_private *dev_priv)
+{
+	if (HAS_PCH_SPLIT(dev_priv))
+		dev_priv->rawclk_freq = intel_pch_rawclk(dev_priv);
+	else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
+		dev_priv->rawclk_freq = intel_vlv_hrawclk(dev_priv);
+	else if (IS_G4X(dev_priv) || IS_PINEVIEW(dev_priv))
+		dev_priv->rawclk_freq = intel_g4x_hrawclk(dev_priv);
+	else
+		return; /* no rawclk on other platforms, or no need to know it */
+
+	DRM_DEBUG_DRIVER("rawclk rate: %d kHz\n", dev_priv->rawclk_freq);
+}
+
+static void intel_update_czclk(struct drm_i915_private *dev_priv)
+{
+	if (!(IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)))
+		return;
+
+	dev_priv->czclk_freq = vlv_get_cck_clock_hpll(dev_priv, "czclk",
+						      CCK_CZ_CLOCK_CONTROL);
+
+	DRM_DEBUG_DRIVER("CZ clock rate: %d kHz\n", dev_priv->czclk_freq);
+}
+
+static inline u32 /* units of 100MHz */
+intel_fdi_link_freq(struct drm_i915_private *dev_priv,
+		    const struct intel_crtc_state *pipe_config)
+{
+	if (HAS_DDI(dev_priv))
+		return pipe_config->port_clock; /* SPLL */
+	else if (IS_GEN5(dev_priv))
+		return ((I915_READ(FDI_PLL_BIOS_0) & FDI_PLL_FB_CLOCK_MASK) + 2) * 10000;
+	else
+		return 270000;
+}
+
+static const intel_limit_t intel_limits_i8xx_dac = {
+	.dot = { .min = 25000, .max = 350000 },
+	.vco = { .min = 908000, .max = 1512000 },
+	.n = { .min = 2, .max = 16 },
+	.m = { .min = 96, .max = 140 },
+	.m1 = { .min = 18, .max = 26 },
+	.m2 = { .min = 6, .max = 16 },
+	.p = { .min = 4, .max = 128 },
+	.p1 = { .min = 2, .max = 33 },
+	.p2 = { .dot_limit = 165000,
+		.p2_slow = 4, .p2_fast = 2 },
+};
+
+static const intel_limit_t intel_limits_i8xx_dvo = {
+	.dot = { .min = 25000, .max = 350000 },
+	.vco = { .min = 908000, .max = 1512000 },
+	.n = { .min = 2, .max = 16 },
+	.m = { .min = 96, .max = 140 },
+	.m1 = { .min = 18, .max = 26 },
+	.m2 = { .min = 6, .max = 16 },
+	.p = { .min = 4, .max = 128 },
+	.p1 = { .min = 2, .max = 33 },
+	.p2 = { .dot_limit = 165000,
+		.p2_slow = 4, .p2_fast = 4 },
+};
+
+static const intel_limit_t intel_limits_i8xx_lvds = {
+	.dot = { .min = 25000, .max = 350000 },
+	.vco = { .min = 908000, .max = 1512000 },
+	.n = { .min = 2, .max = 16 },
+	.m = { .min = 96, .max = 140 },
+	.m1 = { .min = 18, .max = 26 },
+	.m2 = { .min = 6, .max = 16 },
+	.p = { .min = 4, .max = 128 },
+	.p1 = { .min = 1, .max = 6 },
+	.p2 = { .dot_limit = 165000,
+		.p2_slow = 14, .p2_fast = 7 },
+};
+
+static const intel_limit_t intel_limits_i9xx_sdvo = {
+	.dot = { .min = 20000, .max = 400000 },
+	.vco = { .min = 1400000, .max = 2800000 },
+	.n = { .min = 1, .max = 6 },
+	.m = { .min = 70, .max = 120 },
+	.m1 = { .min = 8, .max = 18 },
+	.m2 = { .min = 3, .max = 7 },
+	.p = { .min = 5, .max = 80 },
+	.p1 = { .min = 1, .max = 8 },
+	.p2 = { .dot_limit = 200000,
+		.p2_slow = 10, .p2_fast = 5 },
+};
+
+static const intel_limit_t intel_limits_i9xx_lvds = {
+	.dot = { .min = 20000, .max = 400000 },
+	.vco = { .min = 1400000, .max = 2800000 },
+	.n = { .min = 1, .max = 6 },
+	.m = { .min = 70, .max = 120 },
+	.m1 = { .min = 8, .max = 18 },
+	.m2 = { .min = 3, .max = 7 },
+	.p = { .min = 7, .max = 98 },
+	.p1 = { .min = 1, .max = 8 },
+	.p2 = { .dot_limit = 112000,
+		.p2_slow = 14, .p2_fast = 7 },
+};
+
+
+static const intel_limit_t intel_limits_g4x_sdvo = {
+	.dot = { .min = 25000, .max = 270000 },
+	.vco = { .min = 1750000, .max = 3500000},
+	.n = { .min = 1, .max = 4 },
+	.m = { .min = 104, .max = 138 },
+	.m1 = { .min = 17, .max = 23 },
+	.m2 = { .min = 5, .max = 11 },
+	.p = { .min = 10, .max = 30 },
+	.p1 = { .min = 1, .max = 3},
+	.p2 = { .dot_limit = 270000,
+		.p2_slow = 10,
+		.p2_fast = 10
+	},
+};
+
+static const intel_limit_t intel_limits_g4x_hdmi = {
+	.dot = { .min = 22000, .max = 400000 },
+	.vco = { .min = 1750000, .max = 3500000},
+	.n = { .min = 1, .max = 4 },
+	.m = { .min = 104, .max = 138 },
+	.m1 = { .min = 16, .max = 23 },
+	.m2 = { .min = 5, .max = 11 },
+	.p = { .min = 5, .max = 80 },
+	.p1 = { .min = 1, .max = 8},
+	.p2 = { .dot_limit = 165000,
+		.p2_slow = 10, .p2_fast = 5 },
+};
+
+static const intel_limit_t intel_limits_g4x_single_channel_lvds = {
+	.dot = { .min = 20000, .max = 115000 },
+	.vco = { .min = 1750000, .max = 3500000 },
+	.n = { .min = 1, .max = 3 },
+	.m = { .min = 104, .max = 138 },
+	.m1 = { .min = 17, .max = 23 },
+	.m2 = { .min = 5, .max = 11 },
+	.p = { .min = 28, .max = 112 },
+	.p1 = { .min = 2, .max = 8 },
+	.p2 = { .dot_limit = 0,
+		.p2_slow = 14, .p2_fast = 14
+	},
+};
+
+static const intel_limit_t intel_limits_g4x_dual_channel_lvds = {
+	.dot = { .min = 80000, .max = 224000 },
+	.vco = { .min = 1750000, .max = 3500000 },
+	.n = { .min = 1, .max = 3 },
+	.m = { .min = 104, .max = 138 },
+	.m1 = { .min = 17, .max = 23 },
+	.m2 = { .min = 5, .max = 11 },
+	.p = { .min = 14, .max = 42 },
+	.p1 = { .min = 2, .max = 6 },
+	.p2 = { .dot_limit = 0,
+		.p2_slow = 7, .p2_fast = 7
+	},
+};
+
+static const intel_limit_t intel_limits_pineview_sdvo = {
+	.dot = { .min = 20000, .max = 400000},
+	.vco = { .min = 1700000, .max = 3500000 },
+	/* Pineview's Ncounter is a ring counter */
+	.n = { .min = 3, .max = 6 },
+	.m = { .min = 2, .max = 256 },
+	/* Pineview only has one combined m divider, which we treat as m2. */
+	.m1 = { .min = 0, .max = 0 },
+	.m2 = { .min = 0, .max = 254 },
+	.p = { .min = 5, .max = 80 },
+	.p1 = { .min = 1, .max = 8 },
+	.p2 = { .dot_limit = 200000,
+		.p2_slow = 10, .p2_fast = 5 },
+};
+
+static const intel_limit_t intel_limits_pineview_lvds = {
+	.dot = { .min = 20000, .max = 400000 },
+	.vco = { .min = 1700000, .max = 3500000 },
+	.n = { .min = 3, .max = 6 },
+	.m = { .min = 2, .max = 256 },
+	.m1 = { .min = 0, .max = 0 },
+	.m2 = { .min = 0, .max = 254 },
+	.p = { .min = 7, .max = 112 },
+	.p1 = { .min = 1, .max = 8 },
+	.p2 = { .dot_limit = 112000,
+		.p2_slow = 14, .p2_fast = 14 },
+};
+
+/* Ironlake / Sandybridge
+ *
+ * We calculate clock using (register_value + 2) for N/M1/M2, so here
+ * the range value for them is (actual_value - 2).
+ */
+static const intel_limit_t intel_limits_ironlake_dac = {
+	.dot = { .min = 25000, .max = 350000 },
+	.vco = { .min = 1760000, .max = 3510000 },
+	.n = { .min = 1, .max = 5 },
+	.m = { .min = 79, .max = 127 },
+	.m1 = { .min = 12, .max = 22 },
+	.m2 = { .min = 5, .max = 9 },
+	.p = { .min = 5, .max = 80 },
+	.p1 = { .min = 1, .max = 8 },
+	.p2 = { .dot_limit = 225000,
+		.p2_slow = 10, .p2_fast = 5 },
+};
+
+static const intel_limit_t intel_limits_ironlake_single_lvds = {
+	.dot = { .min = 25000, .max = 350000 },
+	.vco = { .min = 1760000, .max = 3510000 },
+	.n = { .min = 1, .max = 3 },
+	.m = { .min = 79, .max = 118 },
+	.m1 = { .min = 12, .max = 22 },
+	.m2 = { .min = 5, .max = 9 },
+	.p = { .min = 28, .max = 112 },
+	.p1 = { .min = 2, .max = 8 },
+	.p2 = { .dot_limit = 225000,
+		.p2_slow = 14, .p2_fast = 14 },
+};
+
+static const intel_limit_t intel_limits_ironlake_dual_lvds = {
+	.dot = { .min = 25000, .max = 350000 },
+	.vco = { .min = 1760000, .max = 3510000 },
+	.n = { .min = 1, .max = 3 },
+	.m = { .min = 79, .max = 127 },
+	.m1 = { .min = 12, .max = 22 },
+	.m2 = { .min = 5, .max = 9 },
+	.p = { .min = 14, .max = 56 },
+	.p1 = { .min = 2, .max = 8 },
+	.p2 = { .dot_limit = 225000,
+		.p2_slow = 7, .p2_fast = 7 },
+};
+
+/* LVDS 100mhz refclk limits. */
+static const intel_limit_t intel_limits_ironlake_single_lvds_100m = {
+	.dot = { .min = 25000, .max = 350000 },
+	.vco = { .min = 1760000, .max = 3510000 },
+	.n = { .min = 1, .max = 2 },
+	.m = { .min = 79, .max = 126 },
+	.m1 = { .min = 12, .max = 22 },
+	.m2 = { .min = 5, .max = 9 },
+	.p = { .min = 28, .max = 112 },
+	.p1 = { .min = 2, .max = 8 },
+	.p2 = { .dot_limit = 225000,
+		.p2_slow = 14, .p2_fast = 14 },
+};
+
+static const intel_limit_t intel_limits_ironlake_dual_lvds_100m = {
+	.dot = { .min = 25000, .max = 350000 },
+	.vco = { .min = 1760000, .max = 3510000 },
+	.n = { .min = 1, .max = 3 },
+	.m = { .min = 79, .max = 126 },
+	.m1 = { .min = 12, .max = 22 },
+	.m2 = { .min = 5, .max = 9 },
+	.p = { .min = 14, .max = 42 },
+	.p1 = { .min = 2, .max = 6 },
+	.p2 = { .dot_limit = 225000,
+		.p2_slow = 7, .p2_fast = 7 },
+};
+
+static const intel_limit_t intel_limits_vlv = {
+	 /*
+	  * These are the data rate limits (measured in fast clocks)
+	  * since those are the strictest limits we have. The fast
+	  * clock and actual rate limits are more relaxed, so checking
+	  * them would make no difference.
+	  */
+	.dot = { .min = 25000 * 5, .max = 270000 * 5 },
+	.vco = { .min = 4000000, .max = 6000000 },
+	.n = { .min = 1, .max = 7 },
+	.m1 = { .min = 2, .max = 3 },
+	.m2 = { .min = 11, .max = 156 },
+	.p1 = { .min = 2, .max = 3 },
+	.p2 = { .p2_slow = 2, .p2_fast = 20 }, /* slow=min, fast=max */
+};
+
+static const intel_limit_t intel_limits_chv = {
+	/*
+	 * These are the data rate limits (measured in fast clocks)
+	 * since those are the strictest limits we have.  The fast
+	 * clock and actual rate limits are more relaxed, so checking
+	 * them would make no difference.
+	 */
+	.dot = { .min = 25000 * 5, .max = 540000 * 5},
+	.vco = { .min = 4800000, .max = 6480000 },
+	.n = { .min = 1, .max = 1 },
+	.m1 = { .min = 2, .max = 2 },
+	.m2 = { .min = 24 << 22, .max = 175 << 22 },
+	.p1 = { .min = 2, .max = 4 },
+	.p2 = {	.p2_slow = 1, .p2_fast = 14 },
+};
+
+static const intel_limit_t intel_limits_bxt = {
+	/* FIXME: find real dot limits */
+	.dot = { .min = 0, .max = INT_MAX },
+	.vco = { .min = 4800000, .max = 6700000 },
+	.n = { .min = 1, .max = 1 },
+	.m1 = { .min = 2, .max = 2 },
+	/* FIXME: find real m2 limits */
+	.m2 = { .min = 2 << 22, .max = 255 << 22 },
+	.p1 = { .min = 2, .max = 4 },
+	.p2 = { .p2_slow = 1, .p2_fast = 20 },
+};
+
+static bool
+needs_modeset(struct drm_crtc_state *state)
+{
+	return drm_atomic_crtc_needs_modeset(state);
+}
+
+/**
+ * Returns whether any output on the specified pipe is of the specified type
+ */
+bool intel_pipe_has_type(struct intel_crtc *crtc, enum intel_output_type type)
+{
+	struct drm_device *dev = crtc->base.dev;
+	struct intel_encoder *encoder;
+
+	for_each_encoder_on_crtc(dev, &crtc->base, encoder)
+		if (encoder->type == type)
+			return true;
+
+	return false;
+}
+
+/**
+ * Returns whether any output on the specified pipe will have the specified
+ * type after a staged modeset is complete, i.e., the same as
+ * intel_pipe_has_type() but looking at encoder->new_crtc instead of
+ * encoder->crtc.
+ */
+static bool intel_pipe_will_have_type(const struct intel_crtc_state *crtc_state,
+				      int type)
+{
+	struct drm_atomic_state *state = crtc_state->base.state;
+	struct drm_connector *connector;
+	struct drm_connector_state *connector_state;
+	struct intel_encoder *encoder;
+	int i, num_connectors = 0;
+
+	for_each_connector_in_state(state, connector, connector_state, i) {
+		if (connector_state->crtc != crtc_state->base.crtc)
+			continue;
+
+		num_connectors++;
+
+		encoder = to_intel_encoder(connector_state->best_encoder);
+		if (encoder->type == type)
+			return true;
+	}
+
+	WARN_ON(num_connectors == 0);
+
+	return false;
+}
+
+/*
+ * Platform specific helpers to calculate the port PLL loopback- (clock.m),
+ * and post-divider (clock.p) values, pre- (clock.vco) and post-divided fast
+ * (clock.dot) clock rates. This fast dot clock is fed to the port's IO logic.
+ * The helpers' return value is the rate of the clock that is fed to the
+ * display engine's pipe which can be the above fast dot clock rate or a
+ * divided-down version of it.
+ */
+/* m1 is reserved as 0 in Pineview, n is a ring counter */
+static int pnv_calc_dpll_params(int refclk, intel_clock_t *clock)
+{
+	clock->m = clock->m2 + 2;
+	clock->p = clock->p1 * clock->p2;
+	if (WARN_ON(clock->n == 0 || clock->p == 0))
+		return 0;
+	clock->vco = DIV_ROUND_CLOSEST(refclk * clock->m, clock->n);
+	clock->dot = DIV_ROUND_CLOSEST(clock->vco, clock->p);
+
+	return clock->dot;
+}
+
+static uint32_t i9xx_dpll_compute_m(struct dpll *dpll)
+{
+	return 5 * (dpll->m1 + 2) + (dpll->m2 + 2);
+}
+
+static int i9xx_calc_dpll_params(int refclk, intel_clock_t *clock)
+{
+	clock->m = i9xx_dpll_compute_m(clock);
+	clock->p = clock->p1 * clock->p2;
+	if (WARN_ON(clock->n + 2 == 0 || clock->p == 0))
+		return 0;
+	clock->vco = DIV_ROUND_CLOSEST(refclk * clock->m, clock->n + 2);
+	clock->dot = DIV_ROUND_CLOSEST(clock->vco, clock->p);
+
+	return clock->dot;
+}
+
+static int vlv_calc_dpll_params(int refclk, intel_clock_t *clock)
+{
+	clock->m = clock->m1 * clock->m2;
+	clock->p = clock->p1 * clock->p2;
+	if (WARN_ON(clock->n == 0 || clock->p == 0))
+		return 0;
+	clock->vco = DIV_ROUND_CLOSEST(refclk * clock->m, clock->n);
+	clock->dot = DIV_ROUND_CLOSEST(clock->vco, clock->p);
+
+	return clock->dot / 5;
+}
+
+int chv_calc_dpll_params(int refclk, intel_clock_t *clock)
+{
+	clock->m = clock->m1 * clock->m2;
+	clock->p = clock->p1 * clock->p2;
+	if (WARN_ON(clock->n == 0 || clock->p == 0))
+		return 0;
+	clock->vco = DIV_ROUND_CLOSEST_ULL((uint64_t)refclk * clock->m,
+			clock->n << 22);
+	clock->dot = DIV_ROUND_CLOSEST(clock->vco, clock->p);
+
+	return clock->dot / 5;
+}
+
+#define INTELPllInvalid(s)   do { /* DRM_DEBUG(s); */ return false; } while (0)
+/**
+ * Returns whether the given set of divisors are valid for a given refclk with
+ * the given connectors.
+ */
+
+static bool intel_PLL_is_valid(struct drm_device *dev,
+			       const intel_limit_t *limit,
+			       const intel_clock_t *clock)
+{
+	if (clock->n   < limit->n.min   || limit->n.max   < clock->n)
+		INTELPllInvalid("n out of range\n");
+	if (clock->p1  < limit->p1.min  || limit->p1.max  < clock->p1)
+		INTELPllInvalid("p1 out of range\n");
+	if (clock->m2  < limit->m2.min  || limit->m2.max  < clock->m2)
+		INTELPllInvalid("m2 out of range\n");
+	if (clock->m1  < limit->m1.min  || limit->m1.max  < clock->m1)
+		INTELPllInvalid("m1 out of range\n");
+
+	if (!IS_PINEVIEW(dev) && !IS_VALLEYVIEW(dev) &&
+	    !IS_CHERRYVIEW(dev) && !IS_BROXTON(dev))
+		if (clock->m1 <= clock->m2)
+			INTELPllInvalid("m1 <= m2\n");
+
+	if (!IS_VALLEYVIEW(dev) && !IS_CHERRYVIEW(dev) && !IS_BROXTON(dev)) {
+		if (clock->p < limit->p.min || limit->p.max < clock->p)
+			INTELPllInvalid("p out of range\n");
+		if (clock->m < limit->m.min || limit->m.max < clock->m)
+			INTELPllInvalid("m out of range\n");
+	}
+
+	if (clock->vco < limit->vco.min || limit->vco.max < clock->vco)
+		INTELPllInvalid("vco out of range\n");
+	/* XXX: We may need to be checking "Dot clock" depending on the multiplier,
+	 * connector, etc., rather than just a single range.
+	 */
+	if (clock->dot < limit->dot.min || limit->dot.max < clock->dot)
+		INTELPllInvalid("dot out of range\n");
+
+	return true;
+}
+
+static int
+i9xx_select_p2_div(const intel_limit_t *limit,
+		   const struct intel_crtc_state *crtc_state,
+		   int target)
+{
+	struct drm_device *dev = crtc_state->base.crtc->dev;
+
+	if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_LVDS)) {
+		/*
+		 * For LVDS just rely on its current settings for dual-channel.
+		 * We haven't figured out how to reliably set up different
+		 * single/dual channel state, if we even can.
+		 */
+		if (intel_is_dual_link_lvds(dev))
+			return limit->p2.p2_fast;
+		else
+			return limit->p2.p2_slow;
+	} else {
+		if (target < limit->p2.dot_limit)
+			return limit->p2.p2_slow;
+		else
+			return limit->p2.p2_fast;
+	}
+}
+
+/*
+ * Returns a set of divisors for the desired target clock with the given
+ * refclk, or FALSE.  The returned values represent the clock equation:
+ * reflck * (5 * (m1 + 2) + (m2 + 2)) / (n + 2) / p1 / p2.
+ *
+ * Target and reference clocks are specified in kHz.
+ *
+ * If match_clock is provided, then best_clock P divider must match the P
+ * divider from @match_clock used for LVDS downclocking.
+ */
+static bool
+i9xx_find_best_dpll(const intel_limit_t *limit,
+		    struct intel_crtc_state *crtc_state,
+		    int target, int refclk, intel_clock_t *match_clock,
+		    intel_clock_t *best_clock)
+{
+	struct drm_device *dev = crtc_state->base.crtc->dev;
+	intel_clock_t clock;
+	int err = target;
+
+	memset(best_clock, 0, sizeof(*best_clock));
+
+	clock.p2 = i9xx_select_p2_div(limit, crtc_state, target);
+
+	for (clock.m1 = limit->m1.min; clock.m1 <= limit->m1.max;
+	     clock.m1++) {
+		for (clock.m2 = limit->m2.min;
+		     clock.m2 <= limit->m2.max; clock.m2++) {
+			if (clock.m2 >= clock.m1)
+				break;
+			for (clock.n = limit->n.min;
+			     clock.n <= limit->n.max; clock.n++) {
+				for (clock.p1 = limit->p1.min;
+					clock.p1 <= limit->p1.max; clock.p1++) {
+					int this_err;
+
+					i9xx_calc_dpll_params(refclk, &clock);
+					if (!intel_PLL_is_valid(dev, limit,
+								&clock))
+						continue;
+					if (match_clock &&
+					    clock.p != match_clock->p)
+						continue;
+
+					this_err = abs(clock.dot - target);
+					if (this_err < err) {
+						*best_clock = clock;
+						err = this_err;
+					}
+				}
+			}
+		}
+	}
+
+	return (err != target);
+}
+
+/*
+ * Returns a set of divisors for the desired target clock with the given
+ * refclk, or FALSE.  The returned values represent the clock equation:
+ * reflck * (5 * (m1 + 2) + (m2 + 2)) / (n + 2) / p1 / p2.
+ *
+ * Target and reference clocks are specified in kHz.
+ *
+ * If match_clock is provided, then best_clock P divider must match the P
+ * divider from @match_clock used for LVDS downclocking.
+ */
+static bool
+pnv_find_best_dpll(const intel_limit_t *limit,
+		   struct intel_crtc_state *crtc_state,
+		   int target, int refclk, intel_clock_t *match_clock,
+		   intel_clock_t *best_clock)
+{
+	struct drm_device *dev = crtc_state->base.crtc->dev;
+	intel_clock_t clock;
+	int err = target;
+
+	memset(best_clock, 0, sizeof(*best_clock));
+
+	clock.p2 = i9xx_select_p2_div(limit, crtc_state, target);
+
+	for (clock.m1 = limit->m1.min; clock.m1 <= limit->m1.max;
+	     clock.m1++) {
+		for (clock.m2 = limit->m2.min;
+		     clock.m2 <= limit->m2.max; clock.m2++) {
+			for (clock.n = limit->n.min;
+			     clock.n <= limit->n.max; clock.n++) {
+				for (clock.p1 = limit->p1.min;
+					clock.p1 <= limit->p1.max; clock.p1++) {
+					int this_err;
+
+					pnv_calc_dpll_params(refclk, &clock);
+					if (!intel_PLL_is_valid(dev, limit,
+								&clock))
+						continue;
+					if (match_clock &&
+					    clock.p != match_clock->p)
+						continue;
+
+					this_err = abs(clock.dot - target);
+					if (this_err < err) {
+						*best_clock = clock;
+						err = this_err;
+					}
+				}
+			}
+		}
+	}
+
+	return (err != target);
+}
+
+/*
+ * Returns a set of divisors for the desired target clock with the given
+ * refclk, or FALSE.  The returned values represent the clock equation:
+ * reflck * (5 * (m1 + 2) + (m2 + 2)) / (n + 2) / p1 / p2.
+ *
+ * Target and reference clocks are specified in kHz.
+ *
+ * If match_clock is provided, then best_clock P divider must match the P
+ * divider from @match_clock used for LVDS downclocking.
+ */
+static bool
+g4x_find_best_dpll(const intel_limit_t *limit,
+		   struct intel_crtc_state *crtc_state,
+		   int target, int refclk, intel_clock_t *match_clock,
+		   intel_clock_t *best_clock)
+{
+	struct drm_device *dev = crtc_state->base.crtc->dev;
+	intel_clock_t clock;
+	int max_n;
+	bool found = false;
+	/* approximately equals target * 0.00585 */
+	int err_most = (target >> 8) + (target >> 9);
+
+	memset(best_clock, 0, sizeof(*best_clock));
+
+	clock.p2 = i9xx_select_p2_div(limit, crtc_state, target);
+
+	max_n = limit->n.max;
+	/* based on hardware requirement, prefer smaller n to precision */
+	for (clock.n = limit->n.min; clock.n <= max_n; clock.n++) {
+		/* based on hardware requirement, prefere larger m1,m2 */
+		for (clock.m1 = limit->m1.max;
+		     clock.m1 >= limit->m1.min; clock.m1--) {
+			for (clock.m2 = limit->m2.max;
+			     clock.m2 >= limit->m2.min; clock.m2--) {
+				for (clock.p1 = limit->p1.max;
+				     clock.p1 >= limit->p1.min; clock.p1--) {
+					int this_err;
+
+					i9xx_calc_dpll_params(refclk, &clock);
+					if (!intel_PLL_is_valid(dev, limit,
+								&clock))
+						continue;
+
+					this_err = abs(clock.dot - target);
+					if (this_err < err_most) {
+						*best_clock = clock;
+						err_most = this_err;
+						max_n = clock.n;
+						found = true;
+					}
+				}
+			}
+		}
+	}
+	return found;
+}
+
+/*
+ * Check if the calculated PLL configuration is more optimal compared to the
+ * best configuration and error found so far. Return the calculated error.
+ */
+static bool vlv_PLL_is_optimal(struct drm_device *dev, int target_freq,
+			       const intel_clock_t *calculated_clock,
+			       const intel_clock_t *best_clock,
+			       unsigned int best_error_ppm,
+			       unsigned int *error_ppm)
+{
+	/*
+	 * For CHV ignore the error and consider only the P value.
+	 * Prefer a bigger P value based on HW requirements.
+	 */
+	if (IS_CHERRYVIEW(dev)) {
+		*error_ppm = 0;
+
+		return calculated_clock->p > best_clock->p;
+	}
+
+	if (WARN_ON_ONCE(!target_freq))
+		return false;
+
+	*error_ppm = div_u64(1000000ULL *
+				abs(target_freq - calculated_clock->dot),
+			     target_freq);
+	/*
+	 * Prefer a better P value over a better (smaller) error if the error
+	 * is small. Ensure this preference for future configurations too by
+	 * setting the error to 0.
+	 */
+	if (*error_ppm < 100 && calculated_clock->p > best_clock->p) {
+		*error_ppm = 0;
+
+		return true;
+	}
+
+	return *error_ppm + 10 < best_error_ppm;
+}
+
+/*
+ * Returns a set of divisors for the desired target clock with the given
+ * refclk, or FALSE.  The returned values represent the clock equation:
+ * reflck * (5 * (m1 + 2) + (m2 + 2)) / (n + 2) / p1 / p2.
+ */
+static bool
+vlv_find_best_dpll(const intel_limit_t *limit,
+		   struct intel_crtc_state *crtc_state,
+		   int target, int refclk, intel_clock_t *match_clock,
+		   intel_clock_t *best_clock)
+{
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
+	struct drm_device *dev = crtc->base.dev;
+	intel_clock_t clock;
+	unsigned int bestppm = 1000000;
+	/* min update 19.2 MHz */
+	int max_n = min(limit->n.max, refclk / 19200);
+	bool found = false;
+
+	target *= 5; /* fast clock */
+
+	memset(best_clock, 0, sizeof(*best_clock));
+
+	/* based on hardware requirement, prefer smaller n to precision */
+	for (clock.n = limit->n.min; clock.n <= max_n; clock.n++) {
+		for (clock.p1 = limit->p1.max; clock.p1 >= limit->p1.min; clock.p1--) {
+			for (clock.p2 = limit->p2.p2_fast; clock.p2 >= limit->p2.p2_slow;
+			     clock.p2 -= clock.p2 > 10 ? 2 : 1) {
+				clock.p = clock.p1 * clock.p2;
+				/* based on hardware requirement, prefer bigger m1,m2 values */
+				for (clock.m1 = limit->m1.min; clock.m1 <= limit->m1.max; clock.m1++) {
+					unsigned int ppm;
+
+					clock.m2 = DIV_ROUND_CLOSEST(target * clock.p * clock.n,
+								     refclk * clock.m1);
+
+					vlv_calc_dpll_params(refclk, &clock);
+
+					if (!intel_PLL_is_valid(dev, limit,
+								&clock))
+						continue;
+
+					if (!vlv_PLL_is_optimal(dev, target,
+								&clock,
+								best_clock,
+								bestppm, &ppm))
+						continue;
+
+					*best_clock = clock;
+					bestppm = ppm;
+					found = true;
+				}
+			}
+		}
+	}
+
+	return found;
+}
+
+/*
+ * Returns a set of divisors for the desired target clock with the given
+ * refclk, or FALSE.  The returned values represent the clock equation:
+ * reflck * (5 * (m1 + 2) + (m2 + 2)) / (n + 2) / p1 / p2.
+ */
+static bool
+chv_find_best_dpll(const intel_limit_t *limit,
+		   struct intel_crtc_state *crtc_state,
+		   int target, int refclk, intel_clock_t *match_clock,
+		   intel_clock_t *best_clock)
+{
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
+	struct drm_device *dev = crtc->base.dev;
+	unsigned int best_error_ppm;
+	intel_clock_t clock;
+	uint64_t m2;
+	int found = false;
+
+	memset(best_clock, 0, sizeof(*best_clock));
+	best_error_ppm = 1000000;
+
+	/*
+	 * Based on hardware doc, the n always set to 1, and m1 always
+	 * set to 2.  If requires to support 200Mhz refclk, we need to
+	 * revisit this because n may not 1 anymore.
+	 */
+	clock.n = 1, clock.m1 = 2;
+	target *= 5;	/* fast clock */
+
+	for (clock.p1 = limit->p1.max; clock.p1 >= limit->p1.min; clock.p1--) {
+		for (clock.p2 = limit->p2.p2_fast;
+				clock.p2 >= limit->p2.p2_slow;
+				clock.p2 -= clock.p2 > 10 ? 2 : 1) {
+			unsigned int error_ppm;
+
+			clock.p = clock.p1 * clock.p2;
+
+			m2 = DIV_ROUND_CLOSEST_ULL(((uint64_t)target * clock.p *
+					clock.n) << 22, refclk * clock.m1);
+
+			if (m2 > INT_MAX/clock.m1)
+				continue;
+
+			clock.m2 = m2;
+
+			chv_calc_dpll_params(refclk, &clock);
+
+			if (!intel_PLL_is_valid(dev, limit, &clock))
+				continue;
+
+			if (!vlv_PLL_is_optimal(dev, target, &clock, best_clock,
+						best_error_ppm, &error_ppm))
+				continue;
+
+			*best_clock = clock;
+			best_error_ppm = error_ppm;
+			found = true;
+		}
+	}
+
+	return found;
+}
+
+bool bxt_find_best_dpll(struct intel_crtc_state *crtc_state, int target_clock,
+			intel_clock_t *best_clock)
+{
+	int refclk = 100000;
+	const intel_limit_t *limit = &intel_limits_bxt;
+
+	return chv_find_best_dpll(limit, crtc_state,
+				  target_clock, refclk, NULL, best_clock);
+}
+
+bool intel_crtc_active(struct drm_crtc *crtc)
+{
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+
+	/* Be paranoid as we can arrive here with only partial
+	 * state retrieved from the hardware during setup.
+	 *
+	 * We can ditch the adjusted_mode.crtc_clock check as soon
+	 * as Haswell has gained clock readout/fastboot support.
+	 *
+	 * We can ditch the crtc->primary->fb check as soon as we can
+	 * properly reconstruct framebuffers.
+	 *
+	 * FIXME: The intel_crtc->active here should be switched to
+	 * crtc->state->active once we have proper CRTC states wired up
+	 * for atomic.
+	 */
+	return intel_crtc->active && crtc->primary->state->fb &&
+		intel_crtc->config->base.adjusted_mode.crtc_clock;
+}
+
+enum transcoder intel_pipe_to_cpu_transcoder(struct drm_i915_private *dev_priv,
+					     enum pipe pipe)
+{
+	struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe];
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+
+	return intel_crtc->config->cpu_transcoder;
+}
+
+static bool pipe_dsl_stopped(struct drm_device *dev, enum pipe pipe)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	i915_reg_t reg = PIPEDSL(pipe);
+	u32 line1, line2;
+	u32 line_mask;
+
+	if (IS_GEN2(dev))
+		line_mask = DSL_LINEMASK_GEN2;
+	else
+		line_mask = DSL_LINEMASK_GEN3;
+
+	line1 = I915_READ(reg) & line_mask;
+	msleep(5);
+	line2 = I915_READ(reg) & line_mask;
+
+	return line1 == line2;
+}
+
+/*
+ * intel_wait_for_pipe_off - wait for pipe to turn off
+ * @crtc: crtc whose pipe to wait for
+ *
+ * After disabling a pipe, we can't wait for vblank in the usual way,
+ * spinning on the vblank interrupt status bit, since we won't actually
+ * see an interrupt when the pipe is disabled.
+ *
+ * On Gen4 and above:
+ *   wait for the pipe register state bit to turn off
+ *
+ * Otherwise:
+ *   wait for the display line value to settle (it usually
+ *   ends up stopping at the start of the next frame).
+ *
+ */
+static void intel_wait_for_pipe_off(struct intel_crtc *crtc)
+{
+	struct drm_device *dev = crtc->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	enum transcoder cpu_transcoder = crtc->config->cpu_transcoder;
+	enum pipe pipe = crtc->pipe;
+
+	if (INTEL_INFO(dev)->gen >= 4) {
+		i915_reg_t reg = PIPECONF(cpu_transcoder);
+
+		/* Wait for the Pipe State to go off */
+		if (wait_for((I915_READ(reg) & I965_PIPECONF_ACTIVE) == 0,
+			     100))
+			WARN(1, "pipe_off wait timed out\n");
+	} else {
+		/* Wait for the display line to settle */
+		if (wait_for(pipe_dsl_stopped(dev, pipe), 100))
+			WARN(1, "pipe_off wait timed out\n");
+	}
+}
+
+/* Only for pre-ILK configs */
+void assert_pll(struct drm_i915_private *dev_priv,
+		enum pipe pipe, bool state)
+{
+	u32 val;
+	bool cur_state;
+
+	val = I915_READ(DPLL(pipe));
+	cur_state = !!(val & DPLL_VCO_ENABLE);
+	I915_STATE_WARN(cur_state != state,
+	     "PLL state assertion failure (expected %s, current %s)\n",
+			onoff(state), onoff(cur_state));
+}
+
+/* XXX: the dsi pll is shared between MIPI DSI ports */
+void assert_dsi_pll(struct drm_i915_private *dev_priv, bool state)
+{
+	u32 val;
+	bool cur_state;
+
+	mutex_lock(&dev_priv->sb_lock);
+	val = vlv_cck_read(dev_priv, CCK_REG_DSI_PLL_CONTROL);
+	mutex_unlock(&dev_priv->sb_lock);
+
+	cur_state = val & DSI_PLL_VCO_EN;
+	I915_STATE_WARN(cur_state != state,
+	     "DSI PLL state assertion failure (expected %s, current %s)\n",
+			onoff(state), onoff(cur_state));
+}
+
+static void assert_fdi_tx(struct drm_i915_private *dev_priv,
+			  enum pipe pipe, bool state)
+{
+	bool cur_state;
+	enum transcoder cpu_transcoder = intel_pipe_to_cpu_transcoder(dev_priv,
+								      pipe);
+
+	if (HAS_DDI(dev_priv)) {
+		/* DDI does not have a specific FDI_TX register */
+		u32 val = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder));
+		cur_state = !!(val & TRANS_DDI_FUNC_ENABLE);
+	} else {
+		u32 val = I915_READ(FDI_TX_CTL(pipe));
+		cur_state = !!(val & FDI_TX_ENABLE);
+	}
+	I915_STATE_WARN(cur_state != state,
+	     "FDI TX state assertion failure (expected %s, current %s)\n",
+			onoff(state), onoff(cur_state));
+}
+#define assert_fdi_tx_enabled(d, p) assert_fdi_tx(d, p, true)
+#define assert_fdi_tx_disabled(d, p) assert_fdi_tx(d, p, false)
+
+static void assert_fdi_rx(struct drm_i915_private *dev_priv,
+			  enum pipe pipe, bool state)
+{
+	u32 val;
+	bool cur_state;
+
+	val = I915_READ(FDI_RX_CTL(pipe));
+	cur_state = !!(val & FDI_RX_ENABLE);
+	I915_STATE_WARN(cur_state != state,
+	     "FDI RX state assertion failure (expected %s, current %s)\n",
+			onoff(state), onoff(cur_state));
+}
+#define assert_fdi_rx_enabled(d, p) assert_fdi_rx(d, p, true)
+#define assert_fdi_rx_disabled(d, p) assert_fdi_rx(d, p, false)
+
+static void assert_fdi_tx_pll_enabled(struct drm_i915_private *dev_priv,
+				      enum pipe pipe)
+{
+	u32 val;
+
+	/* ILK FDI PLL is always enabled */
+	if (INTEL_INFO(dev_priv)->gen == 5)
+		return;
+
+	/* On Haswell, DDI ports are responsible for the FDI PLL setup */
+	if (HAS_DDI(dev_priv))
+		return;
+
+	val = I915_READ(FDI_TX_CTL(pipe));
+	I915_STATE_WARN(!(val & FDI_TX_PLL_ENABLE), "FDI TX PLL assertion failure, should be active but is disabled\n");
+}
+
+void assert_fdi_rx_pll(struct drm_i915_private *dev_priv,
+		       enum pipe pipe, bool state)
+{
+	u32 val;
+	bool cur_state;
+
+	val = I915_READ(FDI_RX_CTL(pipe));
+	cur_state = !!(val & FDI_RX_PLL_ENABLE);
+	I915_STATE_WARN(cur_state != state,
+	     "FDI RX PLL assertion failure (expected %s, current %s)\n",
+			onoff(state), onoff(cur_state));
+}
+
+void assert_panel_unlocked(struct drm_i915_private *dev_priv,
+			   enum pipe pipe)
+{
+	struct drm_device *dev = dev_priv->dev;
+	i915_reg_t pp_reg;
+	u32 val;
+	enum pipe panel_pipe = PIPE_A;
+	bool locked = true;
+
+	if (WARN_ON(HAS_DDI(dev)))
+		return;
+
+	if (HAS_PCH_SPLIT(dev)) {
+		u32 port_sel;
+
+		pp_reg = PCH_PP_CONTROL;
+		port_sel = I915_READ(PCH_PP_ON_DELAYS) & PANEL_PORT_SELECT_MASK;
+
+		if (port_sel == PANEL_PORT_SELECT_LVDS &&
+		    I915_READ(PCH_LVDS) & LVDS_PIPEB_SELECT)
+			panel_pipe = PIPE_B;
+		/* XXX: else fix for eDP */
+	} else if (IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev)) {
+		/* presumably write lock depends on pipe, not port select */
+		pp_reg = VLV_PIPE_PP_CONTROL(pipe);
+		panel_pipe = pipe;
+	} else {
+		pp_reg = PP_CONTROL;
+		if (I915_READ(LVDS) & LVDS_PIPEB_SELECT)
+			panel_pipe = PIPE_B;
+	}
+
+	val = I915_READ(pp_reg);
+	if (!(val & PANEL_POWER_ON) ||
+	    ((val & PANEL_UNLOCK_MASK) == PANEL_UNLOCK_REGS))
+		locked = false;
+
+	I915_STATE_WARN(panel_pipe == pipe && locked,
+	     "panel assertion failure, pipe %c regs locked\n",
+	     pipe_name(pipe));
+}
+
+static void assert_cursor(struct drm_i915_private *dev_priv,
+			  enum pipe pipe, bool state)
+{
+	struct drm_device *dev = dev_priv->dev;
+	bool cur_state;
+
+	if (IS_845G(dev) || IS_I865G(dev))
+		cur_state = I915_READ(CURCNTR(PIPE_A)) & CURSOR_ENABLE;
+	else
+		cur_state = I915_READ(CURCNTR(pipe)) & CURSOR_MODE;
+
+	I915_STATE_WARN(cur_state != state,
+	     "cursor on pipe %c assertion failure (expected %s, current %s)\n",
+			pipe_name(pipe), onoff(state), onoff(cur_state));
+}
+#define assert_cursor_enabled(d, p) assert_cursor(d, p, true)
+#define assert_cursor_disabled(d, p) assert_cursor(d, p, false)
+
+void assert_pipe(struct drm_i915_private *dev_priv,
+		 enum pipe pipe, bool state)
+{
+	bool cur_state;
+	enum transcoder cpu_transcoder = intel_pipe_to_cpu_transcoder(dev_priv,
+								      pipe);
+	enum intel_display_power_domain power_domain;
+
+	/* if we need the pipe quirk it must be always on */
+	if ((pipe == PIPE_A && dev_priv->quirks & QUIRK_PIPEA_FORCE) ||
+	    (pipe == PIPE_B && dev_priv->quirks & QUIRK_PIPEB_FORCE))
+		state = true;
+
+	power_domain = POWER_DOMAIN_TRANSCODER(cpu_transcoder);
+	if (intel_display_power_get_if_enabled(dev_priv, power_domain)) {
+		u32 val = I915_READ(PIPECONF(cpu_transcoder));
+		cur_state = !!(val & PIPECONF_ENABLE);
+
+		intel_display_power_put(dev_priv, power_domain);
+	} else {
+		cur_state = false;
+	}
+
+	I915_STATE_WARN(cur_state != state,
+	     "pipe %c assertion failure (expected %s, current %s)\n",
+			pipe_name(pipe), onoff(state), onoff(cur_state));
+}
+
+static void assert_plane(struct drm_i915_private *dev_priv,
+			 enum plane plane, bool state)
+{
+	u32 val;
+	bool cur_state;
+
+	val = I915_READ(DSPCNTR(plane));
+	cur_state = !!(val & DISPLAY_PLANE_ENABLE);
+	I915_STATE_WARN(cur_state != state,
+	     "plane %c assertion failure (expected %s, current %s)\n",
+			plane_name(plane), onoff(state), onoff(cur_state));
+}
+
+#define assert_plane_enabled(d, p) assert_plane(d, p, true)
+#define assert_plane_disabled(d, p) assert_plane(d, p, false)
+
+static void assert_planes_disabled(struct drm_i915_private *dev_priv,
+				   enum pipe pipe)
+{
+	struct drm_device *dev = dev_priv->dev;
+	int i;
+
+	/* Primary planes are fixed to pipes on gen4+ */
+	if (INTEL_INFO(dev)->gen >= 4) {
+		u32 val = I915_READ(DSPCNTR(pipe));
+		I915_STATE_WARN(val & DISPLAY_PLANE_ENABLE,
+		     "plane %c assertion failure, should be disabled but not\n",
+		     plane_name(pipe));
+		return;
+	}
+
+	/* Need to check both planes against the pipe */
+	for_each_pipe(dev_priv, i) {
+		u32 val = I915_READ(DSPCNTR(i));
+		enum pipe cur_pipe = (val & DISPPLANE_SEL_PIPE_MASK) >>
+			DISPPLANE_SEL_PIPE_SHIFT;
+		I915_STATE_WARN((val & DISPLAY_PLANE_ENABLE) && pipe == cur_pipe,
+		     "plane %c assertion failure, should be off on pipe %c but is still active\n",
+		     plane_name(i), pipe_name(pipe));
+	}
+}
+
+static void assert_sprites_disabled(struct drm_i915_private *dev_priv,
+				    enum pipe pipe)
+{
+	struct drm_device *dev = dev_priv->dev;
+	int sprite;
+
+	if (INTEL_INFO(dev)->gen >= 9) {
+		for_each_sprite(dev_priv, pipe, sprite) {
+			u32 val = I915_READ(PLANE_CTL(pipe, sprite));
+			I915_STATE_WARN(val & PLANE_CTL_ENABLE,
+			     "plane %d assertion failure, should be off on pipe %c but is still active\n",
+			     sprite, pipe_name(pipe));
+		}
+	} else if (IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev)) {
+		for_each_sprite(dev_priv, pipe, sprite) {
+			u32 val = I915_READ(SPCNTR(pipe, sprite));
+			I915_STATE_WARN(val & SP_ENABLE,
+			     "sprite %c assertion failure, should be off on pipe %c but is still active\n",
+			     sprite_name(pipe, sprite), pipe_name(pipe));
+		}
+	} else if (INTEL_INFO(dev)->gen >= 7) {
+		u32 val = I915_READ(SPRCTL(pipe));
+		I915_STATE_WARN(val & SPRITE_ENABLE,
+		     "sprite %c assertion failure, should be off on pipe %c but is still active\n",
+		     plane_name(pipe), pipe_name(pipe));
+	} else if (INTEL_INFO(dev)->gen >= 5) {
+		u32 val = I915_READ(DVSCNTR(pipe));
+		I915_STATE_WARN(val & DVS_ENABLE,
+		     "sprite %c assertion failure, should be off on pipe %c but is still active\n",
+		     plane_name(pipe), pipe_name(pipe));
+	}
+}
+
+static void assert_vblank_disabled(struct drm_crtc *crtc)
+{
+	if (I915_STATE_WARN_ON(drm_crtc_vblank_get(crtc) == 0))
+		drm_crtc_vblank_put(crtc);
+}
+
+void assert_pch_transcoder_disabled(struct drm_i915_private *dev_priv,
+				    enum pipe pipe)
+{
+	u32 val;
+	bool enabled;
+
+	val = I915_READ(PCH_TRANSCONF(pipe));
+	enabled = !!(val & TRANS_ENABLE);
+	I915_STATE_WARN(enabled,
+	     "transcoder assertion failed, should be off on pipe %c but is still active\n",
+	     pipe_name(pipe));
+}
+
+static bool dp_pipe_enabled(struct drm_i915_private *dev_priv,
+			    enum pipe pipe, u32 port_sel, u32 val)
+{
+	if ((val & DP_PORT_EN) == 0)
+		return false;
+
+	if (HAS_PCH_CPT(dev_priv)) {
+		u32 trans_dp_ctl = I915_READ(TRANS_DP_CTL(pipe));
+		if ((trans_dp_ctl & TRANS_DP_PORT_SEL_MASK) != port_sel)
+			return false;
+	} else if (IS_CHERRYVIEW(dev_priv)) {
+		if ((val & DP_PIPE_MASK_CHV) != DP_PIPE_SELECT_CHV(pipe))
+			return false;
+	} else {
+		if ((val & DP_PIPE_MASK) != (pipe << 30))
+			return false;
+	}
+	return true;
+}
+
+static bool hdmi_pipe_enabled(struct drm_i915_private *dev_priv,
+			      enum pipe pipe, u32 val)
+{
+	if ((val & SDVO_ENABLE) == 0)
+		return false;
+
+	if (HAS_PCH_CPT(dev_priv)) {
+		if ((val & SDVO_PIPE_SEL_MASK_CPT) != SDVO_PIPE_SEL_CPT(pipe))
+			return false;
+	} else if (IS_CHERRYVIEW(dev_priv)) {
+		if ((val & SDVO_PIPE_SEL_MASK_CHV) != SDVO_PIPE_SEL_CHV(pipe))
+			return false;
+	} else {
+		if ((val & SDVO_PIPE_SEL_MASK) != SDVO_PIPE_SEL(pipe))
+			return false;
+	}
+	return true;
+}
+
+static bool lvds_pipe_enabled(struct drm_i915_private *dev_priv,
+			      enum pipe pipe, u32 val)
+{
+	if ((val & LVDS_PORT_EN) == 0)
+		return false;
+
+	if (HAS_PCH_CPT(dev_priv)) {
+		if ((val & PORT_TRANS_SEL_MASK) != PORT_TRANS_SEL_CPT(pipe))
+			return false;
+	} else {
+		if ((val & LVDS_PIPE_MASK) != LVDS_PIPE(pipe))
+			return false;
+	}
+	return true;
+}
+
+static bool adpa_pipe_enabled(struct drm_i915_private *dev_priv,
+			      enum pipe pipe, u32 val)
+{
+	if ((val & ADPA_DAC_ENABLE) == 0)
+		return false;
+	if (HAS_PCH_CPT(dev_priv)) {
+		if ((val & PORT_TRANS_SEL_MASK) != PORT_TRANS_SEL_CPT(pipe))
+			return false;
+	} else {
+		if ((val & ADPA_PIPE_SELECT_MASK) != ADPA_PIPE_SELECT(pipe))
+			return false;
+	}
+	return true;
+}
+
+static void assert_pch_dp_disabled(struct drm_i915_private *dev_priv,
+				   enum pipe pipe, i915_reg_t reg,
+				   u32 port_sel)
+{
+	u32 val = I915_READ(reg);
+	I915_STATE_WARN(dp_pipe_enabled(dev_priv, pipe, port_sel, val),
+	     "PCH DP (0x%08x) enabled on transcoder %c, should be disabled\n",
+	     i915_mmio_reg_offset(reg), pipe_name(pipe));
+
+	I915_STATE_WARN(HAS_PCH_IBX(dev_priv) && (val & DP_PORT_EN) == 0
+	     && (val & DP_PIPEB_SELECT),
+	     "IBX PCH dp port still using transcoder B\n");
+}
+
+static void assert_pch_hdmi_disabled(struct drm_i915_private *dev_priv,
+				     enum pipe pipe, i915_reg_t reg)
+{
+	u32 val = I915_READ(reg);
+	I915_STATE_WARN(hdmi_pipe_enabled(dev_priv, pipe, val),
+	     "PCH HDMI (0x%08x) enabled on transcoder %c, should be disabled\n",
+	     i915_mmio_reg_offset(reg), pipe_name(pipe));
+
+	I915_STATE_WARN(HAS_PCH_IBX(dev_priv) && (val & SDVO_ENABLE) == 0
+	     && (val & SDVO_PIPE_B_SELECT),
+	     "IBX PCH hdmi port still using transcoder B\n");
+}
+
+static void assert_pch_ports_disabled(struct drm_i915_private *dev_priv,
+				      enum pipe pipe)
+{
+	u32 val;
+
+	assert_pch_dp_disabled(dev_priv, pipe, PCH_DP_B, TRANS_DP_PORT_SEL_B);
+	assert_pch_dp_disabled(dev_priv, pipe, PCH_DP_C, TRANS_DP_PORT_SEL_C);
+	assert_pch_dp_disabled(dev_priv, pipe, PCH_DP_D, TRANS_DP_PORT_SEL_D);
+
+	val = I915_READ(PCH_ADPA);
+	I915_STATE_WARN(adpa_pipe_enabled(dev_priv, pipe, val),
+	     "PCH VGA enabled on transcoder %c, should be disabled\n",
+	     pipe_name(pipe));
+
+	val = I915_READ(PCH_LVDS);
+	I915_STATE_WARN(lvds_pipe_enabled(dev_priv, pipe, val),
+	     "PCH LVDS enabled on transcoder %c, should be disabled\n",
+	     pipe_name(pipe));
+
+	assert_pch_hdmi_disabled(dev_priv, pipe, PCH_HDMIB);
+	assert_pch_hdmi_disabled(dev_priv, pipe, PCH_HDMIC);
+	assert_pch_hdmi_disabled(dev_priv, pipe, PCH_HDMID);
+}
+
+static void _vlv_enable_pll(struct intel_crtc *crtc,
+			    const struct intel_crtc_state *pipe_config)
+{
+	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
+	enum pipe pipe = crtc->pipe;
+
+	I915_WRITE(DPLL(pipe), pipe_config->dpll_hw_state.dpll);
+	POSTING_READ(DPLL(pipe));
+	udelay(150);
+
+	if (wait_for(((I915_READ(DPLL(pipe)) & DPLL_LOCK_VLV) == DPLL_LOCK_VLV), 1))
+		DRM_ERROR("DPLL %d failed to lock\n", pipe);
+}
+
+static void vlv_enable_pll(struct intel_crtc *crtc,
+			   const struct intel_crtc_state *pipe_config)
+{
+	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
+	enum pipe pipe = crtc->pipe;
+
+	assert_pipe_disabled(dev_priv, pipe);
+
+	/* PLL is protected by panel, make sure we can write it */
+	assert_panel_unlocked(dev_priv, pipe);
+
+	if (pipe_config->dpll_hw_state.dpll & DPLL_VCO_ENABLE)
+		_vlv_enable_pll(crtc, pipe_config);
+
+	I915_WRITE(DPLL_MD(pipe), pipe_config->dpll_hw_state.dpll_md);
+	POSTING_READ(DPLL_MD(pipe));
+}
+
+
+static void _chv_enable_pll(struct intel_crtc *crtc,
+			    const struct intel_crtc_state *pipe_config)
+{
+	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
+	enum pipe pipe = crtc->pipe;
+	enum dpio_channel port = vlv_pipe_to_channel(pipe);
+	u32 tmp;
+
+	mutex_lock(&dev_priv->sb_lock);
+
+	/* Enable back the 10bit clock to display controller */
+	tmp = vlv_dpio_read(dev_priv, pipe, CHV_CMN_DW14(port));
+	tmp |= DPIO_DCLKP_EN;
+	vlv_dpio_write(dev_priv, pipe, CHV_CMN_DW14(port), tmp);
+
+	mutex_unlock(&dev_priv->sb_lock);
+
+	/*
+	 * Need to wait > 100ns between dclkp clock enable bit and PLL enable.
+	 */
+	udelay(1);
+
+	/* Enable PLL */
+	I915_WRITE(DPLL(pipe), pipe_config->dpll_hw_state.dpll);
+
+	/* Check PLL is locked */
+	if (wait_for(((I915_READ(DPLL(pipe)) & DPLL_LOCK_VLV) == DPLL_LOCK_VLV), 1))
+		DRM_ERROR("PLL %d failed to lock\n", pipe);
+}
+
+static void chv_enable_pll(struct intel_crtc *crtc,
+			   const struct intel_crtc_state *pipe_config)
+{
+	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
+	enum pipe pipe = crtc->pipe;
+
+	assert_pipe_disabled(dev_priv, pipe);
+
+	/* PLL is protected by panel, make sure we can write it */
+	assert_panel_unlocked(dev_priv, pipe);
+
+	if (pipe_config->dpll_hw_state.dpll & DPLL_VCO_ENABLE)
+		_chv_enable_pll(crtc, pipe_config);
+
+	if (pipe != PIPE_A) {
+		/*
+		 * WaPixelRepeatModeFixForC0:chv
+		 *
+		 * DPLLCMD is AWOL. Use chicken bits to propagate
+		 * the value from DPLLBMD to either pipe B or C.
+		 */
+		I915_WRITE(CBR4_VLV, pipe == PIPE_B ? CBR_DPLLBMD_PIPE_B : CBR_DPLLBMD_PIPE_C);
+		I915_WRITE(DPLL_MD(PIPE_B), pipe_config->dpll_hw_state.dpll_md);
+		I915_WRITE(CBR4_VLV, 0);
+		dev_priv->chv_dpll_md[pipe] = pipe_config->dpll_hw_state.dpll_md;
+
+		/*
+		 * DPLLB VGA mode also seems to cause problems.
+		 * We should always have it disabled.
+		 */
+		WARN_ON((I915_READ(DPLL(PIPE_B)) & DPLL_VGA_MODE_DIS) == 0);
+	} else {
+		I915_WRITE(DPLL_MD(pipe), pipe_config->dpll_hw_state.dpll_md);
+		POSTING_READ(DPLL_MD(pipe));
+	}
+}
+
+static int intel_num_dvo_pipes(struct drm_device *dev)
+{
+	struct intel_crtc *crtc;
+	int count = 0;
+
+	for_each_intel_crtc(dev, crtc)
+		count += crtc->base.state->active &&
+			intel_pipe_has_type(crtc, INTEL_OUTPUT_DVO);
+
+	return count;
+}
+
+static void i9xx_enable_pll(struct intel_crtc *crtc)
+{
+	struct drm_device *dev = crtc->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	i915_reg_t reg = DPLL(crtc->pipe);
+	u32 dpll = crtc->config->dpll_hw_state.dpll;
+
+	assert_pipe_disabled(dev_priv, crtc->pipe);
+
+	/* PLL is protected by panel, make sure we can write it */
+	if (IS_MOBILE(dev) && !IS_I830(dev))
+		assert_panel_unlocked(dev_priv, crtc->pipe);
+
+	/* Enable DVO 2x clock on both PLLs if necessary */
+	if (IS_I830(dev) && intel_num_dvo_pipes(dev) > 0) {
+		/*
+		 * It appears to be important that we don't enable this
+		 * for the current pipe before otherwise configuring the
+		 * PLL. No idea how this should be handled if multiple
+		 * DVO outputs are enabled simultaneosly.
+		 */
+		dpll |= DPLL_DVO_2X_MODE;
+		I915_WRITE(DPLL(!crtc->pipe),
+			   I915_READ(DPLL(!crtc->pipe)) | DPLL_DVO_2X_MODE);
+	}
+
+	/*
+	 * Apparently we need to have VGA mode enabled prior to changing
+	 * the P1/P2 dividers. Otherwise the DPLL will keep using the old
+	 * dividers, even though the register value does change.
+	 */
+	I915_WRITE(reg, 0);
+
+	I915_WRITE(reg, dpll);
+
+	/* Wait for the clocks to stabilize. */
+	POSTING_READ(reg);
+	udelay(150);
+
+	if (INTEL_INFO(dev)->gen >= 4) {
+		I915_WRITE(DPLL_MD(crtc->pipe),
+			   crtc->config->dpll_hw_state.dpll_md);
+	} else {
+		/* The pixel multiplier can only be updated once the
+		 * DPLL is enabled and the clocks are stable.
+		 *
+		 * So write it again.
+		 */
+		I915_WRITE(reg, dpll);
+	}
+
+	/* We do this three times for luck */
+	I915_WRITE(reg, dpll);
+	POSTING_READ(reg);
+	udelay(150); /* wait for warmup */
+	I915_WRITE(reg, dpll);
+	POSTING_READ(reg);
+	udelay(150); /* wait for warmup */
+	I915_WRITE(reg, dpll);
+	POSTING_READ(reg);
+	udelay(150); /* wait for warmup */
+}
+
+/**
+ * i9xx_disable_pll - disable a PLL
+ * @dev_priv: i915 private structure
+ * @pipe: pipe PLL to disable
+ *
+ * Disable the PLL for @pipe, making sure the pipe is off first.
+ *
+ * Note!  This is for pre-ILK only.
+ */
+static void i9xx_disable_pll(struct intel_crtc *crtc)
+{
+	struct drm_device *dev = crtc->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	enum pipe pipe = crtc->pipe;
+
+	/* Disable DVO 2x clock on both PLLs if necessary */
+	if (IS_I830(dev) &&
+	    intel_pipe_has_type(crtc, INTEL_OUTPUT_DVO) &&
+	    !intel_num_dvo_pipes(dev)) {
+		I915_WRITE(DPLL(PIPE_B),
+			   I915_READ(DPLL(PIPE_B)) & ~DPLL_DVO_2X_MODE);
+		I915_WRITE(DPLL(PIPE_A),
+			   I915_READ(DPLL(PIPE_A)) & ~DPLL_DVO_2X_MODE);
+	}
+
+	/* Don't disable pipe or pipe PLLs if needed */
+	if ((pipe == PIPE_A && dev_priv->quirks & QUIRK_PIPEA_FORCE) ||
+	    (pipe == PIPE_B && dev_priv->quirks & QUIRK_PIPEB_FORCE))
+		return;
+
+	/* Make sure the pipe isn't still relying on us */
+	assert_pipe_disabled(dev_priv, pipe);
+
+	I915_WRITE(DPLL(pipe), DPLL_VGA_MODE_DIS);
+	POSTING_READ(DPLL(pipe));
+}
+
+static void vlv_disable_pll(struct drm_i915_private *dev_priv, enum pipe pipe)
+{
+	u32 val;
+
+	/* Make sure the pipe isn't still relying on us */
+	assert_pipe_disabled(dev_priv, pipe);
+
+	val = DPLL_INTEGRATED_REF_CLK_VLV |
+		DPLL_REF_CLK_ENABLE_VLV | DPLL_VGA_MODE_DIS;
+	if (pipe != PIPE_A)
+		val |= DPLL_INTEGRATED_CRI_CLK_VLV;
+
+	I915_WRITE(DPLL(pipe), val);
+	POSTING_READ(DPLL(pipe));
+}
+
+static void chv_disable_pll(struct drm_i915_private *dev_priv, enum pipe pipe)
+{
+	enum dpio_channel port = vlv_pipe_to_channel(pipe);
+	u32 val;
+
+	/* Make sure the pipe isn't still relying on us */
+	assert_pipe_disabled(dev_priv, pipe);
+
+	val = DPLL_SSC_REF_CLK_CHV |
+		DPLL_REF_CLK_ENABLE_VLV | DPLL_VGA_MODE_DIS;
+	if (pipe != PIPE_A)
+		val |= DPLL_INTEGRATED_CRI_CLK_VLV;
+
+	I915_WRITE(DPLL(pipe), val);
+	POSTING_READ(DPLL(pipe));
+
+	mutex_lock(&dev_priv->sb_lock);
+
+	/* Disable 10bit clock to display controller */
+	val = vlv_dpio_read(dev_priv, pipe, CHV_CMN_DW14(port));
+	val &= ~DPIO_DCLKP_EN;
+	vlv_dpio_write(dev_priv, pipe, CHV_CMN_DW14(port), val);
+
+	mutex_unlock(&dev_priv->sb_lock);
+}
+
+void vlv_wait_port_ready(struct drm_i915_private *dev_priv,
+			 struct intel_digital_port *dport,
+			 unsigned int expected_mask)
+{
+	u32 port_mask;
+	i915_reg_t dpll_reg;
+
+	switch (dport->port) {
+	case PORT_B:
+		port_mask = DPLL_PORTB_READY_MASK;
+		dpll_reg = DPLL(0);
+		break;
+	case PORT_C:
+		port_mask = DPLL_PORTC_READY_MASK;
+		dpll_reg = DPLL(0);
+		expected_mask <<= 4;
+		break;
+	case PORT_D:
+		port_mask = DPLL_PORTD_READY_MASK;
+		dpll_reg = DPIO_PHY_STATUS;
+		break;
+	default:
+		BUG();
+	}
+
+	if (wait_for((I915_READ(dpll_reg) & port_mask) == expected_mask, 1000))
+		WARN(1, "timed out waiting for port %c ready: got 0x%x, expected 0x%x\n",
+		     port_name(dport->port), I915_READ(dpll_reg) & port_mask, expected_mask);
+}
+
+static void ironlake_enable_pch_transcoder(struct drm_i915_private *dev_priv,
+					   enum pipe pipe)
+{
+	struct drm_device *dev = dev_priv->dev;
+	struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe];
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	i915_reg_t reg;
+	uint32_t val, pipeconf_val;
+
+	/* Make sure PCH DPLL is enabled */
+	assert_shared_dpll_enabled(dev_priv, intel_crtc->config->shared_dpll);
+
+	/* FDI must be feeding us bits for PCH ports */
+	assert_fdi_tx_enabled(dev_priv, pipe);
+	assert_fdi_rx_enabled(dev_priv, pipe);
+
+	if (HAS_PCH_CPT(dev)) {
+		/* Workaround: Set the timing override bit before enabling the
+		 * pch transcoder. */
+		reg = TRANS_CHICKEN2(pipe);
+		val = I915_READ(reg);
+		val |= TRANS_CHICKEN2_TIMING_OVERRIDE;
+		I915_WRITE(reg, val);
+	}
+
+	reg = PCH_TRANSCONF(pipe);
+	val = I915_READ(reg);
+	pipeconf_val = I915_READ(PIPECONF(pipe));
+
+	if (HAS_PCH_IBX(dev_priv)) {
+		/*
+		 * Make the BPC in transcoder be consistent with
+		 * that in pipeconf reg. For HDMI we must use 8bpc
+		 * here for both 8bpc and 12bpc.
+		 */
+		val &= ~PIPECONF_BPC_MASK;
+		if (intel_pipe_has_type(intel_crtc, INTEL_OUTPUT_HDMI))
+			val |= PIPECONF_8BPC;
+		else
+			val |= pipeconf_val & PIPECONF_BPC_MASK;
+	}
+
+	val &= ~TRANS_INTERLACE_MASK;
+	if ((pipeconf_val & PIPECONF_INTERLACE_MASK) == PIPECONF_INTERLACED_ILK)
+		if (HAS_PCH_IBX(dev_priv) &&
+		    intel_pipe_has_type(intel_crtc, INTEL_OUTPUT_SDVO))
+			val |= TRANS_LEGACY_INTERLACED_ILK;
+		else
+			val |= TRANS_INTERLACED;
+	else
+		val |= TRANS_PROGRESSIVE;
+
+	I915_WRITE(reg, val | TRANS_ENABLE);
+	if (wait_for(I915_READ(reg) & TRANS_STATE_ENABLE, 100))
+		DRM_ERROR("failed to enable transcoder %c\n", pipe_name(pipe));
+}
+
+static void lpt_enable_pch_transcoder(struct drm_i915_private *dev_priv,
+				      enum transcoder cpu_transcoder)
+{
+	u32 val, pipeconf_val;
+
+	/* FDI must be feeding us bits for PCH ports */
+	assert_fdi_tx_enabled(dev_priv, (enum pipe) cpu_transcoder);
+	assert_fdi_rx_enabled(dev_priv, TRANSCODER_A);
+
+	/* Workaround: set timing override bit. */
+	val = I915_READ(TRANS_CHICKEN2(PIPE_A));
+	val |= TRANS_CHICKEN2_TIMING_OVERRIDE;
+	I915_WRITE(TRANS_CHICKEN2(PIPE_A), val);
+
+	val = TRANS_ENABLE;
+	pipeconf_val = I915_READ(PIPECONF(cpu_transcoder));
+
+	if ((pipeconf_val & PIPECONF_INTERLACE_MASK_HSW) ==
+	    PIPECONF_INTERLACED_ILK)
+		val |= TRANS_INTERLACED;
+	else
+		val |= TRANS_PROGRESSIVE;
+
+	I915_WRITE(LPT_TRANSCONF, val);
+	if (wait_for(I915_READ(LPT_TRANSCONF) & TRANS_STATE_ENABLE, 100))
+		DRM_ERROR("Failed to enable PCH transcoder\n");
+}
+
+static void ironlake_disable_pch_transcoder(struct drm_i915_private *dev_priv,
+					    enum pipe pipe)
+{
+	struct drm_device *dev = dev_priv->dev;
+	i915_reg_t reg;
+	uint32_t val;
+
+	/* FDI relies on the transcoder */
+	assert_fdi_tx_disabled(dev_priv, pipe);
+	assert_fdi_rx_disabled(dev_priv, pipe);
+
+	/* Ports must be off as well */
+	assert_pch_ports_disabled(dev_priv, pipe);
+
+	reg = PCH_TRANSCONF(pipe);
+	val = I915_READ(reg);
+	val &= ~TRANS_ENABLE;
+	I915_WRITE(reg, val);
+	/* wait for PCH transcoder off, transcoder state */
+	if (wait_for((I915_READ(reg) & TRANS_STATE_ENABLE) == 0, 50))
+		DRM_ERROR("failed to disable transcoder %c\n", pipe_name(pipe));
+
+	if (HAS_PCH_CPT(dev)) {
+		/* Workaround: Clear the timing override chicken bit again. */
+		reg = TRANS_CHICKEN2(pipe);
+		val = I915_READ(reg);
+		val &= ~TRANS_CHICKEN2_TIMING_OVERRIDE;
+		I915_WRITE(reg, val);
+	}
+}
+
+static void lpt_disable_pch_transcoder(struct drm_i915_private *dev_priv)
+{
+	u32 val;
+
+	val = I915_READ(LPT_TRANSCONF);
+	val &= ~TRANS_ENABLE;
+	I915_WRITE(LPT_TRANSCONF, val);
+	/* wait for PCH transcoder off, transcoder state */
+	if (wait_for((I915_READ(LPT_TRANSCONF) & TRANS_STATE_ENABLE) == 0, 50))
+		DRM_ERROR("Failed to disable PCH transcoder\n");
+
+	/* Workaround: clear timing override bit. */
+	val = I915_READ(TRANS_CHICKEN2(PIPE_A));
+	val &= ~TRANS_CHICKEN2_TIMING_OVERRIDE;
+	I915_WRITE(TRANS_CHICKEN2(PIPE_A), val);
+}
+
+/**
+ * intel_enable_pipe - enable a pipe, asserting requirements
+ * @crtc: crtc responsible for the pipe
+ *
+ * Enable @crtc's pipe, making sure that various hardware specific requirements
+ * are met, if applicable, e.g. PLL enabled, LVDS pairs enabled, etc.
+ */
+static void intel_enable_pipe(struct intel_crtc *crtc)
+{
+	struct drm_device *dev = crtc->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	enum pipe pipe = crtc->pipe;
+	enum transcoder cpu_transcoder = crtc->config->cpu_transcoder;
+	enum pipe pch_transcoder;
+	i915_reg_t reg;
+	u32 val;
+
+	DRM_DEBUG_KMS("enabling pipe %c\n", pipe_name(pipe));
+
+	assert_planes_disabled(dev_priv, pipe);
+	assert_cursor_disabled(dev_priv, pipe);
+	assert_sprites_disabled(dev_priv, pipe);
+
+	if (HAS_PCH_LPT(dev_priv))
+		pch_transcoder = TRANSCODER_A;
+	else
+		pch_transcoder = pipe;
+
+	/*
+	 * A pipe without a PLL won't actually be able to drive bits from
+	 * a plane.  On ILK+ the pipe PLLs are integrated, so we don't
+	 * need the check.
+	 */
+	if (HAS_GMCH_DISPLAY(dev_priv))
+		if (crtc->config->has_dsi_encoder)
+			assert_dsi_pll_enabled(dev_priv);
+		else
+			assert_pll_enabled(dev_priv, pipe);
+	else {
+		if (crtc->config->has_pch_encoder) {
+			/* if driving the PCH, we need FDI enabled */
+			assert_fdi_rx_pll_enabled(dev_priv, pch_transcoder);
+			assert_fdi_tx_pll_enabled(dev_priv,
+						  (enum pipe) cpu_transcoder);
+		}
+		/* FIXME: assert CPU port conditions for SNB+ */
+	}
+
+	reg = PIPECONF(cpu_transcoder);
+	val = I915_READ(reg);
+	if (val & PIPECONF_ENABLE) {
+		WARN_ON(!((pipe == PIPE_A && dev_priv->quirks & QUIRK_PIPEA_FORCE) ||
+			  (pipe == PIPE_B && dev_priv->quirks & QUIRK_PIPEB_FORCE)));
+		return;
+	}
+
+	I915_WRITE(reg, val | PIPECONF_ENABLE);
+	POSTING_READ(reg);
+
+	/*
+	 * Until the pipe starts DSL will read as 0, which would cause
+	 * an apparent vblank timestamp jump, which messes up also the
+	 * frame count when it's derived from the timestamps. So let's
+	 * wait for the pipe to start properly before we call
+	 * drm_crtc_vblank_on()
+	 */
+	if (dev->max_vblank_count == 0 &&
+	    wait_for(intel_get_crtc_scanline(crtc) != crtc->scanline_offset, 50))
+		DRM_ERROR("pipe %c didn't start\n", pipe_name(pipe));
+}
+
+/**
+ * intel_disable_pipe - disable a pipe, asserting requirements
+ * @crtc: crtc whose pipes is to be disabled
+ *
+ * Disable the pipe of @crtc, making sure that various hardware
+ * specific requirements are met, if applicable, e.g. plane
+ * disabled, panel fitter off, etc.
+ *
+ * Will wait until the pipe has shut down before returning.
+ */
+static void intel_disable_pipe(struct intel_crtc *crtc)
+{
+	struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
+	enum transcoder cpu_transcoder = crtc->config->cpu_transcoder;
+	enum pipe pipe = crtc->pipe;
+	i915_reg_t reg;
+	u32 val;
+
+	DRM_DEBUG_KMS("disabling pipe %c\n", pipe_name(pipe));
+
+	/*
+	 * Make sure planes won't keep trying to pump pixels to us,
+	 * or we might hang the display.
+	 */
+	assert_planes_disabled(dev_priv, pipe);
+	assert_cursor_disabled(dev_priv, pipe);
+	assert_sprites_disabled(dev_priv, pipe);
+
+	reg = PIPECONF(cpu_transcoder);
+	val = I915_READ(reg);
+	if ((val & PIPECONF_ENABLE) == 0)
+		return;
+
+	/*
+	 * Double wide has implications for planes
+	 * so best keep it disabled when not needed.
+	 */
+	if (crtc->config->double_wide)
+		val &= ~PIPECONF_DOUBLE_WIDE;
+
+	/* Don't disable pipe or pipe PLLs if needed */
+	if (!(pipe == PIPE_A && dev_priv->quirks & QUIRK_PIPEA_FORCE) &&
+	    !(pipe == PIPE_B && dev_priv->quirks & QUIRK_PIPEB_FORCE))
+		val &= ~PIPECONF_ENABLE;
+
+	I915_WRITE(reg, val);
+	if ((val & PIPECONF_ENABLE) == 0)
+		intel_wait_for_pipe_off(crtc);
+}
+
+static bool need_vtd_wa(struct drm_device *dev)
+{
+#ifdef CONFIG_INTEL_IOMMU
+	if (INTEL_INFO(dev)->gen >= 6 && intel_iommu_gfx_mapped)
+		return true;
+#endif
+	return false;
+}
+
+static unsigned int intel_tile_size(const struct drm_i915_private *dev_priv)
+{
+	return IS_GEN2(dev_priv) ? 2048 : 4096;
+}
+
+static unsigned int intel_tile_width_bytes(const struct drm_i915_private *dev_priv,
+					   uint64_t fb_modifier, unsigned int cpp)
+{
+	switch (fb_modifier) {
+	case DRM_FORMAT_MOD_NONE:
+		return cpp;
+	case I915_FORMAT_MOD_X_TILED:
+		if (IS_GEN2(dev_priv))
+			return 128;
+		else
+			return 512;
+	case I915_FORMAT_MOD_Y_TILED:
+		if (IS_GEN2(dev_priv) || HAS_128_BYTE_Y_TILING(dev_priv))
+			return 128;
+		else
+			return 512;
+	case I915_FORMAT_MOD_Yf_TILED:
+		switch (cpp) {
+		case 1:
+			return 64;
+		case 2:
+		case 4:
+			return 128;
+		case 8:
+		case 16:
+			return 256;
+		default:
+			MISSING_CASE(cpp);
+			return cpp;
+		}
+		break;
+	default:
+		MISSING_CASE(fb_modifier);
+		return cpp;
+	}
+}
+
+unsigned int intel_tile_height(const struct drm_i915_private *dev_priv,
+			       uint64_t fb_modifier, unsigned int cpp)
+{
+	if (fb_modifier == DRM_FORMAT_MOD_NONE)
+		return 1;
+	else
+		return intel_tile_size(dev_priv) /
+			intel_tile_width_bytes(dev_priv, fb_modifier, cpp);
+}
+
+/* Return the tile dimensions in pixel units */
+static void intel_tile_dims(const struct drm_i915_private *dev_priv,
+			    unsigned int *tile_width,
+			    unsigned int *tile_height,
+			    uint64_t fb_modifier,
+			    unsigned int cpp)
+{
+	unsigned int tile_width_bytes =
+		intel_tile_width_bytes(dev_priv, fb_modifier, cpp);
+
+	*tile_width = tile_width_bytes / cpp;
+	*tile_height = intel_tile_size(dev_priv) / tile_width_bytes;
+}
+
+unsigned int
+intel_fb_align_height(struct drm_device *dev, unsigned int height,
+		      uint32_t pixel_format, uint64_t fb_modifier)
+{
+	unsigned int cpp = drm_format_plane_cpp(pixel_format, 0);
+	unsigned int tile_height = intel_tile_height(to_i915(dev), fb_modifier, cpp);
+
+	return ALIGN(height, tile_height);
+}
+
+unsigned int intel_rotation_info_size(const struct intel_rotation_info *rot_info)
+{
+	unsigned int size = 0;
+	int i;
+
+	for (i = 0 ; i < ARRAY_SIZE(rot_info->plane); i++)
+		size += rot_info->plane[i].width * rot_info->plane[i].height;
+
+	return size;
+}
+
+static void
+intel_fill_fb_ggtt_view(struct i915_ggtt_view *view,
+			const struct drm_framebuffer *fb,
+			unsigned int rotation)
+{
+	if (intel_rotation_90_or_270(rotation)) {
+		*view = i915_ggtt_view_rotated;
+		view->params.rotated = to_intel_framebuffer(fb)->rot_info;
+	} else {
+		*view = i915_ggtt_view_normal;
+	}
+}
+
+static void
+intel_fill_fb_info(struct drm_i915_private *dev_priv,
+		   struct drm_framebuffer *fb)
+{
+	struct intel_rotation_info *info = &to_intel_framebuffer(fb)->rot_info;
+	unsigned int tile_size, tile_width, tile_height, cpp;
+
+	tile_size = intel_tile_size(dev_priv);
+
+	cpp = drm_format_plane_cpp(fb->pixel_format, 0);
+	intel_tile_dims(dev_priv, &tile_width, &tile_height,
+			fb->modifier[0], cpp);
+
+	info->plane[0].width = DIV_ROUND_UP(fb->pitches[0], tile_width * cpp);
+	info->plane[0].height = DIV_ROUND_UP(fb->height, tile_height);
+
+	if (info->pixel_format == DRM_FORMAT_NV12) {
+		cpp = drm_format_plane_cpp(fb->pixel_format, 1);
+		intel_tile_dims(dev_priv, &tile_width, &tile_height,
+				fb->modifier[1], cpp);
+
+		info->uv_offset = fb->offsets[1];
+		info->plane[1].width = DIV_ROUND_UP(fb->pitches[1], tile_width * cpp);
+		info->plane[1].height = DIV_ROUND_UP(fb->height / 2, tile_height);
+	}
+}
+
+static unsigned int intel_linear_alignment(const struct drm_i915_private *dev_priv)
+{
+	if (INTEL_INFO(dev_priv)->gen >= 9)
+		return 256 * 1024;
+	else if (IS_BROADWATER(dev_priv) || IS_CRESTLINE(dev_priv) ||
+		 IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
+		return 128 * 1024;
+	else if (INTEL_INFO(dev_priv)->gen >= 4)
+		return 4 * 1024;
+	else
+		return 0;
+}
+
+static unsigned int intel_surf_alignment(const struct drm_i915_private *dev_priv,
+					 uint64_t fb_modifier)
+{
+	switch (fb_modifier) {
+	case DRM_FORMAT_MOD_NONE:
+		return intel_linear_alignment(dev_priv);
+	case I915_FORMAT_MOD_X_TILED:
+		if (INTEL_INFO(dev_priv)->gen >= 9)
+			return 256 * 1024;
+		return 0;
+	case I915_FORMAT_MOD_Y_TILED:
+	case I915_FORMAT_MOD_Yf_TILED:
+		return 1 * 1024 * 1024;
+	default:
+		MISSING_CASE(fb_modifier);
+		return 0;
+	}
+}
+
+int
+intel_pin_and_fence_fb_obj(struct drm_framebuffer *fb,
+			   unsigned int rotation)
+{
+	struct drm_device *dev = fb->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct drm_i915_gem_object *obj = intel_fb_obj(fb);
+	struct i915_ggtt_view view;
+	u32 alignment;
+	int ret;
+
+	WARN_ON(!mutex_is_locked(&dev->struct_mutex));
+
+	alignment = intel_surf_alignment(dev_priv, fb->modifier[0]);
+
+	intel_fill_fb_ggtt_view(&view, fb, rotation);
+
+	/* Note that the w/a also requires 64 PTE of padding following the
+	 * bo. We currently fill all unused PTE with the shadow page and so
+	 * we should always have valid PTE following the scanout preventing
+	 * the VT-d warning.
+	 */
+	if (need_vtd_wa(dev) && alignment < 256 * 1024)
+		alignment = 256 * 1024;
+
+	/*
+	 * Global gtt pte registers are special registers which actually forward
+	 * writes to a chunk of system memory. Which means that there is no risk
+	 * that the register values disappear as soon as we call
+	 * intel_runtime_pm_put(), so it is correct to wrap only the
+	 * pin/unpin/fence and not more.
+	 */
+	intel_runtime_pm_get(dev_priv);
+
+	ret = i915_gem_object_pin_to_display_plane(obj, alignment,
+						   &view);
+	if (ret)
+		goto err_pm;
+
+	/* Install a fence for tiled scan-out. Pre-i965 always needs a
+	 * fence, whereas 965+ only requires a fence if using
+	 * framebuffer compression.  For simplicity, we always install
+	 * a fence as the cost is not that onerous.
+	 */
+	if (view.type == I915_GGTT_VIEW_NORMAL) {
+		ret = i915_gem_object_get_fence(obj);
+		if (ret == -EDEADLK) {
+			/*
+			 * -EDEADLK means there are no free fences
+			 * no pending flips.
+			 *
+			 * This is propagated to atomic, but it uses
+			 * -EDEADLK to force a locking recovery, so
+			 * change the returned error to -EBUSY.
+			 */
+			ret = -EBUSY;
+			goto err_unpin;
+		} else if (ret)
+			goto err_unpin;
+
+		i915_gem_object_pin_fence(obj);
+	}
+
+	intel_runtime_pm_put(dev_priv);
+	return 0;
+
+err_unpin:
+	i915_gem_object_unpin_from_display_plane(obj, &view);
+err_pm:
+	intel_runtime_pm_put(dev_priv);
+	return ret;
+}
+
+static void intel_unpin_fb_obj(struct drm_framebuffer *fb, unsigned int rotation)
+{
+	struct drm_i915_gem_object *obj = intel_fb_obj(fb);
+	struct i915_ggtt_view view;
+
+	WARN_ON(!mutex_is_locked(&obj->base.dev->struct_mutex));
+
+	intel_fill_fb_ggtt_view(&view, fb, rotation);
+
+	if (view.type == I915_GGTT_VIEW_NORMAL)
+		i915_gem_object_unpin_fence(obj);
+
+	i915_gem_object_unpin_from_display_plane(obj, &view);
+}
+
+/*
+ * Adjust the tile offset by moving the difference into
+ * the x/y offsets.
+ *
+ * Input tile dimensions and pitch must already be
+ * rotated to match x and y, and in pixel units.
+ */
+static u32 intel_adjust_tile_offset(int *x, int *y,
+				    unsigned int tile_width,
+				    unsigned int tile_height,
+				    unsigned int tile_size,
+				    unsigned int pitch_tiles,
+				    u32 old_offset,
+				    u32 new_offset)
+{
+	unsigned int tiles;
+
+	WARN_ON(old_offset & (tile_size - 1));
+	WARN_ON(new_offset & (tile_size - 1));
+	WARN_ON(new_offset > old_offset);
+
+	tiles = (old_offset - new_offset) / tile_size;
+
+	*y += tiles / pitch_tiles * tile_height;
+	*x += tiles % pitch_tiles * tile_width;
+
+	return new_offset;
+}
+
+/*
+ * Computes the linear offset to the base tile and adjusts
+ * x, y. bytes per pixel is assumed to be a power-of-two.
+ *
+ * In the 90/270 rotated case, x and y are assumed
+ * to be already rotated to match the rotated GTT view, and
+ * pitch is the tile_height aligned framebuffer height.
+ */
+u32 intel_compute_tile_offset(int *x, int *y,
+			      const struct drm_framebuffer *fb, int plane,
+			      unsigned int pitch,
+			      unsigned int rotation)
+{
+	const struct drm_i915_private *dev_priv = to_i915(fb->dev);
+	uint64_t fb_modifier = fb->modifier[plane];
+	unsigned int cpp = drm_format_plane_cpp(fb->pixel_format, plane);
+	u32 offset, offset_aligned, alignment;
+
+	alignment = intel_surf_alignment(dev_priv, fb_modifier);
+	if (alignment)
+		alignment--;
+
+	if (fb_modifier != DRM_FORMAT_MOD_NONE) {
+		unsigned int tile_size, tile_width, tile_height;
+		unsigned int tile_rows, tiles, pitch_tiles;
+
+		tile_size = intel_tile_size(dev_priv);
+		intel_tile_dims(dev_priv, &tile_width, &tile_height,
+				fb_modifier, cpp);
+
+		if (intel_rotation_90_or_270(rotation)) {
+			pitch_tiles = pitch / tile_height;
+			swap(tile_width, tile_height);
+		} else {
+			pitch_tiles = pitch / (tile_width * cpp);
+		}
+
+		tile_rows = *y / tile_height;
+		*y %= tile_height;
+
+		tiles = *x / tile_width;
+		*x %= tile_width;
+
+		offset = (tile_rows * pitch_tiles + tiles) * tile_size;
+		offset_aligned = offset & ~alignment;
+
+		intel_adjust_tile_offset(x, y, tile_width, tile_height,
+					 tile_size, pitch_tiles,
+					 offset, offset_aligned);
+	} else {
+		offset = *y * pitch + *x * cpp;
+		offset_aligned = offset & ~alignment;
+
+		*y = (offset & alignment) / pitch;
+		*x = ((offset & alignment) - *y * pitch) / cpp;
+	}
+
+	return offset_aligned;
+}
+
+static int i9xx_format_to_fourcc(int format)
+{
+	switch (format) {
+	case DISPPLANE_8BPP:
+		return DRM_FORMAT_C8;
+	case DISPPLANE_BGRX555:
+		return DRM_FORMAT_XRGB1555;
+	case DISPPLANE_BGRX565:
+		return DRM_FORMAT_RGB565;
+	default:
+	case DISPPLANE_BGRX888:
+		return DRM_FORMAT_XRGB8888;
+	case DISPPLANE_RGBX888:
+		return DRM_FORMAT_XBGR8888;
+	case DISPPLANE_BGRX101010:
+		return DRM_FORMAT_XRGB2101010;
+	case DISPPLANE_RGBX101010:
+		return DRM_FORMAT_XBGR2101010;
+	}
+}
+
+static int skl_format_to_fourcc(int format, bool rgb_order, bool alpha)
+{
+	switch (format) {
+	case PLANE_CTL_FORMAT_RGB_565:
+		return DRM_FORMAT_RGB565;
+	default:
+	case PLANE_CTL_FORMAT_XRGB_8888:
+		if (rgb_order) {
+			if (alpha)
+				return DRM_FORMAT_ABGR8888;
+			else
+				return DRM_FORMAT_XBGR8888;
+		} else {
+			if (alpha)
+				return DRM_FORMAT_ARGB8888;
+			else
+				return DRM_FORMAT_XRGB8888;
+		}
+	case PLANE_CTL_FORMAT_XRGB_2101010:
+		if (rgb_order)
+			return DRM_FORMAT_XBGR2101010;
+		else
+			return DRM_FORMAT_XRGB2101010;
+	}
+}
+
+static bool
+intel_alloc_initial_plane_obj(struct intel_crtc *crtc,
+			      struct intel_initial_plane_config *plane_config)
+{
+	struct drm_device *dev = crtc->base.dev;
+	struct drm_i915_private *dev_priv = to_i915(dev);
+	struct i915_ggtt *ggtt = &dev_priv->ggtt;
+	struct drm_i915_gem_object *obj = NULL;
+	struct drm_mode_fb_cmd2 mode_cmd = { 0 };
+	struct drm_framebuffer *fb = &plane_config->fb->base;
+	u32 base_aligned = round_down(plane_config->base, PAGE_SIZE);
+	u32 size_aligned = round_up(plane_config->base + plane_config->size,
+				    PAGE_SIZE);
+
+	size_aligned -= base_aligned;
+
+	if (plane_config->size == 0)
+		return false;
+
+	/* If the FB is too big, just don't use it since fbdev is not very
+	 * important and we should probably use that space with FBC or other
+	 * features. */
+	if (size_aligned * 2 > ggtt->stolen_usable_size)
+		return false;
+
+	mutex_lock(&dev->struct_mutex);
+
+	obj = i915_gem_object_create_stolen_for_preallocated(dev,
+							     base_aligned,
+							     base_aligned,
+							     size_aligned);
+	if (!obj) {
+		mutex_unlock(&dev->struct_mutex);
+		return false;
+	}
+
+	obj->tiling_mode = plane_config->tiling;
+	if (obj->tiling_mode == I915_TILING_X)
+		obj->stride = fb->pitches[0];
+
+	mode_cmd.pixel_format = fb->pixel_format;
+	mode_cmd.width = fb->width;
+	mode_cmd.height = fb->height;
+	mode_cmd.pitches[0] = fb->pitches[0];
+	mode_cmd.modifier[0] = fb->modifier[0];
+	mode_cmd.flags = DRM_MODE_FB_MODIFIERS;
+
+	if (intel_framebuffer_init(dev, to_intel_framebuffer(fb),
+				   &mode_cmd, obj)) {
+		DRM_DEBUG_KMS("intel fb init failed\n");
+		goto out_unref_obj;
+	}
+
+	mutex_unlock(&dev->struct_mutex);
+
+	DRM_DEBUG_KMS("initial plane fb obj %p\n", obj);
+	return true;
+
+out_unref_obj:
+	drm_gem_object_unreference(&obj->base);
+	mutex_unlock(&dev->struct_mutex);
+	return false;
+}
+
+/* Update plane->state->fb to match plane->fb after driver-internal updates */
+static void
+update_state_fb(struct drm_plane *plane)
+{
+	if (plane->fb == plane->state->fb)
+		return;
+
+	if (plane->state->fb)
+		drm_framebuffer_unreference(plane->state->fb);
+	plane->state->fb = plane->fb;
+	if (plane->state->fb)
+		drm_framebuffer_reference(plane->state->fb);
+}
+
+static void
+intel_find_initial_plane_obj(struct intel_crtc *intel_crtc,
+			     struct intel_initial_plane_config *plane_config)
+{
+	struct drm_device *dev = intel_crtc->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct drm_crtc *c;
+	struct intel_crtc *i;
+	struct drm_i915_gem_object *obj;
+	struct drm_plane *primary = intel_crtc->base.primary;
+	struct drm_plane_state *plane_state = primary->state;
+	struct drm_crtc_state *crtc_state = intel_crtc->base.state;
+	struct intel_plane *intel_plane = to_intel_plane(primary);
+	struct intel_plane_state *intel_state =
+		to_intel_plane_state(plane_state);
+	struct drm_framebuffer *fb;
+
+	if (!plane_config->fb)
+		return;
+
+	if (intel_alloc_initial_plane_obj(intel_crtc, plane_config)) {
+		fb = &plane_config->fb->base;
+		goto valid_fb;
+	}
+
+	kfree(plane_config->fb);
+
+	/*
+	 * Failed to alloc the obj, check to see if we should share
+	 * an fb with another CRTC instead
+	 */
+	for_each_crtc(dev, c) {
+		i = to_intel_crtc(c);
+
+		if (c == &intel_crtc->base)
+			continue;
+
+		if (!i->active)
+			continue;
+
+		fb = c->primary->fb;
+		if (!fb)
+			continue;
+
+		obj = intel_fb_obj(fb);
+		if (i915_gem_obj_ggtt_offset(obj) == plane_config->base) {
+			drm_framebuffer_reference(fb);
+			goto valid_fb;
+		}
+	}
+
+	/*
+	 * We've failed to reconstruct the BIOS FB.  Current display state
+	 * indicates that the primary plane is visible, but has a NULL FB,
+	 * which will lead to problems later if we don't fix it up.  The
+	 * simplest solution is to just disable the primary plane now and
+	 * pretend the BIOS never had it enabled.
+	 */
+	to_intel_plane_state(plane_state)->visible = false;
+	crtc_state->plane_mask &= ~(1 << drm_plane_index(primary));
+	intel_pre_disable_primary_noatomic(&intel_crtc->base);
+	intel_plane->disable_plane(primary, &intel_crtc->base);
+
+	return;
+
+valid_fb:
+	plane_state->src_x = 0;
+	plane_state->src_y = 0;
+	plane_state->src_w = fb->width << 16;
+	plane_state->src_h = fb->height << 16;
+
+	plane_state->crtc_x = 0;
+	plane_state->crtc_y = 0;
+	plane_state->crtc_w = fb->width;
+	plane_state->crtc_h = fb->height;
+
+	intel_state->src.x1 = plane_state->src_x;
+	intel_state->src.y1 = plane_state->src_y;
+	intel_state->src.x2 = plane_state->src_x + plane_state->src_w;
+	intel_state->src.y2 = plane_state->src_y + plane_state->src_h;
+	intel_state->dst.x1 = plane_state->crtc_x;
+	intel_state->dst.y1 = plane_state->crtc_y;
+	intel_state->dst.x2 = plane_state->crtc_x + plane_state->crtc_w;
+	intel_state->dst.y2 = plane_state->crtc_y + plane_state->crtc_h;
+
+	obj = intel_fb_obj(fb);
+	if (obj->tiling_mode != I915_TILING_NONE)
+		dev_priv->preserve_bios_swizzle = true;
+
+	drm_framebuffer_reference(fb);
+	primary->fb = primary->state->fb = fb;
+	primary->crtc = primary->state->crtc = &intel_crtc->base;
+	intel_crtc->base.state->plane_mask |= (1 << drm_plane_index(primary));
+	obj->frontbuffer_bits |= to_intel_plane(primary)->frontbuffer_bit;
+}
+
+static void i9xx_update_primary_plane(struct drm_plane *primary,
+				      const struct intel_crtc_state *crtc_state,
+				      const struct intel_plane_state *plane_state)
+{
+	struct drm_device *dev = primary->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state->base.crtc);
+	struct drm_framebuffer *fb = plane_state->base.fb;
+	struct drm_i915_gem_object *obj = intel_fb_obj(fb);
+	int plane = intel_crtc->plane;
+	u32 linear_offset;
+	u32 dspcntr;
+	i915_reg_t reg = DSPCNTR(plane);
+	unsigned int rotation = plane_state->base.rotation;
+	int cpp = drm_format_plane_cpp(fb->pixel_format, 0);
+	int x = plane_state->src.x1 >> 16;
+	int y = plane_state->src.y1 >> 16;
+
+	dspcntr = DISPPLANE_GAMMA_ENABLE;
+
+	dspcntr |= DISPLAY_PLANE_ENABLE;
+
+	if (INTEL_INFO(dev)->gen < 4) {
+		if (intel_crtc->pipe == PIPE_B)
+			dspcntr |= DISPPLANE_SEL_PIPE_B;
+
+		/* pipesrc and dspsize control the size that is scaled from,
+		 * which should always be the user's requested size.
+		 */
+		I915_WRITE(DSPSIZE(plane),
+			   ((crtc_state->pipe_src_h - 1) << 16) |
+			   (crtc_state->pipe_src_w - 1));
+		I915_WRITE(DSPPOS(plane), 0);
+	} else if (IS_CHERRYVIEW(dev) && plane == PLANE_B) {
+		I915_WRITE(PRIMSIZE(plane),
+			   ((crtc_state->pipe_src_h - 1) << 16) |
+			   (crtc_state->pipe_src_w - 1));
+		I915_WRITE(PRIMPOS(plane), 0);
+		I915_WRITE(PRIMCNSTALPHA(plane), 0);
+	}
+
+	switch (fb->pixel_format) {
+	case DRM_FORMAT_C8:
+		dspcntr |= DISPPLANE_8BPP;
+		break;
+	case DRM_FORMAT_XRGB1555:
+		dspcntr |= DISPPLANE_BGRX555;
+		break;
+	case DRM_FORMAT_RGB565:
+		dspcntr |= DISPPLANE_BGRX565;
+		break;
+	case DRM_FORMAT_XRGB8888:
+		dspcntr |= DISPPLANE_BGRX888;
+		break;
+	case DRM_FORMAT_XBGR8888:
+		dspcntr |= DISPPLANE_RGBX888;
+		break;
+	case DRM_FORMAT_XRGB2101010:
+		dspcntr |= DISPPLANE_BGRX101010;
+		break;
+	case DRM_FORMAT_XBGR2101010:
+		dspcntr |= DISPPLANE_RGBX101010;
+		break;
+	default:
+		BUG();
+	}
+
+	if (INTEL_INFO(dev)->gen >= 4 &&
+	    obj->tiling_mode != I915_TILING_NONE)
+		dspcntr |= DISPPLANE_TILED;
+
+	if (IS_G4X(dev))
+		dspcntr |= DISPPLANE_TRICKLE_FEED_DISABLE;
+
+	linear_offset = y * fb->pitches[0] + x * cpp;
+
+	if (INTEL_INFO(dev)->gen >= 4) {
+		intel_crtc->dspaddr_offset =
+			intel_compute_tile_offset(&x, &y, fb, 0,
+						  fb->pitches[0], rotation);
+		linear_offset -= intel_crtc->dspaddr_offset;
+	} else {
+		intel_crtc->dspaddr_offset = linear_offset;
+	}
+
+	if (rotation == BIT(DRM_ROTATE_180)) {
+		dspcntr |= DISPPLANE_ROTATE_180;
+
+		x += (crtc_state->pipe_src_w - 1);
+		y += (crtc_state->pipe_src_h - 1);
+
+		/* Finding the last pixel of the last line of the display
+		data and adding to linear_offset*/
+		linear_offset +=
+			(crtc_state->pipe_src_h - 1) * fb->pitches[0] +
+			(crtc_state->pipe_src_w - 1) * cpp;
+	}
+
+	intel_crtc->adjusted_x = x;
+	intel_crtc->adjusted_y = y;
+
+	I915_WRITE(reg, dspcntr);
+
+	I915_WRITE(DSPSTRIDE(plane), fb->pitches[0]);
+	if (INTEL_INFO(dev)->gen >= 4) {
+		I915_WRITE(DSPSURF(plane),
+			   i915_gem_obj_ggtt_offset(obj) + intel_crtc->dspaddr_offset);
+		I915_WRITE(DSPTILEOFF(plane), (y << 16) | x);
+		I915_WRITE(DSPLINOFF(plane), linear_offset);
+	} else
+		I915_WRITE(DSPADDR(plane), i915_gem_obj_ggtt_offset(obj) + linear_offset);
+	POSTING_READ(reg);
+}
+
+static void i9xx_disable_primary_plane(struct drm_plane *primary,
+				       struct drm_crtc *crtc)
+{
+	struct drm_device *dev = crtc->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	int plane = intel_crtc->plane;
+
+	I915_WRITE(DSPCNTR(plane), 0);
+	if (INTEL_INFO(dev_priv)->gen >= 4)
+		I915_WRITE(DSPSURF(plane), 0);
+	else
+		I915_WRITE(DSPADDR(plane), 0);
+	POSTING_READ(DSPCNTR(plane));
+}
+
+static void ironlake_update_primary_plane(struct drm_plane *primary,
+					  const struct intel_crtc_state *crtc_state,
+					  const struct intel_plane_state *plane_state)
+{
+	struct drm_device *dev = primary->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state->base.crtc);
+	struct drm_framebuffer *fb = plane_state->base.fb;
+	struct drm_i915_gem_object *obj = intel_fb_obj(fb);
+	int plane = intel_crtc->plane;
+	u32 linear_offset;
+	u32 dspcntr;
+	i915_reg_t reg = DSPCNTR(plane);
+	unsigned int rotation = plane_state->base.rotation;
+	int cpp = drm_format_plane_cpp(fb->pixel_format, 0);
+	int x = plane_state->src.x1 >> 16;
+	int y = plane_state->src.y1 >> 16;
+
+	dspcntr = DISPPLANE_GAMMA_ENABLE;
+	dspcntr |= DISPLAY_PLANE_ENABLE;
+
+	if (IS_HASWELL(dev) || IS_BROADWELL(dev))
+		dspcntr |= DISPPLANE_PIPE_CSC_ENABLE;
+
+	switch (fb->pixel_format) {
+	case DRM_FORMAT_C8:
+		dspcntr |= DISPPLANE_8BPP;
+		break;
+	case DRM_FORMAT_RGB565:
+		dspcntr |= DISPPLANE_BGRX565;
+		break;
+	case DRM_FORMAT_XRGB8888:
+		dspcntr |= DISPPLANE_BGRX888;
+		break;
+	case DRM_FORMAT_XBGR8888:
+		dspcntr |= DISPPLANE_RGBX888;
+		break;
+	case DRM_FORMAT_XRGB2101010:
+		dspcntr |= DISPPLANE_BGRX101010;
+		break;
+	case DRM_FORMAT_XBGR2101010:
+		dspcntr |= DISPPLANE_RGBX101010;
+		break;
+	default:
+		BUG();
+	}
+
+	if (obj->tiling_mode != I915_TILING_NONE)
+		dspcntr |= DISPPLANE_TILED;
+
+	if (!IS_HASWELL(dev) && !IS_BROADWELL(dev))
+		dspcntr |= DISPPLANE_TRICKLE_FEED_DISABLE;
+
+	linear_offset = y * fb->pitches[0] + x * cpp;
+	intel_crtc->dspaddr_offset =
+		intel_compute_tile_offset(&x, &y, fb, 0,
+					  fb->pitches[0], rotation);
+	linear_offset -= intel_crtc->dspaddr_offset;
+	if (rotation == BIT(DRM_ROTATE_180)) {
+		dspcntr |= DISPPLANE_ROTATE_180;
+
+		if (!IS_HASWELL(dev) && !IS_BROADWELL(dev)) {
+			x += (crtc_state->pipe_src_w - 1);
+			y += (crtc_state->pipe_src_h - 1);
+
+			/* Finding the last pixel of the last line of the display
+			data and adding to linear_offset*/
+			linear_offset +=
+				(crtc_state->pipe_src_h - 1) * fb->pitches[0] +
+				(crtc_state->pipe_src_w - 1) * cpp;
+		}
+	}
+
+	intel_crtc->adjusted_x = x;
+	intel_crtc->adjusted_y = y;
+
+	I915_WRITE(reg, dspcntr);
+
+	I915_WRITE(DSPSTRIDE(plane), fb->pitches[0]);
+	I915_WRITE(DSPSURF(plane),
+		   i915_gem_obj_ggtt_offset(obj) + intel_crtc->dspaddr_offset);
+	if (IS_HASWELL(dev) || IS_BROADWELL(dev)) {
+		I915_WRITE(DSPOFFSET(plane), (y << 16) | x);
+	} else {
+		I915_WRITE(DSPTILEOFF(plane), (y << 16) | x);
+		I915_WRITE(DSPLINOFF(plane), linear_offset);
+	}
+	POSTING_READ(reg);
+}
+
+u32 intel_fb_stride_alignment(const struct drm_i915_private *dev_priv,
+			      uint64_t fb_modifier, uint32_t pixel_format)
+{
+	if (fb_modifier == DRM_FORMAT_MOD_NONE) {
+		return 64;
+	} else {
+		int cpp = drm_format_plane_cpp(pixel_format, 0);
+
+		return intel_tile_width_bytes(dev_priv, fb_modifier, cpp);
+	}
+}
+
+u32 intel_plane_obj_offset(struct intel_plane *intel_plane,
+			   struct drm_i915_gem_object *obj,
+			   unsigned int plane)
+{
+	struct i915_ggtt_view view;
+	struct i915_vma *vma;
+	u64 offset;
+
+	intel_fill_fb_ggtt_view(&view, intel_plane->base.state->fb,
+				intel_plane->base.state->rotation);
+
+	vma = i915_gem_obj_to_ggtt_view(obj, &view);
+	if (WARN(!vma, "ggtt vma for display object not found! (view=%u)\n",
+		view.type))
+		return -1;
+
+	offset = vma->node.start;
+
+	if (plane == 1) {
+		offset += vma->ggtt_view.params.rotated.uv_start_page *
+			  PAGE_SIZE;
+	}
+
+	WARN_ON(upper_32_bits(offset));
+
+	return lower_32_bits(offset);
+}
+
+static void skl_detach_scaler(struct intel_crtc *intel_crtc, int id)
+{
+	struct drm_device *dev = intel_crtc->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	I915_WRITE(SKL_PS_CTRL(intel_crtc->pipe, id), 0);
+	I915_WRITE(SKL_PS_WIN_POS(intel_crtc->pipe, id), 0);
+	I915_WRITE(SKL_PS_WIN_SZ(intel_crtc->pipe, id), 0);
+}
+
+/*
+ * This function detaches (aka. unbinds) unused scalers in hardware
+ */
+static void skl_detach_scalers(struct intel_crtc *intel_crtc)
+{
+	struct intel_crtc_scaler_state *scaler_state;
+	int i;
+
+	scaler_state = &intel_crtc->config->scaler_state;
+
+	/* loop through and disable scalers that aren't in use */
+	for (i = 0; i < intel_crtc->num_scalers; i++) {
+		if (!scaler_state->scalers[i].in_use)
+			skl_detach_scaler(intel_crtc, i);
+	}
+}
+
+u32 skl_plane_ctl_format(uint32_t pixel_format)
+{
+	switch (pixel_format) {
+	case DRM_FORMAT_C8:
+		return PLANE_CTL_FORMAT_INDEXED;
+	case DRM_FORMAT_RGB565:
+		return PLANE_CTL_FORMAT_RGB_565;
+	case DRM_FORMAT_XBGR8888:
+		return PLANE_CTL_FORMAT_XRGB_8888 | PLANE_CTL_ORDER_RGBX;
+	case DRM_FORMAT_XRGB8888:
+		return PLANE_CTL_FORMAT_XRGB_8888;
+	/*
+	 * XXX: For ARBG/ABGR formats we default to expecting scanout buffers
+	 * to be already pre-multiplied. We need to add a knob (or a different
+	 * DRM_FORMAT) for user-space to configure that.
+	 */
+	case DRM_FORMAT_ABGR8888:
+		return PLANE_CTL_FORMAT_XRGB_8888 | PLANE_CTL_ORDER_RGBX |
+			PLANE_CTL_ALPHA_SW_PREMULTIPLY;
+	case DRM_FORMAT_ARGB8888:
+		return PLANE_CTL_FORMAT_XRGB_8888 |
+			PLANE_CTL_ALPHA_SW_PREMULTIPLY;
+	case DRM_FORMAT_XRGB2101010:
+		return PLANE_CTL_FORMAT_XRGB_2101010;
+	case DRM_FORMAT_XBGR2101010:
+		return PLANE_CTL_ORDER_RGBX | PLANE_CTL_FORMAT_XRGB_2101010;
+	case DRM_FORMAT_YUYV:
+		return PLANE_CTL_FORMAT_YUV422 | PLANE_CTL_YUV422_YUYV;
+	case DRM_FORMAT_YVYU:
+		return PLANE_CTL_FORMAT_YUV422 | PLANE_CTL_YUV422_YVYU;
+	case DRM_FORMAT_UYVY:
+		return PLANE_CTL_FORMAT_YUV422 | PLANE_CTL_YUV422_UYVY;
+	case DRM_FORMAT_VYUY:
+		return PLANE_CTL_FORMAT_YUV422 | PLANE_CTL_YUV422_VYUY;
+	default:
+		MISSING_CASE(pixel_format);
+	}
+
+	return 0;
+}
+
+u32 skl_plane_ctl_tiling(uint64_t fb_modifier)
+{
+	switch (fb_modifier) {
+	case DRM_FORMAT_MOD_NONE:
+		break;
+	case I915_FORMAT_MOD_X_TILED:
+		return PLANE_CTL_TILED_X;
+	case I915_FORMAT_MOD_Y_TILED:
+		return PLANE_CTL_TILED_Y;
+	case I915_FORMAT_MOD_Yf_TILED:
+		return PLANE_CTL_TILED_YF;
+	default:
+		MISSING_CASE(fb_modifier);
+	}
+
+	return 0;
+}
+
+u32 skl_plane_ctl_rotation(unsigned int rotation)
+{
+	switch (rotation) {
+	case BIT(DRM_ROTATE_0):
+		break;
+	/*
+	 * DRM_ROTATE_ is counter clockwise to stay compatible with Xrandr
+	 * while i915 HW rotation is clockwise, thats why this swapping.
+	 */
+	case BIT(DRM_ROTATE_90):
+		return PLANE_CTL_ROTATE_270;
+	case BIT(DRM_ROTATE_180):
+		return PLANE_CTL_ROTATE_180;
+	case BIT(DRM_ROTATE_270):
+		return PLANE_CTL_ROTATE_90;
+	default:
+		MISSING_CASE(rotation);
+	}
+
+	return 0;
+}
+
+static void skylake_update_primary_plane(struct drm_plane *plane,
+					 const struct intel_crtc_state *crtc_state,
+					 const struct intel_plane_state *plane_state)
+{
+	struct drm_device *dev = plane->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state->base.crtc);
+	struct drm_framebuffer *fb = plane_state->base.fb;
+	struct drm_i915_gem_object *obj = intel_fb_obj(fb);
+	int pipe = intel_crtc->pipe;
+	u32 plane_ctl, stride_div, stride;
+	u32 tile_height, plane_offset, plane_size;
+	unsigned int rotation = plane_state->base.rotation;
+	int x_offset, y_offset;
+	u32 surf_addr;
+	int scaler_id = plane_state->scaler_id;
+	int src_x = plane_state->src.x1 >> 16;
+	int src_y = plane_state->src.y1 >> 16;
+	int src_w = drm_rect_width(&plane_state->src) >> 16;
+	int src_h = drm_rect_height(&plane_state->src) >> 16;
+	int dst_x = plane_state->dst.x1;
+	int dst_y = plane_state->dst.y1;
+	int dst_w = drm_rect_width(&plane_state->dst);
+	int dst_h = drm_rect_height(&plane_state->dst);
+
+	plane_ctl = PLANE_CTL_ENABLE |
+		    PLANE_CTL_PIPE_GAMMA_ENABLE |
+		    PLANE_CTL_PIPE_CSC_ENABLE;
+
+	plane_ctl |= skl_plane_ctl_format(fb->pixel_format);
+	plane_ctl |= skl_plane_ctl_tiling(fb->modifier[0]);
+	plane_ctl |= PLANE_CTL_PLANE_GAMMA_DISABLE;
+	plane_ctl |= skl_plane_ctl_rotation(rotation);
+
+	stride_div = intel_fb_stride_alignment(dev_priv, fb->modifier[0],
+					       fb->pixel_format);
+	surf_addr = intel_plane_obj_offset(to_intel_plane(plane), obj, 0);
+
+	WARN_ON(drm_rect_width(&plane_state->src) == 0);
+
+	if (intel_rotation_90_or_270(rotation)) {
+		int cpp = drm_format_plane_cpp(fb->pixel_format, 0);
+
+		/* stride = Surface height in tiles */
+		tile_height = intel_tile_height(dev_priv, fb->modifier[0], cpp);
+		stride = DIV_ROUND_UP(fb->height, tile_height);
+		x_offset = stride * tile_height - src_y - src_h;
+		y_offset = src_x;
+		plane_size = (src_w - 1) << 16 | (src_h - 1);
+	} else {
+		stride = fb->pitches[0] / stride_div;
+		x_offset = src_x;
+		y_offset = src_y;
+		plane_size = (src_h - 1) << 16 | (src_w - 1);
+	}
+	plane_offset = y_offset << 16 | x_offset;
+
+	intel_crtc->adjusted_x = x_offset;
+	intel_crtc->adjusted_y = y_offset;
+
+	I915_WRITE(PLANE_CTL(pipe, 0), plane_ctl);
+	I915_WRITE(PLANE_OFFSET(pipe, 0), plane_offset);
+	I915_WRITE(PLANE_SIZE(pipe, 0), plane_size);
+	I915_WRITE(PLANE_STRIDE(pipe, 0), stride);
+
+	if (scaler_id >= 0) {
+		uint32_t ps_ctrl = 0;
+
+		WARN_ON(!dst_w || !dst_h);
+		ps_ctrl = PS_SCALER_EN | PS_PLANE_SEL(0) |
+			crtc_state->scaler_state.scalers[scaler_id].mode;
+		I915_WRITE(SKL_PS_CTRL(pipe, scaler_id), ps_ctrl);
+		I915_WRITE(SKL_PS_PWR_GATE(pipe, scaler_id), 0);
+		I915_WRITE(SKL_PS_WIN_POS(pipe, scaler_id), (dst_x << 16) | dst_y);
+		I915_WRITE(SKL_PS_WIN_SZ(pipe, scaler_id), (dst_w << 16) | dst_h);
+		I915_WRITE(PLANE_POS(pipe, 0), 0);
+	} else {
+		I915_WRITE(PLANE_POS(pipe, 0), (dst_y << 16) | dst_x);
+	}
+
+	I915_WRITE(PLANE_SURF(pipe, 0), surf_addr);
+
+	POSTING_READ(PLANE_SURF(pipe, 0));
+}
+
+static void skylake_disable_primary_plane(struct drm_plane *primary,
+					  struct drm_crtc *crtc)
+{
+	struct drm_device *dev = crtc->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	int pipe = to_intel_crtc(crtc)->pipe;
+
+	I915_WRITE(PLANE_CTL(pipe, 0), 0);
+	I915_WRITE(PLANE_SURF(pipe, 0), 0);
+	POSTING_READ(PLANE_SURF(pipe, 0));
+}
+
+/* Assume fb object is pinned & idle & fenced and just update base pointers */
+static int
+intel_pipe_set_base_atomic(struct drm_crtc *crtc, struct drm_framebuffer *fb,
+			   int x, int y, enum mode_set_atomic state)
+{
+	/* Support for kgdboc is disabled, this needs a major rework. */
+	DRM_ERROR("legacy panic handler not supported any more.\n");
+
+	return -ENODEV;
+}
+
+static void intel_complete_page_flips(struct drm_device *dev)
+{
+	struct drm_crtc *crtc;
+
+	for_each_crtc(dev, crtc) {
+		struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+		enum plane plane = intel_crtc->plane;
+
+		intel_prepare_page_flip(dev, plane);
+		intel_finish_page_flip_plane(dev, plane);
+	}
+}
+
+static void intel_update_primary_planes(struct drm_device *dev)
+{
+	struct drm_crtc *crtc;
+
+	for_each_crtc(dev, crtc) {
+		struct intel_plane *plane = to_intel_plane(crtc->primary);
+		struct intel_plane_state *plane_state;
+
+		drm_modeset_lock_crtc(crtc, &plane->base);
+		plane_state = to_intel_plane_state(plane->base.state);
+
+		if (plane_state->visible)
+			plane->update_plane(&plane->base,
+					    to_intel_crtc_state(crtc->state),
+					    plane_state);
+
+		drm_modeset_unlock_crtc(crtc);
+	}
+}
+
+void intel_prepare_reset(struct drm_device *dev)
+{
+	/* no reset support for gen2 */
+	if (IS_GEN2(dev))
+		return;
+
+	/* reset doesn't touch the display */
+	if (INTEL_INFO(dev)->gen >= 5 || IS_G4X(dev))
+		return;
+
+	drm_modeset_lock_all(dev);
+	/*
+	 * Disabling the crtcs gracefully seems nicer. Also the
+	 * g33 docs say we should at least disable all the planes.
+	 */
+	intel_display_suspend(dev);
+}
+
+void intel_finish_reset(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = to_i915(dev);
+
+	/*
+	 * Flips in the rings will be nuked by the reset,
+	 * so complete all pending flips so that user space
+	 * will get its events and not get stuck.
+	 */
+	intel_complete_page_flips(dev);
+
+	/* no reset support for gen2 */
+	if (IS_GEN2(dev))
+		return;
+
+	/* reset doesn't touch the display */
+	if (INTEL_INFO(dev)->gen >= 5 || IS_G4X(dev)) {
+		/*
+		 * Flips in the rings have been nuked by the reset,
+		 * so update the base address of all primary
+		 * planes to the the last fb to make sure we're
+		 * showing the correct fb after a reset.
+		 *
+		 * FIXME: Atomic will make this obsolete since we won't schedule
+		 * CS-based flips (which might get lost in gpu resets) any more.
+		 */
+		intel_update_primary_planes(dev);
+		return;
+	}
+
+	/*
+	 * The display has been reset as well,
+	 * so need a full re-initialization.
+	 */
+	intel_runtime_pm_disable_interrupts(dev_priv);
+	intel_runtime_pm_enable_interrupts(dev_priv);
+
+	intel_modeset_init_hw(dev);
+
+	spin_lock_irq(&dev_priv->irq_lock);
+	if (dev_priv->display.hpd_irq_setup)
+		dev_priv->display.hpd_irq_setup(dev);
+	spin_unlock_irq(&dev_priv->irq_lock);
+
+	intel_display_resume(dev);
+
+	intel_hpd_init(dev_priv);
+
+	drm_modeset_unlock_all(dev);
+}
+
+static bool intel_crtc_has_pending_flip(struct drm_crtc *crtc)
+{
+	struct drm_device *dev = crtc->dev;
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	unsigned reset_counter;
+	bool pending;
+
+	reset_counter = i915_reset_counter(&to_i915(dev)->gpu_error);
+	if (intel_crtc->reset_counter != reset_counter)
+		return false;
+
+	spin_lock_irq(&dev->event_lock);
+	pending = to_intel_crtc(crtc)->unpin_work != NULL;
+	spin_unlock_irq(&dev->event_lock);
+
+	return pending;
+}
+
+static void intel_update_pipe_config(struct intel_crtc *crtc,
+				     struct intel_crtc_state *old_crtc_state)
+{
+	struct drm_device *dev = crtc->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_crtc_state *pipe_config =
+		to_intel_crtc_state(crtc->base.state);
+
+	/* drm_atomic_helper_update_legacy_modeset_state might not be called. */
+	crtc->base.mode = crtc->base.state->mode;
+
+	DRM_DEBUG_KMS("Updating pipe size %ix%i -> %ix%i\n",
+		      old_crtc_state->pipe_src_w, old_crtc_state->pipe_src_h,
+		      pipe_config->pipe_src_w, pipe_config->pipe_src_h);
+
+	/*
+	 * Update pipe size and adjust fitter if needed: the reason for this is
+	 * that in compute_mode_changes we check the native mode (not the pfit
+	 * mode) to see if we can flip rather than do a full mode set. In the
+	 * fastboot case, we'll flip, but if we don't update the pipesrc and
+	 * pfit state, we'll end up with a big fb scanned out into the wrong
+	 * sized surface.
+	 */
+
+	I915_WRITE(PIPESRC(crtc->pipe),
+		   ((pipe_config->pipe_src_w - 1) << 16) |
+		   (pipe_config->pipe_src_h - 1));
+
+	/* on skylake this is done by detaching scalers */
+	if (INTEL_INFO(dev)->gen >= 9) {
+		skl_detach_scalers(crtc);
+
+		if (pipe_config->pch_pfit.enabled)
+			skylake_pfit_enable(crtc);
+	} else if (HAS_PCH_SPLIT(dev)) {
+		if (pipe_config->pch_pfit.enabled)
+			ironlake_pfit_enable(crtc);
+		else if (old_crtc_state->pch_pfit.enabled)
+			ironlake_pfit_disable(crtc, true);
+	}
+}
+
+static void intel_fdi_normal_train(struct drm_crtc *crtc)
+{
+	struct drm_device *dev = crtc->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	int pipe = intel_crtc->pipe;
+	i915_reg_t reg;
+	u32 temp;
+
+	/* enable normal train */
+	reg = FDI_TX_CTL(pipe);
+	temp = I915_READ(reg);
+	if (IS_IVYBRIDGE(dev)) {
+		temp &= ~FDI_LINK_TRAIN_NONE_IVB;
+		temp |= FDI_LINK_TRAIN_NONE_IVB | FDI_TX_ENHANCE_FRAME_ENABLE;
+	} else {
+		temp &= ~FDI_LINK_TRAIN_NONE;
+		temp |= FDI_LINK_TRAIN_NONE | FDI_TX_ENHANCE_FRAME_ENABLE;
+	}
+	I915_WRITE(reg, temp);
+
+	reg = FDI_RX_CTL(pipe);
+	temp = I915_READ(reg);
+	if (HAS_PCH_CPT(dev)) {
+		temp &= ~FDI_LINK_TRAIN_PATTERN_MASK_CPT;
+		temp |= FDI_LINK_TRAIN_NORMAL_CPT;
+	} else {
+		temp &= ~FDI_LINK_TRAIN_NONE;
+		temp |= FDI_LINK_TRAIN_NONE;
+	}
+	I915_WRITE(reg, temp | FDI_RX_ENHANCE_FRAME_ENABLE);
+
+	/* wait one idle pattern time */
+	POSTING_READ(reg);
+	udelay(1000);
+
+	/* IVB wants error correction enabled */
+	if (IS_IVYBRIDGE(dev))
+		I915_WRITE(reg, I915_READ(reg) | FDI_FS_ERRC_ENABLE |
+			   FDI_FE_ERRC_ENABLE);
+}
+
+/* The FDI link training functions for ILK/Ibexpeak. */
+static void ironlake_fdi_link_train(struct drm_crtc *crtc)
+{
+	struct drm_device *dev = crtc->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	int pipe = intel_crtc->pipe;
+	i915_reg_t reg;
+	u32 temp, tries;
+
+	/* FDI needs bits from pipe first */
+	assert_pipe_enabled(dev_priv, pipe);
+
+	/* Train 1: umask FDI RX Interrupt symbol_lock and bit_lock bit
+	   for train result */
+	reg = FDI_RX_IMR(pipe);
+	temp = I915_READ(reg);
+	temp &= ~FDI_RX_SYMBOL_LOCK;
+	temp &= ~FDI_RX_BIT_LOCK;
+	I915_WRITE(reg, temp);
+	I915_READ(reg);
+	udelay(150);
+
+	/* enable CPU FDI TX and PCH FDI RX */
+	reg = FDI_TX_CTL(pipe);
+	temp = I915_READ(reg);
+	temp &= ~FDI_DP_PORT_WIDTH_MASK;
+	temp |= FDI_DP_PORT_WIDTH(intel_crtc->config->fdi_lanes);
+	temp &= ~FDI_LINK_TRAIN_NONE;
+	temp |= FDI_LINK_TRAIN_PATTERN_1;
+	I915_WRITE(reg, temp | FDI_TX_ENABLE);
+
+	reg = FDI_RX_CTL(pipe);
+	temp = I915_READ(reg);
+	temp &= ~FDI_LINK_TRAIN_NONE;
+	temp |= FDI_LINK_TRAIN_PATTERN_1;
+	I915_WRITE(reg, temp | FDI_RX_ENABLE);
+
+	POSTING_READ(reg);
+	udelay(150);
+
+	/* Ironlake workaround, enable clock pointer after FDI enable*/
+	I915_WRITE(FDI_RX_CHICKEN(pipe), FDI_RX_PHASE_SYNC_POINTER_OVR);
+	I915_WRITE(FDI_RX_CHICKEN(pipe), FDI_RX_PHASE_SYNC_POINTER_OVR |
+		   FDI_RX_PHASE_SYNC_POINTER_EN);
+
+	reg = FDI_RX_IIR(pipe);
+	for (tries = 0; tries < 5; tries++) {
+		temp = I915_READ(reg);
+		DRM_DEBUG_KMS("FDI_RX_IIR 0x%x\n", temp);
+
+		if ((temp & FDI_RX_BIT_LOCK)) {
+			DRM_DEBUG_KMS("FDI train 1 done.\n");
+			I915_WRITE(reg, temp | FDI_RX_BIT_LOCK);
+			break;
+		}
+	}
+	if (tries == 5)
+		DRM_ERROR("FDI train 1 fail!\n");
+
+	/* Train 2 */
+	reg = FDI_TX_CTL(pipe);
+	temp = I915_READ(reg);
+	temp &= ~FDI_LINK_TRAIN_NONE;
+	temp |= FDI_LINK_TRAIN_PATTERN_2;
+	I915_WRITE(reg, temp);
+
+	reg = FDI_RX_CTL(pipe);
+	temp = I915_READ(reg);
+	temp &= ~FDI_LINK_TRAIN_NONE;
+	temp |= FDI_LINK_TRAIN_PATTERN_2;
+	I915_WRITE(reg, temp);
+
+	POSTING_READ(reg);
+	udelay(150);
+
+	reg = FDI_RX_IIR(pipe);
+	for (tries = 0; tries < 5; tries++) {
+		temp = I915_READ(reg);
+		DRM_DEBUG_KMS("FDI_RX_IIR 0x%x\n", temp);
+
+		if (temp & FDI_RX_SYMBOL_LOCK) {
+			I915_WRITE(reg, temp | FDI_RX_SYMBOL_LOCK);
+			DRM_DEBUG_KMS("FDI train 2 done.\n");
+			break;
+		}
+	}
+	if (tries == 5)
+		DRM_ERROR("FDI train 2 fail!\n");
+
+	DRM_DEBUG_KMS("FDI train done\n");
+
+}
+
+static const int snb_b_fdi_train_param[] = {
+	FDI_LINK_TRAIN_400MV_0DB_SNB_B,
+	FDI_LINK_TRAIN_400MV_6DB_SNB_B,
+	FDI_LINK_TRAIN_600MV_3_5DB_SNB_B,
+	FDI_LINK_TRAIN_800MV_0DB_SNB_B,
+};
+
+/* The FDI link training functions for SNB/Cougarpoint. */
+static void gen6_fdi_link_train(struct drm_crtc *crtc)
+{
+	struct drm_device *dev = crtc->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	int pipe = intel_crtc->pipe;
+	i915_reg_t reg;
+	u32 temp, i, retry;
+
+	/* Train 1: umask FDI RX Interrupt symbol_lock and bit_lock bit
+	   for train result */
+	reg = FDI_RX_IMR(pipe);
+	temp = I915_READ(reg);
+	temp &= ~FDI_RX_SYMBOL_LOCK;
+	temp &= ~FDI_RX_BIT_LOCK;
+	I915_WRITE(reg, temp);
+
+	POSTING_READ(reg);
+	udelay(150);
+
+	/* enable CPU FDI TX and PCH FDI RX */
+	reg = FDI_TX_CTL(pipe);
+	temp = I915_READ(reg);
+	temp &= ~FDI_DP_PORT_WIDTH_MASK;
+	temp |= FDI_DP_PORT_WIDTH(intel_crtc->config->fdi_lanes);
+	temp &= ~FDI_LINK_TRAIN_NONE;
+	temp |= FDI_LINK_TRAIN_PATTERN_1;
+	temp &= ~FDI_LINK_TRAIN_VOL_EMP_MASK;
+	/* SNB-B */
+	temp |= FDI_LINK_TRAIN_400MV_0DB_SNB_B;
+	I915_WRITE(reg, temp | FDI_TX_ENABLE);
+
+	I915_WRITE(FDI_RX_MISC(pipe),
+		   FDI_RX_TP1_TO_TP2_48 | FDI_RX_FDI_DELAY_90);
+
+	reg = FDI_RX_CTL(pipe);
+	temp = I915_READ(reg);
+	if (HAS_PCH_CPT(dev)) {
+		temp &= ~FDI_LINK_TRAIN_PATTERN_MASK_CPT;
+		temp |= FDI_LINK_TRAIN_PATTERN_1_CPT;
+	} else {
+		temp &= ~FDI_LINK_TRAIN_NONE;
+		temp |= FDI_LINK_TRAIN_PATTERN_1;
+	}
+	I915_WRITE(reg, temp | FDI_RX_ENABLE);
+
+	POSTING_READ(reg);
+	udelay(150);
+
+	for (i = 0; i < 4; i++) {
+		reg = FDI_TX_CTL(pipe);
+		temp = I915_READ(reg);
+		temp &= ~FDI_LINK_TRAIN_VOL_EMP_MASK;
+		temp |= snb_b_fdi_train_param[i];
+		I915_WRITE(reg, temp);
+
+		POSTING_READ(reg);
+		udelay(500);
+
+		for (retry = 0; retry < 5; retry++) {
+			reg = FDI_RX_IIR(pipe);
+			temp = I915_READ(reg);
+			DRM_DEBUG_KMS("FDI_RX_IIR 0x%x\n", temp);
+			if (temp & FDI_RX_BIT_LOCK) {
+				I915_WRITE(reg, temp | FDI_RX_BIT_LOCK);
+				DRM_DEBUG_KMS("FDI train 1 done.\n");
+				break;
+			}
+			udelay(50);
+		}
+		if (retry < 5)
+			break;
+	}
+	if (i == 4)
+		DRM_ERROR("FDI train 1 fail!\n");
+
+	/* Train 2 */
+	reg = FDI_TX_CTL(pipe);
+	temp = I915_READ(reg);
+	temp &= ~FDI_LINK_TRAIN_NONE;
+	temp |= FDI_LINK_TRAIN_PATTERN_2;
+	if (IS_GEN6(dev)) {
+		temp &= ~FDI_LINK_TRAIN_VOL_EMP_MASK;
+		/* SNB-B */
+		temp |= FDI_LINK_TRAIN_400MV_0DB_SNB_B;
+	}
+	I915_WRITE(reg, temp);
+
+	reg = FDI_RX_CTL(pipe);
+	temp = I915_READ(reg);
+	if (HAS_PCH_CPT(dev)) {
+		temp &= ~FDI_LINK_TRAIN_PATTERN_MASK_CPT;
+		temp |= FDI_LINK_TRAIN_PATTERN_2_CPT;
+	} else {
+		temp &= ~FDI_LINK_TRAIN_NONE;
+		temp |= FDI_LINK_TRAIN_PATTERN_2;
+	}
+	I915_WRITE(reg, temp);
+
+	POSTING_READ(reg);
+	udelay(150);
+
+	for (i = 0; i < 4; i++) {
+		reg = FDI_TX_CTL(pipe);
+		temp = I915_READ(reg);
+		temp &= ~FDI_LINK_TRAIN_VOL_EMP_MASK;
+		temp |= snb_b_fdi_train_param[i];
+		I915_WRITE(reg, temp);
+
+		POSTING_READ(reg);
+		udelay(500);
+
+		for (retry = 0; retry < 5; retry++) {
+			reg = FDI_RX_IIR(pipe);
+			temp = I915_READ(reg);
+			DRM_DEBUG_KMS("FDI_RX_IIR 0x%x\n", temp);
+			if (temp & FDI_RX_SYMBOL_LOCK) {
+				I915_WRITE(reg, temp | FDI_RX_SYMBOL_LOCK);
+				DRM_DEBUG_KMS("FDI train 2 done.\n");
+				break;
+			}
+			udelay(50);
+		}
+		if (retry < 5)
+			break;
+	}
+	if (i == 4)
+		DRM_ERROR("FDI train 2 fail!\n");
+
+	DRM_DEBUG_KMS("FDI train done.\n");
+}
+
+/* Manual link training for Ivy Bridge A0 parts */
+static void ivb_manual_fdi_link_train(struct drm_crtc *crtc)
+{
+	struct drm_device *dev = crtc->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	int pipe = intel_crtc->pipe;
+	i915_reg_t reg;
+	u32 temp, i, j;
+
+	/* Train 1: umask FDI RX Interrupt symbol_lock and bit_lock bit
+	   for train result */
+	reg = FDI_RX_IMR(pipe);
+	temp = I915_READ(reg);
+	temp &= ~FDI_RX_SYMBOL_LOCK;
+	temp &= ~FDI_RX_BIT_LOCK;
+	I915_WRITE(reg, temp);
+
+	POSTING_READ(reg);
+	udelay(150);
+
+	DRM_DEBUG_KMS("FDI_RX_IIR before link train 0x%x\n",
+		      I915_READ(FDI_RX_IIR(pipe)));
+
+	/* Try each vswing and preemphasis setting twice before moving on */
+	for (j = 0; j < ARRAY_SIZE(snb_b_fdi_train_param) * 2; j++) {
+		/* disable first in case we need to retry */
+		reg = FDI_TX_CTL(pipe);
+		temp = I915_READ(reg);
+		temp &= ~(FDI_LINK_TRAIN_AUTO | FDI_LINK_TRAIN_NONE_IVB);
+		temp &= ~FDI_TX_ENABLE;
+		I915_WRITE(reg, temp);
+
+		reg = FDI_RX_CTL(pipe);
+		temp = I915_READ(reg);
+		temp &= ~FDI_LINK_TRAIN_AUTO;
+		temp &= ~FDI_LINK_TRAIN_PATTERN_MASK_CPT;
+		temp &= ~FDI_RX_ENABLE;
+		I915_WRITE(reg, temp);
+
+		/* enable CPU FDI TX and PCH FDI RX */
+		reg = FDI_TX_CTL(pipe);
+		temp = I915_READ(reg);
+		temp &= ~FDI_DP_PORT_WIDTH_MASK;
+		temp |= FDI_DP_PORT_WIDTH(intel_crtc->config->fdi_lanes);
+		temp |= FDI_LINK_TRAIN_PATTERN_1_IVB;
+		temp &= ~FDI_LINK_TRAIN_VOL_EMP_MASK;
+		temp |= snb_b_fdi_train_param[j/2];
+		temp |= FDI_COMPOSITE_SYNC;
+		I915_WRITE(reg, temp | FDI_TX_ENABLE);
+
+		I915_WRITE(FDI_RX_MISC(pipe),
+			   FDI_RX_TP1_TO_TP2_48 | FDI_RX_FDI_DELAY_90);
+
+		reg = FDI_RX_CTL(pipe);
+		temp = I915_READ(reg);
+		temp |= FDI_LINK_TRAIN_PATTERN_1_CPT;
+		temp |= FDI_COMPOSITE_SYNC;
+		I915_WRITE(reg, temp | FDI_RX_ENABLE);
+
+		POSTING_READ(reg);
+		udelay(1); /* should be 0.5us */
+
+		for (i = 0; i < 4; i++) {
+			reg = FDI_RX_IIR(pipe);
+			temp = I915_READ(reg);
+			DRM_DEBUG_KMS("FDI_RX_IIR 0x%x\n", temp);
+
+			if (temp & FDI_RX_BIT_LOCK ||
+			    (I915_READ(reg) & FDI_RX_BIT_LOCK)) {
+				I915_WRITE(reg, temp | FDI_RX_BIT_LOCK);
+				DRM_DEBUG_KMS("FDI train 1 done, level %i.\n",
+					      i);
+				break;
+			}
+			udelay(1); /* should be 0.5us */
+		}
+		if (i == 4) {
+			DRM_DEBUG_KMS("FDI train 1 fail on vswing %d\n", j / 2);
+			continue;
+		}
+
+		/* Train 2 */
+		reg = FDI_TX_CTL(pipe);
+		temp = I915_READ(reg);
+		temp &= ~FDI_LINK_TRAIN_NONE_IVB;
+		temp |= FDI_LINK_TRAIN_PATTERN_2_IVB;
+		I915_WRITE(reg, temp);
+
+		reg = FDI_RX_CTL(pipe);
+		temp = I915_READ(reg);
+		temp &= ~FDI_LINK_TRAIN_PATTERN_MASK_CPT;
+		temp |= FDI_LINK_TRAIN_PATTERN_2_CPT;
+		I915_WRITE(reg, temp);
+
+		POSTING_READ(reg);
+		udelay(2); /* should be 1.5us */
+
+		for (i = 0; i < 4; i++) {
+			reg = FDI_RX_IIR(pipe);
+			temp = I915_READ(reg);
+			DRM_DEBUG_KMS("FDI_RX_IIR 0x%x\n", temp);
+
+			if (temp & FDI_RX_SYMBOL_LOCK ||
+			    (I915_READ(reg) & FDI_RX_SYMBOL_LOCK)) {
+				I915_WRITE(reg, temp | FDI_RX_SYMBOL_LOCK);
+				DRM_DEBUG_KMS("FDI train 2 done, level %i.\n",
+					      i);
+				goto train_done;
+			}
+			udelay(2); /* should be 1.5us */
+		}
+		if (i == 4)
+			DRM_DEBUG_KMS("FDI train 2 fail on vswing %d\n", j / 2);
+	}
+
+train_done:
+	DRM_DEBUG_KMS("FDI train done.\n");
+}
+
+static void ironlake_fdi_pll_enable(struct intel_crtc *intel_crtc)
+{
+	struct drm_device *dev = intel_crtc->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	int pipe = intel_crtc->pipe;
+	i915_reg_t reg;
+	u32 temp;
+
+	/* enable PCH FDI RX PLL, wait warmup plus DMI latency */
+	reg = FDI_RX_CTL(pipe);
+	temp = I915_READ(reg);
+	temp &= ~(FDI_DP_PORT_WIDTH_MASK | (0x7 << 16));
+	temp |= FDI_DP_PORT_WIDTH(intel_crtc->config->fdi_lanes);
+	temp |= (I915_READ(PIPECONF(pipe)) & PIPECONF_BPC_MASK) << 11;
+	I915_WRITE(reg, temp | FDI_RX_PLL_ENABLE);
+
+	POSTING_READ(reg);
+	udelay(200);
+
+	/* Switch from Rawclk to PCDclk */
+	temp = I915_READ(reg);
+	I915_WRITE(reg, temp | FDI_PCDCLK);
+
+	POSTING_READ(reg);
+	udelay(200);
+
+	/* Enable CPU FDI TX PLL, always on for Ironlake */
+	reg = FDI_TX_CTL(pipe);
+	temp = I915_READ(reg);
+	if ((temp & FDI_TX_PLL_ENABLE) == 0) {
+		I915_WRITE(reg, temp | FDI_TX_PLL_ENABLE);
+
+		POSTING_READ(reg);
+		udelay(100);
+	}
+}
+
+static void ironlake_fdi_pll_disable(struct intel_crtc *intel_crtc)
+{
+	struct drm_device *dev = intel_crtc->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	int pipe = intel_crtc->pipe;
+	i915_reg_t reg;
+	u32 temp;
+
+	/* Switch from PCDclk to Rawclk */
+	reg = FDI_RX_CTL(pipe);
+	temp = I915_READ(reg);
+	I915_WRITE(reg, temp & ~FDI_PCDCLK);
+
+	/* Disable CPU FDI TX PLL */
+	reg = FDI_TX_CTL(pipe);
+	temp = I915_READ(reg);
+	I915_WRITE(reg, temp & ~FDI_TX_PLL_ENABLE);
+
+	POSTING_READ(reg);
+	udelay(100);
+
+	reg = FDI_RX_CTL(pipe);
+	temp = I915_READ(reg);
+	I915_WRITE(reg, temp & ~FDI_RX_PLL_ENABLE);
+
+	/* Wait for the clocks to turn off. */
+	POSTING_READ(reg);
+	udelay(100);
+}
+
+static void ironlake_fdi_disable(struct drm_crtc *crtc)
+{
+	struct drm_device *dev = crtc->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	int pipe = intel_crtc->pipe;
+	i915_reg_t reg;
+	u32 temp;
+
+	/* disable CPU FDI tx and PCH FDI rx */
+	reg = FDI_TX_CTL(pipe);
+	temp = I915_READ(reg);
+	I915_WRITE(reg, temp & ~FDI_TX_ENABLE);
+	POSTING_READ(reg);
+
+	reg = FDI_RX_CTL(pipe);
+	temp = I915_READ(reg);
+	temp &= ~(0x7 << 16);
+	temp |= (I915_READ(PIPECONF(pipe)) & PIPECONF_BPC_MASK) << 11;
+	I915_WRITE(reg, temp & ~FDI_RX_ENABLE);
+
+	POSTING_READ(reg);
+	udelay(100);
+
+	/* Ironlake workaround, disable clock pointer after downing FDI */
+	if (HAS_PCH_IBX(dev))
+		I915_WRITE(FDI_RX_CHICKEN(pipe), FDI_RX_PHASE_SYNC_POINTER_OVR);
+
+	/* still set train pattern 1 */
+	reg = FDI_TX_CTL(pipe);
+	temp = I915_READ(reg);
+	temp &= ~FDI_LINK_TRAIN_NONE;
+	temp |= FDI_LINK_TRAIN_PATTERN_1;
+	I915_WRITE(reg, temp);
+
+	reg = FDI_RX_CTL(pipe);
+	temp = I915_READ(reg);
+	if (HAS_PCH_CPT(dev)) {
+		temp &= ~FDI_LINK_TRAIN_PATTERN_MASK_CPT;
+		temp |= FDI_LINK_TRAIN_PATTERN_1_CPT;
+	} else {
+		temp &= ~FDI_LINK_TRAIN_NONE;
+		temp |= FDI_LINK_TRAIN_PATTERN_1;
+	}
+	/* BPC in FDI rx is consistent with that in PIPECONF */
+	temp &= ~(0x07 << 16);
+	temp |= (I915_READ(PIPECONF(pipe)) & PIPECONF_BPC_MASK) << 11;
+	I915_WRITE(reg, temp);
+
+	POSTING_READ(reg);
+	udelay(100);
+}
+
+bool intel_has_pending_fb_unpin(struct drm_device *dev)
+{
+	struct intel_crtc *crtc;
+
+	/* Note that we don't need to be called with mode_config.lock here
+	 * as our list of CRTC objects is static for the lifetime of the
+	 * device and so cannot disappear as we iterate. Similarly, we can
+	 * happily treat the predicates as racy, atomic checks as userspace
+	 * cannot claim and pin a new fb without at least acquring the
+	 * struct_mutex and so serialising with us.
+	 */
+	for_each_intel_crtc(dev, crtc) {
+		if (atomic_read(&crtc->unpin_work_count) == 0)
+			continue;
+
+		if (crtc->unpin_work)
+			intel_wait_for_vblank(dev, crtc->pipe);
+
+		return true;
+	}
+
+	return false;
+}
+
+static void page_flip_completed(struct intel_crtc *intel_crtc)
+{
+	struct drm_i915_private *dev_priv = to_i915(intel_crtc->base.dev);
+	struct intel_unpin_work *work = intel_crtc->unpin_work;
+
+	/* ensure that the unpin work is consistent wrt ->pending. */
+	smp_rmb();
+	intel_crtc->unpin_work = NULL;
+
+	if (work->event)
+		drm_crtc_send_vblank_event(&intel_crtc->base, work->event);
+
+	drm_crtc_vblank_put(&intel_crtc->base);
+
+	wake_up_all(&dev_priv->pending_flip_queue);
+	queue_work(dev_priv->wq, &work->work);
+
+	trace_i915_flip_complete(intel_crtc->plane,
+				 work->pending_flip_obj);
+}
+
+static int intel_crtc_wait_for_pending_flips(struct drm_crtc *crtc)
+{
+	struct drm_device *dev = crtc->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	long ret;
+
+	WARN_ON(waitqueue_active(&dev_priv->pending_flip_queue));
+
+	ret = wait_event_interruptible_timeout(
+					dev_priv->pending_flip_queue,
+					!intel_crtc_has_pending_flip(crtc),
+					60*HZ);
+
+	if (ret < 0)
+		return ret;
+
+	if (ret == 0) {
+		struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+
+		spin_lock_irq(&dev->event_lock);
+		if (intel_crtc->unpin_work) {
+			WARN_ONCE(1, "Removing stuck page flip\n");
+			page_flip_completed(intel_crtc);
+		}
+		spin_unlock_irq(&dev->event_lock);
+	}
+
+	return 0;
+}
+
+static void lpt_disable_iclkip(struct drm_i915_private *dev_priv)
+{
+	u32 temp;
+
+	I915_WRITE(PIXCLK_GATE, PIXCLK_GATE_GATE);
+
+	mutex_lock(&dev_priv->sb_lock);
+
+	temp = intel_sbi_read(dev_priv, SBI_SSCCTL6, SBI_ICLK);
+	temp |= SBI_SSCCTL_DISABLE;
+	intel_sbi_write(dev_priv, SBI_SSCCTL6, temp, SBI_ICLK);
+
+	mutex_unlock(&dev_priv->sb_lock);
+}
+
+/* Program iCLKIP clock to the desired frequency */
+static void lpt_program_iclkip(struct drm_crtc *crtc)
+{
+	struct drm_i915_private *dev_priv = to_i915(crtc->dev);
+	int clock = to_intel_crtc(crtc)->config->base.adjusted_mode.crtc_clock;
+	u32 divsel, phaseinc, auxdiv, phasedir = 0;
+	u32 temp;
+
+	lpt_disable_iclkip(dev_priv);
+
+	/* The iCLK virtual clock root frequency is in MHz,
+	 * but the adjusted_mode->crtc_clock in in KHz. To get the
+	 * divisors, it is necessary to divide one by another, so we
+	 * convert the virtual clock precision to KHz here for higher
+	 * precision.
+	 */
+	for (auxdiv = 0; auxdiv < 2; auxdiv++) {
+		u32 iclk_virtual_root_freq = 172800 * 1000;
+		u32 iclk_pi_range = 64;
+		u32 desired_divisor;
+
+		desired_divisor = DIV_ROUND_CLOSEST(iclk_virtual_root_freq,
+						    clock << auxdiv);
+		divsel = (desired_divisor / iclk_pi_range) - 2;
+		phaseinc = desired_divisor % iclk_pi_range;
+
+		/*
+		 * Near 20MHz is a corner case which is
+		 * out of range for the 7-bit divisor
+		 */
+		if (divsel <= 0x7f)
+			break;
+	}
+
+	/* This should not happen with any sane values */
+	WARN_ON(SBI_SSCDIVINTPHASE_DIVSEL(divsel) &
+		~SBI_SSCDIVINTPHASE_DIVSEL_MASK);
+	WARN_ON(SBI_SSCDIVINTPHASE_DIR(phasedir) &
+		~SBI_SSCDIVINTPHASE_INCVAL_MASK);
+
+	DRM_DEBUG_KMS("iCLKIP clock: found settings for %dKHz refresh rate: auxdiv=%x, divsel=%x, phasedir=%x, phaseinc=%x\n",
+			clock,
+			auxdiv,
+			divsel,
+			phasedir,
+			phaseinc);
+
+	mutex_lock(&dev_priv->sb_lock);
+
+	/* Program SSCDIVINTPHASE6 */
+	temp = intel_sbi_read(dev_priv, SBI_SSCDIVINTPHASE6, SBI_ICLK);
+	temp &= ~SBI_SSCDIVINTPHASE_DIVSEL_MASK;
+	temp |= SBI_SSCDIVINTPHASE_DIVSEL(divsel);
+	temp &= ~SBI_SSCDIVINTPHASE_INCVAL_MASK;
+	temp |= SBI_SSCDIVINTPHASE_INCVAL(phaseinc);
+	temp |= SBI_SSCDIVINTPHASE_DIR(phasedir);
+	temp |= SBI_SSCDIVINTPHASE_PROPAGATE;
+	intel_sbi_write(dev_priv, SBI_SSCDIVINTPHASE6, temp, SBI_ICLK);
+
+	/* Program SSCAUXDIV */
+	temp = intel_sbi_read(dev_priv, SBI_SSCAUXDIV6, SBI_ICLK);
+	temp &= ~SBI_SSCAUXDIV_FINALDIV2SEL(1);
+	temp |= SBI_SSCAUXDIV_FINALDIV2SEL(auxdiv);
+	intel_sbi_write(dev_priv, SBI_SSCAUXDIV6, temp, SBI_ICLK);
+
+	/* Enable modulator and associated divider */
+	temp = intel_sbi_read(dev_priv, SBI_SSCCTL6, SBI_ICLK);
+	temp &= ~SBI_SSCCTL_DISABLE;
+	intel_sbi_write(dev_priv, SBI_SSCCTL6, temp, SBI_ICLK);
+
+	mutex_unlock(&dev_priv->sb_lock);
+
+	/* Wait for initialization time */
+	udelay(24);
+
+	I915_WRITE(PIXCLK_GATE, PIXCLK_GATE_UNGATE);
+}
+
+int lpt_get_iclkip(struct drm_i915_private *dev_priv)
+{
+	u32 divsel, phaseinc, auxdiv;
+	u32 iclk_virtual_root_freq = 172800 * 1000;
+	u32 iclk_pi_range = 64;
+	u32 desired_divisor;
+	u32 temp;
+
+	if ((I915_READ(PIXCLK_GATE) & PIXCLK_GATE_UNGATE) == 0)
+		return 0;
+
+	mutex_lock(&dev_priv->sb_lock);
+
+	temp = intel_sbi_read(dev_priv, SBI_SSCCTL6, SBI_ICLK);
+	if (temp & SBI_SSCCTL_DISABLE) {
+		mutex_unlock(&dev_priv->sb_lock);
+		return 0;
+	}
+
+	temp = intel_sbi_read(dev_priv, SBI_SSCDIVINTPHASE6, SBI_ICLK);
+	divsel = (temp & SBI_SSCDIVINTPHASE_DIVSEL_MASK) >>
+		SBI_SSCDIVINTPHASE_DIVSEL_SHIFT;
+	phaseinc = (temp & SBI_SSCDIVINTPHASE_INCVAL_MASK) >>
+		SBI_SSCDIVINTPHASE_INCVAL_SHIFT;
+
+	temp = intel_sbi_read(dev_priv, SBI_SSCAUXDIV6, SBI_ICLK);
+	auxdiv = (temp & SBI_SSCAUXDIV_FINALDIV2SEL_MASK) >>
+		SBI_SSCAUXDIV_FINALDIV2SEL_SHIFT;
+
+	mutex_unlock(&dev_priv->sb_lock);
+
+	desired_divisor = (divsel + 2) * iclk_pi_range + phaseinc;
+
+	return DIV_ROUND_CLOSEST(iclk_virtual_root_freq,
+				 desired_divisor << auxdiv);
+}
+
+static void ironlake_pch_transcoder_set_timings(struct intel_crtc *crtc,
+						enum pipe pch_transcoder)
+{
+	struct drm_device *dev = crtc->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	enum transcoder cpu_transcoder = crtc->config->cpu_transcoder;
+
+	I915_WRITE(PCH_TRANS_HTOTAL(pch_transcoder),
+		   I915_READ(HTOTAL(cpu_transcoder)));
+	I915_WRITE(PCH_TRANS_HBLANK(pch_transcoder),
+		   I915_READ(HBLANK(cpu_transcoder)));
+	I915_WRITE(PCH_TRANS_HSYNC(pch_transcoder),
+		   I915_READ(HSYNC(cpu_transcoder)));
+
+	I915_WRITE(PCH_TRANS_VTOTAL(pch_transcoder),
+		   I915_READ(VTOTAL(cpu_transcoder)));
+	I915_WRITE(PCH_TRANS_VBLANK(pch_transcoder),
+		   I915_READ(VBLANK(cpu_transcoder)));
+	I915_WRITE(PCH_TRANS_VSYNC(pch_transcoder),
+		   I915_READ(VSYNC(cpu_transcoder)));
+	I915_WRITE(PCH_TRANS_VSYNCSHIFT(pch_transcoder),
+		   I915_READ(VSYNCSHIFT(cpu_transcoder)));
+}
+
+static void cpt_set_fdi_bc_bifurcation(struct drm_device *dev, bool enable)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	uint32_t temp;
+
+	temp = I915_READ(SOUTH_CHICKEN1);
+	if (!!(temp & FDI_BC_BIFURCATION_SELECT) == enable)
+		return;
+
+	WARN_ON(I915_READ(FDI_RX_CTL(PIPE_B)) & FDI_RX_ENABLE);
+	WARN_ON(I915_READ(FDI_RX_CTL(PIPE_C)) & FDI_RX_ENABLE);
+
+	temp &= ~FDI_BC_BIFURCATION_SELECT;
+	if (enable)
+		temp |= FDI_BC_BIFURCATION_SELECT;
+
+	DRM_DEBUG_KMS("%sabling fdi C rx\n", enable ? "en" : "dis");
+	I915_WRITE(SOUTH_CHICKEN1, temp);
+	POSTING_READ(SOUTH_CHICKEN1);
+}
+
+static void ivybridge_update_fdi_bc_bifurcation(struct intel_crtc *intel_crtc)
+{
+	struct drm_device *dev = intel_crtc->base.dev;
+
+	switch (intel_crtc->pipe) {
+	case PIPE_A:
+		break;
+	case PIPE_B:
+		if (intel_crtc->config->fdi_lanes > 2)
+			cpt_set_fdi_bc_bifurcation(dev, false);
+		else
+			cpt_set_fdi_bc_bifurcation(dev, true);
+
+		break;
+	case PIPE_C:
+		cpt_set_fdi_bc_bifurcation(dev, true);
+
+		break;
+	default:
+		BUG();
+	}
+}
+
+/* Return which DP Port should be selected for Transcoder DP control */
+static enum port
+intel_trans_dp_port_sel(struct drm_crtc *crtc)
+{
+	struct drm_device *dev = crtc->dev;
+	struct intel_encoder *encoder;
+
+	for_each_encoder_on_crtc(dev, crtc, encoder) {
+		if (encoder->type == INTEL_OUTPUT_DISPLAYPORT ||
+		    encoder->type == INTEL_OUTPUT_EDP)
+			return enc_to_dig_port(&encoder->base)->port;
+	}
+
+	return -1;
+}
+
+/*
+ * Enable PCH resources required for PCH ports:
+ *   - PCH PLLs
+ *   - FDI training & RX/TX
+ *   - update transcoder timings
+ *   - DP transcoding bits
+ *   - transcoder
+ */
+static void ironlake_pch_enable(struct drm_crtc *crtc)
+{
+	struct drm_device *dev = crtc->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	int pipe = intel_crtc->pipe;
+	u32 temp;
+
+	assert_pch_transcoder_disabled(dev_priv, pipe);
+
+	if (IS_IVYBRIDGE(dev))
+		ivybridge_update_fdi_bc_bifurcation(intel_crtc);
+
+	/* Write the TU size bits before fdi link training, so that error
+	 * detection works. */
+	I915_WRITE(FDI_RX_TUSIZE1(pipe),
+		   I915_READ(PIPE_DATA_M1(pipe)) & TU_SIZE_MASK);
+
+	/* For PCH output, training FDI link */
+	dev_priv->display.fdi_link_train(crtc);
+
+	/* We need to program the right clock selection before writing the pixel
+	 * mutliplier into the DPLL. */
+	if (HAS_PCH_CPT(dev)) {
+		u32 sel;
+
+		temp = I915_READ(PCH_DPLL_SEL);
+		temp |= TRANS_DPLL_ENABLE(pipe);
+		sel = TRANS_DPLLB_SEL(pipe);
+		if (intel_crtc->config->shared_dpll ==
+		    intel_get_shared_dpll_by_id(dev_priv, DPLL_ID_PCH_PLL_B))
+			temp |= sel;
+		else
+			temp &= ~sel;
+		I915_WRITE(PCH_DPLL_SEL, temp);
+	}
+
+	/* XXX: pch pll's can be enabled any time before we enable the PCH
+	 * transcoder, and we actually should do this to not upset any PCH
+	 * transcoder that already use the clock when we share it.
+	 *
+	 * Note that enable_shared_dpll tries to do the right thing, but
+	 * get_shared_dpll unconditionally resets the pll - we need that to have
+	 * the right LVDS enable sequence. */
+	intel_enable_shared_dpll(intel_crtc);
+
+	/* set transcoder timing, panel must allow it */
+	assert_panel_unlocked(dev_priv, pipe);
+	ironlake_pch_transcoder_set_timings(intel_crtc, pipe);
+
+	intel_fdi_normal_train(crtc);
+
+	/* For PCH DP, enable TRANS_DP_CTL */
+	if (HAS_PCH_CPT(dev) && intel_crtc->config->has_dp_encoder) {
+		const struct drm_display_mode *adjusted_mode =
+			&intel_crtc->config->base.adjusted_mode;
+		u32 bpc = (I915_READ(PIPECONF(pipe)) & PIPECONF_BPC_MASK) >> 5;
+		i915_reg_t reg = TRANS_DP_CTL(pipe);
+		temp = I915_READ(reg);
+		temp &= ~(TRANS_DP_PORT_SEL_MASK |
+			  TRANS_DP_SYNC_MASK |
+			  TRANS_DP_BPC_MASK);
+		temp |= TRANS_DP_OUTPUT_ENABLE;
+		temp |= bpc << 9; /* same format but at 11:9 */
+
+		if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC)
+			temp |= TRANS_DP_HSYNC_ACTIVE_HIGH;
+		if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC)
+			temp |= TRANS_DP_VSYNC_ACTIVE_HIGH;
+
+		switch (intel_trans_dp_port_sel(crtc)) {
+		case PORT_B:
+			temp |= TRANS_DP_PORT_SEL_B;
+			break;
+		case PORT_C:
+			temp |= TRANS_DP_PORT_SEL_C;
+			break;
+		case PORT_D:
+			temp |= TRANS_DP_PORT_SEL_D;
+			break;
+		default:
+			BUG();
+		}
+
+		I915_WRITE(reg, temp);
+	}
+
+	ironlake_enable_pch_transcoder(dev_priv, pipe);
+}
+
+static void lpt_pch_enable(struct drm_crtc *crtc)
+{
+	struct drm_device *dev = crtc->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
+
+	assert_pch_transcoder_disabled(dev_priv, TRANSCODER_A);
+
+	lpt_program_iclkip(crtc);
+
+	/* Set transcoder timing. */
+	ironlake_pch_transcoder_set_timings(intel_crtc, PIPE_A);
+
+	lpt_enable_pch_transcoder(dev_priv, cpu_transcoder);
+}
+
+static void cpt_verify_modeset(struct drm_device *dev, int pipe)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	i915_reg_t dslreg = PIPEDSL(pipe);
+	u32 temp;
+
+	temp = I915_READ(dslreg);
+	udelay(500);
+	if (wait_for(I915_READ(dslreg) != temp, 5)) {
+		if (wait_for(I915_READ(dslreg) != temp, 5))
+			DRM_ERROR("mode set failed: pipe %c stuck\n", pipe_name(pipe));
+	}
+}
+
+static int
+skl_update_scaler(struct intel_crtc_state *crtc_state, bool force_detach,
+		  unsigned scaler_user, int *scaler_id, unsigned int rotation,
+		  int src_w, int src_h, int dst_w, int dst_h)
+{
+	struct intel_crtc_scaler_state *scaler_state =
+		&crtc_state->scaler_state;
+	struct intel_crtc *intel_crtc =
+		to_intel_crtc(crtc_state->base.crtc);
+	int need_scaling;
+
+	need_scaling = intel_rotation_90_or_270(rotation) ?
+		(src_h != dst_w || src_w != dst_h):
+		(src_w != dst_w || src_h != dst_h);
+
+	/*
+	 * if plane is being disabled or scaler is no more required or force detach
+	 *  - free scaler binded to this plane/crtc
+	 *  - in order to do this, update crtc->scaler_usage
+	 *
+	 * Here scaler state in crtc_state is set free so that
+	 * scaler can be assigned to other user. Actual register
+	 * update to free the scaler is done in plane/panel-fit programming.
+	 * For this purpose crtc/plane_state->scaler_id isn't reset here.
+	 */
+	if (force_detach || !need_scaling) {
+		if (*scaler_id >= 0) {
+			scaler_state->scaler_users &= ~(1 << scaler_user);
+			scaler_state->scalers[*scaler_id].in_use = 0;
+
+			DRM_DEBUG_KMS("scaler_user index %u.%u: "
+				"Staged freeing scaler id %d scaler_users = 0x%x\n",
+				intel_crtc->pipe, scaler_user, *scaler_id,
+				scaler_state->scaler_users);
+			*scaler_id = -1;
+		}
+		return 0;
+	}
+
+	/* range checks */
+	if (src_w < SKL_MIN_SRC_W || src_h < SKL_MIN_SRC_H ||
+		dst_w < SKL_MIN_DST_W || dst_h < SKL_MIN_DST_H ||
+
+		src_w > SKL_MAX_SRC_W || src_h > SKL_MAX_SRC_H ||
+		dst_w > SKL_MAX_DST_W || dst_h > SKL_MAX_DST_H) {
+		DRM_DEBUG_KMS("scaler_user index %u.%u: src %ux%u dst %ux%u "
+			"size is out of scaler range\n",
+			intel_crtc->pipe, scaler_user, src_w, src_h, dst_w, dst_h);
+		return -EINVAL;
+	}
+
+	/* mark this plane as a scaler user in crtc_state */
+	scaler_state->scaler_users |= (1 << scaler_user);
+	DRM_DEBUG_KMS("scaler_user index %u.%u: "
+		"staged scaling request for %ux%u->%ux%u scaler_users = 0x%x\n",
+		intel_crtc->pipe, scaler_user, src_w, src_h, dst_w, dst_h,
+		scaler_state->scaler_users);
+
+	return 0;
+}
+
+/**
+ * skl_update_scaler_crtc - Stages update to scaler state for a given crtc.
+ *
+ * @state: crtc's scaler state
+ *
+ * Return
+ *     0 - scaler_usage updated successfully
+ *    error - requested scaling cannot be supported or other error condition
+ */
+int skl_update_scaler_crtc(struct intel_crtc_state *state)
+{
+	struct intel_crtc *intel_crtc = to_intel_crtc(state->base.crtc);
+	const struct drm_display_mode *adjusted_mode = &state->base.adjusted_mode;
+
+	DRM_DEBUG_KMS("Updating scaler for [CRTC:%i] scaler_user index %u.%u\n",
+		      intel_crtc->base.base.id, intel_crtc->pipe, SKL_CRTC_INDEX);
+
+	return skl_update_scaler(state, !state->base.active, SKL_CRTC_INDEX,
+		&state->scaler_state.scaler_id, BIT(DRM_ROTATE_0),
+		state->pipe_src_w, state->pipe_src_h,
+		adjusted_mode->crtc_hdisplay, adjusted_mode->crtc_vdisplay);
+}
+
+/**
+ * skl_update_scaler_plane - Stages update to scaler state for a given plane.
+ *
+ * @state: crtc's scaler state
+ * @plane_state: atomic plane state to update
+ *
+ * Return
+ *     0 - scaler_usage updated successfully
+ *    error - requested scaling cannot be supported or other error condition
+ */
+static int skl_update_scaler_plane(struct intel_crtc_state *crtc_state,
+				   struct intel_plane_state *plane_state)
+{
+
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state->base.crtc);
+	struct intel_plane *intel_plane =
+		to_intel_plane(plane_state->base.plane);
+	struct drm_framebuffer *fb = plane_state->base.fb;
+	int ret;
+
+	bool force_detach = !fb || !plane_state->visible;
+
+	DRM_DEBUG_KMS("Updating scaler for [PLANE:%d] scaler_user index %u.%u\n",
+		      intel_plane->base.base.id, intel_crtc->pipe,
+		      drm_plane_index(&intel_plane->base));
+
+	ret = skl_update_scaler(crtc_state, force_detach,
+				drm_plane_index(&intel_plane->base),
+				&plane_state->scaler_id,
+				plane_state->base.rotation,
+				drm_rect_width(&plane_state->src) >> 16,
+				drm_rect_height(&plane_state->src) >> 16,
+				drm_rect_width(&plane_state->dst),
+				drm_rect_height(&plane_state->dst));
+
+	if (ret || plane_state->scaler_id < 0)
+		return ret;
+
+	/* check colorkey */
+	if (plane_state->ckey.flags != I915_SET_COLORKEY_NONE) {
+		DRM_DEBUG_KMS("[PLANE:%d] scaling with color key not allowed",
+			      intel_plane->base.base.id);
+		return -EINVAL;
+	}
+
+	/* Check src format */
+	switch (fb->pixel_format) {
+	case DRM_FORMAT_RGB565:
+	case DRM_FORMAT_XBGR8888:
+	case DRM_FORMAT_XRGB8888:
+	case DRM_FORMAT_ABGR8888:
+	case DRM_FORMAT_ARGB8888:
+	case DRM_FORMAT_XRGB2101010:
+	case DRM_FORMAT_XBGR2101010:
+	case DRM_FORMAT_YUYV:
+	case DRM_FORMAT_YVYU:
+	case DRM_FORMAT_UYVY:
+	case DRM_FORMAT_VYUY:
+		break;
+	default:
+		DRM_DEBUG_KMS("[PLANE:%d] FB:%d unsupported scaling format 0x%x\n",
+			intel_plane->base.base.id, fb->base.id, fb->pixel_format);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static void skylake_scaler_disable(struct intel_crtc *crtc)
+{
+	int i;
+
+	for (i = 0; i < crtc->num_scalers; i++)
+		skl_detach_scaler(crtc, i);
+}
+
+static void skylake_pfit_enable(struct intel_crtc *crtc)
+{
+	struct drm_device *dev = crtc->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	int pipe = crtc->pipe;
+	struct intel_crtc_scaler_state *scaler_state =
+		&crtc->config->scaler_state;
+
+	DRM_DEBUG_KMS("for crtc_state = %p\n", crtc->config);
+
+	if (crtc->config->pch_pfit.enabled) {
+		int id;
+
+		if (WARN_ON(crtc->config->scaler_state.scaler_id < 0)) {
+			DRM_ERROR("Requesting pfit without getting a scaler first\n");
+			return;
+		}
+
+		id = scaler_state->scaler_id;
+		I915_WRITE(SKL_PS_CTRL(pipe, id), PS_SCALER_EN |
+			PS_FILTER_MEDIUM | scaler_state->scalers[id].mode);
+		I915_WRITE(SKL_PS_WIN_POS(pipe, id), crtc->config->pch_pfit.pos);
+		I915_WRITE(SKL_PS_WIN_SZ(pipe, id), crtc->config->pch_pfit.size);
+
+		DRM_DEBUG_KMS("for crtc_state = %p scaler_id = %d\n", crtc->config, id);
+	}
+}
+
+static void ironlake_pfit_enable(struct intel_crtc *crtc)
+{
+	struct drm_device *dev = crtc->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	int pipe = crtc->pipe;
+
+	if (crtc->config->pch_pfit.enabled) {
+		/* Force use of hard-coded filter coefficients
+		 * as some pre-programmed values are broken,
+		 * e.g. x201.
+		 */
+		if (IS_IVYBRIDGE(dev) || IS_HASWELL(dev))
+			I915_WRITE(PF_CTL(pipe), PF_ENABLE | PF_FILTER_MED_3x3 |
+						 PF_PIPE_SEL_IVB(pipe));
+		else
+			I915_WRITE(PF_CTL(pipe), PF_ENABLE | PF_FILTER_MED_3x3);
+		I915_WRITE(PF_WIN_POS(pipe), crtc->config->pch_pfit.pos);
+		I915_WRITE(PF_WIN_SZ(pipe), crtc->config->pch_pfit.size);
+	}
+}
+
+void hsw_enable_ips(struct intel_crtc *crtc)
+{
+	struct drm_device *dev = crtc->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	if (!crtc->config->ips_enabled)
+		return;
+
+	/*
+	 * We can only enable IPS after we enable a plane and wait for a vblank
+	 * This function is called from post_plane_update, which is run after
+	 * a vblank wait.
+	 */
+
+	assert_plane_enabled(dev_priv, crtc->plane);
+	if (IS_BROADWELL(dev)) {
+		mutex_lock(&dev_priv->rps.hw_lock);
+		WARN_ON(sandybridge_pcode_write(dev_priv, DISPLAY_IPS_CONTROL, 0xc0000000));
+		mutex_unlock(&dev_priv->rps.hw_lock);
+		/* Quoting Art Runyan: "its not safe to expect any particular
+		 * value in IPS_CTL bit 31 after enabling IPS through the
+		 * mailbox." Moreover, the mailbox may return a bogus state,
+		 * so we need to just enable it and continue on.
+		 */
+	} else {
+		I915_WRITE(IPS_CTL, IPS_ENABLE);
+		/* The bit only becomes 1 in the next vblank, so this wait here
+		 * is essentially intel_wait_for_vblank. If we don't have this
+		 * and don't wait for vblanks until the end of crtc_enable, then
+		 * the HW state readout code will complain that the expected
+		 * IPS_CTL value is not the one we read. */
+		if (wait_for(I915_READ_NOTRACE(IPS_CTL) & IPS_ENABLE, 50))
+			DRM_ERROR("Timed out waiting for IPS enable\n");
+	}
+}
+
+void hsw_disable_ips(struct intel_crtc *crtc)
+{
+	struct drm_device *dev = crtc->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	if (!crtc->config->ips_enabled)
+		return;
+
+	assert_plane_enabled(dev_priv, crtc->plane);
+	if (IS_BROADWELL(dev)) {
+		mutex_lock(&dev_priv->rps.hw_lock);
+		WARN_ON(sandybridge_pcode_write(dev_priv, DISPLAY_IPS_CONTROL, 0));
+		mutex_unlock(&dev_priv->rps.hw_lock);
+		/* wait for pcode to finish disabling IPS, which may take up to 42ms */
+		if (wait_for((I915_READ(IPS_CTL) & IPS_ENABLE) == 0, 42))
+			DRM_ERROR("Timed out waiting for IPS disable\n");
+	} else {
+		I915_WRITE(IPS_CTL, 0);
+		POSTING_READ(IPS_CTL);
+	}
+
+	/* We need to wait for a vblank before we can disable the plane. */
+	intel_wait_for_vblank(dev, crtc->pipe);
+}
+
+static void intel_crtc_dpms_overlay_disable(struct intel_crtc *intel_crtc)
+{
+	if (intel_crtc->overlay) {
+		struct drm_device *dev = intel_crtc->base.dev;
+		struct drm_i915_private *dev_priv = dev->dev_private;
+
+		mutex_lock(&dev->struct_mutex);
+		dev_priv->mm.interruptible = false;
+		(void) intel_overlay_switch_off(intel_crtc->overlay);
+		dev_priv->mm.interruptible = true;
+		mutex_unlock(&dev->struct_mutex);
+	}
+
+	/* Let userspace switch the overlay on again. In most cases userspace
+	 * has to recompute where to put it anyway.
+	 */
+}
+
+/**
+ * intel_post_enable_primary - Perform operations after enabling primary plane
+ * @crtc: the CRTC whose primary plane was just enabled
+ *
+ * Performs potentially sleeping operations that must be done after the primary
+ * plane is enabled, such as updating FBC and IPS.  Note that this may be
+ * called due to an explicit primary plane update, or due to an implicit
+ * re-enable that is caused when a sprite plane is updated to no longer
+ * completely hide the primary plane.
+ */
+static void
+intel_post_enable_primary(struct drm_crtc *crtc)
+{
+	struct drm_device *dev = crtc->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	int pipe = intel_crtc->pipe;
+
+	/*
+	 * FIXME IPS should be fine as long as one plane is
+	 * enabled, but in practice it seems to have problems
+	 * when going from primary only to sprite only and vice
+	 * versa.
+	 */
+	hsw_enable_ips(intel_crtc);
+
+	/*
+	 * Gen2 reports pipe underruns whenever all planes are disabled.
+	 * So don't enable underrun reporting before at least some planes
+	 * are enabled.
+	 * FIXME: Need to fix the logic to work when we turn off all planes
+	 * but leave the pipe running.
+	 */
+	if (IS_GEN2(dev))
+		intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, true);
+
+	/* Underruns don't always raise interrupts, so check manually. */
+	intel_check_cpu_fifo_underruns(dev_priv);
+	intel_check_pch_fifo_underruns(dev_priv);
+}
+
+/* FIXME move all this to pre_plane_update() with proper state tracking */
+static void
+intel_pre_disable_primary(struct drm_crtc *crtc)
+{
+	struct drm_device *dev = crtc->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	int pipe = intel_crtc->pipe;
+
+	/*
+	 * Gen2 reports pipe underruns whenever all planes are disabled.
+	 * So diasble underrun reporting before all the planes get disabled.
+	 * FIXME: Need to fix the logic to work when we turn off all planes
+	 * but leave the pipe running.
+	 */
+	if (IS_GEN2(dev))
+		intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, false);
+
+	/*
+	 * FIXME IPS should be fine as long as one plane is
+	 * enabled, but in practice it seems to have problems
+	 * when going from primary only to sprite only and vice
+	 * versa.
+	 */
+	hsw_disable_ips(intel_crtc);
+}
+
+/* FIXME get rid of this and use pre_plane_update */
+static void
+intel_pre_disable_primary_noatomic(struct drm_crtc *crtc)
+{
+	struct drm_device *dev = crtc->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	int pipe = intel_crtc->pipe;
+
+	intel_pre_disable_primary(crtc);
+
+	/*
+	 * Vblank time updates from the shadow to live plane control register
+	 * are blocked if the memory self-refresh mode is active at that
+	 * moment. So to make sure the plane gets truly disabled, disable
+	 * first the self-refresh mode. The self-refresh enable bit in turn
+	 * will be checked/applied by the HW only at the next frame start
+	 * event which is after the vblank start event, so we need to have a
+	 * wait-for-vblank between disabling the plane and the pipe.
+	 */
+	if (HAS_GMCH_DISPLAY(dev)) {
+		intel_set_memory_cxsr(dev_priv, false);
+		dev_priv->wm.vlv.cxsr = false;
+		intel_wait_for_vblank(dev, pipe);
+	}
+}
+
+static void intel_post_plane_update(struct intel_crtc_state *old_crtc_state)
+{
+	struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->base.crtc);
+	struct drm_atomic_state *old_state = old_crtc_state->base.state;
+	struct intel_crtc_state *pipe_config =
+		to_intel_crtc_state(crtc->base.state);
+	struct drm_device *dev = crtc->base.dev;
+	struct drm_plane *primary = crtc->base.primary;
+	struct drm_plane_state *old_pri_state =
+		drm_atomic_get_existing_plane_state(old_state, primary);
+
+	intel_frontbuffer_flip(dev, pipe_config->fb_bits);
+
+	crtc->wm.cxsr_allowed = true;
+
+	if (pipe_config->update_wm_post && pipe_config->base.active)
+		intel_update_watermarks(&crtc->base);
+
+	if (old_pri_state) {
+		struct intel_plane_state *primary_state =
+			to_intel_plane_state(primary->state);
+		struct intel_plane_state *old_primary_state =
+			to_intel_plane_state(old_pri_state);
+
+		intel_fbc_post_update(crtc);
+
+		if (primary_state->visible &&
+		    (needs_modeset(&pipe_config->base) ||
+		     !old_primary_state->visible))
+			intel_post_enable_primary(&crtc->base);
+	}
+}
+
+static void intel_pre_plane_update(struct intel_crtc_state *old_crtc_state)
+{
+	struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->base.crtc);
+	struct drm_device *dev = crtc->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_crtc_state *pipe_config =
+		to_intel_crtc_state(crtc->base.state);
+	struct drm_atomic_state *old_state = old_crtc_state->base.state;
+	struct drm_plane *primary = crtc->base.primary;
+	struct drm_plane_state *old_pri_state =
+		drm_atomic_get_existing_plane_state(old_state, primary);
+	bool modeset = needs_modeset(&pipe_config->base);
+
+	if (old_pri_state) {
+		struct intel_plane_state *primary_state =
+			to_intel_plane_state(primary->state);
+		struct intel_plane_state *old_primary_state =
+			to_intel_plane_state(old_pri_state);
+
+		intel_fbc_pre_update(crtc);
+
+		if (old_primary_state->visible &&
+		    (modeset || !primary_state->visible))
+			intel_pre_disable_primary(&crtc->base);
+	}
+
+	if (pipe_config->disable_cxsr) {
+		crtc->wm.cxsr_allowed = false;
+
+		/*
+		 * Vblank time updates from the shadow to live plane control register
+		 * are blocked if the memory self-refresh mode is active at that
+		 * moment. So to make sure the plane gets truly disabled, disable
+		 * first the self-refresh mode. The self-refresh enable bit in turn
+		 * will be checked/applied by the HW only at the next frame start
+		 * event which is after the vblank start event, so we need to have a
+		 * wait-for-vblank between disabling the plane and the pipe.
+		 */
+		if (old_crtc_state->base.active) {
+			intel_set_memory_cxsr(dev_priv, false);
+			dev_priv->wm.vlv.cxsr = false;
+			intel_wait_for_vblank(dev, crtc->pipe);
+		}
+	}
+
+	/*
+	 * IVB workaround: must disable low power watermarks for at least
+	 * one frame before enabling scaling.  LP watermarks can be re-enabled
+	 * when scaling is disabled.
+	 *
+	 * WaCxSRDisabledForSpriteScaling:ivb
+	 */
+	if (pipe_config->disable_lp_wm) {
+		ilk_disable_lp_wm(dev);
+		intel_wait_for_vblank(dev, crtc->pipe);
+	}
+
+	/*
+	 * If we're doing a modeset, we're done.  No need to do any pre-vblank
+	 * watermark programming here.
+	 */
+	if (needs_modeset(&pipe_config->base))
+		return;
+
+	/*
+	 * For platforms that support atomic watermarks, program the
+	 * 'intermediate' watermarks immediately.  On pre-gen9 platforms, these
+	 * will be the intermediate values that are safe for both pre- and
+	 * post- vblank; when vblank happens, the 'active' values will be set
+	 * to the final 'target' values and we'll do this again to get the
+	 * optimal watermarks.  For gen9+ platforms, the values we program here
+	 * will be the final target values which will get automatically latched
+	 * at vblank time; no further programming will be necessary.
+	 *
+	 * If a platform hasn't been transitioned to atomic watermarks yet,
+	 * we'll continue to update watermarks the old way, if flags tell
+	 * us to.
+	 */
+	if (dev_priv->display.initial_watermarks != NULL)
+		dev_priv->display.initial_watermarks(pipe_config);
+	else if (pipe_config->update_wm_pre)
+		intel_update_watermarks(&crtc->base);
+}
+
+static void intel_crtc_disable_planes(struct drm_crtc *crtc, unsigned plane_mask)
+{
+	struct drm_device *dev = crtc->dev;
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	struct drm_plane *p;
+	int pipe = intel_crtc->pipe;
+
+	intel_crtc_dpms_overlay_disable(intel_crtc);
+
+	drm_for_each_plane_mask(p, dev, plane_mask)
+		to_intel_plane(p)->disable_plane(p, crtc);
+
+	/*
+	 * FIXME: Once we grow proper nuclear flip support out of this we need
+	 * to compute the mask of flip planes precisely. For the time being
+	 * consider this a flip to a NULL plane.
+	 */
+	intel_frontbuffer_flip(dev, INTEL_FRONTBUFFER_ALL_MASK(pipe));
+}
+
+static void ironlake_crtc_enable(struct drm_crtc *crtc)
+{
+	struct drm_device *dev = crtc->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	struct intel_encoder *encoder;
+	int pipe = intel_crtc->pipe;
+	struct intel_crtc_state *pipe_config =
+		to_intel_crtc_state(crtc->state);
+
+	if (WARN_ON(intel_crtc->active))
+		return;
+
+	/*
+	 * Sometimes spurious CPU pipe underruns happen during FDI
+	 * training, at least with VGA+HDMI cloning. Suppress them.
+	 *
+	 * On ILK we get an occasional spurious CPU pipe underruns
+	 * between eDP port A enable and vdd enable. Also PCH port
+	 * enable seems to result in the occasional CPU pipe underrun.
+	 *
+	 * Spurious PCH underruns also occur during PCH enabling.
+	 */
+	if (intel_crtc->config->has_pch_encoder || IS_GEN5(dev_priv))
+		intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, false);
+	if (intel_crtc->config->has_pch_encoder)
+		intel_set_pch_fifo_underrun_reporting(dev_priv, pipe, false);
+
+	if (intel_crtc->config->has_pch_encoder)
+		intel_prepare_shared_dpll(intel_crtc);
+
+	if (intel_crtc->config->has_dp_encoder)
+		intel_dp_set_m_n(intel_crtc, M1_N1);
+
+	intel_set_pipe_timings(intel_crtc);
+	intel_set_pipe_src_size(intel_crtc);
+
+	if (intel_crtc->config->has_pch_encoder) {
+		intel_cpu_transcoder_set_m_n(intel_crtc,
+				     &intel_crtc->config->fdi_m_n, NULL);
+	}
+
+	ironlake_set_pipeconf(crtc);
+
+	intel_crtc->active = true;
+
+	for_each_encoder_on_crtc(dev, crtc, encoder)
+		if (encoder->pre_enable)
+			encoder->pre_enable(encoder);
+
+	if (intel_crtc->config->has_pch_encoder) {
+		/* Note: FDI PLL enabling _must_ be done before we enable the
+		 * cpu pipes, hence this is separate from all the other fdi/pch
+		 * enabling. */
+		ironlake_fdi_pll_enable(intel_crtc);
+	} else {
+		assert_fdi_tx_disabled(dev_priv, pipe);
+		assert_fdi_rx_disabled(dev_priv, pipe);
+	}
+
+	ironlake_pfit_enable(intel_crtc);
+
+	/*
+	 * On ILK+ LUT must be loaded before the pipe is running but with
+	 * clocks enabled
+	 */
+	intel_color_load_luts(&pipe_config->base);
+
+	if (dev_priv->display.initial_watermarks != NULL)
+		dev_priv->display.initial_watermarks(intel_crtc->config);
+	intel_enable_pipe(intel_crtc);
+
+	if (intel_crtc->config->has_pch_encoder)
+		ironlake_pch_enable(crtc);
+
+	assert_vblank_disabled(crtc);
+	drm_crtc_vblank_on(crtc);
+
+	for_each_encoder_on_crtc(dev, crtc, encoder)
+		encoder->enable(encoder);
+
+	if (HAS_PCH_CPT(dev))
+		cpt_verify_modeset(dev, intel_crtc->pipe);
+
+	/* Must wait for vblank to avoid spurious PCH FIFO underruns */
+	if (intel_crtc->config->has_pch_encoder)
+		intel_wait_for_vblank(dev, pipe);
+	intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, true);
+	intel_set_pch_fifo_underrun_reporting(dev_priv, pipe, true);
+}
+
+/* IPS only exists on ULT machines and is tied to pipe A. */
+static bool hsw_crtc_supports_ips(struct intel_crtc *crtc)
+{
+	return HAS_IPS(crtc->base.dev) && crtc->pipe == PIPE_A;
+}
+
+static void haswell_crtc_enable(struct drm_crtc *crtc)
+{
+	struct drm_device *dev = crtc->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	struct intel_encoder *encoder;
+	int pipe = intel_crtc->pipe, hsw_workaround_pipe;
+	enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
+	struct intel_crtc_state *pipe_config =
+		to_intel_crtc_state(crtc->state);
+
+	if (WARN_ON(intel_crtc->active))
+		return;
+
+	if (intel_crtc->config->has_pch_encoder)
+		intel_set_pch_fifo_underrun_reporting(dev_priv, TRANSCODER_A,
+						      false);
+
+	if (intel_crtc->config->shared_dpll)
+		intel_enable_shared_dpll(intel_crtc);
+
+	if (intel_crtc->config->has_dp_encoder)
+		intel_dp_set_m_n(intel_crtc, M1_N1);
+
+	if (!intel_crtc->config->has_dsi_encoder)
+		intel_set_pipe_timings(intel_crtc);
+
+	intel_set_pipe_src_size(intel_crtc);
+
+	if (cpu_transcoder != TRANSCODER_EDP &&
+	    !transcoder_is_dsi(cpu_transcoder)) {
+		I915_WRITE(PIPE_MULT(cpu_transcoder),
+			   intel_crtc->config->pixel_multiplier - 1);
+	}
+
+	if (intel_crtc->config->has_pch_encoder) {
+		intel_cpu_transcoder_set_m_n(intel_crtc,
+				     &intel_crtc->config->fdi_m_n, NULL);
+	}
+
+	if (!intel_crtc->config->has_dsi_encoder)
+		haswell_set_pipeconf(crtc);
+
+	haswell_set_pipemisc(crtc);
+
+	intel_color_set_csc(&pipe_config->base);
+
+	intel_crtc->active = true;
+
+	if (intel_crtc->config->has_pch_encoder)
+		intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, false);
+	else
+		intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, true);
+
+	for_each_encoder_on_crtc(dev, crtc, encoder) {
+		if (encoder->pre_enable)
+			encoder->pre_enable(encoder);
+	}
+
+	if (intel_crtc->config->has_pch_encoder)
+		dev_priv->display.fdi_link_train(crtc);
+
+	if (!intel_crtc->config->has_dsi_encoder)
+		intel_ddi_enable_pipe_clock(intel_crtc);
+
+	if (INTEL_INFO(dev)->gen >= 9)
+		skylake_pfit_enable(intel_crtc);
+	else
+		ironlake_pfit_enable(intel_crtc);
+
+	/*
+	 * On ILK+ LUT must be loaded before the pipe is running but with
+	 * clocks enabled
+	 */
+	intel_color_load_luts(&pipe_config->base);
+
+	intel_ddi_set_pipe_settings(crtc);
+	if (!intel_crtc->config->has_dsi_encoder)
+		intel_ddi_enable_transcoder_func(crtc);
+
+	if (dev_priv->display.initial_watermarks != NULL)
+		dev_priv->display.initial_watermarks(pipe_config);
+	else
+		intel_update_watermarks(crtc);
+
+	/* XXX: Do the pipe assertions at the right place for BXT DSI. */
+	if (!intel_crtc->config->has_dsi_encoder)
+		intel_enable_pipe(intel_crtc);
+
+	if (intel_crtc->config->has_pch_encoder)
+		lpt_pch_enable(crtc);
+
+	if (intel_crtc->config->dp_encoder_is_mst)
+		intel_ddi_set_vc_payload_alloc(crtc, true);
+
+	assert_vblank_disabled(crtc);
+	drm_crtc_vblank_on(crtc);
+
+	for_each_encoder_on_crtc(dev, crtc, encoder) {
+		encoder->enable(encoder);
+		intel_opregion_notify_encoder(encoder, true);
+	}
+
+	if (intel_crtc->config->has_pch_encoder) {
+		intel_wait_for_vblank(dev, pipe);
+		intel_wait_for_vblank(dev, pipe);
+		intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, true);
+		intel_set_pch_fifo_underrun_reporting(dev_priv, TRANSCODER_A,
+						      true);
+	}
+
+	/* If we change the relative order between pipe/planes enabling, we need
+	 * to change the workaround. */
+	hsw_workaround_pipe = pipe_config->hsw_workaround_pipe;
+	if (IS_HASWELL(dev) && hsw_workaround_pipe != INVALID_PIPE) {
+		intel_wait_for_vblank(dev, hsw_workaround_pipe);
+		intel_wait_for_vblank(dev, hsw_workaround_pipe);
+	}
+}
+
+static void ironlake_pfit_disable(struct intel_crtc *crtc, bool force)
+{
+	struct drm_device *dev = crtc->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	int pipe = crtc->pipe;
+
+	/* To avoid upsetting the power well on haswell only disable the pfit if
+	 * it's in use. The hw state code will make sure we get this right. */
+	if (force || crtc->config->pch_pfit.enabled) {
+		I915_WRITE(PF_CTL(pipe), 0);
+		I915_WRITE(PF_WIN_POS(pipe), 0);
+		I915_WRITE(PF_WIN_SZ(pipe), 0);
+	}
+}
+
+static void ironlake_crtc_disable(struct drm_crtc *crtc)
+{
+	struct drm_device *dev = crtc->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	struct intel_encoder *encoder;
+	int pipe = intel_crtc->pipe;
+
+	/*
+	 * Sometimes spurious CPU pipe underruns happen when the
+	 * pipe is already disabled, but FDI RX/TX is still enabled.
+	 * Happens at least with VGA+HDMI cloning. Suppress them.
+	 */
+	if (intel_crtc->config->has_pch_encoder) {
+		intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, false);
+		intel_set_pch_fifo_underrun_reporting(dev_priv, pipe, false);
+	}
+
+	for_each_encoder_on_crtc(dev, crtc, encoder)
+		encoder->disable(encoder);
+
+	drm_crtc_vblank_off(crtc);
+	assert_vblank_disabled(crtc);
+
+	intel_disable_pipe(intel_crtc);
+
+	ironlake_pfit_disable(intel_crtc, false);
+
+	if (intel_crtc->config->has_pch_encoder)
+		ironlake_fdi_disable(crtc);
+
+	for_each_encoder_on_crtc(dev, crtc, encoder)
+		if (encoder->post_disable)
+			encoder->post_disable(encoder);
+
+	if (intel_crtc->config->has_pch_encoder) {
+		ironlake_disable_pch_transcoder(dev_priv, pipe);
+
+		if (HAS_PCH_CPT(dev)) {
+			i915_reg_t reg;
+			u32 temp;
+
+			/* disable TRANS_DP_CTL */
+			reg = TRANS_DP_CTL(pipe);
+			temp = I915_READ(reg);
+			temp &= ~(TRANS_DP_OUTPUT_ENABLE |
+				  TRANS_DP_PORT_SEL_MASK);
+			temp |= TRANS_DP_PORT_SEL_NONE;
+			I915_WRITE(reg, temp);
+
+			/* disable DPLL_SEL */
+			temp = I915_READ(PCH_DPLL_SEL);
+			temp &= ~(TRANS_DPLL_ENABLE(pipe) | TRANS_DPLLB_SEL(pipe));
+			I915_WRITE(PCH_DPLL_SEL, temp);
+		}
+
+		ironlake_fdi_pll_disable(intel_crtc);
+	}
+
+	intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, true);
+	intel_set_pch_fifo_underrun_reporting(dev_priv, pipe, true);
+}
+
+static void haswell_crtc_disable(struct drm_crtc *crtc)
+{
+	struct drm_device *dev = crtc->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	struct intel_encoder *encoder;
+	enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
+
+	if (intel_crtc->config->has_pch_encoder)
+		intel_set_pch_fifo_underrun_reporting(dev_priv, TRANSCODER_A,
+						      false);
+
+	for_each_encoder_on_crtc(dev, crtc, encoder) {
+		intel_opregion_notify_encoder(encoder, false);
+		encoder->disable(encoder);
+	}
+
+	drm_crtc_vblank_off(crtc);
+	assert_vblank_disabled(crtc);
+
+	/* XXX: Do the pipe assertions at the right place for BXT DSI. */
+	if (!intel_crtc->config->has_dsi_encoder)
+		intel_disable_pipe(intel_crtc);
+
+	if (intel_crtc->config->dp_encoder_is_mst)
+		intel_ddi_set_vc_payload_alloc(crtc, false);
+
+	if (!intel_crtc->config->has_dsi_encoder)
+		intel_ddi_disable_transcoder_func(dev_priv, cpu_transcoder);
+
+	if (INTEL_INFO(dev)->gen >= 9)
+		skylake_scaler_disable(intel_crtc);
+	else
+		ironlake_pfit_disable(intel_crtc, false);
+
+	if (!intel_crtc->config->has_dsi_encoder)
+		intel_ddi_disable_pipe_clock(intel_crtc);
+
+	for_each_encoder_on_crtc(dev, crtc, encoder)
+		if (encoder->post_disable)
+			encoder->post_disable(encoder);
+
+	if (intel_crtc->config->has_pch_encoder) {
+		lpt_disable_pch_transcoder(dev_priv);
+		lpt_disable_iclkip(dev_priv);
+		intel_ddi_fdi_disable(crtc);
+
+		intel_set_pch_fifo_underrun_reporting(dev_priv, TRANSCODER_A,
+						      true);
+	}
+}
+
+static void i9xx_pfit_enable(struct intel_crtc *crtc)
+{
+	struct drm_device *dev = crtc->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_crtc_state *pipe_config = crtc->config;
+
+	if (!pipe_config->gmch_pfit.control)
+		return;
+
+	/*
+	 * The panel fitter should only be adjusted whilst the pipe is disabled,
+	 * according to register description and PRM.
+	 */
+	WARN_ON(I915_READ(PFIT_CONTROL) & PFIT_ENABLE);
+	assert_pipe_disabled(dev_priv, crtc->pipe);
+
+	I915_WRITE(PFIT_PGM_RATIOS, pipe_config->gmch_pfit.pgm_ratios);
+	I915_WRITE(PFIT_CONTROL, pipe_config->gmch_pfit.control);
+
+	/* Border color in case we don't scale up to the full screen. Black by
+	 * default, change to something else for debugging. */
+	I915_WRITE(BCLRPAT(crtc->pipe), 0);
+}
+
+static enum intel_display_power_domain port_to_power_domain(enum port port)
+{
+	switch (port) {
+	case PORT_A:
+		return POWER_DOMAIN_PORT_DDI_A_LANES;
+	case PORT_B:
+		return POWER_DOMAIN_PORT_DDI_B_LANES;
+	case PORT_C:
+		return POWER_DOMAIN_PORT_DDI_C_LANES;
+	case PORT_D:
+		return POWER_DOMAIN_PORT_DDI_D_LANES;
+	case PORT_E:
+		return POWER_DOMAIN_PORT_DDI_E_LANES;
+	default:
+		MISSING_CASE(port);
+		return POWER_DOMAIN_PORT_OTHER;
+	}
+}
+
+static enum intel_display_power_domain port_to_aux_power_domain(enum port port)
+{
+	switch (port) {
+	case PORT_A:
+		return POWER_DOMAIN_AUX_A;
+	case PORT_B:
+		return POWER_DOMAIN_AUX_B;
+	case PORT_C:
+		return POWER_DOMAIN_AUX_C;
+	case PORT_D:
+		return POWER_DOMAIN_AUX_D;
+	case PORT_E:
+		/* FIXME: Check VBT for actual wiring of PORT E */
+		return POWER_DOMAIN_AUX_D;
+	default:
+		MISSING_CASE(port);
+		return POWER_DOMAIN_AUX_A;
+	}
+}
+
+enum intel_display_power_domain
+intel_display_port_power_domain(struct intel_encoder *intel_encoder)
+{
+	struct drm_device *dev = intel_encoder->base.dev;
+	struct intel_digital_port *intel_dig_port;
+
+	switch (intel_encoder->type) {
+	case INTEL_OUTPUT_UNKNOWN:
+		/* Only DDI platforms should ever use this output type */
+		WARN_ON_ONCE(!HAS_DDI(dev));
+	case INTEL_OUTPUT_DISPLAYPORT:
+	case INTEL_OUTPUT_HDMI:
+	case INTEL_OUTPUT_EDP:
+		intel_dig_port = enc_to_dig_port(&intel_encoder->base);
+		return port_to_power_domain(intel_dig_port->port);
+	case INTEL_OUTPUT_DP_MST:
+		intel_dig_port = enc_to_mst(&intel_encoder->base)->primary;
+		return port_to_power_domain(intel_dig_port->port);
+	case INTEL_OUTPUT_ANALOG:
+		return POWER_DOMAIN_PORT_CRT;
+	case INTEL_OUTPUT_DSI:
+		return POWER_DOMAIN_PORT_DSI;
+	default:
+		return POWER_DOMAIN_PORT_OTHER;
+	}
+}
+
+enum intel_display_power_domain
+intel_display_port_aux_power_domain(struct intel_encoder *intel_encoder)
+{
+	struct drm_device *dev = intel_encoder->base.dev;
+	struct intel_digital_port *intel_dig_port;
+
+	switch (intel_encoder->type) {
+	case INTEL_OUTPUT_UNKNOWN:
+	case INTEL_OUTPUT_HDMI:
+		/*
+		 * Only DDI platforms should ever use these output types.
+		 * We can get here after the HDMI detect code has already set
+		 * the type of the shared encoder. Since we can't be sure
+		 * what's the status of the given connectors, play safe and
+		 * run the DP detection too.
+		 */
+		WARN_ON_ONCE(!HAS_DDI(dev));
+	case INTEL_OUTPUT_DISPLAYPORT:
+	case INTEL_OUTPUT_EDP:
+		intel_dig_port = enc_to_dig_port(&intel_encoder->base);
+		return port_to_aux_power_domain(intel_dig_port->port);
+	case INTEL_OUTPUT_DP_MST:
+		intel_dig_port = enc_to_mst(&intel_encoder->base)->primary;
+		return port_to_aux_power_domain(intel_dig_port->port);
+	default:
+		MISSING_CASE(intel_encoder->type);
+		return POWER_DOMAIN_AUX_A;
+	}
+}
+
+static unsigned long get_crtc_power_domains(struct drm_crtc *crtc,
+					    struct intel_crtc_state *crtc_state)
+{
+	struct drm_device *dev = crtc->dev;
+	struct drm_encoder *encoder;
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	enum pipe pipe = intel_crtc->pipe;
+	unsigned long mask;
+	enum transcoder transcoder = crtc_state->cpu_transcoder;
+
+	if (!crtc_state->base.active)
+		return 0;
+
+	mask = BIT(POWER_DOMAIN_PIPE(pipe));
+	mask |= BIT(POWER_DOMAIN_TRANSCODER(transcoder));
+	if (crtc_state->pch_pfit.enabled ||
+	    crtc_state->pch_pfit.force_thru)
+		mask |= BIT(POWER_DOMAIN_PIPE_PANEL_FITTER(pipe));
+
+	drm_for_each_encoder_mask(encoder, dev, crtc_state->base.encoder_mask) {
+		struct intel_encoder *intel_encoder = to_intel_encoder(encoder);
+
+		mask |= BIT(intel_display_port_power_domain(intel_encoder));
+	}
+
+	if (crtc_state->shared_dpll)
+		mask |= BIT(POWER_DOMAIN_PLLS);
+
+	return mask;
+}
+
+static unsigned long
+modeset_get_crtc_power_domains(struct drm_crtc *crtc,
+			       struct intel_crtc_state *crtc_state)
+{
+	struct drm_i915_private *dev_priv = crtc->dev->dev_private;
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	enum intel_display_power_domain domain;
+	unsigned long domains, new_domains, old_domains;
+
+	old_domains = intel_crtc->enabled_power_domains;
+	intel_crtc->enabled_power_domains = new_domains =
+		get_crtc_power_domains(crtc, crtc_state);
+
+	domains = new_domains & ~old_domains;
+
+	for_each_power_domain(domain, domains)
+		intel_display_power_get(dev_priv, domain);
+
+	return old_domains & ~new_domains;
+}
+
+static void modeset_put_power_domains(struct drm_i915_private *dev_priv,
+				      unsigned long domains)
+{
+	enum intel_display_power_domain domain;
+
+	for_each_power_domain(domain, domains)
+		intel_display_power_put(dev_priv, domain);
+}
+
+static int intel_compute_max_dotclk(struct drm_i915_private *dev_priv)
+{
+	int max_cdclk_freq = dev_priv->max_cdclk_freq;
+
+	if (INTEL_INFO(dev_priv)->gen >= 9 ||
+	    IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv))
+		return max_cdclk_freq;
+	else if (IS_CHERRYVIEW(dev_priv))
+		return max_cdclk_freq*95/100;
+	else if (INTEL_INFO(dev_priv)->gen < 4)
+		return 2*max_cdclk_freq*90/100;
+	else
+		return max_cdclk_freq*90/100;
+}
+
+static void intel_update_max_cdclk(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev)) {
+		u32 limit = I915_READ(SKL_DFSM) & SKL_DFSM_CDCLK_LIMIT_MASK;
+
+		if (limit == SKL_DFSM_CDCLK_LIMIT_675)
+			dev_priv->max_cdclk_freq = 675000;
+		else if (limit == SKL_DFSM_CDCLK_LIMIT_540)
+			dev_priv->max_cdclk_freq = 540000;
+		else if (limit == SKL_DFSM_CDCLK_LIMIT_450)
+			dev_priv->max_cdclk_freq = 450000;
+		else
+			dev_priv->max_cdclk_freq = 337500;
+	} else if (IS_BROXTON(dev)) {
+		dev_priv->max_cdclk_freq = 624000;
+	} else if (IS_BROADWELL(dev))  {
+		/*
+		 * FIXME with extra cooling we can allow
+		 * 540 MHz for ULX and 675 Mhz for ULT.
+		 * How can we know if extra cooling is
+		 * available? PCI ID, VTB, something else?
+		 */
+		if (I915_READ(FUSE_STRAP) & HSW_CDCLK_LIMIT)
+			dev_priv->max_cdclk_freq = 450000;
+		else if (IS_BDW_ULX(dev))
+			dev_priv->max_cdclk_freq = 450000;
+		else if (IS_BDW_ULT(dev))
+			dev_priv->max_cdclk_freq = 540000;
+		else
+			dev_priv->max_cdclk_freq = 675000;
+	} else if (IS_CHERRYVIEW(dev)) {
+		dev_priv->max_cdclk_freq = 320000;
+	} else if (IS_VALLEYVIEW(dev)) {
+		dev_priv->max_cdclk_freq = 400000;
+	} else {
+		/* otherwise assume cdclk is fixed */
+		dev_priv->max_cdclk_freq = dev_priv->cdclk_freq;
+	}
+
+	dev_priv->max_dotclk_freq = intel_compute_max_dotclk(dev_priv);
+
+	DRM_DEBUG_DRIVER("Max CD clock rate: %d kHz\n",
+			 dev_priv->max_cdclk_freq);
+
+	DRM_DEBUG_DRIVER("Max dotclock rate: %d kHz\n",
+			 dev_priv->max_dotclk_freq);
+}
+
+static void intel_update_cdclk(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	dev_priv->cdclk_freq = dev_priv->display.get_display_clock_speed(dev);
+	DRM_DEBUG_DRIVER("Current CD clock rate: %d kHz\n",
+			 dev_priv->cdclk_freq);
+
+	/*
+	 * Program the gmbus_freq based on the cdclk frequency.
+	 * BSpec erroneously claims we should aim for 4MHz, but
+	 * in fact 1MHz is the correct frequency.
+	 */
+	if (IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev)) {
+		/*
+		 * Program the gmbus_freq based on the cdclk frequency.
+		 * BSpec erroneously claims we should aim for 4MHz, but
+		 * in fact 1MHz is the correct frequency.
+		 */
+		I915_WRITE(GMBUSFREQ_VLV, DIV_ROUND_UP(dev_priv->cdclk_freq, 1000));
+	}
+
+	if (dev_priv->max_cdclk_freq == 0)
+		intel_update_max_cdclk(dev);
+}
+
+static void broxton_set_cdclk(struct drm_i915_private *dev_priv, int frequency)
+{
+	uint32_t divider;
+	uint32_t ratio;
+	uint32_t current_freq;
+	int ret;
+
+	/* frequency = 19.2MHz * ratio / 2 / div{1,1.5,2,4} */
+	switch (frequency) {
+	case 144000:
+		divider = BXT_CDCLK_CD2X_DIV_SEL_4;
+		ratio = BXT_DE_PLL_RATIO(60);
+		break;
+	case 288000:
+		divider = BXT_CDCLK_CD2X_DIV_SEL_2;
+		ratio = BXT_DE_PLL_RATIO(60);
+		break;
+	case 384000:
+		divider = BXT_CDCLK_CD2X_DIV_SEL_1_5;
+		ratio = BXT_DE_PLL_RATIO(60);
+		break;
+	case 576000:
+		divider = BXT_CDCLK_CD2X_DIV_SEL_1;
+		ratio = BXT_DE_PLL_RATIO(60);
+		break;
+	case 624000:
+		divider = BXT_CDCLK_CD2X_DIV_SEL_1;
+		ratio = BXT_DE_PLL_RATIO(65);
+		break;
+	case 19200:
+		/*
+		 * Bypass frequency with DE PLL disabled. Init ratio, divider
+		 * to suppress GCC warning.
+		 */
+		ratio = 0;
+		divider = 0;
+		break;
+	default:
+		DRM_ERROR("unsupported CDCLK freq %d", frequency);
+
+		return;
+	}
+
+	mutex_lock(&dev_priv->rps.hw_lock);
+	/* Inform power controller of upcoming frequency change */
+	ret = sandybridge_pcode_write(dev_priv, HSW_PCODE_DE_WRITE_FREQ_REQ,
+				      0x80000000);
+	mutex_unlock(&dev_priv->rps.hw_lock);
+
+	if (ret) {
+		DRM_ERROR("PCode CDCLK freq change notify failed (err %d, freq %d)\n",
+			  ret, frequency);
+		return;
+	}
+
+	current_freq = I915_READ(CDCLK_CTL) & CDCLK_FREQ_DECIMAL_MASK;
+	/* convert from .1 fixpoint MHz with -1MHz offset to kHz */
+	current_freq = current_freq * 500 + 1000;
+
+	/*
+	 * DE PLL has to be disabled when
+	 * - setting to 19.2MHz (bypass, PLL isn't used)
+	 * - before setting to 624MHz (PLL needs toggling)
+	 * - before setting to any frequency from 624MHz (PLL needs toggling)
+	 */
+	if (frequency == 19200 || frequency == 624000 ||
+	    current_freq == 624000) {
+		I915_WRITE(BXT_DE_PLL_ENABLE, ~BXT_DE_PLL_PLL_ENABLE);
+		/* Timeout 200us */
+		if (wait_for(!(I915_READ(BXT_DE_PLL_ENABLE) & BXT_DE_PLL_LOCK),
+			     1))
+			DRM_ERROR("timout waiting for DE PLL unlock\n");
+	}
+
+	if (frequency != 19200) {
+		uint32_t val;
+
+		val = I915_READ(BXT_DE_PLL_CTL);
+		val &= ~BXT_DE_PLL_RATIO_MASK;
+		val |= ratio;
+		I915_WRITE(BXT_DE_PLL_CTL, val);
+
+		I915_WRITE(BXT_DE_PLL_ENABLE, BXT_DE_PLL_PLL_ENABLE);
+		/* Timeout 200us */
+		if (wait_for(I915_READ(BXT_DE_PLL_ENABLE) & BXT_DE_PLL_LOCK, 1))
+			DRM_ERROR("timeout waiting for DE PLL lock\n");
+
+		val = I915_READ(CDCLK_CTL);
+		val &= ~BXT_CDCLK_CD2X_DIV_SEL_MASK;
+		val |= divider;
+		/*
+		 * Disable SSA Precharge when CD clock frequency < 500 MHz,
+		 * enable otherwise.
+		 */
+		val &= ~BXT_CDCLK_SSA_PRECHARGE_ENABLE;
+		if (frequency >= 500000)
+			val |= BXT_CDCLK_SSA_PRECHARGE_ENABLE;
+
+		val &= ~CDCLK_FREQ_DECIMAL_MASK;
+		/* convert from kHz to .1 fixpoint MHz with -1MHz offset */
+		val |= (frequency - 1000) / 500;
+		I915_WRITE(CDCLK_CTL, val);
+	}
+
+	mutex_lock(&dev_priv->rps.hw_lock);
+	ret = sandybridge_pcode_write(dev_priv, HSW_PCODE_DE_WRITE_FREQ_REQ,
+				      DIV_ROUND_UP(frequency, 25000));
+	mutex_unlock(&dev_priv->rps.hw_lock);
+
+	if (ret) {
+		DRM_ERROR("PCode CDCLK freq set failed, (err %d, freq %d)\n",
+			  ret, frequency);
+		return;
+	}
+
+	intel_update_cdclk(dev_priv->dev);
+}
+
+static bool broxton_cdclk_is_enabled(struct drm_i915_private *dev_priv)
+{
+	if (!(I915_READ(BXT_DE_PLL_ENABLE) & BXT_DE_PLL_PLL_ENABLE))
+		return false;
+
+	/* TODO: Check for a valid CDCLK rate */
+
+	if (!(I915_READ(DBUF_CTL) & DBUF_POWER_REQUEST)) {
+		DRM_DEBUG_DRIVER("CDCLK enabled, but DBUF power not requested\n");
+
+		return false;
+	}
+
+	if (!(I915_READ(DBUF_CTL) & DBUF_POWER_STATE)) {
+		DRM_DEBUG_DRIVER("CDCLK enabled, but DBUF power hasn't settled\n");
+
+		return false;
+	}
+
+	return true;
+}
+
+bool broxton_cdclk_verify_state(struct drm_i915_private *dev_priv)
+{
+	return broxton_cdclk_is_enabled(dev_priv);
+}
+
+void broxton_init_cdclk(struct drm_i915_private *dev_priv)
+{
+	/* check if cd clock is enabled */
+	if (broxton_cdclk_is_enabled(dev_priv)) {
+		DRM_DEBUG_KMS("CDCLK already enabled, won't reprogram it\n");
+		return;
+	}
+
+	DRM_DEBUG_KMS("CDCLK not enabled, enabling it\n");
+
+	/*
+	 * FIXME:
+	 * - The initial CDCLK needs to be read from VBT.
+	 *   Need to make this change after VBT has changes for BXT.
+	 * - check if setting the max (or any) cdclk freq is really necessary
+	 *   here, it belongs to modeset time
+	 */
+	broxton_set_cdclk(dev_priv, 624000);
+
+	I915_WRITE(DBUF_CTL, I915_READ(DBUF_CTL) | DBUF_POWER_REQUEST);
+	POSTING_READ(DBUF_CTL);
+
+	udelay(10);
+
+	if (!(I915_READ(DBUF_CTL) & DBUF_POWER_STATE))
+		DRM_ERROR("DBuf power enable timeout!\n");
+}
+
+void broxton_uninit_cdclk(struct drm_i915_private *dev_priv)
+{
+	I915_WRITE(DBUF_CTL, I915_READ(DBUF_CTL) & ~DBUF_POWER_REQUEST);
+	POSTING_READ(DBUF_CTL);
+
+	udelay(10);
+
+	if (I915_READ(DBUF_CTL) & DBUF_POWER_STATE)
+		DRM_ERROR("DBuf power disable timeout!\n");
+
+	/* Set minimum (bypass) frequency, in effect turning off the DE PLL */
+	broxton_set_cdclk(dev_priv, 19200);
+}
+
+static const struct skl_cdclk_entry {
+	unsigned int freq;
+	unsigned int vco;
+} skl_cdclk_frequencies[] = {
+	{ .freq = 308570, .vco = 8640 },
+	{ .freq = 337500, .vco = 8100 },
+	{ .freq = 432000, .vco = 8640 },
+	{ .freq = 450000, .vco = 8100 },
+	{ .freq = 540000, .vco = 8100 },
+	{ .freq = 617140, .vco = 8640 },
+	{ .freq = 675000, .vco = 8100 },
+};
+
+static unsigned int skl_cdclk_decimal(unsigned int freq)
+{
+	return (freq - 1000) / 500;
+}
+
+static unsigned int skl_cdclk_get_vco(unsigned int freq)
+{
+	unsigned int i;
+
+	for (i = 0; i < ARRAY_SIZE(skl_cdclk_frequencies); i++) {
+		const struct skl_cdclk_entry *e = &skl_cdclk_frequencies[i];
+
+		if (e->freq == freq)
+			return e->vco;
+	}
+
+	return 8100;
+}
+
+static void
+skl_dpll0_enable(struct drm_i915_private *dev_priv, unsigned int required_vco)
+{
+	unsigned int min_freq;
+	u32 val;
+
+	/* select the minimum CDCLK before enabling DPLL 0 */
+	val = I915_READ(CDCLK_CTL);
+	val &= ~CDCLK_FREQ_SEL_MASK | ~CDCLK_FREQ_DECIMAL_MASK;
+	val |= CDCLK_FREQ_337_308;
+
+	if (required_vco == 8640)
+		min_freq = 308570;
+	else
+		min_freq = 337500;
+
+	val = CDCLK_FREQ_337_308 | skl_cdclk_decimal(min_freq);
+
+	I915_WRITE(CDCLK_CTL, val);
+	POSTING_READ(CDCLK_CTL);
+
+	/*
+	 * We always enable DPLL0 with the lowest link rate possible, but still
+	 * taking into account the VCO required to operate the eDP panel at the
+	 * desired frequency. The usual DP link rates operate with a VCO of
+	 * 8100 while the eDP 1.4 alternate link rates need a VCO of 8640.
+	 * The modeset code is responsible for the selection of the exact link
+	 * rate later on, with the constraint of choosing a frequency that
+	 * works with required_vco.
+	 */
+	val = I915_READ(DPLL_CTRL1);
+
+	val &= ~(DPLL_CTRL1_HDMI_MODE(SKL_DPLL0) | DPLL_CTRL1_SSC(SKL_DPLL0) |
+		 DPLL_CTRL1_LINK_RATE_MASK(SKL_DPLL0));
+	val |= DPLL_CTRL1_OVERRIDE(SKL_DPLL0);
+	if (required_vco == 8640)
+		val |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_1080,
+					    SKL_DPLL0);
+	else
+		val |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_810,
+					    SKL_DPLL0);
+
+	I915_WRITE(DPLL_CTRL1, val);
+	POSTING_READ(DPLL_CTRL1);
+
+	I915_WRITE(LCPLL1_CTL, I915_READ(LCPLL1_CTL) | LCPLL_PLL_ENABLE);
+
+	if (wait_for(I915_READ(LCPLL1_CTL) & LCPLL_PLL_LOCK, 5))
+		DRM_ERROR("DPLL0 not locked\n");
+}
+
+static bool skl_cdclk_pcu_ready(struct drm_i915_private *dev_priv)
+{
+	int ret;
+	u32 val;
+
+	/* inform PCU we want to change CDCLK */
+	val = SKL_CDCLK_PREPARE_FOR_CHANGE;
+	mutex_lock(&dev_priv->rps.hw_lock);
+	ret = sandybridge_pcode_read(dev_priv, SKL_PCODE_CDCLK_CONTROL, &val);
+	mutex_unlock(&dev_priv->rps.hw_lock);
+
+	return ret == 0 && (val & SKL_CDCLK_READY_FOR_CHANGE);
+}
+
+static bool skl_cdclk_wait_for_pcu_ready(struct drm_i915_private *dev_priv)
+{
+	unsigned int i;
+
+	for (i = 0; i < 15; i++) {
+		if (skl_cdclk_pcu_ready(dev_priv))
+			return true;
+		udelay(10);
+	}
+
+	return false;
+}
+
+static void skl_set_cdclk(struct drm_i915_private *dev_priv, unsigned int freq)
+{
+	struct drm_device *dev = dev_priv->dev;
+	u32 freq_select, pcu_ack;
+
+	DRM_DEBUG_DRIVER("Changing CDCLK to %dKHz\n", freq);
+
+	if (!skl_cdclk_wait_for_pcu_ready(dev_priv)) {
+		DRM_ERROR("failed to inform PCU about cdclk change\n");
+		return;
+	}
+
+	/* set CDCLK_CTL */
+	switch(freq) {
+	case 450000:
+	case 432000:
+		freq_select = CDCLK_FREQ_450_432;
+		pcu_ack = 1;
+		break;
+	case 540000:
+		freq_select = CDCLK_FREQ_540;
+		pcu_ack = 2;
+		break;
+	case 308570:
+	case 337500:
+	default:
+		freq_select = CDCLK_FREQ_337_308;
+		pcu_ack = 0;
+		break;
+	case 617140:
+	case 675000:
+		freq_select = CDCLK_FREQ_675_617;
+		pcu_ack = 3;
+		break;
+	}
+
+	I915_WRITE(CDCLK_CTL, freq_select | skl_cdclk_decimal(freq));
+	POSTING_READ(CDCLK_CTL);
+
+	/* inform PCU of the change */
+	mutex_lock(&dev_priv->rps.hw_lock);
+	sandybridge_pcode_write(dev_priv, SKL_PCODE_CDCLK_CONTROL, pcu_ack);
+	mutex_unlock(&dev_priv->rps.hw_lock);
+
+	intel_update_cdclk(dev);
+}
+
+void skl_uninit_cdclk(struct drm_i915_private *dev_priv)
+{
+	/* disable DBUF power */
+	I915_WRITE(DBUF_CTL, I915_READ(DBUF_CTL) & ~DBUF_POWER_REQUEST);
+	POSTING_READ(DBUF_CTL);
+
+	udelay(10);
+
+	if (I915_READ(DBUF_CTL) & DBUF_POWER_STATE)
+		DRM_ERROR("DBuf power disable timeout\n");
+
+	/* disable DPLL0 */
+	I915_WRITE(LCPLL1_CTL, I915_READ(LCPLL1_CTL) & ~LCPLL_PLL_ENABLE);
+	if (wait_for(!(I915_READ(LCPLL1_CTL) & LCPLL_PLL_LOCK), 1))
+		DRM_ERROR("Couldn't disable DPLL0\n");
+}
+
+void skl_init_cdclk(struct drm_i915_private *dev_priv)
+{
+	unsigned int required_vco;
+
+	/* DPLL0 not enabled (happens on early BIOS versions) */
+	if (!(I915_READ(LCPLL1_CTL) & LCPLL_PLL_ENABLE)) {
+		/* enable DPLL0 */
+		required_vco = skl_cdclk_get_vco(dev_priv->skl_boot_cdclk);
+		skl_dpll0_enable(dev_priv, required_vco);
+	}
+
+	/* set CDCLK to the frequency the BIOS chose */
+	skl_set_cdclk(dev_priv, dev_priv->skl_boot_cdclk);
+
+	/* enable DBUF power */
+	I915_WRITE(DBUF_CTL, I915_READ(DBUF_CTL) | DBUF_POWER_REQUEST);
+	POSTING_READ(DBUF_CTL);
+
+	udelay(10);
+
+	if (!(I915_READ(DBUF_CTL) & DBUF_POWER_STATE))
+		DRM_ERROR("DBuf power enable timeout\n");
+}
+
+int skl_sanitize_cdclk(struct drm_i915_private *dev_priv)
+{
+	uint32_t lcpll1 = I915_READ(LCPLL1_CTL);
+	uint32_t cdctl = I915_READ(CDCLK_CTL);
+	int freq = dev_priv->skl_boot_cdclk;
+
+	/*
+	 * check if the pre-os intialized the display
+	 * There is SWF18 scratchpad register defined which is set by the
+	 * pre-os which can be used by the OS drivers to check the status
+	 */
+	if ((I915_READ(SWF_ILK(0x18)) & 0x00FFFFFF) == 0)
+		goto sanitize;
+
+	/* Is PLL enabled and locked ? */
+	if (!((lcpll1 & LCPLL_PLL_ENABLE) && (lcpll1 & LCPLL_PLL_LOCK)))
+		goto sanitize;
+
+	/* DPLL okay; verify the cdclock
+	 *
+	 * Noticed in some instances that the freq selection is correct but
+	 * decimal part is programmed wrong from BIOS where pre-os does not
+	 * enable display. Verify the same as well.
+	 */
+	if (cdctl == ((cdctl & CDCLK_FREQ_SEL_MASK) | skl_cdclk_decimal(freq)))
+		/* All well; nothing to sanitize */
+		return false;
+sanitize:
+	/*
+	 * As of now initialize with max cdclk till
+	 * we get dynamic cdclk support
+	 * */
+	dev_priv->skl_boot_cdclk = dev_priv->max_cdclk_freq;
+	skl_init_cdclk(dev_priv);
+
+	/* we did have to sanitize */
+	return true;
+}
+
+/* Adjust CDclk dividers to allow high res or save power if possible */
+static void valleyview_set_cdclk(struct drm_device *dev, int cdclk)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	u32 val, cmd;
+
+	WARN_ON(dev_priv->display.get_display_clock_speed(dev)
+					!= dev_priv->cdclk_freq);
+
+	if (cdclk >= 320000) /* jump to highest voltage for 400MHz too */
+		cmd = 2;
+	else if (cdclk == 266667)
+		cmd = 1;
+	else
+		cmd = 0;
+
+	mutex_lock(&dev_priv->rps.hw_lock);
+	val = vlv_punit_read(dev_priv, PUNIT_REG_DSPFREQ);
+	val &= ~DSPFREQGUAR_MASK;
+	val |= (cmd << DSPFREQGUAR_SHIFT);
+	vlv_punit_write(dev_priv, PUNIT_REG_DSPFREQ, val);
+	if (wait_for((vlv_punit_read(dev_priv, PUNIT_REG_DSPFREQ) &
+		      DSPFREQSTAT_MASK) == (cmd << DSPFREQSTAT_SHIFT),
+		     50)) {
+		DRM_ERROR("timed out waiting for CDclk change\n");
+	}
+	mutex_unlock(&dev_priv->rps.hw_lock);
+
+	mutex_lock(&dev_priv->sb_lock);
+
+	if (cdclk == 400000) {
+		u32 divider;
+
+		divider = DIV_ROUND_CLOSEST(dev_priv->hpll_freq << 1, cdclk) - 1;
+
+		/* adjust cdclk divider */
+		val = vlv_cck_read(dev_priv, CCK_DISPLAY_CLOCK_CONTROL);
+		val &= ~CCK_FREQUENCY_VALUES;
+		val |= divider;
+		vlv_cck_write(dev_priv, CCK_DISPLAY_CLOCK_CONTROL, val);
+
+		if (wait_for((vlv_cck_read(dev_priv, CCK_DISPLAY_CLOCK_CONTROL) &
+			      CCK_FREQUENCY_STATUS) == (divider << CCK_FREQUENCY_STATUS_SHIFT),
+			     50))
+			DRM_ERROR("timed out waiting for CDclk change\n");
+	}
+
+	/* adjust self-refresh exit latency value */
+	val = vlv_bunit_read(dev_priv, BUNIT_REG_BISOC);
+	val &= ~0x7f;
+
+	/*
+	 * For high bandwidth configs, we set a higher latency in the bunit
+	 * so that the core display fetch happens in time to avoid underruns.
+	 */
+	if (cdclk == 400000)
+		val |= 4500 / 250; /* 4.5 usec */
+	else
+		val |= 3000 / 250; /* 3.0 usec */
+	vlv_bunit_write(dev_priv, BUNIT_REG_BISOC, val);
+
+	mutex_unlock(&dev_priv->sb_lock);
+
+	intel_update_cdclk(dev);
+}
+
+static void cherryview_set_cdclk(struct drm_device *dev, int cdclk)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	u32 val, cmd;
+
+	WARN_ON(dev_priv->display.get_display_clock_speed(dev)
+						!= dev_priv->cdclk_freq);
+
+	switch (cdclk) {
+	case 333333:
+	case 320000:
+	case 266667:
+	case 200000:
+		break;
+	default:
+		MISSING_CASE(cdclk);
+		return;
+	}
+
+	/*
+	 * Specs are full of misinformation, but testing on actual
+	 * hardware has shown that we just need to write the desired
+	 * CCK divider into the Punit register.
+	 */
+	cmd = DIV_ROUND_CLOSEST(dev_priv->hpll_freq << 1, cdclk) - 1;
+
+	mutex_lock(&dev_priv->rps.hw_lock);
+	val = vlv_punit_read(dev_priv, PUNIT_REG_DSPFREQ);
+	val &= ~DSPFREQGUAR_MASK_CHV;
+	val |= (cmd << DSPFREQGUAR_SHIFT_CHV);
+	vlv_punit_write(dev_priv, PUNIT_REG_DSPFREQ, val);
+	if (wait_for((vlv_punit_read(dev_priv, PUNIT_REG_DSPFREQ) &
+		      DSPFREQSTAT_MASK_CHV) == (cmd << DSPFREQSTAT_SHIFT_CHV),
+		     50)) {
+		DRM_ERROR("timed out waiting for CDclk change\n");
+	}
+	mutex_unlock(&dev_priv->rps.hw_lock);
+
+	intel_update_cdclk(dev);
+}
+
+static int valleyview_calc_cdclk(struct drm_i915_private *dev_priv,
+				 int max_pixclk)
+{
+	int freq_320 = (dev_priv->hpll_freq <<  1) % 320000 != 0 ? 333333 : 320000;
+	int limit = IS_CHERRYVIEW(dev_priv) ? 95 : 90;
+
+	/*
+	 * Really only a few cases to deal with, as only 4 CDclks are supported:
+	 *   200MHz
+	 *   267MHz
+	 *   320/333MHz (depends on HPLL freq)
+	 *   400MHz (VLV only)
+	 * So we check to see whether we're above 90% (VLV) or 95% (CHV)
+	 * of the lower bin and adjust if needed.
+	 *
+	 * We seem to get an unstable or solid color picture at 200MHz.
+	 * Not sure what's wrong. For now use 200MHz only when all pipes
+	 * are off.
+	 */
+	if (!IS_CHERRYVIEW(dev_priv) &&
+	    max_pixclk > freq_320*limit/100)
+		return 400000;
+	else if (max_pixclk > 266667*limit/100)
+		return freq_320;
+	else if (max_pixclk > 0)
+		return 266667;
+	else
+		return 200000;
+}
+
+static int broxton_calc_cdclk(struct drm_i915_private *dev_priv,
+			      int max_pixclk)
+{
+	/*
+	 * FIXME:
+	 * - remove the guardband, it's not needed on BXT
+	 * - set 19.2MHz bypass frequency if there are no active pipes
+	 */
+	if (max_pixclk > 576000*9/10)
+		return 624000;
+	else if (max_pixclk > 384000*9/10)
+		return 576000;
+	else if (max_pixclk > 288000*9/10)
+		return 384000;
+	else if (max_pixclk > 144000*9/10)
+		return 288000;
+	else
+		return 144000;
+}
+
+/* Compute the max pixel clock for new configuration. */
+static int intel_mode_max_pixclk(struct drm_device *dev,
+				 struct drm_atomic_state *state)
+{
+	struct intel_atomic_state *intel_state = to_intel_atomic_state(state);
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct drm_crtc *crtc;
+	struct drm_crtc_state *crtc_state;
+	unsigned max_pixclk = 0, i;
+	enum pipe pipe;
+
+	memcpy(intel_state->min_pixclk, dev_priv->min_pixclk,
+	       sizeof(intel_state->min_pixclk));
+
+	for_each_crtc_in_state(state, crtc, crtc_state, i) {
+		int pixclk = 0;
+
+		if (crtc_state->enable)
+			pixclk = crtc_state->adjusted_mode.crtc_clock;
+
+		intel_state->min_pixclk[i] = pixclk;
+	}
+
+	for_each_pipe(dev_priv, pipe)
+		max_pixclk = max(intel_state->min_pixclk[pipe], max_pixclk);
+
+	return max_pixclk;
+}
+
+static int valleyview_modeset_calc_cdclk(struct drm_atomic_state *state)
+{
+	struct drm_device *dev = state->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	int max_pixclk = intel_mode_max_pixclk(dev, state);
+	struct intel_atomic_state *intel_state =
+		to_intel_atomic_state(state);
+
+	if (max_pixclk < 0)
+		return max_pixclk;
+
+	intel_state->cdclk = intel_state->dev_cdclk =
+		valleyview_calc_cdclk(dev_priv, max_pixclk);
+
+	if (!intel_state->active_crtcs)
+		intel_state->dev_cdclk = valleyview_calc_cdclk(dev_priv, 0);
+
+	return 0;
+}
+
+static int broxton_modeset_calc_cdclk(struct drm_atomic_state *state)
+{
+	struct drm_device *dev = state->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	int max_pixclk = intel_mode_max_pixclk(dev, state);
+	struct intel_atomic_state *intel_state =
+		to_intel_atomic_state(state);
+
+	if (max_pixclk < 0)
+		return max_pixclk;
+
+	intel_state->cdclk = intel_state->dev_cdclk =
+		broxton_calc_cdclk(dev_priv, max_pixclk);
+
+	if (!intel_state->active_crtcs)
+		intel_state->dev_cdclk = broxton_calc_cdclk(dev_priv, 0);
+
+	return 0;
+}
+
+static void vlv_program_pfi_credits(struct drm_i915_private *dev_priv)
+{
+	unsigned int credits, default_credits;
+
+	if (IS_CHERRYVIEW(dev_priv))
+		default_credits = PFI_CREDIT(12);
+	else
+		default_credits = PFI_CREDIT(8);
+
+	if (dev_priv->cdclk_freq >= dev_priv->czclk_freq) {
+		/* CHV suggested value is 31 or 63 */
+		if (IS_CHERRYVIEW(dev_priv))
+			credits = PFI_CREDIT_63;
+		else
+			credits = PFI_CREDIT(15);
+	} else {
+		credits = default_credits;
+	}
+
+	/*
+	 * WA - write default credits before re-programming
+	 * FIXME: should we also set the resend bit here?
+	 */
+	I915_WRITE(GCI_CONTROL, VGA_FAST_MODE_DISABLE |
+		   default_credits);
+
+	I915_WRITE(GCI_CONTROL, VGA_FAST_MODE_DISABLE |
+		   credits | PFI_CREDIT_RESEND);
+
+	/*
+	 * FIXME is this guaranteed to clear
+	 * immediately or should we poll for it?
+	 */
+	WARN_ON(I915_READ(GCI_CONTROL) & PFI_CREDIT_RESEND);
+}
+
+static void valleyview_modeset_commit_cdclk(struct drm_atomic_state *old_state)
+{
+	struct drm_device *dev = old_state->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_atomic_state *old_intel_state =
+		to_intel_atomic_state(old_state);
+	unsigned req_cdclk = old_intel_state->dev_cdclk;
+
+	/*
+	 * FIXME: We can end up here with all power domains off, yet
+	 * with a CDCLK frequency other than the minimum. To account
+	 * for this take the PIPE-A power domain, which covers the HW
+	 * blocks needed for the following programming. This can be
+	 * removed once it's guaranteed that we get here either with
+	 * the minimum CDCLK set, or the required power domains
+	 * enabled.
+	 */
+	intel_display_power_get(dev_priv, POWER_DOMAIN_PIPE_A);
+
+	if (IS_CHERRYVIEW(dev))
+		cherryview_set_cdclk(dev, req_cdclk);
+	else
+		valleyview_set_cdclk(dev, req_cdclk);
+
+	vlv_program_pfi_credits(dev_priv);
+
+	intel_display_power_put(dev_priv, POWER_DOMAIN_PIPE_A);
+}
+
+static void valleyview_crtc_enable(struct drm_crtc *crtc)
+{
+	struct drm_device *dev = crtc->dev;
+	struct drm_i915_private *dev_priv = to_i915(dev);
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	struct intel_encoder *encoder;
+	struct intel_crtc_state *pipe_config =
+		to_intel_crtc_state(crtc->state);
+	int pipe = intel_crtc->pipe;
+
+	if (WARN_ON(intel_crtc->active))
+		return;
+
+	if (intel_crtc->config->has_dp_encoder)
+		intel_dp_set_m_n(intel_crtc, M1_N1);
+
+	intel_set_pipe_timings(intel_crtc);
+	intel_set_pipe_src_size(intel_crtc);
+
+	if (IS_CHERRYVIEW(dev) && pipe == PIPE_B) {
+		struct drm_i915_private *dev_priv = dev->dev_private;
+
+		I915_WRITE(CHV_BLEND(pipe), CHV_BLEND_LEGACY);
+		I915_WRITE(CHV_CANVAS(pipe), 0);
+	}
+
+	i9xx_set_pipeconf(intel_crtc);
+
+	intel_crtc->active = true;
+
+	intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, true);
+
+	for_each_encoder_on_crtc(dev, crtc, encoder)
+		if (encoder->pre_pll_enable)
+			encoder->pre_pll_enable(encoder);
+
+	if (IS_CHERRYVIEW(dev)) {
+		chv_prepare_pll(intel_crtc, intel_crtc->config);
+		chv_enable_pll(intel_crtc, intel_crtc->config);
+	} else {
+		vlv_prepare_pll(intel_crtc, intel_crtc->config);
+		vlv_enable_pll(intel_crtc, intel_crtc->config);
+	}
+
+	for_each_encoder_on_crtc(dev, crtc, encoder)
+		if (encoder->pre_enable)
+			encoder->pre_enable(encoder);
+
+	i9xx_pfit_enable(intel_crtc);
+
+	intel_color_load_luts(&pipe_config->base);
+
+	intel_update_watermarks(crtc);
+	intel_enable_pipe(intel_crtc);
+
+	assert_vblank_disabled(crtc);
+	drm_crtc_vblank_on(crtc);
+
+	for_each_encoder_on_crtc(dev, crtc, encoder)
+		encoder->enable(encoder);
+}
+
+static void i9xx_set_pll_dividers(struct intel_crtc *crtc)
+{
+	struct drm_device *dev = crtc->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	I915_WRITE(FP0(crtc->pipe), crtc->config->dpll_hw_state.fp0);
+	I915_WRITE(FP1(crtc->pipe), crtc->config->dpll_hw_state.fp1);
+}
+
+static void i9xx_crtc_enable(struct drm_crtc *crtc)
+{
+	struct drm_device *dev = crtc->dev;
+	struct drm_i915_private *dev_priv = to_i915(dev);
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	struct intel_encoder *encoder;
+	struct intel_crtc_state *pipe_config =
+		to_intel_crtc_state(crtc->state);
+	enum pipe pipe = intel_crtc->pipe;
+
+	if (WARN_ON(intel_crtc->active))
+		return;
+
+	i9xx_set_pll_dividers(intel_crtc);
+
+	if (intel_crtc->config->has_dp_encoder)
+		intel_dp_set_m_n(intel_crtc, M1_N1);
+
+	intel_set_pipe_timings(intel_crtc);
+	intel_set_pipe_src_size(intel_crtc);
+
+	i9xx_set_pipeconf(intel_crtc);
+
+	intel_crtc->active = true;
+
+	if (!IS_GEN2(dev))
+		intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, true);
+
+	for_each_encoder_on_crtc(dev, crtc, encoder)
+		if (encoder->pre_enable)
+			encoder->pre_enable(encoder);
+
+	i9xx_enable_pll(intel_crtc);
+
+	i9xx_pfit_enable(intel_crtc);
+
+	intel_color_load_luts(&pipe_config->base);
+
+	intel_update_watermarks(crtc);
+	intel_enable_pipe(intel_crtc);
+
+	assert_vblank_disabled(crtc);
+	drm_crtc_vblank_on(crtc);
+
+	for_each_encoder_on_crtc(dev, crtc, encoder)
+		encoder->enable(encoder);
+}
+
+static void i9xx_pfit_disable(struct intel_crtc *crtc)
+{
+	struct drm_device *dev = crtc->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	if (!crtc->config->gmch_pfit.control)
+		return;
+
+	assert_pipe_disabled(dev_priv, crtc->pipe);
+
+	DRM_DEBUG_DRIVER("disabling pfit, current: 0x%08x\n",
+			 I915_READ(PFIT_CONTROL));
+	I915_WRITE(PFIT_CONTROL, 0);
+}
+
+static void i9xx_crtc_disable(struct drm_crtc *crtc)
+{
+	struct drm_device *dev = crtc->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	struct intel_encoder *encoder;
+	int pipe = intel_crtc->pipe;
+
+	/*
+	 * On gen2 planes are double buffered but the pipe isn't, so we must
+	 * wait for planes to fully turn off before disabling the pipe.
+	 */
+	if (IS_GEN2(dev))
+		intel_wait_for_vblank(dev, pipe);
+
+	for_each_encoder_on_crtc(dev, crtc, encoder)
+		encoder->disable(encoder);
+
+	drm_crtc_vblank_off(crtc);
+	assert_vblank_disabled(crtc);
+
+	intel_disable_pipe(intel_crtc);
+
+	i9xx_pfit_disable(intel_crtc);
+
+	for_each_encoder_on_crtc(dev, crtc, encoder)
+		if (encoder->post_disable)
+			encoder->post_disable(encoder);
+
+	if (!intel_crtc->config->has_dsi_encoder) {
+		if (IS_CHERRYVIEW(dev))
+			chv_disable_pll(dev_priv, pipe);
+		else if (IS_VALLEYVIEW(dev))
+			vlv_disable_pll(dev_priv, pipe);
+		else
+			i9xx_disable_pll(intel_crtc);
+	}
+
+	for_each_encoder_on_crtc(dev, crtc, encoder)
+		if (encoder->post_pll_disable)
+			encoder->post_pll_disable(encoder);
+
+	if (!IS_GEN2(dev))
+		intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, false);
+}
+
+static void intel_crtc_disable_noatomic(struct drm_crtc *crtc)
+{
+	struct intel_encoder *encoder;
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	struct drm_i915_private *dev_priv = to_i915(crtc->dev);
+	enum intel_display_power_domain domain;
+	unsigned long domains;
+
+	if (!intel_crtc->active)
+		return;
+
+	if (to_intel_plane_state(crtc->primary->state)->visible) {
+		WARN_ON(intel_crtc->unpin_work);
+
+		intel_pre_disable_primary_noatomic(crtc);
+
+		intel_crtc_disable_planes(crtc, 1 << drm_plane_index(crtc->primary));
+		to_intel_plane_state(crtc->primary->state)->visible = false;
+	}
+
+	dev_priv->display.crtc_disable(crtc);
+
+	DRM_DEBUG_KMS("[CRTC:%d] hw state adjusted, was enabled, now disabled\n",
+		      crtc->base.id);
+
+	WARN_ON(drm_atomic_set_mode_for_crtc(crtc->state, NULL) < 0);
+	crtc->state->active = false;
+	intel_crtc->active = false;
+	crtc->enabled = false;
+	crtc->state->connector_mask = 0;
+	crtc->state->encoder_mask = 0;
+
+	for_each_encoder_on_crtc(crtc->dev, crtc, encoder)
+		encoder->base.crtc = NULL;
+
+	intel_fbc_disable(intel_crtc);
+	intel_update_watermarks(crtc);
+	intel_disable_shared_dpll(intel_crtc);
+
+	domains = intel_crtc->enabled_power_domains;
+	for_each_power_domain(domain, domains)
+		intel_display_power_put(dev_priv, domain);
+	intel_crtc->enabled_power_domains = 0;
+
+	dev_priv->active_crtcs &= ~(1 << intel_crtc->pipe);
+	dev_priv->min_pixclk[intel_crtc->pipe] = 0;
+}
+
+/*
+ * turn all crtc's off, but do not adjust state
+ * This has to be paired with a call to intel_modeset_setup_hw_state.
+ */
+int intel_display_suspend(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = to_i915(dev);
+	struct drm_atomic_state *state;
+	int ret;
+
+	state = drm_atomic_helper_suspend(dev);
+	ret = PTR_ERR_OR_ZERO(state);
+	if (ret)
+		DRM_ERROR("Suspending crtc's failed with %i\n", ret);
+	else
+		dev_priv->modeset_restore_state = state;
+	return ret;
+}
+
+void intel_encoder_destroy(struct drm_encoder *encoder)
+{
+	struct intel_encoder *intel_encoder = to_intel_encoder(encoder);
+
+	drm_encoder_cleanup(encoder);
+	kfree(intel_encoder);
+}
+
+/* Cross check the actual hw state with our own modeset state tracking (and it's
+ * internal consistency). */
+static void intel_connector_verify_state(struct intel_connector *connector)
+{
+	struct drm_crtc *crtc = connector->base.state->crtc;
+
+	DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
+		      connector->base.base.id,
+		      connector->base.name);
+
+	if (connector->get_hw_state(connector)) {
+		struct intel_encoder *encoder = connector->encoder;
+		struct drm_connector_state *conn_state = connector->base.state;
+
+		I915_STATE_WARN(!crtc,
+			 "connector enabled without attached crtc\n");
+
+		if (!crtc)
+			return;
+
+		I915_STATE_WARN(!crtc->state->active,
+		      "connector is active, but attached crtc isn't\n");
+
+		if (!encoder || encoder->type == INTEL_OUTPUT_DP_MST)
+			return;
+
+		I915_STATE_WARN(conn_state->best_encoder != &encoder->base,
+			"atomic encoder doesn't match attached encoder\n");
+
+		I915_STATE_WARN(conn_state->crtc != encoder->base.crtc,
+			"attached encoder crtc differs from connector crtc\n");
+	} else {
+		I915_STATE_WARN(crtc && crtc->state->active,
+			"attached crtc is active, but connector isn't\n");
+		I915_STATE_WARN(!crtc && connector->base.state->best_encoder,
+			"best encoder set without crtc!\n");
+	}
+}
+
+int intel_connector_init(struct intel_connector *connector)
+{
+	drm_atomic_helper_connector_reset(&connector->base);
+
+	if (!connector->base.state)
+		return -ENOMEM;
+
+	return 0;
+}
+
+struct intel_connector *intel_connector_alloc(void)
+{
+	struct intel_connector *connector;
+
+	connector = kzalloc(sizeof *connector, GFP_KERNEL);
+	if (!connector)
+		return NULL;
+
+	if (intel_connector_init(connector) < 0) {
+		kfree(connector);
+		return NULL;
+	}
+
+	return connector;
+}
+
+/* Simple connector->get_hw_state implementation for encoders that support only
+ * one connector and no cloning and hence the encoder state determines the state
+ * of the connector. */
+bool intel_connector_get_hw_state(struct intel_connector *connector)
+{
+	enum pipe pipe = 0;
+	struct intel_encoder *encoder = connector->encoder;
+
+	return encoder->get_hw_state(encoder, &pipe);
+}
+
+static int pipe_required_fdi_lanes(struct intel_crtc_state *crtc_state)
+{
+	if (crtc_state->base.enable && crtc_state->has_pch_encoder)
+		return crtc_state->fdi_lanes;
+
+	return 0;
+}
+
+static int ironlake_check_fdi_lanes(struct drm_device *dev, enum pipe pipe,
+				     struct intel_crtc_state *pipe_config)
+{
+	struct drm_atomic_state *state = pipe_config->base.state;
+	struct intel_crtc *other_crtc;
+	struct intel_crtc_state *other_crtc_state;
+
+	DRM_DEBUG_KMS("checking fdi config on pipe %c, lanes %i\n",
+		      pipe_name(pipe), pipe_config->fdi_lanes);
+	if (pipe_config->fdi_lanes > 4) {
+		DRM_DEBUG_KMS("invalid fdi lane config on pipe %c: %i lanes\n",
+			      pipe_name(pipe), pipe_config->fdi_lanes);
+		return -EINVAL;
+	}
+
+	if (IS_HASWELL(dev) || IS_BROADWELL(dev)) {
+		if (pipe_config->fdi_lanes > 2) {
+			DRM_DEBUG_KMS("only 2 lanes on haswell, required: %i lanes\n",
+				      pipe_config->fdi_lanes);
+			return -EINVAL;
+		} else {
+			return 0;
+		}
+	}
+
+	if (INTEL_INFO(dev)->num_pipes == 2)
+		return 0;
+
+	/* Ivybridge 3 pipe is really complicated */
+	switch (pipe) {
+	case PIPE_A:
+		return 0;
+	case PIPE_B:
+		if (pipe_config->fdi_lanes <= 2)
+			return 0;
+
+		other_crtc = to_intel_crtc(intel_get_crtc_for_pipe(dev, PIPE_C));
+		other_crtc_state =
+			intel_atomic_get_crtc_state(state, other_crtc);
+		if (IS_ERR(other_crtc_state))
+			return PTR_ERR(other_crtc_state);
+
+		if (pipe_required_fdi_lanes(other_crtc_state) > 0) {
+			DRM_DEBUG_KMS("invalid shared fdi lane config on pipe %c: %i lanes\n",
+				      pipe_name(pipe), pipe_config->fdi_lanes);
+			return -EINVAL;
+		}
+		return 0;
+	case PIPE_C:
+		if (pipe_config->fdi_lanes > 2) {
+			DRM_DEBUG_KMS("only 2 lanes on pipe %c: required %i lanes\n",
+				      pipe_name(pipe), pipe_config->fdi_lanes);
+			return -EINVAL;
+		}
+
+		other_crtc = to_intel_crtc(intel_get_crtc_for_pipe(dev, PIPE_B));
+		other_crtc_state =
+			intel_atomic_get_crtc_state(state, other_crtc);
+		if (IS_ERR(other_crtc_state))
+			return PTR_ERR(other_crtc_state);
+
+		if (pipe_required_fdi_lanes(other_crtc_state) > 2) {
+			DRM_DEBUG_KMS("fdi link B uses too many lanes to enable link C\n");
+			return -EINVAL;
+		}
+		return 0;
+	default:
+		BUG();
+	}
+}
+
+#define RETRY 1
+static int ironlake_fdi_compute_config(struct intel_crtc *intel_crtc,
+				       struct intel_crtc_state *pipe_config)
+{
+	struct drm_device *dev = intel_crtc->base.dev;
+	const struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
+	int lane, link_bw, fdi_dotclock, ret;
+	bool needs_recompute = false;
+
+retry:
+	/* FDI is a binary signal running at ~2.7GHz, encoding
+	 * each output octet as 10 bits. The actual frequency
+	 * is stored as a divider into a 100MHz clock, and the
+	 * mode pixel clock is stored in units of 1KHz.
+	 * Hence the bw of each lane in terms of the mode signal
+	 * is:
+	 */
+	link_bw = intel_fdi_link_freq(to_i915(dev), pipe_config);
+
+	fdi_dotclock = adjusted_mode->crtc_clock;
+
+	lane = ironlake_get_lanes_required(fdi_dotclock, link_bw,
+					   pipe_config->pipe_bpp);
+
+	pipe_config->fdi_lanes = lane;
+
+	intel_link_compute_m_n(pipe_config->pipe_bpp, lane, fdi_dotclock,
+			       link_bw, &pipe_config->fdi_m_n);
+
+	ret = ironlake_check_fdi_lanes(dev, intel_crtc->pipe, pipe_config);
+	if (ret == -EINVAL && pipe_config->pipe_bpp > 6*3) {
+		pipe_config->pipe_bpp -= 2*3;
+		DRM_DEBUG_KMS("fdi link bw constraint, reducing pipe bpp to %i\n",
+			      pipe_config->pipe_bpp);
+		needs_recompute = true;
+		pipe_config->bw_constrained = true;
+
+		goto retry;
+	}
+
+	if (needs_recompute)
+		return RETRY;
+
+	return ret;
+}
+
+static bool pipe_config_supports_ips(struct drm_i915_private *dev_priv,
+				     struct intel_crtc_state *pipe_config)
+{
+	if (pipe_config->pipe_bpp > 24)
+		return false;
+
+	/* HSW can handle pixel rate up to cdclk? */
+	if (IS_HASWELL(dev_priv))
+		return true;
+
+	/*
+	 * We compare against max which means we must take
+	 * the increased cdclk requirement into account when
+	 * calculating the new cdclk.
+	 *
+	 * Should measure whether using a lower cdclk w/o IPS
+	 */
+	return ilk_pipe_pixel_rate(pipe_config) <=
+		dev_priv->max_cdclk_freq * 95 / 100;
+}
+
+static void hsw_compute_ips_config(struct intel_crtc *crtc,
+				   struct intel_crtc_state *pipe_config)
+{
+	struct drm_device *dev = crtc->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	pipe_config->ips_enabled = i915.enable_ips &&
+		hsw_crtc_supports_ips(crtc) &&
+		pipe_config_supports_ips(dev_priv, pipe_config);
+}
+
+static bool intel_crtc_supports_double_wide(const struct intel_crtc *crtc)
+{
+	const struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
+
+	/* GDG double wide on either pipe, otherwise pipe A only */
+	return INTEL_INFO(dev_priv)->gen < 4 &&
+		(crtc->pipe == PIPE_A || IS_I915G(dev_priv));
+}
+
+static int intel_crtc_compute_config(struct intel_crtc *crtc,
+				     struct intel_crtc_state *pipe_config)
+{
+	struct drm_device *dev = crtc->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	const struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
+
+	/* FIXME should check pixel clock limits on all platforms */
+	if (INTEL_INFO(dev)->gen < 4) {
+		int clock_limit = dev_priv->max_cdclk_freq * 9 / 10;
+
+		/*
+		 * Enable double wide mode when the dot clock
+		 * is > 90% of the (display) core speed.
+		 */
+		if (intel_crtc_supports_double_wide(crtc) &&
+		    adjusted_mode->crtc_clock > clock_limit) {
+			clock_limit *= 2;
+			pipe_config->double_wide = true;
+		}
+
+		if (adjusted_mode->crtc_clock > clock_limit) {
+			DRM_DEBUG_KMS("requested pixel clock (%d kHz) too high (max: %d kHz, double wide: %s)\n",
+				      adjusted_mode->crtc_clock, clock_limit,
+				      yesno(pipe_config->double_wide));
+			return -EINVAL;
+		}
+	}
+
+	/*
+	 * Pipe horizontal size must be even in:
+	 * - DVO ganged mode
+	 * - LVDS dual channel mode
+	 * - Double wide pipe
+	 */
+	if ((intel_pipe_will_have_type(pipe_config, INTEL_OUTPUT_LVDS) &&
+	     intel_is_dual_link_lvds(dev)) || pipe_config->double_wide)
+		pipe_config->pipe_src_w &= ~1;
+
+	/* Cantiga+ cannot handle modes with a hsync front porch of 0.
+	 * WaPruneModeWithIncorrectHsyncOffset:ctg,elk,ilk,snb,ivb,vlv,hsw.
+	 */
+	if ((INTEL_INFO(dev)->gen > 4 || IS_G4X(dev)) &&
+		adjusted_mode->crtc_hsync_start == adjusted_mode->crtc_hdisplay)
+		return -EINVAL;
+
+	if (HAS_IPS(dev))
+		hsw_compute_ips_config(crtc, pipe_config);
+
+	if (pipe_config->has_pch_encoder)
+		return ironlake_fdi_compute_config(crtc, pipe_config);
+
+	return 0;
+}
+
+static int skylake_get_display_clock_speed(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = to_i915(dev);
+	uint32_t lcpll1 = I915_READ(LCPLL1_CTL);
+	uint32_t cdctl = I915_READ(CDCLK_CTL);
+	uint32_t linkrate;
+
+	if (!(lcpll1 & LCPLL_PLL_ENABLE))
+		return 24000; /* 24MHz is the cd freq with NSSC ref */
+
+	if ((cdctl & CDCLK_FREQ_SEL_MASK) == CDCLK_FREQ_540)
+		return 540000;
+
+	linkrate = (I915_READ(DPLL_CTRL1) &
+		    DPLL_CTRL1_LINK_RATE_MASK(SKL_DPLL0)) >> 1;
+
+	if (linkrate == DPLL_CTRL1_LINK_RATE_2160 ||
+	    linkrate == DPLL_CTRL1_LINK_RATE_1080) {
+		/* vco 8640 */
+		switch (cdctl & CDCLK_FREQ_SEL_MASK) {
+		case CDCLK_FREQ_450_432:
+			return 432000;
+		case CDCLK_FREQ_337_308:
+			return 308570;
+		case CDCLK_FREQ_675_617:
+			return 617140;
+		default:
+			WARN(1, "Unknown cd freq selection\n");
+		}
+	} else {
+		/* vco 8100 */
+		switch (cdctl & CDCLK_FREQ_SEL_MASK) {
+		case CDCLK_FREQ_450_432:
+			return 450000;
+		case CDCLK_FREQ_337_308:
+			return 337500;
+		case CDCLK_FREQ_675_617:
+			return 675000;
+		default:
+			WARN(1, "Unknown cd freq selection\n");
+		}
+	}
+
+	/* error case, do as if DPLL0 isn't enabled */
+	return 24000;
+}
+
+static int broxton_get_display_clock_speed(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = to_i915(dev);
+	uint32_t cdctl = I915_READ(CDCLK_CTL);
+	uint32_t pll_ratio = I915_READ(BXT_DE_PLL_CTL) & BXT_DE_PLL_RATIO_MASK;
+	uint32_t pll_enab = I915_READ(BXT_DE_PLL_ENABLE);
+	int cdclk;
+
+	if (!(pll_enab & BXT_DE_PLL_PLL_ENABLE))
+		return 19200;
+
+	cdclk = 19200 * pll_ratio / 2;
+
+	switch (cdctl & BXT_CDCLK_CD2X_DIV_SEL_MASK) {
+	case BXT_CDCLK_CD2X_DIV_SEL_1:
+		return cdclk;  /* 576MHz or 624MHz */
+	case BXT_CDCLK_CD2X_DIV_SEL_1_5:
+		return cdclk * 2 / 3; /* 384MHz */
+	case BXT_CDCLK_CD2X_DIV_SEL_2:
+		return cdclk / 2; /* 288MHz */
+	case BXT_CDCLK_CD2X_DIV_SEL_4:
+		return cdclk / 4; /* 144MHz */
+	}
+
+	/* error case, do as if DE PLL isn't enabled */
+	return 19200;
+}
+
+static int broadwell_get_display_clock_speed(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	uint32_t lcpll = I915_READ(LCPLL_CTL);
+	uint32_t freq = lcpll & LCPLL_CLK_FREQ_MASK;
+
+	if (lcpll & LCPLL_CD_SOURCE_FCLK)
+		return 800000;
+	else if (I915_READ(FUSE_STRAP) & HSW_CDCLK_LIMIT)
+		return 450000;
+	else if (freq == LCPLL_CLK_FREQ_450)
+		return 450000;
+	else if (freq == LCPLL_CLK_FREQ_54O_BDW)
+		return 540000;
+	else if (freq == LCPLL_CLK_FREQ_337_5_BDW)
+		return 337500;
+	else
+		return 675000;
+}
+
+static int haswell_get_display_clock_speed(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	uint32_t lcpll = I915_READ(LCPLL_CTL);
+	uint32_t freq = lcpll & LCPLL_CLK_FREQ_MASK;
+
+	if (lcpll & LCPLL_CD_SOURCE_FCLK)
+		return 800000;
+	else if (I915_READ(FUSE_STRAP) & HSW_CDCLK_LIMIT)
+		return 450000;
+	else if (freq == LCPLL_CLK_FREQ_450)
+		return 450000;
+	else if (IS_HSW_ULT(dev))
+		return 337500;
+	else
+		return 540000;
+}
+
+static int valleyview_get_display_clock_speed(struct drm_device *dev)
+{
+	return vlv_get_cck_clock_hpll(to_i915(dev), "cdclk",
+				      CCK_DISPLAY_CLOCK_CONTROL);
+}
+
+static int ilk_get_display_clock_speed(struct drm_device *dev)
+{
+	return 450000;
+}
+
+static int i945_get_display_clock_speed(struct drm_device *dev)
+{
+	return 400000;
+}
+
+static int i915_get_display_clock_speed(struct drm_device *dev)
+{
+	return 333333;
+}
+
+static int i9xx_misc_get_display_clock_speed(struct drm_device *dev)
+{
+	return 200000;
+}
+
+static int pnv_get_display_clock_speed(struct drm_device *dev)
+{
+	u16 gcfgc = 0;
+
+	pci_read_config_word(dev->pdev, GCFGC, &gcfgc);
+
+	switch (gcfgc & GC_DISPLAY_CLOCK_MASK) {
+	case GC_DISPLAY_CLOCK_267_MHZ_PNV:
+		return 266667;
+	case GC_DISPLAY_CLOCK_333_MHZ_PNV:
+		return 333333;
+	case GC_DISPLAY_CLOCK_444_MHZ_PNV:
+		return 444444;
+	case GC_DISPLAY_CLOCK_200_MHZ_PNV:
+		return 200000;
+	default:
+		DRM_ERROR("Unknown pnv display core clock 0x%04x\n", gcfgc);
+	case GC_DISPLAY_CLOCK_133_MHZ_PNV:
+		return 133333;
+	case GC_DISPLAY_CLOCK_167_MHZ_PNV:
+		return 166667;
+	}
+}
+
+static int i915gm_get_display_clock_speed(struct drm_device *dev)
+{
+	u16 gcfgc = 0;
+
+	pci_read_config_word(dev->pdev, GCFGC, &gcfgc);
+
+	if (gcfgc & GC_LOW_FREQUENCY_ENABLE)
+		return 133333;
+	else {
+		switch (gcfgc & GC_DISPLAY_CLOCK_MASK) {
+		case GC_DISPLAY_CLOCK_333_MHZ:
+			return 333333;
+		default:
+		case GC_DISPLAY_CLOCK_190_200_MHZ:
+			return 190000;
+		}
+	}
+}
+
+static int i865_get_display_clock_speed(struct drm_device *dev)
+{
+	return 266667;
+}
+
+static int i85x_get_display_clock_speed(struct drm_device *dev)
+{
+	u16 hpllcc = 0;
+
+	/*
+	 * 852GM/852GMV only supports 133 MHz and the HPLLCC
+	 * encoding is different :(
+	 * FIXME is this the right way to detect 852GM/852GMV?
+	 */
+	if (dev->pdev->revision == 0x1)
+		return 133333;
+
+	pci_bus_read_config_word(dev->pdev->bus,
+				 PCI_DEVFN(0, 3), HPLLCC, &hpllcc);
+
+	/* Assume that the hardware is in the high speed state.  This
+	 * should be the default.
+	 */
+	switch (hpllcc & GC_CLOCK_CONTROL_MASK) {
+	case GC_CLOCK_133_200:
+	case GC_CLOCK_133_200_2:
+	case GC_CLOCK_100_200:
+		return 200000;
+	case GC_CLOCK_166_250:
+		return 250000;
+	case GC_CLOCK_100_133:
+		return 133333;
+	case GC_CLOCK_133_266:
+	case GC_CLOCK_133_266_2:
+	case GC_CLOCK_166_266:
+		return 266667;
+	}
+
+	/* Shouldn't happen */
+	return 0;
+}
+
+static int i830_get_display_clock_speed(struct drm_device *dev)
+{
+	return 133333;
+}
+
+static unsigned int intel_hpll_vco(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	static const unsigned int blb_vco[8] = {
+		[0] = 3200000,
+		[1] = 4000000,
+		[2] = 5333333,
+		[3] = 4800000,
+		[4] = 6400000,
+	};
+	static const unsigned int pnv_vco[8] = {
+		[0] = 3200000,
+		[1] = 4000000,
+		[2] = 5333333,
+		[3] = 4800000,
+		[4] = 2666667,
+	};
+	static const unsigned int cl_vco[8] = {
+		[0] = 3200000,
+		[1] = 4000000,
+		[2] = 5333333,
+		[3] = 6400000,
+		[4] = 3333333,
+		[5] = 3566667,
+		[6] = 4266667,
+	};
+	static const unsigned int elk_vco[8] = {
+		[0] = 3200000,
+		[1] = 4000000,
+		[2] = 5333333,
+		[3] = 4800000,
+	};
+	static const unsigned int ctg_vco[8] = {
+		[0] = 3200000,
+		[1] = 4000000,
+		[2] = 5333333,
+		[3] = 6400000,
+		[4] = 2666667,
+		[5] = 4266667,
+	};
+	const unsigned int *vco_table;
+	unsigned int vco;
+	uint8_t tmp = 0;
+
+	/* FIXME other chipsets? */
+	if (IS_GM45(dev))
+		vco_table = ctg_vco;
+	else if (IS_G4X(dev))
+		vco_table = elk_vco;
+	else if (IS_CRESTLINE(dev))
+		vco_table = cl_vco;
+	else if (IS_PINEVIEW(dev))
+		vco_table = pnv_vco;
+	else if (IS_G33(dev))
+		vco_table = blb_vco;
+	else
+		return 0;
+
+	tmp = I915_READ(IS_MOBILE(dev) ? HPLLVCO_MOBILE : HPLLVCO);
+
+	vco = vco_table[tmp & 0x7];
+	if (vco == 0)
+		DRM_ERROR("Bad HPLL VCO (HPLLVCO=0x%02x)\n", tmp);
+	else
+		DRM_DEBUG_KMS("HPLL VCO %u kHz\n", vco);
+
+	return vco;
+}
+
+static int gm45_get_display_clock_speed(struct drm_device *dev)
+{
+	unsigned int cdclk_sel, vco = intel_hpll_vco(dev);
+	uint16_t tmp = 0;
+
+	pci_read_config_word(dev->pdev, GCFGC, &tmp);
+
+	cdclk_sel = (tmp >> 12) & 0x1;
+
+	switch (vco) {
+	case 2666667:
+	case 4000000:
+	case 5333333:
+		return cdclk_sel ? 333333 : 222222;
+	case 3200000:
+		return cdclk_sel ? 320000 : 228571;
+	default:
+		DRM_ERROR("Unable to determine CDCLK. HPLL VCO=%u, CFGC=0x%04x\n", vco, tmp);
+		return 222222;
+	}
+}
+
+static int i965gm_get_display_clock_speed(struct drm_device *dev)
+{
+	static const uint8_t div_3200[] = { 16, 10,  8 };
+	static const uint8_t div_4000[] = { 20, 12, 10 };
+	static const uint8_t div_5333[] = { 24, 16, 14 };
+	const uint8_t *div_table;
+	unsigned int cdclk_sel, vco = intel_hpll_vco(dev);
+	uint16_t tmp = 0;
+
+	pci_read_config_word(dev->pdev, GCFGC, &tmp);
+
+	cdclk_sel = ((tmp >> 8) & 0x1f) - 1;
+
+	if (cdclk_sel >= ARRAY_SIZE(div_3200))
+		goto fail;
+
+	switch (vco) {
+	case 3200000:
+		div_table = div_3200;
+		break;
+	case 4000000:
+		div_table = div_4000;
+		break;
+	case 5333333:
+		div_table = div_5333;
+		break;
+	default:
+		goto fail;
+	}
+
+	return DIV_ROUND_CLOSEST(vco, div_table[cdclk_sel]);
+
+fail:
+	DRM_ERROR("Unable to determine CDCLK. HPLL VCO=%u kHz, CFGC=0x%04x\n", vco, tmp);
+	return 200000;
+}
+
+static int g33_get_display_clock_speed(struct drm_device *dev)
+{
+	static const uint8_t div_3200[] = { 12, 10,  8,  7, 5, 16 };
+	static const uint8_t div_4000[] = { 14, 12, 10,  8, 6, 20 };
+	static const uint8_t div_4800[] = { 20, 14, 12, 10, 8, 24 };
+	static const uint8_t div_5333[] = { 20, 16, 12, 12, 8, 28 };
+	const uint8_t *div_table;
+	unsigned int cdclk_sel, vco = intel_hpll_vco(dev);
+	uint16_t tmp = 0;
+
+	pci_read_config_word(dev->pdev, GCFGC, &tmp);
+
+	cdclk_sel = (tmp >> 4) & 0x7;
+
+	if (cdclk_sel >= ARRAY_SIZE(div_3200))
+		goto fail;
+
+	switch (vco) {
+	case 3200000:
+		div_table = div_3200;
+		break;
+	case 4000000:
+		div_table = div_4000;
+		break;
+	case 4800000:
+		div_table = div_4800;
+		break;
+	case 5333333:
+		div_table = div_5333;
+		break;
+	default:
+		goto fail;
+	}
+
+	return DIV_ROUND_CLOSEST(vco, div_table[cdclk_sel]);
+
+fail:
+	DRM_ERROR("Unable to determine CDCLK. HPLL VCO=%u kHz, CFGC=0x%08x\n", vco, tmp);
+	return 190476;
+}
+
+static void
+intel_reduce_m_n_ratio(uint32_t *num, uint32_t *den)
+{
+	while (*num > DATA_LINK_M_N_MASK ||
+	       *den > DATA_LINK_M_N_MASK) {
+		*num >>= 1;
+		*den >>= 1;
+	}
+}
+
+static void compute_m_n(unsigned int m, unsigned int n,
+			uint32_t *ret_m, uint32_t *ret_n)
+{
+	*ret_n = min_t(unsigned int, roundup_pow_of_two(n), DATA_LINK_N_MAX);
+	*ret_m = div_u64((uint64_t) m * *ret_n, n);
+	intel_reduce_m_n_ratio(ret_m, ret_n);
+}
+
+void
+intel_link_compute_m_n(int bits_per_pixel, int nlanes,
+		       int pixel_clock, int link_clock,
+		       struct intel_link_m_n *m_n)
+{
+	m_n->tu = 64;
+
+	compute_m_n(bits_per_pixel * pixel_clock,
+		    link_clock * nlanes * 8,
+		    &m_n->gmch_m, &m_n->gmch_n);
+
+	compute_m_n(pixel_clock, link_clock,
+		    &m_n->link_m, &m_n->link_n);
+}
+
+static inline bool intel_panel_use_ssc(struct drm_i915_private *dev_priv)
+{
+	if (i915.panel_use_ssc >= 0)
+		return i915.panel_use_ssc != 0;
+	return dev_priv->vbt.lvds_use_ssc
+		&& !(dev_priv->quirks & QUIRK_LVDS_SSC_DISABLE);
+}
+
+static uint32_t pnv_dpll_compute_fp(struct dpll *dpll)
+{
+	return (1 << dpll->n) << 16 | dpll->m2;
+}
+
+static uint32_t i9xx_dpll_compute_fp(struct dpll *dpll)
+{
+	return dpll->n << 16 | dpll->m1 << 8 | dpll->m2;
+}
+
+static void i9xx_update_pll_dividers(struct intel_crtc *crtc,
+				     struct intel_crtc_state *crtc_state,
+				     intel_clock_t *reduced_clock)
+{
+	struct drm_device *dev = crtc->base.dev;
+	u32 fp, fp2 = 0;
+
+	if (IS_PINEVIEW(dev)) {
+		fp = pnv_dpll_compute_fp(&crtc_state->dpll);
+		if (reduced_clock)
+			fp2 = pnv_dpll_compute_fp(reduced_clock);
+	} else {
+		fp = i9xx_dpll_compute_fp(&crtc_state->dpll);
+		if (reduced_clock)
+			fp2 = i9xx_dpll_compute_fp(reduced_clock);
+	}
+
+	crtc_state->dpll_hw_state.fp0 = fp;
+
+	crtc->lowfreq_avail = false;
+	if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_LVDS) &&
+	    reduced_clock) {
+		crtc_state->dpll_hw_state.fp1 = fp2;
+		crtc->lowfreq_avail = true;
+	} else {
+		crtc_state->dpll_hw_state.fp1 = fp;
+	}
+}
+
+static void vlv_pllb_recal_opamp(struct drm_i915_private *dev_priv, enum pipe
+		pipe)
+{
+	u32 reg_val;
+
+	/*
+	 * PLLB opamp always calibrates to max value of 0x3f, force enable it
+	 * and set it to a reasonable value instead.
+	 */
+	reg_val = vlv_dpio_read(dev_priv, pipe, VLV_PLL_DW9(1));
+	reg_val &= 0xffffff00;
+	reg_val |= 0x00000030;
+	vlv_dpio_write(dev_priv, pipe, VLV_PLL_DW9(1), reg_val);
+
+	reg_val = vlv_dpio_read(dev_priv, pipe, VLV_REF_DW13);
+	reg_val &= 0x8cffffff;
+	reg_val = 0x8c000000;
+	vlv_dpio_write(dev_priv, pipe, VLV_REF_DW13, reg_val);
+
+	reg_val = vlv_dpio_read(dev_priv, pipe, VLV_PLL_DW9(1));
+	reg_val &= 0xffffff00;
+	vlv_dpio_write(dev_priv, pipe, VLV_PLL_DW9(1), reg_val);
+
+	reg_val = vlv_dpio_read(dev_priv, pipe, VLV_REF_DW13);
+	reg_val &= 0x00ffffff;
+	reg_val |= 0xb0000000;
+	vlv_dpio_write(dev_priv, pipe, VLV_REF_DW13, reg_val);
+}
+
+static void intel_pch_transcoder_set_m_n(struct intel_crtc *crtc,
+					 struct intel_link_m_n *m_n)
+{
+	struct drm_device *dev = crtc->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	int pipe = crtc->pipe;
+
+	I915_WRITE(PCH_TRANS_DATA_M1(pipe), TU_SIZE(m_n->tu) | m_n->gmch_m);
+	I915_WRITE(PCH_TRANS_DATA_N1(pipe), m_n->gmch_n);
+	I915_WRITE(PCH_TRANS_LINK_M1(pipe), m_n->link_m);
+	I915_WRITE(PCH_TRANS_LINK_N1(pipe), m_n->link_n);
+}
+
+static void intel_cpu_transcoder_set_m_n(struct intel_crtc *crtc,
+					 struct intel_link_m_n *m_n,
+					 struct intel_link_m_n *m2_n2)
+{
+	struct drm_device *dev = crtc->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	int pipe = crtc->pipe;
+	enum transcoder transcoder = crtc->config->cpu_transcoder;
+
+	if (INTEL_INFO(dev)->gen >= 5) {
+		I915_WRITE(PIPE_DATA_M1(transcoder), TU_SIZE(m_n->tu) | m_n->gmch_m);
+		I915_WRITE(PIPE_DATA_N1(transcoder), m_n->gmch_n);
+		I915_WRITE(PIPE_LINK_M1(transcoder), m_n->link_m);
+		I915_WRITE(PIPE_LINK_N1(transcoder), m_n->link_n);
+		/* M2_N2 registers to be set only for gen < 8 (M2_N2 available
+		 * for gen < 8) and if DRRS is supported (to make sure the
+		 * registers are not unnecessarily accessed).
+		 */
+		if (m2_n2 && (IS_CHERRYVIEW(dev) || INTEL_INFO(dev)->gen < 8) &&
+			crtc->config->has_drrs) {
+			I915_WRITE(PIPE_DATA_M2(transcoder),
+					TU_SIZE(m2_n2->tu) | m2_n2->gmch_m);
+			I915_WRITE(PIPE_DATA_N2(transcoder), m2_n2->gmch_n);
+			I915_WRITE(PIPE_LINK_M2(transcoder), m2_n2->link_m);
+			I915_WRITE(PIPE_LINK_N2(transcoder), m2_n2->link_n);
+		}
+	} else {
+		I915_WRITE(PIPE_DATA_M_G4X(pipe), TU_SIZE(m_n->tu) | m_n->gmch_m);
+		I915_WRITE(PIPE_DATA_N_G4X(pipe), m_n->gmch_n);
+		I915_WRITE(PIPE_LINK_M_G4X(pipe), m_n->link_m);
+		I915_WRITE(PIPE_LINK_N_G4X(pipe), m_n->link_n);
+	}
+}
+
+void intel_dp_set_m_n(struct intel_crtc *crtc, enum link_m_n_set m_n)
+{
+	struct intel_link_m_n *dp_m_n, *dp_m2_n2 = NULL;
+
+	if (m_n == M1_N1) {
+		dp_m_n = &crtc->config->dp_m_n;
+		dp_m2_n2 = &crtc->config->dp_m2_n2;
+	} else if (m_n == M2_N2) {
+
+		/*
+		 * M2_N2 registers are not supported. Hence m2_n2 divider value
+		 * needs to be programmed into M1_N1.
+		 */
+		dp_m_n = &crtc->config->dp_m2_n2;
+	} else {
+		DRM_ERROR("Unsupported divider value\n");
+		return;
+	}
+
+	if (crtc->config->has_pch_encoder)
+		intel_pch_transcoder_set_m_n(crtc, &crtc->config->dp_m_n);
+	else
+		intel_cpu_transcoder_set_m_n(crtc, dp_m_n, dp_m2_n2);
+}
+
+static void vlv_compute_dpll(struct intel_crtc *crtc,
+			     struct intel_crtc_state *pipe_config)
+{
+	pipe_config->dpll_hw_state.dpll = DPLL_INTEGRATED_REF_CLK_VLV |
+		DPLL_REF_CLK_ENABLE_VLV | DPLL_VGA_MODE_DIS;
+	if (crtc->pipe != PIPE_A)
+		pipe_config->dpll_hw_state.dpll |= DPLL_INTEGRATED_CRI_CLK_VLV;
+
+	/* DPLL not used with DSI, but still need the rest set up */
+	if (!pipe_config->has_dsi_encoder)
+		pipe_config->dpll_hw_state.dpll |= DPLL_VCO_ENABLE |
+			DPLL_EXT_BUFFER_ENABLE_VLV;
+
+	pipe_config->dpll_hw_state.dpll_md =
+		(pipe_config->pixel_multiplier - 1) << DPLL_MD_UDI_MULTIPLIER_SHIFT;
+}
+
+static void chv_compute_dpll(struct intel_crtc *crtc,
+			     struct intel_crtc_state *pipe_config)
+{
+	pipe_config->dpll_hw_state.dpll = DPLL_SSC_REF_CLK_CHV |
+		DPLL_REF_CLK_ENABLE_VLV | DPLL_VGA_MODE_DIS;
+	if (crtc->pipe != PIPE_A)
+		pipe_config->dpll_hw_state.dpll |= DPLL_INTEGRATED_CRI_CLK_VLV;
+
+	/* DPLL not used with DSI, but still need the rest set up */
+	if (!pipe_config->has_dsi_encoder)
+		pipe_config->dpll_hw_state.dpll |= DPLL_VCO_ENABLE;
+
+	pipe_config->dpll_hw_state.dpll_md =
+		(pipe_config->pixel_multiplier - 1) << DPLL_MD_UDI_MULTIPLIER_SHIFT;
+}
+
+static void vlv_prepare_pll(struct intel_crtc *crtc,
+			    const struct intel_crtc_state *pipe_config)
+{
+	struct drm_device *dev = crtc->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	enum pipe pipe = crtc->pipe;
+	u32 mdiv;
+	u32 bestn, bestm1, bestm2, bestp1, bestp2;
+	u32 coreclk, reg_val;
+
+	/* Enable Refclk */
+	I915_WRITE(DPLL(pipe),
+		   pipe_config->dpll_hw_state.dpll &
+		   ~(DPLL_VCO_ENABLE | DPLL_EXT_BUFFER_ENABLE_VLV));
+
+	/* No need to actually set up the DPLL with DSI */
+	if ((pipe_config->dpll_hw_state.dpll & DPLL_VCO_ENABLE) == 0)
+		return;
+
+	mutex_lock(&dev_priv->sb_lock);
+
+	bestn = pipe_config->dpll.n;
+	bestm1 = pipe_config->dpll.m1;
+	bestm2 = pipe_config->dpll.m2;
+	bestp1 = pipe_config->dpll.p1;
+	bestp2 = pipe_config->dpll.p2;
+
+	/* See eDP HDMI DPIO driver vbios notes doc */
+
+	/* PLL B needs special handling */
+	if (pipe == PIPE_B)
+		vlv_pllb_recal_opamp(dev_priv, pipe);
+
+	/* Set up Tx target for periodic Rcomp update */
+	vlv_dpio_write(dev_priv, pipe, VLV_PLL_DW9_BCAST, 0x0100000f);
+
+	/* Disable target IRef on PLL */
+	reg_val = vlv_dpio_read(dev_priv, pipe, VLV_PLL_DW8(pipe));
+	reg_val &= 0x00ffffff;
+	vlv_dpio_write(dev_priv, pipe, VLV_PLL_DW8(pipe), reg_val);
+
+	/* Disable fast lock */
+	vlv_dpio_write(dev_priv, pipe, VLV_CMN_DW0, 0x610);
+
+	/* Set idtafcrecal before PLL is enabled */
+	mdiv = ((bestm1 << DPIO_M1DIV_SHIFT) | (bestm2 & DPIO_M2DIV_MASK));
+	mdiv |= ((bestp1 << DPIO_P1_SHIFT) | (bestp2 << DPIO_P2_SHIFT));
+	mdiv |= ((bestn << DPIO_N_SHIFT));
+	mdiv |= (1 << DPIO_K_SHIFT);
+
+	/*
+	 * Post divider depends on pixel clock rate, DAC vs digital (and LVDS,
+	 * but we don't support that).
+	 * Note: don't use the DAC post divider as it seems unstable.
+	 */
+	mdiv |= (DPIO_POST_DIV_HDMIDP << DPIO_POST_DIV_SHIFT);
+	vlv_dpio_write(dev_priv, pipe, VLV_PLL_DW3(pipe), mdiv);
+
+	mdiv |= DPIO_ENABLE_CALIBRATION;
+	vlv_dpio_write(dev_priv, pipe, VLV_PLL_DW3(pipe), mdiv);
+
+	/* Set HBR and RBR LPF coefficients */
+	if (pipe_config->port_clock == 162000 ||
+	    intel_pipe_has_type(crtc, INTEL_OUTPUT_ANALOG) ||
+	    intel_pipe_has_type(crtc, INTEL_OUTPUT_HDMI))
+		vlv_dpio_write(dev_priv, pipe, VLV_PLL_DW10(pipe),
+				 0x009f0003);
+	else
+		vlv_dpio_write(dev_priv, pipe, VLV_PLL_DW10(pipe),
+				 0x00d0000f);
+
+	if (pipe_config->has_dp_encoder) {
+		/* Use SSC source */
+		if (pipe == PIPE_A)
+			vlv_dpio_write(dev_priv, pipe, VLV_PLL_DW5(pipe),
+					 0x0df40000);
+		else
+			vlv_dpio_write(dev_priv, pipe, VLV_PLL_DW5(pipe),
+					 0x0df70000);
+	} else { /* HDMI or VGA */
+		/* Use bend source */
+		if (pipe == PIPE_A)
+			vlv_dpio_write(dev_priv, pipe, VLV_PLL_DW5(pipe),
+					 0x0df70000);
+		else
+			vlv_dpio_write(dev_priv, pipe, VLV_PLL_DW5(pipe),
+					 0x0df40000);
+	}
+
+	coreclk = vlv_dpio_read(dev_priv, pipe, VLV_PLL_DW7(pipe));
+	coreclk = (coreclk & 0x0000ff00) | 0x01c00000;
+	if (intel_pipe_has_type(crtc, INTEL_OUTPUT_DISPLAYPORT) ||
+	    intel_pipe_has_type(crtc, INTEL_OUTPUT_EDP))
+		coreclk |= 0x01000000;
+	vlv_dpio_write(dev_priv, pipe, VLV_PLL_DW7(pipe), coreclk);
+
+	vlv_dpio_write(dev_priv, pipe, VLV_PLL_DW11(pipe), 0x87871000);
+	mutex_unlock(&dev_priv->sb_lock);
+}
+
+static void chv_prepare_pll(struct intel_crtc *crtc,
+			    const struct intel_crtc_state *pipe_config)
+{
+	struct drm_device *dev = crtc->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	enum pipe pipe = crtc->pipe;
+	enum dpio_channel port = vlv_pipe_to_channel(pipe);
+	u32 loopfilter, tribuf_calcntr;
+	u32 bestn, bestm1, bestm2, bestp1, bestp2, bestm2_frac;
+	u32 dpio_val;
+	int vco;
+
+	/* Enable Refclk and SSC */
+	I915_WRITE(DPLL(pipe),
+		   pipe_config->dpll_hw_state.dpll & ~DPLL_VCO_ENABLE);
+
+	/* No need to actually set up the DPLL with DSI */
+	if ((pipe_config->dpll_hw_state.dpll & DPLL_VCO_ENABLE) == 0)
+		return;
+
+	bestn = pipe_config->dpll.n;
+	bestm2_frac = pipe_config->dpll.m2 & 0x3fffff;
+	bestm1 = pipe_config->dpll.m1;
+	bestm2 = pipe_config->dpll.m2 >> 22;
+	bestp1 = pipe_config->dpll.p1;
+	bestp2 = pipe_config->dpll.p2;
+	vco = pipe_config->dpll.vco;
+	dpio_val = 0;
+	loopfilter = 0;
+
+	mutex_lock(&dev_priv->sb_lock);
+
+	/* p1 and p2 divider */
+	vlv_dpio_write(dev_priv, pipe, CHV_CMN_DW13(port),
+			5 << DPIO_CHV_S1_DIV_SHIFT |
+			bestp1 << DPIO_CHV_P1_DIV_SHIFT |
+			bestp2 << DPIO_CHV_P2_DIV_SHIFT |
+			1 << DPIO_CHV_K_DIV_SHIFT);
+
+	/* Feedback post-divider - m2 */
+	vlv_dpio_write(dev_priv, pipe, CHV_PLL_DW0(port), bestm2);
+
+	/* Feedback refclk divider - n and m1 */
+	vlv_dpio_write(dev_priv, pipe, CHV_PLL_DW1(port),
+			DPIO_CHV_M1_DIV_BY_2 |
+			1 << DPIO_CHV_N_DIV_SHIFT);
+
+	/* M2 fraction division */
+	vlv_dpio_write(dev_priv, pipe, CHV_PLL_DW2(port), bestm2_frac);
+
+	/* M2 fraction division enable */
+	dpio_val = vlv_dpio_read(dev_priv, pipe, CHV_PLL_DW3(port));
+	dpio_val &= ~(DPIO_CHV_FEEDFWD_GAIN_MASK | DPIO_CHV_FRAC_DIV_EN);
+	dpio_val |= (2 << DPIO_CHV_FEEDFWD_GAIN_SHIFT);
+	if (bestm2_frac)
+		dpio_val |= DPIO_CHV_FRAC_DIV_EN;
+	vlv_dpio_write(dev_priv, pipe, CHV_PLL_DW3(port), dpio_val);
+
+	/* Program digital lock detect threshold */
+	dpio_val = vlv_dpio_read(dev_priv, pipe, CHV_PLL_DW9(port));
+	dpio_val &= ~(DPIO_CHV_INT_LOCK_THRESHOLD_MASK |
+					DPIO_CHV_INT_LOCK_THRESHOLD_SEL_COARSE);
+	dpio_val |= (0x5 << DPIO_CHV_INT_LOCK_THRESHOLD_SHIFT);
+	if (!bestm2_frac)
+		dpio_val |= DPIO_CHV_INT_LOCK_THRESHOLD_SEL_COARSE;
+	vlv_dpio_write(dev_priv, pipe, CHV_PLL_DW9(port), dpio_val);
+
+	/* Loop filter */
+	if (vco == 5400000) {
+		loopfilter |= (0x3 << DPIO_CHV_PROP_COEFF_SHIFT);
+		loopfilter |= (0x8 << DPIO_CHV_INT_COEFF_SHIFT);
+		loopfilter |= (0x1 << DPIO_CHV_GAIN_CTRL_SHIFT);
+		tribuf_calcntr = 0x9;
+	} else if (vco <= 6200000) {
+		loopfilter |= (0x5 << DPIO_CHV_PROP_COEFF_SHIFT);
+		loopfilter |= (0xB << DPIO_CHV_INT_COEFF_SHIFT);
+		loopfilter |= (0x3 << DPIO_CHV_GAIN_CTRL_SHIFT);
+		tribuf_calcntr = 0x9;
+	} else if (vco <= 6480000) {
+		loopfilter |= (0x4 << DPIO_CHV_PROP_COEFF_SHIFT);
+		loopfilter |= (0x9 << DPIO_CHV_INT_COEFF_SHIFT);
+		loopfilter |= (0x3 << DPIO_CHV_GAIN_CTRL_SHIFT);
+		tribuf_calcntr = 0x8;
+	} else {
+		/* Not supported. Apply the same limits as in the max case */
+		loopfilter |= (0x4 << DPIO_CHV_PROP_COEFF_SHIFT);
+		loopfilter |= (0x9 << DPIO_CHV_INT_COEFF_SHIFT);
+		loopfilter |= (0x3 << DPIO_CHV_GAIN_CTRL_SHIFT);
+		tribuf_calcntr = 0;
+	}
+	vlv_dpio_write(dev_priv, pipe, CHV_PLL_DW6(port), loopfilter);
+
+	dpio_val = vlv_dpio_read(dev_priv, pipe, CHV_PLL_DW8(port));
+	dpio_val &= ~DPIO_CHV_TDC_TARGET_CNT_MASK;
+	dpio_val |= (tribuf_calcntr << DPIO_CHV_TDC_TARGET_CNT_SHIFT);
+	vlv_dpio_write(dev_priv, pipe, CHV_PLL_DW8(port), dpio_val);
+
+	/* AFC Recal */
+	vlv_dpio_write(dev_priv, pipe, CHV_CMN_DW14(port),
+			vlv_dpio_read(dev_priv, pipe, CHV_CMN_DW14(port)) |
+			DPIO_AFC_RECAL);
+
+	mutex_unlock(&dev_priv->sb_lock);
+}
+
+/**
+ * vlv_force_pll_on - forcibly enable just the PLL
+ * @dev_priv: i915 private structure
+ * @pipe: pipe PLL to enable
+ * @dpll: PLL configuration
+ *
+ * Enable the PLL for @pipe using the supplied @dpll config. To be used
+ * in cases where we need the PLL enabled even when @pipe is not going to
+ * be enabled.
+ */
+int vlv_force_pll_on(struct drm_device *dev, enum pipe pipe,
+		     const struct dpll *dpll)
+{
+	struct intel_crtc *crtc =
+		to_intel_crtc(intel_get_crtc_for_pipe(dev, pipe));
+	struct intel_crtc_state *pipe_config;
+
+	pipe_config = kzalloc(sizeof(*pipe_config), GFP_KERNEL);
+	if (!pipe_config)
+		return -ENOMEM;
+
+	pipe_config->base.crtc = &crtc->base;
+	pipe_config->pixel_multiplier = 1;
+	pipe_config->dpll = *dpll;
+
+	if (IS_CHERRYVIEW(dev)) {
+		chv_compute_dpll(crtc, pipe_config);
+		chv_prepare_pll(crtc, pipe_config);
+		chv_enable_pll(crtc, pipe_config);
+	} else {
+		vlv_compute_dpll(crtc, pipe_config);
+		vlv_prepare_pll(crtc, pipe_config);
+		vlv_enable_pll(crtc, pipe_config);
+	}
+
+	kfree(pipe_config);
+
+	return 0;
+}
+
+/**
+ * vlv_force_pll_off - forcibly disable just the PLL
+ * @dev_priv: i915 private structure
+ * @pipe: pipe PLL to disable
+ *
+ * Disable the PLL for @pipe. To be used in cases where we need
+ * the PLL enabled even when @pipe is not going to be enabled.
+ */
+void vlv_force_pll_off(struct drm_device *dev, enum pipe pipe)
+{
+	if (IS_CHERRYVIEW(dev))
+		chv_disable_pll(to_i915(dev), pipe);
+	else
+		vlv_disable_pll(to_i915(dev), pipe);
+}
+
+static void i9xx_compute_dpll(struct intel_crtc *crtc,
+			      struct intel_crtc_state *crtc_state,
+			      intel_clock_t *reduced_clock)
+{
+	struct drm_device *dev = crtc->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	u32 dpll;
+	bool is_sdvo;
+	struct dpll *clock = &crtc_state->dpll;
+
+	i9xx_update_pll_dividers(crtc, crtc_state, reduced_clock);
+
+	is_sdvo = intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_SDVO) ||
+		intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_HDMI);
+
+	dpll = DPLL_VGA_MODE_DIS;
+
+	if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_LVDS))
+		dpll |= DPLLB_MODE_LVDS;
+	else
+		dpll |= DPLLB_MODE_DAC_SERIAL;
+
+	if (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev)) {
+		dpll |= (crtc_state->pixel_multiplier - 1)
+			<< SDVO_MULTIPLIER_SHIFT_HIRES;
+	}
+
+	if (is_sdvo)
+		dpll |= DPLL_SDVO_HIGH_SPEED;
+
+	if (crtc_state->has_dp_encoder)
+		dpll |= DPLL_SDVO_HIGH_SPEED;
+
+	/* compute bitmask from p1 value */
+	if (IS_PINEVIEW(dev))
+		dpll |= (1 << (clock->p1 - 1)) << DPLL_FPA01_P1_POST_DIV_SHIFT_PINEVIEW;
+	else {
+		dpll |= (1 << (clock->p1 - 1)) << DPLL_FPA01_P1_POST_DIV_SHIFT;
+		if (IS_G4X(dev) && reduced_clock)
+			dpll |= (1 << (reduced_clock->p1 - 1)) << DPLL_FPA1_P1_POST_DIV_SHIFT;
+	}
+	switch (clock->p2) {
+	case 5:
+		dpll |= DPLL_DAC_SERIAL_P2_CLOCK_DIV_5;
+		break;
+	case 7:
+		dpll |= DPLLB_LVDS_P2_CLOCK_DIV_7;
+		break;
+	case 10:
+		dpll |= DPLL_DAC_SERIAL_P2_CLOCK_DIV_10;
+		break;
+	case 14:
+		dpll |= DPLLB_LVDS_P2_CLOCK_DIV_14;
+		break;
+	}
+	if (INTEL_INFO(dev)->gen >= 4)
+		dpll |= (6 << PLL_LOAD_PULSE_PHASE_SHIFT);
+
+	if (crtc_state->sdvo_tv_clock)
+		dpll |= PLL_REF_INPUT_TVCLKINBC;
+	else if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_LVDS) &&
+		 intel_panel_use_ssc(dev_priv))
+		dpll |= PLLB_REF_INPUT_SPREADSPECTRUMIN;
+	else
+		dpll |= PLL_REF_INPUT_DREFCLK;
+
+	dpll |= DPLL_VCO_ENABLE;
+	crtc_state->dpll_hw_state.dpll = dpll;
+
+	if (INTEL_INFO(dev)->gen >= 4) {
+		u32 dpll_md = (crtc_state->pixel_multiplier - 1)
+			<< DPLL_MD_UDI_MULTIPLIER_SHIFT;
+		crtc_state->dpll_hw_state.dpll_md = dpll_md;
+	}
+}
+
+static void i8xx_compute_dpll(struct intel_crtc *crtc,
+			      struct intel_crtc_state *crtc_state,
+			      intel_clock_t *reduced_clock)
+{
+	struct drm_device *dev = crtc->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	u32 dpll;
+	struct dpll *clock = &crtc_state->dpll;
+
+	i9xx_update_pll_dividers(crtc, crtc_state, reduced_clock);
+
+	dpll = DPLL_VGA_MODE_DIS;
+
+	if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_LVDS)) {
+		dpll |= (1 << (clock->p1 - 1)) << DPLL_FPA01_P1_POST_DIV_SHIFT;
+	} else {
+		if (clock->p1 == 2)
+			dpll |= PLL_P1_DIVIDE_BY_TWO;
+		else
+			dpll |= (clock->p1 - 2) << DPLL_FPA01_P1_POST_DIV_SHIFT;
+		if (clock->p2 == 4)
+			dpll |= PLL_P2_DIVIDE_BY_4;
+	}
+
+	if (!IS_I830(dev) && intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_DVO))
+		dpll |= DPLL_DVO_2X_MODE;
+
+	if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_LVDS) &&
+	    intel_panel_use_ssc(dev_priv))
+		dpll |= PLLB_REF_INPUT_SPREADSPECTRUMIN;
+	else
+		dpll |= PLL_REF_INPUT_DREFCLK;
+
+	dpll |= DPLL_VCO_ENABLE;
+	crtc_state->dpll_hw_state.dpll = dpll;
+}
+
+static void intel_set_pipe_timings(struct intel_crtc *intel_crtc)
+{
+	struct drm_device *dev = intel_crtc->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	enum pipe pipe = intel_crtc->pipe;
+	enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
+	const struct drm_display_mode *adjusted_mode = &intel_crtc->config->base.adjusted_mode;
+	uint32_t crtc_vtotal, crtc_vblank_end;
+	int vsyncshift = 0;
+
+	/* We need to be careful not to changed the adjusted mode, for otherwise
+	 * the hw state checker will get angry at the mismatch. */
+	crtc_vtotal = adjusted_mode->crtc_vtotal;
+	crtc_vblank_end = adjusted_mode->crtc_vblank_end;
+
+	if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) {
+		/* the chip adds 2 halflines automatically */
+		crtc_vtotal -= 1;
+		crtc_vblank_end -= 1;
+
+		if (intel_pipe_has_type(intel_crtc, INTEL_OUTPUT_SDVO))
+			vsyncshift = (adjusted_mode->crtc_htotal - 1) / 2;
+		else
+			vsyncshift = adjusted_mode->crtc_hsync_start -
+				adjusted_mode->crtc_htotal / 2;
+		if (vsyncshift < 0)
+			vsyncshift += adjusted_mode->crtc_htotal;
+	}
+
+	if (INTEL_INFO(dev)->gen > 3)
+		I915_WRITE(VSYNCSHIFT(cpu_transcoder), vsyncshift);
+
+	I915_WRITE(HTOTAL(cpu_transcoder),
+		   (adjusted_mode->crtc_hdisplay - 1) |
+		   ((adjusted_mode->crtc_htotal - 1) << 16));
+	I915_WRITE(HBLANK(cpu_transcoder),
+		   (adjusted_mode->crtc_hblank_start - 1) |
+		   ((adjusted_mode->crtc_hblank_end - 1) << 16));
+	I915_WRITE(HSYNC(cpu_transcoder),
+		   (adjusted_mode->crtc_hsync_start - 1) |
+		   ((adjusted_mode->crtc_hsync_end - 1) << 16));
+
+	I915_WRITE(VTOTAL(cpu_transcoder),
+		   (adjusted_mode->crtc_vdisplay - 1) |
+		   ((crtc_vtotal - 1) << 16));
+	I915_WRITE(VBLANK(cpu_transcoder),
+		   (adjusted_mode->crtc_vblank_start - 1) |
+		   ((crtc_vblank_end - 1) << 16));
+	I915_WRITE(VSYNC(cpu_transcoder),
+		   (adjusted_mode->crtc_vsync_start - 1) |
+		   ((adjusted_mode->crtc_vsync_end - 1) << 16));
+
+	/* Workaround: when the EDP input selection is B, the VTOTAL_B must be
+	 * programmed with the VTOTAL_EDP value. Same for VTOTAL_C. This is
+	 * documented on the DDI_FUNC_CTL register description, EDP Input Select
+	 * bits. */
+	if (IS_HASWELL(dev) && cpu_transcoder == TRANSCODER_EDP &&
+	    (pipe == PIPE_B || pipe == PIPE_C))
+		I915_WRITE(VTOTAL(pipe), I915_READ(VTOTAL(cpu_transcoder)));
+
+}
+
+static void intel_set_pipe_src_size(struct intel_crtc *intel_crtc)
+{
+	struct drm_device *dev = intel_crtc->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	enum pipe pipe = intel_crtc->pipe;
+
+	/* pipesrc controls the size that is scaled from, which should
+	 * always be the user's requested size.
+	 */
+	I915_WRITE(PIPESRC(pipe),
+		   ((intel_crtc->config->pipe_src_w - 1) << 16) |
+		   (intel_crtc->config->pipe_src_h - 1));
+}
+
+static void intel_get_pipe_timings(struct intel_crtc *crtc,
+				   struct intel_crtc_state *pipe_config)
+{
+	struct drm_device *dev = crtc->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	enum transcoder cpu_transcoder = pipe_config->cpu_transcoder;
+	uint32_t tmp;
+
+	tmp = I915_READ(HTOTAL(cpu_transcoder));
+	pipe_config->base.adjusted_mode.crtc_hdisplay = (tmp & 0xffff) + 1;
+	pipe_config->base.adjusted_mode.crtc_htotal = ((tmp >> 16) & 0xffff) + 1;
+	tmp = I915_READ(HBLANK(cpu_transcoder));
+	pipe_config->base.adjusted_mode.crtc_hblank_start = (tmp & 0xffff) + 1;
+	pipe_config->base.adjusted_mode.crtc_hblank_end = ((tmp >> 16) & 0xffff) + 1;
+	tmp = I915_READ(HSYNC(cpu_transcoder));
+	pipe_config->base.adjusted_mode.crtc_hsync_start = (tmp & 0xffff) + 1;
+	pipe_config->base.adjusted_mode.crtc_hsync_end = ((tmp >> 16) & 0xffff) + 1;
+
+	tmp = I915_READ(VTOTAL(cpu_transcoder));
+	pipe_config->base.adjusted_mode.crtc_vdisplay = (tmp & 0xffff) + 1;
+	pipe_config->base.adjusted_mode.crtc_vtotal = ((tmp >> 16) & 0xffff) + 1;
+	tmp = I915_READ(VBLANK(cpu_transcoder));
+	pipe_config->base.adjusted_mode.crtc_vblank_start = (tmp & 0xffff) + 1;
+	pipe_config->base.adjusted_mode.crtc_vblank_end = ((tmp >> 16) & 0xffff) + 1;
+	tmp = I915_READ(VSYNC(cpu_transcoder));
+	pipe_config->base.adjusted_mode.crtc_vsync_start = (tmp & 0xffff) + 1;
+	pipe_config->base.adjusted_mode.crtc_vsync_end = ((tmp >> 16) & 0xffff) + 1;
+
+	if (I915_READ(PIPECONF(cpu_transcoder)) & PIPECONF_INTERLACE_MASK) {
+		pipe_config->base.adjusted_mode.flags |= DRM_MODE_FLAG_INTERLACE;
+		pipe_config->base.adjusted_mode.crtc_vtotal += 1;
+		pipe_config->base.adjusted_mode.crtc_vblank_end += 1;
+	}
+}
+
+static void intel_get_pipe_src_size(struct intel_crtc *crtc,
+				    struct intel_crtc_state *pipe_config)
+{
+	struct drm_device *dev = crtc->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	u32 tmp;
+
+	tmp = I915_READ(PIPESRC(crtc->pipe));
+	pipe_config->pipe_src_h = (tmp & 0xffff) + 1;
+	pipe_config->pipe_src_w = ((tmp >> 16) & 0xffff) + 1;
+
+	pipe_config->base.mode.vdisplay = pipe_config->pipe_src_h;
+	pipe_config->base.mode.hdisplay = pipe_config->pipe_src_w;
+}
+
+void intel_mode_from_pipe_config(struct drm_display_mode *mode,
+				 struct intel_crtc_state *pipe_config)
+{
+	mode->hdisplay = pipe_config->base.adjusted_mode.crtc_hdisplay;
+	mode->htotal = pipe_config->base.adjusted_mode.crtc_htotal;
+	mode->hsync_start = pipe_config->base.adjusted_mode.crtc_hsync_start;
+	mode->hsync_end = pipe_config->base.adjusted_mode.crtc_hsync_end;
+
+	mode->vdisplay = pipe_config->base.adjusted_mode.crtc_vdisplay;
+	mode->vtotal = pipe_config->base.adjusted_mode.crtc_vtotal;
+	mode->vsync_start = pipe_config->base.adjusted_mode.crtc_vsync_start;
+	mode->vsync_end = pipe_config->base.adjusted_mode.crtc_vsync_end;
+
+	mode->flags = pipe_config->base.adjusted_mode.flags;
+	mode->type = DRM_MODE_TYPE_DRIVER;
+
+	mode->clock = pipe_config->base.adjusted_mode.crtc_clock;
+	mode->flags |= pipe_config->base.adjusted_mode.flags;
+
+	mode->hsync = drm_mode_hsync(mode);
+	mode->vrefresh = drm_mode_vrefresh(mode);
+	drm_mode_set_name(mode);
+}
+
+static void i9xx_set_pipeconf(struct intel_crtc *intel_crtc)
+{
+	struct drm_device *dev = intel_crtc->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	uint32_t pipeconf;
+
+	pipeconf = 0;
+
+	if ((intel_crtc->pipe == PIPE_A && dev_priv->quirks & QUIRK_PIPEA_FORCE) ||
+	    (intel_crtc->pipe == PIPE_B && dev_priv->quirks & QUIRK_PIPEB_FORCE))
+		pipeconf |= I915_READ(PIPECONF(intel_crtc->pipe)) & PIPECONF_ENABLE;
+
+	if (intel_crtc->config->double_wide)
+		pipeconf |= PIPECONF_DOUBLE_WIDE;
+
+	/* only g4x and later have fancy bpc/dither controls */
+	if (IS_G4X(dev) || IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev)) {
+		/* Bspec claims that we can't use dithering for 30bpp pipes. */
+		if (intel_crtc->config->dither && intel_crtc->config->pipe_bpp != 30)
+			pipeconf |= PIPECONF_DITHER_EN |
+				    PIPECONF_DITHER_TYPE_SP;
+
+		switch (intel_crtc->config->pipe_bpp) {
+		case 18:
+			pipeconf |= PIPECONF_6BPC;
+			break;
+		case 24:
+			pipeconf |= PIPECONF_8BPC;
+			break;
+		case 30:
+			pipeconf |= PIPECONF_10BPC;
+			break;
+		default:
+			/* Case prevented by intel_choose_pipe_bpp_dither. */
+			BUG();
+		}
+	}
+
+	if (HAS_PIPE_CXSR(dev)) {
+		if (intel_crtc->lowfreq_avail) {
+			DRM_DEBUG_KMS("enabling CxSR downclocking\n");
+			pipeconf |= PIPECONF_CXSR_DOWNCLOCK;
+		} else {
+			DRM_DEBUG_KMS("disabling CxSR downclocking\n");
+		}
+	}
+
+	if (intel_crtc->config->base.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE) {
+		if (INTEL_INFO(dev)->gen < 4 ||
+		    intel_pipe_has_type(intel_crtc, INTEL_OUTPUT_SDVO))
+			pipeconf |= PIPECONF_INTERLACE_W_FIELD_INDICATION;
+		else
+			pipeconf |= PIPECONF_INTERLACE_W_SYNC_SHIFT;
+	} else
+		pipeconf |= PIPECONF_PROGRESSIVE;
+
+	if ((IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev)) &&
+	     intel_crtc->config->limited_color_range)
+		pipeconf |= PIPECONF_COLOR_RANGE_SELECT;
+
+	I915_WRITE(PIPECONF(intel_crtc->pipe), pipeconf);
+	POSTING_READ(PIPECONF(intel_crtc->pipe));
+}
+
+static int i8xx_crtc_compute_clock(struct intel_crtc *crtc,
+				   struct intel_crtc_state *crtc_state)
+{
+	struct drm_device *dev = crtc->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	const intel_limit_t *limit;
+	int refclk = 48000;
+
+	memset(&crtc_state->dpll_hw_state, 0,
+	       sizeof(crtc_state->dpll_hw_state));
+
+	if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_LVDS)) {
+		if (intel_panel_use_ssc(dev_priv)) {
+			refclk = dev_priv->vbt.lvds_ssc_freq;
+			DRM_DEBUG_KMS("using SSC reference clock of %d kHz\n", refclk);
+		}
+
+		limit = &intel_limits_i8xx_lvds;
+	} else if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_DVO)) {
+		limit = &intel_limits_i8xx_dvo;
+	} else {
+		limit = &intel_limits_i8xx_dac;
+	}
+
+	if (!crtc_state->clock_set &&
+	    !i9xx_find_best_dpll(limit, crtc_state, crtc_state->port_clock,
+				 refclk, NULL, &crtc_state->dpll)) {
+		DRM_ERROR("Couldn't find PLL settings for mode!\n");
+		return -EINVAL;
+	}
+
+	i8xx_compute_dpll(crtc, crtc_state, NULL);
+
+	return 0;
+}
+
+static int g4x_crtc_compute_clock(struct intel_crtc *crtc,
+				  struct intel_crtc_state *crtc_state)
+{
+	struct drm_device *dev = crtc->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	const intel_limit_t *limit;
+	int refclk = 96000;
+
+	memset(&crtc_state->dpll_hw_state, 0,
+	       sizeof(crtc_state->dpll_hw_state));
+
+	if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_LVDS)) {
+		if (intel_panel_use_ssc(dev_priv)) {
+			refclk = dev_priv->vbt.lvds_ssc_freq;
+			DRM_DEBUG_KMS("using SSC reference clock of %d kHz\n", refclk);
+		}
+
+		if (intel_is_dual_link_lvds(dev))
+			limit = &intel_limits_g4x_dual_channel_lvds;
+		else
+			limit = &intel_limits_g4x_single_channel_lvds;
+	} else if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_HDMI) ||
+		   intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_ANALOG)) {
+		limit = &intel_limits_g4x_hdmi;
+	} else if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_SDVO)) {
+		limit = &intel_limits_g4x_sdvo;
+	} else {
+		/* The option is for other outputs */
+		limit = &intel_limits_i9xx_sdvo;
+	}
+
+	if (!crtc_state->clock_set &&
+	    !g4x_find_best_dpll(limit, crtc_state, crtc_state->port_clock,
+				refclk, NULL, &crtc_state->dpll)) {
+		DRM_ERROR("Couldn't find PLL settings for mode!\n");
+		return -EINVAL;
+	}
+
+	i9xx_compute_dpll(crtc, crtc_state, NULL);
+
+	return 0;
+}
+
+static int pnv_crtc_compute_clock(struct intel_crtc *crtc,
+				  struct intel_crtc_state *crtc_state)
+{
+	struct drm_device *dev = crtc->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	const intel_limit_t *limit;
+	int refclk = 96000;
+
+	memset(&crtc_state->dpll_hw_state, 0,
+	       sizeof(crtc_state->dpll_hw_state));
+
+	if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_LVDS)) {
+		if (intel_panel_use_ssc(dev_priv)) {
+			refclk = dev_priv->vbt.lvds_ssc_freq;
+			DRM_DEBUG_KMS("using SSC reference clock of %d kHz\n", refclk);
+		}
+
+		limit = &intel_limits_pineview_lvds;
+	} else {
+		limit = &intel_limits_pineview_sdvo;
+	}
+
+	if (!crtc_state->clock_set &&
+	    !pnv_find_best_dpll(limit, crtc_state, crtc_state->port_clock,
+				refclk, NULL, &crtc_state->dpll)) {
+		DRM_ERROR("Couldn't find PLL settings for mode!\n");
+		return -EINVAL;
+	}
+
+	i9xx_compute_dpll(crtc, crtc_state, NULL);
+
+	return 0;
+}
+
+static int i9xx_crtc_compute_clock(struct intel_crtc *crtc,
+				   struct intel_crtc_state *crtc_state)
+{
+	struct drm_device *dev = crtc->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	const intel_limit_t *limit;
+	int refclk = 96000;
+
+	memset(&crtc_state->dpll_hw_state, 0,
+	       sizeof(crtc_state->dpll_hw_state));
+
+	if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_LVDS)) {
+		if (intel_panel_use_ssc(dev_priv)) {
+			refclk = dev_priv->vbt.lvds_ssc_freq;
+			DRM_DEBUG_KMS("using SSC reference clock of %d kHz\n", refclk);
+		}
+
+		limit = &intel_limits_i9xx_lvds;
+	} else {
+		limit = &intel_limits_i9xx_sdvo;
+	}
+
+	if (!crtc_state->clock_set &&
+	    !i9xx_find_best_dpll(limit, crtc_state, crtc_state->port_clock,
+				 refclk, NULL, &crtc_state->dpll)) {
+		DRM_ERROR("Couldn't find PLL settings for mode!\n");
+		return -EINVAL;
+	}
+
+	i9xx_compute_dpll(crtc, crtc_state, NULL);
+
+	return 0;
+}
+
+static int chv_crtc_compute_clock(struct intel_crtc *crtc,
+				  struct intel_crtc_state *crtc_state)
+{
+	int refclk = 100000;
+	const intel_limit_t *limit = &intel_limits_chv;
+
+	memset(&crtc_state->dpll_hw_state, 0,
+	       sizeof(crtc_state->dpll_hw_state));
+
+	if (!crtc_state->clock_set &&
+	    !chv_find_best_dpll(limit, crtc_state, crtc_state->port_clock,
+				refclk, NULL, &crtc_state->dpll)) {
+		DRM_ERROR("Couldn't find PLL settings for mode!\n");
+		return -EINVAL;
+	}
+
+	chv_compute_dpll(crtc, crtc_state);
+
+	return 0;
+}
+
+static int vlv_crtc_compute_clock(struct intel_crtc *crtc,
+				  struct intel_crtc_state *crtc_state)
+{
+	int refclk = 100000;
+	const intel_limit_t *limit = &intel_limits_vlv;
+
+	memset(&crtc_state->dpll_hw_state, 0,
+	       sizeof(crtc_state->dpll_hw_state));
+
+	if (!crtc_state->clock_set &&
+	    !vlv_find_best_dpll(limit, crtc_state, crtc_state->port_clock,
+				refclk, NULL, &crtc_state->dpll)) {
+		DRM_ERROR("Couldn't find PLL settings for mode!\n");
+		return -EINVAL;
+	}
+
+	vlv_compute_dpll(crtc, crtc_state);
+
+	return 0;
+}
+
+static void i9xx_get_pfit_config(struct intel_crtc *crtc,
+				 struct intel_crtc_state *pipe_config)
+{
+	struct drm_device *dev = crtc->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	uint32_t tmp;
+
+	if (INTEL_INFO(dev)->gen <= 3 && (IS_I830(dev) || !IS_MOBILE(dev)))
+		return;
+
+	tmp = I915_READ(PFIT_CONTROL);
+	if (!(tmp & PFIT_ENABLE))
+		return;
+
+	/* Check whether the pfit is attached to our pipe. */
+	if (INTEL_INFO(dev)->gen < 4) {
+		if (crtc->pipe != PIPE_B)
+			return;
+	} else {
+		if ((tmp & PFIT_PIPE_MASK) != (crtc->pipe << PFIT_PIPE_SHIFT))
+			return;
+	}
+
+	pipe_config->gmch_pfit.control = tmp;
+	pipe_config->gmch_pfit.pgm_ratios = I915_READ(PFIT_PGM_RATIOS);
+}
+
+static void vlv_crtc_clock_get(struct intel_crtc *crtc,
+			       struct intel_crtc_state *pipe_config)
+{
+	struct drm_device *dev = crtc->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	int pipe = pipe_config->cpu_transcoder;
+	intel_clock_t clock;
+	u32 mdiv;
+	int refclk = 100000;
+
+	/* In case of DSI, DPLL will not be used */
+	if ((pipe_config->dpll_hw_state.dpll & DPLL_VCO_ENABLE) == 0)
+		return;
+
+	mutex_lock(&dev_priv->sb_lock);
+	mdiv = vlv_dpio_read(dev_priv, pipe, VLV_PLL_DW3(pipe));
+	mutex_unlock(&dev_priv->sb_lock);
+
+	clock.m1 = (mdiv >> DPIO_M1DIV_SHIFT) & 7;
+	clock.m2 = mdiv & DPIO_M2DIV_MASK;
+	clock.n = (mdiv >> DPIO_N_SHIFT) & 0xf;
+	clock.p1 = (mdiv >> DPIO_P1_SHIFT) & 7;
+	clock.p2 = (mdiv >> DPIO_P2_SHIFT) & 0x1f;
+
+	pipe_config->port_clock = vlv_calc_dpll_params(refclk, &clock);
+}
+
+static void
+i9xx_get_initial_plane_config(struct intel_crtc *crtc,
+			      struct intel_initial_plane_config *plane_config)
+{
+	struct drm_device *dev = crtc->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	u32 val, base, offset;
+	int pipe = crtc->pipe, plane = crtc->plane;
+	int fourcc, pixel_format;
+	unsigned int aligned_height;
+	struct drm_framebuffer *fb;
+	struct intel_framebuffer *intel_fb;
+
+	val = I915_READ(DSPCNTR(plane));
+	if (!(val & DISPLAY_PLANE_ENABLE))
+		return;
+
+	intel_fb = kzalloc(sizeof(*intel_fb), GFP_KERNEL);
+	if (!intel_fb) {
+		DRM_DEBUG_KMS("failed to alloc fb\n");
+		return;
+	}
+
+	fb = &intel_fb->base;
+
+	if (INTEL_INFO(dev)->gen >= 4) {
+		if (val & DISPPLANE_TILED) {
+			plane_config->tiling = I915_TILING_X;
+			fb->modifier[0] = I915_FORMAT_MOD_X_TILED;
+		}
+	}
+
+	pixel_format = val & DISPPLANE_PIXFORMAT_MASK;
+	fourcc = i9xx_format_to_fourcc(pixel_format);
+	fb->pixel_format = fourcc;
+	fb->bits_per_pixel = drm_format_plane_cpp(fourcc, 0) * 8;
+
+	if (INTEL_INFO(dev)->gen >= 4) {
+		if (plane_config->tiling)
+			offset = I915_READ(DSPTILEOFF(plane));
+		else
+			offset = I915_READ(DSPLINOFF(plane));
+		base = I915_READ(DSPSURF(plane)) & 0xfffff000;
+	} else {
+		base = I915_READ(DSPADDR(plane));
+	}
+	plane_config->base = base;
+
+	val = I915_READ(PIPESRC(pipe));
+	fb->width = ((val >> 16) & 0xfff) + 1;
+	fb->height = ((val >> 0) & 0xfff) + 1;
+
+	val = I915_READ(DSPSTRIDE(pipe));
+	fb->pitches[0] = val & 0xffffffc0;
+
+	aligned_height = intel_fb_align_height(dev, fb->height,
+					       fb->pixel_format,
+					       fb->modifier[0]);
+
+	plane_config->size = fb->pitches[0] * aligned_height;
+
+	DRM_DEBUG_KMS("pipe/plane %c/%d with fb: size=%dx%d@%d, offset=%x, pitch %d, size 0x%x\n",
+		      pipe_name(pipe), plane, fb->width, fb->height,
+		      fb->bits_per_pixel, base, fb->pitches[0],
+		      plane_config->size);
+
+	plane_config->fb = intel_fb;
+}
+
+static void chv_crtc_clock_get(struct intel_crtc *crtc,
+			       struct intel_crtc_state *pipe_config)
+{
+	struct drm_device *dev = crtc->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	int pipe = pipe_config->cpu_transcoder;
+	enum dpio_channel port = vlv_pipe_to_channel(pipe);
+	intel_clock_t clock;
+	u32 cmn_dw13, pll_dw0, pll_dw1, pll_dw2, pll_dw3;
+	int refclk = 100000;
+
+	/* In case of DSI, DPLL will not be used */
+	if ((pipe_config->dpll_hw_state.dpll & DPLL_VCO_ENABLE) == 0)
+		return;
+
+	mutex_lock(&dev_priv->sb_lock);
+	cmn_dw13 = vlv_dpio_read(dev_priv, pipe, CHV_CMN_DW13(port));
+	pll_dw0 = vlv_dpio_read(dev_priv, pipe, CHV_PLL_DW0(port));
+	pll_dw1 = vlv_dpio_read(dev_priv, pipe, CHV_PLL_DW1(port));
+	pll_dw2 = vlv_dpio_read(dev_priv, pipe, CHV_PLL_DW2(port));
+	pll_dw3 = vlv_dpio_read(dev_priv, pipe, CHV_PLL_DW3(port));
+	mutex_unlock(&dev_priv->sb_lock);
+
+	clock.m1 = (pll_dw1 & 0x7) == DPIO_CHV_M1_DIV_BY_2 ? 2 : 0;
+	clock.m2 = (pll_dw0 & 0xff) << 22;
+	if (pll_dw3 & DPIO_CHV_FRAC_DIV_EN)
+		clock.m2 |= pll_dw2 & 0x3fffff;
+	clock.n = (pll_dw1 >> DPIO_CHV_N_DIV_SHIFT) & 0xf;
+	clock.p1 = (cmn_dw13 >> DPIO_CHV_P1_DIV_SHIFT) & 0x7;
+	clock.p2 = (cmn_dw13 >> DPIO_CHV_P2_DIV_SHIFT) & 0x1f;
+
+	pipe_config->port_clock = chv_calc_dpll_params(refclk, &clock);
+}
+
+static bool i9xx_get_pipe_config(struct intel_crtc *crtc,
+				 struct intel_crtc_state *pipe_config)
+{
+	struct drm_device *dev = crtc->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	enum intel_display_power_domain power_domain;
+	uint32_t tmp;
+	bool ret;
+
+	power_domain = POWER_DOMAIN_PIPE(crtc->pipe);
+	if (!intel_display_power_get_if_enabled(dev_priv, power_domain))
+		return false;
+
+	pipe_config->cpu_transcoder = (enum transcoder) crtc->pipe;
+	pipe_config->shared_dpll = NULL;
+
+	ret = false;
+
+	tmp = I915_READ(PIPECONF(crtc->pipe));
+	if (!(tmp & PIPECONF_ENABLE))
+		goto out;
+
+	if (IS_G4X(dev) || IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev)) {
+		switch (tmp & PIPECONF_BPC_MASK) {
+		case PIPECONF_6BPC:
+			pipe_config->pipe_bpp = 18;
+			break;
+		case PIPECONF_8BPC:
+			pipe_config->pipe_bpp = 24;
+			break;
+		case PIPECONF_10BPC:
+			pipe_config->pipe_bpp = 30;
+			break;
+		default:
+			break;
+		}
+	}
+
+	if ((IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev)) &&
+	    (tmp & PIPECONF_COLOR_RANGE_SELECT))
+		pipe_config->limited_color_range = true;
+
+	if (INTEL_INFO(dev)->gen < 4)
+		pipe_config->double_wide = tmp & PIPECONF_DOUBLE_WIDE;
+
+	intel_get_pipe_timings(crtc, pipe_config);
+	intel_get_pipe_src_size(crtc, pipe_config);
+
+	i9xx_get_pfit_config(crtc, pipe_config);
+
+	if (INTEL_INFO(dev)->gen >= 4) {
+		/* No way to read it out on pipes B and C */
+		if (IS_CHERRYVIEW(dev) && crtc->pipe != PIPE_A)
+			tmp = dev_priv->chv_dpll_md[crtc->pipe];
+		else
+			tmp = I915_READ(DPLL_MD(crtc->pipe));
+		pipe_config->pixel_multiplier =
+			((tmp & DPLL_MD_UDI_MULTIPLIER_MASK)
+			 >> DPLL_MD_UDI_MULTIPLIER_SHIFT) + 1;
+		pipe_config->dpll_hw_state.dpll_md = tmp;
+	} else if (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev)) {
+		tmp = I915_READ(DPLL(crtc->pipe));
+		pipe_config->pixel_multiplier =
+			((tmp & SDVO_MULTIPLIER_MASK)
+			 >> SDVO_MULTIPLIER_SHIFT_HIRES) + 1;
+	} else {
+		/* Note that on i915G/GM the pixel multiplier is in the sdvo
+		 * port and will be fixed up in the encoder->get_config
+		 * function. */
+		pipe_config->pixel_multiplier = 1;
+	}
+	pipe_config->dpll_hw_state.dpll = I915_READ(DPLL(crtc->pipe));
+	if (!IS_VALLEYVIEW(dev) && !IS_CHERRYVIEW(dev)) {
+		/*
+		 * DPLL_DVO_2X_MODE must be enabled for both DPLLs
+		 * on 830. Filter it out here so that we don't
+		 * report errors due to that.
+		 */
+		if (IS_I830(dev))
+			pipe_config->dpll_hw_state.dpll &= ~DPLL_DVO_2X_MODE;
+
+		pipe_config->dpll_hw_state.fp0 = I915_READ(FP0(crtc->pipe));
+		pipe_config->dpll_hw_state.fp1 = I915_READ(FP1(crtc->pipe));
+	} else {
+		/* Mask out read-only status bits. */
+		pipe_config->dpll_hw_state.dpll &= ~(DPLL_LOCK_VLV |
+						     DPLL_PORTC_READY_MASK |
+						     DPLL_PORTB_READY_MASK);
+	}
+
+	if (IS_CHERRYVIEW(dev))
+		chv_crtc_clock_get(crtc, pipe_config);
+	else if (IS_VALLEYVIEW(dev))
+		vlv_crtc_clock_get(crtc, pipe_config);
+	else
+		i9xx_crtc_clock_get(crtc, pipe_config);
+
+	/*
+	 * Normally the dotclock is filled in by the encoder .get_config()
+	 * but in case the pipe is enabled w/o any ports we need a sane
+	 * default.
+	 */
+	pipe_config->base.adjusted_mode.crtc_clock =
+		pipe_config->port_clock / pipe_config->pixel_multiplier;
+
+	ret = true;
+
+out:
+	intel_display_power_put(dev_priv, power_domain);
+
+	return ret;
+}
+
+static void ironlake_init_pch_refclk(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_encoder *encoder;
+	int i;
+	u32 val, final;
+	bool has_lvds = false;
+	bool has_cpu_edp = false;
+	bool has_panel = false;
+	bool has_ck505 = false;
+	bool can_ssc = false;
+	bool using_ssc_source = false;
+
+	/* We need to take the global config into account */
+	for_each_intel_encoder(dev, encoder) {
+		switch (encoder->type) {
+		case INTEL_OUTPUT_LVDS:
+			has_panel = true;
+			has_lvds = true;
+			break;
+		case INTEL_OUTPUT_EDP:
+			has_panel = true;
+			if (enc_to_dig_port(&encoder->base)->port == PORT_A)
+				has_cpu_edp = true;
+			break;
+		default:
+			break;
+		}
+	}
+
+	if (HAS_PCH_IBX(dev)) {
+		has_ck505 = dev_priv->vbt.display_clock_mode;
+		can_ssc = has_ck505;
+	} else {
+		has_ck505 = false;
+		can_ssc = true;
+	}
+
+	/* Check if any DPLLs are using the SSC source */
+	for (i = 0; i < dev_priv->num_shared_dpll; i++) {
+		u32 temp = I915_READ(PCH_DPLL(i));
+
+		if (!(temp & DPLL_VCO_ENABLE))
+			continue;
+
+		if ((temp & PLL_REF_INPUT_MASK) ==
+		    PLLB_REF_INPUT_SPREADSPECTRUMIN) {
+			using_ssc_source = true;
+			break;
+		}
+	}
+
+	DRM_DEBUG_KMS("has_panel %d has_lvds %d has_ck505 %d using_ssc_source %d\n",
+		      has_panel, has_lvds, has_ck505, using_ssc_source);
+
+	/* Ironlake: try to setup display ref clock before DPLL
+	 * enabling. This is only under driver's control after
+	 * PCH B stepping, previous chipset stepping should be
+	 * ignoring this setting.
+	 */
+	val = I915_READ(PCH_DREF_CONTROL);
+
+	/* As we must carefully and slowly disable/enable each source in turn,
+	 * compute the final state we want first and check if we need to
+	 * make any changes at all.
+	 */
+	final = val;
+	final &= ~DREF_NONSPREAD_SOURCE_MASK;
+	if (has_ck505)
+		final |= DREF_NONSPREAD_CK505_ENABLE;
+	else
+		final |= DREF_NONSPREAD_SOURCE_ENABLE;
+
+	final &= ~DREF_SSC_SOURCE_MASK;
+	final &= ~DREF_CPU_SOURCE_OUTPUT_MASK;
+	final &= ~DREF_SSC1_ENABLE;
+
+	if (has_panel) {
+		final |= DREF_SSC_SOURCE_ENABLE;
+
+		if (intel_panel_use_ssc(dev_priv) && can_ssc)
+			final |= DREF_SSC1_ENABLE;
+
+		if (has_cpu_edp) {
+			if (intel_panel_use_ssc(dev_priv) && can_ssc)
+				final |= DREF_CPU_SOURCE_OUTPUT_DOWNSPREAD;
+			else
+				final |= DREF_CPU_SOURCE_OUTPUT_NONSPREAD;
+		} else
+			final |= DREF_CPU_SOURCE_OUTPUT_DISABLE;
+	} else if (using_ssc_source) {
+		final |= DREF_SSC_SOURCE_ENABLE;
+		final |= DREF_SSC1_ENABLE;
+	}
+
+	if (final == val)
+		return;
+
+	/* Always enable nonspread source */
+	val &= ~DREF_NONSPREAD_SOURCE_MASK;
+
+	if (has_ck505)
+		val |= DREF_NONSPREAD_CK505_ENABLE;
+	else
+		val |= DREF_NONSPREAD_SOURCE_ENABLE;
+
+	if (has_panel) {
+		val &= ~DREF_SSC_SOURCE_MASK;
+		val |= DREF_SSC_SOURCE_ENABLE;
+
+		/* SSC must be turned on before enabling the CPU output  */
+		if (intel_panel_use_ssc(dev_priv) && can_ssc) {
+			DRM_DEBUG_KMS("Using SSC on panel\n");
+			val |= DREF_SSC1_ENABLE;
+		} else
+			val &= ~DREF_SSC1_ENABLE;
+
+		/* Get SSC going before enabling the outputs */
+		I915_WRITE(PCH_DREF_CONTROL, val);
+		POSTING_READ(PCH_DREF_CONTROL);
+		udelay(200);
+
+		val &= ~DREF_CPU_SOURCE_OUTPUT_MASK;
+
+		/* Enable CPU source on CPU attached eDP */
+		if (has_cpu_edp) {
+			if (intel_panel_use_ssc(dev_priv) && can_ssc) {
+				DRM_DEBUG_KMS("Using SSC on eDP\n");
+				val |= DREF_CPU_SOURCE_OUTPUT_DOWNSPREAD;
+			} else
+				val |= DREF_CPU_SOURCE_OUTPUT_NONSPREAD;
+		} else
+			val |= DREF_CPU_SOURCE_OUTPUT_DISABLE;
+
+		I915_WRITE(PCH_DREF_CONTROL, val);
+		POSTING_READ(PCH_DREF_CONTROL);
+		udelay(200);
+	} else {
+		DRM_DEBUG_KMS("Disabling CPU source output\n");
+
+		val &= ~DREF_CPU_SOURCE_OUTPUT_MASK;
+
+		/* Turn off CPU output */
+		val |= DREF_CPU_SOURCE_OUTPUT_DISABLE;
+
+		I915_WRITE(PCH_DREF_CONTROL, val);
+		POSTING_READ(PCH_DREF_CONTROL);
+		udelay(200);
+
+		if (!using_ssc_source) {
+			DRM_DEBUG_KMS("Disabling SSC source\n");
+
+			/* Turn off the SSC source */
+			val &= ~DREF_SSC_SOURCE_MASK;
+			val |= DREF_SSC_SOURCE_DISABLE;
+
+			/* Turn off SSC1 */
+			val &= ~DREF_SSC1_ENABLE;
+
+			I915_WRITE(PCH_DREF_CONTROL, val);
+			POSTING_READ(PCH_DREF_CONTROL);
+			udelay(200);
+		}
+	}
+
+	BUG_ON(val != final);
+}
+
+static void lpt_reset_fdi_mphy(struct drm_i915_private *dev_priv)
+{
+	uint32_t tmp;
+
+	tmp = I915_READ(SOUTH_CHICKEN2);
+	tmp |= FDI_MPHY_IOSFSB_RESET_CTL;
+	I915_WRITE(SOUTH_CHICKEN2, tmp);
+
+	if (wait_for_us(I915_READ(SOUTH_CHICKEN2) &
+			FDI_MPHY_IOSFSB_RESET_STATUS, 100))
+		DRM_ERROR("FDI mPHY reset assert timeout\n");
+
+	tmp = I915_READ(SOUTH_CHICKEN2);
+	tmp &= ~FDI_MPHY_IOSFSB_RESET_CTL;
+	I915_WRITE(SOUTH_CHICKEN2, tmp);
+
+	if (wait_for_us((I915_READ(SOUTH_CHICKEN2) &
+			 FDI_MPHY_IOSFSB_RESET_STATUS) == 0, 100))
+		DRM_ERROR("FDI mPHY reset de-assert timeout\n");
+}
+
+/* WaMPhyProgramming:hsw */
+static void lpt_program_fdi_mphy(struct drm_i915_private *dev_priv)
+{
+	uint32_t tmp;
+
+	tmp = intel_sbi_read(dev_priv, 0x8008, SBI_MPHY);
+	tmp &= ~(0xFF << 24);
+	tmp |= (0x12 << 24);
+	intel_sbi_write(dev_priv, 0x8008, tmp, SBI_MPHY);
+
+	tmp = intel_sbi_read(dev_priv, 0x2008, SBI_MPHY);
+	tmp |= (1 << 11);
+	intel_sbi_write(dev_priv, 0x2008, tmp, SBI_MPHY);
+
+	tmp = intel_sbi_read(dev_priv, 0x2108, SBI_MPHY);
+	tmp |= (1 << 11);
+	intel_sbi_write(dev_priv, 0x2108, tmp, SBI_MPHY);
+
+	tmp = intel_sbi_read(dev_priv, 0x206C, SBI_MPHY);
+	tmp |= (1 << 24) | (1 << 21) | (1 << 18);
+	intel_sbi_write(dev_priv, 0x206C, tmp, SBI_MPHY);
+
+	tmp = intel_sbi_read(dev_priv, 0x216C, SBI_MPHY);
+	tmp |= (1 << 24) | (1 << 21) | (1 << 18);
+	intel_sbi_write(dev_priv, 0x216C, tmp, SBI_MPHY);
+
+	tmp = intel_sbi_read(dev_priv, 0x2080, SBI_MPHY);
+	tmp &= ~(7 << 13);
+	tmp |= (5 << 13);
+	intel_sbi_write(dev_priv, 0x2080, tmp, SBI_MPHY);
+
+	tmp = intel_sbi_read(dev_priv, 0x2180, SBI_MPHY);
+	tmp &= ~(7 << 13);
+	tmp |= (5 << 13);
+	intel_sbi_write(dev_priv, 0x2180, tmp, SBI_MPHY);
+
+	tmp = intel_sbi_read(dev_priv, 0x208C, SBI_MPHY);
+	tmp &= ~0xFF;
+	tmp |= 0x1C;
+	intel_sbi_write(dev_priv, 0x208C, tmp, SBI_MPHY);
+
+	tmp = intel_sbi_read(dev_priv, 0x218C, SBI_MPHY);
+	tmp &= ~0xFF;
+	tmp |= 0x1C;
+	intel_sbi_write(dev_priv, 0x218C, tmp, SBI_MPHY);
+
+	tmp = intel_sbi_read(dev_priv, 0x2098, SBI_MPHY);
+	tmp &= ~(0xFF << 16);
+	tmp |= (0x1C << 16);
+	intel_sbi_write(dev_priv, 0x2098, tmp, SBI_MPHY);
+
+	tmp = intel_sbi_read(dev_priv, 0x2198, SBI_MPHY);
+	tmp &= ~(0xFF << 16);
+	tmp |= (0x1C << 16);
+	intel_sbi_write(dev_priv, 0x2198, tmp, SBI_MPHY);
+
+	tmp = intel_sbi_read(dev_priv, 0x20C4, SBI_MPHY);
+	tmp |= (1 << 27);
+	intel_sbi_write(dev_priv, 0x20C4, tmp, SBI_MPHY);
+
+	tmp = intel_sbi_read(dev_priv, 0x21C4, SBI_MPHY);
+	tmp |= (1 << 27);
+	intel_sbi_write(dev_priv, 0x21C4, tmp, SBI_MPHY);
+
+	tmp = intel_sbi_read(dev_priv, 0x20EC, SBI_MPHY);
+	tmp &= ~(0xF << 28);
+	tmp |= (4 << 28);
+	intel_sbi_write(dev_priv, 0x20EC, tmp, SBI_MPHY);
+
+	tmp = intel_sbi_read(dev_priv, 0x21EC, SBI_MPHY);
+	tmp &= ~(0xF << 28);
+	tmp |= (4 << 28);
+	intel_sbi_write(dev_priv, 0x21EC, tmp, SBI_MPHY);
+}
+
+/* Implements 3 different sequences from BSpec chapter "Display iCLK
+ * Programming" based on the parameters passed:
+ * - Sequence to enable CLKOUT_DP
+ * - Sequence to enable CLKOUT_DP without spread
+ * - Sequence to enable CLKOUT_DP for FDI usage and configure PCH FDI I/O
+ */
+static void lpt_enable_clkout_dp(struct drm_device *dev, bool with_spread,
+				 bool with_fdi)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	uint32_t reg, tmp;
+
+	if (WARN(with_fdi && !with_spread, "FDI requires downspread\n"))
+		with_spread = true;
+	if (WARN(HAS_PCH_LPT_LP(dev) && with_fdi, "LP PCH doesn't have FDI\n"))
+		with_fdi = false;
+
+	mutex_lock(&dev_priv->sb_lock);
+
+	tmp = intel_sbi_read(dev_priv, SBI_SSCCTL, SBI_ICLK);
+	tmp &= ~SBI_SSCCTL_DISABLE;
+	tmp |= SBI_SSCCTL_PATHALT;
+	intel_sbi_write(dev_priv, SBI_SSCCTL, tmp, SBI_ICLK);
+
+	udelay(24);
+
+	if (with_spread) {
+		tmp = intel_sbi_read(dev_priv, SBI_SSCCTL, SBI_ICLK);
+		tmp &= ~SBI_SSCCTL_PATHALT;
+		intel_sbi_write(dev_priv, SBI_SSCCTL, tmp, SBI_ICLK);
+
+		if (with_fdi) {
+			lpt_reset_fdi_mphy(dev_priv);
+			lpt_program_fdi_mphy(dev_priv);
+		}
+	}
+
+	reg = HAS_PCH_LPT_LP(dev) ? SBI_GEN0 : SBI_DBUFF0;
+	tmp = intel_sbi_read(dev_priv, reg, SBI_ICLK);
+	tmp |= SBI_GEN0_CFG_BUFFENABLE_DISABLE;
+	intel_sbi_write(dev_priv, reg, tmp, SBI_ICLK);
+
+	mutex_unlock(&dev_priv->sb_lock);
+}
+
+/* Sequence to disable CLKOUT_DP */
+static void lpt_disable_clkout_dp(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	uint32_t reg, tmp;
+
+	mutex_lock(&dev_priv->sb_lock);
+
+	reg = HAS_PCH_LPT_LP(dev) ? SBI_GEN0 : SBI_DBUFF0;
+	tmp = intel_sbi_read(dev_priv, reg, SBI_ICLK);
+	tmp &= ~SBI_GEN0_CFG_BUFFENABLE_DISABLE;
+	intel_sbi_write(dev_priv, reg, tmp, SBI_ICLK);
+
+	tmp = intel_sbi_read(dev_priv, SBI_SSCCTL, SBI_ICLK);
+	if (!(tmp & SBI_SSCCTL_DISABLE)) {
+		if (!(tmp & SBI_SSCCTL_PATHALT)) {
+			tmp |= SBI_SSCCTL_PATHALT;
+			intel_sbi_write(dev_priv, SBI_SSCCTL, tmp, SBI_ICLK);
+			udelay(32);
+		}
+		tmp |= SBI_SSCCTL_DISABLE;
+		intel_sbi_write(dev_priv, SBI_SSCCTL, tmp, SBI_ICLK);
+	}
+
+	mutex_unlock(&dev_priv->sb_lock);
+}
+
+#define BEND_IDX(steps) ((50 + (steps)) / 5)
+
+static const uint16_t sscdivintphase[] = {
+	[BEND_IDX( 50)] = 0x3B23,
+	[BEND_IDX( 45)] = 0x3B23,
+	[BEND_IDX( 40)] = 0x3C23,
+	[BEND_IDX( 35)] = 0x3C23,
+	[BEND_IDX( 30)] = 0x3D23,
+	[BEND_IDX( 25)] = 0x3D23,
+	[BEND_IDX( 20)] = 0x3E23,
+	[BEND_IDX( 15)] = 0x3E23,
+	[BEND_IDX( 10)] = 0x3F23,
+	[BEND_IDX(  5)] = 0x3F23,
+	[BEND_IDX(  0)] = 0x0025,
+	[BEND_IDX( -5)] = 0x0025,
+	[BEND_IDX(-10)] = 0x0125,
+	[BEND_IDX(-15)] = 0x0125,
+	[BEND_IDX(-20)] = 0x0225,
+	[BEND_IDX(-25)] = 0x0225,
+	[BEND_IDX(-30)] = 0x0325,
+	[BEND_IDX(-35)] = 0x0325,
+	[BEND_IDX(-40)] = 0x0425,
+	[BEND_IDX(-45)] = 0x0425,
+	[BEND_IDX(-50)] = 0x0525,
+};
+
+/*
+ * Bend CLKOUT_DP
+ * steps -50 to 50 inclusive, in steps of 5
+ * < 0 slow down the clock, > 0 speed up the clock, 0 == no bend (135MHz)
+ * change in clock period = -(steps / 10) * 5.787 ps
+ */
+static void lpt_bend_clkout_dp(struct drm_i915_private *dev_priv, int steps)
+{
+	uint32_t tmp;
+	int idx = BEND_IDX(steps);
+
+	if (WARN_ON(steps % 5 != 0))
+		return;
+
+	if (WARN_ON(idx >= ARRAY_SIZE(sscdivintphase)))
+		return;
+
+	mutex_lock(&dev_priv->sb_lock);
+
+	if (steps % 10 != 0)
+		tmp = 0xAAAAAAAB;
+	else
+		tmp = 0x00000000;
+	intel_sbi_write(dev_priv, SBI_SSCDITHPHASE, tmp, SBI_ICLK);
+
+	tmp = intel_sbi_read(dev_priv, SBI_SSCDIVINTPHASE, SBI_ICLK);
+	tmp &= 0xffff0000;
+	tmp |= sscdivintphase[idx];
+	intel_sbi_write(dev_priv, SBI_SSCDIVINTPHASE, tmp, SBI_ICLK);
+
+	mutex_unlock(&dev_priv->sb_lock);
+}
+
+#undef BEND_IDX
+
+static void lpt_init_pch_refclk(struct drm_device *dev)
+{
+	struct intel_encoder *encoder;
+	bool has_vga = false;
+
+	for_each_intel_encoder(dev, encoder) {
+		switch (encoder->type) {
+		case INTEL_OUTPUT_ANALOG:
+			has_vga = true;
+			break;
+		default:
+			break;
+		}
+	}
+
+	if (has_vga) {
+		lpt_bend_clkout_dp(to_i915(dev), 0);
+		lpt_enable_clkout_dp(dev, true, true);
+	} else {
+		lpt_disable_clkout_dp(dev);
+	}
+}
+
+/*
+ * Initialize reference clocks when the driver loads
+ */
+void intel_init_pch_refclk(struct drm_device *dev)
+{
+	if (HAS_PCH_IBX(dev) || HAS_PCH_CPT(dev))
+		ironlake_init_pch_refclk(dev);
+	else if (HAS_PCH_LPT(dev))
+		lpt_init_pch_refclk(dev);
+}
+
+static void ironlake_set_pipeconf(struct drm_crtc *crtc)
+{
+	struct drm_i915_private *dev_priv = crtc->dev->dev_private;
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	int pipe = intel_crtc->pipe;
+	uint32_t val;
+
+	val = 0;
+
+	switch (intel_crtc->config->pipe_bpp) {
+	case 18:
+		val |= PIPECONF_6BPC;
+		break;
+	case 24:
+		val |= PIPECONF_8BPC;
+		break;
+	case 30:
+		val |= PIPECONF_10BPC;
+		break;
+	case 36:
+		val |= PIPECONF_12BPC;
+		break;
+	default:
+		/* Case prevented by intel_choose_pipe_bpp_dither. */
+		BUG();
+	}
+
+	if (intel_crtc->config->dither)
+		val |= (PIPECONF_DITHER_EN | PIPECONF_DITHER_TYPE_SP);
+
+	if (intel_crtc->config->base.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE)
+		val |= PIPECONF_INTERLACED_ILK;
+	else
+		val |= PIPECONF_PROGRESSIVE;
+
+	if (intel_crtc->config->limited_color_range)
+		val |= PIPECONF_COLOR_RANGE_SELECT;
+
+	I915_WRITE(PIPECONF(pipe), val);
+	POSTING_READ(PIPECONF(pipe));
+}
+
+static void haswell_set_pipeconf(struct drm_crtc *crtc)
+{
+	struct drm_i915_private *dev_priv = crtc->dev->dev_private;
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
+	u32 val = 0;
+
+	if (IS_HASWELL(dev_priv) && intel_crtc->config->dither)
+		val |= (PIPECONF_DITHER_EN | PIPECONF_DITHER_TYPE_SP);
+
+	if (intel_crtc->config->base.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE)
+		val |= PIPECONF_INTERLACED_ILK;
+	else
+		val |= PIPECONF_PROGRESSIVE;
+
+	I915_WRITE(PIPECONF(cpu_transcoder), val);
+	POSTING_READ(PIPECONF(cpu_transcoder));
+}
+
+static void haswell_set_pipemisc(struct drm_crtc *crtc)
+{
+	struct drm_i915_private *dev_priv = crtc->dev->dev_private;
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+
+	if (IS_BROADWELL(dev_priv) || INTEL_INFO(dev_priv)->gen >= 9) {
+		u32 val = 0;
+
+		switch (intel_crtc->config->pipe_bpp) {
+		case 18:
+			val |= PIPEMISC_DITHER_6_BPC;
+			break;
+		case 24:
+			val |= PIPEMISC_DITHER_8_BPC;
+			break;
+		case 30:
+			val |= PIPEMISC_DITHER_10_BPC;
+			break;
+		case 36:
+			val |= PIPEMISC_DITHER_12_BPC;
+			break;
+		default:
+			/* Case prevented by pipe_config_set_bpp. */
+			BUG();
+		}
+
+		if (intel_crtc->config->dither)
+			val |= PIPEMISC_DITHER_ENABLE | PIPEMISC_DITHER_TYPE_SP;
+
+		I915_WRITE(PIPEMISC(intel_crtc->pipe), val);
+	}
+}
+
+int ironlake_get_lanes_required(int target_clock, int link_bw, int bpp)
+{
+	/*
+	 * Account for spread spectrum to avoid
+	 * oversubscribing the link. Max center spread
+	 * is 2.5%; use 5% for safety's sake.
+	 */
+	u32 bps = target_clock * bpp * 21 / 20;
+	return DIV_ROUND_UP(bps, link_bw * 8);
+}
+
+static bool ironlake_needs_fb_cb_tune(struct dpll *dpll, int factor)
+{
+	return i9xx_dpll_compute_m(dpll) < factor * dpll->n;
+}
+
+static void ironlake_compute_dpll(struct intel_crtc *intel_crtc,
+				  struct intel_crtc_state *crtc_state,
+				  intel_clock_t *reduced_clock)
+{
+	struct drm_crtc *crtc = &intel_crtc->base;
+	struct drm_device *dev = crtc->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct drm_atomic_state *state = crtc_state->base.state;
+	struct drm_connector *connector;
+	struct drm_connector_state *connector_state;
+	struct intel_encoder *encoder;
+	u32 dpll, fp, fp2;
+	int factor, i;
+	bool is_lvds = false, is_sdvo = false;
+
+	for_each_connector_in_state(state, connector, connector_state, i) {
+		if (connector_state->crtc != crtc_state->base.crtc)
+			continue;
+
+		encoder = to_intel_encoder(connector_state->best_encoder);
+
+		switch (encoder->type) {
+		case INTEL_OUTPUT_LVDS:
+			is_lvds = true;
+			break;
+		case INTEL_OUTPUT_SDVO:
+		case INTEL_OUTPUT_HDMI:
+			is_sdvo = true;
+			break;
+		default:
+			break;
+		}
+	}
+
+	/* Enable autotuning of the PLL clock (if permissible) */
+	factor = 21;
+	if (is_lvds) {
+		if ((intel_panel_use_ssc(dev_priv) &&
+		     dev_priv->vbt.lvds_ssc_freq == 100000) ||
+		    (HAS_PCH_IBX(dev) && intel_is_dual_link_lvds(dev)))
+			factor = 25;
+	} else if (crtc_state->sdvo_tv_clock)
+		factor = 20;
+
+	fp = i9xx_dpll_compute_fp(&crtc_state->dpll);
+
+	if (ironlake_needs_fb_cb_tune(&crtc_state->dpll, factor))
+		fp |= FP_CB_TUNE;
+
+	if (reduced_clock) {
+		fp2 = i9xx_dpll_compute_fp(reduced_clock);
+
+		if (reduced_clock->m < factor * reduced_clock->n)
+			fp2 |= FP_CB_TUNE;
+	} else {
+		fp2 = fp;
+	}
+
+	dpll = 0;
+
+	if (is_lvds)
+		dpll |= DPLLB_MODE_LVDS;
+	else
+		dpll |= DPLLB_MODE_DAC_SERIAL;
+
+	dpll |= (crtc_state->pixel_multiplier - 1)
+		<< PLL_REF_SDVO_HDMI_MULTIPLIER_SHIFT;
+
+	if (is_sdvo)
+		dpll |= DPLL_SDVO_HIGH_SPEED;
+	if (crtc_state->has_dp_encoder)
+		dpll |= DPLL_SDVO_HIGH_SPEED;
+
+	/* compute bitmask from p1 value */
+	dpll |= (1 << (crtc_state->dpll.p1 - 1)) << DPLL_FPA01_P1_POST_DIV_SHIFT;
+	/* also FPA1 */
+	dpll |= (1 << (crtc_state->dpll.p1 - 1)) << DPLL_FPA1_P1_POST_DIV_SHIFT;
+
+	switch (crtc_state->dpll.p2) {
+	case 5:
+		dpll |= DPLL_DAC_SERIAL_P2_CLOCK_DIV_5;
+		break;
+	case 7:
+		dpll |= DPLLB_LVDS_P2_CLOCK_DIV_7;
+		break;
+	case 10:
+		dpll |= DPLL_DAC_SERIAL_P2_CLOCK_DIV_10;
+		break;
+	case 14:
+		dpll |= DPLLB_LVDS_P2_CLOCK_DIV_14;
+		break;
+	}
+
+	if (is_lvds && intel_panel_use_ssc(dev_priv))
+		dpll |= PLLB_REF_INPUT_SPREADSPECTRUMIN;
+	else
+		dpll |= PLL_REF_INPUT_DREFCLK;
+
+	dpll |= DPLL_VCO_ENABLE;
+
+	crtc_state->dpll_hw_state.dpll = dpll;
+	crtc_state->dpll_hw_state.fp0 = fp;
+	crtc_state->dpll_hw_state.fp1 = fp2;
+}
+
+static int ironlake_crtc_compute_clock(struct intel_crtc *crtc,
+				       struct intel_crtc_state *crtc_state)
+{
+	struct drm_device *dev = crtc->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	intel_clock_t reduced_clock;
+	bool has_reduced_clock = false;
+	struct intel_shared_dpll *pll;
+	const intel_limit_t *limit;
+	int refclk = 120000;
+
+	memset(&crtc_state->dpll_hw_state, 0,
+	       sizeof(crtc_state->dpll_hw_state));
+
+	crtc->lowfreq_avail = false;
+
+	/* CPU eDP is the only output that doesn't need a PCH PLL of its own. */
+	if (!crtc_state->has_pch_encoder)
+		return 0;
+
+	if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_LVDS)) {
+		if (intel_panel_use_ssc(dev_priv)) {
+			DRM_DEBUG_KMS("using SSC reference clock of %d kHz\n",
+				      dev_priv->vbt.lvds_ssc_freq);
+			refclk = dev_priv->vbt.lvds_ssc_freq;
+		}
+
+		if (intel_is_dual_link_lvds(dev)) {
+			if (refclk == 100000)
+				limit = &intel_limits_ironlake_dual_lvds_100m;
+			else
+				limit = &intel_limits_ironlake_dual_lvds;
+		} else {
+			if (refclk == 100000)
+				limit = &intel_limits_ironlake_single_lvds_100m;
+			else
+				limit = &intel_limits_ironlake_single_lvds;
+		}
+	} else {
+		limit = &intel_limits_ironlake_dac;
+	}
+
+	if (!crtc_state->clock_set &&
+	    !g4x_find_best_dpll(limit, crtc_state, crtc_state->port_clock,
+				refclk, NULL, &crtc_state->dpll)) {
+		DRM_ERROR("Couldn't find PLL settings for mode!\n");
+		return -EINVAL;
+	}
+
+	ironlake_compute_dpll(crtc, crtc_state,
+			      has_reduced_clock ? &reduced_clock : NULL);
+
+	pll = intel_get_shared_dpll(crtc, crtc_state, NULL);
+	if (pll == NULL) {
+		DRM_DEBUG_DRIVER("failed to find PLL for pipe %c\n",
+				 pipe_name(crtc->pipe));
+		return -EINVAL;
+	}
+
+	if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_LVDS) &&
+	    has_reduced_clock)
+		crtc->lowfreq_avail = true;
+
+	return 0;
+}
+
+static void intel_pch_transcoder_get_m_n(struct intel_crtc *crtc,
+					 struct intel_link_m_n *m_n)
+{
+	struct drm_device *dev = crtc->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	enum pipe pipe = crtc->pipe;
+
+	m_n->link_m = I915_READ(PCH_TRANS_LINK_M1(pipe));
+	m_n->link_n = I915_READ(PCH_TRANS_LINK_N1(pipe));
+	m_n->gmch_m = I915_READ(PCH_TRANS_DATA_M1(pipe))
+		& ~TU_SIZE_MASK;
+	m_n->gmch_n = I915_READ(PCH_TRANS_DATA_N1(pipe));
+	m_n->tu = ((I915_READ(PCH_TRANS_DATA_M1(pipe))
+		    & TU_SIZE_MASK) >> TU_SIZE_SHIFT) + 1;
+}
+
+static void intel_cpu_transcoder_get_m_n(struct intel_crtc *crtc,
+					 enum transcoder transcoder,
+					 struct intel_link_m_n *m_n,
+					 struct intel_link_m_n *m2_n2)
+{
+	struct drm_device *dev = crtc->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	enum pipe pipe = crtc->pipe;
+
+	if (INTEL_INFO(dev)->gen >= 5) {
+		m_n->link_m = I915_READ(PIPE_LINK_M1(transcoder));
+		m_n->link_n = I915_READ(PIPE_LINK_N1(transcoder));
+		m_n->gmch_m = I915_READ(PIPE_DATA_M1(transcoder))
+			& ~TU_SIZE_MASK;
+		m_n->gmch_n = I915_READ(PIPE_DATA_N1(transcoder));
+		m_n->tu = ((I915_READ(PIPE_DATA_M1(transcoder))
+			    & TU_SIZE_MASK) >> TU_SIZE_SHIFT) + 1;
+		/* Read M2_N2 registers only for gen < 8 (M2_N2 available for
+		 * gen < 8) and if DRRS is supported (to make sure the
+		 * registers are not unnecessarily read).
+		 */
+		if (m2_n2 && INTEL_INFO(dev)->gen < 8 &&
+			crtc->config->has_drrs) {
+			m2_n2->link_m = I915_READ(PIPE_LINK_M2(transcoder));
+			m2_n2->link_n =	I915_READ(PIPE_LINK_N2(transcoder));
+			m2_n2->gmch_m =	I915_READ(PIPE_DATA_M2(transcoder))
+					& ~TU_SIZE_MASK;
+			m2_n2->gmch_n =	I915_READ(PIPE_DATA_N2(transcoder));
+			m2_n2->tu = ((I915_READ(PIPE_DATA_M2(transcoder))
+					& TU_SIZE_MASK) >> TU_SIZE_SHIFT) + 1;
+		}
+	} else {
+		m_n->link_m = I915_READ(PIPE_LINK_M_G4X(pipe));
+		m_n->link_n = I915_READ(PIPE_LINK_N_G4X(pipe));
+		m_n->gmch_m = I915_READ(PIPE_DATA_M_G4X(pipe))
+			& ~TU_SIZE_MASK;
+		m_n->gmch_n = I915_READ(PIPE_DATA_N_G4X(pipe));
+		m_n->tu = ((I915_READ(PIPE_DATA_M_G4X(pipe))
+			    & TU_SIZE_MASK) >> TU_SIZE_SHIFT) + 1;
+	}
+}
+
+void intel_dp_get_m_n(struct intel_crtc *crtc,
+		      struct intel_crtc_state *pipe_config)
+{
+	if (pipe_config->has_pch_encoder)
+		intel_pch_transcoder_get_m_n(crtc, &pipe_config->dp_m_n);
+	else
+		intel_cpu_transcoder_get_m_n(crtc, pipe_config->cpu_transcoder,
+					     &pipe_config->dp_m_n,
+					     &pipe_config->dp_m2_n2);
+}
+
+static void ironlake_get_fdi_m_n_config(struct intel_crtc *crtc,
+					struct intel_crtc_state *pipe_config)
+{
+	intel_cpu_transcoder_get_m_n(crtc, pipe_config->cpu_transcoder,
+				     &pipe_config->fdi_m_n, NULL);
+}
+
+static void skylake_get_pfit_config(struct intel_crtc *crtc,
+				    struct intel_crtc_state *pipe_config)
+{
+	struct drm_device *dev = crtc->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_crtc_scaler_state *scaler_state = &pipe_config->scaler_state;
+	uint32_t ps_ctrl = 0;
+	int id = -1;
+	int i;
+
+	/* find scaler attached to this pipe */
+	for (i = 0; i < crtc->num_scalers; i++) {
+		ps_ctrl = I915_READ(SKL_PS_CTRL(crtc->pipe, i));
+		if (ps_ctrl & PS_SCALER_EN && !(ps_ctrl & PS_PLANE_SEL_MASK)) {
+			id = i;
+			pipe_config->pch_pfit.enabled = true;
+			pipe_config->pch_pfit.pos = I915_READ(SKL_PS_WIN_POS(crtc->pipe, i));
+			pipe_config->pch_pfit.size = I915_READ(SKL_PS_WIN_SZ(crtc->pipe, i));
+			break;
+		}
+	}
+
+	scaler_state->scaler_id = id;
+	if (id >= 0) {
+		scaler_state->scaler_users |= (1 << SKL_CRTC_INDEX);
+	} else {
+		scaler_state->scaler_users &= ~(1 << SKL_CRTC_INDEX);
+	}
+}
+
+static void
+skylake_get_initial_plane_config(struct intel_crtc *crtc,
+				 struct intel_initial_plane_config *plane_config)
+{
+	struct drm_device *dev = crtc->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	u32 val, base, offset, stride_mult, tiling;
+	int pipe = crtc->pipe;
+	int fourcc, pixel_format;
+	unsigned int aligned_height;
+	struct drm_framebuffer *fb;
+	struct intel_framebuffer *intel_fb;
+
+	intel_fb = kzalloc(sizeof(*intel_fb), GFP_KERNEL);
+	if (!intel_fb) {
+		DRM_DEBUG_KMS("failed to alloc fb\n");
+		return;
+	}
+
+	fb = &intel_fb->base;
+
+	val = I915_READ(PLANE_CTL(pipe, 0));
+	if (!(val & PLANE_CTL_ENABLE))
+		goto error;
+
+	pixel_format = val & PLANE_CTL_FORMAT_MASK;
+	fourcc = skl_format_to_fourcc(pixel_format,
+				      val & PLANE_CTL_ORDER_RGBX,
+				      val & PLANE_CTL_ALPHA_MASK);
+	fb->pixel_format = fourcc;
+	fb->bits_per_pixel = drm_format_plane_cpp(fourcc, 0) * 8;
+
+	tiling = val & PLANE_CTL_TILED_MASK;
+	switch (tiling) {
+	case PLANE_CTL_TILED_LINEAR:
+		fb->modifier[0] = DRM_FORMAT_MOD_NONE;
+		break;
+	case PLANE_CTL_TILED_X:
+		plane_config->tiling = I915_TILING_X;
+		fb->modifier[0] = I915_FORMAT_MOD_X_TILED;
+		break;
+	case PLANE_CTL_TILED_Y:
+		fb->modifier[0] = I915_FORMAT_MOD_Y_TILED;
+		break;
+	case PLANE_CTL_TILED_YF:
+		fb->modifier[0] = I915_FORMAT_MOD_Yf_TILED;
+		break;
+	default:
+		MISSING_CASE(tiling);
+		goto error;
+	}
+
+	base = I915_READ(PLANE_SURF(pipe, 0)) & 0xfffff000;
+	plane_config->base = base;
+
+	offset = I915_READ(PLANE_OFFSET(pipe, 0));
+
+	val = I915_READ(PLANE_SIZE(pipe, 0));
+	fb->height = ((val >> 16) & 0xfff) + 1;
+	fb->width = ((val >> 0) & 0x1fff) + 1;
+
+	val = I915_READ(PLANE_STRIDE(pipe, 0));
+	stride_mult = intel_fb_stride_alignment(dev_priv, fb->modifier[0],
+						fb->pixel_format);
+	fb->pitches[0] = (val & 0x3ff) * stride_mult;
+
+	aligned_height = intel_fb_align_height(dev, fb->height,
+					       fb->pixel_format,
+					       fb->modifier[0]);
+
+	plane_config->size = fb->pitches[0] * aligned_height;
+
+	DRM_DEBUG_KMS("pipe %c with fb: size=%dx%d@%d, offset=%x, pitch %d, size 0x%x\n",
+		      pipe_name(pipe), fb->width, fb->height,
+		      fb->bits_per_pixel, base, fb->pitches[0],
+		      plane_config->size);
+
+	plane_config->fb = intel_fb;
+	return;
+
+error:
+	kfree(fb);
+}
+
+static void ironlake_get_pfit_config(struct intel_crtc *crtc,
+				     struct intel_crtc_state *pipe_config)
+{
+	struct drm_device *dev = crtc->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	uint32_t tmp;
+
+	tmp = I915_READ(PF_CTL(crtc->pipe));
+
+	if (tmp & PF_ENABLE) {
+		pipe_config->pch_pfit.enabled = true;
+		pipe_config->pch_pfit.pos = I915_READ(PF_WIN_POS(crtc->pipe));
+		pipe_config->pch_pfit.size = I915_READ(PF_WIN_SZ(crtc->pipe));
+
+		/* We currently do not free assignements of panel fitters on
+		 * ivb/hsw (since we don't use the higher upscaling modes which
+		 * differentiates them) so just WARN about this case for now. */
+		if (IS_GEN7(dev)) {
+			WARN_ON((tmp & PF_PIPE_SEL_MASK_IVB) !=
+				PF_PIPE_SEL_IVB(crtc->pipe));
+		}
+	}
+}
+
+static void
+ironlake_get_initial_plane_config(struct intel_crtc *crtc,
+				  struct intel_initial_plane_config *plane_config)
+{
+	struct drm_device *dev = crtc->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	u32 val, base, offset;
+	int pipe = crtc->pipe;
+	int fourcc, pixel_format;
+	unsigned int aligned_height;
+	struct drm_framebuffer *fb;
+	struct intel_framebuffer *intel_fb;
+
+	val = I915_READ(DSPCNTR(pipe));
+	if (!(val & DISPLAY_PLANE_ENABLE))
+		return;
+
+	intel_fb = kzalloc(sizeof(*intel_fb), GFP_KERNEL);
+	if (!intel_fb) {
+		DRM_DEBUG_KMS("failed to alloc fb\n");
+		return;
+	}
+
+	fb = &intel_fb->base;
+
+	if (INTEL_INFO(dev)->gen >= 4) {
+		if (val & DISPPLANE_TILED) {
+			plane_config->tiling = I915_TILING_X;
+			fb->modifier[0] = I915_FORMAT_MOD_X_TILED;
+		}
+	}
+
+	pixel_format = val & DISPPLANE_PIXFORMAT_MASK;
+	fourcc = i9xx_format_to_fourcc(pixel_format);
+	fb->pixel_format = fourcc;
+	fb->bits_per_pixel = drm_format_plane_cpp(fourcc, 0) * 8;
+
+	base = I915_READ(DSPSURF(pipe)) & 0xfffff000;
+	if (IS_HASWELL(dev) || IS_BROADWELL(dev)) {
+		offset = I915_READ(DSPOFFSET(pipe));
+	} else {
+		if (plane_config->tiling)
+			offset = I915_READ(DSPTILEOFF(pipe));
+		else
+			offset = I915_READ(DSPLINOFF(pipe));
+	}
+	plane_config->base = base;
+
+	val = I915_READ(PIPESRC(pipe));
+	fb->width = ((val >> 16) & 0xfff) + 1;
+	fb->height = ((val >> 0) & 0xfff) + 1;
+
+	val = I915_READ(DSPSTRIDE(pipe));
+	fb->pitches[0] = val & 0xffffffc0;
+
+	aligned_height = intel_fb_align_height(dev, fb->height,
+					       fb->pixel_format,
+					       fb->modifier[0]);
+
+	plane_config->size = fb->pitches[0] * aligned_height;
+
+	DRM_DEBUG_KMS("pipe %c with fb: size=%dx%d@%d, offset=%x, pitch %d, size 0x%x\n",
+		      pipe_name(pipe), fb->width, fb->height,
+		      fb->bits_per_pixel, base, fb->pitches[0],
+		      plane_config->size);
+
+	plane_config->fb = intel_fb;
+}
+
+static bool ironlake_get_pipe_config(struct intel_crtc *crtc,
+				     struct intel_crtc_state *pipe_config)
+{
+	struct drm_device *dev = crtc->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	enum intel_display_power_domain power_domain;
+	uint32_t tmp;
+	bool ret;
+
+	power_domain = POWER_DOMAIN_PIPE(crtc->pipe);
+	if (!intel_display_power_get_if_enabled(dev_priv, power_domain))
+		return false;
+
+	pipe_config->cpu_transcoder = (enum transcoder) crtc->pipe;
+	pipe_config->shared_dpll = NULL;
+
+	ret = false;
+	tmp = I915_READ(PIPECONF(crtc->pipe));
+	if (!(tmp & PIPECONF_ENABLE))
+		goto out;
+
+	switch (tmp & PIPECONF_BPC_MASK) {
+	case PIPECONF_6BPC:
+		pipe_config->pipe_bpp = 18;
+		break;
+	case PIPECONF_8BPC:
+		pipe_config->pipe_bpp = 24;
+		break;
+	case PIPECONF_10BPC:
+		pipe_config->pipe_bpp = 30;
+		break;
+	case PIPECONF_12BPC:
+		pipe_config->pipe_bpp = 36;
+		break;
+	default:
+		break;
+	}
+
+	if (tmp & PIPECONF_COLOR_RANGE_SELECT)
+		pipe_config->limited_color_range = true;
+
+	if (I915_READ(PCH_TRANSCONF(crtc->pipe)) & TRANS_ENABLE) {
+		struct intel_shared_dpll *pll;
+		enum intel_dpll_id pll_id;
+
+		pipe_config->has_pch_encoder = true;
+
+		tmp = I915_READ(FDI_RX_CTL(crtc->pipe));
+		pipe_config->fdi_lanes = ((FDI_DP_PORT_WIDTH_MASK & tmp) >>
+					  FDI_DP_PORT_WIDTH_SHIFT) + 1;
+
+		ironlake_get_fdi_m_n_config(crtc, pipe_config);
+
+		if (HAS_PCH_IBX(dev_priv)) {
+			pll_id = (enum intel_dpll_id) crtc->pipe;
+		} else {
+			tmp = I915_READ(PCH_DPLL_SEL);
+			if (tmp & TRANS_DPLLB_SEL(crtc->pipe))
+				pll_id = DPLL_ID_PCH_PLL_B;
+			else
+				pll_id= DPLL_ID_PCH_PLL_A;
+		}
+
+		pipe_config->shared_dpll =
+			intel_get_shared_dpll_by_id(dev_priv, pll_id);
+		pll = pipe_config->shared_dpll;
+
+		WARN_ON(!pll->funcs.get_hw_state(dev_priv, pll,
+						 &pipe_config->dpll_hw_state));
+
+		tmp = pipe_config->dpll_hw_state.dpll;
+		pipe_config->pixel_multiplier =
+			((tmp & PLL_REF_SDVO_HDMI_MULTIPLIER_MASK)
+			 >> PLL_REF_SDVO_HDMI_MULTIPLIER_SHIFT) + 1;
+
+		ironlake_pch_clock_get(crtc, pipe_config);
+	} else {
+		pipe_config->pixel_multiplier = 1;
+	}
+
+	intel_get_pipe_timings(crtc, pipe_config);
+	intel_get_pipe_src_size(crtc, pipe_config);
+
+	ironlake_get_pfit_config(crtc, pipe_config);
+
+	ret = true;
+
+out:
+	intel_display_power_put(dev_priv, power_domain);
+
+	return ret;
+}
+
+static void assert_can_disable_lcpll(struct drm_i915_private *dev_priv)
+{
+	struct drm_device *dev = dev_priv->dev;
+	struct intel_crtc *crtc;
+
+	for_each_intel_crtc(dev, crtc)
+		I915_STATE_WARN(crtc->active, "CRTC for pipe %c enabled\n",
+		     pipe_name(crtc->pipe));
+
+	I915_STATE_WARN(I915_READ(HSW_PWR_WELL_DRIVER), "Power well on\n");
+	I915_STATE_WARN(I915_READ(SPLL_CTL) & SPLL_PLL_ENABLE, "SPLL enabled\n");
+	I915_STATE_WARN(I915_READ(WRPLL_CTL(0)) & WRPLL_PLL_ENABLE, "WRPLL1 enabled\n");
+	I915_STATE_WARN(I915_READ(WRPLL_CTL(1)) & WRPLL_PLL_ENABLE, "WRPLL2 enabled\n");
+	I915_STATE_WARN(I915_READ(PCH_PP_STATUS) & PP_ON, "Panel power on\n");
+	I915_STATE_WARN(I915_READ(BLC_PWM_CPU_CTL2) & BLM_PWM_ENABLE,
+	     "CPU PWM1 enabled\n");
+	if (IS_HASWELL(dev))
+		I915_STATE_WARN(I915_READ(HSW_BLC_PWM2_CTL) & BLM_PWM_ENABLE,
+		     "CPU PWM2 enabled\n");
+	I915_STATE_WARN(I915_READ(BLC_PWM_PCH_CTL1) & BLM_PCH_PWM_ENABLE,
+	     "PCH PWM1 enabled\n");
+	I915_STATE_WARN(I915_READ(UTIL_PIN_CTL) & UTIL_PIN_ENABLE,
+	     "Utility pin enabled\n");
+	I915_STATE_WARN(I915_READ(PCH_GTC_CTL) & PCH_GTC_ENABLE, "PCH GTC enabled\n");
+
+	/*
+	 * In theory we can still leave IRQs enabled, as long as only the HPD
+	 * interrupts remain enabled. We used to check for that, but since it's
+	 * gen-specific and since we only disable LCPLL after we fully disable
+	 * the interrupts, the check below should be enough.
+	 */
+	I915_STATE_WARN(intel_irqs_enabled(dev_priv), "IRQs enabled\n");
+}
+
+static uint32_t hsw_read_dcomp(struct drm_i915_private *dev_priv)
+{
+	struct drm_device *dev = dev_priv->dev;
+
+	if (IS_HASWELL(dev))
+		return I915_READ(D_COMP_HSW);
+	else
+		return I915_READ(D_COMP_BDW);
+}
+
+static void hsw_write_dcomp(struct drm_i915_private *dev_priv, uint32_t val)
+{
+	struct drm_device *dev = dev_priv->dev;
+
+	if (IS_HASWELL(dev)) {
+		mutex_lock(&dev_priv->rps.hw_lock);
+		if (sandybridge_pcode_write(dev_priv, GEN6_PCODE_WRITE_D_COMP,
+					    val))
+			DRM_ERROR("Failed to write to D_COMP\n");
+		mutex_unlock(&dev_priv->rps.hw_lock);
+	} else {
+		I915_WRITE(D_COMP_BDW, val);
+		POSTING_READ(D_COMP_BDW);
+	}
+}
+
+/*
+ * This function implements pieces of two sequences from BSpec:
+ * - Sequence for display software to disable LCPLL
+ * - Sequence for display software to allow package C8+
+ * The steps implemented here are just the steps that actually touch the LCPLL
+ * register. Callers should take care of disabling all the display engine
+ * functions, doing the mode unset, fixing interrupts, etc.
+ */
+static void hsw_disable_lcpll(struct drm_i915_private *dev_priv,
+			      bool switch_to_fclk, bool allow_power_down)
+{
+	uint32_t val;
+
+	assert_can_disable_lcpll(dev_priv);
+
+	val = I915_READ(LCPLL_CTL);
+
+	if (switch_to_fclk) {
+		val |= LCPLL_CD_SOURCE_FCLK;
+		I915_WRITE(LCPLL_CTL, val);
+
+		if (wait_for_us(I915_READ(LCPLL_CTL) &
+				LCPLL_CD_SOURCE_FCLK_DONE, 1))
+			DRM_ERROR("Switching to FCLK failed\n");
+
+		val = I915_READ(LCPLL_CTL);
+	}
+
+	val |= LCPLL_PLL_DISABLE;
+	I915_WRITE(LCPLL_CTL, val);
+	POSTING_READ(LCPLL_CTL);
+
+	if (wait_for((I915_READ(LCPLL_CTL) & LCPLL_PLL_LOCK) == 0, 1))
+		DRM_ERROR("LCPLL still locked\n");
+
+	val = hsw_read_dcomp(dev_priv);
+	val |= D_COMP_COMP_DISABLE;
+	hsw_write_dcomp(dev_priv, val);
+	ndelay(100);
+
+	if (wait_for((hsw_read_dcomp(dev_priv) & D_COMP_RCOMP_IN_PROGRESS) == 0,
+		     1))
+		DRM_ERROR("D_COMP RCOMP still in progress\n");
+
+	if (allow_power_down) {
+		val = I915_READ(LCPLL_CTL);
+		val |= LCPLL_POWER_DOWN_ALLOW;
+		I915_WRITE(LCPLL_CTL, val);
+		POSTING_READ(LCPLL_CTL);
+	}
+}
+
+/*
+ * Fully restores LCPLL, disallowing power down and switching back to LCPLL
+ * source.
+ */
+static void hsw_restore_lcpll(struct drm_i915_private *dev_priv)
+{
+	uint32_t val;
+
+	val = I915_READ(LCPLL_CTL);
+
+	if ((val & (LCPLL_PLL_LOCK | LCPLL_PLL_DISABLE | LCPLL_CD_SOURCE_FCLK |
+		    LCPLL_POWER_DOWN_ALLOW)) == LCPLL_PLL_LOCK)
+		return;
+
+	/*
+	 * Make sure we're not on PC8 state before disabling PC8, otherwise
+	 * we'll hang the machine. To prevent PC8 state, just enable force_wake.
+	 */
+	intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL);
+
+	if (val & LCPLL_POWER_DOWN_ALLOW) {
+		val &= ~LCPLL_POWER_DOWN_ALLOW;
+		I915_WRITE(LCPLL_CTL, val);
+		POSTING_READ(LCPLL_CTL);
+	}
+
+	val = hsw_read_dcomp(dev_priv);
+	val |= D_COMP_COMP_FORCE;
+	val &= ~D_COMP_COMP_DISABLE;
+	hsw_write_dcomp(dev_priv, val);
+
+	val = I915_READ(LCPLL_CTL);
+	val &= ~LCPLL_PLL_DISABLE;
+	I915_WRITE(LCPLL_CTL, val);
+
+	if (wait_for(I915_READ(LCPLL_CTL) & LCPLL_PLL_LOCK, 5))
+		DRM_ERROR("LCPLL not locked yet\n");
+
+	if (val & LCPLL_CD_SOURCE_FCLK) {
+		val = I915_READ(LCPLL_CTL);
+		val &= ~LCPLL_CD_SOURCE_FCLK;
+		I915_WRITE(LCPLL_CTL, val);
+
+		if (wait_for_us((I915_READ(LCPLL_CTL) &
+				 LCPLL_CD_SOURCE_FCLK_DONE) == 0, 1))
+			DRM_ERROR("Switching back to LCPLL failed\n");
+	}
+
+	intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
+	intel_update_cdclk(dev_priv->dev);
+}
+
+/*
+ * Package states C8 and deeper are really deep PC states that can only be
+ * reached when all the devices on the system allow it, so even if the graphics
+ * device allows PC8+, it doesn't mean the system will actually get to these
+ * states. Our driver only allows PC8+ when going into runtime PM.
+ *
+ * The requirements for PC8+ are that all the outputs are disabled, the power
+ * well is disabled and most interrupts are disabled, and these are also
+ * requirements for runtime PM. When these conditions are met, we manually do
+ * the other conditions: disable the interrupts, clocks and switch LCPLL refclk
+ * to Fclk. If we're in PC8+ and we get an non-hotplug interrupt, we can hard
+ * hang the machine.
+ *
+ * When we really reach PC8 or deeper states (not just when we allow it) we lose
+ * the state of some registers, so when we come back from PC8+ we need to
+ * restore this state. We don't get into PC8+ if we're not in RC6, so we don't
+ * need to take care of the registers kept by RC6. Notice that this happens even
+ * if we don't put the device in PCI D3 state (which is what currently happens
+ * because of the runtime PM support).
+ *
+ * For more, read "Display Sequences for Package C8" on the hardware
+ * documentation.
+ */
+void hsw_enable_pc8(struct drm_i915_private *dev_priv)
+{
+	struct drm_device *dev = dev_priv->dev;
+	uint32_t val;
+
+	DRM_DEBUG_KMS("Enabling package C8+\n");
+
+	if (HAS_PCH_LPT_LP(dev)) {
+		val = I915_READ(SOUTH_DSPCLK_GATE_D);
+		val &= ~PCH_LP_PARTITION_LEVEL_DISABLE;
+		I915_WRITE(SOUTH_DSPCLK_GATE_D, val);
+	}
+
+	lpt_disable_clkout_dp(dev);
+	hsw_disable_lcpll(dev_priv, true, true);
+}
+
+void hsw_disable_pc8(struct drm_i915_private *dev_priv)
+{
+	struct drm_device *dev = dev_priv->dev;
+	uint32_t val;
+
+	DRM_DEBUG_KMS("Disabling package C8+\n");
+
+	hsw_restore_lcpll(dev_priv);
+	lpt_init_pch_refclk(dev);
+
+	if (HAS_PCH_LPT_LP(dev)) {
+		val = I915_READ(SOUTH_DSPCLK_GATE_D);
+		val |= PCH_LP_PARTITION_LEVEL_DISABLE;
+		I915_WRITE(SOUTH_DSPCLK_GATE_D, val);
+	}
+}
+
+static void broxton_modeset_commit_cdclk(struct drm_atomic_state *old_state)
+{
+	struct drm_device *dev = old_state->dev;
+	struct intel_atomic_state *old_intel_state =
+		to_intel_atomic_state(old_state);
+	unsigned int req_cdclk = old_intel_state->dev_cdclk;
+
+	broxton_set_cdclk(to_i915(dev), req_cdclk);
+}
+
+/* compute the max rate for new configuration */
+static int ilk_max_pixel_rate(struct drm_atomic_state *state)
+{
+	struct intel_atomic_state *intel_state = to_intel_atomic_state(state);
+	struct drm_i915_private *dev_priv = state->dev->dev_private;
+	struct drm_crtc *crtc;
+	struct drm_crtc_state *cstate;
+	struct intel_crtc_state *crtc_state;
+	unsigned max_pixel_rate = 0, i;
+	enum pipe pipe;
+
+	memcpy(intel_state->min_pixclk, dev_priv->min_pixclk,
+	       sizeof(intel_state->min_pixclk));
+
+	for_each_crtc_in_state(state, crtc, cstate, i) {
+		int pixel_rate;
+
+		crtc_state = to_intel_crtc_state(cstate);
+		if (!crtc_state->base.enable) {
+			intel_state->min_pixclk[i] = 0;
+			continue;
+		}
+
+		pixel_rate = ilk_pipe_pixel_rate(crtc_state);
+
+		/* pixel rate mustn't exceed 95% of cdclk with IPS on BDW */
+		if (IS_BROADWELL(dev_priv) && crtc_state->ips_enabled)
+			pixel_rate = DIV_ROUND_UP(pixel_rate * 100, 95);
+
+		intel_state->min_pixclk[i] = pixel_rate;
+	}
+
+	for_each_pipe(dev_priv, pipe)
+		max_pixel_rate = max(intel_state->min_pixclk[pipe], max_pixel_rate);
+
+	return max_pixel_rate;
+}
+
+static void broadwell_set_cdclk(struct drm_device *dev, int cdclk)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	uint32_t val, data;
+	int ret;
+
+	if (WARN((I915_READ(LCPLL_CTL) &
+		  (LCPLL_PLL_DISABLE | LCPLL_PLL_LOCK |
+		   LCPLL_CD_CLOCK_DISABLE | LCPLL_ROOT_CD_CLOCK_DISABLE |
+		   LCPLL_CD2X_CLOCK_DISABLE | LCPLL_POWER_DOWN_ALLOW |
+		   LCPLL_CD_SOURCE_FCLK)) != LCPLL_PLL_LOCK,
+		 "trying to change cdclk frequency with cdclk not enabled\n"))
+		return;
+
+	mutex_lock(&dev_priv->rps.hw_lock);
+	ret = sandybridge_pcode_write(dev_priv,
+				      BDW_PCODE_DISPLAY_FREQ_CHANGE_REQ, 0x0);
+	mutex_unlock(&dev_priv->rps.hw_lock);
+	if (ret) {
+		DRM_ERROR("failed to inform pcode about cdclk change\n");
+		return;
+	}
+
+	val = I915_READ(LCPLL_CTL);
+	val |= LCPLL_CD_SOURCE_FCLK;
+	I915_WRITE(LCPLL_CTL, val);
+
+	if (wait_for_us(I915_READ(LCPLL_CTL) &
+			LCPLL_CD_SOURCE_FCLK_DONE, 1))
+		DRM_ERROR("Switching to FCLK failed\n");
+
+	val = I915_READ(LCPLL_CTL);
+	val &= ~LCPLL_CLK_FREQ_MASK;
+
+	switch (cdclk) {
+	case 450000:
+		val |= LCPLL_CLK_FREQ_450;
+		data = 0;
+		break;
+	case 540000:
+		val |= LCPLL_CLK_FREQ_54O_BDW;
+		data = 1;
+		break;
+	case 337500:
+		val |= LCPLL_CLK_FREQ_337_5_BDW;
+		data = 2;
+		break;
+	case 675000:
+		val |= LCPLL_CLK_FREQ_675_BDW;
+		data = 3;
+		break;
+	default:
+		WARN(1, "invalid cdclk frequency\n");
+		return;
+	}
+
+	I915_WRITE(LCPLL_CTL, val);
+
+	val = I915_READ(LCPLL_CTL);
+	val &= ~LCPLL_CD_SOURCE_FCLK;
+	I915_WRITE(LCPLL_CTL, val);
+
+	if (wait_for_us((I915_READ(LCPLL_CTL) &
+			LCPLL_CD_SOURCE_FCLK_DONE) == 0, 1))
+		DRM_ERROR("Switching back to LCPLL failed\n");
+
+	mutex_lock(&dev_priv->rps.hw_lock);
+	sandybridge_pcode_write(dev_priv, HSW_PCODE_DE_WRITE_FREQ_REQ, data);
+	mutex_unlock(&dev_priv->rps.hw_lock);
+
+	I915_WRITE(CDCLK_FREQ, DIV_ROUND_CLOSEST(cdclk, 1000) - 1);
+
+	intel_update_cdclk(dev);
+
+	WARN(cdclk != dev_priv->cdclk_freq,
+	     "cdclk requested %d kHz but got %d kHz\n",
+	     cdclk, dev_priv->cdclk_freq);
+}
+
+static int broadwell_modeset_calc_cdclk(struct drm_atomic_state *state)
+{
+	struct drm_i915_private *dev_priv = to_i915(state->dev);
+	struct intel_atomic_state *intel_state = to_intel_atomic_state(state);
+	int max_pixclk = ilk_max_pixel_rate(state);
+	int cdclk;
+
+	/*
+	 * FIXME should also account for plane ratio
+	 * once 64bpp pixel formats are supported.
+	 */
+	if (max_pixclk > 540000)
+		cdclk = 675000;
+	else if (max_pixclk > 450000)
+		cdclk = 540000;
+	else if (max_pixclk > 337500)
+		cdclk = 450000;
+	else
+		cdclk = 337500;
+
+	if (cdclk > dev_priv->max_cdclk_freq) {
+		DRM_DEBUG_KMS("requested cdclk (%d kHz) exceeds max (%d kHz)\n",
+			      cdclk, dev_priv->max_cdclk_freq);
+		return -EINVAL;
+	}
+
+	intel_state->cdclk = intel_state->dev_cdclk = cdclk;
+	if (!intel_state->active_crtcs)
+		intel_state->dev_cdclk = 337500;
+
+	return 0;
+}
+
+static void broadwell_modeset_commit_cdclk(struct drm_atomic_state *old_state)
+{
+	struct drm_device *dev = old_state->dev;
+	struct intel_atomic_state *old_intel_state =
+		to_intel_atomic_state(old_state);
+	unsigned req_cdclk = old_intel_state->dev_cdclk;
+
+	broadwell_set_cdclk(dev, req_cdclk);
+}
+
+static int haswell_crtc_compute_clock(struct intel_crtc *crtc,
+				      struct intel_crtc_state *crtc_state)
+{
+	struct intel_encoder *intel_encoder =
+		intel_ddi_get_crtc_new_encoder(crtc_state);
+
+	if (intel_encoder->type != INTEL_OUTPUT_DSI) {
+		if (!intel_ddi_pll_select(crtc, crtc_state))
+			return -EINVAL;
+	}
+
+	crtc->lowfreq_avail = false;
+
+	return 0;
+}
+
+static void bxt_get_ddi_pll(struct drm_i915_private *dev_priv,
+				enum port port,
+				struct intel_crtc_state *pipe_config)
+{
+	enum intel_dpll_id id;
+
+	switch (port) {
+	case PORT_A:
+		pipe_config->ddi_pll_sel = SKL_DPLL0;
+		id = DPLL_ID_SKL_DPLL0;
+		break;
+	case PORT_B:
+		pipe_config->ddi_pll_sel = SKL_DPLL1;
+		id = DPLL_ID_SKL_DPLL1;
+		break;
+	case PORT_C:
+		pipe_config->ddi_pll_sel = SKL_DPLL2;
+		id = DPLL_ID_SKL_DPLL2;
+		break;
+	default:
+		DRM_ERROR("Incorrect port type\n");
+		return;
+	}
+
+	pipe_config->shared_dpll = intel_get_shared_dpll_by_id(dev_priv, id);
+}
+
+static void skylake_get_ddi_pll(struct drm_i915_private *dev_priv,
+				enum port port,
+				struct intel_crtc_state *pipe_config)
+{
+	enum intel_dpll_id id;
+	u32 temp;
+
+	temp = I915_READ(DPLL_CTRL2) & DPLL_CTRL2_DDI_CLK_SEL_MASK(port);
+	pipe_config->ddi_pll_sel = temp >> (port * 3 + 1);
+
+	switch (pipe_config->ddi_pll_sel) {
+	case SKL_DPLL0:
+		id = DPLL_ID_SKL_DPLL0;
+		break;
+	case SKL_DPLL1:
+		id = DPLL_ID_SKL_DPLL1;
+		break;
+	case SKL_DPLL2:
+		id = DPLL_ID_SKL_DPLL2;
+		break;
+	case SKL_DPLL3:
+		id = DPLL_ID_SKL_DPLL3;
+		break;
+	default:
+		MISSING_CASE(pipe_config->ddi_pll_sel);
+		return;
+	}
+
+	pipe_config->shared_dpll = intel_get_shared_dpll_by_id(dev_priv, id);
+}
+
+static void haswell_get_ddi_pll(struct drm_i915_private *dev_priv,
+				enum port port,
+				struct intel_crtc_state *pipe_config)
+{
+	enum intel_dpll_id id;
+
+	pipe_config->ddi_pll_sel = I915_READ(PORT_CLK_SEL(port));
+
+	switch (pipe_config->ddi_pll_sel) {
+	case PORT_CLK_SEL_WRPLL1:
+		id = DPLL_ID_WRPLL1;
+		break;
+	case PORT_CLK_SEL_WRPLL2:
+		id = DPLL_ID_WRPLL2;
+		break;
+	case PORT_CLK_SEL_SPLL:
+		id = DPLL_ID_SPLL;
+		break;
+	case PORT_CLK_SEL_LCPLL_810:
+		id = DPLL_ID_LCPLL_810;
+		break;
+	case PORT_CLK_SEL_LCPLL_1350:
+		id = DPLL_ID_LCPLL_1350;
+		break;
+	case PORT_CLK_SEL_LCPLL_2700:
+		id = DPLL_ID_LCPLL_2700;
+		break;
+	default:
+		MISSING_CASE(pipe_config->ddi_pll_sel);
+		/* fall through */
+	case PORT_CLK_SEL_NONE:
+		return;
+	}
+
+	pipe_config->shared_dpll = intel_get_shared_dpll_by_id(dev_priv, id);
+}
+
+static bool hsw_get_transcoder_state(struct intel_crtc *crtc,
+				     struct intel_crtc_state *pipe_config,
+				     unsigned long *power_domain_mask)
+{
+	struct drm_device *dev = crtc->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	enum intel_display_power_domain power_domain;
+	u32 tmp;
+
+	pipe_config->cpu_transcoder = (enum transcoder) crtc->pipe;
+
+	/*
+	 * XXX: Do intel_display_power_get_if_enabled before reading this (for
+	 * consistency and less surprising code; it's in always on power).
+	 */
+	tmp = I915_READ(TRANS_DDI_FUNC_CTL(TRANSCODER_EDP));
+	if (tmp & TRANS_DDI_FUNC_ENABLE) {
+		enum pipe trans_edp_pipe;
+		switch (tmp & TRANS_DDI_EDP_INPUT_MASK) {
+		default:
+			WARN(1, "unknown pipe linked to edp transcoder\n");
+		case TRANS_DDI_EDP_INPUT_A_ONOFF:
+		case TRANS_DDI_EDP_INPUT_A_ON:
+			trans_edp_pipe = PIPE_A;
+			break;
+		case TRANS_DDI_EDP_INPUT_B_ONOFF:
+			trans_edp_pipe = PIPE_B;
+			break;
+		case TRANS_DDI_EDP_INPUT_C_ONOFF:
+			trans_edp_pipe = PIPE_C;
+			break;
+		}
+
+		if (trans_edp_pipe == crtc->pipe)
+			pipe_config->cpu_transcoder = TRANSCODER_EDP;
+	}
+
+	power_domain = POWER_DOMAIN_TRANSCODER(pipe_config->cpu_transcoder);
+	if (!intel_display_power_get_if_enabled(dev_priv, power_domain))
+		return false;
+	*power_domain_mask |= BIT(power_domain);
+
+	tmp = I915_READ(PIPECONF(pipe_config->cpu_transcoder));
+
+	return tmp & PIPECONF_ENABLE;
+}
+
+static bool bxt_get_dsi_transcoder_state(struct intel_crtc *crtc,
+					 struct intel_crtc_state *pipe_config,
+					 unsigned long *power_domain_mask)
+{
+	struct drm_device *dev = crtc->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	enum intel_display_power_domain power_domain;
+	enum port port;
+	enum transcoder cpu_transcoder;
+	u32 tmp;
+
+	pipe_config->has_dsi_encoder = false;
+
+	for_each_port_masked(port, BIT(PORT_A) | BIT(PORT_C)) {
+		if (port == PORT_A)
+			cpu_transcoder = TRANSCODER_DSI_A;
+		else
+			cpu_transcoder = TRANSCODER_DSI_C;
+
+		power_domain = POWER_DOMAIN_TRANSCODER(cpu_transcoder);
+		if (!intel_display_power_get_if_enabled(dev_priv, power_domain))
+			continue;
+		*power_domain_mask |= BIT(power_domain);
+
+		/*
+		 * The PLL needs to be enabled with a valid divider
+		 * configuration, otherwise accessing DSI registers will hang
+		 * the machine. See BSpec North Display Engine
+		 * registers/MIPI[BXT]. We can break out here early, since we
+		 * need the same DSI PLL to be enabled for both DSI ports.
+		 */
+		if (!intel_dsi_pll_is_enabled(dev_priv))
+			break;
+
+		/* XXX: this works for video mode only */
+		tmp = I915_READ(BXT_MIPI_PORT_CTRL(port));
+		if (!(tmp & DPI_ENABLE))
+			continue;
+
+		tmp = I915_READ(MIPI_CTRL(port));
+		if ((tmp & BXT_PIPE_SELECT_MASK) != BXT_PIPE_SELECT(crtc->pipe))
+			continue;
+
+		pipe_config->cpu_transcoder = cpu_transcoder;
+		pipe_config->has_dsi_encoder = true;
+		break;
+	}
+
+	return pipe_config->has_dsi_encoder;
+}
+
+static void haswell_get_ddi_port_state(struct intel_crtc *crtc,
+				       struct intel_crtc_state *pipe_config)
+{
+	struct drm_device *dev = crtc->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_shared_dpll *pll;
+	enum port port;
+	uint32_t tmp;
+
+	tmp = I915_READ(TRANS_DDI_FUNC_CTL(pipe_config->cpu_transcoder));
+
+	port = (tmp & TRANS_DDI_PORT_MASK) >> TRANS_DDI_PORT_SHIFT;
+
+	if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev))
+		skylake_get_ddi_pll(dev_priv, port, pipe_config);
+	else if (IS_BROXTON(dev))
+		bxt_get_ddi_pll(dev_priv, port, pipe_config);
+	else
+		haswell_get_ddi_pll(dev_priv, port, pipe_config);
+
+	pll = pipe_config->shared_dpll;
+	if (pll) {
+		WARN_ON(!pll->funcs.get_hw_state(dev_priv, pll,
+						 &pipe_config->dpll_hw_state));
+	}
+
+	/*
+	 * Haswell has only FDI/PCH transcoder A. It is which is connected to
+	 * DDI E. So just check whether this pipe is wired to DDI E and whether
+	 * the PCH transcoder is on.
+	 */
+	if (INTEL_INFO(dev)->gen < 9 &&
+	    (port == PORT_E) && I915_READ(LPT_TRANSCONF) & TRANS_ENABLE) {
+		pipe_config->has_pch_encoder = true;
+
+		tmp = I915_READ(FDI_RX_CTL(PIPE_A));
+		pipe_config->fdi_lanes = ((FDI_DP_PORT_WIDTH_MASK & tmp) >>
+					  FDI_DP_PORT_WIDTH_SHIFT) + 1;
+
+		ironlake_get_fdi_m_n_config(crtc, pipe_config);
+	}
+}
+
+static bool haswell_get_pipe_config(struct intel_crtc *crtc,
+				    struct intel_crtc_state *pipe_config)
+{
+	struct drm_device *dev = crtc->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	enum intel_display_power_domain power_domain;
+	unsigned long power_domain_mask;
+	bool active;
+
+	power_domain = POWER_DOMAIN_PIPE(crtc->pipe);
+	if (!intel_display_power_get_if_enabled(dev_priv, power_domain))
+		return false;
+	power_domain_mask = BIT(power_domain);
+
+	pipe_config->shared_dpll = NULL;
+
+	active = hsw_get_transcoder_state(crtc, pipe_config, &power_domain_mask);
+
+	if (IS_BROXTON(dev_priv)) {
+		bxt_get_dsi_transcoder_state(crtc, pipe_config,
+					     &power_domain_mask);
+		WARN_ON(active && pipe_config->has_dsi_encoder);
+		if (pipe_config->has_dsi_encoder)
+			active = true;
+	}
+
+	if (!active)
+		goto out;
+
+	if (!pipe_config->has_dsi_encoder) {
+		haswell_get_ddi_port_state(crtc, pipe_config);
+		intel_get_pipe_timings(crtc, pipe_config);
+	}
+
+	intel_get_pipe_src_size(crtc, pipe_config);
+
+	pipe_config->gamma_mode =
+		I915_READ(GAMMA_MODE(crtc->pipe)) & GAMMA_MODE_MODE_MASK;
+
+	if (INTEL_INFO(dev)->gen >= 9) {
+		skl_init_scalers(dev, crtc, pipe_config);
+	}
+
+	if (INTEL_INFO(dev)->gen >= 9) {
+		pipe_config->scaler_state.scaler_id = -1;
+		pipe_config->scaler_state.scaler_users &= ~(1 << SKL_CRTC_INDEX);
+	}
+
+	power_domain = POWER_DOMAIN_PIPE_PANEL_FITTER(crtc->pipe);
+	if (intel_display_power_get_if_enabled(dev_priv, power_domain)) {
+		power_domain_mask |= BIT(power_domain);
+		if (INTEL_INFO(dev)->gen >= 9)
+			skylake_get_pfit_config(crtc, pipe_config);
+		else
+			ironlake_get_pfit_config(crtc, pipe_config);
+	}
+
+	if (IS_HASWELL(dev))
+		pipe_config->ips_enabled = hsw_crtc_supports_ips(crtc) &&
+			(I915_READ(IPS_CTL) & IPS_ENABLE);
+
+	if (pipe_config->cpu_transcoder != TRANSCODER_EDP &&
+	    !transcoder_is_dsi(pipe_config->cpu_transcoder)) {
+		pipe_config->pixel_multiplier =
+			I915_READ(PIPE_MULT(pipe_config->cpu_transcoder)) + 1;
+	} else {
+		pipe_config->pixel_multiplier = 1;
+	}
+
+out:
+	for_each_power_domain(power_domain, power_domain_mask)
+		intel_display_power_put(dev_priv, power_domain);
+
+	return active;
+}
+
+static void i845_update_cursor(struct drm_crtc *crtc, u32 base,
+			       const struct intel_plane_state *plane_state)
+{
+	struct drm_device *dev = crtc->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	uint32_t cntl = 0, size = 0;
+
+	if (plane_state && plane_state->visible) {
+		unsigned int width = plane_state->base.crtc_w;
+		unsigned int height = plane_state->base.crtc_h;
+		unsigned int stride = roundup_pow_of_two(width) * 4;
+
+		switch (stride) {
+		default:
+			WARN_ONCE(1, "Invalid cursor width/stride, width=%u, stride=%u\n",
+				  width, stride);
+			stride = 256;
+			/* fallthrough */
+		case 256:
+		case 512:
+		case 1024:
+		case 2048:
+			break;
+		}
+
+		cntl |= CURSOR_ENABLE |
+			CURSOR_GAMMA_ENABLE |
+			CURSOR_FORMAT_ARGB |
+			CURSOR_STRIDE(stride);
+
+		size = (height << 12) | width;
+	}
+
+	if (intel_crtc->cursor_cntl != 0 &&
+	    (intel_crtc->cursor_base != base ||
+	     intel_crtc->cursor_size != size ||
+	     intel_crtc->cursor_cntl != cntl)) {
+		/* On these chipsets we can only modify the base/size/stride
+		 * whilst the cursor is disabled.
+		 */
+		I915_WRITE(CURCNTR(PIPE_A), 0);
+		POSTING_READ(CURCNTR(PIPE_A));
+		intel_crtc->cursor_cntl = 0;
+	}
+
+	if (intel_crtc->cursor_base != base) {
+		I915_WRITE(CURBASE(PIPE_A), base);
+		intel_crtc->cursor_base = base;
+	}
+
+	if (intel_crtc->cursor_size != size) {
+		I915_WRITE(CURSIZE, size);
+		intel_crtc->cursor_size = size;
+	}
+
+	if (intel_crtc->cursor_cntl != cntl) {
+		I915_WRITE(CURCNTR(PIPE_A), cntl);
+		POSTING_READ(CURCNTR(PIPE_A));
+		intel_crtc->cursor_cntl = cntl;
+	}
+}
+
+static void i9xx_update_cursor(struct drm_crtc *crtc, u32 base,
+			       const struct intel_plane_state *plane_state)
+{
+	struct drm_device *dev = crtc->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	int pipe = intel_crtc->pipe;
+	uint32_t cntl = 0;
+
+	if (plane_state && plane_state->visible) {
+		cntl = MCURSOR_GAMMA_ENABLE;
+		switch (plane_state->base.crtc_w) {
+			case 64:
+				cntl |= CURSOR_MODE_64_ARGB_AX;
+				break;
+			case 128:
+				cntl |= CURSOR_MODE_128_ARGB_AX;
+				break;
+			case 256:
+				cntl |= CURSOR_MODE_256_ARGB_AX;
+				break;
+			default:
+				MISSING_CASE(plane_state->base.crtc_w);
+				return;
+		}
+		cntl |= pipe << 28; /* Connect to correct pipe */
+
+		if (HAS_DDI(dev))
+			cntl |= CURSOR_PIPE_CSC_ENABLE;
+
+		if (plane_state->base.rotation == BIT(DRM_ROTATE_180))
+			cntl |= CURSOR_ROTATE_180;
+	}
+
+	if (intel_crtc->cursor_cntl != cntl) {
+		I915_WRITE(CURCNTR(pipe), cntl);
+		POSTING_READ(CURCNTR(pipe));
+		intel_crtc->cursor_cntl = cntl;
+	}
+
+	/* and commit changes on next vblank */
+	I915_WRITE(CURBASE(pipe), base);
+	POSTING_READ(CURBASE(pipe));
+
+	intel_crtc->cursor_base = base;
+}
+
+/* If no-part of the cursor is visible on the framebuffer, then the GPU may hang... */
+static void intel_crtc_update_cursor(struct drm_crtc *crtc,
+				     const struct intel_plane_state *plane_state)
+{
+	struct drm_device *dev = crtc->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	int pipe = intel_crtc->pipe;
+	u32 base = intel_crtc->cursor_addr;
+	u32 pos = 0;
+
+	if (plane_state) {
+		int x = plane_state->base.crtc_x;
+		int y = plane_state->base.crtc_y;
+
+		if (x < 0) {
+			pos |= CURSOR_POS_SIGN << CURSOR_X_SHIFT;
+			x = -x;
+		}
+		pos |= x << CURSOR_X_SHIFT;
+
+		if (y < 0) {
+			pos |= CURSOR_POS_SIGN << CURSOR_Y_SHIFT;
+			y = -y;
+		}
+		pos |= y << CURSOR_Y_SHIFT;
+
+		/* ILK+ do this automagically */
+		if (HAS_GMCH_DISPLAY(dev) &&
+		    plane_state->base.rotation == BIT(DRM_ROTATE_180)) {
+			base += (plane_state->base.crtc_h *
+				 plane_state->base.crtc_w - 1) * 4;
+		}
+	}
+
+	I915_WRITE(CURPOS(pipe), pos);
+
+	if (IS_845G(dev) || IS_I865G(dev))
+		i845_update_cursor(crtc, base, plane_state);
+	else
+		i9xx_update_cursor(crtc, base, plane_state);
+}
+
+static bool cursor_size_ok(struct drm_device *dev,
+			   uint32_t width, uint32_t height)
+{
+	if (width == 0 || height == 0)
+		return false;
+
+	/*
+	 * 845g/865g are special in that they are only limited by
+	 * the width of their cursors, the height is arbitrary up to
+	 * the precision of the register. Everything else requires
+	 * square cursors, limited to a few power-of-two sizes.
+	 */
+	if (IS_845G(dev) || IS_I865G(dev)) {
+		if ((width & 63) != 0)
+			return false;
+
+		if (width > (IS_845G(dev) ? 64 : 512))
+			return false;
+
+		if (height > 1023)
+			return false;
+	} else {
+		switch (width | height) {
+		case 256:
+		case 128:
+			if (IS_GEN2(dev))
+				return false;
+		case 64:
+			break;
+		default:
+			return false;
+		}
+	}
+
+	return true;
+}
+
+/* VESA 640x480x72Hz mode to set on the pipe */
+static struct drm_display_mode load_detect_mode = {
+	DRM_MODE("640x480", DRM_MODE_TYPE_DEFAULT, 31500, 640, 664,
+		 704, 832, 0, 480, 489, 491, 520, 0, DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
+};
+
+struct drm_framebuffer *
+__intel_framebuffer_create(struct drm_device *dev,
+			   struct drm_mode_fb_cmd2 *mode_cmd,
+			   struct drm_i915_gem_object *obj)
+{
+	struct intel_framebuffer *intel_fb;
+	int ret;
+
+	intel_fb = kzalloc(sizeof(*intel_fb), GFP_KERNEL);
+	if (!intel_fb)
+		return ERR_PTR(-ENOMEM);
+
+	ret = intel_framebuffer_init(dev, intel_fb, mode_cmd, obj);
+	if (ret)
+		goto err;
+
+	return &intel_fb->base;
+
+err:
+	kfree(intel_fb);
+	return ERR_PTR(ret);
+}
+
+static struct drm_framebuffer *
+intel_framebuffer_create(struct drm_device *dev,
+			 struct drm_mode_fb_cmd2 *mode_cmd,
+			 struct drm_i915_gem_object *obj)
+{
+	struct drm_framebuffer *fb;
+	int ret;
+
+	ret = i915_mutex_lock_interruptible(dev);
+	if (ret)
+		return ERR_PTR(ret);
+	fb = __intel_framebuffer_create(dev, mode_cmd, obj);
+	mutex_unlock(&dev->struct_mutex);
+
+	return fb;
+}
+
+static u32
+intel_framebuffer_pitch_for_width(int width, int bpp)
+{
+	u32 pitch = DIV_ROUND_UP(width * bpp, 8);
+	return ALIGN(pitch, 64);
+}
+
+static u32
+intel_framebuffer_size_for_mode(struct drm_display_mode *mode, int bpp)
+{
+	u32 pitch = intel_framebuffer_pitch_for_width(mode->hdisplay, bpp);
+	return PAGE_ALIGN(pitch * mode->vdisplay);
+}
+
+static struct drm_framebuffer *
+intel_framebuffer_create_for_mode(struct drm_device *dev,
+				  struct drm_display_mode *mode,
+				  int depth, int bpp)
+{
+	struct drm_framebuffer *fb;
+	struct drm_i915_gem_object *obj;
+	struct drm_mode_fb_cmd2 mode_cmd = { 0 };
+
+	obj = i915_gem_alloc_object(dev,
+				    intel_framebuffer_size_for_mode(mode, bpp));
+	if (obj == NULL)
+		return ERR_PTR(-ENOMEM);
+
+	mode_cmd.width = mode->hdisplay;
+	mode_cmd.height = mode->vdisplay;
+	mode_cmd.pitches[0] = intel_framebuffer_pitch_for_width(mode_cmd.width,
+								bpp);
+	mode_cmd.pixel_format = drm_mode_legacy_fb_format(bpp, depth);
+
+	fb = intel_framebuffer_create(dev, &mode_cmd, obj);
+	if (IS_ERR(fb))
+		drm_gem_object_unreference_unlocked(&obj->base);
+
+	return fb;
+}
+
+static struct drm_framebuffer *
+mode_fits_in_fbdev(struct drm_device *dev,
+		   struct drm_display_mode *mode)
+{
+#ifdef CONFIG_DRM_FBDEV_EMULATION
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct drm_i915_gem_object *obj;
+	struct drm_framebuffer *fb;
+
+	if (!dev_priv->fbdev)
+		return NULL;
+
+	if (!dev_priv->fbdev->fb)
+		return NULL;
+
+	obj = dev_priv->fbdev->fb->obj;
+	BUG_ON(!obj);
+
+	fb = &dev_priv->fbdev->fb->base;
+	if (fb->pitches[0] < intel_framebuffer_pitch_for_width(mode->hdisplay,
+							       fb->bits_per_pixel))
+		return NULL;
+
+	if (obj->base.size < mode->vdisplay * fb->pitches[0])
+		return NULL;
+
+	drm_framebuffer_reference(fb);
+	return fb;
+#else
+	return NULL;
+#endif
+}
+
+static int intel_modeset_setup_plane_state(struct drm_atomic_state *state,
+					   struct drm_crtc *crtc,
+					   struct drm_display_mode *mode,
+					   struct drm_framebuffer *fb,
+					   int x, int y)
+{
+	struct drm_plane_state *plane_state;
+	int hdisplay, vdisplay;
+	int ret;
+
+	plane_state = drm_atomic_get_plane_state(state, crtc->primary);
+	if (IS_ERR(plane_state))
+		return PTR_ERR(plane_state);
+
+	if (mode)
+		drm_crtc_get_hv_timing(mode, &hdisplay, &vdisplay);
+	else
+		hdisplay = vdisplay = 0;
+
+	ret = drm_atomic_set_crtc_for_plane(plane_state, fb ? crtc : NULL);
+	if (ret)
+		return ret;
+	drm_atomic_set_fb_for_plane(plane_state, fb);
+	plane_state->crtc_x = 0;
+	plane_state->crtc_y = 0;
+	plane_state->crtc_w = hdisplay;
+	plane_state->crtc_h = vdisplay;
+	plane_state->src_x = x << 16;
+	plane_state->src_y = y << 16;
+	plane_state->src_w = hdisplay << 16;
+	plane_state->src_h = vdisplay << 16;
+
+	return 0;
+}
+
+bool intel_get_load_detect_pipe(struct drm_connector *connector,
+				struct drm_display_mode *mode,
+				struct intel_load_detect_pipe *old,
+				struct drm_modeset_acquire_ctx *ctx)
+{
+	struct intel_crtc *intel_crtc;
+	struct intel_encoder *intel_encoder =
+		intel_attached_encoder(connector);
+	struct drm_crtc *possible_crtc;
+	struct drm_encoder *encoder = &intel_encoder->base;
+	struct drm_crtc *crtc = NULL;
+	struct drm_device *dev = encoder->dev;
+	struct drm_framebuffer *fb;
+	struct drm_mode_config *config = &dev->mode_config;
+	struct drm_atomic_state *state = NULL, *restore_state = NULL;
+	struct drm_connector_state *connector_state;
+	struct intel_crtc_state *crtc_state;
+	int ret, i = -1;
+
+	DRM_DEBUG_KMS("[CONNECTOR:%d:%s], [ENCODER:%d:%s]\n",
+		      connector->base.id, connector->name,
+		      encoder->base.id, encoder->name);
+
+	old->restore_state = NULL;
+
+retry:
+	ret = drm_modeset_lock(&config->connection_mutex, ctx);
+	if (ret)
+		goto fail;
+
+	/*
+	 * Algorithm gets a little messy:
+	 *
+	 *   - if the connector already has an assigned crtc, use it (but make
+	 *     sure it's on first)
+	 *
+	 *   - try to find the first unused crtc that can drive this connector,
+	 *     and use that if we find one
+	 */
+
+	/* See if we already have a CRTC for this connector */
+	if (connector->state->crtc) {
+		crtc = connector->state->crtc;
+
+		ret = drm_modeset_lock(&crtc->mutex, ctx);
+		if (ret)
+			goto fail;
+
+		/* Make sure the crtc and connector are running */
+		goto found;
+	}
+
+	/* Find an unused one (if possible) */
+	for_each_crtc(dev, possible_crtc) {
+		i++;
+		if (!(encoder->possible_crtcs & (1 << i)))
+			continue;
+
+		ret = drm_modeset_lock(&possible_crtc->mutex, ctx);
+		if (ret)
+			goto fail;
+
+		if (possible_crtc->state->enable) {
+			drm_modeset_unlock(&possible_crtc->mutex);
+			continue;
+		}
+
+		crtc = possible_crtc;
+		break;
+	}
+
+	/*
+	 * If we didn't find an unused CRTC, don't use any.
+	 */
+	if (!crtc) {
+		DRM_DEBUG_KMS("no pipe available for load-detect\n");
+		goto fail;
+	}
+
+found:
+	intel_crtc = to_intel_crtc(crtc);
+
+	ret = drm_modeset_lock(&crtc->primary->mutex, ctx);
+	if (ret)
+		goto fail;
+
+	state = drm_atomic_state_alloc(dev);
+	restore_state = drm_atomic_state_alloc(dev);
+	if (!state || !restore_state) {
+		ret = -ENOMEM;
+		goto fail;
+	}
+
+	state->acquire_ctx = ctx;
+	restore_state->acquire_ctx = ctx;
+
+	connector_state = drm_atomic_get_connector_state(state, connector);
+	if (IS_ERR(connector_state)) {
+		ret = PTR_ERR(connector_state);
+		goto fail;
+	}
+
+	ret = drm_atomic_set_crtc_for_connector(connector_state, crtc);
+	if (ret)
+		goto fail;
+
+	crtc_state = intel_atomic_get_crtc_state(state, intel_crtc);
+	if (IS_ERR(crtc_state)) {
+		ret = PTR_ERR(crtc_state);
+		goto fail;
+	}
+
+	crtc_state->base.active = crtc_state->base.enable = true;
+
+	if (!mode)
+		mode = &load_detect_mode;
+
+	/* We need a framebuffer large enough to accommodate all accesses
+	 * that the plane may generate whilst we perform load detection.
+	 * We can not rely on the fbcon either being present (we get called
+	 * during its initialisation to detect all boot displays, or it may
+	 * not even exist) or that it is large enough to satisfy the
+	 * requested mode.
+	 */
+	fb = mode_fits_in_fbdev(dev, mode);
+	if (fb == NULL) {
+		DRM_DEBUG_KMS("creating tmp fb for load-detection\n");
+		fb = intel_framebuffer_create_for_mode(dev, mode, 24, 32);
+	} else
+		DRM_DEBUG_KMS("reusing fbdev for load-detection framebuffer\n");
+	if (IS_ERR(fb)) {
+		DRM_DEBUG_KMS("failed to allocate framebuffer for load-detection\n");
+		goto fail;
+	}
+
+	ret = intel_modeset_setup_plane_state(state, crtc, mode, fb, 0, 0);
+	if (ret)
+		goto fail;
+
+	drm_framebuffer_unreference(fb);
+
+	ret = drm_atomic_set_mode_for_crtc(&crtc_state->base, mode);
+	if (ret)
+		goto fail;
+
+	ret = PTR_ERR_OR_ZERO(drm_atomic_get_connector_state(restore_state, connector));
+	if (!ret)
+		ret = PTR_ERR_OR_ZERO(drm_atomic_get_crtc_state(restore_state, crtc));
+	if (!ret)
+		ret = PTR_ERR_OR_ZERO(drm_atomic_get_plane_state(restore_state, crtc->primary));
+	if (ret) {
+		DRM_DEBUG_KMS("Failed to create a copy of old state to restore: %i\n", ret);
+		goto fail;
+	}
+
+	ret = drm_atomic_commit(state);
+	if (ret) {
+		DRM_DEBUG_KMS("failed to set mode on load-detect pipe\n");
+		goto fail;
+	}
+
+	old->restore_state = restore_state;
+
+	/* let the connector get through one full cycle before testing */
+	intel_wait_for_vblank(dev, intel_crtc->pipe);
+	return true;
+
+fail:
+	drm_atomic_state_free(state);
+	drm_atomic_state_free(restore_state);
+	restore_state = state = NULL;
+
+	if (ret == -EDEADLK) {
+		drm_modeset_backoff(ctx);
+		goto retry;
+	}
+
+	return false;
+}
+
+void intel_release_load_detect_pipe(struct drm_connector *connector,
+				    struct intel_load_detect_pipe *old,
+				    struct drm_modeset_acquire_ctx *ctx)
+{
+	struct intel_encoder *intel_encoder =
+		intel_attached_encoder(connector);
+	struct drm_encoder *encoder = &intel_encoder->base;
+	struct drm_atomic_state *state = old->restore_state;
+	int ret;
+
+	DRM_DEBUG_KMS("[CONNECTOR:%d:%s], [ENCODER:%d:%s]\n",
+		      connector->base.id, connector->name,
+		      encoder->base.id, encoder->name);
+
+	if (!state)
+		return;
+
+	ret = drm_atomic_commit(state);
+	if (ret) {
+		DRM_DEBUG_KMS("Couldn't release load detect pipe: %i\n", ret);
+		drm_atomic_state_free(state);
+	}
+}
+
+static int i9xx_pll_refclk(struct drm_device *dev,
+			   const struct intel_crtc_state *pipe_config)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	u32 dpll = pipe_config->dpll_hw_state.dpll;
+
+	if ((dpll & PLL_REF_INPUT_MASK) == PLLB_REF_INPUT_SPREADSPECTRUMIN)
+		return dev_priv->vbt.lvds_ssc_freq;
+	else if (HAS_PCH_SPLIT(dev))
+		return 120000;
+	else if (!IS_GEN2(dev))
+		return 96000;
+	else
+		return 48000;
+}
+
+/* Returns the clock of the currently programmed mode of the given pipe. */
+static void i9xx_crtc_clock_get(struct intel_crtc *crtc,
+				struct intel_crtc_state *pipe_config)
+{
+	struct drm_device *dev = crtc->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	int pipe = pipe_config->cpu_transcoder;
+	u32 dpll = pipe_config->dpll_hw_state.dpll;
+	u32 fp;
+	intel_clock_t clock;
+	int port_clock;
+	int refclk = i9xx_pll_refclk(dev, pipe_config);
+
+	if ((dpll & DISPLAY_RATE_SELECT_FPA1) == 0)
+		fp = pipe_config->dpll_hw_state.fp0;
+	else
+		fp = pipe_config->dpll_hw_state.fp1;
+
+	clock.m1 = (fp & FP_M1_DIV_MASK) >> FP_M1_DIV_SHIFT;
+	if (IS_PINEVIEW(dev)) {
+		clock.n = ffs((fp & FP_N_PINEVIEW_DIV_MASK) >> FP_N_DIV_SHIFT) - 1;
+		clock.m2 = (fp & FP_M2_PINEVIEW_DIV_MASK) >> FP_M2_DIV_SHIFT;
+	} else {
+		clock.n = (fp & FP_N_DIV_MASK) >> FP_N_DIV_SHIFT;
+		clock.m2 = (fp & FP_M2_DIV_MASK) >> FP_M2_DIV_SHIFT;
+	}
+
+	if (!IS_GEN2(dev)) {
+		if (IS_PINEVIEW(dev))
+			clock.p1 = ffs((dpll & DPLL_FPA01_P1_POST_DIV_MASK_PINEVIEW) >>
+				DPLL_FPA01_P1_POST_DIV_SHIFT_PINEVIEW);
+		else
+			clock.p1 = ffs((dpll & DPLL_FPA01_P1_POST_DIV_MASK) >>
+			       DPLL_FPA01_P1_POST_DIV_SHIFT);
+
+		switch (dpll & DPLL_MODE_MASK) {
+		case DPLLB_MODE_DAC_SERIAL:
+			clock.p2 = dpll & DPLL_DAC_SERIAL_P2_CLOCK_DIV_5 ?
+				5 : 10;
+			break;
+		case DPLLB_MODE_LVDS:
+			clock.p2 = dpll & DPLLB_LVDS_P2_CLOCK_DIV_7 ?
+				7 : 14;
+			break;
+		default:
+			DRM_DEBUG_KMS("Unknown DPLL mode %08x in programmed "
+				  "mode\n", (int)(dpll & DPLL_MODE_MASK));
+			return;
+		}
+
+		if (IS_PINEVIEW(dev))
+			port_clock = pnv_calc_dpll_params(refclk, &clock);
+		else
+			port_clock = i9xx_calc_dpll_params(refclk, &clock);
+	} else {
+		u32 lvds = IS_I830(dev) ? 0 : I915_READ(LVDS);
+		bool is_lvds = (pipe == 1) && (lvds & LVDS_PORT_EN);
+
+		if (is_lvds) {
+			clock.p1 = ffs((dpll & DPLL_FPA01_P1_POST_DIV_MASK_I830_LVDS) >>
+				       DPLL_FPA01_P1_POST_DIV_SHIFT);
+
+			if (lvds & LVDS_CLKB_POWER_UP)
+				clock.p2 = 7;
+			else
+				clock.p2 = 14;
+		} else {
+			if (dpll & PLL_P1_DIVIDE_BY_TWO)
+				clock.p1 = 2;
+			else {
+				clock.p1 = ((dpll & DPLL_FPA01_P1_POST_DIV_MASK_I830) >>
+					    DPLL_FPA01_P1_POST_DIV_SHIFT) + 2;
+			}
+			if (dpll & PLL_P2_DIVIDE_BY_4)
+				clock.p2 = 4;
+			else
+				clock.p2 = 2;
+		}
+
+		port_clock = i9xx_calc_dpll_params(refclk, &clock);
+	}
+
+	/*
+	 * This value includes pixel_multiplier. We will use
+	 * port_clock to compute adjusted_mode.crtc_clock in the
+	 * encoder's get_config() function.
+	 */
+	pipe_config->port_clock = port_clock;
+}
+
+int intel_dotclock_calculate(int link_freq,
+			     const struct intel_link_m_n *m_n)
+{
+	/*
+	 * The calculation for the data clock is:
+	 * pixel_clock = ((m/n)*(link_clock * nr_lanes))/bpp
+	 * But we want to avoid losing precison if possible, so:
+	 * pixel_clock = ((m * link_clock * nr_lanes)/(n*bpp))
+	 *
+	 * and the link clock is simpler:
+	 * link_clock = (m * link_clock) / n
+	 */
+
+	if (!m_n->link_n)
+		return 0;
+
+	return div_u64((u64)m_n->link_m * link_freq, m_n->link_n);
+}
+
+static void ironlake_pch_clock_get(struct intel_crtc *crtc,
+				   struct intel_crtc_state *pipe_config)
+{
+	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
+
+	/* read out port_clock from the DPLL */
+	i9xx_crtc_clock_get(crtc, pipe_config);
+
+	/*
+	 * In case there is an active pipe without active ports,
+	 * we may need some idea for the dotclock anyway.
+	 * Calculate one based on the FDI configuration.
+	 */
+	pipe_config->base.adjusted_mode.crtc_clock =
+		intel_dotclock_calculate(intel_fdi_link_freq(dev_priv, pipe_config),
+					 &pipe_config->fdi_m_n);
+}
+
+/** Returns the currently programmed mode of the given pipe. */
+struct drm_display_mode *intel_crtc_mode_get(struct drm_device *dev,
+					     struct drm_crtc *crtc)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
+	struct drm_display_mode *mode;
+	struct intel_crtc_state *pipe_config;
+	int htot = I915_READ(HTOTAL(cpu_transcoder));
+	int hsync = I915_READ(HSYNC(cpu_transcoder));
+	int vtot = I915_READ(VTOTAL(cpu_transcoder));
+	int vsync = I915_READ(VSYNC(cpu_transcoder));
+	enum pipe pipe = intel_crtc->pipe;
+
+	mode = kzalloc(sizeof(*mode), GFP_KERNEL);
+	if (!mode)
+		return NULL;
+
+	pipe_config = kzalloc(sizeof(*pipe_config), GFP_KERNEL);
+	if (!pipe_config) {
+		kfree(mode);
+		return NULL;
+	}
+
+	/*
+	 * Construct a pipe_config sufficient for getting the clock info
+	 * back out of crtc_clock_get.
+	 *
+	 * Note, if LVDS ever uses a non-1 pixel multiplier, we'll need
+	 * to use a real value here instead.
+	 */
+	pipe_config->cpu_transcoder = (enum transcoder) pipe;
+	pipe_config->pixel_multiplier = 1;
+	pipe_config->dpll_hw_state.dpll = I915_READ(DPLL(pipe));
+	pipe_config->dpll_hw_state.fp0 = I915_READ(FP0(pipe));
+	pipe_config->dpll_hw_state.fp1 = I915_READ(FP1(pipe));
+	i9xx_crtc_clock_get(intel_crtc, pipe_config);
+
+	mode->clock = pipe_config->port_clock / pipe_config->pixel_multiplier;
+	mode->hdisplay = (htot & 0xffff) + 1;
+	mode->htotal = ((htot & 0xffff0000) >> 16) + 1;
+	mode->hsync_start = (hsync & 0xffff) + 1;
+	mode->hsync_end = ((hsync & 0xffff0000) >> 16) + 1;
+	mode->vdisplay = (vtot & 0xffff) + 1;
+	mode->vtotal = ((vtot & 0xffff0000) >> 16) + 1;
+	mode->vsync_start = (vsync & 0xffff) + 1;
+	mode->vsync_end = ((vsync & 0xffff0000) >> 16) + 1;
+
+	drm_mode_set_name(mode);
+
+	kfree(pipe_config);
+
+	return mode;
+}
+
+void intel_mark_busy(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	if (dev_priv->mm.busy)
+		return;
+
+	intel_runtime_pm_get(dev_priv);
+	i915_update_gfx_val(dev_priv);
+	if (INTEL_INFO(dev)->gen >= 6)
+		gen6_rps_busy(dev_priv);
+	dev_priv->mm.busy = true;
+}
+
+void intel_mark_idle(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	if (!dev_priv->mm.busy)
+		return;
+
+	dev_priv->mm.busy = false;
+
+	if (INTEL_INFO(dev)->gen >= 6)
+		gen6_rps_idle(dev->dev_private);
+
+	intel_runtime_pm_put(dev_priv);
+}
+
+static void intel_crtc_destroy(struct drm_crtc *crtc)
+{
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	struct drm_device *dev = crtc->dev;
+	struct intel_unpin_work *work;
+
+	spin_lock_irq(&dev->event_lock);
+	work = intel_crtc->unpin_work;
+	intel_crtc->unpin_work = NULL;
+	spin_unlock_irq(&dev->event_lock);
+
+	if (work) {
+		cancel_work_sync(&work->work);
+		kfree(work);
+	}
+
+	drm_crtc_cleanup(crtc);
+
+	kfree(intel_crtc);
+}
+
+static void intel_unpin_work_fn(struct work_struct *__work)
+{
+	struct intel_unpin_work *work =
+		container_of(__work, struct intel_unpin_work, work);
+	struct intel_crtc *crtc = to_intel_crtc(work->crtc);
+	struct drm_device *dev = crtc->base.dev;
+	struct drm_plane *primary = crtc->base.primary;
+
+	mutex_lock(&dev->struct_mutex);
+	intel_unpin_fb_obj(work->old_fb, primary->state->rotation);
+	drm_gem_object_unreference(&work->pending_flip_obj->base);
+
+	if (work->flip_queued_req)
+		i915_gem_request_assign(&work->flip_queued_req, NULL);
+	mutex_unlock(&dev->struct_mutex);
+
+	intel_frontbuffer_flip_complete(dev, to_intel_plane(primary)->frontbuffer_bit);
+	intel_fbc_post_update(crtc);
+	drm_framebuffer_unreference(work->old_fb);
+
+	BUG_ON(atomic_read(&crtc->unpin_work_count) == 0);
+	atomic_dec(&crtc->unpin_work_count);
+
+	kfree(work);
+}
+
+static void do_intel_finish_page_flip(struct drm_device *dev,
+				      struct drm_crtc *crtc)
+{
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	struct intel_unpin_work *work;
+	unsigned long flags;
+
+	/* Ignore early vblank irqs */
+	if (intel_crtc == NULL)
+		return;
+
+	/*
+	 * This is called both by irq handlers and the reset code (to complete
+	 * lost pageflips) so needs the full irqsave spinlocks.
+	 */
+	spin_lock_irqsave(&dev->event_lock, flags);
+	work = intel_crtc->unpin_work;
+
+	/* Ensure we don't miss a work->pending update ... */
+	smp_rmb();
+
+	if (work == NULL || atomic_read(&work->pending) < INTEL_FLIP_COMPLETE) {
+		spin_unlock_irqrestore(&dev->event_lock, flags);
+		return;
+	}
+
+	page_flip_completed(intel_crtc);
+
+	spin_unlock_irqrestore(&dev->event_lock, flags);
+}
+
+void intel_finish_page_flip(struct drm_device *dev, int pipe)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe];
+
+	do_intel_finish_page_flip(dev, crtc);
+}
+
+void intel_finish_page_flip_plane(struct drm_device *dev, int plane)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct drm_crtc *crtc = dev_priv->plane_to_crtc_mapping[plane];
+
+	do_intel_finish_page_flip(dev, crtc);
+}
+
+/* Is 'a' after or equal to 'b'? */
+static bool g4x_flip_count_after_eq(u32 a, u32 b)
+{
+	return !((a - b) & 0x80000000);
+}
+
+static bool page_flip_finished(struct intel_crtc *crtc)
+{
+	struct drm_device *dev = crtc->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	unsigned reset_counter;
+
+	reset_counter = i915_reset_counter(&dev_priv->gpu_error);
+	if (crtc->reset_counter != reset_counter)
+		return true;
+
+	/*
+	 * The relevant registers doen't exist on pre-ctg.
+	 * As the flip done interrupt doesn't trigger for mmio
+	 * flips on gmch platforms, a flip count check isn't
+	 * really needed there. But since ctg has the registers,
+	 * include it in the check anyway.
+	 */
+	if (INTEL_INFO(dev)->gen < 5 && !IS_G4X(dev))
+		return true;
+
+	/*
+	 * BDW signals flip done immediately if the plane
+	 * is disabled, even if the plane enable is already
+	 * armed to occur at the next vblank :(
+	 */
+
+	/*
+	 * A DSPSURFLIVE check isn't enough in case the mmio and CS flips
+	 * used the same base address. In that case the mmio flip might
+	 * have completed, but the CS hasn't even executed the flip yet.
+	 *
+	 * A flip count check isn't enough as the CS might have updated
+	 * the base address just after start of vblank, but before we
+	 * managed to process the interrupt. This means we'd complete the
+	 * CS flip too soon.
+	 *
+	 * Combining both checks should get us a good enough result. It may
+	 * still happen that the CS flip has been executed, but has not
+	 * yet actually completed. But in case the base address is the same
+	 * anyway, we don't really care.
+	 */
+	return (I915_READ(DSPSURFLIVE(crtc->plane)) & ~0xfff) ==
+		crtc->unpin_work->gtt_offset &&
+		g4x_flip_count_after_eq(I915_READ(PIPE_FLIPCOUNT_G4X(crtc->pipe)),
+				    crtc->unpin_work->flip_count);
+}
+
+void intel_prepare_page_flip(struct drm_device *dev, int plane)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_crtc *intel_crtc =
+		to_intel_crtc(dev_priv->plane_to_crtc_mapping[plane]);
+	unsigned long flags;
+
+
+	/*
+	 * This is called both by irq handlers and the reset code (to complete
+	 * lost pageflips) so needs the full irqsave spinlocks.
+	 *
+	 * NB: An MMIO update of the plane base pointer will also
+	 * generate a page-flip completion irq, i.e. every modeset
+	 * is also accompanied by a spurious intel_prepare_page_flip().
+	 */
+	spin_lock_irqsave(&dev->event_lock, flags);
+	if (intel_crtc->unpin_work && page_flip_finished(intel_crtc))
+		atomic_inc_not_zero(&intel_crtc->unpin_work->pending);
+	spin_unlock_irqrestore(&dev->event_lock, flags);
+}
+
+static inline void intel_mark_page_flip_active(struct intel_unpin_work *work)
+{
+	/* Ensure that the work item is consistent when activating it ... */
+	smp_wmb();
+	atomic_set(&work->pending, INTEL_FLIP_PENDING);
+	/* and that it is marked active as soon as the irq could fire. */
+	smp_wmb();
+}
+
+static int intel_gen2_queue_flip(struct drm_device *dev,
+				 struct drm_crtc *crtc,
+				 struct drm_framebuffer *fb,
+				 struct drm_i915_gem_object *obj,
+				 struct drm_i915_gem_request *req,
+				 uint32_t flags)
+{
+	struct intel_engine_cs *engine = req->engine;
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	u32 flip_mask;
+	int ret;
+
+	ret = intel_ring_begin(req, 6);
+	if (ret)
+		return ret;
+
+	/* Can't queue multiple flips, so wait for the previous
+	 * one to finish before executing the next.
+	 */
+	if (intel_crtc->plane)
+		flip_mask = MI_WAIT_FOR_PLANE_B_FLIP;
+	else
+		flip_mask = MI_WAIT_FOR_PLANE_A_FLIP;
+	intel_ring_emit(engine, MI_WAIT_FOR_EVENT | flip_mask);
+	intel_ring_emit(engine, MI_NOOP);
+	intel_ring_emit(engine, MI_DISPLAY_FLIP |
+			MI_DISPLAY_FLIP_PLANE(intel_crtc->plane));
+	intel_ring_emit(engine, fb->pitches[0]);
+	intel_ring_emit(engine, intel_crtc->unpin_work->gtt_offset);
+	intel_ring_emit(engine, 0); /* aux display base address, unused */
+
+	intel_mark_page_flip_active(intel_crtc->unpin_work);
+	return 0;
+}
+
+static int intel_gen3_queue_flip(struct drm_device *dev,
+				 struct drm_crtc *crtc,
+				 struct drm_framebuffer *fb,
+				 struct drm_i915_gem_object *obj,
+				 struct drm_i915_gem_request *req,
+				 uint32_t flags)
+{
+	struct intel_engine_cs *engine = req->engine;
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	u32 flip_mask;
+	int ret;
+
+	ret = intel_ring_begin(req, 6);
+	if (ret)
+		return ret;
+
+	if (intel_crtc->plane)
+		flip_mask = MI_WAIT_FOR_PLANE_B_FLIP;
+	else
+		flip_mask = MI_WAIT_FOR_PLANE_A_FLIP;
+	intel_ring_emit(engine, MI_WAIT_FOR_EVENT | flip_mask);
+	intel_ring_emit(engine, MI_NOOP);
+	intel_ring_emit(engine, MI_DISPLAY_FLIP_I915 |
+			MI_DISPLAY_FLIP_PLANE(intel_crtc->plane));
+	intel_ring_emit(engine, fb->pitches[0]);
+	intel_ring_emit(engine, intel_crtc->unpin_work->gtt_offset);
+	intel_ring_emit(engine, MI_NOOP);
+
+	intel_mark_page_flip_active(intel_crtc->unpin_work);
+	return 0;
+}
+
+static int intel_gen4_queue_flip(struct drm_device *dev,
+				 struct drm_crtc *crtc,
+				 struct drm_framebuffer *fb,
+				 struct drm_i915_gem_object *obj,
+				 struct drm_i915_gem_request *req,
+				 uint32_t flags)
+{
+	struct intel_engine_cs *engine = req->engine;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	uint32_t pf, pipesrc;
+	int ret;
+
+	ret = intel_ring_begin(req, 4);
+	if (ret)
+		return ret;
+
+	/* i965+ uses the linear or tiled offsets from the
+	 * Display Registers (which do not change across a page-flip)
+	 * so we need only reprogram the base address.
+	 */
+	intel_ring_emit(engine, MI_DISPLAY_FLIP |
+			MI_DISPLAY_FLIP_PLANE(intel_crtc->plane));
+	intel_ring_emit(engine, fb->pitches[0]);
+	intel_ring_emit(engine, intel_crtc->unpin_work->gtt_offset |
+			obj->tiling_mode);
+
+	/* XXX Enabling the panel-fitter across page-flip is so far
+	 * untested on non-native modes, so ignore it for now.
+	 * pf = I915_READ(pipe == 0 ? PFA_CTL_1 : PFB_CTL_1) & PF_ENABLE;
+	 */
+	pf = 0;
+	pipesrc = I915_READ(PIPESRC(intel_crtc->pipe)) & 0x0fff0fff;
+	intel_ring_emit(engine, pf | pipesrc);
+
+	intel_mark_page_flip_active(intel_crtc->unpin_work);
+	return 0;
+}
+
+static int intel_gen6_queue_flip(struct drm_device *dev,
+				 struct drm_crtc *crtc,
+				 struct drm_framebuffer *fb,
+				 struct drm_i915_gem_object *obj,
+				 struct drm_i915_gem_request *req,
+				 uint32_t flags)
+{
+	struct intel_engine_cs *engine = req->engine;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	uint32_t pf, pipesrc;
+	int ret;
+
+	ret = intel_ring_begin(req, 4);
+	if (ret)
+		return ret;
+
+	intel_ring_emit(engine, MI_DISPLAY_FLIP |
+			MI_DISPLAY_FLIP_PLANE(intel_crtc->plane));
+	intel_ring_emit(engine, fb->pitches[0] | obj->tiling_mode);
+	intel_ring_emit(engine, intel_crtc->unpin_work->gtt_offset);
+
+	/* Contrary to the suggestions in the documentation,
+	 * "Enable Panel Fitter" does not seem to be required when page
+	 * flipping with a non-native mode, and worse causes a normal
+	 * modeset to fail.
+	 * pf = I915_READ(PF_CTL(intel_crtc->pipe)) & PF_ENABLE;
+	 */
+	pf = 0;
+	pipesrc = I915_READ(PIPESRC(intel_crtc->pipe)) & 0x0fff0fff;
+	intel_ring_emit(engine, pf | pipesrc);
+
+	intel_mark_page_flip_active(intel_crtc->unpin_work);
+	return 0;
+}
+
+static int intel_gen7_queue_flip(struct drm_device *dev,
+				 struct drm_crtc *crtc,
+				 struct drm_framebuffer *fb,
+				 struct drm_i915_gem_object *obj,
+				 struct drm_i915_gem_request *req,
+				 uint32_t flags)
+{
+	struct intel_engine_cs *engine = req->engine;
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	uint32_t plane_bit = 0;
+	int len, ret;
+
+	switch (intel_crtc->plane) {
+	case PLANE_A:
+		plane_bit = MI_DISPLAY_FLIP_IVB_PLANE_A;
+		break;
+	case PLANE_B:
+		plane_bit = MI_DISPLAY_FLIP_IVB_PLANE_B;
+		break;
+	case PLANE_C:
+		plane_bit = MI_DISPLAY_FLIP_IVB_PLANE_C;
+		break;
+	default:
+		WARN_ONCE(1, "unknown plane in flip command\n");
+		return -ENODEV;
+	}
+
+	len = 4;
+	if (engine->id == RCS) {
+		len += 6;
+		/*
+		 * On Gen 8, SRM is now taking an extra dword to accommodate
+		 * 48bits addresses, and we need a NOOP for the batch size to
+		 * stay even.
+		 */
+		if (IS_GEN8(dev))
+			len += 2;
+	}
+
+	/*
+	 * BSpec MI_DISPLAY_FLIP for IVB:
+	 * "The full packet must be contained within the same cache line."
+	 *
+	 * Currently the LRI+SRM+MI_DISPLAY_FLIP all fit within the same
+	 * cacheline, if we ever start emitting more commands before
+	 * the MI_DISPLAY_FLIP we may need to first emit everything else,
+	 * then do the cacheline alignment, and finally emit the
+	 * MI_DISPLAY_FLIP.
+	 */
+	ret = intel_ring_cacheline_align(req);
+	if (ret)
+		return ret;
+
+	ret = intel_ring_begin(req, len);
+	if (ret)
+		return ret;
+
+	/* Unmask the flip-done completion message. Note that the bspec says that
+	 * we should do this for both the BCS and RCS, and that we must not unmask
+	 * more than one flip event at any time (or ensure that one flip message
+	 * can be sent by waiting for flip-done prior to queueing new flips).
+	 * Experimentation says that BCS works despite DERRMR masking all
+	 * flip-done completion events and that unmasking all planes at once
+	 * for the RCS also doesn't appear to drop events. Setting the DERRMR
+	 * to zero does lead to lockups within MI_DISPLAY_FLIP.
+	 */
+	if (engine->id == RCS) {
+		intel_ring_emit(engine, MI_LOAD_REGISTER_IMM(1));
+		intel_ring_emit_reg(engine, DERRMR);
+		intel_ring_emit(engine, ~(DERRMR_PIPEA_PRI_FLIP_DONE |
+					  DERRMR_PIPEB_PRI_FLIP_DONE |
+					  DERRMR_PIPEC_PRI_FLIP_DONE));
+		if (IS_GEN8(dev))
+			intel_ring_emit(engine, MI_STORE_REGISTER_MEM_GEN8 |
+					      MI_SRM_LRM_GLOBAL_GTT);
+		else
+			intel_ring_emit(engine, MI_STORE_REGISTER_MEM |
+					      MI_SRM_LRM_GLOBAL_GTT);
+		intel_ring_emit_reg(engine, DERRMR);
+		intel_ring_emit(engine, engine->scratch.gtt_offset + 256);
+		if (IS_GEN8(dev)) {
+			intel_ring_emit(engine, 0);
+			intel_ring_emit(engine, MI_NOOP);
+		}
+	}
+
+	intel_ring_emit(engine, MI_DISPLAY_FLIP_I915 | plane_bit);
+	intel_ring_emit(engine, (fb->pitches[0] | obj->tiling_mode));
+	intel_ring_emit(engine, intel_crtc->unpin_work->gtt_offset);
+	intel_ring_emit(engine, (MI_NOOP));
+
+	intel_mark_page_flip_active(intel_crtc->unpin_work);
+	return 0;
+}
+
+static bool use_mmio_flip(struct intel_engine_cs *engine,
+			  struct drm_i915_gem_object *obj)
+{
+	/*
+	 * This is not being used for older platforms, because
+	 * non-availability of flip done interrupt forces us to use
+	 * CS flips. Older platforms derive flip done using some clever
+	 * tricks involving the flip_pending status bits and vblank irqs.
+	 * So using MMIO flips there would disrupt this mechanism.
+	 */
+
+	if (engine == NULL)
+		return true;
+
+	if (INTEL_INFO(engine->dev)->gen < 5)
+		return false;
+
+	if (i915.use_mmio_flip < 0)
+		return false;
+	else if (i915.use_mmio_flip > 0)
+		return true;
+	else if (i915.enable_execlists)
+		return true;
+	else if (obj->base.dma_buf &&
+		 !reservation_object_test_signaled_rcu(obj->base.dma_buf->resv,
+						       false))
+		return true;
+	else
+		return engine != i915_gem_request_get_engine(obj->last_write_req);
+}
+
+static void skl_do_mmio_flip(struct intel_crtc *intel_crtc,
+			     unsigned int rotation,
+			     struct intel_unpin_work *work)
+{
+	struct drm_device *dev = intel_crtc->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct drm_framebuffer *fb = intel_crtc->base.primary->fb;
+	const enum pipe pipe = intel_crtc->pipe;
+	u32 ctl, stride, tile_height;
+
+	ctl = I915_READ(PLANE_CTL(pipe, 0));
+	ctl &= ~PLANE_CTL_TILED_MASK;
+	switch (fb->modifier[0]) {
+	case DRM_FORMAT_MOD_NONE:
+		break;
+	case I915_FORMAT_MOD_X_TILED:
+		ctl |= PLANE_CTL_TILED_X;
+		break;
+	case I915_FORMAT_MOD_Y_TILED:
+		ctl |= PLANE_CTL_TILED_Y;
+		break;
+	case I915_FORMAT_MOD_Yf_TILED:
+		ctl |= PLANE_CTL_TILED_YF;
+		break;
+	default:
+		MISSING_CASE(fb->modifier[0]);
+	}
+
+	/*
+	 * The stride is either expressed as a multiple of 64 bytes chunks for
+	 * linear buffers or in number of tiles for tiled buffers.
+	 */
+	if (intel_rotation_90_or_270(rotation)) {
+		/* stride = Surface height in tiles */
+		tile_height = intel_tile_height(dev_priv, fb->modifier[0], 0);
+		stride = DIV_ROUND_UP(fb->height, tile_height);
+	} else {
+		stride = fb->pitches[0] /
+			intel_fb_stride_alignment(dev_priv, fb->modifier[0],
+						  fb->pixel_format);
+	}
+
+	/*
+	 * Both PLANE_CTL and PLANE_STRIDE are not updated on vblank but on
+	 * PLANE_SURF updates, the update is then guaranteed to be atomic.
+	 */
+	I915_WRITE(PLANE_CTL(pipe, 0), ctl);
+	I915_WRITE(PLANE_STRIDE(pipe, 0), stride);
+
+	I915_WRITE(PLANE_SURF(pipe, 0), work->gtt_offset);
+	POSTING_READ(PLANE_SURF(pipe, 0));
+}
+
+static void ilk_do_mmio_flip(struct intel_crtc *intel_crtc,
+			     struct intel_unpin_work *work)
+{
+	struct drm_device *dev = intel_crtc->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_framebuffer *intel_fb =
+		to_intel_framebuffer(intel_crtc->base.primary->fb);
+	struct drm_i915_gem_object *obj = intel_fb->obj;
+	i915_reg_t reg = DSPCNTR(intel_crtc->plane);
+	u32 dspcntr;
+
+	dspcntr = I915_READ(reg);
+
+	if (obj->tiling_mode != I915_TILING_NONE)
+		dspcntr |= DISPPLANE_TILED;
+	else
+		dspcntr &= ~DISPPLANE_TILED;
+
+	I915_WRITE(reg, dspcntr);
+
+	I915_WRITE(DSPSURF(intel_crtc->plane), work->gtt_offset);
+	POSTING_READ(DSPSURF(intel_crtc->plane));
+}
+
+/*
+ * XXX: This is the temporary way to update the plane registers until we get
+ * around to using the usual plane update functions for MMIO flips
+ */
+static void intel_do_mmio_flip(struct intel_mmio_flip *mmio_flip)
+{
+	struct intel_crtc *crtc = mmio_flip->crtc;
+	struct intel_unpin_work *work;
+
+	spin_lock_irq(&crtc->base.dev->event_lock);
+	work = crtc->unpin_work;
+	spin_unlock_irq(&crtc->base.dev->event_lock);
+	if (work == NULL)
+		return;
+
+	intel_mark_page_flip_active(work);
+
+	intel_pipe_update_start(crtc);
+
+	if (INTEL_INFO(mmio_flip->i915)->gen >= 9)
+		skl_do_mmio_flip(crtc, mmio_flip->rotation, work);
+	else
+		/* use_mmio_flip() retricts MMIO flips to ilk+ */
+		ilk_do_mmio_flip(crtc, work);
+
+	intel_pipe_update_end(crtc);
+}
+
+static void intel_mmio_flip_work_func(struct work_struct *work)
+{
+	struct intel_mmio_flip *mmio_flip =
+		container_of(work, struct intel_mmio_flip, work);
+	struct intel_framebuffer *intel_fb =
+		to_intel_framebuffer(mmio_flip->crtc->base.primary->fb);
+	struct drm_i915_gem_object *obj = intel_fb->obj;
+
+	if (mmio_flip->req) {
+		WARN_ON(__i915_wait_request(mmio_flip->req,
+					    false, NULL,
+					    &mmio_flip->i915->rps.mmioflips));
+		i915_gem_request_unreference__unlocked(mmio_flip->req);
+	}
+
+	/* For framebuffer backed by dmabuf, wait for fence */
+	if (obj->base.dma_buf)
+		WARN_ON(reservation_object_wait_timeout_rcu(obj->base.dma_buf->resv,
+							    false, false,
+							    MAX_SCHEDULE_TIMEOUT) < 0);
+
+	intel_do_mmio_flip(mmio_flip);
+	kfree(mmio_flip);
+}
+
+static int intel_queue_mmio_flip(struct drm_device *dev,
+				 struct drm_crtc *crtc,
+				 struct drm_i915_gem_object *obj)
+{
+	struct intel_mmio_flip *mmio_flip;
+
+	mmio_flip = kmalloc(sizeof(*mmio_flip), GFP_KERNEL);
+	if (mmio_flip == NULL)
+		return -ENOMEM;
+
+	mmio_flip->i915 = to_i915(dev);
+	mmio_flip->req = i915_gem_request_reference(obj->last_write_req);
+	mmio_flip->crtc = to_intel_crtc(crtc);
+	mmio_flip->rotation = crtc->primary->state->rotation;
+
+	INIT_WORK(&mmio_flip->work, intel_mmio_flip_work_func);
+	schedule_work(&mmio_flip->work);
+
+	return 0;
+}
+
+static int intel_default_queue_flip(struct drm_device *dev,
+				    struct drm_crtc *crtc,
+				    struct drm_framebuffer *fb,
+				    struct drm_i915_gem_object *obj,
+				    struct drm_i915_gem_request *req,
+				    uint32_t flags)
+{
+	return -ENODEV;
+}
+
+static bool __intel_pageflip_stall_check(struct drm_device *dev,
+					 struct drm_crtc *crtc)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	struct intel_unpin_work *work = intel_crtc->unpin_work;
+	u32 addr;
+
+	if (atomic_read(&work->pending) >= INTEL_FLIP_COMPLETE)
+		return true;
+
+	if (atomic_read(&work->pending) < INTEL_FLIP_PENDING)
+		return false;
+
+	if (!work->enable_stall_check)
+		return false;
+
+	if (work->flip_ready_vblank == 0) {
+		if (work->flip_queued_req &&
+		    !i915_gem_request_completed(work->flip_queued_req, true))
+			return false;
+
+		work->flip_ready_vblank = drm_crtc_vblank_count(crtc);
+	}
+
+	if (drm_crtc_vblank_count(crtc) - work->flip_ready_vblank < 3)
+		return false;
+
+	/* Potential stall - if we see that the flip has happened,
+	 * assume a missed interrupt. */
+	if (INTEL_INFO(dev)->gen >= 4)
+		addr = I915_HI_DISPBASE(I915_READ(DSPSURF(intel_crtc->plane)));
+	else
+		addr = I915_READ(DSPADDR(intel_crtc->plane));
+
+	/* There is a potential issue here with a false positive after a flip
+	 * to the same address. We could address this by checking for a
+	 * non-incrementing frame counter.
+	 */
+	return addr == work->gtt_offset;
+}
+
+void intel_check_page_flip(struct drm_device *dev, int pipe)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe];
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	struct intel_unpin_work *work;
+
+	WARN_ON(!in_interrupt());
+
+	if (crtc == NULL)
+		return;
+
+	spin_lock(&dev->event_lock);
+	work = intel_crtc->unpin_work;
+	if (work != NULL && __intel_pageflip_stall_check(dev, crtc)) {
+		WARN_ONCE(1, "Kicking stuck page flip: queued at %d, now %d\n",
+			 work->flip_queued_vblank, drm_vblank_count(dev, pipe));
+		page_flip_completed(intel_crtc);
+		work = NULL;
+	}
+	if (work != NULL &&
+	    drm_vblank_count(dev, pipe) - work->flip_queued_vblank > 1)
+		intel_queue_rps_boost_for_request(dev, work->flip_queued_req);
+	spin_unlock(&dev->event_lock);
+}
+
+static int intel_crtc_page_flip(struct drm_crtc *crtc,
+				struct drm_framebuffer *fb,
+				struct drm_pending_vblank_event *event,
+				uint32_t page_flip_flags)
+{
+	struct drm_device *dev = crtc->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct drm_framebuffer *old_fb = crtc->primary->fb;
+	struct drm_i915_gem_object *obj = intel_fb_obj(fb);
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	struct drm_plane *primary = crtc->primary;
+	enum pipe pipe = intel_crtc->pipe;
+	struct intel_unpin_work *work;
+	struct intel_engine_cs *engine;
+	bool mmio_flip;
+	struct drm_i915_gem_request *request = NULL;
+	int ret;
+
+	/*
+	 * drm_mode_page_flip_ioctl() should already catch this, but double
+	 * check to be safe.  In the future we may enable pageflipping from
+	 * a disabled primary plane.
+	 */
+	if (WARN_ON(intel_fb_obj(old_fb) == NULL))
+		return -EBUSY;
+
+	/* Can't change pixel format via MI display flips. */
+	if (fb->pixel_format != crtc->primary->fb->pixel_format)
+		return -EINVAL;
+
+	/*
+	 * TILEOFF/LINOFF registers can't be changed via MI display flips.
+	 * Note that pitch changes could also affect these register.
+	 */
+	if (INTEL_INFO(dev)->gen > 3 &&
+	    (fb->offsets[0] != crtc->primary->fb->offsets[0] ||
+	     fb->pitches[0] != crtc->primary->fb->pitches[0]))
+		return -EINVAL;
+
+	if (i915_terminally_wedged(&dev_priv->gpu_error))
+		goto out_hang;
+
+	work = kzalloc(sizeof(*work), GFP_KERNEL);
+	if (work == NULL)
+		return -ENOMEM;
+
+	work->event = event;
+	work->crtc = crtc;
+	work->old_fb = old_fb;
+	INIT_WORK(&work->work, intel_unpin_work_fn);
+
+	ret = drm_crtc_vblank_get(crtc);
+	if (ret)
+		goto free_work;
+
+	/* We borrow the event spin lock for protecting unpin_work */
+	spin_lock_irq(&dev->event_lock);
+	if (intel_crtc->unpin_work) {
+		/* Before declaring the flip queue wedged, check if
+		 * the hardware completed the operation behind our backs.
+		 */
+		if (__intel_pageflip_stall_check(dev, crtc)) {
+			DRM_DEBUG_DRIVER("flip queue: previous flip completed, continuing\n");
+			page_flip_completed(intel_crtc);
+		} else {
+			DRM_DEBUG_DRIVER("flip queue: crtc already busy\n");
+			spin_unlock_irq(&dev->event_lock);
+
+			drm_crtc_vblank_put(crtc);
+			kfree(work);
+			return -EBUSY;
+		}
+	}
+	intel_crtc->unpin_work = work;
+	spin_unlock_irq(&dev->event_lock);
+
+	if (atomic_read(&intel_crtc->unpin_work_count) >= 2)
+		flush_workqueue(dev_priv->wq);
+
+	/* Reference the objects for the scheduled work. */
+	drm_framebuffer_reference(work->old_fb);
+	drm_gem_object_reference(&obj->base);
+
+	crtc->primary->fb = fb;
+	update_state_fb(crtc->primary);
+	intel_fbc_pre_update(intel_crtc);
+
+	work->pending_flip_obj = obj;
+
+	ret = i915_mutex_lock_interruptible(dev);
+	if (ret)
+		goto cleanup;
+
+	intel_crtc->reset_counter = i915_reset_counter(&dev_priv->gpu_error);
+	if (__i915_reset_in_progress_or_wedged(intel_crtc->reset_counter)) {
+		ret = -EIO;
+		goto cleanup;
+	}
+
+	atomic_inc(&intel_crtc->unpin_work_count);
+
+	if (INTEL_INFO(dev)->gen >= 5 || IS_G4X(dev))
+		work->flip_count = I915_READ(PIPE_FLIPCOUNT_G4X(pipe)) + 1;
+
+	if (IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev)) {
+		engine = &dev_priv->engine[BCS];
+		if (obj->tiling_mode != intel_fb_obj(work->old_fb)->tiling_mode)
+			/* vlv: DISPLAY_FLIP fails to change tiling */
+			engine = NULL;
+	} else if (IS_IVYBRIDGE(dev) || IS_HASWELL(dev)) {
+		engine = &dev_priv->engine[BCS];
+	} else if (INTEL_INFO(dev)->gen >= 7) {
+		engine = i915_gem_request_get_engine(obj->last_write_req);
+		if (engine == NULL || engine->id != RCS)
+			engine = &dev_priv->engine[BCS];
+	} else {
+		engine = &dev_priv->engine[RCS];
+	}
+
+	mmio_flip = use_mmio_flip(engine, obj);
+
+	/* When using CS flips, we want to emit semaphores between rings.
+	 * However, when using mmio flips we will create a task to do the
+	 * synchronisation, so all we want here is to pin the framebuffer
+	 * into the display plane and skip any waits.
+	 */
+	if (!mmio_flip) {
+		ret = i915_gem_object_sync(obj, engine, &request);
+		if (ret)
+			goto cleanup_pending;
+	}
+
+	ret = intel_pin_and_fence_fb_obj(fb, primary->state->rotation);
+	if (ret)
+		goto cleanup_pending;
+
+	work->gtt_offset = intel_plane_obj_offset(to_intel_plane(primary),
+						  obj, 0);
+	work->gtt_offset += intel_crtc->dspaddr_offset;
+
+	if (mmio_flip) {
+		ret = intel_queue_mmio_flip(dev, crtc, obj);
+		if (ret)
+			goto cleanup_unpin;
+
+		i915_gem_request_assign(&work->flip_queued_req,
+					obj->last_write_req);
+	} else {
+		if (!request) {
+			request = i915_gem_request_alloc(engine, NULL);
+			if (IS_ERR(request)) {
+				ret = PTR_ERR(request);
+				goto cleanup_unpin;
+			}
+		}
+
+		ret = dev_priv->display.queue_flip(dev, crtc, fb, obj, request,
+						   page_flip_flags);
+		if (ret)
+			goto cleanup_unpin;
+
+		i915_gem_request_assign(&work->flip_queued_req, request);
+	}
+
+	if (request)
+		i915_add_request_no_flush(request);
+
+	work->flip_queued_vblank = drm_crtc_vblank_count(crtc);
+	work->enable_stall_check = true;
+
+	i915_gem_track_fb(intel_fb_obj(work->old_fb), obj,
+			  to_intel_plane(primary)->frontbuffer_bit);
+	mutex_unlock(&dev->struct_mutex);
+
+	intel_frontbuffer_flip_prepare(dev,
+				       to_intel_plane(primary)->frontbuffer_bit);
+
+	trace_i915_flip_request(intel_crtc->plane, obj);
+
+	return 0;
+
+cleanup_unpin:
+	intel_unpin_fb_obj(fb, crtc->primary->state->rotation);
+cleanup_pending:
+	if (!IS_ERR_OR_NULL(request))
+		i915_add_request_no_flush(request);
+	atomic_dec(&intel_crtc->unpin_work_count);
+	mutex_unlock(&dev->struct_mutex);
+cleanup:
+	crtc->primary->fb = old_fb;
+	update_state_fb(crtc->primary);
+
+	drm_gem_object_unreference_unlocked(&obj->base);
+	drm_framebuffer_unreference(work->old_fb);
+
+	spin_lock_irq(&dev->event_lock);
+	intel_crtc->unpin_work = NULL;
+	spin_unlock_irq(&dev->event_lock);
+
+	drm_crtc_vblank_put(crtc);
+free_work:
+	kfree(work);
+
+	if (ret == -EIO) {
+		struct drm_atomic_state *state;
+		struct drm_plane_state *plane_state;
+
+out_hang:
+		state = drm_atomic_state_alloc(dev);
+		if (!state)
+			return -ENOMEM;
+		state->acquire_ctx = drm_modeset_legacy_acquire_ctx(crtc);
+
+retry:
+		plane_state = drm_atomic_get_plane_state(state, primary);
+		ret = PTR_ERR_OR_ZERO(plane_state);
+		if (!ret) {
+			drm_atomic_set_fb_for_plane(plane_state, fb);
+
+			ret = drm_atomic_set_crtc_for_plane(plane_state, crtc);
+			if (!ret)
+				ret = drm_atomic_commit(state);
+		}
+
+		if (ret == -EDEADLK) {
+			drm_modeset_backoff(state->acquire_ctx);
+			drm_atomic_state_clear(state);
+			goto retry;
+		}
+
+		if (ret)
+			drm_atomic_state_free(state);
+
+		if (ret == 0 && event) {
+			spin_lock_irq(&dev->event_lock);
+			drm_crtc_send_vblank_event(crtc, event);
+			spin_unlock_irq(&dev->event_lock);
+		}
+	}
+	return ret;
+}
+
+
+/**
+ * intel_wm_need_update - Check whether watermarks need updating
+ * @plane: drm plane
+ * @state: new plane state
+ *
+ * Check current plane state versus the new one to determine whether
+ * watermarks need to be recalculated.
+ *
+ * Returns true or false.
+ */
+static bool intel_wm_need_update(struct drm_plane *plane,
+				 struct drm_plane_state *state)
+{
+	struct intel_plane_state *new = to_intel_plane_state(state);
+	struct intel_plane_state *cur = to_intel_plane_state(plane->state);
+
+	/* Update watermarks on tiling or size changes. */
+	if (new->visible != cur->visible)
+		return true;
+
+	if (!cur->base.fb || !new->base.fb)
+		return false;
+
+	if (cur->base.fb->modifier[0] != new->base.fb->modifier[0] ||
+	    cur->base.rotation != new->base.rotation ||
+	    drm_rect_width(&new->src) != drm_rect_width(&cur->src) ||
+	    drm_rect_height(&new->src) != drm_rect_height(&cur->src) ||
+	    drm_rect_width(&new->dst) != drm_rect_width(&cur->dst) ||
+	    drm_rect_height(&new->dst) != drm_rect_height(&cur->dst))
+		return true;
+
+	return false;
+}
+
+static bool needs_scaling(struct intel_plane_state *state)
+{
+	int src_w = drm_rect_width(&state->src) >> 16;
+	int src_h = drm_rect_height(&state->src) >> 16;
+	int dst_w = drm_rect_width(&state->dst);
+	int dst_h = drm_rect_height(&state->dst);
+
+	return (src_w != dst_w || src_h != dst_h);
+}
+
+int intel_plane_atomic_calc_changes(struct drm_crtc_state *crtc_state,
+				    struct drm_plane_state *plane_state)
+{
+	struct intel_crtc_state *pipe_config = to_intel_crtc_state(crtc_state);
+	struct drm_crtc *crtc = crtc_state->crtc;
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	struct drm_plane *plane = plane_state->plane;
+	struct drm_device *dev = crtc->dev;
+	struct drm_i915_private *dev_priv = to_i915(dev);
+	struct intel_plane_state *old_plane_state =
+		to_intel_plane_state(plane->state);
+	int idx = intel_crtc->base.base.id, ret;
+	bool mode_changed = needs_modeset(crtc_state);
+	bool was_crtc_enabled = crtc->state->active;
+	bool is_crtc_enabled = crtc_state->active;
+	bool turn_off, turn_on, visible, was_visible;
+	struct drm_framebuffer *fb = plane_state->fb;
+
+	if (crtc_state && INTEL_INFO(dev)->gen >= 9 &&
+	    plane->type != DRM_PLANE_TYPE_CURSOR) {
+		ret = skl_update_scaler_plane(
+			to_intel_crtc_state(crtc_state),
+			to_intel_plane_state(plane_state));
+		if (ret)
+			return ret;
+	}
+
+	was_visible = old_plane_state->visible;
+	visible = to_intel_plane_state(plane_state)->visible;
+
+	if (!was_crtc_enabled && WARN_ON(was_visible))
+		was_visible = false;
+
+	/*
+	 * Visibility is calculated as if the crtc was on, but
+	 * after scaler setup everything depends on it being off
+	 * when the crtc isn't active.
+	 */
+	if (!is_crtc_enabled)
+		to_intel_plane_state(plane_state)->visible = visible = false;
+
+	if (!was_visible && !visible)
+		return 0;
+
+	if (fb != old_plane_state->base.fb)
+		pipe_config->fb_changed = true;
+
+	turn_off = was_visible && (!visible || mode_changed);
+	turn_on = visible && (!was_visible || mode_changed);
+
+	DRM_DEBUG_ATOMIC("[CRTC:%i] has [PLANE:%i] with fb %i\n", idx,
+			 plane->base.id, fb ? fb->base.id : -1);
+
+	DRM_DEBUG_ATOMIC("[PLANE:%i] visible %i -> %i, off %i, on %i, ms %i\n",
+			 plane->base.id, was_visible, visible,
+			 turn_off, turn_on, mode_changed);
+
+	if (turn_on) {
+		pipe_config->update_wm_pre = true;
+
+		/* must disable cxsr around plane enable/disable */
+		if (plane->type != DRM_PLANE_TYPE_CURSOR)
+			pipe_config->disable_cxsr = true;
+	} else if (turn_off) {
+		pipe_config->update_wm_post = true;
+
+		/* must disable cxsr around plane enable/disable */
+		if (plane->type != DRM_PLANE_TYPE_CURSOR)
+			pipe_config->disable_cxsr = true;
+	} else if (intel_wm_need_update(plane, plane_state)) {
+		/* FIXME bollocks */
+		pipe_config->update_wm_pre = true;
+		pipe_config->update_wm_post = true;
+	}
+
+	/* Pre-gen9 platforms need two-step watermark updates */
+	if ((pipe_config->update_wm_pre || pipe_config->update_wm_post) &&
+	    INTEL_INFO(dev)->gen < 9 && dev_priv->display.optimize_watermarks)
+		to_intel_crtc_state(crtc_state)->wm.need_postvbl_update = true;
+
+	if (visible || was_visible)
+		pipe_config->fb_bits |= to_intel_plane(plane)->frontbuffer_bit;
+
+	/*
+	 * WaCxSRDisabledForSpriteScaling:ivb
+	 *
+	 * cstate->update_wm was already set above, so this flag will
+	 * take effect when we commit and program watermarks.
+	 */
+	if (plane->type == DRM_PLANE_TYPE_OVERLAY && IS_IVYBRIDGE(dev) &&
+	    needs_scaling(to_intel_plane_state(plane_state)) &&
+	    !needs_scaling(old_plane_state))
+		pipe_config->disable_lp_wm = true;
+
+	return 0;
+}
+
+static bool encoders_cloneable(const struct intel_encoder *a,
+			       const struct intel_encoder *b)
+{
+	/* masks could be asymmetric, so check both ways */
+	return a == b || (a->cloneable & (1 << b->type) &&
+			  b->cloneable & (1 << a->type));
+}
+
+static bool check_single_encoder_cloning(struct drm_atomic_state *state,
+					 struct intel_crtc *crtc,
+					 struct intel_encoder *encoder)
+{
+	struct intel_encoder *source_encoder;
+	struct drm_connector *connector;
+	struct drm_connector_state *connector_state;
+	int i;
+
+	for_each_connector_in_state(state, connector, connector_state, i) {
+		if (connector_state->crtc != &crtc->base)
+			continue;
+
+		source_encoder =
+			to_intel_encoder(connector_state->best_encoder);
+		if (!encoders_cloneable(encoder, source_encoder))
+			return false;
+	}
+
+	return true;
+}
+
+static bool check_encoder_cloning(struct drm_atomic_state *state,
+				  struct intel_crtc *crtc)
+{
+	struct intel_encoder *encoder;
+	struct drm_connector *connector;
+	struct drm_connector_state *connector_state;
+	int i;
+
+	for_each_connector_in_state(state, connector, connector_state, i) {
+		if (connector_state->crtc != &crtc->base)
+			continue;
+
+		encoder = to_intel_encoder(connector_state->best_encoder);
+		if (!check_single_encoder_cloning(state, crtc, encoder))
+			return false;
+	}
+
+	return true;
+}
+
+static int intel_crtc_atomic_check(struct drm_crtc *crtc,
+				   struct drm_crtc_state *crtc_state)
+{
+	struct drm_device *dev = crtc->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	struct intel_crtc_state *pipe_config =
+		to_intel_crtc_state(crtc_state);
+	struct drm_atomic_state *state = crtc_state->state;
+	int ret;
+	bool mode_changed = needs_modeset(crtc_state);
+
+	if (mode_changed && !check_encoder_cloning(state, intel_crtc)) {
+		DRM_DEBUG_KMS("rejecting invalid cloning configuration\n");
+		return -EINVAL;
+	}
+
+	if (mode_changed && !crtc_state->active)
+		pipe_config->update_wm_post = true;
+
+	if (mode_changed && crtc_state->enable &&
+	    dev_priv->display.crtc_compute_clock &&
+	    !WARN_ON(pipe_config->shared_dpll)) {
+		ret = dev_priv->display.crtc_compute_clock(intel_crtc,
+							   pipe_config);
+		if (ret)
+			return ret;
+	}
+
+	if (crtc_state->color_mgmt_changed) {
+		ret = intel_color_check(crtc, crtc_state);
+		if (ret)
+			return ret;
+
+		/*
+		 * Changing color management on Intel hardware is
+		 * handled as part of planes update.
+		 */
+		crtc_state->planes_changed = true;
+	}
+
+	ret = 0;
+	if (dev_priv->display.compute_pipe_wm) {
+		ret = dev_priv->display.compute_pipe_wm(pipe_config);
+		if (ret) {
+			DRM_DEBUG_KMS("Target pipe watermarks are invalid\n");
+			return ret;
+		}
+	}
+
+	if (dev_priv->display.compute_intermediate_wm &&
+	    !to_intel_atomic_state(state)->skip_intermediate_wm) {
+		if (WARN_ON(!dev_priv->display.compute_pipe_wm))
+			return 0;
+
+		/*
+		 * Calculate 'intermediate' watermarks that satisfy both the
+		 * old state and the new state.  We can program these
+		 * immediately.
+		 */
+		ret = dev_priv->display.compute_intermediate_wm(crtc->dev,
+								intel_crtc,
+								pipe_config);
+		if (ret) {
+			DRM_DEBUG_KMS("No valid intermediate pipe watermarks are possible\n");
+			return ret;
+		}
+	} else if (dev_priv->display.compute_intermediate_wm) {
+		if (HAS_PCH_SPLIT(dev_priv) && INTEL_GEN(dev_priv) < 9)
+			pipe_config->wm.intermediate = pipe_config->wm.optimal.ilk;
+	}
+
+	if (INTEL_INFO(dev)->gen >= 9) {
+		if (mode_changed)
+			ret = skl_update_scaler_crtc(pipe_config);
+
+		if (!ret)
+			ret = intel_atomic_setup_scalers(dev, intel_crtc,
+							 pipe_config);
+	}
+
+	return ret;
+}
+
+static const struct drm_crtc_helper_funcs intel_helper_funcs = {
+	.mode_set_base_atomic = intel_pipe_set_base_atomic,
+	.atomic_begin = intel_begin_crtc_commit,
+	.atomic_flush = intel_finish_crtc_commit,
+	.atomic_check = intel_crtc_atomic_check,
+};
+
+static void intel_modeset_update_connector_atomic_state(struct drm_device *dev)
+{
+	struct intel_connector *connector;
+
+	for_each_intel_connector(dev, connector) {
+		if (connector->base.encoder) {
+			connector->base.state->best_encoder =
+				connector->base.encoder;
+			connector->base.state->crtc =
+				connector->base.encoder->crtc;
+		} else {
+			connector->base.state->best_encoder = NULL;
+			connector->base.state->crtc = NULL;
+		}
+	}
+}
+
+static void
+connected_sink_compute_bpp(struct intel_connector *connector,
+			   struct intel_crtc_state *pipe_config)
+{
+	int bpp = pipe_config->pipe_bpp;
+
+	DRM_DEBUG_KMS("[CONNECTOR:%d:%s] checking for sink bpp constrains\n",
+		connector->base.base.id,
+		connector->base.name);
+
+	/* Don't use an invalid EDID bpc value */
+	if (connector->base.display_info.bpc &&
+	    connector->base.display_info.bpc * 3 < bpp) {
+		DRM_DEBUG_KMS("clamping display bpp (was %d) to EDID reported max of %d\n",
+			      bpp, connector->base.display_info.bpc*3);
+		pipe_config->pipe_bpp = connector->base.display_info.bpc*3;
+	}
+
+	/* Clamp bpp to default limit on screens without EDID 1.4 */
+	if (connector->base.display_info.bpc == 0) {
+		int type = connector->base.connector_type;
+		int clamp_bpp = 24;
+
+		/* Fall back to 18 bpp when DP sink capability is unknown. */
+		if (type == DRM_MODE_CONNECTOR_DisplayPort ||
+		    type == DRM_MODE_CONNECTOR_eDP)
+			clamp_bpp = 18;
+
+		if (bpp > clamp_bpp) {
+			DRM_DEBUG_KMS("clamping display bpp (was %d) to default limit of %d\n",
+				      bpp, clamp_bpp);
+			pipe_config->pipe_bpp = clamp_bpp;
+		}
+	}
+}
+
+static int
+compute_baseline_pipe_bpp(struct intel_crtc *crtc,
+			  struct intel_crtc_state *pipe_config)
+{
+	struct drm_device *dev = crtc->base.dev;
+	struct drm_atomic_state *state;
+	struct drm_connector *connector;
+	struct drm_connector_state *connector_state;
+	int bpp, i;
+
+	if ((IS_G4X(dev) || IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev)))
+		bpp = 10*3;
+	else if (INTEL_INFO(dev)->gen >= 5)
+		bpp = 12*3;
+	else
+		bpp = 8*3;
+
+
+	pipe_config->pipe_bpp = bpp;
+
+	state = pipe_config->base.state;
+
+	/* Clamp display bpp to EDID value */
+	for_each_connector_in_state(state, connector, connector_state, i) {
+		if (connector_state->crtc != &crtc->base)
+			continue;
+
+		connected_sink_compute_bpp(to_intel_connector(connector),
+					   pipe_config);
+	}
+
+	return bpp;
+}
+
+static void intel_dump_crtc_timings(const struct drm_display_mode *mode)
+{
+	DRM_DEBUG_KMS("crtc timings: %d %d %d %d %d %d %d %d %d, "
+			"type: 0x%x flags: 0x%x\n",
+		mode->crtc_clock,
+		mode->crtc_hdisplay, mode->crtc_hsync_start,
+		mode->crtc_hsync_end, mode->crtc_htotal,
+		mode->crtc_vdisplay, mode->crtc_vsync_start,
+		mode->crtc_vsync_end, mode->crtc_vtotal, mode->type, mode->flags);
+}
+
+static void intel_dump_pipe_config(struct intel_crtc *crtc,
+				   struct intel_crtc_state *pipe_config,
+				   const char *context)
+{
+	struct drm_device *dev = crtc->base.dev;
+	struct drm_plane *plane;
+	struct intel_plane *intel_plane;
+	struct intel_plane_state *state;
+	struct drm_framebuffer *fb;
+
+	DRM_DEBUG_KMS("[CRTC:%d]%s config %p for pipe %c\n", crtc->base.base.id,
+		      context, pipe_config, pipe_name(crtc->pipe));
+
+	DRM_DEBUG_KMS("cpu_transcoder: %s\n", transcoder_name(pipe_config->cpu_transcoder));
+	DRM_DEBUG_KMS("pipe bpp: %i, dithering: %i\n",
+		      pipe_config->pipe_bpp, pipe_config->dither);
+	DRM_DEBUG_KMS("fdi/pch: %i, lanes: %i, gmch_m: %u, gmch_n: %u, link_m: %u, link_n: %u, tu: %u\n",
+		      pipe_config->has_pch_encoder,
+		      pipe_config->fdi_lanes,
+		      pipe_config->fdi_m_n.gmch_m, pipe_config->fdi_m_n.gmch_n,
+		      pipe_config->fdi_m_n.link_m, pipe_config->fdi_m_n.link_n,
+		      pipe_config->fdi_m_n.tu);
+	DRM_DEBUG_KMS("dp: %i, lanes: %i, gmch_m: %u, gmch_n: %u, link_m: %u, link_n: %u, tu: %u\n",
+		      pipe_config->has_dp_encoder,
+		      pipe_config->lane_count,
+		      pipe_config->dp_m_n.gmch_m, pipe_config->dp_m_n.gmch_n,
+		      pipe_config->dp_m_n.link_m, pipe_config->dp_m_n.link_n,
+		      pipe_config->dp_m_n.tu);
+
+	DRM_DEBUG_KMS("dp: %i, lanes: %i, gmch_m2: %u, gmch_n2: %u, link_m2: %u, link_n2: %u, tu2: %u\n",
+		      pipe_config->has_dp_encoder,
+		      pipe_config->lane_count,
+		      pipe_config->dp_m2_n2.gmch_m,
+		      pipe_config->dp_m2_n2.gmch_n,
+		      pipe_config->dp_m2_n2.link_m,
+		      pipe_config->dp_m2_n2.link_n,
+		      pipe_config->dp_m2_n2.tu);
+
+	DRM_DEBUG_KMS("audio: %i, infoframes: %i\n",
+		      pipe_config->has_audio,
+		      pipe_config->has_infoframe);
+
+	DRM_DEBUG_KMS("requested mode:\n");
+	drm_mode_debug_printmodeline(&pipe_config->base.mode);
+	DRM_DEBUG_KMS("adjusted mode:\n");
+	drm_mode_debug_printmodeline(&pipe_config->base.adjusted_mode);
+	intel_dump_crtc_timings(&pipe_config->base.adjusted_mode);
+	DRM_DEBUG_KMS("port clock: %d\n", pipe_config->port_clock);
+	DRM_DEBUG_KMS("pipe src size: %dx%d\n",
+		      pipe_config->pipe_src_w, pipe_config->pipe_src_h);
+	DRM_DEBUG_KMS("num_scalers: %d, scaler_users: 0x%x, scaler_id: %d\n",
+		      crtc->num_scalers,
+		      pipe_config->scaler_state.scaler_users,
+		      pipe_config->scaler_state.scaler_id);
+	DRM_DEBUG_KMS("gmch pfit: control: 0x%08x, ratios: 0x%08x, lvds border: 0x%08x\n",
+		      pipe_config->gmch_pfit.control,
+		      pipe_config->gmch_pfit.pgm_ratios,
+		      pipe_config->gmch_pfit.lvds_border_bits);
+	DRM_DEBUG_KMS("pch pfit: pos: 0x%08x, size: 0x%08x, %s\n",
+		      pipe_config->pch_pfit.pos,
+		      pipe_config->pch_pfit.size,
+		      pipe_config->pch_pfit.enabled ? "enabled" : "disabled");
+	DRM_DEBUG_KMS("ips: %i\n", pipe_config->ips_enabled);
+	DRM_DEBUG_KMS("double wide: %i\n", pipe_config->double_wide);
+
+	if (IS_BROXTON(dev)) {
+		DRM_DEBUG_KMS("ddi_pll_sel: %u; dpll_hw_state: ebb0: 0x%x, ebb4: 0x%x,"
+			      "pll0: 0x%x, pll1: 0x%x, pll2: 0x%x, pll3: 0x%x, "
+			      "pll6: 0x%x, pll8: 0x%x, pll9: 0x%x, pll10: 0x%x, pcsdw12: 0x%x\n",
+			      pipe_config->ddi_pll_sel,
+			      pipe_config->dpll_hw_state.ebb0,
+			      pipe_config->dpll_hw_state.ebb4,
+			      pipe_config->dpll_hw_state.pll0,
+			      pipe_config->dpll_hw_state.pll1,
+			      pipe_config->dpll_hw_state.pll2,
+			      pipe_config->dpll_hw_state.pll3,
+			      pipe_config->dpll_hw_state.pll6,
+			      pipe_config->dpll_hw_state.pll8,
+			      pipe_config->dpll_hw_state.pll9,
+			      pipe_config->dpll_hw_state.pll10,
+			      pipe_config->dpll_hw_state.pcsdw12);
+	} else if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev)) {
+		DRM_DEBUG_KMS("ddi_pll_sel: %u; dpll_hw_state: "
+			      "ctrl1: 0x%x, cfgcr1: 0x%x, cfgcr2: 0x%x\n",
+			      pipe_config->ddi_pll_sel,
+			      pipe_config->dpll_hw_state.ctrl1,
+			      pipe_config->dpll_hw_state.cfgcr1,
+			      pipe_config->dpll_hw_state.cfgcr2);
+	} else if (HAS_DDI(dev)) {
+		DRM_DEBUG_KMS("ddi_pll_sel: 0x%x; dpll_hw_state: wrpll: 0x%x spll: 0x%x\n",
+			      pipe_config->ddi_pll_sel,
+			      pipe_config->dpll_hw_state.wrpll,
+			      pipe_config->dpll_hw_state.spll);
+	} else {
+		DRM_DEBUG_KMS("dpll_hw_state: dpll: 0x%x, dpll_md: 0x%x, "
+			      "fp0: 0x%x, fp1: 0x%x\n",
+			      pipe_config->dpll_hw_state.dpll,
+			      pipe_config->dpll_hw_state.dpll_md,
+			      pipe_config->dpll_hw_state.fp0,
+			      pipe_config->dpll_hw_state.fp1);
+	}
+
+	DRM_DEBUG_KMS("planes on this crtc\n");
+	list_for_each_entry(plane, &dev->mode_config.plane_list, head) {
+		intel_plane = to_intel_plane(plane);
+		if (intel_plane->pipe != crtc->pipe)
+			continue;
+
+		state = to_intel_plane_state(plane->state);
+		fb = state->base.fb;
+		if (!fb) {
+			DRM_DEBUG_KMS("%s PLANE:%d plane: %u.%u idx: %d "
+				"disabled, scaler_id = %d\n",
+				plane->type == DRM_PLANE_TYPE_CURSOR ? "CURSOR" : "STANDARD",
+				plane->base.id, intel_plane->pipe,
+				(crtc->base.primary == plane) ? 0 : intel_plane->plane + 1,
+				drm_plane_index(plane), state->scaler_id);
+			continue;
+		}
+
+		DRM_DEBUG_KMS("%s PLANE:%d plane: %u.%u idx: %d enabled",
+			plane->type == DRM_PLANE_TYPE_CURSOR ? "CURSOR" : "STANDARD",
+			plane->base.id, intel_plane->pipe,
+			crtc->base.primary == plane ? 0 : intel_plane->plane + 1,
+			drm_plane_index(plane));
+		DRM_DEBUG_KMS("\tFB:%d, fb = %ux%u format = 0x%x",
+			fb->base.id, fb->width, fb->height, fb->pixel_format);
+		DRM_DEBUG_KMS("\tscaler:%d src (%u, %u) %ux%u dst (%u, %u) %ux%u\n",
+			state->scaler_id,
+			state->src.x1 >> 16, state->src.y1 >> 16,
+			drm_rect_width(&state->src) >> 16,
+			drm_rect_height(&state->src) >> 16,
+			state->dst.x1, state->dst.y1,
+			drm_rect_width(&state->dst), drm_rect_height(&state->dst));
+	}
+}
+
+static bool check_digital_port_conflicts(struct drm_atomic_state *state)
+{
+	struct drm_device *dev = state->dev;
+	struct drm_connector *connector;
+	unsigned int used_ports = 0;
+
+	/*
+	 * Walk the connector list instead of the encoder
+	 * list to detect the problem on ddi platforms
+	 * where there's just one encoder per digital port.
+	 */
+	drm_for_each_connector(connector, dev) {
+		struct drm_connector_state *connector_state;
+		struct intel_encoder *encoder;
+
+		connector_state = drm_atomic_get_existing_connector_state(state, connector);
+		if (!connector_state)
+			connector_state = connector->state;
+
+		if (!connector_state->best_encoder)
+			continue;
+
+		encoder = to_intel_encoder(connector_state->best_encoder);
+
+		WARN_ON(!connector_state->crtc);
+
+		switch (encoder->type) {
+			unsigned int port_mask;
+		case INTEL_OUTPUT_UNKNOWN:
+			if (WARN_ON(!HAS_DDI(dev)))
+				break;
+		case INTEL_OUTPUT_DISPLAYPORT:
+		case INTEL_OUTPUT_HDMI:
+		case INTEL_OUTPUT_EDP:
+			port_mask = 1 << enc_to_dig_port(&encoder->base)->port;
+
+			/* the same port mustn't appear more than once */
+			if (used_ports & port_mask)
+				return false;
+
+			used_ports |= port_mask;
+		default:
+			break;
+		}
+	}
+
+	return true;
+}
+
+static void
+clear_intel_crtc_state(struct intel_crtc_state *crtc_state)
+{
+	struct drm_crtc_state tmp_state;
+	struct intel_crtc_scaler_state scaler_state;
+	struct intel_dpll_hw_state dpll_hw_state;
+	struct intel_shared_dpll *shared_dpll;
+	uint32_t ddi_pll_sel;
+	bool force_thru;
+
+	/* FIXME: before the switch to atomic started, a new pipe_config was
+	 * kzalloc'd. Code that depends on any field being zero should be
+	 * fixed, so that the crtc_state can be safely duplicated. For now,
+	 * only fields that are know to not cause problems are preserved. */
+
+	tmp_state = crtc_state->base;
+	scaler_state = crtc_state->scaler_state;
+	shared_dpll = crtc_state->shared_dpll;
+	dpll_hw_state = crtc_state->dpll_hw_state;
+	ddi_pll_sel = crtc_state->ddi_pll_sel;
+	force_thru = crtc_state->pch_pfit.force_thru;
+
+	memset(crtc_state, 0, sizeof *crtc_state);
+
+	crtc_state->base = tmp_state;
+	crtc_state->scaler_state = scaler_state;
+	crtc_state->shared_dpll = shared_dpll;
+	crtc_state->dpll_hw_state = dpll_hw_state;
+	crtc_state->ddi_pll_sel = ddi_pll_sel;
+	crtc_state->pch_pfit.force_thru = force_thru;
+}
+
+static int
+intel_modeset_pipe_config(struct drm_crtc *crtc,
+			  struct intel_crtc_state *pipe_config)
+{
+	struct drm_atomic_state *state = pipe_config->base.state;
+	struct intel_encoder *encoder;
+	struct drm_connector *connector;
+	struct drm_connector_state *connector_state;
+	int base_bpp, ret = -EINVAL;
+	int i;
+	bool retry = true;
+
+	clear_intel_crtc_state(pipe_config);
+
+	pipe_config->cpu_transcoder =
+		(enum transcoder) to_intel_crtc(crtc)->pipe;
+
+	/*
+	 * Sanitize sync polarity flags based on requested ones. If neither
+	 * positive or negative polarity is requested, treat this as meaning
+	 * negative polarity.
+	 */
+	if (!(pipe_config->base.adjusted_mode.flags &
+	      (DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NHSYNC)))
+		pipe_config->base.adjusted_mode.flags |= DRM_MODE_FLAG_NHSYNC;
+
+	if (!(pipe_config->base.adjusted_mode.flags &
+	      (DRM_MODE_FLAG_PVSYNC | DRM_MODE_FLAG_NVSYNC)))
+		pipe_config->base.adjusted_mode.flags |= DRM_MODE_FLAG_NVSYNC;
+
+	base_bpp = compute_baseline_pipe_bpp(to_intel_crtc(crtc),
+					     pipe_config);
+	if (base_bpp < 0)
+		goto fail;
+
+	/*
+	 * Determine the real pipe dimensions. Note that stereo modes can
+	 * increase the actual pipe size due to the frame doubling and
+	 * insertion of additional space for blanks between the frame. This
+	 * is stored in the crtc timings. We use the requested mode to do this
+	 * computation to clearly distinguish it from the adjusted mode, which
+	 * can be changed by the connectors in the below retry loop.
+	 */
+	drm_crtc_get_hv_timing(&pipe_config->base.mode,
+			       &pipe_config->pipe_src_w,
+			       &pipe_config->pipe_src_h);
+
+encoder_retry:
+	/* Ensure the port clock defaults are reset when retrying. */
+	pipe_config->port_clock = 0;
+	pipe_config->pixel_multiplier = 1;
+
+	/* Fill in default crtc timings, allow encoders to overwrite them. */
+	drm_mode_set_crtcinfo(&pipe_config->base.adjusted_mode,
+			      CRTC_STEREO_DOUBLE);
+
+	/* Pass our mode to the connectors and the CRTC to give them a chance to
+	 * adjust it according to limitations or connector properties, and also
+	 * a chance to reject the mode entirely.
+	 */
+	for_each_connector_in_state(state, connector, connector_state, i) {
+		if (connector_state->crtc != crtc)
+			continue;
+
+		encoder = to_intel_encoder(connector_state->best_encoder);
+
+		if (!(encoder->compute_config(encoder, pipe_config))) {
+			DRM_DEBUG_KMS("Encoder config failure\n");
+			goto fail;
+		}
+	}
+
+	/* Set default port clock if not overwritten by the encoder. Needs to be
+	 * done afterwards in case the encoder adjusts the mode. */
+	if (!pipe_config->port_clock)
+		pipe_config->port_clock = pipe_config->base.adjusted_mode.crtc_clock
+			* pipe_config->pixel_multiplier;
+
+	ret = intel_crtc_compute_config(to_intel_crtc(crtc), pipe_config);
+	if (ret < 0) {
+		DRM_DEBUG_KMS("CRTC fixup failed\n");
+		goto fail;
+	}
+
+	if (ret == RETRY) {
+		if (WARN(!retry, "loop in pipe configuration computation\n")) {
+			ret = -EINVAL;
+			goto fail;
+		}
+
+		DRM_DEBUG_KMS("CRTC bw constrained, retrying\n");
+		retry = false;
+		goto encoder_retry;
+	}
+
+	/* Dithering seems to not pass-through bits correctly when it should, so
+	 * only enable it on 6bpc panels. */
+	pipe_config->dither = pipe_config->pipe_bpp == 6*3;
+	DRM_DEBUG_KMS("hw max bpp: %i, pipe bpp: %i, dithering: %i\n",
+		      base_bpp, pipe_config->pipe_bpp, pipe_config->dither);
+
+fail:
+	return ret;
+}
+
+static void
+intel_modeset_update_crtc_state(struct drm_atomic_state *state)
+{
+	struct drm_crtc *crtc;
+	struct drm_crtc_state *crtc_state;
+	int i;
+
+	/* Double check state. */
+	for_each_crtc_in_state(state, crtc, crtc_state, i) {
+		to_intel_crtc(crtc)->config = to_intel_crtc_state(crtc->state);
+
+		/* Update hwmode for vblank functions */
+		if (crtc->state->active)
+			crtc->hwmode = crtc->state->adjusted_mode;
+		else
+			crtc->hwmode.crtc_clock = 0;
+
+		/*
+		 * Update legacy state to satisfy fbc code. This can
+		 * be removed when fbc uses the atomic state.
+		 */
+		if (drm_atomic_get_existing_plane_state(state, crtc->primary)) {
+			struct drm_plane_state *plane_state = crtc->primary->state;
+
+			crtc->primary->fb = plane_state->fb;
+			crtc->x = plane_state->src_x >> 16;
+			crtc->y = plane_state->src_y >> 16;
+		}
+	}
+}
+
+static bool intel_fuzzy_clock_check(int clock1, int clock2)
+{
+	int diff;
+
+	if (clock1 == clock2)
+		return true;
+
+	if (!clock1 || !clock2)
+		return false;
+
+	diff = abs(clock1 - clock2);
+
+	if (((((diff + clock1 + clock2) * 100)) / (clock1 + clock2)) < 105)
+		return true;
+
+	return false;
+}
+
+#define for_each_intel_crtc_masked(dev, mask, intel_crtc) \
+	list_for_each_entry((intel_crtc), \
+			    &(dev)->mode_config.crtc_list, \
+			    base.head) \
+		for_each_if (mask & (1 <<(intel_crtc)->pipe))
+
+static bool
+intel_compare_m_n(unsigned int m, unsigned int n,
+		  unsigned int m2, unsigned int n2,
+		  bool exact)
+{
+	if (m == m2 && n == n2)
+		return true;
+
+	if (exact || !m || !n || !m2 || !n2)
+		return false;
+
+	BUILD_BUG_ON(DATA_LINK_M_N_MASK > INT_MAX);
+
+	if (n > n2) {
+		while (n > n2) {
+			m2 <<= 1;
+			n2 <<= 1;
+		}
+	} else if (n < n2) {
+		while (n < n2) {
+			m <<= 1;
+			n <<= 1;
+		}
+	}
+
+	if (n != n2)
+		return false;
+
+	return intel_fuzzy_clock_check(m, m2);
+}
+
+static bool
+intel_compare_link_m_n(const struct intel_link_m_n *m_n,
+		       struct intel_link_m_n *m2_n2,
+		       bool adjust)
+{
+	if (m_n->tu == m2_n2->tu &&
+	    intel_compare_m_n(m_n->gmch_m, m_n->gmch_n,
+			      m2_n2->gmch_m, m2_n2->gmch_n, !adjust) &&
+	    intel_compare_m_n(m_n->link_m, m_n->link_n,
+			      m2_n2->link_m, m2_n2->link_n, !adjust)) {
+		if (adjust)
+			*m2_n2 = *m_n;
+
+		return true;
+	}
+
+	return false;
+}
+
+static bool
+intel_pipe_config_compare(struct drm_device *dev,
+			  struct intel_crtc_state *current_config,
+			  struct intel_crtc_state *pipe_config,
+			  bool adjust)
+{
+	bool ret = true;
+
+#define INTEL_ERR_OR_DBG_KMS(fmt, ...) \
+	do { \
+		if (!adjust) \
+			DRM_ERROR(fmt, ##__VA_ARGS__); \
+		else \
+			DRM_DEBUG_KMS(fmt, ##__VA_ARGS__); \
+	} while (0)
+
+#define PIPE_CONF_CHECK_X(name)	\
+	if (current_config->name != pipe_config->name) { \
+		INTEL_ERR_OR_DBG_KMS("mismatch in " #name " " \
+			  "(expected 0x%08x, found 0x%08x)\n", \
+			  current_config->name, \
+			  pipe_config->name); \
+		ret = false; \
+	}
+
+#define PIPE_CONF_CHECK_I(name)	\
+	if (current_config->name != pipe_config->name) { \
+		INTEL_ERR_OR_DBG_KMS("mismatch in " #name " " \
+			  "(expected %i, found %i)\n", \
+			  current_config->name, \
+			  pipe_config->name); \
+		ret = false; \
+	}
+
+#define PIPE_CONF_CHECK_P(name)	\
+	if (current_config->name != pipe_config->name) { \
+		INTEL_ERR_OR_DBG_KMS("mismatch in " #name " " \
+			  "(expected %p, found %p)\n", \
+			  current_config->name, \
+			  pipe_config->name); \
+		ret = false; \
+	}
+
+#define PIPE_CONF_CHECK_M_N(name) \
+	if (!intel_compare_link_m_n(&current_config->name, \
+				    &pipe_config->name,\
+				    adjust)) { \
+		INTEL_ERR_OR_DBG_KMS("mismatch in " #name " " \
+			  "(expected tu %i gmch %i/%i link %i/%i, " \
+			  "found tu %i, gmch %i/%i link %i/%i)\n", \
+			  current_config->name.tu, \
+			  current_config->name.gmch_m, \
+			  current_config->name.gmch_n, \
+			  current_config->name.link_m, \
+			  current_config->name.link_n, \
+			  pipe_config->name.tu, \
+			  pipe_config->name.gmch_m, \
+			  pipe_config->name.gmch_n, \
+			  pipe_config->name.link_m, \
+			  pipe_config->name.link_n); \
+		ret = false; \
+	}
+
+/* This is required for BDW+ where there is only one set of registers for
+ * switching between high and low RR.
+ * This macro can be used whenever a comparison has to be made between one
+ * hw state and multiple sw state variables.
+ */
+#define PIPE_CONF_CHECK_M_N_ALT(name, alt_name) \
+	if (!intel_compare_link_m_n(&current_config->name, \
+				    &pipe_config->name, adjust) && \
+	    !intel_compare_link_m_n(&current_config->alt_name, \
+				    &pipe_config->name, adjust)) { \
+		INTEL_ERR_OR_DBG_KMS("mismatch in " #name " " \
+			  "(expected tu %i gmch %i/%i link %i/%i, " \
+			  "or tu %i gmch %i/%i link %i/%i, " \
+			  "found tu %i, gmch %i/%i link %i/%i)\n", \
+			  current_config->name.tu, \
+			  current_config->name.gmch_m, \
+			  current_config->name.gmch_n, \
+			  current_config->name.link_m, \
+			  current_config->name.link_n, \
+			  current_config->alt_name.tu, \
+			  current_config->alt_name.gmch_m, \
+			  current_config->alt_name.gmch_n, \
+			  current_config->alt_name.link_m, \
+			  current_config->alt_name.link_n, \
+			  pipe_config->name.tu, \
+			  pipe_config->name.gmch_m, \
+			  pipe_config->name.gmch_n, \
+			  pipe_config->name.link_m, \
+			  pipe_config->name.link_n); \
+		ret = false; \
+	}
+
+#define PIPE_CONF_CHECK_FLAGS(name, mask)	\
+	if ((current_config->name ^ pipe_config->name) & (mask)) { \
+		INTEL_ERR_OR_DBG_KMS("mismatch in " #name "(" #mask ") " \
+			  "(expected %i, found %i)\n", \
+			  current_config->name & (mask), \
+			  pipe_config->name & (mask)); \
+		ret = false; \
+	}
+
+#define PIPE_CONF_CHECK_CLOCK_FUZZY(name) \
+	if (!intel_fuzzy_clock_check(current_config->name, pipe_config->name)) { \
+		INTEL_ERR_OR_DBG_KMS("mismatch in " #name " " \
+			  "(expected %i, found %i)\n", \
+			  current_config->name, \
+			  pipe_config->name); \
+		ret = false; \
+	}
+
+#define PIPE_CONF_QUIRK(quirk)	\
+	((current_config->quirks | pipe_config->quirks) & (quirk))
+
+	PIPE_CONF_CHECK_I(cpu_transcoder);
+
+	PIPE_CONF_CHECK_I(has_pch_encoder);
+	PIPE_CONF_CHECK_I(fdi_lanes);
+	PIPE_CONF_CHECK_M_N(fdi_m_n);
+
+	PIPE_CONF_CHECK_I(has_dp_encoder);
+	PIPE_CONF_CHECK_I(lane_count);
+
+	if (INTEL_INFO(dev)->gen < 8) {
+		PIPE_CONF_CHECK_M_N(dp_m_n);
+
+		if (current_config->has_drrs)
+			PIPE_CONF_CHECK_M_N(dp_m2_n2);
+	} else
+		PIPE_CONF_CHECK_M_N_ALT(dp_m_n, dp_m2_n2);
+
+	PIPE_CONF_CHECK_I(has_dsi_encoder);
+
+	PIPE_CONF_CHECK_I(base.adjusted_mode.crtc_hdisplay);
+	PIPE_CONF_CHECK_I(base.adjusted_mode.crtc_htotal);
+	PIPE_CONF_CHECK_I(base.adjusted_mode.crtc_hblank_start);
+	PIPE_CONF_CHECK_I(base.adjusted_mode.crtc_hblank_end);
+	PIPE_CONF_CHECK_I(base.adjusted_mode.crtc_hsync_start);
+	PIPE_CONF_CHECK_I(base.adjusted_mode.crtc_hsync_end);
+
+	PIPE_CONF_CHECK_I(base.adjusted_mode.crtc_vdisplay);
+	PIPE_CONF_CHECK_I(base.adjusted_mode.crtc_vtotal);
+	PIPE_CONF_CHECK_I(base.adjusted_mode.crtc_vblank_start);
+	PIPE_CONF_CHECK_I(base.adjusted_mode.crtc_vblank_end);
+	PIPE_CONF_CHECK_I(base.adjusted_mode.crtc_vsync_start);
+	PIPE_CONF_CHECK_I(base.adjusted_mode.crtc_vsync_end);
+
+	PIPE_CONF_CHECK_I(pixel_multiplier);
+	PIPE_CONF_CHECK_I(has_hdmi_sink);
+	if ((INTEL_INFO(dev)->gen < 8 && !IS_HASWELL(dev)) ||
+	    IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev))
+		PIPE_CONF_CHECK_I(limited_color_range);
+	PIPE_CONF_CHECK_I(has_infoframe);
+
+	PIPE_CONF_CHECK_I(has_audio);
+
+	PIPE_CONF_CHECK_FLAGS(base.adjusted_mode.flags,
+			      DRM_MODE_FLAG_INTERLACE);
+
+	if (!PIPE_CONF_QUIRK(PIPE_CONFIG_QUIRK_MODE_SYNC_FLAGS)) {
+		PIPE_CONF_CHECK_FLAGS(base.adjusted_mode.flags,
+				      DRM_MODE_FLAG_PHSYNC);
+		PIPE_CONF_CHECK_FLAGS(base.adjusted_mode.flags,
+				      DRM_MODE_FLAG_NHSYNC);
+		PIPE_CONF_CHECK_FLAGS(base.adjusted_mode.flags,
+				      DRM_MODE_FLAG_PVSYNC);
+		PIPE_CONF_CHECK_FLAGS(base.adjusted_mode.flags,
+				      DRM_MODE_FLAG_NVSYNC);
+	}
+
+	PIPE_CONF_CHECK_X(gmch_pfit.control);
+	/* pfit ratios are autocomputed by the hw on gen4+ */
+	if (INTEL_INFO(dev)->gen < 4)
+		PIPE_CONF_CHECK_X(gmch_pfit.pgm_ratios);
+	PIPE_CONF_CHECK_X(gmch_pfit.lvds_border_bits);
+
+	if (!adjust) {
+		PIPE_CONF_CHECK_I(pipe_src_w);
+		PIPE_CONF_CHECK_I(pipe_src_h);
+
+		PIPE_CONF_CHECK_I(pch_pfit.enabled);
+		if (current_config->pch_pfit.enabled) {
+			PIPE_CONF_CHECK_X(pch_pfit.pos);
+			PIPE_CONF_CHECK_X(pch_pfit.size);
+		}
+
+		PIPE_CONF_CHECK_I(scaler_state.scaler_id);
+	}
+
+	/* BDW+ don't expose a synchronous way to read the state */
+	if (IS_HASWELL(dev))
+		PIPE_CONF_CHECK_I(ips_enabled);
+
+	PIPE_CONF_CHECK_I(double_wide);
+
+	PIPE_CONF_CHECK_X(ddi_pll_sel);
+
+	PIPE_CONF_CHECK_P(shared_dpll);
+	PIPE_CONF_CHECK_X(dpll_hw_state.dpll);
+	PIPE_CONF_CHECK_X(dpll_hw_state.dpll_md);
+	PIPE_CONF_CHECK_X(dpll_hw_state.fp0);
+	PIPE_CONF_CHECK_X(dpll_hw_state.fp1);
+	PIPE_CONF_CHECK_X(dpll_hw_state.wrpll);
+	PIPE_CONF_CHECK_X(dpll_hw_state.spll);
+	PIPE_CONF_CHECK_X(dpll_hw_state.ctrl1);
+	PIPE_CONF_CHECK_X(dpll_hw_state.cfgcr1);
+	PIPE_CONF_CHECK_X(dpll_hw_state.cfgcr2);
+
+	PIPE_CONF_CHECK_X(dsi_pll.ctrl);
+	PIPE_CONF_CHECK_X(dsi_pll.div);
+
+	if (IS_G4X(dev) || INTEL_INFO(dev)->gen >= 5)
+		PIPE_CONF_CHECK_I(pipe_bpp);
+
+	PIPE_CONF_CHECK_CLOCK_FUZZY(base.adjusted_mode.crtc_clock);
+	PIPE_CONF_CHECK_CLOCK_FUZZY(port_clock);
+
+#undef PIPE_CONF_CHECK_X
+#undef PIPE_CONF_CHECK_I
+#undef PIPE_CONF_CHECK_P
+#undef PIPE_CONF_CHECK_FLAGS
+#undef PIPE_CONF_CHECK_CLOCK_FUZZY
+#undef PIPE_CONF_QUIRK
+#undef INTEL_ERR_OR_DBG_KMS
+
+	return ret;
+}
+
+static void intel_pipe_config_sanity_check(struct drm_i915_private *dev_priv,
+					   const struct intel_crtc_state *pipe_config)
+{
+	if (pipe_config->has_pch_encoder) {
+		int fdi_dotclock = intel_dotclock_calculate(intel_fdi_link_freq(dev_priv, pipe_config),
+							    &pipe_config->fdi_m_n);
+		int dotclock = pipe_config->base.adjusted_mode.crtc_clock;
+
+		/*
+		 * FDI already provided one idea for the dotclock.
+		 * Yell if the encoder disagrees.
+		 */
+		WARN(!intel_fuzzy_clock_check(fdi_dotclock, dotclock),
+		     "FDI dotclock and encoder dotclock mismatch, fdi: %i, encoder: %i\n",
+		     fdi_dotclock, dotclock);
+	}
+}
+
+static void verify_wm_state(struct drm_crtc *crtc,
+			    struct drm_crtc_state *new_state)
+{
+	struct drm_device *dev = crtc->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct skl_ddb_allocation hw_ddb, *sw_ddb;
+	struct skl_ddb_entry *hw_entry, *sw_entry;
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	const enum pipe pipe = intel_crtc->pipe;
+	int plane;
+
+	if (INTEL_INFO(dev)->gen < 9 || !new_state->active)
+		return;
+
+	skl_ddb_get_hw_state(dev_priv, &hw_ddb);
+	sw_ddb = &dev_priv->wm.skl_hw.ddb;
+
+	/* planes */
+	for_each_plane(dev_priv, pipe, plane) {
+		hw_entry = &hw_ddb.plane[pipe][plane];
+		sw_entry = &sw_ddb->plane[pipe][plane];
+
+		if (skl_ddb_entry_equal(hw_entry, sw_entry))
+			continue;
+
+		DRM_ERROR("mismatch in DDB state pipe %c plane %d "
+			  "(expected (%u,%u), found (%u,%u))\n",
+			  pipe_name(pipe), plane + 1,
+			  sw_entry->start, sw_entry->end,
+			  hw_entry->start, hw_entry->end);
+	}
+
+	/* cursor */
+	hw_entry = &hw_ddb.plane[pipe][PLANE_CURSOR];
+	sw_entry = &sw_ddb->plane[pipe][PLANE_CURSOR];
+
+	if (!skl_ddb_entry_equal(hw_entry, sw_entry)) {
+		DRM_ERROR("mismatch in DDB state pipe %c cursor "
+			  "(expected (%u,%u), found (%u,%u))\n",
+			  pipe_name(pipe),
+			  sw_entry->start, sw_entry->end,
+			  hw_entry->start, hw_entry->end);
+	}
+}
+
+static void
+verify_connector_state(struct drm_device *dev, struct drm_crtc *crtc)
+{
+	struct drm_connector *connector;
+
+	drm_for_each_connector(connector, dev) {
+		struct drm_encoder *encoder = connector->encoder;
+		struct drm_connector_state *state = connector->state;
+
+		if (state->crtc != crtc)
+			continue;
+
+		intel_connector_verify_state(to_intel_connector(connector));
+
+		I915_STATE_WARN(state->best_encoder != encoder,
+		     "connector's atomic encoder doesn't match legacy encoder\n");
+	}
+}
+
+static void
+verify_encoder_state(struct drm_device *dev)
+{
+	struct intel_encoder *encoder;
+	struct intel_connector *connector;
+
+	for_each_intel_encoder(dev, encoder) {
+		bool enabled = false;
+		enum pipe pipe;
+
+		DRM_DEBUG_KMS("[ENCODER:%d:%s]\n",
+			      encoder->base.base.id,
+			      encoder->base.name);
+
+		for_each_intel_connector(dev, connector) {
+			if (connector->base.state->best_encoder != &encoder->base)
+				continue;
+			enabled = true;
+
+			I915_STATE_WARN(connector->base.state->crtc !=
+					encoder->base.crtc,
+			     "connector's crtc doesn't match encoder crtc\n");
+		}
+
+		I915_STATE_WARN(!!encoder->base.crtc != enabled,
+		     "encoder's enabled state mismatch "
+		     "(expected %i, found %i)\n",
+		     !!encoder->base.crtc, enabled);
+
+		if (!encoder->base.crtc) {
+			bool active;
+
+			active = encoder->get_hw_state(encoder, &pipe);
+			I915_STATE_WARN(active,
+			     "encoder detached but still enabled on pipe %c.\n",
+			     pipe_name(pipe));
+		}
+	}
+}
+
+static void
+verify_crtc_state(struct drm_crtc *crtc,
+		  struct drm_crtc_state *old_crtc_state,
+		  struct drm_crtc_state *new_crtc_state)
+{
+	struct drm_device *dev = crtc->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_encoder *encoder;
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	struct intel_crtc_state *pipe_config, *sw_config;
+	struct drm_atomic_state *old_state;
+	bool active;
+
+	old_state = old_crtc_state->state;
+	__drm_atomic_helper_crtc_destroy_state(crtc, old_crtc_state);
+	pipe_config = to_intel_crtc_state(old_crtc_state);
+	memset(pipe_config, 0, sizeof(*pipe_config));
+	pipe_config->base.crtc = crtc;
+	pipe_config->base.state = old_state;
+
+	DRM_DEBUG_KMS("[CRTC:%d]\n", crtc->base.id);
+
+	active = dev_priv->display.get_pipe_config(intel_crtc, pipe_config);
+
+	/* hw state is inconsistent with the pipe quirk */
+	if ((intel_crtc->pipe == PIPE_A && dev_priv->quirks & QUIRK_PIPEA_FORCE) ||
+	    (intel_crtc->pipe == PIPE_B && dev_priv->quirks & QUIRK_PIPEB_FORCE))
+		active = new_crtc_state->active;
+
+	I915_STATE_WARN(new_crtc_state->active != active,
+	     "crtc active state doesn't match with hw state "
+	     "(expected %i, found %i)\n", new_crtc_state->active, active);
+
+	I915_STATE_WARN(intel_crtc->active != new_crtc_state->active,
+	     "transitional active state does not match atomic hw state "
+	     "(expected %i, found %i)\n", new_crtc_state->active, intel_crtc->active);
+
+	for_each_encoder_on_crtc(dev, crtc, encoder) {
+		enum pipe pipe;
+
+		active = encoder->get_hw_state(encoder, &pipe);
+		I915_STATE_WARN(active != new_crtc_state->active,
+			"[ENCODER:%i] active %i with crtc active %i\n",
+			encoder->base.base.id, active, new_crtc_state->active);
+
+		I915_STATE_WARN(active && intel_crtc->pipe != pipe,
+				"Encoder connected to wrong pipe %c\n",
+				pipe_name(pipe));
+
+		if (active)
+			encoder->get_config(encoder, pipe_config);
+	}
+
+	if (!new_crtc_state->active)
+		return;
+
+	intel_pipe_config_sanity_check(dev_priv, pipe_config);
+
+	sw_config = to_intel_crtc_state(crtc->state);
+	if (!intel_pipe_config_compare(dev, sw_config,
+				       pipe_config, false)) {
+		I915_STATE_WARN(1, "pipe state doesn't match!\n");
+		intel_dump_pipe_config(intel_crtc, pipe_config,
+				       "[hw state]");
+		intel_dump_pipe_config(intel_crtc, sw_config,
+				       "[sw state]");
+	}
+}
+
+static void
+verify_single_dpll_state(struct drm_i915_private *dev_priv,
+			 struct intel_shared_dpll *pll,
+			 struct drm_crtc *crtc,
+			 struct drm_crtc_state *new_state)
+{
+	struct intel_dpll_hw_state dpll_hw_state;
+	unsigned crtc_mask;
+	bool active;
+
+	memset(&dpll_hw_state, 0, sizeof(dpll_hw_state));
+
+	DRM_DEBUG_KMS("%s\n", pll->name);
+
+	active = pll->funcs.get_hw_state(dev_priv, pll, &dpll_hw_state);
+
+	if (!(pll->flags & INTEL_DPLL_ALWAYS_ON)) {
+		I915_STATE_WARN(!pll->on && pll->active_mask,
+		     "pll in active use but not on in sw tracking\n");
+		I915_STATE_WARN(pll->on && !pll->active_mask,
+		     "pll is on but not used by any active crtc\n");
+		I915_STATE_WARN(pll->on != active,
+		     "pll on state mismatch (expected %i, found %i)\n",
+		     pll->on, active);
+	}
+
+	if (!crtc) {
+		I915_STATE_WARN(pll->active_mask & ~pll->config.crtc_mask,
+				"more active pll users than references: %x vs %x\n",
+				pll->active_mask, pll->config.crtc_mask);
+
+		return;
+	}
+
+	crtc_mask = 1 << drm_crtc_index(crtc);
+
+	if (new_state->active)
+		I915_STATE_WARN(!(pll->active_mask & crtc_mask),
+				"pll active mismatch (expected pipe %c in active mask 0x%02x)\n",
+				pipe_name(drm_crtc_index(crtc)), pll->active_mask);
+	else
+		I915_STATE_WARN(pll->active_mask & crtc_mask,
+				"pll active mismatch (didn't expect pipe %c in active mask 0x%02x)\n",
+				pipe_name(drm_crtc_index(crtc)), pll->active_mask);
+
+	I915_STATE_WARN(!(pll->config.crtc_mask & crtc_mask),
+			"pll enabled crtcs mismatch (expected 0x%x in 0x%02x)\n",
+			crtc_mask, pll->config.crtc_mask);
+
+	I915_STATE_WARN(pll->on && memcmp(&pll->config.hw_state,
+					  &dpll_hw_state,
+					  sizeof(dpll_hw_state)),
+			"pll hw state mismatch\n");
+}
+
+static void
+verify_shared_dpll_state(struct drm_device *dev, struct drm_crtc *crtc,
+			 struct drm_crtc_state *old_crtc_state,
+			 struct drm_crtc_state *new_crtc_state)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_crtc_state *old_state = to_intel_crtc_state(old_crtc_state);
+	struct intel_crtc_state *new_state = to_intel_crtc_state(new_crtc_state);
+
+	if (new_state->shared_dpll)
+		verify_single_dpll_state(dev_priv, new_state->shared_dpll, crtc, new_crtc_state);
+
+	if (old_state->shared_dpll &&
+	    old_state->shared_dpll != new_state->shared_dpll) {
+		unsigned crtc_mask = 1 << drm_crtc_index(crtc);
+		struct intel_shared_dpll *pll = old_state->shared_dpll;
+
+		I915_STATE_WARN(pll->active_mask & crtc_mask,
+				"pll active mismatch (didn't expect pipe %c in active mask)\n",
+				pipe_name(drm_crtc_index(crtc)));
+		I915_STATE_WARN(pll->config.crtc_mask & crtc_mask,
+				"pll enabled crtcs mismatch (found %x in enabled mask)\n",
+				pipe_name(drm_crtc_index(crtc)));
+	}
+}
+
+static void
+intel_modeset_verify_crtc(struct drm_crtc *crtc,
+			 struct drm_crtc_state *old_state,
+			 struct drm_crtc_state *new_state)
+{
+	if (!needs_modeset(new_state) &&
+	    !to_intel_crtc_state(new_state)->update_pipe)
+		return;
+
+	verify_wm_state(crtc, new_state);
+	verify_connector_state(crtc->dev, crtc);
+	verify_crtc_state(crtc, old_state, new_state);
+	verify_shared_dpll_state(crtc->dev, crtc, old_state, new_state);
+}
+
+static void
+verify_disabled_dpll_state(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	int i;
+
+	for (i = 0; i < dev_priv->num_shared_dpll; i++)
+		verify_single_dpll_state(dev_priv, &dev_priv->shared_dplls[i], NULL, NULL);
+}
+
+static void
+intel_modeset_verify_disabled(struct drm_device *dev)
+{
+	verify_encoder_state(dev);
+	verify_connector_state(dev, NULL);
+	verify_disabled_dpll_state(dev);
+}
+
+static void update_scanline_offset(struct intel_crtc *crtc)
+{
+	struct drm_device *dev = crtc->base.dev;
+
+	/*
+	 * The scanline counter increments at the leading edge of hsync.
+	 *
+	 * On most platforms it starts counting from vtotal-1 on the
+	 * first active line. That means the scanline counter value is
+	 * always one less than what we would expect. Ie. just after
+	 * start of vblank, which also occurs at start of hsync (on the
+	 * last active line), the scanline counter will read vblank_start-1.
+	 *
+	 * On gen2 the scanline counter starts counting from 1 instead
+	 * of vtotal-1, so we have to subtract one (or rather add vtotal-1
+	 * to keep the value positive), instead of adding one.
+	 *
+	 * On HSW+ the behaviour of the scanline counter depends on the output
+	 * type. For DP ports it behaves like most other platforms, but on HDMI
+	 * there's an extra 1 line difference. So we need to add two instead of
+	 * one to the value.
+	 */
+	if (IS_GEN2(dev)) {
+		const struct drm_display_mode *adjusted_mode = &crtc->config->base.adjusted_mode;
+		int vtotal;
+
+		vtotal = adjusted_mode->crtc_vtotal;
+		if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE)
+			vtotal /= 2;
+
+		crtc->scanline_offset = vtotal - 1;
+	} else if (HAS_DDI(dev) &&
+		   intel_pipe_has_type(crtc, INTEL_OUTPUT_HDMI)) {
+		crtc->scanline_offset = 2;
+	} else
+		crtc->scanline_offset = 1;
+}
+
+static void intel_modeset_clear_plls(struct drm_atomic_state *state)
+{
+	struct drm_device *dev = state->dev;
+	struct drm_i915_private *dev_priv = to_i915(dev);
+	struct intel_shared_dpll_config *shared_dpll = NULL;
+	struct drm_crtc *crtc;
+	struct drm_crtc_state *crtc_state;
+	int i;
+
+	if (!dev_priv->display.crtc_compute_clock)
+		return;
+
+	for_each_crtc_in_state(state, crtc, crtc_state, i) {
+		struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+		struct intel_shared_dpll *old_dpll =
+			to_intel_crtc_state(crtc->state)->shared_dpll;
+
+		if (!needs_modeset(crtc_state))
+			continue;
+
+		to_intel_crtc_state(crtc_state)->shared_dpll = NULL;
+
+		if (!old_dpll)
+			continue;
+
+		if (!shared_dpll)
+			shared_dpll = intel_atomic_get_shared_dpll_state(state);
+
+		intel_shared_dpll_config_put(shared_dpll, old_dpll, intel_crtc);
+	}
+}
+
+/*
+ * This implements the workaround described in the "notes" section of the mode
+ * set sequence documentation. When going from no pipes or single pipe to
+ * multiple pipes, and planes are enabled after the pipe, we need to wait at
+ * least 2 vblanks on the first pipe before enabling planes on the second pipe.
+ */
+static int haswell_mode_set_planes_workaround(struct drm_atomic_state *state)
+{
+	struct drm_crtc_state *crtc_state;
+	struct intel_crtc *intel_crtc;
+	struct drm_crtc *crtc;
+	struct intel_crtc_state *first_crtc_state = NULL;
+	struct intel_crtc_state *other_crtc_state = NULL;
+	enum pipe first_pipe = INVALID_PIPE, enabled_pipe = INVALID_PIPE;
+	int i;
+
+	/* look at all crtc's that are going to be enabled in during modeset */
+	for_each_crtc_in_state(state, crtc, crtc_state, i) {
+		intel_crtc = to_intel_crtc(crtc);
+
+		if (!crtc_state->active || !needs_modeset(crtc_state))
+			continue;
+
+		if (first_crtc_state) {
+			other_crtc_state = to_intel_crtc_state(crtc_state);
+			break;
+		} else {
+			first_crtc_state = to_intel_crtc_state(crtc_state);
+			first_pipe = intel_crtc->pipe;
+		}
+	}
+
+	/* No workaround needed? */
+	if (!first_crtc_state)
+		return 0;
+
+	/* w/a possibly needed, check how many crtc's are already enabled. */
+	for_each_intel_crtc(state->dev, intel_crtc) {
+		struct intel_crtc_state *pipe_config;
+
+		pipe_config = intel_atomic_get_crtc_state(state, intel_crtc);
+		if (IS_ERR(pipe_config))
+			return PTR_ERR(pipe_config);
+
+		pipe_config->hsw_workaround_pipe = INVALID_PIPE;
+
+		if (!pipe_config->base.active ||
+		    needs_modeset(&pipe_config->base))
+			continue;
+
+		/* 2 or more enabled crtcs means no need for w/a */
+		if (enabled_pipe != INVALID_PIPE)
+			return 0;
+
+		enabled_pipe = intel_crtc->pipe;
+	}
+
+	if (enabled_pipe != INVALID_PIPE)
+		first_crtc_state->hsw_workaround_pipe = enabled_pipe;
+	else if (other_crtc_state)
+		other_crtc_state->hsw_workaround_pipe = first_pipe;
+
+	return 0;
+}
+
+static int intel_modeset_all_pipes(struct drm_atomic_state *state)
+{
+	struct drm_crtc *crtc;
+	struct drm_crtc_state *crtc_state;
+	int ret = 0;
+
+	/* add all active pipes to the state */
+	for_each_crtc(state->dev, crtc) {
+		crtc_state = drm_atomic_get_crtc_state(state, crtc);
+		if (IS_ERR(crtc_state))
+			return PTR_ERR(crtc_state);
+
+		if (!crtc_state->active || needs_modeset(crtc_state))
+			continue;
+
+		crtc_state->mode_changed = true;
+
+		ret = drm_atomic_add_affected_connectors(state, crtc);
+		if (ret)
+			break;
+
+		ret = drm_atomic_add_affected_planes(state, crtc);
+		if (ret)
+			break;
+	}
+
+	return ret;
+}
+
+static int intel_modeset_checks(struct drm_atomic_state *state)
+{
+	struct intel_atomic_state *intel_state = to_intel_atomic_state(state);
+	struct drm_i915_private *dev_priv = state->dev->dev_private;
+	struct drm_crtc *crtc;
+	struct drm_crtc_state *crtc_state;
+	int ret = 0, i;
+
+	if (!check_digital_port_conflicts(state)) {
+		DRM_DEBUG_KMS("rejecting conflicting digital port configuration\n");
+		return -EINVAL;
+	}
+
+	intel_state->modeset = true;
+	intel_state->active_crtcs = dev_priv->active_crtcs;
+
+	for_each_crtc_in_state(state, crtc, crtc_state, i) {
+		if (crtc_state->active)
+			intel_state->active_crtcs |= 1 << i;
+		else
+			intel_state->active_crtcs &= ~(1 << i);
+	}
+
+	/*
+	 * See if the config requires any additional preparation, e.g.
+	 * to adjust global state with pipes off.  We need to do this
+	 * here so we can get the modeset_pipe updated config for the new
+	 * mode set on this crtc.  For other crtcs we need to use the
+	 * adjusted_mode bits in the crtc directly.
+	 */
+	if (dev_priv->display.modeset_calc_cdclk) {
+		ret = dev_priv->display.modeset_calc_cdclk(state);
+
+		if (!ret && intel_state->dev_cdclk != dev_priv->cdclk_freq)
+			ret = intel_modeset_all_pipes(state);
+
+		if (ret < 0)
+			return ret;
+
+		DRM_DEBUG_KMS("New cdclk calculated to be atomic %u, actual %u\n",
+			      intel_state->cdclk, intel_state->dev_cdclk);
+	} else
+		to_intel_atomic_state(state)->cdclk = dev_priv->atomic_cdclk_freq;
+
+	intel_modeset_clear_plls(state);
+
+	if (IS_HASWELL(dev_priv))
+		return haswell_mode_set_planes_workaround(state);
+
+	return 0;
+}
+
+/*
+ * Handle calculation of various watermark data at the end of the atomic check
+ * phase.  The code here should be run after the per-crtc and per-plane 'check'
+ * handlers to ensure that all derived state has been updated.
+ */
+static void calc_watermark_data(struct drm_atomic_state *state)
+{
+	struct drm_device *dev = state->dev;
+	struct intel_atomic_state *intel_state = to_intel_atomic_state(state);
+	struct drm_crtc *crtc;
+	struct drm_crtc_state *cstate;
+	struct drm_plane *plane;
+	struct drm_plane_state *pstate;
+
+	/*
+	 * Calculate watermark configuration details now that derived
+	 * plane/crtc state is all properly updated.
+	 */
+	drm_for_each_crtc(crtc, dev) {
+		cstate = drm_atomic_get_existing_crtc_state(state, crtc) ?:
+			crtc->state;
+
+		if (cstate->active)
+			intel_state->wm_config.num_pipes_active++;
+	}
+	drm_for_each_legacy_plane(plane, dev) {
+		pstate = drm_atomic_get_existing_plane_state(state, plane) ?:
+			plane->state;
+
+		if (!to_intel_plane_state(pstate)->visible)
+			continue;
+
+		intel_state->wm_config.sprites_enabled = true;
+		if (pstate->crtc_w != pstate->src_w >> 16 ||
+		    pstate->crtc_h != pstate->src_h >> 16)
+			intel_state->wm_config.sprites_scaled = true;
+	}
+}
+
+/**
+ * intel_atomic_check - validate state object
+ * @dev: drm device
+ * @state: state to validate
+ */
+static int intel_atomic_check(struct drm_device *dev,
+			      struct drm_atomic_state *state)
+{
+	struct drm_i915_private *dev_priv = to_i915(dev);
+	struct intel_atomic_state *intel_state = to_intel_atomic_state(state);
+	struct drm_crtc *crtc;
+	struct drm_crtc_state *crtc_state;
+	int ret, i;
+	bool any_ms = false;
+
+	ret = drm_atomic_helper_check_modeset(dev, state);
+	if (ret)
+		return ret;
+
+	for_each_crtc_in_state(state, crtc, crtc_state, i) {
+		struct intel_crtc_state *pipe_config =
+			to_intel_crtc_state(crtc_state);
+
+		/* Catch I915_MODE_FLAG_INHERITED */
+		if (crtc_state->mode.private_flags != crtc->state->mode.private_flags)
+			crtc_state->mode_changed = true;
+
+		if (!crtc_state->enable) {
+			if (needs_modeset(crtc_state))
+				any_ms = true;
+			continue;
+		}
+
+		if (!needs_modeset(crtc_state))
+			continue;
+
+		/* FIXME: For only active_changed we shouldn't need to do any
+		 * state recomputation at all. */
+
+		ret = drm_atomic_add_affected_connectors(state, crtc);
+		if (ret)
+			return ret;
+
+		ret = intel_modeset_pipe_config(crtc, pipe_config);
+		if (ret)
+			return ret;
+
+		if (i915.fastboot &&
+		    intel_pipe_config_compare(dev,
+					to_intel_crtc_state(crtc->state),
+					pipe_config, true)) {
+			crtc_state->mode_changed = false;
+			to_intel_crtc_state(crtc_state)->update_pipe = true;
+		}
+
+		if (needs_modeset(crtc_state)) {
+			any_ms = true;
+
+			ret = drm_atomic_add_affected_planes(state, crtc);
+			if (ret)
+				return ret;
+		}
+
+		intel_dump_pipe_config(to_intel_crtc(crtc), pipe_config,
+				       needs_modeset(crtc_state) ?
+				       "[modeset]" : "[fastset]");
+	}
+
+	if (any_ms) {
+		ret = intel_modeset_checks(state);
+
+		if (ret)
+			return ret;
+	} else
+		intel_state->cdclk = dev_priv->cdclk_freq;
+
+	ret = drm_atomic_helper_check_planes(dev, state);
+	if (ret)
+		return ret;
+
+	intel_fbc_choose_crtc(dev_priv, state);
+	calc_watermark_data(state);
+
+	return 0;
+}
+
+static int intel_atomic_prepare_commit(struct drm_device *dev,
+				       struct drm_atomic_state *state,
+				       bool nonblock)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct drm_plane_state *plane_state;
+	struct drm_crtc_state *crtc_state;
+	struct drm_plane *plane;
+	struct drm_crtc *crtc;
+	int i, ret;
+
+	if (nonblock) {
+		DRM_DEBUG_KMS("i915 does not yet support nonblocking commit\n");
+		return -EINVAL;
+	}
+
+	for_each_crtc_in_state(state, crtc, crtc_state, i) {
+		if (state->legacy_cursor_update)
+			continue;
+
+		ret = intel_crtc_wait_for_pending_flips(crtc);
+		if (ret)
+			return ret;
+
+		if (atomic_read(&to_intel_crtc(crtc)->unpin_work_count) >= 2)
+			flush_workqueue(dev_priv->wq);
+	}
+
+	ret = mutex_lock_interruptible(&dev->struct_mutex);
+	if (ret)
+		return ret;
+
+	ret = drm_atomic_helper_prepare_planes(dev, state);
+	mutex_unlock(&dev->struct_mutex);
+
+	if (!ret && !nonblock) {
+		for_each_plane_in_state(state, plane, plane_state, i) {
+			struct intel_plane_state *intel_plane_state =
+				to_intel_plane_state(plane_state);
+
+			if (!intel_plane_state->wait_req)
+				continue;
+
+			ret = __i915_wait_request(intel_plane_state->wait_req,
+						  true, NULL, NULL);
+			if (ret) {
+				/* Any hang should be swallowed by the wait */
+				WARN_ON(ret == -EIO);
+				mutex_lock(&dev->struct_mutex);
+				drm_atomic_helper_cleanup_planes(dev, state);
+				mutex_unlock(&dev->struct_mutex);
+				break;
+			}
+		}
+	}
+
+	return ret;
+}
+
+static void intel_atomic_wait_for_vblanks(struct drm_device *dev,
+					  struct drm_i915_private *dev_priv,
+					  unsigned crtc_mask)
+{
+	unsigned last_vblank_count[I915_MAX_PIPES];
+	enum pipe pipe;
+	int ret;
+
+	if (!crtc_mask)
+		return;
+
+	for_each_pipe(dev_priv, pipe) {
+		struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe];
+
+		if (!((1 << pipe) & crtc_mask))
+			continue;
+
+		ret = drm_crtc_vblank_get(crtc);
+		if (WARN_ON(ret != 0)) {
+			crtc_mask &= ~(1 << pipe);
+			continue;
+		}
+
+		last_vblank_count[pipe] = drm_crtc_vblank_count(crtc);
+	}
+
+	for_each_pipe(dev_priv, pipe) {
+		struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe];
+		long lret;
+
+		if (!((1 << pipe) & crtc_mask))
+			continue;
+
+		lret = wait_event_timeout(dev->vblank[pipe].queue,
+				last_vblank_count[pipe] !=
+					drm_crtc_vblank_count(crtc),
+				msecs_to_jiffies(50));
+
+		WARN(!lret, "pipe %c vblank wait timed out\n", pipe_name(pipe));
+
+		drm_crtc_vblank_put(crtc);
+	}
+}
+
+static bool needs_vblank_wait(struct intel_crtc_state *crtc_state)
+{
+	/* fb updated, need to unpin old fb */
+	if (crtc_state->fb_changed)
+		return true;
+
+	/* wm changes, need vblank before final wm's */
+	if (crtc_state->update_wm_post)
+		return true;
+
+	/*
+	 * cxsr is re-enabled after vblank.
+	 * This is already handled by crtc_state->update_wm_post,
+	 * but added for clarity.
+	 */
+	if (crtc_state->disable_cxsr)
+		return true;
+
+	return false;
+}
+
+/**
+ * intel_atomic_commit - commit validated state object
+ * @dev: DRM device
+ * @state: the top-level driver state object
+ * @nonblock: nonblocking commit
+ *
+ * This function commits a top-level state object that has been validated
+ * with drm_atomic_helper_check().
+ *
+ * FIXME:  Atomic modeset support for i915 is not yet complete.  At the moment
+ * we can only handle plane-related operations and do not yet support
+ * nonblocking commit.
+ *
+ * RETURNS
+ * Zero for success or -errno.
+ */
+static int intel_atomic_commit(struct drm_device *dev,
+			       struct drm_atomic_state *state,
+			       bool nonblock)
+{
+	struct intel_atomic_state *intel_state = to_intel_atomic_state(state);
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct drm_crtc_state *old_crtc_state;
+	struct drm_crtc *crtc;
+	struct intel_crtc_state *intel_cstate;
+	int ret = 0, i;
+	bool hw_check = intel_state->modeset;
+	unsigned long put_domains[I915_MAX_PIPES] = {};
+	unsigned crtc_vblank_mask = 0;
+
+	ret = intel_atomic_prepare_commit(dev, state, nonblock);
+	if (ret) {
+		DRM_DEBUG_ATOMIC("Preparing state failed with %i\n", ret);
+		return ret;
+	}
+
+	drm_atomic_helper_swap_state(dev, state);
+	dev_priv->wm.config = intel_state->wm_config;
+	intel_shared_dpll_commit(state);
+
+	if (intel_state->modeset) {
+		memcpy(dev_priv->min_pixclk, intel_state->min_pixclk,
+		       sizeof(intel_state->min_pixclk));
+		dev_priv->active_crtcs = intel_state->active_crtcs;
+		dev_priv->atomic_cdclk_freq = intel_state->cdclk;
+
+		intel_display_power_get(dev_priv, POWER_DOMAIN_MODESET);
+	}
+
+	for_each_crtc_in_state(state, crtc, old_crtc_state, i) {
+		struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+
+		if (needs_modeset(crtc->state) ||
+		    to_intel_crtc_state(crtc->state)->update_pipe) {
+			hw_check = true;
+
+			put_domains[to_intel_crtc(crtc)->pipe] =
+				modeset_get_crtc_power_domains(crtc,
+					to_intel_crtc_state(crtc->state));
+		}
+
+		if (!needs_modeset(crtc->state))
+			continue;
+
+		intel_pre_plane_update(to_intel_crtc_state(old_crtc_state));
+
+		if (old_crtc_state->active) {
+			intel_crtc_disable_planes(crtc, old_crtc_state->plane_mask);
+			dev_priv->display.crtc_disable(crtc);
+			intel_crtc->active = false;
+			intel_fbc_disable(intel_crtc);
+			intel_disable_shared_dpll(intel_crtc);
+
+			/*
+			 * Underruns don't always raise
+			 * interrupts, so check manually.
+			 */
+			intel_check_cpu_fifo_underruns(dev_priv);
+			intel_check_pch_fifo_underruns(dev_priv);
+
+			if (!crtc->state->active)
+				intel_update_watermarks(crtc);
+		}
+	}
+
+	/* Only after disabling all output pipelines that will be changed can we
+	 * update the the output configuration. */
+	intel_modeset_update_crtc_state(state);
+
+	if (intel_state->modeset) {
+		drm_atomic_helper_update_legacy_modeset_state(state->dev, state);
+
+		if (dev_priv->display.modeset_commit_cdclk &&
+		    intel_state->dev_cdclk != dev_priv->cdclk_freq)
+			dev_priv->display.modeset_commit_cdclk(state);
+
+		intel_modeset_verify_disabled(dev);
+	}
+
+	/* Now enable the clocks, plane, pipe, and connectors that we set up. */
+	for_each_crtc_in_state(state, crtc, old_crtc_state, i) {
+		struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+		bool modeset = needs_modeset(crtc->state);
+		struct intel_crtc_state *pipe_config =
+			to_intel_crtc_state(crtc->state);
+		bool update_pipe = !modeset && pipe_config->update_pipe;
+
+		if (modeset && crtc->state->active) {
+			update_scanline_offset(to_intel_crtc(crtc));
+			dev_priv->display.crtc_enable(crtc);
+		}
+
+		if (!modeset)
+			intel_pre_plane_update(to_intel_crtc_state(old_crtc_state));
+
+		if (crtc->state->active &&
+		    drm_atomic_get_existing_plane_state(state, crtc->primary))
+			intel_fbc_enable(intel_crtc);
+
+		if (crtc->state->active &&
+		    (crtc->state->planes_changed || update_pipe))
+			drm_atomic_helper_commit_planes_on_crtc(old_crtc_state);
+
+		if (pipe_config->base.active && needs_vblank_wait(pipe_config))
+			crtc_vblank_mask |= 1 << i;
+	}
+
+	/* FIXME: add subpixel order */
+
+	if (!state->legacy_cursor_update)
+		intel_atomic_wait_for_vblanks(dev, dev_priv, crtc_vblank_mask);
+
+	/*
+	 * Now that the vblank has passed, we can go ahead and program the
+	 * optimal watermarks on platforms that need two-step watermark
+	 * programming.
+	 *
+	 * TODO: Move this (and other cleanup) to an async worker eventually.
+	 */
+	for_each_crtc_in_state(state, crtc, old_crtc_state, i) {
+		intel_cstate = to_intel_crtc_state(crtc->state);
+
+		if (dev_priv->display.optimize_watermarks)
+			dev_priv->display.optimize_watermarks(intel_cstate);
+	}
+
+	for_each_crtc_in_state(state, crtc, old_crtc_state, i) {
+		intel_post_plane_update(to_intel_crtc_state(old_crtc_state));
+
+		if (put_domains[i])
+			modeset_put_power_domains(dev_priv, put_domains[i]);
+
+		intel_modeset_verify_crtc(crtc, old_crtc_state, crtc->state);
+	}
+
+	if (intel_state->modeset)
+		intel_display_power_put(dev_priv, POWER_DOMAIN_MODESET);
+
+	mutex_lock(&dev->struct_mutex);
+	drm_atomic_helper_cleanup_planes(dev, state);
+	mutex_unlock(&dev->struct_mutex);
+
+	drm_atomic_state_free(state);
+
+	/* As one of the primary mmio accessors, KMS has a high likelihood
+	 * of triggering bugs in unclaimed access. After we finish
+	 * modesetting, see if an error has been flagged, and if so
+	 * enable debugging for the next modeset - and hope we catch
+	 * the culprit.
+	 *
+	 * XXX note that we assume display power is on at this point.
+	 * This might hold true now but we need to add pm helper to check
+	 * unclaimed only when the hardware is on, as atomic commits
+	 * can happen also when the device is completely off.
+	 */
+	intel_uncore_arm_unclaimed_mmio_detection(dev_priv);
+
+	return 0;
+}
+
+void intel_crtc_restore_mode(struct drm_crtc *crtc)
+{
+	struct drm_device *dev = crtc->dev;
+	struct drm_atomic_state *state;
+	struct drm_crtc_state *crtc_state;
+	int ret;
+
+	state = drm_atomic_state_alloc(dev);
+	if (!state) {
+		DRM_DEBUG_KMS("[CRTC:%d] crtc restore failed, out of memory",
+			      crtc->base.id);
+		return;
+	}
+
+	state->acquire_ctx = drm_modeset_legacy_acquire_ctx(crtc);
+
+retry:
+	crtc_state = drm_atomic_get_crtc_state(state, crtc);
+	ret = PTR_ERR_OR_ZERO(crtc_state);
+	if (!ret) {
+		if (!crtc_state->active)
+			goto out;
+
+		crtc_state->mode_changed = true;
+		ret = drm_atomic_commit(state);
+	}
+
+	if (ret == -EDEADLK) {
+		drm_atomic_state_clear(state);
+		drm_modeset_backoff(state->acquire_ctx);
+		goto retry;
+	}
+
+	if (ret)
+out:
+		drm_atomic_state_free(state);
+}
+
+#undef for_each_intel_crtc_masked
+
+static const struct drm_crtc_funcs intel_crtc_funcs = {
+	.gamma_set = drm_atomic_helper_legacy_gamma_set,
+	.set_config = drm_atomic_helper_set_config,
+	.set_property = drm_atomic_helper_crtc_set_property,
+	.destroy = intel_crtc_destroy,
+	.page_flip = intel_crtc_page_flip,
+	.atomic_duplicate_state = intel_crtc_duplicate_state,
+	.atomic_destroy_state = intel_crtc_destroy_state,
+};
+
+/**
+ * intel_prepare_plane_fb - Prepare fb for usage on plane
+ * @plane: drm plane to prepare for
+ * @fb: framebuffer to prepare for presentation
+ *
+ * Prepares a framebuffer for usage on a display plane.  Generally this
+ * involves pinning the underlying object and updating the frontbuffer tracking
+ * bits.  Some older platforms need special physical address handling for
+ * cursor planes.
+ *
+ * Must be called with struct_mutex held.
+ *
+ * Returns 0 on success, negative error code on failure.
+ */
+int
+intel_prepare_plane_fb(struct drm_plane *plane,
+		       const struct drm_plane_state *new_state)
+{
+	struct drm_device *dev = plane->dev;
+	struct drm_framebuffer *fb = new_state->fb;
+	struct intel_plane *intel_plane = to_intel_plane(plane);
+	struct drm_i915_gem_object *obj = intel_fb_obj(fb);
+	struct drm_i915_gem_object *old_obj = intel_fb_obj(plane->state->fb);
+	int ret = 0;
+
+	if (!obj && !old_obj)
+		return 0;
+
+	if (old_obj) {
+		struct drm_crtc_state *crtc_state =
+			drm_atomic_get_existing_crtc_state(new_state->state, plane->state->crtc);
+
+		/* Big Hammer, we also need to ensure that any pending
+		 * MI_WAIT_FOR_EVENT inside a user batch buffer on the
+		 * current scanout is retired before unpinning the old
+		 * framebuffer. Note that we rely on userspace rendering
+		 * into the buffer attached to the pipe they are waiting
+		 * on. If not, userspace generates a GPU hang with IPEHR
+		 * point to the MI_WAIT_FOR_EVENT.
+		 *
+		 * This should only fail upon a hung GPU, in which case we
+		 * can safely continue.
+		 */
+		if (needs_modeset(crtc_state))
+			ret = i915_gem_object_wait_rendering(old_obj, true);
+		if (ret) {
+			/* GPU hangs should have been swallowed by the wait */
+			WARN_ON(ret == -EIO);
+			return ret;
+		}
+	}
+
+	/* For framebuffer backed by dmabuf, wait for fence */
+	if (obj && obj->base.dma_buf) {
+		long lret;
+
+		lret = reservation_object_wait_timeout_rcu(obj->base.dma_buf->resv,
+							   false, true,
+							   MAX_SCHEDULE_TIMEOUT);
+		if (lret == -ERESTARTSYS)
+			return lret;
+
+		WARN(lret < 0, "waiting returns %li\n", lret);
+	}
+
+	if (!obj) {
+		ret = 0;
+	} else if (plane->type == DRM_PLANE_TYPE_CURSOR &&
+	    INTEL_INFO(dev)->cursor_needs_physical) {
+		int align = IS_I830(dev) ? 16 * 1024 : 256;
+		ret = i915_gem_object_attach_phys(obj, align);
+		if (ret)
+			DRM_DEBUG_KMS("failed to attach phys object\n");
+	} else {
+		ret = intel_pin_and_fence_fb_obj(fb, new_state->rotation);
+	}
+
+	if (ret == 0) {
+		if (obj) {
+			struct intel_plane_state *plane_state =
+				to_intel_plane_state(new_state);
+
+			i915_gem_request_assign(&plane_state->wait_req,
+						obj->last_write_req);
+		}
+
+		i915_gem_track_fb(old_obj, obj, intel_plane->frontbuffer_bit);
+	}
+
+	return ret;
+}
+
+/**
+ * intel_cleanup_plane_fb - Cleans up an fb after plane use
+ * @plane: drm plane to clean up for
+ * @fb: old framebuffer that was on plane
+ *
+ * Cleans up a framebuffer that has just been removed from a plane.
+ *
+ * Must be called with struct_mutex held.
+ */
+void
+intel_cleanup_plane_fb(struct drm_plane *plane,
+		       const struct drm_plane_state *old_state)
+{
+	struct drm_device *dev = plane->dev;
+	struct intel_plane *intel_plane = to_intel_plane(plane);
+	struct intel_plane_state *old_intel_state;
+	struct drm_i915_gem_object *old_obj = intel_fb_obj(old_state->fb);
+	struct drm_i915_gem_object *obj = intel_fb_obj(plane->state->fb);
+
+	old_intel_state = to_intel_plane_state(old_state);
+
+	if (!obj && !old_obj)
+		return;
+
+	if (old_obj && (plane->type != DRM_PLANE_TYPE_CURSOR ||
+	    !INTEL_INFO(dev)->cursor_needs_physical))
+		intel_unpin_fb_obj(old_state->fb, old_state->rotation);
+
+	/* prepare_fb aborted? */
+	if ((old_obj && (old_obj->frontbuffer_bits & intel_plane->frontbuffer_bit)) ||
+	    (obj && !(obj->frontbuffer_bits & intel_plane->frontbuffer_bit)))
+		i915_gem_track_fb(old_obj, obj, intel_plane->frontbuffer_bit);
+
+	i915_gem_request_assign(&old_intel_state->wait_req, NULL);
+}
+
+int
+skl_max_scale(struct intel_crtc *intel_crtc, struct intel_crtc_state *crtc_state)
+{
+	int max_scale;
+	struct drm_device *dev;
+	struct drm_i915_private *dev_priv;
+	int crtc_clock, cdclk;
+
+	if (!intel_crtc || !crtc_state->base.enable)
+		return DRM_PLANE_HELPER_NO_SCALING;
+
+	dev = intel_crtc->base.dev;
+	dev_priv = dev->dev_private;
+	crtc_clock = crtc_state->base.adjusted_mode.crtc_clock;
+	cdclk = to_intel_atomic_state(crtc_state->base.state)->cdclk;
+
+	if (WARN_ON_ONCE(!crtc_clock || cdclk < crtc_clock))
+		return DRM_PLANE_HELPER_NO_SCALING;
+
+	/*
+	 * skl max scale is lower of:
+	 *    close to 3 but not 3, -1 is for that purpose
+	 *            or
+	 *    cdclk/crtc_clock
+	 */
+	max_scale = min((1 << 16) * 3 - 1, (1 << 8) * ((cdclk << 8) / crtc_clock));
+
+	return max_scale;
+}
+
+static int
+intel_check_primary_plane(struct drm_plane *plane,
+			  struct intel_crtc_state *crtc_state,
+			  struct intel_plane_state *state)
+{
+	struct drm_crtc *crtc = state->base.crtc;
+	struct drm_framebuffer *fb = state->base.fb;
+	int min_scale = DRM_PLANE_HELPER_NO_SCALING;
+	int max_scale = DRM_PLANE_HELPER_NO_SCALING;
+	bool can_position = false;
+
+	if (INTEL_INFO(plane->dev)->gen >= 9) {
+		/* use scaler when colorkey is not required */
+		if (state->ckey.flags == I915_SET_COLORKEY_NONE) {
+			min_scale = 1;
+			max_scale = skl_max_scale(to_intel_crtc(crtc), crtc_state);
+		}
+		can_position = true;
+	}
+
+	return drm_plane_helper_check_update(plane, crtc, fb, &state->src,
+					     &state->dst, &state->clip,
+					     min_scale, max_scale,
+					     can_position, true,
+					     &state->visible);
+}
+
+static void intel_begin_crtc_commit(struct drm_crtc *crtc,
+				    struct drm_crtc_state *old_crtc_state)
+{
+	struct drm_device *dev = crtc->dev;
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	struct intel_crtc_state *old_intel_state =
+		to_intel_crtc_state(old_crtc_state);
+	bool modeset = needs_modeset(crtc->state);
+
+	/* Perform vblank evasion around commit operation */
+	intel_pipe_update_start(intel_crtc);
+
+	if (modeset)
+		return;
+
+	if (crtc->state->color_mgmt_changed || to_intel_crtc_state(crtc->state)->update_pipe) {
+		intel_color_set_csc(crtc->state);
+		intel_color_load_luts(crtc->state);
+	}
+
+	if (to_intel_crtc_state(crtc->state)->update_pipe)
+		intel_update_pipe_config(intel_crtc, old_intel_state);
+	else if (INTEL_INFO(dev)->gen >= 9)
+		skl_detach_scalers(intel_crtc);
+}
+
+static void intel_finish_crtc_commit(struct drm_crtc *crtc,
+				     struct drm_crtc_state *old_crtc_state)
+{
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+
+	intel_pipe_update_end(intel_crtc);
+}
+
+/**
+ * intel_plane_destroy - destroy a plane
+ * @plane: plane to destroy
+ *
+ * Common destruction function for all types of planes (primary, cursor,
+ * sprite).
+ */
+void intel_plane_destroy(struct drm_plane *plane)
+{
+	struct intel_plane *intel_plane = to_intel_plane(plane);
+	drm_plane_cleanup(plane);
+	kfree(intel_plane);
+}
+
+const struct drm_plane_funcs intel_plane_funcs = {
+	.update_plane = drm_atomic_helper_update_plane,
+	.disable_plane = drm_atomic_helper_disable_plane,
+	.destroy = intel_plane_destroy,
+	.set_property = drm_atomic_helper_plane_set_property,
+	.atomic_get_property = intel_plane_atomic_get_property,
+	.atomic_set_property = intel_plane_atomic_set_property,
+	.atomic_duplicate_state = intel_plane_duplicate_state,
+	.atomic_destroy_state = intel_plane_destroy_state,
+
+};
+
+static struct drm_plane *intel_primary_plane_create(struct drm_device *dev,
+						    int pipe)
+{
+	struct intel_plane *primary = NULL;
+	struct intel_plane_state *state = NULL;
+	const uint32_t *intel_primary_formats;
+	unsigned int num_formats;
+	int ret;
+
+	primary = kzalloc(sizeof(*primary), GFP_KERNEL);
+	if (!primary)
+		goto fail;
+
+	state = intel_create_plane_state(&primary->base);
+	if (!state)
+		goto fail;
+	primary->base.state = &state->base;
+
+	primary->can_scale = false;
+	primary->max_downscale = 1;
+	if (INTEL_INFO(dev)->gen >= 9) {
+		primary->can_scale = true;
+		state->scaler_id = -1;
+	}
+	primary->pipe = pipe;
+	primary->plane = pipe;
+	primary->frontbuffer_bit = INTEL_FRONTBUFFER_PRIMARY(pipe);
+	primary->check_plane = intel_check_primary_plane;
+	if (HAS_FBC(dev) && INTEL_INFO(dev)->gen < 4)
+		primary->plane = !pipe;
+
+	if (INTEL_INFO(dev)->gen >= 9) {
+		intel_primary_formats = skl_primary_formats;
+		num_formats = ARRAY_SIZE(skl_primary_formats);
+
+		primary->update_plane = skylake_update_primary_plane;
+		primary->disable_plane = skylake_disable_primary_plane;
+	} else if (HAS_PCH_SPLIT(dev)) {
+		intel_primary_formats = i965_primary_formats;
+		num_formats = ARRAY_SIZE(i965_primary_formats);
+
+		primary->update_plane = ironlake_update_primary_plane;
+		primary->disable_plane = i9xx_disable_primary_plane;
+	} else if (INTEL_INFO(dev)->gen >= 4) {
+		intel_primary_formats = i965_primary_formats;
+		num_formats = ARRAY_SIZE(i965_primary_formats);
+
+		primary->update_plane = i9xx_update_primary_plane;
+		primary->disable_plane = i9xx_disable_primary_plane;
+	} else {
+		intel_primary_formats = i8xx_primary_formats;
+		num_formats = ARRAY_SIZE(i8xx_primary_formats);
+
+		primary->update_plane = i9xx_update_primary_plane;
+		primary->disable_plane = i9xx_disable_primary_plane;
+	}
+
+	ret = drm_universal_plane_init(dev, &primary->base, 0,
+				       &intel_plane_funcs,
+				       intel_primary_formats, num_formats,
+				       DRM_PLANE_TYPE_PRIMARY);
+	if (ret)
+		goto fail;
+
+	if (INTEL_INFO(dev)->gen >= 4)
+		intel_create_rotation_property(dev, primary);
+
+	drm_plane_helper_add(&primary->base, &intel_plane_helper_funcs);
+
+	return &primary->base;
+
+fail:
+	kfree(state);
+	kfree(primary);
+
+	return NULL;
+}
+
+void intel_create_rotation_property(struct drm_device *dev, struct intel_plane *plane)
+{
+	if (!dev->mode_config.rotation_property) {
+		unsigned long flags = BIT(DRM_ROTATE_0) |
+			BIT(DRM_ROTATE_180);
+
+		if (INTEL_INFO(dev)->gen >= 9)
+			flags |= BIT(DRM_ROTATE_90) | BIT(DRM_ROTATE_270);
+
+		dev->mode_config.rotation_property =
+			drm_mode_create_rotation_property(dev, flags);
+	}
+	if (dev->mode_config.rotation_property)
+		drm_object_attach_property(&plane->base.base,
+				dev->mode_config.rotation_property,
+				plane->base.state->rotation);
+}
+
+static int
+intel_check_cursor_plane(struct drm_plane *plane,
+			 struct intel_crtc_state *crtc_state,
+			 struct intel_plane_state *state)
+{
+	struct drm_crtc *crtc = crtc_state->base.crtc;
+	struct drm_framebuffer *fb = state->base.fb;
+	struct drm_i915_gem_object *obj = intel_fb_obj(fb);
+	enum pipe pipe = to_intel_plane(plane)->pipe;
+	unsigned stride;
+	int ret;
+
+	ret = drm_plane_helper_check_update(plane, crtc, fb, &state->src,
+					    &state->dst, &state->clip,
+					    DRM_PLANE_HELPER_NO_SCALING,
+					    DRM_PLANE_HELPER_NO_SCALING,
+					    true, true, &state->visible);
+	if (ret)
+		return ret;
+
+	/* if we want to turn off the cursor ignore width and height */
+	if (!obj)
+		return 0;
+
+	/* Check for which cursor types we support */
+	if (!cursor_size_ok(plane->dev, state->base.crtc_w, state->base.crtc_h)) {
+		DRM_DEBUG("Cursor dimension %dx%d not supported\n",
+			  state->base.crtc_w, state->base.crtc_h);
+		return -EINVAL;
+	}
+
+	stride = roundup_pow_of_two(state->base.crtc_w) * 4;
+	if (obj->base.size < stride * state->base.crtc_h) {
+		DRM_DEBUG_KMS("buffer is too small\n");
+		return -ENOMEM;
+	}
+
+	if (fb->modifier[0] != DRM_FORMAT_MOD_NONE) {
+		DRM_DEBUG_KMS("cursor cannot be tiled\n");
+		return -EINVAL;
+	}
+
+	/*
+	 * There's something wrong with the cursor on CHV pipe C.
+	 * If it straddles the left edge of the screen then
+	 * moving it away from the edge or disabling it often
+	 * results in a pipe underrun, and often that can lead to
+	 * dead pipe (constant underrun reported, and it scans
+	 * out just a solid color). To recover from that, the
+	 * display power well must be turned off and on again.
+	 * Refuse the put the cursor into that compromised position.
+	 */
+	if (IS_CHERRYVIEW(plane->dev) && pipe == PIPE_C &&
+	    state->visible && state->base.crtc_x < 0) {
+		DRM_DEBUG_KMS("CHV cursor C not allowed to straddle the left screen edge\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static void
+intel_disable_cursor_plane(struct drm_plane *plane,
+			   struct drm_crtc *crtc)
+{
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+
+	intel_crtc->cursor_addr = 0;
+	intel_crtc_update_cursor(crtc, NULL);
+}
+
+static void
+intel_update_cursor_plane(struct drm_plane *plane,
+			  const struct intel_crtc_state *crtc_state,
+			  const struct intel_plane_state *state)
+{
+	struct drm_crtc *crtc = crtc_state->base.crtc;
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	struct drm_device *dev = plane->dev;
+	struct drm_i915_gem_object *obj = intel_fb_obj(state->base.fb);
+	uint32_t addr;
+
+	if (!obj)
+		addr = 0;
+	else if (!INTEL_INFO(dev)->cursor_needs_physical)
+		addr = i915_gem_obj_ggtt_offset(obj);
+	else
+		addr = obj->phys_handle->busaddr;
+
+	intel_crtc->cursor_addr = addr;
+	intel_crtc_update_cursor(crtc, state);
+}
+
+static struct drm_plane *intel_cursor_plane_create(struct drm_device *dev,
+						   int pipe)
+{
+	struct intel_plane *cursor = NULL;
+	struct intel_plane_state *state = NULL;
+	int ret;
+
+	cursor = kzalloc(sizeof(*cursor), GFP_KERNEL);
+	if (!cursor)
+		goto fail;
+
+	state = intel_create_plane_state(&cursor->base);
+	if (!state)
+		goto fail;
+	cursor->base.state = &state->base;
+
+	cursor->can_scale = false;
+	cursor->max_downscale = 1;
+	cursor->pipe = pipe;
+	cursor->plane = pipe;
+	cursor->frontbuffer_bit = INTEL_FRONTBUFFER_CURSOR(pipe);
+	cursor->check_plane = intel_check_cursor_plane;
+	cursor->update_plane = intel_update_cursor_plane;
+	cursor->disable_plane = intel_disable_cursor_plane;
+
+	ret = drm_universal_plane_init(dev, &cursor->base, 0,
+				       &intel_plane_funcs,
+				       intel_cursor_formats,
+				       ARRAY_SIZE(intel_cursor_formats),
+				       DRM_PLANE_TYPE_CURSOR);
+	if (ret)
+		goto fail;
+
+	if (INTEL_INFO(dev)->gen >= 4) {
+		if (!dev->mode_config.rotation_property)
+			dev->mode_config.rotation_property =
+				drm_mode_create_rotation_property(dev,
+							BIT(DRM_ROTATE_0) |
+							BIT(DRM_ROTATE_180));
+		if (dev->mode_config.rotation_property)
+			drm_object_attach_property(&cursor->base.base,
+				dev->mode_config.rotation_property,
+				state->base.rotation);
+	}
+
+	if (INTEL_INFO(dev)->gen >=9)
+		state->scaler_id = -1;
+
+	drm_plane_helper_add(&cursor->base, &intel_plane_helper_funcs);
+
+	return &cursor->base;
+
+fail:
+	kfree(state);
+	kfree(cursor);
+
+	return NULL;
+}
+
+static void skl_init_scalers(struct drm_device *dev, struct intel_crtc *intel_crtc,
+	struct intel_crtc_state *crtc_state)
+{
+	int i;
+	struct intel_scaler *intel_scaler;
+	struct intel_crtc_scaler_state *scaler_state = &crtc_state->scaler_state;
+
+	for (i = 0; i < intel_crtc->num_scalers; i++) {
+		intel_scaler = &scaler_state->scalers[i];
+		intel_scaler->in_use = 0;
+		intel_scaler->mode = PS_SCALER_MODE_DYN;
+	}
+
+	scaler_state->scaler_id = -1;
+}
+
+static void intel_crtc_init(struct drm_device *dev, int pipe)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_crtc *intel_crtc;
+	struct intel_crtc_state *crtc_state = NULL;
+	struct drm_plane *primary = NULL;
+	struct drm_plane *cursor = NULL;
+	int ret;
+
+	intel_crtc = kzalloc(sizeof(*intel_crtc), GFP_KERNEL);
+	if (intel_crtc == NULL)
+		return;
+
+	crtc_state = kzalloc(sizeof(*crtc_state), GFP_KERNEL);
+	if (!crtc_state)
+		goto fail;
+	intel_crtc->config = crtc_state;
+	intel_crtc->base.state = &crtc_state->base;
+	crtc_state->base.crtc = &intel_crtc->base;
+
+	/* initialize shared scalers */
+	if (INTEL_INFO(dev)->gen >= 9) {
+		if (pipe == PIPE_C)
+			intel_crtc->num_scalers = 1;
+		else
+			intel_crtc->num_scalers = SKL_NUM_SCALERS;
+
+		skl_init_scalers(dev, intel_crtc, crtc_state);
+	}
+
+	primary = intel_primary_plane_create(dev, pipe);
+	if (!primary)
+		goto fail;
+
+	cursor = intel_cursor_plane_create(dev, pipe);
+	if (!cursor)
+		goto fail;
+
+	ret = drm_crtc_init_with_planes(dev, &intel_crtc->base, primary,
+					cursor, &intel_crtc_funcs);
+	if (ret)
+		goto fail;
+
+	/*
+	 * On gen2/3 only plane A can do fbc, but the panel fitter and lvds port
+	 * is hooked to pipe B. Hence we want plane A feeding pipe B.
+	 */
+	intel_crtc->pipe = pipe;
+	intel_crtc->plane = pipe;
+	if (HAS_FBC(dev) && INTEL_INFO(dev)->gen < 4) {
+		DRM_DEBUG_KMS("swapping pipes & planes for FBC\n");
+		intel_crtc->plane = !pipe;
+	}
+
+	intel_crtc->cursor_base = ~0;
+	intel_crtc->cursor_cntl = ~0;
+	intel_crtc->cursor_size = ~0;
+
+	intel_crtc->wm.cxsr_allowed = true;
+
+	BUG_ON(pipe >= ARRAY_SIZE(dev_priv->plane_to_crtc_mapping) ||
+	       dev_priv->plane_to_crtc_mapping[intel_crtc->plane] != NULL);
+	dev_priv->plane_to_crtc_mapping[intel_crtc->plane] = &intel_crtc->base;
+	dev_priv->pipe_to_crtc_mapping[intel_crtc->pipe] = &intel_crtc->base;
+
+	drm_crtc_helper_add(&intel_crtc->base, &intel_helper_funcs);
+
+	intel_color_init(&intel_crtc->base);
+
+	WARN_ON(drm_crtc_index(&intel_crtc->base) != intel_crtc->pipe);
+	return;
+
+fail:
+	if (primary)
+		drm_plane_cleanup(primary);
+	if (cursor)
+		drm_plane_cleanup(cursor);
+	kfree(crtc_state);
+	kfree(intel_crtc);
+}
+
+enum pipe intel_get_pipe_from_connector(struct intel_connector *connector)
+{
+	struct drm_encoder *encoder = connector->base.encoder;
+	struct drm_device *dev = connector->base.dev;
+
+	WARN_ON(!drm_modeset_is_locked(&dev->mode_config.connection_mutex));
+
+	if (!encoder || WARN_ON(!encoder->crtc))
+		return INVALID_PIPE;
+
+	return to_intel_crtc(encoder->crtc)->pipe;
+}
+
+int intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data,
+				struct drm_file *file)
+{
+	struct drm_i915_get_pipe_from_crtc_id *pipe_from_crtc_id = data;
+	struct drm_crtc *drmmode_crtc;
+	struct intel_crtc *crtc;
+
+	drmmode_crtc = drm_crtc_find(dev, pipe_from_crtc_id->crtc_id);
+
+	if (!drmmode_crtc) {
+		DRM_ERROR("no such CRTC id\n");
+		return -ENOENT;
+	}
+
+	crtc = to_intel_crtc(drmmode_crtc);
+	pipe_from_crtc_id->pipe = crtc->pipe;
+
+	return 0;
+}
+
+static int intel_encoder_clones(struct intel_encoder *encoder)
+{
+	struct drm_device *dev = encoder->base.dev;
+	struct intel_encoder *source_encoder;
+	int index_mask = 0;
+	int entry = 0;
+
+	for_each_intel_encoder(dev, source_encoder) {
+		if (encoders_cloneable(encoder, source_encoder))
+			index_mask |= (1 << entry);
+
+		entry++;
+	}
+
+	return index_mask;
+}
+
+static bool has_edp_a(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	if (!IS_MOBILE(dev))
+		return false;
+
+	if ((I915_READ(DP_A) & DP_DETECTED) == 0)
+		return false;
+
+	if (IS_GEN5(dev) && (I915_READ(FUSE_STRAP) & ILK_eDP_A_DISABLE))
+		return false;
+
+	return true;
+}
+
+static bool intel_crt_present(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	if (INTEL_INFO(dev)->gen >= 9)
+		return false;
+
+	if (IS_HSW_ULT(dev) || IS_BDW_ULT(dev))
+		return false;
+
+	if (IS_CHERRYVIEW(dev))
+		return false;
+
+	if (HAS_PCH_LPT_H(dev) && I915_READ(SFUSE_STRAP) & SFUSE_STRAP_CRT_DISABLED)
+		return false;
+
+	/* DDI E can't be used if DDI A requires 4 lanes */
+	if (HAS_DDI(dev) && I915_READ(DDI_BUF_CTL(PORT_A)) & DDI_A_4_LANES)
+		return false;
+
+	if (!dev_priv->vbt.int_crt_support)
+		return false;
+
+	return true;
+}
+
+static void intel_setup_outputs(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_encoder *encoder;
+	bool dpd_is_edp = false;
+
+	intel_lvds_init(dev);
+
+	if (intel_crt_present(dev))
+		intel_crt_init(dev);
+
+	if (IS_BROXTON(dev)) {
+		/*
+		 * FIXME: Broxton doesn't support port detection via the
+		 * DDI_BUF_CTL_A or SFUSE_STRAP registers, find another way to
+		 * detect the ports.
+		 */
+		intel_ddi_init(dev, PORT_A);
+		intel_ddi_init(dev, PORT_B);
+		intel_ddi_init(dev, PORT_C);
+
+		intel_dsi_init(dev);
+	} else if (HAS_DDI(dev)) {
+		int found;
+
+		/*
+		 * Haswell uses DDI functions to detect digital outputs.
+		 * On SKL pre-D0 the strap isn't connected, so we assume
+		 * it's there.
+		 */
+		found = I915_READ(DDI_BUF_CTL(PORT_A)) & DDI_INIT_DISPLAY_DETECTED;
+		/* WaIgnoreDDIAStrap: skl */
+		if (found || IS_SKYLAKE(dev) || IS_KABYLAKE(dev))
+			intel_ddi_init(dev, PORT_A);
+
+		/* DDI B, C and D detection is indicated by the SFUSE_STRAP
+		 * register */
+		found = I915_READ(SFUSE_STRAP);
+
+		if (found & SFUSE_STRAP_DDIB_DETECTED)
+			intel_ddi_init(dev, PORT_B);
+		if (found & SFUSE_STRAP_DDIC_DETECTED)
+			intel_ddi_init(dev, PORT_C);
+		if (found & SFUSE_STRAP_DDID_DETECTED)
+			intel_ddi_init(dev, PORT_D);
+		/*
+		 * On SKL we don't have a way to detect DDI-E so we rely on VBT.
+		 */
+		if ((IS_SKYLAKE(dev) || IS_KABYLAKE(dev)) &&
+		    (dev_priv->vbt.ddi_port_info[PORT_E].supports_dp ||
+		     dev_priv->vbt.ddi_port_info[PORT_E].supports_dvi ||
+		     dev_priv->vbt.ddi_port_info[PORT_E].supports_hdmi))
+			intel_ddi_init(dev, PORT_E);
+
+	} else if (HAS_PCH_SPLIT(dev)) {
+		int found;
+		dpd_is_edp = intel_dp_is_edp(dev, PORT_D);
+
+		if (has_edp_a(dev))
+			intel_dp_init(dev, DP_A, PORT_A);
+
+		if (I915_READ(PCH_HDMIB) & SDVO_DETECTED) {
+			/* PCH SDVOB multiplex with HDMIB */
+			found = intel_sdvo_init(dev, PCH_SDVOB, PORT_B);
+			if (!found)
+				intel_hdmi_init(dev, PCH_HDMIB, PORT_B);
+			if (!found && (I915_READ(PCH_DP_B) & DP_DETECTED))
+				intel_dp_init(dev, PCH_DP_B, PORT_B);
+		}
+
+		if (I915_READ(PCH_HDMIC) & SDVO_DETECTED)
+			intel_hdmi_init(dev, PCH_HDMIC, PORT_C);
+
+		if (!dpd_is_edp && I915_READ(PCH_HDMID) & SDVO_DETECTED)
+			intel_hdmi_init(dev, PCH_HDMID, PORT_D);
+
+		if (I915_READ(PCH_DP_C) & DP_DETECTED)
+			intel_dp_init(dev, PCH_DP_C, PORT_C);
+
+		if (I915_READ(PCH_DP_D) & DP_DETECTED)
+			intel_dp_init(dev, PCH_DP_D, PORT_D);
+	} else if (IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev)) {
+		bool has_edp, has_port;
+
+		/*
+		 * The DP_DETECTED bit is the latched state of the DDC
+		 * SDA pin at boot. However since eDP doesn't require DDC
+		 * (no way to plug in a DP->HDMI dongle) the DDC pins for
+		 * eDP ports may have been muxed to an alternate function.
+		 * Thus we can't rely on the DP_DETECTED bit alone to detect
+		 * eDP ports. Consult the VBT as well as DP_DETECTED to
+		 * detect eDP ports.
+		 *
+		 * Sadly the straps seem to be missing sometimes even for HDMI
+		 * ports (eg. on Voyo V3 - CHT x7-Z8700), so check both strap
+		 * and VBT for the presence of the port. Additionally we can't
+		 * trust the port type the VBT declares as we've seen at least
+		 * HDMI ports that the VBT claim are DP or eDP.
+		 */
+		has_edp = intel_dp_is_edp(dev, PORT_B);
+		has_port = intel_bios_is_port_present(dev_priv, PORT_B);
+		if (I915_READ(VLV_DP_B) & DP_DETECTED || has_port)
+			has_edp &= intel_dp_init(dev, VLV_DP_B, PORT_B);
+		if ((I915_READ(VLV_HDMIB) & SDVO_DETECTED || has_port) && !has_edp)
+			intel_hdmi_init(dev, VLV_HDMIB, PORT_B);
+
+		has_edp = intel_dp_is_edp(dev, PORT_C);
+		has_port = intel_bios_is_port_present(dev_priv, PORT_C);
+		if (I915_READ(VLV_DP_C) & DP_DETECTED || has_port)
+			has_edp &= intel_dp_init(dev, VLV_DP_C, PORT_C);
+		if ((I915_READ(VLV_HDMIC) & SDVO_DETECTED || has_port) && !has_edp)
+			intel_hdmi_init(dev, VLV_HDMIC, PORT_C);
+
+		if (IS_CHERRYVIEW(dev)) {
+			/*
+			 * eDP not supported on port D,
+			 * so no need to worry about it
+			 */
+			has_port = intel_bios_is_port_present(dev_priv, PORT_D);
+			if (I915_READ(CHV_DP_D) & DP_DETECTED || has_port)
+				intel_dp_init(dev, CHV_DP_D, PORT_D);
+			if (I915_READ(CHV_HDMID) & SDVO_DETECTED || has_port)
+				intel_hdmi_init(dev, CHV_HDMID, PORT_D);
+		}
+
+		intel_dsi_init(dev);
+	} else if (!IS_GEN2(dev) && !IS_PINEVIEW(dev)) {
+		bool found = false;
+
+		if (I915_READ(GEN3_SDVOB) & SDVO_DETECTED) {
+			DRM_DEBUG_KMS("probing SDVOB\n");
+			found = intel_sdvo_init(dev, GEN3_SDVOB, PORT_B);
+			if (!found && IS_G4X(dev)) {
+				DRM_DEBUG_KMS("probing HDMI on SDVOB\n");
+				intel_hdmi_init(dev, GEN4_HDMIB, PORT_B);
+			}
+
+			if (!found && IS_G4X(dev))
+				intel_dp_init(dev, DP_B, PORT_B);
+		}
+
+		/* Before G4X SDVOC doesn't have its own detect register */
+
+		if (I915_READ(GEN3_SDVOB) & SDVO_DETECTED) {
+			DRM_DEBUG_KMS("probing SDVOC\n");
+			found = intel_sdvo_init(dev, GEN3_SDVOC, PORT_C);
+		}
+
+		if (!found && (I915_READ(GEN3_SDVOC) & SDVO_DETECTED)) {
+
+			if (IS_G4X(dev)) {
+				DRM_DEBUG_KMS("probing HDMI on SDVOC\n");
+				intel_hdmi_init(dev, GEN4_HDMIC, PORT_C);
+			}
+			if (IS_G4X(dev))
+				intel_dp_init(dev, DP_C, PORT_C);
+		}
+
+		if (IS_G4X(dev) &&
+		    (I915_READ(DP_D) & DP_DETECTED))
+			intel_dp_init(dev, DP_D, PORT_D);
+	} else if (IS_GEN2(dev))
+		intel_dvo_init(dev);
+
+	if (SUPPORTS_TV(dev))
+		intel_tv_init(dev);
+
+	intel_psr_init(dev);
+
+	for_each_intel_encoder(dev, encoder) {
+		encoder->base.possible_crtcs = encoder->crtc_mask;
+		encoder->base.possible_clones =
+			intel_encoder_clones(encoder);
+	}
+
+	intel_init_pch_refclk(dev);
+
+	drm_helper_move_panel_connectors_to_head(dev);
+}
+
+static void intel_user_framebuffer_destroy(struct drm_framebuffer *fb)
+{
+	struct drm_device *dev = fb->dev;
+	struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb);
+
+	drm_framebuffer_cleanup(fb);
+	mutex_lock(&dev->struct_mutex);
+	WARN_ON(!intel_fb->obj->framebuffer_references--);
+	drm_gem_object_unreference(&intel_fb->obj->base);
+	mutex_unlock(&dev->struct_mutex);
+	kfree(intel_fb);
+}
+
+static int intel_user_framebuffer_create_handle(struct drm_framebuffer *fb,
+						struct drm_file *file,
+						unsigned int *handle)
+{
+	struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb);
+	struct drm_i915_gem_object *obj = intel_fb->obj;
+
+	if (obj->userptr.mm) {
+		DRM_DEBUG("attempting to use a userptr for a framebuffer, denied\n");
+		return -EINVAL;
+	}
+
+	return drm_gem_handle_create(file, &obj->base, handle);
+}
+
+static int intel_user_framebuffer_dirty(struct drm_framebuffer *fb,
+					struct drm_file *file,
+					unsigned flags, unsigned color,
+					struct drm_clip_rect *clips,
+					unsigned num_clips)
+{
+	struct drm_device *dev = fb->dev;
+	struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb);
+	struct drm_i915_gem_object *obj = intel_fb->obj;
+
+	mutex_lock(&dev->struct_mutex);
+	intel_fb_obj_flush(obj, false, ORIGIN_DIRTYFB);
+	mutex_unlock(&dev->struct_mutex);
+
+	return 0;
+}
+
+static const struct drm_framebuffer_funcs intel_fb_funcs = {
+	.destroy = intel_user_framebuffer_destroy,
+	.create_handle = intel_user_framebuffer_create_handle,
+	.dirty = intel_user_framebuffer_dirty,
+};
+
+static
+u32 intel_fb_pitch_limit(struct drm_device *dev, uint64_t fb_modifier,
+			 uint32_t pixel_format)
+{
+	u32 gen = INTEL_INFO(dev)->gen;
+
+	if (gen >= 9) {
+		int cpp = drm_format_plane_cpp(pixel_format, 0);
+
+		/* "The stride in bytes must not exceed the of the size of 8K
+		 *  pixels and 32K bytes."
+		 */
+		return min(8192 * cpp, 32768);
+	} else if (gen >= 5 && !IS_VALLEYVIEW(dev) && !IS_CHERRYVIEW(dev)) {
+		return 32*1024;
+	} else if (gen >= 4) {
+		if (fb_modifier == I915_FORMAT_MOD_X_TILED)
+			return 16*1024;
+		else
+			return 32*1024;
+	} else if (gen >= 3) {
+		if (fb_modifier == I915_FORMAT_MOD_X_TILED)
+			return 8*1024;
+		else
+			return 16*1024;
+	} else {
+		/* XXX DSPC is limited to 4k tiled */
+		return 8*1024;
+	}
+}
+
+static int intel_framebuffer_init(struct drm_device *dev,
+				  struct intel_framebuffer *intel_fb,
+				  struct drm_mode_fb_cmd2 *mode_cmd,
+				  struct drm_i915_gem_object *obj)
+{
+	struct drm_i915_private *dev_priv = to_i915(dev);
+	unsigned int aligned_height;
+	int ret;
+	u32 pitch_limit, stride_alignment;
+
+	WARN_ON(!mutex_is_locked(&dev->struct_mutex));
+
+	if (mode_cmd->flags & DRM_MODE_FB_MODIFIERS) {
+		/* Enforce that fb modifier and tiling mode match, but only for
+		 * X-tiled. This is needed for FBC. */
+		if (!!(obj->tiling_mode == I915_TILING_X) !=
+		    !!(mode_cmd->modifier[0] == I915_FORMAT_MOD_X_TILED)) {
+			DRM_DEBUG("tiling_mode doesn't match fb modifier\n");
+			return -EINVAL;
+		}
+	} else {
+		if (obj->tiling_mode == I915_TILING_X)
+			mode_cmd->modifier[0] = I915_FORMAT_MOD_X_TILED;
+		else if (obj->tiling_mode == I915_TILING_Y) {
+			DRM_DEBUG("No Y tiling for legacy addfb\n");
+			return -EINVAL;
+		}
+	}
+
+	/* Passed in modifier sanity checking. */
+	switch (mode_cmd->modifier[0]) {
+	case I915_FORMAT_MOD_Y_TILED:
+	case I915_FORMAT_MOD_Yf_TILED:
+		if (INTEL_INFO(dev)->gen < 9) {
+			DRM_DEBUG("Unsupported tiling 0x%llx!\n",
+				  mode_cmd->modifier[0]);
+			return -EINVAL;
+		}
+	case DRM_FORMAT_MOD_NONE:
+	case I915_FORMAT_MOD_X_TILED:
+		break;
+	default:
+		DRM_DEBUG("Unsupported fb modifier 0x%llx!\n",
+			  mode_cmd->modifier[0]);
+		return -EINVAL;
+	}
+
+	stride_alignment = intel_fb_stride_alignment(dev_priv,
+						     mode_cmd->modifier[0],
+						     mode_cmd->pixel_format);
+	if (mode_cmd->pitches[0] & (stride_alignment - 1)) {
+		DRM_DEBUG("pitch (%d) must be at least %u byte aligned\n",
+			  mode_cmd->pitches[0], stride_alignment);
+		return -EINVAL;
+	}
+
+	pitch_limit = intel_fb_pitch_limit(dev, mode_cmd->modifier[0],
+					   mode_cmd->pixel_format);
+	if (mode_cmd->pitches[0] > pitch_limit) {
+		DRM_DEBUG("%s pitch (%u) must be at less than %d\n",
+			  mode_cmd->modifier[0] != DRM_FORMAT_MOD_NONE ?
+			  "tiled" : "linear",
+			  mode_cmd->pitches[0], pitch_limit);
+		return -EINVAL;
+	}
+
+	if (mode_cmd->modifier[0] == I915_FORMAT_MOD_X_TILED &&
+	    mode_cmd->pitches[0] != obj->stride) {
+		DRM_DEBUG("pitch (%d) must match tiling stride (%d)\n",
+			  mode_cmd->pitches[0], obj->stride);
+		return -EINVAL;
+	}
+
+	/* Reject formats not supported by any plane early. */
+	switch (mode_cmd->pixel_format) {
+	case DRM_FORMAT_C8:
+	case DRM_FORMAT_RGB565:
+	case DRM_FORMAT_XRGB8888:
+	case DRM_FORMAT_ARGB8888:
+		break;
+	case DRM_FORMAT_XRGB1555:
+		if (INTEL_INFO(dev)->gen > 3) {
+			DRM_DEBUG("unsupported pixel format: %s\n",
+				  drm_get_format_name(mode_cmd->pixel_format));
+			return -EINVAL;
+		}
+		break;
+	case DRM_FORMAT_ABGR8888:
+		if (!IS_VALLEYVIEW(dev) && !IS_CHERRYVIEW(dev) &&
+		    INTEL_INFO(dev)->gen < 9) {
+			DRM_DEBUG("unsupported pixel format: %s\n",
+				  drm_get_format_name(mode_cmd->pixel_format));
+			return -EINVAL;
+		}
+		break;
+	case DRM_FORMAT_XBGR8888:
+	case DRM_FORMAT_XRGB2101010:
+	case DRM_FORMAT_XBGR2101010:
+		if (INTEL_INFO(dev)->gen < 4) {
+			DRM_DEBUG("unsupported pixel format: %s\n",
+				  drm_get_format_name(mode_cmd->pixel_format));
+			return -EINVAL;
+		}
+		break;
+	case DRM_FORMAT_ABGR2101010:
+		if (!IS_VALLEYVIEW(dev) && !IS_CHERRYVIEW(dev)) {
+			DRM_DEBUG("unsupported pixel format: %s\n",
+				  drm_get_format_name(mode_cmd->pixel_format));
+			return -EINVAL;
+		}
+		break;
+	case DRM_FORMAT_YUYV:
+	case DRM_FORMAT_UYVY:
+	case DRM_FORMAT_YVYU:
+	case DRM_FORMAT_VYUY:
+		if (INTEL_INFO(dev)->gen < 5) {
+			DRM_DEBUG("unsupported pixel format: %s\n",
+				  drm_get_format_name(mode_cmd->pixel_format));
+			return -EINVAL;
+		}
+		break;
+	default:
+		DRM_DEBUG("unsupported pixel format: %s\n",
+			  drm_get_format_name(mode_cmd->pixel_format));
+		return -EINVAL;
+	}
+
+	/* FIXME need to adjust LINOFF/TILEOFF accordingly. */
+	if (mode_cmd->offsets[0] != 0)
+		return -EINVAL;
+
+	aligned_height = intel_fb_align_height(dev, mode_cmd->height,
+					       mode_cmd->pixel_format,
+					       mode_cmd->modifier[0]);
+	/* FIXME drm helper for size checks (especially planar formats)? */
+	if (obj->base.size < aligned_height * mode_cmd->pitches[0])
+		return -EINVAL;
+
+	drm_helper_mode_fill_fb_struct(&intel_fb->base, mode_cmd);
+	intel_fb->obj = obj;
+
+	intel_fill_fb_info(dev_priv, &intel_fb->base);
+
+	ret = drm_framebuffer_init(dev, &intel_fb->base, &intel_fb_funcs);
+	if (ret) {
+		DRM_ERROR("framebuffer init failed %d\n", ret);
+		return ret;
+	}
+
+	intel_fb->obj->framebuffer_references++;
+
+	return 0;
+}
+
+static struct drm_framebuffer *
+intel_user_framebuffer_create(struct drm_device *dev,
+			      struct drm_file *filp,
+			      const struct drm_mode_fb_cmd2 *user_mode_cmd)
+{
+	struct drm_framebuffer *fb;
+	struct drm_i915_gem_object *obj;
+	struct drm_mode_fb_cmd2 mode_cmd = *user_mode_cmd;
+
+	obj = to_intel_bo(drm_gem_object_lookup(dev, filp,
+						mode_cmd.handles[0]));
+	if (&obj->base == NULL)
+		return ERR_PTR(-ENOENT);
+
+	fb = intel_framebuffer_create(dev, &mode_cmd, obj);
+	if (IS_ERR(fb))
+		drm_gem_object_unreference_unlocked(&obj->base);
+
+	return fb;
+}
+
+#ifndef CONFIG_DRM_FBDEV_EMULATION
+static inline void intel_fbdev_output_poll_changed(struct drm_device *dev)
+{
+}
+#endif
+
+static const struct drm_mode_config_funcs intel_mode_funcs = {
+	.fb_create = intel_user_framebuffer_create,
+	.output_poll_changed = intel_fbdev_output_poll_changed,
+	.atomic_check = intel_atomic_check,
+	.atomic_commit = intel_atomic_commit,
+	.atomic_state_alloc = intel_atomic_state_alloc,
+	.atomic_state_clear = intel_atomic_state_clear,
+};
+
+/**
+ * intel_init_display_hooks - initialize the display modesetting hooks
+ * @dev_priv: device private
+ */
+void intel_init_display_hooks(struct drm_i915_private *dev_priv)
+{
+	if (INTEL_INFO(dev_priv)->gen >= 9) {
+		dev_priv->display.get_pipe_config = haswell_get_pipe_config;
+		dev_priv->display.get_initial_plane_config =
+			skylake_get_initial_plane_config;
+		dev_priv->display.crtc_compute_clock =
+			haswell_crtc_compute_clock;
+		dev_priv->display.crtc_enable = haswell_crtc_enable;
+		dev_priv->display.crtc_disable = haswell_crtc_disable;
+	} else if (HAS_DDI(dev_priv)) {
+		dev_priv->display.get_pipe_config = haswell_get_pipe_config;
+		dev_priv->display.get_initial_plane_config =
+			ironlake_get_initial_plane_config;
+		dev_priv->display.crtc_compute_clock =
+			haswell_crtc_compute_clock;
+		dev_priv->display.crtc_enable = haswell_crtc_enable;
+		dev_priv->display.crtc_disable = haswell_crtc_disable;
+	} else if (HAS_PCH_SPLIT(dev_priv)) {
+		dev_priv->display.get_pipe_config = ironlake_get_pipe_config;
+		dev_priv->display.get_initial_plane_config =
+			ironlake_get_initial_plane_config;
+		dev_priv->display.crtc_compute_clock =
+			ironlake_crtc_compute_clock;
+		dev_priv->display.crtc_enable = ironlake_crtc_enable;
+		dev_priv->display.crtc_disable = ironlake_crtc_disable;
+	} else if (IS_CHERRYVIEW(dev_priv)) {
+		dev_priv->display.get_pipe_config = i9xx_get_pipe_config;
+		dev_priv->display.get_initial_plane_config =
+			i9xx_get_initial_plane_config;
+		dev_priv->display.crtc_compute_clock = chv_crtc_compute_clock;
+		dev_priv->display.crtc_enable = valleyview_crtc_enable;
+		dev_priv->display.crtc_disable = i9xx_crtc_disable;
+	} else if (IS_VALLEYVIEW(dev_priv)) {
+		dev_priv->display.get_pipe_config = i9xx_get_pipe_config;
+		dev_priv->display.get_initial_plane_config =
+			i9xx_get_initial_plane_config;
+		dev_priv->display.crtc_compute_clock = vlv_crtc_compute_clock;
+		dev_priv->display.crtc_enable = valleyview_crtc_enable;
+		dev_priv->display.crtc_disable = i9xx_crtc_disable;
+	} else if (IS_G4X(dev_priv)) {
+		dev_priv->display.get_pipe_config = i9xx_get_pipe_config;
+		dev_priv->display.get_initial_plane_config =
+			i9xx_get_initial_plane_config;
+		dev_priv->display.crtc_compute_clock = g4x_crtc_compute_clock;
+		dev_priv->display.crtc_enable = i9xx_crtc_enable;
+		dev_priv->display.crtc_disable = i9xx_crtc_disable;
+	} else if (IS_PINEVIEW(dev_priv)) {
+		dev_priv->display.get_pipe_config = i9xx_get_pipe_config;
+		dev_priv->display.get_initial_plane_config =
+			i9xx_get_initial_plane_config;
+		dev_priv->display.crtc_compute_clock = pnv_crtc_compute_clock;
+		dev_priv->display.crtc_enable = i9xx_crtc_enable;
+		dev_priv->display.crtc_disable = i9xx_crtc_disable;
+	} else if (!IS_GEN2(dev_priv)) {
+		dev_priv->display.get_pipe_config = i9xx_get_pipe_config;
+		dev_priv->display.get_initial_plane_config =
+			i9xx_get_initial_plane_config;
+		dev_priv->display.crtc_compute_clock = i9xx_crtc_compute_clock;
+		dev_priv->display.crtc_enable = i9xx_crtc_enable;
+		dev_priv->display.crtc_disable = i9xx_crtc_disable;
+	} else {
+		dev_priv->display.get_pipe_config = i9xx_get_pipe_config;
+		dev_priv->display.get_initial_plane_config =
+			i9xx_get_initial_plane_config;
+		dev_priv->display.crtc_compute_clock = i8xx_crtc_compute_clock;
+		dev_priv->display.crtc_enable = i9xx_crtc_enable;
+		dev_priv->display.crtc_disable = i9xx_crtc_disable;
+	}
+
+	/* Returns the core display clock speed */
+	if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv))
+		dev_priv->display.get_display_clock_speed =
+			skylake_get_display_clock_speed;
+	else if (IS_BROXTON(dev_priv))
+		dev_priv->display.get_display_clock_speed =
+			broxton_get_display_clock_speed;
+	else if (IS_BROADWELL(dev_priv))
+		dev_priv->display.get_display_clock_speed =
+			broadwell_get_display_clock_speed;
+	else if (IS_HASWELL(dev_priv))
+		dev_priv->display.get_display_clock_speed =
+			haswell_get_display_clock_speed;
+	else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
+		dev_priv->display.get_display_clock_speed =
+			valleyview_get_display_clock_speed;
+	else if (IS_GEN5(dev_priv))
+		dev_priv->display.get_display_clock_speed =
+			ilk_get_display_clock_speed;
+	else if (IS_I945G(dev_priv) || IS_BROADWATER(dev_priv) ||
+		 IS_GEN6(dev_priv) || IS_IVYBRIDGE(dev_priv))
+		dev_priv->display.get_display_clock_speed =
+			i945_get_display_clock_speed;
+	else if (IS_GM45(dev_priv))
+		dev_priv->display.get_display_clock_speed =
+			gm45_get_display_clock_speed;
+	else if (IS_CRESTLINE(dev_priv))
+		dev_priv->display.get_display_clock_speed =
+			i965gm_get_display_clock_speed;
+	else if (IS_PINEVIEW(dev_priv))
+		dev_priv->display.get_display_clock_speed =
+			pnv_get_display_clock_speed;
+	else if (IS_G33(dev_priv) || IS_G4X(dev_priv))
+		dev_priv->display.get_display_clock_speed =
+			g33_get_display_clock_speed;
+	else if (IS_I915G(dev_priv))
+		dev_priv->display.get_display_clock_speed =
+			i915_get_display_clock_speed;
+	else if (IS_I945GM(dev_priv) || IS_845G(dev_priv))
+		dev_priv->display.get_display_clock_speed =
+			i9xx_misc_get_display_clock_speed;
+	else if (IS_I915GM(dev_priv))
+		dev_priv->display.get_display_clock_speed =
+			i915gm_get_display_clock_speed;
+	else if (IS_I865G(dev_priv))
+		dev_priv->display.get_display_clock_speed =
+			i865_get_display_clock_speed;
+	else if (IS_I85X(dev_priv))
+		dev_priv->display.get_display_clock_speed =
+			i85x_get_display_clock_speed;
+	else { /* 830 */
+		WARN(!IS_I830(dev_priv), "Unknown platform. Assuming 133 MHz CDCLK\n");
+		dev_priv->display.get_display_clock_speed =
+			i830_get_display_clock_speed;
+	}
+
+	if (IS_GEN5(dev_priv)) {
+		dev_priv->display.fdi_link_train = ironlake_fdi_link_train;
+	} else if (IS_GEN6(dev_priv)) {
+		dev_priv->display.fdi_link_train = gen6_fdi_link_train;
+	} else if (IS_IVYBRIDGE(dev_priv)) {
+		/* FIXME: detect B0+ stepping and use auto training */
+		dev_priv->display.fdi_link_train = ivb_manual_fdi_link_train;
+	} else if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) {
+		dev_priv->display.fdi_link_train = hsw_fdi_link_train;
+		if (IS_BROADWELL(dev_priv)) {
+			dev_priv->display.modeset_commit_cdclk =
+				broadwell_modeset_commit_cdclk;
+			dev_priv->display.modeset_calc_cdclk =
+				broadwell_modeset_calc_cdclk;
+		}
+	} else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
+		dev_priv->display.modeset_commit_cdclk =
+			valleyview_modeset_commit_cdclk;
+		dev_priv->display.modeset_calc_cdclk =
+			valleyview_modeset_calc_cdclk;
+	} else if (IS_BROXTON(dev_priv)) {
+		dev_priv->display.modeset_commit_cdclk =
+			broxton_modeset_commit_cdclk;
+		dev_priv->display.modeset_calc_cdclk =
+			broxton_modeset_calc_cdclk;
+	}
+
+	switch (INTEL_INFO(dev_priv)->gen) {
+	case 2:
+		dev_priv->display.queue_flip = intel_gen2_queue_flip;
+		break;
+
+	case 3:
+		dev_priv->display.queue_flip = intel_gen3_queue_flip;
+		break;
+
+	case 4:
+	case 5:
+		dev_priv->display.queue_flip = intel_gen4_queue_flip;
+		break;
+
+	case 6:
+		dev_priv->display.queue_flip = intel_gen6_queue_flip;
+		break;
+	case 7:
+	case 8: /* FIXME(BDW): Check that the gen8 RCS flip works. */
+		dev_priv->display.queue_flip = intel_gen7_queue_flip;
+		break;
+	case 9:
+		/* Drop through - unsupported since execlist only. */
+	default:
+		/* Default just returns -ENODEV to indicate unsupported */
+		dev_priv->display.queue_flip = intel_default_queue_flip;
+	}
+}
+
+/*
+ * Some BIOSes insist on assuming the GPU's pipe A is enabled at suspend,
+ * resume, or other times.  This quirk makes sure that's the case for
+ * affected systems.
+ */
+static void quirk_pipea_force(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	dev_priv->quirks |= QUIRK_PIPEA_FORCE;
+	DRM_INFO("applying pipe a force quirk\n");
+}
+
+static void quirk_pipeb_force(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	dev_priv->quirks |= QUIRK_PIPEB_FORCE;
+	DRM_INFO("applying pipe b force quirk\n");
+}
+
+/*
+ * Some machines (Lenovo U160) do not work with SSC on LVDS for some reason
+ */
+static void quirk_ssc_force_disable(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	dev_priv->quirks |= QUIRK_LVDS_SSC_DISABLE;
+	DRM_INFO("applying lvds SSC disable quirk\n");
+}
+
+/*
+ * A machine (e.g. Acer Aspire 5734Z) may need to invert the panel backlight
+ * brightness value
+ */
+static void quirk_invert_brightness(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	dev_priv->quirks |= QUIRK_INVERT_BRIGHTNESS;
+	DRM_INFO("applying inverted panel brightness quirk\n");
+}
+
+/* Some VBT's incorrectly indicate no backlight is present */
+static void quirk_backlight_present(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	dev_priv->quirks |= QUIRK_BACKLIGHT_PRESENT;
+	DRM_INFO("applying backlight present quirk\n");
+}
+
+struct intel_quirk {
+	int device;
+	int subsystem_vendor;
+	int subsystem_device;
+	void (*hook)(struct drm_device *dev);
+};
+
+/* For systems that don't have a meaningful PCI subdevice/subvendor ID */
+struct intel_dmi_quirk {
+	void (*hook)(struct drm_device *dev);
+	const struct dmi_system_id (*dmi_id_list)[];
+};
+
+static int intel_dmi_reverse_brightness(const struct dmi_system_id *id)
+{
+	DRM_INFO("Backlight polarity reversed on %s\n", id->ident);
+	return 1;
+}
+
+static const struct intel_dmi_quirk intel_dmi_quirks[] = {
+	{
+		.dmi_id_list = &(const struct dmi_system_id[]) {
+			{
+				.callback = intel_dmi_reverse_brightness,
+				.ident = "NCR Corporation",
+				.matches = {DMI_MATCH(DMI_SYS_VENDOR, "NCR Corporation"),
+					    DMI_MATCH(DMI_PRODUCT_NAME, ""),
+				},
+			},
+			{ }  /* terminating entry */
+		},
+		.hook = quirk_invert_brightness,
+	},
+};
+
+static struct intel_quirk intel_quirks[] = {
+	/* Toshiba Protege R-205, S-209 needs pipe A force quirk */
+	{ 0x2592, 0x1179, 0x0001, quirk_pipea_force },
+
+	/* ThinkPad T60 needs pipe A force quirk (bug #16494) */
+	{ 0x2782, 0x17aa, 0x201a, quirk_pipea_force },
+
+	/* 830 needs to leave pipe A & dpll A up */
+	{ 0x3577, PCI_ANY_ID, PCI_ANY_ID, quirk_pipea_force },
+
+	/* 830 needs to leave pipe B & dpll B up */
+	{ 0x3577, PCI_ANY_ID, PCI_ANY_ID, quirk_pipeb_force },
+
+	/* Lenovo U160 cannot use SSC on LVDS */
+	{ 0x0046, 0x17aa, 0x3920, quirk_ssc_force_disable },
+
+	/* Sony Vaio Y cannot use SSC on LVDS */
+	{ 0x0046, 0x104d, 0x9076, quirk_ssc_force_disable },
+
+	/* Acer Aspire 5734Z must invert backlight brightness */
+	{ 0x2a42, 0x1025, 0x0459, quirk_invert_brightness },
+
+	/* Acer/eMachines G725 */
+	{ 0x2a42, 0x1025, 0x0210, quirk_invert_brightness },
+
+	/* Acer/eMachines e725 */
+	{ 0x2a42, 0x1025, 0x0212, quirk_invert_brightness },
+
+	/* Acer/Packard Bell NCL20 */
+	{ 0x2a42, 0x1025, 0x034b, quirk_invert_brightness },
+
+	/* Acer Aspire 4736Z */
+	{ 0x2a42, 0x1025, 0x0260, quirk_invert_brightness },
+
+	/* Acer Aspire 5336 */
+	{ 0x2a42, 0x1025, 0x048a, quirk_invert_brightness },
+
+	/* Acer C720 and C720P Chromebooks (Celeron 2955U) have backlights */
+	{ 0x0a06, 0x1025, 0x0a11, quirk_backlight_present },
+
+	/* Acer C720 Chromebook (Core i3 4005U) */
+	{ 0x0a16, 0x1025, 0x0a11, quirk_backlight_present },
+
+	/* Apple Macbook 2,1 (Core 2 T7400) */
+	{ 0x27a2, 0x8086, 0x7270, quirk_backlight_present },
+
+	/* Apple Macbook 4,1 */
+	{ 0x2a02, 0x106b, 0x00a1, quirk_backlight_present },
+
+	/* Toshiba CB35 Chromebook (Celeron 2955U) */
+	{ 0x0a06, 0x1179, 0x0a88, quirk_backlight_present },
+
+	/* HP Chromebook 14 (Celeron 2955U) */
+	{ 0x0a06, 0x103c, 0x21ed, quirk_backlight_present },
+
+	/* Dell Chromebook 11 */
+	{ 0x0a06, 0x1028, 0x0a35, quirk_backlight_present },
+
+	/* Dell Chromebook 11 (2015 version) */
+	{ 0x0a16, 0x1028, 0x0a35, quirk_backlight_present },
+};
+
+static void intel_init_quirks(struct drm_device *dev)
+{
+	struct pci_dev *d = dev->pdev;
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(intel_quirks); i++) {
+		struct intel_quirk *q = &intel_quirks[i];
+
+		if (d->device == q->device &&
+		    (d->subsystem_vendor == q->subsystem_vendor ||
+		     q->subsystem_vendor == PCI_ANY_ID) &&
+		    (d->subsystem_device == q->subsystem_device ||
+		     q->subsystem_device == PCI_ANY_ID))
+			q->hook(dev);
+	}
+	for (i = 0; i < ARRAY_SIZE(intel_dmi_quirks); i++) {
+		if (dmi_check_system(*intel_dmi_quirks[i].dmi_id_list) != 0)
+			intel_dmi_quirks[i].hook(dev);
+	}
+}
+
+/* Disable the VGA plane that we never use */
+static void i915_disable_vga(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	u8 sr1;
+	i915_reg_t vga_reg = i915_vgacntrl_reg(dev);
+
+	/* WaEnableVGAAccessThroughIOPort:ctg,elk,ilk,snb,ivb,vlv,hsw */
+	vga_get_uninterruptible(dev->pdev, VGA_RSRC_LEGACY_IO);
+	outb(SR01, VGA_SR_INDEX);
+	sr1 = inb(VGA_SR_DATA);
+	outb(sr1 | 1<<5, VGA_SR_DATA);
+	vga_put(dev->pdev, VGA_RSRC_LEGACY_IO);
+	udelay(300);
+
+	I915_WRITE(vga_reg, VGA_DISP_DISABLE);
+	POSTING_READ(vga_reg);
+}
+
+void intel_modeset_init_hw(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	intel_update_cdclk(dev);
+
+	dev_priv->atomic_cdclk_freq = dev_priv->cdclk_freq;
+
+	intel_init_clock_gating(dev);
+	intel_enable_gt_powersave(dev);
+}
+
+/*
+ * Calculate what we think the watermarks should be for the state we've read
+ * out of the hardware and then immediately program those watermarks so that
+ * we ensure the hardware settings match our internal state.
+ *
+ * We can calculate what we think WM's should be by creating a duplicate of the
+ * current state (which was constructed during hardware readout) and running it
+ * through the atomic check code to calculate new watermark values in the
+ * state object.
+ */
+static void sanitize_watermarks(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = to_i915(dev);
+	struct drm_atomic_state *state;
+	struct drm_crtc *crtc;
+	struct drm_crtc_state *cstate;
+	struct drm_modeset_acquire_ctx ctx;
+	int ret;
+	int i;
+
+	/* Only supported on platforms that use atomic watermark design */
+	if (!dev_priv->display.optimize_watermarks)
+		return;
+
+	/*
+	 * We need to hold connection_mutex before calling duplicate_state so
+	 * that the connector loop is protected.
+	 */
+	drm_modeset_acquire_init(&ctx, 0);
+retry:
+	ret = drm_modeset_lock_all_ctx(dev, &ctx);
+	if (ret == -EDEADLK) {
+		drm_modeset_backoff(&ctx);
+		goto retry;
+	} else if (WARN_ON(ret)) {
+		goto fail;
+	}
+
+	state = drm_atomic_helper_duplicate_state(dev, &ctx);
+	if (WARN_ON(IS_ERR(state)))
+		goto fail;
+
+	/*
+	 * Hardware readout is the only time we don't want to calculate
+	 * intermediate watermarks (since we don't trust the current
+	 * watermarks).
+	 */
+	to_intel_atomic_state(state)->skip_intermediate_wm = true;
+
+	ret = intel_atomic_check(dev, state);
+	if (ret) {
+		/*
+		 * If we fail here, it means that the hardware appears to be
+		 * programmed in a way that shouldn't be possible, given our
+		 * understanding of watermark requirements.  This might mean a
+		 * mistake in the hardware readout code or a mistake in the
+		 * watermark calculations for a given platform.  Raise a WARN
+		 * so that this is noticeable.
+		 *
+		 * If this actually happens, we'll have to just leave the
+		 * BIOS-programmed watermarks untouched and hope for the best.
+		 */
+		WARN(true, "Could not determine valid watermarks for inherited state\n");
+		goto fail;
+	}
+
+	/* Write calculated watermark values back */
+	to_i915(dev)->wm.config = to_intel_atomic_state(state)->wm_config;
+	for_each_crtc_in_state(state, crtc, cstate, i) {
+		struct intel_crtc_state *cs = to_intel_crtc_state(cstate);
+
+		cs->wm.need_postvbl_update = true;
+		dev_priv->display.optimize_watermarks(cs);
+	}
+
+	drm_atomic_state_free(state);
+fail:
+	drm_modeset_drop_locks(&ctx);
+	drm_modeset_acquire_fini(&ctx);
+}
+
+void intel_modeset_init(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = to_i915(dev);
+	struct i915_ggtt *ggtt = &dev_priv->ggtt;
+	int sprite, ret;
+	enum pipe pipe;
+	struct intel_crtc *crtc;
+
+	drm_mode_config_init(dev);
+
+	dev->mode_config.min_width = 0;
+	dev->mode_config.min_height = 0;
+
+	dev->mode_config.preferred_depth = 24;
+	dev->mode_config.prefer_shadow = 1;
+
+	dev->mode_config.allow_fb_modifiers = true;
+
+	dev->mode_config.funcs = &intel_mode_funcs;
+
+	intel_init_quirks(dev);
+
+	intel_init_pm(dev);
+
+	if (INTEL_INFO(dev)->num_pipes == 0)
+		return;
+
+	/*
+	 * There may be no VBT; and if the BIOS enabled SSC we can
+	 * just keep using it to avoid unnecessary flicker.  Whereas if the
+	 * BIOS isn't using it, don't assume it will work even if the VBT
+	 * indicates as much.
+	 */
+	if (HAS_PCH_IBX(dev) || HAS_PCH_CPT(dev)) {
+		bool bios_lvds_use_ssc = !!(I915_READ(PCH_DREF_CONTROL) &
+					    DREF_SSC1_ENABLE);
+
+		if (dev_priv->vbt.lvds_use_ssc != bios_lvds_use_ssc) {
+			DRM_DEBUG_KMS("SSC %sabled by BIOS, overriding VBT which says %sabled\n",
+				     bios_lvds_use_ssc ? "en" : "dis",
+				     dev_priv->vbt.lvds_use_ssc ? "en" : "dis");
+			dev_priv->vbt.lvds_use_ssc = bios_lvds_use_ssc;
+		}
+	}
+
+	if (IS_GEN2(dev)) {
+		dev->mode_config.max_width = 2048;
+		dev->mode_config.max_height = 2048;
+	} else if (IS_GEN3(dev)) {
+		dev->mode_config.max_width = 4096;
+		dev->mode_config.max_height = 4096;
+	} else {
+		dev->mode_config.max_width = 8192;
+		dev->mode_config.max_height = 8192;
+	}
+
+	if (IS_845G(dev) || IS_I865G(dev)) {
+		dev->mode_config.cursor_width = IS_845G(dev) ? 64 : 512;
+		dev->mode_config.cursor_height = 1023;
+	} else if (IS_GEN2(dev)) {
+		dev->mode_config.cursor_width = GEN2_CURSOR_WIDTH;
+		dev->mode_config.cursor_height = GEN2_CURSOR_HEIGHT;
+	} else {
+		dev->mode_config.cursor_width = MAX_CURSOR_WIDTH;
+		dev->mode_config.cursor_height = MAX_CURSOR_HEIGHT;
+	}
+
+	dev->mode_config.fb_base = ggtt->mappable_base;
+
+	DRM_DEBUG_KMS("%d display pipe%s available.\n",
+		      INTEL_INFO(dev)->num_pipes,
+		      INTEL_INFO(dev)->num_pipes > 1 ? "s" : "");
+
+	for_each_pipe(dev_priv, pipe) {
+		intel_crtc_init(dev, pipe);
+		for_each_sprite(dev_priv, pipe, sprite) {
+			ret = intel_plane_init(dev, pipe, sprite);
+			if (ret)
+				DRM_DEBUG_KMS("pipe %c sprite %c init failed: %d\n",
+					      pipe_name(pipe), sprite_name(pipe, sprite), ret);
+		}
+	}
+
+	intel_update_czclk(dev_priv);
+	intel_update_rawclk(dev_priv);
+	intel_update_cdclk(dev);
+
+	intel_shared_dpll_init(dev);
+
+	/* Just disable it once at startup */
+	i915_disable_vga(dev);
+	intel_setup_outputs(dev);
+
+	drm_modeset_lock_all(dev);
+	intel_modeset_setup_hw_state(dev);
+	drm_modeset_unlock_all(dev);
+
+	for_each_intel_crtc(dev, crtc) {
+		struct intel_initial_plane_config plane_config = {};
+
+		if (!crtc->active)
+			continue;
+
+		/*
+		 * Note that reserving the BIOS fb up front prevents us
+		 * from stuffing other stolen allocations like the ring
+		 * on top.  This prevents some ugliness at boot time, and
+		 * can even allow for smooth boot transitions if the BIOS
+		 * fb is large enough for the active pipe configuration.
+		 */
+		dev_priv->display.get_initial_plane_config(crtc,
+							   &plane_config);
+
+		/*
+		 * If the fb is shared between multiple heads, we'll
+		 * just get the first one.
+		 */
+		intel_find_initial_plane_obj(crtc, &plane_config);
+	}
+
+	/*
+	 * Make sure hardware watermarks really match the state we read out.
+	 * Note that we need to do this after reconstructing the BIOS fb's
+	 * since the watermark calculation done here will use pstate->fb.
+	 */
+	sanitize_watermarks(dev);
+}
+
+static void intel_enable_pipe_a(struct drm_device *dev)
+{
+	struct intel_connector *connector;
+	struct drm_connector *crt = NULL;
+	struct intel_load_detect_pipe load_detect_temp;
+	struct drm_modeset_acquire_ctx *ctx = dev->mode_config.acquire_ctx;
+
+	/* We can't just switch on the pipe A, we need to set things up with a
+	 * proper mode and output configuration. As a gross hack, enable pipe A
+	 * by enabling the load detect pipe once. */
+	for_each_intel_connector(dev, connector) {
+		if (connector->encoder->type == INTEL_OUTPUT_ANALOG) {
+			crt = &connector->base;
+			break;
+		}
+	}
+
+	if (!crt)
+		return;
+
+	if (intel_get_load_detect_pipe(crt, NULL, &load_detect_temp, ctx))
+		intel_release_load_detect_pipe(crt, &load_detect_temp, ctx);
+}
+
+static bool
+intel_check_plane_mapping(struct intel_crtc *crtc)
+{
+	struct drm_device *dev = crtc->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	u32 val;
+
+	if (INTEL_INFO(dev)->num_pipes == 1)
+		return true;
+
+	val = I915_READ(DSPCNTR(!crtc->plane));
+
+	if ((val & DISPLAY_PLANE_ENABLE) &&
+	    (!!(val & DISPPLANE_SEL_PIPE_MASK) == crtc->pipe))
+		return false;
+
+	return true;
+}
+
+static bool intel_crtc_has_encoders(struct intel_crtc *crtc)
+{
+	struct drm_device *dev = crtc->base.dev;
+	struct intel_encoder *encoder;
+
+	for_each_encoder_on_crtc(dev, &crtc->base, encoder)
+		return true;
+
+	return false;
+}
+
+static bool intel_encoder_has_connectors(struct intel_encoder *encoder)
+{
+	struct drm_device *dev = encoder->base.dev;
+	struct intel_connector *connector;
+
+	for_each_connector_on_encoder(dev, &encoder->base, connector)
+		return true;
+
+	return false;
+}
+
+static void intel_sanitize_crtc(struct intel_crtc *crtc)
+{
+	struct drm_device *dev = crtc->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	enum transcoder cpu_transcoder = crtc->config->cpu_transcoder;
+
+	/* Clear any frame start delays used for debugging left by the BIOS */
+	if (!transcoder_is_dsi(cpu_transcoder)) {
+		i915_reg_t reg = PIPECONF(cpu_transcoder);
+
+		I915_WRITE(reg,
+			   I915_READ(reg) & ~PIPECONF_FRAME_START_DELAY_MASK);
+	}
+
+	/* restore vblank interrupts to correct state */
+	drm_crtc_vblank_reset(&crtc->base);
+	if (crtc->active) {
+		struct intel_plane *plane;
+
+		drm_crtc_vblank_on(&crtc->base);
+
+		/* Disable everything but the primary plane */
+		for_each_intel_plane_on_crtc(dev, crtc, plane) {
+			if (plane->base.type == DRM_PLANE_TYPE_PRIMARY)
+				continue;
+
+			plane->disable_plane(&plane->base, &crtc->base);
+		}
+	}
+
+	/* We need to sanitize the plane -> pipe mapping first because this will
+	 * disable the crtc (and hence change the state) if it is wrong. Note
+	 * that gen4+ has a fixed plane -> pipe mapping.  */
+	if (INTEL_INFO(dev)->gen < 4 && !intel_check_plane_mapping(crtc)) {
+		bool plane;
+
+		DRM_DEBUG_KMS("[CRTC:%d] wrong plane connection detected!\n",
+			      crtc->base.base.id);
+
+		/* Pipe has the wrong plane attached and the plane is active.
+		 * Temporarily change the plane mapping and disable everything
+		 * ...  */
+		plane = crtc->plane;
+		to_intel_plane_state(crtc->base.primary->state)->visible = true;
+		crtc->plane = !plane;
+		intel_crtc_disable_noatomic(&crtc->base);
+		crtc->plane = plane;
+	}
+
+	if (dev_priv->quirks & QUIRK_PIPEA_FORCE &&
+	    crtc->pipe == PIPE_A && !crtc->active) {
+		/* BIOS forgot to enable pipe A, this mostly happens after
+		 * resume. Force-enable the pipe to fix this, the update_dpms
+		 * call below we restore the pipe to the right state, but leave
+		 * the required bits on. */
+		intel_enable_pipe_a(dev);
+	}
+
+	/* Adjust the state of the output pipe according to whether we
+	 * have active connectors/encoders. */
+	if (crtc->active && !intel_crtc_has_encoders(crtc))
+		intel_crtc_disable_noatomic(&crtc->base);
+
+	if (crtc->active || HAS_GMCH_DISPLAY(dev)) {
+		/*
+		 * We start out with underrun reporting disabled to avoid races.
+		 * For correct bookkeeping mark this on active crtcs.
+		 *
+		 * Also on gmch platforms we dont have any hardware bits to
+		 * disable the underrun reporting. Which means we need to start
+		 * out with underrun reporting disabled also on inactive pipes,
+		 * since otherwise we'll complain about the garbage we read when
+		 * e.g. coming up after runtime pm.
+		 *
+		 * No protection against concurrent access is required - at
+		 * worst a fifo underrun happens which also sets this to false.
+		 */
+		crtc->cpu_fifo_underrun_disabled = true;
+		crtc->pch_fifo_underrun_disabled = true;
+	}
+}
+
+static void intel_sanitize_encoder(struct intel_encoder *encoder)
+{
+	struct intel_connector *connector;
+	struct drm_device *dev = encoder->base.dev;
+
+	/* We need to check both for a crtc link (meaning that the
+	 * encoder is active and trying to read from a pipe) and the
+	 * pipe itself being active. */
+	bool has_active_crtc = encoder->base.crtc &&
+		to_intel_crtc(encoder->base.crtc)->active;
+
+	if (intel_encoder_has_connectors(encoder) && !has_active_crtc) {
+		DRM_DEBUG_KMS("[ENCODER:%d:%s] has active connectors but no active pipe!\n",
+			      encoder->base.base.id,
+			      encoder->base.name);
+
+		/* Connector is active, but has no active pipe. This is
+		 * fallout from our resume register restoring. Disable
+		 * the encoder manually again. */
+		if (encoder->base.crtc) {
+			DRM_DEBUG_KMS("[ENCODER:%d:%s] manually disabled\n",
+				      encoder->base.base.id,
+				      encoder->base.name);
+			encoder->disable(encoder);
+			if (encoder->post_disable)
+				encoder->post_disable(encoder);
+		}
+		encoder->base.crtc = NULL;
+
+		/* Inconsistent output/port/pipe state happens presumably due to
+		 * a bug in one of the get_hw_state functions. Or someplace else
+		 * in our code, like the register restore mess on resume. Clamp
+		 * things to off as a safer default. */
+		for_each_intel_connector(dev, connector) {
+			if (connector->encoder != encoder)
+				continue;
+			connector->base.dpms = DRM_MODE_DPMS_OFF;
+			connector->base.encoder = NULL;
+		}
+	}
+	/* Enabled encoders without active connectors will be fixed in
+	 * the crtc fixup. */
+}
+
+void i915_redisable_vga_power_on(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	i915_reg_t vga_reg = i915_vgacntrl_reg(dev);
+
+	if (!(I915_READ(vga_reg) & VGA_DISP_DISABLE)) {
+		DRM_DEBUG_KMS("Something enabled VGA plane, disabling it\n");
+		i915_disable_vga(dev);
+	}
+}
+
+void i915_redisable_vga(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	/* This function can be called both from intel_modeset_setup_hw_state or
+	 * at a very early point in our resume sequence, where the power well
+	 * structures are not yet restored. Since this function is at a very
+	 * paranoid "someone might have enabled VGA while we were not looking"
+	 * level, just check if the power well is enabled instead of trying to
+	 * follow the "don't touch the power well if we don't need it" policy
+	 * the rest of the driver uses. */
+	if (!intel_display_power_get_if_enabled(dev_priv, POWER_DOMAIN_VGA))
+		return;
+
+	i915_redisable_vga_power_on(dev);
+
+	intel_display_power_put(dev_priv, POWER_DOMAIN_VGA);
+}
+
+static bool primary_get_hw_state(struct intel_plane *plane)
+{
+	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
+
+	return I915_READ(DSPCNTR(plane->plane)) & DISPLAY_PLANE_ENABLE;
+}
+
+/* FIXME read out full plane state for all planes */
+static void readout_plane_state(struct intel_crtc *crtc)
+{
+	struct drm_plane *primary = crtc->base.primary;
+	struct intel_plane_state *plane_state =
+		to_intel_plane_state(primary->state);
+
+	plane_state->visible = crtc->active &&
+		primary_get_hw_state(to_intel_plane(primary));
+
+	if (plane_state->visible)
+		crtc->base.state->plane_mask |= 1 << drm_plane_index(primary);
+}
+
+static void intel_modeset_readout_hw_state(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	enum pipe pipe;
+	struct intel_crtc *crtc;
+	struct intel_encoder *encoder;
+	struct intel_connector *connector;
+	int i;
+
+	dev_priv->active_crtcs = 0;
+
+	for_each_intel_crtc(dev, crtc) {
+		struct intel_crtc_state *crtc_state = crtc->config;
+		int pixclk = 0;
+
+		__drm_atomic_helper_crtc_destroy_state(&crtc->base, &crtc_state->base);
+		memset(crtc_state, 0, sizeof(*crtc_state));
+		crtc_state->base.crtc = &crtc->base;
+
+		crtc_state->base.active = crtc_state->base.enable =
+			dev_priv->display.get_pipe_config(crtc, crtc_state);
+
+		crtc->base.enabled = crtc_state->base.enable;
+		crtc->active = crtc_state->base.active;
+
+		if (crtc_state->base.active) {
+			dev_priv->active_crtcs |= 1 << crtc->pipe;
+
+			if (IS_BROADWELL(dev_priv)) {
+				pixclk = ilk_pipe_pixel_rate(crtc_state);
+
+				/* pixel rate mustn't exceed 95% of cdclk with IPS on BDW */
+				if (crtc_state->ips_enabled)
+					pixclk = DIV_ROUND_UP(pixclk * 100, 95);
+			} else if (IS_VALLEYVIEW(dev_priv) ||
+				   IS_CHERRYVIEW(dev_priv) ||
+				   IS_BROXTON(dev_priv))
+				pixclk = crtc_state->base.adjusted_mode.crtc_clock;
+			else
+				WARN_ON(dev_priv->display.modeset_calc_cdclk);
+		}
+
+		dev_priv->min_pixclk[crtc->pipe] = pixclk;
+
+		readout_plane_state(crtc);
+
+		DRM_DEBUG_KMS("[CRTC:%d] hw state readout: %s\n",
+			      crtc->base.base.id,
+			      crtc->active ? "enabled" : "disabled");
+	}
+
+	for (i = 0; i < dev_priv->num_shared_dpll; i++) {
+		struct intel_shared_dpll *pll = &dev_priv->shared_dplls[i];
+
+		pll->on = pll->funcs.get_hw_state(dev_priv, pll,
+						  &pll->config.hw_state);
+		pll->config.crtc_mask = 0;
+		for_each_intel_crtc(dev, crtc) {
+			if (crtc->active && crtc->config->shared_dpll == pll)
+				pll->config.crtc_mask |= 1 << crtc->pipe;
+		}
+		pll->active_mask = pll->config.crtc_mask;
+
+		DRM_DEBUG_KMS("%s hw state readout: crtc_mask 0x%08x, on %i\n",
+			      pll->name, pll->config.crtc_mask, pll->on);
+	}
+
+	for_each_intel_encoder(dev, encoder) {
+		pipe = 0;
+
+		if (encoder->get_hw_state(encoder, &pipe)) {
+			crtc = to_intel_crtc(dev_priv->pipe_to_crtc_mapping[pipe]);
+			encoder->base.crtc = &crtc->base;
+			encoder->get_config(encoder, crtc->config);
+		} else {
+			encoder->base.crtc = NULL;
+		}
+
+		DRM_DEBUG_KMS("[ENCODER:%d:%s] hw state readout: %s, pipe %c\n",
+			      encoder->base.base.id,
+			      encoder->base.name,
+			      encoder->base.crtc ? "enabled" : "disabled",
+			      pipe_name(pipe));
+	}
+
+	for_each_intel_connector(dev, connector) {
+		if (connector->get_hw_state(connector)) {
+			connector->base.dpms = DRM_MODE_DPMS_ON;
+
+			encoder = connector->encoder;
+			connector->base.encoder = &encoder->base;
+
+			if (encoder->base.crtc &&
+			    encoder->base.crtc->state->active) {
+				/*
+				 * This has to be done during hardware readout
+				 * because anything calling .crtc_disable may
+				 * rely on the connector_mask being accurate.
+				 */
+				encoder->base.crtc->state->connector_mask |=
+					1 << drm_connector_index(&connector->base);
+				encoder->base.crtc->state->encoder_mask |=
+					1 << drm_encoder_index(&encoder->base);
+			}
+
+		} else {
+			connector->base.dpms = DRM_MODE_DPMS_OFF;
+			connector->base.encoder = NULL;
+		}
+		DRM_DEBUG_KMS("[CONNECTOR:%d:%s] hw state readout: %s\n",
+			      connector->base.base.id,
+			      connector->base.name,
+			      connector->base.encoder ? "enabled" : "disabled");
+	}
+
+	for_each_intel_crtc(dev, crtc) {
+		crtc->base.hwmode = crtc->config->base.adjusted_mode;
+
+		memset(&crtc->base.mode, 0, sizeof(crtc->base.mode));
+		if (crtc->base.state->active) {
+			intel_mode_from_pipe_config(&crtc->base.mode, crtc->config);
+			intel_mode_from_pipe_config(&crtc->base.state->adjusted_mode, crtc->config);
+			WARN_ON(drm_atomic_set_mode_for_crtc(crtc->base.state, &crtc->base.mode));
+
+			/*
+			 * The initial mode needs to be set in order to keep
+			 * the atomic core happy. It wants a valid mode if the
+			 * crtc's enabled, so we do the above call.
+			 *
+			 * At this point some state updated by the connectors
+			 * in their ->detect() callback has not run yet, so
+			 * no recalculation can be done yet.
+			 *
+			 * Even if we could do a recalculation and modeset
+			 * right now it would cause a double modeset if
+			 * fbdev or userspace chooses a different initial mode.
+			 *
+			 * If that happens, someone indicated they wanted a
+			 * mode change, which means it's safe to do a full
+			 * recalculation.
+			 */
+			crtc->base.state->mode.private_flags = I915_MODE_FLAG_INHERITED;
+
+			drm_calc_timestamping_constants(&crtc->base, &crtc->base.hwmode);
+			update_scanline_offset(crtc);
+		}
+
+		intel_pipe_config_sanity_check(dev_priv, crtc->config);
+	}
+}
+
+/* Scan out the current hw modeset state,
+ * and sanitizes it to the current state
+ */
+static void
+intel_modeset_setup_hw_state(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	enum pipe pipe;
+	struct intel_crtc *crtc;
+	struct intel_encoder *encoder;
+	int i;
+
+	intel_modeset_readout_hw_state(dev);
+
+	/* HW state is read out, now we need to sanitize this mess. */
+	for_each_intel_encoder(dev, encoder) {
+		intel_sanitize_encoder(encoder);
+	}
+
+	for_each_pipe(dev_priv, pipe) {
+		crtc = to_intel_crtc(dev_priv->pipe_to_crtc_mapping[pipe]);
+		intel_sanitize_crtc(crtc);
+		intel_dump_pipe_config(crtc, crtc->config,
+				       "[setup_hw_state]");
+	}
+
+	intel_modeset_update_connector_atomic_state(dev);
+
+	for (i = 0; i < dev_priv->num_shared_dpll; i++) {
+		struct intel_shared_dpll *pll = &dev_priv->shared_dplls[i];
+
+		if (!pll->on || pll->active_mask)
+			continue;
+
+		DRM_DEBUG_KMS("%s enabled but not in use, disabling\n", pll->name);
+
+		pll->funcs.disable(dev_priv, pll);
+		pll->on = false;
+	}
+
+	if (IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev))
+		vlv_wm_get_hw_state(dev);
+	else if (IS_GEN9(dev))
+		skl_wm_get_hw_state(dev);
+	else if (HAS_PCH_SPLIT(dev))
+		ilk_wm_get_hw_state(dev);
+
+	for_each_intel_crtc(dev, crtc) {
+		unsigned long put_domains;
+
+		put_domains = modeset_get_crtc_power_domains(&crtc->base, crtc->config);
+		if (WARN_ON(put_domains))
+			modeset_put_power_domains(dev_priv, put_domains);
+	}
+	intel_display_set_init_power(dev_priv, false);
+
+	intel_fbc_init_pipe_state(dev_priv);
+}
+
+void intel_display_resume(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = to_i915(dev);
+	struct drm_atomic_state *state = dev_priv->modeset_restore_state;
+	struct drm_modeset_acquire_ctx ctx;
+	int ret;
+	bool setup = false;
+
+	dev_priv->modeset_restore_state = NULL;
+
+	/*
+	 * This is a cludge because with real atomic modeset mode_config.mutex
+	 * won't be taken. Unfortunately some probed state like
+	 * audio_codec_enable is still protected by mode_config.mutex, so lock
+	 * it here for now.
+	 */
+	mutex_lock(&dev->mode_config.mutex);
+	drm_modeset_acquire_init(&ctx, 0);
+
+retry:
+	ret = drm_modeset_lock_all_ctx(dev, &ctx);
+
+	if (ret == 0 && !setup) {
+		setup = true;
+
+		intel_modeset_setup_hw_state(dev);
+		i915_redisable_vga(dev);
+	}
+
+	if (ret == 0 && state) {
+		struct drm_crtc_state *crtc_state;
+		struct drm_crtc *crtc;
+		int i;
+
+		state->acquire_ctx = &ctx;
+
+		/* ignore any reset values/BIOS leftovers in the WM registers */
+		to_intel_atomic_state(state)->skip_intermediate_wm = true;
+
+		for_each_crtc_in_state(state, crtc, crtc_state, i) {
+			/*
+			 * Force recalculation even if we restore
+			 * current state. With fast modeset this may not result
+			 * in a modeset when the state is compatible.
+			 */
+			crtc_state->mode_changed = true;
+		}
+
+		ret = drm_atomic_commit(state);
+	}
+
+	if (ret == -EDEADLK) {
+		drm_modeset_backoff(&ctx);
+		goto retry;
+	}
+
+	drm_modeset_drop_locks(&ctx);
+	drm_modeset_acquire_fini(&ctx);
+	mutex_unlock(&dev->mode_config.mutex);
+
+	if (ret) {
+		DRM_ERROR("Restoring old state failed with %i\n", ret);
+		drm_atomic_state_free(state);
+	}
+}
+
+void intel_modeset_gem_init(struct drm_device *dev)
+{
+	struct drm_crtc *c;
+	struct drm_i915_gem_object *obj;
+	int ret;
+
+	intel_init_gt_powersave(dev);
+
+	intel_modeset_init_hw(dev);
+
+	intel_setup_overlay(dev);
+
+	/*
+	 * Make sure any fbs we allocated at startup are properly
+	 * pinned & fenced.  When we do the allocation it's too early
+	 * for this.
+	 */
+	for_each_crtc(dev, c) {
+		obj = intel_fb_obj(c->primary->fb);
+		if (obj == NULL)
+			continue;
+
+		mutex_lock(&dev->struct_mutex);
+		ret = intel_pin_and_fence_fb_obj(c->primary->fb,
+						 c->primary->state->rotation);
+		mutex_unlock(&dev->struct_mutex);
+		if (ret) {
+			DRM_ERROR("failed to pin boot fb on pipe %d\n",
+				  to_intel_crtc(c)->pipe);
+			drm_framebuffer_unreference(c->primary->fb);
+			c->primary->fb = NULL;
+			c->primary->crtc = c->primary->state->crtc = NULL;
+			update_state_fb(c->primary);
+			c->state->plane_mask &= ~(1 << drm_plane_index(c->primary));
+		}
+	}
+
+	intel_backlight_register(dev);
+}
+
+void intel_connector_unregister(struct intel_connector *intel_connector)
+{
+	struct drm_connector *connector = &intel_connector->base;
+
+	intel_panel_destroy_backlight(connector);
+	drm_connector_unregister(connector);
+}
+
+void intel_modeset_cleanup(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_connector *connector;
+
+	intel_disable_gt_powersave(dev);
+
+	intel_backlight_unregister(dev);
+
+	/*
+	 * Interrupts and polling as the first thing to avoid creating havoc.
+	 * Too much stuff here (turning of connectors, ...) would
+	 * experience fancy races otherwise.
+	 */
+	intel_irq_uninstall(dev_priv);
+
+	/*
+	 * Due to the hpd irq storm handling the hotplug work can re-arm the
+	 * poll handlers. Hence disable polling after hpd handling is shut down.
+	 */
+	drm_kms_helper_poll_fini(dev);
+
+	intel_unregister_dsm_handler();
+
+	intel_fbc_global_disable(dev_priv);
+
+	/* flush any delayed tasks or pending work */
+	flush_scheduled_work();
+
+	/* destroy the backlight and sysfs files before encoders/connectors */
+	for_each_intel_connector(dev, connector)
+		connector->unregister(connector);
+
+	drm_mode_config_cleanup(dev);
+
+	intel_cleanup_overlay(dev);
+
+	intel_cleanup_gt_powersave(dev);
+
+	intel_teardown_gmbus(dev);
+}
+
+/*
+ * Return which encoder is currently attached for connector.
+ */
+struct drm_encoder *intel_best_encoder(struct drm_connector *connector)
+{
+	return &intel_attached_encoder(connector)->base;
+}
+
+void intel_connector_attach_encoder(struct intel_connector *connector,
+				    struct intel_encoder *encoder)
+{
+	connector->encoder = encoder;
+	drm_mode_connector_attach_encoder(&connector->base,
+					  &encoder->base);
+}
+
+/*
+ * set vga decode state - true == enable VGA decode
+ */
+int intel_modeset_vga_set_state(struct drm_device *dev, bool state)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	unsigned reg = INTEL_INFO(dev)->gen >= 6 ? SNB_GMCH_CTRL : INTEL_GMCH_CTRL;
+	u16 gmch_ctrl;
+
+	if (pci_read_config_word(dev_priv->bridge_dev, reg, &gmch_ctrl)) {
+		DRM_ERROR("failed to read control word\n");
+		return -EIO;
+	}
+
+	if (!!(gmch_ctrl & INTEL_GMCH_VGA_DISABLE) == !state)
+		return 0;
+
+	if (state)
+		gmch_ctrl &= ~INTEL_GMCH_VGA_DISABLE;
+	else
+		gmch_ctrl |= INTEL_GMCH_VGA_DISABLE;
+
+	if (pci_write_config_word(dev_priv->bridge_dev, reg, gmch_ctrl)) {
+		DRM_ERROR("failed to write control word\n");
+		return -EIO;
+	}
+
+	return 0;
+}
+
+struct intel_display_error_state {
+
+	u32 power_well_driver;
+
+	int num_transcoders;
+
+	struct intel_cursor_error_state {
+		u32 control;
+		u32 position;
+		u32 base;
+		u32 size;
+	} cursor[I915_MAX_PIPES];
+
+	struct intel_pipe_error_state {
+		bool power_domain_on;
+		u32 source;
+		u32 stat;
+	} pipe[I915_MAX_PIPES];
+
+	struct intel_plane_error_state {
+		u32 control;
+		u32 stride;
+		u32 size;
+		u32 pos;
+		u32 addr;
+		u32 surface;
+		u32 tile_offset;
+	} plane[I915_MAX_PIPES];
+
+	struct intel_transcoder_error_state {
+		bool power_domain_on;
+		enum transcoder cpu_transcoder;
+
+		u32 conf;
+
+		u32 htotal;
+		u32 hblank;
+		u32 hsync;
+		u32 vtotal;
+		u32 vblank;
+		u32 vsync;
+	} transcoder[4];
+};
+
+struct intel_display_error_state *
+intel_display_capture_error_state(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_display_error_state *error;
+	int transcoders[] = {
+		TRANSCODER_A,
+		TRANSCODER_B,
+		TRANSCODER_C,
+		TRANSCODER_EDP,
+	};
+	int i;
+
+	if (INTEL_INFO(dev)->num_pipes == 0)
+		return NULL;
+
+	error = kzalloc(sizeof(*error), GFP_ATOMIC);
+	if (error == NULL)
+		return NULL;
+
+	if (IS_HASWELL(dev) || IS_BROADWELL(dev))
+		error->power_well_driver = I915_READ(HSW_PWR_WELL_DRIVER);
+
+	for_each_pipe(dev_priv, i) {
+		error->pipe[i].power_domain_on =
+			__intel_display_power_is_enabled(dev_priv,
+							 POWER_DOMAIN_PIPE(i));
+		if (!error->pipe[i].power_domain_on)
+			continue;
+
+		error->cursor[i].control = I915_READ(CURCNTR(i));
+		error->cursor[i].position = I915_READ(CURPOS(i));
+		error->cursor[i].base = I915_READ(CURBASE(i));
+
+		error->plane[i].control = I915_READ(DSPCNTR(i));
+		error->plane[i].stride = I915_READ(DSPSTRIDE(i));
+		if (INTEL_INFO(dev)->gen <= 3) {
+			error->plane[i].size = I915_READ(DSPSIZE(i));
+			error->plane[i].pos = I915_READ(DSPPOS(i));
+		}
+		if (INTEL_INFO(dev)->gen <= 7 && !IS_HASWELL(dev))
+			error->plane[i].addr = I915_READ(DSPADDR(i));
+		if (INTEL_INFO(dev)->gen >= 4) {
+			error->plane[i].surface = I915_READ(DSPSURF(i));
+			error->plane[i].tile_offset = I915_READ(DSPTILEOFF(i));
+		}
+
+		error->pipe[i].source = I915_READ(PIPESRC(i));
+
+		if (HAS_GMCH_DISPLAY(dev))
+			error->pipe[i].stat = I915_READ(PIPESTAT(i));
+	}
+
+	/* Note: this does not include DSI transcoders. */
+	error->num_transcoders = INTEL_INFO(dev)->num_pipes;
+	if (HAS_DDI(dev_priv))
+		error->num_transcoders++; /* Account for eDP. */
+
+	for (i = 0; i < error->num_transcoders; i++) {
+		enum transcoder cpu_transcoder = transcoders[i];
+
+		error->transcoder[i].power_domain_on =
+			__intel_display_power_is_enabled(dev_priv,
+				POWER_DOMAIN_TRANSCODER(cpu_transcoder));
+		if (!error->transcoder[i].power_domain_on)
+			continue;
+
+		error->transcoder[i].cpu_transcoder = cpu_transcoder;
+
+		error->transcoder[i].conf = I915_READ(PIPECONF(cpu_transcoder));
+		error->transcoder[i].htotal = I915_READ(HTOTAL(cpu_transcoder));
+		error->transcoder[i].hblank = I915_READ(HBLANK(cpu_transcoder));
+		error->transcoder[i].hsync = I915_READ(HSYNC(cpu_transcoder));
+		error->transcoder[i].vtotal = I915_READ(VTOTAL(cpu_transcoder));
+		error->transcoder[i].vblank = I915_READ(VBLANK(cpu_transcoder));
+		error->transcoder[i].vsync = I915_READ(VSYNC(cpu_transcoder));
+	}
+
+	return error;
+}
+
+#define err_printf(e, ...) i915_error_printf(e, __VA_ARGS__)
+
+void
+intel_display_print_error_state(struct drm_i915_error_state_buf *m,
+				struct drm_device *dev,
+				struct intel_display_error_state *error)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	int i;
+
+	if (!error)
+		return;
+
+	err_printf(m, "Num Pipes: %d\n", INTEL_INFO(dev)->num_pipes);
+	if (IS_HASWELL(dev) || IS_BROADWELL(dev))
+		err_printf(m, "PWR_WELL_CTL2: %08x\n",
+			   error->power_well_driver);
+	for_each_pipe(dev_priv, i) {
+		err_printf(m, "Pipe [%d]:\n", i);
+		err_printf(m, "  Power: %s\n",
+			   onoff(error->pipe[i].power_domain_on));
+		err_printf(m, "  SRC: %08x\n", error->pipe[i].source);
+		err_printf(m, "  STAT: %08x\n", error->pipe[i].stat);
+
+		err_printf(m, "Plane [%d]:\n", i);
+		err_printf(m, "  CNTR: %08x\n", error->plane[i].control);
+		err_printf(m, "  STRIDE: %08x\n", error->plane[i].stride);
+		if (INTEL_INFO(dev)->gen <= 3) {
+			err_printf(m, "  SIZE: %08x\n", error->plane[i].size);
+			err_printf(m, "  POS: %08x\n", error->plane[i].pos);
+		}
+		if (INTEL_INFO(dev)->gen <= 7 && !IS_HASWELL(dev))
+			err_printf(m, "  ADDR: %08x\n", error->plane[i].addr);
+		if (INTEL_INFO(dev)->gen >= 4) {
+			err_printf(m, "  SURF: %08x\n", error->plane[i].surface);
+			err_printf(m, "  TILEOFF: %08x\n", error->plane[i].tile_offset);
+		}
+
+		err_printf(m, "Cursor [%d]:\n", i);
+		err_printf(m, "  CNTR: %08x\n", error->cursor[i].control);
+		err_printf(m, "  POS: %08x\n", error->cursor[i].position);
+		err_printf(m, "  BASE: %08x\n", error->cursor[i].base);
+	}
+
+	for (i = 0; i < error->num_transcoders; i++) {
+		err_printf(m, "CPU transcoder: %s\n",
+			   transcoder_name(error->transcoder[i].cpu_transcoder));
+		err_printf(m, "  Power: %s\n",
+			   onoff(error->transcoder[i].power_domain_on));
+		err_printf(m, "  CONF: %08x\n", error->transcoder[i].conf);
+		err_printf(m, "  HTOTAL: %08x\n", error->transcoder[i].htotal);
+		err_printf(m, "  HBLANK: %08x\n", error->transcoder[i].hblank);
+		err_printf(m, "  HSYNC: %08x\n", error->transcoder[i].hsync);
+		err_printf(m, "  VTOTAL: %08x\n", error->transcoder[i].vtotal);
+		err_printf(m, "  VBLANK: %08x\n", error->transcoder[i].vblank);
+		err_printf(m, "  VSYNC: %08x\n", error->transcoder[i].vsync);
+	}
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/i915/intel_dp.c
@@ -0,0 +1,6049 @@
+/*
+ * Copyright © 2008 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Keith Packard <keithp@keithp.com>
+ *
+ */
+
+#include <linux/i2c.h>
+#include <linux/slab.h>
+#include <linux/export.h>
+#include <linux/notifier.h>
+#include <linux/reboot.h>
+#include <drm/drmP.h>
+#include <drm/drm_atomic_helper.h>
+#include <drm/drm_crtc.h>
+#include <drm/drm_crtc_helper.h>
+#include <drm/drm_edid.h>
+#include "intel_drv.h"
+#include <drm/i915_drm.h>
+#include "i915_drv.h"
+
+#define DP_LINK_CHECK_TIMEOUT	(10 * 1000)
+
+/* Compliance test status bits  */
+#define INTEL_DP_RESOLUTION_SHIFT_MASK	0
+#define INTEL_DP_RESOLUTION_PREFERRED	(1 << INTEL_DP_RESOLUTION_SHIFT_MASK)
+#define INTEL_DP_RESOLUTION_STANDARD	(2 << INTEL_DP_RESOLUTION_SHIFT_MASK)
+#define INTEL_DP_RESOLUTION_FAILSAFE	(3 << INTEL_DP_RESOLUTION_SHIFT_MASK)
+
+struct dp_link_dpll {
+	int clock;
+	struct dpll dpll;
+};
+
+static const struct dp_link_dpll gen4_dpll[] = {
+	{ 162000,
+		{ .p1 = 2, .p2 = 10, .n = 2, .m1 = 23, .m2 = 8 } },
+	{ 270000,
+		{ .p1 = 1, .p2 = 10, .n = 1, .m1 = 14, .m2 = 2 } }
+};
+
+static const struct dp_link_dpll pch_dpll[] = {
+	{ 162000,
+		{ .p1 = 2, .p2 = 10, .n = 1, .m1 = 12, .m2 = 9 } },
+	{ 270000,
+		{ .p1 = 1, .p2 = 10, .n = 2, .m1 = 14, .m2 = 8 } }
+};
+
+static const struct dp_link_dpll vlv_dpll[] = {
+	{ 162000,
+		{ .p1 = 3, .p2 = 2, .n = 5, .m1 = 3, .m2 = 81 } },
+	{ 270000,
+		{ .p1 = 2, .p2 = 2, .n = 1, .m1 = 2, .m2 = 27 } }
+};
+
+/*
+ * CHV supports eDP 1.4 that have  more link rates.
+ * Below only provides the fixed rate but exclude variable rate.
+ */
+static const struct dp_link_dpll chv_dpll[] = {
+	/*
+	 * CHV requires to program fractional division for m2.
+	 * m2 is stored in fixed point format using formula below
+	 * (m2_int << 22) | m2_fraction
+	 */
+	{ 162000,	/* m2_int = 32, m2_fraction = 1677722 */
+		{ .p1 = 4, .p2 = 2, .n = 1, .m1 = 2, .m2 = 0x819999a } },
+	{ 270000,	/* m2_int = 27, m2_fraction = 0 */
+		{ .p1 = 4, .p2 = 1, .n = 1, .m1 = 2, .m2 = 0x6c00000 } },
+	{ 540000,	/* m2_int = 27, m2_fraction = 0 */
+		{ .p1 = 2, .p2 = 1, .n = 1, .m1 = 2, .m2 = 0x6c00000 } }
+};
+
+static const int bxt_rates[] = { 162000, 216000, 243000, 270000,
+				  324000, 432000, 540000 };
+static const int skl_rates[] = { 162000, 216000, 270000,
+				  324000, 432000, 540000 };
+static const int default_rates[] = { 162000, 270000, 540000 };
+
+/**
+ * is_edp - is the given port attached to an eDP panel (either CPU or PCH)
+ * @intel_dp: DP struct
+ *
+ * If a CPU or PCH DP output is attached to an eDP panel, this function
+ * will return true, and false otherwise.
+ */
+static bool is_edp(struct intel_dp *intel_dp)
+{
+	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
+
+	return intel_dig_port->base.type == INTEL_OUTPUT_EDP;
+}
+
+static struct drm_device *intel_dp_to_dev(struct intel_dp *intel_dp)
+{
+	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
+
+	return intel_dig_port->base.base.dev;
+}
+
+static struct intel_dp *intel_attached_dp(struct drm_connector *connector)
+{
+	return enc_to_intel_dp(&intel_attached_encoder(connector)->base);
+}
+
+static void intel_dp_link_down(struct intel_dp *intel_dp);
+static bool edp_panel_vdd_on(struct intel_dp *intel_dp);
+static void edp_panel_vdd_off(struct intel_dp *intel_dp, bool sync);
+static void vlv_init_panel_power_sequencer(struct intel_dp *intel_dp);
+static void vlv_steal_power_sequencer(struct drm_device *dev,
+				      enum pipe pipe);
+static void intel_dp_unset_edid(struct intel_dp *intel_dp);
+
+static unsigned int intel_dp_unused_lane_mask(int lane_count)
+{
+	return ~((1 << lane_count) - 1) & 0xf;
+}
+
+static int
+intel_dp_max_link_bw(struct intel_dp  *intel_dp)
+{
+	int max_link_bw = intel_dp->dpcd[DP_MAX_LINK_RATE];
+
+	switch (max_link_bw) {
+	case DP_LINK_BW_1_62:
+	case DP_LINK_BW_2_7:
+	case DP_LINK_BW_5_4:
+		break;
+	default:
+		WARN(1, "invalid max DP link bw val %x, using 1.62Gbps\n",
+		     max_link_bw);
+		max_link_bw = DP_LINK_BW_1_62;
+		break;
+	}
+	return max_link_bw;
+}
+
+static u8 intel_dp_max_lane_count(struct intel_dp *intel_dp)
+{
+	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
+	u8 source_max, sink_max;
+
+	source_max = intel_dig_port->max_lanes;
+	sink_max = drm_dp_max_lane_count(intel_dp->dpcd);
+
+	return min(source_max, sink_max);
+}
+
+/*
+ * The units on the numbers in the next two are... bizarre.  Examples will
+ * make it clearer; this one parallels an example in the eDP spec.
+ *
+ * intel_dp_max_data_rate for one lane of 2.7GHz evaluates as:
+ *
+ *     270000 * 1 * 8 / 10 == 216000
+ *
+ * The actual data capacity of that configuration is 2.16Gbit/s, so the
+ * units are decakilobits.  ->clock in a drm_display_mode is in kilohertz -
+ * or equivalently, kilopixels per second - so for 1680x1050R it'd be
+ * 119000.  At 18bpp that's 2142000 kilobits per second.
+ *
+ * Thus the strange-looking division by 10 in intel_dp_link_required, to
+ * get the result in decakilobits instead of kilobits.
+ */
+
+static int
+intel_dp_link_required(int pixel_clock, int bpp)
+{
+	return (pixel_clock * bpp + 9) / 10;
+}
+
+static int
+intel_dp_max_data_rate(int max_link_clock, int max_lanes)
+{
+	return (max_link_clock * max_lanes * 8) / 10;
+}
+
+static enum drm_mode_status
+intel_dp_mode_valid(struct drm_connector *connector,
+		    struct drm_display_mode *mode)
+{
+	struct intel_dp *intel_dp = intel_attached_dp(connector);
+	struct intel_connector *intel_connector = to_intel_connector(connector);
+	struct drm_display_mode *fixed_mode = intel_connector->panel.fixed_mode;
+	int target_clock = mode->clock;
+	int max_rate, mode_rate, max_lanes, max_link_clock;
+	int max_dotclk = to_i915(connector->dev)->max_dotclk_freq;
+
+	if (is_edp(intel_dp) && fixed_mode) {
+		if (mode->hdisplay > fixed_mode->hdisplay)
+			return MODE_PANEL;
+
+		if (mode->vdisplay > fixed_mode->vdisplay)
+			return MODE_PANEL;
+
+		target_clock = fixed_mode->clock;
+	}
+
+	max_link_clock = intel_dp_max_link_rate(intel_dp);
+	max_lanes = intel_dp_max_lane_count(intel_dp);
+
+	max_rate = intel_dp_max_data_rate(max_link_clock, max_lanes);
+	mode_rate = intel_dp_link_required(target_clock, 18);
+
+	if (mode_rate > max_rate || target_clock > max_dotclk)
+		return MODE_CLOCK_HIGH;
+
+	if (mode->clock < 10000)
+		return MODE_CLOCK_LOW;
+
+	if (mode->flags & DRM_MODE_FLAG_DBLCLK)
+		return MODE_H_ILLEGAL;
+
+	return MODE_OK;
+}
+
+uint32_t intel_dp_pack_aux(const uint8_t *src, int src_bytes)
+{
+	int	i;
+	uint32_t v = 0;
+
+	if (src_bytes > 4)
+		src_bytes = 4;
+	for (i = 0; i < src_bytes; i++)
+		v |= ((uint32_t) src[i]) << ((3-i) * 8);
+	return v;
+}
+
+static void intel_dp_unpack_aux(uint32_t src, uint8_t *dst, int dst_bytes)
+{
+	int i;
+	if (dst_bytes > 4)
+		dst_bytes = 4;
+	for (i = 0; i < dst_bytes; i++)
+		dst[i] = src >> ((3-i) * 8);
+}
+
+static void
+intel_dp_init_panel_power_sequencer(struct drm_device *dev,
+				    struct intel_dp *intel_dp);
+static void
+intel_dp_init_panel_power_sequencer_registers(struct drm_device *dev,
+					      struct intel_dp *intel_dp);
+
+static void pps_lock(struct intel_dp *intel_dp)
+{
+	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
+	struct intel_encoder *encoder = &intel_dig_port->base;
+	struct drm_device *dev = encoder->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	enum intel_display_power_domain power_domain;
+
+	/*
+	 * See vlv_power_sequencer_reset() why we need
+	 * a power domain reference here.
+	 */
+	power_domain = intel_display_port_aux_power_domain(encoder);
+	intel_display_power_get(dev_priv, power_domain);
+
+	mutex_lock(&dev_priv->pps_mutex);
+}
+
+static void pps_unlock(struct intel_dp *intel_dp)
+{
+	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
+	struct intel_encoder *encoder = &intel_dig_port->base;
+	struct drm_device *dev = encoder->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	enum intel_display_power_domain power_domain;
+
+	mutex_unlock(&dev_priv->pps_mutex);
+
+	power_domain = intel_display_port_aux_power_domain(encoder);
+	intel_display_power_put(dev_priv, power_domain);
+}
+
+static void
+vlv_power_sequencer_kick(struct intel_dp *intel_dp)
+{
+	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
+	struct drm_device *dev = intel_dig_port->base.base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	enum pipe pipe = intel_dp->pps_pipe;
+	bool pll_enabled, release_cl_override = false;
+	enum dpio_phy phy = DPIO_PHY(pipe);
+	enum dpio_channel ch = vlv_pipe_to_channel(pipe);
+	uint32_t DP;
+
+	if (WARN(I915_READ(intel_dp->output_reg) & DP_PORT_EN,
+		 "skipping pipe %c power seqeuncer kick due to port %c being active\n",
+		 pipe_name(pipe), port_name(intel_dig_port->port)))
+		return;
+
+	DRM_DEBUG_KMS("kicking pipe %c power sequencer for port %c\n",
+		      pipe_name(pipe), port_name(intel_dig_port->port));
+
+	/* Preserve the BIOS-computed detected bit. This is
+	 * supposed to be read-only.
+	 */
+	DP = I915_READ(intel_dp->output_reg) & DP_DETECTED;
+	DP |= DP_VOLTAGE_0_4 | DP_PRE_EMPHASIS_0;
+	DP |= DP_PORT_WIDTH(1);
+	DP |= DP_LINK_TRAIN_PAT_1;
+
+	if (IS_CHERRYVIEW(dev))
+		DP |= DP_PIPE_SELECT_CHV(pipe);
+	else if (pipe == PIPE_B)
+		DP |= DP_PIPEB_SELECT;
+
+	pll_enabled = I915_READ(DPLL(pipe)) & DPLL_VCO_ENABLE;
+
+	/*
+	 * The DPLL for the pipe must be enabled for this to work.
+	 * So enable temporarily it if it's not already enabled.
+	 */
+	if (!pll_enabled) {
+		release_cl_override = IS_CHERRYVIEW(dev) &&
+			!chv_phy_powergate_ch(dev_priv, phy, ch, true);
+
+		if (vlv_force_pll_on(dev, pipe, IS_CHERRYVIEW(dev) ?
+				     &chv_dpll[0].dpll : &vlv_dpll[0].dpll)) {
+			DRM_ERROR("Failed to force on pll for pipe %c!\n",
+				  pipe_name(pipe));
+			return;
+		}
+	}
+
+	/*
+	 * Similar magic as in intel_dp_enable_port().
+	 * We _must_ do this port enable + disable trick
+	 * to make this power seqeuencer lock onto the port.
+	 * Otherwise even VDD force bit won't work.
+	 */
+	I915_WRITE(intel_dp->output_reg, DP);
+	POSTING_READ(intel_dp->output_reg);
+
+	I915_WRITE(intel_dp->output_reg, DP | DP_PORT_EN);
+	POSTING_READ(intel_dp->output_reg);
+
+	I915_WRITE(intel_dp->output_reg, DP & ~DP_PORT_EN);
+	POSTING_READ(intel_dp->output_reg);
+
+	if (!pll_enabled) {
+		vlv_force_pll_off(dev, pipe);
+
+		if (release_cl_override)
+			chv_phy_powergate_ch(dev_priv, phy, ch, false);
+	}
+}
+
+static enum pipe
+vlv_power_sequencer_pipe(struct intel_dp *intel_dp)
+{
+	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
+	struct drm_device *dev = intel_dig_port->base.base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_encoder *encoder;
+	unsigned int pipes = (1 << PIPE_A) | (1 << PIPE_B);
+	enum pipe pipe;
+
+	lockdep_assert_held(&dev_priv->pps_mutex);
+
+	/* We should never land here with regular DP ports */
+	WARN_ON(!is_edp(intel_dp));
+
+	if (intel_dp->pps_pipe != INVALID_PIPE)
+		return intel_dp->pps_pipe;
+
+	/*
+	 * We don't have power sequencer currently.
+	 * Pick one that's not used by other ports.
+	 */
+	for_each_intel_encoder(dev, encoder) {
+		struct intel_dp *tmp;
+
+		if (encoder->type != INTEL_OUTPUT_EDP)
+			continue;
+
+		tmp = enc_to_intel_dp(&encoder->base);
+
+		if (tmp->pps_pipe != INVALID_PIPE)
+			pipes &= ~(1 << tmp->pps_pipe);
+	}
+
+	/*
+	 * Didn't find one. This should not happen since there
+	 * are two power sequencers and up to two eDP ports.
+	 */
+	if (WARN_ON(pipes == 0))
+		pipe = PIPE_A;
+	else
+		pipe = ffs(pipes) - 1;
+
+	vlv_steal_power_sequencer(dev, pipe);
+	intel_dp->pps_pipe = pipe;
+
+	DRM_DEBUG_KMS("picked pipe %c power sequencer for port %c\n",
+		      pipe_name(intel_dp->pps_pipe),
+		      port_name(intel_dig_port->port));
+
+	/* init power sequencer on this pipe and port */
+	intel_dp_init_panel_power_sequencer(dev, intel_dp);
+	intel_dp_init_panel_power_sequencer_registers(dev, intel_dp);
+
+	/*
+	 * Even vdd force doesn't work until we've made
+	 * the power sequencer lock in on the port.
+	 */
+	vlv_power_sequencer_kick(intel_dp);
+
+	return intel_dp->pps_pipe;
+}
+
+typedef bool (*vlv_pipe_check)(struct drm_i915_private *dev_priv,
+			       enum pipe pipe);
+
+static bool vlv_pipe_has_pp_on(struct drm_i915_private *dev_priv,
+			       enum pipe pipe)
+{
+	return I915_READ(VLV_PIPE_PP_STATUS(pipe)) & PP_ON;
+}
+
+static bool vlv_pipe_has_vdd_on(struct drm_i915_private *dev_priv,
+				enum pipe pipe)
+{
+	return I915_READ(VLV_PIPE_PP_CONTROL(pipe)) & EDP_FORCE_VDD;
+}
+
+static bool vlv_pipe_any(struct drm_i915_private *dev_priv,
+			 enum pipe pipe)
+{
+	return true;
+}
+
+static enum pipe
+vlv_initial_pps_pipe(struct drm_i915_private *dev_priv,
+		     enum port port,
+		     vlv_pipe_check pipe_check)
+{
+	enum pipe pipe;
+
+	for (pipe = PIPE_A; pipe <= PIPE_B; pipe++) {
+		u32 port_sel = I915_READ(VLV_PIPE_PP_ON_DELAYS(pipe)) &
+			PANEL_PORT_SELECT_MASK;
+
+		if (port_sel != PANEL_PORT_SELECT_VLV(port))
+			continue;
+
+		if (!pipe_check(dev_priv, pipe))
+			continue;
+
+		return pipe;
+	}
+
+	return INVALID_PIPE;
+}
+
+static void
+vlv_initial_power_sequencer_setup(struct intel_dp *intel_dp)
+{
+	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
+	struct drm_device *dev = intel_dig_port->base.base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	enum port port = intel_dig_port->port;
+
+	lockdep_assert_held(&dev_priv->pps_mutex);
+
+	/* try to find a pipe with this port selected */
+	/* first pick one where the panel is on */
+	intel_dp->pps_pipe = vlv_initial_pps_pipe(dev_priv, port,
+						  vlv_pipe_has_pp_on);
+	/* didn't find one? pick one where vdd is on */
+	if (intel_dp->pps_pipe == INVALID_PIPE)
+		intel_dp->pps_pipe = vlv_initial_pps_pipe(dev_priv, port,
+							  vlv_pipe_has_vdd_on);
+	/* didn't find one? pick one with just the correct port */
+	if (intel_dp->pps_pipe == INVALID_PIPE)
+		intel_dp->pps_pipe = vlv_initial_pps_pipe(dev_priv, port,
+							  vlv_pipe_any);
+
+	/* didn't find one? just let vlv_power_sequencer_pipe() pick one when needed */
+	if (intel_dp->pps_pipe == INVALID_PIPE) {
+		DRM_DEBUG_KMS("no initial power sequencer for port %c\n",
+			      port_name(port));
+		return;
+	}
+
+	DRM_DEBUG_KMS("initial power sequencer for port %c: pipe %c\n",
+		      port_name(port), pipe_name(intel_dp->pps_pipe));
+
+	intel_dp_init_panel_power_sequencer(dev, intel_dp);
+	intel_dp_init_panel_power_sequencer_registers(dev, intel_dp);
+}
+
+void vlv_power_sequencer_reset(struct drm_i915_private *dev_priv)
+{
+	struct drm_device *dev = dev_priv->dev;
+	struct intel_encoder *encoder;
+
+	if (WARN_ON(!IS_VALLEYVIEW(dev) && !IS_CHERRYVIEW(dev)))
+		return;
+
+	/*
+	 * We can't grab pps_mutex here due to deadlock with power_domain
+	 * mutex when power_domain functions are called while holding pps_mutex.
+	 * That also means that in order to use pps_pipe the code needs to
+	 * hold both a power domain reference and pps_mutex, and the power domain
+	 * reference get/put must be done while _not_ holding pps_mutex.
+	 * pps_{lock,unlock}() do these steps in the correct order, so one
+	 * should use them always.
+	 */
+
+	for_each_intel_encoder(dev, encoder) {
+		struct intel_dp *intel_dp;
+
+		if (encoder->type != INTEL_OUTPUT_EDP)
+			continue;
+
+		intel_dp = enc_to_intel_dp(&encoder->base);
+		intel_dp->pps_pipe = INVALID_PIPE;
+	}
+}
+
+static i915_reg_t
+_pp_ctrl_reg(struct intel_dp *intel_dp)
+{
+	struct drm_device *dev = intel_dp_to_dev(intel_dp);
+
+	if (IS_BROXTON(dev))
+		return BXT_PP_CONTROL(0);
+	else if (HAS_PCH_SPLIT(dev))
+		return PCH_PP_CONTROL;
+	else
+		return VLV_PIPE_PP_CONTROL(vlv_power_sequencer_pipe(intel_dp));
+}
+
+static i915_reg_t
+_pp_stat_reg(struct intel_dp *intel_dp)
+{
+	struct drm_device *dev = intel_dp_to_dev(intel_dp);
+
+	if (IS_BROXTON(dev))
+		return BXT_PP_STATUS(0);
+	else if (HAS_PCH_SPLIT(dev))
+		return PCH_PP_STATUS;
+	else
+		return VLV_PIPE_PP_STATUS(vlv_power_sequencer_pipe(intel_dp));
+}
+
+/* Reboot notifier handler to shutdown panel power to guarantee T12 timing
+   This function only applicable when panel PM state is not to be tracked */
+static int edp_notify_handler(struct notifier_block *this, unsigned long code,
+			      void *unused)
+{
+	struct intel_dp *intel_dp = container_of(this, typeof(* intel_dp),
+						 edp_notifier);
+	struct drm_device *dev = intel_dp_to_dev(intel_dp);
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	if (!is_edp(intel_dp) || code != SYS_RESTART)
+		return 0;
+
+	pps_lock(intel_dp);
+
+	if (IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev)) {
+		enum pipe pipe = vlv_power_sequencer_pipe(intel_dp);
+		i915_reg_t pp_ctrl_reg, pp_div_reg;
+		u32 pp_div;
+
+		pp_ctrl_reg = VLV_PIPE_PP_CONTROL(pipe);
+		pp_div_reg  = VLV_PIPE_PP_DIVISOR(pipe);
+		pp_div = I915_READ(pp_div_reg);
+		pp_div &= PP_REFERENCE_DIVIDER_MASK;
+
+		/* 0x1F write to PP_DIV_REG sets max cycle delay */
+		I915_WRITE(pp_div_reg, pp_div | 0x1F);
+		I915_WRITE(pp_ctrl_reg, PANEL_UNLOCK_REGS | PANEL_POWER_OFF);
+		msleep(intel_dp->panel_power_cycle_delay);
+	}
+
+	pps_unlock(intel_dp);
+
+	return 0;
+}
+
+static bool edp_have_panel_power(struct intel_dp *intel_dp)
+{
+	struct drm_device *dev = intel_dp_to_dev(intel_dp);
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	lockdep_assert_held(&dev_priv->pps_mutex);
+
+	if ((IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev)) &&
+	    intel_dp->pps_pipe == INVALID_PIPE)
+		return false;
+
+	return (I915_READ(_pp_stat_reg(intel_dp)) & PP_ON) != 0;
+}
+
+static bool edp_have_panel_vdd(struct intel_dp *intel_dp)
+{
+	struct drm_device *dev = intel_dp_to_dev(intel_dp);
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	lockdep_assert_held(&dev_priv->pps_mutex);
+
+	if ((IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev)) &&
+	    intel_dp->pps_pipe == INVALID_PIPE)
+		return false;
+
+	return I915_READ(_pp_ctrl_reg(intel_dp)) & EDP_FORCE_VDD;
+}
+
+static void
+intel_dp_check_edp(struct intel_dp *intel_dp)
+{
+	struct drm_device *dev = intel_dp_to_dev(intel_dp);
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	if (!is_edp(intel_dp))
+		return;
+
+	if (!edp_have_panel_power(intel_dp) && !edp_have_panel_vdd(intel_dp)) {
+		WARN(1, "eDP powered off while attempting aux channel communication.\n");
+		DRM_DEBUG_KMS("Status 0x%08x Control 0x%08x\n",
+			      I915_READ(_pp_stat_reg(intel_dp)),
+			      I915_READ(_pp_ctrl_reg(intel_dp)));
+	}
+}
+
+static uint32_t
+intel_dp_aux_wait_done(struct intel_dp *intel_dp, bool has_aux_irq)
+{
+	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
+	struct drm_device *dev = intel_dig_port->base.base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	i915_reg_t ch_ctl = intel_dp->aux_ch_ctl_reg;
+	uint32_t status;
+	bool done;
+
+#define C (((status = I915_READ_NOTRACE(ch_ctl)) & DP_AUX_CH_CTL_SEND_BUSY) == 0)
+	if (has_aux_irq)
+		done = wait_event_timeout(dev_priv->gmbus_wait_queue, C,
+					  msecs_to_jiffies_timeout(10));
+	else
+		done = wait_for(C, 10) == 0;
+	if (!done)
+		DRM_ERROR("dp aux hw did not signal timeout (has irq: %i)!\n",
+			  has_aux_irq);
+#undef C
+
+	return status;
+}
+
+static uint32_t g4x_get_aux_clock_divider(struct intel_dp *intel_dp, int index)
+{
+	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
+	struct drm_i915_private *dev_priv = to_i915(intel_dig_port->base.base.dev);
+
+	if (index)
+		return 0;
+
+	/*
+	 * The clock divider is based off the hrawclk, and would like to run at
+	 * 2MHz.  So, take the hrawclk value and divide by 2000 and use that
+	 */
+	return DIV_ROUND_CLOSEST(dev_priv->rawclk_freq, 2000);
+}
+
+static uint32_t ilk_get_aux_clock_divider(struct intel_dp *intel_dp, int index)
+{
+	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
+	struct drm_i915_private *dev_priv = to_i915(intel_dig_port->base.base.dev);
+
+	if (index)
+		return 0;
+
+	/*
+	 * The clock divider is based off the cdclk or PCH rawclk, and would
+	 * like to run at 2MHz.  So, take the cdclk or PCH rawclk value and
+	 * divide by 2000 and use that
+	 */
+	if (intel_dig_port->port == PORT_A)
+		return DIV_ROUND_CLOSEST(dev_priv->cdclk_freq, 2000);
+	else
+		return DIV_ROUND_CLOSEST(dev_priv->rawclk_freq, 2000);
+}
+
+static uint32_t hsw_get_aux_clock_divider(struct intel_dp *intel_dp, int index)
+{
+	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
+	struct drm_i915_private *dev_priv = to_i915(intel_dig_port->base.base.dev);
+
+	if (intel_dig_port->port != PORT_A && HAS_PCH_LPT_H(dev_priv)) {
+		/* Workaround for non-ULT HSW */
+		switch (index) {
+		case 0: return 63;
+		case 1: return 72;
+		default: return 0;
+		}
+	}
+
+	return ilk_get_aux_clock_divider(intel_dp, index);
+}
+
+static uint32_t skl_get_aux_clock_divider(struct intel_dp *intel_dp, int index)
+{
+	/*
+	 * SKL doesn't need us to program the AUX clock divider (Hardware will
+	 * derive the clock from CDCLK automatically). We still implement the
+	 * get_aux_clock_divider vfunc to plug-in into the existing code.
+	 */
+	return index ? 0 : 1;
+}
+
+static uint32_t g4x_get_aux_send_ctl(struct intel_dp *intel_dp,
+				     bool has_aux_irq,
+				     int send_bytes,
+				     uint32_t aux_clock_divider)
+{
+	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
+	struct drm_device *dev = intel_dig_port->base.base.dev;
+	uint32_t precharge, timeout;
+
+	if (IS_GEN6(dev))
+		precharge = 3;
+	else
+		precharge = 5;
+
+	if (IS_BROADWELL(dev) && intel_dig_port->port == PORT_A)
+		timeout = DP_AUX_CH_CTL_TIME_OUT_600us;
+	else
+		timeout = DP_AUX_CH_CTL_TIME_OUT_400us;
+
+	return DP_AUX_CH_CTL_SEND_BUSY |
+	       DP_AUX_CH_CTL_DONE |
+	       (has_aux_irq ? DP_AUX_CH_CTL_INTERRUPT : 0) |
+	       DP_AUX_CH_CTL_TIME_OUT_ERROR |
+	       timeout |
+	       DP_AUX_CH_CTL_RECEIVE_ERROR |
+	       (send_bytes << DP_AUX_CH_CTL_MESSAGE_SIZE_SHIFT) |
+	       (precharge << DP_AUX_CH_CTL_PRECHARGE_2US_SHIFT) |
+	       (aux_clock_divider << DP_AUX_CH_CTL_BIT_CLOCK_2X_SHIFT);
+}
+
+static uint32_t skl_get_aux_send_ctl(struct intel_dp *intel_dp,
+				      bool has_aux_irq,
+				      int send_bytes,
+				      uint32_t unused)
+{
+	return DP_AUX_CH_CTL_SEND_BUSY |
+	       DP_AUX_CH_CTL_DONE |
+	       (has_aux_irq ? DP_AUX_CH_CTL_INTERRUPT : 0) |
+	       DP_AUX_CH_CTL_TIME_OUT_ERROR |
+	       DP_AUX_CH_CTL_TIME_OUT_1600us |
+	       DP_AUX_CH_CTL_RECEIVE_ERROR |
+	       (send_bytes << DP_AUX_CH_CTL_MESSAGE_SIZE_SHIFT) |
+	       DP_AUX_CH_CTL_SYNC_PULSE_SKL(32);
+}
+
+static int
+intel_dp_aux_ch(struct intel_dp *intel_dp,
+		const uint8_t *send, int send_bytes,
+		uint8_t *recv, int recv_size)
+{
+	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
+	struct drm_device *dev = intel_dig_port->base.base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	i915_reg_t ch_ctl = intel_dp->aux_ch_ctl_reg;
+	uint32_t aux_clock_divider;
+	int i, ret, recv_bytes;
+	uint32_t status;
+	int try, clock = 0;
+	bool has_aux_irq = HAS_AUX_IRQ(dev);
+	bool vdd;
+
+	pps_lock(intel_dp);
+
+	/*
+	 * We will be called with VDD already enabled for dpcd/edid/oui reads.
+	 * In such cases we want to leave VDD enabled and it's up to upper layers
+	 * to turn it off. But for eg. i2c-dev access we need to turn it on/off
+	 * ourselves.
+	 */
+	vdd = edp_panel_vdd_on(intel_dp);
+
+	/* dp aux is extremely sensitive to irq latency, hence request the
+	 * lowest possible wakeup latency and so prevent the cpu from going into
+	 * deep sleep states.
+	 */
+	pm_qos_update_request(&dev_priv->pm_qos, 0);
+
+	intel_dp_check_edp(intel_dp);
+
+	/* Try to wait for any previous AUX channel activity */
+	for (try = 0; try < 3; try++) {
+		status = I915_READ_NOTRACE(ch_ctl);
+		if ((status & DP_AUX_CH_CTL_SEND_BUSY) == 0)
+			break;
+		msleep(1);
+	}
+
+	if (try == 3) {
+		static u32 last_status = -1;
+		const u32 status = I915_READ(ch_ctl);
+
+		if (status != last_status) {
+			WARN(1, "dp_aux_ch not started status 0x%08x\n",
+			     status);
+			last_status = status;
+		}
+
+		ret = -EBUSY;
+		goto out;
+	}
+
+	/* Only 5 data registers! */
+	if (WARN_ON(send_bytes > 20 || recv_size > 20)) {
+		ret = -E2BIG;
+		goto out;
+	}
+
+	while ((aux_clock_divider = intel_dp->get_aux_clock_divider(intel_dp, clock++))) {
+		u32 send_ctl = intel_dp->get_aux_send_ctl(intel_dp,
+							  has_aux_irq,
+							  send_bytes,
+							  aux_clock_divider);
+
+		/* Must try at least 3 times according to DP spec */
+		for (try = 0; try < 5; try++) {
+			/* Load the send data into the aux channel data registers */
+			for (i = 0; i < send_bytes; i += 4)
+				I915_WRITE(intel_dp->aux_ch_data_reg[i >> 2],
+					   intel_dp_pack_aux(send + i,
+							     send_bytes - i));
+
+			/* Send the command and wait for it to complete */
+			I915_WRITE(ch_ctl, send_ctl);
+
+			status = intel_dp_aux_wait_done(intel_dp, has_aux_irq);
+
+			/* Clear done status and any errors */
+			I915_WRITE(ch_ctl,
+				   status |
+				   DP_AUX_CH_CTL_DONE |
+				   DP_AUX_CH_CTL_TIME_OUT_ERROR |
+				   DP_AUX_CH_CTL_RECEIVE_ERROR);
+
+			if (status & DP_AUX_CH_CTL_TIME_OUT_ERROR)
+				continue;
+
+			/* DP CTS 1.2 Core Rev 1.1, 4.2.1.1 & 4.2.1.2
+			 *   400us delay required for errors and timeouts
+			 *   Timeout errors from the HW already meet this
+			 *   requirement so skip to next iteration
+			 */
+			if (status & DP_AUX_CH_CTL_RECEIVE_ERROR) {
+				usleep_range(400, 500);
+				continue;
+			}
+			if (status & DP_AUX_CH_CTL_DONE)
+				goto done;
+		}
+	}
+
+	if ((status & DP_AUX_CH_CTL_DONE) == 0) {
+		DRM_ERROR("dp_aux_ch not done status 0x%08x\n", status);
+		ret = -EBUSY;
+		goto out;
+	}
+
+done:
+	/* Check for timeout or receive error.
+	 * Timeouts occur when the sink is not connected
+	 */
+	if (status & DP_AUX_CH_CTL_RECEIVE_ERROR) {
+		DRM_ERROR("dp_aux_ch receive error status 0x%08x\n", status);
+		ret = -EIO;
+		goto out;
+	}
+
+	/* Timeouts occur when the device isn't connected, so they're
+	 * "normal" -- don't fill the kernel log with these */
+	if (status & DP_AUX_CH_CTL_TIME_OUT_ERROR) {
+		DRM_DEBUG_KMS("dp_aux_ch timeout status 0x%08x\n", status);
+		ret = -ETIMEDOUT;
+		goto out;
+	}
+
+	/* Unload any bytes sent back from the other side */
+	recv_bytes = ((status & DP_AUX_CH_CTL_MESSAGE_SIZE_MASK) >>
+		      DP_AUX_CH_CTL_MESSAGE_SIZE_SHIFT);
+
+	/*
+	 * By BSpec: "Message sizes of 0 or >20 are not allowed."
+	 * We have no idea of what happened so we return -EBUSY so
+	 * drm layer takes care for the necessary retries.
+	 */
+	if (recv_bytes == 0 || recv_bytes > 20) {
+		DRM_DEBUG_KMS("Forbidden recv_bytes = %d on aux transaction\n",
+			      recv_bytes);
+		/*
+		 * FIXME: This patch was created on top of a series that
+		 * organize the retries at drm level. There EBUSY should
+		 * also take care for 1ms wait before retrying.
+		 * That aux retries re-org is still needed and after that is
+		 * merged we remove this sleep from here.
+		 */
+		usleep_range(1000, 1500);
+		ret = -EBUSY;
+		goto out;
+	}
+
+	if (recv_bytes > recv_size)
+		recv_bytes = recv_size;
+
+	for (i = 0; i < recv_bytes; i += 4)
+		intel_dp_unpack_aux(I915_READ(intel_dp->aux_ch_data_reg[i >> 2]),
+				    recv + i, recv_bytes - i);
+
+	ret = recv_bytes;
+out:
+	pm_qos_update_request(&dev_priv->pm_qos, PM_QOS_DEFAULT_VALUE);
+
+	if (vdd)
+		edp_panel_vdd_off(intel_dp, false);
+
+	pps_unlock(intel_dp);
+
+	return ret;
+}
+
+#define BARE_ADDRESS_SIZE	3
+#define HEADER_SIZE		(BARE_ADDRESS_SIZE + 1)
+static ssize_t
+intel_dp_aux_transfer(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg)
+{
+	struct intel_dp *intel_dp = container_of(aux, struct intel_dp, aux);
+	uint8_t txbuf[20], rxbuf[20];
+	size_t txsize, rxsize;
+	int ret;
+
+	txbuf[0] = (msg->request << 4) |
+		((msg->address >> 16) & 0xf);
+	txbuf[1] = (msg->address >> 8) & 0xff;
+	txbuf[2] = msg->address & 0xff;
+	txbuf[3] = msg->size - 1;
+
+	switch (msg->request & ~DP_AUX_I2C_MOT) {
+	case DP_AUX_NATIVE_WRITE:
+	case DP_AUX_I2C_WRITE:
+	case DP_AUX_I2C_WRITE_STATUS_UPDATE:
+		txsize = msg->size ? HEADER_SIZE + msg->size : BARE_ADDRESS_SIZE;
+		rxsize = 2; /* 0 or 1 data bytes */
+
+		if (WARN_ON(txsize > 20))
+			return -E2BIG;
+
+		if (msg->buffer)
+			memcpy(txbuf + HEADER_SIZE, msg->buffer, msg->size);
+		else
+			WARN_ON(msg->size);
+
+		ret = intel_dp_aux_ch(intel_dp, txbuf, txsize, rxbuf, rxsize);
+		if (ret > 0) {
+			msg->reply = rxbuf[0] >> 4;
+
+			if (ret > 1) {
+				/* Number of bytes written in a short write. */
+				ret = clamp_t(int, rxbuf[1], 0, msg->size);
+			} else {
+				/* Return payload size. */
+				ret = msg->size;
+			}
+		}
+		break;
+
+	case DP_AUX_NATIVE_READ:
+	case DP_AUX_I2C_READ:
+		txsize = msg->size ? HEADER_SIZE : BARE_ADDRESS_SIZE;
+		rxsize = msg->size + 1;
+
+		if (WARN_ON(rxsize > 20))
+			return -E2BIG;
+
+		ret = intel_dp_aux_ch(intel_dp, txbuf, txsize, rxbuf, rxsize);
+		if (ret > 0) {
+			msg->reply = rxbuf[0] >> 4;
+			/*
+			 * Assume happy day, and copy the data. The caller is
+			 * expected to check msg->reply before touching it.
+			 *
+			 * Return payload size.
+			 */
+			ret--;
+			memcpy(msg->buffer, rxbuf + 1, ret);
+		}
+		break;
+
+	default:
+		ret = -EINVAL;
+		break;
+	}
+
+	return ret;
+}
+
+static i915_reg_t g4x_aux_ctl_reg(struct drm_i915_private *dev_priv,
+				       enum port port)
+{
+	switch (port) {
+	case PORT_B:
+	case PORT_C:
+	case PORT_D:
+		return DP_AUX_CH_CTL(port);
+	default:
+		MISSING_CASE(port);
+		return DP_AUX_CH_CTL(PORT_B);
+	}
+}
+
+static i915_reg_t g4x_aux_data_reg(struct drm_i915_private *dev_priv,
+					enum port port, int index)
+{
+	switch (port) {
+	case PORT_B:
+	case PORT_C:
+	case PORT_D:
+		return DP_AUX_CH_DATA(port, index);
+	default:
+		MISSING_CASE(port);
+		return DP_AUX_CH_DATA(PORT_B, index);
+	}
+}
+
+static i915_reg_t ilk_aux_ctl_reg(struct drm_i915_private *dev_priv,
+				       enum port port)
+{
+	switch (port) {
+	case PORT_A:
+		return DP_AUX_CH_CTL(port);
+	case PORT_B:
+	case PORT_C:
+	case PORT_D:
+		return PCH_DP_AUX_CH_CTL(port);
+	default:
+		MISSING_CASE(port);
+		return DP_AUX_CH_CTL(PORT_A);
+	}
+}
+
+static i915_reg_t ilk_aux_data_reg(struct drm_i915_private *dev_priv,
+					enum port port, int index)
+{
+	switch (port) {
+	case PORT_A:
+		return DP_AUX_CH_DATA(port, index);
+	case PORT_B:
+	case PORT_C:
+	case PORT_D:
+		return PCH_DP_AUX_CH_DATA(port, index);
+	default:
+		MISSING_CASE(port);
+		return DP_AUX_CH_DATA(PORT_A, index);
+	}
+}
+
+/*
+ * On SKL we don't have Aux for port E so we rely
+ * on VBT to set a proper alternate aux channel.
+ */
+static enum port skl_porte_aux_port(struct drm_i915_private *dev_priv)
+{
+	const struct ddi_vbt_port_info *info =
+		&dev_priv->vbt.ddi_port_info[PORT_E];
+
+	switch (info->alternate_aux_channel) {
+	case DP_AUX_A:
+		return PORT_A;
+	case DP_AUX_B:
+		return PORT_B;
+	case DP_AUX_C:
+		return PORT_C;
+	case DP_AUX_D:
+		return PORT_D;
+	default:
+		MISSING_CASE(info->alternate_aux_channel);
+		return PORT_A;
+	}
+}
+
+static i915_reg_t skl_aux_ctl_reg(struct drm_i915_private *dev_priv,
+				       enum port port)
+{
+	if (port == PORT_E)
+		port = skl_porte_aux_port(dev_priv);
+
+	switch (port) {
+	case PORT_A:
+	case PORT_B:
+	case PORT_C:
+	case PORT_D:
+		return DP_AUX_CH_CTL(port);
+	default:
+		MISSING_CASE(port);
+		return DP_AUX_CH_CTL(PORT_A);
+	}
+}
+
+static i915_reg_t skl_aux_data_reg(struct drm_i915_private *dev_priv,
+					enum port port, int index)
+{
+	if (port == PORT_E)
+		port = skl_porte_aux_port(dev_priv);
+
+	switch (port) {
+	case PORT_A:
+	case PORT_B:
+	case PORT_C:
+	case PORT_D:
+		return DP_AUX_CH_DATA(port, index);
+	default:
+		MISSING_CASE(port);
+		return DP_AUX_CH_DATA(PORT_A, index);
+	}
+}
+
+static i915_reg_t intel_aux_ctl_reg(struct drm_i915_private *dev_priv,
+					 enum port port)
+{
+	if (INTEL_INFO(dev_priv)->gen >= 9)
+		return skl_aux_ctl_reg(dev_priv, port);
+	else if (HAS_PCH_SPLIT(dev_priv))
+		return ilk_aux_ctl_reg(dev_priv, port);
+	else
+		return g4x_aux_ctl_reg(dev_priv, port);
+}
+
+static i915_reg_t intel_aux_data_reg(struct drm_i915_private *dev_priv,
+					  enum port port, int index)
+{
+	if (INTEL_INFO(dev_priv)->gen >= 9)
+		return skl_aux_data_reg(dev_priv, port, index);
+	else if (HAS_PCH_SPLIT(dev_priv))
+		return ilk_aux_data_reg(dev_priv, port, index);
+	else
+		return g4x_aux_data_reg(dev_priv, port, index);
+}
+
+static void intel_aux_reg_init(struct intel_dp *intel_dp)
+{
+	struct drm_i915_private *dev_priv = to_i915(intel_dp_to_dev(intel_dp));
+	enum port port = dp_to_dig_port(intel_dp)->port;
+	int i;
+
+	intel_dp->aux_ch_ctl_reg = intel_aux_ctl_reg(dev_priv, port);
+	for (i = 0; i < ARRAY_SIZE(intel_dp->aux_ch_data_reg); i++)
+		intel_dp->aux_ch_data_reg[i] = intel_aux_data_reg(dev_priv, port, i);
+}
+
+static void
+intel_dp_aux_fini(struct intel_dp *intel_dp)
+{
+	drm_dp_aux_unregister(&intel_dp->aux);
+	kfree(intel_dp->aux.name);
+}
+
+static int
+intel_dp_aux_init(struct intel_dp *intel_dp, struct intel_connector *connector)
+{
+	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
+	enum port port = intel_dig_port->port;
+	int ret;
+
+	intel_aux_reg_init(intel_dp);
+
+	intel_dp->aux.name = kasprintf(GFP_KERNEL, "DPDDC-%c", port_name(port));
+	if (!intel_dp->aux.name)
+		return -ENOMEM;
+
+	intel_dp->aux.dev = connector->base.kdev;
+	intel_dp->aux.transfer = intel_dp_aux_transfer;
+
+	DRM_DEBUG_KMS("registering %s bus for %s\n",
+		      intel_dp->aux.name,
+		      connector->base.kdev->kobj.name);
+
+	ret = drm_dp_aux_register(&intel_dp->aux);
+	if (ret < 0) {
+		DRM_ERROR("drm_dp_aux_register() for %s failed (%d)\n",
+			  intel_dp->aux.name, ret);
+		kfree(intel_dp->aux.name);
+		return ret;
+	}
+
+	return 0;
+}
+
+static void
+intel_dp_connector_unregister(struct intel_connector *intel_connector)
+{
+	struct intel_dp *intel_dp = intel_attached_dp(&intel_connector->base);
+
+	intel_dp_aux_fini(intel_dp);
+	intel_connector_unregister(intel_connector);
+}
+
+static int
+intel_dp_sink_rates(struct intel_dp *intel_dp, const int **sink_rates)
+{
+	if (intel_dp->num_sink_rates) {
+		*sink_rates = intel_dp->sink_rates;
+		return intel_dp->num_sink_rates;
+	}
+
+	*sink_rates = default_rates;
+
+	return (intel_dp_max_link_bw(intel_dp) >> 3) + 1;
+}
+
+bool intel_dp_source_supports_hbr2(struct intel_dp *intel_dp)
+{
+	struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
+	struct drm_device *dev = dig_port->base.base.dev;
+
+	/* WaDisableHBR2:skl */
+	if (IS_SKL_REVID(dev, 0, SKL_REVID_B0))
+		return false;
+
+	if ((IS_HASWELL(dev) && !IS_HSW_ULX(dev)) || IS_BROADWELL(dev) ||
+	    (INTEL_INFO(dev)->gen >= 9))
+		return true;
+	else
+		return false;
+}
+
+static int
+intel_dp_source_rates(struct intel_dp *intel_dp, const int **source_rates)
+{
+	struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
+	struct drm_device *dev = dig_port->base.base.dev;
+	int size;
+
+	if (IS_BROXTON(dev)) {
+		*source_rates = bxt_rates;
+		size = ARRAY_SIZE(bxt_rates);
+	} else if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev)) {
+		*source_rates = skl_rates;
+		size = ARRAY_SIZE(skl_rates);
+	} else {
+		*source_rates = default_rates;
+		size = ARRAY_SIZE(default_rates);
+	}
+
+	/* This depends on the fact that 5.4 is last value in the array */
+	if (!intel_dp_source_supports_hbr2(intel_dp))
+		size--;
+
+	return size;
+}
+
+static void
+intel_dp_set_clock(struct intel_encoder *encoder,
+		   struct intel_crtc_state *pipe_config)
+{
+	struct drm_device *dev = encoder->base.dev;
+	const struct dp_link_dpll *divisor = NULL;
+	int i, count = 0;
+
+	if (IS_G4X(dev)) {
+		divisor = gen4_dpll;
+		count = ARRAY_SIZE(gen4_dpll);
+	} else if (HAS_PCH_SPLIT(dev)) {
+		divisor = pch_dpll;
+		count = ARRAY_SIZE(pch_dpll);
+	} else if (IS_CHERRYVIEW(dev)) {
+		divisor = chv_dpll;
+		count = ARRAY_SIZE(chv_dpll);
+	} else if (IS_VALLEYVIEW(dev)) {
+		divisor = vlv_dpll;
+		count = ARRAY_SIZE(vlv_dpll);
+	}
+
+	if (divisor && count) {
+		for (i = 0; i < count; i++) {
+			if (pipe_config->port_clock == divisor[i].clock) {
+				pipe_config->dpll = divisor[i].dpll;
+				pipe_config->clock_set = true;
+				break;
+			}
+		}
+	}
+}
+
+static int intersect_rates(const int *source_rates, int source_len,
+			   const int *sink_rates, int sink_len,
+			   int *common_rates)
+{
+	int i = 0, j = 0, k = 0;
+
+	while (i < source_len && j < sink_len) {
+		if (source_rates[i] == sink_rates[j]) {
+			if (WARN_ON(k >= DP_MAX_SUPPORTED_RATES))
+				return k;
+			common_rates[k] = source_rates[i];
+			++k;
+			++i;
+			++j;
+		} else if (source_rates[i] < sink_rates[j]) {
+			++i;
+		} else {
+			++j;
+		}
+	}
+	return k;
+}
+
+static int intel_dp_common_rates(struct intel_dp *intel_dp,
+				 int *common_rates)
+{
+	const int *source_rates, *sink_rates;
+	int source_len, sink_len;
+
+	sink_len = intel_dp_sink_rates(intel_dp, &sink_rates);
+	source_len = intel_dp_source_rates(intel_dp, &source_rates);
+
+	return intersect_rates(source_rates, source_len,
+			       sink_rates, sink_len,
+			       common_rates);
+}
+
+static void snprintf_int_array(char *str, size_t len,
+			       const int *array, int nelem)
+{
+	int i;
+
+	str[0] = '\0';
+
+	for (i = 0; i < nelem; i++) {
+		int r = snprintf(str, len, "%s%d", i ? ", " : "", array[i]);
+		if (r >= len)
+			return;
+		str += r;
+		len -= r;
+	}
+}
+
+static void intel_dp_print_rates(struct intel_dp *intel_dp)
+{
+	const int *source_rates, *sink_rates;
+	int source_len, sink_len, common_len;
+	int common_rates[DP_MAX_SUPPORTED_RATES];
+	char str[128]; /* FIXME: too big for stack? */
+
+	if ((drm_debug & DRM_UT_KMS) == 0)
+		return;
+
+	source_len = intel_dp_source_rates(intel_dp, &source_rates);
+	snprintf_int_array(str, sizeof(str), source_rates, source_len);
+	DRM_DEBUG_KMS("source rates: %s\n", str);
+
+	sink_len = intel_dp_sink_rates(intel_dp, &sink_rates);
+	snprintf_int_array(str, sizeof(str), sink_rates, sink_len);
+	DRM_DEBUG_KMS("sink rates: %s\n", str);
+
+	common_len = intel_dp_common_rates(intel_dp, common_rates);
+	snprintf_int_array(str, sizeof(str), common_rates, common_len);
+	DRM_DEBUG_KMS("common rates: %s\n", str);
+}
+
+static int rate_to_index(int find, const int *rates)
+{
+	int i = 0;
+
+	for (i = 0; i < DP_MAX_SUPPORTED_RATES; ++i)
+		if (find == rates[i])
+			break;
+
+	return i;
+}
+
+int
+intel_dp_max_link_rate(struct intel_dp *intel_dp)
+{
+	int rates[DP_MAX_SUPPORTED_RATES] = {};
+	int len;
+
+	len = intel_dp_common_rates(intel_dp, rates);
+	if (WARN_ON(len <= 0))
+		return 162000;
+
+	return rates[rate_to_index(0, rates) - 1];
+}
+
+int intel_dp_rate_select(struct intel_dp *intel_dp, int rate)
+{
+	return rate_to_index(rate, intel_dp->sink_rates);
+}
+
+void intel_dp_compute_rate(struct intel_dp *intel_dp, int port_clock,
+			   uint8_t *link_bw, uint8_t *rate_select)
+{
+	if (intel_dp->num_sink_rates) {
+		*link_bw = 0;
+		*rate_select =
+			intel_dp_rate_select(intel_dp, port_clock);
+	} else {
+		*link_bw = drm_dp_link_rate_to_bw_code(port_clock);
+		*rate_select = 0;
+	}
+}
+
+bool
+intel_dp_compute_config(struct intel_encoder *encoder,
+			struct intel_crtc_state *pipe_config)
+{
+	struct drm_device *dev = encoder->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
+	struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
+	enum port port = dp_to_dig_port(intel_dp)->port;
+	struct intel_crtc *intel_crtc = to_intel_crtc(pipe_config->base.crtc);
+	struct intel_connector *intel_connector = intel_dp->attached_connector;
+	int lane_count, clock;
+	int min_lane_count = 1;
+	int max_lane_count = intel_dp_max_lane_count(intel_dp);
+	/* Conveniently, the link BW constants become indices with a shift...*/
+	int min_clock = 0;
+	int max_clock;
+	int bpp, mode_rate;
+	int link_avail, link_clock;
+	int common_rates[DP_MAX_SUPPORTED_RATES] = {};
+	int common_len;
+	uint8_t link_bw, rate_select;
+
+	common_len = intel_dp_common_rates(intel_dp, common_rates);
+
+	/* No common link rates between source and sink */
+	WARN_ON(common_len <= 0);
+
+	max_clock = common_len - 1;
+
+	if (HAS_PCH_SPLIT(dev) && !HAS_DDI(dev) && port != PORT_A)
+		pipe_config->has_pch_encoder = true;
+
+	pipe_config->has_dp_encoder = true;
+	pipe_config->has_drrs = false;
+	pipe_config->has_audio = intel_dp->has_audio && port != PORT_A;
+
+	if (is_edp(intel_dp) && intel_connector->panel.fixed_mode) {
+		intel_fixed_panel_mode(intel_connector->panel.fixed_mode,
+				       adjusted_mode);
+
+		if (INTEL_INFO(dev)->gen >= 9) {
+			int ret;
+			ret = skl_update_scaler_crtc(pipe_config);
+			if (ret)
+				return ret;
+		}
+
+		if (HAS_GMCH_DISPLAY(dev))
+			intel_gmch_panel_fitting(intel_crtc, pipe_config,
+						 intel_connector->panel.fitting_mode);
+		else
+			intel_pch_panel_fitting(intel_crtc, pipe_config,
+						intel_connector->panel.fitting_mode);
+	}
+
+	if (adjusted_mode->flags & DRM_MODE_FLAG_DBLCLK)
+		return false;
+
+	DRM_DEBUG_KMS("DP link computation with max lane count %i "
+		      "max bw %d pixel clock %iKHz\n",
+		      max_lane_count, common_rates[max_clock],
+		      adjusted_mode->crtc_clock);
+
+	/* Walk through all bpp values. Luckily they're all nicely spaced with 2
+	 * bpc in between. */
+	bpp = pipe_config->pipe_bpp;
+	if (is_edp(intel_dp)) {
+
+		/* Get bpp from vbt only for panels that dont have bpp in edid */
+		if (intel_connector->base.display_info.bpc == 0 &&
+			(dev_priv->vbt.edp.bpp && dev_priv->vbt.edp.bpp < bpp)) {
+			DRM_DEBUG_KMS("clamping bpp for eDP panel to BIOS-provided %i\n",
+				      dev_priv->vbt.edp.bpp);
+			bpp = dev_priv->vbt.edp.bpp;
+		}
+
+		/*
+		 * Use the maximum clock and number of lanes the eDP panel
+		 * advertizes being capable of. The panels are generally
+		 * designed to support only a single clock and lane
+		 * configuration, and typically these values correspond to the
+		 * native resolution of the panel.
+		 */
+		min_lane_count = max_lane_count;
+		min_clock = max_clock;
+	}
+
+	for (; bpp >= 6*3; bpp -= 2*3) {
+		mode_rate = intel_dp_link_required(adjusted_mode->crtc_clock,
+						   bpp);
+
+		for (clock = min_clock; clock <= max_clock; clock++) {
+			for (lane_count = min_lane_count;
+				lane_count <= max_lane_count;
+				lane_count <<= 1) {
+
+				link_clock = common_rates[clock];
+				link_avail = intel_dp_max_data_rate(link_clock,
+								    lane_count);
+
+				if (mode_rate <= link_avail) {
+					goto found;
+				}
+			}
+		}
+	}
+
+	return false;
+
+found:
+	if (intel_dp->color_range_auto) {
+		/*
+		 * See:
+		 * CEA-861-E - 5.1 Default Encoding Parameters
+		 * VESA DisplayPort Ver.1.2a - 5.1.1.1 Video Colorimetry
+		 */
+		pipe_config->limited_color_range =
+			bpp != 18 && drm_match_cea_mode(adjusted_mode) > 1;
+	} else {
+		pipe_config->limited_color_range =
+			intel_dp->limited_color_range;
+	}
+
+	pipe_config->lane_count = lane_count;
+
+	pipe_config->pipe_bpp = bpp;
+	pipe_config->port_clock = common_rates[clock];
+
+	intel_dp_compute_rate(intel_dp, pipe_config->port_clock,
+			      &link_bw, &rate_select);
+
+	DRM_DEBUG_KMS("DP link bw %02x rate select %02x lane count %d clock %d bpp %d\n",
+		      link_bw, rate_select, pipe_config->lane_count,
+		      pipe_config->port_clock, bpp);
+	DRM_DEBUG_KMS("DP link bw required %i available %i\n",
+		      mode_rate, link_avail);
+
+	intel_link_compute_m_n(bpp, lane_count,
+			       adjusted_mode->crtc_clock,
+			       pipe_config->port_clock,
+			       &pipe_config->dp_m_n);
+
+	if (intel_connector->panel.downclock_mode != NULL &&
+		dev_priv->drrs.type == SEAMLESS_DRRS_SUPPORT) {
+			pipe_config->has_drrs = true;
+			intel_link_compute_m_n(bpp, lane_count,
+				intel_connector->panel.downclock_mode->clock,
+				pipe_config->port_clock,
+				&pipe_config->dp_m2_n2);
+	}
+
+	if (!HAS_DDI(dev))
+		intel_dp_set_clock(encoder, pipe_config);
+
+	return true;
+}
+
+void intel_dp_set_link_params(struct intel_dp *intel_dp,
+			      const struct intel_crtc_state *pipe_config)
+{
+	intel_dp->link_rate = pipe_config->port_clock;
+	intel_dp->lane_count = pipe_config->lane_count;
+}
+
+static void intel_dp_prepare(struct intel_encoder *encoder)
+{
+	struct drm_device *dev = encoder->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
+	enum port port = dp_to_dig_port(intel_dp)->port;
+	struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc);
+	const struct drm_display_mode *adjusted_mode = &crtc->config->base.adjusted_mode;
+
+	intel_dp_set_link_params(intel_dp, crtc->config);
+
+	/*
+	 * There are four kinds of DP registers:
+	 *
+	 * 	IBX PCH
+	 * 	SNB CPU
+	 *	IVB CPU
+	 * 	CPT PCH
+	 *
+	 * IBX PCH and CPU are the same for almost everything,
+	 * except that the CPU DP PLL is configured in this
+	 * register
+	 *
+	 * CPT PCH is quite different, having many bits moved
+	 * to the TRANS_DP_CTL register instead. That
+	 * configuration happens (oddly) in ironlake_pch_enable
+	 */
+
+	/* Preserve the BIOS-computed detected bit. This is
+	 * supposed to be read-only.
+	 */
+	intel_dp->DP = I915_READ(intel_dp->output_reg) & DP_DETECTED;
+
+	/* Handle DP bits in common between all three register formats */
+	intel_dp->DP |= DP_VOLTAGE_0_4 | DP_PRE_EMPHASIS_0;
+	intel_dp->DP |= DP_PORT_WIDTH(crtc->config->lane_count);
+
+	/* Split out the IBX/CPU vs CPT settings */
+
+	if (IS_GEN7(dev) && port == PORT_A) {
+		if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC)
+			intel_dp->DP |= DP_SYNC_HS_HIGH;
+		if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC)
+			intel_dp->DP |= DP_SYNC_VS_HIGH;
+		intel_dp->DP |= DP_LINK_TRAIN_OFF_CPT;
+
+		if (drm_dp_enhanced_frame_cap(intel_dp->dpcd))
+			intel_dp->DP |= DP_ENHANCED_FRAMING;
+
+		intel_dp->DP |= crtc->pipe << 29;
+	} else if (HAS_PCH_CPT(dev) && port != PORT_A) {
+		u32 trans_dp;
+
+		intel_dp->DP |= DP_LINK_TRAIN_OFF_CPT;
+
+		trans_dp = I915_READ(TRANS_DP_CTL(crtc->pipe));
+		if (drm_dp_enhanced_frame_cap(intel_dp->dpcd))
+			trans_dp |= TRANS_DP_ENH_FRAMING;
+		else
+			trans_dp &= ~TRANS_DP_ENH_FRAMING;
+		I915_WRITE(TRANS_DP_CTL(crtc->pipe), trans_dp);
+	} else {
+		if (!HAS_PCH_SPLIT(dev) && !IS_VALLEYVIEW(dev) &&
+		    !IS_CHERRYVIEW(dev) && crtc->config->limited_color_range)
+			intel_dp->DP |= DP_COLOR_RANGE_16_235;
+
+		if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC)
+			intel_dp->DP |= DP_SYNC_HS_HIGH;
+		if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC)
+			intel_dp->DP |= DP_SYNC_VS_HIGH;
+		intel_dp->DP |= DP_LINK_TRAIN_OFF;
+
+		if (drm_dp_enhanced_frame_cap(intel_dp->dpcd))
+			intel_dp->DP |= DP_ENHANCED_FRAMING;
+
+		if (IS_CHERRYVIEW(dev))
+			intel_dp->DP |= DP_PIPE_SELECT_CHV(crtc->pipe);
+		else if (crtc->pipe == PIPE_B)
+			intel_dp->DP |= DP_PIPEB_SELECT;
+	}
+}
+
+#define IDLE_ON_MASK		(PP_ON | PP_SEQUENCE_MASK | 0                     | PP_SEQUENCE_STATE_MASK)
+#define IDLE_ON_VALUE   	(PP_ON | PP_SEQUENCE_NONE | 0                     | PP_SEQUENCE_STATE_ON_IDLE)
+
+#define IDLE_OFF_MASK		(PP_ON | PP_SEQUENCE_MASK | 0                     | 0)
+#define IDLE_OFF_VALUE		(0     | PP_SEQUENCE_NONE | 0                     | 0)
+
+#define IDLE_CYCLE_MASK		(PP_ON | PP_SEQUENCE_MASK | PP_CYCLE_DELAY_ACTIVE | PP_SEQUENCE_STATE_MASK)
+#define IDLE_CYCLE_VALUE	(0     | PP_SEQUENCE_NONE | 0                     | PP_SEQUENCE_STATE_OFF_IDLE)
+
+static void wait_panel_status(struct intel_dp *intel_dp,
+				       u32 mask,
+				       u32 value)
+{
+	struct drm_device *dev = intel_dp_to_dev(intel_dp);
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	i915_reg_t pp_stat_reg, pp_ctrl_reg;
+
+	lockdep_assert_held(&dev_priv->pps_mutex);
+
+	pp_stat_reg = _pp_stat_reg(intel_dp);
+	pp_ctrl_reg = _pp_ctrl_reg(intel_dp);
+
+	DRM_DEBUG_KMS("mask %08x value %08x status %08x control %08x\n",
+			mask, value,
+			I915_READ(pp_stat_reg),
+			I915_READ(pp_ctrl_reg));
+
+	if (_wait_for((I915_READ(pp_stat_reg) & mask) == value,
+		      5 * USEC_PER_SEC, 10 * USEC_PER_MSEC))
+		DRM_ERROR("Panel status timeout: status %08x control %08x\n",
+				I915_READ(pp_stat_reg),
+				I915_READ(pp_ctrl_reg));
+
+	DRM_DEBUG_KMS("Wait complete\n");
+}
+
+static void wait_panel_on(struct intel_dp *intel_dp)
+{
+	DRM_DEBUG_KMS("Wait for panel power on\n");
+	wait_panel_status(intel_dp, IDLE_ON_MASK, IDLE_ON_VALUE);
+}
+
+static void wait_panel_off(struct intel_dp *intel_dp)
+{
+	DRM_DEBUG_KMS("Wait for panel power off time\n");
+	wait_panel_status(intel_dp, IDLE_OFF_MASK, IDLE_OFF_VALUE);
+}
+
+static void wait_panel_power_cycle(struct intel_dp *intel_dp)
+{
+	ktime_t panel_power_on_time;
+	s64 panel_power_off_duration;
+
+	DRM_DEBUG_KMS("Wait for panel power cycle\n");
+
+	/* take the difference of currrent time and panel power off time
+	 * and then make panel wait for t11_t12 if needed. */
+	panel_power_on_time = ktime_get_boottime();
+	panel_power_off_duration = ktime_ms_delta(panel_power_on_time, intel_dp->panel_power_off_time);
+
+	/* When we disable the VDD override bit last we have to do the manual
+	 * wait. */
+	if (panel_power_off_duration < (s64)intel_dp->panel_power_cycle_delay)
+		wait_remaining_ms_from_jiffies(jiffies,
+				       intel_dp->panel_power_cycle_delay - panel_power_off_duration);
+
+	wait_panel_status(intel_dp, IDLE_CYCLE_MASK, IDLE_CYCLE_VALUE);
+}
+
+static void wait_backlight_on(struct intel_dp *intel_dp)
+{
+	wait_remaining_ms_from_jiffies(intel_dp->last_power_on,
+				       intel_dp->backlight_on_delay);
+}
+
+static void edp_wait_backlight_off(struct intel_dp *intel_dp)
+{
+	wait_remaining_ms_from_jiffies(intel_dp->last_backlight_off,
+				       intel_dp->backlight_off_delay);
+}
+
+/* Read the current pp_control value, unlocking the register if it
+ * is locked
+ */
+
+static  u32 ironlake_get_pp_control(struct intel_dp *intel_dp)
+{
+	struct drm_device *dev = intel_dp_to_dev(intel_dp);
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	u32 control;
+
+	lockdep_assert_held(&dev_priv->pps_mutex);
+
+	control = I915_READ(_pp_ctrl_reg(intel_dp));
+	if (!IS_BROXTON(dev)) {
+		control &= ~PANEL_UNLOCK_MASK;
+		control |= PANEL_UNLOCK_REGS;
+	}
+	return control;
+}
+
+/*
+ * Must be paired with edp_panel_vdd_off().
+ * Must hold pps_mutex around the whole on/off sequence.
+ * Can be nested with intel_edp_panel_vdd_{on,off}() calls.
+ */
+static bool edp_panel_vdd_on(struct intel_dp *intel_dp)
+{
+	struct drm_device *dev = intel_dp_to_dev(intel_dp);
+	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
+	struct intel_encoder *intel_encoder = &intel_dig_port->base;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	enum intel_display_power_domain power_domain;
+	u32 pp;
+	i915_reg_t pp_stat_reg, pp_ctrl_reg;
+	bool need_to_disable = !intel_dp->want_panel_vdd;
+
+	lockdep_assert_held(&dev_priv->pps_mutex);
+
+	if (!is_edp(intel_dp))
+		return false;
+
+	cancel_delayed_work(&intel_dp->panel_vdd_work);
+	intel_dp->want_panel_vdd = true;
+
+	if (edp_have_panel_vdd(intel_dp))
+		return need_to_disable;
+
+	power_domain = intel_display_port_aux_power_domain(intel_encoder);
+	intel_display_power_get(dev_priv, power_domain);
+
+	DRM_DEBUG_KMS("Turning eDP port %c VDD on\n",
+		      port_name(intel_dig_port->port));
+
+	if (!edp_have_panel_power(intel_dp))
+		wait_panel_power_cycle(intel_dp);
+
+	pp = ironlake_get_pp_control(intel_dp);
+	pp |= EDP_FORCE_VDD;
+
+	pp_stat_reg = _pp_stat_reg(intel_dp);
+	pp_ctrl_reg = _pp_ctrl_reg(intel_dp);
+
+	I915_WRITE(pp_ctrl_reg, pp);
+	POSTING_READ(pp_ctrl_reg);
+	DRM_DEBUG_KMS("PP_STATUS: 0x%08x PP_CONTROL: 0x%08x\n",
+			I915_READ(pp_stat_reg), I915_READ(pp_ctrl_reg));
+	/*
+	 * If the panel wasn't on, delay before accessing aux channel
+	 */
+	if (!edp_have_panel_power(intel_dp)) {
+		DRM_DEBUG_KMS("eDP port %c panel power wasn't enabled\n",
+			      port_name(intel_dig_port->port));
+		msleep(intel_dp->panel_power_up_delay);
+	}
+
+	return need_to_disable;
+}
+
+/*
+ * Must be paired with intel_edp_panel_vdd_off() or
+ * intel_edp_panel_off().
+ * Nested calls to these functions are not allowed since
+ * we drop the lock. Caller must use some higher level
+ * locking to prevent nested calls from other threads.
+ */
+void intel_edp_panel_vdd_on(struct intel_dp *intel_dp)
+{
+	bool vdd;
+
+	if (!is_edp(intel_dp))
+		return;
+
+	pps_lock(intel_dp);
+	vdd = edp_panel_vdd_on(intel_dp);
+	pps_unlock(intel_dp);
+
+	I915_STATE_WARN(!vdd, "eDP port %c VDD already requested on\n",
+	     port_name(dp_to_dig_port(intel_dp)->port));
+}
+
+static void edp_panel_vdd_off_sync(struct intel_dp *intel_dp)
+{
+	struct drm_device *dev = intel_dp_to_dev(intel_dp);
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_digital_port *intel_dig_port =
+		dp_to_dig_port(intel_dp);
+	struct intel_encoder *intel_encoder = &intel_dig_port->base;
+	enum intel_display_power_domain power_domain;
+	u32 pp;
+	i915_reg_t pp_stat_reg, pp_ctrl_reg;
+
+	lockdep_assert_held(&dev_priv->pps_mutex);
+
+	WARN_ON(intel_dp->want_panel_vdd);
+
+	if (!edp_have_panel_vdd(intel_dp))
+		return;
+
+	DRM_DEBUG_KMS("Turning eDP port %c VDD off\n",
+		      port_name(intel_dig_port->port));
+
+	pp = ironlake_get_pp_control(intel_dp);
+	pp &= ~EDP_FORCE_VDD;
+
+	pp_ctrl_reg = _pp_ctrl_reg(intel_dp);
+	pp_stat_reg = _pp_stat_reg(intel_dp);
+
+	I915_WRITE(pp_ctrl_reg, pp);
+	POSTING_READ(pp_ctrl_reg);
+
+	/* Make sure sequencer is idle before allowing subsequent activity */
+	DRM_DEBUG_KMS("PP_STATUS: 0x%08x PP_CONTROL: 0x%08x\n",
+	I915_READ(pp_stat_reg), I915_READ(pp_ctrl_reg));
+
+	if ((pp & POWER_TARGET_ON) == 0)
+		intel_dp->panel_power_off_time = ktime_get_boottime();
+
+	power_domain = intel_display_port_aux_power_domain(intel_encoder);
+	intel_display_power_put(dev_priv, power_domain);
+}
+
+static void edp_panel_vdd_work(struct work_struct *__work)
+{
+	struct intel_dp *intel_dp = container_of(to_delayed_work(__work),
+						 struct intel_dp, panel_vdd_work);
+
+	pps_lock(intel_dp);
+	if (!intel_dp->want_panel_vdd)
+		edp_panel_vdd_off_sync(intel_dp);
+	pps_unlock(intel_dp);
+}
+
+static void edp_panel_vdd_schedule_off(struct intel_dp *intel_dp)
+{
+	unsigned long delay;
+
+	/*
+	 * Queue the timer to fire a long time from now (relative to the power
+	 * down delay) to keep the panel power up across a sequence of
+	 * operations.
+	 */
+	delay = msecs_to_jiffies(intel_dp->panel_power_cycle_delay * 5);
+	schedule_delayed_work(&intel_dp->panel_vdd_work, delay);
+}
+
+/*
+ * Must be paired with edp_panel_vdd_on().
+ * Must hold pps_mutex around the whole on/off sequence.
+ * Can be nested with intel_edp_panel_vdd_{on,off}() calls.
+ */
+static void edp_panel_vdd_off(struct intel_dp *intel_dp, bool sync)
+{
+	struct drm_i915_private *dev_priv =
+		intel_dp_to_dev(intel_dp)->dev_private;
+
+	lockdep_assert_held(&dev_priv->pps_mutex);
+
+	if (!is_edp(intel_dp))
+		return;
+
+	I915_STATE_WARN(!intel_dp->want_panel_vdd, "eDP port %c VDD not forced on",
+	     port_name(dp_to_dig_port(intel_dp)->port));
+
+	intel_dp->want_panel_vdd = false;
+
+	if (sync)
+		edp_panel_vdd_off_sync(intel_dp);
+	else
+		edp_panel_vdd_schedule_off(intel_dp);
+}
+
+static void edp_panel_on(struct intel_dp *intel_dp)
+{
+	struct drm_device *dev = intel_dp_to_dev(intel_dp);
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	u32 pp;
+	i915_reg_t pp_ctrl_reg;
+
+	lockdep_assert_held(&dev_priv->pps_mutex);
+
+	if (!is_edp(intel_dp))
+		return;
+
+	DRM_DEBUG_KMS("Turn eDP port %c panel power on\n",
+		      port_name(dp_to_dig_port(intel_dp)->port));
+
+	if (WARN(edp_have_panel_power(intel_dp),
+		 "eDP port %c panel power already on\n",
+		 port_name(dp_to_dig_port(intel_dp)->port)))
+		return;
+
+	wait_panel_power_cycle(intel_dp);
+
+	pp_ctrl_reg = _pp_ctrl_reg(intel_dp);
+	pp = ironlake_get_pp_control(intel_dp);
+	if (IS_GEN5(dev)) {
+		/* ILK workaround: disable reset around power sequence */
+		pp &= ~PANEL_POWER_RESET;
+		I915_WRITE(pp_ctrl_reg, pp);
+		POSTING_READ(pp_ctrl_reg);
+	}
+
+	pp |= POWER_TARGET_ON;
+	if (!IS_GEN5(dev))
+		pp |= PANEL_POWER_RESET;
+
+	I915_WRITE(pp_ctrl_reg, pp);
+	POSTING_READ(pp_ctrl_reg);
+
+	wait_panel_on(intel_dp);
+	intel_dp->last_power_on = jiffies;
+
+	if (IS_GEN5(dev)) {
+		pp |= PANEL_POWER_RESET; /* restore panel reset bit */
+		I915_WRITE(pp_ctrl_reg, pp);
+		POSTING_READ(pp_ctrl_reg);
+	}
+}
+
+void intel_edp_panel_on(struct intel_dp *intel_dp)
+{
+	if (!is_edp(intel_dp))
+		return;
+
+	pps_lock(intel_dp);
+	edp_panel_on(intel_dp);
+	pps_unlock(intel_dp);
+}
+
+
+static void edp_panel_off(struct intel_dp *intel_dp)
+{
+	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
+	struct intel_encoder *intel_encoder = &intel_dig_port->base;
+	struct drm_device *dev = intel_dp_to_dev(intel_dp);
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	enum intel_display_power_domain power_domain;
+	u32 pp;
+	i915_reg_t pp_ctrl_reg;
+
+	lockdep_assert_held(&dev_priv->pps_mutex);
+
+	if (!is_edp(intel_dp))
+		return;
+
+	DRM_DEBUG_KMS("Turn eDP port %c panel power off\n",
+		      port_name(dp_to_dig_port(intel_dp)->port));
+
+	WARN(!intel_dp->want_panel_vdd, "Need eDP port %c VDD to turn off panel\n",
+	     port_name(dp_to_dig_port(intel_dp)->port));
+
+	pp = ironlake_get_pp_control(intel_dp);
+	/* We need to switch off panel power _and_ force vdd, for otherwise some
+	 * panels get very unhappy and cease to work. */
+	pp &= ~(POWER_TARGET_ON | PANEL_POWER_RESET | EDP_FORCE_VDD |
+		EDP_BLC_ENABLE);
+
+	pp_ctrl_reg = _pp_ctrl_reg(intel_dp);
+
+	intel_dp->want_panel_vdd = false;
+
+	I915_WRITE(pp_ctrl_reg, pp);
+	POSTING_READ(pp_ctrl_reg);
+
+	intel_dp->panel_power_off_time = ktime_get_boottime();
+	wait_panel_off(intel_dp);
+
+	/* We got a reference when we enabled the VDD. */
+	power_domain = intel_display_port_aux_power_domain(intel_encoder);
+	intel_display_power_put(dev_priv, power_domain);
+}
+
+void intel_edp_panel_off(struct intel_dp *intel_dp)
+{
+	if (!is_edp(intel_dp))
+		return;
+
+	pps_lock(intel_dp);
+	edp_panel_off(intel_dp);
+	pps_unlock(intel_dp);
+}
+
+/* Enable backlight in the panel power control. */
+static void _intel_edp_backlight_on(struct intel_dp *intel_dp)
+{
+	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
+	struct drm_device *dev = intel_dig_port->base.base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	u32 pp;
+	i915_reg_t pp_ctrl_reg;
+
+	/*
+	 * If we enable the backlight right away following a panel power
+	 * on, we may see slight flicker as the panel syncs with the eDP
+	 * link.  So delay a bit to make sure the image is solid before
+	 * allowing it to appear.
+	 */
+	wait_backlight_on(intel_dp);
+
+	pps_lock(intel_dp);
+
+	pp = ironlake_get_pp_control(intel_dp);
+	pp |= EDP_BLC_ENABLE;
+
+	pp_ctrl_reg = _pp_ctrl_reg(intel_dp);
+
+	I915_WRITE(pp_ctrl_reg, pp);
+	POSTING_READ(pp_ctrl_reg);
+
+	pps_unlock(intel_dp);
+}
+
+/* Enable backlight PWM and backlight PP control. */
+void intel_edp_backlight_on(struct intel_dp *intel_dp)
+{
+	if (!is_edp(intel_dp))
+		return;
+
+	DRM_DEBUG_KMS("\n");
+
+	intel_panel_enable_backlight(intel_dp->attached_connector);
+	_intel_edp_backlight_on(intel_dp);
+}
+
+/* Disable backlight in the panel power control. */
+static void _intel_edp_backlight_off(struct intel_dp *intel_dp)
+{
+	struct drm_device *dev = intel_dp_to_dev(intel_dp);
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	u32 pp;
+	i915_reg_t pp_ctrl_reg;
+
+	if (!is_edp(intel_dp))
+		return;
+
+	pps_lock(intel_dp);
+
+	pp = ironlake_get_pp_control(intel_dp);
+	pp &= ~EDP_BLC_ENABLE;
+
+	pp_ctrl_reg = _pp_ctrl_reg(intel_dp);
+
+	I915_WRITE(pp_ctrl_reg, pp);
+	POSTING_READ(pp_ctrl_reg);
+
+	pps_unlock(intel_dp);
+
+	intel_dp->last_backlight_off = jiffies;
+	edp_wait_backlight_off(intel_dp);
+}
+
+/* Disable backlight PP control and backlight PWM. */
+void intel_edp_backlight_off(struct intel_dp *intel_dp)
+{
+	if (!is_edp(intel_dp))
+		return;
+
+	DRM_DEBUG_KMS("\n");
+
+	_intel_edp_backlight_off(intel_dp);
+	intel_panel_disable_backlight(intel_dp->attached_connector);
+}
+
+/*
+ * Hook for controlling the panel power control backlight through the bl_power
+ * sysfs attribute. Take care to handle multiple calls.
+ */
+static void intel_edp_backlight_power(struct intel_connector *connector,
+				      bool enable)
+{
+	struct intel_dp *intel_dp = intel_attached_dp(&connector->base);
+	bool is_enabled;
+
+	pps_lock(intel_dp);
+	is_enabled = ironlake_get_pp_control(intel_dp) & EDP_BLC_ENABLE;
+	pps_unlock(intel_dp);
+
+	if (is_enabled == enable)
+		return;
+
+	DRM_DEBUG_KMS("panel power control backlight %s\n",
+		      enable ? "enable" : "disable");
+
+	if (enable)
+		_intel_edp_backlight_on(intel_dp);
+	else
+		_intel_edp_backlight_off(intel_dp);
+}
+
+static void assert_dp_port(struct intel_dp *intel_dp, bool state)
+{
+	struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
+	struct drm_i915_private *dev_priv = to_i915(dig_port->base.base.dev);
+	bool cur_state = I915_READ(intel_dp->output_reg) & DP_PORT_EN;
+
+	I915_STATE_WARN(cur_state != state,
+			"DP port %c state assertion failure (expected %s, current %s)\n",
+			port_name(dig_port->port),
+			onoff(state), onoff(cur_state));
+}
+#define assert_dp_port_disabled(d) assert_dp_port((d), false)
+
+static void assert_edp_pll(struct drm_i915_private *dev_priv, bool state)
+{
+	bool cur_state = I915_READ(DP_A) & DP_PLL_ENABLE;
+
+	I915_STATE_WARN(cur_state != state,
+			"eDP PLL state assertion failure (expected %s, current %s)\n",
+			onoff(state), onoff(cur_state));
+}
+#define assert_edp_pll_enabled(d) assert_edp_pll((d), true)
+#define assert_edp_pll_disabled(d) assert_edp_pll((d), false)
+
+static void ironlake_edp_pll_on(struct intel_dp *intel_dp)
+{
+	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
+	struct intel_crtc *crtc = to_intel_crtc(intel_dig_port->base.base.crtc);
+	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
+
+	assert_pipe_disabled(dev_priv, crtc->pipe);
+	assert_dp_port_disabled(intel_dp);
+	assert_edp_pll_disabled(dev_priv);
+
+	DRM_DEBUG_KMS("enabling eDP PLL for clock %d\n",
+		      crtc->config->port_clock);
+
+	intel_dp->DP &= ~DP_PLL_FREQ_MASK;
+
+	if (crtc->config->port_clock == 162000)
+		intel_dp->DP |= DP_PLL_FREQ_162MHZ;
+	else
+		intel_dp->DP |= DP_PLL_FREQ_270MHZ;
+
+	I915_WRITE(DP_A, intel_dp->DP);
+	POSTING_READ(DP_A);
+	udelay(500);
+
+	/*
+	 * [DevILK] Work around required when enabling DP PLL
+	 * while a pipe is enabled going to FDI:
+	 * 1. Wait for the start of vertical blank on the enabled pipe going to FDI
+	 * 2. Program DP PLL enable
+	 */
+	if (IS_GEN5(dev_priv))
+		intel_wait_for_vblank_if_active(dev_priv->dev, !crtc->pipe);
+
+	intel_dp->DP |= DP_PLL_ENABLE;
+
+	I915_WRITE(DP_A, intel_dp->DP);
+	POSTING_READ(DP_A);
+	udelay(200);
+}
+
+static void ironlake_edp_pll_off(struct intel_dp *intel_dp)
+{
+	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
+	struct intel_crtc *crtc = to_intel_crtc(intel_dig_port->base.base.crtc);
+	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
+
+	assert_pipe_disabled(dev_priv, crtc->pipe);
+	assert_dp_port_disabled(intel_dp);
+	assert_edp_pll_enabled(dev_priv);
+
+	DRM_DEBUG_KMS("disabling eDP PLL\n");
+
+	intel_dp->DP &= ~DP_PLL_ENABLE;
+
+	I915_WRITE(DP_A, intel_dp->DP);
+	POSTING_READ(DP_A);
+	udelay(200);
+}
+
+/* If the sink supports it, try to set the power state appropriately */
+void intel_dp_sink_dpms(struct intel_dp *intel_dp, int mode)
+{
+	int ret, i;
+
+	/* Should have a valid DPCD by this point */
+	if (intel_dp->dpcd[DP_DPCD_REV] < 0x11)
+		return;
+
+	if (mode != DRM_MODE_DPMS_ON) {
+		ret = drm_dp_dpcd_writeb(&intel_dp->aux, DP_SET_POWER,
+					 DP_SET_POWER_D3);
+	} else {
+		/*
+		 * When turning on, we need to retry for 1ms to give the sink
+		 * time to wake up.
+		 */
+		for (i = 0; i < 3; i++) {
+			ret = drm_dp_dpcd_writeb(&intel_dp->aux, DP_SET_POWER,
+						 DP_SET_POWER_D0);
+			if (ret == 1)
+				break;
+			msleep(1);
+		}
+	}
+
+	if (ret != 1)
+		DRM_DEBUG_KMS("failed to %s sink power state\n",
+			      mode == DRM_MODE_DPMS_ON ? "enable" : "disable");
+}
+
+static bool intel_dp_get_hw_state(struct intel_encoder *encoder,
+				  enum pipe *pipe)
+{
+	struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
+	enum port port = dp_to_dig_port(intel_dp)->port;
+	struct drm_device *dev = encoder->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	enum intel_display_power_domain power_domain;
+	u32 tmp;
+	bool ret;
+
+	power_domain = intel_display_port_power_domain(encoder);
+	if (!intel_display_power_get_if_enabled(dev_priv, power_domain))
+		return false;
+
+	ret = false;
+
+	tmp = I915_READ(intel_dp->output_reg);
+
+	if (!(tmp & DP_PORT_EN))
+		goto out;
+
+	if (IS_GEN7(dev) && port == PORT_A) {
+		*pipe = PORT_TO_PIPE_CPT(tmp);
+	} else if (HAS_PCH_CPT(dev) && port != PORT_A) {
+		enum pipe p;
+
+		for_each_pipe(dev_priv, p) {
+			u32 trans_dp = I915_READ(TRANS_DP_CTL(p));
+			if (TRANS_DP_PIPE_TO_PORT(trans_dp) == port) {
+				*pipe = p;
+				ret = true;
+
+				goto out;
+			}
+		}
+
+		DRM_DEBUG_KMS("No pipe for dp port 0x%x found\n",
+			      i915_mmio_reg_offset(intel_dp->output_reg));
+	} else if (IS_CHERRYVIEW(dev)) {
+		*pipe = DP_PORT_TO_PIPE_CHV(tmp);
+	} else {
+		*pipe = PORT_TO_PIPE(tmp);
+	}
+
+	ret = true;
+
+out:
+	intel_display_power_put(dev_priv, power_domain);
+
+	return ret;
+}
+
+static void intel_dp_get_config(struct intel_encoder *encoder,
+				struct intel_crtc_state *pipe_config)
+{
+	struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
+	u32 tmp, flags = 0;
+	struct drm_device *dev = encoder->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	enum port port = dp_to_dig_port(intel_dp)->port;
+	struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc);
+
+	tmp = I915_READ(intel_dp->output_reg);
+
+	pipe_config->has_audio = tmp & DP_AUDIO_OUTPUT_ENABLE && port != PORT_A;
+
+	if (HAS_PCH_CPT(dev) && port != PORT_A) {
+		u32 trans_dp = I915_READ(TRANS_DP_CTL(crtc->pipe));
+
+		if (trans_dp & TRANS_DP_HSYNC_ACTIVE_HIGH)
+			flags |= DRM_MODE_FLAG_PHSYNC;
+		else
+			flags |= DRM_MODE_FLAG_NHSYNC;
+
+		if (trans_dp & TRANS_DP_VSYNC_ACTIVE_HIGH)
+			flags |= DRM_MODE_FLAG_PVSYNC;
+		else
+			flags |= DRM_MODE_FLAG_NVSYNC;
+	} else {
+		if (tmp & DP_SYNC_HS_HIGH)
+			flags |= DRM_MODE_FLAG_PHSYNC;
+		else
+			flags |= DRM_MODE_FLAG_NHSYNC;
+
+		if (tmp & DP_SYNC_VS_HIGH)
+			flags |= DRM_MODE_FLAG_PVSYNC;
+		else
+			flags |= DRM_MODE_FLAG_NVSYNC;
+	}
+
+	pipe_config->base.adjusted_mode.flags |= flags;
+
+	if (!HAS_PCH_SPLIT(dev) && !IS_VALLEYVIEW(dev) &&
+	    !IS_CHERRYVIEW(dev) && tmp & DP_COLOR_RANGE_16_235)
+		pipe_config->limited_color_range = true;
+
+	pipe_config->has_dp_encoder = true;
+
+	pipe_config->lane_count =
+		((tmp & DP_PORT_WIDTH_MASK) >> DP_PORT_WIDTH_SHIFT) + 1;
+
+	intel_dp_get_m_n(crtc, pipe_config);
+
+	if (port == PORT_A) {
+		if ((I915_READ(DP_A) & DP_PLL_FREQ_MASK) == DP_PLL_FREQ_162MHZ)
+			pipe_config->port_clock = 162000;
+		else
+			pipe_config->port_clock = 270000;
+	}
+
+	pipe_config->base.adjusted_mode.crtc_clock =
+		intel_dotclock_calculate(pipe_config->port_clock,
+					 &pipe_config->dp_m_n);
+
+	if (is_edp(intel_dp) && dev_priv->vbt.edp.bpp &&
+	    pipe_config->pipe_bpp > dev_priv->vbt.edp.bpp) {
+		/*
+		 * This is a big fat ugly hack.
+		 *
+		 * Some machines in UEFI boot mode provide us a VBT that has 18
+		 * bpp and 1.62 GHz link bandwidth for eDP, which for reasons
+		 * unknown we fail to light up. Yet the same BIOS boots up with
+		 * 24 bpp and 2.7 GHz link. Use the same bpp as the BIOS uses as
+		 * max, not what it tells us to use.
+		 *
+		 * Note: This will still be broken if the eDP panel is not lit
+		 * up by the BIOS, and thus we can't get the mode at module
+		 * load.
+		 */
+		DRM_DEBUG_KMS("pipe has %d bpp for eDP panel, overriding BIOS-provided max %d bpp\n",
+			      pipe_config->pipe_bpp, dev_priv->vbt.edp.bpp);
+		dev_priv->vbt.edp.bpp = pipe_config->pipe_bpp;
+	}
+}
+
+static void intel_disable_dp(struct intel_encoder *encoder)
+{
+	struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
+	struct drm_device *dev = encoder->base.dev;
+	struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc);
+
+	if (crtc->config->has_audio)
+		intel_audio_codec_disable(encoder);
+
+	if (HAS_PSR(dev) && !HAS_DDI(dev))
+		intel_psr_disable(intel_dp);
+
+	/* Make sure the panel is off before trying to change the mode. But also
+	 * ensure that we have vdd while we switch off the panel. */
+	intel_edp_panel_vdd_on(intel_dp);
+	intel_edp_backlight_off(intel_dp);
+	intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF);
+	intel_edp_panel_off(intel_dp);
+
+	/* disable the port before the pipe on g4x */
+	if (INTEL_INFO(dev)->gen < 5)
+		intel_dp_link_down(intel_dp);
+}
+
+static void ilk_post_disable_dp(struct intel_encoder *encoder)
+{
+	struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
+	enum port port = dp_to_dig_port(intel_dp)->port;
+
+	intel_dp_link_down(intel_dp);
+
+	/* Only ilk+ has port A */
+	if (port == PORT_A)
+		ironlake_edp_pll_off(intel_dp);
+}
+
+static void vlv_post_disable_dp(struct intel_encoder *encoder)
+{
+	struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
+
+	intel_dp_link_down(intel_dp);
+}
+
+static void chv_data_lane_soft_reset(struct intel_encoder *encoder,
+				     bool reset)
+{
+	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
+	enum dpio_channel ch = vlv_dport_to_channel(enc_to_dig_port(&encoder->base));
+	struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc);
+	enum pipe pipe = crtc->pipe;
+	uint32_t val;
+
+	val = vlv_dpio_read(dev_priv, pipe, VLV_PCS01_DW0(ch));
+	if (reset)
+		val &= ~(DPIO_PCS_TX_LANE2_RESET | DPIO_PCS_TX_LANE1_RESET);
+	else
+		val |= DPIO_PCS_TX_LANE2_RESET | DPIO_PCS_TX_LANE1_RESET;
+	vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW0(ch), val);
+
+	if (crtc->config->lane_count > 2) {
+		val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW0(ch));
+		if (reset)
+			val &= ~(DPIO_PCS_TX_LANE2_RESET | DPIO_PCS_TX_LANE1_RESET);
+		else
+			val |= DPIO_PCS_TX_LANE2_RESET | DPIO_PCS_TX_LANE1_RESET;
+		vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW0(ch), val);
+	}
+
+	val = vlv_dpio_read(dev_priv, pipe, VLV_PCS01_DW1(ch));
+	val |= CHV_PCS_REQ_SOFTRESET_EN;
+	if (reset)
+		val &= ~DPIO_PCS_CLK_SOFT_RESET;
+	else
+		val |= DPIO_PCS_CLK_SOFT_RESET;
+	vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW1(ch), val);
+
+	if (crtc->config->lane_count > 2) {
+		val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW1(ch));
+		val |= CHV_PCS_REQ_SOFTRESET_EN;
+		if (reset)
+			val &= ~DPIO_PCS_CLK_SOFT_RESET;
+		else
+			val |= DPIO_PCS_CLK_SOFT_RESET;
+		vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW1(ch), val);
+	}
+}
+
+static void chv_post_disable_dp(struct intel_encoder *encoder)
+{
+	struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
+	struct drm_device *dev = encoder->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	intel_dp_link_down(intel_dp);
+
+	mutex_lock(&dev_priv->sb_lock);
+
+	/* Assert data lane reset */
+	chv_data_lane_soft_reset(encoder, true);
+
+	mutex_unlock(&dev_priv->sb_lock);
+}
+
+static void
+_intel_dp_set_link_train(struct intel_dp *intel_dp,
+			 uint32_t *DP,
+			 uint8_t dp_train_pat)
+{
+	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
+	struct drm_device *dev = intel_dig_port->base.base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	enum port port = intel_dig_port->port;
+
+	if (HAS_DDI(dev)) {
+		uint32_t temp = I915_READ(DP_TP_CTL(port));
+
+		if (dp_train_pat & DP_LINK_SCRAMBLING_DISABLE)
+			temp |= DP_TP_CTL_SCRAMBLE_DISABLE;
+		else
+			temp &= ~DP_TP_CTL_SCRAMBLE_DISABLE;
+
+		temp &= ~DP_TP_CTL_LINK_TRAIN_MASK;
+		switch (dp_train_pat & DP_TRAINING_PATTERN_MASK) {
+		case DP_TRAINING_PATTERN_DISABLE:
+			temp |= DP_TP_CTL_LINK_TRAIN_NORMAL;
+
+			break;
+		case DP_TRAINING_PATTERN_1:
+			temp |= DP_TP_CTL_LINK_TRAIN_PAT1;
+			break;
+		case DP_TRAINING_PATTERN_2:
+			temp |= DP_TP_CTL_LINK_TRAIN_PAT2;
+			break;
+		case DP_TRAINING_PATTERN_3:
+			temp |= DP_TP_CTL_LINK_TRAIN_PAT3;
+			break;
+		}
+		I915_WRITE(DP_TP_CTL(port), temp);
+
+	} else if ((IS_GEN7(dev) && port == PORT_A) ||
+		   (HAS_PCH_CPT(dev) && port != PORT_A)) {
+		*DP &= ~DP_LINK_TRAIN_MASK_CPT;
+
+		switch (dp_train_pat & DP_TRAINING_PATTERN_MASK) {
+		case DP_TRAINING_PATTERN_DISABLE:
+			*DP |= DP_LINK_TRAIN_OFF_CPT;
+			break;
+		case DP_TRAINING_PATTERN_1:
+			*DP |= DP_LINK_TRAIN_PAT_1_CPT;
+			break;
+		case DP_TRAINING_PATTERN_2:
+			*DP |= DP_LINK_TRAIN_PAT_2_CPT;
+			break;
+		case DP_TRAINING_PATTERN_3:
+			DRM_ERROR("DP training pattern 3 not supported\n");
+			*DP |= DP_LINK_TRAIN_PAT_2_CPT;
+			break;
+		}
+
+	} else {
+		if (IS_CHERRYVIEW(dev))
+			*DP &= ~DP_LINK_TRAIN_MASK_CHV;
+		else
+			*DP &= ~DP_LINK_TRAIN_MASK;
+
+		switch (dp_train_pat & DP_TRAINING_PATTERN_MASK) {
+		case DP_TRAINING_PATTERN_DISABLE:
+			*DP |= DP_LINK_TRAIN_OFF;
+			break;
+		case DP_TRAINING_PATTERN_1:
+			*DP |= DP_LINK_TRAIN_PAT_1;
+			break;
+		case DP_TRAINING_PATTERN_2:
+			*DP |= DP_LINK_TRAIN_PAT_2;
+			break;
+		case DP_TRAINING_PATTERN_3:
+			if (IS_CHERRYVIEW(dev)) {
+				*DP |= DP_LINK_TRAIN_PAT_3_CHV;
+			} else {
+				DRM_ERROR("DP training pattern 3 not supported\n");
+				*DP |= DP_LINK_TRAIN_PAT_2;
+			}
+			break;
+		}
+	}
+}
+
+static void intel_dp_enable_port(struct intel_dp *intel_dp)
+{
+	struct drm_device *dev = intel_dp_to_dev(intel_dp);
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_crtc *crtc =
+		to_intel_crtc(dp_to_dig_port(intel_dp)->base.base.crtc);
+
+	/* enable with pattern 1 (as per spec) */
+	_intel_dp_set_link_train(intel_dp, &intel_dp->DP,
+				 DP_TRAINING_PATTERN_1);
+
+	I915_WRITE(intel_dp->output_reg, intel_dp->DP);
+	POSTING_READ(intel_dp->output_reg);
+
+	/*
+	 * Magic for VLV/CHV. We _must_ first set up the register
+	 * without actually enabling the port, and then do another
+	 * write to enable the port. Otherwise link training will
+	 * fail when the power sequencer is freshly used for this port.
+	 */
+	intel_dp->DP |= DP_PORT_EN;
+	if (crtc->config->has_audio)
+		intel_dp->DP |= DP_AUDIO_OUTPUT_ENABLE;
+
+	I915_WRITE(intel_dp->output_reg, intel_dp->DP);
+	POSTING_READ(intel_dp->output_reg);
+}
+
+static void intel_enable_dp(struct intel_encoder *encoder)
+{
+	struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
+	struct drm_device *dev = encoder->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc);
+	uint32_t dp_reg = I915_READ(intel_dp->output_reg);
+	enum pipe pipe = crtc->pipe;
+
+	if (WARN_ON(dp_reg & DP_PORT_EN))
+		return;
+
+	pps_lock(intel_dp);
+
+	if (IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev))
+		vlv_init_panel_power_sequencer(intel_dp);
+
+	intel_dp_enable_port(intel_dp);
+
+	edp_panel_vdd_on(intel_dp);
+	edp_panel_on(intel_dp);
+	edp_panel_vdd_off(intel_dp, true);
+
+	pps_unlock(intel_dp);
+
+	if (IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev)) {
+		unsigned int lane_mask = 0x0;
+
+		if (IS_CHERRYVIEW(dev))
+			lane_mask = intel_dp_unused_lane_mask(crtc->config->lane_count);
+
+		vlv_wait_port_ready(dev_priv, dp_to_dig_port(intel_dp),
+				    lane_mask);
+	}
+
+	intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON);
+	intel_dp_start_link_train(intel_dp);
+	intel_dp_stop_link_train(intel_dp);
+
+	if (crtc->config->has_audio) {
+		DRM_DEBUG_DRIVER("Enabling DP audio on pipe %c\n",
+				 pipe_name(pipe));
+		intel_audio_codec_enable(encoder);
+	}
+}
+
+static void g4x_enable_dp(struct intel_encoder *encoder)
+{
+	struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
+
+	intel_enable_dp(encoder);
+	intel_edp_backlight_on(intel_dp);
+}
+
+static void vlv_enable_dp(struct intel_encoder *encoder)
+{
+	struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
+
+	intel_edp_backlight_on(intel_dp);
+	intel_psr_enable(intel_dp);
+}
+
+static void g4x_pre_enable_dp(struct intel_encoder *encoder)
+{
+	struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
+	enum port port = dp_to_dig_port(intel_dp)->port;
+
+	intel_dp_prepare(encoder);
+
+	/* Only ilk+ has port A */
+	if (port == PORT_A)
+		ironlake_edp_pll_on(intel_dp);
+}
+
+static void vlv_detach_power_sequencer(struct intel_dp *intel_dp)
+{
+	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
+	struct drm_i915_private *dev_priv = intel_dig_port->base.base.dev->dev_private;
+	enum pipe pipe = intel_dp->pps_pipe;
+	i915_reg_t pp_on_reg = VLV_PIPE_PP_ON_DELAYS(pipe);
+
+	edp_panel_vdd_off_sync(intel_dp);
+
+	/*
+	 * VLV seems to get confused when multiple power seqeuencers
+	 * have the same port selected (even if only one has power/vdd
+	 * enabled). The failure manifests as vlv_wait_port_ready() failing
+	 * CHV on the other hand doesn't seem to mind having the same port
+	 * selected in multiple power seqeuencers, but let's clear the
+	 * port select always when logically disconnecting a power sequencer
+	 * from a port.
+	 */
+	DRM_DEBUG_KMS("detaching pipe %c power sequencer from port %c\n",
+		      pipe_name(pipe), port_name(intel_dig_port->port));
+	I915_WRITE(pp_on_reg, 0);
+	POSTING_READ(pp_on_reg);
+
+	intel_dp->pps_pipe = INVALID_PIPE;
+}
+
+static void vlv_steal_power_sequencer(struct drm_device *dev,
+				      enum pipe pipe)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_encoder *encoder;
+
+	lockdep_assert_held(&dev_priv->pps_mutex);
+
+	if (WARN_ON(pipe != PIPE_A && pipe != PIPE_B))
+		return;
+
+	for_each_intel_encoder(dev, encoder) {
+		struct intel_dp *intel_dp;
+		enum port port;
+
+		if (encoder->type != INTEL_OUTPUT_EDP)
+			continue;
+
+		intel_dp = enc_to_intel_dp(&encoder->base);
+		port = dp_to_dig_port(intel_dp)->port;
+
+		if (intel_dp->pps_pipe != pipe)
+			continue;
+
+		DRM_DEBUG_KMS("stealing pipe %c power sequencer from port %c\n",
+			      pipe_name(pipe), port_name(port));
+
+		WARN(encoder->base.crtc,
+		     "stealing pipe %c power sequencer from active eDP port %c\n",
+		     pipe_name(pipe), port_name(port));
+
+		/* make sure vdd is off before we steal it */
+		vlv_detach_power_sequencer(intel_dp);
+	}
+}
+
+static void vlv_init_panel_power_sequencer(struct intel_dp *intel_dp)
+{
+	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
+	struct intel_encoder *encoder = &intel_dig_port->base;
+	struct drm_device *dev = encoder->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc);
+
+	lockdep_assert_held(&dev_priv->pps_mutex);
+
+	if (!is_edp(intel_dp))
+		return;
+
+	if (intel_dp->pps_pipe == crtc->pipe)
+		return;
+
+	/*
+	 * If another power sequencer was being used on this
+	 * port previously make sure to turn off vdd there while
+	 * we still have control of it.
+	 */
+	if (intel_dp->pps_pipe != INVALID_PIPE)
+		vlv_detach_power_sequencer(intel_dp);
+
+	/*
+	 * We may be stealing the power
+	 * sequencer from another port.
+	 */
+	vlv_steal_power_sequencer(dev, crtc->pipe);
+
+	/* now it's all ours */
+	intel_dp->pps_pipe = crtc->pipe;
+
+	DRM_DEBUG_KMS("initializing pipe %c power sequencer for port %c\n",
+		      pipe_name(intel_dp->pps_pipe), port_name(intel_dig_port->port));
+
+	/* init power sequencer on this pipe and port */
+	intel_dp_init_panel_power_sequencer(dev, intel_dp);
+	intel_dp_init_panel_power_sequencer_registers(dev, intel_dp);
+}
+
+static void vlv_pre_enable_dp(struct intel_encoder *encoder)
+{
+	struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
+	struct intel_digital_port *dport = dp_to_dig_port(intel_dp);
+	struct drm_device *dev = encoder->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc);
+	enum dpio_channel port = vlv_dport_to_channel(dport);
+	int pipe = intel_crtc->pipe;
+	u32 val;
+
+	mutex_lock(&dev_priv->sb_lock);
+
+	val = vlv_dpio_read(dev_priv, pipe, VLV_PCS01_DW8(port));
+	val = 0;
+	if (pipe)
+		val |= (1<<21);
+	else
+		val &= ~(1<<21);
+	val |= 0x001000c4;
+	vlv_dpio_write(dev_priv, pipe, VLV_PCS_DW8(port), val);
+	vlv_dpio_write(dev_priv, pipe, VLV_PCS_DW14(port), 0x00760018);
+	vlv_dpio_write(dev_priv, pipe, VLV_PCS_DW23(port), 0x00400888);
+
+	mutex_unlock(&dev_priv->sb_lock);
+
+	intel_enable_dp(encoder);
+}
+
+static void vlv_dp_pre_pll_enable(struct intel_encoder *encoder)
+{
+	struct intel_digital_port *dport = enc_to_dig_port(&encoder->base);
+	struct drm_device *dev = encoder->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_crtc *intel_crtc =
+		to_intel_crtc(encoder->base.crtc);
+	enum dpio_channel port = vlv_dport_to_channel(dport);
+	int pipe = intel_crtc->pipe;
+
+	intel_dp_prepare(encoder);
+
+	/* Program Tx lane resets to default */
+	mutex_lock(&dev_priv->sb_lock);
+	vlv_dpio_write(dev_priv, pipe, VLV_PCS_DW0(port),
+			 DPIO_PCS_TX_LANE2_RESET |
+			 DPIO_PCS_TX_LANE1_RESET);
+	vlv_dpio_write(dev_priv, pipe, VLV_PCS_DW1(port),
+			 DPIO_PCS_CLK_CRI_RXEB_EIOS_EN |
+			 DPIO_PCS_CLK_CRI_RXDIGFILTSG_EN |
+			 (1<<DPIO_PCS_CLK_DATAWIDTH_SHIFT) |
+				 DPIO_PCS_CLK_SOFT_RESET);
+
+	/* Fix up inter-pair skew failure */
+	vlv_dpio_write(dev_priv, pipe, VLV_PCS_DW12(port), 0x00750f00);
+	vlv_dpio_write(dev_priv, pipe, VLV_TX_DW11(port), 0x00001500);
+	vlv_dpio_write(dev_priv, pipe, VLV_TX_DW14(port), 0x40400000);
+	mutex_unlock(&dev_priv->sb_lock);
+}
+
+static void chv_pre_enable_dp(struct intel_encoder *encoder)
+{
+	struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
+	struct intel_digital_port *dport = dp_to_dig_port(intel_dp);
+	struct drm_device *dev = encoder->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_crtc *intel_crtc =
+		to_intel_crtc(encoder->base.crtc);
+	enum dpio_channel ch = vlv_dport_to_channel(dport);
+	int pipe = intel_crtc->pipe;
+	int data, i, stagger;
+	u32 val;
+
+	mutex_lock(&dev_priv->sb_lock);
+
+	/* allow hardware to manage TX FIFO reset source */
+	val = vlv_dpio_read(dev_priv, pipe, VLV_PCS01_DW11(ch));
+	val &= ~DPIO_LANEDESKEW_STRAP_OVRD;
+	vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW11(ch), val);
+
+	if (intel_crtc->config->lane_count > 2) {
+		val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW11(ch));
+		val &= ~DPIO_LANEDESKEW_STRAP_OVRD;
+		vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW11(ch), val);
+	}
+
+	/* Program Tx lane latency optimal setting*/
+	for (i = 0; i < intel_crtc->config->lane_count; i++) {
+		/* Set the upar bit */
+		if (intel_crtc->config->lane_count == 1)
+			data = 0x0;
+		else
+			data = (i == 1) ? 0x0 : 0x1;
+		vlv_dpio_write(dev_priv, pipe, CHV_TX_DW14(ch, i),
+				data << DPIO_UPAR_SHIFT);
+	}
+
+	/* Data lane stagger programming */
+	if (intel_crtc->config->port_clock > 270000)
+		stagger = 0x18;
+	else if (intel_crtc->config->port_clock > 135000)
+		stagger = 0xd;
+	else if (intel_crtc->config->port_clock > 67500)
+		stagger = 0x7;
+	else if (intel_crtc->config->port_clock > 33750)
+		stagger = 0x4;
+	else
+		stagger = 0x2;
+
+	val = vlv_dpio_read(dev_priv, pipe, VLV_PCS01_DW11(ch));
+	val |= DPIO_TX2_STAGGER_MASK(0x1f);
+	vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW11(ch), val);
+
+	if (intel_crtc->config->lane_count > 2) {
+		val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW11(ch));
+		val |= DPIO_TX2_STAGGER_MASK(0x1f);
+		vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW11(ch), val);
+	}
+
+	vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW12(ch),
+		       DPIO_LANESTAGGER_STRAP(stagger) |
+		       DPIO_LANESTAGGER_STRAP_OVRD |
+		       DPIO_TX1_STAGGER_MASK(0x1f) |
+		       DPIO_TX1_STAGGER_MULT(6) |
+		       DPIO_TX2_STAGGER_MULT(0));
+
+	if (intel_crtc->config->lane_count > 2) {
+		vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW12(ch),
+			       DPIO_LANESTAGGER_STRAP(stagger) |
+			       DPIO_LANESTAGGER_STRAP_OVRD |
+			       DPIO_TX1_STAGGER_MASK(0x1f) |
+			       DPIO_TX1_STAGGER_MULT(7) |
+			       DPIO_TX2_STAGGER_MULT(5));
+	}
+
+	/* Deassert data lane reset */
+	chv_data_lane_soft_reset(encoder, false);
+
+	mutex_unlock(&dev_priv->sb_lock);
+
+	intel_enable_dp(encoder);
+
+	/* Second common lane will stay alive on its own now */
+	if (dport->release_cl2_override) {
+		chv_phy_powergate_ch(dev_priv, DPIO_PHY0, DPIO_CH1, false);
+		dport->release_cl2_override = false;
+	}
+}
+
+static void chv_dp_pre_pll_enable(struct intel_encoder *encoder)
+{
+	struct intel_digital_port *dport = enc_to_dig_port(&encoder->base);
+	struct drm_device *dev = encoder->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_crtc *intel_crtc =
+		to_intel_crtc(encoder->base.crtc);
+	enum dpio_channel ch = vlv_dport_to_channel(dport);
+	enum pipe pipe = intel_crtc->pipe;
+	unsigned int lane_mask =
+		intel_dp_unused_lane_mask(intel_crtc->config->lane_count);
+	u32 val;
+
+	intel_dp_prepare(encoder);
+
+	/*
+	 * Must trick the second common lane into life.
+	 * Otherwise we can't even access the PLL.
+	 */
+	if (ch == DPIO_CH0 && pipe == PIPE_B)
+		dport->release_cl2_override =
+			!chv_phy_powergate_ch(dev_priv, DPIO_PHY0, DPIO_CH1, true);
+
+	chv_phy_powergate_lanes(encoder, true, lane_mask);
+
+	mutex_lock(&dev_priv->sb_lock);
+
+	/* Assert data lane reset */
+	chv_data_lane_soft_reset(encoder, true);
+
+	/* program left/right clock distribution */
+	if (pipe != PIPE_B) {
+		val = vlv_dpio_read(dev_priv, pipe, _CHV_CMN_DW5_CH0);
+		val &= ~(CHV_BUFLEFTENA1_MASK | CHV_BUFRIGHTENA1_MASK);
+		if (ch == DPIO_CH0)
+			val |= CHV_BUFLEFTENA1_FORCE;
+		if (ch == DPIO_CH1)
+			val |= CHV_BUFRIGHTENA1_FORCE;
+		vlv_dpio_write(dev_priv, pipe, _CHV_CMN_DW5_CH0, val);
+	} else {
+		val = vlv_dpio_read(dev_priv, pipe, _CHV_CMN_DW1_CH1);
+		val &= ~(CHV_BUFLEFTENA2_MASK | CHV_BUFRIGHTENA2_MASK);
+		if (ch == DPIO_CH0)
+			val |= CHV_BUFLEFTENA2_FORCE;
+		if (ch == DPIO_CH1)
+			val |= CHV_BUFRIGHTENA2_FORCE;
+		vlv_dpio_write(dev_priv, pipe, _CHV_CMN_DW1_CH1, val);
+	}
+
+	/* program clock channel usage */
+	val = vlv_dpio_read(dev_priv, pipe, VLV_PCS01_DW8(ch));
+	val |= CHV_PCS_USEDCLKCHANNEL_OVRRIDE;
+	if (pipe != PIPE_B)
+		val &= ~CHV_PCS_USEDCLKCHANNEL;
+	else
+		val |= CHV_PCS_USEDCLKCHANNEL;
+	vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW8(ch), val);
+
+	if (intel_crtc->config->lane_count > 2) {
+		val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW8(ch));
+		val |= CHV_PCS_USEDCLKCHANNEL_OVRRIDE;
+		if (pipe != PIPE_B)
+			val &= ~CHV_PCS_USEDCLKCHANNEL;
+		else
+			val |= CHV_PCS_USEDCLKCHANNEL;
+		vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW8(ch), val);
+	}
+
+	/*
+	 * This a a bit weird since generally CL
+	 * matches the pipe, but here we need to
+	 * pick the CL based on the port.
+	 */
+	val = vlv_dpio_read(dev_priv, pipe, CHV_CMN_DW19(ch));
+	if (pipe != PIPE_B)
+		val &= ~CHV_CMN_USEDCLKCHANNEL;
+	else
+		val |= CHV_CMN_USEDCLKCHANNEL;
+	vlv_dpio_write(dev_priv, pipe, CHV_CMN_DW19(ch), val);
+
+	mutex_unlock(&dev_priv->sb_lock);
+}
+
+static void chv_dp_post_pll_disable(struct intel_encoder *encoder)
+{
+	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
+	enum pipe pipe = to_intel_crtc(encoder->base.crtc)->pipe;
+	u32 val;
+
+	mutex_lock(&dev_priv->sb_lock);
+
+	/* disable left/right clock distribution */
+	if (pipe != PIPE_B) {
+		val = vlv_dpio_read(dev_priv, pipe, _CHV_CMN_DW5_CH0);
+		val &= ~(CHV_BUFLEFTENA1_MASK | CHV_BUFRIGHTENA1_MASK);
+		vlv_dpio_write(dev_priv, pipe, _CHV_CMN_DW5_CH0, val);
+	} else {
+		val = vlv_dpio_read(dev_priv, pipe, _CHV_CMN_DW1_CH1);
+		val &= ~(CHV_BUFLEFTENA2_MASK | CHV_BUFRIGHTENA2_MASK);
+		vlv_dpio_write(dev_priv, pipe, _CHV_CMN_DW1_CH1, val);
+	}
+
+	mutex_unlock(&dev_priv->sb_lock);
+
+	/*
+	 * Leave the power down bit cleared for at least one
+	 * lane so that chv_powergate_phy_ch() will power
+	 * on something when the channel is otherwise unused.
+	 * When the port is off and the override is removed
+	 * the lanes power down anyway, so otherwise it doesn't
+	 * really matter what the state of power down bits is
+	 * after this.
+	 */
+	chv_phy_powergate_lanes(encoder, false, 0x0);
+}
+
+/*
+ * Fetch AUX CH registers 0x202 - 0x207 which contain
+ * link status information
+ */
+bool
+intel_dp_get_link_status(struct intel_dp *intel_dp, uint8_t link_status[DP_LINK_STATUS_SIZE])
+{
+	return drm_dp_dpcd_read(&intel_dp->aux, DP_LANE0_1_STATUS, link_status,
+				DP_LINK_STATUS_SIZE) == DP_LINK_STATUS_SIZE;
+}
+
+/* These are source-specific values. */
+uint8_t
+intel_dp_voltage_max(struct intel_dp *intel_dp)
+{
+	struct drm_device *dev = intel_dp_to_dev(intel_dp);
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	enum port port = dp_to_dig_port(intel_dp)->port;
+
+	if (IS_BROXTON(dev))
+		return DP_TRAIN_VOLTAGE_SWING_LEVEL_3;
+	else if (INTEL_INFO(dev)->gen >= 9) {
+		if (dev_priv->vbt.edp.low_vswing && port == PORT_A)
+			return DP_TRAIN_VOLTAGE_SWING_LEVEL_3;
+		return DP_TRAIN_VOLTAGE_SWING_LEVEL_2;
+	} else if (IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev))
+		return DP_TRAIN_VOLTAGE_SWING_LEVEL_3;
+	else if (IS_GEN7(dev) && port == PORT_A)
+		return DP_TRAIN_VOLTAGE_SWING_LEVEL_2;
+	else if (HAS_PCH_CPT(dev) && port != PORT_A)
+		return DP_TRAIN_VOLTAGE_SWING_LEVEL_3;
+	else
+		return DP_TRAIN_VOLTAGE_SWING_LEVEL_2;
+}
+
+uint8_t
+intel_dp_pre_emphasis_max(struct intel_dp *intel_dp, uint8_t voltage_swing)
+{
+	struct drm_device *dev = intel_dp_to_dev(intel_dp);
+	enum port port = dp_to_dig_port(intel_dp)->port;
+
+	if (INTEL_INFO(dev)->gen >= 9) {
+		switch (voltage_swing & DP_TRAIN_VOLTAGE_SWING_MASK) {
+		case DP_TRAIN_VOLTAGE_SWING_LEVEL_0:
+			return DP_TRAIN_PRE_EMPH_LEVEL_3;
+		case DP_TRAIN_VOLTAGE_SWING_LEVEL_1:
+			return DP_TRAIN_PRE_EMPH_LEVEL_2;
+		case DP_TRAIN_VOLTAGE_SWING_LEVEL_2:
+			return DP_TRAIN_PRE_EMPH_LEVEL_1;
+		case DP_TRAIN_VOLTAGE_SWING_LEVEL_3:
+			return DP_TRAIN_PRE_EMPH_LEVEL_0;
+		default:
+			return DP_TRAIN_PRE_EMPH_LEVEL_0;
+		}
+	} else if (IS_HASWELL(dev) || IS_BROADWELL(dev)) {
+		switch (voltage_swing & DP_TRAIN_VOLTAGE_SWING_MASK) {
+		case DP_TRAIN_VOLTAGE_SWING_LEVEL_0:
+			return DP_TRAIN_PRE_EMPH_LEVEL_3;
+		case DP_TRAIN_VOLTAGE_SWING_LEVEL_1:
+			return DP_TRAIN_PRE_EMPH_LEVEL_2;
+		case DP_TRAIN_VOLTAGE_SWING_LEVEL_2:
+			return DP_TRAIN_PRE_EMPH_LEVEL_1;
+		case DP_TRAIN_VOLTAGE_SWING_LEVEL_3:
+		default:
+			return DP_TRAIN_PRE_EMPH_LEVEL_0;
+		}
+	} else if (IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev)) {
+		switch (voltage_swing & DP_TRAIN_VOLTAGE_SWING_MASK) {
+		case DP_TRAIN_VOLTAGE_SWING_LEVEL_0:
+			return DP_TRAIN_PRE_EMPH_LEVEL_3;
+		case DP_TRAIN_VOLTAGE_SWING_LEVEL_1:
+			return DP_TRAIN_PRE_EMPH_LEVEL_2;
+		case DP_TRAIN_VOLTAGE_SWING_LEVEL_2:
+			return DP_TRAIN_PRE_EMPH_LEVEL_1;
+		case DP_TRAIN_VOLTAGE_SWING_LEVEL_3:
+		default:
+			return DP_TRAIN_PRE_EMPH_LEVEL_0;
+		}
+	} else if (IS_GEN7(dev) && port == PORT_A) {
+		switch (voltage_swing & DP_TRAIN_VOLTAGE_SWING_MASK) {
+		case DP_TRAIN_VOLTAGE_SWING_LEVEL_0:
+			return DP_TRAIN_PRE_EMPH_LEVEL_2;
+		case DP_TRAIN_VOLTAGE_SWING_LEVEL_1:
+		case DP_TRAIN_VOLTAGE_SWING_LEVEL_2:
+			return DP_TRAIN_PRE_EMPH_LEVEL_1;
+		default:
+			return DP_TRAIN_PRE_EMPH_LEVEL_0;
+		}
+	} else {
+		switch (voltage_swing & DP_TRAIN_VOLTAGE_SWING_MASK) {
+		case DP_TRAIN_VOLTAGE_SWING_LEVEL_0:
+			return DP_TRAIN_PRE_EMPH_LEVEL_2;
+		case DP_TRAIN_VOLTAGE_SWING_LEVEL_1:
+			return DP_TRAIN_PRE_EMPH_LEVEL_2;
+		case DP_TRAIN_VOLTAGE_SWING_LEVEL_2:
+			return DP_TRAIN_PRE_EMPH_LEVEL_1;
+		case DP_TRAIN_VOLTAGE_SWING_LEVEL_3:
+		default:
+			return DP_TRAIN_PRE_EMPH_LEVEL_0;
+		}
+	}
+}
+
+static uint32_t vlv_signal_levels(struct intel_dp *intel_dp)
+{
+	struct drm_device *dev = intel_dp_to_dev(intel_dp);
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_digital_port *dport = dp_to_dig_port(intel_dp);
+	struct intel_crtc *intel_crtc =
+		to_intel_crtc(dport->base.base.crtc);
+	unsigned long demph_reg_value, preemph_reg_value,
+		uniqtranscale_reg_value;
+	uint8_t train_set = intel_dp->train_set[0];
+	enum dpio_channel port = vlv_dport_to_channel(dport);
+	int pipe = intel_crtc->pipe;
+
+	switch (train_set & DP_TRAIN_PRE_EMPHASIS_MASK) {
+	case DP_TRAIN_PRE_EMPH_LEVEL_0:
+		preemph_reg_value = 0x0004000;
+		switch (train_set & DP_TRAIN_VOLTAGE_SWING_MASK) {
+		case DP_TRAIN_VOLTAGE_SWING_LEVEL_0:
+			demph_reg_value = 0x2B405555;
+			uniqtranscale_reg_value = 0x552AB83A;
+			break;
+		case DP_TRAIN_VOLTAGE_SWING_LEVEL_1:
+			demph_reg_value = 0x2B404040;
+			uniqtranscale_reg_value = 0x5548B83A;
+			break;
+		case DP_TRAIN_VOLTAGE_SWING_LEVEL_2:
+			demph_reg_value = 0x2B245555;
+			uniqtranscale_reg_value = 0x5560B83A;
+			break;
+		case DP_TRAIN_VOLTAGE_SWING_LEVEL_3:
+			demph_reg_value = 0x2B405555;
+			uniqtranscale_reg_value = 0x5598DA3A;
+			break;
+		default:
+			return 0;
+		}
+		break;
+	case DP_TRAIN_PRE_EMPH_LEVEL_1:
+		preemph_reg_value = 0x0002000;
+		switch (train_set & DP_TRAIN_VOLTAGE_SWING_MASK) {
+		case DP_TRAIN_VOLTAGE_SWING_LEVEL_0:
+			demph_reg_value = 0x2B404040;
+			uniqtranscale_reg_value = 0x5552B83A;
+			break;
+		case DP_TRAIN_VOLTAGE_SWING_LEVEL_1:
+			demph_reg_value = 0x2B404848;
+			uniqtranscale_reg_value = 0x5580B83A;
+			break;
+		case DP_TRAIN_VOLTAGE_SWING_LEVEL_2:
+			demph_reg_value = 0x2B404040;
+			uniqtranscale_reg_value = 0x55ADDA3A;
+			break;
+		default:
+			return 0;
+		}
+		break;
+	case DP_TRAIN_PRE_EMPH_LEVEL_2:
+		preemph_reg_value = 0x0000000;
+		switch (train_set & DP_TRAIN_VOLTAGE_SWING_MASK) {
+		case DP_TRAIN_VOLTAGE_SWING_LEVEL_0:
+			demph_reg_value = 0x2B305555;
+			uniqtranscale_reg_value = 0x5570B83A;
+			break;
+		case DP_TRAIN_VOLTAGE_SWING_LEVEL_1:
+			demph_reg_value = 0x2B2B4040;
+			uniqtranscale_reg_value = 0x55ADDA3A;
+			break;
+		default:
+			return 0;
+		}
+		break;
+	case DP_TRAIN_PRE_EMPH_LEVEL_3:
+		preemph_reg_value = 0x0006000;
+		switch (train_set & DP_TRAIN_VOLTAGE_SWING_MASK) {
+		case DP_TRAIN_VOLTAGE_SWING_LEVEL_0:
+			demph_reg_value = 0x1B405555;
+			uniqtranscale_reg_value = 0x55ADDA3A;
+			break;
+		default:
+			return 0;
+		}
+		break;
+	default:
+		return 0;
+	}
+
+	mutex_lock(&dev_priv->sb_lock);
+	vlv_dpio_write(dev_priv, pipe, VLV_TX_DW5(port), 0x00000000);
+	vlv_dpio_write(dev_priv, pipe, VLV_TX_DW4(port), demph_reg_value);
+	vlv_dpio_write(dev_priv, pipe, VLV_TX_DW2(port),
+			 uniqtranscale_reg_value);
+	vlv_dpio_write(dev_priv, pipe, VLV_TX_DW3(port), 0x0C782040);
+	vlv_dpio_write(dev_priv, pipe, VLV_PCS_DW11(port), 0x00030000);
+	vlv_dpio_write(dev_priv, pipe, VLV_PCS_DW9(port), preemph_reg_value);
+	vlv_dpio_write(dev_priv, pipe, VLV_TX_DW5(port), 0x80000000);
+	mutex_unlock(&dev_priv->sb_lock);
+
+	return 0;
+}
+
+static bool chv_need_uniq_trans_scale(uint8_t train_set)
+{
+	return (train_set & DP_TRAIN_PRE_EMPHASIS_MASK) == DP_TRAIN_PRE_EMPH_LEVEL_0 &&
+		(train_set & DP_TRAIN_VOLTAGE_SWING_MASK) == DP_TRAIN_VOLTAGE_SWING_LEVEL_3;
+}
+
+static uint32_t chv_signal_levels(struct intel_dp *intel_dp)
+{
+	struct drm_device *dev = intel_dp_to_dev(intel_dp);
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_digital_port *dport = dp_to_dig_port(intel_dp);
+	struct intel_crtc *intel_crtc = to_intel_crtc(dport->base.base.crtc);
+	u32 deemph_reg_value, margin_reg_value, val;
+	uint8_t train_set = intel_dp->train_set[0];
+	enum dpio_channel ch = vlv_dport_to_channel(dport);
+	enum pipe pipe = intel_crtc->pipe;
+	int i;
+
+	switch (train_set & DP_TRAIN_PRE_EMPHASIS_MASK) {
+	case DP_TRAIN_PRE_EMPH_LEVEL_0:
+		switch (train_set & DP_TRAIN_VOLTAGE_SWING_MASK) {
+		case DP_TRAIN_VOLTAGE_SWING_LEVEL_0:
+			deemph_reg_value = 128;
+			margin_reg_value = 52;
+			break;
+		case DP_TRAIN_VOLTAGE_SWING_LEVEL_1:
+			deemph_reg_value = 128;
+			margin_reg_value = 77;
+			break;
+		case DP_TRAIN_VOLTAGE_SWING_LEVEL_2:
+			deemph_reg_value = 128;
+			margin_reg_value = 102;
+			break;
+		case DP_TRAIN_VOLTAGE_SWING_LEVEL_3:
+			deemph_reg_value = 128;
+			margin_reg_value = 154;
+			/* FIXME extra to set for 1200 */
+			break;
+		default:
+			return 0;
+		}
+		break;
+	case DP_TRAIN_PRE_EMPH_LEVEL_1:
+		switch (train_set & DP_TRAIN_VOLTAGE_SWING_MASK) {
+		case DP_TRAIN_VOLTAGE_SWING_LEVEL_0:
+			deemph_reg_value = 85;
+			margin_reg_value = 78;
+			break;
+		case DP_TRAIN_VOLTAGE_SWING_LEVEL_1:
+			deemph_reg_value = 85;
+			margin_reg_value = 116;
+			break;
+		case DP_TRAIN_VOLTAGE_SWING_LEVEL_2:
+			deemph_reg_value = 85;
+			margin_reg_value = 154;
+			break;
+		default:
+			return 0;
+		}
+		break;
+	case DP_TRAIN_PRE_EMPH_LEVEL_2:
+		switch (train_set & DP_TRAIN_VOLTAGE_SWING_MASK) {
+		case DP_TRAIN_VOLTAGE_SWING_LEVEL_0:
+			deemph_reg_value = 64;
+			margin_reg_value = 104;
+			break;
+		case DP_TRAIN_VOLTAGE_SWING_LEVEL_1:
+			deemph_reg_value = 64;
+			margin_reg_value = 154;
+			break;
+		default:
+			return 0;
+		}
+		break;
+	case DP_TRAIN_PRE_EMPH_LEVEL_3:
+		switch (train_set & DP_TRAIN_VOLTAGE_SWING_MASK) {
+		case DP_TRAIN_VOLTAGE_SWING_LEVEL_0:
+			deemph_reg_value = 43;
+			margin_reg_value = 154;
+			break;
+		default:
+			return 0;
+		}
+		break;
+	default:
+		return 0;
+	}
+
+	mutex_lock(&dev_priv->sb_lock);
+
+	/* Clear calc init */
+	val = vlv_dpio_read(dev_priv, pipe, VLV_PCS01_DW10(ch));
+	val &= ~(DPIO_PCS_SWING_CALC_TX0_TX2 | DPIO_PCS_SWING_CALC_TX1_TX3);
+	val &= ~(DPIO_PCS_TX1DEEMP_MASK | DPIO_PCS_TX2DEEMP_MASK);
+	val |= DPIO_PCS_TX1DEEMP_9P5 | DPIO_PCS_TX2DEEMP_9P5;
+	vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW10(ch), val);
+
+	if (intel_crtc->config->lane_count > 2) {
+		val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW10(ch));
+		val &= ~(DPIO_PCS_SWING_CALC_TX0_TX2 | DPIO_PCS_SWING_CALC_TX1_TX3);
+		val &= ~(DPIO_PCS_TX1DEEMP_MASK | DPIO_PCS_TX2DEEMP_MASK);
+		val |= DPIO_PCS_TX1DEEMP_9P5 | DPIO_PCS_TX2DEEMP_9P5;
+		vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW10(ch), val);
+	}
+
+	val = vlv_dpio_read(dev_priv, pipe, VLV_PCS01_DW9(ch));
+	val &= ~(DPIO_PCS_TX1MARGIN_MASK | DPIO_PCS_TX2MARGIN_MASK);
+	val |= DPIO_PCS_TX1MARGIN_000 | DPIO_PCS_TX2MARGIN_000;
+	vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW9(ch), val);
+
+	if (intel_crtc->config->lane_count > 2) {
+		val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW9(ch));
+		val &= ~(DPIO_PCS_TX1MARGIN_MASK | DPIO_PCS_TX2MARGIN_MASK);
+		val |= DPIO_PCS_TX1MARGIN_000 | DPIO_PCS_TX2MARGIN_000;
+		vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW9(ch), val);
+	}
+
+	/* Program swing deemph */
+	for (i = 0; i < intel_crtc->config->lane_count; i++) {
+		val = vlv_dpio_read(dev_priv, pipe, CHV_TX_DW4(ch, i));
+		val &= ~DPIO_SWING_DEEMPH9P5_MASK;
+		val |= deemph_reg_value << DPIO_SWING_DEEMPH9P5_SHIFT;
+		vlv_dpio_write(dev_priv, pipe, CHV_TX_DW4(ch, i), val);
+	}
+
+	/* Program swing margin */
+	for (i = 0; i < intel_crtc->config->lane_count; i++) {
+		val = vlv_dpio_read(dev_priv, pipe, CHV_TX_DW2(ch, i));
+
+		val &= ~DPIO_SWING_MARGIN000_MASK;
+		val |= margin_reg_value << DPIO_SWING_MARGIN000_SHIFT;
+
+		/*
+		 * Supposedly this value shouldn't matter when unique transition
+		 * scale is disabled, but in fact it does matter. Let's just
+		 * always program the same value and hope it's OK.
+		 */
+		val &= ~(0xff << DPIO_UNIQ_TRANS_SCALE_SHIFT);
+		val |= 0x9a << DPIO_UNIQ_TRANS_SCALE_SHIFT;
+
+		vlv_dpio_write(dev_priv, pipe, CHV_TX_DW2(ch, i), val);
+	}
+
+	/*
+	 * The document said it needs to set bit 27 for ch0 and bit 26
+	 * for ch1. Might be a typo in the doc.
+	 * For now, for this unique transition scale selection, set bit
+	 * 27 for ch0 and ch1.
+	 */
+	for (i = 0; i < intel_crtc->config->lane_count; i++) {
+		val = vlv_dpio_read(dev_priv, pipe, CHV_TX_DW3(ch, i));
+		if (chv_need_uniq_trans_scale(train_set))
+			val |= DPIO_TX_UNIQ_TRANS_SCALE_EN;
+		else
+			val &= ~DPIO_TX_UNIQ_TRANS_SCALE_EN;
+		vlv_dpio_write(dev_priv, pipe, CHV_TX_DW3(ch, i), val);
+	}
+
+	/* Start swing calculation */
+	val = vlv_dpio_read(dev_priv, pipe, VLV_PCS01_DW10(ch));
+	val |= DPIO_PCS_SWING_CALC_TX0_TX2 | DPIO_PCS_SWING_CALC_TX1_TX3;
+	vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW10(ch), val);
+
+	if (intel_crtc->config->lane_count > 2) {
+		val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW10(ch));
+		val |= DPIO_PCS_SWING_CALC_TX0_TX2 | DPIO_PCS_SWING_CALC_TX1_TX3;
+		vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW10(ch), val);
+	}
+
+	mutex_unlock(&dev_priv->sb_lock);
+
+	return 0;
+}
+
+static uint32_t
+gen4_signal_levels(uint8_t train_set)
+{
+	uint32_t	signal_levels = 0;
+
+	switch (train_set & DP_TRAIN_VOLTAGE_SWING_MASK) {
+	case DP_TRAIN_VOLTAGE_SWING_LEVEL_0:
+	default:
+		signal_levels |= DP_VOLTAGE_0_4;
+		break;
+	case DP_TRAIN_VOLTAGE_SWING_LEVEL_1:
+		signal_levels |= DP_VOLTAGE_0_6;
+		break;
+	case DP_TRAIN_VOLTAGE_SWING_LEVEL_2:
+		signal_levels |= DP_VOLTAGE_0_8;
+		break;
+	case DP_TRAIN_VOLTAGE_SWING_LEVEL_3:
+		signal_levels |= DP_VOLTAGE_1_2;
+		break;
+	}
+	switch (train_set & DP_TRAIN_PRE_EMPHASIS_MASK) {
+	case DP_TRAIN_PRE_EMPH_LEVEL_0:
+	default:
+		signal_levels |= DP_PRE_EMPHASIS_0;
+		break;
+	case DP_TRAIN_PRE_EMPH_LEVEL_1:
+		signal_levels |= DP_PRE_EMPHASIS_3_5;
+		break;
+	case DP_TRAIN_PRE_EMPH_LEVEL_2:
+		signal_levels |= DP_PRE_EMPHASIS_6;
+		break;
+	case DP_TRAIN_PRE_EMPH_LEVEL_3:
+		signal_levels |= DP_PRE_EMPHASIS_9_5;
+		break;
+	}
+	return signal_levels;
+}
+
+/* Gen6's DP voltage swing and pre-emphasis control */
+static uint32_t
+gen6_edp_signal_levels(uint8_t train_set)
+{
+	int signal_levels = train_set & (DP_TRAIN_VOLTAGE_SWING_MASK |
+					 DP_TRAIN_PRE_EMPHASIS_MASK);
+	switch (signal_levels) {
+	case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_0:
+	case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_0:
+		return EDP_LINK_TRAIN_400_600MV_0DB_SNB_B;
+	case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_1:
+		return EDP_LINK_TRAIN_400MV_3_5DB_SNB_B;
+	case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_2:
+	case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_2:
+		return EDP_LINK_TRAIN_400_600MV_6DB_SNB_B;
+	case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_1:
+	case DP_TRAIN_VOLTAGE_SWING_LEVEL_2 | DP_TRAIN_PRE_EMPH_LEVEL_1:
+		return EDP_LINK_TRAIN_600_800MV_3_5DB_SNB_B;
+	case DP_TRAIN_VOLTAGE_SWING_LEVEL_2 | DP_TRAIN_PRE_EMPH_LEVEL_0:
+	case DP_TRAIN_VOLTAGE_SWING_LEVEL_3 | DP_TRAIN_PRE_EMPH_LEVEL_0:
+		return EDP_LINK_TRAIN_800_1200MV_0DB_SNB_B;
+	default:
+		DRM_DEBUG_KMS("Unsupported voltage swing/pre-emphasis level:"
+			      "0x%x\n", signal_levels);
+		return EDP_LINK_TRAIN_400_600MV_0DB_SNB_B;
+	}
+}
+
+/* Gen7's DP voltage swing and pre-emphasis control */
+static uint32_t
+gen7_edp_signal_levels(uint8_t train_set)
+{
+	int signal_levels = train_set & (DP_TRAIN_VOLTAGE_SWING_MASK |
+					 DP_TRAIN_PRE_EMPHASIS_MASK);
+	switch (signal_levels) {
+	case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_0:
+		return EDP_LINK_TRAIN_400MV_0DB_IVB;
+	case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_1:
+		return EDP_LINK_TRAIN_400MV_3_5DB_IVB;
+	case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_2:
+		return EDP_LINK_TRAIN_400MV_6DB_IVB;
+
+	case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_0:
+		return EDP_LINK_TRAIN_600MV_0DB_IVB;
+	case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_1:
+		return EDP_LINK_TRAIN_600MV_3_5DB_IVB;
+
+	case DP_TRAIN_VOLTAGE_SWING_LEVEL_2 | DP_TRAIN_PRE_EMPH_LEVEL_0:
+		return EDP_LINK_TRAIN_800MV_0DB_IVB;
+	case DP_TRAIN_VOLTAGE_SWING_LEVEL_2 | DP_TRAIN_PRE_EMPH_LEVEL_1:
+		return EDP_LINK_TRAIN_800MV_3_5DB_IVB;
+
+	default:
+		DRM_DEBUG_KMS("Unsupported voltage swing/pre-emphasis level:"
+			      "0x%x\n", signal_levels);
+		return EDP_LINK_TRAIN_500MV_0DB_IVB;
+	}
+}
+
+void
+intel_dp_set_signal_levels(struct intel_dp *intel_dp)
+{
+	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
+	enum port port = intel_dig_port->port;
+	struct drm_device *dev = intel_dig_port->base.base.dev;
+	struct drm_i915_private *dev_priv = to_i915(dev);
+	uint32_t signal_levels, mask = 0;
+	uint8_t train_set = intel_dp->train_set[0];
+
+	if (HAS_DDI(dev)) {
+		signal_levels = ddi_signal_levels(intel_dp);
+
+		if (IS_BROXTON(dev))
+			signal_levels = 0;
+		else
+			mask = DDI_BUF_EMP_MASK;
+	} else if (IS_CHERRYVIEW(dev)) {
+		signal_levels = chv_signal_levels(intel_dp);
+	} else if (IS_VALLEYVIEW(dev)) {
+		signal_levels = vlv_signal_levels(intel_dp);
+	} else if (IS_GEN7(dev) && port == PORT_A) {
+		signal_levels = gen7_edp_signal_levels(train_set);
+		mask = EDP_LINK_TRAIN_VOL_EMP_MASK_IVB;
+	} else if (IS_GEN6(dev) && port == PORT_A) {
+		signal_levels = gen6_edp_signal_levels(train_set);
+		mask = EDP_LINK_TRAIN_VOL_EMP_MASK_SNB;
+	} else {
+		signal_levels = gen4_signal_levels(train_set);
+		mask = DP_VOLTAGE_MASK | DP_PRE_EMPHASIS_MASK;
+	}
+
+	if (mask)
+		DRM_DEBUG_KMS("Using signal levels %08x\n", signal_levels);
+
+	DRM_DEBUG_KMS("Using vswing level %d\n",
+		train_set & DP_TRAIN_VOLTAGE_SWING_MASK);
+	DRM_DEBUG_KMS("Using pre-emphasis level %d\n",
+		(train_set & DP_TRAIN_PRE_EMPHASIS_MASK) >>
+			DP_TRAIN_PRE_EMPHASIS_SHIFT);
+
+	intel_dp->DP = (intel_dp->DP & ~mask) | signal_levels;
+
+	I915_WRITE(intel_dp->output_reg, intel_dp->DP);
+	POSTING_READ(intel_dp->output_reg);
+}
+
+void
+intel_dp_program_link_training_pattern(struct intel_dp *intel_dp,
+				       uint8_t dp_train_pat)
+{
+	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
+	struct drm_i915_private *dev_priv =
+		to_i915(intel_dig_port->base.base.dev);
+
+	_intel_dp_set_link_train(intel_dp, &intel_dp->DP, dp_train_pat);
+
+	I915_WRITE(intel_dp->output_reg, intel_dp->DP);
+	POSTING_READ(intel_dp->output_reg);
+}
+
+void intel_dp_set_idle_link_train(struct intel_dp *intel_dp)
+{
+	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
+	struct drm_device *dev = intel_dig_port->base.base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	enum port port = intel_dig_port->port;
+	uint32_t val;
+
+	if (!HAS_DDI(dev))
+		return;
+
+	val = I915_READ(DP_TP_CTL(port));
+	val &= ~DP_TP_CTL_LINK_TRAIN_MASK;
+	val |= DP_TP_CTL_LINK_TRAIN_IDLE;
+	I915_WRITE(DP_TP_CTL(port), val);
+
+	/*
+	 * On PORT_A we can have only eDP in SST mode. There the only reason
+	 * we need to set idle transmission mode is to work around a HW issue
+	 * where we enable the pipe while not in idle link-training mode.
+	 * In this case there is requirement to wait for a minimum number of
+	 * idle patterns to be sent.
+	 */
+	if (port == PORT_A)
+		return;
+
+	if (wait_for((I915_READ(DP_TP_STATUS(port)) & DP_TP_STATUS_IDLE_DONE),
+		     1))
+		DRM_ERROR("Timed out waiting for DP idle patterns\n");
+}
+
+static void
+intel_dp_link_down(struct intel_dp *intel_dp)
+{
+	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
+	struct intel_crtc *crtc = to_intel_crtc(intel_dig_port->base.base.crtc);
+	enum port port = intel_dig_port->port;
+	struct drm_device *dev = intel_dig_port->base.base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	uint32_t DP = intel_dp->DP;
+
+	if (WARN_ON(HAS_DDI(dev)))
+		return;
+
+	if (WARN_ON((I915_READ(intel_dp->output_reg) & DP_PORT_EN) == 0))
+		return;
+
+	DRM_DEBUG_KMS("\n");
+
+	if ((IS_GEN7(dev) && port == PORT_A) ||
+	    (HAS_PCH_CPT(dev) && port != PORT_A)) {
+		DP &= ~DP_LINK_TRAIN_MASK_CPT;
+		DP |= DP_LINK_TRAIN_PAT_IDLE_CPT;
+	} else {
+		if (IS_CHERRYVIEW(dev))
+			DP &= ~DP_LINK_TRAIN_MASK_CHV;
+		else
+			DP &= ~DP_LINK_TRAIN_MASK;
+		DP |= DP_LINK_TRAIN_PAT_IDLE;
+	}
+	I915_WRITE(intel_dp->output_reg, DP);
+	POSTING_READ(intel_dp->output_reg);
+
+	DP &= ~(DP_PORT_EN | DP_AUDIO_OUTPUT_ENABLE);
+	I915_WRITE(intel_dp->output_reg, DP);
+	POSTING_READ(intel_dp->output_reg);
+
+	/*
+	 * HW workaround for IBX, we need to move the port
+	 * to transcoder A after disabling it to allow the
+	 * matching HDMI port to be enabled on transcoder A.
+	 */
+	if (HAS_PCH_IBX(dev) && crtc->pipe == PIPE_B && port != PORT_A) {
+		/*
+		 * We get CPU/PCH FIFO underruns on the other pipe when
+		 * doing the workaround. Sweep them under the rug.
+		 */
+		intel_set_cpu_fifo_underrun_reporting(dev_priv, PIPE_A, false);
+		intel_set_pch_fifo_underrun_reporting(dev_priv, PIPE_A, false);
+
+		/* always enable with pattern 1 (as per spec) */
+		DP &= ~(DP_PIPEB_SELECT | DP_LINK_TRAIN_MASK);
+		DP |= DP_PORT_EN | DP_LINK_TRAIN_PAT_1;
+		I915_WRITE(intel_dp->output_reg, DP);
+		POSTING_READ(intel_dp->output_reg);
+
+		DP &= ~DP_PORT_EN;
+		I915_WRITE(intel_dp->output_reg, DP);
+		POSTING_READ(intel_dp->output_reg);
+
+		intel_wait_for_vblank_if_active(dev_priv->dev, PIPE_A);
+		intel_set_cpu_fifo_underrun_reporting(dev_priv, PIPE_A, true);
+		intel_set_pch_fifo_underrun_reporting(dev_priv, PIPE_A, true);
+	}
+
+	msleep(intel_dp->panel_power_down_delay);
+
+	intel_dp->DP = DP;
+}
+
+static bool
+intel_dp_get_dpcd(struct intel_dp *intel_dp)
+{
+	struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
+	struct drm_device *dev = dig_port->base.base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	uint8_t rev;
+
+	if (drm_dp_dpcd_read(&intel_dp->aux, 0x000, intel_dp->dpcd,
+			     sizeof(intel_dp->dpcd)) < 0)
+		return false; /* aux transfer failed */
+
+	DRM_DEBUG_KMS("DPCD: %*ph\n", (int) sizeof(intel_dp->dpcd), intel_dp->dpcd);
+
+	if (intel_dp->dpcd[DP_DPCD_REV] == 0)
+		return false; /* DPCD not present */
+
+	if (drm_dp_dpcd_read(&intel_dp->aux, DP_SINK_COUNT,
+			     &intel_dp->sink_count, 1) < 0)
+		return false;
+
+	/*
+	 * Sink count can change between short pulse hpd hence
+	 * a member variable in intel_dp will track any changes
+	 * between short pulse interrupts.
+	 */
+	intel_dp->sink_count = DP_GET_SINK_COUNT(intel_dp->sink_count);
+
+	/*
+	 * SINK_COUNT == 0 and DOWNSTREAM_PORT_PRESENT == 1 implies that
+	 * a dongle is present but no display. Unless we require to know
+	 * if a dongle is present or not, we don't need to update
+	 * downstream port information. So, an early return here saves
+	 * time from performing other operations which are not required.
+	 */
+	if (!is_edp(intel_dp) && !intel_dp->sink_count)
+		return false;
+
+	/* Check if the panel supports PSR */
+	memset(intel_dp->psr_dpcd, 0, sizeof(intel_dp->psr_dpcd));
+	if (is_edp(intel_dp)) {
+		drm_dp_dpcd_read(&intel_dp->aux, DP_PSR_SUPPORT,
+				 intel_dp->psr_dpcd,
+				 sizeof(intel_dp->psr_dpcd));
+		if (intel_dp->psr_dpcd[0] & DP_PSR_IS_SUPPORTED) {
+			dev_priv->psr.sink_support = true;
+			DRM_DEBUG_KMS("Detected EDP PSR Panel.\n");
+		}
+
+		if (INTEL_INFO(dev)->gen >= 9 &&
+			(intel_dp->psr_dpcd[0] & DP_PSR2_IS_SUPPORTED)) {
+			uint8_t frame_sync_cap;
+
+			dev_priv->psr.sink_support = true;
+			drm_dp_dpcd_read(&intel_dp->aux,
+					 DP_SINK_DEVICE_AUX_FRAME_SYNC_CAP,
+					 &frame_sync_cap, 1);
+			dev_priv->psr.aux_frame_sync = frame_sync_cap ? true : false;
+			/* PSR2 needs frame sync as well */
+			dev_priv->psr.psr2_support = dev_priv->psr.aux_frame_sync;
+			DRM_DEBUG_KMS("PSR2 %s on sink",
+				dev_priv->psr.psr2_support ? "supported" : "not supported");
+		}
+	}
+
+	DRM_DEBUG_KMS("Display Port TPS3 support: source %s, sink %s\n",
+		      yesno(intel_dp_source_supports_hbr2(intel_dp)),
+		      yesno(drm_dp_tps3_supported(intel_dp->dpcd)));
+
+	/* Intermediate frequency support */
+	if (is_edp(intel_dp) &&
+	    (intel_dp->dpcd[DP_EDP_CONFIGURATION_CAP] &	DP_DPCD_DISPLAY_CONTROL_CAPABLE) &&
+	    (drm_dp_dpcd_read(&intel_dp->aux, DP_EDP_DPCD_REV, &rev, 1) == 1) &&
+	    (rev >= 0x03)) { /* eDp v1.4 or higher */
+		__le16 sink_rates[DP_MAX_SUPPORTED_RATES];
+		int i;
+
+		drm_dp_dpcd_read(&intel_dp->aux, DP_SUPPORTED_LINK_RATES,
+				sink_rates, sizeof(sink_rates));
+
+		for (i = 0; i < ARRAY_SIZE(sink_rates); i++) {
+			int val = le16_to_cpu(sink_rates[i]);
+
+			if (val == 0)
+				break;
+
+			/* Value read is in kHz while drm clock is saved in deca-kHz */
+			intel_dp->sink_rates[i] = (val * 200) / 10;
+		}
+		intel_dp->num_sink_rates = i;
+	}
+
+	intel_dp_print_rates(intel_dp);
+
+	if (!(intel_dp->dpcd[DP_DOWNSTREAMPORT_PRESENT] &
+	      DP_DWN_STRM_PORT_PRESENT))
+		return true; /* native DP sink */
+
+	if (intel_dp->dpcd[DP_DPCD_REV] == 0x10)
+		return true; /* no per-port downstream info */
+
+	if (drm_dp_dpcd_read(&intel_dp->aux, DP_DOWNSTREAM_PORT_0,
+			     intel_dp->downstream_ports,
+			     DP_MAX_DOWNSTREAM_PORTS) < 0)
+		return false; /* downstream port status fetch failed */
+
+	return true;
+}
+
+static void
+intel_dp_probe_oui(struct intel_dp *intel_dp)
+{
+	u8 buf[3];
+
+	if (!(intel_dp->dpcd[DP_DOWN_STREAM_PORT_COUNT] & DP_OUI_SUPPORT))
+		return;
+
+	if (drm_dp_dpcd_read(&intel_dp->aux, DP_SINK_OUI, buf, 3) == 3)
+		DRM_DEBUG_KMS("Sink OUI: %02hx%02hx%02hx\n",
+			      buf[0], buf[1], buf[2]);
+
+	if (drm_dp_dpcd_read(&intel_dp->aux, DP_BRANCH_OUI, buf, 3) == 3)
+		DRM_DEBUG_KMS("Branch OUI: %02hx%02hx%02hx\n",
+			      buf[0], buf[1], buf[2]);
+}
+
+static bool
+intel_dp_probe_mst(struct intel_dp *intel_dp)
+{
+	u8 buf[1];
+
+	if (!i915.enable_dp_mst)
+		return false;
+
+	if (!intel_dp->can_mst)
+		return false;
+
+	if (intel_dp->dpcd[DP_DPCD_REV] < 0x12)
+		return false;
+
+	if (drm_dp_dpcd_read(&intel_dp->aux, DP_MSTM_CAP, buf, 1)) {
+		if (buf[0] & DP_MST_CAP) {
+			DRM_DEBUG_KMS("Sink is MST capable\n");
+			intel_dp->is_mst = true;
+		} else {
+			DRM_DEBUG_KMS("Sink is not MST capable\n");
+			intel_dp->is_mst = false;
+		}
+	}
+
+	drm_dp_mst_topology_mgr_set_mst(&intel_dp->mst_mgr, intel_dp->is_mst);
+	return intel_dp->is_mst;
+}
+
+static int intel_dp_sink_crc_stop(struct intel_dp *intel_dp)
+{
+	struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
+	struct drm_device *dev = dig_port->base.base.dev;
+	struct intel_crtc *intel_crtc = to_intel_crtc(dig_port->base.base.crtc);
+	u8 buf;
+	int ret = 0;
+	int count = 0;
+	int attempts = 10;
+
+	if (drm_dp_dpcd_readb(&intel_dp->aux, DP_TEST_SINK, &buf) < 0) {
+		DRM_DEBUG_KMS("Sink CRC couldn't be stopped properly\n");
+		ret = -EIO;
+		goto out;
+	}
+
+	if (drm_dp_dpcd_writeb(&intel_dp->aux, DP_TEST_SINK,
+			       buf & ~DP_TEST_SINK_START) < 0) {
+		DRM_DEBUG_KMS("Sink CRC couldn't be stopped properly\n");
+		ret = -EIO;
+		goto out;
+	}
+
+	do {
+		intel_wait_for_vblank(dev, intel_crtc->pipe);
+
+		if (drm_dp_dpcd_readb(&intel_dp->aux,
+				      DP_TEST_SINK_MISC, &buf) < 0) {
+			ret = -EIO;
+			goto out;
+		}
+		count = buf & DP_TEST_COUNT_MASK;
+	} while (--attempts && count);
+
+	if (attempts == 0) {
+		DRM_DEBUG_KMS("TIMEOUT: Sink CRC counter is not zeroed after calculation is stopped\n");
+		ret = -ETIMEDOUT;
+	}
+
+ out:
+	hsw_enable_ips(intel_crtc);
+	return ret;
+}
+
+static int intel_dp_sink_crc_start(struct intel_dp *intel_dp)
+{
+	struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
+	struct drm_device *dev = dig_port->base.base.dev;
+	struct intel_crtc *intel_crtc = to_intel_crtc(dig_port->base.base.crtc);
+	u8 buf;
+	int ret;
+
+	if (drm_dp_dpcd_readb(&intel_dp->aux, DP_TEST_SINK_MISC, &buf) < 0)
+		return -EIO;
+
+	if (!(buf & DP_TEST_CRC_SUPPORTED))
+		return -ENOTTY;
+
+	if (drm_dp_dpcd_readb(&intel_dp->aux, DP_TEST_SINK, &buf) < 0)
+		return -EIO;
+
+	if (buf & DP_TEST_SINK_START) {
+		ret = intel_dp_sink_crc_stop(intel_dp);
+		if (ret)
+			return ret;
+	}
+
+	hsw_disable_ips(intel_crtc);
+
+	if (drm_dp_dpcd_writeb(&intel_dp->aux, DP_TEST_SINK,
+			       buf | DP_TEST_SINK_START) < 0) {
+		hsw_enable_ips(intel_crtc);
+		return -EIO;
+	}
+
+	intel_wait_for_vblank(dev, intel_crtc->pipe);
+	return 0;
+}
+
+int intel_dp_sink_crc(struct intel_dp *intel_dp, u8 *crc)
+{
+	struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
+	struct drm_device *dev = dig_port->base.base.dev;
+	struct intel_crtc *intel_crtc = to_intel_crtc(dig_port->base.base.crtc);
+	u8 buf;
+	int count, ret;
+	int attempts = 6;
+
+	ret = intel_dp_sink_crc_start(intel_dp);
+	if (ret)
+		return ret;
+
+	do {
+		intel_wait_for_vblank(dev, intel_crtc->pipe);
+
+		if (drm_dp_dpcd_readb(&intel_dp->aux,
+				      DP_TEST_SINK_MISC, &buf) < 0) {
+			ret = -EIO;
+			goto stop;
+		}
+		count = buf & DP_TEST_COUNT_MASK;
+
+	} while (--attempts && count == 0);
+
+	if (attempts == 0) {
+		DRM_ERROR("Panel is unable to calculate any CRC after 6 vblanks\n");
+		ret = -ETIMEDOUT;
+		goto stop;
+	}
+
+	if (drm_dp_dpcd_read(&intel_dp->aux, DP_TEST_CRC_R_CR, crc, 6) < 0) {
+		ret = -EIO;
+		goto stop;
+	}
+
+stop:
+	intel_dp_sink_crc_stop(intel_dp);
+	return ret;
+}
+
+static bool
+intel_dp_get_sink_irq(struct intel_dp *intel_dp, u8 *sink_irq_vector)
+{
+	return drm_dp_dpcd_read(&intel_dp->aux,
+				       DP_DEVICE_SERVICE_IRQ_VECTOR,
+				       sink_irq_vector, 1) == 1;
+}
+
+static bool
+intel_dp_get_sink_irq_esi(struct intel_dp *intel_dp, u8 *sink_irq_vector)
+{
+	int ret;
+
+	ret = drm_dp_dpcd_read(&intel_dp->aux,
+					     DP_SINK_COUNT_ESI,
+					     sink_irq_vector, 14);
+	if (ret != 14)
+		return false;
+
+	return true;
+}
+
+static uint8_t intel_dp_autotest_link_training(struct intel_dp *intel_dp)
+{
+	uint8_t test_result = DP_TEST_ACK;
+	return test_result;
+}
+
+static uint8_t intel_dp_autotest_video_pattern(struct intel_dp *intel_dp)
+{
+	uint8_t test_result = DP_TEST_NAK;
+	return test_result;
+}
+
+static uint8_t intel_dp_autotest_edid(struct intel_dp *intel_dp)
+{
+	uint8_t test_result = DP_TEST_NAK;
+	struct intel_connector *intel_connector = intel_dp->attached_connector;
+	struct drm_connector *connector = &intel_connector->base;
+
+	if (intel_connector->detect_edid == NULL ||
+	    connector->edid_corrupt ||
+	    intel_dp->aux.i2c_defer_count > 6) {
+		/* Check EDID read for NACKs, DEFERs and corruption
+		 * (DP CTS 1.2 Core r1.1)
+		 *    4.2.2.4 : Failed EDID read, I2C_NAK
+		 *    4.2.2.5 : Failed EDID read, I2C_DEFER
+		 *    4.2.2.6 : EDID corruption detected
+		 * Use failsafe mode for all cases
+		 */
+		if (intel_dp->aux.i2c_nack_count > 0 ||
+			intel_dp->aux.i2c_defer_count > 0)
+			DRM_DEBUG_KMS("EDID read had %d NACKs, %d DEFERs\n",
+				      intel_dp->aux.i2c_nack_count,
+				      intel_dp->aux.i2c_defer_count);
+		intel_dp->compliance_test_data = INTEL_DP_RESOLUTION_FAILSAFE;
+	} else {
+		struct edid *block = intel_connector->detect_edid;
+
+		/* We have to write the checksum
+		 * of the last block read
+		 */
+		block += intel_connector->detect_edid->extensions;
+
+		if (!drm_dp_dpcd_write(&intel_dp->aux,
+					DP_TEST_EDID_CHECKSUM,
+					&block->checksum,
+					1))
+			DRM_DEBUG_KMS("Failed to write EDID checksum\n");
+
+		test_result = DP_TEST_ACK | DP_TEST_EDID_CHECKSUM_WRITE;
+		intel_dp->compliance_test_data = INTEL_DP_RESOLUTION_STANDARD;
+	}
+
+	/* Set test active flag here so userspace doesn't interrupt things */
+	intel_dp->compliance_test_active = 1;
+
+	return test_result;
+}
+
+static uint8_t intel_dp_autotest_phy_pattern(struct intel_dp *intel_dp)
+{
+	uint8_t test_result = DP_TEST_NAK;
+	return test_result;
+}
+
+static void intel_dp_handle_test_request(struct intel_dp *intel_dp)
+{
+	uint8_t response = DP_TEST_NAK;
+	uint8_t rxdata = 0;
+	int status = 0;
+
+	status = drm_dp_dpcd_read(&intel_dp->aux, DP_TEST_REQUEST, &rxdata, 1);
+	if (status <= 0) {
+		DRM_DEBUG_KMS("Could not read test request from sink\n");
+		goto update_status;
+	}
+
+	switch (rxdata) {
+	case DP_TEST_LINK_TRAINING:
+		DRM_DEBUG_KMS("LINK_TRAINING test requested\n");
+		intel_dp->compliance_test_type = DP_TEST_LINK_TRAINING;
+		response = intel_dp_autotest_link_training(intel_dp);
+		break;
+	case DP_TEST_LINK_VIDEO_PATTERN:
+		DRM_DEBUG_KMS("TEST_PATTERN test requested\n");
+		intel_dp->compliance_test_type = DP_TEST_LINK_VIDEO_PATTERN;
+		response = intel_dp_autotest_video_pattern(intel_dp);
+		break;
+	case DP_TEST_LINK_EDID_READ:
+		DRM_DEBUG_KMS("EDID test requested\n");
+		intel_dp->compliance_test_type = DP_TEST_LINK_EDID_READ;
+		response = intel_dp_autotest_edid(intel_dp);
+		break;
+	case DP_TEST_LINK_PHY_TEST_PATTERN:
+		DRM_DEBUG_KMS("PHY_PATTERN test requested\n");
+		intel_dp->compliance_test_type = DP_TEST_LINK_PHY_TEST_PATTERN;
+		response = intel_dp_autotest_phy_pattern(intel_dp);
+		break;
+	default:
+		DRM_DEBUG_KMS("Invalid test request '%02x'\n", rxdata);
+		break;
+	}
+
+update_status:
+	status = drm_dp_dpcd_write(&intel_dp->aux,
+				   DP_TEST_RESPONSE,
+				   &response, 1);
+	if (status <= 0)
+		DRM_DEBUG_KMS("Could not write test response to sink\n");
+}
+
+static int
+intel_dp_check_mst_status(struct intel_dp *intel_dp)
+{
+	bool bret;
+
+	if (intel_dp->is_mst) {
+		u8 esi[16] = { 0 };
+		int ret = 0;
+		int retry;
+		bool handled;
+		bret = intel_dp_get_sink_irq_esi(intel_dp, esi);
+go_again:
+		if (bret == true) {
+
+			/* check link status - esi[10] = 0x200c */
+			if (intel_dp->active_mst_links &&
+			    !drm_dp_channel_eq_ok(&esi[10], intel_dp->lane_count)) {
+				DRM_DEBUG_KMS("channel EQ not ok, retraining\n");
+				intel_dp_start_link_train(intel_dp);
+				intel_dp_stop_link_train(intel_dp);
+			}
+
+			DRM_DEBUG_KMS("got esi %3ph\n", esi);
+			ret = drm_dp_mst_hpd_irq(&intel_dp->mst_mgr, esi, &handled);
+
+			if (handled) {
+				for (retry = 0; retry < 3; retry++) {
+					int wret;
+					wret = drm_dp_dpcd_write(&intel_dp->aux,
+								 DP_SINK_COUNT_ESI+1,
+								 &esi[1], 3);
+					if (wret == 3) {
+						break;
+					}
+				}
+
+				bret = intel_dp_get_sink_irq_esi(intel_dp, esi);
+				if (bret == true) {
+					DRM_DEBUG_KMS("got esi2 %3ph\n", esi);
+					goto go_again;
+				}
+			} else
+				ret = 0;
+
+			return ret;
+		} else {
+			struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
+			DRM_DEBUG_KMS("failed to get ESI - device may have failed\n");
+			intel_dp->is_mst = false;
+			drm_dp_mst_topology_mgr_set_mst(&intel_dp->mst_mgr, intel_dp->is_mst);
+			/* send a hotplug event */
+			drm_kms_helper_hotplug_event(intel_dig_port->base.base.dev);
+		}
+	}
+	return -EINVAL;
+}
+
+static void
+intel_dp_check_link_status(struct intel_dp *intel_dp)
+{
+	struct intel_encoder *intel_encoder = &dp_to_dig_port(intel_dp)->base;
+	struct drm_device *dev = intel_dp_to_dev(intel_dp);
+	u8 link_status[DP_LINK_STATUS_SIZE];
+
+	WARN_ON(!drm_modeset_is_locked(&dev->mode_config.connection_mutex));
+
+	if (!intel_dp_get_link_status(intel_dp, link_status)) {
+		DRM_ERROR("Failed to get link status\n");
+		return;
+	}
+
+	if (!intel_encoder->base.crtc)
+		return;
+
+	if (!to_intel_crtc(intel_encoder->base.crtc)->active)
+		return;
+
+	/* if link training is requested we should perform it always */
+	if ((intel_dp->compliance_test_type == DP_TEST_LINK_TRAINING) ||
+	    (!drm_dp_channel_eq_ok(link_status, intel_dp->lane_count))) {
+		DRM_DEBUG_KMS("%s: channel EQ not ok, retraining\n",
+			      intel_encoder->base.name);
+		intel_dp_start_link_train(intel_dp);
+		intel_dp_stop_link_train(intel_dp);
+	}
+}
+
+/*
+ * According to DP spec
+ * 5.1.2:
+ *  1. Read DPCD
+ *  2. Configure link according to Receiver Capabilities
+ *  3. Use Link Training from 2.5.3.3 and 3.5.1.3
+ *  4. Check link status on receipt of hot-plug interrupt
+ *
+ * intel_dp_short_pulse -  handles short pulse interrupts
+ * when full detection is not required.
+ * Returns %true if short pulse is handled and full detection
+ * is NOT required and %false otherwise.
+ */
+static bool
+intel_dp_short_pulse(struct intel_dp *intel_dp)
+{
+	struct drm_device *dev = intel_dp_to_dev(intel_dp);
+	u8 sink_irq_vector;
+	u8 old_sink_count = intel_dp->sink_count;
+	bool ret;
+
+	/*
+	 * Clearing compliance test variables to allow capturing
+	 * of values for next automated test request.
+	 */
+	intel_dp->compliance_test_active = 0;
+	intel_dp->compliance_test_type = 0;
+	intel_dp->compliance_test_data = 0;
+
+	/*
+	 * Now read the DPCD to see if it's actually running
+	 * If the current value of sink count doesn't match with
+	 * the value that was stored earlier or dpcd read failed
+	 * we need to do full detection
+	 */
+	ret = intel_dp_get_dpcd(intel_dp);
+
+	if ((old_sink_count != intel_dp->sink_count) || !ret) {
+		/* No need to proceed if we are going to do full detect */
+		return false;
+	}
+
+	/* Try to read the source of the interrupt */
+	if (intel_dp->dpcd[DP_DPCD_REV] >= 0x11 &&
+	    intel_dp_get_sink_irq(intel_dp, &sink_irq_vector)) {
+		/* Clear interrupt source */
+		drm_dp_dpcd_writeb(&intel_dp->aux,
+				   DP_DEVICE_SERVICE_IRQ_VECTOR,
+				   sink_irq_vector);
+
+		if (sink_irq_vector & DP_AUTOMATED_TEST_REQUEST)
+			DRM_DEBUG_DRIVER("Test request in short pulse not handled\n");
+		if (sink_irq_vector & (DP_CP_IRQ | DP_SINK_SPECIFIC_IRQ))
+			DRM_DEBUG_DRIVER("CP or sink specific irq unhandled\n");
+	}
+
+	drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);
+	intel_dp_check_link_status(intel_dp);
+	drm_modeset_unlock(&dev->mode_config.connection_mutex);
+
+	return true;
+}
+
+/* XXX this is probably wrong for multiple downstream ports */
+static enum drm_connector_status
+intel_dp_detect_dpcd(struct intel_dp *intel_dp)
+{
+	uint8_t *dpcd = intel_dp->dpcd;
+	uint8_t type;
+
+	if (!intel_dp_get_dpcd(intel_dp))
+		return connector_status_disconnected;
+
+	if (is_edp(intel_dp))
+		return connector_status_connected;
+
+	/* if there's no downstream port, we're done */
+	if (!(dpcd[DP_DOWNSTREAMPORT_PRESENT] & DP_DWN_STRM_PORT_PRESENT))
+		return connector_status_connected;
+
+	/* If we're HPD-aware, SINK_COUNT changes dynamically */
+	if (intel_dp->dpcd[DP_DPCD_REV] >= 0x11 &&
+	    intel_dp->downstream_ports[0] & DP_DS_PORT_HPD) {
+
+		return intel_dp->sink_count ?
+		connector_status_connected : connector_status_disconnected;
+	}
+
+	/* If no HPD, poke DDC gently */
+	if (drm_probe_ddc(&intel_dp->aux.ddc))
+		return connector_status_connected;
+
+	/* Well we tried, say unknown for unreliable port types */
+	if (intel_dp->dpcd[DP_DPCD_REV] >= 0x11) {
+		type = intel_dp->downstream_ports[0] & DP_DS_PORT_TYPE_MASK;
+		if (type == DP_DS_PORT_TYPE_VGA ||
+		    type == DP_DS_PORT_TYPE_NON_EDID)
+			return connector_status_unknown;
+	} else {
+		type = intel_dp->dpcd[DP_DOWNSTREAMPORT_PRESENT] &
+			DP_DWN_STRM_PORT_TYPE_MASK;
+		if (type == DP_DWN_STRM_PORT_TYPE_ANALOG ||
+		    type == DP_DWN_STRM_PORT_TYPE_OTHER)
+			return connector_status_unknown;
+	}
+
+	/* Anything else is out of spec, warn and ignore */
+	DRM_DEBUG_KMS("Broken DP branch device, ignoring\n");
+	return connector_status_disconnected;
+}
+
+static enum drm_connector_status
+edp_detect(struct intel_dp *intel_dp)
+{
+	struct drm_device *dev = intel_dp_to_dev(intel_dp);
+	enum drm_connector_status status;
+
+	status = intel_panel_detect(dev);
+	if (status == connector_status_unknown)
+		status = connector_status_connected;
+
+	return status;
+}
+
+static bool ibx_digital_port_connected(struct drm_i915_private *dev_priv,
+				       struct intel_digital_port *port)
+{
+	u32 bit;
+
+	switch (port->port) {
+	case PORT_A:
+		return true;
+	case PORT_B:
+		bit = SDE_PORTB_HOTPLUG;
+		break;
+	case PORT_C:
+		bit = SDE_PORTC_HOTPLUG;
+		break;
+	case PORT_D:
+		bit = SDE_PORTD_HOTPLUG;
+		break;
+	default:
+		MISSING_CASE(port->port);
+		return false;
+	}
+
+	return I915_READ(SDEISR) & bit;
+}
+
+static bool cpt_digital_port_connected(struct drm_i915_private *dev_priv,
+				       struct intel_digital_port *port)
+{
+	u32 bit;
+
+	switch (port->port) {
+	case PORT_A:
+		return true;
+	case PORT_B:
+		bit = SDE_PORTB_HOTPLUG_CPT;
+		break;
+	case PORT_C:
+		bit = SDE_PORTC_HOTPLUG_CPT;
+		break;
+	case PORT_D:
+		bit = SDE_PORTD_HOTPLUG_CPT;
+		break;
+	case PORT_E:
+		bit = SDE_PORTE_HOTPLUG_SPT;
+		break;
+	default:
+		MISSING_CASE(port->port);
+		return false;
+	}
+
+	return I915_READ(SDEISR) & bit;
+}
+
+static bool g4x_digital_port_connected(struct drm_i915_private *dev_priv,
+				       struct intel_digital_port *port)
+{
+	u32 bit;
+
+	switch (port->port) {
+	case PORT_B:
+		bit = PORTB_HOTPLUG_LIVE_STATUS_G4X;
+		break;
+	case PORT_C:
+		bit = PORTC_HOTPLUG_LIVE_STATUS_G4X;
+		break;
+	case PORT_D:
+		bit = PORTD_HOTPLUG_LIVE_STATUS_G4X;
+		break;
+	default:
+		MISSING_CASE(port->port);
+		return false;
+	}
+
+	return I915_READ(PORT_HOTPLUG_STAT) & bit;
+}
+
+static bool gm45_digital_port_connected(struct drm_i915_private *dev_priv,
+					struct intel_digital_port *port)
+{
+	u32 bit;
+
+	switch (port->port) {
+	case PORT_B:
+		bit = PORTB_HOTPLUG_LIVE_STATUS_GM45;
+		break;
+	case PORT_C:
+		bit = PORTC_HOTPLUG_LIVE_STATUS_GM45;
+		break;
+	case PORT_D:
+		bit = PORTD_HOTPLUG_LIVE_STATUS_GM45;
+		break;
+	default:
+		MISSING_CASE(port->port);
+		return false;
+	}
+
+	return I915_READ(PORT_HOTPLUG_STAT) & bit;
+}
+
+static bool bxt_digital_port_connected(struct drm_i915_private *dev_priv,
+				       struct intel_digital_port *intel_dig_port)
+{
+	struct intel_encoder *intel_encoder = &intel_dig_port->base;
+	enum port port;
+	u32 bit;
+
+	intel_hpd_pin_to_port(intel_encoder->hpd_pin, &port);
+	switch (port) {
+	case PORT_A:
+		bit = BXT_DE_PORT_HP_DDIA;
+		break;
+	case PORT_B:
+		bit = BXT_DE_PORT_HP_DDIB;
+		break;
+	case PORT_C:
+		bit = BXT_DE_PORT_HP_DDIC;
+		break;
+	default:
+		MISSING_CASE(port);
+		return false;
+	}
+
+	return I915_READ(GEN8_DE_PORT_ISR) & bit;
+}
+
+/*
+ * intel_digital_port_connected - is the specified port connected?
+ * @dev_priv: i915 private structure
+ * @port: the port to test
+ *
+ * Return %true if @port is connected, %false otherwise.
+ */
+bool intel_digital_port_connected(struct drm_i915_private *dev_priv,
+					 struct intel_digital_port *port)
+{
+	if (HAS_PCH_IBX(dev_priv))
+		return ibx_digital_port_connected(dev_priv, port);
+	else if (HAS_PCH_SPLIT(dev_priv))
+		return cpt_digital_port_connected(dev_priv, port);
+	else if (IS_BROXTON(dev_priv))
+		return bxt_digital_port_connected(dev_priv, port);
+	else if (IS_GM45(dev_priv))
+		return gm45_digital_port_connected(dev_priv, port);
+	else
+		return g4x_digital_port_connected(dev_priv, port);
+}
+
+static struct edid *
+intel_dp_get_edid(struct intel_dp *intel_dp)
+{
+	struct intel_connector *intel_connector = intel_dp->attached_connector;
+
+	/* use cached edid if we have one */
+	if (intel_connector->edid) {
+		/* invalid edid */
+		if (IS_ERR(intel_connector->edid))
+			return NULL;
+
+		return drm_edid_duplicate(intel_connector->edid);
+	} else
+		return drm_get_edid(&intel_connector->base,
+				    &intel_dp->aux.ddc);
+}
+
+static void
+intel_dp_set_edid(struct intel_dp *intel_dp)
+{
+	struct intel_connector *intel_connector = intel_dp->attached_connector;
+	struct edid *edid;
+
+	intel_dp_unset_edid(intel_dp);
+	edid = intel_dp_get_edid(intel_dp);
+	intel_connector->detect_edid = edid;
+
+	if (intel_dp->force_audio != HDMI_AUDIO_AUTO)
+		intel_dp->has_audio = intel_dp->force_audio == HDMI_AUDIO_ON;
+	else
+		intel_dp->has_audio = drm_detect_monitor_audio(edid);
+}
+
+static void
+intel_dp_unset_edid(struct intel_dp *intel_dp)
+{
+	struct intel_connector *intel_connector = intel_dp->attached_connector;
+
+	kfree(intel_connector->detect_edid);
+	intel_connector->detect_edid = NULL;
+
+	intel_dp->has_audio = false;
+}
+
+static void
+intel_dp_long_pulse(struct intel_connector *intel_connector)
+{
+	struct drm_connector *connector = &intel_connector->base;
+	struct intel_dp *intel_dp = intel_attached_dp(connector);
+	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
+	struct intel_encoder *intel_encoder = &intel_dig_port->base;
+	struct drm_device *dev = connector->dev;
+	enum drm_connector_status status;
+	enum intel_display_power_domain power_domain;
+	bool ret;
+	u8 sink_irq_vector;
+
+	power_domain = intel_display_port_aux_power_domain(intel_encoder);
+	intel_display_power_get(to_i915(dev), power_domain);
+
+	/* Can't disconnect eDP, but you can close the lid... */
+	if (is_edp(intel_dp))
+		status = edp_detect(intel_dp);
+	else if (intel_digital_port_connected(to_i915(dev),
+					      dp_to_dig_port(intel_dp)))
+		status = intel_dp_detect_dpcd(intel_dp);
+	else
+		status = connector_status_disconnected;
+
+	if (status != connector_status_connected) {
+		intel_dp->compliance_test_active = 0;
+		intel_dp->compliance_test_type = 0;
+		intel_dp->compliance_test_data = 0;
+
+		if (intel_dp->is_mst) {
+			DRM_DEBUG_KMS("MST device may have disappeared %d vs %d\n",
+				      intel_dp->is_mst,
+				      intel_dp->mst_mgr.mst_state);
+			intel_dp->is_mst = false;
+			drm_dp_mst_topology_mgr_set_mst(&intel_dp->mst_mgr,
+							intel_dp->is_mst);
+		}
+
+		goto out;
+	}
+
+	if (intel_encoder->type != INTEL_OUTPUT_EDP)
+		intel_encoder->type = INTEL_OUTPUT_DISPLAYPORT;
+
+	intel_dp_probe_oui(intel_dp);
+
+	ret = intel_dp_probe_mst(intel_dp);
+	if (ret) {
+		/*
+		 * If we are in MST mode then this connector
+		 * won't appear connected or have anything
+		 * with EDID on it
+		 */
+		status = connector_status_disconnected;
+		goto out;
+	} else if (connector->status == connector_status_connected) {
+		/*
+		 * If display was connected already and is still connected
+		 * check links status, there has been known issues of
+		 * link loss triggerring long pulse!!!!
+		 */
+		drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);
+		intel_dp_check_link_status(intel_dp);
+		drm_modeset_unlock(&dev->mode_config.connection_mutex);
+		goto out;
+	}
+
+	/*
+	 * Clearing NACK and defer counts to get their exact values
+	 * while reading EDID which are required by Compliance tests
+	 * 4.2.2.4 and 4.2.2.5
+	 */
+	intel_dp->aux.i2c_nack_count = 0;
+	intel_dp->aux.i2c_defer_count = 0;
+
+	intel_dp_set_edid(intel_dp);
+
+	status = connector_status_connected;
+	intel_dp->detect_done = true;
+
+	/* Try to read the source of the interrupt */
+	if (intel_dp->dpcd[DP_DPCD_REV] >= 0x11 &&
+	    intel_dp_get_sink_irq(intel_dp, &sink_irq_vector)) {
+		/* Clear interrupt source */
+		drm_dp_dpcd_writeb(&intel_dp->aux,
+				   DP_DEVICE_SERVICE_IRQ_VECTOR,
+				   sink_irq_vector);
+
+		if (sink_irq_vector & DP_AUTOMATED_TEST_REQUEST)
+			intel_dp_handle_test_request(intel_dp);
+		if (sink_irq_vector & (DP_CP_IRQ | DP_SINK_SPECIFIC_IRQ))
+			DRM_DEBUG_DRIVER("CP or sink specific irq unhandled\n");
+	}
+
+out:
+	if ((status != connector_status_connected) &&
+	    (intel_dp->is_mst == false))
+		intel_dp_unset_edid(intel_dp);
+
+	intel_display_power_put(to_i915(dev), power_domain);
+	return;
+}
+
+static enum drm_connector_status
+intel_dp_detect(struct drm_connector *connector, bool force)
+{
+	struct intel_dp *intel_dp = intel_attached_dp(connector);
+	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
+	struct intel_encoder *intel_encoder = &intel_dig_port->base;
+	struct intel_connector *intel_connector = to_intel_connector(connector);
+
+	DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
+		      connector->base.id, connector->name);
+
+	if (intel_dp->is_mst) {
+		/* MST devices are disconnected from a monitor POV */
+		intel_dp_unset_edid(intel_dp);
+		if (intel_encoder->type != INTEL_OUTPUT_EDP)
+			intel_encoder->type = INTEL_OUTPUT_DISPLAYPORT;
+		return connector_status_disconnected;
+	}
+
+	/* If full detect is not performed yet, do a full detect */
+	if (!intel_dp->detect_done)
+		intel_dp_long_pulse(intel_dp->attached_connector);
+
+	intel_dp->detect_done = false;
+
+	if (is_edp(intel_dp) || intel_connector->detect_edid)
+		return connector_status_connected;
+	else
+		return connector_status_disconnected;
+}
+
+static void
+intel_dp_force(struct drm_connector *connector)
+{
+	struct intel_dp *intel_dp = intel_attached_dp(connector);
+	struct intel_encoder *intel_encoder = &dp_to_dig_port(intel_dp)->base;
+	struct drm_i915_private *dev_priv = to_i915(intel_encoder->base.dev);
+	enum intel_display_power_domain power_domain;
+
+	DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
+		      connector->base.id, connector->name);
+	intel_dp_unset_edid(intel_dp);
+
+	if (connector->status != connector_status_connected)
+		return;
+
+	power_domain = intel_display_port_aux_power_domain(intel_encoder);
+	intel_display_power_get(dev_priv, power_domain);
+
+	intel_dp_set_edid(intel_dp);
+
+	intel_display_power_put(dev_priv, power_domain);
+
+	if (intel_encoder->type != INTEL_OUTPUT_EDP)
+		intel_encoder->type = INTEL_OUTPUT_DISPLAYPORT;
+}
+
+static int intel_dp_get_modes(struct drm_connector *connector)
+{
+	struct intel_connector *intel_connector = to_intel_connector(connector);
+	struct edid *edid;
+
+	edid = intel_connector->detect_edid;
+	if (edid) {
+		int ret = intel_connector_update_modes(connector, edid);
+		if (ret)
+			return ret;
+	}
+
+	/* if eDP has no EDID, fall back to fixed mode */
+	if (is_edp(intel_attached_dp(connector)) &&
+	    intel_connector->panel.fixed_mode) {
+		struct drm_display_mode *mode;
+
+		mode = drm_mode_duplicate(connector->dev,
+					  intel_connector->panel.fixed_mode);
+		if (mode) {
+			drm_mode_probed_add(connector, mode);
+			return 1;
+		}
+	}
+
+	return 0;
+}
+
+static bool
+intel_dp_detect_audio(struct drm_connector *connector)
+{
+	bool has_audio = false;
+	struct edid *edid;
+
+	edid = to_intel_connector(connector)->detect_edid;
+	if (edid)
+		has_audio = drm_detect_monitor_audio(edid);
+
+	return has_audio;
+}
+
+static int
+intel_dp_set_property(struct drm_connector *connector,
+		      struct drm_property *property,
+		      uint64_t val)
+{
+	struct drm_i915_private *dev_priv = connector->dev->dev_private;
+	struct intel_connector *intel_connector = to_intel_connector(connector);
+	struct intel_encoder *intel_encoder = intel_attached_encoder(connector);
+	struct intel_dp *intel_dp = enc_to_intel_dp(&intel_encoder->base);
+	int ret;
+
+	ret = drm_object_property_set_value(&connector->base, property, val);
+	if (ret)
+		return ret;
+
+	if (property == dev_priv->force_audio_property) {
+		int i = val;
+		bool has_audio;
+
+		if (i == intel_dp->force_audio)
+			return 0;
+
+		intel_dp->force_audio = i;
+
+		if (i == HDMI_AUDIO_AUTO)
+			has_audio = intel_dp_detect_audio(connector);
+		else
+			has_audio = (i == HDMI_AUDIO_ON);
+
+		if (has_audio == intel_dp->has_audio)
+			return 0;
+
+		intel_dp->has_audio = has_audio;
+		goto done;
+	}
+
+	if (property == dev_priv->broadcast_rgb_property) {
+		bool old_auto = intel_dp->color_range_auto;
+		bool old_range = intel_dp->limited_color_range;
+
+		switch (val) {
+		case INTEL_BROADCAST_RGB_AUTO:
+			intel_dp->color_range_auto = true;
+			break;
+		case INTEL_BROADCAST_RGB_FULL:
+			intel_dp->color_range_auto = false;
+			intel_dp->limited_color_range = false;
+			break;
+		case INTEL_BROADCAST_RGB_LIMITED:
+			intel_dp->color_range_auto = false;
+			intel_dp->limited_color_range = true;
+			break;
+		default:
+			return -EINVAL;
+		}
+
+		if (old_auto == intel_dp->color_range_auto &&
+		    old_range == intel_dp->limited_color_range)
+			return 0;
+
+		goto done;
+	}
+
+	if (is_edp(intel_dp) &&
+	    property == connector->dev->mode_config.scaling_mode_property) {
+		if (val == DRM_MODE_SCALE_NONE) {
+			DRM_DEBUG_KMS("no scaling not supported\n");
+			return -EINVAL;
+		}
+		if (HAS_GMCH_DISPLAY(dev_priv) &&
+		    val == DRM_MODE_SCALE_CENTER) {
+			DRM_DEBUG_KMS("centering not supported\n");
+			return -EINVAL;
+		}
+
+		if (intel_connector->panel.fitting_mode == val) {
+			/* the eDP scaling property is not changed */
+			return 0;
+		}
+		intel_connector->panel.fitting_mode = val;
+
+		goto done;
+	}
+
+	return -EINVAL;
+
+done:
+	if (intel_encoder->base.crtc)
+		intel_crtc_restore_mode(intel_encoder->base.crtc);
+
+	return 0;
+}
+
+static void
+intel_dp_connector_destroy(struct drm_connector *connector)
+{
+	struct intel_connector *intel_connector = to_intel_connector(connector);
+
+	kfree(intel_connector->detect_edid);
+
+	if (!IS_ERR_OR_NULL(intel_connector->edid))
+		kfree(intel_connector->edid);
+
+	/* Can't call is_edp() since the encoder may have been destroyed
+	 * already. */
+	if (connector->connector_type == DRM_MODE_CONNECTOR_eDP)
+		intel_panel_fini(&intel_connector->panel);
+
+	drm_connector_cleanup(connector);
+	kfree(connector);
+}
+
+void intel_dp_encoder_destroy(struct drm_encoder *encoder)
+{
+	struct intel_digital_port *intel_dig_port = enc_to_dig_port(encoder);
+	struct intel_dp *intel_dp = &intel_dig_port->dp;
+
+	intel_dp_mst_encoder_cleanup(intel_dig_port);
+	if (is_edp(intel_dp)) {
+		cancel_delayed_work_sync(&intel_dp->panel_vdd_work);
+		/*
+		 * vdd might still be enabled do to the delayed vdd off.
+		 * Make sure vdd is actually turned off here.
+		 */
+		pps_lock(intel_dp);
+		edp_panel_vdd_off_sync(intel_dp);
+		pps_unlock(intel_dp);
+
+		if (intel_dp->edp_notifier.notifier_call) {
+			unregister_reboot_notifier(&intel_dp->edp_notifier);
+			intel_dp->edp_notifier.notifier_call = NULL;
+		}
+	}
+	drm_encoder_cleanup(encoder);
+	kfree(intel_dig_port);
+}
+
+void intel_dp_encoder_suspend(struct intel_encoder *intel_encoder)
+{
+	struct intel_dp *intel_dp = enc_to_intel_dp(&intel_encoder->base);
+
+	if (!is_edp(intel_dp))
+		return;
+
+	/*
+	 * vdd might still be enabled do to the delayed vdd off.
+	 * Make sure vdd is actually turned off here.
+	 */
+	cancel_delayed_work_sync(&intel_dp->panel_vdd_work);
+	pps_lock(intel_dp);
+	edp_panel_vdd_off_sync(intel_dp);
+	pps_unlock(intel_dp);
+}
+
+static void intel_edp_panel_vdd_sanitize(struct intel_dp *intel_dp)
+{
+	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
+	struct drm_device *dev = intel_dig_port->base.base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	enum intel_display_power_domain power_domain;
+
+	lockdep_assert_held(&dev_priv->pps_mutex);
+
+	if (!edp_have_panel_vdd(intel_dp))
+		return;
+
+	/*
+	 * The VDD bit needs a power domain reference, so if the bit is
+	 * already enabled when we boot or resume, grab this reference and
+	 * schedule a vdd off, so we don't hold on to the reference
+	 * indefinitely.
+	 */
+	DRM_DEBUG_KMS("VDD left on by BIOS, adjusting state tracking\n");
+	power_domain = intel_display_port_aux_power_domain(&intel_dig_port->base);
+	intel_display_power_get(dev_priv, power_domain);
+
+	edp_panel_vdd_schedule_off(intel_dp);
+}
+
+void intel_dp_encoder_reset(struct drm_encoder *encoder)
+{
+	struct drm_i915_private *dev_priv = to_i915(encoder->dev);
+	struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
+
+	if (!HAS_DDI(dev_priv))
+		intel_dp->DP = I915_READ(intel_dp->output_reg);
+
+	if (to_intel_encoder(encoder)->type != INTEL_OUTPUT_EDP)
+		return;
+
+	pps_lock(intel_dp);
+
+	/*
+	 * Read out the current power sequencer assignment,
+	 * in case the BIOS did something with it.
+	 */
+	if (IS_VALLEYVIEW(encoder->dev) || IS_CHERRYVIEW(encoder->dev))
+		vlv_initial_power_sequencer_setup(intel_dp);
+
+	intel_edp_panel_vdd_sanitize(intel_dp);
+
+	pps_unlock(intel_dp);
+}
+
+static const struct drm_connector_funcs intel_dp_connector_funcs = {
+	.dpms = drm_atomic_helper_connector_dpms,
+	.detect = intel_dp_detect,
+	.force = intel_dp_force,
+	.fill_modes = drm_helper_probe_single_connector_modes,
+	.set_property = intel_dp_set_property,
+	.atomic_get_property = intel_connector_atomic_get_property,
+	.destroy = intel_dp_connector_destroy,
+	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
+	.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
+};
+
+static const struct drm_connector_helper_funcs intel_dp_connector_helper_funcs = {
+	.get_modes = intel_dp_get_modes,
+	.mode_valid = intel_dp_mode_valid,
+	.best_encoder = intel_best_encoder,
+};
+
+static const struct drm_encoder_funcs intel_dp_enc_funcs = {
+	.reset = intel_dp_encoder_reset,
+	.destroy = intel_dp_encoder_destroy,
+};
+
+enum irqreturn
+intel_dp_hpd_pulse(struct intel_digital_port *intel_dig_port, bool long_hpd)
+{
+	struct intel_dp *intel_dp = &intel_dig_port->dp;
+	struct intel_encoder *intel_encoder = &intel_dig_port->base;
+	struct drm_device *dev = intel_dig_port->base.base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	enum intel_display_power_domain power_domain;
+	enum irqreturn ret = IRQ_NONE;
+
+	if (intel_dig_port->base.type != INTEL_OUTPUT_EDP &&
+	    intel_dig_port->base.type != INTEL_OUTPUT_HDMI)
+		intel_dig_port->base.type = INTEL_OUTPUT_DISPLAYPORT;
+
+	if (long_hpd && intel_dig_port->base.type == INTEL_OUTPUT_EDP) {
+		/*
+		 * vdd off can generate a long pulse on eDP which
+		 * would require vdd on to handle it, and thus we
+		 * would end up in an endless cycle of
+		 * "vdd off -> long hpd -> vdd on -> detect -> vdd off -> ..."
+		 */
+		DRM_DEBUG_KMS("ignoring long hpd on eDP port %c\n",
+			      port_name(intel_dig_port->port));
+		return IRQ_HANDLED;
+	}
+
+	DRM_DEBUG_KMS("got hpd irq on port %c - %s\n",
+		      port_name(intel_dig_port->port),
+		      long_hpd ? "long" : "short");
+
+	power_domain = intel_display_port_aux_power_domain(intel_encoder);
+	intel_display_power_get(dev_priv, power_domain);
+
+	if (long_hpd) {
+		intel_dp_long_pulse(intel_dp->attached_connector);
+		if (intel_dp->is_mst)
+			ret = IRQ_HANDLED;
+		goto put_power;
+
+	} else {
+		if (intel_dp->is_mst) {
+			if (intel_dp_check_mst_status(intel_dp) == -EINVAL) {
+				/*
+				 * If we were in MST mode, and device is not
+				 * there, get out of MST mode
+				 */
+				DRM_DEBUG_KMS("MST device may have disappeared %d vs %d\n",
+					      intel_dp->is_mst, intel_dp->mst_mgr.mst_state);
+				intel_dp->is_mst = false;
+				drm_dp_mst_topology_mgr_set_mst(&intel_dp->mst_mgr,
+								intel_dp->is_mst);
+				goto put_power;
+			}
+		}
+
+		if (!intel_dp->is_mst) {
+			if (!intel_dp_short_pulse(intel_dp)) {
+				intel_dp_long_pulse(intel_dp->attached_connector);
+				goto put_power;
+			}
+		}
+	}
+
+	ret = IRQ_HANDLED;
+
+put_power:
+	intel_display_power_put(dev_priv, power_domain);
+
+	return ret;
+}
+
+/* check the VBT to see whether the eDP is on another port */
+bool intel_dp_is_edp(struct drm_device *dev, enum port port)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	/*
+	 * eDP not supported on g4x. so bail out early just
+	 * for a bit extra safety in case the VBT is bonkers.
+	 */
+	if (INTEL_INFO(dev)->gen < 5)
+		return false;
+
+	if (port == PORT_A)
+		return true;
+
+	return intel_bios_is_port_edp(dev_priv, port);
+}
+
+void
+intel_dp_add_properties(struct intel_dp *intel_dp, struct drm_connector *connector)
+{
+	struct intel_connector *intel_connector = to_intel_connector(connector);
+
+	intel_attach_force_audio_property(connector);
+	intel_attach_broadcast_rgb_property(connector);
+	intel_dp->color_range_auto = true;
+
+	if (is_edp(intel_dp)) {
+		drm_mode_create_scaling_mode_property(connector->dev);
+		drm_object_attach_property(
+			&connector->base,
+			connector->dev->mode_config.scaling_mode_property,
+			DRM_MODE_SCALE_ASPECT);
+		intel_connector->panel.fitting_mode = DRM_MODE_SCALE_ASPECT;
+	}
+}
+
+static void intel_dp_init_panel_power_timestamps(struct intel_dp *intel_dp)
+{
+	intel_dp->panel_power_off_time = ktime_get_boottime();
+	intel_dp->last_power_on = jiffies;
+	intel_dp->last_backlight_off = jiffies;
+}
+
+static void
+intel_dp_init_panel_power_sequencer(struct drm_device *dev,
+				    struct intel_dp *intel_dp)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct edp_power_seq cur, vbt, spec,
+		*final = &intel_dp->pps_delays;
+	u32 pp_on, pp_off, pp_div = 0, pp_ctl = 0;
+	i915_reg_t pp_ctrl_reg, pp_on_reg, pp_off_reg, pp_div_reg;
+
+	lockdep_assert_held(&dev_priv->pps_mutex);
+
+	/* already initialized? */
+	if (final->t11_t12 != 0)
+		return;
+
+	if (IS_BROXTON(dev)) {
+		/*
+		 * TODO: BXT has 2 sets of PPS registers.
+		 * Correct Register for Broxton need to be identified
+		 * using VBT. hardcoding for now
+		 */
+		pp_ctrl_reg = BXT_PP_CONTROL(0);
+		pp_on_reg = BXT_PP_ON_DELAYS(0);
+		pp_off_reg = BXT_PP_OFF_DELAYS(0);
+	} else if (HAS_PCH_SPLIT(dev)) {
+		pp_ctrl_reg = PCH_PP_CONTROL;
+		pp_on_reg = PCH_PP_ON_DELAYS;
+		pp_off_reg = PCH_PP_OFF_DELAYS;
+		pp_div_reg = PCH_PP_DIVISOR;
+	} else {
+		enum pipe pipe = vlv_power_sequencer_pipe(intel_dp);
+
+		pp_ctrl_reg = VLV_PIPE_PP_CONTROL(pipe);
+		pp_on_reg = VLV_PIPE_PP_ON_DELAYS(pipe);
+		pp_off_reg = VLV_PIPE_PP_OFF_DELAYS(pipe);
+		pp_div_reg = VLV_PIPE_PP_DIVISOR(pipe);
+	}
+
+	/* Workaround: Need to write PP_CONTROL with the unlock key as
+	 * the very first thing. */
+	pp_ctl = ironlake_get_pp_control(intel_dp);
+
+	pp_on = I915_READ(pp_on_reg);
+	pp_off = I915_READ(pp_off_reg);
+	if (!IS_BROXTON(dev)) {
+		I915_WRITE(pp_ctrl_reg, pp_ctl);
+		pp_div = I915_READ(pp_div_reg);
+	}
+
+	/* Pull timing values out of registers */
+	cur.t1_t3 = (pp_on & PANEL_POWER_UP_DELAY_MASK) >>
+		PANEL_POWER_UP_DELAY_SHIFT;
+
+	cur.t8 = (pp_on & PANEL_LIGHT_ON_DELAY_MASK) >>
+		PANEL_LIGHT_ON_DELAY_SHIFT;
+
+	cur.t9 = (pp_off & PANEL_LIGHT_OFF_DELAY_MASK) >>
+		PANEL_LIGHT_OFF_DELAY_SHIFT;
+
+	cur.t10 = (pp_off & PANEL_POWER_DOWN_DELAY_MASK) >>
+		PANEL_POWER_DOWN_DELAY_SHIFT;
+
+	if (IS_BROXTON(dev)) {
+		u16 tmp = (pp_ctl & BXT_POWER_CYCLE_DELAY_MASK) >>
+			BXT_POWER_CYCLE_DELAY_SHIFT;
+		if (tmp > 0)
+			cur.t11_t12 = (tmp - 1) * 1000;
+		else
+			cur.t11_t12 = 0;
+	} else {
+		cur.t11_t12 = ((pp_div & PANEL_POWER_CYCLE_DELAY_MASK) >>
+		       PANEL_POWER_CYCLE_DELAY_SHIFT) * 1000;
+	}
+
+	DRM_DEBUG_KMS("cur t1_t3 %d t8 %d t9 %d t10 %d t11_t12 %d\n",
+		      cur.t1_t3, cur.t8, cur.t9, cur.t10, cur.t11_t12);
+
+	vbt = dev_priv->vbt.edp.pps;
+
+	/* Upper limits from eDP 1.3 spec. Note that we use the clunky units of
+	 * our hw here, which are all in 100usec. */
+	spec.t1_t3 = 210 * 10;
+	spec.t8 = 50 * 10; /* no limit for t8, use t7 instead */
+	spec.t9 = 50 * 10; /* no limit for t9, make it symmetric with t8 */
+	spec.t10 = 500 * 10;
+	/* This one is special and actually in units of 100ms, but zero
+	 * based in the hw (so we need to add 100 ms). But the sw vbt
+	 * table multiplies it with 1000 to make it in units of 100usec,
+	 * too. */
+	spec.t11_t12 = (510 + 100) * 10;
+
+	DRM_DEBUG_KMS("vbt t1_t3 %d t8 %d t9 %d t10 %d t11_t12 %d\n",
+		      vbt.t1_t3, vbt.t8, vbt.t9, vbt.t10, vbt.t11_t12);
+
+	/* Use the max of the register settings and vbt. If both are
+	 * unset, fall back to the spec limits. */
+#define assign_final(field)	final->field = (max(cur.field, vbt.field) == 0 ? \
+				       spec.field : \
+				       max(cur.field, vbt.field))
+	assign_final(t1_t3);
+	assign_final(t8);
+	assign_final(t9);
+	assign_final(t10);
+	assign_final(t11_t12);
+#undef assign_final
+
+#define get_delay(field)	(DIV_ROUND_UP(final->field, 10))
+	intel_dp->panel_power_up_delay = get_delay(t1_t3);
+	intel_dp->backlight_on_delay = get_delay(t8);
+	intel_dp->backlight_off_delay = get_delay(t9);
+	intel_dp->panel_power_down_delay = get_delay(t10);
+	intel_dp->panel_power_cycle_delay = get_delay(t11_t12);
+#undef get_delay
+
+	DRM_DEBUG_KMS("panel power up delay %d, power down delay %d, power cycle delay %d\n",
+		      intel_dp->panel_power_up_delay, intel_dp->panel_power_down_delay,
+		      intel_dp->panel_power_cycle_delay);
+
+	DRM_DEBUG_KMS("backlight on delay %d, off delay %d\n",
+		      intel_dp->backlight_on_delay, intel_dp->backlight_off_delay);
+}
+
+static void
+intel_dp_init_panel_power_sequencer_registers(struct drm_device *dev,
+					      struct intel_dp *intel_dp)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	u32 pp_on, pp_off, pp_div, port_sel = 0;
+	int div = dev_priv->rawclk_freq / 1000;
+	i915_reg_t pp_on_reg, pp_off_reg, pp_div_reg, pp_ctrl_reg;
+	enum port port = dp_to_dig_port(intel_dp)->port;
+	const struct edp_power_seq *seq = &intel_dp->pps_delays;
+
+	lockdep_assert_held(&dev_priv->pps_mutex);
+
+	if (IS_BROXTON(dev)) {
+		/*
+		 * TODO: BXT has 2 sets of PPS registers.
+		 * Correct Register for Broxton need to be identified
+		 * using VBT. hardcoding for now
+		 */
+		pp_ctrl_reg = BXT_PP_CONTROL(0);
+		pp_on_reg = BXT_PP_ON_DELAYS(0);
+		pp_off_reg = BXT_PP_OFF_DELAYS(0);
+
+	} else if (HAS_PCH_SPLIT(dev)) {
+		pp_on_reg = PCH_PP_ON_DELAYS;
+		pp_off_reg = PCH_PP_OFF_DELAYS;
+		pp_div_reg = PCH_PP_DIVISOR;
+	} else {
+		enum pipe pipe = vlv_power_sequencer_pipe(intel_dp);
+
+		pp_on_reg = VLV_PIPE_PP_ON_DELAYS(pipe);
+		pp_off_reg = VLV_PIPE_PP_OFF_DELAYS(pipe);
+		pp_div_reg = VLV_PIPE_PP_DIVISOR(pipe);
+	}
+
+	/*
+	 * And finally store the new values in the power sequencer. The
+	 * backlight delays are set to 1 because we do manual waits on them. For
+	 * T8, even BSpec recommends doing it. For T9, if we don't do this,
+	 * we'll end up waiting for the backlight off delay twice: once when we
+	 * do the manual sleep, and once when we disable the panel and wait for
+	 * the PP_STATUS bit to become zero.
+	 */
+	pp_on = (seq->t1_t3 << PANEL_POWER_UP_DELAY_SHIFT) |
+		(1 << PANEL_LIGHT_ON_DELAY_SHIFT);
+	pp_off = (1 << PANEL_LIGHT_OFF_DELAY_SHIFT) |
+		 (seq->t10 << PANEL_POWER_DOWN_DELAY_SHIFT);
+	/* Compute the divisor for the pp clock, simply match the Bspec
+	 * formula. */
+	if (IS_BROXTON(dev)) {
+		pp_div = I915_READ(pp_ctrl_reg);
+		pp_div &= ~BXT_POWER_CYCLE_DELAY_MASK;
+		pp_div |= (DIV_ROUND_UP((seq->t11_t12 + 1), 1000)
+				<< BXT_POWER_CYCLE_DELAY_SHIFT);
+	} else {
+		pp_div = ((100 * div)/2 - 1) << PP_REFERENCE_DIVIDER_SHIFT;
+		pp_div |= (DIV_ROUND_UP(seq->t11_t12, 1000)
+				<< PANEL_POWER_CYCLE_DELAY_SHIFT);
+	}
+
+	/* Haswell doesn't have any port selection bits for the panel
+	 * power sequencer any more. */
+	if (IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev)) {
+		port_sel = PANEL_PORT_SELECT_VLV(port);
+	} else if (HAS_PCH_IBX(dev) || HAS_PCH_CPT(dev)) {
+		if (port == PORT_A)
+			port_sel = PANEL_PORT_SELECT_DPA;
+		else
+			port_sel = PANEL_PORT_SELECT_DPD;
+	}
+
+	pp_on |= port_sel;
+
+	I915_WRITE(pp_on_reg, pp_on);
+	I915_WRITE(pp_off_reg, pp_off);
+	if (IS_BROXTON(dev))
+		I915_WRITE(pp_ctrl_reg, pp_div);
+	else
+		I915_WRITE(pp_div_reg, pp_div);
+
+	DRM_DEBUG_KMS("panel power sequencer register settings: PP_ON %#x, PP_OFF %#x, PP_DIV %#x\n",
+		      I915_READ(pp_on_reg),
+		      I915_READ(pp_off_reg),
+		      IS_BROXTON(dev) ?
+		      (I915_READ(pp_ctrl_reg) & BXT_POWER_CYCLE_DELAY_MASK) :
+		      I915_READ(pp_div_reg));
+}
+
+/**
+ * intel_dp_set_drrs_state - program registers for RR switch to take effect
+ * @dev: DRM device
+ * @refresh_rate: RR to be programmed
+ *
+ * This function gets called when refresh rate (RR) has to be changed from
+ * one frequency to another. Switches can be between high and low RR
+ * supported by the panel or to any other RR based on media playback (in
+ * this case, RR value needs to be passed from user space).
+ *
+ * The caller of this function needs to take a lock on dev_priv->drrs.
+ */
+static void intel_dp_set_drrs_state(struct drm_device *dev, int refresh_rate)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_encoder *encoder;
+	struct intel_digital_port *dig_port = NULL;
+	struct intel_dp *intel_dp = dev_priv->drrs.dp;
+	struct intel_crtc_state *config = NULL;
+	struct intel_crtc *intel_crtc = NULL;
+	enum drrs_refresh_rate_type index = DRRS_HIGH_RR;
+
+	if (refresh_rate <= 0) {
+		DRM_DEBUG_KMS("Refresh rate should be positive non-zero.\n");
+		return;
+	}
+
+	if (intel_dp == NULL) {
+		DRM_DEBUG_KMS("DRRS not supported.\n");
+		return;
+	}
+
+	/*
+	 * FIXME: This needs proper synchronization with psr state for some
+	 * platforms that cannot have PSR and DRRS enabled at the same time.
+	 */
+
+	dig_port = dp_to_dig_port(intel_dp);
+	encoder = &dig_port->base;
+	intel_crtc = to_intel_crtc(encoder->base.crtc);
+
+	if (!intel_crtc) {
+		DRM_DEBUG_KMS("DRRS: intel_crtc not initialized\n");
+		return;
+	}
+
+	config = intel_crtc->config;
+
+	if (dev_priv->drrs.type < SEAMLESS_DRRS_SUPPORT) {
+		DRM_DEBUG_KMS("Only Seamless DRRS supported.\n");
+		return;
+	}
+
+	if (intel_dp->attached_connector->panel.downclock_mode->vrefresh ==
+			refresh_rate)
+		index = DRRS_LOW_RR;
+
+	if (index == dev_priv->drrs.refresh_rate_type) {
+		DRM_DEBUG_KMS(
+			"DRRS requested for previously set RR...ignoring\n");
+		return;
+	}
+
+	if (!intel_crtc->active) {
+		DRM_DEBUG_KMS("eDP encoder disabled. CRTC not Active\n");
+		return;
+	}
+
+	if (INTEL_INFO(dev)->gen >= 8 && !IS_CHERRYVIEW(dev)) {
+		switch (index) {
+		case DRRS_HIGH_RR:
+			intel_dp_set_m_n(intel_crtc, M1_N1);
+			break;
+		case DRRS_LOW_RR:
+			intel_dp_set_m_n(intel_crtc, M2_N2);
+			break;
+		case DRRS_MAX_RR:
+		default:
+			DRM_ERROR("Unsupported refreshrate type\n");
+		}
+	} else if (INTEL_INFO(dev)->gen > 6) {
+		i915_reg_t reg = PIPECONF(intel_crtc->config->cpu_transcoder);
+		u32 val;
+
+		val = I915_READ(reg);
+		if (index > DRRS_HIGH_RR) {
+			if (IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev))
+				val |= PIPECONF_EDP_RR_MODE_SWITCH_VLV;
+			else
+				val |= PIPECONF_EDP_RR_MODE_SWITCH;
+		} else {
+			if (IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev))
+				val &= ~PIPECONF_EDP_RR_MODE_SWITCH_VLV;
+			else
+				val &= ~PIPECONF_EDP_RR_MODE_SWITCH;
+		}
+		I915_WRITE(reg, val);
+	}
+
+	dev_priv->drrs.refresh_rate_type = index;
+
+	DRM_DEBUG_KMS("eDP Refresh Rate set to : %dHz\n", refresh_rate);
+}
+
+/**
+ * intel_edp_drrs_enable - init drrs struct if supported
+ * @intel_dp: DP struct
+ *
+ * Initializes frontbuffer_bits and drrs.dp
+ */
+void intel_edp_drrs_enable(struct intel_dp *intel_dp)
+{
+	struct drm_device *dev = intel_dp_to_dev(intel_dp);
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
+	struct drm_crtc *crtc = dig_port->base.base.crtc;
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+
+	if (!intel_crtc->config->has_drrs) {
+		DRM_DEBUG_KMS("Panel doesn't support DRRS\n");
+		return;
+	}
+
+	mutex_lock(&dev_priv->drrs.mutex);
+	if (WARN_ON(dev_priv->drrs.dp)) {
+		DRM_ERROR("DRRS already enabled\n");
+		goto unlock;
+	}
+
+	dev_priv->drrs.busy_frontbuffer_bits = 0;
+
+	dev_priv->drrs.dp = intel_dp;
+
+unlock:
+	mutex_unlock(&dev_priv->drrs.mutex);
+}
+
+/**
+ * intel_edp_drrs_disable - Disable DRRS
+ * @intel_dp: DP struct
+ *
+ */
+void intel_edp_drrs_disable(struct intel_dp *intel_dp)
+{
+	struct drm_device *dev = intel_dp_to_dev(intel_dp);
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
+	struct drm_crtc *crtc = dig_port->base.base.crtc;
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+
+	if (!intel_crtc->config->has_drrs)
+		return;
+
+	mutex_lock(&dev_priv->drrs.mutex);
+	if (!dev_priv->drrs.dp) {
+		mutex_unlock(&dev_priv->drrs.mutex);
+		return;
+	}
+
+	if (dev_priv->drrs.refresh_rate_type == DRRS_LOW_RR)
+		intel_dp_set_drrs_state(dev_priv->dev,
+			intel_dp->attached_connector->panel.
+			fixed_mode->vrefresh);
+
+	dev_priv->drrs.dp = NULL;
+	mutex_unlock(&dev_priv->drrs.mutex);
+
+	cancel_delayed_work_sync(&dev_priv->drrs.work);
+}
+
+static void intel_edp_drrs_downclock_work(struct work_struct *work)
+{
+	struct drm_i915_private *dev_priv =
+		container_of(work, typeof(*dev_priv), drrs.work.work);
+	struct intel_dp *intel_dp;
+
+	mutex_lock(&dev_priv->drrs.mutex);
+
+	intel_dp = dev_priv->drrs.dp;
+
+	if (!intel_dp)
+		goto unlock;
+
+	/*
+	 * The delayed work can race with an invalidate hence we need to
+	 * recheck.
+	 */
+
+	if (dev_priv->drrs.busy_frontbuffer_bits)
+		goto unlock;
+
+	if (dev_priv->drrs.refresh_rate_type != DRRS_LOW_RR)
+		intel_dp_set_drrs_state(dev_priv->dev,
+			intel_dp->attached_connector->panel.
+			downclock_mode->vrefresh);
+
+unlock:
+	mutex_unlock(&dev_priv->drrs.mutex);
+}
+
+/**
+ * intel_edp_drrs_invalidate - Disable Idleness DRRS
+ * @dev: DRM device
+ * @frontbuffer_bits: frontbuffer plane tracking bits
+ *
+ * This function gets called everytime rendering on the given planes start.
+ * Hence DRRS needs to be Upclocked, i.e. (LOW_RR -> HIGH_RR).
+ *
+ * Dirty frontbuffers relevant to DRRS are tracked in busy_frontbuffer_bits.
+ */
+void intel_edp_drrs_invalidate(struct drm_device *dev,
+		unsigned frontbuffer_bits)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct drm_crtc *crtc;
+	enum pipe pipe;
+
+	if (dev_priv->drrs.type == DRRS_NOT_SUPPORTED)
+		return;
+
+	cancel_delayed_work(&dev_priv->drrs.work);
+
+	mutex_lock(&dev_priv->drrs.mutex);
+	if (!dev_priv->drrs.dp) {
+		mutex_unlock(&dev_priv->drrs.mutex);
+		return;
+	}
+
+	crtc = dp_to_dig_port(dev_priv->drrs.dp)->base.base.crtc;
+	pipe = to_intel_crtc(crtc)->pipe;
+
+	frontbuffer_bits &= INTEL_FRONTBUFFER_ALL_MASK(pipe);
+	dev_priv->drrs.busy_frontbuffer_bits |= frontbuffer_bits;
+
+	/* invalidate means busy screen hence upclock */
+	if (frontbuffer_bits && dev_priv->drrs.refresh_rate_type == DRRS_LOW_RR)
+		intel_dp_set_drrs_state(dev_priv->dev,
+				dev_priv->drrs.dp->attached_connector->panel.
+				fixed_mode->vrefresh);
+
+	mutex_unlock(&dev_priv->drrs.mutex);
+}
+
+/**
+ * intel_edp_drrs_flush - Restart Idleness DRRS
+ * @dev: DRM device
+ * @frontbuffer_bits: frontbuffer plane tracking bits
+ *
+ * This function gets called every time rendering on the given planes has
+ * completed or flip on a crtc is completed. So DRRS should be upclocked
+ * (LOW_RR -> HIGH_RR). And also Idleness detection should be started again,
+ * if no other planes are dirty.
+ *
+ * Dirty frontbuffers relevant to DRRS are tracked in busy_frontbuffer_bits.
+ */
+void intel_edp_drrs_flush(struct drm_device *dev,
+		unsigned frontbuffer_bits)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct drm_crtc *crtc;
+	enum pipe pipe;
+
+	if (dev_priv->drrs.type == DRRS_NOT_SUPPORTED)
+		return;
+
+	cancel_delayed_work(&dev_priv->drrs.work);
+
+	mutex_lock(&dev_priv->drrs.mutex);
+	if (!dev_priv->drrs.dp) {
+		mutex_unlock(&dev_priv->drrs.mutex);
+		return;
+	}
+
+	crtc = dp_to_dig_port(dev_priv->drrs.dp)->base.base.crtc;
+	pipe = to_intel_crtc(crtc)->pipe;
+
+	frontbuffer_bits &= INTEL_FRONTBUFFER_ALL_MASK(pipe);
+	dev_priv->drrs.busy_frontbuffer_bits &= ~frontbuffer_bits;
+
+	/* flush means busy screen hence upclock */
+	if (frontbuffer_bits && dev_priv->drrs.refresh_rate_type == DRRS_LOW_RR)
+		intel_dp_set_drrs_state(dev_priv->dev,
+				dev_priv->drrs.dp->attached_connector->panel.
+				fixed_mode->vrefresh);
+
+	/*
+	 * flush also means no more activity hence schedule downclock, if all
+	 * other fbs are quiescent too
+	 */
+	if (!dev_priv->drrs.busy_frontbuffer_bits)
+		schedule_delayed_work(&dev_priv->drrs.work,
+				msecs_to_jiffies(1000));
+	mutex_unlock(&dev_priv->drrs.mutex);
+}
+
+/**
+ * DOC: Display Refresh Rate Switching (DRRS)
+ *
+ * Display Refresh Rate Switching (DRRS) is a power conservation feature
+ * which enables swtching between low and high refresh rates,
+ * dynamically, based on the usage scenario. This feature is applicable
+ * for internal panels.
+ *
+ * Indication that the panel supports DRRS is given by the panel EDID, which
+ * would list multiple refresh rates for one resolution.
+ *
+ * DRRS is of 2 types - static and seamless.
+ * Static DRRS involves changing refresh rate (RR) by doing a full modeset
+ * (may appear as a blink on screen) and is used in dock-undock scenario.
+ * Seamless DRRS involves changing RR without any visual effect to the user
+ * and can be used during normal system usage. This is done by programming
+ * certain registers.
+ *
+ * Support for static/seamless DRRS may be indicated in the VBT based on
+ * inputs from the panel spec.
+ *
+ * DRRS saves power by switching to low RR based on usage scenarios.
+ *
+ * eDP DRRS:-
+ *        The implementation is based on frontbuffer tracking implementation.
+ * When there is a disturbance on the screen triggered by user activity or a
+ * periodic system activity, DRRS is disabled (RR is changed to high RR).
+ * When there is no movement on screen, after a timeout of 1 second, a switch
+ * to low RR is made.
+ *        For integration with frontbuffer tracking code,
+ * intel_edp_drrs_invalidate() and intel_edp_drrs_flush() are called.
+ *
+ * DRRS can be further extended to support other internal panels and also
+ * the scenario of video playback wherein RR is set based on the rate
+ * requested by userspace.
+ */
+
+/**
+ * intel_dp_drrs_init - Init basic DRRS work and mutex.
+ * @intel_connector: eDP connector
+ * @fixed_mode: preferred mode of panel
+ *
+ * This function is  called only once at driver load to initialize basic
+ * DRRS stuff.
+ *
+ * Returns:
+ * Downclock mode if panel supports it, else return NULL.
+ * DRRS support is determined by the presence of downclock mode (apart
+ * from VBT setting).
+ */
+static struct drm_display_mode *
+intel_dp_drrs_init(struct intel_connector *intel_connector,
+		struct drm_display_mode *fixed_mode)
+{
+	struct drm_connector *connector = &intel_connector->base;
+	struct drm_device *dev = connector->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct drm_display_mode *downclock_mode = NULL;
+
+	INIT_DELAYED_WORK(&dev_priv->drrs.work, intel_edp_drrs_downclock_work);
+	mutex_init(&dev_priv->drrs.mutex);
+
+	if (INTEL_INFO(dev)->gen <= 6) {
+		DRM_DEBUG_KMS("DRRS supported for Gen7 and above\n");
+		return NULL;
+	}
+
+	if (dev_priv->vbt.drrs_type != SEAMLESS_DRRS_SUPPORT) {
+		DRM_DEBUG_KMS("VBT doesn't support DRRS\n");
+		return NULL;
+	}
+
+	downclock_mode = intel_find_panel_downclock
+					(dev, fixed_mode, connector);
+
+	if (!downclock_mode) {
+		DRM_DEBUG_KMS("Downclock mode is not found. DRRS not supported\n");
+		return NULL;
+	}
+
+	dev_priv->drrs.type = dev_priv->vbt.drrs_type;
+
+	dev_priv->drrs.refresh_rate_type = DRRS_HIGH_RR;
+	DRM_DEBUG_KMS("seamless DRRS supported for eDP panel.\n");
+	return downclock_mode;
+}
+
+static bool intel_edp_init_connector(struct intel_dp *intel_dp,
+				     struct intel_connector *intel_connector)
+{
+	struct drm_connector *connector = &intel_connector->base;
+	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
+	struct intel_encoder *intel_encoder = &intel_dig_port->base;
+	struct drm_device *dev = intel_encoder->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct drm_display_mode *fixed_mode = NULL;
+	struct drm_display_mode *downclock_mode = NULL;
+	bool has_dpcd;
+	struct drm_display_mode *scan;
+	struct edid *edid;
+	enum pipe pipe = INVALID_PIPE;
+
+	if (!is_edp(intel_dp))
+		return true;
+
+	pps_lock(intel_dp);
+	intel_edp_panel_vdd_sanitize(intel_dp);
+	pps_unlock(intel_dp);
+
+	/* Cache DPCD and EDID for edp. */
+	has_dpcd = intel_dp_get_dpcd(intel_dp);
+
+	if (has_dpcd) {
+		if (intel_dp->dpcd[DP_DPCD_REV] >= 0x11)
+			dev_priv->no_aux_handshake =
+				intel_dp->dpcd[DP_MAX_DOWNSPREAD] &
+				DP_NO_AUX_HANDSHAKE_LINK_TRAINING;
+	} else {
+		/* if this fails, presume the device is a ghost */
+		DRM_INFO("failed to retrieve link info, disabling eDP\n");
+		return false;
+	}
+
+	/* We now know it's not a ghost, init power sequence regs. */
+	pps_lock(intel_dp);
+	intel_dp_init_panel_power_sequencer_registers(dev, intel_dp);
+	pps_unlock(intel_dp);
+
+	mutex_lock(&dev->mode_config.mutex);
+	edid = drm_get_edid(connector, &intel_dp->aux.ddc);
+	if (edid) {
+		if (drm_add_edid_modes(connector, edid)) {
+			drm_mode_connector_update_edid_property(connector,
+								edid);
+			drm_edid_to_eld(connector, edid);
+		} else {
+			kfree(edid);
+			edid = ERR_PTR(-EINVAL);
+		}
+	} else {
+		edid = ERR_PTR(-ENOENT);
+	}
+	intel_connector->edid = edid;
+
+	/* prefer fixed mode from EDID if available */
+	list_for_each_entry(scan, &connector->probed_modes, head) {
+		if ((scan->type & DRM_MODE_TYPE_PREFERRED)) {
+			fixed_mode = drm_mode_duplicate(dev, scan);
+			downclock_mode = intel_dp_drrs_init(
+						intel_connector, fixed_mode);
+			break;
+		}
+	}
+
+	/* fallback to VBT if available for eDP */
+	if (!fixed_mode && dev_priv->vbt.lfp_lvds_vbt_mode) {
+		fixed_mode = drm_mode_duplicate(dev,
+					dev_priv->vbt.lfp_lvds_vbt_mode);
+		if (fixed_mode) {
+			fixed_mode->type |= DRM_MODE_TYPE_PREFERRED;
+			connector->display_info.width_mm = fixed_mode->width_mm;
+			connector->display_info.height_mm = fixed_mode->height_mm;
+		}
+	}
+	mutex_unlock(&dev->mode_config.mutex);
+
+	if (IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev)) {
+		intel_dp->edp_notifier.notifier_call = edp_notify_handler;
+		register_reboot_notifier(&intel_dp->edp_notifier);
+
+		/*
+		 * Figure out the current pipe for the initial backlight setup.
+		 * If the current pipe isn't valid, try the PPS pipe, and if that
+		 * fails just assume pipe A.
+		 */
+		if (IS_CHERRYVIEW(dev))
+			pipe = DP_PORT_TO_PIPE_CHV(intel_dp->DP);
+		else
+			pipe = PORT_TO_PIPE(intel_dp->DP);
+
+		if (pipe != PIPE_A && pipe != PIPE_B)
+			pipe = intel_dp->pps_pipe;
+
+		if (pipe != PIPE_A && pipe != PIPE_B)
+			pipe = PIPE_A;
+
+		DRM_DEBUG_KMS("using pipe %c for initial backlight setup\n",
+			      pipe_name(pipe));
+	}
+
+	intel_panel_init(&intel_connector->panel, fixed_mode, downclock_mode);
+	intel_connector->panel.backlight.power = intel_edp_backlight_power;
+	intel_panel_setup_backlight(connector, pipe);
+
+	return true;
+}
+
+bool
+intel_dp_init_connector(struct intel_digital_port *intel_dig_port,
+			struct intel_connector *intel_connector)
+{
+	struct drm_connector *connector = &intel_connector->base;
+	struct intel_dp *intel_dp = &intel_dig_port->dp;
+	struct intel_encoder *intel_encoder = &intel_dig_port->base;
+	struct drm_device *dev = intel_encoder->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	enum port port = intel_dig_port->port;
+	int type, ret;
+
+	if (WARN(intel_dig_port->max_lanes < 1,
+		 "Not enough lanes (%d) for DP on port %c\n",
+		 intel_dig_port->max_lanes, port_name(port)))
+		return false;
+
+	intel_dp->pps_pipe = INVALID_PIPE;
+
+	/* intel_dp vfuncs */
+	if (INTEL_INFO(dev)->gen >= 9)
+		intel_dp->get_aux_clock_divider = skl_get_aux_clock_divider;
+	else if (IS_HASWELL(dev) || IS_BROADWELL(dev))
+		intel_dp->get_aux_clock_divider = hsw_get_aux_clock_divider;
+	else if (HAS_PCH_SPLIT(dev))
+		intel_dp->get_aux_clock_divider = ilk_get_aux_clock_divider;
+	else
+		intel_dp->get_aux_clock_divider = g4x_get_aux_clock_divider;
+
+	if (INTEL_INFO(dev)->gen >= 9)
+		intel_dp->get_aux_send_ctl = skl_get_aux_send_ctl;
+	else
+		intel_dp->get_aux_send_ctl = g4x_get_aux_send_ctl;
+
+	if (HAS_DDI(dev))
+		intel_dp->prepare_link_retrain = intel_ddi_prepare_link_retrain;
+
+	/* Preserve the current hw state. */
+	intel_dp->DP = I915_READ(intel_dp->output_reg);
+	intel_dp->attached_connector = intel_connector;
+
+	if (intel_dp_is_edp(dev, port))
+		type = DRM_MODE_CONNECTOR_eDP;
+	else
+		type = DRM_MODE_CONNECTOR_DisplayPort;
+
+	/*
+	 * For eDP we always set the encoder type to INTEL_OUTPUT_EDP, but
+	 * for DP the encoder type can be set by the caller to
+	 * INTEL_OUTPUT_UNKNOWN for DDI, so don't rewrite it.
+	 */
+	if (type == DRM_MODE_CONNECTOR_eDP)
+		intel_encoder->type = INTEL_OUTPUT_EDP;
+
+	/* eDP only on port B and/or C on vlv/chv */
+	if (WARN_ON((IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev)) &&
+		    is_edp(intel_dp) && port != PORT_B && port != PORT_C))
+		return false;
+
+	DRM_DEBUG_KMS("Adding %s connector on port %c\n",
+			type == DRM_MODE_CONNECTOR_eDP ? "eDP" : "DP",
+			port_name(port));
+
+	drm_connector_init(dev, connector, &intel_dp_connector_funcs, type);
+	drm_connector_helper_add(connector, &intel_dp_connector_helper_funcs);
+
+	connector->interlace_allowed = true;
+	connector->doublescan_allowed = 0;
+
+	INIT_DELAYED_WORK(&intel_dp->panel_vdd_work,
+			  edp_panel_vdd_work);
+
+	intel_connector_attach_encoder(intel_connector, intel_encoder);
+	drm_connector_register(connector);
+
+	if (HAS_DDI(dev))
+		intel_connector->get_hw_state = intel_ddi_connector_get_hw_state;
+	else
+		intel_connector->get_hw_state = intel_connector_get_hw_state;
+	intel_connector->unregister = intel_dp_connector_unregister;
+
+	/* Set up the hotplug pin. */
+	switch (port) {
+	case PORT_A:
+		intel_encoder->hpd_pin = HPD_PORT_A;
+		break;
+	case PORT_B:
+		intel_encoder->hpd_pin = HPD_PORT_B;
+		if (IS_BXT_REVID(dev, 0, BXT_REVID_A1))
+			intel_encoder->hpd_pin = HPD_PORT_A;
+		break;
+	case PORT_C:
+		intel_encoder->hpd_pin = HPD_PORT_C;
+		break;
+	case PORT_D:
+		intel_encoder->hpd_pin = HPD_PORT_D;
+		break;
+	case PORT_E:
+		intel_encoder->hpd_pin = HPD_PORT_E;
+		break;
+	default:
+		BUG();
+	}
+
+	if (is_edp(intel_dp)) {
+		pps_lock(intel_dp);
+		intel_dp_init_panel_power_timestamps(intel_dp);
+		if (IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev))
+			vlv_initial_power_sequencer_setup(intel_dp);
+		else
+			intel_dp_init_panel_power_sequencer(dev, intel_dp);
+		pps_unlock(intel_dp);
+	}
+
+	ret = intel_dp_aux_init(intel_dp, intel_connector);
+	if (ret)
+		goto fail;
+
+	/* init MST on ports that can support it */
+	if (HAS_DP_MST(dev) &&
+	    (port == PORT_B || port == PORT_C || port == PORT_D))
+		intel_dp_mst_encoder_init(intel_dig_port,
+					  intel_connector->base.base.id);
+
+	if (!intel_edp_init_connector(intel_dp, intel_connector)) {
+		intel_dp_aux_fini(intel_dp);
+		intel_dp_mst_encoder_cleanup(intel_dig_port);
+		goto fail;
+	}
+
+	intel_dp_add_properties(intel_dp, connector);
+
+	/* For G4X desktop chip, PEG_BAND_GAP_DATA 3:0 must first be written
+	 * 0xd.  Failure to do so will result in spurious interrupts being
+	 * generated on the port when a cable is not attached.
+	 */
+	if (IS_G4X(dev) && !IS_GM45(dev)) {
+		u32 temp = I915_READ(PEG_BAND_GAP_DATA);
+		I915_WRITE(PEG_BAND_GAP_DATA, (temp & ~0xf) | 0xd);
+	}
+
+	i915_debugfs_connector_add(connector);
+
+	return true;
+
+fail:
+	if (is_edp(intel_dp)) {
+		cancel_delayed_work_sync(&intel_dp->panel_vdd_work);
+		/*
+		 * vdd might still be enabled do to the delayed vdd off.
+		 * Make sure vdd is actually turned off here.
+		 */
+		pps_lock(intel_dp);
+		edp_panel_vdd_off_sync(intel_dp);
+		pps_unlock(intel_dp);
+	}
+	drm_connector_unregister(connector);
+	drm_connector_cleanup(connector);
+
+	return false;
+}
+
+bool intel_dp_init(struct drm_device *dev,
+		   i915_reg_t output_reg,
+		   enum port port)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_digital_port *intel_dig_port;
+	struct intel_encoder *intel_encoder;
+	struct drm_encoder *encoder;
+	struct intel_connector *intel_connector;
+
+	intel_dig_port = kzalloc(sizeof(*intel_dig_port), GFP_KERNEL);
+	if (!intel_dig_port)
+		return false;
+
+	intel_connector = intel_connector_alloc();
+	if (!intel_connector)
+		goto err_connector_alloc;
+
+	intel_encoder = &intel_dig_port->base;
+	encoder = &intel_encoder->base;
+
+	if (drm_encoder_init(dev, &intel_encoder->base, &intel_dp_enc_funcs,
+			     DRM_MODE_ENCODER_TMDS))
+		goto err_encoder_init;
+
+	intel_encoder->compute_config = intel_dp_compute_config;
+	intel_encoder->disable = intel_disable_dp;
+	intel_encoder->get_hw_state = intel_dp_get_hw_state;
+	intel_encoder->get_config = intel_dp_get_config;
+	intel_encoder->suspend = intel_dp_encoder_suspend;
+	if (IS_CHERRYVIEW(dev)) {
+		intel_encoder->pre_pll_enable = chv_dp_pre_pll_enable;
+		intel_encoder->pre_enable = chv_pre_enable_dp;
+		intel_encoder->enable = vlv_enable_dp;
+		intel_encoder->post_disable = chv_post_disable_dp;
+		intel_encoder->post_pll_disable = chv_dp_post_pll_disable;
+	} else if (IS_VALLEYVIEW(dev)) {
+		intel_encoder->pre_pll_enable = vlv_dp_pre_pll_enable;
+		intel_encoder->pre_enable = vlv_pre_enable_dp;
+		intel_encoder->enable = vlv_enable_dp;
+		intel_encoder->post_disable = vlv_post_disable_dp;
+	} else {
+		intel_encoder->pre_enable = g4x_pre_enable_dp;
+		intel_encoder->enable = g4x_enable_dp;
+		if (INTEL_INFO(dev)->gen >= 5)
+			intel_encoder->post_disable = ilk_post_disable_dp;
+	}
+
+	intel_dig_port->port = port;
+	intel_dig_port->dp.output_reg = output_reg;
+	intel_dig_port->max_lanes = 4;
+
+	intel_encoder->type = INTEL_OUTPUT_DISPLAYPORT;
+	if (IS_CHERRYVIEW(dev)) {
+		if (port == PORT_D)
+			intel_encoder->crtc_mask = 1 << 2;
+		else
+			intel_encoder->crtc_mask = (1 << 0) | (1 << 1);
+	} else {
+		intel_encoder->crtc_mask = (1 << 0) | (1 << 1) | (1 << 2);
+	}
+	intel_encoder->cloneable = 0;
+
+	intel_dig_port->hpd_pulse = intel_dp_hpd_pulse;
+	dev_priv->hotplug.irq_port[port] = intel_dig_port;
+
+	if (!intel_dp_init_connector(intel_dig_port, intel_connector))
+		goto err_init_connector;
+
+	return true;
+
+err_init_connector:
+	drm_encoder_cleanup(encoder);
+err_encoder_init:
+	kfree(intel_connector);
+err_connector_alloc:
+	kfree(intel_dig_port);
+	return false;
+}
+
+void intel_dp_mst_suspend(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	int i;
+
+	/* disable MST */
+	for (i = 0; i < I915_MAX_PORTS; i++) {
+		struct intel_digital_port *intel_dig_port = dev_priv->hotplug.irq_port[i];
+		if (!intel_dig_port)
+			continue;
+
+		if (intel_dig_port->base.type == INTEL_OUTPUT_DISPLAYPORT) {
+			if (!intel_dig_port->dp.can_mst)
+				continue;
+			if (intel_dig_port->dp.is_mst)
+				drm_dp_mst_topology_mgr_suspend(&intel_dig_port->dp.mst_mgr);
+		}
+	}
+}
+
+void intel_dp_mst_resume(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	int i;
+
+	for (i = 0; i < I915_MAX_PORTS; i++) {
+		struct intel_digital_port *intel_dig_port = dev_priv->hotplug.irq_port[i];
+		if (!intel_dig_port)
+			continue;
+		if (intel_dig_port->base.type == INTEL_OUTPUT_DISPLAYPORT) {
+			int ret;
+
+			if (!intel_dig_port->dp.can_mst)
+				continue;
+
+			ret = drm_dp_mst_topology_mgr_resume(&intel_dig_port->dp.mst_mgr);
+			if (ret != 0) {
+				intel_dp_check_mst_status(&intel_dig_port->dp);
+			}
+		}
+	}
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/i915/intel_dp_link_training.c
@@ -0,0 +1,320 @@
+/*
+ * Copyright © 2008-2015 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include "intel_drv.h"
+
+static void
+intel_get_adjust_train(struct intel_dp *intel_dp,
+		       const uint8_t link_status[DP_LINK_STATUS_SIZE])
+{
+	uint8_t v = 0;
+	uint8_t p = 0;
+	int lane;
+	uint8_t voltage_max;
+	uint8_t preemph_max;
+
+	for (lane = 0; lane < intel_dp->lane_count; lane++) {
+		uint8_t this_v = drm_dp_get_adjust_request_voltage(link_status, lane);
+		uint8_t this_p = drm_dp_get_adjust_request_pre_emphasis(link_status, lane);
+
+		if (this_v > v)
+			v = this_v;
+		if (this_p > p)
+			p = this_p;
+	}
+
+	voltage_max = intel_dp_voltage_max(intel_dp);
+	if (v >= voltage_max)
+		v = voltage_max | DP_TRAIN_MAX_SWING_REACHED;
+
+	preemph_max = intel_dp_pre_emphasis_max(intel_dp, v);
+	if (p >= preemph_max)
+		p = preemph_max | DP_TRAIN_MAX_PRE_EMPHASIS_REACHED;
+
+	for (lane = 0; lane < 4; lane++)
+		intel_dp->train_set[lane] = v | p;
+}
+
+static bool
+intel_dp_set_link_train(struct intel_dp *intel_dp,
+			uint8_t dp_train_pat)
+{
+	uint8_t buf[sizeof(intel_dp->train_set) + 1];
+	int ret, len;
+
+	intel_dp_program_link_training_pattern(intel_dp, dp_train_pat);
+
+	buf[0] = dp_train_pat;
+	if ((dp_train_pat & DP_TRAINING_PATTERN_MASK) ==
+	    DP_TRAINING_PATTERN_DISABLE) {
+		/* don't write DP_TRAINING_LANEx_SET on disable */
+		len = 1;
+	} else {
+		/* DP_TRAINING_LANEx_SET follow DP_TRAINING_PATTERN_SET */
+		memcpy(buf + 1, intel_dp->train_set, intel_dp->lane_count);
+		len = intel_dp->lane_count + 1;
+	}
+
+	ret = drm_dp_dpcd_write(&intel_dp->aux, DP_TRAINING_PATTERN_SET,
+				buf, len);
+
+	return ret == len;
+}
+
+static bool
+intel_dp_reset_link_train(struct intel_dp *intel_dp,
+			uint8_t dp_train_pat)
+{
+	memset(intel_dp->train_set, 0, sizeof(intel_dp->train_set));
+	intel_dp_set_signal_levels(intel_dp);
+	return intel_dp_set_link_train(intel_dp, dp_train_pat);
+}
+
+static bool
+intel_dp_update_link_train(struct intel_dp *intel_dp)
+{
+	int ret;
+
+	intel_dp_set_signal_levels(intel_dp);
+
+	ret = drm_dp_dpcd_write(&intel_dp->aux, DP_TRAINING_LANE0_SET,
+				intel_dp->train_set, intel_dp->lane_count);
+
+	return ret == intel_dp->lane_count;
+}
+
+/* Enable corresponding port and start training pattern 1 */
+static void
+intel_dp_link_training_clock_recovery(struct intel_dp *intel_dp)
+{
+	int i;
+	uint8_t voltage;
+	int voltage_tries, loop_tries;
+	uint8_t link_config[2];
+	uint8_t link_bw, rate_select;
+
+	if (intel_dp->prepare_link_retrain)
+		intel_dp->prepare_link_retrain(intel_dp);
+
+	intel_dp_compute_rate(intel_dp, intel_dp->link_rate,
+			      &link_bw, &rate_select);
+
+	/* Write the link configuration data */
+	link_config[0] = link_bw;
+	link_config[1] = intel_dp->lane_count;
+	if (drm_dp_enhanced_frame_cap(intel_dp->dpcd))
+		link_config[1] |= DP_LANE_COUNT_ENHANCED_FRAME_EN;
+	drm_dp_dpcd_write(&intel_dp->aux, DP_LINK_BW_SET, link_config, 2);
+	if (intel_dp->num_sink_rates)
+		drm_dp_dpcd_write(&intel_dp->aux, DP_LINK_RATE_SET,
+				  &rate_select, 1);
+
+	link_config[0] = 0;
+	link_config[1] = DP_SET_ANSI_8B10B;
+	drm_dp_dpcd_write(&intel_dp->aux, DP_DOWNSPREAD_CTRL, link_config, 2);
+
+	intel_dp->DP |= DP_PORT_EN;
+
+	/* clock recovery */
+	if (!intel_dp_reset_link_train(intel_dp,
+				       DP_TRAINING_PATTERN_1 |
+				       DP_LINK_SCRAMBLING_DISABLE)) {
+		DRM_ERROR("failed to enable link training\n");
+		return;
+	}
+
+	voltage = 0xff;
+	voltage_tries = 0;
+	loop_tries = 0;
+	for (;;) {
+		uint8_t link_status[DP_LINK_STATUS_SIZE];
+
+		drm_dp_link_train_clock_recovery_delay(intel_dp->dpcd);
+		if (!intel_dp_get_link_status(intel_dp, link_status)) {
+			DRM_ERROR("failed to get link status\n");
+			break;
+		}
+
+		if (drm_dp_clock_recovery_ok(link_status, intel_dp->lane_count)) {
+			DRM_DEBUG_KMS("clock recovery OK\n");
+			break;
+		}
+
+		/* Check to see if we've tried the max voltage */
+		for (i = 0; i < intel_dp->lane_count; i++)
+			if ((intel_dp->train_set[i] & DP_TRAIN_MAX_SWING_REACHED) == 0)
+				break;
+		if (i == intel_dp->lane_count) {
+			++loop_tries;
+			if (loop_tries == 5) {
+				DRM_ERROR("too many full retries, give up\n");
+				break;
+			}
+			intel_dp_reset_link_train(intel_dp,
+						  DP_TRAINING_PATTERN_1 |
+						  DP_LINK_SCRAMBLING_DISABLE);
+			voltage_tries = 0;
+			continue;
+		}
+
+		/* Check to see if we've tried the same voltage 5 times */
+		if ((intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK) == voltage) {
+			++voltage_tries;
+			if (voltage_tries == 5) {
+				DRM_ERROR("too many voltage retries, give up\n");
+				break;
+			}
+		} else
+			voltage_tries = 0;
+		voltage = intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK;
+
+		/* Update training set as requested by target */
+		intel_get_adjust_train(intel_dp, link_status);
+		if (!intel_dp_update_link_train(intel_dp)) {
+			DRM_ERROR("failed to update link training\n");
+			break;
+		}
+	}
+}
+
+/*
+ * Pick training pattern for channel equalization. Training Pattern 3 for HBR2
+ * or 1.2 devices that support it, Training Pattern 2 otherwise.
+ */
+static u32 intel_dp_training_pattern(struct intel_dp *intel_dp)
+{
+	u32 training_pattern = DP_TRAINING_PATTERN_2;
+	bool source_tps3, sink_tps3;
+
+	/*
+	 * Intel platforms that support HBR2 also support TPS3. TPS3 support is
+	 * also mandatory for downstream devices that support HBR2. However, not
+	 * all sinks follow the spec.
+	 *
+	 * Due to WaDisableHBR2 SKL < B0 is the only exception where TPS3 is
+	 * supported in source but still not enabled.
+	 */
+	source_tps3 = intel_dp_source_supports_hbr2(intel_dp);
+	sink_tps3 = drm_dp_tps3_supported(intel_dp->dpcd);
+
+	if (source_tps3 && sink_tps3) {
+		training_pattern = DP_TRAINING_PATTERN_3;
+	} else if (intel_dp->link_rate == 540000) {
+		if (!source_tps3)
+			DRM_DEBUG_KMS("5.4 Gbps link rate without source HBR2/TPS3 support\n");
+		if (!sink_tps3)
+			DRM_DEBUG_KMS("5.4 Gbps link rate without sink TPS3 support\n");
+	}
+
+	return training_pattern;
+}
+
+static void
+intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp)
+{
+	bool channel_eq = false;
+	int tries, cr_tries;
+	u32 training_pattern;
+
+	training_pattern = intel_dp_training_pattern(intel_dp);
+
+	/* channel equalization */
+	if (!intel_dp_set_link_train(intel_dp,
+				     training_pattern |
+				     DP_LINK_SCRAMBLING_DISABLE)) {
+		DRM_ERROR("failed to start channel equalization\n");
+		return;
+	}
+
+	tries = 0;
+	cr_tries = 0;
+	channel_eq = false;
+	for (;;) {
+		uint8_t link_status[DP_LINK_STATUS_SIZE];
+
+		if (cr_tries > 5) {
+			DRM_ERROR("failed to train DP, aborting\n");
+			break;
+		}
+
+		drm_dp_link_train_channel_eq_delay(intel_dp->dpcd);
+		if (!intel_dp_get_link_status(intel_dp, link_status)) {
+			DRM_ERROR("failed to get link status\n");
+			break;
+		}
+
+		/* Make sure clock is still ok */
+		if (!drm_dp_clock_recovery_ok(link_status,
+					      intel_dp->lane_count)) {
+			intel_dp_link_training_clock_recovery(intel_dp);
+			intel_dp_set_link_train(intel_dp,
+						training_pattern |
+						DP_LINK_SCRAMBLING_DISABLE);
+			cr_tries++;
+			continue;
+		}
+
+		if (drm_dp_channel_eq_ok(link_status,
+					 intel_dp->lane_count)) {
+			channel_eq = true;
+			break;
+		}
+
+		/* Try 5 times, then try clock recovery if that fails */
+		if (tries > 5) {
+			intel_dp_link_training_clock_recovery(intel_dp);
+			intel_dp_set_link_train(intel_dp,
+						training_pattern |
+						DP_LINK_SCRAMBLING_DISABLE);
+			tries = 0;
+			cr_tries++;
+			continue;
+		}
+
+		/* Update training set as requested by target */
+		intel_get_adjust_train(intel_dp, link_status);
+		if (!intel_dp_update_link_train(intel_dp)) {
+			DRM_ERROR("failed to update link training\n");
+			break;
+		}
+		++tries;
+	}
+
+	intel_dp_set_idle_link_train(intel_dp);
+
+	if (channel_eq)
+		DRM_DEBUG_KMS("Channel EQ done. DP Training successful\n");
+}
+
+void intel_dp_stop_link_train(struct intel_dp *intel_dp)
+{
+	intel_dp_set_link_train(intel_dp,
+				DP_TRAINING_PATTERN_DISABLE);
+}
+
+void
+intel_dp_start_link_train(struct intel_dp *intel_dp)
+{
+	intel_dp_link_training_clock_recovery(intel_dp);
+	intel_dp_link_training_channel_equalization(intel_dp);
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/i915/intel_dp_mst.c
@@ -0,0 +1,599 @@
+/*
+ * Copyright © 2008 Intel Corporation
+ *             2014 Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ */
+
+#include <drm/drmP.h>
+#include "i915_drv.h"
+#include "intel_drv.h"
+#include <drm/drm_atomic_helper.h>
+#include <drm/drm_crtc_helper.h>
+#include <drm/drm_edid.h>
+
+static bool intel_dp_mst_compute_config(struct intel_encoder *encoder,
+					struct intel_crtc_state *pipe_config)
+{
+	struct intel_dp_mst_encoder *intel_mst = enc_to_mst(&encoder->base);
+	struct intel_digital_port *intel_dig_port = intel_mst->primary;
+	struct intel_dp *intel_dp = &intel_dig_port->dp;
+	struct drm_atomic_state *state;
+	int bpp, i;
+	int lane_count, slots;
+	const struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
+	struct drm_connector *drm_connector;
+	struct intel_connector *connector, *found = NULL;
+	struct drm_connector_state *connector_state;
+	int mst_pbn;
+
+	pipe_config->dp_encoder_is_mst = true;
+	pipe_config->has_pch_encoder = false;
+	pipe_config->has_dp_encoder = true;
+	bpp = 24;
+	/*
+	 * for MST we always configure max link bw - the spec doesn't
+	 * seem to suggest we should do otherwise.
+	 */
+	lane_count = drm_dp_max_lane_count(intel_dp->dpcd);
+
+
+	pipe_config->lane_count = lane_count;
+
+	pipe_config->pipe_bpp = 24;
+	pipe_config->port_clock = intel_dp_max_link_rate(intel_dp);
+
+	state = pipe_config->base.state;
+
+	for_each_connector_in_state(state, drm_connector, connector_state, i) {
+		connector = to_intel_connector(drm_connector);
+
+		if (connector_state->best_encoder == &encoder->base) {
+			found = connector;
+			break;
+		}
+	}
+
+	if (!found) {
+		DRM_ERROR("can't find connector\n");
+		return false;
+	}
+
+	mst_pbn = drm_dp_calc_pbn_mode(adjusted_mode->crtc_clock, bpp);
+
+	pipe_config->pbn = mst_pbn;
+	slots = drm_dp_find_vcpi_slots(&intel_dp->mst_mgr, mst_pbn);
+
+	intel_link_compute_m_n(bpp, lane_count,
+			       adjusted_mode->crtc_clock,
+			       pipe_config->port_clock,
+			       &pipe_config->dp_m_n);
+
+	pipe_config->dp_m_n.tu = slots;
+
+	return true;
+
+}
+
+static void intel_mst_disable_dp(struct intel_encoder *encoder)
+{
+	struct intel_dp_mst_encoder *intel_mst = enc_to_mst(&encoder->base);
+	struct intel_digital_port *intel_dig_port = intel_mst->primary;
+	struct intel_dp *intel_dp = &intel_dig_port->dp;
+	int ret;
+
+	DRM_DEBUG_KMS("%d\n", intel_dp->active_mst_links);
+
+	drm_dp_mst_reset_vcpi_slots(&intel_dp->mst_mgr, intel_mst->port);
+
+	ret = drm_dp_update_payload_part1(&intel_dp->mst_mgr);
+	if (ret) {
+		DRM_ERROR("failed to update payload %d\n", ret);
+	}
+}
+
+static void intel_mst_post_disable_dp(struct intel_encoder *encoder)
+{
+	struct intel_dp_mst_encoder *intel_mst = enc_to_mst(&encoder->base);
+	struct intel_digital_port *intel_dig_port = intel_mst->primary;
+	struct intel_dp *intel_dp = &intel_dig_port->dp;
+
+	DRM_DEBUG_KMS("%d\n", intel_dp->active_mst_links);
+
+	/* this can fail */
+	drm_dp_check_act_status(&intel_dp->mst_mgr);
+	/* and this can also fail */
+	drm_dp_update_payload_part2(&intel_dp->mst_mgr);
+
+	drm_dp_mst_deallocate_vcpi(&intel_dp->mst_mgr, intel_mst->port);
+
+	intel_dp->active_mst_links--;
+	intel_mst->port = NULL;
+	if (intel_dp->active_mst_links == 0) {
+		intel_dig_port->base.post_disable(&intel_dig_port->base);
+		intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF);
+	}
+}
+
+static void intel_mst_pre_enable_dp(struct intel_encoder *encoder)
+{
+	struct intel_dp_mst_encoder *intel_mst = enc_to_mst(&encoder->base);
+	struct intel_digital_port *intel_dig_port = intel_mst->primary;
+	struct intel_dp *intel_dp = &intel_dig_port->dp;
+	struct drm_device *dev = encoder->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	enum port port = intel_dig_port->port;
+	int ret;
+	uint32_t temp;
+	struct intel_connector *found = NULL, *connector;
+	int slots;
+	struct drm_crtc *crtc = encoder->base.crtc;
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+
+	for_each_intel_connector(dev, connector) {
+		if (connector->base.state->best_encoder == &encoder->base) {
+			found = connector;
+			break;
+		}
+	}
+
+	if (!found) {
+		DRM_ERROR("can't find connector\n");
+		return;
+	}
+
+	/* MST encoders are bound to a crtc, not to a connector,
+	 * force the mapping here for get_hw_state.
+	 */
+	found->encoder = encoder;
+
+	DRM_DEBUG_KMS("%d\n", intel_dp->active_mst_links);
+	intel_mst->port = found->port;
+
+	if (intel_dp->active_mst_links == 0) {
+		intel_prepare_ddi_buffer(&intel_dig_port->base);
+
+		intel_ddi_clk_select(&intel_dig_port->base, intel_crtc->config);
+
+		intel_dp_set_link_params(intel_dp, intel_crtc->config);
+
+		intel_ddi_init_dp_buf_reg(&intel_dig_port->base);
+
+		intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON);
+
+		intel_dp_start_link_train(intel_dp);
+		intel_dp_stop_link_train(intel_dp);
+	}
+
+	ret = drm_dp_mst_allocate_vcpi(&intel_dp->mst_mgr,
+				       intel_mst->port,
+				       intel_crtc->config->pbn, &slots);
+	if (ret == false) {
+		DRM_ERROR("failed to allocate vcpi\n");
+		return;
+	}
+
+
+	intel_dp->active_mst_links++;
+	temp = I915_READ(DP_TP_STATUS(port));
+	I915_WRITE(DP_TP_STATUS(port), temp);
+
+	ret = drm_dp_update_payload_part1(&intel_dp->mst_mgr);
+}
+
+static void intel_mst_enable_dp(struct intel_encoder *encoder)
+{
+	struct intel_dp_mst_encoder *intel_mst = enc_to_mst(&encoder->base);
+	struct intel_digital_port *intel_dig_port = intel_mst->primary;
+	struct intel_dp *intel_dp = &intel_dig_port->dp;
+	struct drm_device *dev = intel_dig_port->base.base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	enum port port = intel_dig_port->port;
+	int ret;
+
+	DRM_DEBUG_KMS("%d\n", intel_dp->active_mst_links);
+
+	if (wait_for((I915_READ(DP_TP_STATUS(port)) & DP_TP_STATUS_ACT_SENT),
+		     1))
+		DRM_ERROR("Timed out waiting for ACT sent\n");
+
+	ret = drm_dp_check_act_status(&intel_dp->mst_mgr);
+
+	ret = drm_dp_update_payload_part2(&intel_dp->mst_mgr);
+}
+
+static bool intel_dp_mst_enc_get_hw_state(struct intel_encoder *encoder,
+				      enum pipe *pipe)
+{
+	struct intel_dp_mst_encoder *intel_mst = enc_to_mst(&encoder->base);
+	*pipe = intel_mst->pipe;
+	if (intel_mst->port)
+		return true;
+	return false;
+}
+
+static void intel_dp_mst_enc_get_config(struct intel_encoder *encoder,
+					struct intel_crtc_state *pipe_config)
+{
+	struct intel_dp_mst_encoder *intel_mst = enc_to_mst(&encoder->base);
+	struct intel_digital_port *intel_dig_port = intel_mst->primary;
+	struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc);
+	struct drm_device *dev = encoder->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	enum transcoder cpu_transcoder = pipe_config->cpu_transcoder;
+	u32 temp, flags = 0;
+
+	pipe_config->has_dp_encoder = true;
+
+	temp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder));
+	if (temp & TRANS_DDI_PHSYNC)
+		flags |= DRM_MODE_FLAG_PHSYNC;
+	else
+		flags |= DRM_MODE_FLAG_NHSYNC;
+	if (temp & TRANS_DDI_PVSYNC)
+		flags |= DRM_MODE_FLAG_PVSYNC;
+	else
+		flags |= DRM_MODE_FLAG_NVSYNC;
+
+	switch (temp & TRANS_DDI_BPC_MASK) {
+	case TRANS_DDI_BPC_6:
+		pipe_config->pipe_bpp = 18;
+		break;
+	case TRANS_DDI_BPC_8:
+		pipe_config->pipe_bpp = 24;
+		break;
+	case TRANS_DDI_BPC_10:
+		pipe_config->pipe_bpp = 30;
+		break;
+	case TRANS_DDI_BPC_12:
+		pipe_config->pipe_bpp = 36;
+		break;
+	default:
+		break;
+	}
+	pipe_config->base.adjusted_mode.flags |= flags;
+
+	pipe_config->lane_count =
+		((temp & DDI_PORT_WIDTH_MASK) >> DDI_PORT_WIDTH_SHIFT) + 1;
+
+	intel_dp_get_m_n(crtc, pipe_config);
+
+	intel_ddi_clock_get(&intel_dig_port->base, pipe_config);
+}
+
+static int intel_dp_mst_get_ddc_modes(struct drm_connector *connector)
+{
+	struct intel_connector *intel_connector = to_intel_connector(connector);
+	struct intel_dp *intel_dp = intel_connector->mst_port;
+	struct edid *edid;
+	int ret;
+
+	edid = drm_dp_mst_get_edid(connector, &intel_dp->mst_mgr, intel_connector->port);
+	if (!edid)
+		return 0;
+
+	ret = intel_connector_update_modes(connector, edid);
+	kfree(edid);
+
+	return ret;
+}
+
+static enum drm_connector_status
+intel_dp_mst_detect(struct drm_connector *connector, bool force)
+{
+	struct intel_connector *intel_connector = to_intel_connector(connector);
+	struct intel_dp *intel_dp = intel_connector->mst_port;
+
+	return drm_dp_mst_detect_port(connector, &intel_dp->mst_mgr, intel_connector->port);
+}
+
+static int
+intel_dp_mst_set_property(struct drm_connector *connector,
+			  struct drm_property *property,
+			  uint64_t val)
+{
+	return 0;
+}
+
+static void
+intel_dp_mst_connector_destroy(struct drm_connector *connector)
+{
+	struct intel_connector *intel_connector = to_intel_connector(connector);
+
+	if (!IS_ERR_OR_NULL(intel_connector->edid))
+		kfree(intel_connector->edid);
+
+	drm_connector_cleanup(connector);
+	kfree(connector);
+}
+
+static const struct drm_connector_funcs intel_dp_mst_connector_funcs = {
+	.dpms = drm_atomic_helper_connector_dpms,
+	.detect = intel_dp_mst_detect,
+	.fill_modes = drm_helper_probe_single_connector_modes,
+	.set_property = intel_dp_mst_set_property,
+	.atomic_get_property = intel_connector_atomic_get_property,
+	.destroy = intel_dp_mst_connector_destroy,
+	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
+	.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
+};
+
+static int intel_dp_mst_get_modes(struct drm_connector *connector)
+{
+	return intel_dp_mst_get_ddc_modes(connector);
+}
+
+static enum drm_mode_status
+intel_dp_mst_mode_valid(struct drm_connector *connector,
+			struct drm_display_mode *mode)
+{
+	int max_dotclk = to_i915(connector->dev)->max_dotclk_freq;
+
+	/* TODO - validate mode against available PBN for link */
+	if (mode->clock < 10000)
+		return MODE_CLOCK_LOW;
+
+	if (mode->flags & DRM_MODE_FLAG_DBLCLK)
+		return MODE_H_ILLEGAL;
+
+	if (mode->clock > max_dotclk)
+		return MODE_CLOCK_HIGH;
+
+	return MODE_OK;
+}
+
+static struct drm_encoder *intel_mst_atomic_best_encoder(struct drm_connector *connector,
+							 struct drm_connector_state *state)
+{
+	struct intel_connector *intel_connector = to_intel_connector(connector);
+	struct intel_dp *intel_dp = intel_connector->mst_port;
+	struct intel_crtc *crtc = to_intel_crtc(state->crtc);
+
+	return &intel_dp->mst_encoders[crtc->pipe]->base.base;
+}
+
+static struct drm_encoder *intel_mst_best_encoder(struct drm_connector *connector)
+{
+	struct intel_connector *intel_connector = to_intel_connector(connector);
+	struct intel_dp *intel_dp = intel_connector->mst_port;
+	return &intel_dp->mst_encoders[0]->base.base;
+}
+
+static const struct drm_connector_helper_funcs intel_dp_mst_connector_helper_funcs = {
+	.get_modes = intel_dp_mst_get_modes,
+	.mode_valid = intel_dp_mst_mode_valid,
+	.atomic_best_encoder = intel_mst_atomic_best_encoder,
+	.best_encoder = intel_mst_best_encoder,
+};
+
+static void intel_dp_mst_encoder_destroy(struct drm_encoder *encoder)
+{
+	struct intel_dp_mst_encoder *intel_mst = enc_to_mst(encoder);
+
+	drm_encoder_cleanup(encoder);
+	kfree(intel_mst);
+}
+
+static const struct drm_encoder_funcs intel_dp_mst_enc_funcs = {
+	.destroy = intel_dp_mst_encoder_destroy,
+};
+
+static bool intel_dp_mst_get_hw_state(struct intel_connector *connector)
+{
+	if (connector->encoder && connector->base.state->crtc) {
+		enum pipe pipe;
+		if (!connector->encoder->get_hw_state(connector->encoder, &pipe))
+			return false;
+		return true;
+	}
+	return false;
+}
+
+static void intel_connector_add_to_fbdev(struct intel_connector *connector)
+{
+#ifdef CONFIG_DRM_FBDEV_EMULATION
+	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+
+	if (dev_priv->fbdev)
+		drm_fb_helper_add_one_connector(&dev_priv->fbdev->helper,
+						&connector->base);
+#endif
+}
+
+static void intel_connector_remove_from_fbdev(struct intel_connector *connector)
+{
+#ifdef CONFIG_DRM_FBDEV_EMULATION
+	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+
+	if (dev_priv->fbdev)
+		drm_fb_helper_remove_one_connector(&dev_priv->fbdev->helper,
+						   &connector->base);
+#endif
+}
+
+static struct drm_connector *intel_dp_add_mst_connector(struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_port *port, const char *pathprop)
+{
+	struct intel_dp *intel_dp = container_of(mgr, struct intel_dp, mst_mgr);
+	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
+	struct drm_device *dev = intel_dig_port->base.base.dev;
+	struct intel_connector *intel_connector;
+	struct drm_connector *connector;
+	int i;
+
+	intel_connector = intel_connector_alloc();
+	if (!intel_connector)
+		return NULL;
+
+	connector = &intel_connector->base;
+	drm_connector_init(dev, connector, &intel_dp_mst_connector_funcs, DRM_MODE_CONNECTOR_DisplayPort);
+	drm_connector_helper_add(connector, &intel_dp_mst_connector_helper_funcs);
+
+	intel_connector->unregister = intel_connector_unregister;
+	intel_connector->get_hw_state = intel_dp_mst_get_hw_state;
+	intel_connector->mst_port = intel_dp;
+	intel_connector->port = port;
+
+	for (i = PIPE_A; i <= PIPE_C; i++) {
+		drm_mode_connector_attach_encoder(&intel_connector->base,
+						  &intel_dp->mst_encoders[i]->base.base);
+	}
+	intel_dp_add_properties(intel_dp, connector);
+
+	drm_object_attach_property(&connector->base, dev->mode_config.path_property, 0);
+	drm_object_attach_property(&connector->base, dev->mode_config.tile_property, 0);
+
+	drm_mode_connector_set_path_property(connector, pathprop);
+	return connector;
+}
+
+static void intel_dp_register_mst_connector(struct drm_connector *connector)
+{
+	struct intel_connector *intel_connector = to_intel_connector(connector);
+	struct drm_device *dev = connector->dev;
+	drm_modeset_lock_all(dev);
+	intel_connector_add_to_fbdev(intel_connector);
+	drm_modeset_unlock_all(dev);
+	drm_connector_register(&intel_connector->base);
+}
+
+static void intel_dp_destroy_mst_connector(struct drm_dp_mst_topology_mgr *mgr,
+					   struct drm_connector *connector)
+{
+	struct intel_connector *intel_connector = to_intel_connector(connector);
+	struct drm_device *dev = connector->dev;
+
+	intel_connector->unregister(intel_connector);
+
+	/* need to nuke the connector */
+	drm_modeset_lock_all(dev);
+	if (connector->state->crtc) {
+		struct drm_mode_set set;
+		int ret;
+
+		memset(&set, 0, sizeof(set));
+		set.crtc = connector->state->crtc,
+
+		ret = drm_atomic_helper_set_config(&set);
+
+		WARN(ret, "Disabling mst crtc failed with %i\n", ret);
+	}
+
+	intel_connector_remove_from_fbdev(intel_connector);
+	drm_connector_cleanup(connector);
+	drm_modeset_unlock_all(dev);
+
+	kfree(intel_connector);
+	DRM_DEBUG_KMS("\n");
+}
+
+static void intel_dp_mst_hotplug(struct drm_dp_mst_topology_mgr *mgr)
+{
+	struct intel_dp *intel_dp = container_of(mgr, struct intel_dp, mst_mgr);
+	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
+	struct drm_device *dev = intel_dig_port->base.base.dev;
+
+	drm_kms_helper_hotplug_event(dev);
+}
+
+static const struct drm_dp_mst_topology_cbs mst_cbs = {
+	.add_connector = intel_dp_add_mst_connector,
+	.register_connector = intel_dp_register_mst_connector,
+	.destroy_connector = intel_dp_destroy_mst_connector,
+	.hotplug = intel_dp_mst_hotplug,
+};
+
+static struct intel_dp_mst_encoder *
+intel_dp_create_fake_mst_encoder(struct intel_digital_port *intel_dig_port, enum pipe pipe)
+{
+	struct intel_dp_mst_encoder *intel_mst;
+	struct intel_encoder *intel_encoder;
+	struct drm_device *dev = intel_dig_port->base.base.dev;
+
+	intel_mst = kzalloc(sizeof(*intel_mst), GFP_KERNEL);
+
+	if (!intel_mst)
+		return NULL;
+
+	intel_mst->pipe = pipe;
+	intel_encoder = &intel_mst->base;
+	intel_mst->primary = intel_dig_port;
+
+	drm_encoder_init(dev, &intel_encoder->base, &intel_dp_mst_enc_funcs,
+			 DRM_MODE_ENCODER_DPMST);
+
+	intel_encoder->type = INTEL_OUTPUT_DP_MST;
+	intel_encoder->crtc_mask = 0x7;
+	intel_encoder->cloneable = 0;
+
+	intel_encoder->compute_config = intel_dp_mst_compute_config;
+	intel_encoder->disable = intel_mst_disable_dp;
+	intel_encoder->post_disable = intel_mst_post_disable_dp;
+	intel_encoder->pre_enable = intel_mst_pre_enable_dp;
+	intel_encoder->enable = intel_mst_enable_dp;
+	intel_encoder->get_hw_state = intel_dp_mst_enc_get_hw_state;
+	intel_encoder->get_config = intel_dp_mst_enc_get_config;
+
+	return intel_mst;
+
+}
+
+static bool
+intel_dp_create_fake_mst_encoders(struct intel_digital_port *intel_dig_port)
+{
+	int i;
+	struct intel_dp *intel_dp = &intel_dig_port->dp;
+
+	for (i = PIPE_A; i <= PIPE_C; i++)
+		intel_dp->mst_encoders[i] = intel_dp_create_fake_mst_encoder(intel_dig_port, i);
+	return true;
+}
+
+int
+intel_dp_mst_encoder_init(struct intel_digital_port *intel_dig_port, int conn_base_id)
+{
+	struct intel_dp *intel_dp = &intel_dig_port->dp;
+	struct drm_device *dev = intel_dig_port->base.base.dev;
+	int ret;
+
+	intel_dp->can_mst = true;
+	intel_dp->mst_mgr.cbs = &mst_cbs;
+
+	/* create encoders */
+	intel_dp_create_fake_mst_encoders(intel_dig_port);
+	ret = drm_dp_mst_topology_mgr_init(&intel_dp->mst_mgr, dev->dev, &intel_dp->aux, 16, 3, conn_base_id);
+	if (ret) {
+		intel_dp->can_mst = false;
+		return ret;
+	}
+	return 0;
+}
+
+void
+intel_dp_mst_encoder_cleanup(struct intel_digital_port *intel_dig_port)
+{
+	struct intel_dp *intel_dp = &intel_dig_port->dp;
+
+	if (!intel_dp->can_mst)
+		return;
+
+	drm_dp_mst_topology_mgr_destroy(&intel_dp->mst_mgr);
+	/* encoders will get killed by normal cleanup */
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/i915/intel_dpll_mgr.c
@@ -0,0 +1,1786 @@
+/*
+ * Copyright © 2006-2016 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#include "intel_drv.h"
+
+struct intel_shared_dpll *
+intel_get_shared_dpll_by_id(struct drm_i915_private *dev_priv,
+			    enum intel_dpll_id id)
+{
+	return &dev_priv->shared_dplls[id];
+}
+
+enum intel_dpll_id
+intel_get_shared_dpll_id(struct drm_i915_private *dev_priv,
+			 struct intel_shared_dpll *pll)
+{
+	if (WARN_ON(pll < dev_priv->shared_dplls||
+		    pll > &dev_priv->shared_dplls[dev_priv->num_shared_dpll]))
+		return -1;
+
+	return (enum intel_dpll_id) (pll - dev_priv->shared_dplls);
+}
+
+void
+intel_shared_dpll_config_get(struct intel_shared_dpll_config *config,
+			     struct intel_shared_dpll *pll,
+			     struct intel_crtc *crtc)
+{
+	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
+	enum intel_dpll_id id = intel_get_shared_dpll_id(dev_priv, pll);
+
+	config[id].crtc_mask |= 1 << crtc->pipe;
+}
+
+void
+intel_shared_dpll_config_put(struct intel_shared_dpll_config *config,
+			     struct intel_shared_dpll *pll,
+			     struct intel_crtc *crtc)
+{
+	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
+	enum intel_dpll_id id = intel_get_shared_dpll_id(dev_priv, pll);
+
+	config[id].crtc_mask &= ~(1 << crtc->pipe);
+}
+
+/* For ILK+ */
+void assert_shared_dpll(struct drm_i915_private *dev_priv,
+			struct intel_shared_dpll *pll,
+			bool state)
+{
+	bool cur_state;
+	struct intel_dpll_hw_state hw_state;
+
+	if (WARN(!pll, "asserting DPLL %s with no DPLL\n", onoff(state)))
+		return;
+
+	cur_state = pll->funcs.get_hw_state(dev_priv, pll, &hw_state);
+	I915_STATE_WARN(cur_state != state,
+	     "%s assertion failure (expected %s, current %s)\n",
+			pll->name, onoff(state), onoff(cur_state));
+}
+
+void intel_prepare_shared_dpll(struct intel_crtc *crtc)
+{
+	struct drm_device *dev = crtc->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_shared_dpll *pll = crtc->config->shared_dpll;
+
+	if (WARN_ON(pll == NULL))
+		return;
+
+	mutex_lock(&dev_priv->dpll_lock);
+	WARN_ON(!pll->config.crtc_mask);
+	if (!pll->active_mask) {
+		DRM_DEBUG_DRIVER("setting up %s\n", pll->name);
+		WARN_ON(pll->on);
+		assert_shared_dpll_disabled(dev_priv, pll);
+
+		pll->funcs.mode_set(dev_priv, pll);
+	}
+	mutex_unlock(&dev_priv->dpll_lock);
+}
+
+/**
+ * intel_enable_shared_dpll - enable PCH PLL
+ * @dev_priv: i915 private structure
+ * @pipe: pipe PLL to enable
+ *
+ * The PCH PLL needs to be enabled before the PCH transcoder, since it
+ * drives the transcoder clock.
+ */
+void intel_enable_shared_dpll(struct intel_crtc *crtc)
+{
+	struct drm_device *dev = crtc->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_shared_dpll *pll = crtc->config->shared_dpll;
+	unsigned crtc_mask = 1 << drm_crtc_index(&crtc->base);
+	unsigned old_mask;
+
+	if (WARN_ON(pll == NULL))
+		return;
+
+	mutex_lock(&dev_priv->dpll_lock);
+	old_mask = pll->active_mask;
+
+	if (WARN_ON(!(pll->config.crtc_mask & crtc_mask)) ||
+	    WARN_ON(pll->active_mask & crtc_mask))
+		goto out;
+
+	pll->active_mask |= crtc_mask;
+
+	DRM_DEBUG_KMS("enable %s (active %x, on? %d) for crtc %d\n",
+		      pll->name, pll->active_mask, pll->on,
+		      crtc->base.base.id);
+
+	if (old_mask) {
+		WARN_ON(!pll->on);
+		assert_shared_dpll_enabled(dev_priv, pll);
+		goto out;
+	}
+	WARN_ON(pll->on);
+
+	DRM_DEBUG_KMS("enabling %s\n", pll->name);
+	pll->funcs.enable(dev_priv, pll);
+	pll->on = true;
+
+out:
+	mutex_unlock(&dev_priv->dpll_lock);
+}
+
+void intel_disable_shared_dpll(struct intel_crtc *crtc)
+{
+	struct drm_device *dev = crtc->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_shared_dpll *pll = crtc->config->shared_dpll;
+	unsigned crtc_mask = 1 << drm_crtc_index(&crtc->base);
+
+	/* PCH only available on ILK+ */
+	if (INTEL_INFO(dev)->gen < 5)
+		return;
+
+	if (pll == NULL)
+		return;
+
+	mutex_lock(&dev_priv->dpll_lock);
+	if (WARN_ON(!(pll->active_mask & crtc_mask)))
+		goto out;
+
+	DRM_DEBUG_KMS("disable %s (active %x, on? %d) for crtc %d\n",
+		      pll->name, pll->active_mask, pll->on,
+		      crtc->base.base.id);
+
+	assert_shared_dpll_enabled(dev_priv, pll);
+	WARN_ON(!pll->on);
+
+	pll->active_mask &= ~crtc_mask;
+	if (pll->active_mask)
+		goto out;
+
+	DRM_DEBUG_KMS("disabling %s\n", pll->name);
+	pll->funcs.disable(dev_priv, pll);
+	pll->on = false;
+
+out:
+	mutex_unlock(&dev_priv->dpll_lock);
+}
+
+static struct intel_shared_dpll *
+intel_find_shared_dpll(struct intel_crtc *crtc,
+		       struct intel_crtc_state *crtc_state,
+		       enum intel_dpll_id range_min,
+		       enum intel_dpll_id range_max)
+{
+	struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
+	struct intel_shared_dpll *pll;
+	struct intel_shared_dpll_config *shared_dpll;
+	enum intel_dpll_id i;
+
+	shared_dpll = intel_atomic_get_shared_dpll_state(crtc_state->base.state);
+
+	for (i = range_min; i <= range_max; i++) {
+		pll = &dev_priv->shared_dplls[i];
+
+		/* Only want to check enabled timings first */
+		if (shared_dpll[i].crtc_mask == 0)
+			continue;
+
+		if (memcmp(&crtc_state->dpll_hw_state,
+			   &shared_dpll[i].hw_state,
+			   sizeof(crtc_state->dpll_hw_state)) == 0) {
+			DRM_DEBUG_KMS("CRTC:%d sharing existing %s (crtc mask 0x%08x, active %x)\n",
+				      crtc->base.base.id, pll->name,
+				      shared_dpll[i].crtc_mask,
+				      pll->active_mask);
+			return pll;
+		}
+	}
+
+	/* Ok no matching timings, maybe there's a free one? */
+	for (i = range_min; i <= range_max; i++) {
+		pll = &dev_priv->shared_dplls[i];
+		if (shared_dpll[i].crtc_mask == 0) {
+			DRM_DEBUG_KMS("CRTC:%d allocated %s\n",
+				      crtc->base.base.id, pll->name);
+			return pll;
+		}
+	}
+
+	return NULL;
+}
+
+static void
+intel_reference_shared_dpll(struct intel_shared_dpll *pll,
+			    struct intel_crtc_state *crtc_state)
+{
+	struct intel_shared_dpll_config *shared_dpll;
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
+	enum intel_dpll_id i = pll->id;
+
+	shared_dpll = intel_atomic_get_shared_dpll_state(crtc_state->base.state);
+
+	if (shared_dpll[i].crtc_mask == 0)
+		shared_dpll[i].hw_state =
+			crtc_state->dpll_hw_state;
+
+	crtc_state->shared_dpll = pll;
+	DRM_DEBUG_DRIVER("using %s for pipe %c\n", pll->name,
+			 pipe_name(crtc->pipe));
+
+	intel_shared_dpll_config_get(shared_dpll, pll, crtc);
+}
+
+void intel_shared_dpll_commit(struct drm_atomic_state *state)
+{
+	struct drm_i915_private *dev_priv = to_i915(state->dev);
+	struct intel_shared_dpll_config *shared_dpll;
+	struct intel_shared_dpll *pll;
+	enum intel_dpll_id i;
+
+	if (!to_intel_atomic_state(state)->dpll_set)
+		return;
+
+	shared_dpll = to_intel_atomic_state(state)->shared_dpll;
+	for (i = 0; i < dev_priv->num_shared_dpll; i++) {
+		pll = &dev_priv->shared_dplls[i];
+		pll->config = shared_dpll[i];
+	}
+}
+
+static bool ibx_pch_dpll_get_hw_state(struct drm_i915_private *dev_priv,
+				      struct intel_shared_dpll *pll,
+				      struct intel_dpll_hw_state *hw_state)
+{
+	uint32_t val;
+
+	if (!intel_display_power_get_if_enabled(dev_priv, POWER_DOMAIN_PLLS))
+		return false;
+
+	val = I915_READ(PCH_DPLL(pll->id));
+	hw_state->dpll = val;
+	hw_state->fp0 = I915_READ(PCH_FP0(pll->id));
+	hw_state->fp1 = I915_READ(PCH_FP1(pll->id));
+
+	intel_display_power_put(dev_priv, POWER_DOMAIN_PLLS);
+
+	return val & DPLL_VCO_ENABLE;
+}
+
+static void ibx_pch_dpll_mode_set(struct drm_i915_private *dev_priv,
+				  struct intel_shared_dpll *pll)
+{
+	I915_WRITE(PCH_FP0(pll->id), pll->config.hw_state.fp0);
+	I915_WRITE(PCH_FP1(pll->id), pll->config.hw_state.fp1);
+}
+
+static void ibx_assert_pch_refclk_enabled(struct drm_i915_private *dev_priv)
+{
+	u32 val;
+	bool enabled;
+
+	I915_STATE_WARN_ON(!(HAS_PCH_IBX(dev_priv) || HAS_PCH_CPT(dev_priv)));
+
+	val = I915_READ(PCH_DREF_CONTROL);
+	enabled = !!(val & (DREF_SSC_SOURCE_MASK | DREF_NONSPREAD_SOURCE_MASK |
+			    DREF_SUPERSPREAD_SOURCE_MASK));
+	I915_STATE_WARN(!enabled, "PCH refclk assertion failure, should be active but is disabled\n");
+}
+
+static void ibx_pch_dpll_enable(struct drm_i915_private *dev_priv,
+				struct intel_shared_dpll *pll)
+{
+	/* PCH refclock must be enabled first */
+	ibx_assert_pch_refclk_enabled(dev_priv);
+
+	I915_WRITE(PCH_DPLL(pll->id), pll->config.hw_state.dpll);
+
+	/* Wait for the clocks to stabilize. */
+	POSTING_READ(PCH_DPLL(pll->id));
+	udelay(150);
+
+	/* The pixel multiplier can only be updated once the
+	 * DPLL is enabled and the clocks are stable.
+	 *
+	 * So write it again.
+	 */
+	I915_WRITE(PCH_DPLL(pll->id), pll->config.hw_state.dpll);
+	POSTING_READ(PCH_DPLL(pll->id));
+	udelay(200);
+}
+
+static void ibx_pch_dpll_disable(struct drm_i915_private *dev_priv,
+				 struct intel_shared_dpll *pll)
+{
+	struct drm_device *dev = dev_priv->dev;
+	struct intel_crtc *crtc;
+
+	/* Make sure no transcoder isn't still depending on us. */
+	for_each_intel_crtc(dev, crtc) {
+		if (crtc->config->shared_dpll == pll)
+			assert_pch_transcoder_disabled(dev_priv, crtc->pipe);
+	}
+
+	I915_WRITE(PCH_DPLL(pll->id), 0);
+	POSTING_READ(PCH_DPLL(pll->id));
+	udelay(200);
+}
+
+static struct intel_shared_dpll *
+ibx_get_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state,
+	     struct intel_encoder *encoder)
+{
+	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
+	struct intel_shared_dpll *pll;
+	enum intel_dpll_id i;
+
+	if (HAS_PCH_IBX(dev_priv)) {
+		/* Ironlake PCH has a fixed PLL->PCH pipe mapping. */
+		i = (enum intel_dpll_id) crtc->pipe;
+		pll = &dev_priv->shared_dplls[i];
+
+		DRM_DEBUG_KMS("CRTC:%d using pre-allocated %s\n",
+			      crtc->base.base.id, pll->name);
+	} else {
+		pll = intel_find_shared_dpll(crtc, crtc_state,
+					     DPLL_ID_PCH_PLL_A,
+					     DPLL_ID_PCH_PLL_B);
+	}
+
+	if (!pll)
+		return NULL;
+
+	/* reference the pll */
+	intel_reference_shared_dpll(pll, crtc_state);
+
+	return pll;
+}
+
+static const struct intel_shared_dpll_funcs ibx_pch_dpll_funcs = {
+	.mode_set = ibx_pch_dpll_mode_set,
+	.enable = ibx_pch_dpll_enable,
+	.disable = ibx_pch_dpll_disable,
+	.get_hw_state = ibx_pch_dpll_get_hw_state,
+};
+
+static void hsw_ddi_wrpll_enable(struct drm_i915_private *dev_priv,
+			       struct intel_shared_dpll *pll)
+{
+	I915_WRITE(WRPLL_CTL(pll->id), pll->config.hw_state.wrpll);
+	POSTING_READ(WRPLL_CTL(pll->id));
+	udelay(20);
+}
+
+static void hsw_ddi_spll_enable(struct drm_i915_private *dev_priv,
+				struct intel_shared_dpll *pll)
+{
+	I915_WRITE(SPLL_CTL, pll->config.hw_state.spll);
+	POSTING_READ(SPLL_CTL);
+	udelay(20);
+}
+
+static void hsw_ddi_wrpll_disable(struct drm_i915_private *dev_priv,
+				  struct intel_shared_dpll *pll)
+{
+	uint32_t val;
+
+	val = I915_READ(WRPLL_CTL(pll->id));
+	I915_WRITE(WRPLL_CTL(pll->id), val & ~WRPLL_PLL_ENABLE);
+	POSTING_READ(WRPLL_CTL(pll->id));
+}
+
+static void hsw_ddi_spll_disable(struct drm_i915_private *dev_priv,
+				 struct intel_shared_dpll *pll)
+{
+	uint32_t val;
+
+	val = I915_READ(SPLL_CTL);
+	I915_WRITE(SPLL_CTL, val & ~SPLL_PLL_ENABLE);
+	POSTING_READ(SPLL_CTL);
+}
+
+static bool hsw_ddi_wrpll_get_hw_state(struct drm_i915_private *dev_priv,
+				       struct intel_shared_dpll *pll,
+				       struct intel_dpll_hw_state *hw_state)
+{
+	uint32_t val;
+
+	if (!intel_display_power_get_if_enabled(dev_priv, POWER_DOMAIN_PLLS))
+		return false;
+
+	val = I915_READ(WRPLL_CTL(pll->id));
+	hw_state->wrpll = val;
+
+	intel_display_power_put(dev_priv, POWER_DOMAIN_PLLS);
+
+	return val & WRPLL_PLL_ENABLE;
+}
+
+static bool hsw_ddi_spll_get_hw_state(struct drm_i915_private *dev_priv,
+				      struct intel_shared_dpll *pll,
+				      struct intel_dpll_hw_state *hw_state)
+{
+	uint32_t val;
+
+	if (!intel_display_power_get_if_enabled(dev_priv, POWER_DOMAIN_PLLS))
+		return false;
+
+	val = I915_READ(SPLL_CTL);
+	hw_state->spll = val;
+
+	intel_display_power_put(dev_priv, POWER_DOMAIN_PLLS);
+
+	return val & SPLL_PLL_ENABLE;
+}
+
+static uint32_t hsw_pll_to_ddi_pll_sel(struct intel_shared_dpll *pll)
+{
+	switch (pll->id) {
+	case DPLL_ID_WRPLL1:
+		return PORT_CLK_SEL_WRPLL1;
+	case DPLL_ID_WRPLL2:
+		return PORT_CLK_SEL_WRPLL2;
+	case DPLL_ID_SPLL:
+		return PORT_CLK_SEL_SPLL;
+	case DPLL_ID_LCPLL_810:
+		return PORT_CLK_SEL_LCPLL_810;
+	case DPLL_ID_LCPLL_1350:
+		return PORT_CLK_SEL_LCPLL_1350;
+	case DPLL_ID_LCPLL_2700:
+		return PORT_CLK_SEL_LCPLL_2700;
+	default:
+		return PORT_CLK_SEL_NONE;
+	}
+}
+
+#define LC_FREQ 2700
+#define LC_FREQ_2K U64_C(LC_FREQ * 2000)
+
+#define P_MIN 2
+#define P_MAX 64
+#define P_INC 2
+
+/* Constraints for PLL good behavior */
+#define REF_MIN 48
+#define REF_MAX 400
+#define VCO_MIN 2400
+#define VCO_MAX 4800
+
+struct hsw_wrpll_rnp {
+	unsigned p, n2, r2;
+};
+
+static unsigned hsw_wrpll_get_budget_for_freq(int clock)
+{
+	unsigned budget;
+
+	switch (clock) {
+	case 25175000:
+	case 25200000:
+	case 27000000:
+	case 27027000:
+	case 37762500:
+	case 37800000:
+	case 40500000:
+	case 40541000:
+	case 54000000:
+	case 54054000:
+	case 59341000:
+	case 59400000:
+	case 72000000:
+	case 74176000:
+	case 74250000:
+	case 81000000:
+	case 81081000:
+	case 89012000:
+	case 89100000:
+	case 108000000:
+	case 108108000:
+	case 111264000:
+	case 111375000:
+	case 148352000:
+	case 148500000:
+	case 162000000:
+	case 162162000:
+	case 222525000:
+	case 222750000:
+	case 296703000:
+	case 297000000:
+		budget = 0;
+		break;
+	case 233500000:
+	case 245250000:
+	case 247750000:
+	case 253250000:
+	case 298000000:
+		budget = 1500;
+		break;
+	case 169128000:
+	case 169500000:
+	case 179500000:
+	case 202000000:
+		budget = 2000;
+		break;
+	case 256250000:
+	case 262500000:
+	case 270000000:
+	case 272500000:
+	case 273750000:
+	case 280750000:
+	case 281250000:
+	case 286000000:
+	case 291750000:
+		budget = 4000;
+		break;
+	case 267250000:
+	case 268500000:
+		budget = 5000;
+		break;
+	default:
+		budget = 1000;
+		break;
+	}
+
+	return budget;
+}
+
+static void hsw_wrpll_update_rnp(uint64_t freq2k, unsigned budget,
+				 unsigned r2, unsigned n2, unsigned p,
+				 struct hsw_wrpll_rnp *best)
+{
+	uint64_t a, b, c, d, diff, diff_best;
+
+	/* No best (r,n,p) yet */
+	if (best->p == 0) {
+		best->p = p;
+		best->n2 = n2;
+		best->r2 = r2;
+		return;
+	}
+
+	/*
+	 * Output clock is (LC_FREQ_2K / 2000) * N / (P * R), which compares to
+	 * freq2k.
+	 *
+	 * delta = 1e6 *
+	 *	   abs(freq2k - (LC_FREQ_2K * n2/(p * r2))) /
+	 *	   freq2k;
+	 *
+	 * and we would like delta <= budget.
+	 *
+	 * If the discrepancy is above the PPM-based budget, always prefer to
+	 * improve upon the previous solution.  However, if you're within the
+	 * budget, try to maximize Ref * VCO, that is N / (P * R^2).
+	 */
+	a = freq2k * budget * p * r2;
+	b = freq2k * budget * best->p * best->r2;
+	diff = abs_diff(freq2k * p * r2, LC_FREQ_2K * n2);
+	diff_best = abs_diff(freq2k * best->p * best->r2,
+			     LC_FREQ_2K * best->n2);
+	c = 1000000 * diff;
+	d = 1000000 * diff_best;
+
+	if (a < c && b < d) {
+		/* If both are above the budget, pick the closer */
+		if (best->p * best->r2 * diff < p * r2 * diff_best) {
+			best->p = p;
+			best->n2 = n2;
+			best->r2 = r2;
+		}
+	} else if (a >= c && b < d) {
+		/* If A is below the threshold but B is above it?  Update. */
+		best->p = p;
+		best->n2 = n2;
+		best->r2 = r2;
+	} else if (a >= c && b >= d) {
+		/* Both are below the limit, so pick the higher n2/(r2*r2) */
+		if (n2 * best->r2 * best->r2 > best->n2 * r2 * r2) {
+			best->p = p;
+			best->n2 = n2;
+			best->r2 = r2;
+		}
+	}
+	/* Otherwise a < c && b >= d, do nothing */
+}
+
+static void
+hsw_ddi_calculate_wrpll(int clock /* in Hz */,
+			unsigned *r2_out, unsigned *n2_out, unsigned *p_out)
+{
+	uint64_t freq2k;
+	unsigned p, n2, r2;
+	struct hsw_wrpll_rnp best = { 0, 0, 0 };
+	unsigned budget;
+
+	freq2k = clock / 100;
+
+	budget = hsw_wrpll_get_budget_for_freq(clock);
+
+	/* Special case handling for 540 pixel clock: bypass WR PLL entirely
+	 * and directly pass the LC PLL to it. */
+	if (freq2k == 5400000) {
+		*n2_out = 2;
+		*p_out = 1;
+		*r2_out = 2;
+		return;
+	}
+
+	/*
+	 * Ref = LC_FREQ / R, where Ref is the actual reference input seen by
+	 * the WR PLL.
+	 *
+	 * We want R so that REF_MIN <= Ref <= REF_MAX.
+	 * Injecting R2 = 2 * R gives:
+	 *   REF_MAX * r2 > LC_FREQ * 2 and
+	 *   REF_MIN * r2 < LC_FREQ * 2
+	 *
+	 * Which means the desired boundaries for r2 are:
+	 *  LC_FREQ * 2 / REF_MAX < r2 < LC_FREQ * 2 / REF_MIN
+	 *
+	 */
+	for (r2 = LC_FREQ * 2 / REF_MAX + 1;
+	     r2 <= LC_FREQ * 2 / REF_MIN;
+	     r2++) {
+
+		/*
+		 * VCO = N * Ref, that is: VCO = N * LC_FREQ / R
+		 *
+		 * Once again we want VCO_MIN <= VCO <= VCO_MAX.
+		 * Injecting R2 = 2 * R and N2 = 2 * N, we get:
+		 *   VCO_MAX * r2 > n2 * LC_FREQ and
+		 *   VCO_MIN * r2 < n2 * LC_FREQ)
+		 *
+		 * Which means the desired boundaries for n2 are:
+		 * VCO_MIN * r2 / LC_FREQ < n2 < VCO_MAX * r2 / LC_FREQ
+		 */
+		for (n2 = VCO_MIN * r2 / LC_FREQ + 1;
+		     n2 <= VCO_MAX * r2 / LC_FREQ;
+		     n2++) {
+
+			for (p = P_MIN; p <= P_MAX; p += P_INC)
+				hsw_wrpll_update_rnp(freq2k, budget,
+						     r2, n2, p, &best);
+		}
+	}
+
+	*n2_out = best.n2;
+	*p_out = best.p;
+	*r2_out = best.r2;
+}
+
+static struct intel_shared_dpll *
+hsw_get_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state,
+	     struct intel_encoder *encoder)
+{
+	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
+	struct intel_shared_dpll *pll;
+	int clock = crtc_state->port_clock;
+
+	memset(&crtc_state->dpll_hw_state, 0,
+	       sizeof(crtc_state->dpll_hw_state));
+
+	if (encoder->type == INTEL_OUTPUT_HDMI) {
+		uint32_t val;
+		unsigned p, n2, r2;
+
+		hsw_ddi_calculate_wrpll(clock * 1000, &r2, &n2, &p);
+
+		val = WRPLL_PLL_ENABLE | WRPLL_PLL_LCPLL |
+		      WRPLL_DIVIDER_REFERENCE(r2) | WRPLL_DIVIDER_FEEDBACK(n2) |
+		      WRPLL_DIVIDER_POST(p);
+
+		crtc_state->dpll_hw_state.wrpll = val;
+
+		pll = intel_find_shared_dpll(crtc, crtc_state,
+					     DPLL_ID_WRPLL1, DPLL_ID_WRPLL2);
+
+	} else if (encoder->type == INTEL_OUTPUT_DISPLAYPORT ||
+		   encoder->type == INTEL_OUTPUT_DP_MST ||
+		   encoder->type == INTEL_OUTPUT_EDP) {
+		enum intel_dpll_id pll_id;
+
+		switch (clock / 2) {
+		case 81000:
+			pll_id = DPLL_ID_LCPLL_810;
+			break;
+		case 135000:
+			pll_id = DPLL_ID_LCPLL_1350;
+			break;
+		case 270000:
+			pll_id = DPLL_ID_LCPLL_2700;
+			break;
+		default:
+			DRM_DEBUG_KMS("Invalid clock for DP: %d\n", clock);
+			return NULL;
+		}
+
+		pll = intel_get_shared_dpll_by_id(dev_priv, pll_id);
+
+	} else if (encoder->type == INTEL_OUTPUT_ANALOG) {
+		if (WARN_ON(crtc_state->port_clock / 2 != 135000))
+			return NULL;
+
+		crtc_state->dpll_hw_state.spll =
+			SPLL_PLL_ENABLE | SPLL_PLL_FREQ_1350MHz | SPLL_PLL_SSC;
+
+		pll = intel_find_shared_dpll(crtc, crtc_state,
+					     DPLL_ID_SPLL, DPLL_ID_SPLL);
+	} else {
+		return NULL;
+	}
+
+	if (!pll)
+		return NULL;
+
+	crtc_state->ddi_pll_sel = hsw_pll_to_ddi_pll_sel(pll);
+
+	intel_reference_shared_dpll(pll, crtc_state);
+
+	return pll;
+}
+
+
+static const struct intel_shared_dpll_funcs hsw_ddi_wrpll_funcs = {
+	.enable = hsw_ddi_wrpll_enable,
+	.disable = hsw_ddi_wrpll_disable,
+	.get_hw_state = hsw_ddi_wrpll_get_hw_state,
+};
+
+static const struct intel_shared_dpll_funcs hsw_ddi_spll_funcs = {
+	.enable = hsw_ddi_spll_enable,
+	.disable = hsw_ddi_spll_disable,
+	.get_hw_state = hsw_ddi_spll_get_hw_state,
+};
+
+static void hsw_ddi_lcpll_enable(struct drm_i915_private *dev_priv,
+				 struct intel_shared_dpll *pll)
+{
+}
+
+static void hsw_ddi_lcpll_disable(struct drm_i915_private *dev_priv,
+				  struct intel_shared_dpll *pll)
+{
+}
+
+static bool hsw_ddi_lcpll_get_hw_state(struct drm_i915_private *dev_priv,
+				       struct intel_shared_dpll *pll,
+				       struct intel_dpll_hw_state *hw_state)
+{
+	return true;
+}
+
+static const struct intel_shared_dpll_funcs hsw_ddi_lcpll_funcs = {
+	.enable = hsw_ddi_lcpll_enable,
+	.disable = hsw_ddi_lcpll_disable,
+	.get_hw_state = hsw_ddi_lcpll_get_hw_state,
+};
+
+struct skl_dpll_regs {
+	i915_reg_t ctl, cfgcr1, cfgcr2;
+};
+
+/* this array is indexed by the *shared* pll id */
+static const struct skl_dpll_regs skl_dpll_regs[4] = {
+	{
+		/* DPLL 0 */
+		.ctl = LCPLL1_CTL,
+		/* DPLL 0 doesn't support HDMI mode */
+	},
+	{
+		/* DPLL 1 */
+		.ctl = LCPLL2_CTL,
+		.cfgcr1 = DPLL_CFGCR1(SKL_DPLL1),
+		.cfgcr2 = DPLL_CFGCR2(SKL_DPLL1),
+	},
+	{
+		/* DPLL 2 */
+		.ctl = WRPLL_CTL(0),
+		.cfgcr1 = DPLL_CFGCR1(SKL_DPLL2),
+		.cfgcr2 = DPLL_CFGCR2(SKL_DPLL2),
+	},
+	{
+		/* DPLL 3 */
+		.ctl = WRPLL_CTL(1),
+		.cfgcr1 = DPLL_CFGCR1(SKL_DPLL3),
+		.cfgcr2 = DPLL_CFGCR2(SKL_DPLL3),
+	},
+};
+
+static void skl_ddi_pll_write_ctrl1(struct drm_i915_private *dev_priv,
+				    struct intel_shared_dpll *pll)
+{
+	uint32_t val;
+
+	val = I915_READ(DPLL_CTRL1);
+
+	val &= ~(DPLL_CTRL1_HDMI_MODE(pll->id) | DPLL_CTRL1_SSC(pll->id) |
+		 DPLL_CTRL1_LINK_RATE_MASK(pll->id));
+	val |= pll->config.hw_state.ctrl1 << (pll->id * 6);
+
+	I915_WRITE(DPLL_CTRL1, val);
+	POSTING_READ(DPLL_CTRL1);
+}
+
+static void skl_ddi_pll_enable(struct drm_i915_private *dev_priv,
+			       struct intel_shared_dpll *pll)
+{
+	const struct skl_dpll_regs *regs = skl_dpll_regs;
+
+	skl_ddi_pll_write_ctrl1(dev_priv, pll);
+
+	I915_WRITE(regs[pll->id].cfgcr1, pll->config.hw_state.cfgcr1);
+	I915_WRITE(regs[pll->id].cfgcr2, pll->config.hw_state.cfgcr2);
+	POSTING_READ(regs[pll->id].cfgcr1);
+	POSTING_READ(regs[pll->id].cfgcr2);
+
+	/* the enable bit is always bit 31 */
+	I915_WRITE(regs[pll->id].ctl,
+		   I915_READ(regs[pll->id].ctl) | LCPLL_PLL_ENABLE);
+
+	if (wait_for(I915_READ(DPLL_STATUS) & DPLL_LOCK(pll->id), 5))
+		DRM_ERROR("DPLL %d not locked\n", pll->id);
+}
+
+static void skl_ddi_dpll0_enable(struct drm_i915_private *dev_priv,
+				 struct intel_shared_dpll *pll)
+{
+	skl_ddi_pll_write_ctrl1(dev_priv, pll);
+}
+
+static void skl_ddi_pll_disable(struct drm_i915_private *dev_priv,
+				struct intel_shared_dpll *pll)
+{
+	const struct skl_dpll_regs *regs = skl_dpll_regs;
+
+	/* the enable bit is always bit 31 */
+	I915_WRITE(regs[pll->id].ctl,
+		   I915_READ(regs[pll->id].ctl) & ~LCPLL_PLL_ENABLE);
+	POSTING_READ(regs[pll->id].ctl);
+}
+
+static void skl_ddi_dpll0_disable(struct drm_i915_private *dev_priv,
+				  struct intel_shared_dpll *pll)
+{
+}
+
+static bool skl_ddi_pll_get_hw_state(struct drm_i915_private *dev_priv,
+				     struct intel_shared_dpll *pll,
+				     struct intel_dpll_hw_state *hw_state)
+{
+	uint32_t val;
+	const struct skl_dpll_regs *regs = skl_dpll_regs;
+	bool ret;
+
+	if (!intel_display_power_get_if_enabled(dev_priv, POWER_DOMAIN_PLLS))
+		return false;
+
+	ret = false;
+
+	val = I915_READ(regs[pll->id].ctl);
+	if (!(val & LCPLL_PLL_ENABLE))
+		goto out;
+
+	val = I915_READ(DPLL_CTRL1);
+	hw_state->ctrl1 = (val >> (pll->id * 6)) & 0x3f;
+
+	/* avoid reading back stale values if HDMI mode is not enabled */
+	if (val & DPLL_CTRL1_HDMI_MODE(pll->id)) {
+		hw_state->cfgcr1 = I915_READ(regs[pll->id].cfgcr1);
+		hw_state->cfgcr2 = I915_READ(regs[pll->id].cfgcr2);
+	}
+	ret = true;
+
+out:
+	intel_display_power_put(dev_priv, POWER_DOMAIN_PLLS);
+
+	return ret;
+}
+
+static bool skl_ddi_dpll0_get_hw_state(struct drm_i915_private *dev_priv,
+				       struct intel_shared_dpll *pll,
+				       struct intel_dpll_hw_state *hw_state)
+{
+	uint32_t val;
+	const struct skl_dpll_regs *regs = skl_dpll_regs;
+	bool ret;
+
+	if (!intel_display_power_get_if_enabled(dev_priv, POWER_DOMAIN_PLLS))
+		return false;
+
+	ret = false;
+
+	/* DPLL0 is always enabled since it drives CDCLK */
+	val = I915_READ(regs[pll->id].ctl);
+	if (WARN_ON(!(val & LCPLL_PLL_ENABLE)))
+		goto out;
+
+	val = I915_READ(DPLL_CTRL1);
+	hw_state->ctrl1 = (val >> (pll->id * 6)) & 0x3f;
+
+	ret = true;
+
+out:
+	intel_display_power_put(dev_priv, POWER_DOMAIN_PLLS);
+
+	return ret;
+}
+
+struct skl_wrpll_context {
+	uint64_t min_deviation;		/* current minimal deviation */
+	uint64_t central_freq;		/* chosen central freq */
+	uint64_t dco_freq;		/* chosen dco freq */
+	unsigned int p;			/* chosen divider */
+};
+
+static void skl_wrpll_context_init(struct skl_wrpll_context *ctx)
+{
+	memset(ctx, 0, sizeof(*ctx));
+
+	ctx->min_deviation = U64_MAX;
+}
+
+/* DCO freq must be within +1%/-6%  of the DCO central freq */
+#define SKL_DCO_MAX_PDEVIATION	100
+#define SKL_DCO_MAX_NDEVIATION	600
+
+static void skl_wrpll_try_divider(struct skl_wrpll_context *ctx,
+				  uint64_t central_freq,
+				  uint64_t dco_freq,
+				  unsigned int divider)
+{
+	uint64_t deviation;
+
+	deviation = div64_u64(10000 * abs_diff(dco_freq, central_freq),
+			      central_freq);
+
+	/* positive deviation */
+	if (dco_freq >= central_freq) {
+		if (deviation < SKL_DCO_MAX_PDEVIATION &&
+		    deviation < ctx->min_deviation) {
+			ctx->min_deviation = deviation;
+			ctx->central_freq = central_freq;
+			ctx->dco_freq = dco_freq;
+			ctx->p = divider;
+		}
+	/* negative deviation */
+	} else if (deviation < SKL_DCO_MAX_NDEVIATION &&
+		   deviation < ctx->min_deviation) {
+		ctx->min_deviation = deviation;
+		ctx->central_freq = central_freq;
+		ctx->dco_freq = dco_freq;
+		ctx->p = divider;
+	}
+}
+
+static void skl_wrpll_get_multipliers(unsigned int p,
+				      unsigned int *p0 /* out */,
+				      unsigned int *p1 /* out */,
+				      unsigned int *p2 /* out */)
+{
+	/* even dividers */
+	if (p % 2 == 0) {
+		unsigned int half = p / 2;
+
+		if (half == 1 || half == 2 || half == 3 || half == 5) {
+			*p0 = 2;
+			*p1 = 1;
+			*p2 = half;
+		} else if (half % 2 == 0) {
+			*p0 = 2;
+			*p1 = half / 2;
+			*p2 = 2;
+		} else if (half % 3 == 0) {
+			*p0 = 3;
+			*p1 = half / 3;
+			*p2 = 2;
+		} else if (half % 7 == 0) {
+			*p0 = 7;
+			*p1 = half / 7;
+			*p2 = 2;
+		}
+	} else if (p == 3 || p == 9) {  /* 3, 5, 7, 9, 15, 21, 35 */
+		*p0 = 3;
+		*p1 = 1;
+		*p2 = p / 3;
+	} else if (p == 5 || p == 7) {
+		*p0 = p;
+		*p1 = 1;
+		*p2 = 1;
+	} else if (p == 15) {
+		*p0 = 3;
+		*p1 = 1;
+		*p2 = 5;
+	} else if (p == 21) {
+		*p0 = 7;
+		*p1 = 1;
+		*p2 = 3;
+	} else if (p == 35) {
+		*p0 = 7;
+		*p1 = 1;
+		*p2 = 5;
+	}
+}
+
+struct skl_wrpll_params {
+	uint32_t        dco_fraction;
+	uint32_t        dco_integer;
+	uint32_t        qdiv_ratio;
+	uint32_t        qdiv_mode;
+	uint32_t        kdiv;
+	uint32_t        pdiv;
+	uint32_t        central_freq;
+};
+
+static void skl_wrpll_params_populate(struct skl_wrpll_params *params,
+				      uint64_t afe_clock,
+				      uint64_t central_freq,
+				      uint32_t p0, uint32_t p1, uint32_t p2)
+{
+	uint64_t dco_freq;
+
+	switch (central_freq) {
+	case 9600000000ULL:
+		params->central_freq = 0;
+		break;
+	case 9000000000ULL:
+		params->central_freq = 1;
+		break;
+	case 8400000000ULL:
+		params->central_freq = 3;
+	}
+
+	switch (p0) {
+	case 1:
+		params->pdiv = 0;
+		break;
+	case 2:
+		params->pdiv = 1;
+		break;
+	case 3:
+		params->pdiv = 2;
+		break;
+	case 7:
+		params->pdiv = 4;
+		break;
+	default:
+		WARN(1, "Incorrect PDiv\n");
+	}
+
+	switch (p2) {
+	case 5:
+		params->kdiv = 0;
+		break;
+	case 2:
+		params->kdiv = 1;
+		break;
+	case 3:
+		params->kdiv = 2;
+		break;
+	case 1:
+		params->kdiv = 3;
+		break;
+	default:
+		WARN(1, "Incorrect KDiv\n");
+	}
+
+	params->qdiv_ratio = p1;
+	params->qdiv_mode = (params->qdiv_ratio == 1) ? 0 : 1;
+
+	dco_freq = p0 * p1 * p2 * afe_clock;
+
+	/*
+	 * Intermediate values are in Hz.
+	 * Divide by MHz to match bsepc
+	 */
+	params->dco_integer = div_u64(dco_freq, 24 * MHz(1));
+	params->dco_fraction =
+		div_u64((div_u64(dco_freq, 24) -
+			 params->dco_integer * MHz(1)) * 0x8000, MHz(1));
+}
+
+static bool
+skl_ddi_calculate_wrpll(int clock /* in Hz */,
+			struct skl_wrpll_params *wrpll_params)
+{
+	uint64_t afe_clock = clock * 5; /* AFE Clock is 5x Pixel clock */
+	uint64_t dco_central_freq[3] = {8400000000ULL,
+					9000000000ULL,
+					9600000000ULL};
+	static const int even_dividers[] = {  4,  6,  8, 10, 12, 14, 16, 18, 20,
+					     24, 28, 30, 32, 36, 40, 42, 44,
+					     48, 52, 54, 56, 60, 64, 66, 68,
+					     70, 72, 76, 78, 80, 84, 88, 90,
+					     92, 96, 98 };
+	static const int odd_dividers[] = { 3, 5, 7, 9, 15, 21, 35 };
+	static const struct {
+		const int *list;
+		int n_dividers;
+	} dividers[] = {
+		{ even_dividers, ARRAY_SIZE(even_dividers) },
+		{ odd_dividers, ARRAY_SIZE(odd_dividers) },
+	};
+	struct skl_wrpll_context ctx;
+	unsigned int dco, d, i;
+	unsigned int p0, p1, p2;
+
+	skl_wrpll_context_init(&ctx);
+
+	for (d = 0; d < ARRAY_SIZE(dividers); d++) {
+		for (dco = 0; dco < ARRAY_SIZE(dco_central_freq); dco++) {
+			for (i = 0; i < dividers[d].n_dividers; i++) {
+				unsigned int p = dividers[d].list[i];
+				uint64_t dco_freq = p * afe_clock;
+
+				skl_wrpll_try_divider(&ctx,
+						      dco_central_freq[dco],
+						      dco_freq,
+						      p);
+				/*
+				 * Skip the remaining dividers if we're sure to
+				 * have found the definitive divider, we can't
+				 * improve a 0 deviation.
+				 */
+				if (ctx.min_deviation == 0)
+					goto skip_remaining_dividers;
+			}
+		}
+
+skip_remaining_dividers:
+		/*
+		 * If a solution is found with an even divider, prefer
+		 * this one.
+		 */
+		if (d == 0 && ctx.p)
+			break;
+	}
+
+	if (!ctx.p) {
+		DRM_DEBUG_DRIVER("No valid divider found for %dHz\n", clock);
+		return false;
+	}
+
+	/*
+	 * gcc incorrectly analyses that these can be used without being
+	 * initialized. To be fair, it's hard to guess.
+	 */
+	p0 = p1 = p2 = 0;
+	skl_wrpll_get_multipliers(ctx.p, &p0, &p1, &p2);
+	skl_wrpll_params_populate(wrpll_params, afe_clock, ctx.central_freq,
+				  p0, p1, p2);
+
+	return true;
+}
+
+static struct intel_shared_dpll *
+skl_get_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state,
+	     struct intel_encoder *encoder)
+{
+	struct intel_shared_dpll *pll;
+	uint32_t ctrl1, cfgcr1, cfgcr2;
+	int clock = crtc_state->port_clock;
+
+	/*
+	 * See comment in intel_dpll_hw_state to understand why we always use 0
+	 * as the DPLL id in this function.
+	 */
+
+	ctrl1 = DPLL_CTRL1_OVERRIDE(0);
+
+	if (encoder->type == INTEL_OUTPUT_HDMI) {
+		struct skl_wrpll_params wrpll_params = { 0, };
+
+		ctrl1 |= DPLL_CTRL1_HDMI_MODE(0);
+
+		if (!skl_ddi_calculate_wrpll(clock * 1000, &wrpll_params))
+			return NULL;
+
+		cfgcr1 = DPLL_CFGCR1_FREQ_ENABLE |
+			 DPLL_CFGCR1_DCO_FRACTION(wrpll_params.dco_fraction) |
+			 wrpll_params.dco_integer;
+
+		cfgcr2 = DPLL_CFGCR2_QDIV_RATIO(wrpll_params.qdiv_ratio) |
+			 DPLL_CFGCR2_QDIV_MODE(wrpll_params.qdiv_mode) |
+			 DPLL_CFGCR2_KDIV(wrpll_params.kdiv) |
+			 DPLL_CFGCR2_PDIV(wrpll_params.pdiv) |
+			 wrpll_params.central_freq;
+	} else if (encoder->type == INTEL_OUTPUT_DISPLAYPORT ||
+		   encoder->type == INTEL_OUTPUT_DP_MST ||
+		   encoder->type == INTEL_OUTPUT_EDP) {
+		switch (crtc_state->port_clock / 2) {
+		case 81000:
+			ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_810, 0);
+			break;
+		case 135000:
+			ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_1350, 0);
+			break;
+		case 270000:
+			ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_2700, 0);
+			break;
+		/* eDP 1.4 rates */
+		case 162000:
+			ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_1620, 0);
+			break;
+		/* TBD: For DP link rates 2.16 GHz and 4.32 GHz, VCO is 8640 which
+		results in CDCLK change. Need to handle the change of CDCLK by
+		disabling pipes and re-enabling them */
+		case 108000:
+			ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_1080, 0);
+			break;
+		case 216000:
+			ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_2160, 0);
+			break;
+		}
+
+		cfgcr1 = cfgcr2 = 0;
+	} else {
+		return NULL;
+	}
+
+	memset(&crtc_state->dpll_hw_state, 0,
+	       sizeof(crtc_state->dpll_hw_state));
+
+	crtc_state->dpll_hw_state.ctrl1 = ctrl1;
+	crtc_state->dpll_hw_state.cfgcr1 = cfgcr1;
+	crtc_state->dpll_hw_state.cfgcr2 = cfgcr2;
+
+	if (encoder->type == INTEL_OUTPUT_EDP)
+		pll = intel_find_shared_dpll(crtc, crtc_state,
+					     DPLL_ID_SKL_DPLL0,
+					     DPLL_ID_SKL_DPLL0);
+	else
+		pll = intel_find_shared_dpll(crtc, crtc_state,
+					     DPLL_ID_SKL_DPLL1,
+					     DPLL_ID_SKL_DPLL3);
+	if (!pll)
+		return NULL;
+
+	crtc_state->ddi_pll_sel = pll->id;
+
+	intel_reference_shared_dpll(pll, crtc_state);
+
+	return pll;
+}
+
+static const struct intel_shared_dpll_funcs skl_ddi_pll_funcs = {
+	.enable = skl_ddi_pll_enable,
+	.disable = skl_ddi_pll_disable,
+	.get_hw_state = skl_ddi_pll_get_hw_state,
+};
+
+static const struct intel_shared_dpll_funcs skl_ddi_dpll0_funcs = {
+	.enable = skl_ddi_dpll0_enable,
+	.disable = skl_ddi_dpll0_disable,
+	.get_hw_state = skl_ddi_dpll0_get_hw_state,
+};
+
+static void bxt_ddi_pll_enable(struct drm_i915_private *dev_priv,
+				struct intel_shared_dpll *pll)
+{
+	uint32_t temp;
+	enum port port = (enum port)pll->id;	/* 1:1 port->PLL mapping */
+
+	/* Non-SSC reference */
+	temp = I915_READ(BXT_PORT_PLL_ENABLE(port));
+	temp |= PORT_PLL_REF_SEL;
+	I915_WRITE(BXT_PORT_PLL_ENABLE(port), temp);
+
+	/* Disable 10 bit clock */
+	temp = I915_READ(BXT_PORT_PLL_EBB_4(port));
+	temp &= ~PORT_PLL_10BIT_CLK_ENABLE;
+	I915_WRITE(BXT_PORT_PLL_EBB_4(port), temp);
+
+	/* Write P1 & P2 */
+	temp = I915_READ(BXT_PORT_PLL_EBB_0(port));
+	temp &= ~(PORT_PLL_P1_MASK | PORT_PLL_P2_MASK);
+	temp |= pll->config.hw_state.ebb0;
+	I915_WRITE(BXT_PORT_PLL_EBB_0(port), temp);
+
+	/* Write M2 integer */
+	temp = I915_READ(BXT_PORT_PLL(port, 0));
+	temp &= ~PORT_PLL_M2_MASK;
+	temp |= pll->config.hw_state.pll0;
+	I915_WRITE(BXT_PORT_PLL(port, 0), temp);
+
+	/* Write N */
+	temp = I915_READ(BXT_PORT_PLL(port, 1));
+	temp &= ~PORT_PLL_N_MASK;
+	temp |= pll->config.hw_state.pll1;
+	I915_WRITE(BXT_PORT_PLL(port, 1), temp);
+
+	/* Write M2 fraction */
+	temp = I915_READ(BXT_PORT_PLL(port, 2));
+	temp &= ~PORT_PLL_M2_FRAC_MASK;
+	temp |= pll->config.hw_state.pll2;
+	I915_WRITE(BXT_PORT_PLL(port, 2), temp);
+
+	/* Write M2 fraction enable */
+	temp = I915_READ(BXT_PORT_PLL(port, 3));
+	temp &= ~PORT_PLL_M2_FRAC_ENABLE;
+	temp |= pll->config.hw_state.pll3;
+	I915_WRITE(BXT_PORT_PLL(port, 3), temp);
+
+	/* Write coeff */
+	temp = I915_READ(BXT_PORT_PLL(port, 6));
+	temp &= ~PORT_PLL_PROP_COEFF_MASK;
+	temp &= ~PORT_PLL_INT_COEFF_MASK;
+	temp &= ~PORT_PLL_GAIN_CTL_MASK;
+	temp |= pll->config.hw_state.pll6;
+	I915_WRITE(BXT_PORT_PLL(port, 6), temp);
+
+	/* Write calibration val */
+	temp = I915_READ(BXT_PORT_PLL(port, 8));
+	temp &= ~PORT_PLL_TARGET_CNT_MASK;
+	temp |= pll->config.hw_state.pll8;
+	I915_WRITE(BXT_PORT_PLL(port, 8), temp);
+
+	temp = I915_READ(BXT_PORT_PLL(port, 9));
+	temp &= ~PORT_PLL_LOCK_THRESHOLD_MASK;
+	temp |= pll->config.hw_state.pll9;
+	I915_WRITE(BXT_PORT_PLL(port, 9), temp);
+
+	temp = I915_READ(BXT_PORT_PLL(port, 10));
+	temp &= ~PORT_PLL_DCO_AMP_OVR_EN_H;
+	temp &= ~PORT_PLL_DCO_AMP_MASK;
+	temp |= pll->config.hw_state.pll10;
+	I915_WRITE(BXT_PORT_PLL(port, 10), temp);
+
+	/* Recalibrate with new settings */
+	temp = I915_READ(BXT_PORT_PLL_EBB_4(port));
+	temp |= PORT_PLL_RECALIBRATE;
+	I915_WRITE(BXT_PORT_PLL_EBB_4(port), temp);
+	temp &= ~PORT_PLL_10BIT_CLK_ENABLE;
+	temp |= pll->config.hw_state.ebb4;
+	I915_WRITE(BXT_PORT_PLL_EBB_4(port), temp);
+
+	/* Enable PLL */
+	temp = I915_READ(BXT_PORT_PLL_ENABLE(port));
+	temp |= PORT_PLL_ENABLE;
+	I915_WRITE(BXT_PORT_PLL_ENABLE(port), temp);
+	POSTING_READ(BXT_PORT_PLL_ENABLE(port));
+
+	if (wait_for_us((I915_READ(BXT_PORT_PLL_ENABLE(port)) & PORT_PLL_LOCK),
+			200))
+		DRM_ERROR("PLL %d not locked\n", port);
+
+	/*
+	 * While we write to the group register to program all lanes at once we
+	 * can read only lane registers and we pick lanes 0/1 for that.
+	 */
+	temp = I915_READ(BXT_PORT_PCS_DW12_LN01(port));
+	temp &= ~LANE_STAGGER_MASK;
+	temp &= ~LANESTAGGER_STRAP_OVRD;
+	temp |= pll->config.hw_state.pcsdw12;
+	I915_WRITE(BXT_PORT_PCS_DW12_GRP(port), temp);
+}
+
+static void bxt_ddi_pll_disable(struct drm_i915_private *dev_priv,
+					struct intel_shared_dpll *pll)
+{
+	enum port port = (enum port)pll->id;	/* 1:1 port->PLL mapping */
+	uint32_t temp;
+
+	temp = I915_READ(BXT_PORT_PLL_ENABLE(port));
+	temp &= ~PORT_PLL_ENABLE;
+	I915_WRITE(BXT_PORT_PLL_ENABLE(port), temp);
+	POSTING_READ(BXT_PORT_PLL_ENABLE(port));
+}
+
+static bool bxt_ddi_pll_get_hw_state(struct drm_i915_private *dev_priv,
+					struct intel_shared_dpll *pll,
+					struct intel_dpll_hw_state *hw_state)
+{
+	enum port port = (enum port)pll->id;	/* 1:1 port->PLL mapping */
+	uint32_t val;
+	bool ret;
+
+	if (!intel_display_power_get_if_enabled(dev_priv, POWER_DOMAIN_PLLS))
+		return false;
+
+	ret = false;
+
+	val = I915_READ(BXT_PORT_PLL_ENABLE(port));
+	if (!(val & PORT_PLL_ENABLE))
+		goto out;
+
+	hw_state->ebb0 = I915_READ(BXT_PORT_PLL_EBB_0(port));
+	hw_state->ebb0 &= PORT_PLL_P1_MASK | PORT_PLL_P2_MASK;
+
+	hw_state->ebb4 = I915_READ(BXT_PORT_PLL_EBB_4(port));
+	hw_state->ebb4 &= PORT_PLL_10BIT_CLK_ENABLE;
+
+	hw_state->pll0 = I915_READ(BXT_PORT_PLL(port, 0));
+	hw_state->pll0 &= PORT_PLL_M2_MASK;
+
+	hw_state->pll1 = I915_READ(BXT_PORT_PLL(port, 1));
+	hw_state->pll1 &= PORT_PLL_N_MASK;
+
+	hw_state->pll2 = I915_READ(BXT_PORT_PLL(port, 2));
+	hw_state->pll2 &= PORT_PLL_M2_FRAC_MASK;
+
+	hw_state->pll3 = I915_READ(BXT_PORT_PLL(port, 3));
+	hw_state->pll3 &= PORT_PLL_M2_FRAC_ENABLE;
+
+	hw_state->pll6 = I915_READ(BXT_PORT_PLL(port, 6));
+	hw_state->pll6 &= PORT_PLL_PROP_COEFF_MASK |
+			  PORT_PLL_INT_COEFF_MASK |
+			  PORT_PLL_GAIN_CTL_MASK;
+
+	hw_state->pll8 = I915_READ(BXT_PORT_PLL(port, 8));
+	hw_state->pll8 &= PORT_PLL_TARGET_CNT_MASK;
+
+	hw_state->pll9 = I915_READ(BXT_PORT_PLL(port, 9));
+	hw_state->pll9 &= PORT_PLL_LOCK_THRESHOLD_MASK;
+
+	hw_state->pll10 = I915_READ(BXT_PORT_PLL(port, 10));
+	hw_state->pll10 &= PORT_PLL_DCO_AMP_OVR_EN_H |
+			   PORT_PLL_DCO_AMP_MASK;
+
+	/*
+	 * While we write to the group register to program all lanes at once we
+	 * can read only lane registers. We configure all lanes the same way, so
+	 * here just read out lanes 0/1 and output a note if lanes 2/3 differ.
+	 */
+	hw_state->pcsdw12 = I915_READ(BXT_PORT_PCS_DW12_LN01(port));
+	if (I915_READ(BXT_PORT_PCS_DW12_LN23(port)) != hw_state->pcsdw12)
+		DRM_DEBUG_DRIVER("lane stagger config different for lane 01 (%08x) and 23 (%08x)\n",
+				 hw_state->pcsdw12,
+				 I915_READ(BXT_PORT_PCS_DW12_LN23(port)));
+	hw_state->pcsdw12 &= LANE_STAGGER_MASK | LANESTAGGER_STRAP_OVRD;
+
+	ret = true;
+
+out:
+	intel_display_power_put(dev_priv, POWER_DOMAIN_PLLS);
+
+	return ret;
+}
+
+/* bxt clock parameters */
+struct bxt_clk_div {
+	int clock;
+	uint32_t p1;
+	uint32_t p2;
+	uint32_t m2_int;
+	uint32_t m2_frac;
+	bool m2_frac_en;
+	uint32_t n;
+};
+
+/* pre-calculated values for DP linkrates */
+static const struct bxt_clk_div bxt_dp_clk_val[] = {
+	{162000, 4, 2, 32, 1677722, 1, 1},
+	{270000, 4, 1, 27,       0, 0, 1},
+	{540000, 2, 1, 27,       0, 0, 1},
+	{216000, 3, 2, 32, 1677722, 1, 1},
+	{243000, 4, 1, 24, 1258291, 1, 1},
+	{324000, 4, 1, 32, 1677722, 1, 1},
+	{432000, 3, 1, 32, 1677722, 1, 1}
+};
+
+static struct intel_shared_dpll *
+bxt_get_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state,
+	     struct intel_encoder *encoder)
+{
+	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
+	struct intel_shared_dpll *pll;
+	enum intel_dpll_id i;
+	struct intel_digital_port *intel_dig_port;
+	struct bxt_clk_div clk_div = {0};
+	int vco = 0;
+	uint32_t prop_coef, int_coef, gain_ctl, targ_cnt;
+	uint32_t lanestagger;
+	int clock = crtc_state->port_clock;
+
+	if (encoder->type == INTEL_OUTPUT_HDMI) {
+		intel_clock_t best_clock;
+
+		/* Calculate HDMI div */
+		/*
+		 * FIXME: tie the following calculation into
+		 * i9xx_crtc_compute_clock
+		 */
+		if (!bxt_find_best_dpll(crtc_state, clock, &best_clock)) {
+			DRM_DEBUG_DRIVER("no PLL dividers found for clock %d pipe %c\n",
+					 clock, pipe_name(crtc->pipe));
+			return NULL;
+		}
+
+		clk_div.p1 = best_clock.p1;
+		clk_div.p2 = best_clock.p2;
+		WARN_ON(best_clock.m1 != 2);
+		clk_div.n = best_clock.n;
+		clk_div.m2_int = best_clock.m2 >> 22;
+		clk_div.m2_frac = best_clock.m2 & ((1 << 22) - 1);
+		clk_div.m2_frac_en = clk_div.m2_frac != 0;
+
+		vco = best_clock.vco;
+	} else if (encoder->type == INTEL_OUTPUT_DISPLAYPORT ||
+		   encoder->type == INTEL_OUTPUT_EDP) {
+		int i;
+
+		clk_div = bxt_dp_clk_val[0];
+		for (i = 0; i < ARRAY_SIZE(bxt_dp_clk_val); ++i) {
+			if (bxt_dp_clk_val[i].clock == clock) {
+				clk_div = bxt_dp_clk_val[i];
+				break;
+			}
+		}
+		vco = clock * 10 / 2 * clk_div.p1 * clk_div.p2;
+	}
+
+	if (vco >= 6200000 && vco <= 6700000) {
+		prop_coef = 4;
+		int_coef = 9;
+		gain_ctl = 3;
+		targ_cnt = 8;
+	} else if ((vco > 5400000 && vco < 6200000) ||
+			(vco >= 4800000 && vco < 5400000)) {
+		prop_coef = 5;
+		int_coef = 11;
+		gain_ctl = 3;
+		targ_cnt = 9;
+	} else if (vco == 5400000) {
+		prop_coef = 3;
+		int_coef = 8;
+		gain_ctl = 1;
+		targ_cnt = 9;
+	} else {
+		DRM_ERROR("Invalid VCO\n");
+		return NULL;
+	}
+
+	memset(&crtc_state->dpll_hw_state, 0,
+	       sizeof(crtc_state->dpll_hw_state));
+
+	if (clock > 270000)
+		lanestagger = 0x18;
+	else if (clock > 135000)
+		lanestagger = 0x0d;
+	else if (clock > 67000)
+		lanestagger = 0x07;
+	else if (clock > 33000)
+		lanestagger = 0x04;
+	else
+		lanestagger = 0x02;
+
+	crtc_state->dpll_hw_state.ebb0 =
+		PORT_PLL_P1(clk_div.p1) | PORT_PLL_P2(clk_div.p2);
+	crtc_state->dpll_hw_state.pll0 = clk_div.m2_int;
+	crtc_state->dpll_hw_state.pll1 = PORT_PLL_N(clk_div.n);
+	crtc_state->dpll_hw_state.pll2 = clk_div.m2_frac;
+
+	if (clk_div.m2_frac_en)
+		crtc_state->dpll_hw_state.pll3 =
+			PORT_PLL_M2_FRAC_ENABLE;
+
+	crtc_state->dpll_hw_state.pll6 =
+		prop_coef | PORT_PLL_INT_COEFF(int_coef);
+	crtc_state->dpll_hw_state.pll6 |=
+		PORT_PLL_GAIN_CTL(gain_ctl);
+
+	crtc_state->dpll_hw_state.pll8 = targ_cnt;
+
+	crtc_state->dpll_hw_state.pll9 = 5 << PORT_PLL_LOCK_THRESHOLD_SHIFT;
+
+	crtc_state->dpll_hw_state.pll10 =
+		PORT_PLL_DCO_AMP(PORT_PLL_DCO_AMP_DEFAULT)
+		| PORT_PLL_DCO_AMP_OVR_EN_H;
+
+	crtc_state->dpll_hw_state.ebb4 = PORT_PLL_10BIT_CLK_ENABLE;
+
+	crtc_state->dpll_hw_state.pcsdw12 =
+		LANESTAGGER_STRAP_OVRD | lanestagger;
+
+	intel_dig_port = enc_to_dig_port(&encoder->base);
+
+	/* 1:1 mapping between ports and PLLs */
+	i = (enum intel_dpll_id) intel_dig_port->port;
+	pll = intel_get_shared_dpll_by_id(dev_priv, i);
+
+	DRM_DEBUG_KMS("CRTC:%d using pre-allocated %s\n",
+		crtc->base.base.id, pll->name);
+
+	intel_reference_shared_dpll(pll, crtc_state);
+
+	/* shared DPLL id 0 is DPLL A */
+	crtc_state->ddi_pll_sel = pll->id;
+
+	return pll;
+}
+
+static const struct intel_shared_dpll_funcs bxt_ddi_pll_funcs = {
+	.enable = bxt_ddi_pll_enable,
+	.disable = bxt_ddi_pll_disable,
+	.get_hw_state = bxt_ddi_pll_get_hw_state,
+};
+
+static void intel_ddi_pll_init(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	uint32_t val = I915_READ(LCPLL_CTL);
+
+	if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev)) {
+		int cdclk_freq;
+
+		cdclk_freq = dev_priv->display.get_display_clock_speed(dev);
+		dev_priv->skl_boot_cdclk = cdclk_freq;
+		if (skl_sanitize_cdclk(dev_priv))
+			DRM_DEBUG_KMS("Sanitized cdclk programmed by pre-os\n");
+		if (!(I915_READ(LCPLL1_CTL) & LCPLL_PLL_ENABLE))
+			DRM_ERROR("LCPLL1 is disabled\n");
+	} else if (!IS_BROXTON(dev_priv)) {
+		/*
+		 * The LCPLL register should be turned on by the BIOS. For now
+		 * let's just check its state and print errors in case
+		 * something is wrong.  Don't even try to turn it on.
+		 */
+
+		if (val & LCPLL_CD_SOURCE_FCLK)
+			DRM_ERROR("CDCLK source is not LCPLL\n");
+
+		if (val & LCPLL_PLL_DISABLE)
+			DRM_ERROR("LCPLL is disabled\n");
+	}
+}
+
+struct dpll_info {
+	const char *name;
+	const int id;
+	const struct intel_shared_dpll_funcs *funcs;
+	uint32_t flags;
+};
+
+struct intel_dpll_mgr {
+	const struct dpll_info *dpll_info;
+
+	struct intel_shared_dpll *(*get_dpll)(struct intel_crtc *crtc,
+					      struct intel_crtc_state *crtc_state,
+					      struct intel_encoder *encoder);
+};
+
+static const struct dpll_info pch_plls[] = {
+	{ "PCH DPLL A", DPLL_ID_PCH_PLL_A, &ibx_pch_dpll_funcs, 0 },
+	{ "PCH DPLL B", DPLL_ID_PCH_PLL_B, &ibx_pch_dpll_funcs, 0 },
+	{ NULL, -1, NULL, 0 },
+};
+
+static const struct intel_dpll_mgr pch_pll_mgr = {
+	.dpll_info = pch_plls,
+	.get_dpll = ibx_get_dpll,
+};
+
+static const struct dpll_info hsw_plls[] = {
+	{ "WRPLL 1",    DPLL_ID_WRPLL1,     &hsw_ddi_wrpll_funcs, 0 },
+	{ "WRPLL 2",    DPLL_ID_WRPLL2,     &hsw_ddi_wrpll_funcs, 0 },
+	{ "SPLL",       DPLL_ID_SPLL,       &hsw_ddi_spll_funcs,  0 },
+	{ "LCPLL 810",  DPLL_ID_LCPLL_810,  &hsw_ddi_lcpll_funcs, INTEL_DPLL_ALWAYS_ON },
+	{ "LCPLL 1350", DPLL_ID_LCPLL_1350, &hsw_ddi_lcpll_funcs, INTEL_DPLL_ALWAYS_ON },
+	{ "LCPLL 2700", DPLL_ID_LCPLL_2700, &hsw_ddi_lcpll_funcs, INTEL_DPLL_ALWAYS_ON },
+	{ NULL, -1, NULL, },
+};
+
+static const struct intel_dpll_mgr hsw_pll_mgr = {
+	.dpll_info = hsw_plls,
+	.get_dpll = hsw_get_dpll,
+};
+
+static const struct dpll_info skl_plls[] = {
+	{ "DPLL 0", DPLL_ID_SKL_DPLL0, &skl_ddi_dpll0_funcs, INTEL_DPLL_ALWAYS_ON },
+	{ "DPLL 1", DPLL_ID_SKL_DPLL1, &skl_ddi_pll_funcs,   0 },
+	{ "DPLL 2", DPLL_ID_SKL_DPLL2, &skl_ddi_pll_funcs,   0 },
+	{ "DPLL 3", DPLL_ID_SKL_DPLL3, &skl_ddi_pll_funcs,   0 },
+	{ NULL, -1, NULL, },
+};
+
+static const struct intel_dpll_mgr skl_pll_mgr = {
+	.dpll_info = skl_plls,
+	.get_dpll = skl_get_dpll,
+};
+
+static const struct dpll_info bxt_plls[] = {
+	{ "PORT PLL A", DPLL_ID_SKL_DPLL0, &bxt_ddi_pll_funcs, 0 },
+	{ "PORT PLL B", DPLL_ID_SKL_DPLL1, &bxt_ddi_pll_funcs, 0 },
+	{ "PORT PLL C", DPLL_ID_SKL_DPLL2, &bxt_ddi_pll_funcs, 0 },
+	{ NULL, -1, NULL, },
+};
+
+static const struct intel_dpll_mgr bxt_pll_mgr = {
+	.dpll_info = bxt_plls,
+	.get_dpll = bxt_get_dpll,
+};
+
+void intel_shared_dpll_init(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	const struct intel_dpll_mgr *dpll_mgr = NULL;
+	const struct dpll_info *dpll_info;
+	int i;
+
+	if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev))
+		dpll_mgr = &skl_pll_mgr;
+	else if (IS_BROXTON(dev))
+		dpll_mgr = &bxt_pll_mgr;
+	else if (HAS_DDI(dev))
+		dpll_mgr = &hsw_pll_mgr;
+	else if (HAS_PCH_IBX(dev) || HAS_PCH_CPT(dev))
+		dpll_mgr = &pch_pll_mgr;
+
+	if (!dpll_mgr) {
+		dev_priv->num_shared_dpll = 0;
+		return;
+	}
+
+	dpll_info = dpll_mgr->dpll_info;
+
+	for (i = 0; dpll_info[i].id >= 0; i++) {
+		WARN_ON(i != dpll_info[i].id);
+
+		dev_priv->shared_dplls[i].id = dpll_info[i].id;
+		dev_priv->shared_dplls[i].name = dpll_info[i].name;
+		dev_priv->shared_dplls[i].funcs = *dpll_info[i].funcs;
+		dev_priv->shared_dplls[i].flags = dpll_info[i].flags;
+	}
+
+	dev_priv->dpll_mgr = dpll_mgr;
+	dev_priv->num_shared_dpll = i;
+	mutex_init(&dev_priv->dpll_lock);
+
+	BUG_ON(dev_priv->num_shared_dpll > I915_NUM_PLLS);
+
+	/* FIXME: Move this to a more suitable place */
+	if (HAS_DDI(dev))
+		intel_ddi_pll_init(dev);
+}
+
+struct intel_shared_dpll *
+intel_get_shared_dpll(struct intel_crtc *crtc,
+		      struct intel_crtc_state *crtc_state,
+		      struct intel_encoder *encoder)
+{
+	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
+	const struct intel_dpll_mgr *dpll_mgr = dev_priv->dpll_mgr;
+
+	if (WARN_ON(!dpll_mgr))
+		return NULL;
+
+	return dpll_mgr->get_dpll(crtc, crtc_state, encoder);
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/i915/intel_dpll_mgr.h
@@ -0,0 +1,164 @@
+/*
+ * Copyright © 2012-2016 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ */
+
+#ifndef _INTEL_DPLL_MGR_H_
+#define _INTEL_DPLL_MGR_H_
+
+/*FIXME: Move this to a more appropriate place. */
+#define abs_diff(a, b) ({			\
+	typeof(a) __a = (a);			\
+	typeof(b) __b = (b);			\
+	(void) (&__a == &__b);			\
+	__a > __b ? (__a - __b) : (__b - __a); })
+
+struct drm_i915_private;
+struct intel_crtc;
+struct intel_crtc_state;
+struct intel_encoder;
+
+struct intel_shared_dpll;
+struct intel_dpll_mgr;
+
+enum intel_dpll_id {
+	DPLL_ID_PRIVATE = -1, /* non-shared dpll in use */
+	/* real shared dpll ids must be >= 0 */
+	DPLL_ID_PCH_PLL_A = 0,
+	DPLL_ID_PCH_PLL_B = 1,
+	/* hsw/bdw */
+	DPLL_ID_WRPLL1 = 0,
+	DPLL_ID_WRPLL2 = 1,
+	DPLL_ID_SPLL = 2,
+	DPLL_ID_LCPLL_810 = 3,
+	DPLL_ID_LCPLL_1350 = 4,
+	DPLL_ID_LCPLL_2700 = 5,
+
+	/* skl */
+	DPLL_ID_SKL_DPLL0 = 0,
+	DPLL_ID_SKL_DPLL1 = 1,
+	DPLL_ID_SKL_DPLL2 = 2,
+	DPLL_ID_SKL_DPLL3 = 3,
+};
+#define I915_NUM_PLLS 6
+
+/** Inform the state checker that the DPLL is kept enabled even if not
+ * in use by any crtc.
+ */
+#define INTEL_DPLL_ALWAYS_ON	(1 << 0)
+
+struct intel_dpll_hw_state {
+	/* i9xx, pch plls */
+	uint32_t dpll;
+	uint32_t dpll_md;
+	uint32_t fp0;
+	uint32_t fp1;
+
+	/* hsw, bdw */
+	uint32_t wrpll;
+	uint32_t spll;
+
+	/* skl */
+	/*
+	 * DPLL_CTRL1 has 6 bits for each each this DPLL. We store those in
+	 * lower part of ctrl1 and they get shifted into position when writing
+	 * the register.  This allows us to easily compare the state to share
+	 * the DPLL.
+	 */
+	uint32_t ctrl1;
+	/* HDMI only, 0 when used for DP */
+	uint32_t cfgcr1, cfgcr2;
+
+	/* bxt */
+	uint32_t ebb0, ebb4, pll0, pll1, pll2, pll3, pll6, pll8, pll9, pll10,
+		 pcsdw12;
+};
+
+struct intel_shared_dpll_config {
+	unsigned crtc_mask; /* mask of CRTCs sharing this PLL */
+	struct intel_dpll_hw_state hw_state;
+};
+
+struct intel_shared_dpll_funcs {
+	/* The mode_set hook is optional and should be used together with the
+	 * intel_prepare_shared_dpll function. */
+	void (*mode_set)(struct drm_i915_private *dev_priv,
+			 struct intel_shared_dpll *pll);
+	void (*enable)(struct drm_i915_private *dev_priv,
+		       struct intel_shared_dpll *pll);
+	void (*disable)(struct drm_i915_private *dev_priv,
+			struct intel_shared_dpll *pll);
+	bool (*get_hw_state)(struct drm_i915_private *dev_priv,
+			     struct intel_shared_dpll *pll,
+			     struct intel_dpll_hw_state *hw_state);
+};
+
+struct intel_shared_dpll {
+	struct intel_shared_dpll_config config;
+
+	unsigned active_mask; /* mask of active CRTCs (i.e. DPMS on) */
+	bool on; /* is the PLL actually active? Disabled during modeset */
+	const char *name;
+	/* should match the index in the dev_priv->shared_dplls array */
+	enum intel_dpll_id id;
+
+	struct intel_shared_dpll_funcs funcs;
+
+	uint32_t flags;
+};
+
+#define SKL_DPLL0 0
+#define SKL_DPLL1 1
+#define SKL_DPLL2 2
+#define SKL_DPLL3 3
+
+/* shared dpll functions */
+struct intel_shared_dpll *
+intel_get_shared_dpll_by_id(struct drm_i915_private *dev_priv,
+			    enum intel_dpll_id id);
+enum intel_dpll_id
+intel_get_shared_dpll_id(struct drm_i915_private *dev_priv,
+			 struct intel_shared_dpll *pll);
+void
+intel_shared_dpll_config_get(struct intel_shared_dpll_config *config,
+			     struct intel_shared_dpll *pll,
+			     struct intel_crtc *crtc);
+void
+intel_shared_dpll_config_put(struct intel_shared_dpll_config *config,
+			     struct intel_shared_dpll *pll,
+			     struct intel_crtc *crtc);
+void assert_shared_dpll(struct drm_i915_private *dev_priv,
+			struct intel_shared_dpll *pll,
+			bool state);
+#define assert_shared_dpll_enabled(d, p) assert_shared_dpll(d, p, true)
+#define assert_shared_dpll_disabled(d, p) assert_shared_dpll(d, p, false)
+struct intel_shared_dpll *intel_get_shared_dpll(struct intel_crtc *crtc,
+						struct intel_crtc_state *state,
+						struct intel_encoder *encoder);
+void intel_prepare_shared_dpll(struct intel_crtc *crtc);
+void intel_enable_shared_dpll(struct intel_crtc *crtc);
+void intel_disable_shared_dpll(struct intel_crtc *crtc);
+void intel_shared_dpll_commit(struct drm_atomic_state *state);
+void intel_shared_dpll_init(struct drm_device *dev);
+
+
+#endif /* _INTEL_DPLL_MGR_H_ */
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/i915/intel_drv.h
@@ -0,0 +1,1695 @@
+/*
+ * Copyright (c) 2006 Dave Airlie <airlied@linux.ie>
+ * Copyright (c) 2007-2008 Intel Corporation
+ *   Jesse Barnes <jesse.barnes@intel.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+#ifndef __INTEL_DRV_H__
+#define __INTEL_DRV_H__
+
+#include <linux/async.h>
+#include <linux/i2c.h>
+#include <linux/hdmi.h>
+#include <drm/i915_drm.h>
+#include "i915_drv.h"
+#include <drm/drm_crtc.h>
+#include <drm/drm_crtc_helper.h>
+#include <drm/drm_fb_helper.h>
+#include <drm/drm_dp_dual_mode_helper.h>
+#include <drm/drm_dp_mst_helper.h>
+#include <drm/drm_rect.h>
+#include <drm/drm_atomic.h>
+
+/**
+ * _wait_for - magic (register) wait macro
+ *
+ * Does the right thing for modeset paths when run under kdgb or similar atomic
+ * contexts. Note that it's important that we check the condition again after
+ * having timed out, since the timeout could be due to preemption or similar and
+ * we've never had a chance to check the condition before the timeout.
+ *
+ * TODO: When modesetting has fully transitioned to atomic, the below
+ * drm_can_sleep() can be removed and in_atomic()/!in_atomic() asserts
+ * added.
+ */
+#define _wait_for(COND, US, W) ({ \
+	unsigned long timeout__ = jiffies + usecs_to_jiffies(US) + 1;	\
+	int ret__ = 0;							\
+	while (!(COND)) {						\
+		if (time_after(jiffies, timeout__)) {			\
+			if (!(COND))					\
+				ret__ = -ETIMEDOUT;			\
+			break;						\
+		}							\
+		if ((W) && drm_can_sleep()) {				\
+			usleep_range((W), (W)*2);			\
+		} else {						\
+			cpu_relax();					\
+		}							\
+	}								\
+	ret__;								\
+})
+
+#define wait_for(COND, MS)	  	_wait_for((COND), (MS) * 1000, 1000)
+#define wait_for_us(COND, US)	  	_wait_for((COND), (US), 1)
+
+/* If CONFIG_PREEMPT_COUNT is disabled, in_atomic() always reports false. */
+#if defined(CONFIG_DRM_I915_DEBUG) && defined(CONFIG_PREEMPT_COUNT)
+# define _WAIT_FOR_ATOMIC_CHECK WARN_ON_ONCE(!in_atomic())
+#else
+# define _WAIT_FOR_ATOMIC_CHECK do { } while (0)
+#endif
+
+#define _wait_for_atomic(COND, US) ({ \
+	unsigned long end__; \
+	int ret__ = 0; \
+	_WAIT_FOR_ATOMIC_CHECK; \
+	BUILD_BUG_ON((US) > 50000); \
+	end__ = (local_clock() >> 10) + (US) + 1; \
+	while (!(COND)) { \
+		if (time_after((unsigned long)(local_clock() >> 10), end__)) { \
+			/* Unlike the regular wait_for(), this atomic variant \
+			 * cannot be preempted (and we'll just ignore the issue\
+			 * of irq interruptions) and so we know that no time \
+			 * has passed since the last check of COND and can \
+			 * immediately report the timeout. \
+			 */ \
+			ret__ = -ETIMEDOUT; \
+			break; \
+		} \
+		cpu_relax(); \
+	} \
+	ret__; \
+})
+
+#define wait_for_atomic(COND, MS)	_wait_for_atomic((COND), (MS) * 1000)
+#define wait_for_atomic_us(COND, US)	_wait_for_atomic((COND), (US))
+
+#define KHz(x) (1000 * (x))
+#define MHz(x) KHz(1000 * (x))
+
+/*
+ * Display related stuff
+ */
+
+/* store information about an Ixxx DVO */
+/* The i830->i865 use multiple DVOs with multiple i2cs */
+/* the i915, i945 have a single sDVO i2c bus - which is different */
+#define MAX_OUTPUTS 6
+/* maximum connectors per crtcs in the mode set */
+
+/* Maximum cursor sizes */
+#define GEN2_CURSOR_WIDTH 64
+#define GEN2_CURSOR_HEIGHT 64
+#define MAX_CURSOR_WIDTH 256
+#define MAX_CURSOR_HEIGHT 256
+
+#define INTEL_I2C_BUS_DVO 1
+#define INTEL_I2C_BUS_SDVO 2
+
+/* these are outputs from the chip - integrated only
+   external chips are via DVO or SDVO output */
+enum intel_output_type {
+	INTEL_OUTPUT_UNUSED = 0,
+	INTEL_OUTPUT_ANALOG = 1,
+	INTEL_OUTPUT_DVO = 2,
+	INTEL_OUTPUT_SDVO = 3,
+	INTEL_OUTPUT_LVDS = 4,
+	INTEL_OUTPUT_TVOUT = 5,
+	INTEL_OUTPUT_HDMI = 6,
+	INTEL_OUTPUT_DISPLAYPORT = 7,
+	INTEL_OUTPUT_EDP = 8,
+	INTEL_OUTPUT_DSI = 9,
+	INTEL_OUTPUT_UNKNOWN = 10,
+	INTEL_OUTPUT_DP_MST = 11,
+};
+
+#define INTEL_DVO_CHIP_NONE 0
+#define INTEL_DVO_CHIP_LVDS 1
+#define INTEL_DVO_CHIP_TMDS 2
+#define INTEL_DVO_CHIP_TVOUT 4
+
+#define INTEL_DSI_VIDEO_MODE	0
+#define INTEL_DSI_COMMAND_MODE	1
+
+struct intel_framebuffer {
+	struct drm_framebuffer base;
+	struct drm_i915_gem_object *obj;
+	struct intel_rotation_info rot_info;
+};
+
+struct intel_fbdev {
+	struct drm_fb_helper helper;
+	struct intel_framebuffer *fb;
+	int preferred_bpp;
+};
+
+struct intel_encoder {
+	struct drm_encoder base;
+
+	enum intel_output_type type;
+	unsigned int cloneable;
+	void (*hot_plug)(struct intel_encoder *);
+	bool (*compute_config)(struct intel_encoder *,
+			       struct intel_crtc_state *);
+	void (*pre_pll_enable)(struct intel_encoder *);
+	void (*pre_enable)(struct intel_encoder *);
+	void (*enable)(struct intel_encoder *);
+	void (*mode_set)(struct intel_encoder *intel_encoder);
+	void (*disable)(struct intel_encoder *);
+	void (*post_disable)(struct intel_encoder *);
+	void (*post_pll_disable)(struct intel_encoder *);
+	/* Read out the current hw state of this connector, returning true if
+	 * the encoder is active. If the encoder is enabled it also set the pipe
+	 * it is connected to in the pipe parameter. */
+	bool (*get_hw_state)(struct intel_encoder *, enum pipe *pipe);
+	/* Reconstructs the equivalent mode flags for the current hardware
+	 * state. This must be called _after_ display->get_pipe_config has
+	 * pre-filled the pipe config. Note that intel_encoder->base.crtc must
+	 * be set correctly before calling this function. */
+	void (*get_config)(struct intel_encoder *,
+			   struct intel_crtc_state *pipe_config);
+	/*
+	 * Called during system suspend after all pending requests for the
+	 * encoder are flushed (for example for DP AUX transactions) and
+	 * device interrupts are disabled.
+	 */
+	void (*suspend)(struct intel_encoder *);
+	int crtc_mask;
+	enum hpd_pin hpd_pin;
+};
+
+struct intel_panel {
+	struct drm_display_mode *fixed_mode;
+	struct drm_display_mode *downclock_mode;
+	int fitting_mode;
+
+	/* backlight */
+	struct {
+		bool present;
+		u32 level;
+		u32 min;
+		u32 max;
+		bool enabled;
+		bool combination_mode;	/* gen 2/4 only */
+		bool active_low_pwm;
+		bool alternate_pwm_increment;	/* lpt+ */
+
+		/* PWM chip */
+		bool util_pin_active_low;	/* bxt+ */
+		u8 controller;		/* bxt+ only */
+		struct pwm_device *pwm;
+
+		struct backlight_device *device;
+
+		/* Connector and platform specific backlight functions */
+		int (*setup)(struct intel_connector *connector, enum pipe pipe);
+		uint32_t (*get)(struct intel_connector *connector);
+		void (*set)(struct intel_connector *connector, uint32_t level);
+		void (*disable)(struct intel_connector *connector);
+		void (*enable)(struct intel_connector *connector);
+		uint32_t (*hz_to_pwm)(struct intel_connector *connector,
+				      uint32_t hz);
+		void (*power)(struct intel_connector *, bool enable);
+	} backlight;
+};
+
+struct intel_connector {
+	struct drm_connector base;
+	/*
+	 * The fixed encoder this connector is connected to.
+	 */
+	struct intel_encoder *encoder;
+
+	/* Reads out the current hw, returning true if the connector is enabled
+	 * and active (i.e. dpms ON state). */
+	bool (*get_hw_state)(struct intel_connector *);
+
+	/*
+	 * Removes all interfaces through which the connector is accessible
+	 * - like sysfs, debugfs entries -, so that no new operations can be
+	 * started on the connector. Also makes sure all currently pending
+	 * operations finish before returing.
+	 */
+	void (*unregister)(struct intel_connector *);
+
+	/* Panel info for eDP and LVDS */
+	struct intel_panel panel;
+
+	/* Cached EDID for eDP and LVDS. May hold ERR_PTR for invalid EDID. */
+	struct edid *edid;
+	struct edid *detect_edid;
+
+	/* since POLL and HPD connectors may use the same HPD line keep the native
+	   state of connector->polled in case hotplug storm detection changes it */
+	u8 polled;
+
+	void *port; /* store this opaque as its illegal to dereference it */
+
+	struct intel_dp *mst_port;
+};
+
+typedef struct dpll {
+	/* given values */
+	int n;
+	int m1, m2;
+	int p1, p2;
+	/* derived values */
+	int	dot;
+	int	vco;
+	int	m;
+	int	p;
+} intel_clock_t;
+
+struct intel_atomic_state {
+	struct drm_atomic_state base;
+
+	unsigned int cdclk;
+
+	/*
+	 * Calculated device cdclk, can be different from cdclk
+	 * only when all crtc's are DPMS off.
+	 */
+	unsigned int dev_cdclk;
+
+	bool dpll_set, modeset;
+
+	unsigned int active_crtcs;
+	unsigned int min_pixclk[I915_MAX_PIPES];
+
+	struct intel_shared_dpll_config shared_dpll[I915_NUM_PLLS];
+	struct intel_wm_config wm_config;
+
+	/*
+	 * Current watermarks can't be trusted during hardware readout, so
+	 * don't bother calculating intermediate watermarks.
+	 */
+	bool skip_intermediate_wm;
+};
+
+struct intel_plane_state {
+	struct drm_plane_state base;
+	struct drm_rect src;
+	struct drm_rect dst;
+	struct drm_rect clip;
+	bool visible;
+
+	/*
+	 * scaler_id
+	 *    = -1 : not using a scaler
+	 *    >=  0 : using a scalers
+	 *
+	 * plane requiring a scaler:
+	 *   - During check_plane, its bit is set in
+	 *     crtc_state->scaler_state.scaler_users by calling helper function
+	 *     update_scaler_plane.
+	 *   - scaler_id indicates the scaler it got assigned.
+	 *
+	 * plane doesn't require a scaler:
+	 *   - this can happen when scaling is no more required or plane simply
+	 *     got disabled.
+	 *   - During check_plane, corresponding bit is reset in
+	 *     crtc_state->scaler_state.scaler_users by calling helper function
+	 *     update_scaler_plane.
+	 */
+	int scaler_id;
+
+	struct drm_intel_sprite_colorkey ckey;
+
+	/* async flip related structures */
+	struct drm_i915_gem_request *wait_req;
+};
+
+struct intel_initial_plane_config {
+	struct intel_framebuffer *fb;
+	unsigned int tiling;
+	int size;
+	u32 base;
+};
+
+#define SKL_MIN_SRC_W 8
+#define SKL_MAX_SRC_W 4096
+#define SKL_MIN_SRC_H 8
+#define SKL_MAX_SRC_H 4096
+#define SKL_MIN_DST_W 8
+#define SKL_MAX_DST_W 4096
+#define SKL_MIN_DST_H 8
+#define SKL_MAX_DST_H 4096
+
+struct intel_scaler {
+	int in_use;
+	uint32_t mode;
+};
+
+struct intel_crtc_scaler_state {
+#define SKL_NUM_SCALERS 2
+	struct intel_scaler scalers[SKL_NUM_SCALERS];
+
+	/*
+	 * scaler_users: keeps track of users requesting scalers on this crtc.
+	 *
+	 *     If a bit is set, a user is using a scaler.
+	 *     Here user can be a plane or crtc as defined below:
+	 *       bits 0-30 - plane (bit position is index from drm_plane_index)
+	 *       bit 31    - crtc
+	 *
+	 * Instead of creating a new index to cover planes and crtc, using
+	 * existing drm_plane_index for planes which is well less than 31
+	 * planes and bit 31 for crtc. This should be fine to cover all
+	 * our platforms.
+	 *
+	 * intel_atomic_setup_scalers will setup available scalers to users
+	 * requesting scalers. It will gracefully fail if request exceeds
+	 * avilability.
+	 */
+#define SKL_CRTC_INDEX 31
+	unsigned scaler_users;
+
+	/* scaler used by crtc for panel fitting purpose */
+	int scaler_id;
+};
+
+/* drm_mode->private_flags */
+#define I915_MODE_FLAG_INHERITED 1
+
+struct intel_pipe_wm {
+	struct intel_wm_level wm[5];
+	struct intel_wm_level raw_wm[5];
+	uint32_t linetime;
+	bool fbc_wm_enabled;
+	bool pipe_enabled;
+	bool sprites_enabled;
+	bool sprites_scaled;
+};
+
+struct skl_pipe_wm {
+	struct skl_wm_level wm[8];
+	struct skl_wm_level trans_wm;
+	uint32_t linetime;
+};
+
+struct intel_crtc_state {
+	struct drm_crtc_state base;
+
+	/**
+	 * quirks - bitfield with hw state readout quirks
+	 *
+	 * For various reasons the hw state readout code might not be able to
+	 * completely faithfully read out the current state. These cases are
+	 * tracked with quirk flags so that fastboot and state checker can act
+	 * accordingly.
+	 */
+#define PIPE_CONFIG_QUIRK_MODE_SYNC_FLAGS	(1<<0) /* unreliable sync mode.flags */
+	unsigned long quirks;
+
+	unsigned fb_bits; /* framebuffers to flip */
+	bool update_pipe; /* can a fast modeset be performed? */
+	bool disable_cxsr;
+	bool update_wm_pre, update_wm_post; /* watermarks are updated */
+	bool fb_changed; /* fb on any of the planes is changed */
+
+	/* Pipe source size (ie. panel fitter input size)
+	 * All planes will be positioned inside this space,
+	 * and get clipped at the edges. */
+	int pipe_src_w, pipe_src_h;
+
+	/* Whether to set up the PCH/FDI. Note that we never allow sharing
+	 * between pch encoders and cpu encoders. */
+	bool has_pch_encoder;
+
+	/* Are we sending infoframes on the attached port */
+	bool has_infoframe;
+
+	/* CPU Transcoder for the pipe. Currently this can only differ from the
+	 * pipe on Haswell and later (where we have a special eDP transcoder)
+	 * and Broxton (where we have special DSI transcoders). */
+	enum transcoder cpu_transcoder;
+
+	/*
+	 * Use reduced/limited/broadcast rbg range, compressing from the full
+	 * range fed into the crtcs.
+	 */
+	bool limited_color_range;
+
+	/* DP has a bunch of special case unfortunately, so mark the pipe
+	 * accordingly. */
+	bool has_dp_encoder;
+
+	/* DSI has special cases */
+	bool has_dsi_encoder;
+
+	/* Whether we should send NULL infoframes. Required for audio. */
+	bool has_hdmi_sink;
+
+	/* Audio enabled on this pipe. Only valid if either has_hdmi_sink or
+	 * has_dp_encoder is set. */
+	bool has_audio;
+
+	/*
+	 * Enable dithering, used when the selected pipe bpp doesn't match the
+	 * plane bpp.
+	 */
+	bool dither;
+
+	/* Controls for the clock computation, to override various stages. */
+	bool clock_set;
+
+	/* SDVO TV has a bunch of special case. To make multifunction encoders
+	 * work correctly, we need to track this at runtime.*/
+	bool sdvo_tv_clock;
+
+	/*
+	 * crtc bandwidth limit, don't increase pipe bpp or clock if not really
+	 * required. This is set in the 2nd loop of calling encoder's
+	 * ->compute_config if the first pick doesn't work out.
+	 */
+	bool bw_constrained;
+
+	/* Settings for the intel dpll used on pretty much everything but
+	 * haswell. */
+	struct dpll dpll;
+
+	/* Selected dpll when shared or NULL. */
+	struct intel_shared_dpll *shared_dpll;
+
+	/*
+	 * - PORT_CLK_SEL for DDI ports on HSW/BDW.
+	 * - enum skl_dpll on SKL
+	 */
+	uint32_t ddi_pll_sel;
+
+	/* Actual register state of the dpll, for shared dpll cross-checking. */
+	struct intel_dpll_hw_state dpll_hw_state;
+
+	/* DSI PLL registers */
+	struct {
+		u32 ctrl, div;
+	} dsi_pll;
+
+	int pipe_bpp;
+	struct intel_link_m_n dp_m_n;
+
+	/* m2_n2 for eDP downclock */
+	struct intel_link_m_n dp_m2_n2;
+	bool has_drrs;
+
+	/*
+	 * Frequence the dpll for the port should run at. Differs from the
+	 * adjusted dotclock e.g. for DP or 12bpc hdmi mode. This is also
+	 * already multiplied by pixel_multiplier.
+	 */
+	int port_clock;
+
+	/* Used by SDVO (and if we ever fix it, HDMI). */
+	unsigned pixel_multiplier;
+
+	uint8_t lane_count;
+
+	/* Panel fitter controls for gen2-gen4 + VLV */
+	struct {
+		u32 control;
+		u32 pgm_ratios;
+		u32 lvds_border_bits;
+	} gmch_pfit;
+
+	/* Panel fitter placement and size for Ironlake+ */
+	struct {
+		u32 pos;
+		u32 size;
+		bool enabled;
+		bool force_thru;
+	} pch_pfit;
+
+	/* FDI configuration, only valid if has_pch_encoder is set. */
+	int fdi_lanes;
+	struct intel_link_m_n fdi_m_n;
+
+	bool ips_enabled;
+
+	bool enable_fbc;
+
+	bool double_wide;
+
+	bool dp_encoder_is_mst;
+	int pbn;
+
+	struct intel_crtc_scaler_state scaler_state;
+
+	/* w/a for waiting 2 vblanks during crtc enable */
+	enum pipe hsw_workaround_pipe;
+
+	/* IVB sprite scaling w/a (WaCxSRDisabledForSpriteScaling:ivb) */
+	bool disable_lp_wm;
+
+	struct {
+		/*
+		 * Optimal watermarks, programmed post-vblank when this state
+		 * is committed.
+		 */
+		union {
+			struct intel_pipe_wm ilk;
+			struct skl_pipe_wm skl;
+		} optimal;
+
+		/*
+		 * Intermediate watermarks; these can be programmed immediately
+		 * since they satisfy both the current configuration we're
+		 * switching away from and the new configuration we're switching
+		 * to.
+		 */
+		struct intel_pipe_wm intermediate;
+
+		/*
+		 * Platforms with two-step watermark programming will need to
+		 * update watermark programming post-vblank to switch from the
+		 * safe intermediate watermarks to the optimal final
+		 * watermarks.
+		 */
+		bool need_postvbl_update;
+	} wm;
+
+	/* Gamma mode programmed on the pipe */
+	uint32_t gamma_mode;
+};
+
+struct vlv_wm_state {
+	struct vlv_pipe_wm wm[3];
+	struct vlv_sr_wm sr[3];
+	uint8_t num_active_planes;
+	uint8_t num_levels;
+	uint8_t level;
+	bool cxsr;
+};
+
+struct intel_mmio_flip {
+	struct work_struct work;
+	struct drm_i915_private *i915;
+	struct drm_i915_gem_request *req;
+	struct intel_crtc *crtc;
+	unsigned int rotation;
+};
+
+struct intel_crtc {
+	struct drm_crtc base;
+	enum pipe pipe;
+	enum plane plane;
+	u8 lut_r[256], lut_g[256], lut_b[256];
+	/*
+	 * Whether the crtc and the connected output pipeline is active. Implies
+	 * that crtc->enabled is set, i.e. the current mode configuration has
+	 * some outputs connected to this crtc.
+	 */
+	bool active;
+	unsigned long enabled_power_domains;
+	bool lowfreq_avail;
+	struct intel_overlay *overlay;
+	struct intel_unpin_work *unpin_work;
+
+	atomic_t unpin_work_count;
+
+	/* Display surface base address adjustement for pageflips. Note that on
+	 * gen4+ this only adjusts up to a tile, offsets within a tile are
+	 * handled in the hw itself (with the TILEOFF register). */
+	u32 dspaddr_offset;
+	int adjusted_x;
+	int adjusted_y;
+
+	uint32_t cursor_addr;
+	uint32_t cursor_cntl;
+	uint32_t cursor_size;
+	uint32_t cursor_base;
+
+	struct intel_crtc_state *config;
+
+	/* reset counter value when the last flip was submitted */
+	unsigned int reset_counter;
+
+	/* Access to these should be protected by dev_priv->irq_lock. */
+	bool cpu_fifo_underrun_disabled;
+	bool pch_fifo_underrun_disabled;
+
+	/* per-pipe watermark state */
+	struct {
+		/* watermarks currently being used  */
+		union {
+			struct intel_pipe_wm ilk;
+			struct skl_pipe_wm skl;
+		} active;
+
+		/* allow CxSR on this pipe */
+		bool cxsr_allowed;
+	} wm;
+
+	int scanline_offset;
+
+	struct {
+		unsigned start_vbl_count;
+		ktime_t start_vbl_time;
+		int min_vbl, max_vbl;
+		int scanline_start;
+	} debug;
+
+	/* scalers available on this crtc */
+	int num_scalers;
+
+	struct vlv_wm_state wm_state;
+};
+
+struct intel_plane_wm_parameters {
+	uint32_t horiz_pixels;
+	uint32_t vert_pixels;
+	/*
+	 *   For packed pixel formats:
+	 *     bytes_per_pixel - holds bytes per pixel
+	 *   For planar pixel formats:
+	 *     bytes_per_pixel - holds bytes per pixel for uv-plane
+	 *     y_bytes_per_pixel - holds bytes per pixel for y-plane
+	 */
+	uint8_t bytes_per_pixel;
+	uint8_t y_bytes_per_pixel;
+	bool enabled;
+	bool scaled;
+	u64 tiling;
+	unsigned int rotation;
+	uint16_t fifo_size;
+};
+
+struct intel_plane {
+	struct drm_plane base;
+	int plane;
+	enum pipe pipe;
+	bool can_scale;
+	int max_downscale;
+	uint32_t frontbuffer_bit;
+
+	/* Since we need to change the watermarks before/after
+	 * enabling/disabling the planes, we need to store the parameters here
+	 * as the other pieces of the struct may not reflect the values we want
+	 * for the watermark calculations. Currently only Haswell uses this.
+	 */
+	struct intel_plane_wm_parameters wm;
+
+	/*
+	 * NOTE: Do not place new plane state fields here (e.g., when adding
+	 * new plane properties).  New runtime state should now be placed in
+	 * the intel_plane_state structure and accessed via plane_state.
+	 */
+
+	void (*update_plane)(struct drm_plane *plane,
+			     const struct intel_crtc_state *crtc_state,
+			     const struct intel_plane_state *plane_state);
+	void (*disable_plane)(struct drm_plane *plane,
+			      struct drm_crtc *crtc);
+	int (*check_plane)(struct drm_plane *plane,
+			   struct intel_crtc_state *crtc_state,
+			   struct intel_plane_state *state);
+};
+
+struct intel_watermark_params {
+	unsigned long fifo_size;
+	unsigned long max_wm;
+	unsigned long default_wm;
+	unsigned long guard_size;
+	unsigned long cacheline_size;
+};
+
+struct cxsr_latency {
+	int is_desktop;
+	int is_ddr3;
+	unsigned long fsb_freq;
+	unsigned long mem_freq;
+	unsigned long display_sr;
+	unsigned long display_hpll_disable;
+	unsigned long cursor_sr;
+	unsigned long cursor_hpll_disable;
+};
+
+#define to_intel_atomic_state(x) container_of(x, struct intel_atomic_state, base)
+#define to_intel_crtc(x) container_of(x, struct intel_crtc, base)
+#define to_intel_crtc_state(x) container_of(x, struct intel_crtc_state, base)
+#define to_intel_connector(x) container_of(x, struct intel_connector, base)
+#define to_intel_encoder(x) container_of(x, struct intel_encoder, base)
+#define to_intel_framebuffer(x) container_of(x, struct intel_framebuffer, base)
+#define to_intel_plane(x) container_of(x, struct intel_plane, base)
+#define to_intel_plane_state(x) container_of(x, struct intel_plane_state, base)
+#define intel_fb_obj(x) (x ? to_intel_framebuffer(x)->obj : NULL)
+
+struct intel_hdmi {
+	i915_reg_t hdmi_reg;
+	int ddc_bus;
+	struct {
+		enum drm_dp_dual_mode_type type;
+		int max_tmds_clock;
+	} dp_dual_mode;
+	bool limited_color_range;
+	bool color_range_auto;
+	bool has_hdmi_sink;
+	bool has_audio;
+	enum hdmi_force_audio force_audio;
+	bool rgb_quant_range_selectable;
+	enum hdmi_picture_aspect aspect_ratio;
+	struct intel_connector *attached_connector;
+	void (*write_infoframe)(struct drm_encoder *encoder,
+				enum hdmi_infoframe_type type,
+				const void *frame, ssize_t len);
+	void (*set_infoframes)(struct drm_encoder *encoder,
+			       bool enable,
+			       const struct drm_display_mode *adjusted_mode);
+	bool (*infoframe_enabled)(struct drm_encoder *encoder,
+				  const struct intel_crtc_state *pipe_config);
+};
+
+struct intel_dp_mst_encoder;
+#define DP_MAX_DOWNSTREAM_PORTS		0x10
+
+/*
+ * enum link_m_n_set:
+ *	When platform provides two set of M_N registers for dp, we can
+ *	program them and switch between them incase of DRRS.
+ *	But When only one such register is provided, we have to program the
+ *	required divider value on that registers itself based on the DRRS state.
+ *
+ * M1_N1	: Program dp_m_n on M1_N1 registers
+ *			  dp_m2_n2 on M2_N2 registers (If supported)
+ *
+ * M2_N2	: Program dp_m2_n2 on M1_N1 registers
+ *			  M2_N2 registers are not supported
+ */
+
+enum link_m_n_set {
+	/* Sets the m1_n1 and m2_n2 */
+	M1_N1 = 0,
+	M2_N2
+};
+
+struct intel_dp {
+	i915_reg_t output_reg;
+	i915_reg_t aux_ch_ctl_reg;
+	i915_reg_t aux_ch_data_reg[5];
+	uint32_t DP;
+	int link_rate;
+	uint8_t lane_count;
+	uint8_t sink_count;
+	bool has_audio;
+	bool detect_done;
+	enum hdmi_force_audio force_audio;
+	bool limited_color_range;
+	bool color_range_auto;
+	uint8_t dpcd[DP_RECEIVER_CAP_SIZE];
+	uint8_t psr_dpcd[EDP_PSR_RECEIVER_CAP_SIZE];
+	uint8_t downstream_ports[DP_MAX_DOWNSTREAM_PORTS];
+	/* sink rates as reported by DP_SUPPORTED_LINK_RATES */
+	uint8_t num_sink_rates;
+	int sink_rates[DP_MAX_SUPPORTED_RATES];
+	struct drm_dp_aux aux;
+	uint8_t train_set[4];
+	int panel_power_up_delay;
+	int panel_power_down_delay;
+	int panel_power_cycle_delay;
+	int backlight_on_delay;
+	int backlight_off_delay;
+	struct delayed_work panel_vdd_work;
+	bool want_panel_vdd;
+	unsigned long last_power_on;
+	unsigned long last_backlight_off;
+	ktime_t panel_power_off_time;
+
+	struct notifier_block edp_notifier;
+
+	/*
+	 * Pipe whose power sequencer is currently locked into
+	 * this port. Only relevant on VLV/CHV.
+	 */
+	enum pipe pps_pipe;
+	struct edp_power_seq pps_delays;
+
+	bool can_mst; /* this port supports mst */
+	bool is_mst;
+	int active_mst_links;
+	/* connector directly attached - won't be use for modeset in mst world */
+	struct intel_connector *attached_connector;
+
+	/* mst connector list */
+	struct intel_dp_mst_encoder *mst_encoders[I915_MAX_PIPES];
+	struct drm_dp_mst_topology_mgr mst_mgr;
+
+	uint32_t (*get_aux_clock_divider)(struct intel_dp *dp, int index);
+	/*
+	 * This function returns the value we have to program the AUX_CTL
+	 * register with to kick off an AUX transaction.
+	 */
+	uint32_t (*get_aux_send_ctl)(struct intel_dp *dp,
+				     bool has_aux_irq,
+				     int send_bytes,
+				     uint32_t aux_clock_divider);
+
+	/* This is called before a link training is starterd */
+	void (*prepare_link_retrain)(struct intel_dp *intel_dp);
+
+	/* Displayport compliance testing */
+	unsigned long compliance_test_type;
+	unsigned long compliance_test_data;
+	bool compliance_test_active;
+};
+
+struct intel_digital_port {
+	struct intel_encoder base;
+	enum port port;
+	u32 saved_port_bits;
+	struct intel_dp dp;
+	struct intel_hdmi hdmi;
+	enum irqreturn (*hpd_pulse)(struct intel_digital_port *, bool);
+	bool release_cl2_override;
+	uint8_t max_lanes;
+	/* for communication with audio component; protected by av_mutex */
+	const struct drm_connector *audio_connector;
+};
+
+struct intel_dp_mst_encoder {
+	struct intel_encoder base;
+	enum pipe pipe;
+	struct intel_digital_port *primary;
+	void *port; /* store this opaque as its illegal to dereference it */
+};
+
+static inline enum dpio_channel
+vlv_dport_to_channel(struct intel_digital_port *dport)
+{
+	switch (dport->port) {
+	case PORT_B:
+	case PORT_D:
+		return DPIO_CH0;
+	case PORT_C:
+		return DPIO_CH1;
+	default:
+		BUG();
+	}
+}
+
+static inline enum dpio_phy
+vlv_dport_to_phy(struct intel_digital_port *dport)
+{
+	switch (dport->port) {
+	case PORT_B:
+	case PORT_C:
+		return DPIO_PHY0;
+	case PORT_D:
+		return DPIO_PHY1;
+	default:
+		BUG();
+	}
+}
+
+static inline enum dpio_channel
+vlv_pipe_to_channel(enum pipe pipe)
+{
+	switch (pipe) {
+	case PIPE_A:
+	case PIPE_C:
+		return DPIO_CH0;
+	case PIPE_B:
+		return DPIO_CH1;
+	default:
+		BUG();
+	}
+}
+
+static inline struct drm_crtc *
+intel_get_crtc_for_pipe(struct drm_device *dev, int pipe)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	return dev_priv->pipe_to_crtc_mapping[pipe];
+}
+
+static inline struct drm_crtc *
+intel_get_crtc_for_plane(struct drm_device *dev, int plane)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	return dev_priv->plane_to_crtc_mapping[plane];
+}
+
+struct intel_unpin_work {
+	struct work_struct work;
+	struct drm_crtc *crtc;
+	struct drm_framebuffer *old_fb;
+	struct drm_i915_gem_object *pending_flip_obj;
+	struct drm_pending_vblank_event *event;
+	atomic_t pending;
+#define INTEL_FLIP_INACTIVE	0
+#define INTEL_FLIP_PENDING	1
+#define INTEL_FLIP_COMPLETE	2
+	u32 flip_count;
+	u32 gtt_offset;
+	struct drm_i915_gem_request *flip_queued_req;
+	u32 flip_queued_vblank;
+	u32 flip_ready_vblank;
+	bool enable_stall_check;
+};
+
+struct intel_load_detect_pipe {
+	struct drm_atomic_state *restore_state;
+};
+
+static inline struct intel_encoder *
+intel_attached_encoder(struct drm_connector *connector)
+{
+	return to_intel_connector(connector)->encoder;
+}
+
+static inline struct intel_digital_port *
+enc_to_dig_port(struct drm_encoder *encoder)
+{
+	return container_of(encoder, struct intel_digital_port, base.base);
+}
+
+static inline struct intel_dp_mst_encoder *
+enc_to_mst(struct drm_encoder *encoder)
+{
+	return container_of(encoder, struct intel_dp_mst_encoder, base.base);
+}
+
+static inline struct intel_dp *enc_to_intel_dp(struct drm_encoder *encoder)
+{
+	return &enc_to_dig_port(encoder)->dp;
+}
+
+static inline struct intel_digital_port *
+dp_to_dig_port(struct intel_dp *intel_dp)
+{
+	return container_of(intel_dp, struct intel_digital_port, dp);
+}
+
+static inline struct intel_digital_port *
+hdmi_to_dig_port(struct intel_hdmi *intel_hdmi)
+{
+	return container_of(intel_hdmi, struct intel_digital_port, hdmi);
+}
+
+/*
+ * Returns the number of planes for this pipe, ie the number of sprites + 1
+ * (primary plane). This doesn't count the cursor plane then.
+ */
+static inline unsigned int intel_num_planes(struct intel_crtc *crtc)
+{
+	return INTEL_INFO(crtc->base.dev)->num_sprites[crtc->pipe] + 1;
+}
+
+/* intel_fifo_underrun.c */
+bool intel_set_cpu_fifo_underrun_reporting(struct drm_i915_private *dev_priv,
+					   enum pipe pipe, bool enable);
+bool intel_set_pch_fifo_underrun_reporting(struct drm_i915_private *dev_priv,
+					   enum transcoder pch_transcoder,
+					   bool enable);
+void intel_cpu_fifo_underrun_irq_handler(struct drm_i915_private *dev_priv,
+					 enum pipe pipe);
+void intel_pch_fifo_underrun_irq_handler(struct drm_i915_private *dev_priv,
+					 enum transcoder pch_transcoder);
+void intel_check_cpu_fifo_underruns(struct drm_i915_private *dev_priv);
+void intel_check_pch_fifo_underruns(struct drm_i915_private *dev_priv);
+
+/* i915_irq.c */
+void gen5_enable_gt_irq(struct drm_i915_private *dev_priv, uint32_t mask);
+void gen5_disable_gt_irq(struct drm_i915_private *dev_priv, uint32_t mask);
+void gen6_enable_pm_irq(struct drm_i915_private *dev_priv, uint32_t mask);
+void gen6_disable_pm_irq(struct drm_i915_private *dev_priv, uint32_t mask);
+void gen6_reset_rps_interrupts(struct drm_device *dev);
+void gen6_enable_rps_interrupts(struct drm_device *dev);
+void gen6_disable_rps_interrupts(struct drm_device *dev);
+u32 gen6_sanitize_rps_pm_mask(struct drm_i915_private *dev_priv, u32 mask);
+void intel_runtime_pm_disable_interrupts(struct drm_i915_private *dev_priv);
+void intel_runtime_pm_enable_interrupts(struct drm_i915_private *dev_priv);
+static inline bool intel_irqs_enabled(struct drm_i915_private *dev_priv)
+{
+	/*
+	 * We only use drm_irq_uninstall() at unload and VT switch, so
+	 * this is the only thing we need to check.
+	 */
+	return dev_priv->pm.irqs_enabled;
+}
+
+int intel_get_crtc_scanline(struct intel_crtc *crtc);
+void gen8_irq_power_well_post_enable(struct drm_i915_private *dev_priv,
+				     unsigned int pipe_mask);
+void gen8_irq_power_well_pre_disable(struct drm_i915_private *dev_priv,
+				     unsigned int pipe_mask);
+
+/* intel_crt.c */
+void intel_crt_init(struct drm_device *dev);
+
+
+/* intel_ddi.c */
+void intel_ddi_clk_select(struct intel_encoder *encoder,
+			  const struct intel_crtc_state *pipe_config);
+void intel_prepare_ddi_buffer(struct intel_encoder *encoder);
+void hsw_fdi_link_train(struct drm_crtc *crtc);
+void intel_ddi_init(struct drm_device *dev, enum port port);
+enum port intel_ddi_get_encoder_port(struct intel_encoder *intel_encoder);
+bool intel_ddi_get_hw_state(struct intel_encoder *encoder, enum pipe *pipe);
+void intel_ddi_enable_transcoder_func(struct drm_crtc *crtc);
+void intel_ddi_disable_transcoder_func(struct drm_i915_private *dev_priv,
+				       enum transcoder cpu_transcoder);
+void intel_ddi_enable_pipe_clock(struct intel_crtc *intel_crtc);
+void intel_ddi_disable_pipe_clock(struct intel_crtc *intel_crtc);
+bool intel_ddi_pll_select(struct intel_crtc *crtc,
+			  struct intel_crtc_state *crtc_state);
+void intel_ddi_set_pipe_settings(struct drm_crtc *crtc);
+void intel_ddi_prepare_link_retrain(struct intel_dp *intel_dp);
+bool intel_ddi_connector_get_hw_state(struct intel_connector *intel_connector);
+void intel_ddi_fdi_disable(struct drm_crtc *crtc);
+void intel_ddi_get_config(struct intel_encoder *encoder,
+			  struct intel_crtc_state *pipe_config);
+struct intel_encoder *
+intel_ddi_get_crtc_new_encoder(struct intel_crtc_state *crtc_state);
+
+void intel_ddi_init_dp_buf_reg(struct intel_encoder *encoder);
+void intel_ddi_clock_get(struct intel_encoder *encoder,
+			 struct intel_crtc_state *pipe_config);
+void intel_ddi_set_vc_payload_alloc(struct drm_crtc *crtc, bool state);
+uint32_t ddi_signal_levels(struct intel_dp *intel_dp);
+
+/* intel_frontbuffer.c */
+void intel_fb_obj_invalidate(struct drm_i915_gem_object *obj,
+			     enum fb_op_origin origin);
+void intel_frontbuffer_flip_prepare(struct drm_device *dev,
+				    unsigned frontbuffer_bits);
+void intel_frontbuffer_flip_complete(struct drm_device *dev,
+				     unsigned frontbuffer_bits);
+void intel_frontbuffer_flip(struct drm_device *dev,
+			    unsigned frontbuffer_bits);
+unsigned int intel_fb_align_height(struct drm_device *dev,
+				   unsigned int height,
+				   uint32_t pixel_format,
+				   uint64_t fb_format_modifier);
+void intel_fb_obj_flush(struct drm_i915_gem_object *obj, bool retire,
+			enum fb_op_origin origin);
+u32 intel_fb_stride_alignment(const struct drm_i915_private *dev_priv,
+			      uint64_t fb_modifier, uint32_t pixel_format);
+
+/* intel_audio.c */
+void intel_init_audio_hooks(struct drm_i915_private *dev_priv);
+void intel_audio_codec_enable(struct intel_encoder *encoder);
+void intel_audio_codec_disable(struct intel_encoder *encoder);
+void i915_audio_component_init(struct drm_i915_private *dev_priv);
+void i915_audio_component_cleanup(struct drm_i915_private *dev_priv);
+
+/* intel_display.c */
+int vlv_get_cck_clock(struct drm_i915_private *dev_priv,
+		      const char *name, u32 reg, int ref_freq);
+extern const struct drm_plane_funcs intel_plane_funcs;
+void intel_init_display_hooks(struct drm_i915_private *dev_priv);
+unsigned int intel_rotation_info_size(const struct intel_rotation_info *rot_info);
+bool intel_has_pending_fb_unpin(struct drm_device *dev);
+void intel_mark_busy(struct drm_device *dev);
+void intel_mark_idle(struct drm_device *dev);
+void intel_crtc_restore_mode(struct drm_crtc *crtc);
+int intel_display_suspend(struct drm_device *dev);
+void intel_encoder_destroy(struct drm_encoder *encoder);
+int intel_connector_init(struct intel_connector *);
+struct intel_connector *intel_connector_alloc(void);
+bool intel_connector_get_hw_state(struct intel_connector *connector);
+void intel_connector_attach_encoder(struct intel_connector *connector,
+				    struct intel_encoder *encoder);
+struct drm_encoder *intel_best_encoder(struct drm_connector *connector);
+struct drm_display_mode *intel_crtc_mode_get(struct drm_device *dev,
+					     struct drm_crtc *crtc);
+enum pipe intel_get_pipe_from_connector(struct intel_connector *connector);
+int intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data,
+				struct drm_file *file_priv);
+enum transcoder intel_pipe_to_cpu_transcoder(struct drm_i915_private *dev_priv,
+					     enum pipe pipe);
+bool intel_pipe_has_type(struct intel_crtc *crtc, enum intel_output_type type);
+static inline void
+intel_wait_for_vblank(struct drm_device *dev, int pipe)
+{
+	drm_wait_one_vblank(dev, pipe);
+}
+static inline void
+intel_wait_for_vblank_if_active(struct drm_device *dev, int pipe)
+{
+	const struct intel_crtc *crtc =
+		to_intel_crtc(intel_get_crtc_for_pipe(dev, pipe));
+
+	if (crtc->active)
+		intel_wait_for_vblank(dev, pipe);
+}
+int ironlake_get_lanes_required(int target_clock, int link_bw, int bpp);
+void vlv_wait_port_ready(struct drm_i915_private *dev_priv,
+			 struct intel_digital_port *dport,
+			 unsigned int expected_mask);
+bool intel_get_load_detect_pipe(struct drm_connector *connector,
+				struct drm_display_mode *mode,
+				struct intel_load_detect_pipe *old,
+				struct drm_modeset_acquire_ctx *ctx);
+void intel_release_load_detect_pipe(struct drm_connector *connector,
+				    struct intel_load_detect_pipe *old,
+				    struct drm_modeset_acquire_ctx *ctx);
+int intel_pin_and_fence_fb_obj(struct drm_framebuffer *fb,
+			       unsigned int rotation);
+struct drm_framebuffer *
+__intel_framebuffer_create(struct drm_device *dev,
+			   struct drm_mode_fb_cmd2 *mode_cmd,
+			   struct drm_i915_gem_object *obj);
+void intel_prepare_page_flip(struct drm_device *dev, int plane);
+void intel_finish_page_flip(struct drm_device *dev, int pipe);
+void intel_finish_page_flip_plane(struct drm_device *dev, int plane);
+void intel_check_page_flip(struct drm_device *dev, int pipe);
+int intel_prepare_plane_fb(struct drm_plane *plane,
+			   const struct drm_plane_state *new_state);
+void intel_cleanup_plane_fb(struct drm_plane *plane,
+			    const struct drm_plane_state *old_state);
+int intel_plane_atomic_get_property(struct drm_plane *plane,
+				    const struct drm_plane_state *state,
+				    struct drm_property *property,
+				    uint64_t *val);
+int intel_plane_atomic_set_property(struct drm_plane *plane,
+				    struct drm_plane_state *state,
+				    struct drm_property *property,
+				    uint64_t val);
+int intel_plane_atomic_calc_changes(struct drm_crtc_state *crtc_state,
+				    struct drm_plane_state *plane_state);
+
+unsigned int intel_tile_height(const struct drm_i915_private *dev_priv,
+			       uint64_t fb_modifier, unsigned int cpp);
+
+static inline bool
+intel_rotation_90_or_270(unsigned int rotation)
+{
+	return rotation & (BIT(DRM_ROTATE_90) | BIT(DRM_ROTATE_270));
+}
+
+void intel_create_rotation_property(struct drm_device *dev,
+					struct intel_plane *plane);
+
+void assert_pch_transcoder_disabled(struct drm_i915_private *dev_priv,
+				    enum pipe pipe);
+
+int vlv_force_pll_on(struct drm_device *dev, enum pipe pipe,
+		     const struct dpll *dpll);
+void vlv_force_pll_off(struct drm_device *dev, enum pipe pipe);
+int lpt_get_iclkip(struct drm_i915_private *dev_priv);
+
+/* modesetting asserts */
+void assert_panel_unlocked(struct drm_i915_private *dev_priv,
+			   enum pipe pipe);
+void assert_pll(struct drm_i915_private *dev_priv,
+		enum pipe pipe, bool state);
+#define assert_pll_enabled(d, p) assert_pll(d, p, true)
+#define assert_pll_disabled(d, p) assert_pll(d, p, false)
+void assert_dsi_pll(struct drm_i915_private *dev_priv, bool state);
+#define assert_dsi_pll_enabled(d) assert_dsi_pll(d, true)
+#define assert_dsi_pll_disabled(d) assert_dsi_pll(d, false)
+void assert_fdi_rx_pll(struct drm_i915_private *dev_priv,
+		       enum pipe pipe, bool state);
+#define assert_fdi_rx_pll_enabled(d, p) assert_fdi_rx_pll(d, p, true)
+#define assert_fdi_rx_pll_disabled(d, p) assert_fdi_rx_pll(d, p, false)
+void assert_pipe(struct drm_i915_private *dev_priv, enum pipe pipe, bool state);
+#define assert_pipe_enabled(d, p) assert_pipe(d, p, true)
+#define assert_pipe_disabled(d, p) assert_pipe(d, p, false)
+u32 intel_compute_tile_offset(int *x, int *y,
+			      const struct drm_framebuffer *fb, int plane,
+			      unsigned int pitch,
+			      unsigned int rotation);
+void intel_prepare_reset(struct drm_device *dev);
+void intel_finish_reset(struct drm_device *dev);
+void hsw_enable_pc8(struct drm_i915_private *dev_priv);
+void hsw_disable_pc8(struct drm_i915_private *dev_priv);
+void broxton_init_cdclk(struct drm_i915_private *dev_priv);
+void broxton_uninit_cdclk(struct drm_i915_private *dev_priv);
+bool broxton_cdclk_verify_state(struct drm_i915_private *dev_priv);
+void broxton_ddi_phy_init(struct drm_i915_private *dev_priv);
+void broxton_ddi_phy_uninit(struct drm_i915_private *dev_priv);
+void broxton_ddi_phy_verify_state(struct drm_i915_private *dev_priv);
+void gen9_sanitize_dc_state(struct drm_i915_private *dev_priv);
+void bxt_enable_dc9(struct drm_i915_private *dev_priv);
+void bxt_disable_dc9(struct drm_i915_private *dev_priv);
+void gen9_enable_dc5(struct drm_i915_private *dev_priv);
+void skl_init_cdclk(struct drm_i915_private *dev_priv);
+int skl_sanitize_cdclk(struct drm_i915_private *dev_priv);
+void skl_uninit_cdclk(struct drm_i915_private *dev_priv);
+void skl_enable_dc6(struct drm_i915_private *dev_priv);
+void skl_disable_dc6(struct drm_i915_private *dev_priv);
+void intel_dp_get_m_n(struct intel_crtc *crtc,
+		      struct intel_crtc_state *pipe_config);
+void intel_dp_set_m_n(struct intel_crtc *crtc, enum link_m_n_set m_n);
+int intel_dotclock_calculate(int link_freq, const struct intel_link_m_n *m_n);
+bool bxt_find_best_dpll(struct intel_crtc_state *crtc_state, int target_clock,
+			intel_clock_t *best_clock);
+int chv_calc_dpll_params(int refclk, intel_clock_t *pll_clock);
+
+bool intel_crtc_active(struct drm_crtc *crtc);
+void hsw_enable_ips(struct intel_crtc *crtc);
+void hsw_disable_ips(struct intel_crtc *crtc);
+enum intel_display_power_domain
+intel_display_port_power_domain(struct intel_encoder *intel_encoder);
+enum intel_display_power_domain
+intel_display_port_aux_power_domain(struct intel_encoder *intel_encoder);
+void intel_mode_from_pipe_config(struct drm_display_mode *mode,
+				 struct intel_crtc_state *pipe_config);
+
+int skl_update_scaler_crtc(struct intel_crtc_state *crtc_state);
+int skl_max_scale(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state);
+
+u32 intel_plane_obj_offset(struct intel_plane *intel_plane,
+			   struct drm_i915_gem_object *obj,
+			   unsigned int plane);
+
+u32 skl_plane_ctl_format(uint32_t pixel_format);
+u32 skl_plane_ctl_tiling(uint64_t fb_modifier);
+u32 skl_plane_ctl_rotation(unsigned int rotation);
+
+/* intel_csr.c */
+void intel_csr_ucode_init(struct drm_i915_private *);
+void intel_csr_load_program(struct drm_i915_private *);
+void intel_csr_ucode_fini(struct drm_i915_private *);
+void intel_csr_ucode_suspend(struct drm_i915_private *);
+void intel_csr_ucode_resume(struct drm_i915_private *);
+
+/* intel_dp.c */
+bool intel_dp_init(struct drm_device *dev, i915_reg_t output_reg, enum port port);
+bool intel_dp_init_connector(struct intel_digital_port *intel_dig_port,
+			     struct intel_connector *intel_connector);
+void intel_dp_set_link_params(struct intel_dp *intel_dp,
+			      const struct intel_crtc_state *pipe_config);
+void intel_dp_start_link_train(struct intel_dp *intel_dp);
+void intel_dp_stop_link_train(struct intel_dp *intel_dp);
+void intel_dp_sink_dpms(struct intel_dp *intel_dp, int mode);
+void intel_dp_encoder_reset(struct drm_encoder *encoder);
+void intel_dp_encoder_suspend(struct intel_encoder *intel_encoder);
+void intel_dp_encoder_destroy(struct drm_encoder *encoder);
+int intel_dp_sink_crc(struct intel_dp *intel_dp, u8 *crc);
+bool intel_dp_compute_config(struct intel_encoder *encoder,
+			     struct intel_crtc_state *pipe_config);
+bool intel_dp_is_edp(struct drm_device *dev, enum port port);
+enum irqreturn intel_dp_hpd_pulse(struct intel_digital_port *intel_dig_port,
+				  bool long_hpd);
+void intel_edp_backlight_on(struct intel_dp *intel_dp);
+void intel_edp_backlight_off(struct intel_dp *intel_dp);
+void intel_edp_panel_vdd_on(struct intel_dp *intel_dp);
+void intel_edp_panel_on(struct intel_dp *intel_dp);
+void intel_edp_panel_off(struct intel_dp *intel_dp);
+void intel_dp_add_properties(struct intel_dp *intel_dp, struct drm_connector *connector);
+void intel_dp_mst_suspend(struct drm_device *dev);
+void intel_dp_mst_resume(struct drm_device *dev);
+int intel_dp_max_link_rate(struct intel_dp *intel_dp);
+int intel_dp_rate_select(struct intel_dp *intel_dp, int rate);
+void intel_dp_hot_plug(struct intel_encoder *intel_encoder);
+void vlv_power_sequencer_reset(struct drm_i915_private *dev_priv);
+uint32_t intel_dp_pack_aux(const uint8_t *src, int src_bytes);
+void intel_plane_destroy(struct drm_plane *plane);
+void intel_edp_drrs_enable(struct intel_dp *intel_dp);
+void intel_edp_drrs_disable(struct intel_dp *intel_dp);
+void intel_edp_drrs_invalidate(struct drm_device *dev,
+		unsigned frontbuffer_bits);
+void intel_edp_drrs_flush(struct drm_device *dev, unsigned frontbuffer_bits);
+bool intel_digital_port_connected(struct drm_i915_private *dev_priv,
+					 struct intel_digital_port *port);
+
+void
+intel_dp_program_link_training_pattern(struct intel_dp *intel_dp,
+				       uint8_t dp_train_pat);
+void
+intel_dp_set_signal_levels(struct intel_dp *intel_dp);
+void intel_dp_set_idle_link_train(struct intel_dp *intel_dp);
+uint8_t
+intel_dp_voltage_max(struct intel_dp *intel_dp);
+uint8_t
+intel_dp_pre_emphasis_max(struct intel_dp *intel_dp, uint8_t voltage_swing);
+void intel_dp_compute_rate(struct intel_dp *intel_dp, int port_clock,
+			   uint8_t *link_bw, uint8_t *rate_select);
+bool intel_dp_source_supports_hbr2(struct intel_dp *intel_dp);
+bool
+intel_dp_get_link_status(struct intel_dp *intel_dp, uint8_t link_status[DP_LINK_STATUS_SIZE]);
+
+/* intel_dp_mst.c */
+int intel_dp_mst_encoder_init(struct intel_digital_port *intel_dig_port, int conn_id);
+void intel_dp_mst_encoder_cleanup(struct intel_digital_port *intel_dig_port);
+/* intel_dsi.c */
+void intel_dsi_init(struct drm_device *dev);
+
+
+/* intel_dvo.c */
+void intel_dvo_init(struct drm_device *dev);
+
+
+/* legacy fbdev emulation in intel_fbdev.c */
+#ifdef CONFIG_DRM_FBDEV_EMULATION
+extern int intel_fbdev_init(struct drm_device *dev);
+extern void intel_fbdev_initial_config_async(struct drm_device *dev);
+extern void intel_fbdev_fini(struct drm_device *dev);
+extern void intel_fbdev_set_suspend(struct drm_device *dev, int state, bool synchronous);
+extern void intel_fbdev_output_poll_changed(struct drm_device *dev);
+extern void intel_fbdev_restore_mode(struct drm_device *dev);
+#else
+static inline int intel_fbdev_init(struct drm_device *dev)
+{
+	return 0;
+}
+
+static inline void intel_fbdev_initial_config_async(struct drm_device *dev)
+{
+}
+
+static inline void intel_fbdev_fini(struct drm_device *dev)
+{
+}
+
+static inline void intel_fbdev_set_suspend(struct drm_device *dev, int state, bool synchronous)
+{
+}
+
+static inline void intel_fbdev_restore_mode(struct drm_device *dev)
+{
+}
+#endif
+
+/* intel_fbc.c */
+void intel_fbc_choose_crtc(struct drm_i915_private *dev_priv,
+			   struct drm_atomic_state *state);
+bool intel_fbc_is_active(struct drm_i915_private *dev_priv);
+void intel_fbc_pre_update(struct intel_crtc *crtc);
+void intel_fbc_post_update(struct intel_crtc *crtc);
+void intel_fbc_init(struct drm_i915_private *dev_priv);
+void intel_fbc_init_pipe_state(struct drm_i915_private *dev_priv);
+void intel_fbc_enable(struct intel_crtc *crtc);
+void intel_fbc_disable(struct intel_crtc *crtc);
+void intel_fbc_global_disable(struct drm_i915_private *dev_priv);
+void intel_fbc_invalidate(struct drm_i915_private *dev_priv,
+			  unsigned int frontbuffer_bits,
+			  enum fb_op_origin origin);
+void intel_fbc_flush(struct drm_i915_private *dev_priv,
+		     unsigned int frontbuffer_bits, enum fb_op_origin origin);
+void intel_fbc_cleanup_cfb(struct drm_i915_private *dev_priv);
+
+/* intel_hdmi.c */
+void intel_hdmi_init(struct drm_device *dev, i915_reg_t hdmi_reg, enum port port);
+void intel_hdmi_init_connector(struct intel_digital_port *intel_dig_port,
+			       struct intel_connector *intel_connector);
+struct intel_hdmi *enc_to_intel_hdmi(struct drm_encoder *encoder);
+bool intel_hdmi_compute_config(struct intel_encoder *encoder,
+			       struct intel_crtc_state *pipe_config);
+void intel_dp_dual_mode_set_tmds_output(struct intel_hdmi *hdmi, bool enable);
+
+
+/* intel_lvds.c */
+void intel_lvds_init(struct drm_device *dev);
+bool intel_is_dual_link_lvds(struct drm_device *dev);
+
+
+/* intel_modes.c */
+int intel_connector_update_modes(struct drm_connector *connector,
+				 struct edid *edid);
+int intel_ddc_get_modes(struct drm_connector *c, struct i2c_adapter *adapter);
+void intel_attach_force_audio_property(struct drm_connector *connector);
+void intel_attach_broadcast_rgb_property(struct drm_connector *connector);
+void intel_attach_aspect_ratio_property(struct drm_connector *connector);
+
+
+/* intel_overlay.c */
+void intel_setup_overlay(struct drm_device *dev);
+void intel_cleanup_overlay(struct drm_device *dev);
+int intel_overlay_switch_off(struct intel_overlay *overlay);
+int intel_overlay_put_image(struct drm_device *dev, void *data,
+			    struct drm_file *file_priv);
+int intel_overlay_attrs(struct drm_device *dev, void *data,
+			struct drm_file *file_priv);
+void intel_overlay_reset(struct drm_i915_private *dev_priv);
+
+
+/* intel_panel.c */
+int intel_panel_init(struct intel_panel *panel,
+		     struct drm_display_mode *fixed_mode,
+		     struct drm_display_mode *downclock_mode);
+void intel_panel_fini(struct intel_panel *panel);
+void intel_fixed_panel_mode(const struct drm_display_mode *fixed_mode,
+			    struct drm_display_mode *adjusted_mode);
+void intel_pch_panel_fitting(struct intel_crtc *crtc,
+			     struct intel_crtc_state *pipe_config,
+			     int fitting_mode);
+void intel_gmch_panel_fitting(struct intel_crtc *crtc,
+			      struct intel_crtc_state *pipe_config,
+			      int fitting_mode);
+void intel_panel_set_backlight_acpi(struct intel_connector *connector,
+				    u32 level, u32 max);
+int intel_panel_setup_backlight(struct drm_connector *connector, enum pipe pipe);
+void intel_panel_enable_backlight(struct intel_connector *connector);
+void intel_panel_disable_backlight(struct intel_connector *connector);
+void intel_panel_destroy_backlight(struct drm_connector *connector);
+enum drm_connector_status intel_panel_detect(struct drm_device *dev);
+extern struct drm_display_mode *intel_find_panel_downclock(
+				struct drm_device *dev,
+				struct drm_display_mode *fixed_mode,
+				struct drm_connector *connector);
+void intel_backlight_register(struct drm_device *dev);
+void intel_backlight_unregister(struct drm_device *dev);
+
+
+/* intel_psr.c */
+void intel_psr_enable(struct intel_dp *intel_dp);
+void intel_psr_disable(struct intel_dp *intel_dp);
+void intel_psr_invalidate(struct drm_device *dev,
+			  unsigned frontbuffer_bits);
+void intel_psr_flush(struct drm_device *dev,
+		     unsigned frontbuffer_bits,
+		     enum fb_op_origin origin);
+void intel_psr_init(struct drm_device *dev);
+void intel_psr_single_frame_update(struct drm_device *dev,
+				   unsigned frontbuffer_bits);
+
+/* intel_runtime_pm.c */
+int intel_power_domains_init(struct drm_i915_private *);
+void intel_power_domains_fini(struct drm_i915_private *);
+void intel_power_domains_init_hw(struct drm_i915_private *dev_priv, bool resume);
+void intel_power_domains_suspend(struct drm_i915_private *dev_priv);
+void bxt_display_core_init(struct drm_i915_private *dev_priv, bool resume);
+void bxt_display_core_uninit(struct drm_i915_private *dev_priv);
+void intel_runtime_pm_enable(struct drm_i915_private *dev_priv);
+const char *
+intel_display_power_domain_str(enum intel_display_power_domain domain);
+
+bool intel_display_power_is_enabled(struct drm_i915_private *dev_priv,
+				    enum intel_display_power_domain domain);
+bool __intel_display_power_is_enabled(struct drm_i915_private *dev_priv,
+				      enum intel_display_power_domain domain);
+void intel_display_power_get(struct drm_i915_private *dev_priv,
+			     enum intel_display_power_domain domain);
+bool intel_display_power_get_if_enabled(struct drm_i915_private *dev_priv,
+					enum intel_display_power_domain domain);
+void intel_display_power_put(struct drm_i915_private *dev_priv,
+			     enum intel_display_power_domain domain);
+
+static inline void
+assert_rpm_device_not_suspended(struct drm_i915_private *dev_priv)
+{
+	WARN_ONCE(dev_priv->pm.suspended,
+		  "Device suspended during HW access\n");
+}
+
+static inline void
+assert_rpm_wakelock_held(struct drm_i915_private *dev_priv)
+{
+	assert_rpm_device_not_suspended(dev_priv);
+	/* FIXME: Needs to be converted back to WARN_ONCE, but currently causes
+	 * too much noise. */
+	if (!atomic_read(&dev_priv->pm.wakeref_count))
+		DRM_DEBUG_DRIVER("RPM wakelock ref not held during HW access");
+}
+
+static inline int
+assert_rpm_atomic_begin(struct drm_i915_private *dev_priv)
+{
+	int seq = atomic_read(&dev_priv->pm.atomic_seq);
+
+	assert_rpm_wakelock_held(dev_priv);
+
+	return seq;
+}
+
+static inline void
+assert_rpm_atomic_end(struct drm_i915_private *dev_priv, int begin_seq)
+{
+	WARN_ONCE(atomic_read(&dev_priv->pm.atomic_seq) != begin_seq,
+		  "HW access outside of RPM atomic section\n");
+}
+
+/**
+ * disable_rpm_wakeref_asserts - disable the RPM assert checks
+ * @dev_priv: i915 device instance
+ *
+ * This function disable asserts that check if we hold an RPM wakelock
+ * reference, while keeping the device-not-suspended checks still enabled.
+ * It's meant to be used only in special circumstances where our rule about
+ * the wakelock refcount wrt. the device power state doesn't hold. According
+ * to this rule at any point where we access the HW or want to keep the HW in
+ * an active state we must hold an RPM wakelock reference acquired via one of
+ * the intel_runtime_pm_get() helpers. Currently there are a few special spots
+ * where this rule doesn't hold: the IRQ and suspend/resume handlers, the
+ * forcewake release timer, and the GPU RPS and hangcheck works. All other
+ * users should avoid using this function.
+ *
+ * Any calls to this function must have a symmetric call to
+ * enable_rpm_wakeref_asserts().
+ */
+static inline void
+disable_rpm_wakeref_asserts(struct drm_i915_private *dev_priv)
+{
+	atomic_inc(&dev_priv->pm.wakeref_count);
+}
+
+/**
+ * enable_rpm_wakeref_asserts - re-enable the RPM assert checks
+ * @dev_priv: i915 device instance
+ *
+ * This function re-enables the RPM assert checks after disabling them with
+ * disable_rpm_wakeref_asserts. It's meant to be used only in special
+ * circumstances otherwise its use should be avoided.
+ *
+ * Any calls to this function must have a symmetric call to
+ * disable_rpm_wakeref_asserts().
+ */
+static inline void
+enable_rpm_wakeref_asserts(struct drm_i915_private *dev_priv)
+{
+	atomic_dec(&dev_priv->pm.wakeref_count);
+}
+
+/* TODO: convert users of these to rely instead on proper RPM refcounting */
+#define DISABLE_RPM_WAKEREF_ASSERTS(dev_priv)	\
+	disable_rpm_wakeref_asserts(dev_priv)
+
+#define ENABLE_RPM_WAKEREF_ASSERTS(dev_priv)	\
+	enable_rpm_wakeref_asserts(dev_priv)
+
+void intel_runtime_pm_get(struct drm_i915_private *dev_priv);
+bool intel_runtime_pm_get_if_in_use(struct drm_i915_private *dev_priv);
+void intel_runtime_pm_get_noresume(struct drm_i915_private *dev_priv);
+void intel_runtime_pm_put(struct drm_i915_private *dev_priv);
+
+void intel_display_set_init_power(struct drm_i915_private *dev, bool enable);
+
+void chv_phy_powergate_lanes(struct intel_encoder *encoder,
+			     bool override, unsigned int mask);
+bool chv_phy_powergate_ch(struct drm_i915_private *dev_priv, enum dpio_phy phy,
+			  enum dpio_channel ch, bool override);
+
+
+/* intel_pm.c */
+void intel_init_clock_gating(struct drm_device *dev);
+void intel_suspend_hw(struct drm_device *dev);
+int ilk_wm_max_level(const struct drm_device *dev);
+void intel_update_watermarks(struct drm_crtc *crtc);
+void intel_init_pm(struct drm_device *dev);
+void intel_init_clock_gating_hooks(struct drm_i915_private *dev_priv);
+void intel_pm_setup(struct drm_device *dev);
+void intel_gpu_ips_init(struct drm_i915_private *dev_priv);
+void intel_gpu_ips_teardown(void);
+void intel_init_gt_powersave(struct drm_device *dev);
+void intel_cleanup_gt_powersave(struct drm_device *dev);
+void intel_enable_gt_powersave(struct drm_device *dev);
+void intel_disable_gt_powersave(struct drm_device *dev);
+void intel_suspend_gt_powersave(struct drm_device *dev);
+void intel_reset_gt_powersave(struct drm_device *dev);
+void gen6_update_ring_freq(struct drm_device *dev);
+void gen6_rps_busy(struct drm_i915_private *dev_priv);
+void gen6_rps_reset_ei(struct drm_i915_private *dev_priv);
+void gen6_rps_idle(struct drm_i915_private *dev_priv);
+void gen6_rps_boost(struct drm_i915_private *dev_priv,
+		    struct intel_rps_client *rps,
+		    unsigned long submitted);
+void intel_queue_rps_boost_for_request(struct drm_device *dev,
+				       struct drm_i915_gem_request *req);
+void vlv_wm_get_hw_state(struct drm_device *dev);
+void ilk_wm_get_hw_state(struct drm_device *dev);
+void skl_wm_get_hw_state(struct drm_device *dev);
+void skl_ddb_get_hw_state(struct drm_i915_private *dev_priv,
+			  struct skl_ddb_allocation *ddb /* out */);
+uint32_t ilk_pipe_pixel_rate(const struct intel_crtc_state *pipe_config);
+bool ilk_disable_lp_wm(struct drm_device *dev);
+int sanitize_rc6_option(const struct drm_device *dev, int enable_rc6);
+
+/* intel_sdvo.c */
+bool intel_sdvo_init(struct drm_device *dev,
+		     i915_reg_t reg, enum port port);
+
+
+/* intel_sprite.c */
+int intel_plane_init(struct drm_device *dev, enum pipe pipe, int plane);
+int intel_sprite_set_colorkey(struct drm_device *dev, void *data,
+			      struct drm_file *file_priv);
+void intel_pipe_update_start(struct intel_crtc *crtc);
+void intel_pipe_update_end(struct intel_crtc *crtc);
+
+/* intel_tv.c */
+void intel_tv_init(struct drm_device *dev);
+
+/* intel_atomic.c */
+int intel_connector_atomic_get_property(struct drm_connector *connector,
+					const struct drm_connector_state *state,
+					struct drm_property *property,
+					uint64_t *val);
+struct drm_crtc_state *intel_crtc_duplicate_state(struct drm_crtc *crtc);
+void intel_crtc_destroy_state(struct drm_crtc *crtc,
+			       struct drm_crtc_state *state);
+struct drm_atomic_state *intel_atomic_state_alloc(struct drm_device *dev);
+void intel_atomic_state_clear(struct drm_atomic_state *);
+struct intel_shared_dpll_config *
+intel_atomic_get_shared_dpll_state(struct drm_atomic_state *s);
+
+static inline struct intel_crtc_state *
+intel_atomic_get_crtc_state(struct drm_atomic_state *state,
+			    struct intel_crtc *crtc)
+{
+	struct drm_crtc_state *crtc_state;
+	crtc_state = drm_atomic_get_crtc_state(state, &crtc->base);
+	if (IS_ERR(crtc_state))
+		return ERR_CAST(crtc_state);
+
+	return to_intel_crtc_state(crtc_state);
+}
+
+static inline struct intel_plane_state *
+intel_atomic_get_existing_plane_state(struct drm_atomic_state *state,
+				      struct intel_plane *plane)
+{
+	struct drm_plane_state *plane_state;
+
+	plane_state = drm_atomic_get_existing_plane_state(state, &plane->base);
+
+	return to_intel_plane_state(plane_state);
+}
+
+int intel_atomic_setup_scalers(struct drm_device *dev,
+	struct intel_crtc *intel_crtc,
+	struct intel_crtc_state *crtc_state);
+
+/* intel_atomic_plane.c */
+struct intel_plane_state *intel_create_plane_state(struct drm_plane *plane);
+struct drm_plane_state *intel_plane_duplicate_state(struct drm_plane *plane);
+void intel_plane_destroy_state(struct drm_plane *plane,
+			       struct drm_plane_state *state);
+extern const struct drm_plane_helper_funcs intel_plane_helper_funcs;
+
+/* intel_color.c */
+void intel_color_init(struct drm_crtc *crtc);
+int intel_color_check(struct drm_crtc *crtc, struct drm_crtc_state *state);
+void intel_color_set_csc(struct drm_crtc_state *crtc_state);
+void intel_color_load_luts(struct drm_crtc_state *crtc_state);
+
+#endif /* __INTEL_DRV_H__ */
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/i915/intel_dsi.c
@@ -0,0 +1,1564 @@
+/*
+ * Copyright © 2013 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Author: Jani Nikula <jani.nikula@intel.com>
+ */
+
+#include <drm/drmP.h>
+#include <drm/drm_atomic_helper.h>
+#include <drm/drm_crtc.h>
+#include <drm/drm_edid.h>
+#include <drm/i915_drm.h>
+#include <drm/drm_panel.h>
+#include <drm/drm_mipi_dsi.h>
+#include <linux/slab.h>
+#include <linux/gpio/consumer.h>
+#include "i915_drv.h"
+#include "intel_drv.h"
+#include "intel_dsi.h"
+
+static const struct {
+	u16 panel_id;
+	struct drm_panel * (*init)(struct intel_dsi *intel_dsi, u16 panel_id);
+} intel_dsi_drivers[] = {
+	{
+		.panel_id = MIPI_DSI_GENERIC_PANEL_ID,
+		.init = vbt_panel_init,
+	},
+};
+
+/* return pixels in terms of txbyteclkhs */
+static u16 txbyteclkhs(u16 pixels, int bpp, int lane_count,
+		       u16 burst_mode_ratio)
+{
+	return DIV_ROUND_UP(DIV_ROUND_UP(pixels * bpp * burst_mode_ratio,
+					 8 * 100), lane_count);
+}
+
+/* return pixels equvalent to txbyteclkhs */
+static u16 pixels_from_txbyteclkhs(u16 clk_hs, int bpp, int lane_count,
+			u16 burst_mode_ratio)
+{
+	return DIV_ROUND_UP((clk_hs * lane_count * 8 * 100),
+						(bpp * burst_mode_ratio));
+}
+
+enum mipi_dsi_pixel_format pixel_format_from_register_bits(u32 fmt)
+{
+	/* It just so happens the VBT matches register contents. */
+	switch (fmt) {
+	case VID_MODE_FORMAT_RGB888:
+		return MIPI_DSI_FMT_RGB888;
+	case VID_MODE_FORMAT_RGB666:
+		return MIPI_DSI_FMT_RGB666;
+	case VID_MODE_FORMAT_RGB666_PACKED:
+		return MIPI_DSI_FMT_RGB666_PACKED;
+	case VID_MODE_FORMAT_RGB565:
+		return MIPI_DSI_FMT_RGB565;
+	default:
+		MISSING_CASE(fmt);
+		return MIPI_DSI_FMT_RGB666;
+	}
+}
+
+static void wait_for_dsi_fifo_empty(struct intel_dsi *intel_dsi, enum port port)
+{
+	struct drm_encoder *encoder = &intel_dsi->base.base;
+	struct drm_device *dev = encoder->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	u32 mask;
+
+	mask = LP_CTRL_FIFO_EMPTY | HS_CTRL_FIFO_EMPTY |
+		LP_DATA_FIFO_EMPTY | HS_DATA_FIFO_EMPTY;
+
+	if (wait_for((I915_READ(MIPI_GEN_FIFO_STAT(port)) & mask) == mask, 100))
+		DRM_ERROR("DPI FIFOs are not empty\n");
+}
+
+static void write_data(struct drm_i915_private *dev_priv,
+		       i915_reg_t reg,
+		       const u8 *data, u32 len)
+{
+	u32 i, j;
+
+	for (i = 0; i < len; i += 4) {
+		u32 val = 0;
+
+		for (j = 0; j < min_t(u32, len - i, 4); j++)
+			val |= *data++ << 8 * j;
+
+		I915_WRITE(reg, val);
+	}
+}
+
+static void read_data(struct drm_i915_private *dev_priv,
+		      i915_reg_t reg,
+		      u8 *data, u32 len)
+{
+	u32 i, j;
+
+	for (i = 0; i < len; i += 4) {
+		u32 val = I915_READ(reg);
+
+		for (j = 0; j < min_t(u32, len - i, 4); j++)
+			*data++ = val >> 8 * j;
+	}
+}
+
+static ssize_t intel_dsi_host_transfer(struct mipi_dsi_host *host,
+				       const struct mipi_dsi_msg *msg)
+{
+	struct intel_dsi_host *intel_dsi_host = to_intel_dsi_host(host);
+	struct drm_device *dev = intel_dsi_host->intel_dsi->base.base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	enum port port = intel_dsi_host->port;
+	struct mipi_dsi_packet packet;
+	ssize_t ret;
+	const u8 *header, *data;
+	i915_reg_t data_reg, ctrl_reg;
+	u32 data_mask, ctrl_mask;
+
+	ret = mipi_dsi_create_packet(&packet, msg);
+	if (ret < 0)
+		return ret;
+
+	header = packet.header;
+	data = packet.payload;
+
+	if (msg->flags & MIPI_DSI_MSG_USE_LPM) {
+		data_reg = MIPI_LP_GEN_DATA(port);
+		data_mask = LP_DATA_FIFO_FULL;
+		ctrl_reg = MIPI_LP_GEN_CTRL(port);
+		ctrl_mask = LP_CTRL_FIFO_FULL;
+	} else {
+		data_reg = MIPI_HS_GEN_DATA(port);
+		data_mask = HS_DATA_FIFO_FULL;
+		ctrl_reg = MIPI_HS_GEN_CTRL(port);
+		ctrl_mask = HS_CTRL_FIFO_FULL;
+	}
+
+	/* note: this is never true for reads */
+	if (packet.payload_length) {
+
+		if (wait_for((I915_READ(MIPI_GEN_FIFO_STAT(port)) & data_mask) == 0, 50))
+			DRM_ERROR("Timeout waiting for HS/LP DATA FIFO !full\n");
+
+		write_data(dev_priv, data_reg, packet.payload,
+			   packet.payload_length);
+	}
+
+	if (msg->rx_len) {
+		I915_WRITE(MIPI_INTR_STAT(port), GEN_READ_DATA_AVAIL);
+	}
+
+	if (wait_for((I915_READ(MIPI_GEN_FIFO_STAT(port)) & ctrl_mask) == 0, 50)) {
+		DRM_ERROR("Timeout waiting for HS/LP CTRL FIFO !full\n");
+	}
+
+	I915_WRITE(ctrl_reg, header[2] << 16 | header[1] << 8 | header[0]);
+
+	/* ->rx_len is set only for reads */
+	if (msg->rx_len) {
+		data_mask = GEN_READ_DATA_AVAIL;
+		if (wait_for((I915_READ(MIPI_INTR_STAT(port)) & data_mask) == data_mask, 50))
+			DRM_ERROR("Timeout waiting for read data.\n");
+
+		read_data(dev_priv, data_reg, msg->rx_buf, msg->rx_len);
+	}
+
+	/* XXX: fix for reads and writes */
+	return 4 + packet.payload_length;
+}
+
+static int intel_dsi_host_attach(struct mipi_dsi_host *host,
+				 struct mipi_dsi_device *dsi)
+{
+	return 0;
+}
+
+static int intel_dsi_host_detach(struct mipi_dsi_host *host,
+				 struct mipi_dsi_device *dsi)
+{
+	return 0;
+}
+
+static const struct mipi_dsi_host_ops intel_dsi_host_ops = {
+	.attach = intel_dsi_host_attach,
+	.detach = intel_dsi_host_detach,
+	.transfer = intel_dsi_host_transfer,
+};
+
+static struct intel_dsi_host *intel_dsi_host_init(struct intel_dsi *intel_dsi,
+						  enum port port)
+{
+	struct intel_dsi_host *host;
+	struct mipi_dsi_device *device;
+
+	host = kzalloc(sizeof(*host), GFP_KERNEL);
+	if (!host)
+		return NULL;
+
+	host->base.ops = &intel_dsi_host_ops;
+	host->intel_dsi = intel_dsi;
+	host->port = port;
+
+	/*
+	 * We should call mipi_dsi_host_register(&host->base) here, but we don't
+	 * have a host->dev, and we don't have OF stuff either. So just use the
+	 * dsi framework as a library and hope for the best. Create the dsi
+	 * devices by ourselves here too. Need to be careful though, because we
+	 * don't initialize any of the driver model devices here.
+	 */
+	device = kzalloc(sizeof(*device), GFP_KERNEL);
+	if (!device) {
+		kfree(host);
+		return NULL;
+	}
+
+	device->host = &host->base;
+	host->device = device;
+
+	return host;
+}
+
+/*
+ * send a video mode command
+ *
+ * XXX: commands with data in MIPI_DPI_DATA?
+ */
+static int dpi_send_cmd(struct intel_dsi *intel_dsi, u32 cmd, bool hs,
+			enum port port)
+{
+	struct drm_encoder *encoder = &intel_dsi->base.base;
+	struct drm_device *dev = encoder->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	u32 mask;
+
+	/* XXX: pipe, hs */
+	if (hs)
+		cmd &= ~DPI_LP_MODE;
+	else
+		cmd |= DPI_LP_MODE;
+
+	/* clear bit */
+	I915_WRITE(MIPI_INTR_STAT(port), SPL_PKT_SENT_INTERRUPT);
+
+	/* XXX: old code skips write if control unchanged */
+	if (cmd == I915_READ(MIPI_DPI_CONTROL(port)))
+		DRM_ERROR("Same special packet %02x twice in a row.\n", cmd);
+
+	I915_WRITE(MIPI_DPI_CONTROL(port), cmd);
+
+	mask = SPL_PKT_SENT_INTERRUPT;
+	if (wait_for((I915_READ(MIPI_INTR_STAT(port)) & mask) == mask, 100))
+		DRM_ERROR("Video mode command 0x%08x send failed.\n", cmd);
+
+	return 0;
+}
+
+static void band_gap_reset(struct drm_i915_private *dev_priv)
+{
+	mutex_lock(&dev_priv->sb_lock);
+
+	vlv_flisdsi_write(dev_priv, 0x08, 0x0001);
+	vlv_flisdsi_write(dev_priv, 0x0F, 0x0005);
+	vlv_flisdsi_write(dev_priv, 0x0F, 0x0025);
+	udelay(150);
+	vlv_flisdsi_write(dev_priv, 0x0F, 0x0000);
+	vlv_flisdsi_write(dev_priv, 0x08, 0x0000);
+
+	mutex_unlock(&dev_priv->sb_lock);
+}
+
+static inline bool is_vid_mode(struct intel_dsi *intel_dsi)
+{
+	return intel_dsi->operation_mode == INTEL_DSI_VIDEO_MODE;
+}
+
+static inline bool is_cmd_mode(struct intel_dsi *intel_dsi)
+{
+	return intel_dsi->operation_mode == INTEL_DSI_COMMAND_MODE;
+}
+
+static bool intel_dsi_compute_config(struct intel_encoder *encoder,
+				     struct intel_crtc_state *pipe_config)
+{
+	struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
+	struct intel_dsi *intel_dsi = container_of(encoder, struct intel_dsi,
+						   base);
+	struct intel_connector *intel_connector = intel_dsi->attached_connector;
+	struct intel_crtc *crtc = to_intel_crtc(pipe_config->base.crtc);
+	const struct drm_display_mode *fixed_mode = intel_connector->panel.fixed_mode;
+	struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
+	int ret;
+
+	DRM_DEBUG_KMS("\n");
+
+	pipe_config->has_dsi_encoder = true;
+
+	if (fixed_mode) {
+		intel_fixed_panel_mode(fixed_mode, adjusted_mode);
+
+		if (HAS_GMCH_DISPLAY(dev_priv))
+			intel_gmch_panel_fitting(crtc, pipe_config,
+						 intel_connector->panel.fitting_mode);
+		else
+			intel_pch_panel_fitting(crtc, pipe_config,
+						intel_connector->panel.fitting_mode);
+	}
+
+	/* DSI uses short packets for sync events, so clear mode flags for DSI */
+	adjusted_mode->flags = 0;
+
+	if (IS_BROXTON(dev_priv)) {
+		/* Dual link goes to DSI transcoder A. */
+		if (intel_dsi->ports == BIT(PORT_C))
+			pipe_config->cpu_transcoder = TRANSCODER_DSI_C;
+		else
+			pipe_config->cpu_transcoder = TRANSCODER_DSI_A;
+	}
+
+	ret = intel_compute_dsi_pll(encoder, pipe_config);
+	if (ret)
+		return false;
+
+	pipe_config->clock_set = true;
+
+	return true;
+}
+
+static void bxt_dsi_device_ready(struct intel_encoder *encoder)
+{
+	struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
+	struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
+	enum port port;
+	u32 val;
+
+	DRM_DEBUG_KMS("\n");
+
+	/* Exit Low power state in 4 steps*/
+	for_each_dsi_port(port, intel_dsi->ports) {
+
+		/* 1. Enable MIPI PHY transparent latch */
+		val = I915_READ(BXT_MIPI_PORT_CTRL(port));
+		I915_WRITE(BXT_MIPI_PORT_CTRL(port), val | LP_OUTPUT_HOLD);
+		usleep_range(2000, 2500);
+
+		/* 2. Enter ULPS */
+		val = I915_READ(MIPI_DEVICE_READY(port));
+		val &= ~ULPS_STATE_MASK;
+		val |= (ULPS_STATE_ENTER | DEVICE_READY);
+		I915_WRITE(MIPI_DEVICE_READY(port), val);
+		usleep_range(2, 3);
+
+		/* 3. Exit ULPS */
+		val = I915_READ(MIPI_DEVICE_READY(port));
+		val &= ~ULPS_STATE_MASK;
+		val |= (ULPS_STATE_EXIT | DEVICE_READY);
+		I915_WRITE(MIPI_DEVICE_READY(port), val);
+		usleep_range(1000, 1500);
+
+		/* Clear ULPS and set device ready */
+		val = I915_READ(MIPI_DEVICE_READY(port));
+		val &= ~ULPS_STATE_MASK;
+		val |= DEVICE_READY;
+		I915_WRITE(MIPI_DEVICE_READY(port), val);
+	}
+}
+
+static void vlv_dsi_device_ready(struct intel_encoder *encoder)
+{
+	struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
+	struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
+	enum port port;
+	u32 val;
+
+	DRM_DEBUG_KMS("\n");
+
+	mutex_lock(&dev_priv->sb_lock);
+	/* program rcomp for compliance, reduce from 50 ohms to 45 ohms
+	 * needed everytime after power gate */
+	vlv_flisdsi_write(dev_priv, 0x04, 0x0004);
+	mutex_unlock(&dev_priv->sb_lock);
+
+	/* bandgap reset is needed after everytime we do power gate */
+	band_gap_reset(dev_priv);
+
+	for_each_dsi_port(port, intel_dsi->ports) {
+
+		I915_WRITE(MIPI_DEVICE_READY(port), ULPS_STATE_ENTER);
+		usleep_range(2500, 3000);
+
+		/* Enable MIPI PHY transparent latch
+		 * Common bit for both MIPI Port A & MIPI Port C
+		 * No similar bit in MIPI Port C reg
+		 */
+		val = I915_READ(MIPI_PORT_CTRL(PORT_A));
+		I915_WRITE(MIPI_PORT_CTRL(PORT_A), val | LP_OUTPUT_HOLD);
+		usleep_range(1000, 1500);
+
+		I915_WRITE(MIPI_DEVICE_READY(port), ULPS_STATE_EXIT);
+		usleep_range(2500, 3000);
+
+		I915_WRITE(MIPI_DEVICE_READY(port), DEVICE_READY);
+		usleep_range(2500, 3000);
+	}
+}
+
+static void intel_dsi_device_ready(struct intel_encoder *encoder)
+{
+	struct drm_device *dev = encoder->base.dev;
+
+	if (IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev))
+		vlv_dsi_device_ready(encoder);
+	else if (IS_BROXTON(dev))
+		bxt_dsi_device_ready(encoder);
+}
+
+static void intel_dsi_port_enable(struct intel_encoder *encoder)
+{
+	struct drm_device *dev = encoder->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc);
+	struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
+	enum port port;
+
+	if (intel_dsi->dual_link == DSI_DUAL_LINK_FRONT_BACK) {
+		u32 temp;
+
+		temp = I915_READ(VLV_CHICKEN_3);
+		temp &= ~PIXEL_OVERLAP_CNT_MASK |
+					intel_dsi->pixel_overlap <<
+					PIXEL_OVERLAP_CNT_SHIFT;
+		I915_WRITE(VLV_CHICKEN_3, temp);
+	}
+
+	for_each_dsi_port(port, intel_dsi->ports) {
+		i915_reg_t port_ctrl = IS_BROXTON(dev) ?
+			BXT_MIPI_PORT_CTRL(port) : MIPI_PORT_CTRL(port);
+		u32 temp;
+
+		temp = I915_READ(port_ctrl);
+
+		temp &= ~LANE_CONFIGURATION_MASK;
+		temp &= ~DUAL_LINK_MODE_MASK;
+
+		if (intel_dsi->ports == (BIT(PORT_A) | BIT(PORT_C))) {
+			temp |= (intel_dsi->dual_link - 1)
+						<< DUAL_LINK_MODE_SHIFT;
+			temp |= intel_crtc->pipe ?
+					LANE_CONFIGURATION_DUAL_LINK_B :
+					LANE_CONFIGURATION_DUAL_LINK_A;
+		}
+		/* assert ip_tg_enable signal */
+		I915_WRITE(port_ctrl, temp | DPI_ENABLE);
+		POSTING_READ(port_ctrl);
+	}
+}
+
+static void intel_dsi_port_disable(struct intel_encoder *encoder)
+{
+	struct drm_device *dev = encoder->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
+	enum port port;
+
+	for_each_dsi_port(port, intel_dsi->ports) {
+		i915_reg_t port_ctrl = IS_BROXTON(dev) ?
+			BXT_MIPI_PORT_CTRL(port) : MIPI_PORT_CTRL(port);
+		u32 temp;
+
+		/* de-assert ip_tg_enable signal */
+		temp = I915_READ(port_ctrl);
+		I915_WRITE(port_ctrl, temp & ~DPI_ENABLE);
+		POSTING_READ(port_ctrl);
+	}
+}
+
+static void intel_dsi_enable(struct intel_encoder *encoder)
+{
+	struct drm_device *dev = encoder->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
+	enum port port;
+
+	DRM_DEBUG_KMS("\n");
+
+	if (is_cmd_mode(intel_dsi)) {
+		for_each_dsi_port(port, intel_dsi->ports)
+			I915_WRITE(MIPI_MAX_RETURN_PKT_SIZE(port), 8 * 4);
+	} else {
+		msleep(20); /* XXX */
+		for_each_dsi_port(port, intel_dsi->ports)
+			dpi_send_cmd(intel_dsi, TURN_ON, false, port);
+		msleep(100);
+
+		drm_panel_enable(intel_dsi->panel);
+
+		for_each_dsi_port(port, intel_dsi->ports)
+			wait_for_dsi_fifo_empty(intel_dsi, port);
+
+		intel_dsi_port_enable(encoder);
+	}
+
+	intel_panel_enable_backlight(intel_dsi->attached_connector);
+}
+
+static void intel_dsi_prepare(struct intel_encoder *intel_encoder);
+
+static void intel_dsi_pre_enable(struct intel_encoder *encoder)
+{
+	struct drm_device *dev = encoder->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
+	struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc);
+	enum port port;
+	u32 tmp;
+
+	DRM_DEBUG_KMS("\n");
+
+	/*
+	 * The BIOS may leave the PLL in a wonky state where it doesn't
+	 * lock. It needs to be fully powered down to fix it.
+	 */
+	intel_disable_dsi_pll(encoder);
+	intel_enable_dsi_pll(encoder, crtc->config);
+
+	intel_dsi_prepare(encoder);
+
+	/* Panel Enable over CRC PMIC */
+	if (intel_dsi->gpio_panel)
+		gpiod_set_value_cansleep(intel_dsi->gpio_panel, 1);
+
+	msleep(intel_dsi->panel_on_delay);
+
+	if (IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev)) {
+		/* Disable DPOunit clock gating, can stall pipe */
+		tmp = I915_READ(DSPCLK_GATE_D);
+		tmp |= DPOUNIT_CLOCK_GATE_DISABLE;
+		I915_WRITE(DSPCLK_GATE_D, tmp);
+	}
+
+	/* put device in ready state */
+	intel_dsi_device_ready(encoder);
+
+	drm_panel_prepare(intel_dsi->panel);
+
+	for_each_dsi_port(port, intel_dsi->ports)
+		wait_for_dsi_fifo_empty(intel_dsi, port);
+
+	/* Enable port in pre-enable phase itself because as per hw team
+	 * recommendation, port should be enabled befor plane & pipe */
+	intel_dsi_enable(encoder);
+}
+
+static void intel_dsi_enable_nop(struct intel_encoder *encoder)
+{
+	DRM_DEBUG_KMS("\n");
+
+	/* for DSI port enable has to be done before pipe
+	 * and plane enable, so port enable is done in
+	 * pre_enable phase itself unlike other encoders
+	 */
+}
+
+static void intel_dsi_pre_disable(struct intel_encoder *encoder)
+{
+	struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
+	enum port port;
+
+	DRM_DEBUG_KMS("\n");
+
+	intel_panel_disable_backlight(intel_dsi->attached_connector);
+
+	if (is_vid_mode(intel_dsi)) {
+		/* Send Shutdown command to the panel in LP mode */
+		for_each_dsi_port(port, intel_dsi->ports)
+			dpi_send_cmd(intel_dsi, SHUTDOWN, false, port);
+		msleep(10);
+	}
+}
+
+static void intel_dsi_disable(struct intel_encoder *encoder)
+{
+	struct drm_device *dev = encoder->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
+	enum port port;
+	u32 temp;
+
+	DRM_DEBUG_KMS("\n");
+
+	if (is_vid_mode(intel_dsi)) {
+		for_each_dsi_port(port, intel_dsi->ports)
+			wait_for_dsi_fifo_empty(intel_dsi, port);
+
+		intel_dsi_port_disable(encoder);
+		msleep(2);
+	}
+
+	for_each_dsi_port(port, intel_dsi->ports) {
+		/* Panel commands can be sent when clock is in LP11 */
+		I915_WRITE(MIPI_DEVICE_READY(port), 0x0);
+
+		intel_dsi_reset_clocks(encoder, port);
+		I915_WRITE(MIPI_EOT_DISABLE(port), CLOCKSTOP);
+
+		temp = I915_READ(MIPI_DSI_FUNC_PRG(port));
+		temp &= ~VID_MODE_FORMAT_MASK;
+		I915_WRITE(MIPI_DSI_FUNC_PRG(port), temp);
+
+		I915_WRITE(MIPI_DEVICE_READY(port), 0x1);
+	}
+	/* if disable packets are sent before sending shutdown packet then in
+	 * some next enable sequence send turn on packet error is observed */
+	drm_panel_disable(intel_dsi->panel);
+
+	for_each_dsi_port(port, intel_dsi->ports)
+		wait_for_dsi_fifo_empty(intel_dsi, port);
+}
+
+static void intel_dsi_clear_device_ready(struct intel_encoder *encoder)
+{
+	struct drm_device *dev = encoder->base.dev;
+	struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
+	struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
+	enum port port;
+
+	DRM_DEBUG_KMS("\n");
+	for_each_dsi_port(port, intel_dsi->ports) {
+		/* Common bit for both MIPI Port A & MIPI Port C on VLV/CHV */
+		i915_reg_t port_ctrl = IS_BROXTON(dev) ?
+			BXT_MIPI_PORT_CTRL(port) : MIPI_PORT_CTRL(PORT_A);
+		u32 val;
+
+		I915_WRITE(MIPI_DEVICE_READY(port), DEVICE_READY |
+							ULPS_STATE_ENTER);
+		usleep_range(2000, 2500);
+
+		I915_WRITE(MIPI_DEVICE_READY(port), DEVICE_READY |
+							ULPS_STATE_EXIT);
+		usleep_range(2000, 2500);
+
+		I915_WRITE(MIPI_DEVICE_READY(port), DEVICE_READY |
+							ULPS_STATE_ENTER);
+		usleep_range(2000, 2500);
+
+		/* Wait till Clock lanes are in LP-00 state for MIPI Port A
+		 * only. MIPI Port C has no similar bit for checking
+		 */
+		if (wait_for(((I915_READ(port_ctrl) & AFE_LATCHOUT)
+						== 0x00000), 30))
+			DRM_ERROR("DSI LP not going Low\n");
+
+		/* Disable MIPI PHY transparent latch */
+		val = I915_READ(port_ctrl);
+		I915_WRITE(port_ctrl, val & ~LP_OUTPUT_HOLD);
+		usleep_range(1000, 1500);
+
+		I915_WRITE(MIPI_DEVICE_READY(port), 0x00);
+		usleep_range(2000, 2500);
+	}
+
+	intel_disable_dsi_pll(encoder);
+}
+
+static void intel_dsi_post_disable(struct intel_encoder *encoder)
+{
+	struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
+	struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
+
+	DRM_DEBUG_KMS("\n");
+
+	intel_dsi_disable(encoder);
+
+	intel_dsi_clear_device_ready(encoder);
+
+	if (!IS_BROXTON(dev_priv)) {
+		u32 val;
+
+		val = I915_READ(DSPCLK_GATE_D);
+		val &= ~DPOUNIT_CLOCK_GATE_DISABLE;
+		I915_WRITE(DSPCLK_GATE_D, val);
+	}
+
+	drm_panel_unprepare(intel_dsi->panel);
+
+	msleep(intel_dsi->panel_off_delay);
+
+	/* Panel Disable over CRC PMIC */
+	if (intel_dsi->gpio_panel)
+		gpiod_set_value_cansleep(intel_dsi->gpio_panel, 0);
+
+	/*
+	 * FIXME As we do with eDP, just make a note of the time here
+	 * and perform the wait before the next panel power on.
+	 */
+	msleep(intel_dsi->panel_pwr_cycle_delay);
+}
+
+static bool intel_dsi_get_hw_state(struct intel_encoder *encoder,
+				   enum pipe *pipe)
+{
+	struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
+	struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
+	struct drm_device *dev = encoder->base.dev;
+	enum intel_display_power_domain power_domain;
+	enum port port;
+	bool active = false;
+
+	DRM_DEBUG_KMS("\n");
+
+	power_domain = intel_display_port_power_domain(encoder);
+	if (!intel_display_power_get_if_enabled(dev_priv, power_domain))
+		return false;
+
+	/*
+	 * On Broxton the PLL needs to be enabled with a valid divider
+	 * configuration, otherwise accessing DSI registers will hang the
+	 * machine. See BSpec North Display Engine registers/MIPI[BXT].
+	 */
+	if (IS_BROXTON(dev_priv) && !intel_dsi_pll_is_enabled(dev_priv))
+		goto out_put_power;
+
+	/* XXX: this only works for one DSI output */
+	for_each_dsi_port(port, intel_dsi->ports) {
+		i915_reg_t ctrl_reg = IS_BROXTON(dev) ?
+			BXT_MIPI_PORT_CTRL(port) : MIPI_PORT_CTRL(port);
+		bool enabled = I915_READ(ctrl_reg) & DPI_ENABLE;
+
+		/*
+		 * Due to some hardware limitations on VLV/CHV, the DPI enable
+		 * bit in port C control register does not get set. As a
+		 * workaround, check pipe B conf instead.
+		 */
+		if ((IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev)) && port == PORT_C)
+			enabled = I915_READ(PIPECONF(PIPE_B)) & PIPECONF_ENABLE;
+
+		/* Try command mode if video mode not enabled */
+		if (!enabled) {
+			u32 tmp = I915_READ(MIPI_DSI_FUNC_PRG(port));
+			enabled = tmp & CMD_MODE_DATA_WIDTH_MASK;
+		}
+
+		if (!enabled)
+			continue;
+
+		if (!(I915_READ(MIPI_DEVICE_READY(port)) & DEVICE_READY))
+			continue;
+
+		if (IS_BROXTON(dev_priv)) {
+			u32 tmp = I915_READ(MIPI_CTRL(port));
+			tmp &= BXT_PIPE_SELECT_MASK;
+			tmp >>= BXT_PIPE_SELECT_SHIFT;
+
+			if (WARN_ON(tmp > PIPE_C))
+				continue;
+
+			*pipe = tmp;
+		} else {
+			*pipe = port == PORT_A ? PIPE_A : PIPE_B;
+		}
+
+		active = true;
+		break;
+	}
+
+out_put_power:
+	intel_display_power_put(dev_priv, power_domain);
+
+	return active;
+}
+
+static void bxt_dsi_get_pipe_config(struct intel_encoder *encoder,
+				 struct intel_crtc_state *pipe_config)
+{
+	struct drm_device *dev = encoder->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct drm_display_mode *adjusted_mode =
+					&pipe_config->base.adjusted_mode;
+	struct drm_display_mode *adjusted_mode_sw;
+	struct intel_crtc *intel_crtc;
+	struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
+	unsigned int lane_count = intel_dsi->lane_count;
+	unsigned int bpp, fmt;
+	enum port port;
+	u16 hactive, hfp, hsync, hbp, vfp, vsync, vbp;
+	u16 hfp_sw, hsync_sw, hbp_sw;
+	u16 crtc_htotal_sw, crtc_hsync_start_sw, crtc_hsync_end_sw,
+				crtc_hblank_start_sw, crtc_hblank_end_sw;
+
+	intel_crtc = to_intel_crtc(encoder->base.crtc);
+	adjusted_mode_sw = &intel_crtc->config->base.adjusted_mode;
+
+	/*
+	 * Atleast one port is active as encoder->get_config called only if
+	 * encoder->get_hw_state() returns true.
+	 */
+	for_each_dsi_port(port, intel_dsi->ports) {
+		if (I915_READ(BXT_MIPI_PORT_CTRL(port)) & DPI_ENABLE)
+			break;
+	}
+
+	fmt = I915_READ(MIPI_DSI_FUNC_PRG(port)) & VID_MODE_FORMAT_MASK;
+	pipe_config->pipe_bpp =
+			mipi_dsi_pixel_format_to_bpp(
+				pixel_format_from_register_bits(fmt));
+	bpp = pipe_config->pipe_bpp;
+
+	/* In terms of pixels */
+	adjusted_mode->crtc_hdisplay =
+				I915_READ(BXT_MIPI_TRANS_HACTIVE(port));
+	adjusted_mode->crtc_vdisplay =
+				I915_READ(BXT_MIPI_TRANS_VACTIVE(port));
+	adjusted_mode->crtc_vtotal =
+				I915_READ(BXT_MIPI_TRANS_VTOTAL(port));
+
+	hactive = adjusted_mode->crtc_hdisplay;
+	hfp = I915_READ(MIPI_HFP_COUNT(port));
+
+	/*
+	 * Meaningful for video mode non-burst sync pulse mode only,
+	 * can be zero for non-burst sync events and burst modes
+	 */
+	hsync = I915_READ(MIPI_HSYNC_PADDING_COUNT(port));
+	hbp = I915_READ(MIPI_HBP_COUNT(port));
+
+	/* harizontal values are in terms of high speed byte clock */
+	hfp = pixels_from_txbyteclkhs(hfp, bpp, lane_count,
+						intel_dsi->burst_mode_ratio);
+	hsync = pixels_from_txbyteclkhs(hsync, bpp, lane_count,
+						intel_dsi->burst_mode_ratio);
+	hbp = pixels_from_txbyteclkhs(hbp, bpp, lane_count,
+						intel_dsi->burst_mode_ratio);
+
+	if (intel_dsi->dual_link) {
+		hfp *= 2;
+		hsync *= 2;
+		hbp *= 2;
+	}
+
+	/* vertical values are in terms of lines */
+	vfp = I915_READ(MIPI_VFP_COUNT(port));
+	vsync = I915_READ(MIPI_VSYNC_PADDING_COUNT(port));
+	vbp = I915_READ(MIPI_VBP_COUNT(port));
+
+	adjusted_mode->crtc_htotal = hactive + hfp + hsync + hbp;
+	adjusted_mode->crtc_hsync_start = hfp + adjusted_mode->crtc_hdisplay;
+	adjusted_mode->crtc_hsync_end = hsync + adjusted_mode->crtc_hsync_start;
+	adjusted_mode->crtc_hblank_start = adjusted_mode->crtc_hdisplay;
+	adjusted_mode->crtc_hblank_end = adjusted_mode->crtc_htotal;
+
+	adjusted_mode->crtc_vsync_start = vfp + adjusted_mode->crtc_vdisplay;
+	adjusted_mode->crtc_vsync_end = vsync + adjusted_mode->crtc_vsync_start;
+	adjusted_mode->crtc_vblank_start = adjusted_mode->crtc_vdisplay;
+	adjusted_mode->crtc_vblank_end = adjusted_mode->crtc_vtotal;
+
+	/*
+	 * In BXT DSI there is no regs programmed with few horizontal timings
+	 * in Pixels but txbyteclkhs.. So retrieval process adds some
+	 * ROUND_UP ERRORS in the process of PIXELS<==>txbyteclkhs.
+	 * Actually here for the given adjusted_mode, we are calculating the
+	 * value programmed to the port and then back to the horizontal timing
+	 * param in pixels. This is the expected value, including roundup errors
+	 * And if that is same as retrieved value from port, then
+	 * (HW state) adjusted_mode's horizontal timings are corrected to
+	 * match with SW state to nullify the errors.
+	 */
+	/* Calculating the value programmed to the Port register */
+	hfp_sw = adjusted_mode_sw->crtc_hsync_start -
+					adjusted_mode_sw->crtc_hdisplay;
+	hsync_sw = adjusted_mode_sw->crtc_hsync_end -
+					adjusted_mode_sw->crtc_hsync_start;
+	hbp_sw = adjusted_mode_sw->crtc_htotal -
+					adjusted_mode_sw->crtc_hsync_end;
+
+	if (intel_dsi->dual_link) {
+		hfp_sw /= 2;
+		hsync_sw /= 2;
+		hbp_sw /= 2;
+	}
+
+	hfp_sw = txbyteclkhs(hfp_sw, bpp, lane_count,
+						intel_dsi->burst_mode_ratio);
+	hsync_sw = txbyteclkhs(hsync_sw, bpp, lane_count,
+			    intel_dsi->burst_mode_ratio);
+	hbp_sw = txbyteclkhs(hbp_sw, bpp, lane_count,
+						intel_dsi->burst_mode_ratio);
+
+	/* Reverse calculating the adjusted mode parameters from port reg vals*/
+	hfp_sw = pixels_from_txbyteclkhs(hfp_sw, bpp, lane_count,
+						intel_dsi->burst_mode_ratio);
+	hsync_sw = pixels_from_txbyteclkhs(hsync_sw, bpp, lane_count,
+						intel_dsi->burst_mode_ratio);
+	hbp_sw = pixels_from_txbyteclkhs(hbp_sw, bpp, lane_count,
+						intel_dsi->burst_mode_ratio);
+
+	if (intel_dsi->dual_link) {
+		hfp_sw *= 2;
+		hsync_sw *= 2;
+		hbp_sw *= 2;
+	}
+
+	crtc_htotal_sw = adjusted_mode_sw->crtc_hdisplay + hfp_sw +
+							hsync_sw + hbp_sw;
+	crtc_hsync_start_sw = hfp_sw + adjusted_mode_sw->crtc_hdisplay;
+	crtc_hsync_end_sw = hsync_sw + crtc_hsync_start_sw;
+	crtc_hblank_start_sw = adjusted_mode_sw->crtc_hdisplay;
+	crtc_hblank_end_sw = crtc_htotal_sw;
+
+	if (adjusted_mode->crtc_htotal == crtc_htotal_sw)
+		adjusted_mode->crtc_htotal = adjusted_mode_sw->crtc_htotal;
+
+	if (adjusted_mode->crtc_hsync_start == crtc_hsync_start_sw)
+		adjusted_mode->crtc_hsync_start =
+					adjusted_mode_sw->crtc_hsync_start;
+
+	if (adjusted_mode->crtc_hsync_end == crtc_hsync_end_sw)
+		adjusted_mode->crtc_hsync_end =
+					adjusted_mode_sw->crtc_hsync_end;
+
+	if (adjusted_mode->crtc_hblank_start == crtc_hblank_start_sw)
+		adjusted_mode->crtc_hblank_start =
+					adjusted_mode_sw->crtc_hblank_start;
+
+	if (adjusted_mode->crtc_hblank_end == crtc_hblank_end_sw)
+		adjusted_mode->crtc_hblank_end =
+					adjusted_mode_sw->crtc_hblank_end;
+}
+
+static void intel_dsi_get_config(struct intel_encoder *encoder,
+				 struct intel_crtc_state *pipe_config)
+{
+	struct drm_device *dev = encoder->base.dev;
+	u32 pclk;
+	DRM_DEBUG_KMS("\n");
+
+	pipe_config->has_dsi_encoder = true;
+
+	if (IS_BROXTON(dev))
+		bxt_dsi_get_pipe_config(encoder, pipe_config);
+
+	pclk = intel_dsi_get_pclk(encoder, pipe_config->pipe_bpp,
+				  pipe_config);
+	if (!pclk)
+		return;
+
+	pipe_config->base.adjusted_mode.crtc_clock = pclk;
+	pipe_config->port_clock = pclk;
+}
+
+static enum drm_mode_status
+intel_dsi_mode_valid(struct drm_connector *connector,
+		     struct drm_display_mode *mode)
+{
+	struct intel_connector *intel_connector = to_intel_connector(connector);
+	const struct drm_display_mode *fixed_mode = intel_connector->panel.fixed_mode;
+	int max_dotclk = to_i915(connector->dev)->max_dotclk_freq;
+
+	DRM_DEBUG_KMS("\n");
+
+	if (mode->flags & DRM_MODE_FLAG_DBLSCAN) {
+		DRM_DEBUG_KMS("MODE_NO_DBLESCAN\n");
+		return MODE_NO_DBLESCAN;
+	}
+
+	if (fixed_mode) {
+		if (mode->hdisplay > fixed_mode->hdisplay)
+			return MODE_PANEL;
+		if (mode->vdisplay > fixed_mode->vdisplay)
+			return MODE_PANEL;
+		if (fixed_mode->clock > max_dotclk)
+			return MODE_CLOCK_HIGH;
+	}
+
+	return MODE_OK;
+}
+
+/* return txclkesc cycles in terms of divider and duration in us */
+static u16 txclkesc(u32 divider, unsigned int us)
+{
+	switch (divider) {
+	case ESCAPE_CLOCK_DIVIDER_1:
+	default:
+		return 20 * us;
+	case ESCAPE_CLOCK_DIVIDER_2:
+		return 10 * us;
+	case ESCAPE_CLOCK_DIVIDER_4:
+		return 5 * us;
+	}
+}
+
+static void set_dsi_timings(struct drm_encoder *encoder,
+			    const struct drm_display_mode *adjusted_mode)
+{
+	struct drm_device *dev = encoder->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder);
+	enum port port;
+	unsigned int bpp = mipi_dsi_pixel_format_to_bpp(intel_dsi->pixel_format);
+	unsigned int lane_count = intel_dsi->lane_count;
+
+	u16 hactive, hfp, hsync, hbp, vfp, vsync, vbp;
+
+	hactive = adjusted_mode->crtc_hdisplay;
+	hfp = adjusted_mode->crtc_hsync_start - adjusted_mode->crtc_hdisplay;
+	hsync = adjusted_mode->crtc_hsync_end - adjusted_mode->crtc_hsync_start;
+	hbp = adjusted_mode->crtc_htotal - adjusted_mode->crtc_hsync_end;
+
+	if (intel_dsi->dual_link) {
+		hactive /= 2;
+		if (intel_dsi->dual_link == DSI_DUAL_LINK_FRONT_BACK)
+			hactive += intel_dsi->pixel_overlap;
+		hfp /= 2;
+		hsync /= 2;
+		hbp /= 2;
+	}
+
+	vfp = adjusted_mode->crtc_vsync_start - adjusted_mode->crtc_vdisplay;
+	vsync = adjusted_mode->crtc_vsync_end - adjusted_mode->crtc_vsync_start;
+	vbp = adjusted_mode->crtc_vtotal - adjusted_mode->crtc_vsync_end;
+
+	/* horizontal values are in terms of high speed byte clock */
+	hactive = txbyteclkhs(hactive, bpp, lane_count,
+			      intel_dsi->burst_mode_ratio);
+	hfp = txbyteclkhs(hfp, bpp, lane_count, intel_dsi->burst_mode_ratio);
+	hsync = txbyteclkhs(hsync, bpp, lane_count,
+			    intel_dsi->burst_mode_ratio);
+	hbp = txbyteclkhs(hbp, bpp, lane_count, intel_dsi->burst_mode_ratio);
+
+	for_each_dsi_port(port, intel_dsi->ports) {
+		if (IS_BROXTON(dev)) {
+			/*
+			 * Program hdisplay and vdisplay on MIPI transcoder.
+			 * This is different from calculated hactive and
+			 * vactive, as they are calculated per channel basis,
+			 * whereas these values should be based on resolution.
+			 */
+			I915_WRITE(BXT_MIPI_TRANS_HACTIVE(port),
+				   adjusted_mode->crtc_hdisplay);
+			I915_WRITE(BXT_MIPI_TRANS_VACTIVE(port),
+				   adjusted_mode->crtc_vdisplay);
+			I915_WRITE(BXT_MIPI_TRANS_VTOTAL(port),
+				   adjusted_mode->crtc_vtotal);
+		}
+
+		I915_WRITE(MIPI_HACTIVE_AREA_COUNT(port), hactive);
+		I915_WRITE(MIPI_HFP_COUNT(port), hfp);
+
+		/* meaningful for video mode non-burst sync pulse mode only,
+		 * can be zero for non-burst sync events and burst modes */
+		I915_WRITE(MIPI_HSYNC_PADDING_COUNT(port), hsync);
+		I915_WRITE(MIPI_HBP_COUNT(port), hbp);
+
+		/* vertical values are in terms of lines */
+		I915_WRITE(MIPI_VFP_COUNT(port), vfp);
+		I915_WRITE(MIPI_VSYNC_PADDING_COUNT(port), vsync);
+		I915_WRITE(MIPI_VBP_COUNT(port), vbp);
+	}
+}
+
+static u32 pixel_format_to_reg(enum mipi_dsi_pixel_format fmt)
+{
+	switch (fmt) {
+	case MIPI_DSI_FMT_RGB888:
+		return VID_MODE_FORMAT_RGB888;
+	case MIPI_DSI_FMT_RGB666:
+		return VID_MODE_FORMAT_RGB666;
+	case MIPI_DSI_FMT_RGB666_PACKED:
+		return VID_MODE_FORMAT_RGB666_PACKED;
+	case MIPI_DSI_FMT_RGB565:
+		return VID_MODE_FORMAT_RGB565;
+	default:
+		MISSING_CASE(fmt);
+		return VID_MODE_FORMAT_RGB666;
+	}
+}
+
+static void intel_dsi_prepare(struct intel_encoder *intel_encoder)
+{
+	struct drm_encoder *encoder = &intel_encoder->base;
+	struct drm_device *dev = encoder->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
+	struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder);
+	const struct drm_display_mode *adjusted_mode = &intel_crtc->config->base.adjusted_mode;
+	enum port port;
+	unsigned int bpp = mipi_dsi_pixel_format_to_bpp(intel_dsi->pixel_format);
+	u32 val, tmp;
+	u16 mode_hdisplay;
+
+	DRM_DEBUG_KMS("pipe %c\n", pipe_name(intel_crtc->pipe));
+
+	mode_hdisplay = adjusted_mode->crtc_hdisplay;
+
+	if (intel_dsi->dual_link) {
+		mode_hdisplay /= 2;
+		if (intel_dsi->dual_link == DSI_DUAL_LINK_FRONT_BACK)
+			mode_hdisplay += intel_dsi->pixel_overlap;
+	}
+
+	for_each_dsi_port(port, intel_dsi->ports) {
+		if (IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev)) {
+			/*
+			 * escape clock divider, 20MHz, shared for A and C.
+			 * device ready must be off when doing this! txclkesc?
+			 */
+			tmp = I915_READ(MIPI_CTRL(PORT_A));
+			tmp &= ~ESCAPE_CLOCK_DIVIDER_MASK;
+			I915_WRITE(MIPI_CTRL(PORT_A), tmp |
+					ESCAPE_CLOCK_DIVIDER_1);
+
+			/* read request priority is per pipe */
+			tmp = I915_READ(MIPI_CTRL(port));
+			tmp &= ~READ_REQUEST_PRIORITY_MASK;
+			I915_WRITE(MIPI_CTRL(port), tmp |
+					READ_REQUEST_PRIORITY_HIGH);
+		} else if (IS_BROXTON(dev)) {
+			enum pipe pipe = intel_crtc->pipe;
+
+			tmp = I915_READ(MIPI_CTRL(port));
+			tmp &= ~BXT_PIPE_SELECT_MASK;
+
+			tmp |= BXT_PIPE_SELECT(pipe);
+			I915_WRITE(MIPI_CTRL(port), tmp);
+		}
+
+		/* XXX: why here, why like this? handling in irq handler?! */
+		I915_WRITE(MIPI_INTR_STAT(port), 0xffffffff);
+		I915_WRITE(MIPI_INTR_EN(port), 0xffffffff);
+
+		I915_WRITE(MIPI_DPHY_PARAM(port), intel_dsi->dphy_reg);
+
+		I915_WRITE(MIPI_DPI_RESOLUTION(port),
+			adjusted_mode->crtc_vdisplay << VERTICAL_ADDRESS_SHIFT |
+			mode_hdisplay << HORIZONTAL_ADDRESS_SHIFT);
+	}
+
+	set_dsi_timings(encoder, adjusted_mode);
+
+	val = intel_dsi->lane_count << DATA_LANES_PRG_REG_SHIFT;
+	if (is_cmd_mode(intel_dsi)) {
+		val |= intel_dsi->channel << CMD_MODE_CHANNEL_NUMBER_SHIFT;
+		val |= CMD_MODE_DATA_WIDTH_8_BIT; /* XXX */
+	} else {
+		val |= intel_dsi->channel << VID_MODE_CHANNEL_NUMBER_SHIFT;
+		val |= pixel_format_to_reg(intel_dsi->pixel_format);
+	}
+
+	tmp = 0;
+	if (intel_dsi->eotp_pkt == 0)
+		tmp |= EOT_DISABLE;
+	if (intel_dsi->clock_stop)
+		tmp |= CLOCKSTOP;
+
+	for_each_dsi_port(port, intel_dsi->ports) {
+		I915_WRITE(MIPI_DSI_FUNC_PRG(port), val);
+
+		/* timeouts for recovery. one frame IIUC. if counter expires,
+		 * EOT and stop state. */
+
+		/*
+		 * In burst mode, value greater than one DPI line Time in byte
+		 * clock (txbyteclkhs) To timeout this timer 1+ of the above
+		 * said value is recommended.
+		 *
+		 * In non-burst mode, Value greater than one DPI frame time in
+		 * byte clock(txbyteclkhs) To timeout this timer 1+ of the above
+		 * said value is recommended.
+		 *
+		 * In DBI only mode, value greater than one DBI frame time in
+		 * byte clock(txbyteclkhs) To timeout this timer 1+ of the above
+		 * said value is recommended.
+		 */
+
+		if (is_vid_mode(intel_dsi) &&
+			intel_dsi->video_mode_format == VIDEO_MODE_BURST) {
+			I915_WRITE(MIPI_HS_TX_TIMEOUT(port),
+				txbyteclkhs(adjusted_mode->crtc_htotal, bpp,
+					    intel_dsi->lane_count,
+					    intel_dsi->burst_mode_ratio) + 1);
+		} else {
+			I915_WRITE(MIPI_HS_TX_TIMEOUT(port),
+				txbyteclkhs(adjusted_mode->crtc_vtotal *
+					    adjusted_mode->crtc_htotal,
+					    bpp, intel_dsi->lane_count,
+					    intel_dsi->burst_mode_ratio) + 1);
+		}
+		I915_WRITE(MIPI_LP_RX_TIMEOUT(port), intel_dsi->lp_rx_timeout);
+		I915_WRITE(MIPI_TURN_AROUND_TIMEOUT(port),
+						intel_dsi->turn_arnd_val);
+		I915_WRITE(MIPI_DEVICE_RESET_TIMER(port),
+						intel_dsi->rst_timer_val);
+
+		/* dphy stuff */
+
+		/* in terms of low power clock */
+		I915_WRITE(MIPI_INIT_COUNT(port),
+				txclkesc(intel_dsi->escape_clk_div, 100));
+
+		if (IS_BROXTON(dev) && (!intel_dsi->dual_link)) {
+			/*
+			 * BXT spec says write MIPI_INIT_COUNT for
+			 * both the ports, even if only one is
+			 * getting used. So write the other port
+			 * if not in dual link mode.
+			 */
+			I915_WRITE(MIPI_INIT_COUNT(port ==
+						PORT_A ? PORT_C : PORT_A),
+					intel_dsi->init_count);
+		}
+
+		/* recovery disables */
+		I915_WRITE(MIPI_EOT_DISABLE(port), tmp);
+
+		/* in terms of low power clock */
+		I915_WRITE(MIPI_INIT_COUNT(port), intel_dsi->init_count);
+
+		/* in terms of txbyteclkhs. actual high to low switch +
+		 * MIPI_STOP_STATE_STALL * MIPI_LP_BYTECLK.
+		 *
+		 * XXX: write MIPI_STOP_STATE_STALL?
+		 */
+		I915_WRITE(MIPI_HIGH_LOW_SWITCH_COUNT(port),
+						intel_dsi->hs_to_lp_count);
+
+		/* XXX: low power clock equivalence in terms of byte clock.
+		 * the number of byte clocks occupied in one low power clock.
+		 * based on txbyteclkhs and txclkesc.
+		 * txclkesc time / txbyteclk time * (105 + MIPI_STOP_STATE_STALL
+		 * ) / 105.???
+		 */
+		I915_WRITE(MIPI_LP_BYTECLK(port), intel_dsi->lp_byte_clk);
+
+		/* the bw essential for transmitting 16 long packets containing
+		 * 252 bytes meant for dcs write memory command is programmed in
+		 * this register in terms of byte clocks. based on dsi transfer
+		 * rate and the number of lanes configured the time taken to
+		 * transmit 16 long packets in a dsi stream varies. */
+		I915_WRITE(MIPI_DBI_BW_CTRL(port), intel_dsi->bw_timer);
+
+		I915_WRITE(MIPI_CLK_LANE_SWITCH_TIME_CNT(port),
+		intel_dsi->clk_lp_to_hs_count << LP_HS_SSW_CNT_SHIFT |
+		intel_dsi->clk_hs_to_lp_count << HS_LP_PWR_SW_CNT_SHIFT);
+
+		if (is_vid_mode(intel_dsi))
+			/* Some panels might have resolution which is not a
+			 * multiple of 64 like 1366 x 768. Enable RANDOM
+			 * resolution support for such panels by default */
+			I915_WRITE(MIPI_VIDEO_MODE_FORMAT(port),
+				intel_dsi->video_frmt_cfg_bits |
+				intel_dsi->video_mode_format |
+				IP_TG_CONFIG |
+				RANDOM_DPI_DISPLAY_RESOLUTION);
+	}
+}
+
+static enum drm_connector_status
+intel_dsi_detect(struct drm_connector *connector, bool force)
+{
+	return connector_status_connected;
+}
+
+static int intel_dsi_get_modes(struct drm_connector *connector)
+{
+	struct intel_connector *intel_connector = to_intel_connector(connector);
+	struct drm_display_mode *mode;
+
+	DRM_DEBUG_KMS("\n");
+
+	if (!intel_connector->panel.fixed_mode) {
+		DRM_DEBUG_KMS("no fixed mode\n");
+		return 0;
+	}
+
+	mode = drm_mode_duplicate(connector->dev,
+				  intel_connector->panel.fixed_mode);
+	if (!mode) {
+		DRM_DEBUG_KMS("drm_mode_duplicate failed\n");
+		return 0;
+	}
+
+	drm_mode_probed_add(connector, mode);
+	return 1;
+}
+
+static int intel_dsi_set_property(struct drm_connector *connector,
+				  struct drm_property *property,
+				  uint64_t val)
+{
+	struct drm_device *dev = connector->dev;
+	struct intel_connector *intel_connector = to_intel_connector(connector);
+	struct drm_crtc *crtc;
+	int ret;
+
+	ret = drm_object_property_set_value(&connector->base, property, val);
+	if (ret)
+		return ret;
+
+	if (property == dev->mode_config.scaling_mode_property) {
+		if (val == DRM_MODE_SCALE_NONE) {
+			DRM_DEBUG_KMS("no scaling not supported\n");
+			return -EINVAL;
+		}
+		if (HAS_GMCH_DISPLAY(dev) &&
+		    val == DRM_MODE_SCALE_CENTER) {
+			DRM_DEBUG_KMS("centering not supported\n");
+			return -EINVAL;
+		}
+
+		if (intel_connector->panel.fitting_mode == val)
+			return 0;
+
+		intel_connector->panel.fitting_mode = val;
+	}
+
+	crtc = intel_attached_encoder(connector)->base.crtc;
+	if (crtc && crtc->state->enable) {
+		/*
+		 * If the CRTC is enabled, the display will be changed
+		 * according to the new panel fitting mode.
+		 */
+		intel_crtc_restore_mode(crtc);
+	}
+
+	return 0;
+}
+
+static void intel_dsi_connector_destroy(struct drm_connector *connector)
+{
+	struct intel_connector *intel_connector = to_intel_connector(connector);
+
+	DRM_DEBUG_KMS("\n");
+	intel_panel_fini(&intel_connector->panel);
+	drm_connector_cleanup(connector);
+	kfree(connector);
+}
+
+static void intel_dsi_encoder_destroy(struct drm_encoder *encoder)
+{
+	struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder);
+
+	if (intel_dsi->panel) {
+		drm_panel_detach(intel_dsi->panel);
+		/* XXX: Logically this call belongs in the panel driver. */
+		drm_panel_remove(intel_dsi->panel);
+	}
+
+	/* dispose of the gpios */
+	if (intel_dsi->gpio_panel)
+		gpiod_put(intel_dsi->gpio_panel);
+
+	intel_encoder_destroy(encoder);
+}
+
+static const struct drm_encoder_funcs intel_dsi_funcs = {
+	.destroy = intel_dsi_encoder_destroy,
+};
+
+static const struct drm_connector_helper_funcs intel_dsi_connector_helper_funcs = {
+	.get_modes = intel_dsi_get_modes,
+	.mode_valid = intel_dsi_mode_valid,
+	.best_encoder = intel_best_encoder,
+};
+
+static const struct drm_connector_funcs intel_dsi_connector_funcs = {
+	.dpms = drm_atomic_helper_connector_dpms,
+	.detect = intel_dsi_detect,
+	.destroy = intel_dsi_connector_destroy,
+	.fill_modes = drm_helper_probe_single_connector_modes,
+	.set_property = intel_dsi_set_property,
+	.atomic_get_property = intel_connector_atomic_get_property,
+	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
+	.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
+};
+
+static void intel_dsi_add_properties(struct intel_connector *connector)
+{
+	struct drm_device *dev = connector->base.dev;
+
+	if (connector->panel.fixed_mode) {
+		drm_mode_create_scaling_mode_property(dev);
+		drm_object_attach_property(&connector->base.base,
+					   dev->mode_config.scaling_mode_property,
+					   DRM_MODE_SCALE_ASPECT);
+		connector->panel.fitting_mode = DRM_MODE_SCALE_ASPECT;
+	}
+}
+
+void intel_dsi_init(struct drm_device *dev)
+{
+	struct intel_dsi *intel_dsi;
+	struct intel_encoder *intel_encoder;
+	struct drm_encoder *encoder;
+	struct intel_connector *intel_connector;
+	struct drm_connector *connector;
+	struct drm_display_mode *scan, *fixed_mode = NULL;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	enum port port;
+	unsigned int i;
+
+	DRM_DEBUG_KMS("\n");
+
+	/* There is no detection method for MIPI so rely on VBT */
+	if (!intel_bios_is_dsi_present(dev_priv, &port))
+		return;
+
+	if (IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev)) {
+		dev_priv->mipi_mmio_base = VLV_MIPI_BASE;
+	} else if (IS_BROXTON(dev)) {
+		dev_priv->mipi_mmio_base = BXT_MIPI_BASE;
+	} else {
+		DRM_ERROR("Unsupported Mipi device to reg base");
+		return;
+	}
+
+	intel_dsi = kzalloc(sizeof(*intel_dsi), GFP_KERNEL);
+	if (!intel_dsi)
+		return;
+
+	intel_connector = intel_connector_alloc();
+	if (!intel_connector) {
+		kfree(intel_dsi);
+		return;
+	}
+
+	intel_encoder = &intel_dsi->base;
+	encoder = &intel_encoder->base;
+	intel_dsi->attached_connector = intel_connector;
+
+	connector = &intel_connector->base;
+
+	drm_encoder_init(dev, encoder, &intel_dsi_funcs, DRM_MODE_ENCODER_DSI);
+
+	intel_encoder->compute_config = intel_dsi_compute_config;
+	intel_encoder->pre_enable = intel_dsi_pre_enable;
+	intel_encoder->enable = intel_dsi_enable_nop;
+	intel_encoder->disable = intel_dsi_pre_disable;
+	intel_encoder->post_disable = intel_dsi_post_disable;
+	intel_encoder->get_hw_state = intel_dsi_get_hw_state;
+	intel_encoder->get_config = intel_dsi_get_config;
+
+	intel_connector->get_hw_state = intel_connector_get_hw_state;
+	intel_connector->unregister = intel_connector_unregister;
+
+	/*
+	 * On BYT/CHV, pipe A maps to MIPI DSI port A, pipe B maps to MIPI DSI
+	 * port C. BXT isn't limited like this.
+	 */
+	if (IS_BROXTON(dev_priv))
+		intel_encoder->crtc_mask = BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C);
+	else if (port == PORT_A)
+		intel_encoder->crtc_mask = BIT(PIPE_A);
+	else
+		intel_encoder->crtc_mask = BIT(PIPE_B);
+
+	if (dev_priv->vbt.dsi.config->dual_link)
+		intel_dsi->ports = BIT(PORT_A) | BIT(PORT_C);
+	else
+		intel_dsi->ports = BIT(port);
+
+	/* Create a DSI host (and a device) for each port. */
+	for_each_dsi_port(port, intel_dsi->ports) {
+		struct intel_dsi_host *host;
+
+		host = intel_dsi_host_init(intel_dsi, port);
+		if (!host)
+			goto err;
+
+		intel_dsi->dsi_hosts[port] = host;
+	}
+
+	for (i = 0; i < ARRAY_SIZE(intel_dsi_drivers); i++) {
+		intel_dsi->panel = intel_dsi_drivers[i].init(intel_dsi,
+							     intel_dsi_drivers[i].panel_id);
+		if (intel_dsi->panel)
+			break;
+	}
+
+	if (!intel_dsi->panel) {
+		DRM_DEBUG_KMS("no device found\n");
+		goto err;
+	}
+
+	/*
+	 * In case of BYT with CRC PMIC, we need to use GPIO for
+	 * Panel control.
+	 */
+	if (dev_priv->vbt.dsi.config->pwm_blc == PPS_BLC_PMIC) {
+		intel_dsi->gpio_panel =
+			gpiod_get(dev->dev, "panel", GPIOD_OUT_HIGH);
+
+		if (IS_ERR(intel_dsi->gpio_panel)) {
+			DRM_ERROR("Failed to own gpio for panel control\n");
+			intel_dsi->gpio_panel = NULL;
+		}
+	}
+
+	intel_encoder->type = INTEL_OUTPUT_DSI;
+	intel_encoder->cloneable = 0;
+	drm_connector_init(dev, connector, &intel_dsi_connector_funcs,
+			   DRM_MODE_CONNECTOR_DSI);
+
+	drm_connector_helper_add(connector, &intel_dsi_connector_helper_funcs);
+
+	connector->display_info.subpixel_order = SubPixelHorizontalRGB; /*XXX*/
+	connector->interlace_allowed = false;
+	connector->doublescan_allowed = false;
+
+	intel_connector_attach_encoder(intel_connector, intel_encoder);
+
+	drm_panel_attach(intel_dsi->panel, connector);
+
+	mutex_lock(&dev->mode_config.mutex);
+	drm_panel_get_modes(intel_dsi->panel);
+	list_for_each_entry(scan, &connector->probed_modes, head) {
+		if ((scan->type & DRM_MODE_TYPE_PREFERRED)) {
+			fixed_mode = drm_mode_duplicate(dev, scan);
+			break;
+		}
+	}
+	mutex_unlock(&dev->mode_config.mutex);
+
+	if (!fixed_mode) {
+		DRM_DEBUG_KMS("no fixed mode\n");
+		goto err;
+	}
+
+	connector->display_info.width_mm = fixed_mode->width_mm;
+	connector->display_info.height_mm = fixed_mode->height_mm;
+
+	intel_panel_init(&intel_connector->panel, fixed_mode, NULL);
+
+	intel_dsi_add_properties(intel_connector);
+
+	drm_connector_register(connector);
+
+	intel_panel_setup_backlight(connector, INVALID_PIPE);
+
+	return;
+
+err:
+	drm_encoder_cleanup(&intel_encoder->base);
+	kfree(intel_dsi);
+	kfree(intel_connector);
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/i915/intel_dsi.h
@@ -0,0 +1,143 @@
+/*
+ * Copyright © 2013 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef _INTEL_DSI_H
+#define _INTEL_DSI_H
+
+#include <drm/drmP.h>
+#include <drm/drm_crtc.h>
+#include <drm/drm_mipi_dsi.h>
+#include "intel_drv.h"
+
+/* Dual Link support */
+#define DSI_DUAL_LINK_NONE		0
+#define DSI_DUAL_LINK_FRONT_BACK	1
+#define DSI_DUAL_LINK_PIXEL_ALT		2
+
+struct intel_dsi_host;
+
+struct intel_dsi {
+	struct intel_encoder base;
+
+	struct drm_panel *panel;
+	struct intel_dsi_host *dsi_hosts[I915_MAX_PORTS];
+
+	/* GPIO Desc for CRC based Panel control */
+	struct gpio_desc *gpio_panel;
+
+	struct intel_connector *attached_connector;
+
+	/* bit mask of ports being driven */
+	u16 ports;
+
+	/* if true, use HS mode, otherwise LP */
+	bool hs;
+
+	/* virtual channel */
+	int channel;
+
+	/* Video mode or command mode */
+	u16 operation_mode;
+
+	/* number of DSI lanes */
+	unsigned int lane_count;
+
+	/*
+	 * video mode pixel format
+	 *
+	 * XXX: consolidate on .format in struct mipi_dsi_device.
+	 */
+	enum mipi_dsi_pixel_format pixel_format;
+
+	/* video mode format for MIPI_VIDEO_MODE_FORMAT register */
+	u32 video_mode_format;
+
+	/* eot for MIPI_EOT_DISABLE register */
+	u8 eotp_pkt;
+	u8 clock_stop;
+
+	u8 escape_clk_div;
+	u8 dual_link;
+	u8 pixel_overlap;
+	u32 port_bits;
+	u32 bw_timer;
+	u32 dphy_reg;
+	u32 video_frmt_cfg_bits;
+	u16 lp_byte_clk;
+
+	/* timeouts in byte clocks */
+	u16 lp_rx_timeout;
+	u16 turn_arnd_val;
+	u16 rst_timer_val;
+	u16 hs_to_lp_count;
+	u16 clk_lp_to_hs_count;
+	u16 clk_hs_to_lp_count;
+
+	u16 init_count;
+	u32 pclk;
+	u16 burst_mode_ratio;
+
+	/* all delays in ms */
+	u16 backlight_off_delay;
+	u16 backlight_on_delay;
+	u16 panel_on_delay;
+	u16 panel_off_delay;
+	u16 panel_pwr_cycle_delay;
+};
+
+struct intel_dsi_host {
+	struct mipi_dsi_host base;
+	struct intel_dsi *intel_dsi;
+	enum port port;
+
+	/* our little hack */
+	struct mipi_dsi_device *device;
+};
+
+static inline struct intel_dsi_host *to_intel_dsi_host(struct mipi_dsi_host *h)
+{
+	return container_of(h, struct intel_dsi_host, base);
+}
+
+#define for_each_dsi_port(__port, __ports_mask) for_each_port_masked(__port, __ports_mask)
+
+static inline struct intel_dsi *enc_to_intel_dsi(struct drm_encoder *encoder)
+{
+	return container_of(encoder, struct intel_dsi, base.base);
+}
+
+bool intel_dsi_pll_is_enabled(struct drm_i915_private *dev_priv);
+int intel_compute_dsi_pll(struct intel_encoder *encoder,
+			  struct intel_crtc_state *config);
+void intel_enable_dsi_pll(struct intel_encoder *encoder,
+			  const struct intel_crtc_state *config);
+void intel_disable_dsi_pll(struct intel_encoder *encoder);
+u32 intel_dsi_get_pclk(struct intel_encoder *encoder, int pipe_bpp,
+		       struct intel_crtc_state *config);
+void intel_dsi_reset_clocks(struct intel_encoder *encoder,
+			    enum port port);
+
+struct drm_panel *vbt_panel_init(struct intel_dsi *intel_dsi, u16 panel_id);
+enum mipi_dsi_pixel_format pixel_format_from_register_bits(u32 fmt);
+
+#endif /* _INTEL_DSI_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/i915/intel_dsi_panel_vbt.c
@@ -0,0 +1,722 @@
+/*
+ * Copyright © 2014 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Author: Shobhit Kumar <shobhit.kumar@intel.com>
+ *
+ */
+
+#include <drm/drmP.h>
+#include <drm/drm_crtc.h>
+#include <drm/drm_edid.h>
+#include <drm/i915_drm.h>
+#include <drm/drm_panel.h>
+#include <linux/slab.h>
+#include <video/mipi_display.h>
+#include <asm/intel-mid.h>
+#include <video/mipi_display.h>
+#include "i915_drv.h"
+#include "intel_drv.h"
+#include "intel_dsi.h"
+
+struct vbt_panel {
+	struct drm_panel panel;
+	struct intel_dsi *intel_dsi;
+};
+
+static inline struct vbt_panel *to_vbt_panel(struct drm_panel *panel)
+{
+	return container_of(panel, struct vbt_panel, panel);
+}
+
+#define MIPI_TRANSFER_MODE_SHIFT	0
+#define MIPI_VIRTUAL_CHANNEL_SHIFT	1
+#define MIPI_PORT_SHIFT			3
+
+#define PREPARE_CNT_MAX		0x3F
+#define EXIT_ZERO_CNT_MAX	0x3F
+#define CLK_ZERO_CNT_MAX	0xFF
+#define TRAIL_CNT_MAX		0x1F
+
+#define NS_KHZ_RATIO 1000000
+
+/* base offsets for gpio pads */
+#define VLV_GPIO_NC_0_HV_DDI0_HPD	0x4130
+#define VLV_GPIO_NC_1_HV_DDI0_DDC_SDA	0x4120
+#define VLV_GPIO_NC_2_HV_DDI0_DDC_SCL	0x4110
+#define VLV_GPIO_NC_3_PANEL0_VDDEN	0x4140
+#define VLV_GPIO_NC_4_PANEL0_BKLTEN	0x4150
+#define VLV_GPIO_NC_5_PANEL0_BKLTCTL	0x4160
+#define VLV_GPIO_NC_6_HV_DDI1_HPD	0x4180
+#define VLV_GPIO_NC_7_HV_DDI1_DDC_SDA	0x4190
+#define VLV_GPIO_NC_8_HV_DDI1_DDC_SCL	0x4170
+#define VLV_GPIO_NC_9_PANEL1_VDDEN	0x4100
+#define VLV_GPIO_NC_10_PANEL1_BKLTEN	0x40E0
+#define VLV_GPIO_NC_11_PANEL1_BKLTCTL	0x40F0
+
+#define VLV_GPIO_PCONF0(base_offset)	(base_offset)
+#define VLV_GPIO_PAD_VAL(base_offset)	((base_offset) + 8)
+
+struct gpio_map {
+	u16 base_offset;
+	bool init;
+};
+
+static struct gpio_map vlv_gpio_table[] = {
+	{ VLV_GPIO_NC_0_HV_DDI0_HPD },
+	{ VLV_GPIO_NC_1_HV_DDI0_DDC_SDA },
+	{ VLV_GPIO_NC_2_HV_DDI0_DDC_SCL },
+	{ VLV_GPIO_NC_3_PANEL0_VDDEN },
+	{ VLV_GPIO_NC_4_PANEL0_BKLTEN },
+	{ VLV_GPIO_NC_5_PANEL0_BKLTCTL },
+	{ VLV_GPIO_NC_6_HV_DDI1_HPD },
+	{ VLV_GPIO_NC_7_HV_DDI1_DDC_SDA },
+	{ VLV_GPIO_NC_8_HV_DDI1_DDC_SCL },
+	{ VLV_GPIO_NC_9_PANEL1_VDDEN },
+	{ VLV_GPIO_NC_10_PANEL1_BKLTEN },
+	{ VLV_GPIO_NC_11_PANEL1_BKLTCTL },
+};
+
+static inline enum port intel_dsi_seq_port_to_port(u8 port)
+{
+	return port ? PORT_C : PORT_A;
+}
+
+static const u8 *mipi_exec_send_packet(struct intel_dsi *intel_dsi,
+				       const u8 *data)
+{
+	struct mipi_dsi_device *dsi_device;
+	u8 type, flags, seq_port;
+	u16 len;
+	enum port port;
+
+	flags = *data++;
+	type = *data++;
+
+	len = *((u16 *) data);
+	data += 2;
+
+	seq_port = (flags >> MIPI_PORT_SHIFT) & 3;
+
+	/* For DSI single link on Port A & C, the seq_port value which is
+	 * parsed from Sequence Block#53 of VBT has been set to 0
+	 * Now, read/write of packets for the DSI single link on Port A and
+	 * Port C will based on the DVO port from VBT block 2.
+	 */
+	if (intel_dsi->ports == (1 << PORT_C))
+		port = PORT_C;
+	else
+		port = intel_dsi_seq_port_to_port(seq_port);
+
+	dsi_device = intel_dsi->dsi_hosts[port]->device;
+	if (!dsi_device) {
+		DRM_DEBUG_KMS("no dsi device for port %c\n", port_name(port));
+		goto out;
+	}
+
+	if ((flags >> MIPI_TRANSFER_MODE_SHIFT) & 1)
+		dsi_device->mode_flags &= ~MIPI_DSI_MODE_LPM;
+	else
+		dsi_device->mode_flags |= MIPI_DSI_MODE_LPM;
+
+	dsi_device->channel = (flags >> MIPI_VIRTUAL_CHANNEL_SHIFT) & 3;
+
+	switch (type) {
+	case MIPI_DSI_GENERIC_SHORT_WRITE_0_PARAM:
+		mipi_dsi_generic_write(dsi_device, NULL, 0);
+		break;
+	case MIPI_DSI_GENERIC_SHORT_WRITE_1_PARAM:
+		mipi_dsi_generic_write(dsi_device, data, 1);
+		break;
+	case MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM:
+		mipi_dsi_generic_write(dsi_device, data, 2);
+		break;
+	case MIPI_DSI_GENERIC_READ_REQUEST_0_PARAM:
+	case MIPI_DSI_GENERIC_READ_REQUEST_1_PARAM:
+	case MIPI_DSI_GENERIC_READ_REQUEST_2_PARAM:
+		DRM_DEBUG_DRIVER("Generic Read not yet implemented or used\n");
+		break;
+	case MIPI_DSI_GENERIC_LONG_WRITE:
+		mipi_dsi_generic_write(dsi_device, data, len);
+		break;
+	case MIPI_DSI_DCS_SHORT_WRITE:
+		mipi_dsi_dcs_write_buffer(dsi_device, data, 1);
+		break;
+	case MIPI_DSI_DCS_SHORT_WRITE_PARAM:
+		mipi_dsi_dcs_write_buffer(dsi_device, data, 2);
+		break;
+	case MIPI_DSI_DCS_READ:
+		DRM_DEBUG_DRIVER("DCS Read not yet implemented or used\n");
+		break;
+	case MIPI_DSI_DCS_LONG_WRITE:
+		mipi_dsi_dcs_write_buffer(dsi_device, data, len);
+		break;
+	}
+
+out:
+	data += len;
+
+	return data;
+}
+
+static const u8 *mipi_exec_delay(struct intel_dsi *intel_dsi, const u8 *data)
+{
+	u32 delay = *((const u32 *) data);
+
+	usleep_range(delay, delay + 10);
+	data += 4;
+
+	return data;
+}
+
+static void vlv_exec_gpio(struct drm_i915_private *dev_priv,
+			  u8 gpio_source, u8 gpio_index, bool value)
+{
+	struct gpio_map *map;
+	u16 pconf0, padval;
+	u32 tmp;
+	u8 port;
+
+	if (gpio_index >= ARRAY_SIZE(vlv_gpio_table)) {
+		DRM_DEBUG_KMS("unknown gpio index %u\n", gpio_index);
+		return;
+	}
+
+	map = &vlv_gpio_table[gpio_index];
+
+	if (dev_priv->vbt.dsi.seq_version >= 3) {
+		DRM_DEBUG_KMS("GPIO element v3 not supported\n");
+		return;
+	} else {
+		if (gpio_source == 0) {
+			port = IOSF_PORT_GPIO_NC;
+		} else if (gpio_source == 1) {
+			port = IOSF_PORT_GPIO_SC;
+		} else {
+			DRM_DEBUG_KMS("unknown gpio source %u\n", gpio_source);
+			return;
+		}
+	}
+
+	pconf0 = VLV_GPIO_PCONF0(map->base_offset);
+	padval = VLV_GPIO_PAD_VAL(map->base_offset);
+
+	mutex_lock(&dev_priv->sb_lock);
+	if (!map->init) {
+		/* FIXME: remove constant below */
+		vlv_iosf_sb_write(dev_priv, port, pconf0, 0x2000CC00);
+		map->init = true;
+	}
+
+	tmp = 0x4 | value;
+	vlv_iosf_sb_write(dev_priv, port, padval, tmp);
+	mutex_unlock(&dev_priv->sb_lock);
+}
+
+static const u8 *mipi_exec_gpio(struct intel_dsi *intel_dsi, const u8 *data)
+{
+	struct drm_device *dev = intel_dsi->base.base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	u8 gpio_source, gpio_index;
+	bool value;
+
+	if (dev_priv->vbt.dsi.seq_version >= 3)
+		data++;
+
+	gpio_index = *data++;
+
+	/* gpio source in sequence v2 only */
+	if (dev_priv->vbt.dsi.seq_version == 2)
+		gpio_source = (*data >> 1) & 3;
+	else
+		gpio_source = 0;
+
+	/* pull up/down */
+	value = *data++ & 1;
+
+	if (IS_VALLEYVIEW(dev_priv))
+		vlv_exec_gpio(dev_priv, gpio_source, gpio_index, value);
+	else
+		DRM_DEBUG_KMS("GPIO element not supported on this platform\n");
+
+	return data;
+}
+
+static const u8 *mipi_exec_i2c_skip(struct intel_dsi *intel_dsi, const u8 *data)
+{
+	return data + *(data + 6) + 7;
+}
+
+typedef const u8 * (*fn_mipi_elem_exec)(struct intel_dsi *intel_dsi,
+					const u8 *data);
+static const fn_mipi_elem_exec exec_elem[] = {
+	[MIPI_SEQ_ELEM_SEND_PKT] = mipi_exec_send_packet,
+	[MIPI_SEQ_ELEM_DELAY] = mipi_exec_delay,
+	[MIPI_SEQ_ELEM_GPIO] = mipi_exec_gpio,
+	[MIPI_SEQ_ELEM_I2C] = mipi_exec_i2c_skip,
+};
+
+/*
+ * MIPI Sequence from VBT #53 parsing logic
+ * We have already separated each seqence during bios parsing
+ * Following is generic execution function for any sequence
+ */
+
+static const char * const seq_name[] = {
+	[MIPI_SEQ_ASSERT_RESET] = "MIPI_SEQ_ASSERT_RESET",
+	[MIPI_SEQ_INIT_OTP] = "MIPI_SEQ_INIT_OTP",
+	[MIPI_SEQ_DISPLAY_ON] = "MIPI_SEQ_DISPLAY_ON",
+	[MIPI_SEQ_DISPLAY_OFF]  = "MIPI_SEQ_DISPLAY_OFF",
+	[MIPI_SEQ_DEASSERT_RESET] = "MIPI_SEQ_DEASSERT_RESET",
+	[MIPI_SEQ_BACKLIGHT_ON] = "MIPI_SEQ_BACKLIGHT_ON",
+	[MIPI_SEQ_BACKLIGHT_OFF] = "MIPI_SEQ_BACKLIGHT_OFF",
+	[MIPI_SEQ_TEAR_ON] = "MIPI_SEQ_TEAR_ON",
+	[MIPI_SEQ_TEAR_OFF] = "MIPI_SEQ_TEAR_OFF",
+	[MIPI_SEQ_POWER_ON] = "MIPI_SEQ_POWER_ON",
+	[MIPI_SEQ_POWER_OFF] = "MIPI_SEQ_POWER_OFF",
+};
+
+static const char *sequence_name(enum mipi_seq seq_id)
+{
+	if (seq_id < ARRAY_SIZE(seq_name) && seq_name[seq_id])
+		return seq_name[seq_id];
+	else
+		return "(unknown)";
+}
+
+static void generic_exec_sequence(struct drm_panel *panel, enum mipi_seq seq_id)
+{
+	struct vbt_panel *vbt_panel = to_vbt_panel(panel);
+	struct intel_dsi *intel_dsi = vbt_panel->intel_dsi;
+	struct drm_i915_private *dev_priv = to_i915(intel_dsi->base.base.dev);
+	const u8 *data;
+	fn_mipi_elem_exec mipi_elem_exec;
+
+	if (WARN_ON(seq_id >= ARRAY_SIZE(dev_priv->vbt.dsi.sequence)))
+		return;
+
+	data = dev_priv->vbt.dsi.sequence[seq_id];
+	if (!data) {
+		DRM_DEBUG_KMS("MIPI sequence %d - %s not available\n",
+			      seq_id, sequence_name(seq_id));
+		return;
+	}
+
+	WARN_ON(*data != seq_id);
+
+	DRM_DEBUG_KMS("Starting MIPI sequence %d - %s\n",
+		      seq_id, sequence_name(seq_id));
+
+	/* Skip Sequence Byte. */
+	data++;
+
+	/* Skip Size of Sequence. */
+	if (dev_priv->vbt.dsi.seq_version >= 3)
+		data += 4;
+
+	while (1) {
+		u8 operation_byte = *data++;
+		u8 operation_size = 0;
+
+		if (operation_byte == MIPI_SEQ_ELEM_END)
+			break;
+
+		if (operation_byte < ARRAY_SIZE(exec_elem))
+			mipi_elem_exec = exec_elem[operation_byte];
+		else
+			mipi_elem_exec = NULL;
+
+		/* Size of Operation. */
+		if (dev_priv->vbt.dsi.seq_version >= 3)
+			operation_size = *data++;
+
+		if (mipi_elem_exec) {
+			data = mipi_elem_exec(intel_dsi, data);
+		} else if (operation_size) {
+			/* We have size, skip. */
+			DRM_DEBUG_KMS("Unsupported MIPI operation byte %u\n",
+				      operation_byte);
+			data += operation_size;
+		} else {
+			/* No size, can't skip without parsing. */
+			DRM_ERROR("Unsupported MIPI operation byte %u\n",
+				  operation_byte);
+			return;
+		}
+	}
+}
+
+static int vbt_panel_prepare(struct drm_panel *panel)
+{
+	generic_exec_sequence(panel, MIPI_SEQ_ASSERT_RESET);
+	generic_exec_sequence(panel, MIPI_SEQ_INIT_OTP);
+
+	return 0;
+}
+
+static int vbt_panel_unprepare(struct drm_panel *panel)
+{
+	generic_exec_sequence(panel, MIPI_SEQ_DEASSERT_RESET);
+
+	return 0;
+}
+
+static int vbt_panel_enable(struct drm_panel *panel)
+{
+	generic_exec_sequence(panel, MIPI_SEQ_DISPLAY_ON);
+
+	return 0;
+}
+
+static int vbt_panel_disable(struct drm_panel *panel)
+{
+	generic_exec_sequence(panel, MIPI_SEQ_DISPLAY_OFF);
+
+	return 0;
+}
+
+static int vbt_panel_get_modes(struct drm_panel *panel)
+{
+	struct vbt_panel *vbt_panel = to_vbt_panel(panel);
+	struct intel_dsi *intel_dsi = vbt_panel->intel_dsi;
+	struct drm_device *dev = intel_dsi->base.base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct drm_display_mode *mode;
+
+	if (!panel->connector)
+		return 0;
+
+	mode = drm_mode_duplicate(dev, dev_priv->vbt.lfp_lvds_vbt_mode);
+	if (!mode)
+		return 0;
+
+	mode->type |= DRM_MODE_TYPE_PREFERRED;
+
+	drm_mode_probed_add(panel->connector, mode);
+
+	return 1;
+}
+
+static const struct drm_panel_funcs vbt_panel_funcs = {
+	.disable = vbt_panel_disable,
+	.unprepare = vbt_panel_unprepare,
+	.prepare = vbt_panel_prepare,
+	.enable = vbt_panel_enable,
+	.get_modes = vbt_panel_get_modes,
+};
+
+struct drm_panel *vbt_panel_init(struct intel_dsi *intel_dsi, u16 panel_id)
+{
+	struct drm_device *dev = intel_dsi->base.base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct mipi_config *mipi_config = dev_priv->vbt.dsi.config;
+	struct mipi_pps_data *pps = dev_priv->vbt.dsi.pps;
+	struct drm_display_mode *mode = dev_priv->vbt.lfp_lvds_vbt_mode;
+	struct vbt_panel *vbt_panel;
+	u32 bpp;
+	u32 tlpx_ns, extra_byte_count, bitrate, tlpx_ui;
+	u32 ui_num, ui_den;
+	u32 prepare_cnt, exit_zero_cnt, clk_zero_cnt, trail_cnt;
+	u32 ths_prepare_ns, tclk_trail_ns;
+	u32 tclk_prepare_clkzero, ths_prepare_hszero;
+	u32 lp_to_hs_switch, hs_to_lp_switch;
+	u32 pclk, computed_ddr;
+	u16 burst_mode_ratio;
+	enum port port;
+
+	DRM_DEBUG_KMS("\n");
+
+	intel_dsi->eotp_pkt = mipi_config->eot_pkt_disabled ? 0 : 1;
+	intel_dsi->clock_stop = mipi_config->enable_clk_stop ? 1 : 0;
+	intel_dsi->lane_count = mipi_config->lane_cnt + 1;
+	intel_dsi->pixel_format =
+			pixel_format_from_register_bits(
+				mipi_config->videomode_color_format << 7);
+	bpp = mipi_dsi_pixel_format_to_bpp(intel_dsi->pixel_format);
+
+	intel_dsi->dual_link = mipi_config->dual_link;
+	intel_dsi->pixel_overlap = mipi_config->pixel_overlap;
+	intel_dsi->operation_mode = mipi_config->is_cmd_mode;
+	intel_dsi->video_mode_format = mipi_config->video_transfer_mode;
+	intel_dsi->escape_clk_div = mipi_config->byte_clk_sel;
+	intel_dsi->lp_rx_timeout = mipi_config->lp_rx_timeout;
+	intel_dsi->turn_arnd_val = mipi_config->turn_around_timeout;
+	intel_dsi->rst_timer_val = mipi_config->device_reset_timer;
+	intel_dsi->init_count = mipi_config->master_init_timer;
+	intel_dsi->bw_timer = mipi_config->dbi_bw_timer;
+	intel_dsi->video_frmt_cfg_bits =
+		mipi_config->bta_enabled ? DISABLE_VIDEO_BTA : 0;
+
+	pclk = mode->clock;
+
+	/* In dual link mode each port needs half of pixel clock */
+	if (intel_dsi->dual_link) {
+		pclk = pclk / 2;
+
+		/* we can enable pixel_overlap if needed by panel. In this
+		 * case we need to increase the pixelclock for extra pixels
+		 */
+		if (intel_dsi->dual_link == DSI_DUAL_LINK_FRONT_BACK) {
+			pclk += DIV_ROUND_UP(mode->vtotal *
+						intel_dsi->pixel_overlap *
+						60, 1000);
+		}
+	}
+
+	/* Burst Mode Ratio
+	 * Target ddr frequency from VBT / non burst ddr freq
+	 * multiply by 100 to preserve remainder
+	 */
+	if (intel_dsi->video_mode_format == VIDEO_MODE_BURST) {
+		if (mipi_config->target_burst_mode_freq) {
+			computed_ddr = (pclk * bpp) / intel_dsi->lane_count;
+
+			if (mipi_config->target_burst_mode_freq <
+								computed_ddr) {
+				DRM_ERROR("Burst mode freq is less than computed\n");
+				return NULL;
+			}
+
+			burst_mode_ratio = DIV_ROUND_UP(
+				mipi_config->target_burst_mode_freq * 100,
+				computed_ddr);
+
+			pclk = DIV_ROUND_UP(pclk * burst_mode_ratio, 100);
+		} else {
+			DRM_ERROR("Burst mode target is not set\n");
+			return NULL;
+		}
+	} else
+		burst_mode_ratio = 100;
+
+	intel_dsi->burst_mode_ratio = burst_mode_ratio;
+	intel_dsi->pclk = pclk;
+
+	bitrate = (pclk * bpp) / intel_dsi->lane_count;
+
+	switch (intel_dsi->escape_clk_div) {
+	case 0:
+		tlpx_ns = 50;
+		break;
+	case 1:
+		tlpx_ns = 100;
+		break;
+
+	case 2:
+		tlpx_ns = 200;
+		break;
+	default:
+		tlpx_ns = 50;
+		break;
+	}
+
+	switch (intel_dsi->lane_count) {
+	case 1:
+	case 2:
+		extra_byte_count = 2;
+		break;
+	case 3:
+		extra_byte_count = 4;
+		break;
+	case 4:
+	default:
+		extra_byte_count = 3;
+		break;
+	}
+
+	/*
+	 * ui(s) = 1/f [f in hz]
+	 * ui(ns) = 10^9 / (f*10^6) [f in Mhz] -> 10^3/f(Mhz)
+	 */
+
+	/* in Kbps */
+	ui_num = NS_KHZ_RATIO;
+	ui_den = bitrate;
+
+	tclk_prepare_clkzero = mipi_config->tclk_prepare_clkzero;
+	ths_prepare_hszero = mipi_config->ths_prepare_hszero;
+
+	/*
+	 * B060
+	 * LP byte clock = TLPX/ (8UI)
+	 */
+	intel_dsi->lp_byte_clk = DIV_ROUND_UP(tlpx_ns * ui_den, 8 * ui_num);
+
+	/* count values in UI = (ns value) * (bitrate / (2 * 10^6))
+	 *
+	 * Since txddrclkhs_i is 2xUI, all the count values programmed in
+	 * DPHY param register are divided by 2
+	 *
+	 * prepare count
+	 */
+	ths_prepare_ns = max(mipi_config->ths_prepare,
+			     mipi_config->tclk_prepare);
+	prepare_cnt = DIV_ROUND_UP(ths_prepare_ns * ui_den, ui_num * 2);
+
+	/* exit zero count */
+	exit_zero_cnt = DIV_ROUND_UP(
+				(ths_prepare_hszero - ths_prepare_ns) * ui_den,
+				ui_num * 2
+				);
+
+	/*
+	 * Exit zero  is unified val ths_zero and ths_exit
+	 * minimum value for ths_exit = 110ns
+	 * min (exit_zero_cnt * 2) = 110/UI
+	 * exit_zero_cnt = 55/UI
+	 */
+	 if (exit_zero_cnt < (55 * ui_den / ui_num))
+		if ((55 * ui_den) % ui_num)
+			exit_zero_cnt += 1;
+
+	/* clk zero count */
+	clk_zero_cnt = DIV_ROUND_UP(
+			(tclk_prepare_clkzero -	ths_prepare_ns)
+			* ui_den, 2 * ui_num);
+
+	/* trail count */
+	tclk_trail_ns = max(mipi_config->tclk_trail, mipi_config->ths_trail);
+	trail_cnt = DIV_ROUND_UP(tclk_trail_ns * ui_den, 2 * ui_num);
+
+	if (prepare_cnt > PREPARE_CNT_MAX ||
+		exit_zero_cnt > EXIT_ZERO_CNT_MAX ||
+		clk_zero_cnt > CLK_ZERO_CNT_MAX ||
+		trail_cnt > TRAIL_CNT_MAX)
+		DRM_DEBUG_DRIVER("Values crossing maximum limits, restricting to max values\n");
+
+	if (prepare_cnt > PREPARE_CNT_MAX)
+		prepare_cnt = PREPARE_CNT_MAX;
+
+	if (exit_zero_cnt > EXIT_ZERO_CNT_MAX)
+		exit_zero_cnt = EXIT_ZERO_CNT_MAX;
+
+	if (clk_zero_cnt > CLK_ZERO_CNT_MAX)
+		clk_zero_cnt = CLK_ZERO_CNT_MAX;
+
+	if (trail_cnt > TRAIL_CNT_MAX)
+		trail_cnt = TRAIL_CNT_MAX;
+
+	/* B080 */
+	intel_dsi->dphy_reg = exit_zero_cnt << 24 | trail_cnt << 16 |
+						clk_zero_cnt << 8 | prepare_cnt;
+
+	/*
+	 * LP to HS switch count = 4TLPX + PREP_COUNT * 2 + EXIT_ZERO_COUNT * 2
+	 *					+ 10UI + Extra Byte Count
+	 *
+	 * HS to LP switch count = THS-TRAIL + 2TLPX + Extra Byte Count
+	 * Extra Byte Count is calculated according to number of lanes.
+	 * High Low Switch Count is the Max of LP to HS and
+	 * HS to LP switch count
+	 *
+	 */
+	tlpx_ui = DIV_ROUND_UP(tlpx_ns * ui_den, ui_num);
+
+	/* B044 */
+	/* FIXME:
+	 * The comment above does not match with the code */
+	lp_to_hs_switch = DIV_ROUND_UP(4 * tlpx_ui + prepare_cnt * 2 +
+						exit_zero_cnt * 2 + 10, 8);
+
+	hs_to_lp_switch = DIV_ROUND_UP(mipi_config->ths_trail + 2 * tlpx_ui, 8);
+
+	intel_dsi->hs_to_lp_count = max(lp_to_hs_switch, hs_to_lp_switch);
+	intel_dsi->hs_to_lp_count += extra_byte_count;
+
+	/* B088 */
+	/* LP -> HS for clock lanes
+	 * LP clk sync + LP11 + LP01 + tclk_prepare + tclk_zero +
+	 *						extra byte count
+	 * 2TPLX + 1TLPX + 1 TPLX(in ns) + prepare_cnt * 2 + clk_zero_cnt *
+	 *					2(in UI) + extra byte count
+	 * In byteclks = (4TLPX + prepare_cnt * 2 + clk_zero_cnt *2 (in UI)) /
+	 *					8 + extra byte count
+	 */
+	intel_dsi->clk_lp_to_hs_count =
+		DIV_ROUND_UP(
+			4 * tlpx_ui + prepare_cnt * 2 +
+			clk_zero_cnt * 2,
+			8);
+
+	intel_dsi->clk_lp_to_hs_count += extra_byte_count;
+
+	/* HS->LP for Clock Lanes
+	 * Low Power clock synchronisations + 1Tx byteclk + tclk_trail +
+	 *						Extra byte count
+	 * 2TLPX + 8UI + (trail_count*2)(in UI) + Extra byte count
+	 * In byteclks = (2*TLpx(in UI) + trail_count*2 +8)(in UI)/8 +
+	 *						Extra byte count
+	 */
+	intel_dsi->clk_hs_to_lp_count =
+		DIV_ROUND_UP(2 * tlpx_ui + trail_cnt * 2 + 8,
+			8);
+	intel_dsi->clk_hs_to_lp_count += extra_byte_count;
+
+	DRM_DEBUG_KMS("Eot %s\n", intel_dsi->eotp_pkt ? "enabled" : "disabled");
+	DRM_DEBUG_KMS("Clockstop %s\n", intel_dsi->clock_stop ?
+						"disabled" : "enabled");
+	DRM_DEBUG_KMS("Mode %s\n", intel_dsi->operation_mode ? "command" : "video");
+	if (intel_dsi->dual_link == DSI_DUAL_LINK_FRONT_BACK)
+		DRM_DEBUG_KMS("Dual link: DSI_DUAL_LINK_FRONT_BACK\n");
+	else if (intel_dsi->dual_link == DSI_DUAL_LINK_PIXEL_ALT)
+		DRM_DEBUG_KMS("Dual link: DSI_DUAL_LINK_PIXEL_ALT\n");
+	else
+		DRM_DEBUG_KMS("Dual link: NONE\n");
+	DRM_DEBUG_KMS("Pixel Format %d\n", intel_dsi->pixel_format);
+	DRM_DEBUG_KMS("TLPX %d\n", intel_dsi->escape_clk_div);
+	DRM_DEBUG_KMS("LP RX Timeout 0x%x\n", intel_dsi->lp_rx_timeout);
+	DRM_DEBUG_KMS("Turnaround Timeout 0x%x\n", intel_dsi->turn_arnd_val);
+	DRM_DEBUG_KMS("Init Count 0x%x\n", intel_dsi->init_count);
+	DRM_DEBUG_KMS("HS to LP Count 0x%x\n", intel_dsi->hs_to_lp_count);
+	DRM_DEBUG_KMS("LP Byte Clock %d\n", intel_dsi->lp_byte_clk);
+	DRM_DEBUG_KMS("DBI BW Timer 0x%x\n", intel_dsi->bw_timer);
+	DRM_DEBUG_KMS("LP to HS Clock Count 0x%x\n", intel_dsi->clk_lp_to_hs_count);
+	DRM_DEBUG_KMS("HS to LP Clock Count 0x%x\n", intel_dsi->clk_hs_to_lp_count);
+	DRM_DEBUG_KMS("BTA %s\n",
+			intel_dsi->video_frmt_cfg_bits & DISABLE_VIDEO_BTA ?
+			"disabled" : "enabled");
+
+	/* delays in VBT are in unit of 100us, so need to convert
+	 * here in ms
+	 * Delay (100us) * 100 /1000 = Delay / 10 (ms) */
+	intel_dsi->backlight_off_delay = pps->bl_disable_delay / 10;
+	intel_dsi->backlight_on_delay = pps->bl_enable_delay / 10;
+	intel_dsi->panel_on_delay = pps->panel_on_delay / 10;
+	intel_dsi->panel_off_delay = pps->panel_off_delay / 10;
+	intel_dsi->panel_pwr_cycle_delay = pps->panel_power_cycle_delay / 10;
+
+	/* This is cheating a bit with the cleanup. */
+	vbt_panel = devm_kzalloc(dev->dev, sizeof(*vbt_panel), GFP_KERNEL);
+	if (!vbt_panel)
+		return NULL;
+
+	vbt_panel->intel_dsi = intel_dsi;
+	drm_panel_init(&vbt_panel->panel);
+	vbt_panel->panel.funcs = &vbt_panel_funcs;
+	drm_panel_add(&vbt_panel->panel);
+
+	/* a regular driver would get the device in probe */
+	for_each_dsi_port(port, intel_dsi->ports) {
+		mipi_dsi_attach(intel_dsi->dsi_hosts[port]->device);
+	}
+
+	return &vbt_panel->panel;
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/i915/intel_dsi_pll.c
@@ -0,0 +1,565 @@
+/*
+ * Copyright © 2013 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *	Shobhit Kumar <shobhit.kumar@intel.com>
+ *	Yogesh Mohan Marimuthu <yogesh.mohan.marimuthu@intel.com>
+ */
+
+#include <linux/kernel.h>
+#include "intel_drv.h"
+#include "i915_drv.h"
+#include "intel_dsi.h"
+
+static const u16 lfsr_converts[] = {
+	426, 469, 234, 373, 442, 221, 110, 311, 411,		/* 62 - 70 */
+	461, 486, 243, 377, 188, 350, 175, 343, 427, 213,	/* 71 - 80 */
+	106, 53, 282, 397, 454, 227, 113, 56, 284, 142,		/* 81 - 90 */
+	71, 35, 273, 136, 324, 418, 465, 488, 500, 506		/* 91 - 100 */
+};
+
+/* Get DSI clock from pixel clock */
+static u32 dsi_clk_from_pclk(u32 pclk, enum mipi_dsi_pixel_format fmt,
+			     int lane_count)
+{
+	u32 dsi_clk_khz;
+	u32 bpp = mipi_dsi_pixel_format_to_bpp(fmt);
+
+	/* DSI data rate = pixel clock * bits per pixel / lane count
+	   pixel clock is converted from KHz to Hz */
+	dsi_clk_khz = DIV_ROUND_CLOSEST(pclk * bpp, lane_count);
+
+	return dsi_clk_khz;
+}
+
+static int dsi_calc_mnp(struct drm_i915_private *dev_priv,
+			struct intel_crtc_state *config,
+			int target_dsi_clk)
+{
+	unsigned int calc_m = 0, calc_p = 0;
+	unsigned int m_min, m_max, p_min = 2, p_max = 6;
+	unsigned int m, n, p;
+	int ref_clk;
+	int delta = target_dsi_clk;
+	u32 m_seed;
+
+	/* target_dsi_clk is expected in kHz */
+	if (target_dsi_clk < 300000 || target_dsi_clk > 1150000) {
+		DRM_ERROR("DSI CLK Out of Range\n");
+		return -ECHRNG;
+	}
+
+	if (IS_CHERRYVIEW(dev_priv)) {
+		ref_clk = 100000;
+		n = 4;
+		m_min = 70;
+		m_max = 96;
+	} else {
+		ref_clk = 25000;
+		n = 1;
+		m_min = 62;
+		m_max = 92;
+	}
+
+	for (m = m_min; m <= m_max && delta; m++) {
+		for (p = p_min; p <= p_max && delta; p++) {
+			/*
+			 * Find the optimal m and p divisors with minimal delta
+			 * +/- the required clock
+			 */
+			int calc_dsi_clk = (m * ref_clk) / (p * n);
+			int d = abs(target_dsi_clk - calc_dsi_clk);
+			if (d < delta) {
+				delta = d;
+				calc_m = m;
+				calc_p = p;
+			}
+		}
+	}
+
+	/* register has log2(N1), this works fine for powers of two */
+	n = ffs(n) - 1;
+	m_seed = lfsr_converts[calc_m - 62];
+	config->dsi_pll.ctrl = 1 << (DSI_PLL_P1_POST_DIV_SHIFT + calc_p - 2);
+	config->dsi_pll.div = n << DSI_PLL_N1_DIV_SHIFT |
+		m_seed << DSI_PLL_M1_DIV_SHIFT;
+
+	return 0;
+}
+
+/*
+ * XXX: The muxing and gating is hard coded for now. Need to add support for
+ * sharing PLLs with two DSI outputs.
+ */
+static int vlv_compute_dsi_pll(struct intel_encoder *encoder,
+			       struct intel_crtc_state *config)
+{
+	struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
+	struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
+	int ret;
+	u32 dsi_clk;
+
+	dsi_clk = dsi_clk_from_pclk(intel_dsi->pclk, intel_dsi->pixel_format,
+				    intel_dsi->lane_count);
+
+	ret = dsi_calc_mnp(dev_priv, config, dsi_clk);
+	if (ret) {
+		DRM_DEBUG_KMS("dsi_calc_mnp failed\n");
+		return ret;
+	}
+
+	if (intel_dsi->ports & (1 << PORT_A))
+		config->dsi_pll.ctrl |= DSI_PLL_CLK_GATE_DSI0_DSIPLL;
+
+	if (intel_dsi->ports & (1 << PORT_C))
+		config->dsi_pll.ctrl |= DSI_PLL_CLK_GATE_DSI1_DSIPLL;
+
+	config->dsi_pll.ctrl |= DSI_PLL_VCO_EN;
+
+	DRM_DEBUG_KMS("dsi pll div %08x, ctrl %08x\n",
+		      config->dsi_pll.div, config->dsi_pll.ctrl);
+
+	return 0;
+}
+
+static void vlv_enable_dsi_pll(struct intel_encoder *encoder,
+			       const struct intel_crtc_state *config)
+{
+	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
+
+	DRM_DEBUG_KMS("\n");
+
+	mutex_lock(&dev_priv->sb_lock);
+
+	vlv_cck_write(dev_priv, CCK_REG_DSI_PLL_CONTROL, 0);
+	vlv_cck_write(dev_priv, CCK_REG_DSI_PLL_DIVIDER, config->dsi_pll.div);
+	vlv_cck_write(dev_priv, CCK_REG_DSI_PLL_CONTROL,
+		      config->dsi_pll.ctrl & ~DSI_PLL_VCO_EN);
+
+	/* wait at least 0.5 us after ungating before enabling VCO */
+	usleep_range(1, 10);
+
+	vlv_cck_write(dev_priv, CCK_REG_DSI_PLL_CONTROL, config->dsi_pll.ctrl);
+
+	if (wait_for(vlv_cck_read(dev_priv, CCK_REG_DSI_PLL_CONTROL) &
+						DSI_PLL_LOCK, 20)) {
+
+		mutex_unlock(&dev_priv->sb_lock);
+		DRM_ERROR("DSI PLL lock failed\n");
+		return;
+	}
+	mutex_unlock(&dev_priv->sb_lock);
+
+	DRM_DEBUG_KMS("DSI PLL locked\n");
+}
+
+static void vlv_disable_dsi_pll(struct intel_encoder *encoder)
+{
+	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
+	u32 tmp;
+
+	DRM_DEBUG_KMS("\n");
+
+	mutex_lock(&dev_priv->sb_lock);
+
+	tmp = vlv_cck_read(dev_priv, CCK_REG_DSI_PLL_CONTROL);
+	tmp &= ~DSI_PLL_VCO_EN;
+	tmp |= DSI_PLL_LDO_GATE;
+	vlv_cck_write(dev_priv, CCK_REG_DSI_PLL_CONTROL, tmp);
+
+	mutex_unlock(&dev_priv->sb_lock);
+}
+
+static bool bxt_dsi_pll_is_enabled(struct drm_i915_private *dev_priv)
+{
+	bool enabled;
+	u32 val;
+	u32 mask;
+
+	mask = BXT_DSI_PLL_DO_ENABLE | BXT_DSI_PLL_LOCKED;
+	val = I915_READ(BXT_DSI_PLL_ENABLE);
+	enabled = (val & mask) == mask;
+
+	if (!enabled)
+		return false;
+
+	/*
+	 * Both dividers must be programmed with valid values even if only one
+	 * of the PLL is used, see BSpec/Broxton Clocks. Check this here for
+	 * paranoia, since BIOS is known to misconfigure PLLs in this way at
+	 * times, and since accessing DSI registers with invalid dividers
+	 * causes a system hang.
+	 */
+	val = I915_READ(BXT_DSI_PLL_CTL);
+	if (!(val & BXT_DSIA_16X_MASK) || !(val & BXT_DSIC_16X_MASK)) {
+		DRM_DEBUG_DRIVER("PLL is enabled with invalid divider settings (%08x)\n",
+				 val);
+		enabled = false;
+	}
+
+	return enabled;
+}
+
+static void bxt_disable_dsi_pll(struct intel_encoder *encoder)
+{
+	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
+	u32 val;
+
+	DRM_DEBUG_KMS("\n");
+
+	val = I915_READ(BXT_DSI_PLL_ENABLE);
+	val &= ~BXT_DSI_PLL_DO_ENABLE;
+	I915_WRITE(BXT_DSI_PLL_ENABLE, val);
+
+	/*
+	 * PLL lock should deassert within 200us.
+	 * Wait up to 1ms before timing out.
+	 */
+	if (wait_for((I915_READ(BXT_DSI_PLL_ENABLE)
+					& BXT_DSI_PLL_LOCKED) == 0, 1))
+		DRM_ERROR("Timeout waiting for PLL lock deassertion\n");
+}
+
+static void assert_bpp_mismatch(enum mipi_dsi_pixel_format fmt, int pipe_bpp)
+{
+	int bpp = mipi_dsi_pixel_format_to_bpp(fmt);
+
+	WARN(bpp != pipe_bpp,
+	     "bpp match assertion failure (expected %d, current %d)\n",
+	     bpp, pipe_bpp);
+}
+
+static u32 vlv_dsi_get_pclk(struct intel_encoder *encoder, int pipe_bpp,
+			    struct intel_crtc_state *config)
+{
+	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
+	struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
+	u32 dsi_clock, pclk;
+	u32 pll_ctl, pll_div;
+	u32 m = 0, p = 0, n;
+	int refclk = IS_CHERRYVIEW(dev_priv) ? 100000 : 25000;
+	int i;
+
+	DRM_DEBUG_KMS("\n");
+
+	mutex_lock(&dev_priv->sb_lock);
+	pll_ctl = vlv_cck_read(dev_priv, CCK_REG_DSI_PLL_CONTROL);
+	pll_div = vlv_cck_read(dev_priv, CCK_REG_DSI_PLL_DIVIDER);
+	mutex_unlock(&dev_priv->sb_lock);
+
+	config->dsi_pll.ctrl = pll_ctl & ~DSI_PLL_LOCK;
+	config->dsi_pll.div = pll_div;
+
+	/* mask out other bits and extract the P1 divisor */
+	pll_ctl &= DSI_PLL_P1_POST_DIV_MASK;
+	pll_ctl = pll_ctl >> (DSI_PLL_P1_POST_DIV_SHIFT - 2);
+
+	/* N1 divisor */
+	n = (pll_div & DSI_PLL_N1_DIV_MASK) >> DSI_PLL_N1_DIV_SHIFT;
+	n = 1 << n; /* register has log2(N1) */
+
+	/* mask out the other bits and extract the M1 divisor */
+	pll_div &= DSI_PLL_M1_DIV_MASK;
+	pll_div = pll_div >> DSI_PLL_M1_DIV_SHIFT;
+
+	while (pll_ctl) {
+		pll_ctl = pll_ctl >> 1;
+		p++;
+	}
+	p--;
+
+	if (!p) {
+		DRM_ERROR("wrong P1 divisor\n");
+		return 0;
+	}
+
+	for (i = 0; i < ARRAY_SIZE(lfsr_converts); i++) {
+		if (lfsr_converts[i] == pll_div)
+			break;
+	}
+
+	if (i == ARRAY_SIZE(lfsr_converts)) {
+		DRM_ERROR("wrong m_seed programmed\n");
+		return 0;
+	}
+
+	m = i + 62;
+
+	dsi_clock = (m * refclk) / (p * n);
+
+	/* pixel_format and pipe_bpp should agree */
+	assert_bpp_mismatch(intel_dsi->pixel_format, pipe_bpp);
+
+	pclk = DIV_ROUND_CLOSEST(dsi_clock * intel_dsi->lane_count, pipe_bpp);
+
+	return pclk;
+}
+
+static u32 bxt_dsi_get_pclk(struct intel_encoder *encoder, int pipe_bpp,
+			    struct intel_crtc_state *config)
+{
+	u32 pclk;
+	u32 dsi_clk;
+	u32 dsi_ratio;
+	struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
+	struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
+
+	/* Divide by zero */
+	if (!pipe_bpp) {
+		DRM_ERROR("Invalid BPP(0)\n");
+		return 0;
+	}
+
+	config->dsi_pll.ctrl = I915_READ(BXT_DSI_PLL_CTL);
+
+	dsi_ratio = config->dsi_pll.ctrl & BXT_DSI_PLL_RATIO_MASK;
+
+	dsi_clk = (dsi_ratio * BXT_REF_CLOCK_KHZ) / 2;
+
+	/* pixel_format and pipe_bpp should agree */
+	assert_bpp_mismatch(intel_dsi->pixel_format, pipe_bpp);
+
+	pclk = DIV_ROUND_CLOSEST(dsi_clk * intel_dsi->lane_count, pipe_bpp);
+
+	DRM_DEBUG_DRIVER("Calculated pclk=%u\n", pclk);
+	return pclk;
+}
+
+u32 intel_dsi_get_pclk(struct intel_encoder *encoder, int pipe_bpp,
+		       struct intel_crtc_state *config)
+{
+	if (IS_BROXTON(encoder->base.dev))
+		return bxt_dsi_get_pclk(encoder, pipe_bpp, config);
+	else
+		return vlv_dsi_get_pclk(encoder, pipe_bpp, config);
+}
+
+static void vlv_dsi_reset_clocks(struct intel_encoder *encoder, enum port port)
+{
+	u32 temp;
+	struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
+	struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
+
+	temp = I915_READ(MIPI_CTRL(port));
+	temp &= ~ESCAPE_CLOCK_DIVIDER_MASK;
+	I915_WRITE(MIPI_CTRL(port), temp |
+			intel_dsi->escape_clk_div <<
+			ESCAPE_CLOCK_DIVIDER_SHIFT);
+}
+
+/* Program BXT Mipi clocks and dividers */
+static void bxt_dsi_program_clocks(struct drm_device *dev, enum port port,
+				   const struct intel_crtc_state *config)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	u32 tmp;
+	u32 dsi_rate = 0;
+	u32 pll_ratio = 0;
+	u32 rx_div;
+	u32 tx_div;
+	u32 rx_div_upper;
+	u32 rx_div_lower;
+	u32 mipi_8by3_divider;
+
+	/* Clear old configurations */
+	tmp = I915_READ(BXT_MIPI_CLOCK_CTL);
+	tmp &= ~(BXT_MIPI_TX_ESCLK_FIXDIV_MASK(port));
+	tmp &= ~(BXT_MIPI_RX_ESCLK_UPPER_FIXDIV_MASK(port));
+	tmp &= ~(BXT_MIPI_8X_BY3_DIVIDER_MASK(port));
+	tmp &= ~(BXT_MIPI_RX_ESCLK_LOWER_FIXDIV_MASK(port));
+
+	/* Get the current DSI rate(actual) */
+	pll_ratio = config->dsi_pll.ctrl & BXT_DSI_PLL_RATIO_MASK;
+	dsi_rate = (BXT_REF_CLOCK_KHZ * pll_ratio) / 2;
+
+	/*
+	 * tx clock should be <= 20MHz and the div value must be
+	 * subtracted by 1 as per bspec
+	 */
+	tx_div = DIV_ROUND_UP(dsi_rate, 20000) - 1;
+	/*
+	 * rx clock should be <= 150MHz and the div value must be
+	 * subtracted by 1 as per bspec
+	 */
+	rx_div = DIV_ROUND_UP(dsi_rate, 150000) - 1;
+
+	/*
+	 * rx divider value needs to be updated in the
+	 * two differnt bit fields in the register hence splitting the
+	 * rx divider value accordingly
+	 */
+	rx_div_lower = rx_div & RX_DIVIDER_BIT_1_2;
+	rx_div_upper = (rx_div & RX_DIVIDER_BIT_3_4) >> 2;
+
+	/* As per bpsec program the 8/3X clock divider to the below value */
+	if (dev_priv->vbt.dsi.config->is_cmd_mode)
+		mipi_8by3_divider = 0x2;
+	else
+		mipi_8by3_divider = 0x3;
+
+	tmp |= BXT_MIPI_8X_BY3_DIVIDER(port, mipi_8by3_divider);
+	tmp |= BXT_MIPI_TX_ESCLK_DIVIDER(port, tx_div);
+	tmp |= BXT_MIPI_RX_ESCLK_LOWER_DIVIDER(port, rx_div_lower);
+	tmp |= BXT_MIPI_RX_ESCLK_UPPER_DIVIDER(port, rx_div_upper);
+
+	I915_WRITE(BXT_MIPI_CLOCK_CTL, tmp);
+}
+
+static int bxt_compute_dsi_pll(struct intel_encoder *encoder,
+			       struct intel_crtc_state *config)
+{
+	struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
+	u8 dsi_ratio;
+	u32 dsi_clk;
+
+	dsi_clk = dsi_clk_from_pclk(intel_dsi->pclk, intel_dsi->pixel_format,
+				    intel_dsi->lane_count);
+
+	/*
+	 * From clock diagram, to get PLL ratio divider, divide double of DSI
+	 * link rate (i.e., 2*8x=16x frequency value) by ref clock. Make sure to
+	 * round 'up' the result
+	 */
+	dsi_ratio = DIV_ROUND_UP(dsi_clk * 2, BXT_REF_CLOCK_KHZ);
+	if (dsi_ratio < BXT_DSI_PLL_RATIO_MIN ||
+	    dsi_ratio > BXT_DSI_PLL_RATIO_MAX) {
+		DRM_ERROR("Cant get a suitable ratio from DSI PLL ratios\n");
+		return -ECHRNG;
+	}
+
+	/*
+	 * Program DSI ratio and Select MIPIC and MIPIA PLL output as 8x
+	 * Spec says both have to be programmed, even if one is not getting
+	 * used. Configure MIPI_CLOCK_CTL dividers in modeset
+	 */
+	config->dsi_pll.ctrl = dsi_ratio | BXT_DSIA_16X_BY2 | BXT_DSIC_16X_BY2;
+
+	/* As per recommendation from hardware team,
+	 * Prog PVD ratio =1 if dsi ratio <= 50
+	 */
+	if (dsi_ratio <= 50)
+		config->dsi_pll.ctrl |= BXT_DSI_PLL_PVD_RATIO_1;
+
+	return 0;
+}
+
+static void bxt_enable_dsi_pll(struct intel_encoder *encoder,
+			       const struct intel_crtc_state *config)
+{
+	struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
+	struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
+	enum port port;
+	u32 val;
+
+	DRM_DEBUG_KMS("\n");
+
+	/* Configure PLL vales */
+	I915_WRITE(BXT_DSI_PLL_CTL, config->dsi_pll.ctrl);
+	POSTING_READ(BXT_DSI_PLL_CTL);
+
+	/* Program TX, RX, Dphy clocks */
+	for_each_dsi_port(port, intel_dsi->ports)
+		bxt_dsi_program_clocks(encoder->base.dev, port, config);
+
+	/* Enable DSI PLL */
+	val = I915_READ(BXT_DSI_PLL_ENABLE);
+	val |= BXT_DSI_PLL_DO_ENABLE;
+	I915_WRITE(BXT_DSI_PLL_ENABLE, val);
+
+	/* Timeout and fail if PLL not locked */
+	if (wait_for(I915_READ(BXT_DSI_PLL_ENABLE) & BXT_DSI_PLL_LOCKED, 1)) {
+		DRM_ERROR("Timed out waiting for DSI PLL to lock\n");
+		return;
+	}
+
+	DRM_DEBUG_KMS("DSI PLL locked\n");
+}
+
+bool intel_dsi_pll_is_enabled(struct drm_i915_private *dev_priv)
+{
+	if (IS_BROXTON(dev_priv))
+		return bxt_dsi_pll_is_enabled(dev_priv);
+
+	MISSING_CASE(INTEL_DEVID(dev_priv));
+
+	return false;
+}
+
+int intel_compute_dsi_pll(struct intel_encoder *encoder,
+			  struct intel_crtc_state *config)
+{
+	struct drm_device *dev = encoder->base.dev;
+
+	if (IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev))
+		return vlv_compute_dsi_pll(encoder, config);
+	else if (IS_BROXTON(dev))
+		return bxt_compute_dsi_pll(encoder, config);
+
+	return -ENODEV;
+}
+
+void intel_enable_dsi_pll(struct intel_encoder *encoder,
+			  const struct intel_crtc_state *config)
+{
+	struct drm_device *dev = encoder->base.dev;
+
+	if (IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev))
+		vlv_enable_dsi_pll(encoder, config);
+	else if (IS_BROXTON(dev))
+		bxt_enable_dsi_pll(encoder, config);
+}
+
+void intel_disable_dsi_pll(struct intel_encoder *encoder)
+{
+	struct drm_device *dev = encoder->base.dev;
+
+	if (IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev))
+		vlv_disable_dsi_pll(encoder);
+	else if (IS_BROXTON(dev))
+		bxt_disable_dsi_pll(encoder);
+}
+
+static void bxt_dsi_reset_clocks(struct intel_encoder *encoder, enum port port)
+{
+	u32 tmp;
+	struct drm_device *dev = encoder->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	/* Clear old configurations */
+	tmp = I915_READ(BXT_MIPI_CLOCK_CTL);
+	tmp &= ~(BXT_MIPI_TX_ESCLK_FIXDIV_MASK(port));
+	tmp &= ~(BXT_MIPI_RX_ESCLK_UPPER_FIXDIV_MASK(port));
+	tmp &= ~(BXT_MIPI_8X_BY3_DIVIDER_MASK(port));
+	tmp &= ~(BXT_MIPI_RX_ESCLK_LOWER_FIXDIV_MASK(port));
+	I915_WRITE(BXT_MIPI_CLOCK_CTL, tmp);
+	I915_WRITE(MIPI_EOT_DISABLE(port), CLOCKSTOP);
+}
+
+void intel_dsi_reset_clocks(struct intel_encoder *encoder, enum port port)
+{
+	struct drm_device *dev = encoder->base.dev;
+
+	if (IS_BROXTON(dev))
+		bxt_dsi_reset_clocks(encoder, port);
+	else if (IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev))
+		vlv_dsi_reset_clocks(encoder, port);
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/i915/intel_dvo.c
@@ -0,0 +1,547 @@
+/*
+ * Copyright 2006 Dave Airlie <airlied@linux.ie>
+ * Copyright © 2006-2007 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *	Eric Anholt <eric@anholt.net>
+ */
+#include <linux/i2c.h>
+#include <linux/slab.h>
+#include <drm/drmP.h>
+#include <drm/drm_atomic_helper.h>
+#include <drm/drm_crtc.h>
+#include "intel_drv.h"
+#include <drm/i915_drm.h>
+#include "i915_drv.h"
+#include "dvo.h"
+
+#define SIL164_ADDR	0x38
+#define CH7xxx_ADDR	0x76
+#define TFP410_ADDR	0x38
+#define NS2501_ADDR     0x38
+
+static const struct intel_dvo_device intel_dvo_devices[] = {
+	{
+		.type = INTEL_DVO_CHIP_TMDS,
+		.name = "sil164",
+		.dvo_reg = DVOC,
+		.dvo_srcdim_reg = DVOC_SRCDIM,
+		.slave_addr = SIL164_ADDR,
+		.dev_ops = &sil164_ops,
+	},
+	{
+		.type = INTEL_DVO_CHIP_TMDS,
+		.name = "ch7xxx",
+		.dvo_reg = DVOC,
+		.dvo_srcdim_reg = DVOC_SRCDIM,
+		.slave_addr = CH7xxx_ADDR,
+		.dev_ops = &ch7xxx_ops,
+	},
+	{
+		.type = INTEL_DVO_CHIP_TMDS,
+		.name = "ch7xxx",
+		.dvo_reg = DVOC,
+		.dvo_srcdim_reg = DVOC_SRCDIM,
+		.slave_addr = 0x75, /* For some ch7010 */
+		.dev_ops = &ch7xxx_ops,
+	},
+	{
+		.type = INTEL_DVO_CHIP_LVDS,
+		.name = "ivch",
+		.dvo_reg = DVOA,
+		.dvo_srcdim_reg = DVOA_SRCDIM,
+		.slave_addr = 0x02, /* Might also be 0x44, 0x84, 0xc4 */
+		.dev_ops = &ivch_ops,
+	},
+	{
+		.type = INTEL_DVO_CHIP_TMDS,
+		.name = "tfp410",
+		.dvo_reg = DVOC,
+		.dvo_srcdim_reg = DVOC_SRCDIM,
+		.slave_addr = TFP410_ADDR,
+		.dev_ops = &tfp410_ops,
+	},
+	{
+		.type = INTEL_DVO_CHIP_LVDS,
+		.name = "ch7017",
+		.dvo_reg = DVOC,
+		.dvo_srcdim_reg = DVOC_SRCDIM,
+		.slave_addr = 0x75,
+		.gpio = GMBUS_PIN_DPB,
+		.dev_ops = &ch7017_ops,
+	},
+	{
+	        .type = INTEL_DVO_CHIP_TMDS,
+		.name = "ns2501",
+		.dvo_reg = DVOB,
+		.dvo_srcdim_reg = DVOB_SRCDIM,
+		.slave_addr = NS2501_ADDR,
+		.dev_ops = &ns2501_ops,
+       }
+};
+
+struct intel_dvo {
+	struct intel_encoder base;
+
+	struct intel_dvo_device dev;
+
+	struct intel_connector *attached_connector;
+
+	bool panel_wants_dither;
+};
+
+static struct intel_dvo *enc_to_dvo(struct intel_encoder *encoder)
+{
+	return container_of(encoder, struct intel_dvo, base);
+}
+
+static struct intel_dvo *intel_attached_dvo(struct drm_connector *connector)
+{
+	return enc_to_dvo(intel_attached_encoder(connector));
+}
+
+static bool intel_dvo_connector_get_hw_state(struct intel_connector *connector)
+{
+	struct drm_device *dev = connector->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_dvo *intel_dvo = intel_attached_dvo(&connector->base);
+	u32 tmp;
+
+	tmp = I915_READ(intel_dvo->dev.dvo_reg);
+
+	if (!(tmp & DVO_ENABLE))
+		return false;
+
+	return intel_dvo->dev.dev_ops->get_hw_state(&intel_dvo->dev);
+}
+
+static bool intel_dvo_get_hw_state(struct intel_encoder *encoder,
+				   enum pipe *pipe)
+{
+	struct drm_device *dev = encoder->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_dvo *intel_dvo = enc_to_dvo(encoder);
+	u32 tmp;
+
+	tmp = I915_READ(intel_dvo->dev.dvo_reg);
+
+	if (!(tmp & DVO_ENABLE))
+		return false;
+
+	*pipe = PORT_TO_PIPE(tmp);
+
+	return true;
+}
+
+static void intel_dvo_get_config(struct intel_encoder *encoder,
+				 struct intel_crtc_state *pipe_config)
+{
+	struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
+	struct intel_dvo *intel_dvo = enc_to_dvo(encoder);
+	u32 tmp, flags = 0;
+
+	tmp = I915_READ(intel_dvo->dev.dvo_reg);
+	if (tmp & DVO_HSYNC_ACTIVE_HIGH)
+		flags |= DRM_MODE_FLAG_PHSYNC;
+	else
+		flags |= DRM_MODE_FLAG_NHSYNC;
+	if (tmp & DVO_VSYNC_ACTIVE_HIGH)
+		flags |= DRM_MODE_FLAG_PVSYNC;
+	else
+		flags |= DRM_MODE_FLAG_NVSYNC;
+
+	pipe_config->base.adjusted_mode.flags |= flags;
+
+	pipe_config->base.adjusted_mode.crtc_clock = pipe_config->port_clock;
+}
+
+static void intel_disable_dvo(struct intel_encoder *encoder)
+{
+	struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
+	struct intel_dvo *intel_dvo = enc_to_dvo(encoder);
+	i915_reg_t dvo_reg = intel_dvo->dev.dvo_reg;
+	u32 temp = I915_READ(dvo_reg);
+
+	intel_dvo->dev.dev_ops->dpms(&intel_dvo->dev, false);
+	I915_WRITE(dvo_reg, temp & ~DVO_ENABLE);
+	I915_READ(dvo_reg);
+}
+
+static void intel_enable_dvo(struct intel_encoder *encoder)
+{
+	struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
+	struct intel_dvo *intel_dvo = enc_to_dvo(encoder);
+	struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc);
+	i915_reg_t dvo_reg = intel_dvo->dev.dvo_reg;
+	u32 temp = I915_READ(dvo_reg);
+
+	intel_dvo->dev.dev_ops->mode_set(&intel_dvo->dev,
+					 &crtc->config->base.mode,
+					 &crtc->config->base.adjusted_mode);
+
+	I915_WRITE(dvo_reg, temp | DVO_ENABLE);
+	I915_READ(dvo_reg);
+
+	intel_dvo->dev.dev_ops->dpms(&intel_dvo->dev, true);
+}
+
+static enum drm_mode_status
+intel_dvo_mode_valid(struct drm_connector *connector,
+		     struct drm_display_mode *mode)
+{
+	struct intel_dvo *intel_dvo = intel_attached_dvo(connector);
+	const struct drm_display_mode *fixed_mode =
+		to_intel_connector(connector)->panel.fixed_mode;
+	int max_dotclk = to_i915(connector->dev)->max_dotclk_freq;
+	int target_clock = mode->clock;
+
+	if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
+		return MODE_NO_DBLESCAN;
+
+	/* XXX: Validate clock range */
+
+	if (fixed_mode) {
+		if (mode->hdisplay > fixed_mode->hdisplay)
+			return MODE_PANEL;
+		if (mode->vdisplay > fixed_mode->vdisplay)
+			return MODE_PANEL;
+
+		target_clock = fixed_mode->clock;
+	}
+
+	if (target_clock > max_dotclk)
+		return MODE_CLOCK_HIGH;
+
+	return intel_dvo->dev.dev_ops->mode_valid(&intel_dvo->dev, mode);
+}
+
+static bool intel_dvo_compute_config(struct intel_encoder *encoder,
+				     struct intel_crtc_state *pipe_config)
+{
+	struct intel_dvo *intel_dvo = enc_to_dvo(encoder);
+	const struct drm_display_mode *fixed_mode =
+		intel_dvo->attached_connector->panel.fixed_mode;
+	struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
+
+	/* If we have timings from the BIOS for the panel, put them in
+	 * to the adjusted mode.  The CRTC will be set up for this mode,
+	 * with the panel scaling set up to source from the H/VDisplay
+	 * of the original mode.
+	 */
+	if (fixed_mode)
+		intel_fixed_panel_mode(fixed_mode, adjusted_mode);
+
+	return true;
+}
+
+static void intel_dvo_pre_enable(struct intel_encoder *encoder)
+{
+	struct drm_device *dev = encoder->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc);
+	const struct drm_display_mode *adjusted_mode = &crtc->config->base.adjusted_mode;
+	struct intel_dvo *intel_dvo = enc_to_dvo(encoder);
+	int pipe = crtc->pipe;
+	u32 dvo_val;
+	i915_reg_t dvo_reg = intel_dvo->dev.dvo_reg;
+	i915_reg_t dvo_srcdim_reg = intel_dvo->dev.dvo_srcdim_reg;
+
+	/* Save the data order, since I don't know what it should be set to. */
+	dvo_val = I915_READ(dvo_reg) &
+		  (DVO_PRESERVE_MASK | DVO_DATA_ORDER_GBRG);
+	dvo_val |= DVO_DATA_ORDER_FP | DVO_BORDER_ENABLE |
+		   DVO_BLANK_ACTIVE_HIGH;
+
+	if (pipe == 1)
+		dvo_val |= DVO_PIPE_B_SELECT;
+	dvo_val |= DVO_PIPE_STALL;
+	if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC)
+		dvo_val |= DVO_HSYNC_ACTIVE_HIGH;
+	if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC)
+		dvo_val |= DVO_VSYNC_ACTIVE_HIGH;
+
+	/*I915_WRITE(DVOB_SRCDIM,
+	  (adjusted_mode->crtc_hdisplay << DVO_SRCDIM_HORIZONTAL_SHIFT) |
+	  (adjusted_mode->crtc_vdisplay << DVO_SRCDIM_VERTICAL_SHIFT));*/
+	I915_WRITE(dvo_srcdim_reg,
+		   (adjusted_mode->crtc_hdisplay << DVO_SRCDIM_HORIZONTAL_SHIFT) |
+		   (adjusted_mode->crtc_vdisplay << DVO_SRCDIM_VERTICAL_SHIFT));
+	/*I915_WRITE(DVOB, dvo_val);*/
+	I915_WRITE(dvo_reg, dvo_val);
+}
+
+/**
+ * Detect the output connection on our DVO device.
+ *
+ * Unimplemented.
+ */
+static enum drm_connector_status
+intel_dvo_detect(struct drm_connector *connector, bool force)
+{
+	struct intel_dvo *intel_dvo = intel_attached_dvo(connector);
+	DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
+		      connector->base.id, connector->name);
+	return intel_dvo->dev.dev_ops->detect(&intel_dvo->dev);
+}
+
+static int intel_dvo_get_modes(struct drm_connector *connector)
+{
+	struct drm_i915_private *dev_priv = connector->dev->dev_private;
+	const struct drm_display_mode *fixed_mode =
+		to_intel_connector(connector)->panel.fixed_mode;
+
+	/* We should probably have an i2c driver get_modes function for those
+	 * devices which will have a fixed set of modes determined by the chip
+	 * (TV-out, for example), but for now with just TMDS and LVDS,
+	 * that's not the case.
+	 */
+	intel_ddc_get_modes(connector,
+			    intel_gmbus_get_adapter(dev_priv, GMBUS_PIN_DPC));
+	if (!list_empty(&connector->probed_modes))
+		return 1;
+
+	if (fixed_mode) {
+		struct drm_display_mode *mode;
+		mode = drm_mode_duplicate(connector->dev, fixed_mode);
+		if (mode) {
+			drm_mode_probed_add(connector, mode);
+			return 1;
+		}
+	}
+
+	return 0;
+}
+
+static void intel_dvo_destroy(struct drm_connector *connector)
+{
+	drm_connector_cleanup(connector);
+	intel_panel_fini(&to_intel_connector(connector)->panel);
+	kfree(connector);
+}
+
+static const struct drm_connector_funcs intel_dvo_connector_funcs = {
+	.dpms = drm_atomic_helper_connector_dpms,
+	.detect = intel_dvo_detect,
+	.destroy = intel_dvo_destroy,
+	.fill_modes = drm_helper_probe_single_connector_modes,
+	.atomic_get_property = intel_connector_atomic_get_property,
+	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
+	.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
+};
+
+static const struct drm_connector_helper_funcs intel_dvo_connector_helper_funcs = {
+	.mode_valid = intel_dvo_mode_valid,
+	.get_modes = intel_dvo_get_modes,
+	.best_encoder = intel_best_encoder,
+};
+
+static void intel_dvo_enc_destroy(struct drm_encoder *encoder)
+{
+	struct intel_dvo *intel_dvo = enc_to_dvo(to_intel_encoder(encoder));
+
+	if (intel_dvo->dev.dev_ops->destroy)
+		intel_dvo->dev.dev_ops->destroy(&intel_dvo->dev);
+
+	intel_encoder_destroy(encoder);
+}
+
+static const struct drm_encoder_funcs intel_dvo_enc_funcs = {
+	.destroy = intel_dvo_enc_destroy,
+};
+
+/**
+ * Attempts to get a fixed panel timing for LVDS (currently only the i830).
+ *
+ * Other chips with DVO LVDS will need to extend this to deal with the LVDS
+ * chip being on DVOB/C and having multiple pipes.
+ */
+static struct drm_display_mode *
+intel_dvo_get_current_mode(struct drm_connector *connector)
+{
+	struct drm_device *dev = connector->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_dvo *intel_dvo = intel_attached_dvo(connector);
+	uint32_t dvo_val = I915_READ(intel_dvo->dev.dvo_reg);
+	struct drm_display_mode *mode = NULL;
+
+	/* If the DVO port is active, that'll be the LVDS, so we can pull out
+	 * its timings to get how the BIOS set up the panel.
+	 */
+	if (dvo_val & DVO_ENABLE) {
+		struct drm_crtc *crtc;
+		int pipe = (dvo_val & DVO_PIPE_B_SELECT) ? 1 : 0;
+
+		crtc = intel_get_crtc_for_pipe(dev, pipe);
+		if (crtc) {
+			mode = intel_crtc_mode_get(dev, crtc);
+			if (mode) {
+				mode->type |= DRM_MODE_TYPE_PREFERRED;
+				if (dvo_val & DVO_HSYNC_ACTIVE_HIGH)
+					mode->flags |= DRM_MODE_FLAG_PHSYNC;
+				if (dvo_val & DVO_VSYNC_ACTIVE_HIGH)
+					mode->flags |= DRM_MODE_FLAG_PVSYNC;
+			}
+		}
+	}
+
+	return mode;
+}
+
+void intel_dvo_init(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_encoder *intel_encoder;
+	struct intel_dvo *intel_dvo;
+	struct intel_connector *intel_connector;
+	int i;
+	int encoder_type = DRM_MODE_ENCODER_NONE;
+
+	intel_dvo = kzalloc(sizeof(*intel_dvo), GFP_KERNEL);
+	if (!intel_dvo)
+		return;
+
+	intel_connector = intel_connector_alloc();
+	if (!intel_connector) {
+		kfree(intel_dvo);
+		return;
+	}
+
+	intel_dvo->attached_connector = intel_connector;
+
+	intel_encoder = &intel_dvo->base;
+	drm_encoder_init(dev, &intel_encoder->base,
+			 &intel_dvo_enc_funcs, encoder_type);
+
+	intel_encoder->disable = intel_disable_dvo;
+	intel_encoder->enable = intel_enable_dvo;
+	intel_encoder->get_hw_state = intel_dvo_get_hw_state;
+	intel_encoder->get_config = intel_dvo_get_config;
+	intel_encoder->compute_config = intel_dvo_compute_config;
+	intel_encoder->pre_enable = intel_dvo_pre_enable;
+	intel_connector->get_hw_state = intel_dvo_connector_get_hw_state;
+	intel_connector->unregister = intel_connector_unregister;
+
+	/* Now, try to find a controller */
+	for (i = 0; i < ARRAY_SIZE(intel_dvo_devices); i++) {
+		struct drm_connector *connector = &intel_connector->base;
+		const struct intel_dvo_device *dvo = &intel_dvo_devices[i];
+		struct i2c_adapter *i2c;
+		int gpio;
+		bool dvoinit;
+		enum pipe pipe;
+		uint32_t dpll[I915_MAX_PIPES];
+
+		/* Allow the I2C driver info to specify the GPIO to be used in
+		 * special cases, but otherwise default to what's defined
+		 * in the spec.
+		 */
+		if (intel_gmbus_is_valid_pin(dev_priv, dvo->gpio))
+			gpio = dvo->gpio;
+		else if (dvo->type == INTEL_DVO_CHIP_LVDS)
+			gpio = GMBUS_PIN_SSC;
+		else
+			gpio = GMBUS_PIN_DPB;
+
+		/* Set up the I2C bus necessary for the chip we're probing.
+		 * It appears that everything is on GPIOE except for panels
+		 * on i830 laptops, which are on GPIOB (DVOA).
+		 */
+		i2c = intel_gmbus_get_adapter(dev_priv, gpio);
+
+		intel_dvo->dev = *dvo;
+
+		/* GMBUS NAK handling seems to be unstable, hence let the
+		 * transmitter detection run in bit banging mode for now.
+		 */
+		intel_gmbus_force_bit(i2c, true);
+
+		/* ns2501 requires the DVO 2x clock before it will
+		 * respond to i2c accesses, so make sure we have
+		 * have the clock enabled before we attempt to
+		 * initialize the device.
+		 */
+		for_each_pipe(dev_priv, pipe) {
+			dpll[pipe] = I915_READ(DPLL(pipe));
+			I915_WRITE(DPLL(pipe), dpll[pipe] | DPLL_DVO_2X_MODE);
+		}
+
+		dvoinit = dvo->dev_ops->init(&intel_dvo->dev, i2c);
+
+		/* restore the DVO 2x clock state to original */
+		for_each_pipe(dev_priv, pipe) {
+			I915_WRITE(DPLL(pipe), dpll[pipe]);
+		}
+
+		intel_gmbus_force_bit(i2c, false);
+
+		if (!dvoinit)
+			continue;
+
+		intel_encoder->type = INTEL_OUTPUT_DVO;
+		intel_encoder->crtc_mask = (1 << 0) | (1 << 1);
+		switch (dvo->type) {
+		case INTEL_DVO_CHIP_TMDS:
+			intel_encoder->cloneable = (1 << INTEL_OUTPUT_ANALOG) |
+				(1 << INTEL_OUTPUT_DVO);
+			drm_connector_init(dev, connector,
+					   &intel_dvo_connector_funcs,
+					   DRM_MODE_CONNECTOR_DVII);
+			encoder_type = DRM_MODE_ENCODER_TMDS;
+			break;
+		case INTEL_DVO_CHIP_LVDS:
+			intel_encoder->cloneable = 0;
+			drm_connector_init(dev, connector,
+					   &intel_dvo_connector_funcs,
+					   DRM_MODE_CONNECTOR_LVDS);
+			encoder_type = DRM_MODE_ENCODER_LVDS;
+			break;
+		}
+
+		drm_connector_helper_add(connector,
+					 &intel_dvo_connector_helper_funcs);
+		connector->display_info.subpixel_order = SubPixelHorizontalRGB;
+		connector->interlace_allowed = false;
+		connector->doublescan_allowed = false;
+
+		intel_connector_attach_encoder(intel_connector, intel_encoder);
+		if (dvo->type == INTEL_DVO_CHIP_LVDS) {
+			/* For our LVDS chipsets, we should hopefully be able
+			 * to dig the fixed panel mode out of the BIOS data.
+			 * However, it's in a different format from the BIOS
+			 * data on chipsets with integrated LVDS (stored in AIM
+			 * headers, likely), so for now, just get the current
+			 * mode being output through DVO.
+			 */
+			intel_panel_init(&intel_connector->panel,
+					 intel_dvo_get_current_mode(connector),
+					 NULL);
+			intel_dvo->panel_wants_dither = true;
+		}
+
+		drm_connector_register(connector);
+		return;
+	}
+
+	drm_encoder_cleanup(&intel_encoder->base);
+	kfree(intel_dvo);
+	kfree(intel_connector);
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/i915/intel_fbc.c
@@ -0,0 +1,1263 @@
+/*
+ * Copyright © 2014 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+ * DOC: Frame Buffer Compression (FBC)
+ *
+ * FBC tries to save memory bandwidth (and so power consumption) by
+ * compressing the amount of memory used by the display. It is total
+ * transparent to user space and completely handled in the kernel.
+ *
+ * The benefits of FBC are mostly visible with solid backgrounds and
+ * variation-less patterns. It comes from keeping the memory footprint small
+ * and having fewer memory pages opened and accessed for refreshing the display.
+ *
+ * i915 is responsible to reserve stolen memory for FBC and configure its
+ * offset on proper registers. The hardware takes care of all
+ * compress/decompress. However there are many known cases where we have to
+ * forcibly disable it to allow proper screen updates.
+ */
+
+#include "intel_drv.h"
+#include "i915_drv.h"
+
+static inline bool fbc_supported(struct drm_i915_private *dev_priv)
+{
+	return HAS_FBC(dev_priv);
+}
+
+static inline bool fbc_on_pipe_a_only(struct drm_i915_private *dev_priv)
+{
+	return IS_HASWELL(dev_priv) || INTEL_INFO(dev_priv)->gen >= 8;
+}
+
+static inline bool fbc_on_plane_a_only(struct drm_i915_private *dev_priv)
+{
+	return INTEL_INFO(dev_priv)->gen < 4;
+}
+
+static inline bool no_fbc_on_multiple_pipes(struct drm_i915_private *dev_priv)
+{
+	return INTEL_INFO(dev_priv)->gen <= 3;
+}
+
+/*
+ * In some platforms where the CRTC's x:0/y:0 coordinates doesn't match the
+ * frontbuffer's x:0/y:0 coordinates we lie to the hardware about the plane's
+ * origin so the x and y offsets can actually fit the registers. As a
+ * consequence, the fence doesn't really start exactly at the display plane
+ * address we program because it starts at the real start of the buffer, so we
+ * have to take this into consideration here.
+ */
+static unsigned int get_crtc_fence_y_offset(struct intel_crtc *crtc)
+{
+	return crtc->base.y - crtc->adjusted_y;
+}
+
+/*
+ * For SKL+, the plane source size used by the hardware is based on the value we
+ * write to the PLANE_SIZE register. For BDW-, the hardware looks at the value
+ * we wrote to PIPESRC.
+ */
+static void intel_fbc_get_plane_source_size(struct intel_fbc_state_cache *cache,
+					    int *width, int *height)
+{
+	int w, h;
+
+	if (intel_rotation_90_or_270(cache->plane.rotation)) {
+		w = cache->plane.src_h;
+		h = cache->plane.src_w;
+	} else {
+		w = cache->plane.src_w;
+		h = cache->plane.src_h;
+	}
+
+	if (width)
+		*width = w;
+	if (height)
+		*height = h;
+}
+
+static int intel_fbc_calculate_cfb_size(struct drm_i915_private *dev_priv,
+					struct intel_fbc_state_cache *cache)
+{
+	int lines;
+
+	intel_fbc_get_plane_source_size(cache, NULL, &lines);
+	if (INTEL_INFO(dev_priv)->gen >= 7)
+		lines = min(lines, 2048);
+
+	/* Hardware needs the full buffer stride, not just the active area. */
+	return lines * cache->fb.stride;
+}
+
+static void i8xx_fbc_deactivate(struct drm_i915_private *dev_priv)
+{
+	u32 fbc_ctl;
+
+	/* Disable compression */
+	fbc_ctl = I915_READ(FBC_CONTROL);
+	if ((fbc_ctl & FBC_CTL_EN) == 0)
+		return;
+
+	fbc_ctl &= ~FBC_CTL_EN;
+	I915_WRITE(FBC_CONTROL, fbc_ctl);
+
+	/* Wait for compressing bit to clear */
+	if (wait_for((I915_READ(FBC_STATUS) & FBC_STAT_COMPRESSING) == 0, 10)) {
+		DRM_DEBUG_KMS("FBC idle timed out\n");
+		return;
+	}
+}
+
+static void i8xx_fbc_activate(struct drm_i915_private *dev_priv)
+{
+	struct intel_fbc_reg_params *params = &dev_priv->fbc.params;
+	int cfb_pitch;
+	int i;
+	u32 fbc_ctl;
+
+	/* Note: fbc.threshold == 1 for i8xx */
+	cfb_pitch = params->cfb_size / FBC_LL_SIZE;
+	if (params->fb.stride < cfb_pitch)
+		cfb_pitch = params->fb.stride;
+
+	/* FBC_CTL wants 32B or 64B units */
+	if (IS_GEN2(dev_priv))
+		cfb_pitch = (cfb_pitch / 32) - 1;
+	else
+		cfb_pitch = (cfb_pitch / 64) - 1;
+
+	/* Clear old tags */
+	for (i = 0; i < (FBC_LL_SIZE / 32) + 1; i++)
+		I915_WRITE(FBC_TAG(i), 0);
+
+	if (IS_GEN4(dev_priv)) {
+		u32 fbc_ctl2;
+
+		/* Set it up... */
+		fbc_ctl2 = FBC_CTL_FENCE_DBL | FBC_CTL_IDLE_IMM | FBC_CTL_CPU_FENCE;
+		fbc_ctl2 |= FBC_CTL_PLANE(params->crtc.plane);
+		I915_WRITE(FBC_CONTROL2, fbc_ctl2);
+		I915_WRITE(FBC_FENCE_OFF, params->crtc.fence_y_offset);
+	}
+
+	/* enable it... */
+	fbc_ctl = I915_READ(FBC_CONTROL);
+	fbc_ctl &= 0x3fff << FBC_CTL_INTERVAL_SHIFT;
+	fbc_ctl |= FBC_CTL_EN | FBC_CTL_PERIODIC;
+	if (IS_I945GM(dev_priv))
+		fbc_ctl |= FBC_CTL_C3_IDLE; /* 945 needs special SR handling */
+	fbc_ctl |= (cfb_pitch & 0xff) << FBC_CTL_STRIDE_SHIFT;
+	fbc_ctl |= params->fb.fence_reg;
+	I915_WRITE(FBC_CONTROL, fbc_ctl);
+}
+
+static bool i8xx_fbc_is_active(struct drm_i915_private *dev_priv)
+{
+	return I915_READ(FBC_CONTROL) & FBC_CTL_EN;
+}
+
+static void g4x_fbc_activate(struct drm_i915_private *dev_priv)
+{
+	struct intel_fbc_reg_params *params = &dev_priv->fbc.params;
+	u32 dpfc_ctl;
+
+	dpfc_ctl = DPFC_CTL_PLANE(params->crtc.plane) | DPFC_SR_EN;
+	if (drm_format_plane_cpp(params->fb.pixel_format, 0) == 2)
+		dpfc_ctl |= DPFC_CTL_LIMIT_2X;
+	else
+		dpfc_ctl |= DPFC_CTL_LIMIT_1X;
+	dpfc_ctl |= DPFC_CTL_FENCE_EN | params->fb.fence_reg;
+
+	I915_WRITE(DPFC_FENCE_YOFF, params->crtc.fence_y_offset);
+
+	/* enable it... */
+	I915_WRITE(DPFC_CONTROL, dpfc_ctl | DPFC_CTL_EN);
+}
+
+static void g4x_fbc_deactivate(struct drm_i915_private *dev_priv)
+{
+	u32 dpfc_ctl;
+
+	/* Disable compression */
+	dpfc_ctl = I915_READ(DPFC_CONTROL);
+	if (dpfc_ctl & DPFC_CTL_EN) {
+		dpfc_ctl &= ~DPFC_CTL_EN;
+		I915_WRITE(DPFC_CONTROL, dpfc_ctl);
+	}
+}
+
+static bool g4x_fbc_is_active(struct drm_i915_private *dev_priv)
+{
+	return I915_READ(DPFC_CONTROL) & DPFC_CTL_EN;
+}
+
+/* This function forces a CFB recompression through the nuke operation. */
+static void intel_fbc_recompress(struct drm_i915_private *dev_priv)
+{
+	I915_WRITE(MSG_FBC_REND_STATE, FBC_REND_NUKE);
+	POSTING_READ(MSG_FBC_REND_STATE);
+}
+
+static void ilk_fbc_activate(struct drm_i915_private *dev_priv)
+{
+	struct intel_fbc_reg_params *params = &dev_priv->fbc.params;
+	u32 dpfc_ctl;
+	int threshold = dev_priv->fbc.threshold;
+
+	dpfc_ctl = DPFC_CTL_PLANE(params->crtc.plane);
+	if (drm_format_plane_cpp(params->fb.pixel_format, 0) == 2)
+		threshold++;
+
+	switch (threshold) {
+	case 4:
+	case 3:
+		dpfc_ctl |= DPFC_CTL_LIMIT_4X;
+		break;
+	case 2:
+		dpfc_ctl |= DPFC_CTL_LIMIT_2X;
+		break;
+	case 1:
+		dpfc_ctl |= DPFC_CTL_LIMIT_1X;
+		break;
+	}
+	dpfc_ctl |= DPFC_CTL_FENCE_EN;
+	if (IS_GEN5(dev_priv))
+		dpfc_ctl |= params->fb.fence_reg;
+
+	I915_WRITE(ILK_DPFC_FENCE_YOFF, params->crtc.fence_y_offset);
+	I915_WRITE(ILK_FBC_RT_BASE, params->fb.ggtt_offset | ILK_FBC_RT_VALID);
+	/* enable it... */
+	I915_WRITE(ILK_DPFC_CONTROL, dpfc_ctl | DPFC_CTL_EN);
+
+	if (IS_GEN6(dev_priv)) {
+		I915_WRITE(SNB_DPFC_CTL_SA,
+			   SNB_CPU_FENCE_ENABLE | params->fb.fence_reg);
+		I915_WRITE(DPFC_CPU_FENCE_OFFSET, params->crtc.fence_y_offset);
+	}
+
+	intel_fbc_recompress(dev_priv);
+}
+
+static void ilk_fbc_deactivate(struct drm_i915_private *dev_priv)
+{
+	u32 dpfc_ctl;
+
+	/* Disable compression */
+	dpfc_ctl = I915_READ(ILK_DPFC_CONTROL);
+	if (dpfc_ctl & DPFC_CTL_EN) {
+		dpfc_ctl &= ~DPFC_CTL_EN;
+		I915_WRITE(ILK_DPFC_CONTROL, dpfc_ctl);
+	}
+}
+
+static bool ilk_fbc_is_active(struct drm_i915_private *dev_priv)
+{
+	return I915_READ(ILK_DPFC_CONTROL) & DPFC_CTL_EN;
+}
+
+static void gen7_fbc_activate(struct drm_i915_private *dev_priv)
+{
+	struct intel_fbc_reg_params *params = &dev_priv->fbc.params;
+	u32 dpfc_ctl;
+	int threshold = dev_priv->fbc.threshold;
+
+	dpfc_ctl = 0;
+	if (IS_IVYBRIDGE(dev_priv))
+		dpfc_ctl |= IVB_DPFC_CTL_PLANE(params->crtc.plane);
+
+	if (drm_format_plane_cpp(params->fb.pixel_format, 0) == 2)
+		threshold++;
+
+	switch (threshold) {
+	case 4:
+	case 3:
+		dpfc_ctl |= DPFC_CTL_LIMIT_4X;
+		break;
+	case 2:
+		dpfc_ctl |= DPFC_CTL_LIMIT_2X;
+		break;
+	case 1:
+		dpfc_ctl |= DPFC_CTL_LIMIT_1X;
+		break;
+	}
+
+	dpfc_ctl |= IVB_DPFC_CTL_FENCE_EN;
+
+	if (dev_priv->fbc.false_color)
+		dpfc_ctl |= FBC_CTL_FALSE_COLOR;
+
+	if (IS_IVYBRIDGE(dev_priv)) {
+		/* WaFbcAsynchFlipDisableFbcQueue:ivb */
+		I915_WRITE(ILK_DISPLAY_CHICKEN1,
+			   I915_READ(ILK_DISPLAY_CHICKEN1) |
+			   ILK_FBCQ_DIS);
+	} else if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) {
+		/* WaFbcAsynchFlipDisableFbcQueue:hsw,bdw */
+		I915_WRITE(CHICKEN_PIPESL_1(params->crtc.pipe),
+			   I915_READ(CHICKEN_PIPESL_1(params->crtc.pipe)) |
+			   HSW_FBCQ_DIS);
+	}
+
+	I915_WRITE(ILK_DPFC_CONTROL, dpfc_ctl | DPFC_CTL_EN);
+
+	I915_WRITE(SNB_DPFC_CTL_SA,
+		   SNB_CPU_FENCE_ENABLE | params->fb.fence_reg);
+	I915_WRITE(DPFC_CPU_FENCE_OFFSET, params->crtc.fence_y_offset);
+
+	intel_fbc_recompress(dev_priv);
+}
+
+static bool intel_fbc_hw_is_active(struct drm_i915_private *dev_priv)
+{
+	if (INTEL_INFO(dev_priv)->gen >= 5)
+		return ilk_fbc_is_active(dev_priv);
+	else if (IS_GM45(dev_priv))
+		return g4x_fbc_is_active(dev_priv);
+	else
+		return i8xx_fbc_is_active(dev_priv);
+}
+
+static void intel_fbc_hw_activate(struct drm_i915_private *dev_priv)
+{
+	struct intel_fbc *fbc = &dev_priv->fbc;
+
+	fbc->active = true;
+
+	if (INTEL_INFO(dev_priv)->gen >= 7)
+		gen7_fbc_activate(dev_priv);
+	else if (INTEL_INFO(dev_priv)->gen >= 5)
+		ilk_fbc_activate(dev_priv);
+	else if (IS_GM45(dev_priv))
+		g4x_fbc_activate(dev_priv);
+	else
+		i8xx_fbc_activate(dev_priv);
+}
+
+static void intel_fbc_hw_deactivate(struct drm_i915_private *dev_priv)
+{
+	struct intel_fbc *fbc = &dev_priv->fbc;
+
+	fbc->active = false;
+
+	if (INTEL_INFO(dev_priv)->gen >= 5)
+		ilk_fbc_deactivate(dev_priv);
+	else if (IS_GM45(dev_priv))
+		g4x_fbc_deactivate(dev_priv);
+	else
+		i8xx_fbc_deactivate(dev_priv);
+}
+
+/**
+ * intel_fbc_is_active - Is FBC active?
+ * @dev_priv: i915 device instance
+ *
+ * This function is used to verify the current state of FBC.
+ * FIXME: This should be tracked in the plane config eventually
+ *        instead of queried at runtime for most callers.
+ */
+bool intel_fbc_is_active(struct drm_i915_private *dev_priv)
+{
+	return dev_priv->fbc.active;
+}
+
+static void intel_fbc_work_fn(struct work_struct *__work)
+{
+	struct drm_i915_private *dev_priv =
+		container_of(__work, struct drm_i915_private, fbc.work.work);
+	struct intel_fbc *fbc = &dev_priv->fbc;
+	struct intel_fbc_work *work = &fbc->work;
+	struct intel_crtc *crtc = fbc->crtc;
+	struct drm_vblank_crtc *vblank = &dev_priv->dev->vblank[crtc->pipe];
+
+	if (drm_crtc_vblank_get(&crtc->base)) {
+		DRM_ERROR("vblank not available for FBC on pipe %c\n",
+			  pipe_name(crtc->pipe));
+
+		mutex_lock(&fbc->lock);
+		work->scheduled = false;
+		mutex_unlock(&fbc->lock);
+		return;
+	}
+
+retry:
+	/* Delay the actual enabling to let pageflipping cease and the
+	 * display to settle before starting the compression. Note that
+	 * this delay also serves a second purpose: it allows for a
+	 * vblank to pass after disabling the FBC before we attempt
+	 * to modify the control registers.
+	 *
+	 * WaFbcWaitForVBlankBeforeEnable:ilk,snb
+	 *
+	 * It is also worth mentioning that since work->scheduled_vblank can be
+	 * updated multiple times by the other threads, hitting the timeout is
+	 * not an error condition. We'll just end up hitting the "goto retry"
+	 * case below.
+	 */
+	wait_event_timeout(vblank->queue,
+		drm_crtc_vblank_count(&crtc->base) != work->scheduled_vblank,
+		msecs_to_jiffies(50));
+
+	mutex_lock(&fbc->lock);
+
+	/* Were we cancelled? */
+	if (!work->scheduled)
+		goto out;
+
+	/* Were we delayed again while this function was sleeping? */
+	if (drm_crtc_vblank_count(&crtc->base) == work->scheduled_vblank) {
+		mutex_unlock(&fbc->lock);
+		goto retry;
+	}
+
+	intel_fbc_hw_activate(dev_priv);
+
+	work->scheduled = false;
+
+out:
+	mutex_unlock(&fbc->lock);
+	drm_crtc_vblank_put(&crtc->base);
+}
+
+static void intel_fbc_schedule_activation(struct intel_crtc *crtc)
+{
+	struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
+	struct intel_fbc *fbc = &dev_priv->fbc;
+	struct intel_fbc_work *work = &fbc->work;
+
+	WARN_ON(!mutex_is_locked(&fbc->lock));
+
+	if (drm_crtc_vblank_get(&crtc->base)) {
+		DRM_ERROR("vblank not available for FBC on pipe %c\n",
+			  pipe_name(crtc->pipe));
+		return;
+	}
+
+	/* It is useless to call intel_fbc_cancel_work() or cancel_work() in
+	 * this function since we're not releasing fbc.lock, so it won't have an
+	 * opportunity to grab it to discover that it was cancelled. So we just
+	 * update the expected jiffy count. */
+	work->scheduled = true;
+	work->scheduled_vblank = drm_crtc_vblank_count(&crtc->base);
+	drm_crtc_vblank_put(&crtc->base);
+
+	schedule_work(&work->work);
+}
+
+static void intel_fbc_deactivate(struct drm_i915_private *dev_priv)
+{
+	struct intel_fbc *fbc = &dev_priv->fbc;
+
+	WARN_ON(!mutex_is_locked(&fbc->lock));
+
+	/* Calling cancel_work() here won't help due to the fact that the work
+	 * function grabs fbc->lock. Just set scheduled to false so the work
+	 * function can know it was cancelled. */
+	fbc->work.scheduled = false;
+
+	if (fbc->active)
+		intel_fbc_hw_deactivate(dev_priv);
+}
+
+static bool multiple_pipes_ok(struct intel_crtc *crtc)
+{
+	struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
+	struct drm_plane *primary = crtc->base.primary;
+	struct intel_fbc *fbc = &dev_priv->fbc;
+	enum pipe pipe = crtc->pipe;
+
+	/* Don't even bother tracking anything we don't need. */
+	if (!no_fbc_on_multiple_pipes(dev_priv))
+		return true;
+
+	WARN_ON(!drm_modeset_is_locked(&primary->mutex));
+
+	if (to_intel_plane_state(primary->state)->visible)
+		fbc->visible_pipes_mask |= (1 << pipe);
+	else
+		fbc->visible_pipes_mask &= ~(1 << pipe);
+
+	return (fbc->visible_pipes_mask & ~(1 << pipe)) != 0;
+}
+
+static int find_compression_threshold(struct drm_i915_private *dev_priv,
+				      struct drm_mm_node *node,
+				      int size,
+				      int fb_cpp)
+{
+	struct i915_ggtt *ggtt = &dev_priv->ggtt;
+	int compression_threshold = 1;
+	int ret;
+	u64 end;
+
+	/* The FBC hardware for BDW/SKL doesn't have access to the stolen
+	 * reserved range size, so it always assumes the maximum (8mb) is used.
+	 * If we enable FBC using a CFB on that memory range we'll get FIFO
+	 * underruns, even if that range is not reserved by the BIOS. */
+	if (IS_BROADWELL(dev_priv) ||
+	    IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv))
+		end = ggtt->stolen_size - 8 * 1024 * 1024;
+	else
+		end = ggtt->stolen_usable_size;
+
+	/* HACK: This code depends on what we will do in *_enable_fbc. If that
+	 * code changes, this code needs to change as well.
+	 *
+	 * The enable_fbc code will attempt to use one of our 2 compression
+	 * thresholds, therefore, in that case, we only have 1 resort.
+	 */
+
+	/* Try to over-allocate to reduce reallocations and fragmentation. */
+	ret = i915_gem_stolen_insert_node_in_range(dev_priv, node, size <<= 1,
+						   4096, 0, end);
+	if (ret == 0)
+		return compression_threshold;
+
+again:
+	/* HW's ability to limit the CFB is 1:4 */
+	if (compression_threshold > 4 ||
+	    (fb_cpp == 2 && compression_threshold == 2))
+		return 0;
+
+	ret = i915_gem_stolen_insert_node_in_range(dev_priv, node, size >>= 1,
+						   4096, 0, end);
+	if (ret && INTEL_INFO(dev_priv)->gen <= 4) {
+		return 0;
+	} else if (ret) {
+		compression_threshold <<= 1;
+		goto again;
+	} else {
+		return compression_threshold;
+	}
+}
+
+static int intel_fbc_alloc_cfb(struct intel_crtc *crtc)
+{
+	struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
+	struct intel_fbc *fbc = &dev_priv->fbc;
+	struct drm_mm_node *uninitialized_var(compressed_llb);
+	int size, fb_cpp, ret;
+
+	WARN_ON(drm_mm_node_allocated(&fbc->compressed_fb));
+
+	size = intel_fbc_calculate_cfb_size(dev_priv, &fbc->state_cache);
+	fb_cpp = drm_format_plane_cpp(fbc->state_cache.fb.pixel_format, 0);
+
+	ret = find_compression_threshold(dev_priv, &fbc->compressed_fb,
+					 size, fb_cpp);
+	if (!ret)
+		goto err_llb;
+	else if (ret > 1) {
+		DRM_INFO("Reducing the compressed framebuffer size. This may lead to less power savings than a non-reduced-size. Try to increase stolen memory size if available in BIOS.\n");
+
+	}
+
+	fbc->threshold = ret;
+
+	if (INTEL_INFO(dev_priv)->gen >= 5)
+		I915_WRITE(ILK_DPFC_CB_BASE, fbc->compressed_fb.start);
+	else if (IS_GM45(dev_priv)) {
+		I915_WRITE(DPFC_CB_BASE, fbc->compressed_fb.start);
+	} else {
+		compressed_llb = kzalloc(sizeof(*compressed_llb), GFP_KERNEL);
+		if (!compressed_llb)
+			goto err_fb;
+
+		ret = i915_gem_stolen_insert_node(dev_priv, compressed_llb,
+						  4096, 4096);
+		if (ret)
+			goto err_fb;
+
+		fbc->compressed_llb = compressed_llb;
+
+		I915_WRITE(FBC_CFB_BASE,
+			   dev_priv->mm.stolen_base + fbc->compressed_fb.start);
+		I915_WRITE(FBC_LL_BASE,
+			   dev_priv->mm.stolen_base + compressed_llb->start);
+	}
+
+	DRM_DEBUG_KMS("reserved %llu bytes of contiguous stolen space for FBC, threshold: %d\n",
+		      fbc->compressed_fb.size, fbc->threshold);
+
+	return 0;
+
+err_fb:
+	kfree(compressed_llb);
+	i915_gem_stolen_remove_node(dev_priv, &fbc->compressed_fb);
+err_llb:
+	pr_info_once("drm: not enough stolen space for compressed buffer (need %d more bytes), disabling. Hint: you may be able to increase stolen memory size in the BIOS to avoid this.\n", size);
+	return -ENOSPC;
+}
+
+static void __intel_fbc_cleanup_cfb(struct drm_i915_private *dev_priv)
+{
+	struct intel_fbc *fbc = &dev_priv->fbc;
+
+	if (drm_mm_node_allocated(&fbc->compressed_fb))
+		i915_gem_stolen_remove_node(dev_priv, &fbc->compressed_fb);
+
+	if (fbc->compressed_llb) {
+		i915_gem_stolen_remove_node(dev_priv, fbc->compressed_llb);
+		kfree(fbc->compressed_llb);
+	}
+}
+
+void intel_fbc_cleanup_cfb(struct drm_i915_private *dev_priv)
+{
+	struct intel_fbc *fbc = &dev_priv->fbc;
+
+	if (!fbc_supported(dev_priv))
+		return;
+
+	mutex_lock(&fbc->lock);
+	__intel_fbc_cleanup_cfb(dev_priv);
+	mutex_unlock(&fbc->lock);
+}
+
+static bool stride_is_valid(struct drm_i915_private *dev_priv,
+			    unsigned int stride)
+{
+	/* These should have been caught earlier. */
+	WARN_ON(stride < 512);
+	WARN_ON((stride & (64 - 1)) != 0);
+
+	/* Below are the additional FBC restrictions. */
+
+	if (IS_GEN2(dev_priv) || IS_GEN3(dev_priv))
+		return stride == 4096 || stride == 8192;
+
+	if (IS_GEN4(dev_priv) && !IS_G4X(dev_priv) && stride < 2048)
+		return false;
+
+	if (stride > 16384)
+		return false;
+
+	return true;
+}
+
+static bool pixel_format_is_valid(struct drm_i915_private *dev_priv,
+				  uint32_t pixel_format)
+{
+	switch (pixel_format) {
+	case DRM_FORMAT_XRGB8888:
+	case DRM_FORMAT_XBGR8888:
+		return true;
+	case DRM_FORMAT_XRGB1555:
+	case DRM_FORMAT_RGB565:
+		/* 16bpp not supported on gen2 */
+		if (IS_GEN2(dev_priv))
+			return false;
+		/* WaFbcOnly1to1Ratio:ctg */
+		if (IS_G4X(dev_priv))
+			return false;
+		return true;
+	default:
+		return false;
+	}
+}
+
+/*
+ * For some reason, the hardware tracking starts looking at whatever we
+ * programmed as the display plane base address register. It does not look at
+ * the X and Y offset registers. That's why we look at the crtc->adjusted{x,y}
+ * variables instead of just looking at the pipe/plane size.
+ */
+static bool intel_fbc_hw_tracking_covers_screen(struct intel_crtc *crtc)
+{
+	struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
+	struct intel_fbc *fbc = &dev_priv->fbc;
+	unsigned int effective_w, effective_h, max_w, max_h;
+
+	if (INTEL_INFO(dev_priv)->gen >= 8 || IS_HASWELL(dev_priv)) {
+		max_w = 4096;
+		max_h = 4096;
+	} else if (IS_G4X(dev_priv) || INTEL_INFO(dev_priv)->gen >= 5) {
+		max_w = 4096;
+		max_h = 2048;
+	} else {
+		max_w = 2048;
+		max_h = 1536;
+	}
+
+	intel_fbc_get_plane_source_size(&fbc->state_cache, &effective_w,
+					&effective_h);
+	effective_w += crtc->adjusted_x;
+	effective_h += crtc->adjusted_y;
+
+	return effective_w <= max_w && effective_h <= max_h;
+}
+
+static void intel_fbc_update_state_cache(struct intel_crtc *crtc)
+{
+	struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
+	struct intel_fbc *fbc = &dev_priv->fbc;
+	struct intel_fbc_state_cache *cache = &fbc->state_cache;
+	struct intel_crtc_state *crtc_state =
+		to_intel_crtc_state(crtc->base.state);
+	struct intel_plane_state *plane_state =
+		to_intel_plane_state(crtc->base.primary->state);
+	struct drm_framebuffer *fb = plane_state->base.fb;
+	struct drm_i915_gem_object *obj;
+
+	WARN_ON(!drm_modeset_is_locked(&crtc->base.mutex));
+	WARN_ON(!drm_modeset_is_locked(&crtc->base.primary->mutex));
+
+	cache->crtc.mode_flags = crtc_state->base.adjusted_mode.flags;
+	if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv))
+		cache->crtc.hsw_bdw_pixel_rate =
+			ilk_pipe_pixel_rate(crtc_state);
+
+	cache->plane.rotation = plane_state->base.rotation;
+	cache->plane.src_w = drm_rect_width(&plane_state->src) >> 16;
+	cache->plane.src_h = drm_rect_height(&plane_state->src) >> 16;
+	cache->plane.visible = plane_state->visible;
+
+	if (!cache->plane.visible)
+		return;
+
+	obj = intel_fb_obj(fb);
+
+	/* FIXME: We lack the proper locking here, so only run this on the
+	 * platforms that need. */
+	if (INTEL_INFO(dev_priv)->gen >= 5 && INTEL_INFO(dev_priv)->gen < 7)
+		cache->fb.ilk_ggtt_offset = i915_gem_obj_ggtt_offset(obj);
+	cache->fb.pixel_format = fb->pixel_format;
+	cache->fb.stride = fb->pitches[0];
+	cache->fb.fence_reg = obj->fence_reg;
+	cache->fb.tiling_mode = obj->tiling_mode;
+}
+
+static bool intel_fbc_can_activate(struct intel_crtc *crtc)
+{
+	struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
+	struct intel_fbc *fbc = &dev_priv->fbc;
+	struct intel_fbc_state_cache *cache = &fbc->state_cache;
+
+	if (!cache->plane.visible) {
+		fbc->no_fbc_reason = "primary plane not visible";
+		return false;
+	}
+
+	if ((cache->crtc.mode_flags & DRM_MODE_FLAG_INTERLACE) ||
+	    (cache->crtc.mode_flags & DRM_MODE_FLAG_DBLSCAN)) {
+		fbc->no_fbc_reason = "incompatible mode";
+		return false;
+	}
+
+	if (!intel_fbc_hw_tracking_covers_screen(crtc)) {
+		fbc->no_fbc_reason = "mode too large for compression";
+		return false;
+	}
+
+	/* The use of a CPU fence is mandatory in order to detect writes
+	 * by the CPU to the scanout and trigger updates to the FBC.
+	 */
+	if (cache->fb.tiling_mode != I915_TILING_X ||
+	    cache->fb.fence_reg == I915_FENCE_REG_NONE) {
+		fbc->no_fbc_reason = "framebuffer not tiled or fenced";
+		return false;
+	}
+	if (INTEL_INFO(dev_priv)->gen <= 4 && !IS_G4X(dev_priv) &&
+	    cache->plane.rotation != BIT(DRM_ROTATE_0)) {
+		fbc->no_fbc_reason = "rotation unsupported";
+		return false;
+	}
+
+	if (!stride_is_valid(dev_priv, cache->fb.stride)) {
+		fbc->no_fbc_reason = "framebuffer stride not supported";
+		return false;
+	}
+
+	if (!pixel_format_is_valid(dev_priv, cache->fb.pixel_format)) {
+		fbc->no_fbc_reason = "pixel format is invalid";
+		return false;
+	}
+
+	/* WaFbcExceedCdClockThreshold:hsw,bdw */
+	if ((IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) &&
+	    cache->crtc.hsw_bdw_pixel_rate >= dev_priv->cdclk_freq * 95 / 100) {
+		fbc->no_fbc_reason = "pixel rate is too big";
+		return false;
+	}
+
+	/* It is possible for the required CFB size change without a
+	 * crtc->disable + crtc->enable since it is possible to change the
+	 * stride without triggering a full modeset. Since we try to
+	 * over-allocate the CFB, there's a chance we may keep FBC enabled even
+	 * if this happens, but if we exceed the current CFB size we'll have to
+	 * disable FBC. Notice that it would be possible to disable FBC, wait
+	 * for a frame, free the stolen node, then try to reenable FBC in case
+	 * we didn't get any invalidate/deactivate calls, but this would require
+	 * a lot of tracking just for a specific case. If we conclude it's an
+	 * important case, we can implement it later. */
+	if (intel_fbc_calculate_cfb_size(dev_priv, &fbc->state_cache) >
+	    fbc->compressed_fb.size * fbc->threshold) {
+		fbc->no_fbc_reason = "CFB requirements changed";
+		return false;
+	}
+
+	return true;
+}
+
+static bool intel_fbc_can_choose(struct intel_crtc *crtc)
+{
+	struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
+	struct intel_fbc *fbc = &dev_priv->fbc;
+	bool enable_by_default = IS_BROADWELL(dev_priv);
+
+	if (intel_vgpu_active(dev_priv->dev)) {
+		fbc->no_fbc_reason = "VGPU is active";
+		return false;
+	}
+
+	if (i915.enable_fbc < 0 && !enable_by_default) {
+		fbc->no_fbc_reason = "disabled per chip default";
+		return false;
+	}
+
+	if (!i915.enable_fbc) {
+		fbc->no_fbc_reason = "disabled per module param";
+		return false;
+	}
+
+	if (fbc_on_pipe_a_only(dev_priv) && crtc->pipe != PIPE_A) {
+		fbc->no_fbc_reason = "no enabled pipes can have FBC";
+		return false;
+	}
+
+	if (fbc_on_plane_a_only(dev_priv) && crtc->plane != PLANE_A) {
+		fbc->no_fbc_reason = "no enabled planes can have FBC";
+		return false;
+	}
+
+	return true;
+}
+
+static void intel_fbc_get_reg_params(struct intel_crtc *crtc,
+				     struct intel_fbc_reg_params *params)
+{
+	struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
+	struct intel_fbc *fbc = &dev_priv->fbc;
+	struct intel_fbc_state_cache *cache = &fbc->state_cache;
+
+	/* Since all our fields are integer types, use memset here so the
+	 * comparison function can rely on memcmp because the padding will be
+	 * zero. */
+	memset(params, 0, sizeof(*params));
+
+	params->crtc.pipe = crtc->pipe;
+	params->crtc.plane = crtc->plane;
+	params->crtc.fence_y_offset = get_crtc_fence_y_offset(crtc);
+
+	params->fb.pixel_format = cache->fb.pixel_format;
+	params->fb.stride = cache->fb.stride;
+	params->fb.fence_reg = cache->fb.fence_reg;
+
+	params->cfb_size = intel_fbc_calculate_cfb_size(dev_priv, cache);
+
+	params->fb.ggtt_offset = cache->fb.ilk_ggtt_offset;
+}
+
+static bool intel_fbc_reg_params_equal(struct intel_fbc_reg_params *params1,
+				       struct intel_fbc_reg_params *params2)
+{
+	/* We can use this since intel_fbc_get_reg_params() does a memset. */
+	return memcmp(params1, params2, sizeof(*params1)) == 0;
+}
+
+void intel_fbc_pre_update(struct intel_crtc *crtc)
+{
+	struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
+	struct intel_fbc *fbc = &dev_priv->fbc;
+
+	if (!fbc_supported(dev_priv))
+		return;
+
+	mutex_lock(&fbc->lock);
+
+	if (!multiple_pipes_ok(crtc)) {
+		fbc->no_fbc_reason = "more than one pipe active";
+		goto deactivate;
+	}
+
+	if (!fbc->enabled || fbc->crtc != crtc)
+		goto unlock;
+
+	intel_fbc_update_state_cache(crtc);
+
+deactivate:
+	intel_fbc_deactivate(dev_priv);
+unlock:
+	mutex_unlock(&fbc->lock);
+}
+
+static void __intel_fbc_post_update(struct intel_crtc *crtc)
+{
+	struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
+	struct intel_fbc *fbc = &dev_priv->fbc;
+	struct intel_fbc_reg_params old_params;
+
+	WARN_ON(!mutex_is_locked(&fbc->lock));
+
+	if (!fbc->enabled || fbc->crtc != crtc)
+		return;
+
+	if (!intel_fbc_can_activate(crtc)) {
+		WARN_ON(fbc->active);
+		return;
+	}
+
+	old_params = fbc->params;
+	intel_fbc_get_reg_params(crtc, &fbc->params);
+
+	/* If the scanout has not changed, don't modify the FBC settings.
+	 * Note that we make the fundamental assumption that the fb->obj
+	 * cannot be unpinned (and have its GTT offset and fence revoked)
+	 * without first being decoupled from the scanout and FBC disabled.
+	 */
+	if (fbc->active &&
+	    intel_fbc_reg_params_equal(&old_params, &fbc->params))
+		return;
+
+	intel_fbc_deactivate(dev_priv);
+	intel_fbc_schedule_activation(crtc);
+	fbc->no_fbc_reason = "FBC enabled (active or scheduled)";
+}
+
+void intel_fbc_post_update(struct intel_crtc *crtc)
+{
+	struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
+	struct intel_fbc *fbc = &dev_priv->fbc;
+
+	if (!fbc_supported(dev_priv))
+		return;
+
+	mutex_lock(&fbc->lock);
+	__intel_fbc_post_update(crtc);
+	mutex_unlock(&fbc->lock);
+}
+
+static unsigned int intel_fbc_get_frontbuffer_bit(struct intel_fbc *fbc)
+{
+	if (fbc->enabled)
+		return to_intel_plane(fbc->crtc->base.primary)->frontbuffer_bit;
+	else
+		return fbc->possible_framebuffer_bits;
+}
+
+void intel_fbc_invalidate(struct drm_i915_private *dev_priv,
+			  unsigned int frontbuffer_bits,
+			  enum fb_op_origin origin)
+{
+	struct intel_fbc *fbc = &dev_priv->fbc;
+
+	if (!fbc_supported(dev_priv))
+		return;
+
+	if (origin == ORIGIN_GTT || origin == ORIGIN_FLIP)
+		return;
+
+	mutex_lock(&fbc->lock);
+
+	fbc->busy_bits |= intel_fbc_get_frontbuffer_bit(fbc) & frontbuffer_bits;
+
+	if (fbc->enabled && fbc->busy_bits)
+		intel_fbc_deactivate(dev_priv);
+
+	mutex_unlock(&fbc->lock);
+}
+
+void intel_fbc_flush(struct drm_i915_private *dev_priv,
+		     unsigned int frontbuffer_bits, enum fb_op_origin origin)
+{
+	struct intel_fbc *fbc = &dev_priv->fbc;
+
+	if (!fbc_supported(dev_priv))
+		return;
+
+	if (origin == ORIGIN_GTT || origin == ORIGIN_FLIP)
+		return;
+
+	mutex_lock(&fbc->lock);
+
+	fbc->busy_bits &= ~frontbuffer_bits;
+
+	if (!fbc->busy_bits && fbc->enabled &&
+	    (frontbuffer_bits & intel_fbc_get_frontbuffer_bit(fbc))) {
+		if (fbc->active)
+			intel_fbc_recompress(dev_priv);
+		else
+			__intel_fbc_post_update(fbc->crtc);
+	}
+
+	mutex_unlock(&fbc->lock);
+}
+
+/**
+ * intel_fbc_choose_crtc - select a CRTC to enable FBC on
+ * @dev_priv: i915 device instance
+ * @state: the atomic state structure
+ *
+ * This function looks at the proposed state for CRTCs and planes, then chooses
+ * which pipe is going to have FBC by setting intel_crtc_state->enable_fbc to
+ * true.
+ *
+ * Later, intel_fbc_enable is going to look for state->enable_fbc and then maybe
+ * enable FBC for the chosen CRTC. If it does, it will set dev_priv->fbc.crtc.
+ */
+void intel_fbc_choose_crtc(struct drm_i915_private *dev_priv,
+			   struct drm_atomic_state *state)
+{
+	struct intel_fbc *fbc = &dev_priv->fbc;
+	struct drm_crtc *crtc;
+	struct drm_crtc_state *crtc_state;
+	struct drm_plane *plane;
+	struct drm_plane_state *plane_state;
+	bool fbc_crtc_present = false;
+	int i, j;
+
+	mutex_lock(&fbc->lock);
+
+	for_each_crtc_in_state(state, crtc, crtc_state, i) {
+		if (fbc->crtc == to_intel_crtc(crtc)) {
+			fbc_crtc_present = true;
+			break;
+		}
+	}
+	/* This atomic commit doesn't involve the CRTC currently tied to FBC. */
+	if (!fbc_crtc_present && fbc->crtc != NULL)
+		goto out;
+
+	/* Simply choose the first CRTC that is compatible and has a visible
+	 * plane. We could go for fancier schemes such as checking the plane
+	 * size, but this would just affect the few platforms that don't tie FBC
+	 * to pipe or plane A. */
+	for_each_plane_in_state(state, plane, plane_state, i) {
+		struct intel_plane_state *intel_plane_state =
+			to_intel_plane_state(plane_state);
+
+		if (!intel_plane_state->visible)
+			continue;
+
+		for_each_crtc_in_state(state, crtc, crtc_state, j) {
+			struct intel_crtc_state *intel_crtc_state =
+				to_intel_crtc_state(crtc_state);
+
+			if (plane_state->crtc != crtc)
+				continue;
+
+			if (!intel_fbc_can_choose(to_intel_crtc(crtc)))
+				break;
+
+			intel_crtc_state->enable_fbc = true;
+			goto out;
+		}
+	}
+
+out:
+	mutex_unlock(&fbc->lock);
+}
+
+/**
+ * intel_fbc_enable: tries to enable FBC on the CRTC
+ * @crtc: the CRTC
+ *
+ * This function checks if the given CRTC was chosen for FBC, then enables it if
+ * possible. Notice that it doesn't activate FBC. It is valid to call
+ * intel_fbc_enable multiple times for the same pipe without an
+ * intel_fbc_disable in the middle, as long as it is deactivated.
+ */
+void intel_fbc_enable(struct intel_crtc *crtc)
+{
+	struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
+	struct intel_fbc *fbc = &dev_priv->fbc;
+
+	if (!fbc_supported(dev_priv))
+		return;
+
+	mutex_lock(&fbc->lock);
+
+	if (fbc->enabled) {
+		WARN_ON(fbc->crtc == NULL);
+		if (fbc->crtc == crtc) {
+			WARN_ON(!crtc->config->enable_fbc);
+			WARN_ON(fbc->active);
+		}
+		goto out;
+	}
+
+	if (!crtc->config->enable_fbc)
+		goto out;
+
+	WARN_ON(fbc->active);
+	WARN_ON(fbc->crtc != NULL);
+
+	intel_fbc_update_state_cache(crtc);
+	if (intel_fbc_alloc_cfb(crtc)) {
+		fbc->no_fbc_reason = "not enough stolen memory";
+		goto out;
+	}
+
+	DRM_DEBUG_KMS("Enabling FBC on pipe %c\n", pipe_name(crtc->pipe));
+	fbc->no_fbc_reason = "FBC enabled but not active yet\n";
+
+	fbc->enabled = true;
+	fbc->crtc = crtc;
+out:
+	mutex_unlock(&fbc->lock);
+}
+
+/**
+ * __intel_fbc_disable - disable FBC
+ * @dev_priv: i915 device instance
+ *
+ * This is the low level function that actually disables FBC. Callers should
+ * grab the FBC lock.
+ */
+static void __intel_fbc_disable(struct drm_i915_private *dev_priv)
+{
+	struct intel_fbc *fbc = &dev_priv->fbc;
+	struct intel_crtc *crtc = fbc->crtc;
+
+	WARN_ON(!mutex_is_locked(&fbc->lock));
+	WARN_ON(!fbc->enabled);
+	WARN_ON(fbc->active);
+	WARN_ON(crtc->active);
+
+	DRM_DEBUG_KMS("Disabling FBC on pipe %c\n", pipe_name(crtc->pipe));
+
+	__intel_fbc_cleanup_cfb(dev_priv);
+
+	fbc->enabled = false;
+	fbc->crtc = NULL;
+}
+
+/**
+ * intel_fbc_disable - disable FBC if it's associated with crtc
+ * @crtc: the CRTC
+ *
+ * This function disables FBC if it's associated with the provided CRTC.
+ */
+void intel_fbc_disable(struct intel_crtc *crtc)
+{
+	struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
+	struct intel_fbc *fbc = &dev_priv->fbc;
+
+	if (!fbc_supported(dev_priv))
+		return;
+
+	mutex_lock(&fbc->lock);
+	if (fbc->crtc == crtc) {
+		WARN_ON(!fbc->enabled);
+		WARN_ON(fbc->active);
+		__intel_fbc_disable(dev_priv);
+	}
+	mutex_unlock(&fbc->lock);
+
+	cancel_work_sync(&fbc->work.work);
+}
+
+/**
+ * intel_fbc_global_disable - globally disable FBC
+ * @dev_priv: i915 device instance
+ *
+ * This function disables FBC regardless of which CRTC is associated with it.
+ */
+void intel_fbc_global_disable(struct drm_i915_private *dev_priv)
+{
+	struct intel_fbc *fbc = &dev_priv->fbc;
+
+	if (!fbc_supported(dev_priv))
+		return;
+
+	mutex_lock(&fbc->lock);
+	if (fbc->enabled)
+		__intel_fbc_disable(dev_priv);
+	mutex_unlock(&fbc->lock);
+
+	cancel_work_sync(&fbc->work.work);
+}
+
+/**
+ * intel_fbc_init_pipe_state - initialize FBC's CRTC visibility tracking
+ * @dev_priv: i915 device instance
+ *
+ * The FBC code needs to track CRTC visibility since the older platforms can't
+ * have FBC enabled while multiple pipes are used. This function does the
+ * initial setup at driver load to make sure FBC is matching the real hardware.
+ */
+void intel_fbc_init_pipe_state(struct drm_i915_private *dev_priv)
+{
+	struct intel_crtc *crtc;
+
+	/* Don't even bother tracking anything if we don't need. */
+	if (!no_fbc_on_multiple_pipes(dev_priv))
+		return;
+
+	for_each_intel_crtc(dev_priv->dev, crtc)
+		if (intel_crtc_active(&crtc->base) &&
+		    to_intel_plane_state(crtc->base.primary->state)->visible)
+			dev_priv->fbc.visible_pipes_mask |= (1 << crtc->pipe);
+}
+
+/**
+ * intel_fbc_init - Initialize FBC
+ * @dev_priv: the i915 device
+ *
+ * This function might be called during PM init process.
+ */
+void intel_fbc_init(struct drm_i915_private *dev_priv)
+{
+	struct intel_fbc *fbc = &dev_priv->fbc;
+	enum pipe pipe;
+
+	INIT_WORK(&fbc->work.work, intel_fbc_work_fn);
+	mutex_init(&fbc->lock);
+	fbc->enabled = false;
+	fbc->active = false;
+	fbc->work.scheduled = false;
+
+	if (!HAS_FBC(dev_priv)) {
+		fbc->no_fbc_reason = "unsupported by this chipset";
+		return;
+	}
+
+	for_each_pipe(dev_priv, pipe) {
+		fbc->possible_framebuffer_bits |=
+				INTEL_FRONTBUFFER_PRIMARY(pipe);
+
+		if (fbc_on_pipe_a_only(dev_priv))
+			break;
+	}
+
+	/* This value was pulled out of someone's hat */
+	if (INTEL_INFO(dev_priv)->gen <= 4 && !IS_GM45(dev_priv))
+		I915_WRITE(FBC_CONTROL, 500 << FBC_CTL_INTERVAL_SHIFT);
+
+	/* We still don't have any sort of hardware state readout for FBC, so
+	 * deactivate it in case the BIOS activated it to make sure software
+	 * matches the hardware state. */
+	if (intel_fbc_hw_is_active(dev_priv))
+		intel_fbc_hw_deactivate(dev_priv);
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/i915/intel_fbdev.c
@@ -0,0 +1,837 @@
+/*
+ * Copyright © 2007 David Airlie
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *     David Airlie
+ */
+
+#include <linux/async.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/console.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/tty.h>
+#include <linux/sysrq.h>
+#include <linux/delay.h>
+#include <linux/fb.h>
+#include <linux/init.h>
+#include <linux/vga_switcheroo.h>
+
+#include <drm/drmP.h>
+#include <drm/drm_crtc.h>
+#include <drm/drm_fb_helper.h>
+#include "intel_drv.h"
+#include <drm/i915_drm.h>
+#include "i915_drv.h"
+
+static int intel_fbdev_set_par(struct fb_info *info)
+{
+	struct drm_fb_helper *fb_helper = info->par;
+	struct intel_fbdev *ifbdev =
+		container_of(fb_helper, struct intel_fbdev, helper);
+	int ret;
+
+	ret = drm_fb_helper_set_par(info);
+
+	if (ret == 0) {
+		mutex_lock(&fb_helper->dev->struct_mutex);
+		intel_fb_obj_invalidate(ifbdev->fb->obj, ORIGIN_GTT);
+		mutex_unlock(&fb_helper->dev->struct_mutex);
+	}
+
+	return ret;
+}
+
+static int intel_fbdev_blank(int blank, struct fb_info *info)
+{
+	struct drm_fb_helper *fb_helper = info->par;
+	struct intel_fbdev *ifbdev =
+		container_of(fb_helper, struct intel_fbdev, helper);
+	int ret;
+
+	ret = drm_fb_helper_blank(blank, info);
+
+	if (ret == 0) {
+		mutex_lock(&fb_helper->dev->struct_mutex);
+		intel_fb_obj_invalidate(ifbdev->fb->obj, ORIGIN_GTT);
+		mutex_unlock(&fb_helper->dev->struct_mutex);
+	}
+
+	return ret;
+}
+
+static int intel_fbdev_pan_display(struct fb_var_screeninfo *var,
+				   struct fb_info *info)
+{
+	struct drm_fb_helper *fb_helper = info->par;
+	struct intel_fbdev *ifbdev =
+		container_of(fb_helper, struct intel_fbdev, helper);
+
+	int ret;
+	ret = drm_fb_helper_pan_display(var, info);
+
+	if (ret == 0) {
+		mutex_lock(&fb_helper->dev->struct_mutex);
+		intel_fb_obj_invalidate(ifbdev->fb->obj, ORIGIN_GTT);
+		mutex_unlock(&fb_helper->dev->struct_mutex);
+	}
+
+	return ret;
+}
+
+static struct fb_ops intelfb_ops = {
+	.owner = THIS_MODULE,
+	.fb_check_var = drm_fb_helper_check_var,
+	.fb_set_par = intel_fbdev_set_par,
+	.fb_fillrect = drm_fb_helper_cfb_fillrect,
+	.fb_copyarea = drm_fb_helper_cfb_copyarea,
+	.fb_imageblit = drm_fb_helper_cfb_imageblit,
+	.fb_pan_display = intel_fbdev_pan_display,
+	.fb_blank = intel_fbdev_blank,
+	.fb_setcmap = drm_fb_helper_setcmap,
+	.fb_debug_enter = drm_fb_helper_debug_enter,
+	.fb_debug_leave = drm_fb_helper_debug_leave,
+};
+
+static int intelfb_alloc(struct drm_fb_helper *helper,
+			 struct drm_fb_helper_surface_size *sizes)
+{
+	struct intel_fbdev *ifbdev =
+		container_of(helper, struct intel_fbdev, helper);
+	struct drm_framebuffer *fb;
+	struct drm_device *dev = helper->dev;
+	struct drm_i915_private *dev_priv = to_i915(dev);
+	struct i915_ggtt *ggtt = &dev_priv->ggtt;
+	struct drm_mode_fb_cmd2 mode_cmd = {};
+	struct drm_i915_gem_object *obj = NULL;
+	int size, ret;
+
+	/* we don't do packed 24bpp */
+	if (sizes->surface_bpp == 24)
+		sizes->surface_bpp = 32;
+
+	mode_cmd.width = sizes->surface_width;
+	mode_cmd.height = sizes->surface_height;
+
+	mode_cmd.pitches[0] = ALIGN(mode_cmd.width *
+				    DIV_ROUND_UP(sizes->surface_bpp, 8), 64);
+	mode_cmd.pixel_format = drm_mode_legacy_fb_format(sizes->surface_bpp,
+							  sizes->surface_depth);
+
+	mutex_lock(&dev->struct_mutex);
+
+	size = mode_cmd.pitches[0] * mode_cmd.height;
+	size = PAGE_ALIGN(size);
+
+	/* If the FB is too big, just don't use it since fbdev is not very
+	 * important and we should probably use that space with FBC or other
+	 * features. */
+	if (size * 2 < ggtt->stolen_usable_size)
+		obj = i915_gem_object_create_stolen(dev, size);
+	if (obj == NULL)
+		obj = i915_gem_alloc_object(dev, size);
+	if (!obj) {
+		DRM_ERROR("failed to allocate framebuffer\n");
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	fb = __intel_framebuffer_create(dev, &mode_cmd, obj);
+	if (IS_ERR(fb)) {
+		drm_gem_object_unreference(&obj->base);
+		ret = PTR_ERR(fb);
+		goto out;
+	}
+
+	mutex_unlock(&dev->struct_mutex);
+
+	ifbdev->fb = to_intel_framebuffer(fb);
+
+	return 0;
+
+out:
+	mutex_unlock(&dev->struct_mutex);
+	return ret;
+}
+
+static int intelfb_create(struct drm_fb_helper *helper,
+			  struct drm_fb_helper_surface_size *sizes)
+{
+	struct intel_fbdev *ifbdev =
+		container_of(helper, struct intel_fbdev, helper);
+	struct intel_framebuffer *intel_fb = ifbdev->fb;
+	struct drm_device *dev = helper->dev;
+	struct drm_i915_private *dev_priv = to_i915(dev);
+	struct i915_ggtt *ggtt = &dev_priv->ggtt;
+	struct fb_info *info;
+	struct drm_framebuffer *fb;
+	struct drm_i915_gem_object *obj;
+	int size, ret;
+	bool prealloc = false;
+
+	if (intel_fb &&
+	    (sizes->fb_width > intel_fb->base.width ||
+	     sizes->fb_height > intel_fb->base.height)) {
+		DRM_DEBUG_KMS("BIOS fb too small (%dx%d), we require (%dx%d),"
+			      " releasing it\n",
+			      intel_fb->base.width, intel_fb->base.height,
+			      sizes->fb_width, sizes->fb_height);
+		drm_framebuffer_unreference(&intel_fb->base);
+		intel_fb = ifbdev->fb = NULL;
+	}
+	if (!intel_fb || WARN_ON(!intel_fb->obj)) {
+		DRM_DEBUG_KMS("no BIOS fb, allocating a new one\n");
+		ret = intelfb_alloc(helper, sizes);
+		if (ret)
+			return ret;
+		intel_fb = ifbdev->fb;
+	} else {
+		DRM_DEBUG_KMS("re-using BIOS fb\n");
+		prealloc = true;
+		sizes->fb_width = intel_fb->base.width;
+		sizes->fb_height = intel_fb->base.height;
+	}
+
+	obj = intel_fb->obj;
+	size = obj->base.size;
+
+	mutex_lock(&dev->struct_mutex);
+
+	/* Pin the GGTT vma for our access via info->screen_base.
+	 * This also validates that any existing fb inherited from the
+	 * BIOS is suitable for own access.
+	 */
+	ret = intel_pin_and_fence_fb_obj(&ifbdev->fb->base, BIT(DRM_ROTATE_0));
+	if (ret)
+		goto out_unlock;
+
+	info = drm_fb_helper_alloc_fbi(helper);
+	if (IS_ERR(info)) {
+		DRM_ERROR("Failed to allocate fb_info\n");
+		ret = PTR_ERR(info);
+		goto out_unpin;
+	}
+
+	info->par = helper;
+
+	fb = &ifbdev->fb->base;
+
+	ifbdev->helper.fb = fb;
+
+	strcpy(info->fix.id, "inteldrmfb");
+
+	info->flags = FBINFO_DEFAULT | FBINFO_CAN_FORCE_OUTPUT;
+	info->fbops = &intelfb_ops;
+
+	/* setup aperture base/size for vesafb takeover */
+	info->apertures->ranges[0].base = dev->mode_config.fb_base;
+	info->apertures->ranges[0].size = ggtt->mappable_end;
+
+	info->fix.smem_start = dev->mode_config.fb_base + i915_gem_obj_ggtt_offset(obj);
+	info->fix.smem_len = size;
+
+	info->screen_base =
+		ioremap_wc(ggtt->mappable_base + i915_gem_obj_ggtt_offset(obj),
+			   size);
+	if (!info->screen_base) {
+		DRM_ERROR("Failed to remap framebuffer into virtual memory\n");
+		ret = -ENOSPC;
+		goto out_destroy_fbi;
+	}
+	info->screen_size = size;
+
+	/* This driver doesn't need a VT switch to restore the mode on resume */
+	info->skip_vt_switch = true;
+
+	drm_fb_helper_fill_fix(info, fb->pitches[0], fb->depth);
+	drm_fb_helper_fill_var(info, &ifbdev->helper, sizes->fb_width, sizes->fb_height);
+
+	/* If the object is shmemfs backed, it will have given us zeroed pages.
+	 * If the object is stolen however, it will be full of whatever
+	 * garbage was left in there.
+	 */
+	if (ifbdev->fb->obj->stolen && !prealloc)
+		memset_io(info->screen_base, 0, info->screen_size);
+
+	/* Use default scratch pixmap (info->pixmap.flags = FB_PIXMAP_SYSTEM) */
+
+	DRM_DEBUG_KMS("allocated %dx%d fb: 0x%08llx, bo %p\n",
+		      fb->width, fb->height,
+		      i915_gem_obj_ggtt_offset(obj), obj);
+
+	mutex_unlock(&dev->struct_mutex);
+	vga_switcheroo_client_fb_set(dev->pdev, info);
+	return 0;
+
+out_destroy_fbi:
+	drm_fb_helper_release_fbi(helper);
+out_unpin:
+	i915_gem_object_ggtt_unpin(obj);
+out_unlock:
+	mutex_unlock(&dev->struct_mutex);
+	return ret;
+}
+
+/** Sets the color ramps on behalf of RandR */
+static void intel_crtc_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green,
+				    u16 blue, int regno)
+{
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+
+	intel_crtc->lut_r[regno] = red >> 8;
+	intel_crtc->lut_g[regno] = green >> 8;
+	intel_crtc->lut_b[regno] = blue >> 8;
+}
+
+static void intel_crtc_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green,
+				    u16 *blue, int regno)
+{
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+
+	*red = intel_crtc->lut_r[regno] << 8;
+	*green = intel_crtc->lut_g[regno] << 8;
+	*blue = intel_crtc->lut_b[regno] << 8;
+}
+
+static struct drm_fb_helper_crtc *
+intel_fb_helper_crtc(struct drm_fb_helper *fb_helper, struct drm_crtc *crtc)
+{
+	int i;
+
+	for (i = 0; i < fb_helper->crtc_count; i++)
+		if (fb_helper->crtc_info[i].mode_set.crtc == crtc)
+			return &fb_helper->crtc_info[i];
+
+	return NULL;
+}
+
+/*
+ * Try to read the BIOS display configuration and use it for the initial
+ * fb configuration.
+ *
+ * The BIOS or boot loader will generally create an initial display
+ * configuration for us that includes some set of active pipes and displays.
+ * This routine tries to figure out which pipes and connectors are active
+ * and stuffs them into the crtcs and modes array given to us by the
+ * drm_fb_helper code.
+ *
+ * The overall sequence is:
+ *   intel_fbdev_init - from driver load
+ *     intel_fbdev_init_bios - initialize the intel_fbdev using BIOS data
+ *     drm_fb_helper_init - build fb helper structs
+ *     drm_fb_helper_single_add_all_connectors - more fb helper structs
+ *   intel_fbdev_initial_config - apply the config
+ *     drm_fb_helper_initial_config - call ->probe then register_framebuffer()
+ *         drm_setup_crtcs - build crtc config for fbdev
+ *           intel_fb_initial_config - find active connectors etc
+ *         drm_fb_helper_single_fb_probe - set up fbdev
+ *           intelfb_create - re-use or alloc fb, build out fbdev structs
+ *
+ * Note that we don't make special consideration whether we could actually
+ * switch to the selected modes without a full modeset. E.g. when the display
+ * is in VGA mode we need to recalculate watermarks and set a new high-res
+ * framebuffer anyway.
+ */
+static bool intel_fb_initial_config(struct drm_fb_helper *fb_helper,
+				    struct drm_fb_helper_crtc **crtcs,
+				    struct drm_display_mode **modes,
+				    struct drm_fb_offset *offsets,
+				    bool *enabled, int width, int height)
+{
+	struct drm_device *dev = fb_helper->dev;
+	int i, j;
+	bool *save_enabled;
+	bool fallback = true;
+	int num_connectors_enabled = 0;
+	int num_connectors_detected = 0;
+	uint64_t conn_configured = 0, mask;
+	int pass = 0;
+
+	save_enabled = kcalloc(fb_helper->connector_count, sizeof(bool),
+			       GFP_KERNEL);
+	if (!save_enabled)
+		return false;
+
+	memcpy(save_enabled, enabled, fb_helper->connector_count);
+	mask = (1 << fb_helper->connector_count) - 1;
+retry:
+	for (i = 0; i < fb_helper->connector_count; i++) {
+		struct drm_fb_helper_connector *fb_conn;
+		struct drm_connector *connector;
+		struct drm_encoder *encoder;
+		struct drm_fb_helper_crtc *new_crtc;
+		struct intel_crtc *intel_crtc;
+
+		fb_conn = fb_helper->connector_info[i];
+		connector = fb_conn->connector;
+
+		if (conn_configured & (1 << i))
+			continue;
+
+		if (pass == 0 && !connector->has_tile)
+			continue;
+
+		if (connector->status == connector_status_connected)
+			num_connectors_detected++;
+
+		if (!enabled[i]) {
+			DRM_DEBUG_KMS("connector %s not enabled, skipping\n",
+				      connector->name);
+			conn_configured |= (1 << i);
+			continue;
+		}
+
+		if (connector->force == DRM_FORCE_OFF) {
+			DRM_DEBUG_KMS("connector %s is disabled by user, skipping\n",
+				      connector->name);
+			enabled[i] = false;
+			continue;
+		}
+
+		encoder = connector->state->best_encoder;
+		if (!encoder || WARN_ON(!connector->state->crtc)) {
+			if (connector->force > DRM_FORCE_OFF)
+				goto bail;
+
+			DRM_DEBUG_KMS("connector %s has no encoder or crtc, skipping\n",
+				      connector->name);
+			enabled[i] = false;
+			conn_configured |= (1 << i);
+			continue;
+		}
+
+		num_connectors_enabled++;
+
+		intel_crtc = to_intel_crtc(connector->state->crtc);
+		for (j = 0; j < 256; j++) {
+			intel_crtc->lut_r[j] = j;
+			intel_crtc->lut_g[j] = j;
+			intel_crtc->lut_b[j] = j;
+		}
+
+		new_crtc = intel_fb_helper_crtc(fb_helper, connector->state->crtc);
+
+		/*
+		 * Make sure we're not trying to drive multiple connectors
+		 * with a single CRTC, since our cloning support may not
+		 * match the BIOS.
+		 */
+		for (j = 0; j < fb_helper->connector_count; j++) {
+			if (crtcs[j] == new_crtc) {
+				DRM_DEBUG_KMS("fallback: cloned configuration\n");
+				goto bail;
+			}
+		}
+
+		DRM_DEBUG_KMS("looking for cmdline mode on connector %s\n",
+			      connector->name);
+
+		/* go for command line mode first */
+		modes[i] = drm_pick_cmdline_mode(fb_conn, width, height);
+
+		/* try for preferred next */
+		if (!modes[i]) {
+			DRM_DEBUG_KMS("looking for preferred mode on connector %s %d\n",
+				      connector->name, connector->has_tile);
+			modes[i] = drm_has_preferred_mode(fb_conn, width,
+							  height);
+		}
+
+		/* No preferred mode marked by the EDID? Are there any modes? */
+		if (!modes[i] && !list_empty(&connector->modes)) {
+			DRM_DEBUG_KMS("using first mode listed on connector %s\n",
+				      connector->name);
+			modes[i] = list_first_entry(&connector->modes,
+						    struct drm_display_mode,
+						    head);
+		}
+
+		/* last resort: use current mode */
+		if (!modes[i]) {
+			/*
+			 * IMPORTANT: We want to use the adjusted mode (i.e.
+			 * after the panel fitter upscaling) as the initial
+			 * config, not the input mode, which is what crtc->mode
+			 * usually contains. But since our current
+			 * code puts a mode derived from the post-pfit timings
+			 * into crtc->mode this works out correctly.
+			 *
+			 * This is crtc->mode and not crtc->state->mode for the
+			 * fastboot check to work correctly. crtc_state->mode has
+			 * I915_MODE_FLAG_INHERITED, which we clear to force check
+			 * state.
+			 */
+			DRM_DEBUG_KMS("looking for current mode on connector %s\n",
+				      connector->name);
+			modes[i] = &connector->state->crtc->mode;
+		}
+		crtcs[i] = new_crtc;
+
+		DRM_DEBUG_KMS("connector %s on pipe %c [CRTC:%d]: %dx%d%s\n",
+			      connector->name,
+			      pipe_name(to_intel_crtc(connector->state->crtc)->pipe),
+			      connector->state->crtc->base.id,
+			      modes[i]->hdisplay, modes[i]->vdisplay,
+			      modes[i]->flags & DRM_MODE_FLAG_INTERLACE ? "i" :"");
+
+		fallback = false;
+		conn_configured |= (1 << i);
+	}
+
+	if ((conn_configured & mask) != mask) {
+		pass++;
+		goto retry;
+	}
+
+	/*
+	 * If the BIOS didn't enable everything it could, fall back to have the
+	 * same user experiencing of lighting up as much as possible like the
+	 * fbdev helper library.
+	 */
+	if (num_connectors_enabled != num_connectors_detected &&
+	    num_connectors_enabled < INTEL_INFO(dev)->num_pipes) {
+		DRM_DEBUG_KMS("fallback: Not all outputs enabled\n");
+		DRM_DEBUG_KMS("Enabled: %i, detected: %i\n", num_connectors_enabled,
+			      num_connectors_detected);
+		fallback = true;
+	}
+
+	if (fallback) {
+bail:
+		DRM_DEBUG_KMS("Not using firmware configuration\n");
+		memcpy(enabled, save_enabled, fb_helper->connector_count);
+		kfree(save_enabled);
+		return false;
+	}
+
+	kfree(save_enabled);
+	return true;
+}
+
+static const struct drm_fb_helper_funcs intel_fb_helper_funcs = {
+	.initial_config = intel_fb_initial_config,
+	.gamma_set = intel_crtc_fb_gamma_set,
+	.gamma_get = intel_crtc_fb_gamma_get,
+	.fb_probe = intelfb_create,
+};
+
+static void intel_fbdev_destroy(struct drm_device *dev,
+				struct intel_fbdev *ifbdev)
+{
+	/* We rely on the object-free to release the VMA pinning for
+	 * the info->screen_base mmaping. Leaking the VMA is simpler than
+	 * trying to rectify all the possible error paths leading here.
+	 */
+
+	drm_fb_helper_unregister_fbi(&ifbdev->helper);
+	drm_fb_helper_release_fbi(&ifbdev->helper);
+
+	drm_fb_helper_fini(&ifbdev->helper);
+
+	if (ifbdev->fb) {
+		drm_framebuffer_unregister_private(&ifbdev->fb->base);
+		drm_framebuffer_remove(&ifbdev->fb->base);
+	}
+}
+
+/*
+ * Build an intel_fbdev struct using a BIOS allocated framebuffer, if possible.
+ * The core display code will have read out the current plane configuration,
+ * so we use that to figure out if there's an object for us to use as the
+ * fb, and if so, we re-use it for the fbdev configuration.
+ *
+ * Note we only support a single fb shared across pipes for boot (mostly for
+ * fbcon), so we just find the biggest and use that.
+ */
+static bool intel_fbdev_init_bios(struct drm_device *dev,
+				 struct intel_fbdev *ifbdev)
+{
+	struct intel_framebuffer *fb = NULL;
+	struct drm_crtc *crtc;
+	struct intel_crtc *intel_crtc;
+	unsigned int max_size = 0;
+
+	/* Find the largest fb */
+	for_each_crtc(dev, crtc) {
+		struct drm_i915_gem_object *obj =
+			intel_fb_obj(crtc->primary->state->fb);
+		intel_crtc = to_intel_crtc(crtc);
+
+		if (!crtc->state->active || !obj) {
+			DRM_DEBUG_KMS("pipe %c not active or no fb, skipping\n",
+				      pipe_name(intel_crtc->pipe));
+			continue;
+		}
+
+		if (obj->base.size > max_size) {
+			DRM_DEBUG_KMS("found possible fb from plane %c\n",
+				      pipe_name(intel_crtc->pipe));
+			fb = to_intel_framebuffer(crtc->primary->state->fb);
+			max_size = obj->base.size;
+		}
+	}
+
+	if (!fb) {
+		DRM_DEBUG_KMS("no active fbs found, not using BIOS config\n");
+		goto out;
+	}
+
+	/* Now make sure all the pipes will fit into it */
+	for_each_crtc(dev, crtc) {
+		unsigned int cur_size;
+
+		intel_crtc = to_intel_crtc(crtc);
+
+		if (!crtc->state->active) {
+			DRM_DEBUG_KMS("pipe %c not active, skipping\n",
+				      pipe_name(intel_crtc->pipe));
+			continue;
+		}
+
+		DRM_DEBUG_KMS("checking plane %c for BIOS fb\n",
+			      pipe_name(intel_crtc->pipe));
+
+		/*
+		 * See if the plane fb we found above will fit on this
+		 * pipe.  Note we need to use the selected fb's pitch and bpp
+		 * rather than the current pipe's, since they differ.
+		 */
+		cur_size = intel_crtc->config->base.adjusted_mode.crtc_hdisplay;
+		cur_size = cur_size * fb->base.bits_per_pixel / 8;
+		if (fb->base.pitches[0] < cur_size) {
+			DRM_DEBUG_KMS("fb not wide enough for plane %c (%d vs %d)\n",
+				      pipe_name(intel_crtc->pipe),
+				      cur_size, fb->base.pitches[0]);
+			fb = NULL;
+			break;
+		}
+
+		cur_size = intel_crtc->config->base.adjusted_mode.crtc_vdisplay;
+		cur_size = intel_fb_align_height(dev, cur_size,
+						 fb->base.pixel_format,
+						 fb->base.modifier[0]);
+		cur_size *= fb->base.pitches[0];
+		DRM_DEBUG_KMS("pipe %c area: %dx%d, bpp: %d, size: %d\n",
+			      pipe_name(intel_crtc->pipe),
+			      intel_crtc->config->base.adjusted_mode.crtc_hdisplay,
+			      intel_crtc->config->base.adjusted_mode.crtc_vdisplay,
+			      fb->base.bits_per_pixel,
+			      cur_size);
+
+		if (cur_size > max_size) {
+			DRM_DEBUG_KMS("fb not big enough for plane %c (%d vs %d)\n",
+				      pipe_name(intel_crtc->pipe),
+				      cur_size, max_size);
+			fb = NULL;
+			break;
+		}
+
+		DRM_DEBUG_KMS("fb big enough for plane %c (%d >= %d)\n",
+			      pipe_name(intel_crtc->pipe),
+			      max_size, cur_size);
+	}
+
+	if (!fb) {
+		DRM_DEBUG_KMS("BIOS fb not suitable for all pipes, not using\n");
+		goto out;
+	}
+
+	ifbdev->preferred_bpp = fb->base.bits_per_pixel;
+	ifbdev->fb = fb;
+
+	drm_framebuffer_reference(&ifbdev->fb->base);
+
+	/* Final pass to check if any active pipes don't have fbs */
+	for_each_crtc(dev, crtc) {
+		intel_crtc = to_intel_crtc(crtc);
+
+		if (!crtc->state->active)
+			continue;
+
+		WARN(!crtc->primary->fb,
+		     "re-used BIOS config but lost an fb on crtc %d\n",
+		     crtc->base.id);
+	}
+
+
+	DRM_DEBUG_KMS("using BIOS fb for initial console\n");
+	return true;
+
+out:
+
+	return false;
+}
+
+static void intel_fbdev_suspend_worker(struct work_struct *work)
+{
+	intel_fbdev_set_suspend(container_of(work,
+					     struct drm_i915_private,
+					     fbdev_suspend_work)->dev,
+				FBINFO_STATE_RUNNING,
+				true);
+}
+
+int intel_fbdev_init(struct drm_device *dev)
+{
+	struct intel_fbdev *ifbdev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	int ret;
+
+	if (WARN_ON(INTEL_INFO(dev)->num_pipes == 0))
+		return -ENODEV;
+
+	ifbdev = kzalloc(sizeof(struct intel_fbdev), GFP_KERNEL);
+	if (ifbdev == NULL)
+		return -ENOMEM;
+
+	drm_fb_helper_prepare(dev, &ifbdev->helper, &intel_fb_helper_funcs);
+
+	if (!intel_fbdev_init_bios(dev, ifbdev))
+		ifbdev->preferred_bpp = 32;
+
+	ret = drm_fb_helper_init(dev, &ifbdev->helper,
+				 INTEL_INFO(dev)->num_pipes, 4);
+	if (ret) {
+		kfree(ifbdev);
+		return ret;
+	}
+
+	ifbdev->helper.atomic = true;
+
+	dev_priv->fbdev = ifbdev;
+	INIT_WORK(&dev_priv->fbdev_suspend_work, intel_fbdev_suspend_worker);
+
+	drm_fb_helper_single_add_all_connectors(&ifbdev->helper);
+
+	return 0;
+}
+
+static void intel_fbdev_initial_config(void *data, async_cookie_t cookie)
+{
+	struct drm_i915_private *dev_priv = data;
+	struct intel_fbdev *ifbdev = dev_priv->fbdev;
+
+	/* Due to peculiar init order wrt to hpd handling this is separate. */
+	if (drm_fb_helper_initial_config(&ifbdev->helper,
+					 ifbdev->preferred_bpp))
+		intel_fbdev_fini(dev_priv->dev);
+}
+
+void intel_fbdev_initial_config_async(struct drm_device *dev)
+{
+	async_schedule(intel_fbdev_initial_config, to_i915(dev));
+}
+
+void intel_fbdev_fini(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	if (!dev_priv->fbdev)
+		return;
+
+	flush_work(&dev_priv->fbdev_suspend_work);
+
+	if (!current_is_async())
+		async_synchronize_full();
+	intel_fbdev_destroy(dev, dev_priv->fbdev);
+	kfree(dev_priv->fbdev);
+	dev_priv->fbdev = NULL;
+}
+
+void intel_fbdev_set_suspend(struct drm_device *dev, int state, bool synchronous)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_fbdev *ifbdev = dev_priv->fbdev;
+	struct fb_info *info;
+
+	if (!ifbdev)
+		return;
+
+	info = ifbdev->helper.fbdev;
+
+	if (synchronous) {
+		/* Flush any pending work to turn the console on, and then
+		 * wait to turn it off. It must be synchronous as we are
+		 * about to suspend or unload the driver.
+		 *
+		 * Note that from within the work-handler, we cannot flush
+		 * ourselves, so only flush outstanding work upon suspend!
+		 */
+		if (state != FBINFO_STATE_RUNNING)
+			flush_work(&dev_priv->fbdev_suspend_work);
+		console_lock();
+	} else {
+		/*
+		 * The console lock can be pretty contented on resume due
+		 * to all the printk activity.  Try to keep it out of the hot
+		 * path of resume if possible.
+		 */
+		WARN_ON(state != FBINFO_STATE_RUNNING);
+		if (!console_trylock()) {
+			/* Don't block our own workqueue as this can
+			 * be run in parallel with other i915.ko tasks.
+			 */
+			schedule_work(&dev_priv->fbdev_suspend_work);
+			return;
+		}
+	}
+
+	/* On resume from hibernation: If the object is shmemfs backed, it has
+	 * been restored from swap. If the object is stolen however, it will be
+	 * full of whatever garbage was left in there.
+	 */
+	if (state == FBINFO_STATE_RUNNING && ifbdev->fb->obj->stolen)
+		memset_io(info->screen_base, 0, info->screen_size);
+
+	drm_fb_helper_set_suspend(&ifbdev->helper, state);
+	console_unlock();
+}
+
+void intel_fbdev_output_poll_changed(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	if (dev_priv->fbdev)
+		drm_fb_helper_hotplug_event(&dev_priv->fbdev->helper);
+}
+
+void intel_fbdev_restore_mode(struct drm_device *dev)
+{
+	int ret;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_fbdev *ifbdev = dev_priv->fbdev;
+	struct drm_fb_helper *fb_helper;
+
+	if (!ifbdev)
+		return;
+
+	fb_helper = &ifbdev->helper;
+
+	ret = drm_fb_helper_restore_fbdev_mode_unlocked(fb_helper);
+	if (ret) {
+		DRM_DEBUG("failed to restore crtc mode\n");
+	} else {
+		mutex_lock(&fb_helper->dev->struct_mutex);
+		intel_fb_obj_invalidate(ifbdev->fb->obj, ORIGIN_GTT);
+		mutex_unlock(&fb_helper->dev->struct_mutex);
+	}
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/i915/intel_fifo_underrun.c
@@ -0,0 +1,444 @@
+/*
+ * Copyright © 2014 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Daniel Vetter <daniel.vetter@ffwll.ch>
+ *
+ */
+
+#include "i915_drv.h"
+#include "intel_drv.h"
+
+/**
+ * DOC: fifo underrun handling
+ *
+ * The i915 driver checks for display fifo underruns using the interrupt signals
+ * provided by the hardware. This is enabled by default and fairly useful to
+ * debug display issues, especially watermark settings.
+ *
+ * If an underrun is detected this is logged into dmesg. To avoid flooding logs
+ * and occupying the cpu underrun interrupts are disabled after the first
+ * occurrence until the next modeset on a given pipe.
+ *
+ * Note that underrun detection on gmch platforms is a bit more ugly since there
+ * is no interrupt (despite that the signalling bit is in the PIPESTAT pipe
+ * interrupt register). Also on some other platforms underrun interrupts are
+ * shared, which means that if we detect an underrun we need to disable underrun
+ * reporting on all pipes.
+ *
+ * The code also supports underrun detection on the PCH transcoder.
+ */
+
+static bool ivb_can_enable_err_int(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_crtc *crtc;
+	enum pipe pipe;
+
+	assert_spin_locked(&dev_priv->irq_lock);
+
+	for_each_pipe(dev_priv, pipe) {
+		crtc = to_intel_crtc(dev_priv->pipe_to_crtc_mapping[pipe]);
+
+		if (crtc->cpu_fifo_underrun_disabled)
+			return false;
+	}
+
+	return true;
+}
+
+static bool cpt_can_enable_serr_int(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	enum pipe pipe;
+	struct intel_crtc *crtc;
+
+	assert_spin_locked(&dev_priv->irq_lock);
+
+	for_each_pipe(dev_priv, pipe) {
+		crtc = to_intel_crtc(dev_priv->pipe_to_crtc_mapping[pipe]);
+
+		if (crtc->pch_fifo_underrun_disabled)
+			return false;
+	}
+
+	return true;
+}
+
+static void i9xx_check_fifo_underruns(struct intel_crtc *crtc)
+{
+	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
+	i915_reg_t reg = PIPESTAT(crtc->pipe);
+	u32 pipestat = I915_READ(reg) & 0xffff0000;
+
+	assert_spin_locked(&dev_priv->irq_lock);
+
+	if ((pipestat & PIPE_FIFO_UNDERRUN_STATUS) == 0)
+		return;
+
+	I915_WRITE(reg, pipestat | PIPE_FIFO_UNDERRUN_STATUS);
+	POSTING_READ(reg);
+
+	DRM_ERROR("pipe %c underrun\n", pipe_name(crtc->pipe));
+}
+
+static void i9xx_set_fifo_underrun_reporting(struct drm_device *dev,
+					     enum pipe pipe,
+					     bool enable, bool old)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	i915_reg_t reg = PIPESTAT(pipe);
+	u32 pipestat = I915_READ(reg) & 0xffff0000;
+
+	assert_spin_locked(&dev_priv->irq_lock);
+
+	if (enable) {
+		I915_WRITE(reg, pipestat | PIPE_FIFO_UNDERRUN_STATUS);
+		POSTING_READ(reg);
+	} else {
+		if (old && pipestat & PIPE_FIFO_UNDERRUN_STATUS)
+			DRM_ERROR("pipe %c underrun\n", pipe_name(pipe));
+	}
+}
+
+static void ironlake_set_fifo_underrun_reporting(struct drm_device *dev,
+						 enum pipe pipe, bool enable)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	uint32_t bit = (pipe == PIPE_A) ? DE_PIPEA_FIFO_UNDERRUN :
+					  DE_PIPEB_FIFO_UNDERRUN;
+
+	if (enable)
+		ilk_enable_display_irq(dev_priv, bit);
+	else
+		ilk_disable_display_irq(dev_priv, bit);
+}
+
+static void ivybridge_check_fifo_underruns(struct intel_crtc *crtc)
+{
+	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
+	enum pipe pipe = crtc->pipe;
+	uint32_t err_int = I915_READ(GEN7_ERR_INT);
+
+	assert_spin_locked(&dev_priv->irq_lock);
+
+	if ((err_int & ERR_INT_FIFO_UNDERRUN(pipe)) == 0)
+		return;
+
+	I915_WRITE(GEN7_ERR_INT, ERR_INT_FIFO_UNDERRUN(pipe));
+	POSTING_READ(GEN7_ERR_INT);
+
+	DRM_ERROR("fifo underrun on pipe %c\n", pipe_name(pipe));
+}
+
+static void ivybridge_set_fifo_underrun_reporting(struct drm_device *dev,
+						  enum pipe pipe,
+						  bool enable, bool old)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	if (enable) {
+		I915_WRITE(GEN7_ERR_INT, ERR_INT_FIFO_UNDERRUN(pipe));
+
+		if (!ivb_can_enable_err_int(dev))
+			return;
+
+		ilk_enable_display_irq(dev_priv, DE_ERR_INT_IVB);
+	} else {
+		ilk_disable_display_irq(dev_priv, DE_ERR_INT_IVB);
+
+		if (old &&
+		    I915_READ(GEN7_ERR_INT) & ERR_INT_FIFO_UNDERRUN(pipe)) {
+			DRM_ERROR("uncleared fifo underrun on pipe %c\n",
+				  pipe_name(pipe));
+		}
+	}
+}
+
+static void broadwell_set_fifo_underrun_reporting(struct drm_device *dev,
+						  enum pipe pipe, bool enable)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	if (enable)
+		bdw_enable_pipe_irq(dev_priv, pipe, GEN8_PIPE_FIFO_UNDERRUN);
+	else
+		bdw_disable_pipe_irq(dev_priv, pipe, GEN8_PIPE_FIFO_UNDERRUN);
+}
+
+static void ibx_set_fifo_underrun_reporting(struct drm_device *dev,
+					    enum transcoder pch_transcoder,
+					    bool enable)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	uint32_t bit = (pch_transcoder == TRANSCODER_A) ?
+		       SDE_TRANSA_FIFO_UNDER : SDE_TRANSB_FIFO_UNDER;
+
+	if (enable)
+		ibx_enable_display_interrupt(dev_priv, bit);
+	else
+		ibx_disable_display_interrupt(dev_priv, bit);
+}
+
+static void cpt_check_pch_fifo_underruns(struct intel_crtc *crtc)
+{
+	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
+	enum transcoder pch_transcoder = (enum transcoder) crtc->pipe;
+	uint32_t serr_int = I915_READ(SERR_INT);
+
+	assert_spin_locked(&dev_priv->irq_lock);
+
+	if ((serr_int & SERR_INT_TRANS_FIFO_UNDERRUN(pch_transcoder)) == 0)
+		return;
+
+	I915_WRITE(SERR_INT, SERR_INT_TRANS_FIFO_UNDERRUN(pch_transcoder));
+	POSTING_READ(SERR_INT);
+
+	DRM_ERROR("pch fifo underrun on pch transcoder %s\n",
+		  transcoder_name(pch_transcoder));
+}
+
+static void cpt_set_fifo_underrun_reporting(struct drm_device *dev,
+					    enum transcoder pch_transcoder,
+					    bool enable, bool old)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	if (enable) {
+		I915_WRITE(SERR_INT,
+			   SERR_INT_TRANS_FIFO_UNDERRUN(pch_transcoder));
+
+		if (!cpt_can_enable_serr_int(dev))
+			return;
+
+		ibx_enable_display_interrupt(dev_priv, SDE_ERROR_CPT);
+	} else {
+		ibx_disable_display_interrupt(dev_priv, SDE_ERROR_CPT);
+
+		if (old && I915_READ(SERR_INT) &
+		    SERR_INT_TRANS_FIFO_UNDERRUN(pch_transcoder)) {
+			DRM_ERROR("uncleared pch fifo underrun on pch transcoder %s\n",
+				  transcoder_name(pch_transcoder));
+		}
+	}
+}
+
+static bool __intel_set_cpu_fifo_underrun_reporting(struct drm_device *dev,
+						    enum pipe pipe, bool enable)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe];
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	bool old;
+
+	assert_spin_locked(&dev_priv->irq_lock);
+
+	old = !intel_crtc->cpu_fifo_underrun_disabled;
+	intel_crtc->cpu_fifo_underrun_disabled = !enable;
+
+	if (HAS_GMCH_DISPLAY(dev))
+		i9xx_set_fifo_underrun_reporting(dev, pipe, enable, old);
+	else if (IS_GEN5(dev) || IS_GEN6(dev))
+		ironlake_set_fifo_underrun_reporting(dev, pipe, enable);
+	else if (IS_GEN7(dev))
+		ivybridge_set_fifo_underrun_reporting(dev, pipe, enable, old);
+	else if (IS_GEN8(dev) || IS_GEN9(dev))
+		broadwell_set_fifo_underrun_reporting(dev, pipe, enable);
+
+	return old;
+}
+
+/**
+ * intel_set_cpu_fifo_underrun_reporting - set cpu fifo underrrun reporting state
+ * @dev_priv: i915 device instance
+ * @pipe: (CPU) pipe to set state for
+ * @enable: whether underruns should be reported or not
+ *
+ * This function sets the fifo underrun state for @pipe. It is used in the
+ * modeset code to avoid false positives since on many platforms underruns are
+ * expected when disabling or enabling the pipe.
+ *
+ * Notice that on some platforms disabling underrun reports for one pipe
+ * disables for all due to shared interrupts. Actual reporting is still per-pipe
+ * though.
+ *
+ * Returns the previous state of underrun reporting.
+ */
+bool intel_set_cpu_fifo_underrun_reporting(struct drm_i915_private *dev_priv,
+					   enum pipe pipe, bool enable)
+{
+	unsigned long flags;
+	bool ret;
+
+	spin_lock_irqsave(&dev_priv->irq_lock, flags);
+	ret = __intel_set_cpu_fifo_underrun_reporting(dev_priv->dev, pipe,
+						      enable);
+	spin_unlock_irqrestore(&dev_priv->irq_lock, flags);
+
+	return ret;
+}
+
+/**
+ * intel_set_pch_fifo_underrun_reporting - set PCH fifo underrun reporting state
+ * @dev_priv: i915 device instance
+ * @pch_transcoder: the PCH transcoder (same as pipe on IVB and older)
+ * @enable: whether underruns should be reported or not
+ *
+ * This function makes us disable or enable PCH fifo underruns for a specific
+ * PCH transcoder. Notice that on some PCHs (e.g. CPT/PPT), disabling FIFO
+ * underrun reporting for one transcoder may also disable all the other PCH
+ * error interruts for the other transcoders, due to the fact that there's just
+ * one interrupt mask/enable bit for all the transcoders.
+ *
+ * Returns the previous state of underrun reporting.
+ */
+bool intel_set_pch_fifo_underrun_reporting(struct drm_i915_private *dev_priv,
+					   enum transcoder pch_transcoder,
+					   bool enable)
+{
+	struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pch_transcoder];
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	unsigned long flags;
+	bool old;
+
+	/*
+	 * NOTE: Pre-LPT has a fixed cpu pipe -> pch transcoder mapping, but LPT
+	 * has only one pch transcoder A that all pipes can use. To avoid racy
+	 * pch transcoder -> pipe lookups from interrupt code simply store the
+	 * underrun statistics in crtc A. Since we never expose this anywhere
+	 * nor use it outside of the fifo underrun code here using the "wrong"
+	 * crtc on LPT won't cause issues.
+	 */
+
+	spin_lock_irqsave(&dev_priv->irq_lock, flags);
+
+	old = !intel_crtc->pch_fifo_underrun_disabled;
+	intel_crtc->pch_fifo_underrun_disabled = !enable;
+
+	if (HAS_PCH_IBX(dev_priv))
+		ibx_set_fifo_underrun_reporting(dev_priv->dev, pch_transcoder,
+						enable);
+	else
+		cpt_set_fifo_underrun_reporting(dev_priv->dev, pch_transcoder,
+						enable, old);
+
+	spin_unlock_irqrestore(&dev_priv->irq_lock, flags);
+	return old;
+}
+
+/**
+ * intel_cpu_fifo_underrun_irq_handler - handle CPU fifo underrun interrupt
+ * @dev_priv: i915 device instance
+ * @pipe: (CPU) pipe to set state for
+ *
+ * This handles a CPU fifo underrun interrupt, generating an underrun warning
+ * into dmesg if underrun reporting is enabled and then disables the underrun
+ * interrupt to avoid an irq storm.
+ */
+void intel_cpu_fifo_underrun_irq_handler(struct drm_i915_private *dev_priv,
+					 enum pipe pipe)
+{
+	struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe];
+
+	/* We may be called too early in init, thanks BIOS! */
+	if (crtc == NULL)
+		return;
+
+	/* GMCH can't disable fifo underruns, filter them. */
+	if (HAS_GMCH_DISPLAY(dev_priv) &&
+	    to_intel_crtc(crtc)->cpu_fifo_underrun_disabled)
+		return;
+
+	if (intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, false))
+		DRM_ERROR("CPU pipe %c FIFO underrun\n",
+			  pipe_name(pipe));
+}
+
+/**
+ * intel_pch_fifo_underrun_irq_handler - handle PCH fifo underrun interrupt
+ * @dev_priv: i915 device instance
+ * @pch_transcoder: the PCH transcoder (same as pipe on IVB and older)
+ *
+ * This handles a PCH fifo underrun interrupt, generating an underrun warning
+ * into dmesg if underrun reporting is enabled and then disables the underrun
+ * interrupt to avoid an irq storm.
+ */
+void intel_pch_fifo_underrun_irq_handler(struct drm_i915_private *dev_priv,
+					 enum transcoder pch_transcoder)
+{
+	if (intel_set_pch_fifo_underrun_reporting(dev_priv, pch_transcoder,
+						  false))
+		DRM_ERROR("PCH transcoder %s FIFO underrun\n",
+			  transcoder_name(pch_transcoder));
+}
+
+/**
+ * intel_check_cpu_fifo_underruns - check for CPU fifo underruns immediately
+ * @dev_priv: i915 device instance
+ *
+ * Check for CPU fifo underruns immediately. Useful on IVB/HSW where the shared
+ * error interrupt may have been disabled, and so CPU fifo underruns won't
+ * necessarily raise an interrupt, and on GMCH platforms where underruns never
+ * raise an interrupt.
+ */
+void intel_check_cpu_fifo_underruns(struct drm_i915_private *dev_priv)
+{
+	struct intel_crtc *crtc;
+
+	spin_lock_irq(&dev_priv->irq_lock);
+
+	for_each_intel_crtc(dev_priv->dev, crtc) {
+		if (crtc->cpu_fifo_underrun_disabled)
+			continue;
+
+		if (HAS_GMCH_DISPLAY(dev_priv))
+			i9xx_check_fifo_underruns(crtc);
+		else if (IS_GEN7(dev_priv))
+			ivybridge_check_fifo_underruns(crtc);
+	}
+
+	spin_unlock_irq(&dev_priv->irq_lock);
+}
+
+/**
+ * intel_check_pch_fifo_underruns - check for PCH fifo underruns immediately
+ * @dev_priv: i915 device instance
+ *
+ * Check for PCH fifo underruns immediately. Useful on CPT/PPT where the shared
+ * error interrupt may have been disabled, and so PCH fifo underruns won't
+ * necessarily raise an interrupt.
+ */
+void intel_check_pch_fifo_underruns(struct drm_i915_private *dev_priv)
+{
+	struct intel_crtc *crtc;
+
+	spin_lock_irq(&dev_priv->irq_lock);
+
+	for_each_intel_crtc(dev_priv->dev, crtc) {
+		if (crtc->pch_fifo_underrun_disabled)
+			continue;
+
+		if (HAS_PCH_CPT(dev_priv))
+			cpt_check_pch_fifo_underruns(crtc);
+	}
+
+	spin_unlock_irq(&dev_priv->irq_lock);
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/i915/intel_frontbuffer.c
@@ -0,0 +1,243 @@
+/*
+ * Copyright © 2014 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *	Daniel Vetter <daniel.vetter@ffwll.ch>
+ */
+
+/**
+ * DOC: frontbuffer tracking
+ *
+ * Many features require us to track changes to the currently active
+ * frontbuffer, especially rendering targeted at the frontbuffer.
+ *
+ * To be able to do so GEM tracks frontbuffers using a bitmask for all possible
+ * frontbuffer slots through i915_gem_track_fb(). The function in this file are
+ * then called when the contents of the frontbuffer are invalidated, when
+ * frontbuffer rendering has stopped again to flush out all the changes and when
+ * the frontbuffer is exchanged with a flip. Subsystems interested in
+ * frontbuffer changes (e.g. PSR, FBC, DRRS) should directly put their callbacks
+ * into the relevant places and filter for the frontbuffer slots that they are
+ * interested int.
+ *
+ * On a high level there are two types of powersaving features. The first one
+ * work like a special cache (FBC and PSR) and are interested when they should
+ * stop caching and when to restart caching. This is done by placing callbacks
+ * into the invalidate and the flush functions: At invalidate the caching must
+ * be stopped and at flush time it can be restarted. And maybe they need to know
+ * when the frontbuffer changes (e.g. when the hw doesn't initiate an invalidate
+ * and flush on its own) which can be achieved with placing callbacks into the
+ * flip functions.
+ *
+ * The other type of display power saving feature only cares about busyness
+ * (e.g. DRRS). In that case all three (invalidate, flush and flip) indicate
+ * busyness. There is no direct way to detect idleness. Instead an idle timer
+ * work delayed work should be started from the flush and flip functions and
+ * cancelled as soon as busyness is detected.
+ *
+ * Note that there's also an older frontbuffer activity tracking scheme which
+ * just tracks general activity. This is done by the various mark_busy and
+ * mark_idle functions. For display power management features using these
+ * functions is deprecated and should be avoided.
+ */
+
+#include <drm/drmP.h>
+
+#include "intel_drv.h"
+#include "i915_drv.h"
+
+/**
+ * intel_fb_obj_invalidate - invalidate frontbuffer object
+ * @obj: GEM object to invalidate
+ * @origin: which operation caused the invalidation
+ *
+ * This function gets called every time rendering on the given object starts and
+ * frontbuffer caching (fbc, low refresh rate for DRRS, panel self refresh) must
+ * be invalidated. For ORIGIN_CS any subsequent invalidation will be delayed
+ * until the rendering completes or a flip on this frontbuffer plane is
+ * scheduled.
+ */
+void intel_fb_obj_invalidate(struct drm_i915_gem_object *obj,
+			     enum fb_op_origin origin)
+{
+	struct drm_device *dev = obj->base.dev;
+	struct drm_i915_private *dev_priv = to_i915(dev);
+
+	WARN_ON(!mutex_is_locked(&dev->struct_mutex));
+
+	if (!obj->frontbuffer_bits)
+		return;
+
+	if (origin == ORIGIN_CS) {
+		mutex_lock(&dev_priv->fb_tracking.lock);
+		dev_priv->fb_tracking.busy_bits
+			|= obj->frontbuffer_bits;
+		dev_priv->fb_tracking.flip_bits
+			&= ~obj->frontbuffer_bits;
+		mutex_unlock(&dev_priv->fb_tracking.lock);
+	}
+
+	intel_psr_invalidate(dev, obj->frontbuffer_bits);
+	intel_edp_drrs_invalidate(dev, obj->frontbuffer_bits);
+	intel_fbc_invalidate(dev_priv, obj->frontbuffer_bits, origin);
+}
+
+/**
+ * intel_frontbuffer_flush - flush frontbuffer
+ * @dev: DRM device
+ * @frontbuffer_bits: frontbuffer plane tracking bits
+ * @origin: which operation caused the flush
+ *
+ * This function gets called every time rendering on the given planes has
+ * completed and frontbuffer caching can be started again. Flushes will get
+ * delayed if they're blocked by some outstanding asynchronous rendering.
+ *
+ * Can be called without any locks held.
+ */
+static void intel_frontbuffer_flush(struct drm_device *dev,
+				    unsigned frontbuffer_bits,
+				    enum fb_op_origin origin)
+{
+	struct drm_i915_private *dev_priv = to_i915(dev);
+
+	/* Delay flushing when rings are still busy.*/
+	mutex_lock(&dev_priv->fb_tracking.lock);
+	frontbuffer_bits &= ~dev_priv->fb_tracking.busy_bits;
+	mutex_unlock(&dev_priv->fb_tracking.lock);
+
+	if (!frontbuffer_bits)
+		return;
+
+	intel_edp_drrs_flush(dev, frontbuffer_bits);
+	intel_psr_flush(dev, frontbuffer_bits, origin);
+	intel_fbc_flush(dev_priv, frontbuffer_bits, origin);
+}
+
+/**
+ * intel_fb_obj_flush - flush frontbuffer object
+ * @obj: GEM object to flush
+ * @retire: set when retiring asynchronous rendering
+ * @origin: which operation caused the flush
+ *
+ * This function gets called every time rendering on the given object has
+ * completed and frontbuffer caching can be started again. If @retire is true
+ * then any delayed flushes will be unblocked.
+ */
+void intel_fb_obj_flush(struct drm_i915_gem_object *obj,
+			bool retire, enum fb_op_origin origin)
+{
+	struct drm_device *dev = obj->base.dev;
+	struct drm_i915_private *dev_priv = to_i915(dev);
+	unsigned frontbuffer_bits;
+
+	WARN_ON(!mutex_is_locked(&dev->struct_mutex));
+
+	if (!obj->frontbuffer_bits)
+		return;
+
+	frontbuffer_bits = obj->frontbuffer_bits;
+
+	if (retire) {
+		mutex_lock(&dev_priv->fb_tracking.lock);
+		/* Filter out new bits since rendering started. */
+		frontbuffer_bits &= dev_priv->fb_tracking.busy_bits;
+
+		dev_priv->fb_tracking.busy_bits &= ~frontbuffer_bits;
+		mutex_unlock(&dev_priv->fb_tracking.lock);
+	}
+
+	intel_frontbuffer_flush(dev, frontbuffer_bits, origin);
+}
+
+/**
+ * intel_frontbuffer_flip_prepare - prepare asynchronous frontbuffer flip
+ * @dev: DRM device
+ * @frontbuffer_bits: frontbuffer plane tracking bits
+ *
+ * This function gets called after scheduling a flip on @obj. The actual
+ * frontbuffer flushing will be delayed until completion is signalled with
+ * intel_frontbuffer_flip_complete. If an invalidate happens in between this
+ * flush will be cancelled.
+ *
+ * Can be called without any locks held.
+ */
+void intel_frontbuffer_flip_prepare(struct drm_device *dev,
+				    unsigned frontbuffer_bits)
+{
+	struct drm_i915_private *dev_priv = to_i915(dev);
+
+	mutex_lock(&dev_priv->fb_tracking.lock);
+	dev_priv->fb_tracking.flip_bits |= frontbuffer_bits;
+	/* Remove stale busy bits due to the old buffer. */
+	dev_priv->fb_tracking.busy_bits &= ~frontbuffer_bits;
+	mutex_unlock(&dev_priv->fb_tracking.lock);
+
+	intel_psr_single_frame_update(dev, frontbuffer_bits);
+}
+
+/**
+ * intel_frontbuffer_flip_complete - complete asynchronous frontbuffer flip
+ * @dev: DRM device
+ * @frontbuffer_bits: frontbuffer plane tracking bits
+ *
+ * This function gets called after the flip has been latched and will complete
+ * on the next vblank. It will execute the flush if it hasn't been cancelled yet.
+ *
+ * Can be called without any locks held.
+ */
+void intel_frontbuffer_flip_complete(struct drm_device *dev,
+				     unsigned frontbuffer_bits)
+{
+	struct drm_i915_private *dev_priv = to_i915(dev);
+
+	mutex_lock(&dev_priv->fb_tracking.lock);
+	/* Mask any cancelled flips. */
+	frontbuffer_bits &= dev_priv->fb_tracking.flip_bits;
+	dev_priv->fb_tracking.flip_bits &= ~frontbuffer_bits;
+	mutex_unlock(&dev_priv->fb_tracking.lock);
+
+	intel_frontbuffer_flush(dev, frontbuffer_bits, ORIGIN_FLIP);
+}
+
+/**
+ * intel_frontbuffer_flip - synchronous frontbuffer flip
+ * @dev: DRM device
+ * @frontbuffer_bits: frontbuffer plane tracking bits
+ *
+ * This function gets called after scheduling a flip on @obj. This is for
+ * synchronous plane updates which will happen on the next vblank and which will
+ * not get delayed by pending gpu rendering.
+ *
+ * Can be called without any locks held.
+ */
+void intel_frontbuffer_flip(struct drm_device *dev,
+			    unsigned frontbuffer_bits)
+{
+	struct drm_i915_private *dev_priv = to_i915(dev);
+
+	mutex_lock(&dev_priv->fb_tracking.lock);
+	/* Remove stale busy bits due to the old buffer. */
+	dev_priv->fb_tracking.busy_bits &= ~frontbuffer_bits;
+	mutex_unlock(&dev_priv->fb_tracking.lock);
+
+	intel_frontbuffer_flush(dev, frontbuffer_bits, ORIGIN_FLIP);
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/i915/intel_guc.h
@@ -0,0 +1,157 @@
+/*
+ * Copyright © 2014 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ */
+#ifndef _INTEL_GUC_H_
+#define _INTEL_GUC_H_
+
+#include "intel_guc_fwif.h"
+#include "i915_guc_reg.h"
+
+struct drm_i915_gem_request;
+
+/*
+ * This structure primarily describes the GEM object shared with the GuC.
+ * The GEM object is held for the entire lifetime of our interaction with
+ * the GuC, being allocated before the GuC is loaded with its firmware.
+ * Because there's no way to update the address used by the GuC after
+ * initialisation, the shared object must stay pinned into the GGTT as
+ * long as the GuC is in use. We also keep the first page (only) mapped
+ * into kernel address space, as it includes shared data that must be
+ * updated on every request submission.
+ *
+ * The single GEM object described here is actually made up of several
+ * separate areas, as far as the GuC is concerned. The first page (kept
+ * kmap'd) includes the "process decriptor" which holds sequence data for
+ * the doorbell, and one cacheline which actually *is* the doorbell; a
+ * write to this will "ring the doorbell" (i.e. send an interrupt to the
+ * GuC). The subsequent  pages of the client object constitute the work
+ * queue (a circular array of work items), again described in the process
+ * descriptor. Work queue pages are mapped momentarily as required.
+ *
+ * Finally, we also keep a few statistics here, including the number of
+ * submissions to each engine, and a record of the last submission failure
+ * (if any).
+ */
+struct i915_guc_client {
+	struct drm_i915_gem_object *client_obj;
+	void *client_base;		/* first page (only) of above	*/
+	struct intel_context *owner;
+	struct intel_guc *guc;
+	uint32_t priority;
+	uint32_t ctx_index;
+
+	uint32_t proc_desc_offset;
+	uint32_t doorbell_offset;
+	uint32_t cookie;
+	uint16_t doorbell_id;
+	uint16_t padding;		/* Maintain alignment		*/
+
+	uint32_t wq_offset;
+	uint32_t wq_size;
+	uint32_t wq_tail;
+	uint32_t unused;		/* Was 'wq_head'		*/
+
+	/* GuC submission statistics & status */
+	uint64_t submissions[GUC_MAX_ENGINES_NUM];
+	uint32_t q_fail;
+	uint32_t b_fail;
+	int retcode;
+	int spare;			/* pad to 32 DWords		*/
+};
+
+enum intel_guc_fw_status {
+	GUC_FIRMWARE_FAIL = -1,
+	GUC_FIRMWARE_NONE = 0,
+	GUC_FIRMWARE_PENDING,
+	GUC_FIRMWARE_SUCCESS
+};
+
+/*
+ * This structure encapsulates all the data needed during the process
+ * of fetching, caching, and loading the firmware image into the GuC.
+ */
+struct intel_guc_fw {
+	struct drm_device *		guc_dev;
+	const char *			guc_fw_path;
+	size_t				guc_fw_size;
+	struct drm_i915_gem_object *	guc_fw_obj;
+	enum intel_guc_fw_status	guc_fw_fetch_status;
+	enum intel_guc_fw_status	guc_fw_load_status;
+
+	uint16_t			guc_fw_major_wanted;
+	uint16_t			guc_fw_minor_wanted;
+	uint16_t			guc_fw_major_found;
+	uint16_t			guc_fw_minor_found;
+
+	uint32_t header_size;
+	uint32_t header_offset;
+	uint32_t rsa_size;
+	uint32_t rsa_offset;
+	uint32_t ucode_size;
+	uint32_t ucode_offset;
+};
+
+struct intel_guc {
+	struct intel_guc_fw guc_fw;
+	uint32_t log_flags;
+	struct drm_i915_gem_object *log_obj;
+
+	struct drm_i915_gem_object *ads_obj;
+
+	struct drm_i915_gem_object *ctx_pool_obj;
+	struct ida ctx_ids;
+
+	struct i915_guc_client *execbuf_client;
+
+	DECLARE_BITMAP(doorbell_bitmap, GUC_MAX_DOORBELLS);
+	uint32_t db_cacheline;		/* Cyclic counter mod pagesize	*/
+
+	/* Action status & statistics */
+	uint64_t action_count;		/* Total commands issued	*/
+	uint32_t action_cmd;		/* Last command word		*/
+	uint32_t action_status;		/* Last return status		*/
+	uint32_t action_fail;		/* Total number of failures	*/
+	int32_t action_err;		/* Last error code		*/
+
+	uint64_t submissions[GUC_MAX_ENGINES_NUM];
+	uint32_t last_seqno[GUC_MAX_ENGINES_NUM];
+};
+
+/* intel_guc_loader.c */
+extern void intel_guc_ucode_init(struct drm_device *dev);
+extern int intel_guc_ucode_load(struct drm_device *dev);
+extern void intel_guc_ucode_fini(struct drm_device *dev);
+extern const char *intel_guc_fw_status_repr(enum intel_guc_fw_status status);
+extern int intel_guc_suspend(struct drm_device *dev);
+extern int intel_guc_resume(struct drm_device *dev);
+
+/* i915_guc_submission.c */
+int i915_guc_submission_init(struct drm_device *dev);
+int i915_guc_submission_enable(struct drm_device *dev);
+int i915_guc_submit(struct i915_guc_client *client,
+		    struct drm_i915_gem_request *rq);
+void i915_guc_submission_disable(struct drm_device *dev);
+void i915_guc_submission_fini(struct drm_device *dev);
+int i915_guc_wq_check_space(struct i915_guc_client *client);
+
+#endif
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/i915/intel_guc_fwif.h
@@ -0,0 +1,450 @@
+/*
+ * Copyright © 2014 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+#ifndef _INTEL_GUC_FWIF_H
+#define _INTEL_GUC_FWIF_H
+
+/*
+ * This file is partially autogenerated, although currently with some manual
+ * fixups afterwards. In future, it should be entirely autogenerated, in order
+ * to ensure that the definitions herein remain in sync with those used by the
+ * GuC's own firmware.
+ *
+ * EDITING THIS FILE IS THEREFORE NOT RECOMMENDED - YOUR CHANGES MAY BE LOST.
+ */
+
+#define GFXCORE_FAMILY_GEN9		12
+#define GFXCORE_FAMILY_UNKNOWN		0x7fffffff
+
+#define GUC_CTX_PRIORITY_KMD_HIGH	0
+#define GUC_CTX_PRIORITY_HIGH		1
+#define GUC_CTX_PRIORITY_KMD_NORMAL	2
+#define GUC_CTX_PRIORITY_NORMAL		3
+#define GUC_CTX_PRIORITY_NUM		4
+
+#define GUC_MAX_GPU_CONTEXTS		1024
+#define	GUC_INVALID_CTX_ID		GUC_MAX_GPU_CONTEXTS
+
+#define GUC_RENDER_ENGINE		0
+#define GUC_VIDEO_ENGINE		1
+#define GUC_BLITTER_ENGINE		2
+#define GUC_VIDEOENHANCE_ENGINE		3
+#define GUC_VIDEO_ENGINE2		4
+#define GUC_MAX_ENGINES_NUM		(GUC_VIDEO_ENGINE2 + 1)
+
+/* Work queue item header definitions */
+#define WQ_STATUS_ACTIVE		1
+#define WQ_STATUS_SUSPENDED		2
+#define WQ_STATUS_CMD_ERROR		3
+#define WQ_STATUS_ENGINE_ID_NOT_USED	4
+#define WQ_STATUS_SUSPENDED_FROM_RESET	5
+#define WQ_TYPE_SHIFT			0
+#define   WQ_TYPE_BATCH_BUF		(0x1 << WQ_TYPE_SHIFT)
+#define   WQ_TYPE_PSEUDO		(0x2 << WQ_TYPE_SHIFT)
+#define   WQ_TYPE_INORDER		(0x3 << WQ_TYPE_SHIFT)
+#define WQ_TARGET_SHIFT			10
+#define WQ_LEN_SHIFT			16
+#define WQ_NO_WCFLUSH_WAIT		(1 << 27)
+#define WQ_PRESENT_WORKLOAD		(1 << 28)
+#define WQ_WORKLOAD_SHIFT		29
+#define   WQ_WORKLOAD_GENERAL		(0 << WQ_WORKLOAD_SHIFT)
+#define   WQ_WORKLOAD_GPGPU		(1 << WQ_WORKLOAD_SHIFT)
+#define   WQ_WORKLOAD_TOUCH		(2 << WQ_WORKLOAD_SHIFT)
+
+#define WQ_RING_TAIL_SHIFT		20
+#define WQ_RING_TAIL_MASK		(0x7FF << WQ_RING_TAIL_SHIFT)
+
+#define GUC_DOORBELL_ENABLED		1
+#define GUC_DOORBELL_DISABLED		0
+
+#define GUC_CTX_DESC_ATTR_ACTIVE	(1 << 0)
+#define GUC_CTX_DESC_ATTR_PENDING_DB	(1 << 1)
+#define GUC_CTX_DESC_ATTR_KERNEL	(1 << 2)
+#define GUC_CTX_DESC_ATTR_PREEMPT	(1 << 3)
+#define GUC_CTX_DESC_ATTR_RESET		(1 << 4)
+#define GUC_CTX_DESC_ATTR_WQLOCKED	(1 << 5)
+#define GUC_CTX_DESC_ATTR_PCH		(1 << 6)
+#define GUC_CTX_DESC_ATTR_TERMINATED	(1 << 7)
+
+/* The guc control data is 10 DWORDs */
+#define GUC_CTL_CTXINFO			0
+#define   GUC_CTL_CTXNUM_IN16_SHIFT	0
+#define   GUC_CTL_BASE_ADDR_SHIFT	12
+
+#define GUC_CTL_ARAT_HIGH		1
+#define GUC_CTL_ARAT_LOW		2
+
+#define GUC_CTL_DEVICE_INFO		3
+#define   GUC_CTL_GTTYPE_SHIFT		0
+#define   GUC_CTL_COREFAMILY_SHIFT	7
+
+#define GUC_CTL_LOG_PARAMS		4
+#define   GUC_LOG_VALID			(1 << 0)
+#define   GUC_LOG_NOTIFY_ON_HALF_FULL	(1 << 1)
+#define   GUC_LOG_ALLOC_IN_MEGABYTE	(1 << 3)
+#define   GUC_LOG_CRASH_PAGES		1
+#define   GUC_LOG_CRASH_SHIFT		4
+#define   GUC_LOG_DPC_PAGES		3
+#define   GUC_LOG_DPC_SHIFT		6
+#define   GUC_LOG_ISR_PAGES		3
+#define   GUC_LOG_ISR_SHIFT		9
+#define   GUC_LOG_BUF_ADDR_SHIFT	12
+
+#define GUC_CTL_PAGE_FAULT_CONTROL	5
+
+#define GUC_CTL_WA			6
+#define   GUC_CTL_WA_UK_BY_DRIVER	(1 << 3)
+
+#define GUC_CTL_FEATURE			7
+#define   GUC_CTL_VCS2_ENABLED		(1 << 0)
+#define   GUC_CTL_KERNEL_SUBMISSIONS	(1 << 1)
+#define   GUC_CTL_FEATURE2		(1 << 2)
+#define   GUC_CTL_POWER_GATING		(1 << 3)
+#define   GUC_CTL_DISABLE_SCHEDULER	(1 << 4)
+#define   GUC_CTL_PREEMPTION_LOG	(1 << 5)
+#define   GUC_CTL_ENABLE_SLPC		(1 << 7)
+#define   GUC_CTL_RESET_ON_PREMPT_FAILURE	(1 << 8)
+
+#define GUC_CTL_DEBUG			8
+#define   GUC_LOG_VERBOSITY_SHIFT	0
+#define   GUC_LOG_VERBOSITY_LOW		(0 << GUC_LOG_VERBOSITY_SHIFT)
+#define   GUC_LOG_VERBOSITY_MED		(1 << GUC_LOG_VERBOSITY_SHIFT)
+#define   GUC_LOG_VERBOSITY_HIGH	(2 << GUC_LOG_VERBOSITY_SHIFT)
+#define   GUC_LOG_VERBOSITY_ULTRA	(3 << GUC_LOG_VERBOSITY_SHIFT)
+/* Verbosity range-check limits, without the shift */
+#define	  GUC_LOG_VERBOSITY_MIN		0
+#define	  GUC_LOG_VERBOSITY_MAX		3
+#define	  GUC_LOG_VERBOSITY_MASK	0x0000000f
+#define	  GUC_LOG_DESTINATION_MASK	(3 << 4)
+#define   GUC_LOG_DISABLED		(1 << 6)
+#define   GUC_PROFILE_ENABLED		(1 << 7)
+#define   GUC_WQ_TRACK_ENABLED		(1 << 8)
+#define   GUC_ADS_ENABLED		(1 << 9)
+#define   GUC_DEBUG_RESERVED		(1 << 10)
+#define   GUC_ADS_ADDR_SHIFT		11
+#define   GUC_ADS_ADDR_MASK		0xfffff800
+
+#define GUC_CTL_RSRVD			9
+
+#define GUC_CTL_MAX_DWORDS		(SOFT_SCRATCH_COUNT - 2) /* [1..14] */
+
+/**
+ * DOC: GuC Firmware Layout
+ *
+ * The GuC firmware layout looks like this:
+ *
+ *     +-------------------------------+
+ *     |        guc_css_header         |
+ *     | contains major/minor version  |
+ *     +-------------------------------+
+ *     |             uCode             |
+ *     +-------------------------------+
+ *     |         RSA signature         |
+ *     +-------------------------------+
+ *     |          modulus key          |
+ *     +-------------------------------+
+ *     |          exponent val         |
+ *     +-------------------------------+
+ *
+ * The firmware may or may not have modulus key and exponent data. The header,
+ * uCode and RSA signature are must-have components that will be used by driver.
+ * Length of each components, which is all in dwords, can be found in header.
+ * In the case that modulus and exponent are not present in fw, a.k.a truncated
+ * image, the length value still appears in header.
+ *
+ * Driver will do some basic fw size validation based on the following rules:
+ *
+ * 1. Header, uCode and RSA are must-have components.
+ * 2. All firmware components, if they present, are in the sequence illustrated
+ * in the layout table above.
+ * 3. Length info of each component can be found in header, in dwords.
+ * 4. Modulus and exponent key are not required by driver. They may not appear
+ * in fw. So driver will load a truncated firmware in this case.
+ */
+
+struct guc_css_header {
+	uint32_t module_type;
+	/* header_size includes all non-uCode bits, including css_header, rsa
+	 * key, modulus key and exponent data. */
+	uint32_t header_size_dw;
+	uint32_t header_version;
+	uint32_t module_id;
+	uint32_t module_vendor;
+	union {
+		struct {
+			uint8_t day;
+			uint8_t month;
+			uint16_t year;
+		};
+		uint32_t date;
+	};
+	uint32_t size_dw; /* uCode plus header_size_dw */
+	uint32_t key_size_dw;
+	uint32_t modulus_size_dw;
+	uint32_t exponent_size_dw;
+	union {
+		struct {
+			uint8_t hour;
+			uint8_t min;
+			uint16_t sec;
+		};
+		uint32_t time;
+	};
+
+	char username[8];
+	char buildnumber[12];
+	uint32_t device_id;
+	uint32_t guc_sw_version;
+	uint32_t prod_preprod_fw;
+	uint32_t reserved[12];
+	uint32_t header_info;
+} __packed;
+
+struct guc_doorbell_info {
+	u32 db_status;
+	u32 cookie;
+	u32 reserved[14];
+} __packed;
+
+union guc_doorbell_qw {
+	struct {
+		u32 db_status;
+		u32 cookie;
+	};
+	u64 value_qw;
+} __packed;
+
+#define GUC_MAX_DOORBELLS		256
+#define GUC_INVALID_DOORBELL_ID		(GUC_MAX_DOORBELLS)
+
+#define GUC_DB_SIZE			(PAGE_SIZE)
+#define GUC_WQ_SIZE			(PAGE_SIZE * 2)
+
+/* Work item for submitting workloads into work queue of GuC. */
+struct guc_wq_item {
+	u32 header;
+	u32 context_desc;
+	u32 ring_tail;
+	u32 fence_id;
+} __packed;
+
+struct guc_process_desc {
+	u32 context_id;
+	u64 db_base_addr;
+	u32 head;
+	u32 tail;
+	u32 error_offset;
+	u64 wq_base_addr;
+	u32 wq_size_bytes;
+	u32 wq_status;
+	u32 engine_presence;
+	u32 priority;
+	u32 reserved[30];
+} __packed;
+
+/* engine id and context id is packed into guc_execlist_context.context_id*/
+#define GUC_ELC_CTXID_OFFSET		0
+#define GUC_ELC_ENGINE_OFFSET		29
+
+/* The execlist context including software and HW information */
+struct guc_execlist_context {
+	u32 context_desc;
+	u32 context_id;
+	u32 ring_status;
+	u32 ring_lcra;
+	u32 ring_begin;
+	u32 ring_end;
+	u32 ring_next_free_location;
+	u32 ring_current_tail_pointer_value;
+	u8 engine_state_submit_value;
+	u8 engine_state_wait_value;
+	u16 pagefault_count;
+	u16 engine_submit_queue_count;
+} __packed;
+
+/*Context descriptor for communicating between uKernel and Driver*/
+struct guc_context_desc {
+	u32 sched_common_area;
+	u32 context_id;
+	u32 pas_id;
+	u8 engines_used;
+	u64 db_trigger_cpu;
+	u32 db_trigger_uk;
+	u64 db_trigger_phy;
+	u16 db_id;
+
+	struct guc_execlist_context lrc[GUC_MAX_ENGINES_NUM];
+
+	u8 attribute;
+
+	u32 priority;
+
+	u32 wq_sampled_tail_offset;
+	u32 wq_total_submit_enqueues;
+
+	u32 process_desc;
+	u32 wq_addr;
+	u32 wq_size;
+
+	u32 engine_presence;
+
+	u8 engine_suspended;
+
+	u8 reserved0[3];
+	u64 reserved1[1];
+
+	u64 desc_private;
+} __packed;
+
+#define GUC_FORCEWAKE_RENDER	(1 << 0)
+#define GUC_FORCEWAKE_MEDIA	(1 << 1)
+
+#define GUC_POWER_UNSPECIFIED	0
+#define GUC_POWER_D0		1
+#define GUC_POWER_D1		2
+#define GUC_POWER_D2		3
+#define GUC_POWER_D3		4
+
+/* Scheduling policy settings */
+
+/* Reset engine upon preempt failure */
+#define POLICY_RESET_ENGINE		(1<<0)
+/* Preempt to idle on quantum expiry */
+#define POLICY_PREEMPT_TO_IDLE		(1<<1)
+
+#define POLICY_MAX_NUM_WI		15
+
+struct guc_policy {
+	/* Time for one workload to execute. (in micro seconds) */
+	u32 execution_quantum;
+	u32 reserved1;
+
+	/* Time to wait for a preemption request to completed before issuing a
+	 * reset. (in micro seconds). */
+	u32 preemption_time;
+
+	/* How much time to allow to run after the first fault is observed.
+	 * Then preempt afterwards. (in micro seconds) */
+	u32 fault_time;
+
+	u32 policy_flags;
+	u32 reserved[2];
+} __packed;
+
+struct guc_policies {
+	struct guc_policy policy[GUC_CTX_PRIORITY_NUM][GUC_MAX_ENGINES_NUM];
+
+	/* In micro seconds. How much time to allow before DPC processing is
+	 * called back via interrupt (to prevent DPC queue drain starving).
+	 * Typically 1000s of micro seconds (example only, not granularity). */
+	u32 dpc_promote_time;
+
+	/* Must be set to take these new values. */
+	u32 is_valid;
+
+	/* Max number of WIs to process per call. A large value may keep CS
+	 * idle. */
+	u32 max_num_work_items;
+
+	u32 reserved[19];
+} __packed;
+
+/* GuC MMIO reg state struct */
+
+#define GUC_REGSET_FLAGS_NONE		0x0
+#define GUC_REGSET_POWERCYCLE		0x1
+#define GUC_REGSET_MASKED		0x2
+#define GUC_REGSET_ENGINERESET		0x4
+#define GUC_REGSET_SAVE_DEFAULT_VALUE	0x8
+#define GUC_REGSET_SAVE_CURRENT_VALUE	0x10
+
+#define GUC_REGSET_MAX_REGISTERS	25
+#define GUC_MMIO_WHITE_LIST_START	0x24d0
+#define GUC_MMIO_WHITE_LIST_MAX		12
+#define GUC_S3_SAVE_SPACE_PAGES		10
+
+struct guc_mmio_regset {
+	struct __packed {
+		u32 offset;
+		u32 value;
+		u32 flags;
+	} registers[GUC_REGSET_MAX_REGISTERS];
+
+	u32 values_valid;
+	u32 number_of_registers;
+} __packed;
+
+struct guc_mmio_reg_state {
+	struct guc_mmio_regset global_reg;
+	struct guc_mmio_regset engine_reg[GUC_MAX_ENGINES_NUM];
+
+	/* MMIO registers that are set as non privileged */
+	struct __packed {
+		u32 mmio_start;
+		u32 offsets[GUC_MMIO_WHITE_LIST_MAX];
+		u32 count;
+	} mmio_white_list[GUC_MAX_ENGINES_NUM];
+} __packed;
+
+/* GuC Additional Data Struct */
+
+struct guc_ads {
+	u32 reg_state_addr;
+	u32 reg_state_buffer;
+	u32 golden_context_lrca;
+	u32 scheduler_policies;
+	u32 reserved0[3];
+	u32 eng_state_size[GUC_MAX_ENGINES_NUM];
+	u32 reserved2[4];
+} __packed;
+
+/* This Action will be programmed in C180 - SOFT_SCRATCH_O_REG */
+enum host2guc_action {
+	HOST2GUC_ACTION_DEFAULT = 0x0,
+	HOST2GUC_ACTION_SAMPLE_FORCEWAKE = 0x6,
+	HOST2GUC_ACTION_ALLOCATE_DOORBELL = 0x10,
+	HOST2GUC_ACTION_DEALLOCATE_DOORBELL = 0x20,
+	HOST2GUC_ACTION_ENTER_S_STATE = 0x501,
+	HOST2GUC_ACTION_EXIT_S_STATE = 0x502,
+	HOST2GUC_ACTION_SLPC_REQUEST = 0x3003,
+	HOST2GUC_ACTION_LIMIT
+};
+
+/*
+ * The GuC sends its response to a command by overwriting the
+ * command in SS0. The response is distinguishable from a command
+ * by the fact that all the MASK bits are set. The remaining bits
+ * give more detail.
+ */
+#define	GUC2HOST_RESPONSE_MASK		((u32)0xF0000000)
+#define	GUC2HOST_IS_RESPONSE(x) 	((u32)(x) >= GUC2HOST_RESPONSE_MASK)
+#define	GUC2HOST_STATUS(x)		(GUC2HOST_RESPONSE_MASK | (x))
+
+/* GUC will return status back to SOFT_SCRATCH_O_REG */
+enum guc2host_status {
+	GUC2HOST_STATUS_SUCCESS = GUC2HOST_STATUS(0x0),
+	GUC2HOST_STATUS_ALLOCATE_DOORBELL_FAIL = GUC2HOST_STATUS(0x10),
+	GUC2HOST_STATUS_DEALLOCATE_DOORBELL_FAIL = GUC2HOST_STATUS(0x20),
+	GUC2HOST_STATUS_GENERIC_FAIL = GUC2HOST_STATUS(0x0000F000)
+};
+
+#endif
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/i915/intel_guc_loader.c
@@ -0,0 +1,691 @@
+/*
+ * Copyright © 2014 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Vinit Azad <vinit.azad@intel.com>
+ *    Ben Widawsky <ben@bwidawsk.net>
+ *    Dave Gordon <david.s.gordon@intel.com>
+ *    Alex Dai <yu.dai@intel.com>
+ */
+#include <linux/firmware.h>
+#include "i915_drv.h"
+#include "intel_guc.h"
+
+/**
+ * DOC: GuC-specific firmware loader
+ *
+ * intel_guc:
+ * Top level structure of guc. It handles firmware loading and manages client
+ * pool and doorbells. intel_guc owns a i915_guc_client to replace the legacy
+ * ExecList submission.
+ *
+ * Firmware versioning:
+ * The firmware build process will generate a version header file with major and
+ * minor version defined. The versions are built into CSS header of firmware.
+ * i915 kernel driver set the minimal firmware version required per platform.
+ * The firmware installation package will install (symbolic link) proper version
+ * of firmware.
+ *
+ * GuC address space:
+ * GuC does not allow any gfx GGTT address that falls into range [0, WOPCM_TOP),
+ * which is reserved for Boot ROM, SRAM and WOPCM. Currently this top address is
+ * 512K. In order to exclude 0-512K address space from GGTT, all gfx objects
+ * used by GuC is pinned with PIN_OFFSET_BIAS along with size of WOPCM.
+ *
+ * Firmware log:
+ * Firmware log is enabled by setting i915.guc_log_level to non-negative level.
+ * Log data is printed out via reading debugfs i915_guc_log_dump. Reading from
+ * i915_guc_load_status will print out firmware loading status and scratch
+ * registers value.
+ *
+ */
+
+#define I915_SKL_GUC_UCODE "i915/skl_guc_ver6.bin"
+MODULE_FIRMWARE(I915_SKL_GUC_UCODE);
+
+/* User-friendly representation of an enum */
+const char *intel_guc_fw_status_repr(enum intel_guc_fw_status status)
+{
+	switch (status) {
+	case GUC_FIRMWARE_FAIL:
+		return "FAIL";
+	case GUC_FIRMWARE_NONE:
+		return "NONE";
+	case GUC_FIRMWARE_PENDING:
+		return "PENDING";
+	case GUC_FIRMWARE_SUCCESS:
+		return "SUCCESS";
+	default:
+		return "UNKNOWN!";
+	}
+};
+
+static void direct_interrupts_to_host(struct drm_i915_private *dev_priv)
+{
+	struct intel_engine_cs *engine;
+	int irqs;
+
+	/* tell all command streamers NOT to forward interrupts and vblank to GuC */
+	irqs = _MASKED_FIELD(GFX_FORWARD_VBLANK_MASK, GFX_FORWARD_VBLANK_NEVER);
+	irqs |= _MASKED_BIT_DISABLE(GFX_INTERRUPT_STEERING);
+	for_each_engine(engine, dev_priv)
+		I915_WRITE(RING_MODE_GEN7(engine), irqs);
+
+	/* route all GT interrupts to the host */
+	I915_WRITE(GUC_BCS_RCS_IER, 0);
+	I915_WRITE(GUC_VCS2_VCS1_IER, 0);
+	I915_WRITE(GUC_WD_VECS_IER, 0);
+}
+
+static void direct_interrupts_to_guc(struct drm_i915_private *dev_priv)
+{
+	struct intel_engine_cs *engine;
+	int irqs;
+
+	/* tell all command streamers to forward interrupts and vblank to GuC */
+	irqs = _MASKED_FIELD(GFX_FORWARD_VBLANK_MASK, GFX_FORWARD_VBLANK_ALWAYS);
+	irqs |= _MASKED_BIT_ENABLE(GFX_INTERRUPT_STEERING);
+	for_each_engine(engine, dev_priv)
+		I915_WRITE(RING_MODE_GEN7(engine), irqs);
+
+	/* route USER_INTERRUPT to Host, all others are sent to GuC. */
+	irqs = GT_RENDER_USER_INTERRUPT << GEN8_RCS_IRQ_SHIFT |
+	       GT_RENDER_USER_INTERRUPT << GEN8_BCS_IRQ_SHIFT;
+	/* These three registers have the same bit definitions */
+	I915_WRITE(GUC_BCS_RCS_IER, ~irqs);
+	I915_WRITE(GUC_VCS2_VCS1_IER, ~irqs);
+	I915_WRITE(GUC_WD_VECS_IER, ~irqs);
+}
+
+static u32 get_gttype(struct drm_i915_private *dev_priv)
+{
+	/* XXX: GT type based on PCI device ID? field seems unused by fw */
+	return 0;
+}
+
+static u32 get_core_family(struct drm_i915_private *dev_priv)
+{
+	switch (INTEL_INFO(dev_priv)->gen) {
+	case 9:
+		return GFXCORE_FAMILY_GEN9;
+
+	default:
+		DRM_ERROR("GUC: unsupported core family\n");
+		return GFXCORE_FAMILY_UNKNOWN;
+	}
+}
+
+static void set_guc_init_params(struct drm_i915_private *dev_priv)
+{
+	struct intel_guc *guc = &dev_priv->guc;
+	u32 params[GUC_CTL_MAX_DWORDS];
+	int i;
+
+	memset(&params, 0, sizeof(params));
+
+	params[GUC_CTL_DEVICE_INFO] |=
+		(get_gttype(dev_priv) << GUC_CTL_GTTYPE_SHIFT) |
+		(get_core_family(dev_priv) << GUC_CTL_COREFAMILY_SHIFT);
+
+	/*
+	 * GuC ARAT increment is 10 ns. GuC default scheduler quantum is one
+	 * second. This ARAR is calculated by:
+	 * Scheduler-Quantum-in-ns / ARAT-increment-in-ns = 1000000000 / 10
+	 */
+	params[GUC_CTL_ARAT_HIGH] = 0;
+	params[GUC_CTL_ARAT_LOW] = 100000000;
+
+	params[GUC_CTL_WA] |= GUC_CTL_WA_UK_BY_DRIVER;
+
+	params[GUC_CTL_FEATURE] |= GUC_CTL_DISABLE_SCHEDULER |
+			GUC_CTL_VCS2_ENABLED;
+
+	if (i915.guc_log_level >= 0) {
+		params[GUC_CTL_LOG_PARAMS] = guc->log_flags;
+		params[GUC_CTL_DEBUG] =
+			i915.guc_log_level << GUC_LOG_VERBOSITY_SHIFT;
+	}
+
+	if (guc->ads_obj) {
+		u32 ads = (u32)i915_gem_obj_ggtt_offset(guc->ads_obj)
+				>> PAGE_SHIFT;
+		params[GUC_CTL_DEBUG] |= ads << GUC_ADS_ADDR_SHIFT;
+		params[GUC_CTL_DEBUG] |= GUC_ADS_ENABLED;
+	}
+
+	/* If GuC submission is enabled, set up additional parameters here */
+	if (i915.enable_guc_submission) {
+		u32 pgs = i915_gem_obj_ggtt_offset(dev_priv->guc.ctx_pool_obj);
+		u32 ctx_in_16 = GUC_MAX_GPU_CONTEXTS / 16;
+
+		pgs >>= PAGE_SHIFT;
+		params[GUC_CTL_CTXINFO] = (pgs << GUC_CTL_BASE_ADDR_SHIFT) |
+			(ctx_in_16 << GUC_CTL_CTXNUM_IN16_SHIFT);
+
+		params[GUC_CTL_FEATURE] |= GUC_CTL_KERNEL_SUBMISSIONS;
+
+		/* Unmask this bit to enable the GuC's internal scheduler */
+		params[GUC_CTL_FEATURE] &= ~GUC_CTL_DISABLE_SCHEDULER;
+	}
+
+	I915_WRITE(SOFT_SCRATCH(0), 0);
+
+	for (i = 0; i < GUC_CTL_MAX_DWORDS; i++)
+		I915_WRITE(SOFT_SCRATCH(1 + i), params[i]);
+}
+
+/*
+ * Read the GuC status register (GUC_STATUS) and store it in the
+ * specified location; then return a boolean indicating whether
+ * the value matches either of two values representing completion
+ * of the GuC boot process.
+ *
+ * This is used for polling the GuC status in a wait_for()
+ * loop below.
+ */
+static inline bool guc_ucode_response(struct drm_i915_private *dev_priv,
+				      u32 *status)
+{
+	u32 val = I915_READ(GUC_STATUS);
+	u32 uk_val = val & GS_UKERNEL_MASK;
+	*status = val;
+	return (uk_val == GS_UKERNEL_READY ||
+		((val & GS_MIA_CORE_STATE) && uk_val == GS_UKERNEL_LAPIC_DONE));
+}
+
+/*
+ * Transfer the firmware image to RAM for execution by the microcontroller.
+ *
+ * Architecturally, the DMA engine is bidirectional, and can potentially even
+ * transfer between GTT locations. This functionality is left out of the API
+ * for now as there is no need for it.
+ *
+ * Note that GuC needs the CSS header plus uKernel code to be copied by the
+ * DMA engine in one operation, whereas the RSA signature is loaded via MMIO.
+ */
+static int guc_ucode_xfer_dma(struct drm_i915_private *dev_priv)
+{
+	struct intel_guc_fw *guc_fw = &dev_priv->guc.guc_fw;
+	struct drm_i915_gem_object *fw_obj = guc_fw->guc_fw_obj;
+	unsigned long offset;
+	struct sg_table *sg = fw_obj->pages;
+	u32 status, rsa[UOS_RSA_SCRATCH_MAX_COUNT];
+	int i, ret = 0;
+
+	/* where RSA signature starts */
+	offset = guc_fw->rsa_offset;
+
+	/* Copy RSA signature from the fw image to HW for verification */
+	sg_pcopy_to_buffer(sg->sgl, sg->nents, rsa, sizeof(rsa), offset);
+	for (i = 0; i < UOS_RSA_SCRATCH_MAX_COUNT; i++)
+		I915_WRITE(UOS_RSA_SCRATCH(i), rsa[i]);
+
+	/* The header plus uCode will be copied to WOPCM via DMA, excluding any
+	 * other components */
+	I915_WRITE(DMA_COPY_SIZE, guc_fw->header_size + guc_fw->ucode_size);
+
+	/* Set the source address for the new blob */
+	offset = i915_gem_obj_ggtt_offset(fw_obj) + guc_fw->header_offset;
+	I915_WRITE(DMA_ADDR_0_LOW, lower_32_bits(offset));
+	I915_WRITE(DMA_ADDR_0_HIGH, upper_32_bits(offset) & 0xFFFF);
+
+	/*
+	 * Set the DMA destination. Current uCode expects the code to be
+	 * loaded at 8k; locations below this are used for the stack.
+	 */
+	I915_WRITE(DMA_ADDR_1_LOW, 0x2000);
+	I915_WRITE(DMA_ADDR_1_HIGH, DMA_ADDRESS_SPACE_WOPCM);
+
+	/* Finally start the DMA */
+	I915_WRITE(DMA_CTRL, _MASKED_BIT_ENABLE(UOS_MOVE | START_DMA));
+
+	/*
+	 * Wait for the DMA to complete & the GuC to start up.
+	 * NB: Docs recommend not using the interrupt for completion.
+	 * Measurements indicate this should take no more than 20ms, so a
+	 * timeout here indicates that the GuC has failed and is unusable.
+	 * (Higher levels of the driver will attempt to fall back to
+	 * execlist mode if this happens.)
+	 */
+	ret = wait_for(guc_ucode_response(dev_priv, &status), 100);
+
+	DRM_DEBUG_DRIVER("DMA status 0x%x, GuC status 0x%x\n",
+			I915_READ(DMA_CTRL), status);
+
+	if ((status & GS_BOOTROM_MASK) == GS_BOOTROM_RSA_FAILED) {
+		DRM_ERROR("GuC firmware signature verification failed\n");
+		ret = -ENOEXEC;
+	}
+
+	DRM_DEBUG_DRIVER("returning %d\n", ret);
+
+	return ret;
+}
+
+/*
+ * Load the GuC firmware blob into the MinuteIA.
+ */
+static int guc_ucode_xfer(struct drm_i915_private *dev_priv)
+{
+	struct intel_guc_fw *guc_fw = &dev_priv->guc.guc_fw;
+	struct drm_device *dev = dev_priv->dev;
+	int ret;
+
+	ret = i915_gem_object_set_to_gtt_domain(guc_fw->guc_fw_obj, false);
+	if (ret) {
+		DRM_DEBUG_DRIVER("set-domain failed %d\n", ret);
+		return ret;
+	}
+
+	ret = i915_gem_obj_ggtt_pin(guc_fw->guc_fw_obj, 0, 0);
+	if (ret) {
+		DRM_DEBUG_DRIVER("pin failed %d\n", ret);
+		return ret;
+	}
+
+	/* Invalidate GuC TLB to let GuC take the latest updates to GTT. */
+	I915_WRITE(GEN8_GTCR, GEN8_GTCR_INVALIDATE);
+
+	intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL);
+
+	/* init WOPCM */
+	I915_WRITE(GUC_WOPCM_SIZE, GUC_WOPCM_SIZE_VALUE);
+	I915_WRITE(DMA_GUC_WOPCM_OFFSET, GUC_WOPCM_OFFSET_VALUE);
+
+	/* Enable MIA caching. GuC clock gating is disabled. */
+	I915_WRITE(GUC_SHIM_CONTROL, GUC_SHIM_CONTROL_VALUE);
+
+	/* WaDisableMinuteIaClockGating:skl,bxt */
+	if (IS_SKL_REVID(dev, 0, SKL_REVID_B0) ||
+	    IS_BXT_REVID(dev, 0, BXT_REVID_A1)) {
+		I915_WRITE(GUC_SHIM_CONTROL, (I915_READ(GUC_SHIM_CONTROL) &
+					      ~GUC_ENABLE_MIA_CLOCK_GATING));
+	}
+
+	/* WaC6DisallowByGfxPause*/
+	I915_WRITE(GEN6_GFXPAUSE, 0x30FFF);
+
+	if (IS_BROXTON(dev))
+		I915_WRITE(GEN9LP_GT_PM_CONFIG, GT_DOORBELL_ENABLE);
+	else
+		I915_WRITE(GEN9_GT_PM_CONFIG, GT_DOORBELL_ENABLE);
+
+	if (IS_GEN9(dev)) {
+		/* DOP Clock Gating Enable for GuC clocks */
+		I915_WRITE(GEN7_MISCCPCTL, (GEN8_DOP_CLOCK_GATE_GUC_ENABLE |
+					    I915_READ(GEN7_MISCCPCTL)));
+
+		/* allows for 5us before GT can go to RC6 */
+		I915_WRITE(GUC_ARAT_C6DIS, 0x1FF);
+	}
+
+	set_guc_init_params(dev_priv);
+
+	ret = guc_ucode_xfer_dma(dev_priv);
+
+	intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
+
+	/*
+	 * We keep the object pages for reuse during resume. But we can unpin it
+	 * now that DMA has completed, so it doesn't continue to take up space.
+	 */
+	i915_gem_object_ggtt_unpin(guc_fw->guc_fw_obj);
+
+	return ret;
+}
+
+static int i915_reset_guc(struct drm_i915_private *dev_priv)
+{
+	int ret;
+	u32 guc_status;
+
+	ret = intel_guc_reset(dev_priv);
+	if (ret) {
+		DRM_ERROR("GuC reset failed, ret = %d\n", ret);
+		return ret;
+	}
+
+	guc_status = I915_READ(GUC_STATUS);
+	WARN(!(guc_status & GS_MIA_IN_RESET),
+	     "GuC status: 0x%x, MIA core expected to be in reset\n", guc_status);
+
+	return ret;
+}
+
+/**
+ * intel_guc_ucode_load() - load GuC uCode into the device
+ * @dev:	drm device
+ *
+ * Called from gem_init_hw() during driver loading and also after a GPU reset.
+ *
+ * The firmware image should have already been fetched into memory by the
+ * earlier call to intel_guc_ucode_init(), so here we need only check that
+ * is succeeded, and then transfer the image to the h/w.
+ *
+ * Return:	non-zero code on error
+ */
+int intel_guc_ucode_load(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_guc_fw *guc_fw = &dev_priv->guc.guc_fw;
+	int retries, err = 0;
+
+	if (!i915.enable_guc_submission)
+		return 0;
+
+	DRM_DEBUG_DRIVER("GuC fw status: fetch %s, load %s\n",
+		intel_guc_fw_status_repr(guc_fw->guc_fw_fetch_status),
+		intel_guc_fw_status_repr(guc_fw->guc_fw_load_status));
+
+	direct_interrupts_to_host(dev_priv);
+
+	if (guc_fw->guc_fw_fetch_status == GUC_FIRMWARE_NONE)
+		return 0;
+
+	if (guc_fw->guc_fw_fetch_status == GUC_FIRMWARE_SUCCESS &&
+	    guc_fw->guc_fw_load_status == GUC_FIRMWARE_FAIL)
+		return -ENOEXEC;
+
+	guc_fw->guc_fw_load_status = GUC_FIRMWARE_PENDING;
+
+	DRM_DEBUG_DRIVER("GuC fw fetch status %s\n",
+		intel_guc_fw_status_repr(guc_fw->guc_fw_fetch_status));
+
+	switch (guc_fw->guc_fw_fetch_status) {
+	case GUC_FIRMWARE_FAIL:
+		/* something went wrong :( */
+		err = -EIO;
+		goto fail;
+
+	case GUC_FIRMWARE_NONE:
+	case GUC_FIRMWARE_PENDING:
+	default:
+		/* "can't happen" */
+		WARN_ONCE(1, "GuC fw %s invalid guc_fw_fetch_status %s [%d]\n",
+			guc_fw->guc_fw_path,
+			intel_guc_fw_status_repr(guc_fw->guc_fw_fetch_status),
+			guc_fw->guc_fw_fetch_status);
+		err = -ENXIO;
+		goto fail;
+
+	case GUC_FIRMWARE_SUCCESS:
+		break;
+	}
+
+	err = i915_guc_submission_init(dev);
+	if (err)
+		goto fail;
+
+	/*
+	 * WaEnableuKernelHeaderValidFix:skl,bxt
+	 * For BXT, this is only upto B0 but below WA is required for later
+	 * steppings also so this is extended as well.
+	 */
+	/* WaEnableGuCBootHashCheckNotSet:skl,bxt */
+	for (retries = 3; ; ) {
+		/*
+		 * Always reset the GuC just before (re)loading, so
+		 * that the state and timing are fairly predictable
+		 */
+		err = i915_reset_guc(dev_priv);
+		if (err) {
+			DRM_ERROR("GuC reset failed, err %d\n", err);
+			goto fail;
+		}
+
+		err = guc_ucode_xfer(dev_priv);
+		if (!err)
+			break;
+
+		if (--retries == 0)
+			goto fail;
+
+		DRM_INFO("GuC fw load failed, err %d; will reset and "
+			"retry %d more time(s)\n", err, retries);
+	}
+
+	guc_fw->guc_fw_load_status = GUC_FIRMWARE_SUCCESS;
+
+	DRM_DEBUG_DRIVER("GuC fw status: fetch %s, load %s\n",
+		intel_guc_fw_status_repr(guc_fw->guc_fw_fetch_status),
+		intel_guc_fw_status_repr(guc_fw->guc_fw_load_status));
+
+	if (i915.enable_guc_submission) {
+		/* The execbuf_client will be recreated. Release it first. */
+		i915_guc_submission_disable(dev);
+
+		err = i915_guc_submission_enable(dev);
+		if (err)
+			goto fail;
+		direct_interrupts_to_guc(dev_priv);
+	}
+
+	return 0;
+
+fail:
+	DRM_ERROR("GuC firmware load failed, err %d\n", err);
+	if (guc_fw->guc_fw_load_status == GUC_FIRMWARE_PENDING)
+		guc_fw->guc_fw_load_status = GUC_FIRMWARE_FAIL;
+
+	direct_interrupts_to_host(dev_priv);
+	i915_guc_submission_disable(dev);
+	i915_guc_submission_fini(dev);
+
+	return err;
+}
+
+static void guc_fw_fetch(struct drm_device *dev, struct intel_guc_fw *guc_fw)
+{
+	struct drm_i915_gem_object *obj;
+	const struct firmware *fw;
+	struct guc_css_header *css;
+	size_t size;
+	int err;
+
+	DRM_DEBUG_DRIVER("before requesting firmware: GuC fw fetch status %s\n",
+		intel_guc_fw_status_repr(guc_fw->guc_fw_fetch_status));
+
+	err = request_firmware(&fw, guc_fw->guc_fw_path, &dev->pdev->dev);
+	if (err)
+		goto fail;
+	if (!fw)
+		goto fail;
+
+	DRM_DEBUG_DRIVER("fetch GuC fw from %s succeeded, fw %p\n",
+		guc_fw->guc_fw_path, fw);
+
+	/* Check the size of the blob before examining buffer contents */
+	if (fw->size < sizeof(struct guc_css_header)) {
+		DRM_ERROR("Firmware header is missing\n");
+		goto fail;
+	}
+
+	css = (struct guc_css_header *)fw->data;
+
+	/* Firmware bits always start from header */
+	guc_fw->header_offset = 0;
+	guc_fw->header_size = (css->header_size_dw - css->modulus_size_dw -
+		css->key_size_dw - css->exponent_size_dw) * sizeof(u32);
+
+	if (guc_fw->header_size != sizeof(struct guc_css_header)) {
+		DRM_ERROR("CSS header definition mismatch\n");
+		goto fail;
+	}
+
+	/* then, uCode */
+	guc_fw->ucode_offset = guc_fw->header_offset + guc_fw->header_size;
+	guc_fw->ucode_size = (css->size_dw - css->header_size_dw) * sizeof(u32);
+
+	/* now RSA */
+	if (css->key_size_dw != UOS_RSA_SCRATCH_MAX_COUNT) {
+		DRM_ERROR("RSA key size is bad\n");
+		goto fail;
+	}
+	guc_fw->rsa_offset = guc_fw->ucode_offset + guc_fw->ucode_size;
+	guc_fw->rsa_size = css->key_size_dw * sizeof(u32);
+
+	/* At least, it should have header, uCode and RSA. Size of all three. */
+	size = guc_fw->header_size + guc_fw->ucode_size + guc_fw->rsa_size;
+	if (fw->size < size) {
+		DRM_ERROR("Missing firmware components\n");
+		goto fail;
+	}
+
+	/* Header and uCode will be loaded to WOPCM. Size of the two. */
+	size = guc_fw->header_size + guc_fw->ucode_size;
+
+	/* Top 32k of WOPCM is reserved (8K stack + 24k RC6 context). */
+	if (size > GUC_WOPCM_SIZE_VALUE - 0x8000) {
+		DRM_ERROR("Firmware is too large to fit in WOPCM\n");
+		goto fail;
+	}
+
+	/*
+	 * The GuC firmware image has the version number embedded at a well-known
+	 * offset within the firmware blob; note that major / minor version are
+	 * TWO bytes each (i.e. u16), although all pointers and offsets are defined
+	 * in terms of bytes (u8).
+	 */
+	guc_fw->guc_fw_major_found = css->guc_sw_version >> 16;
+	guc_fw->guc_fw_minor_found = css->guc_sw_version & 0xFFFF;
+
+	if (guc_fw->guc_fw_major_found != guc_fw->guc_fw_major_wanted ||
+	    guc_fw->guc_fw_minor_found < guc_fw->guc_fw_minor_wanted) {
+		DRM_ERROR("GuC firmware version %d.%d, required %d.%d\n",
+			guc_fw->guc_fw_major_found, guc_fw->guc_fw_minor_found,
+			guc_fw->guc_fw_major_wanted, guc_fw->guc_fw_minor_wanted);
+		err = -ENOEXEC;
+		goto fail;
+	}
+
+	DRM_DEBUG_DRIVER("firmware version %d.%d OK (minimum %d.%d)\n",
+			guc_fw->guc_fw_major_found, guc_fw->guc_fw_minor_found,
+			guc_fw->guc_fw_major_wanted, guc_fw->guc_fw_minor_wanted);
+
+	mutex_lock(&dev->struct_mutex);
+	obj = i915_gem_object_create_from_data(dev, fw->data, fw->size);
+	mutex_unlock(&dev->struct_mutex);
+	if (IS_ERR_OR_NULL(obj)) {
+		err = obj ? PTR_ERR(obj) : -ENOMEM;
+		goto fail;
+	}
+
+	guc_fw->guc_fw_obj = obj;
+	guc_fw->guc_fw_size = fw->size;
+
+	DRM_DEBUG_DRIVER("GuC fw fetch status SUCCESS, obj %p\n",
+			guc_fw->guc_fw_obj);
+
+	release_firmware(fw);
+	guc_fw->guc_fw_fetch_status = GUC_FIRMWARE_SUCCESS;
+	return;
+
+fail:
+	DRM_DEBUG_DRIVER("GuC fw fetch status FAIL; err %d, fw %p, obj %p\n",
+		err, fw, guc_fw->guc_fw_obj);
+	DRM_ERROR("Failed to fetch GuC firmware from %s (error %d)\n",
+		  guc_fw->guc_fw_path, err);
+
+	mutex_lock(&dev->struct_mutex);
+	obj = guc_fw->guc_fw_obj;
+	if (obj)
+		drm_gem_object_unreference(&obj->base);
+	guc_fw->guc_fw_obj = NULL;
+	mutex_unlock(&dev->struct_mutex);
+
+	release_firmware(fw);		/* OK even if fw is NULL */
+	guc_fw->guc_fw_fetch_status = GUC_FIRMWARE_FAIL;
+}
+
+/**
+ * intel_guc_ucode_init() - define parameters and fetch firmware
+ * @dev:	drm device
+ *
+ * Called early during driver load, but after GEM is initialised.
+ *
+ * The firmware will be transferred to the GuC's memory later,
+ * when intel_guc_ucode_load() is called.
+ */
+void intel_guc_ucode_init(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_guc_fw *guc_fw = &dev_priv->guc.guc_fw;
+	const char *fw_path;
+
+	if (!HAS_GUC_SCHED(dev))
+		i915.enable_guc_submission = false;
+
+	if (!HAS_GUC_UCODE(dev)) {
+		fw_path = NULL;
+	} else if (IS_SKYLAKE(dev)) {
+		fw_path = I915_SKL_GUC_UCODE;
+		guc_fw->guc_fw_major_wanted = 6;
+		guc_fw->guc_fw_minor_wanted = 1;
+	} else {
+		i915.enable_guc_submission = false;
+		fw_path = "";	/* unknown device */
+	}
+
+	if (!i915.enable_guc_submission)
+		return;
+
+	guc_fw->guc_dev = dev;
+	guc_fw->guc_fw_path = fw_path;
+	guc_fw->guc_fw_fetch_status = GUC_FIRMWARE_NONE;
+	guc_fw->guc_fw_load_status = GUC_FIRMWARE_NONE;
+
+	if (fw_path == NULL)
+		return;
+
+	if (*fw_path == '\0') {
+		DRM_ERROR("No GuC firmware known for this platform\n");
+		guc_fw->guc_fw_fetch_status = GUC_FIRMWARE_FAIL;
+		return;
+	}
+
+	guc_fw->guc_fw_fetch_status = GUC_FIRMWARE_PENDING;
+	DRM_DEBUG_DRIVER("GuC firmware pending, path %s\n", fw_path);
+	guc_fw_fetch(dev, guc_fw);
+	/* status must now be FAIL or SUCCESS */
+}
+
+/**
+ * intel_guc_ucode_fini() - clean up all allocated resources
+ * @dev:	drm device
+ */
+void intel_guc_ucode_fini(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_guc_fw *guc_fw = &dev_priv->guc.guc_fw;
+
+	mutex_lock(&dev->struct_mutex);
+	direct_interrupts_to_host(dev_priv);
+	i915_guc_submission_disable(dev);
+	i915_guc_submission_fini(dev);
+
+	if (guc_fw->guc_fw_obj)
+		drm_gem_object_unreference(&guc_fw->guc_fw_obj->base);
+	guc_fw->guc_fw_obj = NULL;
+	mutex_unlock(&dev->struct_mutex);
+
+	guc_fw->guc_fw_fetch_status = GUC_FIRMWARE_NONE;
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/i915/intel_hdmi.c
@@ -0,0 +1,2339 @@
+/*
+ * Copyright 2006 Dave Airlie <airlied@linux.ie>
+ * Copyright © 2006-2009 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *	Eric Anholt <eric@anholt.net>
+ *	Jesse Barnes <jesse.barnes@intel.com>
+ */
+
+#include <linux/i2c.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/hdmi.h>
+#include <drm/drmP.h>
+#include <drm/drm_atomic_helper.h>
+#include <drm/drm_crtc.h>
+#include <drm/drm_edid.h>
+#include "intel_drv.h"
+#include <drm/i915_drm.h>
+#include "i915_drv.h"
+
+static struct drm_device *intel_hdmi_to_dev(struct intel_hdmi *intel_hdmi)
+{
+	return hdmi_to_dig_port(intel_hdmi)->base.base.dev;
+}
+
+static void
+assert_hdmi_port_disabled(struct intel_hdmi *intel_hdmi)
+{
+	struct drm_device *dev = intel_hdmi_to_dev(intel_hdmi);
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	uint32_t enabled_bits;
+
+	enabled_bits = HAS_DDI(dev) ? DDI_BUF_CTL_ENABLE : SDVO_ENABLE;
+
+	WARN(I915_READ(intel_hdmi->hdmi_reg) & enabled_bits,
+	     "HDMI port enabled, expecting disabled\n");
+}
+
+struct intel_hdmi *enc_to_intel_hdmi(struct drm_encoder *encoder)
+{
+	struct intel_digital_port *intel_dig_port =
+		container_of(encoder, struct intel_digital_port, base.base);
+	return &intel_dig_port->hdmi;
+}
+
+static struct intel_hdmi *intel_attached_hdmi(struct drm_connector *connector)
+{
+	return enc_to_intel_hdmi(&intel_attached_encoder(connector)->base);
+}
+
+static u32 g4x_infoframe_index(enum hdmi_infoframe_type type)
+{
+	switch (type) {
+	case HDMI_INFOFRAME_TYPE_AVI:
+		return VIDEO_DIP_SELECT_AVI;
+	case HDMI_INFOFRAME_TYPE_SPD:
+		return VIDEO_DIP_SELECT_SPD;
+	case HDMI_INFOFRAME_TYPE_VENDOR:
+		return VIDEO_DIP_SELECT_VENDOR;
+	default:
+		MISSING_CASE(type);
+		return 0;
+	}
+}
+
+static u32 g4x_infoframe_enable(enum hdmi_infoframe_type type)
+{
+	switch (type) {
+	case HDMI_INFOFRAME_TYPE_AVI:
+		return VIDEO_DIP_ENABLE_AVI;
+	case HDMI_INFOFRAME_TYPE_SPD:
+		return VIDEO_DIP_ENABLE_SPD;
+	case HDMI_INFOFRAME_TYPE_VENDOR:
+		return VIDEO_DIP_ENABLE_VENDOR;
+	default:
+		MISSING_CASE(type);
+		return 0;
+	}
+}
+
+static u32 hsw_infoframe_enable(enum hdmi_infoframe_type type)
+{
+	switch (type) {
+	case HDMI_INFOFRAME_TYPE_AVI:
+		return VIDEO_DIP_ENABLE_AVI_HSW;
+	case HDMI_INFOFRAME_TYPE_SPD:
+		return VIDEO_DIP_ENABLE_SPD_HSW;
+	case HDMI_INFOFRAME_TYPE_VENDOR:
+		return VIDEO_DIP_ENABLE_VS_HSW;
+	default:
+		MISSING_CASE(type);
+		return 0;
+	}
+}
+
+static i915_reg_t
+hsw_dip_data_reg(struct drm_i915_private *dev_priv,
+		 enum transcoder cpu_transcoder,
+		 enum hdmi_infoframe_type type,
+		 int i)
+{
+	switch (type) {
+	case HDMI_INFOFRAME_TYPE_AVI:
+		return HSW_TVIDEO_DIP_AVI_DATA(cpu_transcoder, i);
+	case HDMI_INFOFRAME_TYPE_SPD:
+		return HSW_TVIDEO_DIP_SPD_DATA(cpu_transcoder, i);
+	case HDMI_INFOFRAME_TYPE_VENDOR:
+		return HSW_TVIDEO_DIP_VS_DATA(cpu_transcoder, i);
+	default:
+		MISSING_CASE(type);
+		return INVALID_MMIO_REG;
+	}
+}
+
+static void g4x_write_infoframe(struct drm_encoder *encoder,
+				enum hdmi_infoframe_type type,
+				const void *frame, ssize_t len)
+{
+	const uint32_t *data = frame;
+	struct drm_device *dev = encoder->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	u32 val = I915_READ(VIDEO_DIP_CTL);
+	int i;
+
+	WARN(!(val & VIDEO_DIP_ENABLE), "Writing DIP with CTL reg disabled\n");
+
+	val &= ~(VIDEO_DIP_SELECT_MASK | 0xf); /* clear DIP data offset */
+	val |= g4x_infoframe_index(type);
+
+	val &= ~g4x_infoframe_enable(type);
+
+	I915_WRITE(VIDEO_DIP_CTL, val);
+
+	mmiowb();
+	for (i = 0; i < len; i += 4) {
+		I915_WRITE(VIDEO_DIP_DATA, *data);
+		data++;
+	}
+	/* Write every possible data byte to force correct ECC calculation. */
+	for (; i < VIDEO_DIP_DATA_SIZE; i += 4)
+		I915_WRITE(VIDEO_DIP_DATA, 0);
+	mmiowb();
+
+	val |= g4x_infoframe_enable(type);
+	val &= ~VIDEO_DIP_FREQ_MASK;
+	val |= VIDEO_DIP_FREQ_VSYNC;
+
+	I915_WRITE(VIDEO_DIP_CTL, val);
+	POSTING_READ(VIDEO_DIP_CTL);
+}
+
+static bool g4x_infoframe_enabled(struct drm_encoder *encoder,
+				  const struct intel_crtc_state *pipe_config)
+{
+	struct drm_i915_private *dev_priv = to_i915(encoder->dev);
+	struct intel_digital_port *intel_dig_port = enc_to_dig_port(encoder);
+	u32 val = I915_READ(VIDEO_DIP_CTL);
+
+	if ((val & VIDEO_DIP_ENABLE) == 0)
+		return false;
+
+	if ((val & VIDEO_DIP_PORT_MASK) != VIDEO_DIP_PORT(intel_dig_port->port))
+		return false;
+
+	return val & (VIDEO_DIP_ENABLE_AVI |
+		      VIDEO_DIP_ENABLE_VENDOR | VIDEO_DIP_ENABLE_SPD);
+}
+
+static void ibx_write_infoframe(struct drm_encoder *encoder,
+				enum hdmi_infoframe_type type,
+				const void *frame, ssize_t len)
+{
+	const uint32_t *data = frame;
+	struct drm_device *dev = encoder->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
+	i915_reg_t reg = TVIDEO_DIP_CTL(intel_crtc->pipe);
+	u32 val = I915_READ(reg);
+	int i;
+
+	WARN(!(val & VIDEO_DIP_ENABLE), "Writing DIP with CTL reg disabled\n");
+
+	val &= ~(VIDEO_DIP_SELECT_MASK | 0xf); /* clear DIP data offset */
+	val |= g4x_infoframe_index(type);
+
+	val &= ~g4x_infoframe_enable(type);
+
+	I915_WRITE(reg, val);
+
+	mmiowb();
+	for (i = 0; i < len; i += 4) {
+		I915_WRITE(TVIDEO_DIP_DATA(intel_crtc->pipe), *data);
+		data++;
+	}
+	/* Write every possible data byte to force correct ECC calculation. */
+	for (; i < VIDEO_DIP_DATA_SIZE; i += 4)
+		I915_WRITE(TVIDEO_DIP_DATA(intel_crtc->pipe), 0);
+	mmiowb();
+
+	val |= g4x_infoframe_enable(type);
+	val &= ~VIDEO_DIP_FREQ_MASK;
+	val |= VIDEO_DIP_FREQ_VSYNC;
+
+	I915_WRITE(reg, val);
+	POSTING_READ(reg);
+}
+
+static bool ibx_infoframe_enabled(struct drm_encoder *encoder,
+				  const struct intel_crtc_state *pipe_config)
+{
+	struct drm_i915_private *dev_priv = to_i915(encoder->dev);
+	struct intel_digital_port *intel_dig_port = enc_to_dig_port(encoder);
+	enum pipe pipe = to_intel_crtc(pipe_config->base.crtc)->pipe;
+	i915_reg_t reg = TVIDEO_DIP_CTL(pipe);
+	u32 val = I915_READ(reg);
+
+	if ((val & VIDEO_DIP_ENABLE) == 0)
+		return false;
+
+	if ((val & VIDEO_DIP_PORT_MASK) != VIDEO_DIP_PORT(intel_dig_port->port))
+		return false;
+
+	return val & (VIDEO_DIP_ENABLE_AVI |
+		      VIDEO_DIP_ENABLE_VENDOR | VIDEO_DIP_ENABLE_GAMUT |
+		      VIDEO_DIP_ENABLE_SPD | VIDEO_DIP_ENABLE_GCP);
+}
+
+static void cpt_write_infoframe(struct drm_encoder *encoder,
+				enum hdmi_infoframe_type type,
+				const void *frame, ssize_t len)
+{
+	const uint32_t *data = frame;
+	struct drm_device *dev = encoder->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
+	i915_reg_t reg = TVIDEO_DIP_CTL(intel_crtc->pipe);
+	u32 val = I915_READ(reg);
+	int i;
+
+	WARN(!(val & VIDEO_DIP_ENABLE), "Writing DIP with CTL reg disabled\n");
+
+	val &= ~(VIDEO_DIP_SELECT_MASK | 0xf); /* clear DIP data offset */
+	val |= g4x_infoframe_index(type);
+
+	/* The DIP control register spec says that we need to update the AVI
+	 * infoframe without clearing its enable bit */
+	if (type != HDMI_INFOFRAME_TYPE_AVI)
+		val &= ~g4x_infoframe_enable(type);
+
+	I915_WRITE(reg, val);
+
+	mmiowb();
+	for (i = 0; i < len; i += 4) {
+		I915_WRITE(TVIDEO_DIP_DATA(intel_crtc->pipe), *data);
+		data++;
+	}
+	/* Write every possible data byte to force correct ECC calculation. */
+	for (; i < VIDEO_DIP_DATA_SIZE; i += 4)
+		I915_WRITE(TVIDEO_DIP_DATA(intel_crtc->pipe), 0);
+	mmiowb();
+
+	val |= g4x_infoframe_enable(type);
+	val &= ~VIDEO_DIP_FREQ_MASK;
+	val |= VIDEO_DIP_FREQ_VSYNC;
+
+	I915_WRITE(reg, val);
+	POSTING_READ(reg);
+}
+
+static bool cpt_infoframe_enabled(struct drm_encoder *encoder,
+				  const struct intel_crtc_state *pipe_config)
+{
+	struct drm_i915_private *dev_priv = to_i915(encoder->dev);
+	enum pipe pipe = to_intel_crtc(pipe_config->base.crtc)->pipe;
+	u32 val = I915_READ(TVIDEO_DIP_CTL(pipe));
+
+	if ((val & VIDEO_DIP_ENABLE) == 0)
+		return false;
+
+	return val & (VIDEO_DIP_ENABLE_AVI |
+		      VIDEO_DIP_ENABLE_VENDOR | VIDEO_DIP_ENABLE_GAMUT |
+		      VIDEO_DIP_ENABLE_SPD | VIDEO_DIP_ENABLE_GCP);
+}
+
+static void vlv_write_infoframe(struct drm_encoder *encoder,
+				enum hdmi_infoframe_type type,
+				const void *frame, ssize_t len)
+{
+	const uint32_t *data = frame;
+	struct drm_device *dev = encoder->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
+	i915_reg_t reg = VLV_TVIDEO_DIP_CTL(intel_crtc->pipe);
+	u32 val = I915_READ(reg);
+	int i;
+
+	WARN(!(val & VIDEO_DIP_ENABLE), "Writing DIP with CTL reg disabled\n");
+
+	val &= ~(VIDEO_DIP_SELECT_MASK | 0xf); /* clear DIP data offset */
+	val |= g4x_infoframe_index(type);
+
+	val &= ~g4x_infoframe_enable(type);
+
+	I915_WRITE(reg, val);
+
+	mmiowb();
+	for (i = 0; i < len; i += 4) {
+		I915_WRITE(VLV_TVIDEO_DIP_DATA(intel_crtc->pipe), *data);
+		data++;
+	}
+	/* Write every possible data byte to force correct ECC calculation. */
+	for (; i < VIDEO_DIP_DATA_SIZE; i += 4)
+		I915_WRITE(VLV_TVIDEO_DIP_DATA(intel_crtc->pipe), 0);
+	mmiowb();
+
+	val |= g4x_infoframe_enable(type);
+	val &= ~VIDEO_DIP_FREQ_MASK;
+	val |= VIDEO_DIP_FREQ_VSYNC;
+
+	I915_WRITE(reg, val);
+	POSTING_READ(reg);
+}
+
+static bool vlv_infoframe_enabled(struct drm_encoder *encoder,
+				  const struct intel_crtc_state *pipe_config)
+{
+	struct drm_i915_private *dev_priv = to_i915(encoder->dev);
+	struct intel_digital_port *intel_dig_port = enc_to_dig_port(encoder);
+	enum pipe pipe = to_intel_crtc(pipe_config->base.crtc)->pipe;
+	u32 val = I915_READ(VLV_TVIDEO_DIP_CTL(pipe));
+
+	if ((val & VIDEO_DIP_ENABLE) == 0)
+		return false;
+
+	if ((val & VIDEO_DIP_PORT_MASK) != VIDEO_DIP_PORT(intel_dig_port->port))
+		return false;
+
+	return val & (VIDEO_DIP_ENABLE_AVI |
+		      VIDEO_DIP_ENABLE_VENDOR | VIDEO_DIP_ENABLE_GAMUT |
+		      VIDEO_DIP_ENABLE_SPD | VIDEO_DIP_ENABLE_GCP);
+}
+
+static void hsw_write_infoframe(struct drm_encoder *encoder,
+				enum hdmi_infoframe_type type,
+				const void *frame, ssize_t len)
+{
+	const uint32_t *data = frame;
+	struct drm_device *dev = encoder->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
+	enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
+	i915_reg_t ctl_reg = HSW_TVIDEO_DIP_CTL(cpu_transcoder);
+	i915_reg_t data_reg;
+	int i;
+	u32 val = I915_READ(ctl_reg);
+
+	data_reg = hsw_dip_data_reg(dev_priv, cpu_transcoder, type, 0);
+
+	val &= ~hsw_infoframe_enable(type);
+	I915_WRITE(ctl_reg, val);
+
+	mmiowb();
+	for (i = 0; i < len; i += 4) {
+		I915_WRITE(hsw_dip_data_reg(dev_priv, cpu_transcoder,
+					    type, i >> 2), *data);
+		data++;
+	}
+	/* Write every possible data byte to force correct ECC calculation. */
+	for (; i < VIDEO_DIP_DATA_SIZE; i += 4)
+		I915_WRITE(hsw_dip_data_reg(dev_priv, cpu_transcoder,
+					    type, i >> 2), 0);
+	mmiowb();
+
+	val |= hsw_infoframe_enable(type);
+	I915_WRITE(ctl_reg, val);
+	POSTING_READ(ctl_reg);
+}
+
+static bool hsw_infoframe_enabled(struct drm_encoder *encoder,
+				  const struct intel_crtc_state *pipe_config)
+{
+	struct drm_i915_private *dev_priv = to_i915(encoder->dev);
+	u32 val = I915_READ(HSW_TVIDEO_DIP_CTL(pipe_config->cpu_transcoder));
+
+	return val & (VIDEO_DIP_ENABLE_VSC_HSW | VIDEO_DIP_ENABLE_AVI_HSW |
+		      VIDEO_DIP_ENABLE_GCP_HSW | VIDEO_DIP_ENABLE_VS_HSW |
+		      VIDEO_DIP_ENABLE_GMP_HSW | VIDEO_DIP_ENABLE_SPD_HSW);
+}
+
+/*
+ * The data we write to the DIP data buffer registers is 1 byte bigger than the
+ * HDMI infoframe size because of an ECC/reserved byte at position 3 (starting
+ * at 0). It's also a byte used by DisplayPort so the same DIP registers can be
+ * used for both technologies.
+ *
+ * DW0: Reserved/ECC/DP | HB2 | HB1 | HB0
+ * DW1:       DB3       | DB2 | DB1 | DB0
+ * DW2:       DB7       | DB6 | DB5 | DB4
+ * DW3: ...
+ *
+ * (HB is Header Byte, DB is Data Byte)
+ *
+ * The hdmi pack() functions don't know about that hardware specific hole so we
+ * trick them by giving an offset into the buffer and moving back the header
+ * bytes by one.
+ */
+static void intel_write_infoframe(struct drm_encoder *encoder,
+				  union hdmi_infoframe *frame)
+{
+	struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
+	uint8_t buffer[VIDEO_DIP_DATA_SIZE];
+	ssize_t len;
+
+	/* see comment above for the reason for this offset */
+	len = hdmi_infoframe_pack(frame, buffer + 1, sizeof(buffer) - 1);
+	if (len < 0)
+		return;
+
+	/* Insert the 'hole' (see big comment above) at position 3 */
+	buffer[0] = buffer[1];
+	buffer[1] = buffer[2];
+	buffer[2] = buffer[3];
+	buffer[3] = 0;
+	len++;
+
+	intel_hdmi->write_infoframe(encoder, frame->any.type, buffer, len);
+}
+
+static void intel_hdmi_set_avi_infoframe(struct drm_encoder *encoder,
+					 const struct drm_display_mode *adjusted_mode)
+{
+	struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
+	struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
+	union hdmi_infoframe frame;
+	int ret;
+
+	ret = drm_hdmi_avi_infoframe_from_display_mode(&frame.avi,
+						       adjusted_mode);
+	if (ret < 0) {
+		DRM_ERROR("couldn't fill AVI infoframe\n");
+		return;
+	}
+
+	if (intel_hdmi->rgb_quant_range_selectable) {
+		if (intel_crtc->config->limited_color_range)
+			frame.avi.quantization_range =
+				HDMI_QUANTIZATION_RANGE_LIMITED;
+		else
+			frame.avi.quantization_range =
+				HDMI_QUANTIZATION_RANGE_FULL;
+	}
+
+	intel_write_infoframe(encoder, &frame);
+}
+
+static void intel_hdmi_set_spd_infoframe(struct drm_encoder *encoder)
+{
+	union hdmi_infoframe frame;
+	int ret;
+
+	ret = hdmi_spd_infoframe_init(&frame.spd, "Intel", "Integrated gfx");
+	if (ret < 0) {
+		DRM_ERROR("couldn't fill SPD infoframe\n");
+		return;
+	}
+
+	frame.spd.sdi = HDMI_SPD_SDI_PC;
+
+	intel_write_infoframe(encoder, &frame);
+}
+
+static void
+intel_hdmi_set_hdmi_infoframe(struct drm_encoder *encoder,
+			      const struct drm_display_mode *adjusted_mode)
+{
+	union hdmi_infoframe frame;
+	int ret;
+
+	ret = drm_hdmi_vendor_infoframe_from_display_mode(&frame.vendor.hdmi,
+							  adjusted_mode);
+	if (ret < 0)
+		return;
+
+	intel_write_infoframe(encoder, &frame);
+}
+
+static void g4x_set_infoframes(struct drm_encoder *encoder,
+			       bool enable,
+			       const struct drm_display_mode *adjusted_mode)
+{
+	struct drm_i915_private *dev_priv = encoder->dev->dev_private;
+	struct intel_digital_port *intel_dig_port = enc_to_dig_port(encoder);
+	struct intel_hdmi *intel_hdmi = &intel_dig_port->hdmi;
+	i915_reg_t reg = VIDEO_DIP_CTL;
+	u32 val = I915_READ(reg);
+	u32 port = VIDEO_DIP_PORT(intel_dig_port->port);
+
+	assert_hdmi_port_disabled(intel_hdmi);
+
+	/* If the registers were not initialized yet, they might be zeroes,
+	 * which means we're selecting the AVI DIP and we're setting its
+	 * frequency to once. This seems to really confuse the HW and make
+	 * things stop working (the register spec says the AVI always needs to
+	 * be sent every VSync). So here we avoid writing to the register more
+	 * than we need and also explicitly select the AVI DIP and explicitly
+	 * set its frequency to every VSync. Avoiding to write it twice seems to
+	 * be enough to solve the problem, but being defensive shouldn't hurt us
+	 * either. */
+	val |= VIDEO_DIP_SELECT_AVI | VIDEO_DIP_FREQ_VSYNC;
+
+	if (!enable) {
+		if (!(val & VIDEO_DIP_ENABLE))
+			return;
+		if (port != (val & VIDEO_DIP_PORT_MASK)) {
+			DRM_DEBUG_KMS("video DIP still enabled on port %c\n",
+				      (val & VIDEO_DIP_PORT_MASK) >> 29);
+			return;
+		}
+		val &= ~(VIDEO_DIP_ENABLE | VIDEO_DIP_ENABLE_AVI |
+			 VIDEO_DIP_ENABLE_VENDOR | VIDEO_DIP_ENABLE_SPD);
+		I915_WRITE(reg, val);
+		POSTING_READ(reg);
+		return;
+	}
+
+	if (port != (val & VIDEO_DIP_PORT_MASK)) {
+		if (val & VIDEO_DIP_ENABLE) {
+			DRM_DEBUG_KMS("video DIP already enabled on port %c\n",
+				      (val & VIDEO_DIP_PORT_MASK) >> 29);
+			return;
+		}
+		val &= ~VIDEO_DIP_PORT_MASK;
+		val |= port;
+	}
+
+	val |= VIDEO_DIP_ENABLE;
+	val &= ~(VIDEO_DIP_ENABLE_AVI |
+		 VIDEO_DIP_ENABLE_VENDOR | VIDEO_DIP_ENABLE_SPD);
+
+	I915_WRITE(reg, val);
+	POSTING_READ(reg);
+
+	intel_hdmi_set_avi_infoframe(encoder, adjusted_mode);
+	intel_hdmi_set_spd_infoframe(encoder);
+	intel_hdmi_set_hdmi_infoframe(encoder, adjusted_mode);
+}
+
+static bool hdmi_sink_is_deep_color(struct drm_encoder *encoder)
+{
+	struct drm_device *dev = encoder->dev;
+	struct drm_connector *connector;
+
+	WARN_ON(!drm_modeset_is_locked(&dev->mode_config.connection_mutex));
+
+	/*
+	 * HDMI cloning is only supported on g4x which doesn't
+	 * support deep color or GCP infoframes anyway so no
+	 * need to worry about multiple HDMI sinks here.
+	 */
+	list_for_each_entry(connector, &dev->mode_config.connector_list, head)
+		if (connector->encoder == encoder)
+			return connector->display_info.bpc > 8;
+
+	return false;
+}
+
+/*
+ * Determine if default_phase=1 can be indicated in the GCP infoframe.
+ *
+ * From HDMI specification 1.4a:
+ * - The first pixel of each Video Data Period shall always have a pixel packing phase of 0
+ * - The first pixel following each Video Data Period shall have a pixel packing phase of 0
+ * - The PP bits shall be constant for all GCPs and will be equal to the last packing phase
+ * - The first pixel following every transition of HSYNC or VSYNC shall have a pixel packing
+ *   phase of 0
+ */
+static bool gcp_default_phase_possible(int pipe_bpp,
+				       const struct drm_display_mode *mode)
+{
+	unsigned int pixels_per_group;
+
+	switch (pipe_bpp) {
+	case 30:
+		/* 4 pixels in 5 clocks */
+		pixels_per_group = 4;
+		break;
+	case 36:
+		/* 2 pixels in 3 clocks */
+		pixels_per_group = 2;
+		break;
+	case 48:
+		/* 1 pixel in 2 clocks */
+		pixels_per_group = 1;
+		break;
+	default:
+		/* phase information not relevant for 8bpc */
+		return false;
+	}
+
+	return mode->crtc_hdisplay % pixels_per_group == 0 &&
+		mode->crtc_htotal % pixels_per_group == 0 &&
+		mode->crtc_hblank_start % pixels_per_group == 0 &&
+		mode->crtc_hblank_end % pixels_per_group == 0 &&
+		mode->crtc_hsync_start % pixels_per_group == 0 &&
+		mode->crtc_hsync_end % pixels_per_group == 0 &&
+		((mode->flags & DRM_MODE_FLAG_INTERLACE) == 0 ||
+		 mode->crtc_htotal/2 % pixels_per_group == 0);
+}
+
+static bool intel_hdmi_set_gcp_infoframe(struct drm_encoder *encoder)
+{
+	struct drm_i915_private *dev_priv = encoder->dev->dev_private;
+	struct intel_crtc *crtc = to_intel_crtc(encoder->crtc);
+	i915_reg_t reg;
+	u32 val = 0;
+
+	if (HAS_DDI(dev_priv))
+		reg = HSW_TVIDEO_DIP_GCP(crtc->config->cpu_transcoder);
+	else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
+		reg = VLV_TVIDEO_DIP_GCP(crtc->pipe);
+	else if (HAS_PCH_SPLIT(dev_priv))
+		reg = TVIDEO_DIP_GCP(crtc->pipe);
+	else
+		return false;
+
+	/* Indicate color depth whenever the sink supports deep color */
+	if (hdmi_sink_is_deep_color(encoder))
+		val |= GCP_COLOR_INDICATION;
+
+	/* Enable default_phase whenever the display mode is suitably aligned */
+	if (gcp_default_phase_possible(crtc->config->pipe_bpp,
+				       &crtc->config->base.adjusted_mode))
+		val |= GCP_DEFAULT_PHASE_ENABLE;
+
+	I915_WRITE(reg, val);
+
+	return val != 0;
+}
+
+static void ibx_set_infoframes(struct drm_encoder *encoder,
+			       bool enable,
+			       const struct drm_display_mode *adjusted_mode)
+{
+	struct drm_i915_private *dev_priv = encoder->dev->dev_private;
+	struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
+	struct intel_digital_port *intel_dig_port = enc_to_dig_port(encoder);
+	struct intel_hdmi *intel_hdmi = &intel_dig_port->hdmi;
+	i915_reg_t reg = TVIDEO_DIP_CTL(intel_crtc->pipe);
+	u32 val = I915_READ(reg);
+	u32 port = VIDEO_DIP_PORT(intel_dig_port->port);
+
+	assert_hdmi_port_disabled(intel_hdmi);
+
+	/* See the big comment in g4x_set_infoframes() */
+	val |= VIDEO_DIP_SELECT_AVI | VIDEO_DIP_FREQ_VSYNC;
+
+	if (!enable) {
+		if (!(val & VIDEO_DIP_ENABLE))
+			return;
+		val &= ~(VIDEO_DIP_ENABLE | VIDEO_DIP_ENABLE_AVI |
+			 VIDEO_DIP_ENABLE_VENDOR | VIDEO_DIP_ENABLE_GAMUT |
+			 VIDEO_DIP_ENABLE_SPD | VIDEO_DIP_ENABLE_GCP);
+		I915_WRITE(reg, val);
+		POSTING_READ(reg);
+		return;
+	}
+
+	if (port != (val & VIDEO_DIP_PORT_MASK)) {
+		WARN(val & VIDEO_DIP_ENABLE,
+		     "DIP already enabled on port %c\n",
+		     (val & VIDEO_DIP_PORT_MASK) >> 29);
+		val &= ~VIDEO_DIP_PORT_MASK;
+		val |= port;
+	}
+
+	val |= VIDEO_DIP_ENABLE;
+	val &= ~(VIDEO_DIP_ENABLE_AVI |
+		 VIDEO_DIP_ENABLE_VENDOR | VIDEO_DIP_ENABLE_GAMUT |
+		 VIDEO_DIP_ENABLE_SPD | VIDEO_DIP_ENABLE_GCP);
+
+	if (intel_hdmi_set_gcp_infoframe(encoder))
+		val |= VIDEO_DIP_ENABLE_GCP;
+
+	I915_WRITE(reg, val);
+	POSTING_READ(reg);
+
+	intel_hdmi_set_avi_infoframe(encoder, adjusted_mode);
+	intel_hdmi_set_spd_infoframe(encoder);
+	intel_hdmi_set_hdmi_infoframe(encoder, adjusted_mode);
+}
+
+static void cpt_set_infoframes(struct drm_encoder *encoder,
+			       bool enable,
+			       const struct drm_display_mode *adjusted_mode)
+{
+	struct drm_i915_private *dev_priv = encoder->dev->dev_private;
+	struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
+	struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
+	i915_reg_t reg = TVIDEO_DIP_CTL(intel_crtc->pipe);
+	u32 val = I915_READ(reg);
+
+	assert_hdmi_port_disabled(intel_hdmi);
+
+	/* See the big comment in g4x_set_infoframes() */
+	val |= VIDEO_DIP_SELECT_AVI | VIDEO_DIP_FREQ_VSYNC;
+
+	if (!enable) {
+		if (!(val & VIDEO_DIP_ENABLE))
+			return;
+		val &= ~(VIDEO_DIP_ENABLE | VIDEO_DIP_ENABLE_AVI |
+			 VIDEO_DIP_ENABLE_VENDOR | VIDEO_DIP_ENABLE_GAMUT |
+			 VIDEO_DIP_ENABLE_SPD | VIDEO_DIP_ENABLE_GCP);
+		I915_WRITE(reg, val);
+		POSTING_READ(reg);
+		return;
+	}
+
+	/* Set both together, unset both together: see the spec. */
+	val |= VIDEO_DIP_ENABLE | VIDEO_DIP_ENABLE_AVI;
+	val &= ~(VIDEO_DIP_ENABLE_VENDOR | VIDEO_DIP_ENABLE_GAMUT |
+		 VIDEO_DIP_ENABLE_SPD | VIDEO_DIP_ENABLE_GCP);
+
+	if (intel_hdmi_set_gcp_infoframe(encoder))
+		val |= VIDEO_DIP_ENABLE_GCP;
+
+	I915_WRITE(reg, val);
+	POSTING_READ(reg);
+
+	intel_hdmi_set_avi_infoframe(encoder, adjusted_mode);
+	intel_hdmi_set_spd_infoframe(encoder);
+	intel_hdmi_set_hdmi_infoframe(encoder, adjusted_mode);
+}
+
+static void vlv_set_infoframes(struct drm_encoder *encoder,
+			       bool enable,
+			       const struct drm_display_mode *adjusted_mode)
+{
+	struct drm_i915_private *dev_priv = encoder->dev->dev_private;
+	struct intel_digital_port *intel_dig_port = enc_to_dig_port(encoder);
+	struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
+	struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
+	i915_reg_t reg = VLV_TVIDEO_DIP_CTL(intel_crtc->pipe);
+	u32 val = I915_READ(reg);
+	u32 port = VIDEO_DIP_PORT(intel_dig_port->port);
+
+	assert_hdmi_port_disabled(intel_hdmi);
+
+	/* See the big comment in g4x_set_infoframes() */
+	val |= VIDEO_DIP_SELECT_AVI | VIDEO_DIP_FREQ_VSYNC;
+
+	if (!enable) {
+		if (!(val & VIDEO_DIP_ENABLE))
+			return;
+		val &= ~(VIDEO_DIP_ENABLE | VIDEO_DIP_ENABLE_AVI |
+			 VIDEO_DIP_ENABLE_VENDOR | VIDEO_DIP_ENABLE_GAMUT |
+			 VIDEO_DIP_ENABLE_SPD | VIDEO_DIP_ENABLE_GCP);
+		I915_WRITE(reg, val);
+		POSTING_READ(reg);
+		return;
+	}
+
+	if (port != (val & VIDEO_DIP_PORT_MASK)) {
+		WARN(val & VIDEO_DIP_ENABLE,
+		     "DIP already enabled on port %c\n",
+		     (val & VIDEO_DIP_PORT_MASK) >> 29);
+		val &= ~VIDEO_DIP_PORT_MASK;
+		val |= port;
+	}
+
+	val |= VIDEO_DIP_ENABLE;
+	val &= ~(VIDEO_DIP_ENABLE_AVI |
+		 VIDEO_DIP_ENABLE_VENDOR | VIDEO_DIP_ENABLE_GAMUT |
+		 VIDEO_DIP_ENABLE_SPD | VIDEO_DIP_ENABLE_GCP);
+
+	if (intel_hdmi_set_gcp_infoframe(encoder))
+		val |= VIDEO_DIP_ENABLE_GCP;
+
+	I915_WRITE(reg, val);
+	POSTING_READ(reg);
+
+	intel_hdmi_set_avi_infoframe(encoder, adjusted_mode);
+	intel_hdmi_set_spd_infoframe(encoder);
+	intel_hdmi_set_hdmi_infoframe(encoder, adjusted_mode);
+}
+
+static void hsw_set_infoframes(struct drm_encoder *encoder,
+			       bool enable,
+			       const struct drm_display_mode *adjusted_mode)
+{
+	struct drm_i915_private *dev_priv = encoder->dev->dev_private;
+	struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
+	struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
+	i915_reg_t reg = HSW_TVIDEO_DIP_CTL(intel_crtc->config->cpu_transcoder);
+	u32 val = I915_READ(reg);
+
+	assert_hdmi_port_disabled(intel_hdmi);
+
+	val &= ~(VIDEO_DIP_ENABLE_VSC_HSW | VIDEO_DIP_ENABLE_AVI_HSW |
+		 VIDEO_DIP_ENABLE_GCP_HSW | VIDEO_DIP_ENABLE_VS_HSW |
+		 VIDEO_DIP_ENABLE_GMP_HSW | VIDEO_DIP_ENABLE_SPD_HSW);
+
+	if (!enable) {
+		I915_WRITE(reg, val);
+		POSTING_READ(reg);
+		return;
+	}
+
+	if (intel_hdmi_set_gcp_infoframe(encoder))
+		val |= VIDEO_DIP_ENABLE_GCP_HSW;
+
+	I915_WRITE(reg, val);
+	POSTING_READ(reg);
+
+	intel_hdmi_set_avi_infoframe(encoder, adjusted_mode);
+	intel_hdmi_set_spd_infoframe(encoder);
+	intel_hdmi_set_hdmi_infoframe(encoder, adjusted_mode);
+}
+
+void intel_dp_dual_mode_set_tmds_output(struct intel_hdmi *hdmi, bool enable)
+{
+	struct drm_i915_private *dev_priv = to_i915(intel_hdmi_to_dev(hdmi));
+	struct i2c_adapter *adapter =
+		intel_gmbus_get_adapter(dev_priv, hdmi->ddc_bus);
+
+	if (hdmi->dp_dual_mode.type < DRM_DP_DUAL_MODE_TYPE2_DVI)
+		return;
+
+	DRM_DEBUG_KMS("%s DP dual mode adaptor TMDS output\n",
+		      enable ? "Enabling" : "Disabling");
+
+	drm_dp_dual_mode_set_tmds_output(hdmi->dp_dual_mode.type,
+					 adapter, enable);
+}
+
+static void intel_hdmi_prepare(struct intel_encoder *encoder)
+{
+	struct drm_device *dev = encoder->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc);
+	struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&encoder->base);
+	const struct drm_display_mode *adjusted_mode = &crtc->config->base.adjusted_mode;
+	u32 hdmi_val;
+
+	intel_dp_dual_mode_set_tmds_output(intel_hdmi, true);
+
+	hdmi_val = SDVO_ENCODING_HDMI;
+	if (!HAS_PCH_SPLIT(dev) && crtc->config->limited_color_range)
+		hdmi_val |= HDMI_COLOR_RANGE_16_235;
+	if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC)
+		hdmi_val |= SDVO_VSYNC_ACTIVE_HIGH;
+	if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC)
+		hdmi_val |= SDVO_HSYNC_ACTIVE_HIGH;
+
+	if (crtc->config->pipe_bpp > 24)
+		hdmi_val |= HDMI_COLOR_FORMAT_12bpc;
+	else
+		hdmi_val |= SDVO_COLOR_FORMAT_8bpc;
+
+	if (crtc->config->has_hdmi_sink)
+		hdmi_val |= HDMI_MODE_SELECT_HDMI;
+
+	if (HAS_PCH_CPT(dev))
+		hdmi_val |= SDVO_PIPE_SEL_CPT(crtc->pipe);
+	else if (IS_CHERRYVIEW(dev))
+		hdmi_val |= SDVO_PIPE_SEL_CHV(crtc->pipe);
+	else
+		hdmi_val |= SDVO_PIPE_SEL(crtc->pipe);
+
+	I915_WRITE(intel_hdmi->hdmi_reg, hdmi_val);
+	POSTING_READ(intel_hdmi->hdmi_reg);
+}
+
+static bool intel_hdmi_get_hw_state(struct intel_encoder *encoder,
+				    enum pipe *pipe)
+{
+	struct drm_device *dev = encoder->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&encoder->base);
+	enum intel_display_power_domain power_domain;
+	u32 tmp;
+	bool ret;
+
+	power_domain = intel_display_port_power_domain(encoder);
+	if (!intel_display_power_get_if_enabled(dev_priv, power_domain))
+		return false;
+
+	ret = false;
+
+	tmp = I915_READ(intel_hdmi->hdmi_reg);
+
+	if (!(tmp & SDVO_ENABLE))
+		goto out;
+
+	if (HAS_PCH_CPT(dev))
+		*pipe = PORT_TO_PIPE_CPT(tmp);
+	else if (IS_CHERRYVIEW(dev))
+		*pipe = SDVO_PORT_TO_PIPE_CHV(tmp);
+	else
+		*pipe = PORT_TO_PIPE(tmp);
+
+	ret = true;
+
+out:
+	intel_display_power_put(dev_priv, power_domain);
+
+	return ret;
+}
+
+static void intel_hdmi_get_config(struct intel_encoder *encoder,
+				  struct intel_crtc_state *pipe_config)
+{
+	struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&encoder->base);
+	struct drm_device *dev = encoder->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	u32 tmp, flags = 0;
+	int dotclock;
+
+	tmp = I915_READ(intel_hdmi->hdmi_reg);
+
+	if (tmp & SDVO_HSYNC_ACTIVE_HIGH)
+		flags |= DRM_MODE_FLAG_PHSYNC;
+	else
+		flags |= DRM_MODE_FLAG_NHSYNC;
+
+	if (tmp & SDVO_VSYNC_ACTIVE_HIGH)
+		flags |= DRM_MODE_FLAG_PVSYNC;
+	else
+		flags |= DRM_MODE_FLAG_NVSYNC;
+
+	if (tmp & HDMI_MODE_SELECT_HDMI)
+		pipe_config->has_hdmi_sink = true;
+
+	if (intel_hdmi->infoframe_enabled(&encoder->base, pipe_config))
+		pipe_config->has_infoframe = true;
+
+	if (tmp & SDVO_AUDIO_ENABLE)
+		pipe_config->has_audio = true;
+
+	if (!HAS_PCH_SPLIT(dev) &&
+	    tmp & HDMI_COLOR_RANGE_16_235)
+		pipe_config->limited_color_range = true;
+
+	pipe_config->base.adjusted_mode.flags |= flags;
+
+	if ((tmp & SDVO_COLOR_FORMAT_MASK) == HDMI_COLOR_FORMAT_12bpc)
+		dotclock = pipe_config->port_clock * 2 / 3;
+	else
+		dotclock = pipe_config->port_clock;
+
+	if (pipe_config->pixel_multiplier)
+		dotclock /= pipe_config->pixel_multiplier;
+
+	pipe_config->base.adjusted_mode.crtc_clock = dotclock;
+
+	pipe_config->lane_count = 4;
+}
+
+static void intel_enable_hdmi_audio(struct intel_encoder *encoder)
+{
+	struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc);
+
+	WARN_ON(!crtc->config->has_hdmi_sink);
+	DRM_DEBUG_DRIVER("Enabling HDMI audio on pipe %c\n",
+			 pipe_name(crtc->pipe));
+	intel_audio_codec_enable(encoder);
+}
+
+static void g4x_enable_hdmi(struct intel_encoder *encoder)
+{
+	struct drm_device *dev = encoder->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc);
+	struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&encoder->base);
+	u32 temp;
+
+	temp = I915_READ(intel_hdmi->hdmi_reg);
+
+	temp |= SDVO_ENABLE;
+	if (crtc->config->has_audio)
+		temp |= SDVO_AUDIO_ENABLE;
+
+	I915_WRITE(intel_hdmi->hdmi_reg, temp);
+	POSTING_READ(intel_hdmi->hdmi_reg);
+
+	if (crtc->config->has_audio)
+		intel_enable_hdmi_audio(encoder);
+}
+
+static void ibx_enable_hdmi(struct intel_encoder *encoder)
+{
+	struct drm_device *dev = encoder->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc);
+	struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&encoder->base);
+	u32 temp;
+
+	temp = I915_READ(intel_hdmi->hdmi_reg);
+
+	temp |= SDVO_ENABLE;
+	if (crtc->config->has_audio)
+		temp |= SDVO_AUDIO_ENABLE;
+
+	/*
+	 * HW workaround, need to write this twice for issue
+	 * that may result in first write getting masked.
+	 */
+	I915_WRITE(intel_hdmi->hdmi_reg, temp);
+	POSTING_READ(intel_hdmi->hdmi_reg);
+	I915_WRITE(intel_hdmi->hdmi_reg, temp);
+	POSTING_READ(intel_hdmi->hdmi_reg);
+
+	/*
+	 * HW workaround, need to toggle enable bit off and on
+	 * for 12bpc with pixel repeat.
+	 *
+	 * FIXME: BSpec says this should be done at the end of
+	 * of the modeset sequence, so not sure if this isn't too soon.
+	 */
+	if (crtc->config->pipe_bpp > 24 &&
+	    crtc->config->pixel_multiplier > 1) {
+		I915_WRITE(intel_hdmi->hdmi_reg, temp & ~SDVO_ENABLE);
+		POSTING_READ(intel_hdmi->hdmi_reg);
+
+		/*
+		 * HW workaround, need to write this twice for issue
+		 * that may result in first write getting masked.
+		 */
+		I915_WRITE(intel_hdmi->hdmi_reg, temp);
+		POSTING_READ(intel_hdmi->hdmi_reg);
+		I915_WRITE(intel_hdmi->hdmi_reg, temp);
+		POSTING_READ(intel_hdmi->hdmi_reg);
+	}
+
+	if (crtc->config->has_audio)
+		intel_enable_hdmi_audio(encoder);
+}
+
+static void cpt_enable_hdmi(struct intel_encoder *encoder)
+{
+	struct drm_device *dev = encoder->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc);
+	struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&encoder->base);
+	enum pipe pipe = crtc->pipe;
+	u32 temp;
+
+	temp = I915_READ(intel_hdmi->hdmi_reg);
+
+	temp |= SDVO_ENABLE;
+	if (crtc->config->has_audio)
+		temp |= SDVO_AUDIO_ENABLE;
+
+	/*
+	 * WaEnableHDMI8bpcBefore12bpc:snb,ivb
+	 *
+	 * The procedure for 12bpc is as follows:
+	 * 1. disable HDMI clock gating
+	 * 2. enable HDMI with 8bpc
+	 * 3. enable HDMI with 12bpc
+	 * 4. enable HDMI clock gating
+	 */
+
+	if (crtc->config->pipe_bpp > 24) {
+		I915_WRITE(TRANS_CHICKEN1(pipe),
+			   I915_READ(TRANS_CHICKEN1(pipe)) |
+			   TRANS_CHICKEN1_HDMIUNIT_GC_DISABLE);
+
+		temp &= ~SDVO_COLOR_FORMAT_MASK;
+		temp |= SDVO_COLOR_FORMAT_8bpc;
+	}
+
+	I915_WRITE(intel_hdmi->hdmi_reg, temp);
+	POSTING_READ(intel_hdmi->hdmi_reg);
+
+	if (crtc->config->pipe_bpp > 24) {
+		temp &= ~SDVO_COLOR_FORMAT_MASK;
+		temp |= HDMI_COLOR_FORMAT_12bpc;
+
+		I915_WRITE(intel_hdmi->hdmi_reg, temp);
+		POSTING_READ(intel_hdmi->hdmi_reg);
+
+		I915_WRITE(TRANS_CHICKEN1(pipe),
+			   I915_READ(TRANS_CHICKEN1(pipe)) &
+			   ~TRANS_CHICKEN1_HDMIUNIT_GC_DISABLE);
+	}
+
+	if (crtc->config->has_audio)
+		intel_enable_hdmi_audio(encoder);
+}
+
+static void vlv_enable_hdmi(struct intel_encoder *encoder)
+{
+}
+
+static void intel_disable_hdmi(struct intel_encoder *encoder)
+{
+	struct drm_device *dev = encoder->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&encoder->base);
+	struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc);
+	u32 temp;
+
+	temp = I915_READ(intel_hdmi->hdmi_reg);
+
+	temp &= ~(SDVO_ENABLE | SDVO_AUDIO_ENABLE);
+	I915_WRITE(intel_hdmi->hdmi_reg, temp);
+	POSTING_READ(intel_hdmi->hdmi_reg);
+
+	/*
+	 * HW workaround for IBX, we need to move the port
+	 * to transcoder A after disabling it to allow the
+	 * matching DP port to be enabled on transcoder A.
+	 */
+	if (HAS_PCH_IBX(dev) && crtc->pipe == PIPE_B) {
+		/*
+		 * We get CPU/PCH FIFO underruns on the other pipe when
+		 * doing the workaround. Sweep them under the rug.
+		 */
+		intel_set_cpu_fifo_underrun_reporting(dev_priv, PIPE_A, false);
+		intel_set_pch_fifo_underrun_reporting(dev_priv, PIPE_A, false);
+
+		temp &= ~SDVO_PIPE_B_SELECT;
+		temp |= SDVO_ENABLE;
+		/*
+		 * HW workaround, need to write this twice for issue
+		 * that may result in first write getting masked.
+		 */
+		I915_WRITE(intel_hdmi->hdmi_reg, temp);
+		POSTING_READ(intel_hdmi->hdmi_reg);
+		I915_WRITE(intel_hdmi->hdmi_reg, temp);
+		POSTING_READ(intel_hdmi->hdmi_reg);
+
+		temp &= ~SDVO_ENABLE;
+		I915_WRITE(intel_hdmi->hdmi_reg, temp);
+		POSTING_READ(intel_hdmi->hdmi_reg);
+
+		intel_wait_for_vblank_if_active(dev_priv->dev, PIPE_A);
+		intel_set_cpu_fifo_underrun_reporting(dev_priv, PIPE_A, true);
+		intel_set_pch_fifo_underrun_reporting(dev_priv, PIPE_A, true);
+	}
+
+	intel_hdmi->set_infoframes(&encoder->base, false, NULL);
+
+	intel_dp_dual_mode_set_tmds_output(intel_hdmi, false);
+}
+
+static void g4x_disable_hdmi(struct intel_encoder *encoder)
+{
+	struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc);
+
+	if (crtc->config->has_audio)
+		intel_audio_codec_disable(encoder);
+
+	intel_disable_hdmi(encoder);
+}
+
+static void pch_disable_hdmi(struct intel_encoder *encoder)
+{
+	struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc);
+
+	if (crtc->config->has_audio)
+		intel_audio_codec_disable(encoder);
+}
+
+static void pch_post_disable_hdmi(struct intel_encoder *encoder)
+{
+	intel_disable_hdmi(encoder);
+}
+
+static int intel_hdmi_source_max_tmds_clock(struct drm_i915_private *dev_priv)
+{
+	if (IS_G4X(dev_priv))
+		return 165000;
+	else if (IS_HASWELL(dev_priv) || INTEL_INFO(dev_priv)->gen >= 8)
+		return 300000;
+	else
+		return 225000;
+}
+
+static int hdmi_port_clock_limit(struct intel_hdmi *hdmi,
+				 bool respect_downstream_limits)
+{
+	struct drm_device *dev = intel_hdmi_to_dev(hdmi);
+	int max_tmds_clock = intel_hdmi_source_max_tmds_clock(to_i915(dev));
+
+	if (respect_downstream_limits) {
+		if (hdmi->dp_dual_mode.max_tmds_clock)
+			max_tmds_clock = min(max_tmds_clock,
+					     hdmi->dp_dual_mode.max_tmds_clock);
+		if (!hdmi->has_hdmi_sink)
+			max_tmds_clock = min(max_tmds_clock, 165000);
+	}
+
+	return max_tmds_clock;
+}
+
+static enum drm_mode_status
+hdmi_port_clock_valid(struct intel_hdmi *hdmi,
+		      int clock, bool respect_downstream_limits)
+{
+	struct drm_device *dev = intel_hdmi_to_dev(hdmi);
+
+	if (clock < 25000)
+		return MODE_CLOCK_LOW;
+	if (clock > hdmi_port_clock_limit(hdmi, respect_downstream_limits))
+		return MODE_CLOCK_HIGH;
+
+	/* BXT DPLL can't generate 223-240 MHz */
+	if (IS_BROXTON(dev) && clock > 223333 && clock < 240000)
+		return MODE_CLOCK_RANGE;
+
+	/* CHV DPLL can't generate 216-240 MHz */
+	if (IS_CHERRYVIEW(dev) && clock > 216000 && clock < 240000)
+		return MODE_CLOCK_RANGE;
+
+	return MODE_OK;
+}
+
+static enum drm_mode_status
+intel_hdmi_mode_valid(struct drm_connector *connector,
+		      struct drm_display_mode *mode)
+{
+	struct intel_hdmi *hdmi = intel_attached_hdmi(connector);
+	struct drm_device *dev = intel_hdmi_to_dev(hdmi);
+	enum drm_mode_status status;
+	int clock;
+	int max_dotclk = to_i915(connector->dev)->max_dotclk_freq;
+
+	if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
+		return MODE_NO_DBLESCAN;
+
+	clock = mode->clock;
+
+	if ((mode->flags & DRM_MODE_FLAG_3D_MASK) == DRM_MODE_FLAG_3D_FRAME_PACKING)
+		clock *= 2;
+
+	if (clock > max_dotclk)
+		return MODE_CLOCK_HIGH;
+
+	if (mode->flags & DRM_MODE_FLAG_DBLCLK)
+		clock *= 2;
+
+	/* check if we can do 8bpc */
+	status = hdmi_port_clock_valid(hdmi, clock, true);
+
+	/* if we can't do 8bpc we may still be able to do 12bpc */
+	if (!HAS_GMCH_DISPLAY(dev) && status != MODE_OK)
+		status = hdmi_port_clock_valid(hdmi, clock * 3 / 2, true);
+
+	return status;
+}
+
+static bool hdmi_12bpc_possible(struct intel_crtc_state *crtc_state)
+{
+	struct drm_device *dev = crtc_state->base.crtc->dev;
+	struct drm_atomic_state *state;
+	struct intel_encoder *encoder;
+	struct drm_connector *connector;
+	struct drm_connector_state *connector_state;
+	int count = 0, count_hdmi = 0;
+	int i;
+
+	if (HAS_GMCH_DISPLAY(dev))
+		return false;
+
+	state = crtc_state->base.state;
+
+	for_each_connector_in_state(state, connector, connector_state, i) {
+		if (connector_state->crtc != crtc_state->base.crtc)
+			continue;
+
+		encoder = to_intel_encoder(connector_state->best_encoder);
+
+		count_hdmi += encoder->type == INTEL_OUTPUT_HDMI;
+		count++;
+	}
+
+	/*
+	 * HDMI 12bpc affects the clocks, so it's only possible
+	 * when not cloning with other encoder types.
+	 */
+	return count_hdmi > 0 && count_hdmi == count;
+}
+
+bool intel_hdmi_compute_config(struct intel_encoder *encoder,
+			       struct intel_crtc_state *pipe_config)
+{
+	struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&encoder->base);
+	struct drm_device *dev = encoder->base.dev;
+	struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
+	int clock_8bpc = pipe_config->base.adjusted_mode.crtc_clock;
+	int clock_12bpc = clock_8bpc * 3 / 2;
+	int desired_bpp;
+
+	pipe_config->has_hdmi_sink = intel_hdmi->has_hdmi_sink;
+
+	if (pipe_config->has_hdmi_sink)
+		pipe_config->has_infoframe = true;
+
+	if (intel_hdmi->color_range_auto) {
+		/* See CEA-861-E - 5.1 Default Encoding Parameters */
+		pipe_config->limited_color_range =
+			pipe_config->has_hdmi_sink &&
+			drm_match_cea_mode(adjusted_mode) > 1;
+	} else {
+		pipe_config->limited_color_range =
+			intel_hdmi->limited_color_range;
+	}
+
+	if (adjusted_mode->flags & DRM_MODE_FLAG_DBLCLK) {
+		pipe_config->pixel_multiplier = 2;
+		clock_8bpc *= 2;
+		clock_12bpc *= 2;
+	}
+
+	if (HAS_PCH_SPLIT(dev) && !HAS_DDI(dev))
+		pipe_config->has_pch_encoder = true;
+
+	if (pipe_config->has_hdmi_sink && intel_hdmi->has_audio)
+		pipe_config->has_audio = true;
+
+	/*
+	 * HDMI is either 12 or 8, so if the display lets 10bpc sneak
+	 * through, clamp it down. Note that g4x/vlv don't support 12bpc hdmi
+	 * outputs. We also need to check that the higher clock still fits
+	 * within limits.
+	 */
+	if (pipe_config->pipe_bpp > 8*3 && pipe_config->has_hdmi_sink &&
+	    hdmi_port_clock_valid(intel_hdmi, clock_12bpc, true) == MODE_OK &&
+	    hdmi_12bpc_possible(pipe_config)) {
+		DRM_DEBUG_KMS("picking bpc to 12 for HDMI output\n");
+		desired_bpp = 12*3;
+
+		/* Need to adjust the port link by 1.5x for 12bpc. */
+		pipe_config->port_clock = clock_12bpc;
+	} else {
+		DRM_DEBUG_KMS("picking bpc to 8 for HDMI output\n");
+		desired_bpp = 8*3;
+
+		pipe_config->port_clock = clock_8bpc;
+	}
+
+	if (!pipe_config->bw_constrained) {
+		DRM_DEBUG_KMS("forcing pipe bpc to %i for HDMI\n", desired_bpp);
+		pipe_config->pipe_bpp = desired_bpp;
+	}
+
+	if (hdmi_port_clock_valid(intel_hdmi, pipe_config->port_clock,
+				  false) != MODE_OK) {
+		DRM_DEBUG_KMS("unsupported HDMI clock, rejecting mode\n");
+		return false;
+	}
+
+	/* Set user selected PAR to incoming mode's member */
+	adjusted_mode->picture_aspect_ratio = intel_hdmi->aspect_ratio;
+
+	pipe_config->lane_count = 4;
+
+	return true;
+}
+
+static void
+intel_hdmi_unset_edid(struct drm_connector *connector)
+{
+	struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector);
+
+	intel_hdmi->has_hdmi_sink = false;
+	intel_hdmi->has_audio = false;
+	intel_hdmi->rgb_quant_range_selectable = false;
+
+	intel_hdmi->dp_dual_mode.type = DRM_DP_DUAL_MODE_NONE;
+	intel_hdmi->dp_dual_mode.max_tmds_clock = 0;
+
+	kfree(to_intel_connector(connector)->detect_edid);
+	to_intel_connector(connector)->detect_edid = NULL;
+}
+
+static void
+intel_hdmi_dp_dual_mode_detect(struct drm_connector *connector, bool has_edid)
+{
+	struct drm_i915_private *dev_priv = to_i915(connector->dev);
+	struct intel_hdmi *hdmi = intel_attached_hdmi(connector);
+	enum port port = hdmi_to_dig_port(hdmi)->port;
+	struct i2c_adapter *adapter =
+		intel_gmbus_get_adapter(dev_priv, hdmi->ddc_bus);
+	enum drm_dp_dual_mode_type type = drm_dp_dual_mode_detect(adapter);
+
+	/*
+	 * Type 1 DVI adaptors are not required to implement any
+	 * registers, so we can't always detect their presence.
+	 * Ideally we should be able to check the state of the
+	 * CONFIG1 pin, but no such luck on our hardware.
+	 *
+	 * The only method left to us is to check the VBT to see
+	 * if the port is a dual mode capable DP port. But let's
+	 * only do that when we sucesfully read the EDID, to avoid
+	 * confusing log messages about DP dual mode adaptors when
+	 * there's nothing connected to the port.
+	 */
+	if (type == DRM_DP_DUAL_MODE_UNKNOWN) {
+		if (has_edid &&
+		    intel_bios_is_port_dp_dual_mode(dev_priv, port)) {
+			DRM_DEBUG_KMS("Assuming DP dual mode adaptor presence based on VBT\n");
+			type = DRM_DP_DUAL_MODE_TYPE1_DVI;
+		} else {
+			type = DRM_DP_DUAL_MODE_NONE;
+		}
+	}
+
+	if (type == DRM_DP_DUAL_MODE_NONE)
+		return;
+
+	hdmi->dp_dual_mode.type = type;
+	hdmi->dp_dual_mode.max_tmds_clock =
+		drm_dp_dual_mode_max_tmds_clock(type, adapter);
+
+	DRM_DEBUG_KMS("DP dual mode adaptor (%s) detected (max TMDS clock: %d kHz)\n",
+		      drm_dp_get_dual_mode_type_name(type),
+		      hdmi->dp_dual_mode.max_tmds_clock);
+}
+
+static bool
+intel_hdmi_set_edid(struct drm_connector *connector, bool force)
+{
+	struct drm_i915_private *dev_priv = to_i915(connector->dev);
+	struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector);
+	struct edid *edid = NULL;
+	bool connected = false;
+
+	if (force) {
+		intel_display_power_get(dev_priv, POWER_DOMAIN_GMBUS);
+
+		edid = drm_get_edid(connector,
+				    intel_gmbus_get_adapter(dev_priv,
+				    intel_hdmi->ddc_bus));
+
+		intel_hdmi_dp_dual_mode_detect(connector, edid != NULL);
+
+		intel_display_power_put(dev_priv, POWER_DOMAIN_GMBUS);
+	}
+
+	to_intel_connector(connector)->detect_edid = edid;
+	if (edid && edid->input & DRM_EDID_INPUT_DIGITAL) {
+		intel_hdmi->rgb_quant_range_selectable =
+			drm_rgb_quant_range_selectable(edid);
+
+		intel_hdmi->has_audio = drm_detect_monitor_audio(edid);
+		if (intel_hdmi->force_audio != HDMI_AUDIO_AUTO)
+			intel_hdmi->has_audio =
+				intel_hdmi->force_audio == HDMI_AUDIO_ON;
+
+		if (intel_hdmi->force_audio != HDMI_AUDIO_OFF_DVI)
+			intel_hdmi->has_hdmi_sink =
+				drm_detect_hdmi_monitor(edid);
+
+		connected = true;
+	}
+
+	return connected;
+}
+
+static enum drm_connector_status
+intel_hdmi_detect(struct drm_connector *connector, bool force)
+{
+	enum drm_connector_status status;
+	struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector);
+	struct drm_i915_private *dev_priv = to_i915(connector->dev);
+	bool live_status = false;
+	unsigned int try;
+
+	DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
+		      connector->base.id, connector->name);
+
+	intel_display_power_get(dev_priv, POWER_DOMAIN_GMBUS);
+
+	for (try = 0; !live_status && try < 9; try++) {
+		if (try)
+			msleep(10);
+		live_status = intel_digital_port_connected(dev_priv,
+				hdmi_to_dig_port(intel_hdmi));
+	}
+
+	if (!live_status) {
+		DRM_DEBUG_KMS("HDMI live status down\n");
+		/*
+		 * Live status register is not reliable on all intel platforms.
+		 * So consider live_status only for certain platforms, for
+		 * others, read EDID to determine presence of sink.
+		 */
+		if (INTEL_INFO(dev_priv)->gen < 7 || IS_IVYBRIDGE(dev_priv))
+			live_status = true;
+	}
+
+	intel_hdmi_unset_edid(connector);
+
+	if (intel_hdmi_set_edid(connector, live_status)) {
+		struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector);
+
+		hdmi_to_dig_port(intel_hdmi)->base.type = INTEL_OUTPUT_HDMI;
+		status = connector_status_connected;
+	} else
+		status = connector_status_disconnected;
+
+	intel_display_power_put(dev_priv, POWER_DOMAIN_GMBUS);
+
+	return status;
+}
+
+static void
+intel_hdmi_force(struct drm_connector *connector)
+{
+	struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector);
+
+	DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
+		      connector->base.id, connector->name);
+
+	intel_hdmi_unset_edid(connector);
+
+	if (connector->status != connector_status_connected)
+		return;
+
+	intel_hdmi_set_edid(connector, true);
+	hdmi_to_dig_port(intel_hdmi)->base.type = INTEL_OUTPUT_HDMI;
+}
+
+static int intel_hdmi_get_modes(struct drm_connector *connector)
+{
+	struct edid *edid;
+
+	edid = to_intel_connector(connector)->detect_edid;
+	if (edid == NULL)
+		return 0;
+
+	return intel_connector_update_modes(connector, edid);
+}
+
+static bool
+intel_hdmi_detect_audio(struct drm_connector *connector)
+{
+	bool has_audio = false;
+	struct edid *edid;
+
+	edid = to_intel_connector(connector)->detect_edid;
+	if (edid && edid->input & DRM_EDID_INPUT_DIGITAL)
+		has_audio = drm_detect_monitor_audio(edid);
+
+	return has_audio;
+}
+
+static int
+intel_hdmi_set_property(struct drm_connector *connector,
+			struct drm_property *property,
+			uint64_t val)
+{
+	struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector);
+	struct intel_digital_port *intel_dig_port =
+		hdmi_to_dig_port(intel_hdmi);
+	struct drm_i915_private *dev_priv = connector->dev->dev_private;
+	int ret;
+
+	ret = drm_object_property_set_value(&connector->base, property, val);
+	if (ret)
+		return ret;
+
+	if (property == dev_priv->force_audio_property) {
+		enum hdmi_force_audio i = val;
+		bool has_audio;
+
+		if (i == intel_hdmi->force_audio)
+			return 0;
+
+		intel_hdmi->force_audio = i;
+
+		if (i == HDMI_AUDIO_AUTO)
+			has_audio = intel_hdmi_detect_audio(connector);
+		else
+			has_audio = (i == HDMI_AUDIO_ON);
+
+		if (i == HDMI_AUDIO_OFF_DVI)
+			intel_hdmi->has_hdmi_sink = 0;
+
+		intel_hdmi->has_audio = has_audio;
+		goto done;
+	}
+
+	if (property == dev_priv->broadcast_rgb_property) {
+		bool old_auto = intel_hdmi->color_range_auto;
+		bool old_range = intel_hdmi->limited_color_range;
+
+		switch (val) {
+		case INTEL_BROADCAST_RGB_AUTO:
+			intel_hdmi->color_range_auto = true;
+			break;
+		case INTEL_BROADCAST_RGB_FULL:
+			intel_hdmi->color_range_auto = false;
+			intel_hdmi->limited_color_range = false;
+			break;
+		case INTEL_BROADCAST_RGB_LIMITED:
+			intel_hdmi->color_range_auto = false;
+			intel_hdmi->limited_color_range = true;
+			break;
+		default:
+			return -EINVAL;
+		}
+
+		if (old_auto == intel_hdmi->color_range_auto &&
+		    old_range == intel_hdmi->limited_color_range)
+			return 0;
+
+		goto done;
+	}
+
+	if (property == connector->dev->mode_config.aspect_ratio_property) {
+		switch (val) {
+		case DRM_MODE_PICTURE_ASPECT_NONE:
+			intel_hdmi->aspect_ratio = HDMI_PICTURE_ASPECT_NONE;
+			break;
+		case DRM_MODE_PICTURE_ASPECT_4_3:
+			intel_hdmi->aspect_ratio = HDMI_PICTURE_ASPECT_4_3;
+			break;
+		case DRM_MODE_PICTURE_ASPECT_16_9:
+			intel_hdmi->aspect_ratio = HDMI_PICTURE_ASPECT_16_9;
+			break;
+		default:
+			return -EINVAL;
+		}
+		goto done;
+	}
+
+	return -EINVAL;
+
+done:
+	if (intel_dig_port->base.base.crtc)
+		intel_crtc_restore_mode(intel_dig_port->base.base.crtc);
+
+	return 0;
+}
+
+static void intel_hdmi_pre_enable(struct intel_encoder *encoder)
+{
+	struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&encoder->base);
+	struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc);
+	const struct drm_display_mode *adjusted_mode = &intel_crtc->config->base.adjusted_mode;
+
+	intel_hdmi_prepare(encoder);
+
+	intel_hdmi->set_infoframes(&encoder->base,
+				   intel_crtc->config->has_hdmi_sink,
+				   adjusted_mode);
+}
+
+static void vlv_hdmi_pre_enable(struct intel_encoder *encoder)
+{
+	struct intel_digital_port *dport = enc_to_dig_port(&encoder->base);
+	struct intel_hdmi *intel_hdmi = &dport->hdmi;
+	struct drm_device *dev = encoder->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_crtc *intel_crtc =
+		to_intel_crtc(encoder->base.crtc);
+	const struct drm_display_mode *adjusted_mode = &intel_crtc->config->base.adjusted_mode;
+	enum dpio_channel port = vlv_dport_to_channel(dport);
+	int pipe = intel_crtc->pipe;
+	u32 val;
+
+	/* Enable clock channels for this port */
+	mutex_lock(&dev_priv->sb_lock);
+	val = vlv_dpio_read(dev_priv, pipe, VLV_PCS01_DW8(port));
+	val = 0;
+	if (pipe)
+		val |= (1<<21);
+	else
+		val &= ~(1<<21);
+	val |= 0x001000c4;
+	vlv_dpio_write(dev_priv, pipe, VLV_PCS_DW8(port), val);
+
+	/* HDMI 1.0V-2dB */
+	vlv_dpio_write(dev_priv, pipe, VLV_TX_DW5(port), 0);
+	vlv_dpio_write(dev_priv, pipe, VLV_TX_DW4(port), 0x2b245f5f);
+	vlv_dpio_write(dev_priv, pipe, VLV_TX_DW2(port), 0x5578b83a);
+	vlv_dpio_write(dev_priv, pipe, VLV_TX_DW3(port), 0x0c782040);
+	vlv_dpio_write(dev_priv, pipe, VLV_TX3_DW4(port), 0x2b247878);
+	vlv_dpio_write(dev_priv, pipe, VLV_PCS_DW11(port), 0x00030000);
+	vlv_dpio_write(dev_priv, pipe, VLV_PCS_DW9(port), 0x00002000);
+	vlv_dpio_write(dev_priv, pipe, VLV_TX_DW5(port), DPIO_TX_OCALINIT_EN);
+
+	/* Program lane clock */
+	vlv_dpio_write(dev_priv, pipe, VLV_PCS_DW14(port), 0x00760018);
+	vlv_dpio_write(dev_priv, pipe, VLV_PCS_DW23(port), 0x00400888);
+	mutex_unlock(&dev_priv->sb_lock);
+
+	intel_hdmi->set_infoframes(&encoder->base,
+				   intel_crtc->config->has_hdmi_sink,
+				   adjusted_mode);
+
+	g4x_enable_hdmi(encoder);
+
+	vlv_wait_port_ready(dev_priv, dport, 0x0);
+}
+
+static void vlv_hdmi_pre_pll_enable(struct intel_encoder *encoder)
+{
+	struct intel_digital_port *dport = enc_to_dig_port(&encoder->base);
+	struct drm_device *dev = encoder->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_crtc *intel_crtc =
+		to_intel_crtc(encoder->base.crtc);
+	enum dpio_channel port = vlv_dport_to_channel(dport);
+	int pipe = intel_crtc->pipe;
+
+	intel_hdmi_prepare(encoder);
+
+	/* Program Tx lane resets to default */
+	mutex_lock(&dev_priv->sb_lock);
+	vlv_dpio_write(dev_priv, pipe, VLV_PCS_DW0(port),
+			 DPIO_PCS_TX_LANE2_RESET |
+			 DPIO_PCS_TX_LANE1_RESET);
+	vlv_dpio_write(dev_priv, pipe, VLV_PCS_DW1(port),
+			 DPIO_PCS_CLK_CRI_RXEB_EIOS_EN |
+			 DPIO_PCS_CLK_CRI_RXDIGFILTSG_EN |
+			 (1<<DPIO_PCS_CLK_DATAWIDTH_SHIFT) |
+			 DPIO_PCS_CLK_SOFT_RESET);
+
+	/* Fix up inter-pair skew failure */
+	vlv_dpio_write(dev_priv, pipe, VLV_PCS_DW12(port), 0x00750f00);
+	vlv_dpio_write(dev_priv, pipe, VLV_TX_DW11(port), 0x00001500);
+	vlv_dpio_write(dev_priv, pipe, VLV_TX_DW14(port), 0x40400000);
+
+	vlv_dpio_write(dev_priv, pipe, VLV_PCS_DW9(port), 0x00002000);
+	vlv_dpio_write(dev_priv, pipe, VLV_TX_DW5(port), DPIO_TX_OCALINIT_EN);
+	mutex_unlock(&dev_priv->sb_lock);
+}
+
+static void chv_data_lane_soft_reset(struct intel_encoder *encoder,
+				     bool reset)
+{
+	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
+	enum dpio_channel ch = vlv_dport_to_channel(enc_to_dig_port(&encoder->base));
+	struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc);
+	enum pipe pipe = crtc->pipe;
+	uint32_t val;
+
+	val = vlv_dpio_read(dev_priv, pipe, VLV_PCS01_DW0(ch));
+	if (reset)
+		val &= ~(DPIO_PCS_TX_LANE2_RESET | DPIO_PCS_TX_LANE1_RESET);
+	else
+		val |= DPIO_PCS_TX_LANE2_RESET | DPIO_PCS_TX_LANE1_RESET;
+	vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW0(ch), val);
+
+	if (crtc->config->lane_count > 2) {
+		val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW0(ch));
+		if (reset)
+			val &= ~(DPIO_PCS_TX_LANE2_RESET | DPIO_PCS_TX_LANE1_RESET);
+		else
+			val |= DPIO_PCS_TX_LANE2_RESET | DPIO_PCS_TX_LANE1_RESET;
+		vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW0(ch), val);
+	}
+
+	val = vlv_dpio_read(dev_priv, pipe, VLV_PCS01_DW1(ch));
+	val |= CHV_PCS_REQ_SOFTRESET_EN;
+	if (reset)
+		val &= ~DPIO_PCS_CLK_SOFT_RESET;
+	else
+		val |= DPIO_PCS_CLK_SOFT_RESET;
+	vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW1(ch), val);
+
+	if (crtc->config->lane_count > 2) {
+		val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW1(ch));
+		val |= CHV_PCS_REQ_SOFTRESET_EN;
+		if (reset)
+			val &= ~DPIO_PCS_CLK_SOFT_RESET;
+		else
+			val |= DPIO_PCS_CLK_SOFT_RESET;
+		vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW1(ch), val);
+	}
+}
+
+static void chv_hdmi_pre_pll_enable(struct intel_encoder *encoder)
+{
+	struct intel_digital_port *dport = enc_to_dig_port(&encoder->base);
+	struct drm_device *dev = encoder->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_crtc *intel_crtc =
+		to_intel_crtc(encoder->base.crtc);
+	enum dpio_channel ch = vlv_dport_to_channel(dport);
+	enum pipe pipe = intel_crtc->pipe;
+	u32 val;
+
+	intel_hdmi_prepare(encoder);
+
+	/*
+	 * Must trick the second common lane into life.
+	 * Otherwise we can't even access the PLL.
+	 */
+	if (ch == DPIO_CH0 && pipe == PIPE_B)
+		dport->release_cl2_override =
+			!chv_phy_powergate_ch(dev_priv, DPIO_PHY0, DPIO_CH1, true);
+
+	chv_phy_powergate_lanes(encoder, true, 0x0);
+
+	mutex_lock(&dev_priv->sb_lock);
+
+	/* Assert data lane reset */
+	chv_data_lane_soft_reset(encoder, true);
+
+	/* program left/right clock distribution */
+	if (pipe != PIPE_B) {
+		val = vlv_dpio_read(dev_priv, pipe, _CHV_CMN_DW5_CH0);
+		val &= ~(CHV_BUFLEFTENA1_MASK | CHV_BUFRIGHTENA1_MASK);
+		if (ch == DPIO_CH0)
+			val |= CHV_BUFLEFTENA1_FORCE;
+		if (ch == DPIO_CH1)
+			val |= CHV_BUFRIGHTENA1_FORCE;
+		vlv_dpio_write(dev_priv, pipe, _CHV_CMN_DW5_CH0, val);
+	} else {
+		val = vlv_dpio_read(dev_priv, pipe, _CHV_CMN_DW1_CH1);
+		val &= ~(CHV_BUFLEFTENA2_MASK | CHV_BUFRIGHTENA2_MASK);
+		if (ch == DPIO_CH0)
+			val |= CHV_BUFLEFTENA2_FORCE;
+		if (ch == DPIO_CH1)
+			val |= CHV_BUFRIGHTENA2_FORCE;
+		vlv_dpio_write(dev_priv, pipe, _CHV_CMN_DW1_CH1, val);
+	}
+
+	/* program clock channel usage */
+	val = vlv_dpio_read(dev_priv, pipe, VLV_PCS01_DW8(ch));
+	val |= CHV_PCS_USEDCLKCHANNEL_OVRRIDE;
+	if (pipe != PIPE_B)
+		val &= ~CHV_PCS_USEDCLKCHANNEL;
+	else
+		val |= CHV_PCS_USEDCLKCHANNEL;
+	vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW8(ch), val);
+
+	val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW8(ch));
+	val |= CHV_PCS_USEDCLKCHANNEL_OVRRIDE;
+	if (pipe != PIPE_B)
+		val &= ~CHV_PCS_USEDCLKCHANNEL;
+	else
+		val |= CHV_PCS_USEDCLKCHANNEL;
+	vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW8(ch), val);
+
+	/*
+	 * This a a bit weird since generally CL
+	 * matches the pipe, but here we need to
+	 * pick the CL based on the port.
+	 */
+	val = vlv_dpio_read(dev_priv, pipe, CHV_CMN_DW19(ch));
+	if (pipe != PIPE_B)
+		val &= ~CHV_CMN_USEDCLKCHANNEL;
+	else
+		val |= CHV_CMN_USEDCLKCHANNEL;
+	vlv_dpio_write(dev_priv, pipe, CHV_CMN_DW19(ch), val);
+
+	mutex_unlock(&dev_priv->sb_lock);
+}
+
+static void chv_hdmi_post_pll_disable(struct intel_encoder *encoder)
+{
+	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
+	enum pipe pipe = to_intel_crtc(encoder->base.crtc)->pipe;
+	u32 val;
+
+	mutex_lock(&dev_priv->sb_lock);
+
+	/* disable left/right clock distribution */
+	if (pipe != PIPE_B) {
+		val = vlv_dpio_read(dev_priv, pipe, _CHV_CMN_DW5_CH0);
+		val &= ~(CHV_BUFLEFTENA1_MASK | CHV_BUFRIGHTENA1_MASK);
+		vlv_dpio_write(dev_priv, pipe, _CHV_CMN_DW5_CH0, val);
+	} else {
+		val = vlv_dpio_read(dev_priv, pipe, _CHV_CMN_DW1_CH1);
+		val &= ~(CHV_BUFLEFTENA2_MASK | CHV_BUFRIGHTENA2_MASK);
+		vlv_dpio_write(dev_priv, pipe, _CHV_CMN_DW1_CH1, val);
+	}
+
+	mutex_unlock(&dev_priv->sb_lock);
+
+	/*
+	 * Leave the power down bit cleared for at least one
+	 * lane so that chv_powergate_phy_ch() will power
+	 * on something when the channel is otherwise unused.
+	 * When the port is off and the override is removed
+	 * the lanes power down anyway, so otherwise it doesn't
+	 * really matter what the state of power down bits is
+	 * after this.
+	 */
+	chv_phy_powergate_lanes(encoder, false, 0x0);
+}
+
+static void vlv_hdmi_post_disable(struct intel_encoder *encoder)
+{
+	struct intel_digital_port *dport = enc_to_dig_port(&encoder->base);
+	struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
+	struct intel_crtc *intel_crtc =
+		to_intel_crtc(encoder->base.crtc);
+	enum dpio_channel port = vlv_dport_to_channel(dport);
+	int pipe = intel_crtc->pipe;
+
+	/* Reset lanes to avoid HDMI flicker (VLV w/a) */
+	mutex_lock(&dev_priv->sb_lock);
+	vlv_dpio_write(dev_priv, pipe, VLV_PCS_DW0(port), 0x00000000);
+	vlv_dpio_write(dev_priv, pipe, VLV_PCS_DW1(port), 0x00e00060);
+	mutex_unlock(&dev_priv->sb_lock);
+}
+
+static void chv_hdmi_post_disable(struct intel_encoder *encoder)
+{
+	struct drm_device *dev = encoder->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	mutex_lock(&dev_priv->sb_lock);
+
+	/* Assert data lane reset */
+	chv_data_lane_soft_reset(encoder, true);
+
+	mutex_unlock(&dev_priv->sb_lock);
+}
+
+static void chv_hdmi_pre_enable(struct intel_encoder *encoder)
+{
+	struct intel_digital_port *dport = enc_to_dig_port(&encoder->base);
+	struct intel_hdmi *intel_hdmi = &dport->hdmi;
+	struct drm_device *dev = encoder->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_crtc *intel_crtc =
+		to_intel_crtc(encoder->base.crtc);
+	const struct drm_display_mode *adjusted_mode = &intel_crtc->config->base.adjusted_mode;
+	enum dpio_channel ch = vlv_dport_to_channel(dport);
+	int pipe = intel_crtc->pipe;
+	int data, i, stagger;
+	u32 val;
+
+	mutex_lock(&dev_priv->sb_lock);
+
+	/* allow hardware to manage TX FIFO reset source */
+	val = vlv_dpio_read(dev_priv, pipe, VLV_PCS01_DW11(ch));
+	val &= ~DPIO_LANEDESKEW_STRAP_OVRD;
+	vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW11(ch), val);
+
+	val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW11(ch));
+	val &= ~DPIO_LANEDESKEW_STRAP_OVRD;
+	vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW11(ch), val);
+
+	/* Program Tx latency optimal setting */
+	for (i = 0; i < 4; i++) {
+		/* Set the upar bit */
+		data = (i == 1) ? 0x0 : 0x1;
+		vlv_dpio_write(dev_priv, pipe, CHV_TX_DW14(ch, i),
+				data << DPIO_UPAR_SHIFT);
+	}
+
+	/* Data lane stagger programming */
+	if (intel_crtc->config->port_clock > 270000)
+		stagger = 0x18;
+	else if (intel_crtc->config->port_clock > 135000)
+		stagger = 0xd;
+	else if (intel_crtc->config->port_clock > 67500)
+		stagger = 0x7;
+	else if (intel_crtc->config->port_clock > 33750)
+		stagger = 0x4;
+	else
+		stagger = 0x2;
+
+	val = vlv_dpio_read(dev_priv, pipe, VLV_PCS01_DW11(ch));
+	val |= DPIO_TX2_STAGGER_MASK(0x1f);
+	vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW11(ch), val);
+
+	val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW11(ch));
+	val |= DPIO_TX2_STAGGER_MASK(0x1f);
+	vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW11(ch), val);
+
+	vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW12(ch),
+		       DPIO_LANESTAGGER_STRAP(stagger) |
+		       DPIO_LANESTAGGER_STRAP_OVRD |
+		       DPIO_TX1_STAGGER_MASK(0x1f) |
+		       DPIO_TX1_STAGGER_MULT(6) |
+		       DPIO_TX2_STAGGER_MULT(0));
+
+	vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW12(ch),
+		       DPIO_LANESTAGGER_STRAP(stagger) |
+		       DPIO_LANESTAGGER_STRAP_OVRD |
+		       DPIO_TX1_STAGGER_MASK(0x1f) |
+		       DPIO_TX1_STAGGER_MULT(7) |
+		       DPIO_TX2_STAGGER_MULT(5));
+
+	/* Deassert data lane reset */
+	chv_data_lane_soft_reset(encoder, false);
+
+	/* Clear calc init */
+	val = vlv_dpio_read(dev_priv, pipe, VLV_PCS01_DW10(ch));
+	val &= ~(DPIO_PCS_SWING_CALC_TX0_TX2 | DPIO_PCS_SWING_CALC_TX1_TX3);
+	val &= ~(DPIO_PCS_TX1DEEMP_MASK | DPIO_PCS_TX2DEEMP_MASK);
+	val |= DPIO_PCS_TX1DEEMP_9P5 | DPIO_PCS_TX2DEEMP_9P5;
+	vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW10(ch), val);
+
+	val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW10(ch));
+	val &= ~(DPIO_PCS_SWING_CALC_TX0_TX2 | DPIO_PCS_SWING_CALC_TX1_TX3);
+	val &= ~(DPIO_PCS_TX1DEEMP_MASK | DPIO_PCS_TX2DEEMP_MASK);
+	val |= DPIO_PCS_TX1DEEMP_9P5 | DPIO_PCS_TX2DEEMP_9P5;
+	vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW10(ch), val);
+
+	val = vlv_dpio_read(dev_priv, pipe, VLV_PCS01_DW9(ch));
+	val &= ~(DPIO_PCS_TX1MARGIN_MASK | DPIO_PCS_TX2MARGIN_MASK);
+	val |= DPIO_PCS_TX1MARGIN_000 | DPIO_PCS_TX2MARGIN_000;
+	vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW9(ch), val);
+
+	val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW9(ch));
+	val &= ~(DPIO_PCS_TX1MARGIN_MASK | DPIO_PCS_TX2MARGIN_MASK);
+	val |= DPIO_PCS_TX1MARGIN_000 | DPIO_PCS_TX2MARGIN_000;
+	vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW9(ch), val);
+
+	/* FIXME: Program the support xxx V-dB */
+	/* Use 800mV-0dB */
+	for (i = 0; i < 4; i++) {
+		val = vlv_dpio_read(dev_priv, pipe, CHV_TX_DW4(ch, i));
+		val &= ~DPIO_SWING_DEEMPH9P5_MASK;
+		val |= 128 << DPIO_SWING_DEEMPH9P5_SHIFT;
+		vlv_dpio_write(dev_priv, pipe, CHV_TX_DW4(ch, i), val);
+	}
+
+	for (i = 0; i < 4; i++) {
+		val = vlv_dpio_read(dev_priv, pipe, CHV_TX_DW2(ch, i));
+
+		val &= ~DPIO_SWING_MARGIN000_MASK;
+		val |= 102 << DPIO_SWING_MARGIN000_SHIFT;
+
+		/*
+		 * Supposedly this value shouldn't matter when unique transition
+		 * scale is disabled, but in fact it does matter. Let's just
+		 * always program the same value and hope it's OK.
+		 */
+		val &= ~(0xff << DPIO_UNIQ_TRANS_SCALE_SHIFT);
+		val |= 0x9a << DPIO_UNIQ_TRANS_SCALE_SHIFT;
+
+		vlv_dpio_write(dev_priv, pipe, CHV_TX_DW2(ch, i), val);
+	}
+
+	/*
+	 * The document said it needs to set bit 27 for ch0 and bit 26
+	 * for ch1. Might be a typo in the doc.
+	 * For now, for this unique transition scale selection, set bit
+	 * 27 for ch0 and ch1.
+	 */
+	for (i = 0; i < 4; i++) {
+		val = vlv_dpio_read(dev_priv, pipe, CHV_TX_DW3(ch, i));
+		val &= ~DPIO_TX_UNIQ_TRANS_SCALE_EN;
+		vlv_dpio_write(dev_priv, pipe, CHV_TX_DW3(ch, i), val);
+	}
+
+	/* Start swing calculation */
+	val = vlv_dpio_read(dev_priv, pipe, VLV_PCS01_DW10(ch));
+	val |= DPIO_PCS_SWING_CALC_TX0_TX2 | DPIO_PCS_SWING_CALC_TX1_TX3;
+	vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW10(ch), val);
+
+	val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW10(ch));
+	val |= DPIO_PCS_SWING_CALC_TX0_TX2 | DPIO_PCS_SWING_CALC_TX1_TX3;
+	vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW10(ch), val);
+
+	mutex_unlock(&dev_priv->sb_lock);
+
+	intel_hdmi->set_infoframes(&encoder->base,
+				   intel_crtc->config->has_hdmi_sink,
+				   adjusted_mode);
+
+	g4x_enable_hdmi(encoder);
+
+	vlv_wait_port_ready(dev_priv, dport, 0x0);
+
+	/* Second common lane will stay alive on its own now */
+	if (dport->release_cl2_override) {
+		chv_phy_powergate_ch(dev_priv, DPIO_PHY0, DPIO_CH1, false);
+		dport->release_cl2_override = false;
+	}
+}
+
+static void intel_hdmi_destroy(struct drm_connector *connector)
+{
+	kfree(to_intel_connector(connector)->detect_edid);
+	drm_connector_cleanup(connector);
+	kfree(connector);
+}
+
+static const struct drm_connector_funcs intel_hdmi_connector_funcs = {
+	.dpms = drm_atomic_helper_connector_dpms,
+	.detect = intel_hdmi_detect,
+	.force = intel_hdmi_force,
+	.fill_modes = drm_helper_probe_single_connector_modes,
+	.set_property = intel_hdmi_set_property,
+	.atomic_get_property = intel_connector_atomic_get_property,
+	.destroy = intel_hdmi_destroy,
+	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
+	.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
+};
+
+static const struct drm_connector_helper_funcs intel_hdmi_connector_helper_funcs = {
+	.get_modes = intel_hdmi_get_modes,
+	.mode_valid = intel_hdmi_mode_valid,
+	.best_encoder = intel_best_encoder,
+};
+
+static const struct drm_encoder_funcs intel_hdmi_enc_funcs = {
+	.destroy = intel_encoder_destroy,
+};
+
+static void
+intel_hdmi_add_properties(struct intel_hdmi *intel_hdmi, struct drm_connector *connector)
+{
+	intel_attach_force_audio_property(connector);
+	intel_attach_broadcast_rgb_property(connector);
+	intel_hdmi->color_range_auto = true;
+	intel_attach_aspect_ratio_property(connector);
+	intel_hdmi->aspect_ratio = HDMI_PICTURE_ASPECT_NONE;
+}
+
+void intel_hdmi_init_connector(struct intel_digital_port *intel_dig_port,
+			       struct intel_connector *intel_connector)
+{
+	struct drm_connector *connector = &intel_connector->base;
+	struct intel_hdmi *intel_hdmi = &intel_dig_port->hdmi;
+	struct intel_encoder *intel_encoder = &intel_dig_port->base;
+	struct drm_device *dev = intel_encoder->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	enum port port = intel_dig_port->port;
+	uint8_t alternate_ddc_pin;
+
+	DRM_DEBUG_KMS("Adding HDMI connector on port %c\n",
+		      port_name(port));
+
+	if (WARN(intel_dig_port->max_lanes < 4,
+		 "Not enough lanes (%d) for HDMI on port %c\n",
+		 intel_dig_port->max_lanes, port_name(port)))
+		return;
+
+	drm_connector_init(dev, connector, &intel_hdmi_connector_funcs,
+			   DRM_MODE_CONNECTOR_HDMIA);
+	drm_connector_helper_add(connector, &intel_hdmi_connector_helper_funcs);
+
+	connector->interlace_allowed = 1;
+	connector->doublescan_allowed = 0;
+	connector->stereo_allowed = 1;
+
+	switch (port) {
+	case PORT_B:
+		if (IS_BROXTON(dev_priv))
+			intel_hdmi->ddc_bus = GMBUS_PIN_1_BXT;
+		else
+			intel_hdmi->ddc_bus = GMBUS_PIN_DPB;
+		/*
+		 * On BXT A0/A1, sw needs to activate DDIA HPD logic and
+		 * interrupts to check the external panel connection.
+		 */
+		if (IS_BXT_REVID(dev_priv, 0, BXT_REVID_A1))
+			intel_encoder->hpd_pin = HPD_PORT_A;
+		else
+			intel_encoder->hpd_pin = HPD_PORT_B;
+		break;
+	case PORT_C:
+		if (IS_BROXTON(dev_priv))
+			intel_hdmi->ddc_bus = GMBUS_PIN_2_BXT;
+		else
+			intel_hdmi->ddc_bus = GMBUS_PIN_DPC;
+		intel_encoder->hpd_pin = HPD_PORT_C;
+		break;
+	case PORT_D:
+		if (WARN_ON(IS_BROXTON(dev_priv)))
+			intel_hdmi->ddc_bus = GMBUS_PIN_DISABLED;
+		else if (IS_CHERRYVIEW(dev_priv))
+			intel_hdmi->ddc_bus = GMBUS_PIN_DPD_CHV;
+		else
+			intel_hdmi->ddc_bus = GMBUS_PIN_DPD;
+		intel_encoder->hpd_pin = HPD_PORT_D;
+		break;
+	case PORT_E:
+		/* On SKL PORT E doesn't have seperate GMBUS pin
+		 *  We rely on VBT to set a proper alternate GMBUS pin. */
+		alternate_ddc_pin =
+			dev_priv->vbt.ddi_port_info[PORT_E].alternate_ddc_pin;
+		switch (alternate_ddc_pin) {
+		case DDC_PIN_B:
+			intel_hdmi->ddc_bus = GMBUS_PIN_DPB;
+			break;
+		case DDC_PIN_C:
+			intel_hdmi->ddc_bus = GMBUS_PIN_DPC;
+			break;
+		case DDC_PIN_D:
+			intel_hdmi->ddc_bus = GMBUS_PIN_DPD;
+			break;
+		default:
+			MISSING_CASE(alternate_ddc_pin);
+		}
+		intel_encoder->hpd_pin = HPD_PORT_E;
+		break;
+	case PORT_A:
+		intel_encoder->hpd_pin = HPD_PORT_A;
+		/* Internal port only for eDP. */
+	default:
+		BUG();
+	}
+
+	if (IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev)) {
+		intel_hdmi->write_infoframe = vlv_write_infoframe;
+		intel_hdmi->set_infoframes = vlv_set_infoframes;
+		intel_hdmi->infoframe_enabled = vlv_infoframe_enabled;
+	} else if (IS_G4X(dev)) {
+		intel_hdmi->write_infoframe = g4x_write_infoframe;
+		intel_hdmi->set_infoframes = g4x_set_infoframes;
+		intel_hdmi->infoframe_enabled = g4x_infoframe_enabled;
+	} else if (HAS_DDI(dev)) {
+		intel_hdmi->write_infoframe = hsw_write_infoframe;
+		intel_hdmi->set_infoframes = hsw_set_infoframes;
+		intel_hdmi->infoframe_enabled = hsw_infoframe_enabled;
+	} else if (HAS_PCH_IBX(dev)) {
+		intel_hdmi->write_infoframe = ibx_write_infoframe;
+		intel_hdmi->set_infoframes = ibx_set_infoframes;
+		intel_hdmi->infoframe_enabled = ibx_infoframe_enabled;
+	} else {
+		intel_hdmi->write_infoframe = cpt_write_infoframe;
+		intel_hdmi->set_infoframes = cpt_set_infoframes;
+		intel_hdmi->infoframe_enabled = cpt_infoframe_enabled;
+	}
+
+	if (HAS_DDI(dev))
+		intel_connector->get_hw_state = intel_ddi_connector_get_hw_state;
+	else
+		intel_connector->get_hw_state = intel_connector_get_hw_state;
+	intel_connector->unregister = intel_connector_unregister;
+
+	intel_hdmi_add_properties(intel_hdmi, connector);
+
+	intel_connector_attach_encoder(intel_connector, intel_encoder);
+	drm_connector_register(connector);
+	intel_hdmi->attached_connector = intel_connector;
+
+	/* For G4X desktop chip, PEG_BAND_GAP_DATA 3:0 must first be written
+	 * 0xd.  Failure to do so will result in spurious interrupts being
+	 * generated on the port when a cable is not attached.
+	 */
+	if (IS_G4X(dev) && !IS_GM45(dev)) {
+		u32 temp = I915_READ(PEG_BAND_GAP_DATA);
+		I915_WRITE(PEG_BAND_GAP_DATA, (temp & ~0xf) | 0xd);
+	}
+}
+
+void intel_hdmi_init(struct drm_device *dev,
+		     i915_reg_t hdmi_reg, enum port port)
+{
+	struct intel_digital_port *intel_dig_port;
+	struct intel_encoder *intel_encoder;
+	struct intel_connector *intel_connector;
+
+	intel_dig_port = kzalloc(sizeof(*intel_dig_port), GFP_KERNEL);
+	if (!intel_dig_port)
+		return;
+
+	intel_connector = intel_connector_alloc();
+	if (!intel_connector) {
+		kfree(intel_dig_port);
+		return;
+	}
+
+	intel_encoder = &intel_dig_port->base;
+
+	drm_encoder_init(dev, &intel_encoder->base, &intel_hdmi_enc_funcs,
+			 DRM_MODE_ENCODER_TMDS);
+
+	intel_encoder->compute_config = intel_hdmi_compute_config;
+	if (HAS_PCH_SPLIT(dev)) {
+		intel_encoder->disable = pch_disable_hdmi;
+		intel_encoder->post_disable = pch_post_disable_hdmi;
+	} else {
+		intel_encoder->disable = g4x_disable_hdmi;
+	}
+	intel_encoder->get_hw_state = intel_hdmi_get_hw_state;
+	intel_encoder->get_config = intel_hdmi_get_config;
+	if (IS_CHERRYVIEW(dev)) {
+		intel_encoder->pre_pll_enable = chv_hdmi_pre_pll_enable;
+		intel_encoder->pre_enable = chv_hdmi_pre_enable;
+		intel_encoder->enable = vlv_enable_hdmi;
+		intel_encoder->post_disable = chv_hdmi_post_disable;
+		intel_encoder->post_pll_disable = chv_hdmi_post_pll_disable;
+	} else if (IS_VALLEYVIEW(dev)) {
+		intel_encoder->pre_pll_enable = vlv_hdmi_pre_pll_enable;
+		intel_encoder->pre_enable = vlv_hdmi_pre_enable;
+		intel_encoder->enable = vlv_enable_hdmi;
+		intel_encoder->post_disable = vlv_hdmi_post_disable;
+	} else {
+		intel_encoder->pre_enable = intel_hdmi_pre_enable;
+		if (HAS_PCH_CPT(dev))
+			intel_encoder->enable = cpt_enable_hdmi;
+		else if (HAS_PCH_IBX(dev))
+			intel_encoder->enable = ibx_enable_hdmi;
+		else
+			intel_encoder->enable = g4x_enable_hdmi;
+	}
+
+	intel_encoder->type = INTEL_OUTPUT_HDMI;
+	if (IS_CHERRYVIEW(dev)) {
+		if (port == PORT_D)
+			intel_encoder->crtc_mask = 1 << 2;
+		else
+			intel_encoder->crtc_mask = (1 << 0) | (1 << 1);
+	} else {
+		intel_encoder->crtc_mask = (1 << 0) | (1 << 1) | (1 << 2);
+	}
+	intel_encoder->cloneable = 1 << INTEL_OUTPUT_ANALOG;
+	/*
+	 * BSpec is unclear about HDMI+HDMI cloning on g4x, but it seems
+	 * to work on real hardware. And since g4x can send infoframes to
+	 * only one port anyway, nothing is lost by allowing it.
+	 */
+	if (IS_G4X(dev))
+		intel_encoder->cloneable |= 1 << INTEL_OUTPUT_HDMI;
+
+	intel_dig_port->port = port;
+	intel_dig_port->hdmi.hdmi_reg = hdmi_reg;
+	intel_dig_port->dp.output_reg = INVALID_MMIO_REG;
+	intel_dig_port->max_lanes = 4;
+
+	intel_hdmi_init_connector(intel_dig_port, intel_connector);
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/i915/intel_hotplug.c
@@ -0,0 +1,513 @@
+/*
+ * Copyright © 2015 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include <linux/kernel.h>
+
+#include <drm/drmP.h>
+#include <drm/i915_drm.h>
+
+#include "i915_drv.h"
+#include "intel_drv.h"
+
+/**
+ * DOC: Hotplug
+ *
+ * Simply put, hotplug occurs when a display is connected to or disconnected
+ * from the system. However, there may be adapters and docking stations and
+ * Display Port short pulses and MST devices involved, complicating matters.
+ *
+ * Hotplug in i915 is handled in many different levels of abstraction.
+ *
+ * The platform dependent interrupt handling code in i915_irq.c enables,
+ * disables, and does preliminary handling of the interrupts. The interrupt
+ * handlers gather the hotplug detect (HPD) information from relevant registers
+ * into a platform independent mask of hotplug pins that have fired.
+ *
+ * The platform independent interrupt handler intel_hpd_irq_handler() in
+ * intel_hotplug.c does hotplug irq storm detection and mitigation, and passes
+ * further processing to appropriate bottom halves (Display Port specific and
+ * regular hotplug).
+ *
+ * The Display Port work function i915_digport_work_func() calls into
+ * intel_dp_hpd_pulse() via hooks, which handles DP short pulses and DP MST long
+ * pulses, with failures and non-MST long pulses triggering regular hotplug
+ * processing on the connector.
+ *
+ * The regular hotplug work function i915_hotplug_work_func() calls connector
+ * detect hooks, and, if connector status changes, triggers sending of hotplug
+ * uevent to userspace via drm_kms_helper_hotplug_event().
+ *
+ * Finally, the userspace is responsible for triggering a modeset upon receiving
+ * the hotplug uevent, disabling or enabling the crtc as needed.
+ *
+ * The hotplug interrupt storm detection and mitigation code keeps track of the
+ * number of interrupts per hotplug pin per a period of time, and if the number
+ * of interrupts exceeds a certain threshold, the interrupt is disabled for a
+ * while before being re-enabled. The intention is to mitigate issues raising
+ * from broken hardware triggering massive amounts of interrupts and grinding
+ * the system to a halt.
+ *
+ * Current implementation expects that hotplug interrupt storm will not be
+ * seen when display port sink is connected, hence on platforms whose DP
+ * callback is handled by i915_digport_work_func reenabling of hpd is not
+ * performed (it was never expected to be disabled in the first place ;) )
+ * this is specific to DP sinks handled by this routine and any other display
+ * such as HDMI or DVI enabled on the same port will have proper logic since
+ * it will use i915_hotplug_work_func where this logic is handled.
+ */
+
+bool intel_hpd_pin_to_port(enum hpd_pin pin, enum port *port)
+{
+	switch (pin) {
+	case HPD_PORT_A:
+		*port = PORT_A;
+		return true;
+	case HPD_PORT_B:
+		*port = PORT_B;
+		return true;
+	case HPD_PORT_C:
+		*port = PORT_C;
+		return true;
+	case HPD_PORT_D:
+		*port = PORT_D;
+		return true;
+	case HPD_PORT_E:
+		*port = PORT_E;
+		return true;
+	default:
+		return false;	/* no hpd */
+	}
+}
+
+#define HPD_STORM_DETECT_PERIOD		1000
+#define HPD_STORM_THRESHOLD		5
+#define HPD_STORM_REENABLE_DELAY	(2 * 60 * 1000)
+
+/**
+ * intel_hpd_irq_storm_detect - gather stats and detect HPD irq storm on a pin
+ * @dev_priv: private driver data pointer
+ * @pin: the pin to gather stats on
+ *
+ * Gather stats about HPD irqs from the specified @pin, and detect irq
+ * storms. Only the pin specific stats and state are changed, the caller is
+ * responsible for further action.
+ *
+ * @HPD_STORM_THRESHOLD irqs are allowed within @HPD_STORM_DETECT_PERIOD ms,
+ * otherwise it's considered an irq storm, and the irq state is set to
+ * @HPD_MARK_DISABLED.
+ *
+ * Return true if an irq storm was detected on @pin.
+ */
+static bool intel_hpd_irq_storm_detect(struct drm_i915_private *dev_priv,
+				       enum hpd_pin pin)
+{
+	unsigned long start = dev_priv->hotplug.stats[pin].last_jiffies;
+	unsigned long end = start + msecs_to_jiffies(HPD_STORM_DETECT_PERIOD);
+	bool storm = false;
+
+	if (!time_in_range(jiffies, start, end)) {
+		dev_priv->hotplug.stats[pin].last_jiffies = jiffies;
+		dev_priv->hotplug.stats[pin].count = 0;
+		DRM_DEBUG_KMS("Received HPD interrupt on PIN %d - cnt: 0\n", pin);
+	} else if (dev_priv->hotplug.stats[pin].count > HPD_STORM_THRESHOLD) {
+		dev_priv->hotplug.stats[pin].state = HPD_MARK_DISABLED;
+		DRM_DEBUG_KMS("HPD interrupt storm detected on PIN %d\n", pin);
+		storm = true;
+	} else {
+		dev_priv->hotplug.stats[pin].count++;
+		DRM_DEBUG_KMS("Received HPD interrupt on PIN %d - cnt: %d\n", pin,
+			      dev_priv->hotplug.stats[pin].count);
+	}
+
+	return storm;
+}
+
+static void intel_hpd_irq_storm_disable(struct drm_i915_private *dev_priv)
+{
+	struct drm_device *dev = dev_priv->dev;
+	struct drm_mode_config *mode_config = &dev->mode_config;
+	struct intel_connector *intel_connector;
+	struct intel_encoder *intel_encoder;
+	struct drm_connector *connector;
+	enum hpd_pin pin;
+	bool hpd_disabled = false;
+
+	assert_spin_locked(&dev_priv->irq_lock);
+
+	list_for_each_entry(connector, &mode_config->connector_list, head) {
+		if (connector->polled != DRM_CONNECTOR_POLL_HPD)
+			continue;
+
+		intel_connector = to_intel_connector(connector);
+		intel_encoder = intel_connector->encoder;
+		if (!intel_encoder)
+			continue;
+
+		pin = intel_encoder->hpd_pin;
+		if (pin == HPD_NONE ||
+		    dev_priv->hotplug.stats[pin].state != HPD_MARK_DISABLED)
+			continue;
+
+		DRM_INFO("HPD interrupt storm detected on connector %s: "
+			 "switching from hotplug detection to polling\n",
+			 connector->name);
+
+		dev_priv->hotplug.stats[pin].state = HPD_DISABLED;
+		connector->polled = DRM_CONNECTOR_POLL_CONNECT
+			| DRM_CONNECTOR_POLL_DISCONNECT;
+		hpd_disabled = true;
+	}
+
+	/* Enable polling and queue hotplug re-enabling. */
+	if (hpd_disabled) {
+		drm_kms_helper_poll_enable_locked(dev);
+		mod_delayed_work(system_wq, &dev_priv->hotplug.reenable_work,
+				 msecs_to_jiffies(HPD_STORM_REENABLE_DELAY));
+	}
+}
+
+static void intel_hpd_irq_storm_reenable_work(struct work_struct *work)
+{
+	struct drm_i915_private *dev_priv =
+		container_of(work, typeof(*dev_priv),
+			     hotplug.reenable_work.work);
+	struct drm_device *dev = dev_priv->dev;
+	struct drm_mode_config *mode_config = &dev->mode_config;
+	int i;
+
+	intel_runtime_pm_get(dev_priv);
+
+	spin_lock_irq(&dev_priv->irq_lock);
+	for_each_hpd_pin(i) {
+		struct drm_connector *connector;
+
+		if (dev_priv->hotplug.stats[i].state != HPD_DISABLED)
+			continue;
+
+		dev_priv->hotplug.stats[i].state = HPD_ENABLED;
+
+		list_for_each_entry(connector, &mode_config->connector_list, head) {
+			struct intel_connector *intel_connector = to_intel_connector(connector);
+
+			if (intel_connector->encoder->hpd_pin == i) {
+				if (connector->polled != intel_connector->polled)
+					DRM_DEBUG_DRIVER("Reenabling HPD on connector %s\n",
+							 connector->name);
+				connector->polled = intel_connector->polled;
+				if (!connector->polled)
+					connector->polled = DRM_CONNECTOR_POLL_HPD;
+			}
+		}
+	}
+	if (dev_priv->display.hpd_irq_setup)
+		dev_priv->display.hpd_irq_setup(dev);
+	spin_unlock_irq(&dev_priv->irq_lock);
+
+	intel_runtime_pm_put(dev_priv);
+}
+
+static bool intel_hpd_irq_event(struct drm_device *dev,
+				struct drm_connector *connector)
+{
+	enum drm_connector_status old_status;
+
+	WARN_ON(!mutex_is_locked(&dev->mode_config.mutex));
+	old_status = connector->status;
+
+	connector->status = connector->funcs->detect(connector, false);
+	if (old_status == connector->status)
+		return false;
+
+	DRM_DEBUG_KMS("[CONNECTOR:%d:%s] status updated from %s to %s\n",
+		      connector->base.id,
+		      connector->name,
+		      drm_get_connector_status_name(old_status),
+		      drm_get_connector_status_name(connector->status));
+
+	return true;
+}
+
+static void i915_digport_work_func(struct work_struct *work)
+{
+	struct drm_i915_private *dev_priv =
+		container_of(work, struct drm_i915_private, hotplug.dig_port_work);
+	u32 long_port_mask, short_port_mask;
+	struct intel_digital_port *intel_dig_port;
+	int i;
+	u32 old_bits = 0;
+
+	spin_lock_irq(&dev_priv->irq_lock);
+	long_port_mask = dev_priv->hotplug.long_port_mask;
+	dev_priv->hotplug.long_port_mask = 0;
+	short_port_mask = dev_priv->hotplug.short_port_mask;
+	dev_priv->hotplug.short_port_mask = 0;
+	spin_unlock_irq(&dev_priv->irq_lock);
+
+	for (i = 0; i < I915_MAX_PORTS; i++) {
+		bool valid = false;
+		bool long_hpd = false;
+		intel_dig_port = dev_priv->hotplug.irq_port[i];
+		if (!intel_dig_port || !intel_dig_port->hpd_pulse)
+			continue;
+
+		if (long_port_mask & (1 << i))  {
+			valid = true;
+			long_hpd = true;
+		} else if (short_port_mask & (1 << i))
+			valid = true;
+
+		if (valid) {
+			enum irqreturn ret;
+
+			ret = intel_dig_port->hpd_pulse(intel_dig_port, long_hpd);
+			if (ret == IRQ_NONE) {
+				/* fall back to old school hpd */
+				old_bits |= (1 << intel_dig_port->base.hpd_pin);
+			}
+		}
+	}
+
+	if (old_bits) {
+		spin_lock_irq(&dev_priv->irq_lock);
+		dev_priv->hotplug.event_bits |= old_bits;
+		spin_unlock_irq(&dev_priv->irq_lock);
+		schedule_work(&dev_priv->hotplug.hotplug_work);
+	}
+}
+
+/*
+ * Handle hotplug events outside the interrupt handler proper.
+ */
+static void i915_hotplug_work_func(struct work_struct *work)
+{
+	struct drm_i915_private *dev_priv =
+		container_of(work, struct drm_i915_private, hotplug.hotplug_work);
+	struct drm_device *dev = dev_priv->dev;
+	struct drm_mode_config *mode_config = &dev->mode_config;
+	struct intel_connector *intel_connector;
+	struct intel_encoder *intel_encoder;
+	struct drm_connector *connector;
+	bool changed = false;
+	u32 hpd_event_bits;
+
+	mutex_lock(&mode_config->mutex);
+	DRM_DEBUG_KMS("running encoder hotplug functions\n");
+
+	spin_lock_irq(&dev_priv->irq_lock);
+
+	hpd_event_bits = dev_priv->hotplug.event_bits;
+	dev_priv->hotplug.event_bits = 0;
+
+	/* Disable hotplug on connectors that hit an irq storm. */
+	intel_hpd_irq_storm_disable(dev_priv);
+
+	spin_unlock_irq(&dev_priv->irq_lock);
+
+	list_for_each_entry(connector, &mode_config->connector_list, head) {
+		intel_connector = to_intel_connector(connector);
+		if (!intel_connector->encoder)
+			continue;
+		intel_encoder = intel_connector->encoder;
+		if (hpd_event_bits & (1 << intel_encoder->hpd_pin)) {
+			DRM_DEBUG_KMS("Connector %s (pin %i) received hotplug event.\n",
+				      connector->name, intel_encoder->hpd_pin);
+			if (intel_encoder->hot_plug)
+				intel_encoder->hot_plug(intel_encoder);
+			if (intel_hpd_irq_event(dev, connector))
+				changed = true;
+		}
+	}
+	mutex_unlock(&mode_config->mutex);
+
+	if (changed)
+		drm_kms_helper_hotplug_event(dev);
+}
+
+
+/**
+ * intel_hpd_irq_handler - main hotplug irq handler
+ * @dev: drm device
+ * @pin_mask: a mask of hpd pins that have triggered the irq
+ * @long_mask: a mask of hpd pins that may be long hpd pulses
+ *
+ * This is the main hotplug irq handler for all platforms. The platform specific
+ * irq handlers call the platform specific hotplug irq handlers, which read and
+ * decode the appropriate registers into bitmasks about hpd pins that have
+ * triggered (@pin_mask), and which of those pins may be long pulses
+ * (@long_mask). The @long_mask is ignored if the port corresponding to the pin
+ * is not a digital port.
+ *
+ * Here, we do hotplug irq storm detection and mitigation, and pass further
+ * processing to appropriate bottom halves.
+ */
+void intel_hpd_irq_handler(struct drm_device *dev,
+			   u32 pin_mask, u32 long_mask)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	int i;
+	enum port port;
+	bool storm_detected = false;
+	bool queue_dig = false, queue_hp = false;
+	bool is_dig_port;
+
+	if (!pin_mask)
+		return;
+
+	spin_lock(&dev_priv->irq_lock);
+	for_each_hpd_pin(i) {
+		if (!(BIT(i) & pin_mask))
+			continue;
+
+		is_dig_port = intel_hpd_pin_to_port(i, &port) &&
+			      dev_priv->hotplug.irq_port[port];
+
+		if (is_dig_port) {
+			bool long_hpd = long_mask & BIT(i);
+
+			DRM_DEBUG_DRIVER("digital hpd port %c - %s\n", port_name(port),
+					 long_hpd ? "long" : "short");
+			/*
+			 * For long HPD pulses we want to have the digital queue happen,
+			 * but we still want HPD storm detection to function.
+			 */
+			queue_dig = true;
+			if (long_hpd) {
+				dev_priv->hotplug.long_port_mask |= (1 << port);
+			} else {
+				/* for short HPD just trigger the digital queue */
+				dev_priv->hotplug.short_port_mask |= (1 << port);
+				continue;
+			}
+		}
+
+		if (dev_priv->hotplug.stats[i].state == HPD_DISABLED) {
+			/*
+			 * On GMCH platforms the interrupt mask bits only
+			 * prevent irq generation, not the setting of the
+			 * hotplug bits itself. So only WARN about unexpected
+			 * interrupts on saner platforms.
+			 */
+			WARN_ONCE(!HAS_GMCH_DISPLAY(dev),
+				  "Received HPD interrupt on pin %d although disabled\n", i);
+			continue;
+		}
+
+		if (dev_priv->hotplug.stats[i].state != HPD_ENABLED)
+			continue;
+
+		if (!is_dig_port) {
+			dev_priv->hotplug.event_bits |= BIT(i);
+			queue_hp = true;
+		}
+
+		if (intel_hpd_irq_storm_detect(dev_priv, i)) {
+			dev_priv->hotplug.event_bits &= ~BIT(i);
+			storm_detected = true;
+		}
+	}
+
+	if (storm_detected)
+		dev_priv->display.hpd_irq_setup(dev);
+	spin_unlock(&dev_priv->irq_lock);
+
+	/*
+	 * Our hotplug handler can grab modeset locks (by calling down into the
+	 * fb helpers). Hence it must not be run on our own dev-priv->wq work
+	 * queue for otherwise the flush_work in the pageflip code will
+	 * deadlock.
+	 */
+	if (queue_dig)
+		queue_work(dev_priv->hotplug.dp_wq, &dev_priv->hotplug.dig_port_work);
+	if (queue_hp)
+		schedule_work(&dev_priv->hotplug.hotplug_work);
+}
+
+/**
+ * intel_hpd_init - initializes and enables hpd support
+ * @dev_priv: i915 device instance
+ *
+ * This function enables the hotplug support. It requires that interrupts have
+ * already been enabled with intel_irq_init_hw(). From this point on hotplug and
+ * poll request can run concurrently to other code, so locking rules must be
+ * obeyed.
+ *
+ * This is a separate step from interrupt enabling to simplify the locking rules
+ * in the driver load and resume code.
+ */
+void intel_hpd_init(struct drm_i915_private *dev_priv)
+{
+	struct drm_device *dev = dev_priv->dev;
+	struct drm_mode_config *mode_config = &dev->mode_config;
+	struct drm_connector *connector;
+	int i;
+
+	for_each_hpd_pin(i) {
+		dev_priv->hotplug.stats[i].count = 0;
+		dev_priv->hotplug.stats[i].state = HPD_ENABLED;
+	}
+	list_for_each_entry(connector, &mode_config->connector_list, head) {
+		struct intel_connector *intel_connector = to_intel_connector(connector);
+		connector->polled = intel_connector->polled;
+
+		/* MST has a dynamic intel_connector->encoder and it's reprobing
+		 * is all handled by the MST helpers. */
+		if (intel_connector->mst_port)
+			continue;
+
+		if (!connector->polled && I915_HAS_HOTPLUG(dev) &&
+		    intel_connector->encoder->hpd_pin > HPD_NONE)
+			connector->polled = DRM_CONNECTOR_POLL_HPD;
+	}
+
+	/*
+	 * Interrupt setup is already guaranteed to be single-threaded, this is
+	 * just to make the assert_spin_locked checks happy.
+	 */
+	spin_lock_irq(&dev_priv->irq_lock);
+	if (dev_priv->display.hpd_irq_setup)
+		dev_priv->display.hpd_irq_setup(dev);
+	spin_unlock_irq(&dev_priv->irq_lock);
+}
+
+void intel_hpd_init_work(struct drm_i915_private *dev_priv)
+{
+	INIT_WORK(&dev_priv->hotplug.hotplug_work, i915_hotplug_work_func);
+	INIT_WORK(&dev_priv->hotplug.dig_port_work, i915_digport_work_func);
+	INIT_DELAYED_WORK(&dev_priv->hotplug.reenable_work,
+			  intel_hpd_irq_storm_reenable_work);
+}
+
+void intel_hpd_cancel_work(struct drm_i915_private *dev_priv)
+{
+	spin_lock_irq(&dev_priv->irq_lock);
+
+	dev_priv->hotplug.long_port_mask = 0;
+	dev_priv->hotplug.short_port_mask = 0;
+	dev_priv->hotplug.event_bits = 0;
+
+	spin_unlock_irq(&dev_priv->irq_lock);
+
+	cancel_work_sync(&dev_priv->hotplug.dig_port_work);
+	cancel_work_sync(&dev_priv->hotplug.hotplug_work);
+	cancel_delayed_work_sync(&dev_priv->hotplug.reenable_work);
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/i915/intel_i2c.c
@@ -0,0 +1,750 @@
+/*
+ * Copyright (c) 2006 Dave Airlie <airlied@linux.ie>
+ * Copyright © 2006-2008,2010 Intel Corporation
+ *   Jesse Barnes <jesse.barnes@intel.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *	Eric Anholt <eric@anholt.net>
+ *	Chris Wilson <chris@chris-wilson.co.uk>
+ */
+#include <linux/i2c.h>
+#include <linux/i2c-algo-bit.h>
+#include <linux/export.h>
+#include <drm/drmP.h>
+#include "intel_drv.h"
+#include <drm/i915_drm.h>
+#include "i915_drv.h"
+
+struct gmbus_pin {
+	const char *name;
+	i915_reg_t reg;
+};
+
+/* Map gmbus pin pairs to names and registers. */
+static const struct gmbus_pin gmbus_pins[] = {
+	[GMBUS_PIN_SSC] = { "ssc", GPIOB },
+	[GMBUS_PIN_VGADDC] = { "vga", GPIOA },
+	[GMBUS_PIN_PANEL] = { "panel", GPIOC },
+	[GMBUS_PIN_DPC] = { "dpc", GPIOD },
+	[GMBUS_PIN_DPB] = { "dpb", GPIOE },
+	[GMBUS_PIN_DPD] = { "dpd", GPIOF },
+};
+
+static const struct gmbus_pin gmbus_pins_bdw[] = {
+	[GMBUS_PIN_VGADDC] = { "vga", GPIOA },
+	[GMBUS_PIN_DPC] = { "dpc", GPIOD },
+	[GMBUS_PIN_DPB] = { "dpb", GPIOE },
+	[GMBUS_PIN_DPD] = { "dpd", GPIOF },
+};
+
+static const struct gmbus_pin gmbus_pins_skl[] = {
+	[GMBUS_PIN_DPC] = { "dpc", GPIOD },
+	[GMBUS_PIN_DPB] = { "dpb", GPIOE },
+	[GMBUS_PIN_DPD] = { "dpd", GPIOF },
+};
+
+static const struct gmbus_pin gmbus_pins_bxt[] = {
+	[GMBUS_PIN_1_BXT] = { "dpb", GPIOB },
+	[GMBUS_PIN_2_BXT] = { "dpc", GPIOC },
+	[GMBUS_PIN_3_BXT] = { "misc", GPIOD },
+};
+
+/* pin is expected to be valid */
+static const struct gmbus_pin *get_gmbus_pin(struct drm_i915_private *dev_priv,
+					     unsigned int pin)
+{
+	if (IS_BROXTON(dev_priv))
+		return &gmbus_pins_bxt[pin];
+	else if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv))
+		return &gmbus_pins_skl[pin];
+	else if (IS_BROADWELL(dev_priv))
+		return &gmbus_pins_bdw[pin];
+	else
+		return &gmbus_pins[pin];
+}
+
+bool intel_gmbus_is_valid_pin(struct drm_i915_private *dev_priv,
+			      unsigned int pin)
+{
+	unsigned int size;
+
+	if (IS_BROXTON(dev_priv))
+		size = ARRAY_SIZE(gmbus_pins_bxt);
+	else if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv))
+		size = ARRAY_SIZE(gmbus_pins_skl);
+	else if (IS_BROADWELL(dev_priv))
+		size = ARRAY_SIZE(gmbus_pins_bdw);
+	else
+		size = ARRAY_SIZE(gmbus_pins);
+
+	return pin < size &&
+		i915_mmio_reg_valid(get_gmbus_pin(dev_priv, pin)->reg);
+}
+
+/* Intel GPIO access functions */
+
+#define I2C_RISEFALL_TIME 10
+
+static inline struct intel_gmbus *
+to_intel_gmbus(struct i2c_adapter *i2c)
+{
+	return container_of(i2c, struct intel_gmbus, adapter);
+}
+
+void
+intel_i2c_reset(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	I915_WRITE(GMBUS0, 0);
+	I915_WRITE(GMBUS4, 0);
+}
+
+static void intel_i2c_quirk_set(struct drm_i915_private *dev_priv, bool enable)
+{
+	u32 val;
+
+	/* When using bit bashing for I2C, this bit needs to be set to 1 */
+	if (!IS_PINEVIEW(dev_priv))
+		return;
+
+	val = I915_READ(DSPCLK_GATE_D);
+	if (enable)
+		val |= DPCUNIT_CLOCK_GATE_DISABLE;
+	else
+		val &= ~DPCUNIT_CLOCK_GATE_DISABLE;
+	I915_WRITE(DSPCLK_GATE_D, val);
+}
+
+static u32 get_reserved(struct intel_gmbus *bus)
+{
+	struct drm_i915_private *dev_priv = bus->dev_priv;
+	struct drm_device *dev = dev_priv->dev;
+	u32 reserved = 0;
+
+	/* On most chips, these bits must be preserved in software. */
+	if (!IS_I830(dev) && !IS_845G(dev))
+		reserved = I915_READ_NOTRACE(bus->gpio_reg) &
+					     (GPIO_DATA_PULLUP_DISABLE |
+					      GPIO_CLOCK_PULLUP_DISABLE);
+
+	return reserved;
+}
+
+static int get_clock(void *data)
+{
+	struct intel_gmbus *bus = data;
+	struct drm_i915_private *dev_priv = bus->dev_priv;
+	u32 reserved = get_reserved(bus);
+	I915_WRITE_NOTRACE(bus->gpio_reg, reserved | GPIO_CLOCK_DIR_MASK);
+	I915_WRITE_NOTRACE(bus->gpio_reg, reserved);
+	return (I915_READ_NOTRACE(bus->gpio_reg) & GPIO_CLOCK_VAL_IN) != 0;
+}
+
+static int get_data(void *data)
+{
+	struct intel_gmbus *bus = data;
+	struct drm_i915_private *dev_priv = bus->dev_priv;
+	u32 reserved = get_reserved(bus);
+	I915_WRITE_NOTRACE(bus->gpio_reg, reserved | GPIO_DATA_DIR_MASK);
+	I915_WRITE_NOTRACE(bus->gpio_reg, reserved);
+	return (I915_READ_NOTRACE(bus->gpio_reg) & GPIO_DATA_VAL_IN) != 0;
+}
+
+static void set_clock(void *data, int state_high)
+{
+	struct intel_gmbus *bus = data;
+	struct drm_i915_private *dev_priv = bus->dev_priv;
+	u32 reserved = get_reserved(bus);
+	u32 clock_bits;
+
+	if (state_high)
+		clock_bits = GPIO_CLOCK_DIR_IN | GPIO_CLOCK_DIR_MASK;
+	else
+		clock_bits = GPIO_CLOCK_DIR_OUT | GPIO_CLOCK_DIR_MASK |
+			GPIO_CLOCK_VAL_MASK;
+
+	I915_WRITE_NOTRACE(bus->gpio_reg, reserved | clock_bits);
+	POSTING_READ(bus->gpio_reg);
+}
+
+static void set_data(void *data, int state_high)
+{
+	struct intel_gmbus *bus = data;
+	struct drm_i915_private *dev_priv = bus->dev_priv;
+	u32 reserved = get_reserved(bus);
+	u32 data_bits;
+
+	if (state_high)
+		data_bits = GPIO_DATA_DIR_IN | GPIO_DATA_DIR_MASK;
+	else
+		data_bits = GPIO_DATA_DIR_OUT | GPIO_DATA_DIR_MASK |
+			GPIO_DATA_VAL_MASK;
+
+	I915_WRITE_NOTRACE(bus->gpio_reg, reserved | data_bits);
+	POSTING_READ(bus->gpio_reg);
+}
+
+static int
+intel_gpio_pre_xfer(struct i2c_adapter *adapter)
+{
+	struct intel_gmbus *bus = container_of(adapter,
+					       struct intel_gmbus,
+					       adapter);
+	struct drm_i915_private *dev_priv = bus->dev_priv;
+
+	intel_i2c_reset(dev_priv->dev);
+	intel_i2c_quirk_set(dev_priv, true);
+	set_data(bus, 1);
+	set_clock(bus, 1);
+	udelay(I2C_RISEFALL_TIME);
+	return 0;
+}
+
+static void
+intel_gpio_post_xfer(struct i2c_adapter *adapter)
+{
+	struct intel_gmbus *bus = container_of(adapter,
+					       struct intel_gmbus,
+					       adapter);
+	struct drm_i915_private *dev_priv = bus->dev_priv;
+
+	set_data(bus, 1);
+	set_clock(bus, 1);
+	intel_i2c_quirk_set(dev_priv, false);
+}
+
+static void
+intel_gpio_setup(struct intel_gmbus *bus, unsigned int pin)
+{
+	struct drm_i915_private *dev_priv = bus->dev_priv;
+	struct i2c_algo_bit_data *algo;
+
+	algo = &bus->bit_algo;
+
+	bus->gpio_reg = _MMIO(dev_priv->gpio_mmio_base +
+			      i915_mmio_reg_offset(get_gmbus_pin(dev_priv, pin)->reg));
+	bus->adapter.algo_data = algo;
+	algo->setsda = set_data;
+	algo->setscl = set_clock;
+	algo->getsda = get_data;
+	algo->getscl = get_clock;
+	algo->pre_xfer = intel_gpio_pre_xfer;
+	algo->post_xfer = intel_gpio_post_xfer;
+	algo->udelay = I2C_RISEFALL_TIME;
+	algo->timeout = usecs_to_jiffies(2200);
+	algo->data = bus;
+}
+
+static int
+gmbus_wait_hw_status(struct drm_i915_private *dev_priv,
+		     u32 gmbus2_status,
+		     u32 gmbus4_irq_en)
+{
+	int i;
+	u32 gmbus2 = 0;
+	DEFINE_WAIT(wait);
+
+	if (!HAS_GMBUS_IRQ(dev_priv))
+		gmbus4_irq_en = 0;
+
+	/* Important: The hw handles only the first bit, so set only one! Since
+	 * we also need to check for NAKs besides the hw ready/idle signal, we
+	 * need to wake up periodically and check that ourselves. */
+	I915_WRITE(GMBUS4, gmbus4_irq_en);
+
+	for (i = 0; i < msecs_to_jiffies_timeout(50); i++) {
+		prepare_to_wait(&dev_priv->gmbus_wait_queue, &wait,
+				TASK_UNINTERRUPTIBLE);
+
+		gmbus2 = I915_READ_NOTRACE(GMBUS2);
+		if (gmbus2 & (GMBUS_SATOER | gmbus2_status))
+			break;
+
+		schedule_timeout(1);
+	}
+	finish_wait(&dev_priv->gmbus_wait_queue, &wait);
+
+	I915_WRITE(GMBUS4, 0);
+
+	if (gmbus2 & GMBUS_SATOER)
+		return -ENXIO;
+	if (gmbus2 & gmbus2_status)
+		return 0;
+	return -ETIMEDOUT;
+}
+
+static int
+gmbus_wait_idle(struct drm_i915_private *dev_priv)
+{
+	int ret;
+
+#define C ((I915_READ_NOTRACE(GMBUS2) & GMBUS_ACTIVE) == 0)
+
+	if (!HAS_GMBUS_IRQ(dev_priv))
+		return wait_for(C, 10);
+
+	/* Important: The hw handles only the first bit, so set only one! */
+	I915_WRITE(GMBUS4, GMBUS_IDLE_EN);
+
+	ret = wait_event_timeout(dev_priv->gmbus_wait_queue, C,
+				 msecs_to_jiffies_timeout(10));
+
+	I915_WRITE(GMBUS4, 0);
+
+	if (ret)
+		return 0;
+	else
+		return -ETIMEDOUT;
+#undef C
+}
+
+static int
+gmbus_xfer_read_chunk(struct drm_i915_private *dev_priv,
+		      unsigned short addr, u8 *buf, unsigned int len,
+		      u32 gmbus1_index)
+{
+	I915_WRITE(GMBUS1,
+		   gmbus1_index |
+		   GMBUS_CYCLE_WAIT |
+		   (len << GMBUS_BYTE_COUNT_SHIFT) |
+		   (addr << GMBUS_SLAVE_ADDR_SHIFT) |
+		   GMBUS_SLAVE_READ | GMBUS_SW_RDY);
+	while (len) {
+		int ret;
+		u32 val, loop = 0;
+
+		ret = gmbus_wait_hw_status(dev_priv, GMBUS_HW_RDY,
+					   GMBUS_HW_RDY_EN);
+		if (ret)
+			return ret;
+
+		val = I915_READ(GMBUS3);
+		do {
+			*buf++ = val & 0xff;
+			val >>= 8;
+		} while (--len && ++loop < 4);
+	}
+
+	return 0;
+}
+
+static int
+gmbus_xfer_read(struct drm_i915_private *dev_priv, struct i2c_msg *msg,
+		u32 gmbus1_index)
+{
+	u8 *buf = msg->buf;
+	unsigned int rx_size = msg->len;
+	unsigned int len;
+	int ret;
+
+	do {
+		len = min(rx_size, GMBUS_BYTE_COUNT_MAX);
+
+		ret = gmbus_xfer_read_chunk(dev_priv, msg->addr,
+					    buf, len, gmbus1_index);
+		if (ret)
+			return ret;
+
+		rx_size -= len;
+		buf += len;
+	} while (rx_size != 0);
+
+	return 0;
+}
+
+static int
+gmbus_xfer_write_chunk(struct drm_i915_private *dev_priv,
+		       unsigned short addr, u8 *buf, unsigned int len)
+{
+	unsigned int chunk_size = len;
+	u32 val, loop;
+
+	val = loop = 0;
+	while (len && loop < 4) {
+		val |= *buf++ << (8 * loop++);
+		len -= 1;
+	}
+
+	I915_WRITE(GMBUS3, val);
+	I915_WRITE(GMBUS1,
+		   GMBUS_CYCLE_WAIT |
+		   (chunk_size << GMBUS_BYTE_COUNT_SHIFT) |
+		   (addr << GMBUS_SLAVE_ADDR_SHIFT) |
+		   GMBUS_SLAVE_WRITE | GMBUS_SW_RDY);
+	while (len) {
+		int ret;
+
+		val = loop = 0;
+		do {
+			val |= *buf++ << (8 * loop);
+		} while (--len && ++loop < 4);
+
+		I915_WRITE(GMBUS3, val);
+
+		ret = gmbus_wait_hw_status(dev_priv, GMBUS_HW_RDY,
+					   GMBUS_HW_RDY_EN);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
+static int
+gmbus_xfer_write(struct drm_i915_private *dev_priv, struct i2c_msg *msg)
+{
+	u8 *buf = msg->buf;
+	unsigned int tx_size = msg->len;
+	unsigned int len;
+	int ret;
+
+	do {
+		len = min(tx_size, GMBUS_BYTE_COUNT_MAX);
+
+		ret = gmbus_xfer_write_chunk(dev_priv, msg->addr, buf, len);
+		if (ret)
+			return ret;
+
+		buf += len;
+		tx_size -= len;
+	} while (tx_size != 0);
+
+	return 0;
+}
+
+/*
+ * The gmbus controller can combine a 1 or 2 byte write with a read that
+ * immediately follows it by using an "INDEX" cycle.
+ */
+static bool
+gmbus_is_index_read(struct i2c_msg *msgs, int i, int num)
+{
+	return (i + 1 < num &&
+		!(msgs[i].flags & I2C_M_RD) && msgs[i].len <= 2 &&
+		(msgs[i + 1].flags & I2C_M_RD));
+}
+
+static int
+gmbus_xfer_index_read(struct drm_i915_private *dev_priv, struct i2c_msg *msgs)
+{
+	u32 gmbus1_index = 0;
+	u32 gmbus5 = 0;
+	int ret;
+
+	if (msgs[0].len == 2)
+		gmbus5 = GMBUS_2BYTE_INDEX_EN |
+			 msgs[0].buf[1] | (msgs[0].buf[0] << 8);
+	if (msgs[0].len == 1)
+		gmbus1_index = GMBUS_CYCLE_INDEX |
+			       (msgs[0].buf[0] << GMBUS_SLAVE_INDEX_SHIFT);
+
+	/* GMBUS5 holds 16-bit index */
+	if (gmbus5)
+		I915_WRITE(GMBUS5, gmbus5);
+
+	ret = gmbus_xfer_read(dev_priv, &msgs[1], gmbus1_index);
+
+	/* Clear GMBUS5 after each index transfer */
+	if (gmbus5)
+		I915_WRITE(GMBUS5, 0);
+
+	return ret;
+}
+
+static int
+do_gmbus_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int num)
+{
+	struct intel_gmbus *bus = container_of(adapter,
+					       struct intel_gmbus,
+					       adapter);
+	struct drm_i915_private *dev_priv = bus->dev_priv;
+	int i = 0, inc, try = 0;
+	int ret = 0;
+
+retry:
+	I915_WRITE(GMBUS0, bus->reg0);
+
+	for (; i < num; i += inc) {
+		inc = 1;
+		if (gmbus_is_index_read(msgs, i, num)) {
+			ret = gmbus_xfer_index_read(dev_priv, &msgs[i]);
+			inc = 2; /* an index read is two msgs */
+		} else if (msgs[i].flags & I2C_M_RD) {
+			ret = gmbus_xfer_read(dev_priv, &msgs[i], 0);
+		} else {
+			ret = gmbus_xfer_write(dev_priv, &msgs[i]);
+		}
+
+		if (!ret)
+			ret = gmbus_wait_hw_status(dev_priv, GMBUS_HW_WAIT_PHASE,
+						   GMBUS_HW_WAIT_EN);
+		if (ret == -ETIMEDOUT)
+			goto timeout;
+		else if (ret)
+			goto clear_err;
+	}
+
+	/* Generate a STOP condition on the bus. Note that gmbus can't generata
+	 * a STOP on the very first cycle. To simplify the code we
+	 * unconditionally generate the STOP condition with an additional gmbus
+	 * cycle. */
+	I915_WRITE(GMBUS1, GMBUS_CYCLE_STOP | GMBUS_SW_RDY);
+
+	/* Mark the GMBUS interface as disabled after waiting for idle.
+	 * We will re-enable it at the start of the next xfer,
+	 * till then let it sleep.
+	 */
+	if (gmbus_wait_idle(dev_priv)) {
+		DRM_DEBUG_KMS("GMBUS [%s] timed out waiting for idle\n",
+			 adapter->name);
+		ret = -ETIMEDOUT;
+	}
+	I915_WRITE(GMBUS0, 0);
+	ret = ret ?: i;
+	goto out;
+
+clear_err:
+	/*
+	 * Wait for bus to IDLE before clearing NAK.
+	 * If we clear the NAK while bus is still active, then it will stay
+	 * active and the next transaction may fail.
+	 *
+	 * If no ACK is received during the address phase of a transaction, the
+	 * adapter must report -ENXIO. It is not clear what to return if no ACK
+	 * is received at other times. But we have to be careful to not return
+	 * spurious -ENXIO because that will prevent i2c and drm edid functions
+	 * from retrying. So return -ENXIO only when gmbus properly quiescents -
+	 * timing out seems to happen when there _is_ a ddc chip present, but
+	 * it's slow responding and only answers on the 2nd retry.
+	 */
+	ret = -ENXIO;
+	if (gmbus_wait_idle(dev_priv)) {
+		DRM_DEBUG_KMS("GMBUS [%s] timed out after NAK\n",
+			      adapter->name);
+		ret = -ETIMEDOUT;
+	}
+
+	/* Toggle the Software Clear Interrupt bit. This has the effect
+	 * of resetting the GMBUS controller and so clearing the
+	 * BUS_ERROR raised by the slave's NAK.
+	 */
+	I915_WRITE(GMBUS1, GMBUS_SW_CLR_INT);
+	I915_WRITE(GMBUS1, 0);
+	I915_WRITE(GMBUS0, 0);
+
+	DRM_DEBUG_KMS("GMBUS [%s] NAK for addr: %04x %c(%d)\n",
+			 adapter->name, msgs[i].addr,
+			 (msgs[i].flags & I2C_M_RD) ? 'r' : 'w', msgs[i].len);
+
+	/*
+	 * Passive adapters sometimes NAK the first probe. Retry the first
+	 * message once on -ENXIO for GMBUS transfers; the bit banging algorithm
+	 * has retries internally. See also the retry loop in
+	 * drm_do_probe_ddc_edid, which bails out on the first -ENXIO.
+	 */
+	if (ret == -ENXIO && i == 0 && try++ == 0) {
+		DRM_DEBUG_KMS("GMBUS [%s] NAK on first message, retry\n",
+			      adapter->name);
+		goto retry;
+	}
+
+	goto out;
+
+timeout:
+	DRM_DEBUG_KMS("GMBUS [%s] timed out, falling back to bit banging on pin %d\n",
+		      bus->adapter.name, bus->reg0 & 0xff);
+	I915_WRITE(GMBUS0, 0);
+
+	/*
+	 * Hardware may not support GMBUS over these pins? Try GPIO bitbanging
+	 * instead. Use EAGAIN to have i2c core retry.
+	 */
+	ret = -EAGAIN;
+
+out:
+	return ret;
+}
+
+static int
+gmbus_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int num)
+{
+	struct intel_gmbus *bus = container_of(adapter, struct intel_gmbus,
+					       adapter);
+	struct drm_i915_private *dev_priv = bus->dev_priv;
+	int ret;
+
+	intel_display_power_get(dev_priv, POWER_DOMAIN_GMBUS);
+	mutex_lock(&dev_priv->gmbus_mutex);
+
+	if (bus->force_bit) {
+		ret = i2c_bit_algo.master_xfer(adapter, msgs, num);
+		if (ret < 0)
+			bus->force_bit &= ~GMBUS_FORCE_BIT_RETRY;
+	} else {
+		ret = do_gmbus_xfer(adapter, msgs, num);
+		if (ret == -EAGAIN)
+			bus->force_bit |= GMBUS_FORCE_BIT_RETRY;
+	}
+
+	mutex_unlock(&dev_priv->gmbus_mutex);
+	intel_display_power_put(dev_priv, POWER_DOMAIN_GMBUS);
+
+	return ret;
+}
+
+static u32 gmbus_func(struct i2c_adapter *adapter)
+{
+	return i2c_bit_algo.functionality(adapter) &
+		(I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL |
+		/* I2C_FUNC_10BIT_ADDR | */
+		I2C_FUNC_SMBUS_READ_BLOCK_DATA |
+		I2C_FUNC_SMBUS_BLOCK_PROC_CALL);
+}
+
+static const struct i2c_algorithm gmbus_algorithm = {
+	.master_xfer	= gmbus_xfer,
+	.functionality	= gmbus_func
+};
+
+/**
+ * intel_gmbus_setup - instantiate all Intel i2c GMBuses
+ * @dev: DRM device
+ */
+int intel_setup_gmbus(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_gmbus *bus;
+	unsigned int pin;
+	int ret;
+
+	if (HAS_PCH_NOP(dev))
+		return 0;
+
+	if (IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev))
+		dev_priv->gpio_mmio_base = VLV_DISPLAY_BASE;
+	else if (!HAS_GMCH_DISPLAY(dev_priv))
+		dev_priv->gpio_mmio_base =
+			i915_mmio_reg_offset(PCH_GPIOA) -
+			i915_mmio_reg_offset(GPIOA);
+
+	mutex_init(&dev_priv->gmbus_mutex);
+	init_waitqueue_head(&dev_priv->gmbus_wait_queue);
+
+	for (pin = 0; pin < ARRAY_SIZE(dev_priv->gmbus); pin++) {
+		if (!intel_gmbus_is_valid_pin(dev_priv, pin))
+			continue;
+
+		bus = &dev_priv->gmbus[pin];
+
+		bus->adapter.owner = THIS_MODULE;
+		bus->adapter.class = I2C_CLASS_DDC;
+		snprintf(bus->adapter.name,
+			 sizeof(bus->adapter.name),
+			 "i915 gmbus %s",
+			 get_gmbus_pin(dev_priv, pin)->name);
+
+		bus->adapter.dev.parent = &dev->pdev->dev;
+		bus->dev_priv = dev_priv;
+
+		bus->adapter.algo = &gmbus_algorithm;
+
+		/*
+		 * We wish to retry with bit banging
+		 * after a timed out GMBUS attempt.
+		 */
+		bus->adapter.retries = 1;
+
+		/* By default use a conservative clock rate */
+		bus->reg0 = pin | GMBUS_RATE_100KHZ;
+
+		/* gmbus seems to be broken on i830 */
+		if (IS_I830(dev))
+			bus->force_bit = 1;
+
+		intel_gpio_setup(bus, pin);
+
+		ret = i2c_add_adapter(&bus->adapter);
+		if (ret)
+			goto err;
+	}
+
+	intel_i2c_reset(dev_priv->dev);
+
+	return 0;
+
+err:
+	while (pin--) {
+		if (!intel_gmbus_is_valid_pin(dev_priv, pin))
+			continue;
+
+		bus = &dev_priv->gmbus[pin];
+		i2c_del_adapter(&bus->adapter);
+	}
+	return ret;
+}
+
+struct i2c_adapter *intel_gmbus_get_adapter(struct drm_i915_private *dev_priv,
+					    unsigned int pin)
+{
+	if (WARN_ON(!intel_gmbus_is_valid_pin(dev_priv, pin)))
+		return NULL;
+
+	return &dev_priv->gmbus[pin].adapter;
+}
+
+void intel_gmbus_set_speed(struct i2c_adapter *adapter, int speed)
+{
+	struct intel_gmbus *bus = to_intel_gmbus(adapter);
+
+	bus->reg0 = (bus->reg0 & ~(0x3 << 8)) | speed;
+}
+
+void intel_gmbus_force_bit(struct i2c_adapter *adapter, bool force_bit)
+{
+	struct intel_gmbus *bus = to_intel_gmbus(adapter);
+	struct drm_i915_private *dev_priv = bus->dev_priv;
+
+	mutex_lock(&dev_priv->gmbus_mutex);
+
+	bus->force_bit += force_bit ? 1 : -1;
+	DRM_DEBUG_KMS("%sabling bit-banging on %s. force bit now %d\n",
+		      force_bit ? "en" : "dis", adapter->name,
+		      bus->force_bit);
+
+	mutex_unlock(&dev_priv->gmbus_mutex);
+}
+
+void intel_teardown_gmbus(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_gmbus *bus;
+	unsigned int pin;
+
+	for (pin = 0; pin < ARRAY_SIZE(dev_priv->gmbus); pin++) {
+		if (!intel_gmbus_is_valid_pin(dev_priv, pin))
+			continue;
+
+		bus = &dev_priv->gmbus[pin];
+		i2c_del_adapter(&bus->adapter);
+	}
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/i915/intel_lrc.c
@@ -0,0 +1,2672 @@
+/*
+ * Copyright © 2014 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Ben Widawsky <ben@bwidawsk.net>
+ *    Michel Thierry <michel.thierry@intel.com>
+ *    Thomas Daniel <thomas.daniel@intel.com>
+ *    Oscar Mateo <oscar.mateo@intel.com>
+ *
+ */
+
+/**
+ * DOC: Logical Rings, Logical Ring Contexts and Execlists
+ *
+ * Motivation:
+ * GEN8 brings an expansion of the HW contexts: "Logical Ring Contexts".
+ * These expanded contexts enable a number of new abilities, especially
+ * "Execlists" (also implemented in this file).
+ *
+ * One of the main differences with the legacy HW contexts is that logical
+ * ring contexts incorporate many more things to the context's state, like
+ * PDPs or ringbuffer control registers:
+ *
+ * The reason why PDPs are included in the context is straightforward: as
+ * PPGTTs (per-process GTTs) are actually per-context, having the PDPs
+ * contained there mean you don't need to do a ppgtt->switch_mm yourself,
+ * instead, the GPU will do it for you on the context switch.
+ *
+ * But, what about the ringbuffer control registers (head, tail, etc..)?
+ * shouldn't we just need a set of those per engine command streamer? This is
+ * where the name "Logical Rings" starts to make sense: by virtualizing the
+ * rings, the engine cs shifts to a new "ring buffer" with every context
+ * switch. When you want to submit a workload to the GPU you: A) choose your
+ * context, B) find its appropriate virtualized ring, C) write commands to it
+ * and then, finally, D) tell the GPU to switch to that context.
+ *
+ * Instead of the legacy MI_SET_CONTEXT, the way you tell the GPU to switch
+ * to a contexts is via a context execution list, ergo "Execlists".
+ *
+ * LRC implementation:
+ * Regarding the creation of contexts, we have:
+ *
+ * - One global default context.
+ * - One local default context for each opened fd.
+ * - One local extra context for each context create ioctl call.
+ *
+ * Now that ringbuffers belong per-context (and not per-engine, like before)
+ * and that contexts are uniquely tied to a given engine (and not reusable,
+ * like before) we need:
+ *
+ * - One ringbuffer per-engine inside each context.
+ * - One backing object per-engine inside each context.
+ *
+ * The global default context starts its life with these new objects fully
+ * allocated and populated. The local default context for each opened fd is
+ * more complex, because we don't know at creation time which engine is going
+ * to use them. To handle this, we have implemented a deferred creation of LR
+ * contexts:
+ *
+ * The local context starts its life as a hollow or blank holder, that only
+ * gets populated for a given engine once we receive an execbuffer. If later
+ * on we receive another execbuffer ioctl for the same context but a different
+ * engine, we allocate/populate a new ringbuffer and context backing object and
+ * so on.
+ *
+ * Finally, regarding local contexts created using the ioctl call: as they are
+ * only allowed with the render ring, we can allocate & populate them right
+ * away (no need to defer anything, at least for now).
+ *
+ * Execlists implementation:
+ * Execlists are the new method by which, on gen8+ hardware, workloads are
+ * submitted for execution (as opposed to the legacy, ringbuffer-based, method).
+ * This method works as follows:
+ *
+ * When a request is committed, its commands (the BB start and any leading or
+ * trailing commands, like the seqno breadcrumbs) are placed in the ringbuffer
+ * for the appropriate context. The tail pointer in the hardware context is not
+ * updated at this time, but instead, kept by the driver in the ringbuffer
+ * structure. A structure representing this request is added to a request queue
+ * for the appropriate engine: this structure contains a copy of the context's
+ * tail after the request was written to the ring buffer and a pointer to the
+ * context itself.
+ *
+ * If the engine's request queue was empty before the request was added, the
+ * queue is processed immediately. Otherwise the queue will be processed during
+ * a context switch interrupt. In any case, elements on the queue will get sent
+ * (in pairs) to the GPU's ExecLists Submit Port (ELSP, for short) with a
+ * globally unique 20-bits submission ID.
+ *
+ * When execution of a request completes, the GPU updates the context status
+ * buffer with a context complete event and generates a context switch interrupt.
+ * During the interrupt handling, the driver examines the events in the buffer:
+ * for each context complete event, if the announced ID matches that on the head
+ * of the request queue, then that request is retired and removed from the queue.
+ *
+ * After processing, if any requests were retired and the queue is not empty
+ * then a new execution list can be submitted. The two requests at the front of
+ * the queue are next to be submitted but since a context may not occur twice in
+ * an execution list, if subsequent requests have the same ID as the first then
+ * the two requests must be combined. This is done simply by discarding requests
+ * at the head of the queue until either only one requests is left (in which case
+ * we use a NULL second context) or the first two requests have unique IDs.
+ *
+ * By always executing the first two requests in the queue the driver ensures
+ * that the GPU is kept as busy as possible. In the case where a single context
+ * completes but a second context is still executing, the request for this second
+ * context will be at the head of the queue when we remove the first one. This
+ * request will then be resubmitted along with a new request for a different context,
+ * which will cause the hardware to continue executing the second request and queue
+ * the new request (the GPU detects the condition of a context getting preempted
+ * with the same context and optimizes the context switch flow by not doing
+ * preemption, but just sampling the new tail pointer).
+ *
+ */
+#include <linux/interrupt.h>
+
+#include <drm/drmP.h>
+#include <drm/i915_drm.h>
+#include "i915_drv.h"
+#include "intel_mocs.h"
+
+#define GEN9_LR_CONTEXT_RENDER_SIZE (22 * PAGE_SIZE)
+#define GEN8_LR_CONTEXT_RENDER_SIZE (20 * PAGE_SIZE)
+#define GEN8_LR_CONTEXT_OTHER_SIZE (2 * PAGE_SIZE)
+
+#define RING_EXECLIST_QFULL		(1 << 0x2)
+#define RING_EXECLIST1_VALID		(1 << 0x3)
+#define RING_EXECLIST0_VALID		(1 << 0x4)
+#define RING_EXECLIST_ACTIVE_STATUS	(3 << 0xE)
+#define RING_EXECLIST1_ACTIVE		(1 << 0x11)
+#define RING_EXECLIST0_ACTIVE		(1 << 0x12)
+
+#define GEN8_CTX_STATUS_IDLE_ACTIVE	(1 << 0)
+#define GEN8_CTX_STATUS_PREEMPTED	(1 << 1)
+#define GEN8_CTX_STATUS_ELEMENT_SWITCH	(1 << 2)
+#define GEN8_CTX_STATUS_ACTIVE_IDLE	(1 << 3)
+#define GEN8_CTX_STATUS_COMPLETE	(1 << 4)
+#define GEN8_CTX_STATUS_LITE_RESTORE	(1 << 15)
+
+#define CTX_LRI_HEADER_0		0x01
+#define CTX_CONTEXT_CONTROL		0x02
+#define CTX_RING_HEAD			0x04
+#define CTX_RING_TAIL			0x06
+#define CTX_RING_BUFFER_START		0x08
+#define CTX_RING_BUFFER_CONTROL		0x0a
+#define CTX_BB_HEAD_U			0x0c
+#define CTX_BB_HEAD_L			0x0e
+#define CTX_BB_STATE			0x10
+#define CTX_SECOND_BB_HEAD_U		0x12
+#define CTX_SECOND_BB_HEAD_L		0x14
+#define CTX_SECOND_BB_STATE		0x16
+#define CTX_BB_PER_CTX_PTR		0x18
+#define CTX_RCS_INDIRECT_CTX		0x1a
+#define CTX_RCS_INDIRECT_CTX_OFFSET	0x1c
+#define CTX_LRI_HEADER_1		0x21
+#define CTX_CTX_TIMESTAMP		0x22
+#define CTX_PDP3_UDW			0x24
+#define CTX_PDP3_LDW			0x26
+#define CTX_PDP2_UDW			0x28
+#define CTX_PDP2_LDW			0x2a
+#define CTX_PDP1_UDW			0x2c
+#define CTX_PDP1_LDW			0x2e
+#define CTX_PDP0_UDW			0x30
+#define CTX_PDP0_LDW			0x32
+#define CTX_LRI_HEADER_2		0x41
+#define CTX_R_PWR_CLK_STATE		0x42
+#define CTX_GPGPU_CSR_BASE_ADDRESS	0x44
+
+#define GEN8_CTX_VALID (1<<0)
+#define GEN8_CTX_FORCE_PD_RESTORE (1<<1)
+#define GEN8_CTX_FORCE_RESTORE (1<<2)
+#define GEN8_CTX_L3LLC_COHERENT (1<<5)
+#define GEN8_CTX_PRIVILEGE (1<<8)
+
+#define ASSIGN_CTX_REG(reg_state, pos, reg, val) do { \
+	(reg_state)[(pos)+0] = i915_mmio_reg_offset(reg); \
+	(reg_state)[(pos)+1] = (val); \
+} while (0)
+
+#define ASSIGN_CTX_PDP(ppgtt, reg_state, n) do {		\
+	const u64 _addr = i915_page_dir_dma_addr((ppgtt), (n));	\
+	reg_state[CTX_PDP ## n ## _UDW+1] = upper_32_bits(_addr); \
+	reg_state[CTX_PDP ## n ## _LDW+1] = lower_32_bits(_addr); \
+} while (0)
+
+#define ASSIGN_CTX_PML4(ppgtt, reg_state) do { \
+	reg_state[CTX_PDP0_UDW + 1] = upper_32_bits(px_dma(&ppgtt->pml4)); \
+	reg_state[CTX_PDP0_LDW + 1] = lower_32_bits(px_dma(&ppgtt->pml4)); \
+} while (0)
+
+enum {
+	ADVANCED_CONTEXT = 0,
+	LEGACY_32B_CONTEXT,
+	ADVANCED_AD_CONTEXT,
+	LEGACY_64B_CONTEXT
+};
+#define GEN8_CTX_ADDRESSING_MODE_SHIFT 3
+#define GEN8_CTX_ADDRESSING_MODE(dev)  (USES_FULL_48BIT_PPGTT(dev) ?\
+		LEGACY_64B_CONTEXT :\
+		LEGACY_32B_CONTEXT)
+enum {
+	FAULT_AND_HANG = 0,
+	FAULT_AND_HALT, /* Debug only */
+	FAULT_AND_STREAM,
+	FAULT_AND_CONTINUE /* Unsupported */
+};
+#define GEN8_CTX_ID_SHIFT 32
+#define GEN8_CTX_RCS_INDIRECT_CTX_OFFSET_DEFAULT	0x17
+#define GEN9_CTX_RCS_INDIRECT_CTX_OFFSET_DEFAULT	0x26
+
+static int intel_lr_context_pin(struct intel_context *ctx,
+				struct intel_engine_cs *engine);
+
+/**
+ * intel_sanitize_enable_execlists() - sanitize i915.enable_execlists
+ * @dev: DRM device.
+ * @enable_execlists: value of i915.enable_execlists module parameter.
+ *
+ * Only certain platforms support Execlists (the prerequisites being
+ * support for Logical Ring Contexts and Aliasing PPGTT or better).
+ *
+ * Return: 1 if Execlists is supported and has to be enabled.
+ */
+int intel_sanitize_enable_execlists(struct drm_device *dev, int enable_execlists)
+{
+	WARN_ON(i915.enable_ppgtt == -1);
+
+	/* On platforms with execlist available, vGPU will only
+	 * support execlist mode, no ring buffer mode.
+	 */
+	if (HAS_LOGICAL_RING_CONTEXTS(dev) && intel_vgpu_active(dev))
+		return 1;
+
+	if (INTEL_INFO(dev)->gen >= 9)
+		return 1;
+
+	if (enable_execlists == 0)
+		return 0;
+
+	if (HAS_LOGICAL_RING_CONTEXTS(dev) && USES_PPGTT(dev) &&
+	    i915.use_mmio_flip >= 0)
+		return 1;
+
+	return 0;
+}
+
+static void
+logical_ring_init_platform_invariants(struct intel_engine_cs *engine)
+{
+	struct drm_device *dev = engine->dev;
+
+	if (IS_GEN8(dev) || IS_GEN9(dev))
+		engine->idle_lite_restore_wa = ~0;
+
+	engine->disable_lite_restore_wa = (IS_SKL_REVID(dev, 0, SKL_REVID_B0) ||
+					IS_BXT_REVID(dev, 0, BXT_REVID_A1)) &&
+					(engine->id == VCS || engine->id == VCS2);
+
+	engine->ctx_desc_template = GEN8_CTX_VALID;
+	engine->ctx_desc_template |= GEN8_CTX_ADDRESSING_MODE(dev) <<
+				   GEN8_CTX_ADDRESSING_MODE_SHIFT;
+	if (IS_GEN8(dev))
+		engine->ctx_desc_template |= GEN8_CTX_L3LLC_COHERENT;
+	engine->ctx_desc_template |= GEN8_CTX_PRIVILEGE;
+
+	/* TODO: WaDisableLiteRestore when we start using semaphore
+	 * signalling between Command Streamers */
+	/* ring->ctx_desc_template |= GEN8_CTX_FORCE_RESTORE; */
+
+	/* WaEnableForceRestoreInCtxtDescForVCS:skl */
+	/* WaEnableForceRestoreInCtxtDescForVCS:bxt */
+	if (engine->disable_lite_restore_wa)
+		engine->ctx_desc_template |= GEN8_CTX_FORCE_RESTORE;
+}
+
+/**
+ * intel_lr_context_descriptor_update() - calculate & cache the descriptor
+ * 					  descriptor for a pinned context
+ *
+ * @ctx: Context to work on
+ * @ring: Engine the descriptor will be used with
+ *
+ * The context descriptor encodes various attributes of a context,
+ * including its GTT address and some flags. Because it's fairly
+ * expensive to calculate, we'll just do it once and cache the result,
+ * which remains valid until the context is unpinned.
+ *
+ * This is what a descriptor looks like, from LSB to MSB:
+ *    bits 0-11:    flags, GEN8_CTX_* (cached in ctx_desc_template)
+ *    bits 12-31:    LRCA, GTT address of (the HWSP of) this context
+ *    bits 32-51:    ctx ID, a globally unique tag (the LRCA again!)
+ *    bits 52-63:    reserved, may encode the engine ID (for GuC)
+ */
+static void
+intel_lr_context_descriptor_update(struct intel_context *ctx,
+				   struct intel_engine_cs *engine)
+{
+	uint64_t lrca, desc;
+
+	lrca = ctx->engine[engine->id].lrc_vma->node.start +
+	       LRC_PPHWSP_PN * PAGE_SIZE;
+
+	desc = engine->ctx_desc_template;			   /* bits  0-11 */
+	desc |= lrca;					   /* bits 12-31 */
+	desc |= (lrca >> PAGE_SHIFT) << GEN8_CTX_ID_SHIFT; /* bits 32-51 */
+
+	ctx->engine[engine->id].lrc_desc = desc;
+}
+
+uint64_t intel_lr_context_descriptor(struct intel_context *ctx,
+				     struct intel_engine_cs *engine)
+{
+	return ctx->engine[engine->id].lrc_desc;
+}
+
+/**
+ * intel_execlists_ctx_id() - get the Execlists Context ID
+ * @ctx: Context to get the ID for
+ * @ring: Engine to get the ID for
+ *
+ * Do not confuse with ctx->id! Unfortunately we have a name overload
+ * here: the old context ID we pass to userspace as a handler so that
+ * they can refer to a context, and the new context ID we pass to the
+ * ELSP so that the GPU can inform us of the context status via
+ * interrupts.
+ *
+ * The context ID is a portion of the context descriptor, so we can
+ * just extract the required part from the cached descriptor.
+ *
+ * Return: 20-bits globally unique context ID.
+ */
+u32 intel_execlists_ctx_id(struct intel_context *ctx,
+			   struct intel_engine_cs *engine)
+{
+	return intel_lr_context_descriptor(ctx, engine) >> GEN8_CTX_ID_SHIFT;
+}
+
+static void execlists_elsp_write(struct drm_i915_gem_request *rq0,
+				 struct drm_i915_gem_request *rq1)
+{
+
+	struct intel_engine_cs *engine = rq0->engine;
+	struct drm_device *dev = engine->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	uint64_t desc[2];
+
+	if (rq1) {
+		desc[1] = intel_lr_context_descriptor(rq1->ctx, rq1->engine);
+		rq1->elsp_submitted++;
+	} else {
+		desc[1] = 0;
+	}
+
+	desc[0] = intel_lr_context_descriptor(rq0->ctx, rq0->engine);
+	rq0->elsp_submitted++;
+
+	/* You must always write both descriptors in the order below. */
+	I915_WRITE_FW(RING_ELSP(engine), upper_32_bits(desc[1]));
+	I915_WRITE_FW(RING_ELSP(engine), lower_32_bits(desc[1]));
+
+	I915_WRITE_FW(RING_ELSP(engine), upper_32_bits(desc[0]));
+	/* The context is automatically loaded after the following */
+	I915_WRITE_FW(RING_ELSP(engine), lower_32_bits(desc[0]));
+
+	/* ELSP is a wo register, use another nearby reg for posting */
+	POSTING_READ_FW(RING_EXECLIST_STATUS_LO(engine));
+}
+
+static void
+execlists_update_context_pdps(struct i915_hw_ppgtt *ppgtt, u32 *reg_state)
+{
+	ASSIGN_CTX_PDP(ppgtt, reg_state, 3);
+	ASSIGN_CTX_PDP(ppgtt, reg_state, 2);
+	ASSIGN_CTX_PDP(ppgtt, reg_state, 1);
+	ASSIGN_CTX_PDP(ppgtt, reg_state, 0);
+}
+
+static void execlists_update_context(struct drm_i915_gem_request *rq)
+{
+	struct intel_engine_cs *engine = rq->engine;
+	struct i915_hw_ppgtt *ppgtt = rq->ctx->ppgtt;
+	uint32_t *reg_state = rq->ctx->engine[engine->id].lrc_reg_state;
+
+	reg_state[CTX_RING_TAIL+1] = rq->tail;
+
+	/* True 32b PPGTT with dynamic page allocation: update PDP
+	 * registers and point the unallocated PDPs to scratch page.
+	 * PML4 is allocated during ppgtt init, so this is not needed
+	 * in 48-bit mode.
+	 */
+	if (ppgtt && !USES_FULL_48BIT_PPGTT(ppgtt->base.dev))
+		execlists_update_context_pdps(ppgtt, reg_state);
+}
+
+static void execlists_submit_requests(struct drm_i915_gem_request *rq0,
+				      struct drm_i915_gem_request *rq1)
+{
+	struct drm_i915_private *dev_priv = rq0->i915;
+	unsigned int fw_domains = rq0->engine->fw_domains;
+
+	execlists_update_context(rq0);
+
+	if (rq1)
+		execlists_update_context(rq1);
+
+	spin_lock_irq(&dev_priv->uncore.lock);
+	intel_uncore_forcewake_get__locked(dev_priv, fw_domains);
+
+	execlists_elsp_write(rq0, rq1);
+
+	intel_uncore_forcewake_put__locked(dev_priv, fw_domains);
+	spin_unlock_irq(&dev_priv->uncore.lock);
+}
+
+static void execlists_context_unqueue(struct intel_engine_cs *engine)
+{
+	struct drm_i915_gem_request *req0 = NULL, *req1 = NULL;
+	struct drm_i915_gem_request *cursor, *tmp;
+
+	assert_spin_locked(&engine->execlist_lock);
+
+	/*
+	 * If irqs are not active generate a warning as batches that finish
+	 * without the irqs may get lost and a GPU Hang may occur.
+	 */
+	WARN_ON(!intel_irqs_enabled(engine->dev->dev_private));
+
+	/* Try to read in pairs */
+	list_for_each_entry_safe(cursor, tmp, &engine->execlist_queue,
+				 execlist_link) {
+		if (!req0) {
+			req0 = cursor;
+		} else if (req0->ctx == cursor->ctx) {
+			/* Same ctx: ignore first request, as second request
+			 * will update tail past first request's workload */
+			cursor->elsp_submitted = req0->elsp_submitted;
+			list_move_tail(&req0->execlist_link,
+				       &engine->execlist_retired_req_list);
+			req0 = cursor;
+		} else {
+			req1 = cursor;
+			WARN_ON(req1->elsp_submitted);
+			break;
+		}
+	}
+
+	if (unlikely(!req0))
+		return;
+
+	if (req0->elsp_submitted & engine->idle_lite_restore_wa) {
+		/*
+		 * WaIdleLiteRestore: make sure we never cause a lite restore
+		 * with HEAD==TAIL.
+		 *
+		 * Apply the wa NOOPS to prevent ring:HEAD == req:TAIL as we
+		 * resubmit the request. See gen8_emit_request() for where we
+		 * prepare the padding after the end of the request.
+		 */
+		struct intel_ringbuffer *ringbuf;
+
+		ringbuf = req0->ctx->engine[engine->id].ringbuf;
+		req0->tail += 8;
+		req0->tail &= ringbuf->size - 1;
+	}
+
+	execlists_submit_requests(req0, req1);
+}
+
+static unsigned int
+execlists_check_remove_request(struct intel_engine_cs *engine, u32 request_id)
+{
+	struct drm_i915_gem_request *head_req;
+
+	assert_spin_locked(&engine->execlist_lock);
+
+	head_req = list_first_entry_or_null(&engine->execlist_queue,
+					    struct drm_i915_gem_request,
+					    execlist_link);
+
+	if (!head_req)
+		return 0;
+
+	if (unlikely(intel_execlists_ctx_id(head_req->ctx, engine) != request_id))
+		return 0;
+
+	WARN(head_req->elsp_submitted == 0, "Never submitted head request\n");
+
+	if (--head_req->elsp_submitted > 0)
+		return 0;
+
+	list_move_tail(&head_req->execlist_link,
+		       &engine->execlist_retired_req_list);
+
+	return 1;
+}
+
+static u32
+get_context_status(struct intel_engine_cs *engine, unsigned int read_pointer,
+		   u32 *context_id)
+{
+	struct drm_i915_private *dev_priv = engine->dev->dev_private;
+	u32 status;
+
+	read_pointer %= GEN8_CSB_ENTRIES;
+
+	status = I915_READ_FW(RING_CONTEXT_STATUS_BUF_LO(engine, read_pointer));
+
+	if (status & GEN8_CTX_STATUS_IDLE_ACTIVE)
+		return 0;
+
+	*context_id = I915_READ_FW(RING_CONTEXT_STATUS_BUF_HI(engine,
+							      read_pointer));
+
+	return status;
+}
+
+/**
+ * intel_lrc_irq_handler() - handle Context Switch interrupts
+ * @engine: Engine Command Streamer to handle.
+ *
+ * Check the unread Context Status Buffers and manage the submission of new
+ * contexts to the ELSP accordingly.
+ */
+static void intel_lrc_irq_handler(unsigned long data)
+{
+	struct intel_engine_cs *engine = (struct intel_engine_cs *)data;
+	struct drm_i915_private *dev_priv = engine->dev->dev_private;
+	u32 status_pointer;
+	unsigned int read_pointer, write_pointer;
+	u32 csb[GEN8_CSB_ENTRIES][2];
+	unsigned int csb_read = 0, i;
+	unsigned int submit_contexts = 0;
+
+	intel_uncore_forcewake_get(dev_priv, engine->fw_domains);
+
+	status_pointer = I915_READ_FW(RING_CONTEXT_STATUS_PTR(engine));
+
+	read_pointer = engine->next_context_status_buffer;
+	write_pointer = GEN8_CSB_WRITE_PTR(status_pointer);
+	if (read_pointer > write_pointer)
+		write_pointer += GEN8_CSB_ENTRIES;
+
+	while (read_pointer < write_pointer) {
+		if (WARN_ON_ONCE(csb_read == GEN8_CSB_ENTRIES))
+			break;
+		csb[csb_read][0] = get_context_status(engine, ++read_pointer,
+						      &csb[csb_read][1]);
+		csb_read++;
+	}
+
+	engine->next_context_status_buffer = write_pointer % GEN8_CSB_ENTRIES;
+
+	/* Update the read pointer to the old write pointer. Manual ringbuffer
+	 * management ftw </sarcasm> */
+	I915_WRITE_FW(RING_CONTEXT_STATUS_PTR(engine),
+		      _MASKED_FIELD(GEN8_CSB_READ_PTR_MASK,
+				    engine->next_context_status_buffer << 8));
+
+	intel_uncore_forcewake_put(dev_priv, engine->fw_domains);
+
+	spin_lock(&engine->execlist_lock);
+
+	for (i = 0; i < csb_read; i++) {
+		if (unlikely(csb[i][0] & GEN8_CTX_STATUS_PREEMPTED)) {
+			if (csb[i][0] & GEN8_CTX_STATUS_LITE_RESTORE) {
+				if (execlists_check_remove_request(engine, csb[i][1]))
+					WARN(1, "Lite Restored request removed from queue\n");
+			} else
+				WARN(1, "Preemption without Lite Restore\n");
+		}
+
+		if (csb[i][0] & (GEN8_CTX_STATUS_ACTIVE_IDLE |
+		    GEN8_CTX_STATUS_ELEMENT_SWITCH))
+			submit_contexts +=
+				execlists_check_remove_request(engine, csb[i][1]);
+	}
+
+	if (submit_contexts) {
+		if (!engine->disable_lite_restore_wa ||
+		    (csb[i][0] & GEN8_CTX_STATUS_ACTIVE_IDLE))
+			execlists_context_unqueue(engine);
+	}
+
+	spin_unlock(&engine->execlist_lock);
+
+	if (unlikely(submit_contexts > 2))
+		DRM_ERROR("More than two context complete events?\n");
+}
+
+static void execlists_context_queue(struct drm_i915_gem_request *request)
+{
+	struct intel_engine_cs *engine = request->engine;
+	struct drm_i915_gem_request *cursor;
+	int num_elements = 0;
+
+	if (request->ctx != request->i915->kernel_context)
+		intel_lr_context_pin(request->ctx, engine);
+
+	i915_gem_request_reference(request);
+
+	spin_lock_bh(&engine->execlist_lock);
+
+	list_for_each_entry(cursor, &engine->execlist_queue, execlist_link)
+		if (++num_elements > 2)
+			break;
+
+	if (num_elements > 2) {
+		struct drm_i915_gem_request *tail_req;
+
+		tail_req = list_last_entry(&engine->execlist_queue,
+					   struct drm_i915_gem_request,
+					   execlist_link);
+
+		if (request->ctx == tail_req->ctx) {
+			WARN(tail_req->elsp_submitted != 0,
+				"More than 2 already-submitted reqs queued\n");
+			list_move_tail(&tail_req->execlist_link,
+				       &engine->execlist_retired_req_list);
+		}
+	}
+
+	list_add_tail(&request->execlist_link, &engine->execlist_queue);
+	if (num_elements == 0)
+		execlists_context_unqueue(engine);
+
+	spin_unlock_bh(&engine->execlist_lock);
+}
+
+static int logical_ring_invalidate_all_caches(struct drm_i915_gem_request *req)
+{
+	struct intel_engine_cs *engine = req->engine;
+	uint32_t flush_domains;
+	int ret;
+
+	flush_domains = 0;
+	if (engine->gpu_caches_dirty)
+		flush_domains = I915_GEM_GPU_DOMAINS;
+
+	ret = engine->emit_flush(req, I915_GEM_GPU_DOMAINS, flush_domains);
+	if (ret)
+		return ret;
+
+	engine->gpu_caches_dirty = false;
+	return 0;
+}
+
+static int execlists_move_to_gpu(struct drm_i915_gem_request *req,
+				 struct list_head *vmas)
+{
+	const unsigned other_rings = ~intel_engine_flag(req->engine);
+	struct i915_vma *vma;
+	uint32_t flush_domains = 0;
+	bool flush_chipset = false;
+	int ret;
+
+	list_for_each_entry(vma, vmas, exec_list) {
+		struct drm_i915_gem_object *obj = vma->obj;
+
+		if (obj->active & other_rings) {
+			ret = i915_gem_object_sync(obj, req->engine, &req);
+			if (ret)
+				return ret;
+		}
+
+		if (obj->base.write_domain & I915_GEM_DOMAIN_CPU)
+			flush_chipset |= i915_gem_clflush_object(obj, false);
+
+		flush_domains |= obj->base.write_domain;
+	}
+
+	if (flush_domains & I915_GEM_DOMAIN_GTT)
+		wmb();
+
+	/* Unconditionally invalidate gpu caches and ensure that we do flush
+	 * any residual writes from the previous batch.
+	 */
+	return logical_ring_invalidate_all_caches(req);
+}
+
+int intel_logical_ring_alloc_request_extras(struct drm_i915_gem_request *request)
+{
+	int ret = 0;
+
+	request->ringbuf = request->ctx->engine[request->engine->id].ringbuf;
+
+	if (i915.enable_guc_submission) {
+		/*
+		 * Check that the GuC has space for the request before
+		 * going any further, as the i915_add_request() call
+		 * later on mustn't fail ...
+		 */
+		struct intel_guc *guc = &request->i915->guc;
+
+		ret = i915_guc_wq_check_space(guc->execbuf_client);
+		if (ret)
+			return ret;
+	}
+
+	if (request->ctx != request->i915->kernel_context)
+		ret = intel_lr_context_pin(request->ctx, request->engine);
+
+	return ret;
+}
+
+/*
+ * intel_logical_ring_advance_and_submit() - advance the tail and submit the workload
+ * @request: Request to advance the logical ringbuffer of.
+ *
+ * The tail is updated in our logical ringbuffer struct, not in the actual context. What
+ * really happens during submission is that the context and current tail will be placed
+ * on a queue waiting for the ELSP to be ready to accept a new context submission. At that
+ * point, the tail *inside* the context is updated and the ELSP written to.
+ */
+static int
+intel_logical_ring_advance_and_submit(struct drm_i915_gem_request *request)
+{
+	struct intel_ringbuffer *ringbuf = request->ringbuf;
+	struct drm_i915_private *dev_priv = request->i915;
+	struct intel_engine_cs *engine = request->engine;
+
+	intel_logical_ring_advance(ringbuf);
+	request->tail = ringbuf->tail;
+
+	/*
+	 * Here we add two extra NOOPs as padding to avoid
+	 * lite restore of a context with HEAD==TAIL.
+	 *
+	 * Caller must reserve WA_TAIL_DWORDS for us!
+	 */
+	intel_logical_ring_emit(ringbuf, MI_NOOP);
+	intel_logical_ring_emit(ringbuf, MI_NOOP);
+	intel_logical_ring_advance(ringbuf);
+
+	if (intel_engine_stopped(engine))
+		return 0;
+
+	if (engine->last_context != request->ctx) {
+		if (engine->last_context)
+			intel_lr_context_unpin(engine->last_context, engine);
+		if (request->ctx != request->i915->kernel_context) {
+			intel_lr_context_pin(request->ctx, engine);
+			engine->last_context = request->ctx;
+		} else {
+			engine->last_context = NULL;
+		}
+	}
+
+	if (dev_priv->guc.execbuf_client)
+		i915_guc_submit(dev_priv->guc.execbuf_client, request);
+	else
+		execlists_context_queue(request);
+
+	return 0;
+}
+
+int intel_logical_ring_reserve_space(struct drm_i915_gem_request *request)
+{
+	/*
+	 * The first call merely notes the reserve request and is common for
+	 * all back ends. The subsequent localised _begin() call actually
+	 * ensures that the reservation is available. Without the begin, if
+	 * the request creator immediately submitted the request without
+	 * adding any commands to it then there might not actually be
+	 * sufficient room for the submission commands.
+	 */
+	intel_ring_reserved_space_reserve(request->ringbuf, MIN_SPACE_FOR_ADD_REQUEST);
+
+	return intel_ring_begin(request, 0);
+}
+
+/**
+ * execlists_submission() - submit a batchbuffer for execution, Execlists style
+ * @dev: DRM device.
+ * @file: DRM file.
+ * @ring: Engine Command Streamer to submit to.
+ * @ctx: Context to employ for this submission.
+ * @args: execbuffer call arguments.
+ * @vmas: list of vmas.
+ * @batch_obj: the batchbuffer to submit.
+ * @exec_start: batchbuffer start virtual address pointer.
+ * @dispatch_flags: translated execbuffer call flags.
+ *
+ * This is the evil twin version of i915_gem_ringbuffer_submission. It abstracts
+ * away the submission details of the execbuffer ioctl call.
+ *
+ * Return: non-zero if the submission fails.
+ */
+int intel_execlists_submission(struct i915_execbuffer_params *params,
+			       struct drm_i915_gem_execbuffer2 *args,
+			       struct list_head *vmas)
+{
+	struct drm_device       *dev = params->dev;
+	struct intel_engine_cs *engine = params->engine;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_ringbuffer *ringbuf = params->ctx->engine[engine->id].ringbuf;
+	u64 exec_start;
+	int instp_mode;
+	u32 instp_mask;
+	int ret;
+
+	instp_mode = args->flags & I915_EXEC_CONSTANTS_MASK;
+	instp_mask = I915_EXEC_CONSTANTS_MASK;
+	switch (instp_mode) {
+	case I915_EXEC_CONSTANTS_REL_GENERAL:
+	case I915_EXEC_CONSTANTS_ABSOLUTE:
+	case I915_EXEC_CONSTANTS_REL_SURFACE:
+		if (instp_mode != 0 && engine != &dev_priv->engine[RCS]) {
+			DRM_DEBUG("non-0 rel constants mode on non-RCS\n");
+			return -EINVAL;
+		}
+
+		if (instp_mode != dev_priv->relative_constants_mode) {
+			if (instp_mode == I915_EXEC_CONSTANTS_REL_SURFACE) {
+				DRM_DEBUG("rel surface constants mode invalid on gen5+\n");
+				return -EINVAL;
+			}
+
+			/* The HW changed the meaning on this bit on gen6 */
+			instp_mask &= ~I915_EXEC_CONSTANTS_REL_SURFACE;
+		}
+		break;
+	default:
+		DRM_DEBUG("execbuf with unknown constants: %d\n", instp_mode);
+		return -EINVAL;
+	}
+
+	if (args->flags & I915_EXEC_GEN7_SOL_RESET) {
+		DRM_DEBUG("sol reset is gen7 only\n");
+		return -EINVAL;
+	}
+
+	ret = execlists_move_to_gpu(params->request, vmas);
+	if (ret)
+		return ret;
+
+	if (engine == &dev_priv->engine[RCS] &&
+	    instp_mode != dev_priv->relative_constants_mode) {
+		ret = intel_ring_begin(params->request, 4);
+		if (ret)
+			return ret;
+
+		intel_logical_ring_emit(ringbuf, MI_NOOP);
+		intel_logical_ring_emit(ringbuf, MI_LOAD_REGISTER_IMM(1));
+		intel_logical_ring_emit_reg(ringbuf, INSTPM);
+		intel_logical_ring_emit(ringbuf, instp_mask << 16 | instp_mode);
+		intel_logical_ring_advance(ringbuf);
+
+		dev_priv->relative_constants_mode = instp_mode;
+	}
+
+	exec_start = params->batch_obj_vm_offset +
+		     args->batch_start_offset;
+
+	ret = engine->emit_bb_start(params->request, exec_start, params->dispatch_flags);
+	if (ret)
+		return ret;
+
+	trace_i915_gem_ring_dispatch(params->request, params->dispatch_flags);
+
+	i915_gem_execbuffer_move_to_active(vmas, params->request);
+
+	return 0;
+}
+
+void intel_execlists_retire_requests(struct intel_engine_cs *engine)
+{
+	struct drm_i915_gem_request *req, *tmp;
+	struct list_head retired_list;
+
+	WARN_ON(!mutex_is_locked(&engine->dev->struct_mutex));
+	if (list_empty(&engine->execlist_retired_req_list))
+		return;
+
+	INIT_LIST_HEAD(&retired_list);
+	spin_lock_bh(&engine->execlist_lock);
+	list_replace_init(&engine->execlist_retired_req_list, &retired_list);
+	spin_unlock_bh(&engine->execlist_lock);
+
+	list_for_each_entry_safe(req, tmp, &retired_list, execlist_link) {
+		struct intel_context *ctx = req->ctx;
+		struct drm_i915_gem_object *ctx_obj =
+				ctx->engine[engine->id].state;
+
+		if (ctx_obj && (ctx != req->i915->kernel_context))
+			intel_lr_context_unpin(ctx, engine);
+
+		list_del(&req->execlist_link);
+		i915_gem_request_unreference(req);
+	}
+}
+
+void intel_logical_ring_stop(struct intel_engine_cs *engine)
+{
+	struct drm_i915_private *dev_priv = engine->dev->dev_private;
+	int ret;
+
+	if (!intel_engine_initialized(engine))
+		return;
+
+	ret = intel_engine_idle(engine);
+	if (ret)
+		DRM_ERROR("failed to quiesce %s whilst cleaning up: %d\n",
+			  engine->name, ret);
+
+	/* TODO: Is this correct with Execlists enabled? */
+	I915_WRITE_MODE(engine, _MASKED_BIT_ENABLE(STOP_RING));
+	if (wait_for((I915_READ_MODE(engine) & MODE_IDLE) != 0, 1000)) {
+		DRM_ERROR("%s :timed out trying to stop ring\n", engine->name);
+		return;
+	}
+	I915_WRITE_MODE(engine, _MASKED_BIT_DISABLE(STOP_RING));
+}
+
+int logical_ring_flush_all_caches(struct drm_i915_gem_request *req)
+{
+	struct intel_engine_cs *engine = req->engine;
+	int ret;
+
+	if (!engine->gpu_caches_dirty)
+		return 0;
+
+	ret = engine->emit_flush(req, 0, I915_GEM_GPU_DOMAINS);
+	if (ret)
+		return ret;
+
+	engine->gpu_caches_dirty = false;
+	return 0;
+}
+
+static int intel_lr_context_do_pin(struct intel_context *ctx,
+				   struct intel_engine_cs *engine)
+{
+	struct drm_device *dev = engine->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct drm_i915_gem_object *ctx_obj = ctx->engine[engine->id].state;
+	struct intel_ringbuffer *ringbuf = ctx->engine[engine->id].ringbuf;
+	void *vaddr;
+	u32 *lrc_reg_state;
+	int ret;
+
+	WARN_ON(!mutex_is_locked(&engine->dev->struct_mutex));
+
+	ret = i915_gem_obj_ggtt_pin(ctx_obj, GEN8_LR_CONTEXT_ALIGN,
+			PIN_OFFSET_BIAS | GUC_WOPCM_TOP);
+	if (ret)
+		return ret;
+
+	vaddr = i915_gem_object_pin_map(ctx_obj);
+	if (IS_ERR(vaddr)) {
+		ret = PTR_ERR(vaddr);
+		goto unpin_ctx_obj;
+	}
+
+	lrc_reg_state = vaddr + LRC_STATE_PN * PAGE_SIZE;
+
+	ret = intel_pin_and_map_ringbuffer_obj(engine->dev, ringbuf);
+	if (ret)
+		goto unpin_map;
+
+	ctx->engine[engine->id].lrc_vma = i915_gem_obj_to_ggtt(ctx_obj);
+	intel_lr_context_descriptor_update(ctx, engine);
+	lrc_reg_state[CTX_RING_BUFFER_START+1] = ringbuf->vma->node.start;
+	ctx->engine[engine->id].lrc_reg_state = lrc_reg_state;
+	ctx_obj->dirty = true;
+
+	/* Invalidate GuC TLB. */
+	if (i915.enable_guc_submission)
+		I915_WRITE(GEN8_GTCR, GEN8_GTCR_INVALIDATE);
+
+	return ret;
+
+unpin_map:
+	i915_gem_object_unpin_map(ctx_obj);
+unpin_ctx_obj:
+	i915_gem_object_ggtt_unpin(ctx_obj);
+
+	return ret;
+}
+
+static int intel_lr_context_pin(struct intel_context *ctx,
+				struct intel_engine_cs *engine)
+{
+	int ret = 0;
+
+	if (ctx->engine[engine->id].pin_count++ == 0) {
+		ret = intel_lr_context_do_pin(ctx, engine);
+		if (ret)
+			goto reset_pin_count;
+
+		i915_gem_context_reference(ctx);
+	}
+	return ret;
+
+reset_pin_count:
+	ctx->engine[engine->id].pin_count = 0;
+	return ret;
+}
+
+void intel_lr_context_unpin(struct intel_context *ctx,
+			    struct intel_engine_cs *engine)
+{
+	struct drm_i915_gem_object *ctx_obj = ctx->engine[engine->id].state;
+
+	WARN_ON(!mutex_is_locked(&ctx->i915->dev->struct_mutex));
+	if (--ctx->engine[engine->id].pin_count == 0) {
+		i915_gem_object_unpin_map(ctx_obj);
+		intel_unpin_ringbuffer_obj(ctx->engine[engine->id].ringbuf);
+		i915_gem_object_ggtt_unpin(ctx_obj);
+		ctx->engine[engine->id].lrc_vma = NULL;
+		ctx->engine[engine->id].lrc_desc = 0;
+		ctx->engine[engine->id].lrc_reg_state = NULL;
+
+		i915_gem_context_unreference(ctx);
+	}
+}
+
+static int intel_logical_ring_workarounds_emit(struct drm_i915_gem_request *req)
+{
+	int ret, i;
+	struct intel_engine_cs *engine = req->engine;
+	struct intel_ringbuffer *ringbuf = req->ringbuf;
+	struct drm_device *dev = engine->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct i915_workarounds *w = &dev_priv->workarounds;
+
+	if (w->count == 0)
+		return 0;
+
+	engine->gpu_caches_dirty = true;
+	ret = logical_ring_flush_all_caches(req);
+	if (ret)
+		return ret;
+
+	ret = intel_ring_begin(req, w->count * 2 + 2);
+	if (ret)
+		return ret;
+
+	intel_logical_ring_emit(ringbuf, MI_LOAD_REGISTER_IMM(w->count));
+	for (i = 0; i < w->count; i++) {
+		intel_logical_ring_emit_reg(ringbuf, w->reg[i].addr);
+		intel_logical_ring_emit(ringbuf, w->reg[i].value);
+	}
+	intel_logical_ring_emit(ringbuf, MI_NOOP);
+
+	intel_logical_ring_advance(ringbuf);
+
+	engine->gpu_caches_dirty = true;
+	ret = logical_ring_flush_all_caches(req);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+#define wa_ctx_emit(batch, index, cmd)					\
+	do {								\
+		int __index = (index)++;				\
+		if (WARN_ON(__index >= (PAGE_SIZE / sizeof(uint32_t)))) { \
+			return -ENOSPC;					\
+		}							\
+		batch[__index] = (cmd);					\
+	} while (0)
+
+#define wa_ctx_emit_reg(batch, index, reg) \
+	wa_ctx_emit((batch), (index), i915_mmio_reg_offset(reg))
+
+/*
+ * In this WA we need to set GEN8_L3SQCREG4[21:21] and reset it after
+ * PIPE_CONTROL instruction. This is required for the flush to happen correctly
+ * but there is a slight complication as this is applied in WA batch where the
+ * values are only initialized once so we cannot take register value at the
+ * beginning and reuse it further; hence we save its value to memory, upload a
+ * constant value with bit21 set and then we restore it back with the saved value.
+ * To simplify the WA, a constant value is formed by using the default value
+ * of this register. This shouldn't be a problem because we are only modifying
+ * it for a short period and this batch in non-premptible. We can ofcourse
+ * use additional instructions that read the actual value of the register
+ * at that time and set our bit of interest but it makes the WA complicated.
+ *
+ * This WA is also required for Gen9 so extracting as a function avoids
+ * code duplication.
+ */
+static inline int gen8_emit_flush_coherentl3_wa(struct intel_engine_cs *engine,
+						uint32_t *const batch,
+						uint32_t index)
+{
+	struct drm_i915_private *dev_priv = engine->dev->dev_private;
+	uint32_t l3sqc4_flush = (0x40400000 | GEN8_LQSC_FLUSH_COHERENT_LINES);
+
+	/*
+	 * WaDisableLSQCROPERFforOCL:skl,kbl
+	 * This WA is implemented in skl_init_clock_gating() but since
+	 * this batch updates GEN8_L3SQCREG4 with default value we need to
+	 * set this bit here to retain the WA during flush.
+	 */
+	if (IS_SKL_REVID(dev_priv, 0, SKL_REVID_E0) ||
+	    IS_KBL_REVID(dev_priv, 0, KBL_REVID_E0))
+		l3sqc4_flush |= GEN8_LQSC_RO_PERF_DIS;
+
+	wa_ctx_emit(batch, index, (MI_STORE_REGISTER_MEM_GEN8 |
+				   MI_SRM_LRM_GLOBAL_GTT));
+	wa_ctx_emit_reg(batch, index, GEN8_L3SQCREG4);
+	wa_ctx_emit(batch, index, engine->scratch.gtt_offset + 256);
+	wa_ctx_emit(batch, index, 0);
+
+	wa_ctx_emit(batch, index, MI_LOAD_REGISTER_IMM(1));
+	wa_ctx_emit_reg(batch, index, GEN8_L3SQCREG4);
+	wa_ctx_emit(batch, index, l3sqc4_flush);
+
+	wa_ctx_emit(batch, index, GFX_OP_PIPE_CONTROL(6));
+	wa_ctx_emit(batch, index, (PIPE_CONTROL_CS_STALL |
+				   PIPE_CONTROL_DC_FLUSH_ENABLE));
+	wa_ctx_emit(batch, index, 0);
+	wa_ctx_emit(batch, index, 0);
+	wa_ctx_emit(batch, index, 0);
+	wa_ctx_emit(batch, index, 0);
+
+	wa_ctx_emit(batch, index, (MI_LOAD_REGISTER_MEM_GEN8 |
+				   MI_SRM_LRM_GLOBAL_GTT));
+	wa_ctx_emit_reg(batch, index, GEN8_L3SQCREG4);
+	wa_ctx_emit(batch, index, engine->scratch.gtt_offset + 256);
+	wa_ctx_emit(batch, index, 0);
+
+	return index;
+}
+
+static inline uint32_t wa_ctx_start(struct i915_wa_ctx_bb *wa_ctx,
+				    uint32_t offset,
+				    uint32_t start_alignment)
+{
+	return wa_ctx->offset = ALIGN(offset, start_alignment);
+}
+
+static inline int wa_ctx_end(struct i915_wa_ctx_bb *wa_ctx,
+			     uint32_t offset,
+			     uint32_t size_alignment)
+{
+	wa_ctx->size = offset - wa_ctx->offset;
+
+	WARN(wa_ctx->size % size_alignment,
+	     "wa_ctx_bb failed sanity checks: size %d is not aligned to %d\n",
+	     wa_ctx->size, size_alignment);
+	return 0;
+}
+
+/**
+ * gen8_init_indirectctx_bb() - initialize indirect ctx batch with WA
+ *
+ * @ring: only applicable for RCS
+ * @wa_ctx: structure representing wa_ctx
+ *  offset: specifies start of the batch, should be cache-aligned. This is updated
+ *    with the offset value received as input.
+ *  size: size of the batch in DWORDS but HW expects in terms of cachelines
+ * @batch: page in which WA are loaded
+ * @offset: This field specifies the start of the batch, it should be
+ *  cache-aligned otherwise it is adjusted accordingly.
+ *  Typically we only have one indirect_ctx and per_ctx batch buffer which are
+ *  initialized at the beginning and shared across all contexts but this field
+ *  helps us to have multiple batches at different offsets and select them based
+ *  on a criteria. At the moment this batch always start at the beginning of the page
+ *  and at this point we don't have multiple wa_ctx batch buffers.
+ *
+ *  The number of WA applied are not known at the beginning; we use this field
+ *  to return the no of DWORDS written.
+ *
+ *  It is to be noted that this batch does not contain MI_BATCH_BUFFER_END
+ *  so it adds NOOPs as padding to make it cacheline aligned.
+ *  MI_BATCH_BUFFER_END will be added to perctx batch and both of them together
+ *  makes a complete batch buffer.
+ *
+ * Return: non-zero if we exceed the PAGE_SIZE limit.
+ */
+
+static int gen8_init_indirectctx_bb(struct intel_engine_cs *engine,
+				    struct i915_wa_ctx_bb *wa_ctx,
+				    uint32_t *const batch,
+				    uint32_t *offset)
+{
+	uint32_t scratch_addr;
+	uint32_t index = wa_ctx_start(wa_ctx, *offset, CACHELINE_DWORDS);
+
+	/* WaDisableCtxRestoreArbitration:bdw,chv */
+	wa_ctx_emit(batch, index, MI_ARB_ON_OFF | MI_ARB_DISABLE);
+
+	/* WaFlushCoherentL3CacheLinesAtContextSwitch:bdw */
+	if (IS_BROADWELL(engine->dev)) {
+		int rc = gen8_emit_flush_coherentl3_wa(engine, batch, index);
+		if (rc < 0)
+			return rc;
+		index = rc;
+	}
+
+	/* WaClearSlmSpaceAtContextSwitch:bdw,chv */
+	/* Actual scratch location is at 128 bytes offset */
+	scratch_addr = engine->scratch.gtt_offset + 2*CACHELINE_BYTES;
+
+	wa_ctx_emit(batch, index, GFX_OP_PIPE_CONTROL(6));
+	wa_ctx_emit(batch, index, (PIPE_CONTROL_FLUSH_L3 |
+				   PIPE_CONTROL_GLOBAL_GTT_IVB |
+				   PIPE_CONTROL_CS_STALL |
+				   PIPE_CONTROL_QW_WRITE));
+	wa_ctx_emit(batch, index, scratch_addr);
+	wa_ctx_emit(batch, index, 0);
+	wa_ctx_emit(batch, index, 0);
+	wa_ctx_emit(batch, index, 0);
+
+	/* Pad to end of cacheline */
+	while (index % CACHELINE_DWORDS)
+		wa_ctx_emit(batch, index, MI_NOOP);
+
+	/*
+	 * MI_BATCH_BUFFER_END is not required in Indirect ctx BB because
+	 * execution depends on the length specified in terms of cache lines
+	 * in the register CTX_RCS_INDIRECT_CTX
+	 */
+
+	return wa_ctx_end(wa_ctx, *offset = index, CACHELINE_DWORDS);
+}
+
+/**
+ * gen8_init_perctx_bb() - initialize per ctx batch with WA
+ *
+ * @ring: only applicable for RCS
+ * @wa_ctx: structure representing wa_ctx
+ *  offset: specifies start of the batch, should be cache-aligned.
+ *  size: size of the batch in DWORDS but HW expects in terms of cachelines
+ * @batch: page in which WA are loaded
+ * @offset: This field specifies the start of this batch.
+ *   This batch is started immediately after indirect_ctx batch. Since we ensure
+ *   that indirect_ctx ends on a cacheline this batch is aligned automatically.
+ *
+ *   The number of DWORDS written are returned using this field.
+ *
+ *  This batch is terminated with MI_BATCH_BUFFER_END and so we need not add padding
+ *  to align it with cacheline as padding after MI_BATCH_BUFFER_END is redundant.
+ */
+static int gen8_init_perctx_bb(struct intel_engine_cs *engine,
+			       struct i915_wa_ctx_bb *wa_ctx,
+			       uint32_t *const batch,
+			       uint32_t *offset)
+{
+	uint32_t index = wa_ctx_start(wa_ctx, *offset, CACHELINE_DWORDS);
+
+	/* WaDisableCtxRestoreArbitration:bdw,chv */
+	wa_ctx_emit(batch, index, MI_ARB_ON_OFF | MI_ARB_ENABLE);
+
+	wa_ctx_emit(batch, index, MI_BATCH_BUFFER_END);
+
+	return wa_ctx_end(wa_ctx, *offset = index, 1);
+}
+
+static int gen9_init_indirectctx_bb(struct intel_engine_cs *engine,
+				    struct i915_wa_ctx_bb *wa_ctx,
+				    uint32_t *const batch,
+				    uint32_t *offset)
+{
+	int ret;
+	struct drm_device *dev = engine->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	uint32_t index = wa_ctx_start(wa_ctx, *offset, CACHELINE_DWORDS);
+
+	/* WaDisableCtxRestoreArbitration:skl,bxt */
+	if (IS_SKL_REVID(dev, 0, SKL_REVID_D0) ||
+	    IS_BXT_REVID(dev, 0, BXT_REVID_A1))
+		wa_ctx_emit(batch, index, MI_ARB_ON_OFF | MI_ARB_DISABLE);
+
+	/* WaFlushCoherentL3CacheLinesAtContextSwitch:skl,bxt */
+	ret = gen8_emit_flush_coherentl3_wa(engine, batch, index);
+	if (ret < 0)
+		return ret;
+	index = ret;
+
+	/* WaClearSlmSpaceAtContextSwitch:kbl */
+	/* Actual scratch location is at 128 bytes offset */
+	if (IS_KBL_REVID(dev_priv, 0, KBL_REVID_A0)) {
+		uint32_t scratch_addr
+			= engine->scratch.gtt_offset + 2*CACHELINE_BYTES;
+
+		wa_ctx_emit(batch, index, GFX_OP_PIPE_CONTROL(6));
+		wa_ctx_emit(batch, index, (PIPE_CONTROL_FLUSH_L3 |
+					   PIPE_CONTROL_GLOBAL_GTT_IVB |
+					   PIPE_CONTROL_CS_STALL |
+					   PIPE_CONTROL_QW_WRITE));
+		wa_ctx_emit(batch, index, scratch_addr);
+		wa_ctx_emit(batch, index, 0);
+		wa_ctx_emit(batch, index, 0);
+		wa_ctx_emit(batch, index, 0);
+	}
+	/* Pad to end of cacheline */
+	while (index % CACHELINE_DWORDS)
+		wa_ctx_emit(batch, index, MI_NOOP);
+
+	return wa_ctx_end(wa_ctx, *offset = index, CACHELINE_DWORDS);
+}
+
+static int gen9_init_perctx_bb(struct intel_engine_cs *engine,
+			       struct i915_wa_ctx_bb *wa_ctx,
+			       uint32_t *const batch,
+			       uint32_t *offset)
+{
+	struct drm_device *dev = engine->dev;
+	uint32_t index = wa_ctx_start(wa_ctx, *offset, CACHELINE_DWORDS);
+
+	/* WaSetDisablePixMaskCammingAndRhwoInCommonSliceChicken:skl,bxt */
+	if (IS_SKL_REVID(dev, 0, SKL_REVID_B0) ||
+	    IS_BXT_REVID(dev, 0, BXT_REVID_A1)) {
+		wa_ctx_emit(batch, index, MI_LOAD_REGISTER_IMM(1));
+		wa_ctx_emit_reg(batch, index, GEN9_SLICE_COMMON_ECO_CHICKEN0);
+		wa_ctx_emit(batch, index,
+			    _MASKED_BIT_ENABLE(DISABLE_PIXEL_MASK_CAMMING));
+		wa_ctx_emit(batch, index, MI_NOOP);
+	}
+
+	/* WaClearTdlStateAckDirtyBits:bxt */
+	if (IS_BXT_REVID(dev, 0, BXT_REVID_B0)) {
+		wa_ctx_emit(batch, index, MI_LOAD_REGISTER_IMM(4));
+
+		wa_ctx_emit_reg(batch, index, GEN8_STATE_ACK);
+		wa_ctx_emit(batch, index, _MASKED_BIT_DISABLE(GEN9_SUBSLICE_TDL_ACK_BITS));
+
+		wa_ctx_emit_reg(batch, index, GEN9_STATE_ACK_SLICE1);
+		wa_ctx_emit(batch, index, _MASKED_BIT_DISABLE(GEN9_SUBSLICE_TDL_ACK_BITS));
+
+		wa_ctx_emit_reg(batch, index, GEN9_STATE_ACK_SLICE2);
+		wa_ctx_emit(batch, index, _MASKED_BIT_DISABLE(GEN9_SUBSLICE_TDL_ACK_BITS));
+
+		wa_ctx_emit_reg(batch, index, GEN7_ROW_CHICKEN2);
+		/* dummy write to CS, mask bits are 0 to ensure the register is not modified */
+		wa_ctx_emit(batch, index, 0x0);
+		wa_ctx_emit(batch, index, MI_NOOP);
+	}
+
+	/* WaDisableCtxRestoreArbitration:skl,bxt */
+	if (IS_SKL_REVID(dev, 0, SKL_REVID_D0) ||
+	    IS_BXT_REVID(dev, 0, BXT_REVID_A1))
+		wa_ctx_emit(batch, index, MI_ARB_ON_OFF | MI_ARB_ENABLE);
+
+	wa_ctx_emit(batch, index, MI_BATCH_BUFFER_END);
+
+	return wa_ctx_end(wa_ctx, *offset = index, 1);
+}
+
+static int lrc_setup_wa_ctx_obj(struct intel_engine_cs *engine, u32 size)
+{
+	int ret;
+
+	engine->wa_ctx.obj = i915_gem_alloc_object(engine->dev,
+						   PAGE_ALIGN(size));
+	if (!engine->wa_ctx.obj) {
+		DRM_DEBUG_DRIVER("alloc LRC WA ctx backing obj failed.\n");
+		return -ENOMEM;
+	}
+
+	ret = i915_gem_obj_ggtt_pin(engine->wa_ctx.obj, PAGE_SIZE, 0);
+	if (ret) {
+		DRM_DEBUG_DRIVER("pin LRC WA ctx backing obj failed: %d\n",
+				 ret);
+		drm_gem_object_unreference(&engine->wa_ctx.obj->base);
+		return ret;
+	}
+
+	return 0;
+}
+
+static void lrc_destroy_wa_ctx_obj(struct intel_engine_cs *engine)
+{
+	if (engine->wa_ctx.obj) {
+		i915_gem_object_ggtt_unpin(engine->wa_ctx.obj);
+		drm_gem_object_unreference(&engine->wa_ctx.obj->base);
+		engine->wa_ctx.obj = NULL;
+	}
+}
+
+static int intel_init_workaround_bb(struct intel_engine_cs *engine)
+{
+	int ret;
+	uint32_t *batch;
+	uint32_t offset;
+	struct page *page;
+	struct i915_ctx_workarounds *wa_ctx = &engine->wa_ctx;
+
+	WARN_ON(engine->id != RCS);
+
+	/* update this when WA for higher Gen are added */
+	if (INTEL_INFO(engine->dev)->gen > 9) {
+		DRM_ERROR("WA batch buffer is not initialized for Gen%d\n",
+			  INTEL_INFO(engine->dev)->gen);
+		return 0;
+	}
+
+	/* some WA perform writes to scratch page, ensure it is valid */
+	if (engine->scratch.obj == NULL) {
+		DRM_ERROR("scratch page not allocated for %s\n", engine->name);
+		return -EINVAL;
+	}
+
+	ret = lrc_setup_wa_ctx_obj(engine, PAGE_SIZE);
+	if (ret) {
+		DRM_DEBUG_DRIVER("Failed to setup context WA page: %d\n", ret);
+		return ret;
+	}
+
+	page = i915_gem_object_get_dirty_page(wa_ctx->obj, 0);
+	batch = kmap_atomic(page);
+	offset = 0;
+
+	if (INTEL_INFO(engine->dev)->gen == 8) {
+		ret = gen8_init_indirectctx_bb(engine,
+					       &wa_ctx->indirect_ctx,
+					       batch,
+					       &offset);
+		if (ret)
+			goto out;
+
+		ret = gen8_init_perctx_bb(engine,
+					  &wa_ctx->per_ctx,
+					  batch,
+					  &offset);
+		if (ret)
+			goto out;
+	} else if (INTEL_INFO(engine->dev)->gen == 9) {
+		ret = gen9_init_indirectctx_bb(engine,
+					       &wa_ctx->indirect_ctx,
+					       batch,
+					       &offset);
+		if (ret)
+			goto out;
+
+		ret = gen9_init_perctx_bb(engine,
+					  &wa_ctx->per_ctx,
+					  batch,
+					  &offset);
+		if (ret)
+			goto out;
+	}
+
+out:
+	kunmap_atomic(batch);
+	if (ret)
+		lrc_destroy_wa_ctx_obj(engine);
+
+	return ret;
+}
+
+static void lrc_init_hws(struct intel_engine_cs *engine)
+{
+	struct drm_i915_private *dev_priv = engine->dev->dev_private;
+
+	I915_WRITE(RING_HWS_PGA(engine->mmio_base),
+		   (u32)engine->status_page.gfx_addr);
+	POSTING_READ(RING_HWS_PGA(engine->mmio_base));
+}
+
+static int gen8_init_common_ring(struct intel_engine_cs *engine)
+{
+	struct drm_device *dev = engine->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	unsigned int next_context_status_buffer_hw;
+
+	lrc_init_hws(engine);
+
+	I915_WRITE_IMR(engine,
+		       ~(engine->irq_enable_mask | engine->irq_keep_mask));
+	I915_WRITE(RING_HWSTAM(engine->mmio_base), 0xffffffff);
+
+	I915_WRITE(RING_MODE_GEN7(engine),
+		   _MASKED_BIT_DISABLE(GFX_REPLAY_MODE) |
+		   _MASKED_BIT_ENABLE(GFX_RUN_LIST_ENABLE));
+	POSTING_READ(RING_MODE_GEN7(engine));
+
+	/*
+	 * Instead of resetting the Context Status Buffer (CSB) read pointer to
+	 * zero, we need to read the write pointer from hardware and use its
+	 * value because "this register is power context save restored".
+	 * Effectively, these states have been observed:
+	 *
+	 *      | Suspend-to-idle (freeze) | Suspend-to-RAM (mem) |
+	 * BDW  | CSB regs not reset       | CSB regs reset       |
+	 * CHT  | CSB regs not reset       | CSB regs not reset   |
+	 * SKL  |         ?                |         ?            |
+	 * BXT  |         ?                |         ?            |
+	 */
+	next_context_status_buffer_hw =
+		GEN8_CSB_WRITE_PTR(I915_READ(RING_CONTEXT_STATUS_PTR(engine)));
+
+	/*
+	 * When the CSB registers are reset (also after power-up / gpu reset),
+	 * CSB write pointer is set to all 1's, which is not valid, use '5' in
+	 * this special case, so the first element read is CSB[0].
+	 */
+	if (next_context_status_buffer_hw == GEN8_CSB_PTR_MASK)
+		next_context_status_buffer_hw = (GEN8_CSB_ENTRIES - 1);
+
+	engine->next_context_status_buffer = next_context_status_buffer_hw;
+	DRM_DEBUG_DRIVER("Execlists enabled for %s\n", engine->name);
+
+	intel_engine_init_hangcheck(engine);
+
+	return intel_mocs_init_engine(engine);
+}
+
+static int gen8_init_render_ring(struct intel_engine_cs *engine)
+{
+	struct drm_device *dev = engine->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	int ret;
+
+	ret = gen8_init_common_ring(engine);
+	if (ret)
+		return ret;
+
+	/* We need to disable the AsyncFlip performance optimisations in order
+	 * to use MI_WAIT_FOR_EVENT within the CS. It should already be
+	 * programmed to '1' on all products.
+	 *
+	 * WaDisableAsyncFlipPerfMode:snb,ivb,hsw,vlv,bdw,chv
+	 */
+	I915_WRITE(MI_MODE, _MASKED_BIT_ENABLE(ASYNC_FLIP_PERF_DISABLE));
+
+	I915_WRITE(INSTPM, _MASKED_BIT_ENABLE(INSTPM_FORCE_ORDERING));
+
+	return init_workarounds_ring(engine);
+}
+
+static int gen9_init_render_ring(struct intel_engine_cs *engine)
+{
+	int ret;
+
+	ret = gen8_init_common_ring(engine);
+	if (ret)
+		return ret;
+
+	return init_workarounds_ring(engine);
+}
+
+static int intel_logical_ring_emit_pdps(struct drm_i915_gem_request *req)
+{
+	struct i915_hw_ppgtt *ppgtt = req->ctx->ppgtt;
+	struct intel_engine_cs *engine = req->engine;
+	struct intel_ringbuffer *ringbuf = req->ringbuf;
+	const int num_lri_cmds = GEN8_LEGACY_PDPES * 2;
+	int i, ret;
+
+	ret = intel_ring_begin(req, num_lri_cmds * 2 + 2);
+	if (ret)
+		return ret;
+
+	intel_logical_ring_emit(ringbuf, MI_LOAD_REGISTER_IMM(num_lri_cmds));
+	for (i = GEN8_LEGACY_PDPES - 1; i >= 0; i--) {
+		const dma_addr_t pd_daddr = i915_page_dir_dma_addr(ppgtt, i);
+
+		intel_logical_ring_emit_reg(ringbuf,
+					    GEN8_RING_PDP_UDW(engine, i));
+		intel_logical_ring_emit(ringbuf, upper_32_bits(pd_daddr));
+		intel_logical_ring_emit_reg(ringbuf,
+					    GEN8_RING_PDP_LDW(engine, i));
+		intel_logical_ring_emit(ringbuf, lower_32_bits(pd_daddr));
+	}
+
+	intel_logical_ring_emit(ringbuf, MI_NOOP);
+	intel_logical_ring_advance(ringbuf);
+
+	return 0;
+}
+
+static int gen8_emit_bb_start(struct drm_i915_gem_request *req,
+			      u64 offset, unsigned dispatch_flags)
+{
+	struct intel_ringbuffer *ringbuf = req->ringbuf;
+	bool ppgtt = !(dispatch_flags & I915_DISPATCH_SECURE);
+	int ret;
+
+	/* Don't rely in hw updating PDPs, specially in lite-restore.
+	 * Ideally, we should set Force PD Restore in ctx descriptor,
+	 * but we can't. Force Restore would be a second option, but
+	 * it is unsafe in case of lite-restore (because the ctx is
+	 * not idle). PML4 is allocated during ppgtt init so this is
+	 * not needed in 48-bit.*/
+	if (req->ctx->ppgtt &&
+	    (intel_engine_flag(req->engine) & req->ctx->ppgtt->pd_dirty_rings)) {
+		if (!USES_FULL_48BIT_PPGTT(req->i915) &&
+		    !intel_vgpu_active(req->i915->dev)) {
+			ret = intel_logical_ring_emit_pdps(req);
+			if (ret)
+				return ret;
+		}
+
+		req->ctx->ppgtt->pd_dirty_rings &= ~intel_engine_flag(req->engine);
+	}
+
+	ret = intel_ring_begin(req, 4);
+	if (ret)
+		return ret;
+
+	/* FIXME(BDW): Address space and security selectors. */
+	intel_logical_ring_emit(ringbuf, MI_BATCH_BUFFER_START_GEN8 |
+				(ppgtt<<8) |
+				(dispatch_flags & I915_DISPATCH_RS ?
+				 MI_BATCH_RESOURCE_STREAMER : 0));
+	intel_logical_ring_emit(ringbuf, lower_32_bits(offset));
+	intel_logical_ring_emit(ringbuf, upper_32_bits(offset));
+	intel_logical_ring_emit(ringbuf, MI_NOOP);
+	intel_logical_ring_advance(ringbuf);
+
+	return 0;
+}
+
+static bool gen8_logical_ring_get_irq(struct intel_engine_cs *engine)
+{
+	struct drm_device *dev = engine->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	unsigned long flags;
+
+	if (WARN_ON(!intel_irqs_enabled(dev_priv)))
+		return false;
+
+	spin_lock_irqsave(&dev_priv->irq_lock, flags);
+	if (engine->irq_refcount++ == 0) {
+		I915_WRITE_IMR(engine,
+			       ~(engine->irq_enable_mask | engine->irq_keep_mask));
+		POSTING_READ(RING_IMR(engine->mmio_base));
+	}
+	spin_unlock_irqrestore(&dev_priv->irq_lock, flags);
+
+	return true;
+}
+
+static void gen8_logical_ring_put_irq(struct intel_engine_cs *engine)
+{
+	struct drm_device *dev = engine->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	unsigned long flags;
+
+	spin_lock_irqsave(&dev_priv->irq_lock, flags);
+	if (--engine->irq_refcount == 0) {
+		I915_WRITE_IMR(engine, ~engine->irq_keep_mask);
+		POSTING_READ(RING_IMR(engine->mmio_base));
+	}
+	spin_unlock_irqrestore(&dev_priv->irq_lock, flags);
+}
+
+static int gen8_emit_flush(struct drm_i915_gem_request *request,
+			   u32 invalidate_domains,
+			   u32 unused)
+{
+	struct intel_ringbuffer *ringbuf = request->ringbuf;
+	struct intel_engine_cs *engine = ringbuf->engine;
+	struct drm_device *dev = engine->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	uint32_t cmd;
+	int ret;
+
+	ret = intel_ring_begin(request, 4);
+	if (ret)
+		return ret;
+
+	cmd = MI_FLUSH_DW + 1;
+
+	/* We always require a command barrier so that subsequent
+	 * commands, such as breadcrumb interrupts, are strictly ordered
+	 * wrt the contents of the write cache being flushed to memory
+	 * (and thus being coherent from the CPU).
+	 */
+	cmd |= MI_FLUSH_DW_STORE_INDEX | MI_FLUSH_DW_OP_STOREDW;
+
+	if (invalidate_domains & I915_GEM_GPU_DOMAINS) {
+		cmd |= MI_INVALIDATE_TLB;
+		if (engine == &dev_priv->engine[VCS])
+			cmd |= MI_INVALIDATE_BSD;
+	}
+
+	intel_logical_ring_emit(ringbuf, cmd);
+	intel_logical_ring_emit(ringbuf,
+				I915_GEM_HWS_SCRATCH_ADDR |
+				MI_FLUSH_DW_USE_GTT);
+	intel_logical_ring_emit(ringbuf, 0); /* upper addr */
+	intel_logical_ring_emit(ringbuf, 0); /* value */
+	intel_logical_ring_advance(ringbuf);
+
+	return 0;
+}
+
+static int gen8_emit_flush_render(struct drm_i915_gem_request *request,
+				  u32 invalidate_domains,
+				  u32 flush_domains)
+{
+	struct intel_ringbuffer *ringbuf = request->ringbuf;
+	struct intel_engine_cs *engine = ringbuf->engine;
+	u32 scratch_addr = engine->scratch.gtt_offset + 2 * CACHELINE_BYTES;
+	bool vf_flush_wa = false, dc_flush_wa = false;
+	u32 flags = 0;
+	int ret;
+	int len;
+
+	flags |= PIPE_CONTROL_CS_STALL;
+
+	if (flush_domains) {
+		flags |= PIPE_CONTROL_RENDER_TARGET_CACHE_FLUSH;
+		flags |= PIPE_CONTROL_DEPTH_CACHE_FLUSH;
+		flags |= PIPE_CONTROL_DC_FLUSH_ENABLE;
+		flags |= PIPE_CONTROL_FLUSH_ENABLE;
+	}
+
+	if (invalidate_domains) {
+		flags |= PIPE_CONTROL_TLB_INVALIDATE;
+		flags |= PIPE_CONTROL_INSTRUCTION_CACHE_INVALIDATE;
+		flags |= PIPE_CONTROL_TEXTURE_CACHE_INVALIDATE;
+		flags |= PIPE_CONTROL_VF_CACHE_INVALIDATE;
+		flags |= PIPE_CONTROL_CONST_CACHE_INVALIDATE;
+		flags |= PIPE_CONTROL_STATE_CACHE_INVALIDATE;
+		flags |= PIPE_CONTROL_QW_WRITE;
+		flags |= PIPE_CONTROL_GLOBAL_GTT_IVB;
+
+		/*
+		 * On GEN9: before VF_CACHE_INVALIDATE we need to emit a NULL
+		 * pipe control.
+		 */
+		if (IS_GEN9(engine->dev))
+			vf_flush_wa = true;
+
+		/* WaForGAMHang:kbl */
+		if (IS_KBL_REVID(request->i915, 0, KBL_REVID_B0))
+			dc_flush_wa = true;
+	}
+
+	len = 6;
+
+	if (vf_flush_wa)
+		len += 6;
+
+	if (dc_flush_wa)
+		len += 12;
+
+	ret = intel_ring_begin(request, len);
+	if (ret)
+		return ret;
+
+	if (vf_flush_wa) {
+		intel_logical_ring_emit(ringbuf, GFX_OP_PIPE_CONTROL(6));
+		intel_logical_ring_emit(ringbuf, 0);
+		intel_logical_ring_emit(ringbuf, 0);
+		intel_logical_ring_emit(ringbuf, 0);
+		intel_logical_ring_emit(ringbuf, 0);
+		intel_logical_ring_emit(ringbuf, 0);
+	}
+
+	if (dc_flush_wa) {
+		intel_logical_ring_emit(ringbuf, GFX_OP_PIPE_CONTROL(6));
+		intel_logical_ring_emit(ringbuf, PIPE_CONTROL_DC_FLUSH_ENABLE);
+		intel_logical_ring_emit(ringbuf, 0);
+		intel_logical_ring_emit(ringbuf, 0);
+		intel_logical_ring_emit(ringbuf, 0);
+		intel_logical_ring_emit(ringbuf, 0);
+	}
+
+	intel_logical_ring_emit(ringbuf, GFX_OP_PIPE_CONTROL(6));
+	intel_logical_ring_emit(ringbuf, flags);
+	intel_logical_ring_emit(ringbuf, scratch_addr);
+	intel_logical_ring_emit(ringbuf, 0);
+	intel_logical_ring_emit(ringbuf, 0);
+	intel_logical_ring_emit(ringbuf, 0);
+
+	if (dc_flush_wa) {
+		intel_logical_ring_emit(ringbuf, GFX_OP_PIPE_CONTROL(6));
+		intel_logical_ring_emit(ringbuf, PIPE_CONTROL_CS_STALL);
+		intel_logical_ring_emit(ringbuf, 0);
+		intel_logical_ring_emit(ringbuf, 0);
+		intel_logical_ring_emit(ringbuf, 0);
+		intel_logical_ring_emit(ringbuf, 0);
+	}
+
+	intel_logical_ring_advance(ringbuf);
+
+	return 0;
+}
+
+static u32 gen8_get_seqno(struct intel_engine_cs *engine)
+{
+	return intel_read_status_page(engine, I915_GEM_HWS_INDEX);
+}
+
+static void gen8_set_seqno(struct intel_engine_cs *engine, u32 seqno)
+{
+	intel_write_status_page(engine, I915_GEM_HWS_INDEX, seqno);
+}
+
+static void bxt_a_seqno_barrier(struct intel_engine_cs *engine)
+{
+	/*
+	 * On BXT A steppings there is a HW coherency issue whereby the
+	 * MI_STORE_DATA_IMM storing the completed request's seqno
+	 * occasionally doesn't invalidate the CPU cache. Work around this by
+	 * clflushing the corresponding cacheline whenever the caller wants
+	 * the coherency to be guaranteed. Note that this cacheline is known
+	 * to be clean at this point, since we only write it in
+	 * bxt_a_set_seqno(), where we also do a clflush after the write. So
+	 * this clflush in practice becomes an invalidate operation.
+	 */
+	intel_flush_status_page(engine, I915_GEM_HWS_INDEX);
+}
+
+static void bxt_a_set_seqno(struct intel_engine_cs *engine, u32 seqno)
+{
+	intel_write_status_page(engine, I915_GEM_HWS_INDEX, seqno);
+
+	/* See bxt_a_get_seqno() explaining the reason for the clflush. */
+	intel_flush_status_page(engine, I915_GEM_HWS_INDEX);
+}
+
+/*
+ * Reserve space for 2 NOOPs at the end of each request to be
+ * used as a workaround for not being allowed to do lite
+ * restore with HEAD==TAIL (WaIdleLiteRestore).
+ */
+#define WA_TAIL_DWORDS 2
+
+static inline u32 hws_seqno_address(struct intel_engine_cs *engine)
+{
+	return engine->status_page.gfx_addr + I915_GEM_HWS_INDEX_ADDR;
+}
+
+static int gen8_emit_request(struct drm_i915_gem_request *request)
+{
+	struct intel_ringbuffer *ringbuf = request->ringbuf;
+	int ret;
+
+	ret = intel_ring_begin(request, 6 + WA_TAIL_DWORDS);
+	if (ret)
+		return ret;
+
+	/* w/a: bit 5 needs to be zero for MI_FLUSH_DW address. */
+	BUILD_BUG_ON(I915_GEM_HWS_INDEX_ADDR & (1 << 5));
+
+	intel_logical_ring_emit(ringbuf,
+				(MI_FLUSH_DW + 1) | MI_FLUSH_DW_OP_STOREDW);
+	intel_logical_ring_emit(ringbuf,
+				hws_seqno_address(request->engine) |
+				MI_FLUSH_DW_USE_GTT);
+	intel_logical_ring_emit(ringbuf, 0);
+	intel_logical_ring_emit(ringbuf, i915_gem_request_get_seqno(request));
+	intel_logical_ring_emit(ringbuf, MI_USER_INTERRUPT);
+	intel_logical_ring_emit(ringbuf, MI_NOOP);
+	return intel_logical_ring_advance_and_submit(request);
+}
+
+static int gen8_emit_request_render(struct drm_i915_gem_request *request)
+{
+	struct intel_ringbuffer *ringbuf = request->ringbuf;
+	int ret;
+
+	ret = intel_ring_begin(request, 8 + WA_TAIL_DWORDS);
+	if (ret)
+		return ret;
+
+	/* We're using qword write, seqno should be aligned to 8 bytes. */
+	BUILD_BUG_ON(I915_GEM_HWS_INDEX & 1);
+
+	/* w/a for post sync ops following a GPGPU operation we
+	 * need a prior CS_STALL, which is emitted by the flush
+	 * following the batch.
+	 */
+	intel_logical_ring_emit(ringbuf, GFX_OP_PIPE_CONTROL(6));
+	intel_logical_ring_emit(ringbuf,
+				(PIPE_CONTROL_GLOBAL_GTT_IVB |
+				 PIPE_CONTROL_CS_STALL |
+				 PIPE_CONTROL_QW_WRITE));
+	intel_logical_ring_emit(ringbuf, hws_seqno_address(request->engine));
+	intel_logical_ring_emit(ringbuf, 0);
+	intel_logical_ring_emit(ringbuf, i915_gem_request_get_seqno(request));
+	/* We're thrashing one dword of HWS. */
+	intel_logical_ring_emit(ringbuf, 0);
+	intel_logical_ring_emit(ringbuf, MI_USER_INTERRUPT);
+	intel_logical_ring_emit(ringbuf, MI_NOOP);
+	return intel_logical_ring_advance_and_submit(request);
+}
+
+static int intel_lr_context_render_state_init(struct drm_i915_gem_request *req)
+{
+	struct render_state so;
+	int ret;
+
+	ret = i915_gem_render_state_prepare(req->engine, &so);
+	if (ret)
+		return ret;
+
+	if (so.rodata == NULL)
+		return 0;
+
+	ret = req->engine->emit_bb_start(req, so.ggtt_offset,
+				       I915_DISPATCH_SECURE);
+	if (ret)
+		goto out;
+
+	ret = req->engine->emit_bb_start(req,
+				       (so.ggtt_offset + so.aux_batch_offset),
+				       I915_DISPATCH_SECURE);
+	if (ret)
+		goto out;
+
+	i915_vma_move_to_active(i915_gem_obj_to_ggtt(so.obj), req);
+
+out:
+	i915_gem_render_state_fini(&so);
+	return ret;
+}
+
+static int gen8_init_rcs_context(struct drm_i915_gem_request *req)
+{
+	int ret;
+
+	ret = intel_logical_ring_workarounds_emit(req);
+	if (ret)
+		return ret;
+
+	ret = intel_rcs_context_init_mocs(req);
+	/*
+	 * Failing to program the MOCS is non-fatal.The system will not
+	 * run at peak performance. So generate an error and carry on.
+	 */
+	if (ret)
+		DRM_ERROR("MOCS failed to program: expect performance issues.\n");
+
+	return intel_lr_context_render_state_init(req);
+}
+
+/**
+ * intel_logical_ring_cleanup() - deallocate the Engine Command Streamer
+ *
+ * @ring: Engine Command Streamer.
+ *
+ */
+void intel_logical_ring_cleanup(struct intel_engine_cs *engine)
+{
+	struct drm_i915_private *dev_priv;
+
+	if (!intel_engine_initialized(engine))
+		return;
+
+	/*
+	 * Tasklet cannot be active at this point due intel_mark_active/idle
+	 * so this is just for documentation.
+	 */
+	if (WARN_ON(test_bit(TASKLET_STATE_SCHED, &engine->irq_tasklet.state)))
+		tasklet_kill(&engine->irq_tasklet);
+
+	dev_priv = engine->dev->dev_private;
+
+	if (engine->buffer) {
+		intel_logical_ring_stop(engine);
+		WARN_ON((I915_READ_MODE(engine) & MODE_IDLE) == 0);
+	}
+
+	if (engine->cleanup)
+		engine->cleanup(engine);
+
+	i915_cmd_parser_fini_ring(engine);
+	i915_gem_batch_pool_fini(&engine->batch_pool);
+
+	if (engine->status_page.obj) {
+		i915_gem_object_unpin_map(engine->status_page.obj);
+		engine->status_page.obj = NULL;
+	}
+
+	engine->idle_lite_restore_wa = 0;
+	engine->disable_lite_restore_wa = false;
+	engine->ctx_desc_template = 0;
+
+	lrc_destroy_wa_ctx_obj(engine);
+	engine->dev = NULL;
+}
+
+static void
+logical_ring_default_vfuncs(struct drm_device *dev,
+			    struct intel_engine_cs *engine)
+{
+	/* Default vfuncs which can be overriden by each engine. */
+	engine->init_hw = gen8_init_common_ring;
+	engine->emit_request = gen8_emit_request;
+	engine->emit_flush = gen8_emit_flush;
+	engine->irq_get = gen8_logical_ring_get_irq;
+	engine->irq_put = gen8_logical_ring_put_irq;
+	engine->emit_bb_start = gen8_emit_bb_start;
+	engine->get_seqno = gen8_get_seqno;
+	engine->set_seqno = gen8_set_seqno;
+	if (IS_BXT_REVID(dev, 0, BXT_REVID_A1)) {
+		engine->irq_seqno_barrier = bxt_a_seqno_barrier;
+		engine->set_seqno = bxt_a_set_seqno;
+	}
+}
+
+static inline void
+logical_ring_default_irqs(struct intel_engine_cs *engine, unsigned shift)
+{
+	engine->irq_enable_mask = GT_RENDER_USER_INTERRUPT << shift;
+	engine->irq_keep_mask = GT_CONTEXT_SWITCH_INTERRUPT << shift;
+}
+
+static int
+lrc_setup_hws(struct intel_engine_cs *engine,
+	      struct drm_i915_gem_object *dctx_obj)
+{
+	void *hws;
+
+	/* The HWSP is part of the default context object in LRC mode. */
+	engine->status_page.gfx_addr = i915_gem_obj_ggtt_offset(dctx_obj) +
+				       LRC_PPHWSP_PN * PAGE_SIZE;
+	hws = i915_gem_object_pin_map(dctx_obj);
+	if (IS_ERR(hws))
+		return PTR_ERR(hws);
+	engine->status_page.page_addr = hws + LRC_PPHWSP_PN * PAGE_SIZE;
+	engine->status_page.obj = dctx_obj;
+
+	return 0;
+}
+
+static int
+logical_ring_init(struct drm_device *dev, struct intel_engine_cs *engine)
+{
+	struct drm_i915_private *dev_priv = to_i915(dev);
+	struct intel_context *dctx = dev_priv->kernel_context;
+	enum forcewake_domains fw_domains;
+	int ret;
+
+	/* Intentionally left blank. */
+	engine->buffer = NULL;
+
+	engine->dev = dev;
+	INIT_LIST_HEAD(&engine->active_list);
+	INIT_LIST_HEAD(&engine->request_list);
+	i915_gem_batch_pool_init(dev, &engine->batch_pool);
+	init_waitqueue_head(&engine->irq_queue);
+
+	INIT_LIST_HEAD(&engine->buffers);
+	INIT_LIST_HEAD(&engine->execlist_queue);
+	INIT_LIST_HEAD(&engine->execlist_retired_req_list);
+	spin_lock_init(&engine->execlist_lock);
+
+	tasklet_init(&engine->irq_tasklet,
+		     intel_lrc_irq_handler, (unsigned long)engine);
+
+	logical_ring_init_platform_invariants(engine);
+
+	fw_domains = intel_uncore_forcewake_for_reg(dev_priv,
+						    RING_ELSP(engine),
+						    FW_REG_WRITE);
+
+	fw_domains |= intel_uncore_forcewake_for_reg(dev_priv,
+						     RING_CONTEXT_STATUS_PTR(engine),
+						     FW_REG_READ | FW_REG_WRITE);
+
+	fw_domains |= intel_uncore_forcewake_for_reg(dev_priv,
+						     RING_CONTEXT_STATUS_BUF_BASE(engine),
+						     FW_REG_READ);
+
+	engine->fw_domains = fw_domains;
+
+	ret = i915_cmd_parser_init_ring(engine);
+	if (ret)
+		goto error;
+
+	ret = intel_lr_context_deferred_alloc(dctx, engine);
+	if (ret)
+		goto error;
+
+	/* As this is the default context, always pin it */
+	ret = intel_lr_context_do_pin(dctx, engine);
+	if (ret) {
+		DRM_ERROR(
+			"Failed to pin and map ringbuffer %s: %d\n",
+			engine->name, ret);
+		goto error;
+	}
+
+	/* And setup the hardware status page. */
+	ret = lrc_setup_hws(engine, dctx->engine[engine->id].state);
+	if (ret) {
+		DRM_ERROR("Failed to set up hws %s: %d\n", engine->name, ret);
+		goto error;
+	}
+
+	return 0;
+
+error:
+	intel_logical_ring_cleanup(engine);
+	return ret;
+}
+
+static int logical_render_ring_init(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_engine_cs *engine = &dev_priv->engine[RCS];
+	int ret;
+
+	engine->name = "render ring";
+	engine->id = RCS;
+	engine->exec_id = I915_EXEC_RENDER;
+	engine->guc_id = GUC_RENDER_ENGINE;
+	engine->mmio_base = RENDER_RING_BASE;
+
+	logical_ring_default_irqs(engine, GEN8_RCS_IRQ_SHIFT);
+	if (HAS_L3_DPF(dev))
+		engine->irq_keep_mask |= GT_RENDER_L3_PARITY_ERROR_INTERRUPT;
+
+	logical_ring_default_vfuncs(dev, engine);
+
+	/* Override some for render ring. */
+	if (INTEL_INFO(dev)->gen >= 9)
+		engine->init_hw = gen9_init_render_ring;
+	else
+		engine->init_hw = gen8_init_render_ring;
+	engine->init_context = gen8_init_rcs_context;
+	engine->cleanup = intel_fini_pipe_control;
+	engine->emit_flush = gen8_emit_flush_render;
+	engine->emit_request = gen8_emit_request_render;
+
+	engine->dev = dev;
+
+	ret = intel_init_pipe_control(engine);
+	if (ret)
+		return ret;
+
+	ret = intel_init_workaround_bb(engine);
+	if (ret) {
+		/*
+		 * We continue even if we fail to initialize WA batch
+		 * because we only expect rare glitches but nothing
+		 * critical to prevent us from using GPU
+		 */
+		DRM_ERROR("WA batch buffer initialization failed: %d\n",
+			  ret);
+	}
+
+	ret = logical_ring_init(dev, engine);
+	if (ret) {
+		lrc_destroy_wa_ctx_obj(engine);
+	}
+
+	return ret;
+}
+
+static int logical_bsd_ring_init(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_engine_cs *engine = &dev_priv->engine[VCS];
+
+	engine->name = "bsd ring";
+	engine->id = VCS;
+	engine->exec_id = I915_EXEC_BSD;
+	engine->guc_id = GUC_VIDEO_ENGINE;
+	engine->mmio_base = GEN6_BSD_RING_BASE;
+
+	logical_ring_default_irqs(engine, GEN8_VCS1_IRQ_SHIFT);
+	logical_ring_default_vfuncs(dev, engine);
+
+	return logical_ring_init(dev, engine);
+}
+
+static int logical_bsd2_ring_init(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_engine_cs *engine = &dev_priv->engine[VCS2];
+
+	engine->name = "bsd2 ring";
+	engine->id = VCS2;
+	engine->exec_id = I915_EXEC_BSD;
+	engine->guc_id = GUC_VIDEO_ENGINE2;
+	engine->mmio_base = GEN8_BSD2_RING_BASE;
+
+	logical_ring_default_irqs(engine, GEN8_VCS2_IRQ_SHIFT);
+	logical_ring_default_vfuncs(dev, engine);
+
+	return logical_ring_init(dev, engine);
+}
+
+static int logical_blt_ring_init(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_engine_cs *engine = &dev_priv->engine[BCS];
+
+	engine->name = "blitter ring";
+	engine->id = BCS;
+	engine->exec_id = I915_EXEC_BLT;
+	engine->guc_id = GUC_BLITTER_ENGINE;
+	engine->mmio_base = BLT_RING_BASE;
+
+	logical_ring_default_irqs(engine, GEN8_BCS_IRQ_SHIFT);
+	logical_ring_default_vfuncs(dev, engine);
+
+	return logical_ring_init(dev, engine);
+}
+
+static int logical_vebox_ring_init(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_engine_cs *engine = &dev_priv->engine[VECS];
+
+	engine->name = "video enhancement ring";
+	engine->id = VECS;
+	engine->exec_id = I915_EXEC_VEBOX;
+	engine->guc_id = GUC_VIDEOENHANCE_ENGINE;
+	engine->mmio_base = VEBOX_RING_BASE;
+
+	logical_ring_default_irqs(engine, GEN8_VECS_IRQ_SHIFT);
+	logical_ring_default_vfuncs(dev, engine);
+
+	return logical_ring_init(dev, engine);
+}
+
+/**
+ * intel_logical_rings_init() - allocate, populate and init the Engine Command Streamers
+ * @dev: DRM device.
+ *
+ * This function inits the engines for an Execlists submission style (the equivalent in the
+ * legacy ringbuffer submission world would be i915_gem_init_engines). It does it only for
+ * those engines that are present in the hardware.
+ *
+ * Return: non-zero if the initialization failed.
+ */
+int intel_logical_rings_init(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	int ret;
+
+	ret = logical_render_ring_init(dev);
+	if (ret)
+		return ret;
+
+	if (HAS_BSD(dev)) {
+		ret = logical_bsd_ring_init(dev);
+		if (ret)
+			goto cleanup_render_ring;
+	}
+
+	if (HAS_BLT(dev)) {
+		ret = logical_blt_ring_init(dev);
+		if (ret)
+			goto cleanup_bsd_ring;
+	}
+
+	if (HAS_VEBOX(dev)) {
+		ret = logical_vebox_ring_init(dev);
+		if (ret)
+			goto cleanup_blt_ring;
+	}
+
+	if (HAS_BSD2(dev)) {
+		ret = logical_bsd2_ring_init(dev);
+		if (ret)
+			goto cleanup_vebox_ring;
+	}
+
+	return 0;
+
+cleanup_vebox_ring:
+	intel_logical_ring_cleanup(&dev_priv->engine[VECS]);
+cleanup_blt_ring:
+	intel_logical_ring_cleanup(&dev_priv->engine[BCS]);
+cleanup_bsd_ring:
+	intel_logical_ring_cleanup(&dev_priv->engine[VCS]);
+cleanup_render_ring:
+	intel_logical_ring_cleanup(&dev_priv->engine[RCS]);
+
+	return ret;
+}
+
+static u32
+make_rpcs(struct drm_device *dev)
+{
+	u32 rpcs = 0;
+
+	/*
+	 * No explicit RPCS request is needed to ensure full
+	 * slice/subslice/EU enablement prior to Gen9.
+	*/
+	if (INTEL_INFO(dev)->gen < 9)
+		return 0;
+
+	/*
+	 * Starting in Gen9, render power gating can leave
+	 * slice/subslice/EU in a partially enabled state. We
+	 * must make an explicit request through RPCS for full
+	 * enablement.
+	*/
+	if (INTEL_INFO(dev)->has_slice_pg) {
+		rpcs |= GEN8_RPCS_S_CNT_ENABLE;
+		rpcs |= INTEL_INFO(dev)->slice_total <<
+			GEN8_RPCS_S_CNT_SHIFT;
+		rpcs |= GEN8_RPCS_ENABLE;
+	}
+
+	if (INTEL_INFO(dev)->has_subslice_pg) {
+		rpcs |= GEN8_RPCS_SS_CNT_ENABLE;
+		rpcs |= INTEL_INFO(dev)->subslice_per_slice <<
+			GEN8_RPCS_SS_CNT_SHIFT;
+		rpcs |= GEN8_RPCS_ENABLE;
+	}
+
+	if (INTEL_INFO(dev)->has_eu_pg) {
+		rpcs |= INTEL_INFO(dev)->eu_per_subslice <<
+			GEN8_RPCS_EU_MIN_SHIFT;
+		rpcs |= INTEL_INFO(dev)->eu_per_subslice <<
+			GEN8_RPCS_EU_MAX_SHIFT;
+		rpcs |= GEN8_RPCS_ENABLE;
+	}
+
+	return rpcs;
+}
+
+static u32 intel_lr_indirect_ctx_offset(struct intel_engine_cs *engine)
+{
+	u32 indirect_ctx_offset;
+
+	switch (INTEL_INFO(engine->dev)->gen) {
+	default:
+		MISSING_CASE(INTEL_INFO(engine->dev)->gen);
+		/* fall through */
+	case 9:
+		indirect_ctx_offset =
+			GEN9_CTX_RCS_INDIRECT_CTX_OFFSET_DEFAULT;
+		break;
+	case 8:
+		indirect_ctx_offset =
+			GEN8_CTX_RCS_INDIRECT_CTX_OFFSET_DEFAULT;
+		break;
+	}
+
+	return indirect_ctx_offset;
+}
+
+static int
+populate_lr_context(struct intel_context *ctx,
+		    struct drm_i915_gem_object *ctx_obj,
+		    struct intel_engine_cs *engine,
+		    struct intel_ringbuffer *ringbuf)
+{
+	struct drm_device *dev = engine->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct i915_hw_ppgtt *ppgtt = ctx->ppgtt;
+	void *vaddr;
+	u32 *reg_state;
+	int ret;
+
+	if (!ppgtt)
+		ppgtt = dev_priv->mm.aliasing_ppgtt;
+
+	ret = i915_gem_object_set_to_cpu_domain(ctx_obj, true);
+	if (ret) {
+		DRM_DEBUG_DRIVER("Could not set to CPU domain\n");
+		return ret;
+	}
+
+	vaddr = i915_gem_object_pin_map(ctx_obj);
+	if (IS_ERR(vaddr)) {
+		ret = PTR_ERR(vaddr);
+		DRM_DEBUG_DRIVER("Could not map object pages! (%d)\n", ret);
+		return ret;
+	}
+	ctx_obj->dirty = true;
+
+	/* The second page of the context object contains some fields which must
+	 * be set up prior to the first execution. */
+	reg_state = vaddr + LRC_STATE_PN * PAGE_SIZE;
+
+	/* A context is actually a big batch buffer with several MI_LOAD_REGISTER_IMM
+	 * commands followed by (reg, value) pairs. The values we are setting here are
+	 * only for the first context restore: on a subsequent save, the GPU will
+	 * recreate this batchbuffer with new values (including all the missing
+	 * MI_LOAD_REGISTER_IMM commands that we are not initializing here). */
+	reg_state[CTX_LRI_HEADER_0] =
+		MI_LOAD_REGISTER_IMM(engine->id == RCS ? 14 : 11) | MI_LRI_FORCE_POSTED;
+	ASSIGN_CTX_REG(reg_state, CTX_CONTEXT_CONTROL,
+		       RING_CONTEXT_CONTROL(engine),
+		       _MASKED_BIT_ENABLE(CTX_CTRL_INHIBIT_SYN_CTX_SWITCH |
+					  CTX_CTRL_ENGINE_CTX_RESTORE_INHIBIT |
+					  (HAS_RESOURCE_STREAMER(dev) ?
+					    CTX_CTRL_RS_CTX_ENABLE : 0)));
+	ASSIGN_CTX_REG(reg_state, CTX_RING_HEAD, RING_HEAD(engine->mmio_base),
+		       0);
+	ASSIGN_CTX_REG(reg_state, CTX_RING_TAIL, RING_TAIL(engine->mmio_base),
+		       0);
+	/* Ring buffer start address is not known until the buffer is pinned.
+	 * It is written to the context image in execlists_update_context()
+	 */
+	ASSIGN_CTX_REG(reg_state, CTX_RING_BUFFER_START,
+		       RING_START(engine->mmio_base), 0);
+	ASSIGN_CTX_REG(reg_state, CTX_RING_BUFFER_CONTROL,
+		       RING_CTL(engine->mmio_base),
+		       ((ringbuf->size - PAGE_SIZE) & RING_NR_PAGES) | RING_VALID);
+	ASSIGN_CTX_REG(reg_state, CTX_BB_HEAD_U,
+		       RING_BBADDR_UDW(engine->mmio_base), 0);
+	ASSIGN_CTX_REG(reg_state, CTX_BB_HEAD_L,
+		       RING_BBADDR(engine->mmio_base), 0);
+	ASSIGN_CTX_REG(reg_state, CTX_BB_STATE,
+		       RING_BBSTATE(engine->mmio_base),
+		       RING_BB_PPGTT);
+	ASSIGN_CTX_REG(reg_state, CTX_SECOND_BB_HEAD_U,
+		       RING_SBBADDR_UDW(engine->mmio_base), 0);
+	ASSIGN_CTX_REG(reg_state, CTX_SECOND_BB_HEAD_L,
+		       RING_SBBADDR(engine->mmio_base), 0);
+	ASSIGN_CTX_REG(reg_state, CTX_SECOND_BB_STATE,
+		       RING_SBBSTATE(engine->mmio_base), 0);
+	if (engine->id == RCS) {
+		ASSIGN_CTX_REG(reg_state, CTX_BB_PER_CTX_PTR,
+			       RING_BB_PER_CTX_PTR(engine->mmio_base), 0);
+		ASSIGN_CTX_REG(reg_state, CTX_RCS_INDIRECT_CTX,
+			       RING_INDIRECT_CTX(engine->mmio_base), 0);
+		ASSIGN_CTX_REG(reg_state, CTX_RCS_INDIRECT_CTX_OFFSET,
+			       RING_INDIRECT_CTX_OFFSET(engine->mmio_base), 0);
+		if (engine->wa_ctx.obj) {
+			struct i915_ctx_workarounds *wa_ctx = &engine->wa_ctx;
+			uint32_t ggtt_offset = i915_gem_obj_ggtt_offset(wa_ctx->obj);
+
+			reg_state[CTX_RCS_INDIRECT_CTX+1] =
+				(ggtt_offset + wa_ctx->indirect_ctx.offset * sizeof(uint32_t)) |
+				(wa_ctx->indirect_ctx.size / CACHELINE_DWORDS);
+
+			reg_state[CTX_RCS_INDIRECT_CTX_OFFSET+1] =
+				intel_lr_indirect_ctx_offset(engine) << 6;
+
+			reg_state[CTX_BB_PER_CTX_PTR+1] =
+				(ggtt_offset + wa_ctx->per_ctx.offset * sizeof(uint32_t)) |
+				0x01;
+		}
+	}
+	reg_state[CTX_LRI_HEADER_1] = MI_LOAD_REGISTER_IMM(9) | MI_LRI_FORCE_POSTED;
+	ASSIGN_CTX_REG(reg_state, CTX_CTX_TIMESTAMP,
+		       RING_CTX_TIMESTAMP(engine->mmio_base), 0);
+	/* PDP values well be assigned later if needed */
+	ASSIGN_CTX_REG(reg_state, CTX_PDP3_UDW, GEN8_RING_PDP_UDW(engine, 3),
+		       0);
+	ASSIGN_CTX_REG(reg_state, CTX_PDP3_LDW, GEN8_RING_PDP_LDW(engine, 3),
+		       0);
+	ASSIGN_CTX_REG(reg_state, CTX_PDP2_UDW, GEN8_RING_PDP_UDW(engine, 2),
+		       0);
+	ASSIGN_CTX_REG(reg_state, CTX_PDP2_LDW, GEN8_RING_PDP_LDW(engine, 2),
+		       0);
+	ASSIGN_CTX_REG(reg_state, CTX_PDP1_UDW, GEN8_RING_PDP_UDW(engine, 1),
+		       0);
+	ASSIGN_CTX_REG(reg_state, CTX_PDP1_LDW, GEN8_RING_PDP_LDW(engine, 1),
+		       0);
+	ASSIGN_CTX_REG(reg_state, CTX_PDP0_UDW, GEN8_RING_PDP_UDW(engine, 0),
+		       0);
+	ASSIGN_CTX_REG(reg_state, CTX_PDP0_LDW, GEN8_RING_PDP_LDW(engine, 0),
+		       0);
+
+	if (USES_FULL_48BIT_PPGTT(ppgtt->base.dev)) {
+		/* 64b PPGTT (48bit canonical)
+		 * PDP0_DESCRIPTOR contains the base address to PML4 and
+		 * other PDP Descriptors are ignored.
+		 */
+		ASSIGN_CTX_PML4(ppgtt, reg_state);
+	} else {
+		/* 32b PPGTT
+		 * PDP*_DESCRIPTOR contains the base address of space supported.
+		 * With dynamic page allocation, PDPs may not be allocated at
+		 * this point. Point the unallocated PDPs to the scratch page
+		 */
+		execlists_update_context_pdps(ppgtt, reg_state);
+	}
+
+	if (engine->id == RCS) {
+		reg_state[CTX_LRI_HEADER_2] = MI_LOAD_REGISTER_IMM(1);
+		ASSIGN_CTX_REG(reg_state, CTX_R_PWR_CLK_STATE, GEN8_R_PWR_CLK_STATE,
+			       make_rpcs(dev));
+	}
+
+	i915_gem_object_unpin_map(ctx_obj);
+
+	return 0;
+}
+
+/**
+ * intel_lr_context_free() - free the LRC specific bits of a context
+ * @ctx: the LR context to free.
+ *
+ * The real context freeing is done in i915_gem_context_free: this only
+ * takes care of the bits that are LRC related: the per-engine backing
+ * objects and the logical ringbuffer.
+ */
+void intel_lr_context_free(struct intel_context *ctx)
+{
+	int i;
+
+	for (i = I915_NUM_ENGINES; --i >= 0; ) {
+		struct intel_ringbuffer *ringbuf = ctx->engine[i].ringbuf;
+		struct drm_i915_gem_object *ctx_obj = ctx->engine[i].state;
+
+		if (!ctx_obj)
+			continue;
+
+		if (ctx == ctx->i915->kernel_context) {
+			intel_unpin_ringbuffer_obj(ringbuf);
+			i915_gem_object_ggtt_unpin(ctx_obj);
+			i915_gem_object_unpin_map(ctx_obj);
+		}
+
+		WARN_ON(ctx->engine[i].pin_count);
+		intel_ringbuffer_free(ringbuf);
+		drm_gem_object_unreference(&ctx_obj->base);
+	}
+}
+
+/**
+ * intel_lr_context_size() - return the size of the context for an engine
+ * @ring: which engine to find the context size for
+ *
+ * Each engine may require a different amount of space for a context image,
+ * so when allocating (or copying) an image, this function can be used to
+ * find the right size for the specific engine.
+ *
+ * Return: size (in bytes) of an engine-specific context image
+ *
+ * Note: this size includes the HWSP, which is part of the context image
+ * in LRC mode, but does not include the "shared data page" used with
+ * GuC submission. The caller should account for this if using the GuC.
+ */
+uint32_t intel_lr_context_size(struct intel_engine_cs *engine)
+{
+	int ret = 0;
+
+	WARN_ON(INTEL_INFO(engine->dev)->gen < 8);
+
+	switch (engine->id) {
+	case RCS:
+		if (INTEL_INFO(engine->dev)->gen >= 9)
+			ret = GEN9_LR_CONTEXT_RENDER_SIZE;
+		else
+			ret = GEN8_LR_CONTEXT_RENDER_SIZE;
+		break;
+	case VCS:
+	case BCS:
+	case VECS:
+	case VCS2:
+		ret = GEN8_LR_CONTEXT_OTHER_SIZE;
+		break;
+	}
+
+	return ret;
+}
+
+/**
+ * intel_lr_context_deferred_alloc() - create the LRC specific bits of a context
+ * @ctx: LR context to create.
+ * @ring: engine to be used with the context.
+ *
+ * This function can be called more than once, with different engines, if we plan
+ * to use the context with them. The context backing objects and the ringbuffers
+ * (specially the ringbuffer backing objects) suck a lot of memory up, and that's why
+ * the creation is a deferred call: it's better to make sure first that we need to use
+ * a given ring with the context.
+ *
+ * Return: non-zero on error.
+ */
+
+int intel_lr_context_deferred_alloc(struct intel_context *ctx,
+				    struct intel_engine_cs *engine)
+{
+	struct drm_device *dev = engine->dev;
+	struct drm_i915_gem_object *ctx_obj;
+	uint32_t context_size;
+	struct intel_ringbuffer *ringbuf;
+	int ret;
+
+	WARN_ON(ctx->legacy_hw_ctx.rcs_state != NULL);
+	WARN_ON(ctx->engine[engine->id].state);
+
+	context_size = round_up(intel_lr_context_size(engine), 4096);
+
+	/* One extra page as the sharing data between driver and GuC */
+	context_size += PAGE_SIZE * LRC_PPHWSP_PN;
+
+	ctx_obj = i915_gem_alloc_object(dev, context_size);
+	if (!ctx_obj) {
+		DRM_DEBUG_DRIVER("Alloc LRC backing obj failed.\n");
+		return -ENOMEM;
+	}
+
+	ringbuf = intel_engine_create_ringbuffer(engine, 4 * PAGE_SIZE);
+	if (IS_ERR(ringbuf)) {
+		ret = PTR_ERR(ringbuf);
+		goto error_deref_obj;
+	}
+
+	ret = populate_lr_context(ctx, ctx_obj, engine, ringbuf);
+	if (ret) {
+		DRM_DEBUG_DRIVER("Failed to populate LRC: %d\n", ret);
+		goto error_ringbuf;
+	}
+
+	ctx->engine[engine->id].ringbuf = ringbuf;
+	ctx->engine[engine->id].state = ctx_obj;
+
+	if (ctx != ctx->i915->kernel_context && engine->init_context) {
+		struct drm_i915_gem_request *req;
+
+		req = i915_gem_request_alloc(engine, ctx);
+		if (IS_ERR(req)) {
+			ret = PTR_ERR(req);
+			DRM_ERROR("ring create req: %d\n", ret);
+			goto error_ringbuf;
+		}
+
+		ret = engine->init_context(req);
+		i915_add_request_no_flush(req);
+		if (ret) {
+			DRM_ERROR("ring init context: %d\n",
+				ret);
+			goto error_ringbuf;
+		}
+	}
+	return 0;
+
+error_ringbuf:
+	intel_ringbuffer_free(ringbuf);
+error_deref_obj:
+	drm_gem_object_unreference(&ctx_obj->base);
+	ctx->engine[engine->id].ringbuf = NULL;
+	ctx->engine[engine->id].state = NULL;
+	return ret;
+}
+
+void intel_lr_context_reset(struct drm_i915_private *dev_priv,
+			    struct intel_context *ctx)
+{
+	struct intel_engine_cs *engine;
+
+	for_each_engine(engine, dev_priv) {
+		struct drm_i915_gem_object *ctx_obj =
+				ctx->engine[engine->id].state;
+		struct intel_ringbuffer *ringbuf =
+				ctx->engine[engine->id].ringbuf;
+		void *vaddr;
+		uint32_t *reg_state;
+
+		if (!ctx_obj)
+			continue;
+
+		vaddr = i915_gem_object_pin_map(ctx_obj);
+		if (WARN_ON(IS_ERR(vaddr)))
+			continue;
+
+		reg_state = vaddr + LRC_STATE_PN * PAGE_SIZE;
+		ctx_obj->dirty = true;
+
+		reg_state[CTX_RING_HEAD+1] = 0;
+		reg_state[CTX_RING_TAIL+1] = 0;
+
+		i915_gem_object_unpin_map(ctx_obj);
+
+		ringbuf->head = 0;
+		ringbuf->tail = 0;
+	}
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/i915/intel_lrc.h
@@ -0,0 +1,128 @@
+/*
+ * Copyright © 2014 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef _INTEL_LRC_H_
+#define _INTEL_LRC_H_
+
+#include "intel_ringbuffer.h"
+
+#define GEN8_LR_CONTEXT_ALIGN 4096
+
+/* Execlists regs */
+#define RING_ELSP(ring)				_MMIO((ring)->mmio_base + 0x230)
+#define RING_EXECLIST_STATUS_LO(ring)		_MMIO((ring)->mmio_base + 0x234)
+#define RING_EXECLIST_STATUS_HI(ring)		_MMIO((ring)->mmio_base + 0x234 + 4)
+#define RING_CONTEXT_CONTROL(ring)		_MMIO((ring)->mmio_base + 0x244)
+#define	  CTX_CTRL_INHIBIT_SYN_CTX_SWITCH	(1 << 3)
+#define	  CTX_CTRL_ENGINE_CTX_RESTORE_INHIBIT	(1 << 0)
+#define   CTX_CTRL_RS_CTX_ENABLE                (1 << 1)
+#define RING_CONTEXT_STATUS_BUF_BASE(ring)	_MMIO((ring)->mmio_base + 0x370)
+#define RING_CONTEXT_STATUS_BUF_LO(ring, i)	_MMIO((ring)->mmio_base + 0x370 + (i) * 8)
+#define RING_CONTEXT_STATUS_BUF_HI(ring, i)	_MMIO((ring)->mmio_base + 0x370 + (i) * 8 + 4)
+#define RING_CONTEXT_STATUS_PTR(ring)		_MMIO((ring)->mmio_base + 0x3a0)
+
+/* The docs specify that the write pointer wraps around after 5h, "After status
+ * is written out to the last available status QW at offset 5h, this pointer
+ * wraps to 0."
+ *
+ * Therefore, one must infer than even though there are 3 bits available, 6 and
+ * 7 appear to be * reserved.
+ */
+#define GEN8_CSB_ENTRIES 6
+#define GEN8_CSB_PTR_MASK 0x7
+#define GEN8_CSB_READ_PTR_MASK (GEN8_CSB_PTR_MASK << 8)
+#define GEN8_CSB_WRITE_PTR_MASK (GEN8_CSB_PTR_MASK << 0)
+#define GEN8_CSB_WRITE_PTR(csb_status) \
+	(((csb_status) & GEN8_CSB_WRITE_PTR_MASK) >> 0)
+#define GEN8_CSB_READ_PTR(csb_status) \
+	(((csb_status) & GEN8_CSB_READ_PTR_MASK) >> 8)
+
+/* Logical Rings */
+int intel_logical_ring_alloc_request_extras(struct drm_i915_gem_request *request);
+int intel_logical_ring_reserve_space(struct drm_i915_gem_request *request);
+void intel_logical_ring_stop(struct intel_engine_cs *engine);
+void intel_logical_ring_cleanup(struct intel_engine_cs *engine);
+int intel_logical_rings_init(struct drm_device *dev);
+
+int logical_ring_flush_all_caches(struct drm_i915_gem_request *req);
+/**
+ * intel_logical_ring_advance() - advance the ringbuffer tail
+ * @ringbuf: Ringbuffer to advance.
+ *
+ * The tail is only updated in our logical ringbuffer struct.
+ */
+static inline void intel_logical_ring_advance(struct intel_ringbuffer *ringbuf)
+{
+	ringbuf->tail &= ringbuf->size - 1;
+}
+/**
+ * intel_logical_ring_emit() - write a DWORD to the ringbuffer.
+ * @ringbuf: Ringbuffer to write to.
+ * @data: DWORD to write.
+ */
+static inline void intel_logical_ring_emit(struct intel_ringbuffer *ringbuf,
+					   u32 data)
+{
+	iowrite32(data, ringbuf->virtual_start + ringbuf->tail);
+	ringbuf->tail += 4;
+}
+static inline void intel_logical_ring_emit_reg(struct intel_ringbuffer *ringbuf,
+					       i915_reg_t reg)
+{
+	intel_logical_ring_emit(ringbuf, i915_mmio_reg_offset(reg));
+}
+
+/* Logical Ring Contexts */
+
+/* One extra page is added before LRC for GuC as shared data */
+#define LRC_GUCSHR_PN	(0)
+#define LRC_PPHWSP_PN	(LRC_GUCSHR_PN + 1)
+#define LRC_STATE_PN	(LRC_PPHWSP_PN + 1)
+
+void intel_lr_context_free(struct intel_context *ctx);
+uint32_t intel_lr_context_size(struct intel_engine_cs *engine);
+int intel_lr_context_deferred_alloc(struct intel_context *ctx,
+				    struct intel_engine_cs *engine);
+void intel_lr_context_unpin(struct intel_context *ctx,
+			    struct intel_engine_cs *engine);
+
+struct drm_i915_private;
+
+void intel_lr_context_reset(struct drm_i915_private *dev_priv,
+			    struct intel_context *ctx);
+uint64_t intel_lr_context_descriptor(struct intel_context *ctx,
+				     struct intel_engine_cs *engine);
+
+u32 intel_execlists_ctx_id(struct intel_context *ctx,
+			   struct intel_engine_cs *engine);
+
+/* Execlists */
+int intel_sanitize_enable_execlists(struct drm_device *dev, int enable_execlists);
+struct i915_execbuffer_params;
+int intel_execlists_submission(struct i915_execbuffer_params *params,
+			       struct drm_i915_gem_execbuffer2 *args,
+			       struct list_head *vmas);
+
+void intel_execlists_retire_requests(struct intel_engine_cs *engine);
+
+#endif /* _INTEL_LRC_H_ */
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/i915/intel_lvds.c
@@ -0,0 +1,1143 @@
+/*
+ * Copyright © 2006-2007 Intel Corporation
+ * Copyright (c) 2006 Dave Airlie <airlied@linux.ie>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *	Eric Anholt <eric@anholt.net>
+ *      Dave Airlie <airlied@linux.ie>
+ *      Jesse Barnes <jesse.barnes@intel.com>
+ */
+
+#include <acpi/button.h>
+#include <linux/dmi.h>
+#include <linux/i2c.h>
+#include <linux/slab.h>
+#include <drm/drmP.h>
+#include <drm/drm_atomic_helper.h>
+#include <drm/drm_crtc.h>
+#include <drm/drm_edid.h>
+#include "intel_drv.h"
+#include <drm/i915_drm.h>
+#include "i915_drv.h"
+#include <linux/acpi.h>
+
+/* Private structure for the integrated LVDS support */
+struct intel_lvds_connector {
+	struct intel_connector base;
+
+	struct notifier_block lid_notifier;
+};
+
+struct intel_lvds_encoder {
+	struct intel_encoder base;
+
+	bool is_dual_link;
+	i915_reg_t reg;
+	u32 a3_power;
+
+	struct intel_lvds_connector *attached_connector;
+};
+
+static struct intel_lvds_encoder *to_lvds_encoder(struct drm_encoder *encoder)
+{
+	return container_of(encoder, struct intel_lvds_encoder, base.base);
+}
+
+static struct intel_lvds_connector *to_lvds_connector(struct drm_connector *connector)
+{
+	return container_of(connector, struct intel_lvds_connector, base.base);
+}
+
+static bool intel_lvds_get_hw_state(struct intel_encoder *encoder,
+				    enum pipe *pipe)
+{
+	struct drm_device *dev = encoder->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_lvds_encoder *lvds_encoder = to_lvds_encoder(&encoder->base);
+	enum intel_display_power_domain power_domain;
+	u32 tmp;
+	bool ret;
+
+	power_domain = intel_display_port_power_domain(encoder);
+	if (!intel_display_power_get_if_enabled(dev_priv, power_domain))
+		return false;
+
+	ret = false;
+
+	tmp = I915_READ(lvds_encoder->reg);
+
+	if (!(tmp & LVDS_PORT_EN))
+		goto out;
+
+	if (HAS_PCH_CPT(dev))
+		*pipe = PORT_TO_PIPE_CPT(tmp);
+	else
+		*pipe = PORT_TO_PIPE(tmp);
+
+	ret = true;
+
+out:
+	intel_display_power_put(dev_priv, power_domain);
+
+	return ret;
+}
+
+static void intel_lvds_get_config(struct intel_encoder *encoder,
+				  struct intel_crtc_state *pipe_config)
+{
+	struct drm_device *dev = encoder->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_lvds_encoder *lvds_encoder = to_lvds_encoder(&encoder->base);
+	u32 tmp, flags = 0;
+
+	tmp = I915_READ(lvds_encoder->reg);
+	if (tmp & LVDS_HSYNC_POLARITY)
+		flags |= DRM_MODE_FLAG_NHSYNC;
+	else
+		flags |= DRM_MODE_FLAG_PHSYNC;
+	if (tmp & LVDS_VSYNC_POLARITY)
+		flags |= DRM_MODE_FLAG_NVSYNC;
+	else
+		flags |= DRM_MODE_FLAG_PVSYNC;
+
+	pipe_config->base.adjusted_mode.flags |= flags;
+
+	if (INTEL_INFO(dev)->gen < 5)
+		pipe_config->gmch_pfit.lvds_border_bits =
+			tmp & LVDS_BORDER_ENABLE;
+
+	/* gen2/3 store dither state in pfit control, needs to match */
+	if (INTEL_INFO(dev)->gen < 4) {
+		tmp = I915_READ(PFIT_CONTROL);
+
+		pipe_config->gmch_pfit.control |= tmp & PANEL_8TO6_DITHER_ENABLE;
+	}
+
+	pipe_config->base.adjusted_mode.crtc_clock = pipe_config->port_clock;
+}
+
+static void intel_pre_enable_lvds(struct intel_encoder *encoder)
+{
+	struct intel_lvds_encoder *lvds_encoder = to_lvds_encoder(&encoder->base);
+	struct drm_device *dev = encoder->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc);
+	const struct drm_display_mode *adjusted_mode = &crtc->config->base.adjusted_mode;
+	int pipe = crtc->pipe;
+	u32 temp;
+
+	if (HAS_PCH_SPLIT(dev)) {
+		assert_fdi_rx_pll_disabled(dev_priv, pipe);
+		assert_shared_dpll_disabled(dev_priv,
+					    crtc->config->shared_dpll);
+	} else {
+		assert_pll_disabled(dev_priv, pipe);
+	}
+
+	temp = I915_READ(lvds_encoder->reg);
+	temp |= LVDS_PORT_EN | LVDS_A0A2_CLKA_POWER_UP;
+
+	if (HAS_PCH_CPT(dev)) {
+		temp &= ~PORT_TRANS_SEL_MASK;
+		temp |= PORT_TRANS_SEL_CPT(pipe);
+	} else {
+		if (pipe == 1) {
+			temp |= LVDS_PIPEB_SELECT;
+		} else {
+			temp &= ~LVDS_PIPEB_SELECT;
+		}
+	}
+
+	/* set the corresponsding LVDS_BORDER bit */
+	temp &= ~LVDS_BORDER_ENABLE;
+	temp |= crtc->config->gmch_pfit.lvds_border_bits;
+	/* Set the B0-B3 data pairs corresponding to whether we're going to
+	 * set the DPLLs for dual-channel mode or not.
+	 */
+	if (lvds_encoder->is_dual_link)
+		temp |= LVDS_B0B3_POWER_UP | LVDS_CLKB_POWER_UP;
+	else
+		temp &= ~(LVDS_B0B3_POWER_UP | LVDS_CLKB_POWER_UP);
+
+	/* It would be nice to set 24 vs 18-bit mode (LVDS_A3_POWER_UP)
+	 * appropriately here, but we need to look more thoroughly into how
+	 * panels behave in the two modes. For now, let's just maintain the
+	 * value we got from the BIOS.
+	 */
+	 temp &= ~LVDS_A3_POWER_MASK;
+	 temp |= lvds_encoder->a3_power;
+
+	/* Set the dithering flag on LVDS as needed, note that there is no
+	 * special lvds dither control bit on pch-split platforms, dithering is
+	 * only controlled through the PIPECONF reg. */
+	if (INTEL_INFO(dev)->gen == 4) {
+		/* Bspec wording suggests that LVDS port dithering only exists
+		 * for 18bpp panels. */
+		if (crtc->config->dither && crtc->config->pipe_bpp == 18)
+			temp |= LVDS_ENABLE_DITHER;
+		else
+			temp &= ~LVDS_ENABLE_DITHER;
+	}
+	temp &= ~(LVDS_HSYNC_POLARITY | LVDS_VSYNC_POLARITY);
+	if (adjusted_mode->flags & DRM_MODE_FLAG_NHSYNC)
+		temp |= LVDS_HSYNC_POLARITY;
+	if (adjusted_mode->flags & DRM_MODE_FLAG_NVSYNC)
+		temp |= LVDS_VSYNC_POLARITY;
+
+	I915_WRITE(lvds_encoder->reg, temp);
+}
+
+/**
+ * Sets the power state for the panel.
+ */
+static void intel_enable_lvds(struct intel_encoder *encoder)
+{
+	struct drm_device *dev = encoder->base.dev;
+	struct intel_lvds_encoder *lvds_encoder = to_lvds_encoder(&encoder->base);
+	struct intel_connector *intel_connector =
+		&lvds_encoder->attached_connector->base;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	i915_reg_t ctl_reg, stat_reg;
+
+	if (HAS_PCH_SPLIT(dev)) {
+		ctl_reg = PCH_PP_CONTROL;
+		stat_reg = PCH_PP_STATUS;
+	} else {
+		ctl_reg = PP_CONTROL;
+		stat_reg = PP_STATUS;
+	}
+
+	I915_WRITE(lvds_encoder->reg, I915_READ(lvds_encoder->reg) | LVDS_PORT_EN);
+
+	I915_WRITE(ctl_reg, I915_READ(ctl_reg) | POWER_TARGET_ON);
+	POSTING_READ(lvds_encoder->reg);
+	if (wait_for((I915_READ(stat_reg) & PP_ON) != 0, 1000))
+		DRM_ERROR("timed out waiting for panel to power on\n");
+
+	intel_panel_enable_backlight(intel_connector);
+}
+
+static void intel_disable_lvds(struct intel_encoder *encoder)
+{
+	struct drm_device *dev = encoder->base.dev;
+	struct intel_lvds_encoder *lvds_encoder = to_lvds_encoder(&encoder->base);
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	i915_reg_t ctl_reg, stat_reg;
+
+	if (HAS_PCH_SPLIT(dev)) {
+		ctl_reg = PCH_PP_CONTROL;
+		stat_reg = PCH_PP_STATUS;
+	} else {
+		ctl_reg = PP_CONTROL;
+		stat_reg = PP_STATUS;
+	}
+
+	I915_WRITE(ctl_reg, I915_READ(ctl_reg) & ~POWER_TARGET_ON);
+	if (wait_for((I915_READ(stat_reg) & PP_ON) == 0, 1000))
+		DRM_ERROR("timed out waiting for panel to power off\n");
+
+	I915_WRITE(lvds_encoder->reg, I915_READ(lvds_encoder->reg) & ~LVDS_PORT_EN);
+	POSTING_READ(lvds_encoder->reg);
+}
+
+static void gmch_disable_lvds(struct intel_encoder *encoder)
+{
+	struct intel_lvds_encoder *lvds_encoder = to_lvds_encoder(&encoder->base);
+	struct intel_connector *intel_connector =
+		&lvds_encoder->attached_connector->base;
+
+	intel_panel_disable_backlight(intel_connector);
+
+	intel_disable_lvds(encoder);
+}
+
+static void pch_disable_lvds(struct intel_encoder *encoder)
+{
+	struct intel_lvds_encoder *lvds_encoder = to_lvds_encoder(&encoder->base);
+	struct intel_connector *intel_connector =
+		&lvds_encoder->attached_connector->base;
+
+	intel_panel_disable_backlight(intel_connector);
+}
+
+static void pch_post_disable_lvds(struct intel_encoder *encoder)
+{
+	intel_disable_lvds(encoder);
+}
+
+static enum drm_mode_status
+intel_lvds_mode_valid(struct drm_connector *connector,
+		      struct drm_display_mode *mode)
+{
+	struct intel_connector *intel_connector = to_intel_connector(connector);
+	struct drm_display_mode *fixed_mode = intel_connector->panel.fixed_mode;
+	int max_pixclk = to_i915(connector->dev)->max_dotclk_freq;
+
+	if (mode->hdisplay > fixed_mode->hdisplay)
+		return MODE_PANEL;
+	if (mode->vdisplay > fixed_mode->vdisplay)
+		return MODE_PANEL;
+	if (fixed_mode->clock > max_pixclk)
+		return MODE_CLOCK_HIGH;
+
+	return MODE_OK;
+}
+
+static bool intel_lvds_compute_config(struct intel_encoder *intel_encoder,
+				      struct intel_crtc_state *pipe_config)
+{
+	struct drm_device *dev = intel_encoder->base.dev;
+	struct intel_lvds_encoder *lvds_encoder =
+		to_lvds_encoder(&intel_encoder->base);
+	struct intel_connector *intel_connector =
+		&lvds_encoder->attached_connector->base;
+	struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
+	struct intel_crtc *intel_crtc = to_intel_crtc(pipe_config->base.crtc);
+	unsigned int lvds_bpp;
+
+	/* Should never happen!! */
+	if (INTEL_INFO(dev)->gen < 4 && intel_crtc->pipe == 0) {
+		DRM_ERROR("Can't support LVDS on pipe A\n");
+		return false;
+	}
+
+	if (lvds_encoder->a3_power == LVDS_A3_POWER_UP)
+		lvds_bpp = 8*3;
+	else
+		lvds_bpp = 6*3;
+
+	if (lvds_bpp != pipe_config->pipe_bpp && !pipe_config->bw_constrained) {
+		DRM_DEBUG_KMS("forcing display bpp (was %d) to LVDS (%d)\n",
+			      pipe_config->pipe_bpp, lvds_bpp);
+		pipe_config->pipe_bpp = lvds_bpp;
+	}
+
+	/*
+	 * We have timings from the BIOS for the panel, put them in
+	 * to the adjusted mode.  The CRTC will be set up for this mode,
+	 * with the panel scaling set up to source from the H/VDisplay
+	 * of the original mode.
+	 */
+	intel_fixed_panel_mode(intel_connector->panel.fixed_mode,
+			       adjusted_mode);
+
+	if (HAS_PCH_SPLIT(dev)) {
+		pipe_config->has_pch_encoder = true;
+
+		intel_pch_panel_fitting(intel_crtc, pipe_config,
+					intel_connector->panel.fitting_mode);
+	} else {
+		intel_gmch_panel_fitting(intel_crtc, pipe_config,
+					 intel_connector->panel.fitting_mode);
+
+	}
+
+	/*
+	 * XXX: It would be nice to support lower refresh rates on the
+	 * panels to reduce power consumption, and perhaps match the
+	 * user's requested refresh rate.
+	 */
+
+	return true;
+}
+
+/**
+ * Detect the LVDS connection.
+ *
+ * Since LVDS doesn't have hotlug, we use the lid as a proxy.  Open means
+ * connected and closed means disconnected.  We also send hotplug events as
+ * needed, using lid status notification from the input layer.
+ */
+static enum drm_connector_status
+intel_lvds_detect(struct drm_connector *connector, bool force)
+{
+	struct drm_device *dev = connector->dev;
+	enum drm_connector_status status;
+
+	DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
+		      connector->base.id, connector->name);
+
+	status = intel_panel_detect(dev);
+	if (status != connector_status_unknown)
+		return status;
+
+	return connector_status_connected;
+}
+
+/**
+ * Return the list of DDC modes if available, or the BIOS fixed mode otherwise.
+ */
+static int intel_lvds_get_modes(struct drm_connector *connector)
+{
+	struct intel_lvds_connector *lvds_connector = to_lvds_connector(connector);
+	struct drm_device *dev = connector->dev;
+	struct drm_display_mode *mode;
+
+	/* use cached edid if we have one */
+	if (!IS_ERR_OR_NULL(lvds_connector->base.edid))
+		return drm_add_edid_modes(connector, lvds_connector->base.edid);
+
+	mode = drm_mode_duplicate(dev, lvds_connector->base.panel.fixed_mode);
+	if (mode == NULL)
+		return 0;
+
+	drm_mode_probed_add(connector, mode);
+	return 1;
+}
+
+static int intel_no_modeset_on_lid_dmi_callback(const struct dmi_system_id *id)
+{
+	DRM_INFO("Skipping forced modeset for %s\n", id->ident);
+	return 1;
+}
+
+/* The GPU hangs up on these systems if modeset is performed on LID open */
+static const struct dmi_system_id intel_no_modeset_on_lid[] = {
+	{
+		.callback = intel_no_modeset_on_lid_dmi_callback,
+		.ident = "Toshiba Tecra A11",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "TECRA A11"),
+		},
+	},
+
+	{ }	/* terminating entry */
+};
+
+/*
+ * Lid events. Note the use of 'modeset':
+ *  - we set it to MODESET_ON_LID_OPEN on lid close,
+ *    and set it to MODESET_DONE on open
+ *  - we use it as a "only once" bit (ie we ignore
+ *    duplicate events where it was already properly set)
+ *  - the suspend/resume paths will set it to
+ *    MODESET_SUSPENDED and ignore the lid open event,
+ *    because they restore the mode ("lid open").
+ */
+static int intel_lid_notify(struct notifier_block *nb, unsigned long val,
+			    void *unused)
+{
+	struct intel_lvds_connector *lvds_connector =
+		container_of(nb, struct intel_lvds_connector, lid_notifier);
+	struct drm_connector *connector = &lvds_connector->base.base;
+	struct drm_device *dev = connector->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	if (dev->switch_power_state != DRM_SWITCH_POWER_ON)
+		return NOTIFY_OK;
+
+	mutex_lock(&dev_priv->modeset_restore_lock);
+	if (dev_priv->modeset_restore == MODESET_SUSPENDED)
+		goto exit;
+	/*
+	 * check and update the status of LVDS connector after receiving
+	 * the LID nofication event.
+	 */
+	connector->status = connector->funcs->detect(connector, false);
+
+	/* Don't force modeset on machines where it causes a GPU lockup */
+	if (dmi_check_system(intel_no_modeset_on_lid))
+		goto exit;
+	if (!acpi_lid_open()) {
+		/* do modeset on next lid open event */
+		dev_priv->modeset_restore = MODESET_ON_LID_OPEN;
+		goto exit;
+	}
+
+	if (dev_priv->modeset_restore == MODESET_DONE)
+		goto exit;
+
+	/*
+	 * Some old platform's BIOS love to wreak havoc while the lid is closed.
+	 * We try to detect this here and undo any damage. The split for PCH
+	 * platforms is rather conservative and a bit arbitrary expect that on
+	 * those platforms VGA disabling requires actual legacy VGA I/O access,
+	 * and as part of the cleanup in the hw state restore we also redisable
+	 * the vga plane.
+	 */
+	if (!HAS_PCH_SPLIT(dev))
+		intel_display_resume(dev);
+
+	dev_priv->modeset_restore = MODESET_DONE;
+
+exit:
+	mutex_unlock(&dev_priv->modeset_restore_lock);
+	return NOTIFY_OK;
+}
+
+/**
+ * intel_lvds_destroy - unregister and free LVDS structures
+ * @connector: connector to free
+ *
+ * Unregister the DDC bus for this connector then free the driver private
+ * structure.
+ */
+static void intel_lvds_destroy(struct drm_connector *connector)
+{
+	struct intel_lvds_connector *lvds_connector =
+		to_lvds_connector(connector);
+
+	if (lvds_connector->lid_notifier.notifier_call)
+		acpi_lid_notifier_unregister(&lvds_connector->lid_notifier);
+
+	if (!IS_ERR_OR_NULL(lvds_connector->base.edid))
+		kfree(lvds_connector->base.edid);
+
+	intel_panel_fini(&lvds_connector->base.panel);
+
+	drm_connector_cleanup(connector);
+	kfree(connector);
+}
+
+static int intel_lvds_set_property(struct drm_connector *connector,
+				   struct drm_property *property,
+				   uint64_t value)
+{
+	struct intel_connector *intel_connector = to_intel_connector(connector);
+	struct drm_device *dev = connector->dev;
+
+	if (property == dev->mode_config.scaling_mode_property) {
+		struct drm_crtc *crtc;
+
+		if (value == DRM_MODE_SCALE_NONE) {
+			DRM_DEBUG_KMS("no scaling not supported\n");
+			return -EINVAL;
+		}
+
+		if (intel_connector->panel.fitting_mode == value) {
+			/* the LVDS scaling property is not changed */
+			return 0;
+		}
+		intel_connector->panel.fitting_mode = value;
+
+		crtc = intel_attached_encoder(connector)->base.crtc;
+		if (crtc && crtc->state->enable) {
+			/*
+			 * If the CRTC is enabled, the display will be changed
+			 * according to the new panel fitting mode.
+			 */
+			intel_crtc_restore_mode(crtc);
+		}
+	}
+
+	return 0;
+}
+
+static const struct drm_connector_helper_funcs intel_lvds_connector_helper_funcs = {
+	.get_modes = intel_lvds_get_modes,
+	.mode_valid = intel_lvds_mode_valid,
+	.best_encoder = intel_best_encoder,
+};
+
+static const struct drm_connector_funcs intel_lvds_connector_funcs = {
+	.dpms = drm_atomic_helper_connector_dpms,
+	.detect = intel_lvds_detect,
+	.fill_modes = drm_helper_probe_single_connector_modes,
+	.set_property = intel_lvds_set_property,
+	.atomic_get_property = intel_connector_atomic_get_property,
+	.destroy = intel_lvds_destroy,
+	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
+	.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
+};
+
+static const struct drm_encoder_funcs intel_lvds_enc_funcs = {
+	.destroy = intel_encoder_destroy,
+};
+
+static int intel_no_lvds_dmi_callback(const struct dmi_system_id *id)
+{
+	DRM_INFO("Skipping LVDS initialization for %s\n", id->ident);
+	return 1;
+}
+
+/* These systems claim to have LVDS, but really don't */
+static const struct dmi_system_id intel_no_lvds[] = {
+	{
+		.callback = intel_no_lvds_dmi_callback,
+		.ident = "Apple Mac Mini (Core series)",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Apple"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "Macmini1,1"),
+		},
+	},
+	{
+		.callback = intel_no_lvds_dmi_callback,
+		.ident = "Apple Mac Mini (Core 2 series)",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Apple"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "Macmini2,1"),
+		},
+	},
+	{
+		.callback = intel_no_lvds_dmi_callback,
+		.ident = "MSI IM-945GSE-A",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "MSI"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "A9830IMS"),
+		},
+	},
+	{
+		.callback = intel_no_lvds_dmi_callback,
+		.ident = "Dell Studio Hybrid",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+			DMI_MATCH(DMI_PRODUCT_NAME, "Studio Hybrid 140g"),
+		},
+	},
+	{
+		.callback = intel_no_lvds_dmi_callback,
+		.ident = "Dell OptiPlex FX170",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+			DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex FX170"),
+		},
+	},
+	{
+		.callback = intel_no_lvds_dmi_callback,
+		.ident = "AOpen Mini PC",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "AOpen"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "i965GMx-IF"),
+		},
+	},
+	{
+		.callback = intel_no_lvds_dmi_callback,
+		.ident = "AOpen Mini PC MP915",
+		.matches = {
+			DMI_MATCH(DMI_BOARD_VENDOR, "AOpen"),
+			DMI_MATCH(DMI_BOARD_NAME, "i915GMx-F"),
+		},
+	},
+	{
+		.callback = intel_no_lvds_dmi_callback,
+		.ident = "AOpen i915GMm-HFS",
+		.matches = {
+			DMI_MATCH(DMI_BOARD_VENDOR, "AOpen"),
+			DMI_MATCH(DMI_BOARD_NAME, "i915GMm-HFS"),
+		},
+	},
+	{
+		.callback = intel_no_lvds_dmi_callback,
+                .ident = "AOpen i45GMx-I",
+                .matches = {
+                        DMI_MATCH(DMI_BOARD_VENDOR, "AOpen"),
+                        DMI_MATCH(DMI_BOARD_NAME, "i45GMx-I"),
+                },
+        },
+	{
+		.callback = intel_no_lvds_dmi_callback,
+		.ident = "Aopen i945GTt-VFA",
+		.matches = {
+			DMI_MATCH(DMI_PRODUCT_VERSION, "AO00001JW"),
+		},
+	},
+	{
+		.callback = intel_no_lvds_dmi_callback,
+		.ident = "Clientron U800",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Clientron"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "U800"),
+		},
+	},
+	{
+                .callback = intel_no_lvds_dmi_callback,
+                .ident = "Clientron E830",
+                .matches = {
+                        DMI_MATCH(DMI_SYS_VENDOR, "Clientron"),
+                        DMI_MATCH(DMI_PRODUCT_NAME, "E830"),
+                },
+        },
+        {
+		.callback = intel_no_lvds_dmi_callback,
+		.ident = "Asus EeeBox PC EB1007",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer INC."),
+			DMI_MATCH(DMI_PRODUCT_NAME, "EB1007"),
+		},
+	},
+	{
+		.callback = intel_no_lvds_dmi_callback,
+		.ident = "Asus AT5NM10T-I",
+		.matches = {
+			DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
+			DMI_MATCH(DMI_BOARD_NAME, "AT5NM10T-I"),
+		},
+	},
+	{
+		.callback = intel_no_lvds_dmi_callback,
+		.ident = "Hewlett-Packard HP t5740",
+		.matches = {
+			DMI_MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"),
+			DMI_MATCH(DMI_PRODUCT_NAME, " t5740"),
+		},
+	},
+	{
+		.callback = intel_no_lvds_dmi_callback,
+		.ident = "Hewlett-Packard t5745",
+		.matches = {
+			DMI_MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "hp t5745"),
+		},
+	},
+	{
+		.callback = intel_no_lvds_dmi_callback,
+		.ident = "Hewlett-Packard st5747",
+		.matches = {
+			DMI_MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "hp st5747"),
+		},
+	},
+	{
+		.callback = intel_no_lvds_dmi_callback,
+		.ident = "MSI Wind Box DC500",
+		.matches = {
+			DMI_MATCH(DMI_BOARD_VENDOR, "MICRO-STAR INTERNATIONAL CO., LTD"),
+			DMI_MATCH(DMI_BOARD_NAME, "MS-7469"),
+		},
+	},
+	{
+		.callback = intel_no_lvds_dmi_callback,
+		.ident = "Gigabyte GA-D525TUD",
+		.matches = {
+			DMI_MATCH(DMI_BOARD_VENDOR, "Gigabyte Technology Co., Ltd."),
+			DMI_MATCH(DMI_BOARD_NAME, "D525TUD"),
+		},
+	},
+	{
+		.callback = intel_no_lvds_dmi_callback,
+		.ident = "Supermicro X7SPA-H",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Supermicro"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "X7SPA-H"),
+		},
+	},
+	{
+		.callback = intel_no_lvds_dmi_callback,
+		.ident = "Fujitsu Esprimo Q900",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "ESPRIMO Q900"),
+		},
+	},
+	{
+		.callback = intel_no_lvds_dmi_callback,
+		.ident = "Intel D410PT",
+		.matches = {
+			DMI_MATCH(DMI_BOARD_VENDOR, "Intel"),
+			DMI_MATCH(DMI_BOARD_NAME, "D410PT"),
+		},
+	},
+	{
+		.callback = intel_no_lvds_dmi_callback,
+		.ident = "Intel D425KT",
+		.matches = {
+			DMI_MATCH(DMI_BOARD_VENDOR, "Intel"),
+			DMI_EXACT_MATCH(DMI_BOARD_NAME, "D425KT"),
+		},
+	},
+	{
+		.callback = intel_no_lvds_dmi_callback,
+		.ident = "Intel D510MO",
+		.matches = {
+			DMI_MATCH(DMI_BOARD_VENDOR, "Intel"),
+			DMI_EXACT_MATCH(DMI_BOARD_NAME, "D510MO"),
+		},
+	},
+	{
+		.callback = intel_no_lvds_dmi_callback,
+		.ident = "Intel D525MW",
+		.matches = {
+			DMI_MATCH(DMI_BOARD_VENDOR, "Intel"),
+			DMI_EXACT_MATCH(DMI_BOARD_NAME, "D525MW"),
+		},
+	},
+
+	{ }	/* terminating entry */
+};
+
+static int intel_dual_link_lvds_callback(const struct dmi_system_id *id)
+{
+	DRM_INFO("Forcing lvds to dual link mode on %s\n", id->ident);
+	return 1;
+}
+
+static const struct dmi_system_id intel_dual_link_lvds[] = {
+	{
+		.callback = intel_dual_link_lvds_callback,
+		.ident = "Apple MacBook Pro 15\" (2010)",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
+			DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro6,2"),
+		},
+	},
+	{
+		.callback = intel_dual_link_lvds_callback,
+		.ident = "Apple MacBook Pro 15\" (2011)",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
+			DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro8,2"),
+		},
+	},
+	{
+		.callback = intel_dual_link_lvds_callback,
+		.ident = "Apple MacBook Pro 15\" (2012)",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
+			DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro9,1"),
+		},
+	},
+	{ }	/* terminating entry */
+};
+
+bool intel_is_dual_link_lvds(struct drm_device *dev)
+{
+	struct intel_encoder *encoder;
+	struct intel_lvds_encoder *lvds_encoder;
+
+	for_each_intel_encoder(dev, encoder) {
+		if (encoder->type == INTEL_OUTPUT_LVDS) {
+			lvds_encoder = to_lvds_encoder(&encoder->base);
+
+			return lvds_encoder->is_dual_link;
+		}
+	}
+
+	return false;
+}
+
+static bool compute_is_dual_link_lvds(struct intel_lvds_encoder *lvds_encoder)
+{
+	struct drm_device *dev = lvds_encoder->base.base.dev;
+	unsigned int val;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	/* use the module option value if specified */
+	if (i915.lvds_channel_mode > 0)
+		return i915.lvds_channel_mode == 2;
+
+	/* single channel LVDS is limited to 112 MHz */
+	if (lvds_encoder->attached_connector->base.panel.fixed_mode->clock
+	    > 112999)
+		return true;
+
+	if (dmi_check_system(intel_dual_link_lvds))
+		return true;
+
+	/* BIOS should set the proper LVDS register value at boot, but
+	 * in reality, it doesn't set the value when the lid is closed;
+	 * we need to check "the value to be set" in VBT when LVDS
+	 * register is uninitialized.
+	 */
+	val = I915_READ(lvds_encoder->reg);
+	if (!(val & ~(LVDS_PIPE_MASK | LVDS_DETECTED)))
+		val = dev_priv->vbt.bios_lvds_val;
+
+	return (val & LVDS_CLKB_POWER_MASK) == LVDS_CLKB_POWER_UP;
+}
+
+static bool intel_lvds_supported(struct drm_device *dev)
+{
+	/* With the introduction of the PCH we gained a dedicated
+	 * LVDS presence pin, use it. */
+	if (HAS_PCH_IBX(dev) || HAS_PCH_CPT(dev))
+		return true;
+
+	/* Otherwise LVDS was only attached to mobile products,
+	 * except for the inglorious 830gm */
+	if (INTEL_INFO(dev)->gen <= 4 && IS_MOBILE(dev) && !IS_I830(dev))
+		return true;
+
+	return false;
+}
+
+/**
+ * intel_lvds_init - setup LVDS connectors on this device
+ * @dev: drm device
+ *
+ * Create the connector, register the LVDS DDC bus, and try to figure out what
+ * modes we can display on the LVDS panel (if present).
+ */
+void intel_lvds_init(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_lvds_encoder *lvds_encoder;
+	struct intel_encoder *intel_encoder;
+	struct intel_lvds_connector *lvds_connector;
+	struct intel_connector *intel_connector;
+	struct drm_connector *connector;
+	struct drm_encoder *encoder;
+	struct drm_display_mode *scan; /* *modes, *bios_mode; */
+	struct drm_display_mode *fixed_mode = NULL;
+	struct drm_display_mode *downclock_mode = NULL;
+	struct edid *edid;
+	struct drm_crtc *crtc;
+	i915_reg_t lvds_reg;
+	u32 lvds;
+	int pipe;
+	u8 pin;
+
+	/*
+	 * Unlock registers and just leave them unlocked. Do this before
+	 * checking quirk lists to avoid bogus WARNINGs.
+	 */
+	if (HAS_PCH_SPLIT(dev)) {
+		I915_WRITE(PCH_PP_CONTROL,
+			   I915_READ(PCH_PP_CONTROL) | PANEL_UNLOCK_REGS);
+	} else if (INTEL_INFO(dev_priv)->gen < 5) {
+		I915_WRITE(PP_CONTROL,
+			   I915_READ(PP_CONTROL) | PANEL_UNLOCK_REGS);
+	}
+	if (!intel_lvds_supported(dev))
+		return;
+
+	/* Skip init on machines we know falsely report LVDS */
+	if (dmi_check_system(intel_no_lvds))
+		return;
+
+	if (HAS_PCH_SPLIT(dev))
+		lvds_reg = PCH_LVDS;
+	else
+		lvds_reg = LVDS;
+
+	lvds = I915_READ(lvds_reg);
+
+	if (HAS_PCH_SPLIT(dev)) {
+		if ((lvds & LVDS_DETECTED) == 0)
+			return;
+		if (dev_priv->vbt.edp.support) {
+			DRM_DEBUG_KMS("disable LVDS for eDP support\n");
+			return;
+		}
+	}
+
+	pin = GMBUS_PIN_PANEL;
+	if (!intel_bios_is_lvds_present(dev_priv, &pin)) {
+		if ((lvds & LVDS_PORT_EN) == 0) {
+			DRM_DEBUG_KMS("LVDS is not present in VBT\n");
+			return;
+		}
+		DRM_DEBUG_KMS("LVDS is not present in VBT, but enabled anyway\n");
+	}
+
+	 /* Set the Panel Power On/Off timings if uninitialized. */
+	if (INTEL_INFO(dev_priv)->gen < 5 &&
+	    I915_READ(PP_ON_DELAYS) == 0 && I915_READ(PP_OFF_DELAYS) == 0) {
+		/* Set T2 to 40ms and T5 to 200ms */
+		I915_WRITE(PP_ON_DELAYS, 0x019007d0);
+
+		/* Set T3 to 35ms and Tx to 200ms */
+		I915_WRITE(PP_OFF_DELAYS, 0x015e07d0);
+
+		DRM_DEBUG_KMS("Panel power timings uninitialized, setting defaults\n");
+	}
+
+	lvds_encoder = kzalloc(sizeof(*lvds_encoder), GFP_KERNEL);
+	if (!lvds_encoder)
+		return;
+
+	lvds_connector = kzalloc(sizeof(*lvds_connector), GFP_KERNEL);
+	if (!lvds_connector) {
+		kfree(lvds_encoder);
+		return;
+	}
+
+	if (intel_connector_init(&lvds_connector->base) < 0) {
+		kfree(lvds_connector);
+		kfree(lvds_encoder);
+		return;
+	}
+
+	lvds_encoder->attached_connector = lvds_connector;
+
+	intel_encoder = &lvds_encoder->base;
+	encoder = &intel_encoder->base;
+	intel_connector = &lvds_connector->base;
+	connector = &intel_connector->base;
+	drm_connector_init(dev, &intel_connector->base, &intel_lvds_connector_funcs,
+			   DRM_MODE_CONNECTOR_LVDS);
+
+	drm_encoder_init(dev, &intel_encoder->base, &intel_lvds_enc_funcs,
+			 DRM_MODE_ENCODER_LVDS);
+
+	intel_encoder->enable = intel_enable_lvds;
+	intel_encoder->pre_enable = intel_pre_enable_lvds;
+	intel_encoder->compute_config = intel_lvds_compute_config;
+	if (HAS_PCH_SPLIT(dev_priv)) {
+		intel_encoder->disable = pch_disable_lvds;
+		intel_encoder->post_disable = pch_post_disable_lvds;
+	} else {
+		intel_encoder->disable = gmch_disable_lvds;
+	}
+	intel_encoder->get_hw_state = intel_lvds_get_hw_state;
+	intel_encoder->get_config = intel_lvds_get_config;
+	intel_connector->get_hw_state = intel_connector_get_hw_state;
+	intel_connector->unregister = intel_connector_unregister;
+
+	intel_connector_attach_encoder(intel_connector, intel_encoder);
+	intel_encoder->type = INTEL_OUTPUT_LVDS;
+
+	intel_encoder->cloneable = 0;
+	if (HAS_PCH_SPLIT(dev))
+		intel_encoder->crtc_mask = (1 << 0) | (1 << 1) | (1 << 2);
+	else if (IS_GEN4(dev))
+		intel_encoder->crtc_mask = (1 << 0) | (1 << 1);
+	else
+		intel_encoder->crtc_mask = (1 << 1);
+
+	drm_connector_helper_add(connector, &intel_lvds_connector_helper_funcs);
+	connector->display_info.subpixel_order = SubPixelHorizontalRGB;
+	connector->interlace_allowed = false;
+	connector->doublescan_allowed = false;
+
+	lvds_encoder->reg = lvds_reg;
+
+	/* create the scaling mode property */
+	drm_mode_create_scaling_mode_property(dev);
+	drm_object_attach_property(&connector->base,
+				      dev->mode_config.scaling_mode_property,
+				      DRM_MODE_SCALE_ASPECT);
+	intel_connector->panel.fitting_mode = DRM_MODE_SCALE_ASPECT;
+	/*
+	 * LVDS discovery:
+	 * 1) check for EDID on DDC
+	 * 2) check for VBT data
+	 * 3) check to see if LVDS is already on
+	 *    if none of the above, no panel
+	 * 4) make sure lid is open
+	 *    if closed, act like it's not there for now
+	 */
+
+	/*
+	 * Attempt to get the fixed panel mode from DDC.  Assume that the
+	 * preferred mode is the right one.
+	 */
+	mutex_lock(&dev->mode_config.mutex);
+	edid = drm_get_edid(connector, intel_gmbus_get_adapter(dev_priv, pin));
+	if (edid) {
+		if (drm_add_edid_modes(connector, edid)) {
+			drm_mode_connector_update_edid_property(connector,
+								edid);
+		} else {
+			kfree(edid);
+			edid = ERR_PTR(-EINVAL);
+		}
+	} else {
+		edid = ERR_PTR(-ENOENT);
+	}
+	lvds_connector->base.edid = edid;
+
+	if (IS_ERR_OR_NULL(edid)) {
+		/* Didn't get an EDID, so
+		 * Set wide sync ranges so we get all modes
+		 * handed to valid_mode for checking
+		 */
+		connector->display_info.min_vfreq = 0;
+		connector->display_info.max_vfreq = 200;
+		connector->display_info.min_hfreq = 0;
+		connector->display_info.max_hfreq = 200;
+	}
+
+	list_for_each_entry(scan, &connector->probed_modes, head) {
+		if (scan->type & DRM_MODE_TYPE_PREFERRED) {
+			DRM_DEBUG_KMS("using preferred mode from EDID: ");
+			drm_mode_debug_printmodeline(scan);
+
+			fixed_mode = drm_mode_duplicate(dev, scan);
+			if (fixed_mode)
+				goto out;
+		}
+	}
+
+	/* Failed to get EDID, what about VBT? */
+	if (dev_priv->vbt.lfp_lvds_vbt_mode) {
+		DRM_DEBUG_KMS("using mode from VBT: ");
+		drm_mode_debug_printmodeline(dev_priv->vbt.lfp_lvds_vbt_mode);
+
+		fixed_mode = drm_mode_duplicate(dev, dev_priv->vbt.lfp_lvds_vbt_mode);
+		if (fixed_mode) {
+			fixed_mode->type |= DRM_MODE_TYPE_PREFERRED;
+			connector->display_info.width_mm = fixed_mode->width_mm;
+			connector->display_info.height_mm = fixed_mode->height_mm;
+			goto out;
+		}
+	}
+
+	/*
+	 * If we didn't get EDID, try checking if the panel is already turned
+	 * on.  If so, assume that whatever is currently programmed is the
+	 * correct mode.
+	 */
+
+	/* Ironlake: FIXME if still fail, not try pipe mode now */
+	if (HAS_PCH_SPLIT(dev))
+		goto failed;
+
+	pipe = (lvds & LVDS_PIPEB_SELECT) ? 1 : 0;
+	crtc = intel_get_crtc_for_pipe(dev, pipe);
+
+	if (crtc && (lvds & LVDS_PORT_EN)) {
+		fixed_mode = intel_crtc_mode_get(dev, crtc);
+		if (fixed_mode) {
+			DRM_DEBUG_KMS("using current (BIOS) mode: ");
+			drm_mode_debug_printmodeline(fixed_mode);
+			fixed_mode->type |= DRM_MODE_TYPE_PREFERRED;
+			goto out;
+		}
+	}
+
+	/* If we still don't have a mode after all that, give up. */
+	if (!fixed_mode)
+		goto failed;
+
+out:
+	mutex_unlock(&dev->mode_config.mutex);
+
+	intel_panel_init(&intel_connector->panel, fixed_mode, downclock_mode);
+
+	lvds_encoder->is_dual_link = compute_is_dual_link_lvds(lvds_encoder);
+	DRM_DEBUG_KMS("detected %s-link lvds configuration\n",
+		      lvds_encoder->is_dual_link ? "dual" : "single");
+
+	lvds_encoder->a3_power = lvds & LVDS_A3_POWER_MASK;
+
+	lvds_connector->lid_notifier.notifier_call = intel_lid_notify;
+	if (acpi_lid_notifier_register(&lvds_connector->lid_notifier)) {
+		DRM_DEBUG_KMS("lid notifier registration failed\n");
+		lvds_connector->lid_notifier.notifier_call = NULL;
+	}
+	drm_connector_register(connector);
+
+	intel_panel_setup_backlight(connector, INVALID_PIPE);
+
+	return;
+
+failed:
+	mutex_unlock(&dev->mode_config.mutex);
+
+	DRM_DEBUG_KMS("No LVDS modes found, disabling.\n");
+	drm_connector_cleanup(connector);
+	drm_encoder_cleanup(encoder);
+	kfree(lvds_encoder);
+	kfree(lvds_connector);
+	return;
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/i915/intel_mocs.c
@@ -0,0 +1,427 @@
+/*
+ * Copyright (c) 2015 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions: *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include "intel_mocs.h"
+#include "intel_lrc.h"
+#include "intel_ringbuffer.h"
+
+/* structures required */
+struct drm_i915_mocs_entry {
+	u32 control_value;
+	u16 l3cc_value;
+};
+
+struct drm_i915_mocs_table {
+	u32 size;
+	const struct drm_i915_mocs_entry *table;
+};
+
+/* Defines for the tables (XXX_MOCS_0 - XXX_MOCS_63) */
+#define LE_CACHEABILITY(value)	((value) << 0)
+#define LE_TGT_CACHE(value)	((value) << 2)
+#define LE_LRUM(value)		((value) << 4)
+#define LE_AOM(value)		((value) << 6)
+#define LE_RSC(value)		((value) << 7)
+#define LE_SCC(value)		((value) << 8)
+#define LE_PFM(value)		((value) << 11)
+#define LE_SCF(value)		((value) << 14)
+
+/* Defines for the tables (LNCFMOCS0 - LNCFMOCS31) - two entries per word */
+#define L3_ESC(value)		((value) << 0)
+#define L3_SCC(value)		((value) << 1)
+#define L3_CACHEABILITY(value)	((value) << 4)
+
+/* Helper defines */
+#define GEN9_NUM_MOCS_ENTRIES	62  /* 62 out of 64 - 63 & 64 are reserved. */
+
+/* (e)LLC caching options */
+#define LE_PAGETABLE		0
+#define LE_UC			1
+#define LE_WT			2
+#define LE_WB			3
+
+/* L3 caching options */
+#define L3_DIRECT		0
+#define L3_UC			1
+#define L3_RESERVED		2
+#define L3_WB			3
+
+/* Target cache */
+#define ELLC			0
+#define LLC			1
+#define LLC_ELLC		2
+
+/*
+ * MOCS tables
+ *
+ * These are the MOCS tables that are programmed across all the rings.
+ * The control value is programmed to all the rings that support the
+ * MOCS registers. While the l3cc_values are only programmed to the
+ * LNCFCMOCS0 - LNCFCMOCS32 registers.
+ *
+ * These tables are intended to be kept reasonably consistent across
+ * platforms. However some of the fields are not applicable to all of
+ * them.
+ *
+ * Entries not part of the following tables are undefined as far as
+ * userspace is concerned and shouldn't be relied upon.  For the time
+ * being they will be implicitly initialized to the strictest caching
+ * configuration (uncached) to guarantee forwards compatibility with
+ * userspace programs written against more recent kernels providing
+ * additional MOCS entries.
+ *
+ * NOTE: These tables MUST start with being uncached and the length
+ *       MUST be less than 63 as the last two registers are reserved
+ *       by the hardware.  These tables are part of the kernel ABI and
+ *       may only be updated incrementally by adding entries at the
+ *       end.
+ */
+static const struct drm_i915_mocs_entry skylake_mocs_table[] = {
+	/* { 0x00000009, 0x0010 } */
+	{ (LE_CACHEABILITY(LE_UC) | LE_TGT_CACHE(LLC_ELLC) | LE_LRUM(0) |
+	   LE_AOM(0) | LE_RSC(0) | LE_SCC(0) | LE_PFM(0) | LE_SCF(0)),
+	  (L3_ESC(0) | L3_SCC(0) | L3_CACHEABILITY(L3_UC)) },
+	/* { 0x00000038, 0x0030 } */
+	{ (LE_CACHEABILITY(LE_PAGETABLE) | LE_TGT_CACHE(LLC_ELLC) | LE_LRUM(3) |
+	   LE_AOM(0) | LE_RSC(0) | LE_SCC(0) | LE_PFM(0) | LE_SCF(0)),
+	  (L3_ESC(0) | L3_SCC(0) | L3_CACHEABILITY(L3_WB)) },
+	/* { 0x0000003b, 0x0030 } */
+	{ (LE_CACHEABILITY(LE_WB) | LE_TGT_CACHE(LLC_ELLC) | LE_LRUM(3) |
+	   LE_AOM(0) | LE_RSC(0) | LE_SCC(0) | LE_PFM(0) | LE_SCF(0)),
+	  (L3_ESC(0) | L3_SCC(0) | L3_CACHEABILITY(L3_WB)) }
+};
+
+/* NOTE: the LE_TGT_CACHE is not used on Broxton */
+static const struct drm_i915_mocs_entry broxton_mocs_table[] = {
+	/* { 0x00000009, 0x0010 } */
+	{ (LE_CACHEABILITY(LE_UC) | LE_TGT_CACHE(LLC_ELLC) | LE_LRUM(0) |
+	   LE_AOM(0) | LE_RSC(0) | LE_SCC(0) | LE_PFM(0) | LE_SCF(0)),
+	  (L3_ESC(0) | L3_SCC(0) | L3_CACHEABILITY(L3_UC)) },
+	/* { 0x00000038, 0x0030 } */
+	{ (LE_CACHEABILITY(LE_PAGETABLE) | LE_TGT_CACHE(LLC_ELLC) | LE_LRUM(3) |
+	   LE_AOM(0) | LE_RSC(0) | LE_SCC(0) | LE_PFM(0) | LE_SCF(0)),
+	  (L3_ESC(0) | L3_SCC(0) | L3_CACHEABILITY(L3_WB)) },
+	/* { 0x0000003b, 0x0030 } */
+	{ (LE_CACHEABILITY(LE_WB) | LE_TGT_CACHE(LLC_ELLC) | LE_LRUM(3) |
+	   LE_AOM(0) | LE_RSC(0) | LE_SCC(0) | LE_PFM(0) | LE_SCF(0)),
+	  (L3_ESC(0) | L3_SCC(0) | L3_CACHEABILITY(L3_WB)) }
+};
+
+/**
+ * get_mocs_settings()
+ * @dev_priv:	i915 device.
+ * @table:      Output table that will be made to point at appropriate
+ *	      MOCS values for the device.
+ *
+ * This function will return the values of the MOCS table that needs to
+ * be programmed for the platform. It will return the values that need
+ * to be programmed and if they need to be programmed.
+ *
+ * Return: true if there are applicable MOCS settings for the device.
+ */
+static bool get_mocs_settings(struct drm_i915_private *dev_priv,
+			      struct drm_i915_mocs_table *table)
+{
+	bool result = false;
+
+	if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv)) {
+		table->size  = ARRAY_SIZE(skylake_mocs_table);
+		table->table = skylake_mocs_table;
+		result = true;
+	} else if (IS_BROXTON(dev_priv)) {
+		table->size  = ARRAY_SIZE(broxton_mocs_table);
+		table->table = broxton_mocs_table;
+		result = true;
+	} else {
+		WARN_ONCE(INTEL_INFO(dev_priv)->gen >= 9,
+			  "Platform that should have a MOCS table does not.\n");
+	}
+
+	/* WaDisableSkipCaching:skl,bxt,kbl */
+	if (IS_GEN9(dev_priv)) {
+		int i;
+
+		for (i = 0; i < table->size; i++)
+			if (WARN_ON(table->table[i].l3cc_value &
+				    (L3_ESC(1) || L3_SCC(0x7))))
+				return false;
+	}
+
+	return result;
+}
+
+static i915_reg_t mocs_register(enum intel_engine_id ring, int index)
+{
+	switch (ring) {
+	case RCS:
+		return GEN9_GFX_MOCS(index);
+	case VCS:
+		return GEN9_MFX0_MOCS(index);
+	case BCS:
+		return GEN9_BLT_MOCS(index);
+	case VECS:
+		return GEN9_VEBOX_MOCS(index);
+	case VCS2:
+		return GEN9_MFX1_MOCS(index);
+	default:
+		MISSING_CASE(ring);
+		return INVALID_MMIO_REG;
+	}
+}
+
+/**
+ * intel_mocs_init_engine() - emit the mocs control table
+ * @engine:	The engine for whom to emit the registers.
+ *
+ * This function simply emits a MI_LOAD_REGISTER_IMM command for the
+ * given table starting at the given address.
+ *
+ * Return: 0 on success, otherwise the error status.
+ */
+int intel_mocs_init_engine(struct intel_engine_cs *engine)
+{
+	struct drm_i915_private *dev_priv = to_i915(engine->dev);
+	struct drm_i915_mocs_table table;
+	unsigned int index;
+
+	if (!get_mocs_settings(dev_priv, &table))
+		return 0;
+
+	if (WARN_ON(table.size > GEN9_NUM_MOCS_ENTRIES))
+		return -ENODEV;
+
+	for (index = 0; index < table.size; index++)
+		I915_WRITE(mocs_register(engine->id, index),
+			   table.table[index].control_value);
+
+	/*
+	 * Ok, now set the unused entries to uncached. These entries
+	 * are officially undefined and no contract for the contents
+	 * and settings is given for these entries.
+	 *
+	 * Entry 0 in the table is uncached - so we are just writing
+	 * that value to all the used entries.
+	 */
+	for (; index < GEN9_NUM_MOCS_ENTRIES; index++)
+		I915_WRITE(mocs_register(engine->id, index),
+			   table.table[0].control_value);
+
+	return 0;
+}
+
+/**
+ * emit_mocs_control_table() - emit the mocs control table
+ * @req:	Request to set up the MOCS table for.
+ * @table:	The values to program into the control regs.
+ *
+ * This function simply emits a MI_LOAD_REGISTER_IMM command for the
+ * given table starting at the given address.
+ *
+ * Return: 0 on success, otherwise the error status.
+ */
+static int emit_mocs_control_table(struct drm_i915_gem_request *req,
+				   const struct drm_i915_mocs_table *table)
+{
+	struct intel_ringbuffer *ringbuf = req->ringbuf;
+	enum intel_engine_id engine = req->engine->id;
+	unsigned int index;
+	int ret;
+
+	if (WARN_ON(table->size > GEN9_NUM_MOCS_ENTRIES))
+		return -ENODEV;
+
+	ret = intel_ring_begin(req, 2 + 2 * GEN9_NUM_MOCS_ENTRIES);
+	if (ret)
+		return ret;
+
+	intel_logical_ring_emit(ringbuf,
+				MI_LOAD_REGISTER_IMM(GEN9_NUM_MOCS_ENTRIES));
+
+	for (index = 0; index < table->size; index++) {
+		intel_logical_ring_emit_reg(ringbuf,
+					    mocs_register(engine, index));
+		intel_logical_ring_emit(ringbuf,
+					table->table[index].control_value);
+	}
+
+	/*
+	 * Ok, now set the unused entries to uncached. These entries
+	 * are officially undefined and no contract for the contents
+	 * and settings is given for these entries.
+	 *
+	 * Entry 0 in the table is uncached - so we are just writing
+	 * that value to all the used entries.
+	 */
+	for (; index < GEN9_NUM_MOCS_ENTRIES; index++) {
+		intel_logical_ring_emit_reg(ringbuf,
+					    mocs_register(engine, index));
+		intel_logical_ring_emit(ringbuf,
+					table->table[0].control_value);
+	}
+
+	intel_logical_ring_emit(ringbuf, MI_NOOP);
+	intel_logical_ring_advance(ringbuf);
+
+	return 0;
+}
+
+static inline u32 l3cc_combine(const struct drm_i915_mocs_table *table,
+			       u16 low,
+			       u16 high)
+{
+	return table->table[low].l3cc_value |
+	       table->table[high].l3cc_value << 16;
+}
+
+/**
+ * emit_mocs_l3cc_table() - emit the mocs control table
+ * @req:	Request to set up the MOCS table for.
+ * @table:	The values to program into the control regs.
+ *
+ * This function simply emits a MI_LOAD_REGISTER_IMM command for the
+ * given table starting at the given address. This register set is
+ * programmed in pairs.
+ *
+ * Return: 0 on success, otherwise the error status.
+ */
+static int emit_mocs_l3cc_table(struct drm_i915_gem_request *req,
+				const struct drm_i915_mocs_table *table)
+{
+	struct intel_ringbuffer *ringbuf = req->ringbuf;
+	unsigned int i;
+	int ret;
+
+	if (WARN_ON(table->size > GEN9_NUM_MOCS_ENTRIES))
+		return -ENODEV;
+
+	ret = intel_ring_begin(req, 2 + GEN9_NUM_MOCS_ENTRIES);
+	if (ret)
+		return ret;
+
+	intel_logical_ring_emit(ringbuf,
+			MI_LOAD_REGISTER_IMM(GEN9_NUM_MOCS_ENTRIES / 2));
+
+	for (i = 0; i < table->size/2; i++) {
+		intel_logical_ring_emit_reg(ringbuf, GEN9_LNCFCMOCS(i));
+		intel_logical_ring_emit(ringbuf,
+					l3cc_combine(table, 2*i, 2*i+1));
+	}
+
+	if (table->size & 0x01) {
+		/* Odd table size - 1 left over */
+		intel_logical_ring_emit_reg(ringbuf, GEN9_LNCFCMOCS(i));
+		intel_logical_ring_emit(ringbuf, l3cc_combine(table, 2*i, 0));
+		i++;
+	}
+
+	/*
+	 * Now set the rest of the table to uncached - use entry 0 as
+	 * this will be uncached. Leave the last pair uninitialised as
+	 * they are reserved by the hardware.
+	 */
+	for (; i < GEN9_NUM_MOCS_ENTRIES / 2; i++) {
+		intel_logical_ring_emit_reg(ringbuf, GEN9_LNCFCMOCS(i));
+		intel_logical_ring_emit(ringbuf, l3cc_combine(table, 0, 0));
+	}
+
+	intel_logical_ring_emit(ringbuf, MI_NOOP);
+	intel_logical_ring_advance(ringbuf);
+
+	return 0;
+}
+
+/**
+ * intel_mocs_init_l3cc_table() - program the mocs control table
+ * @dev:      The the device to be programmed.
+ *
+ * This function simply programs the mocs registers for the given table
+ * starting at the given address. This register set is  programmed in pairs.
+ *
+ * These registers may get programmed more than once, it is simpler to
+ * re-program 32 registers than maintain the state of when they were programmed.
+ * We are always reprogramming with the same values and this only on context
+ * start.
+ *
+ * Return: Nothing.
+ */
+void intel_mocs_init_l3cc_table(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = to_i915(dev);
+	struct drm_i915_mocs_table table;
+	unsigned int i;
+
+	if (!get_mocs_settings(dev_priv, &table))
+		return;
+
+	for (i = 0; i < table.size/2; i++)
+		I915_WRITE(GEN9_LNCFCMOCS(i), l3cc_combine(&table, 2*i, 2*i+1));
+
+	/* Odd table size - 1 left over */
+	if (table.size & 0x01) {
+		I915_WRITE(GEN9_LNCFCMOCS(i), l3cc_combine(&table, 2*i, 0));
+		i++;
+	}
+
+	/*
+	 * Now set the rest of the table to uncached - use entry 0 as
+	 * this will be uncached. Leave the last pair as initialised as
+	 * they are reserved by the hardware.
+	 */
+	for (; i < (GEN9_NUM_MOCS_ENTRIES / 2); i++)
+		I915_WRITE(GEN9_LNCFCMOCS(i), l3cc_combine(&table, 0, 0));
+}
+
+/**
+ * intel_rcs_context_init_mocs() - program the MOCS register.
+ * @req:	Request to set up the MOCS tables for.
+ *
+ * This function will emit a batch buffer with the values required for
+ * programming the MOCS register values for all the currently supported
+ * rings.
+ *
+ * These registers are partially stored in the RCS context, so they are
+ * emitted at the same time so that when a context is created these registers
+ * are set up. These registers have to be emitted into the start of the
+ * context as setting the ELSP will re-init some of these registers back
+ * to the hw values.
+ *
+ * Return: 0 on success, otherwise the error status.
+ */
+int intel_rcs_context_init_mocs(struct drm_i915_gem_request *req)
+{
+	struct drm_i915_mocs_table t;
+	int ret;
+
+	if (get_mocs_settings(req->i915, &t)) {
+		/* Program the RCS control registers */
+		ret = emit_mocs_control_table(req, &t);
+		if (ret)
+			return ret;
+
+		/* Now program the l3cc registers */
+		ret = emit_mocs_l3cc_table(req, &t);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/i915/intel_mocs.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2015 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef INTEL_MOCS_H
+#define INTEL_MOCS_H
+
+/**
+ * DOC: Memory Objects Control State (MOCS)
+ *
+ * Motivation:
+ * In previous Gens the MOCS settings was a value that was set by user land as
+ * part of the batch. In Gen9 this has changed to be a single table (per ring)
+ * that all batches now reference by index instead of programming the MOCS
+ * directly.
+ *
+ * The one wrinkle in this is that only PART of the MOCS tables are included
+ * in context (The GFX_MOCS_0 - GFX_MOCS_64 and the LNCFCMOCS0 - LNCFCMOCS32
+ * registers). The rest are not (the settings for the other rings).
+ *
+ * This table needs to be set at system start-up because the way the table
+ * interacts with the contexts and the GmmLib interface.
+ *
+ *
+ * Implementation:
+ *
+ * The tables (one per supported platform) are defined in intel_mocs.c
+ * and are programmed in the first batch after the context is loaded
+ * (with the hardware workarounds). This will then let the usual
+ * context handling keep the MOCS in step.
+ */
+
+#include <drm/drmP.h>
+#include "i915_drv.h"
+
+int intel_rcs_context_init_mocs(struct drm_i915_gem_request *req);
+void intel_mocs_init_l3cc_table(struct drm_device *dev);
+int intel_mocs_init_engine(struct intel_engine_cs *ring);
+
+#endif
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/i915/intel_modes.c
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) 2007 Dave Airlie <airlied@linux.ie>
+ * Copyright (c) 2007, 2010 Intel Corporation
+ *   Jesse Barnes <jesse.barnes@intel.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#include <linux/slab.h>
+#include <linux/i2c.h>
+#include <linux/fb.h>
+#include <drm/drm_edid.h>
+#include <drm/drmP.h>
+#include "intel_drv.h"
+#include "i915_drv.h"
+
+/**
+ * intel_connector_update_modes - update connector from edid
+ * @connector: DRM connector device to use
+ * @edid: previously read EDID information
+ */
+int intel_connector_update_modes(struct drm_connector *connector,
+				struct edid *edid)
+{
+	int ret;
+
+	drm_mode_connector_update_edid_property(connector, edid);
+	ret = drm_add_edid_modes(connector, edid);
+	drm_edid_to_eld(connector, edid);
+
+	return ret;
+}
+
+/**
+ * intel_ddc_get_modes - get modelist from monitor
+ * @connector: DRM connector device to use
+ * @adapter: i2c adapter
+ *
+ * Fetch the EDID information from @connector using the DDC bus.
+ */
+int intel_ddc_get_modes(struct drm_connector *connector,
+			struct i2c_adapter *adapter)
+{
+	struct edid *edid;
+	int ret;
+
+	edid = drm_get_edid(connector, adapter);
+	if (!edid)
+		return 0;
+
+	ret = intel_connector_update_modes(connector, edid);
+	kfree(edid);
+
+	return ret;
+}
+
+static const struct drm_prop_enum_list force_audio_names[] = {
+	{ HDMI_AUDIO_OFF_DVI, "force-dvi" },
+	{ HDMI_AUDIO_OFF, "off" },
+	{ HDMI_AUDIO_AUTO, "auto" },
+	{ HDMI_AUDIO_ON, "on" },
+};
+
+void
+intel_attach_force_audio_property(struct drm_connector *connector)
+{
+	struct drm_device *dev = connector->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct drm_property *prop;
+
+	prop = dev_priv->force_audio_property;
+	if (prop == NULL) {
+		prop = drm_property_create_enum(dev, 0,
+					   "audio",
+					   force_audio_names,
+					   ARRAY_SIZE(force_audio_names));
+		if (prop == NULL)
+			return;
+
+		dev_priv->force_audio_property = prop;
+	}
+	drm_object_attach_property(&connector->base, prop, 0);
+}
+
+static const struct drm_prop_enum_list broadcast_rgb_names[] = {
+	{ INTEL_BROADCAST_RGB_AUTO, "Automatic" },
+	{ INTEL_BROADCAST_RGB_FULL, "Full" },
+	{ INTEL_BROADCAST_RGB_LIMITED, "Limited 16:235" },
+};
+
+void
+intel_attach_broadcast_rgb_property(struct drm_connector *connector)
+{
+	struct drm_device *dev = connector->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct drm_property *prop;
+
+	prop = dev_priv->broadcast_rgb_property;
+	if (prop == NULL) {
+		prop = drm_property_create_enum(dev, DRM_MODE_PROP_ENUM,
+					   "Broadcast RGB",
+					   broadcast_rgb_names,
+					   ARRAY_SIZE(broadcast_rgb_names));
+		if (prop == NULL)
+			return;
+
+		dev_priv->broadcast_rgb_property = prop;
+	}
+
+	drm_object_attach_property(&connector->base, prop, 0);
+}
+
+void
+intel_attach_aspect_ratio_property(struct drm_connector *connector)
+{
+	if (!drm_mode_create_aspect_ratio_property(connector->dev))
+		drm_object_attach_property(&connector->base,
+			connector->dev->mode_config.aspect_ratio_property,
+			DRM_MODE_PICTURE_ASPECT_NONE);
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/i915/intel_opregion.c
@@ -0,0 +1,1053 @@
+/*
+ * Copyright 2008 Intel Corporation <hong.liu@intel.com>
+ * Copyright 2008 Red Hat <mjg@redhat.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial
+ * portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NON-INFRINGEMENT.  IN NO EVENT SHALL INTEL AND/OR ITS SUPPLIERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ */
+
+#include <linux/acpi.h>
+#include <linux/dmi.h>
+#include <acpi/video.h>
+
+#include <drm/drmP.h>
+#include <drm/i915_drm.h>
+#include "i915_drv.h"
+#include "intel_drv.h"
+
+#define OPREGION_HEADER_OFFSET 0
+#define OPREGION_ACPI_OFFSET   0x100
+#define   ACPI_CLID 0x01ac /* current lid state indicator */
+#define   ACPI_CDCK 0x01b0 /* current docking state indicator */
+#define OPREGION_SWSCI_OFFSET  0x200
+#define OPREGION_ASLE_OFFSET   0x300
+#define OPREGION_VBT_OFFSET    0x400
+#define OPREGION_ASLE_EXT_OFFSET	0x1C00
+
+#define OPREGION_SIGNATURE "IntelGraphicsMem"
+#define MBOX_ACPI      (1<<0)
+#define MBOX_SWSCI     (1<<1)
+#define MBOX_ASLE      (1<<2)
+#define MBOX_ASLE_EXT  (1<<4)
+
+struct opregion_header {
+	u8 signature[16];
+	u32 size;
+	u32 opregion_ver;
+	u8 bios_ver[32];
+	u8 vbios_ver[16];
+	u8 driver_ver[16];
+	u32 mboxes;
+	u32 driver_model;
+	u32 pcon;
+	u8 dver[32];
+	u8 rsvd[124];
+} __packed;
+
+/* OpRegion mailbox #1: public ACPI methods */
+struct opregion_acpi {
+	u32 drdy;       /* driver readiness */
+	u32 csts;       /* notification status */
+	u32 cevt;       /* current event */
+	u8 rsvd1[20];
+	u32 didl[8];    /* supported display devices ID list */
+	u32 cpdl[8];    /* currently presented display list */
+	u32 cadl[8];    /* currently active display list */
+	u32 nadl[8];    /* next active devices list */
+	u32 aslp;       /* ASL sleep time-out */
+	u32 tidx;       /* toggle table index */
+	u32 chpd;       /* current hotplug enable indicator */
+	u32 clid;       /* current lid state*/
+	u32 cdck;       /* current docking state */
+	u32 sxsw;       /* Sx state resume */
+	u32 evts;       /* ASL supported events */
+	u32 cnot;       /* current OS notification */
+	u32 nrdy;       /* driver status */
+	u32 did2[7];	/* extended supported display devices ID list */
+	u32 cpd2[7];	/* extended attached display devices list */
+	u8 rsvd2[4];
+} __packed;
+
+/* OpRegion mailbox #2: SWSCI */
+struct opregion_swsci {
+	u32 scic;       /* SWSCI command|status|data */
+	u32 parm;       /* command parameters */
+	u32 dslp;       /* driver sleep time-out */
+	u8 rsvd[244];
+} __packed;
+
+/* OpRegion mailbox #3: ASLE */
+struct opregion_asle {
+	u32 ardy;       /* driver readiness */
+	u32 aslc;       /* ASLE interrupt command */
+	u32 tche;       /* technology enabled indicator */
+	u32 alsi;       /* current ALS illuminance reading */
+	u32 bclp;       /* backlight brightness to set */
+	u32 pfit;       /* panel fitting state */
+	u32 cblv;       /* current brightness level */
+	u16 bclm[20];   /* backlight level duty cycle mapping table */
+	u32 cpfm;       /* current panel fitting mode */
+	u32 epfm;       /* enabled panel fitting modes */
+	u8 plut[74];    /* panel LUT and identifier */
+	u32 pfmb;       /* PWM freq and min brightness */
+	u32 cddv;       /* color correction default values */
+	u32 pcft;       /* power conservation features */
+	u32 srot;       /* supported rotation angles */
+	u32 iuer;       /* IUER events */
+	u64 fdss;
+	u32 fdsp;
+	u32 stat;
+	u64 rvda;	/* Physical address of raw vbt data */
+	u32 rvds;	/* Size of raw vbt data */
+	u8 rsvd[58];
+} __packed;
+
+/* OpRegion mailbox #5: ASLE ext */
+struct opregion_asle_ext {
+	u32 phed;	/* Panel Header */
+	u8 bddc[256];	/* Panel EDID */
+	u8 rsvd[764];
+} __packed;
+
+/* Driver readiness indicator */
+#define ASLE_ARDY_READY		(1 << 0)
+#define ASLE_ARDY_NOT_READY	(0 << 0)
+
+/* ASLE Interrupt Command (ASLC) bits */
+#define ASLC_SET_ALS_ILLUM		(1 << 0)
+#define ASLC_SET_BACKLIGHT		(1 << 1)
+#define ASLC_SET_PFIT			(1 << 2)
+#define ASLC_SET_PWM_FREQ		(1 << 3)
+#define ASLC_SUPPORTED_ROTATION_ANGLES	(1 << 4)
+#define ASLC_BUTTON_ARRAY		(1 << 5)
+#define ASLC_CONVERTIBLE_INDICATOR	(1 << 6)
+#define ASLC_DOCKING_INDICATOR		(1 << 7)
+#define ASLC_ISCT_STATE_CHANGE		(1 << 8)
+#define ASLC_REQ_MSK			0x1ff
+/* response bits */
+#define ASLC_ALS_ILLUM_FAILED		(1 << 10)
+#define ASLC_BACKLIGHT_FAILED		(1 << 12)
+#define ASLC_PFIT_FAILED		(1 << 14)
+#define ASLC_PWM_FREQ_FAILED		(1 << 16)
+#define ASLC_ROTATION_ANGLES_FAILED	(1 << 18)
+#define ASLC_BUTTON_ARRAY_FAILED	(1 << 20)
+#define ASLC_CONVERTIBLE_FAILED		(1 << 22)
+#define ASLC_DOCKING_FAILED		(1 << 24)
+#define ASLC_ISCT_STATE_FAILED		(1 << 26)
+
+/* Technology enabled indicator */
+#define ASLE_TCHE_ALS_EN	(1 << 0)
+#define ASLE_TCHE_BLC_EN	(1 << 1)
+#define ASLE_TCHE_PFIT_EN	(1 << 2)
+#define ASLE_TCHE_PFMB_EN	(1 << 3)
+
+/* ASLE backlight brightness to set */
+#define ASLE_BCLP_VALID                (1<<31)
+#define ASLE_BCLP_MSK          (~(1<<31))
+
+/* ASLE panel fitting request */
+#define ASLE_PFIT_VALID         (1<<31)
+#define ASLE_PFIT_CENTER (1<<0)
+#define ASLE_PFIT_STRETCH_TEXT (1<<1)
+#define ASLE_PFIT_STRETCH_GFX (1<<2)
+
+/* PWM frequency and minimum brightness */
+#define ASLE_PFMB_BRIGHTNESS_MASK (0xff)
+#define ASLE_PFMB_BRIGHTNESS_VALID (1<<8)
+#define ASLE_PFMB_PWM_MASK (0x7ffffe00)
+#define ASLE_PFMB_PWM_VALID (1<<31)
+
+#define ASLE_CBLV_VALID         (1<<31)
+
+/* IUER */
+#define ASLE_IUER_DOCKING		(1 << 7)
+#define ASLE_IUER_CONVERTIBLE		(1 << 6)
+#define ASLE_IUER_ROTATION_LOCK_BTN	(1 << 4)
+#define ASLE_IUER_VOLUME_DOWN_BTN	(1 << 3)
+#define ASLE_IUER_VOLUME_UP_BTN		(1 << 2)
+#define ASLE_IUER_WINDOWS_BTN		(1 << 1)
+#define ASLE_IUER_POWER_BTN		(1 << 0)
+
+/* Software System Control Interrupt (SWSCI) */
+#define SWSCI_SCIC_INDICATOR		(1 << 0)
+#define SWSCI_SCIC_MAIN_FUNCTION_SHIFT	1
+#define SWSCI_SCIC_MAIN_FUNCTION_MASK	(0xf << 1)
+#define SWSCI_SCIC_SUB_FUNCTION_SHIFT	8
+#define SWSCI_SCIC_SUB_FUNCTION_MASK	(0xff << 8)
+#define SWSCI_SCIC_EXIT_PARAMETER_SHIFT	8
+#define SWSCI_SCIC_EXIT_PARAMETER_MASK	(0xff << 8)
+#define SWSCI_SCIC_EXIT_STATUS_SHIFT	5
+#define SWSCI_SCIC_EXIT_STATUS_MASK	(7 << 5)
+#define SWSCI_SCIC_EXIT_STATUS_SUCCESS	1
+
+#define SWSCI_FUNCTION_CODE(main, sub) \
+	((main) << SWSCI_SCIC_MAIN_FUNCTION_SHIFT | \
+	 (sub) << SWSCI_SCIC_SUB_FUNCTION_SHIFT)
+
+/* SWSCI: Get BIOS Data (GBDA) */
+#define SWSCI_GBDA			4
+#define SWSCI_GBDA_SUPPORTED_CALLS	SWSCI_FUNCTION_CODE(SWSCI_GBDA, 0)
+#define SWSCI_GBDA_REQUESTED_CALLBACKS	SWSCI_FUNCTION_CODE(SWSCI_GBDA, 1)
+#define SWSCI_GBDA_BOOT_DISPLAY_PREF	SWSCI_FUNCTION_CODE(SWSCI_GBDA, 4)
+#define SWSCI_GBDA_PANEL_DETAILS	SWSCI_FUNCTION_CODE(SWSCI_GBDA, 5)
+#define SWSCI_GBDA_TV_STANDARD		SWSCI_FUNCTION_CODE(SWSCI_GBDA, 6)
+#define SWSCI_GBDA_INTERNAL_GRAPHICS	SWSCI_FUNCTION_CODE(SWSCI_GBDA, 7)
+#define SWSCI_GBDA_SPREAD_SPECTRUM	SWSCI_FUNCTION_CODE(SWSCI_GBDA, 10)
+
+/* SWSCI: System BIOS Callbacks (SBCB) */
+#define SWSCI_SBCB			6
+#define SWSCI_SBCB_SUPPORTED_CALLBACKS	SWSCI_FUNCTION_CODE(SWSCI_SBCB, 0)
+#define SWSCI_SBCB_INIT_COMPLETION	SWSCI_FUNCTION_CODE(SWSCI_SBCB, 1)
+#define SWSCI_SBCB_PRE_HIRES_SET_MODE	SWSCI_FUNCTION_CODE(SWSCI_SBCB, 3)
+#define SWSCI_SBCB_POST_HIRES_SET_MODE	SWSCI_FUNCTION_CODE(SWSCI_SBCB, 4)
+#define SWSCI_SBCB_DISPLAY_SWITCH	SWSCI_FUNCTION_CODE(SWSCI_SBCB, 5)
+#define SWSCI_SBCB_SET_TV_FORMAT	SWSCI_FUNCTION_CODE(SWSCI_SBCB, 6)
+#define SWSCI_SBCB_ADAPTER_POWER_STATE	SWSCI_FUNCTION_CODE(SWSCI_SBCB, 7)
+#define SWSCI_SBCB_DISPLAY_POWER_STATE	SWSCI_FUNCTION_CODE(SWSCI_SBCB, 8)
+#define SWSCI_SBCB_SET_BOOT_DISPLAY	SWSCI_FUNCTION_CODE(SWSCI_SBCB, 9)
+#define SWSCI_SBCB_SET_PANEL_DETAILS	SWSCI_FUNCTION_CODE(SWSCI_SBCB, 10)
+#define SWSCI_SBCB_SET_INTERNAL_GFX	SWSCI_FUNCTION_CODE(SWSCI_SBCB, 11)
+#define SWSCI_SBCB_POST_HIRES_TO_DOS_FS	SWSCI_FUNCTION_CODE(SWSCI_SBCB, 16)
+#define SWSCI_SBCB_SUSPEND_RESUME	SWSCI_FUNCTION_CODE(SWSCI_SBCB, 17)
+#define SWSCI_SBCB_SET_SPREAD_SPECTRUM	SWSCI_FUNCTION_CODE(SWSCI_SBCB, 18)
+#define SWSCI_SBCB_POST_VBE_PM		SWSCI_FUNCTION_CODE(SWSCI_SBCB, 19)
+#define SWSCI_SBCB_ENABLE_DISABLE_AUDIO	SWSCI_FUNCTION_CODE(SWSCI_SBCB, 21)
+
+#define ACPI_OTHER_OUTPUT (0<<8)
+#define ACPI_VGA_OUTPUT (1<<8)
+#define ACPI_TV_OUTPUT (2<<8)
+#define ACPI_DIGITAL_OUTPUT (3<<8)
+#define ACPI_LVDS_OUTPUT (4<<8)
+
+#define MAX_DSLP	1500
+
+static int swsci(struct drm_device *dev, u32 function, u32 parm, u32 *parm_out)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct opregion_swsci *swsci = dev_priv->opregion.swsci;
+	u32 main_function, sub_function, scic;
+	u16 swsci_val;
+	u32 dslp;
+
+	if (!swsci)
+		return -ENODEV;
+
+	main_function = (function & SWSCI_SCIC_MAIN_FUNCTION_MASK) >>
+		SWSCI_SCIC_MAIN_FUNCTION_SHIFT;
+	sub_function = (function & SWSCI_SCIC_SUB_FUNCTION_MASK) >>
+		SWSCI_SCIC_SUB_FUNCTION_SHIFT;
+
+	/* Check if we can call the function. See swsci_setup for details. */
+	if (main_function == SWSCI_SBCB) {
+		if ((dev_priv->opregion.swsci_sbcb_sub_functions &
+		     (1 << sub_function)) == 0)
+			return -EINVAL;
+	} else if (main_function == SWSCI_GBDA) {
+		if ((dev_priv->opregion.swsci_gbda_sub_functions &
+		     (1 << sub_function)) == 0)
+			return -EINVAL;
+	}
+
+	/* Driver sleep timeout in ms. */
+	dslp = swsci->dslp;
+	if (!dslp) {
+		/* The spec says 2ms should be the default, but it's too small
+		 * for some machines. */
+		dslp = 50;
+	} else if (dslp > MAX_DSLP) {
+		/* Hey bios, trust must be earned. */
+		DRM_INFO_ONCE("ACPI BIOS requests an excessive sleep of %u ms, "
+			      "using %u ms instead\n", dslp, MAX_DSLP);
+		dslp = MAX_DSLP;
+	}
+
+	/* The spec tells us to do this, but we are the only user... */
+	scic = swsci->scic;
+	if (scic & SWSCI_SCIC_INDICATOR) {
+		DRM_DEBUG_DRIVER("SWSCI request already in progress\n");
+		return -EBUSY;
+	}
+
+	scic = function | SWSCI_SCIC_INDICATOR;
+
+	swsci->parm = parm;
+	swsci->scic = scic;
+
+	/* Ensure SCI event is selected and event trigger is cleared. */
+	pci_read_config_word(dev->pdev, SWSCI, &swsci_val);
+	if (!(swsci_val & SWSCI_SCISEL) || (swsci_val & SWSCI_GSSCIE)) {
+		swsci_val |= SWSCI_SCISEL;
+		swsci_val &= ~SWSCI_GSSCIE;
+		pci_write_config_word(dev->pdev, SWSCI, swsci_val);
+	}
+
+	/* Use event trigger to tell bios to check the mail. */
+	swsci_val |= SWSCI_GSSCIE;
+	pci_write_config_word(dev->pdev, SWSCI, swsci_val);
+
+	/* Poll for the result. */
+#define C (((scic = swsci->scic) & SWSCI_SCIC_INDICATOR) == 0)
+	if (wait_for(C, dslp)) {
+		DRM_DEBUG_DRIVER("SWSCI request timed out\n");
+		return -ETIMEDOUT;
+	}
+
+	scic = (scic & SWSCI_SCIC_EXIT_STATUS_MASK) >>
+		SWSCI_SCIC_EXIT_STATUS_SHIFT;
+
+	/* Note: scic == 0 is an error! */
+	if (scic != SWSCI_SCIC_EXIT_STATUS_SUCCESS) {
+		DRM_DEBUG_DRIVER("SWSCI request error %u\n", scic);
+		return -EIO;
+	}
+
+	if (parm_out)
+		*parm_out = swsci->parm;
+
+	return 0;
+
+#undef C
+}
+
+#define DISPLAY_TYPE_CRT			0
+#define DISPLAY_TYPE_TV				1
+#define DISPLAY_TYPE_EXTERNAL_FLAT_PANEL	2
+#define DISPLAY_TYPE_INTERNAL_FLAT_PANEL	3
+
+int intel_opregion_notify_encoder(struct intel_encoder *intel_encoder,
+				  bool enable)
+{
+	struct drm_device *dev = intel_encoder->base.dev;
+	u32 parm = 0;
+	u32 type = 0;
+	u32 port;
+
+	/* don't care about old stuff for now */
+	if (!HAS_DDI(dev))
+		return 0;
+
+	if (intel_encoder->type == INTEL_OUTPUT_DSI)
+		port = 0;
+	else
+		port = intel_ddi_get_encoder_port(intel_encoder);
+
+	if (port == PORT_E)  {
+		port = 0;
+	} else {
+		parm |= 1 << port;
+		port++;
+	}
+
+	if (!enable)
+		parm |= 4 << 8;
+
+	switch (intel_encoder->type) {
+	case INTEL_OUTPUT_ANALOG:
+		type = DISPLAY_TYPE_CRT;
+		break;
+	case INTEL_OUTPUT_UNKNOWN:
+	case INTEL_OUTPUT_DISPLAYPORT:
+	case INTEL_OUTPUT_HDMI:
+	case INTEL_OUTPUT_DP_MST:
+		type = DISPLAY_TYPE_EXTERNAL_FLAT_PANEL;
+		break;
+	case INTEL_OUTPUT_EDP:
+	case INTEL_OUTPUT_DSI:
+		type = DISPLAY_TYPE_INTERNAL_FLAT_PANEL;
+		break;
+	default:
+		WARN_ONCE(1, "unsupported intel_encoder type %d\n",
+			  intel_encoder->type);
+		return -EINVAL;
+	}
+
+	parm |= type << (16 + port * 3);
+
+	return swsci(dev, SWSCI_SBCB_DISPLAY_POWER_STATE, parm, NULL);
+}
+
+static const struct {
+	pci_power_t pci_power_state;
+	u32 parm;
+} power_state_map[] = {
+	{ PCI_D0,	0x00 },
+	{ PCI_D1,	0x01 },
+	{ PCI_D2,	0x02 },
+	{ PCI_D3hot,	0x04 },
+	{ PCI_D3cold,	0x04 },
+};
+
+int intel_opregion_notify_adapter(struct drm_device *dev, pci_power_t state)
+{
+	int i;
+
+	if (!HAS_DDI(dev))
+		return 0;
+
+	for (i = 0; i < ARRAY_SIZE(power_state_map); i++) {
+		if (state == power_state_map[i].pci_power_state)
+			return swsci(dev, SWSCI_SBCB_ADAPTER_POWER_STATE,
+				     power_state_map[i].parm, NULL);
+	}
+
+	return -EINVAL;
+}
+
+static u32 asle_set_backlight(struct drm_device *dev, u32 bclp)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_connector *connector;
+	struct opregion_asle *asle = dev_priv->opregion.asle;
+
+	DRM_DEBUG_DRIVER("bclp = 0x%08x\n", bclp);
+
+	if (acpi_video_get_backlight_type() == acpi_backlight_native) {
+		DRM_DEBUG_KMS("opregion backlight request ignored\n");
+		return 0;
+	}
+
+	if (!(bclp & ASLE_BCLP_VALID))
+		return ASLC_BACKLIGHT_FAILED;
+
+	bclp &= ASLE_BCLP_MSK;
+	if (bclp > 255)
+		return ASLC_BACKLIGHT_FAILED;
+
+	drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);
+
+	/*
+	 * Update backlight on all connectors that support backlight (usually
+	 * only one).
+	 */
+	DRM_DEBUG_KMS("updating opregion backlight %d/255\n", bclp);
+	for_each_intel_connector(dev, connector)
+		intel_panel_set_backlight_acpi(connector, bclp, 255);
+	asle->cblv = DIV_ROUND_UP(bclp * 100, 255) | ASLE_CBLV_VALID;
+
+	drm_modeset_unlock(&dev->mode_config.connection_mutex);
+
+
+	return 0;
+}
+
+static u32 asle_set_als_illum(struct drm_device *dev, u32 alsi)
+{
+	/* alsi is the current ALS reading in lux. 0 indicates below sensor
+	   range, 0xffff indicates above sensor range. 1-0xfffe are valid */
+	DRM_DEBUG_DRIVER("Illum is not supported\n");
+	return ASLC_ALS_ILLUM_FAILED;
+}
+
+static u32 asle_set_pwm_freq(struct drm_device *dev, u32 pfmb)
+{
+	DRM_DEBUG_DRIVER("PWM freq is not supported\n");
+	return ASLC_PWM_FREQ_FAILED;
+}
+
+static u32 asle_set_pfit(struct drm_device *dev, u32 pfit)
+{
+	/* Panel fitting is currently controlled by the X code, so this is a
+	   noop until modesetting support works fully */
+	DRM_DEBUG_DRIVER("Pfit is not supported\n");
+	return ASLC_PFIT_FAILED;
+}
+
+static u32 asle_set_supported_rotation_angles(struct drm_device *dev, u32 srot)
+{
+	DRM_DEBUG_DRIVER("SROT is not supported\n");
+	return ASLC_ROTATION_ANGLES_FAILED;
+}
+
+static u32 asle_set_button_array(struct drm_device *dev, u32 iuer)
+{
+	if (!iuer)
+		DRM_DEBUG_DRIVER("Button array event is not supported (nothing)\n");
+	if (iuer & ASLE_IUER_ROTATION_LOCK_BTN)
+		DRM_DEBUG_DRIVER("Button array event is not supported (rotation lock)\n");
+	if (iuer & ASLE_IUER_VOLUME_DOWN_BTN)
+		DRM_DEBUG_DRIVER("Button array event is not supported (volume down)\n");
+	if (iuer & ASLE_IUER_VOLUME_UP_BTN)
+		DRM_DEBUG_DRIVER("Button array event is not supported (volume up)\n");
+	if (iuer & ASLE_IUER_WINDOWS_BTN)
+		DRM_DEBUG_DRIVER("Button array event is not supported (windows)\n");
+	if (iuer & ASLE_IUER_POWER_BTN)
+		DRM_DEBUG_DRIVER("Button array event is not supported (power)\n");
+
+	return ASLC_BUTTON_ARRAY_FAILED;
+}
+
+static u32 asle_set_convertible(struct drm_device *dev, u32 iuer)
+{
+	if (iuer & ASLE_IUER_CONVERTIBLE)
+		DRM_DEBUG_DRIVER("Convertible is not supported (clamshell)\n");
+	else
+		DRM_DEBUG_DRIVER("Convertible is not supported (slate)\n");
+
+	return ASLC_CONVERTIBLE_FAILED;
+}
+
+static u32 asle_set_docking(struct drm_device *dev, u32 iuer)
+{
+	if (iuer & ASLE_IUER_DOCKING)
+		DRM_DEBUG_DRIVER("Docking is not supported (docked)\n");
+	else
+		DRM_DEBUG_DRIVER("Docking is not supported (undocked)\n");
+
+	return ASLC_DOCKING_FAILED;
+}
+
+static u32 asle_isct_state(struct drm_device *dev)
+{
+	DRM_DEBUG_DRIVER("ISCT is not supported\n");
+	return ASLC_ISCT_STATE_FAILED;
+}
+
+static void asle_work(struct work_struct *work)
+{
+	struct intel_opregion *opregion =
+		container_of(work, struct intel_opregion, asle_work);
+	struct drm_i915_private *dev_priv =
+		container_of(opregion, struct drm_i915_private, opregion);
+	struct drm_device *dev = dev_priv->dev;
+	struct opregion_asle *asle = dev_priv->opregion.asle;
+	u32 aslc_stat = 0;
+	u32 aslc_req;
+
+	if (!asle)
+		return;
+
+	aslc_req = asle->aslc;
+
+	if (!(aslc_req & ASLC_REQ_MSK)) {
+		DRM_DEBUG_DRIVER("No request on ASLC interrupt 0x%08x\n",
+				 aslc_req);
+		return;
+	}
+
+	if (aslc_req & ASLC_SET_ALS_ILLUM)
+		aslc_stat |= asle_set_als_illum(dev, asle->alsi);
+
+	if (aslc_req & ASLC_SET_BACKLIGHT)
+		aslc_stat |= asle_set_backlight(dev, asle->bclp);
+
+	if (aslc_req & ASLC_SET_PFIT)
+		aslc_stat |= asle_set_pfit(dev, asle->pfit);
+
+	if (aslc_req & ASLC_SET_PWM_FREQ)
+		aslc_stat |= asle_set_pwm_freq(dev, asle->pfmb);
+
+	if (aslc_req & ASLC_SUPPORTED_ROTATION_ANGLES)
+		aslc_stat |= asle_set_supported_rotation_angles(dev,
+							asle->srot);
+
+	if (aslc_req & ASLC_BUTTON_ARRAY)
+		aslc_stat |= asle_set_button_array(dev, asle->iuer);
+
+	if (aslc_req & ASLC_CONVERTIBLE_INDICATOR)
+		aslc_stat |= asle_set_convertible(dev, asle->iuer);
+
+	if (aslc_req & ASLC_DOCKING_INDICATOR)
+		aslc_stat |= asle_set_docking(dev, asle->iuer);
+
+	if (aslc_req & ASLC_ISCT_STATE_CHANGE)
+		aslc_stat |= asle_isct_state(dev);
+
+	asle->aslc = aslc_stat;
+}
+
+void intel_opregion_asle_intr(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	if (dev_priv->opregion.asle)
+		schedule_work(&dev_priv->opregion.asle_work);
+}
+
+#define ACPI_EV_DISPLAY_SWITCH (1<<0)
+#define ACPI_EV_LID            (1<<1)
+#define ACPI_EV_DOCK           (1<<2)
+
+static struct intel_opregion *system_opregion;
+
+static int intel_opregion_video_event(struct notifier_block *nb,
+				      unsigned long val, void *data)
+{
+	/* The only video events relevant to opregion are 0x80. These indicate
+	   either a docking event, lid switch or display switch request. In
+	   Linux, these are handled by the dock, button and video drivers.
+	*/
+
+	struct acpi_bus_event *event = data;
+	struct opregion_acpi *acpi;
+	int ret = NOTIFY_OK;
+
+	if (strcmp(event->device_class, ACPI_VIDEO_CLASS) != 0)
+		return NOTIFY_DONE;
+
+	if (!system_opregion)
+		return NOTIFY_DONE;
+
+	acpi = system_opregion->acpi;
+
+	if (event->type == 0x80 && ((acpi->cevt & 1) == 0))
+		ret = NOTIFY_BAD;
+
+	acpi->csts = 0;
+
+	return ret;
+}
+
+static struct notifier_block intel_opregion_notifier = {
+	.notifier_call = intel_opregion_video_event,
+};
+
+/*
+ * Initialise the DIDL field in opregion. This passes a list of devices to
+ * the firmware. Values are defined by section B.4.2 of the ACPI specification
+ * (version 3)
+ */
+
+static u32 get_did(struct intel_opregion *opregion, int i)
+{
+	u32 did;
+
+	if (i < ARRAY_SIZE(opregion->acpi->didl)) {
+		did = opregion->acpi->didl[i];
+	} else {
+		i -= ARRAY_SIZE(opregion->acpi->didl);
+
+		if (WARN_ON(i >= ARRAY_SIZE(opregion->acpi->did2)))
+			return 0;
+
+		did = opregion->acpi->did2[i];
+	}
+
+	return did;
+}
+
+static void set_did(struct intel_opregion *opregion, int i, u32 val)
+{
+	if (i < ARRAY_SIZE(opregion->acpi->didl)) {
+		opregion->acpi->didl[i] = val;
+	} else {
+		i -= ARRAY_SIZE(opregion->acpi->didl);
+
+		if (WARN_ON(i >= ARRAY_SIZE(opregion->acpi->did2)))
+			return;
+
+		opregion->acpi->did2[i] = val;
+	}
+}
+
+static void intel_didl_outputs(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_opregion *opregion = &dev_priv->opregion;
+	struct drm_connector *connector;
+	acpi_handle handle;
+	struct acpi_device *acpi_dev, *acpi_cdev, *acpi_video_bus = NULL;
+	unsigned long long device_id;
+	acpi_status status;
+	u32 temp, max_outputs;
+	int i = 0;
+
+	handle = ACPI_HANDLE(&dev->pdev->dev);
+	if (!handle || acpi_bus_get_device(handle, &acpi_dev))
+		return;
+
+	if (acpi_is_video_device(handle))
+		acpi_video_bus = acpi_dev;
+	else {
+		list_for_each_entry(acpi_cdev, &acpi_dev->children, node) {
+			if (acpi_is_video_device(acpi_cdev->handle)) {
+				acpi_video_bus = acpi_cdev;
+				break;
+			}
+		}
+	}
+
+	if (!acpi_video_bus) {
+		DRM_DEBUG_KMS("No ACPI video bus found\n");
+		return;
+	}
+
+	/*
+	 * In theory, did2, the extended didl, gets added at opregion version
+	 * 3.0. In practice, however, we're supposed to set it for earlier
+	 * versions as well, since a BIOS that doesn't understand did2 should
+	 * not look at it anyway. Use a variable so we can tweak this if a need
+	 * arises later.
+	 */
+	max_outputs = ARRAY_SIZE(opregion->acpi->didl) +
+		ARRAY_SIZE(opregion->acpi->did2);
+
+	list_for_each_entry(acpi_cdev, &acpi_video_bus->children, node) {
+		if (i >= max_outputs) {
+			DRM_DEBUG_KMS("More than %u outputs detected via ACPI\n",
+				      max_outputs);
+			return;
+		}
+		status = acpi_evaluate_integer(acpi_cdev->handle, "_ADR",
+					       NULL, &device_id);
+		if (ACPI_SUCCESS(status)) {
+			if (!device_id)
+				goto blind_set;
+			set_did(opregion, i++, (u32)(device_id & 0x0f0f));
+		}
+	}
+
+end:
+	DRM_DEBUG_KMS("%d outputs detected\n", i);
+
+	/* If fewer than max outputs, the list must be null terminated */
+	if (i < max_outputs)
+		set_did(opregion, i, 0);
+	return;
+
+blind_set:
+	i = 0;
+	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
+		int output_type = ACPI_OTHER_OUTPUT;
+		if (i >= max_outputs) {
+			DRM_DEBUG_KMS("More than %u outputs in connector list\n",
+				      max_outputs);
+			return;
+		}
+		switch (connector->connector_type) {
+		case DRM_MODE_CONNECTOR_VGA:
+		case DRM_MODE_CONNECTOR_DVIA:
+			output_type = ACPI_VGA_OUTPUT;
+			break;
+		case DRM_MODE_CONNECTOR_Composite:
+		case DRM_MODE_CONNECTOR_SVIDEO:
+		case DRM_MODE_CONNECTOR_Component:
+		case DRM_MODE_CONNECTOR_9PinDIN:
+			output_type = ACPI_TV_OUTPUT;
+			break;
+		case DRM_MODE_CONNECTOR_DVII:
+		case DRM_MODE_CONNECTOR_DVID:
+		case DRM_MODE_CONNECTOR_DisplayPort:
+		case DRM_MODE_CONNECTOR_HDMIA:
+		case DRM_MODE_CONNECTOR_HDMIB:
+			output_type = ACPI_DIGITAL_OUTPUT;
+			break;
+		case DRM_MODE_CONNECTOR_LVDS:
+			output_type = ACPI_LVDS_OUTPUT;
+			break;
+		}
+		temp = get_did(opregion, i);
+		set_did(opregion, i, temp | (1 << 31) | output_type | i);
+		i++;
+	}
+	goto end;
+}
+
+static void intel_setup_cadls(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_opregion *opregion = &dev_priv->opregion;
+	int i = 0;
+	u32 disp_id;
+
+	/* Initialize the CADL field by duplicating the DIDL values.
+	 * Technically, this is not always correct as display outputs may exist,
+	 * but not active. This initialization is necessary for some Clevo
+	 * laptops that check this field before processing the brightness and
+	 * display switching hotkeys. Just like DIDL, CADL is NULL-terminated if
+	 * there are less than eight devices. */
+	do {
+		disp_id = get_did(opregion, i);
+		opregion->acpi->cadl[i] = disp_id;
+	} while (++i < 8 && disp_id != 0);
+}
+
+void intel_opregion_init(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_opregion *opregion = &dev_priv->opregion;
+
+	if (!opregion->header)
+		return;
+
+	if (opregion->acpi) {
+		intel_didl_outputs(dev);
+		intel_setup_cadls(dev);
+
+		/* Notify BIOS we are ready to handle ACPI video ext notifs.
+		 * Right now, all the events are handled by the ACPI video module.
+		 * We don't actually need to do anything with them. */
+		opregion->acpi->csts = 0;
+		opregion->acpi->drdy = 1;
+
+		system_opregion = opregion;
+		register_acpi_notifier(&intel_opregion_notifier);
+	}
+
+	if (opregion->asle) {
+		opregion->asle->tche = ASLE_TCHE_BLC_EN;
+		opregion->asle->ardy = ASLE_ARDY_READY;
+	}
+}
+
+void intel_opregion_fini(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_opregion *opregion = &dev_priv->opregion;
+
+	if (!opregion->header)
+		return;
+
+	if (opregion->asle)
+		opregion->asle->ardy = ASLE_ARDY_NOT_READY;
+
+	cancel_work_sync(&dev_priv->opregion.asle_work);
+
+	if (opregion->acpi) {
+		opregion->acpi->drdy = 0;
+
+		system_opregion = NULL;
+		unregister_acpi_notifier(&intel_opregion_notifier);
+	}
+
+	/* just clear all opregion memory pointers now */
+	memunmap(opregion->header);
+	if (opregion->rvda) {
+		memunmap(opregion->rvda);
+		opregion->rvda = NULL;
+	}
+	opregion->header = NULL;
+	opregion->acpi = NULL;
+	opregion->swsci = NULL;
+	opregion->asle = NULL;
+	opregion->vbt = NULL;
+	opregion->lid_state = NULL;
+}
+
+static void swsci_setup(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_opregion *opregion = &dev_priv->opregion;
+	bool requested_callbacks = false;
+	u32 tmp;
+
+	/* Sub-function code 0 is okay, let's allow them. */
+	opregion->swsci_gbda_sub_functions = 1;
+	opregion->swsci_sbcb_sub_functions = 1;
+
+	/* We use GBDA to ask for supported GBDA calls. */
+	if (swsci(dev, SWSCI_GBDA_SUPPORTED_CALLS, 0, &tmp) == 0) {
+		/* make the bits match the sub-function codes */
+		tmp <<= 1;
+		opregion->swsci_gbda_sub_functions |= tmp;
+	}
+
+	/*
+	 * We also use GBDA to ask for _requested_ SBCB callbacks. The driver
+	 * must not call interfaces that are not specifically requested by the
+	 * bios.
+	 */
+	if (swsci(dev, SWSCI_GBDA_REQUESTED_CALLBACKS, 0, &tmp) == 0) {
+		/* here, the bits already match sub-function codes */
+		opregion->swsci_sbcb_sub_functions |= tmp;
+		requested_callbacks = true;
+	}
+
+	/*
+	 * But we use SBCB to ask for _supported_ SBCB calls. This does not mean
+	 * the callback is _requested_. But we still can't call interfaces that
+	 * are not requested.
+	 */
+	if (swsci(dev, SWSCI_SBCB_SUPPORTED_CALLBACKS, 0, &tmp) == 0) {
+		/* make the bits match the sub-function codes */
+		u32 low = tmp & 0x7ff;
+		u32 high = tmp & ~0xfff; /* bit 11 is reserved */
+		tmp = (high << 4) | (low << 1) | 1;
+
+		/* best guess what to do with supported wrt requested */
+		if (requested_callbacks) {
+			u32 req = opregion->swsci_sbcb_sub_functions;
+			if ((req & tmp) != req)
+				DRM_DEBUG_DRIVER("SWSCI BIOS requested (%08x) SBCB callbacks that are not supported (%08x)\n", req, tmp);
+			/* XXX: for now, trust the requested callbacks */
+			/* opregion->swsci_sbcb_sub_functions &= tmp; */
+		} else {
+			opregion->swsci_sbcb_sub_functions |= tmp;
+		}
+	}
+
+	DRM_DEBUG_DRIVER("SWSCI GBDA callbacks %08x, SBCB callbacks %08x\n",
+			 opregion->swsci_gbda_sub_functions,
+			 opregion->swsci_sbcb_sub_functions);
+}
+
+static int intel_no_opregion_vbt_callback(const struct dmi_system_id *id)
+{
+	DRM_DEBUG_KMS("Falling back to manually reading VBT from "
+		      "VBIOS ROM for %s\n", id->ident);
+	return 1;
+}
+
+static const struct dmi_system_id intel_no_opregion_vbt[] = {
+	{
+		.callback = intel_no_opregion_vbt_callback,
+		.ident = "ThinkCentre A57",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "97027RG"),
+		},
+	},
+	{ }
+};
+
+int intel_opregion_setup(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_opregion *opregion = &dev_priv->opregion;
+	u32 asls, mboxes;
+	char buf[sizeof(OPREGION_SIGNATURE)];
+	int err = 0;
+	void *base;
+
+	BUILD_BUG_ON(sizeof(struct opregion_header) != 0x100);
+	BUILD_BUG_ON(sizeof(struct opregion_acpi) != 0x100);
+	BUILD_BUG_ON(sizeof(struct opregion_swsci) != 0x100);
+	BUILD_BUG_ON(sizeof(struct opregion_asle) != 0x100);
+	BUILD_BUG_ON(sizeof(struct opregion_asle_ext) != 0x400);
+
+	pci_read_config_dword(dev->pdev, ASLS, &asls);
+	DRM_DEBUG_DRIVER("graphic opregion physical addr: 0x%x\n", asls);
+	if (asls == 0) {
+		DRM_DEBUG_DRIVER("ACPI OpRegion not supported!\n");
+		return -ENOTSUPP;
+	}
+
+	INIT_WORK(&opregion->asle_work, asle_work);
+
+	base = memremap(asls, OPREGION_SIZE, MEMREMAP_WB);
+	if (!base)
+		return -ENOMEM;
+
+	memcpy(buf, base, sizeof(buf));
+
+	if (memcmp(buf, OPREGION_SIGNATURE, 16)) {
+		DRM_DEBUG_DRIVER("opregion signature mismatch\n");
+		err = -EINVAL;
+		goto err_out;
+	}
+	opregion->header = base;
+	opregion->lid_state = base + ACPI_CLID;
+
+	mboxes = opregion->header->mboxes;
+	if (mboxes & MBOX_ACPI) {
+		DRM_DEBUG_DRIVER("Public ACPI methods supported\n");
+		opregion->acpi = base + OPREGION_ACPI_OFFSET;
+	}
+
+	if (mboxes & MBOX_SWSCI) {
+		DRM_DEBUG_DRIVER("SWSCI supported\n");
+		opregion->swsci = base + OPREGION_SWSCI_OFFSET;
+		swsci_setup(dev);
+	}
+
+	if (mboxes & MBOX_ASLE) {
+		DRM_DEBUG_DRIVER("ASLE supported\n");
+		opregion->asle = base + OPREGION_ASLE_OFFSET;
+
+		opregion->asle->ardy = ASLE_ARDY_NOT_READY;
+	}
+
+	if (mboxes & MBOX_ASLE_EXT)
+		DRM_DEBUG_DRIVER("ASLE extension supported\n");
+
+	if (!dmi_check_system(intel_no_opregion_vbt)) {
+		const void *vbt = NULL;
+		u32 vbt_size = 0;
+
+		if (opregion->header->opregion_ver >= 2 && opregion->asle &&
+		    opregion->asle->rvda && opregion->asle->rvds) {
+			opregion->rvda = memremap(opregion->asle->rvda,
+						  opregion->asle->rvds,
+						  MEMREMAP_WB);
+			vbt = opregion->rvda;
+			vbt_size = opregion->asle->rvds;
+		}
+
+		if (intel_bios_is_valid_vbt(vbt, vbt_size)) {
+			DRM_DEBUG_KMS("Found valid VBT in ACPI OpRegion (RVDA)\n");
+			opregion->vbt = vbt;
+			opregion->vbt_size = vbt_size;
+		} else {
+			vbt = base + OPREGION_VBT_OFFSET;
+			vbt_size = OPREGION_ASLE_EXT_OFFSET - OPREGION_VBT_OFFSET;
+			if (intel_bios_is_valid_vbt(vbt, vbt_size)) {
+				DRM_DEBUG_KMS("Found valid VBT in ACPI OpRegion (Mailbox #4)\n");
+				opregion->vbt = vbt;
+				opregion->vbt_size = vbt_size;
+			}
+		}
+	}
+
+	return 0;
+
+err_out:
+	memunmap(base);
+	return err;
+}
+
+int
+intel_opregion_get_panel_type(struct drm_device *dev)
+{
+	u32 panel_details;
+	int ret;
+
+	ret = swsci(dev, SWSCI_GBDA_PANEL_DETAILS, 0x0, &panel_details);
+	if (ret) {
+		DRM_DEBUG_KMS("Failed to get panel details from OpRegion (%d)\n",
+			      ret);
+		return ret;
+	}
+
+	ret = (panel_details >> 8) & 0xff;
+	if (ret > 0x10) {
+		DRM_DEBUG_KMS("Invalid OpRegion panel type 0x%x\n", ret);
+		return -EINVAL;
+	}
+
+	/* fall back to VBT panel type? */
+	if (ret == 0x0) {
+		DRM_DEBUG_KMS("No panel type in OpRegion\n");
+		return -ENODEV;
+	}
+
+	/*
+	 * FIXME On Dell XPS 13 9350 the OpRegion panel type (0) gives us
+	 * low vswing for eDP, whereas the VBT panel type (2) gives us normal
+	 * vswing instead. Low vswing results in some display flickers, so
+	 * let's simply ignore the OpRegion panel type on SKL for now.
+	 */
+	if (IS_SKYLAKE(dev)) {
+		DRM_DEBUG_KMS("Ignoring OpRegion panel type (%d)\n", ret - 1);
+		return -ENODEV;
+	}
+
+	return ret - 1;
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/i915/intel_overlay.c
@@ -0,0 +1,1597 @@
+/*
+ * Copyright © 2009
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Authors:
+ *    Daniel Vetter <daniel@ffwll.ch>
+ *
+ * Derived from Xorg ddx, xf86-video-intel, src/i830_video.c
+ */
+#include <drm/drmP.h>
+#include <drm/i915_drm.h>
+#include "i915_drv.h"
+#include "i915_reg.h"
+#include "intel_drv.h"
+
+/* Limits for overlay size. According to intel doc, the real limits are:
+ * Y width: 4095, UV width (planar): 2047, Y height: 2047,
+ * UV width (planar): * 1023. But the xorg thinks 2048 for height and width. Use
+ * the mininum of both.  */
+#define IMAGE_MAX_WIDTH		2048
+#define IMAGE_MAX_HEIGHT	2046 /* 2 * 1023 */
+/* on 830 and 845 these large limits result in the card hanging */
+#define IMAGE_MAX_WIDTH_LEGACY	1024
+#define IMAGE_MAX_HEIGHT_LEGACY	1088
+
+/* overlay register definitions */
+/* OCMD register */
+#define OCMD_TILED_SURFACE	(0x1<<19)
+#define OCMD_MIRROR_MASK	(0x3<<17)
+#define OCMD_MIRROR_MODE	(0x3<<17)
+#define OCMD_MIRROR_HORIZONTAL	(0x1<<17)
+#define OCMD_MIRROR_VERTICAL	(0x2<<17)
+#define OCMD_MIRROR_BOTH	(0x3<<17)
+#define OCMD_BYTEORDER_MASK	(0x3<<14) /* zero for YUYV or FOURCC YUY2 */
+#define OCMD_UV_SWAP		(0x1<<14) /* YVYU */
+#define OCMD_Y_SWAP		(0x2<<14) /* UYVY or FOURCC UYVY */
+#define OCMD_Y_AND_UV_SWAP	(0x3<<14) /* VYUY */
+#define OCMD_SOURCE_FORMAT_MASK (0xf<<10)
+#define OCMD_RGB_888		(0x1<<10) /* not in i965 Intel docs */
+#define OCMD_RGB_555		(0x2<<10) /* not in i965 Intel docs */
+#define OCMD_RGB_565		(0x3<<10) /* not in i965 Intel docs */
+#define OCMD_YUV_422_PACKED	(0x8<<10)
+#define OCMD_YUV_411_PACKED	(0x9<<10) /* not in i965 Intel docs */
+#define OCMD_YUV_420_PLANAR	(0xc<<10)
+#define OCMD_YUV_422_PLANAR	(0xd<<10)
+#define OCMD_YUV_410_PLANAR	(0xe<<10) /* also 411 */
+#define OCMD_TVSYNCFLIP_PARITY	(0x1<<9)
+#define OCMD_TVSYNCFLIP_ENABLE	(0x1<<7)
+#define OCMD_BUF_TYPE_MASK	(0x1<<5)
+#define OCMD_BUF_TYPE_FRAME	(0x0<<5)
+#define OCMD_BUF_TYPE_FIELD	(0x1<<5)
+#define OCMD_TEST_MODE		(0x1<<4)
+#define OCMD_BUFFER_SELECT	(0x3<<2)
+#define OCMD_BUFFER0		(0x0<<2)
+#define OCMD_BUFFER1		(0x1<<2)
+#define OCMD_FIELD_SELECT	(0x1<<2)
+#define OCMD_FIELD0		(0x0<<1)
+#define OCMD_FIELD1		(0x1<<1)
+#define OCMD_ENABLE		(0x1<<0)
+
+/* OCONFIG register */
+#define OCONF_PIPE_MASK		(0x1<<18)
+#define OCONF_PIPE_A		(0x0<<18)
+#define OCONF_PIPE_B		(0x1<<18)
+#define OCONF_GAMMA2_ENABLE	(0x1<<16)
+#define OCONF_CSC_MODE_BT601	(0x0<<5)
+#define OCONF_CSC_MODE_BT709	(0x1<<5)
+#define OCONF_CSC_BYPASS	(0x1<<4)
+#define OCONF_CC_OUT_8BIT	(0x1<<3)
+#define OCONF_TEST_MODE		(0x1<<2)
+#define OCONF_THREE_LINE_BUFFER	(0x1<<0)
+#define OCONF_TWO_LINE_BUFFER	(0x0<<0)
+
+/* DCLRKM (dst-key) register */
+#define DST_KEY_ENABLE		(0x1<<31)
+#define CLK_RGB24_MASK		0x0
+#define CLK_RGB16_MASK		0x070307
+#define CLK_RGB15_MASK		0x070707
+#define CLK_RGB8I_MASK		0xffffff
+
+#define RGB16_TO_COLORKEY(c) \
+	(((c & 0xF800) << 8) | ((c & 0x07E0) << 5) | ((c & 0x001F) << 3))
+#define RGB15_TO_COLORKEY(c) \
+	(((c & 0x7c00) << 9) | ((c & 0x03E0) << 6) | ((c & 0x001F) << 3))
+
+/* overlay flip addr flag */
+#define OFC_UPDATE		0x1
+
+/* polyphase filter coefficients */
+#define N_HORIZ_Y_TAPS          5
+#define N_VERT_Y_TAPS           3
+#define N_HORIZ_UV_TAPS         3
+#define N_VERT_UV_TAPS          3
+#define N_PHASES                17
+#define MAX_TAPS                5
+
+/* memory bufferd overlay registers */
+struct overlay_registers {
+	u32 OBUF_0Y;
+	u32 OBUF_1Y;
+	u32 OBUF_0U;
+	u32 OBUF_0V;
+	u32 OBUF_1U;
+	u32 OBUF_1V;
+	u32 OSTRIDE;
+	u32 YRGB_VPH;
+	u32 UV_VPH;
+	u32 HORZ_PH;
+	u32 INIT_PHS;
+	u32 DWINPOS;
+	u32 DWINSZ;
+	u32 SWIDTH;
+	u32 SWIDTHSW;
+	u32 SHEIGHT;
+	u32 YRGBSCALE;
+	u32 UVSCALE;
+	u32 OCLRC0;
+	u32 OCLRC1;
+	u32 DCLRKV;
+	u32 DCLRKM;
+	u32 SCLRKVH;
+	u32 SCLRKVL;
+	u32 SCLRKEN;
+	u32 OCONFIG;
+	u32 OCMD;
+	u32 RESERVED1; /* 0x6C */
+	u32 OSTART_0Y;
+	u32 OSTART_1Y;
+	u32 OSTART_0U;
+	u32 OSTART_0V;
+	u32 OSTART_1U;
+	u32 OSTART_1V;
+	u32 OTILEOFF_0Y;
+	u32 OTILEOFF_1Y;
+	u32 OTILEOFF_0U;
+	u32 OTILEOFF_0V;
+	u32 OTILEOFF_1U;
+	u32 OTILEOFF_1V;
+	u32 FASTHSCALE; /* 0xA0 */
+	u32 UVSCALEV; /* 0xA4 */
+	u32 RESERVEDC[(0x200 - 0xA8) / 4]; /* 0xA8 - 0x1FC */
+	u16 Y_VCOEFS[N_VERT_Y_TAPS * N_PHASES]; /* 0x200 */
+	u16 RESERVEDD[0x100 / 2 - N_VERT_Y_TAPS * N_PHASES];
+	u16 Y_HCOEFS[N_HORIZ_Y_TAPS * N_PHASES]; /* 0x300 */
+	u16 RESERVEDE[0x200 / 2 - N_HORIZ_Y_TAPS * N_PHASES];
+	u16 UV_VCOEFS[N_VERT_UV_TAPS * N_PHASES]; /* 0x500 */
+	u16 RESERVEDF[0x100 / 2 - N_VERT_UV_TAPS * N_PHASES];
+	u16 UV_HCOEFS[N_HORIZ_UV_TAPS * N_PHASES]; /* 0x600 */
+	u16 RESERVEDG[0x100 / 2 - N_HORIZ_UV_TAPS * N_PHASES];
+};
+
+struct intel_overlay {
+	struct drm_device *dev;
+	struct intel_crtc *crtc;
+	struct drm_i915_gem_object *vid_bo;
+	struct drm_i915_gem_object *old_vid_bo;
+	bool active;
+	bool pfit_active;
+	u32 pfit_vscale_ratio; /* shifted-point number, (1<<12) == 1.0 */
+	u32 color_key:24;
+	u32 color_key_enabled:1;
+	u32 brightness, contrast, saturation;
+	u32 old_xscale, old_yscale;
+	/* register access */
+	u32 flip_addr;
+	struct drm_i915_gem_object *reg_bo;
+	/* flip handling */
+	struct drm_i915_gem_request *last_flip_req;
+	void (*flip_tail)(struct intel_overlay *);
+};
+
+static struct overlay_registers __iomem *
+intel_overlay_map_regs(struct intel_overlay *overlay)
+{
+	struct drm_i915_private *dev_priv = to_i915(overlay->dev);
+	struct i915_ggtt *ggtt = &dev_priv->ggtt;
+	struct overlay_registers __iomem *regs;
+
+	if (OVERLAY_NEEDS_PHYSICAL(overlay->dev))
+		regs = (struct overlay_registers __iomem *)overlay->reg_bo->phys_handle->vaddr;
+	else
+		regs = io_mapping_map_wc(ggtt->mappable,
+					 i915_gem_obj_ggtt_offset(overlay->reg_bo));
+
+	return regs;
+}
+
+static void intel_overlay_unmap_regs(struct intel_overlay *overlay,
+				     struct overlay_registers __iomem *regs)
+{
+	if (!OVERLAY_NEEDS_PHYSICAL(overlay->dev))
+		io_mapping_unmap(regs);
+}
+
+static int intel_overlay_do_wait_request(struct intel_overlay *overlay,
+					 struct drm_i915_gem_request *req,
+					 void (*tail)(struct intel_overlay *))
+{
+	int ret;
+
+	WARN_ON(overlay->last_flip_req);
+	i915_gem_request_assign(&overlay->last_flip_req, req);
+	i915_add_request(req);
+
+	overlay->flip_tail = tail;
+	ret = i915_wait_request(overlay->last_flip_req);
+	if (ret)
+		return ret;
+
+	i915_gem_request_assign(&overlay->last_flip_req, NULL);
+	return 0;
+}
+
+/* overlay needs to be disable in OCMD reg */
+static int intel_overlay_on(struct intel_overlay *overlay)
+{
+	struct drm_device *dev = overlay->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_engine_cs *engine = &dev_priv->engine[RCS];
+	struct drm_i915_gem_request *req;
+	int ret;
+
+	WARN_ON(overlay->active);
+	WARN_ON(IS_I830(dev) && !(dev_priv->quirks & QUIRK_PIPEA_FORCE));
+
+	req = i915_gem_request_alloc(engine, NULL);
+	if (IS_ERR(req))
+		return PTR_ERR(req);
+
+	ret = intel_ring_begin(req, 4);
+	if (ret) {
+		i915_add_request_no_flush(req);
+		return ret;
+	}
+
+	overlay->active = true;
+
+	intel_ring_emit(engine, MI_OVERLAY_FLIP | MI_OVERLAY_ON);
+	intel_ring_emit(engine, overlay->flip_addr | OFC_UPDATE);
+	intel_ring_emit(engine, MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);
+	intel_ring_emit(engine, MI_NOOP);
+	intel_ring_advance(engine);
+
+	return intel_overlay_do_wait_request(overlay, req, NULL);
+}
+
+/* overlay needs to be enabled in OCMD reg */
+static int intel_overlay_continue(struct intel_overlay *overlay,
+				  bool load_polyphase_filter)
+{
+	struct drm_device *dev = overlay->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_engine_cs *engine = &dev_priv->engine[RCS];
+	struct drm_i915_gem_request *req;
+	u32 flip_addr = overlay->flip_addr;
+	u32 tmp;
+	int ret;
+
+	WARN_ON(!overlay->active);
+
+	if (load_polyphase_filter)
+		flip_addr |= OFC_UPDATE;
+
+	/* check for underruns */
+	tmp = I915_READ(DOVSTA);
+	if (tmp & (1 << 17))
+		DRM_DEBUG("overlay underrun, DOVSTA: %x\n", tmp);
+
+	req = i915_gem_request_alloc(engine, NULL);
+	if (IS_ERR(req))
+		return PTR_ERR(req);
+
+	ret = intel_ring_begin(req, 2);
+	if (ret) {
+		i915_add_request_no_flush(req);
+		return ret;
+	}
+
+	intel_ring_emit(engine, MI_OVERLAY_FLIP | MI_OVERLAY_CONTINUE);
+	intel_ring_emit(engine, flip_addr);
+	intel_ring_advance(engine);
+
+	WARN_ON(overlay->last_flip_req);
+	i915_gem_request_assign(&overlay->last_flip_req, req);
+	i915_add_request(req);
+
+	return 0;
+}
+
+static void intel_overlay_release_old_vid_tail(struct intel_overlay *overlay)
+{
+	struct drm_i915_gem_object *obj = overlay->old_vid_bo;
+
+	i915_gem_object_ggtt_unpin(obj);
+	drm_gem_object_unreference(&obj->base);
+
+	overlay->old_vid_bo = NULL;
+}
+
+static void intel_overlay_off_tail(struct intel_overlay *overlay)
+{
+	struct drm_i915_gem_object *obj = overlay->vid_bo;
+
+	/* never have the overlay hw on without showing a frame */
+	if (WARN_ON(!obj))
+		return;
+
+	i915_gem_object_ggtt_unpin(obj);
+	drm_gem_object_unreference(&obj->base);
+	overlay->vid_bo = NULL;
+
+	overlay->crtc->overlay = NULL;
+	overlay->crtc = NULL;
+	overlay->active = false;
+}
+
+/* overlay needs to be disabled in OCMD reg */
+static int intel_overlay_off(struct intel_overlay *overlay)
+{
+	struct drm_device *dev = overlay->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_engine_cs *engine = &dev_priv->engine[RCS];
+	struct drm_i915_gem_request *req;
+	u32 flip_addr = overlay->flip_addr;
+	int ret;
+
+	WARN_ON(!overlay->active);
+
+	/* According to intel docs the overlay hw may hang (when switching
+	 * off) without loading the filter coeffs. It is however unclear whether
+	 * this applies to the disabling of the overlay or to the switching off
+	 * of the hw. Do it in both cases */
+	flip_addr |= OFC_UPDATE;
+
+	req = i915_gem_request_alloc(engine, NULL);
+	if (IS_ERR(req))
+		return PTR_ERR(req);
+
+	ret = intel_ring_begin(req, 6);
+	if (ret) {
+		i915_add_request_no_flush(req);
+		return ret;
+	}
+
+	/* wait for overlay to go idle */
+	intel_ring_emit(engine, MI_OVERLAY_FLIP | MI_OVERLAY_CONTINUE);
+	intel_ring_emit(engine, flip_addr);
+	intel_ring_emit(engine, MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);
+	/* turn overlay off */
+	if (IS_I830(dev)) {
+		/* Workaround: Don't disable the overlay fully, since otherwise
+		 * it dies on the next OVERLAY_ON cmd. */
+		intel_ring_emit(engine, MI_NOOP);
+		intel_ring_emit(engine, MI_NOOP);
+		intel_ring_emit(engine, MI_NOOP);
+	} else {
+		intel_ring_emit(engine, MI_OVERLAY_FLIP | MI_OVERLAY_OFF);
+		intel_ring_emit(engine, flip_addr);
+		intel_ring_emit(engine,
+				MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);
+	}
+	intel_ring_advance(engine);
+
+	return intel_overlay_do_wait_request(overlay, req, intel_overlay_off_tail);
+}
+
+/* recover from an interruption due to a signal
+ * We have to be careful not to repeat work forever an make forward progess. */
+static int intel_overlay_recover_from_interrupt(struct intel_overlay *overlay)
+{
+	int ret;
+
+	if (overlay->last_flip_req == NULL)
+		return 0;
+
+	ret = i915_wait_request(overlay->last_flip_req);
+	if (ret)
+		return ret;
+
+	if (overlay->flip_tail)
+		overlay->flip_tail(overlay);
+
+	i915_gem_request_assign(&overlay->last_flip_req, NULL);
+	return 0;
+}
+
+/* Wait for pending overlay flip and release old frame.
+ * Needs to be called before the overlay register are changed
+ * via intel_overlay_(un)map_regs
+ */
+static int intel_overlay_release_old_vid(struct intel_overlay *overlay)
+{
+	struct drm_device *dev = overlay->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_engine_cs *engine = &dev_priv->engine[RCS];
+	int ret;
+
+	WARN_ON(!mutex_is_locked(&dev->struct_mutex));
+
+	/* Only wait if there is actually an old frame to release to
+	 * guarantee forward progress.
+	 */
+	if (!overlay->old_vid_bo)
+		return 0;
+
+	if (I915_READ(ISR) & I915_OVERLAY_PLANE_FLIP_PENDING_INTERRUPT) {
+		/* synchronous slowpath */
+		struct drm_i915_gem_request *req;
+
+		req = i915_gem_request_alloc(engine, NULL);
+		if (IS_ERR(req))
+			return PTR_ERR(req);
+
+		ret = intel_ring_begin(req, 2);
+		if (ret) {
+			i915_add_request_no_flush(req);
+			return ret;
+		}
+
+		intel_ring_emit(engine,
+				MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);
+		intel_ring_emit(engine, MI_NOOP);
+		intel_ring_advance(engine);
+
+		ret = intel_overlay_do_wait_request(overlay, req,
+						    intel_overlay_release_old_vid_tail);
+		if (ret)
+			return ret;
+	}
+
+	intel_overlay_release_old_vid_tail(overlay);
+
+
+	i915_gem_track_fb(overlay->old_vid_bo, NULL,
+			  INTEL_FRONTBUFFER_OVERLAY(overlay->crtc->pipe));
+	return 0;
+}
+
+void intel_overlay_reset(struct drm_i915_private *dev_priv)
+{
+	struct intel_overlay *overlay = dev_priv->overlay;
+
+	if (!overlay)
+		return;
+
+	intel_overlay_release_old_vid(overlay);
+
+	overlay->last_flip_req = NULL;
+	overlay->old_xscale = 0;
+	overlay->old_yscale = 0;
+	overlay->crtc = NULL;
+	overlay->active = false;
+}
+
+struct put_image_params {
+	int format;
+	short dst_x;
+	short dst_y;
+	short dst_w;
+	short dst_h;
+	short src_w;
+	short src_scan_h;
+	short src_scan_w;
+	short src_h;
+	short stride_Y;
+	short stride_UV;
+	int offset_Y;
+	int offset_U;
+	int offset_V;
+};
+
+static int packed_depth_bytes(u32 format)
+{
+	switch (format & I915_OVERLAY_DEPTH_MASK) {
+	case I915_OVERLAY_YUV422:
+		return 4;
+	case I915_OVERLAY_YUV411:
+		/* return 6; not implemented */
+	default:
+		return -EINVAL;
+	}
+}
+
+static int packed_width_bytes(u32 format, short width)
+{
+	switch (format & I915_OVERLAY_DEPTH_MASK) {
+	case I915_OVERLAY_YUV422:
+		return width << 1;
+	default:
+		return -EINVAL;
+	}
+}
+
+static int uv_hsubsampling(u32 format)
+{
+	switch (format & I915_OVERLAY_DEPTH_MASK) {
+	case I915_OVERLAY_YUV422:
+	case I915_OVERLAY_YUV420:
+		return 2;
+	case I915_OVERLAY_YUV411:
+	case I915_OVERLAY_YUV410:
+		return 4;
+	default:
+		return -EINVAL;
+	}
+}
+
+static int uv_vsubsampling(u32 format)
+{
+	switch (format & I915_OVERLAY_DEPTH_MASK) {
+	case I915_OVERLAY_YUV420:
+	case I915_OVERLAY_YUV410:
+		return 2;
+	case I915_OVERLAY_YUV422:
+	case I915_OVERLAY_YUV411:
+		return 1;
+	default:
+		return -EINVAL;
+	}
+}
+
+static u32 calc_swidthsw(struct drm_device *dev, u32 offset, u32 width)
+{
+	u32 mask, shift, ret;
+	if (IS_GEN2(dev)) {
+		mask = 0x1f;
+		shift = 5;
+	} else {
+		mask = 0x3f;
+		shift = 6;
+	}
+	ret = ((offset + width + mask) >> shift) - (offset >> shift);
+	if (!IS_GEN2(dev))
+		ret <<= 1;
+	ret -= 1;
+	return ret << 2;
+}
+
+static const u16 y_static_hcoeffs[N_HORIZ_Y_TAPS * N_PHASES] = {
+	0x3000, 0xb4a0, 0x1930, 0x1920, 0xb4a0,
+	0x3000, 0xb500, 0x19d0, 0x1880, 0xb440,
+	0x3000, 0xb540, 0x1a88, 0x2f80, 0xb3e0,
+	0x3000, 0xb580, 0x1b30, 0x2e20, 0xb380,
+	0x3000, 0xb5c0, 0x1bd8, 0x2cc0, 0xb320,
+	0x3020, 0xb5e0, 0x1c60, 0x2b80, 0xb2c0,
+	0x3020, 0xb5e0, 0x1cf8, 0x2a20, 0xb260,
+	0x3020, 0xb5e0, 0x1d80, 0x28e0, 0xb200,
+	0x3020, 0xb5c0, 0x1e08, 0x3f40, 0xb1c0,
+	0x3020, 0xb580, 0x1e78, 0x3ce0, 0xb160,
+	0x3040, 0xb520, 0x1ed8, 0x3aa0, 0xb120,
+	0x3040, 0xb4a0, 0x1f30, 0x3880, 0xb0e0,
+	0x3040, 0xb400, 0x1f78, 0x3680, 0xb0a0,
+	0x3020, 0xb340, 0x1fb8, 0x34a0, 0xb060,
+	0x3020, 0xb240, 0x1fe0, 0x32e0, 0xb040,
+	0x3020, 0xb140, 0x1ff8, 0x3160, 0xb020,
+	0xb000, 0x3000, 0x0800, 0x3000, 0xb000
+};
+
+static const u16 uv_static_hcoeffs[N_HORIZ_UV_TAPS * N_PHASES] = {
+	0x3000, 0x1800, 0x1800, 0xb000, 0x18d0, 0x2e60,
+	0xb000, 0x1990, 0x2ce0, 0xb020, 0x1a68, 0x2b40,
+	0xb040, 0x1b20, 0x29e0, 0xb060, 0x1bd8, 0x2880,
+	0xb080, 0x1c88, 0x3e60, 0xb0a0, 0x1d28, 0x3c00,
+	0xb0c0, 0x1db8, 0x39e0, 0xb0e0, 0x1e40, 0x37e0,
+	0xb100, 0x1eb8, 0x3620, 0xb100, 0x1f18, 0x34a0,
+	0xb100, 0x1f68, 0x3360, 0xb0e0, 0x1fa8, 0x3240,
+	0xb0c0, 0x1fe0, 0x3140, 0xb060, 0x1ff0, 0x30a0,
+	0x3000, 0x0800, 0x3000
+};
+
+static void update_polyphase_filter(struct overlay_registers __iomem *regs)
+{
+	memcpy_toio(regs->Y_HCOEFS, y_static_hcoeffs, sizeof(y_static_hcoeffs));
+	memcpy_toio(regs->UV_HCOEFS, uv_static_hcoeffs,
+		    sizeof(uv_static_hcoeffs));
+}
+
+static bool update_scaling_factors(struct intel_overlay *overlay,
+				   struct overlay_registers __iomem *regs,
+				   struct put_image_params *params)
+{
+	/* fixed point with a 12 bit shift */
+	u32 xscale, yscale, xscale_UV, yscale_UV;
+#define FP_SHIFT 12
+#define FRACT_MASK 0xfff
+	bool scale_changed = false;
+	int uv_hscale = uv_hsubsampling(params->format);
+	int uv_vscale = uv_vsubsampling(params->format);
+
+	if (params->dst_w > 1)
+		xscale = ((params->src_scan_w - 1) << FP_SHIFT)
+			/(params->dst_w);
+	else
+		xscale = 1 << FP_SHIFT;
+
+	if (params->dst_h > 1)
+		yscale = ((params->src_scan_h - 1) << FP_SHIFT)
+			/(params->dst_h);
+	else
+		yscale = 1 << FP_SHIFT;
+
+	/*if (params->format & I915_OVERLAY_YUV_PLANAR) {*/
+	xscale_UV = xscale/uv_hscale;
+	yscale_UV = yscale/uv_vscale;
+	/* make the Y scale to UV scale ratio an exact multiply */
+	xscale = xscale_UV * uv_hscale;
+	yscale = yscale_UV * uv_vscale;
+	/*} else {
+	  xscale_UV = 0;
+	  yscale_UV = 0;
+	  }*/
+
+	if (xscale != overlay->old_xscale || yscale != overlay->old_yscale)
+		scale_changed = true;
+	overlay->old_xscale = xscale;
+	overlay->old_yscale = yscale;
+
+	iowrite32(((yscale & FRACT_MASK) << 20) |
+		  ((xscale >> FP_SHIFT)  << 16) |
+		  ((xscale & FRACT_MASK) << 3),
+		 &regs->YRGBSCALE);
+
+	iowrite32(((yscale_UV & FRACT_MASK) << 20) |
+		  ((xscale_UV >> FP_SHIFT)  << 16) |
+		  ((xscale_UV & FRACT_MASK) << 3),
+		 &regs->UVSCALE);
+
+	iowrite32((((yscale    >> FP_SHIFT) << 16) |
+		   ((yscale_UV >> FP_SHIFT) << 0)),
+		 &regs->UVSCALEV);
+
+	if (scale_changed)
+		update_polyphase_filter(regs);
+
+	return scale_changed;
+}
+
+static void update_colorkey(struct intel_overlay *overlay,
+			    struct overlay_registers __iomem *regs)
+{
+	u32 key = overlay->color_key;
+	u32 flags;
+
+	flags = 0;
+	if (overlay->color_key_enabled)
+		flags |= DST_KEY_ENABLE;
+
+	switch (overlay->crtc->base.primary->fb->bits_per_pixel) {
+	case 8:
+		key = 0;
+		flags |= CLK_RGB8I_MASK;
+		break;
+
+	case 16:
+		if (overlay->crtc->base.primary->fb->depth == 15) {
+			key = RGB15_TO_COLORKEY(key);
+			flags |= CLK_RGB15_MASK;
+		} else {
+			key = RGB16_TO_COLORKEY(key);
+			flags |= CLK_RGB16_MASK;
+		}
+		break;
+
+	case 24:
+	case 32:
+		flags |= CLK_RGB24_MASK;
+		break;
+	}
+
+	iowrite32(key, &regs->DCLRKV);
+	iowrite32(flags, &regs->DCLRKM);
+}
+
+static u32 overlay_cmd_reg(struct put_image_params *params)
+{
+	u32 cmd = OCMD_ENABLE | OCMD_BUF_TYPE_FRAME | OCMD_BUFFER0;
+
+	if (params->format & I915_OVERLAY_YUV_PLANAR) {
+		switch (params->format & I915_OVERLAY_DEPTH_MASK) {
+		case I915_OVERLAY_YUV422:
+			cmd |= OCMD_YUV_422_PLANAR;
+			break;
+		case I915_OVERLAY_YUV420:
+			cmd |= OCMD_YUV_420_PLANAR;
+			break;
+		case I915_OVERLAY_YUV411:
+		case I915_OVERLAY_YUV410:
+			cmd |= OCMD_YUV_410_PLANAR;
+			break;
+		}
+	} else { /* YUV packed */
+		switch (params->format & I915_OVERLAY_DEPTH_MASK) {
+		case I915_OVERLAY_YUV422:
+			cmd |= OCMD_YUV_422_PACKED;
+			break;
+		case I915_OVERLAY_YUV411:
+			cmd |= OCMD_YUV_411_PACKED;
+			break;
+		}
+
+		switch (params->format & I915_OVERLAY_SWAP_MASK) {
+		case I915_OVERLAY_NO_SWAP:
+			break;
+		case I915_OVERLAY_UV_SWAP:
+			cmd |= OCMD_UV_SWAP;
+			break;
+		case I915_OVERLAY_Y_SWAP:
+			cmd |= OCMD_Y_SWAP;
+			break;
+		case I915_OVERLAY_Y_AND_UV_SWAP:
+			cmd |= OCMD_Y_AND_UV_SWAP;
+			break;
+		}
+	}
+
+	return cmd;
+}
+
+static int intel_overlay_do_put_image(struct intel_overlay *overlay,
+				      struct drm_i915_gem_object *new_bo,
+				      struct put_image_params *params)
+{
+	int ret, tmp_width;
+	struct overlay_registers __iomem *regs;
+	bool scale_changed = false;
+	struct drm_device *dev = overlay->dev;
+	u32 swidth, swidthsw, sheight, ostride;
+	enum pipe pipe = overlay->crtc->pipe;
+
+	WARN_ON(!mutex_is_locked(&dev->struct_mutex));
+	WARN_ON(!drm_modeset_is_locked(&dev->mode_config.connection_mutex));
+
+	ret = intel_overlay_release_old_vid(overlay);
+	if (ret != 0)
+		return ret;
+
+	ret = i915_gem_object_pin_to_display_plane(new_bo, 0,
+						   &i915_ggtt_view_normal);
+	if (ret != 0)
+		return ret;
+
+	ret = i915_gem_object_put_fence(new_bo);
+	if (ret)
+		goto out_unpin;
+
+	if (!overlay->active) {
+		u32 oconfig;
+		regs = intel_overlay_map_regs(overlay);
+		if (!regs) {
+			ret = -ENOMEM;
+			goto out_unpin;
+		}
+		oconfig = OCONF_CC_OUT_8BIT;
+		if (IS_GEN4(overlay->dev))
+			oconfig |= OCONF_CSC_MODE_BT709;
+		oconfig |= pipe == 0 ?
+			OCONF_PIPE_A : OCONF_PIPE_B;
+		iowrite32(oconfig, &regs->OCONFIG);
+		intel_overlay_unmap_regs(overlay, regs);
+
+		ret = intel_overlay_on(overlay);
+		if (ret != 0)
+			goto out_unpin;
+	}
+
+	regs = intel_overlay_map_regs(overlay);
+	if (!regs) {
+		ret = -ENOMEM;
+		goto out_unpin;
+	}
+
+	iowrite32((params->dst_y << 16) | params->dst_x, &regs->DWINPOS);
+	iowrite32((params->dst_h << 16) | params->dst_w, &regs->DWINSZ);
+
+	if (params->format & I915_OVERLAY_YUV_PACKED)
+		tmp_width = packed_width_bytes(params->format, params->src_w);
+	else
+		tmp_width = params->src_w;
+
+	swidth = params->src_w;
+	swidthsw = calc_swidthsw(overlay->dev, params->offset_Y, tmp_width);
+	sheight = params->src_h;
+	iowrite32(i915_gem_obj_ggtt_offset(new_bo) + params->offset_Y, &regs->OBUF_0Y);
+	ostride = params->stride_Y;
+
+	if (params->format & I915_OVERLAY_YUV_PLANAR) {
+		int uv_hscale = uv_hsubsampling(params->format);
+		int uv_vscale = uv_vsubsampling(params->format);
+		u32 tmp_U, tmp_V;
+		swidth |= (params->src_w/uv_hscale) << 16;
+		tmp_U = calc_swidthsw(overlay->dev, params->offset_U,
+				      params->src_w/uv_hscale);
+		tmp_V = calc_swidthsw(overlay->dev, params->offset_V,
+				      params->src_w/uv_hscale);
+		swidthsw |= max_t(u32, tmp_U, tmp_V) << 16;
+		sheight |= (params->src_h/uv_vscale) << 16;
+		iowrite32(i915_gem_obj_ggtt_offset(new_bo) + params->offset_U, &regs->OBUF_0U);
+		iowrite32(i915_gem_obj_ggtt_offset(new_bo) + params->offset_V, &regs->OBUF_0V);
+		ostride |= params->stride_UV << 16;
+	}
+
+	iowrite32(swidth, &regs->SWIDTH);
+	iowrite32(swidthsw, &regs->SWIDTHSW);
+	iowrite32(sheight, &regs->SHEIGHT);
+	iowrite32(ostride, &regs->OSTRIDE);
+
+	scale_changed = update_scaling_factors(overlay, regs, params);
+
+	update_colorkey(overlay, regs);
+
+	iowrite32(overlay_cmd_reg(params), &regs->OCMD);
+
+	intel_overlay_unmap_regs(overlay, regs);
+
+	ret = intel_overlay_continue(overlay, scale_changed);
+	if (ret)
+		goto out_unpin;
+
+	i915_gem_track_fb(overlay->vid_bo, new_bo,
+			  INTEL_FRONTBUFFER_OVERLAY(pipe));
+
+	overlay->old_vid_bo = overlay->vid_bo;
+	overlay->vid_bo = new_bo;
+
+	intel_frontbuffer_flip(dev,
+			       INTEL_FRONTBUFFER_OVERLAY(pipe));
+
+	return 0;
+
+out_unpin:
+	i915_gem_object_ggtt_unpin(new_bo);
+	return ret;
+}
+
+int intel_overlay_switch_off(struct intel_overlay *overlay)
+{
+	struct overlay_registers __iomem *regs;
+	struct drm_device *dev = overlay->dev;
+	int ret;
+
+	WARN_ON(!mutex_is_locked(&dev->struct_mutex));
+	WARN_ON(!drm_modeset_is_locked(&dev->mode_config.connection_mutex));
+
+	ret = intel_overlay_recover_from_interrupt(overlay);
+	if (ret != 0)
+		return ret;
+
+	if (!overlay->active)
+		return 0;
+
+	ret = intel_overlay_release_old_vid(overlay);
+	if (ret != 0)
+		return ret;
+
+	regs = intel_overlay_map_regs(overlay);
+	iowrite32(0, &regs->OCMD);
+	intel_overlay_unmap_regs(overlay, regs);
+
+	ret = intel_overlay_off(overlay);
+	if (ret != 0)
+		return ret;
+
+	intel_overlay_off_tail(overlay);
+	return 0;
+}
+
+static int check_overlay_possible_on_crtc(struct intel_overlay *overlay,
+					  struct intel_crtc *crtc)
+{
+	if (!crtc->active)
+		return -EINVAL;
+
+	/* can't use the overlay with double wide pipe */
+	if (crtc->config->double_wide)
+		return -EINVAL;
+
+	return 0;
+}
+
+static void update_pfit_vscale_ratio(struct intel_overlay *overlay)
+{
+	struct drm_device *dev = overlay->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	u32 pfit_control = I915_READ(PFIT_CONTROL);
+	u32 ratio;
+
+	/* XXX: This is not the same logic as in the xorg driver, but more in
+	 * line with the intel documentation for the i965
+	 */
+	if (INTEL_INFO(dev)->gen >= 4) {
+		/* on i965 use the PGM reg to read out the autoscaler values */
+		ratio = I915_READ(PFIT_PGM_RATIOS) >> PFIT_VERT_SCALE_SHIFT_965;
+	} else {
+		if (pfit_control & VERT_AUTO_SCALE)
+			ratio = I915_READ(PFIT_AUTO_RATIOS);
+		else
+			ratio = I915_READ(PFIT_PGM_RATIOS);
+		ratio >>= PFIT_VERT_SCALE_SHIFT;
+	}
+
+	overlay->pfit_vscale_ratio = ratio;
+}
+
+static int check_overlay_dst(struct intel_overlay *overlay,
+			     struct drm_intel_overlay_put_image *rec)
+{
+	struct drm_display_mode *mode = &overlay->crtc->base.mode;
+
+	if (rec->dst_x < mode->hdisplay &&
+	    rec->dst_x + rec->dst_width <= mode->hdisplay &&
+	    rec->dst_y < mode->vdisplay &&
+	    rec->dst_y + rec->dst_height <= mode->vdisplay)
+		return 0;
+	else
+		return -EINVAL;
+}
+
+static int check_overlay_scaling(struct put_image_params *rec)
+{
+	u32 tmp;
+
+	/* downscaling limit is 8.0 */
+	tmp = ((rec->src_scan_h << 16) / rec->dst_h) >> 16;
+	if (tmp > 7)
+		return -EINVAL;
+	tmp = ((rec->src_scan_w << 16) / rec->dst_w) >> 16;
+	if (tmp > 7)
+		return -EINVAL;
+
+	return 0;
+}
+
+static int check_overlay_src(struct drm_device *dev,
+			     struct drm_intel_overlay_put_image *rec,
+			     struct drm_i915_gem_object *new_bo)
+{
+	int uv_hscale = uv_hsubsampling(rec->flags);
+	int uv_vscale = uv_vsubsampling(rec->flags);
+	u32 stride_mask;
+	int depth;
+	u32 tmp;
+
+	/* check src dimensions */
+	if (IS_845G(dev) || IS_I830(dev)) {
+		if (rec->src_height > IMAGE_MAX_HEIGHT_LEGACY ||
+		    rec->src_width  > IMAGE_MAX_WIDTH_LEGACY)
+			return -EINVAL;
+	} else {
+		if (rec->src_height > IMAGE_MAX_HEIGHT ||
+		    rec->src_width  > IMAGE_MAX_WIDTH)
+			return -EINVAL;
+	}
+
+	/* better safe than sorry, use 4 as the maximal subsampling ratio */
+	if (rec->src_height < N_VERT_Y_TAPS*4 ||
+	    rec->src_width  < N_HORIZ_Y_TAPS*4)
+		return -EINVAL;
+
+	/* check alignment constraints */
+	switch (rec->flags & I915_OVERLAY_TYPE_MASK) {
+	case I915_OVERLAY_RGB:
+		/* not implemented */
+		return -EINVAL;
+
+	case I915_OVERLAY_YUV_PACKED:
+		if (uv_vscale != 1)
+			return -EINVAL;
+
+		depth = packed_depth_bytes(rec->flags);
+		if (depth < 0)
+			return depth;
+
+		/* ignore UV planes */
+		rec->stride_UV = 0;
+		rec->offset_U = 0;
+		rec->offset_V = 0;
+		/* check pixel alignment */
+		if (rec->offset_Y % depth)
+			return -EINVAL;
+		break;
+
+	case I915_OVERLAY_YUV_PLANAR:
+		if (uv_vscale < 0 || uv_hscale < 0)
+			return -EINVAL;
+		/* no offset restrictions for planar formats */
+		break;
+
+	default:
+		return -EINVAL;
+	}
+
+	if (rec->src_width % uv_hscale)
+		return -EINVAL;
+
+	/* stride checking */
+	if (IS_I830(dev) || IS_845G(dev))
+		stride_mask = 255;
+	else
+		stride_mask = 63;
+
+	if (rec->stride_Y & stride_mask || rec->stride_UV & stride_mask)
+		return -EINVAL;
+	if (IS_GEN4(dev) && rec->stride_Y < 512)
+		return -EINVAL;
+
+	tmp = (rec->flags & I915_OVERLAY_TYPE_MASK) == I915_OVERLAY_YUV_PLANAR ?
+		4096 : 8192;
+	if (rec->stride_Y > tmp || rec->stride_UV > 2*1024)
+		return -EINVAL;
+
+	/* check buffer dimensions */
+	switch (rec->flags & I915_OVERLAY_TYPE_MASK) {
+	case I915_OVERLAY_RGB:
+	case I915_OVERLAY_YUV_PACKED:
+		/* always 4 Y values per depth pixels */
+		if (packed_width_bytes(rec->flags, rec->src_width) > rec->stride_Y)
+			return -EINVAL;
+
+		tmp = rec->stride_Y*rec->src_height;
+		if (rec->offset_Y + tmp > new_bo->base.size)
+			return -EINVAL;
+		break;
+
+	case I915_OVERLAY_YUV_PLANAR:
+		if (rec->src_width > rec->stride_Y)
+			return -EINVAL;
+		if (rec->src_width/uv_hscale > rec->stride_UV)
+			return -EINVAL;
+
+		tmp = rec->stride_Y * rec->src_height;
+		if (rec->offset_Y + tmp > new_bo->base.size)
+			return -EINVAL;
+
+		tmp = rec->stride_UV * (rec->src_height / uv_vscale);
+		if (rec->offset_U + tmp > new_bo->base.size ||
+		    rec->offset_V + tmp > new_bo->base.size)
+			return -EINVAL;
+		break;
+	}
+
+	return 0;
+}
+
+/**
+ * Return the pipe currently connected to the panel fitter,
+ * or -1 if the panel fitter is not present or not in use
+ */
+static int intel_panel_fitter_pipe(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	u32  pfit_control;
+
+	/* i830 doesn't have a panel fitter */
+	if (INTEL_INFO(dev)->gen <= 3 && (IS_I830(dev) || !IS_MOBILE(dev)))
+		return -1;
+
+	pfit_control = I915_READ(PFIT_CONTROL);
+
+	/* See if the panel fitter is in use */
+	if ((pfit_control & PFIT_ENABLE) == 0)
+		return -1;
+
+	/* 965 can place panel fitter on either pipe */
+	if (IS_GEN4(dev))
+		return (pfit_control >> 29) & 0x3;
+
+	/* older chips can only use pipe 1 */
+	return 1;
+}
+
+int intel_overlay_put_image(struct drm_device *dev, void *data,
+			    struct drm_file *file_priv)
+{
+	struct drm_intel_overlay_put_image *put_image_rec = data;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_overlay *overlay;
+	struct drm_crtc *drmmode_crtc;
+	struct intel_crtc *crtc;
+	struct drm_i915_gem_object *new_bo;
+	struct put_image_params *params;
+	int ret;
+
+	overlay = dev_priv->overlay;
+	if (!overlay) {
+		DRM_DEBUG("userspace bug: no overlay\n");
+		return -ENODEV;
+	}
+
+	if (!(put_image_rec->flags & I915_OVERLAY_ENABLE)) {
+		drm_modeset_lock_all(dev);
+		mutex_lock(&dev->struct_mutex);
+
+		ret = intel_overlay_switch_off(overlay);
+
+		mutex_unlock(&dev->struct_mutex);
+		drm_modeset_unlock_all(dev);
+
+		return ret;
+	}
+
+	params = kmalloc(sizeof(*params), GFP_KERNEL);
+	if (!params)
+		return -ENOMEM;
+
+	drmmode_crtc = drm_crtc_find(dev, put_image_rec->crtc_id);
+	if (!drmmode_crtc) {
+		ret = -ENOENT;
+		goto out_free;
+	}
+	crtc = to_intel_crtc(drmmode_crtc);
+
+	new_bo = to_intel_bo(drm_gem_object_lookup(dev, file_priv,
+						   put_image_rec->bo_handle));
+	if (&new_bo->base == NULL) {
+		ret = -ENOENT;
+		goto out_free;
+	}
+
+	drm_modeset_lock_all(dev);
+	mutex_lock(&dev->struct_mutex);
+
+	if (new_bo->tiling_mode) {
+		DRM_DEBUG_KMS("buffer used for overlay image can not be tiled\n");
+		ret = -EINVAL;
+		goto out_unlock;
+	}
+
+	ret = intel_overlay_recover_from_interrupt(overlay);
+	if (ret != 0)
+		goto out_unlock;
+
+	if (overlay->crtc != crtc) {
+		struct drm_display_mode *mode = &crtc->base.mode;
+		ret = intel_overlay_switch_off(overlay);
+		if (ret != 0)
+			goto out_unlock;
+
+		ret = check_overlay_possible_on_crtc(overlay, crtc);
+		if (ret != 0)
+			goto out_unlock;
+
+		overlay->crtc = crtc;
+		crtc->overlay = overlay;
+
+		/* line too wide, i.e. one-line-mode */
+		if (mode->hdisplay > 1024 &&
+		    intel_panel_fitter_pipe(dev) == crtc->pipe) {
+			overlay->pfit_active = true;
+			update_pfit_vscale_ratio(overlay);
+		} else
+			overlay->pfit_active = false;
+	}
+
+	ret = check_overlay_dst(overlay, put_image_rec);
+	if (ret != 0)
+		goto out_unlock;
+
+	if (overlay->pfit_active) {
+		params->dst_y = ((((u32)put_image_rec->dst_y) << 12) /
+				 overlay->pfit_vscale_ratio);
+		/* shifting right rounds downwards, so add 1 */
+		params->dst_h = ((((u32)put_image_rec->dst_height) << 12) /
+				 overlay->pfit_vscale_ratio) + 1;
+	} else {
+		params->dst_y = put_image_rec->dst_y;
+		params->dst_h = put_image_rec->dst_height;
+	}
+	params->dst_x = put_image_rec->dst_x;
+	params->dst_w = put_image_rec->dst_width;
+
+	params->src_w = put_image_rec->src_width;
+	params->src_h = put_image_rec->src_height;
+	params->src_scan_w = put_image_rec->src_scan_width;
+	params->src_scan_h = put_image_rec->src_scan_height;
+	if (params->src_scan_h > params->src_h ||
+	    params->src_scan_w > params->src_w) {
+		ret = -EINVAL;
+		goto out_unlock;
+	}
+
+	ret = check_overlay_src(dev, put_image_rec, new_bo);
+	if (ret != 0)
+		goto out_unlock;
+	params->format = put_image_rec->flags & ~I915_OVERLAY_FLAGS_MASK;
+	params->stride_Y = put_image_rec->stride_Y;
+	params->stride_UV = put_image_rec->stride_UV;
+	params->offset_Y = put_image_rec->offset_Y;
+	params->offset_U = put_image_rec->offset_U;
+	params->offset_V = put_image_rec->offset_V;
+
+	/* Check scaling after src size to prevent a divide-by-zero. */
+	ret = check_overlay_scaling(params);
+	if (ret != 0)
+		goto out_unlock;
+
+	ret = intel_overlay_do_put_image(overlay, new_bo, params);
+	if (ret != 0)
+		goto out_unlock;
+
+	mutex_unlock(&dev->struct_mutex);
+	drm_modeset_unlock_all(dev);
+
+	kfree(params);
+
+	return 0;
+
+out_unlock:
+	mutex_unlock(&dev->struct_mutex);
+	drm_modeset_unlock_all(dev);
+	drm_gem_object_unreference_unlocked(&new_bo->base);
+out_free:
+	kfree(params);
+
+	return ret;
+}
+
+static void update_reg_attrs(struct intel_overlay *overlay,
+			     struct overlay_registers __iomem *regs)
+{
+	iowrite32((overlay->contrast << 18) | (overlay->brightness & 0xff),
+		  &regs->OCLRC0);
+	iowrite32(overlay->saturation, &regs->OCLRC1);
+}
+
+static bool check_gamma_bounds(u32 gamma1, u32 gamma2)
+{
+	int i;
+
+	if (gamma1 & 0xff000000 || gamma2 & 0xff000000)
+		return false;
+
+	for (i = 0; i < 3; i++) {
+		if (((gamma1 >> i*8) & 0xff) >= ((gamma2 >> i*8) & 0xff))
+			return false;
+	}
+
+	return true;
+}
+
+static bool check_gamma5_errata(u32 gamma5)
+{
+	int i;
+
+	for (i = 0; i < 3; i++) {
+		if (((gamma5 >> i*8) & 0xff) == 0x80)
+			return false;
+	}
+
+	return true;
+}
+
+static int check_gamma(struct drm_intel_overlay_attrs *attrs)
+{
+	if (!check_gamma_bounds(0, attrs->gamma0) ||
+	    !check_gamma_bounds(attrs->gamma0, attrs->gamma1) ||
+	    !check_gamma_bounds(attrs->gamma1, attrs->gamma2) ||
+	    !check_gamma_bounds(attrs->gamma2, attrs->gamma3) ||
+	    !check_gamma_bounds(attrs->gamma3, attrs->gamma4) ||
+	    !check_gamma_bounds(attrs->gamma4, attrs->gamma5) ||
+	    !check_gamma_bounds(attrs->gamma5, 0x00ffffff))
+		return -EINVAL;
+
+	if (!check_gamma5_errata(attrs->gamma5))
+		return -EINVAL;
+
+	return 0;
+}
+
+int intel_overlay_attrs(struct drm_device *dev, void *data,
+			struct drm_file *file_priv)
+{
+	struct drm_intel_overlay_attrs *attrs = data;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_overlay *overlay;
+	struct overlay_registers __iomem *regs;
+	int ret;
+
+	overlay = dev_priv->overlay;
+	if (!overlay) {
+		DRM_DEBUG("userspace bug: no overlay\n");
+		return -ENODEV;
+	}
+
+	drm_modeset_lock_all(dev);
+	mutex_lock(&dev->struct_mutex);
+
+	ret = -EINVAL;
+	if (!(attrs->flags & I915_OVERLAY_UPDATE_ATTRS)) {
+		attrs->color_key  = overlay->color_key;
+		attrs->brightness = overlay->brightness;
+		attrs->contrast   = overlay->contrast;
+		attrs->saturation = overlay->saturation;
+
+		if (!IS_GEN2(dev)) {
+			attrs->gamma0 = I915_READ(OGAMC0);
+			attrs->gamma1 = I915_READ(OGAMC1);
+			attrs->gamma2 = I915_READ(OGAMC2);
+			attrs->gamma3 = I915_READ(OGAMC3);
+			attrs->gamma4 = I915_READ(OGAMC4);
+			attrs->gamma5 = I915_READ(OGAMC5);
+		}
+	} else {
+		if (attrs->brightness < -128 || attrs->brightness > 127)
+			goto out_unlock;
+		if (attrs->contrast > 255)
+			goto out_unlock;
+		if (attrs->saturation > 1023)
+			goto out_unlock;
+
+		overlay->color_key  = attrs->color_key;
+		overlay->brightness = attrs->brightness;
+		overlay->contrast   = attrs->contrast;
+		overlay->saturation = attrs->saturation;
+
+		regs = intel_overlay_map_regs(overlay);
+		if (!regs) {
+			ret = -ENOMEM;
+			goto out_unlock;
+		}
+
+		update_reg_attrs(overlay, regs);
+
+		intel_overlay_unmap_regs(overlay, regs);
+
+		if (attrs->flags & I915_OVERLAY_UPDATE_GAMMA) {
+			if (IS_GEN2(dev))
+				goto out_unlock;
+
+			if (overlay->active) {
+				ret = -EBUSY;
+				goto out_unlock;
+			}
+
+			ret = check_gamma(attrs);
+			if (ret)
+				goto out_unlock;
+
+			I915_WRITE(OGAMC0, attrs->gamma0);
+			I915_WRITE(OGAMC1, attrs->gamma1);
+			I915_WRITE(OGAMC2, attrs->gamma2);
+			I915_WRITE(OGAMC3, attrs->gamma3);
+			I915_WRITE(OGAMC4, attrs->gamma4);
+			I915_WRITE(OGAMC5, attrs->gamma5);
+		}
+	}
+	overlay->color_key_enabled = (attrs->flags & I915_OVERLAY_DISABLE_DEST_COLORKEY) == 0;
+
+	ret = 0;
+out_unlock:
+	mutex_unlock(&dev->struct_mutex);
+	drm_modeset_unlock_all(dev);
+
+	return ret;
+}
+
+void intel_setup_overlay(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_overlay *overlay;
+	struct drm_i915_gem_object *reg_bo;
+	struct overlay_registers __iomem *regs;
+	int ret;
+
+	if (!HAS_OVERLAY(dev))
+		return;
+
+	overlay = kzalloc(sizeof(*overlay), GFP_KERNEL);
+	if (!overlay)
+		return;
+
+	mutex_lock(&dev->struct_mutex);
+	if (WARN_ON(dev_priv->overlay))
+		goto out_free;
+
+	overlay->dev = dev;
+
+	reg_bo = NULL;
+	if (!OVERLAY_NEEDS_PHYSICAL(dev))
+		reg_bo = i915_gem_object_create_stolen(dev, PAGE_SIZE);
+	if (reg_bo == NULL)
+		reg_bo = i915_gem_alloc_object(dev, PAGE_SIZE);
+	if (reg_bo == NULL)
+		goto out_free;
+	overlay->reg_bo = reg_bo;
+
+	if (OVERLAY_NEEDS_PHYSICAL(dev)) {
+		ret = i915_gem_object_attach_phys(reg_bo, PAGE_SIZE);
+		if (ret) {
+			DRM_ERROR("failed to attach phys overlay regs\n");
+			goto out_free_bo;
+		}
+		overlay->flip_addr = reg_bo->phys_handle->busaddr;
+	} else {
+		ret = i915_gem_obj_ggtt_pin(reg_bo, PAGE_SIZE, PIN_MAPPABLE);
+		if (ret) {
+			DRM_ERROR("failed to pin overlay register bo\n");
+			goto out_free_bo;
+		}
+		overlay->flip_addr = i915_gem_obj_ggtt_offset(reg_bo);
+
+		ret = i915_gem_object_set_to_gtt_domain(reg_bo, true);
+		if (ret) {
+			DRM_ERROR("failed to move overlay register bo into the GTT\n");
+			goto out_unpin_bo;
+		}
+	}
+
+	/* init all values */
+	overlay->color_key = 0x0101fe;
+	overlay->color_key_enabled = true;
+	overlay->brightness = -19;
+	overlay->contrast = 75;
+	overlay->saturation = 146;
+
+	regs = intel_overlay_map_regs(overlay);
+	if (!regs)
+		goto out_unpin_bo;
+
+	memset_io(regs, 0, sizeof(struct overlay_registers));
+	update_polyphase_filter(regs);
+	update_reg_attrs(overlay, regs);
+
+	intel_overlay_unmap_regs(overlay, regs);
+
+	dev_priv->overlay = overlay;
+	mutex_unlock(&dev->struct_mutex);
+	DRM_INFO("initialized overlay support\n");
+	return;
+
+out_unpin_bo:
+	if (!OVERLAY_NEEDS_PHYSICAL(dev))
+		i915_gem_object_ggtt_unpin(reg_bo);
+out_free_bo:
+	drm_gem_object_unreference(&reg_bo->base);
+out_free:
+	mutex_unlock(&dev->struct_mutex);
+	kfree(overlay);
+	return;
+}
+
+void intel_cleanup_overlay(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	if (!dev_priv->overlay)
+		return;
+
+	/* The bo's should be free'd by the generic code already.
+	 * Furthermore modesetting teardown happens beforehand so the
+	 * hardware should be off already */
+	WARN_ON(dev_priv->overlay->active);
+
+	drm_gem_object_unreference_unlocked(&dev_priv->overlay->reg_bo->base);
+	kfree(dev_priv->overlay);
+}
+
+struct intel_overlay_error_state {
+	struct overlay_registers regs;
+	unsigned long base;
+	u32 dovsta;
+	u32 isr;
+};
+
+static struct overlay_registers __iomem *
+intel_overlay_map_regs_atomic(struct intel_overlay *overlay)
+{
+	struct drm_i915_private *dev_priv = to_i915(overlay->dev);
+	struct i915_ggtt *ggtt = &dev_priv->ggtt;
+	struct overlay_registers __iomem *regs;
+
+	if (OVERLAY_NEEDS_PHYSICAL(overlay->dev))
+		/* Cast to make sparse happy, but it's wc memory anyway, so
+		 * equivalent to the wc io mapping on X86. */
+		regs = (struct overlay_registers __iomem *)
+			overlay->reg_bo->phys_handle->vaddr;
+	else
+		regs = io_mapping_map_atomic_wc(ggtt->mappable,
+						i915_gem_obj_ggtt_offset(overlay->reg_bo));
+
+	return regs;
+}
+
+static void intel_overlay_unmap_regs_atomic(struct intel_overlay *overlay,
+					struct overlay_registers __iomem *regs)
+{
+	if (!OVERLAY_NEEDS_PHYSICAL(overlay->dev))
+		io_mapping_unmap_atomic(regs);
+}
+
+
+struct intel_overlay_error_state *
+intel_overlay_capture_error_state(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_overlay *overlay = dev_priv->overlay;
+	struct intel_overlay_error_state *error;
+	struct overlay_registers __iomem *regs;
+
+	if (!overlay || !overlay->active)
+		return NULL;
+
+	error = kmalloc(sizeof(*error), GFP_ATOMIC);
+	if (error == NULL)
+		return NULL;
+
+	error->dovsta = I915_READ(DOVSTA);
+	error->isr = I915_READ(ISR);
+	if (OVERLAY_NEEDS_PHYSICAL(overlay->dev))
+		error->base = (__force long)overlay->reg_bo->phys_handle->vaddr;
+	else
+		error->base = i915_gem_obj_ggtt_offset(overlay->reg_bo);
+
+	regs = intel_overlay_map_regs_atomic(overlay);
+	if (!regs)
+		goto err;
+
+	memcpy_fromio(&error->regs, regs, sizeof(struct overlay_registers));
+	intel_overlay_unmap_regs_atomic(overlay, regs);
+
+	return error;
+
+err:
+	kfree(error);
+	return NULL;
+}
+
+void
+intel_overlay_print_error_state(struct drm_i915_error_state_buf *m,
+				struct intel_overlay_error_state *error)
+{
+	i915_error_printf(m, "Overlay, status: 0x%08x, interrupt: 0x%08x\n",
+			  error->dovsta, error->isr);
+	i915_error_printf(m, "  Register file at 0x%08lx:\n",
+			  error->base);
+
+#define P(x) i915_error_printf(m, "    " #x ":	0x%08x\n", error->regs.x)
+	P(OBUF_0Y);
+	P(OBUF_1Y);
+	P(OBUF_0U);
+	P(OBUF_0V);
+	P(OBUF_1U);
+	P(OBUF_1V);
+	P(OSTRIDE);
+	P(YRGB_VPH);
+	P(UV_VPH);
+	P(HORZ_PH);
+	P(INIT_PHS);
+	P(DWINPOS);
+	P(DWINSZ);
+	P(SWIDTH);
+	P(SWIDTHSW);
+	P(SHEIGHT);
+	P(YRGBSCALE);
+	P(UVSCALE);
+	P(OCLRC0);
+	P(OCLRC1);
+	P(DCLRKV);
+	P(DCLRKM);
+	P(SCLRKVH);
+	P(SCLRKVL);
+	P(SCLRKEN);
+	P(OCONFIG);
+	P(OCMD);
+	P(OSTART_0Y);
+	P(OSTART_1Y);
+	P(OSTART_0U);
+	P(OSTART_0V);
+	P(OSTART_1U);
+	P(OSTART_1V);
+	P(OTILEOFF_0Y);
+	P(OTILEOFF_1Y);
+	P(OTILEOFF_0U);
+	P(OTILEOFF_0V);
+	P(OTILEOFF_1U);
+	P(OTILEOFF_1V);
+	P(FASTHSCALE);
+	P(UVSCALEV);
+#undef P
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/i915/intel_panel.c
@@ -0,0 +1,1841 @@
+/*
+ * Copyright © 2006-2010 Intel Corporation
+ * Copyright (c) 2006 Dave Airlie <airlied@linux.ie>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *	Eric Anholt <eric@anholt.net>
+ *      Dave Airlie <airlied@linux.ie>
+ *      Jesse Barnes <jesse.barnes@intel.com>
+ *      Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/kernel.h>
+#include <linux/moduleparam.h>
+#include <linux/pwm.h>
+#include "intel_drv.h"
+
+#define CRC_PMIC_PWM_PERIOD_NS	21333
+
+void
+intel_fixed_panel_mode(const struct drm_display_mode *fixed_mode,
+		       struct drm_display_mode *adjusted_mode)
+{
+	drm_mode_copy(adjusted_mode, fixed_mode);
+
+	drm_mode_set_crtcinfo(adjusted_mode, 0);
+}
+
+/**
+ * intel_find_panel_downclock - find the reduced downclock for LVDS in EDID
+ * @dev: drm device
+ * @fixed_mode : panel native mode
+ * @connector: LVDS/eDP connector
+ *
+ * Return downclock_avail
+ * Find the reduced downclock for LVDS/eDP in EDID.
+ */
+struct drm_display_mode *
+intel_find_panel_downclock(struct drm_device *dev,
+			struct drm_display_mode *fixed_mode,
+			struct drm_connector *connector)
+{
+	struct drm_display_mode *scan, *tmp_mode;
+	int temp_downclock;
+
+	temp_downclock = fixed_mode->clock;
+	tmp_mode = NULL;
+
+	list_for_each_entry(scan, &connector->probed_modes, head) {
+		/*
+		 * If one mode has the same resolution with the fixed_panel
+		 * mode while they have the different refresh rate, it means
+		 * that the reduced downclock is found. In such
+		 * case we can set the different FPx0/1 to dynamically select
+		 * between low and high frequency.
+		 */
+		if (scan->hdisplay == fixed_mode->hdisplay &&
+		    scan->hsync_start == fixed_mode->hsync_start &&
+		    scan->hsync_end == fixed_mode->hsync_end &&
+		    scan->htotal == fixed_mode->htotal &&
+		    scan->vdisplay == fixed_mode->vdisplay &&
+		    scan->vsync_start == fixed_mode->vsync_start &&
+		    scan->vsync_end == fixed_mode->vsync_end &&
+		    scan->vtotal == fixed_mode->vtotal) {
+			if (scan->clock < temp_downclock) {
+				/*
+				 * The downclock is already found. But we
+				 * expect to find the lower downclock.
+				 */
+				temp_downclock = scan->clock;
+				tmp_mode = scan;
+			}
+		}
+	}
+
+	if (temp_downclock < fixed_mode->clock)
+		return drm_mode_duplicate(dev, tmp_mode);
+	else
+		return NULL;
+}
+
+/* adjusted_mode has been preset to be the panel's fixed mode */
+void
+intel_pch_panel_fitting(struct intel_crtc *intel_crtc,
+			struct intel_crtc_state *pipe_config,
+			int fitting_mode)
+{
+	const struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
+	int x = 0, y = 0, width = 0, height = 0;
+
+	/* Native modes don't need fitting */
+	if (adjusted_mode->crtc_hdisplay == pipe_config->pipe_src_w &&
+	    adjusted_mode->crtc_vdisplay == pipe_config->pipe_src_h)
+		goto done;
+
+	switch (fitting_mode) {
+	case DRM_MODE_SCALE_CENTER:
+		width = pipe_config->pipe_src_w;
+		height = pipe_config->pipe_src_h;
+		x = (adjusted_mode->crtc_hdisplay - width + 1)/2;
+		y = (adjusted_mode->crtc_vdisplay - height + 1)/2;
+		break;
+
+	case DRM_MODE_SCALE_ASPECT:
+		/* Scale but preserve the aspect ratio */
+		{
+			u32 scaled_width = adjusted_mode->crtc_hdisplay
+				* pipe_config->pipe_src_h;
+			u32 scaled_height = pipe_config->pipe_src_w
+				* adjusted_mode->crtc_vdisplay;
+			if (scaled_width > scaled_height) { /* pillar */
+				width = scaled_height / pipe_config->pipe_src_h;
+				if (width & 1)
+					width++;
+				x = (adjusted_mode->crtc_hdisplay - width + 1) / 2;
+				y = 0;
+				height = adjusted_mode->crtc_vdisplay;
+			} else if (scaled_width < scaled_height) { /* letter */
+				height = scaled_width / pipe_config->pipe_src_w;
+				if (height & 1)
+				    height++;
+				y = (adjusted_mode->crtc_vdisplay - height + 1) / 2;
+				x = 0;
+				width = adjusted_mode->crtc_hdisplay;
+			} else {
+				x = y = 0;
+				width = adjusted_mode->crtc_hdisplay;
+				height = adjusted_mode->crtc_vdisplay;
+			}
+		}
+		break;
+
+	case DRM_MODE_SCALE_FULLSCREEN:
+		x = y = 0;
+		width = adjusted_mode->crtc_hdisplay;
+		height = adjusted_mode->crtc_vdisplay;
+		break;
+
+	default:
+		WARN(1, "bad panel fit mode: %d\n", fitting_mode);
+		return;
+	}
+
+done:
+	pipe_config->pch_pfit.pos = (x << 16) | y;
+	pipe_config->pch_pfit.size = (width << 16) | height;
+	pipe_config->pch_pfit.enabled = pipe_config->pch_pfit.size != 0;
+}
+
+static void
+centre_horizontally(struct drm_display_mode *adjusted_mode,
+		    int width)
+{
+	u32 border, sync_pos, blank_width, sync_width;
+
+	/* keep the hsync and hblank widths constant */
+	sync_width = adjusted_mode->crtc_hsync_end - adjusted_mode->crtc_hsync_start;
+	blank_width = adjusted_mode->crtc_hblank_end - adjusted_mode->crtc_hblank_start;
+	sync_pos = (blank_width - sync_width + 1) / 2;
+
+	border = (adjusted_mode->crtc_hdisplay - width + 1) / 2;
+	border += border & 1; /* make the border even */
+
+	adjusted_mode->crtc_hdisplay = width;
+	adjusted_mode->crtc_hblank_start = width + border;
+	adjusted_mode->crtc_hblank_end = adjusted_mode->crtc_hblank_start + blank_width;
+
+	adjusted_mode->crtc_hsync_start = adjusted_mode->crtc_hblank_start + sync_pos;
+	adjusted_mode->crtc_hsync_end = adjusted_mode->crtc_hsync_start + sync_width;
+}
+
+static void
+centre_vertically(struct drm_display_mode *adjusted_mode,
+		  int height)
+{
+	u32 border, sync_pos, blank_width, sync_width;
+
+	/* keep the vsync and vblank widths constant */
+	sync_width = adjusted_mode->crtc_vsync_end - adjusted_mode->crtc_vsync_start;
+	blank_width = adjusted_mode->crtc_vblank_end - adjusted_mode->crtc_vblank_start;
+	sync_pos = (blank_width - sync_width + 1) / 2;
+
+	border = (adjusted_mode->crtc_vdisplay - height + 1) / 2;
+
+	adjusted_mode->crtc_vdisplay = height;
+	adjusted_mode->crtc_vblank_start = height + border;
+	adjusted_mode->crtc_vblank_end = adjusted_mode->crtc_vblank_start + blank_width;
+
+	adjusted_mode->crtc_vsync_start = adjusted_mode->crtc_vblank_start + sync_pos;
+	adjusted_mode->crtc_vsync_end = adjusted_mode->crtc_vsync_start + sync_width;
+}
+
+static inline u32 panel_fitter_scaling(u32 source, u32 target)
+{
+	/*
+	 * Floating point operation is not supported. So the FACTOR
+	 * is defined, which can avoid the floating point computation
+	 * when calculating the panel ratio.
+	 */
+#define ACCURACY 12
+#define FACTOR (1 << ACCURACY)
+	u32 ratio = source * FACTOR / target;
+	return (FACTOR * ratio + FACTOR/2) / FACTOR;
+}
+
+static void i965_scale_aspect(struct intel_crtc_state *pipe_config,
+			      u32 *pfit_control)
+{
+	const struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
+	u32 scaled_width = adjusted_mode->crtc_hdisplay *
+		pipe_config->pipe_src_h;
+	u32 scaled_height = pipe_config->pipe_src_w *
+		adjusted_mode->crtc_vdisplay;
+
+	/* 965+ is easy, it does everything in hw */
+	if (scaled_width > scaled_height)
+		*pfit_control |= PFIT_ENABLE |
+			PFIT_SCALING_PILLAR;
+	else if (scaled_width < scaled_height)
+		*pfit_control |= PFIT_ENABLE |
+			PFIT_SCALING_LETTER;
+	else if (adjusted_mode->crtc_hdisplay != pipe_config->pipe_src_w)
+		*pfit_control |= PFIT_ENABLE | PFIT_SCALING_AUTO;
+}
+
+static void i9xx_scale_aspect(struct intel_crtc_state *pipe_config,
+			      u32 *pfit_control, u32 *pfit_pgm_ratios,
+			      u32 *border)
+{
+	struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
+	u32 scaled_width = adjusted_mode->crtc_hdisplay *
+		pipe_config->pipe_src_h;
+	u32 scaled_height = pipe_config->pipe_src_w *
+		adjusted_mode->crtc_vdisplay;
+	u32 bits;
+
+	/*
+	 * For earlier chips we have to calculate the scaling
+	 * ratio by hand and program it into the
+	 * PFIT_PGM_RATIO register
+	 */
+	if (scaled_width > scaled_height) { /* pillar */
+		centre_horizontally(adjusted_mode,
+				    scaled_height /
+				    pipe_config->pipe_src_h);
+
+		*border = LVDS_BORDER_ENABLE;
+		if (pipe_config->pipe_src_h != adjusted_mode->crtc_vdisplay) {
+			bits = panel_fitter_scaling(pipe_config->pipe_src_h,
+						    adjusted_mode->crtc_vdisplay);
+
+			*pfit_pgm_ratios |= (bits << PFIT_HORIZ_SCALE_SHIFT |
+					     bits << PFIT_VERT_SCALE_SHIFT);
+			*pfit_control |= (PFIT_ENABLE |
+					  VERT_INTERP_BILINEAR |
+					  HORIZ_INTERP_BILINEAR);
+		}
+	} else if (scaled_width < scaled_height) { /* letter */
+		centre_vertically(adjusted_mode,
+				  scaled_width /
+				  pipe_config->pipe_src_w);
+
+		*border = LVDS_BORDER_ENABLE;
+		if (pipe_config->pipe_src_w != adjusted_mode->crtc_hdisplay) {
+			bits = panel_fitter_scaling(pipe_config->pipe_src_w,
+						    adjusted_mode->crtc_hdisplay);
+
+			*pfit_pgm_ratios |= (bits << PFIT_HORIZ_SCALE_SHIFT |
+					     bits << PFIT_VERT_SCALE_SHIFT);
+			*pfit_control |= (PFIT_ENABLE |
+					  VERT_INTERP_BILINEAR |
+					  HORIZ_INTERP_BILINEAR);
+		}
+	} else {
+		/* Aspects match, Let hw scale both directions */
+		*pfit_control |= (PFIT_ENABLE |
+				  VERT_AUTO_SCALE | HORIZ_AUTO_SCALE |
+				  VERT_INTERP_BILINEAR |
+				  HORIZ_INTERP_BILINEAR);
+	}
+}
+
+void intel_gmch_panel_fitting(struct intel_crtc *intel_crtc,
+			      struct intel_crtc_state *pipe_config,
+			      int fitting_mode)
+{
+	struct drm_device *dev = intel_crtc->base.dev;
+	u32 pfit_control = 0, pfit_pgm_ratios = 0, border = 0;
+	struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
+
+	/* Native modes don't need fitting */
+	if (adjusted_mode->crtc_hdisplay == pipe_config->pipe_src_w &&
+	    adjusted_mode->crtc_vdisplay == pipe_config->pipe_src_h)
+		goto out;
+
+	switch (fitting_mode) {
+	case DRM_MODE_SCALE_CENTER:
+		/*
+		 * For centered modes, we have to calculate border widths &
+		 * heights and modify the values programmed into the CRTC.
+		 */
+		centre_horizontally(adjusted_mode, pipe_config->pipe_src_w);
+		centre_vertically(adjusted_mode, pipe_config->pipe_src_h);
+		border = LVDS_BORDER_ENABLE;
+		break;
+	case DRM_MODE_SCALE_ASPECT:
+		/* Scale but preserve the aspect ratio */
+		if (INTEL_INFO(dev)->gen >= 4)
+			i965_scale_aspect(pipe_config, &pfit_control);
+		else
+			i9xx_scale_aspect(pipe_config, &pfit_control,
+					  &pfit_pgm_ratios, &border);
+		break;
+	case DRM_MODE_SCALE_FULLSCREEN:
+		/*
+		 * Full scaling, even if it changes the aspect ratio.
+		 * Fortunately this is all done for us in hw.
+		 */
+		if (pipe_config->pipe_src_h != adjusted_mode->crtc_vdisplay ||
+		    pipe_config->pipe_src_w != adjusted_mode->crtc_hdisplay) {
+			pfit_control |= PFIT_ENABLE;
+			if (INTEL_INFO(dev)->gen >= 4)
+				pfit_control |= PFIT_SCALING_AUTO;
+			else
+				pfit_control |= (VERT_AUTO_SCALE |
+						 VERT_INTERP_BILINEAR |
+						 HORIZ_AUTO_SCALE |
+						 HORIZ_INTERP_BILINEAR);
+		}
+		break;
+	default:
+		WARN(1, "bad panel fit mode: %d\n", fitting_mode);
+		return;
+	}
+
+	/* 965+ wants fuzzy fitting */
+	/* FIXME: handle multiple panels by failing gracefully */
+	if (INTEL_INFO(dev)->gen >= 4)
+		pfit_control |= ((intel_crtc->pipe << PFIT_PIPE_SHIFT) |
+				 PFIT_FILTER_FUZZY);
+
+out:
+	if ((pfit_control & PFIT_ENABLE) == 0) {
+		pfit_control = 0;
+		pfit_pgm_ratios = 0;
+	}
+
+	/* Make sure pre-965 set dither correctly for 18bpp panels. */
+	if (INTEL_INFO(dev)->gen < 4 && pipe_config->pipe_bpp == 18)
+		pfit_control |= PANEL_8TO6_DITHER_ENABLE;
+
+	pipe_config->gmch_pfit.control = pfit_control;
+	pipe_config->gmch_pfit.pgm_ratios = pfit_pgm_ratios;
+	pipe_config->gmch_pfit.lvds_border_bits = border;
+}
+
+enum drm_connector_status
+intel_panel_detect(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	/* Assume that the BIOS does not lie through the OpRegion... */
+	if (!i915.panel_ignore_lid && dev_priv->opregion.lid_state) {
+		return *dev_priv->opregion.lid_state & 0x1 ?
+			connector_status_connected :
+			connector_status_disconnected;
+	}
+
+	switch (i915.panel_ignore_lid) {
+	case -2:
+		return connector_status_connected;
+	case -1:
+		return connector_status_disconnected;
+	default:
+		return connector_status_unknown;
+	}
+}
+
+/**
+ * scale - scale values from one range to another
+ *
+ * @source_val: value in range [@source_min..@source_max]
+ *
+ * Return @source_val in range [@source_min..@source_max] scaled to range
+ * [@target_min..@target_max].
+ */
+static uint32_t scale(uint32_t source_val,
+		      uint32_t source_min, uint32_t source_max,
+		      uint32_t target_min, uint32_t target_max)
+{
+	uint64_t target_val;
+
+	WARN_ON(source_min > source_max);
+	WARN_ON(target_min > target_max);
+
+	/* defensive */
+	source_val = clamp(source_val, source_min, source_max);
+
+	/* avoid overflows */
+	target_val = DIV_ROUND_CLOSEST_ULL((uint64_t)(source_val - source_min) *
+			(target_max - target_min), source_max - source_min);
+	target_val += target_min;
+
+	return target_val;
+}
+
+/* Scale user_level in range [0..user_max] to [hw_min..hw_max]. */
+static inline u32 scale_user_to_hw(struct intel_connector *connector,
+				   u32 user_level, u32 user_max)
+{
+	struct intel_panel *panel = &connector->panel;
+
+	return scale(user_level, 0, user_max,
+		     panel->backlight.min, panel->backlight.max);
+}
+
+/* Scale user_level in range [0..user_max] to [0..hw_max], clamping the result
+ * to [hw_min..hw_max]. */
+static inline u32 clamp_user_to_hw(struct intel_connector *connector,
+				   u32 user_level, u32 user_max)
+{
+	struct intel_panel *panel = &connector->panel;
+	u32 hw_level;
+
+	hw_level = scale(user_level, 0, user_max, 0, panel->backlight.max);
+	hw_level = clamp(hw_level, panel->backlight.min, panel->backlight.max);
+
+	return hw_level;
+}
+
+/* Scale hw_level in range [hw_min..hw_max] to [0..user_max]. */
+static inline u32 scale_hw_to_user(struct intel_connector *connector,
+				   u32 hw_level, u32 user_max)
+{
+	struct intel_panel *panel = &connector->panel;
+
+	return scale(hw_level, panel->backlight.min, panel->backlight.max,
+		     0, user_max);
+}
+
+static u32 intel_panel_compute_brightness(struct intel_connector *connector,
+					  u32 val)
+{
+	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+	struct intel_panel *panel = &connector->panel;
+
+	WARN_ON(panel->backlight.max == 0);
+
+	if (i915.invert_brightness < 0)
+		return val;
+
+	if (i915.invert_brightness > 0 ||
+	    dev_priv->quirks & QUIRK_INVERT_BRIGHTNESS) {
+		return panel->backlight.max - val;
+	}
+
+	return val;
+}
+
+static u32 lpt_get_backlight(struct intel_connector *connector)
+{
+	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+
+	return I915_READ(BLC_PWM_PCH_CTL2) & BACKLIGHT_DUTY_CYCLE_MASK;
+}
+
+static u32 pch_get_backlight(struct intel_connector *connector)
+{
+	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+
+	return I915_READ(BLC_PWM_CPU_CTL) & BACKLIGHT_DUTY_CYCLE_MASK;
+}
+
+static u32 i9xx_get_backlight(struct intel_connector *connector)
+{
+	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+	struct intel_panel *panel = &connector->panel;
+	u32 val;
+
+	val = I915_READ(BLC_PWM_CTL) & BACKLIGHT_DUTY_CYCLE_MASK;
+	if (INTEL_INFO(dev_priv)->gen < 4)
+		val >>= 1;
+
+	if (panel->backlight.combination_mode) {
+		u8 lbpc;
+
+		pci_read_config_byte(dev_priv->dev->pdev, LBPC, &lbpc);
+		val *= lbpc;
+	}
+
+	return val;
+}
+
+static u32 _vlv_get_backlight(struct drm_i915_private *dev_priv, enum pipe pipe)
+{
+	if (WARN_ON(pipe != PIPE_A && pipe != PIPE_B))
+		return 0;
+
+	return I915_READ(VLV_BLC_PWM_CTL(pipe)) & BACKLIGHT_DUTY_CYCLE_MASK;
+}
+
+static u32 vlv_get_backlight(struct intel_connector *connector)
+{
+	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+	enum pipe pipe = intel_get_pipe_from_connector(connector);
+
+	return _vlv_get_backlight(dev_priv, pipe);
+}
+
+static u32 bxt_get_backlight(struct intel_connector *connector)
+{
+	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+	struct intel_panel *panel = &connector->panel;
+
+	return I915_READ(BXT_BLC_PWM_DUTY(panel->backlight.controller));
+}
+
+static u32 pwm_get_backlight(struct intel_connector *connector)
+{
+	struct intel_panel *panel = &connector->panel;
+	int duty_ns;
+
+	duty_ns = pwm_get_duty_cycle(panel->backlight.pwm);
+	return DIV_ROUND_UP(duty_ns * 100, CRC_PMIC_PWM_PERIOD_NS);
+}
+
+static u32 intel_panel_get_backlight(struct intel_connector *connector)
+{
+	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+	struct intel_panel *panel = &connector->panel;
+	u32 val = 0;
+
+	mutex_lock(&dev_priv->backlight_lock);
+
+	if (panel->backlight.enabled) {
+		val = panel->backlight.get(connector);
+		val = intel_panel_compute_brightness(connector, val);
+	}
+
+	mutex_unlock(&dev_priv->backlight_lock);
+
+	DRM_DEBUG_DRIVER("get backlight PWM = %d\n", val);
+	return val;
+}
+
+static void lpt_set_backlight(struct intel_connector *connector, u32 level)
+{
+	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+	u32 val = I915_READ(BLC_PWM_PCH_CTL2) & ~BACKLIGHT_DUTY_CYCLE_MASK;
+	I915_WRITE(BLC_PWM_PCH_CTL2, val | level);
+}
+
+static void pch_set_backlight(struct intel_connector *connector, u32 level)
+{
+	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+	u32 tmp;
+
+	tmp = I915_READ(BLC_PWM_CPU_CTL) & ~BACKLIGHT_DUTY_CYCLE_MASK;
+	I915_WRITE(BLC_PWM_CPU_CTL, tmp | level);
+}
+
+static void i9xx_set_backlight(struct intel_connector *connector, u32 level)
+{
+	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+	struct intel_panel *panel = &connector->panel;
+	u32 tmp, mask;
+
+	WARN_ON(panel->backlight.max == 0);
+
+	if (panel->backlight.combination_mode) {
+		u8 lbpc;
+
+		lbpc = level * 0xfe / panel->backlight.max + 1;
+		level /= lbpc;
+		pci_write_config_byte(dev_priv->dev->pdev, LBPC, lbpc);
+	}
+
+	if (IS_GEN4(dev_priv)) {
+		mask = BACKLIGHT_DUTY_CYCLE_MASK;
+	} else {
+		level <<= 1;
+		mask = BACKLIGHT_DUTY_CYCLE_MASK_PNV;
+	}
+
+	tmp = I915_READ(BLC_PWM_CTL) & ~mask;
+	I915_WRITE(BLC_PWM_CTL, tmp | level);
+}
+
+static void vlv_set_backlight(struct intel_connector *connector, u32 level)
+{
+	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+	enum pipe pipe = intel_get_pipe_from_connector(connector);
+	u32 tmp;
+
+	if (WARN_ON(pipe != PIPE_A && pipe != PIPE_B))
+		return;
+
+	tmp = I915_READ(VLV_BLC_PWM_CTL(pipe)) & ~BACKLIGHT_DUTY_CYCLE_MASK;
+	I915_WRITE(VLV_BLC_PWM_CTL(pipe), tmp | level);
+}
+
+static void bxt_set_backlight(struct intel_connector *connector, u32 level)
+{
+	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+	struct intel_panel *panel = &connector->panel;
+
+	I915_WRITE(BXT_BLC_PWM_DUTY(panel->backlight.controller), level);
+}
+
+static void pwm_set_backlight(struct intel_connector *connector, u32 level)
+{
+	struct intel_panel *panel = &connector->panel;
+	int duty_ns = DIV_ROUND_UP(level * CRC_PMIC_PWM_PERIOD_NS, 100);
+
+	pwm_config(panel->backlight.pwm, duty_ns, CRC_PMIC_PWM_PERIOD_NS);
+}
+
+static void
+intel_panel_actually_set_backlight(struct intel_connector *connector, u32 level)
+{
+	struct intel_panel *panel = &connector->panel;
+
+	DRM_DEBUG_DRIVER("set backlight PWM = %d\n", level);
+
+	level = intel_panel_compute_brightness(connector, level);
+	panel->backlight.set(connector, level);
+}
+
+/* set backlight brightness to level in range [0..max], scaling wrt hw min */
+static void intel_panel_set_backlight(struct intel_connector *connector,
+				      u32 user_level, u32 user_max)
+{
+	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+	struct intel_panel *panel = &connector->panel;
+	u32 hw_level;
+
+	if (!panel->backlight.present)
+		return;
+
+	mutex_lock(&dev_priv->backlight_lock);
+
+	WARN_ON(panel->backlight.max == 0);
+
+	hw_level = scale_user_to_hw(connector, user_level, user_max);
+	panel->backlight.level = hw_level;
+
+	if (panel->backlight.enabled)
+		intel_panel_actually_set_backlight(connector, hw_level);
+
+	mutex_unlock(&dev_priv->backlight_lock);
+}
+
+/* set backlight brightness to level in range [0..max], assuming hw min is
+ * respected.
+ */
+void intel_panel_set_backlight_acpi(struct intel_connector *connector,
+				    u32 user_level, u32 user_max)
+{
+	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+	struct intel_panel *panel = &connector->panel;
+	enum pipe pipe = intel_get_pipe_from_connector(connector);
+	u32 hw_level;
+
+	/*
+	 * INVALID_PIPE may occur during driver init because
+	 * connection_mutex isn't held across the entire backlight
+	 * setup + modeset readout, and the BIOS can issue the
+	 * requests at any time.
+	 */
+	if (!panel->backlight.present || pipe == INVALID_PIPE)
+		return;
+
+	mutex_lock(&dev_priv->backlight_lock);
+
+	WARN_ON(panel->backlight.max == 0);
+
+	hw_level = clamp_user_to_hw(connector, user_level, user_max);
+	panel->backlight.level = hw_level;
+
+	if (panel->backlight.device)
+		panel->backlight.device->props.brightness =
+			scale_hw_to_user(connector,
+					 panel->backlight.level,
+					 panel->backlight.device->props.max_brightness);
+
+	if (panel->backlight.enabled)
+		intel_panel_actually_set_backlight(connector, hw_level);
+
+	mutex_unlock(&dev_priv->backlight_lock);
+}
+
+static void lpt_disable_backlight(struct intel_connector *connector)
+{
+	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+	u32 tmp;
+
+	intel_panel_actually_set_backlight(connector, 0);
+
+	/*
+	 * Although we don't support or enable CPU PWM with LPT/SPT based
+	 * systems, it may have been enabled prior to loading the
+	 * driver. Disable to avoid warnings on LCPLL disable.
+	 *
+	 * This needs rework if we need to add support for CPU PWM on PCH split
+	 * platforms.
+	 */
+	tmp = I915_READ(BLC_PWM_CPU_CTL2);
+	if (tmp & BLM_PWM_ENABLE) {
+		DRM_DEBUG_KMS("cpu backlight was enabled, disabling\n");
+		I915_WRITE(BLC_PWM_CPU_CTL2, tmp & ~BLM_PWM_ENABLE);
+	}
+
+	tmp = I915_READ(BLC_PWM_PCH_CTL1);
+	I915_WRITE(BLC_PWM_PCH_CTL1, tmp & ~BLM_PCH_PWM_ENABLE);
+}
+
+static void pch_disable_backlight(struct intel_connector *connector)
+{
+	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+	u32 tmp;
+
+	intel_panel_actually_set_backlight(connector, 0);
+
+	tmp = I915_READ(BLC_PWM_CPU_CTL2);
+	I915_WRITE(BLC_PWM_CPU_CTL2, tmp & ~BLM_PWM_ENABLE);
+
+	tmp = I915_READ(BLC_PWM_PCH_CTL1);
+	I915_WRITE(BLC_PWM_PCH_CTL1, tmp & ~BLM_PCH_PWM_ENABLE);
+}
+
+static void i9xx_disable_backlight(struct intel_connector *connector)
+{
+	intel_panel_actually_set_backlight(connector, 0);
+}
+
+static void i965_disable_backlight(struct intel_connector *connector)
+{
+	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+	u32 tmp;
+
+	intel_panel_actually_set_backlight(connector, 0);
+
+	tmp = I915_READ(BLC_PWM_CTL2);
+	I915_WRITE(BLC_PWM_CTL2, tmp & ~BLM_PWM_ENABLE);
+}
+
+static void vlv_disable_backlight(struct intel_connector *connector)
+{
+	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+	enum pipe pipe = intel_get_pipe_from_connector(connector);
+	u32 tmp;
+
+	if (WARN_ON(pipe != PIPE_A && pipe != PIPE_B))
+		return;
+
+	intel_panel_actually_set_backlight(connector, 0);
+
+	tmp = I915_READ(VLV_BLC_PWM_CTL2(pipe));
+	I915_WRITE(VLV_BLC_PWM_CTL2(pipe), tmp & ~BLM_PWM_ENABLE);
+}
+
+static void bxt_disable_backlight(struct intel_connector *connector)
+{
+	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+	struct intel_panel *panel = &connector->panel;
+	u32 tmp, val;
+
+	intel_panel_actually_set_backlight(connector, 0);
+
+	tmp = I915_READ(BXT_BLC_PWM_CTL(panel->backlight.controller));
+	I915_WRITE(BXT_BLC_PWM_CTL(panel->backlight.controller),
+			tmp & ~BXT_BLC_PWM_ENABLE);
+
+	if (panel->backlight.controller == 1) {
+		val = I915_READ(UTIL_PIN_CTL);
+		val &= ~UTIL_PIN_ENABLE;
+		I915_WRITE(UTIL_PIN_CTL, val);
+	}
+}
+
+static void pwm_disable_backlight(struct intel_connector *connector)
+{
+	struct intel_panel *panel = &connector->panel;
+
+	/* Disable the backlight */
+	pwm_config(panel->backlight.pwm, 0, CRC_PMIC_PWM_PERIOD_NS);
+	usleep_range(2000, 3000);
+	pwm_disable(panel->backlight.pwm);
+}
+
+void intel_panel_disable_backlight(struct intel_connector *connector)
+{
+	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+	struct intel_panel *panel = &connector->panel;
+
+	if (!panel->backlight.present)
+		return;
+
+	/*
+	 * Do not disable backlight on the vga_switcheroo path. When switching
+	 * away from i915, the other client may depend on i915 to handle the
+	 * backlight. This will leave the backlight on unnecessarily when
+	 * another client is not activated.
+	 */
+	if (dev_priv->dev->switch_power_state == DRM_SWITCH_POWER_CHANGING) {
+		DRM_DEBUG_DRIVER("Skipping backlight disable on vga switch\n");
+		return;
+	}
+
+	mutex_lock(&dev_priv->backlight_lock);
+
+	if (panel->backlight.device)
+		panel->backlight.device->props.power = FB_BLANK_POWERDOWN;
+	panel->backlight.enabled = false;
+	panel->backlight.disable(connector);
+
+	mutex_unlock(&dev_priv->backlight_lock);
+}
+
+static void lpt_enable_backlight(struct intel_connector *connector)
+{
+	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+	struct intel_panel *panel = &connector->panel;
+	u32 pch_ctl1, pch_ctl2, schicken;
+
+	pch_ctl1 = I915_READ(BLC_PWM_PCH_CTL1);
+	if (pch_ctl1 & BLM_PCH_PWM_ENABLE) {
+		DRM_DEBUG_KMS("pch backlight already enabled\n");
+		pch_ctl1 &= ~BLM_PCH_PWM_ENABLE;
+		I915_WRITE(BLC_PWM_PCH_CTL1, pch_ctl1);
+	}
+
+	if (HAS_PCH_LPT(dev_priv)) {
+		schicken = I915_READ(SOUTH_CHICKEN2);
+		if (panel->backlight.alternate_pwm_increment)
+			schicken |= LPT_PWM_GRANULARITY;
+		else
+			schicken &= ~LPT_PWM_GRANULARITY;
+		I915_WRITE(SOUTH_CHICKEN2, schicken);
+	} else {
+		schicken = I915_READ(SOUTH_CHICKEN1);
+		if (panel->backlight.alternate_pwm_increment)
+			schicken |= SPT_PWM_GRANULARITY;
+		else
+			schicken &= ~SPT_PWM_GRANULARITY;
+		I915_WRITE(SOUTH_CHICKEN1, schicken);
+	}
+
+	pch_ctl2 = panel->backlight.max << 16;
+	I915_WRITE(BLC_PWM_PCH_CTL2, pch_ctl2);
+
+	pch_ctl1 = 0;
+	if (panel->backlight.active_low_pwm)
+		pch_ctl1 |= BLM_PCH_POLARITY;
+
+	/* After LPT, override is the default. */
+	if (HAS_PCH_LPT(dev_priv))
+		pch_ctl1 |= BLM_PCH_OVERRIDE_ENABLE;
+
+	I915_WRITE(BLC_PWM_PCH_CTL1, pch_ctl1);
+	POSTING_READ(BLC_PWM_PCH_CTL1);
+	I915_WRITE(BLC_PWM_PCH_CTL1, pch_ctl1 | BLM_PCH_PWM_ENABLE);
+
+	/* This won't stick until the above enable. */
+	intel_panel_actually_set_backlight(connector, panel->backlight.level);
+}
+
+static void pch_enable_backlight(struct intel_connector *connector)
+{
+	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+	struct intel_panel *panel = &connector->panel;
+	enum pipe pipe = intel_get_pipe_from_connector(connector);
+	enum transcoder cpu_transcoder =
+		intel_pipe_to_cpu_transcoder(dev_priv, pipe);
+	u32 cpu_ctl2, pch_ctl1, pch_ctl2;
+
+	cpu_ctl2 = I915_READ(BLC_PWM_CPU_CTL2);
+	if (cpu_ctl2 & BLM_PWM_ENABLE) {
+		DRM_DEBUG_KMS("cpu backlight already enabled\n");
+		cpu_ctl2 &= ~BLM_PWM_ENABLE;
+		I915_WRITE(BLC_PWM_CPU_CTL2, cpu_ctl2);
+	}
+
+	pch_ctl1 = I915_READ(BLC_PWM_PCH_CTL1);
+	if (pch_ctl1 & BLM_PCH_PWM_ENABLE) {
+		DRM_DEBUG_KMS("pch backlight already enabled\n");
+		pch_ctl1 &= ~BLM_PCH_PWM_ENABLE;
+		I915_WRITE(BLC_PWM_PCH_CTL1, pch_ctl1);
+	}
+
+	if (cpu_transcoder == TRANSCODER_EDP)
+		cpu_ctl2 = BLM_TRANSCODER_EDP;
+	else
+		cpu_ctl2 = BLM_PIPE(cpu_transcoder);
+	I915_WRITE(BLC_PWM_CPU_CTL2, cpu_ctl2);
+	POSTING_READ(BLC_PWM_CPU_CTL2);
+	I915_WRITE(BLC_PWM_CPU_CTL2, cpu_ctl2 | BLM_PWM_ENABLE);
+
+	/* This won't stick until the above enable. */
+	intel_panel_actually_set_backlight(connector, panel->backlight.level);
+
+	pch_ctl2 = panel->backlight.max << 16;
+	I915_WRITE(BLC_PWM_PCH_CTL2, pch_ctl2);
+
+	pch_ctl1 = 0;
+	if (panel->backlight.active_low_pwm)
+		pch_ctl1 |= BLM_PCH_POLARITY;
+
+	I915_WRITE(BLC_PWM_PCH_CTL1, pch_ctl1);
+	POSTING_READ(BLC_PWM_PCH_CTL1);
+	I915_WRITE(BLC_PWM_PCH_CTL1, pch_ctl1 | BLM_PCH_PWM_ENABLE);
+}
+
+static void i9xx_enable_backlight(struct intel_connector *connector)
+{
+	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+	struct intel_panel *panel = &connector->panel;
+	u32 ctl, freq;
+
+	ctl = I915_READ(BLC_PWM_CTL);
+	if (ctl & BACKLIGHT_DUTY_CYCLE_MASK_PNV) {
+		DRM_DEBUG_KMS("backlight already enabled\n");
+		I915_WRITE(BLC_PWM_CTL, 0);
+	}
+
+	freq = panel->backlight.max;
+	if (panel->backlight.combination_mode)
+		freq /= 0xff;
+
+	ctl = freq << 17;
+	if (panel->backlight.combination_mode)
+		ctl |= BLM_LEGACY_MODE;
+	if (IS_PINEVIEW(dev_priv) && panel->backlight.active_low_pwm)
+		ctl |= BLM_POLARITY_PNV;
+
+	I915_WRITE(BLC_PWM_CTL, ctl);
+	POSTING_READ(BLC_PWM_CTL);
+
+	/* XXX: combine this into above write? */
+	intel_panel_actually_set_backlight(connector, panel->backlight.level);
+
+	/*
+	 * Needed to enable backlight on some 855gm models. BLC_HIST_CTL is
+	 * 855gm only, but checking for gen2 is safe, as 855gm is the only gen2
+	 * that has backlight.
+	 */
+	if (IS_GEN2(dev_priv))
+		I915_WRITE(BLC_HIST_CTL, BLM_HISTOGRAM_ENABLE);
+}
+
+static void i965_enable_backlight(struct intel_connector *connector)
+{
+	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+	struct intel_panel *panel = &connector->panel;
+	enum pipe pipe = intel_get_pipe_from_connector(connector);
+	u32 ctl, ctl2, freq;
+
+	ctl2 = I915_READ(BLC_PWM_CTL2);
+	if (ctl2 & BLM_PWM_ENABLE) {
+		DRM_DEBUG_KMS("backlight already enabled\n");
+		ctl2 &= ~BLM_PWM_ENABLE;
+		I915_WRITE(BLC_PWM_CTL2, ctl2);
+	}
+
+	freq = panel->backlight.max;
+	if (panel->backlight.combination_mode)
+		freq /= 0xff;
+
+	ctl = freq << 16;
+	I915_WRITE(BLC_PWM_CTL, ctl);
+
+	ctl2 = BLM_PIPE(pipe);
+	if (panel->backlight.combination_mode)
+		ctl2 |= BLM_COMBINATION_MODE;
+	if (panel->backlight.active_low_pwm)
+		ctl2 |= BLM_POLARITY_I965;
+	I915_WRITE(BLC_PWM_CTL2, ctl2);
+	POSTING_READ(BLC_PWM_CTL2);
+	I915_WRITE(BLC_PWM_CTL2, ctl2 | BLM_PWM_ENABLE);
+
+	intel_panel_actually_set_backlight(connector, panel->backlight.level);
+}
+
+static void vlv_enable_backlight(struct intel_connector *connector)
+{
+	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+	struct intel_panel *panel = &connector->panel;
+	enum pipe pipe = intel_get_pipe_from_connector(connector);
+	u32 ctl, ctl2;
+
+	if (WARN_ON(pipe != PIPE_A && pipe != PIPE_B))
+		return;
+
+	ctl2 = I915_READ(VLV_BLC_PWM_CTL2(pipe));
+	if (ctl2 & BLM_PWM_ENABLE) {
+		DRM_DEBUG_KMS("backlight already enabled\n");
+		ctl2 &= ~BLM_PWM_ENABLE;
+		I915_WRITE(VLV_BLC_PWM_CTL2(pipe), ctl2);
+	}
+
+	ctl = panel->backlight.max << 16;
+	I915_WRITE(VLV_BLC_PWM_CTL(pipe), ctl);
+
+	/* XXX: combine this into above write? */
+	intel_panel_actually_set_backlight(connector, panel->backlight.level);
+
+	ctl2 = 0;
+	if (panel->backlight.active_low_pwm)
+		ctl2 |= BLM_POLARITY_I965;
+	I915_WRITE(VLV_BLC_PWM_CTL2(pipe), ctl2);
+	POSTING_READ(VLV_BLC_PWM_CTL2(pipe));
+	I915_WRITE(VLV_BLC_PWM_CTL2(pipe), ctl2 | BLM_PWM_ENABLE);
+}
+
+static void bxt_enable_backlight(struct intel_connector *connector)
+{
+	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+	struct intel_panel *panel = &connector->panel;
+	enum pipe pipe = intel_get_pipe_from_connector(connector);
+	u32 pwm_ctl, val;
+
+	/* To use 2nd set of backlight registers, utility pin has to be
+	 * enabled with PWM mode.
+	 * The field should only be changed when the utility pin is disabled
+	 */
+	if (panel->backlight.controller == 1) {
+		val = I915_READ(UTIL_PIN_CTL);
+		if (val & UTIL_PIN_ENABLE) {
+			DRM_DEBUG_KMS("util pin already enabled\n");
+			val &= ~UTIL_PIN_ENABLE;
+			I915_WRITE(UTIL_PIN_CTL, val);
+		}
+
+		val = 0;
+		if (panel->backlight.util_pin_active_low)
+			val |= UTIL_PIN_POLARITY;
+		I915_WRITE(UTIL_PIN_CTL, val | UTIL_PIN_PIPE(pipe) |
+				UTIL_PIN_MODE_PWM | UTIL_PIN_ENABLE);
+	}
+
+	pwm_ctl = I915_READ(BXT_BLC_PWM_CTL(panel->backlight.controller));
+	if (pwm_ctl & BXT_BLC_PWM_ENABLE) {
+		DRM_DEBUG_KMS("backlight already enabled\n");
+		pwm_ctl &= ~BXT_BLC_PWM_ENABLE;
+		I915_WRITE(BXT_BLC_PWM_CTL(panel->backlight.controller),
+				pwm_ctl);
+	}
+
+	I915_WRITE(BXT_BLC_PWM_FREQ(panel->backlight.controller),
+			panel->backlight.max);
+
+	intel_panel_actually_set_backlight(connector, panel->backlight.level);
+
+	pwm_ctl = 0;
+	if (panel->backlight.active_low_pwm)
+		pwm_ctl |= BXT_BLC_PWM_POLARITY;
+
+	I915_WRITE(BXT_BLC_PWM_CTL(panel->backlight.controller), pwm_ctl);
+	POSTING_READ(BXT_BLC_PWM_CTL(panel->backlight.controller));
+	I915_WRITE(BXT_BLC_PWM_CTL(panel->backlight.controller),
+			pwm_ctl | BXT_BLC_PWM_ENABLE);
+}
+
+static void pwm_enable_backlight(struct intel_connector *connector)
+{
+	struct intel_panel *panel = &connector->panel;
+
+	pwm_enable(panel->backlight.pwm);
+	intel_panel_actually_set_backlight(connector, panel->backlight.level);
+}
+
+void intel_panel_enable_backlight(struct intel_connector *connector)
+{
+	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+	struct intel_panel *panel = &connector->panel;
+	enum pipe pipe = intel_get_pipe_from_connector(connector);
+
+	if (!panel->backlight.present)
+		return;
+
+	DRM_DEBUG_KMS("pipe %c\n", pipe_name(pipe));
+
+	mutex_lock(&dev_priv->backlight_lock);
+
+	WARN_ON(panel->backlight.max == 0);
+
+	if (panel->backlight.level <= panel->backlight.min) {
+		panel->backlight.level = panel->backlight.max;
+		if (panel->backlight.device)
+			panel->backlight.device->props.brightness =
+				scale_hw_to_user(connector,
+						 panel->backlight.level,
+						 panel->backlight.device->props.max_brightness);
+	}
+
+	panel->backlight.enable(connector);
+	panel->backlight.enabled = true;
+	if (panel->backlight.device)
+		panel->backlight.device->props.power = FB_BLANK_UNBLANK;
+
+	mutex_unlock(&dev_priv->backlight_lock);
+}
+
+#if IS_ENABLED(CONFIG_BACKLIGHT_CLASS_DEVICE)
+static int intel_backlight_device_update_status(struct backlight_device *bd)
+{
+	struct intel_connector *connector = bl_get_data(bd);
+	struct intel_panel *panel = &connector->panel;
+	struct drm_device *dev = connector->base.dev;
+
+	drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);
+	DRM_DEBUG_KMS("updating intel_backlight, brightness=%d/%d\n",
+		      bd->props.brightness, bd->props.max_brightness);
+	intel_panel_set_backlight(connector, bd->props.brightness,
+				  bd->props.max_brightness);
+
+	/*
+	 * Allow flipping bl_power as a sub-state of enabled. Sadly the
+	 * backlight class device does not make it easy to to differentiate
+	 * between callbacks for brightness and bl_power, so our backlight_power
+	 * callback needs to take this into account.
+	 */
+	if (panel->backlight.enabled) {
+		if (panel->backlight.power) {
+			bool enable = bd->props.power == FB_BLANK_UNBLANK &&
+				bd->props.brightness != 0;
+			panel->backlight.power(connector, enable);
+		}
+	} else {
+		bd->props.power = FB_BLANK_POWERDOWN;
+	}
+
+	drm_modeset_unlock(&dev->mode_config.connection_mutex);
+	return 0;
+}
+
+static int intel_backlight_device_get_brightness(struct backlight_device *bd)
+{
+	struct intel_connector *connector = bl_get_data(bd);
+	struct drm_device *dev = connector->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	u32 hw_level;
+	int ret;
+
+	intel_runtime_pm_get(dev_priv);
+	drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);
+
+	hw_level = intel_panel_get_backlight(connector);
+	ret = scale_hw_to_user(connector, hw_level, bd->props.max_brightness);
+
+	drm_modeset_unlock(&dev->mode_config.connection_mutex);
+	intel_runtime_pm_put(dev_priv);
+
+	return ret;
+}
+
+static const struct backlight_ops intel_backlight_device_ops = {
+	.update_status = intel_backlight_device_update_status,
+	.get_brightness = intel_backlight_device_get_brightness,
+};
+
+static int intel_backlight_device_register(struct intel_connector *connector)
+{
+	struct intel_panel *panel = &connector->panel;
+	struct backlight_properties props;
+
+	if (WARN_ON(panel->backlight.device))
+		return -ENODEV;
+
+	if (!panel->backlight.present)
+		return 0;
+
+	WARN_ON(panel->backlight.max == 0);
+
+	memset(&props, 0, sizeof(props));
+	props.type = BACKLIGHT_RAW;
+
+	/*
+	 * Note: Everything should work even if the backlight device max
+	 * presented to the userspace is arbitrarily chosen.
+	 */
+	props.max_brightness = panel->backlight.max;
+	props.brightness = scale_hw_to_user(connector,
+					    panel->backlight.level,
+					    props.max_brightness);
+
+	if (panel->backlight.enabled)
+		props.power = FB_BLANK_UNBLANK;
+	else
+		props.power = FB_BLANK_POWERDOWN;
+
+	/*
+	 * Note: using the same name independent of the connector prevents
+	 * registration of multiple backlight devices in the driver.
+	 */
+	panel->backlight.device =
+		backlight_device_register("intel_backlight",
+					  connector->base.kdev,
+					  connector,
+					  &intel_backlight_device_ops, &props);
+
+	if (IS_ERR(panel->backlight.device)) {
+		DRM_ERROR("Failed to register backlight: %ld\n",
+			  PTR_ERR(panel->backlight.device));
+		panel->backlight.device = NULL;
+		return -ENODEV;
+	}
+
+	DRM_DEBUG_KMS("Connector %s backlight sysfs interface registered\n",
+		      connector->base.name);
+
+	return 0;
+}
+
+static void intel_backlight_device_unregister(struct intel_connector *connector)
+{
+	struct intel_panel *panel = &connector->panel;
+
+	if (panel->backlight.device) {
+		backlight_device_unregister(panel->backlight.device);
+		panel->backlight.device = NULL;
+	}
+}
+#else /* CONFIG_BACKLIGHT_CLASS_DEVICE */
+static int intel_backlight_device_register(struct intel_connector *connector)
+{
+	return 0;
+}
+static void intel_backlight_device_unregister(struct intel_connector *connector)
+{
+}
+#endif /* CONFIG_BACKLIGHT_CLASS_DEVICE */
+
+/*
+ * BXT: PWM clock frequency = 19.2 MHz.
+ */
+static u32 bxt_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz)
+{
+	return DIV_ROUND_CLOSEST(KHz(19200), pwm_freq_hz);
+}
+
+/*
+ * SPT: This value represents the period of the PWM stream in clock periods
+ * multiplied by 16 (default increment) or 128 (alternate increment selected in
+ * SCHICKEN_1 bit 0). PWM clock is 24 MHz.
+ */
+static u32 spt_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz)
+{
+	struct intel_panel *panel = &connector->panel;
+	u32 mul;
+
+	if (panel->backlight.alternate_pwm_increment)
+		mul = 128;
+	else
+		mul = 16;
+
+	return DIV_ROUND_CLOSEST(MHz(24), pwm_freq_hz * mul);
+}
+
+/*
+ * LPT: This value represents the period of the PWM stream in clock periods
+ * multiplied by 128 (default increment) or 16 (alternate increment, selected in
+ * LPT SOUTH_CHICKEN2 register bit 5).
+ */
+static u32 lpt_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz)
+{
+	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+	struct intel_panel *panel = &connector->panel;
+	u32 mul, clock;
+
+	if (panel->backlight.alternate_pwm_increment)
+		mul = 16;
+	else
+		mul = 128;
+
+	if (HAS_PCH_LPT_H(dev_priv))
+		clock = MHz(135); /* LPT:H */
+	else
+		clock = MHz(24); /* LPT:LP */
+
+	return DIV_ROUND_CLOSEST(clock, pwm_freq_hz * mul);
+}
+
+/*
+ * ILK/SNB/IVB: This value represents the period of the PWM stream in PCH
+ * display raw clocks multiplied by 128.
+ */
+static u32 pch_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz)
+{
+	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+
+	return DIV_ROUND_CLOSEST(KHz(dev_priv->rawclk_freq), pwm_freq_hz * 128);
+}
+
+/*
+ * Gen2: This field determines the number of time base events (display core
+ * clock frequency/32) in total for a complete cycle of modulated backlight
+ * control.
+ *
+ * Gen3: A time base event equals the display core clock ([DevPNV] HRAW clock)
+ * divided by 32.
+ */
+static u32 i9xx_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz)
+{
+	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+	int clock;
+
+	if (IS_PINEVIEW(dev_priv))
+		clock = KHz(dev_priv->rawclk_freq);
+	else
+		clock = KHz(dev_priv->cdclk_freq);
+
+	return DIV_ROUND_CLOSEST(clock, pwm_freq_hz * 32);
+}
+
+/*
+ * Gen4: This value represents the period of the PWM stream in display core
+ * clocks ([DevCTG] HRAW clocks) multiplied by 128.
+ *
+ */
+static u32 i965_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz)
+{
+	struct drm_device *dev = connector->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	int clock;
+
+	if (IS_G4X(dev_priv))
+		clock = KHz(dev_priv->rawclk_freq);
+	else
+		clock = KHz(dev_priv->cdclk_freq);
+
+	return DIV_ROUND_CLOSEST(clock, pwm_freq_hz * 128);
+}
+
+/*
+ * VLV: This value represents the period of the PWM stream in display core
+ * clocks ([DevCTG] 200MHz HRAW clocks) multiplied by 128 or 25MHz S0IX clocks
+ * multiplied by 16. CHV uses a 19.2MHz S0IX clock.
+ */
+static u32 vlv_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz)
+{
+	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+	int mul, clock;
+
+	if ((I915_READ(CBR1_VLV) & CBR_PWM_CLOCK_MUX_SELECT) == 0) {
+		if (IS_CHERRYVIEW(dev_priv))
+			clock = KHz(19200);
+		else
+			clock = MHz(25);
+		mul = 16;
+	} else {
+		clock = KHz(dev_priv->rawclk_freq);
+		mul = 128;
+	}
+
+	return DIV_ROUND_CLOSEST(clock, pwm_freq_hz * mul);
+}
+
+static u32 get_backlight_max_vbt(struct intel_connector *connector)
+{
+	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+	struct intel_panel *panel = &connector->panel;
+	u16 pwm_freq_hz = dev_priv->vbt.backlight.pwm_freq_hz;
+	u32 pwm;
+
+	if (!panel->backlight.hz_to_pwm) {
+		DRM_DEBUG_KMS("backlight frequency conversion not supported\n");
+		return 0;
+	}
+
+	if (pwm_freq_hz) {
+		DRM_DEBUG_KMS("VBT defined backlight frequency %u Hz\n",
+			      pwm_freq_hz);
+	} else {
+		pwm_freq_hz = 200;
+		DRM_DEBUG_KMS("default backlight frequency %u Hz\n",
+			      pwm_freq_hz);
+	}
+
+	pwm = panel->backlight.hz_to_pwm(connector, pwm_freq_hz);
+	if (!pwm) {
+		DRM_DEBUG_KMS("backlight frequency conversion failed\n");
+		return 0;
+	}
+
+	return pwm;
+}
+
+/*
+ * Note: The setup hooks can't assume pipe is set!
+ */
+static u32 get_backlight_min_vbt(struct intel_connector *connector)
+{
+	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+	struct intel_panel *panel = &connector->panel;
+	int min;
+
+	WARN_ON(panel->backlight.max == 0);
+
+	/*
+	 * XXX: If the vbt value is 255, it makes min equal to max, which leads
+	 * to problems. There are such machines out there. Either our
+	 * interpretation is wrong or the vbt has bogus data. Or both. Safeguard
+	 * against this by letting the minimum be at most (arbitrarily chosen)
+	 * 25% of the max.
+	 */
+	min = clamp_t(int, dev_priv->vbt.backlight.min_brightness, 0, 64);
+	if (min != dev_priv->vbt.backlight.min_brightness) {
+		DRM_DEBUG_KMS("clamping VBT min backlight %d/255 to %d/255\n",
+			      dev_priv->vbt.backlight.min_brightness, min);
+	}
+
+	/* vbt value is a coefficient in range [0..255] */
+	return scale(min, 0, 255, 0, panel->backlight.max);
+}
+
+static int lpt_setup_backlight(struct intel_connector *connector, enum pipe unused)
+{
+	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+	struct intel_panel *panel = &connector->panel;
+	u32 pch_ctl1, pch_ctl2, val;
+	bool alt;
+
+	if (HAS_PCH_LPT(dev_priv))
+		alt = I915_READ(SOUTH_CHICKEN2) & LPT_PWM_GRANULARITY;
+	else
+		alt = I915_READ(SOUTH_CHICKEN1) & SPT_PWM_GRANULARITY;
+	panel->backlight.alternate_pwm_increment = alt;
+
+	pch_ctl1 = I915_READ(BLC_PWM_PCH_CTL1);
+	panel->backlight.active_low_pwm = pch_ctl1 & BLM_PCH_POLARITY;
+
+	pch_ctl2 = I915_READ(BLC_PWM_PCH_CTL2);
+	panel->backlight.max = pch_ctl2 >> 16;
+
+	if (!panel->backlight.max)
+		panel->backlight.max = get_backlight_max_vbt(connector);
+
+	if (!panel->backlight.max)
+		return -ENODEV;
+
+	panel->backlight.min = get_backlight_min_vbt(connector);
+
+	val = lpt_get_backlight(connector);
+	panel->backlight.level = intel_panel_compute_brightness(connector, val);
+
+	panel->backlight.enabled = (pch_ctl1 & BLM_PCH_PWM_ENABLE) &&
+		panel->backlight.level != 0;
+
+	return 0;
+}
+
+static int pch_setup_backlight(struct intel_connector *connector, enum pipe unused)
+{
+	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+	struct intel_panel *panel = &connector->panel;
+	u32 cpu_ctl2, pch_ctl1, pch_ctl2, val;
+
+	pch_ctl1 = I915_READ(BLC_PWM_PCH_CTL1);
+	panel->backlight.active_low_pwm = pch_ctl1 & BLM_PCH_POLARITY;
+
+	pch_ctl2 = I915_READ(BLC_PWM_PCH_CTL2);
+	panel->backlight.max = pch_ctl2 >> 16;
+
+	if (!panel->backlight.max)
+		panel->backlight.max = get_backlight_max_vbt(connector);
+
+	if (!panel->backlight.max)
+		return -ENODEV;
+
+	panel->backlight.min = get_backlight_min_vbt(connector);
+
+	val = pch_get_backlight(connector);
+	panel->backlight.level = intel_panel_compute_brightness(connector, val);
+
+	cpu_ctl2 = I915_READ(BLC_PWM_CPU_CTL2);
+	panel->backlight.enabled = (cpu_ctl2 & BLM_PWM_ENABLE) &&
+		(pch_ctl1 & BLM_PCH_PWM_ENABLE) && panel->backlight.level != 0;
+
+	return 0;
+}
+
+static int i9xx_setup_backlight(struct intel_connector *connector, enum pipe unused)
+{
+	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+	struct intel_panel *panel = &connector->panel;
+	u32 ctl, val;
+
+	ctl = I915_READ(BLC_PWM_CTL);
+
+	if (IS_GEN2(dev_priv) || IS_I915GM(dev_priv) || IS_I945GM(dev_priv))
+		panel->backlight.combination_mode = ctl & BLM_LEGACY_MODE;
+
+	if (IS_PINEVIEW(dev_priv))
+		panel->backlight.active_low_pwm = ctl & BLM_POLARITY_PNV;
+
+	panel->backlight.max = ctl >> 17;
+
+	if (!panel->backlight.max) {
+		panel->backlight.max = get_backlight_max_vbt(connector);
+		panel->backlight.max >>= 1;
+	}
+
+	if (!panel->backlight.max)
+		return -ENODEV;
+
+	if (panel->backlight.combination_mode)
+		panel->backlight.max *= 0xff;
+
+	panel->backlight.min = get_backlight_min_vbt(connector);
+
+	val = i9xx_get_backlight(connector);
+	panel->backlight.level = intel_panel_compute_brightness(connector, val);
+
+	panel->backlight.enabled = panel->backlight.level != 0;
+
+	return 0;
+}
+
+static int i965_setup_backlight(struct intel_connector *connector, enum pipe unused)
+{
+	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+	struct intel_panel *panel = &connector->panel;
+	u32 ctl, ctl2, val;
+
+	ctl2 = I915_READ(BLC_PWM_CTL2);
+	panel->backlight.combination_mode = ctl2 & BLM_COMBINATION_MODE;
+	panel->backlight.active_low_pwm = ctl2 & BLM_POLARITY_I965;
+
+	ctl = I915_READ(BLC_PWM_CTL);
+	panel->backlight.max = ctl >> 16;
+
+	if (!panel->backlight.max)
+		panel->backlight.max = get_backlight_max_vbt(connector);
+
+	if (!panel->backlight.max)
+		return -ENODEV;
+
+	if (panel->backlight.combination_mode)
+		panel->backlight.max *= 0xff;
+
+	panel->backlight.min = get_backlight_min_vbt(connector);
+
+	val = i9xx_get_backlight(connector);
+	panel->backlight.level = intel_panel_compute_brightness(connector, val);
+
+	panel->backlight.enabled = (ctl2 & BLM_PWM_ENABLE) &&
+		panel->backlight.level != 0;
+
+	return 0;
+}
+
+static int vlv_setup_backlight(struct intel_connector *connector, enum pipe pipe)
+{
+	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+	struct intel_panel *panel = &connector->panel;
+	u32 ctl, ctl2, val;
+
+	if (WARN_ON(pipe != PIPE_A && pipe != PIPE_B))
+		return -ENODEV;
+
+	ctl2 = I915_READ(VLV_BLC_PWM_CTL2(pipe));
+	panel->backlight.active_low_pwm = ctl2 & BLM_POLARITY_I965;
+
+	ctl = I915_READ(VLV_BLC_PWM_CTL(pipe));
+	panel->backlight.max = ctl >> 16;
+
+	if (!panel->backlight.max)
+		panel->backlight.max = get_backlight_max_vbt(connector);
+
+	if (!panel->backlight.max)
+		return -ENODEV;
+
+	panel->backlight.min = get_backlight_min_vbt(connector);
+
+	val = _vlv_get_backlight(dev_priv, pipe);
+	panel->backlight.level = intel_panel_compute_brightness(connector, val);
+
+	panel->backlight.enabled = (ctl2 & BLM_PWM_ENABLE) &&
+		panel->backlight.level != 0;
+
+	return 0;
+}
+
+static int
+bxt_setup_backlight(struct intel_connector *connector, enum pipe unused)
+{
+	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+	struct intel_panel *panel = &connector->panel;
+	u32 pwm_ctl, val;
+
+	/*
+	 * For BXT hard coding the Backlight controller to 0.
+	 * TODO : Read the controller value from VBT and generalize
+	 */
+	panel->backlight.controller = 0;
+
+	pwm_ctl = I915_READ(BXT_BLC_PWM_CTL(panel->backlight.controller));
+
+	/* Keeping the check if controller 1 is to be programmed.
+	 * This will come into affect once the VBT parsing
+	 * is fixed for controller selection, and controller 1 is used
+	 * for a prticular display configuration.
+	 */
+	if (panel->backlight.controller == 1) {
+		val = I915_READ(UTIL_PIN_CTL);
+		panel->backlight.util_pin_active_low =
+					val & UTIL_PIN_POLARITY;
+	}
+
+	panel->backlight.active_low_pwm = pwm_ctl & BXT_BLC_PWM_POLARITY;
+	panel->backlight.max =
+		I915_READ(BXT_BLC_PWM_FREQ(panel->backlight.controller));
+
+	if (!panel->backlight.max)
+		panel->backlight.max = get_backlight_max_vbt(connector);
+
+	if (!panel->backlight.max)
+		return -ENODEV;
+
+	val = bxt_get_backlight(connector);
+	panel->backlight.level = intel_panel_compute_brightness(connector, val);
+
+	panel->backlight.enabled = (pwm_ctl & BXT_BLC_PWM_ENABLE) &&
+		panel->backlight.level != 0;
+
+	return 0;
+}
+
+static int pwm_setup_backlight(struct intel_connector *connector,
+			       enum pipe pipe)
+{
+	struct drm_device *dev = connector->base.dev;
+	struct intel_panel *panel = &connector->panel;
+	int retval;
+
+	/* Get the PWM chip for backlight control */
+	panel->backlight.pwm = pwm_get(dev->dev, "pwm_backlight");
+	if (IS_ERR(panel->backlight.pwm)) {
+		DRM_ERROR("Failed to own the pwm chip\n");
+		panel->backlight.pwm = NULL;
+		return -ENODEV;
+	}
+
+	retval = pwm_config(panel->backlight.pwm, CRC_PMIC_PWM_PERIOD_NS,
+			    CRC_PMIC_PWM_PERIOD_NS);
+	if (retval < 0) {
+		DRM_ERROR("Failed to configure the pwm chip\n");
+		pwm_put(panel->backlight.pwm);
+		panel->backlight.pwm = NULL;
+		return retval;
+	}
+
+	panel->backlight.min = 0; /* 0% */
+	panel->backlight.max = 100; /* 100% */
+	panel->backlight.level = DIV_ROUND_UP(
+				 pwm_get_duty_cycle(panel->backlight.pwm) * 100,
+				 CRC_PMIC_PWM_PERIOD_NS);
+	panel->backlight.enabled = panel->backlight.level != 0;
+
+	return 0;
+}
+
+int intel_panel_setup_backlight(struct drm_connector *connector, enum pipe pipe)
+{
+	struct drm_i915_private *dev_priv = to_i915(connector->dev);
+	struct intel_connector *intel_connector = to_intel_connector(connector);
+	struct intel_panel *panel = &intel_connector->panel;
+	int ret;
+
+	if (!dev_priv->vbt.backlight.present) {
+		if (dev_priv->quirks & QUIRK_BACKLIGHT_PRESENT) {
+			DRM_DEBUG_KMS("no backlight present per VBT, but present per quirk\n");
+		} else {
+			DRM_DEBUG_KMS("no backlight present per VBT\n");
+			return 0;
+		}
+	}
+
+	/* ensure intel_panel has been initialized first */
+	if (WARN_ON(!panel->backlight.setup))
+		return -ENODEV;
+
+	/* set level and max in panel struct */
+	mutex_lock(&dev_priv->backlight_lock);
+	ret = panel->backlight.setup(intel_connector, pipe);
+	mutex_unlock(&dev_priv->backlight_lock);
+
+	if (ret) {
+		DRM_DEBUG_KMS("failed to setup backlight for connector %s\n",
+			      connector->name);
+		return ret;
+	}
+
+	panel->backlight.present = true;
+
+	DRM_DEBUG_KMS("Connector %s backlight initialized, %s, brightness %u/%u\n",
+		      connector->name,
+		      panel->backlight.enabled ? "enabled" : "disabled",
+		      panel->backlight.level, panel->backlight.max);
+
+	return 0;
+}
+
+void intel_panel_destroy_backlight(struct drm_connector *connector)
+{
+	struct intel_connector *intel_connector = to_intel_connector(connector);
+	struct intel_panel *panel = &intel_connector->panel;
+
+	/* dispose of the pwm */
+	if (panel->backlight.pwm)
+		pwm_put(panel->backlight.pwm);
+
+	panel->backlight.present = false;
+}
+
+/* Set up chip specific backlight functions */
+static void
+intel_panel_init_backlight_funcs(struct intel_panel *panel)
+{
+	struct intel_connector *connector =
+		container_of(panel, struct intel_connector, panel);
+	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+
+	if (IS_BROXTON(dev_priv)) {
+		panel->backlight.setup = bxt_setup_backlight;
+		panel->backlight.enable = bxt_enable_backlight;
+		panel->backlight.disable = bxt_disable_backlight;
+		panel->backlight.set = bxt_set_backlight;
+		panel->backlight.get = bxt_get_backlight;
+		panel->backlight.hz_to_pwm = bxt_hz_to_pwm;
+	} else if (HAS_PCH_LPT(dev_priv) || HAS_PCH_SPT(dev_priv) ||
+		   HAS_PCH_KBP(dev_priv)) {
+		panel->backlight.setup = lpt_setup_backlight;
+		panel->backlight.enable = lpt_enable_backlight;
+		panel->backlight.disable = lpt_disable_backlight;
+		panel->backlight.set = lpt_set_backlight;
+		panel->backlight.get = lpt_get_backlight;
+		if (HAS_PCH_LPT(dev_priv))
+			panel->backlight.hz_to_pwm = lpt_hz_to_pwm;
+		else
+			panel->backlight.hz_to_pwm = spt_hz_to_pwm;
+	} else if (HAS_PCH_SPLIT(dev_priv)) {
+		panel->backlight.setup = pch_setup_backlight;
+		panel->backlight.enable = pch_enable_backlight;
+		panel->backlight.disable = pch_disable_backlight;
+		panel->backlight.set = pch_set_backlight;
+		panel->backlight.get = pch_get_backlight;
+		panel->backlight.hz_to_pwm = pch_hz_to_pwm;
+	} else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
+		if (connector->base.connector_type == DRM_MODE_CONNECTOR_DSI) {
+			panel->backlight.setup = pwm_setup_backlight;
+			panel->backlight.enable = pwm_enable_backlight;
+			panel->backlight.disable = pwm_disable_backlight;
+			panel->backlight.set = pwm_set_backlight;
+			panel->backlight.get = pwm_get_backlight;
+		} else {
+			panel->backlight.setup = vlv_setup_backlight;
+			panel->backlight.enable = vlv_enable_backlight;
+			panel->backlight.disable = vlv_disable_backlight;
+			panel->backlight.set = vlv_set_backlight;
+			panel->backlight.get = vlv_get_backlight;
+			panel->backlight.hz_to_pwm = vlv_hz_to_pwm;
+		}
+	} else if (IS_GEN4(dev_priv)) {
+		panel->backlight.setup = i965_setup_backlight;
+		panel->backlight.enable = i965_enable_backlight;
+		panel->backlight.disable = i965_disable_backlight;
+		panel->backlight.set = i9xx_set_backlight;
+		panel->backlight.get = i9xx_get_backlight;
+		panel->backlight.hz_to_pwm = i965_hz_to_pwm;
+	} else {
+		panel->backlight.setup = i9xx_setup_backlight;
+		panel->backlight.enable = i9xx_enable_backlight;
+		panel->backlight.disable = i9xx_disable_backlight;
+		panel->backlight.set = i9xx_set_backlight;
+		panel->backlight.get = i9xx_get_backlight;
+		panel->backlight.hz_to_pwm = i9xx_hz_to_pwm;
+	}
+}
+
+int intel_panel_init(struct intel_panel *panel,
+		     struct drm_display_mode *fixed_mode,
+		     struct drm_display_mode *downclock_mode)
+{
+	intel_panel_init_backlight_funcs(panel);
+
+	panel->fixed_mode = fixed_mode;
+	panel->downclock_mode = downclock_mode;
+
+	return 0;
+}
+
+void intel_panel_fini(struct intel_panel *panel)
+{
+	struct intel_connector *intel_connector =
+		container_of(panel, struct intel_connector, panel);
+
+	if (panel->fixed_mode)
+		drm_mode_destroy(intel_connector->base.dev, panel->fixed_mode);
+
+	if (panel->downclock_mode)
+		drm_mode_destroy(intel_connector->base.dev,
+				panel->downclock_mode);
+}
+
+void intel_backlight_register(struct drm_device *dev)
+{
+	struct intel_connector *connector;
+
+	for_each_intel_connector(dev, connector)
+		intel_backlight_device_register(connector);
+}
+
+void intel_backlight_unregister(struct drm_device *dev)
+{
+	struct intel_connector *connector;
+
+	for_each_intel_connector(dev, connector)
+		intel_backlight_device_unregister(connector);
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/i915/intel_pm.c
@@ -0,0 +1,7498 @@
+/*
+ * Copyright © 2012 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Eugeni Dodonov <eugeni.dodonov@intel.com>
+ *
+ */
+
+#include <linux/cpufreq.h>
+#include "i915_drv.h"
+#include "intel_drv.h"
+#include "../../drivers/platform/x86/intel_ips.h"
+#include <linux/module.h>
+
+/**
+ * DOC: RC6
+ *
+ * RC6 is a special power stage which allows the GPU to enter an very
+ * low-voltage mode when idle, using down to 0V while at this stage.  This
+ * stage is entered automatically when the GPU is idle when RC6 support is
+ * enabled, and as soon as new workload arises GPU wakes up automatically as well.
+ *
+ * There are different RC6 modes available in Intel GPU, which differentiate
+ * among each other with the latency required to enter and leave RC6 and
+ * voltage consumed by the GPU in different states.
+ *
+ * The combination of the following flags define which states GPU is allowed
+ * to enter, while RC6 is the normal RC6 state, RC6p is the deep RC6, and
+ * RC6pp is deepest RC6. Their support by hardware varies according to the
+ * GPU, BIOS, chipset and platform. RC6 is usually the safest one and the one
+ * which brings the most power savings; deeper states save more power, but
+ * require higher latency to switch to and wake up.
+ */
+#define INTEL_RC6_ENABLE			(1<<0)
+#define INTEL_RC6p_ENABLE			(1<<1)
+#define INTEL_RC6pp_ENABLE			(1<<2)
+
+static void gen9_init_clock_gating(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	/* See Bspec note for PSR2_CTL bit 31, Wa#828:skl,bxt,kbl */
+	I915_WRITE(CHICKEN_PAR1_1,
+		   I915_READ(CHICKEN_PAR1_1) | SKL_EDP_PSR_FIX_RDWRAP);
+
+	I915_WRITE(GEN8_CONFIG0,
+		   I915_READ(GEN8_CONFIG0) | GEN9_DEFAULT_FIXES);
+
+	/* WaEnableChickenDCPR:skl,bxt,kbl */
+	I915_WRITE(GEN8_CHICKEN_DCPR_1,
+		   I915_READ(GEN8_CHICKEN_DCPR_1) | MASK_WAKEMEM);
+
+	/* WaFbcTurnOffFbcWatermark:skl,bxt,kbl */
+	/* WaFbcWakeMemOn:skl,bxt,kbl */
+	I915_WRITE(DISP_ARB_CTL, I915_READ(DISP_ARB_CTL) |
+		   DISP_FBC_WM_DIS |
+		   DISP_FBC_MEMORY_WAKE);
+
+	/* WaFbcHighMemBwCorruptionAvoidance:skl,bxt,kbl */
+	I915_WRITE(ILK_DPFC_CHICKEN, I915_READ(ILK_DPFC_CHICKEN) |
+		   ILK_DPFC_DISABLE_DUMMY0);
+}
+
+static void bxt_init_clock_gating(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	gen9_init_clock_gating(dev);
+
+	/* WaDisableSDEUnitClockGating:bxt */
+	I915_WRITE(GEN8_UCGCTL6, I915_READ(GEN8_UCGCTL6) |
+		   GEN8_SDEUNIT_CLOCK_GATE_DISABLE);
+
+	/*
+	 * FIXME:
+	 * GEN8_HDCUNIT_CLOCK_GATE_DISABLE_HDCREQ applies on 3x6 GT SKUs only.
+	 */
+	I915_WRITE(GEN8_UCGCTL6, I915_READ(GEN8_UCGCTL6) |
+		   GEN8_HDCUNIT_CLOCK_GATE_DISABLE_HDCREQ);
+
+	/*
+	 * Wa: Backlight PWM may stop in the asserted state, causing backlight
+	 * to stay fully on.
+	 */
+	if (IS_BXT_REVID(dev_priv, BXT_REVID_B0, REVID_FOREVER))
+		I915_WRITE(GEN9_CLKGATE_DIS_0, I915_READ(GEN9_CLKGATE_DIS_0) |
+			   PWM1_GATING_DIS | PWM2_GATING_DIS);
+}
+
+static void i915_pineview_get_mem_freq(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	u32 tmp;
+
+	tmp = I915_READ(CLKCFG);
+
+	switch (tmp & CLKCFG_FSB_MASK) {
+	case CLKCFG_FSB_533:
+		dev_priv->fsb_freq = 533; /* 133*4 */
+		break;
+	case CLKCFG_FSB_800:
+		dev_priv->fsb_freq = 800; /* 200*4 */
+		break;
+	case CLKCFG_FSB_667:
+		dev_priv->fsb_freq =  667; /* 167*4 */
+		break;
+	case CLKCFG_FSB_400:
+		dev_priv->fsb_freq = 400; /* 100*4 */
+		break;
+	}
+
+	switch (tmp & CLKCFG_MEM_MASK) {
+	case CLKCFG_MEM_533:
+		dev_priv->mem_freq = 533;
+		break;
+	case CLKCFG_MEM_667:
+		dev_priv->mem_freq = 667;
+		break;
+	case CLKCFG_MEM_800:
+		dev_priv->mem_freq = 800;
+		break;
+	}
+
+	/* detect pineview DDR3 setting */
+	tmp = I915_READ(CSHRDDR3CTL);
+	dev_priv->is_ddr3 = (tmp & CSHRDDR3CTL_DDR3) ? 1 : 0;
+}
+
+static void i915_ironlake_get_mem_freq(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	u16 ddrpll, csipll;
+
+	ddrpll = I915_READ16(DDRMPLL1);
+	csipll = I915_READ16(CSIPLL0);
+
+	switch (ddrpll & 0xff) {
+	case 0xc:
+		dev_priv->mem_freq = 800;
+		break;
+	case 0x10:
+		dev_priv->mem_freq = 1066;
+		break;
+	case 0x14:
+		dev_priv->mem_freq = 1333;
+		break;
+	case 0x18:
+		dev_priv->mem_freq = 1600;
+		break;
+	default:
+		DRM_DEBUG_DRIVER("unknown memory frequency 0x%02x\n",
+				 ddrpll & 0xff);
+		dev_priv->mem_freq = 0;
+		break;
+	}
+
+	dev_priv->ips.r_t = dev_priv->mem_freq;
+
+	switch (csipll & 0x3ff) {
+	case 0x00c:
+		dev_priv->fsb_freq = 3200;
+		break;
+	case 0x00e:
+		dev_priv->fsb_freq = 3733;
+		break;
+	case 0x010:
+		dev_priv->fsb_freq = 4266;
+		break;
+	case 0x012:
+		dev_priv->fsb_freq = 4800;
+		break;
+	case 0x014:
+		dev_priv->fsb_freq = 5333;
+		break;
+	case 0x016:
+		dev_priv->fsb_freq = 5866;
+		break;
+	case 0x018:
+		dev_priv->fsb_freq = 6400;
+		break;
+	default:
+		DRM_DEBUG_DRIVER("unknown fsb frequency 0x%04x\n",
+				 csipll & 0x3ff);
+		dev_priv->fsb_freq = 0;
+		break;
+	}
+
+	if (dev_priv->fsb_freq == 3200) {
+		dev_priv->ips.c_m = 0;
+	} else if (dev_priv->fsb_freq > 3200 && dev_priv->fsb_freq <= 4800) {
+		dev_priv->ips.c_m = 1;
+	} else {
+		dev_priv->ips.c_m = 2;
+	}
+}
+
+static const struct cxsr_latency cxsr_latency_table[] = {
+	{1, 0, 800, 400, 3382, 33382, 3983, 33983},    /* DDR2-400 SC */
+	{1, 0, 800, 667, 3354, 33354, 3807, 33807},    /* DDR2-667 SC */
+	{1, 0, 800, 800, 3347, 33347, 3763, 33763},    /* DDR2-800 SC */
+	{1, 1, 800, 667, 6420, 36420, 6873, 36873},    /* DDR3-667 SC */
+	{1, 1, 800, 800, 5902, 35902, 6318, 36318},    /* DDR3-800 SC */
+
+	{1, 0, 667, 400, 3400, 33400, 4021, 34021},    /* DDR2-400 SC */
+	{1, 0, 667, 667, 3372, 33372, 3845, 33845},    /* DDR2-667 SC */
+	{1, 0, 667, 800, 3386, 33386, 3822, 33822},    /* DDR2-800 SC */
+	{1, 1, 667, 667, 6438, 36438, 6911, 36911},    /* DDR3-667 SC */
+	{1, 1, 667, 800, 5941, 35941, 6377, 36377},    /* DDR3-800 SC */
+
+	{1, 0, 400, 400, 3472, 33472, 4173, 34173},    /* DDR2-400 SC */
+	{1, 0, 400, 667, 3443, 33443, 3996, 33996},    /* DDR2-667 SC */
+	{1, 0, 400, 800, 3430, 33430, 3946, 33946},    /* DDR2-800 SC */
+	{1, 1, 400, 667, 6509, 36509, 7062, 37062},    /* DDR3-667 SC */
+	{1, 1, 400, 800, 5985, 35985, 6501, 36501},    /* DDR3-800 SC */
+
+	{0, 0, 800, 400, 3438, 33438, 4065, 34065},    /* DDR2-400 SC */
+	{0, 0, 800, 667, 3410, 33410, 3889, 33889},    /* DDR2-667 SC */
+	{0, 0, 800, 800, 3403, 33403, 3845, 33845},    /* DDR2-800 SC */
+	{0, 1, 800, 667, 6476, 36476, 6955, 36955},    /* DDR3-667 SC */
+	{0, 1, 800, 800, 5958, 35958, 6400, 36400},    /* DDR3-800 SC */
+
+	{0, 0, 667, 400, 3456, 33456, 4103, 34106},    /* DDR2-400 SC */
+	{0, 0, 667, 667, 3428, 33428, 3927, 33927},    /* DDR2-667 SC */
+	{0, 0, 667, 800, 3443, 33443, 3905, 33905},    /* DDR2-800 SC */
+	{0, 1, 667, 667, 6494, 36494, 6993, 36993},    /* DDR3-667 SC */
+	{0, 1, 667, 800, 5998, 35998, 6460, 36460},    /* DDR3-800 SC */
+
+	{0, 0, 400, 400, 3528, 33528, 4255, 34255},    /* DDR2-400 SC */
+	{0, 0, 400, 667, 3500, 33500, 4079, 34079},    /* DDR2-667 SC */
+	{0, 0, 400, 800, 3487, 33487, 4029, 34029},    /* DDR2-800 SC */
+	{0, 1, 400, 667, 6566, 36566, 7145, 37145},    /* DDR3-667 SC */
+	{0, 1, 400, 800, 6042, 36042, 6584, 36584},    /* DDR3-800 SC */
+};
+
+static const struct cxsr_latency *intel_get_cxsr_latency(int is_desktop,
+							 int is_ddr3,
+							 int fsb,
+							 int mem)
+{
+	const struct cxsr_latency *latency;
+	int i;
+
+	if (fsb == 0 || mem == 0)
+		return NULL;
+
+	for (i = 0; i < ARRAY_SIZE(cxsr_latency_table); i++) {
+		latency = &cxsr_latency_table[i];
+		if (is_desktop == latency->is_desktop &&
+		    is_ddr3 == latency->is_ddr3 &&
+		    fsb == latency->fsb_freq && mem == latency->mem_freq)
+			return latency;
+	}
+
+	DRM_DEBUG_KMS("Unknown FSB/MEM found, disable CxSR\n");
+
+	return NULL;
+}
+
+static void chv_set_memory_dvfs(struct drm_i915_private *dev_priv, bool enable)
+{
+	u32 val;
+
+	mutex_lock(&dev_priv->rps.hw_lock);
+
+	val = vlv_punit_read(dev_priv, PUNIT_REG_DDR_SETUP2);
+	if (enable)
+		val &= ~FORCE_DDR_HIGH_FREQ;
+	else
+		val |= FORCE_DDR_HIGH_FREQ;
+	val &= ~FORCE_DDR_LOW_FREQ;
+	val |= FORCE_DDR_FREQ_REQ_ACK;
+	vlv_punit_write(dev_priv, PUNIT_REG_DDR_SETUP2, val);
+
+	if (wait_for((vlv_punit_read(dev_priv, PUNIT_REG_DDR_SETUP2) &
+		      FORCE_DDR_FREQ_REQ_ACK) == 0, 3))
+		DRM_ERROR("timed out waiting for Punit DDR DVFS request\n");
+
+	mutex_unlock(&dev_priv->rps.hw_lock);
+}
+
+static void chv_set_memory_pm5(struct drm_i915_private *dev_priv, bool enable)
+{
+	u32 val;
+
+	mutex_lock(&dev_priv->rps.hw_lock);
+
+	val = vlv_punit_read(dev_priv, PUNIT_REG_DSPFREQ);
+	if (enable)
+		val |= DSP_MAXFIFO_PM5_ENABLE;
+	else
+		val &= ~DSP_MAXFIFO_PM5_ENABLE;
+	vlv_punit_write(dev_priv, PUNIT_REG_DSPFREQ, val);
+
+	mutex_unlock(&dev_priv->rps.hw_lock);
+}
+
+#define FW_WM(value, plane) \
+	(((value) << DSPFW_ ## plane ## _SHIFT) & DSPFW_ ## plane ## _MASK)
+
+void intel_set_memory_cxsr(struct drm_i915_private *dev_priv, bool enable)
+{
+	struct drm_device *dev = dev_priv->dev;
+	u32 val;
+
+	if (IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev)) {
+		I915_WRITE(FW_BLC_SELF_VLV, enable ? FW_CSPWRDWNEN : 0);
+		POSTING_READ(FW_BLC_SELF_VLV);
+		dev_priv->wm.vlv.cxsr = enable;
+	} else if (IS_G4X(dev) || IS_CRESTLINE(dev)) {
+		I915_WRITE(FW_BLC_SELF, enable ? FW_BLC_SELF_EN : 0);
+		POSTING_READ(FW_BLC_SELF);
+	} else if (IS_PINEVIEW(dev)) {
+		val = I915_READ(DSPFW3) & ~PINEVIEW_SELF_REFRESH_EN;
+		val |= enable ? PINEVIEW_SELF_REFRESH_EN : 0;
+		I915_WRITE(DSPFW3, val);
+		POSTING_READ(DSPFW3);
+	} else if (IS_I945G(dev) || IS_I945GM(dev)) {
+		val = enable ? _MASKED_BIT_ENABLE(FW_BLC_SELF_EN) :
+			       _MASKED_BIT_DISABLE(FW_BLC_SELF_EN);
+		I915_WRITE(FW_BLC_SELF, val);
+		POSTING_READ(FW_BLC_SELF);
+	} else if (IS_I915GM(dev)) {
+		val = enable ? _MASKED_BIT_ENABLE(INSTPM_SELF_EN) :
+			       _MASKED_BIT_DISABLE(INSTPM_SELF_EN);
+		I915_WRITE(INSTPM, val);
+		POSTING_READ(INSTPM);
+	} else {
+		return;
+	}
+
+	DRM_DEBUG_KMS("memory self-refresh is %s\n",
+		      enable ? "enabled" : "disabled");
+}
+
+
+/*
+ * Latency for FIFO fetches is dependent on several factors:
+ *   - memory configuration (speed, channels)
+ *   - chipset
+ *   - current MCH state
+ * It can be fairly high in some situations, so here we assume a fairly
+ * pessimal value.  It's a tradeoff between extra memory fetches (if we
+ * set this value too high, the FIFO will fetch frequently to stay full)
+ * and power consumption (set it too low to save power and we might see
+ * FIFO underruns and display "flicker").
+ *
+ * A value of 5us seems to be a good balance; safe for very low end
+ * platforms but not overly aggressive on lower latency configs.
+ */
+static const int pessimal_latency_ns = 5000;
+
+#define VLV_FIFO_START(dsparb, dsparb2, lo_shift, hi_shift) \
+	((((dsparb) >> (lo_shift)) & 0xff) | ((((dsparb2) >> (hi_shift)) & 0x1) << 8))
+
+static int vlv_get_fifo_size(struct drm_device *dev,
+			      enum pipe pipe, int plane)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	int sprite0_start, sprite1_start, size;
+
+	switch (pipe) {
+		uint32_t dsparb, dsparb2, dsparb3;
+	case PIPE_A:
+		dsparb = I915_READ(DSPARB);
+		dsparb2 = I915_READ(DSPARB2);
+		sprite0_start = VLV_FIFO_START(dsparb, dsparb2, 0, 0);
+		sprite1_start = VLV_FIFO_START(dsparb, dsparb2, 8, 4);
+		break;
+	case PIPE_B:
+		dsparb = I915_READ(DSPARB);
+		dsparb2 = I915_READ(DSPARB2);
+		sprite0_start = VLV_FIFO_START(dsparb, dsparb2, 16, 8);
+		sprite1_start = VLV_FIFO_START(dsparb, dsparb2, 24, 12);
+		break;
+	case PIPE_C:
+		dsparb2 = I915_READ(DSPARB2);
+		dsparb3 = I915_READ(DSPARB3);
+		sprite0_start = VLV_FIFO_START(dsparb3, dsparb2, 0, 16);
+		sprite1_start = VLV_FIFO_START(dsparb3, dsparb2, 8, 20);
+		break;
+	default:
+		return 0;
+	}
+
+	switch (plane) {
+	case 0:
+		size = sprite0_start;
+		break;
+	case 1:
+		size = sprite1_start - sprite0_start;
+		break;
+	case 2:
+		size = 512 - 1 - sprite1_start;
+		break;
+	default:
+		return 0;
+	}
+
+	DRM_DEBUG_KMS("Pipe %c %s %c FIFO size: %d\n",
+		      pipe_name(pipe), plane == 0 ? "primary" : "sprite",
+		      plane == 0 ? plane_name(pipe) : sprite_name(pipe, plane - 1),
+		      size);
+
+	return size;
+}
+
+static int i9xx_get_fifo_size(struct drm_device *dev, int plane)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	uint32_t dsparb = I915_READ(DSPARB);
+	int size;
+
+	size = dsparb & 0x7f;
+	if (plane)
+		size = ((dsparb >> DSPARB_CSTART_SHIFT) & 0x7f) - size;
+
+	DRM_DEBUG_KMS("FIFO size - (0x%08x) %s: %d\n", dsparb,
+		      plane ? "B" : "A", size);
+
+	return size;
+}
+
+static int i830_get_fifo_size(struct drm_device *dev, int plane)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	uint32_t dsparb = I915_READ(DSPARB);
+	int size;
+
+	size = dsparb & 0x1ff;
+	if (plane)
+		size = ((dsparb >> DSPARB_BEND_SHIFT) & 0x1ff) - size;
+	size >>= 1; /* Convert to cachelines */
+
+	DRM_DEBUG_KMS("FIFO size - (0x%08x) %s: %d\n", dsparb,
+		      plane ? "B" : "A", size);
+
+	return size;
+}
+
+static int i845_get_fifo_size(struct drm_device *dev, int plane)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	uint32_t dsparb = I915_READ(DSPARB);
+	int size;
+
+	size = dsparb & 0x7f;
+	size >>= 2; /* Convert to cachelines */
+
+	DRM_DEBUG_KMS("FIFO size - (0x%08x) %s: %d\n", dsparb,
+		      plane ? "B" : "A",
+		      size);
+
+	return size;
+}
+
+/* Pineview has different values for various configs */
+static const struct intel_watermark_params pineview_display_wm = {
+	.fifo_size = PINEVIEW_DISPLAY_FIFO,
+	.max_wm = PINEVIEW_MAX_WM,
+	.default_wm = PINEVIEW_DFT_WM,
+	.guard_size = PINEVIEW_GUARD_WM,
+	.cacheline_size = PINEVIEW_FIFO_LINE_SIZE,
+};
+static const struct intel_watermark_params pineview_display_hplloff_wm = {
+	.fifo_size = PINEVIEW_DISPLAY_FIFO,
+	.max_wm = PINEVIEW_MAX_WM,
+	.default_wm = PINEVIEW_DFT_HPLLOFF_WM,
+	.guard_size = PINEVIEW_GUARD_WM,
+	.cacheline_size = PINEVIEW_FIFO_LINE_SIZE,
+};
+static const struct intel_watermark_params pineview_cursor_wm = {
+	.fifo_size = PINEVIEW_CURSOR_FIFO,
+	.max_wm = PINEVIEW_CURSOR_MAX_WM,
+	.default_wm = PINEVIEW_CURSOR_DFT_WM,
+	.guard_size = PINEVIEW_CURSOR_GUARD_WM,
+	.cacheline_size = PINEVIEW_FIFO_LINE_SIZE,
+};
+static const struct intel_watermark_params pineview_cursor_hplloff_wm = {
+	.fifo_size = PINEVIEW_CURSOR_FIFO,
+	.max_wm = PINEVIEW_CURSOR_MAX_WM,
+	.default_wm = PINEVIEW_CURSOR_DFT_WM,
+	.guard_size = PINEVIEW_CURSOR_GUARD_WM,
+	.cacheline_size = PINEVIEW_FIFO_LINE_SIZE,
+};
+static const struct intel_watermark_params g4x_wm_info = {
+	.fifo_size = G4X_FIFO_SIZE,
+	.max_wm = G4X_MAX_WM,
+	.default_wm = G4X_MAX_WM,
+	.guard_size = 2,
+	.cacheline_size = G4X_FIFO_LINE_SIZE,
+};
+static const struct intel_watermark_params g4x_cursor_wm_info = {
+	.fifo_size = I965_CURSOR_FIFO,
+	.max_wm = I965_CURSOR_MAX_WM,
+	.default_wm = I965_CURSOR_DFT_WM,
+	.guard_size = 2,
+	.cacheline_size = G4X_FIFO_LINE_SIZE,
+};
+static const struct intel_watermark_params i965_cursor_wm_info = {
+	.fifo_size = I965_CURSOR_FIFO,
+	.max_wm = I965_CURSOR_MAX_WM,
+	.default_wm = I965_CURSOR_DFT_WM,
+	.guard_size = 2,
+	.cacheline_size = I915_FIFO_LINE_SIZE,
+};
+static const struct intel_watermark_params i945_wm_info = {
+	.fifo_size = I945_FIFO_SIZE,
+	.max_wm = I915_MAX_WM,
+	.default_wm = 1,
+	.guard_size = 2,
+	.cacheline_size = I915_FIFO_LINE_SIZE,
+};
+static const struct intel_watermark_params i915_wm_info = {
+	.fifo_size = I915_FIFO_SIZE,
+	.max_wm = I915_MAX_WM,
+	.default_wm = 1,
+	.guard_size = 2,
+	.cacheline_size = I915_FIFO_LINE_SIZE,
+};
+static const struct intel_watermark_params i830_a_wm_info = {
+	.fifo_size = I855GM_FIFO_SIZE,
+	.max_wm = I915_MAX_WM,
+	.default_wm = 1,
+	.guard_size = 2,
+	.cacheline_size = I830_FIFO_LINE_SIZE,
+};
+static const struct intel_watermark_params i830_bc_wm_info = {
+	.fifo_size = I855GM_FIFO_SIZE,
+	.max_wm = I915_MAX_WM/2,
+	.default_wm = 1,
+	.guard_size = 2,
+	.cacheline_size = I830_FIFO_LINE_SIZE,
+};
+static const struct intel_watermark_params i845_wm_info = {
+	.fifo_size = I830_FIFO_SIZE,
+	.max_wm = I915_MAX_WM,
+	.default_wm = 1,
+	.guard_size = 2,
+	.cacheline_size = I830_FIFO_LINE_SIZE,
+};
+
+/**
+ * intel_calculate_wm - calculate watermark level
+ * @clock_in_khz: pixel clock
+ * @wm: chip FIFO params
+ * @cpp: bytes per pixel
+ * @latency_ns: memory latency for the platform
+ *
+ * Calculate the watermark level (the level at which the display plane will
+ * start fetching from memory again).  Each chip has a different display
+ * FIFO size and allocation, so the caller needs to figure that out and pass
+ * in the correct intel_watermark_params structure.
+ *
+ * As the pixel clock runs, the FIFO will be drained at a rate that depends
+ * on the pixel size.  When it reaches the watermark level, it'll start
+ * fetching FIFO line sized based chunks from memory until the FIFO fills
+ * past the watermark point.  If the FIFO drains completely, a FIFO underrun
+ * will occur, and a display engine hang could result.
+ */
+static unsigned long intel_calculate_wm(unsigned long clock_in_khz,
+					const struct intel_watermark_params *wm,
+					int fifo_size, int cpp,
+					unsigned long latency_ns)
+{
+	long entries_required, wm_size;
+
+	/*
+	 * Note: we need to make sure we don't overflow for various clock &
+	 * latency values.
+	 * clocks go from a few thousand to several hundred thousand.
+	 * latency is usually a few thousand
+	 */
+	entries_required = ((clock_in_khz / 1000) * cpp * latency_ns) /
+		1000;
+	entries_required = DIV_ROUND_UP(entries_required, wm->cacheline_size);
+
+	DRM_DEBUG_KMS("FIFO entries required for mode: %ld\n", entries_required);
+
+	wm_size = fifo_size - (entries_required + wm->guard_size);
+
+	DRM_DEBUG_KMS("FIFO watermark level: %ld\n", wm_size);
+
+	/* Don't promote wm_size to unsigned... */
+	if (wm_size > (long)wm->max_wm)
+		wm_size = wm->max_wm;
+	if (wm_size <= 0)
+		wm_size = wm->default_wm;
+
+	/*
+	 * Bspec seems to indicate that the value shouldn't be lower than
+	 * 'burst size + 1'. Certainly 830 is quite unhappy with low values.
+	 * Lets go for 8 which is the burst size since certain platforms
+	 * already use a hardcoded 8 (which is what the spec says should be
+	 * done).
+	 */
+	if (wm_size <= 8)
+		wm_size = 8;
+
+	return wm_size;
+}
+
+static struct drm_crtc *single_enabled_crtc(struct drm_device *dev)
+{
+	struct drm_crtc *crtc, *enabled = NULL;
+
+	for_each_crtc(dev, crtc) {
+		if (intel_crtc_active(crtc)) {
+			if (enabled)
+				return NULL;
+			enabled = crtc;
+		}
+	}
+
+	return enabled;
+}
+
+static void pineview_update_wm(struct drm_crtc *unused_crtc)
+{
+	struct drm_device *dev = unused_crtc->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct drm_crtc *crtc;
+	const struct cxsr_latency *latency;
+	u32 reg;
+	unsigned long wm;
+
+	latency = intel_get_cxsr_latency(IS_PINEVIEW_G(dev), dev_priv->is_ddr3,
+					 dev_priv->fsb_freq, dev_priv->mem_freq);
+	if (!latency) {
+		DRM_DEBUG_KMS("Unknown FSB/MEM found, disable CxSR\n");
+		intel_set_memory_cxsr(dev_priv, false);
+		return;
+	}
+
+	crtc = single_enabled_crtc(dev);
+	if (crtc) {
+		const struct drm_display_mode *adjusted_mode = &to_intel_crtc(crtc)->config->base.adjusted_mode;
+		int cpp = drm_format_plane_cpp(crtc->primary->state->fb->pixel_format, 0);
+		int clock = adjusted_mode->crtc_clock;
+
+		/* Display SR */
+		wm = intel_calculate_wm(clock, &pineview_display_wm,
+					pineview_display_wm.fifo_size,
+					cpp, latency->display_sr);
+		reg = I915_READ(DSPFW1);
+		reg &= ~DSPFW_SR_MASK;
+		reg |= FW_WM(wm, SR);
+		I915_WRITE(DSPFW1, reg);
+		DRM_DEBUG_KMS("DSPFW1 register is %x\n", reg);
+
+		/* cursor SR */
+		wm = intel_calculate_wm(clock, &pineview_cursor_wm,
+					pineview_display_wm.fifo_size,
+					cpp, latency->cursor_sr);
+		reg = I915_READ(DSPFW3);
+		reg &= ~DSPFW_CURSOR_SR_MASK;
+		reg |= FW_WM(wm, CURSOR_SR);
+		I915_WRITE(DSPFW3, reg);
+
+		/* Display HPLL off SR */
+		wm = intel_calculate_wm(clock, &pineview_display_hplloff_wm,
+					pineview_display_hplloff_wm.fifo_size,
+					cpp, latency->display_hpll_disable);
+		reg = I915_READ(DSPFW3);
+		reg &= ~DSPFW_HPLL_SR_MASK;
+		reg |= FW_WM(wm, HPLL_SR);
+		I915_WRITE(DSPFW3, reg);
+
+		/* cursor HPLL off SR */
+		wm = intel_calculate_wm(clock, &pineview_cursor_hplloff_wm,
+					pineview_display_hplloff_wm.fifo_size,
+					cpp, latency->cursor_hpll_disable);
+		reg = I915_READ(DSPFW3);
+		reg &= ~DSPFW_HPLL_CURSOR_MASK;
+		reg |= FW_WM(wm, HPLL_CURSOR);
+		I915_WRITE(DSPFW3, reg);
+		DRM_DEBUG_KMS("DSPFW3 register is %x\n", reg);
+
+		intel_set_memory_cxsr(dev_priv, true);
+	} else {
+		intel_set_memory_cxsr(dev_priv, false);
+	}
+}
+
+static bool g4x_compute_wm0(struct drm_device *dev,
+			    int plane,
+			    const struct intel_watermark_params *display,
+			    int display_latency_ns,
+			    const struct intel_watermark_params *cursor,
+			    int cursor_latency_ns,
+			    int *plane_wm,
+			    int *cursor_wm)
+{
+	struct drm_crtc *crtc;
+	const struct drm_display_mode *adjusted_mode;
+	int htotal, hdisplay, clock, cpp;
+	int line_time_us, line_count;
+	int entries, tlb_miss;
+
+	crtc = intel_get_crtc_for_plane(dev, plane);
+	if (!intel_crtc_active(crtc)) {
+		*cursor_wm = cursor->guard_size;
+		*plane_wm = display->guard_size;
+		return false;
+	}
+
+	adjusted_mode = &to_intel_crtc(crtc)->config->base.adjusted_mode;
+	clock = adjusted_mode->crtc_clock;
+	htotal = adjusted_mode->crtc_htotal;
+	hdisplay = to_intel_crtc(crtc)->config->pipe_src_w;
+	cpp = drm_format_plane_cpp(crtc->primary->state->fb->pixel_format, 0);
+
+	/* Use the small buffer method to calculate plane watermark */
+	entries = ((clock * cpp / 1000) * display_latency_ns) / 1000;
+	tlb_miss = display->fifo_size*display->cacheline_size - hdisplay * 8;
+	if (tlb_miss > 0)
+		entries += tlb_miss;
+	entries = DIV_ROUND_UP(entries, display->cacheline_size);
+	*plane_wm = entries + display->guard_size;
+	if (*plane_wm > (int)display->max_wm)
+		*plane_wm = display->max_wm;
+
+	/* Use the large buffer method to calculate cursor watermark */
+	line_time_us = max(htotal * 1000 / clock, 1);
+	line_count = (cursor_latency_ns / line_time_us + 1000) / 1000;
+	entries = line_count * crtc->cursor->state->crtc_w * cpp;
+	tlb_miss = cursor->fifo_size*cursor->cacheline_size - hdisplay * 8;
+	if (tlb_miss > 0)
+		entries += tlb_miss;
+	entries = DIV_ROUND_UP(entries, cursor->cacheline_size);
+	*cursor_wm = entries + cursor->guard_size;
+	if (*cursor_wm > (int)cursor->max_wm)
+		*cursor_wm = (int)cursor->max_wm;
+
+	return true;
+}
+
+/*
+ * Check the wm result.
+ *
+ * If any calculated watermark values is larger than the maximum value that
+ * can be programmed into the associated watermark register, that watermark
+ * must be disabled.
+ */
+static bool g4x_check_srwm(struct drm_device *dev,
+			   int display_wm, int cursor_wm,
+			   const struct intel_watermark_params *display,
+			   const struct intel_watermark_params *cursor)
+{
+	DRM_DEBUG_KMS("SR watermark: display plane %d, cursor %d\n",
+		      display_wm, cursor_wm);
+
+	if (display_wm > display->max_wm) {
+		DRM_DEBUG_KMS("display watermark is too large(%d/%ld), disabling\n",
+			      display_wm, display->max_wm);
+		return false;
+	}
+
+	if (cursor_wm > cursor->max_wm) {
+		DRM_DEBUG_KMS("cursor watermark is too large(%d/%ld), disabling\n",
+			      cursor_wm, cursor->max_wm);
+		return false;
+	}
+
+	if (!(display_wm || cursor_wm)) {
+		DRM_DEBUG_KMS("SR latency is 0, disabling\n");
+		return false;
+	}
+
+	return true;
+}
+
+static bool g4x_compute_srwm(struct drm_device *dev,
+			     int plane,
+			     int latency_ns,
+			     const struct intel_watermark_params *display,
+			     const struct intel_watermark_params *cursor,
+			     int *display_wm, int *cursor_wm)
+{
+	struct drm_crtc *crtc;
+	const struct drm_display_mode *adjusted_mode;
+	int hdisplay, htotal, cpp, clock;
+	unsigned long line_time_us;
+	int line_count, line_size;
+	int small, large;
+	int entries;
+
+	if (!latency_ns) {
+		*display_wm = *cursor_wm = 0;
+		return false;
+	}
+
+	crtc = intel_get_crtc_for_plane(dev, plane);
+	adjusted_mode = &to_intel_crtc(crtc)->config->base.adjusted_mode;
+	clock = adjusted_mode->crtc_clock;
+	htotal = adjusted_mode->crtc_htotal;
+	hdisplay = to_intel_crtc(crtc)->config->pipe_src_w;
+	cpp = drm_format_plane_cpp(crtc->primary->state->fb->pixel_format, 0);
+
+	line_time_us = max(htotal * 1000 / clock, 1);
+	line_count = (latency_ns / line_time_us + 1000) / 1000;
+	line_size = hdisplay * cpp;
+
+	/* Use the minimum of the small and large buffer method for primary */
+	small = ((clock * cpp / 1000) * latency_ns) / 1000;
+	large = line_count * line_size;
+
+	entries = DIV_ROUND_UP(min(small, large), display->cacheline_size);
+	*display_wm = entries + display->guard_size;
+
+	/* calculate the self-refresh watermark for display cursor */
+	entries = line_count * cpp * crtc->cursor->state->crtc_w;
+	entries = DIV_ROUND_UP(entries, cursor->cacheline_size);
+	*cursor_wm = entries + cursor->guard_size;
+
+	return g4x_check_srwm(dev,
+			      *display_wm, *cursor_wm,
+			      display, cursor);
+}
+
+#define FW_WM_VLV(value, plane) \
+	(((value) << DSPFW_ ## plane ## _SHIFT) & DSPFW_ ## plane ## _MASK_VLV)
+
+static void vlv_write_wm_values(struct intel_crtc *crtc,
+				const struct vlv_wm_values *wm)
+{
+	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
+	enum pipe pipe = crtc->pipe;
+
+	I915_WRITE(VLV_DDL(pipe),
+		   (wm->ddl[pipe].cursor << DDL_CURSOR_SHIFT) |
+		   (wm->ddl[pipe].sprite[1] << DDL_SPRITE_SHIFT(1)) |
+		   (wm->ddl[pipe].sprite[0] << DDL_SPRITE_SHIFT(0)) |
+		   (wm->ddl[pipe].primary << DDL_PLANE_SHIFT));
+
+	I915_WRITE(DSPFW1,
+		   FW_WM(wm->sr.plane, SR) |
+		   FW_WM(wm->pipe[PIPE_B].cursor, CURSORB) |
+		   FW_WM_VLV(wm->pipe[PIPE_B].primary, PLANEB) |
+		   FW_WM_VLV(wm->pipe[PIPE_A].primary, PLANEA));
+	I915_WRITE(DSPFW2,
+		   FW_WM_VLV(wm->pipe[PIPE_A].sprite[1], SPRITEB) |
+		   FW_WM(wm->pipe[PIPE_A].cursor, CURSORA) |
+		   FW_WM_VLV(wm->pipe[PIPE_A].sprite[0], SPRITEA));
+	I915_WRITE(DSPFW3,
+		   FW_WM(wm->sr.cursor, CURSOR_SR));
+
+	if (IS_CHERRYVIEW(dev_priv)) {
+		I915_WRITE(DSPFW7_CHV,
+			   FW_WM_VLV(wm->pipe[PIPE_B].sprite[1], SPRITED) |
+			   FW_WM_VLV(wm->pipe[PIPE_B].sprite[0], SPRITEC));
+		I915_WRITE(DSPFW8_CHV,
+			   FW_WM_VLV(wm->pipe[PIPE_C].sprite[1], SPRITEF) |
+			   FW_WM_VLV(wm->pipe[PIPE_C].sprite[0], SPRITEE));
+		I915_WRITE(DSPFW9_CHV,
+			   FW_WM_VLV(wm->pipe[PIPE_C].primary, PLANEC) |
+			   FW_WM(wm->pipe[PIPE_C].cursor, CURSORC));
+		I915_WRITE(DSPHOWM,
+			   FW_WM(wm->sr.plane >> 9, SR_HI) |
+			   FW_WM(wm->pipe[PIPE_C].sprite[1] >> 8, SPRITEF_HI) |
+			   FW_WM(wm->pipe[PIPE_C].sprite[0] >> 8, SPRITEE_HI) |
+			   FW_WM(wm->pipe[PIPE_C].primary >> 8, PLANEC_HI) |
+			   FW_WM(wm->pipe[PIPE_B].sprite[1] >> 8, SPRITED_HI) |
+			   FW_WM(wm->pipe[PIPE_B].sprite[0] >> 8, SPRITEC_HI) |
+			   FW_WM(wm->pipe[PIPE_B].primary >> 8, PLANEB_HI) |
+			   FW_WM(wm->pipe[PIPE_A].sprite[1] >> 8, SPRITEB_HI) |
+			   FW_WM(wm->pipe[PIPE_A].sprite[0] >> 8, SPRITEA_HI) |
+			   FW_WM(wm->pipe[PIPE_A].primary >> 8, PLANEA_HI));
+	} else {
+		I915_WRITE(DSPFW7,
+			   FW_WM_VLV(wm->pipe[PIPE_B].sprite[1], SPRITED) |
+			   FW_WM_VLV(wm->pipe[PIPE_B].sprite[0], SPRITEC));
+		I915_WRITE(DSPHOWM,
+			   FW_WM(wm->sr.plane >> 9, SR_HI) |
+			   FW_WM(wm->pipe[PIPE_B].sprite[1] >> 8, SPRITED_HI) |
+			   FW_WM(wm->pipe[PIPE_B].sprite[0] >> 8, SPRITEC_HI) |
+			   FW_WM(wm->pipe[PIPE_B].primary >> 8, PLANEB_HI) |
+			   FW_WM(wm->pipe[PIPE_A].sprite[1] >> 8, SPRITEB_HI) |
+			   FW_WM(wm->pipe[PIPE_A].sprite[0] >> 8, SPRITEA_HI) |
+			   FW_WM(wm->pipe[PIPE_A].primary >> 8, PLANEA_HI));
+	}
+
+	/* zero (unused) WM1 watermarks */
+	I915_WRITE(DSPFW4, 0);
+	I915_WRITE(DSPFW5, 0);
+	I915_WRITE(DSPFW6, 0);
+	I915_WRITE(DSPHOWM1, 0);
+
+	POSTING_READ(DSPFW1);
+}
+
+#undef FW_WM_VLV
+
+enum vlv_wm_level {
+	VLV_WM_LEVEL_PM2,
+	VLV_WM_LEVEL_PM5,
+	VLV_WM_LEVEL_DDR_DVFS,
+};
+
+/* latency must be in 0.1us units. */
+static unsigned int vlv_wm_method2(unsigned int pixel_rate,
+				   unsigned int pipe_htotal,
+				   unsigned int horiz_pixels,
+				   unsigned int cpp,
+				   unsigned int latency)
+{
+	unsigned int ret;
+
+	ret = (latency * pixel_rate) / (pipe_htotal * 10000);
+	ret = (ret + 1) * horiz_pixels * cpp;
+	ret = DIV_ROUND_UP(ret, 64);
+
+	return ret;
+}
+
+static void vlv_setup_wm_latency(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	/* all latencies in usec */
+	dev_priv->wm.pri_latency[VLV_WM_LEVEL_PM2] = 3;
+
+	dev_priv->wm.max_level = VLV_WM_LEVEL_PM2;
+
+	if (IS_CHERRYVIEW(dev_priv)) {
+		dev_priv->wm.pri_latency[VLV_WM_LEVEL_PM5] = 12;
+		dev_priv->wm.pri_latency[VLV_WM_LEVEL_DDR_DVFS] = 33;
+
+		dev_priv->wm.max_level = VLV_WM_LEVEL_DDR_DVFS;
+	}
+}
+
+static uint16_t vlv_compute_wm_level(struct intel_plane *plane,
+				     struct intel_crtc *crtc,
+				     const struct intel_plane_state *state,
+				     int level)
+{
+	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
+	int clock, htotal, cpp, width, wm;
+
+	if (dev_priv->wm.pri_latency[level] == 0)
+		return USHRT_MAX;
+
+	if (!state->visible)
+		return 0;
+
+	cpp = drm_format_plane_cpp(state->base.fb->pixel_format, 0);
+	clock = crtc->config->base.adjusted_mode.crtc_clock;
+	htotal = crtc->config->base.adjusted_mode.crtc_htotal;
+	width = crtc->config->pipe_src_w;
+	if (WARN_ON(htotal == 0))
+		htotal = 1;
+
+	if (plane->base.type == DRM_PLANE_TYPE_CURSOR) {
+		/*
+		 * FIXME the formula gives values that are
+		 * too big for the cursor FIFO, and hence we
+		 * would never be able to use cursors. For
+		 * now just hardcode the watermark.
+		 */
+		wm = 63;
+	} else {
+		wm = vlv_wm_method2(clock, htotal, width, cpp,
+				    dev_priv->wm.pri_latency[level] * 10);
+	}
+
+	return min_t(int, wm, USHRT_MAX);
+}
+
+static void vlv_compute_fifo(struct intel_crtc *crtc)
+{
+	struct drm_device *dev = crtc->base.dev;
+	struct vlv_wm_state *wm_state = &crtc->wm_state;
+	struct intel_plane *plane;
+	unsigned int total_rate = 0;
+	const int fifo_size = 512 - 1;
+	int fifo_extra, fifo_left = fifo_size;
+
+	for_each_intel_plane_on_crtc(dev, crtc, plane) {
+		struct intel_plane_state *state =
+			to_intel_plane_state(plane->base.state);
+
+		if (plane->base.type == DRM_PLANE_TYPE_CURSOR)
+			continue;
+
+		if (state->visible) {
+			wm_state->num_active_planes++;
+			total_rate += drm_format_plane_cpp(state->base.fb->pixel_format, 0);
+		}
+	}
+
+	for_each_intel_plane_on_crtc(dev, crtc, plane) {
+		struct intel_plane_state *state =
+			to_intel_plane_state(plane->base.state);
+		unsigned int rate;
+
+		if (plane->base.type == DRM_PLANE_TYPE_CURSOR) {
+			plane->wm.fifo_size = 63;
+			continue;
+		}
+
+		if (!state->visible) {
+			plane->wm.fifo_size = 0;
+			continue;
+		}
+
+		rate = drm_format_plane_cpp(state->base.fb->pixel_format, 0);
+		plane->wm.fifo_size = fifo_size * rate / total_rate;
+		fifo_left -= plane->wm.fifo_size;
+	}
+
+	fifo_extra = DIV_ROUND_UP(fifo_left, wm_state->num_active_planes ?: 1);
+
+	/* spread the remainder evenly */
+	for_each_intel_plane_on_crtc(dev, crtc, plane) {
+		int plane_extra;
+
+		if (fifo_left == 0)
+			break;
+
+		if (plane->base.type == DRM_PLANE_TYPE_CURSOR)
+			continue;
+
+		/* give it all to the first plane if none are active */
+		if (plane->wm.fifo_size == 0 &&
+		    wm_state->num_active_planes)
+			continue;
+
+		plane_extra = min(fifo_extra, fifo_left);
+		plane->wm.fifo_size += plane_extra;
+		fifo_left -= plane_extra;
+	}
+
+	WARN_ON(fifo_left != 0);
+}
+
+static void vlv_invert_wms(struct intel_crtc *crtc)
+{
+	struct vlv_wm_state *wm_state = &crtc->wm_state;
+	int level;
+
+	for (level = 0; level < wm_state->num_levels; level++) {
+		struct drm_device *dev = crtc->base.dev;
+		const int sr_fifo_size = INTEL_INFO(dev)->num_pipes * 512 - 1;
+		struct intel_plane *plane;
+
+		wm_state->sr[level].plane = sr_fifo_size - wm_state->sr[level].plane;
+		wm_state->sr[level].cursor = 63 - wm_state->sr[level].cursor;
+
+		for_each_intel_plane_on_crtc(dev, crtc, plane) {
+			switch (plane->base.type) {
+				int sprite;
+			case DRM_PLANE_TYPE_CURSOR:
+				wm_state->wm[level].cursor = plane->wm.fifo_size -
+					wm_state->wm[level].cursor;
+				break;
+			case DRM_PLANE_TYPE_PRIMARY:
+				wm_state->wm[level].primary = plane->wm.fifo_size -
+					wm_state->wm[level].primary;
+				break;
+			case DRM_PLANE_TYPE_OVERLAY:
+				sprite = plane->plane;
+				wm_state->wm[level].sprite[sprite] = plane->wm.fifo_size -
+					wm_state->wm[level].sprite[sprite];
+				break;
+			}
+		}
+	}
+}
+
+static void vlv_compute_wm(struct intel_crtc *crtc)
+{
+	struct drm_device *dev = crtc->base.dev;
+	struct vlv_wm_state *wm_state = &crtc->wm_state;
+	struct intel_plane *plane;
+	int sr_fifo_size = INTEL_INFO(dev)->num_pipes * 512 - 1;
+	int level;
+
+	memset(wm_state, 0, sizeof(*wm_state));
+
+	wm_state->cxsr = crtc->pipe != PIPE_C && crtc->wm.cxsr_allowed;
+	wm_state->num_levels = to_i915(dev)->wm.max_level + 1;
+
+	wm_state->num_active_planes = 0;
+
+	vlv_compute_fifo(crtc);
+
+	if (wm_state->num_active_planes != 1)
+		wm_state->cxsr = false;
+
+	if (wm_state->cxsr) {
+		for (level = 0; level < wm_state->num_levels; level++) {
+			wm_state->sr[level].plane = sr_fifo_size;
+			wm_state->sr[level].cursor = 63;
+		}
+	}
+
+	for_each_intel_plane_on_crtc(dev, crtc, plane) {
+		struct intel_plane_state *state =
+			to_intel_plane_state(plane->base.state);
+
+		if (!state->visible)
+			continue;
+
+		/* normal watermarks */
+		for (level = 0; level < wm_state->num_levels; level++) {
+			int wm = vlv_compute_wm_level(plane, crtc, state, level);
+			int max_wm = plane->base.type == DRM_PLANE_TYPE_CURSOR ? 63 : 511;
+
+			/* hack */
+			if (WARN_ON(level == 0 && wm > max_wm))
+				wm = max_wm;
+
+			if (wm > plane->wm.fifo_size)
+				break;
+
+			switch (plane->base.type) {
+				int sprite;
+			case DRM_PLANE_TYPE_CURSOR:
+				wm_state->wm[level].cursor = wm;
+				break;
+			case DRM_PLANE_TYPE_PRIMARY:
+				wm_state->wm[level].primary = wm;
+				break;
+			case DRM_PLANE_TYPE_OVERLAY:
+				sprite = plane->plane;
+				wm_state->wm[level].sprite[sprite] = wm;
+				break;
+			}
+		}
+
+		wm_state->num_levels = level;
+
+		if (!wm_state->cxsr)
+			continue;
+
+		/* maxfifo watermarks */
+		switch (plane->base.type) {
+			int sprite, level;
+		case DRM_PLANE_TYPE_CURSOR:
+			for (level = 0; level < wm_state->num_levels; level++)
+				wm_state->sr[level].cursor =
+					wm_state->wm[level].cursor;
+			break;
+		case DRM_PLANE_TYPE_PRIMARY:
+			for (level = 0; level < wm_state->num_levels; level++)
+				wm_state->sr[level].plane =
+					min(wm_state->sr[level].plane,
+					    wm_state->wm[level].primary);
+			break;
+		case DRM_PLANE_TYPE_OVERLAY:
+			sprite = plane->plane;
+			for (level = 0; level < wm_state->num_levels; level++)
+				wm_state->sr[level].plane =
+					min(wm_state->sr[level].plane,
+					    wm_state->wm[level].sprite[sprite]);
+			break;
+		}
+	}
+
+	/* clear any (partially) filled invalid levels */
+	for (level = wm_state->num_levels; level < to_i915(dev)->wm.max_level + 1; level++) {
+		memset(&wm_state->wm[level], 0, sizeof(wm_state->wm[level]));
+		memset(&wm_state->sr[level], 0, sizeof(wm_state->sr[level]));
+	}
+
+	vlv_invert_wms(crtc);
+}
+
+#define VLV_FIFO(plane, value) \
+	(((value) << DSPARB_ ## plane ## _SHIFT_VLV) & DSPARB_ ## plane ## _MASK_VLV)
+
+static void vlv_pipe_set_fifo_size(struct intel_crtc *crtc)
+{
+	struct drm_device *dev = crtc->base.dev;
+	struct drm_i915_private *dev_priv = to_i915(dev);
+	struct intel_plane *plane;
+	int sprite0_start = 0, sprite1_start = 0, fifo_size = 0;
+
+	for_each_intel_plane_on_crtc(dev, crtc, plane) {
+		if (plane->base.type == DRM_PLANE_TYPE_CURSOR) {
+			WARN_ON(plane->wm.fifo_size != 63);
+			continue;
+		}
+
+		if (plane->base.type == DRM_PLANE_TYPE_PRIMARY)
+			sprite0_start = plane->wm.fifo_size;
+		else if (plane->plane == 0)
+			sprite1_start = sprite0_start + plane->wm.fifo_size;
+		else
+			fifo_size = sprite1_start + plane->wm.fifo_size;
+	}
+
+	WARN_ON(fifo_size != 512 - 1);
+
+	DRM_DEBUG_KMS("Pipe %c FIFO split %d / %d / %d\n",
+		      pipe_name(crtc->pipe), sprite0_start,
+		      sprite1_start, fifo_size);
+
+	switch (crtc->pipe) {
+		uint32_t dsparb, dsparb2, dsparb3;
+	case PIPE_A:
+		dsparb = I915_READ(DSPARB);
+		dsparb2 = I915_READ(DSPARB2);
+
+		dsparb &= ~(VLV_FIFO(SPRITEA, 0xff) |
+			    VLV_FIFO(SPRITEB, 0xff));
+		dsparb |= (VLV_FIFO(SPRITEA, sprite0_start) |
+			   VLV_FIFO(SPRITEB, sprite1_start));
+
+		dsparb2 &= ~(VLV_FIFO(SPRITEA_HI, 0x1) |
+			     VLV_FIFO(SPRITEB_HI, 0x1));
+		dsparb2 |= (VLV_FIFO(SPRITEA_HI, sprite0_start >> 8) |
+			   VLV_FIFO(SPRITEB_HI, sprite1_start >> 8));
+
+		I915_WRITE(DSPARB, dsparb);
+		I915_WRITE(DSPARB2, dsparb2);
+		break;
+	case PIPE_B:
+		dsparb = I915_READ(DSPARB);
+		dsparb2 = I915_READ(DSPARB2);
+
+		dsparb &= ~(VLV_FIFO(SPRITEC, 0xff) |
+			    VLV_FIFO(SPRITED, 0xff));
+		dsparb |= (VLV_FIFO(SPRITEC, sprite0_start) |
+			   VLV_FIFO(SPRITED, sprite1_start));
+
+		dsparb2 &= ~(VLV_FIFO(SPRITEC_HI, 0xff) |
+			     VLV_FIFO(SPRITED_HI, 0xff));
+		dsparb2 |= (VLV_FIFO(SPRITEC_HI, sprite0_start >> 8) |
+			   VLV_FIFO(SPRITED_HI, sprite1_start >> 8));
+
+		I915_WRITE(DSPARB, dsparb);
+		I915_WRITE(DSPARB2, dsparb2);
+		break;
+	case PIPE_C:
+		dsparb3 = I915_READ(DSPARB3);
+		dsparb2 = I915_READ(DSPARB2);
+
+		dsparb3 &= ~(VLV_FIFO(SPRITEE, 0xff) |
+			     VLV_FIFO(SPRITEF, 0xff));
+		dsparb3 |= (VLV_FIFO(SPRITEE, sprite0_start) |
+			    VLV_FIFO(SPRITEF, sprite1_start));
+
+		dsparb2 &= ~(VLV_FIFO(SPRITEE_HI, 0xff) |
+			     VLV_FIFO(SPRITEF_HI, 0xff));
+		dsparb2 |= (VLV_FIFO(SPRITEE_HI, sprite0_start >> 8) |
+			   VLV_FIFO(SPRITEF_HI, sprite1_start >> 8));
+
+		I915_WRITE(DSPARB3, dsparb3);
+		I915_WRITE(DSPARB2, dsparb2);
+		break;
+	default:
+		break;
+	}
+}
+
+#undef VLV_FIFO
+
+static void vlv_merge_wm(struct drm_device *dev,
+			 struct vlv_wm_values *wm)
+{
+	struct intel_crtc *crtc;
+	int num_active_crtcs = 0;
+
+	wm->level = to_i915(dev)->wm.max_level;
+	wm->cxsr = true;
+
+	for_each_intel_crtc(dev, crtc) {
+		const struct vlv_wm_state *wm_state = &crtc->wm_state;
+
+		if (!crtc->active)
+			continue;
+
+		if (!wm_state->cxsr)
+			wm->cxsr = false;
+
+		num_active_crtcs++;
+		wm->level = min_t(int, wm->level, wm_state->num_levels - 1);
+	}
+
+	if (num_active_crtcs != 1)
+		wm->cxsr = false;
+
+	if (num_active_crtcs > 1)
+		wm->level = VLV_WM_LEVEL_PM2;
+
+	for_each_intel_crtc(dev, crtc) {
+		struct vlv_wm_state *wm_state = &crtc->wm_state;
+		enum pipe pipe = crtc->pipe;
+
+		if (!crtc->active)
+			continue;
+
+		wm->pipe[pipe] = wm_state->wm[wm->level];
+		if (wm->cxsr)
+			wm->sr = wm_state->sr[wm->level];
+
+		wm->ddl[pipe].primary = DDL_PRECISION_HIGH | 2;
+		wm->ddl[pipe].sprite[0] = DDL_PRECISION_HIGH | 2;
+		wm->ddl[pipe].sprite[1] = DDL_PRECISION_HIGH | 2;
+		wm->ddl[pipe].cursor = DDL_PRECISION_HIGH | 2;
+	}
+}
+
+static void vlv_update_wm(struct drm_crtc *crtc)
+{
+	struct drm_device *dev = crtc->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	enum pipe pipe = intel_crtc->pipe;
+	struct vlv_wm_values wm = {};
+
+	vlv_compute_wm(intel_crtc);
+	vlv_merge_wm(dev, &wm);
+
+	if (memcmp(&dev_priv->wm.vlv, &wm, sizeof(wm)) == 0) {
+		/* FIXME should be part of crtc atomic commit */
+		vlv_pipe_set_fifo_size(intel_crtc);
+		return;
+	}
+
+	if (wm.level < VLV_WM_LEVEL_DDR_DVFS &&
+	    dev_priv->wm.vlv.level >= VLV_WM_LEVEL_DDR_DVFS)
+		chv_set_memory_dvfs(dev_priv, false);
+
+	if (wm.level < VLV_WM_LEVEL_PM5 &&
+	    dev_priv->wm.vlv.level >= VLV_WM_LEVEL_PM5)
+		chv_set_memory_pm5(dev_priv, false);
+
+	if (!wm.cxsr && dev_priv->wm.vlv.cxsr)
+		intel_set_memory_cxsr(dev_priv, false);
+
+	/* FIXME should be part of crtc atomic commit */
+	vlv_pipe_set_fifo_size(intel_crtc);
+
+	vlv_write_wm_values(intel_crtc, &wm);
+
+	DRM_DEBUG_KMS("Setting FIFO watermarks - %c: plane=%d, cursor=%d, "
+		      "sprite0=%d, sprite1=%d, SR: plane=%d, cursor=%d level=%d cxsr=%d\n",
+		      pipe_name(pipe), wm.pipe[pipe].primary, wm.pipe[pipe].cursor,
+		      wm.pipe[pipe].sprite[0], wm.pipe[pipe].sprite[1],
+		      wm.sr.plane, wm.sr.cursor, wm.level, wm.cxsr);
+
+	if (wm.cxsr && !dev_priv->wm.vlv.cxsr)
+		intel_set_memory_cxsr(dev_priv, true);
+
+	if (wm.level >= VLV_WM_LEVEL_PM5 &&
+	    dev_priv->wm.vlv.level < VLV_WM_LEVEL_PM5)
+		chv_set_memory_pm5(dev_priv, true);
+
+	if (wm.level >= VLV_WM_LEVEL_DDR_DVFS &&
+	    dev_priv->wm.vlv.level < VLV_WM_LEVEL_DDR_DVFS)
+		chv_set_memory_dvfs(dev_priv, true);
+
+	dev_priv->wm.vlv = wm;
+}
+
+#define single_plane_enabled(mask) is_power_of_2(mask)
+
+static void g4x_update_wm(struct drm_crtc *crtc)
+{
+	struct drm_device *dev = crtc->dev;
+	static const int sr_latency_ns = 12000;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	int planea_wm, planeb_wm, cursora_wm, cursorb_wm;
+	int plane_sr, cursor_sr;
+	unsigned int enabled = 0;
+	bool cxsr_enabled;
+
+	if (g4x_compute_wm0(dev, PIPE_A,
+			    &g4x_wm_info, pessimal_latency_ns,
+			    &g4x_cursor_wm_info, pessimal_latency_ns,
+			    &planea_wm, &cursora_wm))
+		enabled |= 1 << PIPE_A;
+
+	if (g4x_compute_wm0(dev, PIPE_B,
+			    &g4x_wm_info, pessimal_latency_ns,
+			    &g4x_cursor_wm_info, pessimal_latency_ns,
+			    &planeb_wm, &cursorb_wm))
+		enabled |= 1 << PIPE_B;
+
+	if (single_plane_enabled(enabled) &&
+	    g4x_compute_srwm(dev, ffs(enabled) - 1,
+			     sr_latency_ns,
+			     &g4x_wm_info,
+			     &g4x_cursor_wm_info,
+			     &plane_sr, &cursor_sr)) {
+		cxsr_enabled = true;
+	} else {
+		cxsr_enabled = false;
+		intel_set_memory_cxsr(dev_priv, false);
+		plane_sr = cursor_sr = 0;
+	}
+
+	DRM_DEBUG_KMS("Setting FIFO watermarks - A: plane=%d, cursor=%d, "
+		      "B: plane=%d, cursor=%d, SR: plane=%d, cursor=%d\n",
+		      planea_wm, cursora_wm,
+		      planeb_wm, cursorb_wm,
+		      plane_sr, cursor_sr);
+
+	I915_WRITE(DSPFW1,
+		   FW_WM(plane_sr, SR) |
+		   FW_WM(cursorb_wm, CURSORB) |
+		   FW_WM(planeb_wm, PLANEB) |
+		   FW_WM(planea_wm, PLANEA));
+	I915_WRITE(DSPFW2,
+		   (I915_READ(DSPFW2) & ~DSPFW_CURSORA_MASK) |
+		   FW_WM(cursora_wm, CURSORA));
+	/* HPLL off in SR has some issues on G4x... disable it */
+	I915_WRITE(DSPFW3,
+		   (I915_READ(DSPFW3) & ~(DSPFW_HPLL_SR_EN | DSPFW_CURSOR_SR_MASK)) |
+		   FW_WM(cursor_sr, CURSOR_SR));
+
+	if (cxsr_enabled)
+		intel_set_memory_cxsr(dev_priv, true);
+}
+
+static void i965_update_wm(struct drm_crtc *unused_crtc)
+{
+	struct drm_device *dev = unused_crtc->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct drm_crtc *crtc;
+	int srwm = 1;
+	int cursor_sr = 16;
+	bool cxsr_enabled;
+
+	/* Calc sr entries for one plane configs */
+	crtc = single_enabled_crtc(dev);
+	if (crtc) {
+		/* self-refresh has much higher latency */
+		static const int sr_latency_ns = 12000;
+		const struct drm_display_mode *adjusted_mode = &to_intel_crtc(crtc)->config->base.adjusted_mode;
+		int clock = adjusted_mode->crtc_clock;
+		int htotal = adjusted_mode->crtc_htotal;
+		int hdisplay = to_intel_crtc(crtc)->config->pipe_src_w;
+		int cpp = drm_format_plane_cpp(crtc->primary->state->fb->pixel_format, 0);
+		unsigned long line_time_us;
+		int entries;
+
+		line_time_us = max(htotal * 1000 / clock, 1);
+
+		/* Use ns/us then divide to preserve precision */
+		entries = (((sr_latency_ns / line_time_us) + 1000) / 1000) *
+			cpp * hdisplay;
+		entries = DIV_ROUND_UP(entries, I915_FIFO_LINE_SIZE);
+		srwm = I965_FIFO_SIZE - entries;
+		if (srwm < 0)
+			srwm = 1;
+		srwm &= 0x1ff;
+		DRM_DEBUG_KMS("self-refresh entries: %d, wm: %d\n",
+			      entries, srwm);
+
+		entries = (((sr_latency_ns / line_time_us) + 1000) / 1000) *
+			cpp * crtc->cursor->state->crtc_w;
+		entries = DIV_ROUND_UP(entries,
+					  i965_cursor_wm_info.cacheline_size);
+		cursor_sr = i965_cursor_wm_info.fifo_size -
+			(entries + i965_cursor_wm_info.guard_size);
+
+		if (cursor_sr > i965_cursor_wm_info.max_wm)
+			cursor_sr = i965_cursor_wm_info.max_wm;
+
+		DRM_DEBUG_KMS("self-refresh watermark: display plane %d "
+			      "cursor %d\n", srwm, cursor_sr);
+
+		cxsr_enabled = true;
+	} else {
+		cxsr_enabled = false;
+		/* Turn off self refresh if both pipes are enabled */
+		intel_set_memory_cxsr(dev_priv, false);
+	}
+
+	DRM_DEBUG_KMS("Setting FIFO watermarks - A: 8, B: 8, C: 8, SR %d\n",
+		      srwm);
+
+	/* 965 has limitations... */
+	I915_WRITE(DSPFW1, FW_WM(srwm, SR) |
+		   FW_WM(8, CURSORB) |
+		   FW_WM(8, PLANEB) |
+		   FW_WM(8, PLANEA));
+	I915_WRITE(DSPFW2, FW_WM(8, CURSORA) |
+		   FW_WM(8, PLANEC_OLD));
+	/* update cursor SR watermark */
+	I915_WRITE(DSPFW3, FW_WM(cursor_sr, CURSOR_SR));
+
+	if (cxsr_enabled)
+		intel_set_memory_cxsr(dev_priv, true);
+}
+
+#undef FW_WM
+
+static void i9xx_update_wm(struct drm_crtc *unused_crtc)
+{
+	struct drm_device *dev = unused_crtc->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	const struct intel_watermark_params *wm_info;
+	uint32_t fwater_lo;
+	uint32_t fwater_hi;
+	int cwm, srwm = 1;
+	int fifo_size;
+	int planea_wm, planeb_wm;
+	struct drm_crtc *crtc, *enabled = NULL;
+
+	if (IS_I945GM(dev))
+		wm_info = &i945_wm_info;
+	else if (!IS_GEN2(dev))
+		wm_info = &i915_wm_info;
+	else
+		wm_info = &i830_a_wm_info;
+
+	fifo_size = dev_priv->display.get_fifo_size(dev, 0);
+	crtc = intel_get_crtc_for_plane(dev, 0);
+	if (intel_crtc_active(crtc)) {
+		const struct drm_display_mode *adjusted_mode;
+		int cpp = drm_format_plane_cpp(crtc->primary->state->fb->pixel_format, 0);
+		if (IS_GEN2(dev))
+			cpp = 4;
+
+		adjusted_mode = &to_intel_crtc(crtc)->config->base.adjusted_mode;
+		planea_wm = intel_calculate_wm(adjusted_mode->crtc_clock,
+					       wm_info, fifo_size, cpp,
+					       pessimal_latency_ns);
+		enabled = crtc;
+	} else {
+		planea_wm = fifo_size - wm_info->guard_size;
+		if (planea_wm > (long)wm_info->max_wm)
+			planea_wm = wm_info->max_wm;
+	}
+
+	if (IS_GEN2(dev))
+		wm_info = &i830_bc_wm_info;
+
+	fifo_size = dev_priv->display.get_fifo_size(dev, 1);
+	crtc = intel_get_crtc_for_plane(dev, 1);
+	if (intel_crtc_active(crtc)) {
+		const struct drm_display_mode *adjusted_mode;
+		int cpp = drm_format_plane_cpp(crtc->primary->state->fb->pixel_format, 0);
+		if (IS_GEN2(dev))
+			cpp = 4;
+
+		adjusted_mode = &to_intel_crtc(crtc)->config->base.adjusted_mode;
+		planeb_wm = intel_calculate_wm(adjusted_mode->crtc_clock,
+					       wm_info, fifo_size, cpp,
+					       pessimal_latency_ns);
+		if (enabled == NULL)
+			enabled = crtc;
+		else
+			enabled = NULL;
+	} else {
+		planeb_wm = fifo_size - wm_info->guard_size;
+		if (planeb_wm > (long)wm_info->max_wm)
+			planeb_wm = wm_info->max_wm;
+	}
+
+	DRM_DEBUG_KMS("FIFO watermarks - A: %d, B: %d\n", planea_wm, planeb_wm);
+
+	if (IS_I915GM(dev) && enabled) {
+		struct drm_i915_gem_object *obj;
+
+		obj = intel_fb_obj(enabled->primary->state->fb);
+
+		/* self-refresh seems busted with untiled */
+		if (obj->tiling_mode == I915_TILING_NONE)
+			enabled = NULL;
+	}
+
+	/*
+	 * Overlay gets an aggressive default since video jitter is bad.
+	 */
+	cwm = 2;
+
+	/* Play safe and disable self-refresh before adjusting watermarks. */
+	intel_set_memory_cxsr(dev_priv, false);
+
+	/* Calc sr entries for one plane configs */
+	if (HAS_FW_BLC(dev) && enabled) {
+		/* self-refresh has much higher latency */
+		static const int sr_latency_ns = 6000;
+		const struct drm_display_mode *adjusted_mode = &to_intel_crtc(enabled)->config->base.adjusted_mode;
+		int clock = adjusted_mode->crtc_clock;
+		int htotal = adjusted_mode->crtc_htotal;
+		int hdisplay = to_intel_crtc(enabled)->config->pipe_src_w;
+		int cpp = drm_format_plane_cpp(enabled->primary->state->fb->pixel_format, 0);
+		unsigned long line_time_us;
+		int entries;
+
+		line_time_us = max(htotal * 1000 / clock, 1);
+
+		/* Use ns/us then divide to preserve precision */
+		entries = (((sr_latency_ns / line_time_us) + 1000) / 1000) *
+			cpp * hdisplay;
+		entries = DIV_ROUND_UP(entries, wm_info->cacheline_size);
+		DRM_DEBUG_KMS("self-refresh entries: %d\n", entries);
+		srwm = wm_info->fifo_size - entries;
+		if (srwm < 0)
+			srwm = 1;
+
+		if (IS_I945G(dev) || IS_I945GM(dev))
+			I915_WRITE(FW_BLC_SELF,
+				   FW_BLC_SELF_FIFO_MASK | (srwm & 0xff));
+		else if (IS_I915GM(dev))
+			I915_WRITE(FW_BLC_SELF, srwm & 0x3f);
+	}
+
+	DRM_DEBUG_KMS("Setting FIFO watermarks - A: %d, B: %d, C: %d, SR %d\n",
+		      planea_wm, planeb_wm, cwm, srwm);
+
+	fwater_lo = ((planeb_wm & 0x3f) << 16) | (planea_wm & 0x3f);
+	fwater_hi = (cwm & 0x1f);
+
+	/* Set request length to 8 cachelines per fetch */
+	fwater_lo = fwater_lo | (1 << 24) | (1 << 8);
+	fwater_hi = fwater_hi | (1 << 8);
+
+	I915_WRITE(FW_BLC, fwater_lo);
+	I915_WRITE(FW_BLC2, fwater_hi);
+
+	if (enabled)
+		intel_set_memory_cxsr(dev_priv, true);
+}
+
+static void i845_update_wm(struct drm_crtc *unused_crtc)
+{
+	struct drm_device *dev = unused_crtc->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct drm_crtc *crtc;
+	const struct drm_display_mode *adjusted_mode;
+	uint32_t fwater_lo;
+	int planea_wm;
+
+	crtc = single_enabled_crtc(dev);
+	if (crtc == NULL)
+		return;
+
+	adjusted_mode = &to_intel_crtc(crtc)->config->base.adjusted_mode;
+	planea_wm = intel_calculate_wm(adjusted_mode->crtc_clock,
+				       &i845_wm_info,
+				       dev_priv->display.get_fifo_size(dev, 0),
+				       4, pessimal_latency_ns);
+	fwater_lo = I915_READ(FW_BLC) & ~0xfff;
+	fwater_lo |= (3<<8) | planea_wm;
+
+	DRM_DEBUG_KMS("Setting FIFO watermarks - A: %d\n", planea_wm);
+
+	I915_WRITE(FW_BLC, fwater_lo);
+}
+
+uint32_t ilk_pipe_pixel_rate(const struct intel_crtc_state *pipe_config)
+{
+	uint32_t pixel_rate;
+
+	pixel_rate = pipe_config->base.adjusted_mode.crtc_clock;
+
+	/* We only use IF-ID interlacing. If we ever use PF-ID we'll need to
+	 * adjust the pixel_rate here. */
+
+	if (pipe_config->pch_pfit.enabled) {
+		uint64_t pipe_w, pipe_h, pfit_w, pfit_h;
+		uint32_t pfit_size = pipe_config->pch_pfit.size;
+
+		pipe_w = pipe_config->pipe_src_w;
+		pipe_h = pipe_config->pipe_src_h;
+
+		pfit_w = (pfit_size >> 16) & 0xFFFF;
+		pfit_h = pfit_size & 0xFFFF;
+		if (pipe_w < pfit_w)
+			pipe_w = pfit_w;
+		if (pipe_h < pfit_h)
+			pipe_h = pfit_h;
+
+		if (WARN_ON(!pfit_w || !pfit_h))
+			return pixel_rate;
+
+		pixel_rate = div_u64((uint64_t) pixel_rate * pipe_w * pipe_h,
+				     pfit_w * pfit_h);
+	}
+
+	return pixel_rate;
+}
+
+/* latency must be in 0.1us units. */
+static uint32_t ilk_wm_method1(uint32_t pixel_rate, uint8_t cpp, uint32_t latency)
+{
+	uint64_t ret;
+
+	if (WARN(latency == 0, "Latency value missing\n"))
+		return UINT_MAX;
+
+	ret = (uint64_t) pixel_rate * cpp * latency;
+	ret = DIV_ROUND_UP_ULL(ret, 64 * 10000) + 2;
+
+	return ret;
+}
+
+/* latency must be in 0.1us units. */
+static uint32_t ilk_wm_method2(uint32_t pixel_rate, uint32_t pipe_htotal,
+			       uint32_t horiz_pixels, uint8_t cpp,
+			       uint32_t latency)
+{
+	uint32_t ret;
+
+	if (WARN(latency == 0, "Latency value missing\n"))
+		return UINT_MAX;
+	if (WARN_ON(!pipe_htotal))
+		return UINT_MAX;
+
+	ret = (latency * pixel_rate) / (pipe_htotal * 10000);
+	ret = (ret + 1) * horiz_pixels * cpp;
+	ret = DIV_ROUND_UP(ret, 64) + 2;
+	return ret;
+}
+
+static uint32_t ilk_wm_fbc(uint32_t pri_val, uint32_t horiz_pixels,
+			   uint8_t cpp)
+{
+	/*
+	 * Neither of these should be possible since this function shouldn't be
+	 * called if the CRTC is off or the plane is invisible.  But let's be
+	 * extra paranoid to avoid a potential divide-by-zero if we screw up
+	 * elsewhere in the driver.
+	 */
+	if (WARN_ON(!cpp))
+		return 0;
+	if (WARN_ON(!horiz_pixels))
+		return 0;
+
+	return DIV_ROUND_UP(pri_val * 64, horiz_pixels * cpp) + 2;
+}
+
+struct ilk_wm_maximums {
+	uint16_t pri;
+	uint16_t spr;
+	uint16_t cur;
+	uint16_t fbc;
+};
+
+/*
+ * For both WM_PIPE and WM_LP.
+ * mem_value must be in 0.1us units.
+ */
+static uint32_t ilk_compute_pri_wm(const struct intel_crtc_state *cstate,
+				   const struct intel_plane_state *pstate,
+				   uint32_t mem_value,
+				   bool is_lp)
+{
+	int cpp = pstate->base.fb ?
+		drm_format_plane_cpp(pstate->base.fb->pixel_format, 0) : 0;
+	uint32_t method1, method2;
+
+	if (!cstate->base.active || !pstate->visible)
+		return 0;
+
+	method1 = ilk_wm_method1(ilk_pipe_pixel_rate(cstate), cpp, mem_value);
+
+	if (!is_lp)
+		return method1;
+
+	method2 = ilk_wm_method2(ilk_pipe_pixel_rate(cstate),
+				 cstate->base.adjusted_mode.crtc_htotal,
+				 drm_rect_width(&pstate->dst),
+				 cpp, mem_value);
+
+	return min(method1, method2);
+}
+
+/*
+ * For both WM_PIPE and WM_LP.
+ * mem_value must be in 0.1us units.
+ */
+static uint32_t ilk_compute_spr_wm(const struct intel_crtc_state *cstate,
+				   const struct intel_plane_state *pstate,
+				   uint32_t mem_value)
+{
+	int cpp = pstate->base.fb ?
+		drm_format_plane_cpp(pstate->base.fb->pixel_format, 0) : 0;
+	uint32_t method1, method2;
+
+	if (!cstate->base.active || !pstate->visible)
+		return 0;
+
+	method1 = ilk_wm_method1(ilk_pipe_pixel_rate(cstate), cpp, mem_value);
+	method2 = ilk_wm_method2(ilk_pipe_pixel_rate(cstate),
+				 cstate->base.adjusted_mode.crtc_htotal,
+				 drm_rect_width(&pstate->dst),
+				 cpp, mem_value);
+	return min(method1, method2);
+}
+
+/*
+ * For both WM_PIPE and WM_LP.
+ * mem_value must be in 0.1us units.
+ */
+static uint32_t ilk_compute_cur_wm(const struct intel_crtc_state *cstate,
+				   const struct intel_plane_state *pstate,
+				   uint32_t mem_value)
+{
+	/*
+	 * We treat the cursor plane as always-on for the purposes of watermark
+	 * calculation.  Until we have two-stage watermark programming merged,
+	 * this is necessary to avoid flickering.
+	 */
+	int cpp = 4;
+	int width = pstate->visible ? pstate->base.crtc_w : 64;
+
+	if (!cstate->base.active)
+		return 0;
+
+	return ilk_wm_method2(ilk_pipe_pixel_rate(cstate),
+			      cstate->base.adjusted_mode.crtc_htotal,
+			      width, cpp, mem_value);
+}
+
+/* Only for WM_LP. */
+static uint32_t ilk_compute_fbc_wm(const struct intel_crtc_state *cstate,
+				   const struct intel_plane_state *pstate,
+				   uint32_t pri_val)
+{
+	int cpp = pstate->base.fb ?
+		drm_format_plane_cpp(pstate->base.fb->pixel_format, 0) : 0;
+
+	if (!cstate->base.active || !pstate->visible)
+		return 0;
+
+	return ilk_wm_fbc(pri_val, drm_rect_width(&pstate->dst), cpp);
+}
+
+static unsigned int ilk_display_fifo_size(const struct drm_device *dev)
+{
+	if (INTEL_INFO(dev)->gen >= 8)
+		return 3072;
+	else if (INTEL_INFO(dev)->gen >= 7)
+		return 768;
+	else
+		return 512;
+}
+
+static unsigned int ilk_plane_wm_reg_max(const struct drm_device *dev,
+					 int level, bool is_sprite)
+{
+	if (INTEL_INFO(dev)->gen >= 8)
+		/* BDW primary/sprite plane watermarks */
+		return level == 0 ? 255 : 2047;
+	else if (INTEL_INFO(dev)->gen >= 7)
+		/* IVB/HSW primary/sprite plane watermarks */
+		return level == 0 ? 127 : 1023;
+	else if (!is_sprite)
+		/* ILK/SNB primary plane watermarks */
+		return level == 0 ? 127 : 511;
+	else
+		/* ILK/SNB sprite plane watermarks */
+		return level == 0 ? 63 : 255;
+}
+
+static unsigned int ilk_cursor_wm_reg_max(const struct drm_device *dev,
+					  int level)
+{
+	if (INTEL_INFO(dev)->gen >= 7)
+		return level == 0 ? 63 : 255;
+	else
+		return level == 0 ? 31 : 63;
+}
+
+static unsigned int ilk_fbc_wm_reg_max(const struct drm_device *dev)
+{
+	if (INTEL_INFO(dev)->gen >= 8)
+		return 31;
+	else
+		return 15;
+}
+
+/* Calculate the maximum primary/sprite plane watermark */
+static unsigned int ilk_plane_wm_max(const struct drm_device *dev,
+				     int level,
+				     const struct intel_wm_config *config,
+				     enum intel_ddb_partitioning ddb_partitioning,
+				     bool is_sprite)
+{
+	unsigned int fifo_size = ilk_display_fifo_size(dev);
+
+	/* if sprites aren't enabled, sprites get nothing */
+	if (is_sprite && !config->sprites_enabled)
+		return 0;
+
+	/* HSW allows LP1+ watermarks even with multiple pipes */
+	if (level == 0 || config->num_pipes_active > 1) {
+		fifo_size /= INTEL_INFO(dev)->num_pipes;
+
+		/*
+		 * For some reason the non self refresh
+		 * FIFO size is only half of the self
+		 * refresh FIFO size on ILK/SNB.
+		 */
+		if (INTEL_INFO(dev)->gen <= 6)
+			fifo_size /= 2;
+	}
+
+	if (config->sprites_enabled) {
+		/* level 0 is always calculated with 1:1 split */
+		if (level > 0 && ddb_partitioning == INTEL_DDB_PART_5_6) {
+			if (is_sprite)
+				fifo_size *= 5;
+			fifo_size /= 6;
+		} else {
+			fifo_size /= 2;
+		}
+	}
+
+	/* clamp to max that the registers can hold */
+	return min(fifo_size, ilk_plane_wm_reg_max(dev, level, is_sprite));
+}
+
+/* Calculate the maximum cursor plane watermark */
+static unsigned int ilk_cursor_wm_max(const struct drm_device *dev,
+				      int level,
+				      const struct intel_wm_config *config)
+{
+	/* HSW LP1+ watermarks w/ multiple pipes */
+	if (level > 0 && config->num_pipes_active > 1)
+		return 64;
+
+	/* otherwise just report max that registers can hold */
+	return ilk_cursor_wm_reg_max(dev, level);
+}
+
+static void ilk_compute_wm_maximums(const struct drm_device *dev,
+				    int level,
+				    const struct intel_wm_config *config,
+				    enum intel_ddb_partitioning ddb_partitioning,
+				    struct ilk_wm_maximums *max)
+{
+	max->pri = ilk_plane_wm_max(dev, level, config, ddb_partitioning, false);
+	max->spr = ilk_plane_wm_max(dev, level, config, ddb_partitioning, true);
+	max->cur = ilk_cursor_wm_max(dev, level, config);
+	max->fbc = ilk_fbc_wm_reg_max(dev);
+}
+
+static void ilk_compute_wm_reg_maximums(struct drm_device *dev,
+					int level,
+					struct ilk_wm_maximums *max)
+{
+	max->pri = ilk_plane_wm_reg_max(dev, level, false);
+	max->spr = ilk_plane_wm_reg_max(dev, level, true);
+	max->cur = ilk_cursor_wm_reg_max(dev, level);
+	max->fbc = ilk_fbc_wm_reg_max(dev);
+}
+
+static bool ilk_validate_wm_level(int level,
+				  const struct ilk_wm_maximums *max,
+				  struct intel_wm_level *result)
+{
+	bool ret;
+
+	/* already determined to be invalid? */
+	if (!result->enable)
+		return false;
+
+	result->enable = result->pri_val <= max->pri &&
+			 result->spr_val <= max->spr &&
+			 result->cur_val <= max->cur;
+
+	ret = result->enable;
+
+	/*
+	 * HACK until we can pre-compute everything,
+	 * and thus fail gracefully if LP0 watermarks
+	 * are exceeded...
+	 */
+	if (level == 0 && !result->enable) {
+		if (result->pri_val > max->pri)
+			DRM_DEBUG_KMS("Primary WM%d too large %u (max %u)\n",
+				      level, result->pri_val, max->pri);
+		if (result->spr_val > max->spr)
+			DRM_DEBUG_KMS("Sprite WM%d too large %u (max %u)\n",
+				      level, result->spr_val, max->spr);
+		if (result->cur_val > max->cur)
+			DRM_DEBUG_KMS("Cursor WM%d too large %u (max %u)\n",
+				      level, result->cur_val, max->cur);
+
+		result->pri_val = min_t(uint32_t, result->pri_val, max->pri);
+		result->spr_val = min_t(uint32_t, result->spr_val, max->spr);
+		result->cur_val = min_t(uint32_t, result->cur_val, max->cur);
+		result->enable = true;
+	}
+
+	return ret;
+}
+
+static void ilk_compute_wm_level(const struct drm_i915_private *dev_priv,
+				 const struct intel_crtc *intel_crtc,
+				 int level,
+				 struct intel_crtc_state *cstate,
+				 struct intel_plane_state *pristate,
+				 struct intel_plane_state *sprstate,
+				 struct intel_plane_state *curstate,
+				 struct intel_wm_level *result)
+{
+	uint16_t pri_latency = dev_priv->wm.pri_latency[level];
+	uint16_t spr_latency = dev_priv->wm.spr_latency[level];
+	uint16_t cur_latency = dev_priv->wm.cur_latency[level];
+
+	/* WM1+ latency values stored in 0.5us units */
+	if (level > 0) {
+		pri_latency *= 5;
+		spr_latency *= 5;
+		cur_latency *= 5;
+	}
+
+	if (pristate) {
+		result->pri_val = ilk_compute_pri_wm(cstate, pristate,
+						     pri_latency, level);
+		result->fbc_val = ilk_compute_fbc_wm(cstate, pristate, result->pri_val);
+	}
+
+	if (sprstate)
+		result->spr_val = ilk_compute_spr_wm(cstate, sprstate, spr_latency);
+
+	if (curstate)
+		result->cur_val = ilk_compute_cur_wm(cstate, curstate, cur_latency);
+
+	result->enable = true;
+}
+
+static uint32_t
+hsw_compute_linetime_wm(struct drm_device *dev,
+			struct intel_crtc_state *cstate)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	const struct drm_display_mode *adjusted_mode =
+		&cstate->base.adjusted_mode;
+	u32 linetime, ips_linetime;
+
+	if (!cstate->base.active)
+		return 0;
+	if (WARN_ON(adjusted_mode->crtc_clock == 0))
+		return 0;
+	if (WARN_ON(dev_priv->cdclk_freq == 0))
+		return 0;
+
+	/* The WM are computed with base on how long it takes to fill a single
+	 * row at the given clock rate, multiplied by 8.
+	 * */
+	linetime = DIV_ROUND_CLOSEST(adjusted_mode->crtc_htotal * 1000 * 8,
+				     adjusted_mode->crtc_clock);
+	ips_linetime = DIV_ROUND_CLOSEST(adjusted_mode->crtc_htotal * 1000 * 8,
+					 dev_priv->cdclk_freq);
+
+	return PIPE_WM_LINETIME_IPS_LINETIME(ips_linetime) |
+	       PIPE_WM_LINETIME_TIME(linetime);
+}
+
+static void intel_read_wm_latency(struct drm_device *dev, uint16_t wm[8])
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	if (IS_GEN9(dev)) {
+		uint32_t val;
+		int ret, i;
+		int level, max_level = ilk_wm_max_level(dev);
+
+		/* read the first set of memory latencies[0:3] */
+		val = 0; /* data0 to be programmed to 0 for first set */
+		mutex_lock(&dev_priv->rps.hw_lock);
+		ret = sandybridge_pcode_read(dev_priv,
+					     GEN9_PCODE_READ_MEM_LATENCY,
+					     &val);
+		mutex_unlock(&dev_priv->rps.hw_lock);
+
+		if (ret) {
+			DRM_ERROR("SKL Mailbox read error = %d\n", ret);
+			return;
+		}
+
+		wm[0] = val & GEN9_MEM_LATENCY_LEVEL_MASK;
+		wm[1] = (val >> GEN9_MEM_LATENCY_LEVEL_1_5_SHIFT) &
+				GEN9_MEM_LATENCY_LEVEL_MASK;
+		wm[2] = (val >> GEN9_MEM_LATENCY_LEVEL_2_6_SHIFT) &
+				GEN9_MEM_LATENCY_LEVEL_MASK;
+		wm[3] = (val >> GEN9_MEM_LATENCY_LEVEL_3_7_SHIFT) &
+				GEN9_MEM_LATENCY_LEVEL_MASK;
+
+		/* read the second set of memory latencies[4:7] */
+		val = 1; /* data0 to be programmed to 1 for second set */
+		mutex_lock(&dev_priv->rps.hw_lock);
+		ret = sandybridge_pcode_read(dev_priv,
+					     GEN9_PCODE_READ_MEM_LATENCY,
+					     &val);
+		mutex_unlock(&dev_priv->rps.hw_lock);
+		if (ret) {
+			DRM_ERROR("SKL Mailbox read error = %d\n", ret);
+			return;
+		}
+
+		wm[4] = val & GEN9_MEM_LATENCY_LEVEL_MASK;
+		wm[5] = (val >> GEN9_MEM_LATENCY_LEVEL_1_5_SHIFT) &
+				GEN9_MEM_LATENCY_LEVEL_MASK;
+		wm[6] = (val >> GEN9_MEM_LATENCY_LEVEL_2_6_SHIFT) &
+				GEN9_MEM_LATENCY_LEVEL_MASK;
+		wm[7] = (val >> GEN9_MEM_LATENCY_LEVEL_3_7_SHIFT) &
+				GEN9_MEM_LATENCY_LEVEL_MASK;
+
+		/*
+		 * WaWmMemoryReadLatency:skl
+		 *
+		 * punit doesn't take into account the read latency so we need
+		 * to add 2us to the various latency levels we retrieve from
+		 * the punit.
+		 *   - W0 is a bit special in that it's the only level that
+		 *   can't be disabled if we want to have display working, so
+		 *   we always add 2us there.
+		 *   - For levels >=1, punit returns 0us latency when they are
+		 *   disabled, so we respect that and don't add 2us then
+		 *
+		 * Additionally, if a level n (n > 1) has a 0us latency, all
+		 * levels m (m >= n) need to be disabled. We make sure to
+		 * sanitize the values out of the punit to satisfy this
+		 * requirement.
+		 */
+		wm[0] += 2;
+		for (level = 1; level <= max_level; level++)
+			if (wm[level] != 0)
+				wm[level] += 2;
+			else {
+				for (i = level + 1; i <= max_level; i++)
+					wm[i] = 0;
+
+				break;
+			}
+	} else if (IS_HASWELL(dev) || IS_BROADWELL(dev)) {
+		uint64_t sskpd = I915_READ64(MCH_SSKPD);
+
+		wm[0] = (sskpd >> 56) & 0xFF;
+		if (wm[0] == 0)
+			wm[0] = sskpd & 0xF;
+		wm[1] = (sskpd >> 4) & 0xFF;
+		wm[2] = (sskpd >> 12) & 0xFF;
+		wm[3] = (sskpd >> 20) & 0x1FF;
+		wm[4] = (sskpd >> 32) & 0x1FF;
+	} else if (INTEL_INFO(dev)->gen >= 6) {
+		uint32_t sskpd = I915_READ(MCH_SSKPD);
+
+		wm[0] = (sskpd >> SSKPD_WM0_SHIFT) & SSKPD_WM_MASK;
+		wm[1] = (sskpd >> SSKPD_WM1_SHIFT) & SSKPD_WM_MASK;
+		wm[2] = (sskpd >> SSKPD_WM2_SHIFT) & SSKPD_WM_MASK;
+		wm[3] = (sskpd >> SSKPD_WM3_SHIFT) & SSKPD_WM_MASK;
+	} else if (INTEL_INFO(dev)->gen >= 5) {
+		uint32_t mltr = I915_READ(MLTR_ILK);
+
+		/* ILK primary LP0 latency is 700 ns */
+		wm[0] = 7;
+		wm[1] = (mltr >> MLTR_WM1_SHIFT) & ILK_SRLT_MASK;
+		wm[2] = (mltr >> MLTR_WM2_SHIFT) & ILK_SRLT_MASK;
+	}
+}
+
+static void intel_fixup_spr_wm_latency(struct drm_device *dev, uint16_t wm[5])
+{
+	/* ILK sprite LP0 latency is 1300 ns */
+	if (INTEL_INFO(dev)->gen == 5)
+		wm[0] = 13;
+}
+
+static void intel_fixup_cur_wm_latency(struct drm_device *dev, uint16_t wm[5])
+{
+	/* ILK cursor LP0 latency is 1300 ns */
+	if (INTEL_INFO(dev)->gen == 5)
+		wm[0] = 13;
+
+	/* WaDoubleCursorLP3Latency:ivb */
+	if (IS_IVYBRIDGE(dev))
+		wm[3] *= 2;
+}
+
+int ilk_wm_max_level(const struct drm_device *dev)
+{
+	/* how many WM levels are we expecting */
+	if (INTEL_INFO(dev)->gen >= 9)
+		return 7;
+	else if (IS_HASWELL(dev) || IS_BROADWELL(dev))
+		return 4;
+	else if (INTEL_INFO(dev)->gen >= 6)
+		return 3;
+	else
+		return 2;
+}
+
+static void intel_print_wm_latency(struct drm_device *dev,
+				   const char *name,
+				   const uint16_t wm[8])
+{
+	int level, max_level = ilk_wm_max_level(dev);
+
+	for (level = 0; level <= max_level; level++) {
+		unsigned int latency = wm[level];
+
+		if (latency == 0) {
+			DRM_ERROR("%s WM%d latency not provided\n",
+				  name, level);
+			continue;
+		}
+
+		/*
+		 * - latencies are in us on gen9.
+		 * - before then, WM1+ latency values are in 0.5us units
+		 */
+		if (IS_GEN9(dev))
+			latency *= 10;
+		else if (level > 0)
+			latency *= 5;
+
+		DRM_DEBUG_KMS("%s WM%d latency %u (%u.%u usec)\n",
+			      name, level, wm[level],
+			      latency / 10, latency % 10);
+	}
+}
+
+static bool ilk_increase_wm_latency(struct drm_i915_private *dev_priv,
+				    uint16_t wm[5], uint16_t min)
+{
+	int level, max_level = ilk_wm_max_level(dev_priv->dev);
+
+	if (wm[0] >= min)
+		return false;
+
+	wm[0] = max(wm[0], min);
+	for (level = 1; level <= max_level; level++)
+		wm[level] = max_t(uint16_t, wm[level], DIV_ROUND_UP(min, 5));
+
+	return true;
+}
+
+static void snb_wm_latency_quirk(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	bool changed;
+
+	/*
+	 * The BIOS provided WM memory latency values are often
+	 * inadequate for high resolution displays. Adjust them.
+	 */
+	changed = ilk_increase_wm_latency(dev_priv, dev_priv->wm.pri_latency, 12) |
+		ilk_increase_wm_latency(dev_priv, dev_priv->wm.spr_latency, 12) |
+		ilk_increase_wm_latency(dev_priv, dev_priv->wm.cur_latency, 12);
+
+	if (!changed)
+		return;
+
+	DRM_DEBUG_KMS("WM latency values increased to avoid potential underruns\n");
+	intel_print_wm_latency(dev, "Primary", dev_priv->wm.pri_latency);
+	intel_print_wm_latency(dev, "Sprite", dev_priv->wm.spr_latency);
+	intel_print_wm_latency(dev, "Cursor", dev_priv->wm.cur_latency);
+}
+
+static void ilk_setup_wm_latency(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	intel_read_wm_latency(dev, dev_priv->wm.pri_latency);
+
+	memcpy(dev_priv->wm.spr_latency, dev_priv->wm.pri_latency,
+	       sizeof(dev_priv->wm.pri_latency));
+	memcpy(dev_priv->wm.cur_latency, dev_priv->wm.pri_latency,
+	       sizeof(dev_priv->wm.pri_latency));
+
+	intel_fixup_spr_wm_latency(dev, dev_priv->wm.spr_latency);
+	intel_fixup_cur_wm_latency(dev, dev_priv->wm.cur_latency);
+
+	intel_print_wm_latency(dev, "Primary", dev_priv->wm.pri_latency);
+	intel_print_wm_latency(dev, "Sprite", dev_priv->wm.spr_latency);
+	intel_print_wm_latency(dev, "Cursor", dev_priv->wm.cur_latency);
+
+	if (IS_GEN6(dev))
+		snb_wm_latency_quirk(dev);
+}
+
+static void skl_setup_wm_latency(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	intel_read_wm_latency(dev, dev_priv->wm.skl_latency);
+	intel_print_wm_latency(dev, "Gen9 Plane", dev_priv->wm.skl_latency);
+}
+
+static bool ilk_validate_pipe_wm(struct drm_device *dev,
+				 struct intel_pipe_wm *pipe_wm)
+{
+	/* LP0 watermark maximums depend on this pipe alone */
+	const struct intel_wm_config config = {
+		.num_pipes_active = 1,
+		.sprites_enabled = pipe_wm->sprites_enabled,
+		.sprites_scaled = pipe_wm->sprites_scaled,
+	};
+	struct ilk_wm_maximums max;
+
+	/* LP0 watermarks always use 1/2 DDB partitioning */
+	ilk_compute_wm_maximums(dev, 0, &config, INTEL_DDB_PART_1_2, &max);
+
+	/* At least LP0 must be valid */
+	if (!ilk_validate_wm_level(0, &max, &pipe_wm->wm[0])) {
+		DRM_DEBUG_KMS("LP0 watermark invalid\n");
+		return false;
+	}
+
+	return true;
+}
+
+/* Compute new watermarks for the pipe */
+static int ilk_compute_pipe_wm(struct intel_crtc_state *cstate)
+{
+	struct drm_atomic_state *state = cstate->base.state;
+	struct intel_crtc *intel_crtc = to_intel_crtc(cstate->base.crtc);
+	struct intel_pipe_wm *pipe_wm;
+	struct drm_device *dev = state->dev;
+	const struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_plane *intel_plane;
+	struct intel_plane_state *pristate = NULL;
+	struct intel_plane_state *sprstate = NULL;
+	struct intel_plane_state *curstate = NULL;
+	int level, max_level = ilk_wm_max_level(dev), usable_level;
+	struct ilk_wm_maximums max;
+
+	pipe_wm = &cstate->wm.optimal.ilk;
+
+	for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane) {
+		struct intel_plane_state *ps;
+
+		ps = intel_atomic_get_existing_plane_state(state,
+							   intel_plane);
+		if (!ps)
+			continue;
+
+		if (intel_plane->base.type == DRM_PLANE_TYPE_PRIMARY)
+			pristate = ps;
+		else if (intel_plane->base.type == DRM_PLANE_TYPE_OVERLAY)
+			sprstate = ps;
+		else if (intel_plane->base.type == DRM_PLANE_TYPE_CURSOR)
+			curstate = ps;
+	}
+
+	pipe_wm->pipe_enabled = cstate->base.active;
+	if (sprstate) {
+		pipe_wm->sprites_enabled = sprstate->visible;
+		pipe_wm->sprites_scaled = sprstate->visible &&
+			(drm_rect_width(&sprstate->dst) != drm_rect_width(&sprstate->src) >> 16 ||
+			 drm_rect_height(&sprstate->dst) != drm_rect_height(&sprstate->src) >> 16);
+	}
+
+	usable_level = max_level;
+
+	/* ILK/SNB: LP2+ watermarks only w/o sprites */
+	if (INTEL_INFO(dev)->gen <= 6 && pipe_wm->sprites_enabled)
+		usable_level = 1;
+
+	/* ILK/SNB/IVB: LP1+ watermarks only w/o scaling */
+	if (pipe_wm->sprites_scaled)
+		usable_level = 0;
+
+	ilk_compute_wm_level(dev_priv, intel_crtc, 0, cstate,
+			     pristate, sprstate, curstate, &pipe_wm->raw_wm[0]);
+
+	memset(&pipe_wm->wm, 0, sizeof(pipe_wm->wm));
+	pipe_wm->wm[0] = pipe_wm->raw_wm[0];
+
+	if (IS_HASWELL(dev) || IS_BROADWELL(dev))
+		pipe_wm->linetime = hsw_compute_linetime_wm(dev, cstate);
+
+	if (!ilk_validate_pipe_wm(dev, pipe_wm))
+		return -EINVAL;
+
+	ilk_compute_wm_reg_maximums(dev, 1, &max);
+
+	for (level = 1; level <= max_level; level++) {
+		struct intel_wm_level *wm = &pipe_wm->raw_wm[level];
+
+		ilk_compute_wm_level(dev_priv, intel_crtc, level, cstate,
+				     pristate, sprstate, curstate, wm);
+
+		/*
+		 * Disable any watermark level that exceeds the
+		 * register maximums since such watermarks are
+		 * always invalid.
+		 */
+		if (level > usable_level)
+			continue;
+
+		if (ilk_validate_wm_level(level, &max, wm))
+			pipe_wm->wm[level] = *wm;
+		else
+			usable_level = level;
+	}
+
+	return 0;
+}
+
+/*
+ * Build a set of 'intermediate' watermark values that satisfy both the old
+ * state and the new state.  These can be programmed to the hardware
+ * immediately.
+ */
+static int ilk_compute_intermediate_wm(struct drm_device *dev,
+				       struct intel_crtc *intel_crtc,
+				       struct intel_crtc_state *newstate)
+{
+	struct intel_pipe_wm *a = &newstate->wm.intermediate;
+	struct intel_pipe_wm *b = &intel_crtc->wm.active.ilk;
+	int level, max_level = ilk_wm_max_level(dev);
+
+	/*
+	 * Start with the final, target watermarks, then combine with the
+	 * currently active watermarks to get values that are safe both before
+	 * and after the vblank.
+	 */
+	*a = newstate->wm.optimal.ilk;
+	a->pipe_enabled |= b->pipe_enabled;
+	a->sprites_enabled |= b->sprites_enabled;
+	a->sprites_scaled |= b->sprites_scaled;
+
+	for (level = 0; level <= max_level; level++) {
+		struct intel_wm_level *a_wm = &a->wm[level];
+		const struct intel_wm_level *b_wm = &b->wm[level];
+
+		a_wm->enable &= b_wm->enable;
+		a_wm->pri_val = max(a_wm->pri_val, b_wm->pri_val);
+		a_wm->spr_val = max(a_wm->spr_val, b_wm->spr_val);
+		a_wm->cur_val = max(a_wm->cur_val, b_wm->cur_val);
+		a_wm->fbc_val = max(a_wm->fbc_val, b_wm->fbc_val);
+	}
+
+	/*
+	 * We need to make sure that these merged watermark values are
+	 * actually a valid configuration themselves.  If they're not,
+	 * there's no safe way to transition from the old state to
+	 * the new state, so we need to fail the atomic transaction.
+	 */
+	if (!ilk_validate_pipe_wm(dev, a))
+		return -EINVAL;
+
+	/*
+	 * If our intermediate WM are identical to the final WM, then we can
+	 * omit the post-vblank programming; only update if it's different.
+	 */
+	if (memcmp(a, &newstate->wm.optimal.ilk, sizeof(*a)) == 0)
+		newstate->wm.need_postvbl_update = false;
+
+	return 0;
+}
+
+/*
+ * Merge the watermarks from all active pipes for a specific level.
+ */
+static void ilk_merge_wm_level(struct drm_device *dev,
+			       int level,
+			       struct intel_wm_level *ret_wm)
+{
+	const struct intel_crtc *intel_crtc;
+
+	ret_wm->enable = true;
+
+	for_each_intel_crtc(dev, intel_crtc) {
+		const struct intel_pipe_wm *active = &intel_crtc->wm.active.ilk;
+		const struct intel_wm_level *wm = &active->wm[level];
+
+		if (!active->pipe_enabled)
+			continue;
+
+		/*
+		 * The watermark values may have been used in the past,
+		 * so we must maintain them in the registers for some
+		 * time even if the level is now disabled.
+		 */
+		if (!wm->enable)
+			ret_wm->enable = false;
+
+		ret_wm->pri_val = max(ret_wm->pri_val, wm->pri_val);
+		ret_wm->spr_val = max(ret_wm->spr_val, wm->spr_val);
+		ret_wm->cur_val = max(ret_wm->cur_val, wm->cur_val);
+		ret_wm->fbc_val = max(ret_wm->fbc_val, wm->fbc_val);
+	}
+}
+
+/*
+ * Merge all low power watermarks for all active pipes.
+ */
+static void ilk_wm_merge(struct drm_device *dev,
+			 const struct intel_wm_config *config,
+			 const struct ilk_wm_maximums *max,
+			 struct intel_pipe_wm *merged)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	int level, max_level = ilk_wm_max_level(dev);
+	int last_enabled_level = max_level;
+
+	/* ILK/SNB/IVB: LP1+ watermarks only w/ single pipe */
+	if ((INTEL_INFO(dev)->gen <= 6 || IS_IVYBRIDGE(dev)) &&
+	    config->num_pipes_active > 1)
+		last_enabled_level = 0;
+
+	/* ILK: FBC WM must be disabled always */
+	merged->fbc_wm_enabled = INTEL_INFO(dev)->gen >= 6;
+
+	/* merge each WM1+ level */
+	for (level = 1; level <= max_level; level++) {
+		struct intel_wm_level *wm = &merged->wm[level];
+
+		ilk_merge_wm_level(dev, level, wm);
+
+		if (level > last_enabled_level)
+			wm->enable = false;
+		else if (!ilk_validate_wm_level(level, max, wm))
+			/* make sure all following levels get disabled */
+			last_enabled_level = level - 1;
+
+		/*
+		 * The spec says it is preferred to disable
+		 * FBC WMs instead of disabling a WM level.
+		 */
+		if (wm->fbc_val > max->fbc) {
+			if (wm->enable)
+				merged->fbc_wm_enabled = false;
+			wm->fbc_val = 0;
+		}
+	}
+
+	/* ILK: LP2+ must be disabled when FBC WM is disabled but FBC enabled */
+	/*
+	 * FIXME this is racy. FBC might get enabled later.
+	 * What we should check here is whether FBC can be
+	 * enabled sometime later.
+	 */
+	if (IS_GEN5(dev) && !merged->fbc_wm_enabled &&
+	    intel_fbc_is_active(dev_priv)) {
+		for (level = 2; level <= max_level; level++) {
+			struct intel_wm_level *wm = &merged->wm[level];
+
+			wm->enable = false;
+		}
+	}
+}
+
+static int ilk_wm_lp_to_level(int wm_lp, const struct intel_pipe_wm *pipe_wm)
+{
+	/* LP1,LP2,LP3 levels are either 1,2,3 or 1,3,4 */
+	return wm_lp + (wm_lp >= 2 && pipe_wm->wm[4].enable);
+}
+
+/* The value we need to program into the WM_LPx latency field */
+static unsigned int ilk_wm_lp_latency(struct drm_device *dev, int level)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	if (IS_HASWELL(dev) || IS_BROADWELL(dev))
+		return 2 * level;
+	else
+		return dev_priv->wm.pri_latency[level];
+}
+
+static void ilk_compute_wm_results(struct drm_device *dev,
+				   const struct intel_pipe_wm *merged,
+				   enum intel_ddb_partitioning partitioning,
+				   struct ilk_wm_values *results)
+{
+	struct intel_crtc *intel_crtc;
+	int level, wm_lp;
+
+	results->enable_fbc_wm = merged->fbc_wm_enabled;
+	results->partitioning = partitioning;
+
+	/* LP1+ register values */
+	for (wm_lp = 1; wm_lp <= 3; wm_lp++) {
+		const struct intel_wm_level *r;
+
+		level = ilk_wm_lp_to_level(wm_lp, merged);
+
+		r = &merged->wm[level];
+
+		/*
+		 * Maintain the watermark values even if the level is
+		 * disabled. Doing otherwise could cause underruns.
+		 */
+		results->wm_lp[wm_lp - 1] =
+			(ilk_wm_lp_latency(dev, level) << WM1_LP_LATENCY_SHIFT) |
+			(r->pri_val << WM1_LP_SR_SHIFT) |
+			r->cur_val;
+
+		if (r->enable)
+			results->wm_lp[wm_lp - 1] |= WM1_LP_SR_EN;
+
+		if (INTEL_INFO(dev)->gen >= 8)
+			results->wm_lp[wm_lp - 1] |=
+				r->fbc_val << WM1_LP_FBC_SHIFT_BDW;
+		else
+			results->wm_lp[wm_lp - 1] |=
+				r->fbc_val << WM1_LP_FBC_SHIFT;
+
+		/*
+		 * Always set WM1S_LP_EN when spr_val != 0, even if the
+		 * level is disabled. Doing otherwise could cause underruns.
+		 */
+		if (INTEL_INFO(dev)->gen <= 6 && r->spr_val) {
+			WARN_ON(wm_lp != 1);
+			results->wm_lp_spr[wm_lp - 1] = WM1S_LP_EN | r->spr_val;
+		} else
+			results->wm_lp_spr[wm_lp - 1] = r->spr_val;
+	}
+
+	/* LP0 register values */
+	for_each_intel_crtc(dev, intel_crtc) {
+		enum pipe pipe = intel_crtc->pipe;
+		const struct intel_wm_level *r =
+			&intel_crtc->wm.active.ilk.wm[0];
+
+		if (WARN_ON(!r->enable))
+			continue;
+
+		results->wm_linetime[pipe] = intel_crtc->wm.active.ilk.linetime;
+
+		results->wm_pipe[pipe] =
+			(r->pri_val << WM0_PIPE_PLANE_SHIFT) |
+			(r->spr_val << WM0_PIPE_SPRITE_SHIFT) |
+			r->cur_val;
+	}
+}
+
+/* Find the result with the highest level enabled. Check for enable_fbc_wm in
+ * case both are at the same level. Prefer r1 in case they're the same. */
+static struct intel_pipe_wm *ilk_find_best_result(struct drm_device *dev,
+						  struct intel_pipe_wm *r1,
+						  struct intel_pipe_wm *r2)
+{
+	int level, max_level = ilk_wm_max_level(dev);
+	int level1 = 0, level2 = 0;
+
+	for (level = 1; level <= max_level; level++) {
+		if (r1->wm[level].enable)
+			level1 = level;
+		if (r2->wm[level].enable)
+			level2 = level;
+	}
+
+	if (level1 == level2) {
+		if (r2->fbc_wm_enabled && !r1->fbc_wm_enabled)
+			return r2;
+		else
+			return r1;
+	} else if (level1 > level2) {
+		return r1;
+	} else {
+		return r2;
+	}
+}
+
+/* dirty bits used to track which watermarks need changes */
+#define WM_DIRTY_PIPE(pipe) (1 << (pipe))
+#define WM_DIRTY_LINETIME(pipe) (1 << (8 + (pipe)))
+#define WM_DIRTY_LP(wm_lp) (1 << (15 + (wm_lp)))
+#define WM_DIRTY_LP_ALL (WM_DIRTY_LP(1) | WM_DIRTY_LP(2) | WM_DIRTY_LP(3))
+#define WM_DIRTY_FBC (1 << 24)
+#define WM_DIRTY_DDB (1 << 25)
+
+static unsigned int ilk_compute_wm_dirty(struct drm_i915_private *dev_priv,
+					 const struct ilk_wm_values *old,
+					 const struct ilk_wm_values *new)
+{
+	unsigned int dirty = 0;
+	enum pipe pipe;
+	int wm_lp;
+
+	for_each_pipe(dev_priv, pipe) {
+		if (old->wm_linetime[pipe] != new->wm_linetime[pipe]) {
+			dirty |= WM_DIRTY_LINETIME(pipe);
+			/* Must disable LP1+ watermarks too */
+			dirty |= WM_DIRTY_LP_ALL;
+		}
+
+		if (old->wm_pipe[pipe] != new->wm_pipe[pipe]) {
+			dirty |= WM_DIRTY_PIPE(pipe);
+			/* Must disable LP1+ watermarks too */
+			dirty |= WM_DIRTY_LP_ALL;
+		}
+	}
+
+	if (old->enable_fbc_wm != new->enable_fbc_wm) {
+		dirty |= WM_DIRTY_FBC;
+		/* Must disable LP1+ watermarks too */
+		dirty |= WM_DIRTY_LP_ALL;
+	}
+
+	if (old->partitioning != new->partitioning) {
+		dirty |= WM_DIRTY_DDB;
+		/* Must disable LP1+ watermarks too */
+		dirty |= WM_DIRTY_LP_ALL;
+	}
+
+	/* LP1+ watermarks already deemed dirty, no need to continue */
+	if (dirty & WM_DIRTY_LP_ALL)
+		return dirty;
+
+	/* Find the lowest numbered LP1+ watermark in need of an update... */
+	for (wm_lp = 1; wm_lp <= 3; wm_lp++) {
+		if (old->wm_lp[wm_lp - 1] != new->wm_lp[wm_lp - 1] ||
+		    old->wm_lp_spr[wm_lp - 1] != new->wm_lp_spr[wm_lp - 1])
+			break;
+	}
+
+	/* ...and mark it and all higher numbered LP1+ watermarks as dirty */
+	for (; wm_lp <= 3; wm_lp++)
+		dirty |= WM_DIRTY_LP(wm_lp);
+
+	return dirty;
+}
+
+static bool _ilk_disable_lp_wm(struct drm_i915_private *dev_priv,
+			       unsigned int dirty)
+{
+	struct ilk_wm_values *previous = &dev_priv->wm.hw;
+	bool changed = false;
+
+	if (dirty & WM_DIRTY_LP(3) && previous->wm_lp[2] & WM1_LP_SR_EN) {
+		previous->wm_lp[2] &= ~WM1_LP_SR_EN;
+		I915_WRITE(WM3_LP_ILK, previous->wm_lp[2]);
+		changed = true;
+	}
+	if (dirty & WM_DIRTY_LP(2) && previous->wm_lp[1] & WM1_LP_SR_EN) {
+		previous->wm_lp[1] &= ~WM1_LP_SR_EN;
+		I915_WRITE(WM2_LP_ILK, previous->wm_lp[1]);
+		changed = true;
+	}
+	if (dirty & WM_DIRTY_LP(1) && previous->wm_lp[0] & WM1_LP_SR_EN) {
+		previous->wm_lp[0] &= ~WM1_LP_SR_EN;
+		I915_WRITE(WM1_LP_ILK, previous->wm_lp[0]);
+		changed = true;
+	}
+
+	/*
+	 * Don't touch WM1S_LP_EN here.
+	 * Doing so could cause underruns.
+	 */
+
+	return changed;
+}
+
+/*
+ * The spec says we shouldn't write when we don't need, because every write
+ * causes WMs to be re-evaluated, expending some power.
+ */
+static void ilk_write_wm_values(struct drm_i915_private *dev_priv,
+				struct ilk_wm_values *results)
+{
+	struct drm_device *dev = dev_priv->dev;
+	struct ilk_wm_values *previous = &dev_priv->wm.hw;
+	unsigned int dirty;
+	uint32_t val;
+
+	dirty = ilk_compute_wm_dirty(dev_priv, previous, results);
+	if (!dirty)
+		return;
+
+	_ilk_disable_lp_wm(dev_priv, dirty);
+
+	if (dirty & WM_DIRTY_PIPE(PIPE_A))
+		I915_WRITE(WM0_PIPEA_ILK, results->wm_pipe[0]);
+	if (dirty & WM_DIRTY_PIPE(PIPE_B))
+		I915_WRITE(WM0_PIPEB_ILK, results->wm_pipe[1]);
+	if (dirty & WM_DIRTY_PIPE(PIPE_C))
+		I915_WRITE(WM0_PIPEC_IVB, results->wm_pipe[2]);
+
+	if (dirty & WM_DIRTY_LINETIME(PIPE_A))
+		I915_WRITE(PIPE_WM_LINETIME(PIPE_A), results->wm_linetime[0]);
+	if (dirty & WM_DIRTY_LINETIME(PIPE_B))
+		I915_WRITE(PIPE_WM_LINETIME(PIPE_B), results->wm_linetime[1]);
+	if (dirty & WM_DIRTY_LINETIME(PIPE_C))
+		I915_WRITE(PIPE_WM_LINETIME(PIPE_C), results->wm_linetime[2]);
+
+	if (dirty & WM_DIRTY_DDB) {
+		if (IS_HASWELL(dev) || IS_BROADWELL(dev)) {
+			val = I915_READ(WM_MISC);
+			if (results->partitioning == INTEL_DDB_PART_1_2)
+				val &= ~WM_MISC_DATA_PARTITION_5_6;
+			else
+				val |= WM_MISC_DATA_PARTITION_5_6;
+			I915_WRITE(WM_MISC, val);
+		} else {
+			val = I915_READ(DISP_ARB_CTL2);
+			if (results->partitioning == INTEL_DDB_PART_1_2)
+				val &= ~DISP_DATA_PARTITION_5_6;
+			else
+				val |= DISP_DATA_PARTITION_5_6;
+			I915_WRITE(DISP_ARB_CTL2, val);
+		}
+	}
+
+	if (dirty & WM_DIRTY_FBC) {
+		val = I915_READ(DISP_ARB_CTL);
+		if (results->enable_fbc_wm)
+			val &= ~DISP_FBC_WM_DIS;
+		else
+			val |= DISP_FBC_WM_DIS;
+		I915_WRITE(DISP_ARB_CTL, val);
+	}
+
+	if (dirty & WM_DIRTY_LP(1) &&
+	    previous->wm_lp_spr[0] != results->wm_lp_spr[0])
+		I915_WRITE(WM1S_LP_ILK, results->wm_lp_spr[0]);
+
+	if (INTEL_INFO(dev)->gen >= 7) {
+		if (dirty & WM_DIRTY_LP(2) && previous->wm_lp_spr[1] != results->wm_lp_spr[1])
+			I915_WRITE(WM2S_LP_IVB, results->wm_lp_spr[1]);
+		if (dirty & WM_DIRTY_LP(3) && previous->wm_lp_spr[2] != results->wm_lp_spr[2])
+			I915_WRITE(WM3S_LP_IVB, results->wm_lp_spr[2]);
+	}
+
+	if (dirty & WM_DIRTY_LP(1) && previous->wm_lp[0] != results->wm_lp[0])
+		I915_WRITE(WM1_LP_ILK, results->wm_lp[0]);
+	if (dirty & WM_DIRTY_LP(2) && previous->wm_lp[1] != results->wm_lp[1])
+		I915_WRITE(WM2_LP_ILK, results->wm_lp[1]);
+	if (dirty & WM_DIRTY_LP(3) && previous->wm_lp[2] != results->wm_lp[2])
+		I915_WRITE(WM3_LP_ILK, results->wm_lp[2]);
+
+	dev_priv->wm.hw = *results;
+}
+
+bool ilk_disable_lp_wm(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	return _ilk_disable_lp_wm(dev_priv, WM_DIRTY_LP_ALL);
+}
+
+/*
+ * On gen9, we need to allocate Display Data Buffer (DDB) portions to the
+ * different active planes.
+ */
+
+#define SKL_DDB_SIZE		896	/* in blocks */
+#define BXT_DDB_SIZE		512
+
+/*
+ * Return the index of a plane in the SKL DDB and wm result arrays.  Primary
+ * plane is always in slot 0, cursor is always in slot I915_MAX_PLANES-1, and
+ * other universal planes are in indices 1..n.  Note that this may leave unused
+ * indices between the top "sprite" plane and the cursor.
+ */
+static int
+skl_wm_plane_id(const struct intel_plane *plane)
+{
+	switch (plane->base.type) {
+	case DRM_PLANE_TYPE_PRIMARY:
+		return 0;
+	case DRM_PLANE_TYPE_CURSOR:
+		return PLANE_CURSOR;
+	case DRM_PLANE_TYPE_OVERLAY:
+		return plane->plane + 1;
+	default:
+		MISSING_CASE(plane->base.type);
+		return plane->plane;
+	}
+}
+
+static void
+skl_ddb_get_pipe_allocation_limits(struct drm_device *dev,
+				   const struct intel_crtc_state *cstate,
+				   const struct intel_wm_config *config,
+				   struct skl_ddb_entry *alloc /* out */)
+{
+	struct drm_crtc *for_crtc = cstate->base.crtc;
+	struct drm_crtc *crtc;
+	unsigned int pipe_size, ddb_size;
+	int nth_active_pipe;
+
+	if (!cstate->base.active) {
+		alloc->start = 0;
+		alloc->end = 0;
+		return;
+	}
+
+	if (IS_BROXTON(dev))
+		ddb_size = BXT_DDB_SIZE;
+	else
+		ddb_size = SKL_DDB_SIZE;
+
+	ddb_size -= 4; /* 4 blocks for bypass path allocation */
+
+	nth_active_pipe = 0;
+	for_each_crtc(dev, crtc) {
+		if (!to_intel_crtc(crtc)->active)
+			continue;
+
+		if (crtc == for_crtc)
+			break;
+
+		nth_active_pipe++;
+	}
+
+	pipe_size = ddb_size / config->num_pipes_active;
+	alloc->start = nth_active_pipe * ddb_size / config->num_pipes_active;
+	alloc->end = alloc->start + pipe_size;
+}
+
+static unsigned int skl_cursor_allocation(const struct intel_wm_config *config)
+{
+	if (config->num_pipes_active == 1)
+		return 32;
+
+	return 8;
+}
+
+static void skl_ddb_entry_init_from_hw(struct skl_ddb_entry *entry, u32 reg)
+{
+	entry->start = reg & 0x3ff;
+	entry->end = (reg >> 16) & 0x3ff;
+	if (entry->end)
+		entry->end += 1;
+}
+
+void skl_ddb_get_hw_state(struct drm_i915_private *dev_priv,
+			  struct skl_ddb_allocation *ddb /* out */)
+{
+	enum pipe pipe;
+	int plane;
+	u32 val;
+
+	memset(ddb, 0, sizeof(*ddb));
+
+	for_each_pipe(dev_priv, pipe) {
+		enum intel_display_power_domain power_domain;
+
+		power_domain = POWER_DOMAIN_PIPE(pipe);
+		if (!intel_display_power_get_if_enabled(dev_priv, power_domain))
+			continue;
+
+		for_each_plane(dev_priv, pipe, plane) {
+			val = I915_READ(PLANE_BUF_CFG(pipe, plane));
+			skl_ddb_entry_init_from_hw(&ddb->plane[pipe][plane],
+						   val);
+		}
+
+		val = I915_READ(CUR_BUF_CFG(pipe));
+		skl_ddb_entry_init_from_hw(&ddb->plane[pipe][PLANE_CURSOR],
+					   val);
+
+		intel_display_power_put(dev_priv, power_domain);
+	}
+}
+
+static unsigned int
+skl_plane_relative_data_rate(const struct intel_crtc_state *cstate,
+			     const struct drm_plane_state *pstate,
+			     int y)
+{
+	struct intel_plane_state *intel_pstate = to_intel_plane_state(pstate);
+	struct drm_framebuffer *fb = pstate->fb;
+	uint32_t width = 0, height = 0;
+
+	width = drm_rect_width(&intel_pstate->src) >> 16;
+	height = drm_rect_height(&intel_pstate->src) >> 16;
+
+	if (intel_rotation_90_or_270(pstate->rotation))
+		swap(width, height);
+
+	/* for planar format */
+	if (fb->pixel_format == DRM_FORMAT_NV12) {
+		if (y)  /* y-plane data rate */
+			return width * height *
+				drm_format_plane_cpp(fb->pixel_format, 0);
+		else    /* uv-plane data rate */
+			return (width / 2) * (height / 2) *
+				drm_format_plane_cpp(fb->pixel_format, 1);
+	}
+
+	/* for packed formats */
+	return width * height * drm_format_plane_cpp(fb->pixel_format, 0);
+}
+
+/*
+ * We don't overflow 32 bits. Worst case is 3 planes enabled, each fetching
+ * a 8192x4096@32bpp framebuffer:
+ *   3 * 4096 * 8192  * 4 < 2^32
+ */
+static unsigned int
+skl_get_total_relative_data_rate(const struct intel_crtc_state *cstate)
+{
+	struct intel_crtc *intel_crtc = to_intel_crtc(cstate->base.crtc);
+	struct drm_device *dev = intel_crtc->base.dev;
+	const struct intel_plane *intel_plane;
+	unsigned int total_data_rate = 0;
+
+	for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane) {
+		const struct drm_plane_state *pstate = intel_plane->base.state;
+
+		if (pstate->fb == NULL)
+			continue;
+
+		if (intel_plane->base.type == DRM_PLANE_TYPE_CURSOR)
+			continue;
+
+		/* packed/uv */
+		total_data_rate += skl_plane_relative_data_rate(cstate,
+								pstate,
+								0);
+
+		if (pstate->fb->pixel_format == DRM_FORMAT_NV12)
+			/* y-plane */
+			total_data_rate += skl_plane_relative_data_rate(cstate,
+									pstate,
+									1);
+	}
+
+	return total_data_rate;
+}
+
+static void
+skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
+		      struct skl_ddb_allocation *ddb /* out */)
+{
+	struct drm_crtc *crtc = cstate->base.crtc;
+	struct drm_device *dev = crtc->dev;
+	struct drm_i915_private *dev_priv = to_i915(dev);
+	struct intel_wm_config *config = &dev_priv->wm.config;
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	struct intel_plane *intel_plane;
+	enum pipe pipe = intel_crtc->pipe;
+	struct skl_ddb_entry *alloc = &ddb->pipe[pipe];
+	uint16_t alloc_size, start, cursor_blocks;
+	uint16_t minimum[I915_MAX_PLANES];
+	uint16_t y_minimum[I915_MAX_PLANES];
+	unsigned int total_data_rate;
+
+	skl_ddb_get_pipe_allocation_limits(dev, cstate, config, alloc);
+	alloc_size = skl_ddb_entry_size(alloc);
+	if (alloc_size == 0) {
+		memset(ddb->plane[pipe], 0, sizeof(ddb->plane[pipe]));
+		memset(&ddb->plane[pipe][PLANE_CURSOR], 0,
+		       sizeof(ddb->plane[pipe][PLANE_CURSOR]));
+		return;
+	}
+
+	cursor_blocks = skl_cursor_allocation(config);
+	ddb->plane[pipe][PLANE_CURSOR].start = alloc->end - cursor_blocks;
+	ddb->plane[pipe][PLANE_CURSOR].end = alloc->end;
+
+	alloc_size -= cursor_blocks;
+	alloc->end -= cursor_blocks;
+
+	/* 1. Allocate the mininum required blocks for each active plane */
+	for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane) {
+		struct drm_plane *plane = &intel_plane->base;
+		struct drm_framebuffer *fb = plane->state->fb;
+		int id = skl_wm_plane_id(intel_plane);
+
+		if (!to_intel_plane_state(plane->state)->visible)
+			continue;
+
+		if (plane->type == DRM_PLANE_TYPE_CURSOR)
+			continue;
+
+		minimum[id] = 8;
+		alloc_size -= minimum[id];
+		y_minimum[id] = (fb->pixel_format == DRM_FORMAT_NV12) ? 8 : 0;
+		alloc_size -= y_minimum[id];
+	}
+
+	/*
+	 * 2. Distribute the remaining space in proportion to the amount of
+	 * data each plane needs to fetch from memory.
+	 *
+	 * FIXME: we may not allocate every single block here.
+	 */
+	total_data_rate = skl_get_total_relative_data_rate(cstate);
+
+	start = alloc->start;
+	for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane) {
+		struct drm_plane *plane = &intel_plane->base;
+		struct drm_plane_state *pstate = intel_plane->base.state;
+		unsigned int data_rate, y_data_rate;
+		uint16_t plane_blocks, y_plane_blocks = 0;
+		int id = skl_wm_plane_id(intel_plane);
+
+		if (!to_intel_plane_state(pstate)->visible)
+			continue;
+		if (plane->type == DRM_PLANE_TYPE_CURSOR)
+			continue;
+
+		data_rate = skl_plane_relative_data_rate(cstate, pstate, 0);
+
+		/*
+		 * allocation for (packed formats) or (uv-plane part of planar format):
+		 * promote the expression to 64 bits to avoid overflowing, the
+		 * result is < available as data_rate / total_data_rate < 1
+		 */
+		plane_blocks = minimum[id];
+		plane_blocks += div_u64((uint64_t)alloc_size * data_rate,
+					total_data_rate);
+
+		ddb->plane[pipe][id].start = start;
+		ddb->plane[pipe][id].end = start + plane_blocks;
+
+		start += plane_blocks;
+
+		/*
+		 * allocation for y_plane part of planar format:
+		 */
+		if (pstate->fb->pixel_format == DRM_FORMAT_NV12) {
+			y_data_rate = skl_plane_relative_data_rate(cstate,
+								   pstate,
+								   1);
+			y_plane_blocks = y_minimum[id];
+			y_plane_blocks += div_u64((uint64_t)alloc_size * y_data_rate,
+						total_data_rate);
+
+			ddb->y_plane[pipe][id].start = start;
+			ddb->y_plane[pipe][id].end = start + y_plane_blocks;
+
+			start += y_plane_blocks;
+		}
+
+	}
+
+}
+
+static uint32_t skl_pipe_pixel_rate(const struct intel_crtc_state *config)
+{
+	/* TODO: Take into account the scalers once we support them */
+	return config->base.adjusted_mode.crtc_clock;
+}
+
+/*
+ * The max latency should be 257 (max the punit can code is 255 and we add 2us
+ * for the read latency) and cpp should always be <= 8, so that
+ * should allow pixel_rate up to ~2 GHz which seems sufficient since max
+ * 2xcdclk is 1350 MHz and the pixel rate should never exceed that.
+*/
+static uint32_t skl_wm_method1(uint32_t pixel_rate, uint8_t cpp, uint32_t latency)
+{
+	uint32_t wm_intermediate_val, ret;
+
+	if (latency == 0)
+		return UINT_MAX;
+
+	wm_intermediate_val = latency * pixel_rate * cpp / 512;
+	ret = DIV_ROUND_UP(wm_intermediate_val, 1000);
+
+	return ret;
+}
+
+static uint32_t skl_wm_method2(uint32_t pixel_rate, uint32_t pipe_htotal,
+			       uint32_t horiz_pixels, uint8_t cpp,
+			       uint64_t tiling, uint32_t latency)
+{
+	uint32_t ret;
+	uint32_t plane_bytes_per_line, plane_blocks_per_line;
+	uint32_t wm_intermediate_val;
+
+	if (latency == 0)
+		return UINT_MAX;
+
+	plane_bytes_per_line = horiz_pixels * cpp;
+
+	if (tiling == I915_FORMAT_MOD_Y_TILED ||
+	    tiling == I915_FORMAT_MOD_Yf_TILED) {
+		plane_bytes_per_line *= 4;
+		plane_blocks_per_line = DIV_ROUND_UP(plane_bytes_per_line, 512);
+		plane_blocks_per_line /= 4;
+	} else {
+		plane_blocks_per_line = DIV_ROUND_UP(plane_bytes_per_line, 512);
+	}
+
+	wm_intermediate_val = latency * pixel_rate;
+	ret = DIV_ROUND_UP(wm_intermediate_val, pipe_htotal * 1000) *
+				plane_blocks_per_line;
+
+	return ret;
+}
+
+static bool skl_ddb_allocation_changed(const struct skl_ddb_allocation *new_ddb,
+				       const struct intel_crtc *intel_crtc)
+{
+	struct drm_device *dev = intel_crtc->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	const struct skl_ddb_allocation *cur_ddb = &dev_priv->wm.skl_hw.ddb;
+
+	/*
+	 * If ddb allocation of pipes changed, it may require recalculation of
+	 * watermarks
+	 */
+	if (memcmp(new_ddb->pipe, cur_ddb->pipe, sizeof(new_ddb->pipe)))
+		return true;
+
+	return false;
+}
+
+static bool skl_compute_plane_wm(const struct drm_i915_private *dev_priv,
+				 struct intel_crtc_state *cstate,
+				 struct intel_plane *intel_plane,
+				 uint16_t ddb_allocation,
+				 int level,
+				 uint16_t *out_blocks, /* out */
+				 uint8_t *out_lines /* out */)
+{
+	struct drm_plane *plane = &intel_plane->base;
+	struct drm_framebuffer *fb = plane->state->fb;
+	struct intel_plane_state *intel_pstate =
+					to_intel_plane_state(plane->state);
+	uint32_t latency = dev_priv->wm.skl_latency[level];
+	uint32_t method1, method2;
+	uint32_t plane_bytes_per_line, plane_blocks_per_line;
+	uint32_t res_blocks, res_lines;
+	uint32_t selected_result;
+	uint8_t cpp;
+	uint32_t width = 0, height = 0;
+
+	if (latency == 0 || !cstate->base.active || !intel_pstate->visible)
+		return false;
+
+	width = drm_rect_width(&intel_pstate->src) >> 16;
+	height = drm_rect_height(&intel_pstate->src) >> 16;
+
+	if (intel_rotation_90_or_270(plane->state->rotation))
+		swap(width, height);
+
+	cpp = drm_format_plane_cpp(fb->pixel_format, 0);
+	method1 = skl_wm_method1(skl_pipe_pixel_rate(cstate),
+				 cpp, latency);
+	method2 = skl_wm_method2(skl_pipe_pixel_rate(cstate),
+				 cstate->base.adjusted_mode.crtc_htotal,
+				 width,
+				 cpp,
+				 fb->modifier[0],
+				 latency);
+
+	plane_bytes_per_line = width * cpp;
+	plane_blocks_per_line = DIV_ROUND_UP(plane_bytes_per_line, 512);
+
+	if (fb->modifier[0] == I915_FORMAT_MOD_Y_TILED ||
+	    fb->modifier[0] == I915_FORMAT_MOD_Yf_TILED) {
+		uint32_t min_scanlines = 4;
+		uint32_t y_tile_minimum;
+		if (intel_rotation_90_or_270(plane->state->rotation)) {
+			int cpp = (fb->pixel_format == DRM_FORMAT_NV12) ?
+				drm_format_plane_cpp(fb->pixel_format, 1) :
+				drm_format_plane_cpp(fb->pixel_format, 0);
+
+			switch (cpp) {
+			case 1:
+				min_scanlines = 16;
+				break;
+			case 2:
+				min_scanlines = 8;
+				break;
+			case 8:
+				WARN(1, "Unsupported pixel depth for rotation");
+			}
+		}
+		y_tile_minimum = plane_blocks_per_line * min_scanlines;
+		selected_result = max(method2, y_tile_minimum);
+	} else {
+		if ((ddb_allocation / plane_blocks_per_line) >= 1)
+			selected_result = min(method1, method2);
+		else
+			selected_result = method1;
+	}
+
+	res_blocks = selected_result + 1;
+	res_lines = DIV_ROUND_UP(selected_result, plane_blocks_per_line);
+
+	if (level >= 1 && level <= 7) {
+		if (fb->modifier[0] == I915_FORMAT_MOD_Y_TILED ||
+		    fb->modifier[0] == I915_FORMAT_MOD_Yf_TILED)
+			res_lines += 4;
+		else
+			res_blocks++;
+	}
+
+	if (res_blocks >= ddb_allocation || res_lines > 31)
+		return false;
+
+	*out_blocks = res_blocks;
+	*out_lines = res_lines;
+
+	return true;
+}
+
+static void skl_compute_wm_level(const struct drm_i915_private *dev_priv,
+				 struct skl_ddb_allocation *ddb,
+				 struct intel_crtc_state *cstate,
+				 int level,
+				 struct skl_wm_level *result)
+{
+	struct drm_device *dev = dev_priv->dev;
+	struct intel_crtc *intel_crtc = to_intel_crtc(cstate->base.crtc);
+	struct intel_plane *intel_plane;
+	uint16_t ddb_blocks;
+	enum pipe pipe = intel_crtc->pipe;
+
+	for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane) {
+		int i = skl_wm_plane_id(intel_plane);
+
+		ddb_blocks = skl_ddb_entry_size(&ddb->plane[pipe][i]);
+
+		result->plane_en[i] = skl_compute_plane_wm(dev_priv,
+						cstate,
+						intel_plane,
+						ddb_blocks,
+						level,
+						&result->plane_res_b[i],
+						&result->plane_res_l[i]);
+	}
+}
+
+static uint32_t
+skl_compute_linetime_wm(struct intel_crtc_state *cstate)
+{
+	if (!cstate->base.active)
+		return 0;
+
+	if (WARN_ON(skl_pipe_pixel_rate(cstate) == 0))
+		return 0;
+
+	return DIV_ROUND_UP(8 * cstate->base.adjusted_mode.crtc_htotal * 1000,
+			    skl_pipe_pixel_rate(cstate));
+}
+
+static void skl_compute_transition_wm(struct intel_crtc_state *cstate,
+				      struct skl_wm_level *trans_wm /* out */)
+{
+	struct drm_crtc *crtc = cstate->base.crtc;
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	struct intel_plane *intel_plane;
+
+	if (!cstate->base.active)
+		return;
+
+	/* Until we know more, just disable transition WMs */
+	for_each_intel_plane_on_crtc(crtc->dev, intel_crtc, intel_plane) {
+		int i = skl_wm_plane_id(intel_plane);
+
+		trans_wm->plane_en[i] = false;
+	}
+}
+
+static void skl_compute_pipe_wm(struct intel_crtc_state *cstate,
+				struct skl_ddb_allocation *ddb,
+				struct skl_pipe_wm *pipe_wm)
+{
+	struct drm_device *dev = cstate->base.crtc->dev;
+	const struct drm_i915_private *dev_priv = dev->dev_private;
+	int level, max_level = ilk_wm_max_level(dev);
+
+	for (level = 0; level <= max_level; level++) {
+		skl_compute_wm_level(dev_priv, ddb, cstate,
+				     level, &pipe_wm->wm[level]);
+	}
+	pipe_wm->linetime = skl_compute_linetime_wm(cstate);
+
+	skl_compute_transition_wm(cstate, &pipe_wm->trans_wm);
+}
+
+static void skl_compute_wm_results(struct drm_device *dev,
+				   struct skl_pipe_wm *p_wm,
+				   struct skl_wm_values *r,
+				   struct intel_crtc *intel_crtc)
+{
+	int level, max_level = ilk_wm_max_level(dev);
+	enum pipe pipe = intel_crtc->pipe;
+	uint32_t temp;
+	int i;
+
+	for (level = 0; level <= max_level; level++) {
+		for (i = 0; i < intel_num_planes(intel_crtc); i++) {
+			temp = 0;
+
+			temp |= p_wm->wm[level].plane_res_l[i] <<
+					PLANE_WM_LINES_SHIFT;
+			temp |= p_wm->wm[level].plane_res_b[i];
+			if (p_wm->wm[level].plane_en[i])
+				temp |= PLANE_WM_EN;
+
+			r->plane[pipe][i][level] = temp;
+		}
+
+		temp = 0;
+
+		temp |= p_wm->wm[level].plane_res_l[PLANE_CURSOR] << PLANE_WM_LINES_SHIFT;
+		temp |= p_wm->wm[level].plane_res_b[PLANE_CURSOR];
+
+		if (p_wm->wm[level].plane_en[PLANE_CURSOR])
+			temp |= PLANE_WM_EN;
+
+		r->plane[pipe][PLANE_CURSOR][level] = temp;
+
+	}
+
+	/* transition WMs */
+	for (i = 0; i < intel_num_planes(intel_crtc); i++) {
+		temp = 0;
+		temp |= p_wm->trans_wm.plane_res_l[i] << PLANE_WM_LINES_SHIFT;
+		temp |= p_wm->trans_wm.plane_res_b[i];
+		if (p_wm->trans_wm.plane_en[i])
+			temp |= PLANE_WM_EN;
+
+		r->plane_trans[pipe][i] = temp;
+	}
+
+	temp = 0;
+	temp |= p_wm->trans_wm.plane_res_l[PLANE_CURSOR] << PLANE_WM_LINES_SHIFT;
+	temp |= p_wm->trans_wm.plane_res_b[PLANE_CURSOR];
+	if (p_wm->trans_wm.plane_en[PLANE_CURSOR])
+		temp |= PLANE_WM_EN;
+
+	r->plane_trans[pipe][PLANE_CURSOR] = temp;
+
+	r->wm_linetime[pipe] = p_wm->linetime;
+}
+
+static void skl_ddb_entry_write(struct drm_i915_private *dev_priv,
+				i915_reg_t reg,
+				const struct skl_ddb_entry *entry)
+{
+	if (entry->end)
+		I915_WRITE(reg, (entry->end - 1) << 16 | entry->start);
+	else
+		I915_WRITE(reg, 0);
+}
+
+static void skl_write_wm_values(struct drm_i915_private *dev_priv,
+				const struct skl_wm_values *new)
+{
+	struct drm_device *dev = dev_priv->dev;
+	struct intel_crtc *crtc;
+
+	for_each_intel_crtc(dev, crtc) {
+		int i, level, max_level = ilk_wm_max_level(dev);
+		enum pipe pipe = crtc->pipe;
+
+		if (!new->dirty[pipe])
+			continue;
+
+		I915_WRITE(PIPE_WM_LINETIME(pipe), new->wm_linetime[pipe]);
+
+		for (level = 0; level <= max_level; level++) {
+			for (i = 0; i < intel_num_planes(crtc); i++)
+				I915_WRITE(PLANE_WM(pipe, i, level),
+					   new->plane[pipe][i][level]);
+			I915_WRITE(CUR_WM(pipe, level),
+				   new->plane[pipe][PLANE_CURSOR][level]);
+		}
+		for (i = 0; i < intel_num_planes(crtc); i++)
+			I915_WRITE(PLANE_WM_TRANS(pipe, i),
+				   new->plane_trans[pipe][i]);
+		I915_WRITE(CUR_WM_TRANS(pipe),
+			   new->plane_trans[pipe][PLANE_CURSOR]);
+
+		for (i = 0; i < intel_num_planes(crtc); i++) {
+			skl_ddb_entry_write(dev_priv,
+					    PLANE_BUF_CFG(pipe, i),
+					    &new->ddb.plane[pipe][i]);
+			skl_ddb_entry_write(dev_priv,
+					    PLANE_NV12_BUF_CFG(pipe, i),
+					    &new->ddb.y_plane[pipe][i]);
+		}
+
+		skl_ddb_entry_write(dev_priv, CUR_BUF_CFG(pipe),
+				    &new->ddb.plane[pipe][PLANE_CURSOR]);
+	}
+}
+
+/*
+ * When setting up a new DDB allocation arrangement, we need to correctly
+ * sequence the times at which the new allocations for the pipes are taken into
+ * account or we'll have pipes fetching from space previously allocated to
+ * another pipe.
+ *
+ * Roughly the sequence looks like:
+ *  1. re-allocate the pipe(s) with the allocation being reduced and not
+ *     overlapping with a previous light-up pipe (another way to put it is:
+ *     pipes with their new allocation strickly included into their old ones).
+ *  2. re-allocate the other pipes that get their allocation reduced
+ *  3. allocate the pipes having their allocation increased
+ *
+ * Steps 1. and 2. are here to take care of the following case:
+ * - Initially DDB looks like this:
+ *     |   B    |   C    |
+ * - enable pipe A.
+ * - pipe B has a reduced DDB allocation that overlaps with the old pipe C
+ *   allocation
+ *     |  A  |  B  |  C  |
+ *
+ * We need to sequence the re-allocation: C, B, A (and not B, C, A).
+ */
+
+static void
+skl_wm_flush_pipe(struct drm_i915_private *dev_priv, enum pipe pipe, int pass)
+{
+	int plane;
+
+	DRM_DEBUG_KMS("flush pipe %c (pass %d)\n", pipe_name(pipe), pass);
+
+	for_each_plane(dev_priv, pipe, plane) {
+		I915_WRITE(PLANE_SURF(pipe, plane),
+			   I915_READ(PLANE_SURF(pipe, plane)));
+	}
+	I915_WRITE(CURBASE(pipe), I915_READ(CURBASE(pipe)));
+}
+
+static bool
+skl_ddb_allocation_included(const struct skl_ddb_allocation *old,
+			    const struct skl_ddb_allocation *new,
+			    enum pipe pipe)
+{
+	uint16_t old_size, new_size;
+
+	old_size = skl_ddb_entry_size(&old->pipe[pipe]);
+	new_size = skl_ddb_entry_size(&new->pipe[pipe]);
+
+	return old_size != new_size &&
+	       new->pipe[pipe].start >= old->pipe[pipe].start &&
+	       new->pipe[pipe].end <= old->pipe[pipe].end;
+}
+
+static void skl_flush_wm_values(struct drm_i915_private *dev_priv,
+				struct skl_wm_values *new_values)
+{
+	struct drm_device *dev = dev_priv->dev;
+	struct skl_ddb_allocation *cur_ddb, *new_ddb;
+	bool reallocated[I915_MAX_PIPES] = {};
+	struct intel_crtc *crtc;
+	enum pipe pipe;
+
+	new_ddb = &new_values->ddb;
+	cur_ddb = &dev_priv->wm.skl_hw.ddb;
+
+	/*
+	 * First pass: flush the pipes with the new allocation contained into
+	 * the old space.
+	 *
+	 * We'll wait for the vblank on those pipes to ensure we can safely
+	 * re-allocate the freed space without this pipe fetching from it.
+	 */
+	for_each_intel_crtc(dev, crtc) {
+		if (!crtc->active)
+			continue;
+
+		pipe = crtc->pipe;
+
+		if (!skl_ddb_allocation_included(cur_ddb, new_ddb, pipe))
+			continue;
+
+		skl_wm_flush_pipe(dev_priv, pipe, 1);
+		intel_wait_for_vblank(dev, pipe);
+
+		reallocated[pipe] = true;
+	}
+
+
+	/*
+	 * Second pass: flush the pipes that are having their allocation
+	 * reduced, but overlapping with a previous allocation.
+	 *
+	 * Here as well we need to wait for the vblank to make sure the freed
+	 * space is not used anymore.
+	 */
+	for_each_intel_crtc(dev, crtc) {
+		if (!crtc->active)
+			continue;
+
+		pipe = crtc->pipe;
+
+		if (reallocated[pipe])
+			continue;
+
+		if (skl_ddb_entry_size(&new_ddb->pipe[pipe]) <
+		    skl_ddb_entry_size(&cur_ddb->pipe[pipe])) {
+			skl_wm_flush_pipe(dev_priv, pipe, 2);
+			intel_wait_for_vblank(dev, pipe);
+			reallocated[pipe] = true;
+		}
+	}
+
+	/*
+	 * Third pass: flush the pipes that got more space allocated.
+	 *
+	 * We don't need to actively wait for the update here, next vblank
+	 * will just get more DDB space with the correct WM values.
+	 */
+	for_each_intel_crtc(dev, crtc) {
+		if (!crtc->active)
+			continue;
+
+		pipe = crtc->pipe;
+
+		/*
+		 * At this point, only the pipes more space than before are
+		 * left to re-allocate.
+		 */
+		if (reallocated[pipe])
+			continue;
+
+		skl_wm_flush_pipe(dev_priv, pipe, 3);
+	}
+}
+
+static bool skl_update_pipe_wm(struct drm_crtc *crtc,
+			       struct skl_ddb_allocation *ddb, /* out */
+			       struct skl_pipe_wm *pipe_wm /* out */)
+{
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	struct intel_crtc_state *cstate = to_intel_crtc_state(crtc->state);
+
+	skl_allocate_pipe_ddb(cstate, ddb);
+	skl_compute_pipe_wm(cstate, ddb, pipe_wm);
+
+	if (!memcmp(&intel_crtc->wm.active.skl, pipe_wm, sizeof(*pipe_wm)))
+		return false;
+
+	intel_crtc->wm.active.skl = *pipe_wm;
+
+	return true;
+}
+
+static void skl_update_other_pipe_wm(struct drm_device *dev,
+				     struct drm_crtc *crtc,
+				     struct skl_wm_values *r)
+{
+	struct intel_crtc *intel_crtc;
+	struct intel_crtc *this_crtc = to_intel_crtc(crtc);
+
+	/*
+	 * If the WM update hasn't changed the allocation for this_crtc (the
+	 * crtc we are currently computing the new WM values for), other
+	 * enabled crtcs will keep the same allocation and we don't need to
+	 * recompute anything for them.
+	 */
+	if (!skl_ddb_allocation_changed(&r->ddb, this_crtc))
+		return;
+
+	/*
+	 * Otherwise, because of this_crtc being freshly enabled/disabled, the
+	 * other active pipes need new DDB allocation and WM values.
+	 */
+	for_each_intel_crtc(dev, intel_crtc) {
+		struct skl_pipe_wm pipe_wm = {};
+		bool wm_changed;
+
+		if (this_crtc->pipe == intel_crtc->pipe)
+			continue;
+
+		if (!intel_crtc->active)
+			continue;
+
+		wm_changed = skl_update_pipe_wm(&intel_crtc->base,
+						&r->ddb, &pipe_wm);
+
+		/*
+		 * If we end up re-computing the other pipe WM values, it's
+		 * because it was really needed, so we expect the WM values to
+		 * be different.
+		 */
+		WARN_ON(!wm_changed);
+
+		skl_compute_wm_results(dev, &pipe_wm, r, intel_crtc);
+		r->dirty[intel_crtc->pipe] = true;
+	}
+}
+
+static void skl_clear_wm(struct skl_wm_values *watermarks, enum pipe pipe)
+{
+	watermarks->wm_linetime[pipe] = 0;
+	memset(watermarks->plane[pipe], 0,
+	       sizeof(uint32_t) * 8 * I915_MAX_PLANES);
+	memset(watermarks->plane_trans[pipe],
+	       0, sizeof(uint32_t) * I915_MAX_PLANES);
+	watermarks->plane_trans[pipe][PLANE_CURSOR] = 0;
+
+	/* Clear ddb entries for pipe */
+	memset(&watermarks->ddb.pipe[pipe], 0, sizeof(struct skl_ddb_entry));
+	memset(&watermarks->ddb.plane[pipe], 0,
+	       sizeof(struct skl_ddb_entry) * I915_MAX_PLANES);
+	memset(&watermarks->ddb.y_plane[pipe], 0,
+	       sizeof(struct skl_ddb_entry) * I915_MAX_PLANES);
+	memset(&watermarks->ddb.plane[pipe][PLANE_CURSOR], 0,
+	       sizeof(struct skl_ddb_entry));
+
+}
+
+static void skl_update_wm(struct drm_crtc *crtc)
+{
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	struct drm_device *dev = crtc->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct skl_wm_values *results = &dev_priv->wm.skl_results;
+	struct intel_crtc_state *cstate = to_intel_crtc_state(crtc->state);
+	struct skl_pipe_wm *pipe_wm = &cstate->wm.optimal.skl;
+
+
+	/* Clear all dirty flags */
+	memset(results->dirty, 0, sizeof(bool) * I915_MAX_PIPES);
+
+	skl_clear_wm(results, intel_crtc->pipe);
+
+	if (!skl_update_pipe_wm(crtc, &results->ddb, pipe_wm))
+		return;
+
+	skl_compute_wm_results(dev, pipe_wm, results, intel_crtc);
+	results->dirty[intel_crtc->pipe] = true;
+
+	skl_update_other_pipe_wm(dev, crtc, results);
+	skl_write_wm_values(dev_priv, results);
+	skl_flush_wm_values(dev_priv, results);
+
+	/* store the new configuration */
+	dev_priv->wm.skl_hw = *results;
+}
+
+static void ilk_compute_wm_config(struct drm_device *dev,
+				  struct intel_wm_config *config)
+{
+	struct intel_crtc *crtc;
+
+	/* Compute the currently _active_ config */
+	for_each_intel_crtc(dev, crtc) {
+		const struct intel_pipe_wm *wm = &crtc->wm.active.ilk;
+
+		if (!wm->pipe_enabled)
+			continue;
+
+		config->sprites_enabled |= wm->sprites_enabled;
+		config->sprites_scaled |= wm->sprites_scaled;
+		config->num_pipes_active++;
+	}
+}
+
+static void ilk_program_watermarks(struct drm_i915_private *dev_priv)
+{
+	struct drm_device *dev = dev_priv->dev;
+	struct intel_pipe_wm lp_wm_1_2 = {}, lp_wm_5_6 = {}, *best_lp_wm;
+	struct ilk_wm_maximums max;
+	struct intel_wm_config config = {};
+	struct ilk_wm_values results = {};
+	enum intel_ddb_partitioning partitioning;
+
+	ilk_compute_wm_config(dev, &config);
+
+	ilk_compute_wm_maximums(dev, 1, &config, INTEL_DDB_PART_1_2, &max);
+	ilk_wm_merge(dev, &config, &max, &lp_wm_1_2);
+
+	/* 5/6 split only in single pipe config on IVB+ */
+	if (INTEL_INFO(dev)->gen >= 7 &&
+	    config.num_pipes_active == 1 && config.sprites_enabled) {
+		ilk_compute_wm_maximums(dev, 1, &config, INTEL_DDB_PART_5_6, &max);
+		ilk_wm_merge(dev, &config, &max, &lp_wm_5_6);
+
+		best_lp_wm = ilk_find_best_result(dev, &lp_wm_1_2, &lp_wm_5_6);
+	} else {
+		best_lp_wm = &lp_wm_1_2;
+	}
+
+	partitioning = (best_lp_wm == &lp_wm_1_2) ?
+		       INTEL_DDB_PART_1_2 : INTEL_DDB_PART_5_6;
+
+	ilk_compute_wm_results(dev, best_lp_wm, partitioning, &results);
+
+	ilk_write_wm_values(dev_priv, &results);
+}
+
+static void ilk_initial_watermarks(struct intel_crtc_state *cstate)
+{
+	struct drm_i915_private *dev_priv = to_i915(cstate->base.crtc->dev);
+	struct intel_crtc *intel_crtc = to_intel_crtc(cstate->base.crtc);
+
+	mutex_lock(&dev_priv->wm.wm_mutex);
+	intel_crtc->wm.active.ilk = cstate->wm.intermediate;
+	ilk_program_watermarks(dev_priv);
+	mutex_unlock(&dev_priv->wm.wm_mutex);
+}
+
+static void ilk_optimize_watermarks(struct intel_crtc_state *cstate)
+{
+	struct drm_i915_private *dev_priv = to_i915(cstate->base.crtc->dev);
+	struct intel_crtc *intel_crtc = to_intel_crtc(cstate->base.crtc);
+
+	mutex_lock(&dev_priv->wm.wm_mutex);
+	if (cstate->wm.need_postvbl_update) {
+		intel_crtc->wm.active.ilk = cstate->wm.optimal.ilk;
+		ilk_program_watermarks(dev_priv);
+	}
+	mutex_unlock(&dev_priv->wm.wm_mutex);
+}
+
+static void skl_pipe_wm_active_state(uint32_t val,
+				     struct skl_pipe_wm *active,
+				     bool is_transwm,
+				     bool is_cursor,
+				     int i,
+				     int level)
+{
+	bool is_enabled = (val & PLANE_WM_EN) != 0;
+
+	if (!is_transwm) {
+		if (!is_cursor) {
+			active->wm[level].plane_en[i] = is_enabled;
+			active->wm[level].plane_res_b[i] =
+					val & PLANE_WM_BLOCKS_MASK;
+			active->wm[level].plane_res_l[i] =
+					(val >> PLANE_WM_LINES_SHIFT) &
+						PLANE_WM_LINES_MASK;
+		} else {
+			active->wm[level].plane_en[PLANE_CURSOR] = is_enabled;
+			active->wm[level].plane_res_b[PLANE_CURSOR] =
+					val & PLANE_WM_BLOCKS_MASK;
+			active->wm[level].plane_res_l[PLANE_CURSOR] =
+					(val >> PLANE_WM_LINES_SHIFT) &
+						PLANE_WM_LINES_MASK;
+		}
+	} else {
+		if (!is_cursor) {
+			active->trans_wm.plane_en[i] = is_enabled;
+			active->trans_wm.plane_res_b[i] =
+					val & PLANE_WM_BLOCKS_MASK;
+			active->trans_wm.plane_res_l[i] =
+					(val >> PLANE_WM_LINES_SHIFT) &
+						PLANE_WM_LINES_MASK;
+		} else {
+			active->trans_wm.plane_en[PLANE_CURSOR] = is_enabled;
+			active->trans_wm.plane_res_b[PLANE_CURSOR] =
+					val & PLANE_WM_BLOCKS_MASK;
+			active->trans_wm.plane_res_l[PLANE_CURSOR] =
+					(val >> PLANE_WM_LINES_SHIFT) &
+						PLANE_WM_LINES_MASK;
+		}
+	}
+}
+
+static void skl_pipe_wm_get_hw_state(struct drm_crtc *crtc)
+{
+	struct drm_device *dev = crtc->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct skl_wm_values *hw = &dev_priv->wm.skl_hw;
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	struct intel_crtc_state *cstate = to_intel_crtc_state(crtc->state);
+	struct skl_pipe_wm *active = &cstate->wm.optimal.skl;
+	enum pipe pipe = intel_crtc->pipe;
+	int level, i, max_level;
+	uint32_t temp;
+
+	max_level = ilk_wm_max_level(dev);
+
+	hw->wm_linetime[pipe] = I915_READ(PIPE_WM_LINETIME(pipe));
+
+	for (level = 0; level <= max_level; level++) {
+		for (i = 0; i < intel_num_planes(intel_crtc); i++)
+			hw->plane[pipe][i][level] =
+					I915_READ(PLANE_WM(pipe, i, level));
+		hw->plane[pipe][PLANE_CURSOR][level] = I915_READ(CUR_WM(pipe, level));
+	}
+
+	for (i = 0; i < intel_num_planes(intel_crtc); i++)
+		hw->plane_trans[pipe][i] = I915_READ(PLANE_WM_TRANS(pipe, i));
+	hw->plane_trans[pipe][PLANE_CURSOR] = I915_READ(CUR_WM_TRANS(pipe));
+
+	if (!intel_crtc->active)
+		return;
+
+	hw->dirty[pipe] = true;
+
+	active->linetime = hw->wm_linetime[pipe];
+
+	for (level = 0; level <= max_level; level++) {
+		for (i = 0; i < intel_num_planes(intel_crtc); i++) {
+			temp = hw->plane[pipe][i][level];
+			skl_pipe_wm_active_state(temp, active, false,
+						false, i, level);
+		}
+		temp = hw->plane[pipe][PLANE_CURSOR][level];
+		skl_pipe_wm_active_state(temp, active, false, true, i, level);
+	}
+
+	for (i = 0; i < intel_num_planes(intel_crtc); i++) {
+		temp = hw->plane_trans[pipe][i];
+		skl_pipe_wm_active_state(temp, active, true, false, i, 0);
+	}
+
+	temp = hw->plane_trans[pipe][PLANE_CURSOR];
+	skl_pipe_wm_active_state(temp, active, true, true, i, 0);
+
+	intel_crtc->wm.active.skl = *active;
+}
+
+void skl_wm_get_hw_state(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct skl_ddb_allocation *ddb = &dev_priv->wm.skl_hw.ddb;
+	struct drm_crtc *crtc;
+
+	skl_ddb_get_hw_state(dev_priv, ddb);
+	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
+		skl_pipe_wm_get_hw_state(crtc);
+}
+
+static void ilk_pipe_wm_get_hw_state(struct drm_crtc *crtc)
+{
+	struct drm_device *dev = crtc->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct ilk_wm_values *hw = &dev_priv->wm.hw;
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	struct intel_crtc_state *cstate = to_intel_crtc_state(crtc->state);
+	struct intel_pipe_wm *active = &cstate->wm.optimal.ilk;
+	enum pipe pipe = intel_crtc->pipe;
+	static const i915_reg_t wm0_pipe_reg[] = {
+		[PIPE_A] = WM0_PIPEA_ILK,
+		[PIPE_B] = WM0_PIPEB_ILK,
+		[PIPE_C] = WM0_PIPEC_IVB,
+	};
+
+	hw->wm_pipe[pipe] = I915_READ(wm0_pipe_reg[pipe]);
+	if (IS_HASWELL(dev) || IS_BROADWELL(dev))
+		hw->wm_linetime[pipe] = I915_READ(PIPE_WM_LINETIME(pipe));
+
+	memset(active, 0, sizeof(*active));
+
+	active->pipe_enabled = intel_crtc->active;
+
+	if (active->pipe_enabled) {
+		u32 tmp = hw->wm_pipe[pipe];
+
+		/*
+		 * For active pipes LP0 watermark is marked as
+		 * enabled, and LP1+ watermaks as disabled since
+		 * we can't really reverse compute them in case
+		 * multiple pipes are active.
+		 */
+		active->wm[0].enable = true;
+		active->wm[0].pri_val = (tmp & WM0_PIPE_PLANE_MASK) >> WM0_PIPE_PLANE_SHIFT;
+		active->wm[0].spr_val = (tmp & WM0_PIPE_SPRITE_MASK) >> WM0_PIPE_SPRITE_SHIFT;
+		active->wm[0].cur_val = tmp & WM0_PIPE_CURSOR_MASK;
+		active->linetime = hw->wm_linetime[pipe];
+	} else {
+		int level, max_level = ilk_wm_max_level(dev);
+
+		/*
+		 * For inactive pipes, all watermark levels
+		 * should be marked as enabled but zeroed,
+		 * which is what we'd compute them to.
+		 */
+		for (level = 0; level <= max_level; level++)
+			active->wm[level].enable = true;
+	}
+
+	intel_crtc->wm.active.ilk = *active;
+}
+
+#define _FW_WM(value, plane) \
+	(((value) & DSPFW_ ## plane ## _MASK) >> DSPFW_ ## plane ## _SHIFT)
+#define _FW_WM_VLV(value, plane) \
+	(((value) & DSPFW_ ## plane ## _MASK_VLV) >> DSPFW_ ## plane ## _SHIFT)
+
+static void vlv_read_wm_values(struct drm_i915_private *dev_priv,
+			       struct vlv_wm_values *wm)
+{
+	enum pipe pipe;
+	uint32_t tmp;
+
+	for_each_pipe(dev_priv, pipe) {
+		tmp = I915_READ(VLV_DDL(pipe));
+
+		wm->ddl[pipe].primary =
+			(tmp >> DDL_PLANE_SHIFT) & (DDL_PRECISION_HIGH | DRAIN_LATENCY_MASK);
+		wm->ddl[pipe].cursor =
+			(tmp >> DDL_CURSOR_SHIFT) & (DDL_PRECISION_HIGH | DRAIN_LATENCY_MASK);
+		wm->ddl[pipe].sprite[0] =
+			(tmp >> DDL_SPRITE_SHIFT(0)) & (DDL_PRECISION_HIGH | DRAIN_LATENCY_MASK);
+		wm->ddl[pipe].sprite[1] =
+			(tmp >> DDL_SPRITE_SHIFT(1)) & (DDL_PRECISION_HIGH | DRAIN_LATENCY_MASK);
+	}
+
+	tmp = I915_READ(DSPFW1);
+	wm->sr.plane = _FW_WM(tmp, SR);
+	wm->pipe[PIPE_B].cursor = _FW_WM(tmp, CURSORB);
+	wm->pipe[PIPE_B].primary = _FW_WM_VLV(tmp, PLANEB);
+	wm->pipe[PIPE_A].primary = _FW_WM_VLV(tmp, PLANEA);
+
+	tmp = I915_READ(DSPFW2);
+	wm->pipe[PIPE_A].sprite[1] = _FW_WM_VLV(tmp, SPRITEB);
+	wm->pipe[PIPE_A].cursor = _FW_WM(tmp, CURSORA);
+	wm->pipe[PIPE_A].sprite[0] = _FW_WM_VLV(tmp, SPRITEA);
+
+	tmp = I915_READ(DSPFW3);
+	wm->sr.cursor = _FW_WM(tmp, CURSOR_SR);
+
+	if (IS_CHERRYVIEW(dev_priv)) {
+		tmp = I915_READ(DSPFW7_CHV);
+		wm->pipe[PIPE_B].sprite[1] = _FW_WM_VLV(tmp, SPRITED);
+		wm->pipe[PIPE_B].sprite[0] = _FW_WM_VLV(tmp, SPRITEC);
+
+		tmp = I915_READ(DSPFW8_CHV);
+		wm->pipe[PIPE_C].sprite[1] = _FW_WM_VLV(tmp, SPRITEF);
+		wm->pipe[PIPE_C].sprite[0] = _FW_WM_VLV(tmp, SPRITEE);
+
+		tmp = I915_READ(DSPFW9_CHV);
+		wm->pipe[PIPE_C].primary = _FW_WM_VLV(tmp, PLANEC);
+		wm->pipe[PIPE_C].cursor = _FW_WM(tmp, CURSORC);
+
+		tmp = I915_READ(DSPHOWM);
+		wm->sr.plane |= _FW_WM(tmp, SR_HI) << 9;
+		wm->pipe[PIPE_C].sprite[1] |= _FW_WM(tmp, SPRITEF_HI) << 8;
+		wm->pipe[PIPE_C].sprite[0] |= _FW_WM(tmp, SPRITEE_HI) << 8;
+		wm->pipe[PIPE_C].primary |= _FW_WM(tmp, PLANEC_HI) << 8;
+		wm->pipe[PIPE_B].sprite[1] |= _FW_WM(tmp, SPRITED_HI) << 8;
+		wm->pipe[PIPE_B].sprite[0] |= _FW_WM(tmp, SPRITEC_HI) << 8;
+		wm->pipe[PIPE_B].primary |= _FW_WM(tmp, PLANEB_HI) << 8;
+		wm->pipe[PIPE_A].sprite[1] |= _FW_WM(tmp, SPRITEB_HI) << 8;
+		wm->pipe[PIPE_A].sprite[0] |= _FW_WM(tmp, SPRITEA_HI) << 8;
+		wm->pipe[PIPE_A].primary |= _FW_WM(tmp, PLANEA_HI) << 8;
+	} else {
+		tmp = I915_READ(DSPFW7);
+		wm->pipe[PIPE_B].sprite[1] = _FW_WM_VLV(tmp, SPRITED);
+		wm->pipe[PIPE_B].sprite[0] = _FW_WM_VLV(tmp, SPRITEC);
+
+		tmp = I915_READ(DSPHOWM);
+		wm->sr.plane |= _FW_WM(tmp, SR_HI) << 9;
+		wm->pipe[PIPE_B].sprite[1] |= _FW_WM(tmp, SPRITED_HI) << 8;
+		wm->pipe[PIPE_B].sprite[0] |= _FW_WM(tmp, SPRITEC_HI) << 8;
+		wm->pipe[PIPE_B].primary |= _FW_WM(tmp, PLANEB_HI) << 8;
+		wm->pipe[PIPE_A].sprite[1] |= _FW_WM(tmp, SPRITEB_HI) << 8;
+		wm->pipe[PIPE_A].sprite[0] |= _FW_WM(tmp, SPRITEA_HI) << 8;
+		wm->pipe[PIPE_A].primary |= _FW_WM(tmp, PLANEA_HI) << 8;
+	}
+}
+
+#undef _FW_WM
+#undef _FW_WM_VLV
+
+void vlv_wm_get_hw_state(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = to_i915(dev);
+	struct vlv_wm_values *wm = &dev_priv->wm.vlv;
+	struct intel_plane *plane;
+	enum pipe pipe;
+	u32 val;
+
+	vlv_read_wm_values(dev_priv, wm);
+
+	for_each_intel_plane(dev, plane) {
+		switch (plane->base.type) {
+			int sprite;
+		case DRM_PLANE_TYPE_CURSOR:
+			plane->wm.fifo_size = 63;
+			break;
+		case DRM_PLANE_TYPE_PRIMARY:
+			plane->wm.fifo_size = vlv_get_fifo_size(dev, plane->pipe, 0);
+			break;
+		case DRM_PLANE_TYPE_OVERLAY:
+			sprite = plane->plane;
+			plane->wm.fifo_size = vlv_get_fifo_size(dev, plane->pipe, sprite + 1);
+			break;
+		}
+	}
+
+	wm->cxsr = I915_READ(FW_BLC_SELF_VLV) & FW_CSPWRDWNEN;
+	wm->level = VLV_WM_LEVEL_PM2;
+
+	if (IS_CHERRYVIEW(dev_priv)) {
+		mutex_lock(&dev_priv->rps.hw_lock);
+
+		val = vlv_punit_read(dev_priv, PUNIT_REG_DSPFREQ);
+		if (val & DSP_MAXFIFO_PM5_ENABLE)
+			wm->level = VLV_WM_LEVEL_PM5;
+
+		/*
+		 * If DDR DVFS is disabled in the BIOS, Punit
+		 * will never ack the request. So if that happens
+		 * assume we don't have to enable/disable DDR DVFS
+		 * dynamically. To test that just set the REQ_ACK
+		 * bit to poke the Punit, but don't change the
+		 * HIGH/LOW bits so that we don't actually change
+		 * the current state.
+		 */
+		val = vlv_punit_read(dev_priv, PUNIT_REG_DDR_SETUP2);
+		val |= FORCE_DDR_FREQ_REQ_ACK;
+		vlv_punit_write(dev_priv, PUNIT_REG_DDR_SETUP2, val);
+
+		if (wait_for((vlv_punit_read(dev_priv, PUNIT_REG_DDR_SETUP2) &
+			      FORCE_DDR_FREQ_REQ_ACK) == 0, 3)) {
+			DRM_DEBUG_KMS("Punit not acking DDR DVFS request, "
+				      "assuming DDR DVFS is disabled\n");
+			dev_priv->wm.max_level = VLV_WM_LEVEL_PM5;
+		} else {
+			val = vlv_punit_read(dev_priv, PUNIT_REG_DDR_SETUP2);
+			if ((val & FORCE_DDR_HIGH_FREQ) == 0)
+				wm->level = VLV_WM_LEVEL_DDR_DVFS;
+		}
+
+		mutex_unlock(&dev_priv->rps.hw_lock);
+	}
+
+	for_each_pipe(dev_priv, pipe)
+		DRM_DEBUG_KMS("Initial watermarks: pipe %c, plane=%d, cursor=%d, sprite0=%d, sprite1=%d\n",
+			      pipe_name(pipe), wm->pipe[pipe].primary, wm->pipe[pipe].cursor,
+			      wm->pipe[pipe].sprite[0], wm->pipe[pipe].sprite[1]);
+
+	DRM_DEBUG_KMS("Initial watermarks: SR plane=%d, SR cursor=%d level=%d cxsr=%d\n",
+		      wm->sr.plane, wm->sr.cursor, wm->level, wm->cxsr);
+}
+
+void ilk_wm_get_hw_state(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct ilk_wm_values *hw = &dev_priv->wm.hw;
+	struct drm_crtc *crtc;
+
+	for_each_crtc(dev, crtc)
+		ilk_pipe_wm_get_hw_state(crtc);
+
+	hw->wm_lp[0] = I915_READ(WM1_LP_ILK);
+	hw->wm_lp[1] = I915_READ(WM2_LP_ILK);
+	hw->wm_lp[2] = I915_READ(WM3_LP_ILK);
+
+	hw->wm_lp_spr[0] = I915_READ(WM1S_LP_ILK);
+	if (INTEL_INFO(dev)->gen >= 7) {
+		hw->wm_lp_spr[1] = I915_READ(WM2S_LP_IVB);
+		hw->wm_lp_spr[2] = I915_READ(WM3S_LP_IVB);
+	}
+
+	if (IS_HASWELL(dev) || IS_BROADWELL(dev))
+		hw->partitioning = (I915_READ(WM_MISC) & WM_MISC_DATA_PARTITION_5_6) ?
+			INTEL_DDB_PART_5_6 : INTEL_DDB_PART_1_2;
+	else if (IS_IVYBRIDGE(dev))
+		hw->partitioning = (I915_READ(DISP_ARB_CTL2) & DISP_DATA_PARTITION_5_6) ?
+			INTEL_DDB_PART_5_6 : INTEL_DDB_PART_1_2;
+
+	hw->enable_fbc_wm =
+		!(I915_READ(DISP_ARB_CTL) & DISP_FBC_WM_DIS);
+}
+
+/**
+ * intel_update_watermarks - update FIFO watermark values based on current modes
+ *
+ * Calculate watermark values for the various WM regs based on current mode
+ * and plane configuration.
+ *
+ * There are several cases to deal with here:
+ *   - normal (i.e. non-self-refresh)
+ *   - self-refresh (SR) mode
+ *   - lines are large relative to FIFO size (buffer can hold up to 2)
+ *   - lines are small relative to FIFO size (buffer can hold more than 2
+ *     lines), so need to account for TLB latency
+ *
+ *   The normal calculation is:
+ *     watermark = dotclock * bytes per pixel * latency
+ *   where latency is platform & configuration dependent (we assume pessimal
+ *   values here).
+ *
+ *   The SR calculation is:
+ *     watermark = (trunc(latency/line time)+1) * surface width *
+ *       bytes per pixel
+ *   where
+ *     line time = htotal / dotclock
+ *     surface width = hdisplay for normal plane and 64 for cursor
+ *   and latency is assumed to be high, as above.
+ *
+ * The final value programmed to the register should always be rounded up,
+ * and include an extra 2 entries to account for clock crossings.
+ *
+ * We don't use the sprite, so we can ignore that.  And on Crestline we have
+ * to set the non-SR watermarks to 8.
+ */
+void intel_update_watermarks(struct drm_crtc *crtc)
+{
+	struct drm_i915_private *dev_priv = crtc->dev->dev_private;
+
+	if (dev_priv->display.update_wm)
+		dev_priv->display.update_wm(crtc);
+}
+
+/*
+ * Lock protecting IPS related data structures
+ */
+DEFINE_SPINLOCK(mchdev_lock);
+
+/* Global for IPS driver to get at the current i915 device. Protected by
+ * mchdev_lock. */
+static struct drm_i915_private *i915_mch_dev;
+
+bool ironlake_set_drps(struct drm_device *dev, u8 val)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	u16 rgvswctl;
+
+	assert_spin_locked(&mchdev_lock);
+
+	rgvswctl = I915_READ16(MEMSWCTL);
+	if (rgvswctl & MEMCTL_CMD_STS) {
+		DRM_DEBUG("gpu busy, RCS change rejected\n");
+		return false; /* still busy with another command */
+	}
+
+	rgvswctl = (MEMCTL_CMD_CHFREQ << MEMCTL_CMD_SHIFT) |
+		(val << MEMCTL_FREQ_SHIFT) | MEMCTL_SFCAVM;
+	I915_WRITE16(MEMSWCTL, rgvswctl);
+	POSTING_READ16(MEMSWCTL);
+
+	rgvswctl |= MEMCTL_CMD_STS;
+	I915_WRITE16(MEMSWCTL, rgvswctl);
+
+	return true;
+}
+
+static void ironlake_enable_drps(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	u32 rgvmodectl;
+	u8 fmax, fmin, fstart, vstart;
+
+	spin_lock_irq(&mchdev_lock);
+
+	rgvmodectl = I915_READ(MEMMODECTL);
+
+	/* Enable temp reporting */
+	I915_WRITE16(PMMISC, I915_READ(PMMISC) | MCPPCE_EN);
+	I915_WRITE16(TSC1, I915_READ(TSC1) | TSE);
+
+	/* 100ms RC evaluation intervals */
+	I915_WRITE(RCUPEI, 100000);
+	I915_WRITE(RCDNEI, 100000);
+
+	/* Set max/min thresholds to 90ms and 80ms respectively */
+	I915_WRITE(RCBMAXAVG, 90000);
+	I915_WRITE(RCBMINAVG, 80000);
+
+	I915_WRITE(MEMIHYST, 1);
+
+	/* Set up min, max, and cur for interrupt handling */
+	fmax = (rgvmodectl & MEMMODE_FMAX_MASK) >> MEMMODE_FMAX_SHIFT;
+	fmin = (rgvmodectl & MEMMODE_FMIN_MASK);
+	fstart = (rgvmodectl & MEMMODE_FSTART_MASK) >>
+		MEMMODE_FSTART_SHIFT;
+
+	vstart = (I915_READ(PXVFREQ(fstart)) & PXVFREQ_PX_MASK) >>
+		PXVFREQ_PX_SHIFT;
+
+	dev_priv->ips.fmax = fmax; /* IPS callback will increase this */
+	dev_priv->ips.fstart = fstart;
+
+	dev_priv->ips.max_delay = fstart;
+	dev_priv->ips.min_delay = fmin;
+	dev_priv->ips.cur_delay = fstart;
+
+	DRM_DEBUG_DRIVER("fmax: %d, fmin: %d, fstart: %d\n",
+			 fmax, fmin, fstart);
+
+	I915_WRITE(MEMINTREN, MEMINT_CX_SUPR_EN | MEMINT_EVAL_CHG_EN);
+
+	/*
+	 * Interrupts will be enabled in ironlake_irq_postinstall
+	 */
+
+	I915_WRITE(VIDSTART, vstart);
+	POSTING_READ(VIDSTART);
+
+	rgvmodectl |= MEMMODE_SWMODE_EN;
+	I915_WRITE(MEMMODECTL, rgvmodectl);
+
+	if (wait_for_atomic((I915_READ(MEMSWCTL) & MEMCTL_CMD_STS) == 0, 10))
+		DRM_ERROR("stuck trying to change perf mode\n");
+	mdelay(1);
+
+	ironlake_set_drps(dev, fstart);
+
+	dev_priv->ips.last_count1 = I915_READ(DMIEC) +
+		I915_READ(DDREC) + I915_READ(CSIEC);
+	dev_priv->ips.last_time1 = jiffies_to_msecs(jiffies);
+	dev_priv->ips.last_count2 = I915_READ(GFXEC);
+	dev_priv->ips.last_time2 = ktime_get_raw_ns();
+
+	spin_unlock_irq(&mchdev_lock);
+}
+
+static void ironlake_disable_drps(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	u16 rgvswctl;
+
+	spin_lock_irq(&mchdev_lock);
+
+	rgvswctl = I915_READ16(MEMSWCTL);
+
+	/* Ack interrupts, disable EFC interrupt */
+	I915_WRITE(MEMINTREN, I915_READ(MEMINTREN) & ~MEMINT_EVAL_CHG_EN);
+	I915_WRITE(MEMINTRSTS, MEMINT_EVAL_CHG);
+	I915_WRITE(DEIER, I915_READ(DEIER) & ~DE_PCU_EVENT);
+	I915_WRITE(DEIIR, DE_PCU_EVENT);
+	I915_WRITE(DEIMR, I915_READ(DEIMR) | DE_PCU_EVENT);
+
+	/* Go back to the starting frequency */
+	ironlake_set_drps(dev, dev_priv->ips.fstart);
+	mdelay(1);
+	rgvswctl |= MEMCTL_CMD_STS;
+	I915_WRITE(MEMSWCTL, rgvswctl);
+	mdelay(1);
+
+	spin_unlock_irq(&mchdev_lock);
+}
+
+/* There's a funny hw issue where the hw returns all 0 when reading from
+ * GEN6_RP_INTERRUPT_LIMITS. Hence we always need to compute the desired value
+ * ourselves, instead of doing a rmw cycle (which might result in us clearing
+ * all limits and the gpu stuck at whatever frequency it is at atm).
+ */
+static u32 intel_rps_limits(struct drm_i915_private *dev_priv, u8 val)
+{
+	u32 limits;
+
+	/* Only set the down limit when we've reached the lowest level to avoid
+	 * getting more interrupts, otherwise leave this clear. This prevents a
+	 * race in the hw when coming out of rc6: There's a tiny window where
+	 * the hw runs at the minimal clock before selecting the desired
+	 * frequency, if the down threshold expires in that window we will not
+	 * receive a down interrupt. */
+	if (IS_GEN9(dev_priv)) {
+		limits = (dev_priv->rps.max_freq_softlimit) << 23;
+		if (val <= dev_priv->rps.min_freq_softlimit)
+			limits |= (dev_priv->rps.min_freq_softlimit) << 14;
+	} else {
+		limits = dev_priv->rps.max_freq_softlimit << 24;
+		if (val <= dev_priv->rps.min_freq_softlimit)
+			limits |= dev_priv->rps.min_freq_softlimit << 16;
+	}
+
+	return limits;
+}
+
+static void gen6_set_rps_thresholds(struct drm_i915_private *dev_priv, u8 val)
+{
+	int new_power;
+	u32 threshold_up = 0, threshold_down = 0; /* in % */
+	u32 ei_up = 0, ei_down = 0;
+
+	new_power = dev_priv->rps.power;
+	switch (dev_priv->rps.power) {
+	case LOW_POWER:
+		if (val > dev_priv->rps.efficient_freq + 1 && val > dev_priv->rps.cur_freq)
+			new_power = BETWEEN;
+		break;
+
+	case BETWEEN:
+		if (val <= dev_priv->rps.efficient_freq && val < dev_priv->rps.cur_freq)
+			new_power = LOW_POWER;
+		else if (val >= dev_priv->rps.rp0_freq && val > dev_priv->rps.cur_freq)
+			new_power = HIGH_POWER;
+		break;
+
+	case HIGH_POWER:
+		if (val < (dev_priv->rps.rp1_freq + dev_priv->rps.rp0_freq) >> 1 && val < dev_priv->rps.cur_freq)
+			new_power = BETWEEN;
+		break;
+	}
+	/* Max/min bins are special */
+	if (val <= dev_priv->rps.min_freq_softlimit)
+		new_power = LOW_POWER;
+	if (val >= dev_priv->rps.max_freq_softlimit)
+		new_power = HIGH_POWER;
+	if (new_power == dev_priv->rps.power)
+		return;
+
+	/* Note the units here are not exactly 1us, but 1280ns. */
+	switch (new_power) {
+	case LOW_POWER:
+		/* Upclock if more than 95% busy over 16ms */
+		ei_up = 16000;
+		threshold_up = 95;
+
+		/* Downclock if less than 85% busy over 32ms */
+		ei_down = 32000;
+		threshold_down = 85;
+		break;
+
+	case BETWEEN:
+		/* Upclock if more than 90% busy over 13ms */
+		ei_up = 13000;
+		threshold_up = 90;
+
+		/* Downclock if less than 75% busy over 32ms */
+		ei_down = 32000;
+		threshold_down = 75;
+		break;
+
+	case HIGH_POWER:
+		/* Upclock if more than 85% busy over 10ms */
+		ei_up = 10000;
+		threshold_up = 85;
+
+		/* Downclock if less than 60% busy over 32ms */
+		ei_down = 32000;
+		threshold_down = 60;
+		break;
+	}
+
+	I915_WRITE(GEN6_RP_UP_EI,
+		GT_INTERVAL_FROM_US(dev_priv, ei_up));
+	I915_WRITE(GEN6_RP_UP_THRESHOLD,
+		GT_INTERVAL_FROM_US(dev_priv, (ei_up * threshold_up / 100)));
+
+	I915_WRITE(GEN6_RP_DOWN_EI,
+		GT_INTERVAL_FROM_US(dev_priv, ei_down));
+	I915_WRITE(GEN6_RP_DOWN_THRESHOLD,
+		GT_INTERVAL_FROM_US(dev_priv, (ei_down * threshold_down / 100)));
+
+	 I915_WRITE(GEN6_RP_CONTROL,
+		    GEN6_RP_MEDIA_TURBO |
+		    GEN6_RP_MEDIA_HW_NORMAL_MODE |
+		    GEN6_RP_MEDIA_IS_GFX |
+		    GEN6_RP_ENABLE |
+		    GEN6_RP_UP_BUSY_AVG |
+		    GEN6_RP_DOWN_IDLE_AVG);
+
+	dev_priv->rps.power = new_power;
+	dev_priv->rps.up_threshold = threshold_up;
+	dev_priv->rps.down_threshold = threshold_down;
+	dev_priv->rps.last_adj = 0;
+}
+
+static u32 gen6_rps_pm_mask(struct drm_i915_private *dev_priv, u8 val)
+{
+	u32 mask = 0;
+
+	if (val > dev_priv->rps.min_freq_softlimit)
+		mask |= GEN6_PM_RP_DOWN_EI_EXPIRED | GEN6_PM_RP_DOWN_THRESHOLD | GEN6_PM_RP_DOWN_TIMEOUT;
+	if (val < dev_priv->rps.max_freq_softlimit)
+		mask |= GEN6_PM_RP_UP_EI_EXPIRED | GEN6_PM_RP_UP_THRESHOLD;
+
+	mask &= dev_priv->pm_rps_events;
+
+	return gen6_sanitize_rps_pm_mask(dev_priv, ~mask);
+}
+
+/* gen6_set_rps is called to update the frequency request, but should also be
+ * called when the range (min_delay and max_delay) is modified so that we can
+ * update the GEN6_RP_INTERRUPT_LIMITS register accordingly. */
+static void gen6_set_rps(struct drm_device *dev, u8 val)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	/* WaGsvDisableTurbo: Workaround to disable turbo on BXT A* */
+	if (IS_BXT_REVID(dev, 0, BXT_REVID_A1))
+		return;
+
+	WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock));
+	WARN_ON(val > dev_priv->rps.max_freq);
+	WARN_ON(val < dev_priv->rps.min_freq);
+
+	/* min/max delay may still have been modified so be sure to
+	 * write the limits value.
+	 */
+	if (val != dev_priv->rps.cur_freq) {
+		gen6_set_rps_thresholds(dev_priv, val);
+
+		if (IS_GEN9(dev))
+			I915_WRITE(GEN6_RPNSWREQ,
+				   GEN9_FREQUENCY(val));
+		else if (IS_HASWELL(dev) || IS_BROADWELL(dev))
+			I915_WRITE(GEN6_RPNSWREQ,
+				   HSW_FREQUENCY(val));
+		else
+			I915_WRITE(GEN6_RPNSWREQ,
+				   GEN6_FREQUENCY(val) |
+				   GEN6_OFFSET(0) |
+				   GEN6_AGGRESSIVE_TURBO);
+	}
+
+	/* Make sure we continue to get interrupts
+	 * until we hit the minimum or maximum frequencies.
+	 */
+	I915_WRITE(GEN6_RP_INTERRUPT_LIMITS, intel_rps_limits(dev_priv, val));
+	I915_WRITE(GEN6_PMINTRMSK, gen6_rps_pm_mask(dev_priv, val));
+
+	POSTING_READ(GEN6_RPNSWREQ);
+
+	dev_priv->rps.cur_freq = val;
+	trace_intel_gpu_freq_change(intel_gpu_freq(dev_priv, val));
+}
+
+static void valleyview_set_rps(struct drm_device *dev, u8 val)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock));
+	WARN_ON(val > dev_priv->rps.max_freq);
+	WARN_ON(val < dev_priv->rps.min_freq);
+
+	if (WARN_ONCE(IS_CHERRYVIEW(dev) && (val & 1),
+		      "Odd GPU freq value\n"))
+		val &= ~1;
+
+	I915_WRITE(GEN6_PMINTRMSK, gen6_rps_pm_mask(dev_priv, val));
+
+	if (val != dev_priv->rps.cur_freq) {
+		vlv_punit_write(dev_priv, PUNIT_REG_GPU_FREQ_REQ, val);
+		if (!IS_CHERRYVIEW(dev_priv))
+			gen6_set_rps_thresholds(dev_priv, val);
+	}
+
+	dev_priv->rps.cur_freq = val;
+	trace_intel_gpu_freq_change(intel_gpu_freq(dev_priv, val));
+}
+
+/* vlv_set_rps_idle: Set the frequency to idle, if Gfx clocks are down
+ *
+ * * If Gfx is Idle, then
+ * 1. Forcewake Media well.
+ * 2. Request idle freq.
+ * 3. Release Forcewake of Media well.
+*/
+static void vlv_set_rps_idle(struct drm_i915_private *dev_priv)
+{
+	u32 val = dev_priv->rps.idle_freq;
+
+	if (dev_priv->rps.cur_freq <= val)
+		return;
+
+	/* Wake up the media well, as that takes a lot less
+	 * power than the Render well. */
+	intel_uncore_forcewake_get(dev_priv, FORCEWAKE_MEDIA);
+	valleyview_set_rps(dev_priv->dev, val);
+	intel_uncore_forcewake_put(dev_priv, FORCEWAKE_MEDIA);
+}
+
+void gen6_rps_busy(struct drm_i915_private *dev_priv)
+{
+	mutex_lock(&dev_priv->rps.hw_lock);
+	if (dev_priv->rps.enabled) {
+		if (dev_priv->pm_rps_events & (GEN6_PM_RP_DOWN_EI_EXPIRED | GEN6_PM_RP_UP_EI_EXPIRED))
+			gen6_rps_reset_ei(dev_priv);
+		I915_WRITE(GEN6_PMINTRMSK,
+			   gen6_rps_pm_mask(dev_priv, dev_priv->rps.cur_freq));
+	}
+	mutex_unlock(&dev_priv->rps.hw_lock);
+}
+
+void gen6_rps_idle(struct drm_i915_private *dev_priv)
+{
+	struct drm_device *dev = dev_priv->dev;
+
+	mutex_lock(&dev_priv->rps.hw_lock);
+	if (dev_priv->rps.enabled) {
+		if (IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev))
+			vlv_set_rps_idle(dev_priv);
+		else
+			gen6_set_rps(dev_priv->dev, dev_priv->rps.idle_freq);
+		dev_priv->rps.last_adj = 0;
+		I915_WRITE(GEN6_PMINTRMSK, 0xffffffff);
+	}
+	mutex_unlock(&dev_priv->rps.hw_lock);
+
+	spin_lock(&dev_priv->rps.client_lock);
+	while (!list_empty(&dev_priv->rps.clients))
+		list_del_init(dev_priv->rps.clients.next);
+	spin_unlock(&dev_priv->rps.client_lock);
+}
+
+void gen6_rps_boost(struct drm_i915_private *dev_priv,
+		    struct intel_rps_client *rps,
+		    unsigned long submitted)
+{
+	/* This is intentionally racy! We peek at the state here, then
+	 * validate inside the RPS worker.
+	 */
+	if (!(dev_priv->mm.busy &&
+	      dev_priv->rps.enabled &&
+	      dev_priv->rps.cur_freq < dev_priv->rps.max_freq_softlimit))
+		return;
+
+	/* Force a RPS boost (and don't count it against the client) if
+	 * the GPU is severely congested.
+	 */
+	if (rps && time_after(jiffies, submitted + DRM_I915_THROTTLE_JIFFIES))
+		rps = NULL;
+
+	spin_lock(&dev_priv->rps.client_lock);
+	if (rps == NULL || list_empty(&rps->link)) {
+		spin_lock_irq(&dev_priv->irq_lock);
+		if (dev_priv->rps.interrupts_enabled) {
+			dev_priv->rps.client_boost = true;
+			queue_work(dev_priv->wq, &dev_priv->rps.work);
+		}
+		spin_unlock_irq(&dev_priv->irq_lock);
+
+		if (rps != NULL) {
+			list_add(&rps->link, &dev_priv->rps.clients);
+			rps->boosts++;
+		} else
+			dev_priv->rps.boosts++;
+	}
+	spin_unlock(&dev_priv->rps.client_lock);
+}
+
+void intel_set_rps(struct drm_device *dev, u8 val)
+{
+	if (IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev))
+		valleyview_set_rps(dev, val);
+	else
+		gen6_set_rps(dev, val);
+}
+
+static void gen9_disable_rc6(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	I915_WRITE(GEN6_RC_CONTROL, 0);
+	I915_WRITE(GEN9_PG_ENABLE, 0);
+}
+
+static void gen9_disable_rps(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	I915_WRITE(GEN6_RP_CONTROL, 0);
+}
+
+static void gen6_disable_rps(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	I915_WRITE(GEN6_RC_CONTROL, 0);
+	I915_WRITE(GEN6_RPNSWREQ, 1 << 31);
+	I915_WRITE(GEN6_RP_CONTROL, 0);
+}
+
+static void cherryview_disable_rps(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	I915_WRITE(GEN6_RC_CONTROL, 0);
+}
+
+static void valleyview_disable_rps(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	/* we're doing forcewake before Disabling RC6,
+	 * This what the BIOS expects when going into suspend */
+	intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL);
+
+	I915_WRITE(GEN6_RC_CONTROL, 0);
+
+	intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
+}
+
+static void intel_print_rc6_info(struct drm_device *dev, u32 mode)
+{
+	if (IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev)) {
+		if (mode & (GEN7_RC_CTL_TO_MODE | GEN6_RC_CTL_EI_MODE(1)))
+			mode = GEN6_RC_CTL_RC6_ENABLE;
+		else
+			mode = 0;
+	}
+	if (HAS_RC6p(dev))
+		DRM_DEBUG_KMS("Enabling RC6 states: RC6 %s RC6p %s RC6pp %s\n",
+			      onoff(mode & GEN6_RC_CTL_RC6_ENABLE),
+			      onoff(mode & GEN6_RC_CTL_RC6p_ENABLE),
+			      onoff(mode & GEN6_RC_CTL_RC6pp_ENABLE));
+
+	else
+		DRM_DEBUG_KMS("Enabling RC6 states: RC6 %s\n",
+			      onoff(mode & GEN6_RC_CTL_RC6_ENABLE));
+}
+
+static bool bxt_check_bios_rc6_setup(const struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = to_i915(dev);
+	struct i915_ggtt *ggtt = &dev_priv->ggtt;
+	bool enable_rc6 = true;
+	unsigned long rc6_ctx_base;
+
+	if (!(I915_READ(RC6_LOCATION) & RC6_CTX_IN_DRAM)) {
+		DRM_DEBUG_KMS("RC6 Base location not set properly.\n");
+		enable_rc6 = false;
+	}
+
+	/*
+	 * The exact context size is not known for BXT, so assume a page size
+	 * for this check.
+	 */
+	rc6_ctx_base = I915_READ(RC6_CTX_BASE) & RC6_CTX_BASE_MASK;
+	if (!((rc6_ctx_base >= ggtt->stolen_reserved_base) &&
+	      (rc6_ctx_base + PAGE_SIZE <= ggtt->stolen_reserved_base +
+					ggtt->stolen_reserved_size))) {
+		DRM_DEBUG_KMS("RC6 Base address not as expected.\n");
+		enable_rc6 = false;
+	}
+
+	if (!(((I915_READ(PWRCTX_MAXCNT_RCSUNIT) & IDLE_TIME_MASK) > 1) &&
+	      ((I915_READ(PWRCTX_MAXCNT_VCSUNIT0) & IDLE_TIME_MASK) > 1) &&
+	      ((I915_READ(PWRCTX_MAXCNT_BCSUNIT) & IDLE_TIME_MASK) > 1) &&
+	      ((I915_READ(PWRCTX_MAXCNT_VECSUNIT) & IDLE_TIME_MASK) > 1))) {
+		DRM_DEBUG_KMS("Engine Idle wait time not set properly.\n");
+		enable_rc6 = false;
+	}
+
+	if (!(I915_READ(GEN6_RC_CONTROL) & (GEN6_RC_CTL_RC6_ENABLE |
+					    GEN6_RC_CTL_HW_ENABLE)) &&
+	    ((I915_READ(GEN6_RC_CONTROL) & GEN6_RC_CTL_HW_ENABLE) ||
+	     !(I915_READ(GEN6_RC_STATE) & RC6_STATE))) {
+		DRM_DEBUG_KMS("HW/SW RC6 is not enabled by BIOS.\n");
+		enable_rc6 = false;
+	}
+
+	return enable_rc6;
+}
+
+int sanitize_rc6_option(const struct drm_device *dev, int enable_rc6)
+{
+	/* No RC6 before Ironlake and code is gone for ilk. */
+	if (INTEL_INFO(dev)->gen < 6)
+		return 0;
+
+	if (!enable_rc6)
+		return 0;
+
+	if (IS_BROXTON(dev) && !bxt_check_bios_rc6_setup(dev)) {
+		DRM_INFO("RC6 disabled by BIOS\n");
+		return 0;
+	}
+
+	/* Respect the kernel parameter if it is set */
+	if (enable_rc6 >= 0) {
+		int mask;
+
+		if (HAS_RC6p(dev))
+			mask = INTEL_RC6_ENABLE | INTEL_RC6p_ENABLE |
+			       INTEL_RC6pp_ENABLE;
+		else
+			mask = INTEL_RC6_ENABLE;
+
+		if ((enable_rc6 & mask) != enable_rc6)
+			DRM_DEBUG_KMS("Adjusting RC6 mask to %d (requested %d, valid %d)\n",
+				      enable_rc6 & mask, enable_rc6, mask);
+
+		return enable_rc6 & mask;
+	}
+
+	if (IS_IVYBRIDGE(dev))
+		return (INTEL_RC6_ENABLE | INTEL_RC6p_ENABLE);
+
+	return INTEL_RC6_ENABLE;
+}
+
+int intel_enable_rc6(const struct drm_device *dev)
+{
+	return i915.enable_rc6;
+}
+
+static void gen6_init_rps_frequencies(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	uint32_t rp_state_cap;
+	u32 ddcc_status = 0;
+	int ret;
+
+	/* All of these values are in units of 50MHz */
+	dev_priv->rps.cur_freq		= 0;
+	/* static values from HW: RP0 > RP1 > RPn (min_freq) */
+	if (IS_BROXTON(dev)) {
+		rp_state_cap = I915_READ(BXT_RP_STATE_CAP);
+		dev_priv->rps.rp0_freq = (rp_state_cap >> 16) & 0xff;
+		dev_priv->rps.rp1_freq = (rp_state_cap >>  8) & 0xff;
+		dev_priv->rps.min_freq = (rp_state_cap >>  0) & 0xff;
+	} else {
+		rp_state_cap = I915_READ(GEN6_RP_STATE_CAP);
+		dev_priv->rps.rp0_freq = (rp_state_cap >>  0) & 0xff;
+		dev_priv->rps.rp1_freq = (rp_state_cap >>  8) & 0xff;
+		dev_priv->rps.min_freq = (rp_state_cap >> 16) & 0xff;
+	}
+
+	/* hw_max = RP0 until we check for overclocking */
+	dev_priv->rps.max_freq		= dev_priv->rps.rp0_freq;
+
+	dev_priv->rps.efficient_freq = dev_priv->rps.rp1_freq;
+	if (IS_HASWELL(dev) || IS_BROADWELL(dev) ||
+	    IS_SKYLAKE(dev) || IS_KABYLAKE(dev)) {
+		ret = sandybridge_pcode_read(dev_priv,
+					HSW_PCODE_DYNAMIC_DUTY_CYCLE_CONTROL,
+					&ddcc_status);
+		if (0 == ret)
+			dev_priv->rps.efficient_freq =
+				clamp_t(u8,
+					((ddcc_status >> 8) & 0xff),
+					dev_priv->rps.min_freq,
+					dev_priv->rps.max_freq);
+	}
+
+	if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev)) {
+		/* Store the frequency values in 16.66 MHZ units, which is
+		   the natural hardware unit for SKL */
+		dev_priv->rps.rp0_freq *= GEN9_FREQ_SCALER;
+		dev_priv->rps.rp1_freq *= GEN9_FREQ_SCALER;
+		dev_priv->rps.min_freq *= GEN9_FREQ_SCALER;
+		dev_priv->rps.max_freq *= GEN9_FREQ_SCALER;
+		dev_priv->rps.efficient_freq *= GEN9_FREQ_SCALER;
+	}
+
+	dev_priv->rps.idle_freq = dev_priv->rps.min_freq;
+
+	/* Preserve min/max settings in case of re-init */
+	if (dev_priv->rps.max_freq_softlimit == 0)
+		dev_priv->rps.max_freq_softlimit = dev_priv->rps.max_freq;
+
+	if (dev_priv->rps.min_freq_softlimit == 0) {
+		if (IS_HASWELL(dev) || IS_BROADWELL(dev))
+			dev_priv->rps.min_freq_softlimit =
+				max_t(int, dev_priv->rps.efficient_freq,
+				      intel_freq_opcode(dev_priv, 450));
+		else
+			dev_priv->rps.min_freq_softlimit =
+				dev_priv->rps.min_freq;
+	}
+}
+
+/* See the Gen9_GT_PM_Programming_Guide doc for the below */
+static void gen9_enable_rps(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL);
+
+	gen6_init_rps_frequencies(dev);
+
+	/* WaGsvDisableTurbo: Workaround to disable turbo on BXT A* */
+	if (IS_BXT_REVID(dev, 0, BXT_REVID_A1)) {
+		/*
+		 * BIOS could leave the Hw Turbo enabled, so need to explicitly
+		 * clear out the Control register just to avoid inconsitency
+		 * with debugfs interface, which will show  Turbo as enabled
+		 * only and that is not expected by the User after adding the
+		 * WaGsvDisableTurbo. Apart from this there is no problem even
+		 * if the Turbo is left enabled in the Control register, as the
+		 * Up/Down interrupts would remain masked.
+		 */
+		gen9_disable_rps(dev);
+		intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
+		return;
+	}
+
+	/* Program defaults and thresholds for RPS*/
+	I915_WRITE(GEN6_RC_VIDEO_FREQ,
+		GEN9_FREQUENCY(dev_priv->rps.rp1_freq));
+
+	/* 1 second timeout*/
+	I915_WRITE(GEN6_RP_DOWN_TIMEOUT,
+		GT_INTERVAL_FROM_US(dev_priv, 1000000));
+
+	I915_WRITE(GEN6_RP_IDLE_HYSTERSIS, 0xa);
+
+	/* Leaning on the below call to gen6_set_rps to program/setup the
+	 * Up/Down EI & threshold registers, as well as the RP_CONTROL,
+	 * RP_INTERRUPT_LIMITS & RPNSWREQ registers */
+	dev_priv->rps.power = HIGH_POWER; /* force a reset */
+	gen6_set_rps(dev_priv->dev, dev_priv->rps.idle_freq);
+
+	intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
+}
+
+static void gen9_enable_rc6(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_engine_cs *engine;
+	uint32_t rc6_mask = 0;
+
+	/* 1a: Software RC state - RC0 */
+	I915_WRITE(GEN6_RC_STATE, 0);
+
+	/* 1b: Get forcewake during program sequence. Although the driver
+	 * hasn't enabled a state yet where we need forcewake, BIOS may have.*/
+	intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL);
+
+	/* 2a: Disable RC states. */
+	I915_WRITE(GEN6_RC_CONTROL, 0);
+
+	/* 2b: Program RC6 thresholds.*/
+
+	/* WaRsDoubleRc6WrlWithCoarsePowerGating: Doubling WRL only when CPG is enabled */
+	if (IS_SKYLAKE(dev))
+		I915_WRITE(GEN6_RC6_WAKE_RATE_LIMIT, 108 << 16);
+	else
+		I915_WRITE(GEN6_RC6_WAKE_RATE_LIMIT, 54 << 16);
+	I915_WRITE(GEN6_RC_EVALUATION_INTERVAL, 125000); /* 12500 * 1280ns */
+	I915_WRITE(GEN6_RC_IDLE_HYSTERSIS, 25); /* 25 * 1280ns */
+	for_each_engine(engine, dev_priv)
+		I915_WRITE(RING_MAX_IDLE(engine->mmio_base), 10);
+
+	if (HAS_GUC_UCODE(dev))
+		I915_WRITE(GUC_MAX_IDLE_COUNT, 0xA);
+
+	I915_WRITE(GEN6_RC_SLEEP, 0);
+
+	/* 2c: Program Coarse Power Gating Policies. */
+	I915_WRITE(GEN9_MEDIA_PG_IDLE_HYSTERESIS, 25);
+	I915_WRITE(GEN9_RENDER_PG_IDLE_HYSTERESIS, 25);
+
+	/* 3a: Enable RC6 */
+	if (intel_enable_rc6(dev) & INTEL_RC6_ENABLE)
+		rc6_mask = GEN6_RC_CTL_RC6_ENABLE;
+	DRM_INFO("RC6 %s\n", onoff(rc6_mask & GEN6_RC_CTL_RC6_ENABLE));
+	/* WaRsUseTimeoutMode */
+	if (IS_SKL_REVID(dev, 0, SKL_REVID_D0) ||
+	    IS_BXT_REVID(dev, 0, BXT_REVID_A1)) {
+		I915_WRITE(GEN6_RC6_THRESHOLD, 625); /* 800us */
+		I915_WRITE(GEN6_RC_CONTROL, GEN6_RC_CTL_HW_ENABLE |
+			   GEN7_RC_CTL_TO_MODE |
+			   rc6_mask);
+	} else {
+		I915_WRITE(GEN6_RC6_THRESHOLD, 37500); /* 37.5/125ms per EI */
+		I915_WRITE(GEN6_RC_CONTROL, GEN6_RC_CTL_HW_ENABLE |
+			   GEN6_RC_CTL_EI_MODE(1) |
+			   rc6_mask);
+	}
+
+	/*
+	 * 3b: Enable Coarse Power Gating only when RC6 is enabled.
+	 * WaRsDisableCoarsePowerGating:skl,bxt - Render/Media PG need to be disabled with RC6.
+	 */
+	if (NEEDS_WaRsDisableCoarsePowerGating(dev))
+		I915_WRITE(GEN9_PG_ENABLE, 0);
+	else
+		I915_WRITE(GEN9_PG_ENABLE, (rc6_mask & GEN6_RC_CTL_RC6_ENABLE) ?
+				(GEN9_RENDER_PG_ENABLE | GEN9_MEDIA_PG_ENABLE) : 0);
+
+	intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
+
+}
+
+static void gen8_enable_rps(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_engine_cs *engine;
+	uint32_t rc6_mask = 0;
+
+	/* 1a: Software RC state - RC0 */
+	I915_WRITE(GEN6_RC_STATE, 0);
+
+	/* 1c & 1d: Get forcewake during program sequence. Although the driver
+	 * hasn't enabled a state yet where we need forcewake, BIOS may have.*/
+	intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL);
+
+	/* 2a: Disable RC states. */
+	I915_WRITE(GEN6_RC_CONTROL, 0);
+
+	/* Initialize rps frequencies */
+	gen6_init_rps_frequencies(dev);
+
+	/* 2b: Program RC6 thresholds.*/
+	I915_WRITE(GEN6_RC6_WAKE_RATE_LIMIT, 40 << 16);
+	I915_WRITE(GEN6_RC_EVALUATION_INTERVAL, 125000); /* 12500 * 1280ns */
+	I915_WRITE(GEN6_RC_IDLE_HYSTERSIS, 25); /* 25 * 1280ns */
+	for_each_engine(engine, dev_priv)
+		I915_WRITE(RING_MAX_IDLE(engine->mmio_base), 10);
+	I915_WRITE(GEN6_RC_SLEEP, 0);
+	if (IS_BROADWELL(dev))
+		I915_WRITE(GEN6_RC6_THRESHOLD, 625); /* 800us/1.28 for TO */
+	else
+		I915_WRITE(GEN6_RC6_THRESHOLD, 50000); /* 50/125ms per EI */
+
+	/* 3: Enable RC6 */
+	if (intel_enable_rc6(dev) & INTEL_RC6_ENABLE)
+		rc6_mask = GEN6_RC_CTL_RC6_ENABLE;
+	intel_print_rc6_info(dev, rc6_mask);
+	if (IS_BROADWELL(dev))
+		I915_WRITE(GEN6_RC_CONTROL, GEN6_RC_CTL_HW_ENABLE |
+				GEN7_RC_CTL_TO_MODE |
+				rc6_mask);
+	else
+		I915_WRITE(GEN6_RC_CONTROL, GEN6_RC_CTL_HW_ENABLE |
+				GEN6_RC_CTL_EI_MODE(1) |
+				rc6_mask);
+
+	/* 4 Program defaults and thresholds for RPS*/
+	I915_WRITE(GEN6_RPNSWREQ,
+		   HSW_FREQUENCY(dev_priv->rps.rp1_freq));
+	I915_WRITE(GEN6_RC_VIDEO_FREQ,
+		   HSW_FREQUENCY(dev_priv->rps.rp1_freq));
+	/* NB: Docs say 1s, and 1000000 - which aren't equivalent */
+	I915_WRITE(GEN6_RP_DOWN_TIMEOUT, 100000000 / 128); /* 1 second timeout */
+
+	/* Docs recommend 900MHz, and 300 MHz respectively */
+	I915_WRITE(GEN6_RP_INTERRUPT_LIMITS,
+		   dev_priv->rps.max_freq_softlimit << 24 |
+		   dev_priv->rps.min_freq_softlimit << 16);
+
+	I915_WRITE(GEN6_RP_UP_THRESHOLD, 7600000 / 128); /* 76ms busyness per EI, 90% */
+	I915_WRITE(GEN6_RP_DOWN_THRESHOLD, 31300000 / 128); /* 313ms busyness per EI, 70%*/
+	I915_WRITE(GEN6_RP_UP_EI, 66000); /* 84.48ms, XXX: random? */
+	I915_WRITE(GEN6_RP_DOWN_EI, 350000); /* 448ms, XXX: random? */
+
+	I915_WRITE(GEN6_RP_IDLE_HYSTERSIS, 10);
+
+	/* 5: Enable RPS */
+	I915_WRITE(GEN6_RP_CONTROL,
+		   GEN6_RP_MEDIA_TURBO |
+		   GEN6_RP_MEDIA_HW_NORMAL_MODE |
+		   GEN6_RP_MEDIA_IS_GFX |
+		   GEN6_RP_ENABLE |
+		   GEN6_RP_UP_BUSY_AVG |
+		   GEN6_RP_DOWN_IDLE_AVG);
+
+	/* 6: Ring frequency + overclocking (our driver does this later */
+
+	dev_priv->rps.power = HIGH_POWER; /* force a reset */
+	gen6_set_rps(dev_priv->dev, dev_priv->rps.idle_freq);
+
+	intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
+}
+
+static void gen6_enable_rps(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_engine_cs *engine;
+	u32 rc6vids, pcu_mbox = 0, rc6_mask = 0;
+	u32 gtfifodbg;
+	int rc6_mode;
+	int ret;
+
+	WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock));
+
+	/* Here begins a magic sequence of register writes to enable
+	 * auto-downclocking.
+	 *
+	 * Perhaps there might be some value in exposing these to
+	 * userspace...
+	 */
+	I915_WRITE(GEN6_RC_STATE, 0);
+
+	/* Clear the DBG now so we don't confuse earlier errors */
+	gtfifodbg = I915_READ(GTFIFODBG);
+	if (gtfifodbg) {
+		DRM_ERROR("GT fifo had a previous error %x\n", gtfifodbg);
+		I915_WRITE(GTFIFODBG, gtfifodbg);
+	}
+
+	intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL);
+
+	/* Initialize rps frequencies */
+	gen6_init_rps_frequencies(dev);
+
+	/* disable the counters and set deterministic thresholds */
+	I915_WRITE(GEN6_RC_CONTROL, 0);
+
+	I915_WRITE(GEN6_RC1_WAKE_RATE_LIMIT, 1000 << 16);
+	I915_WRITE(GEN6_RC6_WAKE_RATE_LIMIT, 40 << 16 | 30);
+	I915_WRITE(GEN6_RC6pp_WAKE_RATE_LIMIT, 30);
+	I915_WRITE(GEN6_RC_EVALUATION_INTERVAL, 125000);
+	I915_WRITE(GEN6_RC_IDLE_HYSTERSIS, 25);
+
+	for_each_engine(engine, dev_priv)
+		I915_WRITE(RING_MAX_IDLE(engine->mmio_base), 10);
+
+	I915_WRITE(GEN6_RC_SLEEP, 0);
+	I915_WRITE(GEN6_RC1e_THRESHOLD, 1000);
+	if (IS_IVYBRIDGE(dev))
+		I915_WRITE(GEN6_RC6_THRESHOLD, 125000);
+	else
+		I915_WRITE(GEN6_RC6_THRESHOLD, 50000);
+	I915_WRITE(GEN6_RC6p_THRESHOLD, 150000);
+	I915_WRITE(GEN6_RC6pp_THRESHOLD, 64000); /* unused */
+
+	/* Check if we are enabling RC6 */
+	rc6_mode = intel_enable_rc6(dev_priv->dev);
+	if (rc6_mode & INTEL_RC6_ENABLE)
+		rc6_mask |= GEN6_RC_CTL_RC6_ENABLE;
+
+	/* We don't use those on Haswell */
+	if (!IS_HASWELL(dev)) {
+		if (rc6_mode & INTEL_RC6p_ENABLE)
+			rc6_mask |= GEN6_RC_CTL_RC6p_ENABLE;
+
+		if (rc6_mode & INTEL_RC6pp_ENABLE)
+			rc6_mask |= GEN6_RC_CTL_RC6pp_ENABLE;
+	}
+
+	intel_print_rc6_info(dev, rc6_mask);
+
+	I915_WRITE(GEN6_RC_CONTROL,
+		   rc6_mask |
+		   GEN6_RC_CTL_EI_MODE(1) |
+		   GEN6_RC_CTL_HW_ENABLE);
+
+	/* Power down if completely idle for over 50ms */
+	I915_WRITE(GEN6_RP_DOWN_TIMEOUT, 50000);
+	I915_WRITE(GEN6_RP_IDLE_HYSTERSIS, 10);
+
+	ret = sandybridge_pcode_write(dev_priv, GEN6_PCODE_WRITE_MIN_FREQ_TABLE, 0);
+	if (ret)
+		DRM_DEBUG_DRIVER("Failed to set the min frequency\n");
+
+	ret = sandybridge_pcode_read(dev_priv, GEN6_READ_OC_PARAMS, &pcu_mbox);
+	if (!ret && (pcu_mbox & (1<<31))) { /* OC supported */
+		DRM_DEBUG_DRIVER("Overclocking supported. Max: %dMHz, Overclock max: %dMHz\n",
+				 (dev_priv->rps.max_freq_softlimit & 0xff) * 50,
+				 (pcu_mbox & 0xff) * 50);
+		dev_priv->rps.max_freq = pcu_mbox & 0xff;
+	}
+
+	dev_priv->rps.power = HIGH_POWER; /* force a reset */
+	gen6_set_rps(dev_priv->dev, dev_priv->rps.idle_freq);
+
+	rc6vids = 0;
+	ret = sandybridge_pcode_read(dev_priv, GEN6_PCODE_READ_RC6VIDS, &rc6vids);
+	if (IS_GEN6(dev) && ret) {
+		DRM_DEBUG_DRIVER("Couldn't check for BIOS workaround\n");
+	} else if (IS_GEN6(dev) && (GEN6_DECODE_RC6_VID(rc6vids & 0xff) < 450)) {
+		DRM_DEBUG_DRIVER("You should update your BIOS. Correcting minimum rc6 voltage (%dmV->%dmV)\n",
+			  GEN6_DECODE_RC6_VID(rc6vids & 0xff), 450);
+		rc6vids &= 0xffff00;
+		rc6vids |= GEN6_ENCODE_RC6_VID(450);
+		ret = sandybridge_pcode_write(dev_priv, GEN6_PCODE_WRITE_RC6VIDS, rc6vids);
+		if (ret)
+			DRM_ERROR("Couldn't fix incorrect rc6 voltage\n");
+	}
+
+	intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
+}
+
+static void __gen6_update_ring_freq(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	int min_freq = 15;
+	unsigned int gpu_freq;
+	unsigned int max_ia_freq, min_ring_freq;
+	unsigned int max_gpu_freq, min_gpu_freq;
+	int scaling_factor = 180;
+	struct cpufreq_policy *policy;
+
+	WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock));
+
+	policy = cpufreq_cpu_get(0);
+	if (policy) {
+		max_ia_freq = policy->cpuinfo.max_freq;
+		cpufreq_cpu_put(policy);
+	} else {
+		/*
+		 * Default to measured freq if none found, PCU will ensure we
+		 * don't go over
+		 */
+		max_ia_freq = tsc_khz;
+	}
+
+	/* Convert from kHz to MHz */
+	max_ia_freq /= 1000;
+
+	min_ring_freq = I915_READ(DCLK) & 0xf;
+	/* convert DDR frequency from units of 266.6MHz to bandwidth */
+	min_ring_freq = mult_frac(min_ring_freq, 8, 3);
+
+	if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev)) {
+		/* Convert GT frequency to 50 HZ units */
+		min_gpu_freq = dev_priv->rps.min_freq / GEN9_FREQ_SCALER;
+		max_gpu_freq = dev_priv->rps.max_freq / GEN9_FREQ_SCALER;
+	} else {
+		min_gpu_freq = dev_priv->rps.min_freq;
+		max_gpu_freq = dev_priv->rps.max_freq;
+	}
+
+	/*
+	 * For each potential GPU frequency, load a ring frequency we'd like
+	 * to use for memory access.  We do this by specifying the IA frequency
+	 * the PCU should use as a reference to determine the ring frequency.
+	 */
+	for (gpu_freq = max_gpu_freq; gpu_freq >= min_gpu_freq; gpu_freq--) {
+		int diff = max_gpu_freq - gpu_freq;
+		unsigned int ia_freq = 0, ring_freq = 0;
+
+		if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev)) {
+			/*
+			 * ring_freq = 2 * GT. ring_freq is in 100MHz units
+			 * No floor required for ring frequency on SKL.
+			 */
+			ring_freq = gpu_freq;
+		} else if (INTEL_INFO(dev)->gen >= 8) {
+			/* max(2 * GT, DDR). NB: GT is 50MHz units */
+			ring_freq = max(min_ring_freq, gpu_freq);
+		} else if (IS_HASWELL(dev)) {
+			ring_freq = mult_frac(gpu_freq, 5, 4);
+			ring_freq = max(min_ring_freq, ring_freq);
+			/* leave ia_freq as the default, chosen by cpufreq */
+		} else {
+			/* On older processors, there is no separate ring
+			 * clock domain, so in order to boost the bandwidth
+			 * of the ring, we need to upclock the CPU (ia_freq).
+			 *
+			 * For GPU frequencies less than 750MHz,
+			 * just use the lowest ring freq.
+			 */
+			if (gpu_freq < min_freq)
+				ia_freq = 800;
+			else
+				ia_freq = max_ia_freq - ((diff * scaling_factor) / 2);
+			ia_freq = DIV_ROUND_CLOSEST(ia_freq, 100);
+		}
+
+		sandybridge_pcode_write(dev_priv,
+					GEN6_PCODE_WRITE_MIN_FREQ_TABLE,
+					ia_freq << GEN6_PCODE_FREQ_IA_RATIO_SHIFT |
+					ring_freq << GEN6_PCODE_FREQ_RING_RATIO_SHIFT |
+					gpu_freq);
+	}
+}
+
+void gen6_update_ring_freq(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	if (!HAS_CORE_RING_FREQ(dev))
+		return;
+
+	mutex_lock(&dev_priv->rps.hw_lock);
+	__gen6_update_ring_freq(dev);
+	mutex_unlock(&dev_priv->rps.hw_lock);
+}
+
+static int cherryview_rps_max_freq(struct drm_i915_private *dev_priv)
+{
+	struct drm_device *dev = dev_priv->dev;
+	u32 val, rp0;
+
+	val = vlv_punit_read(dev_priv, FB_GFX_FMAX_AT_VMAX_FUSE);
+
+	switch (INTEL_INFO(dev)->eu_total) {
+	case 8:
+		/* (2 * 4) config */
+		rp0 = (val >> FB_GFX_FMAX_AT_VMAX_2SS4EU_FUSE_SHIFT);
+		break;
+	case 12:
+		/* (2 * 6) config */
+		rp0 = (val >> FB_GFX_FMAX_AT_VMAX_2SS6EU_FUSE_SHIFT);
+		break;
+	case 16:
+		/* (2 * 8) config */
+	default:
+		/* Setting (2 * 8) Min RP0 for any other combination */
+		rp0 = (val >> FB_GFX_FMAX_AT_VMAX_2SS8EU_FUSE_SHIFT);
+		break;
+	}
+
+	rp0 = (rp0 & FB_GFX_FREQ_FUSE_MASK);
+
+	return rp0;
+}
+
+static int cherryview_rps_rpe_freq(struct drm_i915_private *dev_priv)
+{
+	u32 val, rpe;
+
+	val = vlv_punit_read(dev_priv, PUNIT_GPU_DUTYCYCLE_REG);
+	rpe = (val >> PUNIT_GPU_DUTYCYCLE_RPE_FREQ_SHIFT) & PUNIT_GPU_DUTYCYCLE_RPE_FREQ_MASK;
+
+	return rpe;
+}
+
+static int cherryview_rps_guar_freq(struct drm_i915_private *dev_priv)
+{
+	u32 val, rp1;
+
+	val = vlv_punit_read(dev_priv, FB_GFX_FMAX_AT_VMAX_FUSE);
+	rp1 = (val & FB_GFX_FREQ_FUSE_MASK);
+
+	return rp1;
+}
+
+static int valleyview_rps_guar_freq(struct drm_i915_private *dev_priv)
+{
+	u32 val, rp1;
+
+	val = vlv_nc_read(dev_priv, IOSF_NC_FB_GFX_FREQ_FUSE);
+
+	rp1 = (val & FB_GFX_FGUARANTEED_FREQ_FUSE_MASK) >> FB_GFX_FGUARANTEED_FREQ_FUSE_SHIFT;
+
+	return rp1;
+}
+
+static int valleyview_rps_max_freq(struct drm_i915_private *dev_priv)
+{
+	u32 val, rp0;
+
+	val = vlv_nc_read(dev_priv, IOSF_NC_FB_GFX_FREQ_FUSE);
+
+	rp0 = (val & FB_GFX_MAX_FREQ_FUSE_MASK) >> FB_GFX_MAX_FREQ_FUSE_SHIFT;
+	/* Clamp to max */
+	rp0 = min_t(u32, rp0, 0xea);
+
+	return rp0;
+}
+
+static int valleyview_rps_rpe_freq(struct drm_i915_private *dev_priv)
+{
+	u32 val, rpe;
+
+	val = vlv_nc_read(dev_priv, IOSF_NC_FB_GFX_FMAX_FUSE_LO);
+	rpe = (val & FB_FMAX_VMIN_FREQ_LO_MASK) >> FB_FMAX_VMIN_FREQ_LO_SHIFT;
+	val = vlv_nc_read(dev_priv, IOSF_NC_FB_GFX_FMAX_FUSE_HI);
+	rpe |= (val & FB_FMAX_VMIN_FREQ_HI_MASK) << 5;
+
+	return rpe;
+}
+
+static int valleyview_rps_min_freq(struct drm_i915_private *dev_priv)
+{
+	u32 val;
+
+	val = vlv_punit_read(dev_priv, PUNIT_REG_GPU_LFM) & 0xff;
+	/*
+	 * According to the BYT Punit GPU turbo HAS 1.1.6.3 the minimum value
+	 * for the minimum frequency in GPLL mode is 0xc1. Contrary to this on
+	 * a BYT-M B0 the above register contains 0xbf. Moreover when setting
+	 * a frequency Punit will not allow values below 0xc0. Clamp it 0xc0
+	 * to make sure it matches what Punit accepts.
+	 */
+	return max_t(u32, val, 0xc0);
+}
+
+/* Check that the pctx buffer wasn't move under us. */
+static void valleyview_check_pctx(struct drm_i915_private *dev_priv)
+{
+	unsigned long pctx_addr = I915_READ(VLV_PCBR) & ~4095;
+
+	WARN_ON(pctx_addr != dev_priv->mm.stolen_base +
+			     dev_priv->vlv_pctx->stolen->start);
+}
+
+
+/* Check that the pcbr address is not empty. */
+static void cherryview_check_pctx(struct drm_i915_private *dev_priv)
+{
+	unsigned long pctx_addr = I915_READ(VLV_PCBR) & ~4095;
+
+	WARN_ON((pctx_addr >> VLV_PCBR_ADDR_SHIFT) == 0);
+}
+
+static void cherryview_setup_pctx(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = to_i915(dev);
+	struct i915_ggtt *ggtt = &dev_priv->ggtt;
+	unsigned long pctx_paddr, paddr;
+	u32 pcbr;
+	int pctx_size = 32*1024;
+
+	pcbr = I915_READ(VLV_PCBR);
+	if ((pcbr >> VLV_PCBR_ADDR_SHIFT) == 0) {
+		DRM_DEBUG_DRIVER("BIOS didn't set up PCBR, fixing up\n");
+		paddr = (dev_priv->mm.stolen_base +
+			 (ggtt->stolen_size - pctx_size));
+
+		pctx_paddr = (paddr & (~4095));
+		I915_WRITE(VLV_PCBR, pctx_paddr);
+	}
+
+	DRM_DEBUG_DRIVER("PCBR: 0x%08x\n", I915_READ(VLV_PCBR));
+}
+
+static void valleyview_setup_pctx(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct drm_i915_gem_object *pctx;
+	unsigned long pctx_paddr;
+	u32 pcbr;
+	int pctx_size = 24*1024;
+
+	mutex_lock(&dev->struct_mutex);
+
+	pcbr = I915_READ(VLV_PCBR);
+	if (pcbr) {
+		/* BIOS set it up already, grab the pre-alloc'd space */
+		int pcbr_offset;
+
+		pcbr_offset = (pcbr & (~4095)) - dev_priv->mm.stolen_base;
+		pctx = i915_gem_object_create_stolen_for_preallocated(dev_priv->dev,
+								      pcbr_offset,
+								      I915_GTT_OFFSET_NONE,
+								      pctx_size);
+		goto out;
+	}
+
+	DRM_DEBUG_DRIVER("BIOS didn't set up PCBR, fixing up\n");
+
+	/*
+	 * From the Gunit register HAS:
+	 * The Gfx driver is expected to program this register and ensure
+	 * proper allocation within Gfx stolen memory.  For example, this
+	 * register should be programmed such than the PCBR range does not
+	 * overlap with other ranges, such as the frame buffer, protected
+	 * memory, or any other relevant ranges.
+	 */
+	pctx = i915_gem_object_create_stolen(dev, pctx_size);
+	if (!pctx) {
+		DRM_DEBUG("not enough stolen space for PCTX, disabling\n");
+		goto out;
+	}
+
+	pctx_paddr = dev_priv->mm.stolen_base + pctx->stolen->start;
+	I915_WRITE(VLV_PCBR, pctx_paddr);
+
+out:
+	DRM_DEBUG_DRIVER("PCBR: 0x%08x\n", I915_READ(VLV_PCBR));
+	dev_priv->vlv_pctx = pctx;
+	mutex_unlock(&dev->struct_mutex);
+}
+
+static void valleyview_cleanup_pctx(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	if (WARN_ON(!dev_priv->vlv_pctx))
+		return;
+
+	drm_gem_object_unreference_unlocked(&dev_priv->vlv_pctx->base);
+	dev_priv->vlv_pctx = NULL;
+}
+
+static void vlv_init_gpll_ref_freq(struct drm_i915_private *dev_priv)
+{
+	dev_priv->rps.gpll_ref_freq =
+		vlv_get_cck_clock(dev_priv, "GPLL ref",
+				  CCK_GPLL_CLOCK_CONTROL,
+				  dev_priv->czclk_freq);
+
+	DRM_DEBUG_DRIVER("GPLL reference freq: %d kHz\n",
+			 dev_priv->rps.gpll_ref_freq);
+}
+
+static void valleyview_init_gt_powersave(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	u32 val;
+
+	valleyview_setup_pctx(dev);
+
+	vlv_init_gpll_ref_freq(dev_priv);
+
+	mutex_lock(&dev_priv->rps.hw_lock);
+
+	val = vlv_punit_read(dev_priv, PUNIT_REG_GPU_FREQ_STS);
+	switch ((val >> 6) & 3) {
+	case 0:
+	case 1:
+		dev_priv->mem_freq = 800;
+		break;
+	case 2:
+		dev_priv->mem_freq = 1066;
+		break;
+	case 3:
+		dev_priv->mem_freq = 1333;
+		break;
+	}
+	DRM_DEBUG_DRIVER("DDR speed: %d MHz\n", dev_priv->mem_freq);
+
+	dev_priv->rps.max_freq = valleyview_rps_max_freq(dev_priv);
+	dev_priv->rps.rp0_freq = dev_priv->rps.max_freq;
+	DRM_DEBUG_DRIVER("max GPU freq: %d MHz (%u)\n",
+			 intel_gpu_freq(dev_priv, dev_priv->rps.max_freq),
+			 dev_priv->rps.max_freq);
+
+	dev_priv->rps.efficient_freq = valleyview_rps_rpe_freq(dev_priv);
+	DRM_DEBUG_DRIVER("RPe GPU freq: %d MHz (%u)\n",
+			 intel_gpu_freq(dev_priv, dev_priv->rps.efficient_freq),
+			 dev_priv->rps.efficient_freq);
+
+	dev_priv->rps.rp1_freq = valleyview_rps_guar_freq(dev_priv);
+	DRM_DEBUG_DRIVER("RP1(Guar Freq) GPU freq: %d MHz (%u)\n",
+			 intel_gpu_freq(dev_priv, dev_priv->rps.rp1_freq),
+			 dev_priv->rps.rp1_freq);
+
+	dev_priv->rps.min_freq = valleyview_rps_min_freq(dev_priv);
+	DRM_DEBUG_DRIVER("min GPU freq: %d MHz (%u)\n",
+			 intel_gpu_freq(dev_priv, dev_priv->rps.min_freq),
+			 dev_priv->rps.min_freq);
+
+	dev_priv->rps.idle_freq = dev_priv->rps.min_freq;
+
+	/* Preserve min/max settings in case of re-init */
+	if (dev_priv->rps.max_freq_softlimit == 0)
+		dev_priv->rps.max_freq_softlimit = dev_priv->rps.max_freq;
+
+	if (dev_priv->rps.min_freq_softlimit == 0)
+		dev_priv->rps.min_freq_softlimit = dev_priv->rps.min_freq;
+
+	mutex_unlock(&dev_priv->rps.hw_lock);
+}
+
+static void cherryview_init_gt_powersave(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	u32 val;
+
+	cherryview_setup_pctx(dev);
+
+	vlv_init_gpll_ref_freq(dev_priv);
+
+	mutex_lock(&dev_priv->rps.hw_lock);
+
+	mutex_lock(&dev_priv->sb_lock);
+	val = vlv_cck_read(dev_priv, CCK_FUSE_REG);
+	mutex_unlock(&dev_priv->sb_lock);
+
+	switch ((val >> 2) & 0x7) {
+	case 3:
+		dev_priv->mem_freq = 2000;
+		break;
+	default:
+		dev_priv->mem_freq = 1600;
+		break;
+	}
+	DRM_DEBUG_DRIVER("DDR speed: %d MHz\n", dev_priv->mem_freq);
+
+	dev_priv->rps.max_freq = cherryview_rps_max_freq(dev_priv);
+	dev_priv->rps.rp0_freq = dev_priv->rps.max_freq;
+	DRM_DEBUG_DRIVER("max GPU freq: %d MHz (%u)\n",
+			 intel_gpu_freq(dev_priv, dev_priv->rps.max_freq),
+			 dev_priv->rps.max_freq);
+
+	dev_priv->rps.efficient_freq = cherryview_rps_rpe_freq(dev_priv);
+	DRM_DEBUG_DRIVER("RPe GPU freq: %d MHz (%u)\n",
+			 intel_gpu_freq(dev_priv, dev_priv->rps.efficient_freq),
+			 dev_priv->rps.efficient_freq);
+
+	dev_priv->rps.rp1_freq = cherryview_rps_guar_freq(dev_priv);
+	DRM_DEBUG_DRIVER("RP1(Guar) GPU freq: %d MHz (%u)\n",
+			 intel_gpu_freq(dev_priv, dev_priv->rps.rp1_freq),
+			 dev_priv->rps.rp1_freq);
+
+	/* PUnit validated range is only [RPe, RP0] */
+	dev_priv->rps.min_freq = dev_priv->rps.efficient_freq;
+	DRM_DEBUG_DRIVER("min GPU freq: %d MHz (%u)\n",
+			 intel_gpu_freq(dev_priv, dev_priv->rps.min_freq),
+			 dev_priv->rps.min_freq);
+
+	WARN_ONCE((dev_priv->rps.max_freq |
+		   dev_priv->rps.efficient_freq |
+		   dev_priv->rps.rp1_freq |
+		   dev_priv->rps.min_freq) & 1,
+		  "Odd GPU freq values\n");
+
+	dev_priv->rps.idle_freq = dev_priv->rps.min_freq;
+
+	/* Preserve min/max settings in case of re-init */
+	if (dev_priv->rps.max_freq_softlimit == 0)
+		dev_priv->rps.max_freq_softlimit = dev_priv->rps.max_freq;
+
+	if (dev_priv->rps.min_freq_softlimit == 0)
+		dev_priv->rps.min_freq_softlimit = dev_priv->rps.min_freq;
+
+	mutex_unlock(&dev_priv->rps.hw_lock);
+}
+
+static void valleyview_cleanup_gt_powersave(struct drm_device *dev)
+{
+	valleyview_cleanup_pctx(dev);
+}
+
+static void cherryview_enable_rps(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_engine_cs *engine;
+	u32 gtfifodbg, val, rc6_mode = 0, pcbr;
+
+	WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock));
+
+	gtfifodbg = I915_READ(GTFIFODBG) & ~(GT_FIFO_SBDEDICATE_FREE_ENTRY_CHV |
+					     GT_FIFO_FREE_ENTRIES_CHV);
+	if (gtfifodbg) {
+		DRM_DEBUG_DRIVER("GT fifo had a previous error %x\n",
+				 gtfifodbg);
+		I915_WRITE(GTFIFODBG, gtfifodbg);
+	}
+
+	cherryview_check_pctx(dev_priv);
+
+	/* 1a & 1b: Get forcewake during program sequence. Although the driver
+	 * hasn't enabled a state yet where we need forcewake, BIOS may have.*/
+	intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL);
+
+	/*  Disable RC states. */
+	I915_WRITE(GEN6_RC_CONTROL, 0);
+
+	/* 2a: Program RC6 thresholds.*/
+	I915_WRITE(GEN6_RC6_WAKE_RATE_LIMIT, 40 << 16);
+	I915_WRITE(GEN6_RC_EVALUATION_INTERVAL, 125000); /* 12500 * 1280ns */
+	I915_WRITE(GEN6_RC_IDLE_HYSTERSIS, 25); /* 25 * 1280ns */
+
+	for_each_engine(engine, dev_priv)
+		I915_WRITE(RING_MAX_IDLE(engine->mmio_base), 10);
+	I915_WRITE(GEN6_RC_SLEEP, 0);
+
+	/* TO threshold set to 500 us ( 0x186 * 1.28 us) */
+	I915_WRITE(GEN6_RC6_THRESHOLD, 0x186);
+
+	/* allows RC6 residency counter to work */
+	I915_WRITE(VLV_COUNTER_CONTROL,
+		   _MASKED_BIT_ENABLE(VLV_COUNT_RANGE_HIGH |
+				      VLV_MEDIA_RC6_COUNT_EN |
+				      VLV_RENDER_RC6_COUNT_EN));
+
+	/* For now we assume BIOS is allocating and populating the PCBR  */
+	pcbr = I915_READ(VLV_PCBR);
+
+	/* 3: Enable RC6 */
+	if ((intel_enable_rc6(dev) & INTEL_RC6_ENABLE) &&
+						(pcbr >> VLV_PCBR_ADDR_SHIFT))
+		rc6_mode = GEN7_RC_CTL_TO_MODE;
+
+	I915_WRITE(GEN6_RC_CONTROL, rc6_mode);
+
+	/* 4 Program defaults and thresholds for RPS*/
+	I915_WRITE(GEN6_RP_DOWN_TIMEOUT, 1000000);
+	I915_WRITE(GEN6_RP_UP_THRESHOLD, 59400);
+	I915_WRITE(GEN6_RP_DOWN_THRESHOLD, 245000);
+	I915_WRITE(GEN6_RP_UP_EI, 66000);
+	I915_WRITE(GEN6_RP_DOWN_EI, 350000);
+
+	I915_WRITE(GEN6_RP_IDLE_HYSTERSIS, 10);
+
+	/* 5: Enable RPS */
+	I915_WRITE(GEN6_RP_CONTROL,
+		   GEN6_RP_MEDIA_HW_NORMAL_MODE |
+		   GEN6_RP_MEDIA_IS_GFX |
+		   GEN6_RP_ENABLE |
+		   GEN6_RP_UP_BUSY_AVG |
+		   GEN6_RP_DOWN_IDLE_AVG);
+
+	/* Setting Fixed Bias */
+	val = VLV_OVERRIDE_EN |
+		  VLV_SOC_TDP_EN |
+		  CHV_BIAS_CPU_50_SOC_50;
+	vlv_punit_write(dev_priv, VLV_TURBO_SOC_OVERRIDE, val);
+
+	val = vlv_punit_read(dev_priv, PUNIT_REG_GPU_FREQ_STS);
+
+	/* RPS code assumes GPLL is used */
+	WARN_ONCE((val & GPLLENABLE) == 0, "GPLL not enabled\n");
+
+	DRM_DEBUG_DRIVER("GPLL enabled? %s\n", yesno(val & GPLLENABLE));
+	DRM_DEBUG_DRIVER("GPU status: 0x%08x\n", val);
+
+	dev_priv->rps.cur_freq = (val >> 8) & 0xff;
+	DRM_DEBUG_DRIVER("current GPU freq: %d MHz (%u)\n",
+			 intel_gpu_freq(dev_priv, dev_priv->rps.cur_freq),
+			 dev_priv->rps.cur_freq);
+
+	DRM_DEBUG_DRIVER("setting GPU freq to %d MHz (%u)\n",
+			 intel_gpu_freq(dev_priv, dev_priv->rps.idle_freq),
+			 dev_priv->rps.idle_freq);
+
+	valleyview_set_rps(dev_priv->dev, dev_priv->rps.idle_freq);
+
+	intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
+}
+
+static void valleyview_enable_rps(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_engine_cs *engine;
+	u32 gtfifodbg, val, rc6_mode = 0;
+
+	WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock));
+
+	valleyview_check_pctx(dev_priv);
+
+	gtfifodbg = I915_READ(GTFIFODBG);
+	if (gtfifodbg) {
+		DRM_DEBUG_DRIVER("GT fifo had a previous error %x\n",
+				 gtfifodbg);
+		I915_WRITE(GTFIFODBG, gtfifodbg);
+	}
+
+	/* If VLV, Forcewake all wells, else re-direct to regular path */
+	intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL);
+
+	/*  Disable RC states. */
+	I915_WRITE(GEN6_RC_CONTROL, 0);
+
+	I915_WRITE(GEN6_RP_DOWN_TIMEOUT, 1000000);
+	I915_WRITE(GEN6_RP_UP_THRESHOLD, 59400);
+	I915_WRITE(GEN6_RP_DOWN_THRESHOLD, 245000);
+	I915_WRITE(GEN6_RP_UP_EI, 66000);
+	I915_WRITE(GEN6_RP_DOWN_EI, 350000);
+
+	I915_WRITE(GEN6_RP_IDLE_HYSTERSIS, 10);
+
+	I915_WRITE(GEN6_RP_CONTROL,
+		   GEN6_RP_MEDIA_TURBO |
+		   GEN6_RP_MEDIA_HW_NORMAL_MODE |
+		   GEN6_RP_MEDIA_IS_GFX |
+		   GEN6_RP_ENABLE |
+		   GEN6_RP_UP_BUSY_AVG |
+		   GEN6_RP_DOWN_IDLE_CONT);
+
+	I915_WRITE(GEN6_RC6_WAKE_RATE_LIMIT, 0x00280000);
+	I915_WRITE(GEN6_RC_EVALUATION_INTERVAL, 125000);
+	I915_WRITE(GEN6_RC_IDLE_HYSTERSIS, 25);
+
+	for_each_engine(engine, dev_priv)
+		I915_WRITE(RING_MAX_IDLE(engine->mmio_base), 10);
+
+	I915_WRITE(GEN6_RC6_THRESHOLD, 0x557);
+
+	/* allows RC6 residency counter to work */
+	I915_WRITE(VLV_COUNTER_CONTROL,
+		   _MASKED_BIT_ENABLE(VLV_MEDIA_RC0_COUNT_EN |
+				      VLV_RENDER_RC0_COUNT_EN |
+				      VLV_MEDIA_RC6_COUNT_EN |
+				      VLV_RENDER_RC6_COUNT_EN));
+
+	if (intel_enable_rc6(dev) & INTEL_RC6_ENABLE)
+		rc6_mode = GEN7_RC_CTL_TO_MODE | VLV_RC_CTL_CTX_RST_PARALLEL;
+
+	intel_print_rc6_info(dev, rc6_mode);
+
+	I915_WRITE(GEN6_RC_CONTROL, rc6_mode);
+
+	/* Setting Fixed Bias */
+	val = VLV_OVERRIDE_EN |
+		  VLV_SOC_TDP_EN |
+		  VLV_BIAS_CPU_125_SOC_875;
+	vlv_punit_write(dev_priv, VLV_TURBO_SOC_OVERRIDE, val);
+
+	val = vlv_punit_read(dev_priv, PUNIT_REG_GPU_FREQ_STS);
+
+	/* RPS code assumes GPLL is used */
+	WARN_ONCE((val & GPLLENABLE) == 0, "GPLL not enabled\n");
+
+	DRM_DEBUG_DRIVER("GPLL enabled? %s\n", yesno(val & GPLLENABLE));
+	DRM_DEBUG_DRIVER("GPU status: 0x%08x\n", val);
+
+	dev_priv->rps.cur_freq = (val >> 8) & 0xff;
+	DRM_DEBUG_DRIVER("current GPU freq: %d MHz (%u)\n",
+			 intel_gpu_freq(dev_priv, dev_priv->rps.cur_freq),
+			 dev_priv->rps.cur_freq);
+
+	DRM_DEBUG_DRIVER("setting GPU freq to %d MHz (%u)\n",
+			 intel_gpu_freq(dev_priv, dev_priv->rps.idle_freq),
+			 dev_priv->rps.idle_freq);
+
+	valleyview_set_rps(dev_priv->dev, dev_priv->rps.idle_freq);
+
+	intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
+}
+
+static unsigned long intel_pxfreq(u32 vidfreq)
+{
+	unsigned long freq;
+	int div = (vidfreq & 0x3f0000) >> 16;
+	int post = (vidfreq & 0x3000) >> 12;
+	int pre = (vidfreq & 0x7);
+
+	if (!pre)
+		return 0;
+
+	freq = ((div * 133333) / ((1<<post) * pre));
+
+	return freq;
+}
+
+static const struct cparams {
+	u16 i;
+	u16 t;
+	u16 m;
+	u16 c;
+} cparams[] = {
+	{ 1, 1333, 301, 28664 },
+	{ 1, 1066, 294, 24460 },
+	{ 1, 800, 294, 25192 },
+	{ 0, 1333, 276, 27605 },
+	{ 0, 1066, 276, 27605 },
+	{ 0, 800, 231, 23784 },
+};
+
+static unsigned long __i915_chipset_val(struct drm_i915_private *dev_priv)
+{
+	u64 total_count, diff, ret;
+	u32 count1, count2, count3, m = 0, c = 0;
+	unsigned long now = jiffies_to_msecs(jiffies), diff1;
+	int i;
+
+	assert_spin_locked(&mchdev_lock);
+
+	diff1 = now - dev_priv->ips.last_time1;
+
+	/* Prevent division-by-zero if we are asking too fast.
+	 * Also, we don't get interesting results if we are polling
+	 * faster than once in 10ms, so just return the saved value
+	 * in such cases.
+	 */
+	if (diff1 <= 10)
+		return dev_priv->ips.chipset_power;
+
+	count1 = I915_READ(DMIEC);
+	count2 = I915_READ(DDREC);
+	count3 = I915_READ(CSIEC);
+
+	total_count = count1 + count2 + count3;
+
+	/* FIXME: handle per-counter overflow */
+	if (total_count < dev_priv->ips.last_count1) {
+		diff = ~0UL - dev_priv->ips.last_count1;
+		diff += total_count;
+	} else {
+		diff = total_count - dev_priv->ips.last_count1;
+	}
+
+	for (i = 0; i < ARRAY_SIZE(cparams); i++) {
+		if (cparams[i].i == dev_priv->ips.c_m &&
+		    cparams[i].t == dev_priv->ips.r_t) {
+			m = cparams[i].m;
+			c = cparams[i].c;
+			break;
+		}
+	}
+
+	diff = div_u64(diff, diff1);
+	ret = ((m * diff) + c);
+	ret = div_u64(ret, 10);
+
+	dev_priv->ips.last_count1 = total_count;
+	dev_priv->ips.last_time1 = now;
+
+	dev_priv->ips.chipset_power = ret;
+
+	return ret;
+}
+
+unsigned long i915_chipset_val(struct drm_i915_private *dev_priv)
+{
+	struct drm_device *dev = dev_priv->dev;
+	unsigned long val;
+
+	if (INTEL_INFO(dev)->gen != 5)
+		return 0;
+
+	spin_lock_irq(&mchdev_lock);
+
+	val = __i915_chipset_val(dev_priv);
+
+	spin_unlock_irq(&mchdev_lock);
+
+	return val;
+}
+
+unsigned long i915_mch_val(struct drm_i915_private *dev_priv)
+{
+	unsigned long m, x, b;
+	u32 tsfs;
+
+	tsfs = I915_READ(TSFS);
+
+	m = ((tsfs & TSFS_SLOPE_MASK) >> TSFS_SLOPE_SHIFT);
+	x = I915_READ8(TR1);
+
+	b = tsfs & TSFS_INTR_MASK;
+
+	return ((m * x) / 127) - b;
+}
+
+static int _pxvid_to_vd(u8 pxvid)
+{
+	if (pxvid == 0)
+		return 0;
+
+	if (pxvid >= 8 && pxvid < 31)
+		pxvid = 31;
+
+	return (pxvid + 2) * 125;
+}
+
+static u32 pvid_to_extvid(struct drm_i915_private *dev_priv, u8 pxvid)
+{
+	struct drm_device *dev = dev_priv->dev;
+	const int vd = _pxvid_to_vd(pxvid);
+	const int vm = vd - 1125;
+
+	if (INTEL_INFO(dev)->is_mobile)
+		return vm > 0 ? vm : 0;
+
+	return vd;
+}
+
+static void __i915_update_gfx_val(struct drm_i915_private *dev_priv)
+{
+	u64 now, diff, diffms;
+	u32 count;
+
+	assert_spin_locked(&mchdev_lock);
+
+	now = ktime_get_raw_ns();
+	diffms = now - dev_priv->ips.last_time2;
+	do_div(diffms, NSEC_PER_MSEC);
+
+	/* Don't divide by 0 */
+	if (!diffms)
+		return;
+
+	count = I915_READ(GFXEC);
+
+	if (count < dev_priv->ips.last_count2) {
+		diff = ~0UL - dev_priv->ips.last_count2;
+		diff += count;
+	} else {
+		diff = count - dev_priv->ips.last_count2;
+	}
+
+	dev_priv->ips.last_count2 = count;
+	dev_priv->ips.last_time2 = now;
+
+	/* More magic constants... */
+	diff = diff * 1181;
+	diff = div_u64(diff, diffms * 10);
+	dev_priv->ips.gfx_power = diff;
+}
+
+void i915_update_gfx_val(struct drm_i915_private *dev_priv)
+{
+	struct drm_device *dev = dev_priv->dev;
+
+	if (INTEL_INFO(dev)->gen != 5)
+		return;
+
+	spin_lock_irq(&mchdev_lock);
+
+	__i915_update_gfx_val(dev_priv);
+
+	spin_unlock_irq(&mchdev_lock);
+}
+
+static unsigned long __i915_gfx_val(struct drm_i915_private *dev_priv)
+{
+	unsigned long t, corr, state1, corr2, state2;
+	u32 pxvid, ext_v;
+
+	assert_spin_locked(&mchdev_lock);
+
+	pxvid = I915_READ(PXVFREQ(dev_priv->rps.cur_freq));
+	pxvid = (pxvid >> 24) & 0x7f;
+	ext_v = pvid_to_extvid(dev_priv, pxvid);
+
+	state1 = ext_v;
+
+	t = i915_mch_val(dev_priv);
+
+	/* Revel in the empirically derived constants */
+
+	/* Correction factor in 1/100000 units */
+	if (t > 80)
+		corr = ((t * 2349) + 135940);
+	else if (t >= 50)
+		corr = ((t * 964) + 29317);
+	else /* < 50 */
+		corr = ((t * 301) + 1004);
+
+	corr = corr * ((150142 * state1) / 10000 - 78642);
+	corr /= 100000;
+	corr2 = (corr * dev_priv->ips.corr);
+
+	state2 = (corr2 * state1) / 10000;
+	state2 /= 100; /* convert to mW */
+
+	__i915_update_gfx_val(dev_priv);
+
+	return dev_priv->ips.gfx_power + state2;
+}
+
+unsigned long i915_gfx_val(struct drm_i915_private *dev_priv)
+{
+	struct drm_device *dev = dev_priv->dev;
+	unsigned long val;
+
+	if (INTEL_INFO(dev)->gen != 5)
+		return 0;
+
+	spin_lock_irq(&mchdev_lock);
+
+	val = __i915_gfx_val(dev_priv);
+
+	spin_unlock_irq(&mchdev_lock);
+
+	return val;
+}
+
+/**
+ * i915_bpo_read_mch_val - return value for IPS use
+ *
+ * Calculate and return a value for the IPS driver to use when deciding whether
+ * we have thermal and power headroom to increase CPU or GPU power budget.
+ */
+unsigned long i915_bpo_read_mch_val(void)
+{
+	struct drm_i915_private *dev_priv;
+	unsigned long chipset_val, graphics_val, ret = 0;
+
+	spin_lock_irq(&mchdev_lock);
+	if (!i915_mch_dev)
+		goto out_unlock;
+	dev_priv = i915_mch_dev;
+
+	chipset_val = __i915_chipset_val(dev_priv);
+	graphics_val = __i915_gfx_val(dev_priv);
+
+	ret = chipset_val + graphics_val;
+
+out_unlock:
+	spin_unlock_irq(&mchdev_lock);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(i915_bpo_read_mch_val);
+
+/**
+ * i915_bpo_gpu_raise - raise GPU frequency limit
+ *
+ * Raise the limit; IPS indicates we have thermal headroom.
+ */
+bool i915_bpo_gpu_raise(void)
+{
+	struct drm_i915_private *dev_priv;
+	bool ret = true;
+
+	spin_lock_irq(&mchdev_lock);
+	if (!i915_mch_dev) {
+		ret = false;
+		goto out_unlock;
+	}
+	dev_priv = i915_mch_dev;
+
+	if (dev_priv->ips.max_delay > dev_priv->ips.fmax)
+		dev_priv->ips.max_delay--;
+
+out_unlock:
+	spin_unlock_irq(&mchdev_lock);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(i915_bpo_gpu_raise);
+
+/**
+ * i915_bpo_gpu_lower - lower GPU frequency limit
+ *
+ * IPS indicates we're close to a thermal limit, so throttle back the GPU
+ * frequency maximum.
+ */
+bool i915_bpo_gpu_lower(void)
+{
+	struct drm_i915_private *dev_priv;
+	bool ret = true;
+
+	spin_lock_irq(&mchdev_lock);
+	if (!i915_mch_dev) {
+		ret = false;
+		goto out_unlock;
+	}
+	dev_priv = i915_mch_dev;
+
+	if (dev_priv->ips.max_delay < dev_priv->ips.min_delay)
+		dev_priv->ips.max_delay++;
+
+out_unlock:
+	spin_unlock_irq(&mchdev_lock);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(i915_bpo_gpu_lower);
+
+/**
+ * i915_bpo_gpu_busy - indicate GPU business to IPS
+ *
+ * Tell the IPS driver whether or not the GPU is busy.
+ */
+bool i915_bpo_gpu_busy(void)
+{
+	struct drm_i915_private *dev_priv;
+	struct intel_engine_cs *engine;
+	bool ret = false;
+
+	spin_lock_irq(&mchdev_lock);
+	if (!i915_mch_dev)
+		goto out_unlock;
+	dev_priv = i915_mch_dev;
+
+	for_each_engine(engine, dev_priv)
+		ret |= !list_empty(&engine->request_list);
+
+out_unlock:
+	spin_unlock_irq(&mchdev_lock);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(i915_bpo_gpu_busy);
+
+/**
+ * i915_bpo_gpu_turbo_disable - disable graphics turbo
+ *
+ * Disable graphics turbo by resetting the max frequency and setting the
+ * current frequency to the default.
+ */
+bool i915_bpo_gpu_turbo_disable(void)
+{
+	struct drm_i915_private *dev_priv;
+	bool ret = true;
+
+	spin_lock_irq(&mchdev_lock);
+	if (!i915_mch_dev) {
+		ret = false;
+		goto out_unlock;
+	}
+	dev_priv = i915_mch_dev;
+
+	dev_priv->ips.max_delay = dev_priv->ips.fstart;
+
+	if (!ironlake_set_drps(dev_priv->dev, dev_priv->ips.fstart))
+		ret = false;
+
+out_unlock:
+	spin_unlock_irq(&mchdev_lock);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(i915_bpo_gpu_turbo_disable);
+
+/**
+ * Tells the intel_ips driver that the i915 driver is now loaded, if
+ * IPS got loaded first.
+ *
+ * This awkward dance is so that neither module has to depend on the
+ * other in order for IPS to do the appropriate communication of
+ * GPU turbo limits to i915.
+ */
+static void
+ips_ping_for_i915_load(void)
+{
+	void (*link)(void);
+
+	link = symbol_get(ips_link_to_i915_driver);
+	if (link) {
+		link();
+		symbol_put(ips_link_to_i915_driver);
+	}
+}
+
+void intel_gpu_ips_init(struct drm_i915_private *dev_priv)
+{
+	/* We only register the i915 ips part with intel-ips once everything is
+	 * set up, to avoid intel-ips sneaking in and reading bogus values. */
+	spin_lock_irq(&mchdev_lock);
+	i915_mch_dev = dev_priv;
+	spin_unlock_irq(&mchdev_lock);
+
+	ips_ping_for_i915_load();
+}
+
+void intel_gpu_ips_teardown(void)
+{
+	spin_lock_irq(&mchdev_lock);
+	i915_mch_dev = NULL;
+	spin_unlock_irq(&mchdev_lock);
+}
+
+static void intel_init_emon(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	u32 lcfuse;
+	u8 pxw[16];
+	int i;
+
+	/* Disable to program */
+	I915_WRITE(ECR, 0);
+	POSTING_READ(ECR);
+
+	/* Program energy weights for various events */
+	I915_WRITE(SDEW, 0x15040d00);
+	I915_WRITE(CSIEW0, 0x007f0000);
+	I915_WRITE(CSIEW1, 0x1e220004);
+	I915_WRITE(CSIEW2, 0x04000004);
+
+	for (i = 0; i < 5; i++)
+		I915_WRITE(PEW(i), 0);
+	for (i = 0; i < 3; i++)
+		I915_WRITE(DEW(i), 0);
+
+	/* Program P-state weights to account for frequency power adjustment */
+	for (i = 0; i < 16; i++) {
+		u32 pxvidfreq = I915_READ(PXVFREQ(i));
+		unsigned long freq = intel_pxfreq(pxvidfreq);
+		unsigned long vid = (pxvidfreq & PXVFREQ_PX_MASK) >>
+			PXVFREQ_PX_SHIFT;
+		unsigned long val;
+
+		val = vid * vid;
+		val *= (freq / 1000);
+		val *= 255;
+		val /= (127*127*900);
+		if (val > 0xff)
+			DRM_ERROR("bad pxval: %ld\n", val);
+		pxw[i] = val;
+	}
+	/* Render standby states get 0 weight */
+	pxw[14] = 0;
+	pxw[15] = 0;
+
+	for (i = 0; i < 4; i++) {
+		u32 val = (pxw[i*4] << 24) | (pxw[(i*4)+1] << 16) |
+			(pxw[(i*4)+2] << 8) | (pxw[(i*4)+3]);
+		I915_WRITE(PXW(i), val);
+	}
+
+	/* Adjust magic regs to magic values (more experimental results) */
+	I915_WRITE(OGW0, 0);
+	I915_WRITE(OGW1, 0);
+	I915_WRITE(EG0, 0x00007f00);
+	I915_WRITE(EG1, 0x0000000e);
+	I915_WRITE(EG2, 0x000e0000);
+	I915_WRITE(EG3, 0x68000300);
+	I915_WRITE(EG4, 0x42000000);
+	I915_WRITE(EG5, 0x00140031);
+	I915_WRITE(EG6, 0);
+	I915_WRITE(EG7, 0);
+
+	for (i = 0; i < 8; i++)
+		I915_WRITE(PXWL(i), 0);
+
+	/* Enable PMON + select events */
+	I915_WRITE(ECR, 0x80000019);
+
+	lcfuse = I915_READ(LCFUSE02);
+
+	dev_priv->ips.corr = (lcfuse & LCFUSE_HIV_MASK);
+}
+
+void intel_init_gt_powersave(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	/*
+	 * RPM depends on RC6 to save restore the GT HW context, so make RC6 a
+	 * requirement.
+	 */
+	if (!i915.enable_rc6) {
+		DRM_INFO("RC6 disabled, disabling runtime PM support\n");
+		intel_runtime_pm_get(dev_priv);
+	}
+
+	if (IS_CHERRYVIEW(dev))
+		cherryview_init_gt_powersave(dev);
+	else if (IS_VALLEYVIEW(dev))
+		valleyview_init_gt_powersave(dev);
+}
+
+void intel_cleanup_gt_powersave(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	if (IS_CHERRYVIEW(dev))
+		return;
+	else if (IS_VALLEYVIEW(dev))
+		valleyview_cleanup_gt_powersave(dev);
+
+	if (!i915.enable_rc6)
+		intel_runtime_pm_put(dev_priv);
+}
+
+static void gen6_suspend_rps(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	flush_delayed_work(&dev_priv->rps.delayed_resume_work);
+
+	gen6_disable_rps_interrupts(dev);
+}
+
+/**
+ * intel_suspend_gt_powersave - suspend PM work and helper threads
+ * @dev: drm device
+ *
+ * We don't want to disable RC6 or other features here, we just want
+ * to make sure any work we've queued has finished and won't bother
+ * us while we're suspended.
+ */
+void intel_suspend_gt_powersave(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	if (INTEL_INFO(dev)->gen < 6)
+		return;
+
+	gen6_suspend_rps(dev);
+
+	/* Force GPU to min freq during suspend */
+	gen6_rps_idle(dev_priv);
+}
+
+void intel_disable_gt_powersave(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	if (IS_IRONLAKE_M(dev)) {
+		ironlake_disable_drps(dev);
+	} else if (INTEL_INFO(dev)->gen >= 6) {
+		intel_suspend_gt_powersave(dev);
+
+		mutex_lock(&dev_priv->rps.hw_lock);
+		if (INTEL_INFO(dev)->gen >= 9) {
+			gen9_disable_rc6(dev);
+			gen9_disable_rps(dev);
+		} else if (IS_CHERRYVIEW(dev))
+			cherryview_disable_rps(dev);
+		else if (IS_VALLEYVIEW(dev))
+			valleyview_disable_rps(dev);
+		else
+			gen6_disable_rps(dev);
+
+		dev_priv->rps.enabled = false;
+		mutex_unlock(&dev_priv->rps.hw_lock);
+	}
+}
+
+static void intel_gen6_powersave_work(struct work_struct *work)
+{
+	struct drm_i915_private *dev_priv =
+		container_of(work, struct drm_i915_private,
+			     rps.delayed_resume_work.work);
+	struct drm_device *dev = dev_priv->dev;
+
+	mutex_lock(&dev_priv->rps.hw_lock);
+
+	gen6_reset_rps_interrupts(dev);
+
+	if (IS_CHERRYVIEW(dev)) {
+		cherryview_enable_rps(dev);
+	} else if (IS_VALLEYVIEW(dev)) {
+		valleyview_enable_rps(dev);
+	} else if (INTEL_INFO(dev)->gen >= 9) {
+		gen9_enable_rc6(dev);
+		gen9_enable_rps(dev);
+		if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev))
+			__gen6_update_ring_freq(dev);
+	} else if (IS_BROADWELL(dev)) {
+		gen8_enable_rps(dev);
+		__gen6_update_ring_freq(dev);
+	} else {
+		gen6_enable_rps(dev);
+		__gen6_update_ring_freq(dev);
+	}
+
+	WARN_ON(dev_priv->rps.max_freq < dev_priv->rps.min_freq);
+	WARN_ON(dev_priv->rps.idle_freq > dev_priv->rps.max_freq);
+
+	WARN_ON(dev_priv->rps.efficient_freq < dev_priv->rps.min_freq);
+	WARN_ON(dev_priv->rps.efficient_freq > dev_priv->rps.max_freq);
+
+	dev_priv->rps.enabled = true;
+
+	gen6_enable_rps_interrupts(dev);
+
+	mutex_unlock(&dev_priv->rps.hw_lock);
+
+	intel_runtime_pm_put(dev_priv);
+}
+
+void intel_enable_gt_powersave(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	/* Powersaving is controlled by the host when inside a VM */
+	if (intel_vgpu_active(dev))
+		return;
+
+	if (IS_IRONLAKE_M(dev)) {
+		ironlake_enable_drps(dev);
+		mutex_lock(&dev->struct_mutex);
+		intel_init_emon(dev);
+		mutex_unlock(&dev->struct_mutex);
+	} else if (INTEL_INFO(dev)->gen >= 6) {
+		/*
+		 * PCU communication is slow and this doesn't need to be
+		 * done at any specific time, so do this out of our fast path
+		 * to make resume and init faster.
+		 *
+		 * We depend on the HW RC6 power context save/restore
+		 * mechanism when entering D3 through runtime PM suspend. So
+		 * disable RPM until RPS/RC6 is properly setup. We can only
+		 * get here via the driver load/system resume/runtime resume
+		 * paths, so the _noresume version is enough (and in case of
+		 * runtime resume it's necessary).
+		 */
+		if (schedule_delayed_work(&dev_priv->rps.delayed_resume_work,
+					   round_jiffies_up_relative(HZ)))
+			intel_runtime_pm_get_noresume(dev_priv);
+	}
+}
+
+void intel_reset_gt_powersave(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	if (INTEL_INFO(dev)->gen < 6)
+		return;
+
+	gen6_suspend_rps(dev);
+	dev_priv->rps.enabled = false;
+}
+
+static void ibx_init_clock_gating(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	/*
+	 * On Ibex Peak and Cougar Point, we need to disable clock
+	 * gating for the panel power sequencer or it will fail to
+	 * start up when no ports are active.
+	 */
+	I915_WRITE(SOUTH_DSPCLK_GATE_D, PCH_DPLSUNIT_CLOCK_GATE_DISABLE);
+}
+
+static void g4x_disable_trickle_feed(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	enum pipe pipe;
+
+	for_each_pipe(dev_priv, pipe) {
+		I915_WRITE(DSPCNTR(pipe),
+			   I915_READ(DSPCNTR(pipe)) |
+			   DISPPLANE_TRICKLE_FEED_DISABLE);
+
+		I915_WRITE(DSPSURF(pipe), I915_READ(DSPSURF(pipe)));
+		POSTING_READ(DSPSURF(pipe));
+	}
+}
+
+static void ilk_init_lp_watermarks(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	I915_WRITE(WM3_LP_ILK, I915_READ(WM3_LP_ILK) & ~WM1_LP_SR_EN);
+	I915_WRITE(WM2_LP_ILK, I915_READ(WM2_LP_ILK) & ~WM1_LP_SR_EN);
+	I915_WRITE(WM1_LP_ILK, I915_READ(WM1_LP_ILK) & ~WM1_LP_SR_EN);
+
+	/*
+	 * Don't touch WM1S_LP_EN here.
+	 * Doing so could cause underruns.
+	 */
+}
+
+static void ironlake_init_clock_gating(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	uint32_t dspclk_gate = ILK_VRHUNIT_CLOCK_GATE_DISABLE;
+
+	/*
+	 * Required for FBC
+	 * WaFbcDisableDpfcClockGating:ilk
+	 */
+	dspclk_gate |= ILK_DPFCRUNIT_CLOCK_GATE_DISABLE |
+		   ILK_DPFCUNIT_CLOCK_GATE_DISABLE |
+		   ILK_DPFDUNIT_CLOCK_GATE_ENABLE;
+
+	I915_WRITE(PCH_3DCGDIS0,
+		   MARIUNIT_CLOCK_GATE_DISABLE |
+		   SVSMUNIT_CLOCK_GATE_DISABLE);
+	I915_WRITE(PCH_3DCGDIS1,
+		   VFMUNIT_CLOCK_GATE_DISABLE);
+
+	/*
+	 * According to the spec the following bits should be set in
+	 * order to enable memory self-refresh
+	 * The bit 22/21 of 0x42004
+	 * The bit 5 of 0x42020
+	 * The bit 15 of 0x45000
+	 */
+	I915_WRITE(ILK_DISPLAY_CHICKEN2,
+		   (I915_READ(ILK_DISPLAY_CHICKEN2) |
+		    ILK_DPARB_GATE | ILK_VSDPFD_FULL));
+	dspclk_gate |= ILK_DPARBUNIT_CLOCK_GATE_ENABLE;
+	I915_WRITE(DISP_ARB_CTL,
+		   (I915_READ(DISP_ARB_CTL) |
+		    DISP_FBC_WM_DIS));
+
+	ilk_init_lp_watermarks(dev);
+
+	/*
+	 * Based on the document from hardware guys the following bits
+	 * should be set unconditionally in order to enable FBC.
+	 * The bit 22 of 0x42000
+	 * The bit 22 of 0x42004
+	 * The bit 7,8,9 of 0x42020.
+	 */
+	if (IS_IRONLAKE_M(dev)) {
+		/* WaFbcAsynchFlipDisableFbcQueue:ilk */
+		I915_WRITE(ILK_DISPLAY_CHICKEN1,
+			   I915_READ(ILK_DISPLAY_CHICKEN1) |
+			   ILK_FBCQ_DIS);
+		I915_WRITE(ILK_DISPLAY_CHICKEN2,
+			   I915_READ(ILK_DISPLAY_CHICKEN2) |
+			   ILK_DPARB_GATE);
+	}
+
+	I915_WRITE(ILK_DSPCLK_GATE_D, dspclk_gate);
+
+	I915_WRITE(ILK_DISPLAY_CHICKEN2,
+		   I915_READ(ILK_DISPLAY_CHICKEN2) |
+		   ILK_ELPIN_409_SELECT);
+	I915_WRITE(_3D_CHICKEN2,
+		   _3D_CHICKEN2_WM_READ_PIPELINED << 16 |
+		   _3D_CHICKEN2_WM_READ_PIPELINED);
+
+	/* WaDisableRenderCachePipelinedFlush:ilk */
+	I915_WRITE(CACHE_MODE_0,
+		   _MASKED_BIT_ENABLE(CM0_PIPELINED_RENDER_FLUSH_DISABLE));
+
+	/* WaDisable_RenderCache_OperationalFlush:ilk */
+	I915_WRITE(CACHE_MODE_0, _MASKED_BIT_DISABLE(RC_OP_FLUSH_ENABLE));
+
+	g4x_disable_trickle_feed(dev);
+
+	ibx_init_clock_gating(dev);
+}
+
+static void cpt_init_clock_gating(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	int pipe;
+	uint32_t val;
+
+	/*
+	 * On Ibex Peak and Cougar Point, we need to disable clock
+	 * gating for the panel power sequencer or it will fail to
+	 * start up when no ports are active.
+	 */
+	I915_WRITE(SOUTH_DSPCLK_GATE_D, PCH_DPLSUNIT_CLOCK_GATE_DISABLE |
+		   PCH_DPLUNIT_CLOCK_GATE_DISABLE |
+		   PCH_CPUNIT_CLOCK_GATE_DISABLE);
+	I915_WRITE(SOUTH_CHICKEN2, I915_READ(SOUTH_CHICKEN2) |
+		   DPLS_EDP_PPS_FIX_DIS);
+	/* The below fixes the weird display corruption, a few pixels shifted
+	 * downward, on (only) LVDS of some HP laptops with IVY.
+	 */
+	for_each_pipe(dev_priv, pipe) {
+		val = I915_READ(TRANS_CHICKEN2(pipe));
+		val |= TRANS_CHICKEN2_TIMING_OVERRIDE;
+		val &= ~TRANS_CHICKEN2_FDI_POLARITY_REVERSED;
+		if (dev_priv->vbt.fdi_rx_polarity_inverted)
+			val |= TRANS_CHICKEN2_FDI_POLARITY_REVERSED;
+		val &= ~TRANS_CHICKEN2_FRAME_START_DELAY_MASK;
+		val &= ~TRANS_CHICKEN2_DISABLE_DEEP_COLOR_COUNTER;
+		val &= ~TRANS_CHICKEN2_DISABLE_DEEP_COLOR_MODESWITCH;
+		I915_WRITE(TRANS_CHICKEN2(pipe), val);
+	}
+	/* WADP0ClockGatingDisable */
+	for_each_pipe(dev_priv, pipe) {
+		I915_WRITE(TRANS_CHICKEN1(pipe),
+			   TRANS_CHICKEN1_DP0UNIT_GC_DISABLE);
+	}
+}
+
+static void gen6_check_mch_setup(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	uint32_t tmp;
+
+	tmp = I915_READ(MCH_SSKPD);
+	if ((tmp & MCH_SSKPD_WM0_MASK) != MCH_SSKPD_WM0_VAL)
+		DRM_DEBUG_KMS("Wrong MCH_SSKPD value: 0x%08x This can cause underruns.\n",
+			      tmp);
+}
+
+static void gen6_init_clock_gating(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	uint32_t dspclk_gate = ILK_VRHUNIT_CLOCK_GATE_DISABLE;
+
+	I915_WRITE(ILK_DSPCLK_GATE_D, dspclk_gate);
+
+	I915_WRITE(ILK_DISPLAY_CHICKEN2,
+		   I915_READ(ILK_DISPLAY_CHICKEN2) |
+		   ILK_ELPIN_409_SELECT);
+
+	/* WaDisableHiZPlanesWhenMSAAEnabled:snb */
+	I915_WRITE(_3D_CHICKEN,
+		   _MASKED_BIT_ENABLE(_3D_CHICKEN_HIZ_PLANE_DISABLE_MSAA_4X_SNB));
+
+	/* WaDisable_RenderCache_OperationalFlush:snb */
+	I915_WRITE(CACHE_MODE_0, _MASKED_BIT_DISABLE(RC_OP_FLUSH_ENABLE));
+
+	/*
+	 * BSpec recoomends 8x4 when MSAA is used,
+	 * however in practice 16x4 seems fastest.
+	 *
+	 * Note that PS/WM thread counts depend on the WIZ hashing
+	 * disable bit, which we don't touch here, but it's good
+	 * to keep in mind (see 3DSTATE_PS and 3DSTATE_WM).
+	 */
+	I915_WRITE(GEN6_GT_MODE,
+		   _MASKED_FIELD(GEN6_WIZ_HASHING_MASK, GEN6_WIZ_HASHING_16x4));
+
+	ilk_init_lp_watermarks(dev);
+
+	I915_WRITE(CACHE_MODE_0,
+		   _MASKED_BIT_DISABLE(CM0_STC_EVICT_DISABLE_LRA_SNB));
+
+	I915_WRITE(GEN6_UCGCTL1,
+		   I915_READ(GEN6_UCGCTL1) |
+		   GEN6_BLBUNIT_CLOCK_GATE_DISABLE |
+		   GEN6_CSUNIT_CLOCK_GATE_DISABLE);
+
+	/* According to the BSpec vol1g, bit 12 (RCPBUNIT) clock
+	 * gating disable must be set.  Failure to set it results in
+	 * flickering pixels due to Z write ordering failures after
+	 * some amount of runtime in the Mesa "fire" demo, and Unigine
+	 * Sanctuary and Tropics, and apparently anything else with
+	 * alpha test or pixel discard.
+	 *
+	 * According to the spec, bit 11 (RCCUNIT) must also be set,
+	 * but we didn't debug actual testcases to find it out.
+	 *
+	 * WaDisableRCCUnitClockGating:snb
+	 * WaDisableRCPBUnitClockGating:snb
+	 */
+	I915_WRITE(GEN6_UCGCTL2,
+		   GEN6_RCPBUNIT_CLOCK_GATE_DISABLE |
+		   GEN6_RCCUNIT_CLOCK_GATE_DISABLE);
+
+	/* WaStripsFansDisableFastClipPerformanceFix:snb */
+	I915_WRITE(_3D_CHICKEN3,
+		   _MASKED_BIT_ENABLE(_3D_CHICKEN3_SF_DISABLE_FASTCLIP_CULL));
+
+	/*
+	 * Bspec says:
+	 * "This bit must be set if 3DSTATE_CLIP clip mode is set to normal and
+	 * 3DSTATE_SF number of SF output attributes is more than 16."
+	 */
+	I915_WRITE(_3D_CHICKEN3,
+		   _MASKED_BIT_ENABLE(_3D_CHICKEN3_SF_DISABLE_PIPELINED_ATTR_FETCH));
+
+	/*
+	 * According to the spec the following bits should be
+	 * set in order to enable memory self-refresh and fbc:
+	 * The bit21 and bit22 of 0x42000
+	 * The bit21 and bit22 of 0x42004
+	 * The bit5 and bit7 of 0x42020
+	 * The bit14 of 0x70180
+	 * The bit14 of 0x71180
+	 *
+	 * WaFbcAsynchFlipDisableFbcQueue:snb
+	 */
+	I915_WRITE(ILK_DISPLAY_CHICKEN1,
+		   I915_READ(ILK_DISPLAY_CHICKEN1) |
+		   ILK_FBCQ_DIS | ILK_PABSTRETCH_DIS);
+	I915_WRITE(ILK_DISPLAY_CHICKEN2,
+		   I915_READ(ILK_DISPLAY_CHICKEN2) |
+		   ILK_DPARB_GATE | ILK_VSDPFD_FULL);
+	I915_WRITE(ILK_DSPCLK_GATE_D,
+		   I915_READ(ILK_DSPCLK_GATE_D) |
+		   ILK_DPARBUNIT_CLOCK_GATE_ENABLE  |
+		   ILK_DPFDUNIT_CLOCK_GATE_ENABLE);
+
+	g4x_disable_trickle_feed(dev);
+
+	cpt_init_clock_gating(dev);
+
+	gen6_check_mch_setup(dev);
+}
+
+static void gen7_setup_fixed_func_scheduler(struct drm_i915_private *dev_priv)
+{
+	uint32_t reg = I915_READ(GEN7_FF_THREAD_MODE);
+
+	/*
+	 * WaVSThreadDispatchOverride:ivb,vlv
+	 *
+	 * This actually overrides the dispatch
+	 * mode for all thread types.
+	 */
+	reg &= ~GEN7_FF_SCHED_MASK;
+	reg |= GEN7_FF_TS_SCHED_HW;
+	reg |= GEN7_FF_VS_SCHED_HW;
+	reg |= GEN7_FF_DS_SCHED_HW;
+
+	I915_WRITE(GEN7_FF_THREAD_MODE, reg);
+}
+
+static void lpt_init_clock_gating(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	/*
+	 * TODO: this bit should only be enabled when really needed, then
+	 * disabled when not needed anymore in order to save power.
+	 */
+	if (HAS_PCH_LPT_LP(dev))
+		I915_WRITE(SOUTH_DSPCLK_GATE_D,
+			   I915_READ(SOUTH_DSPCLK_GATE_D) |
+			   PCH_LP_PARTITION_LEVEL_DISABLE);
+
+	/* WADPOClockGatingDisable:hsw */
+	I915_WRITE(TRANS_CHICKEN1(PIPE_A),
+		   I915_READ(TRANS_CHICKEN1(PIPE_A)) |
+		   TRANS_CHICKEN1_DP0UNIT_GC_DISABLE);
+}
+
+static void lpt_suspend_hw(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	if (HAS_PCH_LPT_LP(dev)) {
+		uint32_t val = I915_READ(SOUTH_DSPCLK_GATE_D);
+
+		val &= ~PCH_LP_PARTITION_LEVEL_DISABLE;
+		I915_WRITE(SOUTH_DSPCLK_GATE_D, val);
+	}
+}
+
+static void kabylake_init_clock_gating(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	gen9_init_clock_gating(dev);
+
+	/* WaDisableSDEUnitClockGating:kbl */
+	if (IS_KBL_REVID(dev_priv, 0, KBL_REVID_B0))
+		I915_WRITE(GEN8_UCGCTL6, I915_READ(GEN8_UCGCTL6) |
+			   GEN8_SDEUNIT_CLOCK_GATE_DISABLE);
+
+	/* WaDisableGamClockGating:kbl */
+	if (IS_KBL_REVID(dev_priv, 0, KBL_REVID_B0))
+		I915_WRITE(GEN6_UCGCTL1, I915_READ(GEN6_UCGCTL1) |
+			   GEN6_GAMUNIT_CLOCK_GATE_DISABLE);
+
+	/* WaFbcNukeOnHostModify:kbl */
+	I915_WRITE(ILK_DPFC_CHICKEN, I915_READ(ILK_DPFC_CHICKEN) |
+		   ILK_DPFC_NUKE_ON_ANY_MODIFICATION);
+}
+
+static void skylake_init_clock_gating(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	gen9_init_clock_gating(dev);
+
+	/* WaFbcNukeOnHostModify:skl */
+	I915_WRITE(ILK_DPFC_CHICKEN, I915_READ(ILK_DPFC_CHICKEN) |
+		   ILK_DPFC_NUKE_ON_ANY_MODIFICATION);
+}
+
+static void broadwell_init_clock_gating(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	enum pipe pipe;
+	uint32_t misccpctl;
+
+	ilk_init_lp_watermarks(dev);
+
+	/* WaSwitchSolVfFArbitrationPriority:bdw */
+	I915_WRITE(GAM_ECOCHK, I915_READ(GAM_ECOCHK) | HSW_ECOCHK_ARB_PRIO_SOL);
+
+	/* WaPsrDPAMaskVBlankInSRD:bdw */
+	I915_WRITE(CHICKEN_PAR1_1,
+		   I915_READ(CHICKEN_PAR1_1) | DPA_MASK_VBLANK_SRD);
+
+	/* WaPsrDPRSUnmaskVBlankInSRD:bdw */
+	for_each_pipe(dev_priv, pipe) {
+		I915_WRITE(CHICKEN_PIPESL_1(pipe),
+			   I915_READ(CHICKEN_PIPESL_1(pipe)) |
+			   BDW_DPRS_MASK_VBLANK_SRD);
+	}
+
+	/* WaVSRefCountFullforceMissDisable:bdw */
+	/* WaDSRefCountFullforceMissDisable:bdw */
+	I915_WRITE(GEN7_FF_THREAD_MODE,
+		   I915_READ(GEN7_FF_THREAD_MODE) &
+		   ~(GEN8_FF_DS_REF_CNT_FFME | GEN7_FF_VS_REF_CNT_FFME));
+
+	I915_WRITE(GEN6_RC_SLEEP_PSMI_CONTROL,
+		   _MASKED_BIT_ENABLE(GEN8_RC_SEMA_IDLE_MSG_DISABLE));
+
+	/* WaDisableSDEUnitClockGating:bdw */
+	I915_WRITE(GEN8_UCGCTL6, I915_READ(GEN8_UCGCTL6) |
+		   GEN8_SDEUNIT_CLOCK_GATE_DISABLE);
+
+	/*
+	 * WaProgramL3SqcReg1Default:bdw
+	 * WaTempDisableDOPClkGating:bdw
+	 */
+	misccpctl = I915_READ(GEN7_MISCCPCTL);
+	I915_WRITE(GEN7_MISCCPCTL, misccpctl & ~GEN7_DOP_CLOCK_GATE_ENABLE);
+	I915_WRITE(GEN8_L3SQCREG1, BDW_WA_L3SQCREG1_DEFAULT);
+	/*
+	 * Wait at least 100 clocks before re-enabling clock gating. See
+	 * the definition of L3SQCREG1 in BSpec.
+	 */
+	POSTING_READ(GEN8_L3SQCREG1);
+	udelay(1);
+	I915_WRITE(GEN7_MISCCPCTL, misccpctl);
+
+	/*
+	 * WaGttCachingOffByDefault:bdw
+	 * GTT cache may not work with big pages, so if those
+	 * are ever enabled GTT cache may need to be disabled.
+	 */
+	I915_WRITE(HSW_GTT_CACHE_EN, GTT_CACHE_EN_ALL);
+
+	lpt_init_clock_gating(dev);
+}
+
+static void haswell_init_clock_gating(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	ilk_init_lp_watermarks(dev);
+
+	/* L3 caching of data atomics doesn't work -- disable it. */
+	I915_WRITE(HSW_SCRATCH1, HSW_SCRATCH1_L3_DATA_ATOMICS_DISABLE);
+	I915_WRITE(HSW_ROW_CHICKEN3,
+		   _MASKED_BIT_ENABLE(HSW_ROW_CHICKEN3_L3_GLOBAL_ATOMICS_DISABLE));
+
+	/* This is required by WaCatErrorRejectionIssue:hsw */
+	I915_WRITE(GEN7_SQ_CHICKEN_MBCUNIT_CONFIG,
+			I915_READ(GEN7_SQ_CHICKEN_MBCUNIT_CONFIG) |
+			GEN7_SQ_CHICKEN_MBCUNIT_SQINTMOB);
+
+	/* WaVSRefCountFullforceMissDisable:hsw */
+	I915_WRITE(GEN7_FF_THREAD_MODE,
+		   I915_READ(GEN7_FF_THREAD_MODE) & ~GEN7_FF_VS_REF_CNT_FFME);
+
+	/* WaDisable_RenderCache_OperationalFlush:hsw */
+	I915_WRITE(CACHE_MODE_0_GEN7, _MASKED_BIT_DISABLE(RC_OP_FLUSH_ENABLE));
+
+	/* enable HiZ Raw Stall Optimization */
+	I915_WRITE(CACHE_MODE_0_GEN7,
+		   _MASKED_BIT_DISABLE(HIZ_RAW_STALL_OPT_DISABLE));
+
+	/* WaDisable4x2SubspanOptimization:hsw */
+	I915_WRITE(CACHE_MODE_1,
+		   _MASKED_BIT_ENABLE(PIXEL_SUBSPAN_COLLECT_OPT_DISABLE));
+
+	/*
+	 * BSpec recommends 8x4 when MSAA is used,
+	 * however in practice 16x4 seems fastest.
+	 *
+	 * Note that PS/WM thread counts depend on the WIZ hashing
+	 * disable bit, which we don't touch here, but it's good
+	 * to keep in mind (see 3DSTATE_PS and 3DSTATE_WM).
+	 */
+	I915_WRITE(GEN7_GT_MODE,
+		   _MASKED_FIELD(GEN6_WIZ_HASHING_MASK, GEN6_WIZ_HASHING_16x4));
+
+	/* WaSampleCChickenBitEnable:hsw */
+	I915_WRITE(HALF_SLICE_CHICKEN3,
+		   _MASKED_BIT_ENABLE(HSW_SAMPLE_C_PERFORMANCE));
+
+	/* WaSwitchSolVfFArbitrationPriority:hsw */
+	I915_WRITE(GAM_ECOCHK, I915_READ(GAM_ECOCHK) | HSW_ECOCHK_ARB_PRIO_SOL);
+
+	/* WaRsPkgCStateDisplayPMReq:hsw */
+	I915_WRITE(CHICKEN_PAR1_1,
+		   I915_READ(CHICKEN_PAR1_1) | FORCE_ARB_IDLE_PLANES);
+
+	lpt_init_clock_gating(dev);
+}
+
+static void ivybridge_init_clock_gating(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	uint32_t snpcr;
+
+	ilk_init_lp_watermarks(dev);
+
+	I915_WRITE(ILK_DSPCLK_GATE_D, ILK_VRHUNIT_CLOCK_GATE_DISABLE);
+
+	/* WaDisableEarlyCull:ivb */
+	I915_WRITE(_3D_CHICKEN3,
+		   _MASKED_BIT_ENABLE(_3D_CHICKEN_SF_DISABLE_OBJEND_CULL));
+
+	/* WaDisableBackToBackFlipFix:ivb */
+	I915_WRITE(IVB_CHICKEN3,
+		   CHICKEN3_DGMG_REQ_OUT_FIX_DISABLE |
+		   CHICKEN3_DGMG_DONE_FIX_DISABLE);
+
+	/* WaDisablePSDDualDispatchEnable:ivb */
+	if (IS_IVB_GT1(dev))
+		I915_WRITE(GEN7_HALF_SLICE_CHICKEN1,
+			   _MASKED_BIT_ENABLE(GEN7_PSD_SINGLE_PORT_DISPATCH_ENABLE));
+
+	/* WaDisable_RenderCache_OperationalFlush:ivb */
+	I915_WRITE(CACHE_MODE_0_GEN7, _MASKED_BIT_DISABLE(RC_OP_FLUSH_ENABLE));
+
+	/* Apply the WaDisableRHWOOptimizationForRenderHang:ivb workaround. */
+	I915_WRITE(GEN7_COMMON_SLICE_CHICKEN1,
+		   GEN7_CSC1_RHWO_OPT_DISABLE_IN_RCC);
+
+	/* WaApplyL3ControlAndL3ChickenMode:ivb */
+	I915_WRITE(GEN7_L3CNTLREG1,
+			GEN7_WA_FOR_GEN7_L3_CONTROL);
+	I915_WRITE(GEN7_L3_CHICKEN_MODE_REGISTER,
+		   GEN7_WA_L3_CHICKEN_MODE);
+	if (IS_IVB_GT1(dev))
+		I915_WRITE(GEN7_ROW_CHICKEN2,
+			   _MASKED_BIT_ENABLE(DOP_CLOCK_GATING_DISABLE));
+	else {
+		/* must write both registers */
+		I915_WRITE(GEN7_ROW_CHICKEN2,
+			   _MASKED_BIT_ENABLE(DOP_CLOCK_GATING_DISABLE));
+		I915_WRITE(GEN7_ROW_CHICKEN2_GT2,
+			   _MASKED_BIT_ENABLE(DOP_CLOCK_GATING_DISABLE));
+	}
+
+	/* WaForceL3Serialization:ivb */
+	I915_WRITE(GEN7_L3SQCREG4, I915_READ(GEN7_L3SQCREG4) &
+		   ~L3SQ_URB_READ_CAM_MATCH_DISABLE);
+
+	/*
+	 * According to the spec, bit 13 (RCZUNIT) must be set on IVB.
+	 * This implements the WaDisableRCZUnitClockGating:ivb workaround.
+	 */
+	I915_WRITE(GEN6_UCGCTL2,
+		   GEN6_RCZUNIT_CLOCK_GATE_DISABLE);
+
+	/* This is required by WaCatErrorRejectionIssue:ivb */
+	I915_WRITE(GEN7_SQ_CHICKEN_MBCUNIT_CONFIG,
+			I915_READ(GEN7_SQ_CHICKEN_MBCUNIT_CONFIG) |
+			GEN7_SQ_CHICKEN_MBCUNIT_SQINTMOB);
+
+	g4x_disable_trickle_feed(dev);
+
+	gen7_setup_fixed_func_scheduler(dev_priv);
+
+	if (0) { /* causes HiZ corruption on ivb:gt1 */
+		/* enable HiZ Raw Stall Optimization */
+		I915_WRITE(CACHE_MODE_0_GEN7,
+			   _MASKED_BIT_DISABLE(HIZ_RAW_STALL_OPT_DISABLE));
+	}
+
+	/* WaDisable4x2SubspanOptimization:ivb */
+	I915_WRITE(CACHE_MODE_1,
+		   _MASKED_BIT_ENABLE(PIXEL_SUBSPAN_COLLECT_OPT_DISABLE));
+
+	/*
+	 * BSpec recommends 8x4 when MSAA is used,
+	 * however in practice 16x4 seems fastest.
+	 *
+	 * Note that PS/WM thread counts depend on the WIZ hashing
+	 * disable bit, which we don't touch here, but it's good
+	 * to keep in mind (see 3DSTATE_PS and 3DSTATE_WM).
+	 */
+	I915_WRITE(GEN7_GT_MODE,
+		   _MASKED_FIELD(GEN6_WIZ_HASHING_MASK, GEN6_WIZ_HASHING_16x4));
+
+	snpcr = I915_READ(GEN6_MBCUNIT_SNPCR);
+	snpcr &= ~GEN6_MBC_SNPCR_MASK;
+	snpcr |= GEN6_MBC_SNPCR_MED;
+	I915_WRITE(GEN6_MBCUNIT_SNPCR, snpcr);
+
+	if (!HAS_PCH_NOP(dev))
+		cpt_init_clock_gating(dev);
+
+	gen6_check_mch_setup(dev);
+}
+
+static void valleyview_init_clock_gating(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	/* WaDisableEarlyCull:vlv */
+	I915_WRITE(_3D_CHICKEN3,
+		   _MASKED_BIT_ENABLE(_3D_CHICKEN_SF_DISABLE_OBJEND_CULL));
+
+	/* WaDisableBackToBackFlipFix:vlv */
+	I915_WRITE(IVB_CHICKEN3,
+		   CHICKEN3_DGMG_REQ_OUT_FIX_DISABLE |
+		   CHICKEN3_DGMG_DONE_FIX_DISABLE);
+
+	/* WaPsdDispatchEnable:vlv */
+	/* WaDisablePSDDualDispatchEnable:vlv */
+	I915_WRITE(GEN7_HALF_SLICE_CHICKEN1,
+		   _MASKED_BIT_ENABLE(GEN7_MAX_PS_THREAD_DEP |
+				      GEN7_PSD_SINGLE_PORT_DISPATCH_ENABLE));
+
+	/* WaDisable_RenderCache_OperationalFlush:vlv */
+	I915_WRITE(CACHE_MODE_0_GEN7, _MASKED_BIT_DISABLE(RC_OP_FLUSH_ENABLE));
+
+	/* WaForceL3Serialization:vlv */
+	I915_WRITE(GEN7_L3SQCREG4, I915_READ(GEN7_L3SQCREG4) &
+		   ~L3SQ_URB_READ_CAM_MATCH_DISABLE);
+
+	/* WaDisableDopClockGating:vlv */
+	I915_WRITE(GEN7_ROW_CHICKEN2,
+		   _MASKED_BIT_ENABLE(DOP_CLOCK_GATING_DISABLE));
+
+	/* This is required by WaCatErrorRejectionIssue:vlv */
+	I915_WRITE(GEN7_SQ_CHICKEN_MBCUNIT_CONFIG,
+		   I915_READ(GEN7_SQ_CHICKEN_MBCUNIT_CONFIG) |
+		   GEN7_SQ_CHICKEN_MBCUNIT_SQINTMOB);
+
+	gen7_setup_fixed_func_scheduler(dev_priv);
+
+	/*
+	 * According to the spec, bit 13 (RCZUNIT) must be set on IVB.
+	 * This implements the WaDisableRCZUnitClockGating:vlv workaround.
+	 */
+	I915_WRITE(GEN6_UCGCTL2,
+		   GEN6_RCZUNIT_CLOCK_GATE_DISABLE);
+
+	/* WaDisableL3Bank2xClockGate:vlv
+	 * Disabling L3 clock gating- MMIO 940c[25] = 1
+	 * Set bit 25, to disable L3_BANK_2x_CLK_GATING */
+	I915_WRITE(GEN7_UCGCTL4,
+		   I915_READ(GEN7_UCGCTL4) | GEN7_L3BANK2X_CLOCK_GATE_DISABLE);
+
+	/*
+	 * BSpec says this must be set, even though
+	 * WaDisable4x2SubspanOptimization isn't listed for VLV.
+	 */
+	I915_WRITE(CACHE_MODE_1,
+		   _MASKED_BIT_ENABLE(PIXEL_SUBSPAN_COLLECT_OPT_DISABLE));
+
+	/*
+	 * BSpec recommends 8x4 when MSAA is used,
+	 * however in practice 16x4 seems fastest.
+	 *
+	 * Note that PS/WM thread counts depend on the WIZ hashing
+	 * disable bit, which we don't touch here, but it's good
+	 * to keep in mind (see 3DSTATE_PS and 3DSTATE_WM).
+	 */
+	I915_WRITE(GEN7_GT_MODE,
+		   _MASKED_FIELD(GEN6_WIZ_HASHING_MASK, GEN6_WIZ_HASHING_16x4));
+
+	/*
+	 * WaIncreaseL3CreditsForVLVB0:vlv
+	 * This is the hardware default actually.
+	 */
+	I915_WRITE(GEN7_L3SQCREG1, VLV_B0_WA_L3SQCREG1_VALUE);
+
+	/*
+	 * WaDisableVLVClockGating_VBIIssue:vlv
+	 * Disable clock gating on th GCFG unit to prevent a delay
+	 * in the reporting of vblank events.
+	 */
+	I915_WRITE(VLV_GUNIT_CLOCK_GATE, GCFG_DIS);
+}
+
+static void cherryview_init_clock_gating(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	/* WaVSRefCountFullforceMissDisable:chv */
+	/* WaDSRefCountFullforceMissDisable:chv */
+	I915_WRITE(GEN7_FF_THREAD_MODE,
+		   I915_READ(GEN7_FF_THREAD_MODE) &
+		   ~(GEN8_FF_DS_REF_CNT_FFME | GEN7_FF_VS_REF_CNT_FFME));
+
+	/* WaDisableSemaphoreAndSyncFlipWait:chv */
+	I915_WRITE(GEN6_RC_SLEEP_PSMI_CONTROL,
+		   _MASKED_BIT_ENABLE(GEN8_RC_SEMA_IDLE_MSG_DISABLE));
+
+	/* WaDisableCSUnitClockGating:chv */
+	I915_WRITE(GEN6_UCGCTL1, I915_READ(GEN6_UCGCTL1) |
+		   GEN6_CSUNIT_CLOCK_GATE_DISABLE);
+
+	/* WaDisableSDEUnitClockGating:chv */
+	I915_WRITE(GEN8_UCGCTL6, I915_READ(GEN8_UCGCTL6) |
+		   GEN8_SDEUNIT_CLOCK_GATE_DISABLE);
+
+	/*
+	 * GTT cache may not work with big pages, so if those
+	 * are ever enabled GTT cache may need to be disabled.
+	 */
+	I915_WRITE(HSW_GTT_CACHE_EN, GTT_CACHE_EN_ALL);
+}
+
+static void g4x_init_clock_gating(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	uint32_t dspclk_gate;
+
+	I915_WRITE(RENCLK_GATE_D1, 0);
+	I915_WRITE(RENCLK_GATE_D2, VF_UNIT_CLOCK_GATE_DISABLE |
+		   GS_UNIT_CLOCK_GATE_DISABLE |
+		   CL_UNIT_CLOCK_GATE_DISABLE);
+	I915_WRITE(RAMCLK_GATE_D, 0);
+	dspclk_gate = VRHUNIT_CLOCK_GATE_DISABLE |
+		OVRUNIT_CLOCK_GATE_DISABLE |
+		OVCUNIT_CLOCK_GATE_DISABLE;
+	if (IS_GM45(dev))
+		dspclk_gate |= DSSUNIT_CLOCK_GATE_DISABLE;
+	I915_WRITE(DSPCLK_GATE_D, dspclk_gate);
+
+	/* WaDisableRenderCachePipelinedFlush */
+	I915_WRITE(CACHE_MODE_0,
+		   _MASKED_BIT_ENABLE(CM0_PIPELINED_RENDER_FLUSH_DISABLE));
+
+	/* WaDisable_RenderCache_OperationalFlush:g4x */
+	I915_WRITE(CACHE_MODE_0, _MASKED_BIT_DISABLE(RC_OP_FLUSH_ENABLE));
+
+	g4x_disable_trickle_feed(dev);
+}
+
+static void crestline_init_clock_gating(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	I915_WRITE(RENCLK_GATE_D1, I965_RCC_CLOCK_GATE_DISABLE);
+	I915_WRITE(RENCLK_GATE_D2, 0);
+	I915_WRITE(DSPCLK_GATE_D, 0);
+	I915_WRITE(RAMCLK_GATE_D, 0);
+	I915_WRITE16(DEUC, 0);
+	I915_WRITE(MI_ARB_STATE,
+		   _MASKED_BIT_ENABLE(MI_ARB_DISPLAY_TRICKLE_FEED_DISABLE));
+
+	/* WaDisable_RenderCache_OperationalFlush:gen4 */
+	I915_WRITE(CACHE_MODE_0, _MASKED_BIT_DISABLE(RC_OP_FLUSH_ENABLE));
+}
+
+static void broadwater_init_clock_gating(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	I915_WRITE(RENCLK_GATE_D1, I965_RCZ_CLOCK_GATE_DISABLE |
+		   I965_RCC_CLOCK_GATE_DISABLE |
+		   I965_RCPB_CLOCK_GATE_DISABLE |
+		   I965_ISC_CLOCK_GATE_DISABLE |
+		   I965_FBC_CLOCK_GATE_DISABLE);
+	I915_WRITE(RENCLK_GATE_D2, 0);
+	I915_WRITE(MI_ARB_STATE,
+		   _MASKED_BIT_ENABLE(MI_ARB_DISPLAY_TRICKLE_FEED_DISABLE));
+
+	/* WaDisable_RenderCache_OperationalFlush:gen4 */
+	I915_WRITE(CACHE_MODE_0, _MASKED_BIT_DISABLE(RC_OP_FLUSH_ENABLE));
+}
+
+static void gen3_init_clock_gating(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	u32 dstate = I915_READ(D_STATE);
+
+	dstate |= DSTATE_PLL_D3_OFF | DSTATE_GFX_CLOCK_GATING |
+		DSTATE_DOT_CLOCK_GATING;
+	I915_WRITE(D_STATE, dstate);
+
+	if (IS_PINEVIEW(dev))
+		I915_WRITE(ECOSKPD, _MASKED_BIT_ENABLE(ECO_GATING_CX_ONLY));
+
+	/* IIR "flip pending" means done if this bit is set */
+	I915_WRITE(ECOSKPD, _MASKED_BIT_DISABLE(ECO_FLIP_DONE));
+
+	/* interrupts should cause a wake up from C3 */
+	I915_WRITE(INSTPM, _MASKED_BIT_ENABLE(INSTPM_AGPBUSY_INT_EN));
+
+	/* On GEN3 we really need to make sure the ARB C3 LP bit is set */
+	I915_WRITE(MI_ARB_STATE, _MASKED_BIT_ENABLE(MI_ARB_C3_LP_WRITE_ENABLE));
+
+	I915_WRITE(MI_ARB_STATE,
+		   _MASKED_BIT_ENABLE(MI_ARB_DISPLAY_TRICKLE_FEED_DISABLE));
+}
+
+static void i85x_init_clock_gating(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	I915_WRITE(RENCLK_GATE_D1, SV_CLOCK_GATE_DISABLE);
+
+	/* interrupts should cause a wake up from C3 */
+	I915_WRITE(MI_STATE, _MASKED_BIT_ENABLE(MI_AGPBUSY_INT_EN) |
+		   _MASKED_BIT_DISABLE(MI_AGPBUSY_830_MODE));
+
+	I915_WRITE(MEM_MODE,
+		   _MASKED_BIT_ENABLE(MEM_DISPLAY_TRICKLE_FEED_DISABLE));
+}
+
+static void i830_init_clock_gating(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	I915_WRITE(DSPCLK_GATE_D, OVRUNIT_CLOCK_GATE_DISABLE);
+
+	I915_WRITE(MEM_MODE,
+		   _MASKED_BIT_ENABLE(MEM_DISPLAY_A_TRICKLE_FEED_DISABLE) |
+		   _MASKED_BIT_ENABLE(MEM_DISPLAY_B_TRICKLE_FEED_DISABLE));
+}
+
+void intel_init_clock_gating(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	dev_priv->display.init_clock_gating(dev);
+}
+
+void intel_suspend_hw(struct drm_device *dev)
+{
+	if (HAS_PCH_LPT(dev))
+		lpt_suspend_hw(dev);
+}
+
+static void nop_init_clock_gating(struct drm_device *dev)
+{
+	DRM_DEBUG_KMS("No clock gating settings or workarounds applied.\n");
+}
+
+/**
+ * intel_init_clock_gating_hooks - setup the clock gating hooks
+ * @dev_priv: device private
+ *
+ * Setup the hooks that configure which clocks of a given platform can be
+ * gated and also apply various GT and display specific workarounds for these
+ * platforms. Note that some GT specific workarounds are applied separately
+ * when GPU contexts or batchbuffers start their execution.
+ */
+void intel_init_clock_gating_hooks(struct drm_i915_private *dev_priv)
+{
+	if (IS_SKYLAKE(dev_priv))
+		dev_priv->display.init_clock_gating = skylake_init_clock_gating;
+	else if (IS_KABYLAKE(dev_priv))
+		dev_priv->display.init_clock_gating = kabylake_init_clock_gating;
+	else if (IS_BROXTON(dev_priv))
+		dev_priv->display.init_clock_gating = bxt_init_clock_gating;
+	else if (IS_BROADWELL(dev_priv))
+		dev_priv->display.init_clock_gating = broadwell_init_clock_gating;
+	else if (IS_CHERRYVIEW(dev_priv))
+		dev_priv->display.init_clock_gating = cherryview_init_clock_gating;
+	else if (IS_HASWELL(dev_priv))
+		dev_priv->display.init_clock_gating = haswell_init_clock_gating;
+	else if (IS_IVYBRIDGE(dev_priv))
+		dev_priv->display.init_clock_gating = ivybridge_init_clock_gating;
+	else if (IS_VALLEYVIEW(dev_priv))
+		dev_priv->display.init_clock_gating = valleyview_init_clock_gating;
+	else if (IS_GEN6(dev_priv))
+		dev_priv->display.init_clock_gating = gen6_init_clock_gating;
+	else if (IS_GEN5(dev_priv))
+		dev_priv->display.init_clock_gating = ironlake_init_clock_gating;
+	else if (IS_G4X(dev_priv))
+		dev_priv->display.init_clock_gating = g4x_init_clock_gating;
+	else if (IS_CRESTLINE(dev_priv))
+		dev_priv->display.init_clock_gating = crestline_init_clock_gating;
+	else if (IS_BROADWATER(dev_priv))
+		dev_priv->display.init_clock_gating = broadwater_init_clock_gating;
+	else if (IS_GEN3(dev_priv))
+		dev_priv->display.init_clock_gating = gen3_init_clock_gating;
+	else if (IS_I85X(dev_priv) || IS_I865G(dev_priv))
+		dev_priv->display.init_clock_gating = i85x_init_clock_gating;
+	else if (IS_GEN2(dev_priv))
+		dev_priv->display.init_clock_gating = i830_init_clock_gating;
+	else {
+		MISSING_CASE(INTEL_DEVID(dev_priv));
+		dev_priv->display.init_clock_gating = nop_init_clock_gating;
+	}
+}
+
+/* Set up chip specific power management-related functions */
+void intel_init_pm(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	intel_fbc_init(dev_priv);
+
+	/* For cxsr */
+	if (IS_PINEVIEW(dev))
+		i915_pineview_get_mem_freq(dev);
+	else if (IS_GEN5(dev))
+		i915_ironlake_get_mem_freq(dev);
+
+	/* For FIFO watermark updates */
+	if (INTEL_INFO(dev)->gen >= 9) {
+		skl_setup_wm_latency(dev);
+		dev_priv->display.update_wm = skl_update_wm;
+	} else if (HAS_PCH_SPLIT(dev)) {
+		ilk_setup_wm_latency(dev);
+
+		if ((IS_GEN5(dev) && dev_priv->wm.pri_latency[1] &&
+		     dev_priv->wm.spr_latency[1] && dev_priv->wm.cur_latency[1]) ||
+		    (!IS_GEN5(dev) && dev_priv->wm.pri_latency[0] &&
+		     dev_priv->wm.spr_latency[0] && dev_priv->wm.cur_latency[0])) {
+			dev_priv->display.compute_pipe_wm = ilk_compute_pipe_wm;
+			dev_priv->display.compute_intermediate_wm =
+				ilk_compute_intermediate_wm;
+			dev_priv->display.initial_watermarks =
+				ilk_initial_watermarks;
+			dev_priv->display.optimize_watermarks =
+				ilk_optimize_watermarks;
+		} else {
+			DRM_DEBUG_KMS("Failed to read display plane latency. "
+				      "Disable CxSR\n");
+		}
+	} else if (IS_CHERRYVIEW(dev)) {
+		vlv_setup_wm_latency(dev);
+		dev_priv->display.update_wm = vlv_update_wm;
+	} else if (IS_VALLEYVIEW(dev)) {
+		vlv_setup_wm_latency(dev);
+		dev_priv->display.update_wm = vlv_update_wm;
+	} else if (IS_PINEVIEW(dev)) {
+		if (!intel_get_cxsr_latency(IS_PINEVIEW_G(dev),
+					    dev_priv->is_ddr3,
+					    dev_priv->fsb_freq,
+					    dev_priv->mem_freq)) {
+			DRM_INFO("failed to find known CxSR latency "
+				 "(found ddr%s fsb freq %d, mem freq %d), "
+				 "disabling CxSR\n",
+				 (dev_priv->is_ddr3 == 1) ? "3" : "2",
+				 dev_priv->fsb_freq, dev_priv->mem_freq);
+			/* Disable CxSR and never update its watermark again */
+			intel_set_memory_cxsr(dev_priv, false);
+			dev_priv->display.update_wm = NULL;
+		} else
+			dev_priv->display.update_wm = pineview_update_wm;
+	} else if (IS_G4X(dev)) {
+		dev_priv->display.update_wm = g4x_update_wm;
+	} else if (IS_GEN4(dev)) {
+		dev_priv->display.update_wm = i965_update_wm;
+	} else if (IS_GEN3(dev)) {
+		dev_priv->display.update_wm = i9xx_update_wm;
+		dev_priv->display.get_fifo_size = i9xx_get_fifo_size;
+	} else if (IS_GEN2(dev)) {
+		if (INTEL_INFO(dev)->num_pipes == 1) {
+			dev_priv->display.update_wm = i845_update_wm;
+			dev_priv->display.get_fifo_size = i845_get_fifo_size;
+		} else {
+			dev_priv->display.update_wm = i9xx_update_wm;
+			dev_priv->display.get_fifo_size = i830_get_fifo_size;
+		}
+	} else {
+		DRM_ERROR("unexpected fall-through in intel_init_pm\n");
+	}
+}
+
+int sandybridge_pcode_read(struct drm_i915_private *dev_priv, u32 mbox, u32 *val)
+{
+	WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock));
+
+	if (I915_READ(GEN6_PCODE_MAILBOX) & GEN6_PCODE_READY) {
+		DRM_DEBUG_DRIVER("warning: pcode (read) mailbox access failed\n");
+		return -EAGAIN;
+	}
+
+	I915_WRITE(GEN6_PCODE_DATA, *val);
+	I915_WRITE(GEN6_PCODE_DATA1, 0);
+	I915_WRITE(GEN6_PCODE_MAILBOX, GEN6_PCODE_READY | mbox);
+
+	if (wait_for((I915_READ(GEN6_PCODE_MAILBOX) & GEN6_PCODE_READY) == 0,
+		     500)) {
+		DRM_ERROR("timeout waiting for pcode read (%d) to finish\n", mbox);
+		return -ETIMEDOUT;
+	}
+
+	*val = I915_READ(GEN6_PCODE_DATA);
+	I915_WRITE(GEN6_PCODE_DATA, 0);
+
+	return 0;
+}
+
+int sandybridge_pcode_write(struct drm_i915_private *dev_priv, u32 mbox, u32 val)
+{
+	WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock));
+
+	if (I915_READ(GEN6_PCODE_MAILBOX) & GEN6_PCODE_READY) {
+		DRM_DEBUG_DRIVER("warning: pcode (write) mailbox access failed\n");
+		return -EAGAIN;
+	}
+
+	I915_WRITE(GEN6_PCODE_DATA, val);
+	I915_WRITE(GEN6_PCODE_MAILBOX, GEN6_PCODE_READY | mbox);
+
+	if (wait_for((I915_READ(GEN6_PCODE_MAILBOX) & GEN6_PCODE_READY) == 0,
+		     500)) {
+		DRM_ERROR("timeout waiting for pcode write (%d) to finish\n", mbox);
+		return -ETIMEDOUT;
+	}
+
+	I915_WRITE(GEN6_PCODE_DATA, 0);
+
+	return 0;
+}
+
+static int byt_gpu_freq(struct drm_i915_private *dev_priv, int val)
+{
+	/*
+	 * N = val - 0xb7
+	 * Slow = Fast = GPLL ref * N
+	 */
+	return DIV_ROUND_CLOSEST(dev_priv->rps.gpll_ref_freq * (val - 0xb7), 1000);
+}
+
+static int byt_freq_opcode(struct drm_i915_private *dev_priv, int val)
+{
+	return DIV_ROUND_CLOSEST(1000 * val, dev_priv->rps.gpll_ref_freq) + 0xb7;
+}
+
+static int chv_gpu_freq(struct drm_i915_private *dev_priv, int val)
+{
+	/*
+	 * N = val / 2
+	 * CU (slow) = CU2x (fast) / 2 = GPLL ref * N / 2
+	 */
+	return DIV_ROUND_CLOSEST(dev_priv->rps.gpll_ref_freq * val, 2 * 2 * 1000);
+}
+
+static int chv_freq_opcode(struct drm_i915_private *dev_priv, int val)
+{
+	/* CHV needs even values */
+	return DIV_ROUND_CLOSEST(2 * 1000 * val, dev_priv->rps.gpll_ref_freq) * 2;
+}
+
+int intel_gpu_freq(struct drm_i915_private *dev_priv, int val)
+{
+	if (IS_GEN9(dev_priv))
+		return DIV_ROUND_CLOSEST(val * GT_FREQUENCY_MULTIPLIER,
+					 GEN9_FREQ_SCALER);
+	else if (IS_CHERRYVIEW(dev_priv))
+		return chv_gpu_freq(dev_priv, val);
+	else if (IS_VALLEYVIEW(dev_priv))
+		return byt_gpu_freq(dev_priv, val);
+	else
+		return val * GT_FREQUENCY_MULTIPLIER;
+}
+
+int intel_freq_opcode(struct drm_i915_private *dev_priv, int val)
+{
+	if (IS_GEN9(dev_priv))
+		return DIV_ROUND_CLOSEST(val * GEN9_FREQ_SCALER,
+					 GT_FREQUENCY_MULTIPLIER);
+	else if (IS_CHERRYVIEW(dev_priv))
+		return chv_freq_opcode(dev_priv, val);
+	else if (IS_VALLEYVIEW(dev_priv))
+		return byt_freq_opcode(dev_priv, val);
+	else
+		return DIV_ROUND_CLOSEST(val, GT_FREQUENCY_MULTIPLIER);
+}
+
+struct request_boost {
+	struct work_struct work;
+	struct drm_i915_gem_request *req;
+};
+
+static void __intel_rps_boost_work(struct work_struct *work)
+{
+	struct request_boost *boost = container_of(work, struct request_boost, work);
+	struct drm_i915_gem_request *req = boost->req;
+
+	if (!i915_gem_request_completed(req, true))
+		gen6_rps_boost(to_i915(req->engine->dev), NULL,
+			       req->emitted_jiffies);
+
+	i915_gem_request_unreference__unlocked(req);
+	kfree(boost);
+}
+
+void intel_queue_rps_boost_for_request(struct drm_device *dev,
+				       struct drm_i915_gem_request *req)
+{
+	struct request_boost *boost;
+
+	if (req == NULL || INTEL_INFO(dev)->gen < 6)
+		return;
+
+	if (i915_gem_request_completed(req, true))
+		return;
+
+	boost = kmalloc(sizeof(*boost), GFP_ATOMIC);
+	if (boost == NULL)
+		return;
+
+	i915_gem_request_reference(req);
+	boost->req = req;
+
+	INIT_WORK(&boost->work, __intel_rps_boost_work);
+	queue_work(to_i915(dev)->wq, &boost->work);
+}
+
+void intel_pm_setup(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	mutex_init(&dev_priv->rps.hw_lock);
+	spin_lock_init(&dev_priv->rps.client_lock);
+
+	INIT_DELAYED_WORK(&dev_priv->rps.delayed_resume_work,
+			  intel_gen6_powersave_work);
+	INIT_LIST_HEAD(&dev_priv->rps.clients);
+	INIT_LIST_HEAD(&dev_priv->rps.semaphores.link);
+	INIT_LIST_HEAD(&dev_priv->rps.mmioflips.link);
+
+	dev_priv->pm.suspended = false;
+	atomic_set(&dev_priv->pm.wakeref_count, 0);
+	atomic_set(&dev_priv->pm.atomic_seq, 0);
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/i915/intel_psr.c
@@ -0,0 +1,852 @@
+/*
+ * Copyright © 2014 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+ * DOC: Panel Self Refresh (PSR/SRD)
+ *
+ * Since Haswell Display controller supports Panel Self-Refresh on display
+ * panels witch have a remote frame buffer (RFB) implemented according to PSR
+ * spec in eDP1.3. PSR feature allows the display to go to lower standby states
+ * when system is idle but display is on as it eliminates display refresh
+ * request to DDR memory completely as long as the frame buffer for that
+ * display is unchanged.
+ *
+ * Panel Self Refresh must be supported by both Hardware (source) and
+ * Panel (sink).
+ *
+ * PSR saves power by caching the framebuffer in the panel RFB, which allows us
+ * to power down the link and memory controller. For DSI panels the same idea
+ * is called "manual mode".
+ *
+ * The implementation uses the hardware-based PSR support which automatically
+ * enters/exits self-refresh mode. The hardware takes care of sending the
+ * required DP aux message and could even retrain the link (that part isn't
+ * enabled yet though). The hardware also keeps track of any frontbuffer
+ * changes to know when to exit self-refresh mode again. Unfortunately that
+ * part doesn't work too well, hence why the i915 PSR support uses the
+ * software frontbuffer tracking to make sure it doesn't miss a screen
+ * update. For this integration intel_psr_invalidate() and intel_psr_flush()
+ * get called by the frontbuffer tracking code. Note that because of locking
+ * issues the self-refresh re-enable code is done from a work queue, which
+ * must be correctly synchronized/cancelled when shutting down the pipe."
+ */
+
+#include <drm/drmP.h>
+
+#include "intel_drv.h"
+#include "i915_drv.h"
+
+static bool is_edp_psr(struct intel_dp *intel_dp)
+{
+	return intel_dp->psr_dpcd[0] & DP_PSR_IS_SUPPORTED;
+}
+
+static bool vlv_is_psr_active_on_pipe(struct drm_device *dev, int pipe)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	uint32_t val;
+
+	val = I915_READ(VLV_PSRSTAT(pipe)) &
+	      VLV_EDP_PSR_CURR_STATE_MASK;
+	return (val == VLV_EDP_PSR_ACTIVE_NORFB_UP) ||
+	       (val == VLV_EDP_PSR_ACTIVE_SF_UPDATE);
+}
+
+static void intel_psr_write_vsc(struct intel_dp *intel_dp,
+				const struct edp_vsc_psr *vsc_psr)
+{
+	struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
+	struct drm_device *dev = dig_port->base.base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_crtc *crtc = to_intel_crtc(dig_port->base.base.crtc);
+	enum transcoder cpu_transcoder = crtc->config->cpu_transcoder;
+	i915_reg_t ctl_reg = HSW_TVIDEO_DIP_CTL(cpu_transcoder);
+	uint32_t *data = (uint32_t *) vsc_psr;
+	unsigned int i;
+
+	/* As per BSPec (Pipe Video Data Island Packet), we need to disable
+	   the video DIP being updated before program video DIP data buffer
+	   registers for DIP being updated. */
+	I915_WRITE(ctl_reg, 0);
+	POSTING_READ(ctl_reg);
+
+	for (i = 0; i < sizeof(*vsc_psr); i += 4) {
+		I915_WRITE(HSW_TVIDEO_DIP_VSC_DATA(cpu_transcoder,
+						   i >> 2), *data);
+		data++;
+	}
+	for (; i < VIDEO_DIP_VSC_DATA_SIZE; i += 4)
+		I915_WRITE(HSW_TVIDEO_DIP_VSC_DATA(cpu_transcoder,
+						   i >> 2), 0);
+
+	I915_WRITE(ctl_reg, VIDEO_DIP_ENABLE_VSC_HSW);
+	POSTING_READ(ctl_reg);
+}
+
+static void vlv_psr_setup_vsc(struct intel_dp *intel_dp)
+{
+	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
+	struct drm_device *dev = intel_dig_port->base.base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct drm_crtc *crtc = intel_dig_port->base.base.crtc;
+	enum pipe pipe = to_intel_crtc(crtc)->pipe;
+	uint32_t val;
+
+	/* VLV auto-generate VSC package as per EDP 1.3 spec, Table 3.10 */
+	val  = I915_READ(VLV_VSCSDP(pipe));
+	val &= ~VLV_EDP_PSR_SDP_FREQ_MASK;
+	val |= VLV_EDP_PSR_SDP_FREQ_EVFRAME;
+	I915_WRITE(VLV_VSCSDP(pipe), val);
+}
+
+static void skl_psr_setup_su_vsc(struct intel_dp *intel_dp)
+{
+	struct edp_vsc_psr psr_vsc;
+
+	/* Prepare VSC Header for SU as per EDP 1.4 spec, Table 6.11 */
+	memset(&psr_vsc, 0, sizeof(psr_vsc));
+	psr_vsc.sdp_header.HB0 = 0;
+	psr_vsc.sdp_header.HB1 = 0x7;
+	psr_vsc.sdp_header.HB2 = 0x3;
+	psr_vsc.sdp_header.HB3 = 0xb;
+	intel_psr_write_vsc(intel_dp, &psr_vsc);
+}
+
+static void hsw_psr_setup_vsc(struct intel_dp *intel_dp)
+{
+	struct edp_vsc_psr psr_vsc;
+
+	/* Prepare VSC packet as per EDP 1.3 spec, Table 3.10 */
+	memset(&psr_vsc, 0, sizeof(psr_vsc));
+	psr_vsc.sdp_header.HB0 = 0;
+	psr_vsc.sdp_header.HB1 = 0x7;
+	psr_vsc.sdp_header.HB2 = 0x2;
+	psr_vsc.sdp_header.HB3 = 0x8;
+	intel_psr_write_vsc(intel_dp, &psr_vsc);
+}
+
+static void vlv_psr_enable_sink(struct intel_dp *intel_dp)
+{
+	drm_dp_dpcd_writeb(&intel_dp->aux, DP_PSR_EN_CFG,
+			   DP_PSR_ENABLE | DP_PSR_MAIN_LINK_ACTIVE);
+}
+
+static i915_reg_t psr_aux_ctl_reg(struct drm_i915_private *dev_priv,
+				       enum port port)
+{
+	if (INTEL_INFO(dev_priv)->gen >= 9)
+		return DP_AUX_CH_CTL(port);
+	else
+		return EDP_PSR_AUX_CTL;
+}
+
+static i915_reg_t psr_aux_data_reg(struct drm_i915_private *dev_priv,
+					enum port port, int index)
+{
+	if (INTEL_INFO(dev_priv)->gen >= 9)
+		return DP_AUX_CH_DATA(port, index);
+	else
+		return EDP_PSR_AUX_DATA(index);
+}
+
+static void hsw_psr_enable_sink(struct intel_dp *intel_dp)
+{
+	struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
+	struct drm_device *dev = dig_port->base.base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	uint32_t aux_clock_divider;
+	i915_reg_t aux_ctl_reg;
+	int precharge = 0x3;
+	static const uint8_t aux_msg[] = {
+		[0] = DP_AUX_NATIVE_WRITE << 4,
+		[1] = DP_SET_POWER >> 8,
+		[2] = DP_SET_POWER & 0xff,
+		[3] = 1 - 1,
+		[4] = DP_SET_POWER_D0,
+	};
+	enum port port = dig_port->port;
+	int i;
+
+	BUILD_BUG_ON(sizeof(aux_msg) > 20);
+
+	aux_clock_divider = intel_dp->get_aux_clock_divider(intel_dp, 0);
+
+	/* Enable AUX frame sync at sink */
+	if (dev_priv->psr.aux_frame_sync)
+		drm_dp_dpcd_writeb(&intel_dp->aux,
+				DP_SINK_DEVICE_AUX_FRAME_SYNC_CONF,
+				DP_AUX_FRAME_SYNC_ENABLE);
+
+	aux_ctl_reg = psr_aux_ctl_reg(dev_priv, port);
+
+	/* Setup AUX registers */
+	for (i = 0; i < sizeof(aux_msg); i += 4)
+		I915_WRITE(psr_aux_data_reg(dev_priv, port, i >> 2),
+			   intel_dp_pack_aux(&aux_msg[i], sizeof(aux_msg) - i));
+
+	if (INTEL_INFO(dev)->gen >= 9) {
+		uint32_t val;
+
+		val = I915_READ(aux_ctl_reg);
+		val &= ~DP_AUX_CH_CTL_TIME_OUT_MASK;
+		val |= DP_AUX_CH_CTL_TIME_OUT_1600us;
+		val &= ~DP_AUX_CH_CTL_MESSAGE_SIZE_MASK;
+		val |= (sizeof(aux_msg) << DP_AUX_CH_CTL_MESSAGE_SIZE_SHIFT);
+		/* Use hardcoded data values for PSR, frame sync and GTC */
+		val &= ~DP_AUX_CH_CTL_PSR_DATA_AUX_REG_SKL;
+		val &= ~DP_AUX_CH_CTL_FS_DATA_AUX_REG_SKL;
+		val &= ~DP_AUX_CH_CTL_GTC_DATA_AUX_REG_SKL;
+		I915_WRITE(aux_ctl_reg, val);
+	} else {
+		I915_WRITE(aux_ctl_reg,
+		   DP_AUX_CH_CTL_TIME_OUT_400us |
+		   (sizeof(aux_msg) << DP_AUX_CH_CTL_MESSAGE_SIZE_SHIFT) |
+		   (precharge << DP_AUX_CH_CTL_PRECHARGE_2US_SHIFT) |
+		   (aux_clock_divider << DP_AUX_CH_CTL_BIT_CLOCK_2X_SHIFT));
+	}
+
+	if (dev_priv->psr.link_standby)
+		drm_dp_dpcd_writeb(&intel_dp->aux, DP_PSR_EN_CFG,
+				   DP_PSR_ENABLE | DP_PSR_MAIN_LINK_ACTIVE);
+	else
+		drm_dp_dpcd_writeb(&intel_dp->aux, DP_PSR_EN_CFG,
+				   DP_PSR_ENABLE);
+}
+
+static void vlv_psr_enable_source(struct intel_dp *intel_dp)
+{
+	struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
+	struct drm_device *dev = dig_port->base.base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct drm_crtc *crtc = dig_port->base.base.crtc;
+	enum pipe pipe = to_intel_crtc(crtc)->pipe;
+
+	/* Transition from PSR_state 0 to PSR_state 1, i.e. PSR Inactive */
+	I915_WRITE(VLV_PSRCTL(pipe),
+		   VLV_EDP_PSR_MODE_SW_TIMER |
+		   VLV_EDP_PSR_SRC_TRANSMITTER_STATE |
+		   VLV_EDP_PSR_ENABLE);
+}
+
+static void vlv_psr_activate(struct intel_dp *intel_dp)
+{
+	struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
+	struct drm_device *dev = dig_port->base.base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct drm_crtc *crtc = dig_port->base.base.crtc;
+	enum pipe pipe = to_intel_crtc(crtc)->pipe;
+
+	/* Let's do the transition from PSR_state 1 to PSR_state 2
+	 * that is PSR transition to active - static frame transmission.
+	 * Then Hardware is responsible for the transition to PSR_state 3
+	 * that is PSR active - no Remote Frame Buffer (RFB) update.
+	 */
+	I915_WRITE(VLV_PSRCTL(pipe), I915_READ(VLV_PSRCTL(pipe)) |
+		   VLV_EDP_PSR_ACTIVE_ENTRY);
+}
+
+static void hsw_psr_enable_source(struct intel_dp *intel_dp)
+{
+	struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
+	struct drm_device *dev = dig_port->base.base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	uint32_t max_sleep_time = 0x1f;
+	/*
+	 * Let's respect VBT in case VBT asks a higher idle_frame value.
+	 * Let's use 6 as the minimum to cover all known cases including
+	 * the off-by-one issue that HW has in some cases. Also there are
+	 * cases where sink should be able to train
+	 * with the 5 or 6 idle patterns.
+	 */
+	uint32_t idle_frames = max(6, dev_priv->vbt.psr.idle_frames);
+	uint32_t val = EDP_PSR_ENABLE;
+
+	val |= max_sleep_time << EDP_PSR_MAX_SLEEP_TIME_SHIFT;
+	val |= idle_frames << EDP_PSR_IDLE_FRAME_SHIFT;
+
+	if (IS_HASWELL(dev))
+		val |= EDP_PSR_MIN_LINK_ENTRY_TIME_8_LINES;
+
+	if (dev_priv->psr.link_standby)
+		val |= EDP_PSR_LINK_STANDBY;
+
+	if (dev_priv->vbt.psr.tp1_wakeup_time > 5)
+		val |= EDP_PSR_TP1_TIME_2500us;
+	else if (dev_priv->vbt.psr.tp1_wakeup_time > 1)
+		val |= EDP_PSR_TP1_TIME_500us;
+	else if (dev_priv->vbt.psr.tp1_wakeup_time > 0)
+		val |= EDP_PSR_TP1_TIME_100us;
+	else
+		val |= EDP_PSR_TP1_TIME_0us;
+
+	if (dev_priv->vbt.psr.tp2_tp3_wakeup_time > 5)
+		val |= EDP_PSR_TP2_TP3_TIME_2500us;
+	else if (dev_priv->vbt.psr.tp2_tp3_wakeup_time > 1)
+		val |= EDP_PSR_TP2_TP3_TIME_500us;
+	else if (dev_priv->vbt.psr.tp2_tp3_wakeup_time > 0)
+		val |= EDP_PSR_TP2_TP3_TIME_100us;
+	else
+		val |= EDP_PSR_TP2_TP3_TIME_0us;
+
+	if (intel_dp_source_supports_hbr2(intel_dp) &&
+	    drm_dp_tps3_supported(intel_dp->dpcd))
+		val |= EDP_PSR_TP1_TP3_SEL;
+	else
+		val |= EDP_PSR_TP1_TP2_SEL;
+
+	I915_WRITE(EDP_PSR_CTL, val);
+
+	if (!dev_priv->psr.psr2_support)
+		return;
+
+	/* FIXME: selective update is probably totally broken because it doesn't
+	 * mesh at all with our frontbuffer tracking. And the hw alone isn't
+	 * good enough. */
+	val = EDP_PSR2_ENABLE | EDP_SU_TRACK_ENABLE;
+
+	if (dev_priv->vbt.psr.tp2_tp3_wakeup_time > 5)
+		val |= EDP_PSR2_TP2_TIME_2500;
+	else if (dev_priv->vbt.psr.tp2_tp3_wakeup_time > 1)
+		val |= EDP_PSR2_TP2_TIME_500;
+	else if (dev_priv->vbt.psr.tp2_tp3_wakeup_time > 0)
+		val |= EDP_PSR2_TP2_TIME_100;
+	else
+		val |= EDP_PSR2_TP2_TIME_50;
+
+	I915_WRITE(EDP_PSR2_CTL, val);
+}
+
+static bool intel_psr_match_conditions(struct intel_dp *intel_dp)
+{
+	struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
+	struct drm_device *dev = dig_port->base.base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct drm_crtc *crtc = dig_port->base.base.crtc;
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+
+	lockdep_assert_held(&dev_priv->psr.lock);
+	WARN_ON(!drm_modeset_is_locked(&dev->mode_config.connection_mutex));
+	WARN_ON(!drm_modeset_is_locked(&crtc->mutex));
+
+	dev_priv->psr.source_ok = false;
+
+	/*
+	 * HSW spec explicitly says PSR is tied to port A.
+	 * BDW+ platforms with DDI implementation of PSR have different
+	 * PSR registers per transcoder and we only implement transcoder EDP
+	 * ones. Since by Display design transcoder EDP is tied to port A
+	 * we can safely escape based on the port A.
+	 */
+	if (HAS_DDI(dev) && dig_port->port != PORT_A) {
+		DRM_DEBUG_KMS("PSR condition failed: Port not supported\n");
+		return false;
+	}
+
+	if (!i915.enable_psr) {
+		DRM_DEBUG_KMS("PSR disable by flag\n");
+		return false;
+	}
+
+	if ((IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev)) &&
+	    !dev_priv->psr.link_standby) {
+		DRM_ERROR("PSR condition failed: Link off requested but not supported on this platform\n");
+		return false;
+	}
+
+	if (IS_HASWELL(dev) &&
+	    I915_READ(HSW_STEREO_3D_CTL(intel_crtc->config->cpu_transcoder)) &
+		      S3D_ENABLE) {
+		DRM_DEBUG_KMS("PSR condition failed: Stereo 3D is Enabled\n");
+		return false;
+	}
+
+	if (IS_HASWELL(dev) &&
+	    intel_crtc->config->base.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE) {
+		DRM_DEBUG_KMS("PSR condition failed: Interlaced is Enabled\n");
+		return false;
+	}
+
+	dev_priv->psr.source_ok = true;
+	return true;
+}
+
+static void intel_psr_activate(struct intel_dp *intel_dp)
+{
+	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
+	struct drm_device *dev = intel_dig_port->base.base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	WARN_ON(I915_READ(EDP_PSR_CTL) & EDP_PSR_ENABLE);
+	WARN_ON(dev_priv->psr.active);
+	lockdep_assert_held(&dev_priv->psr.lock);
+
+	/* Enable/Re-enable PSR on the host */
+	if (HAS_DDI(dev))
+		/* On HSW+ after we enable PSR on source it will activate it
+		 * as soon as it match configure idle_frame count. So
+		 * we just actually enable it here on activation time.
+		 */
+		hsw_psr_enable_source(intel_dp);
+	else
+		vlv_psr_activate(intel_dp);
+
+	dev_priv->psr.active = true;
+}
+
+/**
+ * intel_psr_enable - Enable PSR
+ * @intel_dp: Intel DP
+ *
+ * This function can only be called after the pipe is fully trained and enabled.
+ */
+void intel_psr_enable(struct intel_dp *intel_dp)
+{
+	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
+	struct drm_device *dev = intel_dig_port->base.base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_crtc *crtc = to_intel_crtc(intel_dig_port->base.base.crtc);
+
+	if (!HAS_PSR(dev)) {
+		DRM_DEBUG_KMS("PSR not supported on this platform\n");
+		return;
+	}
+
+	if (!is_edp_psr(intel_dp)) {
+		DRM_DEBUG_KMS("PSR not supported by this panel\n");
+		return;
+	}
+
+	mutex_lock(&dev_priv->psr.lock);
+	if (dev_priv->psr.enabled) {
+		DRM_DEBUG_KMS("PSR already in use\n");
+		goto unlock;
+	}
+
+	if (!intel_psr_match_conditions(intel_dp))
+		goto unlock;
+
+	dev_priv->psr.busy_frontbuffer_bits = 0;
+
+	if (HAS_DDI(dev)) {
+		hsw_psr_setup_vsc(intel_dp);
+
+		if (dev_priv->psr.psr2_support) {
+			/* PSR2 is restricted to work with panel resolutions upto 3200x2000 */
+			if (crtc->config->pipe_src_w > 3200 ||
+				crtc->config->pipe_src_h > 2000)
+				dev_priv->psr.psr2_support = false;
+			else
+				skl_psr_setup_su_vsc(intel_dp);
+		}
+
+		/*
+		 * Per Spec: Avoid continuous PSR exit by masking MEMUP and HPD.
+		 * Also mask LPSP to avoid dependency on other drivers that
+		 * might block runtime_pm besides preventing other hw tracking
+		 * issues now we can rely on frontbuffer tracking.
+		 */
+		I915_WRITE(EDP_PSR_DEBUG_CTL, EDP_PSR_DEBUG_MASK_MEMUP |
+			   EDP_PSR_DEBUG_MASK_HPD | EDP_PSR_DEBUG_MASK_LPSP);
+
+		/* Enable PSR on the panel */
+		hsw_psr_enable_sink(intel_dp);
+
+		if (INTEL_INFO(dev)->gen >= 9)
+			intel_psr_activate(intel_dp);
+	} else {
+		vlv_psr_setup_vsc(intel_dp);
+
+		/* Enable PSR on the panel */
+		vlv_psr_enable_sink(intel_dp);
+
+		/* On HSW+ enable_source also means go to PSR entry/active
+		 * state as soon as idle_frame achieved and here would be
+		 * to soon. However on VLV enable_source just enable PSR
+		 * but let it on inactive state. So we might do this prior
+		 * to active transition, i.e. here.
+		 */
+		vlv_psr_enable_source(intel_dp);
+	}
+
+	/*
+	 * FIXME: Activation should happen immediately since this function
+	 * is just called after pipe is fully trained and enabled.
+	 * However on every platform we face issues when first activation
+	 * follows a modeset so quickly.
+	 *     - On VLV/CHV we get bank screen on first activation
+	 *     - On HSW/BDW we get a recoverable frozen screen until next
+	 *       exit-activate sequence.
+	 */
+	if (INTEL_INFO(dev)->gen < 9)
+		schedule_delayed_work(&dev_priv->psr.work,
+				      msecs_to_jiffies(intel_dp->panel_power_cycle_delay * 5));
+
+	dev_priv->psr.enabled = intel_dp;
+unlock:
+	mutex_unlock(&dev_priv->psr.lock);
+}
+
+static void vlv_psr_disable(struct intel_dp *intel_dp)
+{
+	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
+	struct drm_device *dev = intel_dig_port->base.base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_crtc *intel_crtc =
+		to_intel_crtc(intel_dig_port->base.base.crtc);
+	uint32_t val;
+
+	if (dev_priv->psr.active) {
+		/* Put VLV PSR back to PSR_state 0 that is PSR Disabled. */
+		if (wait_for((I915_READ(VLV_PSRSTAT(intel_crtc->pipe)) &
+			      VLV_EDP_PSR_IN_TRANS) == 0, 1))
+			WARN(1, "PSR transition took longer than expected\n");
+
+		val = I915_READ(VLV_PSRCTL(intel_crtc->pipe));
+		val &= ~VLV_EDP_PSR_ACTIVE_ENTRY;
+		val &= ~VLV_EDP_PSR_ENABLE;
+		val &= ~VLV_EDP_PSR_MODE_MASK;
+		I915_WRITE(VLV_PSRCTL(intel_crtc->pipe), val);
+
+		dev_priv->psr.active = false;
+	} else {
+		WARN_ON(vlv_is_psr_active_on_pipe(dev, intel_crtc->pipe));
+	}
+}
+
+static void hsw_psr_disable(struct intel_dp *intel_dp)
+{
+	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
+	struct drm_device *dev = intel_dig_port->base.base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	if (dev_priv->psr.active) {
+		I915_WRITE(EDP_PSR_CTL,
+			   I915_READ(EDP_PSR_CTL) & ~EDP_PSR_ENABLE);
+
+		/* Wait till PSR is idle */
+		if (_wait_for((I915_READ(EDP_PSR_STATUS_CTL) &
+			       EDP_PSR_STATUS_STATE_MASK) == 0,
+			       2 * USEC_PER_SEC, 10 * USEC_PER_MSEC))
+			DRM_ERROR("Timed out waiting for PSR Idle State\n");
+
+		dev_priv->psr.active = false;
+	} else {
+		WARN_ON(I915_READ(EDP_PSR_CTL) & EDP_PSR_ENABLE);
+	}
+}
+
+/**
+ * intel_psr_disable - Disable PSR
+ * @intel_dp: Intel DP
+ *
+ * This function needs to be called before disabling pipe.
+ */
+void intel_psr_disable(struct intel_dp *intel_dp)
+{
+	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
+	struct drm_device *dev = intel_dig_port->base.base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	mutex_lock(&dev_priv->psr.lock);
+	if (!dev_priv->psr.enabled) {
+		mutex_unlock(&dev_priv->psr.lock);
+		return;
+	}
+
+	/* Disable PSR on Source */
+	if (HAS_DDI(dev))
+		hsw_psr_disable(intel_dp);
+	else
+		vlv_psr_disable(intel_dp);
+
+	/* Disable PSR on Sink */
+	drm_dp_dpcd_writeb(&intel_dp->aux, DP_PSR_EN_CFG, 0);
+
+	dev_priv->psr.enabled = NULL;
+	mutex_unlock(&dev_priv->psr.lock);
+
+	cancel_delayed_work_sync(&dev_priv->psr.work);
+}
+
+static void intel_psr_work(struct work_struct *work)
+{
+	struct drm_i915_private *dev_priv =
+		container_of(work, typeof(*dev_priv), psr.work.work);
+	struct intel_dp *intel_dp = dev_priv->psr.enabled;
+	struct drm_crtc *crtc = dp_to_dig_port(intel_dp)->base.base.crtc;
+	enum pipe pipe = to_intel_crtc(crtc)->pipe;
+
+	/* We have to make sure PSR is ready for re-enable
+	 * otherwise it keeps disabled until next full enable/disable cycle.
+	 * PSR might take some time to get fully disabled
+	 * and be ready for re-enable.
+	 */
+	if (HAS_DDI(dev_priv)) {
+		if (wait_for((I915_READ(EDP_PSR_STATUS_CTL) &
+			      EDP_PSR_STATUS_STATE_MASK) == 0, 50)) {
+			DRM_ERROR("Timed out waiting for PSR Idle for re-enable\n");
+			return;
+		}
+	} else {
+		if (wait_for((I915_READ(VLV_PSRSTAT(pipe)) &
+			      VLV_EDP_PSR_IN_TRANS) == 0, 1)) {
+			DRM_ERROR("Timed out waiting for PSR Idle for re-enable\n");
+			return;
+		}
+	}
+	mutex_lock(&dev_priv->psr.lock);
+	intel_dp = dev_priv->psr.enabled;
+
+	if (!intel_dp)
+		goto unlock;
+
+	/*
+	 * The delayed work can race with an invalidate hence we need to
+	 * recheck. Since psr_flush first clears this and then reschedules we
+	 * won't ever miss a flush when bailing out here.
+	 */
+	if (dev_priv->psr.busy_frontbuffer_bits)
+		goto unlock;
+
+	intel_psr_activate(intel_dp);
+unlock:
+	mutex_unlock(&dev_priv->psr.lock);
+}
+
+static void intel_psr_exit(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_dp *intel_dp = dev_priv->psr.enabled;
+	struct drm_crtc *crtc = dp_to_dig_port(intel_dp)->base.base.crtc;
+	enum pipe pipe = to_intel_crtc(crtc)->pipe;
+	u32 val;
+
+	if (!dev_priv->psr.active)
+		return;
+
+	if (HAS_DDI(dev)) {
+		val = I915_READ(EDP_PSR_CTL);
+
+		WARN_ON(!(val & EDP_PSR_ENABLE));
+
+		I915_WRITE(EDP_PSR_CTL, val & ~EDP_PSR_ENABLE);
+	} else {
+		val = I915_READ(VLV_PSRCTL(pipe));
+
+		/* Here we do the transition from PSR_state 3 to PSR_state 5
+		 * directly once PSR State 4 that is active with single frame
+		 * update can be skipped. PSR_state 5 that is PSR exit then
+		 * Hardware is responsible to transition back to PSR_state 1
+		 * that is PSR inactive. Same state after
+		 * vlv_edp_psr_enable_source.
+		 */
+		val &= ~VLV_EDP_PSR_ACTIVE_ENTRY;
+		I915_WRITE(VLV_PSRCTL(pipe), val);
+
+		/* Send AUX wake up - Spec says after transitioning to PSR
+		 * active we have to send AUX wake up by writing 01h in DPCD
+		 * 600h of sink device.
+		 * XXX: This might slow down the transition, but without this
+		 * HW doesn't complete the transition to PSR_state 1 and we
+		 * never get the screen updated.
+		 */
+		drm_dp_dpcd_writeb(&intel_dp->aux, DP_SET_POWER,
+				   DP_SET_POWER_D0);
+	}
+
+	dev_priv->psr.active = false;
+}
+
+/**
+ * intel_psr_single_frame_update - Single Frame Update
+ * @dev: DRM device
+ * @frontbuffer_bits: frontbuffer plane tracking bits
+ *
+ * Some platforms support a single frame update feature that is used to
+ * send and update only one frame on Remote Frame Buffer.
+ * So far it is only implemented for Valleyview and Cherryview because
+ * hardware requires this to be done before a page flip.
+ */
+void intel_psr_single_frame_update(struct drm_device *dev,
+				   unsigned frontbuffer_bits)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct drm_crtc *crtc;
+	enum pipe pipe;
+	u32 val;
+
+	/*
+	 * Single frame update is already supported on BDW+ but it requires
+	 * many W/A and it isn't really needed.
+	 */
+	if (!IS_VALLEYVIEW(dev) && !IS_CHERRYVIEW(dev))
+		return;
+
+	mutex_lock(&dev_priv->psr.lock);
+	if (!dev_priv->psr.enabled) {
+		mutex_unlock(&dev_priv->psr.lock);
+		return;
+	}
+
+	crtc = dp_to_dig_port(dev_priv->psr.enabled)->base.base.crtc;
+	pipe = to_intel_crtc(crtc)->pipe;
+
+	if (frontbuffer_bits & INTEL_FRONTBUFFER_ALL_MASK(pipe)) {
+		val = I915_READ(VLV_PSRCTL(pipe));
+
+		/*
+		 * We need to set this bit before writing registers for a flip.
+		 * This bit will be self-clear when it gets to the PSR active state.
+		 */
+		I915_WRITE(VLV_PSRCTL(pipe), val | VLV_EDP_PSR_SINGLE_FRAME_UPDATE);
+	}
+	mutex_unlock(&dev_priv->psr.lock);
+}
+
+/**
+ * intel_psr_invalidate - Invalidade PSR
+ * @dev: DRM device
+ * @frontbuffer_bits: frontbuffer plane tracking bits
+ *
+ * Since the hardware frontbuffer tracking has gaps we need to integrate
+ * with the software frontbuffer tracking. This function gets called every
+ * time frontbuffer rendering starts and a buffer gets dirtied. PSR must be
+ * disabled if the frontbuffer mask contains a buffer relevant to PSR.
+ *
+ * Dirty frontbuffers relevant to PSR are tracked in busy_frontbuffer_bits."
+ */
+void intel_psr_invalidate(struct drm_device *dev,
+			  unsigned frontbuffer_bits)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct drm_crtc *crtc;
+	enum pipe pipe;
+
+	mutex_lock(&dev_priv->psr.lock);
+	if (!dev_priv->psr.enabled) {
+		mutex_unlock(&dev_priv->psr.lock);
+		return;
+	}
+
+	crtc = dp_to_dig_port(dev_priv->psr.enabled)->base.base.crtc;
+	pipe = to_intel_crtc(crtc)->pipe;
+
+	frontbuffer_bits &= INTEL_FRONTBUFFER_ALL_MASK(pipe);
+	dev_priv->psr.busy_frontbuffer_bits |= frontbuffer_bits;
+
+	if (frontbuffer_bits)
+		intel_psr_exit(dev);
+
+	mutex_unlock(&dev_priv->psr.lock);
+}
+
+/**
+ * intel_psr_flush - Flush PSR
+ * @dev: DRM device
+ * @frontbuffer_bits: frontbuffer plane tracking bits
+ * @origin: which operation caused the flush
+ *
+ * Since the hardware frontbuffer tracking has gaps we need to integrate
+ * with the software frontbuffer tracking. This function gets called every
+ * time frontbuffer rendering has completed and flushed out to memory. PSR
+ * can be enabled again if no other frontbuffer relevant to PSR is dirty.
+ *
+ * Dirty frontbuffers relevant to PSR are tracked in busy_frontbuffer_bits.
+ */
+void intel_psr_flush(struct drm_device *dev,
+		     unsigned frontbuffer_bits, enum fb_op_origin origin)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct drm_crtc *crtc;
+	enum pipe pipe;
+
+	mutex_lock(&dev_priv->psr.lock);
+	if (!dev_priv->psr.enabled) {
+		mutex_unlock(&dev_priv->psr.lock);
+		return;
+	}
+
+	crtc = dp_to_dig_port(dev_priv->psr.enabled)->base.base.crtc;
+	pipe = to_intel_crtc(crtc)->pipe;
+
+	frontbuffer_bits &= INTEL_FRONTBUFFER_ALL_MASK(pipe);
+	dev_priv->psr.busy_frontbuffer_bits &= ~frontbuffer_bits;
+
+	/* By definition flush = invalidate + flush */
+	if (frontbuffer_bits)
+		intel_psr_exit(dev);
+
+	if (!dev_priv->psr.active && !dev_priv->psr.busy_frontbuffer_bits)
+		if (!work_busy(&dev_priv->psr.work.work))
+			schedule_delayed_work(&dev_priv->psr.work,
+					      msecs_to_jiffies(100));
+	mutex_unlock(&dev_priv->psr.lock);
+}
+
+/**
+ * intel_psr_init - Init basic PSR work and mutex.
+ * @dev: DRM device
+ *
+ * This function is  called only once at driver load to initialize basic
+ * PSR stuff.
+ */
+void intel_psr_init(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	dev_priv->psr_mmio_base = IS_HASWELL(dev_priv) ?
+		HSW_EDP_PSR_BASE : BDW_EDP_PSR_BASE;
+
+	/* Per platform default */
+	if (i915.enable_psr == -1) {
+		if (IS_HASWELL(dev) || IS_BROADWELL(dev))
+			i915.enable_psr = 1;
+		else
+			i915.enable_psr = 0;
+	}
+
+	/* Set link_standby x link_off defaults */
+	if (IS_HASWELL(dev) || IS_BROADWELL(dev))
+		/* HSW and BDW require workarounds that we don't implement. */
+		dev_priv->psr.link_standby = false;
+	else if (IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev))
+		/* On VLV and CHV only standby mode is supported. */
+		dev_priv->psr.link_standby = true;
+	else
+		/* For new platforms let's respect VBT back again */
+		dev_priv->psr.link_standby = dev_priv->vbt.psr.full_link;
+
+	/* Override link_standby x link_off defaults */
+	if (i915.enable_psr == 2 && !dev_priv->psr.link_standby) {
+		DRM_DEBUG_KMS("PSR: Forcing link standby\n");
+		dev_priv->psr.link_standby = true;
+	}
+	if (i915.enable_psr == 3 && dev_priv->psr.link_standby) {
+		DRM_DEBUG_KMS("PSR: Forcing main link off\n");
+		dev_priv->psr.link_standby = false;
+	}
+
+	INIT_DELAYED_WORK(&dev_priv->psr.work, intel_psr_work);
+	mutex_init(&dev_priv->psr.lock);
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/i915/intel_renderstate.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright © 2014 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef _INTEL_RENDERSTATE_H
+#define _INTEL_RENDERSTATE_H
+
+#include "i915_drv.h"
+
+extern const struct intel_renderstate_rodata gen6_null_state;
+extern const struct intel_renderstate_rodata gen7_null_state;
+extern const struct intel_renderstate_rodata gen8_null_state;
+extern const struct intel_renderstate_rodata gen9_null_state;
+
+#define RO_RENDERSTATE(_g)						\
+	const struct intel_renderstate_rodata gen ## _g ## _null_state = { \
+		.reloc = gen ## _g ## _null_state_relocs,		\
+		.batch = gen ## _g ## _null_state_batch,		\
+		.batch_items = sizeof(gen ## _g ## _null_state_batch)/4, \
+	}
+
+#endif /* INTEL_RENDERSTATE_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/i915/intel_renderstate_gen6.c
@@ -0,0 +1,315 @@
+/*
+ * Copyright © 2014 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Generated by: intel-gpu-tools-1.8-220-g01153e7
+ */
+
+#include "intel_renderstate.h"
+
+static const u32 gen6_null_state_relocs[] = {
+	0x00000020,
+	0x00000024,
+	0x0000002c,
+	0x000001e0,
+	0x000001e4,
+	-1,
+};
+
+static const u32 gen6_null_state_batch[] = {
+	0x69040000,
+	0x790d0001,
+	0x00000000,
+	0x00000000,
+	0x78180000,
+	0x00000001,
+	0x61010008,
+	0x00000000,
+	0x00000001,	 /* reloc */
+	0x00000001,	 /* reloc */
+	0x00000000,
+	0x00000001,	 /* reloc */
+	0x00000000,
+	0x00000001,
+	0x00000000,
+	0x00000001,
+	0x61020000,
+	0x00000000,
+	0x78050001,
+	0x00000018,
+	0x00000000,
+	0x780d1002,
+	0x00000000,
+	0x00000000,
+	0x00000420,
+	0x78150003,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x78100004,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x78160003,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x78110005,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x78120002,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x78170003,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x79050005,
+	0xe0040000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x79100000,
+	0x00000000,
+	0x79000002,
+	0xffffffff,
+	0x00000000,
+	0x00000000,
+	0x780e0002,
+	0x00000441,
+	0x00000401,
+	0x00000401,
+	0x78021002,
+	0x00000000,
+	0x00000000,
+	0x00000400,
+	0x78130012,
+	0x00400810,
+	0x00000000,
+	0x20000000,
+	0x04000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x78140007,
+	0x00000280,
+	0x08080000,
+	0x00000000,
+	0x00060000,
+	0x4e080002,
+	0x00100400,
+	0x00000000,
+	0x00000000,
+	0x78090005,
+	0x02000000,
+	0x22220000,
+	0x02f60000,
+	0x11330000,
+	0x02850004,
+	0x11220000,
+	0x78011002,
+	0x00000000,
+	0x00000000,
+	0x00000200,
+	0x78080003,
+	0x00002000,
+	0x00000448,	 /* reloc */
+	0x00000448,	 /* reloc */
+	0x00000000,
+	0x05000000,	 /* cmds end */
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000220,	 /* state start */
+	0x00000240,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x0060005a,
+	0x204077be,
+	0x000000c0,
+	0x008d0040,
+	0x0060005a,
+	0x206077be,
+	0x000000c0,
+	0x008d0080,
+	0x0060005a,
+	0x208077be,
+	0x000000d0,
+	0x008d0040,
+	0x0060005a,
+	0x20a077be,
+	0x000000d0,
+	0x008d0080,
+	0x00000201,
+	0x20080061,
+	0x00000000,
+	0x00000000,
+	0x00600001,
+	0x20200022,
+	0x008d0000,
+	0x00000000,
+	0x02800031,
+	0x21c01cc9,
+	0x00000020,
+	0x0a8a0001,
+	0x00600001,
+	0x204003be,
+	0x008d01c0,
+	0x00000000,
+	0x00600001,
+	0x206003be,
+	0x008d01e0,
+	0x00000000,
+	0x00600001,
+	0x208003be,
+	0x008d0200,
+	0x00000000,
+	0x00600001,
+	0x20a003be,
+	0x008d0220,
+	0x00000000,
+	0x00600001,
+	0x20c003be,
+	0x008d0240,
+	0x00000000,
+	0x00600001,
+	0x20e003be,
+	0x008d0260,
+	0x00000000,
+	0x00600001,
+	0x210003be,
+	0x008d0280,
+	0x00000000,
+	0x00600001,
+	0x212003be,
+	0x008d02a0,
+	0x00000000,
+	0x05800031,
+	0x24001cc8,
+	0x00000040,
+	0x90019000,
+	0x0000007e,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x0000007e,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x0000007e,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x0000007e,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x0000007e,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x0000007e,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x0000007e,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x0000007e,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x30000000,
+	0x00000124,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0xf99a130c,
+	0x799a130c,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x80000031,
+	0x00000003,
+	0x00000000,	 /* state end */
+};
+
+RO_RENDERSTATE(6);
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/i915/intel_renderstate_gen7.c
@@ -0,0 +1,279 @@
+/*
+ * Copyright © 2014 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Generated by: intel-gpu-tools-1.8-220-g01153e7
+ */
+
+#include "intel_renderstate.h"
+
+static const u32 gen7_null_state_relocs[] = {
+	0x0000000c,
+	0x00000010,
+	0x00000018,
+	0x000001ec,
+	-1,
+};
+
+static const u32 gen7_null_state_batch[] = {
+	0x69040000,
+	0x61010008,
+	0x00000000,
+	0x00000001,	 /* reloc */
+	0x00000001,	 /* reloc */
+	0x00000000,
+	0x00000001,	 /* reloc */
+	0x00000000,
+	0x00000001,
+	0x00000000,
+	0x00000001,
+	0x790d0002,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x78180000,
+	0x00000001,
+	0x79160000,
+	0x00000008,
+	0x78300000,
+	0x02010040,
+	0x78310000,
+	0x04000000,
+	0x78320000,
+	0x04000000,
+	0x78330000,
+	0x02000000,
+	0x78100004,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x781b0005,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x781c0002,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x781d0004,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x78110005,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x78120002,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x78210000,
+	0x00000000,
+	0x78130005,
+	0x00000000,
+	0x20000000,
+	0x04000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x78140001,
+	0x20000800,
+	0x00000000,
+	0x781e0001,
+	0x00000000,
+	0x00000000,
+	0x78050005,
+	0xe0040000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x78040001,
+	0x00000000,
+	0x00000000,
+	0x78240000,
+	0x00000240,
+	0x78230000,
+	0x00000260,
+	0x782f0000,
+	0x00000280,
+	0x781f000c,
+	0x00400810,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x78200006,
+	0x000002c0,
+	0x08080000,
+	0x00000000,
+	0x28000402,
+	0x00060000,
+	0x00000000,
+	0x00000000,
+	0x78090005,
+	0x02000000,
+	0x22220000,
+	0x02f60000,
+	0x11230000,
+	0x02f60004,
+	0x11230000,
+	0x78080003,
+	0x00006008,
+	0x00000340,	 /* reloc */
+	0xffffffff,
+	0x00000000,
+	0x782a0000,
+	0x00000360,
+	0x79000002,
+	0xffffffff,
+	0x00000000,
+	0x00000000,
+	0x7b000005,
+	0x0000000f,
+	0x00000003,
+	0x00000000,
+	0x00000001,
+	0x00000000,
+	0x00000000,
+	0x05000000,	 /* cmds end */
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000031,	 /* state start */
+	0x00000003,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0xf99a130c,
+	0x799a130c,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000492,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x0080005a,
+	0x2e2077bd,
+	0x000000c0,
+	0x008d0040,
+	0x0080005a,
+	0x2e6077bd,
+	0x000000d0,
+	0x008d0040,
+	0x02800031,
+	0x21801fa9,
+	0x008d0e20,
+	0x08840001,
+	0x00800001,
+	0x2e2003bd,
+	0x008d0180,
+	0x00000000,
+	0x00800001,
+	0x2e6003bd,
+	0x008d01c0,
+	0x00000000,
+	0x00800001,
+	0x2ea003bd,
+	0x008d0200,
+	0x00000000,
+	0x00800001,
+	0x2ee003bd,
+	0x008d0240,
+	0x00000000,
+	0x05800031,
+	0x20001fa8,
+	0x008d0e20,
+	0x90031000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000380,
+	0x000003a0,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,	 /* state end */
+};
+
+RO_RENDERSTATE(7);
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/i915/intel_renderstate_gen8.c
@@ -0,0 +1,983 @@
+/*
+ * Copyright © 2014 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Generated by: intel-gpu-tools-1.8-220-g01153e7
+ */
+
+#include "intel_renderstate.h"
+
+static const u32 gen8_null_state_relocs[] = {
+	0x00000798,
+	0x000007a4,
+	0x000007ac,
+	0x000007bc,
+	-1,
+};
+
+static const u32 gen8_null_state_batch[] = {
+	0x7a000004,
+	0x01000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x69040000,
+	0x78140000,
+	0x04000000,
+	0x7820000a,
+	0x00000000,
+	0x00000000,
+	0x80000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x78130002,
+	0x00000000,
+	0x00000000,
+	0x02001808,
+	0x781f0002,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x78510009,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x78100007,
+	0x00000000,
+	0x00000000,
+	0x00010000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x781b0007,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000800,
+	0x00000000,
+	0x78110008,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x781e0003,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x781d0007,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x78120002,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x78500003,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x781c0002,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x780c0000,
+	0x00000000,
+	0x78520003,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x78300000,
+	0x08010040,
+	0x78310000,
+	0x1e000000,
+	0x78320000,
+	0x1e000000,
+	0x78330000,
+	0x1e000000,
+	0x79190002,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x791a0002,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x791b0002,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x79120000,
+	0x00000000,
+	0x79130000,
+	0x00000000,
+	0x79140000,
+	0x00000000,
+	0x79150000,
+	0x00000000,
+	0x79160000,
+	0x00000000,
+	0x78150009,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x78190009,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x781a0009,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x78160009,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x78170009,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x78490001,
+	0x00000000,
+	0x00000000,
+	0x784a0000,
+	0x00000000,
+	0x784b0000,
+	0x00000004,
+	0x79170101,
+	0x00000000,
+	0x00000080,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x79180006,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x79180006,
+	0x20000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x79180006,
+	0x40000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x79180006,
+	0x60000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x6101000e,
+	0x00000001,	 /* reloc */
+	0x00000000,
+	0x00000000,
+	0x00000001,	 /* reloc */
+	0x00000000,
+	0x00000001,	 /* reloc */
+	0x00000000,
+	0x00000001,
+	0x00000000,
+	0x00000001,	 /* reloc */
+	0x00000000,
+	0x00001001,
+	0x00001001,
+	0x00000001,
+	0x00001001,
+	0x61020001,
+	0x00000000,
+	0x00000000,
+	0x79000002,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x78050006,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x79040002,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x79040002,
+	0x40000000,
+	0x00000000,
+	0x00000000,
+	0x79040002,
+	0x80000000,
+	0x00000000,
+	0x00000000,
+	0x79040002,
+	0xc0000000,
+	0x00000000,
+	0x00000000,
+	0x79080001,
+	0x00000000,
+	0x00000000,
+	0x790a0001,
+	0x00000000,
+	0x00000000,
+	0x78060003,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x78070003,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x78040001,
+	0x00000000,
+	0x00000000,
+	0x79110000,
+	0x00000000,
+	0x780d0000,
+	0x00000000,
+	0x79060000,
+	0x00000000,
+	0x7907001f,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x7902000f,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x790c000f,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x780a0003,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x78080083,
+	0x00004000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x04004000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x08004000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x0c004000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x10004000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x14004000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x18004000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x1c004000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x20004000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x24004000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x28004000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x2c004000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x30004000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x34004000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x38004000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x3c004000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x40004000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x44004000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x48004000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x4c004000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x50004000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x54004000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x58004000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x5c004000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x60004000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x64004000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x68004000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x6c004000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x70004000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x74004000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x78004000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x7c004000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x80004000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x78090043,
+	0x02000000,
+	0x22220000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x680b0001,
+	0x78260000,
+	0x00000000,
+	0x78270000,
+	0x00000000,
+	0x78280000,
+	0x00000000,
+	0x78290000,
+	0x00000000,
+	0x782a0000,
+	0x00000000,
+	0x780e0000,
+	0x00000dc1,
+	0x78240000,
+	0x00000e01,
+	0x784f0000,
+	0x80000100,
+	0x784d0000,
+	0x40000000,
+	0x782b0000,
+	0x00000000,
+	0x782c0000,
+	0x00000000,
+	0x782d0000,
+	0x00000000,
+	0x782e0000,
+	0x00000000,
+	0x782f0000,
+	0x00000000,
+	0x780f0000,
+	0x00000000,
+	0x78230000,
+	0x00000e60,
+	0x78210000,
+	0x00000e80,
+	0x7b000005,
+	0x00000004,
+	0x00000001,
+	0x00000000,
+	0x00000001,
+	0x00000000,
+	0x00000000,
+	0x05000000,	 /* cmds end */
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,	 /* state start */
+	0x00000000,
+	0x3f800000,
+	0x3f800000,
+	0x3f800000,
+	0x3f800000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,	 /* state end */
+};
+
+RO_RENDERSTATE(8);
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/i915/intel_renderstate_gen9.c
@@ -0,0 +1,999 @@
+/*
+ * Copyright © 2014 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Generated by: intel-gpu-tools-1.8-220-g01153e7
+ */
+
+#include "intel_renderstate.h"
+
+static const u32 gen9_null_state_relocs[] = {
+	0x000007a8,
+	0x000007b4,
+	0x000007bc,
+	0x000007cc,
+	-1,
+};
+
+static const u32 gen9_null_state_batch[] = {
+	0x7a000004,
+	0x01000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x69040300,
+	0x78140000,
+	0x04000000,
+	0x7820000a,
+	0x00000000,
+	0x00000000,
+	0x80000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x78130002,
+	0x00000000,
+	0x00000000,
+	0x02001808,
+	0x781f0004,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x78510009,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x78100007,
+	0x00000000,
+	0x00000000,
+	0x00010000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x781b0007,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000800,
+	0x00000000,
+	0x78110008,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x781e0003,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x781d0009,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x78120002,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x78500003,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x781c0002,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x780c0000,
+	0x00000000,
+	0x78520003,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x78300000,
+	0x08010040,
+	0x78310000,
+	0x1e000000,
+	0x78320000,
+	0x1e000000,
+	0x78330000,
+	0x1e000000,
+	0x79190002,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x791a0002,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x791b0002,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x79120000,
+	0x00000000,
+	0x79130000,
+	0x00000000,
+	0x79140000,
+	0x00000000,
+	0x79150000,
+	0x00000000,
+	0x79160000,
+	0x00000000,
+	0x78150009,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x78190009,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x781a0009,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x78160009,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x78170009,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x78490001,
+	0x00000000,
+	0x00000000,
+	0x784a0000,
+	0x00000000,
+	0x784b0000,
+	0x00000004,
+	0x79170101,
+	0x00000000,
+	0x00000080,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x79180006,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x79180006,
+	0x20000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x79180006,
+	0x40000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x79180006,
+	0x60000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x61010011,
+	0x00000001,	 /* reloc */
+	0x00000000,
+	0x00000000,
+	0x00000001,	 /* reloc */
+	0x00000000,
+	0x00000001,	 /* reloc */
+	0x00000000,
+	0x00000001,
+	0x00000000,
+	0x00000001,	 /* reloc */
+	0x00000000,
+	0x00001001,
+	0x00001001,
+	0x00000001,
+	0x00001001,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x61020001,
+	0x00000000,
+	0x00000000,
+	0x79000002,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x78050006,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x79040002,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x79040002,
+	0x40000000,
+	0x00000000,
+	0x00000000,
+	0x79040002,
+	0x80000000,
+	0x00000000,
+	0x00000000,
+	0x79040002,
+	0xc0000000,
+	0x00000000,
+	0x00000000,
+	0x79080001,
+	0x00000000,
+	0x00000000,
+	0x790a0001,
+	0x00000000,
+	0x00000000,
+	0x78060003,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x78070003,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x78040001,
+	0x00000000,
+	0x00000000,
+	0x79110000,
+	0x00000000,
+	0x780d0000,
+	0x00000000,
+	0x79060000,
+	0x00000000,
+	0x7907001f,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x7902000f,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x790c000f,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x780a0003,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x78080083,
+	0x00004000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x04004000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x08004000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x0c004000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x10004000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x14004000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x18004000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x1c004000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x20004000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x24004000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x28004000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x2c004000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x30004000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x34004000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x38004000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x3c004000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x40004000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x44004000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x48004000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x4c004000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x50004000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x54004000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x58004000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x5c004000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x60004000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x64004000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x68004000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x6c004000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x70004000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x74004000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x78004000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x7c004000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x80004000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x78090043,
+	0x02000000,
+	0x22220000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x78550003,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x680b0001,
+	0x780e0000,
+	0x00000e01,
+	0x78240000,
+	0x00000e41,
+	0x784f0000,
+	0x80000100,
+	0x784d0000,
+	0x40000000,
+	0x782b0000,
+	0x00000000,
+	0x782c0000,
+	0x00000000,
+	0x782d0000,
+	0x00000000,
+	0x782e0000,
+	0x00000000,
+	0x782f0000,
+	0x00000000,
+	0x780f0000,
+	0x00000000,
+	0x78230000,
+	0x00000ea0,
+	0x78210000,
+	0x00000ec0,
+	0x78260000,
+	0x00000000,
+	0x78270000,
+	0x00000000,
+	0x78280000,
+	0x00000000,
+	0x78290000,
+	0x00000000,
+	0x782a0000,
+	0x00000000,
+	0x7b000005,
+	0x00000004,
+	0x00000001,
+	0x00000000,
+	0x00000001,
+	0x00000000,
+	0x00000000,
+	0x05000000,	 /* cmds end */
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,	 /* state start */
+	0x00000000,
+	0x3f800000,
+	0x3f800000,
+	0x3f800000,
+	0x3f800000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,	 /* state end */
+};
+
+RO_RENDERSTATE(9);
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/i915/intel_ringbuffer.c
@@ -0,0 +1,3246 @@
+/*
+ * Copyright © 2008-2010 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Eric Anholt <eric@anholt.net>
+ *    Zou Nan hai <nanhai.zou@intel.com>
+ *    Xiang Hai hao<haihao.xiang@intel.com>
+ *
+ */
+
+#include <linux/log2.h>
+#include <drm/drmP.h>
+#include "i915_drv.h"
+#include <drm/i915_drm.h>
+#include "i915_trace.h"
+#include "intel_drv.h"
+
+int __intel_ring_space(int head, int tail, int size)
+{
+	int space = head - tail;
+	if (space <= 0)
+		space += size;
+	return space - I915_RING_FREE_SPACE;
+}
+
+void intel_ring_update_space(struct intel_ringbuffer *ringbuf)
+{
+	if (ringbuf->last_retired_head != -1) {
+		ringbuf->head = ringbuf->last_retired_head;
+		ringbuf->last_retired_head = -1;
+	}
+
+	ringbuf->space = __intel_ring_space(ringbuf->head & HEAD_ADDR,
+					    ringbuf->tail, ringbuf->size);
+}
+
+bool intel_engine_stopped(struct intel_engine_cs *engine)
+{
+	struct drm_i915_private *dev_priv = engine->dev->dev_private;
+	return dev_priv->gpu_error.stop_rings & intel_engine_flag(engine);
+}
+
+static void __intel_ring_advance(struct intel_engine_cs *engine)
+{
+	struct intel_ringbuffer *ringbuf = engine->buffer;
+	ringbuf->tail &= ringbuf->size - 1;
+	if (intel_engine_stopped(engine))
+		return;
+	engine->write_tail(engine, ringbuf->tail);
+}
+
+static int
+gen2_render_ring_flush(struct drm_i915_gem_request *req,
+		       u32	invalidate_domains,
+		       u32	flush_domains)
+{
+	struct intel_engine_cs *engine = req->engine;
+	u32 cmd;
+	int ret;
+
+	cmd = MI_FLUSH;
+	if (((invalidate_domains|flush_domains) & I915_GEM_DOMAIN_RENDER) == 0)
+		cmd |= MI_NO_WRITE_FLUSH;
+
+	if (invalidate_domains & I915_GEM_DOMAIN_SAMPLER)
+		cmd |= MI_READ_FLUSH;
+
+	ret = intel_ring_begin(req, 2);
+	if (ret)
+		return ret;
+
+	intel_ring_emit(engine, cmd);
+	intel_ring_emit(engine, MI_NOOP);
+	intel_ring_advance(engine);
+
+	return 0;
+}
+
+static int
+gen4_render_ring_flush(struct drm_i915_gem_request *req,
+		       u32	invalidate_domains,
+		       u32	flush_domains)
+{
+	struct intel_engine_cs *engine = req->engine;
+	struct drm_device *dev = engine->dev;
+	u32 cmd;
+	int ret;
+
+	/*
+	 * read/write caches:
+	 *
+	 * I915_GEM_DOMAIN_RENDER is always invalidated, but is
+	 * only flushed if MI_NO_WRITE_FLUSH is unset.  On 965, it is
+	 * also flushed at 2d versus 3d pipeline switches.
+	 *
+	 * read-only caches:
+	 *
+	 * I915_GEM_DOMAIN_SAMPLER is flushed on pre-965 if
+	 * MI_READ_FLUSH is set, and is always flushed on 965.
+	 *
+	 * I915_GEM_DOMAIN_COMMAND may not exist?
+	 *
+	 * I915_GEM_DOMAIN_INSTRUCTION, which exists on 965, is
+	 * invalidated when MI_EXE_FLUSH is set.
+	 *
+	 * I915_GEM_DOMAIN_VERTEX, which exists on 965, is
+	 * invalidated with every MI_FLUSH.
+	 *
+	 * TLBs:
+	 *
+	 * On 965, TLBs associated with I915_GEM_DOMAIN_COMMAND
+	 * and I915_GEM_DOMAIN_CPU in are invalidated at PTE write and
+	 * I915_GEM_DOMAIN_RENDER and I915_GEM_DOMAIN_SAMPLER
+	 * are flushed at any MI_FLUSH.
+	 */
+
+	cmd = MI_FLUSH | MI_NO_WRITE_FLUSH;
+	if ((invalidate_domains|flush_domains) & I915_GEM_DOMAIN_RENDER)
+		cmd &= ~MI_NO_WRITE_FLUSH;
+	if (invalidate_domains & I915_GEM_DOMAIN_INSTRUCTION)
+		cmd |= MI_EXE_FLUSH;
+
+	if (invalidate_domains & I915_GEM_DOMAIN_COMMAND &&
+	    (IS_G4X(dev) || IS_GEN5(dev)))
+		cmd |= MI_INVALIDATE_ISP;
+
+	ret = intel_ring_begin(req, 2);
+	if (ret)
+		return ret;
+
+	intel_ring_emit(engine, cmd);
+	intel_ring_emit(engine, MI_NOOP);
+	intel_ring_advance(engine);
+
+	return 0;
+}
+
+/**
+ * Emits a PIPE_CONTROL with a non-zero post-sync operation, for
+ * implementing two workarounds on gen6.  From section 1.4.7.1
+ * "PIPE_CONTROL" of the Sandy Bridge PRM volume 2 part 1:
+ *
+ * [DevSNB-C+{W/A}] Before any depth stall flush (including those
+ * produced by non-pipelined state commands), software needs to first
+ * send a PIPE_CONTROL with no bits set except Post-Sync Operation !=
+ * 0.
+ *
+ * [Dev-SNB{W/A}]: Before a PIPE_CONTROL with Write Cache Flush Enable
+ * =1, a PIPE_CONTROL with any non-zero post-sync-op is required.
+ *
+ * And the workaround for these two requires this workaround first:
+ *
+ * [Dev-SNB{W/A}]: Pipe-control with CS-stall bit set must be sent
+ * BEFORE the pipe-control with a post-sync op and no write-cache
+ * flushes.
+ *
+ * And this last workaround is tricky because of the requirements on
+ * that bit.  From section 1.4.7.2.3 "Stall" of the Sandy Bridge PRM
+ * volume 2 part 1:
+ *
+ *     "1 of the following must also be set:
+ *      - Render Target Cache Flush Enable ([12] of DW1)
+ *      - Depth Cache Flush Enable ([0] of DW1)
+ *      - Stall at Pixel Scoreboard ([1] of DW1)
+ *      - Depth Stall ([13] of DW1)
+ *      - Post-Sync Operation ([13] of DW1)
+ *      - Notify Enable ([8] of DW1)"
+ *
+ * The cache flushes require the workaround flush that triggered this
+ * one, so we can't use it.  Depth stall would trigger the same.
+ * Post-sync nonzero is what triggered this second workaround, so we
+ * can't use that one either.  Notify enable is IRQs, which aren't
+ * really our business.  That leaves only stall at scoreboard.
+ */
+static int
+intel_emit_post_sync_nonzero_flush(struct drm_i915_gem_request *req)
+{
+	struct intel_engine_cs *engine = req->engine;
+	u32 scratch_addr = engine->scratch.gtt_offset + 2 * CACHELINE_BYTES;
+	int ret;
+
+	ret = intel_ring_begin(req, 6);
+	if (ret)
+		return ret;
+
+	intel_ring_emit(engine, GFX_OP_PIPE_CONTROL(5));
+	intel_ring_emit(engine, PIPE_CONTROL_CS_STALL |
+			PIPE_CONTROL_STALL_AT_SCOREBOARD);
+	intel_ring_emit(engine, scratch_addr | PIPE_CONTROL_GLOBAL_GTT); /* address */
+	intel_ring_emit(engine, 0); /* low dword */
+	intel_ring_emit(engine, 0); /* high dword */
+	intel_ring_emit(engine, MI_NOOP);
+	intel_ring_advance(engine);
+
+	ret = intel_ring_begin(req, 6);
+	if (ret)
+		return ret;
+
+	intel_ring_emit(engine, GFX_OP_PIPE_CONTROL(5));
+	intel_ring_emit(engine, PIPE_CONTROL_QW_WRITE);
+	intel_ring_emit(engine, scratch_addr | PIPE_CONTROL_GLOBAL_GTT); /* address */
+	intel_ring_emit(engine, 0);
+	intel_ring_emit(engine, 0);
+	intel_ring_emit(engine, MI_NOOP);
+	intel_ring_advance(engine);
+
+	return 0;
+}
+
+static int
+gen6_render_ring_flush(struct drm_i915_gem_request *req,
+		       u32 invalidate_domains, u32 flush_domains)
+{
+	struct intel_engine_cs *engine = req->engine;
+	u32 flags = 0;
+	u32 scratch_addr = engine->scratch.gtt_offset + 2 * CACHELINE_BYTES;
+	int ret;
+
+	/* Force SNB workarounds for PIPE_CONTROL flushes */
+	ret = intel_emit_post_sync_nonzero_flush(req);
+	if (ret)
+		return ret;
+
+	/* Just flush everything.  Experiments have shown that reducing the
+	 * number of bits based on the write domains has little performance
+	 * impact.
+	 */
+	if (flush_domains) {
+		flags |= PIPE_CONTROL_RENDER_TARGET_CACHE_FLUSH;
+		flags |= PIPE_CONTROL_DEPTH_CACHE_FLUSH;
+		/*
+		 * Ensure that any following seqno writes only happen
+		 * when the render cache is indeed flushed.
+		 */
+		flags |= PIPE_CONTROL_CS_STALL;
+	}
+	if (invalidate_domains) {
+		flags |= PIPE_CONTROL_TLB_INVALIDATE;
+		flags |= PIPE_CONTROL_INSTRUCTION_CACHE_INVALIDATE;
+		flags |= PIPE_CONTROL_TEXTURE_CACHE_INVALIDATE;
+		flags |= PIPE_CONTROL_VF_CACHE_INVALIDATE;
+		flags |= PIPE_CONTROL_CONST_CACHE_INVALIDATE;
+		flags |= PIPE_CONTROL_STATE_CACHE_INVALIDATE;
+		/*
+		 * TLB invalidate requires a post-sync write.
+		 */
+		flags |= PIPE_CONTROL_QW_WRITE | PIPE_CONTROL_CS_STALL;
+	}
+
+	ret = intel_ring_begin(req, 4);
+	if (ret)
+		return ret;
+
+	intel_ring_emit(engine, GFX_OP_PIPE_CONTROL(4));
+	intel_ring_emit(engine, flags);
+	intel_ring_emit(engine, scratch_addr | PIPE_CONTROL_GLOBAL_GTT);
+	intel_ring_emit(engine, 0);
+	intel_ring_advance(engine);
+
+	return 0;
+}
+
+static int
+gen7_render_ring_cs_stall_wa(struct drm_i915_gem_request *req)
+{
+	struct intel_engine_cs *engine = req->engine;
+	int ret;
+
+	ret = intel_ring_begin(req, 4);
+	if (ret)
+		return ret;
+
+	intel_ring_emit(engine, GFX_OP_PIPE_CONTROL(4));
+	intel_ring_emit(engine, PIPE_CONTROL_CS_STALL |
+			      PIPE_CONTROL_STALL_AT_SCOREBOARD);
+	intel_ring_emit(engine, 0);
+	intel_ring_emit(engine, 0);
+	intel_ring_advance(engine);
+
+	return 0;
+}
+
+static int
+gen7_render_ring_flush(struct drm_i915_gem_request *req,
+		       u32 invalidate_domains, u32 flush_domains)
+{
+	struct intel_engine_cs *engine = req->engine;
+	u32 flags = 0;
+	u32 scratch_addr = engine->scratch.gtt_offset + 2 * CACHELINE_BYTES;
+	int ret;
+
+	/*
+	 * Ensure that any following seqno writes only happen when the render
+	 * cache is indeed flushed.
+	 *
+	 * Workaround: 4th PIPE_CONTROL command (except the ones with only
+	 * read-cache invalidate bits set) must have the CS_STALL bit set. We
+	 * don't try to be clever and just set it unconditionally.
+	 */
+	flags |= PIPE_CONTROL_CS_STALL;
+
+	/* Just flush everything.  Experiments have shown that reducing the
+	 * number of bits based on the write domains has little performance
+	 * impact.
+	 */
+	if (flush_domains) {
+		flags |= PIPE_CONTROL_RENDER_TARGET_CACHE_FLUSH;
+		flags |= PIPE_CONTROL_DEPTH_CACHE_FLUSH;
+		flags |= PIPE_CONTROL_DC_FLUSH_ENABLE;
+		flags |= PIPE_CONTROL_FLUSH_ENABLE;
+	}
+	if (invalidate_domains) {
+		flags |= PIPE_CONTROL_TLB_INVALIDATE;
+		flags |= PIPE_CONTROL_INSTRUCTION_CACHE_INVALIDATE;
+		flags |= PIPE_CONTROL_TEXTURE_CACHE_INVALIDATE;
+		flags |= PIPE_CONTROL_VF_CACHE_INVALIDATE;
+		flags |= PIPE_CONTROL_CONST_CACHE_INVALIDATE;
+		flags |= PIPE_CONTROL_STATE_CACHE_INVALIDATE;
+		flags |= PIPE_CONTROL_MEDIA_STATE_CLEAR;
+		/*
+		 * TLB invalidate requires a post-sync write.
+		 */
+		flags |= PIPE_CONTROL_QW_WRITE;
+		flags |= PIPE_CONTROL_GLOBAL_GTT_IVB;
+
+		flags |= PIPE_CONTROL_STALL_AT_SCOREBOARD;
+
+		/* Workaround: we must issue a pipe_control with CS-stall bit
+		 * set before a pipe_control command that has the state cache
+		 * invalidate bit set. */
+		gen7_render_ring_cs_stall_wa(req);
+	}
+
+	ret = intel_ring_begin(req, 4);
+	if (ret)
+		return ret;
+
+	intel_ring_emit(engine, GFX_OP_PIPE_CONTROL(4));
+	intel_ring_emit(engine, flags);
+	intel_ring_emit(engine, scratch_addr);
+	intel_ring_emit(engine, 0);
+	intel_ring_advance(engine);
+
+	return 0;
+}
+
+static int
+gen8_emit_pipe_control(struct drm_i915_gem_request *req,
+		       u32 flags, u32 scratch_addr)
+{
+	struct intel_engine_cs *engine = req->engine;
+	int ret;
+
+	ret = intel_ring_begin(req, 6);
+	if (ret)
+		return ret;
+
+	intel_ring_emit(engine, GFX_OP_PIPE_CONTROL(6));
+	intel_ring_emit(engine, flags);
+	intel_ring_emit(engine, scratch_addr);
+	intel_ring_emit(engine, 0);
+	intel_ring_emit(engine, 0);
+	intel_ring_emit(engine, 0);
+	intel_ring_advance(engine);
+
+	return 0;
+}
+
+static int
+gen8_render_ring_flush(struct drm_i915_gem_request *req,
+		       u32 invalidate_domains, u32 flush_domains)
+{
+	u32 flags = 0;
+	u32 scratch_addr = req->engine->scratch.gtt_offset + 2 * CACHELINE_BYTES;
+	int ret;
+
+	flags |= PIPE_CONTROL_CS_STALL;
+
+	if (flush_domains) {
+		flags |= PIPE_CONTROL_RENDER_TARGET_CACHE_FLUSH;
+		flags |= PIPE_CONTROL_DEPTH_CACHE_FLUSH;
+		flags |= PIPE_CONTROL_DC_FLUSH_ENABLE;
+		flags |= PIPE_CONTROL_FLUSH_ENABLE;
+	}
+	if (invalidate_domains) {
+		flags |= PIPE_CONTROL_TLB_INVALIDATE;
+		flags |= PIPE_CONTROL_INSTRUCTION_CACHE_INVALIDATE;
+		flags |= PIPE_CONTROL_TEXTURE_CACHE_INVALIDATE;
+		flags |= PIPE_CONTROL_VF_CACHE_INVALIDATE;
+		flags |= PIPE_CONTROL_CONST_CACHE_INVALIDATE;
+		flags |= PIPE_CONTROL_STATE_CACHE_INVALIDATE;
+		flags |= PIPE_CONTROL_QW_WRITE;
+		flags |= PIPE_CONTROL_GLOBAL_GTT_IVB;
+
+		/* WaCsStallBeforeStateCacheInvalidate:bdw,chv */
+		ret = gen8_emit_pipe_control(req,
+					     PIPE_CONTROL_CS_STALL |
+					     PIPE_CONTROL_STALL_AT_SCOREBOARD,
+					     0);
+		if (ret)
+			return ret;
+	}
+
+	return gen8_emit_pipe_control(req, flags, scratch_addr);
+}
+
+static void ring_write_tail(struct intel_engine_cs *engine,
+			    u32 value)
+{
+	struct drm_i915_private *dev_priv = engine->dev->dev_private;
+	I915_WRITE_TAIL(engine, value);
+}
+
+u64 intel_ring_get_active_head(struct intel_engine_cs *engine)
+{
+	struct drm_i915_private *dev_priv = engine->dev->dev_private;
+	u64 acthd;
+
+	if (INTEL_INFO(engine->dev)->gen >= 8)
+		acthd = I915_READ64_2x32(RING_ACTHD(engine->mmio_base),
+					 RING_ACTHD_UDW(engine->mmio_base));
+	else if (INTEL_INFO(engine->dev)->gen >= 4)
+		acthd = I915_READ(RING_ACTHD(engine->mmio_base));
+	else
+		acthd = I915_READ(ACTHD);
+
+	return acthd;
+}
+
+static void ring_setup_phys_status_page(struct intel_engine_cs *engine)
+{
+	struct drm_i915_private *dev_priv = engine->dev->dev_private;
+	u32 addr;
+
+	addr = dev_priv->status_page_dmah->busaddr;
+	if (INTEL_INFO(engine->dev)->gen >= 4)
+		addr |= (dev_priv->status_page_dmah->busaddr >> 28) & 0xf0;
+	I915_WRITE(HWS_PGA, addr);
+}
+
+static void intel_ring_setup_status_page(struct intel_engine_cs *engine)
+{
+	struct drm_device *dev = engine->dev;
+	struct drm_i915_private *dev_priv = engine->dev->dev_private;
+	i915_reg_t mmio;
+
+	/* The ring status page addresses are no longer next to the rest of
+	 * the ring registers as of gen7.
+	 */
+	if (IS_GEN7(dev)) {
+		switch (engine->id) {
+		case RCS:
+			mmio = RENDER_HWS_PGA_GEN7;
+			break;
+		case BCS:
+			mmio = BLT_HWS_PGA_GEN7;
+			break;
+		/*
+		 * VCS2 actually doesn't exist on Gen7. Only shut up
+		 * gcc switch check warning
+		 */
+		case VCS2:
+		case VCS:
+			mmio = BSD_HWS_PGA_GEN7;
+			break;
+		case VECS:
+			mmio = VEBOX_HWS_PGA_GEN7;
+			break;
+		}
+	} else if (IS_GEN6(engine->dev)) {
+		mmio = RING_HWS_PGA_GEN6(engine->mmio_base);
+	} else {
+		/* XXX: gen8 returns to sanity */
+		mmio = RING_HWS_PGA(engine->mmio_base);
+	}
+
+	I915_WRITE(mmio, (u32)engine->status_page.gfx_addr);
+	POSTING_READ(mmio);
+
+	/*
+	 * Flush the TLB for this page
+	 *
+	 * FIXME: These two bits have disappeared on gen8, so a question
+	 * arises: do we still need this and if so how should we go about
+	 * invalidating the TLB?
+	 */
+	if (INTEL_INFO(dev)->gen >= 6 && INTEL_INFO(dev)->gen < 8) {
+		i915_reg_t reg = RING_INSTPM(engine->mmio_base);
+
+		/* ring should be idle before issuing a sync flush*/
+		WARN_ON((I915_READ_MODE(engine) & MODE_IDLE) == 0);
+
+		I915_WRITE(reg,
+			   _MASKED_BIT_ENABLE(INSTPM_TLB_INVALIDATE |
+					      INSTPM_SYNC_FLUSH));
+		if (wait_for((I915_READ(reg) & INSTPM_SYNC_FLUSH) == 0,
+			     1000))
+			DRM_ERROR("%s: wait for SyncFlush to complete for TLB invalidation timed out\n",
+				  engine->name);
+	}
+}
+
+static bool stop_ring(struct intel_engine_cs *engine)
+{
+	struct drm_i915_private *dev_priv = to_i915(engine->dev);
+
+	if (!IS_GEN2(engine->dev)) {
+		I915_WRITE_MODE(engine, _MASKED_BIT_ENABLE(STOP_RING));
+		if (wait_for((I915_READ_MODE(engine) & MODE_IDLE) != 0, 1000)) {
+			DRM_ERROR("%s : timed out trying to stop ring\n",
+				  engine->name);
+			/* Sometimes we observe that the idle flag is not
+			 * set even though the ring is empty. So double
+			 * check before giving up.
+			 */
+			if (I915_READ_HEAD(engine) != I915_READ_TAIL(engine))
+				return false;
+		}
+	}
+
+	I915_WRITE_CTL(engine, 0);
+	I915_WRITE_HEAD(engine, 0);
+	engine->write_tail(engine, 0);
+
+	if (!IS_GEN2(engine->dev)) {
+		(void)I915_READ_CTL(engine);
+		I915_WRITE_MODE(engine, _MASKED_BIT_DISABLE(STOP_RING));
+	}
+
+	return (I915_READ_HEAD(engine) & HEAD_ADDR) == 0;
+}
+
+void intel_engine_init_hangcheck(struct intel_engine_cs *engine)
+{
+	memset(&engine->hangcheck, 0, sizeof(engine->hangcheck));
+}
+
+static int init_ring_common(struct intel_engine_cs *engine)
+{
+	struct drm_device *dev = engine->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_ringbuffer *ringbuf = engine->buffer;
+	struct drm_i915_gem_object *obj = ringbuf->obj;
+	int ret = 0;
+
+	intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL);
+
+	if (!stop_ring(engine)) {
+		/* G45 ring initialization often fails to reset head to zero */
+		DRM_DEBUG_KMS("%s head not reset to zero "
+			      "ctl %08x head %08x tail %08x start %08x\n",
+			      engine->name,
+			      I915_READ_CTL(engine),
+			      I915_READ_HEAD(engine),
+			      I915_READ_TAIL(engine),
+			      I915_READ_START(engine));
+
+		if (!stop_ring(engine)) {
+			DRM_ERROR("failed to set %s head to zero "
+				  "ctl %08x head %08x tail %08x start %08x\n",
+				  engine->name,
+				  I915_READ_CTL(engine),
+				  I915_READ_HEAD(engine),
+				  I915_READ_TAIL(engine),
+				  I915_READ_START(engine));
+			ret = -EIO;
+			goto out;
+		}
+	}
+
+	if (I915_NEED_GFX_HWS(dev))
+		intel_ring_setup_status_page(engine);
+	else
+		ring_setup_phys_status_page(engine);
+
+	/* Enforce ordering by reading HEAD register back */
+	I915_READ_HEAD(engine);
+
+	/* Initialize the ring. This must happen _after_ we've cleared the ring
+	 * registers with the above sequence (the readback of the HEAD registers
+	 * also enforces ordering), otherwise the hw might lose the new ring
+	 * register values. */
+	I915_WRITE_START(engine, i915_gem_obj_ggtt_offset(obj));
+
+	/* WaClearRingBufHeadRegAtInit:ctg,elk */
+	if (I915_READ_HEAD(engine))
+		DRM_DEBUG("%s initialization failed [head=%08x], fudging\n",
+			  engine->name, I915_READ_HEAD(engine));
+	I915_WRITE_HEAD(engine, 0);
+	(void)I915_READ_HEAD(engine);
+
+	I915_WRITE_CTL(engine,
+			((ringbuf->size - PAGE_SIZE) & RING_NR_PAGES)
+			| RING_VALID);
+
+	/* If the head is still not zero, the ring is dead */
+	if (wait_for((I915_READ_CTL(engine) & RING_VALID) != 0 &&
+		     I915_READ_START(engine) == i915_gem_obj_ggtt_offset(obj) &&
+		     (I915_READ_HEAD(engine) & HEAD_ADDR) == 0, 50)) {
+		DRM_ERROR("%s initialization failed "
+			  "ctl %08x (valid? %d) head %08x tail %08x start %08x [expected %08lx]\n",
+			  engine->name,
+			  I915_READ_CTL(engine),
+			  I915_READ_CTL(engine) & RING_VALID,
+			  I915_READ_HEAD(engine), I915_READ_TAIL(engine),
+			  I915_READ_START(engine),
+			  (unsigned long)i915_gem_obj_ggtt_offset(obj));
+		ret = -EIO;
+		goto out;
+	}
+
+	ringbuf->last_retired_head = -1;
+	ringbuf->head = I915_READ_HEAD(engine);
+	ringbuf->tail = I915_READ_TAIL(engine) & TAIL_ADDR;
+	intel_ring_update_space(ringbuf);
+
+	intel_engine_init_hangcheck(engine);
+
+out:
+	intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
+
+	return ret;
+}
+
+void
+intel_fini_pipe_control(struct intel_engine_cs *engine)
+{
+	struct drm_device *dev = engine->dev;
+
+	if (engine->scratch.obj == NULL)
+		return;
+
+	if (INTEL_INFO(dev)->gen >= 5) {
+		kunmap(sg_page(engine->scratch.obj->pages->sgl));
+		i915_gem_object_ggtt_unpin(engine->scratch.obj);
+	}
+
+	drm_gem_object_unreference(&engine->scratch.obj->base);
+	engine->scratch.obj = NULL;
+}
+
+int
+intel_init_pipe_control(struct intel_engine_cs *engine)
+{
+	int ret;
+
+	WARN_ON(engine->scratch.obj);
+
+	engine->scratch.obj = i915_gem_alloc_object(engine->dev, 4096);
+	if (engine->scratch.obj == NULL) {
+		DRM_ERROR("Failed to allocate seqno page\n");
+		ret = -ENOMEM;
+		goto err;
+	}
+
+	ret = i915_gem_object_set_cache_level(engine->scratch.obj,
+					      I915_CACHE_LLC);
+	if (ret)
+		goto err_unref;
+
+	ret = i915_gem_obj_ggtt_pin(engine->scratch.obj, 4096, 0);
+	if (ret)
+		goto err_unref;
+
+	engine->scratch.gtt_offset = i915_gem_obj_ggtt_offset(engine->scratch.obj);
+	engine->scratch.cpu_page = kmap(sg_page(engine->scratch.obj->pages->sgl));
+	if (engine->scratch.cpu_page == NULL) {
+		ret = -ENOMEM;
+		goto err_unpin;
+	}
+
+	DRM_DEBUG_DRIVER("%s pipe control offset: 0x%08x\n",
+			 engine->name, engine->scratch.gtt_offset);
+	return 0;
+
+err_unpin:
+	i915_gem_object_ggtt_unpin(engine->scratch.obj);
+err_unref:
+	drm_gem_object_unreference(&engine->scratch.obj->base);
+err:
+	return ret;
+}
+
+static int intel_ring_workarounds_emit(struct drm_i915_gem_request *req)
+{
+	int ret, i;
+	struct intel_engine_cs *engine = req->engine;
+	struct drm_device *dev = engine->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct i915_workarounds *w = &dev_priv->workarounds;
+
+	if (w->count == 0)
+		return 0;
+
+	engine->gpu_caches_dirty = true;
+	ret = intel_ring_flush_all_caches(req);
+	if (ret)
+		return ret;
+
+	ret = intel_ring_begin(req, (w->count * 2 + 2));
+	if (ret)
+		return ret;
+
+	intel_ring_emit(engine, MI_LOAD_REGISTER_IMM(w->count));
+	for (i = 0; i < w->count; i++) {
+		intel_ring_emit_reg(engine, w->reg[i].addr);
+		intel_ring_emit(engine, w->reg[i].value);
+	}
+	intel_ring_emit(engine, MI_NOOP);
+
+	intel_ring_advance(engine);
+
+	engine->gpu_caches_dirty = true;
+	ret = intel_ring_flush_all_caches(req);
+	if (ret)
+		return ret;
+
+	DRM_DEBUG_DRIVER("Number of Workarounds emitted: %d\n", w->count);
+
+	return 0;
+}
+
+static int intel_rcs_ctx_init(struct drm_i915_gem_request *req)
+{
+	int ret;
+
+	ret = intel_ring_workarounds_emit(req);
+	if (ret != 0)
+		return ret;
+
+	ret = i915_gem_render_state_init(req);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static int wa_add(struct drm_i915_private *dev_priv,
+		  i915_reg_t addr,
+		  const u32 mask, const u32 val)
+{
+	const u32 idx = dev_priv->workarounds.count;
+
+	if (WARN_ON(idx >= I915_MAX_WA_REGS))
+		return -ENOSPC;
+
+	dev_priv->workarounds.reg[idx].addr = addr;
+	dev_priv->workarounds.reg[idx].value = val;
+	dev_priv->workarounds.reg[idx].mask = mask;
+
+	dev_priv->workarounds.count++;
+
+	return 0;
+}
+
+#define WA_REG(addr, mask, val) do { \
+		const int r = wa_add(dev_priv, (addr), (mask), (val)); \
+		if (r) \
+			return r; \
+	} while (0)
+
+#define WA_SET_BIT_MASKED(addr, mask) \
+	WA_REG(addr, (mask), _MASKED_BIT_ENABLE(mask))
+
+#define WA_CLR_BIT_MASKED(addr, mask) \
+	WA_REG(addr, (mask), _MASKED_BIT_DISABLE(mask))
+
+#define WA_SET_FIELD_MASKED(addr, mask, value) \
+	WA_REG(addr, mask, _MASKED_FIELD(mask, value))
+
+#define WA_SET_BIT(addr, mask) WA_REG(addr, mask, I915_READ(addr) | (mask))
+#define WA_CLR_BIT(addr, mask) WA_REG(addr, mask, I915_READ(addr) & ~(mask))
+
+#define WA_WRITE(addr, val) WA_REG(addr, 0xffffffff, val)
+
+static int wa_ring_whitelist_reg(struct intel_engine_cs *engine,
+				 i915_reg_t reg)
+{
+	struct drm_i915_private *dev_priv = engine->dev->dev_private;
+	struct i915_workarounds *wa = &dev_priv->workarounds;
+	const uint32_t index = wa->hw_whitelist_count[engine->id];
+
+	if (WARN_ON(index >= RING_MAX_NONPRIV_SLOTS))
+		return -EINVAL;
+
+	WA_WRITE(RING_FORCE_TO_NONPRIV(engine->mmio_base, index),
+		 i915_mmio_reg_offset(reg));
+	wa->hw_whitelist_count[engine->id]++;
+
+	return 0;
+}
+
+static int gen8_init_workarounds(struct intel_engine_cs *engine)
+{
+	struct drm_device *dev = engine->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	WA_SET_BIT_MASKED(INSTPM, INSTPM_FORCE_ORDERING);
+
+	/* WaDisableAsyncFlipPerfMode:bdw,chv */
+	WA_SET_BIT_MASKED(MI_MODE, ASYNC_FLIP_PERF_DISABLE);
+
+	/* WaDisablePartialInstShootdown:bdw,chv */
+	WA_SET_BIT_MASKED(GEN8_ROW_CHICKEN,
+			  PARTIAL_INSTRUCTION_SHOOTDOWN_DISABLE);
+
+	/* Use Force Non-Coherent whenever executing a 3D context. This is a
+	 * workaround for for a possible hang in the unlikely event a TLB
+	 * invalidation occurs during a PSD flush.
+	 */
+	/* WaForceEnableNonCoherent:bdw,chv */
+	/* WaHdcDisableFetchWhenMasked:bdw,chv */
+	WA_SET_BIT_MASKED(HDC_CHICKEN0,
+			  HDC_DONOT_FETCH_MEM_WHEN_MASKED |
+			  HDC_FORCE_NON_COHERENT);
+
+	/* From the Haswell PRM, Command Reference: Registers, CACHE_MODE_0:
+	 * "The Hierarchical Z RAW Stall Optimization allows non-overlapping
+	 *  polygons in the same 8x4 pixel/sample area to be processed without
+	 *  stalling waiting for the earlier ones to write to Hierarchical Z
+	 *  buffer."
+	 *
+	 * This optimization is off by default for BDW and CHV; turn it on.
+	 */
+	WA_CLR_BIT_MASKED(CACHE_MODE_0_GEN7, HIZ_RAW_STALL_OPT_DISABLE);
+
+	/* Wa4x4STCOptimizationDisable:bdw,chv */
+	WA_SET_BIT_MASKED(CACHE_MODE_1, GEN8_4x4_STC_OPTIMIZATION_DISABLE);
+
+	/*
+	 * BSpec recommends 8x4 when MSAA is used,
+	 * however in practice 16x4 seems fastest.
+	 *
+	 * Note that PS/WM thread counts depend on the WIZ hashing
+	 * disable bit, which we don't touch here, but it's good
+	 * to keep in mind (see 3DSTATE_PS and 3DSTATE_WM).
+	 */
+	WA_SET_FIELD_MASKED(GEN7_GT_MODE,
+			    GEN6_WIZ_HASHING_MASK,
+			    GEN6_WIZ_HASHING_16x4);
+
+	return 0;
+}
+
+static int bdw_init_workarounds(struct intel_engine_cs *engine)
+{
+	int ret;
+	struct drm_device *dev = engine->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	ret = gen8_init_workarounds(engine);
+	if (ret)
+		return ret;
+
+	/* WaDisableThreadStallDopClockGating:bdw (pre-production) */
+	WA_SET_BIT_MASKED(GEN8_ROW_CHICKEN, STALL_DOP_GATING_DISABLE);
+
+	/* WaDisableDopClockGating:bdw */
+	WA_SET_BIT_MASKED(GEN7_ROW_CHICKEN2,
+			  DOP_CLOCK_GATING_DISABLE);
+
+	WA_SET_BIT_MASKED(HALF_SLICE_CHICKEN3,
+			  GEN8_SAMPLER_POWER_BYPASS_DIS);
+
+	WA_SET_BIT_MASKED(HDC_CHICKEN0,
+			  /* WaForceContextSaveRestoreNonCoherent:bdw */
+			  HDC_FORCE_CONTEXT_SAVE_RESTORE_NON_COHERENT |
+			  /* WaDisableFenceDestinationToSLM:bdw (pre-prod) */
+			  (IS_BDW_GT3(dev) ? HDC_FENCE_DEST_SLM_DISABLE : 0));
+
+	return 0;
+}
+
+static int chv_init_workarounds(struct intel_engine_cs *engine)
+{
+	int ret;
+	struct drm_device *dev = engine->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	ret = gen8_init_workarounds(engine);
+	if (ret)
+		return ret;
+
+	/* WaDisableThreadStallDopClockGating:chv */
+	WA_SET_BIT_MASKED(GEN8_ROW_CHICKEN, STALL_DOP_GATING_DISABLE);
+
+	/* Improve HiZ throughput on CHV. */
+	WA_SET_BIT_MASKED(HIZ_CHICKEN, CHV_HZ_8X8_MODE_IN_1X);
+
+	return 0;
+}
+
+static int gen9_init_workarounds(struct intel_engine_cs *engine)
+{
+	struct drm_device *dev = engine->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	int ret;
+
+	/* WaConextSwitchWithConcurrentTLBInvalidate:skl,bxt,kbl */
+	I915_WRITE(GEN9_CSFE_CHICKEN1_RCS, _MASKED_BIT_ENABLE(GEN9_PREEMPT_GPGPU_SYNC_SWITCH_DISABLE));
+
+	/* WaEnableLbsSlaRetryTimerDecrement:skl,bxt,kbl */
+	I915_WRITE(BDW_SCRATCH1, I915_READ(BDW_SCRATCH1) |
+		   GEN9_LBS_SLA_RETRY_TIMER_DECREMENT_ENABLE);
+
+	/* WaDisableKillLogic:bxt,skl,kbl */
+	I915_WRITE(GAM_ECOCHK, I915_READ(GAM_ECOCHK) |
+		   ECOCHK_DIS_TLB);
+
+	/* WaClearFlowControlGpgpuContextSave:skl,bxt,kbl */
+	/* WaDisablePartialInstShootdown:skl,bxt,kbl */
+	WA_SET_BIT_MASKED(GEN8_ROW_CHICKEN,
+			  FLOW_CONTROL_ENABLE |
+			  PARTIAL_INSTRUCTION_SHOOTDOWN_DISABLE);
+
+	/* Syncing dependencies between camera and graphics:skl,bxt,kbl */
+	WA_SET_BIT_MASKED(HALF_SLICE_CHICKEN3,
+			  GEN9_DISABLE_OCL_OOB_SUPPRESS_LOGIC);
+
+	/* WaDisableDgMirrorFixInHalfSliceChicken5:skl,bxt */
+	if (IS_SKL_REVID(dev, 0, SKL_REVID_B0) ||
+	    IS_BXT_REVID(dev, 0, BXT_REVID_A1))
+		WA_CLR_BIT_MASKED(GEN9_HALF_SLICE_CHICKEN5,
+				  GEN9_DG_MIRROR_FIX_ENABLE);
+
+	/* WaSetDisablePixMaskCammingAndRhwoInCommonSliceChicken:skl,bxt */
+	if (IS_SKL_REVID(dev, 0, SKL_REVID_B0) ||
+	    IS_BXT_REVID(dev, 0, BXT_REVID_A1)) {
+		WA_SET_BIT_MASKED(GEN7_COMMON_SLICE_CHICKEN1,
+				  GEN9_RHWO_OPTIMIZATION_DISABLE);
+		/*
+		 * WA also requires GEN9_SLICE_COMMON_ECO_CHICKEN0[14:14] to be set
+		 * but we do that in per ctx batchbuffer as there is an issue
+		 * with this register not getting restored on ctx restore
+		 */
+	}
+
+	/* WaEnableYV12BugFixInHalfSliceChicken7:skl,bxt,kbl */
+	/* WaEnableSamplerGPGPUPreemptionSupport:skl,bxt,kbl */
+	WA_SET_BIT_MASKED(GEN9_HALF_SLICE_CHICKEN7,
+			  GEN9_ENABLE_YV12_BUGFIX |
+			  GEN9_ENABLE_GPGPU_PREEMPTION);
+
+	/* Wa4x4STCOptimizationDisable:skl,bxt,kbl */
+	/* WaDisablePartialResolveInVc:skl,bxt,kbl */
+	WA_SET_BIT_MASKED(CACHE_MODE_1, (GEN8_4x4_STC_OPTIMIZATION_DISABLE |
+					 GEN9_PARTIAL_RESOLVE_IN_VC_DISABLE));
+
+	/* WaCcsTlbPrefetchDisable:skl,bxt,kbl */
+	WA_CLR_BIT_MASKED(GEN9_HALF_SLICE_CHICKEN5,
+			  GEN9_CCS_TLB_PREFETCH_ENABLE);
+
+	/* WaDisableMaskBasedCammingInRCC:skl,bxt */
+	if (IS_SKL_REVID(dev, SKL_REVID_C0, SKL_REVID_C0) ||
+	    IS_BXT_REVID(dev, 0, BXT_REVID_A1))
+		WA_SET_BIT_MASKED(SLICE_ECO_CHICKEN0,
+				  PIXEL_MASK_CAMMING_DISABLE);
+
+	/* WaForceContextSaveRestoreNonCoherent:skl,bxt,kbl */
+	WA_SET_BIT_MASKED(HDC_CHICKEN0,
+			  HDC_FORCE_CONTEXT_SAVE_RESTORE_NON_COHERENT |
+			  HDC_FORCE_CSR_NON_COHERENT_OVR_DISABLE);
+
+	/* WaForceEnableNonCoherent and WaDisableHDCInvalidation are
+	 * both tied to WaForceContextSaveRestoreNonCoherent
+	 * in some hsds for skl. We keep the tie for all gen9. The
+	 * documentation is a bit hazy and so we want to get common behaviour,
+	 * even though there is no clear evidence we would need both on kbl/bxt.
+	 * This area has been source of system hangs so we play it safe
+	 * and mimic the skl regardless of what bspec says.
+	 *
+	 * Use Force Non-Coherent whenever executing a 3D context. This
+	 * is a workaround for a possible hang in the unlikely event
+	 * a TLB invalidation occurs during a PSD flush.
+	 */
+
+	/* WaForceEnableNonCoherent:skl,bxt,kbl */
+	WA_SET_BIT_MASKED(HDC_CHICKEN0,
+			  HDC_FORCE_NON_COHERENT);
+
+	/* WaDisableHDCInvalidation:skl,bxt,kbl */
+	I915_WRITE(GAM_ECOCHK, I915_READ(GAM_ECOCHK) |
+		   BDW_DISABLE_HDC_INVALIDATION);
+
+	/* WaDisableSamplerPowerBypassForSOPingPong:skl,bxt,kbl */
+	if (IS_SKYLAKE(dev_priv) ||
+	    IS_KABYLAKE(dev_priv) ||
+	    IS_BXT_REVID(dev_priv, 0, BXT_REVID_B0))
+		WA_SET_BIT_MASKED(HALF_SLICE_CHICKEN3,
+				  GEN8_SAMPLER_POWER_BYPASS_DIS);
+
+	/* WaDisableSTUnitPowerOptimization:skl,bxt,kbl */
+	WA_SET_BIT_MASKED(HALF_SLICE_CHICKEN2, GEN8_ST_PO_DISABLE);
+
+	/* WaOCLCoherentLineFlush:skl,bxt,kbl */
+	I915_WRITE(GEN8_L3SQCREG4, (I915_READ(GEN8_L3SQCREG4) |
+				    GEN8_LQSC_FLUSH_COHERENT_LINES));
+
+	/* WaVFEStateAfterPipeControlwithMediaStateClear:skl,bxt */
+	ret = wa_ring_whitelist_reg(engine, GEN9_CTX_PREEMPT_REG);
+	if (ret)
+		return ret;
+
+	/* WaEnablePreemptionGranularityControlByUMD:skl,bxt,kbl */
+	ret= wa_ring_whitelist_reg(engine, GEN8_CS_CHICKEN1);
+	if (ret)
+		return ret;
+
+	/* WaAllowUMDToModifyHDCChicken1:skl,bxt,kbl */
+	ret = wa_ring_whitelist_reg(engine, GEN8_HDC_CHICKEN1);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static int skl_tune_iz_hashing(struct intel_engine_cs *engine)
+{
+	struct drm_device *dev = engine->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	u8 vals[3] = { 0, 0, 0 };
+	unsigned int i;
+
+	for (i = 0; i < 3; i++) {
+		u8 ss;
+
+		/*
+		 * Only consider slices where one, and only one, subslice has 7
+		 * EUs
+		 */
+		if (!is_power_of_2(dev_priv->info.subslice_7eu[i]))
+			continue;
+
+		/*
+		 * subslice_7eu[i] != 0 (because of the check above) and
+		 * ss_max == 4 (maximum number of subslices possible per slice)
+		 *
+		 * ->    0 <= ss <= 3;
+		 */
+		ss = ffs(dev_priv->info.subslice_7eu[i]) - 1;
+		vals[i] = 3 - ss;
+	}
+
+	if (vals[0] == 0 && vals[1] == 0 && vals[2] == 0)
+		return 0;
+
+	/* Tune IZ hashing. See intel_device_info_runtime_init() */
+	WA_SET_FIELD_MASKED(GEN7_GT_MODE,
+			    GEN9_IZ_HASHING_MASK(2) |
+			    GEN9_IZ_HASHING_MASK(1) |
+			    GEN9_IZ_HASHING_MASK(0),
+			    GEN9_IZ_HASHING(2, vals[2]) |
+			    GEN9_IZ_HASHING(1, vals[1]) |
+			    GEN9_IZ_HASHING(0, vals[0]));
+
+	return 0;
+}
+
+static int skl_init_workarounds(struct intel_engine_cs *engine)
+{
+	int ret;
+	struct drm_device *dev = engine->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	ret = gen9_init_workarounds(engine);
+	if (ret)
+		return ret;
+
+	/*
+	 * Actual WA is to disable percontext preemption granularity control
+	 * until D0 which is the default case so this is equivalent to
+	 * !WaDisablePerCtxtPreemptionGranularityControl:skl
+	 */
+	if (IS_SKL_REVID(dev, SKL_REVID_E0, REVID_FOREVER)) {
+		I915_WRITE(GEN7_FF_SLICE_CS_CHICKEN1,
+			   _MASKED_BIT_ENABLE(GEN9_FFSC_PERCTX_PREEMPT_CTRL));
+	}
+
+	if (IS_SKL_REVID(dev_priv, 0, SKL_REVID_E0)) {
+		/* WaDisableChickenBitTSGBarrierAckForFFSliceCS:skl */
+		I915_WRITE(FF_SLICE_CS_CHICKEN2,
+			   _MASKED_BIT_ENABLE(GEN9_TSG_BARRIER_ACK_DISABLE));
+	}
+
+	/* GEN8_L3SQCREG4 has a dependency with WA batch so any new changes
+	 * involving this register should also be added to WA batch as required.
+	 */
+	if (IS_SKL_REVID(dev, 0, SKL_REVID_E0))
+		/* WaDisableLSQCROPERFforOCL:skl */
+		I915_WRITE(GEN8_L3SQCREG4, I915_READ(GEN8_L3SQCREG4) |
+			   GEN8_LQSC_RO_PERF_DIS);
+
+	/* WaEnableGapsTsvCreditFix:skl */
+	if (IS_SKL_REVID(dev, SKL_REVID_C0, REVID_FOREVER)) {
+		I915_WRITE(GEN8_GARBCNTL, (I915_READ(GEN8_GARBCNTL) |
+					   GEN9_GAPS_TSV_CREDIT_DISABLE));
+	}
+
+	/* WaDisablePowerCompilerClockGating:skl */
+	if (IS_SKL_REVID(dev, SKL_REVID_B0, SKL_REVID_B0))
+		WA_SET_BIT_MASKED(HIZ_CHICKEN,
+				  BDW_HIZ_POWER_COMPILER_CLOCK_GATING_DISABLE);
+
+	/* WaBarrierPerformanceFixDisable:skl */
+	if (IS_SKL_REVID(dev, SKL_REVID_C0, SKL_REVID_D0))
+		WA_SET_BIT_MASKED(HDC_CHICKEN0,
+				  HDC_FENCE_DEST_SLM_DISABLE |
+				  HDC_BARRIER_PERFORMANCE_DISABLE);
+
+	/* WaDisableSbeCacheDispatchPortSharing:skl */
+	if (IS_SKL_REVID(dev, 0, SKL_REVID_F0))
+		WA_SET_BIT_MASKED(
+			GEN7_HALF_SLICE_CHICKEN1,
+			GEN7_SBE_SS_CACHE_DISPATCH_PORT_SHARING_DISABLE);
+
+	/* WaDisableGafsUnitClkGating:skl */
+	WA_SET_BIT(GEN7_UCGCTL4, GEN8_EU_GAUNIT_CLOCK_GATE_DISABLE);
+
+	/* WaDisableLSQCROPERFforOCL:skl */
+	ret = wa_ring_whitelist_reg(engine, GEN8_L3SQCREG4);
+	if (ret)
+		return ret;
+
+	return skl_tune_iz_hashing(engine);
+}
+
+static int bxt_init_workarounds(struct intel_engine_cs *engine)
+{
+	int ret;
+	struct drm_device *dev = engine->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	ret = gen9_init_workarounds(engine);
+	if (ret)
+		return ret;
+
+	/* WaStoreMultiplePTEenable:bxt */
+	/* This is a requirement according to Hardware specification */
+	if (IS_BXT_REVID(dev, 0, BXT_REVID_A1))
+		I915_WRITE(TILECTL, I915_READ(TILECTL) | TILECTL_TLBPF);
+
+	/* WaSetClckGatingDisableMedia:bxt */
+	if (IS_BXT_REVID(dev, 0, BXT_REVID_A1)) {
+		I915_WRITE(GEN7_MISCCPCTL, (I915_READ(GEN7_MISCCPCTL) &
+					    ~GEN8_DOP_CLOCK_GATE_MEDIA_ENABLE));
+	}
+
+	/* WaDisableThreadStallDopClockGating:bxt */
+	WA_SET_BIT_MASKED(GEN8_ROW_CHICKEN,
+			  STALL_DOP_GATING_DISABLE);
+
+	/* WaDisableSbeCacheDispatchPortSharing:bxt */
+	if (IS_BXT_REVID(dev, 0, BXT_REVID_B0)) {
+		WA_SET_BIT_MASKED(
+			GEN7_HALF_SLICE_CHICKEN1,
+			GEN7_SBE_SS_CACHE_DISPATCH_PORT_SHARING_DISABLE);
+	}
+
+	/* WaDisableObjectLevelPreemptionForTrifanOrPolygon:bxt */
+	/* WaDisableObjectLevelPreemptionForInstancedDraw:bxt */
+	/* WaDisableObjectLevelPreemtionForInstanceId:bxt */
+	/* WaDisableLSQCROPERFforOCL:bxt */
+	if (IS_BXT_REVID(dev, 0, BXT_REVID_A1)) {
+		ret = wa_ring_whitelist_reg(engine, GEN9_CS_DEBUG_MODE1);
+		if (ret)
+			return ret;
+
+		ret = wa_ring_whitelist_reg(engine, GEN8_L3SQCREG4);
+		if (ret)
+			return ret;
+	}
+
+	/* WaInsertDummyPushConstPs:bxt */
+	if (IS_BXT_REVID(dev_priv, 0, BXT_REVID_B0))
+		WA_SET_BIT_MASKED(COMMON_SLICE_CHICKEN2,
+				  GEN8_SBE_DISABLE_REPLAY_BUF_OPTIMIZATION);
+
+	return 0;
+}
+
+static int kbl_init_workarounds(struct intel_engine_cs *engine)
+{
+	struct drm_i915_private *dev_priv = engine->dev->dev_private;
+	int ret;
+
+	ret = gen9_init_workarounds(engine);
+	if (ret)
+		return ret;
+
+	/* WaEnableGapsTsvCreditFix:kbl */
+	I915_WRITE(GEN8_GARBCNTL, (I915_READ(GEN8_GARBCNTL) |
+				   GEN9_GAPS_TSV_CREDIT_DISABLE));
+
+	/* WaDisableDynamicCreditSharing:kbl */
+	if (IS_KBL_REVID(dev_priv, 0, KBL_REVID_B0))
+		WA_SET_BIT(GAMT_CHKN_BIT_REG,
+			   GAMT_CHKN_DISABLE_DYNAMIC_CREDIT_SHARING);
+
+	/* WaDisableFenceDestinationToSLM:kbl (pre-prod) */
+	if (IS_KBL_REVID(dev_priv, KBL_REVID_A0, KBL_REVID_A0))
+		WA_SET_BIT_MASKED(HDC_CHICKEN0,
+				  HDC_FENCE_DEST_SLM_DISABLE);
+
+	/* GEN8_L3SQCREG4 has a dependency with WA batch so any new changes
+	 * involving this register should also be added to WA batch as required.
+	 */
+	if (IS_KBL_REVID(dev_priv, 0, KBL_REVID_E0))
+		/* WaDisableLSQCROPERFforOCL:kbl */
+		I915_WRITE(GEN8_L3SQCREG4, I915_READ(GEN8_L3SQCREG4) |
+			   GEN8_LQSC_RO_PERF_DIS);
+
+	/* WaInsertDummyPushConstPs:kbl */
+	if (IS_KBL_REVID(dev_priv, 0, KBL_REVID_B0))
+		WA_SET_BIT_MASKED(COMMON_SLICE_CHICKEN2,
+				  GEN8_SBE_DISABLE_REPLAY_BUF_OPTIMIZATION);
+
+	/* WaDisableGafsUnitClkGating:kbl */
+	WA_SET_BIT(GEN7_UCGCTL4, GEN8_EU_GAUNIT_CLOCK_GATE_DISABLE);
+
+	/* WaDisableSbeCacheDispatchPortSharing:kbl */
+	WA_SET_BIT_MASKED(
+		GEN7_HALF_SLICE_CHICKEN1,
+		GEN7_SBE_SS_CACHE_DISPATCH_PORT_SHARING_DISABLE);
+
+	/* WaDisableLSQCROPERFforOCL:kbl */
+	ret = wa_ring_whitelist_reg(engine, GEN8_L3SQCREG4);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+int init_workarounds_ring(struct intel_engine_cs *engine)
+{
+	struct drm_device *dev = engine->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	WARN_ON(engine->id != RCS);
+
+	dev_priv->workarounds.count = 0;
+	dev_priv->workarounds.hw_whitelist_count[RCS] = 0;
+
+	if (IS_BROADWELL(dev))
+		return bdw_init_workarounds(engine);
+
+	if (IS_CHERRYVIEW(dev))
+		return chv_init_workarounds(engine);
+
+	if (IS_SKYLAKE(dev))
+		return skl_init_workarounds(engine);
+
+	if (IS_BROXTON(dev))
+		return bxt_init_workarounds(engine);
+
+	if (IS_KABYLAKE(dev_priv))
+		return kbl_init_workarounds(engine);
+
+	return 0;
+}
+
+static int init_render_ring(struct intel_engine_cs *engine)
+{
+	struct drm_device *dev = engine->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	int ret = init_ring_common(engine);
+	if (ret)
+		return ret;
+
+	/* WaTimedSingleVertexDispatch:cl,bw,ctg,elk,ilk,snb */
+	if (INTEL_INFO(dev)->gen >= 4 && INTEL_INFO(dev)->gen < 7)
+		I915_WRITE(MI_MODE, _MASKED_BIT_ENABLE(VS_TIMER_DISPATCH));
+
+	/* We need to disable the AsyncFlip performance optimisations in order
+	 * to use MI_WAIT_FOR_EVENT within the CS. It should already be
+	 * programmed to '1' on all products.
+	 *
+	 * WaDisableAsyncFlipPerfMode:snb,ivb,hsw,vlv
+	 */
+	if (INTEL_INFO(dev)->gen >= 6 && INTEL_INFO(dev)->gen < 8)
+		I915_WRITE(MI_MODE, _MASKED_BIT_ENABLE(ASYNC_FLIP_PERF_DISABLE));
+
+	/* Required for the hardware to program scanline values for waiting */
+	/* WaEnableFlushTlbInvalidationMode:snb */
+	if (INTEL_INFO(dev)->gen == 6)
+		I915_WRITE(GFX_MODE,
+			   _MASKED_BIT_ENABLE(GFX_TLB_INVALIDATE_EXPLICIT));
+
+	/* WaBCSVCSTlbInvalidationMode:ivb,vlv,hsw */
+	if (IS_GEN7(dev))
+		I915_WRITE(GFX_MODE_GEN7,
+			   _MASKED_BIT_ENABLE(GFX_TLB_INVALIDATE_EXPLICIT) |
+			   _MASKED_BIT_ENABLE(GFX_REPLAY_MODE));
+
+	if (IS_GEN6(dev)) {
+		/* From the Sandybridge PRM, volume 1 part 3, page 24:
+		 * "If this bit is set, STCunit will have LRA as replacement
+		 *  policy. [...] This bit must be reset.  LRA replacement
+		 *  policy is not supported."
+		 */
+		I915_WRITE(CACHE_MODE_0,
+			   _MASKED_BIT_DISABLE(CM0_STC_EVICT_DISABLE_LRA_SNB));
+	}
+
+	if (INTEL_INFO(dev)->gen >= 6 && INTEL_INFO(dev)->gen < 8)
+		I915_WRITE(INSTPM, _MASKED_BIT_ENABLE(INSTPM_FORCE_ORDERING));
+
+	if (HAS_L3_DPF(dev))
+		I915_WRITE_IMR(engine, ~GT_PARITY_ERROR(dev));
+
+	return init_workarounds_ring(engine);
+}
+
+static void render_ring_cleanup(struct intel_engine_cs *engine)
+{
+	struct drm_device *dev = engine->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	if (dev_priv->semaphore_obj) {
+		i915_gem_object_ggtt_unpin(dev_priv->semaphore_obj);
+		drm_gem_object_unreference(&dev_priv->semaphore_obj->base);
+		dev_priv->semaphore_obj = NULL;
+	}
+
+	intel_fini_pipe_control(engine);
+}
+
+static int gen8_rcs_signal(struct drm_i915_gem_request *signaller_req,
+			   unsigned int num_dwords)
+{
+#define MBOX_UPDATE_DWORDS 8
+	struct intel_engine_cs *signaller = signaller_req->engine;
+	struct drm_device *dev = signaller->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_engine_cs *waiter;
+	enum intel_engine_id id;
+	int ret, num_rings;
+
+	num_rings = hweight32(INTEL_INFO(dev)->ring_mask);
+	num_dwords += (num_rings-1) * MBOX_UPDATE_DWORDS;
+#undef MBOX_UPDATE_DWORDS
+
+	ret = intel_ring_begin(signaller_req, num_dwords);
+	if (ret)
+		return ret;
+
+	for_each_engine_id(waiter, dev_priv, id) {
+		u32 seqno;
+		u64 gtt_offset = signaller->semaphore.signal_ggtt[id];
+		if (gtt_offset == MI_SEMAPHORE_SYNC_INVALID)
+			continue;
+
+		seqno = i915_gem_request_get_seqno(signaller_req);
+		intel_ring_emit(signaller, GFX_OP_PIPE_CONTROL(6));
+		intel_ring_emit(signaller, PIPE_CONTROL_GLOBAL_GTT_IVB |
+					   PIPE_CONTROL_QW_WRITE |
+					   PIPE_CONTROL_FLUSH_ENABLE);
+		intel_ring_emit(signaller, lower_32_bits(gtt_offset));
+		intel_ring_emit(signaller, upper_32_bits(gtt_offset));
+		intel_ring_emit(signaller, seqno);
+		intel_ring_emit(signaller, 0);
+		intel_ring_emit(signaller, MI_SEMAPHORE_SIGNAL |
+					   MI_SEMAPHORE_TARGET(waiter->hw_id));
+		intel_ring_emit(signaller, 0);
+	}
+
+	return 0;
+}
+
+static int gen8_xcs_signal(struct drm_i915_gem_request *signaller_req,
+			   unsigned int num_dwords)
+{
+#define MBOX_UPDATE_DWORDS 6
+	struct intel_engine_cs *signaller = signaller_req->engine;
+	struct drm_device *dev = signaller->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_engine_cs *waiter;
+	enum intel_engine_id id;
+	int ret, num_rings;
+
+	num_rings = hweight32(INTEL_INFO(dev)->ring_mask);
+	num_dwords += (num_rings-1) * MBOX_UPDATE_DWORDS;
+#undef MBOX_UPDATE_DWORDS
+
+	ret = intel_ring_begin(signaller_req, num_dwords);
+	if (ret)
+		return ret;
+
+	for_each_engine_id(waiter, dev_priv, id) {
+		u32 seqno;
+		u64 gtt_offset = signaller->semaphore.signal_ggtt[id];
+		if (gtt_offset == MI_SEMAPHORE_SYNC_INVALID)
+			continue;
+
+		seqno = i915_gem_request_get_seqno(signaller_req);
+		intel_ring_emit(signaller, (MI_FLUSH_DW + 1) |
+					   MI_FLUSH_DW_OP_STOREDW);
+		intel_ring_emit(signaller, lower_32_bits(gtt_offset) |
+					   MI_FLUSH_DW_USE_GTT);
+		intel_ring_emit(signaller, upper_32_bits(gtt_offset));
+		intel_ring_emit(signaller, seqno);
+		intel_ring_emit(signaller, MI_SEMAPHORE_SIGNAL |
+					   MI_SEMAPHORE_TARGET(waiter->hw_id));
+		intel_ring_emit(signaller, 0);
+	}
+
+	return 0;
+}
+
+static int gen6_signal(struct drm_i915_gem_request *signaller_req,
+		       unsigned int num_dwords)
+{
+	struct intel_engine_cs *signaller = signaller_req->engine;
+	struct drm_device *dev = signaller->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_engine_cs *useless;
+	enum intel_engine_id id;
+	int ret, num_rings;
+
+#define MBOX_UPDATE_DWORDS 3
+	num_rings = hweight32(INTEL_INFO(dev)->ring_mask);
+	num_dwords += round_up((num_rings-1) * MBOX_UPDATE_DWORDS, 2);
+#undef MBOX_UPDATE_DWORDS
+
+	ret = intel_ring_begin(signaller_req, num_dwords);
+	if (ret)
+		return ret;
+
+	for_each_engine_id(useless, dev_priv, id) {
+		i915_reg_t mbox_reg = signaller->semaphore.mbox.signal[id];
+
+		if (i915_mmio_reg_valid(mbox_reg)) {
+			u32 seqno = i915_gem_request_get_seqno(signaller_req);
+
+			intel_ring_emit(signaller, MI_LOAD_REGISTER_IMM(1));
+			intel_ring_emit_reg(signaller, mbox_reg);
+			intel_ring_emit(signaller, seqno);
+		}
+	}
+
+	/* If num_dwords was rounded, make sure the tail pointer is correct */
+	if (num_rings % 2 == 0)
+		intel_ring_emit(signaller, MI_NOOP);
+
+	return 0;
+}
+
+/**
+ * gen6_add_request - Update the semaphore mailbox registers
+ *
+ * @request - request to write to the ring
+ *
+ * Update the mailbox registers in the *other* rings with the current seqno.
+ * This acts like a signal in the canonical semaphore.
+ */
+static int
+gen6_add_request(struct drm_i915_gem_request *req)
+{
+	struct intel_engine_cs *engine = req->engine;
+	int ret;
+
+	if (engine->semaphore.signal)
+		ret = engine->semaphore.signal(req, 4);
+	else
+		ret = intel_ring_begin(req, 4);
+
+	if (ret)
+		return ret;
+
+	intel_ring_emit(engine, MI_STORE_DWORD_INDEX);
+	intel_ring_emit(engine,
+			I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT);
+	intel_ring_emit(engine, i915_gem_request_get_seqno(req));
+	intel_ring_emit(engine, MI_USER_INTERRUPT);
+	__intel_ring_advance(engine);
+
+	return 0;
+}
+
+static inline bool i915_gem_has_seqno_wrapped(struct drm_device *dev,
+					      u32 seqno)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	return dev_priv->last_seqno < seqno;
+}
+
+/**
+ * intel_ring_sync - sync the waiter to the signaller on seqno
+ *
+ * @waiter - ring that is waiting
+ * @signaller - ring which has, or will signal
+ * @seqno - seqno which the waiter will block on
+ */
+
+static int
+gen8_ring_sync(struct drm_i915_gem_request *waiter_req,
+	       struct intel_engine_cs *signaller,
+	       u32 seqno)
+{
+	struct intel_engine_cs *waiter = waiter_req->engine;
+	struct drm_i915_private *dev_priv = waiter->dev->dev_private;
+	int ret;
+
+	ret = intel_ring_begin(waiter_req, 4);
+	if (ret)
+		return ret;
+
+	intel_ring_emit(waiter, MI_SEMAPHORE_WAIT |
+				MI_SEMAPHORE_GLOBAL_GTT |
+				MI_SEMAPHORE_POLL |
+				MI_SEMAPHORE_SAD_GTE_SDD);
+	intel_ring_emit(waiter, seqno);
+	intel_ring_emit(waiter,
+			lower_32_bits(GEN8_WAIT_OFFSET(waiter, signaller->id)));
+	intel_ring_emit(waiter,
+			upper_32_bits(GEN8_WAIT_OFFSET(waiter, signaller->id)));
+	intel_ring_advance(waiter);
+	return 0;
+}
+
+static int
+gen6_ring_sync(struct drm_i915_gem_request *waiter_req,
+	       struct intel_engine_cs *signaller,
+	       u32 seqno)
+{
+	struct intel_engine_cs *waiter = waiter_req->engine;
+	u32 dw1 = MI_SEMAPHORE_MBOX |
+		  MI_SEMAPHORE_COMPARE |
+		  MI_SEMAPHORE_REGISTER;
+	u32 wait_mbox = signaller->semaphore.mbox.wait[waiter->id];
+	int ret;
+
+	/* Throughout all of the GEM code, seqno passed implies our current
+	 * seqno is >= the last seqno executed. However for hardware the
+	 * comparison is strictly greater than.
+	 */
+	seqno -= 1;
+
+	WARN_ON(wait_mbox == MI_SEMAPHORE_SYNC_INVALID);
+
+	ret = intel_ring_begin(waiter_req, 4);
+	if (ret)
+		return ret;
+
+	/* If seqno wrap happened, omit the wait with no-ops */
+	if (likely(!i915_gem_has_seqno_wrapped(waiter->dev, seqno))) {
+		intel_ring_emit(waiter, dw1 | wait_mbox);
+		intel_ring_emit(waiter, seqno);
+		intel_ring_emit(waiter, 0);
+		intel_ring_emit(waiter, MI_NOOP);
+	} else {
+		intel_ring_emit(waiter, MI_NOOP);
+		intel_ring_emit(waiter, MI_NOOP);
+		intel_ring_emit(waiter, MI_NOOP);
+		intel_ring_emit(waiter, MI_NOOP);
+	}
+	intel_ring_advance(waiter);
+
+	return 0;
+}
+
+#define PIPE_CONTROL_FLUSH(ring__, addr__)					\
+do {									\
+	intel_ring_emit(ring__, GFX_OP_PIPE_CONTROL(4) | PIPE_CONTROL_QW_WRITE |		\
+		 PIPE_CONTROL_DEPTH_STALL);				\
+	intel_ring_emit(ring__, (addr__) | PIPE_CONTROL_GLOBAL_GTT);			\
+	intel_ring_emit(ring__, 0);							\
+	intel_ring_emit(ring__, 0);							\
+} while (0)
+
+static int
+pc_render_add_request(struct drm_i915_gem_request *req)
+{
+	struct intel_engine_cs *engine = req->engine;
+	u32 scratch_addr = engine->scratch.gtt_offset + 2 * CACHELINE_BYTES;
+	int ret;
+
+	/* For Ironlake, MI_USER_INTERRUPT was deprecated and apparently
+	 * incoherent with writes to memory, i.e. completely fubar,
+	 * so we need to use PIPE_NOTIFY instead.
+	 *
+	 * However, we also need to workaround the qword write
+	 * incoherence by flushing the 6 PIPE_NOTIFY buffers out to
+	 * memory before requesting an interrupt.
+	 */
+	ret = intel_ring_begin(req, 32);
+	if (ret)
+		return ret;
+
+	intel_ring_emit(engine,
+			GFX_OP_PIPE_CONTROL(4) | PIPE_CONTROL_QW_WRITE |
+			PIPE_CONTROL_WRITE_FLUSH |
+			PIPE_CONTROL_TEXTURE_CACHE_INVALIDATE);
+	intel_ring_emit(engine,
+			engine->scratch.gtt_offset | PIPE_CONTROL_GLOBAL_GTT);
+	intel_ring_emit(engine, i915_gem_request_get_seqno(req));
+	intel_ring_emit(engine, 0);
+	PIPE_CONTROL_FLUSH(engine, scratch_addr);
+	scratch_addr += 2 * CACHELINE_BYTES; /* write to separate cachelines */
+	PIPE_CONTROL_FLUSH(engine, scratch_addr);
+	scratch_addr += 2 * CACHELINE_BYTES;
+	PIPE_CONTROL_FLUSH(engine, scratch_addr);
+	scratch_addr += 2 * CACHELINE_BYTES;
+	PIPE_CONTROL_FLUSH(engine, scratch_addr);
+	scratch_addr += 2 * CACHELINE_BYTES;
+	PIPE_CONTROL_FLUSH(engine, scratch_addr);
+	scratch_addr += 2 * CACHELINE_BYTES;
+	PIPE_CONTROL_FLUSH(engine, scratch_addr);
+
+	intel_ring_emit(engine,
+			GFX_OP_PIPE_CONTROL(4) | PIPE_CONTROL_QW_WRITE |
+			PIPE_CONTROL_WRITE_FLUSH |
+			PIPE_CONTROL_TEXTURE_CACHE_INVALIDATE |
+			PIPE_CONTROL_NOTIFY);
+	intel_ring_emit(engine,
+			engine->scratch.gtt_offset | PIPE_CONTROL_GLOBAL_GTT);
+	intel_ring_emit(engine, i915_gem_request_get_seqno(req));
+	intel_ring_emit(engine, 0);
+	__intel_ring_advance(engine);
+
+	return 0;
+}
+
+static void
+gen6_seqno_barrier(struct intel_engine_cs *engine)
+{
+	struct drm_i915_private *dev_priv = engine->dev->dev_private;
+
+	/* Workaround to force correct ordering between irq and seqno writes on
+	 * ivb (and maybe also on snb) by reading from a CS register (like
+	 * ACTHD) before reading the status page.
+	 *
+	 * Note that this effectively stalls the read by the time it takes to
+	 * do a memory transaction, which more or less ensures that the write
+	 * from the GPU has sufficient time to invalidate the CPU cacheline.
+	 * Alternatively we could delay the interrupt from the CS ring to give
+	 * the write time to land, but that would incur a delay after every
+	 * batch i.e. much more frequent than a delay when waiting for the
+	 * interrupt (with the same net latency).
+	 *
+	 * Also note that to prevent whole machine hangs on gen7, we have to
+	 * take the spinlock to guard against concurrent cacheline access.
+	 */
+	spin_lock_irq(&dev_priv->uncore.lock);
+	POSTING_READ_FW(RING_ACTHD(engine->mmio_base));
+	spin_unlock_irq(&dev_priv->uncore.lock);
+}
+
+static u32
+ring_get_seqno(struct intel_engine_cs *engine)
+{
+	return intel_read_status_page(engine, I915_GEM_HWS_INDEX);
+}
+
+static void
+ring_set_seqno(struct intel_engine_cs *engine, u32 seqno)
+{
+	intel_write_status_page(engine, I915_GEM_HWS_INDEX, seqno);
+}
+
+static u32
+pc_render_get_seqno(struct intel_engine_cs *engine)
+{
+	return engine->scratch.cpu_page[0];
+}
+
+static void
+pc_render_set_seqno(struct intel_engine_cs *engine, u32 seqno)
+{
+	engine->scratch.cpu_page[0] = seqno;
+}
+
+static bool
+gen5_ring_get_irq(struct intel_engine_cs *engine)
+{
+	struct drm_device *dev = engine->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	unsigned long flags;
+
+	if (WARN_ON(!intel_irqs_enabled(dev_priv)))
+		return false;
+
+	spin_lock_irqsave(&dev_priv->irq_lock, flags);
+	if (engine->irq_refcount++ == 0)
+		gen5_enable_gt_irq(dev_priv, engine->irq_enable_mask);
+	spin_unlock_irqrestore(&dev_priv->irq_lock, flags);
+
+	return true;
+}
+
+static void
+gen5_ring_put_irq(struct intel_engine_cs *engine)
+{
+	struct drm_device *dev = engine->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	unsigned long flags;
+
+	spin_lock_irqsave(&dev_priv->irq_lock, flags);
+	if (--engine->irq_refcount == 0)
+		gen5_disable_gt_irq(dev_priv, engine->irq_enable_mask);
+	spin_unlock_irqrestore(&dev_priv->irq_lock, flags);
+}
+
+static bool
+i9xx_ring_get_irq(struct intel_engine_cs *engine)
+{
+	struct drm_device *dev = engine->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	unsigned long flags;
+
+	if (!intel_irqs_enabled(dev_priv))
+		return false;
+
+	spin_lock_irqsave(&dev_priv->irq_lock, flags);
+	if (engine->irq_refcount++ == 0) {
+		dev_priv->irq_mask &= ~engine->irq_enable_mask;
+		I915_WRITE(IMR, dev_priv->irq_mask);
+		POSTING_READ(IMR);
+	}
+	spin_unlock_irqrestore(&dev_priv->irq_lock, flags);
+
+	return true;
+}
+
+static void
+i9xx_ring_put_irq(struct intel_engine_cs *engine)
+{
+	struct drm_device *dev = engine->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	unsigned long flags;
+
+	spin_lock_irqsave(&dev_priv->irq_lock, flags);
+	if (--engine->irq_refcount == 0) {
+		dev_priv->irq_mask |= engine->irq_enable_mask;
+		I915_WRITE(IMR, dev_priv->irq_mask);
+		POSTING_READ(IMR);
+	}
+	spin_unlock_irqrestore(&dev_priv->irq_lock, flags);
+}
+
+static bool
+i8xx_ring_get_irq(struct intel_engine_cs *engine)
+{
+	struct drm_device *dev = engine->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	unsigned long flags;
+
+	if (!intel_irqs_enabled(dev_priv))
+		return false;
+
+	spin_lock_irqsave(&dev_priv->irq_lock, flags);
+	if (engine->irq_refcount++ == 0) {
+		dev_priv->irq_mask &= ~engine->irq_enable_mask;
+		I915_WRITE16(IMR, dev_priv->irq_mask);
+		POSTING_READ16(IMR);
+	}
+	spin_unlock_irqrestore(&dev_priv->irq_lock, flags);
+
+	return true;
+}
+
+static void
+i8xx_ring_put_irq(struct intel_engine_cs *engine)
+{
+	struct drm_device *dev = engine->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	unsigned long flags;
+
+	spin_lock_irqsave(&dev_priv->irq_lock, flags);
+	if (--engine->irq_refcount == 0) {
+		dev_priv->irq_mask |= engine->irq_enable_mask;
+		I915_WRITE16(IMR, dev_priv->irq_mask);
+		POSTING_READ16(IMR);
+	}
+	spin_unlock_irqrestore(&dev_priv->irq_lock, flags);
+}
+
+static int
+bsd_ring_flush(struct drm_i915_gem_request *req,
+	       u32     invalidate_domains,
+	       u32     flush_domains)
+{
+	struct intel_engine_cs *engine = req->engine;
+	int ret;
+
+	ret = intel_ring_begin(req, 2);
+	if (ret)
+		return ret;
+
+	intel_ring_emit(engine, MI_FLUSH);
+	intel_ring_emit(engine, MI_NOOP);
+	intel_ring_advance(engine);
+	return 0;
+}
+
+static int
+i9xx_add_request(struct drm_i915_gem_request *req)
+{
+	struct intel_engine_cs *engine = req->engine;
+	int ret;
+
+	ret = intel_ring_begin(req, 4);
+	if (ret)
+		return ret;
+
+	intel_ring_emit(engine, MI_STORE_DWORD_INDEX);
+	intel_ring_emit(engine,
+			I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT);
+	intel_ring_emit(engine, i915_gem_request_get_seqno(req));
+	intel_ring_emit(engine, MI_USER_INTERRUPT);
+	__intel_ring_advance(engine);
+
+	return 0;
+}
+
+static bool
+gen6_ring_get_irq(struct intel_engine_cs *engine)
+{
+	struct drm_device *dev = engine->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	unsigned long flags;
+
+	if (WARN_ON(!intel_irqs_enabled(dev_priv)))
+		return false;
+
+	spin_lock_irqsave(&dev_priv->irq_lock, flags);
+	if (engine->irq_refcount++ == 0) {
+		if (HAS_L3_DPF(dev) && engine->id == RCS)
+			I915_WRITE_IMR(engine,
+				       ~(engine->irq_enable_mask |
+					 GT_PARITY_ERROR(dev)));
+		else
+			I915_WRITE_IMR(engine, ~engine->irq_enable_mask);
+		gen5_enable_gt_irq(dev_priv, engine->irq_enable_mask);
+	}
+	spin_unlock_irqrestore(&dev_priv->irq_lock, flags);
+
+	return true;
+}
+
+static void
+gen6_ring_put_irq(struct intel_engine_cs *engine)
+{
+	struct drm_device *dev = engine->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	unsigned long flags;
+
+	spin_lock_irqsave(&dev_priv->irq_lock, flags);
+	if (--engine->irq_refcount == 0) {
+		if (HAS_L3_DPF(dev) && engine->id == RCS)
+			I915_WRITE_IMR(engine, ~GT_PARITY_ERROR(dev));
+		else
+			I915_WRITE_IMR(engine, ~0);
+		gen5_disable_gt_irq(dev_priv, engine->irq_enable_mask);
+	}
+	spin_unlock_irqrestore(&dev_priv->irq_lock, flags);
+}
+
+static bool
+hsw_vebox_get_irq(struct intel_engine_cs *engine)
+{
+	struct drm_device *dev = engine->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	unsigned long flags;
+
+	if (WARN_ON(!intel_irqs_enabled(dev_priv)))
+		return false;
+
+	spin_lock_irqsave(&dev_priv->irq_lock, flags);
+	if (engine->irq_refcount++ == 0) {
+		I915_WRITE_IMR(engine, ~engine->irq_enable_mask);
+		gen6_enable_pm_irq(dev_priv, engine->irq_enable_mask);
+	}
+	spin_unlock_irqrestore(&dev_priv->irq_lock, flags);
+
+	return true;
+}
+
+static void
+hsw_vebox_put_irq(struct intel_engine_cs *engine)
+{
+	struct drm_device *dev = engine->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	unsigned long flags;
+
+	spin_lock_irqsave(&dev_priv->irq_lock, flags);
+	if (--engine->irq_refcount == 0) {
+		I915_WRITE_IMR(engine, ~0);
+		gen6_disable_pm_irq(dev_priv, engine->irq_enable_mask);
+	}
+	spin_unlock_irqrestore(&dev_priv->irq_lock, flags);
+}
+
+static bool
+gen8_ring_get_irq(struct intel_engine_cs *engine)
+{
+	struct drm_device *dev = engine->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	unsigned long flags;
+
+	if (WARN_ON(!intel_irqs_enabled(dev_priv)))
+		return false;
+
+	spin_lock_irqsave(&dev_priv->irq_lock, flags);
+	if (engine->irq_refcount++ == 0) {
+		if (HAS_L3_DPF(dev) && engine->id == RCS) {
+			I915_WRITE_IMR(engine,
+				       ~(engine->irq_enable_mask |
+					 GT_RENDER_L3_PARITY_ERROR_INTERRUPT));
+		} else {
+			I915_WRITE_IMR(engine, ~engine->irq_enable_mask);
+		}
+		POSTING_READ(RING_IMR(engine->mmio_base));
+	}
+	spin_unlock_irqrestore(&dev_priv->irq_lock, flags);
+
+	return true;
+}
+
+static void
+gen8_ring_put_irq(struct intel_engine_cs *engine)
+{
+	struct drm_device *dev = engine->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	unsigned long flags;
+
+	spin_lock_irqsave(&dev_priv->irq_lock, flags);
+	if (--engine->irq_refcount == 0) {
+		if (HAS_L3_DPF(dev) && engine->id == RCS) {
+			I915_WRITE_IMR(engine,
+				       ~GT_RENDER_L3_PARITY_ERROR_INTERRUPT);
+		} else {
+			I915_WRITE_IMR(engine, ~0);
+		}
+		POSTING_READ(RING_IMR(engine->mmio_base));
+	}
+	spin_unlock_irqrestore(&dev_priv->irq_lock, flags);
+}
+
+static int
+i965_dispatch_execbuffer(struct drm_i915_gem_request *req,
+			 u64 offset, u32 length,
+			 unsigned dispatch_flags)
+{
+	struct intel_engine_cs *engine = req->engine;
+	int ret;
+
+	ret = intel_ring_begin(req, 2);
+	if (ret)
+		return ret;
+
+	intel_ring_emit(engine,
+			MI_BATCH_BUFFER_START |
+			MI_BATCH_GTT |
+			(dispatch_flags & I915_DISPATCH_SECURE ?
+			 0 : MI_BATCH_NON_SECURE_I965));
+	intel_ring_emit(engine, offset);
+	intel_ring_advance(engine);
+
+	return 0;
+}
+
+/* Just userspace ABI convention to limit the wa batch bo to a resonable size */
+#define I830_BATCH_LIMIT (256*1024)
+#define I830_TLB_ENTRIES (2)
+#define I830_WA_SIZE max(I830_TLB_ENTRIES*4096, I830_BATCH_LIMIT)
+static int
+i830_dispatch_execbuffer(struct drm_i915_gem_request *req,
+			 u64 offset, u32 len,
+			 unsigned dispatch_flags)
+{
+	struct intel_engine_cs *engine = req->engine;
+	u32 cs_offset = engine->scratch.gtt_offset;
+	int ret;
+
+	ret = intel_ring_begin(req, 6);
+	if (ret)
+		return ret;
+
+	/* Evict the invalid PTE TLBs */
+	intel_ring_emit(engine, COLOR_BLT_CMD | BLT_WRITE_RGBA);
+	intel_ring_emit(engine, BLT_DEPTH_32 | BLT_ROP_COLOR_COPY | 4096);
+	intel_ring_emit(engine, I830_TLB_ENTRIES << 16 | 4); /* load each page */
+	intel_ring_emit(engine, cs_offset);
+	intel_ring_emit(engine, 0xdeadbeef);
+	intel_ring_emit(engine, MI_NOOP);
+	intel_ring_advance(engine);
+
+	if ((dispatch_flags & I915_DISPATCH_PINNED) == 0) {
+		if (len > I830_BATCH_LIMIT)
+			return -ENOSPC;
+
+		ret = intel_ring_begin(req, 6 + 2);
+		if (ret)
+			return ret;
+
+		/* Blit the batch (which has now all relocs applied) to the
+		 * stable batch scratch bo area (so that the CS never
+		 * stumbles over its tlb invalidation bug) ...
+		 */
+		intel_ring_emit(engine, SRC_COPY_BLT_CMD | BLT_WRITE_RGBA);
+		intel_ring_emit(engine,
+				BLT_DEPTH_32 | BLT_ROP_SRC_COPY | 4096);
+		intel_ring_emit(engine, DIV_ROUND_UP(len, 4096) << 16 | 4096);
+		intel_ring_emit(engine, cs_offset);
+		intel_ring_emit(engine, 4096);
+		intel_ring_emit(engine, offset);
+
+		intel_ring_emit(engine, MI_FLUSH);
+		intel_ring_emit(engine, MI_NOOP);
+		intel_ring_advance(engine);
+
+		/* ... and execute it. */
+		offset = cs_offset;
+	}
+
+	ret = intel_ring_begin(req, 2);
+	if (ret)
+		return ret;
+
+	intel_ring_emit(engine, MI_BATCH_BUFFER_START | MI_BATCH_GTT);
+	intel_ring_emit(engine, offset | (dispatch_flags & I915_DISPATCH_SECURE ?
+					  0 : MI_BATCH_NON_SECURE));
+	intel_ring_advance(engine);
+
+	return 0;
+}
+
+static int
+i915_dispatch_execbuffer(struct drm_i915_gem_request *req,
+			 u64 offset, u32 len,
+			 unsigned dispatch_flags)
+{
+	struct intel_engine_cs *engine = req->engine;
+	int ret;
+
+	ret = intel_ring_begin(req, 2);
+	if (ret)
+		return ret;
+
+	intel_ring_emit(engine, MI_BATCH_BUFFER_START | MI_BATCH_GTT);
+	intel_ring_emit(engine, offset | (dispatch_flags & I915_DISPATCH_SECURE ?
+					  0 : MI_BATCH_NON_SECURE));
+	intel_ring_advance(engine);
+
+	return 0;
+}
+
+static void cleanup_phys_status_page(struct intel_engine_cs *engine)
+{
+	struct drm_i915_private *dev_priv = to_i915(engine->dev);
+
+	if (!dev_priv->status_page_dmah)
+		return;
+
+	drm_pci_free(engine->dev, dev_priv->status_page_dmah);
+	engine->status_page.page_addr = NULL;
+}
+
+static void cleanup_status_page(struct intel_engine_cs *engine)
+{
+	struct drm_i915_gem_object *obj;
+
+	obj = engine->status_page.obj;
+	if (obj == NULL)
+		return;
+
+	kunmap(sg_page(obj->pages->sgl));
+	i915_gem_object_ggtt_unpin(obj);
+	drm_gem_object_unreference(&obj->base);
+	engine->status_page.obj = NULL;
+}
+
+static int init_status_page(struct intel_engine_cs *engine)
+{
+	struct drm_i915_gem_object *obj = engine->status_page.obj;
+
+	if (obj == NULL) {
+		unsigned flags;
+		int ret;
+
+		obj = i915_gem_alloc_object(engine->dev, 4096);
+		if (obj == NULL) {
+			DRM_ERROR("Failed to allocate status page\n");
+			return -ENOMEM;
+		}
+
+		ret = i915_gem_object_set_cache_level(obj, I915_CACHE_LLC);
+		if (ret)
+			goto err_unref;
+
+		flags = 0;
+		if (!HAS_LLC(engine->dev))
+			/* On g33, we cannot place HWS above 256MiB, so
+			 * restrict its pinning to the low mappable arena.
+			 * Though this restriction is not documented for
+			 * gen4, gen5, or byt, they also behave similarly
+			 * and hang if the HWS is placed at the top of the
+			 * GTT. To generalise, it appears that all !llc
+			 * platforms have issues with us placing the HWS
+			 * above the mappable region (even though we never
+			 * actualy map it).
+			 */
+			flags |= PIN_MAPPABLE;
+		ret = i915_gem_obj_ggtt_pin(obj, 4096, flags);
+		if (ret) {
+err_unref:
+			drm_gem_object_unreference(&obj->base);
+			return ret;
+		}
+
+		engine->status_page.obj = obj;
+	}
+
+	engine->status_page.gfx_addr = i915_gem_obj_ggtt_offset(obj);
+	engine->status_page.page_addr = kmap(sg_page(obj->pages->sgl));
+	memset(engine->status_page.page_addr, 0, PAGE_SIZE);
+
+	DRM_DEBUG_DRIVER("%s hws offset: 0x%08x\n",
+			engine->name, engine->status_page.gfx_addr);
+
+	return 0;
+}
+
+static int init_phys_status_page(struct intel_engine_cs *engine)
+{
+	struct drm_i915_private *dev_priv = engine->dev->dev_private;
+
+	if (!dev_priv->status_page_dmah) {
+		dev_priv->status_page_dmah =
+			drm_pci_alloc(engine->dev, PAGE_SIZE, PAGE_SIZE);
+		if (!dev_priv->status_page_dmah)
+			return -ENOMEM;
+	}
+
+	engine->status_page.page_addr = dev_priv->status_page_dmah->vaddr;
+	memset(engine->status_page.page_addr, 0, PAGE_SIZE);
+
+	return 0;
+}
+
+void intel_unpin_ringbuffer_obj(struct intel_ringbuffer *ringbuf)
+{
+	if (HAS_LLC(ringbuf->obj->base.dev) && !ringbuf->obj->stolen)
+		i915_gem_object_unpin_map(ringbuf->obj);
+	else
+		iounmap(ringbuf->virtual_start);
+	ringbuf->virtual_start = NULL;
+	ringbuf->vma = NULL;
+	i915_gem_object_ggtt_unpin(ringbuf->obj);
+}
+
+int intel_pin_and_map_ringbuffer_obj(struct drm_device *dev,
+				     struct intel_ringbuffer *ringbuf)
+{
+	struct drm_i915_private *dev_priv = to_i915(dev);
+	struct i915_ggtt *ggtt = &dev_priv->ggtt;
+	struct drm_i915_gem_object *obj = ringbuf->obj;
+	/* Ring wraparound at offset 0 sometimes hangs. No idea why. */
+	unsigned flags = PIN_OFFSET_BIAS | 4096;
+	void *addr;
+	int ret;
+
+	if (HAS_LLC(dev_priv) && !obj->stolen) {
+		ret = i915_gem_obj_ggtt_pin(obj, PAGE_SIZE, flags);
+		if (ret)
+			return ret;
+
+		ret = i915_gem_object_set_to_cpu_domain(obj, true);
+		if (ret)
+			goto err_unpin;
+
+		addr = i915_gem_object_pin_map(obj);
+		if (IS_ERR(addr)) {
+			ret = PTR_ERR(addr);
+			goto err_unpin;
+		}
+	} else {
+		ret = i915_gem_obj_ggtt_pin(obj, PAGE_SIZE,
+					    flags | PIN_MAPPABLE);
+		if (ret)
+			return ret;
+
+		ret = i915_gem_object_set_to_gtt_domain(obj, true);
+		if (ret)
+			goto err_unpin;
+
+		/* Access through the GTT requires the device to be awake. */
+		assert_rpm_wakelock_held(dev_priv);
+
+		addr = ioremap_wc(ggtt->mappable_base +
+				  i915_gem_obj_ggtt_offset(obj), ringbuf->size);
+		if (addr == NULL) {
+			ret = -ENOMEM;
+			goto err_unpin;
+		}
+	}
+
+	ringbuf->virtual_start = addr;
+	ringbuf->vma = i915_gem_obj_to_ggtt(obj);
+	return 0;
+
+err_unpin:
+	i915_gem_object_ggtt_unpin(obj);
+	return ret;
+}
+
+static void intel_destroy_ringbuffer_obj(struct intel_ringbuffer *ringbuf)
+{
+	drm_gem_object_unreference(&ringbuf->obj->base);
+	ringbuf->obj = NULL;
+}
+
+static int intel_alloc_ringbuffer_obj(struct drm_device *dev,
+				      struct intel_ringbuffer *ringbuf)
+{
+	struct drm_i915_gem_object *obj;
+
+	obj = NULL;
+	if (!HAS_LLC(dev))
+		obj = i915_gem_object_create_stolen(dev, ringbuf->size);
+	if (obj == NULL)
+		obj = i915_gem_alloc_object(dev, ringbuf->size);
+	if (obj == NULL)
+		return -ENOMEM;
+
+	/* mark ring buffers as read-only from GPU side by default */
+	obj->gt_ro = 1;
+
+	ringbuf->obj = obj;
+
+	return 0;
+}
+
+struct intel_ringbuffer *
+intel_engine_create_ringbuffer(struct intel_engine_cs *engine, int size)
+{
+	struct intel_ringbuffer *ring;
+	int ret;
+
+	ring = kzalloc(sizeof(*ring), GFP_KERNEL);
+	if (ring == NULL) {
+		DRM_DEBUG_DRIVER("Failed to allocate ringbuffer %s\n",
+				 engine->name);
+		return ERR_PTR(-ENOMEM);
+	}
+
+	ring->engine = engine;
+	list_add(&ring->link, &engine->buffers);
+
+	ring->size = size;
+	/* Workaround an erratum on the i830 which causes a hang if
+	 * the TAIL pointer points to within the last 2 cachelines
+	 * of the buffer.
+	 */
+	ring->effective_size = size;
+	if (IS_I830(engine->dev) || IS_845G(engine->dev))
+		ring->effective_size -= 2 * CACHELINE_BYTES;
+
+	ring->last_retired_head = -1;
+	intel_ring_update_space(ring);
+
+	ret = intel_alloc_ringbuffer_obj(engine->dev, ring);
+	if (ret) {
+		DRM_DEBUG_DRIVER("Failed to allocate ringbuffer %s: %d\n",
+				 engine->name, ret);
+		list_del(&ring->link);
+		kfree(ring);
+		return ERR_PTR(ret);
+	}
+
+	return ring;
+}
+
+void
+intel_ringbuffer_free(struct intel_ringbuffer *ring)
+{
+	intel_destroy_ringbuffer_obj(ring);
+	list_del(&ring->link);
+	kfree(ring);
+}
+
+static int intel_init_ring_buffer(struct drm_device *dev,
+				  struct intel_engine_cs *engine)
+{
+	struct intel_ringbuffer *ringbuf;
+	int ret;
+
+	WARN_ON(engine->buffer);
+
+	engine->dev = dev;
+	INIT_LIST_HEAD(&engine->active_list);
+	INIT_LIST_HEAD(&engine->request_list);
+	INIT_LIST_HEAD(&engine->execlist_queue);
+	INIT_LIST_HEAD(&engine->buffers);
+	i915_gem_batch_pool_init(dev, &engine->batch_pool);
+	memset(engine->semaphore.sync_seqno, 0,
+	       sizeof(engine->semaphore.sync_seqno));
+
+	init_waitqueue_head(&engine->irq_queue);
+
+	ringbuf = intel_engine_create_ringbuffer(engine, 32 * PAGE_SIZE);
+	if (IS_ERR(ringbuf)) {
+		ret = PTR_ERR(ringbuf);
+		goto error;
+	}
+	engine->buffer = ringbuf;
+
+	if (I915_NEED_GFX_HWS(dev)) {
+		ret = init_status_page(engine);
+		if (ret)
+			goto error;
+	} else {
+		WARN_ON(engine->id != RCS);
+		ret = init_phys_status_page(engine);
+		if (ret)
+			goto error;
+	}
+
+	ret = intel_pin_and_map_ringbuffer_obj(dev, ringbuf);
+	if (ret) {
+		DRM_ERROR("Failed to pin and map ringbuffer %s: %d\n",
+				engine->name, ret);
+		intel_destroy_ringbuffer_obj(ringbuf);
+		goto error;
+	}
+
+	ret = i915_cmd_parser_init_ring(engine);
+	if (ret)
+		goto error;
+
+	return 0;
+
+error:
+	intel_cleanup_engine(engine);
+	return ret;
+}
+
+void intel_cleanup_engine(struct intel_engine_cs *engine)
+{
+	struct drm_i915_private *dev_priv;
+
+	if (!intel_engine_initialized(engine))
+		return;
+
+	dev_priv = to_i915(engine->dev);
+
+	if (engine->buffer) {
+		intel_stop_engine(engine);
+		WARN_ON(!IS_GEN2(engine->dev) && (I915_READ_MODE(engine) & MODE_IDLE) == 0);
+
+		intel_unpin_ringbuffer_obj(engine->buffer);
+		intel_ringbuffer_free(engine->buffer);
+		engine->buffer = NULL;
+	}
+
+	if (engine->cleanup)
+		engine->cleanup(engine);
+
+	if (I915_NEED_GFX_HWS(engine->dev)) {
+		cleanup_status_page(engine);
+	} else {
+		WARN_ON(engine->id != RCS);
+		cleanup_phys_status_page(engine);
+	}
+
+	i915_cmd_parser_fini_ring(engine);
+	i915_gem_batch_pool_fini(&engine->batch_pool);
+	engine->dev = NULL;
+}
+
+int intel_engine_idle(struct intel_engine_cs *engine)
+{
+	struct drm_i915_gem_request *req;
+
+	/* Wait upon the last request to be completed */
+	if (list_empty(&engine->request_list))
+		return 0;
+
+	req = list_entry(engine->request_list.prev,
+			 struct drm_i915_gem_request,
+			 list);
+
+	/* Make sure we do not trigger any retires */
+	return __i915_wait_request(req,
+				   req->i915->mm.interruptible,
+				   NULL, NULL);
+}
+
+int intel_ring_alloc_request_extras(struct drm_i915_gem_request *request)
+{
+	request->ringbuf = request->engine->buffer;
+	return 0;
+}
+
+int intel_ring_reserve_space(struct drm_i915_gem_request *request)
+{
+	/*
+	 * The first call merely notes the reserve request and is common for
+	 * all back ends. The subsequent localised _begin() call actually
+	 * ensures that the reservation is available. Without the begin, if
+	 * the request creator immediately submitted the request without
+	 * adding any commands to it then there might not actually be
+	 * sufficient room for the submission commands.
+	 */
+	intel_ring_reserved_space_reserve(request->ringbuf, MIN_SPACE_FOR_ADD_REQUEST);
+
+	return intel_ring_begin(request, 0);
+}
+
+void intel_ring_reserved_space_reserve(struct intel_ringbuffer *ringbuf, int size)
+{
+	GEM_BUG_ON(ringbuf->reserved_size);
+	ringbuf->reserved_size = size;
+}
+
+void intel_ring_reserved_space_cancel(struct intel_ringbuffer *ringbuf)
+{
+	GEM_BUG_ON(!ringbuf->reserved_size);
+	ringbuf->reserved_size   = 0;
+}
+
+void intel_ring_reserved_space_use(struct intel_ringbuffer *ringbuf)
+{
+	GEM_BUG_ON(!ringbuf->reserved_size);
+	ringbuf->reserved_size   = 0;
+}
+
+void intel_ring_reserved_space_end(struct intel_ringbuffer *ringbuf)
+{
+	GEM_BUG_ON(ringbuf->reserved_size);
+}
+
+static int wait_for_space(struct drm_i915_gem_request *req, int bytes)
+{
+	struct intel_ringbuffer *ringbuf = req->ringbuf;
+	struct intel_engine_cs *engine = req->engine;
+	struct drm_i915_gem_request *target;
+
+	intel_ring_update_space(ringbuf);
+	if (ringbuf->space >= bytes)
+		return 0;
+
+	/*
+	 * Space is reserved in the ringbuffer for finalising the request,
+	 * as that cannot be allowed to fail. During request finalisation,
+	 * reserved_space is set to 0 to stop the overallocation and the
+	 * assumption is that then we never need to wait (which has the
+	 * risk of failing with EINTR).
+	 *
+	 * See also i915_gem_request_alloc() and i915_add_request().
+	 */
+	GEM_BUG_ON(!ringbuf->reserved_size);
+
+	list_for_each_entry(target, &engine->request_list, list) {
+		unsigned space;
+
+		/*
+		 * The request queue is per-engine, so can contain requests
+		 * from multiple ringbuffers. Here, we must ignore any that
+		 * aren't from the ringbuffer we're considering.
+		 */
+		if (target->ringbuf != ringbuf)
+			continue;
+
+		/* Would completion of this request free enough space? */
+		space = __intel_ring_space(target->postfix, ringbuf->tail,
+					   ringbuf->size);
+		if (space >= bytes)
+			break;
+	}
+
+	if (WARN_ON(&target->list == &engine->request_list))
+		return -ENOSPC;
+
+	return i915_wait_request(target);
+}
+
+int intel_ring_begin(struct drm_i915_gem_request *req, int num_dwords)
+{
+	struct intel_ringbuffer *ringbuf = req->ringbuf;
+	int remain_actual = ringbuf->size - ringbuf->tail;
+	int remain_usable = ringbuf->effective_size - ringbuf->tail;
+	int bytes = num_dwords * sizeof(u32);
+	int total_bytes, wait_bytes;
+	bool need_wrap = false;
+
+	total_bytes = bytes + ringbuf->reserved_size;
+
+	if (unlikely(bytes > remain_usable)) {
+		/*
+		 * Not enough space for the basic request. So need to flush
+		 * out the remainder and then wait for base + reserved.
+		 */
+		wait_bytes = remain_actual + total_bytes;
+		need_wrap = true;
+	} else if (unlikely(total_bytes > remain_usable)) {
+		/*
+		 * The base request will fit but the reserved space
+		 * falls off the end. So we don't need an immediate wrap
+		 * and only need to effectively wait for the reserved
+		 * size space from the start of ringbuffer.
+		 */
+		wait_bytes = remain_actual + ringbuf->reserved_size;
+	} else {
+		/* No wrapping required, just waiting. */
+		wait_bytes = total_bytes;
+	}
+
+	if (wait_bytes > ringbuf->space) {
+		int ret = wait_for_space(req, wait_bytes);
+		if (unlikely(ret))
+			return ret;
+
+		intel_ring_update_space(ringbuf);
+		if (unlikely(ringbuf->space < wait_bytes))
+			return -EAGAIN;
+	}
+
+	if (unlikely(need_wrap)) {
+		GEM_BUG_ON(remain_actual > ringbuf->space);
+		GEM_BUG_ON(ringbuf->tail + remain_actual > ringbuf->size);
+
+		/* Fill the tail with MI_NOOP */
+		memset(ringbuf->virtual_start + ringbuf->tail,
+		       0, remain_actual);
+		ringbuf->tail = 0;
+		ringbuf->space -= remain_actual;
+	}
+
+	ringbuf->space -= bytes;
+	GEM_BUG_ON(ringbuf->space < 0);
+	return 0;
+}
+
+/* Align the ring tail to a cacheline boundary */
+int intel_ring_cacheline_align(struct drm_i915_gem_request *req)
+{
+	struct intel_engine_cs *engine = req->engine;
+	int num_dwords = (engine->buffer->tail & (CACHELINE_BYTES - 1)) / sizeof(uint32_t);
+	int ret;
+
+	if (num_dwords == 0)
+		return 0;
+
+	num_dwords = CACHELINE_BYTES / sizeof(uint32_t) - num_dwords;
+	ret = intel_ring_begin(req, num_dwords);
+	if (ret)
+		return ret;
+
+	while (num_dwords--)
+		intel_ring_emit(engine, MI_NOOP);
+
+	intel_ring_advance(engine);
+
+	return 0;
+}
+
+void intel_ring_init_seqno(struct intel_engine_cs *engine, u32 seqno)
+{
+	struct drm_i915_private *dev_priv = to_i915(engine->dev);
+
+	/* Our semaphore implementation is strictly monotonic (i.e. we proceed
+	 * so long as the semaphore value in the register/page is greater
+	 * than the sync value), so whenever we reset the seqno,
+	 * so long as we reset the tracking semaphore value to 0, it will
+	 * always be before the next request's seqno. If we don't reset
+	 * the semaphore value, then when the seqno moves backwards all
+	 * future waits will complete instantly (causing rendering corruption).
+	 */
+	if (INTEL_INFO(dev_priv)->gen == 6 || INTEL_INFO(dev_priv)->gen == 7) {
+		I915_WRITE(RING_SYNC_0(engine->mmio_base), 0);
+		I915_WRITE(RING_SYNC_1(engine->mmio_base), 0);
+		if (HAS_VEBOX(dev_priv))
+			I915_WRITE(RING_SYNC_2(engine->mmio_base), 0);
+	}
+	if (dev_priv->semaphore_obj) {
+		struct drm_i915_gem_object *obj = dev_priv->semaphore_obj;
+		struct page *page = i915_gem_object_get_dirty_page(obj, 0);
+		void *semaphores = kmap(page);
+		memset(semaphores + GEN8_SEMAPHORE_OFFSET(engine->id, 0),
+		       0, I915_NUM_ENGINES * gen8_semaphore_seqno_size);
+		kunmap(page);
+	}
+	memset(engine->semaphore.sync_seqno, 0,
+	       sizeof(engine->semaphore.sync_seqno));
+
+	engine->set_seqno(engine, seqno);
+	engine->last_submitted_seqno = seqno;
+
+	engine->hangcheck.seqno = seqno;
+}
+
+static void gen6_bsd_ring_write_tail(struct intel_engine_cs *engine,
+				     u32 value)
+{
+	struct drm_i915_private *dev_priv = engine->dev->dev_private;
+
+       /* Every tail move must follow the sequence below */
+
+	/* Disable notification that the ring is IDLE. The GT
+	 * will then assume that it is busy and bring it out of rc6.
+	 */
+	I915_WRITE(GEN6_BSD_SLEEP_PSMI_CONTROL,
+		   _MASKED_BIT_ENABLE(GEN6_BSD_SLEEP_MSG_DISABLE));
+
+	/* Clear the context id. Here be magic! */
+	I915_WRITE64(GEN6_BSD_RNCID, 0x0);
+
+	/* Wait for the ring not to be idle, i.e. for it to wake up. */
+	if (wait_for((I915_READ(GEN6_BSD_SLEEP_PSMI_CONTROL) &
+		      GEN6_BSD_SLEEP_INDICATOR) == 0,
+		     50))
+		DRM_ERROR("timed out waiting for the BSD ring to wake up\n");
+
+	/* Now that the ring is fully powered up, update the tail */
+	I915_WRITE_TAIL(engine, value);
+	POSTING_READ(RING_TAIL(engine->mmio_base));
+
+	/* Let the ring send IDLE messages to the GT again,
+	 * and so let it sleep to conserve power when idle.
+	 */
+	I915_WRITE(GEN6_BSD_SLEEP_PSMI_CONTROL,
+		   _MASKED_BIT_DISABLE(GEN6_BSD_SLEEP_MSG_DISABLE));
+}
+
+static int gen6_bsd_ring_flush(struct drm_i915_gem_request *req,
+			       u32 invalidate, u32 flush)
+{
+	struct intel_engine_cs *engine = req->engine;
+	uint32_t cmd;
+	int ret;
+
+	ret = intel_ring_begin(req, 4);
+	if (ret)
+		return ret;
+
+	cmd = MI_FLUSH_DW;
+	if (INTEL_INFO(engine->dev)->gen >= 8)
+		cmd += 1;
+
+	/* We always require a command barrier so that subsequent
+	 * commands, such as breadcrumb interrupts, are strictly ordered
+	 * wrt the contents of the write cache being flushed to memory
+	 * (and thus being coherent from the CPU).
+	 */
+	cmd |= MI_FLUSH_DW_STORE_INDEX | MI_FLUSH_DW_OP_STOREDW;
+
+	/*
+	 * Bspec vol 1c.5 - video engine command streamer:
+	 * "If ENABLED, all TLBs will be invalidated once the flush
+	 * operation is complete. This bit is only valid when the
+	 * Post-Sync Operation field is a value of 1h or 3h."
+	 */
+	if (invalidate & I915_GEM_GPU_DOMAINS)
+		cmd |= MI_INVALIDATE_TLB | MI_INVALIDATE_BSD;
+
+	intel_ring_emit(engine, cmd);
+	intel_ring_emit(engine,
+			I915_GEM_HWS_SCRATCH_ADDR | MI_FLUSH_DW_USE_GTT);
+	if (INTEL_INFO(engine->dev)->gen >= 8) {
+		intel_ring_emit(engine, 0); /* upper addr */
+		intel_ring_emit(engine, 0); /* value */
+	} else  {
+		intel_ring_emit(engine, 0);
+		intel_ring_emit(engine, MI_NOOP);
+	}
+	intel_ring_advance(engine);
+	return 0;
+}
+
+static int
+gen8_ring_dispatch_execbuffer(struct drm_i915_gem_request *req,
+			      u64 offset, u32 len,
+			      unsigned dispatch_flags)
+{
+	struct intel_engine_cs *engine = req->engine;
+	bool ppgtt = USES_PPGTT(engine->dev) &&
+			!(dispatch_flags & I915_DISPATCH_SECURE);
+	int ret;
+
+	ret = intel_ring_begin(req, 4);
+	if (ret)
+		return ret;
+
+	/* FIXME(BDW): Address space and security selectors. */
+	intel_ring_emit(engine, MI_BATCH_BUFFER_START_GEN8 | (ppgtt<<8) |
+			(dispatch_flags & I915_DISPATCH_RS ?
+			 MI_BATCH_RESOURCE_STREAMER : 0));
+	intel_ring_emit(engine, lower_32_bits(offset));
+	intel_ring_emit(engine, upper_32_bits(offset));
+	intel_ring_emit(engine, MI_NOOP);
+	intel_ring_advance(engine);
+
+	return 0;
+}
+
+static int
+hsw_ring_dispatch_execbuffer(struct drm_i915_gem_request *req,
+			     u64 offset, u32 len,
+			     unsigned dispatch_flags)
+{
+	struct intel_engine_cs *engine = req->engine;
+	int ret;
+
+	ret = intel_ring_begin(req, 2);
+	if (ret)
+		return ret;
+
+	intel_ring_emit(engine,
+			MI_BATCH_BUFFER_START |
+			(dispatch_flags & I915_DISPATCH_SECURE ?
+			 0 : MI_BATCH_PPGTT_HSW | MI_BATCH_NON_SECURE_HSW) |
+			(dispatch_flags & I915_DISPATCH_RS ?
+			 MI_BATCH_RESOURCE_STREAMER : 0));
+	/* bit0-7 is the length on GEN6+ */
+	intel_ring_emit(engine, offset);
+	intel_ring_advance(engine);
+
+	return 0;
+}
+
+static int
+gen6_ring_dispatch_execbuffer(struct drm_i915_gem_request *req,
+			      u64 offset, u32 len,
+			      unsigned dispatch_flags)
+{
+	struct intel_engine_cs *engine = req->engine;
+	int ret;
+
+	ret = intel_ring_begin(req, 2);
+	if (ret)
+		return ret;
+
+	intel_ring_emit(engine,
+			MI_BATCH_BUFFER_START |
+			(dispatch_flags & I915_DISPATCH_SECURE ?
+			 0 : MI_BATCH_NON_SECURE_I965));
+	/* bit0-7 is the length on GEN6+ */
+	intel_ring_emit(engine, offset);
+	intel_ring_advance(engine);
+
+	return 0;
+}
+
+/* Blitter support (SandyBridge+) */
+
+static int gen6_ring_flush(struct drm_i915_gem_request *req,
+			   u32 invalidate, u32 flush)
+{
+	struct intel_engine_cs *engine = req->engine;
+	struct drm_device *dev = engine->dev;
+	uint32_t cmd;
+	int ret;
+
+	ret = intel_ring_begin(req, 4);
+	if (ret)
+		return ret;
+
+	cmd = MI_FLUSH_DW;
+	if (INTEL_INFO(dev)->gen >= 8)
+		cmd += 1;
+
+	/* We always require a command barrier so that subsequent
+	 * commands, such as breadcrumb interrupts, are strictly ordered
+	 * wrt the contents of the write cache being flushed to memory
+	 * (and thus being coherent from the CPU).
+	 */
+	cmd |= MI_FLUSH_DW_STORE_INDEX | MI_FLUSH_DW_OP_STOREDW;
+
+	/*
+	 * Bspec vol 1c.3 - blitter engine command streamer:
+	 * "If ENABLED, all TLBs will be invalidated once the flush
+	 * operation is complete. This bit is only valid when the
+	 * Post-Sync Operation field is a value of 1h or 3h."
+	 */
+	if (invalidate & I915_GEM_DOMAIN_RENDER)
+		cmd |= MI_INVALIDATE_TLB;
+	intel_ring_emit(engine, cmd);
+	intel_ring_emit(engine,
+			I915_GEM_HWS_SCRATCH_ADDR | MI_FLUSH_DW_USE_GTT);
+	if (INTEL_INFO(dev)->gen >= 8) {
+		intel_ring_emit(engine, 0); /* upper addr */
+		intel_ring_emit(engine, 0); /* value */
+	} else  {
+		intel_ring_emit(engine, 0);
+		intel_ring_emit(engine, MI_NOOP);
+	}
+	intel_ring_advance(engine);
+
+	return 0;
+}
+
+int intel_init_render_ring_buffer(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_engine_cs *engine = &dev_priv->engine[RCS];
+	struct drm_i915_gem_object *obj;
+	int ret;
+
+	engine->name = "render ring";
+	engine->id = RCS;
+	engine->exec_id = I915_EXEC_RENDER;
+	engine->hw_id = 0;
+	engine->mmio_base = RENDER_RING_BASE;
+
+	if (INTEL_INFO(dev)->gen >= 8) {
+		if (i915_semaphore_is_enabled(dev)) {
+			obj = i915_gem_alloc_object(dev, 4096);
+			if (obj == NULL) {
+				DRM_ERROR("Failed to allocate semaphore bo. Disabling semaphores\n");
+				i915.semaphores = 0;
+			} else {
+				i915_gem_object_set_cache_level(obj, I915_CACHE_LLC);
+				ret = i915_gem_obj_ggtt_pin(obj, 0, PIN_NONBLOCK);
+				if (ret != 0) {
+					drm_gem_object_unreference(&obj->base);
+					DRM_ERROR("Failed to pin semaphore bo. Disabling semaphores\n");
+					i915.semaphores = 0;
+				} else
+					dev_priv->semaphore_obj = obj;
+			}
+		}
+
+		engine->init_context = intel_rcs_ctx_init;
+		engine->add_request = gen6_add_request;
+		engine->flush = gen8_render_ring_flush;
+		engine->irq_get = gen8_ring_get_irq;
+		engine->irq_put = gen8_ring_put_irq;
+		engine->irq_enable_mask = GT_RENDER_USER_INTERRUPT;
+		engine->irq_seqno_barrier = gen6_seqno_barrier;
+		engine->get_seqno = ring_get_seqno;
+		engine->set_seqno = ring_set_seqno;
+		if (i915_semaphore_is_enabled(dev)) {
+			WARN_ON(!dev_priv->semaphore_obj);
+			engine->semaphore.sync_to = gen8_ring_sync;
+			engine->semaphore.signal = gen8_rcs_signal;
+			GEN8_RING_SEMAPHORE_INIT(engine);
+		}
+	} else if (INTEL_INFO(dev)->gen >= 6) {
+		engine->init_context = intel_rcs_ctx_init;
+		engine->add_request = gen6_add_request;
+		engine->flush = gen7_render_ring_flush;
+		if (INTEL_INFO(dev)->gen == 6)
+			engine->flush = gen6_render_ring_flush;
+		engine->irq_get = gen6_ring_get_irq;
+		engine->irq_put = gen6_ring_put_irq;
+		engine->irq_enable_mask = GT_RENDER_USER_INTERRUPT;
+		engine->irq_seqno_barrier = gen6_seqno_barrier;
+		engine->get_seqno = ring_get_seqno;
+		engine->set_seqno = ring_set_seqno;
+		if (i915_semaphore_is_enabled(dev)) {
+			engine->semaphore.sync_to = gen6_ring_sync;
+			engine->semaphore.signal = gen6_signal;
+			/*
+			 * The current semaphore is only applied on pre-gen8
+			 * platform.  And there is no VCS2 ring on the pre-gen8
+			 * platform. So the semaphore between RCS and VCS2 is
+			 * initialized as INVALID.  Gen8 will initialize the
+			 * sema between VCS2 and RCS later.
+			 */
+			engine->semaphore.mbox.wait[RCS] = MI_SEMAPHORE_SYNC_INVALID;
+			engine->semaphore.mbox.wait[VCS] = MI_SEMAPHORE_SYNC_RV;
+			engine->semaphore.mbox.wait[BCS] = MI_SEMAPHORE_SYNC_RB;
+			engine->semaphore.mbox.wait[VECS] = MI_SEMAPHORE_SYNC_RVE;
+			engine->semaphore.mbox.wait[VCS2] = MI_SEMAPHORE_SYNC_INVALID;
+			engine->semaphore.mbox.signal[RCS] = GEN6_NOSYNC;
+			engine->semaphore.mbox.signal[VCS] = GEN6_VRSYNC;
+			engine->semaphore.mbox.signal[BCS] = GEN6_BRSYNC;
+			engine->semaphore.mbox.signal[VECS] = GEN6_VERSYNC;
+			engine->semaphore.mbox.signal[VCS2] = GEN6_NOSYNC;
+		}
+	} else if (IS_GEN5(dev)) {
+		engine->add_request = pc_render_add_request;
+		engine->flush = gen4_render_ring_flush;
+		engine->get_seqno = pc_render_get_seqno;
+		engine->set_seqno = pc_render_set_seqno;
+		engine->irq_get = gen5_ring_get_irq;
+		engine->irq_put = gen5_ring_put_irq;
+		engine->irq_enable_mask = GT_RENDER_USER_INTERRUPT |
+					GT_RENDER_PIPECTL_NOTIFY_INTERRUPT;
+	} else {
+		engine->add_request = i9xx_add_request;
+		if (INTEL_INFO(dev)->gen < 4)
+			engine->flush = gen2_render_ring_flush;
+		else
+			engine->flush = gen4_render_ring_flush;
+		engine->get_seqno = ring_get_seqno;
+		engine->set_seqno = ring_set_seqno;
+		if (IS_GEN2(dev)) {
+			engine->irq_get = i8xx_ring_get_irq;
+			engine->irq_put = i8xx_ring_put_irq;
+		} else {
+			engine->irq_get = i9xx_ring_get_irq;
+			engine->irq_put = i9xx_ring_put_irq;
+		}
+		engine->irq_enable_mask = I915_USER_INTERRUPT;
+	}
+	engine->write_tail = ring_write_tail;
+
+	if (IS_HASWELL(dev))
+		engine->dispatch_execbuffer = hsw_ring_dispatch_execbuffer;
+	else if (IS_GEN8(dev))
+		engine->dispatch_execbuffer = gen8_ring_dispatch_execbuffer;
+	else if (INTEL_INFO(dev)->gen >= 6)
+		engine->dispatch_execbuffer = gen6_ring_dispatch_execbuffer;
+	else if (INTEL_INFO(dev)->gen >= 4)
+		engine->dispatch_execbuffer = i965_dispatch_execbuffer;
+	else if (IS_I830(dev) || IS_845G(dev))
+		engine->dispatch_execbuffer = i830_dispatch_execbuffer;
+	else
+		engine->dispatch_execbuffer = i915_dispatch_execbuffer;
+	engine->init_hw = init_render_ring;
+	engine->cleanup = render_ring_cleanup;
+
+	/* Workaround batchbuffer to combat CS tlb bug. */
+	if (HAS_BROKEN_CS_TLB(dev)) {
+		obj = i915_gem_alloc_object(dev, I830_WA_SIZE);
+		if (obj == NULL) {
+			DRM_ERROR("Failed to allocate batch bo\n");
+			return -ENOMEM;
+		}
+
+		ret = i915_gem_obj_ggtt_pin(obj, 0, 0);
+		if (ret != 0) {
+			drm_gem_object_unreference(&obj->base);
+			DRM_ERROR("Failed to ping batch bo\n");
+			return ret;
+		}
+
+		engine->scratch.obj = obj;
+		engine->scratch.gtt_offset = i915_gem_obj_ggtt_offset(obj);
+	}
+
+	ret = intel_init_ring_buffer(dev, engine);
+	if (ret)
+		return ret;
+
+	if (INTEL_INFO(dev)->gen >= 5) {
+		ret = intel_init_pipe_control(engine);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
+int intel_init_bsd_ring_buffer(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_engine_cs *engine = &dev_priv->engine[VCS];
+
+	engine->name = "bsd ring";
+	engine->id = VCS;
+	engine->exec_id = I915_EXEC_BSD;
+	engine->hw_id = 1;
+
+	engine->write_tail = ring_write_tail;
+	if (INTEL_INFO(dev)->gen >= 6) {
+		engine->mmio_base = GEN6_BSD_RING_BASE;
+		/* gen6 bsd needs a special wa for tail updates */
+		if (IS_GEN6(dev))
+			engine->write_tail = gen6_bsd_ring_write_tail;
+		engine->flush = gen6_bsd_ring_flush;
+		engine->add_request = gen6_add_request;
+		engine->irq_seqno_barrier = gen6_seqno_barrier;
+		engine->get_seqno = ring_get_seqno;
+		engine->set_seqno = ring_set_seqno;
+		if (INTEL_INFO(dev)->gen >= 8) {
+			engine->irq_enable_mask =
+				GT_RENDER_USER_INTERRUPT << GEN8_VCS1_IRQ_SHIFT;
+			engine->irq_get = gen8_ring_get_irq;
+			engine->irq_put = gen8_ring_put_irq;
+			engine->dispatch_execbuffer =
+				gen8_ring_dispatch_execbuffer;
+			if (i915_semaphore_is_enabled(dev)) {
+				engine->semaphore.sync_to = gen8_ring_sync;
+				engine->semaphore.signal = gen8_xcs_signal;
+				GEN8_RING_SEMAPHORE_INIT(engine);
+			}
+		} else {
+			engine->irq_enable_mask = GT_BSD_USER_INTERRUPT;
+			engine->irq_get = gen6_ring_get_irq;
+			engine->irq_put = gen6_ring_put_irq;
+			engine->dispatch_execbuffer =
+				gen6_ring_dispatch_execbuffer;
+			if (i915_semaphore_is_enabled(dev)) {
+				engine->semaphore.sync_to = gen6_ring_sync;
+				engine->semaphore.signal = gen6_signal;
+				engine->semaphore.mbox.wait[RCS] = MI_SEMAPHORE_SYNC_VR;
+				engine->semaphore.mbox.wait[VCS] = MI_SEMAPHORE_SYNC_INVALID;
+				engine->semaphore.mbox.wait[BCS] = MI_SEMAPHORE_SYNC_VB;
+				engine->semaphore.mbox.wait[VECS] = MI_SEMAPHORE_SYNC_VVE;
+				engine->semaphore.mbox.wait[VCS2] = MI_SEMAPHORE_SYNC_INVALID;
+				engine->semaphore.mbox.signal[RCS] = GEN6_RVSYNC;
+				engine->semaphore.mbox.signal[VCS] = GEN6_NOSYNC;
+				engine->semaphore.mbox.signal[BCS] = GEN6_BVSYNC;
+				engine->semaphore.mbox.signal[VECS] = GEN6_VEVSYNC;
+				engine->semaphore.mbox.signal[VCS2] = GEN6_NOSYNC;
+			}
+		}
+	} else {
+		engine->mmio_base = BSD_RING_BASE;
+		engine->flush = bsd_ring_flush;
+		engine->add_request = i9xx_add_request;
+		engine->get_seqno = ring_get_seqno;
+		engine->set_seqno = ring_set_seqno;
+		if (IS_GEN5(dev)) {
+			engine->irq_enable_mask = ILK_BSD_USER_INTERRUPT;
+			engine->irq_get = gen5_ring_get_irq;
+			engine->irq_put = gen5_ring_put_irq;
+		} else {
+			engine->irq_enable_mask = I915_BSD_USER_INTERRUPT;
+			engine->irq_get = i9xx_ring_get_irq;
+			engine->irq_put = i9xx_ring_put_irq;
+		}
+		engine->dispatch_execbuffer = i965_dispatch_execbuffer;
+	}
+	engine->init_hw = init_ring_common;
+
+	return intel_init_ring_buffer(dev, engine);
+}
+
+/**
+ * Initialize the second BSD ring (eg. Broadwell GT3, Skylake GT3)
+ */
+int intel_init_bsd2_ring_buffer(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_engine_cs *engine = &dev_priv->engine[VCS2];
+
+	engine->name = "bsd2 ring";
+	engine->id = VCS2;
+	engine->exec_id = I915_EXEC_BSD;
+	engine->hw_id = 4;
+
+	engine->write_tail = ring_write_tail;
+	engine->mmio_base = GEN8_BSD2_RING_BASE;
+	engine->flush = gen6_bsd_ring_flush;
+	engine->add_request = gen6_add_request;
+	engine->irq_seqno_barrier = gen6_seqno_barrier;
+	engine->get_seqno = ring_get_seqno;
+	engine->set_seqno = ring_set_seqno;
+	engine->irq_enable_mask =
+			GT_RENDER_USER_INTERRUPT << GEN8_VCS2_IRQ_SHIFT;
+	engine->irq_get = gen8_ring_get_irq;
+	engine->irq_put = gen8_ring_put_irq;
+	engine->dispatch_execbuffer =
+			gen8_ring_dispatch_execbuffer;
+	if (i915_semaphore_is_enabled(dev)) {
+		engine->semaphore.sync_to = gen8_ring_sync;
+		engine->semaphore.signal = gen8_xcs_signal;
+		GEN8_RING_SEMAPHORE_INIT(engine);
+	}
+	engine->init_hw = init_ring_common;
+
+	return intel_init_ring_buffer(dev, engine);
+}
+
+int intel_init_blt_ring_buffer(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_engine_cs *engine = &dev_priv->engine[BCS];
+
+	engine->name = "blitter ring";
+	engine->id = BCS;
+	engine->exec_id = I915_EXEC_BLT;
+	engine->hw_id = 2;
+
+	engine->mmio_base = BLT_RING_BASE;
+	engine->write_tail = ring_write_tail;
+	engine->flush = gen6_ring_flush;
+	engine->add_request = gen6_add_request;
+	engine->irq_seqno_barrier = gen6_seqno_barrier;
+	engine->get_seqno = ring_get_seqno;
+	engine->set_seqno = ring_set_seqno;
+	if (INTEL_INFO(dev)->gen >= 8) {
+		engine->irq_enable_mask =
+			GT_RENDER_USER_INTERRUPT << GEN8_BCS_IRQ_SHIFT;
+		engine->irq_get = gen8_ring_get_irq;
+		engine->irq_put = gen8_ring_put_irq;
+		engine->dispatch_execbuffer = gen8_ring_dispatch_execbuffer;
+		if (i915_semaphore_is_enabled(dev)) {
+			engine->semaphore.sync_to = gen8_ring_sync;
+			engine->semaphore.signal = gen8_xcs_signal;
+			GEN8_RING_SEMAPHORE_INIT(engine);
+		}
+	} else {
+		engine->irq_enable_mask = GT_BLT_USER_INTERRUPT;
+		engine->irq_get = gen6_ring_get_irq;
+		engine->irq_put = gen6_ring_put_irq;
+		engine->dispatch_execbuffer = gen6_ring_dispatch_execbuffer;
+		if (i915_semaphore_is_enabled(dev)) {
+			engine->semaphore.signal = gen6_signal;
+			engine->semaphore.sync_to = gen6_ring_sync;
+			/*
+			 * The current semaphore is only applied on pre-gen8
+			 * platform.  And there is no VCS2 ring on the pre-gen8
+			 * platform. So the semaphore between BCS and VCS2 is
+			 * initialized as INVALID.  Gen8 will initialize the
+			 * sema between BCS and VCS2 later.
+			 */
+			engine->semaphore.mbox.wait[RCS] = MI_SEMAPHORE_SYNC_BR;
+			engine->semaphore.mbox.wait[VCS] = MI_SEMAPHORE_SYNC_BV;
+			engine->semaphore.mbox.wait[BCS] = MI_SEMAPHORE_SYNC_INVALID;
+			engine->semaphore.mbox.wait[VECS] = MI_SEMAPHORE_SYNC_BVE;
+			engine->semaphore.mbox.wait[VCS2] = MI_SEMAPHORE_SYNC_INVALID;
+			engine->semaphore.mbox.signal[RCS] = GEN6_RBSYNC;
+			engine->semaphore.mbox.signal[VCS] = GEN6_VBSYNC;
+			engine->semaphore.mbox.signal[BCS] = GEN6_NOSYNC;
+			engine->semaphore.mbox.signal[VECS] = GEN6_VEBSYNC;
+			engine->semaphore.mbox.signal[VCS2] = GEN6_NOSYNC;
+		}
+	}
+	engine->init_hw = init_ring_common;
+
+	return intel_init_ring_buffer(dev, engine);
+}
+
+int intel_init_vebox_ring_buffer(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_engine_cs *engine = &dev_priv->engine[VECS];
+
+	engine->name = "video enhancement ring";
+	engine->id = VECS;
+	engine->exec_id = I915_EXEC_VEBOX;
+	engine->hw_id = 3;
+
+	engine->mmio_base = VEBOX_RING_BASE;
+	engine->write_tail = ring_write_tail;
+	engine->flush = gen6_ring_flush;
+	engine->add_request = gen6_add_request;
+	engine->irq_seqno_barrier = gen6_seqno_barrier;
+	engine->get_seqno = ring_get_seqno;
+	engine->set_seqno = ring_set_seqno;
+
+	if (INTEL_INFO(dev)->gen >= 8) {
+		engine->irq_enable_mask =
+			GT_RENDER_USER_INTERRUPT << GEN8_VECS_IRQ_SHIFT;
+		engine->irq_get = gen8_ring_get_irq;
+		engine->irq_put = gen8_ring_put_irq;
+		engine->dispatch_execbuffer = gen8_ring_dispatch_execbuffer;
+		if (i915_semaphore_is_enabled(dev)) {
+			engine->semaphore.sync_to = gen8_ring_sync;
+			engine->semaphore.signal = gen8_xcs_signal;
+			GEN8_RING_SEMAPHORE_INIT(engine);
+		}
+	} else {
+		engine->irq_enable_mask = PM_VEBOX_USER_INTERRUPT;
+		engine->irq_get = hsw_vebox_get_irq;
+		engine->irq_put = hsw_vebox_put_irq;
+		engine->dispatch_execbuffer = gen6_ring_dispatch_execbuffer;
+		if (i915_semaphore_is_enabled(dev)) {
+			engine->semaphore.sync_to = gen6_ring_sync;
+			engine->semaphore.signal = gen6_signal;
+			engine->semaphore.mbox.wait[RCS] = MI_SEMAPHORE_SYNC_VER;
+			engine->semaphore.mbox.wait[VCS] = MI_SEMAPHORE_SYNC_VEV;
+			engine->semaphore.mbox.wait[BCS] = MI_SEMAPHORE_SYNC_VEB;
+			engine->semaphore.mbox.wait[VECS] = MI_SEMAPHORE_SYNC_INVALID;
+			engine->semaphore.mbox.wait[VCS2] = MI_SEMAPHORE_SYNC_INVALID;
+			engine->semaphore.mbox.signal[RCS] = GEN6_RVESYNC;
+			engine->semaphore.mbox.signal[VCS] = GEN6_VVESYNC;
+			engine->semaphore.mbox.signal[BCS] = GEN6_BVESYNC;
+			engine->semaphore.mbox.signal[VECS] = GEN6_NOSYNC;
+			engine->semaphore.mbox.signal[VCS2] = GEN6_NOSYNC;
+		}
+	}
+	engine->init_hw = init_ring_common;
+
+	return intel_init_ring_buffer(dev, engine);
+}
+
+int
+intel_ring_flush_all_caches(struct drm_i915_gem_request *req)
+{
+	struct intel_engine_cs *engine = req->engine;
+	int ret;
+
+	if (!engine->gpu_caches_dirty)
+		return 0;
+
+	ret = engine->flush(req, 0, I915_GEM_GPU_DOMAINS);
+	if (ret)
+		return ret;
+
+	trace_i915_gem_ring_flush(req, 0, I915_GEM_GPU_DOMAINS);
+
+	engine->gpu_caches_dirty = false;
+	return 0;
+}
+
+int
+intel_ring_invalidate_all_caches(struct drm_i915_gem_request *req)
+{
+	struct intel_engine_cs *engine = req->engine;
+	uint32_t flush_domains;
+	int ret;
+
+	flush_domains = 0;
+	if (engine->gpu_caches_dirty)
+		flush_domains = I915_GEM_GPU_DOMAINS;
+
+	ret = engine->flush(req, I915_GEM_GPU_DOMAINS, flush_domains);
+	if (ret)
+		return ret;
+
+	trace_i915_gem_ring_flush(req, I915_GEM_GPU_DOMAINS, flush_domains);
+
+	engine->gpu_caches_dirty = false;
+	return 0;
+}
+
+void
+intel_stop_engine(struct intel_engine_cs *engine)
+{
+	int ret;
+
+	if (!intel_engine_initialized(engine))
+		return;
+
+	ret = intel_engine_idle(engine);
+	if (ret)
+		DRM_ERROR("failed to quiesce %s whilst cleaning up: %d\n",
+			  engine->name, ret);
+
+	stop_ring(engine);
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/i915/intel_ringbuffer.h
@@ -0,0 +1,511 @@
+#ifndef _INTEL_RINGBUFFER_H_
+#define _INTEL_RINGBUFFER_H_
+
+#include <linux/hashtable.h>
+#include "i915_gem_batch_pool.h"
+
+#define I915_CMD_HASH_ORDER 9
+
+/* Early gen2 devices have a cacheline of just 32 bytes, using 64 is overkill,
+ * but keeps the logic simple. Indeed, the whole purpose of this macro is just
+ * to give some inclination as to some of the magic values used in the various
+ * workarounds!
+ */
+#define CACHELINE_BYTES 64
+#define CACHELINE_DWORDS (CACHELINE_BYTES / sizeof(uint32_t))
+
+/*
+ * Gen2 BSpec "1. Programming Environment" / 1.4.4.6 "Ring Buffer Use"
+ * Gen3 BSpec "vol1c Memory Interface Functions" / 2.3.4.5 "Ring Buffer Use"
+ * Gen4+ BSpec "vol1c Memory Interface and Command Stream" / 5.3.4.5 "Ring Buffer Use"
+ *
+ * "If the Ring Buffer Head Pointer and the Tail Pointer are on the same
+ * cacheline, the Head Pointer must not be greater than the Tail
+ * Pointer."
+ */
+#define I915_RING_FREE_SPACE 64
+
+struct  intel_hw_status_page {
+	u32		*page_addr;
+	unsigned int	gfx_addr;
+	struct		drm_i915_gem_object *obj;
+};
+
+#define I915_READ_TAIL(ring) I915_READ(RING_TAIL((ring)->mmio_base))
+#define I915_WRITE_TAIL(ring, val) I915_WRITE(RING_TAIL((ring)->mmio_base), val)
+
+#define I915_READ_START(ring) I915_READ(RING_START((ring)->mmio_base))
+#define I915_WRITE_START(ring, val) I915_WRITE(RING_START((ring)->mmio_base), val)
+
+#define I915_READ_HEAD(ring)  I915_READ(RING_HEAD((ring)->mmio_base))
+#define I915_WRITE_HEAD(ring, val) I915_WRITE(RING_HEAD((ring)->mmio_base), val)
+
+#define I915_READ_CTL(ring) I915_READ(RING_CTL((ring)->mmio_base))
+#define I915_WRITE_CTL(ring, val) I915_WRITE(RING_CTL((ring)->mmio_base), val)
+
+#define I915_READ_IMR(ring) I915_READ(RING_IMR((ring)->mmio_base))
+#define I915_WRITE_IMR(ring, val) I915_WRITE(RING_IMR((ring)->mmio_base), val)
+
+#define I915_READ_MODE(ring) I915_READ(RING_MI_MODE((ring)->mmio_base))
+#define I915_WRITE_MODE(ring, val) I915_WRITE(RING_MI_MODE((ring)->mmio_base), val)
+
+/* seqno size is actually only a uint32, but since we plan to use MI_FLUSH_DW to
+ * do the writes, and that must have qw aligned offsets, simply pretend it's 8b.
+ */
+#define gen8_semaphore_seqno_size sizeof(uint64_t)
+#define GEN8_SEMAPHORE_OFFSET(__from, __to)			     \
+	(((__from) * I915_NUM_ENGINES  + (__to)) * gen8_semaphore_seqno_size)
+#define GEN8_SIGNAL_OFFSET(__ring, to)			     \
+	(i915_gem_obj_ggtt_offset(dev_priv->semaphore_obj) + \
+	 GEN8_SEMAPHORE_OFFSET((__ring)->id, (to)))
+#define GEN8_WAIT_OFFSET(__ring, from)			     \
+	(i915_gem_obj_ggtt_offset(dev_priv->semaphore_obj) + \
+	 GEN8_SEMAPHORE_OFFSET(from, (__ring)->id))
+
+#define GEN8_RING_SEMAPHORE_INIT(e) do { \
+	if (!dev_priv->semaphore_obj) { \
+		break; \
+	} \
+	(e)->semaphore.signal_ggtt[RCS] = GEN8_SIGNAL_OFFSET((e), RCS); \
+	(e)->semaphore.signal_ggtt[VCS] = GEN8_SIGNAL_OFFSET((e), VCS); \
+	(e)->semaphore.signal_ggtt[BCS] = GEN8_SIGNAL_OFFSET((e), BCS); \
+	(e)->semaphore.signal_ggtt[VECS] = GEN8_SIGNAL_OFFSET((e), VECS); \
+	(e)->semaphore.signal_ggtt[VCS2] = GEN8_SIGNAL_OFFSET((e), VCS2); \
+	(e)->semaphore.signal_ggtt[(e)->id] = MI_SEMAPHORE_SYNC_INVALID; \
+	} while(0)
+
+enum intel_ring_hangcheck_action {
+	HANGCHECK_IDLE = 0,
+	HANGCHECK_WAIT,
+	HANGCHECK_ACTIVE,
+	HANGCHECK_KICK,
+	HANGCHECK_HUNG,
+};
+
+#define HANGCHECK_SCORE_RING_HUNG 31
+
+struct intel_ring_hangcheck {
+	u64 acthd;
+	u32 seqno;
+	unsigned user_interrupts;
+	int score;
+	enum intel_ring_hangcheck_action action;
+	int deadlock;
+	u32 instdone[I915_NUM_INSTDONE_REG];
+};
+
+struct intel_ringbuffer {
+	struct drm_i915_gem_object *obj;
+	void __iomem *virtual_start;
+	struct i915_vma *vma;
+
+	struct intel_engine_cs *engine;
+	struct list_head link;
+
+	u32 head;
+	u32 tail;
+	int space;
+	int size;
+	int effective_size;
+	int reserved_size;
+
+	/** We track the position of the requests in the ring buffer, and
+	 * when each is retired we increment last_retired_head as the GPU
+	 * must have finished processing the request and so we know we
+	 * can advance the ringbuffer up to that position.
+	 *
+	 * last_retired_head is set to -1 after the value is consumed so
+	 * we can detect new retirements.
+	 */
+	u32 last_retired_head;
+};
+
+struct	intel_context;
+struct drm_i915_reg_table;
+
+/*
+ * we use a single page to load ctx workarounds so all of these
+ * values are referred in terms of dwords
+ *
+ * struct i915_wa_ctx_bb:
+ *  offset: specifies batch starting position, also helpful in case
+ *    if we want to have multiple batches at different offsets based on
+ *    some criteria. It is not a requirement at the moment but provides
+ *    an option for future use.
+ *  size: size of the batch in DWORDS
+ */
+struct  i915_ctx_workarounds {
+	struct i915_wa_ctx_bb {
+		u32 offset;
+		u32 size;
+	} indirect_ctx, per_ctx;
+	struct drm_i915_gem_object *obj;
+};
+
+struct  intel_engine_cs {
+	const char	*name;
+	enum intel_engine_id {
+		RCS = 0,
+		BCS,
+		VCS,
+		VCS2,	/* Keep instances of the same type engine together. */
+		VECS
+	} id;
+#define I915_NUM_ENGINES 5
+#define _VCS(n) (VCS + (n))
+	unsigned int exec_id;
+	unsigned int hw_id;
+	unsigned int guc_id; /* XXX same as hw_id? */
+	u32		mmio_base;
+	struct		drm_device *dev;
+	struct intel_ringbuffer *buffer;
+	struct list_head buffers;
+
+	/*
+	 * A pool of objects to use as shadow copies of client batch buffers
+	 * when the command parser is enabled. Prevents the client from
+	 * modifying the batch contents after software parsing.
+	 */
+	struct i915_gem_batch_pool batch_pool;
+
+	struct intel_hw_status_page status_page;
+	struct i915_ctx_workarounds wa_ctx;
+
+	unsigned irq_refcount; /* protected by dev_priv->irq_lock */
+	u32		irq_enable_mask;	/* bitmask to enable ring interrupt */
+	struct drm_i915_gem_request *trace_irq_req;
+	bool __must_check (*irq_get)(struct intel_engine_cs *ring);
+	void		(*irq_put)(struct intel_engine_cs *ring);
+
+	int		(*init_hw)(struct intel_engine_cs *ring);
+
+	int		(*init_context)(struct drm_i915_gem_request *req);
+
+	void		(*write_tail)(struct intel_engine_cs *ring,
+				      u32 value);
+	int __must_check (*flush)(struct drm_i915_gem_request *req,
+				  u32	invalidate_domains,
+				  u32	flush_domains);
+	int		(*add_request)(struct drm_i915_gem_request *req);
+	/* Some chipsets are not quite as coherent as advertised and need
+	 * an expensive kick to force a true read of the up-to-date seqno.
+	 * However, the up-to-date seqno is not always required and the last
+	 * seen value is good enough. Note that the seqno will always be
+	 * monotonic, even if not coherent.
+	 */
+	void		(*irq_seqno_barrier)(struct intel_engine_cs *ring);
+	u32		(*get_seqno)(struct intel_engine_cs *ring);
+	void		(*set_seqno)(struct intel_engine_cs *ring,
+				     u32 seqno);
+	int		(*dispatch_execbuffer)(struct drm_i915_gem_request *req,
+					       u64 offset, u32 length,
+					       unsigned dispatch_flags);
+#define I915_DISPATCH_SECURE 0x1
+#define I915_DISPATCH_PINNED 0x2
+#define I915_DISPATCH_RS     0x4
+	void		(*cleanup)(struct intel_engine_cs *ring);
+
+	/* GEN8 signal/wait table - never trust comments!
+	 *	  signal to	signal to    signal to   signal to      signal to
+	 *	    RCS		   VCS          BCS        VECS		 VCS2
+	 *      --------------------------------------------------------------------
+	 *  RCS | NOP (0x00) | VCS (0x08) | BCS (0x10) | VECS (0x18) | VCS2 (0x20) |
+	 *	|-------------------------------------------------------------------
+	 *  VCS | RCS (0x28) | NOP (0x30) | BCS (0x38) | VECS (0x40) | VCS2 (0x48) |
+	 *	|-------------------------------------------------------------------
+	 *  BCS | RCS (0x50) | VCS (0x58) | NOP (0x60) | VECS (0x68) | VCS2 (0x70) |
+	 *	|-------------------------------------------------------------------
+	 * VECS | RCS (0x78) | VCS (0x80) | BCS (0x88) |  NOP (0x90) | VCS2 (0x98) |
+	 *	|-------------------------------------------------------------------
+	 * VCS2 | RCS (0xa0) | VCS (0xa8) | BCS (0xb0) | VECS (0xb8) | NOP  (0xc0) |
+	 *	|-------------------------------------------------------------------
+	 *
+	 * Generalization:
+	 *  f(x, y) := (x->id * NUM_RINGS * seqno_size) + (seqno_size * y->id)
+	 *  ie. transpose of g(x, y)
+	 *
+	 *	 sync from	sync from    sync from    sync from	sync from
+	 *	    RCS		   VCS          BCS        VECS		 VCS2
+	 *      --------------------------------------------------------------------
+	 *  RCS | NOP (0x00) | VCS (0x28) | BCS (0x50) | VECS (0x78) | VCS2 (0xa0) |
+	 *	|-------------------------------------------------------------------
+	 *  VCS | RCS (0x08) | NOP (0x30) | BCS (0x58) | VECS (0x80) | VCS2 (0xa8) |
+	 *	|-------------------------------------------------------------------
+	 *  BCS | RCS (0x10) | VCS (0x38) | NOP (0x60) | VECS (0x88) | VCS2 (0xb0) |
+	 *	|-------------------------------------------------------------------
+	 * VECS | RCS (0x18) | VCS (0x40) | BCS (0x68) |  NOP (0x90) | VCS2 (0xb8) |
+	 *	|-------------------------------------------------------------------
+	 * VCS2 | RCS (0x20) | VCS (0x48) | BCS (0x70) | VECS (0x98) |  NOP (0xc0) |
+	 *	|-------------------------------------------------------------------
+	 *
+	 * Generalization:
+	 *  g(x, y) := (y->id * NUM_RINGS * seqno_size) + (seqno_size * x->id)
+	 *  ie. transpose of f(x, y)
+	 */
+	struct {
+		u32	sync_seqno[I915_NUM_ENGINES-1];
+
+		union {
+			struct {
+				/* our mbox written by others */
+				u32		wait[I915_NUM_ENGINES];
+				/* mboxes this ring signals to */
+				i915_reg_t	signal[I915_NUM_ENGINES];
+			} mbox;
+			u64		signal_ggtt[I915_NUM_ENGINES];
+		};
+
+		/* AKA wait() */
+		int	(*sync_to)(struct drm_i915_gem_request *to_req,
+				   struct intel_engine_cs *from,
+				   u32 seqno);
+		int	(*signal)(struct drm_i915_gem_request *signaller_req,
+				  /* num_dwords needed by caller */
+				  unsigned int num_dwords);
+	} semaphore;
+
+	/* Execlists */
+	struct tasklet_struct irq_tasklet;
+	spinlock_t execlist_lock; /* used inside tasklet, use spin_lock_bh */
+	struct list_head execlist_queue;
+	struct list_head execlist_retired_req_list;
+	unsigned int fw_domains;
+	unsigned int next_context_status_buffer;
+	unsigned int idle_lite_restore_wa;
+	bool disable_lite_restore_wa;
+	u32 ctx_desc_template;
+	u32             irq_keep_mask; /* bitmask for interrupts that should not be masked */
+	int		(*emit_request)(struct drm_i915_gem_request *request);
+	int		(*emit_flush)(struct drm_i915_gem_request *request,
+				      u32 invalidate_domains,
+				      u32 flush_domains);
+	int		(*emit_bb_start)(struct drm_i915_gem_request *req,
+					 u64 offset, unsigned dispatch_flags);
+
+	/**
+	 * List of objects currently involved in rendering from the
+	 * ringbuffer.
+	 *
+	 * Includes buffers having the contents of their GPU caches
+	 * flushed, not necessarily primitives.  last_read_req
+	 * represents when the rendering involved will be completed.
+	 *
+	 * A reference is held on the buffer while on this list.
+	 */
+	struct list_head active_list;
+
+	/**
+	 * List of breadcrumbs associated with GPU requests currently
+	 * outstanding.
+	 */
+	struct list_head request_list;
+
+	/**
+	 * Seqno of request most recently submitted to request_list.
+	 * Used exclusively by hang checker to avoid grabbing lock while
+	 * inspecting request list.
+	 */
+	u32 last_submitted_seqno;
+	unsigned user_interrupts;
+
+	bool gpu_caches_dirty;
+
+	wait_queue_head_t irq_queue;
+
+	struct intel_context *last_context;
+
+	struct intel_ring_hangcheck hangcheck;
+
+	struct {
+		struct drm_i915_gem_object *obj;
+		u32 gtt_offset;
+		volatile u32 *cpu_page;
+	} scratch;
+
+	bool needs_cmd_parser;
+
+	/*
+	 * Table of commands the command parser needs to know about
+	 * for this ring.
+	 */
+	DECLARE_HASHTABLE(cmd_hash, I915_CMD_HASH_ORDER);
+
+	/*
+	 * Table of registers allowed in commands that read/write registers.
+	 */
+	const struct drm_i915_reg_table *reg_tables;
+	int reg_table_count;
+
+	/*
+	 * Returns the bitmask for the length field of the specified command.
+	 * Return 0 for an unrecognized/invalid command.
+	 *
+	 * If the command parser finds an entry for a command in the ring's
+	 * cmd_tables, it gets the command's length based on the table entry.
+	 * If not, it calls this function to determine the per-ring length field
+	 * encoding for the command (i.e. certain opcode ranges use certain bits
+	 * to encode the command length in the header).
+	 */
+	u32 (*get_cmd_length_mask)(u32 cmd_header);
+};
+
+static inline bool
+intel_engine_initialized(struct intel_engine_cs *engine)
+{
+	return engine->dev != NULL;
+}
+
+static inline unsigned
+intel_engine_flag(struct intel_engine_cs *engine)
+{
+	return 1 << engine->id;
+}
+
+static inline u32
+intel_ring_sync_index(struct intel_engine_cs *engine,
+		      struct intel_engine_cs *other)
+{
+	int idx;
+
+	/*
+	 * rcs -> 0 = vcs, 1 = bcs, 2 = vecs, 3 = vcs2;
+	 * vcs -> 0 = bcs, 1 = vecs, 2 = vcs2, 3 = rcs;
+	 * bcs -> 0 = vecs, 1 = vcs2. 2 = rcs, 3 = vcs;
+	 * vecs -> 0 = vcs2, 1 = rcs, 2 = vcs, 3 = bcs;
+	 * vcs2 -> 0 = rcs, 1 = vcs, 2 = bcs, 3 = vecs;
+	 */
+
+	idx = (other - engine) - 1;
+	if (idx < 0)
+		idx += I915_NUM_ENGINES;
+
+	return idx;
+}
+
+static inline void
+intel_flush_status_page(struct intel_engine_cs *engine, int reg)
+{
+	mb();
+	clflush(&engine->status_page.page_addr[reg]);
+	mb();
+}
+
+static inline u32
+intel_read_status_page(struct intel_engine_cs *engine, int reg)
+{
+	/* Ensure that the compiler doesn't optimize away the load. */
+	return READ_ONCE(engine->status_page.page_addr[reg]);
+}
+
+static inline void
+intel_write_status_page(struct intel_engine_cs *engine,
+			int reg, u32 value)
+{
+	engine->status_page.page_addr[reg] = value;
+}
+
+/*
+ * Reads a dword out of the status page, which is written to from the command
+ * queue by automatic updates, MI_REPORT_HEAD, MI_STORE_DATA_INDEX, or
+ * MI_STORE_DATA_IMM.
+ *
+ * The following dwords have a reserved meaning:
+ * 0x00: ISR copy, updated when an ISR bit not set in the HWSTAM changes.
+ * 0x04: ring 0 head pointer
+ * 0x05: ring 1 head pointer (915-class)
+ * 0x06: ring 2 head pointer (915-class)
+ * 0x10-0x1b: Context status DWords (GM45)
+ * 0x1f: Last written status offset. (GM45)
+ * 0x20-0x2f: Reserved (Gen6+)
+ *
+ * The area from dword 0x30 to 0x3ff is available for driver usage.
+ */
+#define I915_GEM_HWS_INDEX		0x30
+#define I915_GEM_HWS_INDEX_ADDR (I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT)
+#define I915_GEM_HWS_SCRATCH_INDEX	0x40
+#define I915_GEM_HWS_SCRATCH_ADDR (I915_GEM_HWS_SCRATCH_INDEX << MI_STORE_DWORD_INDEX_SHIFT)
+
+struct intel_ringbuffer *
+intel_engine_create_ringbuffer(struct intel_engine_cs *engine, int size);
+int intel_pin_and_map_ringbuffer_obj(struct drm_device *dev,
+				     struct intel_ringbuffer *ringbuf);
+void intel_unpin_ringbuffer_obj(struct intel_ringbuffer *ringbuf);
+void intel_ringbuffer_free(struct intel_ringbuffer *ring);
+
+void intel_stop_engine(struct intel_engine_cs *engine);
+void intel_cleanup_engine(struct intel_engine_cs *engine);
+
+int intel_ring_alloc_request_extras(struct drm_i915_gem_request *request);
+
+int __must_check intel_ring_begin(struct drm_i915_gem_request *req, int n);
+int __must_check intel_ring_cacheline_align(struct drm_i915_gem_request *req);
+static inline void intel_ring_emit(struct intel_engine_cs *engine,
+				   u32 data)
+{
+	struct intel_ringbuffer *ringbuf = engine->buffer;
+	iowrite32(data, ringbuf->virtual_start + ringbuf->tail);
+	ringbuf->tail += 4;
+}
+static inline void intel_ring_emit_reg(struct intel_engine_cs *engine,
+				       i915_reg_t reg)
+{
+	intel_ring_emit(engine, i915_mmio_reg_offset(reg));
+}
+static inline void intel_ring_advance(struct intel_engine_cs *engine)
+{
+	struct intel_ringbuffer *ringbuf = engine->buffer;
+	ringbuf->tail &= ringbuf->size - 1;
+}
+int __intel_ring_space(int head, int tail, int size);
+void intel_ring_update_space(struct intel_ringbuffer *ringbuf);
+bool intel_engine_stopped(struct intel_engine_cs *engine);
+
+int __must_check intel_engine_idle(struct intel_engine_cs *engine);
+void intel_ring_init_seqno(struct intel_engine_cs *engine, u32 seqno);
+int intel_ring_flush_all_caches(struct drm_i915_gem_request *req);
+int intel_ring_invalidate_all_caches(struct drm_i915_gem_request *req);
+
+void intel_fini_pipe_control(struct intel_engine_cs *engine);
+int intel_init_pipe_control(struct intel_engine_cs *engine);
+
+int intel_init_render_ring_buffer(struct drm_device *dev);
+int intel_init_bsd_ring_buffer(struct drm_device *dev);
+int intel_init_bsd2_ring_buffer(struct drm_device *dev);
+int intel_init_blt_ring_buffer(struct drm_device *dev);
+int intel_init_vebox_ring_buffer(struct drm_device *dev);
+
+u64 intel_ring_get_active_head(struct intel_engine_cs *engine);
+
+int init_workarounds_ring(struct intel_engine_cs *engine);
+
+static inline u32 intel_ring_get_tail(struct intel_ringbuffer *ringbuf)
+{
+	return ringbuf->tail;
+}
+
+/*
+ * Arbitrary size for largest possible 'add request' sequence. The code paths
+ * are complex and variable. Empirical measurement shows that the worst case
+ * is ILK at 136 words. Reserving too much is better than reserving too little
+ * as that allows for corner cases that might have been missed. So the figure
+ * has been rounded up to 160 words.
+ */
+#define MIN_SPACE_FOR_ADD_REQUEST	160
+
+/*
+ * Reserve space in the ring to guarantee that the i915_add_request() call
+ * will always have sufficient room to do its stuff. The request creation
+ * code calls this automatically.
+ */
+void intel_ring_reserved_space_reserve(struct intel_ringbuffer *ringbuf, int size);
+/* Cancel the reservation, e.g. because the request is being discarded. */
+void intel_ring_reserved_space_cancel(struct intel_ringbuffer *ringbuf);
+/* Use the reserved space - for use by i915_add_request() only. */
+void intel_ring_reserved_space_use(struct intel_ringbuffer *ringbuf);
+/* Finish with the reserved space - for use by i915_add_request() only. */
+void intel_ring_reserved_space_end(struct intel_ringbuffer *ringbuf);
+
+/* Legacy ringbuffer specific portion of reservation code: */
+int intel_ring_reserve_space(struct drm_i915_gem_request *request);
+
+#endif /* _INTEL_RINGBUFFER_H_ */
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/i915/intel_runtime_pm.c
@@ -0,0 +1,2605 @@
+/*
+ * Copyright © 2012-2014 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Eugeni Dodonov <eugeni.dodonov@intel.com>
+ *    Daniel Vetter <daniel.vetter@ffwll.ch>
+ *
+ */
+
+#include <linux/pm_runtime.h>
+#include <linux/vgaarb.h>
+
+#include "i915_drv.h"
+#include "intel_drv.h"
+
+/**
+ * DOC: runtime pm
+ *
+ * The i915 driver supports dynamic enabling and disabling of entire hardware
+ * blocks at runtime. This is especially important on the display side where
+ * software is supposed to control many power gates manually on recent hardware,
+ * since on the GT side a lot of the power management is done by the hardware.
+ * But even there some manual control at the device level is required.
+ *
+ * Since i915 supports a diverse set of platforms with a unified codebase and
+ * hardware engineers just love to shuffle functionality around between power
+ * domains there's a sizeable amount of indirection required. This file provides
+ * generic functions to the driver for grabbing and releasing references for
+ * abstract power domains. It then maps those to the actual power wells
+ * present for a given platform.
+ */
+
+#define for_each_power_well(i, power_well, domain_mask, power_domains)	\
+	for (i = 0;							\
+	     i < (power_domains)->power_well_count &&			\
+		 ((power_well) = &(power_domains)->power_wells[i]);	\
+	     i++)							\
+		for_each_if ((power_well)->domains & (domain_mask))
+
+#define for_each_power_well_rev(i, power_well, domain_mask, power_domains) \
+	for (i = (power_domains)->power_well_count - 1;			 \
+	     i >= 0 && ((power_well) = &(power_domains)->power_wells[i]);\
+	     i--)							 \
+		for_each_if ((power_well)->domains & (domain_mask))
+
+bool intel_display_power_well_is_enabled(struct drm_i915_private *dev_priv,
+				    int power_well_id);
+
+const char *
+intel_display_power_domain_str(enum intel_display_power_domain domain)
+{
+	switch (domain) {
+	case POWER_DOMAIN_PIPE_A:
+		return "PIPE_A";
+	case POWER_DOMAIN_PIPE_B:
+		return "PIPE_B";
+	case POWER_DOMAIN_PIPE_C:
+		return "PIPE_C";
+	case POWER_DOMAIN_PIPE_A_PANEL_FITTER:
+		return "PIPE_A_PANEL_FITTER";
+	case POWER_DOMAIN_PIPE_B_PANEL_FITTER:
+		return "PIPE_B_PANEL_FITTER";
+	case POWER_DOMAIN_PIPE_C_PANEL_FITTER:
+		return "PIPE_C_PANEL_FITTER";
+	case POWER_DOMAIN_TRANSCODER_A:
+		return "TRANSCODER_A";
+	case POWER_DOMAIN_TRANSCODER_B:
+		return "TRANSCODER_B";
+	case POWER_DOMAIN_TRANSCODER_C:
+		return "TRANSCODER_C";
+	case POWER_DOMAIN_TRANSCODER_EDP:
+		return "TRANSCODER_EDP";
+	case POWER_DOMAIN_TRANSCODER_DSI_A:
+		return "TRANSCODER_DSI_A";
+	case POWER_DOMAIN_TRANSCODER_DSI_C:
+		return "TRANSCODER_DSI_C";
+	case POWER_DOMAIN_PORT_DDI_A_LANES:
+		return "PORT_DDI_A_LANES";
+	case POWER_DOMAIN_PORT_DDI_B_LANES:
+		return "PORT_DDI_B_LANES";
+	case POWER_DOMAIN_PORT_DDI_C_LANES:
+		return "PORT_DDI_C_LANES";
+	case POWER_DOMAIN_PORT_DDI_D_LANES:
+		return "PORT_DDI_D_LANES";
+	case POWER_DOMAIN_PORT_DDI_E_LANES:
+		return "PORT_DDI_E_LANES";
+	case POWER_DOMAIN_PORT_DSI:
+		return "PORT_DSI";
+	case POWER_DOMAIN_PORT_CRT:
+		return "PORT_CRT";
+	case POWER_DOMAIN_PORT_OTHER:
+		return "PORT_OTHER";
+	case POWER_DOMAIN_VGA:
+		return "VGA";
+	case POWER_DOMAIN_AUDIO:
+		return "AUDIO";
+	case POWER_DOMAIN_PLLS:
+		return "PLLS";
+	case POWER_DOMAIN_AUX_A:
+		return "AUX_A";
+	case POWER_DOMAIN_AUX_B:
+		return "AUX_B";
+	case POWER_DOMAIN_AUX_C:
+		return "AUX_C";
+	case POWER_DOMAIN_AUX_D:
+		return "AUX_D";
+	case POWER_DOMAIN_GMBUS:
+		return "GMBUS";
+	case POWER_DOMAIN_INIT:
+		return "INIT";
+	case POWER_DOMAIN_MODESET:
+		return "MODESET";
+	default:
+		MISSING_CASE(domain);
+		return "?";
+	}
+}
+
+static void intel_power_well_enable(struct drm_i915_private *dev_priv,
+				    struct i915_power_well *power_well)
+{
+	DRM_DEBUG_KMS("enabling %s\n", power_well->name);
+	power_well->ops->enable(dev_priv, power_well);
+	power_well->hw_enabled = true;
+}
+
+static void intel_power_well_disable(struct drm_i915_private *dev_priv,
+				     struct i915_power_well *power_well)
+{
+	DRM_DEBUG_KMS("disabling %s\n", power_well->name);
+	power_well->hw_enabled = false;
+	power_well->ops->disable(dev_priv, power_well);
+}
+
+/*
+ * We should only use the power well if we explicitly asked the hardware to
+ * enable it, so check if it's enabled and also check if we've requested it to
+ * be enabled.
+ */
+static bool hsw_power_well_enabled(struct drm_i915_private *dev_priv,
+				   struct i915_power_well *power_well)
+{
+	return I915_READ(HSW_PWR_WELL_DRIVER) ==
+		     (HSW_PWR_WELL_ENABLE_REQUEST | HSW_PWR_WELL_STATE_ENABLED);
+}
+
+/**
+ * __intel_display_power_is_enabled - unlocked check for a power domain
+ * @dev_priv: i915 device instance
+ * @domain: power domain to check
+ *
+ * This is the unlocked version of intel_display_power_is_enabled() and should
+ * only be used from error capture and recovery code where deadlocks are
+ * possible.
+ *
+ * Returns:
+ * True when the power domain is enabled, false otherwise.
+ */
+bool __intel_display_power_is_enabled(struct drm_i915_private *dev_priv,
+				      enum intel_display_power_domain domain)
+{
+	struct i915_power_domains *power_domains;
+	struct i915_power_well *power_well;
+	bool is_enabled;
+	int i;
+
+	if (dev_priv->pm.suspended)
+		return false;
+
+	power_domains = &dev_priv->power_domains;
+
+	is_enabled = true;
+
+	for_each_power_well_rev(i, power_well, BIT(domain), power_domains) {
+		if (power_well->always_on)
+			continue;
+
+		if (!power_well->hw_enabled) {
+			is_enabled = false;
+			break;
+		}
+	}
+
+	return is_enabled;
+}
+
+/**
+ * intel_display_power_is_enabled - check for a power domain
+ * @dev_priv: i915 device instance
+ * @domain: power domain to check
+ *
+ * This function can be used to check the hw power domain state. It is mostly
+ * used in hardware state readout functions. Everywhere else code should rely
+ * upon explicit power domain reference counting to ensure that the hardware
+ * block is powered up before accessing it.
+ *
+ * Callers must hold the relevant modesetting locks to ensure that concurrent
+ * threads can't disable the power well while the caller tries to read a few
+ * registers.
+ *
+ * Returns:
+ * True when the power domain is enabled, false otherwise.
+ */
+bool intel_display_power_is_enabled(struct drm_i915_private *dev_priv,
+				    enum intel_display_power_domain domain)
+{
+	struct i915_power_domains *power_domains;
+	bool ret;
+
+	power_domains = &dev_priv->power_domains;
+
+	mutex_lock(&power_domains->lock);
+	ret = __intel_display_power_is_enabled(dev_priv, domain);
+	mutex_unlock(&power_domains->lock);
+
+	return ret;
+}
+
+/**
+ * intel_display_set_init_power - set the initial power domain state
+ * @dev_priv: i915 device instance
+ * @enable: whether to enable or disable the initial power domain state
+ *
+ * For simplicity our driver load/unload and system suspend/resume code assumes
+ * that all power domains are always enabled. This functions controls the state
+ * of this little hack. While the initial power domain state is enabled runtime
+ * pm is effectively disabled.
+ */
+void intel_display_set_init_power(struct drm_i915_private *dev_priv,
+				  bool enable)
+{
+	if (dev_priv->power_domains.init_power_on == enable)
+		return;
+
+	if (enable)
+		intel_display_power_get(dev_priv, POWER_DOMAIN_INIT);
+	else
+		intel_display_power_put(dev_priv, POWER_DOMAIN_INIT);
+
+	dev_priv->power_domains.init_power_on = enable;
+}
+
+/*
+ * Starting with Haswell, we have a "Power Down Well" that can be turned off
+ * when not needed anymore. We have 4 registers that can request the power well
+ * to be enabled, and it will only be disabled if none of the registers is
+ * requesting it to be enabled.
+ */
+static void hsw_power_well_post_enable(struct drm_i915_private *dev_priv)
+{
+	struct drm_device *dev = dev_priv->dev;
+
+	/*
+	 * After we re-enable the power well, if we touch VGA register 0x3d5
+	 * we'll get unclaimed register interrupts. This stops after we write
+	 * anything to the VGA MSR register. The vgacon module uses this
+	 * register all the time, so if we unbind our driver and, as a
+	 * consequence, bind vgacon, we'll get stuck in an infinite loop at
+	 * console_unlock(). So make here we touch the VGA MSR register, making
+	 * sure vgacon can keep working normally without triggering interrupts
+	 * and error messages.
+	 */
+	vga_get_uninterruptible(dev->pdev, VGA_RSRC_LEGACY_IO);
+	outb(inb(VGA_MSR_READ), VGA_MSR_WRITE);
+	vga_put(dev->pdev, VGA_RSRC_LEGACY_IO);
+
+	if (IS_BROADWELL(dev))
+		gen8_irq_power_well_post_enable(dev_priv,
+						1 << PIPE_C | 1 << PIPE_B);
+}
+
+static void hsw_power_well_pre_disable(struct drm_i915_private *dev_priv)
+{
+	if (IS_BROADWELL(dev_priv))
+		gen8_irq_power_well_pre_disable(dev_priv,
+						1 << PIPE_C | 1 << PIPE_B);
+}
+
+static void skl_power_well_post_enable(struct drm_i915_private *dev_priv,
+				       struct i915_power_well *power_well)
+{
+	struct drm_device *dev = dev_priv->dev;
+
+	/*
+	 * After we re-enable the power well, if we touch VGA register 0x3d5
+	 * we'll get unclaimed register interrupts. This stops after we write
+	 * anything to the VGA MSR register. The vgacon module uses this
+	 * register all the time, so if we unbind our driver and, as a
+	 * consequence, bind vgacon, we'll get stuck in an infinite loop at
+	 * console_unlock(). So make here we touch the VGA MSR register, making
+	 * sure vgacon can keep working normally without triggering interrupts
+	 * and error messages.
+	 */
+	if (power_well->data == SKL_DISP_PW_2) {
+		vga_get_uninterruptible(dev->pdev, VGA_RSRC_LEGACY_IO);
+		outb(inb(VGA_MSR_READ), VGA_MSR_WRITE);
+		vga_put(dev->pdev, VGA_RSRC_LEGACY_IO);
+
+		gen8_irq_power_well_post_enable(dev_priv,
+						1 << PIPE_C | 1 << PIPE_B);
+	}
+}
+
+static void skl_power_well_pre_disable(struct drm_i915_private *dev_priv,
+				       struct i915_power_well *power_well)
+{
+	if (power_well->data == SKL_DISP_PW_2)
+		gen8_irq_power_well_pre_disable(dev_priv,
+						1 << PIPE_C | 1 << PIPE_B);
+}
+
+static void hsw_set_power_well(struct drm_i915_private *dev_priv,
+			       struct i915_power_well *power_well, bool enable)
+{
+	bool is_enabled, enable_requested;
+	uint32_t tmp;
+
+	tmp = I915_READ(HSW_PWR_WELL_DRIVER);
+	is_enabled = tmp & HSW_PWR_WELL_STATE_ENABLED;
+	enable_requested = tmp & HSW_PWR_WELL_ENABLE_REQUEST;
+
+	if (enable) {
+		if (!enable_requested)
+			I915_WRITE(HSW_PWR_WELL_DRIVER,
+				   HSW_PWR_WELL_ENABLE_REQUEST);
+
+		if (!is_enabled) {
+			DRM_DEBUG_KMS("Enabling power well\n");
+			if (wait_for((I915_READ(HSW_PWR_WELL_DRIVER) &
+				      HSW_PWR_WELL_STATE_ENABLED), 20))
+				DRM_ERROR("Timeout enabling power well\n");
+			hsw_power_well_post_enable(dev_priv);
+		}
+
+	} else {
+		if (enable_requested) {
+			hsw_power_well_pre_disable(dev_priv);
+			I915_WRITE(HSW_PWR_WELL_DRIVER, 0);
+			POSTING_READ(HSW_PWR_WELL_DRIVER);
+			DRM_DEBUG_KMS("Requesting to disable the power well\n");
+		}
+	}
+}
+
+#define SKL_DISPLAY_POWERWELL_2_POWER_DOMAINS (		\
+	BIT(POWER_DOMAIN_TRANSCODER_A) |		\
+	BIT(POWER_DOMAIN_PIPE_B) |			\
+	BIT(POWER_DOMAIN_TRANSCODER_B) |		\
+	BIT(POWER_DOMAIN_PIPE_C) |			\
+	BIT(POWER_DOMAIN_TRANSCODER_C) |		\
+	BIT(POWER_DOMAIN_PIPE_B_PANEL_FITTER) |		\
+	BIT(POWER_DOMAIN_PIPE_C_PANEL_FITTER) |		\
+	BIT(POWER_DOMAIN_PORT_DDI_B_LANES) |		\
+	BIT(POWER_DOMAIN_PORT_DDI_C_LANES) |		\
+	BIT(POWER_DOMAIN_PORT_DDI_D_LANES) |		\
+	BIT(POWER_DOMAIN_PORT_DDI_E_LANES) |		\
+	BIT(POWER_DOMAIN_AUX_B) |                       \
+	BIT(POWER_DOMAIN_AUX_C) |			\
+	BIT(POWER_DOMAIN_AUX_D) |			\
+	BIT(POWER_DOMAIN_AUDIO) |			\
+	BIT(POWER_DOMAIN_VGA) |				\
+	BIT(POWER_DOMAIN_INIT))
+#define SKL_DISPLAY_DDI_A_E_POWER_DOMAINS (		\
+	BIT(POWER_DOMAIN_PORT_DDI_A_LANES) |		\
+	BIT(POWER_DOMAIN_PORT_DDI_E_LANES) |		\
+	BIT(POWER_DOMAIN_INIT))
+#define SKL_DISPLAY_DDI_B_POWER_DOMAINS (		\
+	BIT(POWER_DOMAIN_PORT_DDI_B_LANES) |		\
+	BIT(POWER_DOMAIN_INIT))
+#define SKL_DISPLAY_DDI_C_POWER_DOMAINS (		\
+	BIT(POWER_DOMAIN_PORT_DDI_C_LANES) |		\
+	BIT(POWER_DOMAIN_INIT))
+#define SKL_DISPLAY_DDI_D_POWER_DOMAINS (		\
+	BIT(POWER_DOMAIN_PORT_DDI_D_LANES) |		\
+	BIT(POWER_DOMAIN_INIT))
+#define SKL_DISPLAY_DC_OFF_POWER_DOMAINS (		\
+	SKL_DISPLAY_POWERWELL_2_POWER_DOMAINS |		\
+	BIT(POWER_DOMAIN_MODESET) |			\
+	BIT(POWER_DOMAIN_AUX_A) |			\
+	BIT(POWER_DOMAIN_INIT))
+
+#define BXT_DISPLAY_POWERWELL_2_POWER_DOMAINS (		\
+	BIT(POWER_DOMAIN_TRANSCODER_A) |		\
+	BIT(POWER_DOMAIN_PIPE_B) |			\
+	BIT(POWER_DOMAIN_TRANSCODER_B) |		\
+	BIT(POWER_DOMAIN_PIPE_C) |			\
+	BIT(POWER_DOMAIN_TRANSCODER_C) |		\
+	BIT(POWER_DOMAIN_PIPE_B_PANEL_FITTER) |		\
+	BIT(POWER_DOMAIN_PIPE_C_PANEL_FITTER) |		\
+	BIT(POWER_DOMAIN_PORT_DDI_B_LANES) |		\
+	BIT(POWER_DOMAIN_PORT_DDI_C_LANES) |		\
+	BIT(POWER_DOMAIN_AUX_B) |			\
+	BIT(POWER_DOMAIN_AUX_C) |			\
+	BIT(POWER_DOMAIN_AUDIO) |			\
+	BIT(POWER_DOMAIN_VGA) |				\
+	BIT(POWER_DOMAIN_GMBUS) |			\
+	BIT(POWER_DOMAIN_INIT))
+#define BXT_DISPLAY_DC_OFF_POWER_DOMAINS (		\
+	BXT_DISPLAY_POWERWELL_2_POWER_DOMAINS |		\
+	BIT(POWER_DOMAIN_MODESET) |			\
+	BIT(POWER_DOMAIN_AUX_A) |			\
+	BIT(POWER_DOMAIN_INIT))
+
+static void assert_can_enable_dc9(struct drm_i915_private *dev_priv)
+{
+	WARN_ONCE((I915_READ(DC_STATE_EN) & DC_STATE_EN_DC9),
+		  "DC9 already programmed to be enabled.\n");
+	WARN_ONCE(I915_READ(DC_STATE_EN) & DC_STATE_EN_UPTO_DC5,
+		  "DC5 still not disabled to enable DC9.\n");
+	WARN_ONCE(I915_READ(HSW_PWR_WELL_DRIVER), "Power well on.\n");
+	WARN_ONCE(intel_irqs_enabled(dev_priv),
+		  "Interrupts not disabled yet.\n");
+
+	 /*
+	  * TODO: check for the following to verify the conditions to enter DC9
+	  * state are satisfied:
+	  * 1] Check relevant display engine registers to verify if mode set
+	  * disable sequence was followed.
+	  * 2] Check if display uninitialize sequence is initialized.
+	  */
+}
+
+static void assert_can_disable_dc9(struct drm_i915_private *dev_priv)
+{
+	WARN_ONCE(intel_irqs_enabled(dev_priv),
+		  "Interrupts not disabled yet.\n");
+	WARN_ONCE(I915_READ(DC_STATE_EN) & DC_STATE_EN_UPTO_DC5,
+		  "DC5 still not disabled.\n");
+
+	 /*
+	  * TODO: check for the following to verify DC9 state was indeed
+	  * entered before programming to disable it:
+	  * 1] Check relevant display engine registers to verify if mode
+	  *  set disable sequence was followed.
+	  * 2] Check if display uninitialize sequence is initialized.
+	  */
+}
+
+static void gen9_write_dc_state(struct drm_i915_private *dev_priv,
+				u32 state)
+{
+	int rewrites = 0;
+	int rereads = 0;
+	u32 v;
+
+	I915_WRITE(DC_STATE_EN, state);
+
+	/* It has been observed that disabling the dc6 state sometimes
+	 * doesn't stick and dmc keeps returning old value. Make sure
+	 * the write really sticks enough times and also force rewrite until
+	 * we are confident that state is exactly what we want.
+	 */
+	do  {
+		v = I915_READ(DC_STATE_EN);
+
+		if (v != state) {
+			I915_WRITE(DC_STATE_EN, state);
+			rewrites++;
+			rereads = 0;
+		} else if (rereads++ > 5) {
+			break;
+		}
+
+	} while (rewrites < 100);
+
+	if (v != state)
+		DRM_ERROR("Writing dc state to 0x%x failed, now 0x%x\n",
+			  state, v);
+
+	/* Most of the times we need one retry, avoid spam */
+	if (rewrites > 1)
+		DRM_DEBUG_KMS("Rewrote dc state to 0x%x %d times\n",
+			      state, rewrites);
+}
+
+static u32 gen9_dc_mask(struct drm_i915_private *dev_priv)
+{
+	u32 mask;
+
+	mask = DC_STATE_EN_UPTO_DC5;
+	if (IS_BROXTON(dev_priv))
+		mask |= DC_STATE_EN_DC9;
+	else
+		mask |= DC_STATE_EN_UPTO_DC6;
+
+	return mask;
+}
+
+void gen9_sanitize_dc_state(struct drm_i915_private *dev_priv)
+{
+	u32 val;
+
+	val = I915_READ(DC_STATE_EN) & gen9_dc_mask(dev_priv);
+
+	DRM_DEBUG_KMS("Resetting DC state tracking from %02x to %02x\n",
+		      dev_priv->csr.dc_state, val);
+	dev_priv->csr.dc_state = val;
+}
+
+static void gen9_set_dc_state(struct drm_i915_private *dev_priv, uint32_t state)
+{
+	uint32_t val;
+	uint32_t mask;
+
+	if (WARN_ON_ONCE(state & ~dev_priv->csr.allowed_dc_mask))
+		state &= dev_priv->csr.allowed_dc_mask;
+
+	val = I915_READ(DC_STATE_EN);
+	mask = gen9_dc_mask(dev_priv);
+	DRM_DEBUG_KMS("Setting DC state from %02x to %02x\n",
+		      val & mask, state);
+
+	/* Check if DMC is ignoring our DC state requests */
+	if ((val & mask) != dev_priv->csr.dc_state)
+		DRM_ERROR("DC state mismatch (0x%x -> 0x%x)\n",
+			  dev_priv->csr.dc_state, val & mask);
+
+	val &= ~mask;
+	val |= state;
+
+	gen9_write_dc_state(dev_priv, val);
+
+	dev_priv->csr.dc_state = val & mask;
+}
+
+void bxt_enable_dc9(struct drm_i915_private *dev_priv)
+{
+	assert_can_enable_dc9(dev_priv);
+
+	DRM_DEBUG_KMS("Enabling DC9\n");
+
+	gen9_set_dc_state(dev_priv, DC_STATE_EN_DC9);
+}
+
+void bxt_disable_dc9(struct drm_i915_private *dev_priv)
+{
+	assert_can_disable_dc9(dev_priv);
+
+	DRM_DEBUG_KMS("Disabling DC9\n");
+
+	gen9_set_dc_state(dev_priv, DC_STATE_DISABLE);
+}
+
+static void assert_csr_loaded(struct drm_i915_private *dev_priv)
+{
+	WARN_ONCE(!I915_READ(CSR_PROGRAM(0)),
+		  "CSR program storage start is NULL\n");
+	WARN_ONCE(!I915_READ(CSR_SSP_BASE), "CSR SSP Base Not fine\n");
+	WARN_ONCE(!I915_READ(CSR_HTP_SKL), "CSR HTP Not fine\n");
+}
+
+static void assert_can_enable_dc5(struct drm_i915_private *dev_priv)
+{
+	bool pg2_enabled = intel_display_power_well_is_enabled(dev_priv,
+					SKL_DISP_PW_2);
+
+	WARN_ONCE(pg2_enabled, "PG2 not disabled to enable DC5.\n");
+
+	WARN_ONCE((I915_READ(DC_STATE_EN) & DC_STATE_EN_UPTO_DC5),
+		  "DC5 already programmed to be enabled.\n");
+	assert_rpm_wakelock_held(dev_priv);
+
+	assert_csr_loaded(dev_priv);
+}
+
+void gen9_enable_dc5(struct drm_i915_private *dev_priv)
+{
+	assert_can_enable_dc5(dev_priv);
+
+	DRM_DEBUG_KMS("Enabling DC5\n");
+
+	gen9_set_dc_state(dev_priv, DC_STATE_EN_UPTO_DC5);
+}
+
+static void assert_can_enable_dc6(struct drm_i915_private *dev_priv)
+{
+	WARN_ONCE(I915_READ(UTIL_PIN_CTL) & UTIL_PIN_ENABLE,
+		  "Backlight is not disabled.\n");
+	WARN_ONCE((I915_READ(DC_STATE_EN) & DC_STATE_EN_UPTO_DC6),
+		  "DC6 already programmed to be enabled.\n");
+
+	assert_csr_loaded(dev_priv);
+}
+
+void skl_enable_dc6(struct drm_i915_private *dev_priv)
+{
+	assert_can_enable_dc6(dev_priv);
+
+	DRM_DEBUG_KMS("Enabling DC6\n");
+
+	gen9_set_dc_state(dev_priv, DC_STATE_EN_UPTO_DC6);
+
+}
+
+void skl_disable_dc6(struct drm_i915_private *dev_priv)
+{
+	DRM_DEBUG_KMS("Disabling DC6\n");
+
+	gen9_set_dc_state(dev_priv, DC_STATE_DISABLE);
+}
+
+static void
+gen9_sanitize_power_well_requests(struct drm_i915_private *dev_priv,
+				  struct i915_power_well *power_well)
+{
+	enum skl_disp_power_wells power_well_id = power_well->data;
+	u32 val;
+	u32 mask;
+
+	mask = SKL_POWER_WELL_REQ(power_well_id);
+
+	val = I915_READ(HSW_PWR_WELL_KVMR);
+	if (WARN_ONCE(val & mask, "Clearing unexpected KVMR request for %s\n",
+		      power_well->name))
+		I915_WRITE(HSW_PWR_WELL_KVMR, val & ~mask);
+
+	val = I915_READ(HSW_PWR_WELL_BIOS);
+	val |= I915_READ(HSW_PWR_WELL_DEBUG);
+
+	if (!(val & mask))
+		return;
+
+	/*
+	 * DMC is known to force on the request bits for power well 1 on SKL
+	 * and BXT and the misc IO power well on SKL but we don't expect any
+	 * other request bits to be set, so WARN for those.
+	 */
+	if (power_well_id == SKL_DISP_PW_1 ||
+	    ((IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv)) &&
+	     power_well_id == SKL_DISP_PW_MISC_IO))
+		DRM_DEBUG_DRIVER("Clearing auxiliary requests for %s forced on "
+				 "by DMC\n", power_well->name);
+	else
+		WARN_ONCE(1, "Clearing unexpected auxiliary requests for %s\n",
+			  power_well->name);
+
+	I915_WRITE(HSW_PWR_WELL_BIOS, val & ~mask);
+	I915_WRITE(HSW_PWR_WELL_DEBUG, val & ~mask);
+}
+
+static void skl_set_power_well(struct drm_i915_private *dev_priv,
+			struct i915_power_well *power_well, bool enable)
+{
+	uint32_t tmp, fuse_status;
+	uint32_t req_mask, state_mask;
+	bool is_enabled, enable_requested, check_fuse_status = false;
+
+	tmp = I915_READ(HSW_PWR_WELL_DRIVER);
+	fuse_status = I915_READ(SKL_FUSE_STATUS);
+
+	switch (power_well->data) {
+	case SKL_DISP_PW_1:
+		if (wait_for((I915_READ(SKL_FUSE_STATUS) &
+			SKL_FUSE_PG0_DIST_STATUS), 1)) {
+			DRM_ERROR("PG0 not enabled\n");
+			return;
+		}
+		break;
+	case SKL_DISP_PW_2:
+		if (!(fuse_status & SKL_FUSE_PG1_DIST_STATUS)) {
+			DRM_ERROR("PG1 in disabled state\n");
+			return;
+		}
+		break;
+	case SKL_DISP_PW_DDI_A_E:
+	case SKL_DISP_PW_DDI_B:
+	case SKL_DISP_PW_DDI_C:
+	case SKL_DISP_PW_DDI_D:
+	case SKL_DISP_PW_MISC_IO:
+		break;
+	default:
+		WARN(1, "Unknown power well %lu\n", power_well->data);
+		return;
+	}
+
+	req_mask = SKL_POWER_WELL_REQ(power_well->data);
+	enable_requested = tmp & req_mask;
+	state_mask = SKL_POWER_WELL_STATE(power_well->data);
+	is_enabled = tmp & state_mask;
+
+	if (!enable && enable_requested)
+		skl_power_well_pre_disable(dev_priv, power_well);
+
+	if (enable) {
+		if (!enable_requested) {
+			WARN((tmp & state_mask) &&
+				!I915_READ(HSW_PWR_WELL_BIOS),
+				"Invalid for power well status to be enabled, unless done by the BIOS, \
+				when request is to disable!\n");
+			I915_WRITE(HSW_PWR_WELL_DRIVER, tmp | req_mask);
+		}
+
+		if (!is_enabled) {
+			DRM_DEBUG_KMS("Enabling %s\n", power_well->name);
+			check_fuse_status = true;
+		}
+	} else {
+		if (enable_requested) {
+			I915_WRITE(HSW_PWR_WELL_DRIVER,	tmp & ~req_mask);
+			POSTING_READ(HSW_PWR_WELL_DRIVER);
+			DRM_DEBUG_KMS("Disabling %s\n", power_well->name);
+		}
+
+		if (IS_GEN9(dev_priv))
+			gen9_sanitize_power_well_requests(dev_priv, power_well);
+	}
+
+	if (wait_for(!!(I915_READ(HSW_PWR_WELL_DRIVER) & state_mask) == enable,
+		     1))
+		DRM_ERROR("%s %s timeout\n",
+			  power_well->name, enable ? "enable" : "disable");
+
+	if (check_fuse_status) {
+		if (power_well->data == SKL_DISP_PW_1) {
+			if (wait_for((I915_READ(SKL_FUSE_STATUS) &
+				SKL_FUSE_PG1_DIST_STATUS), 1))
+				DRM_ERROR("PG1 distributing status timeout\n");
+		} else if (power_well->data == SKL_DISP_PW_2) {
+			if (wait_for((I915_READ(SKL_FUSE_STATUS) &
+				SKL_FUSE_PG2_DIST_STATUS), 1))
+				DRM_ERROR("PG2 distributing status timeout\n");
+		}
+	}
+
+	if (enable && !is_enabled)
+		skl_power_well_post_enable(dev_priv, power_well);
+}
+
+static void hsw_power_well_sync_hw(struct drm_i915_private *dev_priv,
+				   struct i915_power_well *power_well)
+{
+	hsw_set_power_well(dev_priv, power_well, power_well->count > 0);
+
+	/*
+	 * We're taking over the BIOS, so clear any requests made by it since
+	 * the driver is in charge now.
+	 */
+	if (I915_READ(HSW_PWR_WELL_BIOS) & HSW_PWR_WELL_ENABLE_REQUEST)
+		I915_WRITE(HSW_PWR_WELL_BIOS, 0);
+}
+
+static void hsw_power_well_enable(struct drm_i915_private *dev_priv,
+				  struct i915_power_well *power_well)
+{
+	hsw_set_power_well(dev_priv, power_well, true);
+}
+
+static void hsw_power_well_disable(struct drm_i915_private *dev_priv,
+				   struct i915_power_well *power_well)
+{
+	hsw_set_power_well(dev_priv, power_well, false);
+}
+
+static bool skl_power_well_enabled(struct drm_i915_private *dev_priv,
+					struct i915_power_well *power_well)
+{
+	uint32_t mask = SKL_POWER_WELL_REQ(power_well->data) |
+		SKL_POWER_WELL_STATE(power_well->data);
+
+	return (I915_READ(HSW_PWR_WELL_DRIVER) & mask) == mask;
+}
+
+static void skl_power_well_sync_hw(struct drm_i915_private *dev_priv,
+				struct i915_power_well *power_well)
+{
+	skl_set_power_well(dev_priv, power_well, power_well->count > 0);
+
+	/* Clear any request made by BIOS as driver is taking over */
+	I915_WRITE(HSW_PWR_WELL_BIOS, 0);
+}
+
+static void skl_power_well_enable(struct drm_i915_private *dev_priv,
+				struct i915_power_well *power_well)
+{
+	skl_set_power_well(dev_priv, power_well, true);
+}
+
+static void skl_power_well_disable(struct drm_i915_private *dev_priv,
+				struct i915_power_well *power_well)
+{
+	skl_set_power_well(dev_priv, power_well, false);
+}
+
+static bool gen9_dc_off_power_well_enabled(struct drm_i915_private *dev_priv,
+					   struct i915_power_well *power_well)
+{
+	return (I915_READ(DC_STATE_EN) & DC_STATE_EN_UPTO_DC5_DC6_MASK) == 0;
+}
+
+static void gen9_dc_off_power_well_enable(struct drm_i915_private *dev_priv,
+					  struct i915_power_well *power_well)
+{
+	gen9_set_dc_state(dev_priv, DC_STATE_DISABLE);
+
+	if (IS_BROXTON(dev_priv)) {
+		broxton_cdclk_verify_state(dev_priv);
+		broxton_ddi_phy_verify_state(dev_priv);
+	}
+}
+
+static void gen9_dc_off_power_well_disable(struct drm_i915_private *dev_priv,
+					   struct i915_power_well *power_well)
+{
+	if (!dev_priv->csr.dmc_payload)
+		return;
+
+	if (dev_priv->csr.allowed_dc_mask & DC_STATE_EN_UPTO_DC6)
+		skl_enable_dc6(dev_priv);
+	else if (dev_priv->csr.allowed_dc_mask & DC_STATE_EN_UPTO_DC5)
+		gen9_enable_dc5(dev_priv);
+}
+
+static void gen9_dc_off_power_well_sync_hw(struct drm_i915_private *dev_priv,
+					   struct i915_power_well *power_well)
+{
+	if (power_well->count > 0)
+		gen9_dc_off_power_well_enable(dev_priv, power_well);
+	else
+		gen9_dc_off_power_well_disable(dev_priv, power_well);
+}
+
+static void i9xx_always_on_power_well_noop(struct drm_i915_private *dev_priv,
+					   struct i915_power_well *power_well)
+{
+}
+
+static bool i9xx_always_on_power_well_enabled(struct drm_i915_private *dev_priv,
+					     struct i915_power_well *power_well)
+{
+	return true;
+}
+
+static void vlv_set_power_well(struct drm_i915_private *dev_priv,
+			       struct i915_power_well *power_well, bool enable)
+{
+	enum punit_power_well power_well_id = power_well->data;
+	u32 mask;
+	u32 state;
+	u32 ctrl;
+
+	mask = PUNIT_PWRGT_MASK(power_well_id);
+	state = enable ? PUNIT_PWRGT_PWR_ON(power_well_id) :
+			 PUNIT_PWRGT_PWR_GATE(power_well_id);
+
+	mutex_lock(&dev_priv->rps.hw_lock);
+
+#define COND \
+	((vlv_punit_read(dev_priv, PUNIT_REG_PWRGT_STATUS) & mask) == state)
+
+	if (COND)
+		goto out;
+
+	ctrl = vlv_punit_read(dev_priv, PUNIT_REG_PWRGT_CTRL);
+	ctrl &= ~mask;
+	ctrl |= state;
+	vlv_punit_write(dev_priv, PUNIT_REG_PWRGT_CTRL, ctrl);
+
+	if (wait_for(COND, 100))
+		DRM_ERROR("timeout setting power well state %08x (%08x)\n",
+			  state,
+			  vlv_punit_read(dev_priv, PUNIT_REG_PWRGT_CTRL));
+
+#undef COND
+
+out:
+	mutex_unlock(&dev_priv->rps.hw_lock);
+}
+
+static void vlv_power_well_sync_hw(struct drm_i915_private *dev_priv,
+				   struct i915_power_well *power_well)
+{
+	vlv_set_power_well(dev_priv, power_well, power_well->count > 0);
+}
+
+static void vlv_power_well_enable(struct drm_i915_private *dev_priv,
+				  struct i915_power_well *power_well)
+{
+	vlv_set_power_well(dev_priv, power_well, true);
+}
+
+static void vlv_power_well_disable(struct drm_i915_private *dev_priv,
+				   struct i915_power_well *power_well)
+{
+	vlv_set_power_well(dev_priv, power_well, false);
+}
+
+static bool vlv_power_well_enabled(struct drm_i915_private *dev_priv,
+				   struct i915_power_well *power_well)
+{
+	int power_well_id = power_well->data;
+	bool enabled = false;
+	u32 mask;
+	u32 state;
+	u32 ctrl;
+
+	mask = PUNIT_PWRGT_MASK(power_well_id);
+	ctrl = PUNIT_PWRGT_PWR_ON(power_well_id);
+
+	mutex_lock(&dev_priv->rps.hw_lock);
+
+	state = vlv_punit_read(dev_priv, PUNIT_REG_PWRGT_STATUS) & mask;
+	/*
+	 * We only ever set the power-on and power-gate states, anything
+	 * else is unexpected.
+	 */
+	WARN_ON(state != PUNIT_PWRGT_PWR_ON(power_well_id) &&
+		state != PUNIT_PWRGT_PWR_GATE(power_well_id));
+	if (state == ctrl)
+		enabled = true;
+
+	/*
+	 * A transient state at this point would mean some unexpected party
+	 * is poking at the power controls too.
+	 */
+	ctrl = vlv_punit_read(dev_priv, PUNIT_REG_PWRGT_CTRL) & mask;
+	WARN_ON(ctrl != state);
+
+	mutex_unlock(&dev_priv->rps.hw_lock);
+
+	return enabled;
+}
+
+static void vlv_init_display_clock_gating(struct drm_i915_private *dev_priv)
+{
+	I915_WRITE(DSPCLK_GATE_D, VRHUNIT_CLOCK_GATE_DISABLE);
+
+	/*
+	 * Disable trickle feed and enable pnd deadline calculation
+	 */
+	I915_WRITE(MI_ARB_VLV, MI_ARB_DISPLAY_TRICKLE_FEED_DISABLE);
+	I915_WRITE(CBR1_VLV, 0);
+}
+
+static void vlv_display_power_well_init(struct drm_i915_private *dev_priv)
+{
+	enum pipe pipe;
+
+	/*
+	 * Enable the CRI clock source so we can get at the
+	 * display and the reference clock for VGA
+	 * hotplug / manual detection. Supposedly DSI also
+	 * needs the ref clock up and running.
+	 *
+	 * CHV DPLL B/C have some issues if VGA mode is enabled.
+	 */
+	for_each_pipe(dev_priv->dev, pipe) {
+		u32 val = I915_READ(DPLL(pipe));
+
+		val |= DPLL_REF_CLK_ENABLE_VLV | DPLL_VGA_MODE_DIS;
+		if (pipe != PIPE_A)
+			val |= DPLL_INTEGRATED_CRI_CLK_VLV;
+
+		I915_WRITE(DPLL(pipe), val);
+	}
+
+	vlv_init_display_clock_gating(dev_priv);
+
+	spin_lock_irq(&dev_priv->irq_lock);
+	valleyview_enable_display_irqs(dev_priv);
+	spin_unlock_irq(&dev_priv->irq_lock);
+
+	/*
+	 * During driver initialization/resume we can avoid restoring the
+	 * part of the HW/SW state that will be inited anyway explicitly.
+	 */
+	if (dev_priv->power_domains.initializing)
+		return;
+
+	intel_hpd_init(dev_priv);
+
+	i915_redisable_vga_power_on(dev_priv->dev);
+}
+
+static void vlv_display_power_well_deinit(struct drm_i915_private *dev_priv)
+{
+	spin_lock_irq(&dev_priv->irq_lock);
+	valleyview_disable_display_irqs(dev_priv);
+	spin_unlock_irq(&dev_priv->irq_lock);
+
+	/* make sure we're done processing display irqs */
+	synchronize_irq(dev_priv->dev->irq);
+
+	vlv_power_sequencer_reset(dev_priv);
+}
+
+static void vlv_display_power_well_enable(struct drm_i915_private *dev_priv,
+					  struct i915_power_well *power_well)
+{
+	WARN_ON_ONCE(power_well->data != PUNIT_POWER_WELL_DISP2D);
+
+	vlv_set_power_well(dev_priv, power_well, true);
+
+	vlv_display_power_well_init(dev_priv);
+}
+
+static void vlv_display_power_well_disable(struct drm_i915_private *dev_priv,
+					   struct i915_power_well *power_well)
+{
+	WARN_ON_ONCE(power_well->data != PUNIT_POWER_WELL_DISP2D);
+
+	vlv_display_power_well_deinit(dev_priv);
+
+	vlv_set_power_well(dev_priv, power_well, false);
+}
+
+static void vlv_dpio_cmn_power_well_enable(struct drm_i915_private *dev_priv,
+					   struct i915_power_well *power_well)
+{
+	WARN_ON_ONCE(power_well->data != PUNIT_POWER_WELL_DPIO_CMN_BC);
+
+	/* since ref/cri clock was enabled */
+	udelay(1); /* >10ns for cmnreset, >0ns for sidereset */
+
+	vlv_set_power_well(dev_priv, power_well, true);
+
+	/*
+	 * From VLV2A0_DP_eDP_DPIO_driver_vbios_notes_10.docx -
+	 *  6.	De-assert cmn_reset/side_reset. Same as VLV X0.
+	 *   a.	GUnit 0x2110 bit[0] set to 1 (def 0)
+	 *   b.	The other bits such as sfr settings / modesel may all
+	 *	be set to 0.
+	 *
+	 * This should only be done on init and resume from S3 with
+	 * both PLLs disabled, or we risk losing DPIO and PLL
+	 * synchronization.
+	 */
+	I915_WRITE(DPIO_CTL, I915_READ(DPIO_CTL) | DPIO_CMNRST);
+}
+
+static void vlv_dpio_cmn_power_well_disable(struct drm_i915_private *dev_priv,
+					    struct i915_power_well *power_well)
+{
+	enum pipe pipe;
+
+	WARN_ON_ONCE(power_well->data != PUNIT_POWER_WELL_DPIO_CMN_BC);
+
+	for_each_pipe(dev_priv, pipe)
+		assert_pll_disabled(dev_priv, pipe);
+
+	/* Assert common reset */
+	I915_WRITE(DPIO_CTL, I915_READ(DPIO_CTL) & ~DPIO_CMNRST);
+
+	vlv_set_power_well(dev_priv, power_well, false);
+}
+
+#define POWER_DOMAIN_MASK (BIT(POWER_DOMAIN_NUM) - 1)
+
+static struct i915_power_well *lookup_power_well(struct drm_i915_private *dev_priv,
+						 int power_well_id)
+{
+	struct i915_power_domains *power_domains = &dev_priv->power_domains;
+	int i;
+
+	for (i = 0; i < power_domains->power_well_count; i++) {
+		struct i915_power_well *power_well;
+
+		power_well = &power_domains->power_wells[i];
+		if (power_well->data == power_well_id)
+			return power_well;
+	}
+
+	return NULL;
+}
+
+#define BITS_SET(val, bits) (((val) & (bits)) == (bits))
+
+static void assert_chv_phy_status(struct drm_i915_private *dev_priv)
+{
+	struct i915_power_well *cmn_bc =
+		lookup_power_well(dev_priv, PUNIT_POWER_WELL_DPIO_CMN_BC);
+	struct i915_power_well *cmn_d =
+		lookup_power_well(dev_priv, PUNIT_POWER_WELL_DPIO_CMN_D);
+	u32 phy_control = dev_priv->chv_phy_control;
+	u32 phy_status = 0;
+	u32 phy_status_mask = 0xffffffff;
+	u32 tmp;
+
+	/*
+	 * The BIOS can leave the PHY is some weird state
+	 * where it doesn't fully power down some parts.
+	 * Disable the asserts until the PHY has been fully
+	 * reset (ie. the power well has been disabled at
+	 * least once).
+	 */
+	if (!dev_priv->chv_phy_assert[DPIO_PHY0])
+		phy_status_mask &= ~(PHY_STATUS_CMN_LDO(DPIO_PHY0, DPIO_CH0) |
+				     PHY_STATUS_SPLINE_LDO(DPIO_PHY0, DPIO_CH0, 0) |
+				     PHY_STATUS_SPLINE_LDO(DPIO_PHY0, DPIO_CH0, 1) |
+				     PHY_STATUS_CMN_LDO(DPIO_PHY0, DPIO_CH1) |
+				     PHY_STATUS_SPLINE_LDO(DPIO_PHY0, DPIO_CH1, 0) |
+				     PHY_STATUS_SPLINE_LDO(DPIO_PHY0, DPIO_CH1, 1));
+
+	if (!dev_priv->chv_phy_assert[DPIO_PHY1])
+		phy_status_mask &= ~(PHY_STATUS_CMN_LDO(DPIO_PHY1, DPIO_CH0) |
+				     PHY_STATUS_SPLINE_LDO(DPIO_PHY1, DPIO_CH0, 0) |
+				     PHY_STATUS_SPLINE_LDO(DPIO_PHY1, DPIO_CH0, 1));
+
+	if (cmn_bc->ops->is_enabled(dev_priv, cmn_bc)) {
+		phy_status |= PHY_POWERGOOD(DPIO_PHY0);
+
+		/* this assumes override is only used to enable lanes */
+		if ((phy_control & PHY_CH_POWER_DOWN_OVRD_EN(DPIO_PHY0, DPIO_CH0)) == 0)
+			phy_control |= PHY_CH_POWER_DOWN_OVRD(0xf, DPIO_PHY0, DPIO_CH0);
+
+		if ((phy_control & PHY_CH_POWER_DOWN_OVRD_EN(DPIO_PHY0, DPIO_CH1)) == 0)
+			phy_control |= PHY_CH_POWER_DOWN_OVRD(0xf, DPIO_PHY0, DPIO_CH1);
+
+		/* CL1 is on whenever anything is on in either channel */
+		if (BITS_SET(phy_control,
+			     PHY_CH_POWER_DOWN_OVRD(0xf, DPIO_PHY0, DPIO_CH0) |
+			     PHY_CH_POWER_DOWN_OVRD(0xf, DPIO_PHY0, DPIO_CH1)))
+			phy_status |= PHY_STATUS_CMN_LDO(DPIO_PHY0, DPIO_CH0);
+
+		/*
+		 * The DPLLB check accounts for the pipe B + port A usage
+		 * with CL2 powered up but all the lanes in the second channel
+		 * powered down.
+		 */
+		if (BITS_SET(phy_control,
+			     PHY_CH_POWER_DOWN_OVRD(0xf, DPIO_PHY0, DPIO_CH1)) &&
+		    (I915_READ(DPLL(PIPE_B)) & DPLL_VCO_ENABLE) == 0)
+			phy_status |= PHY_STATUS_CMN_LDO(DPIO_PHY0, DPIO_CH1);
+
+		if (BITS_SET(phy_control,
+			     PHY_CH_POWER_DOWN_OVRD(0x3, DPIO_PHY0, DPIO_CH0)))
+			phy_status |= PHY_STATUS_SPLINE_LDO(DPIO_PHY0, DPIO_CH0, 0);
+		if (BITS_SET(phy_control,
+			     PHY_CH_POWER_DOWN_OVRD(0xc, DPIO_PHY0, DPIO_CH0)))
+			phy_status |= PHY_STATUS_SPLINE_LDO(DPIO_PHY0, DPIO_CH0, 1);
+
+		if (BITS_SET(phy_control,
+			     PHY_CH_POWER_DOWN_OVRD(0x3, DPIO_PHY0, DPIO_CH1)))
+			phy_status |= PHY_STATUS_SPLINE_LDO(DPIO_PHY0, DPIO_CH1, 0);
+		if (BITS_SET(phy_control,
+			     PHY_CH_POWER_DOWN_OVRD(0xc, DPIO_PHY0, DPIO_CH1)))
+			phy_status |= PHY_STATUS_SPLINE_LDO(DPIO_PHY0, DPIO_CH1, 1);
+	}
+
+	if (cmn_d->ops->is_enabled(dev_priv, cmn_d)) {
+		phy_status |= PHY_POWERGOOD(DPIO_PHY1);
+
+		/* this assumes override is only used to enable lanes */
+		if ((phy_control & PHY_CH_POWER_DOWN_OVRD_EN(DPIO_PHY1, DPIO_CH0)) == 0)
+			phy_control |= PHY_CH_POWER_DOWN_OVRD(0xf, DPIO_PHY1, DPIO_CH0);
+
+		if (BITS_SET(phy_control,
+			     PHY_CH_POWER_DOWN_OVRD(0xf, DPIO_PHY1, DPIO_CH0)))
+			phy_status |= PHY_STATUS_CMN_LDO(DPIO_PHY1, DPIO_CH0);
+
+		if (BITS_SET(phy_control,
+			     PHY_CH_POWER_DOWN_OVRD(0x3, DPIO_PHY1, DPIO_CH0)))
+			phy_status |= PHY_STATUS_SPLINE_LDO(DPIO_PHY1, DPIO_CH0, 0);
+		if (BITS_SET(phy_control,
+			     PHY_CH_POWER_DOWN_OVRD(0xc, DPIO_PHY1, DPIO_CH0)))
+			phy_status |= PHY_STATUS_SPLINE_LDO(DPIO_PHY1, DPIO_CH0, 1);
+	}
+
+	phy_status &= phy_status_mask;
+
+	/*
+	 * The PHY may be busy with some initial calibration and whatnot,
+	 * so the power state can take a while to actually change.
+	 */
+	if (wait_for((tmp = I915_READ(DISPLAY_PHY_STATUS) & phy_status_mask) == phy_status, 10))
+		WARN(phy_status != tmp,
+		     "Unexpected PHY_STATUS 0x%08x, expected 0x%08x (PHY_CONTROL=0x%08x)\n",
+		     tmp, phy_status, dev_priv->chv_phy_control);
+}
+
+#undef BITS_SET
+
+static void chv_dpio_cmn_power_well_enable(struct drm_i915_private *dev_priv,
+					   struct i915_power_well *power_well)
+{
+	enum dpio_phy phy;
+	enum pipe pipe;
+	uint32_t tmp;
+
+	WARN_ON_ONCE(power_well->data != PUNIT_POWER_WELL_DPIO_CMN_BC &&
+		     power_well->data != PUNIT_POWER_WELL_DPIO_CMN_D);
+
+	if (power_well->data == PUNIT_POWER_WELL_DPIO_CMN_BC) {
+		pipe = PIPE_A;
+		phy = DPIO_PHY0;
+	} else {
+		pipe = PIPE_C;
+		phy = DPIO_PHY1;
+	}
+
+	/* since ref/cri clock was enabled */
+	udelay(1); /* >10ns for cmnreset, >0ns for sidereset */
+	vlv_set_power_well(dev_priv, power_well, true);
+
+	/* Poll for phypwrgood signal */
+	if (wait_for(I915_READ(DISPLAY_PHY_STATUS) & PHY_POWERGOOD(phy), 1))
+		DRM_ERROR("Display PHY %d is not power up\n", phy);
+
+	mutex_lock(&dev_priv->sb_lock);
+
+	/* Enable dynamic power down */
+	tmp = vlv_dpio_read(dev_priv, pipe, CHV_CMN_DW28);
+	tmp |= DPIO_DYNPWRDOWNEN_CH0 | DPIO_CL1POWERDOWNEN |
+		DPIO_SUS_CLK_CONFIG_GATE_CLKREQ;
+	vlv_dpio_write(dev_priv, pipe, CHV_CMN_DW28, tmp);
+
+	if (power_well->data == PUNIT_POWER_WELL_DPIO_CMN_BC) {
+		tmp = vlv_dpio_read(dev_priv, pipe, _CHV_CMN_DW6_CH1);
+		tmp |= DPIO_DYNPWRDOWNEN_CH1;
+		vlv_dpio_write(dev_priv, pipe, _CHV_CMN_DW6_CH1, tmp);
+	} else {
+		/*
+		 * Force the non-existing CL2 off. BXT does this
+		 * too, so maybe it saves some power even though
+		 * CL2 doesn't exist?
+		 */
+		tmp = vlv_dpio_read(dev_priv, pipe, CHV_CMN_DW30);
+		tmp |= DPIO_CL2_LDOFUSE_PWRENB;
+		vlv_dpio_write(dev_priv, pipe, CHV_CMN_DW30, tmp);
+	}
+
+	mutex_unlock(&dev_priv->sb_lock);
+
+	dev_priv->chv_phy_control |= PHY_COM_LANE_RESET_DEASSERT(phy);
+	I915_WRITE(DISPLAY_PHY_CONTROL, dev_priv->chv_phy_control);
+
+	DRM_DEBUG_KMS("Enabled DPIO PHY%d (PHY_CONTROL=0x%08x)\n",
+		      phy, dev_priv->chv_phy_control);
+
+	assert_chv_phy_status(dev_priv);
+}
+
+static void chv_dpio_cmn_power_well_disable(struct drm_i915_private *dev_priv,
+					    struct i915_power_well *power_well)
+{
+	enum dpio_phy phy;
+
+	WARN_ON_ONCE(power_well->data != PUNIT_POWER_WELL_DPIO_CMN_BC &&
+		     power_well->data != PUNIT_POWER_WELL_DPIO_CMN_D);
+
+	if (power_well->data == PUNIT_POWER_WELL_DPIO_CMN_BC) {
+		phy = DPIO_PHY0;
+		assert_pll_disabled(dev_priv, PIPE_A);
+		assert_pll_disabled(dev_priv, PIPE_B);
+	} else {
+		phy = DPIO_PHY1;
+		assert_pll_disabled(dev_priv, PIPE_C);
+	}
+
+	dev_priv->chv_phy_control &= ~PHY_COM_LANE_RESET_DEASSERT(phy);
+	I915_WRITE(DISPLAY_PHY_CONTROL, dev_priv->chv_phy_control);
+
+	vlv_set_power_well(dev_priv, power_well, false);
+
+	DRM_DEBUG_KMS("Disabled DPIO PHY%d (PHY_CONTROL=0x%08x)\n",
+		      phy, dev_priv->chv_phy_control);
+
+	/* PHY is fully reset now, so we can enable the PHY state asserts */
+	dev_priv->chv_phy_assert[phy] = true;
+
+	assert_chv_phy_status(dev_priv);
+}
+
+static void assert_chv_phy_powergate(struct drm_i915_private *dev_priv, enum dpio_phy phy,
+				     enum dpio_channel ch, bool override, unsigned int mask)
+{
+	enum pipe pipe = phy == DPIO_PHY0 ? PIPE_A : PIPE_C;
+	u32 reg, val, expected, actual;
+
+	/*
+	 * The BIOS can leave the PHY is some weird state
+	 * where it doesn't fully power down some parts.
+	 * Disable the asserts until the PHY has been fully
+	 * reset (ie. the power well has been disabled at
+	 * least once).
+	 */
+	if (!dev_priv->chv_phy_assert[phy])
+		return;
+
+	if (ch == DPIO_CH0)
+		reg = _CHV_CMN_DW0_CH0;
+	else
+		reg = _CHV_CMN_DW6_CH1;
+
+	mutex_lock(&dev_priv->sb_lock);
+	val = vlv_dpio_read(dev_priv, pipe, reg);
+	mutex_unlock(&dev_priv->sb_lock);
+
+	/*
+	 * This assumes !override is only used when the port is disabled.
+	 * All lanes should power down even without the override when
+	 * the port is disabled.
+	 */
+	if (!override || mask == 0xf) {
+		expected = DPIO_ALLDL_POWERDOWN | DPIO_ANYDL_POWERDOWN;
+		/*
+		 * If CH1 common lane is not active anymore
+		 * (eg. for pipe B DPLL) the entire channel will
+		 * shut down, which causes the common lane registers
+		 * to read as 0. That means we can't actually check
+		 * the lane power down status bits, but as the entire
+		 * register reads as 0 it's a good indication that the
+		 * channel is indeed entirely powered down.
+		 */
+		if (ch == DPIO_CH1 && val == 0)
+			expected = 0;
+	} else if (mask != 0x0) {
+		expected = DPIO_ANYDL_POWERDOWN;
+	} else {
+		expected = 0;
+	}
+
+	if (ch == DPIO_CH0)
+		actual = val >> DPIO_ANYDL_POWERDOWN_SHIFT_CH0;
+	else
+		actual = val >> DPIO_ANYDL_POWERDOWN_SHIFT_CH1;
+	actual &= DPIO_ALLDL_POWERDOWN | DPIO_ANYDL_POWERDOWN;
+
+	WARN(actual != expected,
+	     "Unexpected DPIO lane power down: all %d, any %d. Expected: all %d, any %d. (0x%x = 0x%08x)\n",
+	     !!(actual & DPIO_ALLDL_POWERDOWN), !!(actual & DPIO_ANYDL_POWERDOWN),
+	     !!(expected & DPIO_ALLDL_POWERDOWN), !!(expected & DPIO_ANYDL_POWERDOWN),
+	     reg, val);
+}
+
+bool chv_phy_powergate_ch(struct drm_i915_private *dev_priv, enum dpio_phy phy,
+			  enum dpio_channel ch, bool override)
+{
+	struct i915_power_domains *power_domains = &dev_priv->power_domains;
+	bool was_override;
+
+	mutex_lock(&power_domains->lock);
+
+	was_override = dev_priv->chv_phy_control & PHY_CH_POWER_DOWN_OVRD_EN(phy, ch);
+
+	if (override == was_override)
+		goto out;
+
+	if (override)
+		dev_priv->chv_phy_control |= PHY_CH_POWER_DOWN_OVRD_EN(phy, ch);
+	else
+		dev_priv->chv_phy_control &= ~PHY_CH_POWER_DOWN_OVRD_EN(phy, ch);
+
+	I915_WRITE(DISPLAY_PHY_CONTROL, dev_priv->chv_phy_control);
+
+	DRM_DEBUG_KMS("Power gating DPIO PHY%d CH%d (DPIO_PHY_CONTROL=0x%08x)\n",
+		      phy, ch, dev_priv->chv_phy_control);
+
+	assert_chv_phy_status(dev_priv);
+
+out:
+	mutex_unlock(&power_domains->lock);
+
+	return was_override;
+}
+
+void chv_phy_powergate_lanes(struct intel_encoder *encoder,
+			     bool override, unsigned int mask)
+{
+	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
+	struct i915_power_domains *power_domains = &dev_priv->power_domains;
+	enum dpio_phy phy = vlv_dport_to_phy(enc_to_dig_port(&encoder->base));
+	enum dpio_channel ch = vlv_dport_to_channel(enc_to_dig_port(&encoder->base));
+
+	mutex_lock(&power_domains->lock);
+
+	dev_priv->chv_phy_control &= ~PHY_CH_POWER_DOWN_OVRD(0xf, phy, ch);
+	dev_priv->chv_phy_control |= PHY_CH_POWER_DOWN_OVRD(mask, phy, ch);
+
+	if (override)
+		dev_priv->chv_phy_control |= PHY_CH_POWER_DOWN_OVRD_EN(phy, ch);
+	else
+		dev_priv->chv_phy_control &= ~PHY_CH_POWER_DOWN_OVRD_EN(phy, ch);
+
+	I915_WRITE(DISPLAY_PHY_CONTROL, dev_priv->chv_phy_control);
+
+	DRM_DEBUG_KMS("Power gating DPIO PHY%d CH%d lanes 0x%x (PHY_CONTROL=0x%08x)\n",
+		      phy, ch, mask, dev_priv->chv_phy_control);
+
+	assert_chv_phy_status(dev_priv);
+
+	assert_chv_phy_powergate(dev_priv, phy, ch, override, mask);
+
+	mutex_unlock(&power_domains->lock);
+}
+
+static bool chv_pipe_power_well_enabled(struct drm_i915_private *dev_priv,
+					struct i915_power_well *power_well)
+{
+	enum pipe pipe = power_well->data;
+	bool enabled;
+	u32 state, ctrl;
+
+	mutex_lock(&dev_priv->rps.hw_lock);
+
+	state = vlv_punit_read(dev_priv, PUNIT_REG_DSPFREQ) & DP_SSS_MASK(pipe);
+	/*
+	 * We only ever set the power-on and power-gate states, anything
+	 * else is unexpected.
+	 */
+	WARN_ON(state != DP_SSS_PWR_ON(pipe) && state != DP_SSS_PWR_GATE(pipe));
+	enabled = state == DP_SSS_PWR_ON(pipe);
+
+	/*
+	 * A transient state at this point would mean some unexpected party
+	 * is poking at the power controls too.
+	 */
+	ctrl = vlv_punit_read(dev_priv, PUNIT_REG_DSPFREQ) & DP_SSC_MASK(pipe);
+	WARN_ON(ctrl << 16 != state);
+
+	mutex_unlock(&dev_priv->rps.hw_lock);
+
+	return enabled;
+}
+
+static void chv_set_pipe_power_well(struct drm_i915_private *dev_priv,
+				    struct i915_power_well *power_well,
+				    bool enable)
+{
+	enum pipe pipe = power_well->data;
+	u32 state;
+	u32 ctrl;
+
+	state = enable ? DP_SSS_PWR_ON(pipe) : DP_SSS_PWR_GATE(pipe);
+
+	mutex_lock(&dev_priv->rps.hw_lock);
+
+#define COND \
+	((vlv_punit_read(dev_priv, PUNIT_REG_DSPFREQ) & DP_SSS_MASK(pipe)) == state)
+
+	if (COND)
+		goto out;
+
+	ctrl = vlv_punit_read(dev_priv, PUNIT_REG_DSPFREQ);
+	ctrl &= ~DP_SSC_MASK(pipe);
+	ctrl |= enable ? DP_SSC_PWR_ON(pipe) : DP_SSC_PWR_GATE(pipe);
+	vlv_punit_write(dev_priv, PUNIT_REG_DSPFREQ, ctrl);
+
+	if (wait_for(COND, 100))
+		DRM_ERROR("timeout setting power well state %08x (%08x)\n",
+			  state,
+			  vlv_punit_read(dev_priv, PUNIT_REG_DSPFREQ));
+
+#undef COND
+
+out:
+	mutex_unlock(&dev_priv->rps.hw_lock);
+}
+
+static void chv_pipe_power_well_sync_hw(struct drm_i915_private *dev_priv,
+					struct i915_power_well *power_well)
+{
+	WARN_ON_ONCE(power_well->data != PIPE_A);
+
+	chv_set_pipe_power_well(dev_priv, power_well, power_well->count > 0);
+}
+
+static void chv_pipe_power_well_enable(struct drm_i915_private *dev_priv,
+				       struct i915_power_well *power_well)
+{
+	WARN_ON_ONCE(power_well->data != PIPE_A);
+
+	chv_set_pipe_power_well(dev_priv, power_well, true);
+
+	vlv_display_power_well_init(dev_priv);
+}
+
+static void chv_pipe_power_well_disable(struct drm_i915_private *dev_priv,
+					struct i915_power_well *power_well)
+{
+	WARN_ON_ONCE(power_well->data != PIPE_A);
+
+	vlv_display_power_well_deinit(dev_priv);
+
+	chv_set_pipe_power_well(dev_priv, power_well, false);
+}
+
+static void
+__intel_display_power_get_domain(struct drm_i915_private *dev_priv,
+				 enum intel_display_power_domain domain)
+{
+	struct i915_power_domains *power_domains = &dev_priv->power_domains;
+	struct i915_power_well *power_well;
+	int i;
+
+	for_each_power_well(i, power_well, BIT(domain), power_domains) {
+		if (!power_well->count++)
+			intel_power_well_enable(dev_priv, power_well);
+	}
+
+	power_domains->domain_use_count[domain]++;
+}
+
+/**
+ * intel_display_power_get - grab a power domain reference
+ * @dev_priv: i915 device instance
+ * @domain: power domain to reference
+ *
+ * This function grabs a power domain reference for @domain and ensures that the
+ * power domain and all its parents are powered up. Therefore users should only
+ * grab a reference to the innermost power domain they need.
+ *
+ * Any power domain reference obtained by this function must have a symmetric
+ * call to intel_display_power_put() to release the reference again.
+ */
+void intel_display_power_get(struct drm_i915_private *dev_priv,
+			     enum intel_display_power_domain domain)
+{
+	struct i915_power_domains *power_domains = &dev_priv->power_domains;
+
+	intel_runtime_pm_get(dev_priv);
+
+	mutex_lock(&power_domains->lock);
+
+	__intel_display_power_get_domain(dev_priv, domain);
+
+	mutex_unlock(&power_domains->lock);
+}
+
+/**
+ * intel_display_power_get_if_enabled - grab a reference for an enabled display power domain
+ * @dev_priv: i915 device instance
+ * @domain: power domain to reference
+ *
+ * This function grabs a power domain reference for @domain and ensures that the
+ * power domain and all its parents are powered up. Therefore users should only
+ * grab a reference to the innermost power domain they need.
+ *
+ * Any power domain reference obtained by this function must have a symmetric
+ * call to intel_display_power_put() to release the reference again.
+ */
+bool intel_display_power_get_if_enabled(struct drm_i915_private *dev_priv,
+					enum intel_display_power_domain domain)
+{
+	struct i915_power_domains *power_domains = &dev_priv->power_domains;
+	bool is_enabled;
+
+	if (!intel_runtime_pm_get_if_in_use(dev_priv))
+		return false;
+
+	mutex_lock(&power_domains->lock);
+
+	if (__intel_display_power_is_enabled(dev_priv, domain)) {
+		__intel_display_power_get_domain(dev_priv, domain);
+		is_enabled = true;
+	} else {
+		is_enabled = false;
+	}
+
+	mutex_unlock(&power_domains->lock);
+
+	if (!is_enabled)
+		intel_runtime_pm_put(dev_priv);
+
+	return is_enabled;
+}
+
+/**
+ * intel_display_power_put - release a power domain reference
+ * @dev_priv: i915 device instance
+ * @domain: power domain to reference
+ *
+ * This function drops the power domain reference obtained by
+ * intel_display_power_get() and might power down the corresponding hardware
+ * block right away if this is the last reference.
+ */
+void intel_display_power_put(struct drm_i915_private *dev_priv,
+			     enum intel_display_power_domain domain)
+{
+	struct i915_power_domains *power_domains;
+	struct i915_power_well *power_well;
+	int i;
+
+	power_domains = &dev_priv->power_domains;
+
+	mutex_lock(&power_domains->lock);
+
+	WARN(!power_domains->domain_use_count[domain],
+	     "Use count on domain %s is already zero\n",
+	     intel_display_power_domain_str(domain));
+	power_domains->domain_use_count[domain]--;
+
+	for_each_power_well_rev(i, power_well, BIT(domain), power_domains) {
+		WARN(!power_well->count,
+		     "Use count on power well %s is already zero",
+		     power_well->name);
+
+		if (!--power_well->count)
+			intel_power_well_disable(dev_priv, power_well);
+	}
+
+	mutex_unlock(&power_domains->lock);
+
+	intel_runtime_pm_put(dev_priv);
+}
+
+#define HSW_DISPLAY_POWER_DOMAINS (			\
+	BIT(POWER_DOMAIN_PIPE_B) |			\
+	BIT(POWER_DOMAIN_PIPE_C) |			\
+	BIT(POWER_DOMAIN_PIPE_A_PANEL_FITTER) |		\
+	BIT(POWER_DOMAIN_PIPE_B_PANEL_FITTER) |		\
+	BIT(POWER_DOMAIN_PIPE_C_PANEL_FITTER) |		\
+	BIT(POWER_DOMAIN_TRANSCODER_A) |		\
+	BIT(POWER_DOMAIN_TRANSCODER_B) |		\
+	BIT(POWER_DOMAIN_TRANSCODER_C) |		\
+	BIT(POWER_DOMAIN_PORT_DDI_B_LANES) |		\
+	BIT(POWER_DOMAIN_PORT_DDI_C_LANES) |		\
+	BIT(POWER_DOMAIN_PORT_DDI_D_LANES) |		\
+	BIT(POWER_DOMAIN_PORT_CRT) | /* DDI E */	\
+	BIT(POWER_DOMAIN_VGA) |				\
+	BIT(POWER_DOMAIN_AUDIO) |			\
+	BIT(POWER_DOMAIN_INIT))
+
+#define BDW_DISPLAY_POWER_DOMAINS (			\
+	BIT(POWER_DOMAIN_PIPE_B) |			\
+	BIT(POWER_DOMAIN_PIPE_C) |			\
+	BIT(POWER_DOMAIN_PIPE_B_PANEL_FITTER) |		\
+	BIT(POWER_DOMAIN_PIPE_C_PANEL_FITTER) |		\
+	BIT(POWER_DOMAIN_TRANSCODER_A) |		\
+	BIT(POWER_DOMAIN_TRANSCODER_B) |		\
+	BIT(POWER_DOMAIN_TRANSCODER_C) |		\
+	BIT(POWER_DOMAIN_PORT_DDI_B_LANES) |		\
+	BIT(POWER_DOMAIN_PORT_DDI_C_LANES) |		\
+	BIT(POWER_DOMAIN_PORT_DDI_D_LANES) |		\
+	BIT(POWER_DOMAIN_PORT_CRT) | /* DDI E */	\
+	BIT(POWER_DOMAIN_VGA) |				\
+	BIT(POWER_DOMAIN_AUDIO) |			\
+	BIT(POWER_DOMAIN_INIT))
+
+#define VLV_DISPLAY_POWER_DOMAINS (		\
+	BIT(POWER_DOMAIN_PIPE_A) |		\
+	BIT(POWER_DOMAIN_PIPE_B) |		\
+	BIT(POWER_DOMAIN_PIPE_A_PANEL_FITTER) |	\
+	BIT(POWER_DOMAIN_PIPE_B_PANEL_FITTER) |	\
+	BIT(POWER_DOMAIN_TRANSCODER_A) |	\
+	BIT(POWER_DOMAIN_TRANSCODER_B) |	\
+	BIT(POWER_DOMAIN_PORT_DDI_B_LANES) |	\
+	BIT(POWER_DOMAIN_PORT_DDI_C_LANES) |	\
+	BIT(POWER_DOMAIN_PORT_DSI) |		\
+	BIT(POWER_DOMAIN_PORT_CRT) |		\
+	BIT(POWER_DOMAIN_VGA) |			\
+	BIT(POWER_DOMAIN_AUDIO) |		\
+	BIT(POWER_DOMAIN_AUX_B) |		\
+	BIT(POWER_DOMAIN_AUX_C) |		\
+	BIT(POWER_DOMAIN_GMBUS) |		\
+	BIT(POWER_DOMAIN_INIT))
+
+#define VLV_DPIO_CMN_BC_POWER_DOMAINS (		\
+	BIT(POWER_DOMAIN_PORT_DDI_B_LANES) |	\
+	BIT(POWER_DOMAIN_PORT_DDI_C_LANES) |	\
+	BIT(POWER_DOMAIN_PORT_CRT) |		\
+	BIT(POWER_DOMAIN_AUX_B) |		\
+	BIT(POWER_DOMAIN_AUX_C) |		\
+	BIT(POWER_DOMAIN_INIT))
+
+#define VLV_DPIO_TX_B_LANES_01_POWER_DOMAINS (	\
+	BIT(POWER_DOMAIN_PORT_DDI_B_LANES) |	\
+	BIT(POWER_DOMAIN_AUX_B) |		\
+	BIT(POWER_DOMAIN_INIT))
+
+#define VLV_DPIO_TX_B_LANES_23_POWER_DOMAINS (	\
+	BIT(POWER_DOMAIN_PORT_DDI_B_LANES) |	\
+	BIT(POWER_DOMAIN_AUX_B) |		\
+	BIT(POWER_DOMAIN_INIT))
+
+#define VLV_DPIO_TX_C_LANES_01_POWER_DOMAINS (	\
+	BIT(POWER_DOMAIN_PORT_DDI_C_LANES) |	\
+	BIT(POWER_DOMAIN_AUX_C) |		\
+	BIT(POWER_DOMAIN_INIT))
+
+#define VLV_DPIO_TX_C_LANES_23_POWER_DOMAINS (	\
+	BIT(POWER_DOMAIN_PORT_DDI_C_LANES) |	\
+	BIT(POWER_DOMAIN_AUX_C) |		\
+	BIT(POWER_DOMAIN_INIT))
+
+#define CHV_DISPLAY_POWER_DOMAINS (		\
+	BIT(POWER_DOMAIN_PIPE_A) |		\
+	BIT(POWER_DOMAIN_PIPE_B) |		\
+	BIT(POWER_DOMAIN_PIPE_C) |		\
+	BIT(POWER_DOMAIN_PIPE_A_PANEL_FITTER) |	\
+	BIT(POWER_DOMAIN_PIPE_B_PANEL_FITTER) |	\
+	BIT(POWER_DOMAIN_PIPE_C_PANEL_FITTER) |	\
+	BIT(POWER_DOMAIN_TRANSCODER_A) |	\
+	BIT(POWER_DOMAIN_TRANSCODER_B) |	\
+	BIT(POWER_DOMAIN_TRANSCODER_C) |	\
+	BIT(POWER_DOMAIN_PORT_DDI_B_LANES) |	\
+	BIT(POWER_DOMAIN_PORT_DDI_C_LANES) |	\
+	BIT(POWER_DOMAIN_PORT_DDI_D_LANES) |	\
+	BIT(POWER_DOMAIN_PORT_DSI) |		\
+	BIT(POWER_DOMAIN_VGA) |			\
+	BIT(POWER_DOMAIN_AUDIO) |		\
+	BIT(POWER_DOMAIN_AUX_B) |		\
+	BIT(POWER_DOMAIN_AUX_C) |		\
+	BIT(POWER_DOMAIN_AUX_D) |		\
+	BIT(POWER_DOMAIN_GMBUS) |		\
+	BIT(POWER_DOMAIN_INIT))
+
+#define CHV_DPIO_CMN_BC_POWER_DOMAINS (		\
+	BIT(POWER_DOMAIN_PORT_DDI_B_LANES) |	\
+	BIT(POWER_DOMAIN_PORT_DDI_C_LANES) |	\
+	BIT(POWER_DOMAIN_AUX_B) |		\
+	BIT(POWER_DOMAIN_AUX_C) |		\
+	BIT(POWER_DOMAIN_INIT))
+
+#define CHV_DPIO_CMN_D_POWER_DOMAINS (		\
+	BIT(POWER_DOMAIN_PORT_DDI_D_LANES) |	\
+	BIT(POWER_DOMAIN_AUX_D) |		\
+	BIT(POWER_DOMAIN_INIT))
+
+static const struct i915_power_well_ops i9xx_always_on_power_well_ops = {
+	.sync_hw = i9xx_always_on_power_well_noop,
+	.enable = i9xx_always_on_power_well_noop,
+	.disable = i9xx_always_on_power_well_noop,
+	.is_enabled = i9xx_always_on_power_well_enabled,
+};
+
+static const struct i915_power_well_ops chv_pipe_power_well_ops = {
+	.sync_hw = chv_pipe_power_well_sync_hw,
+	.enable = chv_pipe_power_well_enable,
+	.disable = chv_pipe_power_well_disable,
+	.is_enabled = chv_pipe_power_well_enabled,
+};
+
+static const struct i915_power_well_ops chv_dpio_cmn_power_well_ops = {
+	.sync_hw = vlv_power_well_sync_hw,
+	.enable = chv_dpio_cmn_power_well_enable,
+	.disable = chv_dpio_cmn_power_well_disable,
+	.is_enabled = vlv_power_well_enabled,
+};
+
+static struct i915_power_well i9xx_always_on_power_well[] = {
+	{
+		.name = "always-on",
+		.always_on = 1,
+		.domains = POWER_DOMAIN_MASK,
+		.ops = &i9xx_always_on_power_well_ops,
+	},
+};
+
+static const struct i915_power_well_ops hsw_power_well_ops = {
+	.sync_hw = hsw_power_well_sync_hw,
+	.enable = hsw_power_well_enable,
+	.disable = hsw_power_well_disable,
+	.is_enabled = hsw_power_well_enabled,
+};
+
+static const struct i915_power_well_ops skl_power_well_ops = {
+	.sync_hw = skl_power_well_sync_hw,
+	.enable = skl_power_well_enable,
+	.disable = skl_power_well_disable,
+	.is_enabled = skl_power_well_enabled,
+};
+
+static const struct i915_power_well_ops gen9_dc_off_power_well_ops = {
+	.sync_hw = gen9_dc_off_power_well_sync_hw,
+	.enable = gen9_dc_off_power_well_enable,
+	.disable = gen9_dc_off_power_well_disable,
+	.is_enabled = gen9_dc_off_power_well_enabled,
+};
+
+static struct i915_power_well hsw_power_wells[] = {
+	{
+		.name = "always-on",
+		.always_on = 1,
+		.domains = POWER_DOMAIN_MASK,
+		.ops = &i9xx_always_on_power_well_ops,
+	},
+	{
+		.name = "display",
+		.domains = HSW_DISPLAY_POWER_DOMAINS,
+		.ops = &hsw_power_well_ops,
+	},
+};
+
+static struct i915_power_well bdw_power_wells[] = {
+	{
+		.name = "always-on",
+		.always_on = 1,
+		.domains = POWER_DOMAIN_MASK,
+		.ops = &i9xx_always_on_power_well_ops,
+	},
+	{
+		.name = "display",
+		.domains = BDW_DISPLAY_POWER_DOMAINS,
+		.ops = &hsw_power_well_ops,
+	},
+};
+
+static const struct i915_power_well_ops vlv_display_power_well_ops = {
+	.sync_hw = vlv_power_well_sync_hw,
+	.enable = vlv_display_power_well_enable,
+	.disable = vlv_display_power_well_disable,
+	.is_enabled = vlv_power_well_enabled,
+};
+
+static const struct i915_power_well_ops vlv_dpio_cmn_power_well_ops = {
+	.sync_hw = vlv_power_well_sync_hw,
+	.enable = vlv_dpio_cmn_power_well_enable,
+	.disable = vlv_dpio_cmn_power_well_disable,
+	.is_enabled = vlv_power_well_enabled,
+};
+
+static const struct i915_power_well_ops vlv_dpio_power_well_ops = {
+	.sync_hw = vlv_power_well_sync_hw,
+	.enable = vlv_power_well_enable,
+	.disable = vlv_power_well_disable,
+	.is_enabled = vlv_power_well_enabled,
+};
+
+static struct i915_power_well vlv_power_wells[] = {
+	{
+		.name = "always-on",
+		.always_on = 1,
+		.domains = POWER_DOMAIN_MASK,
+		.ops = &i9xx_always_on_power_well_ops,
+		.data = PUNIT_POWER_WELL_ALWAYS_ON,
+	},
+	{
+		.name = "display",
+		.domains = VLV_DISPLAY_POWER_DOMAINS,
+		.data = PUNIT_POWER_WELL_DISP2D,
+		.ops = &vlv_display_power_well_ops,
+	},
+	{
+		.name = "dpio-tx-b-01",
+		.domains = VLV_DPIO_TX_B_LANES_01_POWER_DOMAINS |
+			   VLV_DPIO_TX_B_LANES_23_POWER_DOMAINS |
+			   VLV_DPIO_TX_C_LANES_01_POWER_DOMAINS |
+			   VLV_DPIO_TX_C_LANES_23_POWER_DOMAINS,
+		.ops = &vlv_dpio_power_well_ops,
+		.data = PUNIT_POWER_WELL_DPIO_TX_B_LANES_01,
+	},
+	{
+		.name = "dpio-tx-b-23",
+		.domains = VLV_DPIO_TX_B_LANES_01_POWER_DOMAINS |
+			   VLV_DPIO_TX_B_LANES_23_POWER_DOMAINS |
+			   VLV_DPIO_TX_C_LANES_01_POWER_DOMAINS |
+			   VLV_DPIO_TX_C_LANES_23_POWER_DOMAINS,
+		.ops = &vlv_dpio_power_well_ops,
+		.data = PUNIT_POWER_WELL_DPIO_TX_B_LANES_23,
+	},
+	{
+		.name = "dpio-tx-c-01",
+		.domains = VLV_DPIO_TX_B_LANES_01_POWER_DOMAINS |
+			   VLV_DPIO_TX_B_LANES_23_POWER_DOMAINS |
+			   VLV_DPIO_TX_C_LANES_01_POWER_DOMAINS |
+			   VLV_DPIO_TX_C_LANES_23_POWER_DOMAINS,
+		.ops = &vlv_dpio_power_well_ops,
+		.data = PUNIT_POWER_WELL_DPIO_TX_C_LANES_01,
+	},
+	{
+		.name = "dpio-tx-c-23",
+		.domains = VLV_DPIO_TX_B_LANES_01_POWER_DOMAINS |
+			   VLV_DPIO_TX_B_LANES_23_POWER_DOMAINS |
+			   VLV_DPIO_TX_C_LANES_01_POWER_DOMAINS |
+			   VLV_DPIO_TX_C_LANES_23_POWER_DOMAINS,
+		.ops = &vlv_dpio_power_well_ops,
+		.data = PUNIT_POWER_WELL_DPIO_TX_C_LANES_23,
+	},
+	{
+		.name = "dpio-common",
+		.domains = VLV_DPIO_CMN_BC_POWER_DOMAINS,
+		.data = PUNIT_POWER_WELL_DPIO_CMN_BC,
+		.ops = &vlv_dpio_cmn_power_well_ops,
+	},
+};
+
+static struct i915_power_well chv_power_wells[] = {
+	{
+		.name = "always-on",
+		.always_on = 1,
+		.domains = POWER_DOMAIN_MASK,
+		.ops = &i9xx_always_on_power_well_ops,
+	},
+	{
+		.name = "display",
+		/*
+		 * Pipe A power well is the new disp2d well. Pipe B and C
+		 * power wells don't actually exist. Pipe A power well is
+		 * required for any pipe to work.
+		 */
+		.domains = CHV_DISPLAY_POWER_DOMAINS,
+		.data = PIPE_A,
+		.ops = &chv_pipe_power_well_ops,
+	},
+	{
+		.name = "dpio-common-bc",
+		.domains = CHV_DPIO_CMN_BC_POWER_DOMAINS,
+		.data = PUNIT_POWER_WELL_DPIO_CMN_BC,
+		.ops = &chv_dpio_cmn_power_well_ops,
+	},
+	{
+		.name = "dpio-common-d",
+		.domains = CHV_DPIO_CMN_D_POWER_DOMAINS,
+		.data = PUNIT_POWER_WELL_DPIO_CMN_D,
+		.ops = &chv_dpio_cmn_power_well_ops,
+	},
+};
+
+bool intel_display_power_well_is_enabled(struct drm_i915_private *dev_priv,
+				    int power_well_id)
+{
+	struct i915_power_well *power_well;
+	bool ret;
+
+	power_well = lookup_power_well(dev_priv, power_well_id);
+	ret = power_well->ops->is_enabled(dev_priv, power_well);
+
+	return ret;
+}
+
+static struct i915_power_well skl_power_wells[] = {
+	{
+		.name = "always-on",
+		.always_on = 1,
+		.domains = POWER_DOMAIN_MASK,
+		.ops = &i9xx_always_on_power_well_ops,
+		.data = SKL_DISP_PW_ALWAYS_ON,
+	},
+	{
+		.name = "power well 1",
+		/* Handled by the DMC firmware */
+		.domains = 0,
+		.ops = &skl_power_well_ops,
+		.data = SKL_DISP_PW_1,
+	},
+	{
+		.name = "MISC IO power well",
+		/* Handled by the DMC firmware */
+		.domains = 0,
+		.ops = &skl_power_well_ops,
+		.data = SKL_DISP_PW_MISC_IO,
+	},
+	{
+		.name = "DC off",
+		.domains = SKL_DISPLAY_DC_OFF_POWER_DOMAINS,
+		.ops = &gen9_dc_off_power_well_ops,
+		.data = SKL_DISP_PW_DC_OFF,
+	},
+	{
+		.name = "power well 2",
+		.domains = SKL_DISPLAY_POWERWELL_2_POWER_DOMAINS,
+		.ops = &skl_power_well_ops,
+		.data = SKL_DISP_PW_2,
+	},
+	{
+		.name = "DDI A/E power well",
+		.domains = SKL_DISPLAY_DDI_A_E_POWER_DOMAINS,
+		.ops = &skl_power_well_ops,
+		.data = SKL_DISP_PW_DDI_A_E,
+	},
+	{
+		.name = "DDI B power well",
+		.domains = SKL_DISPLAY_DDI_B_POWER_DOMAINS,
+		.ops = &skl_power_well_ops,
+		.data = SKL_DISP_PW_DDI_B,
+	},
+	{
+		.name = "DDI C power well",
+		.domains = SKL_DISPLAY_DDI_C_POWER_DOMAINS,
+		.ops = &skl_power_well_ops,
+		.data = SKL_DISP_PW_DDI_C,
+	},
+	{
+		.name = "DDI D power well",
+		.domains = SKL_DISPLAY_DDI_D_POWER_DOMAINS,
+		.ops = &skl_power_well_ops,
+		.data = SKL_DISP_PW_DDI_D,
+	},
+};
+
+static struct i915_power_well bxt_power_wells[] = {
+	{
+		.name = "always-on",
+		.always_on = 1,
+		.domains = POWER_DOMAIN_MASK,
+		.ops = &i9xx_always_on_power_well_ops,
+	},
+	{
+		.name = "power well 1",
+		.domains = 0,
+		.ops = &skl_power_well_ops,
+		.data = SKL_DISP_PW_1,
+	},
+	{
+		.name = "DC off",
+		.domains = BXT_DISPLAY_DC_OFF_POWER_DOMAINS,
+		.ops = &gen9_dc_off_power_well_ops,
+		.data = SKL_DISP_PW_DC_OFF,
+	},
+	{
+		.name = "power well 2",
+		.domains = BXT_DISPLAY_POWERWELL_2_POWER_DOMAINS,
+		.ops = &skl_power_well_ops,
+		.data = SKL_DISP_PW_2,
+	},
+};
+
+static int
+sanitize_disable_power_well_option(const struct drm_i915_private *dev_priv,
+				   int disable_power_well)
+{
+	if (disable_power_well >= 0)
+		return !!disable_power_well;
+
+	return 1;
+}
+
+static uint32_t get_allowed_dc_mask(const struct drm_i915_private *dev_priv,
+				    int enable_dc)
+{
+	uint32_t mask;
+	int requested_dc;
+	int max_dc;
+
+	if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv)) {
+		max_dc = 2;
+		mask = 0;
+	} else if (IS_BROXTON(dev_priv)) {
+		max_dc = 1;
+		/*
+		 * DC9 has a separate HW flow from the rest of the DC states,
+		 * not depending on the DMC firmware. It's needed by system
+		 * suspend/resume, so allow it unconditionally.
+		 */
+		mask = DC_STATE_EN_DC9;
+	} else {
+		max_dc = 0;
+		mask = 0;
+	}
+
+	if (!i915.disable_power_well)
+		max_dc = 0;
+
+	if (enable_dc >= 0 && enable_dc <= max_dc) {
+		requested_dc = enable_dc;
+	} else if (enable_dc == -1) {
+		requested_dc = max_dc;
+	} else if (enable_dc > max_dc && enable_dc <= 2) {
+		DRM_DEBUG_KMS("Adjusting requested max DC state (%d->%d)\n",
+			      enable_dc, max_dc);
+		requested_dc = max_dc;
+	} else {
+		DRM_ERROR("Unexpected value for enable_dc (%d)\n", enable_dc);
+		requested_dc = max_dc;
+	}
+
+	if (requested_dc > 1)
+		mask |= DC_STATE_EN_UPTO_DC6;
+	if (requested_dc > 0)
+		mask |= DC_STATE_EN_UPTO_DC5;
+
+	DRM_DEBUG_KMS("Allowed DC state mask %02x\n", mask);
+
+	return mask;
+}
+
+#define set_power_wells(power_domains, __power_wells) ({		\
+	(power_domains)->power_wells = (__power_wells);			\
+	(power_domains)->power_well_count = ARRAY_SIZE(__power_wells);	\
+})
+
+/**
+ * intel_power_domains_init - initializes the power domain structures
+ * @dev_priv: i915 device instance
+ *
+ * Initializes the power domain structures for @dev_priv depending upon the
+ * supported platform.
+ */
+int intel_power_domains_init(struct drm_i915_private *dev_priv)
+{
+	struct i915_power_domains *power_domains = &dev_priv->power_domains;
+
+	i915.disable_power_well = sanitize_disable_power_well_option(dev_priv,
+						     i915.disable_power_well);
+	dev_priv->csr.allowed_dc_mask = get_allowed_dc_mask(dev_priv,
+							    i915.enable_dc);
+
+	BUILD_BUG_ON(POWER_DOMAIN_NUM > 31);
+
+	mutex_init(&power_domains->lock);
+
+	/*
+	 * The enabling order will be from lower to higher indexed wells,
+	 * the disabling order is reversed.
+	 */
+	if (IS_HASWELL(dev_priv)) {
+		set_power_wells(power_domains, hsw_power_wells);
+	} else if (IS_BROADWELL(dev_priv)) {
+		set_power_wells(power_domains, bdw_power_wells);
+	} else if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv)) {
+		set_power_wells(power_domains, skl_power_wells);
+	} else if (IS_BROXTON(dev_priv)) {
+		set_power_wells(power_domains, bxt_power_wells);
+	} else if (IS_CHERRYVIEW(dev_priv)) {
+		set_power_wells(power_domains, chv_power_wells);
+	} else if (IS_VALLEYVIEW(dev_priv)) {
+		set_power_wells(power_domains, vlv_power_wells);
+	} else {
+		set_power_wells(power_domains, i9xx_always_on_power_well);
+	}
+
+	return 0;
+}
+
+/**
+ * intel_power_domains_fini - finalizes the power domain structures
+ * @dev_priv: i915 device instance
+ *
+ * Finalizes the power domain structures for @dev_priv depending upon the
+ * supported platform. This function also disables runtime pm and ensures that
+ * the device stays powered up so that the driver can be reloaded.
+ */
+void intel_power_domains_fini(struct drm_i915_private *dev_priv)
+{
+	struct device *device = &dev_priv->dev->pdev->dev;
+
+	/*
+	 * The i915.ko module is still not prepared to be loaded when
+	 * the power well is not enabled, so just enable it in case
+	 * we're going to unload/reload.
+	 * The following also reacquires the RPM reference the core passed
+	 * to the driver during loading, which is dropped in
+	 * intel_runtime_pm_enable(). We have to hand back the control of the
+	 * device to the core with this reference held.
+	 */
+	intel_display_set_init_power(dev_priv, true);
+
+	/* Remove the refcount we took to keep power well support disabled. */
+	if (!i915.disable_power_well)
+		intel_display_power_put(dev_priv, POWER_DOMAIN_INIT);
+
+	/*
+	 * Remove the refcount we took in intel_runtime_pm_enable() in case
+	 * the platform doesn't support runtime PM.
+	 */
+	if (!HAS_RUNTIME_PM(dev_priv))
+		pm_runtime_put(device);
+}
+
+static void intel_power_domains_sync_hw(struct drm_i915_private *dev_priv)
+{
+	struct i915_power_domains *power_domains = &dev_priv->power_domains;
+	struct i915_power_well *power_well;
+	int i;
+
+	mutex_lock(&power_domains->lock);
+	for_each_power_well(i, power_well, POWER_DOMAIN_MASK, power_domains) {
+		power_well->ops->sync_hw(dev_priv, power_well);
+		power_well->hw_enabled = power_well->ops->is_enabled(dev_priv,
+								     power_well);
+	}
+	mutex_unlock(&power_domains->lock);
+}
+
+static void skl_display_core_init(struct drm_i915_private *dev_priv,
+				   bool resume)
+{
+	struct i915_power_domains *power_domains = &dev_priv->power_domains;
+	struct i915_power_well *well;
+	uint32_t val;
+
+	gen9_set_dc_state(dev_priv, DC_STATE_DISABLE);
+
+	/* enable PCH reset handshake */
+	val = I915_READ(HSW_NDE_RSTWRN_OPT);
+	I915_WRITE(HSW_NDE_RSTWRN_OPT, val | RESET_PCH_HANDSHAKE_ENABLE);
+
+	/* enable PG1 and Misc I/O */
+	mutex_lock(&power_domains->lock);
+
+	well = lookup_power_well(dev_priv, SKL_DISP_PW_1);
+	intel_power_well_enable(dev_priv, well);
+
+	well = lookup_power_well(dev_priv, SKL_DISP_PW_MISC_IO);
+	intel_power_well_enable(dev_priv, well);
+
+	mutex_unlock(&power_domains->lock);
+
+	if (!resume)
+		return;
+
+	skl_init_cdclk(dev_priv);
+
+	if (dev_priv->csr.dmc_payload)
+		intel_csr_load_program(dev_priv);
+}
+
+static void skl_display_core_uninit(struct drm_i915_private *dev_priv)
+{
+	struct i915_power_domains *power_domains = &dev_priv->power_domains;
+	struct i915_power_well *well;
+
+	gen9_set_dc_state(dev_priv, DC_STATE_DISABLE);
+
+	skl_uninit_cdclk(dev_priv);
+
+	/* The spec doesn't call for removing the reset handshake flag */
+	/* disable PG1 and Misc I/O */
+
+	mutex_lock(&power_domains->lock);
+
+	well = lookup_power_well(dev_priv, SKL_DISP_PW_MISC_IO);
+	intel_power_well_disable(dev_priv, well);
+
+	well = lookup_power_well(dev_priv, SKL_DISP_PW_1);
+	intel_power_well_disable(dev_priv, well);
+
+	mutex_unlock(&power_domains->lock);
+}
+
+void bxt_display_core_init(struct drm_i915_private *dev_priv,
+			   bool resume)
+{
+	struct i915_power_domains *power_domains = &dev_priv->power_domains;
+	struct i915_power_well *well;
+	uint32_t val;
+
+	gen9_set_dc_state(dev_priv, DC_STATE_DISABLE);
+
+	/*
+	 * NDE_RSTWRN_OPT RST PCH Handshake En must always be 0b on BXT
+	 * or else the reset will hang because there is no PCH to respond.
+	 * Move the handshake programming to initialization sequence.
+	 * Previously was left up to BIOS.
+	 */
+	val = I915_READ(HSW_NDE_RSTWRN_OPT);
+	val &= ~RESET_PCH_HANDSHAKE_ENABLE;
+	I915_WRITE(HSW_NDE_RSTWRN_OPT, val);
+
+	/* Enable PG1 */
+	mutex_lock(&power_domains->lock);
+
+	well = lookup_power_well(dev_priv, SKL_DISP_PW_1);
+	intel_power_well_enable(dev_priv, well);
+
+	mutex_unlock(&power_domains->lock);
+
+	broxton_init_cdclk(dev_priv);
+	broxton_ddi_phy_init(dev_priv);
+
+	broxton_cdclk_verify_state(dev_priv);
+	broxton_ddi_phy_verify_state(dev_priv);
+
+	if (resume && dev_priv->csr.dmc_payload)
+		intel_csr_load_program(dev_priv);
+}
+
+void bxt_display_core_uninit(struct drm_i915_private *dev_priv)
+{
+	struct i915_power_domains *power_domains = &dev_priv->power_domains;
+	struct i915_power_well *well;
+
+	gen9_set_dc_state(dev_priv, DC_STATE_DISABLE);
+
+	broxton_ddi_phy_uninit(dev_priv);
+	broxton_uninit_cdclk(dev_priv);
+
+	/* The spec doesn't call for removing the reset handshake flag */
+
+	/* Disable PG1 */
+	mutex_lock(&power_domains->lock);
+
+	well = lookup_power_well(dev_priv, SKL_DISP_PW_1);
+	intel_power_well_disable(dev_priv, well);
+
+	mutex_unlock(&power_domains->lock);
+}
+
+static void chv_phy_control_init(struct drm_i915_private *dev_priv)
+{
+	struct i915_power_well *cmn_bc =
+		lookup_power_well(dev_priv, PUNIT_POWER_WELL_DPIO_CMN_BC);
+	struct i915_power_well *cmn_d =
+		lookup_power_well(dev_priv, PUNIT_POWER_WELL_DPIO_CMN_D);
+
+	/*
+	 * DISPLAY_PHY_CONTROL can get corrupted if read. As a
+	 * workaround never ever read DISPLAY_PHY_CONTROL, and
+	 * instead maintain a shadow copy ourselves. Use the actual
+	 * power well state and lane status to reconstruct the
+	 * expected initial value.
+	 */
+	dev_priv->chv_phy_control =
+		PHY_LDO_SEQ_DELAY(PHY_LDO_DELAY_600NS, DPIO_PHY0) |
+		PHY_LDO_SEQ_DELAY(PHY_LDO_DELAY_600NS, DPIO_PHY1) |
+		PHY_CH_POWER_MODE(PHY_CH_DEEP_PSR, DPIO_PHY0, DPIO_CH0) |
+		PHY_CH_POWER_MODE(PHY_CH_DEEP_PSR, DPIO_PHY0, DPIO_CH1) |
+		PHY_CH_POWER_MODE(PHY_CH_DEEP_PSR, DPIO_PHY1, DPIO_CH0);
+
+	/*
+	 * If all lanes are disabled we leave the override disabled
+	 * with all power down bits cleared to match the state we
+	 * would use after disabling the port. Otherwise enable the
+	 * override and set the lane powerdown bits accding to the
+	 * current lane status.
+	 */
+	if (cmn_bc->ops->is_enabled(dev_priv, cmn_bc)) {
+		uint32_t status = I915_READ(DPLL(PIPE_A));
+		unsigned int mask;
+
+		mask = status & DPLL_PORTB_READY_MASK;
+		if (mask == 0xf)
+			mask = 0x0;
+		else
+			dev_priv->chv_phy_control |=
+				PHY_CH_POWER_DOWN_OVRD_EN(DPIO_PHY0, DPIO_CH0);
+
+		dev_priv->chv_phy_control |=
+			PHY_CH_POWER_DOWN_OVRD(mask, DPIO_PHY0, DPIO_CH0);
+
+		mask = (status & DPLL_PORTC_READY_MASK) >> 4;
+		if (mask == 0xf)
+			mask = 0x0;
+		else
+			dev_priv->chv_phy_control |=
+				PHY_CH_POWER_DOWN_OVRD_EN(DPIO_PHY0, DPIO_CH1);
+
+		dev_priv->chv_phy_control |=
+			PHY_CH_POWER_DOWN_OVRD(mask, DPIO_PHY0, DPIO_CH1);
+
+		dev_priv->chv_phy_control |= PHY_COM_LANE_RESET_DEASSERT(DPIO_PHY0);
+
+		dev_priv->chv_phy_assert[DPIO_PHY0] = false;
+	} else {
+		dev_priv->chv_phy_assert[DPIO_PHY0] = true;
+	}
+
+	if (cmn_d->ops->is_enabled(dev_priv, cmn_d)) {
+		uint32_t status = I915_READ(DPIO_PHY_STATUS);
+		unsigned int mask;
+
+		mask = status & DPLL_PORTD_READY_MASK;
+
+		if (mask == 0xf)
+			mask = 0x0;
+		else
+			dev_priv->chv_phy_control |=
+				PHY_CH_POWER_DOWN_OVRD_EN(DPIO_PHY1, DPIO_CH0);
+
+		dev_priv->chv_phy_control |=
+			PHY_CH_POWER_DOWN_OVRD(mask, DPIO_PHY1, DPIO_CH0);
+
+		dev_priv->chv_phy_control |= PHY_COM_LANE_RESET_DEASSERT(DPIO_PHY1);
+
+		dev_priv->chv_phy_assert[DPIO_PHY1] = false;
+	} else {
+		dev_priv->chv_phy_assert[DPIO_PHY1] = true;
+	}
+
+	I915_WRITE(DISPLAY_PHY_CONTROL, dev_priv->chv_phy_control);
+
+	DRM_DEBUG_KMS("Initial PHY_CONTROL=0x%08x\n",
+		      dev_priv->chv_phy_control);
+}
+
+static void vlv_cmnlane_wa(struct drm_i915_private *dev_priv)
+{
+	struct i915_power_well *cmn =
+		lookup_power_well(dev_priv, PUNIT_POWER_WELL_DPIO_CMN_BC);
+	struct i915_power_well *disp2d =
+		lookup_power_well(dev_priv, PUNIT_POWER_WELL_DISP2D);
+
+	/* If the display might be already active skip this */
+	if (cmn->ops->is_enabled(dev_priv, cmn) &&
+	    disp2d->ops->is_enabled(dev_priv, disp2d) &&
+	    I915_READ(DPIO_CTL) & DPIO_CMNRST)
+		return;
+
+	DRM_DEBUG_KMS("toggling display PHY side reset\n");
+
+	/* cmnlane needs DPLL registers */
+	disp2d->ops->enable(dev_priv, disp2d);
+
+	/*
+	 * From VLV2A0_DP_eDP_HDMI_DPIO_driver_vbios_notes_11.docx:
+	 * Need to assert and de-assert PHY SB reset by gating the
+	 * common lane power, then un-gating it.
+	 * Simply ungating isn't enough to reset the PHY enough to get
+	 * ports and lanes running.
+	 */
+	cmn->ops->disable(dev_priv, cmn);
+}
+
+/**
+ * intel_power_domains_init_hw - initialize hardware power domain state
+ * @dev_priv: i915 device instance
+ *
+ * This function initializes the hardware power domain state and enables all
+ * power domains using intel_display_set_init_power().
+ */
+void intel_power_domains_init_hw(struct drm_i915_private *dev_priv, bool resume)
+{
+	struct drm_device *dev = dev_priv->dev;
+	struct i915_power_domains *power_domains = &dev_priv->power_domains;
+
+	power_domains->initializing = true;
+
+	if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev)) {
+		skl_display_core_init(dev_priv, resume);
+	} else if (IS_BROXTON(dev)) {
+		bxt_display_core_init(dev_priv, resume);
+	} else if (IS_CHERRYVIEW(dev)) {
+		mutex_lock(&power_domains->lock);
+		chv_phy_control_init(dev_priv);
+		mutex_unlock(&power_domains->lock);
+	} else if (IS_VALLEYVIEW(dev)) {
+		mutex_lock(&power_domains->lock);
+		vlv_cmnlane_wa(dev_priv);
+		mutex_unlock(&power_domains->lock);
+	}
+
+	/* For now, we need the power well to be always enabled. */
+	intel_display_set_init_power(dev_priv, true);
+	/* Disable power support if the user asked so. */
+	if (!i915.disable_power_well)
+		intel_display_power_get(dev_priv, POWER_DOMAIN_INIT);
+	intel_power_domains_sync_hw(dev_priv);
+	power_domains->initializing = false;
+}
+
+/**
+ * intel_power_domains_suspend - suspend power domain state
+ * @dev_priv: i915 device instance
+ *
+ * This function prepares the hardware power domain state before entering
+ * system suspend. It must be paired with intel_power_domains_init_hw().
+ */
+void intel_power_domains_suspend(struct drm_i915_private *dev_priv)
+{
+	/*
+	 * Even if power well support was disabled we still want to disable
+	 * power wells while we are system suspended.
+	 */
+	if (!i915.disable_power_well)
+		intel_display_power_put(dev_priv, POWER_DOMAIN_INIT);
+
+	if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv))
+		skl_display_core_uninit(dev_priv);
+	else if (IS_BROXTON(dev_priv))
+		bxt_display_core_uninit(dev_priv);
+}
+
+/**
+ * intel_runtime_pm_get - grab a runtime pm reference
+ * @dev_priv: i915 device instance
+ *
+ * This function grabs a device-level runtime pm reference (mostly used for GEM
+ * code to ensure the GTT or GT is on) and ensures that it is powered up.
+ *
+ * Any runtime pm reference obtained by this function must have a symmetric
+ * call to intel_runtime_pm_put() to release the reference again.
+ */
+void intel_runtime_pm_get(struct drm_i915_private *dev_priv)
+{
+	struct drm_device *dev = dev_priv->dev;
+	struct device *device = &dev->pdev->dev;
+
+	pm_runtime_get_sync(device);
+
+	atomic_inc(&dev_priv->pm.wakeref_count);
+	assert_rpm_wakelock_held(dev_priv);
+}
+
+/**
+ * intel_runtime_pm_get_if_in_use - grab a runtime pm reference if device in use
+ * @dev_priv: i915 device instance
+ *
+ * This function grabs a device-level runtime pm reference if the device is
+ * already in use and ensures that it is powered up.
+ *
+ * Any runtime pm reference obtained by this function must have a symmetric
+ * call to intel_runtime_pm_put() to release the reference again.
+ */
+bool intel_runtime_pm_get_if_in_use(struct drm_i915_private *dev_priv)
+{
+	struct drm_device *dev = dev_priv->dev;
+	struct device *device = &dev->pdev->dev;
+
+	if (IS_ENABLED(CONFIG_PM)) {
+		int ret = pm_runtime_get_if_in_use(device);
+
+		/*
+		 * In cases runtime PM is disabled by the RPM core and we get
+		 * an -EINVAL return value we are not supposed to call this
+		 * function, since the power state is undefined. This applies
+		 * atm to the late/early system suspend/resume handlers.
+		 */
+		WARN_ON_ONCE(ret < 0);
+		if (ret <= 0)
+			return false;
+	}
+
+	atomic_inc(&dev_priv->pm.wakeref_count);
+	assert_rpm_wakelock_held(dev_priv);
+
+	return true;
+}
+
+/**
+ * intel_runtime_pm_get_noresume - grab a runtime pm reference
+ * @dev_priv: i915 device instance
+ *
+ * This function grabs a device-level runtime pm reference (mostly used for GEM
+ * code to ensure the GTT or GT is on).
+ *
+ * It will _not_ power up the device but instead only check that it's powered
+ * on.  Therefore it is only valid to call this functions from contexts where
+ * the device is known to be powered up and where trying to power it up would
+ * result in hilarity and deadlocks. That pretty much means only the system
+ * suspend/resume code where this is used to grab runtime pm references for
+ * delayed setup down in work items.
+ *
+ * Any runtime pm reference obtained by this function must have a symmetric
+ * call to intel_runtime_pm_put() to release the reference again.
+ */
+void intel_runtime_pm_get_noresume(struct drm_i915_private *dev_priv)
+{
+	struct drm_device *dev = dev_priv->dev;
+	struct device *device = &dev->pdev->dev;
+
+	assert_rpm_wakelock_held(dev_priv);
+	pm_runtime_get_noresume(device);
+
+	atomic_inc(&dev_priv->pm.wakeref_count);
+}
+
+/**
+ * intel_runtime_pm_put - release a runtime pm reference
+ * @dev_priv: i915 device instance
+ *
+ * This function drops the device-level runtime pm reference obtained by
+ * intel_runtime_pm_get() and might power down the corresponding
+ * hardware block right away if this is the last reference.
+ */
+void intel_runtime_pm_put(struct drm_i915_private *dev_priv)
+{
+	struct drm_device *dev = dev_priv->dev;
+	struct device *device = &dev->pdev->dev;
+
+	assert_rpm_wakelock_held(dev_priv);
+	if (atomic_dec_and_test(&dev_priv->pm.wakeref_count))
+		atomic_inc(&dev_priv->pm.atomic_seq);
+
+	pm_runtime_mark_last_busy(device);
+	pm_runtime_put_autosuspend(device);
+}
+
+/**
+ * intel_runtime_pm_enable - enable runtime pm
+ * @dev_priv: i915 device instance
+ *
+ * This function enables runtime pm at the end of the driver load sequence.
+ *
+ * Note that this function does currently not enable runtime pm for the
+ * subordinate display power domains. That is only done on the first modeset
+ * using intel_display_set_init_power().
+ */
+void intel_runtime_pm_enable(struct drm_i915_private *dev_priv)
+{
+	struct drm_device *dev = dev_priv->dev;
+	struct device *device = &dev->pdev->dev;
+
+	pm_runtime_set_autosuspend_delay(device, 10000); /* 10s */
+	pm_runtime_mark_last_busy(device);
+
+	/*
+	 * Take a permanent reference to disable the RPM functionality and drop
+	 * it only when unloading the driver. Use the low level get/put helpers,
+	 * so the driver's own RPM reference tracking asserts also work on
+	 * platforms without RPM support.
+	 */
+	if (!HAS_RUNTIME_PM(dev)) {
+		pm_runtime_dont_use_autosuspend(device);
+		pm_runtime_get_sync(device);
+	} else {
+		pm_runtime_use_autosuspend(device);
+	}
+
+	/*
+	 * The core calls the driver load handler with an RPM reference held.
+	 * We drop that here and will reacquire it during unloading in
+	 * intel_power_domains_fini().
+	 */
+	pm_runtime_put_autosuspend(device);
+}
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/i915/intel_sdvo.c
@@ -0,0 +1,3080 @@
+/*
+ * Copyright 2006 Dave Airlie <airlied@linux.ie>
+ * Copyright © 2006-2007 Intel Corporation
+ *   Jesse Barnes <jesse.barnes@intel.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *	Eric Anholt <eric@anholt.net>
+ */
+#include <linux/i2c.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/export.h>
+#include <drm/drmP.h>
+#include <drm/drm_atomic_helper.h>
+#include <drm/drm_crtc.h>
+#include <drm/drm_edid.h>
+#include "intel_drv.h"
+#include <drm/i915_drm.h>
+#include "i915_drv.h"
+#include "intel_sdvo_regs.h"
+
+#define SDVO_TMDS_MASK (SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_TMDS1)
+#define SDVO_RGB_MASK  (SDVO_OUTPUT_RGB0 | SDVO_OUTPUT_RGB1)
+#define SDVO_LVDS_MASK (SDVO_OUTPUT_LVDS0 | SDVO_OUTPUT_LVDS1)
+#define SDVO_TV_MASK   (SDVO_OUTPUT_CVBS0 | SDVO_OUTPUT_SVID0 | SDVO_OUTPUT_YPRPB0)
+
+#define SDVO_OUTPUT_MASK (SDVO_TMDS_MASK | SDVO_RGB_MASK | SDVO_LVDS_MASK |\
+			SDVO_TV_MASK)
+
+#define IS_TV(c)	(c->output_flag & SDVO_TV_MASK)
+#define IS_TMDS(c)	(c->output_flag & SDVO_TMDS_MASK)
+#define IS_LVDS(c)	(c->output_flag & SDVO_LVDS_MASK)
+#define IS_TV_OR_LVDS(c) (c->output_flag & (SDVO_TV_MASK | SDVO_LVDS_MASK))
+#define IS_DIGITAL(c) (c->output_flag & (SDVO_TMDS_MASK | SDVO_LVDS_MASK))
+
+
+static const char * const tv_format_names[] = {
+	"NTSC_M"   , "NTSC_J"  , "NTSC_443",
+	"PAL_B"    , "PAL_D"   , "PAL_G"   ,
+	"PAL_H"    , "PAL_I"   , "PAL_M"   ,
+	"PAL_N"    , "PAL_NC"  , "PAL_60"  ,
+	"SECAM_B"  , "SECAM_D" , "SECAM_G" ,
+	"SECAM_K"  , "SECAM_K1", "SECAM_L" ,
+	"SECAM_60"
+};
+
+#define TV_FORMAT_NUM  ARRAY_SIZE(tv_format_names)
+
+struct intel_sdvo {
+	struct intel_encoder base;
+
+	struct i2c_adapter *i2c;
+	u8 slave_addr;
+
+	struct i2c_adapter ddc;
+
+	/* Register for the SDVO device: SDVOB or SDVOC */
+	i915_reg_t sdvo_reg;
+
+	/* Active outputs controlled by this SDVO output */
+	uint16_t controlled_output;
+
+	/*
+	 * Capabilities of the SDVO device returned by
+	 * intel_sdvo_get_capabilities()
+	 */
+	struct intel_sdvo_caps caps;
+
+	/* Pixel clock limitations reported by the SDVO device, in kHz */
+	int pixel_clock_min, pixel_clock_max;
+
+	/*
+	* For multiple function SDVO device,
+	* this is for current attached outputs.
+	*/
+	uint16_t attached_output;
+
+	/*
+	 * Hotplug activation bits for this device
+	 */
+	uint16_t hotplug_active;
+
+	/**
+	 * This is used to select the color range of RBG outputs in HDMI mode.
+	 * It is only valid when using TMDS encoding and 8 bit per color mode.
+	 */
+	uint32_t color_range;
+	bool color_range_auto;
+
+	/**
+	 * HDMI user specified aspect ratio
+	 */
+	enum hdmi_picture_aspect aspect_ratio;
+
+	/**
+	 * This is set if we're going to treat the device as TV-out.
+	 *
+	 * While we have these nice friendly flags for output types that ought
+	 * to decide this for us, the S-Video output on our HDMI+S-Video card
+	 * shows up as RGB1 (VGA).
+	 */
+	bool is_tv;
+
+	enum port port;
+
+	/* This is for current tv format name */
+	int tv_format_index;
+
+	/**
+	 * This is set if we treat the device as HDMI, instead of DVI.
+	 */
+	bool is_hdmi;
+	bool has_hdmi_monitor;
+	bool has_hdmi_audio;
+	bool rgb_quant_range_selectable;
+
+	/**
+	 * This is set if we detect output of sdvo device as LVDS and
+	 * have a valid fixed mode to use with the panel.
+	 */
+	bool is_lvds;
+
+	/**
+	 * This is sdvo fixed pannel mode pointer
+	 */
+	struct drm_display_mode *sdvo_lvds_fixed_mode;
+
+	/* DDC bus used by this SDVO encoder */
+	uint8_t ddc_bus;
+
+	/*
+	 * the sdvo flag gets lost in round trip: dtd->adjusted_mode->dtd
+	 */
+	uint8_t dtd_sdvo_flags;
+};
+
+struct intel_sdvo_connector {
+	struct intel_connector base;
+
+	/* Mark the type of connector */
+	uint16_t output_flag;
+
+	enum hdmi_force_audio force_audio;
+
+	/* This contains all current supported TV format */
+	u8 tv_format_supported[TV_FORMAT_NUM];
+	int   format_supported_num;
+	struct drm_property *tv_format;
+
+	/* add the property for the SDVO-TV */
+	struct drm_property *left;
+	struct drm_property *right;
+	struct drm_property *top;
+	struct drm_property *bottom;
+	struct drm_property *hpos;
+	struct drm_property *vpos;
+	struct drm_property *contrast;
+	struct drm_property *saturation;
+	struct drm_property *hue;
+	struct drm_property *sharpness;
+	struct drm_property *flicker_filter;
+	struct drm_property *flicker_filter_adaptive;
+	struct drm_property *flicker_filter_2d;
+	struct drm_property *tv_chroma_filter;
+	struct drm_property *tv_luma_filter;
+	struct drm_property *dot_crawl;
+
+	/* add the property for the SDVO-TV/LVDS */
+	struct drm_property *brightness;
+
+	/* Add variable to record current setting for the above property */
+	u32	left_margin, right_margin, top_margin, bottom_margin;
+
+	/* this is to get the range of margin.*/
+	u32	max_hscan,  max_vscan;
+	u32	max_hpos, cur_hpos;
+	u32	max_vpos, cur_vpos;
+	u32	cur_brightness, max_brightness;
+	u32	cur_contrast,	max_contrast;
+	u32	cur_saturation, max_saturation;
+	u32	cur_hue,	max_hue;
+	u32	cur_sharpness,	max_sharpness;
+	u32	cur_flicker_filter,		max_flicker_filter;
+	u32	cur_flicker_filter_adaptive,	max_flicker_filter_adaptive;
+	u32	cur_flicker_filter_2d,		max_flicker_filter_2d;
+	u32	cur_tv_chroma_filter,	max_tv_chroma_filter;
+	u32	cur_tv_luma_filter,	max_tv_luma_filter;
+	u32	cur_dot_crawl,	max_dot_crawl;
+};
+
+static struct intel_sdvo *to_sdvo(struct intel_encoder *encoder)
+{
+	return container_of(encoder, struct intel_sdvo, base);
+}
+
+static struct intel_sdvo *intel_attached_sdvo(struct drm_connector *connector)
+{
+	return to_sdvo(intel_attached_encoder(connector));
+}
+
+static struct intel_sdvo_connector *to_intel_sdvo_connector(struct drm_connector *connector)
+{
+	return container_of(to_intel_connector(connector), struct intel_sdvo_connector, base);
+}
+
+static bool
+intel_sdvo_output_setup(struct intel_sdvo *intel_sdvo, uint16_t flags);
+static bool
+intel_sdvo_tv_create_property(struct intel_sdvo *intel_sdvo,
+			      struct intel_sdvo_connector *intel_sdvo_connector,
+			      int type);
+static bool
+intel_sdvo_create_enhance_property(struct intel_sdvo *intel_sdvo,
+				   struct intel_sdvo_connector *intel_sdvo_connector);
+
+/**
+ * Writes the SDVOB or SDVOC with the given value, but always writes both
+ * SDVOB and SDVOC to work around apparent hardware issues (according to
+ * comments in the BIOS).
+ */
+static void intel_sdvo_write_sdvox(struct intel_sdvo *intel_sdvo, u32 val)
+{
+	struct drm_device *dev = intel_sdvo->base.base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	u32 bval = val, cval = val;
+	int i;
+
+	if (HAS_PCH_SPLIT(dev_priv)) {
+		I915_WRITE(intel_sdvo->sdvo_reg, val);
+		POSTING_READ(intel_sdvo->sdvo_reg);
+		/*
+		 * HW workaround, need to write this twice for issue
+		 * that may result in first write getting masked.
+		 */
+		if (HAS_PCH_IBX(dev)) {
+			I915_WRITE(intel_sdvo->sdvo_reg, val);
+			POSTING_READ(intel_sdvo->sdvo_reg);
+		}
+		return;
+	}
+
+	if (intel_sdvo->port == PORT_B)
+		cval = I915_READ(GEN3_SDVOC);
+	else
+		bval = I915_READ(GEN3_SDVOB);
+
+	/*
+	 * Write the registers twice for luck. Sometimes,
+	 * writing them only once doesn't appear to 'stick'.
+	 * The BIOS does this too. Yay, magic
+	 */
+	for (i = 0; i < 2; i++)
+	{
+		I915_WRITE(GEN3_SDVOB, bval);
+		POSTING_READ(GEN3_SDVOB);
+		I915_WRITE(GEN3_SDVOC, cval);
+		POSTING_READ(GEN3_SDVOC);
+	}
+}
+
+static bool intel_sdvo_read_byte(struct intel_sdvo *intel_sdvo, u8 addr, u8 *ch)
+{
+	struct i2c_msg msgs[] = {
+		{
+			.addr = intel_sdvo->slave_addr,
+			.flags = 0,
+			.len = 1,
+			.buf = &addr,
+		},
+		{
+			.addr = intel_sdvo->slave_addr,
+			.flags = I2C_M_RD,
+			.len = 1,
+			.buf = ch,
+		}
+	};
+	int ret;
+
+	if ((ret = i2c_transfer(intel_sdvo->i2c, msgs, 2)) == 2)
+		return true;
+
+	DRM_DEBUG_KMS("i2c transfer returned %d\n", ret);
+	return false;
+}
+
+#define SDVO_CMD_NAME_ENTRY(cmd) {cmd, #cmd}
+/** Mapping of command numbers to names, for debug output */
+static const struct _sdvo_cmd_name {
+	u8 cmd;
+	const char *name;
+} sdvo_cmd_names[] = {
+	SDVO_CMD_NAME_ENTRY(SDVO_CMD_RESET),
+	SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_DEVICE_CAPS),
+	SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_FIRMWARE_REV),
+	SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_TRAINED_INPUTS),
+	SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_ACTIVE_OUTPUTS),
+	SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_ACTIVE_OUTPUTS),
+	SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_IN_OUT_MAP),
+	SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_IN_OUT_MAP),
+	SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_ATTACHED_DISPLAYS),
+	SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_HOT_PLUG_SUPPORT),
+	SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_ACTIVE_HOT_PLUG),
+	SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_ACTIVE_HOT_PLUG),
+	SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_INTERRUPT_EVENT_SOURCE),
+	SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_TARGET_INPUT),
+	SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_TARGET_OUTPUT),
+	SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_INPUT_TIMINGS_PART1),
+	SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_INPUT_TIMINGS_PART2),
+	SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_INPUT_TIMINGS_PART1),
+	SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_INPUT_TIMINGS_PART2),
+	SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_INPUT_TIMINGS_PART1),
+	SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_OUTPUT_TIMINGS_PART1),
+	SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_OUTPUT_TIMINGS_PART2),
+	SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_OUTPUT_TIMINGS_PART1),
+	SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_OUTPUT_TIMINGS_PART2),
+	SDVO_CMD_NAME_ENTRY(SDVO_CMD_CREATE_PREFERRED_INPUT_TIMING),
+	SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART1),
+	SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART2),
+	SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_INPUT_PIXEL_CLOCK_RANGE),
+	SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_OUTPUT_PIXEL_CLOCK_RANGE),
+	SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SUPPORTED_CLOCK_RATE_MULTS),
+	SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_CLOCK_RATE_MULT),
+	SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_CLOCK_RATE_MULT),
+	SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SUPPORTED_TV_FORMATS),
+	SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_TV_FORMAT),
+	SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_TV_FORMAT),
+	SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SUPPORTED_POWER_STATES),
+	SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_POWER_STATE),
+	SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_ENCODER_POWER_STATE),
+	SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_DISPLAY_POWER_STATE),
+	SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_CONTROL_BUS_SWITCH),
+	SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SDTV_RESOLUTION_SUPPORT),
+	SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SCALED_HDTV_RESOLUTION_SUPPORT),
+	SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SUPPORTED_ENHANCEMENTS),
+
+	/* Add the op code for SDVO enhancements */
+	SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_HPOS),
+	SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_HPOS),
+	SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_HPOS),
+	SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_VPOS),
+	SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_VPOS),
+	SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_VPOS),
+	SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_SATURATION),
+	SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SATURATION),
+	SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_SATURATION),
+	SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_HUE),
+	SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_HUE),
+	SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_HUE),
+	SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_CONTRAST),
+	SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_CONTRAST),
+	SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_CONTRAST),
+	SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_BRIGHTNESS),
+	SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_BRIGHTNESS),
+	SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_BRIGHTNESS),
+	SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_OVERSCAN_H),
+	SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_OVERSCAN_H),
+	SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_OVERSCAN_H),
+	SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_OVERSCAN_V),
+	SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_OVERSCAN_V),
+	SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_OVERSCAN_V),
+	SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_FLICKER_FILTER),
+	SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_FLICKER_FILTER),
+	SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_FLICKER_FILTER),
+	SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_FLICKER_FILTER_ADAPTIVE),
+	SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_FLICKER_FILTER_ADAPTIVE),
+	SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_FLICKER_FILTER_ADAPTIVE),
+	SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_FLICKER_FILTER_2D),
+	SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_FLICKER_FILTER_2D),
+	SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_FLICKER_FILTER_2D),
+	SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_SHARPNESS),
+	SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SHARPNESS),
+	SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_SHARPNESS),
+	SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_DOT_CRAWL),
+	SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_DOT_CRAWL),
+	SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_TV_CHROMA_FILTER),
+	SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_TV_CHROMA_FILTER),
+	SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_TV_CHROMA_FILTER),
+	SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_TV_LUMA_FILTER),
+	SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_TV_LUMA_FILTER),
+	SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_TV_LUMA_FILTER),
+
+	/* HDMI op code */
+	SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SUPP_ENCODE),
+	SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_ENCODE),
+	SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_ENCODE),
+	SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_PIXEL_REPLI),
+	SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_PIXEL_REPLI),
+	SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_COLORIMETRY_CAP),
+	SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_COLORIMETRY),
+	SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_COLORIMETRY),
+	SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_AUDIO_ENCRYPT_PREFER),
+	SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_AUDIO_STAT),
+	SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_AUDIO_STAT),
+	SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_HBUF_INDEX),
+	SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_HBUF_INDEX),
+	SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_HBUF_INFO),
+	SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_HBUF_AV_SPLIT),
+	SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_HBUF_AV_SPLIT),
+	SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_HBUF_TXRATE),
+	SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_HBUF_TXRATE),
+	SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_HBUF_DATA),
+	SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_HBUF_DATA),
+};
+
+#define SDVO_NAME(svdo) ((svdo)->port == PORT_B ? "SDVOB" : "SDVOC")
+
+static void intel_sdvo_debug_write(struct intel_sdvo *intel_sdvo, u8 cmd,
+				   const void *args, int args_len)
+{
+	int i, pos = 0;
+#define BUF_LEN 256
+	char buffer[BUF_LEN];
+
+#define BUF_PRINT(args...) \
+	pos += snprintf(buffer + pos, max_t(int, BUF_LEN - pos, 0), args)
+
+
+	for (i = 0; i < args_len; i++) {
+		BUF_PRINT("%02X ", ((u8 *)args)[i]);
+	}
+	for (; i < 8; i++) {
+		BUF_PRINT("   ");
+	}
+	for (i = 0; i < ARRAY_SIZE(sdvo_cmd_names); i++) {
+		if (cmd == sdvo_cmd_names[i].cmd) {
+			BUF_PRINT("(%s)", sdvo_cmd_names[i].name);
+			break;
+		}
+	}
+	if (i == ARRAY_SIZE(sdvo_cmd_names)) {
+		BUF_PRINT("(%02X)", cmd);
+	}
+	BUG_ON(pos >= BUF_LEN - 1);
+#undef BUF_PRINT
+#undef BUF_LEN
+
+	DRM_DEBUG_KMS("%s: W: %02X %s\n", SDVO_NAME(intel_sdvo), cmd, buffer);
+}
+
+static const char * const cmd_status_names[] = {
+	"Power on",
+	"Success",
+	"Not supported",
+	"Invalid arg",
+	"Pending",
+	"Target not specified",
+	"Scaling not supported"
+};
+
+static bool intel_sdvo_write_cmd(struct intel_sdvo *intel_sdvo, u8 cmd,
+				 const void *args, int args_len)
+{
+	u8 *buf, status;
+	struct i2c_msg *msgs;
+	int i, ret = true;
+
+        /* Would be simpler to allocate both in one go ? */        
+	buf = kzalloc(args_len * 2 + 2, GFP_KERNEL);
+	if (!buf)
+		return false;
+
+	msgs = kcalloc(args_len + 3, sizeof(*msgs), GFP_KERNEL);
+	if (!msgs) {
+	        kfree(buf);
+		return false;
+        }
+
+	intel_sdvo_debug_write(intel_sdvo, cmd, args, args_len);
+
+	for (i = 0; i < args_len; i++) {
+		msgs[i].addr = intel_sdvo->slave_addr;
+		msgs[i].flags = 0;
+		msgs[i].len = 2;
+		msgs[i].buf = buf + 2 *i;
+		buf[2*i + 0] = SDVO_I2C_ARG_0 - i;
+		buf[2*i + 1] = ((u8*)args)[i];
+	}
+	msgs[i].addr = intel_sdvo->slave_addr;
+	msgs[i].flags = 0;
+	msgs[i].len = 2;
+	msgs[i].buf = buf + 2*i;
+	buf[2*i + 0] = SDVO_I2C_OPCODE;
+	buf[2*i + 1] = cmd;
+
+	/* the following two are to read the response */
+	status = SDVO_I2C_CMD_STATUS;
+	msgs[i+1].addr = intel_sdvo->slave_addr;
+	msgs[i+1].flags = 0;
+	msgs[i+1].len = 1;
+	msgs[i+1].buf = &status;
+
+	msgs[i+2].addr = intel_sdvo->slave_addr;
+	msgs[i+2].flags = I2C_M_RD;
+	msgs[i+2].len = 1;
+	msgs[i+2].buf = &status;
+
+	ret = i2c_transfer(intel_sdvo->i2c, msgs, i+3);
+	if (ret < 0) {
+		DRM_DEBUG_KMS("I2c transfer returned %d\n", ret);
+		ret = false;
+		goto out;
+	}
+	if (ret != i+3) {
+		/* failure in I2C transfer */
+		DRM_DEBUG_KMS("I2c transfer returned %d/%d\n", ret, i+3);
+		ret = false;
+	}
+
+out:
+	kfree(msgs);
+	kfree(buf);
+	return ret;
+}
+
+static bool intel_sdvo_read_response(struct intel_sdvo *intel_sdvo,
+				     void *response, int response_len)
+{
+	u8 retry = 15; /* 5 quick checks, followed by 10 long checks */
+	u8 status;
+	int i, pos = 0;
+#define BUF_LEN 256
+	char buffer[BUF_LEN];
+
+
+	/*
+	 * The documentation states that all commands will be
+	 * processed within 15µs, and that we need only poll
+	 * the status byte a maximum of 3 times in order for the
+	 * command to be complete.
+	 *
+	 * Check 5 times in case the hardware failed to read the docs.
+	 *
+	 * Also beware that the first response by many devices is to
+	 * reply PENDING and stall for time. TVs are notorious for
+	 * requiring longer than specified to complete their replies.
+	 * Originally (in the DDX long ago), the delay was only ever 15ms
+	 * with an additional delay of 30ms applied for TVs added later after
+	 * many experiments. To accommodate both sets of delays, we do a
+	 * sequence of slow checks if the device is falling behind and fails
+	 * to reply within 5*15µs.
+	 */
+	if (!intel_sdvo_read_byte(intel_sdvo,
+				  SDVO_I2C_CMD_STATUS,
+				  &status))
+		goto log_fail;
+
+	while ((status == SDVO_CMD_STATUS_PENDING ||
+		status == SDVO_CMD_STATUS_TARGET_NOT_SPECIFIED) && --retry) {
+		if (retry < 10)
+			msleep(15);
+		else
+			udelay(15);
+
+		if (!intel_sdvo_read_byte(intel_sdvo,
+					  SDVO_I2C_CMD_STATUS,
+					  &status))
+			goto log_fail;
+	}
+
+#define BUF_PRINT(args...) \
+	pos += snprintf(buffer + pos, max_t(int, BUF_LEN - pos, 0), args)
+
+	if (status <= SDVO_CMD_STATUS_SCALING_NOT_SUPP)
+		BUF_PRINT("(%s)", cmd_status_names[status]);
+	else
+		BUF_PRINT("(??? %d)", status);
+
+	if (status != SDVO_CMD_STATUS_SUCCESS)
+		goto log_fail;
+
+	/* Read the command response */
+	for (i = 0; i < response_len; i++) {
+		if (!intel_sdvo_read_byte(intel_sdvo,
+					  SDVO_I2C_RETURN_0 + i,
+					  &((u8 *)response)[i]))
+			goto log_fail;
+		BUF_PRINT(" %02X", ((u8 *)response)[i]);
+	}
+	BUG_ON(pos >= BUF_LEN - 1);
+#undef BUF_PRINT
+#undef BUF_LEN
+
+	DRM_DEBUG_KMS("%s: R: %s\n", SDVO_NAME(intel_sdvo), buffer);
+	return true;
+
+log_fail:
+	DRM_DEBUG_KMS("%s: R: ... failed\n", SDVO_NAME(intel_sdvo));
+	return false;
+}
+
+static int intel_sdvo_get_pixel_multiplier(const struct drm_display_mode *adjusted_mode)
+{
+	if (adjusted_mode->crtc_clock >= 100000)
+		return 1;
+	else if (adjusted_mode->crtc_clock >= 50000)
+		return 2;
+	else
+		return 4;
+}
+
+static bool intel_sdvo_set_control_bus_switch(struct intel_sdvo *intel_sdvo,
+					      u8 ddc_bus)
+{
+	/* This must be the immediately preceding write before the i2c xfer */
+	return intel_sdvo_write_cmd(intel_sdvo,
+				    SDVO_CMD_SET_CONTROL_BUS_SWITCH,
+				    &ddc_bus, 1);
+}
+
+static bool intel_sdvo_set_value(struct intel_sdvo *intel_sdvo, u8 cmd, const void *data, int len)
+{
+	if (!intel_sdvo_write_cmd(intel_sdvo, cmd, data, len))
+		return false;
+
+	return intel_sdvo_read_response(intel_sdvo, NULL, 0);
+}
+
+static bool
+intel_sdvo_get_value(struct intel_sdvo *intel_sdvo, u8 cmd, void *value, int len)
+{
+	if (!intel_sdvo_write_cmd(intel_sdvo, cmd, NULL, 0))
+		return false;
+
+	return intel_sdvo_read_response(intel_sdvo, value, len);
+}
+
+static bool intel_sdvo_set_target_input(struct intel_sdvo *intel_sdvo)
+{
+	struct intel_sdvo_set_target_input_args targets = {0};
+	return intel_sdvo_set_value(intel_sdvo,
+				    SDVO_CMD_SET_TARGET_INPUT,
+				    &targets, sizeof(targets));
+}
+
+/**
+ * Return whether each input is trained.
+ *
+ * This function is making an assumption about the layout of the response,
+ * which should be checked against the docs.
+ */
+static bool intel_sdvo_get_trained_inputs(struct intel_sdvo *intel_sdvo, bool *input_1, bool *input_2)
+{
+	struct intel_sdvo_get_trained_inputs_response response;
+
+	BUILD_BUG_ON(sizeof(response) != 1);
+	if (!intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_TRAINED_INPUTS,
+				  &response, sizeof(response)))
+		return false;
+
+	*input_1 = response.input0_trained;
+	*input_2 = response.input1_trained;
+	return true;
+}
+
+static bool intel_sdvo_set_active_outputs(struct intel_sdvo *intel_sdvo,
+					  u16 outputs)
+{
+	return intel_sdvo_set_value(intel_sdvo,
+				    SDVO_CMD_SET_ACTIVE_OUTPUTS,
+				    &outputs, sizeof(outputs));
+}
+
+static bool intel_sdvo_get_active_outputs(struct intel_sdvo *intel_sdvo,
+					  u16 *outputs)
+{
+	return intel_sdvo_get_value(intel_sdvo,
+				    SDVO_CMD_GET_ACTIVE_OUTPUTS,
+				    outputs, sizeof(*outputs));
+}
+
+static bool intel_sdvo_set_encoder_power_state(struct intel_sdvo *intel_sdvo,
+					       int mode)
+{
+	u8 state = SDVO_ENCODER_STATE_ON;
+
+	switch (mode) {
+	case DRM_MODE_DPMS_ON:
+		state = SDVO_ENCODER_STATE_ON;
+		break;
+	case DRM_MODE_DPMS_STANDBY:
+		state = SDVO_ENCODER_STATE_STANDBY;
+		break;
+	case DRM_MODE_DPMS_SUSPEND:
+		state = SDVO_ENCODER_STATE_SUSPEND;
+		break;
+	case DRM_MODE_DPMS_OFF:
+		state = SDVO_ENCODER_STATE_OFF;
+		break;
+	}
+
+	return intel_sdvo_set_value(intel_sdvo,
+				    SDVO_CMD_SET_ENCODER_POWER_STATE, &state, sizeof(state));
+}
+
+static bool intel_sdvo_get_input_pixel_clock_range(struct intel_sdvo *intel_sdvo,
+						   int *clock_min,
+						   int *clock_max)
+{
+	struct intel_sdvo_pixel_clock_range clocks;
+
+	BUILD_BUG_ON(sizeof(clocks) != 4);
+	if (!intel_sdvo_get_value(intel_sdvo,
+				  SDVO_CMD_GET_INPUT_PIXEL_CLOCK_RANGE,
+				  &clocks, sizeof(clocks)))
+		return false;
+
+	/* Convert the values from units of 10 kHz to kHz. */
+	*clock_min = clocks.min * 10;
+	*clock_max = clocks.max * 10;
+	return true;
+}
+
+static bool intel_sdvo_set_target_output(struct intel_sdvo *intel_sdvo,
+					 u16 outputs)
+{
+	return intel_sdvo_set_value(intel_sdvo,
+				    SDVO_CMD_SET_TARGET_OUTPUT,
+				    &outputs, sizeof(outputs));
+}
+
+static bool intel_sdvo_set_timing(struct intel_sdvo *intel_sdvo, u8 cmd,
+				  struct intel_sdvo_dtd *dtd)
+{
+	return intel_sdvo_set_value(intel_sdvo, cmd, &dtd->part1, sizeof(dtd->part1)) &&
+		intel_sdvo_set_value(intel_sdvo, cmd + 1, &dtd->part2, sizeof(dtd->part2));
+}
+
+static bool intel_sdvo_get_timing(struct intel_sdvo *intel_sdvo, u8 cmd,
+				  struct intel_sdvo_dtd *dtd)
+{
+	return intel_sdvo_get_value(intel_sdvo, cmd, &dtd->part1, sizeof(dtd->part1)) &&
+		intel_sdvo_get_value(intel_sdvo, cmd + 1, &dtd->part2, sizeof(dtd->part2));
+}
+
+static bool intel_sdvo_set_input_timing(struct intel_sdvo *intel_sdvo,
+					 struct intel_sdvo_dtd *dtd)
+{
+	return intel_sdvo_set_timing(intel_sdvo,
+				     SDVO_CMD_SET_INPUT_TIMINGS_PART1, dtd);
+}
+
+static bool intel_sdvo_set_output_timing(struct intel_sdvo *intel_sdvo,
+					 struct intel_sdvo_dtd *dtd)
+{
+	return intel_sdvo_set_timing(intel_sdvo,
+				     SDVO_CMD_SET_OUTPUT_TIMINGS_PART1, dtd);
+}
+
+static bool intel_sdvo_get_input_timing(struct intel_sdvo *intel_sdvo,
+					struct intel_sdvo_dtd *dtd)
+{
+	return intel_sdvo_get_timing(intel_sdvo,
+				     SDVO_CMD_GET_INPUT_TIMINGS_PART1, dtd);
+}
+
+static bool
+intel_sdvo_create_preferred_input_timing(struct intel_sdvo *intel_sdvo,
+					 uint16_t clock,
+					 uint16_t width,
+					 uint16_t height)
+{
+	struct intel_sdvo_preferred_input_timing_args args;
+
+	memset(&args, 0, sizeof(args));
+	args.clock = clock;
+	args.width = width;
+	args.height = height;
+	args.interlace = 0;
+
+	if (intel_sdvo->is_lvds &&
+	   (intel_sdvo->sdvo_lvds_fixed_mode->hdisplay != width ||
+	    intel_sdvo->sdvo_lvds_fixed_mode->vdisplay != height))
+		args.scaled = 1;
+
+	return intel_sdvo_set_value(intel_sdvo,
+				    SDVO_CMD_CREATE_PREFERRED_INPUT_TIMING,
+				    &args, sizeof(args));
+}
+
+static bool intel_sdvo_get_preferred_input_timing(struct intel_sdvo *intel_sdvo,
+						  struct intel_sdvo_dtd *dtd)
+{
+	BUILD_BUG_ON(sizeof(dtd->part1) != 8);
+	BUILD_BUG_ON(sizeof(dtd->part2) != 8);
+	return intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART1,
+				    &dtd->part1, sizeof(dtd->part1)) &&
+		intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART2,
+				     &dtd->part2, sizeof(dtd->part2));
+}
+
+static bool intel_sdvo_set_clock_rate_mult(struct intel_sdvo *intel_sdvo, u8 val)
+{
+	return intel_sdvo_set_value(intel_sdvo, SDVO_CMD_SET_CLOCK_RATE_MULT, &val, 1);
+}
+
+static void intel_sdvo_get_dtd_from_mode(struct intel_sdvo_dtd *dtd,
+					 const struct drm_display_mode *mode)
+{
+	uint16_t width, height;
+	uint16_t h_blank_len, h_sync_len, v_blank_len, v_sync_len;
+	uint16_t h_sync_offset, v_sync_offset;
+	int mode_clock;
+
+	memset(dtd, 0, sizeof(*dtd));
+
+	width = mode->hdisplay;
+	height = mode->vdisplay;
+
+	/* do some mode translations */
+	h_blank_len = mode->htotal - mode->hdisplay;
+	h_sync_len = mode->hsync_end - mode->hsync_start;
+
+	v_blank_len = mode->vtotal - mode->vdisplay;
+	v_sync_len = mode->vsync_end - mode->vsync_start;
+
+	h_sync_offset = mode->hsync_start - mode->hdisplay;
+	v_sync_offset = mode->vsync_start - mode->vdisplay;
+
+	mode_clock = mode->clock;
+	mode_clock /= 10;
+	dtd->part1.clock = mode_clock;
+
+	dtd->part1.h_active = width & 0xff;
+	dtd->part1.h_blank = h_blank_len & 0xff;
+	dtd->part1.h_high = (((width >> 8) & 0xf) << 4) |
+		((h_blank_len >> 8) & 0xf);
+	dtd->part1.v_active = height & 0xff;
+	dtd->part1.v_blank = v_blank_len & 0xff;
+	dtd->part1.v_high = (((height >> 8) & 0xf) << 4) |
+		((v_blank_len >> 8) & 0xf);
+
+	dtd->part2.h_sync_off = h_sync_offset & 0xff;
+	dtd->part2.h_sync_width = h_sync_len & 0xff;
+	dtd->part2.v_sync_off_width = (v_sync_offset & 0xf) << 4 |
+		(v_sync_len & 0xf);
+	dtd->part2.sync_off_width_high = ((h_sync_offset & 0x300) >> 2) |
+		((h_sync_len & 0x300) >> 4) | ((v_sync_offset & 0x30) >> 2) |
+		((v_sync_len & 0x30) >> 4);
+
+	dtd->part2.dtd_flags = 0x18;
+	if (mode->flags & DRM_MODE_FLAG_INTERLACE)
+		dtd->part2.dtd_flags |= DTD_FLAG_INTERLACE;
+	if (mode->flags & DRM_MODE_FLAG_PHSYNC)
+		dtd->part2.dtd_flags |= DTD_FLAG_HSYNC_POSITIVE;
+	if (mode->flags & DRM_MODE_FLAG_PVSYNC)
+		dtd->part2.dtd_flags |= DTD_FLAG_VSYNC_POSITIVE;
+
+	dtd->part2.v_sync_off_high = v_sync_offset & 0xc0;
+}
+
+static void intel_sdvo_get_mode_from_dtd(struct drm_display_mode *pmode,
+					 const struct intel_sdvo_dtd *dtd)
+{
+	struct drm_display_mode mode = {};
+
+	mode.hdisplay = dtd->part1.h_active;
+	mode.hdisplay += ((dtd->part1.h_high >> 4) & 0x0f) << 8;
+	mode.hsync_start = mode.hdisplay + dtd->part2.h_sync_off;
+	mode.hsync_start += (dtd->part2.sync_off_width_high & 0xc0) << 2;
+	mode.hsync_end = mode.hsync_start + dtd->part2.h_sync_width;
+	mode.hsync_end += (dtd->part2.sync_off_width_high & 0x30) << 4;
+	mode.htotal = mode.hdisplay + dtd->part1.h_blank;
+	mode.htotal += (dtd->part1.h_high & 0xf) << 8;
+
+	mode.vdisplay = dtd->part1.v_active;
+	mode.vdisplay += ((dtd->part1.v_high >> 4) & 0x0f) << 8;
+	mode.vsync_start = mode.vdisplay;
+	mode.vsync_start += (dtd->part2.v_sync_off_width >> 4) & 0xf;
+	mode.vsync_start += (dtd->part2.sync_off_width_high & 0x0c) << 2;
+	mode.vsync_start += dtd->part2.v_sync_off_high & 0xc0;
+	mode.vsync_end = mode.vsync_start +
+		(dtd->part2.v_sync_off_width & 0xf);
+	mode.vsync_end += (dtd->part2.sync_off_width_high & 0x3) << 4;
+	mode.vtotal = mode.vdisplay + dtd->part1.v_blank;
+	mode.vtotal += (dtd->part1.v_high & 0xf) << 8;
+
+	mode.clock = dtd->part1.clock * 10;
+
+	if (dtd->part2.dtd_flags & DTD_FLAG_INTERLACE)
+		mode.flags |= DRM_MODE_FLAG_INTERLACE;
+	if (dtd->part2.dtd_flags & DTD_FLAG_HSYNC_POSITIVE)
+		mode.flags |= DRM_MODE_FLAG_PHSYNC;
+	else
+		mode.flags |= DRM_MODE_FLAG_NHSYNC;
+	if (dtd->part2.dtd_flags & DTD_FLAG_VSYNC_POSITIVE)
+		mode.flags |= DRM_MODE_FLAG_PVSYNC;
+	else
+		mode.flags |= DRM_MODE_FLAG_NVSYNC;
+
+	drm_mode_set_crtcinfo(&mode, 0);
+
+	drm_mode_copy(pmode, &mode);
+}
+
+static bool intel_sdvo_check_supp_encode(struct intel_sdvo *intel_sdvo)
+{
+	struct intel_sdvo_encode encode;
+
+	BUILD_BUG_ON(sizeof(encode) != 2);
+	return intel_sdvo_get_value(intel_sdvo,
+				  SDVO_CMD_GET_SUPP_ENCODE,
+				  &encode, sizeof(encode));
+}
+
+static bool intel_sdvo_set_encode(struct intel_sdvo *intel_sdvo,
+				  uint8_t mode)
+{
+	return intel_sdvo_set_value(intel_sdvo, SDVO_CMD_SET_ENCODE, &mode, 1);
+}
+
+static bool intel_sdvo_set_colorimetry(struct intel_sdvo *intel_sdvo,
+				       uint8_t mode)
+{
+	return intel_sdvo_set_value(intel_sdvo, SDVO_CMD_SET_COLORIMETRY, &mode, 1);
+}
+
+#if 0
+static void intel_sdvo_dump_hdmi_buf(struct intel_sdvo *intel_sdvo)
+{
+	int i, j;
+	uint8_t set_buf_index[2];
+	uint8_t av_split;
+	uint8_t buf_size;
+	uint8_t buf[48];
+	uint8_t *pos;
+
+	intel_sdvo_get_value(encoder, SDVO_CMD_GET_HBUF_AV_SPLIT, &av_split, 1);
+
+	for (i = 0; i <= av_split; i++) {
+		set_buf_index[0] = i; set_buf_index[1] = 0;
+		intel_sdvo_write_cmd(encoder, SDVO_CMD_SET_HBUF_INDEX,
+				     set_buf_index, 2);
+		intel_sdvo_write_cmd(encoder, SDVO_CMD_GET_HBUF_INFO, NULL, 0);
+		intel_sdvo_read_response(encoder, &buf_size, 1);
+
+		pos = buf;
+		for (j = 0; j <= buf_size; j += 8) {
+			intel_sdvo_write_cmd(encoder, SDVO_CMD_GET_HBUF_DATA,
+					     NULL, 0);
+			intel_sdvo_read_response(encoder, pos, 8);
+			pos += 8;
+		}
+	}
+}
+#endif
+
+static bool intel_sdvo_write_infoframe(struct intel_sdvo *intel_sdvo,
+				       unsigned if_index, uint8_t tx_rate,
+				       const uint8_t *data, unsigned length)
+{
+	uint8_t set_buf_index[2] = { if_index, 0 };
+	uint8_t hbuf_size, tmp[8];
+	int i;
+
+	if (!intel_sdvo_set_value(intel_sdvo,
+				  SDVO_CMD_SET_HBUF_INDEX,
+				  set_buf_index, 2))
+		return false;
+
+	if (!intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_HBUF_INFO,
+				  &hbuf_size, 1))
+		return false;
+
+	/* Buffer size is 0 based, hooray! */
+	hbuf_size++;
+
+	DRM_DEBUG_KMS("writing sdvo hbuf: %i, hbuf_size %i, hbuf_size: %i\n",
+		      if_index, length, hbuf_size);
+
+	for (i = 0; i < hbuf_size; i += 8) {
+		memset(tmp, 0, 8);
+		if (i < length)
+			memcpy(tmp, data + i, min_t(unsigned, 8, length - i));
+
+		if (!intel_sdvo_set_value(intel_sdvo,
+					  SDVO_CMD_SET_HBUF_DATA,
+					  tmp, 8))
+			return false;
+	}
+
+	return intel_sdvo_set_value(intel_sdvo,
+				    SDVO_CMD_SET_HBUF_TXRATE,
+				    &tx_rate, 1);
+}
+
+static bool intel_sdvo_set_avi_infoframe(struct intel_sdvo *intel_sdvo,
+					 const struct drm_display_mode *adjusted_mode)
+{
+	uint8_t sdvo_data[HDMI_INFOFRAME_SIZE(AVI)];
+	struct drm_crtc *crtc = intel_sdvo->base.base.crtc;
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	union hdmi_infoframe frame;
+	int ret;
+	ssize_t len;
+
+	ret = drm_hdmi_avi_infoframe_from_display_mode(&frame.avi,
+						       adjusted_mode);
+	if (ret < 0) {
+		DRM_ERROR("couldn't fill AVI infoframe\n");
+		return false;
+	}
+
+	if (intel_sdvo->rgb_quant_range_selectable) {
+		if (intel_crtc->config->limited_color_range)
+			frame.avi.quantization_range =
+				HDMI_QUANTIZATION_RANGE_LIMITED;
+		else
+			frame.avi.quantization_range =
+				HDMI_QUANTIZATION_RANGE_FULL;
+	}
+
+	len = hdmi_infoframe_pack(&frame, sdvo_data, sizeof(sdvo_data));
+	if (len < 0)
+		return false;
+
+	return intel_sdvo_write_infoframe(intel_sdvo, SDVO_HBUF_INDEX_AVI_IF,
+					  SDVO_HBUF_TX_VSYNC,
+					  sdvo_data, sizeof(sdvo_data));
+}
+
+static bool intel_sdvo_set_tv_format(struct intel_sdvo *intel_sdvo)
+{
+	struct intel_sdvo_tv_format format;
+	uint32_t format_map;
+
+	format_map = 1 << intel_sdvo->tv_format_index;
+	memset(&format, 0, sizeof(format));
+	memcpy(&format, &format_map, min(sizeof(format), sizeof(format_map)));
+
+	BUILD_BUG_ON(sizeof(format) != 6);
+	return intel_sdvo_set_value(intel_sdvo,
+				    SDVO_CMD_SET_TV_FORMAT,
+				    &format, sizeof(format));
+}
+
+static bool
+intel_sdvo_set_output_timings_from_mode(struct intel_sdvo *intel_sdvo,
+					const struct drm_display_mode *mode)
+{
+	struct intel_sdvo_dtd output_dtd;
+
+	if (!intel_sdvo_set_target_output(intel_sdvo,
+					  intel_sdvo->attached_output))
+		return false;
+
+	intel_sdvo_get_dtd_from_mode(&output_dtd, mode);
+	if (!intel_sdvo_set_output_timing(intel_sdvo, &output_dtd))
+		return false;
+
+	return true;
+}
+
+/* Asks the sdvo controller for the preferred input mode given the output mode.
+ * Unfortunately we have to set up the full output mode to do that. */
+static bool
+intel_sdvo_get_preferred_input_mode(struct intel_sdvo *intel_sdvo,
+				    const struct drm_display_mode *mode,
+				    struct drm_display_mode *adjusted_mode)
+{
+	struct intel_sdvo_dtd input_dtd;
+
+	/* Reset the input timing to the screen. Assume always input 0. */
+	if (!intel_sdvo_set_target_input(intel_sdvo))
+		return false;
+
+	if (!intel_sdvo_create_preferred_input_timing(intel_sdvo,
+						      mode->clock / 10,
+						      mode->hdisplay,
+						      mode->vdisplay))
+		return false;
+
+	if (!intel_sdvo_get_preferred_input_timing(intel_sdvo,
+						   &input_dtd))
+		return false;
+
+	intel_sdvo_get_mode_from_dtd(adjusted_mode, &input_dtd);
+	intel_sdvo->dtd_sdvo_flags = input_dtd.part2.sdvo_flags;
+
+	return true;
+}
+
+static void i9xx_adjust_sdvo_tv_clock(struct intel_crtc_state *pipe_config)
+{
+	unsigned dotclock = pipe_config->port_clock;
+	struct dpll *clock = &pipe_config->dpll;
+
+	/* SDVO TV has fixed PLL values depend on its clock range,
+	   this mirrors vbios setting. */
+	if (dotclock >= 100000 && dotclock < 140500) {
+		clock->p1 = 2;
+		clock->p2 = 10;
+		clock->n = 3;
+		clock->m1 = 16;
+		clock->m2 = 8;
+	} else if (dotclock >= 140500 && dotclock <= 200000) {
+		clock->p1 = 1;
+		clock->p2 = 10;
+		clock->n = 6;
+		clock->m1 = 12;
+		clock->m2 = 8;
+	} else {
+		WARN(1, "SDVO TV clock out of range: %i\n", dotclock);
+	}
+
+	pipe_config->clock_set = true;
+}
+
+static bool intel_sdvo_compute_config(struct intel_encoder *encoder,
+				      struct intel_crtc_state *pipe_config)
+{
+	struct intel_sdvo *intel_sdvo = to_sdvo(encoder);
+	struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
+	struct drm_display_mode *mode = &pipe_config->base.mode;
+
+	DRM_DEBUG_KMS("forcing bpc to 8 for SDVO\n");
+	pipe_config->pipe_bpp = 8*3;
+
+	if (HAS_PCH_SPLIT(encoder->base.dev))
+		pipe_config->has_pch_encoder = true;
+
+	/* We need to construct preferred input timings based on our
+	 * output timings.  To do that, we have to set the output
+	 * timings, even though this isn't really the right place in
+	 * the sequence to do it. Oh well.
+	 */
+	if (intel_sdvo->is_tv) {
+		if (!intel_sdvo_set_output_timings_from_mode(intel_sdvo, mode))
+			return false;
+
+		(void) intel_sdvo_get_preferred_input_mode(intel_sdvo,
+							   mode,
+							   adjusted_mode);
+		pipe_config->sdvo_tv_clock = true;
+	} else if (intel_sdvo->is_lvds) {
+		if (!intel_sdvo_set_output_timings_from_mode(intel_sdvo,
+							     intel_sdvo->sdvo_lvds_fixed_mode))
+			return false;
+
+		(void) intel_sdvo_get_preferred_input_mode(intel_sdvo,
+							   mode,
+							   adjusted_mode);
+	}
+
+	/* Make the CRTC code factor in the SDVO pixel multiplier.  The
+	 * SDVO device will factor out the multiplier during mode_set.
+	 */
+	pipe_config->pixel_multiplier =
+		intel_sdvo_get_pixel_multiplier(adjusted_mode);
+
+	pipe_config->has_hdmi_sink = intel_sdvo->has_hdmi_monitor;
+
+	if (intel_sdvo->color_range_auto) {
+		/* See CEA-861-E - 5.1 Default Encoding Parameters */
+		/* FIXME: This bit is only valid when using TMDS encoding and 8
+		 * bit per color mode. */
+		if (pipe_config->has_hdmi_sink &&
+		    drm_match_cea_mode(adjusted_mode) > 1)
+			pipe_config->limited_color_range = true;
+	} else {
+		if (pipe_config->has_hdmi_sink &&
+		    intel_sdvo->color_range == HDMI_COLOR_RANGE_16_235)
+			pipe_config->limited_color_range = true;
+	}
+
+	/* Clock computation needs to happen after pixel multiplier. */
+	if (intel_sdvo->is_tv)
+		i9xx_adjust_sdvo_tv_clock(pipe_config);
+
+	/* Set user selected PAR to incoming mode's member */
+	if (intel_sdvo->is_hdmi)
+		adjusted_mode->picture_aspect_ratio = intel_sdvo->aspect_ratio;
+
+	return true;
+}
+
+static void intel_sdvo_pre_enable(struct intel_encoder *intel_encoder)
+{
+	struct drm_device *dev = intel_encoder->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_crtc *crtc = to_intel_crtc(intel_encoder->base.crtc);
+	const struct drm_display_mode *adjusted_mode = &crtc->config->base.adjusted_mode;
+	struct drm_display_mode *mode = &crtc->config->base.mode;
+	struct intel_sdvo *intel_sdvo = to_sdvo(intel_encoder);
+	u32 sdvox;
+	struct intel_sdvo_in_out_map in_out;
+	struct intel_sdvo_dtd input_dtd, output_dtd;
+	int rate;
+
+	if (!mode)
+		return;
+
+	/* First, set the input mapping for the first input to our controlled
+	 * output. This is only correct if we're a single-input device, in
+	 * which case the first input is the output from the appropriate SDVO
+	 * channel on the motherboard.  In a two-input device, the first input
+	 * will be SDVOB and the second SDVOC.
+	 */
+	in_out.in0 = intel_sdvo->attached_output;
+	in_out.in1 = 0;
+
+	intel_sdvo_set_value(intel_sdvo,
+			     SDVO_CMD_SET_IN_OUT_MAP,
+			     &in_out, sizeof(in_out));
+
+	/* Set the output timings to the screen */
+	if (!intel_sdvo_set_target_output(intel_sdvo,
+					  intel_sdvo->attached_output))
+		return;
+
+	/* lvds has a special fixed output timing. */
+	if (intel_sdvo->is_lvds)
+		intel_sdvo_get_dtd_from_mode(&output_dtd,
+					     intel_sdvo->sdvo_lvds_fixed_mode);
+	else
+		intel_sdvo_get_dtd_from_mode(&output_dtd, mode);
+	if (!intel_sdvo_set_output_timing(intel_sdvo, &output_dtd))
+		DRM_INFO("Setting output timings on %s failed\n",
+			 SDVO_NAME(intel_sdvo));
+
+	/* Set the input timing to the screen. Assume always input 0. */
+	if (!intel_sdvo_set_target_input(intel_sdvo))
+		return;
+
+	if (crtc->config->has_hdmi_sink) {
+		intel_sdvo_set_encode(intel_sdvo, SDVO_ENCODE_HDMI);
+		intel_sdvo_set_colorimetry(intel_sdvo,
+					   SDVO_COLORIMETRY_RGB256);
+		intel_sdvo_set_avi_infoframe(intel_sdvo, adjusted_mode);
+	} else
+		intel_sdvo_set_encode(intel_sdvo, SDVO_ENCODE_DVI);
+
+	if (intel_sdvo->is_tv &&
+	    !intel_sdvo_set_tv_format(intel_sdvo))
+		return;
+
+	intel_sdvo_get_dtd_from_mode(&input_dtd, adjusted_mode);
+
+	if (intel_sdvo->is_tv || intel_sdvo->is_lvds)
+		input_dtd.part2.sdvo_flags = intel_sdvo->dtd_sdvo_flags;
+	if (!intel_sdvo_set_input_timing(intel_sdvo, &input_dtd))
+		DRM_INFO("Setting input timings on %s failed\n",
+			 SDVO_NAME(intel_sdvo));
+
+	switch (crtc->config->pixel_multiplier) {
+	default:
+		WARN(1, "unknown pixel multiplier specified\n");
+	case 1: rate = SDVO_CLOCK_RATE_MULT_1X; break;
+	case 2: rate = SDVO_CLOCK_RATE_MULT_2X; break;
+	case 4: rate = SDVO_CLOCK_RATE_MULT_4X; break;
+	}
+	if (!intel_sdvo_set_clock_rate_mult(intel_sdvo, rate))
+		return;
+
+	/* Set the SDVO control regs. */
+	if (INTEL_INFO(dev)->gen >= 4) {
+		/* The real mode polarity is set by the SDVO commands, using
+		 * struct intel_sdvo_dtd. */
+		sdvox = SDVO_VSYNC_ACTIVE_HIGH | SDVO_HSYNC_ACTIVE_HIGH;
+		if (!HAS_PCH_SPLIT(dev) && crtc->config->limited_color_range)
+			sdvox |= HDMI_COLOR_RANGE_16_235;
+		if (INTEL_INFO(dev)->gen < 5)
+			sdvox |= SDVO_BORDER_ENABLE;
+	} else {
+		sdvox = I915_READ(intel_sdvo->sdvo_reg);
+		if (intel_sdvo->port == PORT_B)
+			sdvox &= SDVOB_PRESERVE_MASK;
+		else
+			sdvox &= SDVOC_PRESERVE_MASK;
+		sdvox |= (9 << 19) | SDVO_BORDER_ENABLE;
+	}
+
+	if (INTEL_PCH_TYPE(dev) >= PCH_CPT)
+		sdvox |= SDVO_PIPE_SEL_CPT(crtc->pipe);
+	else
+		sdvox |= SDVO_PIPE_SEL(crtc->pipe);
+
+	if (intel_sdvo->has_hdmi_audio)
+		sdvox |= SDVO_AUDIO_ENABLE;
+
+	if (INTEL_INFO(dev)->gen >= 4) {
+		/* done in crtc_mode_set as the dpll_md reg must be written early */
+	} else if (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev)) {
+		/* done in crtc_mode_set as it lives inside the dpll register */
+	} else {
+		sdvox |= (crtc->config->pixel_multiplier - 1)
+			<< SDVO_PORT_MULTIPLY_SHIFT;
+	}
+
+	if (input_dtd.part2.sdvo_flags & SDVO_NEED_TO_STALL &&
+	    INTEL_INFO(dev)->gen < 5)
+		sdvox |= SDVO_STALL_SELECT;
+	intel_sdvo_write_sdvox(intel_sdvo, sdvox);
+}
+
+static bool intel_sdvo_connector_get_hw_state(struct intel_connector *connector)
+{
+	struct intel_sdvo_connector *intel_sdvo_connector =
+		to_intel_sdvo_connector(&connector->base);
+	struct intel_sdvo *intel_sdvo = intel_attached_sdvo(&connector->base);
+	u16 active_outputs = 0;
+
+	intel_sdvo_get_active_outputs(intel_sdvo, &active_outputs);
+
+	if (active_outputs & intel_sdvo_connector->output_flag)
+		return true;
+	else
+		return false;
+}
+
+static bool intel_sdvo_get_hw_state(struct intel_encoder *encoder,
+				    enum pipe *pipe)
+{
+	struct drm_device *dev = encoder->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_sdvo *intel_sdvo = to_sdvo(encoder);
+	u16 active_outputs = 0;
+	u32 tmp;
+
+	tmp = I915_READ(intel_sdvo->sdvo_reg);
+	intel_sdvo_get_active_outputs(intel_sdvo, &active_outputs);
+
+	if (!(tmp & SDVO_ENABLE) && (active_outputs == 0))
+		return false;
+
+	if (HAS_PCH_CPT(dev))
+		*pipe = PORT_TO_PIPE_CPT(tmp);
+	else
+		*pipe = PORT_TO_PIPE(tmp);
+
+	return true;
+}
+
+static void intel_sdvo_get_config(struct intel_encoder *encoder,
+				  struct intel_crtc_state *pipe_config)
+{
+	struct drm_device *dev = encoder->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_sdvo *intel_sdvo = to_sdvo(encoder);
+	struct intel_sdvo_dtd dtd;
+	int encoder_pixel_multiplier = 0;
+	int dotclock;
+	u32 flags = 0, sdvox;
+	u8 val;
+	bool ret;
+
+	sdvox = I915_READ(intel_sdvo->sdvo_reg);
+
+	ret = intel_sdvo_get_input_timing(intel_sdvo, &dtd);
+	if (!ret) {
+		/* Some sdvo encoders are not spec compliant and don't
+		 * implement the mandatory get_timings function. */
+		DRM_DEBUG_DRIVER("failed to retrieve SDVO DTD\n");
+		pipe_config->quirks |= PIPE_CONFIG_QUIRK_MODE_SYNC_FLAGS;
+	} else {
+		if (dtd.part2.dtd_flags & DTD_FLAG_HSYNC_POSITIVE)
+			flags |= DRM_MODE_FLAG_PHSYNC;
+		else
+			flags |= DRM_MODE_FLAG_NHSYNC;
+
+		if (dtd.part2.dtd_flags & DTD_FLAG_VSYNC_POSITIVE)
+			flags |= DRM_MODE_FLAG_PVSYNC;
+		else
+			flags |= DRM_MODE_FLAG_NVSYNC;
+	}
+
+	pipe_config->base.adjusted_mode.flags |= flags;
+
+	/*
+	 * pixel multiplier readout is tricky: Only on i915g/gm it is stored in
+	 * the sdvo port register, on all other platforms it is part of the dpll
+	 * state. Since the general pipe state readout happens before the
+	 * encoder->get_config we so already have a valid pixel multplier on all
+	 * other platfroms.
+	 */
+	if (IS_I915G(dev) || IS_I915GM(dev)) {
+		pipe_config->pixel_multiplier =
+			((sdvox & SDVO_PORT_MULTIPLY_MASK)
+			 >> SDVO_PORT_MULTIPLY_SHIFT) + 1;
+	}
+
+	dotclock = pipe_config->port_clock;
+
+	if (pipe_config->pixel_multiplier)
+		dotclock /= pipe_config->pixel_multiplier;
+
+	pipe_config->base.adjusted_mode.crtc_clock = dotclock;
+
+	/* Cross check the port pixel multiplier with the sdvo encoder state. */
+	if (intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_CLOCK_RATE_MULT,
+				 &val, 1)) {
+		switch (val) {
+		case SDVO_CLOCK_RATE_MULT_1X:
+			encoder_pixel_multiplier = 1;
+			break;
+		case SDVO_CLOCK_RATE_MULT_2X:
+			encoder_pixel_multiplier = 2;
+			break;
+		case SDVO_CLOCK_RATE_MULT_4X:
+			encoder_pixel_multiplier = 4;
+			break;
+		}
+	}
+
+	if (sdvox & HDMI_COLOR_RANGE_16_235)
+		pipe_config->limited_color_range = true;
+
+	if (intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_ENCODE,
+				 &val, 1)) {
+		if (val == SDVO_ENCODE_HDMI)
+			pipe_config->has_hdmi_sink = true;
+	}
+
+	WARN(encoder_pixel_multiplier != pipe_config->pixel_multiplier,
+	     "SDVO pixel multiplier mismatch, port: %i, encoder: %i\n",
+	     pipe_config->pixel_multiplier, encoder_pixel_multiplier);
+}
+
+static void intel_disable_sdvo(struct intel_encoder *encoder)
+{
+	struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
+	struct intel_sdvo *intel_sdvo = to_sdvo(encoder);
+	struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc);
+	u32 temp;
+
+	intel_sdvo_set_active_outputs(intel_sdvo, 0);
+	if (0)
+		intel_sdvo_set_encoder_power_state(intel_sdvo,
+						   DRM_MODE_DPMS_OFF);
+
+	temp = I915_READ(intel_sdvo->sdvo_reg);
+
+	temp &= ~SDVO_ENABLE;
+	intel_sdvo_write_sdvox(intel_sdvo, temp);
+
+	/*
+	 * HW workaround for IBX, we need to move the port
+	 * to transcoder A after disabling it to allow the
+	 * matching DP port to be enabled on transcoder A.
+	 */
+	if (HAS_PCH_IBX(dev_priv) && crtc->pipe == PIPE_B) {
+		/*
+		 * We get CPU/PCH FIFO underruns on the other pipe when
+		 * doing the workaround. Sweep them under the rug.
+		 */
+		intel_set_cpu_fifo_underrun_reporting(dev_priv, PIPE_A, false);
+		intel_set_pch_fifo_underrun_reporting(dev_priv, PIPE_A, false);
+
+		temp &= ~SDVO_PIPE_B_SELECT;
+		temp |= SDVO_ENABLE;
+		intel_sdvo_write_sdvox(intel_sdvo, temp);
+
+		temp &= ~SDVO_ENABLE;
+		intel_sdvo_write_sdvox(intel_sdvo, temp);
+
+		intel_wait_for_vblank_if_active(dev_priv->dev, PIPE_A);
+		intel_set_cpu_fifo_underrun_reporting(dev_priv, PIPE_A, true);
+		intel_set_pch_fifo_underrun_reporting(dev_priv, PIPE_A, true);
+	}
+}
+
+static void pch_disable_sdvo(struct intel_encoder *encoder)
+{
+}
+
+static void pch_post_disable_sdvo(struct intel_encoder *encoder)
+{
+	intel_disable_sdvo(encoder);
+}
+
+static void intel_enable_sdvo(struct intel_encoder *encoder)
+{
+	struct drm_device *dev = encoder->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_sdvo *intel_sdvo = to_sdvo(encoder);
+	struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc);
+	u32 temp;
+	bool input1, input2;
+	int i;
+	bool success;
+
+	temp = I915_READ(intel_sdvo->sdvo_reg);
+	temp |= SDVO_ENABLE;
+	intel_sdvo_write_sdvox(intel_sdvo, temp);
+
+	for (i = 0; i < 2; i++)
+		intel_wait_for_vblank(dev, intel_crtc->pipe);
+
+	success = intel_sdvo_get_trained_inputs(intel_sdvo, &input1, &input2);
+	/* Warn if the device reported failure to sync.
+	 * A lot of SDVO devices fail to notify of sync, but it's
+	 * a given it the status is a success, we succeeded.
+	 */
+	if (success && !input1) {
+		DRM_DEBUG_KMS("First %s output reported failure to "
+				"sync\n", SDVO_NAME(intel_sdvo));
+	}
+
+	if (0)
+		intel_sdvo_set_encoder_power_state(intel_sdvo,
+						   DRM_MODE_DPMS_ON);
+	intel_sdvo_set_active_outputs(intel_sdvo, intel_sdvo->attached_output);
+}
+
+static enum drm_mode_status
+intel_sdvo_mode_valid(struct drm_connector *connector,
+		      struct drm_display_mode *mode)
+{
+	struct intel_sdvo *intel_sdvo = intel_attached_sdvo(connector);
+	int max_dotclk = to_i915(connector->dev)->max_dotclk_freq;
+
+	if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
+		return MODE_NO_DBLESCAN;
+
+	if (intel_sdvo->pixel_clock_min > mode->clock)
+		return MODE_CLOCK_LOW;
+
+	if (intel_sdvo->pixel_clock_max < mode->clock)
+		return MODE_CLOCK_HIGH;
+
+	if (mode->clock > max_dotclk)
+		return MODE_CLOCK_HIGH;
+
+	if (intel_sdvo->is_lvds) {
+		if (mode->hdisplay > intel_sdvo->sdvo_lvds_fixed_mode->hdisplay)
+			return MODE_PANEL;
+
+		if (mode->vdisplay > intel_sdvo->sdvo_lvds_fixed_mode->vdisplay)
+			return MODE_PANEL;
+	}
+
+	return MODE_OK;
+}
+
+static bool intel_sdvo_get_capabilities(struct intel_sdvo *intel_sdvo, struct intel_sdvo_caps *caps)
+{
+	BUILD_BUG_ON(sizeof(*caps) != 8);
+	if (!intel_sdvo_get_value(intel_sdvo,
+				  SDVO_CMD_GET_DEVICE_CAPS,
+				  caps, sizeof(*caps)))
+		return false;
+
+	DRM_DEBUG_KMS("SDVO capabilities:\n"
+		      "  vendor_id: %d\n"
+		      "  device_id: %d\n"
+		      "  device_rev_id: %d\n"
+		      "  sdvo_version_major: %d\n"
+		      "  sdvo_version_minor: %d\n"
+		      "  sdvo_inputs_mask: %d\n"
+		      "  smooth_scaling: %d\n"
+		      "  sharp_scaling: %d\n"
+		      "  up_scaling: %d\n"
+		      "  down_scaling: %d\n"
+		      "  stall_support: %d\n"
+		      "  output_flags: %d\n",
+		      caps->vendor_id,
+		      caps->device_id,
+		      caps->device_rev_id,
+		      caps->sdvo_version_major,
+		      caps->sdvo_version_minor,
+		      caps->sdvo_inputs_mask,
+		      caps->smooth_scaling,
+		      caps->sharp_scaling,
+		      caps->up_scaling,
+		      caps->down_scaling,
+		      caps->stall_support,
+		      caps->output_flags);
+
+	return true;
+}
+
+static uint16_t intel_sdvo_get_hotplug_support(struct intel_sdvo *intel_sdvo)
+{
+	struct drm_device *dev = intel_sdvo->base.base.dev;
+	uint16_t hotplug;
+
+	if (!I915_HAS_HOTPLUG(dev))
+		return 0;
+
+	/* HW Erratum: SDVO Hotplug is broken on all i945G chips, there's noise
+	 * on the line. */
+	if (IS_I945G(dev) || IS_I945GM(dev))
+		return 0;
+
+	if (!intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_HOT_PLUG_SUPPORT,
+					&hotplug, sizeof(hotplug)))
+		return 0;
+
+	return hotplug;
+}
+
+static void intel_sdvo_enable_hotplug(struct intel_encoder *encoder)
+{
+	struct intel_sdvo *intel_sdvo = to_sdvo(encoder);
+
+	intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_SET_ACTIVE_HOT_PLUG,
+			&intel_sdvo->hotplug_active, 2);
+}
+
+static bool
+intel_sdvo_multifunc_encoder(struct intel_sdvo *intel_sdvo)
+{
+	/* Is there more than one type of output? */
+	return hweight16(intel_sdvo->caps.output_flags) > 1;
+}
+
+static struct edid *
+intel_sdvo_get_edid(struct drm_connector *connector)
+{
+	struct intel_sdvo *sdvo = intel_attached_sdvo(connector);
+	return drm_get_edid(connector, &sdvo->ddc);
+}
+
+/* Mac mini hack -- use the same DDC as the analog connector */
+static struct edid *
+intel_sdvo_get_analog_edid(struct drm_connector *connector)
+{
+	struct drm_i915_private *dev_priv = connector->dev->dev_private;
+
+	return drm_get_edid(connector,
+			    intel_gmbus_get_adapter(dev_priv,
+						    dev_priv->vbt.crt_ddc_pin));
+}
+
+static enum drm_connector_status
+intel_sdvo_tmds_sink_detect(struct drm_connector *connector)
+{
+	struct intel_sdvo *intel_sdvo = intel_attached_sdvo(connector);
+	enum drm_connector_status status;
+	struct edid *edid;
+
+	edid = intel_sdvo_get_edid(connector);
+
+	if (edid == NULL && intel_sdvo_multifunc_encoder(intel_sdvo)) {
+		u8 ddc, saved_ddc = intel_sdvo->ddc_bus;
+
+		/*
+		 * Don't use the 1 as the argument of DDC bus switch to get
+		 * the EDID. It is used for SDVO SPD ROM.
+		 */
+		for (ddc = intel_sdvo->ddc_bus >> 1; ddc > 1; ddc >>= 1) {
+			intel_sdvo->ddc_bus = ddc;
+			edid = intel_sdvo_get_edid(connector);
+			if (edid)
+				break;
+		}
+		/*
+		 * If we found the EDID on the other bus,
+		 * assume that is the correct DDC bus.
+		 */
+		if (edid == NULL)
+			intel_sdvo->ddc_bus = saved_ddc;
+	}
+
+	/*
+	 * When there is no edid and no monitor is connected with VGA
+	 * port, try to use the CRT ddc to read the EDID for DVI-connector.
+	 */
+	if (edid == NULL)
+		edid = intel_sdvo_get_analog_edid(connector);
+
+	status = connector_status_unknown;
+	if (edid != NULL) {
+		/* DDC bus is shared, match EDID to connector type */
+		if (edid->input & DRM_EDID_INPUT_DIGITAL) {
+			status = connector_status_connected;
+			if (intel_sdvo->is_hdmi) {
+				intel_sdvo->has_hdmi_monitor = drm_detect_hdmi_monitor(edid);
+				intel_sdvo->has_hdmi_audio = drm_detect_monitor_audio(edid);
+				intel_sdvo->rgb_quant_range_selectable =
+					drm_rgb_quant_range_selectable(edid);
+			}
+		} else
+			status = connector_status_disconnected;
+		kfree(edid);
+	}
+
+	if (status == connector_status_connected) {
+		struct intel_sdvo_connector *intel_sdvo_connector = to_intel_sdvo_connector(connector);
+		if (intel_sdvo_connector->force_audio != HDMI_AUDIO_AUTO)
+			intel_sdvo->has_hdmi_audio = (intel_sdvo_connector->force_audio == HDMI_AUDIO_ON);
+	}
+
+	return status;
+}
+
+static bool
+intel_sdvo_connector_matches_edid(struct intel_sdvo_connector *sdvo,
+				  struct edid *edid)
+{
+	bool monitor_is_digital = !!(edid->input & DRM_EDID_INPUT_DIGITAL);
+	bool connector_is_digital = !!IS_DIGITAL(sdvo);
+
+	DRM_DEBUG_KMS("connector_is_digital? %d, monitor_is_digital? %d\n",
+		      connector_is_digital, monitor_is_digital);
+	return connector_is_digital == monitor_is_digital;
+}
+
+static enum drm_connector_status
+intel_sdvo_detect(struct drm_connector *connector, bool force)
+{
+	uint16_t response;
+	struct intel_sdvo *intel_sdvo = intel_attached_sdvo(connector);
+	struct intel_sdvo_connector *intel_sdvo_connector = to_intel_sdvo_connector(connector);
+	enum drm_connector_status ret;
+
+	DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
+		      connector->base.id, connector->name);
+
+	if (!intel_sdvo_get_value(intel_sdvo,
+				  SDVO_CMD_GET_ATTACHED_DISPLAYS,
+				  &response, 2))
+		return connector_status_unknown;
+
+	DRM_DEBUG_KMS("SDVO response %d %d [%x]\n",
+		      response & 0xff, response >> 8,
+		      intel_sdvo_connector->output_flag);
+
+	if (response == 0)
+		return connector_status_disconnected;
+
+	intel_sdvo->attached_output = response;
+
+	intel_sdvo->has_hdmi_monitor = false;
+	intel_sdvo->has_hdmi_audio = false;
+	intel_sdvo->rgb_quant_range_selectable = false;
+
+	if ((intel_sdvo_connector->output_flag & response) == 0)
+		ret = connector_status_disconnected;
+	else if (IS_TMDS(intel_sdvo_connector))
+		ret = intel_sdvo_tmds_sink_detect(connector);
+	else {
+		struct edid *edid;
+
+		/* if we have an edid check it matches the connection */
+		edid = intel_sdvo_get_edid(connector);
+		if (edid == NULL)
+			edid = intel_sdvo_get_analog_edid(connector);
+		if (edid != NULL) {
+			if (intel_sdvo_connector_matches_edid(intel_sdvo_connector,
+							      edid))
+				ret = connector_status_connected;
+			else
+				ret = connector_status_disconnected;
+
+			kfree(edid);
+		} else
+			ret = connector_status_connected;
+	}
+
+	/* May update encoder flag for like clock for SDVO TV, etc.*/
+	if (ret == connector_status_connected) {
+		intel_sdvo->is_tv = false;
+		intel_sdvo->is_lvds = false;
+
+		if (response & SDVO_TV_MASK)
+			intel_sdvo->is_tv = true;
+		if (response & SDVO_LVDS_MASK)
+			intel_sdvo->is_lvds = intel_sdvo->sdvo_lvds_fixed_mode != NULL;
+	}
+
+	return ret;
+}
+
+static void intel_sdvo_get_ddc_modes(struct drm_connector *connector)
+{
+	struct edid *edid;
+
+	DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
+		      connector->base.id, connector->name);
+
+	/* set the bus switch and get the modes */
+	edid = intel_sdvo_get_edid(connector);
+
+	/*
+	 * Mac mini hack.  On this device, the DVI-I connector shares one DDC
+	 * link between analog and digital outputs. So, if the regular SDVO
+	 * DDC fails, check to see if the analog output is disconnected, in
+	 * which case we'll look there for the digital DDC data.
+	 */
+	if (edid == NULL)
+		edid = intel_sdvo_get_analog_edid(connector);
+
+	if (edid != NULL) {
+		if (intel_sdvo_connector_matches_edid(to_intel_sdvo_connector(connector),
+						      edid)) {
+			drm_mode_connector_update_edid_property(connector, edid);
+			drm_add_edid_modes(connector, edid);
+		}
+
+		kfree(edid);
+	}
+}
+
+/*
+ * Set of SDVO TV modes.
+ * Note!  This is in reply order (see loop in get_tv_modes).
+ * XXX: all 60Hz refresh?
+ */
+static const struct drm_display_mode sdvo_tv_modes[] = {
+	{ DRM_MODE("320x200", DRM_MODE_TYPE_DRIVER, 5815, 320, 321, 384,
+		   416, 0, 200, 201, 232, 233, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+	{ DRM_MODE("320x240", DRM_MODE_TYPE_DRIVER, 6814, 320, 321, 384,
+		   416, 0, 240, 241, 272, 273, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+	{ DRM_MODE("400x300", DRM_MODE_TYPE_DRIVER, 9910, 400, 401, 464,
+		   496, 0, 300, 301, 332, 333, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+	{ DRM_MODE("640x350", DRM_MODE_TYPE_DRIVER, 16913, 640, 641, 704,
+		   736, 0, 350, 351, 382, 383, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+	{ DRM_MODE("640x400", DRM_MODE_TYPE_DRIVER, 19121, 640, 641, 704,
+		   736, 0, 400, 401, 432, 433, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+	{ DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 22654, 640, 641, 704,
+		   736, 0, 480, 481, 512, 513, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+	{ DRM_MODE("704x480", DRM_MODE_TYPE_DRIVER, 24624, 704, 705, 768,
+		   800, 0, 480, 481, 512, 513, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+	{ DRM_MODE("704x576", DRM_MODE_TYPE_DRIVER, 29232, 704, 705, 768,
+		   800, 0, 576, 577, 608, 609, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+	{ DRM_MODE("720x350", DRM_MODE_TYPE_DRIVER, 18751, 720, 721, 784,
+		   816, 0, 350, 351, 382, 383, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+	{ DRM_MODE("720x400", DRM_MODE_TYPE_DRIVER, 21199, 720, 721, 784,
+		   816, 0, 400, 401, 432, 433, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+	{ DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 25116, 720, 721, 784,
+		   816, 0, 480, 481, 512, 513, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+	{ DRM_MODE("720x540", DRM_MODE_TYPE_DRIVER, 28054, 720, 721, 784,
+		   816, 0, 540, 541, 572, 573, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+	{ DRM_MODE("720x576", DRM_MODE_TYPE_DRIVER, 29816, 720, 721, 784,
+		   816, 0, 576, 577, 608, 609, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+	{ DRM_MODE("768x576", DRM_MODE_TYPE_DRIVER, 31570, 768, 769, 832,
+		   864, 0, 576, 577, 608, 609, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+	{ DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 34030, 800, 801, 864,
+		   896, 0, 600, 601, 632, 633, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+	{ DRM_MODE("832x624", DRM_MODE_TYPE_DRIVER, 36581, 832, 833, 896,
+		   928, 0, 624, 625, 656, 657, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+	{ DRM_MODE("920x766", DRM_MODE_TYPE_DRIVER, 48707, 920, 921, 984,
+		   1016, 0, 766, 767, 798, 799, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+	{ DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 53827, 1024, 1025, 1088,
+		   1120, 0, 768, 769, 800, 801, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+	{ DRM_MODE("1280x1024", DRM_MODE_TYPE_DRIVER, 87265, 1280, 1281, 1344,
+		   1376, 0, 1024, 1025, 1056, 1057, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+};
+
+static void intel_sdvo_get_tv_modes(struct drm_connector *connector)
+{
+	struct intel_sdvo *intel_sdvo = intel_attached_sdvo(connector);
+	struct intel_sdvo_sdtv_resolution_request tv_res;
+	uint32_t reply = 0, format_map = 0;
+	int i;
+
+	DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
+		      connector->base.id, connector->name);
+
+	/* Read the list of supported input resolutions for the selected TV
+	 * format.
+	 */
+	format_map = 1 << intel_sdvo->tv_format_index;
+	memcpy(&tv_res, &format_map,
+	       min(sizeof(format_map), sizeof(struct intel_sdvo_sdtv_resolution_request)));
+
+	if (!intel_sdvo_set_target_output(intel_sdvo, intel_sdvo->attached_output))
+		return;
+
+	BUILD_BUG_ON(sizeof(tv_res) != 3);
+	if (!intel_sdvo_write_cmd(intel_sdvo,
+				  SDVO_CMD_GET_SDTV_RESOLUTION_SUPPORT,
+				  &tv_res, sizeof(tv_res)))
+		return;
+	if (!intel_sdvo_read_response(intel_sdvo, &reply, 3))
+		return;
+
+	for (i = 0; i < ARRAY_SIZE(sdvo_tv_modes); i++)
+		if (reply & (1 << i)) {
+			struct drm_display_mode *nmode;
+			nmode = drm_mode_duplicate(connector->dev,
+						   &sdvo_tv_modes[i]);
+			if (nmode)
+				drm_mode_probed_add(connector, nmode);
+		}
+}
+
+static void intel_sdvo_get_lvds_modes(struct drm_connector *connector)
+{
+	struct intel_sdvo *intel_sdvo = intel_attached_sdvo(connector);
+	struct drm_i915_private *dev_priv = connector->dev->dev_private;
+	struct drm_display_mode *newmode;
+
+	DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
+		      connector->base.id, connector->name);
+
+	/*
+	 * Fetch modes from VBT. For SDVO prefer the VBT mode since some
+	 * SDVO->LVDS transcoders can't cope with the EDID mode.
+	 */
+	if (dev_priv->vbt.sdvo_lvds_vbt_mode != NULL) {
+		newmode = drm_mode_duplicate(connector->dev,
+					     dev_priv->vbt.sdvo_lvds_vbt_mode);
+		if (newmode != NULL) {
+			/* Guarantee the mode is preferred */
+			newmode->type = (DRM_MODE_TYPE_PREFERRED |
+					 DRM_MODE_TYPE_DRIVER);
+			drm_mode_probed_add(connector, newmode);
+		}
+	}
+
+	/*
+	 * Attempt to get the mode list from DDC.
+	 * Assume that the preferred modes are
+	 * arranged in priority order.
+	 */
+	intel_ddc_get_modes(connector, &intel_sdvo->ddc);
+
+	list_for_each_entry(newmode, &connector->probed_modes, head) {
+		if (newmode->type & DRM_MODE_TYPE_PREFERRED) {
+			intel_sdvo->sdvo_lvds_fixed_mode =
+				drm_mode_duplicate(connector->dev, newmode);
+
+			intel_sdvo->is_lvds = true;
+			break;
+		}
+	}
+}
+
+static int intel_sdvo_get_modes(struct drm_connector *connector)
+{
+	struct intel_sdvo_connector *intel_sdvo_connector = to_intel_sdvo_connector(connector);
+
+	if (IS_TV(intel_sdvo_connector))
+		intel_sdvo_get_tv_modes(connector);
+	else if (IS_LVDS(intel_sdvo_connector))
+		intel_sdvo_get_lvds_modes(connector);
+	else
+		intel_sdvo_get_ddc_modes(connector);
+
+	return !list_empty(&connector->probed_modes);
+}
+
+static void intel_sdvo_destroy(struct drm_connector *connector)
+{
+	struct intel_sdvo_connector *intel_sdvo_connector = to_intel_sdvo_connector(connector);
+
+	drm_connector_cleanup(connector);
+	kfree(intel_sdvo_connector);
+}
+
+static bool intel_sdvo_detect_hdmi_audio(struct drm_connector *connector)
+{
+	struct intel_sdvo *intel_sdvo = intel_attached_sdvo(connector);
+	struct edid *edid;
+	bool has_audio = false;
+
+	if (!intel_sdvo->is_hdmi)
+		return false;
+
+	edid = intel_sdvo_get_edid(connector);
+	if (edid != NULL && edid->input & DRM_EDID_INPUT_DIGITAL)
+		has_audio = drm_detect_monitor_audio(edid);
+	kfree(edid);
+
+	return has_audio;
+}
+
+static int
+intel_sdvo_set_property(struct drm_connector *connector,
+			struct drm_property *property,
+			uint64_t val)
+{
+	struct intel_sdvo *intel_sdvo = intel_attached_sdvo(connector);
+	struct intel_sdvo_connector *intel_sdvo_connector = to_intel_sdvo_connector(connector);
+	struct drm_i915_private *dev_priv = connector->dev->dev_private;
+	uint16_t temp_value;
+	uint8_t cmd;
+	int ret;
+
+	ret = drm_object_property_set_value(&connector->base, property, val);
+	if (ret)
+		return ret;
+
+	if (property == dev_priv->force_audio_property) {
+		int i = val;
+		bool has_audio;
+
+		if (i == intel_sdvo_connector->force_audio)
+			return 0;
+
+		intel_sdvo_connector->force_audio = i;
+
+		if (i == HDMI_AUDIO_AUTO)
+			has_audio = intel_sdvo_detect_hdmi_audio(connector);
+		else
+			has_audio = (i == HDMI_AUDIO_ON);
+
+		if (has_audio == intel_sdvo->has_hdmi_audio)
+			return 0;
+
+		intel_sdvo->has_hdmi_audio = has_audio;
+		goto done;
+	}
+
+	if (property == dev_priv->broadcast_rgb_property) {
+		bool old_auto = intel_sdvo->color_range_auto;
+		uint32_t old_range = intel_sdvo->color_range;
+
+		switch (val) {
+		case INTEL_BROADCAST_RGB_AUTO:
+			intel_sdvo->color_range_auto = true;
+			break;
+		case INTEL_BROADCAST_RGB_FULL:
+			intel_sdvo->color_range_auto = false;
+			intel_sdvo->color_range = 0;
+			break;
+		case INTEL_BROADCAST_RGB_LIMITED:
+			intel_sdvo->color_range_auto = false;
+			/* FIXME: this bit is only valid when using TMDS
+			 * encoding and 8 bit per color mode. */
+			intel_sdvo->color_range = HDMI_COLOR_RANGE_16_235;
+			break;
+		default:
+			return -EINVAL;
+		}
+
+		if (old_auto == intel_sdvo->color_range_auto &&
+		    old_range == intel_sdvo->color_range)
+			return 0;
+
+		goto done;
+	}
+
+	if (property == connector->dev->mode_config.aspect_ratio_property) {
+		switch (val) {
+		case DRM_MODE_PICTURE_ASPECT_NONE:
+			intel_sdvo->aspect_ratio = HDMI_PICTURE_ASPECT_NONE;
+			break;
+		case DRM_MODE_PICTURE_ASPECT_4_3:
+			intel_sdvo->aspect_ratio = HDMI_PICTURE_ASPECT_4_3;
+			break;
+		case DRM_MODE_PICTURE_ASPECT_16_9:
+			intel_sdvo->aspect_ratio = HDMI_PICTURE_ASPECT_16_9;
+			break;
+		default:
+			return -EINVAL;
+		}
+		goto done;
+	}
+
+#define CHECK_PROPERTY(name, NAME) \
+	if (intel_sdvo_connector->name == property) { \
+		if (intel_sdvo_connector->cur_##name == temp_value) return 0; \
+		if (intel_sdvo_connector->max_##name < temp_value) return -EINVAL; \
+		cmd = SDVO_CMD_SET_##NAME; \
+		intel_sdvo_connector->cur_##name = temp_value; \
+		goto set_value; \
+	}
+
+	if (property == intel_sdvo_connector->tv_format) {
+		if (val >= TV_FORMAT_NUM)
+			return -EINVAL;
+
+		if (intel_sdvo->tv_format_index ==
+		    intel_sdvo_connector->tv_format_supported[val])
+			return 0;
+
+		intel_sdvo->tv_format_index = intel_sdvo_connector->tv_format_supported[val];
+		goto done;
+	} else if (IS_TV_OR_LVDS(intel_sdvo_connector)) {
+		temp_value = val;
+		if (intel_sdvo_connector->left == property) {
+			drm_object_property_set_value(&connector->base,
+							 intel_sdvo_connector->right, val);
+			if (intel_sdvo_connector->left_margin == temp_value)
+				return 0;
+
+			intel_sdvo_connector->left_margin = temp_value;
+			intel_sdvo_connector->right_margin = temp_value;
+			temp_value = intel_sdvo_connector->max_hscan -
+				intel_sdvo_connector->left_margin;
+			cmd = SDVO_CMD_SET_OVERSCAN_H;
+			goto set_value;
+		} else if (intel_sdvo_connector->right == property) {
+			drm_object_property_set_value(&connector->base,
+							 intel_sdvo_connector->left, val);
+			if (intel_sdvo_connector->right_margin == temp_value)
+				return 0;
+
+			intel_sdvo_connector->left_margin = temp_value;
+			intel_sdvo_connector->right_margin = temp_value;
+			temp_value = intel_sdvo_connector->max_hscan -
+				intel_sdvo_connector->left_margin;
+			cmd = SDVO_CMD_SET_OVERSCAN_H;
+			goto set_value;
+		} else if (intel_sdvo_connector->top == property) {
+			drm_object_property_set_value(&connector->base,
+							 intel_sdvo_connector->bottom, val);
+			if (intel_sdvo_connector->top_margin == temp_value)
+				return 0;
+
+			intel_sdvo_connector->top_margin = temp_value;
+			intel_sdvo_connector->bottom_margin = temp_value;
+			temp_value = intel_sdvo_connector->max_vscan -
+				intel_sdvo_connector->top_margin;
+			cmd = SDVO_CMD_SET_OVERSCAN_V;
+			goto set_value;
+		} else if (intel_sdvo_connector->bottom == property) {
+			drm_object_property_set_value(&connector->base,
+							 intel_sdvo_connector->top, val);
+			if (intel_sdvo_connector->bottom_margin == temp_value)
+				return 0;
+
+			intel_sdvo_connector->top_margin = temp_value;
+			intel_sdvo_connector->bottom_margin = temp_value;
+			temp_value = intel_sdvo_connector->max_vscan -
+				intel_sdvo_connector->top_margin;
+			cmd = SDVO_CMD_SET_OVERSCAN_V;
+			goto set_value;
+		}
+		CHECK_PROPERTY(hpos, HPOS)
+		CHECK_PROPERTY(vpos, VPOS)
+		CHECK_PROPERTY(saturation, SATURATION)
+		CHECK_PROPERTY(contrast, CONTRAST)
+		CHECK_PROPERTY(hue, HUE)
+		CHECK_PROPERTY(brightness, BRIGHTNESS)
+		CHECK_PROPERTY(sharpness, SHARPNESS)
+		CHECK_PROPERTY(flicker_filter, FLICKER_FILTER)
+		CHECK_PROPERTY(flicker_filter_2d, FLICKER_FILTER_2D)
+		CHECK_PROPERTY(flicker_filter_adaptive, FLICKER_FILTER_ADAPTIVE)
+		CHECK_PROPERTY(tv_chroma_filter, TV_CHROMA_FILTER)
+		CHECK_PROPERTY(tv_luma_filter, TV_LUMA_FILTER)
+		CHECK_PROPERTY(dot_crawl, DOT_CRAWL)
+	}
+
+	return -EINVAL; /* unknown property */
+
+set_value:
+	if (!intel_sdvo_set_value(intel_sdvo, cmd, &temp_value, 2))
+		return -EIO;
+
+
+done:
+	if (intel_sdvo->base.base.crtc)
+		intel_crtc_restore_mode(intel_sdvo->base.base.crtc);
+
+	return 0;
+#undef CHECK_PROPERTY
+}
+
+static const struct drm_connector_funcs intel_sdvo_connector_funcs = {
+	.dpms = drm_atomic_helper_connector_dpms,
+	.detect = intel_sdvo_detect,
+	.fill_modes = drm_helper_probe_single_connector_modes,
+	.set_property = intel_sdvo_set_property,
+	.atomic_get_property = intel_connector_atomic_get_property,
+	.destroy = intel_sdvo_destroy,
+	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
+	.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
+};
+
+static const struct drm_connector_helper_funcs intel_sdvo_connector_helper_funcs = {
+	.get_modes = intel_sdvo_get_modes,
+	.mode_valid = intel_sdvo_mode_valid,
+	.best_encoder = intel_best_encoder,
+};
+
+static void intel_sdvo_enc_destroy(struct drm_encoder *encoder)
+{
+	struct intel_sdvo *intel_sdvo = to_sdvo(to_intel_encoder(encoder));
+
+	if (intel_sdvo->sdvo_lvds_fixed_mode != NULL)
+		drm_mode_destroy(encoder->dev,
+				 intel_sdvo->sdvo_lvds_fixed_mode);
+
+	i2c_del_adapter(&intel_sdvo->ddc);
+	intel_encoder_destroy(encoder);
+}
+
+static const struct drm_encoder_funcs intel_sdvo_enc_funcs = {
+	.destroy = intel_sdvo_enc_destroy,
+};
+
+static void
+intel_sdvo_guess_ddc_bus(struct intel_sdvo *sdvo)
+{
+	uint16_t mask = 0;
+	unsigned int num_bits;
+
+	/* Make a mask of outputs less than or equal to our own priority in the
+	 * list.
+	 */
+	switch (sdvo->controlled_output) {
+	case SDVO_OUTPUT_LVDS1:
+		mask |= SDVO_OUTPUT_LVDS1;
+	case SDVO_OUTPUT_LVDS0:
+		mask |= SDVO_OUTPUT_LVDS0;
+	case SDVO_OUTPUT_TMDS1:
+		mask |= SDVO_OUTPUT_TMDS1;
+	case SDVO_OUTPUT_TMDS0:
+		mask |= SDVO_OUTPUT_TMDS0;
+	case SDVO_OUTPUT_RGB1:
+		mask |= SDVO_OUTPUT_RGB1;
+	case SDVO_OUTPUT_RGB0:
+		mask |= SDVO_OUTPUT_RGB0;
+		break;
+	}
+
+	/* Count bits to find what number we are in the priority list. */
+	mask &= sdvo->caps.output_flags;
+	num_bits = hweight16(mask);
+	/* If more than 3 outputs, default to DDC bus 3 for now. */
+	if (num_bits > 3)
+		num_bits = 3;
+
+	/* Corresponds to SDVO_CONTROL_BUS_DDCx */
+	sdvo->ddc_bus = 1 << num_bits;
+}
+
+/**
+ * Choose the appropriate DDC bus for control bus switch command for this
+ * SDVO output based on the controlled output.
+ *
+ * DDC bus number assignment is in a priority order of RGB outputs, then TMDS
+ * outputs, then LVDS outputs.
+ */
+static void
+intel_sdvo_select_ddc_bus(struct drm_i915_private *dev_priv,
+			  struct intel_sdvo *sdvo)
+{
+	struct sdvo_device_mapping *mapping;
+
+	if (sdvo->port == PORT_B)
+		mapping = &dev_priv->vbt.sdvo_mappings[0];
+	else
+		mapping = &dev_priv->vbt.sdvo_mappings[1];
+
+	if (mapping->initialized)
+		sdvo->ddc_bus = 1 << ((mapping->ddc_pin & 0xf0) >> 4);
+	else
+		intel_sdvo_guess_ddc_bus(sdvo);
+}
+
+static void
+intel_sdvo_select_i2c_bus(struct drm_i915_private *dev_priv,
+			  struct intel_sdvo *sdvo)
+{
+	struct sdvo_device_mapping *mapping;
+	u8 pin;
+
+	if (sdvo->port == PORT_B)
+		mapping = &dev_priv->vbt.sdvo_mappings[0];
+	else
+		mapping = &dev_priv->vbt.sdvo_mappings[1];
+
+	if (mapping->initialized &&
+	    intel_gmbus_is_valid_pin(dev_priv, mapping->i2c_pin))
+		pin = mapping->i2c_pin;
+	else
+		pin = GMBUS_PIN_DPB;
+
+	sdvo->i2c = intel_gmbus_get_adapter(dev_priv, pin);
+
+	/* With gmbus we should be able to drive sdvo i2c at 2MHz, but somehow
+	 * our code totally fails once we start using gmbus. Hence fall back to
+	 * bit banging for now. */
+	intel_gmbus_force_bit(sdvo->i2c, true);
+}
+
+/* undo any changes intel_sdvo_select_i2c_bus() did to sdvo->i2c */
+static void
+intel_sdvo_unselect_i2c_bus(struct intel_sdvo *sdvo)
+{
+	intel_gmbus_force_bit(sdvo->i2c, false);
+}
+
+static bool
+intel_sdvo_is_hdmi_connector(struct intel_sdvo *intel_sdvo, int device)
+{
+	return intel_sdvo_check_supp_encode(intel_sdvo);
+}
+
+static u8
+intel_sdvo_get_slave_addr(struct drm_device *dev, struct intel_sdvo *sdvo)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct sdvo_device_mapping *my_mapping, *other_mapping;
+
+	if (sdvo->port == PORT_B) {
+		my_mapping = &dev_priv->vbt.sdvo_mappings[0];
+		other_mapping = &dev_priv->vbt.sdvo_mappings[1];
+	} else {
+		my_mapping = &dev_priv->vbt.sdvo_mappings[1];
+		other_mapping = &dev_priv->vbt.sdvo_mappings[0];
+	}
+
+	/* If the BIOS described our SDVO device, take advantage of it. */
+	if (my_mapping->slave_addr)
+		return my_mapping->slave_addr;
+
+	/* If the BIOS only described a different SDVO device, use the
+	 * address that it isn't using.
+	 */
+	if (other_mapping->slave_addr) {
+		if (other_mapping->slave_addr == 0x70)
+			return 0x72;
+		else
+			return 0x70;
+	}
+
+	/* No SDVO device info is found for another DVO port,
+	 * so use mapping assumption we had before BIOS parsing.
+	 */
+	if (sdvo->port == PORT_B)
+		return 0x70;
+	else
+		return 0x72;
+}
+
+static void
+intel_sdvo_connector_unregister(struct intel_connector *intel_connector)
+{
+	struct drm_connector *drm_connector;
+	struct intel_sdvo *sdvo_encoder;
+
+	drm_connector = &intel_connector->base;
+	sdvo_encoder = intel_attached_sdvo(&intel_connector->base);
+
+	sysfs_remove_link(&drm_connector->kdev->kobj,
+			  sdvo_encoder->ddc.dev.kobj.name);
+	intel_connector_unregister(intel_connector);
+}
+
+static int
+intel_sdvo_connector_init(struct intel_sdvo_connector *connector,
+			  struct intel_sdvo *encoder)
+{
+	struct drm_connector *drm_connector;
+	int ret;
+
+	drm_connector = &connector->base.base;
+	ret = drm_connector_init(encoder->base.base.dev,
+			   drm_connector,
+			   &intel_sdvo_connector_funcs,
+			   connector->base.base.connector_type);
+	if (ret < 0)
+		return ret;
+
+	drm_connector_helper_add(drm_connector,
+				 &intel_sdvo_connector_helper_funcs);
+
+	connector->base.base.interlace_allowed = 1;
+	connector->base.base.doublescan_allowed = 0;
+	connector->base.base.display_info.subpixel_order = SubPixelHorizontalRGB;
+	connector->base.get_hw_state = intel_sdvo_connector_get_hw_state;
+	connector->base.unregister = intel_sdvo_connector_unregister;
+
+	intel_connector_attach_encoder(&connector->base, &encoder->base);
+	ret = drm_connector_register(drm_connector);
+	if (ret < 0)
+		goto err1;
+
+	ret = sysfs_create_link(&drm_connector->kdev->kobj,
+				&encoder->ddc.dev.kobj,
+				encoder->ddc.dev.kobj.name);
+	if (ret < 0)
+		goto err2;
+
+	return 0;
+
+err2:
+	drm_connector_unregister(drm_connector);
+err1:
+	drm_connector_cleanup(drm_connector);
+
+	return ret;
+}
+
+static void
+intel_sdvo_add_hdmi_properties(struct intel_sdvo *intel_sdvo,
+			       struct intel_sdvo_connector *connector)
+{
+	struct drm_device *dev = connector->base.base.dev;
+
+	intel_attach_force_audio_property(&connector->base.base);
+	if (INTEL_INFO(dev)->gen >= 4 && IS_MOBILE(dev)) {
+		intel_attach_broadcast_rgb_property(&connector->base.base);
+		intel_sdvo->color_range_auto = true;
+	}
+	intel_attach_aspect_ratio_property(&connector->base.base);
+	intel_sdvo->aspect_ratio = HDMI_PICTURE_ASPECT_NONE;
+}
+
+static struct intel_sdvo_connector *intel_sdvo_connector_alloc(void)
+{
+	struct intel_sdvo_connector *sdvo_connector;
+
+	sdvo_connector = kzalloc(sizeof(*sdvo_connector), GFP_KERNEL);
+	if (!sdvo_connector)
+		return NULL;
+
+	if (intel_connector_init(&sdvo_connector->base) < 0) {
+		kfree(sdvo_connector);
+		return NULL;
+	}
+
+	return sdvo_connector;
+}
+
+static bool
+intel_sdvo_dvi_init(struct intel_sdvo *intel_sdvo, int device)
+{
+	struct drm_encoder *encoder = &intel_sdvo->base.base;
+	struct drm_connector *connector;
+	struct intel_encoder *intel_encoder = to_intel_encoder(encoder);
+	struct intel_connector *intel_connector;
+	struct intel_sdvo_connector *intel_sdvo_connector;
+
+	DRM_DEBUG_KMS("initialising DVI device %d\n", device);
+
+	intel_sdvo_connector = intel_sdvo_connector_alloc();
+	if (!intel_sdvo_connector)
+		return false;
+
+	if (device == 0) {
+		intel_sdvo->controlled_output |= SDVO_OUTPUT_TMDS0;
+		intel_sdvo_connector->output_flag = SDVO_OUTPUT_TMDS0;
+	} else if (device == 1) {
+		intel_sdvo->controlled_output |= SDVO_OUTPUT_TMDS1;
+		intel_sdvo_connector->output_flag = SDVO_OUTPUT_TMDS1;
+	}
+
+	intel_connector = &intel_sdvo_connector->base;
+	connector = &intel_connector->base;
+	if (intel_sdvo_get_hotplug_support(intel_sdvo) &
+		intel_sdvo_connector->output_flag) {
+		intel_sdvo->hotplug_active |= intel_sdvo_connector->output_flag;
+		/* Some SDVO devices have one-shot hotplug interrupts.
+		 * Ensure that they get re-enabled when an interrupt happens.
+		 */
+		intel_encoder->hot_plug = intel_sdvo_enable_hotplug;
+		intel_sdvo_enable_hotplug(intel_encoder);
+	} else {
+		intel_connector->polled = DRM_CONNECTOR_POLL_CONNECT | DRM_CONNECTOR_POLL_DISCONNECT;
+	}
+	encoder->encoder_type = DRM_MODE_ENCODER_TMDS;
+	connector->connector_type = DRM_MODE_CONNECTOR_DVID;
+
+	if (intel_sdvo_is_hdmi_connector(intel_sdvo, device)) {
+		connector->connector_type = DRM_MODE_CONNECTOR_HDMIA;
+		intel_sdvo->is_hdmi = true;
+	}
+
+	if (intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo) < 0) {
+		kfree(intel_sdvo_connector);
+		return false;
+	}
+
+	if (intel_sdvo->is_hdmi)
+		intel_sdvo_add_hdmi_properties(intel_sdvo, intel_sdvo_connector);
+
+	return true;
+}
+
+static bool
+intel_sdvo_tv_init(struct intel_sdvo *intel_sdvo, int type)
+{
+	struct drm_encoder *encoder = &intel_sdvo->base.base;
+	struct drm_connector *connector;
+	struct intel_connector *intel_connector;
+	struct intel_sdvo_connector *intel_sdvo_connector;
+
+	DRM_DEBUG_KMS("initialising TV type %d\n", type);
+
+	intel_sdvo_connector = intel_sdvo_connector_alloc();
+	if (!intel_sdvo_connector)
+		return false;
+
+	intel_connector = &intel_sdvo_connector->base;
+	connector = &intel_connector->base;
+	encoder->encoder_type = DRM_MODE_ENCODER_TVDAC;
+	connector->connector_type = DRM_MODE_CONNECTOR_SVIDEO;
+
+	intel_sdvo->controlled_output |= type;
+	intel_sdvo_connector->output_flag = type;
+
+	intel_sdvo->is_tv = true;
+
+	if (intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo) < 0) {
+		kfree(intel_sdvo_connector);
+		return false;
+	}
+
+	if (!intel_sdvo_tv_create_property(intel_sdvo, intel_sdvo_connector, type))
+		goto err;
+
+	if (!intel_sdvo_create_enhance_property(intel_sdvo, intel_sdvo_connector))
+		goto err;
+
+	return true;
+
+err:
+	drm_connector_unregister(connector);
+	intel_sdvo_destroy(connector);
+	return false;
+}
+
+static bool
+intel_sdvo_analog_init(struct intel_sdvo *intel_sdvo, int device)
+{
+	struct drm_encoder *encoder = &intel_sdvo->base.base;
+	struct drm_connector *connector;
+	struct intel_connector *intel_connector;
+	struct intel_sdvo_connector *intel_sdvo_connector;
+
+	DRM_DEBUG_KMS("initialising analog device %d\n", device);
+
+	intel_sdvo_connector = intel_sdvo_connector_alloc();
+	if (!intel_sdvo_connector)
+		return false;
+
+	intel_connector = &intel_sdvo_connector->base;
+	connector = &intel_connector->base;
+	intel_connector->polled = DRM_CONNECTOR_POLL_CONNECT;
+	encoder->encoder_type = DRM_MODE_ENCODER_DAC;
+	connector->connector_type = DRM_MODE_CONNECTOR_VGA;
+
+	if (device == 0) {
+		intel_sdvo->controlled_output |= SDVO_OUTPUT_RGB0;
+		intel_sdvo_connector->output_flag = SDVO_OUTPUT_RGB0;
+	} else if (device == 1) {
+		intel_sdvo->controlled_output |= SDVO_OUTPUT_RGB1;
+		intel_sdvo_connector->output_flag = SDVO_OUTPUT_RGB1;
+	}
+
+	if (intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo) < 0) {
+		kfree(intel_sdvo_connector);
+		return false;
+	}
+
+	return true;
+}
+
+static bool
+intel_sdvo_lvds_init(struct intel_sdvo *intel_sdvo, int device)
+{
+	struct drm_encoder *encoder = &intel_sdvo->base.base;
+	struct drm_connector *connector;
+	struct intel_connector *intel_connector;
+	struct intel_sdvo_connector *intel_sdvo_connector;
+
+	DRM_DEBUG_KMS("initialising LVDS device %d\n", device);
+
+	intel_sdvo_connector = intel_sdvo_connector_alloc();
+	if (!intel_sdvo_connector)
+		return false;
+
+	intel_connector = &intel_sdvo_connector->base;
+	connector = &intel_connector->base;
+	encoder->encoder_type = DRM_MODE_ENCODER_LVDS;
+	connector->connector_type = DRM_MODE_CONNECTOR_LVDS;
+
+	if (device == 0) {
+		intel_sdvo->controlled_output |= SDVO_OUTPUT_LVDS0;
+		intel_sdvo_connector->output_flag = SDVO_OUTPUT_LVDS0;
+	} else if (device == 1) {
+		intel_sdvo->controlled_output |= SDVO_OUTPUT_LVDS1;
+		intel_sdvo_connector->output_flag = SDVO_OUTPUT_LVDS1;
+	}
+
+	if (intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo) < 0) {
+		kfree(intel_sdvo_connector);
+		return false;
+	}
+
+	if (!intel_sdvo_create_enhance_property(intel_sdvo, intel_sdvo_connector))
+		goto err;
+
+	return true;
+
+err:
+	drm_connector_unregister(connector);
+	intel_sdvo_destroy(connector);
+	return false;
+}
+
+static bool
+intel_sdvo_output_setup(struct intel_sdvo *intel_sdvo, uint16_t flags)
+{
+	intel_sdvo->is_tv = false;
+	intel_sdvo->is_lvds = false;
+
+	/* SDVO requires XXX1 function may not exist unless it has XXX0 function.*/
+
+	if (flags & SDVO_OUTPUT_TMDS0)
+		if (!intel_sdvo_dvi_init(intel_sdvo, 0))
+			return false;
+
+	if ((flags & SDVO_TMDS_MASK) == SDVO_TMDS_MASK)
+		if (!intel_sdvo_dvi_init(intel_sdvo, 1))
+			return false;
+
+	/* TV has no XXX1 function block */
+	if (flags & SDVO_OUTPUT_SVID0)
+		if (!intel_sdvo_tv_init(intel_sdvo, SDVO_OUTPUT_SVID0))
+			return false;
+
+	if (flags & SDVO_OUTPUT_CVBS0)
+		if (!intel_sdvo_tv_init(intel_sdvo, SDVO_OUTPUT_CVBS0))
+			return false;
+
+	if (flags & SDVO_OUTPUT_YPRPB0)
+		if (!intel_sdvo_tv_init(intel_sdvo, SDVO_OUTPUT_YPRPB0))
+			return false;
+
+	if (flags & SDVO_OUTPUT_RGB0)
+		if (!intel_sdvo_analog_init(intel_sdvo, 0))
+			return false;
+
+	if ((flags & SDVO_RGB_MASK) == SDVO_RGB_MASK)
+		if (!intel_sdvo_analog_init(intel_sdvo, 1))
+			return false;
+
+	if (flags & SDVO_OUTPUT_LVDS0)
+		if (!intel_sdvo_lvds_init(intel_sdvo, 0))
+			return false;
+
+	if ((flags & SDVO_LVDS_MASK) == SDVO_LVDS_MASK)
+		if (!intel_sdvo_lvds_init(intel_sdvo, 1))
+			return false;
+
+	if ((flags & SDVO_OUTPUT_MASK) == 0) {
+		unsigned char bytes[2];
+
+		intel_sdvo->controlled_output = 0;
+		memcpy(bytes, &intel_sdvo->caps.output_flags, 2);
+		DRM_DEBUG_KMS("%s: Unknown SDVO output type (0x%02x%02x)\n",
+			      SDVO_NAME(intel_sdvo),
+			      bytes[0], bytes[1]);
+		return false;
+	}
+	intel_sdvo->base.crtc_mask = (1 << 0) | (1 << 1) | (1 << 2);
+
+	return true;
+}
+
+static void intel_sdvo_output_cleanup(struct intel_sdvo *intel_sdvo)
+{
+	struct drm_device *dev = intel_sdvo->base.base.dev;
+	struct drm_connector *connector, *tmp;
+
+	list_for_each_entry_safe(connector, tmp,
+				 &dev->mode_config.connector_list, head) {
+		if (intel_attached_encoder(connector) == &intel_sdvo->base) {
+			drm_connector_unregister(connector);
+			intel_sdvo_destroy(connector);
+		}
+	}
+}
+
+static bool intel_sdvo_tv_create_property(struct intel_sdvo *intel_sdvo,
+					  struct intel_sdvo_connector *intel_sdvo_connector,
+					  int type)
+{
+	struct drm_device *dev = intel_sdvo->base.base.dev;
+	struct intel_sdvo_tv_format format;
+	uint32_t format_map, i;
+
+	if (!intel_sdvo_set_target_output(intel_sdvo, type))
+		return false;
+
+	BUILD_BUG_ON(sizeof(format) != 6);
+	if (!intel_sdvo_get_value(intel_sdvo,
+				  SDVO_CMD_GET_SUPPORTED_TV_FORMATS,
+				  &format, sizeof(format)))
+		return false;
+
+	memcpy(&format_map, &format, min(sizeof(format_map), sizeof(format)));
+
+	if (format_map == 0)
+		return false;
+
+	intel_sdvo_connector->format_supported_num = 0;
+	for (i = 0 ; i < TV_FORMAT_NUM; i++)
+		if (format_map & (1 << i))
+			intel_sdvo_connector->tv_format_supported[intel_sdvo_connector->format_supported_num++] = i;
+
+
+	intel_sdvo_connector->tv_format =
+			drm_property_create(dev, DRM_MODE_PROP_ENUM,
+					    "mode", intel_sdvo_connector->format_supported_num);
+	if (!intel_sdvo_connector->tv_format)
+		return false;
+
+	for (i = 0; i < intel_sdvo_connector->format_supported_num; i++)
+		drm_property_add_enum(
+				intel_sdvo_connector->tv_format, i,
+				i, tv_format_names[intel_sdvo_connector->tv_format_supported[i]]);
+
+	intel_sdvo->tv_format_index = intel_sdvo_connector->tv_format_supported[0];
+	drm_object_attach_property(&intel_sdvo_connector->base.base.base,
+				      intel_sdvo_connector->tv_format, 0);
+	return true;
+
+}
+
+#define ENHANCEMENT(name, NAME) do { \
+	if (enhancements.name) { \
+		if (!intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_MAX_##NAME, &data_value, 4) || \
+		    !intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_##NAME, &response, 2)) \
+			return false; \
+		intel_sdvo_connector->max_##name = data_value[0]; \
+		intel_sdvo_connector->cur_##name = response; \
+		intel_sdvo_connector->name = \
+			drm_property_create_range(dev, 0, #name, 0, data_value[0]); \
+		if (!intel_sdvo_connector->name) return false; \
+		drm_object_attach_property(&connector->base, \
+					      intel_sdvo_connector->name, \
+					      intel_sdvo_connector->cur_##name); \
+		DRM_DEBUG_KMS(#name ": max %d, default %d, current %d\n", \
+			      data_value[0], data_value[1], response); \
+	} \
+} while (0)
+
+static bool
+intel_sdvo_create_enhance_property_tv(struct intel_sdvo *intel_sdvo,
+				      struct intel_sdvo_connector *intel_sdvo_connector,
+				      struct intel_sdvo_enhancements_reply enhancements)
+{
+	struct drm_device *dev = intel_sdvo->base.base.dev;
+	struct drm_connector *connector = &intel_sdvo_connector->base.base;
+	uint16_t response, data_value[2];
+
+	/* when horizontal overscan is supported, Add the left/right  property */
+	if (enhancements.overscan_h) {
+		if (!intel_sdvo_get_value(intel_sdvo,
+					  SDVO_CMD_GET_MAX_OVERSCAN_H,
+					  &data_value, 4))
+			return false;
+
+		if (!intel_sdvo_get_value(intel_sdvo,
+					  SDVO_CMD_GET_OVERSCAN_H,
+					  &response, 2))
+			return false;
+
+		intel_sdvo_connector->max_hscan = data_value[0];
+		intel_sdvo_connector->left_margin = data_value[0] - response;
+		intel_sdvo_connector->right_margin = intel_sdvo_connector->left_margin;
+		intel_sdvo_connector->left =
+			drm_property_create_range(dev, 0, "left_margin", 0, data_value[0]);
+		if (!intel_sdvo_connector->left)
+			return false;
+
+		drm_object_attach_property(&connector->base,
+					      intel_sdvo_connector->left,
+					      intel_sdvo_connector->left_margin);
+
+		intel_sdvo_connector->right =
+			drm_property_create_range(dev, 0, "right_margin", 0, data_value[0]);
+		if (!intel_sdvo_connector->right)
+			return false;
+
+		drm_object_attach_property(&connector->base,
+					      intel_sdvo_connector->right,
+					      intel_sdvo_connector->right_margin);
+		DRM_DEBUG_KMS("h_overscan: max %d, "
+			      "default %d, current %d\n",
+			      data_value[0], data_value[1], response);
+	}
+
+	if (enhancements.overscan_v) {
+		if (!intel_sdvo_get_value(intel_sdvo,
+					  SDVO_CMD_GET_MAX_OVERSCAN_V,
+					  &data_value, 4))
+			return false;
+
+		if (!intel_sdvo_get_value(intel_sdvo,
+					  SDVO_CMD_GET_OVERSCAN_V,
+					  &response, 2))
+			return false;
+
+		intel_sdvo_connector->max_vscan = data_value[0];
+		intel_sdvo_connector->top_margin = data_value[0] - response;
+		intel_sdvo_connector->bottom_margin = intel_sdvo_connector->top_margin;
+		intel_sdvo_connector->top =
+			drm_property_create_range(dev, 0,
+					    "top_margin", 0, data_value[0]);
+		if (!intel_sdvo_connector->top)
+			return false;
+
+		drm_object_attach_property(&connector->base,
+					      intel_sdvo_connector->top,
+					      intel_sdvo_connector->top_margin);
+
+		intel_sdvo_connector->bottom =
+			drm_property_create_range(dev, 0,
+					    "bottom_margin", 0, data_value[0]);
+		if (!intel_sdvo_connector->bottom)
+			return false;
+
+		drm_object_attach_property(&connector->base,
+					      intel_sdvo_connector->bottom,
+					      intel_sdvo_connector->bottom_margin);
+		DRM_DEBUG_KMS("v_overscan: max %d, "
+			      "default %d, current %d\n",
+			      data_value[0], data_value[1], response);
+	}
+
+	ENHANCEMENT(hpos, HPOS);
+	ENHANCEMENT(vpos, VPOS);
+	ENHANCEMENT(saturation, SATURATION);
+	ENHANCEMENT(contrast, CONTRAST);
+	ENHANCEMENT(hue, HUE);
+	ENHANCEMENT(sharpness, SHARPNESS);
+	ENHANCEMENT(brightness, BRIGHTNESS);
+	ENHANCEMENT(flicker_filter, FLICKER_FILTER);
+	ENHANCEMENT(flicker_filter_adaptive, FLICKER_FILTER_ADAPTIVE);
+	ENHANCEMENT(flicker_filter_2d, FLICKER_FILTER_2D);
+	ENHANCEMENT(tv_chroma_filter, TV_CHROMA_FILTER);
+	ENHANCEMENT(tv_luma_filter, TV_LUMA_FILTER);
+
+	if (enhancements.dot_crawl) {
+		if (!intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_DOT_CRAWL, &response, 2))
+			return false;
+
+		intel_sdvo_connector->max_dot_crawl = 1;
+		intel_sdvo_connector->cur_dot_crawl = response & 0x1;
+		intel_sdvo_connector->dot_crawl =
+			drm_property_create_range(dev, 0, "dot_crawl", 0, 1);
+		if (!intel_sdvo_connector->dot_crawl)
+			return false;
+
+		drm_object_attach_property(&connector->base,
+					      intel_sdvo_connector->dot_crawl,
+					      intel_sdvo_connector->cur_dot_crawl);
+		DRM_DEBUG_KMS("dot crawl: current %d\n", response);
+	}
+
+	return true;
+}
+
+static bool
+intel_sdvo_create_enhance_property_lvds(struct intel_sdvo *intel_sdvo,
+					struct intel_sdvo_connector *intel_sdvo_connector,
+					struct intel_sdvo_enhancements_reply enhancements)
+{
+	struct drm_device *dev = intel_sdvo->base.base.dev;
+	struct drm_connector *connector = &intel_sdvo_connector->base.base;
+	uint16_t response, data_value[2];
+
+	ENHANCEMENT(brightness, BRIGHTNESS);
+
+	return true;
+}
+#undef ENHANCEMENT
+
+static bool intel_sdvo_create_enhance_property(struct intel_sdvo *intel_sdvo,
+					       struct intel_sdvo_connector *intel_sdvo_connector)
+{
+	union {
+		struct intel_sdvo_enhancements_reply reply;
+		uint16_t response;
+	} enhancements;
+
+	BUILD_BUG_ON(sizeof(enhancements) != 2);
+
+	enhancements.response = 0;
+	intel_sdvo_get_value(intel_sdvo,
+			     SDVO_CMD_GET_SUPPORTED_ENHANCEMENTS,
+			     &enhancements, sizeof(enhancements));
+	if (enhancements.response == 0) {
+		DRM_DEBUG_KMS("No enhancement is supported\n");
+		return true;
+	}
+
+	if (IS_TV(intel_sdvo_connector))
+		return intel_sdvo_create_enhance_property_tv(intel_sdvo, intel_sdvo_connector, enhancements.reply);
+	else if (IS_LVDS(intel_sdvo_connector))
+		return intel_sdvo_create_enhance_property_lvds(intel_sdvo, intel_sdvo_connector, enhancements.reply);
+	else
+		return true;
+}
+
+static int intel_sdvo_ddc_proxy_xfer(struct i2c_adapter *adapter,
+				     struct i2c_msg *msgs,
+				     int num)
+{
+	struct intel_sdvo *sdvo = adapter->algo_data;
+
+	if (!intel_sdvo_set_control_bus_switch(sdvo, sdvo->ddc_bus))
+		return -EIO;
+
+	return sdvo->i2c->algo->master_xfer(sdvo->i2c, msgs, num);
+}
+
+static u32 intel_sdvo_ddc_proxy_func(struct i2c_adapter *adapter)
+{
+	struct intel_sdvo *sdvo = adapter->algo_data;
+	return sdvo->i2c->algo->functionality(sdvo->i2c);
+}
+
+static const struct i2c_algorithm intel_sdvo_ddc_proxy = {
+	.master_xfer	= intel_sdvo_ddc_proxy_xfer,
+	.functionality	= intel_sdvo_ddc_proxy_func
+};
+
+static bool
+intel_sdvo_init_ddc_proxy(struct intel_sdvo *sdvo,
+			  struct drm_device *dev)
+{
+	sdvo->ddc.owner = THIS_MODULE;
+	sdvo->ddc.class = I2C_CLASS_DDC;
+	snprintf(sdvo->ddc.name, I2C_NAME_SIZE, "SDVO DDC proxy");
+	sdvo->ddc.dev.parent = &dev->pdev->dev;
+	sdvo->ddc.algo_data = sdvo;
+	sdvo->ddc.algo = &intel_sdvo_ddc_proxy;
+
+	return i2c_add_adapter(&sdvo->ddc) == 0;
+}
+
+static void assert_sdvo_port_valid(const struct drm_i915_private *dev_priv,
+				   enum port port)
+{
+	if (HAS_PCH_SPLIT(dev_priv))
+		WARN_ON(port != PORT_B);
+	else
+		WARN_ON(port != PORT_B && port != PORT_C);
+}
+
+bool intel_sdvo_init(struct drm_device *dev,
+		     i915_reg_t sdvo_reg, enum port port)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_encoder *intel_encoder;
+	struct intel_sdvo *intel_sdvo;
+	int i;
+
+	assert_sdvo_port_valid(dev_priv, port);
+
+	intel_sdvo = kzalloc(sizeof(*intel_sdvo), GFP_KERNEL);
+	if (!intel_sdvo)
+		return false;
+
+	intel_sdvo->sdvo_reg = sdvo_reg;
+	intel_sdvo->port = port;
+	intel_sdvo->slave_addr = intel_sdvo_get_slave_addr(dev, intel_sdvo) >> 1;
+	intel_sdvo_select_i2c_bus(dev_priv, intel_sdvo);
+	if (!intel_sdvo_init_ddc_proxy(intel_sdvo, dev))
+		goto err_i2c_bus;
+
+	/* encoder type will be decided later */
+	intel_encoder = &intel_sdvo->base;
+	intel_encoder->type = INTEL_OUTPUT_SDVO;
+	drm_encoder_init(dev, &intel_encoder->base, &intel_sdvo_enc_funcs, 0);
+
+	/* Read the regs to test if we can talk to the device */
+	for (i = 0; i < 0x40; i++) {
+		u8 byte;
+
+		if (!intel_sdvo_read_byte(intel_sdvo, i, &byte)) {
+			DRM_DEBUG_KMS("No SDVO device found on %s\n",
+				      SDVO_NAME(intel_sdvo));
+			goto err;
+		}
+	}
+
+	intel_encoder->compute_config = intel_sdvo_compute_config;
+	if (HAS_PCH_SPLIT(dev)) {
+		intel_encoder->disable = pch_disable_sdvo;
+		intel_encoder->post_disable = pch_post_disable_sdvo;
+	} else {
+		intel_encoder->disable = intel_disable_sdvo;
+	}
+	intel_encoder->pre_enable = intel_sdvo_pre_enable;
+	intel_encoder->enable = intel_enable_sdvo;
+	intel_encoder->get_hw_state = intel_sdvo_get_hw_state;
+	intel_encoder->get_config = intel_sdvo_get_config;
+
+	/* In default case sdvo lvds is false */
+	if (!intel_sdvo_get_capabilities(intel_sdvo, &intel_sdvo->caps))
+		goto err;
+
+	if (intel_sdvo_output_setup(intel_sdvo,
+				    intel_sdvo->caps.output_flags) != true) {
+		DRM_DEBUG_KMS("SDVO output failed to setup on %s\n",
+			      SDVO_NAME(intel_sdvo));
+		/* Output_setup can leave behind connectors! */
+		goto err_output;
+	}
+
+	/* Only enable the hotplug irq if we need it, to work around noisy
+	 * hotplug lines.
+	 */
+	if (intel_sdvo->hotplug_active) {
+		if (intel_sdvo->port == PORT_B)
+			intel_encoder->hpd_pin = HPD_SDVO_B;
+		else
+			intel_encoder->hpd_pin = HPD_SDVO_C;
+	}
+
+	/*
+	 * Cloning SDVO with anything is often impossible, since the SDVO
+	 * encoder can request a special input timing mode. And even if that's
+	 * not the case we have evidence that cloning a plain unscaled mode with
+	 * VGA doesn't really work. Furthermore the cloning flags are way too
+	 * simplistic anyway to express such constraints, so just give up on
+	 * cloning for SDVO encoders.
+	 */
+	intel_sdvo->base.cloneable = 0;
+
+	intel_sdvo_select_ddc_bus(dev_priv, intel_sdvo);
+
+	/* Set the input timing to the screen. Assume always input 0. */
+	if (!intel_sdvo_set_target_input(intel_sdvo))
+		goto err_output;
+
+	if (!intel_sdvo_get_input_pixel_clock_range(intel_sdvo,
+						    &intel_sdvo->pixel_clock_min,
+						    &intel_sdvo->pixel_clock_max))
+		goto err_output;
+
+	DRM_DEBUG_KMS("%s device VID/DID: %02X:%02X.%02X, "
+			"clock range %dMHz - %dMHz, "
+			"input 1: %c, input 2: %c, "
+			"output 1: %c, output 2: %c\n",
+			SDVO_NAME(intel_sdvo),
+			intel_sdvo->caps.vendor_id, intel_sdvo->caps.device_id,
+			intel_sdvo->caps.device_rev_id,
+			intel_sdvo->pixel_clock_min / 1000,
+			intel_sdvo->pixel_clock_max / 1000,
+			(intel_sdvo->caps.sdvo_inputs_mask & 0x1) ? 'Y' : 'N',
+			(intel_sdvo->caps.sdvo_inputs_mask & 0x2) ? 'Y' : 'N',
+			/* check currently supported outputs */
+			intel_sdvo->caps.output_flags &
+			(SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_RGB0) ? 'Y' : 'N',
+			intel_sdvo->caps.output_flags &
+			(SDVO_OUTPUT_TMDS1 | SDVO_OUTPUT_RGB1) ? 'Y' : 'N');
+	return true;
+
+err_output:
+	intel_sdvo_output_cleanup(intel_sdvo);
+
+err:
+	drm_encoder_cleanup(&intel_encoder->base);
+	i2c_del_adapter(&intel_sdvo->ddc);
+err_i2c_bus:
+	intel_sdvo_unselect_i2c_bus(intel_sdvo);
+	kfree(intel_sdvo);
+
+	return false;
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/i915/intel_sdvo_regs.h
@@ -0,0 +1,730 @@
+/*
+ * Copyright © 2006-2007 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *	Eric Anholt <eric@anholt.net>
+ */
+
+/*
+ * SDVO command definitions and structures.
+ */
+
+#define SDVO_OUTPUT_FIRST   (0)
+#define SDVO_OUTPUT_TMDS0   (1 << 0)
+#define SDVO_OUTPUT_RGB0    (1 << 1)
+#define SDVO_OUTPUT_CVBS0   (1 << 2)
+#define SDVO_OUTPUT_SVID0   (1 << 3)
+#define SDVO_OUTPUT_YPRPB0  (1 << 4)
+#define SDVO_OUTPUT_SCART0  (1 << 5)
+#define SDVO_OUTPUT_LVDS0   (1 << 6)
+#define SDVO_OUTPUT_TMDS1   (1 << 8)
+#define SDVO_OUTPUT_RGB1    (1 << 9)
+#define SDVO_OUTPUT_CVBS1   (1 << 10)
+#define SDVO_OUTPUT_SVID1   (1 << 11)
+#define SDVO_OUTPUT_YPRPB1  (1 << 12)
+#define SDVO_OUTPUT_SCART1  (1 << 13)
+#define SDVO_OUTPUT_LVDS1   (1 << 14)
+#define SDVO_OUTPUT_LAST    (14)
+
+struct intel_sdvo_caps {
+	u8 vendor_id;
+	u8 device_id;
+	u8 device_rev_id;
+	u8 sdvo_version_major;
+	u8 sdvo_version_minor;
+	unsigned int sdvo_inputs_mask:2;
+	unsigned int smooth_scaling:1;
+	unsigned int sharp_scaling:1;
+	unsigned int up_scaling:1;
+	unsigned int down_scaling:1;
+	unsigned int stall_support:1;
+	unsigned int pad:1;
+	u16 output_flags;
+} __packed;
+
+/* Note: SDVO detailed timing flags match EDID misc flags. */
+#define DTD_FLAG_HSYNC_POSITIVE (1 << 1)
+#define DTD_FLAG_VSYNC_POSITIVE (1 << 2)
+#define DTD_FLAG_INTERLACE	(1 << 7)
+
+/* This matches the EDID DTD structure, more or less */
+struct intel_sdvo_dtd {
+	struct {
+		u16 clock;	/* pixel clock, in 10kHz units */
+		u8 h_active;	/* lower 8 bits (pixels) */
+		u8 h_blank;	/* lower 8 bits (pixels) */
+		u8 h_high;	/* upper 4 bits each h_active, h_blank */
+		u8 v_active;	/* lower 8 bits (lines) */
+		u8 v_blank;	/* lower 8 bits (lines) */
+		u8 v_high;	/* upper 4 bits each v_active, v_blank */
+	} part1;
+
+	struct {
+		u8 h_sync_off;	/* lower 8 bits, from hblank start */
+		u8 h_sync_width;	/* lower 8 bits (pixels) */
+		/* lower 4 bits each vsync offset, vsync width */
+		u8 v_sync_off_width;
+		/*
+		* 2 high bits of hsync offset, 2 high bits of hsync width,
+		* bits 4-5 of vsync offset, and 2 high bits of vsync width.
+		*/
+		u8 sync_off_width_high;
+		u8 dtd_flags;
+		u8 sdvo_flags;
+		/* bits 6-7 of vsync offset at bits 6-7 */
+		u8 v_sync_off_high;
+		u8 reserved;
+	} part2;
+} __packed;
+
+struct intel_sdvo_pixel_clock_range {
+	u16 min;	/* pixel clock, in 10kHz units */
+	u16 max;	/* pixel clock, in 10kHz units */
+} __packed;
+
+struct intel_sdvo_preferred_input_timing_args {
+	u16 clock;
+	u16 width;
+	u16 height;
+	u8	interlace:1;
+	u8	scaled:1;
+	u8	pad:6;
+} __packed;
+
+/* I2C registers for SDVO */
+#define SDVO_I2C_ARG_0				0x07
+#define SDVO_I2C_ARG_1				0x06
+#define SDVO_I2C_ARG_2				0x05
+#define SDVO_I2C_ARG_3				0x04
+#define SDVO_I2C_ARG_4				0x03
+#define SDVO_I2C_ARG_5				0x02
+#define SDVO_I2C_ARG_6				0x01
+#define SDVO_I2C_ARG_7				0x00
+#define SDVO_I2C_OPCODE				0x08
+#define SDVO_I2C_CMD_STATUS			0x09
+#define SDVO_I2C_RETURN_0			0x0a
+#define SDVO_I2C_RETURN_1			0x0b
+#define SDVO_I2C_RETURN_2			0x0c
+#define SDVO_I2C_RETURN_3			0x0d
+#define SDVO_I2C_RETURN_4			0x0e
+#define SDVO_I2C_RETURN_5			0x0f
+#define SDVO_I2C_RETURN_6			0x10
+#define SDVO_I2C_RETURN_7			0x11
+#define SDVO_I2C_VENDOR_BEGIN			0x20
+
+/* Status results */
+#define SDVO_CMD_STATUS_POWER_ON		0x0
+#define SDVO_CMD_STATUS_SUCCESS			0x1
+#define SDVO_CMD_STATUS_NOTSUPP			0x2
+#define SDVO_CMD_STATUS_INVALID_ARG		0x3
+#define SDVO_CMD_STATUS_PENDING			0x4
+#define SDVO_CMD_STATUS_TARGET_NOT_SPECIFIED	0x5
+#define SDVO_CMD_STATUS_SCALING_NOT_SUPP	0x6
+
+/* SDVO commands, argument/result registers */
+
+#define SDVO_CMD_RESET					0x01
+
+/* Returns a struct intel_sdvo_caps */
+#define SDVO_CMD_GET_DEVICE_CAPS			0x02
+
+#define SDVO_CMD_GET_FIRMWARE_REV			0x86
+# define SDVO_DEVICE_FIRMWARE_MINOR			SDVO_I2C_RETURN_0
+# define SDVO_DEVICE_FIRMWARE_MAJOR			SDVO_I2C_RETURN_1
+# define SDVO_DEVICE_FIRMWARE_PATCH			SDVO_I2C_RETURN_2
+
+/*
+ * Reports which inputs are trained (managed to sync).
+ *
+ * Devices must have trained within 2 vsyncs of a mode change.
+ */
+#define SDVO_CMD_GET_TRAINED_INPUTS			0x03
+struct intel_sdvo_get_trained_inputs_response {
+	unsigned int input0_trained:1;
+	unsigned int input1_trained:1;
+	unsigned int pad:6;
+} __packed;
+
+/* Returns a struct intel_sdvo_output_flags of active outputs. */
+#define SDVO_CMD_GET_ACTIVE_OUTPUTS			0x04
+
+/*
+ * Sets the current set of active outputs.
+ *
+ * Takes a struct intel_sdvo_output_flags.  Must be preceded by a SET_IN_OUT_MAP
+ * on multi-output devices.
+ */
+#define SDVO_CMD_SET_ACTIVE_OUTPUTS			0x05
+
+/*
+ * Returns the current mapping of SDVO inputs to outputs on the device.
+ *
+ * Returns two struct intel_sdvo_output_flags structures.
+ */
+#define SDVO_CMD_GET_IN_OUT_MAP				0x06
+struct intel_sdvo_in_out_map {
+	u16 in0, in1;
+};
+
+/*
+ * Sets the current mapping of SDVO inputs to outputs on the device.
+ *
+ * Takes two struct i380_sdvo_output_flags structures.
+ */
+#define SDVO_CMD_SET_IN_OUT_MAP				0x07
+
+/*
+ * Returns a struct intel_sdvo_output_flags of attached displays.
+ */
+#define SDVO_CMD_GET_ATTACHED_DISPLAYS			0x0b
+
+/*
+ * Returns a struct intel_sdvo_ouptut_flags of displays supporting hot plugging.
+ */
+#define SDVO_CMD_GET_HOT_PLUG_SUPPORT			0x0c
+
+/*
+ * Takes a struct intel_sdvo_output_flags.
+ */
+#define SDVO_CMD_SET_ACTIVE_HOT_PLUG			0x0d
+
+/*
+ * Returns a struct intel_sdvo_output_flags of displays with hot plug
+ * interrupts enabled.
+ */
+#define SDVO_CMD_GET_ACTIVE_HOT_PLUG			0x0e
+
+#define SDVO_CMD_GET_INTERRUPT_EVENT_SOURCE		0x0f
+struct intel_sdvo_get_interrupt_event_source_response {
+	u16 interrupt_status;
+	unsigned int ambient_light_interrupt:1;
+	unsigned int hdmi_audio_encrypt_change:1;
+	unsigned int pad:6;
+} __packed;
+
+/*
+ * Selects which input is affected by future input commands.
+ *
+ * Commands affected include SET_INPUT_TIMINGS_PART[12],
+ * GET_INPUT_TIMINGS_PART[12], GET_PREFERRED_INPUT_TIMINGS_PART[12],
+ * GET_INPUT_PIXEL_CLOCK_RANGE, and CREATE_PREFERRED_INPUT_TIMINGS.
+ */
+#define SDVO_CMD_SET_TARGET_INPUT			0x10
+struct intel_sdvo_set_target_input_args {
+	unsigned int target_1:1;
+	unsigned int pad:7;
+} __packed;
+
+/*
+ * Takes a struct intel_sdvo_output_flags of which outputs are targeted by
+ * future output commands.
+ *
+ * Affected commands inclue SET_OUTPUT_TIMINGS_PART[12],
+ * GET_OUTPUT_TIMINGS_PART[12], and GET_OUTPUT_PIXEL_CLOCK_RANGE.
+ */
+#define SDVO_CMD_SET_TARGET_OUTPUT			0x11
+
+#define SDVO_CMD_GET_INPUT_TIMINGS_PART1		0x12
+#define SDVO_CMD_GET_INPUT_TIMINGS_PART2		0x13
+#define SDVO_CMD_SET_INPUT_TIMINGS_PART1		0x14
+#define SDVO_CMD_SET_INPUT_TIMINGS_PART2		0x15
+#define SDVO_CMD_SET_OUTPUT_TIMINGS_PART1		0x16
+#define SDVO_CMD_SET_OUTPUT_TIMINGS_PART2		0x17
+#define SDVO_CMD_GET_OUTPUT_TIMINGS_PART1		0x18
+#define SDVO_CMD_GET_OUTPUT_TIMINGS_PART2		0x19
+/* Part 1 */
+# define SDVO_DTD_CLOCK_LOW				SDVO_I2C_ARG_0
+# define SDVO_DTD_CLOCK_HIGH				SDVO_I2C_ARG_1
+# define SDVO_DTD_H_ACTIVE				SDVO_I2C_ARG_2
+# define SDVO_DTD_H_BLANK				SDVO_I2C_ARG_3
+# define SDVO_DTD_H_HIGH				SDVO_I2C_ARG_4
+# define SDVO_DTD_V_ACTIVE				SDVO_I2C_ARG_5
+# define SDVO_DTD_V_BLANK				SDVO_I2C_ARG_6
+# define SDVO_DTD_V_HIGH				SDVO_I2C_ARG_7
+/* Part 2 */
+# define SDVO_DTD_HSYNC_OFF				SDVO_I2C_ARG_0
+# define SDVO_DTD_HSYNC_WIDTH				SDVO_I2C_ARG_1
+# define SDVO_DTD_VSYNC_OFF_WIDTH			SDVO_I2C_ARG_2
+# define SDVO_DTD_SYNC_OFF_WIDTH_HIGH			SDVO_I2C_ARG_3
+# define SDVO_DTD_DTD_FLAGS				SDVO_I2C_ARG_4
+# define SDVO_DTD_DTD_FLAG_INTERLACED				(1 << 7)
+# define SDVO_DTD_DTD_FLAG_STEREO_MASK				(3 << 5)
+# define SDVO_DTD_DTD_FLAG_INPUT_MASK				(3 << 3)
+# define SDVO_DTD_DTD_FLAG_SYNC_MASK				(3 << 1)
+# define SDVO_DTD_SDVO_FLAS				SDVO_I2C_ARG_5
+# define SDVO_DTD_SDVO_FLAG_STALL				(1 << 7)
+# define SDVO_DTD_SDVO_FLAG_CENTERED				(0 << 6)
+# define SDVO_DTD_SDVO_FLAG_UPPER_LEFT				(1 << 6)
+# define SDVO_DTD_SDVO_FLAG_SCALING_MASK			(3 << 4)
+# define SDVO_DTD_SDVO_FLAG_SCALING_NONE			(0 << 4)
+# define SDVO_DTD_SDVO_FLAG_SCALING_SHARP			(1 << 4)
+# define SDVO_DTD_SDVO_FLAG_SCALING_SMOOTH			(2 << 4)
+# define SDVO_DTD_VSYNC_OFF_HIGH			SDVO_I2C_ARG_6
+
+/*
+ * Generates a DTD based on the given width, height, and flags.
+ *
+ * This will be supported by any device supporting scaling or interlaced
+ * modes.
+ */
+#define SDVO_CMD_CREATE_PREFERRED_INPUT_TIMING		0x1a
+# define SDVO_PREFERRED_INPUT_TIMING_CLOCK_LOW		SDVO_I2C_ARG_0
+# define SDVO_PREFERRED_INPUT_TIMING_CLOCK_HIGH		SDVO_I2C_ARG_1
+# define SDVO_PREFERRED_INPUT_TIMING_WIDTH_LOW		SDVO_I2C_ARG_2
+# define SDVO_PREFERRED_INPUT_TIMING_WIDTH_HIGH		SDVO_I2C_ARG_3
+# define SDVO_PREFERRED_INPUT_TIMING_HEIGHT_LOW		SDVO_I2C_ARG_4
+# define SDVO_PREFERRED_INPUT_TIMING_HEIGHT_HIGH	SDVO_I2C_ARG_5
+# define SDVO_PREFERRED_INPUT_TIMING_FLAGS		SDVO_I2C_ARG_6
+# define SDVO_PREFERRED_INPUT_TIMING_FLAGS_INTERLACED		(1 << 0)
+# define SDVO_PREFERRED_INPUT_TIMING_FLAGS_SCALED		(1 << 1)
+
+#define SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART1	0x1b
+#define SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART2	0x1c
+
+/* Returns a struct intel_sdvo_pixel_clock_range */
+#define SDVO_CMD_GET_INPUT_PIXEL_CLOCK_RANGE		0x1d
+/* Returns a struct intel_sdvo_pixel_clock_range */
+#define SDVO_CMD_GET_OUTPUT_PIXEL_CLOCK_RANGE		0x1e
+
+/* Returns a byte bitfield containing SDVO_CLOCK_RATE_MULT_* flags */
+#define SDVO_CMD_GET_SUPPORTED_CLOCK_RATE_MULTS		0x1f
+
+/* Returns a byte containing a SDVO_CLOCK_RATE_MULT_* flag */
+#define SDVO_CMD_GET_CLOCK_RATE_MULT			0x20
+/* Takes a byte containing a SDVO_CLOCK_RATE_MULT_* flag */
+#define SDVO_CMD_SET_CLOCK_RATE_MULT			0x21
+# define SDVO_CLOCK_RATE_MULT_1X				(1 << 0)
+# define SDVO_CLOCK_RATE_MULT_2X				(1 << 1)
+# define SDVO_CLOCK_RATE_MULT_4X				(1 << 3)
+
+#define SDVO_CMD_GET_SUPPORTED_TV_FORMATS		0x27
+/* 6 bytes of bit flags for TV formats shared by all TV format functions */
+struct intel_sdvo_tv_format {
+	unsigned int ntsc_m:1;
+	unsigned int ntsc_j:1;
+	unsigned int ntsc_443:1;
+	unsigned int pal_b:1;
+	unsigned int pal_d:1;
+	unsigned int pal_g:1;
+	unsigned int pal_h:1;
+	unsigned int pal_i:1;
+
+	unsigned int pal_m:1;
+	unsigned int pal_n:1;
+	unsigned int pal_nc:1;
+	unsigned int pal_60:1;
+	unsigned int secam_b:1;
+	unsigned int secam_d:1;
+	unsigned int secam_g:1;
+	unsigned int secam_k:1;
+
+	unsigned int secam_k1:1;
+	unsigned int secam_l:1;
+	unsigned int secam_60:1;
+	unsigned int hdtv_std_smpte_240m_1080i_59:1;
+	unsigned int hdtv_std_smpte_240m_1080i_60:1;
+	unsigned int hdtv_std_smpte_260m_1080i_59:1;
+	unsigned int hdtv_std_smpte_260m_1080i_60:1;
+	unsigned int hdtv_std_smpte_274m_1080i_50:1;
+
+	unsigned int hdtv_std_smpte_274m_1080i_59:1;
+	unsigned int hdtv_std_smpte_274m_1080i_60:1;
+	unsigned int hdtv_std_smpte_274m_1080p_23:1;
+	unsigned int hdtv_std_smpte_274m_1080p_24:1;
+	unsigned int hdtv_std_smpte_274m_1080p_25:1;
+	unsigned int hdtv_std_smpte_274m_1080p_29:1;
+	unsigned int hdtv_std_smpte_274m_1080p_30:1;
+	unsigned int hdtv_std_smpte_274m_1080p_50:1;
+
+	unsigned int hdtv_std_smpte_274m_1080p_59:1;
+	unsigned int hdtv_std_smpte_274m_1080p_60:1;
+	unsigned int hdtv_std_smpte_295m_1080i_50:1;
+	unsigned int hdtv_std_smpte_295m_1080p_50:1;
+	unsigned int hdtv_std_smpte_296m_720p_59:1;
+	unsigned int hdtv_std_smpte_296m_720p_60:1;
+	unsigned int hdtv_std_smpte_296m_720p_50:1;
+	unsigned int hdtv_std_smpte_293m_480p_59:1;
+
+	unsigned int hdtv_std_smpte_170m_480i_59:1;
+	unsigned int hdtv_std_iturbt601_576i_50:1;
+	unsigned int hdtv_std_iturbt601_576p_50:1;
+	unsigned int hdtv_std_eia_7702a_480i_60:1;
+	unsigned int hdtv_std_eia_7702a_480p_60:1;
+	unsigned int pad:3;
+} __packed;
+
+#define SDVO_CMD_GET_TV_FORMAT				0x28
+
+#define SDVO_CMD_SET_TV_FORMAT				0x29
+
+/* Returns the resolutiosn that can be used with the given TV format */
+#define SDVO_CMD_GET_SDTV_RESOLUTION_SUPPORT		0x83
+struct intel_sdvo_sdtv_resolution_request {
+	unsigned int ntsc_m:1;
+	unsigned int ntsc_j:1;
+	unsigned int ntsc_443:1;
+	unsigned int pal_b:1;
+	unsigned int pal_d:1;
+	unsigned int pal_g:1;
+	unsigned int pal_h:1;
+	unsigned int pal_i:1;
+
+	unsigned int pal_m:1;
+	unsigned int pal_n:1;
+	unsigned int pal_nc:1;
+	unsigned int pal_60:1;
+	unsigned int secam_b:1;
+	unsigned int secam_d:1;
+	unsigned int secam_g:1;
+	unsigned int secam_k:1;
+
+	unsigned int secam_k1:1;
+	unsigned int secam_l:1;
+	unsigned int secam_60:1;
+	unsigned int pad:5;
+} __packed;
+
+struct intel_sdvo_sdtv_resolution_reply {
+	unsigned int res_320x200:1;
+	unsigned int res_320x240:1;
+	unsigned int res_400x300:1;
+	unsigned int res_640x350:1;
+	unsigned int res_640x400:1;
+	unsigned int res_640x480:1;
+	unsigned int res_704x480:1;
+	unsigned int res_704x576:1;
+
+	unsigned int res_720x350:1;
+	unsigned int res_720x400:1;
+	unsigned int res_720x480:1;
+	unsigned int res_720x540:1;
+	unsigned int res_720x576:1;
+	unsigned int res_768x576:1;
+	unsigned int res_800x600:1;
+	unsigned int res_832x624:1;
+
+	unsigned int res_920x766:1;
+	unsigned int res_1024x768:1;
+	unsigned int res_1280x1024:1;
+	unsigned int pad:5;
+} __packed;
+
+/* Get supported resolution with squire pixel aspect ratio that can be
+   scaled for the requested HDTV format */
+#define SDVO_CMD_GET_SCALED_HDTV_RESOLUTION_SUPPORT		0x85
+
+struct intel_sdvo_hdtv_resolution_request {
+	unsigned int hdtv_std_smpte_240m_1080i_59:1;
+	unsigned int hdtv_std_smpte_240m_1080i_60:1;
+	unsigned int hdtv_std_smpte_260m_1080i_59:1;
+	unsigned int hdtv_std_smpte_260m_1080i_60:1;
+	unsigned int hdtv_std_smpte_274m_1080i_50:1;
+	unsigned int hdtv_std_smpte_274m_1080i_59:1;
+	unsigned int hdtv_std_smpte_274m_1080i_60:1;
+	unsigned int hdtv_std_smpte_274m_1080p_23:1;
+
+	unsigned int hdtv_std_smpte_274m_1080p_24:1;
+	unsigned int hdtv_std_smpte_274m_1080p_25:1;
+	unsigned int hdtv_std_smpte_274m_1080p_29:1;
+	unsigned int hdtv_std_smpte_274m_1080p_30:1;
+	unsigned int hdtv_std_smpte_274m_1080p_50:1;
+	unsigned int hdtv_std_smpte_274m_1080p_59:1;
+	unsigned int hdtv_std_smpte_274m_1080p_60:1;
+	unsigned int hdtv_std_smpte_295m_1080i_50:1;
+
+	unsigned int hdtv_std_smpte_295m_1080p_50:1;
+	unsigned int hdtv_std_smpte_296m_720p_59:1;
+	unsigned int hdtv_std_smpte_296m_720p_60:1;
+	unsigned int hdtv_std_smpte_296m_720p_50:1;
+	unsigned int hdtv_std_smpte_293m_480p_59:1;
+	unsigned int hdtv_std_smpte_170m_480i_59:1;
+	unsigned int hdtv_std_iturbt601_576i_50:1;
+	unsigned int hdtv_std_iturbt601_576p_50:1;
+
+	unsigned int hdtv_std_eia_7702a_480i_60:1;
+	unsigned int hdtv_std_eia_7702a_480p_60:1;
+	unsigned int pad:6;
+} __packed;
+
+struct intel_sdvo_hdtv_resolution_reply {
+	unsigned int res_640x480:1;
+	unsigned int res_800x600:1;
+	unsigned int res_1024x768:1;
+	unsigned int res_1280x960:1;
+	unsigned int res_1400x1050:1;
+	unsigned int res_1600x1200:1;
+	unsigned int res_1920x1440:1;
+	unsigned int res_2048x1536:1;
+
+	unsigned int res_2560x1920:1;
+	unsigned int res_3200x2400:1;
+	unsigned int res_3840x2880:1;
+	unsigned int pad1:5;
+
+	unsigned int res_848x480:1;
+	unsigned int res_1064x600:1;
+	unsigned int res_1280x720:1;
+	unsigned int res_1360x768:1;
+	unsigned int res_1704x960:1;
+	unsigned int res_1864x1050:1;
+	unsigned int res_1920x1080:1;
+	unsigned int res_2128x1200:1;
+
+	unsigned int res_2560x1400:1;
+	unsigned int res_2728x1536:1;
+	unsigned int res_3408x1920:1;
+	unsigned int res_4264x2400:1;
+	unsigned int res_5120x2880:1;
+	unsigned int pad2:3;
+
+	unsigned int res_768x480:1;
+	unsigned int res_960x600:1;
+	unsigned int res_1152x720:1;
+	unsigned int res_1124x768:1;
+	unsigned int res_1536x960:1;
+	unsigned int res_1680x1050:1;
+	unsigned int res_1728x1080:1;
+	unsigned int res_1920x1200:1;
+
+	unsigned int res_2304x1440:1;
+	unsigned int res_2456x1536:1;
+	unsigned int res_3072x1920:1;
+	unsigned int res_3840x2400:1;
+	unsigned int res_4608x2880:1;
+	unsigned int pad3:3;
+
+	unsigned int res_1280x1024:1;
+	unsigned int pad4:7;
+
+	unsigned int res_1280x768:1;
+	unsigned int pad5:7;
+} __packed;
+
+/* Get supported power state returns info for encoder and monitor, rely on
+   last SetTargetInput and SetTargetOutput calls */
+#define SDVO_CMD_GET_SUPPORTED_POWER_STATES		0x2a
+/* Get power state returns info for encoder and monitor, rely on last
+   SetTargetInput and SetTargetOutput calls */
+#define SDVO_CMD_GET_POWER_STATE			0x2b
+#define SDVO_CMD_GET_ENCODER_POWER_STATE		0x2b
+#define SDVO_CMD_SET_ENCODER_POWER_STATE		0x2c
+# define SDVO_ENCODER_STATE_ON					(1 << 0)
+# define SDVO_ENCODER_STATE_STANDBY				(1 << 1)
+# define SDVO_ENCODER_STATE_SUSPEND				(1 << 2)
+# define SDVO_ENCODER_STATE_OFF					(1 << 3)
+# define SDVO_MONITOR_STATE_ON					(1 << 4)
+# define SDVO_MONITOR_STATE_STANDBY				(1 << 5)
+# define SDVO_MONITOR_STATE_SUSPEND				(1 << 6)
+# define SDVO_MONITOR_STATE_OFF					(1 << 7)
+
+#define SDVO_CMD_GET_MAX_PANEL_POWER_SEQUENCING		0x2d
+#define SDVO_CMD_GET_PANEL_POWER_SEQUENCING		0x2e
+#define SDVO_CMD_SET_PANEL_POWER_SEQUENCING		0x2f
+/*
+ * The panel power sequencing parameters are in units of milliseconds.
+ * The high fields are bits 8:9 of the 10-bit values.
+ */
+struct sdvo_panel_power_sequencing {
+	u8 t0;
+	u8 t1;
+	u8 t2;
+	u8 t3;
+	u8 t4;
+
+	unsigned int t0_high:2;
+	unsigned int t1_high:2;
+	unsigned int t2_high:2;
+	unsigned int t3_high:2;
+
+	unsigned int t4_high:2;
+	unsigned int pad:6;
+} __packed;
+
+#define SDVO_CMD_GET_MAX_BACKLIGHT_LEVEL		0x30
+struct sdvo_max_backlight_reply {
+	u8 max_value;
+	u8 default_value;
+} __packed;
+
+#define SDVO_CMD_GET_BACKLIGHT_LEVEL			0x31
+#define SDVO_CMD_SET_BACKLIGHT_LEVEL			0x32
+
+#define SDVO_CMD_GET_AMBIENT_LIGHT			0x33
+struct sdvo_get_ambient_light_reply {
+	u16 trip_low;
+	u16 trip_high;
+	u16 value;
+} __packed;
+#define SDVO_CMD_SET_AMBIENT_LIGHT			0x34
+struct sdvo_set_ambient_light_reply {
+	u16 trip_low;
+	u16 trip_high;
+	unsigned int enable:1;
+	unsigned int pad:7;
+} __packed;
+
+/* Set display power state */
+#define SDVO_CMD_SET_DISPLAY_POWER_STATE		0x7d
+# define SDVO_DISPLAY_STATE_ON				(1 << 0)
+# define SDVO_DISPLAY_STATE_STANDBY			(1 << 1)
+# define SDVO_DISPLAY_STATE_SUSPEND			(1 << 2)
+# define SDVO_DISPLAY_STATE_OFF				(1 << 3)
+
+#define SDVO_CMD_GET_SUPPORTED_ENHANCEMENTS		0x84
+struct intel_sdvo_enhancements_reply {
+	unsigned int flicker_filter:1;
+	unsigned int flicker_filter_adaptive:1;
+	unsigned int flicker_filter_2d:1;
+	unsigned int saturation:1;
+	unsigned int hue:1;
+	unsigned int brightness:1;
+	unsigned int contrast:1;
+	unsigned int overscan_h:1;
+
+	unsigned int overscan_v:1;
+	unsigned int hpos:1;
+	unsigned int vpos:1;
+	unsigned int sharpness:1;
+	unsigned int dot_crawl:1;
+	unsigned int dither:1;
+	unsigned int tv_chroma_filter:1;
+	unsigned int tv_luma_filter:1;
+} __packed;
+
+/* Picture enhancement limits below are dependent on the current TV format,
+ * and thus need to be queried and set after it.
+ */
+#define SDVO_CMD_GET_MAX_FLICKER_FILTER			0x4d
+#define SDVO_CMD_GET_MAX_FLICKER_FILTER_ADAPTIVE	0x7b
+#define SDVO_CMD_GET_MAX_FLICKER_FILTER_2D		0x52
+#define SDVO_CMD_GET_MAX_SATURATION			0x55
+#define SDVO_CMD_GET_MAX_HUE				0x58
+#define SDVO_CMD_GET_MAX_BRIGHTNESS			0x5b
+#define SDVO_CMD_GET_MAX_CONTRAST			0x5e
+#define SDVO_CMD_GET_MAX_OVERSCAN_H			0x61
+#define SDVO_CMD_GET_MAX_OVERSCAN_V			0x64
+#define SDVO_CMD_GET_MAX_HPOS				0x67
+#define SDVO_CMD_GET_MAX_VPOS				0x6a
+#define SDVO_CMD_GET_MAX_SHARPNESS			0x6d
+#define SDVO_CMD_GET_MAX_TV_CHROMA_FILTER		0x74
+#define SDVO_CMD_GET_MAX_TV_LUMA_FILTER			0x77
+struct intel_sdvo_enhancement_limits_reply {
+	u16 max_value;
+	u16 default_value;
+} __packed;
+
+#define SDVO_CMD_GET_LVDS_PANEL_INFORMATION		0x7f
+#define SDVO_CMD_SET_LVDS_PANEL_INFORMATION		0x80
+# define SDVO_LVDS_COLOR_DEPTH_18			(0 << 0)
+# define SDVO_LVDS_COLOR_DEPTH_24			(1 << 0)
+# define SDVO_LVDS_CONNECTOR_SPWG			(0 << 2)
+# define SDVO_LVDS_CONNECTOR_OPENLDI			(1 << 2)
+# define SDVO_LVDS_SINGLE_CHANNEL			(0 << 4)
+# define SDVO_LVDS_DUAL_CHANNEL				(1 << 4)
+
+#define SDVO_CMD_GET_FLICKER_FILTER			0x4e
+#define SDVO_CMD_SET_FLICKER_FILTER			0x4f
+#define SDVO_CMD_GET_FLICKER_FILTER_ADAPTIVE		0x50
+#define SDVO_CMD_SET_FLICKER_FILTER_ADAPTIVE		0x51
+#define SDVO_CMD_GET_FLICKER_FILTER_2D			0x53
+#define SDVO_CMD_SET_FLICKER_FILTER_2D			0x54
+#define SDVO_CMD_GET_SATURATION				0x56
+#define SDVO_CMD_SET_SATURATION				0x57
+#define SDVO_CMD_GET_HUE				0x59
+#define SDVO_CMD_SET_HUE				0x5a
+#define SDVO_CMD_GET_BRIGHTNESS				0x5c
+#define SDVO_CMD_SET_BRIGHTNESS				0x5d
+#define SDVO_CMD_GET_CONTRAST				0x5f
+#define SDVO_CMD_SET_CONTRAST				0x60
+#define SDVO_CMD_GET_OVERSCAN_H				0x62
+#define SDVO_CMD_SET_OVERSCAN_H				0x63
+#define SDVO_CMD_GET_OVERSCAN_V				0x65
+#define SDVO_CMD_SET_OVERSCAN_V				0x66
+#define SDVO_CMD_GET_HPOS				0x68
+#define SDVO_CMD_SET_HPOS				0x69
+#define SDVO_CMD_GET_VPOS				0x6b
+#define SDVO_CMD_SET_VPOS				0x6c
+#define SDVO_CMD_GET_SHARPNESS				0x6e
+#define SDVO_CMD_SET_SHARPNESS				0x6f
+#define SDVO_CMD_GET_TV_CHROMA_FILTER			0x75
+#define SDVO_CMD_SET_TV_CHROMA_FILTER			0x76
+#define SDVO_CMD_GET_TV_LUMA_FILTER			0x78
+#define SDVO_CMD_SET_TV_LUMA_FILTER			0x79
+struct intel_sdvo_enhancements_arg {
+	u16 value;
+} __packed;
+
+#define SDVO_CMD_GET_DOT_CRAWL				0x70
+#define SDVO_CMD_SET_DOT_CRAWL				0x71
+# define SDVO_DOT_CRAWL_ON					(1 << 0)
+# define SDVO_DOT_CRAWL_DEFAULT_ON				(1 << 1)
+
+#define SDVO_CMD_GET_DITHER				0x72
+#define SDVO_CMD_SET_DITHER				0x73
+# define SDVO_DITHER_ON						(1 << 0)
+# define SDVO_DITHER_DEFAULT_ON					(1 << 1)
+
+#define SDVO_CMD_SET_CONTROL_BUS_SWITCH			0x7a
+# define SDVO_CONTROL_BUS_PROM				(1 << 0)
+# define SDVO_CONTROL_BUS_DDC1				(1 << 1)
+# define SDVO_CONTROL_BUS_DDC2				(1 << 2)
+# define SDVO_CONTROL_BUS_DDC3				(1 << 3)
+
+/* HDMI op codes */
+#define SDVO_CMD_GET_SUPP_ENCODE	0x9d
+#define SDVO_CMD_GET_ENCODE		0x9e
+#define SDVO_CMD_SET_ENCODE		0x9f
+  #define SDVO_ENCODE_DVI	0x0
+  #define SDVO_ENCODE_HDMI	0x1
+#define SDVO_CMD_SET_PIXEL_REPLI	0x8b
+#define SDVO_CMD_GET_PIXEL_REPLI	0x8c
+#define SDVO_CMD_GET_COLORIMETRY_CAP	0x8d
+#define SDVO_CMD_SET_COLORIMETRY	0x8e
+  #define SDVO_COLORIMETRY_RGB256   0x0
+  #define SDVO_COLORIMETRY_RGB220   0x1
+  #define SDVO_COLORIMETRY_YCrCb422 0x3
+  #define SDVO_COLORIMETRY_YCrCb444 0x4
+#define SDVO_CMD_GET_COLORIMETRY	0x8f
+#define SDVO_CMD_GET_AUDIO_ENCRYPT_PREFER 0x90
+#define SDVO_CMD_SET_AUDIO_STAT		0x91
+#define SDVO_CMD_GET_AUDIO_STAT		0x92
+#define SDVO_CMD_SET_HBUF_INDEX		0x93
+  #define SDVO_HBUF_INDEX_ELD		0
+  #define SDVO_HBUF_INDEX_AVI_IF	1
+#define SDVO_CMD_GET_HBUF_INDEX		0x94
+#define SDVO_CMD_GET_HBUF_INFO		0x95
+#define SDVO_CMD_SET_HBUF_AV_SPLIT	0x96
+#define SDVO_CMD_GET_HBUF_AV_SPLIT	0x97
+#define SDVO_CMD_SET_HBUF_DATA		0x98
+#define SDVO_CMD_GET_HBUF_DATA		0x99
+#define SDVO_CMD_SET_HBUF_TXRATE	0x9a
+#define SDVO_CMD_GET_HBUF_TXRATE	0x9b
+  #define SDVO_HBUF_TX_DISABLED	(0 << 6)
+  #define SDVO_HBUF_TX_ONCE	(2 << 6)
+  #define SDVO_HBUF_TX_VSYNC	(3 << 6)
+#define SDVO_CMD_GET_AUDIO_TX_INFO	0x9c
+#define SDVO_NEED_TO_STALL  (1 << 7)
+
+struct intel_sdvo_encode {
+	u8 dvi_rev;
+	u8 hdmi_rev;
+} __packed;
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/i915/intel_sideband.c
@@ -0,0 +1,269 @@
+/*
+ * Copyright © 2013 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ */
+
+#include "i915_drv.h"
+#include "intel_drv.h"
+
+/*
+ * IOSF sideband, see VLV2_SidebandMsg_HAS.docx and
+ * VLV_VLV2_PUNIT_HAS_0.8.docx
+ */
+
+/* Standard MMIO read, non-posted */
+#define SB_MRD_NP	0x00
+/* Standard MMIO write, non-posted */
+#define SB_MWR_NP	0x01
+/* Private register read, double-word addressing, non-posted */
+#define SB_CRRDDA_NP	0x06
+/* Private register write, double-word addressing, non-posted */
+#define SB_CRWRDA_NP	0x07
+
+static int vlv_sideband_rw(struct drm_i915_private *dev_priv, u32 devfn,
+			   u32 port, u32 opcode, u32 addr, u32 *val)
+{
+	u32 cmd, be = 0xf, bar = 0;
+	bool is_read = (opcode == SB_MRD_NP || opcode == SB_CRRDDA_NP);
+
+	cmd = (devfn << IOSF_DEVFN_SHIFT) | (opcode << IOSF_OPCODE_SHIFT) |
+		(port << IOSF_PORT_SHIFT) | (be << IOSF_BYTE_ENABLES_SHIFT) |
+		(bar << IOSF_BAR_SHIFT);
+
+	WARN_ON(!mutex_is_locked(&dev_priv->sb_lock));
+
+	if (wait_for((I915_READ(VLV_IOSF_DOORBELL_REQ) & IOSF_SB_BUSY) == 0, 5)) {
+		DRM_DEBUG_DRIVER("IOSF sideband idle wait (%s) timed out\n",
+				 is_read ? "read" : "write");
+		return -EAGAIN;
+	}
+
+	I915_WRITE(VLV_IOSF_ADDR, addr);
+	if (!is_read)
+		I915_WRITE(VLV_IOSF_DATA, *val);
+	I915_WRITE(VLV_IOSF_DOORBELL_REQ, cmd);
+
+	if (wait_for((I915_READ(VLV_IOSF_DOORBELL_REQ) & IOSF_SB_BUSY) == 0, 5)) {
+		DRM_DEBUG_DRIVER("IOSF sideband finish wait (%s) timed out\n",
+				 is_read ? "read" : "write");
+		return -ETIMEDOUT;
+	}
+
+	if (is_read)
+		*val = I915_READ(VLV_IOSF_DATA);
+	I915_WRITE(VLV_IOSF_DATA, 0);
+
+	return 0;
+}
+
+u32 vlv_punit_read(struct drm_i915_private *dev_priv, u32 addr)
+{
+	u32 val = 0;
+
+	WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock));
+
+	mutex_lock(&dev_priv->sb_lock);
+	vlv_sideband_rw(dev_priv, PCI_DEVFN(0, 0), IOSF_PORT_PUNIT,
+			SB_CRRDDA_NP, addr, &val);
+	mutex_unlock(&dev_priv->sb_lock);
+
+	return val;
+}
+
+void vlv_punit_write(struct drm_i915_private *dev_priv, u32 addr, u32 val)
+{
+	WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock));
+
+	mutex_lock(&dev_priv->sb_lock);
+	vlv_sideband_rw(dev_priv, PCI_DEVFN(0, 0), IOSF_PORT_PUNIT,
+			SB_CRWRDA_NP, addr, &val);
+	mutex_unlock(&dev_priv->sb_lock);
+}
+
+u32 vlv_bunit_read(struct drm_i915_private *dev_priv, u32 reg)
+{
+	u32 val = 0;
+
+	vlv_sideband_rw(dev_priv, PCI_DEVFN(0, 0), IOSF_PORT_BUNIT,
+			SB_CRRDDA_NP, reg, &val);
+
+	return val;
+}
+
+void vlv_bunit_write(struct drm_i915_private *dev_priv, u32 reg, u32 val)
+{
+	vlv_sideband_rw(dev_priv, PCI_DEVFN(0, 0), IOSF_PORT_BUNIT,
+			SB_CRWRDA_NP, reg, &val);
+}
+
+u32 vlv_nc_read(struct drm_i915_private *dev_priv, u8 addr)
+{
+	u32 val = 0;
+
+	WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock));
+
+	mutex_lock(&dev_priv->sb_lock);
+	vlv_sideband_rw(dev_priv, PCI_DEVFN(0, 0), IOSF_PORT_NC,
+			SB_CRRDDA_NP, addr, &val);
+	mutex_unlock(&dev_priv->sb_lock);
+
+	return val;
+}
+
+u32 vlv_iosf_sb_read(struct drm_i915_private *dev_priv, u8 port, u32 reg)
+{
+	u32 val = 0;
+	vlv_sideband_rw(dev_priv, PCI_DEVFN(0, 0), port,
+			SB_CRRDDA_NP, reg, &val);
+	return val;
+}
+
+void vlv_iosf_sb_write(struct drm_i915_private *dev_priv,
+		       u8 port, u32 reg, u32 val)
+{
+	vlv_sideband_rw(dev_priv, PCI_DEVFN(0, 0), port,
+			SB_CRWRDA_NP, reg, &val);
+}
+
+u32 vlv_cck_read(struct drm_i915_private *dev_priv, u32 reg)
+{
+	u32 val = 0;
+	vlv_sideband_rw(dev_priv, PCI_DEVFN(0, 0), IOSF_PORT_CCK,
+			SB_CRRDDA_NP, reg, &val);
+	return val;
+}
+
+void vlv_cck_write(struct drm_i915_private *dev_priv, u32 reg, u32 val)
+{
+	vlv_sideband_rw(dev_priv, PCI_DEVFN(0, 0), IOSF_PORT_CCK,
+			SB_CRWRDA_NP, reg, &val);
+}
+
+u32 vlv_ccu_read(struct drm_i915_private *dev_priv, u32 reg)
+{
+	u32 val = 0;
+	vlv_sideband_rw(dev_priv, PCI_DEVFN(0, 0), IOSF_PORT_CCU,
+			SB_CRRDDA_NP, reg, &val);
+	return val;
+}
+
+void vlv_ccu_write(struct drm_i915_private *dev_priv, u32 reg, u32 val)
+{
+	vlv_sideband_rw(dev_priv, PCI_DEVFN(0, 0), IOSF_PORT_CCU,
+			SB_CRWRDA_NP, reg, &val);
+}
+
+u32 vlv_dpio_read(struct drm_i915_private *dev_priv, enum pipe pipe, int reg)
+{
+	u32 val = 0;
+
+	vlv_sideband_rw(dev_priv, DPIO_DEVFN, DPIO_PHY_IOSF_PORT(DPIO_PHY(pipe)),
+			SB_MRD_NP, reg, &val);
+
+	/*
+	 * FIXME: There might be some registers where all 1's is a valid value,
+	 * so ideally we should check the register offset instead...
+	 */
+	WARN(val == 0xffffffff, "DPIO read pipe %c reg 0x%x == 0x%x\n",
+	     pipe_name(pipe), reg, val);
+
+	return val;
+}
+
+void vlv_dpio_write(struct drm_i915_private *dev_priv, enum pipe pipe, int reg, u32 val)
+{
+	vlv_sideband_rw(dev_priv, DPIO_DEVFN, DPIO_PHY_IOSF_PORT(DPIO_PHY(pipe)),
+			SB_MWR_NP, reg, &val);
+}
+
+/* SBI access */
+u32 intel_sbi_read(struct drm_i915_private *dev_priv, u16 reg,
+		   enum intel_sbi_destination destination)
+{
+	u32 value = 0;
+	WARN_ON(!mutex_is_locked(&dev_priv->sb_lock));
+
+	if (wait_for((I915_READ(SBI_CTL_STAT) & SBI_BUSY) == 0,
+				100)) {
+		DRM_ERROR("timeout waiting for SBI to become ready\n");
+		return 0;
+	}
+
+	I915_WRITE(SBI_ADDR, (reg << 16));
+
+	if (destination == SBI_ICLK)
+		value = SBI_CTL_DEST_ICLK | SBI_CTL_OP_CRRD;
+	else
+		value = SBI_CTL_DEST_MPHY | SBI_CTL_OP_IORD;
+	I915_WRITE(SBI_CTL_STAT, value | SBI_BUSY);
+
+	if (wait_for((I915_READ(SBI_CTL_STAT) & (SBI_BUSY | SBI_RESPONSE_FAIL)) == 0,
+				100)) {
+		DRM_ERROR("timeout waiting for SBI to complete read transaction\n");
+		return 0;
+	}
+
+	return I915_READ(SBI_DATA);
+}
+
+void intel_sbi_write(struct drm_i915_private *dev_priv, u16 reg, u32 value,
+		     enum intel_sbi_destination destination)
+{
+	u32 tmp;
+
+	WARN_ON(!mutex_is_locked(&dev_priv->sb_lock));
+
+	if (wait_for((I915_READ(SBI_CTL_STAT) & SBI_BUSY) == 0,
+				100)) {
+		DRM_ERROR("timeout waiting for SBI to become ready\n");
+		return;
+	}
+
+	I915_WRITE(SBI_ADDR, (reg << 16));
+	I915_WRITE(SBI_DATA, value);
+
+	if (destination == SBI_ICLK)
+		tmp = SBI_CTL_DEST_ICLK | SBI_CTL_OP_CRWR;
+	else
+		tmp = SBI_CTL_DEST_MPHY | SBI_CTL_OP_IOWR;
+	I915_WRITE(SBI_CTL_STAT, SBI_BUSY | tmp);
+
+	if (wait_for((I915_READ(SBI_CTL_STAT) & (SBI_BUSY | SBI_RESPONSE_FAIL)) == 0,
+				100)) {
+		DRM_ERROR("timeout waiting for SBI to complete write transaction\n");
+		return;
+	}
+}
+
+u32 vlv_flisdsi_read(struct drm_i915_private *dev_priv, u32 reg)
+{
+	u32 val = 0;
+	vlv_sideband_rw(dev_priv, DPIO_DEVFN, IOSF_PORT_FLISDSI, SB_CRRDDA_NP,
+			reg, &val);
+	return val;
+}
+
+void vlv_flisdsi_write(struct drm_i915_private *dev_priv, u32 reg, u32 val)
+{
+	vlv_sideband_rw(dev_priv, DPIO_DEVFN, IOSF_PORT_FLISDSI, SB_CRWRDA_NP,
+			reg, &val);
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/i915/intel_sprite.c
@@ -0,0 +1,1132 @@
+/*
+ * Copyright © 2011 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Authors:
+ *   Jesse Barnes <jbarnes@virtuousgeek.org>
+ *
+ * New plane/sprite handling.
+ *
+ * The older chips had a separate interface for programming plane related
+ * registers; newer ones are much simpler and we can use the new DRM plane
+ * support.
+ */
+#include <drm/drmP.h>
+#include <drm/drm_crtc.h>
+#include <drm/drm_fourcc.h>
+#include <drm/drm_rect.h>
+#include <drm/drm_atomic.h>
+#include <drm/drm_plane_helper.h>
+#include "intel_drv.h"
+#include <drm/i915_drm.h>
+#include "i915_drv.h"
+
+static bool
+format_is_yuv(uint32_t format)
+{
+	switch (format) {
+	case DRM_FORMAT_YUYV:
+	case DRM_FORMAT_UYVY:
+	case DRM_FORMAT_VYUY:
+	case DRM_FORMAT_YVYU:
+		return true;
+	default:
+		return false;
+	}
+}
+
+static int usecs_to_scanlines(const struct drm_display_mode *adjusted_mode,
+			      int usecs)
+{
+	/* paranoia */
+	if (!adjusted_mode->crtc_htotal)
+		return 1;
+
+	return DIV_ROUND_UP(usecs * adjusted_mode->crtc_clock,
+			    1000 * adjusted_mode->crtc_htotal);
+}
+
+/**
+ * intel_pipe_update_start() - start update of a set of display registers
+ * @crtc: the crtc of which the registers are going to be updated
+ * @start_vbl_count: vblank counter return pointer used for error checking
+ *
+ * Mark the start of an update to pipe registers that should be updated
+ * atomically regarding vblank. If the next vblank will happens within
+ * the next 100 us, this function waits until the vblank passes.
+ *
+ * After a successful call to this function, interrupts will be disabled
+ * until a subsequent call to intel_pipe_update_end(). That is done to
+ * avoid random delays. The value written to @start_vbl_count should be
+ * supplied to intel_pipe_update_end() for error checking.
+ */
+void intel_pipe_update_start(struct intel_crtc *crtc)
+{
+	struct drm_device *dev = crtc->base.dev;
+	const struct drm_display_mode *adjusted_mode = &crtc->config->base.adjusted_mode;
+	enum pipe pipe = crtc->pipe;
+	long timeout = msecs_to_jiffies_timeout(1);
+	int scanline, min, max, vblank_start;
+	wait_queue_head_t *wq = drm_crtc_vblank_waitqueue(&crtc->base);
+	DEFINE_WAIT(wait);
+
+	vblank_start = adjusted_mode->crtc_vblank_start;
+	if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE)
+		vblank_start = DIV_ROUND_UP(vblank_start, 2);
+
+	/* FIXME needs to be calibrated sensibly */
+	min = vblank_start - usecs_to_scanlines(adjusted_mode, 100);
+	max = vblank_start - 1;
+
+	local_irq_disable();
+
+	if (min <= 0 || max <= 0)
+		return;
+
+	if (WARN_ON(drm_crtc_vblank_get(&crtc->base)))
+		return;
+
+	crtc->debug.min_vbl = min;
+	crtc->debug.max_vbl = max;
+	trace_i915_pipe_update_start(crtc);
+
+	for (;;) {
+		/*
+		 * prepare_to_wait() has a memory barrier, which guarantees
+		 * other CPUs can see the task state update by the time we
+		 * read the scanline.
+		 */
+		prepare_to_wait(wq, &wait, TASK_UNINTERRUPTIBLE);
+
+		scanline = intel_get_crtc_scanline(crtc);
+		if (scanline < min || scanline > max)
+			break;
+
+		if (timeout <= 0) {
+			DRM_ERROR("Potential atomic update failure on pipe %c\n",
+				  pipe_name(crtc->pipe));
+			break;
+		}
+
+		local_irq_enable();
+
+		timeout = schedule_timeout(timeout);
+
+		local_irq_disable();
+	}
+
+	finish_wait(wq, &wait);
+
+	drm_crtc_vblank_put(&crtc->base);
+
+	crtc->debug.scanline_start = scanline;
+	crtc->debug.start_vbl_time = ktime_get();
+	crtc->debug.start_vbl_count =
+		dev->driver->get_vblank_counter(dev, pipe);
+
+	trace_i915_pipe_update_vblank_evaded(crtc);
+}
+
+/**
+ * intel_pipe_update_end() - end update of a set of display registers
+ * @crtc: the crtc of which the registers were updated
+ * @start_vbl_count: start vblank counter (used for error checking)
+ *
+ * Mark the end of an update started with intel_pipe_update_start(). This
+ * re-enables interrupts and verifies the update was actually completed
+ * before a vblank using the value of @start_vbl_count.
+ */
+void intel_pipe_update_end(struct intel_crtc *crtc)
+{
+	struct drm_device *dev = crtc->base.dev;
+	enum pipe pipe = crtc->pipe;
+	int scanline_end = intel_get_crtc_scanline(crtc);
+	u32 end_vbl_count = dev->driver->get_vblank_counter(dev, pipe);
+	ktime_t end_vbl_time = ktime_get();
+
+	trace_i915_pipe_update_end(crtc, end_vbl_count, scanline_end);
+
+	local_irq_enable();
+
+	if (crtc->debug.start_vbl_count &&
+	    crtc->debug.start_vbl_count != end_vbl_count) {
+		DRM_ERROR("Atomic update failure on pipe %c (start=%u end=%u) time %lld us, min %d, max %d, scanline start %d, end %d\n",
+			  pipe_name(pipe), crtc->debug.start_vbl_count,
+			  end_vbl_count,
+			  ktime_us_delta(end_vbl_time, crtc->debug.start_vbl_time),
+			  crtc->debug.min_vbl, crtc->debug.max_vbl,
+			  crtc->debug.scanline_start, scanline_end);
+	}
+}
+
+static void
+skl_update_plane(struct drm_plane *drm_plane,
+		 const struct intel_crtc_state *crtc_state,
+		 const struct intel_plane_state *plane_state)
+{
+	struct drm_device *dev = drm_plane->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_plane *intel_plane = to_intel_plane(drm_plane);
+	struct drm_framebuffer *fb = plane_state->base.fb;
+	struct drm_i915_gem_object *obj = intel_fb_obj(fb);
+	const int pipe = intel_plane->pipe;
+	const int plane = intel_plane->plane + 1;
+	u32 plane_ctl, stride_div, stride;
+	const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
+	u32 surf_addr;
+	u32 tile_height, plane_offset, plane_size;
+	unsigned int rotation = plane_state->base.rotation;
+	int x_offset, y_offset;
+	int crtc_x = plane_state->dst.x1;
+	int crtc_y = plane_state->dst.y1;
+	uint32_t crtc_w = drm_rect_width(&plane_state->dst);
+	uint32_t crtc_h = drm_rect_height(&plane_state->dst);
+	uint32_t x = plane_state->src.x1 >> 16;
+	uint32_t y = plane_state->src.y1 >> 16;
+	uint32_t src_w = drm_rect_width(&plane_state->src) >> 16;
+	uint32_t src_h = drm_rect_height(&plane_state->src) >> 16;
+	const struct intel_scaler *scaler =
+		&crtc_state->scaler_state.scalers[plane_state->scaler_id];
+
+	plane_ctl = PLANE_CTL_ENABLE |
+		PLANE_CTL_PIPE_GAMMA_ENABLE |
+		PLANE_CTL_PIPE_CSC_ENABLE;
+
+	plane_ctl |= skl_plane_ctl_format(fb->pixel_format);
+	plane_ctl |= skl_plane_ctl_tiling(fb->modifier[0]);
+
+	plane_ctl |= skl_plane_ctl_rotation(rotation);
+
+	stride_div = intel_fb_stride_alignment(dev_priv, fb->modifier[0],
+					       fb->pixel_format);
+
+	/* Sizes are 0 based */
+	src_w--;
+	src_h--;
+	crtc_w--;
+	crtc_h--;
+
+	if (key->flags) {
+		I915_WRITE(PLANE_KEYVAL(pipe, plane), key->min_value);
+		I915_WRITE(PLANE_KEYMAX(pipe, plane), key->max_value);
+		I915_WRITE(PLANE_KEYMSK(pipe, plane), key->channel_mask);
+	}
+
+	if (key->flags & I915_SET_COLORKEY_DESTINATION)
+		plane_ctl |= PLANE_CTL_KEY_ENABLE_DESTINATION;
+	else if (key->flags & I915_SET_COLORKEY_SOURCE)
+		plane_ctl |= PLANE_CTL_KEY_ENABLE_SOURCE;
+
+	surf_addr = intel_plane_obj_offset(intel_plane, obj, 0);
+
+	if (intel_rotation_90_or_270(rotation)) {
+		int cpp = drm_format_plane_cpp(fb->pixel_format, 0);
+
+		/* stride: Surface height in tiles */
+		tile_height = intel_tile_height(dev_priv, fb->modifier[0], cpp);
+		stride = DIV_ROUND_UP(fb->height, tile_height);
+		plane_size = (src_w << 16) | src_h;
+		x_offset = stride * tile_height - y - (src_h + 1);
+		y_offset = x;
+	} else {
+		stride = fb->pitches[0] / stride_div;
+		plane_size = (src_h << 16) | src_w;
+		x_offset = x;
+		y_offset = y;
+	}
+	plane_offset = y_offset << 16 | x_offset;
+
+	I915_WRITE(PLANE_OFFSET(pipe, plane), plane_offset);
+	I915_WRITE(PLANE_STRIDE(pipe, plane), stride);
+	I915_WRITE(PLANE_SIZE(pipe, plane), plane_size);
+
+	/* program plane scaler */
+	if (plane_state->scaler_id >= 0) {
+		uint32_t ps_ctrl = 0;
+		int scaler_id = plane_state->scaler_id;
+
+		DRM_DEBUG_KMS("plane = %d PS_PLANE_SEL(plane) = 0x%x\n", plane,
+			PS_PLANE_SEL(plane));
+		ps_ctrl = PS_SCALER_EN | PS_PLANE_SEL(plane) | scaler->mode;
+		I915_WRITE(SKL_PS_CTRL(pipe, scaler_id), ps_ctrl);
+		I915_WRITE(SKL_PS_PWR_GATE(pipe, scaler_id), 0);
+		I915_WRITE(SKL_PS_WIN_POS(pipe, scaler_id), (crtc_x << 16) | crtc_y);
+		I915_WRITE(SKL_PS_WIN_SZ(pipe, scaler_id),
+			((crtc_w + 1) << 16)|(crtc_h + 1));
+
+		I915_WRITE(PLANE_POS(pipe, plane), 0);
+	} else {
+		I915_WRITE(PLANE_POS(pipe, plane), (crtc_y << 16) | crtc_x);
+	}
+
+	I915_WRITE(PLANE_CTL(pipe, plane), plane_ctl);
+	I915_WRITE(PLANE_SURF(pipe, plane), surf_addr);
+	POSTING_READ(PLANE_SURF(pipe, plane));
+}
+
+static void
+skl_disable_plane(struct drm_plane *dplane, struct drm_crtc *crtc)
+{
+	struct drm_device *dev = dplane->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_plane *intel_plane = to_intel_plane(dplane);
+	const int pipe = intel_plane->pipe;
+	const int plane = intel_plane->plane + 1;
+
+	I915_WRITE(PLANE_CTL(pipe, plane), 0);
+
+	I915_WRITE(PLANE_SURF(pipe, plane), 0);
+	POSTING_READ(PLANE_SURF(pipe, plane));
+}
+
+static void
+chv_update_csc(struct intel_plane *intel_plane, uint32_t format)
+{
+	struct drm_i915_private *dev_priv = intel_plane->base.dev->dev_private;
+	int plane = intel_plane->plane;
+
+	/* Seems RGB data bypasses the CSC always */
+	if (!format_is_yuv(format))
+		return;
+
+	/*
+	 * BT.601 limited range YCbCr -> full range RGB
+	 *
+	 * |r|   | 6537 4769     0|   |cr  |
+	 * |g| = |-3330 4769 -1605| x |y-64|
+	 * |b|   |    0 4769  8263|   |cb  |
+	 *
+	 * Cb and Cr apparently come in as signed already, so no
+	 * need for any offset. For Y we need to remove the offset.
+	 */
+	I915_WRITE(SPCSCYGOFF(plane), SPCSC_OOFF(0) | SPCSC_IOFF(-64));
+	I915_WRITE(SPCSCCBOFF(plane), SPCSC_OOFF(0) | SPCSC_IOFF(0));
+	I915_WRITE(SPCSCCROFF(plane), SPCSC_OOFF(0) | SPCSC_IOFF(0));
+
+	I915_WRITE(SPCSCC01(plane), SPCSC_C1(4769) | SPCSC_C0(6537));
+	I915_WRITE(SPCSCC23(plane), SPCSC_C1(-3330) | SPCSC_C0(0));
+	I915_WRITE(SPCSCC45(plane), SPCSC_C1(-1605) | SPCSC_C0(4769));
+	I915_WRITE(SPCSCC67(plane), SPCSC_C1(4769) | SPCSC_C0(0));
+	I915_WRITE(SPCSCC8(plane), SPCSC_C0(8263));
+
+	I915_WRITE(SPCSCYGICLAMP(plane), SPCSC_IMAX(940) | SPCSC_IMIN(64));
+	I915_WRITE(SPCSCCBICLAMP(plane), SPCSC_IMAX(448) | SPCSC_IMIN(-448));
+	I915_WRITE(SPCSCCRICLAMP(plane), SPCSC_IMAX(448) | SPCSC_IMIN(-448));
+
+	I915_WRITE(SPCSCYGOCLAMP(plane), SPCSC_OMAX(1023) | SPCSC_OMIN(0));
+	I915_WRITE(SPCSCCBOCLAMP(plane), SPCSC_OMAX(1023) | SPCSC_OMIN(0));
+	I915_WRITE(SPCSCCROCLAMP(plane), SPCSC_OMAX(1023) | SPCSC_OMIN(0));
+}
+
+static void
+vlv_update_plane(struct drm_plane *dplane,
+		 const struct intel_crtc_state *crtc_state,
+		 const struct intel_plane_state *plane_state)
+{
+	struct drm_device *dev = dplane->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_plane *intel_plane = to_intel_plane(dplane);
+	struct drm_framebuffer *fb = plane_state->base.fb;
+	struct drm_i915_gem_object *obj = intel_fb_obj(fb);
+	int pipe = intel_plane->pipe;
+	int plane = intel_plane->plane;
+	u32 sprctl;
+	u32 sprsurf_offset, linear_offset;
+	unsigned int rotation = dplane->state->rotation;
+	int cpp = drm_format_plane_cpp(fb->pixel_format, 0);
+	const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
+	int crtc_x = plane_state->dst.x1;
+	int crtc_y = plane_state->dst.y1;
+	uint32_t crtc_w = drm_rect_width(&plane_state->dst);
+	uint32_t crtc_h = drm_rect_height(&plane_state->dst);
+	uint32_t x = plane_state->src.x1 >> 16;
+	uint32_t y = plane_state->src.y1 >> 16;
+	uint32_t src_w = drm_rect_width(&plane_state->src) >> 16;
+	uint32_t src_h = drm_rect_height(&plane_state->src) >> 16;
+
+	sprctl = SP_ENABLE;
+
+	switch (fb->pixel_format) {
+	case DRM_FORMAT_YUYV:
+		sprctl |= SP_FORMAT_YUV422 | SP_YUV_ORDER_YUYV;
+		break;
+	case DRM_FORMAT_YVYU:
+		sprctl |= SP_FORMAT_YUV422 | SP_YUV_ORDER_YVYU;
+		break;
+	case DRM_FORMAT_UYVY:
+		sprctl |= SP_FORMAT_YUV422 | SP_YUV_ORDER_UYVY;
+		break;
+	case DRM_FORMAT_VYUY:
+		sprctl |= SP_FORMAT_YUV422 | SP_YUV_ORDER_VYUY;
+		break;
+	case DRM_FORMAT_RGB565:
+		sprctl |= SP_FORMAT_BGR565;
+		break;
+	case DRM_FORMAT_XRGB8888:
+		sprctl |= SP_FORMAT_BGRX8888;
+		break;
+	case DRM_FORMAT_ARGB8888:
+		sprctl |= SP_FORMAT_BGRA8888;
+		break;
+	case DRM_FORMAT_XBGR2101010:
+		sprctl |= SP_FORMAT_RGBX1010102;
+		break;
+	case DRM_FORMAT_ABGR2101010:
+		sprctl |= SP_FORMAT_RGBA1010102;
+		break;
+	case DRM_FORMAT_XBGR8888:
+		sprctl |= SP_FORMAT_RGBX8888;
+		break;
+	case DRM_FORMAT_ABGR8888:
+		sprctl |= SP_FORMAT_RGBA8888;
+		break;
+	default:
+		/*
+		 * If we get here one of the upper layers failed to filter
+		 * out the unsupported plane formats
+		 */
+		BUG();
+		break;
+	}
+
+	/*
+	 * Enable gamma to match primary/cursor plane behaviour.
+	 * FIXME should be user controllable via propertiesa.
+	 */
+	sprctl |= SP_GAMMA_ENABLE;
+
+	if (obj->tiling_mode != I915_TILING_NONE)
+		sprctl |= SP_TILED;
+
+	/* Sizes are 0 based */
+	src_w--;
+	src_h--;
+	crtc_w--;
+	crtc_h--;
+
+	linear_offset = y * fb->pitches[0] + x * cpp;
+	sprsurf_offset = intel_compute_tile_offset(&x, &y, fb, 0,
+						   fb->pitches[0], rotation);
+	linear_offset -= sprsurf_offset;
+
+	if (rotation == BIT(DRM_ROTATE_180)) {
+		sprctl |= SP_ROTATE_180;
+
+		x += src_w;
+		y += src_h;
+		linear_offset += src_h * fb->pitches[0] + src_w * cpp;
+	}
+
+	if (key->flags) {
+		I915_WRITE(SPKEYMINVAL(pipe, plane), key->min_value);
+		I915_WRITE(SPKEYMAXVAL(pipe, plane), key->max_value);
+		I915_WRITE(SPKEYMSK(pipe, plane), key->channel_mask);
+	}
+
+	if (key->flags & I915_SET_COLORKEY_SOURCE)
+		sprctl |= SP_SOURCE_KEY;
+
+	if (IS_CHERRYVIEW(dev) && pipe == PIPE_B)
+		chv_update_csc(intel_plane, fb->pixel_format);
+
+	I915_WRITE(SPSTRIDE(pipe, plane), fb->pitches[0]);
+	I915_WRITE(SPPOS(pipe, plane), (crtc_y << 16) | crtc_x);
+
+	if (obj->tiling_mode != I915_TILING_NONE)
+		I915_WRITE(SPTILEOFF(pipe, plane), (y << 16) | x);
+	else
+		I915_WRITE(SPLINOFF(pipe, plane), linear_offset);
+
+	I915_WRITE(SPCONSTALPHA(pipe, plane), 0);
+
+	I915_WRITE(SPSIZE(pipe, plane), (crtc_h << 16) | crtc_w);
+	I915_WRITE(SPCNTR(pipe, plane), sprctl);
+	I915_WRITE(SPSURF(pipe, plane), i915_gem_obj_ggtt_offset(obj) +
+		   sprsurf_offset);
+	POSTING_READ(SPSURF(pipe, plane));
+}
+
+static void
+vlv_disable_plane(struct drm_plane *dplane, struct drm_crtc *crtc)
+{
+	struct drm_device *dev = dplane->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_plane *intel_plane = to_intel_plane(dplane);
+	int pipe = intel_plane->pipe;
+	int plane = intel_plane->plane;
+
+	I915_WRITE(SPCNTR(pipe, plane), 0);
+
+	I915_WRITE(SPSURF(pipe, plane), 0);
+	POSTING_READ(SPSURF(pipe, plane));
+}
+
+static void
+ivb_update_plane(struct drm_plane *plane,
+		 const struct intel_crtc_state *crtc_state,
+		 const struct intel_plane_state *plane_state)
+{
+	struct drm_device *dev = plane->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_plane *intel_plane = to_intel_plane(plane);
+	struct drm_framebuffer *fb = plane_state->base.fb;
+	struct drm_i915_gem_object *obj = intel_fb_obj(fb);
+	enum pipe pipe = intel_plane->pipe;
+	u32 sprctl, sprscale = 0;
+	u32 sprsurf_offset, linear_offset;
+	unsigned int rotation = plane_state->base.rotation;
+	int cpp = drm_format_plane_cpp(fb->pixel_format, 0);
+	const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
+	int crtc_x = plane_state->dst.x1;
+	int crtc_y = plane_state->dst.y1;
+	uint32_t crtc_w = drm_rect_width(&plane_state->dst);
+	uint32_t crtc_h = drm_rect_height(&plane_state->dst);
+	uint32_t x = plane_state->src.x1 >> 16;
+	uint32_t y = plane_state->src.y1 >> 16;
+	uint32_t src_w = drm_rect_width(&plane_state->src) >> 16;
+	uint32_t src_h = drm_rect_height(&plane_state->src) >> 16;
+
+	sprctl = SPRITE_ENABLE;
+
+	switch (fb->pixel_format) {
+	case DRM_FORMAT_XBGR8888:
+		sprctl |= SPRITE_FORMAT_RGBX888 | SPRITE_RGB_ORDER_RGBX;
+		break;
+	case DRM_FORMAT_XRGB8888:
+		sprctl |= SPRITE_FORMAT_RGBX888;
+		break;
+	case DRM_FORMAT_YUYV:
+		sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_YUYV;
+		break;
+	case DRM_FORMAT_YVYU:
+		sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_YVYU;
+		break;
+	case DRM_FORMAT_UYVY:
+		sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_UYVY;
+		break;
+	case DRM_FORMAT_VYUY:
+		sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_VYUY;
+		break;
+	default:
+		BUG();
+	}
+
+	/*
+	 * Enable gamma to match primary/cursor plane behaviour.
+	 * FIXME should be user controllable via propertiesa.
+	 */
+	sprctl |= SPRITE_GAMMA_ENABLE;
+
+	if (obj->tiling_mode != I915_TILING_NONE)
+		sprctl |= SPRITE_TILED;
+
+	if (IS_HASWELL(dev) || IS_BROADWELL(dev))
+		sprctl &= ~SPRITE_TRICKLE_FEED_DISABLE;
+	else
+		sprctl |= SPRITE_TRICKLE_FEED_DISABLE;
+
+	if (IS_HASWELL(dev) || IS_BROADWELL(dev))
+		sprctl |= SPRITE_PIPE_CSC_ENABLE;
+
+	/* Sizes are 0 based */
+	src_w--;
+	src_h--;
+	crtc_w--;
+	crtc_h--;
+
+	if (crtc_w != src_w || crtc_h != src_h)
+		sprscale = SPRITE_SCALE_ENABLE | (src_w << 16) | src_h;
+
+	linear_offset = y * fb->pitches[0] + x * cpp;
+	sprsurf_offset = intel_compute_tile_offset(&x, &y, fb, 0,
+						   fb->pitches[0], rotation);
+	linear_offset -= sprsurf_offset;
+
+	if (rotation == BIT(DRM_ROTATE_180)) {
+		sprctl |= SPRITE_ROTATE_180;
+
+		/* HSW and BDW does this automagically in hardware */
+		if (!IS_HASWELL(dev) && !IS_BROADWELL(dev)) {
+			x += src_w;
+			y += src_h;
+			linear_offset += src_h * fb->pitches[0] + src_w * cpp;
+		}
+	}
+
+	if (key->flags) {
+		I915_WRITE(SPRKEYVAL(pipe), key->min_value);
+		I915_WRITE(SPRKEYMAX(pipe), key->max_value);
+		I915_WRITE(SPRKEYMSK(pipe), key->channel_mask);
+	}
+
+	if (key->flags & I915_SET_COLORKEY_DESTINATION)
+		sprctl |= SPRITE_DEST_KEY;
+	else if (key->flags & I915_SET_COLORKEY_SOURCE)
+		sprctl |= SPRITE_SOURCE_KEY;
+
+	I915_WRITE(SPRSTRIDE(pipe), fb->pitches[0]);
+	I915_WRITE(SPRPOS(pipe), (crtc_y << 16) | crtc_x);
+
+	/* HSW consolidates SPRTILEOFF and SPRLINOFF into a single SPROFFSET
+	 * register */
+	if (IS_HASWELL(dev) || IS_BROADWELL(dev))
+		I915_WRITE(SPROFFSET(pipe), (y << 16) | x);
+	else if (obj->tiling_mode != I915_TILING_NONE)
+		I915_WRITE(SPRTILEOFF(pipe), (y << 16) | x);
+	else
+		I915_WRITE(SPRLINOFF(pipe), linear_offset);
+
+	I915_WRITE(SPRSIZE(pipe), (crtc_h << 16) | crtc_w);
+	if (intel_plane->can_scale)
+		I915_WRITE(SPRSCALE(pipe), sprscale);
+	I915_WRITE(SPRCTL(pipe), sprctl);
+	I915_WRITE(SPRSURF(pipe),
+		   i915_gem_obj_ggtt_offset(obj) + sprsurf_offset);
+	POSTING_READ(SPRSURF(pipe));
+}
+
+static void
+ivb_disable_plane(struct drm_plane *plane, struct drm_crtc *crtc)
+{
+	struct drm_device *dev = plane->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_plane *intel_plane = to_intel_plane(plane);
+	int pipe = intel_plane->pipe;
+
+	I915_WRITE(SPRCTL(pipe), 0);
+	/* Can't leave the scaler enabled... */
+	if (intel_plane->can_scale)
+		I915_WRITE(SPRSCALE(pipe), 0);
+
+	I915_WRITE(SPRSURF(pipe), 0);
+	POSTING_READ(SPRSURF(pipe));
+}
+
+static void
+ilk_update_plane(struct drm_plane *plane,
+		 const struct intel_crtc_state *crtc_state,
+		 const struct intel_plane_state *plane_state)
+{
+	struct drm_device *dev = plane->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_plane *intel_plane = to_intel_plane(plane);
+	struct drm_framebuffer *fb = plane_state->base.fb;
+	struct drm_i915_gem_object *obj = intel_fb_obj(fb);
+	int pipe = intel_plane->pipe;
+	u32 dvscntr, dvsscale;
+	u32 dvssurf_offset, linear_offset;
+	unsigned int rotation = plane_state->base.rotation;
+	int cpp = drm_format_plane_cpp(fb->pixel_format, 0);
+	const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
+	int crtc_x = plane_state->dst.x1;
+	int crtc_y = plane_state->dst.y1;
+	uint32_t crtc_w = drm_rect_width(&plane_state->dst);
+	uint32_t crtc_h = drm_rect_height(&plane_state->dst);
+	uint32_t x = plane_state->src.x1 >> 16;
+	uint32_t y = plane_state->src.y1 >> 16;
+	uint32_t src_w = drm_rect_width(&plane_state->src) >> 16;
+	uint32_t src_h = drm_rect_height(&plane_state->src) >> 16;
+
+	dvscntr = DVS_ENABLE;
+
+	switch (fb->pixel_format) {
+	case DRM_FORMAT_XBGR8888:
+		dvscntr |= DVS_FORMAT_RGBX888 | DVS_RGB_ORDER_XBGR;
+		break;
+	case DRM_FORMAT_XRGB8888:
+		dvscntr |= DVS_FORMAT_RGBX888;
+		break;
+	case DRM_FORMAT_YUYV:
+		dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_YUYV;
+		break;
+	case DRM_FORMAT_YVYU:
+		dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_YVYU;
+		break;
+	case DRM_FORMAT_UYVY:
+		dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_UYVY;
+		break;
+	case DRM_FORMAT_VYUY:
+		dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_VYUY;
+		break;
+	default:
+		BUG();
+	}
+
+	/*
+	 * Enable gamma to match primary/cursor plane behaviour.
+	 * FIXME should be user controllable via propertiesa.
+	 */
+	dvscntr |= DVS_GAMMA_ENABLE;
+
+	if (obj->tiling_mode != I915_TILING_NONE)
+		dvscntr |= DVS_TILED;
+
+	if (IS_GEN6(dev))
+		dvscntr |= DVS_TRICKLE_FEED_DISABLE; /* must disable */
+
+	/* Sizes are 0 based */
+	src_w--;
+	src_h--;
+	crtc_w--;
+	crtc_h--;
+
+	dvsscale = 0;
+	if (crtc_w != src_w || crtc_h != src_h)
+		dvsscale = DVS_SCALE_ENABLE | (src_w << 16) | src_h;
+
+	linear_offset = y * fb->pitches[0] + x * cpp;
+	dvssurf_offset = intel_compute_tile_offset(&x, &y, fb, 0,
+						   fb->pitches[0], rotation);
+	linear_offset -= dvssurf_offset;
+
+	if (rotation == BIT(DRM_ROTATE_180)) {
+		dvscntr |= DVS_ROTATE_180;
+
+		x += src_w;
+		y += src_h;
+		linear_offset += src_h * fb->pitches[0] + src_w * cpp;
+	}
+
+	if (key->flags) {
+		I915_WRITE(DVSKEYVAL(pipe), key->min_value);
+		I915_WRITE(DVSKEYMAX(pipe), key->max_value);
+		I915_WRITE(DVSKEYMSK(pipe), key->channel_mask);
+	}
+
+	if (key->flags & I915_SET_COLORKEY_DESTINATION)
+		dvscntr |= DVS_DEST_KEY;
+	else if (key->flags & I915_SET_COLORKEY_SOURCE)
+		dvscntr |= DVS_SOURCE_KEY;
+
+	I915_WRITE(DVSSTRIDE(pipe), fb->pitches[0]);
+	I915_WRITE(DVSPOS(pipe), (crtc_y << 16) | crtc_x);
+
+	if (obj->tiling_mode != I915_TILING_NONE)
+		I915_WRITE(DVSTILEOFF(pipe), (y << 16) | x);
+	else
+		I915_WRITE(DVSLINOFF(pipe), linear_offset);
+
+	I915_WRITE(DVSSIZE(pipe), (crtc_h << 16) | crtc_w);
+	I915_WRITE(DVSSCALE(pipe), dvsscale);
+	I915_WRITE(DVSCNTR(pipe), dvscntr);
+	I915_WRITE(DVSSURF(pipe),
+		   i915_gem_obj_ggtt_offset(obj) + dvssurf_offset);
+	POSTING_READ(DVSSURF(pipe));
+}
+
+static void
+ilk_disable_plane(struct drm_plane *plane, struct drm_crtc *crtc)
+{
+	struct drm_device *dev = plane->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_plane *intel_plane = to_intel_plane(plane);
+	int pipe = intel_plane->pipe;
+
+	I915_WRITE(DVSCNTR(pipe), 0);
+	/* Disable the scaler */
+	I915_WRITE(DVSSCALE(pipe), 0);
+
+	I915_WRITE(DVSSURF(pipe), 0);
+	POSTING_READ(DVSSURF(pipe));
+}
+
+static int
+intel_check_sprite_plane(struct drm_plane *plane,
+			 struct intel_crtc_state *crtc_state,
+			 struct intel_plane_state *state)
+{
+	struct drm_device *dev = plane->dev;
+	struct drm_crtc *crtc = state->base.crtc;
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	struct intel_plane *intel_plane = to_intel_plane(plane);
+	struct drm_framebuffer *fb = state->base.fb;
+	int crtc_x, crtc_y;
+	unsigned int crtc_w, crtc_h;
+	uint32_t src_x, src_y, src_w, src_h;
+	struct drm_rect *src = &state->src;
+	struct drm_rect *dst = &state->dst;
+	const struct drm_rect *clip = &state->clip;
+	int hscale, vscale;
+	int max_scale, min_scale;
+	bool can_scale;
+
+	if (!fb) {
+		state->visible = false;
+		return 0;
+	}
+
+	/* Don't modify another pipe's plane */
+	if (intel_plane->pipe != intel_crtc->pipe) {
+		DRM_DEBUG_KMS("Wrong plane <-> crtc mapping\n");
+		return -EINVAL;
+	}
+
+	/* FIXME check all gen limits */
+	if (fb->width < 3 || fb->height < 3 || fb->pitches[0] > 16384) {
+		DRM_DEBUG_KMS("Unsuitable framebuffer for plane\n");
+		return -EINVAL;
+	}
+
+	/* setup can_scale, min_scale, max_scale */
+	if (INTEL_INFO(dev)->gen >= 9) {
+		/* use scaler when colorkey is not required */
+		if (state->ckey.flags == I915_SET_COLORKEY_NONE) {
+			can_scale = 1;
+			min_scale = 1;
+			max_scale = skl_max_scale(intel_crtc, crtc_state);
+		} else {
+			can_scale = 0;
+			min_scale = DRM_PLANE_HELPER_NO_SCALING;
+			max_scale = DRM_PLANE_HELPER_NO_SCALING;
+		}
+	} else {
+		can_scale = intel_plane->can_scale;
+		max_scale = intel_plane->max_downscale << 16;
+		min_scale = intel_plane->can_scale ? 1 : (1 << 16);
+	}
+
+	/*
+	 * FIXME the following code does a bunch of fuzzy adjustments to the
+	 * coordinates and sizes. We probably need some way to decide whether
+	 * more strict checking should be done instead.
+	 */
+	drm_rect_rotate(src, fb->width << 16, fb->height << 16,
+			state->base.rotation);
+
+	hscale = drm_rect_calc_hscale_relaxed(src, dst, min_scale, max_scale);
+	BUG_ON(hscale < 0);
+
+	vscale = drm_rect_calc_vscale_relaxed(src, dst, min_scale, max_scale);
+	BUG_ON(vscale < 0);
+
+	state->visible = drm_rect_clip_scaled(src, dst, clip, hscale, vscale);
+
+	crtc_x = dst->x1;
+	crtc_y = dst->y1;
+	crtc_w = drm_rect_width(dst);
+	crtc_h = drm_rect_height(dst);
+
+	if (state->visible) {
+		/* check again in case clipping clamped the results */
+		hscale = drm_rect_calc_hscale(src, dst, min_scale, max_scale);
+		if (hscale < 0) {
+			DRM_DEBUG_KMS("Horizontal scaling factor out of limits\n");
+			drm_rect_debug_print("src: ", src, true);
+			drm_rect_debug_print("dst: ", dst, false);
+
+			return hscale;
+		}
+
+		vscale = drm_rect_calc_vscale(src, dst, min_scale, max_scale);
+		if (vscale < 0) {
+			DRM_DEBUG_KMS("Vertical scaling factor out of limits\n");
+			drm_rect_debug_print("src: ", src, true);
+			drm_rect_debug_print("dst: ", dst, false);
+
+			return vscale;
+		}
+
+		/* Make the source viewport size an exact multiple of the scaling factors. */
+		drm_rect_adjust_size(src,
+				     drm_rect_width(dst) * hscale - drm_rect_width(src),
+				     drm_rect_height(dst) * vscale - drm_rect_height(src));
+
+		drm_rect_rotate_inv(src, fb->width << 16, fb->height << 16,
+				    state->base.rotation);
+
+		/* sanity check to make sure the src viewport wasn't enlarged */
+		WARN_ON(src->x1 < (int) state->base.src_x ||
+			src->y1 < (int) state->base.src_y ||
+			src->x2 > (int) state->base.src_x + state->base.src_w ||
+			src->y2 > (int) state->base.src_y + state->base.src_h);
+
+		/*
+		 * Hardware doesn't handle subpixel coordinates.
+		 * Adjust to (macro)pixel boundary, but be careful not to
+		 * increase the source viewport size, because that could
+		 * push the downscaling factor out of bounds.
+		 */
+		src_x = src->x1 >> 16;
+		src_w = drm_rect_width(src) >> 16;
+		src_y = src->y1 >> 16;
+		src_h = drm_rect_height(src) >> 16;
+
+		if (format_is_yuv(fb->pixel_format)) {
+			src_x &= ~1;
+			src_w &= ~1;
+
+			/*
+			 * Must keep src and dst the
+			 * same if we can't scale.
+			 */
+			if (!can_scale)
+				crtc_w &= ~1;
+
+			if (crtc_w == 0)
+				state->visible = false;
+		}
+	}
+
+	/* Check size restrictions when scaling */
+	if (state->visible && (src_w != crtc_w || src_h != crtc_h)) {
+		unsigned int width_bytes;
+		int cpp = drm_format_plane_cpp(fb->pixel_format, 0);
+
+		WARN_ON(!can_scale);
+
+		/* FIXME interlacing min height is 6 */
+
+		if (crtc_w < 3 || crtc_h < 3)
+			state->visible = false;
+
+		if (src_w < 3 || src_h < 3)
+			state->visible = false;
+
+		width_bytes = ((src_x * cpp) & 63) + src_w * cpp;
+
+		if (INTEL_INFO(dev)->gen < 9 && (src_w > 2048 || src_h > 2048 ||
+		    width_bytes > 4096 || fb->pitches[0] > 4096)) {
+			DRM_DEBUG_KMS("Source dimensions exceed hardware limits\n");
+			return -EINVAL;
+		}
+	}
+
+	if (state->visible) {
+		src->x1 = src_x << 16;
+		src->x2 = (src_x + src_w) << 16;
+		src->y1 = src_y << 16;
+		src->y2 = (src_y + src_h) << 16;
+	}
+
+	dst->x1 = crtc_x;
+	dst->x2 = crtc_x + crtc_w;
+	dst->y1 = crtc_y;
+	dst->y2 = crtc_y + crtc_h;
+
+	return 0;
+}
+
+int intel_sprite_set_colorkey(struct drm_device *dev, void *data,
+			      struct drm_file *file_priv)
+{
+	struct drm_intel_sprite_colorkey *set = data;
+	struct drm_plane *plane;
+	struct drm_plane_state *plane_state;
+	struct drm_atomic_state *state;
+	struct drm_modeset_acquire_ctx ctx;
+	int ret = 0;
+
+	/* Make sure we don't try to enable both src & dest simultaneously */
+	if ((set->flags & (I915_SET_COLORKEY_DESTINATION | I915_SET_COLORKEY_SOURCE)) == (I915_SET_COLORKEY_DESTINATION | I915_SET_COLORKEY_SOURCE))
+		return -EINVAL;
+
+	if ((IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev)) &&
+	    set->flags & I915_SET_COLORKEY_DESTINATION)
+		return -EINVAL;
+
+	plane = drm_plane_find(dev, set->plane_id);
+	if (!plane || plane->type != DRM_PLANE_TYPE_OVERLAY)
+		return -ENOENT;
+
+	drm_modeset_acquire_init(&ctx, 0);
+
+	state = drm_atomic_state_alloc(plane->dev);
+	if (!state) {
+		ret = -ENOMEM;
+		goto out;
+	}
+	state->acquire_ctx = &ctx;
+
+	while (1) {
+		plane_state = drm_atomic_get_plane_state(state, plane);
+		ret = PTR_ERR_OR_ZERO(plane_state);
+		if (!ret) {
+			to_intel_plane_state(plane_state)->ckey = *set;
+			ret = drm_atomic_commit(state);
+		}
+
+		if (ret != -EDEADLK)
+			break;
+
+		drm_atomic_state_clear(state);
+		drm_modeset_backoff(&ctx);
+	}
+
+	if (ret)
+		drm_atomic_state_free(state);
+
+out:
+	drm_modeset_drop_locks(&ctx);
+	drm_modeset_acquire_fini(&ctx);
+	return ret;
+}
+
+static const uint32_t ilk_plane_formats[] = {
+	DRM_FORMAT_XRGB8888,
+	DRM_FORMAT_YUYV,
+	DRM_FORMAT_YVYU,
+	DRM_FORMAT_UYVY,
+	DRM_FORMAT_VYUY,
+};
+
+static const uint32_t snb_plane_formats[] = {
+	DRM_FORMAT_XBGR8888,
+	DRM_FORMAT_XRGB8888,
+	DRM_FORMAT_YUYV,
+	DRM_FORMAT_YVYU,
+	DRM_FORMAT_UYVY,
+	DRM_FORMAT_VYUY,
+};
+
+static const uint32_t vlv_plane_formats[] = {
+	DRM_FORMAT_RGB565,
+	DRM_FORMAT_ABGR8888,
+	DRM_FORMAT_ARGB8888,
+	DRM_FORMAT_XBGR8888,
+	DRM_FORMAT_XRGB8888,
+	DRM_FORMAT_XBGR2101010,
+	DRM_FORMAT_ABGR2101010,
+	DRM_FORMAT_YUYV,
+	DRM_FORMAT_YVYU,
+	DRM_FORMAT_UYVY,
+	DRM_FORMAT_VYUY,
+};
+
+static uint32_t skl_plane_formats[] = {
+	DRM_FORMAT_RGB565,
+	DRM_FORMAT_ABGR8888,
+	DRM_FORMAT_ARGB8888,
+	DRM_FORMAT_XBGR8888,
+	DRM_FORMAT_XRGB8888,
+	DRM_FORMAT_YUYV,
+	DRM_FORMAT_YVYU,
+	DRM_FORMAT_UYVY,
+	DRM_FORMAT_VYUY,
+};
+
+int
+intel_plane_init(struct drm_device *dev, enum pipe pipe, int plane)
+{
+	struct intel_plane *intel_plane = NULL;
+	struct intel_plane_state *state = NULL;
+	unsigned long possible_crtcs;
+	const uint32_t *plane_formats;
+	int num_plane_formats;
+	int ret;
+
+	if (INTEL_INFO(dev)->gen < 5)
+		return -ENODEV;
+
+	intel_plane = kzalloc(sizeof(*intel_plane), GFP_KERNEL);
+	if (!intel_plane) {
+		ret = -ENOMEM;
+		goto fail;
+	}
+
+	state = intel_create_plane_state(&intel_plane->base);
+	if (!state) {
+		ret = -ENOMEM;
+		goto fail;
+	}
+	intel_plane->base.state = &state->base;
+
+	switch (INTEL_INFO(dev)->gen) {
+	case 5:
+	case 6:
+		intel_plane->can_scale = true;
+		intel_plane->max_downscale = 16;
+		intel_plane->update_plane = ilk_update_plane;
+		intel_plane->disable_plane = ilk_disable_plane;
+
+		if (IS_GEN6(dev)) {
+			plane_formats = snb_plane_formats;
+			num_plane_formats = ARRAY_SIZE(snb_plane_formats);
+		} else {
+			plane_formats = ilk_plane_formats;
+			num_plane_formats = ARRAY_SIZE(ilk_plane_formats);
+		}
+		break;
+
+	case 7:
+	case 8:
+		if (IS_IVYBRIDGE(dev)) {
+			intel_plane->can_scale = true;
+			intel_plane->max_downscale = 2;
+		} else {
+			intel_plane->can_scale = false;
+			intel_plane->max_downscale = 1;
+		}
+
+		if (IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev)) {
+			intel_plane->update_plane = vlv_update_plane;
+			intel_plane->disable_plane = vlv_disable_plane;
+
+			plane_formats = vlv_plane_formats;
+			num_plane_formats = ARRAY_SIZE(vlv_plane_formats);
+		} else {
+			intel_plane->update_plane = ivb_update_plane;
+			intel_plane->disable_plane = ivb_disable_plane;
+
+			plane_formats = snb_plane_formats;
+			num_plane_formats = ARRAY_SIZE(snb_plane_formats);
+		}
+		break;
+	case 9:
+		intel_plane->can_scale = true;
+		intel_plane->update_plane = skl_update_plane;
+		intel_plane->disable_plane = skl_disable_plane;
+		state->scaler_id = -1;
+
+		plane_formats = skl_plane_formats;
+		num_plane_formats = ARRAY_SIZE(skl_plane_formats);
+		break;
+	default:
+		MISSING_CASE(INTEL_INFO(dev)->gen);
+		ret = -ENODEV;
+		goto fail;
+	}
+
+	intel_plane->pipe = pipe;
+	intel_plane->plane = plane;
+	intel_plane->frontbuffer_bit = INTEL_FRONTBUFFER_SPRITE(pipe, plane);
+	intel_plane->check_plane = intel_check_sprite_plane;
+
+	possible_crtcs = (1 << pipe);
+
+	ret = drm_universal_plane_init(dev, &intel_plane->base, possible_crtcs,
+				       &intel_plane_funcs,
+				       plane_formats, num_plane_formats,
+				       DRM_PLANE_TYPE_OVERLAY);
+	if (ret)
+		goto fail;
+
+	intel_create_rotation_property(dev, intel_plane);
+
+	drm_plane_helper_add(&intel_plane->base, &intel_plane_helper_funcs);
+
+	return 0;
+
+fail:
+	kfree(state);
+	kfree(intel_plane);
+
+	return ret;
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/i915/intel_tv.c
@@ -0,0 +1,1646 @@
+/*
+ * Copyright © 2006-2008 Intel Corporation
+ *   Jesse Barnes <jesse.barnes@intel.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Eric Anholt <eric@anholt.net>
+ *
+ */
+
+/** @file
+ * Integrated TV-out support for the 915GM and 945GM.
+ */
+
+#include <drm/drmP.h>
+#include <drm/drm_atomic_helper.h>
+#include <drm/drm_crtc.h>
+#include <drm/drm_edid.h>
+#include "intel_drv.h"
+#include <drm/i915_drm.h>
+#include "i915_drv.h"
+
+enum tv_margin {
+	TV_MARGIN_LEFT, TV_MARGIN_TOP,
+	TV_MARGIN_RIGHT, TV_MARGIN_BOTTOM
+};
+
+/** Private structure for the integrated TV support */
+struct intel_tv {
+	struct intel_encoder base;
+
+	int type;
+	const char *tv_format;
+	int margin[4];
+	u32 save_TV_H_CTL_1;
+	u32 save_TV_H_CTL_2;
+	u32 save_TV_H_CTL_3;
+	u32 save_TV_V_CTL_1;
+	u32 save_TV_V_CTL_2;
+	u32 save_TV_V_CTL_3;
+	u32 save_TV_V_CTL_4;
+	u32 save_TV_V_CTL_5;
+	u32 save_TV_V_CTL_6;
+	u32 save_TV_V_CTL_7;
+	u32 save_TV_SC_CTL_1, save_TV_SC_CTL_2, save_TV_SC_CTL_3;
+
+	u32 save_TV_CSC_Y;
+	u32 save_TV_CSC_Y2;
+	u32 save_TV_CSC_U;
+	u32 save_TV_CSC_U2;
+	u32 save_TV_CSC_V;
+	u32 save_TV_CSC_V2;
+	u32 save_TV_CLR_KNOBS;
+	u32 save_TV_CLR_LEVEL;
+	u32 save_TV_WIN_POS;
+	u32 save_TV_WIN_SIZE;
+	u32 save_TV_FILTER_CTL_1;
+	u32 save_TV_FILTER_CTL_2;
+	u32 save_TV_FILTER_CTL_3;
+
+	u32 save_TV_H_LUMA[60];
+	u32 save_TV_H_CHROMA[60];
+	u32 save_TV_V_LUMA[43];
+	u32 save_TV_V_CHROMA[43];
+
+	u32 save_TV_DAC;
+	u32 save_TV_CTL;
+};
+
+struct video_levels {
+	int blank, black, burst;
+};
+
+struct color_conversion {
+	u16 ry, gy, by, ay;
+	u16 ru, gu, bu, au;
+	u16 rv, gv, bv, av;
+};
+
+static const u32 filter_table[] = {
+	0xB1403000, 0x2E203500, 0x35002E20, 0x3000B140,
+	0x35A0B160, 0x2DC02E80, 0xB1403480, 0xB1603000,
+	0x2EA03640, 0x34002D80, 0x3000B120, 0x36E0B160,
+	0x2D202EF0, 0xB1203380, 0xB1603000, 0x2F303780,
+	0x33002CC0, 0x3000B100, 0x3820B160, 0x2C802F50,
+	0xB10032A0, 0xB1603000, 0x2F9038C0, 0x32202C20,
+	0x3000B0E0, 0x3980B160, 0x2BC02FC0, 0xB0E031C0,
+	0xB1603000, 0x2FF03A20, 0x31602B60, 0xB020B0C0,
+	0x3AE0B160, 0x2B001810, 0xB0C03120, 0xB140B020,
+	0x18283BA0, 0x30C02A80, 0xB020B0A0, 0x3C60B140,
+	0x2A201838, 0xB0A03080, 0xB120B020, 0x18383D20,
+	0x304029C0, 0xB040B080, 0x3DE0B100, 0x29601848,
+	0xB0803000, 0xB100B040, 0x18483EC0, 0xB0402900,
+	0xB040B060, 0x3F80B0C0, 0x28801858, 0xB060B080,
+	0xB0A0B060, 0x18602820, 0xB0A02820, 0x0000B060,
+	0xB1403000, 0x2E203500, 0x35002E20, 0x3000B140,
+	0x35A0B160, 0x2DC02E80, 0xB1403480, 0xB1603000,
+	0x2EA03640, 0x34002D80, 0x3000B120, 0x36E0B160,
+	0x2D202EF0, 0xB1203380, 0xB1603000, 0x2F303780,
+	0x33002CC0, 0x3000B100, 0x3820B160, 0x2C802F50,
+	0xB10032A0, 0xB1603000, 0x2F9038C0, 0x32202C20,
+	0x3000B0E0, 0x3980B160, 0x2BC02FC0, 0xB0E031C0,
+	0xB1603000, 0x2FF03A20, 0x31602B60, 0xB020B0C0,
+	0x3AE0B160, 0x2B001810, 0xB0C03120, 0xB140B020,
+	0x18283BA0, 0x30C02A80, 0xB020B0A0, 0x3C60B140,
+	0x2A201838, 0xB0A03080, 0xB120B020, 0x18383D20,
+	0x304029C0, 0xB040B080, 0x3DE0B100, 0x29601848,
+	0xB0803000, 0xB100B040, 0x18483EC0, 0xB0402900,
+	0xB040B060, 0x3F80B0C0, 0x28801858, 0xB060B080,
+	0xB0A0B060, 0x18602820, 0xB0A02820, 0x0000B060,
+	0x36403000, 0x2D002CC0, 0x30003640, 0x2D0036C0,
+	0x35C02CC0, 0x37403000, 0x2C802D40, 0x30003540,
+	0x2D8037C0, 0x34C02C40, 0x38403000, 0x2BC02E00,
+	0x30003440, 0x2E2038C0, 0x34002B80, 0x39803000,
+	0x2B402E40, 0x30003380, 0x2E603A00, 0x33402B00,
+	0x3A803040, 0x2A802EA0, 0x30403300, 0x2EC03B40,
+	0x32802A40, 0x3C003040, 0x2A002EC0, 0x30803240,
+	0x2EC03C80, 0x320029C0, 0x3D403080, 0x29402F00,
+	0x308031C0, 0x2F203DC0, 0x31802900, 0x3E8030C0,
+	0x28802F40, 0x30C03140, 0x2F203F40, 0x31402840,
+	0x28003100, 0x28002F00, 0x00003100, 0x36403000,
+	0x2D002CC0, 0x30003640, 0x2D0036C0,
+	0x35C02CC0, 0x37403000, 0x2C802D40, 0x30003540,
+	0x2D8037C0, 0x34C02C40, 0x38403000, 0x2BC02E00,
+	0x30003440, 0x2E2038C0, 0x34002B80, 0x39803000,
+	0x2B402E40, 0x30003380, 0x2E603A00, 0x33402B00,
+	0x3A803040, 0x2A802EA0, 0x30403300, 0x2EC03B40,
+	0x32802A40, 0x3C003040, 0x2A002EC0, 0x30803240,
+	0x2EC03C80, 0x320029C0, 0x3D403080, 0x29402F00,
+	0x308031C0, 0x2F203DC0, 0x31802900, 0x3E8030C0,
+	0x28802F40, 0x30C03140, 0x2F203F40, 0x31402840,
+	0x28003100, 0x28002F00, 0x00003100,
+};
+
+/*
+ * Color conversion values have 3 separate fixed point formats:
+ *
+ * 10 bit fields (ay, au)
+ *   1.9 fixed point (b.bbbbbbbbb)
+ * 11 bit fields (ry, by, ru, gu, gv)
+ *   exp.mantissa (ee.mmmmmmmmm)
+ *   ee = 00 = 10^-1 (0.mmmmmmmmm)
+ *   ee = 01 = 10^-2 (0.0mmmmmmmmm)
+ *   ee = 10 = 10^-3 (0.00mmmmmmmmm)
+ *   ee = 11 = 10^-4 (0.000mmmmmmmmm)
+ * 12 bit fields (gy, rv, bu)
+ *   exp.mantissa (eee.mmmmmmmmm)
+ *   eee = 000 = 10^-1 (0.mmmmmmmmm)
+ *   eee = 001 = 10^-2 (0.0mmmmmmmmm)
+ *   eee = 010 = 10^-3 (0.00mmmmmmmmm)
+ *   eee = 011 = 10^-4 (0.000mmmmmmmmm)
+ *   eee = 100 = reserved
+ *   eee = 101 = reserved
+ *   eee = 110 = reserved
+ *   eee = 111 = 10^0 (m.mmmmmmmm) (only usable for 1.0 representation)
+ *
+ * Saturation and contrast are 8 bits, with their own representation:
+ * 8 bit field (saturation, contrast)
+ *   exp.mantissa (ee.mmmmmm)
+ *   ee = 00 = 10^-1 (0.mmmmmm)
+ *   ee = 01 = 10^0 (m.mmmmm)
+ *   ee = 10 = 10^1 (mm.mmmm)
+ *   ee = 11 = 10^2 (mmm.mmm)
+ *
+ * Simple conversion function:
+ *
+ * static u32
+ * float_to_csc_11(float f)
+ * {
+ *     u32 exp;
+ *     u32 mant;
+ *     u32 ret;
+ *
+ *     if (f < 0)
+ *         f = -f;
+ *
+ *     if (f >= 1) {
+ *         exp = 0x7;
+ *	   mant = 1 << 8;
+ *     } else {
+ *         for (exp = 0; exp < 3 && f < 0.5; exp++)
+ *	   f *= 2.0;
+ *         mant = (f * (1 << 9) + 0.5);
+ *         if (mant >= (1 << 9))
+ *             mant = (1 << 9) - 1;
+ *     }
+ *     ret = (exp << 9) | mant;
+ *     return ret;
+ * }
+ */
+
+/*
+ * Behold, magic numbers!  If we plant them they might grow a big
+ * s-video cable to the sky... or something.
+ *
+ * Pre-converted to appropriate hex value.
+ */
+
+/*
+ * PAL & NTSC values for composite & s-video connections
+ */
+static const struct color_conversion ntsc_m_csc_composite = {
+	.ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0104,
+	.ru = 0x0733, .gu = 0x052d, .bu = 0x05c7, .au = 0x0200,
+	.rv = 0x0340, .gv = 0x030c, .bv = 0x06d0, .av = 0x0200,
+};
+
+static const struct video_levels ntsc_m_levels_composite = {
+	.blank = 225, .black = 267, .burst = 113,
+};
+
+static const struct color_conversion ntsc_m_csc_svideo = {
+	.ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0133,
+	.ru = 0x076a, .gu = 0x0564, .bu = 0x030d, .au = 0x0200,
+	.rv = 0x037a, .gv = 0x033d, .bv = 0x06f6, .av = 0x0200,
+};
+
+static const struct video_levels ntsc_m_levels_svideo = {
+	.blank = 266, .black = 316, .burst = 133,
+};
+
+static const struct color_conversion ntsc_j_csc_composite = {
+	.ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0119,
+	.ru = 0x074c, .gu = 0x0546, .bu = 0x05ec, .au = 0x0200,
+	.rv = 0x035a, .gv = 0x0322, .bv = 0x06e1, .av = 0x0200,
+};
+
+static const struct video_levels ntsc_j_levels_composite = {
+	.blank = 225, .black = 225, .burst = 113,
+};
+
+static const struct color_conversion ntsc_j_csc_svideo = {
+	.ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x014c,
+	.ru = 0x0788, .gu = 0x0581, .bu = 0x0322, .au = 0x0200,
+	.rv = 0x0399, .gv = 0x0356, .bv = 0x070a, .av = 0x0200,
+};
+
+static const struct video_levels ntsc_j_levels_svideo = {
+	.blank = 266, .black = 266, .burst = 133,
+};
+
+static const struct color_conversion pal_csc_composite = {
+	.ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0113,
+	.ru = 0x0745, .gu = 0x053f, .bu = 0x05e1, .au = 0x0200,
+	.rv = 0x0353, .gv = 0x031c, .bv = 0x06dc, .av = 0x0200,
+};
+
+static const struct video_levels pal_levels_composite = {
+	.blank = 237, .black = 237, .burst = 118,
+};
+
+static const struct color_conversion pal_csc_svideo = {
+	.ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0145,
+	.ru = 0x0780, .gu = 0x0579, .bu = 0x031c, .au = 0x0200,
+	.rv = 0x0390, .gv = 0x034f, .bv = 0x0705, .av = 0x0200,
+};
+
+static const struct video_levels pal_levels_svideo = {
+	.blank = 280, .black = 280, .burst = 139,
+};
+
+static const struct color_conversion pal_m_csc_composite = {
+	.ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0104,
+	.ru = 0x0733, .gu = 0x052d, .bu = 0x05c7, .au = 0x0200,
+	.rv = 0x0340, .gv = 0x030c, .bv = 0x06d0, .av = 0x0200,
+};
+
+static const struct video_levels pal_m_levels_composite = {
+	.blank = 225, .black = 267, .burst = 113,
+};
+
+static const struct color_conversion pal_m_csc_svideo = {
+	.ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0133,
+	.ru = 0x076a, .gu = 0x0564, .bu = 0x030d, .au = 0x0200,
+	.rv = 0x037a, .gv = 0x033d, .bv = 0x06f6, .av = 0x0200,
+};
+
+static const struct video_levels pal_m_levels_svideo = {
+	.blank = 266, .black = 316, .burst = 133,
+};
+
+static const struct color_conversion pal_n_csc_composite = {
+	.ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0104,
+	.ru = 0x0733, .gu = 0x052d, .bu = 0x05c7, .au = 0x0200,
+	.rv = 0x0340, .gv = 0x030c, .bv = 0x06d0, .av = 0x0200,
+};
+
+static const struct video_levels pal_n_levels_composite = {
+	.blank = 225, .black = 267, .burst = 118,
+};
+
+static const struct color_conversion pal_n_csc_svideo = {
+	.ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0133,
+	.ru = 0x076a, .gu = 0x0564, .bu = 0x030d, .au = 0x0200,
+	.rv = 0x037a, .gv = 0x033d, .bv = 0x06f6, .av = 0x0200,
+};
+
+static const struct video_levels pal_n_levels_svideo = {
+	.blank = 266, .black = 316, .burst = 139,
+};
+
+/*
+ * Component connections
+ */
+static const struct color_conversion sdtv_csc_yprpb = {
+	.ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0145,
+	.ru = 0x0559, .gu = 0x0353, .bu = 0x0100, .au = 0x0200,
+	.rv = 0x0100, .gv = 0x03ad, .bv = 0x074d, .av = 0x0200,
+};
+
+static const struct color_conversion hdtv_csc_yprpb = {
+	.ry = 0x05b3, .gy = 0x016e, .by = 0x0728, .ay = 0x0145,
+	.ru = 0x07d5, .gu = 0x038b, .bu = 0x0100, .au = 0x0200,
+	.rv = 0x0100, .gv = 0x03d1, .bv = 0x06bc, .av = 0x0200,
+};
+
+static const struct video_levels component_levels = {
+	.blank = 279, .black = 279, .burst = 0,
+};
+
+
+struct tv_mode {
+	const char *name;
+	int clock;
+	int refresh; /* in millihertz (for precision) */
+	u32 oversample;
+	int hsync_end, hblank_start, hblank_end, htotal;
+	bool progressive, trilevel_sync, component_only;
+	int vsync_start_f1, vsync_start_f2, vsync_len;
+	bool veq_ena;
+	int veq_start_f1, veq_start_f2, veq_len;
+	int vi_end_f1, vi_end_f2, nbr_end;
+	bool burst_ena;
+	int hburst_start, hburst_len;
+	int vburst_start_f1, vburst_end_f1;
+	int vburst_start_f2, vburst_end_f2;
+	int vburst_start_f3, vburst_end_f3;
+	int vburst_start_f4, vburst_end_f4;
+	/*
+	 * subcarrier programming
+	 */
+	int dda2_size, dda3_size, dda1_inc, dda2_inc, dda3_inc;
+	u32 sc_reset;
+	bool pal_burst;
+	/*
+	 * blank/black levels
+	 */
+	const struct video_levels *composite_levels, *svideo_levels;
+	const struct color_conversion *composite_color, *svideo_color;
+	const u32 *filter_table;
+	int max_srcw;
+};
+
+
+/*
+ * Sub carrier DDA
+ *
+ *  I think this works as follows:
+ *
+ *  subcarrier freq = pixel_clock * (dda1_inc + dda2_inc / dda2_size) / 4096
+ *
+ * Presumably, when dda3 is added in, it gets to adjust the dda2_inc value
+ *
+ * So,
+ *  dda1_ideal = subcarrier/pixel * 4096
+ *  dda1_inc = floor (dda1_ideal)
+ *  dda2 = dda1_ideal - dda1_inc
+ *
+ *  then pick a ratio for dda2 that gives the closest approximation. If
+ *  you can't get close enough, you can play with dda3 as well. This
+ *  seems likely to happen when dda2 is small as the jumps would be larger
+ *
+ * To invert this,
+ *
+ *  pixel_clock = subcarrier * 4096 / (dda1_inc + dda2_inc / dda2_size)
+ *
+ * The constants below were all computed using a 107.520MHz clock
+ */
+
+/**
+ * Register programming values for TV modes.
+ *
+ * These values account for -1s required.
+ */
+
+static const struct tv_mode tv_modes[] = {
+	{
+		.name		= "NTSC-M",
+		.clock		= 108000,
+		.refresh	= 59940,
+		.oversample	= TV_OVERSAMPLE_8X,
+		.component_only = 0,
+		/* 525 Lines, 60 Fields, 15.734KHz line, Sub-Carrier 3.580MHz */
+
+		.hsync_end	= 64,		    .hblank_end		= 124,
+		.hblank_start	= 836,		    .htotal		= 857,
+
+		.progressive	= false,	    .trilevel_sync = false,
+
+		.vsync_start_f1	= 6,		    .vsync_start_f2	= 7,
+		.vsync_len	= 6,
+
+		.veq_ena	= true,		    .veq_start_f1	= 0,
+		.veq_start_f2	= 1,		    .veq_len		= 18,
+
+		.vi_end_f1	= 20,		    .vi_end_f2		= 21,
+		.nbr_end	= 240,
+
+		.burst_ena	= true,
+		.hburst_start	= 72,		    .hburst_len		= 34,
+		.vburst_start_f1 = 9,		    .vburst_end_f1	= 240,
+		.vburst_start_f2 = 10,		    .vburst_end_f2	= 240,
+		.vburst_start_f3 = 9,		    .vburst_end_f3	= 240,
+		.vburst_start_f4 = 10,		    .vburst_end_f4	= 240,
+
+		/* desired 3.5800000 actual 3.5800000 clock 107.52 */
+		.dda1_inc	=    135,
+		.dda2_inc	=  20800,	    .dda2_size		=  27456,
+		.dda3_inc	=      0,	    .dda3_size		=      0,
+		.sc_reset	= TV_SC_RESET_EVERY_4,
+		.pal_burst	= false,
+
+		.composite_levels = &ntsc_m_levels_composite,
+		.composite_color = &ntsc_m_csc_composite,
+		.svideo_levels  = &ntsc_m_levels_svideo,
+		.svideo_color = &ntsc_m_csc_svideo,
+
+		.filter_table = filter_table,
+	},
+	{
+		.name		= "NTSC-443",
+		.clock		= 108000,
+		.refresh	= 59940,
+		.oversample	= TV_OVERSAMPLE_8X,
+		.component_only = 0,
+		/* 525 Lines, 60 Fields, 15.734KHz line, Sub-Carrier 4.43MHz */
+		.hsync_end	= 64,		    .hblank_end		= 124,
+		.hblank_start	= 836,		    .htotal		= 857,
+
+		.progressive	= false,	    .trilevel_sync = false,
+
+		.vsync_start_f1 = 6,		    .vsync_start_f2	= 7,
+		.vsync_len	= 6,
+
+		.veq_ena	= true,		    .veq_start_f1	= 0,
+		.veq_start_f2	= 1,		    .veq_len		= 18,
+
+		.vi_end_f1	= 20,		    .vi_end_f2		= 21,
+		.nbr_end	= 240,
+
+		.burst_ena	= true,
+		.hburst_start	= 72,		    .hburst_len		= 34,
+		.vburst_start_f1 = 9,		    .vburst_end_f1	= 240,
+		.vburst_start_f2 = 10,		    .vburst_end_f2	= 240,
+		.vburst_start_f3 = 9,		    .vburst_end_f3	= 240,
+		.vburst_start_f4 = 10,		    .vburst_end_f4	= 240,
+
+		/* desired 4.4336180 actual 4.4336180 clock 107.52 */
+		.dda1_inc       =    168,
+		.dda2_inc       =   4093,       .dda2_size      =  27456,
+		.dda3_inc       =    310,       .dda3_size      =    525,
+		.sc_reset   = TV_SC_RESET_NEVER,
+		.pal_burst  = false,
+
+		.composite_levels = &ntsc_m_levels_composite,
+		.composite_color = &ntsc_m_csc_composite,
+		.svideo_levels  = &ntsc_m_levels_svideo,
+		.svideo_color = &ntsc_m_csc_svideo,
+
+		.filter_table = filter_table,
+	},
+	{
+		.name		= "NTSC-J",
+		.clock		= 108000,
+		.refresh	= 59940,
+		.oversample	= TV_OVERSAMPLE_8X,
+		.component_only = 0,
+
+		/* 525 Lines, 60 Fields, 15.734KHz line, Sub-Carrier 3.580MHz */
+		.hsync_end	= 64,		    .hblank_end		= 124,
+		.hblank_start = 836,	    .htotal		= 857,
+
+		.progressive	= false,    .trilevel_sync = false,
+
+		.vsync_start_f1	= 6,	    .vsync_start_f2	= 7,
+		.vsync_len	= 6,
+
+		.veq_ena      = true,	    .veq_start_f1	= 0,
+		.veq_start_f2 = 1,	    .veq_len		= 18,
+
+		.vi_end_f1	= 20,		    .vi_end_f2		= 21,
+		.nbr_end	= 240,
+
+		.burst_ena	= true,
+		.hburst_start	= 72,		    .hburst_len		= 34,
+		.vburst_start_f1 = 9,		    .vburst_end_f1	= 240,
+		.vburst_start_f2 = 10,		    .vburst_end_f2	= 240,
+		.vburst_start_f3 = 9,		    .vburst_end_f3	= 240,
+		.vburst_start_f4 = 10,		    .vburst_end_f4	= 240,
+
+		/* desired 3.5800000 actual 3.5800000 clock 107.52 */
+		.dda1_inc	=    135,
+		.dda2_inc	=  20800,	    .dda2_size		=  27456,
+		.dda3_inc	=      0,	    .dda3_size		=      0,
+		.sc_reset	= TV_SC_RESET_EVERY_4,
+		.pal_burst	= false,
+
+		.composite_levels = &ntsc_j_levels_composite,
+		.composite_color = &ntsc_j_csc_composite,
+		.svideo_levels  = &ntsc_j_levels_svideo,
+		.svideo_color = &ntsc_j_csc_svideo,
+
+		.filter_table = filter_table,
+	},
+	{
+		.name		= "PAL-M",
+		.clock		= 108000,
+		.refresh	= 59940,
+		.oversample	= TV_OVERSAMPLE_8X,
+		.component_only = 0,
+
+		/* 525 Lines, 60 Fields, 15.734KHz line, Sub-Carrier 3.580MHz */
+		.hsync_end	= 64,		  .hblank_end		= 124,
+		.hblank_start = 836,	  .htotal		= 857,
+
+		.progressive	= false,	    .trilevel_sync = false,
+
+		.vsync_start_f1	= 6,		    .vsync_start_f2	= 7,
+		.vsync_len	= 6,
+
+		.veq_ena	= true,		    .veq_start_f1	= 0,
+		.veq_start_f2	= 1,		    .veq_len		= 18,
+
+		.vi_end_f1	= 20,		    .vi_end_f2		= 21,
+		.nbr_end	= 240,
+
+		.burst_ena	= true,
+		.hburst_start	= 72,		    .hburst_len		= 34,
+		.vburst_start_f1 = 9,		    .vburst_end_f1	= 240,
+		.vburst_start_f2 = 10,		    .vburst_end_f2	= 240,
+		.vburst_start_f3 = 9,		    .vburst_end_f3	= 240,
+		.vburst_start_f4 = 10,		    .vburst_end_f4	= 240,
+
+		/* desired 3.5800000 actual 3.5800000 clock 107.52 */
+		.dda1_inc	=    135,
+		.dda2_inc	=  16704,	    .dda2_size		=  27456,
+		.dda3_inc	=      0,	    .dda3_size		=      0,
+		.sc_reset	= TV_SC_RESET_EVERY_8,
+		.pal_burst  = true,
+
+		.composite_levels = &pal_m_levels_composite,
+		.composite_color = &pal_m_csc_composite,
+		.svideo_levels  = &pal_m_levels_svideo,
+		.svideo_color = &pal_m_csc_svideo,
+
+		.filter_table = filter_table,
+	},
+	{
+		/* 625 Lines, 50 Fields, 15.625KHz line, Sub-Carrier 4.434MHz */
+		.name	    = "PAL-N",
+		.clock		= 108000,
+		.refresh	= 50000,
+		.oversample	= TV_OVERSAMPLE_8X,
+		.component_only = 0,
+
+		.hsync_end	= 64,		    .hblank_end		= 128,
+		.hblank_start = 844,	    .htotal		= 863,
+
+		.progressive  = false,    .trilevel_sync = false,
+
+
+		.vsync_start_f1	= 6,	   .vsync_start_f2	= 7,
+		.vsync_len	= 6,
+
+		.veq_ena	= true,		    .veq_start_f1	= 0,
+		.veq_start_f2	= 1,		    .veq_len		= 18,
+
+		.vi_end_f1	= 24,		    .vi_end_f2		= 25,
+		.nbr_end	= 286,
+
+		.burst_ena	= true,
+		.hburst_start = 73,	    .hburst_len		= 34,
+		.vburst_start_f1 = 8,	    .vburst_end_f1	= 285,
+		.vburst_start_f2 = 8,	    .vburst_end_f2	= 286,
+		.vburst_start_f3 = 9,	    .vburst_end_f3	= 286,
+		.vburst_start_f4 = 9,	    .vburst_end_f4	= 285,
+
+
+		/* desired 4.4336180 actual 4.4336180 clock 107.52 */
+		.dda1_inc       =    135,
+		.dda2_inc       =  23578,       .dda2_size      =  27648,
+		.dda3_inc       =    134,       .dda3_size      =    625,
+		.sc_reset   = TV_SC_RESET_EVERY_8,
+		.pal_burst  = true,
+
+		.composite_levels = &pal_n_levels_composite,
+		.composite_color = &pal_n_csc_composite,
+		.svideo_levels  = &pal_n_levels_svideo,
+		.svideo_color = &pal_n_csc_svideo,
+
+		.filter_table = filter_table,
+	},
+	{
+		/* 625 Lines, 50 Fields, 15.625KHz line, Sub-Carrier 4.434MHz */
+		.name	    = "PAL",
+		.clock		= 108000,
+		.refresh	= 50000,
+		.oversample	= TV_OVERSAMPLE_8X,
+		.component_only = 0,
+
+		.hsync_end	= 64,		    .hblank_end		= 142,
+		.hblank_start	= 844,	    .htotal		= 863,
+
+		.progressive	= false,    .trilevel_sync = false,
+
+		.vsync_start_f1	= 5,	    .vsync_start_f2	= 6,
+		.vsync_len	= 5,
+
+		.veq_ena	= true,	    .veq_start_f1	= 0,
+		.veq_start_f2	= 1,	    .veq_len		= 15,
+
+		.vi_end_f1	= 24,		    .vi_end_f2		= 25,
+		.nbr_end	= 286,
+
+		.burst_ena	= true,
+		.hburst_start	= 73,		    .hburst_len		= 32,
+		.vburst_start_f1 = 8,		    .vburst_end_f1	= 285,
+		.vburst_start_f2 = 8,		    .vburst_end_f2	= 286,
+		.vburst_start_f3 = 9,		    .vburst_end_f3	= 286,
+		.vburst_start_f4 = 9,		    .vburst_end_f4	= 285,
+
+		/* desired 4.4336180 actual 4.4336180 clock 107.52 */
+		.dda1_inc       =    168,
+		.dda2_inc       =   4122,       .dda2_size      =  27648,
+		.dda3_inc       =     67,       .dda3_size      =    625,
+		.sc_reset   = TV_SC_RESET_EVERY_8,
+		.pal_burst  = true,
+
+		.composite_levels = &pal_levels_composite,
+		.composite_color = &pal_csc_composite,
+		.svideo_levels  = &pal_levels_svideo,
+		.svideo_color = &pal_csc_svideo,
+
+		.filter_table = filter_table,
+	},
+	{
+		.name       = "480p",
+		.clock		= 107520,
+		.refresh	= 59940,
+		.oversample     = TV_OVERSAMPLE_4X,
+		.component_only = 1,
+
+		.hsync_end      = 64,               .hblank_end         = 122,
+		.hblank_start   = 842,              .htotal             = 857,
+
+		.progressive    = true,		    .trilevel_sync = false,
+
+		.vsync_start_f1 = 12,               .vsync_start_f2     = 12,
+		.vsync_len      = 12,
+
+		.veq_ena        = false,
+
+		.vi_end_f1      = 44,               .vi_end_f2          = 44,
+		.nbr_end        = 479,
+
+		.burst_ena      = false,
+
+		.filter_table = filter_table,
+	},
+	{
+		.name       = "576p",
+		.clock		= 107520,
+		.refresh	= 50000,
+		.oversample     = TV_OVERSAMPLE_4X,
+		.component_only = 1,
+
+		.hsync_end      = 64,               .hblank_end         = 139,
+		.hblank_start   = 859,              .htotal             = 863,
+
+		.progressive    = true,		    .trilevel_sync = false,
+
+		.vsync_start_f1 = 10,               .vsync_start_f2     = 10,
+		.vsync_len      = 10,
+
+		.veq_ena        = false,
+
+		.vi_end_f1      = 48,               .vi_end_f2          = 48,
+		.nbr_end        = 575,
+
+		.burst_ena      = false,
+
+		.filter_table = filter_table,
+	},
+	{
+		.name       = "720p@60Hz",
+		.clock		= 148800,
+		.refresh	= 60000,
+		.oversample     = TV_OVERSAMPLE_2X,
+		.component_only = 1,
+
+		.hsync_end      = 80,               .hblank_end         = 300,
+		.hblank_start   = 1580,             .htotal             = 1649,
+
+		.progressive	= true,		    .trilevel_sync = true,
+
+		.vsync_start_f1 = 10,               .vsync_start_f2     = 10,
+		.vsync_len      = 10,
+
+		.veq_ena        = false,
+
+		.vi_end_f1      = 29,               .vi_end_f2          = 29,
+		.nbr_end        = 719,
+
+		.burst_ena      = false,
+
+		.filter_table = filter_table,
+	},
+	{
+		.name       = "720p@50Hz",
+		.clock		= 148800,
+		.refresh	= 50000,
+		.oversample     = TV_OVERSAMPLE_2X,
+		.component_only = 1,
+
+		.hsync_end      = 80,               .hblank_end         = 300,
+		.hblank_start   = 1580,             .htotal             = 1979,
+
+		.progressive	= true,		    .trilevel_sync = true,
+
+		.vsync_start_f1 = 10,               .vsync_start_f2     = 10,
+		.vsync_len      = 10,
+
+		.veq_ena        = false,
+
+		.vi_end_f1      = 29,               .vi_end_f2          = 29,
+		.nbr_end        = 719,
+
+		.burst_ena      = false,
+
+		.filter_table = filter_table,
+		.max_srcw = 800
+	},
+	{
+		.name       = "1080i@50Hz",
+		.clock		= 148800,
+		.refresh	= 50000,
+		.oversample     = TV_OVERSAMPLE_2X,
+		.component_only = 1,
+
+		.hsync_end      = 88,               .hblank_end         = 235,
+		.hblank_start   = 2155,             .htotal             = 2639,
+
+		.progressive	= false,	  .trilevel_sync = true,
+
+		.vsync_start_f1 = 4,              .vsync_start_f2     = 5,
+		.vsync_len      = 10,
+
+		.veq_ena	= true,	    .veq_start_f1	= 4,
+		.veq_start_f2   = 4,	    .veq_len		= 10,
+
+
+		.vi_end_f1      = 21,           .vi_end_f2          = 22,
+		.nbr_end        = 539,
+
+		.burst_ena      = false,
+
+		.filter_table = filter_table,
+	},
+	{
+		.name       = "1080i@60Hz",
+		.clock		= 148800,
+		.refresh	= 60000,
+		.oversample     = TV_OVERSAMPLE_2X,
+		.component_only = 1,
+
+		.hsync_end      = 88,               .hblank_end         = 235,
+		.hblank_start   = 2155,             .htotal             = 2199,
+
+		.progressive	= false,	    .trilevel_sync = true,
+
+		.vsync_start_f1 = 4,               .vsync_start_f2     = 5,
+		.vsync_len      = 10,
+
+		.veq_ena	= true,		    .veq_start_f1	= 4,
+		.veq_start_f2	= 4,		    .veq_len		= 10,
+
+
+		.vi_end_f1      = 21,               .vi_end_f2          = 22,
+		.nbr_end        = 539,
+
+		.burst_ena      = false,
+
+		.filter_table = filter_table,
+	},
+};
+
+static struct intel_tv *enc_to_tv(struct intel_encoder *encoder)
+{
+	return container_of(encoder, struct intel_tv, base);
+}
+
+static struct intel_tv *intel_attached_tv(struct drm_connector *connector)
+{
+	return enc_to_tv(intel_attached_encoder(connector));
+}
+
+static bool
+intel_tv_get_hw_state(struct intel_encoder *encoder, enum pipe *pipe)
+{
+	struct drm_device *dev = encoder->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	u32 tmp = I915_READ(TV_CTL);
+
+	if (!(tmp & TV_ENC_ENABLE))
+		return false;
+
+	*pipe = PORT_TO_PIPE(tmp);
+
+	return true;
+}
+
+static void
+intel_enable_tv(struct intel_encoder *encoder)
+{
+	struct drm_device *dev = encoder->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	/* Prevents vblank waits from timing out in intel_tv_detect_type() */
+	intel_wait_for_vblank(encoder->base.dev,
+			      to_intel_crtc(encoder->base.crtc)->pipe);
+
+	I915_WRITE(TV_CTL, I915_READ(TV_CTL) | TV_ENC_ENABLE);
+}
+
+static void
+intel_disable_tv(struct intel_encoder *encoder)
+{
+	struct drm_device *dev = encoder->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	I915_WRITE(TV_CTL, I915_READ(TV_CTL) & ~TV_ENC_ENABLE);
+}
+
+static const struct tv_mode *
+intel_tv_mode_lookup(const char *tv_format)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(tv_modes); i++) {
+		const struct tv_mode *tv_mode = &tv_modes[i];
+
+		if (!strcmp(tv_format, tv_mode->name))
+			return tv_mode;
+	}
+	return NULL;
+}
+
+static const struct tv_mode *
+intel_tv_mode_find(struct intel_tv *intel_tv)
+{
+	return intel_tv_mode_lookup(intel_tv->tv_format);
+}
+
+static enum drm_mode_status
+intel_tv_mode_valid(struct drm_connector *connector,
+		    struct drm_display_mode *mode)
+{
+	struct intel_tv *intel_tv = intel_attached_tv(connector);
+	const struct tv_mode *tv_mode = intel_tv_mode_find(intel_tv);
+	int max_dotclk = to_i915(connector->dev)->max_dotclk_freq;
+
+	if (mode->clock > max_dotclk)
+		return MODE_CLOCK_HIGH;
+
+	/* Ensure TV refresh is close to desired refresh */
+	if (tv_mode && abs(tv_mode->refresh - drm_mode_vrefresh(mode) * 1000)
+				< 1000)
+		return MODE_OK;
+
+	return MODE_CLOCK_RANGE;
+}
+
+
+static void
+intel_tv_get_config(struct intel_encoder *encoder,
+		    struct intel_crtc_state *pipe_config)
+{
+	pipe_config->base.adjusted_mode.crtc_clock = pipe_config->port_clock;
+}
+
+static bool
+intel_tv_compute_config(struct intel_encoder *encoder,
+			struct intel_crtc_state *pipe_config)
+{
+	struct intel_tv *intel_tv = enc_to_tv(encoder);
+	const struct tv_mode *tv_mode = intel_tv_mode_find(intel_tv);
+
+	if (!tv_mode)
+		return false;
+
+	pipe_config->base.adjusted_mode.crtc_clock = tv_mode->clock;
+	DRM_DEBUG_KMS("forcing bpc to 8 for TV\n");
+	pipe_config->pipe_bpp = 8*3;
+
+	/* TV has it's own notion of sync and other mode flags, so clear them. */
+	pipe_config->base.adjusted_mode.flags = 0;
+
+	/*
+	 * FIXME: We don't check whether the input mode is actually what we want
+	 * or whether userspace is doing something stupid.
+	 */
+
+	return true;
+}
+
+static void
+set_tv_mode_timings(struct drm_i915_private *dev_priv,
+		    const struct tv_mode *tv_mode,
+		    bool burst_ena)
+{
+	u32 hctl1, hctl2, hctl3;
+	u32 vctl1, vctl2, vctl3, vctl4, vctl5, vctl6, vctl7;
+
+	hctl1 = (tv_mode->hsync_end << TV_HSYNC_END_SHIFT) |
+		(tv_mode->htotal << TV_HTOTAL_SHIFT);
+
+	hctl2 = (tv_mode->hburst_start << 16) |
+		(tv_mode->hburst_len << TV_HBURST_LEN_SHIFT);
+
+	if (burst_ena)
+		hctl2 |= TV_BURST_ENA;
+
+	hctl3 = (tv_mode->hblank_start << TV_HBLANK_START_SHIFT) |
+		(tv_mode->hblank_end << TV_HBLANK_END_SHIFT);
+
+	vctl1 = (tv_mode->nbr_end << TV_NBR_END_SHIFT) |
+		(tv_mode->vi_end_f1 << TV_VI_END_F1_SHIFT) |
+		(tv_mode->vi_end_f2 << TV_VI_END_F2_SHIFT);
+
+	vctl2 = (tv_mode->vsync_len << TV_VSYNC_LEN_SHIFT) |
+		(tv_mode->vsync_start_f1 << TV_VSYNC_START_F1_SHIFT) |
+		(tv_mode->vsync_start_f2 << TV_VSYNC_START_F2_SHIFT);
+
+	vctl3 = (tv_mode->veq_len << TV_VEQ_LEN_SHIFT) |
+		(tv_mode->veq_start_f1 << TV_VEQ_START_F1_SHIFT) |
+		(tv_mode->veq_start_f2 << TV_VEQ_START_F2_SHIFT);
+
+	if (tv_mode->veq_ena)
+		vctl3 |= TV_EQUAL_ENA;
+
+	vctl4 = (tv_mode->vburst_start_f1 << TV_VBURST_START_F1_SHIFT) |
+		(tv_mode->vburst_end_f1 << TV_VBURST_END_F1_SHIFT);
+
+	vctl5 = (tv_mode->vburst_start_f2 << TV_VBURST_START_F2_SHIFT) |
+		(tv_mode->vburst_end_f2 << TV_VBURST_END_F2_SHIFT);
+
+	vctl6 = (tv_mode->vburst_start_f3 << TV_VBURST_START_F3_SHIFT) |
+		(tv_mode->vburst_end_f3 << TV_VBURST_END_F3_SHIFT);
+
+	vctl7 = (tv_mode->vburst_start_f4 << TV_VBURST_START_F4_SHIFT) |
+		(tv_mode->vburst_end_f4 << TV_VBURST_END_F4_SHIFT);
+
+	I915_WRITE(TV_H_CTL_1, hctl1);
+	I915_WRITE(TV_H_CTL_2, hctl2);
+	I915_WRITE(TV_H_CTL_3, hctl3);
+	I915_WRITE(TV_V_CTL_1, vctl1);
+	I915_WRITE(TV_V_CTL_2, vctl2);
+	I915_WRITE(TV_V_CTL_3, vctl3);
+	I915_WRITE(TV_V_CTL_4, vctl4);
+	I915_WRITE(TV_V_CTL_5, vctl5);
+	I915_WRITE(TV_V_CTL_6, vctl6);
+	I915_WRITE(TV_V_CTL_7, vctl7);
+}
+
+static void set_color_conversion(struct drm_i915_private *dev_priv,
+				 const struct color_conversion *color_conversion)
+{
+	if (!color_conversion)
+		return;
+
+	I915_WRITE(TV_CSC_Y, (color_conversion->ry << 16) |
+		   color_conversion->gy);
+	I915_WRITE(TV_CSC_Y2, (color_conversion->by << 16) |
+		   color_conversion->ay);
+	I915_WRITE(TV_CSC_U, (color_conversion->ru << 16) |
+		   color_conversion->gu);
+	I915_WRITE(TV_CSC_U2, (color_conversion->bu << 16) |
+		   color_conversion->au);
+	I915_WRITE(TV_CSC_V, (color_conversion->rv << 16) |
+		   color_conversion->gv);
+	I915_WRITE(TV_CSC_V2, (color_conversion->bv << 16) |
+		   color_conversion->av);
+}
+
+static void intel_tv_pre_enable(struct intel_encoder *encoder)
+{
+	struct drm_device *dev = encoder->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc);
+	struct intel_tv *intel_tv = enc_to_tv(encoder);
+	const struct tv_mode *tv_mode = intel_tv_mode_find(intel_tv);
+	u32 tv_ctl;
+	u32 scctl1, scctl2, scctl3;
+	int i, j;
+	const struct video_levels *video_levels;
+	const struct color_conversion *color_conversion;
+	bool burst_ena;
+	int xpos = 0x0, ypos = 0x0;
+	unsigned int xsize, ysize;
+
+	if (!tv_mode)
+		return;	/* can't happen (mode_prepare prevents this) */
+
+	tv_ctl = I915_READ(TV_CTL);
+	tv_ctl &= TV_CTL_SAVE;
+
+	switch (intel_tv->type) {
+	default:
+	case DRM_MODE_CONNECTOR_Unknown:
+	case DRM_MODE_CONNECTOR_Composite:
+		tv_ctl |= TV_ENC_OUTPUT_COMPOSITE;
+		video_levels = tv_mode->composite_levels;
+		color_conversion = tv_mode->composite_color;
+		burst_ena = tv_mode->burst_ena;
+		break;
+	case DRM_MODE_CONNECTOR_Component:
+		tv_ctl |= TV_ENC_OUTPUT_COMPONENT;
+		video_levels = &component_levels;
+		if (tv_mode->burst_ena)
+			color_conversion = &sdtv_csc_yprpb;
+		else
+			color_conversion = &hdtv_csc_yprpb;
+		burst_ena = false;
+		break;
+	case DRM_MODE_CONNECTOR_SVIDEO:
+		tv_ctl |= TV_ENC_OUTPUT_SVIDEO;
+		video_levels = tv_mode->svideo_levels;
+		color_conversion = tv_mode->svideo_color;
+		burst_ena = tv_mode->burst_ena;
+		break;
+	}
+
+	if (intel_crtc->pipe == 1)
+		tv_ctl |= TV_ENC_PIPEB_SELECT;
+	tv_ctl |= tv_mode->oversample;
+
+	if (tv_mode->progressive)
+		tv_ctl |= TV_PROGRESSIVE;
+	if (tv_mode->trilevel_sync)
+		tv_ctl |= TV_TRILEVEL_SYNC;
+	if (tv_mode->pal_burst)
+		tv_ctl |= TV_PAL_BURST;
+
+	scctl1 = 0;
+	if (tv_mode->dda1_inc)
+		scctl1 |= TV_SC_DDA1_EN;
+	if (tv_mode->dda2_inc)
+		scctl1 |= TV_SC_DDA2_EN;
+	if (tv_mode->dda3_inc)
+		scctl1 |= TV_SC_DDA3_EN;
+	scctl1 |= tv_mode->sc_reset;
+	if (video_levels)
+		scctl1 |= video_levels->burst << TV_BURST_LEVEL_SHIFT;
+	scctl1 |= tv_mode->dda1_inc << TV_SCDDA1_INC_SHIFT;
+
+	scctl2 = tv_mode->dda2_size << TV_SCDDA2_SIZE_SHIFT |
+		tv_mode->dda2_inc << TV_SCDDA2_INC_SHIFT;
+
+	scctl3 = tv_mode->dda3_size << TV_SCDDA3_SIZE_SHIFT |
+		tv_mode->dda3_inc << TV_SCDDA3_INC_SHIFT;
+
+	/* Enable two fixes for the chips that need them. */
+	if (IS_I915GM(dev))
+		tv_ctl |= TV_ENC_C0_FIX | TV_ENC_SDP_FIX;
+
+	set_tv_mode_timings(dev_priv, tv_mode, burst_ena);
+
+	I915_WRITE(TV_SC_CTL_1, scctl1);
+	I915_WRITE(TV_SC_CTL_2, scctl2);
+	I915_WRITE(TV_SC_CTL_3, scctl3);
+
+	set_color_conversion(dev_priv, color_conversion);
+
+	if (INTEL_INFO(dev)->gen >= 4)
+		I915_WRITE(TV_CLR_KNOBS, 0x00404000);
+	else
+		I915_WRITE(TV_CLR_KNOBS, 0x00606000);
+
+	if (video_levels)
+		I915_WRITE(TV_CLR_LEVEL,
+			   ((video_levels->black << TV_BLACK_LEVEL_SHIFT) |
+			    (video_levels->blank << TV_BLANK_LEVEL_SHIFT)));
+
+	assert_pipe_disabled(dev_priv, intel_crtc->pipe);
+
+	/* Filter ctl must be set before TV_WIN_SIZE */
+	I915_WRITE(TV_FILTER_CTL_1, TV_AUTO_SCALE);
+	xsize = tv_mode->hblank_start - tv_mode->hblank_end;
+	if (tv_mode->progressive)
+		ysize = tv_mode->nbr_end + 1;
+	else
+		ysize = 2*tv_mode->nbr_end + 1;
+
+	xpos += intel_tv->margin[TV_MARGIN_LEFT];
+	ypos += intel_tv->margin[TV_MARGIN_TOP];
+	xsize -= (intel_tv->margin[TV_MARGIN_LEFT] +
+		  intel_tv->margin[TV_MARGIN_RIGHT]);
+	ysize -= (intel_tv->margin[TV_MARGIN_TOP] +
+		  intel_tv->margin[TV_MARGIN_BOTTOM]);
+	I915_WRITE(TV_WIN_POS, (xpos<<16)|ypos);
+	I915_WRITE(TV_WIN_SIZE, (xsize<<16)|ysize);
+
+	j = 0;
+	for (i = 0; i < 60; i++)
+		I915_WRITE(TV_H_LUMA(i), tv_mode->filter_table[j++]);
+	for (i = 0; i < 60; i++)
+		I915_WRITE(TV_H_CHROMA(i), tv_mode->filter_table[j++]);
+	for (i = 0; i < 43; i++)
+		I915_WRITE(TV_V_LUMA(i), tv_mode->filter_table[j++]);
+	for (i = 0; i < 43; i++)
+		I915_WRITE(TV_V_CHROMA(i), tv_mode->filter_table[j++]);
+	I915_WRITE(TV_DAC, I915_READ(TV_DAC) & TV_DAC_SAVE);
+	I915_WRITE(TV_CTL, tv_ctl);
+}
+
+static const struct drm_display_mode reported_modes[] = {
+	{
+		.name = "NTSC 480i",
+		.clock = 107520,
+		.hdisplay = 1280,
+		.hsync_start = 1368,
+		.hsync_end = 1496,
+		.htotal = 1712,
+
+		.vdisplay = 1024,
+		.vsync_start = 1027,
+		.vsync_end = 1034,
+		.vtotal = 1104,
+		.type = DRM_MODE_TYPE_DRIVER,
+	},
+};
+
+/**
+ * Detects TV presence by checking for load.
+ *
+ * Requires that the current pipe's DPLL is active.
+
+ * \return true if TV is connected.
+ * \return false if TV is disconnected.
+ */
+static int
+intel_tv_detect_type(struct intel_tv *intel_tv,
+		      struct drm_connector *connector)
+{
+	struct drm_crtc *crtc = connector->state->crtc;
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	struct drm_device *dev = connector->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	u32 tv_ctl, save_tv_ctl;
+	u32 tv_dac, save_tv_dac;
+	int type;
+
+	/* Disable TV interrupts around load detect or we'll recurse */
+	if (connector->polled & DRM_CONNECTOR_POLL_HPD) {
+		spin_lock_irq(&dev_priv->irq_lock);
+		i915_disable_pipestat(dev_priv, 0,
+				      PIPE_HOTPLUG_INTERRUPT_STATUS |
+				      PIPE_HOTPLUG_TV_INTERRUPT_STATUS);
+		spin_unlock_irq(&dev_priv->irq_lock);
+	}
+
+	save_tv_dac = tv_dac = I915_READ(TV_DAC);
+	save_tv_ctl = tv_ctl = I915_READ(TV_CTL);
+
+	/* Poll for TV detection */
+	tv_ctl &= ~(TV_ENC_ENABLE | TV_TEST_MODE_MASK);
+	tv_ctl |= TV_TEST_MODE_MONITOR_DETECT;
+	if (intel_crtc->pipe == 1)
+		tv_ctl |= TV_ENC_PIPEB_SELECT;
+	else
+		tv_ctl &= ~TV_ENC_PIPEB_SELECT;
+
+	tv_dac &= ~(TVDAC_SENSE_MASK | DAC_A_MASK | DAC_B_MASK | DAC_C_MASK);
+	tv_dac |= (TVDAC_STATE_CHG_EN |
+		   TVDAC_A_SENSE_CTL |
+		   TVDAC_B_SENSE_CTL |
+		   TVDAC_C_SENSE_CTL |
+		   DAC_CTL_OVERRIDE |
+		   DAC_A_0_7_V |
+		   DAC_B_0_7_V |
+		   DAC_C_0_7_V);
+
+
+	/*
+	 * The TV sense state should be cleared to zero on cantiga platform. Otherwise
+	 * the TV is misdetected. This is hardware requirement.
+	 */
+	if (IS_GM45(dev))
+		tv_dac &= ~(TVDAC_STATE_CHG_EN | TVDAC_A_SENSE_CTL |
+			    TVDAC_B_SENSE_CTL | TVDAC_C_SENSE_CTL);
+
+	I915_WRITE(TV_CTL, tv_ctl);
+	I915_WRITE(TV_DAC, tv_dac);
+	POSTING_READ(TV_DAC);
+
+	intel_wait_for_vblank(dev, intel_crtc->pipe);
+
+	type = -1;
+	tv_dac = I915_READ(TV_DAC);
+	DRM_DEBUG_KMS("TV detected: %x, %x\n", tv_ctl, tv_dac);
+	/*
+	 *  A B C
+	 *  0 1 1 Composite
+	 *  1 0 X svideo
+	 *  0 0 0 Component
+	 */
+	if ((tv_dac & TVDAC_SENSE_MASK) == (TVDAC_B_SENSE | TVDAC_C_SENSE)) {
+		DRM_DEBUG_KMS("Detected Composite TV connection\n");
+		type = DRM_MODE_CONNECTOR_Composite;
+	} else if ((tv_dac & (TVDAC_A_SENSE|TVDAC_B_SENSE)) == TVDAC_A_SENSE) {
+		DRM_DEBUG_KMS("Detected S-Video TV connection\n");
+		type = DRM_MODE_CONNECTOR_SVIDEO;
+	} else if ((tv_dac & TVDAC_SENSE_MASK) == 0) {
+		DRM_DEBUG_KMS("Detected Component TV connection\n");
+		type = DRM_MODE_CONNECTOR_Component;
+	} else {
+		DRM_DEBUG_KMS("Unrecognised TV connection\n");
+		type = -1;
+	}
+
+	I915_WRITE(TV_DAC, save_tv_dac & ~TVDAC_STATE_CHG_EN);
+	I915_WRITE(TV_CTL, save_tv_ctl);
+	POSTING_READ(TV_CTL);
+
+	/* For unknown reasons the hw barfs if we don't do this vblank wait. */
+	intel_wait_for_vblank(dev, intel_crtc->pipe);
+
+	/* Restore interrupt config */
+	if (connector->polled & DRM_CONNECTOR_POLL_HPD) {
+		spin_lock_irq(&dev_priv->irq_lock);
+		i915_enable_pipestat(dev_priv, 0,
+				     PIPE_HOTPLUG_INTERRUPT_STATUS |
+				     PIPE_HOTPLUG_TV_INTERRUPT_STATUS);
+		spin_unlock_irq(&dev_priv->irq_lock);
+	}
+
+	return type;
+}
+
+/*
+ * Here we set accurate tv format according to connector type
+ * i.e Component TV should not be assigned by NTSC or PAL
+ */
+static void intel_tv_find_better_format(struct drm_connector *connector)
+{
+	struct intel_tv *intel_tv = intel_attached_tv(connector);
+	const struct tv_mode *tv_mode = intel_tv_mode_find(intel_tv);
+	int i;
+
+	if ((intel_tv->type == DRM_MODE_CONNECTOR_Component) ==
+		tv_mode->component_only)
+		return;
+
+
+	for (i = 0; i < ARRAY_SIZE(tv_modes); i++) {
+		tv_mode = tv_modes + i;
+
+		if ((intel_tv->type == DRM_MODE_CONNECTOR_Component) ==
+			tv_mode->component_only)
+			break;
+	}
+
+	intel_tv->tv_format = tv_mode->name;
+	drm_object_property_set_value(&connector->base,
+		connector->dev->mode_config.tv_mode_property, i);
+}
+
+/**
+ * Detect the TV connection.
+ *
+ * Currently this always returns CONNECTOR_STATUS_UNKNOWN, as we need to be sure
+ * we have a pipe programmed in order to probe the TV.
+ */
+static enum drm_connector_status
+intel_tv_detect(struct drm_connector *connector, bool force)
+{
+	struct drm_display_mode mode;
+	struct intel_tv *intel_tv = intel_attached_tv(connector);
+	enum drm_connector_status status;
+	int type;
+
+	DRM_DEBUG_KMS("[CONNECTOR:%d:%s] force=%d\n",
+		      connector->base.id, connector->name,
+		      force);
+
+	mode = reported_modes[0];
+
+	if (force) {
+		struct intel_load_detect_pipe tmp;
+		struct drm_modeset_acquire_ctx ctx;
+
+		drm_modeset_acquire_init(&ctx, 0);
+
+		if (intel_get_load_detect_pipe(connector, &mode, &tmp, &ctx)) {
+			type = intel_tv_detect_type(intel_tv, connector);
+			intel_release_load_detect_pipe(connector, &tmp, &ctx);
+			status = type < 0 ?
+				connector_status_disconnected :
+				connector_status_connected;
+		} else
+			status = connector_status_unknown;
+
+		drm_modeset_drop_locks(&ctx);
+		drm_modeset_acquire_fini(&ctx);
+	} else
+		return connector->status;
+
+	if (status != connector_status_connected)
+		return status;
+
+	intel_tv->type = type;
+	intel_tv_find_better_format(connector);
+
+	return connector_status_connected;
+}
+
+static const struct input_res {
+	const char *name;
+	int w, h;
+} input_res_table[] = {
+	{"640x480", 640, 480},
+	{"800x600", 800, 600},
+	{"1024x768", 1024, 768},
+	{"1280x1024", 1280, 1024},
+	{"848x480", 848, 480},
+	{"1280x720", 1280, 720},
+	{"1920x1080", 1920, 1080},
+};
+
+/*
+ * Chose preferred mode  according to line number of TV format
+ */
+static void
+intel_tv_chose_preferred_modes(struct drm_connector *connector,
+			       struct drm_display_mode *mode_ptr)
+{
+	struct intel_tv *intel_tv = intel_attached_tv(connector);
+	const struct tv_mode *tv_mode = intel_tv_mode_find(intel_tv);
+
+	if (tv_mode->nbr_end < 480 && mode_ptr->vdisplay == 480)
+		mode_ptr->type |= DRM_MODE_TYPE_PREFERRED;
+	else if (tv_mode->nbr_end > 480) {
+		if (tv_mode->progressive == true && tv_mode->nbr_end < 720) {
+			if (mode_ptr->vdisplay == 720)
+				mode_ptr->type |= DRM_MODE_TYPE_PREFERRED;
+		} else if (mode_ptr->vdisplay == 1080)
+				mode_ptr->type |= DRM_MODE_TYPE_PREFERRED;
+	}
+}
+
+/**
+ * Stub get_modes function.
+ *
+ * This should probably return a set of fixed modes, unless we can figure out
+ * how to probe modes off of TV connections.
+ */
+
+static int
+intel_tv_get_modes(struct drm_connector *connector)
+{
+	struct drm_display_mode *mode_ptr;
+	struct intel_tv *intel_tv = intel_attached_tv(connector);
+	const struct tv_mode *tv_mode = intel_tv_mode_find(intel_tv);
+	int j, count = 0;
+	u64 tmp;
+
+	for (j = 0; j < ARRAY_SIZE(input_res_table);
+	     j++) {
+		const struct input_res *input = &input_res_table[j];
+		unsigned int hactive_s = input->w;
+		unsigned int vactive_s = input->h;
+
+		if (tv_mode->max_srcw && input->w > tv_mode->max_srcw)
+			continue;
+
+		if (input->w > 1024 && (!tv_mode->progressive
+					&& !tv_mode->component_only))
+			continue;
+
+		mode_ptr = drm_mode_create(connector->dev);
+		if (!mode_ptr)
+			continue;
+		strncpy(mode_ptr->name, input->name, DRM_DISPLAY_MODE_LEN);
+		mode_ptr->name[DRM_DISPLAY_MODE_LEN - 1] = '\0';
+
+		mode_ptr->hdisplay = hactive_s;
+		mode_ptr->hsync_start = hactive_s + 1;
+		mode_ptr->hsync_end = hactive_s + 64;
+		if (mode_ptr->hsync_end <= mode_ptr->hsync_start)
+			mode_ptr->hsync_end = mode_ptr->hsync_start + 1;
+		mode_ptr->htotal = hactive_s + 96;
+
+		mode_ptr->vdisplay = vactive_s;
+		mode_ptr->vsync_start = vactive_s + 1;
+		mode_ptr->vsync_end = vactive_s + 32;
+		if (mode_ptr->vsync_end <= mode_ptr->vsync_start)
+			mode_ptr->vsync_end = mode_ptr->vsync_start  + 1;
+		mode_ptr->vtotal = vactive_s + 33;
+
+		tmp = (u64) tv_mode->refresh * mode_ptr->vtotal;
+		tmp *= mode_ptr->htotal;
+		tmp = div_u64(tmp, 1000000);
+		mode_ptr->clock = (int) tmp;
+
+		mode_ptr->type = DRM_MODE_TYPE_DRIVER;
+		intel_tv_chose_preferred_modes(connector, mode_ptr);
+		drm_mode_probed_add(connector, mode_ptr);
+		count++;
+	}
+
+	return count;
+}
+
+static void
+intel_tv_destroy(struct drm_connector *connector)
+{
+	drm_connector_cleanup(connector);
+	kfree(connector);
+}
+
+
+static int
+intel_tv_set_property(struct drm_connector *connector, struct drm_property *property,
+		      uint64_t val)
+{
+	struct drm_device *dev = connector->dev;
+	struct intel_tv *intel_tv = intel_attached_tv(connector);
+	struct drm_crtc *crtc = intel_tv->base.base.crtc;
+	int ret = 0;
+	bool changed = false;
+
+	ret = drm_object_property_set_value(&connector->base, property, val);
+	if (ret < 0)
+		goto out;
+
+	if (property == dev->mode_config.tv_left_margin_property &&
+		intel_tv->margin[TV_MARGIN_LEFT] != val) {
+		intel_tv->margin[TV_MARGIN_LEFT] = val;
+		changed = true;
+	} else if (property == dev->mode_config.tv_right_margin_property &&
+		intel_tv->margin[TV_MARGIN_RIGHT] != val) {
+		intel_tv->margin[TV_MARGIN_RIGHT] = val;
+		changed = true;
+	} else if (property == dev->mode_config.tv_top_margin_property &&
+		intel_tv->margin[TV_MARGIN_TOP] != val) {
+		intel_tv->margin[TV_MARGIN_TOP] = val;
+		changed = true;
+	} else if (property == dev->mode_config.tv_bottom_margin_property &&
+		intel_tv->margin[TV_MARGIN_BOTTOM] != val) {
+		intel_tv->margin[TV_MARGIN_BOTTOM] = val;
+		changed = true;
+	} else if (property == dev->mode_config.tv_mode_property) {
+		if (val >= ARRAY_SIZE(tv_modes)) {
+			ret = -EINVAL;
+			goto out;
+		}
+		if (!strcmp(intel_tv->tv_format, tv_modes[val].name))
+			goto out;
+
+		intel_tv->tv_format = tv_modes[val].name;
+		changed = true;
+	} else {
+		ret = -EINVAL;
+		goto out;
+	}
+
+	if (changed && crtc)
+		intel_crtc_restore_mode(crtc);
+out:
+	return ret;
+}
+
+static const struct drm_connector_funcs intel_tv_connector_funcs = {
+	.dpms = drm_atomic_helper_connector_dpms,
+	.detect = intel_tv_detect,
+	.destroy = intel_tv_destroy,
+	.set_property = intel_tv_set_property,
+	.atomic_get_property = intel_connector_atomic_get_property,
+	.fill_modes = drm_helper_probe_single_connector_modes,
+	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
+	.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
+};
+
+static const struct drm_connector_helper_funcs intel_tv_connector_helper_funcs = {
+	.mode_valid = intel_tv_mode_valid,
+	.get_modes = intel_tv_get_modes,
+	.best_encoder = intel_best_encoder,
+};
+
+static const struct drm_encoder_funcs intel_tv_enc_funcs = {
+	.destroy = intel_encoder_destroy,
+};
+
+void
+intel_tv_init(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct drm_connector *connector;
+	struct intel_tv *intel_tv;
+	struct intel_encoder *intel_encoder;
+	struct intel_connector *intel_connector;
+	u32 tv_dac_on, tv_dac_off, save_tv_dac;
+	const char *tv_format_names[ARRAY_SIZE(tv_modes)];
+	int i, initial_mode = 0;
+
+	if ((I915_READ(TV_CTL) & TV_FUSE_STATE_MASK) == TV_FUSE_STATE_DISABLED)
+		return;
+
+	if (!intel_bios_is_tv_present(dev_priv)) {
+		DRM_DEBUG_KMS("Integrated TV is not present.\n");
+		return;
+	}
+
+	/*
+	 * Sanity check the TV output by checking to see if the
+	 * DAC register holds a value
+	 */
+	save_tv_dac = I915_READ(TV_DAC);
+
+	I915_WRITE(TV_DAC, save_tv_dac | TVDAC_STATE_CHG_EN);
+	tv_dac_on = I915_READ(TV_DAC);
+
+	I915_WRITE(TV_DAC, save_tv_dac & ~TVDAC_STATE_CHG_EN);
+	tv_dac_off = I915_READ(TV_DAC);
+
+	I915_WRITE(TV_DAC, save_tv_dac);
+
+	/*
+	 * If the register does not hold the state change enable
+	 * bit, (either as a 0 or a 1), assume it doesn't really
+	 * exist
+	 */
+	if ((tv_dac_on & TVDAC_STATE_CHG_EN) == 0 ||
+	    (tv_dac_off & TVDAC_STATE_CHG_EN) != 0)
+		return;
+
+	intel_tv = kzalloc(sizeof(*intel_tv), GFP_KERNEL);
+	if (!intel_tv) {
+		return;
+	}
+
+	intel_connector = intel_connector_alloc();
+	if (!intel_connector) {
+		kfree(intel_tv);
+		return;
+	}
+
+	intel_encoder = &intel_tv->base;
+	connector = &intel_connector->base;
+
+	/* The documentation, for the older chipsets at least, recommend
+	 * using a polling method rather than hotplug detection for TVs.
+	 * This is because in order to perform the hotplug detection, the PLLs
+	 * for the TV must be kept alive increasing power drain and starving
+	 * bandwidth from other encoders. Notably for instance, it causes
+	 * pipe underruns on Crestline when this encoder is supposedly idle.
+	 *
+	 * More recent chipsets favour HDMI rather than integrated S-Video.
+	 */
+	intel_connector->polled = DRM_CONNECTOR_POLL_CONNECT;
+
+	drm_connector_init(dev, connector, &intel_tv_connector_funcs,
+			   DRM_MODE_CONNECTOR_SVIDEO);
+
+	drm_encoder_init(dev, &intel_encoder->base, &intel_tv_enc_funcs,
+			 DRM_MODE_ENCODER_TVDAC);
+
+	intel_encoder->compute_config = intel_tv_compute_config;
+	intel_encoder->get_config = intel_tv_get_config;
+	intel_encoder->pre_enable = intel_tv_pre_enable;
+	intel_encoder->enable = intel_enable_tv;
+	intel_encoder->disable = intel_disable_tv;
+	intel_encoder->get_hw_state = intel_tv_get_hw_state;
+	intel_connector->get_hw_state = intel_connector_get_hw_state;
+	intel_connector->unregister = intel_connector_unregister;
+
+	intel_connector_attach_encoder(intel_connector, intel_encoder);
+	intel_encoder->type = INTEL_OUTPUT_TVOUT;
+	intel_encoder->crtc_mask = (1 << 0) | (1 << 1);
+	intel_encoder->cloneable = 0;
+	intel_encoder->base.possible_crtcs = ((1 << 0) | (1 << 1));
+	intel_tv->type = DRM_MODE_CONNECTOR_Unknown;
+
+	/* BIOS margin values */
+	intel_tv->margin[TV_MARGIN_LEFT] = 54;
+	intel_tv->margin[TV_MARGIN_TOP] = 36;
+	intel_tv->margin[TV_MARGIN_RIGHT] = 46;
+	intel_tv->margin[TV_MARGIN_BOTTOM] = 37;
+
+	intel_tv->tv_format = tv_modes[initial_mode].name;
+
+	drm_connector_helper_add(connector, &intel_tv_connector_helper_funcs);
+	connector->interlace_allowed = false;
+	connector->doublescan_allowed = false;
+
+	/* Create TV properties then attach current values */
+	for (i = 0; i < ARRAY_SIZE(tv_modes); i++)
+		tv_format_names[i] = tv_modes[i].name;
+	drm_mode_create_tv_properties(dev,
+				      ARRAY_SIZE(tv_modes),
+				      tv_format_names);
+
+	drm_object_attach_property(&connector->base, dev->mode_config.tv_mode_property,
+				   initial_mode);
+	drm_object_attach_property(&connector->base,
+				   dev->mode_config.tv_left_margin_property,
+				   intel_tv->margin[TV_MARGIN_LEFT]);
+	drm_object_attach_property(&connector->base,
+				   dev->mode_config.tv_top_margin_property,
+				   intel_tv->margin[TV_MARGIN_TOP]);
+	drm_object_attach_property(&connector->base,
+				   dev->mode_config.tv_right_margin_property,
+				   intel_tv->margin[TV_MARGIN_RIGHT]);
+	drm_object_attach_property(&connector->base,
+				   dev->mode_config.tv_bottom_margin_property,
+				   intel_tv->margin[TV_MARGIN_BOTTOM]);
+	drm_connector_register(connector);
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/i915/intel_uncore.c
@@ -0,0 +1,1905 @@
+/*
+ * Copyright © 2013 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include "i915_drv.h"
+#include "intel_drv.h"
+#include "i915_vgpu.h"
+
+#include <linux/pm_runtime.h>
+
+#define FORCEWAKE_ACK_TIMEOUT_MS 50
+
+#define __raw_posting_read(dev_priv__, reg__) (void)__raw_i915_read32((dev_priv__), (reg__))
+
+static const char * const forcewake_domain_names[] = {
+	"render",
+	"blitter",
+	"media",
+};
+
+const char *
+intel_uncore_forcewake_domain_to_str(const enum forcewake_domain_id id)
+{
+	BUILD_BUG_ON(ARRAY_SIZE(forcewake_domain_names) != FW_DOMAIN_ID_COUNT);
+
+	if (id >= 0 && id < FW_DOMAIN_ID_COUNT)
+		return forcewake_domain_names[id];
+
+	WARN_ON(id);
+
+	return "unknown";
+}
+
+static inline void
+fw_domain_reset(const struct intel_uncore_forcewake_domain *d)
+{
+	WARN_ON(!i915_mmio_reg_valid(d->reg_set));
+	__raw_i915_write32(d->i915, d->reg_set, d->val_reset);
+}
+
+static inline void
+fw_domain_arm_timer(struct intel_uncore_forcewake_domain *d)
+{
+	d->wake_count++;
+	hrtimer_start_range_ns(&d->timer,
+			       ktime_set(0, NSEC_PER_MSEC),
+			       NSEC_PER_MSEC,
+			       HRTIMER_MODE_REL);
+}
+
+static inline void
+fw_domain_wait_ack_clear(const struct intel_uncore_forcewake_domain *d)
+{
+	if (wait_for_atomic((__raw_i915_read32(d->i915, d->reg_ack) &
+			     FORCEWAKE_KERNEL) == 0,
+			    FORCEWAKE_ACK_TIMEOUT_MS))
+		DRM_ERROR("%s: timed out waiting for forcewake ack to clear.\n",
+			  intel_uncore_forcewake_domain_to_str(d->id));
+}
+
+static inline void
+fw_domain_get(const struct intel_uncore_forcewake_domain *d)
+{
+	__raw_i915_write32(d->i915, d->reg_set, d->val_set);
+}
+
+static inline void
+fw_domain_wait_ack(const struct intel_uncore_forcewake_domain *d)
+{
+	if (wait_for_atomic((__raw_i915_read32(d->i915, d->reg_ack) &
+			     FORCEWAKE_KERNEL),
+			    FORCEWAKE_ACK_TIMEOUT_MS))
+		DRM_ERROR("%s: timed out waiting for forcewake ack request.\n",
+			  intel_uncore_forcewake_domain_to_str(d->id));
+}
+
+static inline void
+fw_domain_put(const struct intel_uncore_forcewake_domain *d)
+{
+	__raw_i915_write32(d->i915, d->reg_set, d->val_clear);
+}
+
+static inline void
+fw_domain_posting_read(const struct intel_uncore_forcewake_domain *d)
+{
+	/* something from same cacheline, but not from the set register */
+	if (i915_mmio_reg_valid(d->reg_post))
+		__raw_posting_read(d->i915, d->reg_post);
+}
+
+static void
+fw_domains_get(struct drm_i915_private *dev_priv, enum forcewake_domains fw_domains)
+{
+	struct intel_uncore_forcewake_domain *d;
+
+	for_each_fw_domain_masked(d, fw_domains, dev_priv) {
+		fw_domain_wait_ack_clear(d);
+		fw_domain_get(d);
+	}
+
+	for_each_fw_domain_masked(d, fw_domains, dev_priv)
+		fw_domain_wait_ack(d);
+}
+
+static void
+fw_domains_put(struct drm_i915_private *dev_priv, enum forcewake_domains fw_domains)
+{
+	struct intel_uncore_forcewake_domain *d;
+
+	for_each_fw_domain_masked(d, fw_domains, dev_priv) {
+		fw_domain_put(d);
+		fw_domain_posting_read(d);
+	}
+}
+
+static void
+fw_domains_posting_read(struct drm_i915_private *dev_priv)
+{
+	struct intel_uncore_forcewake_domain *d;
+
+	/* No need to do for all, just do for first found */
+	for_each_fw_domain(d, dev_priv) {
+		fw_domain_posting_read(d);
+		break;
+	}
+}
+
+static void
+fw_domains_reset(struct drm_i915_private *dev_priv, enum forcewake_domains fw_domains)
+{
+	struct intel_uncore_forcewake_domain *d;
+
+	if (dev_priv->uncore.fw_domains == 0)
+		return;
+
+	for_each_fw_domain_masked(d, fw_domains, dev_priv)
+		fw_domain_reset(d);
+
+	fw_domains_posting_read(dev_priv);
+}
+
+static void __gen6_gt_wait_for_thread_c0(struct drm_i915_private *dev_priv)
+{
+	/* w/a for a sporadic read returning 0 by waiting for the GT
+	 * thread to wake up.
+	 */
+	if (wait_for_atomic_us((__raw_i915_read32(dev_priv, GEN6_GT_THREAD_STATUS_REG) &
+				GEN6_GT_THREAD_STATUS_CORE_MASK) == 0, 500))
+		DRM_ERROR("GT thread status wait timed out\n");
+}
+
+static void fw_domains_get_with_thread_status(struct drm_i915_private *dev_priv,
+					      enum forcewake_domains fw_domains)
+{
+	fw_domains_get(dev_priv, fw_domains);
+
+	/* WaRsForcewakeWaitTC0:snb,ivb,hsw,bdw,vlv */
+	__gen6_gt_wait_for_thread_c0(dev_priv);
+}
+
+static void gen6_gt_check_fifodbg(struct drm_i915_private *dev_priv)
+{
+	u32 gtfifodbg;
+
+	gtfifodbg = __raw_i915_read32(dev_priv, GTFIFODBG);
+	if (WARN(gtfifodbg, "GT wake FIFO error 0x%x\n", gtfifodbg))
+		__raw_i915_write32(dev_priv, GTFIFODBG, gtfifodbg);
+}
+
+static void fw_domains_put_with_fifo(struct drm_i915_private *dev_priv,
+				     enum forcewake_domains fw_domains)
+{
+	fw_domains_put(dev_priv, fw_domains);
+	gen6_gt_check_fifodbg(dev_priv);
+}
+
+static inline u32 fifo_free_entries(struct drm_i915_private *dev_priv)
+{
+	u32 count = __raw_i915_read32(dev_priv, GTFIFOCTL);
+
+	return count & GT_FIFO_FREE_ENTRIES_MASK;
+}
+
+static int __gen6_gt_wait_for_fifo(struct drm_i915_private *dev_priv)
+{
+	int ret = 0;
+
+	/* On VLV, FIFO will be shared by both SW and HW.
+	 * So, we need to read the FREE_ENTRIES everytime */
+	if (IS_VALLEYVIEW(dev_priv))
+		dev_priv->uncore.fifo_count = fifo_free_entries(dev_priv);
+
+	if (dev_priv->uncore.fifo_count < GT_FIFO_NUM_RESERVED_ENTRIES) {
+		int loop = 500;
+		u32 fifo = fifo_free_entries(dev_priv);
+
+		while (fifo <= GT_FIFO_NUM_RESERVED_ENTRIES && loop--) {
+			udelay(10);
+			fifo = fifo_free_entries(dev_priv);
+		}
+		if (WARN_ON(loop < 0 && fifo <= GT_FIFO_NUM_RESERVED_ENTRIES))
+			++ret;
+		dev_priv->uncore.fifo_count = fifo;
+	}
+	dev_priv->uncore.fifo_count--;
+
+	return ret;
+}
+
+static enum hrtimer_restart
+intel_uncore_fw_release_timer(struct hrtimer *timer)
+{
+	struct intel_uncore_forcewake_domain *domain =
+	       container_of(timer, struct intel_uncore_forcewake_domain, timer);
+	unsigned long irqflags;
+
+	assert_rpm_device_not_suspended(domain->i915);
+
+	spin_lock_irqsave(&domain->i915->uncore.lock, irqflags);
+	if (WARN_ON(domain->wake_count == 0))
+		domain->wake_count++;
+
+	if (--domain->wake_count == 0)
+		domain->i915->uncore.funcs.force_wake_put(domain->i915,
+							  1 << domain->id);
+
+	spin_unlock_irqrestore(&domain->i915->uncore.lock, irqflags);
+
+	return HRTIMER_NORESTART;
+}
+
+void intel_uncore_forcewake_reset(struct drm_device *dev, bool restore)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	unsigned long irqflags;
+	struct intel_uncore_forcewake_domain *domain;
+	int retry_count = 100;
+	enum forcewake_domains fw = 0, active_domains;
+
+	/* Hold uncore.lock across reset to prevent any register access
+	 * with forcewake not set correctly. Wait until all pending
+	 * timers are run before holding.
+	 */
+	while (1) {
+		active_domains = 0;
+
+		for_each_fw_domain(domain, dev_priv) {
+			if (hrtimer_cancel(&domain->timer) == 0)
+				continue;
+
+			intel_uncore_fw_release_timer(&domain->timer);
+		}
+
+		spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
+
+		for_each_fw_domain(domain, dev_priv) {
+			if (hrtimer_active(&domain->timer))
+				active_domains |= domain->mask;
+		}
+
+		if (active_domains == 0)
+			break;
+
+		if (--retry_count == 0) {
+			DRM_ERROR("Timed out waiting for forcewake timers to finish\n");
+			break;
+		}
+
+		spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
+		cond_resched();
+	}
+
+	WARN_ON(active_domains);
+
+	for_each_fw_domain(domain, dev_priv)
+		if (domain->wake_count)
+			fw |= domain->mask;
+
+	if (fw)
+		dev_priv->uncore.funcs.force_wake_put(dev_priv, fw);
+
+	fw_domains_reset(dev_priv, FORCEWAKE_ALL);
+
+	if (restore) { /* If reset with a user forcewake, try to restore */
+		if (fw)
+			dev_priv->uncore.funcs.force_wake_get(dev_priv, fw);
+
+		if (IS_GEN6(dev) || IS_GEN7(dev))
+			dev_priv->uncore.fifo_count =
+				fifo_free_entries(dev_priv);
+	}
+
+	if (!restore)
+		assert_forcewakes_inactive(dev_priv);
+
+	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
+}
+
+static u64 gen9_edram_size(struct drm_i915_private *dev_priv)
+{
+	const unsigned int ways[8] = { 4, 8, 12, 16, 16, 16, 16, 16 };
+	const unsigned int sets[4] = { 1, 1, 2, 2 };
+	const u32 cap = dev_priv->edram_cap;
+
+	return EDRAM_NUM_BANKS(cap) *
+		ways[EDRAM_WAYS_IDX(cap)] *
+		sets[EDRAM_SETS_IDX(cap)] *
+		1024 * 1024;
+}
+
+u64 intel_uncore_edram_size(struct drm_i915_private *dev_priv)
+{
+	if (!HAS_EDRAM(dev_priv))
+		return 0;
+
+	/* The needed capability bits for size calculation
+	 * are not there with pre gen9 so return 128MB always.
+	 */
+	if (INTEL_GEN(dev_priv) < 9)
+		return 128 * 1024 * 1024;
+
+	return gen9_edram_size(dev_priv);
+}
+
+static void intel_uncore_edram_detect(struct drm_i915_private *dev_priv)
+{
+	if (IS_HASWELL(dev_priv) ||
+	    IS_BROADWELL(dev_priv) ||
+	    INTEL_GEN(dev_priv) >= 9) {
+		dev_priv->edram_cap = __raw_i915_read32(dev_priv,
+							HSW_EDRAM_CAP);
+
+		/* NB: We can't write IDICR yet because we do not have gt funcs
+		 * set up */
+	} else {
+		dev_priv->edram_cap = 0;
+	}
+
+	if (HAS_EDRAM(dev_priv))
+		DRM_INFO("Found %lluMB of eDRAM\n",
+			 intel_uncore_edram_size(dev_priv) / (1024 * 1024));
+}
+
+static bool
+fpga_check_for_unclaimed_mmio(struct drm_i915_private *dev_priv)
+{
+	u32 dbg;
+
+	dbg = __raw_i915_read32(dev_priv, FPGA_DBG);
+	if (likely(!(dbg & FPGA_DBG_RM_NOCLAIM)))
+		return false;
+
+	__raw_i915_write32(dev_priv, FPGA_DBG, FPGA_DBG_RM_NOCLAIM);
+
+	return true;
+}
+
+static bool
+vlv_check_for_unclaimed_mmio(struct drm_i915_private *dev_priv)
+{
+	u32 cer;
+
+	cer = __raw_i915_read32(dev_priv, CLAIM_ER);
+	if (likely(!(cer & (CLAIM_ER_OVERFLOW | CLAIM_ER_CTR_MASK))))
+		return false;
+
+	__raw_i915_write32(dev_priv, CLAIM_ER, CLAIM_ER_CLR);
+
+	return true;
+}
+
+static bool
+check_for_unclaimed_mmio(struct drm_i915_private *dev_priv)
+{
+	if (HAS_FPGA_DBG_UNCLAIMED(dev_priv))
+		return fpga_check_for_unclaimed_mmio(dev_priv);
+
+	if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
+		return vlv_check_for_unclaimed_mmio(dev_priv);
+
+	return false;
+}
+
+static void __intel_uncore_early_sanitize(struct drm_device *dev,
+					  bool restore_forcewake)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	/* clear out unclaimed reg detection bit */
+	if (check_for_unclaimed_mmio(dev_priv))
+		DRM_DEBUG("unclaimed mmio detected on uncore init, clearing\n");
+
+	/* clear out old GT FIFO errors */
+	if (IS_GEN6(dev) || IS_GEN7(dev))
+		__raw_i915_write32(dev_priv, GTFIFODBG,
+				   __raw_i915_read32(dev_priv, GTFIFODBG));
+
+	/* WaDisableShadowRegForCpd:chv */
+	if (IS_CHERRYVIEW(dev)) {
+		__raw_i915_write32(dev_priv, GTFIFOCTL,
+				   __raw_i915_read32(dev_priv, GTFIFOCTL) |
+				   GT_FIFO_CTL_BLOCK_ALL_POLICY_STALL |
+				   GT_FIFO_CTL_RC6_POLICY_STALL);
+	}
+
+	intel_uncore_forcewake_reset(dev, restore_forcewake);
+}
+
+void intel_uncore_early_sanitize(struct drm_device *dev, bool restore_forcewake)
+{
+	__intel_uncore_early_sanitize(dev, restore_forcewake);
+	i915_check_and_clear_faults(dev);
+}
+
+void intel_uncore_sanitize(struct drm_device *dev)
+{
+	i915.enable_rc6 = sanitize_rc6_option(dev, i915.enable_rc6);
+
+	/* BIOS often leaves RC6 enabled, but disable it for hw init */
+	intel_disable_gt_powersave(dev);
+}
+
+static void __intel_uncore_forcewake_get(struct drm_i915_private *dev_priv,
+					 enum forcewake_domains fw_domains)
+{
+	struct intel_uncore_forcewake_domain *domain;
+
+	if (!dev_priv->uncore.funcs.force_wake_get)
+		return;
+
+	fw_domains &= dev_priv->uncore.fw_domains;
+
+	for_each_fw_domain_masked(domain, fw_domains, dev_priv) {
+		if (domain->wake_count++)
+			fw_domains &= ~domain->mask;
+	}
+
+	if (fw_domains)
+		dev_priv->uncore.funcs.force_wake_get(dev_priv, fw_domains);
+}
+
+/**
+ * intel_uncore_forcewake_get - grab forcewake domain references
+ * @dev_priv: i915 device instance
+ * @fw_domains: forcewake domains to get reference on
+ *
+ * This function can be used get GT's forcewake domain references.
+ * Normal register access will handle the forcewake domains automatically.
+ * However if some sequence requires the GT to not power down a particular
+ * forcewake domains this function should be called at the beginning of the
+ * sequence. And subsequently the reference should be dropped by symmetric
+ * call to intel_unforce_forcewake_put(). Usually caller wants all the domains
+ * to be kept awake so the @fw_domains would be then FORCEWAKE_ALL.
+ */
+void intel_uncore_forcewake_get(struct drm_i915_private *dev_priv,
+				enum forcewake_domains fw_domains)
+{
+	unsigned long irqflags;
+
+	if (!dev_priv->uncore.funcs.force_wake_get)
+		return;
+
+	assert_rpm_wakelock_held(dev_priv);
+
+	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
+	__intel_uncore_forcewake_get(dev_priv, fw_domains);
+	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
+}
+
+/**
+ * intel_uncore_forcewake_get__locked - grab forcewake domain references
+ * @dev_priv: i915 device instance
+ * @fw_domains: forcewake domains to get reference on
+ *
+ * See intel_uncore_forcewake_get(). This variant places the onus
+ * on the caller to explicitly handle the dev_priv->uncore.lock spinlock.
+ */
+void intel_uncore_forcewake_get__locked(struct drm_i915_private *dev_priv,
+					enum forcewake_domains fw_domains)
+{
+	assert_spin_locked(&dev_priv->uncore.lock);
+
+	if (!dev_priv->uncore.funcs.force_wake_get)
+		return;
+
+	__intel_uncore_forcewake_get(dev_priv, fw_domains);
+}
+
+static void __intel_uncore_forcewake_put(struct drm_i915_private *dev_priv,
+					 enum forcewake_domains fw_domains)
+{
+	struct intel_uncore_forcewake_domain *domain;
+
+	if (!dev_priv->uncore.funcs.force_wake_put)
+		return;
+
+	fw_domains &= dev_priv->uncore.fw_domains;
+
+	for_each_fw_domain_masked(domain, fw_domains, dev_priv) {
+		if (WARN_ON(domain->wake_count == 0))
+			continue;
+
+		if (--domain->wake_count)
+			continue;
+
+		fw_domain_arm_timer(domain);
+	}
+}
+
+/**
+ * intel_uncore_forcewake_put - release a forcewake domain reference
+ * @dev_priv: i915 device instance
+ * @fw_domains: forcewake domains to put references
+ *
+ * This function drops the device-level forcewakes for specified
+ * domains obtained by intel_uncore_forcewake_get().
+ */
+void intel_uncore_forcewake_put(struct drm_i915_private *dev_priv,
+				enum forcewake_domains fw_domains)
+{
+	unsigned long irqflags;
+
+	if (!dev_priv->uncore.funcs.force_wake_put)
+		return;
+
+	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
+	__intel_uncore_forcewake_put(dev_priv, fw_domains);
+	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
+}
+
+/**
+ * intel_uncore_forcewake_put__locked - grab forcewake domain references
+ * @dev_priv: i915 device instance
+ * @fw_domains: forcewake domains to get reference on
+ *
+ * See intel_uncore_forcewake_put(). This variant places the onus
+ * on the caller to explicitly handle the dev_priv->uncore.lock spinlock.
+ */
+void intel_uncore_forcewake_put__locked(struct drm_i915_private *dev_priv,
+					enum forcewake_domains fw_domains)
+{
+	assert_spin_locked(&dev_priv->uncore.lock);
+
+	if (!dev_priv->uncore.funcs.force_wake_put)
+		return;
+
+	__intel_uncore_forcewake_put(dev_priv, fw_domains);
+}
+
+void assert_forcewakes_inactive(struct drm_i915_private *dev_priv)
+{
+	struct intel_uncore_forcewake_domain *domain;
+
+	if (!dev_priv->uncore.funcs.force_wake_get)
+		return;
+
+	for_each_fw_domain(domain, dev_priv)
+		WARN_ON(domain->wake_count);
+}
+
+/* We give fast paths for the really cool registers */
+#define NEEDS_FORCE_WAKE(reg) ((reg) < 0x40000)
+
+#define __gen6_reg_read_fw_domains(offset) \
+({ \
+	enum forcewake_domains __fwd; \
+	if (NEEDS_FORCE_WAKE(offset)) \
+		__fwd = FORCEWAKE_RENDER; \
+	else \
+		__fwd = 0; \
+	__fwd; \
+})
+
+#define REG_RANGE(reg, start, end) ((reg) >= (start) && (reg) < (end))
+
+#define FORCEWAKE_VLV_RENDER_RANGE_OFFSET(reg) \
+	(REG_RANGE((reg), 0x2000, 0x4000) || \
+	 REG_RANGE((reg), 0x5000, 0x8000) || \
+	 REG_RANGE((reg), 0xB000, 0x12000) || \
+	 REG_RANGE((reg), 0x2E000, 0x30000))
+
+#define FORCEWAKE_VLV_MEDIA_RANGE_OFFSET(reg) \
+	(REG_RANGE((reg), 0x12000, 0x14000) || \
+	 REG_RANGE((reg), 0x22000, 0x24000) || \
+	 REG_RANGE((reg), 0x30000, 0x40000))
+
+#define __vlv_reg_read_fw_domains(offset) \
+({ \
+	enum forcewake_domains __fwd = 0; \
+	if (!NEEDS_FORCE_WAKE(offset)) \
+		__fwd = 0; \
+	else if (FORCEWAKE_VLV_RENDER_RANGE_OFFSET(offset)) \
+		__fwd = FORCEWAKE_RENDER; \
+	else if (FORCEWAKE_VLV_MEDIA_RANGE_OFFSET(offset)) \
+		__fwd = FORCEWAKE_MEDIA; \
+	__fwd; \
+})
+
+static const i915_reg_t gen8_shadowed_regs[] = {
+	GEN6_RPNSWREQ,
+	GEN6_RC_VIDEO_FREQ,
+	RING_TAIL(RENDER_RING_BASE),
+	RING_TAIL(GEN6_BSD_RING_BASE),
+	RING_TAIL(VEBOX_RING_BASE),
+	RING_TAIL(BLT_RING_BASE),
+	/* TODO: Other registers are not yet used */
+};
+
+static bool is_gen8_shadowed(u32 offset)
+{
+	int i;
+	for (i = 0; i < ARRAY_SIZE(gen8_shadowed_regs); i++)
+		if (offset == gen8_shadowed_regs[i].reg)
+			return true;
+
+	return false;
+}
+
+#define __gen8_reg_write_fw_domains(offset) \
+({ \
+	enum forcewake_domains __fwd; \
+	if (NEEDS_FORCE_WAKE(offset) && !is_gen8_shadowed(offset)) \
+		__fwd = FORCEWAKE_RENDER; \
+	else \
+		__fwd = 0; \
+	__fwd; \
+})
+
+#define FORCEWAKE_CHV_RENDER_RANGE_OFFSET(reg) \
+	(REG_RANGE((reg), 0x2000, 0x4000) || \
+	 REG_RANGE((reg), 0x5200, 0x8000) || \
+	 REG_RANGE((reg), 0x8300, 0x8500) || \
+	 REG_RANGE((reg), 0xB000, 0xB480) || \
+	 REG_RANGE((reg), 0xE000, 0xE800))
+
+#define FORCEWAKE_CHV_MEDIA_RANGE_OFFSET(reg) \
+	(REG_RANGE((reg), 0x8800, 0x8900) || \
+	 REG_RANGE((reg), 0xD000, 0xD800) || \
+	 REG_RANGE((reg), 0x12000, 0x14000) || \
+	 REG_RANGE((reg), 0x1A000, 0x1C000) || \
+	 REG_RANGE((reg), 0x1E800, 0x1EA00) || \
+	 REG_RANGE((reg), 0x30000, 0x38000))
+
+#define FORCEWAKE_CHV_COMMON_RANGE_OFFSET(reg) \
+	(REG_RANGE((reg), 0x4000, 0x5000) || \
+	 REG_RANGE((reg), 0x8000, 0x8300) || \
+	 REG_RANGE((reg), 0x8500, 0x8600) || \
+	 REG_RANGE((reg), 0x9000, 0xB000) || \
+	 REG_RANGE((reg), 0xF000, 0x10000))
+
+#define __chv_reg_read_fw_domains(offset) \
+({ \
+	enum forcewake_domains __fwd = 0; \
+	if (!NEEDS_FORCE_WAKE(offset)) \
+		__fwd = 0; \
+	else if (FORCEWAKE_CHV_RENDER_RANGE_OFFSET(offset)) \
+		__fwd = FORCEWAKE_RENDER; \
+	else if (FORCEWAKE_CHV_MEDIA_RANGE_OFFSET(offset)) \
+		__fwd = FORCEWAKE_MEDIA; \
+	else if (FORCEWAKE_CHV_COMMON_RANGE_OFFSET(offset)) \
+		__fwd = FORCEWAKE_RENDER | FORCEWAKE_MEDIA; \
+	__fwd; \
+})
+
+#define __chv_reg_write_fw_domains(offset) \
+({ \
+	enum forcewake_domains __fwd = 0; \
+	if (!NEEDS_FORCE_WAKE(offset) || is_gen8_shadowed(offset)) \
+		__fwd = 0; \
+	else if (FORCEWAKE_CHV_RENDER_RANGE_OFFSET(offset)) \
+		__fwd = FORCEWAKE_RENDER; \
+	else if (FORCEWAKE_CHV_MEDIA_RANGE_OFFSET(offset)) \
+		__fwd = FORCEWAKE_MEDIA; \
+	else if (FORCEWAKE_CHV_COMMON_RANGE_OFFSET(offset)) \
+		__fwd = FORCEWAKE_RENDER | FORCEWAKE_MEDIA; \
+	__fwd; \
+})
+
+#define FORCEWAKE_GEN9_UNCORE_RANGE_OFFSET(reg) \
+	REG_RANGE((reg), 0xB00,  0x2000)
+
+#define FORCEWAKE_GEN9_RENDER_RANGE_OFFSET(reg) \
+	(REG_RANGE((reg), 0x2000, 0x2700) || \
+	 REG_RANGE((reg), 0x3000, 0x4000) || \
+	 REG_RANGE((reg), 0x5200, 0x8000) || \
+	 REG_RANGE((reg), 0x8140, 0x8160) || \
+	 REG_RANGE((reg), 0x8300, 0x8500) || \
+	 REG_RANGE((reg), 0x8C00, 0x8D00) || \
+	 REG_RANGE((reg), 0xB000, 0xB480) || \
+	 REG_RANGE((reg), 0xE000, 0xE900) || \
+	 REG_RANGE((reg), 0x24400, 0x24800))
+
+#define FORCEWAKE_GEN9_MEDIA_RANGE_OFFSET(reg) \
+	(REG_RANGE((reg), 0x8130, 0x8140) || \
+	 REG_RANGE((reg), 0x8800, 0x8A00) || \
+	 REG_RANGE((reg), 0xD000, 0xD800) || \
+	 REG_RANGE((reg), 0x12000, 0x14000) || \
+	 REG_RANGE((reg), 0x1A000, 0x1EA00) || \
+	 REG_RANGE((reg), 0x30000, 0x40000))
+
+#define FORCEWAKE_GEN9_COMMON_RANGE_OFFSET(reg) \
+	REG_RANGE((reg), 0x9400, 0x9800)
+
+#define FORCEWAKE_GEN9_BLITTER_RANGE_OFFSET(reg) \
+	((reg) < 0x40000 && \
+	 !FORCEWAKE_GEN9_UNCORE_RANGE_OFFSET(reg) && \
+	 !FORCEWAKE_GEN9_RENDER_RANGE_OFFSET(reg) && \
+	 !FORCEWAKE_GEN9_MEDIA_RANGE_OFFSET(reg) && \
+	 !FORCEWAKE_GEN9_COMMON_RANGE_OFFSET(reg))
+
+#define SKL_NEEDS_FORCE_WAKE(reg) \
+	((reg) < 0x40000 && !FORCEWAKE_GEN9_UNCORE_RANGE_OFFSET(reg))
+
+#define __gen9_reg_read_fw_domains(offset) \
+({ \
+	enum forcewake_domains __fwd; \
+	if (!SKL_NEEDS_FORCE_WAKE(offset)) \
+		__fwd = 0; \
+	else if (FORCEWAKE_GEN9_RENDER_RANGE_OFFSET(offset)) \
+		__fwd = FORCEWAKE_RENDER; \
+	else if (FORCEWAKE_GEN9_MEDIA_RANGE_OFFSET(offset)) \
+		__fwd = FORCEWAKE_MEDIA; \
+	else if (FORCEWAKE_GEN9_COMMON_RANGE_OFFSET(offset)) \
+		__fwd = FORCEWAKE_RENDER | FORCEWAKE_MEDIA; \
+	else \
+		__fwd = FORCEWAKE_BLITTER; \
+	__fwd; \
+})
+
+static const i915_reg_t gen9_shadowed_regs[] = {
+	RING_TAIL(RENDER_RING_BASE),
+	RING_TAIL(GEN6_BSD_RING_BASE),
+	RING_TAIL(VEBOX_RING_BASE),
+	RING_TAIL(BLT_RING_BASE),
+	GEN6_RPNSWREQ,
+	GEN6_RC_VIDEO_FREQ,
+	/* TODO: Other registers are not yet used */
+};
+
+static bool is_gen9_shadowed(u32 offset)
+{
+	int i;
+	for (i = 0; i < ARRAY_SIZE(gen9_shadowed_regs); i++)
+		if (offset == gen9_shadowed_regs[i].reg)
+			return true;
+
+	return false;
+}
+
+#define __gen9_reg_write_fw_domains(offset) \
+({ \
+	enum forcewake_domains __fwd; \
+	if (!SKL_NEEDS_FORCE_WAKE(offset) || is_gen9_shadowed(offset)) \
+		__fwd = 0; \
+	else if (FORCEWAKE_GEN9_RENDER_RANGE_OFFSET(offset)) \
+		__fwd = FORCEWAKE_RENDER; \
+	else if (FORCEWAKE_GEN9_MEDIA_RANGE_OFFSET(offset)) \
+		__fwd = FORCEWAKE_MEDIA; \
+	else if (FORCEWAKE_GEN9_COMMON_RANGE_OFFSET(offset)) \
+		__fwd = FORCEWAKE_RENDER | FORCEWAKE_MEDIA; \
+	else \
+		__fwd = FORCEWAKE_BLITTER; \
+	__fwd; \
+})
+
+static void
+ilk_dummy_write(struct drm_i915_private *dev_priv)
+{
+	/* WaIssueDummyWriteToWakeupFromRC6:ilk Issue a dummy write to wake up
+	 * the chip from rc6 before touching it for real. MI_MODE is masked,
+	 * hence harmless to write 0 into. */
+	__raw_i915_write32(dev_priv, MI_MODE, 0);
+}
+
+static void
+__unclaimed_reg_debug(struct drm_i915_private *dev_priv,
+		      const i915_reg_t reg,
+		      const bool read,
+		      const bool before)
+{
+	if (WARN(check_for_unclaimed_mmio(dev_priv),
+		 "Unclaimed register detected %s %s register 0x%x\n",
+		 before ? "before" : "after",
+		 read ? "reading" : "writing to",
+		 i915_mmio_reg_offset(reg)))
+		i915.mmio_debug--; /* Only report the first N failures */
+}
+
+static inline void
+unclaimed_reg_debug(struct drm_i915_private *dev_priv,
+		    const i915_reg_t reg,
+		    const bool read,
+		    const bool before)
+{
+	if (likely(!i915.mmio_debug))
+		return;
+
+	__unclaimed_reg_debug(dev_priv, reg, read, before);
+}
+
+#define GEN2_READ_HEADER(x) \
+	u##x val = 0; \
+	assert_rpm_wakelock_held(dev_priv);
+
+#define GEN2_READ_FOOTER \
+	trace_i915_reg_rw(false, reg, val, sizeof(val), trace); \
+	return val
+
+#define __gen2_read(x) \
+static u##x \
+gen2_read##x(struct drm_i915_private *dev_priv, i915_reg_t reg, bool trace) { \
+	GEN2_READ_HEADER(x); \
+	val = __raw_i915_read##x(dev_priv, reg); \
+	GEN2_READ_FOOTER; \
+}
+
+#define __gen5_read(x) \
+static u##x \
+gen5_read##x(struct drm_i915_private *dev_priv, i915_reg_t reg, bool trace) { \
+	GEN2_READ_HEADER(x); \
+	ilk_dummy_write(dev_priv); \
+	val = __raw_i915_read##x(dev_priv, reg); \
+	GEN2_READ_FOOTER; \
+}
+
+__gen5_read(8)
+__gen5_read(16)
+__gen5_read(32)
+__gen5_read(64)
+__gen2_read(8)
+__gen2_read(16)
+__gen2_read(32)
+__gen2_read(64)
+
+#undef __gen5_read
+#undef __gen2_read
+
+#undef GEN2_READ_FOOTER
+#undef GEN2_READ_HEADER
+
+#define GEN6_READ_HEADER(x) \
+	u32 offset = i915_mmio_reg_offset(reg); \
+	unsigned long irqflags; \
+	u##x val = 0; \
+	assert_rpm_wakelock_held(dev_priv); \
+	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags); \
+	unclaimed_reg_debug(dev_priv, reg, true, true)
+
+#define GEN6_READ_FOOTER \
+	unclaimed_reg_debug(dev_priv, reg, true, false); \
+	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); \
+	trace_i915_reg_rw(false, reg, val, sizeof(val), trace); \
+	return val
+
+static inline void __force_wake_auto(struct drm_i915_private *dev_priv,
+				     enum forcewake_domains fw_domains)
+{
+	struct intel_uncore_forcewake_domain *domain;
+
+	if (WARN_ON(!fw_domains))
+		return;
+
+	/* Ideally GCC would be constant-fold and eliminate this loop */
+	for_each_fw_domain_masked(domain, fw_domains, dev_priv) {
+		if (domain->wake_count) {
+			fw_domains &= ~domain->mask;
+			continue;
+		}
+
+		fw_domain_arm_timer(domain);
+	}
+
+	if (fw_domains)
+		dev_priv->uncore.funcs.force_wake_get(dev_priv, fw_domains);
+}
+
+#define __gen6_read(x) \
+static u##x \
+gen6_read##x(struct drm_i915_private *dev_priv, i915_reg_t reg, bool trace) { \
+	enum forcewake_domains fw_engine; \
+	GEN6_READ_HEADER(x); \
+	fw_engine = __gen6_reg_read_fw_domains(offset); \
+	if (fw_engine) \
+		__force_wake_auto(dev_priv, fw_engine); \
+	val = __raw_i915_read##x(dev_priv, reg); \
+	GEN6_READ_FOOTER; \
+}
+
+#define __vlv_read(x) \
+static u##x \
+vlv_read##x(struct drm_i915_private *dev_priv, i915_reg_t reg, bool trace) { \
+	enum forcewake_domains fw_engine; \
+	GEN6_READ_HEADER(x); \
+	fw_engine = __vlv_reg_read_fw_domains(offset); \
+	if (fw_engine) \
+		__force_wake_auto(dev_priv, fw_engine); \
+	val = __raw_i915_read##x(dev_priv, reg); \
+	GEN6_READ_FOOTER; \
+}
+
+#define __chv_read(x) \
+static u##x \
+chv_read##x(struct drm_i915_private *dev_priv, i915_reg_t reg, bool trace) { \
+	enum forcewake_domains fw_engine; \
+	GEN6_READ_HEADER(x); \
+	fw_engine = __chv_reg_read_fw_domains(offset); \
+	if (fw_engine) \
+		__force_wake_auto(dev_priv, fw_engine); \
+	val = __raw_i915_read##x(dev_priv, reg); \
+	GEN6_READ_FOOTER; \
+}
+
+#define __gen9_read(x) \
+static u##x \
+gen9_read##x(struct drm_i915_private *dev_priv, i915_reg_t reg, bool trace) { \
+	enum forcewake_domains fw_engine; \
+	GEN6_READ_HEADER(x); \
+	fw_engine = __gen9_reg_read_fw_domains(offset); \
+	if (fw_engine) \
+		__force_wake_auto(dev_priv, fw_engine); \
+	val = __raw_i915_read##x(dev_priv, reg); \
+	GEN6_READ_FOOTER; \
+}
+
+__gen9_read(8)
+__gen9_read(16)
+__gen9_read(32)
+__gen9_read(64)
+__chv_read(8)
+__chv_read(16)
+__chv_read(32)
+__chv_read(64)
+__vlv_read(8)
+__vlv_read(16)
+__vlv_read(32)
+__vlv_read(64)
+__gen6_read(8)
+__gen6_read(16)
+__gen6_read(32)
+__gen6_read(64)
+
+#undef __gen9_read
+#undef __chv_read
+#undef __vlv_read
+#undef __gen6_read
+#undef GEN6_READ_FOOTER
+#undef GEN6_READ_HEADER
+
+#define VGPU_READ_HEADER(x) \
+	unsigned long irqflags; \
+	u##x val = 0; \
+	assert_rpm_device_not_suspended(dev_priv); \
+	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags)
+
+#define VGPU_READ_FOOTER \
+	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); \
+	trace_i915_reg_rw(false, reg, val, sizeof(val), trace); \
+	return val
+
+#define __vgpu_read(x) \
+static u##x \
+vgpu_read##x(struct drm_i915_private *dev_priv, i915_reg_t reg, bool trace) { \
+	VGPU_READ_HEADER(x); \
+	val = __raw_i915_read##x(dev_priv, reg); \
+	VGPU_READ_FOOTER; \
+}
+
+__vgpu_read(8)
+__vgpu_read(16)
+__vgpu_read(32)
+__vgpu_read(64)
+
+#undef __vgpu_read
+#undef VGPU_READ_FOOTER
+#undef VGPU_READ_HEADER
+
+#define GEN2_WRITE_HEADER \
+	trace_i915_reg_rw(true, reg, val, sizeof(val), trace); \
+	assert_rpm_wakelock_held(dev_priv); \
+
+#define GEN2_WRITE_FOOTER
+
+#define __gen2_write(x) \
+static void \
+gen2_write##x(struct drm_i915_private *dev_priv, i915_reg_t reg, u##x val, bool trace) { \
+	GEN2_WRITE_HEADER; \
+	__raw_i915_write##x(dev_priv, reg, val); \
+	GEN2_WRITE_FOOTER; \
+}
+
+#define __gen5_write(x) \
+static void \
+gen5_write##x(struct drm_i915_private *dev_priv, i915_reg_t reg, u##x val, bool trace) { \
+	GEN2_WRITE_HEADER; \
+	ilk_dummy_write(dev_priv); \
+	__raw_i915_write##x(dev_priv, reg, val); \
+	GEN2_WRITE_FOOTER; \
+}
+
+__gen5_write(8)
+__gen5_write(16)
+__gen5_write(32)
+__gen5_write(64)
+__gen2_write(8)
+__gen2_write(16)
+__gen2_write(32)
+__gen2_write(64)
+
+#undef __gen5_write
+#undef __gen2_write
+
+#undef GEN2_WRITE_FOOTER
+#undef GEN2_WRITE_HEADER
+
+#define GEN6_WRITE_HEADER \
+	u32 offset = i915_mmio_reg_offset(reg); \
+	unsigned long irqflags; \
+	trace_i915_reg_rw(true, reg, val, sizeof(val), trace); \
+	assert_rpm_wakelock_held(dev_priv); \
+	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags); \
+	unclaimed_reg_debug(dev_priv, reg, false, true)
+
+#define GEN6_WRITE_FOOTER \
+	unclaimed_reg_debug(dev_priv, reg, false, false); \
+	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags)
+
+#define __gen6_write(x) \
+static void \
+gen6_write##x(struct drm_i915_private *dev_priv, i915_reg_t reg, u##x val, bool trace) { \
+	u32 __fifo_ret = 0; \
+	GEN6_WRITE_HEADER; \
+	if (NEEDS_FORCE_WAKE(offset)) { \
+		__fifo_ret = __gen6_gt_wait_for_fifo(dev_priv); \
+	} \
+	__raw_i915_write##x(dev_priv, reg, val); \
+	if (unlikely(__fifo_ret)) { \
+		gen6_gt_check_fifodbg(dev_priv); \
+	} \
+	GEN6_WRITE_FOOTER; \
+}
+
+#define __hsw_write(x) \
+static void \
+hsw_write##x(struct drm_i915_private *dev_priv, i915_reg_t reg, u##x val, bool trace) { \
+	u32 __fifo_ret = 0; \
+	GEN6_WRITE_HEADER; \
+	if (NEEDS_FORCE_WAKE(offset)) { \
+		__fifo_ret = __gen6_gt_wait_for_fifo(dev_priv); \
+	} \
+	__raw_i915_write##x(dev_priv, reg, val); \
+	if (unlikely(__fifo_ret)) { \
+		gen6_gt_check_fifodbg(dev_priv); \
+	} \
+	GEN6_WRITE_FOOTER; \
+}
+
+#define __gen8_write(x) \
+static void \
+gen8_write##x(struct drm_i915_private *dev_priv, i915_reg_t reg, u##x val, bool trace) { \
+	enum forcewake_domains fw_engine; \
+	GEN6_WRITE_HEADER; \
+	fw_engine = __gen8_reg_write_fw_domains(offset); \
+	if (fw_engine) \
+		__force_wake_auto(dev_priv, fw_engine); \
+	__raw_i915_write##x(dev_priv, reg, val); \
+	GEN6_WRITE_FOOTER; \
+}
+
+#define __chv_write(x) \
+static void \
+chv_write##x(struct drm_i915_private *dev_priv, i915_reg_t reg, u##x val, bool trace) { \
+	enum forcewake_domains fw_engine; \
+	GEN6_WRITE_HEADER; \
+	fw_engine = __chv_reg_write_fw_domains(offset); \
+	if (fw_engine) \
+		__force_wake_auto(dev_priv, fw_engine); \
+	__raw_i915_write##x(dev_priv, reg, val); \
+	GEN6_WRITE_FOOTER; \
+}
+
+#define __gen9_write(x) \
+static void \
+gen9_write##x(struct drm_i915_private *dev_priv, i915_reg_t reg, u##x val, \
+		bool trace) { \
+	enum forcewake_domains fw_engine; \
+	GEN6_WRITE_HEADER; \
+	fw_engine = __gen9_reg_write_fw_domains(offset); \
+	if (fw_engine) \
+		__force_wake_auto(dev_priv, fw_engine); \
+	__raw_i915_write##x(dev_priv, reg, val); \
+	GEN6_WRITE_FOOTER; \
+}
+
+__gen9_write(8)
+__gen9_write(16)
+__gen9_write(32)
+__gen9_write(64)
+__chv_write(8)
+__chv_write(16)
+__chv_write(32)
+__chv_write(64)
+__gen8_write(8)
+__gen8_write(16)
+__gen8_write(32)
+__gen8_write(64)
+__hsw_write(8)
+__hsw_write(16)
+__hsw_write(32)
+__hsw_write(64)
+__gen6_write(8)
+__gen6_write(16)
+__gen6_write(32)
+__gen6_write(64)
+
+#undef __gen9_write
+#undef __chv_write
+#undef __gen8_write
+#undef __hsw_write
+#undef __gen6_write
+#undef GEN6_WRITE_FOOTER
+#undef GEN6_WRITE_HEADER
+
+#define VGPU_WRITE_HEADER \
+	unsigned long irqflags; \
+	trace_i915_reg_rw(true, reg, val, sizeof(val), trace); \
+	assert_rpm_device_not_suspended(dev_priv); \
+	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags)
+
+#define VGPU_WRITE_FOOTER \
+	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags)
+
+#define __vgpu_write(x) \
+static void vgpu_write##x(struct drm_i915_private *dev_priv, \
+			  i915_reg_t reg, u##x val, bool trace) { \
+	VGPU_WRITE_HEADER; \
+	__raw_i915_write##x(dev_priv, reg, val); \
+	VGPU_WRITE_FOOTER; \
+}
+
+__vgpu_write(8)
+__vgpu_write(16)
+__vgpu_write(32)
+__vgpu_write(64)
+
+#undef __vgpu_write
+#undef VGPU_WRITE_FOOTER
+#undef VGPU_WRITE_HEADER
+
+#define ASSIGN_WRITE_MMIO_VFUNCS(x) \
+do { \
+	dev_priv->uncore.funcs.mmio_writeb = x##_write8; \
+	dev_priv->uncore.funcs.mmio_writew = x##_write16; \
+	dev_priv->uncore.funcs.mmio_writel = x##_write32; \
+	dev_priv->uncore.funcs.mmio_writeq = x##_write64; \
+} while (0)
+
+#define ASSIGN_READ_MMIO_VFUNCS(x) \
+do { \
+	dev_priv->uncore.funcs.mmio_readb = x##_read8; \
+	dev_priv->uncore.funcs.mmio_readw = x##_read16; \
+	dev_priv->uncore.funcs.mmio_readl = x##_read32; \
+	dev_priv->uncore.funcs.mmio_readq = x##_read64; \
+} while (0)
+
+
+static void fw_domain_init(struct drm_i915_private *dev_priv,
+			   enum forcewake_domain_id domain_id,
+			   i915_reg_t reg_set,
+			   i915_reg_t reg_ack)
+{
+	struct intel_uncore_forcewake_domain *d;
+
+	if (WARN_ON(domain_id >= FW_DOMAIN_ID_COUNT))
+		return;
+
+	d = &dev_priv->uncore.fw_domain[domain_id];
+
+	WARN_ON(d->wake_count);
+
+	d->wake_count = 0;
+	d->reg_set = reg_set;
+	d->reg_ack = reg_ack;
+
+	if (IS_GEN6(dev_priv)) {
+		d->val_reset = 0;
+		d->val_set = FORCEWAKE_KERNEL;
+		d->val_clear = 0;
+	} else {
+		/* WaRsClearFWBitsAtReset:bdw,skl */
+		d->val_reset = _MASKED_BIT_DISABLE(0xffff);
+		d->val_set = _MASKED_BIT_ENABLE(FORCEWAKE_KERNEL);
+		d->val_clear = _MASKED_BIT_DISABLE(FORCEWAKE_KERNEL);
+	}
+
+	if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
+		d->reg_post = FORCEWAKE_ACK_VLV;
+	else if (IS_GEN6(dev_priv) || IS_GEN7(dev_priv) || IS_GEN8(dev_priv))
+		d->reg_post = ECOBUS;
+
+	d->i915 = dev_priv;
+	d->id = domain_id;
+
+	BUILD_BUG_ON(FORCEWAKE_RENDER != (1 << FW_DOMAIN_ID_RENDER));
+	BUILD_BUG_ON(FORCEWAKE_BLITTER != (1 << FW_DOMAIN_ID_BLITTER));
+	BUILD_BUG_ON(FORCEWAKE_MEDIA != (1 << FW_DOMAIN_ID_MEDIA));
+
+	d->mask = 1 << domain_id;
+
+	hrtimer_init(&d->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
+	d->timer.function = intel_uncore_fw_release_timer;
+
+	dev_priv->uncore.fw_domains |= (1 << domain_id);
+
+	fw_domain_reset(d);
+}
+
+static void intel_uncore_fw_domains_init(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	if (INTEL_INFO(dev_priv)->gen <= 5)
+		return;
+
+	if (IS_GEN9(dev)) {
+		dev_priv->uncore.funcs.force_wake_get = fw_domains_get;
+		dev_priv->uncore.funcs.force_wake_put = fw_domains_put;
+		fw_domain_init(dev_priv, FW_DOMAIN_ID_RENDER,
+			       FORCEWAKE_RENDER_GEN9,
+			       FORCEWAKE_ACK_RENDER_GEN9);
+		fw_domain_init(dev_priv, FW_DOMAIN_ID_BLITTER,
+			       FORCEWAKE_BLITTER_GEN9,
+			       FORCEWAKE_ACK_BLITTER_GEN9);
+		fw_domain_init(dev_priv, FW_DOMAIN_ID_MEDIA,
+			       FORCEWAKE_MEDIA_GEN9, FORCEWAKE_ACK_MEDIA_GEN9);
+	} else if (IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev)) {
+		dev_priv->uncore.funcs.force_wake_get = fw_domains_get;
+		if (!IS_CHERRYVIEW(dev))
+			dev_priv->uncore.funcs.force_wake_put =
+				fw_domains_put_with_fifo;
+		else
+			dev_priv->uncore.funcs.force_wake_put = fw_domains_put;
+		fw_domain_init(dev_priv, FW_DOMAIN_ID_RENDER,
+			       FORCEWAKE_VLV, FORCEWAKE_ACK_VLV);
+		fw_domain_init(dev_priv, FW_DOMAIN_ID_MEDIA,
+			       FORCEWAKE_MEDIA_VLV, FORCEWAKE_ACK_MEDIA_VLV);
+	} else if (IS_HASWELL(dev) || IS_BROADWELL(dev)) {
+		dev_priv->uncore.funcs.force_wake_get =
+			fw_domains_get_with_thread_status;
+		if (IS_HASWELL(dev))
+			dev_priv->uncore.funcs.force_wake_put =
+				fw_domains_put_with_fifo;
+		else
+			dev_priv->uncore.funcs.force_wake_put = fw_domains_put;
+		fw_domain_init(dev_priv, FW_DOMAIN_ID_RENDER,
+			       FORCEWAKE_MT, FORCEWAKE_ACK_HSW);
+	} else if (IS_IVYBRIDGE(dev)) {
+		u32 ecobus;
+
+		/* IVB configs may use multi-threaded forcewake */
+
+		/* A small trick here - if the bios hasn't configured
+		 * MT forcewake, and if the device is in RC6, then
+		 * force_wake_mt_get will not wake the device and the
+		 * ECOBUS read will return zero. Which will be
+		 * (correctly) interpreted by the test below as MT
+		 * forcewake being disabled.
+		 */
+		dev_priv->uncore.funcs.force_wake_get =
+			fw_domains_get_with_thread_status;
+		dev_priv->uncore.funcs.force_wake_put =
+			fw_domains_put_with_fifo;
+
+		/* We need to init first for ECOBUS access and then
+		 * determine later if we want to reinit, in case of MT access is
+		 * not working. In this stage we don't know which flavour this
+		 * ivb is, so it is better to reset also the gen6 fw registers
+		 * before the ecobus check.
+		 */
+
+		__raw_i915_write32(dev_priv, FORCEWAKE, 0);
+		__raw_posting_read(dev_priv, ECOBUS);
+
+		fw_domain_init(dev_priv, FW_DOMAIN_ID_RENDER,
+			       FORCEWAKE_MT, FORCEWAKE_MT_ACK);
+
+		mutex_lock(&dev->struct_mutex);
+		fw_domains_get_with_thread_status(dev_priv, FORCEWAKE_ALL);
+		ecobus = __raw_i915_read32(dev_priv, ECOBUS);
+		fw_domains_put_with_fifo(dev_priv, FORCEWAKE_ALL);
+		mutex_unlock(&dev->struct_mutex);
+
+		if (!(ecobus & FORCEWAKE_MT_ENABLE)) {
+			DRM_INFO("No MT forcewake available on Ivybridge, this can result in issues\n");
+			DRM_INFO("when using vblank-synced partial screen updates.\n");
+			fw_domain_init(dev_priv, FW_DOMAIN_ID_RENDER,
+				       FORCEWAKE, FORCEWAKE_ACK);
+		}
+	} else if (IS_GEN6(dev)) {
+		dev_priv->uncore.funcs.force_wake_get =
+			fw_domains_get_with_thread_status;
+		dev_priv->uncore.funcs.force_wake_put =
+			fw_domains_put_with_fifo;
+		fw_domain_init(dev_priv, FW_DOMAIN_ID_RENDER,
+			       FORCEWAKE, FORCEWAKE_ACK);
+	}
+
+	/* All future platforms are expected to require complex power gating */
+	WARN_ON(dev_priv->uncore.fw_domains == 0);
+}
+
+void intel_uncore_init(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	i915_check_vgpu(dev);
+
+	intel_uncore_edram_detect(dev_priv);
+	intel_uncore_fw_domains_init(dev);
+	__intel_uncore_early_sanitize(dev, false);
+
+	dev_priv->uncore.unclaimed_mmio_check = 1;
+
+	switch (INTEL_INFO(dev)->gen) {
+	default:
+	case 9:
+		ASSIGN_WRITE_MMIO_VFUNCS(gen9);
+		ASSIGN_READ_MMIO_VFUNCS(gen9);
+		break;
+	case 8:
+		if (IS_CHERRYVIEW(dev)) {
+			ASSIGN_WRITE_MMIO_VFUNCS(chv);
+			ASSIGN_READ_MMIO_VFUNCS(chv);
+
+		} else {
+			ASSIGN_WRITE_MMIO_VFUNCS(gen8);
+			ASSIGN_READ_MMIO_VFUNCS(gen6);
+		}
+		break;
+	case 7:
+	case 6:
+		if (IS_HASWELL(dev)) {
+			ASSIGN_WRITE_MMIO_VFUNCS(hsw);
+		} else {
+			ASSIGN_WRITE_MMIO_VFUNCS(gen6);
+		}
+
+		if (IS_VALLEYVIEW(dev)) {
+			ASSIGN_READ_MMIO_VFUNCS(vlv);
+		} else {
+			ASSIGN_READ_MMIO_VFUNCS(gen6);
+		}
+		break;
+	case 5:
+		ASSIGN_WRITE_MMIO_VFUNCS(gen5);
+		ASSIGN_READ_MMIO_VFUNCS(gen5);
+		break;
+	case 4:
+	case 3:
+	case 2:
+		ASSIGN_WRITE_MMIO_VFUNCS(gen2);
+		ASSIGN_READ_MMIO_VFUNCS(gen2);
+		break;
+	}
+
+	if (intel_vgpu_active(dev)) {
+		ASSIGN_WRITE_MMIO_VFUNCS(vgpu);
+		ASSIGN_READ_MMIO_VFUNCS(vgpu);
+	}
+
+	i915_check_and_clear_faults(dev);
+}
+#undef ASSIGN_WRITE_MMIO_VFUNCS
+#undef ASSIGN_READ_MMIO_VFUNCS
+
+void intel_uncore_fini(struct drm_device *dev)
+{
+	/* Paranoia: make sure we have disabled everything before we exit. */
+	intel_uncore_sanitize(dev);
+	intel_uncore_forcewake_reset(dev, false);
+}
+
+#define GEN_RANGE(l, h) GENMASK(h, l)
+
+static const struct register_whitelist {
+	i915_reg_t offset_ldw, offset_udw;
+	uint32_t size;
+	/* supported gens, 0x10 for 4, 0x30 for 4 and 5, etc. */
+	uint32_t gen_bitmask;
+} whitelist[] = {
+	{ .offset_ldw = RING_TIMESTAMP(RENDER_RING_BASE),
+	  .offset_udw = RING_TIMESTAMP_UDW(RENDER_RING_BASE),
+	  .size = 8, .gen_bitmask = GEN_RANGE(4, 9) },
+};
+
+int i915_reg_read_ioctl(struct drm_device *dev,
+			void *data, struct drm_file *file)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct drm_i915_reg_read *reg = data;
+	struct register_whitelist const *entry = whitelist;
+	unsigned size;
+	i915_reg_t offset_ldw, offset_udw;
+	int i, ret = 0;
+
+	for (i = 0; i < ARRAY_SIZE(whitelist); i++, entry++) {
+		if (i915_mmio_reg_offset(entry->offset_ldw) == (reg->offset & -entry->size) &&
+		    (1 << INTEL_INFO(dev)->gen & entry->gen_bitmask))
+			break;
+	}
+
+	if (i == ARRAY_SIZE(whitelist))
+		return -EINVAL;
+
+	/* We use the low bits to encode extra flags as the register should
+	 * be naturally aligned (and those that are not so aligned merely
+	 * limit the available flags for that register).
+	 */
+	offset_ldw = entry->offset_ldw;
+	offset_udw = entry->offset_udw;
+	size = entry->size;
+	size |= reg->offset ^ i915_mmio_reg_offset(offset_ldw);
+
+	intel_runtime_pm_get(dev_priv);
+
+	switch (size) {
+	case 8 | 1:
+		reg->val = I915_READ64_2x32(offset_ldw, offset_udw);
+		break;
+	case 8:
+		reg->val = I915_READ64(offset_ldw);
+		break;
+	case 4:
+		reg->val = I915_READ(offset_ldw);
+		break;
+	case 2:
+		reg->val = I915_READ16(offset_ldw);
+		break;
+	case 1:
+		reg->val = I915_READ8(offset_ldw);
+		break;
+	default:
+		ret = -EINVAL;
+		goto out;
+	}
+
+out:
+	intel_runtime_pm_put(dev_priv);
+	return ret;
+}
+
+int i915_get_reset_stats_ioctl(struct drm_device *dev,
+			       void *data, struct drm_file *file)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct drm_i915_reset_stats *args = data;
+	struct i915_ctx_hang_stats *hs;
+	struct intel_context *ctx;
+	int ret;
+
+	if (args->flags || args->pad)
+		return -EINVAL;
+
+	if (args->ctx_id == DEFAULT_CONTEXT_HANDLE && !capable(CAP_SYS_ADMIN))
+		return -EPERM;
+
+	ret = mutex_lock_interruptible(&dev->struct_mutex);
+	if (ret)
+		return ret;
+
+	ctx = i915_gem_context_get(file->driver_priv, args->ctx_id);
+	if (IS_ERR(ctx)) {
+		mutex_unlock(&dev->struct_mutex);
+		return PTR_ERR(ctx);
+	}
+	hs = &ctx->hang_stats;
+
+	if (capable(CAP_SYS_ADMIN))
+		args->reset_count = i915_reset_count(&dev_priv->gpu_error);
+	else
+		args->reset_count = 0;
+
+	args->batch_active = hs->batch_active;
+	args->batch_pending = hs->batch_pending;
+
+	mutex_unlock(&dev->struct_mutex);
+
+	return 0;
+}
+
+static int i915_reset_complete(struct drm_device *dev)
+{
+	u8 gdrst;
+	pci_read_config_byte(dev->pdev, I915_GDRST, &gdrst);
+	return (gdrst & GRDOM_RESET_STATUS) == 0;
+}
+
+static int i915_do_reset(struct drm_device *dev, unsigned engine_mask)
+{
+	/* assert reset for at least 20 usec */
+	pci_write_config_byte(dev->pdev, I915_GDRST, GRDOM_RESET_ENABLE);
+	udelay(20);
+	pci_write_config_byte(dev->pdev, I915_GDRST, 0);
+
+	return wait_for(i915_reset_complete(dev), 500);
+}
+
+static int g4x_reset_complete(struct drm_device *dev)
+{
+	u8 gdrst;
+	pci_read_config_byte(dev->pdev, I915_GDRST, &gdrst);
+	return (gdrst & GRDOM_RESET_ENABLE) == 0;
+}
+
+static int g33_do_reset(struct drm_device *dev, unsigned engine_mask)
+{
+	pci_write_config_byte(dev->pdev, I915_GDRST, GRDOM_RESET_ENABLE);
+	return wait_for(g4x_reset_complete(dev), 500);
+}
+
+static int g4x_do_reset(struct drm_device *dev, unsigned engine_mask)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	int ret;
+
+	pci_write_config_byte(dev->pdev, I915_GDRST,
+			      GRDOM_RENDER | GRDOM_RESET_ENABLE);
+	ret =  wait_for(g4x_reset_complete(dev), 500);
+	if (ret)
+		return ret;
+
+	/* WaVcpClkGateDisableForMediaReset:ctg,elk */
+	I915_WRITE(VDECCLK_GATE_D, I915_READ(VDECCLK_GATE_D) | VCP_UNIT_CLOCK_GATE_DISABLE);
+	POSTING_READ(VDECCLK_GATE_D);
+
+	pci_write_config_byte(dev->pdev, I915_GDRST,
+			      GRDOM_MEDIA | GRDOM_RESET_ENABLE);
+	ret =  wait_for(g4x_reset_complete(dev), 500);
+	if (ret)
+		return ret;
+
+	/* WaVcpClkGateDisableForMediaReset:ctg,elk */
+	I915_WRITE(VDECCLK_GATE_D, I915_READ(VDECCLK_GATE_D) & ~VCP_UNIT_CLOCK_GATE_DISABLE);
+	POSTING_READ(VDECCLK_GATE_D);
+
+	pci_write_config_byte(dev->pdev, I915_GDRST, 0);
+
+	return 0;
+}
+
+static int ironlake_do_reset(struct drm_device *dev, unsigned engine_mask)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	int ret;
+
+	I915_WRITE(ILK_GDSR,
+		   ILK_GRDOM_RENDER | ILK_GRDOM_RESET_ENABLE);
+	ret = wait_for((I915_READ(ILK_GDSR) &
+			ILK_GRDOM_RESET_ENABLE) == 0, 500);
+	if (ret)
+		return ret;
+
+	I915_WRITE(ILK_GDSR,
+		   ILK_GRDOM_MEDIA | ILK_GRDOM_RESET_ENABLE);
+	ret = wait_for((I915_READ(ILK_GDSR) &
+			ILK_GRDOM_RESET_ENABLE) == 0, 500);
+	if (ret)
+		return ret;
+
+	I915_WRITE(ILK_GDSR, 0);
+
+	return 0;
+}
+
+/* Reset the hardware domains (GENX_GRDOM_*) specified by mask */
+static int gen6_hw_domain_reset(struct drm_i915_private *dev_priv,
+				u32 hw_domain_mask)
+{
+	int ret;
+
+	/* GEN6_GDRST is not in the gt power well, no need to check
+	 * for fifo space for the write or forcewake the chip for
+	 * the read
+	 */
+	__raw_i915_write32(dev_priv, GEN6_GDRST, hw_domain_mask);
+
+#define ACKED ((__raw_i915_read32(dev_priv, GEN6_GDRST) & hw_domain_mask) == 0)
+	/* Spin waiting for the device to ack the reset requests */
+	ret = wait_for(ACKED, 500);
+#undef ACKED
+
+	return ret;
+}
+
+/**
+ * gen6_reset_engines - reset individual engines
+ * @dev: DRM device
+ * @engine_mask: mask of intel_ring_flag() engines or ALL_ENGINES for full reset
+ *
+ * This function will reset the individual engines that are set in engine_mask.
+ * If you provide ALL_ENGINES as mask, full global domain reset will be issued.
+ *
+ * Note: It is responsibility of the caller to handle the difference between
+ * asking full domain reset versus reset for all available individual engines.
+ *
+ * Returns 0 on success, nonzero on error.
+ */
+static int gen6_reset_engines(struct drm_device *dev, unsigned engine_mask)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_engine_cs *engine;
+	const u32 hw_engine_mask[I915_NUM_ENGINES] = {
+		[RCS] = GEN6_GRDOM_RENDER,
+		[BCS] = GEN6_GRDOM_BLT,
+		[VCS] = GEN6_GRDOM_MEDIA,
+		[VCS2] = GEN8_GRDOM_MEDIA2,
+		[VECS] = GEN6_GRDOM_VECS,
+	};
+	u32 hw_mask;
+	int ret;
+
+	if (engine_mask == ALL_ENGINES) {
+		hw_mask = GEN6_GRDOM_FULL;
+	} else {
+		hw_mask = 0;
+		for_each_engine_masked(engine, dev_priv, engine_mask)
+			hw_mask |= hw_engine_mask[engine->id];
+	}
+
+	ret = gen6_hw_domain_reset(dev_priv, hw_mask);
+
+	intel_uncore_forcewake_reset(dev, true);
+
+	return ret;
+}
+
+static int wait_for_register_fw(struct drm_i915_private *dev_priv,
+				i915_reg_t reg,
+				const u32 mask,
+				const u32 value,
+				const unsigned long timeout_ms)
+{
+	return wait_for((I915_READ_FW(reg) & mask) == value, timeout_ms);
+}
+
+static int gen8_request_engine_reset(struct intel_engine_cs *engine)
+{
+	int ret;
+	struct drm_i915_private *dev_priv = engine->dev->dev_private;
+
+	I915_WRITE_FW(RING_RESET_CTL(engine->mmio_base),
+		      _MASKED_BIT_ENABLE(RESET_CTL_REQUEST_RESET));
+
+	ret = wait_for_register_fw(dev_priv,
+				   RING_RESET_CTL(engine->mmio_base),
+				   RESET_CTL_READY_TO_RESET,
+				   RESET_CTL_READY_TO_RESET,
+				   700);
+	if (ret)
+		DRM_ERROR("%s: reset request timeout\n", engine->name);
+
+	return ret;
+}
+
+static void gen8_unrequest_engine_reset(struct intel_engine_cs *engine)
+{
+	struct drm_i915_private *dev_priv = engine->dev->dev_private;
+
+	I915_WRITE_FW(RING_RESET_CTL(engine->mmio_base),
+		      _MASKED_BIT_DISABLE(RESET_CTL_REQUEST_RESET));
+}
+
+static int gen8_reset_engines(struct drm_device *dev, unsigned engine_mask)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_engine_cs *engine;
+
+	for_each_engine_masked(engine, dev_priv, engine_mask)
+		if (gen8_request_engine_reset(engine))
+			goto not_ready;
+
+	return gen6_reset_engines(dev, engine_mask);
+
+not_ready:
+	for_each_engine_masked(engine, dev_priv, engine_mask)
+		gen8_unrequest_engine_reset(engine);
+
+	return -EIO;
+}
+
+static int (*intel_get_gpu_reset(struct drm_device *dev))(struct drm_device *,
+							  unsigned engine_mask)
+{
+	if (!i915.reset)
+		return NULL;
+
+	if (INTEL_INFO(dev)->gen >= 8)
+		return gen8_reset_engines;
+	else if (INTEL_INFO(dev)->gen >= 6)
+		return gen6_reset_engines;
+	else if (IS_GEN5(dev))
+		return ironlake_do_reset;
+	else if (IS_G4X(dev))
+		return g4x_do_reset;
+	else if (IS_G33(dev))
+		return g33_do_reset;
+	else if (INTEL_INFO(dev)->gen >= 3)
+		return i915_do_reset;
+	else
+		return NULL;
+}
+
+int intel_gpu_reset(struct drm_device *dev, unsigned engine_mask)
+{
+	struct drm_i915_private *dev_priv = to_i915(dev);
+	int (*reset)(struct drm_device *, unsigned);
+	int ret;
+
+	reset = intel_get_gpu_reset(dev);
+	if (reset == NULL)
+		return -ENODEV;
+
+	/* If the power well sleeps during the reset, the reset
+	 * request may be dropped and never completes (causing -EIO).
+	 */
+	intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL);
+	ret = reset(dev, engine_mask);
+	intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
+
+	return ret;
+}
+
+bool intel_has_gpu_reset(struct drm_device *dev)
+{
+	return intel_get_gpu_reset(dev) != NULL;
+}
+
+int intel_guc_reset(struct drm_i915_private *dev_priv)
+{
+	int ret;
+	unsigned long irqflags;
+
+	if (!i915.enable_guc_submission)
+		return -EINVAL;
+
+	intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL);
+	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
+
+	ret = gen6_hw_domain_reset(dev_priv, GEN9_GRDOM_GUC);
+
+	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
+	intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
+
+	return ret;
+}
+
+bool intel_uncore_unclaimed_mmio(struct drm_i915_private *dev_priv)
+{
+	return check_for_unclaimed_mmio(dev_priv);
+}
+
+bool
+intel_uncore_arm_unclaimed_mmio_detection(struct drm_i915_private *dev_priv)
+{
+	if (unlikely(i915.mmio_debug ||
+		     dev_priv->uncore.unclaimed_mmio_check <= 0))
+		return false;
+
+	if (unlikely(intel_uncore_unclaimed_mmio(dev_priv))) {
+		DRM_DEBUG("Unclaimed register detected, "
+			  "enabling oneshot unclaimed register reporting. "
+			  "Please use i915.mmio_debug=N for more information.\n");
+		i915.mmio_debug++;
+		dev_priv->uncore.unclaimed_mmio_check--;
+		return true;
+	}
+
+	return false;
+}
+
+static enum forcewake_domains
+intel_uncore_forcewake_for_read(struct drm_i915_private *dev_priv,
+				i915_reg_t reg)
+{
+	enum forcewake_domains fw_domains;
+
+	if (intel_vgpu_active(dev_priv->dev))
+		return 0;
+
+	switch (INTEL_INFO(dev_priv)->gen) {
+	case 9:
+		fw_domains = __gen9_reg_read_fw_domains(i915_mmio_reg_offset(reg));
+		break;
+	case 8:
+		if (IS_CHERRYVIEW(dev_priv))
+			fw_domains = __chv_reg_read_fw_domains(i915_mmio_reg_offset(reg));
+		else
+			fw_domains = __gen6_reg_read_fw_domains(i915_mmio_reg_offset(reg));
+		break;
+	case 7:
+	case 6:
+		if (IS_VALLEYVIEW(dev_priv))
+			fw_domains = __vlv_reg_read_fw_domains(i915_mmio_reg_offset(reg));
+		else
+			fw_domains = __gen6_reg_read_fw_domains(i915_mmio_reg_offset(reg));
+		break;
+	default:
+		MISSING_CASE(INTEL_INFO(dev_priv)->gen);
+	case 5: /* forcewake was introduced with gen6 */
+	case 4:
+	case 3:
+	case 2:
+		return 0;
+	}
+
+	WARN_ON(fw_domains & ~dev_priv->uncore.fw_domains);
+
+	return fw_domains;
+}
+
+static enum forcewake_domains
+intel_uncore_forcewake_for_write(struct drm_i915_private *dev_priv,
+				 i915_reg_t reg)
+{
+	enum forcewake_domains fw_domains;
+
+	if (intel_vgpu_active(dev_priv->dev))
+		return 0;
+
+	switch (INTEL_INFO(dev_priv)->gen) {
+	case 9:
+		fw_domains = __gen9_reg_write_fw_domains(i915_mmio_reg_offset(reg));
+		break;
+	case 8:
+		if (IS_CHERRYVIEW(dev_priv))
+			fw_domains = __chv_reg_write_fw_domains(i915_mmio_reg_offset(reg));
+		else
+			fw_domains = __gen8_reg_write_fw_domains(i915_mmio_reg_offset(reg));
+		break;
+	case 7:
+	case 6:
+		fw_domains = FORCEWAKE_RENDER;
+		break;
+	default:
+		MISSING_CASE(INTEL_INFO(dev_priv)->gen);
+	case 5:
+	case 4:
+	case 3:
+	case 2:
+		return 0;
+	}
+
+	WARN_ON(fw_domains & ~dev_priv->uncore.fw_domains);
+
+	return fw_domains;
+}
+
+/**
+ * intel_uncore_forcewake_for_reg - which forcewake domains are needed to access
+ * 				    a register
+ * @dev_priv: pointer to struct drm_i915_private
+ * @reg: register in question
+ * @op: operation bitmask of FW_REG_READ and/or FW_REG_WRITE
+ *
+ * Returns a set of forcewake domains required to be taken with for example
+ * intel_uncore_forcewake_get for the specified register to be accessible in the
+ * specified mode (read, write or read/write) with raw mmio accessors.
+ *
+ * NOTE: On Gen6 and Gen7 write forcewake domain (FORCEWAKE_RENDER) requires the
+ * callers to do FIFO management on their own or risk losing writes.
+ */
+enum forcewake_domains
+intel_uncore_forcewake_for_reg(struct drm_i915_private *dev_priv,
+			       i915_reg_t reg, unsigned int op)
+{
+	enum forcewake_domains fw_domains = 0;
+
+	WARN_ON(!op);
+
+	if (op & FW_REG_READ)
+		fw_domains = intel_uncore_forcewake_for_read(dev_priv, reg);
+
+	if (op & FW_REG_WRITE)
+		fw_domains |= intel_uncore_forcewake_for_write(dev_priv, reg);
+
+	return fw_domains;
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/i915/intel_vbt_defs.h
@@ -0,0 +1,845 @@
+/*
+ * Copyright © 2006-2016 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Authors:
+ *    Eric Anholt <eric@anholt.net>
+ *
+ */
+
+/*
+ * This information is private to VBT parsing in intel_bios.c.
+ *
+ * Please do NOT include anywhere else.
+ */
+#ifndef _INTEL_BIOS_PRIVATE
+#error "intel_vbt_defs.h is private to intel_bios.c"
+#endif
+
+#ifndef _INTEL_VBT_DEFS_H_
+#define _INTEL_VBT_DEFS_H_
+
+#include "intel_bios.h"
+
+/**
+ * struct vbt_header - VBT Header structure
+ * @signature:		VBT signature, always starts with "$VBT"
+ * @version:		Version of this structure
+ * @header_size:	Size of this structure
+ * @vbt_size:		Size of VBT (VBT Header, BDB Header and data blocks)
+ * @vbt_checksum:	Checksum
+ * @reserved0:		Reserved
+ * @bdb_offset:		Offset of &struct bdb_header from beginning of VBT
+ * @aim_offset:		Offsets of add-in data blocks from beginning of VBT
+ */
+struct vbt_header {
+	u8 signature[20];
+	u16 version;
+	u16 header_size;
+	u16 vbt_size;
+	u8 vbt_checksum;
+	u8 reserved0;
+	u32 bdb_offset;
+	u32 aim_offset[4];
+} __packed;
+
+/**
+ * struct bdb_header - BDB Header structure
+ * @signature:		BDB signature "BIOS_DATA_BLOCK"
+ * @version:		Version of the data block definitions
+ * @header_size:	Size of this structure
+ * @bdb_size:		Size of BDB (BDB Header and data blocks)
+ */
+struct bdb_header {
+	u8 signature[16];
+	u16 version;
+	u16 header_size;
+	u16 bdb_size;
+} __packed;
+
+/* strictly speaking, this is a "skip" block, but it has interesting info */
+struct vbios_data {
+	u8 type; /* 0 == desktop, 1 == mobile */
+	u8 relstage;
+	u8 chipset;
+	u8 lvds_present:1;
+	u8 tv_present:1;
+	u8 rsvd2:6; /* finish byte */
+	u8 rsvd3[4];
+	u8 signon[155];
+	u8 copyright[61];
+	u16 code_segment;
+	u8 dos_boot_mode;
+	u8 bandwidth_percent;
+	u8 rsvd4; /* popup memory size */
+	u8 resize_pci_bios;
+	u8 rsvd5; /* is crt already on ddc2 */
+} __packed;
+
+/*
+ * There are several types of BIOS data blocks (BDBs), each block has
+ * an ID and size in the first 3 bytes (ID in first, size in next 2).
+ * Known types are listed below.
+ */
+#define BDB_GENERAL_FEATURES	  1
+#define BDB_GENERAL_DEFINITIONS	  2
+#define BDB_OLD_TOGGLE_LIST	  3
+#define BDB_MODE_SUPPORT_LIST	  4
+#define BDB_GENERIC_MODE_TABLE	  5
+#define BDB_EXT_MMIO_REGS	  6
+#define BDB_SWF_IO		  7
+#define BDB_SWF_MMIO		  8
+#define BDB_PSR			  9
+#define BDB_MODE_REMOVAL_TABLE	 10
+#define BDB_CHILD_DEVICE_TABLE	 11
+#define BDB_DRIVER_FEATURES	 12
+#define BDB_DRIVER_PERSISTENCE	 13
+#define BDB_EXT_TABLE_PTRS	 14
+#define BDB_DOT_CLOCK_OVERRIDE	 15
+#define BDB_DISPLAY_SELECT	 16
+/* 17 rsvd */
+#define BDB_DRIVER_ROTATION	 18
+#define BDB_DISPLAY_REMOVE	 19
+#define BDB_OEM_CUSTOM		 20
+#define BDB_EFP_LIST		 21 /* workarounds for VGA hsync/vsync */
+#define BDB_SDVO_LVDS_OPTIONS	 22
+#define BDB_SDVO_PANEL_DTDS	 23
+#define BDB_SDVO_LVDS_PNP_IDS	 24
+#define BDB_SDVO_LVDS_POWER_SEQ	 25
+#define BDB_TV_OPTIONS		 26
+#define BDB_EDP			 27
+#define BDB_LVDS_OPTIONS	 40
+#define BDB_LVDS_LFP_DATA_PTRS	 41
+#define BDB_LVDS_LFP_DATA	 42
+#define BDB_LVDS_BACKLIGHT	 43
+#define BDB_LVDS_POWER		 44
+#define BDB_MIPI_CONFIG		 52
+#define BDB_MIPI_SEQUENCE	 53
+#define BDB_SKIP		254 /* VBIOS private block, ignore */
+
+struct bdb_general_features {
+        /* bits 1 */
+	u8 panel_fitting:2;
+	u8 flexaim:1;
+	u8 msg_enable:1;
+	u8 clear_screen:3;
+	u8 color_flip:1;
+
+        /* bits 2 */
+	u8 download_ext_vbt:1;
+	u8 enable_ssc:1;
+	u8 ssc_freq:1;
+	u8 enable_lfp_on_override:1;
+	u8 disable_ssc_ddt:1;
+	u8 rsvd7:1;
+	u8 display_clock_mode:1;
+	u8 rsvd8:1; /* finish byte */
+
+        /* bits 3 */
+	u8 disable_smooth_vision:1;
+	u8 single_dvi:1;
+	u8 rsvd9:1;
+	u8 fdi_rx_polarity_inverted:1;
+	u8 rsvd10:4; /* finish byte */
+
+        /* bits 4 */
+	u8 legacy_monitor_detect;
+
+        /* bits 5 */
+	u8 int_crt_support:1;
+	u8 int_tv_support:1;
+	u8 int_efp_support:1;
+	u8 dp_ssc_enb:1;	/* PCH attached eDP supports SSC */
+	u8 dp_ssc_freq:1;	/* SSC freq for PCH attached eDP */
+	u8 rsvd11:3; /* finish byte */
+} __packed;
+
+/* pre-915 */
+#define GPIO_PIN_DVI_LVDS	0x03 /* "DVI/LVDS DDC GPIO pins" */
+#define GPIO_PIN_ADD_I2C	0x05 /* "ADDCARD I2C GPIO pins" */
+#define GPIO_PIN_ADD_DDC	0x04 /* "ADDCARD DDC GPIO pins" */
+#define GPIO_PIN_ADD_DDC_I2C	0x06 /* "ADDCARD DDC/I2C GPIO pins" */
+
+/* Pre 915 */
+#define DEVICE_TYPE_NONE	0x00
+#define DEVICE_TYPE_CRT		0x01
+#define DEVICE_TYPE_TV		0x09
+#define DEVICE_TYPE_EFP		0x12
+#define DEVICE_TYPE_LFP		0x22
+/* On 915+ */
+#define DEVICE_TYPE_CRT_DPMS		0x6001
+#define DEVICE_TYPE_CRT_DPMS_HOTPLUG	0x4001
+#define DEVICE_TYPE_TV_COMPOSITE	0x0209
+#define DEVICE_TYPE_TV_MACROVISION	0x0289
+#define DEVICE_TYPE_TV_RF_COMPOSITE	0x020c
+#define DEVICE_TYPE_TV_SVIDEO_COMPOSITE	0x0609
+#define DEVICE_TYPE_TV_SCART		0x0209
+#define DEVICE_TYPE_TV_CODEC_HOTPLUG_PWR 0x6009
+#define DEVICE_TYPE_EFP_HOTPLUG_PWR	0x6012
+#define DEVICE_TYPE_EFP_DVI_HOTPLUG_PWR	0x6052
+#define DEVICE_TYPE_EFP_DVI_I		0x6053
+#define DEVICE_TYPE_EFP_DVI_D_DUAL	0x6152
+#define DEVICE_TYPE_EFP_DVI_D_HDCP	0x60d2
+#define DEVICE_TYPE_OPENLDI_HOTPLUG_PWR	0x6062
+#define DEVICE_TYPE_OPENLDI_DUALPIX	0x6162
+#define DEVICE_TYPE_LFP_PANELLINK	0x5012
+#define DEVICE_TYPE_LFP_CMOS_PWR	0x5042
+#define DEVICE_TYPE_LFP_LVDS_PWR	0x5062
+#define DEVICE_TYPE_LFP_LVDS_DUAL	0x5162
+#define DEVICE_TYPE_LFP_LVDS_DUAL_HDCP	0x51e2
+
+#define DEVICE_CFG_NONE		0x00
+#define DEVICE_CFG_12BIT_DVOB	0x01
+#define DEVICE_CFG_12BIT_DVOC	0x02
+#define DEVICE_CFG_24BIT_DVOBC	0x09
+#define DEVICE_CFG_24BIT_DVOCB	0x0a
+#define DEVICE_CFG_DUAL_DVOB	0x11
+#define DEVICE_CFG_DUAL_DVOC	0x12
+#define DEVICE_CFG_DUAL_DVOBC	0x13
+#define DEVICE_CFG_DUAL_LINK_DVOBC	0x19
+#define DEVICE_CFG_DUAL_LINK_DVOCB	0x1a
+
+#define DEVICE_WIRE_NONE	0x00
+#define DEVICE_WIRE_DVOB	0x01
+#define DEVICE_WIRE_DVOC	0x02
+#define DEVICE_WIRE_DVOBC	0x03
+#define DEVICE_WIRE_DVOBB	0x05
+#define DEVICE_WIRE_DVOCC	0x06
+#define DEVICE_WIRE_DVOB_MASTER 0x0d
+#define DEVICE_WIRE_DVOC_MASTER 0x0e
+
+#define DEVICE_PORT_DVOA	0x00 /* none on 845+ */
+#define DEVICE_PORT_DVOB	0x01
+#define DEVICE_PORT_DVOC	0x02
+
+/*
+ * We used to keep this struct but without any version control. We should avoid
+ * using it in the future, but it should be safe to keep using it in the old
+ * code. Do not change; we rely on its size.
+ */
+struct old_child_dev_config {
+	u16 handle;
+	u16 device_type;
+	u8  device_id[10]; /* ascii string */
+	u16 addin_offset;
+	u8  dvo_port; /* See Device_PORT_* above */
+	u8  i2c_pin;
+	u8  slave_addr;
+	u8  ddc_pin;
+	u16 edid_ptr;
+	u8  dvo_cfg; /* See DEVICE_CFG_* above */
+	u8  dvo2_port;
+	u8  i2c2_pin;
+	u8  slave2_addr;
+	u8  ddc2_pin;
+	u8  capabilities;
+	u8  dvo_wiring;/* See DEVICE_WIRE_* above */
+	u8  dvo2_wiring;
+	u16 extended_type;
+	u8  dvo_function;
+} __packed;
+
+/* This one contains field offsets that are known to be common for all BDB
+ * versions. Notice that the meaning of the contents contents may still change,
+ * but at least the offsets are consistent. */
+
+struct common_child_dev_config {
+	u16 handle;
+	u16 device_type;
+	u8 not_common1[12];
+	u8 dvo_port;
+	u8 not_common2[2];
+	u8 ddc_pin;
+	u16 edid_ptr;
+	u8 dvo_cfg; /* See DEVICE_CFG_* above */
+	u8 efp_routed:1;
+	u8 lane_reversal:1;
+	u8 lspcon:1;
+	u8 iboost:1;
+	u8 hpd_invert:1;
+	u8 flag_reserved:3;
+	u8 hdmi_support:1;
+	u8 dp_support:1;
+	u8 tmds_support:1;
+	u8 support_reserved:5;
+	u8 not_common3[12];
+	u8 iboost_level;
+} __packed;
+
+
+/* This field changes depending on the BDB version, so the most reliable way to
+ * read it is by checking the BDB version and reading the raw pointer. */
+union child_device_config {
+	/* This one is safe to be used anywhere, but the code should still check
+	 * the BDB version. */
+	u8 raw[33];
+	/* This one should only be kept for legacy code. */
+	struct old_child_dev_config old;
+	/* This one should also be safe to use anywhere, even without version
+	 * checks. */
+	struct common_child_dev_config common;
+} __packed;
+
+struct bdb_general_definitions {
+	/* DDC GPIO */
+	u8 crt_ddc_gmbus_pin;
+
+	/* DPMS bits */
+	u8 dpms_acpi:1;
+	u8 skip_boot_crt_detect:1;
+	u8 dpms_aim:1;
+	u8 rsvd1:5; /* finish byte */
+
+	/* boot device bits */
+	u8 boot_display[2];
+	u8 child_dev_size;
+
+	/*
+	 * Device info:
+	 * If TV is present, it'll be at devices[0].
+	 * LVDS will be next, either devices[0] or [1], if present.
+	 * On some platforms the number of device is 6. But could be as few as
+	 * 4 if both TV and LVDS are missing.
+	 * And the device num is related with the size of general definition
+	 * block. It is obtained by using the following formula:
+	 * number = (block_size - sizeof(bdb_general_definitions))/
+	 *	     defs->child_dev_size;
+	 */
+	uint8_t devices[0];
+} __packed;
+
+/* Mask for DRRS / Panel Channel / SSC / BLT control bits extraction */
+#define MODE_MASK		0x3
+
+struct bdb_lvds_options {
+	u8 panel_type;
+	u8 rsvd1;
+	/* LVDS capabilities, stored in a dword */
+	u8 pfit_mode:2;
+	u8 pfit_text_mode_enhanced:1;
+	u8 pfit_gfx_mode_enhanced:1;
+	u8 pfit_ratio_auto:1;
+	u8 pixel_dither:1;
+	u8 lvds_edid:1;
+	u8 rsvd2:1;
+	u8 rsvd4;
+	/* LVDS Panel channel bits stored here */
+	u32 lvds_panel_channel_bits;
+	/* LVDS SSC (Spread Spectrum Clock) bits stored here. */
+	u16 ssc_bits;
+	u16 ssc_freq;
+	u16 ssc_ddt;
+	/* Panel color depth defined here */
+	u16 panel_color_depth;
+	/* LVDS panel type bits stored here */
+	u32 dps_panel_type_bits;
+	/* LVDS backlight control type bits stored here */
+	u32 blt_control_type_bits;
+} __packed;
+
+/* LFP pointer table contains entries to the struct below */
+struct bdb_lvds_lfp_data_ptr {
+	u16 fp_timing_offset; /* offsets are from start of bdb */
+	u8 fp_table_size;
+	u16 dvo_timing_offset;
+	u8 dvo_table_size;
+	u16 panel_pnp_id_offset;
+	u8 pnp_table_size;
+} __packed;
+
+struct bdb_lvds_lfp_data_ptrs {
+	u8 lvds_entries; /* followed by one or more lvds_data_ptr structs */
+	struct bdb_lvds_lfp_data_ptr ptr[16];
+} __packed;
+
+/* LFP data has 3 blocks per entry */
+struct lvds_fp_timing {
+	u16 x_res;
+	u16 y_res;
+	u32 lvds_reg;
+	u32 lvds_reg_val;
+	u32 pp_on_reg;
+	u32 pp_on_reg_val;
+	u32 pp_off_reg;
+	u32 pp_off_reg_val;
+	u32 pp_cycle_reg;
+	u32 pp_cycle_reg_val;
+	u32 pfit_reg;
+	u32 pfit_reg_val;
+	u16 terminator;
+} __packed;
+
+struct lvds_dvo_timing {
+	u16 clock;		/**< In 10khz */
+	u8 hactive_lo;
+	u8 hblank_lo;
+	u8 hblank_hi:4;
+	u8 hactive_hi:4;
+	u8 vactive_lo;
+	u8 vblank_lo;
+	u8 vblank_hi:4;
+	u8 vactive_hi:4;
+	u8 hsync_off_lo;
+	u8 hsync_pulse_width;
+	u8 vsync_pulse_width:4;
+	u8 vsync_off:4;
+	u8 rsvd0:6;
+	u8 hsync_off_hi:2;
+	u8 himage_lo;
+	u8 vimage_lo;
+	u8 vimage_hi:4;
+	u8 himage_hi:4;
+	u8 h_border;
+	u8 v_border;
+	u8 rsvd1:3;
+	u8 digital:2;
+	u8 vsync_positive:1;
+	u8 hsync_positive:1;
+	u8 rsvd2:1;
+} __packed;
+
+struct lvds_pnp_id {
+	u16 mfg_name;
+	u16 product_code;
+	u32 serial;
+	u8 mfg_week;
+	u8 mfg_year;
+} __packed;
+
+struct bdb_lvds_lfp_data_entry {
+	struct lvds_fp_timing fp_timing;
+	struct lvds_dvo_timing dvo_timing;
+	struct lvds_pnp_id pnp_id;
+} __packed;
+
+struct bdb_lvds_lfp_data {
+	struct bdb_lvds_lfp_data_entry data[16];
+} __packed;
+
+#define BDB_BACKLIGHT_TYPE_NONE	0
+#define BDB_BACKLIGHT_TYPE_PWM	2
+
+struct bdb_lfp_backlight_data_entry {
+	u8 type:2;
+	u8 active_low_pwm:1;
+	u8 obsolete1:5;
+	u16 pwm_freq_hz;
+	u8 min_brightness;
+	u8 obsolete2;
+	u8 obsolete3;
+} __packed;
+
+struct bdb_lfp_backlight_data {
+	u8 entry_size;
+	struct bdb_lfp_backlight_data_entry data[16];
+	u8 level[16];
+} __packed;
+
+struct aimdb_header {
+	char signature[16];
+	char oem_device[20];
+	u16 aimdb_version;
+	u16 aimdb_header_size;
+	u16 aimdb_size;
+} __packed;
+
+struct aimdb_block {
+	u8 aimdb_id;
+	u16 aimdb_size;
+} __packed;
+
+struct vch_panel_data {
+	u16 fp_timing_offset;
+	u8 fp_timing_size;
+	u16 dvo_timing_offset;
+	u8 dvo_timing_size;
+	u16 text_fitting_offset;
+	u8 text_fitting_size;
+	u16 graphics_fitting_offset;
+	u8 graphics_fitting_size;
+} __packed;
+
+struct vch_bdb_22 {
+	struct aimdb_block aimdb_block;
+	struct vch_panel_data panels[16];
+} __packed;
+
+struct bdb_sdvo_lvds_options {
+	u8 panel_backlight;
+	u8 h40_set_panel_type;
+	u8 panel_type;
+	u8 ssc_clk_freq;
+	u16 als_low_trip;
+	u16 als_high_trip;
+	u8 sclalarcoeff_tab_row_num;
+	u8 sclalarcoeff_tab_row_size;
+	u8 coefficient[8];
+	u8 panel_misc_bits_1;
+	u8 panel_misc_bits_2;
+	u8 panel_misc_bits_3;
+	u8 panel_misc_bits_4;
+} __packed;
+
+
+#define BDB_DRIVER_FEATURE_NO_LVDS		0
+#define BDB_DRIVER_FEATURE_INT_LVDS		1
+#define BDB_DRIVER_FEATURE_SDVO_LVDS		2
+#define BDB_DRIVER_FEATURE_EDP			3
+
+struct bdb_driver_features {
+	u8 boot_dev_algorithm:1;
+	u8 block_display_switch:1;
+	u8 allow_display_switch:1;
+	u8 hotplug_dvo:1;
+	u8 dual_view_zoom:1;
+	u8 int15h_hook:1;
+	u8 sprite_in_clone:1;
+	u8 primary_lfp_id:1;
+
+	u16 boot_mode_x;
+	u16 boot_mode_y;
+	u8 boot_mode_bpp;
+	u8 boot_mode_refresh;
+
+	u16 enable_lfp_primary:1;
+	u16 selective_mode_pruning:1;
+	u16 dual_frequency:1;
+	u16 render_clock_freq:1; /* 0: high freq; 1: low freq */
+	u16 nt_clone_support:1;
+	u16 power_scheme_ui:1; /* 0: CUI; 1: 3rd party */
+	u16 sprite_display_assign:1; /* 0: secondary; 1: primary */
+	u16 cui_aspect_scaling:1;
+	u16 preserve_aspect_ratio:1;
+	u16 sdvo_device_power_down:1;
+	u16 crt_hotplug:1;
+	u16 lvds_config:2;
+	u16 tv_hotplug:1;
+	u16 hdmi_config:2;
+
+	u8 static_display:1;
+	u8 reserved2:7;
+	u16 legacy_crt_max_x;
+	u16 legacy_crt_max_y;
+	u8 legacy_crt_max_refresh;
+
+	u8 hdmi_termination;
+	u8 custom_vbt_version;
+	/* Driver features data block */
+	u16 rmpm_enabled:1;
+	u16 s2ddt_enabled:1;
+	u16 dpst_enabled:1;
+	u16 bltclt_enabled:1;
+	u16 adb_enabled:1;
+	u16 drrs_enabled:1;
+	u16 grs_enabled:1;
+	u16 gpmt_enabled:1;
+	u16 tbt_enabled:1;
+	u16 psr_enabled:1;
+	u16 ips_enabled:1;
+	u16 reserved3:4;
+	u16 pc_feature_valid:1;
+} __packed;
+
+#define EDP_18BPP	0
+#define EDP_24BPP	1
+#define EDP_30BPP	2
+#define EDP_RATE_1_62	0
+#define EDP_RATE_2_7	1
+#define EDP_LANE_1	0
+#define EDP_LANE_2	1
+#define EDP_LANE_4	3
+#define EDP_PREEMPHASIS_NONE	0
+#define EDP_PREEMPHASIS_3_5dB	1
+#define EDP_PREEMPHASIS_6dB	2
+#define EDP_PREEMPHASIS_9_5dB	3
+#define EDP_VSWING_0_4V		0
+#define EDP_VSWING_0_6V		1
+#define EDP_VSWING_0_8V		2
+#define EDP_VSWING_1_2V		3
+
+
+struct edp_link_params {
+	u8 rate:4;
+	u8 lanes:4;
+	u8 preemphasis:4;
+	u8 vswing:4;
+} __packed;
+
+struct bdb_edp {
+	struct edp_power_seq power_seqs[16];
+	u32 color_depth;
+	struct edp_link_params link_params[16];
+	u32 sdrrs_msa_timing_delay;
+
+	/* ith bit indicates enabled/disabled for (i+1)th panel */
+	u16 edp_s3d_feature;
+	u16 edp_t3_optimization;
+	u64 edp_vswing_preemph;		/* v173 */
+} __packed;
+
+struct psr_table {
+	/* Feature bits */
+	u8 full_link:1;
+	u8 require_aux_to_wakeup:1;
+	u8 feature_bits_rsvd:6;
+
+	/* Wait times */
+	u8 idle_frames:4;
+	u8 lines_to_wait:3;
+	u8 wait_times_rsvd:1;
+
+	/* TP wake up time in multiple of 100 */
+	u16 tp1_wakeup_time;
+	u16 tp2_tp3_wakeup_time;
+} __packed;
+
+struct bdb_psr {
+	struct psr_table psr_table[16];
+} __packed;
+
+/*
+ * Driver<->VBIOS interaction occurs through scratch bits in
+ * GR18 & SWF*.
+ */
+
+/* GR18 bits are set on display switch and hotkey events */
+#define GR18_DRIVER_SWITCH_EN	(1<<7) /* 0: VBIOS control, 1: driver control */
+#define GR18_HOTKEY_MASK	0x78 /* See also SWF4 15:0 */
+#define   GR18_HK_NONE		(0x0<<3)
+#define   GR18_HK_LFP_STRETCH	(0x1<<3)
+#define   GR18_HK_TOGGLE_DISP	(0x2<<3)
+#define   GR18_HK_DISP_SWITCH	(0x4<<3) /* see SWF14 15:0 for what to enable */
+#define   GR18_HK_POPUP_DISABLED (0x6<<3)
+#define   GR18_HK_POPUP_ENABLED	(0x7<<3)
+#define   GR18_HK_PFIT		(0x8<<3)
+#define   GR18_HK_APM_CHANGE	(0xa<<3)
+#define   GR18_HK_MULTIPLE	(0xc<<3)
+#define GR18_USER_INT_EN	(1<<2)
+#define GR18_A0000_FLUSH_EN	(1<<1)
+#define GR18_SMM_EN		(1<<0)
+
+/* Set by driver, cleared by VBIOS */
+#define SWF00_YRES_SHIFT	16
+#define SWF00_XRES_SHIFT	0
+#define SWF00_RES_MASK		0xffff
+
+/* Set by VBIOS at boot time and driver at runtime */
+#define SWF01_TV2_FORMAT_SHIFT	8
+#define SWF01_TV1_FORMAT_SHIFT	0
+#define SWF01_TV_FORMAT_MASK	0xffff
+
+#define SWF10_VBIOS_BLC_I2C_EN	(1<<29)
+#define SWF10_GTT_OVERRIDE_EN	(1<<28)
+#define SWF10_LFP_DPMS_OVR	(1<<27) /* override DPMS on display switch */
+#define SWF10_ACTIVE_TOGGLE_LIST_MASK (7<<24)
+#define   SWF10_OLD_TOGGLE	0x0
+#define   SWF10_TOGGLE_LIST_1	0x1
+#define   SWF10_TOGGLE_LIST_2	0x2
+#define   SWF10_TOGGLE_LIST_3	0x3
+#define   SWF10_TOGGLE_LIST_4	0x4
+#define SWF10_PANNING_EN	(1<<23)
+#define SWF10_DRIVER_LOADED	(1<<22)
+#define SWF10_EXTENDED_DESKTOP	(1<<21)
+#define SWF10_EXCLUSIVE_MODE	(1<<20)
+#define SWF10_OVERLAY_EN	(1<<19)
+#define SWF10_PLANEB_HOLDOFF	(1<<18)
+#define SWF10_PLANEA_HOLDOFF	(1<<17)
+#define SWF10_VGA_HOLDOFF	(1<<16)
+#define SWF10_ACTIVE_DISP_MASK	0xffff
+#define   SWF10_PIPEB_LFP2	(1<<15)
+#define   SWF10_PIPEB_EFP2	(1<<14)
+#define   SWF10_PIPEB_TV2	(1<<13)
+#define   SWF10_PIPEB_CRT2	(1<<12)
+#define   SWF10_PIPEB_LFP	(1<<11)
+#define   SWF10_PIPEB_EFP	(1<<10)
+#define   SWF10_PIPEB_TV	(1<<9)
+#define   SWF10_PIPEB_CRT	(1<<8)
+#define   SWF10_PIPEA_LFP2	(1<<7)
+#define   SWF10_PIPEA_EFP2	(1<<6)
+#define   SWF10_PIPEA_TV2	(1<<5)
+#define   SWF10_PIPEA_CRT2	(1<<4)
+#define   SWF10_PIPEA_LFP	(1<<3)
+#define   SWF10_PIPEA_EFP	(1<<2)
+#define   SWF10_PIPEA_TV	(1<<1)
+#define   SWF10_PIPEA_CRT	(1<<0)
+
+#define SWF11_MEMORY_SIZE_SHIFT	16
+#define SWF11_SV_TEST_EN	(1<<15)
+#define SWF11_IS_AGP		(1<<14)
+#define SWF11_DISPLAY_HOLDOFF	(1<<13)
+#define SWF11_DPMS_REDUCED	(1<<12)
+#define SWF11_IS_VBE_MODE	(1<<11)
+#define SWF11_PIPEB_ACCESS	(1<<10) /* 0 here means pipe a */
+#define SWF11_DPMS_MASK		0x07
+#define   SWF11_DPMS_OFF	(1<<2)
+#define   SWF11_DPMS_SUSPEND	(1<<1)
+#define   SWF11_DPMS_STANDBY	(1<<0)
+#define   SWF11_DPMS_ON		0
+
+#define SWF14_GFX_PFIT_EN	(1<<31)
+#define SWF14_TEXT_PFIT_EN	(1<<30)
+#define SWF14_LID_STATUS_CLOSED	(1<<29) /* 0 here means open */
+#define SWF14_POPUP_EN		(1<<28)
+#define SWF14_DISPLAY_HOLDOFF	(1<<27)
+#define SWF14_DISP_DETECT_EN	(1<<26)
+#define SWF14_DOCKING_STATUS_DOCKED (1<<25) /* 0 here means undocked */
+#define SWF14_DRIVER_STATUS	(1<<24)
+#define SWF14_OS_TYPE_WIN9X	(1<<23)
+#define SWF14_OS_TYPE_WINNT	(1<<22)
+/* 21:19 rsvd */
+#define SWF14_PM_TYPE_MASK	0x00070000
+#define   SWF14_PM_ACPI_VIDEO	(0x4 << 16)
+#define   SWF14_PM_ACPI		(0x3 << 16)
+#define   SWF14_PM_APM_12	(0x2 << 16)
+#define   SWF14_PM_APM_11	(0x1 << 16)
+#define SWF14_HK_REQUEST_MASK	0x0000ffff /* see GR18 6:3 for event type */
+          /* if GR18 indicates a display switch */
+#define   SWF14_DS_PIPEB_LFP2_EN (1<<15)
+#define   SWF14_DS_PIPEB_EFP2_EN (1<<14)
+#define   SWF14_DS_PIPEB_TV2_EN  (1<<13)
+#define   SWF14_DS_PIPEB_CRT2_EN (1<<12)
+#define   SWF14_DS_PIPEB_LFP_EN  (1<<11)
+#define   SWF14_DS_PIPEB_EFP_EN  (1<<10)
+#define   SWF14_DS_PIPEB_TV_EN   (1<<9)
+#define   SWF14_DS_PIPEB_CRT_EN  (1<<8)
+#define   SWF14_DS_PIPEA_LFP2_EN (1<<7)
+#define   SWF14_DS_PIPEA_EFP2_EN (1<<6)
+#define   SWF14_DS_PIPEA_TV2_EN  (1<<5)
+#define   SWF14_DS_PIPEA_CRT2_EN (1<<4)
+#define   SWF14_DS_PIPEA_LFP_EN  (1<<3)
+#define   SWF14_DS_PIPEA_EFP_EN  (1<<2)
+#define   SWF14_DS_PIPEA_TV_EN   (1<<1)
+#define   SWF14_DS_PIPEA_CRT_EN  (1<<0)
+          /* if GR18 indicates a panel fitting request */
+#define   SWF14_PFIT_EN		(1<<0) /* 0 means disable */
+          /* if GR18 indicates an APM change request */
+#define   SWF14_APM_HIBERNATE	0x4
+#define   SWF14_APM_SUSPEND	0x3
+#define   SWF14_APM_STANDBY	0x1
+#define   SWF14_APM_RESTORE	0x0
+
+/* Add the device class for LFP, TV, HDMI */
+#define	 DEVICE_TYPE_INT_LFP	0x1022
+#define	 DEVICE_TYPE_INT_TV	0x1009
+#define	 DEVICE_TYPE_HDMI	0x60D2
+#define	 DEVICE_TYPE_DP		0x68C6
+#define	 DEVICE_TYPE_DP_DUAL_MODE	0x60D6
+#define	 DEVICE_TYPE_eDP	0x78C6
+
+#define  DEVICE_TYPE_CLASS_EXTENSION	(1 << 15)
+#define  DEVICE_TYPE_POWER_MANAGEMENT	(1 << 14)
+#define  DEVICE_TYPE_HOTPLUG_SIGNALING	(1 << 13)
+#define  DEVICE_TYPE_INTERNAL_CONNECTOR	(1 << 12)
+#define  DEVICE_TYPE_NOT_HDMI_OUTPUT	(1 << 11)
+#define  DEVICE_TYPE_MIPI_OUTPUT	(1 << 10)
+#define  DEVICE_TYPE_COMPOSITE_OUTPUT	(1 << 9)
+#define  DEVICE_TYPE_DUAL_CHANNEL	(1 << 8)
+#define  DEVICE_TYPE_HIGH_SPEED_LINK	(1 << 6)
+#define  DEVICE_TYPE_LVDS_SINGALING	(1 << 5)
+#define  DEVICE_TYPE_TMDS_DVI_SIGNALING	(1 << 4)
+#define  DEVICE_TYPE_VIDEO_SIGNALING	(1 << 3)
+#define  DEVICE_TYPE_DISPLAYPORT_OUTPUT	(1 << 2)
+#define  DEVICE_TYPE_DIGITAL_OUTPUT	(1 << 1)
+#define  DEVICE_TYPE_ANALOG_OUTPUT	(1 << 0)
+
+/*
+ * Bits we care about when checking for DEVICE_TYPE_eDP
+ * Depending on the system, the other bits may or may not
+ * be set for eDP outputs.
+ */
+#define DEVICE_TYPE_eDP_BITS \
+	(DEVICE_TYPE_INTERNAL_CONNECTOR | \
+	 DEVICE_TYPE_MIPI_OUTPUT | \
+	 DEVICE_TYPE_COMPOSITE_OUTPUT | \
+	 DEVICE_TYPE_DUAL_CHANNEL | \
+	 DEVICE_TYPE_LVDS_SINGALING | \
+	 DEVICE_TYPE_TMDS_DVI_SIGNALING | \
+	 DEVICE_TYPE_VIDEO_SIGNALING | \
+	 DEVICE_TYPE_DISPLAYPORT_OUTPUT | \
+	 DEVICE_TYPE_ANALOG_OUTPUT)
+
+#define DEVICE_TYPE_DP_DUAL_MODE_BITS \
+	(DEVICE_TYPE_INTERNAL_CONNECTOR | \
+	 DEVICE_TYPE_MIPI_OUTPUT | \
+	 DEVICE_TYPE_COMPOSITE_OUTPUT | \
+	 DEVICE_TYPE_LVDS_SINGALING | \
+	 DEVICE_TYPE_TMDS_DVI_SIGNALING | \
+	 DEVICE_TYPE_VIDEO_SIGNALING | \
+	 DEVICE_TYPE_DISPLAYPORT_OUTPUT | \
+	 DEVICE_TYPE_DIGITAL_OUTPUT | \
+	 DEVICE_TYPE_ANALOG_OUTPUT)
+
+/* define the DVO port for HDMI output type */
+#define		DVO_B		1
+#define		DVO_C		2
+#define		DVO_D		3
+
+/* Possible values for the "DVO Port" field for versions >= 155: */
+#define DVO_PORT_HDMIA	0
+#define DVO_PORT_HDMIB	1
+#define DVO_PORT_HDMIC	2
+#define DVO_PORT_HDMID	3
+#define DVO_PORT_LVDS	4
+#define DVO_PORT_TV	5
+#define DVO_PORT_CRT	6
+#define DVO_PORT_DPB	7
+#define DVO_PORT_DPC	8
+#define DVO_PORT_DPD	9
+#define DVO_PORT_DPA	10
+#define DVO_PORT_DPE	11
+#define DVO_PORT_HDMIE	12
+#define DVO_PORT_MIPIA	21
+#define DVO_PORT_MIPIB	22
+#define DVO_PORT_MIPIC	23
+#define DVO_PORT_MIPID	24
+
+/* Block 52 contains MIPI configuration block
+ * 6 * bdb_mipi_config, followed by 6 pps data block
+ * block below
+ */
+#define MAX_MIPI_CONFIGURATIONS	6
+
+struct bdb_mipi_config {
+	struct mipi_config config[MAX_MIPI_CONFIGURATIONS];
+	struct mipi_pps_data pps[MAX_MIPI_CONFIGURATIONS];
+} __packed;
+
+/* Block 53 contains MIPI sequences as needed by the panel
+ * for enabling it. This block can be variable in size and
+ * can be maximum of 6 blocks
+ */
+struct bdb_mipi_sequence {
+	u8 version;
+	u8 data[0];
+} __packed;
+
+enum mipi_gpio_pin_index {
+	MIPI_GPIO_UNDEFINED = 0,
+	MIPI_GPIO_PANEL_ENABLE,
+	MIPI_GPIO_BL_ENABLE,
+	MIPI_GPIO_PWM_ENABLE,
+	MIPI_GPIO_RESET_N,
+	MIPI_GPIO_PWR_DOWN_R,
+	MIPI_GPIO_STDBY_RST_N,
+	MIPI_GPIO_MAX
+};
+
+#endif /* _INTEL_VBT_DEFS_H_ */
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/include/Kbuild
@@ -0,0 +1,2 @@
+
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/include/README
@@ -0,0 +1,4 @@
+Only use this directory for things which need to share their headers with
+other parts of the kernel or other modules in ubuntu/
+
+Otherwise, keep them local to the module directory.
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox-update
@@ -0,0 +1,49 @@
+#!/bin/bash
+#
+# vbox-update <dkms top level>
+
+#
+# NOTE: update vbox/BOM if you get the source from anywhere other than
+# the archive.
+#
+# To update:
+#  TMP=$HOME/tmp
+#  wget -O $TMP/virtualbox-guest-dkms.deb http://ports.ubuntu.com/pool/multiverse/v/virtualbox/virtualbox-guest-dkms_4.3.22-dfsg-1_all.deb
+#  dpkg-deb -R $TMP/virtualbox-guest-dkms.deb $TMP/virtualbox-guest-update
+#  vbox-update $TMP/virtualbox-guest-update
+#
+# To test build:
+#  fakeroot debian/rules prepare-generic
+#  make O=debian/build/build-generic/ ubuntu/vbox/vboxguest/vboxguest.ko ubuntu/vbox/vboxvideo/vboxvideo.ko ubuntu/vbox/vboxsf/vboxsf.ko
+#
+
+if [ "$#" -ne 1 ]; then
+	echo "Usage: $0 <unpacked vbox dkms guest directory>" 1>&2
+	exit 1
+fi
+vbox="$1"
+
+# Update vbox ...
+git rm -rf vbox
+mkdir vbox
+cp -rp "$vbox/usr/src/"*/* vbox
+
+# Work out what version this represents.
+ver=`awk '($1 == "Version:") { print $2 }' <"$vbox/DEBIAN/control"`
+
+# Fix up the KBUILD_EXTMOD as we are not building externally.
+for make in vbox/*/Makefile
+do
+	sed -i -e '1iKBUILD_EXTMOD=${srctree}/ubuntu/vbox' $make
+done
+
+# Record the version number and nominal source.
+{
+	echo "Source: http://ports.ubuntu.com/pool/multiverse/v/virtualbox/virtualbox-guest-dkms_${ver}_all.deb"
+	echo "Version: $ver"
+} >vbox/BOM
+
+git add vbox
+{
+	echo "UBUNTU: ubuntu: vbox -- update to $ver"
+} | git commit -s -F -
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/BOM
@@ -0,0 +1,2 @@
+Source: http://ports.ubuntu.com/pool/multiverse/v/virtualbox/virtualbox-guest-dkms_5.0.18-dfsg-2build1_all.deb
+Version: 5.0.18-dfsg-2build1
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/Makefile
@@ -0,0 +1,3 @@
+.NOTPARALLEL:
+
+obj-m = vboxguest/ vboxsf/ vboxvideo/
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/dkms.conf
@@ -0,0 +1,13 @@
+PACKAGE_NAME="virtualbox-guest"
+PACKAGE_VERSION="5.0.18"
+CLEAN="rm -f *.*o"
+BUILT_MODULE_NAME[0]="vboxguest"
+BUILT_MODULE_LOCATION[0]="vboxguest"
+DEST_MODULE_LOCATION[0]="/updates"
+BUILT_MODULE_NAME[1]="vboxsf"
+BUILT_MODULE_LOCATION[1]="vboxsf"
+DEST_MODULE_LOCATION[1]="/updates"
+BUILT_MODULE_NAME[2]="vboxvideo"
+BUILT_MODULE_LOCATION[2]="vboxvideo"
+DEST_MODULE_LOCATION[2]="/updates"
+AUTOINSTALL="yes"
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/include/VBox/HGSMI/HGSMI.h
@@ -0,0 +1,264 @@
+/** @file
+ *
+ * VBox Host Guest Shared Memory Interface (HGSMI).
+ * Host/Guest shared part.
+ */
+
+/*
+ * Copyright (C) 2006-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+
+#ifndef ___VBox_HGSMI_HGSMI_h
+#define ___VBox_HGSMI_HGSMI_h
+
+#include <iprt/assert.h>
+#include <iprt/types.h>
+
+#include <VBox/HGSMI/HGSMIDefs.h>
+#include <VBox/HGSMI/HGSMIChannels.h>
+#include <VBox/HGSMI/HGSMIMemAlloc.h>
+
+/*
+ * Basic mechanism for the HGSMI is to prepare and pass data buffer to the host and the guest.
+ * Data inside these buffers are opaque for the HGSMI and are interpreted by higher levels.
+ *
+ * Every shared memory buffer passed between the guest/host has the following structure:
+ *
+ * HGSMIBUFFERHEADER header;
+ * uint8_t data[header.u32BufferSize];
+ * HGSMIBUFFERTAIL tail;
+ *
+ * Note: Offset of the 'header' in the memory is used for virtual hardware IO.
+ *
+ * Buffers are verifyed using the offset and the content of the header and the tail,
+ * which are constant during a call.
+ *
+ * Invalid buffers are ignored.
+ *
+ * Actual 'data' is not verifyed, as it is expected that the data can be changed by the
+ * called function.
+ *
+ * Since only the offset of the buffer is passed in a IO operation, the header and tail
+ * must contain:
+ *     * size of data in this buffer;
+ *     * checksum for buffer verification.
+ *
+ * For segmented transfers:
+ *     * the sequence identifier;
+ *     * offset of the current segment in the sequence;
+ *     * total bytes in the transfer.
+ *
+ * Additionally contains:
+ *     * the channel ID;
+ *     * the channel information.
+ */
+
+typedef struct HGSMIHEAP
+{
+    HGSMIAREA area; /* Description. */
+    HGSMIMADATA ma; /* Memory allocator */
+} HGSMIHEAP;
+
+/* The size of the array of channels. Array indexes are uint8_t. Note: the value must not be changed. */
+#define HGSMI_NUMBER_OF_CHANNELS 0x100
+
+/* Channel handler called when the guest submits a buffer. */
+typedef DECLCALLBACK(int) FNHGSMICHANNELHANDLER(void *pvHandler, uint16_t u16ChannelInfo, void *pvBuffer, HGSMISIZE cbBuffer);
+typedef FNHGSMICHANNELHANDLER *PFNHGSMICHANNELHANDLER;
+
+/* Information about a handler: pfn + context. */
+typedef struct _HGSMICHANNELHANDLER
+{
+    PFNHGSMICHANNELHANDLER pfnHandler;
+    void *pvHandler;
+} HGSMICHANNELHANDLER;
+
+/* Channel description. */
+typedef struct _HGSMICHANNEL
+{
+    HGSMICHANNELHANDLER handler;       /* The channel handler. */
+    const char *pszName;               /* NULL for hardcoded channels or RTStrDup'ed name. */
+    uint8_t u8Channel;                 /* The channel id, equal to the channel index in the array. */
+    uint8_t u8Flags;                   /* HGSMI_CH_F_* */
+} HGSMICHANNEL;
+
+typedef struct _HGSMICHANNELINFO
+{
+    HGSMICHANNEL Channels[HGSMI_NUMBER_OF_CHANNELS]; /* Channel handlers indexed by the channel id.
+                                                      * The array is accessed under the instance lock.
+                                                      */
+}  HGSMICHANNELINFO;
+
+
+RT_C_DECLS_BEGIN
+
+DECLINLINE(HGSMIBUFFERHEADER *) HGSMIBufferHeaderFromPtr(void *pvBuffer)
+{
+    return (HGSMIBUFFERHEADER *)pvBuffer;
+}
+
+DECLINLINE(uint8_t *) HGSMIBufferDataFromPtr(void *pvBuffer)
+{
+    return (uint8_t *)pvBuffer + sizeof(HGSMIBUFFERHEADER);
+}
+
+DECLINLINE(HGSMIBUFFERTAIL *) HGSMIBufferTailFromPtr(void *pvBuffer,
+                                                     uint32_t u32DataSize)
+{
+    return (HGSMIBUFFERTAIL *)(HGSMIBufferDataFromPtr(pvBuffer) + u32DataSize);
+}
+
+DECLINLINE(HGSMISIZE) HGSMIBufferMinimumSize(void)
+{
+    return sizeof(HGSMIBUFFERHEADER) + sizeof(HGSMIBUFFERTAIL);
+}
+
+DECLINLINE(HGSMIBUFFERHEADER *) HGSMIBufferHeaderFromData(const void *pvData)
+{
+    return (HGSMIBUFFERHEADER *)((uint8_t *)pvData - sizeof(HGSMIBUFFERHEADER));
+}
+
+DECLINLINE(HGSMISIZE) HGSMIBufferRequiredSize(uint32_t u32DataSize)
+{
+    return HGSMIBufferMinimumSize() + u32DataSize;
+}
+
+DECLINLINE(HGSMIOFFSET) HGSMIPointerToOffset(const HGSMIAREA *pArea,
+                                             const void *pv)
+{
+    return pArea->offBase + (HGSMIOFFSET)((uint8_t *)pv - pArea->pu8Base);
+}
+
+DECLINLINE(void *) HGSMIOffsetToPointer(const HGSMIAREA *pArea,
+                                        HGSMIOFFSET offBuffer)
+{
+    return pArea->pu8Base + (offBuffer - pArea->offBase);
+}
+
+DECLINLINE(uint8_t *) HGSMIBufferDataFromOffset(const HGSMIAREA *pArea,
+                                                HGSMIOFFSET offBuffer)
+{
+    void *pvBuffer = HGSMIOffsetToPointer(pArea, offBuffer);
+    return HGSMIBufferDataFromPtr(pvBuffer);
+}
+
+DECLINLINE(HGSMIOFFSET) HGSMIBufferOffsetFromData(const HGSMIAREA *pArea,
+                                                  void *pvData)
+{
+    HGSMIBUFFERHEADER *pHeader = HGSMIBufferHeaderFromData(pvData);
+    return HGSMIPointerToOffset(pArea, pHeader);
+}
+
+DECLINLINE(uint8_t *) HGSMIBufferDataAndChInfoFromOffset(const HGSMIAREA *pArea,
+                                                         HGSMIOFFSET offBuffer,
+                                                         uint16_t *pu16ChannelInfo)
+{
+    HGSMIBUFFERHEADER *pHeader = (HGSMIBUFFERHEADER *)HGSMIOffsetToPointer(pArea, offBuffer);
+    *pu16ChannelInfo = pHeader->u16ChannelInfo;
+    return HGSMIBufferDataFromPtr(pHeader);
+}
+
+uint32_t HGSMIChecksum(HGSMIOFFSET offBuffer,
+                       const HGSMIBUFFERHEADER *pHeader,
+                       const HGSMIBUFFERTAIL *pTail);
+
+int HGSMIAreaInitialize(HGSMIAREA *pArea,
+                        void *pvBase,
+                        HGSMISIZE cbArea,
+                        HGSMIOFFSET offBase);
+
+void HGSMIAreaClear(HGSMIAREA *pArea);
+
+DECLINLINE(bool) HGSMIAreaContainsOffset(const HGSMIAREA *pArea, HGSMIOFFSET off)
+{
+    return off >= pArea->offBase && off - pArea->offBase < pArea->cbArea;
+}
+
+DECLINLINE(bool) HGSMIAreaContainsPointer(const HGSMIAREA *pArea, const void *pv)
+{
+    return (uintptr_t)pv >= (uintptr_t)pArea->pu8Base && (uintptr_t)pv - (uintptr_t)pArea->pu8Base < pArea->cbArea;
+}
+
+HGSMIOFFSET HGSMIBufferInitializeSingle(const HGSMIAREA *pArea,
+                                        HGSMIBUFFERHEADER *pHeader,
+                                        HGSMISIZE cbBuffer,
+                                        uint8_t u8Channel,
+                                        uint16_t u16ChannelInfo);
+
+int HGSMIHeapSetup(HGSMIHEAP *pHeap,
+                   void *pvBase,
+                   HGSMISIZE cbArea,
+                   HGSMIOFFSET offBase,
+                   const HGSMIENV *pEnv);
+
+void HGSMIHeapDestroy(HGSMIHEAP *pHeap);
+
+void *HGSMIHeapBufferAlloc(HGSMIHEAP *pHeap,
+                           HGSMISIZE cbBuffer);
+
+void HGSMIHeapBufferFree(HGSMIHEAP *pHeap,
+                         void *pvBuf);
+
+void *HGSMIHeapAlloc(HGSMIHEAP *pHeap,
+                     HGSMISIZE cbData,
+                     uint8_t u8Channel,
+                     uint16_t u16ChannelInfo);
+
+void HGSMIHeapFree(HGSMIHEAP *pHeap,
+                   void *pvData);
+
+DECLINLINE(const HGSMIAREA *) HGSMIHeapArea(HGSMIHEAP *pHeap)
+{
+    return &pHeap->area;
+}
+
+DECLINLINE(HGSMIOFFSET) HGSMIHeapOffset(HGSMIHEAP *pHeap)
+{
+    return HGSMIHeapArea(pHeap)->offBase;
+}
+
+DECLINLINE(HGSMISIZE) HGSMIHeapSize(HGSMIHEAP *pHeap)
+{
+    return HGSMIHeapArea(pHeap)->cbArea;
+}
+
+DECLINLINE(HGSMIOFFSET) HGSMIHeapBufferOffset(HGSMIHEAP *pHeap,
+                                              void *pvData)
+{
+    return HGSMIBufferOffsetFromData(HGSMIHeapArea(pHeap), pvData);
+}
+
+HGSMICHANNEL *HGSMIChannelFindById(HGSMICHANNELINFO *pChannelInfo,
+                                   uint8_t u8Channel);
+
+int HGSMIChannelRegister(HGSMICHANNELINFO *pChannelInfo,
+                         uint8_t u8Channel,
+                         const char *pszName,
+                         PFNHGSMICHANNELHANDLER pfnChannelHandler,
+                         void *pvChannelHandler);
+
+int HGSMIBufferProcess(const HGSMIAREA *pArea,
+                       HGSMICHANNELINFO *pChannelInfo,
+                       HGSMIOFFSET offBuffer);
+RT_C_DECLS_END
+
+#endif /* !___VBox_HGSMI_HGSMI_h */
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/include/VBox/HGSMI/HGSMIChSetup.h
@@ -0,0 +1,77 @@
+/** @file
+ * VBox Host Guest Shared Memory Interface (HGSMI), sHost/Guest shared part.
+ */
+
+/*
+ * Copyright (C) 2006-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+#ifndef ___VBox_HGSMI_HGSMIChSetup_h
+#define ___VBox_HGSMI_HGSMIChSetup_h
+
+#include <VBox/HGSMI/HGSMI.h>
+
+/* HGSMI setup and configuration channel commands and data structures. */
+#define HGSMI_CC_HOST_FLAGS_LOCATION 0 /* Tell the host the location of HGSMIHOSTFLAGS structure,
+                                        * where the host can write information about pending
+                                        * buffers, etc, and which can be quickly polled by
+                                        * the guest without a need to port IO.
+                                        */
+
+typedef struct _HGSMIBUFFERLOCATION
+{
+    HGSMIOFFSET offLocation;
+    HGSMISIZE   cbLocation;
+} HGSMIBUFFERLOCATION;
+AssertCompileSize(HGSMIBUFFERLOCATION, 8);
+
+/* HGSMI setup and configuration data structures. */
+/* host->guest commands pending, should be accessed under FIFO lock only */
+#define HGSMIHOSTFLAGS_COMMANDS_PENDING    0x1
+/* IRQ is fired, should be accessed under VGAState::lock only  */
+#define HGSMIHOSTFLAGS_IRQ                 0x2
+#ifdef VBOX_WITH_WDDM
+/* one or more guest commands is completed, should be accessed under FIFO lock only */
+# define HGSMIHOSTFLAGS_GCOMMAND_COMPLETED 0x4
+/* watchdog timer interrupt flag (used for debugging), should be accessed under VGAState::lock only */
+# define HGSMIHOSTFLAGS_WATCHDOG           0x8
+#endif
+/* vsync interrupt flag, should be accessed under VGAState::lock only */
+#define HGSMIHOSTFLAGS_VSYNC               0x10
+/** monitor hotplug flag, should be accessed under VGAState::lock only */
+#define HGSMIHOSTFLAGS_HOTPLUG             0x20
+/** Cursor capability state change flag, should be accessed under
+ * VGAState::lock only.  @see VBVACONF32. */
+#define HGSMIHOSTFLAGS_CURSOR_CAPABILITIES 0x40
+
+typedef struct _HGSMIHOSTFLAGS
+{
+    /* host flags can be accessed and modified in multiple threads concurrently,
+     * e.g. CrOpenGL HGCM and GUI threads when to completing HGSMI 3D and Video Accel respectively,
+     * EMT thread when dealing with HGSMI command processing, etc.
+     * Besides settings/cleaning flags atomically, some each flag has its own special sync restrictions,
+     * see commants for flags definitions above */
+    volatile uint32_t u32HostFlags;
+    uint32_t au32Reserved[3];
+} HGSMIHOSTFLAGS;
+AssertCompileSize(HGSMIHOSTFLAGS, 16);
+
+#endif
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/include/VBox/HGSMI/HGSMIChannels.h
@@ -0,0 +1,64 @@
+/** @file
+ *
+ * VBox Host Guest Shared Memory Interface (HGSMI).
+ * Host/Guest shared part.
+ * Channel identifiers.
+ */
+
+/*
+ * Copyright (C) 2006-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+
+#ifndef __HGSMIChannels_h__
+#define __HGSMIChannels_h__
+
+
+/* Each channel has an 8 bit identifier. There are a number of predefined
+ * (hardcoded) channels.
+ *
+ * HGSMI_CH_HGSMI channel can be used to map a string channel identifier
+ * to a free 16 bit numerical value. values are allocated in range
+ * [HGSMI_CH_STRING_FIRST;HGSMI_CH_STRING_LAST].
+ *
+ */
+
+
+/* Predefined channel identifiers. Used internally by VBOX to simplify the channel setup. */
+#define HGSMI_CH_RESERVED     (0x00) /* A reserved channel value. */
+
+#define HGSMI_CH_HGSMI        (0x01) /* HGCMI: setup and configuration channel. */
+
+#define HGSMI_CH_VBVA         (0x02) /* Graphics: VBVA. */
+#define HGSMI_CH_SEAMLESS     (0x03) /* Graphics: Seamless with a single guest region. */
+#define HGSMI_CH_SEAMLESS2    (0x04) /* Graphics: Seamless with separate host windows. */
+#define HGSMI_CH_OPENGL       (0x05) /* Graphics: OpenGL HW acceleration. */
+
+
+/* Dynamically allocated channel identifiers. */
+#define HGSMI_CH_STRING_FIRST (0x20) /* The first channel index to be used for string mappings (inclusive). */
+#define HGSMI_CH_STRING_LAST  (0xff) /* The last channel index for string mappings (inclusive). */
+
+
+/* Check whether the channel identifier is allocated for a dynamic channel. */
+#define HGSMI_IS_DYNAMIC_CHANNEL(_channel) (((uint8_t)(_channel) & 0xE0) != 0)
+
+
+#endif /* !__HGSMIChannels_h__*/
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/include/VBox/HGSMI/HGSMIDefs.h
@@ -0,0 +1,123 @@
+/** @file
+ *
+ * VBox Host Guest Shared Memory Interface (HGSMI).
+ * Host/Guest shared part: types and defines.
+ */
+
+/*
+ * Copyright (C) 2006-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+
+#ifndef ___VBox_HGSMI_HGSMIDefs_h
+#define ___VBox_HGSMI_HGSMIDefs_h
+
+#include <iprt/assert.h>
+#include <iprt/types.h>
+
+/* HGSMI uses 32 bit offsets and sizes. */
+typedef uint32_t HGSMISIZE;
+typedef uint32_t HGSMIOFFSET;
+
+#define HGSMIOFFSET_VOID ((HGSMIOFFSET)~0)
+
+/* Describes a shared memory area buffer.
+ * Used for calculations with offsets and for buffers verification.
+ */
+typedef struct HGSMIAREA
+{
+    uint8_t     *pu8Base; /* The starting address of the area. Corresponds to offset 'offBase'. */
+    HGSMIOFFSET  offBase; /* The starting offset of the area. */
+    HGSMIOFFSET  offLast; /* The last valid offset:
+                           * offBase + cbArea - 1 - (sizeof(header) + sizeof(tail)).
+                           */
+    HGSMISIZE    cbArea;  /* Size of the area. */
+} HGSMIAREA;
+
+
+/* The buffer description flags. */
+#define HGSMI_BUFFER_HEADER_F_SEQ_MASK     0x03 /* Buffer sequence type mask. */
+#define HGSMI_BUFFER_HEADER_F_SEQ_SINGLE   0x00 /* Single buffer, not a part of a sequence. */
+#define HGSMI_BUFFER_HEADER_F_SEQ_START    0x01 /* The first buffer in a sequence. */
+#define HGSMI_BUFFER_HEADER_F_SEQ_CONTINUE 0x02 /* A middle buffer in a sequence. */
+#define HGSMI_BUFFER_HEADER_F_SEQ_END      0x03 /* The last buffer in a sequence. */
+
+
+#pragma pack(1)
+/* 16 bytes buffer header. */
+typedef struct HGSMIBUFFERHEADER
+{
+    uint32_t    u32DataSize;            /* Size of data that follows the header. */
+
+    uint8_t     u8Flags;                /* The buffer description: HGSMI_BUFFER_HEADER_F_* */
+
+    uint8_t     u8Channel;              /* The channel the data must be routed to. */
+    uint16_t    u16ChannelInfo;         /* Opaque to the HGSMI, used by the channel. */
+
+    union {
+        uint8_t au8Union[8];            /* Opaque placeholder to make the union 8 bytes. */
+
+        struct
+        {                               /* HGSMI_BUFFER_HEADER_F_SEQ_SINGLE */
+            uint32_t u32Reserved1;      /* A reserved field, initialize to 0. */
+            uint32_t u32Reserved2;      /* A reserved field, initialize to 0. */
+        } Buffer;
+
+        struct
+        {                               /* HGSMI_BUFFER_HEADER_F_SEQ_START */
+            uint32_t u32SequenceNumber; /* The sequence number, the same for all buffers in the sequence. */
+            uint32_t u32SequenceSize;   /* The total size of the sequence. */
+        } SequenceStart;
+
+        struct
+        {                               /* HGSMI_BUFFER_HEADER_F_SEQ_CONTINUE and HGSMI_BUFFER_HEADER_F_SEQ_END */
+            uint32_t u32SequenceNumber; /* The sequence number, the same for all buffers in the sequence. */
+            uint32_t u32SequenceOffset; /* Data offset in the entire sequence. */
+        } SequenceContinue;
+    } u;
+} HGSMIBUFFERHEADER;
+
+/* 8 bytes buffer tail. */
+typedef struct HGSMIBUFFERTAIL
+{
+    uint32_t    u32Reserved;        /* Reserved, must be initialized to 0. */
+    uint32_t    u32Checksum;        /* Verifyer for the buffer header and offset and for first 4 bytes of the tail. */
+} HGSMIBUFFERTAIL;
+#pragma pack()
+
+AssertCompileSize(HGSMIBUFFERHEADER, 16);
+AssertCompileSize(HGSMIBUFFERTAIL, 8);
+
+/* The size of the array of channels. Array indexes are uint8_t. Note: the value must not be changed. */
+#define HGSMI_NUMBER_OF_CHANNELS 0x100
+
+typedef struct HGSMIENV
+{
+    /* Environment context pointer. */
+    void *pvEnv;
+
+    /* Allocate system memory. */
+    DECLCALLBACKMEMBER(void *, pfnAlloc)(void *pvEnv, HGSMISIZE cb);
+
+    /* Free system memory. */
+    DECLCALLBACKMEMBER(void, pfnFree)(void *pvEnv, void *pv);
+} HGSMIENV;
+
+#endif /* !___VBox_HGSMI_HGSMIDefs_h */
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/include/VBox/HGSMI/HGSMIMemAlloc.h
@@ -0,0 +1,100 @@
+/** @file
+ *
+ * VBox Host Guest Shared Memory Interface (HGSMI).
+ * Memory allocator.
+ */
+
+/*
+ * Copyright (C) 2014-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+
+#ifndef ___VBox_HGSMI_HGSMIMemAlloc_h
+#define ___VBox_HGSMI_HGSMIMemAlloc_h
+
+#include <VBox/HGSMI/HGSMIDefs.h>
+#include <iprt/list.h>
+
+
+/* Descriptor. */
+#define HGSMI_MA_DESC_OFFSET_MASK UINT32_C(0xFFFFFFE0)
+#define HGSMI_MA_DESC_FREE_MASK   UINT32_C(0x00000010)
+#define HGSMI_MA_DESC_ORDER_MASK  UINT32_C(0x0000000F)
+
+#define HGSMI_MA_DESC_OFFSET(d)  ((d) & HGSMI_MA_DESC_OFFSET_MASK)
+#define HGSMI_MA_DESC_IS_FREE(d) (((d) & HGSMI_MA_DESC_FREE_MASK) != 0)
+#define HGSMI_MA_DESC_ORDER(d)   ((d) & HGSMI_MA_DESC_ORDER_MASK)
+
+#define HGSMI_MA_DESC_ORDER_BASE UINT32_C(5)
+
+#define HGSMI_MA_BLOCK_SIZE_MIN (UINT32_C(1) << (HGSMI_MA_DESC_ORDER_BASE + 0))
+#define HGSMI_MA_BLOCK_SIZE_MAX (UINT32_C(1) << (HGSMI_MA_DESC_ORDER_BASE + HGSMI_MA_DESC_ORDER_MASK))
+
+/* HGSMI_MA_DESC_ORDER_BASE must correspond to HGSMI_MA_DESC_OFFSET_MASK. */
+AssertCompile((~HGSMI_MA_DESC_OFFSET_MASK + 1) == HGSMI_MA_BLOCK_SIZE_MIN);
+
+
+typedef struct HGSMIMABLOCK
+{
+    RTLISTNODE nodeBlock;
+    RTLISTNODE nodeFree;
+    HGSMIOFFSET descriptor;
+} HGSMIMABLOCK;
+
+typedef struct HGSMIMADATA
+{
+    HGSMIAREA area;
+    HGSMIENV env;
+    HGSMISIZE cbMaxBlock;
+
+    uint32_t cBlocks;                                           /* How many blocks in the listBlocks. */
+    RTLISTANCHOR listBlocks;                                    /* All memory blocks, sorted. */
+    RTLISTANCHOR aListFreeBlocks[HGSMI_MA_DESC_ORDER_MASK + 1]; /* For free blocks of each order. */
+} HGSMIMADATA;
+
+RT_C_DECLS_BEGIN
+
+int HGSMIMAInit(HGSMIMADATA *pMA, const HGSMIAREA *pArea,
+                HGSMIOFFSET *paDescriptors, uint32_t cDescriptors, HGSMISIZE cbMaxBlock,
+                const HGSMIENV *pEnv);
+void HGSMIMAUninit(HGSMIMADATA *pMA);
+
+void *HGSMIMAAlloc(HGSMIMADATA *pMA, HGSMISIZE cb);
+void HGSMIMAFree(HGSMIMADATA *pMA, void *pv);
+
+HGSMIMABLOCK *HGSMIMASearchOffset(HGSMIMADATA *pMA, HGSMIOFFSET off);
+
+uint32_t HGSMIPopCnt32(uint32_t u32);
+
+DECLINLINE(HGSMISIZE) HGSMIMAOrder2Size(HGSMIOFFSET order)
+{
+    return (UINT32_C(1) << (HGSMI_MA_DESC_ORDER_BASE + order));
+}
+
+DECLINLINE(HGSMIOFFSET) HGSMIMASize2Order(HGSMISIZE cb)
+{
+    HGSMIOFFSET order = HGSMIPopCnt32(cb - 1) - HGSMI_MA_DESC_ORDER_BASE;
+    Assert(HGSMIMAOrder2Size(order) == cb);
+    return order;
+}
+
+RT_C_DECLS_END
+
+#endif /* !___VBox_HGSMI_HGSMIMemAlloc_h */
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/include/VBox/Hardware/VBoxVideoVBE.h
@@ -0,0 +1,87 @@
+/** @file
+ * VirtualBox graphics card port I/O definitions
+ */
+
+/*
+ * Copyright (C) 2006-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+#ifndef ___VBox_Hardware_VBoxVideoVBE_h
+#define ___VBox_Hardware_VBoxVideoVBE_h
+
+/* GUEST <-> HOST Communication API */
+
+/** @todo FIXME: Either dynamicly ask host for this or put somewhere high in
+ *               physical memory like 0xE0000000. */
+
+#define VBE_DISPI_BANK_ADDRESS          0xA0000
+#define VBE_DISPI_BANK_SIZE_KB          64
+
+#define VBE_DISPI_MAX_XRES              16384
+#define VBE_DISPI_MAX_YRES              16384
+#define VBE_DISPI_MAX_BPP               32
+
+#define VBE_DISPI_IOPORT_INDEX          0x01CE
+#define VBE_DISPI_IOPORT_DATA           0x01CF
+
+#define VBE_DISPI_IOPORT_DAC_WRITE_INDEX  0x03C8
+#define VBE_DISPI_IOPORT_DAC_DATA         0x03C9
+
+#define VBE_DISPI_INDEX_ID              0x0
+#define VBE_DISPI_INDEX_XRES            0x1
+#define VBE_DISPI_INDEX_YRES            0x2
+#define VBE_DISPI_INDEX_BPP             0x3
+#define VBE_DISPI_INDEX_ENABLE          0x4
+#define VBE_DISPI_INDEX_BANK            0x5
+#define VBE_DISPI_INDEX_VIRT_WIDTH      0x6
+#define VBE_DISPI_INDEX_VIRT_HEIGHT     0x7
+#define VBE_DISPI_INDEX_X_OFFSET        0x8
+#define VBE_DISPI_INDEX_Y_OFFSET        0x9
+#define VBE_DISPI_INDEX_VBOX_VIDEO      0xa
+#define VBE_DISPI_INDEX_FB_BASE_HI      0xb
+
+#define VBE_DISPI_ID0                   0xB0C0
+#define VBE_DISPI_ID1                   0xB0C1
+#define VBE_DISPI_ID2                   0xB0C2
+#define VBE_DISPI_ID3                   0xB0C3
+#define VBE_DISPI_ID4                   0xB0C4
+
+#define VBE_DISPI_ID_VBOX_VIDEO         0xBE00
+/* The VBOX interface id. Indicates support for VBVA shared memory interface. */
+#define VBE_DISPI_ID_HGSMI              0xBE01
+#define VBE_DISPI_ID_ANYX               0xBE02
+
+#define VBE_DISPI_DISABLED              0x00
+#define VBE_DISPI_ENABLED               0x01
+#define VBE_DISPI_GETCAPS               0x02
+#define VBE_DISPI_8BIT_DAC              0x20
+/** @note this definition is a BOCHS legacy, used only in the video BIOS
+ *        code and ignored by the emulated hardware. */
+#define VBE_DISPI_LFB_ENABLED           0x40
+#define VBE_DISPI_NOCLEARMEM            0x80
+
+#define VGA_PORT_HGSMI_HOST             0x3b0
+#define VGA_PORT_HGSMI_GUEST            0x3d0
+
+/* this should be in sync with monitorCount <xsd:maxInclusive value="64"/> in src/VBox/Main/xml/VirtualBox-settings-common.xsd */
+#define VBOX_VIDEO_MAX_SCREENS 64
+
+#endif /* !___VBox_Hardware_VBoxVideoVBE_h */
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/include/VBox/VBoxGuest.h
@@ -0,0 +1,565 @@
+/** @file
+ * VBoxGuest - VirtualBox Guest Additions Driver Interface. (ADD,DEV)
+ *
+ * @remarks This is in the process of being split up and usage cleaned up.
+ */
+
+/*
+ * Copyright (C) 2006-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+#ifndef ___VBox_VBoxGuest_h
+#define ___VBox_VBoxGuest_h
+
+#include <VBox/cdefs.h>
+#include <VBox/types.h>
+#include <iprt/assert.h>
+#include <VBox/VMMDev2.h>
+#include <VBox/VBoxGuest2.h>
+
+
+/** @defgroup grp_vboxguest  VirtualBox Guest Additions Device Driver
+ *
+ * Also know as VBoxGuest.
+ *
+ * @{
+ */
+
+/** @defgroup grp_vboxguest_ioc  VirtualBox Guest Additions Driver Interface
+ * @{
+ */
+
+/** @todo It would be nice if we could have two defines without paths. */
+
+/** @def VBOXGUEST_DEVICE_NAME
+ * The support device name. */
+/** @def VBOXGUEST_USER_DEVICE_NAME
+ * The support device name of the user accessible device node. */
+
+#if defined(RT_OS_OS2)
+# define VBOXGUEST_DEVICE_NAME          "\\Dev\\VBoxGst$"
+
+#elif defined(RT_OS_WINDOWS)
+# define VBOXGUEST_DEVICE_NAME          "\\\\.\\VBoxGuest"
+
+/** The support service name. */
+# define VBOXGUEST_SERVICE_NAME         "VBoxGuest"
+/** Global name for Win2k+ */
+# define VBOXGUEST_DEVICE_NAME_GLOBAL   "\\\\.\\Global\\VBoxGuest"
+/** Win32 driver name */
+# define VBOXGUEST_DEVICE_NAME_NT       L"\\Device\\VBoxGuest"
+/** Device name. */
+# define VBOXGUEST_DEVICE_NAME_DOS      L"\\DosDevices\\VBoxGuest"
+
+#elif defined(RT_OS_HAIKU)
+# define VBOXGUEST_DEVICE_NAME          "/dev/misc/vboxguest"
+
+#else /* (PORTME) */
+# define VBOXGUEST_DEVICE_NAME          "/dev/vboxguest"
+# if defined(RT_OS_LINUX)
+#  define VBOXGUEST_USER_DEVICE_NAME    "/dev/vboxuser"
+# endif
+#endif
+
+#ifndef VBOXGUEST_USER_DEVICE_NAME
+# define VBOXGUEST_USER_DEVICE_NAME     VBOXGUEST_DEVICE_NAME
+#endif
+
+/** Fictive start address of the hypervisor physical memory for MmMapIoSpace. */
+#define VBOXGUEST_HYPERVISOR_PHYSICAL_START     UINT32_C(0xf8000000)
+
+#ifdef RT_OS_DARWIN
+/** Cookie used to fend off some unwanted clients to the IOService. */
+# define VBOXGUEST_DARWIN_IOSERVICE_COOKIE      UINT32_C(0x56426f78) /* 'VBox' */
+#endif
+
+#if !defined(IN_RC) && !defined(IN_RING0_AGNOSTIC) && !defined(IPRT_NO_CRT)
+
+/** @name VBoxGuest IOCTL codes and structures.
+ *
+ * The range 0..15 is for basic driver communication.
+ * The range 16..31 is for HGCM communication.
+ * The range 32..47 is reserved for future use.
+ * The range 48..63 is for OS specific communication.
+ * The 7th bit is reserved for future hacks.
+ * The 8th bit is reserved for distinguishing between 32-bit and 64-bit
+ * processes in future 64-bit guest additions.
+ *
+ * @remarks When creating new IOCtl interfaces keep in mind that not all OSes supports
+ *          reporting back the output size. (This got messed up a little bit in VBoxDrv.)
+ *
+ *          The request size is also a little bit tricky as it's passed as part of the
+ *          request code on unix. The size field is 14 bits on Linux, 12 bits on *BSD,
+ *          13 bits Darwin, and 8-bits on Solaris. All the BSDs and Darwin kernels
+ *          will make use of the size field, while Linux and Solaris will not. We're of
+ *          course using the size to validate and/or map/lock the request, so it has
+ *          to be valid.
+ *
+ *          For Solaris we will have to do something special though, 255 isn't
+ *          sufficient for all we need. A 4KB restriction (BSD) is probably not
+ *          too problematic (yet) as a general one.
+ *
+ *          More info can be found in SUPDRVIOC.h and related sources.
+ *
+ * @remarks If adding interfaces that only has input or only has output, some new macros
+ *          needs to be created so the most efficient IOCtl data buffering method can be
+ *          used.
+ * @{
+ */
+#if defined(RT_ARCH_AMD64) || defined(RT_ARCH_SPARC64)
+# define VBOXGUEST_IOCTL_FLAG     128
+#elif defined(RT_ARCH_X86) || defined(RT_ARCH_SPARC)
+# define VBOXGUEST_IOCTL_FLAG     0
+#else
+# error "dunno which arch this is!"
+#endif
+/** @} */
+
+/** Ring-3 request wrapper for big requests.
+ *
+ * This is necessary because the ioctl number scheme on many Unixy OSes (esp. Solaris)
+ * only allows a relatively small size to be encoded into the request. So, for big
+ * request this generic form is used instead. */
+typedef struct VBGLBIGREQ
+{
+    /** Magic value (VBGLBIGREQ_MAGIC). */
+    uint32_t    u32Magic;
+    /** The size of the data buffer. */
+    uint32_t    cbData;
+    /** The user address of the data buffer. */
+    RTR3PTR     pvDataR3;
+#if HC_ARCH_BITS == 32
+    uint32_t    u32Padding;
+#endif
+/** @todo r=bird: We need a 'rc' field for passing VBox status codes. Reused
+ *        some input field as rc on output. */
+} VBGLBIGREQ;
+/** Pointer to a request wrapper for solaris guests. */
+typedef VBGLBIGREQ *PVBGLBIGREQ;
+/** Pointer to a const request wrapper for solaris guests. */
+typedef const VBGLBIGREQ *PCVBGLBIGREQ;
+
+/** The VBGLBIGREQ::u32Magic value (Ryuu Murakami). */
+#define VBGLBIGREQ_MAGIC                            0x19520219
+
+
+#if defined(RT_OS_WINDOWS)
+/** @todo Remove IOCTL_CODE later! Integrate it in VBOXGUEST_IOCTL_CODE below. */
+/** @todo r=bird: IOCTL_CODE is supposedly defined in some header included by Windows.h or ntddk.h, which is why it wasn't in the #if 0 earlier. See HostDrivers/Support/SUPDrvIOC.h... */
+# define IOCTL_CODE(DeviceType, Function, Method, Access, DataSize_ignored) \
+  ( ((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method))
+# define VBOXGUEST_IOCTL_CODE_(Function, Size)      IOCTL_CODE(FILE_DEVICE_UNKNOWN, 2048 + (Function), METHOD_BUFFERED, FILE_WRITE_ACCESS, 0)
+# define VBOXGUEST_IOCTL_STRIP_SIZE(Code)           (Code)
+
+#elif defined(RT_OS_OS2)
+  /* No automatic buffering, size not encoded. */
+# define VBOXGUEST_IOCTL_CATEGORY                   0xc2
+# define VBOXGUEST_IOCTL_CODE_(Function, Size)      ((unsigned char)(Function))
+# define VBOXGUEST_IOCTL_CATEGORY_FAST              0xc3 /**< Also defined in VBoxGuestA-os2.asm. */
+# define VBOXGUEST_IOCTL_CODE_FAST_(Function)       ((unsigned char)(Function))
+# define VBOXGUEST_IOCTL_STRIP_SIZE(Code)           (Code)
+
+#elif defined(RT_OS_SOLARIS)
+  /* No automatic buffering, size limited to 255 bytes => use VBGLBIGREQ for everything. */
+# include <sys/ioccom.h>
+# define VBOXGUEST_IOCTL_CODE_(Function, Size)      _IOWRN('V', (Function), sizeof(VBGLBIGREQ))
+# define VBOXGUEST_IOCTL_CODE_FAST_(Function)       _IO(  'V', (Function))
+# define VBOXGUEST_IOCTL_STRIP_SIZE(Code)           (Code)
+
+#elif defined(RT_OS_LINUX)
+  /* No automatic buffering, size limited to 16KB. */
+# include <linux/ioctl.h>
+# define VBOXGUEST_IOCTL_CODE_(Function, Size)      _IOC(_IOC_READ|_IOC_WRITE, 'V', (Function), (Size))
+# define VBOXGUEST_IOCTL_CODE_FAST_(Function)       _IO(  'V', (Function))
+# define VBOXGUEST_IOCTL_STRIP_SIZE(Code)           VBOXGUEST_IOCTL_CODE_(_IOC_NR((Code)), 0)
+
+#elif defined(RT_OS_HAIKU)
+  /* No automatic buffering, size not encoded. */
+  /** @todo do something better */
+# define VBOXGUEST_IOCTL_CODE_(Function, Size)      (0x56420000 | (Function))
+# define VBOXGUEST_IOCTL_CODE_FAST_(Function)       (0x56420000 | (Function))
+# define VBOXGUEST_IOCTL_STRIP_SIZE(Code)           (Code)
+
+#elif defined(RT_OS_FREEBSD) /** @todo r=bird: Please do it like SUPDRVIOC to keep it as similar as possible. */
+# include <sys/ioccom.h>
+
+# define VBOXGUEST_IOCTL_CODE_(Function, Size)      _IOWR('V', (Function), VBGLBIGREQ)
+# define VBOXGUEST_IOCTL_CODE_FAST_(Function)       _IO(  'V', (Function))
+# define VBOXGUEST_IOCTL_STRIP_SIZE(Code)           IOCBASECMD(Code)
+
+#else /* BSD Like */
+  /* Automatic buffering, size limited to 4KB on *BSD and 8KB on Darwin - commands the limit, 4KB. */
+# include <sys/ioccom.h>
+# define VBOXGUEST_IOCTL_CODE_(Function, Size)      _IOC(IOC_INOUT, 'V', (Function), (Size))
+# define VBOXGUEST_IOCTL_CODE_FAST_(Function)       _IO('V', (Function))
+# define VBOXGUEST_IOCTL_STRIP_SIZE(uIOCtl)         ( (uIOCtl) & ~_IOC(0,0,0,IOCPARM_MASK) )
+#endif
+
+#define VBOXGUEST_IOCTL_CODE(Function, Size)        VBOXGUEST_IOCTL_CODE_((Function) | VBOXGUEST_IOCTL_FLAG, Size)
+#define VBOXGUEST_IOCTL_CODE_FAST(Function)         VBOXGUEST_IOCTL_CODE_FAST_((Function) | VBOXGUEST_IOCTL_FLAG)
+
+/* Define 32 bit codes to support 32 bit applications requests in the 64 bit guest driver. */
+#ifdef RT_ARCH_AMD64
+# define VBOXGUEST_IOCTL_CODE_32(Function, Size)    VBOXGUEST_IOCTL_CODE_(Function, Size)
+# define VBOXGUEST_IOCTL_CODE_FAST_32(Function)     VBOXGUEST_IOCTL_CODE_FAST_(Function)
+#endif /* RT_ARCH_AMD64 */
+
+
+
+/** IOCTL to VBoxGuest to query the VMMDev IO port region start.
+ * @remarks Ring-0 only. */
+#define VBOXGUEST_IOCTL_GETVMMDEVPORT               VBOXGUEST_IOCTL_CODE(1, sizeof(VBoxGuestPortInfo))
+
+#pragma pack(4)
+typedef struct VBoxGuestPortInfo
+{
+    uint32_t portAddress;
+    struct VMMDevMemory *pVMMDevMemory;
+} VBoxGuestPortInfo;
+
+
+/** IOCTL to VBoxGuest to wait for a VMMDev host notification */
+#define VBOXGUEST_IOCTL_WAITEVENT                   VBOXGUEST_IOCTL_CODE_(2, sizeof(VBoxGuestWaitEventInfo))
+
+/** @name Result codes for VBoxGuestWaitEventInfo::u32Result
+ * @{
+ */
+/** Successful completion, an event occurred. */
+#define VBOXGUEST_WAITEVENT_OK          (0)
+/** Successful completion, timed out. */
+#define VBOXGUEST_WAITEVENT_TIMEOUT     (1)
+/** Wait was interrupted. */
+#define VBOXGUEST_WAITEVENT_INTERRUPTED (2)
+/** An error occurred while processing the request. */
+#define VBOXGUEST_WAITEVENT_ERROR       (3)
+/** @} */
+
+/** Input and output buffers layout of the IOCTL_VBOXGUEST_WAITEVENT */
+typedef struct VBoxGuestWaitEventInfo
+{
+    /** timeout in milliseconds */
+    uint32_t u32TimeoutIn;
+    /** events to wait for */
+    uint32_t u32EventMaskIn;
+    /** result code */
+    uint32_t u32Result;
+    /** events occurred */
+    uint32_t u32EventFlagsOut;
+} VBoxGuestWaitEventInfo;
+AssertCompileSize(VBoxGuestWaitEventInfo, 16);
+
+
+/** IOCTL to VBoxGuest to perform a VMM request
+ * @remark  The data buffer for this IOCtl has an variable size, keep this in mind
+ *          on systems where this matters. */
+#define VBOXGUEST_IOCTL_VMMREQUEST(Size)            VBOXGUEST_IOCTL_CODE_(3, (Size))
+
+
+/** IOCTL to VBoxGuest to control event filter mask. */
+#define VBOXGUEST_IOCTL_CTL_FILTER_MASK             VBOXGUEST_IOCTL_CODE_(4, sizeof(VBoxGuestFilterMaskInfo))
+
+/** Input and output buffer layout of the IOCTL_VBOXGUEST_CTL_FILTER_MASK. */
+typedef struct VBoxGuestFilterMaskInfo
+{
+    uint32_t u32OrMask;
+    uint32_t u32NotMask;
+} VBoxGuestFilterMaskInfo;
+AssertCompileSize(VBoxGuestFilterMaskInfo, 8);
+#pragma pack()
+
+/** IOCTL to VBoxGuest to interrupt (cancel) any pending WAITEVENTs and return.
+ * Handled inside the guest additions and not seen by the host at all.
+ * @see VBOXGUEST_IOCTL_WAITEVENT */
+#define VBOXGUEST_IOCTL_CANCEL_ALL_WAITEVENTS       VBOXGUEST_IOCTL_CODE_(5, 0)
+
+/** IOCTL to VBoxGuest to perform backdoor logging.
+ * The argument is a string buffer of the specified size. */
+#define VBOXGUEST_IOCTL_LOG(Size)                   VBOXGUEST_IOCTL_CODE_(6, (Size))
+
+/** IOCTL to VBoxGuest to check memory ballooning.
+ * The guest kernel module / device driver will ask the host for the current size of
+ * the balloon and adjust the size. Or it will set fHandledInR0 = false and R3 is
+ * responsible for allocating memory and calling R0 (VBOXGUEST_IOCTL_CHANGE_BALLOON). */
+#define VBOXGUEST_IOCTL_CHECK_BALLOON               VBOXGUEST_IOCTL_CODE_(7, sizeof(VBoxGuestCheckBalloonInfo))
+
+/** Output buffer layout of the VBOXGUEST_IOCTL_CHECK_BALLOON. */
+typedef struct VBoxGuestCheckBalloonInfo
+{
+    /** The size of the balloon in chunks of 1MB. */
+    uint32_t cBalloonChunks;
+    /** false = handled in R0, no further action required.
+     *   true = allocate balloon memory in R3. */
+    uint32_t fHandleInR3;
+} VBoxGuestCheckBalloonInfo;
+AssertCompileSize(VBoxGuestCheckBalloonInfo, 8);
+
+
+/** IOCTL to VBoxGuest to supply or revoke one chunk for ballooning.
+ * The guest kernel module / device driver will lock down supplied memory or
+ * unlock reclaimed memory and then forward the physical addresses of the
+ * changed balloon chunk to the host. */
+#define VBOXGUEST_IOCTL_CHANGE_BALLOON              VBOXGUEST_IOCTL_CODE_(8, sizeof(VBoxGuestChangeBalloonInfo))
+
+/** Input buffer layout of the VBOXGUEST_IOCTL_CHANGE_BALLOON request.
+ * Information about a memory chunk used to inflate or deflate the balloon. */
+typedef struct VBoxGuestChangeBalloonInfo
+{
+    /** Address of the chunk. */
+    uint64_t u64ChunkAddr;
+    /** true = inflate, false = deflate. */
+    uint32_t fInflate;
+    /** Alignment padding. */
+    uint32_t u32Align;
+} VBoxGuestChangeBalloonInfo;
+AssertCompileSize(VBoxGuestChangeBalloonInfo, 16);
+
+/** IOCTL to VBoxGuest to write guest core. */
+#define VBOXGUEST_IOCTL_WRITE_CORE_DUMP             VBOXGUEST_IOCTL_CODE(9, sizeof(VBoxGuestWriteCoreDump))
+
+/** Input and output buffer layout of the VBOXGUEST_IOCTL_WRITE_CORE
+ *  request. */
+typedef struct VBoxGuestWriteCoreDump
+{
+    /** Flags (reserved, MBZ). */
+    uint32_t fFlags;
+} VBoxGuestWriteCoreDump;
+AssertCompileSize(VBoxGuestWriteCoreDump, 4);
+
+/** IOCTL to VBoxGuest to update the mouse status features. */
+# define VBOXGUEST_IOCTL_SET_MOUSE_STATUS           VBOXGUEST_IOCTL_CODE_(10, sizeof(uint32_t))
+
+#ifdef VBOX_WITH_HGCM
+/** IOCTL to VBoxGuest to connect to a HGCM service. */
+# define VBOXGUEST_IOCTL_HGCM_CONNECT               VBOXGUEST_IOCTL_CODE(16, sizeof(VBoxGuestHGCMConnectInfo))
+
+/** IOCTL to VBoxGuest to disconnect from a HGCM service. */
+# define VBOXGUEST_IOCTL_HGCM_DISCONNECT            VBOXGUEST_IOCTL_CODE(17, sizeof(VBoxGuestHGCMDisconnectInfo))
+
+/** IOCTL to VBoxGuest to make a call to a HGCM service.
+ * @see VBoxGuestHGCMCallInfo */
+# define VBOXGUEST_IOCTL_HGCM_CALL(Size)            VBOXGUEST_IOCTL_CODE(18, (Size))
+
+/** IOCTL to VBoxGuest to make a timed call to a HGCM service. */
+# define VBOXGUEST_IOCTL_HGCM_CALL_TIMED(Size)      VBOXGUEST_IOCTL_CODE(20, (Size))
+
+/** IOCTL to VBoxGuest passed from the Kernel Mode driver, but containing a user mode data in VBoxGuestHGCMCallInfo
+ * the driver received from the UM. Called in the context of the process passing the data.
+ * @see VBoxGuestHGCMCallInfo */
+# define VBOXGUEST_IOCTL_HGCM_CALL_USERDATA(Size)   VBOXGUEST_IOCTL_CODE(21, (Size))
+
+# ifdef RT_ARCH_AMD64
+/** @name IOCTL numbers that 32-bit clients, like the Windows OpenGL guest
+ *        driver, will use when taking to a 64-bit driver.
+ * @remarks These are only used by the driver implementation!
+ * @{*/
+#  define VBOXGUEST_IOCTL_HGCM_CONNECT_32           VBOXGUEST_IOCTL_CODE_32(16, sizeof(VBoxGuestHGCMConnectInfo))
+#  define VBOXGUEST_IOCTL_HGCM_DISCONNECT_32        VBOXGUEST_IOCTL_CODE_32(17, sizeof(VBoxGuestHGCMDisconnectInfo))
+#  define VBOXGUEST_IOCTL_HGCM_CALL_32(Size)        VBOXGUEST_IOCTL_CODE_32(18, (Size))
+#  define VBOXGUEST_IOCTL_HGCM_CALL_TIMED_32(Size)  VBOXGUEST_IOCTL_CODE_32(20, (Size))
+/** @} */
+# endif /* RT_ARCH_AMD64 */
+
+/** Get the pointer to the first HGCM parameter.  */
+# define VBOXGUEST_HGCM_CALL_PARMS(a)             ( (HGCMFunctionParameter   *)((uint8_t *)(a) + sizeof(VBoxGuestHGCMCallInfo)) )
+/** Get the pointer to the first HGCM parameter in a 32-bit request.  */
+# define VBOXGUEST_HGCM_CALL_PARMS32(a)           ( (HGCMFunctionParameter32 *)((uint8_t *)(a) + sizeof(VBoxGuestHGCMCallInfo)) )
+
+#endif /* VBOX_WITH_HGCM */
+
+#ifdef VBOX_WITH_DPC_LATENCY_CHECKER
+/** IOCTL to VBoxGuest to perform DPC latency tests, printing the result in
+ * the release log on the host.  Takes no data, returns no data. */
+# define VBOXGUEST_IOCTL_DPC_LATENCY_CHECKER        VBOXGUEST_IOCTL_CODE_(30, 0)
+#endif
+
+/** IOCTL to for setting the mouse driver callback. (kernel only) */
+/** @note The callback will be called in interrupt context with the VBoxGuest
+ * device event spinlock held. */
+#define VBOXGUEST_IOCTL_SET_MOUSE_NOTIFY_CALLBACK   VBOXGUEST_IOCTL_CODE(31, sizeof(VBoxGuestMouseSetNotifyCallback))
+
+typedef DECLCALLBACK(void) FNVBOXGUESTMOUSENOTIFY(void *pfnUser);
+typedef FNVBOXGUESTMOUSENOTIFY *PFNVBOXGUESTMOUSENOTIFY;
+
+/** Input buffer for VBOXGUEST_IOCTL_INTERNAL_SET_MOUSE_NOTIFY_CALLBACK. */
+typedef struct VBoxGuestMouseSetNotifyCallback
+{
+    /**
+     * Mouse notification callback.
+     *
+     * @param   pvUser      The callback argument.
+     */
+    PFNVBOXGUESTMOUSENOTIFY      pfnNotify;
+    /** The callback argument*/
+    void                       *pvUser;
+} VBoxGuestMouseSetNotifyCallback;
+
+
+typedef enum VBOXGUESTCAPSACQUIRE_FLAGS
+{
+    VBOXGUESTCAPSACQUIRE_FLAGS_NONE = 0,
+    /* configures VBoxGuest to use the specified caps in Acquire mode, w/o making any caps acquisition/release.
+     * so far it is only possible to set acquire mode for caps, but not clear it,
+     * so u32NotMask is ignored for this request */
+    VBOXGUESTCAPSACQUIRE_FLAGS_CONFIG_ACQUIRE_MODE,
+    /* to ensure enum is 32bit*/
+    VBOXGUESTCAPSACQUIRE_FLAGS_32bit = 0x7fffffff
+} VBOXGUESTCAPSACQUIRE_FLAGS;
+
+typedef struct VBoxGuestCapsAquire
+{
+    /* result status
+     * VINF_SUCCESS - on success
+     * VERR_RESOURCE_BUSY    - some caps in the u32OrMask are acquired by some other VBoxGuest connection.
+     *                         NOTE: no u32NotMask caps are cleaned in this case, i.e. no modifications are done on failure
+     * VER_INVALID_PARAMETER - invalid Caps are specified with either u32OrMask or u32NotMask. No modifications are done on failure.
+     */
+    int32_t rc;
+    /* Acquire command */
+    VBOXGUESTCAPSACQUIRE_FLAGS enmFlags;
+    /* caps to acquire, OR-ed VMMDEV_GUEST_SUPPORTS_XXX flags */
+    uint32_t u32OrMask;
+    /* caps to release, OR-ed VMMDEV_GUEST_SUPPORTS_XXX flags */
+    uint32_t u32NotMask;
+} VBoxGuestCapsAquire;
+
+/** IOCTL to for Acquiring/Releasing Guest Caps
+ * This is used for multiple purposes:
+ * 1. By doing Acquire r3 client application (e.g. VBoxTray) claims it will use
+ *    the given connection for performing operations like Seamles or Auto-resize,
+ *    thus, if the application terminates, the driver will automatically cleanup the caps reported to host,
+ *    so that host knows guest does not support them anymore
+ * 2. In a multy-user environment this will not allow r3 applications (like VBoxTray)
+ *    running in different user sessions simultaneously to interfere with each other.
+ *    An r3 client application (like VBoxTray) is responsible for Acquiring/Releasing caps properly as needed.
+ **/
+#define VBOXGUEST_IOCTL_GUEST_CAPS_ACQUIRE          VBOXGUEST_IOCTL_CODE(32, sizeof(VBoxGuestCapsAquire))
+
+/** IOCTL to VBoxGuest to set guest capabilities. */
+#define VBOXGUEST_IOCTL_SET_GUEST_CAPABILITIES      VBOXGUEST_IOCTL_CODE_(33, sizeof(VBoxGuestSetCapabilitiesInfo))
+
+/** Input and output buffer layout of the VBOXGUEST_IOCTL_SET_GUEST_CAPABILITIES
+ *  IOCtl. */
+typedef struct VBoxGuestSetCapabilitiesInfo
+{
+    uint32_t u32OrMask;
+    uint32_t u32NotMask;
+} VBoxGuestSetCapabilitiesInfo;
+AssertCompileSize(VBoxGuestSetCapabilitiesInfo, 8);
+
+
+#ifdef RT_OS_OS2
+
+/**
+ * The data buffer layout for the IDC entry point (AttachDD).
+ *
+ * @remark  This is defined in multiple 16-bit headers / sources.
+ *          Some places it's called VBGOS2IDC to short things a bit.
+ */
+typedef struct VBOXGUESTOS2IDCCONNECT
+{
+    /** VMMDEV_VERSION. */
+    uint32_t u32Version;
+    /** Opaque session handle. */
+    uint32_t u32Session;
+
+    /**
+     * The 32-bit service entry point.
+     *
+     * @returns VBox status code.
+     * @param   u32Session          The above session handle.
+     * @param   iFunction           The requested function.
+     * @param   pvData              The input/output data buffer. The caller ensures that this
+     *                              cannot be swapped out, or that it's acceptable to take a
+     *                              page in fault in the current context. If the request doesn't
+     *                              take input or produces output, apssing NULL is okay.
+     * @param   cbData              The size of the data buffer.
+     * @param   pcbDataReturned     Where to store the amount of data that's returned.
+     *                              This can be NULL if pvData is NULL.
+     */
+    DECLCALLBACKMEMBER(int, pfnServiceEP)(uint32_t u32Session, unsigned iFunction, void *pvData, size_t cbData, size_t *pcbDataReturned);
+
+    /** The 16-bit service entry point for C code (cdecl).
+     *
+     * It's the same as the 32-bit entry point, but the types has
+     * changed to 16-bit equivalents.
+     *
+     * @code
+     * int far cdecl
+     * VBoxGuestOs2IDCService16(uint32_t u32Session, uint16_t iFunction,
+     *                          void far *fpvData, uint16_t cbData, uint16_t far *pcbDataReturned);
+     * @endcode
+     */
+    RTFAR16 fpfnServiceEP;
+
+    /** The 16-bit service entry point for Assembly code (register).
+     *
+     * This is just a wrapper around fpfnServiceEP to simplify calls
+     * from 16-bit assembly code.
+     *
+     * @returns (e)ax: VBox status code; cx: The amount of data returned.
+     *
+     * @param   u32Session          eax   - The above session handle.
+     * @param   iFunction           dl    - The requested function.
+     * @param   pvData              es:bx - The input/output data buffer.
+     * @param   cbData              cx    - The size of the data buffer.
+     */
+    RTFAR16 fpfnServiceAsmEP;
+} VBOXGUESTOS2IDCCONNECT;
+/** Pointer to VBOXGUESTOS2IDCCONNECT buffer. */
+typedef VBOXGUESTOS2IDCCONNECT *PVBOXGUESTOS2IDCCONNECT;
+
+/** OS/2 specific: IDC client disconnect request.
+ *
+ * This takes no input and it doesn't return anything. Obviously this
+ * is only recognized if it arrives thru the IDC service EP.
+ */
+# define VBOXGUEST_IOCTL_OS2_IDC_DISCONNECT     VBOXGUEST_IOCTL_CODE(48, sizeof(uint32_t))
+
+#endif /* RT_OS_OS2 */
+
+#if defined(RT_OS_LINUX) || defined(RT_OS_SOLARIS) || defined(RT_OS_FREEBSD)
+
+/* Private IOCtls between user space and the kernel video driver.  DRM private
+ * IOCtls always have the type 'd' and a number between 0x40 and 0x99 (0x9F?) */
+
+# define VBOX_DRM_IOCTL(a) (0x40 + DRM_VBOX_ ## a)
+
+/** Stop using HGSMI in the kernel driver until it is re-enabled, so that a
+ *  user-space driver can use it.  It must be re-enabled before the kernel
+ *  driver can be used again in a sensible way. */
+/** @note These IOCtls was removed from the code, but are left here as
+ * templates as we may need similar ones in future. */
+# define DRM_VBOX_DISABLE_HGSMI    0
+# define DRM_IOCTL_VBOX_DISABLE_HGSMI    VBOX_DRM_IOCTL(DISABLE_HGSMI)
+# define VBOXVIDEO_IOCTL_DISABLE_HGSMI   _IO('d', DRM_IOCTL_VBOX_DISABLE_HGSMI)
+/** Enable HGSMI in the kernel driver after it was previously disabled. */
+# define DRM_VBOX_ENABLE_HGSMI     1
+# define DRM_IOCTL_VBOX_ENABLE_HGSMI     VBOX_DRM_IOCTL(ENABLE_HGSMI)
+# define VBOXVIDEO_IOCTL_ENABLE_HGSMI    _IO('d', DRM_IOCTL_VBOX_ENABLE_HGSMI)
+
+#endif /* RT_OS_LINUX || RT_OS_SOLARIS || RT_OS_FREEBSD */
+
+#endif /* !defined(IN_RC) && !defined(IN_RING0_AGNOSTIC) && !defined(IPRT_NO_CRT) */
+
+/** @} */
+
+/** @} */
+#endif
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/include/VBox/VBoxGuest2.h
@@ -0,0 +1,112 @@
+/** @file
+ * VBoxGuest - VirtualBox Guest Additions Driver Interface, Mixed Up Mess.
+ * (ADD,DEV)
+ */
+
+/*
+ * Copyright (C) 2006-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+#ifndef ___VBox_VBoxGuest2_h
+#define ___VBox_VBoxGuest2_h
+
+#include <iprt/assert.h>
+
+#ifdef VBOX_WITH_HGCM
+# include <VBox/VMMDev2.h>
+
+/** @addtogroup grp_vmmdev
+ * @{ */
+
+/**
+ * HGCM connect info structure.
+ *
+ * This is used by VBOXGUEST_IOCTL_HGCM_CONNECT and in VbglR0.
+ *
+ * @ingroup grp_vboxguest
+ */
+# pragma pack(1) /* explicit packing for good measure. */
+typedef struct VBoxGuestHGCMConnectInfo
+{
+    int32_t result;           /**< OUT */
+    HGCMServiceLocation Loc;  /**< IN */
+    uint32_t u32ClientID;     /**< OUT */
+} VBoxGuestHGCMConnectInfo;
+AssertCompileSize(VBoxGuestHGCMConnectInfo, 4+4+128+4);
+# pragma pack()
+
+
+/**
+ * HGCM connect info structure.
+ *
+ * This is used by VBOXGUEST_IOCTL_HGCM_DISCONNECT and in VbglR0.
+ *
+ * @ingroup grp_vboxguest
+ */
+typedef struct VBoxGuestHGCMDisconnectInfo
+{
+    int32_t result;           /**< OUT */
+    uint32_t u32ClientID;     /**< IN */
+} VBoxGuestHGCMDisconnectInfo;
+AssertCompileSize(VBoxGuestHGCMDisconnectInfo, 8);
+
+/**
+ * HGCM call info structure.
+ *
+ * This is used by VBOXGUEST_IOCTL_HGCM_CALL.
+ *
+ * @ingroup grp_vboxguest
+ */
+typedef struct VBoxGuestHGCMCallInfo
+{
+    int32_t result;           /**< OUT Host HGCM return code.*/
+    uint32_t u32ClientID;     /**< IN  The id of the caller. */
+    uint32_t u32Function;     /**< IN  Function number. */
+    uint32_t cParms;          /**< IN  How many parms. */
+    /* Parameters follow in form HGCMFunctionParameter aParms[cParms] */
+} VBoxGuestHGCMCallInfo;
+AssertCompileSize(VBoxGuestHGCMCallInfo, 16);
+
+
+/**
+ * HGCM call info structure.
+ *
+ * This is used by VBOXGUEST_IOCTL_HGCM_CALL_TIMED.
+ *
+ * @ingroup grp_vboxguest
+ */
+# pragma pack(1) /* explicit packing for good measure. */
+typedef struct VBoxGuestHGCMCallInfoTimed
+{
+    uint32_t u32Timeout;         /**< IN  How long to wait for completion before cancelling the call. */
+    uint32_t fInterruptible;     /**< IN  Is this request interruptible? */
+    VBoxGuestHGCMCallInfo info;  /**< IN/OUT The rest of the call information.  Placed after the timeout
+                                  * so that the parameters follow as they would for a normal call. */
+    /* Parameters follow in form HGCMFunctionParameter aParms[cParms] */
+} VBoxGuestHGCMCallInfoTimed;
+AssertCompileSize(VBoxGuestHGCMCallInfoTimed, 8+16);
+# pragma pack()
+
+/** @} */
+
+#endif /* VBOX_WITH_HGCM */
+
+#endif
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/include/VBox/VBoxGuestLib.h
@@ -0,0 +1,858 @@
+/** @file
+ * VBoxGuestLib - VirtualBox Guest Additions Library.
+ */
+
+/*
+ * Copyright (C) 2006-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+#ifndef ___VBox_VBoxGuestLib_h
+#define ___VBox_VBoxGuestLib_h
+
+#include <VBox/types.h>
+#include <VBox/VMMDev2.h>
+#include <VBox/VMMDev.h>     /* grumble */
+#ifdef IN_RING0
+# include <VBox/VBoxGuest.h>
+# include <VBox/VBoxGuest2.h>
+#endif
+
+
+/** @defgroup grp_vboxguest_lib     VirtualBox Guest Additions Library
+ * @ingroup grp_vboxguest
+ * @{
+ */
+
+/** @page pg_guest_lib  VirtualBox Guest Library
+ *
+ * This is a library for abstracting the additions driver interface. There are
+ * multiple versions of the library depending on the context. The main
+ * distinction is between kernel and user mode where the interfaces are very
+ * different.
+ *
+ *
+ * @section sec_guest_lib_ring0     Ring-0
+ *
+ * In ring-0 there are two version:
+ *  - VBOX_LIB_VBGL_R0_BASE / VBoxGuestR0LibBase for the VBoxGuest main driver,
+ *    who is responsible for managing the VMMDev virtual hardware.
+ *  - VBOX_LIB_VBGL_R0 / VBoxGuestR0Lib for other (client) guest drivers.
+ *
+ *
+ * The library source code and the header have a define VBGL_VBOXGUEST, which is
+ * defined for VBoxGuest and undefined for other drivers. Drivers must choose
+ * right library in their makefiles and set VBGL_VBOXGUEST accordingly.
+ *
+ * The libraries consists of:
+ *  - common code to be used by both VBoxGuest and other drivers;
+ *  - VBoxGuest specific code;
+ *  - code for other drivers which communicate with VBoxGuest via an IOCTL.
+ *
+ *
+ * @section sec_guest_lib_ring3     Ring-3
+ *
+ * There are more variants of the library here:
+ *  - VBOX_LIB_VBGL_R3 / VBoxGuestR3Lib for programs.
+ *  - VBOX_LIB_VBGL_R3_XFREE86 / VBoxGuestR3LibXFree86 for old style XFree
+ *    drivers which uses special loader and or symbol resolving strategy.
+ *  - VBOX_LIB_VBGL_R3_SHARED / VBoxGuestR3LibShared for shared objects / DLLs /
+ *    Dylibs.
+ *
+ */
+
+RT_C_DECLS_BEGIN
+
+/** HGCM client ID.
+ * @todo Promote to VBox/types.h  */
+typedef uint32_t HGCMCLIENTID;
+
+
+/** @defgroup grp_vboxguest_lib_r0     Ring-0 interface.
+ * @{
+ */
+#if defined(IN_RING0) && !defined(IN_RING0_AGNOSTIC)
+/** @def DECLR0VBGL
+ * Declare a VBGL ring-0 API with the right calling convention and visibilitiy.
+ * @param type      Return type.  */
+# ifdef RT_OS_DARWIN /** @todo probably apply to all, but don't want a forest fire on our hands right now. */
+#  define DECLR0VBGL(type) DECLHIDDEN(type) VBOXCALL
+# else
+#  define DECLR0VBGL(type) type VBOXCALL
+# endif
+# define DECLVBGL(type) DECLR0VBGL(type)
+
+
+# ifdef VBGL_VBOXGUEST
+
+/**
+ * The library initialization function to be used by the main
+ * VBoxGuest system driver.
+ *
+ * @return VBox status code.
+ */
+DECLVBGL(int) VbglInitPrimary(RTIOPORT portVMMDev, struct VMMDevMemory *pVMMDevMemory);
+
+# else
+
+/**
+ * The library initialization function to be used by all drivers
+ * other than the main VBoxGuest system driver.
+ *
+ * @return VBox status code.
+ */
+DECLVBGL(int) VbglInitClient(void);
+
+# endif
+
+/**
+ * The library termination function.
+ */
+DECLVBGL(void) VbglTerminate (void);
+
+
+/** @name Generic request functions.
+ * @{
+ */
+
+/**
+ * Allocate memory for generic request and initialize the request header.
+ *
+ * @returns VBox status code.
+ * @param   ppReq       Where to return the pointer to the allocated memory.
+ * @param   cbReq       Size of memory block required for the request.
+ * @param   enmReqType  the generic request type.
+ */
+DECLVBGL(int) VbglGRAlloc(VMMDevRequestHeader **ppReq, size_t cbReq, VMMDevRequestType enmReqType);
+
+/**
+ * Perform the generic request.
+ *
+ * @param pReq     pointer the request structure.
+ *
+ * @return VBox status code.
+ */
+DECLVBGL(int) VbglGRPerform (VMMDevRequestHeader *pReq);
+
+/**
+ * Free the generic request memory.
+ *
+ * @param pReq     pointer the request structure.
+ *
+ * @return VBox status code.
+ */
+DECLVBGL(void) VbglGRFree (VMMDevRequestHeader *pReq);
+
+/**
+ * Verify the generic request header.
+ *
+ * @param pReq     pointer the request header structure.
+ * @param cbReq    size of the request memory block. It should be equal to the request size
+ *                 for fixed size requests. It can be greater than the request size for
+ *                 variable size requests.
+ *
+ * @return VBox status code.
+ */
+DECLVBGL(int) VbglGRVerify (const VMMDevRequestHeader *pReq, size_t cbReq);
+/** @} */
+
+# ifdef VBOX_WITH_HGCM
+
+#  ifdef VBGL_VBOXGUEST
+
+/**
+ * Callback function called from HGCM helpers when a wait for request
+ * completion IRQ is required.
+ *
+ * @returns VINF_SUCCESS, VERR_INTERRUPT or VERR_TIMEOUT.
+ * @param   pvData      VBoxGuest pointer to be passed to callback.
+ * @param   u32Data     VBoxGuest 32 bit value to be passed to callback.
+ */
+typedef DECLCALLBACK(int) FNVBGLHGCMCALLBACK(VMMDevHGCMRequestHeader *pHeader, void *pvData, uint32_t u32Data);
+/** Pointer to a FNVBGLHGCMCALLBACK. */
+typedef FNVBGLHGCMCALLBACK *PFNVBGLHGCMCALLBACK;
+
+/**
+ * Perform a connect request. That is locate required service and
+ * obtain a client identifier for future access.
+ *
+ * @note This function can NOT handle cancelled requests!
+ *
+ * @param   pConnectInfo        The request data.
+ * @param   pfnAsyncCallback    Required pointer to function that is calledwhen
+ *                              host returns VINF_HGCM_ASYNC_EXECUTE. VBoxGuest
+ *                              implements waiting for an IRQ in this function.
+ * @param   pvAsyncData         An arbitrary VBoxGuest pointer to be passed to callback.
+ * @param   u32AsyncData        An arbitrary VBoxGuest 32 bit value to be passed to callback.
+ *
+ * @return  VBox status code.
+ */
+
+DECLR0VBGL(int) VbglR0HGCMInternalConnect (VBoxGuestHGCMConnectInfo *pConnectInfo,
+                                           PFNVBGLHGCMCALLBACK pfnAsyncCallback, void *pvAsyncData, uint32_t u32AsyncData);
+
+
+/**
+ * Perform a disconnect request. That is tell the host that
+ * the client will not call the service anymore.
+ *
+ * @note This function can NOT handle cancelled requests!
+ *
+ * @param   pDisconnectInfo     The request data.
+ * @param   pfnAsyncCallback    Required pointer to function that is called when
+ *                              host returns VINF_HGCM_ASYNC_EXECUTE. VBoxGuest
+ *                              implements waiting for an IRQ in this function.
+ * @param   pvAsyncData         An arbitrary VBoxGuest pointer to be passed to callback.
+ * @param   u32AsyncData        An arbitrary VBoxGuest 32 bit value to be passed to
+ *                              callback.
+ *
+ * @return  VBox status code.
+ */
+
+DECLR0VBGL(int) VbglR0HGCMInternalDisconnect (VBoxGuestHGCMDisconnectInfo *pDisconnectInfo,
+                                              PFNVBGLHGCMCALLBACK pfnAsyncCallback, void *pvAsyncData, uint32_t u32AsyncData);
+
+/** Call a HGCM service.
+ *
+ * @note This function can deal with cancelled requests.
+ *
+ * @param   pCallInfo           The request data.
+ * @param   fFlags              Flags, see VBGLR0_HGCMCALL_F_XXX.
+ * @param   pfnAsyncCallback    Required pointer to function that is called when
+ *                              host returns VINF_HGCM_ASYNC_EXECUTE. VBoxGuest
+ *                              implements waiting for an IRQ in this function.
+ * @param   pvAsyncData         An arbitrary VBoxGuest pointer to be passed to callback.
+ * @param   u32AsyncData        An arbitrary VBoxGuest 32 bit value to be passed to callback.
+ *
+ * @return VBox status code.
+ */
+DECLR0VBGL(int) VbglR0HGCMInternalCall (VBoxGuestHGCMCallInfo *pCallInfo, uint32_t cbCallInfo, uint32_t fFlags,
+                                        PFNVBGLHGCMCALLBACK pfnAsyncCallback, void *pvAsyncData, uint32_t u32AsyncData);
+
+/** Call a HGCM service. (32 bits packet structure in a 64 bits guest)
+ *
+ * @note This function can deal with cancelled requests.
+ *
+ * @param   pCallInfo           The request data.
+ * @param   fFlags              Flags, see VBGLR0_HGCMCALL_F_XXX.
+ * @param   pfnAsyncCallback    Required pointer to function that is called when
+ *                              host returns VINF_HGCM_ASYNC_EXECUTE. VBoxGuest
+ *                              implements waiting for an IRQ in this function.
+ * @param   pvAsyncData         An arbitrary VBoxGuest pointer to be passed to callback.
+ * @param   u32AsyncData        An arbitrary VBoxGuest 32 bit value to be passed to callback.
+ *
+ * @return  VBox status code.
+ */
+DECLR0VBGL(int) VbglR0HGCMInternalCall32 (VBoxGuestHGCMCallInfo *pCallInfo, uint32_t cbCallInfo, uint32_t fFlags,
+                                          PFNVBGLHGCMCALLBACK pfnAsyncCallback, void *pvAsyncData, uint32_t u32AsyncData);
+
+/** @name VbglR0HGCMInternalCall flags
+ * @{ */
+/** User mode request.
+ * Indicates that only user mode addresses are permitted as parameters. */
+#define VBGLR0_HGCMCALL_F_USER          UINT32_C(0)
+/** Kernel mode request.
+ * Indicates that kernel mode addresses are permitted as parameters. Whether or
+ * not user mode addresses are permitted is, unfortunately, OS specific. The
+ * following OSes allows user mode addresses: Windows, TODO.
+ */
+#define VBGLR0_HGCMCALL_F_KERNEL        UINT32_C(1)
+/** Mode mask. */
+#define VBGLR0_HGCMCALL_F_MODE_MASK     UINT32_C(1)
+/** @} */
+
+#  else  /* !VBGL_VBOXGUEST */
+
+struct VBGLHGCMHANDLEDATA;
+typedef struct VBGLHGCMHANDLEDATA *VBGLHGCMHANDLE;
+
+/** @name HGCM functions
+ * @{
+ */
+
+/**
+ * Connect to a service.
+ *
+ * @param pHandle     Pointer to variable that will hold a handle to be used
+ *                    further in VbglHGCMCall and VbglHGCMClose.
+ * @param pData       Connection information structure.
+ *
+ * @return VBox status code.
+ */
+DECLVBGL(int) VbglHGCMConnect (VBGLHGCMHANDLE *pHandle, VBoxGuestHGCMConnectInfo *pData);
+
+/**
+ * Connect to a service.
+ *
+ * @param handle      Handle of the connection.
+ * @param pData       Disconnect request information structure.
+ *
+ * @return VBox status code.
+ */
+DECLVBGL(int) VbglHGCMDisconnect (VBGLHGCMHANDLE handle, VBoxGuestHGCMDisconnectInfo *pData);
+
+/**
+ * Call to a service.
+ *
+ * @param handle      Handle of the connection.
+ * @param pData       Call request information structure, including function parameters.
+ * @param cbData      Length in bytes of data.
+ *
+ * @return VBox status code.
+ */
+DECLVBGL(int) VbglHGCMCall (VBGLHGCMHANDLE handle, VBoxGuestHGCMCallInfo *pData, uint32_t cbData);
+
+/**
+ * Call to a service with user-mode data received by the calling driver from the User-Mode process.
+ * The call must be done in the context of a calling process.
+ *
+ * @param handle      Handle of the connection.
+ * @param pData       Call request information structure, including function parameters.
+ * @param cbData      Length in bytes of data.
+ *
+ * @return VBox status code.
+ */
+DECLVBGL(int) VbglHGCMCallUserData (VBGLHGCMHANDLE handle, VBoxGuestHGCMCallInfo *pData, uint32_t cbData);
+
+/**
+ * Call to a service with timeout.
+ *
+ * @param handle      Handle of the connection.
+ * @param pData       Call request information structure, including function parameters.
+ * @param cbData      Length in bytes of data.
+ * @param cMillies    Timeout in milliseconds.  Use RT_INDEFINITE_WAIT to wait forever.
+ *
+ * @return VBox status code.
+ */
+DECLVBGL(int) VbglHGCMCallTimed(VBGLHGCMHANDLE handle, VBoxGuestHGCMCallInfoTimed *pData, uint32_t cbData);
+/** @} */
+
+/** @name Undocumented helpers for talking to the Chromium OpenGL Host Service
+ * @{ */
+typedef VBGLHGCMHANDLE VBGLCRCTLHANDLE;
+DECLVBGL(int) VbglR0CrCtlCreate(VBGLCRCTLHANDLE *phCtl);
+DECLVBGL(int) VbglR0CrCtlDestroy(VBGLCRCTLHANDLE hCtl);
+DECLVBGL(int) VbglR0CrCtlConConnect(VBGLCRCTLHANDLE hCtl, HGCMCLIENTID *pidClient);
+DECLVBGL(int) VbglR0CrCtlConDisconnect(VBGLCRCTLHANDLE hCtl, HGCMCLIENTID idClient);
+DECLVBGL(int) VbglR0CrCtlConCall(VBGLCRCTLHANDLE hCtl, struct VBoxGuestHGCMCallInfo *pCallInfo, int cbCallInfo);
+DECLVBGL(int) VbglR0CrCtlConCallUserData(VBGLCRCTLHANDLE hCtl, struct VBoxGuestHGCMCallInfo *pCallInfo, int cbCallInfo);
+/** @} */
+
+#  endif /* !VBGL_VBOXGUEST */
+
+# endif /* VBOX_WITH_HGCM */
+
+
+/**
+ * Initialize the heap.
+ *
+ * @returns VBox status code.
+ */
+DECLVBGL(int) VbglPhysHeapInit (void);
+
+/**
+ * Shutdown the heap.
+ */
+DECLVBGL(void) VbglPhysHeapTerminate (void);
+
+/**
+ * Allocate a memory block.
+ *
+ * @returns Virtual address of the allocated memory block.
+ * @param cbSize    Size of block to be allocated.
+ */
+DECLVBGL(void *) VbglPhysHeapAlloc (uint32_t cbSize);
+
+/**
+ * Get physical address of memory block pointed by the virtual address.
+ *
+ * @note WARNING!
+ *       The function does not acquire the Heap mutex!
+ *       When calling the function make sure that the pointer is a valid one and
+ *       is not being deallocated.  This function can NOT be used for verifying
+ *       if the given pointer is a valid one allocated from the heap.
+ *
+ * @param   pv      Virtual address of memory block.
+ * @returns Physical address of the memory block.
+ */
+DECLVBGL(uint32_t)  VbglPhysHeapGetPhysAddr(void *pv);
+
+/**
+ * Free a memory block.
+ *
+ * @param   pv    Virtual address of memory block.
+ */
+DECLVBGL(void)      VbglPhysHeapFree(void *pv);
+
+DECLVBGL(int) VbglQueryVMMDevMemory (VMMDevMemory **ppVMMDevMemory);
+DECLR0VBGL(bool) VbglR0CanUsePhysPageList(void);
+
+# ifndef VBOX_GUEST
+/** @name Mouse
+ * @{ */
+DECLVBGL(int)     VbglSetMouseNotifyCallback(PFNVBOXGUESTMOUSENOTIFY pfnNotify, void *pvUser);
+DECLVBGL(int)     VbglGetMouseStatus(uint32_t *pfFeatures, uint32_t *px, uint32_t *py);
+DECLVBGL(int)     VbglSetMouseStatus(uint32_t fFeatures);
+/** @}  */
+# endif /* VBOX_GUEST */
+
+#endif /* IN_RING0 && !IN_RING0_AGNOSTIC */
+
+/** @} */
+
+
+/** @defgroup grp_vboxguest_lib_r3      Ring-3 interface.
+ * @{
+ */
+#ifdef IN_RING3
+
+/** @def VBGLR3DECL
+ * Ring 3 VBGL declaration.
+ * @param   type    The return type of the function declaration.
+ */
+# define VBGLR3DECL(type) type VBOXCALL
+
+/** @name General-purpose functions
+ * @{ */
+VBGLR3DECL(int)     VbglR3Init(void);
+VBGLR3DECL(int)     VbglR3InitUser(void);
+VBGLR3DECL(void)    VbglR3Term(void);
+# ifdef ___iprt_time_h
+VBGLR3DECL(int)     VbglR3GetHostTime(PRTTIMESPEC pTime);
+# endif
+VBGLR3DECL(int)     VbglR3InterruptEventWaits(void);
+VBGLR3DECL(int)     VbglR3WriteLog(const char *pch, size_t cch);
+VBGLR3DECL(int)     VbglR3CtlFilterMask(uint32_t fOr, uint32_t fNot);
+VBGLR3DECL(int)     VbglR3Daemonize(bool fNoChDir, bool fNoClose, bool fRespawn, unsigned *pcRespawn);
+VBGLR3DECL(int)     VbglR3PidFile(const char *pszPath, PRTFILE phFile);
+VBGLR3DECL(void)    VbglR3ClosePidFile(const char *pszPath, RTFILE hFile);
+VBGLR3DECL(int)     VbglR3SetGuestCaps(uint32_t fOr, uint32_t fNot);
+VBGLR3DECL(int)     VbglR3WaitEvent(uint32_t fMask, uint32_t cMillies, uint32_t *pfEvents);
+
+VBGLR3DECL(int)     VbglR3ReportAdditionsStatus(VBoxGuestFacilityType Facility, VBoxGuestFacilityStatus StatusCurrent,
+                                                uint32_t fFlags);
+VBGLR3DECL(int)     VbglR3GetAdditionsVersion(char **ppszVer, char **ppszVerEx, char **ppszRev);
+VBGLR3DECL(int)     VbglR3GetAdditionsInstallationPath(char **ppszPath);
+VBGLR3DECL(int)     VbglR3GetSessionId(uint64_t *pu64IdSession);
+
+/** @} */
+
+/** @name Shared clipboard
+ * @{ */
+VBGLR3DECL(int)     VbglR3ClipboardConnect(HGCMCLIENTID *pidClient);
+VBGLR3DECL(int)     VbglR3ClipboardDisconnect(HGCMCLIENTID idClient);
+VBGLR3DECL(int)     VbglR3ClipboardGetHostMsg(HGCMCLIENTID idClient, uint32_t *pMsg, uint32_t *pfFormats);
+VBGLR3DECL(int)     VbglR3ClipboardReadData(HGCMCLIENTID idClient, uint32_t fFormat, void *pv, uint32_t cb, uint32_t *pcb);
+VBGLR3DECL(int)     VbglR3ClipboardReportFormats(HGCMCLIENTID idClient, uint32_t fFormats);
+VBGLR3DECL(int)     VbglR3ClipboardWriteData(HGCMCLIENTID idClient, uint32_t fFormat, void *pv, uint32_t cb);
+/** @} */
+
+/** @name Seamless mode
+ * @{ */
+VBGLR3DECL(int)     VbglR3SeamlessSetCap(bool fState);
+VBGLR3DECL(int)     VbglR3SeamlessWaitEvent(VMMDevSeamlessMode *pMode);
+VBGLR3DECL(int)     VbglR3SeamlessSendRects(uint32_t cRects, PRTRECT pRects);
+VBGLR3DECL(int)     VbglR3SeamlessGetLastEvent(VMMDevSeamlessMode *pMode);
+
+/** @}  */
+
+/** @name Mouse
+ * @{ */
+VBGLR3DECL(int)     VbglR3GetMouseStatus(uint32_t *pfFeatures, uint32_t *px, uint32_t *py);
+VBGLR3DECL(int)     VbglR3SetMouseStatus(uint32_t fFeatures);
+/** @}  */
+
+/** @name Video
+ * @{ */
+VBGLR3DECL(int)     VbglR3VideoAccelEnable(bool fEnable);
+VBGLR3DECL(int)     VbglR3VideoAccelFlush(void);
+VBGLR3DECL(int)     VbglR3SetPointerShape(uint32_t fFlags, uint32_t xHot, uint32_t yHot, uint32_t cx, uint32_t cy,
+                                          const void *pvImg, size_t cbImg);
+VBGLR3DECL(int)     VbglR3SetPointerShapeReq(struct VMMDevReqMousePointer *pReq);
+/** @}  */
+
+/** @name Display
+ * @{ */
+/** The folder for the video mode hint unix domain socket on Unix-like guests.
+ * @note This can be safely changed as all users are rebuilt in lock-step. */
+#define VBGLR3HOSTDISPSOCKETPATH "/tmp/.VBoxService"
+/** The path to the video mode hint unix domain socket on Unix-like guests. */
+#define VBGLR3HOSTDISPSOCKET        VBGLR3VIDEOMODEHINTSOCKETPATH "/VideoModeHint"
+
+/** The folder for saving video mode hints to between sessions. */
+#define VBGLR3HOSTDISPSAVEDMODEPATH "/var/lib/VBoxGuestAdditions"
+/** The path to the file for saving video mode hints to between sessions. */
+#define VBGLR3HOSTDISPSAVEDMODE     VBGLR3HOSTDISPSAVEDMODEPATH "/SavedVideoModes"
+
+VBGLR3DECL(int)     VbglR3GetDisplayChangeRequest(uint32_t *pcx, uint32_t *pcy, uint32_t *pcBits, uint32_t *piDisplay,
+                                                  uint32_t *pdx, uint32_t *pdy, bool *pfEnabled, bool *pfChangeOrigin, bool fAck);
+VBGLR3DECL(bool)    VbglR3HostLikesVideoMode(uint32_t cx, uint32_t cy, uint32_t cBits);
+VBGLR3DECL(int)     VbglR3VideoModeGetHighestSavedScreen(unsigned *pcScreen);
+VBGLR3DECL(int)     VbglR3SaveVideoMode(unsigned cScreen, unsigned cx, unsigned cy, unsigned cBits,
+                                        unsigned x, unsigned y, bool fEnabled);
+VBGLR3DECL(int)     VbglR3RetrieveVideoMode(unsigned cScreen, unsigned *pcx, unsigned *pcy, unsigned *pcBits,
+                                            unsigned *px, unsigned *py, bool *pfEnabled);
+/** @}  */
+
+/** @name VM Statistics
+ * @{ */
+VBGLR3DECL(int)     VbglR3StatQueryInterval(uint32_t *pu32Interval);
+VBGLR3DECL(int)     VbglR3StatReport(VMMDevReportGuestStats *pReq);
+/** @}  */
+
+/** @name Memory ballooning
+ * @{ */
+VBGLR3DECL(int)     VbglR3MemBalloonRefresh(uint32_t *pcChunks, bool *pfHandleInR3);
+VBGLR3DECL(int)     VbglR3MemBalloonChange(void *pv, bool fInflate);
+/** @}  */
+
+/** @name Core Dump
+ * @{ */
+VBGLR3DECL(int)     VbglR3WriteCoreDump(void);
+
+/** @}  */
+
+# ifdef VBOX_WITH_GUEST_PROPS
+/** @name Guest properties
+ * @{ */
+/** @todo Docs. */
+typedef struct VBGLR3GUESTPROPENUM VBGLR3GUESTPROPENUM;
+/** @todo Docs. */
+typedef VBGLR3GUESTPROPENUM *PVBGLR3GUESTPROPENUM;
+VBGLR3DECL(int)     VbglR3GuestPropConnect(uint32_t *pidClient);
+VBGLR3DECL(int)     VbglR3GuestPropDisconnect(HGCMCLIENTID idClient);
+VBGLR3DECL(int)     VbglR3GuestPropWrite(HGCMCLIENTID idClient, const char *pszName, const char *pszValue, const char *pszFlags);
+VBGLR3DECL(int)     VbglR3GuestPropWriteValue(HGCMCLIENTID idClient, const char *pszName, const char *pszValue);
+VBGLR3DECL(int)     VbglR3GuestPropWriteValueV(HGCMCLIENTID idClient, const char *pszName,
+                                               const char *pszValueFormat, va_list va) RT_IPRT_FORMAT_ATTR(3, 0);
+VBGLR3DECL(int)     VbglR3GuestPropWriteValueF(HGCMCLIENTID idClient, const char *pszName,
+                                               const char *pszValueFormat, ...) RT_IPRT_FORMAT_ATTR(3, 4);
+VBGLR3DECL(int)     VbglR3GuestPropRead(HGCMCLIENTID idClient, const char *pszName, void *pvBuf, uint32_t cbBuf, char **ppszValue,
+                                        uint64_t *pu64Timestamp, char **ppszFlags, uint32_t *pcbBufActual);
+VBGLR3DECL(int)     VbglR3GuestPropReadValue(uint32_t ClientId, const char *pszName, char *pszValue, uint32_t cchValue,
+                                             uint32_t *pcchValueActual);
+VBGLR3DECL(int)     VbglR3GuestPropReadValueAlloc(HGCMCLIENTID idClient, const char *pszName, char **ppszValue);
+VBGLR3DECL(void)    VbglR3GuestPropReadValueFree(char *pszValue);
+VBGLR3DECL(int)     VbglR3GuestPropEnumRaw(HGCMCLIENTID idClient, const char *paszPatterns, char *pcBuf, uint32_t cbBuf,
+                                           uint32_t *pcbBufActual);
+VBGLR3DECL(int)     VbglR3GuestPropEnum(HGCMCLIENTID idClient, char const * const *ppaszPatterns, uint32_t cPatterns,
+                                        PVBGLR3GUESTPROPENUM *ppHandle, char const **ppszName, char const **ppszValue,
+                                        uint64_t *pu64Timestamp, char const **ppszFlags);
+VBGLR3DECL(int)     VbglR3GuestPropEnumNext(PVBGLR3GUESTPROPENUM pHandle, char const **ppszName, char const **ppszValue,
+                                            uint64_t *pu64Timestamp, char const **ppszFlags);
+VBGLR3DECL(void)    VbglR3GuestPropEnumFree(PVBGLR3GUESTPROPENUM pHandle);
+VBGLR3DECL(int)     VbglR3GuestPropDelete(HGCMCLIENTID idClient, const char *pszName);
+VBGLR3DECL(int)     VbglR3GuestPropDelSet(HGCMCLIENTID idClient, char const * const *papszPatterns, uint32_t cPatterns);
+VBGLR3DECL(int)     VbglR3GuestPropWait(HGCMCLIENTID idClient, const char *pszPatterns, void *pvBuf, uint32_t cbBuf,
+                                        uint64_t u64Timestamp, uint32_t cMillies, char ** ppszName, char **ppszValue,
+                                        uint64_t *pu64Timestamp, char **ppszFlags, uint32_t *pcbBufActual);
+/** @}  */
+
+/** @name Guest user handling / reporting.
+ * @{ */
+VBGLR3DECL(int)     VbglR3GuestUserReportState(const char *pszUser, const char *pszDomain, VBoxGuestUserState enmState,
+                                               uint8_t *pbDetails, uint32_t cbDetails);
+/** @}  */
+
+/** @name Host version handling
+ * @{ */
+VBGLR3DECL(int)     VbglR3HostVersionCheckForUpdate(HGCMCLIENTID idClient, bool *pfUpdate, char **ppszHostVersion,
+                                                    char **ppszGuestVersion);
+VBGLR3DECL(int)     VbglR3HostVersionLastCheckedLoad(HGCMCLIENTID idClient, char **ppszVer);
+VBGLR3DECL(int)     VbglR3HostVersionLastCheckedStore(HGCMCLIENTID idClient, const char *pszVer);
+/** @}  */
+# endif /* VBOX_WITH_GUEST_PROPS defined */
+
+# ifdef VBOX_WITH_SHARED_FOLDERS
+/** @name Shared folders
+ * @{ */
+/**
+ * Structure containing mapping information for a shared folder.
+ */
+typedef struct VBGLR3SHAREDFOLDERMAPPING
+{
+    /** Mapping status. */
+    uint32_t u32Status;
+    /** Root handle. */
+    uint32_t u32Root;
+} VBGLR3SHAREDFOLDERMAPPING;
+/** Pointer to a shared folder mapping information structure. */
+typedef VBGLR3SHAREDFOLDERMAPPING *PVBGLR3SHAREDFOLDERMAPPING;
+/** Pointer to a const shared folder mapping information structure. */
+typedef VBGLR3SHAREDFOLDERMAPPING const *PCVBGLR3SHAREDFOLDERMAPPING;
+
+VBGLR3DECL(int)     VbglR3SharedFolderConnect(uint32_t *pidClient);
+VBGLR3DECL(int)     VbglR3SharedFolderDisconnect(HGCMCLIENTID idClient);
+VBGLR3DECL(bool)    VbglR3SharedFolderExists(HGCMCLIENTID idClient, const char *pszShareName);
+VBGLR3DECL(int)     VbglR3SharedFolderGetMappings(HGCMCLIENTID idClient, bool fAutoMountOnly,
+                                                  PVBGLR3SHAREDFOLDERMAPPING *ppaMappings, uint32_t *pcMappings);
+VBGLR3DECL(void)    VbglR3SharedFolderFreeMappings(PVBGLR3SHAREDFOLDERMAPPING paMappings);
+VBGLR3DECL(int)     VbglR3SharedFolderGetName(HGCMCLIENTID  idClient,uint32_t u32Root, char **ppszName);
+VBGLR3DECL(int)     VbglR3SharedFolderGetMountPrefix(char **ppszPrefix);
+VBGLR3DECL(int)     VbglR3SharedFolderGetMountDir(char **ppszDir);
+/** @}  */
+# endif /* VBOX_WITH_SHARED_FOLDERS defined */
+
+# ifdef VBOX_WITH_GUEST_CONTROL
+/** @name Guest control
+ * @{ */
+
+/**
+ * Structure containing the context required for
+ * either retrieving or sending a HGCM guest control
+ * commands from or to the host.
+ *
+ * Note: Do not change parameter order without also
+ *       adapting all structure initializers.
+ */
+typedef struct VBGLR3GUESTCTRLCMDCTX
+{
+    /** @todo This struct could be handy if we want to implement
+     *        a second communication channel, e.g. via TCP/IP.
+     *        Use a union for the HGCM stuff then. */
+
+    /** IN: HGCM client ID to use for
+     *      communication. */
+    uint32_t uClientID;
+    /** IN/OUT: Context ID to retrieve
+     *          or to use. */
+    uint32_t uContextID;
+    /** IN: Protocol version to use. */
+    uint32_t uProtocol;
+    /** OUT: Number of parameters retrieved. */
+    uint32_t uNumParms;
+} VBGLR3GUESTCTRLCMDCTX, *PVBGLR3GUESTCTRLCMDCTX;
+
+/* General message handling on the guest. */
+VBGLR3DECL(int) VbglR3GuestCtrlConnect(uint32_t *pidClient);
+VBGLR3DECL(int) VbglR3GuestCtrlDisconnect(uint32_t uClientId);
+VBGLR3DECL(int) VbglR3GuestCtrlMsgFilterSet(uint32_t uClientId, uint32_t uValue, uint32_t uMaskAdd, uint32_t uMaskRemove);
+VBGLR3DECL(int) VbglR3GuestCtrlMsgFilterUnset(uint32_t uClientId);
+VBGLR3DECL(int) VbglR3GuestCtrlMsgReply(PVBGLR3GUESTCTRLCMDCTX pCtx, int rc);
+VBGLR3DECL(int) VbglR3GuestCtrlMsgReplyEx(PVBGLR3GUESTCTRLCMDCTX pCtx, int rc, uint32_t uType,
+                                          void *pvPayload, uint32_t cbPayload);
+VBGLR3DECL(int) VbglR3GuestCtrlMsgSkip(uint32_t uClientId);
+VBGLR3DECL(int) VbglR3GuestCtrlMsgWaitFor(uint32_t uClientId, uint32_t *puMsg, uint32_t *puNumParms);
+VBGLR3DECL(int) VbglR3GuestCtrlCancelPendingWaits(HGCMCLIENTID idClient);
+/* Guest session handling. */
+VBGLR3DECL(int) VbglR3GuestCtrlSessionClose(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t fFlags);
+VBGLR3DECL(int) VbglR3GuestCtrlSessionNotify(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t uType, uint32_t uResult);
+VBGLR3DECL(int) VbglR3GuestCtrlSessionGetOpen(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t *puProtocol, char *pszUser, uint32_t cbUser,
+                                              char *pszPassword, uint32_t  cbPassword, char *pszDomain, uint32_t cbDomain,
+                                              uint32_t *pfFlags, uint32_t *pidSession);
+VBGLR3DECL(int) VbglR3GuestCtrlSessionGetClose(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t *pfFlags, uint32_t *pidSession);
+/* Guest path handling. */
+VBGLR3DECL(int) VbglR3GuestCtrlPathGetRename(PVBGLR3GUESTCTRLCMDCTX pCtx, char *pszSource, uint32_t cbSource, char *pszDest,
+                                             uint32_t cbDest, uint32_t *pfFlags);
+/* Guest process execution. */
+VBGLR3DECL(int) VbglR3GuestCtrlProcGetStart(PVBGLR3GUESTCTRLCMDCTX pCtx, char *pszCmd, uint32_t cbCmd, uint32_t *pfFlags,
+                                            char *pszArgs, uint32_t cbArgs, uint32_t *puNumArgs, char *pszEnv, uint32_t *pcbEnv,
+                                            uint32_t *puNumEnvVars, char *pszUser, uint32_t cbUser, char *pszPassword,
+                                            uint32_t cbPassword, uint32_t *puTimeoutMS, uint32_t *puPriority,
+                                            uint64_t *puAffinity, uint32_t cbAffinity, uint32_t *pcAffinity);
+VBGLR3DECL(int) VbglR3GuestCtrlProcGetTerminate(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t *puPID);
+VBGLR3DECL(int) VbglR3GuestCtrlProcGetInput(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t *puPID, uint32_t *pfFlags, void *pvData,
+                                            uint32_t cbData, uint32_t *pcbSize);
+VBGLR3DECL(int) VbglR3GuestCtrlProcGetOutput(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t *puPID, uint32_t *puHandle, uint32_t *pfFlags);
+VBGLR3DECL(int) VbglR3GuestCtrlProcGetWaitFor(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t *puPID, uint32_t *puWaitFlags,
+                                              uint32_t *puTimeoutMS);
+/* Guest native directory handling. */
+VBGLR3DECL(int) VbglR3GuestCtrlDirGetRemove(PVBGLR3GUESTCTRLCMDCTX pCtx, char *pszPath, uint32_t cbPath, uint32_t *pfFlags);
+/* Guest native file handling. */
+VBGLR3DECL(int) VbglR3GuestCtrlFileGetOpen(PVBGLR3GUESTCTRLCMDCTX pCtx, char *pszFileName, uint32_t cbFileName, char *pszOpenMode,
+                                           uint32_t cbOpenMode, char *pszDisposition, uint32_t cbDisposition, char *pszSharing,
+                                           uint32_t cbSharing, uint32_t *puCreationMode, uint64_t *puOffset);
+VBGLR3DECL(int) VbglR3GuestCtrlFileGetClose(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t *puHandle);
+VBGLR3DECL(int) VbglR3GuestCtrlFileGetRead(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t *puHandle, uint32_t *puToRead);
+VBGLR3DECL(int) VbglR3GuestCtrlFileGetReadAt(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t *puHandle,
+                                             uint32_t *puToRead, uint64_t *poffRead);
+VBGLR3DECL(int) VbglR3GuestCtrlFileGetWrite(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t *puHandle,
+                                            void *pvData, uint32_t cbData, uint32_t *pcbActual);
+VBGLR3DECL(int) VbglR3GuestCtrlFileGetWriteAt(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t *puHandle, void *pvData, uint32_t cbData,
+                                              uint32_t *pcbActual, uint64_t *poffWrite);
+VBGLR3DECL(int) VbglR3GuestCtrlFileGetSeek(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t *puHandle,
+                                           uint32_t *puSeekMethod, uint64_t *poffSeek);
+VBGLR3DECL(int) VbglR3GuestCtrlFileGetTell(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t *puHandle);
+/* Guest -> Host. */
+VBGLR3DECL(int) VbglR3GuestCtrlFileCbOpen(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t uRc, uint32_t uFileHandle);
+VBGLR3DECL(int) VbglR3GuestCtrlFileCbClose(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t uRc);
+VBGLR3DECL(int) VbglR3GuestCtrlFileCbError(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t uRc);
+VBGLR3DECL(int) VbglR3GuestCtrlFileCbRead(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t uRc, void *pvData, uint32_t cbData);
+VBGLR3DECL(int) VbglR3GuestCtrlFileCbWrite(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t uRc, uint32_t uWritten);
+VBGLR3DECL(int) VbglR3GuestCtrlFileCbSeek(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t uRc, uint64_t uOffActual);
+VBGLR3DECL(int) VbglR3GuestCtrlFileCbTell(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t uRc, uint64_t uOffActual);
+VBGLR3DECL(int) VbglR3GuestCtrlProcCbStatus(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t uPID, uint32_t uStatus, uint32_t fFlags,
+                                            void *pvData, uint32_t cbData);
+VBGLR3DECL(int) VbglR3GuestCtrlProcCbOutput(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t uPID, uint32_t uHandle, uint32_t fFlags,
+                                            void *pvData, uint32_t cbData);
+VBGLR3DECL(int) VbglR3GuestCtrlProcCbStatusInput(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t u32PID, uint32_t uStatus,
+                                                 uint32_t fFlags, uint32_t cbWritten);
+
+/** @}  */
+# endif /* VBOX_WITH_GUEST_CONTROL defined */
+
+/** @name Auto-logon handling
+ * @{ */
+VBGLR3DECL(int)     VbglR3AutoLogonReportStatus(VBoxGuestFacilityStatus enmStatus);
+VBGLR3DECL(bool)    VbglR3AutoLogonIsRemoteSession(void);
+/** @}  */
+
+/** @name User credentials handling
+ * @{ */
+VBGLR3DECL(int)     VbglR3CredentialsQueryAvailability(void);
+VBGLR3DECL(int)     VbglR3CredentialsRetrieve(char **ppszUser, char **ppszPassword, char **ppszDomain);
+VBGLR3DECL(int)     VbglR3CredentialsRetrieveUtf16(PRTUTF16 *ppwszUser, PRTUTF16 *ppwszPassword, PRTUTF16 *ppwszDomain);
+VBGLR3DECL(void)    VbglR3CredentialsDestroy(char *pszUser, char *pszPassword, char *pszDomain, uint32_t cPasses);
+VBGLR3DECL(void)    VbglR3CredentialsDestroyUtf16(PRTUTF16 pwszUser, PRTUTF16 pwszPassword, PRTUTF16 pwszDomain,
+                                                  uint32_t cPasses);
+/** @}  */
+
+/** @name CPU hotplug monitor
+ * @{ */
+VBGLR3DECL(int)     VbglR3CpuHotPlugInit(void);
+VBGLR3DECL(int)     VbglR3CpuHotPlugTerm(void);
+VBGLR3DECL(int)     VbglR3CpuHotPlugWaitForEvent(VMMDevCpuEventType *penmEventType, uint32_t *pidCpuCore, uint32_t *pidCpuPackage);
+/** @} */
+
+/** @name Page sharing
+ * @{ */
+VBGLR3DECL(int)     VbglR3RegisterSharedModule(char *pszModuleName, char *pszVersion, RTGCPTR64  GCBaseAddr, uint32_t cbModule,
+                                               unsigned cRegions, VMMDEVSHAREDREGIONDESC *pRegions);
+VBGLR3DECL(int)     VbglR3UnregisterSharedModule(char *pszModuleName, char *pszVersion, RTGCPTR64  GCBaseAddr, uint32_t cbModule);
+VBGLR3DECL(int)     VbglR3CheckSharedModules(void);
+VBGLR3DECL(bool)    VbglR3PageSharingIsEnabled(void);
+VBGLR3DECL(int)     VbglR3PageIsShared(RTGCPTR pPage, bool *pfShared, uint64_t *puPageFlags);
+/** @} */
+
+# ifdef VBOX_WITH_DRAG_AND_DROP
+/** @name Drag and Drop
+ * @{ */
+/**
+ * Structure containing the context required for
+ * either retrieving or sending a HGCM guest drag'n drop
+ * commands from or to the host.
+ *
+ * Note: Do not change parameter order without also
+ *       adapting all structure initializers.
+ */
+typedef struct VBGLR3GUESTDNDCMDCTX
+{
+    /** @todo This struct could be handy if we want to implement
+     *        a second communication channel, e.g. via TCP/IP.
+     *        Use a union for the HGCM stuff then. */
+
+    /** HGCM client ID to use for communication. */
+    uint32_t uClientID;
+    /** The VM's current session ID. */
+    uint64_t uSessionID;
+    /** Protocol version to use. */
+    uint32_t uProtocol;
+    /** Number of parameters retrieved for the current command. */
+    uint32_t uNumParms;
+    /** Max chunk size (in bytes) for data transfers. */
+    uint32_t cbMaxChunkSize;
+} VBGLR3GUESTDNDCMDCTX, *PVBGLR3GUESTDNDCMDCTX;
+
+typedef struct VBGLR3DNDHGCMEVENT
+{
+    uint32_t uType;               /** The event type this struct contains. */
+    uint32_t uScreenId;           /** Screen ID this request belongs to. */
+    char    *pszFormats;          /** Format list (\r\n separated). */
+    uint32_t cbFormats;           /** Size (in bytes) of pszFormats (\0 included). */
+    union
+    {
+        struct
+        {
+            uint32_t uXpos;       /** X position of guest screen. */
+            uint32_t uYpos;       /** Y position of guest screen. */
+            uint32_t uDefAction;  /** Proposed DnD action. */
+            uint32_t uAllActions; /** Allowed DnD actions. */
+        } a; /** Values used in init, move and drop event type. */
+        struct
+        {
+            void    *pvData;      /** Data request. */
+            uint32_t cbData;      /** Size (in bytes) of pvData. */
+        } b; /** Values used in drop data event type. */
+    } u;
+} VBGLR3DNDHGCMEVENT;
+typedef VBGLR3DNDHGCMEVENT *PVBGLR3DNDHGCMEVENT;
+typedef const PVBGLR3DNDHGCMEVENT CPVBGLR3DNDHGCMEVENT;
+VBGLR3DECL(int)     VbglR3DnDConnect(PVBGLR3GUESTDNDCMDCTX pCtx);
+VBGLR3DECL(int)     VbglR3DnDDisconnect(PVBGLR3GUESTDNDCMDCTX pCtx);
+
+VBGLR3DECL(int)     VbglR3DnDRecvNextMsg(PVBGLR3GUESTDNDCMDCTX pCtx, CPVBGLR3DNDHGCMEVENT pEvent);
+
+VBGLR3DECL(int)     VbglR3DnDHGSendAckOp(PVBGLR3GUESTDNDCMDCTX pCtx, uint32_t uAction);
+VBGLR3DECL(int)     VbglR3DnDHGSendReqData(PVBGLR3GUESTDNDCMDCTX pCtx, const char *pcszFormat);
+VBGLR3DECL(int)     VbglR3DnDHGSendProgress(PVBGLR3GUESTDNDCMDCTX pCtx, uint32_t uStatus, uint8_t uPercent, int rcErr);
+#  ifdef VBOX_WITH_DRAG_AND_DROP_GH
+VBGLR3DECL(int)     VbglR3DnDGHSendAckPending(PVBGLR3GUESTDNDCMDCTX pCtx, uint32_t uDefAction, uint32_t uAllActions, const char* pcszFormats, uint32_t cbFormats);
+VBGLR3DECL(int)     VbglR3DnDGHSendData(PVBGLR3GUESTDNDCMDCTX pCtx, const char *pszFormat, void *pvData, uint32_t cbData);
+VBGLR3DECL(int)     VbglR3DnDGHSendError(PVBGLR3GUESTDNDCMDCTX pCtx, int rcOp);
+#  endif /* VBOX_WITH_DRAG_AND_DROP_GH */
+/** @} */
+# endif /* VBOX_WITH_DRAG_AND_DROP */
+
+/* Generic Host Channel Service. */
+VBGLR3DECL(int)  VbglR3HostChannelInit(uint32_t *pu32HGCMClientId);
+VBGLR3DECL(void) VbglR3HostChannelTerm(uint32_t u32HGCMClientId);
+VBGLR3DECL(int)  VbglR3HostChannelAttach(uint32_t *pu32ChannelHandle, uint32_t u32HGCMClientId,
+                                         const char *pszName, uint32_t u32Flags);
+VBGLR3DECL(void) VbglR3HostChannelDetach(uint32_t u32ChannelHandle, uint32_t u32HGCMClientId);
+VBGLR3DECL(int)  VbglR3HostChannelSend(uint32_t u32ChannelHandle, uint32_t u32HGCMClientId,
+                                       void *pvData, uint32_t cbData);
+VBGLR3DECL(int)  VbglR3HostChannelRecv(uint32_t u32ChannelHandle, uint32_t u32HGCMClientId,
+                                       void *pvData, uint32_t cbData,
+                                       uint32_t *pu32SizeReceived, uint32_t *pu32SizeRemaining);
+VBGLR3DECL(int)  VbglR3HostChannelControl(uint32_t u32ChannelHandle, uint32_t u32HGCMClientId,
+                                         uint32_t u32Code, void *pvParm, uint32_t cbParm,
+                                         void *pvData, uint32_t cbData, uint32_t *pu32SizeDataReturned);
+VBGLR3DECL(int)  VbglR3HostChannelEventWait(uint32_t *pu32ChannelHandle, uint32_t u32HGCMClientId,
+                                            uint32_t *pu32EventId, void *pvParm, uint32_t cbParm,
+                                            uint32_t *pu32SizeReturned);
+VBGLR3DECL(int)  VbglR3HostChannelEventCancel(uint32_t u32ChannelHandle, uint32_t u32HGCMClientId);
+VBGLR3DECL(int)  VbglR3HostChannelQuery(const char *pszName, uint32_t u32HGCMClientId, uint32_t u32Code,
+                                        void *pvParm, uint32_t cbParm, void *pvData, uint32_t cbData,
+                                        uint32_t *pu32SizeDataReturned);
+
+/** @name Mode hint storage
+ * @{ */
+VBGLR3DECL(int) VbglR3ReadVideoMode(unsigned cDisplay, unsigned *cx,
+                                    unsigned *cy, unsigned *cBPP, unsigned *x,
+                                    unsigned *y, unsigned *fEnabled);
+VBGLR3DECL(int) VbglR3WriteVideoMode(unsigned cDisplay, unsigned cx,
+                                     unsigned cy, unsigned cBPP, unsigned x,
+                                     unsigned y, unsigned fEnabled);
+/** @} */
+
+/** @name Generic HGCM
+ * @{ */
+VBGLR3DECL(int)     VbglR3HGCMConnect(const char *pszServiceName, HGCMCLIENTID *pidClient);
+VBGLR3DECL(int)     VbglR3HGCMDisconnect(HGCMCLIENTID idClient);
+/** @} */
+
+#endif /* IN_RING3 */
+/** @} */
+
+RT_C_DECLS_END
+
+/** @} */
+
+#endif
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/include/VBox/VBoxGuestLibSharedFolders.h
@@ -0,0 +1,120 @@
+/* $Id: VBoxGuestLibSharedFolders.h $ */
+/** @file
+ * VBoxGuestLib - Central calls header.
+ */
+
+/*
+ * Copyright (C) 2006-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+#ifndef ___VBox_VBoxGuestLibSharedFolders_h_
+#define ___VBox_VBoxGuestLibSharedFolders_h_
+
+#include <VBox/VBoxGuestLib.h>
+#include <VBox/shflsvc.h>
+
+RT_C_DECLS_BEGIN
+
+
+/** @addtogroup grp_vboxguest_lib_r0
+ * @{
+ */
+
+typedef struct VBGLSFCLIENT
+{
+    HGCMCLIENTID idClient;
+    VBGLHGCMHANDLE handle;
+} VBGLSFCLIENT;
+typedef VBGLSFCLIENT *PVBGLSFCLIENT;
+
+typedef struct VBGLSFMAP
+{
+    SHFLROOT root;
+} VBGLSFMAP, *PVBGLSFMAP;
+
+DECLVBGL(int)  VbglR0SfInit(void);
+DECLVBGL(void) VbglR0SfTerm(void);
+DECLVBGL(int)  VbglR0SfConnect(PVBGLSFCLIENT pClient);
+DECLVBGL(void) VbglR0SfDisconnect(PVBGLSFCLIENT pClient);
+
+DECLVBGL(int)  VbglR0SfQueryMappings(PVBGLSFCLIENT pClient, SHFLMAPPING paMappings[], uint32_t *pcMappings);
+
+DECLVBGL(int)  VbglR0SfQueryMapName(PVBGLSFCLIENT pClient, SHFLROOT root, SHFLSTRING *pString, uint32_t size);
+
+/**
+ * Create a new file or folder or open an existing one in a shared folder.  Proxies
+ * to vbsfCreate in the host shared folder service.
+ *
+ * @returns IPRT status code, but see note below
+ * @param   pClient      Host-guest communication connection
+ * @param   pMap         The mapping for the shared folder in which the file
+ *                       or folder is to be created
+ * @param   pParsedPath  The path of the file or folder relative to the shared
+ *                       folder
+ * @param   pCreateParms Parameters for file/folder creation.  See the
+ *                       structure description in shflsvc.h
+ * @retval  pCreateParms See the structure description in shflsvc.h
+ *
+ * @note This function reports errors as follows.  The return value is always
+ *       VINF_SUCCESS unless an exceptional condition occurs - out of
+ *       memory, invalid arguments, etc.  If the file or folder could not be
+ *       opened or created, pCreateParms->Handle will be set to
+ *       SHFL_HANDLE_NIL on return.  In this case the value in
+ *       pCreateParms->Result provides information as to why (e.g.
+ *       SHFL_FILE_EXISTS).  pCreateParms->Result is also set on success
+ *       as additional information.
+ */
+DECLVBGL(int)  VbglR0SfCreate(PVBGLSFCLIENT pClient, PVBGLSFMAP pMap, PSHFLSTRING pParsedPath, PSHFLCREATEPARMS pCreateParms);
+
+DECLVBGL(int)  VbglR0SfClose(PVBGLSFCLIENT pClient, PVBGLSFMAP pMap, SHFLHANDLE Handle);
+DECLVBGL(int)  VbglR0SfRemove(PVBGLSFCLIENT pClient, PVBGLSFMAP pMap, PSHFLSTRING pParsedPath, uint32_t flags);
+DECLVBGL(int)  VbglR0SfRename(PVBGLSFCLIENT pClient, PVBGLSFMAP pMap, PSHFLSTRING pSrcPath, PSHFLSTRING pDestPath, uint32_t flags);
+DECLVBGL(int)  VbglR0SfFlush(PVBGLSFCLIENT pClient, PVBGLSFMAP pMap, SHFLHANDLE hFile);
+
+DECLVBGL(int)  VbglR0SfRead(PVBGLSFCLIENT pClient, PVBGLSFMAP pMap, SHFLHANDLE hFile, uint64_t offset, uint32_t *pcbBuffer, uint8_t *pBuffer, bool fLocked);
+DECLVBGL(int)  VbglR0SfReadPageList(PVBGLSFCLIENT pClient, PVBGLSFMAP pMap, SHFLHANDLE hFile, uint64_t offset, uint32_t *pcbBuffer,
+                                    uint16_t offFirstPage, uint16_t cPages, RTGCPHYS64 *paPages);
+DECLVBGL(int)  VbglR0SfWrite(PVBGLSFCLIENT pClient, PVBGLSFMAP pMap, SHFLHANDLE hFile, uint64_t offset,
+                             uint32_t *pcbBuffer,  uint8_t *pBuffer, bool fLocked);
+DECLVBGL(int)  VbglR0SfWritePhysCont(PVBGLSFCLIENT pClient, PVBGLSFMAP pMap, SHFLHANDLE hFile, uint64_t offset,
+                                     uint32_t *pcbBuffer, RTCCPHYS PhysBuffer);
+DECLVBGL(int)  VbglR0SfWritePageList(PVBGLSFCLIENT pClient, PVBGLSFMAP pMap, SHFLHANDLE hFile, uint64_t offset, uint32_t *pcbBuffer,
+                                     uint16_t offFirstPage, uint16_t cPages, RTGCPHYS64 *paPages);
+
+DECLVBGL(int)  VbglR0SfLock(PVBGLSFCLIENT pClient, PVBGLSFMAP pMap, SHFLHANDLE hFile, uint64_t offset, uint64_t cbSize, uint32_t fLock);
+
+DECLVBGL(int)  VbglR0SfDirInfo(PVBGLSFCLIENT pClient, PVBGLSFMAP pMap, SHFLHANDLE hFile,PSHFLSTRING ParsedPath, uint32_t flags,
+                               uint32_t index, uint32_t *pcbBuffer, PSHFLDIRINFO pBuffer, uint32_t *pcFiles);
+DECLVBGL(int)  VbglR0SfFsInfo(PVBGLSFCLIENT pClient, PVBGLSFMAP pMap, SHFLHANDLE hFile, uint32_t flags, uint32_t *pcbBuffer, PSHFLDIRINFO pBuffer);
+
+DECLVBGL(int)  VbglR0SfMapFolder(PVBGLSFCLIENT pClient, PSHFLSTRING szFolderName, PVBGLSFMAP pMap);
+DECLVBGL(int)  VbglR0SfUnmapFolder(PVBGLSFCLIENT pClient, PVBGLSFMAP pMap);
+DECLVBGL(int)  VbglR0SfSetUtf8(PVBGLSFCLIENT pClient);
+
+DECLVBGL(int)  VbglR0SfReadLink(PVBGLSFCLIENT pClient, PVBGLSFMAP pMap, PSHFLSTRING ParsedPath, uint32_t pcbBuffer, uint8_t *pBuffer);
+DECLVBGL(int)  VbglR0SfSymlink(PVBGLSFCLIENT pClient, PVBGLSFMAP pMap, PSHFLSTRING pNewPath, PSHFLSTRING pOldPath, PSHFLFSOBJINFO pBuffer);
+DECLVBGL(int)  VbglR0SfSetSymlinks(PVBGLSFCLIENT pClient);
+
+/** @} */
+
+RT_C_DECLS_END
+
+#endif
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/include/VBox/VBoxGuestMangling.h
@@ -0,0 +1,32 @@
+/** @file
+ * VBoxGuest - Mangling of IPRT symbols for guest drivers.
+ *
+ * This is included via a compiler directive on platforms with a global kernel
+ * symbol name space (i.e. not Windows, OS/2 and Mac OS X (?)).
+ */
+
+/*
+ * Copyright (C) 2011-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+
+#define RT_MANGLER(symbol)   VBoxGuest_##symbol
+#include <iprt/mangling.h>
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/include/VBox/VBoxVideo.h
@@ -0,0 +1,2016 @@
+/** @file
+ * VirtualBox Video interface.
+ */
+
+/*
+ * Copyright (C) 2006-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+#ifndef ___VBox_VBoxVideo_h
+#define ___VBox_VBoxVideo_h
+
+#include <VBox/VMMDev.h>
+#include <VBox/Hardware/VBoxVideoVBE.h>
+
+#include <iprt/cdefs.h>
+#include <iprt/types.h>
+
+/*
+ * The last 4096 bytes of the guest VRAM contains the generic info for all
+ * DualView chunks: sizes and offsets of chunks. This is filled by miniport.
+ *
+ * Last 4096 bytes of each chunk contain chunk specific data: framebuffer info,
+ * etc. This is used exclusively by the corresponding instance of a display driver.
+ *
+ * The VRAM layout:
+ *     Last 4096 bytes - Adapter information area.
+ *     4096 bytes aligned miniport heap (value specified in the config rouded up).
+ *     Slack - what left after dividing the VRAM.
+ *     4096 bytes aligned framebuffers:
+ *       last 4096 bytes of each framebuffer is the display information area.
+ *
+ * The Virtual Graphics Adapter information in the guest VRAM is stored by the
+ * guest video driver using structures prepended by VBOXVIDEOINFOHDR.
+ *
+ * When the guest driver writes dword 0 to the VBE_DISPI_INDEX_VBOX_VIDEO
+ * the host starts to process the info. The first element at the start of
+ * the 4096 bytes region should be normally be a LINK that points to
+ * actual information chain. That way the guest driver can have some
+ * fixed layout of the information memory block and just rewrite
+ * the link to point to relevant memory chain.
+ *
+ * The processing stops at the END element.
+ *
+ * The host can access the memory only when the port IO is processed.
+ * All data that will be needed later must be copied from these 4096 bytes.
+ * But other VRAM can be used by host until the mode is disabled.
+ *
+ * The guest driver writes dword 0xffffffff to the VBE_DISPI_INDEX_VBOX_VIDEO
+ * to disable the mode.
+ *
+ * VBE_DISPI_INDEX_VBOX_VIDEO is used to read the configuration information
+ * from the host and issue commands to the host.
+ *
+ * The guest writes the VBE_DISPI_INDEX_VBOX_VIDEO index register, the the
+ * following operations with the VBE data register can be performed:
+ *
+ * Operation            Result
+ * write 16 bit value   NOP
+ * read 16 bit value    count of monitors
+ * write 32 bit value   sets the vbox command value and the command processed by the host
+ * read 32 bit value    result of the last vbox command is returned
+ */
+
+#define VBOX_VIDEO_PRIMARY_SCREEN 0
+#define VBOX_VIDEO_NO_SCREEN ~0
+
+/* The size of the information. */
+/*
+ * The minimum HGSMI heap size is PAGE_SIZE (4096 bytes) and is a restriction of the
+ * runtime heapsimple API. Use minimum 2 pages here, because the info area also may
+ * contain other data (for example HGSMIHOSTFLAGS structure).
+ */
+#ifndef VBOX_XPDM_MINIPORT
+# define VBVA_ADAPTER_INFORMATION_SIZE (64*_1K)
+#else
+#define VBVA_ADAPTER_INFORMATION_SIZE  (16*_1K)
+#define VBVA_DISPLAY_INFORMATION_SIZE  (64*_1K)
+#endif
+#define VBVA_MIN_BUFFER_SIZE           (64*_1K)
+
+
+/* The value for port IO to let the adapter to interpret the adapter memory. */
+#define VBOX_VIDEO_DISABLE_ADAPTER_MEMORY        0xFFFFFFFF
+
+/* The value for port IO to let the adapter to interpret the adapter memory. */
+#define VBOX_VIDEO_INTERPRET_ADAPTER_MEMORY      0x00000000
+
+/* The value for port IO to let the adapter to interpret the display memory.
+ * The display number is encoded in low 16 bits.
+ */
+#define VBOX_VIDEO_INTERPRET_DISPLAY_MEMORY_BASE 0x00010000
+
+
+/* The end of the information. */
+#define VBOX_VIDEO_INFO_TYPE_END          0
+/* Instructs the host to fetch the next VBOXVIDEOINFOHDR at the given offset of VRAM. */
+#define VBOX_VIDEO_INFO_TYPE_LINK         1
+/* Information about a display memory position. */
+#define VBOX_VIDEO_INFO_TYPE_DISPLAY      2
+/* Information about a screen. */
+#define VBOX_VIDEO_INFO_TYPE_SCREEN       3
+/* Information about host notifications for the driver. */
+#define VBOX_VIDEO_INFO_TYPE_HOST_EVENTS  4
+/* Information about non-volatile guest VRAM heap. */
+#define VBOX_VIDEO_INFO_TYPE_NV_HEAP      5
+/* VBVA enable/disable. */
+#define VBOX_VIDEO_INFO_TYPE_VBVA_STATUS  6
+/* VBVA flush. */
+#define VBOX_VIDEO_INFO_TYPE_VBVA_FLUSH   7
+/* Query configuration value. */
+#define VBOX_VIDEO_INFO_TYPE_QUERY_CONF32 8
+
+
+#pragma pack(1)
+typedef struct VBOXVIDEOINFOHDR
+{
+    uint8_t u8Type;
+    uint8_t u8Reserved;
+    uint16_t u16Length;
+} VBOXVIDEOINFOHDR;
+
+
+typedef struct VBOXVIDEOINFOLINK
+{
+    /* Relative offset in VRAM */
+    int32_t i32Offset;
+} VBOXVIDEOINFOLINK;
+
+
+/* Resides in adapter info memory. Describes a display VRAM chunk. */
+typedef struct VBOXVIDEOINFODISPLAY
+{
+    /* Index of the framebuffer assigned by guest. */
+    uint32_t u32Index;
+
+    /* Absolute offset in VRAM of the framebuffer to be displayed on the monitor. */
+    uint32_t u32Offset;
+
+    /* The size of the memory that can be used for the screen. */
+    uint32_t u32FramebufferSize;
+
+    /* The size of the memory that is used for the Display information.
+     * The information is at u32Offset + u32FramebufferSize
+     */
+    uint32_t u32InformationSize;
+
+} VBOXVIDEOINFODISPLAY;
+
+
+/* Resides in display info area, describes the current video mode. */
+#define VBOX_VIDEO_INFO_SCREEN_F_NONE   0x00
+#define VBOX_VIDEO_INFO_SCREEN_F_ACTIVE 0x01
+
+typedef struct VBOXVIDEOINFOSCREEN
+{
+    /* Physical X origin relative to the primary screen. */
+    int32_t xOrigin;
+
+    /* Physical Y origin relative to the primary screen. */
+    int32_t yOrigin;
+
+    /* The scan line size in bytes. */
+    uint32_t u32LineSize;
+
+    /* Width of the screen. */
+    uint16_t u16Width;
+
+    /* Height of the screen. */
+    uint16_t u16Height;
+
+    /* Color depth. */
+    uint8_t bitsPerPixel;
+
+    /* VBOX_VIDEO_INFO_SCREEN_F_* */
+    uint8_t u8Flags;
+} VBOXVIDEOINFOSCREEN;
+
+/* The guest initializes the structure to 0. The positions of the structure in the
+ * display info area must not be changed, host will update the structure. Guest checks
+ * the events and modifies the structure as a response to host.
+ */
+#define VBOX_VIDEO_INFO_HOST_EVENTS_F_NONE        0x00000000
+#define VBOX_VIDEO_INFO_HOST_EVENTS_F_VRDP_RESET  0x00000080
+
+typedef struct VBOXVIDEOINFOHOSTEVENTS
+{
+    /* Host events. */
+    uint32_t fu32Events;
+} VBOXVIDEOINFOHOSTEVENTS;
+
+/* Resides in adapter info memory. Describes the non-volatile VRAM heap. */
+typedef struct VBOXVIDEOINFONVHEAP
+{
+    /* Absolute offset in VRAM of the start of the heap. */
+    uint32_t u32HeapOffset;
+
+    /* The size of the heap. */
+    uint32_t u32HeapSize;
+
+} VBOXVIDEOINFONVHEAP;
+
+/* Display information area. */
+typedef struct VBOXVIDEOINFOVBVASTATUS
+{
+    /* Absolute offset in VRAM of the start of the VBVA QUEUE. 0 to disable VBVA. */
+    uint32_t u32QueueOffset;
+
+    /* The size of the VBVA QUEUE. 0 to disable VBVA. */
+    uint32_t u32QueueSize;
+
+} VBOXVIDEOINFOVBVASTATUS;
+
+typedef struct VBOXVIDEOINFOVBVAFLUSH
+{
+    uint32_t u32DataStart;
+
+    uint32_t u32DataEnd;
+
+} VBOXVIDEOINFOVBVAFLUSH;
+
+#define VBOX_VIDEO_QCI32_MONITOR_COUNT       0
+#define VBOX_VIDEO_QCI32_OFFSCREEN_HEAP_SIZE 1
+
+typedef struct VBOXVIDEOINFOQUERYCONF32
+{
+    uint32_t u32Index;
+
+    uint32_t u32Value;
+
+} VBOXVIDEOINFOQUERYCONF32;
+#pragma pack()
+
+#ifdef VBOX_WITH_VIDEOHWACCEL
+#pragma pack(1)
+
+#define VBOXVHWA_VERSION_MAJ 0
+#define VBOXVHWA_VERSION_MIN 0
+#define VBOXVHWA_VERSION_BLD 6
+#define VBOXVHWA_VERSION_RSV 0
+
+typedef enum
+{
+    VBOXVHWACMD_TYPE_SURF_CANCREATE = 1,
+    VBOXVHWACMD_TYPE_SURF_CREATE,
+    VBOXVHWACMD_TYPE_SURF_DESTROY,
+    VBOXVHWACMD_TYPE_SURF_LOCK,
+    VBOXVHWACMD_TYPE_SURF_UNLOCK,
+    VBOXVHWACMD_TYPE_SURF_BLT,
+    VBOXVHWACMD_TYPE_SURF_FLIP,
+    VBOXVHWACMD_TYPE_SURF_OVERLAY_UPDATE,
+    VBOXVHWACMD_TYPE_SURF_OVERLAY_SETPOSITION,
+    VBOXVHWACMD_TYPE_SURF_COLORKEY_SET,
+    VBOXVHWACMD_TYPE_QUERY_INFO1,
+    VBOXVHWACMD_TYPE_QUERY_INFO2,
+    VBOXVHWACMD_TYPE_ENABLE,
+    VBOXVHWACMD_TYPE_DISABLE,
+    VBOXVHWACMD_TYPE_HH_CONSTRUCT,
+    VBOXVHWACMD_TYPE_HH_RESET
+#ifdef VBOX_WITH_WDDM
+    , VBOXVHWACMD_TYPE_SURF_GETINFO
+    , VBOXVHWACMD_TYPE_SURF_COLORFILL
+#endif
+    , VBOXVHWACMD_TYPE_HH_DISABLE
+    , VBOXVHWACMD_TYPE_HH_ENABLE
+    , VBOXVHWACMD_TYPE_HH_SAVESTATE_SAVEBEGIN
+    , VBOXVHWACMD_TYPE_HH_SAVESTATE_SAVEEND
+    , VBOXVHWACMD_TYPE_HH_SAVESTATE_SAVEPERFORM
+    , VBOXVHWACMD_TYPE_HH_SAVESTATE_LOADPERFORM
+} VBOXVHWACMD_TYPE;
+
+/* the command processing was asynch, set by the host to indicate asynch command completion
+ * must not be cleared once set, the command completion is performed by issuing a host->guest completion command
+ * while keeping this flag unchanged */
+#define VBOXVHWACMD_FLAG_HG_ASYNCH               0x00010000
+/* asynch completion is performed by issuing the event */
+#define VBOXVHWACMD_FLAG_GH_ASYNCH_EVENT         0x00000001
+/* issue interrupt on asynch completion */
+#define VBOXVHWACMD_FLAG_GH_ASYNCH_IRQ           0x00000002
+/* guest does not do any op on completion of this command, the host may copy the command and indicate that it does not need the command anymore
+ * by setting the VBOXVHWACMD_FLAG_HG_ASYNCH_RETURNED flag */
+#define VBOXVHWACMD_FLAG_GH_ASYNCH_NOCOMPLETION  0x00000004
+/* the host has copied the VBOXVHWACMD_FLAG_GH_ASYNCH_NOCOMPLETION command and returned it to the guest */
+#define VBOXVHWACMD_FLAG_HG_ASYNCH_RETURNED      0x00020000
+/* this is the host->host cmd, i.e. a configuration command posted by the host to the framebuffer */
+#define VBOXVHWACMD_FLAG_HH_CMD                  0x10000000
+
+typedef struct VBOXVHWACMD
+{
+    VBOXVHWACMD_TYPE enmCmd; /* command type */
+    volatile int32_t rc; /* command result */
+    int32_t iDisplay; /* display index */
+    volatile int32_t Flags; /* ored VBOXVHWACMD_FLAG_xxx values */
+    uint64_t GuestVBVAReserved1; /* field internally used by the guest VBVA cmd handling, must NOT be modified by clients */
+    uint64_t GuestVBVAReserved2; /* field internally used by the guest VBVA cmd handling, must NOT be modified by clients */
+    volatile uint32_t cRefs;
+    int32_t Reserved;
+    union
+    {
+        struct VBOXVHWACMD *pNext;
+        uint32_t             offNext;
+        uint64_t Data; /* the body is 64-bit aligned */
+    } u;
+    char body[1];
+} VBOXVHWACMD;
+
+#define VBOXVHWACMD_HEADSIZE() (RT_OFFSETOF(VBOXVHWACMD, body))
+#define VBOXVHWACMD_SIZE_FROMBODYSIZE(_s) (VBOXVHWACMD_HEADSIZE() + (_s))
+#define VBOXVHWACMD_SIZE(_tCmd) (VBOXVHWACMD_SIZE_FROMBODYSIZE(sizeof(_tCmd)))
+typedef unsigned int VBOXVHWACMD_LENGTH;
+typedef uint64_t VBOXVHWA_SURFHANDLE;
+#define VBOXVHWA_SURFHANDLE_INVALID 0ULL
+#define VBOXVHWACMD_BODY(_p, _t) ((_t*)(_p)->body)
+#define VBOXVHWACMD_HEAD(_pb) ((VBOXVHWACMD*)((uint8_t *)(_pb) - RT_OFFSETOF(VBOXVHWACMD, body)))
+
+typedef struct VBOXVHWA_RECTL
+{
+    int32_t left;
+    int32_t top;
+    int32_t right;
+    int32_t bottom;
+} VBOXVHWA_RECTL;
+
+typedef struct VBOXVHWA_COLORKEY
+{
+    uint32_t low;
+    uint32_t high;
+} VBOXVHWA_COLORKEY;
+
+typedef struct VBOXVHWA_PIXELFORMAT
+{
+    uint32_t flags;
+    uint32_t fourCC;
+    union
+    {
+        uint32_t rgbBitCount;
+        uint32_t yuvBitCount;
+    } c;
+
+    union
+    {
+        uint32_t rgbRBitMask;
+        uint32_t yuvYBitMask;
+    } m1;
+
+    union
+    {
+        uint32_t rgbGBitMask;
+        uint32_t yuvUBitMask;
+    } m2;
+
+    union
+    {
+        uint32_t rgbBBitMask;
+        uint32_t yuvVBitMask;
+    } m3;
+
+    union
+    {
+        uint32_t rgbABitMask;
+    } m4;
+
+    uint32_t Reserved;
+} VBOXVHWA_PIXELFORMAT;
+
+typedef struct VBOXVHWA_SURFACEDESC
+{
+    uint32_t flags;
+    uint32_t height;
+    uint32_t width;
+    uint32_t pitch;
+    uint32_t sizeX;
+    uint32_t sizeY;
+    uint32_t cBackBuffers;
+    uint32_t Reserved;
+    VBOXVHWA_COLORKEY DstOverlayCK;
+    VBOXVHWA_COLORKEY DstBltCK;
+    VBOXVHWA_COLORKEY SrcOverlayCK;
+    VBOXVHWA_COLORKEY SrcBltCK;
+    VBOXVHWA_PIXELFORMAT PixelFormat;
+    uint32_t surfCaps;
+    uint32_t Reserved2;
+    VBOXVHWA_SURFHANDLE hSurf;
+    uint64_t offSurface;
+} VBOXVHWA_SURFACEDESC;
+
+typedef struct VBOXVHWA_BLTFX
+{
+    uint32_t flags;
+    uint32_t rop;
+    uint32_t rotationOp;
+    uint32_t rotation;
+    uint32_t fillColor;
+    uint32_t Reserved;
+    VBOXVHWA_COLORKEY DstCK;
+    VBOXVHWA_COLORKEY SrcCK;
+} VBOXVHWA_BLTFX;
+
+typedef struct VBOXVHWA_OVERLAYFX
+{
+    uint32_t flags;
+    uint32_t Reserved1;
+    uint32_t fxFlags;
+    uint32_t Reserved2;
+    VBOXVHWA_COLORKEY DstCK;
+    VBOXVHWA_COLORKEY SrcCK;
+} VBOXVHWA_OVERLAYFX;
+
+#define VBOXVHWA_CAPS_BLT               0x00000040
+#define VBOXVHWA_CAPS_BLTCOLORFILL      0x04000000
+#define VBOXVHWA_CAPS_BLTFOURCC         0x00000100
+#define VBOXVHWA_CAPS_BLTSTRETCH        0x00000200
+#define VBOXVHWA_CAPS_BLTQUEUE          0x00000080
+
+#define VBOXVHWA_CAPS_OVERLAY           0x00000800
+#define VBOXVHWA_CAPS_OVERLAYFOURCC     0x00002000
+#define VBOXVHWA_CAPS_OVERLAYSTRETCH    0x00004000
+#define VBOXVHWA_CAPS_OVERLAYCANTCLIP   0x00001000
+
+#define VBOXVHWA_CAPS_COLORKEY          0x00400000
+#define VBOXVHWA_CAPS_COLORKEYHWASSIST  0x01000000
+
+#define VBOXVHWA_SCAPS_BACKBUFFER       0x00000004
+#define VBOXVHWA_SCAPS_COMPLEX          0x00000008
+#define VBOXVHWA_SCAPS_FLIP             0x00000010
+#define VBOXVHWA_SCAPS_FRONTBUFFER      0x00000020
+#define VBOXVHWA_SCAPS_OFFSCREENPLAIN   0x00000040
+#define VBOXVHWA_SCAPS_OVERLAY          0x00000080
+#define VBOXVHWA_SCAPS_PRIMARYSURFACE   0x00000200
+#define VBOXVHWA_SCAPS_SYSTEMMEMORY     0x00000800
+#define VBOXVHWA_SCAPS_VIDEOMEMORY      0x00004000
+#define VBOXVHWA_SCAPS_VISIBLE          0x00008000
+#define VBOXVHWA_SCAPS_LOCALVIDMEM      0x10000000
+
+#define VBOXVHWA_PF_PALETTEINDEXED8     0x00000020
+#define VBOXVHWA_PF_RGB                 0x00000040
+#define VBOXVHWA_PF_RGBTOYUV            0x00000100
+#define VBOXVHWA_PF_YUV                 0x00000200
+#define VBOXVHWA_PF_FOURCC              0x00000004
+
+#define VBOXVHWA_LOCK_DISCARDCONTENTS   0x00002000
+
+#define VBOXVHWA_CFG_ENABLED            0x00000001
+
+#define VBOXVHWA_SD_BACKBUFFERCOUNT     0x00000020
+#define VBOXVHWA_SD_CAPS                0x00000001
+#define VBOXVHWA_SD_CKDESTBLT           0x00004000
+#define VBOXVHWA_SD_CKDESTOVERLAY       0x00002000
+#define VBOXVHWA_SD_CKSRCBLT            0x00010000
+#define VBOXVHWA_SD_CKSRCOVERLAY        0x00008000
+#define VBOXVHWA_SD_HEIGHT              0x00000002
+#define VBOXVHWA_SD_PITCH               0x00000008
+#define VBOXVHWA_SD_PIXELFORMAT         0x00001000
+/*#define VBOXVHWA_SD_REFRESHRATE       0x00040000*/
+#define VBOXVHWA_SD_WIDTH               0x00000004
+
+#define VBOXVHWA_CKEYCAPS_DESTBLT                  0x00000001
+#define VBOXVHWA_CKEYCAPS_DESTBLTCLRSPACE          0x00000002
+#define VBOXVHWA_CKEYCAPS_DESTBLTCLRSPACEYUV       0x00000004
+#define VBOXVHWA_CKEYCAPS_DESTBLTYUV               0x00000008
+#define VBOXVHWA_CKEYCAPS_DESTOVERLAY              0x00000010
+#define VBOXVHWA_CKEYCAPS_DESTOVERLAYCLRSPACE      0x00000020
+#define VBOXVHWA_CKEYCAPS_DESTOVERLAYCLRSPACEYUV   0x00000040
+#define VBOXVHWA_CKEYCAPS_DESTOVERLAYONEACTIVE     0x00000080
+#define VBOXVHWA_CKEYCAPS_DESTOVERLAYYUV           0x00000100
+#define VBOXVHWA_CKEYCAPS_SRCBLT                   0x00000200
+#define VBOXVHWA_CKEYCAPS_SRCBLTCLRSPACE           0x00000400
+#define VBOXVHWA_CKEYCAPS_SRCBLTCLRSPACEYUV        0x00000800
+#define VBOXVHWA_CKEYCAPS_SRCBLTYUV                0x00001000
+#define VBOXVHWA_CKEYCAPS_SRCOVERLAY               0x00002000
+#define VBOXVHWA_CKEYCAPS_SRCOVERLAYCLRSPACE       0x00004000
+#define VBOXVHWA_CKEYCAPS_SRCOVERLAYCLRSPACEYUV    0x00008000
+#define VBOXVHWA_CKEYCAPS_SRCOVERLAYONEACTIVE      0x00010000
+#define VBOXVHWA_CKEYCAPS_SRCOVERLAYYUV            0x00020000
+#define VBOXVHWA_CKEYCAPS_NOCOSTOVERLAY            0x00040000
+
+#define VBOXVHWA_BLT_COLORFILL                      0x00000400
+#define VBOXVHWA_BLT_DDFX                           0x00000800
+#define VBOXVHWA_BLT_EXTENDED_FLAGS                 0x40000000
+#define VBOXVHWA_BLT_EXTENDED_LINEAR_CONTENT        0x00000004
+#define VBOXVHWA_BLT_EXTENDED_PRESENTATION_STRETCHFACTOR 0x00000010
+#define VBOXVHWA_BLT_KEYDESTOVERRIDE                0x00004000
+#define VBOXVHWA_BLT_KEYSRCOVERRIDE                 0x00010000
+#define VBOXVHWA_BLT_LAST_PRESENTATION              0x20000000
+#define VBOXVHWA_BLT_PRESENTATION                   0x10000000
+#define VBOXVHWA_BLT_ROP                            0x00020000
+
+
+#define VBOXVHWA_OVER_DDFX                          0x00080000
+#define VBOXVHWA_OVER_HIDE                          0x00000200
+#define VBOXVHWA_OVER_KEYDEST                       0x00000400
+#define VBOXVHWA_OVER_KEYDESTOVERRIDE               0x00000800
+#define VBOXVHWA_OVER_KEYSRC                        0x00001000
+#define VBOXVHWA_OVER_KEYSRCOVERRIDE                0x00002000
+#define VBOXVHWA_OVER_SHOW                          0x00004000
+
+#define VBOXVHWA_CKEY_COLORSPACE                    0x00000001
+#define VBOXVHWA_CKEY_DESTBLT                       0x00000002
+#define VBOXVHWA_CKEY_DESTOVERLAY                   0x00000004
+#define VBOXVHWA_CKEY_SRCBLT                        0x00000008
+#define VBOXVHWA_CKEY_SRCOVERLAY                    0x00000010
+
+#define VBOXVHWA_BLT_ARITHSTRETCHY                  0x00000001
+#define VBOXVHWA_BLT_MIRRORLEFTRIGHT                0x00000002
+#define VBOXVHWA_BLT_MIRRORUPDOWN                   0x00000004
+
+#define VBOXVHWA_OVERFX_ARITHSTRETCHY               0x00000001
+#define VBOXVHWA_OVERFX_MIRRORLEFTRIGHT             0x00000002
+#define VBOXVHWA_OVERFX_MIRRORUPDOWN                0x00000004
+
+#define VBOXVHWA_CAPS2_CANRENDERWINDOWED            0x00080000
+#define VBOXVHWA_CAPS2_WIDESURFACES                 0x00001000
+#define VBOXVHWA_CAPS2_COPYFOURCC                   0x00008000
+/*#define VBOXVHWA_CAPS2_FLIPINTERVAL                 0x00200000*/
+/*#define VBOXVHWA_CAPS2_FLIPNOVSYNC                  0x00400000*/
+
+
+#define VBOXVHWA_OFFSET64_VOID        (UINT64_MAX)
+
+typedef struct VBOXVHWA_VERSION
+{
+    uint32_t maj;
+    uint32_t min;
+    uint32_t bld;
+    uint32_t reserved;
+} VBOXVHWA_VERSION;
+
+#define VBOXVHWA_VERSION_INIT(_pv) do { \
+        (_pv)->maj = VBOXVHWA_VERSION_MAJ; \
+        (_pv)->min = VBOXVHWA_VERSION_MIN; \
+        (_pv)->bld = VBOXVHWA_VERSION_BLD; \
+        (_pv)->reserved = VBOXVHWA_VERSION_RSV; \
+        } while(0)
+
+typedef struct VBOXVHWACMD_QUERYINFO1
+{
+    union
+    {
+        struct
+        {
+            VBOXVHWA_VERSION guestVersion;
+        } in;
+
+        struct
+        {
+            uint32_t cfgFlags;
+            uint32_t caps;
+
+            uint32_t caps2;
+            uint32_t colorKeyCaps;
+
+            uint32_t stretchCaps;
+            uint32_t surfaceCaps;
+
+            uint32_t numOverlays;
+            uint32_t curOverlays;
+
+            uint32_t numFourCC;
+            uint32_t reserved;
+        } out;
+    } u;
+} VBOXVHWACMD_QUERYINFO1;
+
+typedef struct VBOXVHWACMD_QUERYINFO2
+{
+    uint32_t numFourCC;
+    uint32_t FourCC[1];
+} VBOXVHWACMD_QUERYINFO2;
+
+#define VBOXVHWAINFO2_SIZE(_cFourCC) RT_OFFSETOF(VBOXVHWACMD_QUERYINFO2, FourCC[_cFourCC])
+
+typedef struct VBOXVHWACMD_SURF_CANCREATE
+{
+    VBOXVHWA_SURFACEDESC SurfInfo;
+    union
+    {
+        struct
+        {
+            uint32_t bIsDifferentPixelFormat;
+            uint32_t Reserved;
+        } in;
+
+        struct
+        {
+            int32_t ErrInfo;
+        } out;
+    } u;
+} VBOXVHWACMD_SURF_CANCREATE;
+
+typedef struct VBOXVHWACMD_SURF_CREATE
+{
+    VBOXVHWA_SURFACEDESC SurfInfo;
+} VBOXVHWACMD_SURF_CREATE;
+
+#ifdef VBOX_WITH_WDDM
+typedef struct VBOXVHWACMD_SURF_GETINFO
+{
+    VBOXVHWA_SURFACEDESC SurfInfo;
+} VBOXVHWACMD_SURF_GETINFO;
+#endif
+
+typedef struct VBOXVHWACMD_SURF_DESTROY
+{
+    union
+    {
+        struct
+        {
+            VBOXVHWA_SURFHANDLE hSurf;
+        } in;
+    } u;
+} VBOXVHWACMD_SURF_DESTROY;
+
+typedef struct VBOXVHWACMD_SURF_LOCK
+{
+    union
+    {
+        struct
+        {
+            VBOXVHWA_SURFHANDLE hSurf;
+            uint64_t offSurface;
+            uint32_t flags;
+            uint32_t rectValid;
+            VBOXVHWA_RECTL rect;
+        } in;
+    } u;
+} VBOXVHWACMD_SURF_LOCK;
+
+typedef struct VBOXVHWACMD_SURF_UNLOCK
+{
+    union
+    {
+        struct
+        {
+            VBOXVHWA_SURFHANDLE hSurf;
+            uint32_t xUpdatedMemValid;
+            uint32_t reserved;
+            VBOXVHWA_RECTL xUpdatedMemRect;
+        } in;
+    } u;
+} VBOXVHWACMD_SURF_UNLOCK;
+
+typedef struct VBOXVHWACMD_SURF_BLT
+{
+    uint64_t DstGuestSurfInfo;
+    uint64_t SrcGuestSurfInfo;
+    union
+    {
+        struct
+        {
+            VBOXVHWA_SURFHANDLE hDstSurf;
+            uint64_t offDstSurface;
+            VBOXVHWA_RECTL dstRect;
+            VBOXVHWA_SURFHANDLE hSrcSurf;
+            uint64_t offSrcSurface;
+            VBOXVHWA_RECTL srcRect;
+            uint32_t flags;
+            uint32_t xUpdatedSrcMemValid;
+            VBOXVHWA_BLTFX desc;
+            VBOXVHWA_RECTL xUpdatedSrcMemRect;
+        } in;
+    } u;
+} VBOXVHWACMD_SURF_BLT;
+
+#ifdef VBOX_WITH_WDDM
+typedef struct VBOXVHWACMD_SURF_COLORFILL
+{
+    union
+    {
+        struct
+        {
+            VBOXVHWA_SURFHANDLE hSurf;
+            uint64_t offSurface;
+            uint32_t u32Reserved;
+            uint32_t cRects;
+            VBOXVHWA_RECTL aRects[1];
+        } in;
+    } u;
+} VBOXVHWACMD_SURF_COLORFILL;
+#endif
+
+typedef struct VBOXVHWACMD_SURF_FLIP
+{
+    uint64_t TargGuestSurfInfo;
+    uint64_t CurrGuestSurfInfo;
+    union
+    {
+        struct
+        {
+            VBOXVHWA_SURFHANDLE hTargSurf;
+            uint64_t offTargSurface;
+            VBOXVHWA_SURFHANDLE hCurrSurf;
+            uint64_t offCurrSurface;
+            uint32_t flags;
+            uint32_t xUpdatedTargMemValid;
+            VBOXVHWA_RECTL xUpdatedTargMemRect;
+        } in;
+    } u;
+} VBOXVHWACMD_SURF_FLIP;
+
+typedef struct VBOXVHWACMD_SURF_COLORKEY_SET
+{
+    union
+    {
+        struct
+        {
+            VBOXVHWA_SURFHANDLE hSurf;
+            uint64_t offSurface;
+            VBOXVHWA_COLORKEY CKey;
+            uint32_t flags;
+            uint32_t reserved;
+        } in;
+    } u;
+} VBOXVHWACMD_SURF_COLORKEY_SET;
+
+#define VBOXVHWACMD_SURF_OVERLAY_UPDATE_F_SRCMEMRECT 0x00000001
+#define VBOXVHWACMD_SURF_OVERLAY_UPDATE_F_DSTMEMRECT 0x00000002
+
+typedef struct VBOXVHWACMD_SURF_OVERLAY_UPDATE
+{
+    union
+    {
+        struct
+        {
+            VBOXVHWA_SURFHANDLE hDstSurf;
+            uint64_t offDstSurface;
+            VBOXVHWA_RECTL dstRect;
+            VBOXVHWA_SURFHANDLE hSrcSurf;
+            uint64_t offSrcSurface;
+            VBOXVHWA_RECTL srcRect;
+            uint32_t flags;
+            uint32_t xFlags;
+            VBOXVHWA_OVERLAYFX desc;
+            VBOXVHWA_RECTL xUpdatedSrcMemRect;
+            VBOXVHWA_RECTL xUpdatedDstMemRect;
+        } in;
+    } u;
+}VBOXVHWACMD_SURF_OVERLAY_UPDATE;
+
+typedef struct VBOXVHWACMD_SURF_OVERLAY_SETPOSITION
+{
+    union
+    {
+        struct
+        {
+            VBOXVHWA_SURFHANDLE hDstSurf;
+            uint64_t offDstSurface;
+            VBOXVHWA_SURFHANDLE hSrcSurf;
+            uint64_t offSrcSurface;
+            uint32_t xPos;
+            uint32_t yPos;
+            uint32_t flags;
+            uint32_t reserved;
+        } in;
+    } u;
+} VBOXVHWACMD_SURF_OVERLAY_SETPOSITION;
+
+typedef struct VBOXVHWACMD_HH_CONSTRUCT
+{
+    void    *pVM;
+    /* VRAM info for the backend to be able to properly translate VRAM offsets */
+    void    *pvVRAM;
+    uint32_t cbVRAM;
+} VBOXVHWACMD_HH_CONSTRUCT;
+
+typedef struct VBOXVHWACMD_HH_SAVESTATE_SAVEPERFORM
+{
+    struct SSMHANDLE * pSSM;
+} VBOXVHWACMD_HH_SAVESTATE_SAVEPERFORM;
+
+typedef struct VBOXVHWACMD_HH_SAVESTATE_LOADPERFORM
+{
+    struct SSMHANDLE * pSSM;
+} VBOXVHWACMD_HH_SAVESTATE_LOADPERFORM;
+
+typedef DECLCALLBACK(void) FNVBOXVHWA_HH_CALLBACK(void*);
+typedef FNVBOXVHWA_HH_CALLBACK *PFNVBOXVHWA_HH_CALLBACK;
+
+#define VBOXVHWA_HH_CALLBACK_SET(_pCmd, _pfn, _parg) \
+    do { \
+        (_pCmd)->GuestVBVAReserved1 = (uint64_t)(uintptr_t)(_pfn); \
+        (_pCmd)->GuestVBVAReserved2 = (uint64_t)(uintptr_t)(_parg); \
+    }while(0)
+
+#define VBOXVHWA_HH_CALLBACK_GET(_pCmd) ((PFNVBOXVHWA_HH_CALLBACK)(_pCmd)->GuestVBVAReserved1)
+#define VBOXVHWA_HH_CALLBACK_GET_ARG(_pCmd) ((void*)(_pCmd)->GuestVBVAReserved2)
+
+#pragma pack()
+#endif /* #ifdef VBOX_WITH_VIDEOHWACCEL */
+
+/* All structures are without alignment. */
+#pragma pack(1)
+
+typedef struct VBVAHOSTFLAGS
+{
+    uint32_t u32HostEvents;
+    uint32_t u32SupportedOrders;
+} VBVAHOSTFLAGS;
+
+typedef struct VBVABUFFER
+{
+    VBVAHOSTFLAGS hostFlags;
+
+    /* The offset where the data start in the buffer. */
+    uint32_t off32Data;
+    /* The offset where next data must be placed in the buffer. */
+    uint32_t off32Free;
+
+    /* The queue of record descriptions. */
+    VBVARECORD aRecords[VBVA_MAX_RECORDS];
+    uint32_t indexRecordFirst;
+    uint32_t indexRecordFree;
+
+    /* Space to leave free in the buffer when large partial records are transferred. */
+    uint32_t cbPartialWriteThreshold;
+
+    uint32_t cbData;
+    uint8_t  au8Data[1]; /* variable size for the rest of the VBVABUFFER area in VRAM. */
+} VBVABUFFER;
+
+#define VBVA_MAX_RECORD_SIZE (128*_1M)
+
+/* guest->host commands */
+#define VBVA_QUERY_CONF32 1
+#define VBVA_SET_CONF32   2
+#define VBVA_INFO_VIEW    3
+#define VBVA_INFO_HEAP    4
+#define VBVA_FLUSH        5
+#define VBVA_INFO_SCREEN  6
+#define VBVA_ENABLE       7
+#define VBVA_MOUSE_POINTER_SHAPE 8
+#ifdef VBOX_WITH_VIDEOHWACCEL
+# define VBVA_VHWA_CMD    9
+#endif /* # ifdef VBOX_WITH_VIDEOHWACCEL */
+#ifdef VBOX_WITH_VDMA
+# define VBVA_VDMA_CTL   10 /* setup G<->H DMA channel info */
+# define VBVA_VDMA_CMD    11 /* G->H DMA command             */
+#endif
+#define VBVA_INFO_CAPS   12 /* informs host about HGSMI caps. see VBVACAPS below */
+#define VBVA_SCANLINE_CFG    13 /* configures scanline, see VBVASCANLINECFG below */
+#define VBVA_SCANLINE_INFO   14 /* requests scanline info, see VBVASCANLINEINFO below */
+#define VBVA_CMDVBVA_SUBMIT  16 /* inform host about VBVA Command submission */
+#define VBVA_CMDVBVA_FLUSH   17 /* inform host about VBVA Command submission */
+#define VBVA_CMDVBVA_CTL     18 /* G->H DMA command             */
+#define VBVA_QUERY_MODE_HINTS 19 /* Query most recent mode hints sent. */
+/** Report the guest virtual desktop position and size for mapping host and
+ * guest pointer positions. */
+#define VBVA_REPORT_INPUT_MAPPING 20
+/** Report the guest cursor position and query the host position. */
+#define VBVA_CURSOR_POSITION 21
+
+/* host->guest commands */
+#define VBVAHG_EVENT              1
+#define VBVAHG_DISPLAY_CUSTOM     2
+#ifdef VBOX_WITH_VDMA
+#define VBVAHG_SHGSMI_COMPLETION  3
+#endif
+
+#ifdef VBOX_WITH_VIDEOHWACCEL
+#define VBVAHG_DCUSTOM_VHWA_CMDCOMPLETE 1
+#pragma pack(1)
+typedef struct VBVAHOSTCMDVHWACMDCOMPLETE
+{
+    uint32_t offCmd;
+}VBVAHOSTCMDVHWACMDCOMPLETE;
+#pragma pack()
+#endif /* # ifdef VBOX_WITH_VIDEOHWACCEL */
+
+#pragma pack(1)
+typedef enum
+{
+    VBVAHOSTCMD_OP_EVENT = 1,
+    VBVAHOSTCMD_OP_CUSTOM
+}VBVAHOSTCMD_OP_TYPE;
+
+typedef struct VBVAHOSTCMDEVENT
+{
+    uint64_t pEvent;
+}VBVAHOSTCMDEVENT;
+
+
+typedef struct VBVAHOSTCMD
+{
+    /* destination ID if >=0 specifies display index, otherwize the command is directed to the miniport */
+    int32_t iDstID;
+    int32_t customOpCode;
+    union
+    {
+        struct VBVAHOSTCMD *pNext;
+        uint32_t             offNext;
+        uint64_t Data; /* the body is 64-bit aligned */
+    } u;
+    char body[1];
+}VBVAHOSTCMD;
+
+#define VBVAHOSTCMD_SIZE(_size) (sizeof(VBVAHOSTCMD) + (_size))
+#define VBVAHOSTCMD_BODY(_pCmd, _tBody) ((_tBody*)(_pCmd)->body)
+#define VBVAHOSTCMD_HDR(_pBody) ((VBVAHOSTCMD*)(((uint8_t*)_pBody) - RT_OFFSETOF(VBVAHOSTCMD, body)))
+#define VBVAHOSTCMD_HDRSIZE (RT_OFFSETOF(VBVAHOSTCMD, body))
+
+#pragma pack()
+
+/* VBVACONF32::u32Index */
+#define VBOX_VBVA_CONF32_MONITOR_COUNT  0
+#define VBOX_VBVA_CONF32_HOST_HEAP_SIZE 1
+/** Returns VINF_SUCCESS if the host can report mode hints via VBVA.
+ * Set value to VERR_NOT_SUPPORTED before calling. */
+#define VBOX_VBVA_CONF32_MODE_HINT_REPORTING  2
+/** Returns VINF_SUCCESS if the host can receive guest cursor information via
+ * VBVA.  Set value to VERR_NOT_SUPPORTED before calling. */
+#define VBOX_VBVA_CONF32_GUEST_CURSOR_REPORTING  3
+/** Returns the currently available host cursor capabilities.  Available if
+ * VBVACONF32::VBOX_VBVA_CONF32_GUEST_CURSOR_REPORTING returns success.
+ * @see VMMDevReqMouseStatus::mouseFeatures. */
+#define VBOX_VBVA_CONF32_CURSOR_CAPABILITIES  4
+/** Returns the supported flags in VBVAINFOSCREEN::u8Flags. */
+#define VBOX_VBVA_CONF32_SCREEN_FLAGS 5
+/** Returns the max size of VBVA record. */
+#define VBOX_VBVA_CONF32_MAX_RECORD_SIZE 6
+
+typedef struct VBVACONF32
+{
+    uint32_t u32Index;
+    uint32_t u32Value;
+} VBVACONF32;
+
+typedef struct VBVAINFOVIEW
+{
+    /* Index of the screen, assigned by the guest. */
+    uint32_t u32ViewIndex;
+
+    /* The screen offset in VRAM, the framebuffer starts here. */
+    uint32_t u32ViewOffset;
+
+    /* The size of the VRAM memory that can be used for the view. */
+    uint32_t u32ViewSize;
+
+    /* The recommended maximum size of the VRAM memory for the screen. */
+    uint32_t u32MaxScreenSize;
+} VBVAINFOVIEW;
+
+typedef struct VBVAINFOHEAP
+{
+    /* Absolute offset in VRAM of the start of the heap. */
+    uint32_t u32HeapOffset;
+
+    /* The size of the heap. */
+    uint32_t u32HeapSize;
+
+} VBVAINFOHEAP;
+
+typedef struct VBVAFLUSH
+{
+    uint32_t u32Reserved;
+
+} VBVAFLUSH;
+
+typedef struct VBVACMDVBVASUBMIT
+{
+    uint32_t u32Reserved;
+} VBVACMDVBVASUBMIT;
+
+/* flush is requested because due to guest command buffer overflow */
+#define VBVACMDVBVAFLUSH_F_GUEST_BUFFER_OVERFLOW 1
+
+typedef struct VBVACMDVBVAFLUSH
+{
+    uint32_t u32Flags;
+} VBVACMDVBVAFLUSH;
+
+
+/* VBVAINFOSCREEN::u8Flags */
+#define VBVA_SCREEN_F_NONE     0x0000
+#define VBVA_SCREEN_F_ACTIVE   0x0001
+/** The virtual monitor has been disabled by the guest and should be removed
+ * by the host and ignored for purposes of pointer position calculation. */
+#define VBVA_SCREEN_F_DISABLED 0x0002
+/** The virtual monitor has been blanked by the guest and should be blacked
+ * out by the host. */
+#define VBVA_SCREEN_F_BLANK    0x0004
+
+typedef struct VBVAINFOSCREEN
+{
+    /* Which view contains the screen. */
+    uint32_t u32ViewIndex;
+
+    /* Physical X origin relative to the primary screen. */
+    int32_t i32OriginX;
+
+    /* Physical Y origin relative to the primary screen. */
+    int32_t i32OriginY;
+
+    /* Offset of visible framebuffer relative to the framebuffer start. */
+    uint32_t u32StartOffset;
+
+    /* The scan line size in bytes. */
+    uint32_t u32LineSize;
+
+    /* Width of the screen. */
+    uint32_t u32Width;
+
+    /* Height of the screen. */
+    uint32_t u32Height;
+
+    /* Color depth. */
+    uint16_t u16BitsPerPixel;
+
+    /* VBVA_SCREEN_F_* */
+    uint16_t u16Flags;
+} VBVAINFOSCREEN;
+
+
+/* VBVAENABLE::u32Flags */
+#define VBVA_F_NONE    0x00000000
+#define VBVA_F_ENABLE  0x00000001
+#define VBVA_F_DISABLE 0x00000002
+/* extended VBVA to be used with WDDM */
+#define VBVA_F_EXTENDED 0x00000004
+/* vbva offset is absolute VRAM offset */
+#define VBVA_F_ABSOFFSET 0x00000008
+
+typedef struct VBVAENABLE
+{
+    uint32_t u32Flags;
+    uint32_t u32Offset;
+    int32_t  i32Result;
+} VBVAENABLE;
+
+typedef struct VBVAENABLE_EX
+{
+    VBVAENABLE Base;
+    uint32_t u32ScreenId;
+} VBVAENABLE_EX;
+
+
+typedef struct VBVAMOUSEPOINTERSHAPE
+{
+    /* The host result. */
+    int32_t i32Result;
+
+    /* VBOX_MOUSE_POINTER_* bit flags. */
+    uint32_t fu32Flags;
+
+    /* X coordinate of the hot spot. */
+    uint32_t u32HotX;
+
+    /* Y coordinate of the hot spot. */
+    uint32_t u32HotY;
+
+    /* Width of the pointer in pixels. */
+    uint32_t u32Width;
+
+    /* Height of the pointer in scanlines. */
+    uint32_t u32Height;
+
+    /* Pointer data.
+     *
+     ****
+     * The data consists of 1 bpp AND mask followed by 32 bpp XOR (color) mask.
+     *
+     * For pointers without alpha channel the XOR mask pixels are 32 bit values: (lsb)BGR0(msb).
+     * For pointers with alpha channel the XOR mask consists of (lsb)BGRA(msb) 32 bit values.
+     *
+     * Guest driver must create the AND mask for pointers with alpha channel, so if host does not
+     * support alpha, the pointer could be displayed as a normal color pointer. The AND mask can
+     * be constructed from alpha values. For example alpha value >= 0xf0 means bit 0 in the AND mask.
+     *
+     * The AND mask is 1 bpp bitmap with byte aligned scanlines. Size of AND mask,
+     * therefore, is cbAnd = (width + 7) / 8 * height. The padding bits at the
+     * end of any scanline are undefined.
+     *
+     * The XOR mask follows the AND mask on the next 4 bytes aligned offset:
+     * uint8_t *pXor = pAnd + (cbAnd + 3) & ~3
+     * Bytes in the gap between the AND and the XOR mask are undefined.
+     * XOR mask scanlines have no gap between them and size of XOR mask is:
+     * cXor = width * 4 * height.
+     ****
+     *
+     * Preallocate 4 bytes for accessing actual data as p->au8Data.
+     */
+    uint8_t au8Data[4];
+
+} VBVAMOUSEPOINTERSHAPE;
+
+/* the guest driver can handle asynch guest cmd completion by reading the command offset from io port */
+#define VBVACAPS_COMPLETEGCMD_BY_IOREAD 0x00000001
+/* the guest driver can handle video adapter IRQs */
+#define VBVACAPS_IRQ                    0x00000002
+/** The guest can read video mode hints sent via VBVA. */
+#define VBVACAPS_VIDEO_MODE_HINTS       0x00000004
+/** The guest can switch to a software cursor on demand. */
+#define VBVACAPS_DISABLE_CURSOR_INTEGRATION 0x00000008
+/** The guest does not depend on host handling the VBE registers. */
+#define VBVACAPS_USE_VBVA_ONLY 0x00000010
+typedef struct VBVACAPS
+{
+    int32_t rc;
+    uint32_t fCaps;
+} VBVACAPS;
+
+/* makes graphics device generate IRQ on VSYNC */
+#define VBVASCANLINECFG_ENABLE_VSYNC_IRQ        0x00000001
+/* guest driver may request the current scanline */
+#define VBVASCANLINECFG_ENABLE_SCANLINE_INFO    0x00000002
+/* request the current refresh period, returned in u32RefreshPeriodMs */
+#define VBVASCANLINECFG_QUERY_REFRESH_PERIOD    0x00000004
+/* set new refresh period specified in u32RefreshPeriodMs.
+ * if used with VBVASCANLINECFG_QUERY_REFRESH_PERIOD,
+ * u32RefreshPeriodMs is set to the previous refresh period on return */
+#define VBVASCANLINECFG_SET_REFRESH_PERIOD      0x00000008
+
+typedef struct VBVASCANLINECFG
+{
+    int32_t rc;
+    uint32_t fFlags;
+    uint32_t u32RefreshPeriodMs;
+    uint32_t u32Reserved;
+} VBVASCANLINECFG;
+
+typedef struct VBVASCANLINEINFO
+{
+    int32_t rc;
+    uint32_t u32ScreenId;
+    uint32_t u32InVBlank;
+    uint32_t u32ScanLine;
+} VBVASCANLINEINFO;
+
+/** Query the most recent mode hints received from the host. */
+typedef struct VBVAQUERYMODEHINTS
+{
+    /** The maximum number of screens to return hints for. */
+    uint16_t cHintsQueried;
+    /** The size of the mode hint structures directly following this one. */
+    uint16_t cbHintStructureGuest;
+    /** The return code for the operation.  Initialise to VERR_NOT_SUPPORTED. */
+    int32_t  rc;
+} VBVAQUERYMODEHINTS;
+
+/** Structure in which a mode hint is returned.  The guest allocates an array
+ *  of these immediately after the VBVAQUERYMODEHINTS structure.  To accomodate
+ *  future extensions, the VBVAQUERYMODEHINTS structure specifies the size of
+ *  the VBVAMODEHINT structures allocated by the guest, and the host only fills
+ *  out structure elements which fit into that size.  The host should fill any
+ *  unused members (e.g. dx, dy) or structure space on the end with ~0.  The
+ *  whole structure can legally be set to ~0 to skip a screen. */
+typedef struct VBVAMODEHINT
+{
+    uint32_t magic;
+    uint32_t cx;
+    uint32_t cy;
+    uint32_t cBPP;  /* Which has never been used... */
+    uint32_t cDisplay;
+    uint32_t dx;  /**< X offset into the virtual frame-buffer. */
+    uint32_t dy;  /**< Y offset into the virtual frame-buffer. */
+    uint32_t fEnabled;  /* Not fFlags.  Add new members for new flags. */
+} VBVAMODEHINT;
+
+#define VBVAMODEHINT_MAGIC UINT32_C(0x0801add9)
+
+/** Report the rectangle relative to which absolute pointer events should be
+ *  expressed.  This information remains valid until the next VBVA resize event
+ *  for any screen, at which time it is reset to the bounding rectangle of all
+ *  virtual screens and must be re-set.
+ *  @see VBVA_REPORT_INPUT_MAPPING. */
+typedef struct VBVAREPORTINPUTMAPPING
+{
+    int32_t x;    /**< Upper left X co-ordinate relative to the first screen. */
+    int32_t y;    /**< Upper left Y co-ordinate relative to the first screen. */
+    uint32_t cx;  /**< Rectangle width. */
+    uint32_t cy;  /**< Rectangle height. */
+} VBVAREPORTINPUTMAPPING;
+
+/** Report the guest cursor position and query the host one.  The host may wish
+ *  to use the guest information to re-position its own cursor (though this is
+ *  currently unlikely).
+ *  @see VBVA_CURSOR_POSITION */
+typedef struct VBVACURSORPOSITION
+{
+    uint32_t fReportPosition;  /**< Are we reporting a position? */
+    uint32_t x;                /**< Guest cursor X position */
+    uint32_t y;                /**< Guest cursor Y position */
+} VBVACURSORPOSITION;
+
+#pragma pack()
+
+typedef uint64_t VBOXVIDEOOFFSET;
+
+#define VBOXVIDEOOFFSET_VOID ((VBOXVIDEOOFFSET)~0)
+
+#pragma pack(1)
+
+/*
+ * VBOXSHGSMI made on top HGSMI and allows receiving notifications
+ * about G->H command completion
+ */
+/* SHGSMI command header */
+typedef struct VBOXSHGSMIHEADER
+{
+    uint64_t pvNext;    /*<- completion processing queue */
+    uint32_t fFlags;    /*<- see VBOXSHGSMI_FLAG_XXX Flags */
+    uint32_t cRefs;     /*<- command referece count */
+    uint64_t u64Info1;  /*<- contents depends on the fFlags value */
+    uint64_t u64Info2;  /*<- contents depends on the fFlags value */
+} VBOXSHGSMIHEADER, *PVBOXSHGSMIHEADER;
+
+typedef enum
+{
+    VBOXVDMACMD_TYPE_UNDEFINED         = 0,
+    VBOXVDMACMD_TYPE_DMA_PRESENT_BLT   = 1,
+    VBOXVDMACMD_TYPE_DMA_BPB_TRANSFER,
+    VBOXVDMACMD_TYPE_DMA_BPB_FILL,
+    VBOXVDMACMD_TYPE_DMA_PRESENT_SHADOW2PRIMARY,
+    VBOXVDMACMD_TYPE_DMA_PRESENT_CLRFILL,
+    VBOXVDMACMD_TYPE_DMA_PRESENT_FLIP,
+    VBOXVDMACMD_TYPE_DMA_NOP,
+    VBOXVDMACMD_TYPE_CHROMIUM_CMD, /* chromium cmd */
+    VBOXVDMACMD_TYPE_DMA_BPB_TRANSFER_VRAMSYS,
+    VBOXVDMACMD_TYPE_CHILD_STATUS_IRQ /* make the device notify child (monitor) state change IRQ */
+} VBOXVDMACMD_TYPE;
+
+#pragma pack()
+
+/* the command processing was asynch, set by the host to indicate asynch command completion
+ * must not be cleared once set, the command completion is performed by issuing a host->guest completion command
+ * while keeping this flag unchanged */
+#define VBOXSHGSMI_FLAG_HG_ASYNCH               0x00010000
+#if 0
+/* if set     - asynch completion is performed by issuing the event,
+ * if cleared - asynch completion is performed by calling a callback */
+#define VBOXSHGSMI_FLAG_GH_ASYNCH_EVENT         0x00000001
+#endif
+/* issue interrupt on asynch completion, used for critical G->H commands,
+ * i.e. for completion of which guest is waiting. */
+#define VBOXSHGSMI_FLAG_GH_ASYNCH_IRQ           0x00000002
+/* guest does not do any op on completion of this command,
+ * the host may copy the command and indicate that it does not need the command anymore
+ * by not setting VBOXSHGSMI_FLAG_HG_ASYNCH */
+#define VBOXSHGSMI_FLAG_GH_ASYNCH_NOCOMPLETION  0x00000004
+/* guest requires the command to be processed asynchronously,
+ * not setting VBOXSHGSMI_FLAG_HG_ASYNCH by the host in this case is treated as command failure */
+#define VBOXSHGSMI_FLAG_GH_ASYNCH_FORCE         0x00000008
+/* force IRQ on cmd completion */
+#define VBOXSHGSMI_FLAG_GH_ASYNCH_IRQ_FORCE     0x00000010
+/* an IRQ-level callback is associated with the command */
+#define VBOXSHGSMI_FLAG_GH_ASYNCH_CALLBACK_IRQ  0x00000020
+/* guest expects this command to be completed synchronously */
+#define VBOXSHGSMI_FLAG_GH_SYNCH                0x00000040
+
+
+DECLINLINE(uint8_t *) VBoxSHGSMIBufferData (const VBOXSHGSMIHEADER* pHeader)
+{
+    return (uint8_t *)pHeader + sizeof (VBOXSHGSMIHEADER);
+}
+
+#define VBoxSHGSMIBufferHeaderSize() (sizeof (VBOXSHGSMIHEADER))
+
+DECLINLINE(PVBOXSHGSMIHEADER) VBoxSHGSMIBufferHeader (const void *pvData)
+{
+    return (PVBOXSHGSMIHEADER)((uint8_t *)pvData - sizeof (VBOXSHGSMIHEADER));
+}
+
+#ifdef VBOX_WITH_VDMA
+# pragma pack(1)
+
+/* VDMA - Video DMA */
+
+/* VDMA Control API */
+/* VBOXVDMA_CTL::u32Flags */
+typedef enum
+{
+    VBOXVDMA_CTL_TYPE_NONE = 0,
+    VBOXVDMA_CTL_TYPE_ENABLE,
+    VBOXVDMA_CTL_TYPE_DISABLE,
+    VBOXVDMA_CTL_TYPE_FLUSH,
+    VBOXVDMA_CTL_TYPE_WATCHDOG
+} VBOXVDMA_CTL_TYPE;
+
+typedef struct VBOXVDMA_CTL
+{
+    VBOXVDMA_CTL_TYPE enmCtl;
+    uint32_t u32Offset;
+    int32_t  i32Result;
+} VBOXVDMA_CTL, *PVBOXVDMA_CTL;
+
+typedef struct VBOXVDMA_RECTL
+{
+    int16_t left;
+    int16_t top;
+    uint16_t width;
+    uint16_t height;
+} VBOXVDMA_RECTL, *PVBOXVDMA_RECTL;
+
+typedef enum
+{
+    VBOXVDMA_PIXEL_FORMAT_UNKNOWN      =  0,
+    VBOXVDMA_PIXEL_FORMAT_R8G8B8       = 20,
+    VBOXVDMA_PIXEL_FORMAT_A8R8G8B8     = 21,
+    VBOXVDMA_PIXEL_FORMAT_X8R8G8B8     = 22,
+    VBOXVDMA_PIXEL_FORMAT_R5G6B5       = 23,
+    VBOXVDMA_PIXEL_FORMAT_X1R5G5B5     = 24,
+    VBOXVDMA_PIXEL_FORMAT_A1R5G5B5     = 25,
+    VBOXVDMA_PIXEL_FORMAT_A4R4G4B4     = 26,
+    VBOXVDMA_PIXEL_FORMAT_R3G3B2       = 27,
+    VBOXVDMA_PIXEL_FORMAT_A8           = 28,
+    VBOXVDMA_PIXEL_FORMAT_A8R3G3B2     = 29,
+    VBOXVDMA_PIXEL_FORMAT_X4R4G4B4     = 30,
+    VBOXVDMA_PIXEL_FORMAT_A2B10G10R10  = 31,
+    VBOXVDMA_PIXEL_FORMAT_A8B8G8R8     = 32,
+    VBOXVDMA_PIXEL_FORMAT_X8B8G8R8     = 33,
+    VBOXVDMA_PIXEL_FORMAT_G16R16       = 34,
+    VBOXVDMA_PIXEL_FORMAT_A2R10G10B10  = 35,
+    VBOXVDMA_PIXEL_FORMAT_A16B16G16R16 = 36,
+    VBOXVDMA_PIXEL_FORMAT_A8P8         = 40,
+    VBOXVDMA_PIXEL_FORMAT_P8           = 41,
+    VBOXVDMA_PIXEL_FORMAT_L8           = 50,
+    VBOXVDMA_PIXEL_FORMAT_A8L8         = 51,
+    VBOXVDMA_PIXEL_FORMAT_A4L4         = 52,
+    VBOXVDMA_PIXEL_FORMAT_V8U8         = 60,
+    VBOXVDMA_PIXEL_FORMAT_L6V5U5       = 61,
+    VBOXVDMA_PIXEL_FORMAT_X8L8V8U8     = 62,
+    VBOXVDMA_PIXEL_FORMAT_Q8W8V8U8     = 63,
+    VBOXVDMA_PIXEL_FORMAT_V16U16       = 64,
+    VBOXVDMA_PIXEL_FORMAT_W11V11U10    = 65,
+    VBOXVDMA_PIXEL_FORMAT_A2W10V10U10  = 67
+} VBOXVDMA_PIXEL_FORMAT;
+
+typedef struct VBOXVDMA_SURF_DESC
+{
+    uint32_t width;
+    uint32_t height;
+    VBOXVDMA_PIXEL_FORMAT format;
+    uint32_t bpp;
+    uint32_t pitch;
+    uint32_t fFlags;
+} VBOXVDMA_SURF_DESC, *PVBOXVDMA_SURF_DESC;
+
+/*typedef uint64_t VBOXVDMAPHADDRESS;*/
+typedef uint64_t VBOXVDMASURFHANDLE;
+
+/* region specified as a rectangle, otherwize it is a size of memory pointed to by phys address */
+#define VBOXVDMAOPERAND_FLAGS_RECTL       0x1
+/* Surface handle is valid */
+#define VBOXVDMAOPERAND_FLAGS_PRIMARY        0x2
+/* address is offset in VRAM */
+#define VBOXVDMAOPERAND_FLAGS_VRAMOFFSET  0x4
+
+
+/* VBOXVDMACBUF_DR::phBuf specifies offset in VRAM */
+#define VBOXVDMACBUF_FLAG_BUF_VRAM_OFFSET 0x00000001
+/* command buffer follows the VBOXVDMACBUF_DR in VRAM, VBOXVDMACBUF_DR::phBuf is ignored */
+#define VBOXVDMACBUF_FLAG_BUF_FOLLOWS_DR  0x00000002
+
+/*
+ * We can not submit the DMA command via VRAM since we do not have control over
+ * DMA command buffer [de]allocation, i.e. we only control the buffer contents.
+ * In other words the system may call one of our callbacks to fill a command buffer
+ * with the necessary commands and then discard the buffer w/o any notification.
+ *
+ * We have only DMA command buffer physical address at submission time.
+ *
+ * so the only way is to */
+typedef struct VBOXVDMACBUF_DR
+{
+    uint16_t fFlags;
+    uint16_t cbBuf;
+    /* RT_SUCCESS()     - on success
+     * VERR_INTERRUPTED - on preemption
+     * VERR_xxx         - on error */
+    int32_t  rc;
+    union
+    {
+        uint64_t phBuf;
+        VBOXVIDEOOFFSET offVramBuf;
+    } Location;
+    uint64_t aGuestData[7];
+} VBOXVDMACBUF_DR, *PVBOXVDMACBUF_DR;
+
+#define VBOXVDMACBUF_DR_TAIL(_pCmd, _t) ( (_t*)(((uint8_t*)(_pCmd)) + sizeof (VBOXVDMACBUF_DR)) )
+#define VBOXVDMACBUF_DR_FROM_TAIL(_pCmd) ( (VBOXVDMACBUF_DR*)(((uint8_t*)(_pCmd)) - sizeof (VBOXVDMACBUF_DR)) )
+
+typedef struct VBOXVDMACMD
+{
+    VBOXVDMACMD_TYPE enmType;
+    uint32_t u32CmdSpecific;
+} VBOXVDMACMD, *PVBOXVDMACMD;
+
+#define VBOXVDMACMD_HEADER_SIZE() sizeof (VBOXVDMACMD)
+#define VBOXVDMACMD_SIZE_FROMBODYSIZE(_s) (VBOXVDMACMD_HEADER_SIZE() + (_s))
+#define VBOXVDMACMD_SIZE(_t) (VBOXVDMACMD_SIZE_FROMBODYSIZE(sizeof (_t)))
+#define VBOXVDMACMD_BODY(_pCmd, _t) ( (_t*)(((uint8_t*)(_pCmd)) + VBOXVDMACMD_HEADER_SIZE()) )
+#define VBOXVDMACMD_BODY_SIZE(_s) ( (_s) - VBOXVDMACMD_HEADER_SIZE() )
+#define VBOXVDMACMD_FROM_BODY(_pCmd) ( (VBOXVDMACMD*)(((uint8_t*)(_pCmd)) - VBOXVDMACMD_HEADER_SIZE()) )
+#define VBOXVDMACMD_BODY_FIELD_OFFSET(_ot, _t, _f) ( (_ot)(uintptr_t)( VBOXVDMACMD_BODY(0, uint8_t) + RT_OFFSETOF(_t, _f) ) )
+
+typedef struct VBOXVDMACMD_DMA_PRESENT_BLT
+{
+    VBOXVIDEOOFFSET offSrc;
+    VBOXVIDEOOFFSET offDst;
+    VBOXVDMA_SURF_DESC srcDesc;
+    VBOXVDMA_SURF_DESC dstDesc;
+    VBOXVDMA_RECTL srcRectl;
+    VBOXVDMA_RECTL dstRectl;
+    uint32_t u32Reserved;
+    uint32_t cDstSubRects;
+    VBOXVDMA_RECTL aDstSubRects[1];
+} VBOXVDMACMD_DMA_PRESENT_BLT, *PVBOXVDMACMD_DMA_PRESENT_BLT;
+
+typedef struct VBOXVDMACMD_DMA_PRESENT_SHADOW2PRIMARY
+{
+    VBOXVDMA_RECTL Rect;
+} VBOXVDMACMD_DMA_PRESENT_SHADOW2PRIMARY, *PVBOXVDMACMD_DMA_PRESENT_SHADOW2PRIMARY;
+
+
+#define VBOXVDMACMD_DMA_BPB_TRANSFER_F_SRC_VRAMOFFSET 0x00000001
+#define VBOXVDMACMD_DMA_BPB_TRANSFER_F_DST_VRAMOFFSET 0x00000002
+
+typedef struct VBOXVDMACMD_DMA_BPB_TRANSFER
+{
+    uint32_t cbTransferSize;
+    uint32_t fFlags;
+    union
+    {
+        uint64_t phBuf;
+        VBOXVIDEOOFFSET offVramBuf;
+    } Src;
+    union
+    {
+        uint64_t phBuf;
+        VBOXVIDEOOFFSET offVramBuf;
+    } Dst;
+} VBOXVDMACMD_DMA_BPB_TRANSFER, *PVBOXVDMACMD_DMA_BPB_TRANSFER;
+
+#define VBOXVDMACMD_SYSMEMEL_F_PAGELIST 0x00000001
+
+typedef struct VBOXVDMACMD_SYSMEMEL
+{
+    uint32_t cPages;
+    uint32_t fFlags;
+    uint64_t phBuf[1];
+} VBOXVDMACMD_SYSMEMEL, *PVBOXVDMACMD_SYSMEMEL;
+
+#define VBOXVDMACMD_SYSMEMEL_NEXT(_pEl) (((_pEl)->fFlags & VBOXVDMACMD_SYSMEMEL_F_PAGELIST) ? \
+        ((PVBOXVDMACMD_SYSMEMEL)(((uint8_t*)(_pEl))+RT_OFFSETOF(VBOXVDMACMD_SYSMEMEL, phBuf[(_pEl)->cPages]))) \
+        : \
+        ((_pEl)+1)
+
+#define VBOXVDMACMD_DMA_BPB_TRANSFER_VRAMSYS_SYS2VRAM 0x00000001
+
+typedef struct VBOXVDMACMD_DMA_BPB_TRANSFER_VRAMSYS
+{
+    uint32_t cTransferPages;
+    uint32_t fFlags;
+    VBOXVIDEOOFFSET offVramBuf;
+    VBOXVDMACMD_SYSMEMEL FirstEl;
+} VBOXVDMACMD_DMA_BPB_TRANSFER_VRAMSYS, *PVBOXVDMACMD_DMA_BPB_TRANSFER_VRAMSYS;
+
+typedef struct VBOXVDMACMD_DMA_BPB_FILL
+{
+    VBOXVIDEOOFFSET offSurf;
+    uint32_t cbFillSize;
+    uint32_t u32FillPattern;
+} VBOXVDMACMD_DMA_BPB_FILL, *PVBOXVDMACMD_DMA_BPB_FILL;
+
+#define VBOXVDMA_CHILD_STATUS_F_CONNECTED    0x01
+#define VBOXVDMA_CHILD_STATUS_F_DISCONNECTED 0x02
+#define VBOXVDMA_CHILD_STATUS_F_ROTATED      0x04
+
+typedef struct VBOXVDMA_CHILD_STATUS
+{
+    uint32_t iChild;
+    uint8_t  fFlags;
+    uint8_t  u8RotationAngle;
+    uint16_t u16Reserved;
+} VBOXVDMA_CHILD_STATUS, *PVBOXVDMA_CHILD_STATUS;
+
+/* apply the aInfos are applied to all targets, the iTarget is ignored */
+#define VBOXVDMACMD_CHILD_STATUS_IRQ_F_APPLY_TO_ALL 0x00000001
+
+typedef struct VBOXVDMACMD_CHILD_STATUS_IRQ
+{
+    uint32_t cInfos;
+    uint32_t fFlags;
+    VBOXVDMA_CHILD_STATUS aInfos[1];
+} VBOXVDMACMD_CHILD_STATUS_IRQ, *PVBOXVDMACMD_CHILD_STATUS_IRQ;
+
+# pragma pack()
+#endif /* #ifdef VBOX_WITH_VDMA */
+
+#pragma pack(1)
+typedef struct VBOXVDMACMD_CHROMIUM_BUFFER
+{
+    VBOXVIDEOOFFSET offBuffer;
+    uint32_t cbBuffer;
+    uint32_t u32GuestData;
+    uint64_t u64GuestData;
+} VBOXVDMACMD_CHROMIUM_BUFFER, *PVBOXVDMACMD_CHROMIUM_BUFFER;
+
+typedef struct VBOXVDMACMD_CHROMIUM_CMD
+{
+    uint32_t cBuffers;
+    uint32_t u32Reserved;
+    VBOXVDMACMD_CHROMIUM_BUFFER aBuffers[1];
+} VBOXVDMACMD_CHROMIUM_CMD, *PVBOXVDMACMD_CHROMIUM_CMD;
+
+typedef enum
+{
+    VBOXVDMACMD_CHROMIUM_CTL_TYPE_UNKNOWN = 0,
+    VBOXVDMACMD_CHROMIUM_CTL_TYPE_CRHGSMI_SETUP,
+    VBOXVDMACMD_CHROMIUM_CTL_TYPE_SAVESTATE_BEGIN,
+    VBOXVDMACMD_CHROMIUM_CTL_TYPE_SAVESTATE_END,
+    VBOXVDMACMD_CHROMIUM_CTL_TYPE_CRHGSMI_SETUP_MAINCB,
+    VBOXVDMACMD_CHROMIUM_CTL_TYPE_CRCONNECT,
+    VBOXVDMACMD_CHROMIUM_CTL_TYPE_SIZEHACK = 0x7fffffff
+} VBOXVDMACMD_CHROMIUM_CTL_TYPE;
+
+typedef struct VBOXVDMACMD_CHROMIUM_CTL
+{
+    VBOXVDMACMD_CHROMIUM_CTL_TYPE enmType;
+    uint32_t cbCmd;
+} VBOXVDMACMD_CHROMIUM_CTL, *PVBOXVDMACMD_CHROMIUM_CTL;
+
+
+typedef struct PDMIDISPLAYVBVACALLBACKS *HCRHGSMICMDCOMPLETION;
+typedef DECLCALLBACK(int) FNCRHGSMICMDCOMPLETION(HCRHGSMICMDCOMPLETION hCompletion, PVBOXVDMACMD_CHROMIUM_CMD pCmd, int rc);
+typedef FNCRHGSMICMDCOMPLETION *PFNCRHGSMICMDCOMPLETION;
+
+/* tells whether 3D backend has some 3D overlay data displayed */
+typedef DECLCALLBACK(bool) FNCROGLHASDATA(void);
+typedef FNCROGLHASDATA *PFNCROGLHASDATA;
+
+/* same as PFNCROGLHASDATA, but for specific screen */
+typedef DECLCALLBACK(bool) FNCROGLHASDATAFORSCREEN(uint32_t i32ScreenID);
+typedef FNCROGLHASDATAFORSCREEN *PFNCROGLHASDATAFORSCREEN;
+
+/* callbacks chrogl gives to main */
+typedef struct CR_MAIN_INTERFACE
+{
+    PFNCROGLHASDATA pfnHasData;
+    PFNCROGLHASDATAFORSCREEN pfnHasDataForScreen;
+} CR_MAIN_INTERFACE;
+
+typedef struct VBOXVDMACMD_CHROMIUM_CTL_CRHGSMI_SETUP_MAINCB
+{
+    VBOXVDMACMD_CHROMIUM_CTL Hdr;
+    /*in*/
+    HCRHGSMICMDCOMPLETION hCompletion;
+    PFNCRHGSMICMDCOMPLETION pfnCompletion;
+    /*out*/
+    CR_MAIN_INTERFACE MainInterface;
+} VBOXVDMACMD_CHROMIUM_CTL_CRHGSMI_SETUP_MAINCB, *PVBOXVDMACMD_CHROMIUM_CTL_CRHGSMI_SETUP_MAINCB;
+
+typedef struct VBOXCRCON_SERVER *HVBOXCRCON_SERVER;
+typedef struct PDMIDISPLAYVBVACALLBACKS* HVBOXCRCON_CLIENT;
+
+typedef struct VBOXCRCON_3DRGN_CLIENT* HVBOXCRCON_3DRGN_CLIENT;
+typedef struct VBOXCRCON_3DRGN_ASYNCCLIENT* HVBOXCRCON_3DRGN_ASYNCCLIENT;
+
+/* server callbacks */
+/* submit chromium cmd */
+typedef DECLCALLBACK(int) FNVBOXCRCON_SVR_CRCMD(HVBOXCRCON_SERVER hServer, PVBOXVDMACMD_CHROMIUM_CMD pCmd, uint32_t cbCmd);
+typedef FNVBOXCRCON_SVR_CRCMD *PFNVBOXCRCON_SVR_CRCMD;
+
+/* submit chromium control cmd */
+typedef DECLCALLBACK(int) FNVBOXCRCON_SVR_CRCTL(HVBOXCRCON_SERVER hServer, PVBOXVDMACMD_CHROMIUM_CTL pCtl, uint32_t cbCmd);
+typedef FNVBOXCRCON_SVR_CRCTL *PFNVBOXCRCON_SVR_CRCTL;
+
+/* request 3D data.
+ * The protocol is the following:
+ * 1. if there is no 3D data displayed on screen, returns VINF_EOF immediately w/o calling any PFNVBOXCRCON_3DRGN_XXX callbacks
+ * 2. otherwise calls PFNVBOXCRCON_3DRGN_ONSUBMIT, submits the "regions get" request to the CrOpenGL server to process it asynchronously and returns VINF_SUCCESS
+ * 2.a on "regions get" request processing calls PFNVBOXCRCON_3DRGN_BEGIN,
+ * 2.b then PFNVBOXCRCON_3DRGN_REPORT zero or more times for each 3D region,
+ * 2.c and then PFNVBOXCRCON_3DRGN_END
+ * 3. returns VERR_XXX code on failure
+ * */
+typedef DECLCALLBACK(int) FNVBOXCRCON_SVR_3DRGN_GET(HVBOXCRCON_SERVER hServer, HVBOXCRCON_3DRGN_CLIENT hRgnClient, uint32_t idScreen);
+typedef FNVBOXCRCON_SVR_3DRGN_GET *PFNVBOXCRCON_SVR_3DRGN_GET;
+
+/* 3D Regions Client callbacks */
+/* called from the PFNVBOXCRCON_SVR_3DRGN_GET callback in case server has 3D data and is going to process the request asynchronously,
+ * see comments for PFNVBOXCRCON_SVR_3DRGN_GET above */
+typedef DECLCALLBACK(int) FNVBOXCRCON_3DRGN_ONSUBMIT(HVBOXCRCON_3DRGN_CLIENT hRgnClient, uint32_t idScreen, HVBOXCRCON_3DRGN_ASYNCCLIENT *phRgnAsyncClient);
+typedef FNVBOXCRCON_3DRGN_ONSUBMIT *PFNVBOXCRCON_3DRGN_ONSUBMIT;
+
+/* called from the "regions get" command processing thread, to indicate that the "regions get" is started.
+ * see comments for PFNVBOXCRCON_SVR_3DRGN_GET above */
+typedef DECLCALLBACK(int) FNVBOXCRCON_3DRGN_BEGIN(HVBOXCRCON_3DRGN_ASYNCCLIENT hRgnAsyncClient, uint32_t idScreen);
+typedef FNVBOXCRCON_3DRGN_BEGIN *PFNVBOXCRCON_3DRGN_BEGIN;
+
+/* called from the "regions get" command processing thread, to report a 3D region.
+ * see comments for PFNVBOXCRCON_SVR_3DRGN_GET above */
+typedef DECLCALLBACK(int) FNVBOXCRCON_3DRGN_REPORT(HVBOXCRCON_3DRGN_ASYNCCLIENT hRgnAsyncClient, uint32_t idScreen, void *pvData, uint32_t cbStride, const RTRECT *pRect);
+typedef FNVBOXCRCON_3DRGN_REPORT *PFNVBOXCRCON_3DRGN_REPORT;
+
+/* called from the "regions get" command processing thread, to indicate that the "regions get" is completed.
+ * see comments for PFNVBOXCRCON_SVR_3DRGN_GET above */
+typedef DECLCALLBACK(int) FNVBOXCRCON_3DRGN_END(HVBOXCRCON_3DRGN_ASYNCCLIENT hRgnAsyncClient, uint32_t idScreen);
+typedef FNVBOXCRCON_3DRGN_END *PFNVBOXCRCON_3DRGN_END;
+
+
+/* client callbacks */
+/* complete chromium cmd */
+typedef DECLCALLBACK(int) FNVBOXCRCON_CLT_CRCTL_COMPLETE(HVBOXCRCON_CLIENT hClient, PVBOXVDMACMD_CHROMIUM_CTL pCtl, int rc);
+typedef FNVBOXCRCON_CLT_CRCTL_COMPLETE *PFNVBOXCRCON_CLT_CRCTL_COMPLETE;
+
+/* complete chromium control cmd */
+typedef DECLCALLBACK(int) FNVBOXCRCON_CLT_CRCMD_COMPLETE(HVBOXCRCON_CLIENT hClient, PVBOXVDMACMD_CHROMIUM_CMD pCmd, int rc);
+typedef FNVBOXCRCON_CLT_CRCMD_COMPLETE *PFNVBOXCRCON_CLT_CRCMD_COMPLETE;
+
+typedef struct VBOXCRCON_SERVER_CALLBACKS
+{
+    HVBOXCRCON_SERVER hServer;
+    PFNVBOXCRCON_SVR_CRCMD pfnCrCmd;
+    PFNVBOXCRCON_SVR_CRCTL pfnCrCtl;
+    PFNVBOXCRCON_SVR_3DRGN_GET pfn3DRgnGet;
+} VBOXCRCON_SERVER_CALLBACKS, *PVBOXCRCON_SERVER_CALLBACKS;
+
+typedef struct VBOXCRCON_CLIENT_CALLBACKS
+{
+    HVBOXCRCON_CLIENT hClient;
+    PFNVBOXCRCON_CLT_CRCMD_COMPLETE pfnCrCmdComplete;
+    PFNVBOXCRCON_CLT_CRCTL_COMPLETE pfnCrCtlComplete;
+    PFNVBOXCRCON_3DRGN_ONSUBMIT pfn3DRgnOnSubmit;
+    PFNVBOXCRCON_3DRGN_BEGIN pfn3DRgnBegin;
+    PFNVBOXCRCON_3DRGN_REPORT pfn3DRgnReport;
+    PFNVBOXCRCON_3DRGN_END pfn3DRgnEnd;
+} VBOXCRCON_CLIENT_CALLBACKS, *PVBOXCRCON_CLIENT_CALLBACKS;
+
+/* issued by Main to establish connection between Main and CrOpenGL service */
+typedef struct VBOXVDMACMD_CHROMIUM_CTL_CRCONNECT
+{
+    VBOXVDMACMD_CHROMIUM_CTL Hdr;
+    /*input (filled by Client) :*/
+    /*class VMMDev*/void *pVMMDev;
+    VBOXCRCON_CLIENT_CALLBACKS ClientCallbacks;
+    /*output (filled by Server) :*/
+    VBOXCRCON_SERVER_CALLBACKS ServerCallbacks;
+} VBOXVDMACMD_CHROMIUM_CTL_CRCONNECT, *PVBOXVDMACMD_CHROMIUM_CTL_CRCONNECT;
+
+/* ring command buffer dr */
+#define VBOXCMDVBVA_STATE_SUBMITTED   1
+#define VBOXCMDVBVA_STATE_CANCELLED   2
+#define VBOXCMDVBVA_STATE_IN_PROGRESS 3
+/* the "completed" state is signalled via the ring buffer values */
+
+/* CrHgsmi command */
+#define VBOXCMDVBVA_OPTYPE_CRCMD                        1
+/* blit command that does blitting of allocations identified by VRAM offset or host id
+ * for VRAM-offset ones the size and format are same as primary */
+#define VBOXCMDVBVA_OPTYPE_BLT                          2
+/* flip */
+#define VBOXCMDVBVA_OPTYPE_FLIP                         3
+/* ColorFill */
+#define VBOXCMDVBVA_OPTYPE_CLRFILL                      4
+/* allocation paging transfer request */
+#define VBOXCMDVBVA_OPTYPE_PAGING_TRANSFER              5
+/* allocation paging fill request */
+#define VBOXCMDVBVA_OPTYPE_PAGING_FILL                  6
+/* same as VBOXCMDVBVA_OPTYPE_NOP, but contains VBOXCMDVBVA_HDR data */
+#define VBOXCMDVBVA_OPTYPE_NOPCMD                       7
+/* actual command is stored in guest system memory */
+#define VBOXCMDVBVA_OPTYPE_SYSMEMCMD                    8
+/* complex command - i.e. can contain multiple commands
+ * i.e. the VBOXCMDVBVA_OPTYPE_COMPLEXCMD VBOXCMDVBVA_HDR is followed
+ * by one or more VBOXCMDVBVA_HDR commands.
+ * Each command's size is specified in it's VBOXCMDVBVA_HDR's u32FenceID field */
+#define VBOXCMDVBVA_OPTYPE_COMPLEXCMD                   9
+
+/* nop - is a one-bit command. The buffer size to skip is determined by VBVA buffer size */
+#define VBOXCMDVBVA_OPTYPE_NOP                          0x80
+
+/* u8Flags flags */
+/* transfer from RAM to Allocation */
+#define VBOXCMDVBVA_OPF_PAGING_TRANSFER_IN                  0x80
+
+#define VBOXCMDVBVA_OPF_BLT_TYPE_SAMEDIM_A8R8G8B8           0
+#define VBOXCMDVBVA_OPF_BLT_TYPE_GENERIC_A8R8G8B8           1
+#define VBOXCMDVBVA_OPF_BLT_TYPE_OFFPRIMSZFMT_OR_ID         2
+
+#define VBOXCMDVBVA_OPF_BLT_TYPE_MASK                       3
+
+
+#define VBOXCMDVBVA_OPF_CLRFILL_TYPE_GENERIC_A8R8G8B8       0
+
+#define VBOXCMDVBVA_OPF_CLRFILL_TYPE_MASK                   1
+
+
+/* blit direction is from first operand to second */
+#define VBOXCMDVBVA_OPF_BLT_DIR_IN_2                        0x10
+/* operand 1 contains host id */
+#define VBOXCMDVBVA_OPF_OPERAND1_ISID                       0x20
+/* operand 2 contains host id */
+#define VBOXCMDVBVA_OPF_OPERAND2_ISID                       0x40
+/* primary hint id is src */
+#define VBOXCMDVBVA_OPF_PRIMARY_HINT_SRC                    0x80
+
+/* trying to make the header as small as possible,
+ * we'd have pretty few op codes actually, so 8bit is quite enough,
+ * we will be able to extend it in any way. */
+typedef struct VBOXCMDVBVA_HDR
+{
+    /* one VBOXCMDVBVA_OPTYPE_XXX, except NOP, see comments above */
+    uint8_t u8OpCode;
+    /* command-specific
+     * VBOXCMDVBVA_OPTYPE_CRCMD                     - must be null
+     * VBOXCMDVBVA_OPTYPE_BLT                       - OR-ed VBOXCMDVBVA_OPF_ALLOC_XXX flags
+     * VBOXCMDVBVA_OPTYPE_PAGING_TRANSFER           - must be null
+     * VBOXCMDVBVA_OPTYPE_PAGING_FILL               - must be null
+     * VBOXCMDVBVA_OPTYPE_NOPCMD                    - must be null
+     * VBOXCMDVBVA_OPTYPE_NOP                       - not applicable (as the entire VBOXCMDVBVA_HDR is not valid) */
+    uint8_t u8Flags;
+    /* one of VBOXCMDVBVA_STATE_XXX*/
+    volatile uint8_t u8State;
+    union
+    {
+        /* result, 0 on success, otherwise contains the failure code TBD */
+        int8_t i8Result;
+        uint8_t u8PrimaryID;
+    } u;
+    union
+    {
+        /* complex command (VBOXCMDVBVA_OPTYPE_COMPLEXCMD) element data */
+        struct
+        {
+            /* command length */
+            uint16_t u16CbCmdHost;
+            /* guest-specific data, host expects it to be NULL */
+            uint16_t u16CbCmdGuest;
+        } complexCmdEl;
+        /* DXGK DDI fence ID */
+        uint32_t u32FenceID;
+    } u2;
+} VBOXCMDVBVA_HDR;
+
+typedef uint32_t VBOXCMDVBVAOFFSET;
+typedef uint64_t VBOXCMDVBVAPHADDR;
+typedef uint32_t VBOXCMDVBVAPAGEIDX;
+
+typedef struct VBOXCMDVBVA_CRCMD_BUFFER
+{
+    uint32_t cbBuffer;
+    VBOXCMDVBVAOFFSET offBuffer;
+} VBOXCMDVBVA_CRCMD_BUFFER;
+
+typedef struct VBOXCMDVBVA_CRCMD_CMD
+{
+    uint32_t cBuffers;
+    VBOXCMDVBVA_CRCMD_BUFFER aBuffers[1];
+} VBOXCMDVBVA_CRCMD_CMD;
+
+typedef struct VBOXCMDVBVA_CRCMD
+{
+    VBOXCMDVBVA_HDR Hdr;
+    VBOXCMDVBVA_CRCMD_CMD Cmd;
+} VBOXCMDVBVA_CRCMD;
+
+typedef struct VBOXCMDVBVA_ALLOCINFO
+{
+    union
+    {
+        VBOXCMDVBVAOFFSET offVRAM;
+        uint32_t id;
+    } u;
+} VBOXCMDVBVA_ALLOCINFO;
+
+typedef struct VBOXCMDVBVA_ALLOCDESC
+{
+    VBOXCMDVBVA_ALLOCINFO Info;
+    uint16_t u16Width;
+    uint16_t u16Height;
+} VBOXCMDVBVA_ALLOCDESC;
+
+typedef struct VBOXCMDVBVA_RECT
+{
+   /** Coordinates of affected rectangle. */
+   int16_t xLeft;
+   int16_t yTop;
+   int16_t xRight;
+   int16_t yBottom;
+} VBOXCMDVBVA_RECT;
+
+typedef struct VBOXCMDVBVA_POINT
+{
+   int16_t x;
+   int16_t y;
+} VBOXCMDVBVA_POINT;
+
+typedef struct VBOXCMDVBVA_BLT_HDR
+{
+    VBOXCMDVBVA_HDR Hdr;
+    VBOXCMDVBVA_POINT Pos;
+} VBOXCMDVBVA_BLT_HDR;
+
+typedef struct VBOXCMDVBVA_BLT_PRIMARY
+{
+    VBOXCMDVBVA_BLT_HDR Hdr;
+    VBOXCMDVBVA_ALLOCINFO alloc;
+    /* the rects count is determined from the command size */
+    VBOXCMDVBVA_RECT aRects[1];
+} VBOXCMDVBVA_BLT_PRIMARY;
+
+typedef struct VBOXCMDVBVA_BLT_PRIMARY_GENERIC_A8R8G8B8
+{
+    VBOXCMDVBVA_BLT_HDR Hdr;
+    VBOXCMDVBVA_ALLOCDESC alloc;
+    /* the rects count is determined from the command size */
+    VBOXCMDVBVA_RECT aRects[1];
+} VBOXCMDVBVA_BLT_PRIMARY_GENERIC_A8R8G8B8;
+
+typedef struct VBOXCMDVBVA_BLT_OFFPRIMSZFMT_OR_ID
+{
+    VBOXCMDVBVA_BLT_HDR Hdr;
+    VBOXCMDVBVA_ALLOCINFO alloc;
+    uint32_t id;
+    /* the rects count is determined from the command size */
+    VBOXCMDVBVA_RECT aRects[1];
+} VBOXCMDVBVA_BLT_OFFPRIMSZFMT_OR_ID;
+
+typedef struct VBOXCMDVBVA_BLT_SAMEDIM_A8R8G8B8
+{
+    VBOXCMDVBVA_BLT_HDR Hdr;
+    VBOXCMDVBVA_ALLOCDESC alloc1;
+    VBOXCMDVBVA_ALLOCINFO info2;
+    /* the rects count is determined from the command size */
+    VBOXCMDVBVA_RECT aRects[1];
+} VBOXCMDVBVA_BLT_SAMEDIM_A8R8G8B8;
+
+typedef struct VBOXCMDVBVA_BLT_GENERIC_A8R8G8B8
+{
+    VBOXCMDVBVA_BLT_HDR Hdr;
+    VBOXCMDVBVA_ALLOCDESC alloc1;
+    VBOXCMDVBVA_ALLOCDESC alloc2;
+    /* the rects count is determined from the command size */
+    VBOXCMDVBVA_RECT aRects[1];
+} VBOXCMDVBVA_BLT_GENERIC_A8R8G8B8;
+
+#define VBOXCMDVBVA_SIZEOF_BLTSTRUCT_MAX (sizeof (VBOXCMDVBVA_BLT_GENERIC_A8R8G8B8))
+
+typedef struct VBOXCMDVBVA_FLIP
+{
+    VBOXCMDVBVA_HDR Hdr;
+    VBOXCMDVBVA_ALLOCINFO src;
+    VBOXCMDVBVA_RECT aRects[1];
+} VBOXCMDVBVA_FLIP;
+
+#define VBOXCMDVBVA_SIZEOF_FLIPSTRUCT_MIN (RT_OFFSETOF(VBOXCMDVBVA_FLIP, aRects))
+
+typedef struct VBOXCMDVBVA_CLRFILL_HDR
+{
+    VBOXCMDVBVA_HDR Hdr;
+    uint32_t u32Color;
+} VBOXCMDVBVA_CLRFILL_HDR;
+
+typedef struct VBOXCMDVBVA_CLRFILL_PRIMARY
+{
+    VBOXCMDVBVA_CLRFILL_HDR Hdr;
+    VBOXCMDVBVA_RECT aRects[1];
+} VBOXCMDVBVA_CLRFILL_PRIMARY;
+
+typedef struct VBOXCMDVBVA_CLRFILL_GENERIC_A8R8G8B8
+{
+    VBOXCMDVBVA_CLRFILL_HDR Hdr;
+    VBOXCMDVBVA_ALLOCDESC dst;
+    VBOXCMDVBVA_RECT aRects[1];
+} VBOXCMDVBVA_CLRFILL_GENERIC_A8R8G8B8;
+
+#define VBOXCMDVBVA_SIZEOF_CLRFILLSTRUCT_MAX (sizeof (VBOXCMDVBVA_CLRFILL_GENERIC_A8R8G8B8))
+
+#if 0
+#define VBOXCMDVBVA_SYSMEMEL_CPAGES_MAX  0x1000
+
+typedef struct VBOXCMDVBVA_SYSMEMEL
+{
+    uint32_t cPagesAfterFirst  : 12;
+    uint32_t iPage1            : 20;
+    uint32_t iPage2;
+} VBOXCMDVBVA_SYSMEMEL;
+#endif
+
+typedef struct VBOXCMDVBVA_PAGING_TRANSFER_DATA
+{
+    /* for now can only contain offVRAM.
+     * paging transfer can NOT be initiated for allocations having host 3D object (hostID) associated */
+    VBOXCMDVBVA_ALLOCINFO Alloc;
+    VBOXCMDVBVAPAGEIDX aPageNumbers[1];
+} VBOXCMDVBVA_PAGING_TRANSFER_DATA;
+
+typedef struct VBOXCMDVBVA_PAGING_TRANSFER
+{
+    VBOXCMDVBVA_HDR Hdr;
+    VBOXCMDVBVA_PAGING_TRANSFER_DATA Data;
+} VBOXCMDVBVA_PAGING_TRANSFER;
+
+typedef struct VBOXCMDVBVA_PAGING_FILL
+{
+    VBOXCMDVBVA_HDR Hdr;
+    uint32_t u32CbFill;
+    uint32_t u32Pattern;
+    /* paging transfer can NOT be initiated for allocations having host 3D object (hostID) associated */
+    VBOXCMDVBVAOFFSET offVRAM;
+} VBOXCMDVBVA_PAGING_FILL;
+
+typedef struct VBOXCMDVBVA_SYSMEMCMD
+{
+    VBOXCMDVBVA_HDR Hdr;
+    VBOXCMDVBVAPHADDR phCmd;
+} VBOXCMDVBVA_SYSMEMCMD;
+
+#define VBOXCMDVBVACTL_TYPE_ENABLE     1
+#define VBOXCMDVBVACTL_TYPE_3DCTL      2
+#define VBOXCMDVBVACTL_TYPE_RESIZE     3
+
+typedef struct VBOXCMDVBVA_CTL
+{
+    uint32_t u32Type;
+    int32_t i32Result;
+} VBOXCMDVBVA_CTL;
+
+typedef struct VBOXCMDVBVA_CTL_ENABLE
+{
+    VBOXCMDVBVA_CTL Hdr;
+    VBVAENABLE Enable;
+} VBOXCMDVBVA_CTL_ENABLE;
+
+#define VBOXCMDVBVA_SCREENMAP_SIZE(_elType) ((VBOX_VIDEO_MAX_SCREENS + sizeof (_elType) - 1) / sizeof (_elType))
+#define VBOXCMDVBVA_SCREENMAP_DECL(_elType, _name) _elType _name[VBOXCMDVBVA_SCREENMAP_SIZE(_elType)]
+
+typedef struct VBOXCMDVBVA_RESIZE_ENTRY
+{
+    VBVAINFOSCREEN Screen;
+    VBOXCMDVBVA_SCREENMAP_DECL(uint32_t, aTargetMap);
+} VBOXCMDVBVA_RESIZE_ENTRY;
+
+typedef struct VBOXCMDVBVA_RESIZE
+{
+    VBOXCMDVBVA_RESIZE_ENTRY aEntries[1];
+} VBOXCMDVBVA_RESIZE;
+
+typedef struct VBOXCMDVBVA_CTL_RESIZE
+{
+    VBOXCMDVBVA_CTL Hdr;
+    VBOXCMDVBVA_RESIZE Resize;
+} VBOXCMDVBVA_CTL_RESIZE;
+
+#define VBOXCMDVBVA3DCTL_TYPE_CONNECT     1
+#define VBOXCMDVBVA3DCTL_TYPE_DISCONNECT  2
+#define VBOXCMDVBVA3DCTL_TYPE_CMD         3
+
+typedef struct VBOXCMDVBVA_3DCTL
+{
+    uint32_t u32Type;
+    uint32_t u32CmdClientId;
+} VBOXCMDVBVA_3DCTL;
+
+typedef struct VBOXCMDVBVA_3DCTL_CONNECT
+{
+    VBOXCMDVBVA_3DCTL Hdr;
+    uint32_t u32MajorVersion;
+    uint32_t u32MinorVersion;
+    uint64_t u64Pid;
+} VBOXCMDVBVA_3DCTL_CONNECT;
+
+typedef struct VBOXCMDVBVA_3DCTL_CMD
+{
+    VBOXCMDVBVA_3DCTL Hdr;
+    VBOXCMDVBVA_HDR Cmd;
+} VBOXCMDVBVA_3DCTL_CMD;
+
+typedef struct VBOXCMDVBVA_CTL_3DCTL_CMD
+{
+    VBOXCMDVBVA_CTL Hdr;
+    VBOXCMDVBVA_3DCTL_CMD Cmd;
+} VBOXCMDVBVA_CTL_3DCTL_CMD;
+
+typedef struct VBOXCMDVBVA_CTL_3DCTL_CONNECT
+{
+    VBOXCMDVBVA_CTL Hdr;
+    VBOXCMDVBVA_3DCTL_CONNECT Connect;
+} VBOXCMDVBVA_CTL_3DCTL_CONNECT;
+
+typedef struct VBOXCMDVBVA_CTL_3DCTL
+{
+    VBOXCMDVBVA_CTL Hdr;
+    VBOXCMDVBVA_3DCTL Ctl;
+} VBOXCMDVBVA_CTL_3DCTL;
+
+#pragma pack()
+
+
+#ifdef VBOXVDMA_WITH_VBVA
+# pragma pack(1)
+
+typedef struct VBOXVDMAVBVACMD
+{
+    HGSMIOFFSET offCmd;
+} VBOXVDMAVBVACMD;
+
+#pragma pack()
+#endif
+
+#endif
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/include/VBox/VBoxVideoGuest.h
@@ -0,0 +1,347 @@
+/** @file
+ *
+ * VBox Host Guest Shared Memory Interface (HGSMI).
+ * OS-independent guest structures.
+ */
+
+/*
+ * Copyright (C) 2006-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+
+#ifndef __HGSMI_GUEST_h__
+#define __HGSMI_GUEST_h__
+
+#include <VBox/HGSMI/HGSMI.h>
+#include <VBox/HGSMI/HGSMIChSetup.h>
+#include <VBox/VBoxVideo.h>
+
+#ifdef VBOX_XPDM_MINIPORT
+RT_C_DECLS_BEGIN
+# include "miniport.h"
+# include "ntddvdeo.h"
+# include <Video.h>
+RT_C_DECLS_END
+#elif defined VBOX_GUESTR3XORGMOD
+# include <compiler.h>
+#else
+# include <iprt/asm-amd64-x86.h>
+#endif
+
+#ifdef VBOX_WDDM_MINIPORT
+# include "wddm/VBoxMPShgsmi.h"
+ typedef VBOXSHGSMI HGSMIGUESTCMDHEAP;
+# define HGSMIGUESTCMDHEAP_GET(_p) (&(_p)->Heap)
+#else
+ typedef HGSMIHEAP HGSMIGUESTCMDHEAP;
+# define HGSMIGUESTCMDHEAP_GET(_p) (_p)
+#endif
+
+RT_C_DECLS_BEGIN
+
+/**
+ * Structure grouping the context needed for submitting commands to the host
+ * via HGSMI
+ */
+typedef struct HGSMIGUESTCOMMANDCONTEXT
+{
+    /** Information about the memory heap located in VRAM from which data
+     * structures to be sent to the host are allocated. */
+    HGSMIGUESTCMDHEAP heapCtx;
+    /** The I/O port used for submitting commands to the host by writing their
+     * offsets into the heap. */
+    RTIOPORT port;
+} HGSMIGUESTCOMMANDCONTEXT, *PHGSMIGUESTCOMMANDCONTEXT;
+
+
+/**
+ * Structure grouping the context needed for receiving commands from the host
+ * via HGSMI
+ */
+typedef struct HGSMIHOSTCOMMANDCONTEXT
+{
+    /** Information about the memory area located in VRAM in which the host
+     * places data structures to be read by the guest. */
+    HGSMIAREA areaCtx;
+    /** Convenience structure used for matching host commands to handlers. */
+    /** @todo handlers are registered individually in code rather than just
+     * passing a static structure in order to gain extra flexibility.  There is
+     * currently no expected usage case for this though.  Is the additional
+     * complexity really justified? */
+    HGSMICHANNELINFO channels;
+    /** Flag to indicate that one thread is currently processing the command
+     * queue. */
+    volatile bool fHostCmdProcessing;
+    /* Pointer to the VRAM location where the HGSMI host flags are kept. */
+    volatile HGSMIHOSTFLAGS *pfHostFlags;
+    /** The I/O port used for receiving commands from the host as offsets into
+     * the memory area and sending back confirmations (command completion,
+     * IRQ acknowlegement). */
+    RTIOPORT port;
+} HGSMIHOSTCOMMANDCONTEXT, *PHGSMIHOSTCOMMANDCONTEXT;
+
+
+/**
+ * Structure grouping the context needed for sending graphics acceleration
+ * information to the host via VBVA.  Each screen has its own VBVA buffer.
+ */
+typedef struct VBVABUFFERCONTEXT
+{
+    /** Offset of the buffer in the VRAM section for the screen */
+    uint32_t    offVRAMBuffer;
+    /** Length of the buffer in bytes */
+    uint32_t    cbBuffer;
+    /** This flag is set if we wrote to the buffer faster than the host could
+     * read it. */
+    bool        fHwBufferOverflow;
+    /** The VBVA record that we are currently preparing for the host, NULL if
+     * none. */
+    struct VBVARECORD *pRecord;
+    /** Pointer to the VBVA buffer mapped into the current address space.  Will
+     * be NULL if VBVA is not enabled. */
+    struct VBVABUFFER *pVBVA;
+} VBVABUFFERCONTEXT, *PVBVABUFFERCONTEXT;
+
+/** @name Helper functions
+ * @{ */
+/** Write an 8-bit value to an I/O port. */
+DECLINLINE(void) VBoxVideoCmnPortWriteUchar(RTIOPORT Port, uint8_t Value)
+{
+#ifdef VBOX_XPDM_MINIPORT
+    VideoPortWritePortUchar((PUCHAR)Port, Value);
+#elif defined VBOX_GUESTR3XORGMOD
+    outb(Port, Value);
+#else  /** @todo make these explicit */
+    ASMOutU8(Port, Value);
+#endif
+}
+
+/** Write a 16-bit value to an I/O port. */
+DECLINLINE(void) VBoxVideoCmnPortWriteUshort(RTIOPORT Port, uint16_t Value)
+{
+#ifdef VBOX_XPDM_MINIPORT
+    VideoPortWritePortUshort((PUSHORT)Port,Value);
+#elif defined VBOX_GUESTR3XORGMOD
+    outw(Port, Value);
+#else
+    ASMOutU16(Port, Value);
+#endif
+}
+
+/** Write a 32-bit value to an I/O port. */
+DECLINLINE(void) VBoxVideoCmnPortWriteUlong(RTIOPORT Port, uint32_t Value)
+{
+#ifdef VBOX_XPDM_MINIPORT
+    VideoPortWritePortUlong((PULONG)Port,Value);
+#elif defined VBOX_GUESTR3XORGMOD
+    outl(Port, Value);
+#else
+    ASMOutU32(Port, Value);
+#endif
+}
+
+/** Read an 8-bit value from an I/O port. */
+DECLINLINE(uint8_t) VBoxVideoCmnPortReadUchar(RTIOPORT Port)
+{
+#ifdef VBOX_XPDM_MINIPORT
+    return VideoPortReadPortUchar((PUCHAR)Port);
+#elif defined VBOX_GUESTR3XORGMOD
+    return inb(Port);
+#else
+    return ASMInU8(Port);
+#endif
+}
+
+/** Read a 16-bit value from an I/O port. */
+DECLINLINE(uint16_t) VBoxVideoCmnPortReadUshort(RTIOPORT Port)
+{
+#ifdef VBOX_XPDM_MINIPORT
+    return VideoPortReadPortUshort((PUSHORT)Port);
+#elif defined VBOX_GUESTR3XORGMOD
+    return inw(Port);
+#else
+    return ASMInU16(Port);
+#endif
+}
+
+/** Read a 32-bit value from an I/O port. */
+DECLINLINE(uint32_t) VBoxVideoCmnPortReadUlong(RTIOPORT Port)
+{
+#ifdef VBOX_XPDM_MINIPORT
+    return VideoPortReadPortUlong((PULONG)Port);
+#elif defined VBOX_GUESTR3XORGMOD
+    return inl(Port);
+#else
+    return ASMInU32(Port);
+#endif
+}
+
+/** @}  */
+
+/** @name Base HGSMI APIs
+ * @{ */
+
+/** Acknowlege an IRQ. */
+DECLINLINE(void) VBoxHGSMIClearIrq(PHGSMIHOSTCOMMANDCONTEXT pCtx)
+{
+    VBoxVideoCmnPortWriteUlong(pCtx->port, HGSMIOFFSET_VOID);
+}
+
+RTDECL(void)     VBoxHGSMIHostCmdComplete(PHGSMIHOSTCOMMANDCONTEXT pCtx,
+                                          void *pvMem);
+RTDECL(void)     VBoxHGSMIProcessHostQueue(PHGSMIHOSTCOMMANDCONTEXT pCtx);
+RTDECL(bool)     VBoxHGSMIIsSupported(void);
+RTDECL(void *)   VBoxHGSMIBufferAlloc(PHGSMIGUESTCOMMANDCONTEXT pCtx,
+                                      HGSMISIZE cbData,
+                                      uint8_t u8Ch,
+                                      uint16_t u16Op);
+RTDECL(void)     VBoxHGSMIBufferFree(PHGSMIGUESTCOMMANDCONTEXT pCtx,
+                                     void *pvBuffer);
+RTDECL(int)      VBoxHGSMIBufferSubmit(PHGSMIGUESTCOMMANDCONTEXT pCtx,
+                                       void *pvBuffer);
+RTDECL(void)     VBoxHGSMIGetBaseMappingInfo(uint32_t cbVRAM,
+                                             uint32_t *poffVRAMBaseMapping,
+                                             uint32_t *pcbMapping,
+                                             uint32_t *poffGuestHeapMemory,
+                                             uint32_t *pcbGuestHeapMemory,
+                                             uint32_t *poffHostFlags);
+RTDECL(int)      VBoxHGSMIReportFlagsLocation(PHGSMIGUESTCOMMANDCONTEXT pCtx,
+                                              HGSMIOFFSET offLocation);
+RTDECL(int)      VBoxHGSMISendCapsInfo(PHGSMIGUESTCOMMANDCONTEXT pCtx,
+                                       uint32_t fCaps);
+/** @todo we should provide a cleanup function too as part of the API */
+RTDECL(int)      VBoxHGSMISetupGuestContext(PHGSMIGUESTCOMMANDCONTEXT pCtx,
+                                            void *pvGuestHeapMemory,
+                                            uint32_t cbGuestHeapMemory,
+                                            uint32_t offVRAMGuestHeapMemory,
+                                            const HGSMIENV *pEnv);
+RTDECL(void)     VBoxHGSMIGetHostAreaMapping(PHGSMIGUESTCOMMANDCONTEXT pCtx,
+                                             uint32_t cbVRAM,
+                                             uint32_t offVRAMBaseMapping,
+                                             uint32_t *poffVRAMHostArea,
+                                             uint32_t *pcbHostArea);
+RTDECL(void)     VBoxHGSMISetupHostContext(PHGSMIHOSTCOMMANDCONTEXT pCtx,
+                                           void *pvBaseMapping,
+                                           uint32_t offHostFlags,
+                                           void *pvHostAreaMapping,
+                                           uint32_t offVRAMHostArea,
+                                           uint32_t cbHostArea);
+RTDECL(int)      VBoxHGSMISendHostCtxInfo(PHGSMIGUESTCOMMANDCONTEXT pCtx,
+                                          HGSMIOFFSET offVRAMFlagsLocation,
+                                          uint32_t fCaps,
+                                          uint32_t offVRAMHostArea,
+                                          uint32_t cbHostArea);
+RTDECL(int)      VBoxQueryConfHGSMI(PHGSMIGUESTCOMMANDCONTEXT pCtx,
+                                    uint32_t u32Index, uint32_t *pulValue);
+RTDECL(int)      VBoxQueryConfHGSMIDef(PHGSMIGUESTCOMMANDCONTEXT pCtx,
+                                       uint32_t u32Index, uint32_t u32DefValue, uint32_t *pulValue);
+RTDECL(int)      VBoxHGSMIUpdatePointerShape(PHGSMIGUESTCOMMANDCONTEXT pCtx,
+                                             uint32_t fFlags,
+                                             uint32_t cHotX,
+                                             uint32_t cHotY,
+                                             uint32_t cWidth,
+                                             uint32_t cHeight,
+                                             uint8_t *pPixels,
+                                             uint32_t cbLength);
+RTDECL(int)      VBoxHGSMICursorPosition(PHGSMIGUESTCOMMANDCONTEXT pCtx, bool fReportPosition, uint32_t x, uint32_t y,
+                                         uint32_t *pxHost, uint32_t *pyHost);
+
+/** @}  */
+
+/** @name VBVA APIs
+ * @{ */
+RTDECL(bool) VBoxVBVAEnable(PVBVABUFFERCONTEXT pCtx,
+                            PHGSMIGUESTCOMMANDCONTEXT pHGSMICtx,
+                            struct VBVABUFFER *pVBVA, int32_t cScreen);
+RTDECL(void) VBoxVBVADisable(PVBVABUFFERCONTEXT pCtx,
+                             PHGSMIGUESTCOMMANDCONTEXT pHGSMICtx,
+                             int32_t cScreen);
+RTDECL(bool) VBoxVBVABufferBeginUpdate(PVBVABUFFERCONTEXT pCtx,
+                                       PHGSMIGUESTCOMMANDCONTEXT pHGSMICtx);
+RTDECL(void) VBoxVBVABufferEndUpdate(PVBVABUFFERCONTEXT pCtx);
+RTDECL(bool) VBoxVBVAWrite(PVBVABUFFERCONTEXT pCtx,
+                           PHGSMIGUESTCOMMANDCONTEXT pHGSMICtx,
+                           const void *pv, uint32_t cb);
+RTDECL(bool) VBoxVBVAOrderSupported(PVBVABUFFERCONTEXT pCtx, unsigned code);
+RTDECL(void) VBoxVBVASetupBufferContext(PVBVABUFFERCONTEXT pCtx,
+                                        uint32_t offVRAMBuffer,
+                                        uint32_t cbBuffer);
+
+/** @}  */
+
+/** @name Modesetting APIs
+ * @{ */
+
+RTDECL(uint32_t) VBoxHGSMIGetMonitorCount(PHGSMIGUESTCOMMANDCONTEXT pCtx);
+RTDECL(uint32_t) VBoxVideoGetVRAMSize(void);
+RTDECL(bool)     VBoxVideoAnyWidthAllowed(void);
+RTDECL(uint16_t) VBoxHGSMIGetScreenFlags(PHGSMIGUESTCOMMANDCONTEXT pCtx);
+
+struct VBVAINFOVIEW;
+/**
+ * Callback funtion called from @a VBoxHGSMISendViewInfo to initialise
+ * the @a VBVAINFOVIEW structure for each screen.
+ *
+ * @returns  iprt status code
+ * @param  pvData  context data for the callback, passed to @a
+ *                 VBoxHGSMISendViewInfo along with the callback
+ * @param  pInfo   array of @a VBVAINFOVIEW structures to be filled in
+ * @todo  explicitly pass the array size
+ */
+typedef DECLCALLBACK(int) FNHGSMIFILLVIEWINFO(void *pvData,
+                                              struct VBVAINFOVIEW *pInfo,
+                                              uint32_t cViews);
+/** Pointer to a FNHGSMIFILLVIEWINFO callback */
+typedef FNHGSMIFILLVIEWINFO *PFNHGSMIFILLVIEWINFO;
+
+RTDECL(int)      VBoxHGSMISendViewInfo(PHGSMIGUESTCOMMANDCONTEXT pCtx,
+                                       uint32_t u32Count,
+                                       PFNHGSMIFILLVIEWINFO pfnFill,
+                                       void *pvData);
+RTDECL(void)     VBoxVideoSetModeRegisters(uint16_t cWidth, uint16_t cHeight,
+                                           uint16_t cVirtWidth, uint16_t cBPP,
+                                           uint16_t fFlags,
+                                           uint16_t cx, uint16_t cy);
+RTDECL(bool)     VBoxVideoGetModeRegisters(uint16_t *pcWidth,
+                                           uint16_t *pcHeight,
+                                           uint16_t *pcVirtWidth,
+                                           uint16_t *pcBPP,
+                                           uint16_t *pfFlags);
+RTDECL(void)     VBoxVideoDisableVBE(void);
+RTDECL(void)     VBoxHGSMIProcessDisplayInfo(PHGSMIGUESTCOMMANDCONTEXT pCtx,
+                                             uint32_t cDisplay,
+                                             int32_t  cOriginX,
+                                             int32_t  cOriginY,
+                                             uint32_t offStart,
+                                             uint32_t cbPitch,
+                                             uint32_t cWidth,
+                                             uint32_t cHeight,
+                                             uint16_t cBPP,
+                                             uint16_t fFlags);
+RTDECL(int)      VBoxHGSMIUpdateInputMapping(PHGSMIGUESTCOMMANDCONTEXT pCtx, int32_t  cOriginX, int32_t  cOriginY,
+                                             uint32_t cWidth, uint32_t cHeight);
+RTDECL(int) VBoxHGSMIGetModeHints(PHGSMIGUESTCOMMANDCONTEXT pCtx,
+                                  unsigned cScreens, VBVAMODEHINT *paHints);
+
+/** @}  */
+
+RT_C_DECLS_END
+
+#endif /* __HGSMI_GUEST_h__*/
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/include/VBox/VMMDev.h
@@ -0,0 +1,2210 @@
+/** @file
+ * Virtual Device for Guest <-> VMM/Host communication (ADD,DEV).
+ */
+
+/*
+ * Copyright (C) 2006-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+#ifndef ___VBox_VMMDev_h
+#define ___VBox_VMMDev_h
+
+#include <VBox/cdefs.h>
+#include <VBox/param.h>                 /* for the PCI IDs. */
+#include <VBox/types.h>
+#include <VBox/err.h>
+#include <VBox/ostypes.h>
+#include <VBox/VMMDev2.h>
+#include <iprt/assert.h>
+
+
+#pragma pack(4) /* force structure dword packing here. */
+RT_C_DECLS_BEGIN
+
+
+/** @defgroup grp_vmmdev    VMM Device
+ *
+ * @note This interface cannot be changed, it can only be extended!
+ *
+ * @{
+ */
+
+
+/** Size of VMMDev RAM region accessible by guest.
+ * Must be big enough to contain VMMDevMemory structure (see further down).
+ * For now: 4 megabyte.
+ */
+#define VMMDEV_RAM_SIZE                                     (4 * 256 * PAGE_SIZE)
+
+/** Size of VMMDev heap region accessible by guest.
+ *  (Must be a power of two (pci range).)
+ */
+#define VMMDEV_HEAP_SIZE                                    (4 * PAGE_SIZE)
+
+/** Port for generic request interface (relative offset). */
+#define VMMDEV_PORT_OFF_REQUEST                             0
+
+
+/** @name VMMDev events.
+ *
+ * Used mainly by VMMDevReq_AcknowledgeEvents/VMMDevEvents and version 1.3 of
+ * VMMDevMemory.
+ *
+ * @{
+ */
+/** Host mouse capabilities has been changed. */
+#define VMMDEV_EVENT_MOUSE_CAPABILITIES_CHANGED             RT_BIT(0)
+/** HGCM event. */
+#define VMMDEV_EVENT_HGCM                                   RT_BIT(1)
+/** A display change request has been issued. */
+#define VMMDEV_EVENT_DISPLAY_CHANGE_REQUEST                 RT_BIT(2)
+/** Credentials are available for judgement. */
+#define VMMDEV_EVENT_JUDGE_CREDENTIALS                      RT_BIT(3)
+/** The guest has been restored. */
+#define VMMDEV_EVENT_RESTORED                               RT_BIT(4)
+/** Seamless mode state changed. */
+#define VMMDEV_EVENT_SEAMLESS_MODE_CHANGE_REQUEST           RT_BIT(5)
+/** Memory balloon size changed. */
+#define VMMDEV_EVENT_BALLOON_CHANGE_REQUEST                 RT_BIT(6)
+/** Statistics interval changed. */
+#define VMMDEV_EVENT_STATISTICS_INTERVAL_CHANGE_REQUEST     RT_BIT(7)
+/** VRDP status changed. */
+#define VMMDEV_EVENT_VRDP                                   RT_BIT(8)
+/** New mouse position data available. */
+#define VMMDEV_EVENT_MOUSE_POSITION_CHANGED                 RT_BIT(9)
+/** CPU hotplug event occurred. */
+#define VMMDEV_EVENT_CPU_HOTPLUG                            RT_BIT(10)
+/** The mask of valid events, for sanity checking. */
+#define VMMDEV_EVENT_VALID_EVENT_MASK                       UINT32_C(0x000007ff)
+/** @} */
+
+
+/** @defgroup grp_vmmdev_req    VMMDev Generic Request Interface
+ * @{
+ */
+
+/** @name Current version of the VMMDev interface.
+ *
+ * Additions are allowed to work only if
+ * additions_major == vmmdev_current && additions_minor <= vmmdev_current.
+ * Additions version is reported to host (VMMDev) by VMMDevReq_ReportGuestInfo.
+ *
+ * @remarks These defines also live in the 16-bit and assembly versions of this
+ *          header.
+ */
+#define VMMDEV_VERSION                      0x00010004
+#define VMMDEV_VERSION_MAJOR                (VMMDEV_VERSION >> 16)
+#define VMMDEV_VERSION_MINOR                (VMMDEV_VERSION & 0xffff)
+/** @} */
+
+/** Maximum request packet size. */
+#define VMMDEV_MAX_VMMDEVREQ_SIZE           _1M
+/** Maximum number of HGCM parameters. */
+#define VMMDEV_MAX_HGCM_PARMS               1024
+/** Maximum total size of hgcm buffers in one call. */
+#define VMMDEV_MAX_HGCM_DATA_SIZE           UINT32_C(0x7FFFFFFF)
+
+/**
+ * VMMDev request types.
+ * @note when updating this, adjust vmmdevGetRequestSize() as well
+ */
+typedef enum
+{
+    VMMDevReq_InvalidRequest             =  0,
+    VMMDevReq_GetMouseStatus             =  1,
+    VMMDevReq_SetMouseStatus             =  2,
+    VMMDevReq_SetPointerShape            =  3,
+    VMMDevReq_GetHostVersion             =  4,
+    VMMDevReq_Idle                       =  5,
+    VMMDevReq_GetHostTime                = 10,
+    VMMDevReq_GetHypervisorInfo          = 20,
+    VMMDevReq_SetHypervisorInfo          = 21,
+    VMMDevReq_RegisterPatchMemory        = 22, /* since version 3.0.6 */
+    VMMDevReq_DeregisterPatchMemory      = 23, /* since version 3.0.6 */
+    VMMDevReq_SetPowerStatus             = 30,
+    VMMDevReq_AcknowledgeEvents          = 41,
+    VMMDevReq_CtlGuestFilterMask         = 42,
+    VMMDevReq_ReportGuestInfo            = 50,
+    VMMDevReq_ReportGuestInfo2           = 58, /* since version 3.2.0 */
+    VMMDevReq_ReportGuestStatus          = 59, /* since version 3.2.8 */
+    VMMDevReq_ReportGuestUserState       = 74, /* since version 4.3 */
+    /**
+     * Retrieve a display resize request sent by the host using
+     * @a IDisplay:setVideoModeHint.  Deprecated.
+     *
+     * Similar to @a VMMDevReq_GetDisplayChangeRequest2, except that it only
+     * considers host requests sent for the first virtual display.  This guest
+     * request should not be used in new guest code, and the results are
+     * undefined if a guest mixes calls to this and
+     * @a VMMDevReq_GetDisplayChangeRequest2.
+     */
+    VMMDevReq_GetDisplayChangeRequest    = 51,
+    VMMDevReq_VideoModeSupported         = 52,
+    VMMDevReq_GetHeightReduction         = 53,
+    /**
+     * Retrieve a display resize request sent by the host using
+     * @a IDisplay:setVideoModeHint.
+     *
+     * Queries a display resize request sent from the host.  If the
+     * @a eventAck member is sent to true and there is an unqueried
+     * request available for one of the virtual display then that request will
+     * be returned.  If several displays have unqueried requests the lowest
+     * numbered display will be chosen first.  Only the most recent unseen
+     * request for each display is remembered.
+     * If @a eventAck is set to false, the last host request queried with
+     * @a eventAck set is resent, or failing that the most recent received from
+     * the host.  If no host request was ever received then all zeros are
+     * returned.
+     */
+    VMMDevReq_GetDisplayChangeRequest2   = 54,
+    VMMDevReq_ReportGuestCapabilities    = 55,
+    VMMDevReq_SetGuestCapabilities       = 56,
+    VMMDevReq_VideoModeSupported2        = 57, /* since version 3.2.0 */
+    VMMDevReq_GetDisplayChangeRequestEx  = 80, /* since version 4.2.4 */
+#ifdef VBOX_WITH_HGCM
+    VMMDevReq_HGCMConnect                = 60,
+    VMMDevReq_HGCMDisconnect             = 61,
+#ifdef VBOX_WITH_64_BITS_GUESTS
+    VMMDevReq_HGCMCall32                 = 62,
+    VMMDevReq_HGCMCall64                 = 63,
+#else
+    VMMDevReq_HGCMCall                   = 62,
+#endif /* VBOX_WITH_64_BITS_GUESTS */
+    VMMDevReq_HGCMCancel                 = 64,
+    VMMDevReq_HGCMCancel2                = 65,
+#endif
+    VMMDevReq_VideoAccelEnable           = 70,
+    VMMDevReq_VideoAccelFlush            = 71,
+    VMMDevReq_VideoSetVisibleRegion      = 72,
+    VMMDevReq_GetSeamlessChangeRequest   = 73,
+    VMMDevReq_QueryCredentials           = 100,
+    VMMDevReq_ReportCredentialsJudgement = 101,
+    VMMDevReq_ReportGuestStats           = 110,
+    VMMDevReq_GetMemBalloonChangeRequest = 111,
+    VMMDevReq_GetStatisticsChangeRequest = 112,
+    VMMDevReq_ChangeMemBalloon           = 113,
+    VMMDevReq_GetVRDPChangeRequest       = 150,
+    VMMDevReq_LogString                  = 200,
+    VMMDevReq_GetCpuHotPlugRequest       = 210,
+    VMMDevReq_SetCpuHotPlugStatus        = 211,
+    VMMDevReq_RegisterSharedModule       = 212,
+    VMMDevReq_UnregisterSharedModule     = 213,
+    VMMDevReq_CheckSharedModules         = 214,
+    VMMDevReq_GetPageSharingStatus       = 215,
+    VMMDevReq_DebugIsPageShared          = 216,
+    VMMDevReq_GetSessionId               = 217, /* since version 3.2.8 */
+    VMMDevReq_WriteCoreDump              = 218,
+    VMMDevReq_GuestHeartbeat             = 219,
+    VMMDevReq_HeartbeatConfigure         = 220,
+    VMMDevReq_SizeHack                   = 0x7fffffff
+} VMMDevRequestType;
+
+#ifdef VBOX_WITH_64_BITS_GUESTS
+/*
+ * Constants and structures are redefined for the guest.
+ *
+ * Host code MUST always use either *32 or *64 variant explicitely.
+ * Host source code will use VBOX_HGCM_HOST_CODE define to catch undefined
+ * data types and constants.
+ *
+ * This redefinition means that the new additions builds will use
+ * the *64 or *32 variants depending on the current architecture bit count (ARCH_BITS).
+ */
+# ifndef VBOX_HGCM_HOST_CODE
+#  if ARCH_BITS == 64
+#   define VMMDevReq_HGCMCall VMMDevReq_HGCMCall64
+#  elif ARCH_BITS == 32
+#   define VMMDevReq_HGCMCall VMMDevReq_HGCMCall32
+#  else
+#   error "Unsupported ARCH_BITS"
+#  endif
+# endif /* !VBOX_HGCM_HOST_CODE */
+#endif /* VBOX_WITH_64_BITS_GUESTS */
+
+/** Version of VMMDevRequestHeader structure. */
+#define VMMDEV_REQUEST_HEADER_VERSION (0x10001)
+
+
+/**
+ * Generic VMMDev request header.
+ */
+typedef struct
+{
+    /** IN: Size of the structure in bytes (including body). */
+    uint32_t size;
+    /** IN: Version of the structure.  */
+    uint32_t version;
+    /** IN: Type of the request. */
+    VMMDevRequestType requestType;
+    /** OUT: Return code. */
+    int32_t  rc;
+    /** Reserved field no.1. MBZ. */
+    uint32_t reserved1;
+    /** Reserved field no.2. MBZ. */
+    uint32_t reserved2;
+} VMMDevRequestHeader;
+AssertCompileSize(VMMDevRequestHeader, 24);
+
+
+/**
+ * Mouse status request structure.
+ *
+ * Used by VMMDevReq_GetMouseStatus and VMMDevReq_SetMouseStatus.
+ */
+typedef struct
+{
+    /** header */
+    VMMDevRequestHeader header;
+    /** Mouse feature mask. See VMMDEV_MOUSE_*. */
+    uint32_t mouseFeatures;
+    /** Mouse x position. */
+    int32_t pointerXPos;
+    /** Mouse y position. */
+    int32_t pointerYPos;
+} VMMDevReqMouseStatus;
+AssertCompileSize(VMMDevReqMouseStatus, 24+12);
+
+/** @name Mouse capability bits (VMMDevReqMouseStatus::mouseFeatures).
+ * @{ */
+/** The guest can (== wants to) handle absolute coordinates.  */
+#define VMMDEV_MOUSE_GUEST_CAN_ABSOLUTE                     RT_BIT(0)
+/** The host can (== wants to) send absolute coordinates.
+ * (Input not captured.) */
+#define VMMDEV_MOUSE_HOST_WANTS_ABSOLUTE                    RT_BIT(1)
+/** The guest can *NOT* switch to software cursor and therefore depends on the
+ * host cursor.
+ *
+ * When guest additions are installed and the host has promised to display the
+ * cursor itself, the guest installs a hardware mouse driver. Don't ask the
+ * guest to switch to a software cursor then. */
+#define VMMDEV_MOUSE_GUEST_NEEDS_HOST_CURSOR                RT_BIT(2)
+/** The host does NOT provide support for drawing the cursor itself. */
+#define VMMDEV_MOUSE_HOST_CANNOT_HWPOINTER                  RT_BIT(3)
+/** The guest can read VMMDev events to find out about pointer movement */
+#define VMMDEV_MOUSE_NEW_PROTOCOL                           RT_BIT(4)
+/** If the guest changes the status of the
+ * VMMDEV_MOUSE_GUEST_NEEDS_HOST_CURSOR bit, the host will honour this */
+#define VMMDEV_MOUSE_HOST_RECHECKS_NEEDS_HOST_CURSOR        RT_BIT(5)
+/** The host supplies an absolute pointing device.  The Guest Additions may
+ * wish to use this to decide whether to install their own driver */
+#define VMMDEV_MOUSE_HOST_HAS_ABS_DEV                       RT_BIT(6)
+/** The mask of all VMMDEV_MOUSE_* flags */
+#define VMMDEV_MOUSE_MASK                                   UINT32_C(0x0000007f)
+/** The mask of guest capability changes for which notification events should
+ * be sent */
+#define VMMDEV_MOUSE_NOTIFY_HOST_MASK \
+      (VMMDEV_MOUSE_GUEST_CAN_ABSOLUTE | VMMDEV_MOUSE_GUEST_NEEDS_HOST_CURSOR)
+/** The mask of all capabilities which the guest can legitimately change */
+#define VMMDEV_MOUSE_GUEST_MASK \
+      (VMMDEV_MOUSE_NOTIFY_HOST_MASK | VMMDEV_MOUSE_NEW_PROTOCOL)
+/** The mask of host capability changes for which notification events should
+ * be sent */
+#define VMMDEV_MOUSE_NOTIFY_GUEST_MASK \
+      VMMDEV_MOUSE_HOST_WANTS_ABSOLUTE
+/** The mask of all capabilities which the host can legitimately change */
+#define VMMDEV_MOUSE_HOST_MASK \
+      (  VMMDEV_MOUSE_NOTIFY_GUEST_MASK \
+       | VMMDEV_MOUSE_HOST_CANNOT_HWPOINTER \
+       | VMMDEV_MOUSE_HOST_RECHECKS_NEEDS_HOST_CURSOR \
+       | VMMDEV_MOUSE_HOST_HAS_ABS_DEV)
+/** @} */
+
+/** @name Absolute mouse reporting range
+ * @{ */
+/** @todo Should these be here?  They are needed by both host and guest. */
+/** The minumum value our pointing device can return. */
+#define VMMDEV_MOUSE_RANGE_MIN 0
+/** The maximum value our pointing device can return. */
+#define VMMDEV_MOUSE_RANGE_MAX 0xFFFF
+/** The full range our pointing device can return. */
+#define VMMDEV_MOUSE_RANGE (VMMDEV_MOUSE_RANGE_MAX - VMMDEV_MOUSE_RANGE_MIN)
+/** @} */
+
+
+/**
+ * Mouse pointer shape/visibility change request.
+ *
+ * Used by VMMDevReq_SetPointerShape. The size is variable.
+ */
+typedef struct VMMDevReqMousePointer
+{
+    /** Header. */
+    VMMDevRequestHeader header;
+    /** VBOX_MOUSE_POINTER_* bit flags. */
+    uint32_t fFlags;
+    /** x coordinate of hot spot. */
+    uint32_t xHot;
+    /** y coordinate of hot spot. */
+    uint32_t yHot;
+    /** Width of the pointer in pixels. */
+    uint32_t width;
+    /** Height of the pointer in scanlines. */
+    uint32_t height;
+    /** Pointer data.
+     *
+     ****
+     * The data consists of 1 bpp AND mask followed by 32 bpp XOR (color) mask.
+     *
+     * For pointers without alpha channel the XOR mask pixels are 32 bit values: (lsb)BGR0(msb).
+     * For pointers with alpha channel the XOR mask consists of (lsb)BGRA(msb) 32 bit values.
+     *
+     * Guest driver must create the AND mask for pointers with alpha channel, so if host does not
+     * support alpha, the pointer could be displayed as a normal color pointer. The AND mask can
+     * be constructed from alpha values. For example alpha value >= 0xf0 means bit 0 in the AND mask.
+     *
+     * The AND mask is 1 bpp bitmap with byte aligned scanlines. Size of AND mask,
+     * therefore, is cbAnd = (width + 7) / 8 * height. The padding bits at the
+     * end of any scanline are undefined.
+     *
+     * The XOR mask follows the AND mask on the next 4 bytes aligned offset:
+     * uint8_t *pXor = pAnd + (cbAnd + 3) & ~3
+     * Bytes in the gap between the AND and the XOR mask are undefined.
+     * XOR mask scanlines have no gap between them and size of XOR mask is:
+     * cXor = width * 4 * height.
+     ****
+     *
+     * Preallocate 4 bytes for accessing actual data as p->pointerData.
+     */
+    char pointerData[4];
+} VMMDevReqMousePointer;
+AssertCompileSize(VMMDevReqMousePointer, 24+24);
+
+/**
+ * Get the size that a VMMDevReqMousePointer request should have for a given
+ * size of cursor, including the trailing cursor image and mask data.
+ * @note an "empty" request still has the four preallocated bytes of data
+ *
+ * @returns the size
+ * @param  width   the cursor width
+ * @param  height  the cursor height
+ */
+DECLINLINE(size_t) vmmdevGetMousePointerReqSize(uint32_t width, uint32_t height)
+{
+    size_t cbBase = RT_OFFSETOF(VMMDevReqMousePointer, pointerData);
+    size_t cbMask = (width + 7) / 8 * height;
+    size_t cbArgb = width * height * 4;
+    return RT_MAX(cbBase + ((cbMask + 3) & ~3) + cbArgb,
+                  sizeof(VMMDevReqMousePointer));
+}
+
+/** @name VMMDevReqMousePointer::fFlags
+ * @note The VBOX_MOUSE_POINTER_* flags are used in the guest video driver,
+ *       values must be <= 0x8000 and must not be changed. (try make more sense
+ *       of this, please).
+ * @{
+ */
+/** pointer is visible */
+#define VBOX_MOUSE_POINTER_VISIBLE (0x0001)
+/** pointer has alpha channel */
+#define VBOX_MOUSE_POINTER_ALPHA   (0x0002)
+/** pointerData contains new pointer shape */
+#define VBOX_MOUSE_POINTER_SHAPE   (0x0004)
+/** @} */
+
+
+/**
+ * String log request structure.
+ *
+ * Used by VMMDevReq_LogString.
+ * @deprecated  Use the IPRT logger or VbglR3WriteLog instead.
+ */
+typedef struct
+{
+    /** header */
+    VMMDevRequestHeader header;
+    /** variable length string data */
+    char szString[1];
+} VMMDevReqLogString;
+AssertCompileSize(VMMDevReqLogString, 24+4);
+
+
+/**
+ * VirtualBox host version request structure.
+ *
+ * Used by VMMDevReq_GetHostVersion.
+ *
+ * @remarks VBGL uses this to detect the precense of new features in the
+ *          interface.
+ */
+typedef struct
+{
+    /** Header. */
+    VMMDevRequestHeader header;
+    /** Major version. */
+    uint16_t major;
+    /** Minor version. */
+    uint16_t minor;
+    /** Build number. */
+    uint32_t build;
+    /** SVN revision. */
+    uint32_t revision;
+    /** Feature mask. */
+    uint32_t features;
+} VMMDevReqHostVersion;
+AssertCompileSize(VMMDevReqHostVersion, 24+16);
+
+/** @name VMMDevReqHostVersion::features
+ * @{ */
+/** Physical page lists are supported by HGCM. */
+#define VMMDEV_HVF_HGCM_PHYS_PAGE_LIST  RT_BIT(0)
+/** @} */
+
+
+/**
+ * Guest capabilities structure.
+ *
+ * Used by VMMDevReq_ReportGuestCapabilities.
+ */
+typedef struct
+{
+    /** Header. */
+    VMMDevRequestHeader header;
+    /** Capabilities (VMMDEV_GUEST_*). */
+    uint32_t caps;
+} VMMDevReqGuestCapabilities;
+AssertCompileSize(VMMDevReqGuestCapabilities, 24+4);
+
+/**
+ * Guest capabilities structure, version 2.
+ *
+ * Used by VMMDevReq_SetGuestCapabilities.
+ */
+typedef struct
+{
+    /** Header. */
+    VMMDevRequestHeader header;
+    /** Mask of capabilities to be added. */
+    uint32_t u32OrMask;
+    /** Mask of capabilities to be removed. */
+    uint32_t u32NotMask;
+} VMMDevReqGuestCapabilities2;
+AssertCompileSize(VMMDevReqGuestCapabilities2, 24+8);
+
+/** @name Guest capability bits.
+ * Used by VMMDevReq_ReportGuestCapabilities and VMMDevReq_SetGuestCapabilities.
+ * @{ */
+/** The guest supports seamless display rendering. */
+#define VMMDEV_GUEST_SUPPORTS_SEAMLESS                      RT_BIT_32(0)
+/** The guest supports mapping guest to host windows. */
+#define VMMDEV_GUEST_SUPPORTS_GUEST_HOST_WINDOW_MAPPING     RT_BIT_32(1)
+/** The guest graphical additions are active.
+ * Used for fast activation and deactivation of certain graphical operations
+ * (e.g. resizing & seamless). The legacy VMMDevReq_ReportGuestCapabilities
+ * request sets this automatically, but VMMDevReq_SetGuestCapabilities does
+ * not. */
+#define VMMDEV_GUEST_SUPPORTS_GRAPHICS                      RT_BIT_32(2)
+/** The mask of valid events, for sanity checking. */
+#define VMMDEV_GUEST_CAPABILITIES_MASK                      UINT32_C(0x00000007)
+/** @} */
+
+
+/**
+ * Idle request structure.
+ *
+ * Used by VMMDevReq_Idle.
+ */
+typedef struct
+{
+    /** Header. */
+    VMMDevRequestHeader header;
+} VMMDevReqIdle;
+AssertCompileSize(VMMDevReqIdle, 24);
+
+
+/**
+ * Host time request structure.
+ *
+ * Used by VMMDevReq_GetHostTime.
+ */
+typedef struct
+{
+    /** Header */
+    VMMDevRequestHeader header;
+    /** OUT: Time in milliseconds since unix epoch. */
+    uint64_t time;
+} VMMDevReqHostTime;
+AssertCompileSize(VMMDevReqHostTime, 24+8);
+
+
+/**
+ * Hypervisor info structure.
+ *
+ * Used by VMMDevReq_GetHypervisorInfo and VMMDevReq_SetHypervisorInfo.
+ */
+typedef struct
+{
+    /** Header. */
+    VMMDevRequestHeader header;
+    /** Guest virtual address of proposed hypervisor start.
+     * Not used by VMMDevReq_GetHypervisorInfo.
+     * @todo Make this 64-bit compatible? */
+    RTGCPTR32 hypervisorStart;
+    /** Hypervisor size in bytes. */
+    uint32_t hypervisorSize;
+} VMMDevReqHypervisorInfo;
+AssertCompileSize(VMMDevReqHypervisorInfo, 24+8);
+
+/** @name Default patch memory size .
+ * Used by VMMDevReq_RegisterPatchMemory and VMMDevReq_DeregisterPatchMemory.
+ * @{ */
+#define VMMDEV_GUEST_DEFAULT_PATCHMEM_SIZE          8192
+/** @} */
+
+/**
+ * Patching memory structure. (locked executable & read-only page from the guest's perspective)
+ *
+ * Used by VMMDevReq_RegisterPatchMemory and VMMDevReq_DeregisterPatchMemory
+ */
+typedef struct
+{
+    /** Header. */
+    VMMDevRequestHeader header;
+    /** Guest virtual address of the patching page(s). */
+    RTGCPTR64           pPatchMem;
+    /** Patch page size in bytes. */
+    uint32_t            cbPatchMem;
+} VMMDevReqPatchMemory;
+AssertCompileSize(VMMDevReqPatchMemory, 24+12);
+
+
+/**
+ * Guest power requests.
+ *
+ * See VMMDevReq_SetPowerStatus and VMMDevPowerStateRequest.
+ */
+typedef enum
+{
+    VMMDevPowerState_Invalid   = 0,
+    VMMDevPowerState_Pause     = 1,
+    VMMDevPowerState_PowerOff  = 2,
+    VMMDevPowerState_SaveState = 3,
+    VMMDevPowerState_SizeHack = 0x7fffffff
+} VMMDevPowerState;
+AssertCompileSize(VMMDevPowerState, 4);
+
+/**
+ * VM power status structure.
+ *
+ * Used by VMMDevReq_SetPowerStatus.
+ */
+typedef struct
+{
+    /** Header. */
+    VMMDevRequestHeader header;
+    /** Power state request. */
+    VMMDevPowerState powerState;
+} VMMDevPowerStateRequest;
+AssertCompileSize(VMMDevPowerStateRequest, 24+4);
+
+
+/**
+ * Pending events structure.
+ *
+ * Used by VMMDevReq_AcknowledgeEvents.
+ */
+typedef struct
+{
+    /** Header. */
+    VMMDevRequestHeader header;
+    /** OUT: Pending event mask. */
+    uint32_t events;
+} VMMDevEvents;
+AssertCompileSize(VMMDevEvents, 24+4);
+
+
+/**
+ * Guest event filter mask control.
+ *
+ * Used by VMMDevReq_CtlGuestFilterMask.
+ */
+typedef struct
+{
+    /** Header. */
+    VMMDevRequestHeader header;
+    /** Mask of events to be added to the filter. */
+    uint32_t u32OrMask;
+    /** Mask of events to be removed from the filter. */
+    uint32_t u32NotMask;
+} VMMDevCtlGuestFilterMask;
+AssertCompileSize(VMMDevCtlGuestFilterMask, 24+8);
+
+
+/**
+ * Guest information structure.
+ *
+ * Used by VMMDevReportGuestInfo and PDMIVMMDEVCONNECTOR::pfnUpdateGuestVersion.
+ */
+typedef struct VBoxGuestInfo
+{
+    /** The VMMDev interface version expected by additions.
+      * *Deprecated*, do not use anymore! Will be removed. */
+    uint32_t interfaceVersion;
+    /** Guest OS type. */
+    VBOXOSTYPE osType;
+} VBoxGuestInfo;
+AssertCompileSize(VBoxGuestInfo, 8);
+
+/**
+ * Guest information report.
+ *
+ * Used by VMMDevReq_ReportGuestInfo.
+ */
+typedef struct
+{
+    /** Header. */
+    VMMDevRequestHeader header;
+    /** Guest information. */
+    VBoxGuestInfo guestInfo;
+} VMMDevReportGuestInfo;
+AssertCompileSize(VMMDevReportGuestInfo, 24+8);
+
+
+/**
+ * Guest information structure, version 2.
+ *
+ * Used by VMMDevReportGuestInfo2 and PDMIVMMDEVCONNECTOR::pfnUpdateGuestVersion2.
+ */
+typedef struct VBoxGuestInfo2
+{
+    /** Major version. */
+    uint16_t additionsMajor;
+    /** Minor version. */
+    uint16_t additionsMinor;
+    /** Build number. */
+    uint32_t additionsBuild;
+    /** SVN revision. */
+    uint32_t additionsRevision;
+    /** Feature mask, currently unused. */
+    uint32_t additionsFeatures;
+    /** The intentional meaning of this field was:
+     * Some additional information, for example 'Beta 1' or something like that.
+     *
+     * The way it was implemented was implemented: VBOX_VERSION_STRING.
+     *
+     * This means the first three members are duplicated in this field (if the guest
+     * build config is sane). So, the user must check this and chop it off before
+     * usage.  There is, because of the Main code's blind trust in the field's
+     * content, no way back. */
+    char     szName[128];
+} VBoxGuestInfo2;
+AssertCompileSize(VBoxGuestInfo2, 144);
+
+/**
+ * Guest information report, version 2.
+ *
+ * Used by VMMDevReq_ReportGuestInfo2.
+ */
+typedef struct
+{
+    /** Header. */
+    VMMDevRequestHeader header;
+    /** Guest information. */
+    VBoxGuestInfo2 guestInfo;
+} VMMDevReportGuestInfo2;
+AssertCompileSize(VMMDevReportGuestInfo2, 24+144);
+
+
+/**
+ * The guest facility.
+ * This needs to be kept in sync with AdditionsFacilityType of the Main API!
+ */
+typedef enum
+{
+    VBoxGuestFacilityType_Unknown         = 0,
+    VBoxGuestFacilityType_VBoxGuestDriver = 20,
+    VBoxGuestFacilityType_AutoLogon       = 90,  /* VBoxGINA / VBoxCredProv / pam_vbox. */
+    VBoxGuestFacilityType_VBoxService     = 100,
+    VBoxGuestFacilityType_VBoxTrayClient  = 101, /* VBoxTray (Windows), VBoxClient (Linux, Unix). */
+    VBoxGuestFacilityType_Seamless        = 1000,
+    VBoxGuestFacilityType_Graphics        = 1100,
+    VBoxGuestFacilityType_All             = 0x7ffffffe,
+    VBoxGuestFacilityType_SizeHack        = 0x7fffffff
+} VBoxGuestFacilityType;
+AssertCompileSize(VBoxGuestFacilityType, 4);
+
+
+/**
+ * The current guest status of a facility.
+ * This needs to be kept in sync with AdditionsFacilityStatus of the Main API!
+ *
+ * @remarks r=bird: Pretty please, for future types like this, simply do a
+ *          linear allocation without any gaps.  This stuff is impossible work
+ *          efficiently with, let alone validate.  Applies to the other facility
+ *          enums too.
+ */
+typedef enum
+{
+    VBoxGuestFacilityStatus_Inactive    = 0,
+    VBoxGuestFacilityStatus_Paused      = 1,
+    VBoxGuestFacilityStatus_PreInit     = 20,
+    VBoxGuestFacilityStatus_Init        = 30,
+    VBoxGuestFacilityStatus_Active      = 50,
+    VBoxGuestFacilityStatus_Terminating = 100,
+    VBoxGuestFacilityStatus_Terminated  = 101,
+    VBoxGuestFacilityStatus_Failed  =     800,
+    VBoxGuestFacilityStatus_Unknown     = 999,
+    VBoxGuestFacilityStatus_SizeHack    = 0x7fffffff
+} VBoxGuestFacilityStatus;
+AssertCompileSize(VBoxGuestFacilityStatus, 4);
+
+
+/**
+ * The facility class.
+ * This needs to be kept in sync with AdditionsFacilityClass of the Main API!
+ */
+typedef enum
+{
+    VBoxGuestFacilityClass_None       = 0,
+    VBoxGuestFacilityClass_Driver     = 10,
+    VBoxGuestFacilityClass_Service    = 30,
+    VBoxGuestFacilityClass_Program    = 50,
+    VBoxGuestFacilityClass_Feature    = 100,
+    VBoxGuestFacilityClass_ThirdParty = 999,
+    VBoxGuestFacilityClass_All        = 0x7ffffffe,
+    VBoxGuestFacilityClass_SizeHack   = 0x7fffffff
+} VBoxGuestFacilityClass;
+AssertCompileSize(VBoxGuestFacilityClass, 4);
+
+
+/**
+ * Guest status structure.
+ *
+ * Used by VMMDevReqGuestStatus.
+ */
+typedef struct VBoxGuestStatus
+{
+    /** Facility the status is indicated for. */
+    VBoxGuestFacilityType facility;
+    /** Current guest status. */
+    VBoxGuestFacilityStatus status;
+    /** Flags, not used at the moment. */
+    uint32_t flags;
+} VBoxGuestStatus;
+AssertCompileSize(VBoxGuestStatus, 12);
+
+/**
+ * Guest Additions status structure.
+ *
+ * Used by VMMDevReq_ReportGuestStatus.
+ */
+typedef struct
+{
+    /** Header. */
+    VMMDevRequestHeader header;
+    /** Guest information. */
+    VBoxGuestStatus guestStatus;
+} VMMDevReportGuestStatus;
+AssertCompileSize(VMMDevReportGuestStatus, 24+12);
+
+
+/**
+ * The current status of specific guest user.
+ * This needs to be kept in sync with GuestUserState of the Main API!
+ */
+typedef enum VBoxGuestUserState
+{
+    VBoxGuestUserState_Unknown            = 0,
+    VBoxGuestUserState_LoggedIn           = 1,
+    VBoxGuestUserState_LoggedOut          = 2,
+    VBoxGuestUserState_Locked             = 3,
+    VBoxGuestUserState_Unlocked           = 4,
+    VBoxGuestUserState_Disabled           = 5,
+    VBoxGuestUserState_Idle               = 6,
+    VBoxGuestUserState_InUse              = 7,
+    VBoxGuestUserState_Created            = 8,
+    VBoxGuestUserState_Deleted            = 9,
+    VBoxGuestUserState_SessionChanged     = 10,
+    VBoxGuestUserState_CredentialsChanged = 11,
+    VBoxGuestUserState_RoleChanged        = 12,
+    VBoxGuestUserState_GroupAdded         = 13,
+    VBoxGuestUserState_GroupRemoved       = 14,
+    VBoxGuestUserState_Elevated           = 15,
+    VBoxGuestUserState_SizeHack           = 0x7fffffff
+} VBoxGuestUserState;
+AssertCompileSize(VBoxGuestUserState, 4);
+
+
+/**
+ * Guest user status updates.
+ */
+typedef struct VBoxGuestUserStatus
+{
+    /** The guest user state to send. */
+    VBoxGuestUserState  state;
+    /** Size (in bytes) of szUser. */
+    uint32_t            cbUser;
+    /** Size (in bytes) of szDomain. */
+    uint32_t            cbDomain;
+    /** Size (in bytes) of aDetails. */
+    uint32_t            cbDetails;
+    /** Note: Here begins the dynamically
+     *        allocated region. */
+    /** Guest user to report state for. */
+    char                szUser[1];
+    /** Domain the guest user is bound to. */
+    char                szDomain[1];
+    /** Optional details of the state. */
+    uint8_t             aDetails[1];
+} VBoxGuestUserStatus;
+AssertCompileSize(VBoxGuestUserStatus, 20);
+
+
+/**
+ * Guest user status structure.
+ *
+ * Used by VMMDevReq_ReportGuestUserStatus.
+ */
+typedef struct
+{
+    /** Header. */
+    VMMDevRequestHeader header;
+    /** Guest user status. */
+    VBoxGuestUserStatus status;
+} VMMDevReportGuestUserState;
+AssertCompileSize(VMMDevReportGuestUserState, 24+20);
+
+
+/**
+ * Guest statistics structure.
+ *
+ * Used by VMMDevReportGuestStats and PDMIVMMDEVCONNECTOR::pfnReportStatistics.
+ */
+typedef struct VBoxGuestStatistics
+{
+    /** Virtual CPU ID. */
+    uint32_t        u32CpuId;
+    /** Reported statistics. */
+    uint32_t        u32StatCaps;
+    /** Idle CPU load (0-100) for last interval. */
+    uint32_t        u32CpuLoad_Idle;
+    /** Kernel CPU load (0-100) for last interval. */
+    uint32_t        u32CpuLoad_Kernel;
+    /** User CPU load (0-100) for last interval. */
+    uint32_t        u32CpuLoad_User;
+    /** Nr of threads. */
+    uint32_t        u32Threads;
+    /** Nr of processes. */
+    uint32_t        u32Processes;
+    /** Nr of handles. */
+    uint32_t        u32Handles;
+    /** Memory load (0-100). */
+    uint32_t        u32MemoryLoad;
+    /** Page size of guest system. */
+    uint32_t        u32PageSize;
+    /** Total physical memory (in 4KB pages). */
+    uint32_t        u32PhysMemTotal;
+    /** Available physical memory (in 4KB pages). */
+    uint32_t        u32PhysMemAvail;
+    /** Ballooned physical memory (in 4KB pages). */
+    uint32_t        u32PhysMemBalloon;
+    /** Total number of committed memory (which is not necessarily in-use) (in 4KB pages). */
+    uint32_t        u32MemCommitTotal;
+    /** Total amount of memory used by the kernel (in 4KB pages). */
+    uint32_t        u32MemKernelTotal;
+    /** Total amount of paged memory used by the kernel (in 4KB pages). */
+    uint32_t        u32MemKernelPaged;
+    /** Total amount of nonpaged memory used by the kernel (in 4KB pages). */
+    uint32_t        u32MemKernelNonPaged;
+    /** Total amount of memory used for the system cache (in 4KB pages). */
+    uint32_t        u32MemSystemCache;
+    /** Pagefile size (in 4KB pages). */
+    uint32_t        u32PageFileSize;
+} VBoxGuestStatistics;
+AssertCompileSize(VBoxGuestStatistics, 19*4);
+
+/** @name Guest statistics values (VBoxGuestStatistics::u32StatCaps).
+ * @{ */
+#define VBOX_GUEST_STAT_CPU_LOAD_IDLE       RT_BIT(0)
+#define VBOX_GUEST_STAT_CPU_LOAD_KERNEL     RT_BIT(1)
+#define VBOX_GUEST_STAT_CPU_LOAD_USER       RT_BIT(2)
+#define VBOX_GUEST_STAT_THREADS             RT_BIT(3)
+#define VBOX_GUEST_STAT_PROCESSES           RT_BIT(4)
+#define VBOX_GUEST_STAT_HANDLES             RT_BIT(5)
+#define VBOX_GUEST_STAT_MEMORY_LOAD         RT_BIT(6)
+#define VBOX_GUEST_STAT_PHYS_MEM_TOTAL      RT_BIT(7)
+#define VBOX_GUEST_STAT_PHYS_MEM_AVAIL      RT_BIT(8)
+#define VBOX_GUEST_STAT_PHYS_MEM_BALLOON    RT_BIT(9)
+#define VBOX_GUEST_STAT_MEM_COMMIT_TOTAL    RT_BIT(10)
+#define VBOX_GUEST_STAT_MEM_KERNEL_TOTAL    RT_BIT(11)
+#define VBOX_GUEST_STAT_MEM_KERNEL_PAGED    RT_BIT(12)
+#define VBOX_GUEST_STAT_MEM_KERNEL_NONPAGED RT_BIT(13)
+#define VBOX_GUEST_STAT_MEM_SYSTEM_CACHE    RT_BIT(14)
+#define VBOX_GUEST_STAT_PAGE_FILE_SIZE      RT_BIT(15)
+/** @} */
+
+/**
+ * Guest statistics command structure.
+ *
+ * Used by VMMDevReq_ReportGuestStats.
+ */
+typedef struct
+{
+    /** Header. */
+    VMMDevRequestHeader header;
+    /** Guest information. */
+    VBoxGuestStatistics guestStats;
+} VMMDevReportGuestStats;
+AssertCompileSize(VMMDevReportGuestStats, 24+19*4);
+
+
+/** Memory balloon change request structure. */
+#define VMMDEV_MAX_MEMORY_BALLOON(PhysMemTotal)     ( (9 * (PhysMemTotal)) / 10 )
+
+/**
+ * Poll for ballooning change request.
+ *
+ * Used by VMMDevReq_GetMemBalloonChangeRequest.
+ */
+typedef struct
+{
+    /** Header. */
+    VMMDevRequestHeader header;
+    /** Balloon size in megabytes. */
+    uint32_t            cBalloonChunks;
+    /** Guest ram size in megabytes. */
+    uint32_t            cPhysMemChunks;
+    /** Setting this to VMMDEV_EVENT_BALLOON_CHANGE_REQUEST indicates that the
+     * request is a response to that event.
+     * (Don't confuse this with VMMDevReq_AcknowledgeEvents.) */
+    uint32_t            eventAck;
+} VMMDevGetMemBalloonChangeRequest;
+AssertCompileSize(VMMDevGetMemBalloonChangeRequest, 24+12);
+
+
+/**
+ * Change the size of the balloon.
+ *
+ * Used by VMMDevReq_ChangeMemBalloon.
+ */
+typedef struct
+{
+    /** Header. */
+    VMMDevRequestHeader header;
+    /** The number of pages in the array. */
+    uint32_t            cPages;
+    /** true = inflate, false = deflate.  */
+    uint32_t            fInflate;
+    /** Physical address (RTGCPHYS) of each page, variable size. */
+    RTGCPHYS            aPhysPage[1];
+} VMMDevChangeMemBalloon;
+AssertCompileSize(VMMDevChangeMemBalloon, 24+16);
+
+/** @name The ballooning chunk size which VMMDev works at.
+ * @{ */
+#define VMMDEV_MEMORY_BALLOON_CHUNK_PAGES            (_1M/4096)
+#define VMMDEV_MEMORY_BALLOON_CHUNK_SIZE             (VMMDEV_MEMORY_BALLOON_CHUNK_PAGES*4096)
+/** @} */
+
+
+/**
+ * Guest statistics interval change request structure.
+ *
+ * Used by VMMDevReq_GetStatisticsChangeRequest.
+ */
+typedef struct
+{
+    /** Header. */
+    VMMDevRequestHeader header;
+    /** The interval in seconds. */
+    uint32_t            u32StatInterval;
+    /** Setting this to VMMDEV_EVENT_STATISTICS_INTERVAL_CHANGE_REQUEST indicates
+     * that the request is a response to that event.
+     * (Don't confuse this with VMMDevReq_AcknowledgeEvents.) */
+    uint32_t            eventAck;
+} VMMDevGetStatisticsChangeRequest;
+AssertCompileSize(VMMDevGetStatisticsChangeRequest, 24+8);
+
+
+/** The size of a string field in the credentials request (including '\\0').
+ * @see VMMDevCredentials  */
+#define VMMDEV_CREDENTIALS_SZ_SIZE          128
+
+/**
+ * Credentials request structure.
+ *
+ * Used by VMMDevReq_QueryCredentials.
+ */
+typedef struct
+{
+    /** Header. */
+    VMMDevRequestHeader header;
+    /** IN/OUT: Request flags. */
+    uint32_t u32Flags;
+    /** OUT: User name (UTF-8). */
+    char szUserName[VMMDEV_CREDENTIALS_SZ_SIZE];
+    /** OUT: Password (UTF-8). */
+    char szPassword[VMMDEV_CREDENTIALS_SZ_SIZE];
+    /** OUT: Domain name (UTF-8). */
+    char szDomain[VMMDEV_CREDENTIALS_SZ_SIZE];
+} VMMDevCredentials;
+AssertCompileSize(VMMDevCredentials, 24+4+3*128);
+
+/** @name Credentials request flag (VMMDevCredentials::u32Flags)
+ * @{ */
+/** query from host whether credentials are present */
+#define VMMDEV_CREDENTIALS_QUERYPRESENCE     RT_BIT(1)
+/** read credentials from host (can be combined with clear) */
+#define VMMDEV_CREDENTIALS_READ              RT_BIT(2)
+/** clear credentials on host (can be combined with read) */
+#define VMMDEV_CREDENTIALS_CLEAR             RT_BIT(3)
+/** read credentials for judgement in the guest */
+#define VMMDEV_CREDENTIALS_READJUDGE         RT_BIT(8)
+/** clear credentials for judegement on the host */
+#define VMMDEV_CREDENTIALS_CLEARJUDGE        RT_BIT(9)
+/** report credentials acceptance by guest */
+#define VMMDEV_CREDENTIALS_JUDGE_OK          RT_BIT(10)
+/** report credentials denial by guest */
+#define VMMDEV_CREDENTIALS_JUDGE_DENY        RT_BIT(11)
+/** report that no judgement could be made by guest */
+#define VMMDEV_CREDENTIALS_JUDGE_NOJUDGEMENT RT_BIT(12)
+
+/** flag telling the guest that credentials are present */
+#define VMMDEV_CREDENTIALS_PRESENT           RT_BIT(16)
+/** flag telling guest that local logons should be prohibited */
+#define VMMDEV_CREDENTIALS_NOLOCALLOGON      RT_BIT(17)
+/** @} */
+
+
+/**
+ * Seamless mode change request structure.
+ *
+ * Used by VMMDevReq_GetSeamlessChangeRequest.
+ */
+typedef struct
+{
+    /** Header. */
+    VMMDevRequestHeader header;
+
+    /** New seamless mode. */
+    VMMDevSeamlessMode mode;
+    /** Setting this to VMMDEV_EVENT_SEAMLESS_MODE_CHANGE_REQUEST indicates
+     * that the request is a response to that event.
+     * (Don't confuse this with VMMDevReq_AcknowledgeEvents.) */
+    uint32_t eventAck;
+} VMMDevSeamlessChangeRequest;
+AssertCompileSize(VMMDevSeamlessChangeRequest, 24+8);
+AssertCompileMemberOffset(VMMDevSeamlessChangeRequest, eventAck, 24+4);
+
+
+/**
+ * Display change request structure.
+ *
+ * Used by VMMDevReq_GetDisplayChangeRequest.
+ */
+typedef struct
+{
+    /** Header. */
+    VMMDevRequestHeader header;
+    /** Horizontal pixel resolution (0 = do not change). */
+    uint32_t xres;
+    /** Vertical pixel resolution (0 = do not change). */
+    uint32_t yres;
+    /** Bits per pixel (0 = do not change). */
+    uint32_t bpp;
+    /** Setting this to VMMDEV_EVENT_DISPLAY_CHANGE_REQUEST indicates
+     * that the request is a response to that event.
+     * (Don't confuse this with VMMDevReq_AcknowledgeEvents.) */
+    uint32_t eventAck;
+} VMMDevDisplayChangeRequest;
+AssertCompileSize(VMMDevDisplayChangeRequest, 24+16);
+
+
+/**
+ * Display change request structure, version 2.
+ *
+ * Used by VMMDevReq_GetDisplayChangeRequest2.
+ */
+typedef struct
+{
+    /** Header. */
+    VMMDevRequestHeader header;
+    /** Horizontal pixel resolution (0 = do not change). */
+    uint32_t xres;
+    /** Vertical pixel resolution (0 = do not change). */
+    uint32_t yres;
+    /** Bits per pixel (0 = do not change). */
+    uint32_t bpp;
+    /** Setting this to VMMDEV_EVENT_DISPLAY_CHANGE_REQUEST indicates
+     * that the request is a response to that event.
+     * (Don't confuse this with VMMDevReq_AcknowledgeEvents.) */
+    uint32_t eventAck;
+    /** 0 for primary display, 1 for the first secondary, etc. */
+    uint32_t display;
+} VMMDevDisplayChangeRequest2;
+AssertCompileSize(VMMDevDisplayChangeRequest2, 24+20);
+
+
+/**
+ * Display change request structure, version Extended.
+ *
+ * Used by VMMDevReq_GetDisplayChangeRequestEx.
+ */
+typedef struct
+{
+    /** Header. */
+    VMMDevRequestHeader header;
+    /** Horizontal pixel resolution (0 = do not change). */
+    uint32_t xres;
+    /** Vertical pixel resolution (0 = do not change). */
+    uint32_t yres;
+    /** Bits per pixel (0 = do not change). */
+    uint32_t bpp;
+    /** Setting this to VMMDEV_EVENT_DISPLAY_CHANGE_REQUEST indicates
+     * that the request is a response to that event.
+     * (Don't confuse this with VMMDevReq_AcknowledgeEvents.) */
+    uint32_t eventAck;
+    /** 0 for primary display, 1 for the first secondary, etc. */
+    uint32_t display;
+    /** New OriginX of secondary virtual screen */
+    uint32_t cxOrigin;
+    /** New OriginY of secondary virtual screen  */
+    uint32_t cyOrigin;
+    /** Change in origin of the secondary virtaul scree is
+     *  required */
+    bool fChangeOrigin;
+    /** secondary virtual screen enabled or disabled */
+    bool fEnabled;
+} VMMDevDisplayChangeRequestEx;
+AssertCompileSize(VMMDevDisplayChangeRequestEx, 24+32);
+
+
+/**
+ * Video mode supported request structure.
+ *
+ * Used by VMMDevReq_VideoModeSupported.
+ */
+typedef struct
+{
+    /** Header. */
+    VMMDevRequestHeader header;
+    /** IN: Horizontal pixel resolution. */
+    uint32_t width;
+    /** IN: Vertical pixel resolution. */
+    uint32_t height;
+    /** IN: Bits per pixel. */
+    uint32_t bpp;
+    /** OUT: Support indicator. */
+    bool fSupported;
+} VMMDevVideoModeSupportedRequest;
+AssertCompileSize(VMMDevVideoModeSupportedRequest, 24+16);
+
+/**
+ * Video mode supported request structure for a specific display.
+ *
+ * Used by VMMDevReq_VideoModeSupported2.
+ */
+typedef struct
+{
+    /** Header. */
+    VMMDevRequestHeader header;
+    /** IN: The guest display number. */
+    uint32_t display;
+    /** IN: Horizontal pixel resolution. */
+    uint32_t width;
+    /** IN: Vertical pixel resolution. */
+    uint32_t height;
+    /** IN: Bits per pixel. */
+    uint32_t bpp;
+    /** OUT: Support indicator. */
+    bool fSupported;
+} VMMDevVideoModeSupportedRequest2;
+AssertCompileSize(VMMDevVideoModeSupportedRequest2, 24+20);
+
+/**
+ * Video modes height reduction request structure.
+ *
+ * Used by VMMDevReq_GetHeightReduction.
+ */
+typedef struct
+{
+    /** Header. */
+    VMMDevRequestHeader header;
+    /** OUT: Height reduction in pixels. */
+    uint32_t heightReduction;
+} VMMDevGetHeightReductionRequest;
+AssertCompileSize(VMMDevGetHeightReductionRequest, 24+4);
+
+
+/**
+ * VRDP change request structure.
+ *
+ * Used by VMMDevReq_GetVRDPChangeRequest.
+ */
+typedef struct
+{
+    /** Header */
+    VMMDevRequestHeader header;
+    /** Whether VRDP is active or not. */
+    uint8_t u8VRDPActive;
+    /** The configured experience level for active VRDP. */
+    uint32_t u32VRDPExperienceLevel;
+} VMMDevVRDPChangeRequest;
+AssertCompileSize(VMMDevVRDPChangeRequest, 24+8);
+AssertCompileMemberOffset(VMMDevVRDPChangeRequest, u8VRDPActive, 24);
+AssertCompileMemberOffset(VMMDevVRDPChangeRequest, u32VRDPExperienceLevel, 24+4);
+
+/** @name VRDP Experience level (VMMDevVRDPChangeRequest::u32VRDPExperienceLevel)
+ * @{ */
+#define VRDP_EXPERIENCE_LEVEL_ZERO     0 /**< Theming disabled. */
+#define VRDP_EXPERIENCE_LEVEL_LOW      1 /**< Full window dragging and desktop wallpaper disabled. */
+#define VRDP_EXPERIENCE_LEVEL_MEDIUM   2 /**< Font smoothing, gradients. */
+#define VRDP_EXPERIENCE_LEVEL_HIGH     3 /**< Animation effects disabled. */
+#define VRDP_EXPERIENCE_LEVEL_FULL     4 /**< Everything enabled. */
+/** @} */
+
+
+/**
+ * VBVA enable request structure.
+ *
+ * Used by VMMDevReq_VideoAccelEnable.
+ */
+typedef struct
+{
+    /** Header. */
+    VMMDevRequestHeader header;
+    /** 0 - disable, !0 - enable. */
+    uint32_t u32Enable;
+    /** The size of VBVAMEMORY::au8RingBuffer expected by driver.
+     *  The host will refuse to enable VBVA if the size is not equal to
+     *  VBVA_RING_BUFFER_SIZE.
+     */
+    uint32_t cbRingBuffer;
+    /** Guest initializes the status to 0. Host sets appropriate VBVA_F_STATUS_ flags. */
+    uint32_t fu32Status;
+} VMMDevVideoAccelEnable;
+AssertCompileSize(VMMDevVideoAccelEnable, 24+12);
+
+/** @name VMMDevVideoAccelEnable::fu32Status.
+ * @{ */
+#define VBVA_F_STATUS_ACCEPTED (0x01)
+#define VBVA_F_STATUS_ENABLED  (0x02)
+/** @} */
+
+
+/**
+ * VBVA flush request structure.
+ *
+ * Used by VMMDevReq_VideoAccelFlush.
+ */
+typedef struct
+{
+    /** Header. */
+    VMMDevRequestHeader header;
+} VMMDevVideoAccelFlush;
+AssertCompileSize(VMMDevVideoAccelFlush, 24);
+
+
+/**
+ * VBVA set visible region request structure.
+ *
+ * Used by VMMDevReq_VideoSetVisibleRegion.
+ */
+typedef struct
+{
+    /** Header. */
+    VMMDevRequestHeader header;
+    /** Number of rectangles */
+    uint32_t cRect;
+    /** Rectangle array.
+     * @todo array is spelled aRects[1].  */
+    RTRECT Rect;
+} VMMDevVideoSetVisibleRegion;
+AssertCompileSize(RTRECT, 16);
+AssertCompileSize(VMMDevVideoSetVisibleRegion, 24+4+16);
+
+/**
+ * CPU event types.
+ */
+typedef enum
+{
+    VMMDevCpuStatusType_Invalid  = 0,
+    VMMDevCpuStatusType_Disable  = 1,
+    VMMDevCpuStatusType_Enable   = 2,
+    VMMDevCpuStatusType_SizeHack = 0x7fffffff
+} VMMDevCpuStatusType;
+
+/**
+ * CPU hotplug event status request.
+ */
+typedef struct
+{
+    /** Header. */
+    VMMDevRequestHeader header;
+    /** Status type */
+    VMMDevCpuStatusType enmStatusType;
+} VMMDevCpuHotPlugStatusRequest;
+AssertCompileSize(VMMDevCpuHotPlugStatusRequest, 24+4);
+
+/**
+ * Get the ID of the changed CPU and event type.
+ */
+typedef struct
+{
+    /** Header. */
+    VMMDevRequestHeader header;
+    /** Event type */
+    VMMDevCpuEventType  enmEventType;
+    /** core id of the CPU changed */
+    uint32_t            idCpuCore;
+    /** package id of the CPU changed */
+    uint32_t            idCpuPackage;
+} VMMDevGetCpuHotPlugRequest;
+AssertCompileSize(VMMDevGetCpuHotPlugRequest, 24+4+4+4);
+
+
+/**
+ * Shared region description
+ */
+typedef struct VMMDEVSHAREDREGIONDESC
+{
+    RTGCPTR64           GCRegionAddr;
+    uint32_t            cbRegion;
+    uint32_t            u32Alignment;
+} VMMDEVSHAREDREGIONDESC;
+AssertCompileSize(VMMDEVSHAREDREGIONDESC, 16);
+
+#define VMMDEVSHAREDREGIONDESC_MAX          32
+
+/**
+ * Shared module registration
+ */
+typedef struct
+{
+    /** Header. */
+    VMMDevRequestHeader         header;
+    /** Shared module size. */
+    uint32_t                    cbModule;
+    /** Number of included region descriptors */
+    uint32_t                    cRegions;
+    /** Base address of the shared module. */
+    RTGCPTR64                   GCBaseAddr;
+    /** Guest OS type. */
+    VBOXOSFAMILY                enmGuestOS;
+    /** Alignment. */
+    uint32_t                    u32Align;
+    /** Module name */
+    char                        szName[128];
+    /** Module version */
+    char                        szVersion[16];
+    /** Shared region descriptor(s). */
+    VMMDEVSHAREDREGIONDESC      aRegions[1];
+} VMMDevSharedModuleRegistrationRequest;
+AssertCompileSize(VMMDevSharedModuleRegistrationRequest, 24+4+4+8+4+4+128+16+16);
+
+
+/**
+ * Shared module unregistration
+ */
+typedef struct
+{
+    /** Header. */
+    VMMDevRequestHeader         header;
+    /** Shared module size. */
+    uint32_t                    cbModule;
+    /** Align at 8 byte boundary. */
+    uint32_t                    u32Alignment;
+    /** Base address of the shared module. */
+    RTGCPTR64                   GCBaseAddr;
+    /** Module name */
+    char                        szName[128];
+    /** Module version */
+    char                        szVersion[16];
+} VMMDevSharedModuleUnregistrationRequest;
+AssertCompileSize(VMMDevSharedModuleUnregistrationRequest, 24+4+4+8+128+16);
+
+
+/**
+ * Shared module periodic check
+ */
+typedef struct
+{
+    /** Header. */
+    VMMDevRequestHeader         header;
+} VMMDevSharedModuleCheckRequest;
+AssertCompileSize(VMMDevSharedModuleCheckRequest, 24);
+
+/**
+ * Paging sharing enabled query
+ */
+typedef struct
+{
+    /** Header. */
+    VMMDevRequestHeader         header;
+    /** Enabled flag (out) */
+    bool                        fEnabled;
+    /** Alignment */
+    bool                        fAlignment[3];
+} VMMDevPageSharingStatusRequest;
+AssertCompileSize(VMMDevPageSharingStatusRequest, 24+4);
+
+
+/**
+ * Page sharing status query (debug build only)
+ */
+typedef struct
+{
+    /** Header. */
+    VMMDevRequestHeader         header;
+    /** Page address. */
+    RTGCPTR                     GCPtrPage;
+    /** Page flags. */
+    uint64_t                    uPageFlags;
+    /** Shared flag (out) */
+    bool                        fShared;
+    /** Alignment */
+    bool                        fAlignment[3];
+} VMMDevPageIsSharedRequest;
+
+/**
+ * Session id request structure.
+ *
+ * Used by VMMDevReq_GetSessionId.
+ */
+typedef struct
+{
+    /** Header */
+    VMMDevRequestHeader header;
+    /** OUT: unique session id; the id will be different after each start, reset or restore of the VM */
+    uint64_t            idSession;
+} VMMDevReqSessionId;
+AssertCompileSize(VMMDevReqSessionId, 24+8);
+
+
+/**
+ * Write Core Dump request.
+ *
+ * Used by VMMDevReq_WriteCoreDump.
+ */
+typedef struct
+{
+    /** Header. */
+    VMMDevRequestHeader header;
+    /** Flags (reserved, MBZ). */
+    uint32_t            fFlags;
+} VMMDevReqWriteCoreDump;
+AssertCompileSize(VMMDevReqWriteCoreDump, 24+4);
+
+/** Heart beat check state structure.
+ *  Used by VMMDevReq_HeartbeatConfigure. */
+typedef struct
+{
+    /** Header. */
+    VMMDevRequestHeader header;
+    /** OUT: Guest heartbeat interval in nanosec. */
+    uint64_t    cNsInterval;
+    /** Heartbeat check flag. */
+    bool fEnabled;
+} VMMDevReqHeartbeat;
+AssertCompileSize(VMMDevReqHeartbeat, 24+12);
+
+
+
+#ifdef VBOX_WITH_HGCM
+
+/** @name HGCM flags.
+ * @{
+ */
+# define VBOX_HGCM_REQ_DONE      RT_BIT_32(VBOX_HGCM_REQ_DONE_BIT)
+# define VBOX_HGCM_REQ_DONE_BIT  0
+# define VBOX_HGCM_REQ_CANCELLED (0x2)
+/** @} */
+
+/**
+ * HGCM request header.
+ */
+typedef struct VMMDevHGCMRequestHeader
+{
+    /** Request header. */
+    VMMDevRequestHeader header;
+
+    /** HGCM flags. */
+    uint32_t fu32Flags;
+
+    /** Result code. */
+    int32_t result;
+} VMMDevHGCMRequestHeader;
+AssertCompileSize(VMMDevHGCMRequestHeader, 24+8);
+
+/**
+ * HGCM connect request structure.
+ *
+ * Used by VMMDevReq_HGCMConnect.
+ */
+typedef struct
+{
+    /** HGCM request header. */
+    VMMDevHGCMRequestHeader header;
+
+    /** IN: Description of service to connect to. */
+    HGCMServiceLocation loc;
+
+    /** OUT: Client identifier assigned by local instance of HGCM. */
+    uint32_t u32ClientID;
+} VMMDevHGCMConnect;
+AssertCompileSize(VMMDevHGCMConnect, 32+132+4);
+
+
+/**
+ * HGCM disconnect request structure.
+ *
+ * Used by VMMDevReq_HGCMDisconnect.
+ */
+typedef struct
+{
+    /** HGCM request header. */
+    VMMDevHGCMRequestHeader header;
+
+    /** IN: Client identifier. */
+    uint32_t u32ClientID;
+} VMMDevHGCMDisconnect;
+AssertCompileSize(VMMDevHGCMDisconnect, 32+4);
+
+/**
+ * HGCM parameter type.
+ */
+typedef enum
+{
+    VMMDevHGCMParmType_Invalid            = 0,
+    VMMDevHGCMParmType_32bit              = 1,
+    VMMDevHGCMParmType_64bit              = 2,
+    VMMDevHGCMParmType_PhysAddr           = 3,  /**< @deprecated Doesn't work, use PageList. */
+    VMMDevHGCMParmType_LinAddr            = 4,  /**< In and Out */
+    VMMDevHGCMParmType_LinAddr_In         = 5,  /**< In  (read;  host<-guest) */
+    VMMDevHGCMParmType_LinAddr_Out        = 6,  /**< Out (write; host->guest) */
+    VMMDevHGCMParmType_LinAddr_Locked     = 7,  /**< Locked In and Out */
+    VMMDevHGCMParmType_LinAddr_Locked_In  = 8,  /**< Locked In  (read;  host<-guest) */
+    VMMDevHGCMParmType_LinAddr_Locked_Out = 9,  /**< Locked Out (write; host->guest) */
+    VMMDevHGCMParmType_PageList           = 10, /**< Physical addresses of locked pages for a buffer. */
+    VMMDevHGCMParmType_SizeHack           = 0x7fffffff
+} HGCMFunctionParameterType;
+AssertCompileSize(HGCMFunctionParameterType, 4);
+
+# ifdef VBOX_WITH_64_BITS_GUESTS
+/**
+ * HGCM function parameter, 32-bit client.
+ */
+typedef struct
+{
+    HGCMFunctionParameterType type;
+    union
+    {
+        uint32_t   value32;
+        uint64_t   value64;
+        struct
+        {
+            uint32_t size;
+
+            union
+            {
+                RTGCPHYS32 physAddr;
+                RTGCPTR32  linearAddr;
+            } u;
+        } Pointer;
+        struct
+        {
+            uint32_t size;   /**< Size of the buffer described by the page list. */
+            uint32_t offset; /**< Relative to the request header, valid if size != 0. */
+        } PageList;
+    } u;
+#  ifdef __cplusplus
+    void SetUInt32(uint32_t u32)
+    {
+        type = VMMDevHGCMParmType_32bit;
+        u.value64 = 0; /* init unused bits to 0 */
+        u.value32 = u32;
+    }
+
+    int GetUInt32(uint32_t *pu32)
+    {
+        if (type == VMMDevHGCMParmType_32bit)
+        {
+            *pu32 = u.value32;
+            return VINF_SUCCESS;
+        }
+        return VERR_INVALID_PARAMETER;
+    }
+
+    void SetUInt64(uint64_t u64)
+    {
+        type      = VMMDevHGCMParmType_64bit;
+        u.value64 = u64;
+    }
+
+    int GetUInt64(uint64_t *pu64)
+    {
+        if (type == VMMDevHGCMParmType_64bit)
+        {
+            *pu64 = u.value64;
+            return VINF_SUCCESS;
+        }
+        return VERR_INVALID_PARAMETER;
+    }
+
+    void SetPtr(void *pv, uint32_t cb)
+    {
+        type                    = VMMDevHGCMParmType_LinAddr;
+        u.Pointer.size          = cb;
+        u.Pointer.u.linearAddr  = (RTGCPTR32)(uintptr_t)pv;
+    }
+#  endif /* __cplusplus */
+} HGCMFunctionParameter32;
+AssertCompileSize(HGCMFunctionParameter32, 4+8);
+
+/**
+ * HGCM function parameter, 64-bit client.
+ */
+typedef struct
+{
+    HGCMFunctionParameterType type;
+    union
+    {
+        uint32_t   value32;
+        uint64_t   value64;
+        struct
+        {
+            uint32_t size;
+
+            union
+            {
+                RTGCPHYS64 physAddr;
+                RTGCPTR64  linearAddr;
+            } u;
+        } Pointer;
+        struct
+        {
+            uint32_t size;   /**< Size of the buffer described by the page list. */
+            uint32_t offset; /**< Relative to the request header, valid if size != 0. */
+        } PageList;
+    } u;
+#  ifdef __cplusplus
+    void SetUInt32(uint32_t u32)
+    {
+        type = VMMDevHGCMParmType_32bit;
+        u.value64 = 0; /* init unused bits to 0 */
+        u.value32 = u32;
+    }
+
+    int GetUInt32(uint32_t *pu32)
+    {
+        if (type == VMMDevHGCMParmType_32bit)
+        {
+            *pu32 = u.value32;
+            return VINF_SUCCESS;
+        }
+        return VERR_INVALID_PARAMETER;
+    }
+
+    void SetUInt64(uint64_t u64)
+    {
+        type      = VMMDevHGCMParmType_64bit;
+        u.value64 = u64;
+    }
+
+    int GetUInt64(uint64_t *pu64)
+    {
+        if (type == VMMDevHGCMParmType_64bit)
+        {
+            *pu64 = u.value64;
+            return VINF_SUCCESS;
+        }
+        return VERR_INVALID_PARAMETER;
+    }
+
+    void SetPtr(void *pv, uint32_t cb)
+    {
+        type                    = VMMDevHGCMParmType_LinAddr;
+        u.Pointer.size          = cb;
+        u.Pointer.u.linearAddr  = (uintptr_t)pv;
+    }
+#  endif /** __cplusplus */
+} HGCMFunctionParameter64;
+AssertCompileSize(HGCMFunctionParameter64, 4+12);
+
+/* Redefine the structure type for the guest code. */
+#  ifndef VBOX_HGCM_HOST_CODE
+#   if ARCH_BITS == 64
+#     define HGCMFunctionParameter  HGCMFunctionParameter64
+#   elif ARCH_BITS == 32
+#     define HGCMFunctionParameter  HGCMFunctionParameter32
+#   else
+#    error "Unsupported sizeof (void *)"
+#   endif
+#  endif /* !VBOX_HGCM_HOST_CODE */
+
+# else /* !VBOX_WITH_64_BITS_GUESTS */
+
+/**
+ * HGCM function parameter, 32-bit client.
+ *
+ * @todo If this is the same as HGCMFunctionParameter32, why the duplication?
+ */
+typedef struct
+{
+    HGCMFunctionParameterType type;
+    union
+    {
+        uint32_t   value32;
+        uint64_t   value64;
+        struct
+        {
+            uint32_t size;
+
+            union
+            {
+                RTGCPHYS32 physAddr;
+                RTGCPTR32  linearAddr;
+            } u;
+        } Pointer;
+        struct
+        {
+            uint32_t size;   /**< Size of the buffer described by the page list. */
+            uint32_t offset; /**< Relative to the request header, valid if size != 0. */
+        } PageList;
+    } u;
+#  ifdef __cplusplus
+    void SetUInt32(uint32_t u32)
+    {
+        type = VMMDevHGCMParmType_32bit;
+        u.value64 = 0; /* init unused bits to 0 */
+        u.value32 = u32;
+    }
+
+    int GetUInt32(uint32_t *pu32)
+    {
+        if (type == VMMDevHGCMParmType_32bit)
+        {
+            *pu32 = u.value32;
+            return VINF_SUCCESS;
+        }
+        return VERR_INVALID_PARAMETER;
+    }
+
+    void SetUInt64(uint64_t u64)
+    {
+        type      = VMMDevHGCMParmType_64bit;
+        u.value64 = u64;
+    }
+
+    int GetUInt64(uint64_t *pu64)
+    {
+        if (type == VMMDevHGCMParmType_64bit)
+        {
+            *pu64 = u.value64;
+            return VINF_SUCCESS;
+        }
+        return VERR_INVALID_PARAMETER;
+    }
+
+    void SetPtr(void *pv, uint32_t cb)
+    {
+        type                    = VMMDevHGCMParmType_LinAddr;
+        u.Pointer.size          = cb;
+        u.Pointer.u.linearAddr  = (uintptr_t)pv;
+    }
+#  endif /* __cplusplus */
+} HGCMFunctionParameter;
+AssertCompileSize(HGCMFunctionParameter, 4+8);
+# endif /* !VBOX_WITH_64_BITS_GUESTS */
+
+/**
+ * HGCM call request structure.
+ *
+ * Used by VMMDevReq_HGCMCall, VMMDevReq_HGCMCall32 and VMMDevReq_HGCMCall64.
+ */
+typedef struct
+{
+    /* request header */
+    VMMDevHGCMRequestHeader header;
+
+    /** IN: Client identifier. */
+    uint32_t u32ClientID;
+    /** IN: Service function number. */
+    uint32_t u32Function;
+    /** IN: Number of parameters. */
+    uint32_t cParms;
+    /** Parameters follow in form: HGCMFunctionParameter aParms[X]; */
+} VMMDevHGCMCall;
+AssertCompileSize(VMMDevHGCMCall, 32+12);
+
+/** @name Direction of data transfer (HGCMPageListInfo::flags). Bit flags.
+ * @{ */
+#define VBOX_HGCM_F_PARM_DIRECTION_NONE      UINT32_C(0x00000000)
+#define VBOX_HGCM_F_PARM_DIRECTION_TO_HOST   UINT32_C(0x00000001)
+#define VBOX_HGCM_F_PARM_DIRECTION_FROM_HOST UINT32_C(0x00000002)
+#define VBOX_HGCM_F_PARM_DIRECTION_BOTH      UINT32_C(0x00000003)
+/** Macro for validating that the specified flags are valid. */
+#define VBOX_HGCM_F_PARM_ARE_VALID(fFlags) \
+    (   (fFlags) > VBOX_HGCM_F_PARM_DIRECTION_NONE \
+     && (fFlags) < VBOX_HGCM_F_PARM_DIRECTION_BOTH )
+/** @} */
+
+/**
+ * VMMDevHGCMParmType_PageList points to this structure to actually describe the
+ * buffer.
+ */
+typedef struct
+{
+    uint32_t flags;        /**< VBOX_HGCM_F_PARM_*. */
+    uint16_t offFirstPage; /**< Offset in the first page where data begins. */
+    uint16_t cPages;       /**< Number of pages. */
+    RTGCPHYS64 aPages[1];  /**< Page addresses. */
+} HGCMPageListInfo;
+AssertCompileSize(HGCMPageListInfo, 4+2+2+8);
+
+
+/** Get the pointer to the first parmater of a HGCM call request.  */
+# define VMMDEV_HGCM_CALL_PARMS(a)   ((HGCMFunctionParameter *)((uint8_t *)(a) + sizeof (VMMDevHGCMCall)))
+/** Get the pointer to the first parmater of a 32-bit HGCM call request.  */
+# define VMMDEV_HGCM_CALL_PARMS32(a) ((HGCMFunctionParameter32 *)((uint8_t *)(a) + sizeof (VMMDevHGCMCall)))
+
+# ifdef VBOX_WITH_64_BITS_GUESTS
+/* Explicit defines for the host code. */
+#  ifdef VBOX_HGCM_HOST_CODE
+#   define VMMDEV_HGCM_CALL_PARMS32(a) ((HGCMFunctionParameter32 *)((uint8_t *)(a) + sizeof (VMMDevHGCMCall)))
+#   define VMMDEV_HGCM_CALL_PARMS64(a) ((HGCMFunctionParameter64 *)((uint8_t *)(a) + sizeof (VMMDevHGCMCall)))
+#  endif /* VBOX_HGCM_HOST_CODE */
+# endif /* VBOX_WITH_64_BITS_GUESTS */
+
+# define VBOX_HGCM_MAX_PARMS 32
+
+/**
+ * HGCM cancel request structure.
+ *
+ * The Cancel request is issued using the same physical memory address as was
+ * used for the corresponding initial HGCMCall.
+ *
+ * Used by VMMDevReq_HGCMCancel.
+ */
+typedef struct
+{
+    /** Header. */
+    VMMDevHGCMRequestHeader header;
+} VMMDevHGCMCancel;
+AssertCompileSize(VMMDevHGCMCancel, 32);
+
+/**
+ * HGCM cancel request structure, version 2.
+ *
+ * Used by VMMDevReq_HGCMCancel2.
+ *
+ * VINF_SUCCESS when cancelled.
+ * VERR_NOT_FOUND if the specified request cannot be found.
+ * VERR_INVALID_PARAMETER if the address is invalid valid.
+ */
+typedef struct
+{
+    /** Header. */
+    VMMDevRequestHeader header;
+    /** The physical address of the request to cancel. */
+    RTGCPHYS32 physReqToCancel;
+} VMMDevHGCMCancel2;
+AssertCompileSize(VMMDevHGCMCancel2, 24+4);
+
+#endif /* VBOX_WITH_HGCM */
+
+
+/**
+ * Inline helper to determine the request size for the given operation.
+ * Returns 0 if the given operation is not handled and/or supported.
+ *
+ * @returns Size.
+ * @param   requestType     The VMMDev request type.
+ */
+DECLINLINE(size_t) vmmdevGetRequestSize(VMMDevRequestType requestType)
+{
+    switch (requestType)
+    {
+        case VMMDevReq_GetMouseStatus:
+        case VMMDevReq_SetMouseStatus:
+            return sizeof(VMMDevReqMouseStatus);
+        case VMMDevReq_SetPointerShape:
+            return sizeof(VMMDevReqMousePointer);
+        case VMMDevReq_GetHostVersion:
+            return sizeof(VMMDevReqHostVersion);
+        case VMMDevReq_Idle:
+            return sizeof(VMMDevReqIdle);
+        case VMMDevReq_GetHostTime:
+            return sizeof(VMMDevReqHostTime);
+        case VMMDevReq_GetHypervisorInfo:
+        case VMMDevReq_SetHypervisorInfo:
+            return sizeof(VMMDevReqHypervisorInfo);
+        case VMMDevReq_RegisterPatchMemory:
+        case VMMDevReq_DeregisterPatchMemory:
+            return sizeof(VMMDevReqPatchMemory);
+        case VMMDevReq_SetPowerStatus:
+            return sizeof(VMMDevPowerStateRequest);
+        case VMMDevReq_AcknowledgeEvents:
+            return sizeof(VMMDevEvents);
+        case VMMDevReq_ReportGuestInfo:
+            return sizeof(VMMDevReportGuestInfo);
+        case VMMDevReq_ReportGuestInfo2:
+            return sizeof(VMMDevReportGuestInfo2);
+        case VMMDevReq_ReportGuestStatus:
+            return sizeof(VMMDevReportGuestStatus);
+        case VMMDevReq_ReportGuestUserState:
+            return sizeof(VMMDevReportGuestUserState);
+        case VMMDevReq_GetDisplayChangeRequest:
+            return sizeof(VMMDevDisplayChangeRequest);
+        case VMMDevReq_GetDisplayChangeRequest2:
+            return sizeof(VMMDevDisplayChangeRequest2);
+        case VMMDevReq_GetDisplayChangeRequestEx:
+            return sizeof(VMMDevDisplayChangeRequestEx);
+        case VMMDevReq_VideoModeSupported:
+            return sizeof(VMMDevVideoModeSupportedRequest);
+        case VMMDevReq_GetHeightReduction:
+            return sizeof(VMMDevGetHeightReductionRequest);
+        case VMMDevReq_ReportGuestCapabilities:
+            return sizeof(VMMDevReqGuestCapabilities);
+        case VMMDevReq_SetGuestCapabilities:
+            return sizeof(VMMDevReqGuestCapabilities2);
+#ifdef VBOX_WITH_HGCM
+        case VMMDevReq_HGCMConnect:
+            return sizeof(VMMDevHGCMConnect);
+        case VMMDevReq_HGCMDisconnect:
+            return sizeof(VMMDevHGCMDisconnect);
+#ifdef VBOX_WITH_64_BITS_GUESTS
+        case VMMDevReq_HGCMCall32:
+            return sizeof(VMMDevHGCMCall);
+        case VMMDevReq_HGCMCall64:
+            return sizeof(VMMDevHGCMCall);
+#else
+        case VMMDevReq_HGCMCall:
+            return sizeof(VMMDevHGCMCall);
+#endif /* VBOX_WITH_64_BITS_GUESTS */
+        case VMMDevReq_HGCMCancel:
+            return sizeof(VMMDevHGCMCancel);
+#endif /* VBOX_WITH_HGCM */
+        case VMMDevReq_VideoAccelEnable:
+            return sizeof(VMMDevVideoAccelEnable);
+        case VMMDevReq_VideoAccelFlush:
+            return sizeof(VMMDevVideoAccelFlush);
+        case VMMDevReq_VideoSetVisibleRegion:
+            /* The original protocol didn't consider a guest with NO visible
+             * windows */
+            return sizeof(VMMDevVideoSetVisibleRegion) - sizeof(RTRECT);
+        case VMMDevReq_GetSeamlessChangeRequest:
+            return sizeof(VMMDevSeamlessChangeRequest);
+        case VMMDevReq_QueryCredentials:
+            return sizeof(VMMDevCredentials);
+        case VMMDevReq_ReportGuestStats:
+            return sizeof(VMMDevReportGuestStats);
+        case VMMDevReq_GetMemBalloonChangeRequest:
+            return sizeof(VMMDevGetMemBalloonChangeRequest);
+        case VMMDevReq_GetStatisticsChangeRequest:
+            return sizeof(VMMDevGetStatisticsChangeRequest);
+        case VMMDevReq_ChangeMemBalloon:
+            return sizeof(VMMDevChangeMemBalloon);
+        case VMMDevReq_GetVRDPChangeRequest:
+            return sizeof(VMMDevVRDPChangeRequest);
+        case VMMDevReq_LogString:
+            return sizeof(VMMDevReqLogString);
+        case VMMDevReq_CtlGuestFilterMask:
+            return sizeof(VMMDevCtlGuestFilterMask);
+        case VMMDevReq_GetCpuHotPlugRequest:
+            return sizeof(VMMDevGetCpuHotPlugRequest);
+        case VMMDevReq_SetCpuHotPlugStatus:
+            return sizeof(VMMDevCpuHotPlugStatusRequest);
+        case VMMDevReq_RegisterSharedModule:
+            return sizeof(VMMDevSharedModuleRegistrationRequest);
+        case VMMDevReq_UnregisterSharedModule:
+            return sizeof(VMMDevSharedModuleUnregistrationRequest);
+        case VMMDevReq_CheckSharedModules:
+            return sizeof(VMMDevSharedModuleCheckRequest);
+        case VMMDevReq_GetPageSharingStatus:
+            return sizeof(VMMDevPageSharingStatusRequest);
+        case VMMDevReq_DebugIsPageShared:
+            return sizeof(VMMDevPageIsSharedRequest);
+        case VMMDevReq_GetSessionId:
+            return sizeof(VMMDevReqSessionId);
+        case VMMDevReq_HeartbeatConfigure:
+            return sizeof(VMMDevReqHeartbeat);
+        case VMMDevReq_GuestHeartbeat:
+            return sizeof(VMMDevRequestHeader);
+        default:
+            break;
+    }
+
+    return 0;
+}
+
+
+/**
+ * Initializes a request structure.
+ *
+ * @returns VBox status code.
+ * @param   req             The request structure to initialize.
+ * @param   type            The request type.
+ */
+DECLINLINE(int) vmmdevInitRequest(VMMDevRequestHeader *req, VMMDevRequestType type)
+{
+    uint32_t requestSize;
+    if (!req)
+        return VERR_INVALID_PARAMETER;
+    requestSize = (uint32_t)vmmdevGetRequestSize(type);
+    if (!requestSize)
+        return VERR_INVALID_PARAMETER;
+    req->size        = requestSize;
+    req->version     = VMMDEV_REQUEST_HEADER_VERSION;
+    req->requestType = type;
+    req->rc          = VERR_GENERAL_FAILURE;
+    req->reserved1   = 0;
+    req->reserved2   = 0;
+    return VINF_SUCCESS;
+}
+
+/** @} */
+
+
+/**
+ * VBVA command header.
+ *
+ * @todo Where does this fit in?
+ */
+typedef struct VBVACMDHDR
+{
+   /** Coordinates of affected rectangle. */
+   int16_t x;
+   int16_t y;
+   uint16_t w;
+   uint16_t h;
+} VBVACMDHDR;
+AssertCompileSize(VBVACMDHDR, 8);
+
+/** @name VBVA ring defines.
+ *
+ * The VBVA ring buffer is suitable for transferring large (< 2GB) amount of
+ * data. For example big bitmaps which do not fit to the buffer.
+ *
+ * Guest starts writing to the buffer by initializing a record entry in the
+ * aRecords queue. VBVA_F_RECORD_PARTIAL indicates that the record is being
+ * written. As data is written to the ring buffer, the guest increases off32End
+ * for the record.
+ *
+ * The host reads the aRecords on flushes and processes all completed records.
+ * When host encounters situation when only a partial record presents and
+ * cbRecord & ~VBVA_F_RECORD_PARTIAL >= VBVA_RING_BUFFER_SIZE -
+ * VBVA_RING_BUFFER_THRESHOLD, the host fetched all record data and updates
+ * off32Head. After that on each flush the host continues fetching the data
+ * until the record is completed.
+ *
+ */
+#define VBVA_RING_BUFFER_SIZE        (_4M - _1K)
+#define VBVA_RING_BUFFER_THRESHOLD   (4 * _1K)
+
+#define VBVA_MAX_RECORDS (64)
+
+#define VBVA_F_MODE_ENABLED         (0x00000001)
+#define VBVA_F_MODE_VRDP            (0x00000002)
+#define VBVA_F_MODE_VRDP_RESET      (0x00000004)
+#define VBVA_F_MODE_VRDP_ORDER_MASK (0x00000008)
+
+#define VBVA_F_STATE_PROCESSING     (0x00010000)
+
+#define VBVA_F_RECORD_PARTIAL       (0x80000000)
+/** @} */
+
+/**
+ * VBVA record.
+ */
+typedef struct VBVARECORD
+{
+    /** The length of the record. Changed by guest. */
+    uint32_t cbRecord;
+} VBVARECORD;
+AssertCompileSize(VBVARECORD, 4);
+
+
+/**
+ * VBVA memory layout.
+ *
+ * This is a subsection of the VMMDevMemory structure.
+ */
+typedef struct VBVAMEMORY
+{
+    /** VBVA_F_MODE_*. */
+    uint32_t fu32ModeFlags;
+
+    /** The offset where the data start in the buffer. */
+    uint32_t off32Data;
+    /** The offset where next data must be placed in the buffer. */
+    uint32_t off32Free;
+
+    /** The ring buffer for data. */
+    uint8_t  au8RingBuffer[VBVA_RING_BUFFER_SIZE];
+
+    /** The queue of record descriptions. */
+    VBVARECORD aRecords[VBVA_MAX_RECORDS];
+    uint32_t indexRecordFirst;
+    uint32_t indexRecordFree;
+
+    /** RDP orders supported by the client. The guest reports only them
+     * and falls back to DIRTY rects for not supported ones.
+     *
+     * (1 << VBVA_VRDP_*)
+     */
+    uint32_t fu32SupportedOrders;
+
+} VBVAMEMORY;
+AssertCompileSize(VBVAMEMORY, 12 + (_4M-_1K) + 4*64 + 12);
+
+
+/**
+ * The layout of VMMDEV RAM region that contains information for guest.
+ */
+typedef struct VMMDevMemory
+{
+    /** The size of this structure. */
+    uint32_t u32Size;
+    /** The structure version. (VMMDEV_MEMORY_VERSION) */
+    uint32_t u32Version;
+
+    union
+    {
+        struct
+        {
+            /** Flag telling that VMMDev set the IRQ and acknowlegment is required */
+            bool fHaveEvents;
+        } V1_04;
+
+        struct
+        {
+            /** Pending events flags, set by host. */
+            uint32_t u32HostEvents;
+            /** Mask of events the guest wants to see, set by guest. */
+            uint32_t u32GuestEventMask;
+        } V1_03;
+    } V;
+
+    VBVAMEMORY vbvaMemory;
+
+} VMMDevMemory;
+AssertCompileSize(VMMDevMemory, 8+8 + (12 + (_4M-_1K) + 4*64 + 12) );
+AssertCompileMemberOffset(VMMDevMemory, vbvaMemory, 16);
+
+/** Version of VMMDevMemory structure (VMMDevMemory::u32Version). */
+#define VMMDEV_MEMORY_VERSION   (1)
+
+/** @} */
+
+RT_C_DECLS_END
+#pragma pack()
+
+#endif
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/include/VBox/VMMDev2.h
@@ -0,0 +1,122 @@
+/** @file
+ * Virtual Device for Guest <-> VMM/Host communication, Mixed Up Mess. (ADD,DEV)
+ */
+
+/*
+ * Copyright (C) 2006-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+#ifndef ___VBox_VMMDev2_h
+#define ___VBox_VMMDev2_h
+
+#include <iprt/assert.h>
+
+
+/** @addtogroup grp_vmmdev
+ * @{
+ */
+
+
+/**
+ * Seamless mode.
+ *
+ * Used by VbglR3SeamlessWaitEvent
+ *
+ * @ingroup grp_vmmdev_req
+ *
+ * @todo DARN! DARN! DARN! Who forgot to do the 32-bit hack here???
+ *       FIXME! XXX!
+ *
+ *       We will now have to carefully check how our compilers have treated this
+ *       flag. If any are compressing it into a byte type, we'll have to check
+ *       how the request memory is initialized. If we are 104% sure it's ok to
+ *       expand it, we'll expand it. If not, we must redefine the field to a
+ *       uint8_t and a 3 byte padding.
+ */
+typedef enum
+{
+    VMMDev_Seamless_Disabled         = 0,     /**< normal mode; entire guest desktop displayed. */
+    VMMDev_Seamless_Visible_Region   = 1,     /**< visible region mode; only top-level guest windows displayed. */
+    VMMDev_Seamless_Host_Window      = 2      /**< windowed mode; each top-level guest window is represented in a host window. */
+} VMMDevSeamlessMode;
+
+/**
+ * CPU event types.
+ *
+ * Used by VbglR3CpuHotplugWaitForEvent
+ *
+ * @ingroup grp_vmmdev_req
+ */
+typedef enum
+{
+    VMMDevCpuEventType_Invalid  = 0,
+    VMMDevCpuEventType_None     = 1,
+    VMMDevCpuEventType_Plug     = 2,
+    VMMDevCpuEventType_Unplug   = 3,
+    VMMDevCpuEventType_SizeHack = 0x7fffffff
+} VMMDevCpuEventType;
+
+/**
+ * HGCM service location types.
+ * @ingroup grp_vmmdev_req
+ */
+typedef enum
+{
+    VMMDevHGCMLoc_Invalid    = 0,
+    VMMDevHGCMLoc_LocalHost  = 1,
+    VMMDevHGCMLoc_LocalHost_Existing = 2,
+    VMMDevHGCMLoc_SizeHack   = 0x7fffffff
+} HGCMServiceLocationType;
+AssertCompileSize(HGCMServiceLocationType, 4);
+
+/**
+ * HGCM host service location.
+ * @ingroup grp_vmmdev_req
+ */
+typedef struct
+{
+    char achName[128]; /**< This is really szName. */
+} HGCMServiceLocationHost;
+AssertCompileSize(HGCMServiceLocationHost, 128);
+
+/**
+ * HGCM service location.
+ * @ingroup grp_vmmdev_req
+ */
+typedef struct HGCMSERVICELOCATION
+{
+    /** Type of the location. */
+    HGCMServiceLocationType type;
+
+    union
+    {
+        HGCMServiceLocationHost host;
+    } u;
+} HGCMServiceLocation;
+AssertCompileSize(HGCMServiceLocation, 128+4);
+
+/* forward declarations: */
+struct VMMDevReqMousePointer;
+struct VMMDevMemory;
+
+/** @} */
+
+#endif
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/include/VBox/cdefs.h
@@ -0,0 +1,457 @@
+/** @file
+ * VirtualBox - Common C and C++ definition.
+ */
+
+/*
+ * Copyright (C) 2006-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+#ifndef ___VBox_cdefs_h
+#define ___VBox_cdefs_h
+
+#include <iprt/cdefs.h>
+
+
+/** @defgroup VBox Common Defintions and Macros
+ * @{
+ */
+
+/** @def VBOX_WITH_STATISTICS
+ * When defined all statistics will be included in the build.
+ * This is enabled by default in all debug builds.
+ */
+#ifndef VBOX_WITH_STATISTICS
+# ifdef DEBUG
+#  define VBOX_WITH_STATISTICS
+# endif
+#endif
+
+/** @def VBOX_STRICT
+ * Alias for RT_STRICT.
+ */
+#ifdef RT_STRICT
+# ifndef VBOX_STRICT
+#  define VBOX_STRICT
+# endif
+#endif
+
+
+/*
+ * Shut up DOXYGEN warnings and guide it properly thru the code.
+ */
+#ifdef DOXYGEN_RUNNING
+#define VBOX_WITH_STATISTICS
+#define VBOX_STRICT
+#define IN_DBG
+#define IN_DIS
+#define IN_INTNET_R0
+#define IN_INTNET_R3
+#define IN_PCIRAW_R0
+#define IN_PCIRAW_R3
+#define IN_REM_R3
+#define IN_SUP_R0
+#define IN_SUP_R3
+#define IN_SUP_RC
+#define IN_SUP_STATIC
+#define IN_USBLIB
+#define IN_VBOXDDU
+#define IN_VMM_RC
+#define IN_VMM_R0
+#define IN_VMM_R3
+#define IN_VMM_STATIC
+#endif
+
+
+
+
+/** @def VBOXCALL
+ * The standard calling convention for VBOX interfaces.
+ */
+#define VBOXCALL   RTCALL
+
+
+
+/** @def IN_DIS
+ * Used to indicate whether we're inside the same link module as the
+ * disassembler.
+ */
+/** @def DISDECL(type)
+ * Disassembly export or import declaration.
+ * @param   type    The return type of the function declaration.
+ */
+#if defined(IN_DIS)
+# define DISDECL(type)      DECLEXPORT(type) VBOXCALL
+#else
+# define DISDECL(type)      DECLIMPORT(type) VBOXCALL
+#endif
+
+
+
+/** @def IN_DBG
+ * Used to indicate whether we're inside the same link module as the debugger
+ * console, gui, and related things (ring-3).
+ */
+/** @def DBGDECL(type)
+ * Debugger module export or import declaration.
+ * Functions declared using this exists only in R3 since the
+ * debugger modules is R3 only.
+ * @param   type    The return type of the function declaration.
+ */
+#if defined(IN_DBG_R3) || defined(IN_DBG)
+# define DBGDECL(type)      DECLEXPORT(type) VBOXCALL
+#else
+# define DBGDECL(type)      DECLIMPORT(type) VBOXCALL
+#endif
+
+
+
+/** @def IN_INTNET_R3
+ * Used to indicate whether we're inside the same link module as the Ring-3
+ * Internal Networking Service.
+ */
+/** @def INTNETR3DECL(type)
+ * Internal Networking Service export or import declaration.
+ * @param   type    The return type of the function declaration.
+ */
+#ifdef IN_INTNET_R3
+# define INTNETR3DECL(type) DECLEXPORT(type) VBOXCALL
+#else
+# define INTNETR3DECL(type) DECLIMPORT(type) VBOXCALL
+#endif
+
+/** @def IN_INTNET_R0
+ * Used to indicate whether we're inside the same link module as the R0
+ * Internal Network Service.
+ */
+/** @def INTNETR0DECL(type)
+ * Internal Networking Service export or import declaration.
+ * @param   type    The return type of the function declaration.
+ */
+#ifdef IN_INTNET_R0
+# define INTNETR0DECL(type) DECLEXPORT(type) VBOXCALL
+#else
+# define INTNETR0DECL(type) DECLIMPORT(type) VBOXCALL
+#endif
+
+
+
+/** @def IN_PCIRAW_R3
+ * Used to indicate whether we're inside the same link module as the Ring-3
+ * PCI passthrough support.
+ */
+/** @def PCIRAWR3DECL(type)
+ * PCI passthrough export or import declaration.
+ * @param   type    The return type of the function declaration.
+ */
+#ifdef IN_PCIRAW_R3
+# define PCIRAWR3DECL(type) DECLEXPORT(type) VBOXCALL
+#else
+# define PCIRAWR3DECL(type) DECLIMPORT(type) VBOXCALL
+#endif
+
+/** @def IN_PCIRAW_R0
+ * Used to indicate whether we're inside the same link module as the R0
+ * PCI passthrough support.
+ */
+/** @def PCIRAWR0DECL(type)
+ * PCI passthroug export or import declaration.
+ * @param   type    The return type of the function declaration.
+ */
+#ifdef IN_PCIRAW_R0
+# define PCIRAWR0DECL(type) DECLEXPORT(type) VBOXCALL
+#else
+# define PCIRAWR0DECL(type) DECLIMPORT(type) VBOXCALL
+#endif
+
+
+
+/** @def IN_REM_R3
+ * Used to indicate whether we're inside the same link module as
+ * the HC Ring-3 Recompiled Execution Manager.
+ */
+/** @def REMR3DECL(type)
+ * Recompiled Execution Manager HC Ring-3 export or import declaration.
+ * @param   type    The return type of the function declaration.
+ */
+#ifdef IN_REM_R3
+# define REMR3DECL(type)    DECLEXPORT(type) VBOXCALL
+#else
+# define REMR3DECL(type)    DECLIMPORT(type) VBOXCALL
+#endif
+
+
+
+/** @def IN_SUP_R3
+ * Used to indicate whether we're inside the same link module as the Ring-3
+ * Support Library or not.
+ */
+/** @def SUPR3DECL(type)
+ * Support library export or import declaration.
+ * @param   type    The return type of the function declaration.
+ */
+#ifdef IN_SUP_R3
+# ifdef IN_SUP_STATIC
+#  define SUPR3DECL(type)   DECLHIDDEN(type) VBOXCALL
+# else
+#  define SUPR3DECL(type)   DECLEXPORT(type) VBOXCALL
+# endif
+#else
+# ifdef IN_SUP_STATIC
+#  define SUPR3DECL(type)   DECLHIDDEN(type) VBOXCALL
+# else
+#  define SUPR3DECL(type)   DECLIMPORT(type) VBOXCALL
+# endif
+#endif
+
+/** @def IN_SUP_R0
+ * Used to indicate whether we're inside the same link module as the Ring-0
+ * Support Library or not.
+ */
+/** @def IN_SUP_STATIC
+ * Used to indicate that the Support Library is built or used as a static
+ * library.
+ */
+/** @def SUPR0DECL(type)
+ * Support library export or import declaration.
+ * @param   type    The return type of the function declaration.
+ */
+#ifdef IN_SUP_R0
+# ifdef IN_SUP_STATIC
+#  define SUPR0DECL(type)   DECLHIDDEN(type) VBOXCALL
+# else
+#  define SUPR0DECL(type)   DECLEXPORT(type) VBOXCALL
+# endif
+#else
+# ifdef IN_SUP_STATIC
+#  define SUPR0DECL(type)   DECLHIDDEN(type) VBOXCALL
+# else
+#  define SUPR0DECL(type)   DECLIMPORT(type) VBOXCALL
+# endif
+#endif
+
+/** @def IN_SUP_RC
+ * Used to indicate whether we're inside the same link module as the RC Support
+ * Library or not.
+ */
+/** @def SUPRCDECL(type)
+ * Support library export or import declaration.
+ * @param   type    The return type of the function declaration.
+ */
+#ifdef IN_SUP_RC
+# define SUPRCDECL(type)    DECLEXPORT(type) VBOXCALL
+#else
+# define SUPRCDECL(type)    DECLIMPORT(type) VBOXCALL
+#endif
+
+/** @def IN_SUP_R0
+ * Used to indicate whether we're inside the same link module as the Ring-0
+ * Support Library or not.
+ */
+/** @def SUPR0DECL(type)
+ * Support library export or import declaration.
+ * @param   type    The return type of the function declaration.
+ */
+#if defined(IN_SUP_R0) || defined(IN_SUP_R3) || defined(IN_SUP_RC)
+# define SUPDECL(type)      DECLEXPORT(type) VBOXCALL
+#else
+# define SUPDECL(type)      DECLIMPORT(type) VBOXCALL
+#endif
+
+
+
+/** @def IN_USBLIB
+ * Used to indicate whether we're inside the same link module as the USBLib.
+ */
+/** @def USBLIB_DECL
+ * USBLIB export or import declaration.
+ * @param   type    The return type of the function declaration.
+ */
+#ifdef IN_RING0
+# define USBLIB_DECL(type)   type VBOXCALL
+#elif defined(IN_USBLIB)
+# define USBLIB_DECL(type)   DECLEXPORT(type) VBOXCALL
+#else
+# define USBLIB_DECL(type)   DECLIMPORT(type) VBOXCALL
+#endif
+
+
+
+/** @def IN_VMM_STATIC
+ * Used to indicate that the virtual machine monitor is built or used as a
+ * static library.
+ */
+/** @def IN_VMM_R3
+ * Used to indicate whether we're inside the same link module as the ring 3 part of the
+ * virtual machine monitor or not.
+ */
+/** @def VMMR3DECL
+ * Ring-3 VMM export or import declaration.
+ * @param   type    The return type of the function declaration.
+ */
+#ifdef IN_VMM_R3
+# ifdef IN_VMM_STATIC
+#  define VMMR3DECL(type)           DECLHIDDEN(type) VBOXCALL
+# else
+#  define VMMR3DECL(type)           DECLEXPORT(type) VBOXCALL
+# endif
+#elif defined(IN_RING3)
+# ifdef IN_VMM_STATIC
+#  define VMMR3DECL(type)           DECLHIDDEN(type) VBOXCALL
+# else
+#  define VMMR3DECL(type)           DECLIMPORT(type) VBOXCALL
+# endif
+#else
+# define VMMR3DECL(type)            DECL_INVALID(type)
+#endif
+
+/** @def IN_VMM_R0
+ * Used to indicate whether we're inside the same link module as the ring-0 part
+ * of the virtual machine monitor or not.
+ */
+/** @def VMMR0DECL
+ * Ring-0 VMM export or import declaration.
+ * @param   type    The return type of the function declaration.
+ */
+#ifdef IN_VMM_R0
+# define VMMR0DECL(type)            DECLEXPORT(type) VBOXCALL
+#elif defined(IN_RING0)
+# define VMMR0DECL(type)            DECLIMPORT(type) VBOXCALL
+#else
+# define VMMR0DECL(type)            DECL_INVALID(type)
+#endif
+
+/** @def IN_VMM_RC
+ * Used to indicate whether we're inside the same link module as the raw-mode
+ * context part of the virtual machine monitor or not.
+ */
+/** @def VMMRCDECL
+ * Raw-mode context VMM export or import declaration.
+ * @param   type    The return type of the function declaration.
+ */
+#ifdef IN_VMM_RC
+# define VMMRCDECL(type)            DECLEXPORT(type) VBOXCALL
+#elif defined(IN_RC)
+# define VMMRCDECL(type)            DECLIMPORT(type) VBOXCALL
+#else
+# define VMMRCDECL(type)            DECL_INVALID(type)
+#endif
+
+/** @def VMMRZDECL
+ * Ring-0 and Raw-mode context VMM export or import declaration.
+ * @param   type    The return type of the function declaration.
+ */
+#if defined(IN_VMM_R0) || defined(IN_VMM_RC)
+# define VMMRZDECL(type)            DECLEXPORT(type) VBOXCALL
+#elif defined(IN_RING0) || defined(IN_RZ)
+# define VMMRZDECL(type)            DECLIMPORT(type) VBOXCALL
+#else
+# define VMMRZDECL(type)            DECL_INVALID(type)
+#endif
+
+/** @def VMMDECL
+ * VMM export or import declaration.
+ * @param   type    The return type of the function declaration.
+ */
+#ifdef IN_VMM_STATIC
+# define VMMDECL(type)              DECLHIDDEN(type) VBOXCALL
+#elif defined(IN_VMM_R3) || defined(IN_VMM_R0) || defined(IN_VMM_RC)
+# define VMMDECL(type)              DECLEXPORT(type) VBOXCALL
+#else
+# define VMMDECL(type)              DECLIMPORT(type) VBOXCALL
+#endif
+
+/** @def VMM_INT_DECL
+ * VMM internal function.
+ * @param   type    The return type of the function declaration.
+ */
+#if defined(IN_VMM_R3) || defined(IN_VMM_R0) || defined(IN_VMM_RC)
+# define VMM_INT_DECL(type)         DECLHIDDEN(type) VBOXCALL
+#else
+# define VMM_INT_DECL(type)         DECL_INVALID(type)
+#endif
+
+/** @def VMMR3_INT_DECL
+ * VMM internal function, ring-3.
+ * @param   type    The return type of the function declaration.
+ */
+#ifdef IN_VMM_R3
+# define VMMR3_INT_DECL(type)       DECLHIDDEN(type) VBOXCALL
+#else
+# define VMMR3_INT_DECL(type)       DECL_INVALID(type)
+#endif
+
+/** @def VMMR0_INT_DECL
+ * VMM internal function, ring-0.
+ * @param   type    The return type of the function declaration.
+ */
+#ifdef IN_VMM_R0
+# define VMMR0_INT_DECL(type)       DECLHIDDEN(type) VBOXCALL
+#else
+# define VMMR0_INT_DECL(type)       DECL_INVALID(type)
+#endif
+
+/** @def VMMRC_INT_DECL
+ * VMM internal function, raw-mode context.
+ * @param   type    The return type of the function declaration.
+ */
+#ifdef IN_VMM_RC
+# define VMMRC_INT_DECL(type)       DECLHIDDEN(type) VBOXCALL
+#else
+# define VMMRC_INT_DECL(type)       DECL_INVALID(type)
+#endif
+
+/** @def VMMRZ_INT_DECL
+ * VMM internal function, ring-0 + raw-mode context.
+ * @param   type    The return type of the function declaration.
+ */
+#if defined(IN_VMM_RC) || defined(IN_VMM_R0)
+# define VMMRZ_INT_DECL(type)       DECLHIDDEN(type) VBOXCALL
+#else
+# define VMMRZ_INT_DECL(type)       DECL_INVALID(type)
+#endif
+
+
+
+/** @def IN_VBOXDDU
+ * Used to indicate whether we're inside the VBoxDDU shared object.
+ */
+/** @def VBOXDDU_DECL(type)
+ * VBoxDDU export or import (ring-3).
+ * @param   type    The return type of the function declaration.
+ */
+#ifdef IN_VBOXDDU
+# ifdef IN_VBOXDDU_STATIC
+#  define VBOXDDU_DECL(type) type
+# else
+#  define VBOXDDU_DECL(type) DECLEXPORT(type) VBOXCALL
+# endif
+#else
+# define VBOXDDU_DECL(type) DECLIMPORT(type) VBOXCALL
+#endif
+
+/** @} */
+
+
+/** @defgroup grp_devdrv    Device Emulations and Drivers
+ * @{ */
+/** @} */
+
+#endif
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/include/VBox/err.h
@@ -0,0 +1,2714 @@
+/** @file
+ * VirtualBox Status Codes.
+ */
+
+/*
+ * Copyright (C) 2006-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+#ifndef ___VBox_err_h
+#define ___VBox_err_h
+
+#include <VBox/cdefs.h>
+#include <iprt/err.h>
+
+
+/** @defgroup grp_err       VBox Error Codes
+ * @{
+ */
+
+/* SED-START */
+
+/** @name Misc. Status Codes
+ * @{
+ */
+/** Failed to allocate VM memory. */
+#define VERR_NO_VM_MEMORY                   (-1000)
+/** RC is toasted and the VMM should be terminated at once, but no need to
+ * panic about it :-) */
+#define VERR_DONT_PANIC                     (-1001)
+/** Unsupported CPU. */
+#define VERR_UNSUPPORTED_CPU                (-1002)
+/** Unsupported CPU mode. */
+#define VERR_UNSUPPORTED_CPU_MODE           (-1003)
+/** Page not present. */
+#define VERR_PAGE_NOT_PRESENT               (-1004)
+/** Invalid/Corrupted configuration file. */
+#define VERR_CFG_INVALID_FORMAT             (-1005)
+/** No configuration value exists. */
+#define VERR_CFG_NO_VALUE                   (-1006)
+/** Selector not present. */
+#define VERR_SELECTOR_NOT_PRESENT           (-1007)
+/** Not code selector. */
+#define VERR_NOT_CODE_SELECTOR              (-1008)
+/** Not data selector. */
+#define VERR_NOT_DATA_SELECTOR              (-1009)
+/** Out of selector bounds. */
+#define VERR_OUT_OF_SELECTOR_BOUNDS         (-1010)
+/** Invalid selector. Usually beyond table limits. */
+#define VERR_INVALID_SELECTOR               (-1011)
+/** Invalid requested privilege level. */
+#define VERR_INVALID_RPL                    (-1012)
+/** PML4 entry not present. */
+#define VERR_PAGE_MAP_LEVEL4_NOT_PRESENT    (-1013)
+/** Page directory pointer not present. */
+#define VERR_PAGE_DIRECTORY_PTR_NOT_PRESENT (-1014)
+/** Raw mode doesn't support SMP. */
+#define VERR_RAW_MODE_INVALID_SMP           (-1015)
+/** Invalid VM handle. */
+#define VERR_INVALID_VM_HANDLE              (-1016)
+/** Invalid VM handle. */
+#define VERR_INVALID_VMCPU_HANDLE           (-1017)
+/** Invalid Virtual CPU ID. */
+#define VERR_INVALID_CPU_ID                 (-1018)
+/** Too many VCPUs. */
+#define VERR_TOO_MANY_CPUS                  (-1019)
+/** The service was disabled on the host.
+ * Returned by pfnInit in VBoxService to indicated a non-fatal error that
+ * should results in the particular service being disabled. */
+#define VERR_SERVICE_DISABLED               (-1020)
+/** The requested feature is not supported in raw-mode. */
+#define VERR_NOT_SUP_IN_RAW_MODE            (-1021)
+/** Invalid CPU index. */
+#define VERR_INVALID_CPU_INDEX              (-1022)
+/** This VirtualBox build does not support raw-mode. */
+#define VERR_RAW_MODE_NOT_SUPPORTED         (-1023)
+/** @} */
+
+
+/** @name Execution Monitor/Manager (EM) Status Codes
+ *
+ * The order of the status codes between VINF_EM_FIRST and VINF_EM_LAST
+ * are of vital importance. The lower the number the higher importance
+ * as a scheduling instruction.
+ * @{
+ */
+/** First scheduling related status code. */
+#define VINF_EM_FIRST                       1100
+/** Indicating that the VM is being terminated and that the execution
+ * shall stop. */
+#define VINF_EM_TERMINATE                   1100
+/** Hypervisor code was stepped.
+ * EM will first send this to the debugger, and if the issue isn't
+ * resolved there it will enter guru meditation. */
+#define VINF_EM_DBG_HYPER_STEPPED           1101
+/** Hit a breakpoint in the hypervisor code,
+ * EM will first send this to the debugger, and if the issue isn't
+ * resolved there it will enter guru meditation. */
+#define VINF_EM_DBG_HYPER_BREAKPOINT        1102
+/** Hit a possible assertion in the hypervisor code,
+ * EM will first send this to the debugger, and if the issue isn't
+ * resolved there it will enter guru meditation. */
+#define VINF_EM_DBG_HYPER_ASSERTION         1103
+/** Indicating that the VM should be suspended for debugging because
+ * the developer wants to inspect the VM state. */
+#define VINF_EM_DBG_STOP                    1105
+/** Indicating success single stepping and that EM should report that
+ * event to the debugger. */
+#define VINF_EM_DBG_STEPPED                 1106
+/** Indicating that a breakpoint was hit and that EM should notify the debugger
+ * and in the event there is no debugger fail fatally. */
+#define VINF_EM_DBG_BREAKPOINT              1107
+/** Indicating that EM should single step an instruction.
+ * The instruction is stepped in the current execution mode (RAW/REM). */
+#define VINF_EM_DBG_STEP                    1108
+/** Indicating that the VM is being turned off and that the EM should
+ * exit to the VM awaiting the destruction request. */
+#define VINF_EM_OFF                         1109
+/** Indicating that the VM has been suspended and that the thread
+ * should wait for request telling it what to do next. */
+#define VINF_EM_SUSPEND                     1110
+/** Indicating that the VM has been reset and that scheduling goes
+ * back to startup defaults. */
+#define VINF_EM_RESET                       1111
+/** Indicating that the VM has executed a halt instruction and that
+ * the emulation thread should wait for an interrupt before resuming
+ * execution. */
+#define VINF_EM_HALT                        1112
+/** Indicating that the VM has been resumed and that the thread should
+ * start executing. */
+#define VINF_EM_RESUME                      1113
+/** Indicating that we've got an out-of-memory condition and that we need
+ * to take the appropriate actions to deal with this.
+ * @remarks It might seem odd at first that this has lower priority than VINF_EM_HALT,
+ *          VINF_EM_SUSPEND, and VINF_EM_RESUME. The reason is that these events are
+ *          vital to correctly operating the VM. Also, they can't normally occur together
+ *          with an out-of-memory condition, and even if that should happen the condition
+ *          will be rediscovered before executing any more code. */
+#define VINF_EM_NO_MEMORY                   1114
+/** The fatal variant of VINF_EM_NO_MEMORY. */
+#define VERR_EM_NO_MEMORY                   (-1114)
+/** Indicating that a rescheduling to recompiled execution.
+ * Typically caused by raw-mode executing code which is difficult/slow
+ * to virtualize rawly.
+ * @remarks Important to have a higher priority (lower number) than the other rescheduling status codes. */
+#define VINF_EM_RESCHEDULE_REM              1115
+/** Indicating that a rescheduling to vmx-mode execution.
+ * Typically caused by REM detecting that hardware-accelerated raw-mode execution is possible. */
+#define VINF_EM_RESCHEDULE_HM            1116
+/** Indicating that a rescheduling to raw-mode execution.
+ * Typically caused by REM detecting that raw-mode execution is possible.
+ * @remarks Important to have a higher priority (lower number) than VINF_EM_RESCHEDULE. */
+#define VINF_EM_RESCHEDULE_RAW              1117
+/** Indicating that a rescheduling now is required. Typically caused by
+ * interrupts having changed the EIP. */
+#define VINF_EM_RESCHEDULE                  1118
+/** PARAV call */
+#define VINF_EM_RESCHEDULE_PARAV            1119
+/** Go back into wait for SIPI mode */
+#define VINF_EM_WAIT_SIPI                   1120
+/** Last scheduling related status code. (inclusive) */
+#define VINF_EM_LAST                        1120
+
+/** Reason for leaving RC: Guest trap which couldn't be handled in RC.
+ * The trap is generally forwarded to the REM and executed there. */
+#define VINF_EM_RAW_GUEST_TRAP              1121
+/** Reason for leaving RC: Interrupted by external interrupt.
+ * The interrupt needed to be handled by the host OS. */
+#define VINF_EM_RAW_INTERRUPT               1122
+/** Reason for leaving RC: Interrupted by external interrupt while in hypervisor
+ * code. The interrupt needed to be handled by the host OS and hypervisor
+ * execution must be resumed. VM state is not complete at this point. */
+#define VINF_EM_RAW_INTERRUPT_HYPER         1123
+/** Reason for leaving RC: A Ring switch was attempted.
+ * Normal cause of action is to execute this in REM. */
+#define VINF_EM_RAW_RING_SWITCH             1124
+/** Reason for leaving RC: A Ring switch was attempted using software interrupt.
+ * Normal cause of action is to execute this in REM. */
+#define VINF_EM_RAW_RING_SWITCH_INT         1125
+/** Reason for leaving RC: A privileged instruction was attempted executed.
+ * Normal cause of action is to execute this in REM. */
+#define VINF_EM_RAW_EXCEPTION_PRIVILEGED    1126
+
+/** Reason for leaving RZ: Emulate instruction. */
+#define VINF_EM_RAW_EMULATE_INSTR           1127
+/** Reason for leaving RC: Unhandled TSS write.
+ * Recompiler gets control. */
+#define VINF_EM_RAW_EMULATE_INSTR_TSS_FAULT 1128
+/** Reason for leaving RC: Unhandled LDT write.
+ * Recompiler gets control. */
+#define VINF_EM_RAW_EMULATE_INSTR_LDT_FAULT 1129
+/** Reason for leaving RC: Unhandled IDT write.
+ * Recompiler gets control. */
+#define VINF_EM_RAW_EMULATE_INSTR_IDT_FAULT 1130
+/** Reason for leaving RC: Partly handled GDT write.
+ * Recompiler gets control. */
+#define VINF_EM_RAW_EMULATE_INSTR_GDT_FAULT 1131
+/** Reason for leaving RC: jump inside generated patch jump.
+ * Fatal error. */
+#define VERR_EM_RAW_PATCH_CONFLICT          (-1133)
+/** Reason for leaving RZ: Ring-3 operation pending. */
+#define VINF_EM_RAW_TO_R3                   1135
+/** Reason for leaving RZ: Timer pending. */
+#define VINF_EM_RAW_TIMER_PENDING           1136
+/** Reason for leaving RC: Interrupt pending (guest). */
+#define VINF_EM_RAW_INTERRUPT_PENDING       1137
+/** Reason for leaving RC: Encountered a stale selector. */
+#define VINF_EM_RAW_STALE_SELECTOR          1138
+/** Reason for leaving RC: The IRET resuming guest code trapped. */
+#define VINF_EM_RAW_IRET_TRAP               1139
+/** Reason for leaving RC: Emulate (MM)IO intensive code in the recompiler. */
+#define VINF_EM_RAW_EMULATE_IO_BLOCK        1140
+/** The interpreter was unable to deal with the instruction at hand. */
+#define VERR_EM_INTERPRETER                 (-1148)
+/** Internal EM error caused by an unknown warning or informational status code. */
+#define VERR_EM_INTERNAL_ERROR              (-1149)
+/** Pending VM request packet. */
+#define VINF_EM_PENDING_REQUEST             1150
+/** Start instruction stepping (debug only). */
+#define VINF_EM_RAW_EMULATE_DBG_STEP        1151
+/** Patch TPR access instruction. */
+#define VINF_EM_HM_PATCH_TPR_INSTR          1152
+/** Unexpected guest mapping conflict detected. */
+#define VERR_EM_UNEXPECTED_MAPPING_CONFLICT (-1154)
+/** Reason for leaving RC: A triple-fault condition. Currently, causes
+ *  a guru meditation. */
+#define VINF_EM_TRIPLE_FAULT                1155
+/** The specified execution engine cannot execute guest code in the current
+ *  state. */
+#define VERR_EM_CANNOT_EXEC_GUEST           (-1156)
+/** Reason for leaving RC: Inject a TRPM event. */
+#define VINF_EM_RAW_INJECT_TRPM_EVENT       1157
+/** Guest tried to trigger a CPU hang.  The guest is probably up to no good. */
+#define VERR_EM_GUEST_CPU_HANG              (-1158)
+/** @} */
+
+
+/** @name Debugging Facility (DBGF) DBGF Status Codes
+ * @{
+ */
+/** The function called requires the caller to be attached as a
+ * debugger to the VM. */
+#define VERR_DBGF_NOT_ATTACHED              (-1200)
+/** Someone (including the caller) was already attached as
+ * debugger to the VM. */
+#define VERR_DBGF_ALREADY_ATTACHED          (-1201)
+/** Tried to halt a debugger which was already halted.
+ * (This is a warning and not an error.) */
+#define VWRN_DBGF_ALREADY_HALTED            1202
+/** The DBGF has no more free breakpoint slots. */
+#define VERR_DBGF_NO_MORE_BP_SLOTS          (-1203)
+/** The DBGF couldn't find the specified breakpoint. */
+#define VERR_DBGF_BP_NOT_FOUND              (-1204)
+/** Attempted to enabled a breakpoint which was already enabled. */
+#define VINF_DBGF_BP_ALREADY_ENABLED        1205
+/** Attempted to disabled a breakpoint which was already disabled. */
+#define VINF_DBGF_BP_ALREADY_DISABLED       1206
+/** The breakpoint already exists. */
+#define VINF_DBGF_BP_ALREADY_EXIST          1207
+/** The byte string was not found. */
+#define VERR_DBGF_MEM_NOT_FOUND             (-1208)
+/** The OS was not detected. */
+#define VERR_DBGF_OS_NOT_DETCTED            (-1209)
+/** The OS was not detected. */
+#define VINF_DBGF_OS_NOT_DETCTED            1209
+/** The specified register was not found. */
+#define VERR_DBGF_REGISTER_NOT_FOUND        (-1210)
+/** The value was truncated to fit.
+ * For queries this means that the register is wider than the queried value.
+ * For setters this means that the value is wider than the register. */
+#define VINF_DBGF_TRUNCATED_REGISTER        1211
+/** The value was zero extended to fit.
+ * For queries this means that the register is narrower than the queried value.
+ * For setters this means that the value is narrower than the register. */
+#define VINF_DBGF_ZERO_EXTENDED_REGISTER    1212
+/** The requested type conversion was not supported. */
+#define VERR_DBGF_UNSUPPORTED_CAST          (-1213)
+/** The register is read-only and cannot be modified. */
+#define VERR_DBGF_READ_ONLY_REGISTER        (-1214)
+/** Internal processing error \#1 in the DBGF register code. */
+#define VERR_DBGF_REG_IPE_1                 (-1215)
+/** Internal processing error \#2 in the DBGF register code. */
+#define VERR_DBGF_REG_IPE_2                 (-1216)
+/** Unhandled \#DB in hypervisor code. */
+#define VERR_DBGF_HYPER_DB_XCPT             (-1217)
+/** Internal processing error \#1 in the DBGF stack code. */
+#define VERR_DBGF_STACK_IPE_1               (-1218)
+/** Internal processing error \#2 in the DBGF stack code. */
+#define VERR_DBGF_STACK_IPE_2               (-1219)
+/** No trace buffer available, please change the VM config. */
+#define VERR_DBGF_NO_TRACE_BUFFER           (-1220)
+/** @} */
+
+
+/** @name Patch Manager (PATM) Status Codes
+ * @{
+ */
+/** Non fatal Patch Manager analysis phase warning */
+#define VWRN_CONTINUE_ANALYSIS              1400
+/** Non fatal Patch Manager recompile phase warning (mapped to VWRN_CONTINUE_ANALYSIS). */
+#define VWRN_CONTINUE_RECOMPILE             VWRN_CONTINUE_ANALYSIS
+/** Continue search (mapped to VWRN_CONTINUE_ANALYSIS). */
+#define VWRN_PATM_CONTINUE_SEARCH           VWRN_CONTINUE_ANALYSIS
+/** Patch installation refused (patch too complex or unsupported instructions ) */
+#define VERR_PATCHING_REFUSED               (-1401)
+/** Unable to find patch */
+#define VERR_PATCH_NOT_FOUND                (-1402)
+/** Patch disabled */
+#define VERR_PATCH_DISABLED                 (-1403)
+/** Patch enabled */
+#define VWRN_PATCH_ENABLED                  1404
+/** Patch was already disabled */
+#define VERR_PATCH_ALREADY_DISABLED         (-1405)
+/** Patch was already enabled */
+#define VERR_PATCH_ALREADY_ENABLED          (-1406)
+/** Patch was removed. */
+#define VWRN_PATCH_REMOVED                  1407
+
+/** Reason for leaving RC: \#GP with EIP pointing to patch code. */
+#define VINF_PATM_PATCH_TRAP_GP             1408
+/** First leave RC code. */
+#define VINF_PATM_LEAVE_RC_FIRST             VINF_PATM_PATCH_TRAP_GP
+/** Reason for leaving RC: \#PF with EIP pointing to patch code. */
+#define VINF_PATM_PATCH_TRAP_PF             1409
+/** Reason for leaving RC: int3 with EIP pointing to patch code. */
+#define VINF_PATM_PATCH_INT3                1410
+/** Reason for leaving RC: \#PF for monitored patch page. */
+#define VINF_PATM_CHECK_PATCH_PAGE          1411
+/** Reason for leaving RC: duplicate instruction called at current eip. */
+#define VINF_PATM_DUPLICATE_FUNCTION        1412
+/** Execute one instruction with the recompiler */
+#define VINF_PATCH_EMULATE_INSTR            1413
+/** Reason for leaving RC: attempt to patch MMIO write. */
+#define VINF_PATM_HC_MMIO_PATCH_WRITE       1414
+/** Reason for leaving RC: attempt to patch MMIO read. */
+#define VINF_PATM_HC_MMIO_PATCH_READ        1415
+/** Reason for leaving RC: pending irq after iret that sets IF. */
+#define VINF_PATM_PENDING_IRQ_AFTER_IRET    1416
+/** Last leave RC code. */
+#define VINF_PATM_LEAVE_RC_LAST              VINF_PATM_PENDING_IRQ_AFTER_IRET
+
+/** No conflicts to resolve */
+#define VERR_PATCH_NO_CONFLICT              (-1425)
+/** Detected unsafe code for patching */
+#define VERR_PATM_UNSAFE_CODE               (-1426)
+/** Terminate search branch */
+#define VWRN_PATCH_END_BRANCH                1427
+/** Already patched */
+#define VERR_PATM_ALREADY_PATCHED           (-1428)
+/** Spinlock detection failed. */
+#define VINF_PATM_SPINLOCK_FAILED           (1429)
+/** Continue execution after patch trap. */
+#define VINF_PATCH_CONTINUE                 (1430)
+/** The patch manager is not used because we're using HM and VT-x/AMD-V. */
+#define VERR_PATM_HM_IPE                    (-1431)
+/** Unexpected trap in patch code. */
+#define VERR_PATM_IPE_TRAP_IN_PATCH_CODE    (-1432)
+
+/** @} */
+
+
+/** @name Code Scanning and Analysis Manager (CSAM) Status Codes
+ * @{
+ */
+/** Trap not handled */
+#define VWRN_CSAM_TRAP_NOT_HANDLED          1500
+/** Patch installed */
+#define VWRN_CSAM_INSTRUCTION_PATCHED       1501
+/** Page record not found */
+#define VWRN_CSAM_PAGE_NOT_FOUND            1502
+/** Reason for leaving RC: CSAM wants perform a task in ring-3. */
+#define VINF_CSAM_PENDING_ACTION            1503
+/** The CSAM is not used because we're using HM and VT-x/AMD-V. */
+#define VERR_CSAM_HM_IPE                    (-1504)
+/** @} */
+
+
+/** @name Page Monitor/Manager (PGM) Status Codes
+ * @{
+ */
+/** Attempt to create a GC mapping which conflicts with an existing mapping. */
+#define VERR_PGM_MAPPING_CONFLICT           (-1600)
+/** The physical handler range has no corresponding RAM range.
+ * If this is MMIO, see todo above the return. If not MMIO, then it's
+ * someone else's fault... */
+#define VERR_PGM_HANDLER_PHYSICAL_NO_RAM_RANGE (-1601)
+/** Attempt to register an access handler for a virtual range of which a part
+ * was already handled. */
+#define VERR_PGM_HANDLER_VIRTUAL_CONFLICT   (-1602)
+/** Attempt to register an access handler for a physical range of which a part
+ * was already handled. */
+#define VERR_PGM_HANDLER_PHYSICAL_CONFLICT  (-1603)
+/** Invalid page directory specified to PGM. */
+#define VERR_PGM_INVALID_PAGE_DIRECTORY     (-1604)
+/** Invalid GC physical address. */
+#define VERR_PGM_INVALID_GC_PHYSICAL_ADDRESS (-1605)
+/** Invalid GC physical range. Usually used when a specified range crosses
+ * a RAM region boundary. */
+#define VERR_PGM_INVALID_GC_PHYSICAL_RANGE  (-1606)
+/** Specified access handler was not found. */
+#define VERR_PGM_HANDLER_NOT_FOUND          (-1607)
+/** Attempt to register a RAM range of which parts are already
+ * covered by existing RAM ranges. */
+#define VERR_PGM_RAM_CONFLICT               (-1608)
+/** Failed to add new mappings because the current mappings are fixed
+ * in guest os memory. */
+#define VERR_PGM_MAPPINGS_FIXED             (-1609)
+/** Failed to fix mappings because of a conflict with the intermediate code. */
+#define VERR_PGM_MAPPINGS_FIX_CONFLICT      (-1610)
+/** Failed to fix mappings because a mapping rejected the address. */
+#define VERR_PGM_MAPPINGS_FIX_REJECTED      (-1611)
+/** Failed to fix mappings because the proposed memory area was to small. */
+#define VERR_PGM_MAPPINGS_FIX_TOO_SMALL     (-1612)
+/** Reason for leaving RZ: The urge to syncing CR3. */
+#define VINF_PGM_SYNC_CR3                   1613
+/** Page not marked for dirty bit tracking */
+#define VINF_PGM_NO_DIRTY_BIT_TRACKING      1614
+/** Page fault caused by dirty bit tracking; corrected */
+#define VINF_PGM_HANDLED_DIRTY_BIT_FAULT    1615
+/** Go ahead with the default Read/Write operation.
+ * This is returned by a R3 physical or virtual handler when it wants the
+ * PGMPhys[Read|Write] routine do the reading/writing. */
+#define VINF_PGM_HANDLER_DO_DEFAULT         1616
+/** The paging mode of the host is not supported yet. */
+#define VERR_PGM_UNSUPPORTED_HOST_PAGING_MODE (-1617)
+/** The physical guest page is a reserved/MMIO page and does not have any HC
+ *  address. */
+#define VERR_PGM_PHYS_PAGE_RESERVED         (-1618)
+/** No page directory available for the hypervisor. */
+#define VERR_PGM_NO_HYPERVISOR_ADDRESS      (-1619)
+/** The shadow page pool was flushed.
+ * This means that a global CR3 sync was flagged. Anyone receiving this kind of status
+ * will have to get down to a SyncCR3 ASAP. See also VINF_PGM_SYNC_CR3. */
+#define VERR_PGM_POOL_FLUSHED               (-1620)
+/** The shadow page pool was cleared.
+ * This is a error code internal to the shadow page pool, it will be
+ * converted to a VERR_PGM_POOL_FLUSHED before leaving the pool code. */
+#define VERR_PGM_POOL_CLEARED               (-1621)
+/** The returned shadow page is cached. */
+#define VINF_PGM_CACHED_PAGE                1622
+/** Returned by handler registration, modification and deregistration
+ * when the shadow PTs could be updated because the guest page
+ * aliased or/and mapped by multiple PTs. */
+#define VINF_PGM_GCPHYS_ALIASED             1623
+/** Reason for leaving RC: Paging mode changed.
+ * PGMChangeMode() uses this to force a switch to R3 so it can safely deal with
+ * a mode switch. */
+#define VINF_PGM_CHANGE_MODE                1624
+/** SyncPage modified the PDE.
+ * This is an internal status code used to communicate back to the \#PF handler
+ * that the PDE was (probably) marked not-present and it should restart the instruction. */
+#define VINF_PGM_SYNCPAGE_MODIFIED_PDE      1625
+/** Physical range crosses dynamic ram chunk boundary; translation to HC ptr not safe. */
+#define VERR_PGM_GCPHYS_RANGE_CROSSES_BOUNDARY  (-1626)
+/** Conflict between the core memory and the intermediate paging context, try again.
+ * There are some very special conditions applying to the intermediate paging context
+ * (used during the world switches), and some times we continuously run into these
+ * when asking the host kernel for memory during VM init. Let us know if you run into
+ * this and we'll adjust the code so it tries harder to avoid it.
+ */
+#define VERR_PGM_INTERMEDIATE_PAGING_CONFLICT   (-1627)
+/** The shadow paging mode is not supported yet. */
+#define VERR_PGM_UNSUPPORTED_SHADOW_PAGING_MODE (-1628)
+/** The dynamic mapping cache for physical memory failed. */
+#define VERR_PGM_DYNMAP_FAILED                  (-1629)
+/** The auto usage cache for the dynamic mapping set is full. */
+#define VERR_PGM_DYNMAP_FULL_SET                (-1630)
+/** The initialization of the dynamic mapping cache failed. */
+#define VERR_PGM_DYNMAP_SETUP_ERROR             (-1631)
+/** The expanding of the dynamic mapping cache failed. */
+#define VERR_PGM_DYNMAP_EXPAND_ERROR            (-1632)
+/** The page is unassigned (akin to VERR_PGM_INVALID_GC_PHYSICAL_ADDRESS). */
+#define VERR_PGM_PHYS_TLB_UNASSIGNED            (-1633)
+/** Catch any access and route it thru PGM. */
+#define VERR_PGM_PHYS_TLB_CATCH_ALL             (-1634)
+/** Catch write access and route it thru PGM. */
+#define VINF_PGM_PHYS_TLB_CATCH_WRITE           1635
+/** Catch write access and route it thru PGM. */
+#define VERR_PGM_PHYS_TLB_CATCH_WRITE           (-1635)
+/** No CR3 root shadow page table. */
+#define VERR_PGM_NO_CR3_SHADOW_ROOT             (-1636)
+/** Trying to free a page with an invalid Page ID. */
+#define VERR_PGM_PHYS_INVALID_PAGE_ID           (-1637)
+/** PGMPhysWrite/Read hit a handler in Ring-0 or raw-mode context. */
+#define VERR_PGM_PHYS_WR_HIT_HANDLER            (-1638)
+/** Trying to free a page that isn't RAM. */
+#define VERR_PGM_PHYS_NOT_RAM                   (-1639)
+/** Not ROM page. */
+#define VERR_PGM_PHYS_NOT_ROM                   (-1640)
+/** Not MMIO page. */
+#define VERR_PGM_PHYS_NOT_MMIO                  (-1641)
+/** Not MMIO2 page. */
+#define VERR_PGM_PHYS_NOT_MMIO2                 (-1642)
+/** Already aliased to a different page. */
+#define VERR_PGM_HANDLER_ALREADY_ALIASED        (-1643)
+/** Already aliased to the same page. */
+#define VINF_PGM_HANDLER_ALREADY_ALIASED        (1643)
+/** PGM pool flush pending - return to ring 3. */
+#define VINF_PGM_POOL_FLUSH_PENDING             (1644)
+/** Unable to use the range for a large page. */
+#define VERR_PGM_INVALID_LARGE_PAGE_RANGE       (-1645)
+/** Don't mess around with ballooned pages. */
+#define VERR_PGM_PHYS_PAGE_BALLOONED            (-1646)
+
+
+/** pgmPhysPageMapCommon encountered PGMPAGETYPE_MMIO2_ALIAS_MMIO. */
+#define VERR_PGM_MAP_MMIO2_ALIAS_MMIO           (-1651)
+/** Guest mappings are disabled. */
+#define VERR_PGM_MAPPINGS_DISABLED              (-1652)
+/** No guest mappings when SMP is enabled. */
+#define VERR_PGM_MAPPINGS_SMP                   (-1653)
+/** Invalid saved page state. */
+#define VERR_PGM_INVALID_SAVED_PAGE_STATE       (-1654)
+/** Encountered an unexpected page type in the saved state. */
+#define VERR_PGM_LOAD_UNEXPECTED_PAGE_TYPE      (-1655)
+/** Encountered an unexpected page state in the saved state. */
+#define VERR_PGM_UNEXPECTED_PAGE_STATE          (-1656)
+/** Couldn't find MMIO2 range from saved state. */
+#define VERR_PGM_SAVED_MMIO2_RANGE_NOT_FOUND    (-1657)
+/** Couldn't find MMIO2 page from saved state. */
+#define VERR_PGM_SAVED_MMIO2_PAGE_NOT_FOUND     (-1658)
+/** Couldn't find ROM range from saved state. */
+#define VERR_PGM_SAVED_ROM_RANGE_NOT_FOUND      (-1659)
+/** Couldn't find ROM page from saved state. */
+#define VERR_PGM_SAVED_ROM_PAGE_NOT_FOUND       (-1660)
+/** ROM page mismatch between saved state and the VM. */
+#define VERR_PGM_SAVED_ROM_PAGE_PROT            (-1661)
+/** Unknown saved state record. */
+#define VERR_PGM_SAVED_REC_TYPE                 (-1662)
+/** Internal processing error in the PGM dynmap (r0/rc). */
+#define VERR_PGM_DYNMAP_IPE                     (-1663)
+/** Internal processing error in the PGM handy page allocator. */
+#define VERR_PGM_HANDY_PAGE_IPE                 (-1664)
+/** Failed to map the guest PML4. */
+#define VERR_PGM_PML4_MAPPING                   (-1665)
+/** Failed to obtain a pool page.  */
+#define VERR_PGM_POOL_GET_PAGE_FAILED           (-1666)
+/** A PGM function was called in a mode where it isn't supposed to be used. */
+#define VERR_PGM_NOT_USED_IN_MODE               (-1667)
+/** The CR3 address specified memory we don't know about. */
+#define VERR_PGM_INVALID_CR3_ADDR               (-1668)
+/** One or the PDPEs specified memory we don't know about. */
+#define VERR_PGM_INVALID_PDPE_ADDR              (-1669)
+/** Internal processing error in the PGM physical handler code. */
+#define VERR_PGM_PHYS_HANDLER_IPE               (-1670)
+/** Internal processing error \#1 in the PGM physial page mapping code. */
+#define VERR_PGM_PHYS_PAGE_MAP_IPE_1            (-1671)
+/** Internal processing error \#2 in the PGM physial page mapping code. */
+#define VERR_PGM_PHYS_PAGE_MAP_IPE_2            (-1672)
+/** Internal processing error \#3 in the PGM physial page mapping code. */
+#define VERR_PGM_PHYS_PAGE_MAP_IPE_3            (-1673)
+/** Internal processing error \#4 in the PGM physial page mapping code. */
+#define VERR_PGM_PHYS_PAGE_MAP_IPE_4            (-1674)
+/** Too many loops looking for a page to reuse. */
+#define VERR_PGM_POOL_TOO_MANY_LOOPS            (-1675)
+/** Internal processing error related to guest mappings. */
+#define VERR_PGM_MAPPING_IPE                    (-1676)
+/** An attempt was made to grow an already maxed out page pool. */
+#define VERR_PGM_POOL_MAXED_OUT_ALREADY         (-1677)
+/** Internal processing error in the page pool code. */
+#define VERR_PGM_POOL_IPE                       (-1678)
+/** The write monitor is already engaged. */
+#define VERR_PGM_WRITE_MONITOR_ENGAGED          (-1679)
+/** Failed to get a guest page which is expected to be present.  */
+#define VERR_PGM_PHYS_PAGE_GET_IPE              (-1680)
+/** We were given a NULL pPage parameter. */
+#define VERR_PGM_PHYS_NULL_PAGE_PARAM           (-1681)
+/** PCI passthru is not supported by this build. */
+#define VERR_PGM_PCI_PASSTHRU_MISCONFIG         (-1682)
+/** Too many MMIO2 ranges. */
+#define VERR_PGM_TOO_MANY_MMIO2_RANGES          (-1683)
+/** Internal processing error in the PGM physial page mapping code dealing
+ * with MMIO2 pages. */
+#define VERR_PGM_PHYS_PAGE_MAP_MMIO2_IPE        (-1684)
+/** @} */
+
+
+/** @name Memory Monitor (MM) Status Codes
+ * @{
+ */
+/** Attempt to register a RAM range of which parts are already
+ * covered by existing RAM ranges. */
+#define VERR_MM_RAM_CONFLICT                    (-1700)
+/** Hypervisor memory allocation failed. */
+#define VERR_MM_HYPER_NO_MEMORY                 (-1701)
+/** A bad trap type ended up in mmGCRamTrap0eHandler. */
+#define VERR_MM_BAD_TRAP_TYPE_IPE               (-1702)
+/** @} */
+
+
+/** @name CPU Monitor (CPUM) Status Codes
+ * @{
+ */
+/** The caller shall raise an \#GP(0) exception. */
+#define VERR_CPUM_RAISE_GP_0                    (-1750)
+/** Incompatible CPUM configuration. */
+#define VERR_CPUM_INCOMPATIBLE_CONFIG           (-1751)
+/** CPUMR3DisasmInstrCPU unexpectedly failed to determine the hidden
+ * parts of the CS register. */
+#define VERR_CPUM_HIDDEN_CS_LOAD_ERROR          (-1752)
+/** Couldn't find the end of CPUID sub-leaves. */
+#define VERR_CPUM_TOO_MANY_CPUID_SUBLEAVES      (-1753)
+/** CPUM internal processing error \#1. */
+#define VERR_CPUM_IPE_1                         (-1754)
+/** CPUM internal processing error \#2. */
+#define VERR_CPUM_IPE_2                         (-1755)
+/** The specified CPU cannot be found in the CPU database. */
+#define VERR_CPUM_DB_CPU_NOT_FOUND              (-1756)
+/** Invalid CPUMCPU offset in MSR range. */
+#define VERR_CPUM_MSR_BAD_CPUMCPU_OFFSET        (-1757)
+/** Return to ring-3 to read the MSR there. */
+#define VINF_CPUM_R3_MSR_READ                   (1758)
+/** Return to ring-3 to write the MSR there. */
+#define VINF_CPUM_R3_MSR_WRITE                  (1759)
+/** Too many CPUID leaves. */
+#define VERR_TOO_MANY_CPUID_LEAVES              (-1760)
+/** Invalid config value. */
+#define VERR_CPUM_INVALID_CONFIG_VALUE          (-1761)
+/** The loaded XSAVE component mask is not compatible with the host CPU
+ * or/and VM config. */
+#define VERR_CPUM_INCOMPATIBLE_XSAVE_COMP_MASK  (-1762)
+/** The loaded XSAVE component mask is not valid. */
+#define VERR_CPUM_INVALID_XSAVE_COMP_MASK       (-1763)
+/** The loaded XSAVE header is not valid. */
+#define VERR_CPUM_INVALID_XSAVE_HDR             (-1764)
+/** The loaded XCR0 register value is not valid. */
+#define VERR_CPUM_INVALID_XCR0                  (-1765)
+/** @} */
+
+
+/** @name Save State Manager (SSM) Status Codes
+ * @{
+ */
+/** The specified data unit already exist. */
+#define VERR_SSM_UNIT_EXISTS                    (-1800)
+/** The specified data unit wasn't found. */
+#define VERR_SSM_UNIT_NOT_FOUND                 (-1801)
+/** The specified data unit wasn't owned by caller. */
+#define VERR_SSM_UNIT_NOT_OWNER                 (-1802)
+
+/** General saved state file integrity error. */
+#define VERR_SSM_INTEGRITY                      (-1810)
+/** The saved state file magic was not recognized. */
+#define VERR_SSM_INTEGRITY_MAGIC                (-1811)
+/** The saved state file version is not supported. */
+#define VERR_SSM_INTEGRITY_VERSION              (-1812)
+/** The saved state file size didn't match the one in the header. */
+#define VERR_SSM_INTEGRITY_SIZE                 (-1813)
+/** The CRC of the saved state file did not match. */
+#define VERR_SSM_INTEGRITY_CRC                  (-1814)
+/** The machine uuid field wasn't null. */
+#define VERR_SMM_INTEGRITY_MACHINE              (-1815)
+/** Saved state header integrity error. */
+#define VERR_SSM_INTEGRITY_HEADER               (-1816)
+/** Unit header integrity error. */
+#define VERR_SSM_INTEGRITY_UNIT                 (-1817)
+/** Invalid unit magic (internal data tag). */
+#define VERR_SSM_INTEGRITY_UNIT_MAGIC           (-1818)
+/** The file contained a data unit which no-one wants. */
+#define VERR_SSM_INTEGRITY_UNIT_NOT_FOUND       (-1819)
+/** Incorrect version numbers in the header. */
+#define VERR_SSM_INTEGRITY_VBOX_VERSION         (-1820)
+/** Footer integrity error. */
+#define VERR_SSM_INTEGRITY_FOOTER               (-1821)
+/** Record header integrity error. */
+#define VERR_SSM_INTEGRITY_REC_HDR              (-1822)
+/** Termination record integrity error. */
+#define VERR_SSM_INTEGRITY_REC_TERM             (-1823)
+/** Termination record CRC mismatch. */
+#define VERR_SSM_INTEGRITY_REC_TERM_CRC         (-1824)
+/** Decompression integrity error.  */
+#define VERR_SSM_INTEGRITY_DECOMPRESSION        (-1825)
+/** Saved state directory wintertides error.  */
+#define VERR_SSM_INTEGRITY_DIR                  (-1826)
+/** The saved state directory magic is wrong. */
+#define VERR_SSM_INTEGRITY_DIR_MAGIC            (-1827)
+
+/** A data unit in the saved state file was defined but didn't any
+ * routine for processing it. */
+#define VERR_SSM_NO_LOAD_EXEC                   (-1830)
+/** A restore routine attempted to load more data then the unit contained. */
+#define VERR_SSM_LOADED_TOO_MUCH                (-1831)
+/** Not in the correct state for the attempted operation. */
+#define VERR_SSM_INVALID_STATE                  (-1832)
+/** Not in the correct state for the attempted operation. */
+#define VERR_SSM_LOADED_TOO_LITTLE              (-1833)
+
+/** Unsupported data unit version.
+ * A SSM user returns this if it doesn't know the u32Version. */
+#define VERR_SSM_UNSUPPORTED_DATA_UNIT_VERSION  (-1840)
+/** The format of a data unit has changed.
+ * A SSM user returns this if it's not able to read the format for
+ * other reasons than u32Version. */
+#define VERR_SSM_DATA_UNIT_FORMAT_CHANGED       (-1841)
+/** The CPUID instruction returns different information when loading than when saved.
+ * Normally caused by hardware changes on the host, but could also be caused by
+ * changes in the BIOS setup. */
+#define VERR_SSM_LOAD_CPUID_MISMATCH            (-1842)
+/** The RAM size differs between the saved state and the VM config. */
+#define VERR_SSM_LOAD_MEMORY_SIZE_MISMATCH      (-1843)
+/** The state doesn't match the VM configuration in one or another way.
+ * (There are certain PCI reconfiguration which the OS could potentially
+ * do which can cause this problem. Check this out when it happens.) */
+#define VERR_SSM_LOAD_CONFIG_MISMATCH           (-1844)
+/** The virtual clock frequency differs too much.
+ * The clock source for the virtual time isn't reliable or the code have changed. */
+#define VERR_SSM_VIRTUAL_CLOCK_HZ               (-1845)
+/** A timeout occurred while waiting for async IDE operations to finish. */
+#define VERR_SSM_IDE_ASYNC_TIMEOUT              (-1846)
+/** One of the structure magics was wrong. */
+#define VERR_SSM_STRUCTURE_MAGIC                (-1847)
+/** The data in the saved state doesn't conform to expectations. */
+#define VERR_SSM_UNEXPECTED_DATA                (-1848)
+/** Trying to read a 64-bit guest physical address into a 32-bit variable. */
+#define VERR_SSM_GCPHYS_OVERFLOW                (-1849)
+/** Trying to read a 64-bit guest virtual address into a 32-bit variable. */
+#define VERR_SSM_GCPTR_OVERFLOW                 (-1850)
+/** Vote for another pass.  */
+#define VINF_SSM_VOTE_FOR_ANOTHER_PASS          1851
+/** Vote for done tell SSM not to call again until the final pass. */
+#define VINF_SSM_VOTE_DONE_DONT_CALL_AGAIN      1852
+/** Vote for giving up.  */
+#define VERR_SSM_VOTE_FOR_GIVING_UP             (-1853)
+/** Don't call again until the final pass. */
+#define VINF_SSM_DONT_CALL_AGAIN                1854
+/** Giving up a live snapshot/teleportation attempt because of too many
+ * passes. */
+#define VERR_SSM_TOO_MANY_PASSES                (-1855)
+/** Giving up a live snapshot/teleportation attempt because the state grew to
+ * big. */
+#define VERR_SSM_STATE_GREW_TOO_BIG             (-1856)
+/** Giving up a live snapshot attempt because we're low on disk space.  */
+#define VERR_SSM_LOW_ON_DISK_SPACE              (-1857)
+/** The operation was cancelled. */
+#define VERR_SSM_CANCELLED                      (-1858)
+/** Nothing that can be cancelled.  */
+#define VERR_SSM_NO_PENDING_OPERATION           (-1859)
+/** The operation has already been cancelled. */
+#define VERR_SSM_ALREADY_CANCELLED              (-1860)
+/** The machine was powered off while saving. */
+#define VERR_SSM_LIVE_POWERED_OFF               (-1861)
+/** The live snapshot/teleportation operation was aborted because of a guru
+ *  meditation. */
+#define VERR_SSM_LIVE_GURU_MEDITATION           (-1862)
+/** The live snapshot/teleportation operation was aborted because of a fatal
+ *  runtime error. */
+#define VERR_SSM_LIVE_FATAL_ERROR               (-1863)
+/** The VM was suspended before or while saving, don't resume execution. */
+#define VINF_SSM_LIVE_SUSPENDED                  1864
+/** Complex SSM field fed to SSMR3PutStruct or SSMR3GetStruct.  Use the
+ * extended API. */
+#define VERR_SSM_FIELD_COMPLEX                  (-1864)
+/** Invalid size of a SSM field with the specified transformation. */
+#define VERR_SSM_FIELD_INVALID_SIZE             (-1865)
+/** The specified field is outside the structure.  */
+#define VERR_SSM_FIELD_OUT_OF_BOUNDS            (-1866)
+/** The field does not follow immediately the previous one. */
+#define VERR_SSM_FIELD_NOT_CONSECUTIVE          (-1867)
+/** The field contains an invalid callback or transformation index. */
+#define VERR_SSM_FIELD_INVALID_CALLBACK         (-1868)
+/** The field contains an invalid padding size. */
+#define VERR_SSM_FIELD_INVALID_PADDING_SIZE     (-1869)
+/** The field contains a value that is out of range. */
+#define VERR_SSM_FIELD_INVALID_VALUE            (-1870)
+/** Generic stream error. */
+#define VERR_SSM_STREAM_ERROR                   (-1871)
+/** SSM did a callback for a pass we didn't expect. */
+#define VERR_SSM_UNEXPECTED_PASS                (-1872)
+/** Someone is trying to skip backwards in the stream... */
+#define VERR_SSM_SKIP_BACKWARDS                 (-1873)
+/** Someone is trying to write a memory block which is too big to encode. */
+#define VERR_SSM_MEM_TOO_BIG                    (-1874)
+/** Encountered an bad (/unknown) record type. */
+#define VERR_SSM_BAD_REC_TYPE                   (-1875)
+/** Internal processing error \#1 in SSM code.  */
+#define VERR_SSM_IPE_1                          (-1876)
+/** Internal processing error \#2 in SSM code.  */
+#define VERR_SSM_IPE_2                          (-1877)
+/** Internal processing error \#3 in SSM code.  */
+#define VERR_SSM_IPE_3                          (-1878)
+/** A field contained an transformation that should only be used when loading
+ * old states. */
+#define VERR_SSM_FIELD_LOAD_ONLY_TRANSFORMATION (-1879)
+/** @} */
+
+
+/** @name Virtual Machine (VM) Status Codes
+ * @{
+ */
+/** The specified at reset handler wasn't found. */
+#define VERR_VM_ATRESET_NOT_FOUND               (-1900)
+/** Invalid VM request type.
+ * For the VMR3ReqAlloc() case, the caller just specified an illegal enmType. For
+ * all the other occurrences it means indicates corruption, broken logic, or stupid
+ * interface user. */
+#define VERR_VM_REQUEST_INVALID_TYPE            (-1901)
+/** Invalid VM request state.
+ * The state of the request packet was not the expected and accepted one(s). Either
+ * the interface user screwed up, or we've got corruption/broken logic. */
+#define VERR_VM_REQUEST_STATE                   (-1902)
+/** Invalid VM request packet.
+ * One or more of the VM controlled packet members didn't contain the correct
+ * values. Some thing's broken. */
+#define VERR_VM_REQUEST_INVALID_PACKAGE         (-1903)
+/** The status field has not been updated yet as the request is still
+ * pending completion. Someone queried the iStatus field before the request
+ * has been fully processed. */
+#define VERR_VM_REQUEST_STATUS_STILL_PENDING    (-1904)
+/** The request has been freed, don't read the status now.
+ * Someone is reading the iStatus field of a freed request packet. */
+#define VERR_VM_REQUEST_STATUS_FREED            (-1905)
+/** A VM api requiring EMT was called from another thread.
+ * Use the VMR3ReqCall() apis to call it! */
+#define VERR_VM_THREAD_NOT_EMT                  (-1906)
+/** The VM state was invalid for the requested operation.
+ * Go check the 'VM Statechart Diagram.gif'. */
+#define VERR_VM_INVALID_VM_STATE                (-1907)
+/** The support driver is not installed.
+ * On linux, open returned ENOENT. */
+#define VERR_VM_DRIVER_NOT_INSTALLED            (-1908)
+/** The support driver is not accessible.
+ * On linux, open returned EPERM. */
+#define VERR_VM_DRIVER_NOT_ACCESSIBLE           (-1909)
+/** Was not able to load the support driver.
+ * On linux, open returned ENODEV. */
+#define VERR_VM_DRIVER_LOAD_ERROR               (-1910)
+/** Was not able to open the support driver.
+ * Generic open error used when none of the other ones fit. */
+#define VERR_VM_DRIVER_OPEN_ERROR               (-1911)
+/** The installed support driver doesn't match the version of the user. */
+#define VERR_VM_DRIVER_VERSION_MISMATCH         (-1912)
+/** Saving the VM state is temporarily not allowed. Try again later. */
+#define VERR_VM_SAVE_STATE_NOT_ALLOWED          (-1913)
+/** An EMT called an API which cannot be called on such a thread. */
+#define VERR_VM_THREAD_IS_EMT                   (-1914)
+/** Encountered an unexpected VM state.  */
+#define VERR_VM_UNEXPECTED_VM_STATE             (-1915)
+/** Unexpected unstable VM state. */
+#define VERR_VM_UNEXPECTED_UNSTABLE_STATE       (-1916)
+/** Too many arguments passed to a VM request / request corruption.  */
+#define VERR_VM_REQUEST_TOO_MANY_ARGS_IPE       (-1917)
+/** Fatal EMT wait error. */
+#define VERR_VM_FATAL_WAIT_ERROR                (-1918)
+/** The VM request was killed at VM termination. */
+#define VERR_VM_REQUEST_KILLED                  (-1919)
+/** @} */
+
+
+/** @name VBox Remote Desktop Protocol (VRDP) Status Codes
+ * @{
+ */
+/** Successful completion of operation (mapped to generic iprt status code). */
+#define VINF_VRDP_SUCCESS                   VINF_SUCCESS
+/** VRDP transport operation timed out (mapped to generic iprt status code). */
+#define VERR_VRDP_TIMEOUT                   VERR_TIMEOUT
+
+/** Unsupported ISO protocol feature */
+#define VERR_VRDP_ISO_UNSUPPORTED           (-2000)
+/** Security (en/decryption) engine error */
+#define VERR_VRDP_SEC_ENGINE_FAIL           (-2001)
+/** VRDP protocol violation */
+#define VERR_VRDP_PROTOCOL_ERROR            (-2002)
+/** Unsupported VRDP protocol feature */
+#define VERR_VRDP_NOT_SUPPORTED             (-2003)
+/** VRDP protocol violation, client sends less data than expected */
+#define VERR_VRDP_INSUFFICIENT_DATA         (-2004)
+/** Internal error, VRDP packet is in wrong operation mode */
+#define VERR_VRDP_INVALID_MODE              (-2005)
+/** Memory allocation failed */
+#define VERR_VRDP_NO_MEMORY                 (-2006)
+/** Client has been rejected */
+#define VERR_VRDP_ACCESS_DENIED             (-2007)
+/** VRPD receives a packet that is not supported */
+#define VWRN_VRDP_PDU_NOT_SUPPORTED         2008
+/** VRDP script allowed the packet to be processed further */
+#define VINF_VRDP_PROCESS_PDU               2009
+/** VRDP script has completed its task */
+#define VINF_VRDP_OPERATION_COMPLETED       2010
+/** VRDP thread has started OK and will run */
+#define VINF_VRDP_THREAD_STARTED            2011
+/** Framebuffer is resized, terminate send bitmap procedure */
+#define VINF_VRDP_RESIZE_REQUESTED          2012
+/** Output can be enabled for the client. */
+#define VINF_VRDP_OUTPUT_ENABLE             2013
+/** @} */
+
+
+/** @name Configuration Manager (CFGM) Status Codes
+ * @{
+ */
+/** The integer value was too big for the requested representation. */
+#define VERR_CFGM_INTEGER_TOO_BIG           (-2100)
+/** Child node was not found. */
+#define VERR_CFGM_CHILD_NOT_FOUND           (-2101)
+/** Path to child node was invalid (i.e. empty). */
+#define VERR_CFGM_INVALID_CHILD_PATH        (-2102)
+/** Value not found. */
+#define VERR_CFGM_VALUE_NOT_FOUND           (-2103)
+/** No parent node specified. */
+#define VERR_CFGM_NO_PARENT                 (-2104)
+/** No node was specified. */
+#define VERR_CFGM_NO_NODE                   (-2105)
+/** The value is not an integer. */
+#define VERR_CFGM_NOT_INTEGER               (-2106)
+/** The value is not a zero terminated character string. */
+#define VERR_CFGM_NOT_STRING                (-2107)
+/** The value is not a byte string. */
+#define VERR_CFGM_NOT_BYTES                 (-2108)
+/** The specified string / bytes buffer was to small. Specify a larger one and retry. */
+#define VERR_CFGM_NOT_ENOUGH_SPACE          (-2109)
+/** The path of a new node contained slashes or was empty. */
+#define VERR_CFGM_INVALID_NODE_PATH         (-2160)
+/** A new node couldn't be inserted because one with the same name exists. */
+#define VERR_CFGM_NODE_EXISTS               (-2161)
+/** A new leaf couldn't be inserted because one with the same name exists. */
+#define VERR_CFGM_LEAF_EXISTS               (-2162)
+/** An unknown config value was encountered. */
+#define VERR_CFGM_CONFIG_UNKNOWN_VALUE      (-2163)
+/** An unknown config node (key) was encountered. */
+#define VERR_CFGM_CONFIG_UNKNOWN_NODE       (-2164)
+/** Internal processing error \#1 in CFGM. */
+#define VERR_CFGM_IPE_1                     (-2165)
+/** @} */
+
+
+/** @name Time Manager (TM) Status Codes
+ * @{
+ */
+/** The loaded timer state was incorrect. */
+#define VERR_TM_LOAD_STATE                  (-2200)
+/** The timer was not in the correct state for the request operation. */
+#define VERR_TM_INVALID_STATE               (-2201)
+/** The timer was in a unknown state. Corruption or stupid coding error. */
+#define VERR_TM_UNKNOWN_STATE               (-2202)
+/** The timer was stuck in an unstable state until we grew impatient and returned. */
+#define VERR_TM_UNSTABLE_STATE              (-2203)
+/** TM requires GIP. */
+#define VERR_TM_GIP_REQUIRED                (-2204)
+/** TM does not support the GIP version. */
+#define VERR_TM_GIP_VERSION                 (-2205)
+/** The GIP update interval is too large. */
+#define VERR_TM_GIP_UPDATE_INTERVAL_TOO_BIG (-2206)
+/** The timer has a bad clock enum value, probably corruption. */
+#define VERR_TM_TIMER_BAD_CLOCK             (-2207)
+/** The timer failed to reach a stable state. */
+#define VERR_TM_TIMER_UNSTABLE_STATE        (-2208)
+/** Attempt to resume a running TSC. */
+#define VERR_TM_TSC_ALREADY_TICKING         (-2209)
+/** Attempt to pause a paused TSC. */
+#define VERR_TM_TSC_ALREADY_PAUSED          (-2210)
+/** Invalid value for cVirtualTicking.  */
+#define VERR_TM_VIRTUAL_TICKING_IPE         (-2211)
+/** @} */
+
+
+/** @name Recompiled Execution Manager (REM) Status Codes
+ * @{
+ */
+/** Fatal error in virtual hardware. */
+#define VERR_REM_VIRTUAL_HARDWARE_ERROR     (-2300)
+/** Fatal error in the recompiler cpu. */
+#define VERR_REM_VIRTUAL_CPU_ERROR          (-2301)
+/** Recompiler execution was interrupted by forced action. */
+#define VINF_REM_INTERRUPED_FF              2302
+/** Too many similar traps. This is a very useful debug only
+ * check (we don't do double/triple faults in REM). */
+#define VERR_REM_TOO_MANY_TRAPS             (-2304)
+/** The REM is out of breakpoint slots. */
+#define VERR_REM_NO_MORE_BP_SLOTS           (-2305)
+/** The REM could not find any breakpoint on the specified address. */
+#define VERR_REM_BP_NOT_FOUND               (-2306)
+/** @} */
+
+
+/** @name Trap Manager / Monitor (TRPM) Status Codes
+ * @{
+ */
+/** No active trap. Cannot query or reset a non-existing trap. */
+#define VERR_TRPM_NO_ACTIVE_TRAP            (-2400)
+/** Active trap. Cannot assert a new trap when one is already active. */
+#define VERR_TRPM_ACTIVE_TRAP               (-2401)
+/** Reason for leaving RC: Guest tried to write to our IDT - fatal.
+ * The VM will be terminated assuming the worst, i.e. that the
+ * guest has read the idtr register. */
+#define VERR_TRPM_SHADOW_IDT_WRITE          (-2402)
+/** Reason for leaving RC: Fatal trap in hypervisor. */
+#define VERR_TRPM_DONT_PANIC                (-2403)
+/** Reason for leaving RC: Double Fault. */
+#define VERR_TRPM_PANIC                     (-2404)
+/** The exception was dispatched for raw-mode execution. */
+#define VINF_TRPM_XCPT_DISPATCHED           2405
+/** Bad TRPM_TRAP_IN_OP. */
+#define VERR_TRPM_BAD_TRAP_IN_OP            (-2406)
+/** Internal processing error \#1 in TRPM. */
+#define VERR_TRPM_IPE_1                     (-2407)
+/** Internal processing error \#2 in TRPM. */
+#define VERR_TRPM_IPE_2                     (-2408)
+/** Internal processing error \#3 in TRPM. */
+#define VERR_TRPM_IPE_3                     (-2409)
+/** Got into a part of TRPM that is not used when HM (VT-x/AMD-V) is enabled. */
+#define VERR_TRPM_HM_IPE                    (-2410)
+/** @} */
+
+
+/** @name Selector Manager / Monitor (SELM) Status Code
+ * @{
+ */
+/** Reason for leaving RC: Guest tried to write to our GDT - fatal.
+ * The VM will be terminated assuming the worst, i.e. that the
+ * guest has read the gdtr register. */
+#define VERR_SELM_SHADOW_GDT_WRITE          (-2500)
+/** Reason for leaving RC: Guest tried to write to our LDT - fatal.
+ * The VM will be terminated assuming the worst, i.e. that the
+ * guest has read the ldtr register. */
+#define VERR_SELM_SHADOW_LDT_WRITE          (-2501)
+/** Reason for leaving RC: Guest tried to write to our TSS - fatal.
+ * The VM will be terminated assuming the worst, i.e. that the
+ * guest has read the ltr register. */
+#define VERR_SELM_SHADOW_TSS_WRITE          (-2502)
+/** Reason for leaving RC: Sync the GDT table to solve a conflict. */
+#define VINF_SELM_SYNC_GDT                  2503
+/** No valid TSS present. */
+#define VERR_SELM_NO_TSS                    (-2504)
+/** Invalid guest LDT selector. */
+#define VERR_SELM_INVALID_LDT               (-2505)
+/** The guest LDT selector is out of bounds. */
+#define VERR_SELM_LDT_OUT_OF_BOUNDS         (-2506)
+/** Unknown error while reading the guest GDT during shadow table updating. */
+#define VERR_SELM_GDT_READ_ERROR            (-2507)
+/** The guest GDT so full that we cannot find free space for our own
+ * selectors. */
+#define VERR_SELM_GDT_TOO_FULL              (-2508)
+/** Got into a part of SELM that is not used when HM (VT-x/AMD-V) is enabled. */
+#define VERR_SELM_HM_IPE                    (-2509)
+/** @} */
+
+
+/** @name I/O Manager / Monitor (IOM) Status Code
+ * @{
+ */
+/** The specified I/O port range was invalid.
+ * It was either empty or it was out of bounds. */
+#define VERR_IOM_INVALID_IOPORT_RANGE       (-2600)
+/** The specified R0 or RC I/O port range didn't have a corresponding R3 range.
+ * IOMR3IOPortRegisterR3() must be called first. */
+#define VERR_IOM_NO_R3_IOPORT_RANGE         (-2601)
+/** The specified I/O port range intruded on an existing range. There is
+ * a I/O port conflict between two device, or a device tried to register
+ * the same range twice. */
+#define VERR_IOM_IOPORT_RANGE_CONFLICT      (-2602)
+/** The I/O port range specified for removal wasn't found or it wasn't contiguous. */
+#define VERR_IOM_IOPORT_RANGE_NOT_FOUND     (-2603)
+/** The specified I/O port range was owned by some other device(s). Both registration
+ * and deregistration, but in the first case only RC and R0 ranges. */
+#define VERR_IOM_NOT_IOPORT_RANGE_OWNER     (-2604)
+
+/** The specified MMIO range was invalid.
+ * It was either empty or it was out of bounds. */
+#define VERR_IOM_INVALID_MMIO_RANGE         (-2605)
+/** The specified R0 or RC MMIO range didn't have a corresponding R3 range.
+ * IOMR3MMIORegisterR3() must be called first. */
+#define VERR_IOM_NO_R3_MMIO_RANGE           (-2606)
+/** The specified MMIO range was owned by some other device(s). Both registration
+ * and deregistration, but in the first case only RC and R0 ranges. */
+#define VERR_IOM_NOT_MMIO_RANGE_OWNER       (-2607)
+/** The specified MMIO range intruded on an existing range. There is
+ * a MMIO conflict between two device, or a device tried to register
+ * the same range twice. */
+#define VERR_IOM_MMIO_RANGE_CONFLICT        (-2608)
+/** The MMIO range specified for removal was not found. */
+#define VERR_IOM_MMIO_RANGE_NOT_FOUND       (-2609)
+/** The MMIO range specified for removal was invalid. The range didn't match
+ * quite match a set of existing ranges. It's not possible to remove parts of
+ * a MMIO range, only one or more full ranges. */
+#define VERR_IOM_INCOMPLETE_MMIO_RANGE      (-2610)
+/** An invalid I/O port size was specified for a read or write operation. */
+#define VERR_IOM_INVALID_IOPORT_SIZE        (-2611)
+/** The MMIO handler was called for a bogus address! Internal error! */
+#define VERR_IOM_MMIO_HANDLER_BOGUS_CALL    (-2612)
+/** The MMIO handler experienced a problem with the disassembler. */
+#define VERR_IOM_MMIO_HANDLER_DISASM_ERROR  (-2613)
+/** The port being read was not present(/unused) and IOM shall return ~0 according to size. */
+#define VERR_IOM_IOPORT_UNUSED              (-2614)
+/** Unused MMIO register read, fill with 00. */
+#define VINF_IOM_MMIO_UNUSED_00             2615
+/** Unused MMIO register read, fill with FF. */
+#define VINF_IOM_MMIO_UNUSED_FF             2616
+
+/** Reason for leaving RZ: I/O port read. */
+#define VINF_IOM_R3_IOPORT_READ             2620
+/** Reason for leaving RZ: I/O port write. */
+#define VINF_IOM_R3_IOPORT_WRITE            2621
+/** Reason for leaving RZ: MMIO read. */
+#define VINF_IOM_R3_MMIO_READ               2623
+/** Reason for leaving RZ: MMIO write. */
+#define VINF_IOM_R3_MMIO_WRITE              2624
+/** Reason for leaving RZ: MMIO read/write. */
+#define VINF_IOM_R3_MMIO_READ_WRITE         2625
+
+/** IOMGCIOPortHandler was given an unexpected opcode. */
+#define VERR_IOM_IOPORT_UNKNOWN_OPCODE      (-2630)
+/** Internal processing error \#1 in the I/O port code. */
+#define VERR_IOM_IOPORT_IPE_1               (-2631)
+/** Internal processing error \#2 in the I/O port code. */
+#define VERR_IOM_IOPORT_IPE_2               (-2632)
+/** Internal processing error \#3 in the I/O port code. */
+#define VERR_IOM_IOPORT_IPE_3               (-2633)
+/** Internal processing error \#1 in the MMIO code. */
+#define VERR_IOM_MMIO_IPE_1                 (-2634)
+/** Internal processing error \#2 in the MMIO code. */
+#define VERR_IOM_MMIO_IPE_2                 (-2635)
+/** Internal processing error \#3 in the MMIO code. */
+#define VERR_IOM_MMIO_IPE_3                 (-2636)
+/** Got into a part of IOM that is not used when HM (VT-x/AMD-V) is enabled. */
+#define VERR_IOM_HM_IPE                     (-2637)
+/** @} */
+
+
+/** @name Virtual Machine Monitor (VMM) Status Codes
+ * @{
+ */
+/** Reason for leaving RZ: Calling host function. */
+#define VINF_VMM_CALL_HOST                  2700
+/** Reason for leaving R0: Hit a ring-0 assertion on EMT. */
+#define VERR_VMM_RING0_ASSERTION            (-2701)
+/** The hyper CR3 differs between PGM and CPUM. */
+#define VERR_VMM_HYPER_CR3_MISMATCH         (-2702)
+/** Reason for leaving RZ: Illegal call to ring-3. */
+#define VERR_VMM_RING3_CALL_DISABLED        (-2703)
+/** The VMMR0.r0 module version does not match VBoxVMM.dll/so/dylib.
+ * If you just upgraded VirtualBox, please terminate all VMs and make sure
+ * that neither VBoxNetDHCP nor VBoxNetNAT is running.  Then try again.
+ * If this error persists, try re-installing VirtualBox. */
+#define VERR_VMM_R0_VERSION_MISMATCH        (-2704)
+/** The VMMRC.rc module version does not match VBoxVMM.dll/so/dylib.
+ * Re-install if you are a user.  Developers should make sure the build is
+ * complete or try with a clean build. */
+#define VERR_VMM_RC_VERSION_MISMATCH        (-2705)
+/** VMM set jump error. */
+#define VERR_VMM_SET_JMP_ERROR              (-2706)
+/** VMM set jump stack overflow error. */
+#define VERR_VMM_SET_JMP_STACK_OVERFLOW     (-2707)
+/** VMM set jump resume error. */
+#define VERR_VMM_SET_JMP_ABORTED_RESUME     (-2708)
+/** VMM long jump error. */
+#define VERR_VMM_LONG_JMP_ERROR             (-2709)
+/** Unknown ring-3 call attempted. */
+#define VERR_VMM_UNKNOWN_RING3_CALL         (-2710)
+/** The ring-3 call didn't set an RC. */
+#define VERR_VMM_RING3_CALL_NO_RC           (-2711)
+/** Reason for leaving RC: Caller the tracer in ring-0. */
+#define VINF_VMM_CALL_TRACER                (2712)
+/** Internal processing error \#1 in the switcher code. */
+#define VERR_VMM_SWITCHER_IPE_1             (-2713)
+/** Reason for leaving RZ: Unknown call to ring-3. */
+#define VINF_VMM_UNKNOWN_RING3_CALL         (2714)
+/** Attempted to use stub switcher. */
+#define VERR_VMM_SWITCHER_STUB              (-2715)
+/** HM returned in the wrong state. */
+#define VERR_VMM_WRONG_HM_VMCPU_STATE       (-2716)
+/** SMAP enabled, but the AC flag was found to be clear - check the kernel
+ * log for details. */
+#define VERR_VMM_SMAP_BUT_AC_CLEAR          (-2717)
+/** @} */
+
+
+/** @name Pluggable Device and Driver Manager (PDM) Status Codes
+ * @{
+ */
+/** An invalid LUN specification was given. */
+#define VERR_PDM_NO_SUCH_LUN                        (-2800)
+/** A device encountered an unknown configuration value.
+ * This means that the device is potentially misconfigured and the device
+ * construction or unit attachment failed because of this. */
+#define VERR_PDM_DEVINS_UNKNOWN_CFG_VALUES          (-2801)
+/** The above driver doesn't export a interface required by a driver being
+ * attached to it. Typical misconfiguration problem. */
+#define VERR_PDM_MISSING_INTERFACE_ABOVE            (-2802)
+/** The below driver doesn't export a interface required by the drive
+ * having attached it. Typical misconfiguration problem. */
+#define VERR_PDM_MISSING_INTERFACE_BELOW            (-2803)
+/** A device didn't find a required interface with an attached driver.
+ * Typical misconfiguration problem. */
+#define VERR_PDM_MISSING_INTERFACE                  (-2804)
+/** A driver encountered an unknown configuration value.
+ * This means that the driver is potentially misconfigured and the driver
+ * construction failed because of this. */
+#define VERR_PDM_DRVINS_UNKNOWN_CFG_VALUES          (-2805)
+/** The PCI bus assigned to a device didn't have room for it.
+ * Either too many devices are configured on the same PCI bus, or there are
+ * some internal problem where PDM/PCI doesn't free up slots when unplugging devices. */
+#define VERR_PDM_TOO_PCI_MANY_DEVICES               (-2806)
+/** A queue is out of free items, the queueing operation failed. */
+#define VERR_PDM_NO_QUEUE_ITEMS                     (-2807)
+/** Not possible to attach further drivers to the driver.
+ * A driver which doesn't support attachments (below of course) will
+ * return this status code if it found that further drivers were configured
+ * to be attached to it. */
+#define VERR_PDM_DRVINS_NO_ATTACH                   (-2808)
+/** Not possible to attach drivers to the device.
+ * A device which doesn't support attachments (below of course) will
+ * return this status code if it found that drivers were configured
+ * to be attached to it. */
+#define VERR_PDM_DEVINS_NO_ATTACH                   (-2809)
+/** No attached driver.
+ * The PDMDRVHLP::pfnAttach and PDMDEVHLP::pfnDriverAttach will return
+ * this error when no driver was configured to be attached. */
+#define VERR_PDM_NO_ATTACHED_DRIVER                 (-2810)
+/** The media geometry hasn't been set yet, so it cannot be obtained.
+ * The caller should then calculate the geometry from the media size. */
+#define VERR_PDM_GEOMETRY_NOT_SET                   (-2811)
+/** The media translation hasn't been set yet, so it cannot be obtained.
+ * The caller should then guess the translation. */
+#define VERR_PDM_TRANSLATION_NOT_SET                (-2812)
+/** The media is not mounted, operation requires a mounted media. */
+#define VERR_PDM_MEDIA_NOT_MOUNTED                  (-2813)
+/** Mount failed because a media was already mounted. Unmount the media
+ * and retry the mount. */
+#define VERR_PDM_MEDIA_MOUNTED                      (-2814)
+/** The media is locked and cannot be unmounted. */
+#define VERR_PDM_MEDIA_LOCKED                       (-2815)
+/** No 'Type' attribute in the DrvBlock configuration.
+ * Misconfiguration. */
+#define VERR_PDM_BLOCK_NO_TYPE                      (-2816)
+/** The 'Type' attribute in the DrvBlock configuration had an unknown value.
+ * Misconfiguration. */
+#define VERR_PDM_BLOCK_UNKNOWN_TYPE                 (-2817)
+/** The 'Translation' attribute in the DrvBlock configuration had an unknown value.
+ * Misconfiguration. */
+#define VERR_PDM_BLOCK_UNKNOWN_TRANSLATION          (-2818)
+/** The block driver type wasn't supported.
+ * Misconfiguration of the kind you get when attaching a floppy to an IDE controller. */
+#define VERR_PDM_UNSUPPORTED_BLOCK_TYPE             (-2819)
+/** A attach or prepare mount call failed because the driver already
+ * had a driver attached. */
+#define VERR_PDM_DRIVER_ALREADY_ATTACHED            (-2820)
+/** An attempt on detaching a driver without anyone actually being attached, or
+ * performing any other operation on an attached driver. */
+#define VERR_PDM_NO_DRIVER_ATTACHED                 (-2821)
+/** The attached driver configuration is missing the 'Driver' attribute. */
+#define VERR_PDM_CFG_MISSING_DRIVER_NAME            (-2822)
+/** The configured driver wasn't found.
+ * Either the necessary driver modules wasn't loaded, the name was
+ * misspelled, or it was a misconfiguration. */
+#define VERR_PDM_DRIVER_NOT_FOUND                   (-2823)
+/** The Ring-3 module was already loaded. */
+#define VINF_PDM_ALREADY_LOADED                     (2824)
+/** The name of the module clashed with an existing module. */
+#define VERR_PDM_MODULE_NAME_CLASH                  (-2825)
+/** Couldn't find any export for registration of drivers/devices. */
+#define VERR_PDM_NO_REGISTRATION_EXPORT             (-2826)
+/** A module name is too long. */
+#define VERR_PDM_MODULE_NAME_TOO_LONG               (-2827)
+/** Driver name clash. Another driver with the same name as the
+ * one being registered exists. */
+#define VERR_PDM_DRIVER_NAME_CLASH                  (-2828)
+/** The version of the driver registration structure is unknown
+ * to this VBox version. Either mixing incompatible versions or
+ * the structure isn't correctly initialized. */
+#define VERR_PDM_UNKNOWN_DRVREG_VERSION             (-2829)
+/** Invalid entry in the driver registration structure. */
+#define VERR_PDM_INVALID_DRIVER_REGISTRATION        (-2830)
+/** Invalid host bit mask. */
+#define VERR_PDM_INVALID_DRIVER_HOST_BITS           (-2831)
+/** Not possible to detach a driver because the above driver/device
+ * doesn't support it. The above entity doesn't implement the pfnDetach call. */
+#define VERR_PDM_DRIVER_DETACH_NOT_POSSIBLE         (-2832)
+/** No PCI Bus is available to register the device with. This is usually a
+ * misconfiguration or in rare cases a buggy pci device. */
+#define VERR_PDM_NO_PCI_BUS                         (-2833)
+/** The device is not a registered PCI device and thus cannot
+ * perform any PCI operations. The device forgot to register it self. */
+#define VERR_PDM_NOT_PCI_DEVICE                     (-2834)
+
+/** The version of the device registration structure is unknown
+ * to this VBox version. Either mixing incompatible versions or
+ * the structure isn't correctly initialized. */
+#define VERR_PDM_UNKNOWN_DEVREG_VERSION             (-2835)
+/** Invalid entry in the device registration structure. */
+#define VERR_PDM_INVALID_DEVICE_REGISTRATION        (-2836)
+/** Invalid host bit mask. */
+#define VERR_PDM_INVALID_DEVICE_GUEST_BITS          (-2837)
+/** The guest bit mask didn't match the guest being loaded. */
+#define VERR_PDM_INVALID_DEVICE_HOST_BITS           (-2838)
+/** Device name clash. Another device with the same name as the
+ * one being registered exists. */
+#define VERR_PDM_DEVICE_NAME_CLASH                  (-2839)
+/** The device wasn't found. There was no registered device
+ * by that name. */
+#define VERR_PDM_DEVICE_NOT_FOUND                   (-2840)
+/** The device instance was not found. */
+#define VERR_PDM_DEVICE_INSTANCE_NOT_FOUND          (-2841)
+/** The device instance have no base interface. */
+#define VERR_PDM_DEVICE_INSTANCE_NO_IBASE           (-2842)
+/** The device instance have no such logical unit. */
+#define VERR_PDM_DEVICE_INSTANCE_LUN_NOT_FOUND      (-2843)
+/** The driver instance could not be found. */
+#define VERR_PDM_DRIVER_INSTANCE_NOT_FOUND          (-2844)
+/** Logical Unit was not found. */
+#define VERR_PDM_LUN_NOT_FOUND                      (-2845)
+/** The Logical Unit was found, but it had no driver attached to it. */
+#define VERR_PDM_NO_DRIVER_ATTACHED_TO_LUN          (-2846)
+/** The Logical Unit was found, but it had no driver attached to it. */
+#define VINF_PDM_NO_DRIVER_ATTACHED_TO_LUN          2846
+/** No PIC device instance is registered with the current VM and thus
+ * the PIC operation cannot be performed. */
+#define VERR_PDM_NO_PIC_INSTANCE                    (-2847)
+/** No APIC device instance is registered with the current VM and thus
+ * the APIC operation cannot be performed. */
+#define VERR_PDM_NO_APIC_INSTANCE                   (-2848)
+/** No DMAC device instance is registered with the current VM and thus
+ * the DMA operation cannot be performed. */
+#define VERR_PDM_NO_DMAC_INSTANCE                   (-2849)
+/** No RTC device instance is registered with the current VM and thus
+ * the RTC or CMOS operation cannot be performed. */
+#define VERR_PDM_NO_RTC_INSTANCE                    (-2850)
+/** Unable to open the host interface due to a sharing violation . */
+#define VERR_PDM_HIF_SHARING_VIOLATION              (-2851)
+/** Unable to open the host interface. */
+#define VERR_PDM_HIF_OPEN_FAILED                    (-2852)
+/** The device doesn't support runtime driver attaching.
+ * The PDMDEVREG::pfnAttach callback function is NULL. */
+#define VERR_PDM_DEVICE_NO_RT_ATTACH                (-2853)
+/** The driver doesn't support runtime driver attaching.
+ * The PDMDRVREG::pfnAttach callback function is NULL. */
+#define VERR_PDM_DRIVER_NO_RT_ATTACH                (-2854)
+/** Invalid host interface version. */
+#define VERR_PDM_HIF_INVALID_VERSION                (-2855)
+
+/** The version of the USB device registration structure is unknown
+ * to this VBox version. Either mixing incompatible versions or
+ * the structure isn't correctly initialized. */
+#define VERR_PDM_UNKNOWN_USBREG_VERSION             (-2856)
+/** Invalid entry in the device registration structure. */
+#define VERR_PDM_INVALID_USB_REGISTRATION           (-2857)
+/** Driver name clash. Another driver with the same name as the
+ * one being registered exists. */
+#define VERR_PDM_USB_NAME_CLASH                     (-2858)
+/** The USB hub is already registered. */
+#define VERR_PDM_USB_HUB_EXISTS                     (-2859)
+/** Couldn't find any USB hubs to attach the device to. */
+#define VERR_PDM_NO_USB_HUBS                        (-2860)
+/** Couldn't find any free USB ports to attach the device to. */
+#define VERR_PDM_NO_USB_PORTS                       (-2861)
+/** Couldn't find the USB Proxy device. Using OSE? */
+#define VERR_PDM_NO_USBPROXY                        (-2862)
+/** The async completion template is still used. */
+#define VERR_PDM_ASYNC_TEMPLATE_BUSY                (-2863)
+/** The async completion task is already suspended. */
+#define VERR_PDM_ASYNC_COMPLETION_ALREADY_SUSPENDED (-2864)
+/** The async completion task is not suspended. */
+#define VERR_PDM_ASYNC_COMPLETION_NOT_SUSPENDED     (-2865)
+/** The driver properties were invalid, and as a consequence construction
+ * failed. Caused my unusable media or similar problems. */
+#define VERR_PDM_DRIVER_INVALID_PROPERTIES          (-2866)
+/** Too many instances of a device. */
+#define VERR_PDM_TOO_MANY_DEVICE_INSTANCES          (-2867)
+/** Too many instances of a driver. */
+#define VERR_PDM_TOO_MANY_DRIVER_INSTANCES          (-2868)
+/** Too many instances of a usb device. */
+#define VERR_PDM_TOO_MANY_USB_DEVICE_INSTANCES      (-2869)
+/** The device instance structure version has changed.
+ *
+ * If you have upgraded VirtualBox recently, please make sure you have
+ * terminated all VMs and upgraded any extension packs.  If this error
+ * persists, try re-installing VirtualBox. */
+#define VERR_PDM_DEVINS_VERSION_MISMATCH            (-2870)
+/** The device helper structure version has changed.
+ *
+ * If you have upgraded VirtualBox recently, please make sure you have
+ * terminated all VMs and upgraded any extension packs.  If this error
+ * persists, try re-installing VirtualBox. */
+#define VERR_PDM_DEVHLPR3_VERSION_MISMATCH          (-2871)
+/** The USB device instance structure version has changed.
+ *
+ * If you have upgraded VirtualBox recently, please make sure you have
+ * terminated all VMs and upgraded any extension packs.  If this error
+ * persists, try re-installing VirtualBox. */
+#define VERR_PDM_USBINS_VERSION_MISMATCH            (-2872)
+/** The USB device helper structure version has changed.
+ *
+ * If you have upgraded VirtualBox recently, please make sure you have
+ * terminated all VMs and upgraded any extension packs.  If this error
+ * persists, try re-installing VirtualBox. */
+#define VERR_PDM_USBHLPR3_VERSION_MISMATCH          (-2873)
+/** The driver instance structure version has changed.
+ *
+ * If you have upgraded VirtualBox recently, please make sure you have
+ * terminated all VMs and upgraded any extension packs.  If this error
+ * persists, try re-installing VirtualBox. */
+#define VERR_PDM_DRVINS_VERSION_MISMATCH            (-2874)
+/** The driver helper structure version has changed.
+ *
+ * If you have upgraded VirtualBox recently, please make sure you have
+ * terminated all VMs and upgraded any extension packs.  If this error
+ * persists, try re-installing VirtualBox. */
+#define VERR_PDM_DRVHLPR3_VERSION_MISMATCH          (-2875)
+/** Generic device structure version mismatch.
+ *
+ * If you have upgraded VirtualBox recently, please make sure you have
+ * terminated all VMs and upgraded any extension packs.  If this error
+ * persists, try re-installing VirtualBox. */
+#define VERR_PDM_DEVICE_VERSION_MISMATCH            (-2876)
+/** Generic USB device structure version mismatch.
+ *
+ * If you have upgraded VirtualBox recently, please make sure you have
+ * terminated all VMs and upgraded any extension packs.  If this error
+ * persists, try re-installing VirtualBox. */
+#define VERR_PDM_USBDEV_VERSION_MISMATCH            (-2877)
+/** Generic driver structure version mismatch.
+ *
+ * If you have upgraded VirtualBox recently, please make sure you have
+ * terminated all VMs and upgraded any extension packs.  If this error
+ * persists, try re-installing VirtualBox. */
+#define VERR_PDM_DRIVER_VERSION_MISMATCH            (-2878)
+/** PDMVMMDevHeapR3ToGCPhys failure. */
+#define VERR_PDM_DEV_HEAP_R3_TO_GCPHYS              (-2879)
+/** A legacy device isn't implementing the HPET notification interface. */
+#define VERR_PDM_HPET_LEGACY_NOTIFY_MISSING         (-2880)
+/** Internal processing error in the critical section code. */
+#define VERR_PDM_CRITSECT_IPE                       (-2881)
+/** The critical section being deleted was not found. */
+#define VERR_PDM_CRITSECT_NOT_FOUND                 (-2882)
+/** A PDMThread API was called by the wrong thread. */
+#define VERR_PDM_THREAD_INVALID_CALLER              (-2883)
+/** Internal processing error \#1 in the PDM Thread code. */
+#define VERR_PDM_THREAD_IPE_1                       (-2884)
+/** Internal processing error \#2 in the PDM Thread code. */
+#define VERR_PDM_THREAD_IPE_2                       (-2885)
+/** Only one PCI function is supported per PDM device. */
+#define VERR_PDM_ONE_PCI_FUNCTION_PER_DEVICE        (-2886)
+/** Bad PCI configuration. */
+#define VERR_PDM_BAD_PCI_CONFIG                     (-2887)
+/** Internal processing error # in the PDM device code. */
+#define VERR_PDM_DEV_IPE_1                          (-2888)
+/** Misconfigured driver chain transformation. */
+#define VERR_PDM_MISCONFIGURED_DRV_TRANSFORMATION   (-2889)
+/** The driver is already removed, not more transformations possible (at
+ *  present). */
+#define VERR_PDM_CANNOT_TRANSFORM_REMOVED_DRIVER    (-2890)
+/** The PCI device isn't configured as a busmaster, physical memory access
+ * rejected. */
+#define VERR_PDM_NOT_PCI_BUS_MASTER                 (-2891)
+/** Got into a part of PDM that is not used when HM (VT-x/AMD-V) is enabled. */
+#define VERR_PDM_HM_IPE                             (-2892)
+/** @} */
+
+
+/** @name Host-Guest Communication Manager (HGCM) Status Codes
+ * @{
+ */
+/** Requested service does not exist. */
+#define VERR_HGCM_SERVICE_NOT_FOUND                 (-2900)
+/** Service rejected client connection */
+#define VINF_HGCM_CLIENT_REJECTED                   2901
+/** Command address is invalid. */
+#define VERR_HGCM_INVALID_CMD_ADDRESS               (-2902)
+/** Service will execute the command in background. */
+#define VINF_HGCM_ASYNC_EXECUTE                     2903
+/** HGCM could not perform requested operation because of an internal error. */
+#define VERR_HGCM_INTERNAL                          (-2904)
+/** Invalid HGCM client id. */
+#define VERR_HGCM_INVALID_CLIENT_ID                 (-2905)
+/** The HGCM is saving state. */
+#define VINF_HGCM_SAVE_STATE                        (2906)
+/** Requested service already exists. */
+#define VERR_HGCM_SERVICE_EXISTS                    (-2907)
+
+/** @} */
+
+
+/** @name Network Address Translation Driver (DrvNAT) Status Codes
+ * @{
+ */
+/** Failed to find the DNS configured for this machine. */
+#define VINF_NAT_DNS                                3000
+/** Failed to convert the specified Guest IP to a binary IP address.
+ * Malformed input. */
+#define VERR_NAT_REDIR_GUEST_IP                     (-3001)
+/** Failed while setting up a redirector rule.
+ * There probably is a conflict between the rule and some existing
+ * service on the computer. */
+#define VERR_NAT_REDIR_SETUP                        (-3002)
+/** @} */
+
+
+/** @name HostIF Driver (DrvTUN) Status Codes
+ * @{
+ */
+/** The Host Interface Networking init program failed. */
+#define VERR_HOSTIF_INIT_FAILED                     (-3100)
+/** The Host Interface Networking device name is too long. */
+#define VERR_HOSTIF_DEVICE_NAME_TOO_LONG            (-3101)
+/** The Host Interface Networking name config IOCTL call failed. */
+#define VERR_HOSTIF_IOCTL                           (-3102)
+/** Failed to make the Host Interface Networking handle non-blocking. */
+#define VERR_HOSTIF_BLOCKING                        (-3103)
+/** If a Host Interface Networking filehandle was specified it's not allowed to
+ * have any init or term programs. */
+#define VERR_HOSTIF_FD_AND_INIT_TERM                (-3104)
+/** The Host Interface Networking terminate program failed. */
+#define VERR_HOSTIF_TERM_FAILED                     (-3105)
+/** @} */
+
+
+/** @name VBox HDD Container (VD) Status Codes
+ * @{
+ */
+/** Invalid image type. */
+#define VERR_VD_INVALID_TYPE                        (-3200)
+/** Operation can't be done in current HDD container state. */
+#define VERR_VD_INVALID_STATE                       (-3201)
+/** Configuration value not found. */
+#define VERR_VD_VALUE_NOT_FOUND                     (-3202)
+/** Virtual HDD is not opened. */
+#define VERR_VD_NOT_OPENED                          (-3203)
+/** Requested image is not opened. */
+#define VERR_VD_IMAGE_NOT_FOUND                     (-3204)
+/** Image is read-only. */
+#define VERR_VD_IMAGE_READ_ONLY                     (-3205)
+/** Geometry hasn't been set. */
+#define VERR_VD_GEOMETRY_NOT_SET                    (-3206)
+/** No data for this block in image. */
+#define VERR_VD_BLOCK_FREE                          (-3207)
+/** Differencing and parent images can't be used together due to UUID. */
+#define VERR_VD_UUID_MISMATCH                       (-3208)
+/** Asynchronous I/O request finished. */
+#define VINF_VD_ASYNC_IO_FINISHED                   3209
+/** Asynchronous I/O is not finished yet. */
+#define VERR_VD_ASYNC_IO_IN_PROGRESS                (-3210)
+/** The image is too small or too large for this format. */
+#define VERR_VD_INVALID_SIZE                        (-3211)
+/** Configuration value is unknown. This indicates misconfiguration. */
+#define VERR_VD_UNKNOWN_CFG_VALUES                  (-3212)
+/** Interface is unknown. This indicates misconfiguration. */
+#define VERR_VD_UNKNOWN_INTERFACE                   (-3213)
+/** The DEK for disk encryption is missing. */
+#define VERR_VD_DEK_MISSING                         (-3214)
+/** The provided password to decrypt the DEK was incorrect. */
+#define VERR_VD_PASSWORD_INCORRECT                  (-3215)
+/** Generic: Invalid image file header. Use this for plugins. */
+#define VERR_VD_GEN_INVALID_HEADER                  (-3220)
+/** VDI: Invalid image file header. */
+#define VERR_VD_VDI_INVALID_HEADER                  (-3230)
+/** VDI: Invalid image file header: invalid signature. */
+#define VERR_VD_VDI_INVALID_SIGNATURE               (-3231)
+/** VDI: Invalid image file header: invalid version. */
+#define VERR_VD_VDI_UNSUPPORTED_VERSION             (-3232)
+/** Comment string is too long. */
+#define VERR_VD_VDI_COMMENT_TOO_LONG                (-3233)
+/** VMDK: Invalid image file header. */
+#define VERR_VD_VMDK_INVALID_HEADER                 (-3240)
+/** VMDK: Invalid image file header: invalid version. */
+#define VERR_VD_VMDK_UNSUPPORTED_VERSION            (-3241)
+/** VMDK: Image property not found. */
+#define VERR_VD_VMDK_VALUE_NOT_FOUND                (-3242)
+/** VMDK: Operation can't be done in current image state. */
+#define VERR_VD_VMDK_INVALID_STATE                  (-3243)
+/** VMDK: Format is invalid/inconsistent. */
+#define VERR_VD_VMDK_INVALID_FORMAT                 (-3244)
+/** VMDK: Invalid write position. */
+#define VERR_VD_VMDK_INVALID_WRITE                  (-3245)
+/** iSCSI: Invalid header, i.e. dummy for validity check. */
+#define VERR_VD_ISCSI_INVALID_HEADER                (-3250)
+/** iSCSI: Operation can't be done in current image state. */
+#define VERR_VD_ISCSI_INVALID_STATE                 (-3251)
+/** iSCSI: Invalid device type (not a disk). */
+#define VERR_VD_ISCSI_INVALID_TYPE                  (-3252)
+/** iSCSI: Initiator secret not decrypted */
+#define VERR_VD_ISCSI_SECRET_ENCRYPTED              (-3253)
+/** VHD: Invalid image file header. */
+#define VERR_VD_VHD_INVALID_HEADER                  (-3260)
+/** Parallels HDD: Invalid image file header. */
+#define VERR_VD_PARALLELS_INVALID_HEADER            (-3265)
+/** DMG: Invalid image file header. */
+#define VERR_VD_DMG_INVALID_HEADER                  (-3267)
+/** Raw: Invalid image file header. */
+#define VERR_VD_RAW_INVALID_HEADER                  (-3270)
+/** Raw: Invalid image file type. */
+#define VERR_VD_RAW_INVALID_TYPE                    (-3271)
+/** The backend needs more metadata before it can continue. */
+#define VERR_VD_NOT_ENOUGH_METADATA                 (-3272)
+/** Halt the current I/O context until further notification from the backend. */
+#define VERR_VD_IOCTX_HALT                          (-3273)
+/** The disk has a cache attached already. */
+#define VERR_VD_CACHE_ALREADY_EXISTS                (-3274)
+/** There is no cache attached to the disk. */
+#define VERR_VD_CACHE_NOT_FOUND                     (-3275)
+/** The cache is not up to date with the image. */
+#define VERR_VD_CACHE_NOT_UP_TO_DATE                (-3276)
+/** The given range does not meet the required alignment. */
+#define VERR_VD_DISCARD_ALIGNMENT_NOT_MET           (-3277)
+/** The discard operation is not supported for this image. */
+#define VERR_VD_DISCARD_NOT_SUPPORTED               (-3278)
+/** The image is the correct format but is corrupted. */
+#define VERR_VD_IMAGE_CORRUPTED                     (-3279)
+/** Repairing the image is not supported. */
+#define VERR_VD_IMAGE_REPAIR_NOT_SUPPORTED          (-3280)
+/** Repairing the image is not possible because the corruption is to severe. */
+#define VERR_VD_IMAGE_REPAIR_IMPOSSIBLE             (-3281)
+/** Reading from the image was not possible because the offset is out of the image range.
+ * This usually indicates that there is a minor corruption in the image meta data. */
+#define VERR_VD_READ_OUT_OF_RANGE                   (-3282)
+/** Block read was marked as free in the image and returned as a zero block. */
+#define VINF_VD_NEW_ZEROED_BLOCK                    3283
+/** Unable to parse the XML in DMG file. */
+#define VERR_VD_DMG_XML_PARSE_ERROR                 (-3284)
+/** Unable to locate a usable DMG file within the XAR archive. */
+#define VERR_VD_DMG_NOT_FOUND_INSIDE_XAR            (-3285)
+/** The size of the raw image is not dividable by 512 */
+#define VERR_VD_RAW_SIZE_MODULO_512                 (-3286)
+/** The size of the raw image is not dividable by 2048 */
+#define VERR_VD_RAW_SIZE_MODULO_2048                (-3287)
+/** The size of the raw optical image is too small (<= 32K) */
+#define VERR_VD_RAW_SIZE_OPTICAL_TOO_SMALL          (-3288)
+/** The size of the raw floppy image is too big (>2.88MB) */
+#define VERR_VD_RAW_SIZE_FLOPPY_TOO_BIG             (-3289)
+
+/** @} */
+
+
+/** @name VBox Guest Library (VBGL) Status Codes
+ * @{
+ */
+/** Library was not initialized. */
+#define VERR_VBGL_NOT_INITIALIZED                   (-3300)
+/** Virtual address was not allocated by the library. */
+#define VERR_VBGL_INVALID_ADDR                      (-3301)
+/** IOCtl to VBoxGuest driver failed. */
+#define VERR_VBGL_IOCTL_FAILED                      (-3302)
+/** @} */
+
+
+/** @name VBox USB (VUSB) Status Codes
+ * @{
+ */
+/** No available ports on the hub.
+ * This error is returned when a device is attempted created and/or attached
+ * to a hub which is out of ports. */
+#define VERR_VUSB_NO_PORTS                          (-3400)
+/** The requested operation cannot be performed on a detached USB device. */
+#define VERR_VUSB_DEVICE_NOT_ATTACHED               (-3401)
+/** Failed to allocate memory for a URB. */
+#define VERR_VUSB_NO_URB_MEMORY                     (-3402)
+/** General failure during URB queuing.
+ * This will go away when the queueing gets proper status code handling. */
+#define VERR_VUSB_FAILED_TO_QUEUE_URB               (-3403)
+/** Device creation failed because the USB device name was not found. */
+#define VERR_VUSB_DEVICE_NAME_NOT_FOUND             (-3404)
+/** Not permitted to open the USB device.
+ * The user doesn't have access to the device in the usbfs, check the mount options. */
+#define VERR_VUSB_USBFS_PERMISSION                  (-3405)
+/** The requested operation cannot be performed because the device
+ * is currently being reset. */
+#define VERR_VUSB_DEVICE_IS_RESETTING               (-3406)
+/** The requested operation cannot be performed because the device
+ * is currently suspended. */
+#define VERR_VUSB_DEVICE_IS_SUSPENDED               (-3407)
+/** Not permitted to open the USB device.
+ * The user doesn't have access to the device node, check group memberships. */
+#define VERR_VUSB_USB_DEVICE_PERMISSION             (-3408)
+/** @} */
+
+
+/** @name VBox VGA Status Codes
+ * @{
+ */
+/** One of the custom modes was incorrect.
+ * The format or bit count of the custom mode value is invalid. */
+#define VERR_VGA_INVALID_CUSTOM_MODE                (-3500)
+/** The display connector is resizing. */
+#define VINF_VGA_RESIZE_IN_PROGRESS                 (3501)
+/** @} */
+
+
+/** @name Internal Networking Status Codes
+ * @{
+ */
+/** The networking interface to filter was not found. */
+#define VERR_INTNET_FLT_IF_NOT_FOUND                (-3600)
+/** The networking interface to filter was busy (used by someone). */
+#define VERR_INTNET_FLT_IF_BUSY                     (-3601)
+/** Failed to create or connect to a networking interface filter. */
+#define VERR_INTNET_FLT_IF_FAILED                   (-3602)
+/** The network already exists with a different trunk configuration. */
+#define VERR_INTNET_INCOMPATIBLE_TRUNK              (-3603)
+/** The network already exists with a different security profile (restricted / public). */
+#define VERR_INTNET_INCOMPATIBLE_FLAGS              (-3604)
+/** Failed to create a virtual network interface instance. */
+#define VERR_INTNET_FLT_VNIC_CREATE_FAILED          (-3605)
+/** Failed to retrieve a virtual network interface link ID. */
+#define VERR_INTNET_FLT_VNIC_LINK_ID_NOT_FOUND      (-3606)
+/** Failed to initialize a virtual network interface instance. */
+#define VERR_INTNET_FLT_VNIC_INIT_FAILED            (-3607)
+/** Failed to open a virtual network interface instance. */
+#define VERR_INTNET_FLT_VNIC_OPEN_FAILED            (-3608)
+/** Failed to retrieve underlying (lower mac) link. */
+#define VERR_INTNET_FLT_LOWER_LINK_INFO_NOT_FOUND   (-3609)
+/** Failed to open underlying link instance. */
+#define VERR_INTNET_FLT_LOWER_LINK_OPEN_FAILED      (-3610)
+/** Failed to get underlying link ID. */
+#define VERR_INTNET_FLT_LOWER_LINK_ID_NOT_FOUND     (-3611)
+/** @} */
+
+
+/** @name Support Driver Status Codes
+ * @{
+ */
+/** The component factory was not found. */
+#define VERR_SUPDRV_COMPONENT_NOT_FOUND             (-3700)
+/** The component factories do not support the requested interface. */
+#define VERR_SUPDRV_INTERFACE_NOT_SUPPORTED         (-3701)
+/** The service module was not found. */
+#define VERR_SUPDRV_SERVICE_NOT_FOUND               (-3702)
+/** The host kernel is too old. */
+#define VERR_SUPDRV_KERNEL_TOO_OLD_FOR_VTX          (-3703)
+/** Bad VTG magic value.  */
+#define VERR_SUPDRV_VTG_MAGIC                       (-3704)
+/** Bad VTG bit count value.  */
+#define VERR_SUPDRV_VTG_BITS                        (-3705)
+/** Bad VTG header - misc.  */
+#define VERR_SUPDRV_VTG_BAD_HDR_MISC                (-3706)
+/** Bad VTG header - offset.  */
+#define VERR_SUPDRV_VTG_BAD_HDR_OFF                 (-3707)
+/** Bad VTG header - offset.  */
+#define VERR_SUPDRV_VTG_BAD_HDR_PTR                 (-3708)
+/** Bad VTG header - to low value.  */
+#define VERR_SUPDRV_VTG_BAD_HDR_TOO_FEW             (-3709)
+/** Bad VTG header - to high value.  */
+#define VERR_SUPDRV_VTG_BAD_HDR_TOO_MUCH            (-3710)
+/** Bad VTG header - size value is not a multiple of the structure size. */
+#define VERR_SUPDRV_VTG_BAD_HDR_NOT_MULTIPLE        (-3711)
+/** Bad VTG string table offset. */
+#define VERR_SUPDRV_VTG_STRTAB_OFF                  (-3712)
+/** Bad VTG string. */
+#define VERR_SUPDRV_VTG_BAD_STRING                  (-3713)
+/** VTG string is too long. */
+#define VERR_SUPDRV_VTG_STRING_TOO_LONG             (-3714)
+/** Bad VTG attribute value. */
+#define VERR_SUPDRV_VTG_BAD_ATTR                    (-3715)
+/** Bad VTG provider descriptor. */
+#define VERR_SUPDRV_VTG_BAD_PROVIDER                (-3716)
+/** Bad VTG probe descriptor. */
+#define VERR_SUPDRV_VTG_BAD_PROBE                   (-3717)
+/** Bad VTG argument list descriptor. */
+#define VERR_SUPDRV_VTG_BAD_ARGLIST                 (-3718)
+/** Bad VTG probe enabled data. */
+#define VERR_SUPDRV_VTG_BAD_PROBE_ENABLED           (-3719)
+/** Bad VTG probe location record. */
+#define VERR_SUPDRV_VTG_BAD_PROBE_LOC               (-3720)
+/** The VTG object for the session or image has already been registered. */
+#define VERR_SUPDRV_VTG_ALREADY_REGISTERED          (-3721)
+/** A driver may only register one VTG object per session. */
+#define VERR_SUPDRV_VTG_ONLY_ONCE_PER_SESSION       (-3722)
+/** A tracer has already been registered. */
+#define VERR_SUPDRV_TRACER_ALREADY_REGISTERED       (-3723)
+/** The session has no tracer associated with it. */
+#define VERR_SUPDRV_TRACER_NOT_REGISTERED           (-3724)
+/** The tracer has already been opened in this sesssion. */
+#define VERR_SUPDRV_TRACER_ALREADY_OPENED           (-3725)
+/** The tracer has not been opened. */
+#define VERR_SUPDRV_TRACER_NOT_OPENED               (-3726)
+/** There is no tracer present. */
+#define VERR_SUPDRV_TRACER_NOT_PRESENT              (-3727)
+/** The tracer is unloading. */
+#define VERR_SUPDRV_TRACER_UNLOADING                (-3728)
+/** Another thread in the session is talking to the tracer.  */
+#define VERR_SUPDRV_TRACER_SESSION_BUSY             (-3729)
+/** The tracer cannot open it self in the same session. */
+#define VERR_SUPDRV_TRACER_CANNOT_OPEN_SELF         (-3730)
+/** Bad argument flags. */
+#define VERR_SUPDRV_TRACER_BAD_ARG_FLAGS            (-3731)
+/** The session has reached the max number of (user mode) providers. */
+#define VERR_SUPDRV_TRACER_TOO_MANY_PROVIDERS       (-3732)
+/** The tracepoint provider object is too large. */
+#define VERR_SUPDRV_TRACER_TOO_LARGE                (-3733)
+/** The probe location array isn't adjacent to the probe enable array. */
+#define VERR_SUPDRV_TRACER_UMOD_NOT_ADJACENT        (-3734)
+/** The user mode tracepoint provider has too many probe locations and
+ * probes. */
+#define VERR_SUPDRV_TRACER_UMOD_TOO_MANY_PROBES     (-3735)
+/** The user mode tracepoint provider string table is too large. */
+#define VERR_SUPDRV_TRACER_UMOD_STRTAB_TOO_BIG      (-3736)
+/** The user mode tracepoint provider string table offset is bad. */
+#define VERR_SUPDRV_TRACER_UMOD_STRTAB_OFF_BAD      (-3737)
+/** The VM process was denied access to vboxdrv because someone have managed to
+ * open the process or its main thread with too broad access rights. */
+#define VERR_SUPDRV_HARDENING_EVIL_HANDLE           (-3738)
+/** Error opening the ApiPort LPC object. */
+#define VERR_SUPDRV_APIPORT_OPEN_ERROR              (-3739)
+/** Error enumerating all processes in the session. */
+#define VERR_SUPDRV_SESSION_PROCESS_ENUM_ERROR      (-3740)
+/** The CSRSS instance associated with the client process could not be
+ * located. */
+#define VERR_SUPDRV_CSRSS_NOT_FOUND                 (-3741)
+/** Type error opening the ApiPort LPC object. */
+#define VERR_SUPDRV_APIPORT_OPEN_ERROR_TYPE         (-3742)
+/** Failed to measure the TSC delta between two CPUs. */
+#define VERR_SUPDRV_TSC_DELTA_MEASUREMENT_FAILED    (-3743)
+/** Failed to calculate the TSC frequency. */
+#define VERR_SUPDRV_TSC_FREQ_MEASUREMENT_FAILED     (-3744)
+/** Failed to get the delta-adjusted TSC value. */
+#define VERR_SUPDRV_TSC_READ_FAILED                 (-3745)
+/** Failed to measure the TSC delta between two CPUs, continue without any
+ *  TSC-delta. */
+#define VWRN_SUPDRV_TSC_DELTA_MEASUREMENT_FAILED     3746
+/** A TSC-delta measurement request is currently being serviced. */
+#define VERR_SUPDRV_TSC_DELTA_MEASUREMENT_BUSY      (-3747)
+/** The process trying to open VBoxDrv is not a budding VM process (1). */
+#define VERR_SUPDRV_NOT_BUDDING_VM_PROCESS_1        (-3748)
+/** The process trying to open VBoxDrv is not a budding VM process (2). */
+#define VERR_SUPDRV_NOT_BUDDING_VM_PROCESS_2        (-3749)
+/** @} */
+
+
+/** @name Support Library Status Codes
+ * @{
+ */
+/** The specified path was not absolute (hardening). */
+#define VERR_SUPLIB_PATH_NOT_ABSOLUTE               (-3750)
+/** The specified path was not clean (hardening). */
+#define VERR_SUPLIB_PATH_NOT_CLEAN                  (-3751)
+/** The specified path is too long (hardening). */
+#define VERR_SUPLIB_PATH_TOO_LONG                   (-3752)
+/** The specified path is too short (hardening). */
+#define VERR_SUPLIB_PATH_TOO_SHORT                  (-3753)
+/** The specified path has too many components (hardening). */
+#define VERR_SUPLIB_PATH_TOO_MANY_COMPONENTS        (-3754)
+/** The specified path is a root path (hardening). */
+#define VERR_SUPLIB_PATH_IS_ROOT                    (-3755)
+/** Failed to enumerate directory (hardening). */
+#define VERR_SUPLIB_DIR_ENUM_FAILED                 (-3756)
+/** Failed to stat a file/dir during enumeration (hardening). */
+#define VERR_SUPLIB_STAT_ENUM_FAILED                (-3757)
+/** Failed to stat a file/dir (hardening). */
+#define VERR_SUPLIB_STAT_FAILED                     (-3758)
+/** Failed to fstat a native handle (hardening). */
+#define VERR_SUPLIB_FSTAT_FAILED                    (-3759)
+/** Found an illegal symbolic link (hardening). */
+#define VERR_SUPLIB_SYMLINKS_ARE_NOT_PERMITTED      (-3760)
+/** Found something which isn't a file nor a directory (hardening). */
+#define VERR_SUPLIB_NOT_DIR_NOT_FILE                (-3761)
+/** The specified path is a directory and not a file (hardening). */
+#define VERR_SUPLIB_IS_DIRECTORY                    (-3762)
+/** The specified path is a file and not a directory (hardening). */
+#define VERR_SUPLIB_IS_FILE                         (-3763)
+/** The path is not the same object as the native handle (hardening). */
+#define VERR_SUPLIB_NOT_SAME_OBJECT                 (-3764)
+/** The owner is not root (hardening). */
+#define VERR_SUPLIB_OWNER_NOT_ROOT                  (-3765)
+/** The group is a non-system group and it has write access (hardening). */
+#define VERR_SUPLIB_WRITE_NON_SYS_GROUP             (-3766)
+/** The file or directory is world writable (hardening). */
+#define VERR_SUPLIB_WORLD_WRITABLE                  (-3767)
+/** The argv[0] of an internal application does not match the executable image
+ * path (hardening). */
+#define VERR_SUPLIB_INVALID_ARGV0_INTERNAL          (-3768)
+/** The internal application does not reside in the correct place (hardening). */
+#define VERR_SUPLIB_INVALID_INTERNAL_APP_DIR        (-3769)
+/** Unable to establish trusted of VM process (0). */
+#define VERR_SUPLIB_NT_PROCESS_UNTRUSTED_0          (-3770)
+/** Unable to establish trusted of VM process (1). */
+#define VERR_SUPLIB_NT_PROCESS_UNTRUSTED_1          (-3771)
+/** Unable to establish trusted of VM process (2). */
+#define VERR_SUPLIB_NT_PROCESS_UNTRUSTED_2          (-3772)
+/** Unable to establish trusted of VM process (3). */
+#define VERR_SUPLIB_NT_PROCESS_UNTRUSTED_3          (-3773)
+/** Unable to establish trusted of VM process (4). */
+#define VERR_SUPLIB_NT_PROCESS_UNTRUSTED_4          (-3774)
+/** Unable to establish trusted of VM process (5). */
+#define VERR_SUPLIB_NT_PROCESS_UNTRUSTED_5          (-3775)
+/** @} */
+
+
+/** @name VBox GMM Status Codes
+ * @{
+ */
+/** The GMM is out of pages and needs to be give another chunk of user memory that
+ * it can lock down and borrow pages from. */
+#define VERR_GMM_SEED_ME                            (-3800)
+/** Unable to allocate more pages from the host system. */
+#define VERR_GMM_OUT_OF_MEMORY                      (-3801)
+/** Hit the global allocation limit.
+ * If you know there is still sufficient memory available, try raising the limit. */
+#define VERR_GMM_HIT_GLOBAL_LIMIT                   (-3802)
+/** Hit the a VM account limit. */
+#define VERR_GMM_HIT_VM_ACCOUNT_LIMIT               (-3803)
+/** Attempt to free more memory than what was previously allocated. */
+#define VERR_GMM_ATTEMPT_TO_FREE_TOO_MUCH           (-3804)
+/** Attempted to report too many pages as deflated.  */
+#define VERR_GMM_ATTEMPT_TO_DEFLATE_TOO_MUCH        (-3805)
+/** The page to be freed or updated was not found. */
+#define VERR_GMM_PAGE_NOT_FOUND                     (-3806)
+/** The specified shared page was not actually private. */
+#define VERR_GMM_PAGE_NOT_PRIVATE                   (-3807)
+/** The specified shared page was not actually shared. */
+#define VERR_GMM_PAGE_NOT_SHARED                    (-3808)
+/** The page to be freed was already freed. */
+#define VERR_GMM_PAGE_ALREADY_FREE                  (-3809)
+/** The page to be updated or freed was noted owned by the caller. */
+#define VERR_GMM_NOT_PAGE_OWNER                     (-3810)
+/** The specified chunk was not found. */
+#define VERR_GMM_CHUNK_NOT_FOUND                    (-3811)
+/** The chunk has already been mapped into the process. */
+#define VERR_GMM_CHUNK_ALREADY_MAPPED               (-3812)
+/** The chunk to be unmapped isn't actually mapped into the process. */
+#define VERR_GMM_CHUNK_NOT_MAPPED                   (-3813)
+/** The chunk has been mapped too many times already (impossible). */
+#define VERR_GMM_TOO_MANY_CHUNK_MAPPINGS            (-3814)
+/** The reservation or reservation update was declined - too many VMs, too
+ * little memory, and/or too low GMM configuration. */
+#define VERR_GMM_MEMORY_RESERVATION_DECLINED        (-3815)
+/** A GMM sanity check failed. */
+#define VERR_GMM_IS_NOT_SANE                        (-3816)
+/** Inserting a new chunk failed. */
+#define VERR_GMM_CHUNK_INSERT                       (-3817)
+/** Failed to obtain the GMM instance. */
+#define VERR_GMM_INSTANCE                           (-3818)
+/** Bad mutex semaphore flags. */
+#define VERR_GMM_MTX_FLAGS                          (-3819)
+/** Internal processing error in the page allocator. */
+#define VERR_GMM_ALLOC_PAGES_IPE                    (-3820)
+/** Invalid page count given to GMMR3FreePagesPerform.  */
+#define VERR_GMM_ACTUAL_PAGES_IPE                   (-3821)
+/** The shared module name is too long. */
+#define VERR_GMM_MODULE_NAME_TOO_LONG               (-3822)
+/** The shared module version string is too long. */
+#define VERR_GMM_MODULE_VERSION_TOO_LONG            (-3823)
+/** The shared module has too many regions. */
+#define VERR_GMM_TOO_MANY_REGIONS                   (-3824)
+/** The guest has reported too many modules. */
+#define VERR_GMM_TOO_MANY_PER_VM_MODULES            (-3825)
+/** The guest has reported too many modules. */
+#define VERR_GMM_TOO_MANY_GLOBAL_MODULES            (-3826)
+/** The shared module is already registered. */
+#define VINF_GMM_SHARED_MODULE_ALREADY_REGISTERED   (3827)
+/** The shared module clashed address wise with a previously registered
+ * module. */
+#define VERR_GMM_SHARED_MODULE_ADDRESS_CLASH        (-3828)
+/** The shared module was not found. */
+#define VERR_GMM_SHARED_MODULE_NOT_FOUND            (-3829)
+/** The size of the shared module was out of range. */
+#define VERR_GMM_BAD_SHARED_MODULE_SIZE             (-3830)
+/** The size of the one or more regions in the shared module was out of
+ * range. */
+#define VERR_GMM_SHARED_MODULE_BAD_REGIONS_SIZE     (-3831)
+/** @} */
+
+
+/** @name VBox GVM Status Codes
+ * @{
+ */
+/** The GVM is out of VM handle space. */
+#define VERR_GVM_TOO_MANY_VMS                       (-3900)
+/** The EMT was not blocked at the time of the call.  */
+#define VINF_GVM_NOT_BLOCKED                        3901
+/** The EMT was not busy running guest code at the time of the call. */
+#define VINF_GVM_NOT_BUSY_IN_GC                     3902
+/** RTThreadYield was called during a GVMMR0SchedPoll call. */
+#define VINF_GVM_YIELDED                            3903
+/** @} */
+
+
+/** @name VBox VMX Status Codes
+ * @{
+ */
+/** VMXON failed; possibly because it was already run before. */
+#define VERR_VMX_VMXON_FAILED                       (-4000)
+/** Invalid VMCS pointer.
+ * (Can be OR'ed with VERR_VMX_INVALID_VMCS_FIELD.) */
+#define VERR_VMX_INVALID_VMCS_PTR                   (-4001)
+/** Invalid VMCS index or write to read-only element. */
+#define VERR_VMX_INVALID_VMCS_FIELD                 (-4002)
+/** Reserved for future status code that we wish to OR with
+ *  VERR_VMX_INVALID_VMCS_PTR and VERR_VMX_INVALID_VMCS_FIELD. */
+#define VERR_VMX_RESERVED                           (-4003)
+/** Invalid VMXON pointer. */
+#define VERR_VMX_INVALID_VMXON_PTR                  (-4004)
+/** Unable to start VM execution. */
+#define VERR_VMX_UNABLE_TO_START_VM                 (-4005)
+/** Unable to switch due to invalid host state. */
+#define VERR_VMX_INVALID_HOST_STATE                 (-4006)
+/** IA32_FEATURE_CONTROL MSR not setup correcty (turn on VMX in the host system BIOS) */
+#define VERR_VMX_ILLEGAL_FEATURE_CONTROL_MSR        (-4007)
+/** Invalid CPU mode for VMX execution. */
+#define VERR_VMX_UNSUPPORTED_MODE                   (-4008)
+/** VMX CPU extension not available */
+#define VERR_VMX_NO_VMX                             (-4009)
+/** CPU was incorrectly left in VMX root mode; incompatible with VirtualBox */
+#define VERR_VMX_IN_VMX_ROOT_MODE                   (-4011)
+/** Somebody cleared X86_CR4_VMXE in the CR4 register. */
+#define VERR_VMX_X86_CR4_VMXE_CLEARED               (-4012)
+/** Failed to enable and lock VT-x features. */
+#define VERR_VMX_MSR_LOCKING_FAILED                 (-4013)
+/** Unable to switch due to invalid guest state. */
+#define VERR_VMX_INVALID_GUEST_STATE                (-4014)
+/** Unexpected VM exit. */
+#define VERR_VMX_UNEXPECTED_EXIT                    (-4015)
+/** Unexpected VM exception. */
+#define VERR_VMX_UNEXPECTED_EXCEPTION               (-4016)
+/** Unexpected interruption exit type. */
+#define VERR_VMX_UNEXPECTED_INTERRUPTION_EXIT_TYPE  (-4017)
+/** CPU is not in VMX root mode; unexpected when leaving VMX root mode. */
+#define VERR_VMX_NOT_IN_VMX_ROOT_MODE               (-4018)
+/** Undefined VM exit code. */
+#define VERR_VMX_UNDEFINED_EXIT_CODE                (-4019)
+/** VMPTRLD failed; possibly because of invalid VMCS launch-state. */
+#define VERR_VMX_VMPTRLD_FAILED                     (-4021)
+/** Invalid VMCS pointer passed to VMLAUNCH/VMRESUME. */
+#define VERR_VMX_INVALID_VMCS_PTR_TO_START_VM       (-4022)
+/** Internal VMX processing error no 1. */
+#define VERR_VMX_IPE_1                              (-4023)
+/** Internal VMX processing error no 2. */
+#define VERR_VMX_IPE_2                              (-4024)
+/** Internal VMX processing error no 3. */
+#define VERR_VMX_IPE_3                              (-4025)
+/** Internal VMX processing error no 4. */
+#define VERR_VMX_IPE_4                              (-4026)
+/** Internal VMX processing error no 5. */
+#define VERR_VMX_IPE_5                              (-4027)
+/** VT-x features for all modes (SMX and non-SMX) disabled by the BIOS. */
+#define VERR_VMX_MSR_ALL_VMX_DISABLED               (-4028)
+/** VT-x features disabled by the BIOS. */
+#define VERR_VMX_MSR_VMX_DISABLED                   (-4029)
+/** VM-Entry Controls internal cache invalid. */
+#define VERR_VMX_ENTRY_CTLS_CACHE_INVALID           (-4030)
+/** VM-Exit Controls internal cache invalid. */
+#define VERR_VMX_EXIT_CTLS_CACHE_INVALID            (-4031)
+/** VM-Execution Pin-based Controls internal cache invalid. */
+#define VERR_VMX_PIN_EXEC_CTLS_CACHE_INVALID        (-4032)
+/** VM-Execution Primary Processor-based Controls internal cache
+ *  invalid. */
+#define VERR_VMX_PROC_EXEC_CTLS_CACHE_INVALID       (-4033)
+/** VM-Execution Secondary Processor-based Controls internal
+ *  cache invalid. */
+#define VERR_VMX_PROC_EXEC2_CTLS_CACHE_INVALID      (-4034)
+/** Failed to set VMXON enable bit while enabling VT-x through the MSR. */
+#define VERR_VMX_MSR_VMX_ENABLE_FAILED              (-4035)
+/** Failed to enable VMXON-in-SMX bit while enabling VT-x through the MSR. */
+#define VERR_VMX_MSR_SMX_VMX_ENABLE_FAILED          (-4036)
+/** @} */
+
+
+/** @name VBox SVM Status Codes
+ * @{
+ */
+/** Unable to start VM execution. */
+#define VERR_SVM_UNABLE_TO_START_VM                 (-4050)
+/** AMD-V bit not set in K6_EFER MSR */
+#define VERR_SVM_ILLEGAL_EFER_MSR                   (-4051)
+/** AMD-V CPU extension not available. */
+#define VERR_SVM_NO_SVM                             (-4052)
+/** AMD-V CPU extension disabled (by BIOS). */
+#define VERR_SVM_DISABLED                           (-4053)
+/** AMD-V CPU extension in-use. */
+#define VERR_SVM_IN_USE                             (-4054)
+/** Invalid pVMCB. */
+#define VERR_SVM_INVALID_PVMCB                      (-4055)
+/** Unexpected SVM exit. */
+#define VERR_SVM_UNEXPECTED_EXIT                    (-4056)
+/** Unexpected SVM exception exit. */
+#define VERR_SVM_UNEXPECTED_XCPT_EXIT               (-4057)
+/** Unexpected SVM patch type. */
+#define VERR_SVM_UNEXPECTED_PATCH_TYPE              (-4058)
+/** Unable to start VM execution due to an invalid guest state. */
+#define VERR_SVM_INVALID_GUEST_STATE                (-4059)
+/** Unknown or unrecognized SVM exit.  */
+#define VERR_SVM_UNKNOWN_EXIT                       (-4060)
+/** Internal SVM processing error no 1. */
+#define VERR_SVM_IPE_1                              (-4061)
+/** Internal SVM processing error no 2. */
+#define VERR_SVM_IPE_2                              (-4062)
+/** Internal SVM processing error no 3. */
+#define VERR_SVM_IPE_3                              (-4063)
+/** Internal SVM processing error no 4. */
+#define VERR_SVM_IPE_4                              (-4064)
+/** Internal SVM processing error no 5. */
+#define VERR_SVM_IPE_5                              (-4065)
+/** @} */
+
+
+/** @name VBox HM Status Codes
+ * @{
+ */
+/** Unable to start VM execution. */
+#define VERR_HM_UNKNOWN_CPU                         (-4100)
+/** No CPUID support. */
+#define VERR_HM_NO_CPUID                            (-4101)
+/** Host is about to go into suspend mode. */
+#define VERR_HM_SUSPEND_PENDING                     (-4102)
+/** Conflicting CFGM values. */
+#define VERR_HM_CONFIG_MISMATCH                     (-4103)
+/** Internal processing error in the HM init code. */
+#define VERR_HM_ALREADY_ENABLED_IPE                 (-4104)
+/** Unexpected MSR in the auto-load/store area.  */
+#define VERR_HM_UNEXPECTED_LD_ST_MSR                (-4105)
+/** No 32-bit to 64-bit switcher in place. */
+#define VERR_HM_NO_32_TO_64_SWITCHER                (-4106)
+/** HMR0Leave was called on the wrong CPU. */
+#define VERR_HM_WRONG_CPU                           (-4107)
+/** Internal processing error \#1 in the HM code.  */
+#define VERR_HM_IPE_1                               (-4108)
+/** Internal processing error \#2 in the HM code.  */
+#define VERR_HM_IPE_2                               (-4109)
+/** Wrong 32/64-bit switcher. */
+#define VERR_HM_WRONG_SWITCHER                      (-4110)
+/** Unknown I/O instruction. */
+#define VERR_HM_UNKNOWN_IO_INSTRUCTION              (-4111)
+/** Unsupported CPU feature combination. */
+#define VERR_HM_UNSUPPORTED_CPU_FEATURE_COMBO       (-4112)
+/** Internal processing error \#3 in the HM code.  */
+#define VERR_HM_IPE_3                               (-4113)
+/** Internal processing error \#4 in the HM code.  */
+#define VERR_HM_IPE_4                               (-4114)
+/** Internal processing error \#5 in the HM code.  */
+#define VERR_HM_IPE_5                               (-4115)
+/** Invalid HM64ON32OP value.  */
+#define VERR_HM_INVALID_HM64ON32OP                  (-4116)
+/** Resume guest execution after injecting a double-fault. */
+#define VINF_HM_DOUBLE_FAULT                        4117
+/** @} */
+
+
+/** @name VBox Disassembler Status Codes
+ * @{
+ */
+/** Invalid opcode byte(s) */
+#define VERR_DIS_INVALID_OPCODE                     (-4200)
+/** Generic failure during disassembly. */
+#define VERR_DIS_GEN_FAILURE                        (-4201)
+/** No read callback. */
+#define VERR_DIS_NO_READ_CALLBACK                   (-4202)
+/** Invalid Mod/RM. */
+#define VERR_DIS_INVALID_MODRM                      (-4203)
+/** Invalid parameter index. */
+#define VERR_DIS_INVALID_PARAMETER                  (-4204)
+/** The instruction is too long. */
+#define VERR_DIS_TOO_LONG_INSTR                     (-4206)
+/** @} */
+
+
+/** @name VBox Webservice Status Codes
+ * @{
+ */
+/** Authentication failed (ISessionManager::logon()) */
+#define VERR_WEB_NOT_AUTHENTICATED                  (-4300)
+/** Invalid format of managed object reference */
+#define VERR_WEB_INVALID_MANAGED_OBJECT_REFERENCE   (-4301)
+/** Invalid session ID in managed object reference */
+#define VERR_WEB_INVALID_SESSION_ID                 (-4302)
+/** Invalid object ID in managed object reference */
+#define VERR_WEB_INVALID_OBJECT_ID                  (-4303)
+/** Unsupported interface for managed object reference */
+#define VERR_WEB_UNSUPPORTED_INTERFACE              (-4304)
+/** @} */
+
+
+/** @name VBox PARAV Status Codes
+ * @{
+ */
+/** Switch back to host */
+#define VINF_PARAV_SWITCH_TO_HOST                   4400
+
+/** @} */
+
+/** @name VBox Video HW Acceleration command status
+ * @{
+ */
+/** command processing is pending, a completion handler will be called */
+#define VINF_VHWA_CMD_PENDING                       4500
+
+/** @} */
+
+
+/** @name VBox COM error codes
+ *
+ * @remarks Global::vboxStatusCodeToCOM and Global::vboxStatusCodeFromCOM uses
+ *          these for conversion that is lossless with respect to important COM
+ *          status codes.  These methods should be moved to the glue library.
+ * @{  */
+/** Unexpected turn of events. */
+#define VERR_COM_UNEXPECTED                         (-4600)
+/** The base of the VirtualBox COM status codes (the lower value)
+ * corresponding 1:1 to VBOX_E_XXX.  This is the lowest value. */
+#define VERR_COM_VBOX_LOWEST                        (-4699)
+/** Object corresponding to the supplied arguments does not exist. */
+#define VERR_COM_OBJECT_NOT_FOUND                   (VERR_COM_VBOX_LOWEST + 1)
+/** Current virtual machine state prevents the operation. */
+#define VERR_COM_INVALID_VM_STATE                   (VERR_COM_VBOX_LOWEST + 2)
+/** Virtual machine error occurred attempting the operation. */
+#define VERR_COM_VM_ERROR                           (VERR_COM_VBOX_LOWEST + 3)
+/** File not accessible or erroneous file contents. */
+#define VERR_COM_FILE_ERROR                         (VERR_COM_VBOX_LOWEST + 4)
+/** IPRT error. */
+#define VERR_COM_IPRT_ERROR                         (VERR_COM_VBOX_LOWEST + 5)
+/** Pluggable Device Manager error. */
+#define VERR_COM_PDM_ERROR                          (VERR_COM_VBOX_LOWEST + 6)
+/** Current object state prohibits operation. */
+#define VERR_COM_INVALID_OBJECT_STATE               (VERR_COM_VBOX_LOWEST + 7)
+/** Host operating system related error. */
+#define VERR_COM_HOST_ERROR                         (VERR_COM_VBOX_LOWEST + 8)
+/** Requested operation is not supported. */
+#define VERR_COM_NOT_SUPPORTED                      (VERR_COM_VBOX_LOWEST + 9)
+/** Invalid XML found. */
+#define VERR_COM_XML_ERROR                          (VERR_COM_VBOX_LOWEST + 10)
+/** Current session state prohibits operation. */
+#define VERR_COM_INVALID_SESSION_STATE              (VERR_COM_VBOX_LOWEST + 11)
+/** Object being in use prohibits operation. */
+#define VERR_COM_OBJECT_IN_USE                      (VERR_COM_VBOX_LOWEST + 12)
+/** Returned by callback methods which does not need to be called
+ * again because the client does not actually make use of them. */
+#define VERR_COM_DONT_CALL_AGAIN                    (VERR_COM_VBOX_LOWEST + 13)
+/** @} */
+
+/** @name VBox VMMDev Status codes
+ * @{
+ */
+/** CPU hotplug events from VMMDev are not monitored by the guest. */
+#define VERR_VMMDEV_CPU_HOTPLUG_NOT_MONITORED_BY_GUEST      (-4700)
+/** @} */
+
+/** @name VBox async I/O manager Status Codes
+ * @{
+ */
+/** Async I/O task is pending, a completion handler will be called. */
+#define VINF_AIO_TASK_PENDING                       4800
+/** @} */
+
+/** @name VBox Virtual SCSI Status Codes
+ * @{
+ */
+/** LUN type is not supported. */
+#define VERR_VSCSI_LUN_TYPE_NOT_SUPPORTED           (-4900)
+/** LUN is already/still attached to a device. */
+#define VERR_VSCSI_LUN_ATTACHED_TO_DEVICE           (-4901)
+/** The specified LUN is invalid. */
+#define VERR_VSCSI_LUN_INVALID                      (-4902)
+/** The LUN is not attached to the device. */
+#define VERR_VSCSI_LUN_NOT_ATTACHED                 (-4903)
+/** The LUN is still busy. */
+#define VERR_VSCSI_LUN_BUSY                         (-4904)
+/** @} */
+
+/** @name VBox FAM Status Codes
+ * @{
+ */
+/** FAM failed to open a connection. */
+#define VERR_FAM_OPEN_FAILED                        (-5000)
+/** FAM failed to add a file to the list to be monitored. */
+#define VERR_FAM_MONITOR_FILE_FAILED                (-5001)
+/** FAM failed to add a directory to the list to be monitored. */
+#define VERR_FAM_MONITOR_DIRECTORY_FAILED           (-5002)
+/** The connection to the FAM daemon was lost. */
+#define VERR_FAM_CONNECTION_LOST                    (-5003)
+/** @} */
+
+
+/** @name PCI Passtrhough Status Codes
+ * @{
+ */
+/** RamPreAlloc not set.
+ * RAM pre-allocation is currently a requirement for PCI passthrough. */
+#define VERR_PCI_PASSTHROUGH_NO_RAM_PREALLOC        (-5100)
+/** VT-x/AMD-V not active.
+ * PCI passthrough currently works only if VT-x/AMD-V is active. */
+#define VERR_PCI_PASSTHROUGH_NO_HM              (-5101)
+/** Nested paging not active.
+ * PCI passthrough currently works only if nested paging is active. */
+#define VERR_PCI_PASSTHROUGH_NO_NESTED_PAGING       (-5102)
+/** @} */
+
+
+/** @name GVMM Status Codes
+ * @{
+ */
+/** Internal error obtaining the GVMM instance. */
+#define VERR_GVMM_INSTANCE                          (-5200)
+/** GVMM does not support the range of CPUs present/possible on the host. */
+#define VERR_GVMM_HOST_CPU_RANGE                    (-5201)
+/** GVMM ran into some broken IPRT code. */
+#define VERR_GVMM_BROKEN_IPRT                       (-5202)
+/** Internal processing error \#1 in the GVMM code. */
+#define VERR_GVMM_IPE_1                             (-5203)
+/** Internal processing error \#2 in the GVMM code. */
+#define VERR_GVMM_IPE_2                             (-5204)
+/** @} */
+
+
+/** @name IEM Status Codes
+ * @{ */
+/** The instruction is not yet implemented by IEM. */
+#define VERR_IEM_INSTR_NOT_IMPLEMENTED              (-5300)
+/** Invalid operand size passed to an IEM function. */
+#define VERR_IEM_INVALID_OPERAND_SIZE               (-5301)
+/** Invalid address mode passed to an IEM function. */
+#define VERR_IEM_INVALID_ADDRESS_MODE               (-5302)
+/** Invalid effective segment register number passed to an IEM function. */
+#define VERR_IEM_INVALID_EFF_SEG                    (-5303)
+/** Invalid instruction length passed to an IEM function. */
+#define VERR_IEM_INVALID_INSTR_LENGTH               (-5304)
+/** Internal status code for indicating that a selector isn't valid (LAR, LSL,
+ *  VERR, VERW).  This is not used outside the instruction implementations. */
+#define VINF_IEM_SELECTOR_NOT_OK                    (5305)
+/** Restart the current instruction. For testing only. */
+#define VERR_IEM_RESTART_INSTRUCTION                (-5389)
+/** This particular aspect of the instruction is not yet implemented by IEM. */
+#define VERR_IEM_ASPECT_NOT_IMPLEMENTED             (-5390)
+/** Internal processing error \#1 in the IEM code. */
+#define VERR_IEM_IPE_1                              (-5391)
+/** Internal processing error \#2 in the IEM code. */
+#define VERR_IEM_IPE_2                              (-5392)
+/** Internal processing error \#3 in the IEM code. */
+#define VERR_IEM_IPE_3                              (-5393)
+/** Internal processing error \#4 in the IEM code. */
+#define VERR_IEM_IPE_4                              (-5394)
+/** Internal processing error \#5 in the IEM code. */
+#define VERR_IEM_IPE_5                              (-5395)
+/** Internal processing error \#6 in the IEM code. */
+#define VERR_IEM_IPE_6                              (-5396)
+/** Internal processing error \#7 in the IEM code. */
+#define VERR_IEM_IPE_7                              (-5397)
+/** Internal processing error \#8 in the IEM code. */
+#define VERR_IEM_IPE_8                              (-5398)
+/** Internal processing error \#9 in the IEM code. */
+#define VERR_IEM_IPE_9                              (-5399)
+/** @} */
+
+
+/** @name DBGC Status Codes
+ *  @{ */
+/** Status that causes DBGC to quit. */
+#define VERR_DBGC_QUIT                              (-5400)
+/** Async command pending. */
+#define VWRN_DBGC_CMD_PENDING                       5401
+/** The command has already been registered. */
+#define VWRN_DBGC_ALREADY_REGISTERED                5402
+/** The command cannot be deregistered because has not been registered.  */
+#define VERR_DBGC_COMMANDS_NOT_REGISTERED           (-5403)
+/** Unknown breakpoint.  */
+#define VERR_DBGC_BP_NOT_FOUND                      (-5404)
+/** The breakpoint already exists. */
+#define VERR_DBGC_BP_EXISTS                         (-5405)
+/** The breakpoint has no command. */
+#define VINF_DBGC_BP_NO_COMMAND                     5406
+/** Generic debugger command failure. */
+#define VERR_DBGC_COMMAND_FAILED                    (-5407)
+/** Logic bug in the DBGC code. */
+#define VERR_DBGC_IPE                               (-5408)
+
+/** The lowest parse status code.   */
+#define VERR_DBGC_PARSE_LOWEST                      (-5499)
+/** Syntax error - too few arguments. */
+#define VERR_DBGC_PARSE_TOO_FEW_ARGUMENTS           (VERR_DBGC_PARSE_LOWEST + 0)
+/** Syntax error - too many arguments. */
+#define VERR_DBGC_PARSE_TOO_MANY_ARGUMENTS          (VERR_DBGC_PARSE_LOWEST + 1)
+/** Syntax error - too many arguments for static storage. */
+#define VERR_DBGC_PARSE_ARGUMENT_OVERFLOW           (VERR_DBGC_PARSE_LOWEST + 2)
+/** Syntax error - expected binary operator. */
+#define VERR_DBGC_PARSE_EXPECTED_BINARY_OP          (VERR_DBGC_PARSE_LOWEST + 3)
+
+/** Syntax error - the argument does not allow a range to be specified. */
+#define VERR_DBGC_PARSE_NO_RANGE_ALLOWED            (VERR_DBGC_PARSE_LOWEST + 5)
+/** Syntax error - unbalanced quotes. */
+#define VERR_DBGC_PARSE_UNBALANCED_QUOTE            (VERR_DBGC_PARSE_LOWEST + 6)
+/** Syntax error - unbalanced parenthesis. */
+#define VERR_DBGC_PARSE_UNBALANCED_PARENTHESIS      (VERR_DBGC_PARSE_LOWEST + 7)
+/** Syntax error - an argument or subargument contains nothing useful. */
+#define VERR_DBGC_PARSE_EMPTY_ARGUMENT              (VERR_DBGC_PARSE_LOWEST + 8)
+/** Syntax error - invalid operator usage. */
+#define VERR_DBGC_PARSE_UNEXPECTED_OPERATOR         (VERR_DBGC_PARSE_LOWEST + 9)
+/** Syntax error - invalid numeric value. */
+#define VERR_DBGC_PARSE_INVALID_NUMBER              (VERR_DBGC_PARSE_LOWEST + 10)
+/** Syntax error - numeric overflow. */
+#define VERR_DBGC_PARSE_NUMBER_TOO_BIG              (VERR_DBGC_PARSE_LOWEST + 11)
+/** Syntax error - invalid operation attempted. */
+#define VERR_DBGC_PARSE_INVALID_OPERATION           (VERR_DBGC_PARSE_LOWEST + 12)
+/** Syntax error - function not found. */
+#define VERR_DBGC_PARSE_FUNCTION_NOT_FOUND          (VERR_DBGC_PARSE_LOWEST + 13)
+/** Syntax error - the specified function is not a function. */
+#define VERR_DBGC_PARSE_NOT_A_FUNCTION              (VERR_DBGC_PARSE_LOWEST + 14)
+/** Syntax error - out of scratch memory. */
+#define VERR_DBGC_PARSE_NO_SCRATCH                  (VERR_DBGC_PARSE_LOWEST + 15)
+/** Syntax error - out of regular heap memory. */
+#define VERR_DBGC_PARSE_NO_MEMORY                   (VERR_DBGC_PARSE_LOWEST + 16)
+/** Syntax error - incorrect argument type. */
+#define VERR_DBGC_PARSE_INCORRECT_ARG_TYPE          (VERR_DBGC_PARSE_LOWEST + 17)
+/** Syntax error - an undefined variable was referenced. */
+#define VERR_DBGC_PARSE_VARIABLE_NOT_FOUND          (VERR_DBGC_PARSE_LOWEST + 18)
+/** Syntax error - a type conversion failed. */
+#define VERR_DBGC_PARSE_CONVERSION_FAILED           (VERR_DBGC_PARSE_LOWEST + 19)
+/** Syntax error - you hit a debugger feature which isn't implemented yet.
+ * (Feel free to help implement it.) */
+#define VERR_DBGC_PARSE_NOT_IMPLEMENTED             (VERR_DBGC_PARSE_LOWEST + 20)
+/** Syntax error - Couldn't satisfy a request for a specific result type. */
+#define VERR_DBGC_PARSE_BAD_RESULT_TYPE             (VERR_DBGC_PARSE_LOWEST + 21)
+/** Syntax error - Cannot read symbol value, it is a set-only symbol. */
+#define VERR_DBGC_PARSE_WRITEONLY_SYMBOL            (VERR_DBGC_PARSE_LOWEST + 22)
+/** Syntax error - Invalid command name. */
+#define VERR_DBGC_PARSE_INVALD_COMMAND_NAME         (VERR_DBGC_PARSE_LOWEST + 23)
+/** Syntax error - Command not found. */
+#define VERR_DBGC_PARSE_COMMAND_NOT_FOUND           (VERR_DBGC_PARSE_LOWEST + 24)
+/** Syntax error - buggy parser. */
+#define VERR_DBGC_PARSE_BUG                         (VERR_DBGC_PARSE_LOWEST + 25)
+/** @} */
+
+
+/** @name Support driver/library shared verification status codes.
+ * @{  */
+/** Process Verification Failure: The memory content does not match the image
+ *  file. */
+#define VERR_SUP_VP_MEMORY_VS_FILE_MISMATCH          (-5600)
+/** Process Verification Failure: The memory protection of a image file section
+ *  does not match what the section header prescribes. */
+#define VERR_SUP_VP_SECTION_PROTECTION_MISMATCH      (-5601)
+/** Process Verification Failure: One of the section in the image file is not
+ *  mapped into memory. */
+#define VERR_SUP_VP_SECTION_NOT_MAPPED               (-5602)
+/** Process Verification Failure: One of the section in the image file is not
+ *  fully mapped into memory. */
+#define VERR_SUP_VP_SECTION_NOT_FULLY_MAPPED         (-5603)
+/** Process Verification Failure: Bad file alignment value in image header. */
+#define VERR_SUP_VP_BAD_FILE_ALIGNMENT_VALUE         (-5604)
+/** Process Verification Failure: Bad image base in header. */
+#define VERR_SUP_VP_BAD_IMAGE_BASE                   (-5605)
+/** Process Verification Failure: Bad image signature. */
+#define VERR_SUP_VP_BAD_IMAGE_SIGNATURE              (-5606)
+/** Process Verification Failure: Bad image size. */
+#define VERR_SUP_VP_BAD_IMAGE_SIZE                   (-5607)
+/** Process Verification Failure: Bad new-header offset in the MZ header. */
+#define VERR_SUP_VP_BAD_MZ_OFFSET                    (-5608)
+/** Process Verification Failure: Bad optional header field. */
+#define VERR_SUP_VP_BAD_OPTIONAL_HEADER              (-5609)
+/** Process Verification Failure: Bad section alignment value in image
+ *  header. */
+#define VERR_SUP_VP_BAD_SECTION_ALIGNMENT_VALUE      (-5610)
+/** Process Verification Failure: Bad section raw data size. */
+#define VERR_SUP_VP_BAD_SECTION_FILE_SIZE            (-5611)
+/** Process Verification Failure: Bad virtual section address. */
+#define VERR_SUP_VP_BAD_SECTION_RVA                  (-5612)
+/** Process Verification Failure: Bad virtual section size. */
+#define VERR_SUP_VP_BAD_SECTION_VIRTUAL_SIZE         (-5613)
+/** Process Verification Failure: Bad size of image header. */
+#define VERR_SUP_VP_BAD_SIZE_OF_HEADERS              (-5614)
+/** Process Verification Failure: The process is being debugged. */
+#define VERR_SUP_VP_DEBUGGED                         (-5615)
+/** Process Verification Failure: A DLL was found more than once. */
+#define VERR_SUP_VP_DUPLICATE_DLL_MAPPING            (-5616)
+/** Process Verification Failure: Image section region is too large. */
+#define VERR_SUP_VP_EMPTY_REGION_TOO_LARGE           (-5617)
+/** Process Verification Failure: Executable file name and process image name
+ *  does not match up. */
+#define VERR_SUP_VP_EXE_VS_PROC_NAME_MISMATCH        (-5618)
+/** Process Verification Failure: Found executable memory allocated in the
+ *  process.  There is only supposed be executable memory associated with
+ *  image file mappings (DLLs & EXE). */
+#define VERR_SUP_VP_FOUND_EXEC_MEMORY                (-5619)
+/** Process Verification Failure: There is more than one known executable mapped
+ *  into the process. */
+#define VERR_SUP_VP_FOUND_MORE_THAN_ONE_EXE_MAPPING  (-5620)
+/** Process Verification Failure: Error closing image file handle. */
+#define VERR_SUP_VP_IMAGE_FILE_CLOSE_ERROR           (-5621)
+/** Process Verification Failure: Error opening image file. */
+#define VERR_SUP_VP_IMAGE_FILE_OPEN_ERROR            (-5622)
+/** Process Verification Failure: Error reading image file header. */
+#define VERR_SUP_VP_IMAGE_HDR_READ_ERROR             (-5623)
+/** Process Verification Failure: Image mapping is bogus as the first region
+ *  has different AllocationBase and BaseAddress values, indicating that a
+ *  section was unmapped or otherwise tampered with. */
+#define VERR_SUP_VP_IMAGE_MAPPING_BASE_ERROR         (-5624)
+/** Process Verification Failure: Error reading process memory for comparing
+ *  with disk data. */
+#define VERR_SUP_VP_MEMORY_READ_ERROR                (-5625)
+/** Process Verification Failure: Found no executable mapped into the process
+ *  address space. */
+#define VERR_SUP_VP_NO_FOUND_NO_EXE_MAPPING          (-5626)
+/** Process Verification Failure: An image mapping failed to report a name. */
+#define VERR_SUP_VP_NO_IMAGE_MAPPING_NAME            (-5627)
+/** Process Verification Failure: No KERNE32.DLL mapping found.  This is
+ *  impossible. */
+#define VERR_SUP_VP_NO_KERNEL32_MAPPING              (-5628)
+/** Process Verification Failure: Error allocating memory. */
+#define VERR_SUP_VP_NO_MEMORY                        (-5629)
+/** Process Verification Failure: Error allocating state memory or querying
+ *  the system32 path. */
+#define VERR_SUP_VP_NO_MEMORY_STATE                  (-5630)
+/** Process Verification Failure: No NTDLL.DLL mapping found.  This is
+ *  impossible. */
+#define VERR_SUP_VP_NO_NTDLL_MAPPING                 (-5631)
+/** Process Verification Failure: A DLL residing outside System32 was found
+ *  in the process. */
+#define VERR_SUP_VP_NON_SYSTEM32_DLL                 (-5632)
+/** Process Verification Failure: An unknown and unwanted DLL was found loaded
+ *  into the process. */
+#define VERR_SUP_VP_NOT_KNOWN_DLL_OR_EXE             (-5633)
+/** Process Verification Failure: The name of an image file changes between
+ *  mapping regions. */
+#define VERR_SUP_VP_NT_MAPPING_NAME_CHANGED          (-5634)
+/** Process Verification Failure: Error querying process name. */
+#define VERR_SUP_VP_NT_QI_PROCESS_NM_ERROR           (-5635)
+/** Process Verification Failure: Error querying thread information. */
+#define VERR_SUP_VP_NT_QI_THREAD_ERROR               (-5636)
+/** Process Verification Failure: Error query virtual memory information. */
+#define VERR_SUP_VP_NT_QI_VIRTUAL_MEMORY_ERROR       (-5637)
+/** Process Verification Failure: Error query virtual memory mapping name. */
+#define VERR_SUP_VP_NT_QI_VIRTUAL_MEMORY_NM_ERROR    (-5638)
+/** Process Verification Failure: Error determining the full path of
+ *  System32. */
+#define VERR_SUP_VP_SYSTEM32_PATH                    (-5639)
+/** Process Verification Failure: The process has more than one thread. */
+#define VERR_SUP_VP_THREAD_NOT_ALONE                 (-5640)
+/** Process Verification Failure: The image mapping is too large (>= 2GB). */
+#define VERR_SUP_VP_TOO_HIGH_REGION_RVA              (-5641)
+/** Process Verification Failure: The memory region is too large (>= 2GB). */
+#define VERR_SUP_VP_TOO_LARGE_REGION                 (-5642)
+/** Process Verification Failure: There are too many DLLs loaded. */
+#define VERR_SUP_VP_TOO_MANY_DLLS_LOADED             (-5643)
+/** Process Verification Failure: An image has too many regions. */
+#define VERR_SUP_VP_TOO_MANY_IMAGE_REGIONS           (-5644)
+/** Process Verification Failure: The process has too many virtual memory
+ *  regions. */
+#define VERR_SUP_VP_TOO_MANY_MEMORY_REGIONS          (-5645)
+/** Process Verification Failure: An image has too many sections. */
+#define VERR_SUP_VP_TOO_MANY_SECTIONS                (-5646)
+/** Process Verification Failure: An image is targeting an unexpected
+ *  machine/CPU. */
+#define VERR_SUP_VP_UNEXPECTED_IMAGE_MACHINE         (-5647)
+/** Process Verification Failure: Unexpected section protection flag
+ *  combination. */
+#define VERR_SUP_VP_UNEXPECTED_SECTION_FLAGS         (-5648)
+/** Process Verification Failure: Expected the process and exe to have forced
+ * integrity checking enabled (verifying signatures). */
+#define VERR_SUP_VP_EXE_MISSING_FORCE_INTEGRITY     (-5649)
+/** Process Verification Failure: Expected the process and exe to have dynamic
+ * base enabled. */
+#define VERR_SUP_VP_EXE_MISSING_DYNAMIC_BASE        (-5650)
+/** Process Verification Failure: Expected the process and exe to advertise
+ * NX compatibility. */
+#define VERR_SUP_VP_EXE_MISSING_NX_COMPAT           (-5651)
+/** Process Verification Failure: The DllCharacteristics of the process
+ * does not match the value in the optional header in the exe file. */
+#define VERR_SUP_VP_DLL_CHARECTERISTICS_MISMATCH    (-5652)
+/** Process Verification Failure: The ImageCharacteristics of the process
+ * does not match the value in the file header in the exe file. */
+#define VERR_SUP_VP_IMAGE_CHARECTERISTICS_MISMATCH  (-5653)
+/** Process Verification Failure: Error querying image information. */
+#define VERR_SUP_VP_NT_QI_PROCESS_IMG_INFO_ERROR    (-5654)
+/** Process Verification Failure: Error querying debug port. */
+#define VERR_SUP_VP_NT_QI_PROCESS_DBG_PORT_ERROR    (-5655)
+/** WinVerifyTrust failed with an unexpected status code when using the
+ * catalog-file approach. */
+#define VERR_SUP_VP_WINTRUST_CAT_FAILURE            (-5656)
+/** The image is required to be signed with the same certificate as the rest
+ * of VirtualBox. */
+#define VERR_SUP_VP_NOT_SIGNED_WITH_BUILD_CERT      (-5657)
+/** Internal processing error: Not build certificate. */
+#define VERR_SUP_VP_NOT_BUILD_CERT_IPE              (-5658)
+/** The image requires to be signed using the kernel-code signing process. */
+#define VERR_SUP_VP_NOT_VALID_KERNEL_CODE_SIGNATURE (-5659)
+/** Unexpected number of valid paths. */
+#define VERR_SUP_VP_UNEXPECTED_VALID_PATH_COUNT     (-5660)
+/** The image is required to force integrity checks. */
+#define VERR_SUP_VP_SIGNATURE_CHECKS_NOT_ENFORCED   (-5661)
+/** Process Verification Failure: Symantec Endpoint Protection must be
+ * disabled for the VirtualBox VM processes.
+ * http://www.symantec.com/connect/articles/creating-application-control-exclusions-symantec-endpoint-protection-121 */
+#define VERR_SUP_VP_SYSFER_DLL                      (-5662)
+/** Process Purification Failure: KERNE32.DLL already mapped into the initial
+ *  process (suspended). */
+#define VERR_SUP_VP_KERNEL32_ALREADY_MAPPED         (-5663)
+/** Process Purification Failure: NtFreeVirtualMemory failed on a chunk of
+ *  executable memory which shouldn't be present in the process. */
+#define VERR_SUP_VP_FREE_VIRTUAL_MEMORY_FAILED      (-5664)
+/** Process Purification Failure: Both NtUnmapViewOfSetion and
+ *  NtProtectVirtualMemory failed to get rid of or passify an non-image
+ *  executable mapping. */
+#define VERR_SUP_VP_UNMAP_AND_PROTECT_FAILED        (-5665)
+/** Process Purification Failure: Unknown memory type of executable memory.   */
+#define VERR_SUP_VP_UNKOWN_MEM_TYPE                 (-5666)
+/** The image file is not owned by TrustedInstaller is it should be. */
+#define VERR_SUP_VP_NOT_OWNED_BY_TRUSTED_INSTALLER  (-5667)
+/** The image is outside the expected range. */
+#define VERR_SUP_VP_IMAGE_TOO_BIG                   (-5668)
+/** Stub process not found so it cannot be revalidated when vboxdrv is opened
+ * by the VM process. */
+#define VERR_SUP_VP_STUB_NOT_FOUND                  (-5669)
+/** Error opening the stub process for revalidation when vboxdrv is opened by
+ *  the VM process. */
+#define VERR_SUP_VP_STUB_OPEN_ERROR                 (-5670)
+/** Stub process thread not found during revalidation upon vboxdrv opening by
+ * the VM process. */
+#define VERR_SUP_VP_STUB_THREAD_NOT_FOUND           (-5671)
+/** Error opening the stub process thread for revalidation when vboxdrv is
+ * opened by the VM process. */
+#define VERR_SUP_VP_STUB_THREAD_OPEN_ERROR          (-5672)
+/** Process Purification Failure: NtAllocateVirtualMemory failed to get us
+ * suitable replacement memory for a chunk of executable memory that
+ * shouldn't be present in our process.  (You will only see this message if you
+ * got potentially fatally buggy anti-virus software installed.) */
+#define VERR_SUP_VP_REPLACE_VIRTUAL_MEMORY_FAILED   (-5673)
+/** Error getting the file mode. */
+#define VERR_SUP_VP_FILE_MODE_ERROR                 (-5674)
+/** Error creating an event semaphore for used with asynchronous reads. */
+#define VERR_SUP_VP_CREATE_READ_EVT_SEM_FAILED      (-5675)
+
+/** @} */
+
+/** @name VBox Extension Pack Status Codes
+ * @{
+ */
+/** The host is not supported. Uninstall the extension pack.
+ * Returned by the VBOXEXTPACKREG::pfnInstalled. */
+#define VERR_EXTPACK_UNSUPPORTED_HOST_UNINSTALL     (-6000)
+/** The VirtualBox version is not supported by one of the extension packs.
+ *
+ * You have probably upgraded VirtualBox recently.  Please upgrade the
+ * extension packs to versions compatible with this VirtualBox release.
+ */
+#define VERR_EXTPACK_VBOX_VERSION_MISMATCH          (-6001)
+/** @} */
+
+
+/** @name VBox Guest Control Status Codes
+ * @{
+ */
+/** Guest side reported an error. */
+#define VERR_GSTCTL_GUEST_ERROR                     (-6200)
+/** A guest control object has changed its overall status. */
+#define VWRN_GSTCTL_OBJECTSTATE_CHANGED             6220
+/** @} */
+
+
+/** @name GIM Status Codes
+ * @{
+ */
+/** No GIM provider is configured for this VM. */
+#define VERR_GIM_NOT_ENABLED                        (-6300)
+/** GIM internal processing error \#1. */
+#define VERR_GIM_IPE_1                              (-6301)
+/** GIM internal processing error \#2. */
+#define VERR_GIM_IPE_2                              (-6302)
+/** GIM internal processing error \#3. */
+#define VERR_GIM_IPE_3                              (-6303)
+/** The GIM provider does not support any paravirtualized TSC. */
+#define VERR_GIM_PVTSC_NOT_AVAILABLE                (-6304)
+/** The guest has not setup use of the paravirtualized TSC. */
+#define VERR_GIM_PVTSC_NOT_ENABLED                  (-6305)
+/** Unknown or invalid GIM provider. */
+#define VERR_GIM_INVALID_PROVIDER                   (-6306)
+/** GIM generic operation failed. */
+#define VERR_GIM_OPERATION_FAILED                   (-6307)
+/** The GIM provider does not support any hypercalls. */
+#define VERR_GIM_HYPERCALLS_NOT_AVAILABLE           (-6308)
+/** The guest has not setup use of the hypercalls. */
+#define VERR_GIM_HYPERCALLS_NOT_ENABLED             (-6309)
+/** The GIM device is not registered with GIM when it ought to be. */
+#define VERR_GIM_DEVICE_NOT_REGISTERED              (-6310)
+/** Hypercall cannot be enabled/performed due to access/permissions/CPL. */
+#define VERR_GIM_HYPERCALL_ACCESS_DENIED            (-6311)
+/** @} */
+
+
+/** @name Main API Status Codes
+ * @{
+ */
+/** The configuration constructor in main failed due to a COM error.  Check
+ * the release log of the VM for further details. */
+#define VERR_MAIN_CONFIG_CONSTRUCTOR_COM_ERROR      (-6400)
+/** The configuration constructor in main failed due to an internal consistency
+ *  error. Consult the release log of the VM for further details. */
+#define VERR_MAIN_CONFIG_CONSTRUCTOR_IPE            (-6401)
+/** @} */
+
+
+/** @name VBox Drag and Drop Status Codes
+ * @{
+ */
+/** Guest side reported an error. */
+#define VERR_GSTDND_GUEST_ERROR                     (-6500)
+/** @} */
+
+
+/** @name Audio Status Codes
+ * @{
+ */
+/** Host backend couldn't be initialized.  Happen if the audio server is not
+ *  reachable, audio hardware is not available or similar.  We should use the
+ *  NULL audio driver. */
+#define VERR_AUDIO_BACKEND_INIT_FAILED              (-6600)
+/** @} */
+
+
+/* SED-END */
+
+/** @} */
+
+
+#endif
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/include/VBox/hgcmsvc.h
@@ -0,0 +1,423 @@
+/** @file
+ * Host-Guest Communication Manager (HGCM) - Service library definitions.
+ */
+
+/*
+ * Copyright (C) 2006-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+#ifndef ___VBox_hgcm_h
+#define ___VBox_hgcm_h
+
+#include <iprt/assert.h>
+#include <iprt/string.h>
+#include <VBox/cdefs.h>
+#include <VBox/types.h>
+#include <VBox/err.h>
+#ifdef VBOX_TEST_HGCM_PARMS
+# include <iprt/test.h>
+#endif
+
+/** @todo proper comments. */
+
+/**
+ * Service interface version.
+ *
+ * Includes layout of both VBOXHGCMSVCFNTABLE and VBOXHGCMSVCHELPERS.
+ *
+ * A service can work with these structures if major version
+ * is equal and minor version of service is <= version of the
+ * structures.
+ *
+ * For example when a new helper is added at the end of helpers
+ * structure, then the minor version will be increased. All older
+ * services still can work because they have their old helpers
+ * unchanged.
+ *
+ * Revision history.
+ * 1.1->2.1 Because the pfnConnect now also has the pvClient parameter.
+ * 2.1->2.2 Because pfnSaveState and pfnLoadState were added
+ * 2.2->3.1 Because pfnHostCall is now synchronous, returns rc, and parameters were changed
+ * 3.1->3.2 Because pfnRegisterExtension was added
+ * 3.2->3.3 Because pfnDisconnectClient helper was added
+ * 3.3->4.1 Because the pvService entry and parameter was added
+ * 4.1->4.2 Because the VBOX_HGCM_SVC_PARM_CALLBACK parameter type was added
+ * 4.2->5.1 Removed the VBOX_HGCM_SVC_PARM_CALLBACK parameter type, as
+ *          this problem is already solved by service extension callbacks
+ */
+#define VBOX_HGCM_SVC_VERSION_MAJOR (0x0005)
+#define VBOX_HGCM_SVC_VERSION_MINOR (0x0001)
+#define VBOX_HGCM_SVC_VERSION ((VBOX_HGCM_SVC_VERSION_MAJOR << 16) + VBOX_HGCM_SVC_VERSION_MINOR)
+
+
+/** Typed pointer to distinguish a call to service. */
+struct VBOXHGCMCALLHANDLE_TYPEDEF;
+typedef struct VBOXHGCMCALLHANDLE_TYPEDEF *VBOXHGCMCALLHANDLE;
+
+/** Service helpers pointers table. */
+typedef struct VBOXHGCMSVCHELPERS
+{
+    /** The service has processed the Call request. */
+    DECLR3CALLBACKMEMBER(void, pfnCallComplete, (VBOXHGCMCALLHANDLE callHandle, int32_t rc));
+
+    void *pvInstance;
+
+    /** The service disconnects the client. */
+    DECLR3CALLBACKMEMBER(void, pfnDisconnectClient, (void *pvInstance, uint32_t u32ClientID));
+} VBOXHGCMSVCHELPERS;
+
+typedef VBOXHGCMSVCHELPERS *PVBOXHGCMSVCHELPERS;
+
+
+#define VBOX_HGCM_SVC_PARM_INVALID (0U)
+#define VBOX_HGCM_SVC_PARM_32BIT (1U)
+#define VBOX_HGCM_SVC_PARM_64BIT (2U)
+#define VBOX_HGCM_SVC_PARM_PTR   (3U)
+
+typedef struct VBOXHGCMSVCPARM
+{
+    /** VBOX_HGCM_SVC_PARM_* values. */
+    uint32_t type;
+
+    union
+    {
+        uint32_t uint32;
+        uint64_t uint64;
+        struct
+        {
+            uint32_t size;
+            void *addr;
+        } pointer;
+    } u;
+#ifdef __cplusplus
+    /** Extract an uint32_t value from an HGCM parameter structure */
+    int getUInt32(uint32_t *u32)
+    {
+        AssertPtrReturn(u32, VERR_INVALID_POINTER);
+        int rc = VINF_SUCCESS;
+        if (type != VBOX_HGCM_SVC_PARM_32BIT)
+            rc = VERR_INVALID_PARAMETER;
+        if (RT_SUCCESS(rc))
+            *u32 = u.uint32;
+        return rc;
+    }
+
+    /** Extract a uint64_t value from an HGCM parameter structure */
+    int getUInt64(uint64_t *u64)
+    {
+        AssertPtrReturn(u64, VERR_INVALID_POINTER);
+        int rc = VINF_SUCCESS;
+        if (type != VBOX_HGCM_SVC_PARM_64BIT)
+            rc = VERR_INVALID_PARAMETER;
+        if (RT_SUCCESS(rc))
+            *u64 = u.uint64;
+        return rc;
+    }
+
+    /** Extract a pointer value from an HGCM parameter structure */
+    int getPointer(void **ppv, uint32_t *pcb)
+    {
+        AssertPtrReturn(ppv, VERR_INVALID_POINTER);
+        AssertPtrReturn(pcb, VERR_INVALID_POINTER);
+        if (type == VBOX_HGCM_SVC_PARM_PTR)
+        {
+            *ppv = u.pointer.addr;
+            *pcb = u.pointer.size;
+            return VINF_SUCCESS;
+        }
+
+        return VERR_INVALID_PARAMETER;
+    }
+
+    /** Extract a constant pointer value from an HGCM parameter structure */
+    int getPointer(const void **ppcv, uint32_t *pcb)
+    {
+        AssertPtrReturn(ppcv, VERR_INVALID_POINTER);
+        AssertPtrReturn(pcb, VERR_INVALID_POINTER);
+        void *pv;
+        int rc = getPointer(&pv, pcb);
+        *ppcv = pv;
+        return rc;
+    }
+
+    /** Extract a pointer value to a non-empty buffer from an HGCM parameter
+     * structure */
+    int getBuffer(void **ppv, uint32_t *pcb)
+    {
+        AssertPtrReturn(ppv, VERR_INVALID_POINTER);
+        AssertPtrReturn(pcb, VERR_INVALID_POINTER);
+        void *pv = NULL;
+        uint32_t cb = 0;
+        int rc = getPointer(&pv, &cb);
+        if (   RT_SUCCESS(rc)
+            && VALID_PTR(pv)
+            && cb > 0)
+        {
+            *ppv = pv;
+            *pcb = cb;
+            return VINF_SUCCESS;
+        }
+
+        return VERR_INVALID_PARAMETER;
+    }
+
+    /** Extract a pointer value to a non-empty constant buffer from an HGCM
+     * parameter structure */
+    int getBuffer(const void **ppcv, uint32_t *pcb)
+    {
+        AssertPtrReturn(ppcv, VERR_INVALID_POINTER);
+        AssertPtrReturn(pcb, VERR_INVALID_POINTER);
+        void *pcv = NULL;
+        int rc = getBuffer(&pcv, pcb);
+        *ppcv = pcv;
+        return rc;
+    }
+
+    /** Extract a string value from an HGCM parameter structure */
+    int getString(char **ppch, uint32_t *pcb)
+    {
+        uint32_t cb = 0;
+        char *pch = NULL;
+        int rc = getBuffer((void **)&pch, &cb);
+        if (RT_FAILURE(rc))
+        {
+            *ppch = NULL;
+            *pcb = 0;
+            return rc;
+        }
+        rc = RTStrValidateEncodingEx(pch, cb,
+                                     RTSTR_VALIDATE_ENCODING_ZERO_TERMINATED);
+        *ppch = pch;
+        *pcb = cb;
+        return rc;
+    }
+
+    /** Extract a constant string value from an HGCM parameter structure */
+    int getString(const char **ppch, uint32_t *pcb)
+    {
+        char *pch = NULL;
+        int rc = getString(&pch, pcb);
+        *ppch = pch;
+        return rc;
+    }
+
+    /** Set a uint32_t value to an HGCM parameter structure */
+    void setUInt32(uint32_t u32)
+    {
+        type = VBOX_HGCM_SVC_PARM_32BIT;
+        u.uint32 = u32;
+    }
+
+    /** Set a uint64_t value to an HGCM parameter structure */
+    void setUInt64(uint64_t u64)
+    {
+        type = VBOX_HGCM_SVC_PARM_64BIT;
+        u.uint64 = u64;
+    }
+
+    /** Set a pointer value to an HGCM parameter structure */
+    void setPointer(void *pv, uint32_t cb)
+    {
+        type = VBOX_HGCM_SVC_PARM_PTR;
+        u.pointer.addr = pv;
+        u.pointer.size = cb;
+    }
+
+    /** Set a const string value to an HGCM parameter structure */
+    void setString(const char *psz)
+    {
+        type = VBOX_HGCM_SVC_PARM_PTR;
+        u.pointer.addr = (void *)psz;
+        u.pointer.size = (uint32_t)strlen(psz) + 1;
+    }
+
+#ifdef ___iprt_cpp_ministring_h
+    /** Set a const string value to an HGCM parameter structure */
+    void setCppString(const RTCString &rString)
+    {
+        type = VBOX_HGCM_SVC_PARM_PTR;
+        u.pointer.addr = (void *)rString.c_str();
+        u.pointer.size = (uint32_t)rString.length() + 1;
+    }
+#endif
+
+#ifdef VBOX_TEST_HGCM_PARMS
+    /** Test the getString member function.  Indirectly tests the getPointer
+     * and getBuffer APIs.
+     * @param  hTest  an running IPRT test
+     * @param  aType  the type that the parameter should be set to before
+     *                calling getString
+     * @param  apcc   the value that the parameter should be set to before
+     *                calling getString, and also the address (!) which we
+     *                expect getString to return.  Stricter than needed of
+     *                course, but I was feeling lazy.
+     * @param  acb    the size that the parameter should be set to before
+     *                calling getString, and also the size which we expect
+     *                getString to return.
+     * @param  rcExp  the expected return value of the call to getString.
+     */
+    void doTestGetString(RTTEST hTest, uint32_t aType, const char *apcc,
+                         uint32_t acb, int rcExp)
+    {
+        /* An RTTest API like this, which would print out an additional line
+         * of context if a test failed, would be nice.  This is because the
+         * line number alone doesn't help much here, given that this is a
+         * subroutine called many times. */
+        /*
+        RTTestContextF(hTest,
+                       ("doTestGetString, aType=%u, apcc=%p, acp=%u, rcExp=%Rrc",
+                        aType, apcc, acp, rcExp));
+         */
+        setPointer((void *)apcc, acb);
+        type = aType;  /* in case we don't want VBOX_HGCM_SVC_PARM_PTR */
+        const char *pcc = NULL;
+        uint32_t cb = 0;
+        int rc = getString(&pcc, &cb);
+        RTTEST_CHECK_RC(hTest, rc, rcExp);
+        if (RT_SUCCESS(rcExp))
+        {
+            RTTEST_CHECK_MSG_RETV(hTest, (pcc == apcc),
+                                  (hTest, "expected %p, got %p", apcc, pcc));
+            RTTEST_CHECK_MSG_RETV(hTest, (cb == acb),
+                                  (hTest, "expected %u, got %u", acb, cb));
+        }
+    }
+
+    /** Run some unit tests on the getString method and indirectly test
+     * getPointer and getBuffer as well. */
+    void testGetString(RTTEST hTest)
+    {
+        RTTestSub(hTest, "HGCM string parameter handling");
+        doTestGetString(hTest, VBOX_HGCM_SVC_PARM_32BIT, "test", 3,
+                        VERR_INVALID_PARAMETER);
+        doTestGetString(hTest, VBOX_HGCM_SVC_PARM_PTR, "test", 5,
+                        VINF_SUCCESS);
+        doTestGetString(hTest, VBOX_HGCM_SVC_PARM_PTR, "test", 3,
+                        VERR_BUFFER_OVERFLOW);
+        doTestGetString(hTest, VBOX_HGCM_SVC_PARM_PTR, "test\xf0", 6,
+                        VERR_INVALID_UTF8_ENCODING);
+        doTestGetString(hTest, VBOX_HGCM_SVC_PARM_PTR, "test", 0,
+                        VERR_INVALID_PARAMETER);
+        doTestGetString(hTest, VBOX_HGCM_SVC_PARM_PTR, (const char *)0x1, 5,
+                        VERR_INVALID_PARAMETER);
+        RTTestSubDone(hTest);
+    }
+#endif
+
+    VBOXHGCMSVCPARM() : type(VBOX_HGCM_SVC_PARM_INVALID) {}
+#endif
+} VBOXHGCMSVCPARM;
+
+typedef VBOXHGCMSVCPARM *PVBOXHGCMSVCPARM;
+
+#ifdef VBOX_WITH_CRHGSMI
+typedef void * HGCMCVSHANDLE;
+
+typedef DECLCALLBACK(void) HGCMHOSTFASTCALLCB (int32_t result, uint32_t u32Function, PVBOXHGCMSVCPARM pParam, void *pvContext);
+typedef HGCMHOSTFASTCALLCB *PHGCMHOSTFASTCALLCB;
+#endif
+
+
+/** Service specific extension callback.
+ *  This callback is called by the service to perform service specific operation.
+ *
+ * @param pvExtension The extension pointer.
+ * @param u32Function What the callback is supposed to do.
+ * @param pvParm      The function parameters.
+ * @param cbParm      The size of the function parameters.
+ */
+typedef DECLCALLBACK(int) FNHGCMSVCEXT(void *pvExtension, uint32_t u32Function, void *pvParm, uint32_t cbParms);
+typedef FNHGCMSVCEXT *PFNHGCMSVCEXT;
+
+/** The Service DLL entry points.
+ *
+ *  HGCM will call the DLL "VBoxHGCMSvcLoad"
+ *  function and the DLL must fill in the VBOXHGCMSVCFNTABLE
+ *  with function pointers.
+ */
+
+/* The structure is used in separately compiled binaries so an explicit packing is required. */
+#pragma pack(1) /** @todo r=bird: The pragma pack(1) is not at all required!! */
+typedef struct VBOXHGCMSVCFNTABLE
+{
+    /** @name Filled by HGCM
+     * @{ */
+
+    /** Size of the structure. */
+    uint32_t                 cbSize;
+
+    /** Version of the structure, including the helpers. */
+    uint32_t                 u32Version;
+
+    PVBOXHGCMSVCHELPERS      pHelpers;
+    /** @} */
+
+    /** @name Filled in by the service.
+     * @{ */
+
+    /** Size of client information the service want to have. */
+    uint32_t                 cbClient;
+#if ARCH_BITS == 64
+    /** Ensure that the following pointers are properly aligned on 64-bit system. */
+    uint32_t                 u32Alignment0;
+#endif
+
+    /** Uninitialize service */
+    DECLR3CALLBACKMEMBER(int, pfnUnload, (void *pvService));
+
+    /** Inform the service about a client connection. */
+    DECLR3CALLBACKMEMBER(int, pfnConnect, (void *pvService, uint32_t u32ClientID, void *pvClient));
+
+    /** Inform the service that the client wants to disconnect. */
+    DECLR3CALLBACKMEMBER(int, pfnDisconnect, (void *pvService, uint32_t u32ClientID, void *pvClient));
+
+    /** Service entry point.
+     *  Return code is passed to pfnCallComplete callback.
+     */
+    DECLR3CALLBACKMEMBER(void, pfnCall, (void *pvService, VBOXHGCMCALLHANDLE callHandle, uint32_t u32ClientID, void *pvClient, uint32_t function, uint32_t cParms, VBOXHGCMSVCPARM paParms[]));
+
+    /** Host Service entry point meant for privileged features invisible to the guest.
+     *  Return code is passed to pfnCallComplete callback.
+     */
+    DECLR3CALLBACKMEMBER(int, pfnHostCall, (void *pvService, uint32_t function, uint32_t cParms, VBOXHGCMSVCPARM paParms[]));
+
+    /** Inform the service about a VM save operation. */
+    DECLR3CALLBACKMEMBER(int, pfnSaveState, (void *pvService, uint32_t u32ClientID, void *pvClient, PSSMHANDLE pSSM));
+
+    /** Inform the service about a VM load operation. */
+    DECLR3CALLBACKMEMBER(int, pfnLoadState, (void *pvService, uint32_t u32ClientID, void *pvClient, PSSMHANDLE pSSM));
+
+    /** Register a service extension callback. */
+    DECLR3CALLBACKMEMBER(int, pfnRegisterExtension, (void *pvService, PFNHGCMSVCEXT pfnExtension, void *pvExtension));
+
+    /** User/instance data pointer for the service. */
+    void *pvService;
+
+    /** @} */
+} VBOXHGCMSVCFNTABLE;
+#pragma pack()
+
+
+/** Service initialization entry point. */
+typedef DECLCALLBACK(int) VBOXHGCMSVCLOAD(VBOXHGCMSVCFNTABLE *ptable);
+typedef VBOXHGCMSVCLOAD *PFNVBOXHGCMSVCLOAD;
+#define VBOX_HGCM_SVCLOAD_NAME "VBoxHGCMSvcLoad"
+
+#endif
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/include/VBox/log.h
@@ -0,0 +1,1163 @@
+/** @file
+ * VirtualBox - Logging.
+ */
+
+/*
+ * Copyright (C) 2006-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+#ifndef ___VBox_log_h
+#define ___VBox_log_h
+
+/*
+ * Set the default loggroup.
+ */
+#ifndef LOG_GROUP
+# define LOG_GROUP LOG_GROUP_DEFAULT
+#endif
+
+#include <iprt/log.h>
+
+
+/** @defgroup grp_rt_vbox_log    VBox Logging
+ * @ingroup grp_rt_vbox
+ * @{
+ */
+
+/** PC port for debug output */
+#define RTLOG_DEBUG_PORT 0x504
+
+/**
+ * VirtualBox Logging Groups.
+ * (Remember to update LOGGROUP_NAMES!)
+ *
+ * @remark It should be pretty obvious, but just to have
+ *         mentioned it, the values are sorted alphabetically (using the
+ *         english alphabet) except for _DEFAULT which is always first.
+ *
+ *         If anyone might be wondering what the alphabet looks like:
+ *              A B C D E F G H I J K L M N O P Q R S T U V W X Y Z _
+ */
+typedef enum LOGGROUP
+{
+    /** The default VBox group. */
+    LOG_GROUP_DEFAULT = RTLOGGROUP_FIRST_USER,
+    /** Audio mixer group. */
+    LOG_GROUP_AUDIO_MIXER,
+    /** Audio mixer buffer group. */
+    LOG_GROUP_AUDIO_MIXER_BUFFER,
+    /** Auto-logon group. */
+    LOG_GROUP_AUTOLOGON,
+    /** CFGM group. */
+    LOG_GROUP_CFGM,
+    /** CPUM group. */
+    LOG_GROUP_CPUM,
+    /** CSAM group. */
+    LOG_GROUP_CSAM,
+    /** Debug Console group. */
+    LOG_GROUP_DBGC,
+    /** DBGF group. */
+    LOG_GROUP_DBGF,
+    /** DBGF info group. */
+    LOG_GROUP_DBGF_INFO,
+    /** The debugger gui. */
+    LOG_GROUP_DBGG,
+    /** Generic Device group. */
+    LOG_GROUP_DEV,
+    /** AC97 Device group. */
+    LOG_GROUP_DEV_AC97,
+    /** ACPI Device group. */
+    LOG_GROUP_DEV_ACPI,
+    /** AHCI Device group. */
+    LOG_GROUP_DEV_AHCI,
+    /** APIC Device group. */
+    LOG_GROUP_DEV_APIC,
+    /** BusLogic SCSI host adapter group. */
+    LOG_GROUP_DEV_BUSLOGIC,
+    /** DMA Controller group. */
+    LOG_GROUP_DEV_DMA,
+    /** Gigabit Ethernet Device group. */
+    LOG_GROUP_DEV_E1000,
+    /** Extensible Firmware Interface Device group. */
+    LOG_GROUP_DEV_EFI,
+    /** USB EHCI Device group. */
+    LOG_GROUP_DEV_EHCI,
+    /** Floppy Controller Device group. */
+    LOG_GROUP_DEV_FDC,
+    /** Guest Interface Manager Device group. */
+    LOG_GROUP_DEV_GIM,
+    /** HDA Device group. */
+    LOG_GROUP_DEV_HDA,
+    /** HDA Codec Device group. */
+    LOG_GROUP_DEV_HDA_CODEC,
+    /** High Precision Event Timer Device group. */
+    LOG_GROUP_DEV_HPET,
+    /** IDE Device group. */
+    LOG_GROUP_DEV_IDE,
+    /** The internal networking IP stack Device group. */
+    LOG_GROUP_DEV_INIP,
+    /** KeyBoard Controller Device group. */
+    LOG_GROUP_DEV_KBD,
+    /** Low Pin Count Device group. */
+    LOG_GROUP_DEV_LPC,
+    /** LsiLogic SCSI controller Device group. */
+    LOG_GROUP_DEV_LSILOGICSCSI,
+    /** NE2000 Device group. */
+    LOG_GROUP_DEV_NE2000,
+    /** USB OHCI Device group. */
+    LOG_GROUP_DEV_OHCI,
+    /** Parallel Device group */
+    LOG_GROUP_DEV_PARALLEL,
+    /** PC Device group. */
+    LOG_GROUP_DEV_PC,
+    /** PC Architecture Device group. */
+    LOG_GROUP_DEV_PC_ARCH,
+    /** PC BIOS Device group. */
+    LOG_GROUP_DEV_PC_BIOS,
+    /** PCI Device group. */
+    LOG_GROUP_DEV_PCI,
+    /** PCI Raw Device group. */
+    LOG_GROUP_DEV_PCI_RAW,
+    /** PCNet Device group. */
+    LOG_GROUP_DEV_PCNET,
+    /** PIC Device group. */
+    LOG_GROUP_DEV_PIC,
+    /** PIT Device group. */
+    LOG_GROUP_DEV_PIT,
+    /** RTC Device group. */
+    LOG_GROUP_DEV_RTC,
+    /** SB16 Device group. */
+    LOG_GROUP_DEV_SB16,
+    /** Serial Device group */
+    LOG_GROUP_DEV_SERIAL,
+    /** System Management Controller Device group. */
+    LOG_GROUP_DEV_SMC,
+    /** VGA Device group. */
+    LOG_GROUP_DEV_VGA,
+    /** Virtio PCI Device group. */
+    LOG_GROUP_DEV_VIRTIO,
+    /** Virtio Network Device group. */
+    LOG_GROUP_DEV_VIRTIO_NET,
+    /** VMM Device group. */
+    LOG_GROUP_DEV_VMM,
+    /** VMM Device group for backdoor logging. */
+    LOG_GROUP_DEV_VMM_BACKDOOR,
+    /** VMM Device group for logging guest backdoor logging to stderr. */
+    LOG_GROUP_DEV_VMM_STDERR,
+    /** VMSVGA Device group. */
+    LOG_GROUP_DEV_VMSVGA,
+    /** USB xHCI Device group. */
+    LOG_GROUP_DEV_XHCI,
+    /** Disassembler group. */
+    LOG_GROUP_DIS,
+    /** Generic driver group. */
+    LOG_GROUP_DRV,
+    /** ACPI driver group */
+    LOG_GROUP_DRV_ACPI,
+    /** Audio driver group */
+    LOG_GROUP_DRV_AUDIO,
+    /** Block driver group. */
+    LOG_GROUP_DRV_BLOCK,
+    /** Char driver group. */
+    LOG_GROUP_DRV_CHAR,
+    /** Disk integrity driver group. */
+    LOG_GROUP_DRV_DISK_INTEGRITY,
+    /** Video Display driver group. */
+    LOG_GROUP_DRV_DISPLAY,
+    /** Floppy media driver group. */
+    LOG_GROUP_DRV_FLOPPY,
+    /** Host Audio driver group. */
+    LOG_GROUP_DRV_HOST_AUDIO,
+    /** Host Base block driver group. */
+    LOG_GROUP_DRV_HOST_BASE,
+    /** Host DVD block driver group. */
+    LOG_GROUP_DRV_HOST_DVD,
+    /** Host floppy block driver group. */
+    LOG_GROUP_DRV_HOST_FLOPPY,
+    /** Host Parallel Driver group */
+    LOG_GROUP_DRV_HOST_PARALLEL,
+    /** Host Serial Driver Group */
+    LOG_GROUP_DRV_HOST_SERIAL,
+    /** The internal networking transport driver group. */
+    LOG_GROUP_DRV_INTNET,
+    /** ISO (CD/DVD) media driver group. */
+    LOG_GROUP_DRV_ISO,
+    /** Keyboard Queue driver group. */
+    LOG_GROUP_DRV_KBD_QUEUE,
+    /** lwIP IP stack driver group. */
+    LOG_GROUP_DRV_LWIP,
+    /** Video Miniport driver group. */
+    LOG_GROUP_DRV_MINIPORT,
+    /** Mouse driver group. */
+    LOG_GROUP_DRV_MOUSE,
+    /** Mouse Queue driver group. */
+    LOG_GROUP_DRV_MOUSE_QUEUE,
+    /** Named Pipe stream driver group. */
+    LOG_GROUP_DRV_NAMEDPIPE,
+    /** NAT network transport driver group */
+    LOG_GROUP_DRV_NAT,
+    /** Raw image driver group */
+    LOG_GROUP_DRV_RAW_IMAGE,
+    /** SCSI driver group. */
+    LOG_GROUP_DRV_SCSI,
+    /** Host SCSI driver group. */
+    LOG_GROUP_DRV_SCSIHOST,
+    /** TCP socket stream driver group. */
+    LOG_GROUP_DRV_TCP,
+    /** Async transport driver group */
+    LOG_GROUP_DRV_TRANSPORT_ASYNC,
+    /** TUN network transport driver group */
+    LOG_GROUP_DRV_TUN,
+    /** UDP tunnet network transport driver group. */
+    LOG_GROUP_DRV_UDPTUNNEL,
+    /** USB Proxy driver group. */
+    LOG_GROUP_DRV_USBPROXY,
+    /** VBoxHDD media driver group. */
+    LOG_GROUP_DRV_VBOXHDD,
+    /** VBox HDD container media driver group. */
+    LOG_GROUP_DRV_VD,
+    /** VRDE audio driver group. */
+    LOG_GROUP_DRV_VRDE_AUDIO,
+    /** Virtual Switch transport driver group */
+    LOG_GROUP_DRV_VSWITCH,
+    /** VUSB driver group */
+    LOG_GROUP_DRV_VUSB,
+    /** EM group. */
+    LOG_GROUP_EM,
+    /** FTM group. */
+    LOG_GROUP_FTM,
+    /** GIM group. */
+    LOG_GROUP_GIM,
+    /** GMM group. */
+    LOG_GROUP_GMM,
+    /** Guest control. */
+    LOG_GROUP_GUEST_CONTROL,
+    /** Guest drag'n drop. */
+    LOG_GROUP_GUEST_DND,
+    /** GUI group. */
+    LOG_GROUP_GUI,
+    /** GVMM group. */
+    LOG_GROUP_GVMM,
+    /** HGCM group */
+    LOG_GROUP_HGCM,
+    /** HGSMI group */
+    LOG_GROUP_HGSMI,
+    /** HM group. */
+    LOG_GROUP_HM,
+    /** IEM group. */
+    LOG_GROUP_IEM,
+    /** IOM group. */
+    LOG_GROUP_IOM,
+    /** XPCOM IPC group. */
+    LOG_GROUP_IPC,
+    /** lwIP group. */
+    LOG_GROUP_LWIP,
+    /** lwIP group, api_lib.c API_LIB_DEBUG */
+    LOG_GROUP_LWIP_API_LIB,
+    /** lwIP group, api_msg.c API_MSG_DEBUG */
+    LOG_GROUP_LWIP_API_MSG,
+    /** lwIP group, etharp.c ETHARP_DEBUG */
+    LOG_GROUP_LWIP_ETHARP,
+    /** lwIP group, icmp.c ICMP_DEBUG */
+    LOG_GROUP_LWIP_ICMP,
+    /** lwIP group, igmp.c IGMP_DEBUG */
+    LOG_GROUP_LWIP_IGMP,
+    /** lwIP group, inet.c INET_DEBUG */
+    LOG_GROUP_LWIP_INET,
+    /** lwIP group, IP_DEBUG (sic!) */
+    LOG_GROUP_LWIP_IP4,
+    /** lwIP group, ip_frag.c IP_REASS_DEBUG (sic!) */
+    LOG_GROUP_LWIP_IP4_REASS,
+    /** lwIP group, IP6_DEBUG */
+    LOG_GROUP_LWIP_IP6,
+    /** lwIP group, mem.c MEM_DEBUG */
+    LOG_GROUP_LWIP_MEM,
+    /** lwIP group, memp.c MEMP_DEBUG */
+    LOG_GROUP_LWIP_MEMP,
+    /** lwIP group, netif.c NETIF_DEBUG */
+    LOG_GROUP_LWIP_NETIF,
+    /** lwIP group, pbuf.c PBUF_DEBUG */
+    LOG_GROUP_LWIP_PBUF,
+    /** lwIP group, raw.c RAW_DEBUG */
+    LOG_GROUP_LWIP_RAW,
+    /** lwIP group, sockets.c SOCKETS_DEBUG */
+    LOG_GROUP_LWIP_SOCKETS,
+    /** lwIP group, SYS_DEBUG */
+    LOG_GROUP_LWIP_SYS,
+    /** lwIP group, TCP_DEBUG */
+    LOG_GROUP_LWIP_TCP,
+    /** lwIP group, tcpip.c TCPIP_DEBUG */
+    LOG_GROUP_LWIP_TCPIP,
+    /** lwIP group, TCP_CWND_DEBUG (congestion window) */
+    LOG_GROUP_LWIP_TCP_CWND,
+    /** lwIP group, tcp_in.c TCP_FR_DEBUG (fast retransmit) */
+    LOG_GROUP_LWIP_TCP_FR,
+    /** lwIP group, tcp_in.c TCP_INPUT_DEBUG */
+    LOG_GROUP_LWIP_TCP_INPUT,
+    /** lwIP group, tcp_out.c TCP_OUTPUT_DEBUG */
+    LOG_GROUP_LWIP_TCP_OUTPUT,
+    /** lwIP group, TCP_QLEN_DEBUG */
+    LOG_GROUP_LWIP_TCP_QLEN,
+    /** lwIP group, TCP_RST_DEBUG */
+    LOG_GROUP_LWIP_TCP_RST,
+    /** lwIP group, TCP_RTO_DEBUG (retransmit) */
+    LOG_GROUP_LWIP_TCP_RTO,
+    /** lwIP group, tcp_in.c TCP_WND_DEBUG (window updates) */
+    LOG_GROUP_LWIP_TCP_WND,
+    /** lwIP group, timers.c TIMERS_DEBUG */
+    LOG_GROUP_LWIP_TIMERS,
+    /** lwIP group, udp.c UDP_DEBUG */
+    LOG_GROUP_LWIP_UDP,
+    /** Main group. */
+    LOG_GROUP_MAIN,
+    /** Main group, IAdditionsFacility. */
+    LOG_GROUP_MAIN_ADDITIONSFACILITY,
+    /** Main group, IAdditionsStateChangedEvent. */
+    LOG_GROUP_MAIN_ADDITIONSSTATECHANGEDEVENT,
+    /** Main group, IAppliance. */
+    LOG_GROUP_MAIN_APPLIANCE,
+    /** Main group, IAudioAdapter. */
+    LOG_GROUP_MAIN_AUDIOADAPTER,
+    /** Main group, IBandwidthControl. */
+    LOG_GROUP_MAIN_BANDWIDTHCONTROL,
+    /** Main group, IBandwidthGroup. */
+    LOG_GROUP_MAIN_BANDWIDTHGROUP,
+    /** Main group, IBandwidthGroupChangedEvent. */
+    LOG_GROUP_MAIN_BANDWIDTHGROUPCHANGEDEVENT,
+    /** Main group, IBIOSSettings. */
+    LOG_GROUP_MAIN_BIOSSETTINGS,
+    /** Main group, ICanShowWindowEvent. */
+    LOG_GROUP_MAIN_CANSHOWWINDOWEVENT,
+    /** Main group, IClipboardModeChangedEvent. */
+    LOG_GROUP_MAIN_CLIPBOARDMODECHANGEDEVENT,
+    /** Main group, IConsole. */
+    LOG_GROUP_MAIN_CONSOLE,
+    /** Main group, ICPUChangedEvent. */
+    LOG_GROUP_MAIN_CPUCHANGEDEVENT,
+    /** Main group, ICPUExecutionCapChangedEvent. */
+    LOG_GROUP_MAIN_CPUEXECUTIONCAPCHANGEDEVENT,
+    /** Main group, IDHCPServer. */
+    LOG_GROUP_MAIN_DHCPSERVER,
+    /** Main group, IDirectory. */
+    LOG_GROUP_MAIN_DIRECTORY,
+    /** Main group, IDisplay. */
+    LOG_GROUP_MAIN_DISPLAY,
+    /** Main group, IDisplaySourceBitmap. */
+    LOG_GROUP_MAIN_DISPLAYSOURCEBITMAP,
+    /** Main group, IDnDBase. */
+    LOG_GROUP_MAIN_DNDBASE,
+    /** Main group, IDnDModeChangedEvent. */
+    LOG_GROUP_MAIN_DNDMODECHANGEDEVENT,
+    /** Main group, IDnDSource. */
+    LOG_GROUP_MAIN_DNDSOURCE,
+    /** Main group, IDnDTarget. */
+    LOG_GROUP_MAIN_DNDTARGET,
+    /** Main group, IEmulatedUSB. */
+    LOG_GROUP_MAIN_EMULATEDUSB,
+    /** Main group, IEvent. */
+    LOG_GROUP_MAIN_EVENT,
+    /** Main group, IEventListener. */
+    LOG_GROUP_MAIN_EVENTLISTENER,
+    /** Main group, IEventSource. */
+    LOG_GROUP_MAIN_EVENTSOURCE,
+    /** Main group, IEventSourceChangedEvent. */
+    LOG_GROUP_MAIN_EVENTSOURCECHANGEDEVENT,
+    /** Main group, IExtPack. */
+    LOG_GROUP_MAIN_EXTPACK,
+    /** Main group, IExtPackBase. */
+    LOG_GROUP_MAIN_EXTPACKBASE,
+    /** Main group, IExtPackFile. */
+    LOG_GROUP_MAIN_EXTPACKFILE,
+    /** Main group, IExtPackManager. */
+    LOG_GROUP_MAIN_EXTPACKMANAGER,
+    /** Main group, IExtPackPlugIn. */
+    LOG_GROUP_MAIN_EXTPACKPLUGIN,
+    /** Main group, IExtraDataCanChangeEvent. */
+    LOG_GROUP_MAIN_EXTRADATACANCHANGEEVENT,
+    /** Main group, IExtraDataChangedEvent. */
+    LOG_GROUP_MAIN_EXTRADATACHANGEDEVENT,
+    /** Main group, IFile. */
+    LOG_GROUP_MAIN_FILE,
+    /** Main group, IFramebuffer. */
+    LOG_GROUP_MAIN_FRAMEBUFFER,
+    /** Main group, IFramebufferOverlay. */
+    LOG_GROUP_MAIN_FRAMEBUFFEROVERLAY,
+    /** Main group, IFsObjInfo. */
+    LOG_GROUP_MAIN_FSOBJINFO,
+    /** Main group, IGuest. */
+    LOG_GROUP_MAIN_GUEST,
+    /** Main group, IGuestDirectory. */
+    LOG_GROUP_MAIN_GUESTDIRECTORY,
+    /** Main group, IGuestDnDSource. */
+    LOG_GROUP_MAIN_GUESTDNDSOURCE,
+    /** Main group, IGuestDnDTarget. */
+    LOG_GROUP_MAIN_GUESTDNDTARGET,
+    /** Main group, IGuestErrorInfo. */
+    LOG_GROUP_MAIN_GUESTERRORINFO,
+    /** Main group, IGuestFile. */
+    LOG_GROUP_MAIN_GUESTFILE,
+    /** Main group, IGuestFileEvent. */
+    LOG_GROUP_MAIN_GUESTFILEEVENT,
+    /** Main group, IGuestFileIOEvent. */
+    LOG_GROUP_MAIN_GUESTFILEIOEVENT,
+    /** Main group, IGuestFileOffsetChangedEvent. */
+    LOG_GROUP_MAIN_GUESTFILEOFFSETCHANGEDEVENT,
+    /** Main group, IGuestFileReadEvent. */
+    LOG_GROUP_MAIN_GUESTFILEREADEVENT,
+    /** Main group, IGuestFileRegisteredEvent. */
+    LOG_GROUP_MAIN_GUESTFILEREGISTEREDEVENT,
+    /** Main group, IGuestFileStateChangedEvent. */
+    LOG_GROUP_MAIN_GUESTFILESTATECHANGEDEVENT,
+    /** Main group, IGuestFileWriteEvent. */
+    LOG_GROUP_MAIN_GUESTFILEWRITEEVENT,
+    /** Main group, IGuestFsObjInfo. */
+    LOG_GROUP_MAIN_GUESTFSOBJINFO,
+    /** Main group, IGuestKeyboardEvent. */
+    LOG_GROUP_MAIN_GUESTKEYBOARDEVENT,
+    /** Main group, IGuestMonitorChangedEvent. */
+    LOG_GROUP_MAIN_GUESTMONITORCHANGEDEVENT,
+    /** Main group, IGuestMouseEvent. */
+    LOG_GROUP_MAIN_GUESTMOUSEEVENT,
+    /** Main group, IGuestMultiTouchEvent. */
+    LOG_GROUP_MAIN_GUESTMULTITOUCHEVENT,
+    /** Main group, IGuestOSType. */
+    LOG_GROUP_MAIN_GUESTOSTYPE,
+    /** Main group, IGuestProcess. */
+    LOG_GROUP_MAIN_GUESTPROCESS,
+    /** Main group, IGuestProcessEvent. */
+    LOG_GROUP_MAIN_GUESTPROCESSEVENT,
+    /** Main group, IGuestProcessInputNotifyEvent. */
+    LOG_GROUP_MAIN_GUESTPROCESSINPUTNOTIFYEVENT,
+    /** Main group, IGuestProcessIOEvent. */
+    LOG_GROUP_MAIN_GUESTPROCESSIOEVENT,
+    /** Main group, IGuestProcessOutputEvent. */
+    LOG_GROUP_MAIN_GUESTPROCESSOUTPUTEVENT,
+    /** Main group, IGuestProcessRegisteredEvent. */
+    LOG_GROUP_MAIN_GUESTPROCESSREGISTEREDEVENT,
+    /** Main group, IGuestProcessStateChangedEvent. */
+    LOG_GROUP_MAIN_GUESTPROCESSSTATECHANGEDEVENT,
+    /** Main group, IGuestPropertyChangedEvent. */
+    LOG_GROUP_MAIN_GUESTPROPERTYCHANGEDEVENT,
+    /** Main group, IGuestSession. */
+    LOG_GROUP_MAIN_GUESTSESSION,
+    /** Main group, IGuestSessionEvent. */
+    LOG_GROUP_MAIN_GUESTSESSIONEVENT,
+    /** Main group, IGuestSessionRegisteredEvent. */
+    LOG_GROUP_MAIN_GUESTSESSIONREGISTEREDEVENT,
+    /** Main group, IGuestSessionStateChangedEvent. */
+    LOG_GROUP_MAIN_GUESTSESSIONSTATECHANGEDEVENT,
+    /** Main group, IGuestUserStateChangedEvent. */
+    LOG_GROUP_MAIN_GUESTUSERSTATECHANGEDEVENT,
+    /** Main group, IHost. */
+    LOG_GROUP_MAIN_HOST,
+    /** Main group, IHostNameResolutionConfigurationChangeEvent. */
+    LOG_GROUP_MAIN_HOSTNAMERESOLUTIONCONFIGURATIONCHANGEEVENT,
+    /** Main group, IHostNetworkInterface. */
+    LOG_GROUP_MAIN_HOSTNETWORKINTERFACE,
+    /** Main group, IHostPCIDevicePlugEvent. */
+    LOG_GROUP_MAIN_HOSTPCIDEVICEPLUGEVENT,
+    /** Main group, IHostUSBDevice. */
+    LOG_GROUP_MAIN_HOSTUSBDEVICE,
+    /** Main group, IHostUSBDeviceFilter. */
+    LOG_GROUP_MAIN_HOSTUSBDEVICEFILTER,
+    /** Main group, IHostVideoInputDevice. */
+    LOG_GROUP_MAIN_HOSTVIDEOINPUTDEVICE,
+    /** Main group, IInternalMachineControl. */
+    LOG_GROUP_MAIN_INTERNALMACHINECONTROL,
+    /** Main group, IInternalSessionControl. */
+    LOG_GROUP_MAIN_INTERNALSESSIONCONTROL,
+    /** Main group, IKeyboard. */
+    LOG_GROUP_MAIN_KEYBOARD,
+    /** Main group, IKeyboardLedsChangedEvent. */
+    LOG_GROUP_MAIN_KEYBOARDLEDSCHANGEDEVENT,
+    /** Main group, IMachine. */
+    LOG_GROUP_MAIN_MACHINE,
+    /** Main group, IMachineDataChangedEvent. */
+    LOG_GROUP_MAIN_MACHINEDATACHANGEDEVENT,
+    /** Main group, IMachineDebugger. */
+    LOG_GROUP_MAIN_MACHINEDEBUGGER,
+    /** Main group, IMachineEvent. */
+    LOG_GROUP_MAIN_MACHINEEVENT,
+    /** Main group, IMachineRegisteredEvent. */
+    LOG_GROUP_MAIN_MACHINEREGISTEREDEVENT,
+    /** Main group, IMachineStateChangedEvent. */
+    LOG_GROUP_MAIN_MACHINESTATECHANGEDEVENT,
+    /** Main group, IMedium. */
+    LOG_GROUP_MAIN_MEDIUM,
+    /** Main group, IMediumAttachment. */
+    LOG_GROUP_MAIN_MEDIUMATTACHMENT,
+    /** Main group, IMediumChangedEvent. */
+    LOG_GROUP_MAIN_MEDIUMCHANGEDEVENT,
+    /** Main group, IMediumConfigChangedEvent. */
+    LOG_GROUP_MAIN_MEDIUMCONFIGCHANGEDEVENT,
+    /** Main group, IMediumFormat. */
+    LOG_GROUP_MAIN_MEDIUMFORMAT,
+    /** Main group, IMediumRegisteredEvent. */
+    LOG_GROUP_MAIN_MEDIUMREGISTEREDEVENT,
+    /** Main group, IMouse. */
+    LOG_GROUP_MAIN_MOUSE,
+    /** Main group, IMouseCapabilityChangedEvent. */
+    LOG_GROUP_MAIN_MOUSECAPABILITYCHANGEDEVENT,
+    /** Main group, IMousePointerShape. */
+    LOG_GROUP_MAIN_MOUSEPOINTERSHAPE,
+    /** Main group, IMousePointerShapeChangedEvent. */
+    LOG_GROUP_MAIN_MOUSEPOINTERSHAPECHANGEDEVENT,
+    /** Main group, INATEngine. */
+    LOG_GROUP_MAIN_NATENGINE,
+    /** Main group, INATNetwork. */
+    LOG_GROUP_MAIN_NATNETWORK,
+    /** Main group, INATNetworkAlterEvent. */
+    LOG_GROUP_MAIN_NATNETWORKALTEREVENT,
+    /** Main group, INATNetworkChangedEvent. */
+    LOG_GROUP_MAIN_NATNETWORKCHANGEDEVENT,
+    /** Main group, INATNetworkCreationDeletionEvent. */
+    LOG_GROUP_MAIN_NATNETWORKCREATIONDELETIONEVENT,
+    /** Main group, INATNetworkPortForwardEvent. */
+    LOG_GROUP_MAIN_NATNETWORKPORTFORWARDEVENT,
+    /** Main group, INATNetworkSettingEvent. */
+    LOG_GROUP_MAIN_NATNETWORKSETTINGEVENT,
+    /** Main group, INATNetworkStartStopEvent. */
+    LOG_GROUP_MAIN_NATNETWORKSTARTSTOPEVENT,
+    /** Main group, INATRedirectEvent. */
+    LOG_GROUP_MAIN_NATREDIRECTEVENT,
+    /** Main group, INetworkAdapter. */
+    LOG_GROUP_MAIN_NETWORKADAPTER,
+    /** Main group, INetworkAdapterChangedEvent. */
+    LOG_GROUP_MAIN_NETWORKADAPTERCHANGEDEVENT,
+    /** Main group, IParallelPort. */
+    LOG_GROUP_MAIN_PARALLELPORT,
+    /** Main group, IParallelPortChangedEvent. */
+    LOG_GROUP_MAIN_PARALLELPORTCHANGEDEVENT,
+    /** Main group, IPCIAddress. */
+    LOG_GROUP_MAIN_PCIADDRESS,
+    /** Main group, IPCIDeviceAttachment. */
+    LOG_GROUP_MAIN_PCIDEVICEATTACHMENT,
+    /** Main group, IPerformanceCollector. */
+    LOG_GROUP_MAIN_PERFORMANCECOLLECTOR,
+    /** Main group, IPerformanceMetric. */
+    LOG_GROUP_MAIN_PERFORMANCEMETRIC,
+    /** Main group, IProcess. */
+    LOG_GROUP_MAIN_PROCESS,
+    /** Main group, IProgress. */
+    LOG_GROUP_MAIN_PROGRESS,
+    /** Main group, IReusableEvent. */
+    LOG_GROUP_MAIN_REUSABLEEVENT,
+    /** Main group, IRuntimeErrorEvent. */
+    LOG_GROUP_MAIN_RUNTIMEERROREVENT,
+    /** Main group, ISerialPort. */
+    LOG_GROUP_MAIN_SERIALPORT,
+    /** Main group, ISerialPortChangedEvent. */
+    LOG_GROUP_MAIN_SERIALPORTCHANGEDEVENT,
+    /** Main group, ISession. */
+    LOG_GROUP_MAIN_SESSION,
+    /** Main group, ISessionStateChangedEvent. */
+    LOG_GROUP_MAIN_SESSIONSTATECHANGEDEVENT,
+    /** Main group, ISharedFolder. */
+    LOG_GROUP_MAIN_SHAREDFOLDER,
+    /** Main group, ISharedFolderChangedEvent. */
+    LOG_GROUP_MAIN_SHAREDFOLDERCHANGEDEVENT,
+    /** Main group, IShowWindowEvent. */
+    LOG_GROUP_MAIN_SHOWWINDOWEVENT,
+    /** Main group, ISnapshot. */
+    LOG_GROUP_MAIN_SNAPSHOT,
+    /** Main group, ISnapshotChangedEvent. */
+    LOG_GROUP_MAIN_SNAPSHOTCHANGEDEVENT,
+    /** Main group, ISnapshotDeletedEvent. */
+    LOG_GROUP_MAIN_SNAPSHOTDELETEDEVENT,
+    /** Main group, ISnapshotEvent. */
+    LOG_GROUP_MAIN_SNAPSHOTEVENT,
+    /** Main group, ISnapshotTakenEvent. */
+    LOG_GROUP_MAIN_SNAPSHOTRESTOREDEVENT,
+    /** Main group, ISnapshotRestoredEvent. */
+    LOG_GROUP_MAIN_SNAPSHOTTAKENEVENT,
+    /** Main group, IStateChangedEvent. */
+    LOG_GROUP_MAIN_STATECHANGEDEVENT,
+    /** Main group, IStorageController. */
+    LOG_GROUP_MAIN_STORAGECONTROLLER,
+    /** Main group, IStorageControllerChangedEvent. */
+    LOG_GROUP_MAIN_STORAGECONTROLLERCHANGEDEVENT,
+    /** Main group, IStorageDeviceChangedEvent. */
+    LOG_GROUP_MAIN_STORAGEDEVICECHANGEDEVENT,
+    /** Main group, ISystemProperties. */
+    LOG_GROUP_MAIN_SYSTEMPROPERTIES,
+    /** Main group, IToken. */
+    LOG_GROUP_MAIN_TOKEN,
+    /** Main group, IUSBController. */
+    LOG_GROUP_MAIN_USBCONTROLLER,
+    /** Main group, IUSBControllerChangedEvent. */
+    LOG_GROUP_MAIN_USBCONTROLLERCHANGEDEVENT,
+    /** Main group, IUSBDevice. */
+    LOG_GROUP_MAIN_USBDEVICE,
+    /** Main group, IUSBDeviceFilter. */
+    LOG_GROUP_MAIN_USBDEVICEFILTER,
+    /** Main group, IUSBDeviceFilters. */
+    LOG_GROUP_MAIN_USBDEVICEFILTERS,
+    /** Main group, IUSBDeviceStateChangedEvent. */
+    LOG_GROUP_MAIN_USBDEVICESTATECHANGEDEVENT,
+    /** Main group, IVBoxSVCAvailabilityChangedEvent. */
+    LOG_GROUP_MAIN_VBOXSVCAVAILABILITYCHANGEDEVENT,
+    /** Main group, IVetoEvent. */
+    LOG_GROUP_MAIN_VETOEVENT,
+    /** Main group, IVFSExplorer. */
+    LOG_GROUP_MAIN_VFSEXPLORER,
+    /** Main group, IVideoCaptureChangedEvent. */
+    LOG_GROUP_MAIN_VIDEOCAPTURECHANGEDEVENT,
+    /** Main group, IVirtualBox. */
+    LOG_GROUP_MAIN_VIRTUALBOX,
+    /** Main group, IVirtualBoxClient. */
+    LOG_GROUP_MAIN_VIRTUALBOXCLIENT,
+    /** Main group, IVirtualSystemDescription. */
+    LOG_GROUP_MAIN_VIRTUALSYSTEMDESCRIPTION,
+    /** Main group, IVRDEServer. */
+    LOG_GROUP_MAIN_VRDESERVER,
+    /** Main group, IVRDEServerChangedEvent. */
+    LOG_GROUP_MAIN_VRDESERVERCHANGEDEVENT,
+    /** Main group, IVRDEServerInfo. */
+    LOG_GROUP_MAIN_VRDESERVERINFO,
+    /** Main group, IVRDEServerInfoChangedEvent. */
+    LOG_GROUP_MAIN_VRDESERVERINFOCHANGEDEVENT,
+    /** Misc. group intended for external use only. */
+    LOG_GROUP_MISC,
+    /** MM group. */
+    LOG_GROUP_MM,
+    /** MM group. */
+    LOG_GROUP_MM_HEAP,
+    /** MM group. */
+    LOG_GROUP_MM_HYPER,
+    /** MM Hypervisor Heap group. */
+    LOG_GROUP_MM_HYPER_HEAP,
+    /** MM Physical/Ram group. */
+    LOG_GROUP_MM_PHYS,
+    /** MM Page pool group. */
+    LOG_GROUP_MM_POOL,
+    /** The NAT service group */
+    LOG_GROUP_NAT_SERVICE,
+    /** The network adaptor driver group. */
+    LOG_GROUP_NET_ADP_DRV,
+    /** The network filter driver group. */
+    LOG_GROUP_NET_FLT_DRV,
+    /** The common network service group */
+    LOG_GROUP_NET_SERVICE,
+    /** Network traffic shaper driver group. */
+    LOG_GROUP_NET_SHAPER,
+    /** PATM group. */
+    LOG_GROUP_PATM,
+    /** PDM group. */
+    LOG_GROUP_PDM,
+    /** PDM Async completion group. */
+    LOG_GROUP_PDM_ASYNC_COMPLETION,
+    /** PDM Block cache group. */
+    LOG_GROUP_PDM_BLK_CACHE,
+    /** PDM Device group. */
+    LOG_GROUP_PDM_DEVICE,
+    /** PDM Driver group. */
+    LOG_GROUP_PDM_DRIVER,
+    /** PDM Loader group. */
+    LOG_GROUP_PDM_LDR,
+    /** PDM Loader group. */
+    LOG_GROUP_PDM_QUEUE,
+    /** PGM group. */
+    LOG_GROUP_PGM,
+    /** PGM dynamic mapping group. */
+    LOG_GROUP_PGM_DYNMAP,
+    /** PGM physical group. */
+    LOG_GROUP_PGM_PHYS,
+    /** PGM physical access group. */
+    LOG_GROUP_PGM_PHYS_ACCESS,
+    /** PGM shadow page pool group. */
+    LOG_GROUP_PGM_POOL,
+    /** PGM shared paging group. */
+    LOG_GROUP_PGM_SHARED,
+    /** REM group. */
+    LOG_GROUP_REM,
+    /** REM disassembly handler group. */
+    LOG_GROUP_REM_DISAS,
+    /** REM access handler group. */
+    LOG_GROUP_REM_HANDLER,
+    /** REM I/O port access group. */
+    LOG_GROUP_REM_IOPORT,
+    /** REM MMIO access group. */
+    LOG_GROUP_REM_MMIO,
+    /** REM Printf. */
+    LOG_GROUP_REM_PRINTF,
+    /** REM running group. */
+    LOG_GROUP_REM_RUN,
+    /** SELM group. */
+    LOG_GROUP_SELM,
+    /** Shared clipboard host service group. */
+    LOG_GROUP_SHARED_CLIPBOARD,
+    /** Chromium OpenGL host service group. */
+    LOG_GROUP_SHARED_CROPENGL,
+    /** Shared folders host service group. */
+    LOG_GROUP_SHARED_FOLDERS,
+    /** OpenGL host service group. */
+    LOG_GROUP_SHARED_OPENGL,
+    /** The internal networking service group. */
+    LOG_GROUP_SRV_INTNET,
+    /** SSM group. */
+    LOG_GROUP_SSM,
+    /** STAM group. */
+    LOG_GROUP_STAM,
+    /** SUP group. */
+    LOG_GROUP_SUP,
+    /** SUPport driver group. */
+    LOG_GROUP_SUP_DRV,
+    /** TM group. */
+    LOG_GROUP_TM,
+    /** TRPM group. */
+    LOG_GROUP_TRPM,
+    /** USB cardreader group. */
+    LOG_GROUP_USB_CARDREADER,
+    /** USB driver group. */
+    LOG_GROUP_USB_DRV,
+    /** USBFilter group. */
+    LOG_GROUP_USB_FILTER,
+    /** USB keyboard device group. */
+    LOG_GROUP_USB_KBD,
+    /** USB mouse/tablet device group. */
+    LOG_GROUP_USB_MOUSE,
+    /** MSD USB device group. */
+    LOG_GROUP_USB_MSD,
+    /** USB remote support. */
+    LOG_GROUP_USB_REMOTE,
+    /** USB webcam. */
+    LOG_GROUP_USB_WEBCAM,
+    /** VBox Guest Additions Driver (VBoxGuest). */
+    LOG_GROUP_VGDRV,
+    /** VBox Guest Additions Library. */
+    LOG_GROUP_VBGL,
+    /** Generic virtual disk layer. */
+    LOG_GROUP_VD,
+    /** DMG virtual disk backend. */
+    LOG_GROUP_VD_DMG,
+    /** iSCSI virtual disk backend. */
+    LOG_GROUP_VD_ISCSI,
+    /** Parallels HDD virtual disk backend. */
+    LOG_GROUP_VD_PARALLELS,
+    /** QCOW virtual disk backend. */
+    LOG_GROUP_VD_QCOW,
+    /** QED virtual disk backend. */
+    LOG_GROUP_VD_QED,
+    /** Raw virtual disk backend. */
+    LOG_GROUP_VD_RAW,
+    /** VDI virtual disk backend. */
+    LOG_GROUP_VD_VDI,
+    /** VHD virtual disk backend. */
+    LOG_GROUP_VD_VHD,
+    /** VHDX virtual disk backend. */
+    LOG_GROUP_VD_VHDX,
+    /** VMDK virtual disk backend. */
+    LOG_GROUP_VD_VMDK,
+    /** VM group. */
+    LOG_GROUP_VM,
+    /** VMM group. */
+    LOG_GROUP_VMM,
+    /** VRDE group */
+    LOG_GROUP_VRDE,
+    /** VRDP group */
+    LOG_GROUP_VRDP,
+    /** VSCSI group */
+    LOG_GROUP_VSCSI,
+    /** Webservice group. */
+    LOG_GROUP_WEBSERVICE
+    /* !!!ALPHABETICALLY!!! */
+} VBOX_LOGGROUP;
+
+
+/** @def VBOX_LOGGROUP_NAMES
+ * VirtualBox Logging group names.
+ *
+ * Must correspond 100% to LOGGROUP!
+ * Don't forget commas!
+ *
+ * @remark It should be pretty obvious, but just to have
+ *         mentioned it, the values are sorted alphabetically (using the
+ *         english alphabet) except for _DEFAULT which is always first.
+ *
+ *         If anyone might be wondering what the alphabet looks like:
+ *              a b c d e f g h i j k l m n o p q r s t u v w x y z
+ */
+#define VBOX_LOGGROUP_NAMES \
+{                   \
+    RT_LOGGROUP_NAMES, \
+    "DEFAULT",      \
+    "AUDIO_MIXER",  \
+    "AUDIO_MIXER_BUFFER", \
+    "AUTOLOGON",    \
+    "CFGM",         \
+    "CPUM",         \
+    "CSAM",         \
+    "DBGC",         \
+    "DBGF",         \
+    "DBGF_INFO",    \
+    "DBGG",         \
+    "DEV",          \
+    "DEV_AC97",     \
+    "DEV_ACPI",     \
+    "DEV_AHCI",     \
+    "DEV_APIC",     \
+    "DEV_BUSLOGIC", \
+    "DEV_DMA",      \
+    "DEV_E1000",    \
+    "DEV_EFI",      \
+    "DEV_EHCI",     \
+    "DEV_FDC",      \
+    "DEV_GIM",      \
+    "DEV_HDA",      \
+    "DEV_HDA_CODEC", \
+    "DEV_HPET",     \
+    "DEV_IDE",      \
+    "DEV_INIP",     \
+    "DEV_KBD",      \
+    "DEV_LPC",      \
+    "DEV_LSILOGICSCSI", \
+    "DEV_NE2000",   \
+    "DEV_OHCI",     \
+    "DEV_PARALLEL", \
+    "DEV_PC",       \
+    "DEV_PC_ARCH",  \
+    "DEV_PC_BIOS",  \
+    "DEV_PCI",      \
+    "DEV_PCI_RAW",  \
+    "DEV_PCNET",    \
+    "DEV_PIC",      \
+    "DEV_PIT",      \
+    "DEV_RTC",      \
+    "DEV_SB16",     \
+    "DEV_SERIAL",   \
+    "DEV_SMC",      \
+    "DEV_VGA",      \
+    "DEV_VIRTIO",   \
+    "DEV_VIRTIO_NET", \
+    "DEV_VMM",      \
+    "DEV_VMM_BACKDOOR", \
+    "DEV_VMM_STDERR", \
+    "DEV_VMSVGA",   \
+    "DEV_XHCI",     \
+    "DIS",          \
+    "DRV",          \
+    "DRV_ACPI",     \
+    "DRV_AUDIO",    \
+    "DRV_BLOCK",    \
+    "DRV_CHAR",     \
+    "DRV_DISK_INTEGRITY", \
+    "DRV_DISPLAY",  \
+    "DRV_FLOPPY",   \
+    "DRV_HOST_AUDIO", \
+    "DRV_HOST_BASE", \
+    "DRV_HOST_DVD", \
+    "DRV_HOST_FLOPPY", \
+    "DRV_HOST_PARALLEL", \
+    "DRV_HOST_SERIAL", \
+    "DRV_INTNET",   \
+    "DRV_ISO",      \
+    "DRV_KBD_QUEUE", \
+    "DRV_LWIP",     \
+    "DRV_MINIPORT", \
+    "DRV_MOUSE",    \
+    "DRV_MOUSE_QUEUE", \
+    "DRV_NAMEDPIPE", \
+    "DRV_NAT",      \
+    "DRV_RAW_IMAGE", \
+    "DRV_SCSI",     \
+    "DRV_SCSIHOST", \
+    "DRV_TELNETSERVER", \
+    "DRV_TRANSPORT_ASYNC", \
+    "DRV_TUN",      \
+    "DRV_UDPTUNNEL", \
+    "DRV_USBPROXY", \
+    "DRV_VBOXHDD",  \
+    "DRV_VD",       \
+    "DRV_VRDE_AUDIO", \
+    "DRV_VSWITCH",  \
+    "DRV_VUSB",     \
+    "EM",           \
+    "FTM",          \
+    "GIM",          \
+    "GMM",          \
+    "GUEST_CONTROL", \
+    "GUEST_DND",    \
+    "GUI",          \
+    "GVMM",         \
+    "HGCM",         \
+    "HGSMI",        \
+    "HM",           \
+    "IEM",          \
+    "IOM",          \
+    "IPC",          \
+    "LWIP",            \
+    "LWIP_API_LIB",    \
+    "LWIP_API_MSG",    \
+    "LWIP_ETHARP",     \
+    "LWIP_ICMP",       \
+    "LWIP_IGMP",       \
+    "LWIP_INET",       \
+    "LWIP_IP4",        \
+    "LWIP_IP4_REASS",  \
+    "LWIP_IP6",        \
+    "LWIP_MEM",        \
+    "LWIP_MEMP",       \
+    "LWIP_NETIF",      \
+    "LWIP_PBUF",       \
+    "LWIP_RAW",        \
+    "LWIP_SOCKETS",    \
+    "LWIP_SYS",        \
+    "LWIP_TCP",        \
+    "LWIP_TCPIP",      \
+    "LWIP_TCP_CWND",   \
+    "LWIP_TCP_FR",     \
+    "LWIP_TCP_INPUT",  \
+    "LWIP_TCP_OUTPUT", \
+    "LWIP_TCP_QLEN",   \
+    "LWIP_TCP_RST",    \
+    "LWIP_TCP_RTO",    \
+    "LWIP_TCP_WND",    \
+    "LWIP_TIMERS",     \
+    "LWIP_UDP",        \
+    "MAIN",         \
+    "MAIN_ADDITIONSFACILITY", \
+    "MAIN_ADDITIONSSTATECHANGEDEVENT", \
+    "MAIN_APPLIANCE", \
+    "MAIN_AUDIOADAPTER", \
+    "MAIN_BANDWIDTHCONTROL", \
+    "MAIN_BANDWIDTHGROUP", \
+    "MAIN_BANDWIDTHGROUPCHANGEDEVENT", \
+    "MAIN_BIOSSETTINGS", \
+    "MAIN_CANSHOWWINDOWEVENT", \
+    "MAIN_CLIPBOARDMODECHANGEDEVENT", \
+    "MAIN_CONSOLE", \
+    "MAIN_CPUCHANGEDEVENT", \
+    "MAIN_CPUEXECUTIONCAPCHANGEDEVENT", \
+    "MAIN_DHCPSERVER", \
+    "MAIN_DIRECTORY", \
+    "MAIN_DISPLAY", \
+    "MAIN_DISPLAYSOURCEBITMAP", \
+    "MAIN_DNDBASE", \
+    "MAIN_DNDMODECHANGEDEVENT", \
+    "MAIN_DNDSOURCE", \
+    "MAIN_DNDTARGET", \
+    "MAIN_EMULATEDUSB",   \
+    "MAIN_EVENT",   \
+    "MAIN_EVENTLISTENER", \
+    "MAIN_EVENTSOURCE", \
+    "MAIN_EVENTSOURCECHANGEDEVENT", \
+    "MAIN_EXTPACK", \
+    "MAIN_EXTPACKBASE", \
+    "MAIN_EXTPACKFILE", \
+    "MAIN_EXTPACKMANAGER", \
+    "MAIN_EXTPACKPLUGIN", \
+    "MAIN_EXTRADATACANCHANGEEVENT", \
+    "MAIN_EXTRADATACHANGEDEVENT", \
+    "MAIN_FILE",    \
+    "MAIN_FRAMEBUFFER", \
+    "MAIN_FRAMEBUFFEROVERLAY", \
+    "MAIN_FSOBJINFO", \
+    "MAIN_GUEST",   \
+    "MAIN_GUESTDIRECTORY", \
+    "MAIN_GUESTDNDSOURCE", \
+    "MAIN_GUESTDNDTARGET", \
+    "MAIN_GUESTERRORINFO", \
+    "MAIN_GUESTFILE", \
+    "MAIN_GUESTFILEEVENT", \
+    "MAIN_GUESTFILEIOEVENT", \
+    "MAIN_GUESTFILEOFFSETCHANGEDEVENT", \
+    "MAIN_GUESTFILEREADEVENT", \
+    "MAIN_GUESTFILEREGISTEREDEVENT", \
+    "MAIN_GUESTFILESTATECHANGEDEVENT", \
+    "MAIN_GUESTFILEWRITEEVENT", \
+    "MAIN_GUESTFSOBJINFO", \
+    "MAIN_GUESTKEYBOARDEVENT", \
+    "MAIN_GUESTMONITORCHANGEDEVENT", \
+    "MAIN_GUESTMOUSEEVENT", \
+    "MAIN_GUESTMULTITOUCHEVENT", \
+    "MAIN_GUESTOSTYPE", \
+    "MAIN_GUESTPROCESS", \
+    "MAIN_GUESTPROCESSEVENT", \
+    "MAIN_GUESTPROCESSINPUTNOTIFYEVENT", \
+    "MAIN_GUESTPROCESSIOEVENT", \
+    "MAIN_GUESTPROCESSOUTPUTEVENT", \
+    "MAIN_GUESTPROCESSREGISTEREDEVENT", \
+    "MAIN_GUESTPROCESSSTATECHANGEDEVENT", \
+    "MAIN_GUESTPROPERTYCHANGEDEVENT", \
+    "MAIN_GUESTSESSION", \
+    "MAIN_GUESTSESSIONEVENT", \
+    "MAIN_GUESTSESSIONREGISTEREDEVENT", \
+    "MAIN_GUESTSESSIONSTATECHANGEDEVENT", \
+    "MAIN_GUESTUSERSTATECHANGEDEVENT", \
+    "MAIN_HOST", \
+    "MAIN_HOSTNAMERESOLUTIONCONFIGURATIONCHANGEEVENT", \
+    "MAIN_HOSTNETWORKINTERFACE", \
+    "MAIN_HOSTPCIDEVICEPLUGEVENT", \
+    "MAIN_HOSTUSBDEVICE", \
+    "MAIN_HOSTUSBDEVICEFILTER", \
+    "MAIN_HOSTVIDEOINPUTDEVICE", \
+    "MAIN_INTERNALMACHINECONTROL", \
+    "MAIN_INTERNALSESSIONCONTROL", \
+    "MAIN_KEYBOARD", \
+    "MAIN_KEYBOARDLEDSCHANGEDEVENT", \
+    "MAIN_MACHINE", \
+    "MAIN_MACHINEDATACHANGEDEVENT", \
+    "MAIN_MACHINEDEBUGGER", \
+    "MAIN_MACHINEEVENT", \
+    "MAIN_MACHINEREGISTEREDEVENT", \
+    "MAIN_MACHINESTATECHANGEDEVENT", \
+    "MAIN_MEDIUM",  \
+    "MAIN_MEDIUMATTACHMENT", \
+    "MAIN_MEDIUMCHANGEDEVENT", \
+    "MAIN_MEDIUMCONFIGCHANGEDEVENT", \
+    "MAIN_MEDIUMFORMAT", \
+    "MAIN_MEDIUMREGISTEREDEVENT", \
+    "MAIN_MOUSE",   \
+    "MAIN_MOUSECAPABILITYCHANGEDEVENT", \
+    "MAIN_MOUSEPOINTERSHAPE", \
+    "MAIN_MOUSEPOINTERSHAPECHANGEDEVENT", \
+    "MAIN_NATENGINE", \
+    "MAIN_NATNETWORK", \
+    "MAIN_NATNETWORKALTEREVENT", \
+    "MAIN_NATNETWORKCHANGEDEVENT", \
+    "MAIN_NATNETWORKCREATIONDELETIONEVENT", \
+    "MAIN_NATNETWORKPORTFORWARDEVENT", \
+    "MAIN_NATNETWORKSETTINGEVENT", \
+    "MAIN_NATNETWORKSTARTSTOPEVENT", \
+    "MAIN_NATREDIRECTEVENT", \
+    "MAIN_NETWORKADAPTER", \
+    "MAIN_NETWORKADAPTERCHANGEDEVENT", \
+    "MAIN_PARALLELPORT", \
+    "MAIN_PARALLELPORTCHANGEDEVENT", \
+    "MAIN_PCIADDRESS", \
+    "MAIN_PCIDEVICEATTACHMENT", \
+    "MAIN_PERFORMANCECOLLECTOR", \
+    "MAIN_PERFORMANCEMETRIC", \
+    "MAIN_PROCESS", \
+    "MAIN_PROGRESS", \
+    "MAIN_REUSABLEEVENT", \
+    "MAIN_RUNTIMEERROREVENT", \
+    "MAIN_SERIALPORT", \
+    "MAIN_SERIALPORTCHANGEDEVENT", \
+    "MAIN_SESSION", \
+    "MAIN_SESSIONSTATECHANGEDEVENT", \
+    "MAIN_SHAREDFOLDER", \
+    "MAIN_SHAREDFOLDERCHANGEDEVENT", \
+    "MAIN_SHOWWINDOWEVENT", \
+    "MAIN_SNAPSHOT", \
+    "MAIN_SNAPSHOTCHANGEDEVENT", \
+    "MAIN_SNAPSHOTDELETEDEVENT", \
+    "MAIN_SNAPSHOTEVENT", \
+    "MAIN_SNAPSHOTRESTOREDEVENT", \
+    "MAIN_SNAPSHOTTAKENEVENT", \
+    "MAIN_STATECHANGEDEVENT", \
+    "MAIN_STORAGECONTROLLER", \
+    "MAIN_STORAGECONTROLLERCHANGEDEVENT", \
+    "MAIN_STORAGEDEVICECHANGEDEVENT", \
+    "MAIN_SYSTEMPROPERTIES", \
+    "MAIN_TOKEN", \
+    "MAIN_USBCONTROLLER", \
+    "MAIN_USBCONTROLLERCHANGEDEVENT", \
+    "MAIN_USBDEVICE", \
+    "MAIN_USBDEVICEFILTER", \
+    "MAIN_USBDEVICEFILTERS", \
+    "MAIN_USBDEVICESTATECHANGEDEVENT", \
+    "MAIN_VBOXSVCAVAILABILITYCHANGEDEVENT", \
+    "MAIN_VETOEVENT", \
+    "MAIN_VFSEXPLORER", \
+    "MAIN_VIDEOCAPTURECHANGEDEVENT", \
+    "MAIN_VIRTUALBOX", \
+    "MAIN_VIRTUALBOXCLIENT", \
+    "MAIN_VIRTUALSYSTEMDESCRIPTION", \
+    "MAIN_VRDESERVER", \
+    "MAIN_VRDESERVERCHANGEDEVENT", \
+    "MAIN_VRDESERVERINFO", \
+    "MAIN_VRDESERVERINFOCHANGEDEVENT", \
+    "MISC",         \
+    "MM",           \
+    "MM_HEAP",      \
+    "MM_HYPER",     \
+    "MM_HYPER_HEAP",\
+    "MM_PHYS",      \
+    "MM_POOL",      \
+    "NAT_SERVICE",  \
+    "NET_ADP_DRV",  \
+    "NET_FLT_DRV",  \
+    "NET_SERVICE",  \
+    "NET_SHAPER",   \
+    "PATM",         \
+    "PDM",          \
+    "PDM_ASYNC_COMPLETION", \
+    "PDM_BLK_CACHE", \
+    "PDM_DEVICE",   \
+    "PDM_DRIVER",   \
+    "PDM_LDR",      \
+    "PDM_QUEUE",    \
+    "PGM",          \
+    "PGM_DYNMAP",   \
+    "PGM_PHYS",     \
+    "PGM_PHYS_ACCESS",\
+    "PGM_POOL",     \
+    "PGM_SHARED",   \
+    "REM",          \
+    "REM_DISAS",    \
+    "REM_HANDLER",  \
+    "REM_IOPORT",   \
+    "REM_MMIO",     \
+    "REM_PRINTF",   \
+    "REM_RUN",      \
+    "SELM",         \
+    "SHARED_CLIPBOARD",\
+    "SHARED_CROPENGL",\
+    "SHARED_FOLDERS",\
+    "SHARED_OPENGL",\
+    "SRV_INTNET",   \
+    "SSM",          \
+    "STAM",         \
+    "SUP",          \
+    "SUP_DRV",      \
+    "TM",           \
+    "TRPM",         \
+    "USB_CARDREADER",\
+    "USB_DRV",      \
+    "USB_FILTER",   \
+    "USB_KBD",      \
+    "USB_MOUSE",    \
+    "USB_MSD",      \
+    "USB_REMOTE",   \
+    "USB_WEBCAM",   \
+    "VGDRV",        \
+    "VBGL",         \
+    "VD",           \
+    "VD_DMG",       \
+    "VD_ISCSI",     \
+    "VD_PARALLELS", \
+    "VD_QCOW",      \
+    "VD_QED",       \
+    "VD_RAW",       \
+    "VD_VDI",       \
+    "VD_VHD",       \
+    "VD_VHDX",      \
+    "VD_VMDK",      \
+    "VM",           \
+    "VMM",          \
+    "VRDE",         \
+    "VRDP",         \
+    "VSCSI",        \
+    "WEBSERVICE",   \
+}
+
+/** @} */
+#endif
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/include/VBox/ostypes.h
@@ -0,0 +1,166 @@
+/** @file
+ * VirtualBox - Global Guest Operating System definition.
+ */
+
+/*
+ * Copyright (C) 2006-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+#ifndef ___VBox_ostypes_h
+#define ___VBox_ostypes_h
+
+#include <iprt/cdefs.h>
+
+RT_C_DECLS_BEGIN
+
+/**
+ * Global list of guest operating system types.
+ *
+ * They are grouped into families. A family identifer is always has
+ * mod 0x10000 == 0. New entries can be added, however other components
+ * depend on the values (e.g. the Qt GUI and guest additions) so the
+ * existing values MUST stay the same.
+ *
+ * Note: distinguish between 32 & 64 bits guest OSes by checking bit 8 (mod 0x100)
+ */
+typedef enum VBOXOSTYPE
+{
+    VBOXOSTYPE_Unknown          = 0,
+    VBOXOSTYPE_Unknown_x64      = 0x00100,
+    VBOXOSTYPE_DOS              = 0x10000,
+    VBOXOSTYPE_Win31            = 0x15000,
+    VBOXOSTYPE_Win9x            = 0x20000,
+    VBOXOSTYPE_Win95            = 0x21000,
+    VBOXOSTYPE_Win98            = 0x22000,
+    VBOXOSTYPE_WinMe            = 0x23000,
+    VBOXOSTYPE_WinNT            = 0x30000,
+    VBOXOSTYPE_WinNT_x64        = 0x30100,
+    VBOXOSTYPE_WinNT4           = 0x31000,
+    VBOXOSTYPE_Win2k            = 0x32000,
+    VBOXOSTYPE_WinXP            = 0x33000,
+    VBOXOSTYPE_WinXP_x64        = 0x33100,
+    VBOXOSTYPE_Win2k3           = 0x34000,
+    VBOXOSTYPE_Win2k3_x64       = 0x34100,
+    VBOXOSTYPE_WinVista         = 0x35000,
+    VBOXOSTYPE_WinVista_x64     = 0x35100,
+    VBOXOSTYPE_Win2k8           = 0x36000,
+    VBOXOSTYPE_Win2k8_x64       = 0x36100,
+    VBOXOSTYPE_Win7             = 0x37000,
+    VBOXOSTYPE_Win7_x64         = 0x37100,
+    VBOXOSTYPE_Win8             = 0x38000,
+    VBOXOSTYPE_Win8_x64         = 0x38100,
+    VBOXOSTYPE_Win2k12_x64      = 0x39100,
+    VBOXOSTYPE_Win81            = 0x3A000,
+    VBOXOSTYPE_Win81_x64        = 0x3A100,
+    VBOXOSTYPE_Win10            = 0x3B000,
+    VBOXOSTYPE_Win10_x64        = 0x3B100,
+    VBOXOSTYPE_OS2              = 0x40000,
+    VBOXOSTYPE_OS2Warp3         = 0x41000,
+    VBOXOSTYPE_OS2Warp4         = 0x42000,
+    VBOXOSTYPE_OS2Warp45        = 0x43000,
+    VBOXOSTYPE_ECS              = 0x44000,
+    VBOXOSTYPE_OS21x            = 0x48000,
+    VBOXOSTYPE_Linux            = 0x50000,
+    VBOXOSTYPE_Linux_x64        = 0x50100,
+    VBOXOSTYPE_Linux22          = 0x51000,
+    VBOXOSTYPE_Linux24          = 0x52000,
+    VBOXOSTYPE_Linux24_x64      = 0x52100,
+    VBOXOSTYPE_Linux26          = 0x53000,
+    VBOXOSTYPE_Linux26_x64      = 0x53100,
+    VBOXOSTYPE_ArchLinux        = 0x54000,
+    VBOXOSTYPE_ArchLinux_x64    = 0x54100,
+    VBOXOSTYPE_Debian           = 0x55000,
+    VBOXOSTYPE_Debian_x64       = 0x55100,
+    VBOXOSTYPE_OpenSUSE         = 0x56000,
+    VBOXOSTYPE_OpenSUSE_x64     = 0x56100,
+    VBOXOSTYPE_FedoraCore       = 0x57000,
+    VBOXOSTYPE_FedoraCore_x64   = 0x57100,
+    VBOXOSTYPE_Gentoo           = 0x58000,
+    VBOXOSTYPE_Gentoo_x64       = 0x58100,
+    VBOXOSTYPE_Mandriva         = 0x59000,
+    VBOXOSTYPE_Mandriva_x64     = 0x59100,
+    VBOXOSTYPE_RedHat           = 0x5A000,
+    VBOXOSTYPE_RedHat_x64       = 0x5A100,
+    VBOXOSTYPE_Turbolinux       = 0x5B000,
+    VBOXOSTYPE_Turbolinux_x64   = 0x5B100,
+    VBOXOSTYPE_Ubuntu           = 0x5C000,
+    VBOXOSTYPE_Ubuntu_x64       = 0x5C100,
+    VBOXOSTYPE_Xandros          = 0x5D000,
+    VBOXOSTYPE_Xandros_x64      = 0x5D100,
+    VBOXOSTYPE_Oracle           = 0x5E000,
+    VBOXOSTYPE_Oracle_x64       = 0x5E100,
+    VBOXOSTYPE_FreeBSD          = 0x60000,
+    VBOXOSTYPE_FreeBSD_x64      = 0x60100,
+    VBOXOSTYPE_OpenBSD          = 0x61000,
+    VBOXOSTYPE_OpenBSD_x64      = 0x61100,
+    VBOXOSTYPE_NetBSD           = 0x62000,
+    VBOXOSTYPE_NetBSD_x64       = 0x62100,
+    VBOXOSTYPE_Netware          = 0x70000,
+    VBOXOSTYPE_Solaris          = 0x80000,
+    VBOXOSTYPE_Solaris_x64      = 0x80100,
+    VBOXOSTYPE_OpenSolaris      = 0x81000,
+    VBOXOSTYPE_OpenSolaris_x64  = 0x81100,
+    VBOXOSTYPE_Solaris11_x64    = 0x82100,
+    VBOXOSTYPE_L4               = 0x90000,
+    VBOXOSTYPE_QNX              = 0xA0000,
+    VBOXOSTYPE_MacOS            = 0xB0000,
+    VBOXOSTYPE_MacOS_x64        = 0xB0100,
+    VBOXOSTYPE_MacOS106         = 0xB2000,
+    VBOXOSTYPE_MacOS106_x64     = 0xB2100,
+    VBOXOSTYPE_MacOS107_x64     = 0xB3100,
+    VBOXOSTYPE_MacOS108_x64     = 0xB4100,
+    VBOXOSTYPE_MacOS109_x64     = 0xB5100,
+    VBOXOSTYPE_MacOS1010_x64    = 0xB6100,
+    VBOXOSTYPE_MacOS1011_x64    = 0xB7100,
+    VBOXOSTYPE_JRockitVE        = 0xC0000,
+    VBOXOSTYPE_Haiku            = 0xD0000,
+    VBOXOSTYPE_Haiku_x64        = 0xD0100,
+/** The bit number which indicates 64-bit or 32-bit. */
+#define VBOXOSTYPE_x64_BIT       8
+    /** The mask which indicates 64-bit. */
+    VBOXOSTYPE_x64            = 1 << VBOXOSTYPE_x64_BIT,
+    /** The usual 32-bit hack. */
+    VBOXOSTYPE_32BIT_HACK = 0x7fffffff
+} VBOXOSTYPE;
+
+
+/**
+ * Global list of guest OS families.
+ */
+typedef enum VBOXOSFAMILY
+{
+    VBOXOSFAMILY_Unknown          = 0,
+    VBOXOSFAMILY_Windows32        = 1,
+    VBOXOSFAMILY_Windows64        = 2,
+    VBOXOSFAMILY_Linux32          = 3,
+    VBOXOSFAMILY_Linux64          = 4,
+    VBOXOSFAMILY_FreeBSD32        = 5,
+    VBOXOSFAMILY_FreeBSD64        = 6,
+    VBOXOSFAMILY_Solaris32        = 7,
+    VBOXOSFAMILY_Solaris64        = 8,
+    VBOXOSFAMILY_MacOSX32         = 9,
+    VBOXOSFAMILY_MacOSX64         = 10,
+    /** The usual 32-bit hack. */
+    VBOXOSFAMILY_32BIT_HACK = 0x7fffffff
+} VBOXOSFAMILY;
+
+RT_C_DECLS_END
+
+#endif
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/include/VBox/param.h
@@ -0,0 +1,175 @@
+/** @file
+ * VirtualBox Parameter Definitions. (VMM,+)
+ *
+ * param.mac is generated from this file by running 'kmk incs' in the root.
+ */
+
+/*
+ * Copyright (C) 2006-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+#ifndef ___VBox_param_h
+#define ___VBox_param_h
+
+#include <iprt/param.h>
+#include <iprt/cdefs.h>
+
+
+/** @defgroup   grp_vbox_param  VBox Parameter Definition
+ * @{
+ */
+
+/** The maximum number of pages that can be allocated and mapped
+ * by various MM, PGM and SUP APIs. */
+#define VBOX_MAX_ALLOC_PAGE_COUNT   (256U * _1M / PAGE_SIZE)
+
+/** @def VBOX_WITH_PAGE_SHARING
+ * Enables the page sharing code.
+ * @remarks This must match GMMR0Init; currently we only support page fusion on
+ *          all 64-bit hosts except Mac OS X */
+#if (   HC_ARCH_BITS == 64          /* ASM-NOINC */ \
+     && (defined(RT_OS_FREEBSD) || defined(RT_OS_LINUX) || defined(RT_OS_SOLARIS) || defined(RT_OS_WINDOWS)) ) /* ASM-NOINC */ \
+ || defined(DOXYGEN_RUNNING)        /* ASM-NOINC */
+# define VBOX_WITH_PAGE_SHARING     /* ASM-NOINC */
+#endif                              /* ASM-NOINC */
+
+
+/** @defgroup   grp_vbox_param_mm  Memory Monitor Parameters
+ * @{
+ */
+/** Initial address of Hypervisor Memory Area.
+ * MUST BE PAGE TABLE ALIGNED! */
+#define MM_HYPER_AREA_ADDRESS       UINT32_C(0xa0000000)
+
+/** The max size of the hypervisor memory area. */
+#define MM_HYPER_AREA_MAX_SIZE      (40U * _1M) /**< @todo Readjust when floating RAMRANGEs have been implemented. Used to be 20 * _1MB */
+
+/** Maximum number of bytes we can dynamically map into the hypervisor region.
+ * This must be a power of 2 number of pages!
+ */
+#define MM_HYPER_DYNAMIC_SIZE       (16U * PAGE_SIZE)
+
+/** The minimum guest RAM size in bytes. */
+#define MM_RAM_MIN                  UINT32_C(0x00400000)
+/** The maximum guest RAM size in bytes. */
+#if HC_ARCH_BITS == 64
+# define MM_RAM_MAX                 UINT64_C(0x20000000000)
+#else
+# define MM_RAM_MAX                 UINT64_C(0x000E0000000)
+#endif
+/** The minimum guest RAM size in MBs. */
+#define MM_RAM_MIN_IN_MB            UINT32_C(4)
+/** The maximum guest RAM size in MBs. */
+#if HC_ARCH_BITS == 64
+# define MM_RAM_MAX_IN_MB           UINT32_C(2097152)
+#else
+# define MM_RAM_MAX_IN_MB           UINT32_C(3584)
+#endif
+/** The default size of the below 4GB RAM hole. */
+#define MM_RAM_HOLE_SIZE_DEFAULT    (512U * _1M)
+/** @} */
+
+
+/** @defgroup   grp_vbox_param_pgm  Page Manager Parameters
+ * @{
+ */
+/** The number of handy pages.
+ * This should be a power of two. */
+#define PGM_HANDY_PAGES             128
+/** The threshold at which allocation of more handy pages is flagged. */
+#define PGM_HANDY_PAGES_SET_FF      32
+/** The threshold at which we will allocate more when in ring-3.
+ * This is must be smaller than both PGM_HANDY_PAGES_SET_FF and
+ * PGM_HANDY_PAGES_MIN. */
+#define PGM_HANDY_PAGES_R3_ALLOC    8
+/** The threshold at which we will allocate more when in ring-0 or raw mode.
+ * The idea is that we should never go below this threshold while in ring-0 or
+ * raw mode because of PGM_HANDY_PAGES_RZ_TO_R3. However, should this happen and
+ * we are actually out of memory, we will have 8 page to get out of whatever
+ * code we're executing.
+ *
+ * This is must be smaller than both PGM_HANDY_PAGES_SET_FF and
+ * PGM_HANDY_PAGES_MIN. */
+#define PGM_HANDY_PAGES_RZ_ALLOC    8
+/** The threshold at which we force return to R3 ASAP.
+ * The idea is that this should be large enough to get out of any code and up to
+ * the main EM loop when we are out of memory.
+ * This must be less or equal to PGM_HANDY_PAGES_MIN. */
+#define PGM_HANDY_PAGES_RZ_TO_R3    24
+/** The minimum number of handy pages (after allocation).
+ * This must be greater or equal to PGM_HANDY_PAGES_SET_FF.
+ * Another name would be PGM_HANDY_PAGES_EXTRA_RESERVATION or _PARANOIA. :-) */
+#define PGM_HANDY_PAGES_MIN         32
+/** @} */
+
+
+/** @defgroup   grp_vbox_param_vmm  VMM Parameters
+ * @{
+ */
+/** VMM stack size. */
+#ifdef RT_OS_DARWIN
+# define VMM_STACK_SIZE             16384U
+#else
+# define VMM_STACK_SIZE             8192U
+#endif
+/** Min number of Virtual CPUs. */
+#define VMM_MIN_CPU_COUNT           1
+/** Max number of Virtual CPUs. */
+#define VMM_MAX_CPU_COUNT           64
+
+/** @} */
+
+
+/** @defgroup   grp_vbox_pci        PCI Identifiers
+ * @{ */
+/** VirtualBox PCI vendor ID. */
+#define VBOX_PCI_VENDORID           (0x80ee)
+
+/** @name VirtualBox graphics card identifiers
+ * @{ */
+#define VBOX_VENDORID               VBOX_PCI_VENDORID   /**< @todo wonderful choice of name! Please squeeze a _VGA_ or something in there, please. */
+#define VBOX_DEVICEID               (0xbeef)            /**< @todo ditto. */
+#define VBOX_VESA_VENDORID          VBOX_PCI_VENDORID
+#define VBOX_VESA_DEVICEID          (0xbeef)
+/** @} */
+
+/** @name VMMDev PCI card identifiers
+ * @{ */
+#define VMMDEV_VENDORID             VBOX_PCI_VENDORID
+#define VMMDEV_DEVICEID             (0xcafe)
+/** @} */
+
+/** @} */
+
+
+/** @defgroup grp_vbox_param_misc  Misc
+ * @{ */
+
+/** The maximum size of a generic segment offload (GSO) frame.  This limit is
+ *  imposed by the 16-bit frame size in internal networking header. */
+#define VBOX_MAX_GSO_SIZE           0xfff0
+
+/** @} */
+
+
+/** @} */
+
+#endif
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/include/VBox/shflsvc.h
@@ -0,0 +1,1423 @@
+/** @file
+ * Shared Folders: Common header for host service and guest clients.
+ */
+
+/*
+ * Copyright (C) 2006-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+#ifndef ___VBox_shflsvc_h
+#define ___VBox_shflsvc_h
+
+#include <VBox/types.h>
+#include <VBox/VBoxGuest2.h>
+#include <VBox/VMMDev.h>
+#include <VBox/hgcmsvc.h>
+#include <iprt/fs.h>
+
+
+/** @name Some bit flag manipulation macros.
+ * @{  */
+#ifndef BIT_FLAG
+#define BIT_FLAG(__Field,__Flag)       ((__Field) & (__Flag))
+#endif
+
+#ifndef BIT_FLAG_SET
+#define BIT_FLAG_SET(__Field,__Flag)   ((__Field) |= (__Flag))
+#endif
+
+#ifndef BIT_FLAG_CLEAR
+#define BIT_FLAG_CLEAR(__Field,__Flag) ((__Field) &= ~(__Flag))
+#endif
+/** @} */
+
+
+/**
+ * Structures shared between guest and the service
+ * can be relocated and use offsets to point to variable
+ * length parts.
+ */
+
+/**
+ * Shared folders protocol works with handles.
+ * Before doing any action on a file system object,
+ * one have to obtain the object handle via a SHFL_FN_CREATE
+ * request. A handle must be closed with SHFL_FN_CLOSE.
+ */
+
+/** Shared Folders service functions. (guest)
+ *  @{
+ */
+
+/** Query mappings changes. */
+#define SHFL_FN_QUERY_MAPPINGS      (1)
+/** Query mappings changes. */
+#define SHFL_FN_QUERY_MAP_NAME      (2)
+/** Open/create object. */
+#define SHFL_FN_CREATE              (3)
+/** Close object handle. */
+#define SHFL_FN_CLOSE               (4)
+/** Read object content. */
+#define SHFL_FN_READ                (5)
+/** Write new object content. */
+#define SHFL_FN_WRITE               (6)
+/** Lock/unlock a range in the object. */
+#define SHFL_FN_LOCK                (7)
+/** List object content. */
+#define SHFL_FN_LIST                (8)
+/** Query/set object information. */
+#define SHFL_FN_INFORMATION         (9)
+/** Remove object */
+#define SHFL_FN_REMOVE              (11)
+/** Map folder (legacy) */
+#define SHFL_FN_MAP_FOLDER_OLD      (12)
+/** Unmap folder */
+#define SHFL_FN_UNMAP_FOLDER        (13)
+/** Rename object (possibly moving it to another directory) */
+#define SHFL_FN_RENAME              (14)
+/** Flush file */
+#define SHFL_FN_FLUSH               (15)
+/** @todo macl, a description, please. */
+#define SHFL_FN_SET_UTF8            (16)
+/** Map folder */
+#define SHFL_FN_MAP_FOLDER          (17)
+/** Read symlink destination (as of VBox 4.0) */
+#define SHFL_FN_READLINK            (18)
+/** Create symlink (as of VBox 4.0) */
+#define SHFL_FN_SYMLINK             (19)
+/** Ask host to show symlinks (as of VBox 4.0) */
+#define SHFL_FN_SET_SYMLINKS        (20)
+
+/** @} */
+
+/** Shared Folders service functions. (host)
+ *  @{
+ */
+
+/** Add shared folder mapping. */
+#define SHFL_FN_ADD_MAPPING         (1)
+/** Remove shared folder mapping. */
+#define SHFL_FN_REMOVE_MAPPING      (2)
+/** Set the led status light address. */
+#define SHFL_FN_SET_STATUS_LED      (3)
+/** Allow the guest to create symbolic links (as of VBox 4.0) */
+#define SHFL_FN_ALLOW_SYMLINKS_CREATE (4)
+/** @} */
+
+/** Root handle for a mapping. Root handles are unique.
+ *  @note
+ *  Function parameters structures consider
+ *  the root handle as 32 bit value. If the typedef
+ *  will be changed, then function parameters must be
+ *  changed accordingly. All those parameters are marked
+ *  with SHFLROOT in comments.
+ */
+typedef uint32_t SHFLROOT;
+
+#define SHFL_ROOT_NIL ((SHFLROOT)~0)
+
+
+/** A shared folders handle for an opened object. */
+typedef uint64_t SHFLHANDLE;
+
+#define SHFL_HANDLE_NIL  ((SHFLHANDLE)~0LL)
+#define SHFL_HANDLE_ROOT ((SHFLHANDLE)0LL)
+
+/** Hardcoded maximum length (in chars) of a shared folder name. */
+#define SHFL_MAX_LEN         (256)
+/** Hardcoded maximum number of shared folder mapping available to the guest. */
+#define SHFL_MAX_MAPPINGS    (64)
+
+/** @name Shared Folders strings. They can be either UTF-8 or UTF-16.
+ * @{
+ */
+
+/**
+ * Shared folder string buffer structure.
+ */
+#pragma pack(1)
+typedef struct _SHFLSTRING
+{
+    /** Allocated size of the String member in bytes. */
+    uint16_t u16Size;
+
+    /** Length of string without trailing nul in bytes. */
+    uint16_t u16Length;
+
+    /** UTF-8 or UTF-16 string. Nul terminated. */
+    union
+    {
+        uint8_t  utf8[1];
+        uint16_t ucs2[1];
+    } String;
+} SHFLSTRING;
+#pragma pack()
+
+#define SHFLSTRING_HEADER_SIZE RT_UOFFSETOF(SHFLSTRING, String)
+
+/** Pointer to a shared folder string buffer. */
+typedef SHFLSTRING *PSHFLSTRING;
+/** Pointer to a const shared folder string buffer. */
+typedef const SHFLSTRING *PCSHFLSTRING;
+
+/** Calculate size of the string. */
+DECLINLINE(uint32_t) ShflStringSizeOfBuffer(PCSHFLSTRING pString)
+{
+    return pString ? sizeof(SHFLSTRING) - sizeof(pString->String) + pString->u16Size : 0;
+}
+
+DECLINLINE(uint32_t) ShflStringLength(PCSHFLSTRING pString)
+{
+    return pString ? pString->u16Length : 0;
+}
+
+DECLINLINE(PSHFLSTRING) ShflStringInitBuffer(void *pvBuffer, uint32_t u32Size)
+{
+    PSHFLSTRING pString = NULL;
+    const uint32_t u32HeaderSize = SHFLSTRING_HEADER_SIZE;
+
+    /*
+     * Check that the buffer size is big enough to hold a zero sized string
+     * and is not too big to fit into 16 bit variables.
+     */
+    if (u32Size >= u32HeaderSize && u32Size - u32HeaderSize <= 0xFFFF)
+    {
+        pString = (PSHFLSTRING)pvBuffer;
+        pString->u16Size = u32Size - u32HeaderSize;
+        pString->u16Length = 0;
+        if (pString->u16Size >= sizeof(pString->String.ucs2[0]))
+            pString->String.ucs2[0] = 0;
+        else if (pString->u16Size >= sizeof(pString->String.utf8[0]))
+            pString->String.utf8[0] = 0;
+    }
+
+    return pString;
+}
+
+/**
+ * Validates a HGCM string output parameter.
+ *
+ * @returns true if valid, false if not.
+ *
+ * @param   pString     The string buffer pointer.
+ * @param   cbBuf       The buffer size from the parameter.
+ */
+DECLINLINE(bool) ShflStringIsValidOut(PCSHFLSTRING pString, uint32_t cbBuf)
+{
+    if (RT_LIKELY(cbBuf > RT_UOFFSETOF(SHFLSTRING, String)))
+        if (RT_LIKELY((uint32_t)pString->u16Size + RT_UOFFSETOF(SHFLSTRING, String) <= cbBuf))
+            if (RT_LIKELY(pString->u16Length < pString->u16Size))
+                return true;
+    return false;
+}
+
+/**
+ * Validates a HGCM string input parameter.
+ *
+ * @returns true if valid, false if not.
+ *
+ * @param   pString     The string buffer pointer.
+ * @param   cbBuf       The buffer size from the parameter.
+ * @param   fUtf8Not16  Set if UTF-8 encoding, clear if UTF-16 encoding.
+ */
+DECLINLINE(bool) ShflStringIsValidIn(PCSHFLSTRING pString, uint32_t cbBuf, bool fUtf8Not16)
+{
+    int rc;
+    if (RT_LIKELY(cbBuf > RT_UOFFSETOF(SHFLSTRING, String)))
+    {
+        if (RT_LIKELY((uint32_t)pString->u16Size + RT_UOFFSETOF(SHFLSTRING, String) <= cbBuf))
+        {
+            if (fUtf8Not16)
+            {
+                /* UTF-8: */
+                if (RT_LIKELY(pString->u16Length < pString->u16Size))
+                {
+                    rc = RTStrValidateEncodingEx((const char *)&pString->String.utf8[0], pString->u16Length + 1,
+                                                 RTSTR_VALIDATE_ENCODING_EXACT_LENGTH | RTSTR_VALIDATE_ENCODING_ZERO_TERMINATED);
+                    if (RT_SUCCESS(rc))
+                        return true;
+                }
+            }
+            else
+            {
+                /* UTF-16: */
+                if (RT_LIKELY(!(pString->u16Length & 1)))
+                {
+                    if (RT_LIKELY((uint32_t)sizeof(RTUTF16) + pString->u16Length <= pString->u16Size))
+                    {
+                        rc = RTUtf16ValidateEncodingEx(&pString->String.ucs2[0], pString->u16Length / 2 + 1,
+                                                       RTSTR_VALIDATE_ENCODING_EXACT_LENGTH
+                                                       | RTSTR_VALIDATE_ENCODING_ZERO_TERMINATED);
+                        if (RT_SUCCESS(rc))
+                            return true;
+                    }
+                }
+            }
+        }
+    }
+    return false;
+}
+
+/**
+ * Validates an optional HGCM string input parameter.
+ *
+ * @returns true if valid, false if not.
+ *
+ * @param   pString     The string buffer pointer. Can be NULL.
+ * @param   cbBuf       The buffer size from the parameter.
+ * @param   fUtf8Not16  Set if UTF-8 encoding, clear if UTF-16 encoding.
+ */
+DECLINLINE(bool) ShflStringIsValidOrNullIn(PCSHFLSTRING pString, uint32_t cbBuf, bool fUtf8Not16)
+{
+    if (pString)
+        return ShflStringIsValidIn(pString, cbBuf, fUtf8Not16);
+    if (RT_LIKELY(cbBuf == 0))
+        return true;
+    return false;
+}
+
+/** @} */
+
+
+/**
+ * The available additional information in a SHFLFSOBJATTR object.
+ */
+typedef enum SHFLFSOBJATTRADD
+{
+    /** No additional information is available / requested. */
+    SHFLFSOBJATTRADD_NOTHING = 1,
+    /** The additional unix attributes (SHFLFSOBJATTR::u::Unix) are
+     *  available / requested. */
+    SHFLFSOBJATTRADD_UNIX,
+    /** The additional extended attribute size (SHFLFSOBJATTR::u::EASize) is
+     *  available / requested. */
+    SHFLFSOBJATTRADD_EASIZE,
+    /** The last valid item (inclusive).
+     * The valid range is SHFLFSOBJATTRADD_NOTHING thru
+     * SHFLFSOBJATTRADD_LAST. */
+    SHFLFSOBJATTRADD_LAST = SHFLFSOBJATTRADD_EASIZE,
+
+    /** The usual 32-bit hack. */
+    SHFLFSOBJATTRADD_32BIT_SIZE_HACK = 0x7fffffff
+} SHFLFSOBJATTRADD;
+
+
+/* Assert sizes of the IRPT types we're using below. */
+AssertCompileSize(RTFMODE,      4);
+AssertCompileSize(RTFOFF,       8);
+AssertCompileSize(RTINODE,      8);
+AssertCompileSize(RTTIMESPEC,   8);
+AssertCompileSize(RTDEV,        4);
+AssertCompileSize(RTUID,        4);
+
+/**
+ * Shared folder filesystem object attributes.
+ */
+#pragma pack(1)
+typedef struct SHFLFSOBJATTR
+{
+    /** Mode flags (st_mode). RTFS_UNIX_*, RTFS_TYPE_*, and RTFS_DOS_*.
+     * @remarks We depend on a number of RTFS_ defines to remain unchanged.
+     *          Fortuntately, these are depending on windows, dos and unix
+     *          standard values, so this shouldn't be much of a pain. */
+    RTFMODE         fMode;
+
+    /** The additional attributes available. */
+    SHFLFSOBJATTRADD  enmAdditional;
+
+    /**
+     * Additional attributes.
+     *
+     * Unless explicitly specified to an API, the API can provide additional
+     * data as it is provided by the underlying OS.
+     */
+    union SHFLFSOBJATTRUNION
+    {
+        /** Additional Unix Attributes
+         * These are available when SHFLFSOBJATTRADD is set in fUnix.
+         */
+         struct SHFLFSOBJATTRUNIX
+         {
+            /** The user owning the filesystem object (st_uid).
+             * This field is ~0U if not supported. */
+            RTUID           uid;
+
+            /** The group the filesystem object is assigned (st_gid).
+             * This field is ~0U if not supported. */
+            RTGID           gid;
+
+            /** Number of hard links to this filesystem object (st_nlink).
+             * This field is 1 if the filesystem doesn't support hardlinking or
+             * the information isn't available.
+             */
+            uint32_t        cHardlinks;
+
+            /** The device number of the device which this filesystem object resides on (st_dev).
+             * This field is 0 if this information is not available. */
+            RTDEV           INodeIdDevice;
+
+            /** The unique identifier (within the filesystem) of this filesystem object (st_ino).
+             * Together with INodeIdDevice, this field can be used as a OS wide unique id
+             * when both their values are not 0.
+             * This field is 0 if the information is not available. */
+            RTINODE         INodeId;
+
+            /** User flags (st_flags).
+             * This field is 0 if this information is not available. */
+            uint32_t        fFlags;
+
+            /** The current generation number (st_gen).
+             * This field is 0 if this information is not available. */
+            uint32_t        GenerationId;
+
+            /** The device number of a character or block device type object (st_rdev).
+             * This field is 0 if the file isn't of a character or block device type and
+             * when the OS doesn't subscribe to the major+minor device idenfication scheme. */
+            RTDEV           Device;
+        } Unix;
+
+        /**
+         * Extended attribute size.
+         */
+        struct SHFLFSOBJATTREASIZE
+        {
+            /** Size of EAs. */
+            RTFOFF          cb;
+        } EASize;
+    } u;
+} SHFLFSOBJATTR;
+#pragma pack()
+AssertCompileSize(SHFLFSOBJATTR, 44);
+/** Pointer to a shared folder filesystem object attributes structure. */
+typedef SHFLFSOBJATTR *PSHFLFSOBJATTR;
+/** Pointer to a const shared folder filesystem object attributes structure. */
+typedef const SHFLFSOBJATTR *PCSHFLFSOBJATTR;
+
+
+/**
+ * Filesystem object information structure.
+ */
+#pragma pack(1)
+typedef struct SHFLFSOBJINFO
+{
+   /** Logical size (st_size).
+    * For normal files this is the size of the file.
+    * For symbolic links, this is the length of the path name contained
+    * in the symbolic link.
+    * For other objects this fields needs to be specified.
+    */
+   RTFOFF       cbObject;
+
+   /** Disk allocation size (st_blocks * DEV_BSIZE). */
+   RTFOFF       cbAllocated;
+
+   /** Time of last access (st_atime).
+    * @remarks  Here (and other places) we depend on the IPRT timespec to
+    *           remain unchanged. */
+   RTTIMESPEC   AccessTime;
+
+   /** Time of last data modification (st_mtime). */
+   RTTIMESPEC   ModificationTime;
+
+   /** Time of last status change (st_ctime).
+    * If not available this is set to ModificationTime.
+    */
+   RTTIMESPEC   ChangeTime;
+
+   /** Time of file birth (st_birthtime).
+    * If not available this is set to ChangeTime.
+    */
+   RTTIMESPEC   BirthTime;
+
+   /** Attributes. */
+   SHFLFSOBJATTR Attr;
+
+} SHFLFSOBJINFO;
+#pragma pack()
+AssertCompileSize(SHFLFSOBJINFO, 92);
+/** Pointer to a shared folder filesystem object information structure. */
+typedef SHFLFSOBJINFO *PSHFLFSOBJINFO;
+/** Pointer to a const shared folder filesystem object information
+ *  structure. */
+typedef const SHFLFSOBJINFO *PCSHFLFSOBJINFO;
+
+
+/**
+ * Copy file system objinfo from IPRT to shared folder format.
+ *
+ * @param   pDst                The shared folder structure.
+ * @param   pSrc                The IPRT structure.
+ */
+DECLINLINE(void) vbfsCopyFsObjInfoFromIprt(PSHFLFSOBJINFO pDst, PCRTFSOBJINFO pSrc)
+{
+    pDst->cbObject          = pSrc->cbObject;
+    pDst->cbAllocated       = pSrc->cbAllocated;
+    pDst->AccessTime        = pSrc->AccessTime;
+    pDst->ModificationTime  = pSrc->ModificationTime;
+    pDst->ChangeTime        = pSrc->ChangeTime;
+    pDst->BirthTime         = pSrc->BirthTime;
+    pDst->Attr.fMode        = pSrc->Attr.fMode;
+    RT_ZERO(pDst->Attr.u);
+    switch (pSrc->Attr.enmAdditional)
+    {
+        default:
+        case RTFSOBJATTRADD_NOTHING:
+            pDst->Attr.enmAdditional        = SHFLFSOBJATTRADD_NOTHING;
+            break;
+
+        case RTFSOBJATTRADD_UNIX:
+            pDst->Attr.enmAdditional        = SHFLFSOBJATTRADD_UNIX;
+            pDst->Attr.u.Unix.uid           = pSrc->Attr.u.Unix.uid;
+            pDst->Attr.u.Unix.gid           = pSrc->Attr.u.Unix.gid;
+            pDst->Attr.u.Unix.cHardlinks    = pSrc->Attr.u.Unix.cHardlinks;
+            pDst->Attr.u.Unix.INodeIdDevice = pSrc->Attr.u.Unix.INodeIdDevice;
+            pDst->Attr.u.Unix.INodeId       = pSrc->Attr.u.Unix.INodeId;
+            pDst->Attr.u.Unix.fFlags        = pSrc->Attr.u.Unix.fFlags;
+            pDst->Attr.u.Unix.GenerationId  = pSrc->Attr.u.Unix.GenerationId;
+            pDst->Attr.u.Unix.Device        = pSrc->Attr.u.Unix.Device;
+            break;
+
+        case RTFSOBJATTRADD_EASIZE:
+            pDst->Attr.enmAdditional        = SHFLFSOBJATTRADD_EASIZE;
+            pDst->Attr.u.EASize.cb          = pSrc->Attr.u.EASize.cb;
+            break;
+    }
+}
+
+
+/** Result of an open/create request.
+ *  Along with handle value the result code
+ *  identifies what has happened while
+ *  trying to open the object.
+ */
+typedef enum _SHFLCREATERESULT
+{
+    SHFL_NO_RESULT,
+    /** Specified path does not exist. */
+    SHFL_PATH_NOT_FOUND,
+    /** Path to file exists, but the last component does not. */
+    SHFL_FILE_NOT_FOUND,
+    /** File already exists and either has been opened or not. */
+    SHFL_FILE_EXISTS,
+    /** New file was created. */
+    SHFL_FILE_CREATED,
+    /** Existing file was replaced or overwritten. */
+    SHFL_FILE_REPLACED
+} SHFLCREATERESULT;
+
+
+/** Open/create flags.
+ *  @{
+ */
+
+/** No flags. Initialization value. */
+#define SHFL_CF_NONE                  (0x00000000)
+
+/** Lookup only the object, do not return a handle. All other flags are ignored. */
+#define SHFL_CF_LOOKUP                (0x00000001)
+
+/** Open parent directory of specified object.
+ *  Useful for the corresponding Windows FSD flag
+ *  and for opening paths like \\dir\\*.* to search the 'dir'.
+ *  @todo possibly not needed???
+ */
+#define SHFL_CF_OPEN_TARGET_DIRECTORY (0x00000002)
+
+/** Create/open a directory. */
+#define SHFL_CF_DIRECTORY             (0x00000004)
+
+/** Open/create action to do if object exists
+ *  and if the object does not exists.
+ *  REPLACE file means atomically DELETE and CREATE.
+ *  OVERWRITE file means truncating the file to 0 and
+ *  setting new size.
+ *  When opening an existing directory REPLACE and OVERWRITE
+ *  actions are considered invalid, and cause returning
+ *  FILE_EXISTS with NIL handle.
+ */
+#define SHFL_CF_ACT_MASK_IF_EXISTS      (0x000000F0)
+#define SHFL_CF_ACT_MASK_IF_NEW         (0x00000F00)
+
+/** What to do if object exists. */
+#define SHFL_CF_ACT_OPEN_IF_EXISTS      (0x00000000)
+#define SHFL_CF_ACT_FAIL_IF_EXISTS      (0x00000010)
+#define SHFL_CF_ACT_REPLACE_IF_EXISTS   (0x00000020)
+#define SHFL_CF_ACT_OVERWRITE_IF_EXISTS (0x00000030)
+
+/** What to do if object does not exist. */
+#define SHFL_CF_ACT_CREATE_IF_NEW       (0x00000000)
+#define SHFL_CF_ACT_FAIL_IF_NEW         (0x00000100)
+
+/** Read/write requested access for the object. */
+#define SHFL_CF_ACCESS_MASK_RW          (0x00003000)
+
+/** No access requested. */
+#define SHFL_CF_ACCESS_NONE             (0x00000000)
+/** Read access requested. */
+#define SHFL_CF_ACCESS_READ             (0x00001000)
+/** Write access requested. */
+#define SHFL_CF_ACCESS_WRITE            (0x00002000)
+/** Read/Write access requested. */
+#define SHFL_CF_ACCESS_READWRITE        (SHFL_CF_ACCESS_READ | SHFL_CF_ACCESS_WRITE)
+
+/** Requested share access for the object. */
+#define SHFL_CF_ACCESS_MASK_DENY        (0x0000C000)
+
+/** Allow any access. */
+#define SHFL_CF_ACCESS_DENYNONE         (0x00000000)
+/** Do not allow read. */
+#define SHFL_CF_ACCESS_DENYREAD         (0x00004000)
+/** Do not allow write. */
+#define SHFL_CF_ACCESS_DENYWRITE        (0x00008000)
+/** Do not allow access. */
+#define SHFL_CF_ACCESS_DENYALL          (SHFL_CF_ACCESS_DENYREAD | SHFL_CF_ACCESS_DENYWRITE)
+
+/** Requested access to attributes of the object. */
+#define SHFL_CF_ACCESS_MASK_ATTR        (0x00030000)
+
+/** No access requested. */
+#define SHFL_CF_ACCESS_ATTR_NONE        (0x00000000)
+/** Read access requested. */
+#define SHFL_CF_ACCESS_ATTR_READ        (0x00010000)
+/** Write access requested. */
+#define SHFL_CF_ACCESS_ATTR_WRITE       (0x00020000)
+/** Read/Write access requested. */
+#define SHFL_CF_ACCESS_ATTR_READWRITE   (SHFL_CF_ACCESS_ATTR_READ | SHFL_CF_ACCESS_ATTR_WRITE)
+
+/** The file is opened in append mode. Ignored if SHFL_CF_ACCESS_WRITE is not set. */
+#define SHFL_CF_ACCESS_APPEND           (0x00040000)
+
+/** @} */
+
+#pragma pack(1)
+typedef struct _SHFLCREATEPARMS
+{
+    /* Returned handle of opened object. */
+    SHFLHANDLE Handle;
+
+    /* Returned result of the operation */
+    SHFLCREATERESULT Result;
+
+    /* SHFL_CF_* */
+    uint32_t CreateFlags;
+
+    /* Attributes of object to create and
+     * returned actual attributes of opened/created object.
+     */
+    SHFLFSOBJINFO Info;
+
+} SHFLCREATEPARMS;
+#pragma pack()
+
+typedef SHFLCREATEPARMS *PSHFLCREATEPARMS;
+
+
+/** Shared Folders mappings.
+ *  @{
+ */
+
+/** The mapping has been added since last query. */
+#define SHFL_MS_NEW        (1)
+/** The mapping has been deleted since last query. */
+#define SHFL_MS_DELETED    (2)
+
+typedef struct _SHFLMAPPING
+{
+    /** Mapping status. */
+    uint32_t u32Status;
+    /** Root handle. */
+    SHFLROOT root;
+} SHFLMAPPING;
+/** Pointer to a SHFLMAPPING structure. */
+typedef SHFLMAPPING *PSHFLMAPPING;
+
+/** @} */
+
+/** Shared Folder directory information
+ *  @{
+ */
+
+typedef struct _SHFLDIRINFO
+{
+    /** Full information about the object. */
+    SHFLFSOBJINFO   Info;
+    /** The length of the short field (number of RTUTF16 chars).
+     * It is 16-bit for reasons of alignment. */
+    uint16_t        cucShortName;
+    /** The short name for 8.3 compatibility.
+     * Empty string if not available.
+     */
+    RTUTF16         uszShortName[14];
+    /** @todo malc, a description, please. */
+    SHFLSTRING      name;
+} SHFLDIRINFO, *PSHFLDIRINFO;
+
+
+/**
+ * Shared folder filesystem properties.
+ */
+typedef struct SHFLFSPROPERTIES
+{
+    /** The maximum size of a filesystem object name.
+     * This does not include the '\\0'. */
+    uint32_t cbMaxComponent;
+
+    /** True if the filesystem is remote.
+     * False if the filesystem is local. */
+    bool    fRemote;
+
+    /** True if the filesystem is case sensitive.
+     * False if the filesystem is case insensitive. */
+    bool    fCaseSensitive;
+
+    /** True if the filesystem is mounted read only.
+     * False if the filesystem is mounted read write. */
+    bool    fReadOnly;
+
+    /** True if the filesystem can encode unicode object names.
+     * False if it can't. */
+    bool    fSupportsUnicode;
+
+    /** True if the filesystem is compresses.
+     * False if it isn't or we don't know. */
+    bool    fCompressed;
+
+    /** True if the filesystem compresses of individual files.
+     * False if it doesn't or we don't know. */
+    bool    fFileCompression;
+
+    /** @todo more? */
+} SHFLFSPROPERTIES;
+AssertCompileSize(SHFLFSPROPERTIES, 12);
+/** Pointer to a shared folder filesystem properties structure. */
+typedef SHFLFSPROPERTIES *PSHFLFSPROPERTIES;
+/** Pointer to a const shared folder filesystem properties structure. */
+typedef SHFLFSPROPERTIES const *PCSHFLFSPROPERTIES;
+
+
+/**
+ * Copy file system properties from IPRT to shared folder format.
+ *
+ * @param   pDst                The shared folder structure.
+ * @param   pSrc                The IPRT structure.
+ */
+DECLINLINE(void) vbfsCopyFsPropertiesFromIprt(PSHFLFSPROPERTIES pDst, PCRTFSPROPERTIES pSrc)
+{
+    RT_ZERO(*pDst);                     /* zap the implicit padding. */
+    pDst->cbMaxComponent   = pSrc->cbMaxComponent;
+    pDst->fRemote          = pSrc->fRemote;
+    pDst->fCaseSensitive   = pSrc->fCaseSensitive;
+    pDst->fReadOnly        = pSrc->fReadOnly;
+    pDst->fSupportsUnicode = pSrc->fSupportsUnicode;
+    pDst->fCompressed      = pSrc->fCompressed;
+    pDst->fFileCompression = pSrc->fFileCompression;
+}
+
+
+typedef struct _SHFLVOLINFO
+{
+    RTFOFF         ullTotalAllocationBytes;
+    RTFOFF         ullAvailableAllocationBytes;
+    uint32_t       ulBytesPerAllocationUnit;
+    uint32_t       ulBytesPerSector;
+    uint32_t       ulSerial;
+    SHFLFSPROPERTIES fsProperties;
+} SHFLVOLINFO, *PSHFLVOLINFO;
+
+/** @} */
+
+/** Function parameter structures.
+ *  @{
+ */
+
+/**
+ * SHFL_FN_QUERY_MAPPINGS
+ */
+/** Validation mask.  Needs to be adjusted
+  * whenever a new SHFL_MF_ flag is added. */
+#define SHFL_MF_MASK       (0x00000011)
+/** UC2 enconded strings. */
+#define SHFL_MF_UCS2       (0x00000000)
+/** Guest uses UTF8 strings, if not set then the strings are unicode (UCS2). */
+#define SHFL_MF_UTF8       (0x00000001)
+/** Just handle the auto-mounted folders. */
+#define SHFL_MF_AUTOMOUNT  (0x00000010)
+
+/** Type of guest system. For future system dependent features. */
+#define SHFL_MF_SYSTEM_MASK    (0x0000FF00)
+#define SHFL_MF_SYSTEM_NONE    (0x00000000)
+#define SHFL_MF_SYSTEM_WINDOWS (0x00000100)
+#define SHFL_MF_SYSTEM_LINUX   (0x00000200)
+
+/** Parameters structure. */
+typedef struct _VBoxSFQueryMappings
+{
+    VBoxGuestHGCMCallInfo callInfo;
+
+    /** 32bit, in:
+     * Flags describing various client needs.
+     */
+    HGCMFunctionParameter flags;
+
+    /** 32bit, in/out:
+     * Number of mappings the client expects.
+     * This is the number of elements in the
+     * mappings array.
+     */
+    HGCMFunctionParameter numberOfMappings;
+
+    /** pointer, in/out:
+     * Points to array of SHFLMAPPING structures.
+     */
+    HGCMFunctionParameter mappings;
+
+} VBoxSFQueryMappings;
+
+/** Number of parameters */
+#define SHFL_CPARMS_QUERY_MAPPINGS (3)
+
+
+
+/**
+ * SHFL_FN_QUERY_MAP_NAME
+ */
+
+/** Parameters structure. */
+typedef struct _VBoxSFQueryMapName
+{
+    VBoxGuestHGCMCallInfo callInfo;
+
+    /** 32bit, in: SHFLROOT
+     * Root handle of the mapping which name is queried.
+     */
+    HGCMFunctionParameter root;
+
+    /** pointer, in/out:
+     * Points to SHFLSTRING buffer.
+     */
+    HGCMFunctionParameter name;
+
+} VBoxSFQueryMapName;
+
+/** Number of parameters */
+#define SHFL_CPARMS_QUERY_MAP_NAME (2)
+
+/**
+ * SHFL_FN_MAP_FOLDER_OLD
+ */
+
+/** Parameters structure. */
+typedef struct _VBoxSFMapFolder_Old
+{
+    VBoxGuestHGCMCallInfo callInfo;
+
+    /** pointer, in:
+     * Points to SHFLSTRING buffer.
+     */
+    HGCMFunctionParameter path;
+
+    /** pointer, out: SHFLROOT
+     * Root handle of the mapping which name is queried.
+     */
+    HGCMFunctionParameter root;
+
+    /** pointer, in: RTUTF16
+     * Path delimiter
+     */
+    HGCMFunctionParameter delimiter;
+
+} VBoxSFMapFolder_Old;
+
+/** Number of parameters */
+#define SHFL_CPARMS_MAP_FOLDER_OLD (3)
+
+/**
+ * SHFL_FN_MAP_FOLDER
+ */
+
+/** Parameters structure. */
+typedef struct _VBoxSFMapFolder
+{
+    VBoxGuestHGCMCallInfo callInfo;
+
+    /** pointer, in:
+     * Points to SHFLSTRING buffer.
+     */
+    HGCMFunctionParameter path;
+
+    /** pointer, out: SHFLROOT
+     * Root handle of the mapping which name is queried.
+     */
+    HGCMFunctionParameter root;
+
+    /** pointer, in: RTUTF16
+     * Path delimiter
+     */
+    HGCMFunctionParameter delimiter;
+
+    /** pointer, in: SHFLROOT
+     * Case senstive flag
+     */
+    HGCMFunctionParameter fCaseSensitive;
+
+} VBoxSFMapFolder;
+
+/** Number of parameters */
+#define SHFL_CPARMS_MAP_FOLDER (4)
+
+/**
+ * SHFL_FN_UNMAP_FOLDER
+ */
+
+/** Parameters structure. */
+typedef struct _VBoxSFUnmapFolder
+{
+    VBoxGuestHGCMCallInfo callInfo;
+
+    /** pointer, in: SHFLROOT
+     * Root handle of the mapping which name is queried.
+     */
+    HGCMFunctionParameter root;
+
+} VBoxSFUnmapFolder;
+
+/** Number of parameters */
+#define SHFL_CPARMS_UNMAP_FOLDER (1)
+
+
+/**
+ * SHFL_FN_CREATE
+ */
+
+/** Parameters structure. */
+typedef struct _VBoxSFCreate
+{
+    VBoxGuestHGCMCallInfo callInfo;
+
+    /** pointer, in: SHFLROOT
+     * Root handle of the mapping which name is queried.
+     */
+    HGCMFunctionParameter root;
+
+    /** pointer, in:
+     * Points to SHFLSTRING buffer.
+     */
+    HGCMFunctionParameter path;
+
+    /** pointer, in/out:
+     * Points to SHFLCREATEPARMS buffer.
+     */
+    HGCMFunctionParameter parms;
+
+} VBoxSFCreate;
+
+/** Number of parameters */
+#define SHFL_CPARMS_CREATE (3)
+
+
+/**
+ * SHFL_FN_CLOSE
+ */
+
+/** Parameters structure. */
+typedef struct _VBoxSFClose
+{
+    VBoxGuestHGCMCallInfo callInfo;
+
+    /** pointer, in: SHFLROOT
+     * Root handle of the mapping which name is queried.
+     */
+    HGCMFunctionParameter root;
+
+
+    /** value64, in:
+     * SHFLHANDLE of object to close.
+     */
+    HGCMFunctionParameter handle;
+
+} VBoxSFClose;
+
+/** Number of parameters */
+#define SHFL_CPARMS_CLOSE (2)
+
+
+/**
+ * SHFL_FN_READ
+ */
+
+/** Parameters structure. */
+typedef struct _VBoxSFRead
+{
+    VBoxGuestHGCMCallInfo callInfo;
+
+    /** pointer, in: SHFLROOT
+     * Root handle of the mapping which name is queried.
+     */
+    HGCMFunctionParameter root;
+
+    /** value64, in:
+     * SHFLHANDLE of object to read from.
+     */
+    HGCMFunctionParameter handle;
+
+    /** value64, in:
+     * Offset to read from.
+     */
+    HGCMFunctionParameter offset;
+
+    /** value64, in/out:
+     * Bytes to read/How many were read.
+     */
+    HGCMFunctionParameter cb;
+
+    /** pointer, out:
+     * Buffer to place data to.
+     */
+    HGCMFunctionParameter buffer;
+
+} VBoxSFRead;
+
+/** Number of parameters */
+#define SHFL_CPARMS_READ (5)
+
+
+
+/**
+ * SHFL_FN_WRITE
+ */
+
+/** Parameters structure. */
+typedef struct _VBoxSFWrite
+{
+    VBoxGuestHGCMCallInfo callInfo;
+
+    /** pointer, in: SHFLROOT
+     * Root handle of the mapping which name is queried.
+     */
+    HGCMFunctionParameter root;
+
+    /** value64, in:
+     * SHFLHANDLE of object to write to.
+     */
+    HGCMFunctionParameter handle;
+
+    /** value64, in:
+     * Offset to write to.
+     */
+    HGCMFunctionParameter offset;
+
+    /** value64, in/out:
+     * Bytes to write/How many were written.
+     */
+    HGCMFunctionParameter cb;
+
+    /** pointer, in:
+     * Data to write.
+     */
+    HGCMFunctionParameter buffer;
+
+} VBoxSFWrite;
+
+/** Number of parameters */
+#define SHFL_CPARMS_WRITE (5)
+
+
+
+/**
+ * SHFL_FN_LOCK
+ */
+
+/** Lock owner is the HGCM client. */
+
+/** Lock mode bit mask. */
+#define SHFL_LOCK_MODE_MASK  (0x3)
+/** Cancel lock on the given range. */
+#define SHFL_LOCK_CANCEL     (0x0)
+/** Acquire read only lock. Prevent write to the range. */
+#define SHFL_LOCK_SHARED     (0x1)
+/** Acquire write lock. Prevent both write and read to the range. */
+#define SHFL_LOCK_EXCLUSIVE  (0x2)
+
+/** Do not wait for lock if it can not be acquired at the time. */
+#define SHFL_LOCK_NOWAIT     (0x0)
+/** Wait and acquire lock. */
+#define SHFL_LOCK_WAIT       (0x4)
+
+/** Lock the specified range. */
+#define SHFL_LOCK_PARTIAL    (0x0)
+/** Lock entire object. */
+#define SHFL_LOCK_ENTIRE     (0x8)
+
+/** Parameters structure. */
+typedef struct _VBoxSFLock
+{
+    VBoxGuestHGCMCallInfo callInfo;
+
+    /** pointer, in: SHFLROOT
+     * Root handle of the mapping which name is queried.
+     */
+    HGCMFunctionParameter root;
+
+    /** value64, in:
+     * SHFLHANDLE of object to be locked.
+     */
+    HGCMFunctionParameter handle;
+
+    /** value64, in:
+     * Starting offset of lock range.
+     */
+    HGCMFunctionParameter offset;
+
+    /** value64, in:
+     * Length of range.
+     */
+    HGCMFunctionParameter length;
+
+    /** value32, in:
+     * Lock flags SHFL_LOCK_*.
+     */
+    HGCMFunctionParameter flags;
+
+} VBoxSFLock;
+
+/** Number of parameters */
+#define SHFL_CPARMS_LOCK (5)
+
+
+
+/**
+ * SHFL_FN_FLUSH
+ */
+
+/** Parameters structure. */
+typedef struct _VBoxSFFlush
+{
+    VBoxGuestHGCMCallInfo callInfo;
+
+    /** pointer, in: SHFLROOT
+     * Root handle of the mapping which name is queried.
+     */
+    HGCMFunctionParameter root;
+
+    /** value64, in:
+     * SHFLHANDLE of object to be locked.
+     */
+    HGCMFunctionParameter handle;
+
+} VBoxSFFlush;
+
+/** Number of parameters */
+#define SHFL_CPARMS_FLUSH (2)
+
+/**
+ * SHFL_FN_LIST
+ */
+
+/** Listing information includes variable length RTDIRENTRY[EX] structures. */
+
+/** @todo might be necessary for future. */
+#define SHFL_LIST_NONE          0
+#define SHFL_LIST_RETURN_ONE        1
+
+/** Parameters structure. */
+typedef struct _VBoxSFList
+{
+    VBoxGuestHGCMCallInfo callInfo;
+
+    /** pointer, in: SHFLROOT
+     * Root handle of the mapping which name is queried.
+     */
+    HGCMFunctionParameter root;
+
+    /** value64, in:
+     * SHFLHANDLE of object to be listed.
+     */
+    HGCMFunctionParameter handle;
+
+    /** value32, in:
+     * List flags SHFL_LIST_*.
+     */
+    HGCMFunctionParameter flags;
+
+    /** value32, in/out:
+     * Bytes to be used for listing information/How many bytes were used.
+     */
+    HGCMFunctionParameter cb;
+
+    /** pointer, in/optional
+     * Points to SHFLSTRING buffer that specifies a search path.
+     */
+    HGCMFunctionParameter path;
+
+    /** pointer, out:
+     * Buffer to place listing information to. (SHFLDIRINFO)
+     */
+    HGCMFunctionParameter buffer;
+
+    /** value32, in/out:
+     * Indicates a key where the listing must be resumed.
+     * in: 0 means start from begin of object.
+     * out: 0 means listing completed.
+     */
+    HGCMFunctionParameter resumePoint;
+
+    /** pointer, out:
+     * Number of files returned
+     */
+    HGCMFunctionParameter cFiles;
+
+} VBoxSFList;
+
+/** Number of parameters */
+#define SHFL_CPARMS_LIST (8)
+
+
+
+/**
+ * SHFL_FN_READLINK
+ */
+
+/** Parameters structure. */
+typedef struct _VBoxSFReadLink
+{
+    VBoxGuestHGCMCallInfo callInfo;
+
+    /** pointer, in: SHFLROOT
+     * Root handle of the mapping which name is queried.
+     */
+    HGCMFunctionParameter root;
+
+    /** pointer, in:
+     * Points to SHFLSTRING buffer.
+     */
+    HGCMFunctionParameter path;
+
+    /** pointer, out:
+     * Buffer to place data to.
+     */
+    HGCMFunctionParameter buffer;
+
+} VBoxSFReadLink;
+
+/** Number of parameters */
+#define SHFL_CPARMS_READLINK (3)
+
+
+
+/**
+ * SHFL_FN_INFORMATION
+ */
+
+/** Mask of Set/Get bit. */
+#define SHFL_INFO_MODE_MASK    (0x1)
+/** Get information */
+#define SHFL_INFO_GET          (0x0)
+/** Set information */
+#define SHFL_INFO_SET          (0x1)
+
+/** Get name of the object. */
+#define SHFL_INFO_NAME         (0x2)
+/** Set size of object (extend/trucate); only applies to file objects */
+#define SHFL_INFO_SIZE         (0x4)
+/** Get/Set file object info. */
+#define SHFL_INFO_FILE         (0x8)
+/** Get volume information. */
+#define SHFL_INFO_VOLUME       (0x10)
+
+/** @todo different file info structures */
+
+
+/** Parameters structure. */
+typedef struct _VBoxSFInformation
+{
+    VBoxGuestHGCMCallInfo callInfo;
+
+    /** pointer, in: SHFLROOT
+     * Root handle of the mapping which name is queried.
+     */
+    HGCMFunctionParameter root;
+
+    /** value64, in:
+     * SHFLHANDLE of object to be listed.
+     */
+    HGCMFunctionParameter handle;
+
+    /** value32, in:
+     * SHFL_INFO_*
+     */
+    HGCMFunctionParameter flags;
+
+    /** value32, in/out:
+     * Bytes to be used for information/How many bytes were used.
+     */
+    HGCMFunctionParameter cb;
+
+    /** pointer, in/out:
+     * Information to be set/get (SHFLFSOBJINFO or SHFLSTRING). Do not forget
+     * to set the SHFLFSOBJINFO::Attr::enmAdditional for Get operation as well.
+     */
+    HGCMFunctionParameter info;
+
+} VBoxSFInformation;
+
+/** Number of parameters */
+#define SHFL_CPARMS_INFORMATION (5)
+
+
+/**
+ * SHFL_FN_REMOVE
+ */
+
+#define SHFL_REMOVE_FILE        (0x1)
+#define SHFL_REMOVE_DIR         (0x2)
+#define SHFL_REMOVE_SYMLINK     (0x4)
+
+/** Parameters structure. */
+typedef struct _VBoxSFRemove
+{
+    VBoxGuestHGCMCallInfo callInfo;
+
+    /** pointer, in: SHFLROOT
+     * Root handle of the mapping which name is queried.
+     */
+    HGCMFunctionParameter root;
+
+    /** pointer, in:
+     * Points to SHFLSTRING buffer.
+     */
+    HGCMFunctionParameter path;
+
+    /** value32, in:
+     * remove flags (file/directory)
+     */
+    HGCMFunctionParameter flags;
+
+} VBoxSFRemove;
+
+#define SHFL_CPARMS_REMOVE  (3)
+
+
+/**
+ * SHFL_FN_RENAME
+ */
+
+#define SHFL_RENAME_FILE                (0x1)
+#define SHFL_RENAME_DIR                 (0x2)
+#define SHFL_RENAME_REPLACE_IF_EXISTS   (0x4)
+
+/** Parameters structure. */
+typedef struct _VBoxSFRename
+{
+    VBoxGuestHGCMCallInfo callInfo;
+
+    /** pointer, in: SHFLROOT
+     * Root handle of the mapping which name is queried.
+     */
+    HGCMFunctionParameter root;
+
+    /** pointer, in:
+     * Points to SHFLSTRING src.
+     */
+    HGCMFunctionParameter src;
+
+    /** pointer, in:
+     * Points to SHFLSTRING dest.
+     */
+    HGCMFunctionParameter dest;
+
+    /** value32, in:
+     * rename flags (file/directory)
+     */
+    HGCMFunctionParameter flags;
+
+} VBoxSFRename;
+
+#define SHFL_CPARMS_RENAME  (4)
+
+
+/**
+ * SHFL_FN_SYMLINK
+ */
+
+/** Parameters structure. */
+typedef struct _VBoxSFSymlink
+{
+    VBoxGuestHGCMCallInfo callInfo;
+
+    /** pointer, in: SHFLROOT
+     * Root handle of the mapping which name is queried.
+     */
+    HGCMFunctionParameter root;
+
+    /** pointer, in:
+     * Points to SHFLSTRING of path for the new symlink.
+     */
+    HGCMFunctionParameter newPath;
+
+    /** pointer, in:
+     * Points to SHFLSTRING of destination for symlink.
+     */
+    HGCMFunctionParameter oldPath;
+
+    /** pointer, out:
+     * Information about created symlink.
+     */
+    HGCMFunctionParameter info;
+
+} VBoxSFSymlink;
+
+#define SHFL_CPARMS_SYMLINK  (4)
+
+
+
+/**
+ * SHFL_FN_ADD_MAPPING
+ * Host call, no guest structure is used.
+ */
+
+/** mapping is writable */
+#define SHFL_ADD_MAPPING_F_WRITABLE         (RT_BIT_32(0))
+/** mapping is automounted by the guest */
+#define SHFL_ADD_MAPPING_F_AUTOMOUNT        (RT_BIT_32(1))
+/** allow the guest to create symlinks */
+#define SHFL_ADD_MAPPING_F_CREATE_SYMLINKS  (RT_BIT_32(2))
+/** mapping is actually missing on the host */
+#define SHFL_ADD_MAPPING_F_MISSING          (RT_BIT_32(3))
+
+#define SHFL_CPARMS_ADD_MAPPING  (3)
+
+/**
+ * SHFL_FN_REMOVE_MAPPING
+ * Host call, no guest structure is used.
+ */
+
+#define SHFL_CPARMS_REMOVE_MAPPING (1)
+
+
+/**
+ * SHFL_FN_SET_STATUS_LED
+ * Host call, no guest structure is used.
+ */
+
+#define SHFL_CPARMS_SET_STATUS_LED (1)
+
+/** @} */
+
+#endif
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/include/VBox/types.h
@@ -0,0 +1,1073 @@
+/** @file
+ * VirtualBox - Types.
+ */
+
+/*
+ * Copyright (C) 2006-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+#ifndef ___VBox_types_h
+#define ___VBox_types_h
+
+#include <VBox/cdefs.h>
+#include <iprt/types.h>
+
+
+/** @defgroup grp_types     VBox Basic Types
+ * @{
+ */
+
+
+/** @defgroup grp_types_both  Common Guest and Host Context Basic Types
+ * @{
+ */
+
+
+/** @defgroup grp_types_hc  Host Context Basic Types
+ * @{
+ */
+
+/** @} */
+
+
+/** @defgroup grp_types_gc  Guest Context Basic Types
+ * @{
+ */
+
+/** @} */
+
+
+/** Pointer to per support driver session data.
+ * (The data is a R0 entity and private to the the R0 SUP part. All
+ * other should consider this a sort of handle.) */
+typedef R0PTRTYPE(struct SUPDRVSESSION *)           PSUPDRVSESSION;
+
+/** Event semaphore handle. Ring-0 / ring-3. */
+typedef R0PTRTYPE(struct SUPSEMEVENTHANDLE *)       SUPSEMEVENT;
+/** Pointer to an event semaphore handle. */
+typedef SUPSEMEVENT                                *PSUPSEMEVENT;
+/** Nil event semaphore handle. */
+#define NIL_SUPSEMEVENT                             ((SUPSEMEVENT)0)
+
+/** Multiple release event semaphore handle. Ring-0 / ring-3. */
+typedef R0PTRTYPE(struct SUPSEMEVENTMULTIHANDLE *)  SUPSEMEVENTMULTI;
+/** Pointer to an multiple release event semaphore handle. */
+typedef SUPSEMEVENTMULTI                           *PSUPSEMEVENTMULTI;
+/** Nil multiple release event semaphore handle. */
+#define NIL_SUPSEMEVENTMULTI                        ((SUPSEMEVENTMULTI)0)
+
+
+/** Pointer to a VM. */
+typedef struct VM                  *PVM;
+/** Pointer to a VM - Ring-0 Ptr. */
+typedef R0PTRTYPE(struct VM *)      PVMR0;
+/** Pointer to a VM - Ring-3 Ptr. */
+typedef R3PTRTYPE(struct VM *)      PVMR3;
+/** Pointer to a VM - RC Ptr. */
+typedef RCPTRTYPE(struct VM *)      PVMRC;
+
+/** Pointer to a virtual CPU structure. */
+typedef struct VMCPU *              PVMCPU;
+/** Pointer to a virtual CPU structure - Ring-3 Ptr. */
+typedef R3PTRTYPE(struct VMCPU *)   PVMCPUR3;
+/** Pointer to a virtual CPU structure - Ring-0 Ptr. */
+typedef R0PTRTYPE(struct VMCPU *)   PVMCPUR0;
+/** Pointer to a virtual CPU structure - RC Ptr. */
+typedef RCPTRTYPE(struct VMCPU *)   PVMCPURC;
+
+/** Pointer to a ring-0 (global) VM structure. */
+typedef R0PTRTYPE(struct GVM *)     PGVM;
+
+/** Pointer to a ring-3 (user mode) VM structure. */
+typedef R3PTRTYPE(struct UVM *)     PUVM;
+
+/** Pointer to a ring-3 (user mode) VMCPU structure. */
+typedef R3PTRTYPE(struct UVMCPU *)  PUVMCPU;
+
+/** Virtual CPU ID. */
+typedef uint32_t                    VMCPUID;
+/** Pointer to a virtual CPU ID. */
+typedef VMCPUID                    *PVMCPUID;
+/** @name Special CPU ID values.
+ * Most of these are for request scheduling.
+ *
+ * @{ */
+/** All virtual CPUs. */
+#define VMCPUID_ALL         UINT32_C(0xfffffff2)
+/** All virtual CPUs, descending order. */
+#define VMCPUID_ALL_REVERSE UINT32_C(0xfffffff3)
+/** Any virtual CPU.
+ * Intended for scheduling a VM request or some other task. */
+#define VMCPUID_ANY         UINT32_C(0xfffffff4)
+/** Any virtual CPU; always queue for future execution.
+ * Intended for scheduling a VM request or some other task. */
+#define VMCPUID_ANY_QUEUE   UINT32_C(0xfffffff5)
+/** The NIL value. */
+#define NIL_VMCPUID         UINT32_C(0xfffffffd)
+/** @} */
+
+/**
+ * Virtual CPU set.
+ */
+typedef struct VMCPUSET
+{
+    /** The bitmap data.  */
+    uint32_t    au32Bitmap[8 /*256/32*/];
+} VMCPUSET;
+/** Pointer to a Virtual CPU set. */
+typedef VMCPUSET *PVMCPUSET;
+/** Pointer to a const Virtual CPU set. */
+typedef VMCPUSET const *PCVMCPUSET;
+
+
+/**
+ * VM State
+ */
+typedef enum VMSTATE
+{
+    /** The VM is being created. */
+    VMSTATE_CREATING = 0,
+    /** The VM is created. */
+    VMSTATE_CREATED,
+    /** The VM state is being loaded from file. */
+    VMSTATE_LOADING,
+    /** The VM is being powered on */
+    VMSTATE_POWERING_ON,
+    /** The VM is being resumed. */
+    VMSTATE_RESUMING,
+    /** The VM is runnning. */
+    VMSTATE_RUNNING,
+    /** Live save: The VM is running and the state is being saved. */
+    VMSTATE_RUNNING_LS,
+    /** Fault Tolerance: The VM is running and the state is being synced. */
+    VMSTATE_RUNNING_FT,
+    /** The VM is being reset. */
+    VMSTATE_RESETTING,
+    /** Live save: The VM is being reset and immediately suspended. */
+    VMSTATE_RESETTING_LS,
+    /** The VM is being suspended. */
+    VMSTATE_SUSPENDING,
+    /** Live save: The VM is being suspended during a live save operation, either as
+     * part of the normal flow or VMR3Reset. */
+    VMSTATE_SUSPENDING_LS,
+    /** Live save: The VM is being suspended by VMR3Suspend during live save. */
+    VMSTATE_SUSPENDING_EXT_LS,
+    /** The VM is suspended. */
+    VMSTATE_SUSPENDED,
+    /** Live save: The VM has been suspended and is waiting for the live save
+     * operation to move on. */
+    VMSTATE_SUSPENDED_LS,
+    /** Live save: The VM has been suspended by VMR3Suspend during a live save. */
+    VMSTATE_SUSPENDED_EXT_LS,
+    /** The VM is suspended and its state is being saved by EMT(0). (See SSM) */
+    VMSTATE_SAVING,
+    /** The VM is being debugged. (See DBGF.) */
+    VMSTATE_DEBUGGING,
+    /** Live save: The VM is being debugged while the live phase is going on. */
+    VMSTATE_DEBUGGING_LS,
+    /** The VM is being powered off. */
+    VMSTATE_POWERING_OFF,
+    /** Live save: The VM is being powered off and the save cancelled. */
+    VMSTATE_POWERING_OFF_LS,
+    /** The VM is switched off, awaiting destruction. */
+    VMSTATE_OFF,
+    /** Live save: Waiting for cancellation and transition to VMSTATE_OFF. */
+    VMSTATE_OFF_LS,
+    /** The VM is powered off because of a fatal error. */
+    VMSTATE_FATAL_ERROR,
+    /** Live save: Waiting for cancellation and transition to FatalError. */
+    VMSTATE_FATAL_ERROR_LS,
+    /** The VM is in guru meditation over a fatal failure. */
+    VMSTATE_GURU_MEDITATION,
+    /** Live save: Waiting for cancellation and transition to GuruMeditation. */
+    VMSTATE_GURU_MEDITATION_LS,
+    /** The VM is screwed because of a failed state loading. */
+    VMSTATE_LOAD_FAILURE,
+    /** The VM is being destroyed. */
+    VMSTATE_DESTROYING,
+    /** Terminated. */
+    VMSTATE_TERMINATED,
+    /** hack forcing the size of the enum to 32-bits. */
+    VMSTATE_MAKE_32BIT_HACK = 0x7fffffff
+} VMSTATE;
+
+/** @def VBOXSTRICTRC_STRICT_ENABLED
+ * Indicates that VBOXSTRICTRC is in strict mode.
+ */
+#if defined(__cplusplus) \
+ && ARCH_BITS == 64    /* cdecl requires classes and structs as hidden params. */ \
+ && !defined(_MSC_VER) /* trouble similar to 32-bit gcc. */ \
+ &&  (   defined(RT_STRICT) \
+      || defined(VBOX_STRICT) \
+      || defined(DEBUG) \
+      || defined(DOXYGEN_RUNNING) )
+# define VBOXSTRICTRC_STRICT_ENABLED 1
+#endif
+
+/** We need RTERR_STRICT_RC.  */
+#if defined(VBOXSTRICTRC_STRICT_ENABLED) && !defined(RTERR_STRICT_RC)
+# define RTERR_STRICT_RC 1
+#endif
+
+/**
+ * Strict VirtualBox status code.
+ *
+ * This is normally an 32-bit integer and the only purpose of the type is to
+ * highlight the special handling that is required.  But in strict build it is a
+ * class that causes compilation and runtime errors for some of the incorrect
+ * handling.
+ */
+#ifdef VBOXSTRICTRC_STRICT_ENABLED
+struct VBOXSTRICTRC
+{
+protected:
+    /** The status code. */
+    int32_t m_rc;
+
+public:
+    /** Default constructor setting the status to VERR_IPE_UNINITIALIZED_STATUS. */
+    VBOXSTRICTRC()
+#ifdef VERR_IPE_UNINITIALIZED_STATUS
+        : m_rc(VERR_IPE_UNINITIALIZED_STATUS)
+#else
+        : m_rc(-233 /*VERR_IPE_UNINITIALIZED_STATUS*/)
+#endif
+    {
+    }
+
+    /** Constructor for normal integer status codes. */
+    VBOXSTRICTRC(int32_t const rc)
+        : m_rc(rc)
+    {
+    }
+
+    /** Getter that VBOXSTRICTRC_VAL can use. */
+    int32_t getValue() const                        { return m_rc; }
+
+    /** @name Comparison operators
+     * @{ */
+    bool operator==(int32_t rc) const               { return m_rc == rc; }
+    bool operator!=(int32_t rc) const               { return m_rc != rc; }
+    bool operator<=(int32_t rc) const               { return m_rc <= rc; }
+    bool operator>=(int32_t rc) const               { return m_rc >= rc; }
+    bool operator<(int32_t rc) const                { return m_rc <  rc; }
+    bool operator>(int32_t rc) const                { return m_rc >  rc; }
+
+    bool operator==(const VBOXSTRICTRC &rRc) const  { return m_rc == rRc.m_rc; }
+    bool operator!=(const VBOXSTRICTRC &rRc) const  { return m_rc != rRc.m_rc; }
+    bool operator<=(const VBOXSTRICTRC &rRc) const  { return m_rc <= rRc.m_rc; }
+    bool operator>=(const VBOXSTRICTRC &rRc) const  { return m_rc >= rRc.m_rc; }
+    bool operator<(const VBOXSTRICTRC &rRc) const   { return m_rc <  rRc.m_rc; }
+    bool operator>(const VBOXSTRICTRC &rRc) const   { return m_rc >  rRc.m_rc; }
+    /** @} */
+
+    /** Special automatic cast for RT_SUCCESS_NP. */
+    operator RTErrStrictType2() const               { return RTErrStrictType2(m_rc); }
+
+private:
+    /** @name Constructors that will prevent some of the bad types.
+     * @{ */
+    VBOXSTRICTRC(uint8_t  rc) : m_rc(-999)          { NOREF(rc); }
+    VBOXSTRICTRC(uint16_t rc) : m_rc(-999)          { NOREF(rc); }
+    VBOXSTRICTRC(uint32_t rc) : m_rc(-999)          { NOREF(rc); }
+    VBOXSTRICTRC(uint64_t rc) : m_rc(-999)          { NOREF(rc); }
+
+    VBOXSTRICTRC(int8_t rc)   : m_rc(-999)          { NOREF(rc); }
+    VBOXSTRICTRC(int16_t rc)  : m_rc(-999)          { NOREF(rc); }
+    VBOXSTRICTRC(int64_t rc)  : m_rc(-999)          { NOREF(rc); }
+    /** @} */
+};
+# ifdef _MSC_VER
+#  pragma warning(disable:4190)
+# endif
+#else
+typedef int32_t VBOXSTRICTRC;
+#endif
+
+/** @def VBOXSTRICTRC_VAL
+ * Explicit getter.
+ * @param rcStrict  The strict VirtualBox status code.
+ */
+#ifdef VBOXSTRICTRC_STRICT_ENABLED
+# define VBOXSTRICTRC_VAL(rcStrict) ( (rcStrict).getValue() )
+#else
+# define VBOXSTRICTRC_VAL(rcStrict) (rcStrict)
+#endif
+
+/** @def VBOXSTRICTRC_TODO
+ * Returns that needs dealing with.
+ * @param rcStrict  The strict VirtualBox status code.
+ */
+#define VBOXSTRICTRC_TODO(rcStrict) VBOXSTRICTRC_VAL(rcStrict)
+
+
+/** Pointer to a PDM Base Interface. */
+typedef struct PDMIBASE *PPDMIBASE;
+/** Pointer to a pointer to a PDM Base Interface. */
+typedef PPDMIBASE *PPPDMIBASE;
+
+/** Pointer to a PDM Device Instance. */
+typedef struct PDMDEVINS *PPDMDEVINS;
+/** Pointer to a pointer to a PDM Device Instance. */
+typedef PPDMDEVINS *PPPDMDEVINS;
+/** R3 pointer to a PDM Device Instance. */
+typedef R3PTRTYPE(PPDMDEVINS) PPDMDEVINSR3;
+/** R0 pointer to a PDM Device Instance. */
+typedef R0PTRTYPE(PPDMDEVINS) PPDMDEVINSR0;
+/** RC pointer to a PDM Device Instance. */
+typedef RCPTRTYPE(PPDMDEVINS) PPDMDEVINSRC;
+
+/** Pointer to a PDM USB Device Instance. */
+typedef struct PDMUSBINS *PPDMUSBINS;
+/** Pointer to a pointer to a PDM USB Device Instance. */
+typedef PPDMUSBINS *PPPDMUSBINS;
+
+/** Pointer to a PDM Driver Instance. */
+typedef struct PDMDRVINS *PPDMDRVINS;
+/** Pointer to a pointer to a PDM Driver Instance. */
+typedef PPDMDRVINS *PPPDMDRVINS;
+/** R3 pointer to a PDM Driver Instance. */
+typedef R3PTRTYPE(PPDMDRVINS) PPDMDRVINSR3;
+/** R0 pointer to a PDM Driver Instance. */
+typedef R0PTRTYPE(PPDMDRVINS) PPDMDRVINSR0;
+/** RC pointer to a PDM Driver Instance. */
+typedef RCPTRTYPE(PPDMDRVINS) PPDMDRVINSRC;
+
+/** Pointer to a PDM Service Instance. */
+typedef struct PDMSRVINS *PPDMSRVINS;
+/** Pointer to a pointer to a PDM Service Instance. */
+typedef PPDMSRVINS *PPPDMSRVINS;
+
+/** Pointer to a PDM critical section. */
+typedef union PDMCRITSECT *PPDMCRITSECT;
+/** Pointer to a const PDM critical section. */
+typedef const union PDMCRITSECT *PCPDMCRITSECT;
+
+/** Pointer to a PDM read/write critical section. */
+typedef union PDMCRITSECTRW *PPDMCRITSECTRW;
+/** Pointer to a const PDM read/write critical section. */
+typedef union PDMCRITSECTRW const *PCPDMCRITSECTRW;
+
+/** R3 pointer to a timer. */
+typedef R3PTRTYPE(struct TMTIMER *) PTMTIMERR3;
+/** Pointer to a R3 pointer to a timer. */
+typedef PTMTIMERR3 *PPTMTIMERR3;
+
+/** R0 pointer to a timer. */
+typedef R0PTRTYPE(struct TMTIMER *) PTMTIMERR0;
+/** Pointer to a R3 pointer to a timer. */
+typedef PTMTIMERR0 *PPTMTIMERR0;
+
+/** RC pointer to a timer. */
+typedef RCPTRTYPE(struct TMTIMER *) PTMTIMERRC;
+/** Pointer to a RC pointer to a timer. */
+typedef PTMTIMERRC *PPTMTIMERRC;
+
+/** Pointer to a timer. */
+typedef CTX_SUFF(PTMTIMER)     PTMTIMER;
+/** Pointer to a pointer to a timer. */
+typedef PTMTIMER              *PPTMTIMER;
+
+/** SSM Operation handle. */
+typedef struct SSMHANDLE *PSSMHANDLE;
+/** Pointer to a const SSM stream method table. */
+typedef struct SSMSTRMOPS const *PCSSMSTRMOPS;
+
+/** Pointer to a CPUMCTX. */
+typedef struct CPUMCTX *PCPUMCTX;
+/** Pointer to a const CPUMCTX. */
+typedef const struct CPUMCTX *PCCPUMCTX;
+
+/** Pointer to a CPU context core. */
+typedef struct CPUMCTXCORE *PCPUMCTXCORE;
+/** Pointer to a const CPU context core. */
+typedef const struct CPUMCTXCORE *PCCPUMCTXCORE;
+
+/** Pointer to a selector register. */
+typedef struct CPUMSELREG *PCPUMSELREG;
+/** Pointer to a const selector register. */
+typedef const struct CPUMSELREG *PCCPUMSELREG;
+
+/** Pointer to selector hidden registers.
+ * @deprecated Replaced by PCPUMSELREG  */
+typedef struct CPUMSELREG *PCPUMSELREGHID;
+/** Pointer to const selector hidden registers.
+ * @deprecated Replaced by PCCPUMSELREG  */
+typedef const struct CPUMSELREG *PCCPUMSELREGHID;
+
+/** @} */
+
+
+/** @defgroup grp_types_idt     Interrupt Descriptor Table Entry.
+ * @todo This all belongs in x86.h!
+ * @{ */
+
+/** @todo VBOXIDT -> VBOXDESCIDT, skip the complex variations. We'll never use them. */
+
+/** IDT Entry, Task Gate view. */
+#pragma pack(1)                         /* paranoia */
+typedef struct VBOXIDTE_TASKGATE
+{
+    /** Reserved. */
+    unsigned    u16Reserved1 : 16;
+    /** Task Segment Selector. */
+    unsigned    u16TSS : 16;
+    /** More reserved. */
+    unsigned    u8Reserved2 : 8;
+    /** Fixed value bit 0 - Set to 1. */
+    unsigned    u1Fixed0 : 1;
+    /** Busy bit. */
+    unsigned    u1Busy : 1;
+    /** Fixed value bit 2 - Set to 1. */
+    unsigned    u1Fixed1 : 1;
+    /** Fixed value bit 3 - Set to 0. */
+    unsigned    u1Fixed2 : 1;
+    /** Fixed value bit 4 - Set to 0. */
+    unsigned    u1Fixed3 : 1;
+    /** Descriptor Privilege level. */
+    unsigned    u2DPL : 2;
+    /** Present flag. */
+    unsigned    u1Present : 1;
+    /** Reserved. */
+    unsigned    u16Reserved3 : 16;
+} VBOXIDTE_TASKGATE;
+#pragma pack()
+/** Pointer to IDT Entry, Task gate view. */
+typedef VBOXIDTE_TASKGATE *PVBOXIDTE_TASKGATE;
+
+
+/** IDT Entry, Intertupt gate view. */
+#pragma pack(1)                         /* paranoia */
+typedef struct VBOXIDTE_INTERRUPTGATE
+{
+    /** Low offset word. */
+    unsigned    u16OffsetLow : 16;
+    /** Segment Selector. */
+    unsigned    u16SegSel : 16;
+    /** Reserved. */
+    unsigned    u5Reserved2 : 5;
+    /** Fixed value bit 0 - Set to 0. */
+    unsigned    u1Fixed0 : 1;
+    /** Fixed value bit 1 - Set to 0. */
+    unsigned    u1Fixed1 : 1;
+    /** Fixed value bit 2 - Set to 0. */
+    unsigned    u1Fixed2 : 1;
+    /** Fixed value bit 3 - Set to 0. */
+    unsigned    u1Fixed3 : 1;
+    /** Fixed value bit 4 - Set to 1. */
+    unsigned    u1Fixed4 : 1;
+    /** Fixed value bit 5 - Set to 1. */
+    unsigned    u1Fixed5 : 1;
+    /** Gate size, 1 = 32 bits, 0 = 16 bits. */
+    unsigned    u132BitGate : 1;
+    /** Fixed value bit 5 - Set to 0. */
+    unsigned    u1Fixed6 : 1;
+    /** Descriptor Privilege level. */
+    unsigned    u2DPL : 2;
+    /** Present flag. */
+    unsigned    u1Present : 1;
+    /** High offset word. */
+    unsigned    u16OffsetHigh : 16;
+} VBOXIDTE_INTERRUPTGATE;
+#pragma pack()
+/** Pointer to IDT Entry, Interrupt gate view. */
+typedef  VBOXIDTE_INTERRUPTGATE *PVBOXIDTE_INTERRUPTGATE;
+
+/** IDT Entry, Trap Gate view. */
+#pragma pack(1)                         /* paranoia */
+typedef struct VBOXIDTE_TRAPGATE
+{
+    /** Low offset word. */
+    unsigned    u16OffsetLow : 16;
+    /** Segment Selector. */
+    unsigned    u16SegSel : 16;
+    /** Reserved. */
+    unsigned    u5Reserved2 : 5;
+    /** Fixed value bit 0 - Set to 0. */
+    unsigned    u1Fixed0 : 1;
+    /** Fixed value bit 1 - Set to 0. */
+    unsigned    u1Fixed1 : 1;
+    /** Fixed value bit 2 - Set to 0. */
+    unsigned    u1Fixed2 : 1;
+    /** Fixed value bit 3 - Set to 1. */
+    unsigned    u1Fixed3 : 1;
+    /** Fixed value bit 4 - Set to 1. */
+    unsigned    u1Fixed4 : 1;
+    /** Fixed value bit 5 - Set to 1. */
+    unsigned    u1Fixed5 : 1;
+    /** Gate size, 1 = 32 bits, 0 = 16 bits. */
+    unsigned    u132BitGate : 1;
+    /** Fixed value bit 5 - Set to 0. */
+    unsigned    u1Fixed6 : 1;
+    /** Descriptor Privilege level. */
+    unsigned    u2DPL : 2;
+    /** Present flag. */
+    unsigned    u1Present : 1;
+    /** High offset word. */
+    unsigned    u16OffsetHigh : 16;
+} VBOXIDTE_TRAPGATE;
+#pragma pack()
+/** Pointer to IDT Entry, Trap Gate view. */
+typedef VBOXIDTE_TRAPGATE *PVBOXIDTE_TRAPGATE;
+
+/** IDT Entry Generic view. */
+#pragma pack(1)                         /* paranoia */
+typedef struct VBOXIDTE_GENERIC
+{
+    /** Low offset word. */
+    unsigned    u16OffsetLow : 16;
+    /** Segment Selector. */
+    unsigned    u16SegSel : 16;
+    /** Reserved. */
+    unsigned    u5Reserved : 5;
+    /** IDT Type part one (not used for task gate). */
+    unsigned    u3Type1 : 3;
+    /** IDT Type part two. */
+    unsigned    u5Type2 : 5;
+    /** Descriptor Privilege level. */
+    unsigned    u2DPL : 2;
+    /** Present flag. */
+    unsigned    u1Present : 1;
+    /** High offset word. */
+    unsigned    u16OffsetHigh : 16;
+} VBOXIDTE_GENERIC;
+#pragma pack()
+/** Pointer to IDT Entry Generic view. */
+typedef VBOXIDTE_GENERIC *PVBOXIDTE_GENERIC;
+
+/** IDT Type1 value. (Reserved for task gate!) */
+#define VBOX_IDTE_TYPE1             0
+/** IDT Type2 value - Task gate. */
+#define VBOX_IDTE_TYPE2_TASK        0x5
+/** IDT Type2 value - 16 bit interrupt gate. */
+#define VBOX_IDTE_TYPE2_INT_16      0x6
+/** IDT Type2 value - 32 bit interrupt gate. */
+#define VBOX_IDTE_TYPE2_INT_32      0xe
+/** IDT Type2 value - 16 bit trap gate. */
+#define VBOX_IDTE_TYPE2_TRAP_16     0x7
+/** IDT Type2 value - 32 bit trap gate. */
+#define VBOX_IDTE_TYPE2_TRAP_32     0xf
+
+/** IDT Entry. */
+#pragma pack(1)                         /* paranoia */
+typedef union VBOXIDTE
+{
+    /** Task gate view. */
+    VBOXIDTE_TASKGATE       Task;
+    /** Trap gate view. */
+    VBOXIDTE_TRAPGATE       Trap;
+    /** Interrupt gate view. */
+    VBOXIDTE_INTERRUPTGATE  Int;
+    /** Generic IDT view. */
+    VBOXIDTE_GENERIC        Gen;
+
+    /** 8 bit unsigned integer view. */
+    uint8_t     au8[8];
+    /** 16 bit unsigned integer view. */
+    uint16_t    au16[4];
+    /** 32 bit unsigned integer view. */
+    uint32_t    au32[2];
+    /** 64 bit unsigned integer view. */
+    uint64_t    au64;
+} VBOXIDTE;
+#pragma pack()
+/** Pointer to IDT Entry. */
+typedef VBOXIDTE *PVBOXIDTE;
+/** Pointer to IDT Entry. */
+typedef VBOXIDTE const *PCVBOXIDTE;
+
+/** IDT Entry, 64-bit mode, Intertupt gate view. */
+#pragma pack(1)                         /* paranoia */
+typedef struct VBOXIDTE64_INTERRUPTGATE
+{
+    /** Low offset word. */
+    unsigned    u16OffsetLow : 16;
+    /** Segment Selector. */
+    unsigned    u16SegSel : 16;
+    /** Interrupt Stack Table Index. */
+    unsigned    u3Ist : 3;
+    /** Fixed value bit 0 - Set to 0. */
+    unsigned    u1Fixed0 : 1;
+    /** Fixed value bit 1 - Set to 0. */
+    unsigned    u1Fixed1 : 1;
+    /** Fixed value bit 2 - Set to 0. */
+    unsigned    u1Fixed2 : 1;
+    /** Fixed value bit 3 - Set to 0. */
+    unsigned    u1Fixed3 : 1;
+    /** Fixed value bit 4 - Set to 0. */
+    unsigned    u1Fixed4 : 1;
+    /** Fixed value bit 5 - Set to 0. */
+    unsigned    u1Fixed5 : 1;
+    /** Fixed value bit 6 - Set to 1. */
+    unsigned    u1Fixed6 : 1;
+    /** Fixed value bit 7 - Set to 1. */
+    unsigned    u1Fixed7 : 1;
+    /** Gate size, 1 = 32 bits, 0 = 16 bits. */
+    unsigned    u132BitGate : 1;
+    /** Fixed value bit 5 - Set to 0. */
+    unsigned    u1Fixed8 : 1;
+    /** Descriptor Privilege level. */
+    unsigned    u2DPL : 2;
+    /** Present flag. */
+    unsigned    u1Present : 1;
+    /** High offset word. */
+    unsigned    u16OffsetHigh : 16;
+    /** Offset bits 32..63. */
+    unsigned    u32OffsetHigh64;
+    /** Reserved. */
+    unsigned    u32Reserved;
+} VBOXIDTE64_INTERRUPTGATE;
+#pragma pack()
+/** Pointer to IDT Entry, 64-bit mode, Interrupt gate view. */
+typedef  VBOXIDTE64_INTERRUPTGATE *PVBOXIDTE64_INTERRUPTGATE;
+
+/** IDT Entry, 64-bit mode, Trap gate view. */
+#pragma pack(1)                         /* paranoia */
+typedef struct VBOXIDTE64_TRAPGATE
+{
+    /** Low offset word. */
+    unsigned    u16OffsetLow : 16;
+    /** Segment Selector. */
+    unsigned    u16SegSel : 16;
+    /** Interrupt Stack Table Index. */
+    unsigned    u3Ist : 3;
+    /** Fixed value bit 0 - Set to 0. */
+    unsigned    u1Fixed0 : 1;
+    /** Fixed value bit 1 - Set to 0. */
+    unsigned    u1Fixed1 : 1;
+    /** Fixed value bit 2 - Set to 0. */
+    unsigned    u1Fixed2 : 1;
+    /** Fixed value bit 3 - Set to 0. */
+    unsigned    u1Fixed3 : 1;
+    /** Fixed value bit 4 - Set to 0. */
+    unsigned    u1Fixed4 : 1;
+    /** Fixed value bit 5 - Set to 1. */
+    unsigned    u1Fixed5 : 1;
+    /** Fixed value bit 6 - Set to 1. */
+    unsigned    u1Fixed6 : 1;
+    /** Fixed value bit 7 - Set to 1. */
+    unsigned    u1Fixed7 : 1;
+    /** Gate size, 1 = 32 bits, 0 = 16 bits. */
+    unsigned    u132BitGate : 1;
+    /** Fixed value bit 5 - Set to 0. */
+    unsigned    u1Fixed8 : 1;
+    /** Descriptor Privilege level. */
+    unsigned    u2DPL : 2;
+    /** Present flag. */
+    unsigned    u1Present : 1;
+    /** High offset word. */
+    unsigned    u16OffsetHigh : 16;
+    /** Offset bits 32..63. */
+    unsigned    u32OffsetHigh64;
+    /** Reserved. */
+    unsigned    u32Reserved;
+} VBOXIDTE64_TRAPGATE;
+#pragma pack()
+/** Pointer to IDT Entry, 64-bit mode, Trap gate view. */
+typedef  VBOXIDTE64_TRAPGATE *PVBOXIDTE64_TRAPGATE;
+
+/** IDT Entry, 64-bit mode, Generic view. */
+#pragma pack(1)                         /* paranoia */
+typedef struct VBOXIDTE64_GENERIC
+{
+    /** Low offset word. */
+    unsigned    u16OffsetLow : 16;
+    /** Segment Selector. */
+    unsigned    u16SegSel : 16;
+    /** Reserved. */
+    unsigned    u3Ist : 3;
+    /** Fixed value bit 0 - Set to 0. */
+    unsigned    u1Fixed0 : 1;
+    /** Fixed value bit 1 - Set to 0. */
+    unsigned    u1Fixed1 : 1;
+    /** IDT Type part one (not used for task gate). */
+    unsigned    u3Type1 : 3;
+    /** IDT Type part two. */
+    unsigned    u5Type2 : 5;
+    /** Descriptor Privilege level. */
+    unsigned    u2DPL : 2;
+    /** Present flag. */
+    unsigned    u1Present : 1;
+    /** High offset word. */
+    unsigned    u16OffsetHigh : 16;
+    /** Offset bits 32..63. */
+    unsigned    u32OffsetHigh64;
+    /** Reserved. */
+    unsigned    u32Reserved;
+} VBOXIDTE64_GENERIC;
+#pragma pack()
+/** Pointer to IDT Entry, 64-bit mode, Generic view. */
+typedef VBOXIDTE64_GENERIC *PVBOXIDTE64_GENERIC;
+
+/** IDT Entry, 64-bit mode. */
+#pragma pack(1)                         /* paranoia */
+typedef union VBOXIDTE64
+{
+    /** Trap gate view. */
+    VBOXIDTE64_TRAPGATE       Trap;
+    /** Interrupt gate view. */
+    VBOXIDTE64_INTERRUPTGATE  Int;
+    /** Generic IDT view. */
+    VBOXIDTE64_GENERIC        Gen;
+
+    /** 8 bit unsigned integer view. */
+    uint8_t     au8[16];
+    /** 16 bit unsigned integer view. */
+    uint16_t    au16[8];
+    /** 32 bit unsigned integer view. */
+    uint32_t    au32[4];
+    /** 64 bit unsigned integer view. */
+    uint64_t    au64[2];
+} VBOXIDTE64;
+#pragma pack()
+/** Pointer to IDT Entry. */
+typedef VBOXIDTE64 *PVBOXIDTE64;
+/** Pointer to IDT Entry. */
+typedef VBOXIDTE64 const *PCVBOXIDTE64;
+
+#pragma pack(1)
+/** IDTR */
+typedef struct VBOXIDTR
+{
+    /** Size of the IDT. */
+    uint16_t    cbIdt;
+    /** Address of the IDT. */
+    uint64_t     pIdt;
+} VBOXIDTR, *PVBOXIDTR;
+#pragma pack()
+
+/** @} */
+
+
+/** @def VBOXIDTE_OFFSET
+ * Return the offset of an IDT entry.
+ */
+#define VBOXIDTE_OFFSET(desc) \
+        (  ((uint32_t)((desc).Gen.u16OffsetHigh) << 16) \
+         | (           (desc).Gen.u16OffsetLow        ) )
+
+/** @def VBOXIDTE64_OFFSET
+ * Return the offset of an IDT entry.
+ */
+#define VBOXIDTE64_OFFSET(desc) \
+        (  ((uint64_t)((desc).Gen.u32OffsetHigh64) << 32) \
+         | ((uint32_t)((desc).Gen.u16OffsetHigh)   << 16) \
+         | (           (desc).Gen.u16OffsetLow          ) )
+
+#pragma pack(1)
+/** GDTR */
+typedef struct VBOXGDTR
+{
+    /** Size of the GDT. */
+    uint16_t    cbGdt;
+    /** Address of the GDT. */
+    uint64_t    pGdt;
+} VBOXGDTR;
+#pragma pack()
+/** Pointer to GDTR. */
+typedef VBOXGDTR *PVBOXGDTR;
+
+/** @} */
+
+
+/**
+ * 32-bit Task Segment used in raw mode.
+ * @todo Move this to SELM! Use X86TSS32 instead.
+ */
+#pragma pack(1)
+typedef struct VBOXTSS
+{
+    /** 0x00 - Back link to previous task. (static) */
+    RTSEL       selPrev;
+    uint16_t    padding1;
+    /** 0x04 - Ring-0 stack pointer. (static) */
+    uint32_t    esp0;
+    /** 0x08 - Ring-0 stack segment. (static) */
+    RTSEL       ss0;
+    uint16_t    padding_ss0;
+    /** 0x0c - Ring-1 stack pointer. (static) */
+    uint32_t    esp1;
+    /** 0x10 - Ring-1 stack segment. (static) */
+    RTSEL       ss1;
+    uint16_t    padding_ss1;
+    /** 0x14 - Ring-2 stack pointer. (static) */
+    uint32_t    esp2;
+    /** 0x18 - Ring-2 stack segment. (static) */
+    RTSEL       ss2;
+    uint16_t    padding_ss2;
+    /** 0x1c - Page directory for the task. (static) */
+    uint32_t    cr3;
+    /** 0x20 - EIP before task switch. */
+    uint32_t    eip;
+    /** 0x24 - EFLAGS before task switch. */
+    uint32_t    eflags;
+    /** 0x28 - EAX before task switch. */
+    uint32_t    eax;
+    /** 0x2c - ECX before task switch. */
+    uint32_t    ecx;
+    /** 0x30 - EDX before task switch. */
+    uint32_t    edx;
+    /** 0x34 - EBX before task switch. */
+    uint32_t    ebx;
+    /** 0x38 - ESP before task switch. */
+    uint32_t    esp;
+    /** 0x3c - EBP before task switch. */
+    uint32_t    ebp;
+    /** 0x40 - ESI before task switch. */
+    uint32_t    esi;
+    /** 0x44 - EDI before task switch. */
+    uint32_t    edi;
+    /** 0x48 - ES before task switch. */
+    RTSEL       es;
+    uint16_t    padding_es;
+    /** 0x4c - CS before task switch. */
+    RTSEL       cs;
+    uint16_t    padding_cs;
+    /** 0x50 - SS before task switch. */
+    RTSEL       ss;
+    uint16_t    padding_ss;
+    /** 0x54 - DS before task switch. */
+    RTSEL       ds;
+    uint16_t    padding_ds;
+    /** 0x58 - FS before task switch. */
+    RTSEL       fs;
+    uint16_t    padding_fs;
+    /** 0x5c - GS before task switch. */
+    RTSEL       gs;
+    uint16_t    padding_gs;
+    /** 0x60 - LDTR before task switch. */
+    RTSEL       selLdt;
+    uint16_t    padding_ldt;
+    /** 0x64 - Debug trap flag */
+    uint16_t    fDebugTrap;
+    /** 0x66 -  Offset relative to the TSS of the start of the I/O Bitmap
+     * and the end of the interrupt redirection bitmap. */
+    uint16_t    offIoBitmap;
+    /** 0x68 -  32 bytes for the virtual interrupt redirection bitmap. (VME) */
+    uint8_t     IntRedirBitmap[32];
+} VBOXTSS;
+#pragma pack()
+/** Pointer to task segment. */
+typedef VBOXTSS *PVBOXTSS;
+/** Pointer to const task segment. */
+typedef const VBOXTSS *PCVBOXTSS;
+
+
+/** Pointer to a callback method table provided by the VM API user. */
+typedef struct VMM2USERMETHODS const *PCVMM2USERMETHODS;
+
+
+/**
+ * Data transport buffer (scatter/gather)
+ */
+typedef struct PDMDATASEG
+{
+    /** Length of buffer in entry. */
+    size_t  cbSeg;
+    /** Pointer to the start of the buffer. */
+    void   *pvSeg;
+} PDMDATASEG;
+/** Pointer to a data transport segment. */
+typedef PDMDATASEG *PPDMDATASEG;
+/** Pointer to a const data transport segment. */
+typedef PDMDATASEG const *PCPDMDATASEG;
+
+
+/**
+ * Forms of generic segment offloading.
+ */
+typedef enum PDMNETWORKGSOTYPE
+{
+    /** Invalid zero value. */
+    PDMNETWORKGSOTYPE_INVALID = 0,
+    /** TCP/IPv4 - no CWR/ECE encoding. */
+    PDMNETWORKGSOTYPE_IPV4_TCP,
+    /** TCP/IPv6 - no CWR/ECE encoding. */
+    PDMNETWORKGSOTYPE_IPV6_TCP,
+    /** UDP/IPv4. */
+    PDMNETWORKGSOTYPE_IPV4_UDP,
+    /** UDP/IPv6. */
+    PDMNETWORKGSOTYPE_IPV6_UDP,
+    /** TCP/IPv6 over IPv4 tunneling - no CWR/ECE encoding.
+     * The header offsets and sizes relates to IPv4 and TCP, the IPv6 header is
+     * figured out as needed.
+     * @todo Needs checking against facts, this is just an outline of the idea. */
+    PDMNETWORKGSOTYPE_IPV4_IPV6_TCP,
+    /** UDP/IPv6 over IPv4 tunneling.
+     * The header offsets and sizes relates to IPv4 and UDP, the IPv6 header is
+     * figured out as needed.
+     * @todo Needs checking against facts, this is just an outline of the idea. */
+    PDMNETWORKGSOTYPE_IPV4_IPV6_UDP,
+    /** The end of valid GSO types. */
+    PDMNETWORKGSOTYPE_END
+} PDMNETWORKGSOTYPE;
+
+
+/**
+ * Generic segment offloading context.
+ *
+ * We generally follow the E1000 specs wrt to which header fields we change.
+ * However the GSO type implies where the checksum fields are and that they are
+ * always updated from scratch (no half done pseudo checksums).
+ *
+ * @remarks This is part of the internal network GSO packets.  Take great care
+ *          when making changes.  The size is expected to be exactly 8 bytes.
+ */
+typedef struct PDMNETWORKGSO
+{
+    /** The type of segmentation offloading we're performing (PDMNETWORKGSOTYPE). */
+    uint8_t             u8Type;
+    /** The total header size. */
+    uint8_t             cbHdrsTotal;
+    /** The max segment size (MSS) to apply. */
+    uint16_t            cbMaxSeg;
+
+    /** Offset of the first header (IPv4 / IPv6).  0 if not not needed. */
+    uint8_t             offHdr1;
+    /** Offset of the second header (TCP / UDP).  0 if not not needed. */
+    uint8_t             offHdr2;
+    /** The header size used for segmentation (equal to offHdr2 in UFO). */
+    uint8_t             cbHdrsSeg;
+    /** Unused. */
+    uint8_t             u8Unused;
+} PDMNETWORKGSO;
+/** Pointer to a GSO context. */
+typedef PDMNETWORKGSO *PPDMNETWORKGSO;
+/** Pointer to a const GSO context. */
+typedef PDMNETWORKGSO const *PCPDMNETWORKGSO;
+
+
+/**
+ * The current ROM page protection.
+ *
+ * @remarks This is part of the saved state.
+ */
+typedef enum PGMROMPROT
+{
+    /** The customary invalid value. */
+    PGMROMPROT_INVALID = 0,
+    /** Read from the virgin ROM page, ignore writes.
+     * Map the virgin page, use write access handler to ignore writes. */
+    PGMROMPROT_READ_ROM_WRITE_IGNORE,
+    /** Read from the virgin ROM page, write to the shadow RAM.
+     * Map the virgin page, use write access handler to change the shadow RAM. */
+    PGMROMPROT_READ_ROM_WRITE_RAM,
+    /** Read from the shadow ROM page, ignore writes.
+     * Map the shadow page read-only, use write access handler to ignore writes. */
+    PGMROMPROT_READ_RAM_WRITE_IGNORE,
+    /** Read from the shadow ROM page, ignore writes.
+     * Map the shadow page read-write, disabled write access handler. */
+    PGMROMPROT_READ_RAM_WRITE_RAM,
+    /** The end of valid values. */
+    PGMROMPROT_END,
+    /** The usual 32-bit type size hack. */
+    PGMROMPROT_32BIT_HACK = 0x7fffffff
+} PGMROMPROT;
+
+
+/**
+ * Page mapping lock.
+ */
+typedef struct PGMPAGEMAPLOCK
+{
+#if defined(IN_RC) || defined(VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0)
+    /** The locked page. */
+    void       *pvPage;
+    /** Pointer to the CPU that made the mapping.
+     * In ring-0 and raw-mode context we don't intend to ever allow long term
+     * locking and this is a way of making sure we're still on the same CPU. */
+    PVMCPU      pVCpu;
+#else
+    /** Pointer to the PGMPAGE and lock type.
+     * bit-0 abuse: set=write, clear=read. */
+    uintptr_t   uPageAndType;
+/** Read lock type value. */
+# define PGMPAGEMAPLOCK_TYPE_READ    ((uintptr_t)0)
+/** Write lock type value. */
+# define PGMPAGEMAPLOCK_TYPE_WRITE   ((uintptr_t)1)
+/** Lock type mask. */
+# define PGMPAGEMAPLOCK_TYPE_MASK    ((uintptr_t)1)
+    /** Pointer to the PGMCHUNKR3MAP. */
+    void       *pvMap;
+#endif
+} PGMPAGEMAPLOCK;
+/** Pointer to a page mapping lock. */
+typedef PGMPAGEMAPLOCK *PPGMPAGEMAPLOCK;
+
+
+/** Pointer to a info helper callback structure. */
+typedef struct DBGFINFOHLP *PDBGFINFOHLP;
+/** Pointer to a const info helper callback structure. */
+typedef const struct DBGFINFOHLP *PCDBGFINFOHLP;
+
+/** Pointer to a const register descriptor. */
+typedef struct DBGFREGDESC const *PCDBGFREGDESC;
+
+
+/** Configuration manager tree node - A key. */
+typedef struct CFGMNODE *PCFGMNODE;
+
+/** Configuration manager tree leaf - A value. */
+typedef struct CFGMLEAF *PCFGMLEAF;
+
+
+/**
+ * CPU modes.
+ */
+typedef enum CPUMMODE
+{
+    /** The usual invalid zero entry. */
+    CPUMMODE_INVALID = 0,
+    /** Real mode. */
+    CPUMMODE_REAL,
+    /** Protected mode (32-bit). */
+    CPUMMODE_PROTECTED,
+    /** Long mode (64-bit). */
+    CPUMMODE_LONG
+} CPUMMODE;
+
+
+/**
+ * CPU mode flags (DISSTATE::mode).
+ */
+typedef enum DISCPUMODE
+{
+    DISCPUMODE_INVALID = 0,
+    DISCPUMODE_16BIT,
+    DISCPUMODE_32BIT,
+    DISCPUMODE_64BIT,
+    /** hack forcing the size of the enum to 32-bits. */
+    DISCPUMODE_MAKE_32BIT_HACK = 0x7fffffff
+} DISCPUMODE;
+
+/** Pointer to the disassembler state. */
+typedef struct DISSTATE *PDISSTATE;
+/** Pointer to a const disassembler state. */
+typedef struct DISSTATE const *PCDISSTATE;
+
+/** @deprecated  PDISSTATE and change pCpu and pDisState to pDis. */
+typedef PDISSTATE PDISCPUSTATE;
+/** @deprecated  PCDISSTATE and change pCpu and pDisState to pDis. */
+typedef PCDISSTATE PCDISCPUSTATE;
+
+
+/** @} */
+
+#endif
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/include/VBox/version.h
@@ -0,0 +1,153 @@
+/** @file
+ * VBox Version Management.
+ */
+
+/*
+ * Copyright (C) 2006-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+#ifndef ___VBox_version_h
+#define ___VBox_version_h
+
+/* Product info. */
+#include <product-generated.h>
+#include <version-generated.h>
+
+#ifdef RC_INVOKED
+/* Some versions of RC has trouble with cdefs.h, so we duplicate these two here. */
+# define RT_STR(str)             #str
+# define RT_XSTR(str)            RT_STR(str)
+#else  /* !RC_INVOKED */
+
+/** Combined version number. */
+# define VBOX_VERSION                    (VBOX_VERSION_MAJOR << 16 | VBOX_VERSION_MINOR)
+/** Get minor version from combined version. */
+# define VBOX_GET_VERSION_MINOR(uVer)    ((uVer) & 0xffff)
+/** Get major version from combined version. */
+# define VBOX_GET_VERSION_MAJOR(uVer)    ((uVer) >> 16)
+
+/**
+ * Make a full version number.
+ *
+ * The returned number can be used in normal integer comparsions and will yield
+ * the expected results.
+ *
+ * @param   uMajor      The major version number.
+ * @param   uMinor      The minor version number.
+ * @param   uBuild      The build number.
+ * @returns Full version number.
+ */
+# define VBOX_FULL_VERSION_MAKE(uMajor, uMinor, uBuild) \
+    (  (uint32_t)((uMajor) &   0xff) << 24 \
+     | (uint32_t)((uMinor) &   0xff) << 16 \
+     | (uint32_t)((uBuild) & 0xffff)       \
+    )
+
+/** Combined version number. */
+# define VBOX_FULL_VERSION              \
+    VBOX_FULL_VERSION_MAKE(VBOX_VERSION_MAJOR, VBOX_VERSION_MINOR, VBOX_VERSION_BUILD)
+/** Get the major version number from a VBOX_FULL_VERSION style number. */
+# define VBOX_FULL_VERSION_GET_MAJOR(uFullVer)  ( ((uFullVer) >> 24) &   0xffU )
+/** Get the minor version number from a VBOX_FULL_VERSION style number. */
+# define VBOX_FULL_VERSION_GET_MINOR(uFullVer)  ( ((uFullVer) >> 16) &   0xffU )
+/** Get the build version number from a VBOX_FULL_VERSION style number. */
+# define VBOX_FULL_VERSION_GET_BUILD(uFullVer)  ( ((uFullVer)      ) & 0xffffU )
+
+/**
+ * Make a short version number for use in 16 bit version fields.
+ *
+ * The returned number can be used in normal integer comparsions and will yield
+ * the expected results.
+ *
+ * @param   uMajor      The major version number.
+ * @param   uMinor      The minor version number.
+ * @returns Short version number.
+ */
+# define VBOX_SHORT_VERSION_MAKE(uMajor, uMinor) \
+    (  (uint16_t)((uMajor) &   0xff) << 8 \
+     | (uint16_t)((uMinor) &   0xff)      \
+    )
+
+/** Combined short version number. */
+# define VBOX_SHORT_VERSION               \
+    VBOX_SHORT_VERSION_MAKE(VBOX_VERSION_MAJOR, VBOX_VERSION_MINOR)
+/** Get the major version number from a VBOX_SHORT_VERSION style number. */
+# define VBOX_SHORT_VERSION_GET_MAJOR(uShortVer)  ( ((uShortVer) >> 8) &   0xffU )
+/** Get the minor version number from a VBOX_SHORT_VERSION style number. */
+# define VBOX_SHORT_VERSION_GET_MINOR(uShortVer)  ( (uShortVer) &   0xffU )
+
+#endif /* !RC_INVOKED */
+
+/** @name Prefined strings for Windows resource files
+ * @{ */
+#define VBOX_RC_COMPANY_NAME            VBOX_VENDOR
+#define VBOX_RC_LEGAL_COPYRIGHT         "Copyright (C) 2009-" VBOX_C_YEAR " Oracle Corporation\0"
+#define VBOX_RC_PRODUCT_NAME                    VBOX_PRODUCT
+#define VBOX_RC_PRODUCT_NAME_GA                 VBOX_PRODUCT " Guest Additions"
+#define VBOX_RC_PRODUCT_NAME_PUEL_EXTPACK       VBOX_PRODUCT " Extension Pack"
+#define VBOX_RC_PRODUCT_NAME_DTRACE_EXTPACK     VBOX_PRODUCT " VBoxDTrace Extension Pack"
+#define VBOX_RC_PRODUCT_NAME_STR                VBOX_RC_PRODUCT_NAME "\0"
+#define VBOX_RC_PRODUCT_NAME_GA_STR             VBOX_RC_PRODUCT_NAME_GA "\0"
+#define VBOX_RC_PRODUCT_NAME_PUEL_EXTPACK_STR   VBOX_RC_PRODUCT_NAME_PUEL_EXTPACK "\0"
+#define VBOX_RC_PRODUCT_NAME_DTRACE_EXTPACK_STR VBOX_RC_PRODUCT_NAME_DTRACE_EXTPACK "\0"
+#define VBOX_RC_PRODUCT_VERSION         VBOX_VERSION_MAJOR , VBOX_VERSION_MINOR , VBOX_VERSION_BUILD , VBOX_SVN_REV_MOD_5K
+#define VBOX_RC_FILE_VERSION            VBOX_VERSION_MAJOR , VBOX_VERSION_MINOR , VBOX_VERSION_BUILD , VBOX_SVN_REV_MOD_5K
+#ifndef VBOX_VERSION_PRERELEASE
+# define VBOX_RC_PRODUCT_VERSION_STR    RT_XSTR(VBOX_VERSION_MAJOR) "." RT_XSTR(VBOX_VERSION_MINOR) "." RT_XSTR(VBOX_VERSION_BUILD) "." RT_XSTR(VBOX_SVN_REV) "\0"
+# define VBOX_RC_FILE_VERSION_STR       RT_XSTR(VBOX_VERSION_MAJOR) "." RT_XSTR(VBOX_VERSION_MINOR) "." RT_XSTR(VBOX_VERSION_BUILD) "." RT_XSTR(VBOX_SVN_REV) "\0"
+#else
+# define VBOX_RC_PRODUCT_VERSION_STR    RT_XSTR(VBOX_VERSION_MAJOR) "." RT_XSTR(VBOX_VERSION_MINOR) "." RT_XSTR(VBOX_VERSION_BUILD) "." RT_XSTR(VBOX_SVN_REV) " (" VBOX_VERSION_PRERELEASE ")\0"
+# define VBOX_RC_FILE_VERSION_STR       RT_XSTR(VBOX_VERSION_MAJOR) "." RT_XSTR(VBOX_VERSION_MINOR) "." RT_XSTR(VBOX_VERSION_BUILD) "." RT_XSTR(VBOX_SVN_REV) " (" VBOX_VERSION_PRERELEASE ")\0"
+#endif
+#define VBOX_RC_FILE_OS                 VOS_NT_WINDOWS32
+#define VBOX_RC_TYPE_DLL                VFT_DLL
+#define VBOX_RC_TYPE_APP                VFT_APP
+#define VBOX_RC_TYPE_DRV                VFT_DRV
+/* Flags and extra strings depending on the build type and who's building. */
+#if defined(DEBUG) || defined(LOG_ENABLED) || defined(RT_STRICT) || defined(VBOX_STRICT) || defined(VBOX_WITH_STATISTICS)
+# define VBOX_RC_FILE_FLAGS_DEBUG       VS_FF_DEBUG
+#else
+# define VBOX_RC_FILE_FLAGS_DEBUG       0
+#endif
+#if VBOX_VERSION_MINOR >= 51 || defined(VBOX_VERSION_PRERELEASE)
+# define VBOX_RC_FILE_FLAGS_PRERELEASE  VS_FF_PRERELEASE
+#else
+# define VBOX_RC_FILE_FLAGS_PRERELEASE  0
+#endif
+#if defined(VBOX_BUILD_SERVER_BUILD) && (VBOX_VERSION_MINOR & 1) == 0
+# define VBOX_RC_FILE_FLAGS_BUILD       0
+# define VBOX_RC_MORE_STRINGS
+#elif defined(VBOX_BUILD_SERVER_BUILD)
+# define VBOX_RC_FILE_FLAGS_BUILD       VS_FF_SPECIALBUILD
+# define VBOX_RC_MORE_STRINGS           VALUE "SpecialBuild", "r" RT_XSTR(VBOX_SVN_REV) "\0"
+#else
+# define VBOX_RC_FILE_FLAGS_BUILD       VS_FF_PRIVATEBUILD
+# ifdef VBOX_PRIVATE_BUILD_DESC
+#  define VBOX_RC_MORE_STRINGS          VALUE "PrivateBuild", VBOX_PRIVATE_BUILD_DESC "\0"
+# else
+#  define VBOX_RC_MORE_STRINGS          VALUE "PrivateBuild", "r" RT_XSTR(VBOX_SVN_REV) "\0"
+# error
+# endif
+#endif
+#define VBOX_RC_FILE_FLAGS              (VBOX_RC_FILE_FLAGS_DEBUG | VBOX_RC_FILE_FLAGS_PRERELEASE | VBOX_RC_FILE_FLAGS_BUILD)
+/** @} */
+
+#endif
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/include/internal/assert.h
@@ -0,0 +1,63 @@
+/* $Id: assert.h $ */
+/** @file
+ * IPRT - Internal RTAssert header
+ */
+
+/*
+ * Copyright (C) 2009-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+#ifndef ___internal_assert_h
+#define ___internal_assert_h
+
+#include <iprt/types.h>
+
+RT_C_DECLS_BEGIN
+
+#ifdef IN_RING0
+
+/**
+ * Print the 1st part of an assert message to whatever native facility is best
+ * fitting.
+ *
+ * @param   pszExpr     Expression. Can be NULL.
+ * @param   uLine       Location line number.
+ * @param   pszFile     Location file name.
+ * @param   pszFunction Location function name.
+ */
+DECLHIDDEN(void) rtR0AssertNativeMsg1(const char *pszExpr, unsigned uLine, const char *pszFile, const char *pszFunction);
+
+/**
+ * Print the 2nd (optional) part of an assert message to whatever native
+ * facility is best fitting.
+ *
+ * @param   fInitial    Whether it's the initial (true) or an additional (false)
+ *                      message.
+ * @param   pszFormat   Printf like format string.
+ * @param   va          Arguments to that string.
+ */
+DECLHIDDEN(void) rtR0AssertNativeMsg2V(bool fInitial, const char *pszFormat, va_list va);
+
+#endif
+
+RT_C_DECLS_END
+
+#endif
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/include/internal/initterm.h
@@ -0,0 +1,53 @@
+/* $Id: initterm.h $ */
+/** @file
+ * IPRT - Initialization & Termination.
+ */
+
+/*
+ * Copyright (C) 2006-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+#ifndef ___internal_initterm_h
+#define ___internal_initterm_h
+
+#include <iprt/cdefs.h>
+
+RT_C_DECLS_BEGIN
+
+#ifdef IN_RING0
+
+/**
+ * Platform specific initialization.
+ *
+ * @returns IPRT status code.
+ */
+DECLHIDDEN(int)  rtR0InitNative(void);
+
+/**
+ * Platform specific termination.
+ */
+DECLHIDDEN(void) rtR0TermNative(void);
+
+#endif /* IN_RING0 */
+
+RT_C_DECLS_END
+
+#endif
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/include/internal/iprt.h
@@ -0,0 +1,204 @@
+/* $Id: iprt.h $ */
+/** @file
+ * IPRT - Internal header for miscellaneous global defs and types.
+ */
+
+/*
+ * Copyright (C) 2009-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+#ifndef ___internal_iprt_h
+#define ___internal_iprt_h
+
+#include <iprt/cdefs.h>
+#include <iprt/types.h>
+
+/** @def RT_EXPORT_SYMBOL
+ * This define is really here just for the linux kernel.
+ * @param   Name        The symbol name.
+ */
+#if defined(RT_OS_LINUX) \
+ && defined(IN_RING0) \
+ && defined(MODULE) \
+ && !defined(RT_NO_EXPORT_SYMBOL)
+# define bool linux_bool /* see r0drv/linux/the-linux-kernel.h */
+# include <linux/version.h>
+# if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 33)
+#  include <generated/autoconf.h>
+# else
+#  ifndef AUTOCONF_INCLUDED
+#   include <linux/autoconf.h>
+#  endif
+# endif
+# if defined(CONFIG_MODVERSIONS) && !defined(MODVERSIONS)
+#  define MODVERSIONS
+#  if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 71)
+#   include <linux/modversions.h>
+#  endif
+# endif
+# include <linux/module.h>
+# undef bool
+# define RT_EXPORT_SYMBOL(Name) EXPORT_SYMBOL(Name)
+#else
+# define RT_EXPORT_SYMBOL(Name) extern int g_rtExportSymbolDummyVariable
+#endif
+
+
+/** @def RT_MORE_STRICT
+ * Enables more assertions in IPRT. */
+#if !defined(RT_MORE_STRICT) && (defined(DEBUG) || defined(RT_STRICT) || defined(DOXYGEN_RUNNING)) && !defined(RT_OS_WINDOWS) /** @todo enable on windows after testing */
+# define RT_MORE_STRICT
+#endif
+
+/** @def RT_ASSERT_PREEMPT_CPUID_VAR
+ * Partner to RT_ASSERT_PREEMPT_CPUID_VAR. Declares and initializes a variable
+ * idAssertCpu to NIL_RTCPUID if preemption is enabled and to RTMpCpuId if
+ * disabled.  When RT_MORE_STRICT isn't defined it declares an uninitialized
+ * dummy variable.
+ *
+ * Requires iprt/mp.h and iprt/asm.h.
+ */
+/** @def RT_ASSERT_PREEMPT_CPUID
+ * Asserts that we didn't change CPU since RT_ASSERT_PREEMPT_CPUID_VAR if
+ * preemption is disabled.  Will also detect changes in preemption
+ * disable/enable status.  This is a noop when RT_MORE_STRICT isn't defined. */
+#ifdef RT_MORE_STRICT
+# define RT_ASSERT_PREEMPT_CPUID_VAR() \
+    RTCPUID const idAssertCpu = RTThreadPreemptIsEnabled(NIL_RTTHREAD) ? NIL_RTCPUID : RTMpCpuId()
+# define RT_ASSERT_PREEMPT_CPUID() \
+   do \
+   { \
+        RTCPUID const idAssertCpuNow = RTThreadPreemptIsEnabled(NIL_RTTHREAD) ? NIL_RTCPUID : RTMpCpuId(); \
+        AssertMsg(idAssertCpu == idAssertCpuNow,  ("%#x, %#x\n", idAssertCpu, idAssertCpuNow)); \
+   } while (0)
+
+#else
+# define RT_ASSERT_PREEMPT_CPUID_VAR()  RTCPUID idAssertCpuDummy
+# define RT_ASSERT_PREEMPT_CPUID()      NOREF(idAssertCpuDummy)
+#endif
+
+/** @def RT_ASSERT_PREEMPT_CPUID_SPIN_ACQUIRED
+ * Extended version of RT_ASSERT_PREEMPT_CPUID for use before
+ * RTSpinlockAcquired* returns.  This macro works the idCpuOwner and idAssertCpu
+ * members of the spinlock instance data. */
+#ifdef RT_MORE_STRICT
+# define RT_ASSERT_PREEMPT_CPUID_SPIN_ACQUIRED(pThis) \
+    do \
+    { \
+        RTCPUID const idAssertCpuNow = RTMpCpuId(); \
+        AssertMsg(idAssertCpu == idAssertCpuNow || idAssertCpu == NIL_RTCPUID,  ("%#x, %#x\n", idAssertCpu, idAssertCpuNow)); \
+        (pThis)->idAssertCpu = idAssertCpu; \
+        (pThis)->idCpuOwner  = idAssertCpuNow; \
+    } while (0)
+#else
+# define RT_ASSERT_PREEMPT_CPUID_SPIN_ACQUIRED(pThis)   NOREF(idAssertCpuDummy)
+#endif
+
+/** @def RT_ASSERT_PREEMPT_CPUID_SPIN_RELEASE_VARS
+ * Extended version of RT_ASSERT_PREEMPT_CPUID_VAR for use with
+ * RTSpinlockRelease* returns. */
+#ifdef RT_MORE_STRICT
+# define RT_ASSERT_PREEMPT_CPUID_SPIN_RELEASE_VARS()    RTCPUID idAssertCpu
+#else
+# define RT_ASSERT_PREEMPT_CPUID_SPIN_RELEASE_VARS()    RTCPUID idAssertCpuDummy
+#endif
+
+/** @def RT_ASSERT_PREEMPT_CPUID_SPIN_RELEASE
+ * Extended version of RT_ASSERT_PREEMPT_CPUID for use in RTSpinlockRelease*
+ * before calling the native API for releasing the spinlock.  It must be
+ * teamed up with RT_ASSERT_PREEMPT_CPUID_SPIN_ACQUIRED. */
+#ifdef RT_MORE_STRICT
+# define RT_ASSERT_PREEMPT_CPUID_SPIN_RELEASE(pThis) \
+    do \
+    { \
+        RTCPUID const idCpuOwner     = (pThis)->idCpuOwner; \
+        RTCPUID const idAssertCpuNow = RTMpCpuId(); \
+        AssertMsg(idCpuOwner == idAssertCpuNow,  ("%#x, %#x\n", idCpuOwner, idAssertCpuNow)); \
+        (pThis)->idCpuOwner  = NIL_RTCPUID; \
+        idAssertCpu = (pThis)->idAssertCpu; \
+        (pThis)->idAssertCpu = NIL_RTCPUID; \
+    } while (0)
+#else
+# define RT_ASSERT_PREEMPT_CPUID_SPIN_RELEASE(pThis)    NOREF(idAssertCpuDummy)
+#endif
+
+/** @def RT_ASSERT_PREEMPT_CPUID_DISABLE
+ * For use in RTThreadPreemptDisable implementations after having disabled
+ * preemption.  Requires iprt/mp.h. */
+#ifdef RT_MORE_STRICT
+# define RT_ASSERT_PREEMPT_CPUID_DISABLE(pStat) \
+    do \
+    { \
+        Assert((pStat)->idCpu == NIL_RTCPUID); \
+        (pStat)->idCpu = RTMpCpuId(); \
+    } while (0)
+#else
+# define RT_ASSERT_PREEMPT_CPUID_DISABLE(pStat) \
+    Assert((pStat)->idCpu == NIL_RTCPUID)
+#endif
+
+/** @def RT_ASSERT_PREEMPT_CPUID_RESTORE
+ * For use in RTThreadPreemptRestore implementations before restoring
+ * preemption.  Requires iprt/mp.h. */
+#ifdef RT_MORE_STRICT
+# define RT_ASSERT_PREEMPT_CPUID_RESTORE(pStat) \
+    do \
+    { \
+        RTCPUID const idAssertCpuNow = RTMpCpuId(); \
+        AssertMsg((pStat)->idCpu == idAssertCpuNow,  ("%#x, %#x\n", (pStat)->idCpu, idAssertCpuNow)); \
+        (pStat)->idCpu = NIL_RTCPUID; \
+    } while (0)
+#else
+# define RT_ASSERT_PREEMPT_CPUID_RESTORE(pStat)         do { } while (0)
+#endif
+
+
+/** @def RT_ASSERT_INTS_ON
+ * Asserts that interrupts are disabled when RT_MORE_STRICT is defined. */
+#ifdef RT_MORE_STRICT
+# if defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86)
+#  define RT_ASSERT_INTS_ON()           Assert(ASMIntAreEnabled())
+# else /* PORTME: Add architecture/platform specific test. */
+#  define RT_ASSERT_INTS_ON()           Assert(RTThreadPreemptIsEnabled(NIL_RTTHREAD))
+# endif
+#else
+# define RT_ASSERT_INTS_ON()            do { } while (0)
+#endif
+
+/** @def RT_ASSERT_PREEMPTIBLE
+ * Asserts that preemption hasn't been disabled (using
+ * RTThreadPreemptDisable) when RT_MORE_STRICT is defined. */
+#ifdef RT_MORE_STRICT
+# define RT_ASSERT_PREEMPTIBLE()        Assert(RTThreadPreemptIsEnabled(NIL_RTTHREAD))
+#else
+# define RT_ASSERT_PREEMPTIBLE()        do { } while (0)
+#endif
+
+
+RT_C_DECLS_BEGIN
+
+#ifdef RT_OS_OS2
+uint32_t rtR0SemWaitOs2ConvertTimeout(uint32_t fFlags, uint64_t uTimeout);
+#endif
+
+RT_C_DECLS_END
+
+#endif
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/include/internal/lockvalidator.h
@@ -0,0 +1,116 @@
+/* $Id: lockvalidator.h $ */
+/** @file
+ * IPRT - Internal RTLockValidator header.
+ */
+
+/*
+ * Copyright (C) 2006-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+#ifndef ___iprt_internal_lockvalidator_h
+#define ___iprt_internal_lockvalidator_h
+
+#include <iprt/types.h>
+#include <iprt/lockvalidator.h>
+
+RT_C_DECLS_BEGIN
+
+
+/**
+ * Record used only on the lock stack for recording the stack and source
+ * position of a recursive lock acquisition.
+ */
+typedef struct RTLOCKVALRECNEST
+{
+    RTLOCKVALRECCORE                Core;
+    /** The recursion level at this point in the stack. */
+    uint32_t                        cRecursion;
+    /** Pointer to the next record on the stack. */
+    PRTLOCKVALRECUNION volatile     pDown;
+    /** Pointer to the first recursion. */
+    PRTLOCKVALRECUNION volatile     pRec;
+    /** Pointer to the next free record when in the
+     *  RTLOCKVALPERTHREAD::pFreeNestRecs list. */
+    struct RTLOCKVALRECNEST        *pNextFree;
+    /** The source position. */
+    RTLOCKVALSRCPOS                 SrcPos;
+} RTLOCKVALRECNEST;
+/** Pointer to a recursion record. */
+typedef RTLOCKVALRECNEST *PRTLOCKVALRECNEST;
+
+
+/**
+ * Record union for simplifying internal processing.
+ */
+typedef union RTLOCKVALRECUNION
+{
+    RTLOCKVALRECCORE                Core;
+    RTLOCKVALRECEXCL                Excl;
+    RTLOCKVALRECSHRD                Shared;
+    RTLOCKVALRECSHRDOWN             ShrdOwner;
+    RTLOCKVALRECNEST                Nest;
+} RTLOCKVALRECUNION;
+
+
+/**
+ * Per thread data for the lock validator.
+ *
+ * This is part of the RTTHREADINT structure.
+ */
+typedef struct RTLOCKVALPERTHREAD
+{
+    /** Where we are blocking. */
+    RTLOCKVALSRCPOS                 SrcPos;
+    /** Top of the lock stack. */
+    PRTLOCKVALRECUNION volatile     pStackTop;
+    /** List of free recursion (nesting) record. */
+    PRTLOCKVALRECNEST               pFreeNestRecs;
+    /** What we're blocking on.
+     * The lock validator sets this, RTThreadUnblock clears it. */
+    PRTLOCKVALRECUNION volatile     pRec;
+    /** The state in which pRec that goes with pRec.
+     * RTThreadUnblocking uses this to figure out when to clear pRec. */
+    RTTHREADSTATE volatile          enmRecState;
+    /** The thread is running inside the lock validator. */
+    bool volatile                   fInValidator;
+    /** Reserved for alignment purposes. */
+    bool                            afReserved[3];
+    /** Number of registered write locks, mutexes and critsects that this thread owns. */
+    int32_t volatile                cWriteLocks;
+    /** Number of registered read locks that this thread owns, nesting included. */
+    int32_t volatile                cReadLocks;
+    /** Bitmap indicating which entires are free (set) and allocated (clear). */
+    uint32_t volatile               bmFreeShrdOwners;
+    /** Reserved for alignment purposes. */
+    uint32_t                        u32Reserved;
+    /** Statically allocated shared owner records */
+    RTLOCKVALRECSHRDOWN             aShrdOwners[32];
+} RTLOCKVALPERTHREAD;
+
+
+DECLHIDDEN(void)    rtLockValidatorInitPerThread(RTLOCKVALPERTHREAD *pPerThread);
+DECLHIDDEN(void)    rtLockValidatorDeletePerThread(RTLOCKVALPERTHREAD *pPerThread);
+DECLHIDDEN(void)    rtLockValidatorSerializeDestructEnter(void);
+DECLHIDDEN(void)    rtLockValidatorSerializeDestructLeave(void);
+
+RT_C_DECLS_END
+
+#endif
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/include/internal/magics.h
@@ -0,0 +1,241 @@
+/* $Id: magics.h $ */
+/** @file
+ * IPRT - Internal header defining The Magic Numbers.
+ */
+
+/*
+ * Copyright (C) 2007-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+#ifndef ___internal_magics_h
+#define ___internal_magics_h
+
+/** @name Magic Numbers.
+ * @{ */
+
+/** Magic number for RTAIOMGRINT::u32Magic. (Emil Erich Kaestner) */
+#define RTAIOMGR_MAGIC                  UINT32_C(0x18990223)
+/** Magic number for RTAIOMGRINTFILE::u32Magic. (Ephraim Kishon) */
+#define RTAIOMGRFILE_MAGIC              UINT32_C(0x19240823)
+/** Magic number for RTDBGMODINT::u32Magic. (Charles Lloyd) */
+#define RTDBGAS_MAGIC                   UINT32_C(0x19380315)
+/** Magic number for RTDBGCFGINT::u32Magic. (McCoy Tyner) */
+#define RTDBGCFG_MAGIC                  UINT32_C(0x19381211)
+/** Magic number for RTDBGMODINT::u32Magic. (Keith Jarrett) */
+#define RTDBGMOD_MAGIC                  UINT32_C(0x19450508)
+/** Magic number for RTDBGMODVTIMG::u32Magic. (Jack DeJohnette) */
+#define RTDBGMODVTDBG_MAGIC             UINT32_C(0x19420809)
+/** Magic number for RTDBGMODVTIMG::u32Magic. (Cecil McBee) */
+#define RTDBGMODVTIMG_MAGIC             UINT32_C(0x19350419)
+/** Magic value for RTDBGKRNLINFOINT::u32Magic. (John Carmack) */
+#define RTDBGKRNLINFO_MAGIC             UINT32_C(0x19700820)
+/** The value of RTDIR::u32Magic. (Michael Ende) */
+#define RTDIR_MAGIC                     UINT32_C(0x19291112)
+/** The value of RTDIR::u32Magic after RTDirClose().  */
+#define RTDIR_MAGIC_DEAD                UINT32_C(0x19950829)
+/** The value of RTDVMINTERNAL::u32Magic. (Dan Brown) */
+#define RTDVM_MAGIC                     UINT32_C(0x19640622)
+/** The value of RTDVMINTERNAL::u32Magic after close. */
+#define RTDVM_MAGIC_DEAD                (~RTDVM_MAGIC)
+/** The value of RTDVMVOLUMEINTERNAL::u32Magic. (Daniel Defoe) */
+#define RTDVMVOLUME_MAGIC               UINT32_C(0x16591961)
+/** The value of RTDVMVOLUMEINTERNAL::u32Magic after close. */
+#define RTDVMVOLUME_MAGIC_DEAD          UINT32_C(0x17310424)
+/** The value of RTFILEAIOCTXINT::u32Magic. (Howard Phillips Lovecraft) */
+#define RTFILEAIOCTX_MAGIC              UINT32_C(0x18900820)
+/** The value of RTFILEAIOCTXINT::u32Magic after RTFileAioCtxDestroy(). */
+#define RTFILEAIOCTX_MAGIC_DEAD         UINT32_C(0x19370315)
+/** The value of RTFILEAIOREQINT::u32Magic. (Stephen Edwin King)  */
+#define RTFILEAIOREQ_MAGIC              UINT32_C(0x19470921)
+/** The value of RTENVINTERNAL::u32Magic. (Rumiko Takahashi) */
+#define RTENV_MAGIC                     UINT32_C(0x19571010)
+/** The value of RTERRVARS::ai32Vars[0]. (Ryuichi Sakamoto) */
+#define RTERRVARS_MAGIC                 UINT32_C(0x19520117)
+/** Magic number for RTHANDLETABLEINT::u32Magic. (Hitomi Kanehara) */
+#define RTHANDLETABLE_MAGIC             UINT32_C(0x19830808)
+/** Magic number for RTHEAPOFFSETINTERNAL::u32Magic. (Neal Town Stephenson) */
+#define RTHEAPOFFSET_MAGIC              UINT32_C(0x19591031)
+/** Magic number for RTHEAPSIMPLEINTERNAL::uMagic. (Kyoichi Katayama) */
+#define RTHEAPSIMPLE_MAGIC              UINT32_C(0x19590105)
+/** The magic value for RTHTTPINTERNAL::u32Magic. (Karl May) */
+#define RTHTTP_MAGIC                    UINT32_C(0x18420225)
+/** The value of RTHTTPINTERNAL::u32Magic after close. */
+#define RTHTTP_MAGIC_DEAD               UINT32_C(0x19120330)
+/** The magic value for RTLDRMODINTERNAL::u32Magic. (Alan Moore) */
+#define RTLDRMOD_MAGIC                  UINT32_C(0x19531118)
+/** The magic value for RTLOCALIPCSERVER::u32Magic. (Naoki Yamamoto) */
+#define RTLOCALIPCSERVER_MAGIC          UINT32_C(0x19600201)
+/** The magic value for RTLOCALIPCSERVER::u32Magic. (Katsuhiro Otomo) */
+#define RTLOCALIPCSESSION_MAGIC         UINT32_C(0x19530414)
+/** The magic value for RTLOCKVALCLASSINT::u32Magic. (Thomas Mann) */
+#define RTLOCKVALCLASS_MAGIC            UINT32_C(0x18750605)
+/** The magic value for RTLOCKVALCLASSINT::u32Magic after destruction. */
+#define RTLOCKVALCLASS_MAGIC_DEAD       UINT32_C(0x19550812)
+/** The magic value for RTLOCKVALRECEXCL::u32Magic. (Vladimir Vladimirovich Nabokov) */
+#define RTLOCKVALRECEXCL_MAGIC          UINT32_C(0x18990422)
+/** The dead magic value for RTLOCKVALRECEXCL::u32Magic. */
+#define RTLOCKVALRECEXCL_MAGIC_DEAD     UINT32_C(0x19770702)
+/** The magic value for RTLOCKVALRECSHRD::u32Magic. (Agnar Mykle) */
+#define RTLOCKVALRECSHRD_MAGIC          UINT32_C(0x19150808)
+/** The magic value for RTLOCKVALRECSHRD::u32Magic after deletion. */
+#define RTLOCKVALRECSHRD_MAGIC_DEAD     UINT32_C(0x19940115)
+/** The magic value for RTLOCKVALRECSHRDOWN::u32Magic. (Jens Ingvald Bjoerneboe) */
+#define RTLOCKVALRECSHRDOWN_MAGIC       UINT32_C(0x19201009)
+/** The magic value for RTLOCKVALRECSHRDOWN::u32Magic after deletion. */
+#define RTLOCKVALRECSHRDOWN_MAGIC_DEAD  UINT32_C(0x19760509)
+/** The magic value for RTLOCKVALRECNEST::u32Magic. (Anne Desclos) */
+#define RTLOCKVALRECNEST_MAGIC          UINT32_C(0x19071123)
+/** The magic value for RTLOCKVALRECNEST::u32Magic after deletion. */
+#define RTLOCKVALRECNEST_MAGIC_DEAD     UINT32_C(0x19980427)
+/** Magic number for RTMEMCACHEINT::u32Magic. (Joseph Weizenbaum) */
+#define RTMEMCACHE_MAGIC                UINT32_C(0x19230108)
+/** Dead magic number for RTMEMCACHEINT::u32Magic. */
+#define RTMEMCACHE_MAGIC_DEAD           UINT32_C(0x20080305)
+/** The magic value for RTMEMPOOL::u32Magic. (Jane Austin) */
+#define RTMEMPOOL_MAGIC                 UINT32_C(0x17751216)
+/** The magic value for RTMEMPOOL::u32Magic after RTMemPoolDestroy. */
+#define RTMEMPOOL_MAGIC_DEAD            UINT32_C(0x18170718)
+/** The magic value for heap blocks. (Edgar Allan Poe) */
+#define RTMEMHDR_MAGIC                  UINT32_C(0x18090119)
+/** The magic value for heap blocks after freeing. */
+#define RTMEMHDR_MAGIC_DEAD             UINT32_C(0x18491007)
+/** The value of RTPIPEINTERNAL::u32Magic. (Frank Schaetzing) */
+#define RTPIPE_MAGIC                    UINT32_C(0x19570528)
+/** The value of RTPOLLSETINTERNAL::u32Magic. (Ai Yazawa) */
+#define RTPOLLSET_MAGIC                 UINT32_C(0x19670307)
+/** RTR0MEMOBJ::u32Magic. (Masakazu Katsura) */
+#define RTR0MEMOBJ_MAGIC                UINT32_C(0x19611210)
+/** RTRANDINT::u32Magic. (Alan Moore) */
+#define RTRANDINT_MAGIC                 UINT32_C(0x19531118)
+/** The value of RTREQ::u32Magic. */
+#define RTREQ_MAGIC                     UINT32_C(0xfeed0001) /**< @todo find a value */
+/** The value of RTREQ::u32Magic of a freed request. */
+#define RTREQ_MAGIC_DEAD                (~RTREQ_MAGIC)
+/** The value of RTREQPOOLINT::u32Magic. */
+#define RTREQPOOL_MAGIC                 UINT32_C(0xfeed0002)/**< @todo find a value */
+/** The value of RTREQPOOLINT::u32Magic after destruction. */
+#define RTREQPOOL_MAGIC_DEAD           (~RTREQPOOL_MAGIC)
+/** The value of RTREQQUEUEINT::u32Magic. */
+#define RTREQQUEUE_MAGIC                UINT32_C(0xfeed0003)/**< @todo find a value */
+/** The value of RTREQQUEUEINT::u32Magic after destruction. */
+#define RTREQQUEUE_MAGIC_DEAD           (~RTREQQUEUE_MAGIC)
+/** The value of RTS3::u32Magic. (Edgar Wallace) */
+#define RTS3_MAGIC                      UINT32_C(0x18750401)
+/** The value of RTS3::u32Magic after RTS3Destroy().  */
+#define RTS3_MAGIC_DEAD                 UINT32_C(0x19320210)
+/** Magic for the event semaphore structure. (Neil Gaiman) */
+#define RTSEMEVENT_MAGIC                UINT32_C(0x19601110)
+/** Magic for the multiple release event semaphore structure. (Isaac Asimov) */
+#define RTSEMEVENTMULTI_MAGIC           UINT32_C(0x19200102)
+/** Dead magic value for multiple release event semaphore structures. */
+#define RTSEMEVENTMULTI_MAGIC_DEAD      UINT32_C(0x19920406)
+/** Magic value for RTSEMFASTMUTEXINTERNAL::u32Magic. (John Ronald Reuel Tolkien) */
+#define RTSEMFASTMUTEX_MAGIC            UINT32_C(0x18920103)
+/** Dead magic value for RTSEMFASTMUTEXINTERNAL::u32Magic. */
+#define RTSEMFASTMUTEX_MAGIC_DEAD       UINT32_C(0x19730902)
+/** Magic for the mutex semaphore structure. (Douglas Adams) */
+#define RTSEMMUTEX_MAGIC                UINT32_C(0x19520311)
+/** Dead magic for the mutex semaphore structure. */
+#define RTSEMMUTEX_MAGIC_DEAD           UINT32_C(0x20010511)
+/** Magic for the spinning mutex semaphore structure. (Natsume Soseki) */
+#define RTSEMSPINMUTEX_MAGIC            UINT32_C(0x18670209)
+/** Dead magic value for RTSEMSPINMUTEXINTERNAL::u32Magic. */
+#define RTSEMSPINMUTEX_MAGIC_DEAD       UINT32_C(0x19161209)
+/** RTSEMRWINTERNAL::u32Magic value. (Kosuke Fujishima) */
+#define RTSEMRW_MAGIC                   UINT32_C(0x19640707)
+/** RTSEMXROADSINTERNAL::u32Magic value. (Kenneth Elton "Ken" Kesey) */
+#define RTSEMXROADS_MAGIC               UINT32_C(0x19350917)
+/** RTSEMXROADSINTERNAL::u32Magic value after RTSemXRoadsDestroy. */
+#define RTSEMXROADS_MAGIC_DEAD          UINT32_C(0x20011110)
+/** The magic value for RTSOCKETINT::u32Magic. (Stanislaw Lem) */
+#define RTSOCKET_MAGIC                  UINT32_C(0x19210912)
+/** The magic value for RTSOCKETINT::u32Magic after destruction. */
+#define RTSOCKET_MAGIC_DEAD             UINT32_C(0x20060326)
+/** Magic value for RTSPINLOCKINTERNAL::u32Magic. (Terry Pratchett) */
+#define RTSPINLOCK_MAGIC                UINT32_C(0x19480428)
+/** Magic value for generic RTSPINLOCKINTERNAL::u32Magic (Georges Prosper Remi). */
+#define RTSPINLOCK_GEN_MAGIC            UINT32_C(0x10970522)
+/** Magic value for RTSTRCACHE::u32Magic. (Sir Arthur Charles Clarke) */
+#define RTSTRCACHE_MAGIC                UINT32_C(0x19171216)
+/** Magic value for RTSTRCACHE::u32Magic after RTStrCacheDestroy. */
+#define RTSTRCACHE_MAGIC_DEAD           UINT32_C(0x20080319)
+/** The value of RTSTREAM::u32Magic for a valid stream. */
+#define RTSTREAM_MAGIC                  UINT32_C(0xe44e44ee)
+/** Magic value for RTTCPSERVER::u32Magic. (Jan Garbarek) */
+#define RTTCPSERVER_MAGIC               UINT32_C(0x19470304)
+/** Magic value for RTTCPSERVER::u32Magic. (Harlan Ellison) */
+#define RTUDPSERVER_MAGIC               UINT32_C(0x19340527)
+/** The value of RTTAR::u32Magic. (Donald Ervin Knuth) */
+#define RTTAR_MAGIC                     UINT32_C(0x19380110)
+/** The value of RTTAR::u32Magic after RTTarClose(). */
+#define RTTAR_MAGIC_DEAD                ~RTTAR_MAGIC
+/** The value of RTTARFILE::u32Magic. (Abraham Stoker) */
+#define RTTARFILE_MAGIC                 UINT32_C(0x18471108)
+/** The value of RTTARFILE::u32Magic after RTTarFileClose(). */
+#define RTTARFILE_MAGIC_DEAD            UINT32_C(0x19120420)
+/** RTTESTINT::u32Magic value. (Daniel Kehlmann) */
+#define RTTESTINT_MAGIC                 UINT32_C(0x19750113)
+/** RTTHREADCTXHOOKINT::u32Magic value. (Dennis MacAlistair Ritchie) */
+#define RTTHREADCTXHOOKINT_MAGIC        UINT32_C(0x19410909)
+/** RTTHREADINT::u32Magic value. (Gilbert Keith Chesterton) */
+#define RTTHREADINT_MAGIC               UINT32_C(0x18740529)
+/** RTTHREADINT::u32Magic value for a dead thread. */
+#define RTTHREADINT_MAGIC_DEAD          UINT32_C(0x19360614)
+/** Magic number for timer handles. (Jared Mason Diamond) */
+#define RTTIMER_MAGIC                   UINT32_C(0x19370910)
+/** Magic number for timer low resolution handles. (Saki Hiwatari) */
+#define RTTIMERLR_MAGIC                 UINT32_C(0x19610715)
+/** Magic value of RTTRACEBUFINT::u32Magic. (George Orwell) */
+#define RTTRACEBUF_MAGIC                UINT32_C(0x19030625)
+/** Magic value of RTTRACEBUFINT::u32Magic after the final release. */
+#define RTTRACEBUF_MAGIC_DEAD           UINT32_C(0x19500121)
+/** The value of RTVFSOBJINTERNAL::u32Magic. (Yasunari Kawabata) */
+#define RTVFSOBJ_MAGIC                  UINT32_C(0x18990614)
+/** The value of RTVFSOBJINTERNAL::u32Magic arter close. */
+#define RTVFSOBJ_MAGIC_DEAD             UINT32_C(0x19720416)
+/** The value of RTVFSINTERNAL::u32Magic. (Sir Kingsley William Amis) */
+#define RTVFS_MAGIC                     UINT32_C(0x19220416)
+/** The value of RTVFSINTERNAL::u32Magic after close.  */
+#define RTVFS_MAGIC_DEAD                UINT32_C(0x19951022)
+/** The value of RTVFSFSSTREAMINTERNAL::u32Magic. (William McGuire "Bill" Bryson) */
+#define RTVFSFSSTREAM_MAGIC             UINT32_C(0x19511208)
+/** The value of RTVFSFSSTREAMINTERNAL::u32Magic after close */
+#define RTVFSFSSTREAM_MAGIC_DEAD        (~RTVFSFSSTREAM_MAGIC)
+/** The value of RTVFSDIRINTERNAL::u32Magic. (Franklin Patrick Herbert, Jr.) */
+#define RTVFSDIR_MAGIC                  UINT32_C(0x19201008)
+/** The value of RTVFSDIRINTERNAL::u32Magic after close. */
+#define RTVFSDIR_MAGIC_DEAD             UINT32_C(0x19860211)
+/** The value of RTVFSFILEINTERNAL::u32Magic. (Charles John Huffam Dickens) */
+#define RTVFSFILE_MAGIC                 UINT32_C(0x18120207)
+/** The value of RTVFSFILEINTERNAL::u32Magic after close. */
+#define RTVFSFILE_MAGIC_DEAD            UINT32_C(0x18700609)
+/** The value of RTVFSIOSTREAMINTERNAL::u32Magic. (Ernest Miller Hemingway) */
+#define RTVFSIOSTREAM_MAGIC             UINT32_C(0x18990721)
+/** The value of RTVFSIOSTREAMINTERNAL::u32Magic after close. */
+#define RTVFSIOSTREAM_MAGIC_DEAD        UINT32_C(0x19610702)
+/** The value of RTVFSSYMLINKINTERNAL::u32Magic. (Francis Scott Key Fitzgerald) */
+#define RTVFSSYMLINK_MAGIC              UINT32_C(0x18960924)
+/** The value of RTVFSSYMLINKINTERNAL::u32Magic after close. */
+#define RTVFSSYMLINK_MAGIC_DEAD         UINT32_C(0x19401221)
+
+/** @} */
+
+#endif
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/include/internal/memobj.h
@@ -0,0 +1,483 @@
+/* $Id: memobj.h $ */
+/** @file
+ * IPRT - Ring-0 Memory Objects.
+ */
+
+/*
+ * Copyright (C) 2006-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+#ifndef ___internal_memobj_h
+#define ___internal_memobj_h
+
+#include <iprt/memobj.h>
+#include <iprt/assert.h>
+#include "internal/magics.h"
+
+RT_C_DECLS_BEGIN
+
+/** @defgroup grp_rt_memobj_int Internals.
+ * @ingroup grp_rt_memobj
+ * @internal
+ * @{
+ */
+
+/**
+ * Ring-0 memory object type.
+ */
+typedef enum RTR0MEMOBJTYPE
+{
+    /** The traditional invalid value. */
+    RTR0MEMOBJTYPE_INVALID = 0,
+
+    /** @name Primary types (parents)
+     * @{ */
+    /** RTR0MemObjAllocPage.
+     * This memory is page aligned and fixed. */
+    RTR0MEMOBJTYPE_PAGE,
+    /** RTR0MemObjAllocLow.
+     * This memory is page aligned, fixed and is backed by physical memory below 4GB. */
+    RTR0MEMOBJTYPE_LOW,
+    /** RTR0MemObjAllocCont.
+     * This memory is page aligned, fixed and is backed by contiguous physical memory below 4GB. */
+    RTR0MEMOBJTYPE_CONT,
+    /** RTR0MemObjLockKernel, RTR0MemObjLockUser.
+     * This memory is page aligned and fixed. It was locked/pinned/wired down by the API call. */
+    RTR0MEMOBJTYPE_LOCK,
+    /** RTR0MemObjAllocPhys, RTR0MemObjEnterPhys.
+     * This memory is physical memory, page aligned, contiguous and doesn't need to have a mapping. */
+    RTR0MEMOBJTYPE_PHYS,
+    /** RTR0MemObjAllocPhysNC.
+     * This memory is physical memory, page aligned and doesn't need to have a mapping. */
+    RTR0MEMOBJTYPE_PHYS_NC,
+    /** RTR0MemObjReserveKernel, RTR0MemObjReserveUser.
+     * This memory is page aligned and has no backing. */
+    RTR0MEMOBJTYPE_RES_VIRT,
+    /** @} */
+
+    /** @name Secondary types (children)
+     * @{
+     */
+    /** RTR0MemObjMapUser, RTR0MemObjMapKernel.
+     * This is a user or kernel context mapping of another ring-0 memory object. */
+    RTR0MEMOBJTYPE_MAPPING,
+    /** @} */
+
+    /** The end of the valid types. Used for sanity checking. */
+    RTR0MEMOBJTYPE_END
+} RTR0MEMOBJTYPE;
+
+
+/** @name RTR0MEMOBJINTERNAL::fFlags
+ * @{ */
+/** Page level protection was changed. */
+#define RTR0MEMOBJ_FLAGS_PROT_CHANGED       RT_BIT_32(0)
+/** @} */
+
+
+typedef struct RTR0MEMOBJINTERNAL *PRTR0MEMOBJINTERNAL;
+typedef struct RTR0MEMOBJINTERNAL **PPRTR0MEMOBJINTERNAL;
+
+/**
+ * Ring-0 memory object.
+ *
+ * When using the PRTR0MEMOBJINTERNAL and PPRTR0MEMOBJINTERNAL types
+ * we get pMem and ppMem variable names.
+ *
+ * When using the RTR0MEMOBJ and PRTR0MEMOBJ types we get MemObj and
+ * pMemObj variable names. We never dereference variables of the RTR0MEMOBJ
+ * type, we always convert it to a PRTR0MEMOBJECTINTERNAL variable first.
+ */
+typedef struct RTR0MEMOBJINTERNAL
+{
+    /** Magic number (RTR0MEMOBJ_MAGIC). */
+    uint32_t        u32Magic;
+    /** The size of this structure. */
+    uint32_t        cbSelf;
+    /** The type of allocation. */
+    RTR0MEMOBJTYPE  enmType;
+    /** Flags, RTR0MEMOBJ_FLAGS_*. */
+    uint32_t        fFlags;
+    /** The size of the memory allocated, pinned down, or mapped. */
+    size_t          cb;
+    /** The memory address.
+     * What this really is varies with the type.
+     * For PAGE, CONT, LOW, RES_VIRT/R0, LOCK/R0 and MAP/R0 it's the ring-0 mapping.
+     * For LOCK/R3, RES_VIRT/R3 and MAP/R3 it is the ring-3 mapping.
+     * For PHYS this might actually be NULL if there isn't any mapping.
+     */
+    void           *pv;
+
+    /** Object relations. */
+    union
+    {
+        /** This is for tracking child memory handles mapping the
+         * memory described by the primary handle. */
+        struct
+        {
+            /** Number of mappings. */
+            uint32_t                cMappingsAllocated;
+            /** Number of mappings in the array. */
+            uint32_t                cMappings;
+            /** Pointers to child handles mapping this memory. */
+            PPRTR0MEMOBJINTERNAL    papMappings;
+        } Parent;
+
+        /** Pointer to the primary handle. */
+        struct
+        {
+            /** Pointer to the parent. */
+            PRTR0MEMOBJINTERNAL     pParent;
+        } Child;
+    } uRel;
+
+    /** Type specific data for the memory types that requires that. */
+    union
+    {
+        /** RTR0MEMTYPE_PAGE. */
+        struct
+        {
+            unsigned iDummy;
+        } Page;
+
+        /** RTR0MEMTYPE_LOW. */
+        struct
+        {
+            unsigned iDummy;
+        } Low;
+
+        /** RTR0MEMTYPE_CONT. */
+        struct
+        {
+            /** The physical address of the first page. */
+            RTHCPHYS    Phys;
+        } Cont;
+
+        /** RTR0MEMTYPE_LOCK_USER. */
+        struct
+        {
+            /** The process that owns the locked memory.
+             * This is NIL_RTR0PROCESS if it's kernel memory. */
+            RTR0PROCESS R0Process;
+        } Lock;
+
+        /** RTR0MEMTYPE_PHYS. */
+        struct
+        {
+            /** The base address of the physical memory. */
+            RTHCPHYS    PhysBase;
+            /** If set this object was created by RTR0MemPhysAlloc, otherwise it was
+             * created by RTR0MemPhysEnter. */
+            bool        fAllocated;
+            /** See RTMEM_CACHE_POLICY_XXX constants */
+            uint32_t    uCachePolicy;
+        } Phys;
+
+        /** RTR0MEMTYPE_PHYS_NC. */
+        struct
+        {
+            unsigned iDummy;
+        } PhysNC;
+
+        /** RTR0MEMOBJTYPE_RES_VIRT */
+        struct
+        {
+            /** The process that owns the reserved memory.
+             * This is NIL_RTR0PROCESS if it's kernel memory. */
+            RTR0PROCESS R0Process;
+        } ResVirt;
+
+        /** RTR0MEMOBJTYPE_MAPPING */
+        struct
+        {
+            /** The process that owns the reserved memory.
+             * This is NIL_RTR0PROCESS if it's kernel memory. */
+            RTR0PROCESS R0Process;
+        } Mapping;
+    } u;
+
+} RTR0MEMOBJINTERNAL;
+
+
+/**
+ * Checks if this is mapping or not.
+ *
+ * @returns true if it's a mapping, otherwise false.
+ * @param   pMem        The ring-0 memory object handle.
+ * @see RTR0MemObjIsMapping
+ */
+DECLINLINE(bool) rtR0MemObjIsMapping(PRTR0MEMOBJINTERNAL pMem)
+{
+    switch (pMem->enmType)
+    {
+        case RTR0MEMOBJTYPE_MAPPING:
+            return true;
+
+        default:
+            return false;
+    }
+}
+
+
+/**
+ * Checks page level protection can be changed on this object.
+ *
+ * @returns true / false.
+ * @param   pMem        The ring-0 memory object handle.
+ */
+DECLINLINE(bool) rtR0MemObjIsProtectable(PRTR0MEMOBJINTERNAL pMem)
+{
+    switch (pMem->enmType)
+    {
+        case RTR0MEMOBJTYPE_MAPPING:
+        case RTR0MEMOBJTYPE_PAGE:
+        case RTR0MEMOBJTYPE_LOW:
+        case RTR0MEMOBJTYPE_CONT:
+            return true;
+
+        default:
+            return false;
+    }
+}
+
+
+/**
+ * Checks if RTR0MEMOBJ::pv is a ring-3 pointer or not.
+ *
+ * @returns true if it's a object with a ring-3 address, otherwise false.
+ * @param   pMem        The ring-0 memory object handle.
+ */
+DECLINLINE(bool) rtR0MemObjIsRing3(PRTR0MEMOBJINTERNAL pMem)
+{
+    switch (pMem->enmType)
+    {
+        case RTR0MEMOBJTYPE_RES_VIRT:
+            return pMem->u.ResVirt.R0Process != NIL_RTR0PROCESS;
+        case RTR0MEMOBJTYPE_LOCK:
+            return pMem->u.Lock.R0Process    != NIL_RTR0PROCESS;
+        case RTR0MEMOBJTYPE_MAPPING:
+            return pMem->u.Mapping.R0Process != NIL_RTR0PROCESS;
+        default:
+            return false;
+    }
+}
+
+
+/**
+ * Frees the memory object (but not the handle).
+ * Any OS specific handle resources will be freed by this call.
+ *
+ * @returns IPRT status code. On failure it is assumed that the object remains valid.
+ * @param   pMem        The ring-0 memory object handle to the memory which should be freed.
+ */
+DECLHIDDEN(int) rtR0MemObjNativeFree(PRTR0MEMOBJINTERNAL pMem);
+
+/**
+ * Allocates page aligned virtual kernel memory.
+ *
+ * The memory is taken from a non paged (= fixed physical memory backing) pool.
+ *
+ * @returns IPRT status code.
+ * @param   ppMem           Where to store the ring-0 memory object handle.
+ * @param   cb              Number of bytes to allocate, page aligned.
+ * @param   fExecutable     Flag indicating whether it should be permitted to executed code in the memory object.
+ */
+DECLHIDDEN(int) rtR0MemObjNativeAllocPage(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, bool fExecutable);
+
+/**
+ * Allocates page aligned virtual kernel memory with physical backing below 4GB.
+ *
+ * The physical memory backing the allocation is fixed.
+ *
+ * @returns IPRT status code.
+ * @param   ppMem           Where to store the ring-0 memory object handle.
+ * @param   cb              Number of bytes to allocate, page aligned.
+ * @param   fExecutable     Flag indicating whether it should be permitted to executed code in the memory object.
+ */
+DECLHIDDEN(int) rtR0MemObjNativeAllocLow(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, bool fExecutable);
+
+/**
+ * Allocates page aligned virtual kernel memory with contiguous physical backing below 4GB.
+ *
+ * The physical memory backing the allocation is fixed.
+ *
+ * @returns IPRT status code.
+ * @param   ppMem           Where to store the ring-0 memory object handle.
+ * @param   cb              Number of bytes to allocate, page aligned.
+ * @param   fExecutable     Flag indicating whether it should be permitted to executed code in the memory object.
+ */
+DECLHIDDEN(int) rtR0MemObjNativeAllocCont(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, bool fExecutable);
+
+/**
+ * Locks a range of user virtual memory.
+ *
+ * @returns IPRT status code.
+ * @param   ppMem           Where to store the ring-0 memory object handle.
+ * @param   R3Ptr           User virtual address, page aligned.
+ * @param   cb              Number of bytes to lock, page aligned.
+ * @param   fAccess         The desired access, a combination of RTMEM_PROT_READ
+ *                          and RTMEM_PROT_WRITE.
+ * @param   R0Process       The process to lock pages in.
+ */
+DECLHIDDEN(int) rtR0MemObjNativeLockUser(PPRTR0MEMOBJINTERNAL ppMem, RTR3PTR R3Ptr, size_t cb, uint32_t fAccess, RTR0PROCESS R0Process);
+
+/**
+ * Locks a range of kernel virtual memory.
+ *
+ * @returns IPRT status code.
+ * @param   ppMem           Where to store the ring-0 memory object handle.
+ * @param   pv              Kernel virtual address, page aligned.
+ * @param   cb              Number of bytes to lock, page aligned.
+ * @param   fAccess         The desired access, a combination of RTMEM_PROT_READ
+ *                          and RTMEM_PROT_WRITE.
+ */
+DECLHIDDEN(int) rtR0MemObjNativeLockKernel(PPRTR0MEMOBJINTERNAL ppMem, void *pv, size_t cb, uint32_t fAccess);
+
+/**
+ * Allocates contiguous page aligned physical memory without (necessarily) any
+ * kernel mapping.
+ *
+ * @returns IPRT status code.
+ * @param   ppMem           Where to store the ring-0 memory object handle.
+ * @param   cb              Number of bytes to allocate, page aligned.
+ * @param   PhysHighest     The highest permitable address (inclusive).
+ *                          NIL_RTHCPHYS if any address is acceptable.
+ * @param   uAlignment      The alignment of the reserved memory.
+ *                          Supported values are PAGE_SIZE, _2M, _4M and _1G.
+ */
+DECLHIDDEN(int) rtR0MemObjNativeAllocPhys(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, RTHCPHYS PhysHighest, size_t uAlignment);
+
+/**
+ * Allocates non-contiguous page aligned physical memory without (necessarily) any kernel mapping.
+ *
+ * @returns IPRT status code.
+ * @retval  VERR_NOT_SUPPORTED if it's not possible to allocated unmapped
+ *          physical memory on this platform.
+ * @param   ppMem           Where to store the ring-0 memory object handle.
+ * @param   cb              Number of bytes to allocate, page aligned.
+ * @param   PhysHighest     The highest permitable address (inclusive).
+ *                          NIL_RTHCPHYS if any address is acceptable.
+ */
+DECLHIDDEN(int) rtR0MemObjNativeAllocPhysNC(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, RTHCPHYS PhysHighest);
+
+/**
+ * Creates a page aligned, contiguous, physical memory object.
+ *
+ * @returns IPRT status code.
+ * @param   ppMem           Where to store the ring-0 memory object handle.
+ * @param   Phys            The physical address to start at, page aligned.
+ * @param   cb              The size of the object in bytes, page aligned.
+ * @param   uCachePolicy    One of the RTMEM_CACHE_XXX modes.
+ */
+DECLHIDDEN(int) rtR0MemObjNativeEnterPhys(PPRTR0MEMOBJINTERNAL ppMem, RTHCPHYS Phys, size_t cb, uint32_t uCachePolicy);
+
+/**
+ * Reserves kernel virtual address space.
+ *
+ * @returns IPRT status code.
+ *          Return VERR_NOT_SUPPORTED to indicate that the user should employ fallback strategies.
+ * @param   ppMem           Where to store the ring-0 memory object handle.
+ * @param   pvFixed         Requested address. (void *)-1 means any address. This matches uAlignment if specified.
+ * @param   cb              The number of bytes to reserve, page aligned.
+ * @param   uAlignment      The alignment of the reserved memory; PAGE_SIZE, _2M or _4M.
+ */
+DECLHIDDEN(int) rtR0MemObjNativeReserveKernel(PPRTR0MEMOBJINTERNAL ppMem, void *pvFixed, size_t cb, size_t uAlignment);
+
+/**
+ * Reserves user virtual address space in the current process.
+ *
+ * @returns IPRT status code.
+ * @param   ppMem           Where to store the ring-0 memory object handle.
+ * @param   R3PtrFixed      Requested address. (RTR3PTR)-1 means any address. This matches uAlignment if specified.
+ * @param   cb              The number of bytes to reserve, page aligned.
+ * @param   uAlignment      The alignment of the reserved memory; PAGE_SIZE, _2M or _4M.
+ * @param   R0Process       The process to reserve the memory in.
+ */
+DECLHIDDEN(int) rtR0MemObjNativeReserveUser(PPRTR0MEMOBJINTERNAL ppMem, RTR3PTR R3PtrFixed, size_t cb, size_t uAlignment, RTR0PROCESS R0Process);
+
+/**
+ * Maps a memory object into user virtual address space in the current process.
+ *
+ * @returns IPRT status code.
+ * @retval  VERR_NOT_SUPPORTED see RTR0MemObjMapKernelEx.
+ *
+ * @param   ppMem           Where to store the ring-0 memory object handle of the mapping object.
+ * @param   pMemToMap       The object to be map.
+ * @param   pvFixed         Requested address. (void *)-1 means any address. This matches uAlignment if specified.
+ * @param   uAlignment      The alignment of the reserved memory; PAGE_SIZE, _2M or _4M.
+ * @param   fProt           Combination of RTMEM_PROT_* flags (except RTMEM_PROT_NONE).
+ * @param   offSub          Where in the object to start mapping. If non-zero
+ *                          the value must be page aligned and cbSub must be
+ *                          non-zero as well.
+ * @param   cbSub           The size of the part of the object to be mapped. If
+ *                          zero the entire object is mapped. The value must be
+ *                          page aligned.
+ */
+DECLHIDDEN(int) rtR0MemObjNativeMapKernel(PPRTR0MEMOBJINTERNAL ppMem, RTR0MEMOBJ pMemToMap, void *pvFixed, size_t uAlignment,
+                                          unsigned fProt, size_t offSub, size_t cbSub);
+
+/**
+ * Maps a memory object into user virtual address space in the current process.
+ *
+ * @returns IPRT status code.
+ * @param   ppMem           Where to store the ring-0 memory object handle of the mapping object.
+ * @param   pMemToMap       The object to be map.
+ * @param   R3PtrFixed      Requested address. (RTR3PTR)-1 means any address. This matches uAlignment if specified.
+ * @param   uAlignment      The alignment of the reserved memory; PAGE_SIZE, _2M or _4M.
+ * @param   fProt           Combination of RTMEM_PROT_* flags (except RTMEM_PROT_NONE).
+ * @param   R0Process       The process to map the memory into.
+ */
+DECLHIDDEN(int) rtR0MemObjNativeMapUser(PPRTR0MEMOBJINTERNAL ppMem, PRTR0MEMOBJINTERNAL pMemToMap, RTR3PTR R3PtrFixed, size_t uAlignment, unsigned fProt, RTR0PROCESS R0Process);
+
+/**
+ * Change the page level protection of one or more pages in a memory object.
+ *
+ * @returns IPRT status code.
+ * @retval  VERR_NOT_SUPPORTED see RTR0MemObjProtect.
+ *
+ * @param   pMem            The memory object.
+ * @param   offSub          Offset into the memory object. Page aligned.
+ * @param   cbSub           Number of bytes to change the protection of. Page
+ *                          aligned.
+ * @param   fProt           Combination of RTMEM_PROT_* flags.
+ */
+DECLHIDDEN(int) rtR0MemObjNativeProtect(PRTR0MEMOBJINTERNAL pMem, size_t offSub, size_t cbSub, uint32_t fProt);
+
+/**
+ * Get the physical address of an page in the memory object.
+ *
+ * @returns The physical address.
+ * @returns NIL_RTHCPHYS if the object doesn't contain fixed physical pages.
+ * @returns NIL_RTHCPHYS if the iPage is out of range.
+ * @returns NIL_RTHCPHYS if the object handle isn't valid.
+ * @param   pMem            The ring-0 memory object handle.
+ * @param   iPage           The page number within the object (valid).
+ */
+DECLHIDDEN(RTHCPHYS) rtR0MemObjNativeGetPagePhysAddr(PRTR0MEMOBJINTERNAL pMem, size_t iPage);
+
+DECLHIDDEN(PRTR0MEMOBJINTERNAL) rtR0MemObjNew(size_t cbSelf, RTR0MEMOBJTYPE enmType, void *pv, size_t cb);
+DECLHIDDEN(void) rtR0MemObjDelete(PRTR0MEMOBJINTERNAL pMem);
+
+/** @} */
+
+RT_C_DECLS_END
+
+#endif
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/include/internal/process.h
@@ -0,0 +1,69 @@
+/* $Id: process.h $ */
+/** @file
+ * IPRT - Internal RTProc header.
+ */
+
+/*
+ * Copyright (C) 2006-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+#ifndef ___internal_process_h
+#define ___internal_process_h
+
+#include <iprt/process.h>
+#include <iprt/param.h>
+
+RT_C_DECLS_BEGIN
+
+extern DECLHIDDEN(RTPROCESS)        g_ProcessSelf;
+extern DECLHIDDEN(RTPROCPRIORITY)   g_enmProcessPriority;
+extern DECLHIDDEN(char)             g_szrtProcExePath[RTPATH_MAX];
+extern DECLHIDDEN(size_t)           g_cchrtProcExePath;
+extern DECLHIDDEN(size_t)           g_cchrtProcDir;
+extern DECLHIDDEN(size_t)           g_offrtProcName;
+extern DECLHIDDEN(bool volatile)    g_frtAtExitCalled;
+
+/**
+ * Validates and sets the process priority.
+ * This will check that all rtThreadNativeSetPriority() will success for all the
+ * thread types when applied to the current thread.
+ *
+ * @returns iprt status code.
+ * @param   enmPriority     The priority to validate and set.
+ * @remark  Located in sched.
+ */
+DECLHIDDEN(int) rtProcNativeSetPriority(RTPROCPRIORITY enmPriority);
+
+/**
+ * Determines the full path to the executable image.
+ *
+ * This is called by rtR3Init.
+ *
+ * @returns IPRT status code.
+ *
+ * @param   pszPath     Pointer to the g_szrtProcExePath buffer.
+ * @param   cchPath     The size of the buffer.
+ */
+DECLHIDDEN(int) rtProcInitExePath(char *pszPath, size_t cchPath);
+
+RT_C_DECLS_END
+
+#endif
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/include/internal/sched.h
@@ -0,0 +1,47 @@
+/* $Id: sched.h $ */
+/** @file
+ * IPRT - Internal RTSched header.
+ */
+
+/*
+ * Copyright (C) 2006-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+#ifndef ___internal_sched_h
+#define ___internal_sched_h
+
+#include <iprt/thread.h>
+#include "internal/process.h"
+#include "internal/thread.h"
+
+RT_C_DECLS_BEGIN
+
+/**
+ * Calculate the scheduling properties for all the threads in the default
+ * process priority, assuming the current thread have the type enmType.
+ *
+ * @returns iprt status code.
+ * @param   enmType     The thread type to be assumed for the current thread.
+ */
+DECLHIDDEN(int) rtSchedNativeCalcDefaultPriority(RTTHREADTYPE enmType);
+
+RT_C_DECLS_END
+
+#endif
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/include/internal/string.h
@@ -0,0 +1,88 @@
+/* $Id: string.h $ */
+/** @file
+ * IPRT - Internal RTStr header.
+ */
+
+/*
+ * Copyright (C) 2006-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+#ifndef ___internal_string_h
+#define ___internal_string_h
+
+#include <iprt/string.h>
+
+RT_C_DECLS_BEGIN
+
+/** @def RTSTR_STRICT
+ * Enables strict assertions on bad string encodings.
+ */
+#ifdef DOXYGEN_RUNNING
+# define RTSTR_STRICT
+#endif
+/*#define RTSTR_STRICT*/
+
+#ifdef RTSTR_STRICT
+# define RTStrAssertMsgFailed(msg)              AssertMsgFailed(msg)
+# define RTStrAssertMsgReturn(expr, msg, rc)    AssertMsgReturn(expr, msg, rc)
+#else
+# define RTStrAssertMsgFailed(msg)              do { } while (0)
+# define RTStrAssertMsgReturn(expr, msg, rc)    do { if (!(expr)) return rc; } while (0)
+#endif
+
+DECLHIDDEN(size_t) rtstrFormatRt(PFNRTSTROUTPUT pfnOutput, void *pvArgOutput, const char **ppszFormat, va_list *pArgs,
+                                 int cchWidth, int cchPrecision, unsigned fFlags, char chArgSize);
+DECLHIDDEN(size_t) rtstrFormatType(PFNRTSTROUTPUT pfnOutput, void *pvArgOutput, const char **ppszFormat, va_list *pArgs,
+                                   int cchWidth, int cchPrecision, unsigned fFlags, char chArgSize);
+
+#ifdef RT_WITH_ICONV_CACHE
+DECLHIDDEN(void) rtStrIconvCacheInit(struct RTTHREADINT *pThread);
+DECLHIDDEN(void) rtStrIconvCacheDestroy(struct RTTHREADINT *pThread);
+#endif
+
+/**
+ * Indexes into RTTHREADINT::ahIconvs
+ */
+typedef enum RTSTRICONV
+{
+    /** UTF-8 to the locale codeset (LC_CTYPE). */
+    RTSTRICONV_UTF8_TO_LOCALE = 0,
+    /** The locale codeset (LC_CTYPE) to UTF-8. */
+    RTSTRICONV_LOCALE_TO_UTF8,
+    /** UTF-8 to the filesystem codeset - if different from the locale codeset. */
+    RTSTRICONV_UTF8_TO_FS,
+    /** The filesystem codeset to UTF-8. */
+    RTSTRICONV_FS_TO_UTF8,
+    /** The end of the valid indexes. */
+    RTSTRICONV_END
+} RTSTRICONV;
+
+DECLHIDDEN(int) rtStrConvert(const char *pchInput, size_t cchInput, const char *pszInputCS,
+                             char **ppszOutput, size_t cbOutput, const char *pszOutputCS,
+                             unsigned cFactor, RTSTRICONV enmCacheIdx);
+DECLHIDDEN(const char *) rtStrGetLocaleCodeset(void);
+DECLHIDDEN(int) rtUtf8Length(const char *psz, size_t cch, size_t *pcuc, size_t *pcchActual);
+
+DECLHIDDEN(int) rtStrToIpAddr6Str(const char *psz, char *pszAddrOut, size_t addrOutSize, char *pszPortOut, size_t portOutSize, bool followRfc);
+
+RT_C_DECLS_END
+
+#endif
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/include/internal/thread.h
@@ -0,0 +1,275 @@
+/* $Id: thread.h $ */
+/** @file
+ * IPRT - Internal RTThread header.
+ */
+
+/*
+ * Copyright (C) 2006-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+#ifndef ___thread_h
+#define ___thread_h
+
+#include <iprt/types.h>
+#include <iprt/thread.h>
+#include <iprt/avl.h>
+#ifdef IN_RING3
+# include <iprt/process.h>
+# include <iprt/critsect.h>
+#endif
+#include "internal/lockvalidator.h"
+#include "internal/magics.h"
+#ifdef RT_WITH_ICONV_CACHE
+# include "internal/string.h"
+#endif
+
+RT_C_DECLS_BEGIN
+
+
+/** Max thread name length. */
+#define RTTHREAD_NAME_LEN       16
+#ifdef IPRT_WITH_GENERIC_TLS
+/** The number of TLS entries for the generic implementation. */
+# define RTTHREAD_TLS_ENTRIES   64
+#endif
+
+/**
+ * Internal representation of a thread.
+ */
+typedef struct RTTHREADINT
+{
+    /** Avl node core - the key is the native thread id. */
+    AVLPVNODECORE           Core;
+    /** Magic value (RTTHREADINT_MAGIC). */
+    uint32_t                u32Magic;
+    /** Reference counter. */
+    uint32_t volatile       cRefs;
+    /** The current thread state. */
+    RTTHREADSTATE volatile  enmState;
+    /** Set when really sleeping. */
+    bool volatile           fReallySleeping;
+#if defined(RT_OS_WINDOWS) && defined(IN_RING3)
+    /** The thread handle
+     * This is not valid until the create function has returned! */
+    uintptr_t               hThread;
+#endif
+#if defined(RT_OS_LINUX) && defined(IN_RING3)
+    /** The thread ID.
+     * This is not valid before rtThreadMain has been called by the new thread.  */
+    pid_t                   tid;
+#endif
+#if defined(RT_OS_SOLARIS) && defined(IN_RING0)
+    /** Debug thread ID needed for thread_join. */
+    uint64_t                tid;
+#endif
+    /** The user event semaphore. */
+    RTSEMEVENTMULTI         EventUser;
+    /** The terminated event semaphore. */
+    RTSEMEVENTMULTI         EventTerminated;
+    /** The thread type. */
+    RTTHREADTYPE            enmType;
+    /** The thread creation flags. (RTTHREADFLAGS) */
+    unsigned                fFlags;
+    /** Internal flags. (RTTHREADINT_FLAGS_ *) */
+    uint32_t                fIntFlags;
+    /** The result code. */
+    int                     rc;
+    /** Thread function. */
+    PFNRTTHREAD             pfnThread;
+    /** Thread function argument. */
+    void                   *pvUser;
+    /** Actual stack size. */
+    size_t                  cbStack;
+#ifdef IN_RING3
+    /** The lock validator data. */
+    RTLOCKVALPERTHREAD      LockValidator;
+#endif /* IN_RING3 */
+#ifdef RT_WITH_ICONV_CACHE
+    /** Handle cache for iconv.
+     * @remarks ASSUMES sizeof(void *) >= sizeof(iconv_t). */
+    void *ahIconvs[RTSTRICONV_END];
+#endif
+#ifdef IPRT_WITH_GENERIC_TLS
+    /** The TLS entries for this thread. */
+    void                   *apvTlsEntries[RTTHREAD_TLS_ENTRIES];
+#endif
+    /** Thread name. */
+    char                    szName[RTTHREAD_NAME_LEN];
+} RTTHREADINT;
+/** Pointer to the internal representation of a thread. */
+typedef RTTHREADINT *PRTTHREADINT;
+
+
+/** @name RTTHREADINT::fIntFlags Masks and Bits.
+ * @{ */
+/** Set if the thread is an alien thread.
+ * Clear if the thread was created by IPRT. */
+#define RTTHREADINT_FLAGS_ALIEN      RT_BIT(0)
+/** Set if the thread has terminated.
+ * Clear if the thread is running. */
+#define RTTHREADINT_FLAGS_TERMINATED RT_BIT(1)
+/** This bit is set if the thread is in the AVL tree. */
+#define RTTHREADINT_FLAG_IN_TREE_BIT 2
+/** @copydoc RTTHREADINT_FLAG_IN_TREE_BIT */
+#define RTTHREADINT_FLAG_IN_TREE     RT_BIT(RTTHREADINT_FLAG_IN_TREE_BIT)
+/** Set if it's the main thread. */
+#define RTTHREADINT_FLAGS_MAIN       RT_BIT(3)
+/** @} */
+
+
+/**
+ * Initialize the native part of the thread management.
+ *
+ * Generally a TLS entry will be allocated at this point (Ring-3).
+ *
+ * @returns iprt status code.
+ */
+DECLHIDDEN(int) rtThreadNativeInit(void);
+
+#ifdef IN_RING3
+/**
+ * Called when IPRT was first initialized in unobtrusive mode and later changed
+ * to obtrustive.
+ *
+ * This is only applicable in ring-3.
+ */
+DECLHIDDEN(void) rtThreadNativeReInitObtrusive(void);
+#endif
+
+/**
+ * Create a native thread.
+ * This creates the thread as described in pThreadInt and stores the thread id in *pThread.
+ *
+ * @returns iprt status code.
+ * @param   pThreadInt      The thread data structure for the thread.
+ * @param   pNativeThread   Where to store the native thread identifier.
+ */
+DECLHIDDEN(int) rtThreadNativeCreate(PRTTHREADINT pThreadInt, PRTNATIVETHREAD pNativeThread);
+
+/**
+ * Adopts a thread, this is called immediately after allocating the
+ * thread structure.
+ *
+ * @param   pThread     Pointer to the thread structure.
+ */
+DECLHIDDEN(int) rtThreadNativeAdopt(PRTTHREADINT pThread);
+
+/**
+ * Called from rtThreadDestroy so that the TLS entry and any native data in the
+ * thread structure can be cleared.
+ *
+ * @param   pThread         The thread structure.
+ */
+DECLHIDDEN(void) rtThreadNativeDestroy(PRTTHREADINT pThread);
+
+#ifdef IN_RING0
+/**
+ * Called from rtThreadWait when the last thread has completed in order to make
+ * sure it's all the way out of IPRT before RTR0Term is called.
+ *
+ * @param   pThread     The thread structure.
+ */
+DECLHIDDEN(void) rtThreadNativeWaitKludge(PRTTHREADINT pThread);
+#endif
+
+
+/**
+ * Sets the priority of the thread according to the thread type
+ * and current process priority.
+ *
+ * The RTTHREADINT::enmType member has not yet been updated and will be updated by
+ * the caller on a successful return.
+ *
+ * @returns iprt status code.
+ * @param   pThread     The thread in question.
+ * @param   enmType     The thread type.
+ * @remark  Located in sched.
+ */
+DECLHIDDEN(int) rtThreadNativeSetPriority(PRTTHREADINT pThread, RTTHREADTYPE enmType);
+
+#ifdef IN_RING3
+# ifdef RT_OS_WINDOWS
+/**
+ * Callback for when a native thread is detaching.
+ *
+ * It give the Win32/64 backend a chance to terminate alien
+ * threads properly.
+ */
+DECLHIDDEN(void) rtThreadNativeDetach(void);
+
+/**
+ * Internal function for informing the debugger about a thread.
+ * @param   pThread     The thread. May differ from the calling thread.
+ */
+DECLHIDDEN(void) rtThreadNativeInformDebugger(PRTTHREADINT pThread);
+# endif
+#endif /* IN_RING3 */
+
+
+/* thread.cpp */
+DECLCALLBACK(DECLHIDDEN(int)) rtThreadMain(PRTTHREADINT pThread, RTNATIVETHREAD NativeThread, const char *pszThreadName);
+DECLHIDDEN(uint32_t)     rtThreadRelease(PRTTHREADINT pThread);
+DECLHIDDEN(void)         rtThreadTerminate(PRTTHREADINT pThread, int rc);
+DECLHIDDEN(PRTTHREADINT) rtThreadGetByNative(RTNATIVETHREAD NativeThread);
+DECLHIDDEN(PRTTHREADINT) rtThreadGet(RTTHREAD Thread);
+DECLHIDDEN(int)          rtThreadInit(void);
+#ifdef IN_RING3
+DECLHIDDEN(void)         rtThreadReInitObtrusive(void);
+#endif
+DECLHIDDEN(void)         rtThreadTerm(void);
+DECLHIDDEN(void)         rtThreadInsert(PRTTHREADINT pThread, RTNATIVETHREAD NativeThread);
+#ifdef IN_RING3
+DECLHIDDEN(int)          rtThreadDoSetProcPriority(RTPROCPRIORITY enmPriority);
+#endif /* !IN_RING0 */
+#ifdef IPRT_WITH_GENERIC_TLS
+DECLHIDDEN(void)         rtThreadClearTlsEntry(RTTLS iTls);
+DECLHIDDEN(void)         rtThreadTlsDestruction(PRTTHREADINT pThread); /* in tls-generic.cpp */
+#endif
+
+#ifdef ___iprt_asm_h
+
+/**
+ * Gets the thread state.
+ *
+ * @returns The thread state.
+ * @param   pThread             The thread.
+ */
+DECLINLINE(RTTHREADSTATE) rtThreadGetState(PRTTHREADINT pThread)
+{
+    return pThread->enmState;
+}
+
+/**
+ * Sets the thread state.
+ *
+ * @param   pThread             The thread.
+ * @param   enmNewState         The new thread state.
+ */
+DECLINLINE(void) rtThreadSetState(PRTTHREADINT pThread, RTTHREADSTATE enmNewState)
+{
+    AssertCompile(sizeof(pThread->enmState) == sizeof(uint32_t));
+    ASMAtomicWriteU32((uint32_t volatile *)&pThread->enmState, enmNewState);
+}
+
+#endif
+
+RT_C_DECLS_END
+
+#endif
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/include/internal/time.h
@@ -0,0 +1,44 @@
+/* $Id: time.h $ */
+/** @file
+ * IPRT - Internal RTTime header
+ */
+
+/*
+ * Copyright (C) 2006-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+#ifndef ___internal_time_h
+#define ___internal_time_h
+
+#include <iprt/types.h>
+
+RT_C_DECLS_BEGIN
+
+#if defined(IN_RING3) || defined(IN_RC)
+
+extern DECLHIDDEN(uint64_t) g_u64ProgramStartNanoTS;
+extern DECLHIDDEN(uint64_t) g_u64ProgramStartMicroTS;
+extern DECLHIDDEN(uint64_t) g_u64ProgramStartMilliTS;
+
+#endif
+
+RT_C_DECLS_END
+
+#endif
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/include/iprt/alloc.h
@@ -0,0 +1,33 @@
+/** @file
+ * IPRT - Memory Allocation.
+ */
+
+/*
+ * Copyright (C) 2006-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+#ifndef ___iprt_alloc_h
+#define ___iprt_alloc_h
+
+/* Forwarding to the canonical header. */
+#include <iprt/mem.h>
+
+#endif
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/include/iprt/alloca.h
@@ -0,0 +1,56 @@
+/** @file
+ * IPRT - alloca().
+ */
+
+/*
+ * Copyright (C) 2006-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+#ifndef ___iprt_alloca_h
+#define ___iprt_alloca_h
+
+#if defined(IN_RC) || defined(IN_RING0_AGNOSTIC)
+# error "No alloca() in raw-mode and agnostic ring-0 context as it may have external dependencies like libgcc."
+#endif
+
+/*
+ * If there are more difficult platforms out there, we'll do OS
+ * specific #ifdefs. But for now we'll just include the headers
+ * which normally contains the alloca() prototype.
+ * When we're in kernel territory it starts getting a bit more
+ * interesting of course...
+ */
+#if defined(IN_RING0) \
+ && (defined(RT_OS_DARWIN) || defined(RT_OS_LINUX) || defined(RT_OS_SOLARIS) || defined(RT_OS_FREEBSD))
+/* ASSUMES GNU C */
+# define alloca(cb) __builtin_alloca(cb)
+
+#else
+# include <stdlib.h>
+# if !defined(RT_OS_DARWIN) && !defined(RT_OS_FREEBSD)
+#  include <malloc.h>
+# endif
+# if defined(RT_OS_SOLARIS) || defined(RT_OS_LINUX)
+#  include <alloca.h>
+# endif
+#endif
+
+#endif
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/include/iprt/asm-amd64-x86.h
@@ -0,0 +1,3318 @@
+/** @file
+ * IPRT - AMD64 and x86 Specific Assembly Functions.
+ */
+
+/*
+ * Copyright (C) 2006-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+#ifndef ___iprt_asm_amd64_x86_h
+#define ___iprt_asm_amd64_x86_h
+
+#include <iprt/types.h>
+#include <iprt/assert.h>
+#if !defined(RT_ARCH_AMD64) && !defined(RT_ARCH_X86)
+# error "Not on AMD64 or x86"
+#endif
+
+#if defined(_MSC_VER) && RT_INLINE_ASM_USES_INTRIN
+# include <intrin.h>
+   /* Emit the intrinsics at all optimization levels. */
+# pragma intrinsic(_ReadWriteBarrier)
+# pragma intrinsic(__cpuid)
+# pragma intrinsic(_enable)
+# pragma intrinsic(_disable)
+# pragma intrinsic(__rdtsc)
+# pragma intrinsic(__readmsr)
+# pragma intrinsic(__writemsr)
+# pragma intrinsic(__outbyte)
+# pragma intrinsic(__outbytestring)
+# pragma intrinsic(__outword)
+# pragma intrinsic(__outwordstring)
+# pragma intrinsic(__outdword)
+# pragma intrinsic(__outdwordstring)
+# pragma intrinsic(__inbyte)
+# pragma intrinsic(__inbytestring)
+# pragma intrinsic(__inword)
+# pragma intrinsic(__inwordstring)
+# pragma intrinsic(__indword)
+# pragma intrinsic(__indwordstring)
+# pragma intrinsic(__invlpg)
+# pragma intrinsic(__wbinvd)
+# pragma intrinsic(__readcr0)
+# pragma intrinsic(__readcr2)
+# pragma intrinsic(__readcr3)
+# pragma intrinsic(__readcr4)
+# pragma intrinsic(__writecr0)
+# pragma intrinsic(__writecr3)
+# pragma intrinsic(__writecr4)
+# pragma intrinsic(__readdr)
+# pragma intrinsic(__writedr)
+# ifdef RT_ARCH_AMD64
+#  pragma intrinsic(__readcr8)
+#  pragma intrinsic(__writecr8)
+# endif
+# if RT_INLINE_ASM_USES_INTRIN >= 15
+#  pragma intrinsic(__readeflags)
+#  pragma intrinsic(__writeeflags)
+#  pragma intrinsic(__rdtscp)
+# endif
+#endif
+
+
+
+/** @defgroup grp_rt_asm_amd64_x86  AMD64 and x86 Specific ASM Routines
+ * @ingroup grp_rt_asm
+ * @{
+ */
+
+/** @todo find a more proper place for these structures? */
+
+#pragma pack(1)
+/** IDTR */
+typedef struct RTIDTR
+{
+    /** Size of the IDT. */
+    uint16_t    cbIdt;
+    /** Address of the IDT. */
+    uintptr_t   pIdt;
+} RTIDTR, *PRTIDTR;
+#pragma pack()
+
+#pragma pack(1)
+/** @internal */
+typedef struct RTIDTRALIGNEDINT
+{
+    /** Alignment padding.   */
+    uint8_t     au16Padding[ARCH_BITS == 64 ? 3 : 1];
+    /** The IDTR structure.  */
+    RTIDTR      Idtr;
+} RTIDTRALIGNEDINT;
+#pragma pack()
+
+/** Wrapped RTIDTR for preventing misalignment exceptions. */
+typedef union RTIDTRALIGNED
+{
+    /** Try make sure this structure has optimal alignment. */
+    uint64_t            auAlignmentHack[ARCH_BITS == 64 ? 2 : 1];
+    /** Aligned structure. */
+    RTIDTRALIGNEDINT    s;
+} RTIDTRALIGNED;
+AssertCompileSize(RTIDTRALIGNED, ARCH_BITS * 2 / 8);
+/** Pointer to a an RTIDTR alignment wrapper. */
+typedef RTIDTRALIGNED *PRIDTRALIGNED;
+
+
+#pragma pack(1)
+/** GDTR */
+typedef struct RTGDTR
+{
+    /** Size of the GDT. */
+    uint16_t    cbGdt;
+    /** Address of the GDT. */
+    uintptr_t   pGdt;
+} RTGDTR, *PRTGDTR;
+#pragma pack()
+
+#pragma pack(1)
+/** @internal */
+typedef struct RTGDTRALIGNEDINT
+{
+    /** Alignment padding.   */
+    uint8_t     au16Padding[ARCH_BITS == 64 ? 3 : 1];
+    /** The GDTR structure.  */
+    RTGDTR      Gdtr;
+} RTGDTRALIGNEDINT;
+#pragma pack()
+
+/** Wrapped RTGDTR for preventing misalignment exceptions. */
+typedef union RTGDTRALIGNED
+{
+    /** Try make sure this structure has optimal alignment. */
+    uint64_t            auAlignmentHack[ARCH_BITS == 64 ? 2 : 1];
+    /** Aligned structure. */
+    RTGDTRALIGNEDINT    s;
+} RTGDTRALIGNED;
+AssertCompileSize(RTGDTRALIGNED, ARCH_BITS * 2 / 8);
+/** Pointer to a an RTGDTR alignment wrapper. */
+typedef RTGDTRALIGNED *PRGDTRALIGNED;
+
+
+/**
+ * Gets the content of the IDTR CPU register.
+ * @param   pIdtr   Where to store the IDTR contents.
+ */
+#if RT_INLINE_ASM_EXTERNAL
+DECLASM(void) ASMGetIDTR(PRTIDTR pIdtr);
+#else
+DECLINLINE(void) ASMGetIDTR(PRTIDTR pIdtr)
+{
+# if RT_INLINE_ASM_GNU_STYLE
+    __asm__ __volatile__("sidt %0" : "=m" (*pIdtr));
+# else
+    __asm
+    {
+#  ifdef RT_ARCH_AMD64
+        mov     rax, [pIdtr]
+        sidt    [rax]
+#  else
+        mov     eax, [pIdtr]
+        sidt    [eax]
+#  endif
+    }
+# endif
+}
+#endif
+
+
+/**
+ * Gets the content of the IDTR.LIMIT CPU register.
+ * @returns IDTR limit.
+ */
+#if RT_INLINE_ASM_EXTERNAL
+DECLASM(uint16_t) ASMGetIdtrLimit(void);
+#else
+DECLINLINE(uint16_t) ASMGetIdtrLimit(void)
+{
+    RTIDTRALIGNED TmpIdtr;
+# if RT_INLINE_ASM_GNU_STYLE
+    __asm__ __volatile__("sidt %0" : "=m" (TmpIdtr.s.Idtr));
+# else
+    __asm
+    {
+        sidt    [TmpIdtr.s.Idtr]
+    }
+# endif
+    return TmpIdtr.s.Idtr.cbIdt;
+}
+#endif
+
+
+/**
+ * Sets the content of the IDTR CPU register.
+ * @param   pIdtr   Where to load the IDTR contents from
+ */
+#if RT_INLINE_ASM_EXTERNAL
+DECLASM(void) ASMSetIDTR(const RTIDTR *pIdtr);
+#else
+DECLINLINE(void) ASMSetIDTR(const RTIDTR *pIdtr)
+{
+# if RT_INLINE_ASM_GNU_STYLE
+    __asm__ __volatile__("lidt %0" : : "m" (*pIdtr));
+# else
+    __asm
+    {
+#  ifdef RT_ARCH_AMD64
+        mov     rax, [pIdtr]
+        lidt    [rax]
+#  else
+        mov     eax, [pIdtr]
+        lidt    [eax]
+#  endif
+    }
+# endif
+}
+#endif
+
+
+/**
+ * Gets the content of the GDTR CPU register.
+ * @param   pGdtr   Where to store the GDTR contents.
+ */
+#if RT_INLINE_ASM_EXTERNAL
+DECLASM(void) ASMGetGDTR(PRTGDTR pGdtr);
+#else
+DECLINLINE(void) ASMGetGDTR(PRTGDTR pGdtr)
+{
+# if RT_INLINE_ASM_GNU_STYLE
+    __asm__ __volatile__("sgdt %0" : "=m" (*pGdtr));
+# else
+    __asm
+    {
+#  ifdef RT_ARCH_AMD64
+        mov     rax, [pGdtr]
+        sgdt    [rax]
+#  else
+        mov     eax, [pGdtr]
+        sgdt    [eax]
+#  endif
+    }
+# endif
+}
+#endif
+
+
+/**
+ * Sets the content of the GDTR CPU register.
+ * @param   pGdtr   Where to load the GDTR contents from
+ */
+#if RT_INLINE_ASM_EXTERNAL
+DECLASM(void) ASMSetGDTR(const RTGDTR *pGdtr);
+#else
+DECLINLINE(void) ASMSetGDTR(const RTGDTR *pGdtr)
+{
+# if RT_INLINE_ASM_GNU_STYLE
+    __asm__ __volatile__("lgdt %0" : : "m" (*pGdtr));
+# else
+    __asm
+    {
+#  ifdef RT_ARCH_AMD64
+        mov     rax, [pGdtr]
+        lgdt    [rax]
+#  else
+        mov     eax, [pGdtr]
+        lgdt    [eax]
+#  endif
+    }
+# endif
+}
+#endif
+
+
+
+/**
+ * Get the cs register.
+ * @returns cs.
+ */
+#if RT_INLINE_ASM_EXTERNAL
+DECLASM(RTSEL) ASMGetCS(void);
+#else
+DECLINLINE(RTSEL) ASMGetCS(void)
+{
+    RTSEL SelCS;
+# if RT_INLINE_ASM_GNU_STYLE
+    __asm__ __volatile__("movw  %%cs, %0\n\t" : "=r" (SelCS));
+# else
+    __asm
+    {
+        mov     ax, cs
+        mov     [SelCS], ax
+    }
+# endif
+    return SelCS;
+}
+#endif
+
+
+/**
+ * Get the DS register.
+ * @returns DS.
+ */
+#if RT_INLINE_ASM_EXTERNAL
+DECLASM(RTSEL) ASMGetDS(void);
+#else
+DECLINLINE(RTSEL) ASMGetDS(void)
+{
+    RTSEL SelDS;
+# if RT_INLINE_ASM_GNU_STYLE
+    __asm__ __volatile__("movw  %%ds, %0\n\t" : "=r" (SelDS));
+# else
+    __asm
+    {
+        mov     ax, ds
+        mov     [SelDS], ax
+    }
+# endif
+    return SelDS;
+}
+#endif
+
+
+/**
+ * Get the ES register.
+ * @returns ES.
+ */
+#if RT_INLINE_ASM_EXTERNAL
+DECLASM(RTSEL) ASMGetES(void);
+#else
+DECLINLINE(RTSEL) ASMGetES(void)
+{
+    RTSEL SelES;
+# if RT_INLINE_ASM_GNU_STYLE
+    __asm__ __volatile__("movw  %%es, %0\n\t" : "=r" (SelES));
+# else
+    __asm
+    {
+        mov     ax, es
+        mov     [SelES], ax
+    }
+# endif
+    return SelES;
+}
+#endif
+
+
+/**
+ * Get the FS register.
+ * @returns FS.
+ */
+#if RT_INLINE_ASM_EXTERNAL
+DECLASM(RTSEL) ASMGetFS(void);
+#else
+DECLINLINE(RTSEL) ASMGetFS(void)
+{
+    RTSEL SelFS;
+# if RT_INLINE_ASM_GNU_STYLE
+    __asm__ __volatile__("movw  %%fs, %0\n\t" : "=r" (SelFS));
+# else
+    __asm
+    {
+        mov     ax, fs
+        mov     [SelFS], ax
+    }
+# endif
+    return SelFS;
+}
+# endif
+
+
+/**
+ * Get the GS register.
+ * @returns GS.
+ */
+#if RT_INLINE_ASM_EXTERNAL
+DECLASM(RTSEL) ASMGetGS(void);
+#else
+DECLINLINE(RTSEL) ASMGetGS(void)
+{
+    RTSEL SelGS;
+# if RT_INLINE_ASM_GNU_STYLE
+    __asm__ __volatile__("movw  %%gs, %0\n\t" : "=r" (SelGS));
+# else
+    __asm
+    {
+        mov     ax, gs
+        mov     [SelGS], ax
+    }
+# endif
+    return SelGS;
+}
+#endif
+
+
+/**
+ * Get the SS register.
+ * @returns SS.
+ */
+#if RT_INLINE_ASM_EXTERNAL
+DECLASM(RTSEL) ASMGetSS(void);
+#else
+DECLINLINE(RTSEL) ASMGetSS(void)
+{
+    RTSEL SelSS;
+# if RT_INLINE_ASM_GNU_STYLE
+    __asm__ __volatile__("movw  %%ss, %0\n\t" : "=r" (SelSS));
+# else
+    __asm
+    {
+        mov     ax, ss
+        mov     [SelSS], ax
+    }
+# endif
+    return SelSS;
+}
+#endif
+
+
+/**
+ * Get the TR register.
+ * @returns TR.
+ */
+#if RT_INLINE_ASM_EXTERNAL
+DECLASM(RTSEL) ASMGetTR(void);
+#else
+DECLINLINE(RTSEL) ASMGetTR(void)
+{
+    RTSEL SelTR;
+# if RT_INLINE_ASM_GNU_STYLE
+    __asm__ __volatile__("str %w0\n\t" : "=r" (SelTR));
+# else
+    __asm
+    {
+        str     ax
+        mov     [SelTR], ax
+    }
+# endif
+    return SelTR;
+}
+#endif
+
+
+/**
+ * Get the LDTR register.
+ * @returns LDTR.
+ */
+#if RT_INLINE_ASM_EXTERNAL
+DECLASM(RTSEL) ASMGetLDTR(void);
+#else
+DECLINLINE(RTSEL) ASMGetLDTR(void)
+{
+    RTSEL SelLDTR;
+# if RT_INLINE_ASM_GNU_STYLE
+    __asm__ __volatile__("sldt %w0\n\t" : "=r" (SelLDTR));
+# else
+    __asm
+    {
+        sldt    ax
+        mov     [SelLDTR], ax
+    }
+# endif
+    return SelLDTR;
+}
+#endif
+
+
+/**
+ * Get the access rights for the segment selector.
+ *
+ * @returns The access rights on success or UINT32_MAX on failure.
+ * @param   uSel        The selector value.
+ *
+ * @remarks Using UINT32_MAX for failure is chosen because valid access rights
+ *          always have bits 0:7 as 0 (on both Intel & AMD).
+ */
+#if RT_INLINE_ASM_EXTERNAL
+DECLASM(uint32_t) ASMGetSegAttr(uint32_t uSel);
+#else
+DECLINLINE(uint32_t) ASMGetSegAttr(uint32_t uSel)
+{
+    uint32_t uAttr;
+    /* LAR only accesses 16-bit of the source operand, but eax for the
+       destination operand is required for getting the full 32-bit access rights. */
+# if RT_INLINE_ASM_GNU_STYLE
+    __asm__ __volatile__("lar %1, %%eax\n\t"
+                         "jz done%=\n\t"
+                         "movl $0xffffffff, %%eax\n\t"
+                         "done%=:\n\t"
+                         "movl %%eax, %0\n\t"
+                         : "=r" (uAttr)
+                         : "r" (uSel)
+                         : "cc", "%eax");
+# else
+    __asm
+    {
+        lar     eax, [uSel]
+        jz      done
+        mov     eax, 0ffffffffh
+        done:
+        mov     [uAttr], eax
+    }
+# endif
+    return uAttr;
+}
+#endif
+
+
+/**
+ * Get the [RE]FLAGS register.
+ * @returns [RE]FLAGS.
+ */
+#if RT_INLINE_ASM_EXTERNAL && RT_INLINE_ASM_USES_INTRIN < 15
+DECLASM(RTCCUINTREG) ASMGetFlags(void);
+#else
+DECLINLINE(RTCCUINTREG) ASMGetFlags(void)
+{
+    RTCCUINTREG uFlags;
+# if RT_INLINE_ASM_GNU_STYLE
+#  ifdef RT_ARCH_AMD64
+    __asm__ __volatile__("pushfq\n\t"
+                         "popq  %0\n\t"
+                         : "=r" (uFlags));
+#  else
+    __asm__ __volatile__("pushfl\n\t"
+                         "popl  %0\n\t"
+                         : "=r" (uFlags));
+#  endif
+# elif RT_INLINE_ASM_USES_INTRIN >= 15
+    uFlags = __readeflags();
+# else
+    __asm
+    {
+#  ifdef RT_ARCH_AMD64
+        pushfq
+        pop  [uFlags]
+#  else
+        pushfd
+        pop  [uFlags]
+#  endif
+    }
+# endif
+    return uFlags;
+}
+#endif
+
+
+/**
+ * Set the [RE]FLAGS register.
+ * @param   uFlags      The new [RE]FLAGS value.
+ */
+#if RT_INLINE_ASM_EXTERNAL && RT_INLINE_ASM_USES_INTRIN < 15
+DECLASM(void) ASMSetFlags(RTCCUINTREG uFlags);
+#else
+DECLINLINE(void) ASMSetFlags(RTCCUINTREG uFlags)
+{
+# if RT_INLINE_ASM_GNU_STYLE
+#  ifdef RT_ARCH_AMD64
+    __asm__ __volatile__("pushq %0\n\t"
+                         "popfq\n\t"
+                         : : "g" (uFlags));
+#  else
+    __asm__ __volatile__("pushl %0\n\t"
+                         "popfl\n\t"
+                         : : "g" (uFlags));
+#  endif
+# elif RT_INLINE_ASM_USES_INTRIN >= 15
+    __writeeflags(uFlags);
+# else
+    __asm
+    {
+#  ifdef RT_ARCH_AMD64
+        push    [uFlags]
+        popfq
+#  else
+        push    [uFlags]
+        popfd
+#  endif
+    }
+# endif
+}
+#endif
+
+
+/**
+ * Modifies the [RE]FLAGS register.
+ * @returns Original value.
+ * @param   fAndEfl     Flags to keep (applied first).
+ * @param   fOrEfl      Flags to be set.
+ */
+#if RT_INLINE_ASM_EXTERNAL && RT_INLINE_ASM_USES_INTRIN < 15
+DECLASM(RTCCUINTREG) ASMChangeFlags(RTCCUINTREG fAndEfl, RTCCUINTREG fOrEfl);
+#else
+DECLINLINE(RTCCUINTREG) ASMChangeFlags(RTCCUINTREG fAndEfl, RTCCUINTREG fOrEfl)
+{
+    RTCCUINTREG fOldEfl;
+# if RT_INLINE_ASM_GNU_STYLE
+#  ifdef RT_ARCH_AMD64
+    __asm__ __volatile__("pushfq\n\t"
+                         "movq  (%%rsp), %0\n\t"
+                         "andq  %0, %1\n\t"
+                         "orq   %3, %1\n\t"
+                         "mov   %1, (%%rsp)\n\t"
+                         "popfq\n\t"
+                         : "=&r" (fOldEfl),
+                           "=r" (fAndEfl)
+                         : "1" (fAndEfl),
+                           "rn" (fOrEfl) );
+#  else
+    __asm__ __volatile__("pushfl\n\t"
+                         "movl  (%%esp), %0\n\t"
+                         "andl  %1, (%%esp)\n\t"
+                         "orl   %2, (%%esp)\n\t"
+                         "popfl\n\t"
+                         : "=&r" (fOldEfl)
+                         : "rn" (fAndEfl),
+                           "rn" (fOrEfl) );
+#  endif
+# elif RT_INLINE_ASM_USES_INTRIN >= 15
+    fOldEfl = __readeflags();
+    __writeeflags((fOldEfl & fAndEfl) | fOrEfl);
+# else
+    __asm
+    {
+#  ifdef RT_ARCH_AMD64
+        mov     rdx, [fAndEfl]
+        mov     rcx, [fOrEfl]
+        pushfq
+        mov     rax, [rsp]
+        and     rdx, rax
+        or      rdx, rcx
+        mov     [rsp], rdx
+        popfq
+        mov     [fOldEfl], rax
+#  else
+        mov     edx, [fAndEfl]
+        mov     ecx, [fOrEfl]
+        pushfd
+        mov     eax, [esp]
+        and     edx, eax
+        or      edx, ecx
+        mov     [esp], edx
+        popfd
+        mov     [fOldEfl], eax
+#  endif
+    }
+# endif
+    return fOldEfl;
+}
+#endif
+
+
+/**
+ * Modifies the [RE]FLAGS register by ORing in one or more flags.
+ * @returns Original value.
+ * @param   fOrEfl      The flags to be set (ORed in).
+ */
+#if RT_INLINE_ASM_EXTERNAL && RT_INLINE_ASM_USES_INTRIN < 15
+DECLASM(RTCCUINTREG) ASMAddFlags(RTCCUINTREG fOrEfl);
+#else
+DECLINLINE(RTCCUINTREG) ASMAddFlags(RTCCUINTREG fOrEfl)
+{
+    RTCCUINTREG fOldEfl;
+# if RT_INLINE_ASM_GNU_STYLE
+#  ifdef RT_ARCH_AMD64
+    __asm__ __volatile__("pushfq\n\t"
+                         "movq  (%%rsp), %0\n\t"
+                         "orq   %1, (%%rsp)\n\t"
+                         "popfq\n\t"
+                         : "=&r" (fOldEfl)
+                         : "rn" (fOrEfl) );
+#  else
+    __asm__ __volatile__("pushfl\n\t"
+                         "movl  (%%esp), %0\n\t"
+                         "orl   %1, (%%esp)\n\t"
+                         "popfl\n\t"
+                         : "=&r" (fOldEfl)
+                         : "rn" (fOrEfl) );
+#  endif
+# elif RT_INLINE_ASM_USES_INTRIN >= 15
+    fOldEfl = __readeflags();
+    __writeeflags(fOldEfl | fOrEfl);
+# else
+    __asm
+    {
+#  ifdef RT_ARCH_AMD64
+        mov     rcx, [fOrEfl]
+        pushfq
+        mov     rdx, [rsp]
+        or      [rsp], rcx
+        popfq
+        mov     [fOldEfl], rax
+#  else
+        mov     ecx, [fOrEfl]
+        pushfd
+        mov     edx, [esp]
+        or      [esp], ecx
+        popfd
+        mov     [fOldEfl], eax
+#  endif
+    }
+# endif
+    return fOldEfl;
+}
+#endif
+
+
+/**
+ * Modifies the [RE]FLAGS register by AND'ing out one or more flags.
+ * @returns Original value.
+ * @param   fAndEfl      The flags to keep.
+ */
+#if RT_INLINE_ASM_EXTERNAL && RT_INLINE_ASM_USES_INTRIN < 15
+DECLASM(RTCCUINTREG) ASMClearFlags(RTCCUINTREG fAndEfl);
+#else
+DECLINLINE(RTCCUINTREG) ASMClearFlags(RTCCUINTREG fAndEfl)
+{
+    RTCCUINTREG fOldEfl;
+# if RT_INLINE_ASM_GNU_STYLE
+#  ifdef RT_ARCH_AMD64
+    __asm__ __volatile__("pushfq\n\t"
+                         "movq  (%%rsp), %0\n\t"
+                         "andq  %1, (%%rsp)\n\t"
+                         "popfq\n\t"
+                         : "=&r" (fOldEfl)
+                         : "rn" (fAndEfl) );
+#  else
+    __asm__ __volatile__("pushfl\n\t"
+                         "movl  (%%esp), %0\n\t"
+                         "andl  %1, (%%esp)\n\t"
+                         "popfl\n\t"
+                         : "=&r" (fOldEfl)
+                         : "rn" (fAndEfl) );
+#  endif
+# elif RT_INLINE_ASM_USES_INTRIN >= 15
+    fOldEfl = __readeflags();
+    __writeeflags(fOldEfl & fAndEfl);
+# else
+    __asm
+    {
+#  ifdef RT_ARCH_AMD64
+        mov     rdx, [fAndEfl]
+        pushfq
+        mov     rdx, [rsp]
+        and     [rsp], rdx
+        popfq
+        mov     [fOldEfl], rax
+#  else
+        mov     edx, [fAndEfl]
+        pushfd
+        mov     edx, [esp]
+        and     [esp], edx
+        popfd
+        mov     [fOldEfl], eax
+#  endif
+    }
+# endif
+    return fOldEfl;
+}
+#endif
+
+
+/**
+ * Gets the content of the CPU timestamp counter register.
+ *
+ * @returns TSC.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(uint64_t) ASMReadTSC(void);
+#else
+DECLINLINE(uint64_t) ASMReadTSC(void)
+{
+    RTUINT64U u;
+# if RT_INLINE_ASM_GNU_STYLE
+    __asm__ __volatile__("rdtsc\n\t" : "=a" (u.s.Lo), "=d" (u.s.Hi));
+# else
+#  if RT_INLINE_ASM_USES_INTRIN
+    u.u = __rdtsc();
+#  else
+    __asm
+    {
+        rdtsc
+        mov     [u.s.Lo], eax
+        mov     [u.s.Hi], edx
+    }
+#  endif
+# endif
+    return u.u;
+}
+#endif
+
+
+/**
+ * Gets the content of the CPU timestamp counter register and the
+ * assoicated AUX value.
+ *
+ * @returns TSC.
+ * @param   puAux   Where to store the AUX value.
+ */
+#if RT_INLINE_ASM_EXTERNAL && RT_INLINE_ASM_USES_INTRIN < 15
+DECLASM(uint64_t) ASMReadTscWithAux(uint32_t *puAux);
+#else
+DECLINLINE(uint64_t) ASMReadTscWithAux(uint32_t *puAux)
+{
+    RTUINT64U u;
+# if RT_INLINE_ASM_GNU_STYLE
+    /* rdtscp is not supported by ancient linux build VM of course :-( */
+    /*__asm__ __volatile__("rdtscp\n\t" : "=a" (u.s.Lo), "=d" (u.s.Hi), "=c" (*puAux)); */
+    __asm__ __volatile__(".byte 0x0f,0x01,0xf9\n\t" : "=a" (u.s.Lo), "=d" (u.s.Hi), "=c" (*puAux));
+# else
+#  if RT_INLINE_ASM_USES_INTRIN >= 15
+    u.u = __rdtscp(puAux);
+#  else
+    __asm
+    {
+        rdtscp
+        mov     [u.s.Lo], eax
+        mov     [u.s.Hi], edx
+        mov     eax, [puAux]
+        mov     [eax], ecx
+    }
+#  endif
+# endif
+    return u.u;
+}
+#endif
+
+
+/**
+ * Performs the cpuid instruction returning all registers.
+ *
+ * @param   uOperator   CPUID operation (eax).
+ * @param   pvEAX       Where to store eax.
+ * @param   pvEBX       Where to store ebx.
+ * @param   pvECX       Where to store ecx.
+ * @param   pvEDX       Where to store edx.
+ * @remark  We're using void pointers to ease the use of special bitfield structures and such.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(void) ASMCpuId(uint32_t uOperator, void *pvEAX, void *pvEBX, void *pvECX, void *pvEDX);
+#else
+DECLINLINE(void) ASMCpuId(uint32_t uOperator, void *pvEAX, void *pvEBX, void *pvECX, void *pvEDX)
+{
+# if RT_INLINE_ASM_GNU_STYLE
+#  ifdef RT_ARCH_AMD64
+    RTCCUINTREG uRAX, uRBX, uRCX, uRDX;
+    __asm__ __volatile__ ("cpuid\n\t"
+                          : "=a" (uRAX),
+                            "=b" (uRBX),
+                            "=c" (uRCX),
+                            "=d" (uRDX)
+             : "0" (uOperator), "2" (0));
+    *(uint32_t *)pvEAX = (uint32_t)uRAX;
+    *(uint32_t *)pvEBX = (uint32_t)uRBX;
+    *(uint32_t *)pvECX = (uint32_t)uRCX;
+    *(uint32_t *)pvEDX = (uint32_t)uRDX;
+#  else
+    __asm__ __volatile__ ("xchgl %%ebx, %1\n\t"
+                          "cpuid\n\t"
+                          "xchgl %%ebx, %1\n\t"
+                         : "=a" (*(uint32_t *)pvEAX),
+                           "=r" (*(uint32_t *)pvEBX),
+                           "=c" (*(uint32_t *)pvECX),
+                           "=d" (*(uint32_t *)pvEDX)
+                         : "0" (uOperator), "2" (0));
+#  endif
+
+# elif RT_INLINE_ASM_USES_INTRIN
+    int aInfo[4];
+    __cpuid(aInfo, uOperator);
+    *(uint32_t *)pvEAX = aInfo[0];
+    *(uint32_t *)pvEBX = aInfo[1];
+    *(uint32_t *)pvECX = aInfo[2];
+    *(uint32_t *)pvEDX = aInfo[3];
+
+# else
+    uint32_t    uEAX;
+    uint32_t    uEBX;
+    uint32_t    uECX;
+    uint32_t    uEDX;
+    __asm
+    {
+        push    ebx
+        mov     eax, [uOperator]
+        cpuid
+        mov     [uEAX], eax
+        mov     [uEBX], ebx
+        mov     [uECX], ecx
+        mov     [uEDX], edx
+        pop     ebx
+    }
+    *(uint32_t *)pvEAX = uEAX;
+    *(uint32_t *)pvEBX = uEBX;
+    *(uint32_t *)pvECX = uECX;
+    *(uint32_t *)pvEDX = uEDX;
+# endif
+}
+#endif
+
+
+/**
+ * Performs the CPUID instruction with EAX and ECX input returning ALL output
+ * registers.
+ *
+ * @param   uOperator   CPUID operation (eax).
+ * @param   uIdxECX     ecx index
+ * @param   pvEAX       Where to store eax.
+ * @param   pvEBX       Where to store ebx.
+ * @param   pvECX       Where to store ecx.
+ * @param   pvEDX       Where to store edx.
+ * @remark  We're using void pointers to ease the use of special bitfield structures and such.
+ */
+#if RT_INLINE_ASM_EXTERNAL || RT_INLINE_ASM_USES_INTRIN
+DECLASM(void) ASMCpuId_Idx_ECX(uint32_t uOperator, uint32_t uIdxECX, void *pvEAX, void *pvEBX, void *pvECX, void *pvEDX);
+#else
+DECLINLINE(void) ASMCpuId_Idx_ECX(uint32_t uOperator, uint32_t uIdxECX, void *pvEAX, void *pvEBX, void *pvECX, void *pvEDX)
+{
+# if RT_INLINE_ASM_GNU_STYLE
+#  ifdef RT_ARCH_AMD64
+    RTCCUINTREG uRAX, uRBX, uRCX, uRDX;
+    __asm__ ("cpuid\n\t"
+             : "=a" (uRAX),
+               "=b" (uRBX),
+               "=c" (uRCX),
+               "=d" (uRDX)
+             : "0" (uOperator),
+               "2" (uIdxECX));
+    *(uint32_t *)pvEAX = (uint32_t)uRAX;
+    *(uint32_t *)pvEBX = (uint32_t)uRBX;
+    *(uint32_t *)pvECX = (uint32_t)uRCX;
+    *(uint32_t *)pvEDX = (uint32_t)uRDX;
+#  else
+    __asm__ ("xchgl %%ebx, %1\n\t"
+             "cpuid\n\t"
+             "xchgl %%ebx, %1\n\t"
+             : "=a" (*(uint32_t *)pvEAX),
+               "=r" (*(uint32_t *)pvEBX),
+               "=c" (*(uint32_t *)pvECX),
+               "=d" (*(uint32_t *)pvEDX)
+             : "0" (uOperator),
+               "2" (uIdxECX));
+#  endif
+
+# elif RT_INLINE_ASM_USES_INTRIN
+    int aInfo[4];
+    __cpuidex(aInfo, uOperator, uIdxECX);
+    *(uint32_t *)pvEAX = aInfo[0];
+    *(uint32_t *)pvEBX = aInfo[1];
+    *(uint32_t *)pvECX = aInfo[2];
+    *(uint32_t *)pvEDX = aInfo[3];
+
+# else
+    uint32_t    uEAX;
+    uint32_t    uEBX;
+    uint32_t    uECX;
+    uint32_t    uEDX;
+    __asm
+    {
+        push    ebx
+        mov     eax, [uOperator]
+        mov     ecx, [uIdxECX]
+        cpuid
+        mov     [uEAX], eax
+        mov     [uEBX], ebx
+        mov     [uECX], ecx
+        mov     [uEDX], edx
+        pop     ebx
+    }
+    *(uint32_t *)pvEAX = uEAX;
+    *(uint32_t *)pvEBX = uEBX;
+    *(uint32_t *)pvECX = uECX;
+    *(uint32_t *)pvEDX = uEDX;
+# endif
+}
+#endif
+
+
+/**
+ * CPUID variant that initializes all 4 registers before the CPUID instruction.
+ *
+ * @returns The EAX result value.
+ * @param   uOperator   CPUID operation (eax).
+ * @param   uInitEBX    The value to assign EBX prior to the CPUID instruction.
+ * @param   uInitECX    The value to assign ECX prior to the CPUID instruction.
+ * @param   uInitEDX    The value to assign EDX prior to the CPUID instruction.
+ * @param   pvEAX       Where to store eax. Optional.
+ * @param   pvEBX       Where to store ebx. Optional.
+ * @param   pvECX       Where to store ecx. Optional.
+ * @param   pvEDX       Where to store edx. Optional.
+ */
+DECLASM(uint32_t) ASMCpuIdExSlow(uint32_t uOperator, uint32_t uInitEBX, uint32_t uInitECX, uint32_t uInitEDX,
+                                 void *pvEAX, void *pvEBX, void *pvECX, void *pvEDX);
+
+
+/**
+ * Performs the cpuid instruction returning ecx and edx.
+ *
+ * @param   uOperator   CPUID operation (eax).
+ * @param   pvECX       Where to store ecx.
+ * @param   pvEDX       Where to store edx.
+ * @remark  We're using void pointers to ease the use of special bitfield structures and such.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(void) ASMCpuId_ECX_EDX(uint32_t uOperator, void *pvECX, void *pvEDX);
+#else
+DECLINLINE(void) ASMCpuId_ECX_EDX(uint32_t uOperator, void *pvECX, void *pvEDX)
+{
+    uint32_t uEBX;
+    ASMCpuId(uOperator, &uOperator, &uEBX, pvECX, pvEDX);
+}
+#endif
+
+
+/**
+ * Performs the cpuid instruction returning eax.
+ *
+ * @param   uOperator   CPUID operation (eax).
+ * @returns EAX after cpuid operation.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(uint32_t) ASMCpuId_EAX(uint32_t uOperator);
+#else
+DECLINLINE(uint32_t) ASMCpuId_EAX(uint32_t uOperator)
+{
+    RTCCUINTREG xAX;
+# if RT_INLINE_ASM_GNU_STYLE
+#  ifdef RT_ARCH_AMD64
+    __asm__ ("cpuid"
+             : "=a" (xAX)
+             : "0" (uOperator)
+             : "rbx", "rcx", "rdx");
+#  elif (defined(PIC) || defined(__PIC__)) && defined(__i386__)
+    __asm__ ("push  %%ebx\n\t"
+             "cpuid\n\t"
+             "pop   %%ebx\n\t"
+             : "=a" (xAX)
+             : "0" (uOperator)
+             : "ecx", "edx");
+#  else
+    __asm__ ("cpuid"
+             : "=a" (xAX)
+             : "0" (uOperator)
+             : "edx", "ecx", "ebx");
+#  endif
+
+# elif RT_INLINE_ASM_USES_INTRIN
+    int aInfo[4];
+    __cpuid(aInfo, uOperator);
+    xAX = aInfo[0];
+
+# else
+    __asm
+    {
+        push    ebx
+        mov     eax, [uOperator]
+        cpuid
+        mov     [xAX], eax
+        pop     ebx
+    }
+# endif
+    return (uint32_t)xAX;
+}
+#endif
+
+
+/**
+ * Performs the cpuid instruction returning ebx.
+ *
+ * @param   uOperator   CPUID operation (eax).
+ * @returns EBX after cpuid operation.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(uint32_t) ASMCpuId_EBX(uint32_t uOperator);
+#else
+DECLINLINE(uint32_t) ASMCpuId_EBX(uint32_t uOperator)
+{
+    RTCCUINTREG xBX;
+# if RT_INLINE_ASM_GNU_STYLE
+#  ifdef RT_ARCH_AMD64
+    RTCCUINTREG uSpill;
+    __asm__ ("cpuid"
+             : "=a" (uSpill),
+               "=b" (xBX)
+             : "0" (uOperator)
+             : "rdx", "rcx");
+#  elif (defined(PIC) || defined(__PIC__)) && defined(__i386__)
+    __asm__ ("push  %%ebx\n\t"
+             "cpuid\n\t"
+             "mov   %%ebx, %%edx\n\t"
+             "pop   %%ebx\n\t"
+             : "=a" (uOperator),
+               "=d" (xBX)
+             : "0" (uOperator)
+             : "ecx");
+#  else
+    __asm__ ("cpuid"
+             : "=a" (uOperator),
+               "=b" (xBX)
+             : "0" (uOperator)
+             : "edx", "ecx");
+#  endif
+
+# elif RT_INLINE_ASM_USES_INTRIN
+    int aInfo[4];
+    __cpuid(aInfo, uOperator);
+    xBX = aInfo[1];
+
+# else
+    __asm
+    {
+        push    ebx
+        mov     eax, [uOperator]
+        cpuid
+        mov     [xBX], ebx
+        pop     ebx
+    }
+# endif
+    return (uint32_t)xBX;
+}
+#endif
+
+
+/**
+ * Performs the cpuid instruction returning ecx.
+ *
+ * @param   uOperator   CPUID operation (eax).
+ * @returns ECX after cpuid operation.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(uint32_t) ASMCpuId_ECX(uint32_t uOperator);
+#else
+DECLINLINE(uint32_t) ASMCpuId_ECX(uint32_t uOperator)
+{
+    RTCCUINTREG xCX;
+# if RT_INLINE_ASM_GNU_STYLE
+#  ifdef RT_ARCH_AMD64
+    RTCCUINTREG uSpill;
+    __asm__ ("cpuid"
+             : "=a" (uSpill),
+               "=c" (xCX)
+             : "0" (uOperator)
+             : "rbx", "rdx");
+#  elif (defined(PIC) || defined(__PIC__)) && defined(__i386__)
+    __asm__ ("push  %%ebx\n\t"
+             "cpuid\n\t"
+             "pop   %%ebx\n\t"
+             : "=a" (uOperator),
+               "=c" (xCX)
+             : "0" (uOperator)
+             : "edx");
+#  else
+    __asm__ ("cpuid"
+             : "=a" (uOperator),
+               "=c" (xCX)
+             : "0" (uOperator)
+             : "ebx", "edx");
+
+#  endif
+
+# elif RT_INLINE_ASM_USES_INTRIN
+    int aInfo[4];
+    __cpuid(aInfo, uOperator);
+    xCX = aInfo[2];
+
+# else
+    __asm
+    {
+        push    ebx
+        mov     eax, [uOperator]
+        cpuid
+        mov     [xCX], ecx
+        pop     ebx
+    }
+# endif
+    return (uint32_t)xCX;
+}
+#endif
+
+
+/**
+ * Performs the cpuid instruction returning edx.
+ *
+ * @param   uOperator   CPUID operation (eax).
+ * @returns EDX after cpuid operation.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(uint32_t) ASMCpuId_EDX(uint32_t uOperator);
+#else
+DECLINLINE(uint32_t) ASMCpuId_EDX(uint32_t uOperator)
+{
+    RTCCUINTREG xDX;
+# if RT_INLINE_ASM_GNU_STYLE
+#  ifdef RT_ARCH_AMD64
+    RTCCUINTREG uSpill;
+    __asm__ ("cpuid"
+             : "=a" (uSpill),
+               "=d" (xDX)
+             : "0" (uOperator)
+             : "rbx", "rcx");
+#  elif (defined(PIC) || defined(__PIC__)) && defined(__i386__)
+    __asm__ ("push  %%ebx\n\t"
+             "cpuid\n\t"
+             "pop   %%ebx\n\t"
+             : "=a" (uOperator),
+               "=d" (xDX)
+             : "0" (uOperator)
+             : "ecx");
+#  else
+    __asm__ ("cpuid"
+             : "=a" (uOperator),
+               "=d" (xDX)
+             : "0" (uOperator)
+             : "ebx", "ecx");
+#  endif
+
+# elif RT_INLINE_ASM_USES_INTRIN
+    int aInfo[4];
+    __cpuid(aInfo, uOperator);
+    xDX = aInfo[3];
+
+# else
+    __asm
+    {
+        push    ebx
+        mov     eax, [uOperator]
+        cpuid
+        mov     [xDX], edx
+        pop     ebx
+    }
+# endif
+    return (uint32_t)xDX;
+}
+#endif
+
+
+/**
+ * Checks if the current CPU supports CPUID.
+ *
+ * @returns true if CPUID is supported.
+ */
+DECLINLINE(bool) ASMHasCpuId(void)
+{
+#ifdef RT_ARCH_AMD64
+    return true; /* ASSUME that all amd64 compatible CPUs have cpuid. */
+#else /* !RT_ARCH_AMD64 */
+    bool        fRet = false;
+# if RT_INLINE_ASM_GNU_STYLE
+    uint32_t    u1;
+    uint32_t    u2;
+    __asm__ ("pushf\n\t"
+             "pop   %1\n\t"
+             "mov   %1, %2\n\t"
+             "xorl  $0x200000, %1\n\t"
+             "push  %1\n\t"
+             "popf\n\t"
+             "pushf\n\t"
+             "pop   %1\n\t"
+             "cmpl  %1, %2\n\t"
+             "setne %0\n\t"
+             "push  %2\n\t"
+             "popf\n\t"
+             : "=m" (fRet), "=r" (u1), "=r" (u2));
+# else
+    __asm
+    {
+        pushfd
+        pop     eax
+        mov     ebx, eax
+        xor     eax, 0200000h
+        push    eax
+        popfd
+        pushfd
+        pop     eax
+        cmp     eax, ebx
+        setne   fRet
+        push    ebx
+        popfd
+    }
+# endif
+    return fRet;
+#endif /* !RT_ARCH_AMD64 */
+}
+
+
+/**
+ * Gets the APIC ID of the current CPU.
+ *
+ * @returns the APIC ID.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(uint8_t) ASMGetApicId(void);
+#else
+DECLINLINE(uint8_t) ASMGetApicId(void)
+{
+    RTCCUINTREG xBX;
+# if RT_INLINE_ASM_GNU_STYLE
+#  ifdef RT_ARCH_AMD64
+    RTCCUINTREG uSpill;
+    __asm__ __volatile__ ("cpuid"
+                          : "=a" (uSpill),
+                            "=b" (xBX)
+                          : "0" (1)
+                          : "rcx", "rdx");
+#  elif (defined(PIC) || defined(__PIC__)) && defined(__i386__)
+    RTCCUINTREG uSpill;
+    __asm__ __volatile__ ("mov   %%ebx,%1\n\t"
+                          "cpuid\n\t"
+                          "xchgl %%ebx,%1\n\t"
+                          : "=a" (uSpill),
+                            "=rm" (xBX)
+                          : "0" (1)
+                          : "ecx", "edx");
+#  else
+    RTCCUINTREG uSpill;
+    __asm__ __volatile__ ("cpuid"
+                          : "=a" (uSpill),
+                            "=b" (xBX)
+                          : "0" (1)
+                          : "ecx", "edx");
+#  endif
+
+# elif RT_INLINE_ASM_USES_INTRIN
+    int aInfo[4];
+    __cpuid(aInfo, 1);
+    xBX = aInfo[1];
+
+# else
+    __asm
+    {
+        push    ebx
+        mov     eax, 1
+        cpuid
+        mov     [xBX], ebx
+        pop     ebx
+    }
+# endif
+    return (uint8_t)(xBX >> 24);
+}
+#endif
+
+
+/**
+ * Tests if it a genuine Intel CPU based on the ASMCpuId(0) output.
+ *
+ * @returns true/false.
+ * @param   uEBX    EBX return from ASMCpuId(0)
+ * @param   uECX    ECX return from ASMCpuId(0)
+ * @param   uEDX    EDX return from ASMCpuId(0)
+ */
+DECLINLINE(bool) ASMIsIntelCpuEx(uint32_t uEBX, uint32_t uECX, uint32_t uEDX)
+{
+    return uEBX == UINT32_C(0x756e6547)
+        && uECX == UINT32_C(0x6c65746e)
+        && uEDX == UINT32_C(0x49656e69);
+}
+
+
+/**
+ * Tests if this is a genuine Intel CPU.
+ *
+ * @returns true/false.
+ * @remarks ASSUMES that cpuid is supported by the CPU.
+ */
+DECLINLINE(bool) ASMIsIntelCpu(void)
+{
+    uint32_t uEAX, uEBX, uECX, uEDX;
+    ASMCpuId(0, &uEAX, &uEBX, &uECX, &uEDX);
+    return ASMIsIntelCpuEx(uEBX, uECX, uEDX);
+}
+
+
+/**
+ * Tests if it an authentic AMD CPU based on the ASMCpuId(0) output.
+ *
+ * @returns true/false.
+ * @param   uEBX    EBX return from ASMCpuId(0)
+ * @param   uECX    ECX return from ASMCpuId(0)
+ * @param   uEDX    EDX return from ASMCpuId(0)
+ */
+DECLINLINE(bool) ASMIsAmdCpuEx(uint32_t uEBX, uint32_t uECX, uint32_t uEDX)
+{
+    return uEBX == UINT32_C(0x68747541)
+        && uECX == UINT32_C(0x444d4163)
+        && uEDX == UINT32_C(0x69746e65);
+}
+
+
+/**
+ * Tests if this is an authentic AMD CPU.
+ *
+ * @returns true/false.
+ * @remarks ASSUMES that cpuid is supported by the CPU.
+ */
+DECLINLINE(bool) ASMIsAmdCpu(void)
+{
+    uint32_t uEAX, uEBX, uECX, uEDX;
+    ASMCpuId(0, &uEAX, &uEBX, &uECX, &uEDX);
+    return ASMIsAmdCpuEx(uEBX, uECX, uEDX);
+}
+
+
+/**
+ * Tests if it a centaur hauling VIA CPU based on the ASMCpuId(0) output.
+ *
+ * @returns true/false.
+ * @param   uEBX    EBX return from ASMCpuId(0).
+ * @param   uECX    ECX return from ASMCpuId(0).
+ * @param   uEDX    EDX return from ASMCpuId(0).
+ */
+DECLINLINE(bool) ASMIsViaCentaurCpuEx(uint32_t uEBX, uint32_t uECX, uint32_t uEDX)
+{
+    return uEBX == UINT32_C(0x746e6543)
+        && uECX == UINT32_C(0x736c7561)
+        && uEDX == UINT32_C(0x48727561);
+}
+
+
+/**
+ * Tests if this is a centaur hauling VIA CPU.
+ *
+ * @returns true/false.
+ * @remarks ASSUMES that cpuid is supported by the CPU.
+ */
+DECLINLINE(bool) ASMIsViaCentaurCpu(void)
+{
+    uint32_t uEAX, uEBX, uECX, uEDX;
+    ASMCpuId(0, &uEAX, &uEBX, &uECX, &uEDX);
+    return ASMIsAmdCpuEx(uEBX, uECX, uEDX);
+}
+
+
+/**
+ * Checks whether ASMCpuId_EAX(0x00000000) indicates a valid range.
+ *
+ *
+ * @returns true/false.
+ * @param   uEAX    The EAX value of CPUID leaf 0x00000000.
+ *
+ * @note    This only succeeds if there are at least two leaves in the range.
+ * @remarks The upper range limit is just some half reasonable value we've
+ *          picked out of thin air.
+ */
+DECLINLINE(bool) ASMIsValidStdRange(uint32_t uEAX)
+{
+    return uEAX >= UINT32_C(0x00000001) && uEAX <= UINT32_C(0x000fffff);
+}
+
+
+/**
+ * Checks whether ASMCpuId_EAX(0x80000000) indicates a valid range.
+ *
+ * This only succeeds if there are at least two leaves in the range.
+ *
+ * @returns true/false.
+ * @param   uEAX    The EAX value of CPUID leaf 0x80000000.
+ *
+ * @note    This only succeeds if there are at least two leaves in the range.
+ * @remarks The upper range limit is just some half reasonable value we've
+ *          picked out of thin air.
+ */
+DECLINLINE(bool) ASMIsValidExtRange(uint32_t uEAX)
+{
+    return uEAX >= UINT32_C(0x80000001) && uEAX <= UINT32_C(0x800fffff);
+}
+
+
+/**
+ * Extracts the CPU family from ASMCpuId(1) or ASMCpuId(0x80000001)
+ *
+ * @returns Family.
+ * @param   uEAX    EAX return from ASMCpuId(1) or ASMCpuId(0x80000001).
+ */
+DECLINLINE(uint32_t) ASMGetCpuFamily(uint32_t uEAX)
+{
+    return ((uEAX >> 8) & 0xf) == 0xf
+         ? ((uEAX >> 20) & 0x7f) + 0xf
+         : ((uEAX >> 8) & 0xf);
+}
+
+
+/**
+ * Extracts the CPU model from ASMCpuId(1) or ASMCpuId(0x80000001), Intel variant.
+ *
+ * @returns Model.
+ * @param   uEAX    EAX from ASMCpuId(1) or ASMCpuId(0x80000001).
+ */
+DECLINLINE(uint32_t) ASMGetCpuModelIntel(uint32_t uEAX)
+{
+    return ((uEAX >> 8) & 0xf) == 0xf || (((uEAX >> 8) & 0xf) == 0x6) /* family! */
+         ? ((uEAX >> 4) & 0xf) | ((uEAX >> 12) & 0xf0)
+         : ((uEAX >> 4) & 0xf);
+}
+
+
+/**
+ * Extracts the CPU model from ASMCpuId(1) or ASMCpuId(0x80000001), AMD variant.
+ *
+ * @returns Model.
+ * @param   uEAX    EAX from ASMCpuId(1) or ASMCpuId(0x80000001).
+ */
+DECLINLINE(uint32_t) ASMGetCpuModelAMD(uint32_t uEAX)
+{
+    return ((uEAX >> 8) & 0xf) == 0xf
+         ? ((uEAX >> 4) & 0xf) | ((uEAX >> 12) & 0xf0)
+         : ((uEAX >> 4) & 0xf);
+}
+
+
+/**
+ * Extracts the CPU model from ASMCpuId(1) or ASMCpuId(0x80000001)
+ *
+ * @returns Model.
+ * @param   uEAX    EAX from ASMCpuId(1) or ASMCpuId(0x80000001).
+ * @param   fIntel  Whether it's an intel CPU. Use ASMIsIntelCpuEx() or ASMIsIntelCpu().
+ */
+DECLINLINE(uint32_t) ASMGetCpuModel(uint32_t uEAX, bool fIntel)
+{
+    return ((uEAX >> 8) & 0xf) == 0xf || (((uEAX >> 8) & 0xf) == 0x6 && fIntel) /* family! */
+         ? ((uEAX >> 4) & 0xf) | ((uEAX >> 12) & 0xf0)
+         : ((uEAX >> 4) & 0xf);
+}
+
+
+/**
+ * Extracts the CPU stepping from ASMCpuId(1) or ASMCpuId(0x80000001)
+ *
+ * @returns Model.
+ * @param   uEAX    EAX from ASMCpuId(1) or ASMCpuId(0x80000001).
+ */
+DECLINLINE(uint32_t) ASMGetCpuStepping(uint32_t uEAX)
+{
+    return uEAX & 0xf;
+}
+
+
+/**
+ * Get cr0.
+ * @returns cr0.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(RTCCUINTREG) ASMGetCR0(void);
+#else
+DECLINLINE(RTCCUINTREG) ASMGetCR0(void)
+{
+    RTCCUINTREG uCR0;
+# if RT_INLINE_ASM_USES_INTRIN
+    uCR0 = __readcr0();
+
+# elif RT_INLINE_ASM_GNU_STYLE
+#  ifdef RT_ARCH_AMD64
+    __asm__ __volatile__("movq  %%cr0, %0\t\n" : "=r" (uCR0));
+#  else
+    __asm__ __volatile__("movl  %%cr0, %0\t\n" : "=r" (uCR0));
+#  endif
+# else
+    __asm
+    {
+#  ifdef RT_ARCH_AMD64
+        mov     rax, cr0
+        mov     [uCR0], rax
+#  else
+        mov     eax, cr0
+        mov     [uCR0], eax
+#  endif
+    }
+# endif
+    return uCR0;
+}
+#endif
+
+
+/**
+ * Sets the CR0 register.
+ * @param   uCR0 The new CR0 value.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(void) ASMSetCR0(RTCCUINTREG uCR0);
+#else
+DECLINLINE(void) ASMSetCR0(RTCCUINTREG uCR0)
+{
+# if RT_INLINE_ASM_USES_INTRIN
+    __writecr0(uCR0);
+
+# elif RT_INLINE_ASM_GNU_STYLE
+#  ifdef RT_ARCH_AMD64
+    __asm__ __volatile__("movq %0, %%cr0\n\t" :: "r" (uCR0));
+#  else
+    __asm__ __volatile__("movl %0, %%cr0\n\t" :: "r" (uCR0));
+#  endif
+# else
+    __asm
+    {
+#  ifdef RT_ARCH_AMD64
+        mov     rax, [uCR0]
+        mov     cr0, rax
+#  else
+        mov     eax, [uCR0]
+        mov     cr0, eax
+#  endif
+    }
+# endif
+}
+#endif
+
+
+/**
+ * Get cr2.
+ * @returns cr2.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(RTCCUINTREG) ASMGetCR2(void);
+#else
+DECLINLINE(RTCCUINTREG) ASMGetCR2(void)
+{
+    RTCCUINTREG uCR2;
+# if RT_INLINE_ASM_USES_INTRIN
+    uCR2 = __readcr2();
+
+# elif RT_INLINE_ASM_GNU_STYLE
+#  ifdef RT_ARCH_AMD64
+    __asm__ __volatile__("movq  %%cr2, %0\t\n" : "=r" (uCR2));
+#  else
+    __asm__ __volatile__("movl  %%cr2, %0\t\n" : "=r" (uCR2));
+#  endif
+# else
+    __asm
+    {
+#  ifdef RT_ARCH_AMD64
+        mov     rax, cr2
+        mov     [uCR2], rax
+#  else
+        mov     eax, cr2
+        mov     [uCR2], eax
+#  endif
+    }
+# endif
+    return uCR2;
+}
+#endif
+
+
+/**
+ * Sets the CR2 register.
+ * @param   uCR2 The new CR0 value.
+ */
+#if RT_INLINE_ASM_EXTERNAL
+DECLASM(void) ASMSetCR2(RTCCUINTREG uCR2);
+#else
+DECLINLINE(void) ASMSetCR2(RTCCUINTREG uCR2)
+{
+# if RT_INLINE_ASM_GNU_STYLE
+#  ifdef RT_ARCH_AMD64
+    __asm__ __volatile__("movq %0, %%cr2\n\t" :: "r" (uCR2));
+#  else
+    __asm__ __volatile__("movl %0, %%cr2\n\t" :: "r" (uCR2));
+#  endif
+# else
+    __asm
+    {
+#  ifdef RT_ARCH_AMD64
+        mov     rax, [uCR2]
+        mov     cr2, rax
+#  else
+        mov     eax, [uCR2]
+        mov     cr2, eax
+#  endif
+    }
+# endif
+}
+#endif
+
+
+/**
+ * Get cr3.
+ * @returns cr3.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(RTCCUINTREG) ASMGetCR3(void);
+#else
+DECLINLINE(RTCCUINTREG) ASMGetCR3(void)
+{
+    RTCCUINTREG uCR3;
+# if RT_INLINE_ASM_USES_INTRIN
+    uCR3 = __readcr3();
+
+# elif RT_INLINE_ASM_GNU_STYLE
+#  ifdef RT_ARCH_AMD64
+    __asm__ __volatile__("movq  %%cr3, %0\t\n" : "=r" (uCR3));
+#  else
+    __asm__ __volatile__("movl  %%cr3, %0\t\n" : "=r" (uCR3));
+#  endif
+# else
+    __asm
+    {
+#  ifdef RT_ARCH_AMD64
+        mov     rax, cr3
+        mov     [uCR3], rax
+#  else
+        mov     eax, cr3
+        mov     [uCR3], eax
+#  endif
+    }
+# endif
+    return uCR3;
+}
+#endif
+
+
+/**
+ * Sets the CR3 register.
+ *
+ * @param   uCR3    New CR3 value.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(void) ASMSetCR3(RTCCUINTREG uCR3);
+#else
+DECLINLINE(void) ASMSetCR3(RTCCUINTREG uCR3)
+{
+# if RT_INLINE_ASM_USES_INTRIN
+    __writecr3(uCR3);
+
+# elif RT_INLINE_ASM_GNU_STYLE
+#  ifdef RT_ARCH_AMD64
+    __asm__ __volatile__("movq %0, %%cr3\n\t" : : "r" (uCR3));
+#  else
+    __asm__ __volatile__("movl %0, %%cr3\n\t" : : "r" (uCR3));
+#  endif
+# else
+    __asm
+    {
+#  ifdef RT_ARCH_AMD64
+        mov     rax, [uCR3]
+        mov     cr3, rax
+#  else
+        mov     eax, [uCR3]
+        mov     cr3, eax
+#  endif
+    }
+# endif
+}
+#endif
+
+
+/**
+ * Reloads the CR3 register.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(void) ASMReloadCR3(void);
+#else
+DECLINLINE(void) ASMReloadCR3(void)
+{
+# if RT_INLINE_ASM_USES_INTRIN
+    __writecr3(__readcr3());
+
+# elif RT_INLINE_ASM_GNU_STYLE
+    RTCCUINTREG u;
+#  ifdef RT_ARCH_AMD64
+    __asm__ __volatile__("movq %%cr3, %0\n\t"
+                         "movq %0, %%cr3\n\t"
+                         : "=r" (u));
+#  else
+    __asm__ __volatile__("movl %%cr3, %0\n\t"
+                         "movl %0, %%cr3\n\t"
+                         : "=r" (u));
+#  endif
+# else
+    __asm
+    {
+#  ifdef RT_ARCH_AMD64
+        mov     rax, cr3
+        mov     cr3, rax
+#  else
+        mov     eax, cr3
+        mov     cr3, eax
+#  endif
+    }
+# endif
+}
+#endif
+
+
+/**
+ * Get cr4.
+ * @returns cr4.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(RTCCUINTREG) ASMGetCR4(void);
+#else
+DECLINLINE(RTCCUINTREG) ASMGetCR4(void)
+{
+    RTCCUINTREG uCR4;
+# if RT_INLINE_ASM_USES_INTRIN
+    uCR4 = __readcr4();
+
+# elif RT_INLINE_ASM_GNU_STYLE
+#  ifdef RT_ARCH_AMD64
+    __asm__ __volatile__("movq  %%cr4, %0\t\n" : "=r" (uCR4));
+#  else
+    __asm__ __volatile__("movl  %%cr4, %0\t\n" : "=r" (uCR4));
+#  endif
+# else
+    __asm
+    {
+#  ifdef RT_ARCH_AMD64
+        mov     rax, cr4
+        mov     [uCR4], rax
+#  else
+        push    eax /* just in case */
+        /*mov     eax, cr4*/
+        _emit   0x0f
+        _emit   0x20
+        _emit   0xe0
+        mov     [uCR4], eax
+        pop     eax
+#  endif
+    }
+# endif
+    return uCR4;
+}
+#endif
+
+
+/**
+ * Sets the CR4 register.
+ *
+ * @param   uCR4    New CR4 value.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(void) ASMSetCR4(RTCCUINTREG uCR4);
+#else
+DECLINLINE(void) ASMSetCR4(RTCCUINTREG uCR4)
+{
+# if RT_INLINE_ASM_USES_INTRIN
+    __writecr4(uCR4);
+
+# elif RT_INLINE_ASM_GNU_STYLE
+#  ifdef RT_ARCH_AMD64
+    __asm__ __volatile__("movq %0, %%cr4\n\t" : : "r" (uCR4));
+#  else
+    __asm__ __volatile__("movl %0, %%cr4\n\t" : : "r" (uCR4));
+#  endif
+# else
+    __asm
+    {
+#  ifdef RT_ARCH_AMD64
+        mov     rax, [uCR4]
+        mov     cr4, rax
+#  else
+        mov     eax, [uCR4]
+        _emit   0x0F
+        _emit   0x22
+        _emit   0xE0        /* mov     cr4, eax */
+#  endif
+    }
+# endif
+}
+#endif
+
+
+/**
+ * Get cr8.
+ * @returns cr8.
+ * @remark  The lock prefix hack for access from non-64-bit modes is NOT used and 0 is returned.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(RTCCUINTREG) ASMGetCR8(void);
+#else
+DECLINLINE(RTCCUINTREG) ASMGetCR8(void)
+{
+# ifdef RT_ARCH_AMD64
+    RTCCUINTREG uCR8;
+#  if RT_INLINE_ASM_USES_INTRIN
+    uCR8 = __readcr8();
+
+#  elif RT_INLINE_ASM_GNU_STYLE
+    __asm__ __volatile__("movq  %%cr8, %0\t\n" : "=r" (uCR8));
+#  else
+    __asm
+    {
+        mov     rax, cr8
+        mov     [uCR8], rax
+    }
+#  endif
+    return uCR8;
+# else /* !RT_ARCH_AMD64 */
+    return 0;
+# endif /* !RT_ARCH_AMD64 */
+}
+#endif
+
+
+/**
+ * Get XCR0 (eXtended feature Control Register 0).
+ * @returns xcr0.
+ */
+DECLASM(uint64_t) ASMGetXcr0(void);
+
+/**
+ * Sets the XCR0 register.
+ * @param   uXcr0   The new XCR0 value.
+ */
+DECLASM(void) ASMSetXcr0(uint64_t uXcr0);
+
+struct X86XSAVEAREA;
+/**
+ * Save extended CPU state.
+ * @param   pXStateArea     Where to save the state.
+ * @param   fComponents     Which state components to save.
+ */
+DECLASM(void) ASMXSave(struct X86XSAVEAREA *pXStateArea, uint64_t fComponents);
+
+/**
+ * Loads extended CPU state.
+ * @param   pXStateArea     Where to load the state from.
+ * @param   fComponents     Which state components to load.
+ */
+DECLASM(void) ASMXRstor(struct X86XSAVEAREA const *pXStateArea, uint64_t fComponents);
+
+
+/**
+ * Enables interrupts (EFLAGS.IF).
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(void) ASMIntEnable(void);
+#else
+DECLINLINE(void) ASMIntEnable(void)
+{
+# if RT_INLINE_ASM_GNU_STYLE
+    __asm("sti\n");
+# elif RT_INLINE_ASM_USES_INTRIN
+    _enable();
+# else
+    __asm sti
+# endif
+}
+#endif
+
+
+/**
+ * Disables interrupts (!EFLAGS.IF).
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(void) ASMIntDisable(void);
+#else
+DECLINLINE(void) ASMIntDisable(void)
+{
+# if RT_INLINE_ASM_GNU_STYLE
+    __asm("cli\n");
+# elif RT_INLINE_ASM_USES_INTRIN
+    _disable();
+# else
+    __asm cli
+# endif
+}
+#endif
+
+
+/**
+ * Disables interrupts and returns previous xFLAGS.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(RTCCUINTREG) ASMIntDisableFlags(void);
+#else
+DECLINLINE(RTCCUINTREG) ASMIntDisableFlags(void)
+{
+    RTCCUINTREG xFlags;
+# if RT_INLINE_ASM_GNU_STYLE
+#  ifdef RT_ARCH_AMD64
+    __asm__ __volatile__("pushfq\n\t"
+                         "cli\n\t"
+                         "popq  %0\n\t"
+                         : "=r" (xFlags));
+#  else
+    __asm__ __volatile__("pushfl\n\t"
+                         "cli\n\t"
+                         "popl  %0\n\t"
+                         : "=r" (xFlags));
+#  endif
+# elif RT_INLINE_ASM_USES_INTRIN && !defined(RT_ARCH_X86)
+    xFlags = ASMGetFlags();
+    _disable();
+# else
+    __asm {
+        pushfd
+        cli
+        pop  [xFlags]
+    }
+# endif
+    return xFlags;
+}
+#endif
+
+
+/**
+ * Are interrupts enabled?
+ *
+ * @returns true / false.
+ */
+DECLINLINE(bool) ASMIntAreEnabled(void)
+{
+    RTCCUINTREG uFlags = ASMGetFlags();
+    return uFlags & 0x200 /* X86_EFL_IF */ ? true : false;
+}
+
+
+/**
+ * Halts the CPU until interrupted.
+ */
+#if RT_INLINE_ASM_EXTERNAL
+DECLASM(void) ASMHalt(void);
+#else
+DECLINLINE(void) ASMHalt(void)
+{
+# if RT_INLINE_ASM_GNU_STYLE
+    __asm__ __volatile__("hlt\n\t");
+# else
+    __asm {
+        hlt
+    }
+# endif
+}
+#endif
+
+
+/**
+ * Reads a machine specific register.
+ *
+ * @returns Register content.
+ * @param   uRegister   Register to read.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(uint64_t) ASMRdMsr(uint32_t uRegister);
+#else
+DECLINLINE(uint64_t) ASMRdMsr(uint32_t uRegister)
+{
+    RTUINT64U u;
+# if RT_INLINE_ASM_GNU_STYLE
+    __asm__ __volatile__("rdmsr\n\t"
+                         : "=a" (u.s.Lo),
+                           "=d" (u.s.Hi)
+                         : "c" (uRegister));
+
+# elif RT_INLINE_ASM_USES_INTRIN
+    u.u = __readmsr(uRegister);
+
+# else
+    __asm
+    {
+        mov     ecx, [uRegister]
+        rdmsr
+        mov     [u.s.Lo], eax
+        mov     [u.s.Hi], edx
+    }
+# endif
+
+    return u.u;
+}
+#endif
+
+
+/**
+ * Writes a machine specific register.
+ *
+ * @returns Register content.
+ * @param   uRegister   Register to write to.
+ * @param   u64Val      Value to write.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(void) ASMWrMsr(uint32_t uRegister, uint64_t u64Val);
+#else
+DECLINLINE(void) ASMWrMsr(uint32_t uRegister, uint64_t u64Val)
+{
+    RTUINT64U u;
+
+    u.u = u64Val;
+# if RT_INLINE_ASM_GNU_STYLE
+    __asm__ __volatile__("wrmsr\n\t"
+                         ::"a" (u.s.Lo),
+                           "d" (u.s.Hi),
+                           "c" (uRegister));
+
+# elif RT_INLINE_ASM_USES_INTRIN
+    __writemsr(uRegister, u.u);
+
+# else
+    __asm
+    {
+        mov     ecx, [uRegister]
+        mov     edx, [u.s.Hi]
+        mov     eax, [u.s.Lo]
+        wrmsr
+    }
+# endif
+}
+#endif
+
+
+/**
+ * Reads a machine specific register, extended version (for AMD).
+ *
+ * @returns Register content.
+ * @param   uRegister   Register to read.
+ * @param   uXDI        RDI/EDI value.
+ */
+#if RT_INLINE_ASM_EXTERNAL
+DECLASM(uint64_t) ASMRdMsrEx(uint32_t uRegister, RTCCUINTREG uXDI);
+#else
+DECLINLINE(uint64_t) ASMRdMsrEx(uint32_t uRegister, RTCCUINTREG uXDI)
+{
+    RTUINT64U u;
+# if RT_INLINE_ASM_GNU_STYLE
+    __asm__ __volatile__("rdmsr\n\t"
+                         : "=a" (u.s.Lo),
+                           "=d" (u.s.Hi)
+                         : "c" (uRegister),
+                           "D" (uXDI));
+
+# else
+    __asm
+    {
+        mov     ecx, [uRegister]
+        xchg    edi, [uXDI]
+        rdmsr
+        mov     [u.s.Lo], eax
+        mov     [u.s.Hi], edx
+        xchg    edi, [uXDI]
+    }
+# endif
+
+    return u.u;
+}
+#endif
+
+
+/**
+ * Writes a machine specific register, extended version (for AMD).
+ *
+ * @returns Register content.
+ * @param   uRegister   Register to write to.
+ * @param   uXDI        RDI/EDI value.
+ * @param   u64Val      Value to write.
+ */
+#if RT_INLINE_ASM_EXTERNAL
+DECLASM(void) ASMWrMsrEx(uint32_t uRegister, RTCCUINTREG uXDI, uint64_t u64Val);
+#else
+DECLINLINE(void) ASMWrMsrEx(uint32_t uRegister, RTCCUINTREG uXDI, uint64_t u64Val)
+{
+    RTUINT64U u;
+
+    u.u = u64Val;
+# if RT_INLINE_ASM_GNU_STYLE
+    __asm__ __volatile__("wrmsr\n\t"
+                         ::"a" (u.s.Lo),
+                           "d" (u.s.Hi),
+                           "c" (uRegister),
+                           "D" (uXDI));
+
+# else
+    __asm
+    {
+        mov     ecx, [uRegister]
+        xchg    edi, [uXDI]
+        mov     edx, [u.s.Hi]
+        mov     eax, [u.s.Lo]
+        wrmsr
+        xchg    edi, [uXDI]
+    }
+# endif
+}
+#endif
+
+
+
+/**
+ * Reads low part of a machine specific register.
+ *
+ * @returns Register content.
+ * @param   uRegister   Register to read.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(uint32_t) ASMRdMsr_Low(uint32_t uRegister);
+#else
+DECLINLINE(uint32_t) ASMRdMsr_Low(uint32_t uRegister)
+{
+    uint32_t u32;
+# if RT_INLINE_ASM_GNU_STYLE
+    __asm__ __volatile__("rdmsr\n\t"
+                         : "=a" (u32)
+                         : "c" (uRegister)
+                         : "edx");
+
+# elif RT_INLINE_ASM_USES_INTRIN
+    u32 = (uint32_t)__readmsr(uRegister);
+
+#else
+    __asm
+    {
+        mov     ecx, [uRegister]
+        rdmsr
+        mov     [u32], eax
+    }
+# endif
+
+    return u32;
+}
+#endif
+
+
+/**
+ * Reads high part of a machine specific register.
+ *
+ * @returns Register content.
+ * @param   uRegister   Register to read.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(uint32_t) ASMRdMsr_High(uint32_t uRegister);
+#else
+DECLINLINE(uint32_t) ASMRdMsr_High(uint32_t uRegister)
+{
+    uint32_t    u32;
+# if RT_INLINE_ASM_GNU_STYLE
+    __asm__ __volatile__("rdmsr\n\t"
+                         : "=d" (u32)
+                         : "c" (uRegister)
+                         : "eax");
+
+# elif RT_INLINE_ASM_USES_INTRIN
+    u32 = (uint32_t)(__readmsr(uRegister) >> 32);
+
+# else
+    __asm
+    {
+        mov     ecx, [uRegister]
+        rdmsr
+        mov     [u32], edx
+    }
+# endif
+
+    return u32;
+}
+#endif
+
+
+/**
+ * Gets dr0.
+ *
+ * @returns dr0.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(RTCCUINTREG) ASMGetDR0(void);
+#else
+DECLINLINE(RTCCUINTREG) ASMGetDR0(void)
+{
+    RTCCUINTREG uDR0;
+# if RT_INLINE_ASM_USES_INTRIN
+    uDR0 = __readdr(0);
+# elif RT_INLINE_ASM_GNU_STYLE
+#  ifdef RT_ARCH_AMD64
+    __asm__ __volatile__("movq   %%dr0, %0\n\t" : "=r" (uDR0));
+#  else
+    __asm__ __volatile__("movl   %%dr0, %0\n\t" : "=r" (uDR0));
+#  endif
+# else
+    __asm
+    {
+#  ifdef RT_ARCH_AMD64
+        mov     rax, dr0
+        mov     [uDR0], rax
+#  else
+        mov     eax, dr0
+        mov     [uDR0], eax
+#  endif
+    }
+# endif
+    return uDR0;
+}
+#endif
+
+
+/**
+ * Gets dr1.
+ *
+ * @returns dr1.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(RTCCUINTREG) ASMGetDR1(void);
+#else
+DECLINLINE(RTCCUINTREG) ASMGetDR1(void)
+{
+    RTCCUINTREG uDR1;
+# if RT_INLINE_ASM_USES_INTRIN
+    uDR1 = __readdr(1);
+# elif RT_INLINE_ASM_GNU_STYLE
+#  ifdef RT_ARCH_AMD64
+    __asm__ __volatile__("movq   %%dr1, %0\n\t" : "=r" (uDR1));
+#  else
+    __asm__ __volatile__("movl   %%dr1, %0\n\t" : "=r" (uDR1));
+#  endif
+# else
+    __asm
+    {
+#  ifdef RT_ARCH_AMD64
+        mov     rax, dr1
+        mov     [uDR1], rax
+#  else
+        mov     eax, dr1
+        mov     [uDR1], eax
+#  endif
+    }
+# endif
+    return uDR1;
+}
+#endif
+
+
+/**
+ * Gets dr2.
+ *
+ * @returns dr2.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(RTCCUINTREG) ASMGetDR2(void);
+#else
+DECLINLINE(RTCCUINTREG) ASMGetDR2(void)
+{
+    RTCCUINTREG uDR2;
+# if RT_INLINE_ASM_USES_INTRIN
+    uDR2 = __readdr(2);
+# elif RT_INLINE_ASM_GNU_STYLE
+#  ifdef RT_ARCH_AMD64
+    __asm__ __volatile__("movq   %%dr2, %0\n\t" : "=r" (uDR2));
+#  else
+    __asm__ __volatile__("movl   %%dr2, %0\n\t" : "=r" (uDR2));
+#  endif
+# else
+    __asm
+    {
+#  ifdef RT_ARCH_AMD64
+        mov     rax, dr2
+        mov     [uDR2], rax
+#  else
+        mov     eax, dr2
+        mov     [uDR2], eax
+#  endif
+    }
+# endif
+    return uDR2;
+}
+#endif
+
+
+/**
+ * Gets dr3.
+ *
+ * @returns dr3.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(RTCCUINTREG) ASMGetDR3(void);
+#else
+DECLINLINE(RTCCUINTREG) ASMGetDR3(void)
+{
+    RTCCUINTREG uDR3;
+# if RT_INLINE_ASM_USES_INTRIN
+    uDR3 = __readdr(3);
+# elif RT_INLINE_ASM_GNU_STYLE
+#  ifdef RT_ARCH_AMD64
+    __asm__ __volatile__("movq   %%dr3, %0\n\t" : "=r" (uDR3));
+#  else
+    __asm__ __volatile__("movl   %%dr3, %0\n\t" : "=r" (uDR3));
+#  endif
+# else
+    __asm
+    {
+#  ifdef RT_ARCH_AMD64
+        mov     rax, dr3
+        mov     [uDR3], rax
+#  else
+        mov     eax, dr3
+        mov     [uDR3], eax
+#  endif
+    }
+# endif
+    return uDR3;
+}
+#endif
+
+
+/**
+ * Gets dr6.
+ *
+ * @returns dr6.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(RTCCUINTREG) ASMGetDR6(void);
+#else
+DECLINLINE(RTCCUINTREG) ASMGetDR6(void)
+{
+    RTCCUINTREG uDR6;
+# if RT_INLINE_ASM_USES_INTRIN
+    uDR6 = __readdr(6);
+# elif RT_INLINE_ASM_GNU_STYLE
+#  ifdef RT_ARCH_AMD64
+    __asm__ __volatile__("movq   %%dr6, %0\n\t" : "=r" (uDR6));
+#  else
+    __asm__ __volatile__("movl   %%dr6, %0\n\t" : "=r" (uDR6));
+#  endif
+# else
+    __asm
+    {
+#  ifdef RT_ARCH_AMD64
+        mov     rax, dr6
+        mov     [uDR6], rax
+#  else
+        mov     eax, dr6
+        mov     [uDR6], eax
+#  endif
+    }
+# endif
+    return uDR6;
+}
+#endif
+
+
+/**
+ * Reads and clears DR6.
+ *
+ * @returns DR6.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(RTCCUINTREG) ASMGetAndClearDR6(void);
+#else
+DECLINLINE(RTCCUINTREG) ASMGetAndClearDR6(void)
+{
+    RTCCUINTREG uDR6;
+# if RT_INLINE_ASM_USES_INTRIN
+    uDR6 = __readdr(6);
+    __writedr(6, 0xffff0ff0U);          /* 31-16 and 4-11 are 1's, 12 and 63-31 are zero. */
+# elif RT_INLINE_ASM_GNU_STYLE
+    RTCCUINTREG uNewValue = 0xffff0ff0U;/* 31-16 and 4-11 are 1's, 12 and 63-31 are zero. */
+#  ifdef RT_ARCH_AMD64
+    __asm__ __volatile__("movq   %%dr6, %0\n\t"
+                         "movq   %1, %%dr6\n\t"
+                         : "=r" (uDR6)
+                         : "r" (uNewValue));
+#  else
+    __asm__ __volatile__("movl   %%dr6, %0\n\t"
+                         "movl   %1, %%dr6\n\t"
+                         : "=r" (uDR6)
+                         : "r" (uNewValue));
+#  endif
+# else
+    __asm
+    {
+#  ifdef RT_ARCH_AMD64
+        mov     rax, dr6
+        mov     [uDR6], rax
+        mov     rcx, rax
+        mov     ecx, 0ffff0ff0h;        /* 31-16 and 4-11 are 1's, 12 and 63-31 are zero. */
+        mov     dr6, rcx
+#  else
+        mov     eax, dr6
+        mov     [uDR6], eax
+        mov     ecx, 0ffff0ff0h;        /* 31-16 and 4-11 are 1's, 12 is zero. */
+        mov     dr6, ecx
+#  endif
+    }
+# endif
+    return uDR6;
+}
+#endif
+
+
+/**
+ * Gets dr7.
+ *
+ * @returns dr7.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(RTCCUINTREG) ASMGetDR7(void);
+#else
+DECLINLINE(RTCCUINTREG) ASMGetDR7(void)
+{
+    RTCCUINTREG uDR7;
+# if RT_INLINE_ASM_USES_INTRIN
+    uDR7 = __readdr(7);
+# elif RT_INLINE_ASM_GNU_STYLE
+#  ifdef RT_ARCH_AMD64
+    __asm__ __volatile__("movq   %%dr7, %0\n\t" : "=r" (uDR7));
+#  else
+    __asm__ __volatile__("movl   %%dr7, %0\n\t" : "=r" (uDR7));
+#  endif
+# else
+    __asm
+    {
+#  ifdef RT_ARCH_AMD64
+        mov     rax, dr7
+        mov     [uDR7], rax
+#  else
+        mov     eax, dr7
+        mov     [uDR7], eax
+#  endif
+    }
+# endif
+    return uDR7;
+}
+#endif
+
+
+/**
+ * Sets dr0.
+ *
+ * @param   uDRVal   Debug register value to write
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(void) ASMSetDR0(RTCCUINTREG uDRVal);
+#else
+DECLINLINE(void) ASMSetDR0(RTCCUINTREG uDRVal)
+{
+# if RT_INLINE_ASM_USES_INTRIN
+    __writedr(0, uDRVal);
+# elif RT_INLINE_ASM_GNU_STYLE
+#  ifdef RT_ARCH_AMD64
+    __asm__ __volatile__("movq   %0, %%dr0\n\t" : : "r" (uDRVal));
+#  else
+    __asm__ __volatile__("movl   %0, %%dr0\n\t" : : "r" (uDRVal));
+#  endif
+# else
+    __asm
+    {
+#  ifdef RT_ARCH_AMD64
+        mov     rax, [uDRVal]
+        mov     dr0, rax
+#  else
+        mov     eax, [uDRVal]
+        mov     dr0, eax
+#  endif
+    }
+# endif
+}
+#endif
+
+
+/**
+ * Sets dr1.
+ *
+ * @param   uDRVal   Debug register value to write
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(void) ASMSetDR1(RTCCUINTREG uDRVal);
+#else
+DECLINLINE(void) ASMSetDR1(RTCCUINTREG uDRVal)
+{
+# if RT_INLINE_ASM_USES_INTRIN
+    __writedr(1, uDRVal);
+# elif RT_INLINE_ASM_GNU_STYLE
+#  ifdef RT_ARCH_AMD64
+    __asm__ __volatile__("movq   %0, %%dr1\n\t" : : "r" (uDRVal));
+#  else
+    __asm__ __volatile__("movl   %0, %%dr1\n\t" : : "r" (uDRVal));
+#  endif
+# else
+    __asm
+    {
+#  ifdef RT_ARCH_AMD64
+        mov     rax, [uDRVal]
+        mov     dr1, rax
+#  else
+        mov     eax, [uDRVal]
+        mov     dr1, eax
+#  endif
+    }
+# endif
+}
+#endif
+
+
+/**
+ * Sets dr2.
+ *
+ * @param   uDRVal   Debug register value to write
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(void) ASMSetDR2(RTCCUINTREG uDRVal);
+#else
+DECLINLINE(void) ASMSetDR2(RTCCUINTREG uDRVal)
+{
+# if RT_INLINE_ASM_USES_INTRIN
+    __writedr(2, uDRVal);
+# elif RT_INLINE_ASM_GNU_STYLE
+#  ifdef RT_ARCH_AMD64
+    __asm__ __volatile__("movq   %0, %%dr2\n\t" : : "r" (uDRVal));
+#  else
+    __asm__ __volatile__("movl   %0, %%dr2\n\t" : : "r" (uDRVal));
+#  endif
+# else
+    __asm
+    {
+#  ifdef RT_ARCH_AMD64
+        mov     rax, [uDRVal]
+        mov     dr2, rax
+#  else
+        mov     eax, [uDRVal]
+        mov     dr2, eax
+#  endif
+    }
+# endif
+}
+#endif
+
+
+/**
+ * Sets dr3.
+ *
+ * @param   uDRVal   Debug register value to write
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(void) ASMSetDR3(RTCCUINTREG uDRVal);
+#else
+DECLINLINE(void) ASMSetDR3(RTCCUINTREG uDRVal)
+{
+# if RT_INLINE_ASM_USES_INTRIN
+    __writedr(3, uDRVal);
+# elif RT_INLINE_ASM_GNU_STYLE
+#  ifdef RT_ARCH_AMD64
+    __asm__ __volatile__("movq   %0, %%dr3\n\t" : : "r" (uDRVal));
+#  else
+    __asm__ __volatile__("movl   %0, %%dr3\n\t" : : "r" (uDRVal));
+#  endif
+# else
+    __asm
+    {
+#  ifdef RT_ARCH_AMD64
+        mov     rax, [uDRVal]
+        mov     dr3, rax
+#  else
+        mov     eax, [uDRVal]
+        mov     dr3, eax
+#  endif
+    }
+# endif
+}
+#endif
+
+
+/**
+ * Sets dr6.
+ *
+ * @param   uDRVal   Debug register value to write
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(void) ASMSetDR6(RTCCUINTREG uDRVal);
+#else
+DECLINLINE(void) ASMSetDR6(RTCCUINTREG uDRVal)
+{
+# if RT_INLINE_ASM_USES_INTRIN
+    __writedr(6, uDRVal);
+# elif RT_INLINE_ASM_GNU_STYLE
+#  ifdef RT_ARCH_AMD64
+    __asm__ __volatile__("movq   %0, %%dr6\n\t" : : "r" (uDRVal));
+#  else
+    __asm__ __volatile__("movl   %0, %%dr6\n\t" : : "r" (uDRVal));
+#  endif
+# else
+    __asm
+    {
+#  ifdef RT_ARCH_AMD64
+        mov     rax, [uDRVal]
+        mov     dr6, rax
+#  else
+        mov     eax, [uDRVal]
+        mov     dr6, eax
+#  endif
+    }
+# endif
+}
+#endif
+
+
+/**
+ * Sets dr7.
+ *
+ * @param   uDRVal   Debug register value to write
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(void) ASMSetDR7(RTCCUINTREG uDRVal);
+#else
+DECLINLINE(void) ASMSetDR7(RTCCUINTREG uDRVal)
+{
+# if RT_INLINE_ASM_USES_INTRIN
+    __writedr(7, uDRVal);
+# elif RT_INLINE_ASM_GNU_STYLE
+#  ifdef RT_ARCH_AMD64
+    __asm__ __volatile__("movq   %0, %%dr7\n\t" : : "r" (uDRVal));
+#  else
+    __asm__ __volatile__("movl   %0, %%dr7\n\t" : : "r" (uDRVal));
+#  endif
+# else
+    __asm
+    {
+#  ifdef RT_ARCH_AMD64
+        mov     rax, [uDRVal]
+        mov     dr7, rax
+#  else
+        mov     eax, [uDRVal]
+        mov     dr7, eax
+#  endif
+    }
+# endif
+}
+#endif
+
+
+/**
+ * Writes a 8-bit unsigned integer to an I/O port, ordered.
+ *
+ * @param   Port    I/O port to write to.
+ * @param   u8      8-bit integer to write.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(void) ASMOutU8(RTIOPORT Port, uint8_t u8);
+#else
+DECLINLINE(void) ASMOutU8(RTIOPORT Port, uint8_t u8)
+{
+# if RT_INLINE_ASM_GNU_STYLE
+    __asm__ __volatile__("outb %b1, %w0\n\t"
+                         :: "Nd" (Port),
+                            "a" (u8));
+
+# elif RT_INLINE_ASM_USES_INTRIN
+    __outbyte(Port, u8);
+
+# else
+    __asm
+    {
+        mov     dx, [Port]
+        mov     al, [u8]
+        out     dx, al
+    }
+# endif
+}
+#endif
+
+
+/**
+ * Reads a 8-bit unsigned integer from an I/O port, ordered.
+ *
+ * @returns 8-bit integer.
+ * @param   Port    I/O port to read from.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(uint8_t) ASMInU8(RTIOPORT Port);
+#else
+DECLINLINE(uint8_t) ASMInU8(RTIOPORT Port)
+{
+    uint8_t u8;
+# if RT_INLINE_ASM_GNU_STYLE
+    __asm__ __volatile__("inb %w1, %b0\n\t"
+                         : "=a" (u8)
+                         : "Nd" (Port));
+
+# elif RT_INLINE_ASM_USES_INTRIN
+    u8 = __inbyte(Port);
+
+# else
+    __asm
+    {
+        mov     dx, [Port]
+        in      al, dx
+        mov     [u8], al
+    }
+# endif
+    return u8;
+}
+#endif
+
+
+/**
+ * Writes a 16-bit unsigned integer to an I/O port, ordered.
+ *
+ * @param   Port    I/O port to write to.
+ * @param   u16     16-bit integer to write.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(void) ASMOutU16(RTIOPORT Port, uint16_t u16);
+#else
+DECLINLINE(void) ASMOutU16(RTIOPORT Port, uint16_t u16)
+{
+# if RT_INLINE_ASM_GNU_STYLE
+    __asm__ __volatile__("outw %w1, %w0\n\t"
+                         :: "Nd" (Port),
+                            "a" (u16));
+
+# elif RT_INLINE_ASM_USES_INTRIN
+    __outword(Port, u16);
+
+# else
+    __asm
+    {
+        mov     dx, [Port]
+        mov     ax, [u16]
+        out     dx, ax
+    }
+# endif
+}
+#endif
+
+
+/**
+ * Reads a 16-bit unsigned integer from an I/O port, ordered.
+ *
+ * @returns 16-bit integer.
+ * @param   Port    I/O port to read from.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(uint16_t) ASMInU16(RTIOPORT Port);
+#else
+DECLINLINE(uint16_t) ASMInU16(RTIOPORT Port)
+{
+    uint16_t u16;
+# if RT_INLINE_ASM_GNU_STYLE
+    __asm__ __volatile__("inw %w1, %w0\n\t"
+                         : "=a" (u16)
+                         : "Nd" (Port));
+
+# elif RT_INLINE_ASM_USES_INTRIN
+    u16 = __inword(Port);
+
+# else
+    __asm
+    {
+        mov     dx, [Port]
+        in      ax, dx
+        mov     [u16], ax
+    }
+# endif
+    return u16;
+}
+#endif
+
+
+/**
+ * Writes a 32-bit unsigned integer to an I/O port, ordered.
+ *
+ * @param   Port    I/O port to write to.
+ * @param   u32     32-bit integer to write.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(void) ASMOutU32(RTIOPORT Port, uint32_t u32);
+#else
+DECLINLINE(void) ASMOutU32(RTIOPORT Port, uint32_t u32)
+{
+# if RT_INLINE_ASM_GNU_STYLE
+    __asm__ __volatile__("outl %1, %w0\n\t"
+                         :: "Nd" (Port),
+                            "a" (u32));
+
+# elif RT_INLINE_ASM_USES_INTRIN
+    __outdword(Port, u32);
+
+# else
+    __asm
+    {
+        mov     dx, [Port]
+        mov     eax, [u32]
+        out     dx, eax
+    }
+# endif
+}
+#endif
+
+
+/**
+ * Reads a 32-bit unsigned integer from an I/O port, ordered.
+ *
+ * @returns 32-bit integer.
+ * @param   Port    I/O port to read from.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(uint32_t) ASMInU32(RTIOPORT Port);
+#else
+DECLINLINE(uint32_t) ASMInU32(RTIOPORT Port)
+{
+    uint32_t u32;
+# if RT_INLINE_ASM_GNU_STYLE
+    __asm__ __volatile__("inl %w1, %0\n\t"
+                         : "=a" (u32)
+                         : "Nd" (Port));
+
+# elif RT_INLINE_ASM_USES_INTRIN
+    u32 = __indword(Port);
+
+# else
+    __asm
+    {
+        mov     dx, [Port]
+        in      eax, dx
+        mov     [u32], eax
+    }
+# endif
+    return u32;
+}
+#endif
+
+
+/**
+ * Writes a string of 8-bit unsigned integer items to an I/O port, ordered.
+ *
+ * @param   Port    I/O port to write to.
+ * @param   pau8    Pointer to the string buffer.
+ * @param   c       The number of items to write.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(void) ASMOutStrU8(RTIOPORT Port, uint8_t const *pau8, size_t c);
+#else
+DECLINLINE(void) ASMOutStrU8(RTIOPORT Port, uint8_t const *pau8, size_t c)
+{
+# if RT_INLINE_ASM_GNU_STYLE
+    __asm__ __volatile__("rep; outsb\n\t"
+                         : "+S" (pau8),
+                           "+c" (c)
+                         : "d" (Port));
+
+# elif RT_INLINE_ASM_USES_INTRIN
+    __outbytestring(Port, (unsigned char *)pau8, (unsigned long)c);
+
+# else
+    __asm
+    {
+        mov     dx, [Port]
+        mov     ecx, [c]
+        mov     eax, [pau8]
+        xchg    esi, eax
+        rep outsb
+        xchg    esi, eax
+    }
+# endif
+}
+#endif
+
+
+/**
+ * Reads a string of 8-bit unsigned integer items from an I/O port, ordered.
+ *
+ * @param   Port    I/O port to read from.
+ * @param   pau8    Pointer to the string buffer (output).
+ * @param   c       The number of items to read.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(void) ASMInStrU8(RTIOPORT Port, uint8_t *pau8, size_t c);
+#else
+DECLINLINE(void) ASMInStrU8(RTIOPORT Port, uint8_t *pau8, size_t c)
+{
+# if RT_INLINE_ASM_GNU_STYLE
+    __asm__ __volatile__("rep; insb\n\t"
+                         : "+D" (pau8),
+                           "+c" (c)
+                         : "d" (Port));
+
+# elif RT_INLINE_ASM_USES_INTRIN
+    __inbytestring(Port, pau8, (unsigned long)c);
+
+# else
+    __asm
+    {
+        mov     dx, [Port]
+        mov     ecx, [c]
+        mov     eax, [pau8]
+        xchg    edi, eax
+        rep insb
+        xchg    edi, eax
+    }
+# endif
+}
+#endif
+
+
+/**
+ * Writes a string of 16-bit unsigned integer items to an I/O port, ordered.
+ *
+ * @param   Port    I/O port to write to.
+ * @param   pau16   Pointer to the string buffer.
+ * @param   c       The number of items to write.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(void) ASMOutStrU16(RTIOPORT Port, uint16_t const *pau16, size_t c);
+#else
+DECLINLINE(void) ASMOutStrU16(RTIOPORT Port, uint16_t const *pau16, size_t c)
+{
+# if RT_INLINE_ASM_GNU_STYLE
+    __asm__ __volatile__("rep; outsw\n\t"
+                         : "+S" (pau16),
+                           "+c" (c)
+                         : "d" (Port));
+
+# elif RT_INLINE_ASM_USES_INTRIN
+    __outwordstring(Port, (unsigned short *)pau16, (unsigned long)c);
+
+# else
+    __asm
+    {
+        mov     dx, [Port]
+        mov     ecx, [c]
+        mov     eax, [pau16]
+        xchg    esi, eax
+        rep outsw
+        xchg    esi, eax
+    }
+# endif
+}
+#endif
+
+
+/**
+ * Reads a string of 16-bit unsigned integer items from an I/O port, ordered.
+ *
+ * @param   Port    I/O port to read from.
+ * @param   pau16   Pointer to the string buffer (output).
+ * @param   c       The number of items to read.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(void) ASMInStrU16(RTIOPORT Port, uint16_t *pau16, size_t c);
+#else
+DECLINLINE(void) ASMInStrU16(RTIOPORT Port, uint16_t *pau16, size_t c)
+{
+# if RT_INLINE_ASM_GNU_STYLE
+    __asm__ __volatile__("rep; insw\n\t"
+                         : "+D" (pau16),
+                           "+c" (c)
+                         : "d" (Port));
+
+# elif RT_INLINE_ASM_USES_INTRIN
+    __inwordstring(Port, pau16, (unsigned long)c);
+
+# else
+    __asm
+    {
+        mov     dx, [Port]
+        mov     ecx, [c]
+        mov     eax, [pau16]
+        xchg    edi, eax
+        rep insw
+        xchg    edi, eax
+    }
+# endif
+}
+#endif
+
+
+/**
+ * Writes a string of 32-bit unsigned integer items to an I/O port, ordered.
+ *
+ * @param   Port    I/O port to write to.
+ * @param   pau32   Pointer to the string buffer.
+ * @param   c       The number of items to write.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(void) ASMOutStrU32(RTIOPORT Port, uint32_t const *pau32, size_t c);
+#else
+DECLINLINE(void) ASMOutStrU32(RTIOPORT Port, uint32_t const *pau32, size_t c)
+{
+# if RT_INLINE_ASM_GNU_STYLE
+    __asm__ __volatile__("rep; outsl\n\t"
+                         : "+S" (pau32),
+                           "+c" (c)
+                         : "d" (Port));
+
+# elif RT_INLINE_ASM_USES_INTRIN
+    __outdwordstring(Port, (unsigned long *)pau32, (unsigned long)c);
+
+# else
+    __asm
+    {
+        mov     dx, [Port]
+        mov     ecx, [c]
+        mov     eax, [pau32]
+        xchg    esi, eax
+        rep outsd
+        xchg    esi, eax
+    }
+# endif
+}
+#endif
+
+
+/**
+ * Reads a string of 32-bit unsigned integer items from an I/O port, ordered.
+ *
+ * @param   Port    I/O port to read from.
+ * @param   pau32   Pointer to the string buffer (output).
+ * @param   c       The number of items to read.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(void) ASMInStrU32(RTIOPORT Port, uint32_t *pau32, size_t c);
+#else
+DECLINLINE(void) ASMInStrU32(RTIOPORT Port, uint32_t *pau32, size_t c)
+{
+# if RT_INLINE_ASM_GNU_STYLE
+    __asm__ __volatile__("rep; insl\n\t"
+                         : "+D" (pau32),
+                           "+c" (c)
+                         : "d" (Port));
+
+# elif RT_INLINE_ASM_USES_INTRIN
+    __indwordstring(Port, (unsigned long *)pau32, (unsigned long)c);
+
+# else
+    __asm
+    {
+        mov     dx, [Port]
+        mov     ecx, [c]
+        mov     eax, [pau32]
+        xchg    edi, eax
+        rep insd
+        xchg    edi, eax
+    }
+# endif
+}
+#endif
+
+
+/**
+ * Invalidate page.
+ *
+ * @param   pv      Address of the page to invalidate.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(void) ASMInvalidatePage(void *pv);
+#else
+DECLINLINE(void) ASMInvalidatePage(void *pv)
+{
+# if RT_INLINE_ASM_USES_INTRIN
+    __invlpg(pv);
+
+# elif RT_INLINE_ASM_GNU_STYLE
+    __asm__ __volatile__("invlpg %0\n\t"
+                         : : "m" (*(uint8_t *)pv));
+# else
+    __asm
+    {
+#  ifdef RT_ARCH_AMD64
+        mov     rax, [pv]
+        invlpg  [rax]
+#  else
+        mov     eax, [pv]
+        invlpg  [eax]
+#  endif
+    }
+# endif
+}
+#endif
+
+
+/**
+ * Write back the internal caches and invalidate them.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(void) ASMWriteBackAndInvalidateCaches(void);
+#else
+DECLINLINE(void) ASMWriteBackAndInvalidateCaches(void)
+{
+# if RT_INLINE_ASM_USES_INTRIN
+    __wbinvd();
+
+# elif RT_INLINE_ASM_GNU_STYLE
+    __asm__ __volatile__("wbinvd");
+# else
+    __asm
+    {
+        wbinvd
+    }
+# endif
+}
+#endif
+
+
+/**
+ * Invalidate internal and (perhaps) external caches without first
+ * flushing dirty cache lines. Use with extreme care.
+ */
+#if RT_INLINE_ASM_EXTERNAL
+DECLASM(void) ASMInvalidateInternalCaches(void);
+#else
+DECLINLINE(void) ASMInvalidateInternalCaches(void)
+{
+# if RT_INLINE_ASM_GNU_STYLE
+    __asm__ __volatile__("invd");
+# else
+    __asm
+    {
+        invd
+    }
+# endif
+}
+#endif
+
+
+/**
+ * Memory load/store fence, waits for any pending writes and reads to complete.
+ * Requires the X86_CPUID_FEATURE_EDX_SSE2 CPUID bit set.
+ */
+DECLINLINE(void) ASMMemoryFenceSSE2(void)
+{
+#if RT_INLINE_ASM_GNU_STYLE
+    __asm__ __volatile__ (".byte 0x0f,0xae,0xf0\n\t");
+#elif RT_INLINE_ASM_USES_INTRIN
+    _mm_mfence();
+#else
+    __asm
+    {
+        _emit   0x0f
+        _emit   0xae
+        _emit   0xf0
+    }
+#endif
+}
+
+
+/**
+ * Memory store fence, waits for any writes to complete.
+ * Requires the X86_CPUID_FEATURE_EDX_SSE CPUID bit set.
+ */
+DECLINLINE(void) ASMWriteFenceSSE(void)
+{
+#if RT_INLINE_ASM_GNU_STYLE
+    __asm__ __volatile__ (".byte 0x0f,0xae,0xf8\n\t");
+#elif RT_INLINE_ASM_USES_INTRIN
+    _mm_sfence();
+#else
+    __asm
+    {
+        _emit   0x0f
+        _emit   0xae
+        _emit   0xf8
+    }
+#endif
+}
+
+
+/**
+ * Memory load fence, waits for any pending reads to complete.
+ * Requires the X86_CPUID_FEATURE_EDX_SSE2 CPUID bit set.
+ */
+DECLINLINE(void) ASMReadFenceSSE2(void)
+{
+#if RT_INLINE_ASM_GNU_STYLE
+    __asm__ __volatile__ (".byte 0x0f,0xae,0xe8\n\t");
+#elif RT_INLINE_ASM_USES_INTRIN
+    _mm_lfence();
+#else
+    __asm
+    {
+        _emit   0x0f
+        _emit   0xae
+        _emit   0xe8
+    }
+#endif
+}
+
+#if !defined(_MSC_VER) || !defined(RT_ARCH_AMD64)
+
+/*
+ * Clear the AC bit in the EFLAGS register.
+ * Requires the X86_CPUID_STEXT_FEATURE_EBX_SMAP CPUID bit set.
+ * Requires to be executed in R0.
+ */
+DECLINLINE(void) ASMClearAC(void)
+{
+#if RT_INLINE_ASM_GNU_STYLE
+    __asm__ __volatile__ (".byte 0x0f,0x01,0xca\n\t");
+#else
+    __asm
+    {
+        _emit   0x0f
+        _emit   0x01
+        _emit   0xca
+    }
+#endif
+}
+
+
+/*
+ * Set the AC bit in the EFLAGS register.
+ * Requires the X86_CPUID_STEXT_FEATURE_EBX_SMAP CPUID bit set.
+ * Requires to be executed in R0.
+ */
+DECLINLINE(void) ASMSetAC(void)
+{
+#if RT_INLINE_ASM_GNU_STYLE
+    __asm__ __volatile__ (".byte 0x0f,0x01,0xcb\n\t");
+#else
+    __asm
+    {
+        _emit   0x0f
+        _emit   0x01
+        _emit   0xcb
+    }
+#endif
+}
+
+#endif /* !_MSC_VER) || !RT_ARCH_AMD64 */
+
+/** @} */
+#endif
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/include/iprt/asm-math.h
@@ -0,0 +1,434 @@
+/** @file
+ * IPRT - Assembly Routines for Optimizing some Integers Math Operations.
+ */
+
+/*
+ * Copyright (C) 2006-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+#ifndef ___iprt_asm_math_h
+#define ___iprt_asm_math_h
+
+#include <iprt/types.h>
+
+#if defined(_MSC_VER) && RT_INLINE_ASM_USES_INTRIN
+# include <intrin.h>
+  /* Emit the intrinsics at all optimization levels. */
+# pragma intrinsic(__emul)
+# pragma intrinsic(__emulu)
+# ifdef RT_ARCH_AMD64
+#  pragma intrinsic(_mul128)
+#  pragma intrinsic(_umul128)
+# endif
+#endif
+
+
+/** @defgroup grp_rt_asm_math   Interger Math Optimizations
+ * @ingroup grp_rt_asm
+ * @{ */
+
+/**
+ * Multiplies two unsigned 32-bit values returning an unsigned 64-bit result.
+ *
+ * @returns u32F1 * u32F2.
+ */
+
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN && defined(RT_ARCH_X86)
+DECLASM(uint64_t) ASMMult2xU32RetU64(uint32_t u32F1, uint32_t u32F2);
+#else
+DECLINLINE(uint64_t) ASMMult2xU32RetU64(uint32_t u32F1, uint32_t u32F2)
+{
+# ifdef RT_ARCH_X86
+    uint64_t u64;
+#  if RT_INLINE_ASM_GNU_STYLE
+    __asm__ __volatile__("mull %%edx"
+                         : "=A" (u64)
+                         : "a" (u32F2), "d" (u32F1));
+#  elif RT_INLINE_ASM_USES_INTRIN
+    u64 = __emulu(u32F1, u32F2);
+#  else
+    __asm
+    {
+        mov     edx, [u32F1]
+        mov     eax, [u32F2]
+        mul     edx
+        mov     dword ptr [u64], eax
+        mov     dword ptr [u64 + 4], edx
+    }
+#  endif
+    return u64;
+# else  /* generic: */
+    return (uint64_t)u32F1 * u32F2;
+# endif
+}
+#endif
+
+
+/**
+ * Multiplies two signed 32-bit values returning a signed 64-bit result.
+ *
+ * @returns u32F1 * u32F2.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN && defined(RT_ARCH_X86)
+DECLASM(int64_t) ASMMult2xS32RetS64(int32_t i32F1, int32_t i32F2);
+#else
+DECLINLINE(int64_t) ASMMult2xS32RetS64(int32_t i32F1, int32_t i32F2)
+{
+# ifdef RT_ARCH_X86
+    int64_t i64;
+#  if RT_INLINE_ASM_GNU_STYLE
+    __asm__ __volatile__("imull %%edx"
+                         : "=A" (i64)
+                         : "a" (i32F2), "d" (i32F1));
+#  elif RT_INLINE_ASM_USES_INTRIN
+    i64 = __emul(i32F1, i32F2);
+#  else
+    __asm
+    {
+        mov     edx, [i32F1]
+        mov     eax, [i32F2]
+        imul    edx
+        mov     dword ptr [i64], eax
+        mov     dword ptr [i64 + 4], edx
+    }
+#  endif
+    return i64;
+# else  /* generic: */
+    return (int64_t)i32F1 * i32F2;
+# endif
+}
+#endif
+
+
+#if ARCH_BITS == 64
+DECLINLINE(uint64_t) ASMMult2xU64Ret2xU64(uint64_t u64F1, uint64_t u64F2, uint64_t *pu64ProdHi)
+{
+# if defined(RT_ARCH_AMD64) && (RT_INLINE_ASM_GNU_STYLE || RT_INLINE_ASM_USES_INTRIN)
+#  if RT_INLINE_ASM_GNU_STYLE
+    uint64_t u64Low, u64High;
+    __asm__ __volatile__("mulq %%rdx"
+                         : "=a" (u64Low), "=d" (u64High)
+                         : "0" (u64F1), "1" (u64F2));
+    *pu64ProdHi = u64High;
+    return u64Low;
+#  elif RT_INLINE_ASM_USES_INTRIN
+    return _umul128(u64F1, u64F2, pu64ProdHi);
+#  else
+#   error "hmm"
+#  endif
+# else  /* generic: */
+    /*
+     *   F1 * F2 = Prod
+     *   --   --
+     *   ab * cd =  b*d + a*d*10  +  b*c*10 + a*c*100
+     *
+     * Where a, b, c and d are 'digits', and 10 is max digit + 1.
+     *
+     * Our digits are 32-bit wide, so instead of 10 we multiply by 4G.
+     *  Prod = F1.s.Lo*F2.s.Lo    + F1.s.Hi*F2.s.Lo*4G
+     *       + F1.s.Lo*F2.s.Hi*4G + F1.s.Hi*F2.s.Hi*4G*4G
+     */
+    RTUINT128U Prod;
+    RTUINT64U  Tmp1;
+    uint64_t   u64Tmp;
+    RTUINT64U  F1, F2;
+    F1.u = u64F1;
+    F2.u = u64F2;
+
+    Prod.s.Lo = ASMMult2xU32RetU64(F1.s.Lo, F2.s.Lo);
+
+    Tmp1.u = ASMMult2xU32RetU64(F1.s.Hi, F2.s.Lo);
+    u64Tmp = (uint64_t)Prod.DWords.dw1 + Tmp1.s.Lo;
+    Prod.DWords.dw1 = (uint32_t)u64Tmp;
+    Prod.s.Hi = Tmp1.s.Hi;
+    Prod.s.Hi += u64Tmp >> 32; /* carry */
+
+    Tmp1.u = ASMMult2xU32RetU64(F1.s.Lo, F2.s.Hi);
+    u64Tmp = (uint64_t)Prod.DWords.dw1 + Tmp1.s.Lo;
+    Prod.DWords.dw1 = (uint32_t)u64Tmp;
+    u64Tmp >>= 32;      /* carry */
+    u64Tmp += Prod.DWords.dw2;
+    u64Tmp += Tmp1.s.Hi;
+    Prod.DWords.dw2 = (uint32_t)u64Tmp;
+    Prod.DWords.dw3 += u64Tmp >> 32; /* carry */
+
+    Prod.s.Hi += ASMMult2xU32RetU64(F1.s.Hi, F2.s.Hi);
+    *pu64ProdHi  = Prod.s.Hi;
+    return Prod.s.Lo;
+# endif
+}
+#endif
+
+
+
+/**
+ * Divides a 64-bit unsigned by a 32-bit unsigned returning an unsigned 32-bit result.
+ *
+ * @returns u64 / u32.
+ */
+#if RT_INLINE_ASM_EXTERNAL && defined(RT_ARCH_X86)
+DECLASM(uint32_t) ASMDivU64ByU32RetU32(uint64_t u64, uint32_t u32);
+#else
+DECLINLINE(uint32_t) ASMDivU64ByU32RetU32(uint64_t u64, uint32_t u32)
+{
+# ifdef RT_ARCH_X86
+#  if RT_INLINE_ASM_GNU_STYLE
+    RTCCUINTREG uDummy;
+    __asm__ __volatile__("divl %3"
+                         : "=a" (u32), "=d"(uDummy)
+                         : "A" (u64), "r" (u32));
+#  else
+    __asm
+    {
+        mov     eax, dword ptr [u64]
+        mov     edx, dword ptr [u64 + 4]
+        mov     ecx, [u32]
+        div     ecx
+        mov     [u32], eax
+    }
+#  endif
+    return u32;
+# else   /* generic: */
+    return (uint32_t)(u64 / u32);
+# endif
+}
+#endif
+
+
+/**
+ * Divides a 64-bit signed by a 32-bit signed returning a signed 32-bit result.
+ *
+ * @returns u64 / u32.
+ */
+#if RT_INLINE_ASM_EXTERNAL && defined(RT_ARCH_X86)
+DECLASM(int32_t) ASMDivS64ByS32RetS32(int64_t i64, int32_t i32);
+#else
+DECLINLINE(int32_t) ASMDivS64ByS32RetS32(int64_t i64, int32_t i32)
+{
+# ifdef RT_ARCH_X86
+#  if RT_INLINE_ASM_GNU_STYLE
+    RTCCUINTREG iDummy;
+    __asm__ __volatile__("idivl %3"
+                         : "=a" (i32), "=d"(iDummy)
+                         : "A" (i64), "r" (i32));
+#  else
+    __asm
+    {
+        mov     eax, dword ptr [i64]
+        mov     edx, dword ptr [i64 + 4]
+        mov     ecx, [i32]
+        idiv    ecx
+        mov     [i32], eax
+    }
+#  endif
+    return i32;
+# else  /* generic: */
+    return (int32_t)(i64 / i32);
+# endif
+}
+#endif
+
+
+/**
+ * Performs 64-bit unsigned by a 32-bit unsigned division with a 32-bit unsigned result,
+ * returning the rest.
+ *
+ * @returns u64 % u32.
+ *
+ * @remarks It is important that the result is <= UINT32_MAX or we'll overflow and crash.
+ */
+#if RT_INLINE_ASM_EXTERNAL && defined(RT_ARCH_X86)
+DECLASM(uint32_t) ASMModU64ByU32RetU32(uint64_t u64, uint32_t u32);
+#else
+DECLINLINE(uint32_t) ASMModU64ByU32RetU32(uint64_t u64, uint32_t u32)
+{
+# ifdef RT_ARCH_X86
+#  if RT_INLINE_ASM_GNU_STYLE
+    RTCCUINTREG uDummy;
+    __asm__ __volatile__("divl %3"
+                         : "=a" (uDummy), "=d"(u32)
+                         : "A" (u64), "r" (u32));
+#  else
+    __asm
+    {
+        mov     eax, dword ptr [u64]
+        mov     edx, dword ptr [u64 + 4]
+        mov     ecx, [u32]
+        div     ecx
+        mov     [u32], edx
+    }
+#  endif
+    return u32;
+# else  /* generic: */
+    return (uint32_t)(u64 % u32);
+# endif
+}
+#endif
+
+
+/**
+ * Performs 64-bit signed by a 32-bit signed division with a 32-bit signed result,
+ * returning the rest.
+ *
+ * @returns u64 % u32.
+ *
+ * @remarks It is important that the result is <= UINT32_MAX or we'll overflow and crash.
+ */
+#if RT_INLINE_ASM_EXTERNAL && defined(RT_ARCH_X86)
+DECLASM(int32_t) ASMModS64ByS32RetS32(int64_t i64, int32_t i32);
+#else
+DECLINLINE(int32_t) ASMModS64ByS32RetS32(int64_t i64, int32_t i32)
+{
+# ifdef RT_ARCH_X86
+#  if RT_INLINE_ASM_GNU_STYLE
+    RTCCUINTREG iDummy;
+    __asm__ __volatile__("idivl %3"
+                         : "=a" (iDummy), "=d"(i32)
+                         : "A" (i64), "r" (i32));
+#  else
+    __asm
+    {
+        mov     eax, dword ptr [i64]
+        mov     edx, dword ptr [i64 + 4]
+        mov     ecx, [i32]
+        idiv    ecx
+        mov     [i32], edx
+    }
+#  endif
+    return i32;
+# else  /* generic: */
+    return (int32_t)(i64 % i32);
+# endif
+}
+#endif
+
+
+/**
+ * Multiple a 32-bit by a 32-bit integer and divide the result by a 32-bit integer
+ * using a 64 bit intermediate result.
+ *
+ * @returns (u32A * u32B) / u32C.
+ * @param   u32A    The 32-bit value (A).
+ * @param   u32B    The 32-bit value to multiple by A.
+ * @param   u32C    The 32-bit value to divide A*B by.
+ *
+ * @remarks Architecture specific.
+ * @remarks Make sure the result won't ever exceed 32-bit, because hardware
+ *          exception may be raised if it does.
+ * @remarks On x86 this may be used to avoid dragging in 64-bit builtin
+ *          arithmetics functions.
+ */
+#if RT_INLINE_ASM_EXTERNAL && (defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86))
+DECLASM(uint32_t) ASMMultU32ByU32DivByU32(uint32_t u32A, uint32_t u32B, uint32_t u32C);
+#else
+DECLINLINE(uint32_t) ASMMultU32ByU32DivByU32(uint32_t u32A, uint32_t u32B, uint32_t u32C)
+{
+# if RT_INLINE_ASM_GNU_STYLE && (defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86))
+    uint32_t u32Result, u32Spill;
+    __asm__ __volatile__("mull %2\n\t"
+                         "divl %3\n\t"
+                         : "=&a" (u32Result),
+                           "=&d" (u32Spill)
+                         : "r" (u32B),
+                           "r" (u32C),
+                           "0" (u32A));
+    return u32Result;
+# else
+    return (uint32_t)(((uint64_t)u32A * u32B) / u32C);
+# endif
+}
+#endif
+
+
+/**
+ * Multiple a 64-bit by a 32-bit integer and divide the result by a 32-bit integer
+ * using a 96 bit intermediate result.
+ *
+ * @returns (u64A * u32B) / u32C.
+ * @param   u64A    The 64-bit value.
+ * @param   u32B    The 32-bit value to multiple by A.
+ * @param   u32C    The 32-bit value to divide A*B by.
+ *
+ * @remarks Architecture specific.
+ * @remarks Make sure the result won't ever exceed 64-bit, because hardware
+ *          exception may be raised if it does.
+ * @remarks On x86 this may be used to avoid dragging in 64-bit builtin
+ *          arithmetics function.
+ */
+#if RT_INLINE_ASM_EXTERNAL || !defined(__GNUC__) || (!defined(RT_ARCH_AMD64) && !defined(RT_ARCH_X86))
+DECLASM(uint64_t) ASMMultU64ByU32DivByU32(uint64_t u64A, uint32_t u32B, uint32_t u32C);
+#else
+DECLINLINE(uint64_t) ASMMultU64ByU32DivByU32(uint64_t u64A, uint32_t u32B, uint32_t u32C)
+{
+# if RT_INLINE_ASM_GNU_STYLE
+#  ifdef RT_ARCH_AMD64
+    uint64_t u64Result, u64Spill;
+    __asm__ __volatile__("mulq %2\n\t"
+                         "divq %3\n\t"
+                         : "=&a" (u64Result),
+                           "=&d" (u64Spill)
+                         : "r" ((uint64_t)u32B),
+                           "r" ((uint64_t)u32C),
+                           "0" (u64A));
+    return u64Result;
+#  else
+    uint32_t u32Dummy;
+    uint64_t u64Result;
+    __asm__ __volatile__("mull %%ecx       \n\t" /* eax = u64Lo.lo = (u64A.lo * u32B).lo
+                                                    edx = u64Lo.hi = (u64A.lo * u32B).hi */
+                         "xchg %%eax,%%esi \n\t" /* esi = u64Lo.lo
+                                                    eax = u64A.hi */
+                         "xchg %%edx,%%edi \n\t" /* edi = u64Low.hi
+                                                    edx = u32C */
+                         "xchg %%edx,%%ecx \n\t" /* ecx = u32C
+                                                    edx = u32B */
+                         "mull %%edx       \n\t" /* eax = u64Hi.lo = (u64A.hi * u32B).lo
+                                                    edx = u64Hi.hi = (u64A.hi * u32B).hi */
+                         "addl %%edi,%%eax \n\t" /* u64Hi.lo += u64Lo.hi */
+                         "adcl $0,%%edx    \n\t" /* u64Hi.hi += carry */
+                         "divl %%ecx       \n\t" /* eax = u64Hi / u32C
+                                                    edx = u64Hi % u32C */
+                         "movl %%eax,%%edi \n\t" /* edi = u64Result.hi = u64Hi / u32C */
+                         "movl %%esi,%%eax \n\t" /* eax = u64Lo.lo */
+                         "divl %%ecx       \n\t" /* u64Result.lo */
+                         "movl %%edi,%%edx \n\t" /* u64Result.hi */
+                         : "=A"(u64Result), "=c"(u32Dummy),
+                           "=S"(u32Dummy), "=D"(u32Dummy)
+                         : "a"((uint32_t)u64A),
+                           "S"((uint32_t)(u64A >> 32)),
+                           "c"(u32B),
+                           "D"(u32C));
+    return u64Result;
+#  endif
+# else
+    RTUINT64U   u;
+    uint64_t    u64Lo = (uint64_t)(u64A & 0xffffffff) * u32B;
+    uint64_t    u64Hi = (uint64_t)(u64A >> 32)        * u32B;
+    u64Hi  += (u64Lo >> 32);
+    u.s.Hi = (uint32_t)(u64Hi / u32C);
+    u.s.Lo = (uint32_t)((((u64Hi % u32C) << 32) + (u64Lo & 0xffffffff)) / u32C);
+    return u.u;
+# endif
+}
+#endif
+
+/** @} */
+#endif
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/include/iprt/asm.h
@@ -0,0 +1,5024 @@
+/** @file
+ * IPRT - Assembly Functions.
+ */
+
+/*
+ * Copyright (C) 2006-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+#ifndef ___iprt_asm_h
+#define ___iprt_asm_h
+
+#include <iprt/cdefs.h>
+#include <iprt/types.h>
+#include <iprt/assert.h>
+/** @def RT_INLINE_ASM_USES_INTRIN
+ * Defined as 1 if we're using a _MSC_VER 1400.
+ * Otherwise defined as 0.
+ */
+
+/* Solaris 10 header ugliness */
+#ifdef u
+# undef u
+#endif
+
+#if defined(_MSC_VER) && RT_INLINE_ASM_USES_INTRIN
+# include <intrin.h>
+  /* Emit the intrinsics at all optimization levels. */
+# pragma intrinsic(_ReadWriteBarrier)
+# pragma intrinsic(__cpuid)
+# pragma intrinsic(__stosd)
+# pragma intrinsic(__stosw)
+# pragma intrinsic(__stosb)
+# pragma intrinsic(_BitScanForward)
+# pragma intrinsic(_BitScanReverse)
+# pragma intrinsic(_bittest)
+# pragma intrinsic(_bittestandset)
+# pragma intrinsic(_bittestandreset)
+# pragma intrinsic(_bittestandcomplement)
+# pragma intrinsic(_byteswap_ushort)
+# pragma intrinsic(_byteswap_ulong)
+# pragma intrinsic(_interlockedbittestandset)
+# pragma intrinsic(_interlockedbittestandreset)
+# pragma intrinsic(_InterlockedAnd)
+# pragma intrinsic(_InterlockedOr)
+# pragma intrinsic(_InterlockedIncrement)
+# pragma intrinsic(_InterlockedDecrement)
+# pragma intrinsic(_InterlockedExchange)
+# pragma intrinsic(_InterlockedExchangeAdd)
+# pragma intrinsic(_InterlockedCompareExchange)
+# pragma intrinsic(_InterlockedCompareExchange64)
+# pragma intrinsic(_rotl)
+# pragma intrinsic(_rotr)
+# pragma intrinsic(_rotl64)
+# pragma intrinsic(_rotr64)
+# ifdef RT_ARCH_AMD64
+#  pragma intrinsic(__stosq)
+#  pragma intrinsic(_byteswap_uint64)
+#  pragma intrinsic(_InterlockedExchange64)
+#  pragma intrinsic(_InterlockedExchangeAdd64)
+#  pragma intrinsic(_InterlockedAnd64)
+#  pragma intrinsic(_InterlockedOr64)
+#  pragma intrinsic(_InterlockedIncrement64)
+#  pragma intrinsic(_InterlockedDecrement64)
+# endif
+#endif
+
+
+/** @defgroup grp_rt_asm    ASM - Assembly Routines
+ * @ingroup grp_rt
+ *
+ * @remarks The difference between ordered and unordered atomic operations are that
+ *          the former will complete outstanding reads and writes before continuing
+ *          while the latter doesn't make any promises about the order. Ordered
+ *          operations doesn't, it seems, make any 100% promise wrt to whether
+ *          the operation will complete before any subsequent memory access.
+ *          (please, correct if wrong.)
+ *
+ *          ASMAtomicSomething operations are all ordered, while ASMAtomicUoSomething
+ *          are unordered (note the Uo).
+ *
+ * @remarks Some remarks about __volatile__: Without this keyword gcc is allowed to reorder
+ *          or even optimize assembler instructions away. For instance, in the following code
+ *          the second rdmsr instruction is optimized away because gcc treats that instruction
+ *          as deterministic:
+ *
+ *            @code
+ *            static inline uint64_t rdmsr_low(int idx)
+ *            {
+ *              uint32_t low;
+ *              __asm__ ("rdmsr" : "=a"(low) : "c"(idx) : "edx");
+ *            }
+ *            ...
+ *            uint32_t msr1 = rdmsr_low(1);
+ *            foo(msr1);
+ *            msr1 = rdmsr_low(1);
+ *            bar(msr1);
+ *            @endcode
+ *
+ *          The input parameter of rdmsr_low is the same for both calls and therefore gcc will
+ *          use the result of the first call as input parameter for bar() as well. For rdmsr this
+ *          is not acceptable as this instruction is _not_ deterministic. This applies to reading
+ *          machine status information in general.
+ *
+ * @{
+ */
+
+
+/** @def RT_INLINE_ASM_GCC_4_3_X_X86
+ * Used to work around some 4.3.x register allocation issues in this version of
+ * the compiler. So far this workaround is still required for 4.4 and 4.5. */
+#ifdef __GNUC__
+# define RT_INLINE_ASM_GCC_4_3_X_X86 (__GNUC__ == 4 && __GNUC_MINOR__ >= 3 && defined(__i386__))
+#endif
+#ifndef RT_INLINE_ASM_GCC_4_3_X_X86
+# define RT_INLINE_ASM_GCC_4_3_X_X86 0
+#endif
+
+/** @def RT_INLINE_DONT_MIX_CMPXCHG8B_AND_PIC
+ * i686-apple-darwin9-gcc-4.0.1 (GCC) 4.0.1 (Apple Inc. build 5493) screws up
+ * RTSemRWRequestWrite semsemrw-lockless-generic.cpp in release builds. PIC
+ * mode, x86.
+ *
+ * Some gcc 4.3.x versions may have register allocation issues with cmpxchg8b
+ * when in PIC mode on x86.
+ */
+#ifndef RT_INLINE_DONT_MIX_CMPXCHG8B_AND_PIC
+# ifdef DOXYGEN_RUNNING
+#  define RT_INLINE_DONT_MIX_CMPXCHG8B_AND_PIC 1
+# else
+#  define RT_INLINE_DONT_MIX_CMPXCHG8B_AND_PIC \
+    (   (defined(PIC) || defined(__PIC__)) \
+     && defined(RT_ARCH_X86) \
+     && (   RT_INLINE_ASM_GCC_4_3_X_X86 \
+         || defined(RT_OS_DARWIN)) )
+# endif
+#endif
+
+
+/** @def ASMReturnAddress
+ * Gets the return address of the current (or calling if you like) function or method.
+ */
+#ifdef _MSC_VER
+# ifdef __cplusplus
+extern "C"
+# endif
+void * _ReturnAddress(void);
+# pragma intrinsic(_ReturnAddress)
+# define ASMReturnAddress() _ReturnAddress()
+#elif defined(__GNUC__) || defined(DOXYGEN_RUNNING)
+# define ASMReturnAddress() __builtin_return_address(0)
+#else
+# error "Unsupported compiler."
+#endif
+
+
+/**
+ * Compiler memory barrier.
+ *
+ * Ensure that the compiler does not use any cached (register/tmp stack) memory
+ * values or any outstanding writes when returning from this function.
+ *
+ * This function must be used if non-volatile data is modified by a
+ * device or the VMM. Typical cases are port access, MMIO access,
+ * trapping instruction, etc.
+ */
+#if RT_INLINE_ASM_GNU_STYLE
+# define ASMCompilerBarrier()   do { __asm__ __volatile__("" : : : "memory"); } while (0)
+#elif RT_INLINE_ASM_USES_INTRIN
+# define ASMCompilerBarrier()   do { _ReadWriteBarrier(); } while (0)
+#else /* 2003 should have _ReadWriteBarrier() but I guess we're at 2002 level then... */
+DECLINLINE(void) ASMCompilerBarrier(void)
+{
+    __asm
+    {
+    }
+}
+#endif
+
+
+/** @def ASMBreakpoint
+ * Debugger Breakpoint.
+ * @deprecated Use RT_BREAKPOINT instead.
+ * @internal
+ */
+#define ASMBreakpoint() RT_BREAKPOINT()
+
+
+/**
+ * Spinloop hint for platforms that have these, empty function on the other
+ * platforms.
+ *
+ * x86 & AMD64: The PAUSE variant of NOP for helping hyperthreaded CPUs detecting
+ * spin locks.
+ */
+#if RT_INLINE_ASM_EXTERNAL && (defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86))
+DECLASM(void) ASMNopPause(void);
+#else
+DECLINLINE(void) ASMNopPause(void)
+{
+# if defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86)
+#  if RT_INLINE_ASM_GNU_STYLE
+    __asm__ __volatile__(".byte 0xf3,0x90\n\t");
+#  else
+    __asm {
+        _emit 0f3h
+        _emit 090h
+    }
+#  endif
+# else
+    /* dummy */
+# endif
+}
+#endif
+
+
+/**
+ * Atomically Exchange an unsigned 8-bit value, ordered.
+ *
+ * @returns Current *pu8 value
+ * @param   pu8    Pointer to the 8-bit variable to update.
+ * @param   u8     The 8-bit value to assign to *pu8.
+ */
+#if RT_INLINE_ASM_EXTERNAL
+DECLASM(uint8_t) ASMAtomicXchgU8(volatile uint8_t *pu8, uint8_t u8);
+#else
+DECLINLINE(uint8_t) ASMAtomicXchgU8(volatile uint8_t *pu8, uint8_t u8)
+{
+# if RT_INLINE_ASM_GNU_STYLE
+    __asm__ __volatile__("xchgb %0, %1\n\t"
+                         : "=m" (*pu8),
+                           "=q" (u8) /* =r - busted on g++ (GCC) 3.4.4 20050721 (Red Hat 3.4.4-2) */
+                         : "1" (u8),
+                           "m" (*pu8));
+# else
+    __asm
+    {
+#  ifdef RT_ARCH_AMD64
+        mov     rdx, [pu8]
+        mov     al, [u8]
+        xchg    [rdx], al
+        mov     [u8], al
+#  else
+        mov     edx, [pu8]
+        mov     al, [u8]
+        xchg    [edx], al
+        mov     [u8], al
+#  endif
+    }
+# endif
+    return u8;
+}
+#endif
+
+
+/**
+ * Atomically Exchange a signed 8-bit value, ordered.
+ *
+ * @returns Current *pu8 value
+ * @param   pi8     Pointer to the 8-bit variable to update.
+ * @param   i8      The 8-bit value to assign to *pi8.
+ */
+DECLINLINE(int8_t) ASMAtomicXchgS8(volatile int8_t *pi8, int8_t i8)
+{
+    return (int8_t)ASMAtomicXchgU8((volatile uint8_t *)pi8, (uint8_t)i8);
+}
+
+
+/**
+ * Atomically Exchange a bool value, ordered.
+ *
+ * @returns Current *pf value
+ * @param   pf      Pointer to the 8-bit variable to update.
+ * @param   f       The 8-bit value to assign to *pi8.
+ */
+DECLINLINE(bool) ASMAtomicXchgBool(volatile bool *pf, bool f)
+{
+#ifdef _MSC_VER
+    return !!ASMAtomicXchgU8((volatile uint8_t *)pf, (uint8_t)f);
+#else
+    return (bool)ASMAtomicXchgU8((volatile uint8_t *)pf, (uint8_t)f);
+#endif
+}
+
+
+/**
+ * Atomically Exchange an unsigned 16-bit value, ordered.
+ *
+ * @returns Current *pu16 value
+ * @param   pu16    Pointer to the 16-bit variable to update.
+ * @param   u16     The 16-bit value to assign to *pu16.
+ */
+#if RT_INLINE_ASM_EXTERNAL
+DECLASM(uint16_t) ASMAtomicXchgU16(volatile uint16_t *pu16, uint16_t u16);
+#else
+DECLINLINE(uint16_t) ASMAtomicXchgU16(volatile uint16_t *pu16, uint16_t u16)
+{
+# if RT_INLINE_ASM_GNU_STYLE
+    __asm__ __volatile__("xchgw %0, %1\n\t"
+                         : "=m" (*pu16),
+                           "=r" (u16)
+                         : "1" (u16),
+                           "m" (*pu16));
+# else
+    __asm
+    {
+#  ifdef RT_ARCH_AMD64
+        mov     rdx, [pu16]
+        mov     ax, [u16]
+        xchg    [rdx], ax
+        mov     [u16], ax
+#  else
+        mov     edx, [pu16]
+        mov     ax, [u16]
+        xchg    [edx], ax
+        mov     [u16], ax
+#  endif
+    }
+# endif
+    return u16;
+}
+#endif
+
+
+/**
+ * Atomically Exchange a signed 16-bit value, ordered.
+ *
+ * @returns Current *pu16 value
+ * @param   pi16    Pointer to the 16-bit variable to update.
+ * @param   i16     The 16-bit value to assign to *pi16.
+ */
+DECLINLINE(int16_t) ASMAtomicXchgS16(volatile int16_t *pi16, int16_t i16)
+{
+    return (int16_t)ASMAtomicXchgU16((volatile uint16_t *)pi16, (uint16_t)i16);
+}
+
+
+/**
+ * Atomically Exchange an unsigned 32-bit value, ordered.
+ *
+ * @returns Current *pu32 value
+ * @param   pu32    Pointer to the 32-bit variable to update.
+ * @param   u32     The 32-bit value to assign to *pu32.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(uint32_t) ASMAtomicXchgU32(volatile uint32_t *pu32, uint32_t u32);
+#else
+DECLINLINE(uint32_t) ASMAtomicXchgU32(volatile uint32_t *pu32, uint32_t u32)
+{
+# if RT_INLINE_ASM_GNU_STYLE
+    __asm__ __volatile__("xchgl %0, %1\n\t"
+                         : "=m" (*pu32),
+                           "=r" (u32)
+                         : "1" (u32),
+                           "m" (*pu32));
+
+# elif RT_INLINE_ASM_USES_INTRIN
+   u32 = _InterlockedExchange((long *)pu32, u32);
+
+# else
+    __asm
+    {
+#  ifdef RT_ARCH_AMD64
+        mov     rdx, [pu32]
+        mov     eax, u32
+        xchg    [rdx], eax
+        mov     [u32], eax
+#  else
+        mov     edx, [pu32]
+        mov     eax, u32
+        xchg    [edx], eax
+        mov     [u32], eax
+#  endif
+    }
+# endif
+    return u32;
+}
+#endif
+
+
+/**
+ * Atomically Exchange a signed 32-bit value, ordered.
+ *
+ * @returns Current *pu32 value
+ * @param   pi32    Pointer to the 32-bit variable to update.
+ * @param   i32     The 32-bit value to assign to *pi32.
+ */
+DECLINLINE(int32_t) ASMAtomicXchgS32(volatile int32_t *pi32, int32_t i32)
+{
+    return (int32_t)ASMAtomicXchgU32((volatile uint32_t *)pi32, (uint32_t)i32);
+}
+
+
+/**
+ * Atomically Exchange an unsigned 64-bit value, ordered.
+ *
+ * @returns Current *pu64 value
+ * @param   pu64    Pointer to the 64-bit variable to update.
+ * @param   u64     The 64-bit value to assign to *pu64.
+ */
+#if (RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN) \
+ || RT_INLINE_DONT_MIX_CMPXCHG8B_AND_PIC
+DECLASM(uint64_t) ASMAtomicXchgU64(volatile uint64_t *pu64, uint64_t u64);
+#else
+DECLINLINE(uint64_t) ASMAtomicXchgU64(volatile uint64_t *pu64, uint64_t u64)
+{
+# if defined(RT_ARCH_AMD64)
+#  if RT_INLINE_ASM_USES_INTRIN
+   u64 = _InterlockedExchange64((__int64 *)pu64, u64);
+
+#  elif RT_INLINE_ASM_GNU_STYLE
+    __asm__ __volatile__("xchgq %0, %1\n\t"
+                         : "=m" (*pu64),
+                           "=r" (u64)
+                         : "1" (u64),
+                           "m" (*pu64));
+#  else
+    __asm
+    {
+        mov     rdx, [pu64]
+        mov     rax, [u64]
+        xchg    [rdx], rax
+        mov     [u64], rax
+    }
+#  endif
+# else /* !RT_ARCH_AMD64 */
+#  if RT_INLINE_ASM_GNU_STYLE
+#   if defined(PIC) || defined(__PIC__)
+    uint32_t u32EBX = (uint32_t)u64;
+    __asm__ __volatile__(/*"xchgl %%esi, %5\n\t"*/
+                         "xchgl %%ebx, %3\n\t"
+                         "1:\n\t"
+                         "lock; cmpxchg8b (%5)\n\t"
+                         "jnz 1b\n\t"
+                         "movl %3, %%ebx\n\t"
+                         /*"xchgl %%esi, %5\n\t"*/
+                         : "=A" (u64),
+                           "=m" (*pu64)
+                         : "0" (*pu64),
+                           "m" ( u32EBX ),
+                           "c" ( (uint32_t)(u64 >> 32) ),
+                           "S" (pu64));
+#   else /* !PIC */
+    __asm__ __volatile__("1:\n\t"
+                         "lock; cmpxchg8b %1\n\t"
+                         "jnz 1b\n\t"
+                         : "=A" (u64),
+                           "=m" (*pu64)
+                         : "0" (*pu64),
+                           "b" ( (uint32_t)u64 ),
+                           "c" ( (uint32_t)(u64 >> 32) ));
+#   endif
+#  else
+    __asm
+    {
+        mov     ebx, dword ptr [u64]
+        mov     ecx, dword ptr [u64 + 4]
+        mov     edi, pu64
+        mov     eax, dword ptr [edi]
+        mov     edx, dword ptr [edi + 4]
+    retry:
+        lock cmpxchg8b [edi]
+        jnz retry
+        mov     dword ptr [u64], eax
+        mov     dword ptr [u64 + 4], edx
+    }
+#  endif
+# endif /* !RT_ARCH_AMD64 */
+    return u64;
+}
+#endif
+
+
+/**
+ * Atomically Exchange an signed 64-bit value, ordered.
+ *
+ * @returns Current *pi64 value
+ * @param   pi64    Pointer to the 64-bit variable to update.
+ * @param   i64     The 64-bit value to assign to *pi64.
+ */
+DECLINLINE(int64_t) ASMAtomicXchgS64(volatile int64_t *pi64, int64_t i64)
+{
+    return (int64_t)ASMAtomicXchgU64((volatile uint64_t *)pi64, (uint64_t)i64);
+}
+
+
+/**
+ * Atomically Exchange a pointer value, ordered.
+ *
+ * @returns Current *ppv value
+ * @param   ppv    Pointer to the pointer variable to update.
+ * @param   pv     The pointer value to assign to *ppv.
+ */
+DECLINLINE(void *) ASMAtomicXchgPtr(void * volatile *ppv, const void *pv)
+{
+#if ARCH_BITS == 32
+    return (void *)ASMAtomicXchgU32((volatile uint32_t *)(void *)ppv, (uint32_t)pv);
+#elif ARCH_BITS == 64
+    return (void *)ASMAtomicXchgU64((volatile uint64_t *)(void *)ppv, (uint64_t)pv);
+#else
+# error "ARCH_BITS is bogus"
+#endif
+}
+
+
+/**
+ * Convenience macro for avoiding the annoying casting with ASMAtomicXchgPtr.
+ *
+ * @returns Current *pv value
+ * @param   ppv     Pointer to the pointer variable to update.
+ * @param   pv      The pointer value to assign to *ppv.
+ * @param   Type    The type of *ppv, sans volatile.
+ */
+#ifdef __GNUC__
+# define ASMAtomicXchgPtrT(ppv, pv, Type) \
+    __extension__ \
+    ({\
+        __typeof__(*(ppv)) volatile * const ppvTypeChecked = (ppv); \
+        Type                          const pvTypeChecked  = (pv); \
+        Type pvTypeCheckedRet = (__typeof__(*(ppv))) ASMAtomicXchgPtr((void * volatile *)ppvTypeChecked, (void *)pvTypeChecked); \
+        pvTypeCheckedRet; \
+     })
+#else
+# define ASMAtomicXchgPtrT(ppv, pv, Type) \
+    (Type)ASMAtomicXchgPtr((void * volatile *)(ppv), (void *)(pv))
+#endif
+
+
+/**
+ * Atomically Exchange a raw-mode context pointer value, ordered.
+ *
+ * @returns Current *ppv value
+ * @param   ppvRC   Pointer to the pointer variable to update.
+ * @param   pvRC    The pointer value to assign to *ppv.
+ */
+DECLINLINE(RTRCPTR) ASMAtomicXchgRCPtr(RTRCPTR volatile *ppvRC, RTRCPTR pvRC)
+{
+    return (RTRCPTR)ASMAtomicXchgU32((uint32_t volatile *)(void *)ppvRC, (uint32_t)pvRC);
+}
+
+
+/**
+ * Atomically Exchange a ring-0 pointer value, ordered.
+ *
+ * @returns Current *ppv value
+ * @param   ppvR0  Pointer to the pointer variable to update.
+ * @param   pvR0   The pointer value to assign to *ppv.
+ */
+DECLINLINE(RTR0PTR) ASMAtomicXchgR0Ptr(RTR0PTR volatile *ppvR0, RTR0PTR pvR0)
+{
+#if R0_ARCH_BITS == 32
+    return (RTR0PTR)ASMAtomicXchgU32((volatile uint32_t *)(void *)ppvR0, (uint32_t)pvR0);
+#elif R0_ARCH_BITS == 64
+    return (RTR0PTR)ASMAtomicXchgU64((volatile uint64_t *)(void *)ppvR0, (uint64_t)pvR0);
+#else
+# error "R0_ARCH_BITS is bogus"
+#endif
+}
+
+
+/**
+ * Atomically Exchange a ring-3 pointer value, ordered.
+ *
+ * @returns Current *ppv value
+ * @param   ppvR3  Pointer to the pointer variable to update.
+ * @param   pvR3   The pointer value to assign to *ppv.
+ */
+DECLINLINE(RTR3PTR) ASMAtomicXchgR3Ptr(RTR3PTR volatile *ppvR3, RTR3PTR pvR3)
+{
+#if R3_ARCH_BITS == 32
+    return (RTR3PTR)ASMAtomicXchgU32((volatile uint32_t *)(void *)ppvR3, (uint32_t)pvR3);
+#elif R3_ARCH_BITS == 64
+    return (RTR3PTR)ASMAtomicXchgU64((volatile uint64_t *)(void *)ppvR3, (uint64_t)pvR3);
+#else
+# error "R3_ARCH_BITS is bogus"
+#endif
+}
+
+
+/** @def ASMAtomicXchgHandle
+ * Atomically Exchange a typical IPRT handle value, ordered.
+ *
+ * @param   ph          Pointer to the value to update.
+ * @param   hNew        The new value to assigned to *pu.
+ * @param   phRes       Where to store the current *ph value.
+ *
+ * @remarks This doesn't currently work for all handles (like RTFILE).
+ */
+#if HC_ARCH_BITS == 32
+# define ASMAtomicXchgHandle(ph, hNew, phRes) \
+   do { \
+       AssertCompile(sizeof(*(ph))    == sizeof(uint32_t)); \
+       AssertCompile(sizeof(*(phRes)) == sizeof(uint32_t)); \
+       *(uint32_t *)(phRes) = ASMAtomicXchgU32((uint32_t volatile *)(ph), (const uint32_t)(hNew)); \
+   } while (0)
+#elif HC_ARCH_BITS == 64
+# define ASMAtomicXchgHandle(ph, hNew, phRes) \
+   do { \
+       AssertCompile(sizeof(*(ph))    == sizeof(uint64_t)); \
+       AssertCompile(sizeof(*(phRes)) == sizeof(uint64_t)); \
+       *(uint64_t *)(phRes) = ASMAtomicXchgU64((uint64_t volatile *)(ph), (const uint64_t)(hNew)); \
+   } while (0)
+#else
+# error HC_ARCH_BITS
+#endif
+
+
+/**
+ * Atomically Exchange a value which size might differ
+ * between platforms or compilers, ordered.
+ *
+ * @param   pu      Pointer to the variable to update.
+ * @param   uNew    The value to assign to *pu.
+ * @todo This is busted as its missing the result argument.
+ */
+#define ASMAtomicXchgSize(pu, uNew) \
+    do { \
+        switch (sizeof(*(pu))) { \
+            case 1: ASMAtomicXchgU8((volatile uint8_t *)(void *)(pu), (uint8_t)(uNew)); break; \
+            case 2: ASMAtomicXchgU16((volatile uint16_t *)(void *)(pu), (uint16_t)(uNew)); break; \
+            case 4: ASMAtomicXchgU32((volatile uint32_t *)(void *)(pu), (uint32_t)(uNew)); break; \
+            case 8: ASMAtomicXchgU64((volatile uint64_t *)(void *)(pu), (uint64_t)(uNew)); break; \
+            default: AssertMsgFailed(("ASMAtomicXchgSize: size %d is not supported\n", sizeof(*(pu)))); \
+        } \
+    } while (0)
+
+/**
+ * Atomically Exchange a value which size might differ
+ * between platforms or compilers, ordered.
+ *
+ * @param   pu      Pointer to the variable to update.
+ * @param   uNew    The value to assign to *pu.
+ * @param   puRes   Where to store the current *pu value.
+ */
+#define ASMAtomicXchgSizeCorrect(pu, uNew, puRes) \
+    do { \
+        switch (sizeof(*(pu))) { \
+            case 1: *(uint8_t  *)(puRes) = ASMAtomicXchgU8((volatile uint8_t *)(void *)(pu), (uint8_t)(uNew)); break; \
+            case 2: *(uint16_t *)(puRes) = ASMAtomicXchgU16((volatile uint16_t *)(void *)(pu), (uint16_t)(uNew)); break; \
+            case 4: *(uint32_t *)(puRes) = ASMAtomicXchgU32((volatile uint32_t *)(void *)(pu), (uint32_t)(uNew)); break; \
+            case 8: *(uint64_t *)(puRes) = ASMAtomicXchgU64((volatile uint64_t *)(void *)(pu), (uint64_t)(uNew)); break; \
+            default: AssertMsgFailed(("ASMAtomicXchgSize: size %d is not supported\n", sizeof(*(pu)))); \
+        } \
+    } while (0)
+
+
+
+/**
+ * Atomically Compare and Exchange an unsigned 8-bit value, ordered.
+ *
+ * @returns true if xchg was done.
+ * @returns false if xchg wasn't done.
+ *
+ * @param   pu8         Pointer to the value to update.
+ * @param   u8New       The new value to assigned to *pu8.
+ * @param   u8Old       The old value to *pu8 compare with.
+ */
+#if RT_INLINE_ASM_EXTERNAL || !RT_INLINE_ASM_GNU_STYLE
+DECLASM(bool) ASMAtomicCmpXchgU8(volatile uint8_t *pu8, const uint8_t u8New, const uint8_t u8Old);
+#else
+DECLINLINE(bool) ASMAtomicCmpXchgU8(volatile uint8_t *pu8, const uint8_t u8New, uint8_t u8Old)
+{
+    uint8_t u8Ret;
+    __asm__ __volatile__("lock; cmpxchgb %3, %0\n\t"
+                         "setz  %1\n\t"
+                         : "=m" (*pu8),
+                           "=qm" (u8Ret),
+                           "=a" (u8Old)
+                         : "q" (u8New),
+                           "2" (u8Old),
+                           "m" (*pu8));
+    return (bool)u8Ret;
+}
+#endif
+
+
+/**
+ * Atomically Compare and Exchange a signed 8-bit value, ordered.
+ *
+ * @returns true if xchg was done.
+ * @returns false if xchg wasn't done.
+ *
+ * @param   pi8         Pointer to the value to update.
+ * @param   i8New       The new value to assigned to *pi8.
+ * @param   i8Old       The old value to *pi8 compare with.
+ */
+DECLINLINE(bool) ASMAtomicCmpXchgS8(volatile int8_t *pi8, const int8_t i8New, const int8_t i8Old)
+{
+    return ASMAtomicCmpXchgU8((volatile uint8_t *)pi8, (const uint8_t)i8New, (const uint8_t)i8Old);
+}
+
+
+/**
+ * Atomically Compare and Exchange a bool value, ordered.
+ *
+ * @returns true if xchg was done.
+ * @returns false if xchg wasn't done.
+ *
+ * @param   pf          Pointer to the value to update.
+ * @param   fNew        The new value to assigned to *pf.
+ * @param   fOld        The old value to *pf compare with.
+ */
+DECLINLINE(bool) ASMAtomicCmpXchgBool(volatile bool *pf, const bool fNew, const bool fOld)
+{
+    return ASMAtomicCmpXchgU8((volatile uint8_t *)pf, (const uint8_t)fNew, (const uint8_t)fOld);
+}
+
+
+/**
+ * Atomically Compare and Exchange an unsigned 32-bit value, ordered.
+ *
+ * @returns true if xchg was done.
+ * @returns false if xchg wasn't done.
+ *
+ * @param   pu32        Pointer to the value to update.
+ * @param   u32New      The new value to assigned to *pu32.
+ * @param   u32Old      The old value to *pu32 compare with.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(bool) ASMAtomicCmpXchgU32(volatile uint32_t *pu32, const uint32_t u32New, const uint32_t u32Old);
+#else
+DECLINLINE(bool) ASMAtomicCmpXchgU32(volatile uint32_t *pu32, const uint32_t u32New, uint32_t u32Old)
+{
+# if RT_INLINE_ASM_GNU_STYLE
+    uint8_t u8Ret;
+    __asm__ __volatile__("lock; cmpxchgl %3, %0\n\t"
+                         "setz  %1\n\t"
+                         : "=m" (*pu32),
+                           "=qm" (u8Ret),
+                           "=a" (u32Old)
+                         : "r" (u32New),
+                           "2" (u32Old),
+                           "m" (*pu32));
+    return (bool)u8Ret;
+
+# elif RT_INLINE_ASM_USES_INTRIN
+    return (uint32_t)_InterlockedCompareExchange((long *)pu32, u32New, u32Old) == u32Old;
+
+# else
+    uint32_t u32Ret;
+    __asm
+    {
+#  ifdef RT_ARCH_AMD64
+        mov     rdx, [pu32]
+#  else
+        mov     edx, [pu32]
+#  endif
+        mov     eax, [u32Old]
+        mov     ecx, [u32New]
+#  ifdef RT_ARCH_AMD64
+        lock cmpxchg [rdx], ecx
+#  else
+        lock cmpxchg [edx], ecx
+#  endif
+        setz    al
+        movzx   eax, al
+        mov     [u32Ret], eax
+    }
+    return !!u32Ret;
+# endif
+}
+#endif
+
+
+/**
+ * Atomically Compare and Exchange a signed 32-bit value, ordered.
+ *
+ * @returns true if xchg was done.
+ * @returns false if xchg wasn't done.
+ *
+ * @param   pi32        Pointer to the value to update.
+ * @param   i32New      The new value to assigned to *pi32.
+ * @param   i32Old      The old value to *pi32 compare with.
+ */
+DECLINLINE(bool) ASMAtomicCmpXchgS32(volatile int32_t *pi32, const int32_t i32New, const int32_t i32Old)
+{
+    return ASMAtomicCmpXchgU32((volatile uint32_t *)pi32, (uint32_t)i32New, (uint32_t)i32Old);
+}
+
+
+/**
+ * Atomically Compare and exchange an unsigned 64-bit value, ordered.
+ *
+ * @returns true if xchg was done.
+ * @returns false if xchg wasn't done.
+ *
+ * @param   pu64    Pointer to the 64-bit variable to update.
+ * @param   u64New  The 64-bit value to assign to *pu64.
+ * @param   u64Old  The value to compare with.
+ */
+#if (RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN) \
+ || RT_INLINE_DONT_MIX_CMPXCHG8B_AND_PIC
+DECLASM(bool) ASMAtomicCmpXchgU64(volatile uint64_t *pu64, const uint64_t u64New, const uint64_t u64Old);
+#else
+DECLINLINE(bool) ASMAtomicCmpXchgU64(volatile uint64_t *pu64, uint64_t u64New, uint64_t u64Old)
+{
+# if RT_INLINE_ASM_USES_INTRIN
+   return (uint64_t)_InterlockedCompareExchange64((__int64 *)pu64, u64New, u64Old) == u64Old;
+
+# elif defined(RT_ARCH_AMD64)
+#  if RT_INLINE_ASM_GNU_STYLE
+    uint8_t u8Ret;
+    __asm__ __volatile__("lock; cmpxchgq %3, %0\n\t"
+                         "setz  %1\n\t"
+                         : "=m" (*pu64),
+                           "=qm" (u8Ret),
+                           "=a" (u64Old)
+                         : "r" (u64New),
+                           "2" (u64Old),
+                           "m" (*pu64));
+    return (bool)u8Ret;
+#  else
+    bool fRet;
+    __asm
+    {
+        mov     rdx, [pu32]
+        mov     rax, [u64Old]
+        mov     rcx, [u64New]
+        lock cmpxchg [rdx], rcx
+        setz    al
+        mov     [fRet], al
+    }
+    return fRet;
+#  endif
+# else /* !RT_ARCH_AMD64 */
+    uint32_t u32Ret;
+#  if RT_INLINE_ASM_GNU_STYLE
+#   if defined(PIC) || defined(__PIC__)
+    uint32_t u32EBX = (uint32_t)u64New;
+    uint32_t u32Spill;
+    __asm__ __volatile__("xchgl %%ebx, %4\n\t"
+                         "lock; cmpxchg8b (%6)\n\t"
+                         "setz  %%al\n\t"
+                         "movl  %4, %%ebx\n\t"
+                         "movzbl %%al, %%eax\n\t"
+                         : "=a" (u32Ret),
+                           "=d" (u32Spill),
+#    if (__GNUC__ * 100 + __GNUC_MINOR__) >= 403
+                           "+m" (*pu64)
+#    else
+                           "=m" (*pu64)
+#    endif
+                         : "A" (u64Old),
+                           "m" ( u32EBX ),
+                           "c" ( (uint32_t)(u64New >> 32) ),
+                           "S" (pu64));
+#   else /* !PIC */
+    uint32_t u32Spill;
+    __asm__ __volatile__("lock; cmpxchg8b %2\n\t"
+                         "setz  %%al\n\t"
+                         "movzbl %%al, %%eax\n\t"
+                         : "=a" (u32Ret),
+                           "=d" (u32Spill),
+                           "+m" (*pu64)
+                         : "A" (u64Old),
+                           "b" ( (uint32_t)u64New ),
+                           "c" ( (uint32_t)(u64New >> 32) ));
+#   endif
+    return (bool)u32Ret;
+#  else
+    __asm
+    {
+        mov     ebx, dword ptr [u64New]
+        mov     ecx, dword ptr [u64New + 4]
+        mov     edi, [pu64]
+        mov     eax, dword ptr [u64Old]
+        mov     edx, dword ptr [u64Old + 4]
+        lock cmpxchg8b [edi]
+        setz    al
+        movzx   eax, al
+        mov     dword ptr [u32Ret], eax
+    }
+    return !!u32Ret;
+#  endif
+# endif /* !RT_ARCH_AMD64 */
+}
+#endif
+
+
+/**
+ * Atomically Compare and exchange a signed 64-bit value, ordered.
+ *
+ * @returns true if xchg was done.
+ * @returns false if xchg wasn't done.
+ *
+ * @param   pi64    Pointer to the 64-bit variable to update.
+ * @param   i64     The 64-bit value to assign to *pu64.
+ * @param   i64Old  The value to compare with.
+ */
+DECLINLINE(bool) ASMAtomicCmpXchgS64(volatile int64_t *pi64, const int64_t i64, const int64_t i64Old)
+{
+    return ASMAtomicCmpXchgU64((volatile uint64_t *)pi64, (uint64_t)i64, (uint64_t)i64Old);
+}
+
+
+/**
+ * Atomically Compare and Exchange a pointer value, ordered.
+ *
+ * @returns true if xchg was done.
+ * @returns false if xchg wasn't done.
+ *
+ * @param   ppv         Pointer to the value to update.
+ * @param   pvNew       The new value to assigned to *ppv.
+ * @param   pvOld       The old value to *ppv compare with.
+ */
+DECLINLINE(bool) ASMAtomicCmpXchgPtrVoid(void * volatile *ppv, const void *pvNew, const void *pvOld)
+{
+#if ARCH_BITS == 32
+    return ASMAtomicCmpXchgU32((volatile uint32_t *)(void *)ppv, (uint32_t)pvNew, (uint32_t)pvOld);
+#elif ARCH_BITS == 64
+    return ASMAtomicCmpXchgU64((volatile uint64_t *)(void *)ppv, (uint64_t)pvNew, (uint64_t)pvOld);
+#else
+# error "ARCH_BITS is bogus"
+#endif
+}
+
+
+/**
+ * Atomically Compare and Exchange a pointer value, ordered.
+ *
+ * @returns true if xchg was done.
+ * @returns false if xchg wasn't done.
+ *
+ * @param   ppv         Pointer to the value to update.
+ * @param   pvNew       The new value to assigned to *ppv.
+ * @param   pvOld       The old value to *ppv compare with.
+ *
+ * @remarks This is relatively type safe on GCC platforms.
+ */
+#ifdef __GNUC__
+# define ASMAtomicCmpXchgPtr(ppv, pvNew, pvOld) \
+    __extension__ \
+    ({\
+        __typeof__(*(ppv)) volatile * const ppvTypeChecked   = (ppv); \
+        __typeof__(*(ppv))            const pvNewTypeChecked = (pvNew); \
+        __typeof__(*(ppv))            const pvOldTypeChecked = (pvOld); \
+        bool fMacroRet = ASMAtomicCmpXchgPtrVoid((void * volatile *)ppvTypeChecked, \
+                                                 (void *)pvNewTypeChecked, (void *)pvOldTypeChecked); \
+        fMacroRet; \
+     })
+#else
+# define ASMAtomicCmpXchgPtr(ppv, pvNew, pvOld) \
+    ASMAtomicCmpXchgPtrVoid((void * volatile *)(ppv), (void *)(pvNew), (void *)(pvOld))
+#endif
+
+
+/** @def ASMAtomicCmpXchgHandle
+ * Atomically Compare and Exchange a typical IPRT handle value, ordered.
+ *
+ * @param   ph          Pointer to the value to update.
+ * @param   hNew        The new value to assigned to *pu.
+ * @param   hOld        The old value to *pu compare with.
+ * @param   fRc         Where to store the result.
+ *
+ * @remarks This doesn't currently work for all handles (like RTFILE).
+ */
+#if HC_ARCH_BITS == 32
+# define ASMAtomicCmpXchgHandle(ph, hNew, hOld, fRc) \
+   do { \
+       AssertCompile(sizeof(*(ph)) == sizeof(uint32_t)); \
+       (fRc) = ASMAtomicCmpXchgU32((uint32_t volatile *)(ph), (const uint32_t)(hNew), (const uint32_t)(hOld)); \
+   } while (0)
+#elif HC_ARCH_BITS == 64
+# define ASMAtomicCmpXchgHandle(ph, hNew, hOld, fRc) \
+   do { \
+       AssertCompile(sizeof(*(ph)) == sizeof(uint64_t)); \
+       (fRc) = ASMAtomicCmpXchgU64((uint64_t volatile *)(ph), (const uint64_t)(hNew), (const uint64_t)(hOld)); \
+   } while (0)
+#else
+# error HC_ARCH_BITS
+#endif
+
+
+/** @def ASMAtomicCmpXchgSize
+ * Atomically Compare and Exchange a value which size might differ
+ * between platforms or compilers, ordered.
+ *
+ * @param   pu          Pointer to the value to update.
+ * @param   uNew        The new value to assigned to *pu.
+ * @param   uOld        The old value to *pu compare with.
+ * @param   fRc         Where to store the result.
+ */
+#define ASMAtomicCmpXchgSize(pu, uNew, uOld, fRc) \
+    do { \
+        switch (sizeof(*(pu))) { \
+            case 4: (fRc) = ASMAtomicCmpXchgU32((volatile uint32_t *)(void *)(pu), (uint32_t)(uNew), (uint32_t)(uOld)); \
+                break; \
+            case 8: (fRc) = ASMAtomicCmpXchgU64((volatile uint64_t *)(void *)(pu), (uint64_t)(uNew), (uint64_t)(uOld)); \
+                break; \
+            default: AssertMsgFailed(("ASMAtomicCmpXchgSize: size %d is not supported\n", sizeof(*(pu)))); \
+                (fRc) = false; \
+                break; \
+        } \
+    } while (0)
+
+
+/**
+ * Atomically Compare and Exchange an unsigned 32-bit value, additionally
+ * passes back old value, ordered.
+ *
+ * @returns true if xchg was done.
+ * @returns false if xchg wasn't done.
+ *
+ * @param   pu32        Pointer to the value to update.
+ * @param   u32New      The new value to assigned to *pu32.
+ * @param   u32Old      The old value to *pu32 compare with.
+ * @param   pu32Old     Pointer store the old value at.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(bool) ASMAtomicCmpXchgExU32(volatile uint32_t *pu32, const uint32_t u32New, const uint32_t u32Old, uint32_t *pu32Old);
+#else
+DECLINLINE(bool) ASMAtomicCmpXchgExU32(volatile uint32_t *pu32, const uint32_t u32New, const uint32_t u32Old, uint32_t *pu32Old)
+{
+# if RT_INLINE_ASM_GNU_STYLE
+    uint8_t u8Ret;
+    __asm__ __volatile__("lock; cmpxchgl %3, %0\n\t"
+                         "setz  %1\n\t"
+                         : "=m" (*pu32),
+                           "=qm" (u8Ret),
+                           "=a" (*pu32Old)
+                         : "r" (u32New),
+                           "a" (u32Old),
+                           "m" (*pu32));
+    return (bool)u8Ret;
+
+# elif RT_INLINE_ASM_USES_INTRIN
+    return (*pu32Old =_InterlockedCompareExchange((long *)pu32, u32New, u32Old)) == u32Old;
+
+# else
+    uint32_t u32Ret;
+    __asm
+    {
+#  ifdef RT_ARCH_AMD64
+        mov     rdx, [pu32]
+#  else
+        mov     edx, [pu32]
+#  endif
+        mov     eax, [u32Old]
+        mov     ecx, [u32New]
+#  ifdef RT_ARCH_AMD64
+        lock cmpxchg [rdx], ecx
+        mov     rdx, [pu32Old]
+        mov     [rdx], eax
+#  else
+        lock cmpxchg [edx], ecx
+        mov     edx, [pu32Old]
+        mov     [edx], eax
+#  endif
+        setz    al
+        movzx   eax, al
+        mov     [u32Ret], eax
+    }
+    return !!u32Ret;
+# endif
+}
+#endif
+
+
+/**
+ * Atomically Compare and Exchange a signed 32-bit value, additionally
+ * passes back old value, ordered.
+ *
+ * @returns true if xchg was done.
+ * @returns false if xchg wasn't done.
+ *
+ * @param   pi32        Pointer to the value to update.
+ * @param   i32New      The new value to assigned to *pi32.
+ * @param   i32Old      The old value to *pi32 compare with.
+ * @param   pi32Old     Pointer store the old value at.
+ */
+DECLINLINE(bool) ASMAtomicCmpXchgExS32(volatile int32_t *pi32, const int32_t i32New, const int32_t i32Old, int32_t *pi32Old)
+{
+    return ASMAtomicCmpXchgExU32((volatile uint32_t *)pi32, (uint32_t)i32New, (uint32_t)i32Old, (uint32_t *)pi32Old);
+}
+
+
+/**
+ * Atomically Compare and exchange an unsigned 64-bit value, additionally
+ * passing back old value, ordered.
+ *
+ * @returns true if xchg was done.
+ * @returns false if xchg wasn't done.
+ *
+ * @param   pu64    Pointer to the 64-bit variable to update.
+ * @param   u64New  The 64-bit value to assign to *pu64.
+ * @param   u64Old  The value to compare with.
+ * @param   pu64Old     Pointer store the old value at.
+ */
+#if (RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN) \
+ || RT_INLINE_DONT_MIX_CMPXCHG8B_AND_PIC
+DECLASM(bool) ASMAtomicCmpXchgExU64(volatile uint64_t *pu64, const uint64_t u64New, const uint64_t u64Old, uint64_t *pu64Old);
+#else
+DECLINLINE(bool) ASMAtomicCmpXchgExU64(volatile uint64_t *pu64, const uint64_t u64New, const uint64_t u64Old, uint64_t *pu64Old)
+{
+# if RT_INLINE_ASM_USES_INTRIN
+   return (*pu64Old =_InterlockedCompareExchange64((__int64 *)pu64, u64New, u64Old)) == u64Old;
+
+# elif defined(RT_ARCH_AMD64)
+#  if RT_INLINE_ASM_GNU_STYLE
+    uint8_t u8Ret;
+    __asm__ __volatile__("lock; cmpxchgq %3, %0\n\t"
+                         "setz  %1\n\t"
+                         : "=m" (*pu64),
+                           "=qm" (u8Ret),
+                           "=a" (*pu64Old)
+                         : "r" (u64New),
+                           "a" (u64Old),
+                           "m" (*pu64));
+    return (bool)u8Ret;
+#  else
+    bool fRet;
+    __asm
+    {
+        mov     rdx, [pu32]
+        mov     rax, [u64Old]
+        mov     rcx, [u64New]
+        lock cmpxchg [rdx], rcx
+        mov     rdx, [pu64Old]
+        mov     [rdx], rax
+        setz    al
+        mov     [fRet], al
+    }
+    return fRet;
+#  endif
+# else /* !RT_ARCH_AMD64 */
+#  if RT_INLINE_ASM_GNU_STYLE
+    uint64_t u64Ret;
+#   if defined(PIC) || defined(__PIC__)
+    /* NB: this code uses a memory clobber description, because the clean
+     * solution with an output value for *pu64 makes gcc run out of registers.
+     * This will cause suboptimal code, and anyone with a better solution is
+     * welcome to improve this. */
+    __asm__ __volatile__("xchgl %%ebx, %1\n\t"
+                         "lock; cmpxchg8b %3\n\t"
+                         "xchgl %%ebx, %1\n\t"
+                         : "=A" (u64Ret)
+                         : "DS" ((uint32_t)u64New),
+                           "c" ((uint32_t)(u64New >> 32)),
+                           "m" (*pu64),
+                           "0" (u64Old)
+                         : "memory" );
+#   else /* !PIC */
+    __asm__ __volatile__("lock; cmpxchg8b %4\n\t"
+                         : "=A" (u64Ret),
+                           "=m" (*pu64)
+                         : "b" ((uint32_t)u64New),
+                           "c" ((uint32_t)(u64New >> 32)),
+                           "m" (*pu64),
+                           "0" (u64Old));
+#   endif
+    *pu64Old = u64Ret;
+    return u64Ret == u64Old;
+#  else
+    uint32_t u32Ret;
+    __asm
+    {
+        mov     ebx, dword ptr [u64New]
+        mov     ecx, dword ptr [u64New + 4]
+        mov     edi, [pu64]
+        mov     eax, dword ptr [u64Old]
+        mov     edx, dword ptr [u64Old + 4]
+        lock cmpxchg8b [edi]
+        mov     ebx, [pu64Old]
+        mov     [ebx], eax
+        setz    al
+        movzx   eax, al
+        add     ebx, 4
+        mov     [ebx], edx
+        mov     dword ptr [u32Ret], eax
+    }
+    return !!u32Ret;
+#  endif
+# endif /* !RT_ARCH_AMD64 */
+}
+#endif
+
+
+/**
+ * Atomically Compare and exchange a signed 64-bit value, additionally
+ * passing back old value, ordered.
+ *
+ * @returns true if xchg was done.
+ * @returns false if xchg wasn't done.
+ *
+ * @param   pi64    Pointer to the 64-bit variable to update.
+ * @param   i64     The 64-bit value to assign to *pu64.
+ * @param   i64Old  The value to compare with.
+ * @param   pi64Old Pointer store the old value at.
+ */
+DECLINLINE(bool) ASMAtomicCmpXchgExS64(volatile int64_t *pi64, const int64_t i64, const int64_t i64Old, int64_t *pi64Old)
+{
+    return ASMAtomicCmpXchgExU64((volatile uint64_t *)pi64, (uint64_t)i64, (uint64_t)i64Old, (uint64_t *)pi64Old);
+}
+
+/** @def ASMAtomicCmpXchgExHandle
+ * Atomically Compare and Exchange a typical IPRT handle value, ordered.
+ *
+ * @param   ph          Pointer to the value to update.
+ * @param   hNew        The new value to assigned to *pu.
+ * @param   hOld        The old value to *pu compare with.
+ * @param   fRc         Where to store the result.
+ * @param   phOldVal    Pointer to where to store the old value.
+ *
+ * @remarks This doesn't currently work for all handles (like RTFILE).
+ */
+#if HC_ARCH_BITS == 32
+# define ASMAtomicCmpXchgExHandle(ph, hNew, hOld, fRc, phOldVal) \
+    do { \
+        AssertCompile(sizeof(*ph)       == sizeof(uint32_t)); \
+        AssertCompile(sizeof(*phOldVal) == sizeof(uint32_t)); \
+        (fRc) = ASMAtomicCmpXchgExU32((volatile uint32_t *)(pu), (uint32_t)(uNew), (uint32_t)(uOld), (uint32_t *)(puOldVal)); \
+    } while (0)
+#elif HC_ARCH_BITS == 64
+# define ASMAtomicCmpXchgExHandle(ph, hNew, hOld, fRc, phOldVal) \
+    do { \
+        AssertCompile(sizeof(*(ph))       == sizeof(uint64_t)); \
+        AssertCompile(sizeof(*(phOldVal)) == sizeof(uint64_t)); \
+        (fRc) = ASMAtomicCmpXchgExU64((volatile uint64_t *)(pu), (uint64_t)(uNew), (uint64_t)(uOld), (uint64_t *)(puOldVal)); \
+    } while (0)
+#else
+# error HC_ARCH_BITS
+#endif
+
+
+/** @def ASMAtomicCmpXchgExSize
+ * Atomically Compare and Exchange a value which size might differ
+ * between platforms or compilers. Additionally passes back old value.
+ *
+ * @param   pu          Pointer to the value to update.
+ * @param   uNew        The new value to assigned to *pu.
+ * @param   uOld        The old value to *pu compare with.
+ * @param   fRc         Where to store the result.
+ * @param   puOldVal    Pointer to where to store the old value.
+ */
+#define ASMAtomicCmpXchgExSize(pu, uNew, uOld, fRc, puOldVal) \
+    do { \
+        switch (sizeof(*(pu))) { \
+            case 4: (fRc) = ASMAtomicCmpXchgExU32((volatile uint32_t *)(void *)(pu), (uint32_t)(uNew), (uint32_t)(uOld), (uint32_t *)(uOldVal)); \
+                break; \
+            case 8: (fRc) = ASMAtomicCmpXchgExU64((volatile uint64_t *)(void *)(pu), (uint64_t)(uNew), (uint64_t)(uOld), (uint64_t *)(uOldVal)); \
+                break; \
+            default: AssertMsgFailed(("ASMAtomicCmpXchgSize: size %d is not supported\n", sizeof(*(pu)))); \
+                (fRc) = false; \
+                (uOldVal) = 0; \
+                break; \
+        } \
+    } while (0)
+
+
+/**
+ * Atomically Compare and Exchange a pointer value, additionally
+ * passing back old value, ordered.
+ *
+ * @returns true if xchg was done.
+ * @returns false if xchg wasn't done.
+ *
+ * @param   ppv         Pointer to the value to update.
+ * @param   pvNew       The new value to assigned to *ppv.
+ * @param   pvOld       The old value to *ppv compare with.
+ * @param   ppvOld      Pointer store the old value at.
+ */
+DECLINLINE(bool) ASMAtomicCmpXchgExPtrVoid(void * volatile *ppv, const void *pvNew, const void *pvOld, void **ppvOld)
+{
+#if ARCH_BITS == 32
+    return ASMAtomicCmpXchgExU32((volatile uint32_t *)(void *)ppv, (uint32_t)pvNew, (uint32_t)pvOld, (uint32_t *)ppvOld);
+#elif ARCH_BITS == 64
+    return ASMAtomicCmpXchgExU64((volatile uint64_t *)(void *)ppv, (uint64_t)pvNew, (uint64_t)pvOld, (uint64_t *)ppvOld);
+#else
+# error "ARCH_BITS is bogus"
+#endif
+}
+
+
+/**
+ * Atomically Compare and Exchange a pointer value, additionally
+ * passing back old value, ordered.
+ *
+ * @returns true if xchg was done.
+ * @returns false if xchg wasn't done.
+ *
+ * @param   ppv         Pointer to the value to update.
+ * @param   pvNew       The new value to assigned to *ppv.
+ * @param   pvOld       The old value to *ppv compare with.
+ * @param   ppvOld      Pointer store the old value at.
+ *
+ * @remarks This is relatively type safe on GCC platforms.
+ */
+#ifdef __GNUC__
+# define ASMAtomicCmpXchgExPtr(ppv, pvNew, pvOld, ppvOld) \
+    __extension__ \
+    ({\
+        __typeof__(*(ppv)) volatile * const ppvTypeChecked    = (ppv); \
+        __typeof__(*(ppv))            const pvNewTypeChecked  = (pvNew); \
+        __typeof__(*(ppv))            const pvOldTypeChecked  = (pvOld); \
+        __typeof__(*(ppv)) *          const ppvOldTypeChecked = (ppvOld); \
+        bool fMacroRet = ASMAtomicCmpXchgExPtrVoid((void * volatile *)ppvTypeChecked, \
+                                                   (void *)pvNewTypeChecked, (void *)pvOldTypeChecked, \
+                                                   (void **)ppvOldTypeChecked); \
+        fMacroRet; \
+     })
+#else
+# define ASMAtomicCmpXchgExPtr(ppv, pvNew, pvOld, ppvOld) \
+    ASMAtomicCmpXchgExPtrVoid((void * volatile *)(ppv), (void *)(pvNew), (void *)(pvOld), (void **)(ppvOld))
+#endif
+
+
+/**
+ * Serialize Instruction.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(void) ASMSerializeInstruction(void);
+#else
+DECLINLINE(void) ASMSerializeInstruction(void)
+{
+# if RT_INLINE_ASM_GNU_STYLE
+    RTCCUINTREG xAX = 0;
+#  ifdef RT_ARCH_AMD64
+    __asm__ ("cpuid"
+             : "=a" (xAX)
+             : "0" (xAX)
+             : "rbx", "rcx", "rdx");
+#  elif (defined(PIC) || defined(__PIC__)) && defined(__i386__)
+    __asm__ ("push  %%ebx\n\t"
+             "cpuid\n\t"
+             "pop   %%ebx\n\t"
+             : "=a" (xAX)
+             : "0" (xAX)
+             : "ecx", "edx");
+#  else
+    __asm__ ("cpuid"
+             : "=a" (xAX)
+             : "0" (xAX)
+             : "ebx", "ecx", "edx");
+#  endif
+
+# elif RT_INLINE_ASM_USES_INTRIN
+    int aInfo[4];
+    __cpuid(aInfo, 0);
+
+# else
+    __asm
+    {
+        push    ebx
+        xor     eax, eax
+        cpuid
+        pop     ebx
+    }
+# endif
+}
+#endif
+
+
+/**
+ * Memory fence, waits for any pending writes and reads to complete.
+ */
+DECLINLINE(void) ASMMemoryFence(void)
+{
+    /** @todo use mfence? check if all cpus we care for support it. */
+    uint32_t volatile u32;
+    ASMAtomicXchgU32(&u32, 0);
+}
+
+
+/**
+ * Write fence, waits for any pending writes to complete.
+ */
+DECLINLINE(void) ASMWriteFence(void)
+{
+    /** @todo use sfence? check if all cpus we care for support it. */
+    ASMMemoryFence();
+}
+
+
+/**
+ * Read fence, waits for any pending reads to complete.
+ */
+DECLINLINE(void) ASMReadFence(void)
+{
+    /** @todo use lfence? check if all cpus we care for support it. */
+    ASMMemoryFence();
+}
+
+
+/**
+ * Atomically reads an unsigned 8-bit value, ordered.
+ *
+ * @returns Current *pu8 value
+ * @param   pu8    Pointer to the 8-bit variable to read.
+ */
+DECLINLINE(uint8_t) ASMAtomicReadU8(volatile uint8_t *pu8)
+{
+    ASMMemoryFence();
+    return *pu8;    /* byte reads are atomic on x86 */
+}
+
+
+/**
+ * Atomically reads an unsigned 8-bit value, unordered.
+ *
+ * @returns Current *pu8 value
+ * @param   pu8    Pointer to the 8-bit variable to read.
+ */
+DECLINLINE(uint8_t) ASMAtomicUoReadU8(volatile uint8_t *pu8)
+{
+    return *pu8;    /* byte reads are atomic on x86 */
+}
+
+
+/**
+ * Atomically reads a signed 8-bit value, ordered.
+ *
+ * @returns Current *pi8 value
+ * @param   pi8    Pointer to the 8-bit variable to read.
+ */
+DECLINLINE(int8_t) ASMAtomicReadS8(volatile int8_t *pi8)
+{
+    ASMMemoryFence();
+    return *pi8;    /* byte reads are atomic on x86 */
+}
+
+
+/**
+ * Atomically reads a signed 8-bit value, unordered.
+ *
+ * @returns Current *pi8 value
+ * @param   pi8    Pointer to the 8-bit variable to read.
+ */
+DECLINLINE(int8_t) ASMAtomicUoReadS8(volatile int8_t *pi8)
+{
+    return *pi8;    /* byte reads are atomic on x86 */
+}
+
+
+/**
+ * Atomically reads an unsigned 16-bit value, ordered.
+ *
+ * @returns Current *pu16 value
+ * @param   pu16    Pointer to the 16-bit variable to read.
+ */
+DECLINLINE(uint16_t) ASMAtomicReadU16(volatile uint16_t *pu16)
+{
+    ASMMemoryFence();
+    Assert(!((uintptr_t)pu16 & 1));
+    return *pu16;
+}
+
+
+/**
+ * Atomically reads an unsigned 16-bit value, unordered.
+ *
+ * @returns Current *pu16 value
+ * @param   pu16    Pointer to the 16-bit variable to read.
+ */
+DECLINLINE(uint16_t) ASMAtomicUoReadU16(volatile uint16_t *pu16)
+{
+    Assert(!((uintptr_t)pu16 & 1));
+    return *pu16;
+}
+
+
+/**
+ * Atomically reads a signed 16-bit value, ordered.
+ *
+ * @returns Current *pi16 value
+ * @param   pi16    Pointer to the 16-bit variable to read.
+ */
+DECLINLINE(int16_t) ASMAtomicReadS16(volatile int16_t *pi16)
+{
+    ASMMemoryFence();
+    Assert(!((uintptr_t)pi16 & 1));
+    return *pi16;
+}
+
+
+/**
+ * Atomically reads a signed 16-bit value, unordered.
+ *
+ * @returns Current *pi16 value
+ * @param   pi16    Pointer to the 16-bit variable to read.
+ */
+DECLINLINE(int16_t) ASMAtomicUoReadS16(volatile int16_t *pi16)
+{
+    Assert(!((uintptr_t)pi16 & 1));
+    return *pi16;
+}
+
+
+/**
+ * Atomically reads an unsigned 32-bit value, ordered.
+ *
+ * @returns Current *pu32 value
+ * @param   pu32    Pointer to the 32-bit variable to read.
+ */
+DECLINLINE(uint32_t) ASMAtomicReadU32(volatile uint32_t *pu32)
+{
+    ASMMemoryFence();
+    Assert(!((uintptr_t)pu32 & 3));
+    return *pu32;
+}
+
+
+/**
+ * Atomically reads an unsigned 32-bit value, unordered.
+ *
+ * @returns Current *pu32 value
+ * @param   pu32    Pointer to the 32-bit variable to read.
+ */
+DECLINLINE(uint32_t) ASMAtomicUoReadU32(volatile uint32_t *pu32)
+{
+    Assert(!((uintptr_t)pu32 & 3));
+    return *pu32;
+}
+
+
+/**
+ * Atomically reads a signed 32-bit value, ordered.
+ *
+ * @returns Current *pi32 value
+ * @param   pi32    Pointer to the 32-bit variable to read.
+ */
+DECLINLINE(int32_t) ASMAtomicReadS32(volatile int32_t *pi32)
+{
+    ASMMemoryFence();
+    Assert(!((uintptr_t)pi32 & 3));
+    return *pi32;
+}
+
+
+/**
+ * Atomically reads a signed 32-bit value, unordered.
+ *
+ * @returns Current *pi32 value
+ * @param   pi32    Pointer to the 32-bit variable to read.
+ */
+DECLINLINE(int32_t) ASMAtomicUoReadS32(volatile int32_t *pi32)
+{
+    Assert(!((uintptr_t)pi32 & 3));
+    return *pi32;
+}
+
+
+/**
+ * Atomically reads an unsigned 64-bit value, ordered.
+ *
+ * @returns Current *pu64 value
+ * @param   pu64    Pointer to the 64-bit variable to read.
+ *                  The memory pointed to must be writable.
+ * @remark  This will fault if the memory is read-only!
+ */
+#if (RT_INLINE_ASM_EXTERNAL && !defined(RT_ARCH_AMD64)) \
+ || RT_INLINE_DONT_MIX_CMPXCHG8B_AND_PIC
+DECLASM(uint64_t) ASMAtomicReadU64(volatile uint64_t *pu64);
+#else
+DECLINLINE(uint64_t) ASMAtomicReadU64(volatile uint64_t *pu64)
+{
+    uint64_t u64;
+# ifdef RT_ARCH_AMD64
+    Assert(!((uintptr_t)pu64 & 7));
+/*#  if RT_INLINE_ASM_GNU_STYLE
+    __asm__ __volatile__(  "mfence\n\t"
+                           "movq %1, %0\n\t"
+                         : "=r" (u64)
+                         : "m" (*pu64));
+#  else
+    __asm
+    {
+        mfence
+        mov     rdx, [pu64]
+        mov     rax, [rdx]
+        mov     [u64], rax
+    }
+#  endif*/
+    ASMMemoryFence();
+    u64 = *pu64;
+# else /* !RT_ARCH_AMD64 */
+#  if RT_INLINE_ASM_GNU_STYLE
+#   if defined(PIC) || defined(__PIC__)
+    uint32_t u32EBX = 0;
+    Assert(!((uintptr_t)pu64 & 7));
+    __asm__ __volatile__("xchgl %%ebx, %3\n\t"
+                         "lock; cmpxchg8b (%5)\n\t"
+                         "movl %3, %%ebx\n\t"
+                         : "=A" (u64),
+#    if (__GNUC__ * 100 + __GNUC_MINOR__) >= 403
+                           "+m" (*pu64)
+#    else
+                           "=m" (*pu64)
+#    endif
+                         : "0" (0ULL),
+                           "m" (u32EBX),
+                           "c" (0),
+                           "S" (pu64));
+#   else /* !PIC */
+    __asm__ __volatile__("lock; cmpxchg8b %1\n\t"
+                         : "=A" (u64),
+                           "+m" (*pu64)
+                         : "0" (0ULL),
+                           "b" (0),
+                           "c" (0));
+#   endif
+#  else
+    Assert(!((uintptr_t)pu64 & 7));
+    __asm
+    {
+        xor     eax, eax
+        xor     edx, edx
+        mov     edi, pu64
+        xor     ecx, ecx
+        xor     ebx, ebx
+        lock cmpxchg8b [edi]
+        mov     dword ptr [u64], eax
+        mov     dword ptr [u64 + 4], edx
+    }
+#  endif
+# endif /* !RT_ARCH_AMD64 */
+    return u64;
+}
+#endif
+
+
+/**
+ * Atomically reads an unsigned 64-bit value, unordered.
+ *
+ * @returns Current *pu64 value
+ * @param   pu64    Pointer to the 64-bit variable to read.
+ *                  The memory pointed to must be writable.
+ * @remark  This will fault if the memory is read-only!
+ */
+#if !defined(RT_ARCH_AMD64) \
+  && (   (RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN) \
+      || RT_INLINE_DONT_MIX_CMPXCHG8B_AND_PIC)
+DECLASM(uint64_t) ASMAtomicUoReadU64(volatile uint64_t *pu64);
+#else
+DECLINLINE(uint64_t) ASMAtomicUoReadU64(volatile uint64_t *pu64)
+{
+    uint64_t u64;
+# ifdef RT_ARCH_AMD64
+    Assert(!((uintptr_t)pu64 & 7));
+/*#  if RT_INLINE_ASM_GNU_STYLE
+    Assert(!((uintptr_t)pu64 & 7));
+    __asm__ __volatile__("movq %1, %0\n\t"
+                         : "=r" (u64)
+                         : "m" (*pu64));
+#  else
+    __asm
+    {
+        mov     rdx, [pu64]
+        mov     rax, [rdx]
+        mov     [u64], rax
+    }
+#  endif */
+    u64 = *pu64;
+# else /* !RT_ARCH_AMD64 */
+#  if RT_INLINE_ASM_GNU_STYLE
+#   if defined(PIC) || defined(__PIC__)
+    uint32_t u32EBX = 0;
+    uint32_t u32Spill;
+    Assert(!((uintptr_t)pu64 & 7));
+    __asm__ __volatile__("xor   %%eax,%%eax\n\t"
+                         "xor   %%ecx,%%ecx\n\t"
+                         "xor   %%edx,%%edx\n\t"
+                         "xchgl %%ebx, %3\n\t"
+                         "lock; cmpxchg8b (%4)\n\t"
+                         "movl %3, %%ebx\n\t"
+                         : "=A" (u64),
+#    if (__GNUC__ * 100 + __GNUC_MINOR__) >= 403
+                           "+m" (*pu64),
+#    else
+                           "=m" (*pu64),
+#    endif
+                           "=c" (u32Spill)
+                         : "m" (u32EBX),
+                           "S" (pu64));
+#   else /* !PIC */
+    __asm__ __volatile__("lock; cmpxchg8b %1\n\t"
+                         : "=A" (u64),
+                           "+m" (*pu64)
+                         : "0" (0ULL),
+                           "b" (0),
+                           "c" (0));
+#   endif
+#  else
+    Assert(!((uintptr_t)pu64 & 7));
+    __asm
+    {
+        xor     eax, eax
+        xor     edx, edx
+        mov     edi, pu64
+        xor     ecx, ecx
+        xor     ebx, ebx
+        lock cmpxchg8b [edi]
+        mov     dword ptr [u64], eax
+        mov     dword ptr [u64 + 4], edx
+    }
+#  endif
+# endif /* !RT_ARCH_AMD64 */
+    return u64;
+}
+#endif
+
+
+/**
+ * Atomically reads a signed 64-bit value, ordered.
+ *
+ * @returns Current *pi64 value
+ * @param   pi64    Pointer to the 64-bit variable to read.
+ *                  The memory pointed to must be writable.
+ * @remark  This will fault if the memory is read-only!
+ */
+DECLINLINE(int64_t) ASMAtomicReadS64(volatile int64_t *pi64)
+{
+    return (int64_t)ASMAtomicReadU64((volatile uint64_t *)pi64);
+}
+
+
+/**
+ * Atomically reads a signed 64-bit value, unordered.
+ *
+ * @returns Current *pi64 value
+ * @param   pi64    Pointer to the 64-bit variable to read.
+ *                  The memory pointed to must be writable.
+ * @remark  This will fault if the memory is read-only!
+ */
+DECLINLINE(int64_t) ASMAtomicUoReadS64(volatile int64_t *pi64)
+{
+    return (int64_t)ASMAtomicUoReadU64((volatile uint64_t *)pi64);
+}
+
+
+/**
+ * Atomically reads a size_t value, ordered.
+ *
+ * @returns Current *pcb value
+ * @param   pcb     Pointer to the size_t variable to read.
+ */
+DECLINLINE(size_t) ASMAtomicReadZ(size_t volatile *pcb)
+{
+#if ARCH_BITS == 64
+    return ASMAtomicReadU64((uint64_t volatile *)pcb);
+#elif ARCH_BITS == 32
+    return ASMAtomicReadU32((uint32_t volatile *)pcb);
+#else
+# error "Unsupported ARCH_BITS value"
+#endif
+}
+
+
+/**
+ * Atomically reads a size_t value, unordered.
+ *
+ * @returns Current *pcb value
+ * @param   pcb     Pointer to the size_t variable to read.
+ */
+DECLINLINE(size_t) ASMAtomicUoReadZ(size_t volatile *pcb)
+{
+#if ARCH_BITS == 64
+    return ASMAtomicUoReadU64((uint64_t volatile *)pcb);
+#elif ARCH_BITS == 32
+    return ASMAtomicUoReadU32((uint32_t volatile *)pcb);
+#else
+# error "Unsupported ARCH_BITS value"
+#endif
+}
+
+
+/**
+ * Atomically reads a pointer value, ordered.
+ *
+ * @returns Current *pv value
+ * @param   ppv     Pointer to the pointer variable to read.
+ *
+ * @remarks Please use ASMAtomicReadPtrT, it provides better type safety and
+ *          requires less typing (no casts).
+ */
+DECLINLINE(void *) ASMAtomicReadPtr(void * volatile *ppv)
+{
+#if ARCH_BITS == 32
+    return (void *)ASMAtomicReadU32((volatile uint32_t *)(void *)ppv);
+#elif ARCH_BITS == 64
+    return (void *)ASMAtomicReadU64((volatile uint64_t *)(void *)ppv);
+#else
+# error "ARCH_BITS is bogus"
+#endif
+}
+
+/**
+ * Convenience macro for avoiding the annoying casting with ASMAtomicReadPtr.
+ *
+ * @returns Current *pv value
+ * @param   ppv     Pointer to the pointer variable to read.
+ * @param   Type    The type of *ppv, sans volatile.
+ */
+#ifdef __GNUC__
+# define ASMAtomicReadPtrT(ppv, Type) \
+    __extension__ \
+    ({\
+        __typeof__(*(ppv)) volatile *ppvTypeChecked = (ppv); \
+        Type pvTypeChecked = (__typeof__(*(ppv))) ASMAtomicReadPtr((void * volatile *)ppvTypeChecked); \
+        pvTypeChecked; \
+     })
+#else
+# define ASMAtomicReadPtrT(ppv, Type) \
+    (Type)ASMAtomicReadPtr((void * volatile *)(ppv))
+#endif
+
+
+/**
+ * Atomically reads a pointer value, unordered.
+ *
+ * @returns Current *pv value
+ * @param   ppv     Pointer to the pointer variable to read.
+ *
+ * @remarks Please use ASMAtomicUoReadPtrT, it provides better type safety and
+ *          requires less typing (no casts).
+ */
+DECLINLINE(void *) ASMAtomicUoReadPtr(void * volatile *ppv)
+{
+#if ARCH_BITS == 32
+    return (void *)ASMAtomicUoReadU32((volatile uint32_t *)(void *)ppv);
+#elif ARCH_BITS == 64
+    return (void *)ASMAtomicUoReadU64((volatile uint64_t *)(void *)ppv);
+#else
+# error "ARCH_BITS is bogus"
+#endif
+}
+
+
+/**
+ * Convenience macro for avoiding the annoying casting with ASMAtomicUoReadPtr.
+ *
+ * @returns Current *pv value
+ * @param   ppv     Pointer to the pointer variable to read.
+ * @param   Type    The type of *ppv, sans volatile.
+ */
+#ifdef __GNUC__
+# define ASMAtomicUoReadPtrT(ppv, Type) \
+    __extension__ \
+    ({\
+        __typeof__(*(ppv)) volatile * const ppvTypeChecked = (ppv); \
+        Type pvTypeChecked = (__typeof__(*(ppv))) ASMAtomicUoReadPtr((void * volatile *)ppvTypeChecked); \
+        pvTypeChecked; \
+     })
+#else
+# define ASMAtomicUoReadPtrT(ppv, Type) \
+    (Type)ASMAtomicUoReadPtr((void * volatile *)(ppv))
+#endif
+
+
+/**
+ * Atomically reads a boolean value, ordered.
+ *
+ * @returns Current *pf value
+ * @param   pf      Pointer to the boolean variable to read.
+ */
+DECLINLINE(bool) ASMAtomicReadBool(volatile bool *pf)
+{
+    ASMMemoryFence();
+    return *pf;     /* byte reads are atomic on x86 */
+}
+
+
+/**
+ * Atomically reads a boolean value, unordered.
+ *
+ * @returns Current *pf value
+ * @param   pf      Pointer to the boolean variable to read.
+ */
+DECLINLINE(bool) ASMAtomicUoReadBool(volatile bool *pf)
+{
+    return *pf;     /* byte reads are atomic on x86 */
+}
+
+
+/**
+ * Atomically read a typical IPRT handle value, ordered.
+ *
+ * @param   ph      Pointer to the handle variable to read.
+ * @param   phRes   Where to store the result.
+ *
+ * @remarks This doesn't currently work for all handles (like RTFILE).
+ */
+#if HC_ARCH_BITS == 32
+# define ASMAtomicReadHandle(ph, phRes) \
+    do { \
+        AssertCompile(sizeof(*(ph))    == sizeof(uint32_t)); \
+        AssertCompile(sizeof(*(phRes)) == sizeof(uint32_t)); \
+        *(uint32_t *)(phRes) = ASMAtomicReadU32((uint32_t volatile *)(ph)); \
+    } while (0)
+#elif HC_ARCH_BITS == 64
+# define ASMAtomicReadHandle(ph, phRes) \
+    do { \
+        AssertCompile(sizeof(*(ph))    == sizeof(uint64_t)); \
+        AssertCompile(sizeof(*(phRes)) == sizeof(uint64_t)); \
+        *(uint64_t *)(phRes) = ASMAtomicReadU64((uint64_t volatile *)(ph)); \
+    } while (0)
+#else
+# error HC_ARCH_BITS
+#endif
+
+
+/**
+ * Atomically read a typical IPRT handle value, unordered.
+ *
+ * @param   ph      Pointer to the handle variable to read.
+ * @param   phRes   Where to store the result.
+ *
+ * @remarks This doesn't currently work for all handles (like RTFILE).
+ */
+#if HC_ARCH_BITS == 32
+# define ASMAtomicUoReadHandle(ph, phRes) \
+    do { \
+        AssertCompile(sizeof(*(ph))    == sizeof(uint32_t)); \
+        AssertCompile(sizeof(*(phRes)) == sizeof(uint32_t)); \
+        *(uint32_t *)(phRes) = ASMAtomicUoReadU32((uint32_t volatile *)(ph)); \
+    } while (0)
+#elif HC_ARCH_BITS == 64
+# define ASMAtomicUoReadHandle(ph, phRes) \
+    do { \
+        AssertCompile(sizeof(*(ph))    == sizeof(uint64_t)); \
+        AssertCompile(sizeof(*(phRes)) == sizeof(uint64_t)); \
+        *(uint64_t *)(phRes) = ASMAtomicUoReadU64((uint64_t volatile *)(ph)); \
+    } while (0)
+#else
+# error HC_ARCH_BITS
+#endif
+
+
+/**
+ * Atomically read a value which size might differ
+ * between platforms or compilers, ordered.
+ *
+ * @param   pu      Pointer to the variable to read.
+ * @param   puRes   Where to store the result.
+ */
+#define ASMAtomicReadSize(pu, puRes) \
+    do { \
+        switch (sizeof(*(pu))) { \
+            case 1: *(uint8_t  *)(puRes) = ASMAtomicReadU8( (volatile uint8_t  *)(void *)(pu)); break; \
+            case 2: *(uint16_t *)(puRes) = ASMAtomicReadU16((volatile uint16_t *)(void *)(pu)); break; \
+            case 4: *(uint32_t *)(puRes) = ASMAtomicReadU32((volatile uint32_t *)(void *)(pu)); break; \
+            case 8: *(uint64_t *)(puRes) = ASMAtomicReadU64((volatile uint64_t *)(void *)(pu)); break; \
+            default: AssertMsgFailed(("ASMAtomicReadSize: size %d is not supported\n", sizeof(*(pu)))); \
+        } \
+    } while (0)
+
+
+/**
+ * Atomically read a value which size might differ
+ * between platforms or compilers, unordered.
+ *
+ * @param   pu      Pointer to the variable to read.
+ * @param   puRes   Where to store the result.
+ */
+#define ASMAtomicUoReadSize(pu, puRes) \
+    do { \
+        switch (sizeof(*(pu))) { \
+            case 1: *(uint8_t  *)(puRes) = ASMAtomicUoReadU8( (volatile uint8_t  *)(void *)(pu)); break; \
+            case 2: *(uint16_t *)(puRes) = ASMAtomicUoReadU16((volatile uint16_t *)(void *)(pu)); break; \
+            case 4: *(uint32_t *)(puRes) = ASMAtomicUoReadU32((volatile uint32_t *)(void *)(pu)); break; \
+            case 8: *(uint64_t *)(puRes) = ASMAtomicUoReadU64((volatile uint64_t *)(void *)(pu)); break; \
+            default: AssertMsgFailed(("ASMAtomicReadSize: size %d is not supported\n", sizeof(*(pu)))); \
+        } \
+    } while (0)
+
+
+/**
+ * Atomically writes an unsigned 8-bit value, ordered.
+ *
+ * @param   pu8     Pointer to the 8-bit variable.
+ * @param   u8      The 8-bit value to assign to *pu8.
+ */
+DECLINLINE(void) ASMAtomicWriteU8(volatile uint8_t *pu8, uint8_t u8)
+{
+    ASMAtomicXchgU8(pu8, u8);
+}
+
+
+/**
+ * Atomically writes an unsigned 8-bit value, unordered.
+ *
+ * @param   pu8     Pointer to the 8-bit variable.
+ * @param   u8      The 8-bit value to assign to *pu8.
+ */
+DECLINLINE(void) ASMAtomicUoWriteU8(volatile uint8_t *pu8, uint8_t u8)
+{
+    *pu8 = u8;      /* byte writes are atomic on x86 */
+}
+
+
+/**
+ * Atomically writes a signed 8-bit value, ordered.
+ *
+ * @param   pi8     Pointer to the 8-bit variable to read.
+ * @param   i8      The 8-bit value to assign to *pi8.
+ */
+DECLINLINE(void) ASMAtomicWriteS8(volatile int8_t *pi8, int8_t i8)
+{
+    ASMAtomicXchgS8(pi8, i8);
+}
+
+
+/**
+ * Atomically writes a signed 8-bit value, unordered.
+ *
+ * @param   pi8     Pointer to the 8-bit variable to write.
+ * @param   i8      The 8-bit value to assign to *pi8.
+ */
+DECLINLINE(void) ASMAtomicUoWriteS8(volatile int8_t *pi8, int8_t i8)
+{
+    *pi8 = i8;      /* byte writes are atomic on x86 */
+}
+
+
+/**
+ * Atomically writes an unsigned 16-bit value, ordered.
+ *
+ * @param   pu16    Pointer to the 16-bit variable to write.
+ * @param   u16     The 16-bit value to assign to *pu16.
+ */
+DECLINLINE(void) ASMAtomicWriteU16(volatile uint16_t *pu16, uint16_t u16)
+{
+    ASMAtomicXchgU16(pu16, u16);
+}
+
+
+/**
+ * Atomically writes an unsigned 16-bit value, unordered.
+ *
+ * @param   pu16    Pointer to the 16-bit variable to write.
+ * @param   u16     The 16-bit value to assign to *pu16.
+ */
+DECLINLINE(void) ASMAtomicUoWriteU16(volatile uint16_t *pu16, uint16_t u16)
+{
+    Assert(!((uintptr_t)pu16 & 1));
+    *pu16 = u16;
+}
+
+
+/**
+ * Atomically writes a signed 16-bit value, ordered.
+ *
+ * @param   pi16    Pointer to the 16-bit variable to write.
+ * @param   i16     The 16-bit value to assign to *pi16.
+ */
+DECLINLINE(void) ASMAtomicWriteS16(volatile int16_t *pi16, int16_t i16)
+{
+    ASMAtomicXchgS16(pi16, i16);
+}
+
+
+/**
+ * Atomically writes a signed 16-bit value, unordered.
+ *
+ * @param   pi16    Pointer to the 16-bit variable to write.
+ * @param   i16     The 16-bit value to assign to *pi16.
+ */
+DECLINLINE(void) ASMAtomicUoWriteS16(volatile int16_t *pi16, int16_t i16)
+{
+    Assert(!((uintptr_t)pi16 & 1));
+    *pi16 = i16;
+}
+
+
+/**
+ * Atomically writes an unsigned 32-bit value, ordered.
+ *
+ * @param   pu32    Pointer to the 32-bit variable to write.
+ * @param   u32     The 32-bit value to assign to *pu32.
+ */
+DECLINLINE(void) ASMAtomicWriteU32(volatile uint32_t *pu32, uint32_t u32)
+{
+    ASMAtomicXchgU32(pu32, u32);
+}
+
+
+/**
+ * Atomically writes an unsigned 32-bit value, unordered.
+ *
+ * @param   pu32    Pointer to the 32-bit variable to write.
+ * @param   u32     The 32-bit value to assign to *pu32.
+ */
+DECLINLINE(void) ASMAtomicUoWriteU32(volatile uint32_t *pu32, uint32_t u32)
+{
+    Assert(!((uintptr_t)pu32 & 3));
+    *pu32 = u32;
+}
+
+
+/**
+ * Atomically writes a signed 32-bit value, ordered.
+ *
+ * @param   pi32    Pointer to the 32-bit variable to write.
+ * @param   i32     The 32-bit value to assign to *pi32.
+ */
+DECLINLINE(void) ASMAtomicWriteS32(volatile int32_t *pi32, int32_t i32)
+{
+    ASMAtomicXchgS32(pi32, i32);
+}
+
+
+/**
+ * Atomically writes a signed 32-bit value, unordered.
+ *
+ * @param   pi32    Pointer to the 32-bit variable to write.
+ * @param   i32     The 32-bit value to assign to *pi32.
+ */
+DECLINLINE(void) ASMAtomicUoWriteS32(volatile int32_t *pi32, int32_t i32)
+{
+    Assert(!((uintptr_t)pi32 & 3));
+    *pi32 = i32;
+}
+
+
+/**
+ * Atomically writes an unsigned 64-bit value, ordered.
+ *
+ * @param   pu64    Pointer to the 64-bit variable to write.
+ * @param   u64     The 64-bit value to assign to *pu64.
+ */
+DECLINLINE(void) ASMAtomicWriteU64(volatile uint64_t *pu64, uint64_t u64)
+{
+    ASMAtomicXchgU64(pu64, u64);
+}
+
+
+/**
+ * Atomically writes an unsigned 64-bit value, unordered.
+ *
+ * @param   pu64    Pointer to the 64-bit variable to write.
+ * @param   u64     The 64-bit value to assign to *pu64.
+ */
+DECLINLINE(void) ASMAtomicUoWriteU64(volatile uint64_t *pu64, uint64_t u64)
+{
+    Assert(!((uintptr_t)pu64 & 7));
+#if ARCH_BITS == 64
+    *pu64 = u64;
+#else
+    ASMAtomicXchgU64(pu64, u64);
+#endif
+}
+
+
+/**
+ * Atomically writes a signed 64-bit value, ordered.
+ *
+ * @param   pi64    Pointer to the 64-bit variable to write.
+ * @param   i64     The 64-bit value to assign to *pi64.
+ */
+DECLINLINE(void) ASMAtomicWriteS64(volatile int64_t *pi64, int64_t i64)
+{
+    ASMAtomicXchgS64(pi64, i64);
+}
+
+
+/**
+ * Atomically writes a signed 64-bit value, unordered.
+ *
+ * @param   pi64    Pointer to the 64-bit variable to write.
+ * @param   i64     The 64-bit value to assign to *pi64.
+ */
+DECLINLINE(void) ASMAtomicUoWriteS64(volatile int64_t *pi64, int64_t i64)
+{
+    Assert(!((uintptr_t)pi64 & 7));
+#if ARCH_BITS == 64
+    *pi64 = i64;
+#else
+    ASMAtomicXchgS64(pi64, i64);
+#endif
+}
+
+
+/**
+ * Atomically writes a boolean value, unordered.
+ *
+ * @param   pf      Pointer to the boolean variable to write.
+ * @param   f       The boolean value to assign to *pf.
+ */
+DECLINLINE(void) ASMAtomicWriteBool(volatile bool *pf, bool f)
+{
+    ASMAtomicWriteU8((uint8_t volatile *)pf, f);
+}
+
+
+/**
+ * Atomically writes a boolean value, unordered.
+ *
+ * @param   pf      Pointer to the boolean variable to write.
+ * @param   f       The boolean value to assign to *pf.
+ */
+DECLINLINE(void) ASMAtomicUoWriteBool(volatile bool *pf, bool f)
+{
+    *pf = f;    /* byte writes are atomic on x86 */
+}
+
+
+/**
+ * Atomically writes a pointer value, ordered.
+ *
+ * @param   ppv     Pointer to the pointer variable to write.
+ * @param   pv      The pointer value to assign to *ppv.
+ */
+DECLINLINE(void) ASMAtomicWritePtrVoid(void * volatile *ppv, const void *pv)
+{
+#if ARCH_BITS == 32
+    ASMAtomicWriteU32((volatile uint32_t *)(void *)ppv, (uint32_t)pv);
+#elif ARCH_BITS == 64
+    ASMAtomicWriteU64((volatile uint64_t *)(void *)ppv, (uint64_t)pv);
+#else
+# error "ARCH_BITS is bogus"
+#endif
+}
+
+
+/**
+ * Atomically writes a pointer value, ordered.
+ *
+ * @param   ppv     Pointer to the pointer variable to write.
+ * @param   pv      The pointer value to assign to *ppv. If NULL use
+ *                  ASMAtomicWriteNullPtr or you'll land in trouble.
+ *
+ * @remarks This is relatively type safe on GCC platforms when @a pv isn't
+ *          NULL.
+ */
+#ifdef __GNUC__
+# define ASMAtomicWritePtr(ppv, pv) \
+    do \
+    { \
+        __typeof__(*(ppv)) volatile * const ppvTypeChecked = (ppv); \
+        __typeof__(*(ppv))            const pvTypeChecked  = (pv); \
+        \
+        AssertCompile(sizeof(*ppv) == sizeof(void *)); \
+        AssertCompile(sizeof(pv) == sizeof(void *)); \
+        Assert(!( (uintptr_t)ppv & ((ARCH_BITS / 8) - 1) )); \
+        \
+        ASMAtomicWritePtrVoid((void * volatile *)(ppvTypeChecked), (void *)(pvTypeChecked)); \
+    } while (0)
+#else
+# define ASMAtomicWritePtr(ppv, pv) \
+    do \
+    { \
+        AssertCompile(sizeof(*ppv) == sizeof(void *)); \
+        AssertCompile(sizeof(pv) == sizeof(void *)); \
+        Assert(!( (uintptr_t)ppv & ((ARCH_BITS / 8) - 1) )); \
+        \
+        ASMAtomicWritePtrVoid((void * volatile *)(ppv), (void *)(pv)); \
+    } while (0)
+#endif
+
+
+/**
+ * Atomically sets a pointer to NULL, ordered.
+ *
+ * @param   ppv     Pointer to the pointer variable that should be set to NULL.
+ *
+ * @remarks This is relatively type safe on GCC platforms.
+ */
+#ifdef __GNUC__
+# define ASMAtomicWriteNullPtr(ppv) \
+    do \
+    { \
+        __typeof__(*(ppv)) * const ppvTypeChecked = (ppv); \
+        AssertCompile(sizeof(*ppv) == sizeof(void *)); \
+        Assert(!( (uintptr_t)ppv & ((ARCH_BITS / 8) - 1) )); \
+        ASMAtomicWritePtrVoid((void * volatile *)(ppvTypeChecked), NULL); \
+    } while (0)
+#else
+# define ASMAtomicWriteNullPtr(ppv) \
+    do \
+    { \
+        AssertCompile(sizeof(*ppv) == sizeof(void *)); \
+        Assert(!( (uintptr_t)ppv & ((ARCH_BITS / 8) - 1) )); \
+        ASMAtomicWritePtrVoid((void * volatile *)(ppv), NULL); \
+    } while (0)
+#endif
+
+
+/**
+ * Atomically writes a pointer value, unordered.
+ *
+ * @returns Current *pv value
+ * @param   ppv     Pointer to the pointer variable.
+ * @param   pv      The pointer value to assign to *ppv. If NULL use
+ *                  ASMAtomicUoWriteNullPtr or you'll land in trouble.
+ *
+ * @remarks This is relatively type safe on GCC platforms when @a pv isn't
+ *          NULL.
+ */
+#ifdef __GNUC__
+# define ASMAtomicUoWritePtr(ppv, pv) \
+    do \
+    { \
+        __typeof__(*(ppv)) volatile * const ppvTypeChecked = (ppv); \
+        __typeof__(*(ppv))            const pvTypeChecked  = (pv); \
+        \
+        AssertCompile(sizeof(*ppv) == sizeof(void *)); \
+        AssertCompile(sizeof(pv) == sizeof(void *)); \
+        Assert(!( (uintptr_t)ppv & ((ARCH_BITS / 8) - 1) )); \
+        \
+        *(ppvTypeChecked) = pvTypeChecked; \
+    } while (0)
+#else
+# define ASMAtomicUoWritePtr(ppv, pv) \
+    do \
+    { \
+        AssertCompile(sizeof(*ppv) == sizeof(void *)); \
+        AssertCompile(sizeof(pv) == sizeof(void *)); \
+        Assert(!( (uintptr_t)ppv & ((ARCH_BITS / 8) - 1) )); \
+        *(ppv) = pv; \
+    } while (0)
+#endif
+
+
+/**
+ * Atomically sets a pointer to NULL, unordered.
+ *
+ * @param   ppv     Pointer to the pointer variable that should be set to NULL.
+ *
+ * @remarks This is relatively type safe on GCC platforms.
+ */
+#ifdef __GNUC__
+# define ASMAtomicUoWriteNullPtr(ppv) \
+    do \
+    { \
+        __typeof__(*(ppv)) volatile * const ppvTypeChecked = (ppv); \
+        AssertCompile(sizeof(*ppv) == sizeof(void *)); \
+        Assert(!( (uintptr_t)ppv & ((ARCH_BITS / 8) - 1) )); \
+        *(ppvTypeChecked) = NULL; \
+    } while (0)
+#else
+# define ASMAtomicUoWriteNullPtr(ppv) \
+    do \
+    { \
+        AssertCompile(sizeof(*ppv) == sizeof(void *)); \
+        Assert(!( (uintptr_t)ppv & ((ARCH_BITS / 8) - 1) )); \
+        *(ppv) = NULL; \
+    } while (0)
+#endif
+
+
+/**
+ * Atomically write a typical IPRT handle value, ordered.
+ *
+ * @param   ph      Pointer to the variable to update.
+ * @param   hNew    The value to assign to *ph.
+ *
+ * @remarks This doesn't currently work for all handles (like RTFILE).
+ */
+#if HC_ARCH_BITS == 32
+# define ASMAtomicWriteHandle(ph, hNew) \
+    do { \
+        AssertCompile(sizeof(*(ph)) == sizeof(uint32_t)); \
+        ASMAtomicWriteU32((uint32_t volatile *)(ph), (const uint32_t)(hNew)); \
+    } while (0)
+#elif HC_ARCH_BITS == 64
+# define ASMAtomicWriteHandle(ph, hNew) \
+    do { \
+        AssertCompile(sizeof(*(ph)) == sizeof(uint64_t)); \
+        ASMAtomicWriteU64((uint64_t volatile *)(ph), (const uint64_t)(hNew)); \
+    } while (0)
+#else
+# error HC_ARCH_BITS
+#endif
+
+
+/**
+ * Atomically write a typical IPRT handle value, unordered.
+ *
+ * @param   ph      Pointer to the variable to update.
+ * @param   hNew    The value to assign to *ph.
+ *
+ * @remarks This doesn't currently work for all handles (like RTFILE).
+ */
+#if HC_ARCH_BITS == 32
+# define ASMAtomicUoWriteHandle(ph, hNew) \
+    do { \
+        AssertCompile(sizeof(*(ph)) == sizeof(uint32_t)); \
+        ASMAtomicUoWriteU32((uint32_t volatile *)(ph), (const uint32_t)hNew); \
+    } while (0)
+#elif HC_ARCH_BITS == 64
+# define ASMAtomicUoWriteHandle(ph, hNew) \
+    do { \
+        AssertCompile(sizeof(*(ph)) == sizeof(uint64_t)); \
+        ASMAtomicUoWriteU64((uint64_t volatile *)(ph), (const uint64_t)hNew); \
+    } while (0)
+#else
+# error HC_ARCH_BITS
+#endif
+
+
+/**
+ * Atomically write a value which size might differ
+ * between platforms or compilers, ordered.
+ *
+ * @param   pu      Pointer to the variable to update.
+ * @param   uNew    The value to assign to *pu.
+ */
+#define ASMAtomicWriteSize(pu, uNew) \
+    do { \
+        switch (sizeof(*(pu))) { \
+            case 1: ASMAtomicWriteU8( (volatile uint8_t  *)(void *)(pu), (uint8_t )(uNew)); break; \
+            case 2: ASMAtomicWriteU16((volatile uint16_t *)(void *)(pu), (uint16_t)(uNew)); break; \
+            case 4: ASMAtomicWriteU32((volatile uint32_t *)(void *)(pu), (uint32_t)(uNew)); break; \
+            case 8: ASMAtomicWriteU64((volatile uint64_t *)(void *)(pu), (uint64_t)(uNew)); break; \
+            default: AssertMsgFailed(("ASMAtomicWriteSize: size %d is not supported\n", sizeof(*(pu)))); \
+        } \
+    } while (0)
+
+/**
+ * Atomically write a value which size might differ
+ * between platforms or compilers, unordered.
+ *
+ * @param   pu      Pointer to the variable to update.
+ * @param   uNew    The value to assign to *pu.
+ */
+#define ASMAtomicUoWriteSize(pu, uNew) \
+    do { \
+        switch (sizeof(*(pu))) { \
+            case 1: ASMAtomicUoWriteU8( (volatile uint8_t  *)(void *)(pu), (uint8_t )(uNew)); break; \
+            case 2: ASMAtomicUoWriteU16((volatile uint16_t *)(void *)(pu), (uint16_t)(uNew)); break; \
+            case 4: ASMAtomicUoWriteU32((volatile uint32_t *)(void *)(pu), (uint32_t)(uNew)); break; \
+            case 8: ASMAtomicUoWriteU64((volatile uint64_t *)(void *)(pu), (uint64_t)(uNew)); break; \
+            default: AssertMsgFailed(("ASMAtomicWriteSize: size %d is not supported\n", sizeof(*(pu)))); \
+        } \
+    } while (0)
+
+
+
+/**
+ * Atomically exchanges and adds to a 32-bit value, ordered.
+ *
+ * @returns The old value.
+ * @param   pu32        Pointer to the value.
+ * @param   u32         Number to add.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(uint32_t) ASMAtomicAddU32(uint32_t volatile *pu32, uint32_t u32);
+#else
+DECLINLINE(uint32_t) ASMAtomicAddU32(uint32_t volatile *pu32, uint32_t u32)
+{
+# if RT_INLINE_ASM_USES_INTRIN
+    u32 = _InterlockedExchangeAdd((long *)pu32, u32);
+    return u32;
+
+# elif RT_INLINE_ASM_GNU_STYLE
+    __asm__ __volatile__("lock; xaddl %0, %1\n\t"
+                         : "=r" (u32),
+                           "=m" (*pu32)
+                         : "0" (u32),
+                           "m" (*pu32)
+                         : "memory");
+    return u32;
+# else
+    __asm
+    {
+        mov     eax, [u32]
+#  ifdef RT_ARCH_AMD64
+        mov     rdx, [pu32]
+        lock xadd [rdx], eax
+#  else
+        mov     edx, [pu32]
+        lock xadd [edx], eax
+#  endif
+        mov     [u32], eax
+    }
+    return u32;
+# endif
+}
+#endif
+
+
+/**
+ * Atomically exchanges and adds to a signed 32-bit value, ordered.
+ *
+ * @returns The old value.
+ * @param   pi32        Pointer to the value.
+ * @param   i32         Number to add.
+ */
+DECLINLINE(int32_t) ASMAtomicAddS32(int32_t volatile *pi32, int32_t i32)
+{
+    return (int32_t)ASMAtomicAddU32((uint32_t volatile *)pi32, (uint32_t)i32);
+}
+
+
+/**
+ * Atomically exchanges and adds to a 64-bit value, ordered.
+ *
+ * @returns The old value.
+ * @param   pu64        Pointer to the value.
+ * @param   u64         Number to add.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(uint64_t) ASMAtomicAddU64(uint64_t volatile *pu64, uint64_t u64);
+#else
+DECLINLINE(uint64_t) ASMAtomicAddU64(uint64_t volatile *pu64, uint64_t u64)
+{
+# if RT_INLINE_ASM_USES_INTRIN && defined(RT_ARCH_AMD64)
+    u64 = _InterlockedExchangeAdd64((__int64 *)pu64, u64);
+    return u64;
+
+# elif RT_INLINE_ASM_GNU_STYLE && defined(RT_ARCH_AMD64)
+    __asm__ __volatile__("lock; xaddq %0, %1\n\t"
+                         : "=r" (u64),
+                           "=m" (*pu64)
+                         : "0" (u64),
+                           "m" (*pu64)
+                         : "memory");
+    return u64;
+# else
+    uint64_t u64Old;
+    for (;;)
+    {
+        uint64_t u64New;
+        u64Old = ASMAtomicUoReadU64(pu64);
+        u64New = u64Old + u64;
+        if (ASMAtomicCmpXchgU64(pu64, u64New, u64Old))
+            break;
+        ASMNopPause();
+    }
+    return u64Old;
+# endif
+}
+#endif
+
+
+/**
+ * Atomically exchanges and adds to a signed 64-bit value, ordered.
+ *
+ * @returns The old value.
+ * @param   pi64        Pointer to the value.
+ * @param   i64         Number to add.
+ */
+DECLINLINE(int64_t) ASMAtomicAddS64(int64_t volatile *pi64, int64_t i64)
+{
+    return (int64_t)ASMAtomicAddU64((uint64_t volatile *)pi64, (uint64_t)i64);
+}
+
+
+/**
+ * Atomically exchanges and adds to a size_t value, ordered.
+ *
+ * @returns The old value.
+ * @param   pcb         Pointer to the size_t value.
+ * @param   cb          Number to add.
+ */
+DECLINLINE(size_t) ASMAtomicAddZ(size_t volatile *pcb, size_t cb)
+{
+#if ARCH_BITS == 64
+    return ASMAtomicAddU64((uint64_t volatile *)pcb, cb);
+#elif ARCH_BITS == 32
+    return ASMAtomicAddU32((uint32_t volatile *)pcb, cb);
+#else
+# error "Unsupported ARCH_BITS value"
+#endif
+}
+
+
+/**
+ * Atomically exchanges and adds a value which size might differ between
+ * platforms or compilers, ordered.
+ *
+ * @param   pu      Pointer to the variable to update.
+ * @param   uNew    The value to add to *pu.
+ * @param   puOld   Where to store the old value.
+ */
+#define ASMAtomicAddSize(pu, uNew, puOld) \
+    do { \
+        switch (sizeof(*(pu))) { \
+            case 4: *(uint32_t  *)(puOld) = ASMAtomicAddU32((volatile uint32_t *)(void *)(pu), (uint32_t)(uNew)); break; \
+            case 8: *(uint64_t  *)(puOld) = ASMAtomicAddU64((volatile uint64_t *)(void *)(pu), (uint64_t)(uNew)); break; \
+            default: AssertMsgFailed(("ASMAtomicAddSize: size %d is not supported\n", sizeof(*(pu)))); \
+        } \
+    } while (0)
+
+
+/**
+ * Atomically exchanges and subtracts to an unsigned 32-bit value, ordered.
+ *
+ * @returns The old value.
+ * @param   pu32        Pointer to the value.
+ * @param   u32         Number to subtract.
+ */
+DECLINLINE(uint32_t) ASMAtomicSubU32(uint32_t volatile *pu32, uint32_t u32)
+{
+    return ASMAtomicAddU32(pu32, (uint32_t)-(int32_t)u32);
+}
+
+
+/**
+ * Atomically exchanges and subtracts to a signed 32-bit value, ordered.
+ *
+ * @returns The old value.
+ * @param   pi32        Pointer to the value.
+ * @param   i32         Number to subtract.
+ */
+DECLINLINE(int32_t) ASMAtomicSubS32(int32_t volatile *pi32, int32_t i32)
+{
+    return (int32_t)ASMAtomicAddU32((uint32_t volatile *)pi32, (uint32_t)-i32);
+}
+
+
+/**
+ * Atomically exchanges and subtracts to an unsigned 64-bit value, ordered.
+ *
+ * @returns The old value.
+ * @param   pu64        Pointer to the value.
+ * @param   u64         Number to subtract.
+ */
+DECLINLINE(uint64_t) ASMAtomicSubU64(uint64_t volatile *pu64, uint64_t u64)
+{
+    return ASMAtomicAddU64(pu64, (uint64_t)-(int64_t)u64);
+}
+
+
+/**
+ * Atomically exchanges and subtracts to a signed 64-bit value, ordered.
+ *
+ * @returns The old value.
+ * @param   pi64        Pointer to the value.
+ * @param   i64         Number to subtract.
+ */
+DECLINLINE(int64_t) ASMAtomicSubS64(int64_t volatile *pi64, int64_t i64)
+{
+    return (int64_t)ASMAtomicAddU64((uint64_t volatile *)pi64, (uint64_t)-i64);
+}
+
+
+/**
+ * Atomically exchanges and subtracts to a size_t value, ordered.
+ *
+ * @returns The old value.
+ * @param   pcb         Pointer to the size_t value.
+ * @param   cb          Number to subtract.
+ */
+DECLINLINE(size_t) ASMAtomicSubZ(size_t volatile *pcb, size_t cb)
+{
+#if ARCH_BITS == 64
+    return ASMAtomicSubU64((uint64_t volatile *)pcb, cb);
+#elif ARCH_BITS == 32
+    return ASMAtomicSubU32((uint32_t volatile *)pcb, cb);
+#else
+# error "Unsupported ARCH_BITS value"
+#endif
+}
+
+
+/**
+ * Atomically exchanges and subtracts a value which size might differ between
+ * platforms or compilers, ordered.
+ *
+ * @param   pu      Pointer to the variable to update.
+ * @param   uNew    The value to subtract to *pu.
+ * @param   puOld   Where to store the old value.
+ */
+#define ASMAtomicSubSize(pu, uNew, puOld) \
+    do { \
+        switch (sizeof(*(pu))) { \
+            case 4: *(uint32_t  *)(puOld) = ASMAtomicSubU32((volatile uint32_t *)(void *)(pu), (uint32_t)(uNew)); break; \
+            case 8: *(uint64_t  *)(puOld) = ASMAtomicSubU64((volatile uint64_t *)(void *)(pu), (uint64_t)(uNew)); break; \
+            default: AssertMsgFailed(("ASMAtomicSubSize: size %d is not supported\n", sizeof(*(pu)))); \
+        } \
+    } while (0)
+
+
+/**
+ * Atomically increment a 32-bit value, ordered.
+ *
+ * @returns The new value.
+ * @param   pu32        Pointer to the value to increment.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(uint32_t) ASMAtomicIncU32(uint32_t volatile *pu32);
+#else
+DECLINLINE(uint32_t) ASMAtomicIncU32(uint32_t volatile *pu32)
+{
+    uint32_t u32;
+# if RT_INLINE_ASM_USES_INTRIN
+    u32 = _InterlockedIncrement((long *)pu32);
+    return u32;
+
+# elif RT_INLINE_ASM_GNU_STYLE
+    __asm__ __volatile__("lock; xaddl %0, %1\n\t"
+                         : "=r" (u32),
+                           "=m" (*pu32)
+                         : "0" (1),
+                           "m" (*pu32)
+                         : "memory");
+    return u32+1;
+# else
+    __asm
+    {
+        mov     eax, 1
+#  ifdef RT_ARCH_AMD64
+        mov     rdx, [pu32]
+        lock xadd [rdx], eax
+#  else
+        mov     edx, [pu32]
+        lock xadd [edx], eax
+#  endif
+        mov     u32, eax
+    }
+    return u32+1;
+# endif
+}
+#endif
+
+
+/**
+ * Atomically increment a signed 32-bit value, ordered.
+ *
+ * @returns The new value.
+ * @param   pi32        Pointer to the value to increment.
+ */
+DECLINLINE(int32_t) ASMAtomicIncS32(int32_t volatile *pi32)
+{
+    return (int32_t)ASMAtomicIncU32((uint32_t volatile *)pi32);
+}
+
+
+/**
+ * Atomically increment a 64-bit value, ordered.
+ *
+ * @returns The new value.
+ * @param   pu64        Pointer to the value to increment.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(uint64_t) ASMAtomicIncU64(uint64_t volatile *pu64);
+#else
+DECLINLINE(uint64_t) ASMAtomicIncU64(uint64_t volatile *pu64)
+{
+# if RT_INLINE_ASM_USES_INTRIN && defined(RT_ARCH_AMD64)
+    uint64_t u64;
+    u64 = _InterlockedIncrement64((__int64 *)pu64);
+    return u64;
+
+# elif RT_INLINE_ASM_GNU_STYLE && defined(RT_ARCH_AMD64)
+    uint64_t u64;
+    __asm__ __volatile__("lock; xaddq %0, %1\n\t"
+                         : "=r" (u64),
+                           "=m" (*pu64)
+                         : "0" (1),
+                           "m" (*pu64)
+                         : "memory");
+    return u64 + 1;
+# else
+    return ASMAtomicAddU64(pu64, 1) + 1;
+# endif
+}
+#endif
+
+
+/**
+ * Atomically increment a signed 64-bit value, ordered.
+ *
+ * @returns The new value.
+ * @param   pi64        Pointer to the value to increment.
+ */
+DECLINLINE(int64_t) ASMAtomicIncS64(int64_t volatile *pi64)
+{
+    return (int64_t)ASMAtomicIncU64((uint64_t volatile *)pi64);
+}
+
+
+/**
+ * Atomically increment a size_t value, ordered.
+ *
+ * @returns The new value.
+ * @param   pcb         Pointer to the value to increment.
+ */
+DECLINLINE(int64_t) ASMAtomicIncZ(size_t volatile *pcb)
+{
+#if ARCH_BITS == 64
+    return ASMAtomicIncU64((uint64_t volatile *)pcb);
+#elif ARCH_BITS == 32
+    return ASMAtomicIncU32((uint32_t volatile *)pcb);
+#else
+# error "Unsupported ARCH_BITS value"
+#endif
+}
+
+
+/**
+ * Atomically decrement an unsigned 32-bit value, ordered.
+ *
+ * @returns The new value.
+ * @param   pu32        Pointer to the value to decrement.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(uint32_t) ASMAtomicDecU32(uint32_t volatile *pu32);
+#else
+DECLINLINE(uint32_t) ASMAtomicDecU32(uint32_t volatile *pu32)
+{
+    uint32_t u32;
+# if RT_INLINE_ASM_USES_INTRIN
+    u32 = _InterlockedDecrement((long *)pu32);
+    return u32;
+
+# elif RT_INLINE_ASM_GNU_STYLE
+    __asm__ __volatile__("lock; xaddl %0, %1\n\t"
+                         : "=r" (u32),
+                           "=m" (*pu32)
+                         : "0" (-1),
+                           "m" (*pu32)
+                         : "memory");
+    return u32-1;
+# else
+    __asm
+    {
+        mov     eax, -1
+#  ifdef RT_ARCH_AMD64
+        mov     rdx, [pu32]
+        lock xadd [rdx], eax
+#  else
+        mov     edx, [pu32]
+        lock xadd [edx], eax
+#  endif
+        mov     u32, eax
+    }
+    return u32-1;
+# endif
+}
+#endif
+
+
+/**
+ * Atomically decrement a signed 32-bit value, ordered.
+ *
+ * @returns The new value.
+ * @param   pi32        Pointer to the value to decrement.
+ */
+DECLINLINE(int32_t) ASMAtomicDecS32(int32_t volatile *pi32)
+{
+    return (int32_t)ASMAtomicDecU32((uint32_t volatile *)pi32);
+}
+
+
+/**
+ * Atomically decrement an unsigned 64-bit value, ordered.
+ *
+ * @returns The new value.
+ * @param   pu64        Pointer to the value to decrement.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(uint64_t) ASMAtomicDecU64(uint64_t volatile *pu64);
+#else
+DECLINLINE(uint64_t) ASMAtomicDecU64(uint64_t volatile *pu64)
+{
+# if RT_INLINE_ASM_USES_INTRIN && defined(RT_ARCH_AMD64)
+    uint64_t u64 = _InterlockedDecrement64((__int64 volatile *)pu64);
+    return u64;
+
+# elif RT_INLINE_ASM_GNU_STYLE && defined(RT_ARCH_AMD64)
+    uint64_t u64;
+    __asm__ __volatile__("lock; xaddq %q0, %1\n\t"
+                         : "=r" (u64),
+                           "=m" (*pu64)
+                         : "0" (~(uint64_t)0),
+                           "m" (*pu64)
+                         : "memory");
+    return u64-1;
+# else
+    return ASMAtomicAddU64(pu64, UINT64_MAX) - 1;
+# endif
+}
+#endif
+
+
+/**
+ * Atomically decrement a signed 64-bit value, ordered.
+ *
+ * @returns The new value.
+ * @param   pi64        Pointer to the value to decrement.
+ */
+DECLINLINE(int64_t) ASMAtomicDecS64(int64_t volatile *pi64)
+{
+    return (int64_t)ASMAtomicDecU64((uint64_t volatile *)pi64);
+}
+
+
+/**
+ * Atomically decrement a size_t value, ordered.
+ *
+ * @returns The new value.
+ * @param   pcb         Pointer to the value to decrement.
+ */
+DECLINLINE(int64_t) ASMAtomicDecZ(size_t volatile *pcb)
+{
+#if ARCH_BITS == 64
+    return ASMAtomicDecU64((uint64_t volatile *)pcb);
+#elif ARCH_BITS == 32
+    return ASMAtomicDecU32((uint32_t volatile *)pcb);
+#else
+# error "Unsupported ARCH_BITS value"
+#endif
+}
+
+
+/**
+ * Atomically Or an unsigned 32-bit value, ordered.
+ *
+ * @param   pu32   Pointer to the pointer variable to OR u32 with.
+ * @param   u32    The value to OR *pu32 with.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(void) ASMAtomicOrU32(uint32_t volatile *pu32, uint32_t u32);
+#else
+DECLINLINE(void) ASMAtomicOrU32(uint32_t volatile *pu32, uint32_t u32)
+{
+# if RT_INLINE_ASM_USES_INTRIN
+    _InterlockedOr((long volatile *)pu32, (long)u32);
+
+# elif RT_INLINE_ASM_GNU_STYLE
+    __asm__ __volatile__("lock; orl %1, %0\n\t"
+                         : "=m" (*pu32)
+                         : "ir" (u32),
+                           "m" (*pu32));
+# else
+    __asm
+    {
+        mov     eax, [u32]
+#  ifdef RT_ARCH_AMD64
+        mov     rdx, [pu32]
+        lock    or [rdx], eax
+#  else
+        mov     edx, [pu32]
+        lock    or [edx], eax
+#  endif
+    }
+# endif
+}
+#endif
+
+
+/**
+ * Atomically Or a signed 32-bit value, ordered.
+ *
+ * @param   pi32   Pointer to the pointer variable to OR u32 with.
+ * @param   i32    The value to OR *pu32 with.
+ */
+DECLINLINE(void) ASMAtomicOrS32(int32_t volatile *pi32, int32_t i32)
+{
+    ASMAtomicOrU32((uint32_t volatile *)pi32, i32);
+}
+
+
+/**
+ * Atomically Or an unsigned 64-bit value, ordered.
+ *
+ * @param   pu64   Pointer to the pointer variable to OR u64 with.
+ * @param   u64    The value to OR *pu64 with.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(void) ASMAtomicOrU64(uint64_t volatile *pu64, uint64_t u64);
+#else
+DECLINLINE(void) ASMAtomicOrU64(uint64_t volatile *pu64, uint64_t u64)
+{
+# if RT_INLINE_ASM_USES_INTRIN && defined(RT_ARCH_AMD64)
+    _InterlockedOr64((__int64 volatile *)pu64, (__int64)u64);
+
+# elif RT_INLINE_ASM_GNU_STYLE && defined(RT_ARCH_AMD64)
+    __asm__ __volatile__("lock; orq %1, %q0\n\t"
+                         : "=m" (*pu64)
+                         : "r" (u64),
+                           "m" (*pu64));
+# else
+    for (;;)
+    {
+        uint64_t u64Old = ASMAtomicUoReadU64(pu64);
+        uint64_t u64New = u64Old | u64;
+        if (ASMAtomicCmpXchgU64(pu64, u64New, u64Old))
+            break;
+        ASMNopPause();
+    }
+# endif
+}
+#endif
+
+
+/**
+ * Atomically Or a signed 64-bit value, ordered.
+ *
+ * @param   pi64   Pointer to the pointer variable to OR u64 with.
+ * @param   i64    The value to OR *pu64 with.
+ */
+DECLINLINE(void) ASMAtomicOrS64(int64_t volatile *pi64, int64_t i64)
+{
+    ASMAtomicOrU64((uint64_t volatile *)pi64, i64);
+}
+
+
+/**
+ * Atomically And an unsigned 32-bit value, ordered.
+ *
+ * @param   pu32   Pointer to the pointer variable to AND u32 with.
+ * @param   u32    The value to AND *pu32 with.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(void) ASMAtomicAndU32(uint32_t volatile *pu32, uint32_t u32);
+#else
+DECLINLINE(void) ASMAtomicAndU32(uint32_t volatile *pu32, uint32_t u32)
+{
+# if RT_INLINE_ASM_USES_INTRIN
+    _InterlockedAnd((long volatile *)pu32, u32);
+
+# elif RT_INLINE_ASM_GNU_STYLE
+    __asm__ __volatile__("lock; andl %1, %0\n\t"
+                         : "=m" (*pu32)
+                         : "ir" (u32),
+                           "m" (*pu32));
+# else
+    __asm
+    {
+        mov     eax, [u32]
+#  ifdef RT_ARCH_AMD64
+        mov     rdx, [pu32]
+        lock and [rdx], eax
+#  else
+        mov     edx, [pu32]
+        lock and [edx], eax
+#  endif
+    }
+# endif
+}
+#endif
+
+
+/**
+ * Atomically And a signed 32-bit value, ordered.
+ *
+ * @param   pi32   Pointer to the pointer variable to AND i32 with.
+ * @param   i32    The value to AND *pi32 with.
+ */
+DECLINLINE(void) ASMAtomicAndS32(int32_t volatile *pi32, int32_t i32)
+{
+    ASMAtomicAndU32((uint32_t volatile *)pi32, (uint32_t)i32);
+}
+
+
+/**
+ * Atomically And an unsigned 64-bit value, ordered.
+ *
+ * @param   pu64   Pointer to the pointer variable to AND u64 with.
+ * @param   u64    The value to AND *pu64 with.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(void) ASMAtomicAndU64(uint64_t volatile *pu64, uint64_t u64);
+#else
+DECLINLINE(void) ASMAtomicAndU64(uint64_t volatile *pu64, uint64_t u64)
+{
+# if RT_INLINE_ASM_USES_INTRIN && defined(RT_ARCH_AMD64)
+    _InterlockedAnd64((__int64 volatile *)pu64, u64);
+
+# elif RT_INLINE_ASM_GNU_STYLE && defined(RT_ARCH_AMD64)
+    __asm__ __volatile__("lock; andq %1, %0\n\t"
+                         : "=m" (*pu64)
+                         : "r" (u64),
+                           "m" (*pu64));
+# else
+    for (;;)
+    {
+        uint64_t u64Old = ASMAtomicUoReadU64(pu64);
+        uint64_t u64New = u64Old & u64;
+        if (ASMAtomicCmpXchgU64(pu64, u64New, u64Old))
+            break;
+        ASMNopPause();
+    }
+# endif
+}
+#endif
+
+
+/**
+ * Atomically And a signed 64-bit value, ordered.
+ *
+ * @param   pi64   Pointer to the pointer variable to AND i64 with.
+ * @param   i64    The value to AND *pi64 with.
+ */
+DECLINLINE(void) ASMAtomicAndS64(int64_t volatile *pi64, int64_t i64)
+{
+    ASMAtomicAndU64((uint64_t volatile *)pi64, (uint64_t)i64);
+}
+
+
+/**
+ * Atomically OR an unsigned 32-bit value, unordered but interrupt safe.
+ *
+ * @param   pu32   Pointer to the pointer variable to OR u32 with.
+ * @param   u32    The value to OR *pu32 with.
+ */
+#if RT_INLINE_ASM_EXTERNAL
+DECLASM(void) ASMAtomicUoOrU32(uint32_t volatile *pu32, uint32_t u32);
+#else
+DECLINLINE(void) ASMAtomicUoOrU32(uint32_t volatile *pu32, uint32_t u32)
+{
+# if RT_INLINE_ASM_GNU_STYLE
+    __asm__ __volatile__("orl %1, %0\n\t"
+                         : "=m" (*pu32)
+                         : "ir" (u32),
+                           "m" (*pu32));
+# else
+    __asm
+    {
+        mov     eax, [u32]
+#  ifdef RT_ARCH_AMD64
+        mov     rdx, [pu32]
+        or      [rdx], eax
+#  else
+        mov     edx, [pu32]
+        or      [edx], eax
+#  endif
+    }
+# endif
+}
+#endif
+
+
+/**
+ * Atomically OR a signed 32-bit value, unordered.
+ *
+ * @param   pi32   Pointer to the pointer variable to OR u32 with.
+ * @param   i32    The value to OR *pu32 with.
+ */
+DECLINLINE(void) ASMAtomicUoOrS32(int32_t volatile *pi32, int32_t i32)
+{
+    ASMAtomicUoOrU32((uint32_t volatile *)pi32, i32);
+}
+
+
+/**
+ * Atomically OR an unsigned 64-bit value, unordered.
+ *
+ * @param   pu64   Pointer to the pointer variable to OR u64 with.
+ * @param   u64    The value to OR *pu64 with.
+ */
+#if RT_INLINE_ASM_EXTERNAL
+DECLASM(void) ASMAtomicUoOrU64(uint64_t volatile *pu64, uint64_t u64);
+#else
+DECLINLINE(void) ASMAtomicUoOrU64(uint64_t volatile *pu64, uint64_t u64)
+{
+# if RT_INLINE_ASM_GNU_STYLE && defined(RT_ARCH_AMD64)
+    __asm__ __volatile__("orq %1, %q0\n\t"
+                         : "=m" (*pu64)
+                         : "r" (u64),
+                           "m" (*pu64));
+# else
+    for (;;)
+    {
+        uint64_t u64Old = ASMAtomicUoReadU64(pu64);
+        uint64_t u64New = u64Old | u64;
+        if (ASMAtomicCmpXchgU64(pu64, u64New, u64Old))
+            break;
+        ASMNopPause();
+    }
+# endif
+}
+#endif
+
+
+/**
+ * Atomically Or a signed 64-bit value, unordered.
+ *
+ * @param   pi64   Pointer to the pointer variable to OR u64 with.
+ * @param   i64    The value to OR *pu64 with.
+ */
+DECLINLINE(void) ASMAtomicUoOrS64(int64_t volatile *pi64, int64_t i64)
+{
+    ASMAtomicUoOrU64((uint64_t volatile *)pi64, i64);
+}
+
+
+/**
+ * Atomically And an unsigned 32-bit value, unordered.
+ *
+ * @param   pu32   Pointer to the pointer variable to AND u32 with.
+ * @param   u32    The value to AND *pu32 with.
+ */
+#if RT_INLINE_ASM_EXTERNAL
+DECLASM(void) ASMAtomicUoAndU32(uint32_t volatile *pu32, uint32_t u32);
+#else
+DECLINLINE(void) ASMAtomicUoAndU32(uint32_t volatile *pu32, uint32_t u32)
+{
+# if RT_INLINE_ASM_GNU_STYLE
+    __asm__ __volatile__("andl %1, %0\n\t"
+                         : "=m" (*pu32)
+                         : "ir" (u32),
+                           "m" (*pu32));
+# else
+    __asm
+    {
+        mov     eax, [u32]
+#  ifdef RT_ARCH_AMD64
+        mov     rdx, [pu32]
+        and     [rdx], eax
+#  else
+        mov     edx, [pu32]
+        and     [edx], eax
+#  endif
+    }
+# endif
+}
+#endif
+
+
+/**
+ * Atomically And a signed 32-bit value, unordered.
+ *
+ * @param   pi32   Pointer to the pointer variable to AND i32 with.
+ * @param   i32    The value to AND *pi32 with.
+ */
+DECLINLINE(void) ASMAtomicUoAndS32(int32_t volatile *pi32, int32_t i32)
+{
+    ASMAtomicUoAndU32((uint32_t volatile *)pi32, (uint32_t)i32);
+}
+
+
+/**
+ * Atomically And an unsigned 64-bit value, unordered.
+ *
+ * @param   pu64   Pointer to the pointer variable to AND u64 with.
+ * @param   u64    The value to AND *pu64 with.
+ */
+#if RT_INLINE_ASM_EXTERNAL
+DECLASM(void) ASMAtomicUoAndU64(uint64_t volatile *pu64, uint64_t u64);
+#else
+DECLINLINE(void) ASMAtomicUoAndU64(uint64_t volatile *pu64, uint64_t u64)
+{
+# if RT_INLINE_ASM_GNU_STYLE && defined(RT_ARCH_AMD64)
+    __asm__ __volatile__("andq %1, %0\n\t"
+                         : "=m" (*pu64)
+                         : "r" (u64),
+                           "m" (*pu64));
+# else
+    for (;;)
+    {
+        uint64_t u64Old = ASMAtomicUoReadU64(pu64);
+        uint64_t u64New = u64Old & u64;
+        if (ASMAtomicCmpXchgU64(pu64, u64New, u64Old))
+            break;
+        ASMNopPause();
+    }
+# endif
+}
+#endif
+
+
+/**
+ * Atomically And a signed 64-bit value, unordered.
+ *
+ * @param   pi64   Pointer to the pointer variable to AND i64 with.
+ * @param   i64    The value to AND *pi64 with.
+ */
+DECLINLINE(void) ASMAtomicUoAndS64(int64_t volatile *pi64, int64_t i64)
+{
+    ASMAtomicUoAndU64((uint64_t volatile *)pi64, (uint64_t)i64);
+}
+
+
+/**
+ * Atomically increment an unsigned 32-bit value, unordered.
+ *
+ * @returns the new value.
+ * @param   pu32   Pointer to the variable to increment.
+ */
+#if RT_INLINE_ASM_EXTERNAL
+DECLASM(uint32_t) ASMAtomicUoIncU32(uint32_t volatile *pu32);
+#else
+DECLINLINE(uint32_t) ASMAtomicUoIncU32(uint32_t volatile *pu32)
+{
+    uint32_t u32;
+# if RT_INLINE_ASM_GNU_STYLE
+    __asm__ __volatile__("xaddl %0, %1\n\t"
+                         : "=r" (u32),
+                           "=m" (*pu32)
+                         : "0" (1),
+                           "m" (*pu32)
+                         : "memory");
+    return u32 + 1;
+# else
+    __asm
+    {
+        mov     eax, 1
+#  ifdef RT_ARCH_AMD64
+        mov     rdx, [pu32]
+        xadd    [rdx], eax
+#  else
+        mov     edx, [pu32]
+        xadd    [edx], eax
+#  endif
+        mov     u32, eax
+    }
+    return u32 + 1;
+# endif
+}
+#endif
+
+
+/**
+ * Atomically decrement an unsigned 32-bit value, unordered.
+ *
+ * @returns the new value.
+ * @param   pu32   Pointer to the variable to decrement.
+ */
+#if RT_INLINE_ASM_EXTERNAL
+DECLASM(uint32_t) ASMAtomicUoDecU32(uint32_t volatile *pu32);
+#else
+DECLINLINE(uint32_t) ASMAtomicUoDecU32(uint32_t volatile *pu32)
+{
+    uint32_t u32;
+# if RT_INLINE_ASM_GNU_STYLE
+    __asm__ __volatile__("lock; xaddl %0, %1\n\t"
+                         : "=r" (u32),
+                           "=m" (*pu32)
+                         : "0" (-1),
+                           "m" (*pu32)
+                         : "memory");
+    return u32 - 1;
+# else
+    __asm
+    {
+        mov     eax, -1
+#  ifdef RT_ARCH_AMD64
+        mov     rdx, [pu32]
+        xadd    [rdx], eax
+#  else
+        mov     edx, [pu32]
+        xadd    [edx], eax
+#  endif
+        mov     u32, eax
+    }
+    return u32 - 1;
+# endif
+}
+#endif
+
+
+/** @def RT_ASM_PAGE_SIZE
+ * We try avoid dragging in iprt/param.h here.
+ * @internal
+ */
+#if defined(RT_ARCH_SPARC64)
+# define RT_ASM_PAGE_SIZE   0x2000
+# if defined(PAGE_SIZE) && !defined(NT_INCLUDED)
+#  if PAGE_SIZE != 0x2000
+#   error "PAGE_SIZE is not 0x2000!"
+#  endif
+# endif
+#else
+# define RT_ASM_PAGE_SIZE   0x1000
+# if defined(PAGE_SIZE) && !defined(NT_INCLUDED)
+#  if PAGE_SIZE != 0x1000
+#   error "PAGE_SIZE is not 0x1000!"
+#  endif
+# endif
+#endif
+
+/**
+ * Zeros a 4K memory page.
+ *
+ * @param   pv  Pointer to the memory block. This must be page aligned.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(void) ASMMemZeroPage(volatile void *pv);
+# else
+DECLINLINE(void) ASMMemZeroPage(volatile void *pv)
+{
+#  if RT_INLINE_ASM_USES_INTRIN
+#   ifdef RT_ARCH_AMD64
+    __stosq((unsigned __int64 *)pv, 0, RT_ASM_PAGE_SIZE / 8);
+#   else
+    __stosd((unsigned long *)pv, 0, RT_ASM_PAGE_SIZE / 4);
+#   endif
+
+#  elif RT_INLINE_ASM_GNU_STYLE
+    RTCCUINTREG uDummy;
+#   ifdef RT_ARCH_AMD64
+    __asm__ __volatile__("rep stosq"
+                         : "=D" (pv),
+                           "=c" (uDummy)
+                         : "0" (pv),
+                           "c" (RT_ASM_PAGE_SIZE >> 3),
+                           "a" (0)
+                         : "memory");
+#   else
+    __asm__ __volatile__("rep stosl"
+                         : "=D" (pv),
+                           "=c" (uDummy)
+                         : "0" (pv),
+                           "c" (RT_ASM_PAGE_SIZE >> 2),
+                           "a" (0)
+                         : "memory");
+#   endif
+#  else
+    __asm
+    {
+#   ifdef RT_ARCH_AMD64
+        xor     rax, rax
+        mov     ecx, 0200h
+        mov     rdi, [pv]
+        rep     stosq
+#   else
+        xor     eax, eax
+        mov     ecx, 0400h
+        mov     edi, [pv]
+        rep     stosd
+#   endif
+    }
+#  endif
+}
+# endif
+
+
+/**
+ * Zeros a memory block with a 32-bit aligned size.
+ *
+ * @param   pv  Pointer to the memory block.
+ * @param   cb  Number of bytes in the block. This MUST be aligned on 32-bit!
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(void) ASMMemZero32(volatile void *pv, size_t cb);
+#else
+DECLINLINE(void) ASMMemZero32(volatile void *pv, size_t cb)
+{
+# if RT_INLINE_ASM_USES_INTRIN
+#  ifdef RT_ARCH_AMD64
+    if (!(cb & 7))
+        __stosq((unsigned __int64 *)pv, 0, cb / 8);
+    else
+#  endif
+        __stosd((unsigned long *)pv, 0, cb / 4);
+
+# elif RT_INLINE_ASM_GNU_STYLE
+    __asm__ __volatile__("rep stosl"
+                         : "=D" (pv),
+                           "=c" (cb)
+                         : "0" (pv),
+                           "1" (cb >> 2),
+                           "a" (0)
+                         : "memory");
+# else
+    __asm
+    {
+        xor     eax, eax
+#  ifdef RT_ARCH_AMD64
+        mov     rcx, [cb]
+        shr     rcx, 2
+        mov     rdi, [pv]
+#  else
+        mov     ecx, [cb]
+        shr     ecx, 2
+        mov     edi, [pv]
+#  endif
+        rep stosd
+    }
+# endif
+}
+#endif
+
+
+/**
+ * Fills a memory block with a 32-bit aligned size.
+ *
+ * @param   pv  Pointer to the memory block.
+ * @param   cb  Number of bytes in the block. This MUST be aligned on 32-bit!
+ * @param   u32 The value to fill with.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(void) ASMMemFill32(volatile void *pv, size_t cb, uint32_t u32);
+#else
+DECLINLINE(void) ASMMemFill32(volatile void *pv, size_t cb, uint32_t u32)
+{
+# if RT_INLINE_ASM_USES_INTRIN
+#  ifdef RT_ARCH_AMD64
+    if (!(cb & 7))
+        __stosq((unsigned __int64 *)pv, RT_MAKE_U64(u32, u32), cb / 8);
+    else
+#  endif
+        __stosd((unsigned long *)pv, u32, cb / 4);
+
+# elif RT_INLINE_ASM_GNU_STYLE
+    __asm__ __volatile__("rep stosl"
+                         : "=D" (pv),
+                           "=c" (cb)
+                         : "0" (pv),
+                           "1" (cb >> 2),
+                           "a" (u32)
+                         : "memory");
+# else
+    __asm
+    {
+#  ifdef RT_ARCH_AMD64
+        mov     rcx, [cb]
+        shr     rcx, 2
+        mov     rdi, [pv]
+#  else
+        mov     ecx, [cb]
+        shr     ecx, 2
+        mov     edi, [pv]
+#  endif
+        mov     eax, [u32]
+        rep stosd
+    }
+# endif
+}
+#endif
+
+
+/**
+ * Checks if a memory page is all zeros.
+ *
+ * @returns true / false.
+ *
+ * @param   pvPage      Pointer to the page.  Must be aligned on 16 byte
+ *                      boundary
+ */
+DECLINLINE(bool) ASMMemIsZeroPage(void const *pvPage)
+{
+# if 0 /*RT_INLINE_ASM_GNU_STYLE - this is actually slower... */
+    union { RTCCUINTREG r; bool f; } uAX;
+    RTCCUINTREG xCX, xDI;
+   Assert(!((uintptr_t)pvPage & 15));
+    __asm__ __volatile__("repe; "
+#  ifdef RT_ARCH_AMD64
+                         "scasq\n\t"
+#  else
+                         "scasl\n\t"
+#  endif
+                         "setnc %%al\n\t"
+                         : "=&c" (xCX),
+                           "=&D" (xDI),
+                           "=&a" (uAX.r)
+                         : "mr" (pvPage),
+#  ifdef RT_ARCH_AMD64
+                         "0" (RT_ASM_PAGE_SIZE/8),
+#  else
+                         "0" (RT_ASM_PAGE_SIZE/4),
+#  endif
+                         "1" (pvPage),
+                         "2" (0));
+    return uAX.f;
+# else
+   uintptr_t const *puPtr = (uintptr_t const *)pvPage;
+   int              cLeft = RT_ASM_PAGE_SIZE / sizeof(uintptr_t) / 8;
+   Assert(!((uintptr_t)pvPage & 15));
+   for (;;)
+   {
+       if (puPtr[0])        return false;
+       if (puPtr[4])        return false;
+
+       if (puPtr[2])        return false;
+       if (puPtr[6])        return false;
+
+       if (puPtr[1])        return false;
+       if (puPtr[5])        return false;
+
+       if (puPtr[3])        return false;
+       if (puPtr[7])        return false;
+
+       if (!--cLeft)
+           return true;
+       puPtr += 8;
+   }
+   return true;
+# endif
+}
+
+
+/**
+ * Checks if a memory block is filled with the specified byte.
+ *
+ * This is a sort of inverted memchr.
+ *
+ * @returns Pointer to the byte which doesn't equal u8.
+ * @returns NULL if all equal to u8.
+ *
+ * @param   pv      Pointer to the memory block.
+ * @param   cb      Number of bytes in the block. This MUST be aligned on 32-bit!
+ * @param   u8      The value it's supposed to be filled with.
+ *
+ * @todo Fix name, it is a predicate function but it's not returning boolean!
+ */
+DECLINLINE(void *) ASMMemIsAll8(void const *pv, size_t cb, uint8_t u8)
+{
+/** @todo rewrite this in inline assembly? */
+    uint8_t const *pb = (uint8_t const *)pv;
+    for (; cb; cb--, pb++)
+        if (RT_LIKELY(*pb == u8))
+        { /* likely */ }
+        else
+            return (void *)pb;
+    return NULL;
+}
+
+
+/**
+ * Checks if a memory block is filled with the specified 32-bit value.
+ *
+ * This is a sort of inverted memchr.
+ *
+ * @returns Pointer to the first value which doesn't equal u32.
+ * @returns NULL if all equal to u32.
+ *
+ * @param   pv      Pointer to the memory block.
+ * @param   cb      Number of bytes in the block. This MUST be aligned on 32-bit!
+ * @param   u32     The value it's supposed to be filled with.
+ *
+ * @todo Fix name, it is a predicate function but it's not returning boolean!
+ */
+DECLINLINE(uint32_t *) ASMMemIsAllU32(void const *pv, size_t cb, uint32_t u32)
+{
+/** @todo rewrite this in inline assembly? */
+    uint32_t const *pu32 = (uint32_t const *)pv;
+    for (; cb; cb -= 4, pu32++)
+        if (RT_LIKELY(*pu32 == u32))
+        { /* likely */ }
+        else
+            return (uint32_t *)pu32;
+    return NULL;
+}
+
+
+/**
+ * Probes a byte pointer for read access.
+ *
+ * While the function will not fault if the byte is not read accessible,
+ * the idea is to do this in a safe place like before acquiring locks
+ * and such like.
+ *
+ * Also, this functions guarantees that an eager compiler is not going
+ * to optimize the probing away.
+ *
+ * @param   pvByte      Pointer to the byte.
+ */
+#if RT_INLINE_ASM_EXTERNAL
+DECLASM(uint8_t) ASMProbeReadByte(const void *pvByte);
+#else
+DECLINLINE(uint8_t) ASMProbeReadByte(const void *pvByte)
+{
+    /** @todo verify that the compiler actually doesn't optimize this away. (intel & gcc) */
+    uint8_t u8;
+# if RT_INLINE_ASM_GNU_STYLE
+    __asm__ __volatile__("movb (%1), %0\n\t"
+                         : "=r" (u8)
+                         : "r" (pvByte));
+# else
+    __asm
+    {
+#  ifdef RT_ARCH_AMD64
+        mov     rax, [pvByte]
+        mov     al, [rax]
+#  else
+        mov     eax, [pvByte]
+        mov     al, [eax]
+#  endif
+        mov     [u8], al
+    }
+# endif
+    return u8;
+}
+#endif
+
+/**
+ * Probes a buffer for read access page by page.
+ *
+ * While the function will fault if the buffer is not fully read
+ * accessible, the idea is to do this in a safe place like before
+ * acquiring locks and such like.
+ *
+ * Also, this functions guarantees that an eager compiler is not going
+ * to optimize the probing away.
+ *
+ * @param   pvBuf       Pointer to the buffer.
+ * @param   cbBuf       The size of the buffer in bytes. Must be >= 1.
+ */
+DECLINLINE(void) ASMProbeReadBuffer(const void *pvBuf, size_t cbBuf)
+{
+    /** @todo verify that the compiler actually doesn't optimize this away. (intel & gcc) */
+    /* the first byte */
+    const uint8_t *pu8 = (const uint8_t *)pvBuf;
+    ASMProbeReadByte(pu8);
+
+    /* the pages in between pages. */
+    while (cbBuf > RT_ASM_PAGE_SIZE)
+    {
+        ASMProbeReadByte(pu8);
+        cbBuf -= RT_ASM_PAGE_SIZE;
+        pu8   += RT_ASM_PAGE_SIZE;
+    }
+
+    /* the last byte */
+    ASMProbeReadByte(pu8 + cbBuf - 1);
+}
+
+
+
+/** @defgroup grp_inline_bits   Bit Operations
+ * @{
+ */
+
+
+/**
+ * Sets a bit in a bitmap.
+ *
+ * @param   pvBitmap    Pointer to the bitmap. This should be 32-bit aligned.
+ * @param   iBit        The bit to set.
+ *
+ * @remarks The 32-bit aligning of pvBitmap is not a strict requirement.
+ *          However, doing so will yield better performance as well as avoiding
+ *          traps accessing the last bits in the bitmap.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(void) ASMBitSet(volatile void *pvBitmap, int32_t iBit);
+#else
+DECLINLINE(void) ASMBitSet(volatile void *pvBitmap, int32_t iBit)
+{
+# if RT_INLINE_ASM_USES_INTRIN
+    _bittestandset((long *)pvBitmap, iBit);
+
+# elif RT_INLINE_ASM_GNU_STYLE
+    __asm__ __volatile__("btsl %1, %0"
+                         : "=m" (*(volatile long *)pvBitmap)
+                         : "Ir" (iBit),
+                           "m" (*(volatile long *)pvBitmap)
+                         : "memory");
+# else
+    __asm
+    {
+#  ifdef RT_ARCH_AMD64
+        mov     rax, [pvBitmap]
+        mov     edx, [iBit]
+        bts     [rax], edx
+#  else
+        mov     eax, [pvBitmap]
+        mov     edx, [iBit]
+        bts     [eax], edx
+#  endif
+    }
+# endif
+}
+#endif
+
+
+/**
+ * Atomically sets a bit in a bitmap, ordered.
+ *
+ * @param   pvBitmap    Pointer to the bitmap. Must be 32-bit aligned, otherwise
+ *                      the memory access isn't atomic!
+ * @param   iBit        The bit to set.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(void) ASMAtomicBitSet(volatile void *pvBitmap, int32_t iBit);
+#else
+DECLINLINE(void) ASMAtomicBitSet(volatile void *pvBitmap, int32_t iBit)
+{
+    AssertMsg(!((uintptr_t)pvBitmap & 3), ("address %p not 32-bit aligned", pvBitmap));
+# if RT_INLINE_ASM_USES_INTRIN
+    _interlockedbittestandset((long *)pvBitmap, iBit);
+# elif RT_INLINE_ASM_GNU_STYLE
+    __asm__ __volatile__("lock; btsl %1, %0"
+                         : "=m" (*(volatile long *)pvBitmap)
+                         : "Ir" (iBit),
+                           "m" (*(volatile long *)pvBitmap)
+                         : "memory");
+# else
+    __asm
+    {
+#  ifdef RT_ARCH_AMD64
+        mov     rax, [pvBitmap]
+        mov     edx, [iBit]
+        lock bts [rax], edx
+#  else
+        mov     eax, [pvBitmap]
+        mov     edx, [iBit]
+        lock bts [eax], edx
+#  endif
+    }
+# endif
+}
+#endif
+
+
+/**
+ * Clears a bit in a bitmap.
+ *
+ * @param   pvBitmap    Pointer to the bitmap.
+ * @param   iBit        The bit to clear.
+ *
+ * @remarks The 32-bit aligning of pvBitmap is not a strict requirement.
+ *          However, doing so will yield better performance as well as avoiding
+ *          traps accessing the last bits in the bitmap.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(void) ASMBitClear(volatile void *pvBitmap, int32_t iBit);
+#else
+DECLINLINE(void) ASMBitClear(volatile void *pvBitmap, int32_t iBit)
+{
+# if RT_INLINE_ASM_USES_INTRIN
+    _bittestandreset((long *)pvBitmap, iBit);
+
+# elif RT_INLINE_ASM_GNU_STYLE
+    __asm__ __volatile__("btrl %1, %0"
+                         : "=m" (*(volatile long *)pvBitmap)
+                         : "Ir" (iBit),
+                           "m" (*(volatile long *)pvBitmap)
+                         : "memory");
+# else
+    __asm
+    {
+#  ifdef RT_ARCH_AMD64
+        mov     rax, [pvBitmap]
+        mov     edx, [iBit]
+        btr     [rax], edx
+#  else
+        mov     eax, [pvBitmap]
+        mov     edx, [iBit]
+        btr     [eax], edx
+#  endif
+    }
+# endif
+}
+#endif
+
+
+/**
+ * Atomically clears a bit in a bitmap, ordered.
+ *
+ * @param   pvBitmap    Pointer to the bitmap. Must be 32-bit aligned, otherwise
+ *                      the memory access isn't atomic!
+ * @param   iBit        The bit to toggle set.
+ * @remarks No memory barrier, take care on smp.
+ */
+#if RT_INLINE_ASM_EXTERNAL
+DECLASM(void) ASMAtomicBitClear(volatile void *pvBitmap, int32_t iBit);
+#else
+DECLINLINE(void) ASMAtomicBitClear(volatile void *pvBitmap, int32_t iBit)
+{
+    AssertMsg(!((uintptr_t)pvBitmap & 3), ("address %p not 32-bit aligned", pvBitmap));
+# if RT_INLINE_ASM_GNU_STYLE
+    __asm__ __volatile__("lock; btrl %1, %0"
+                         : "=m" (*(volatile long *)pvBitmap)
+                         : "Ir" (iBit),
+                           "m" (*(volatile long *)pvBitmap)
+                         : "memory");
+# else
+    __asm
+    {
+#  ifdef RT_ARCH_AMD64
+        mov     rax, [pvBitmap]
+        mov     edx, [iBit]
+        lock btr [rax], edx
+#  else
+        mov     eax, [pvBitmap]
+        mov     edx, [iBit]
+        lock btr [eax], edx
+#  endif
+    }
+# endif
+}
+#endif
+
+
+/**
+ * Toggles a bit in a bitmap.
+ *
+ * @param   pvBitmap    Pointer to the bitmap.
+ * @param   iBit        The bit to toggle.
+ *
+ * @remarks The 32-bit aligning of pvBitmap is not a strict requirement.
+ *          However, doing so will yield better performance as well as avoiding
+ *          traps accessing the last bits in the bitmap.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(void) ASMBitToggle(volatile void *pvBitmap, int32_t iBit);
+#else
+DECLINLINE(void) ASMBitToggle(volatile void *pvBitmap, int32_t iBit)
+{
+# if RT_INLINE_ASM_USES_INTRIN
+    _bittestandcomplement((long *)pvBitmap, iBit);
+# elif RT_INLINE_ASM_GNU_STYLE
+    __asm__ __volatile__("btcl %1, %0"
+                         : "=m" (*(volatile long *)pvBitmap)
+                         : "Ir" (iBit),
+                           "m" (*(volatile long *)pvBitmap)
+                         : "memory");
+# else
+    __asm
+    {
+#  ifdef RT_ARCH_AMD64
+        mov     rax, [pvBitmap]
+        mov     edx, [iBit]
+        btc     [rax], edx
+#  else
+        mov     eax, [pvBitmap]
+        mov     edx, [iBit]
+        btc     [eax], edx
+#  endif
+    }
+# endif
+}
+#endif
+
+
+/**
+ * Atomically toggles a bit in a bitmap, ordered.
+ *
+ * @param   pvBitmap    Pointer to the bitmap. Must be 32-bit aligned, otherwise
+ *                      the memory access isn't atomic!
+ * @param   iBit        The bit to test and set.
+ */
+#if RT_INLINE_ASM_EXTERNAL
+DECLASM(void) ASMAtomicBitToggle(volatile void *pvBitmap, int32_t iBit);
+#else
+DECLINLINE(void) ASMAtomicBitToggle(volatile void *pvBitmap, int32_t iBit)
+{
+    AssertMsg(!((uintptr_t)pvBitmap & 3), ("address %p not 32-bit aligned", pvBitmap));
+# if RT_INLINE_ASM_GNU_STYLE
+    __asm__ __volatile__("lock; btcl %1, %0"
+                         : "=m" (*(volatile long *)pvBitmap)
+                         : "Ir" (iBit),
+                           "m" (*(volatile long *)pvBitmap)
+                         : "memory");
+# else
+    __asm
+    {
+#  ifdef RT_ARCH_AMD64
+        mov     rax, [pvBitmap]
+        mov     edx, [iBit]
+        lock btc [rax], edx
+#  else
+        mov     eax, [pvBitmap]
+        mov     edx, [iBit]
+        lock btc [eax], edx
+#  endif
+    }
+# endif
+}
+#endif
+
+
+/**
+ * Tests and sets a bit in a bitmap.
+ *
+ * @returns true if the bit was set.
+ * @returns false if the bit was clear.
+ *
+ * @param   pvBitmap    Pointer to the bitmap.
+ * @param   iBit        The bit to test and set.
+ *
+ * @remarks The 32-bit aligning of pvBitmap is not a strict requirement.
+ *          However, doing so will yield better performance as well as avoiding
+ *          traps accessing the last bits in the bitmap.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(bool) ASMBitTestAndSet(volatile void *pvBitmap, int32_t iBit);
+#else
+DECLINLINE(bool) ASMBitTestAndSet(volatile void *pvBitmap, int32_t iBit)
+{
+    union { bool f; uint32_t u32; uint8_t u8; } rc;
+# if RT_INLINE_ASM_USES_INTRIN
+    rc.u8 = _bittestandset((long *)pvBitmap, iBit);
+
+# elif RT_INLINE_ASM_GNU_STYLE
+    __asm__ __volatile__("btsl %2, %1\n\t"
+                         "setc %b0\n\t"
+                         "andl $1, %0\n\t"
+                         : "=q" (rc.u32),
+                           "=m" (*(volatile long *)pvBitmap)
+                         : "Ir" (iBit),
+                           "m" (*(volatile long *)pvBitmap)
+                         : "memory");
+# else
+    __asm
+    {
+        mov     edx, [iBit]
+#  ifdef RT_ARCH_AMD64
+        mov     rax, [pvBitmap]
+        bts     [rax], edx
+#  else
+        mov     eax, [pvBitmap]
+        bts     [eax], edx
+#  endif
+        setc    al
+        and     eax, 1
+        mov     [rc.u32], eax
+    }
+# endif
+    return rc.f;
+}
+#endif
+
+
+/**
+ * Atomically tests and sets a bit in a bitmap, ordered.
+ *
+ * @returns true if the bit was set.
+ * @returns false if the bit was clear.
+ *
+ * @param   pvBitmap    Pointer to the bitmap. Must be 32-bit aligned, otherwise
+ *                      the memory access isn't atomic!
+ * @param   iBit        The bit to set.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(bool) ASMAtomicBitTestAndSet(volatile void *pvBitmap, int32_t iBit);
+#else
+DECLINLINE(bool) ASMAtomicBitTestAndSet(volatile void *pvBitmap, int32_t iBit)
+{
+    union { bool f; uint32_t u32; uint8_t u8; } rc;
+    AssertMsg(!((uintptr_t)pvBitmap & 3), ("address %p not 32-bit aligned", pvBitmap));
+# if RT_INLINE_ASM_USES_INTRIN
+    rc.u8 = _interlockedbittestandset((long *)pvBitmap, iBit);
+# elif RT_INLINE_ASM_GNU_STYLE
+    __asm__ __volatile__("lock; btsl %2, %1\n\t"
+                         "setc %b0\n\t"
+                         "andl $1, %0\n\t"
+                         : "=q" (rc.u32),
+                           "=m" (*(volatile long *)pvBitmap)
+                         : "Ir" (iBit),
+                           "m" (*(volatile long *)pvBitmap)
+                         : "memory");
+# else
+    __asm
+    {
+        mov     edx, [iBit]
+#  ifdef RT_ARCH_AMD64
+        mov     rax, [pvBitmap]
+        lock bts [rax], edx
+#  else
+        mov     eax, [pvBitmap]
+        lock bts [eax], edx
+#  endif
+        setc    al
+        and     eax, 1
+        mov     [rc.u32], eax
+    }
+# endif
+    return rc.f;
+}
+#endif
+
+
+/**
+ * Tests and clears a bit in a bitmap.
+ *
+ * @returns true if the bit was set.
+ * @returns false if the bit was clear.
+ *
+ * @param   pvBitmap    Pointer to the bitmap.
+ * @param   iBit        The bit to test and clear.
+ *
+ * @remarks The 32-bit aligning of pvBitmap is not a strict requirement.
+ *          However, doing so will yield better performance as well as avoiding
+ *          traps accessing the last bits in the bitmap.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(bool) ASMBitTestAndClear(volatile void *pvBitmap, int32_t iBit);
+#else
+DECLINLINE(bool) ASMBitTestAndClear(volatile void *pvBitmap, int32_t iBit)
+{
+    union { bool f; uint32_t u32; uint8_t u8; } rc;
+# if RT_INLINE_ASM_USES_INTRIN
+    rc.u8 = _bittestandreset((long *)pvBitmap, iBit);
+
+# elif RT_INLINE_ASM_GNU_STYLE
+    __asm__ __volatile__("btrl %2, %1\n\t"
+                         "setc %b0\n\t"
+                         "andl $1, %0\n\t"
+                         : "=q" (rc.u32),
+                           "=m" (*(volatile long *)pvBitmap)
+                         : "Ir" (iBit),
+                           "m" (*(volatile long *)pvBitmap)
+                         : "memory");
+# else
+    __asm
+    {
+        mov     edx, [iBit]
+#  ifdef RT_ARCH_AMD64
+        mov     rax, [pvBitmap]
+        btr     [rax], edx
+#  else
+        mov     eax, [pvBitmap]
+        btr     [eax], edx
+#  endif
+        setc    al
+        and     eax, 1
+        mov     [rc.u32], eax
+    }
+# endif
+    return rc.f;
+}
+#endif
+
+
+/**
+ * Atomically tests and clears a bit in a bitmap, ordered.
+ *
+ * @returns true if the bit was set.
+ * @returns false if the bit was clear.
+ *
+ * @param   pvBitmap    Pointer to the bitmap. Must be 32-bit aligned, otherwise
+ *                      the memory access isn't atomic!
+ * @param   iBit        The bit to test and clear.
+ *
+ * @remarks No memory barrier, take care on smp.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(bool) ASMAtomicBitTestAndClear(volatile void *pvBitmap, int32_t iBit);
+#else
+DECLINLINE(bool) ASMAtomicBitTestAndClear(volatile void *pvBitmap, int32_t iBit)
+{
+    union { bool f; uint32_t u32; uint8_t u8; } rc;
+    AssertMsg(!((uintptr_t)pvBitmap & 3), ("address %p not 32-bit aligned", pvBitmap));
+# if RT_INLINE_ASM_USES_INTRIN
+    rc.u8 = _interlockedbittestandreset((long *)pvBitmap, iBit);
+
+# elif RT_INLINE_ASM_GNU_STYLE
+    __asm__ __volatile__("lock; btrl %2, %1\n\t"
+                         "setc %b0\n\t"
+                         "andl $1, %0\n\t"
+                         : "=q" (rc.u32),
+                           "=m" (*(volatile long *)pvBitmap)
+                         : "Ir" (iBit),
+                           "m" (*(volatile long *)pvBitmap)
+                         : "memory");
+# else
+    __asm
+    {
+        mov     edx, [iBit]
+#  ifdef RT_ARCH_AMD64
+        mov     rax, [pvBitmap]
+        lock btr [rax], edx
+#  else
+        mov     eax, [pvBitmap]
+        lock btr [eax], edx
+#  endif
+        setc    al
+        and     eax, 1
+        mov     [rc.u32], eax
+    }
+# endif
+    return rc.f;
+}
+#endif
+
+
+/**
+ * Tests and toggles a bit in a bitmap.
+ *
+ * @returns true if the bit was set.
+ * @returns false if the bit was clear.
+ *
+ * @param   pvBitmap    Pointer to the bitmap.
+ * @param   iBit        The bit to test and toggle.
+ *
+ * @remarks The 32-bit aligning of pvBitmap is not a strict requirement.
+ *          However, doing so will yield better performance as well as avoiding
+ *          traps accessing the last bits in the bitmap.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(bool) ASMBitTestAndToggle(volatile void *pvBitmap, int32_t iBit);
+#else
+DECLINLINE(bool) ASMBitTestAndToggle(volatile void *pvBitmap, int32_t iBit)
+{
+    union { bool f; uint32_t u32; uint8_t u8; } rc;
+# if RT_INLINE_ASM_USES_INTRIN
+    rc.u8 = _bittestandcomplement((long *)pvBitmap, iBit);
+
+# elif RT_INLINE_ASM_GNU_STYLE
+    __asm__ __volatile__("btcl %2, %1\n\t"
+                         "setc %b0\n\t"
+                         "andl $1, %0\n\t"
+                         : "=q" (rc.u32),
+                           "=m" (*(volatile long *)pvBitmap)
+                         : "Ir" (iBit),
+                           "m" (*(volatile long *)pvBitmap)
+                         : "memory");
+# else
+    __asm
+    {
+        mov   edx, [iBit]
+#  ifdef RT_ARCH_AMD64
+        mov   rax, [pvBitmap]
+        btc   [rax], edx
+#  else
+        mov   eax, [pvBitmap]
+        btc   [eax], edx
+#  endif
+        setc  al
+        and   eax, 1
+        mov   [rc.u32], eax
+    }
+# endif
+    return rc.f;
+}
+#endif
+
+
+/**
+ * Atomically tests and toggles a bit in a bitmap, ordered.
+ *
+ * @returns true if the bit was set.
+ * @returns false if the bit was clear.
+ *
+ * @param   pvBitmap    Pointer to the bitmap. Must be 32-bit aligned, otherwise
+ *                      the memory access isn't atomic!
+ * @param   iBit        The bit to test and toggle.
+ */
+#if RT_INLINE_ASM_EXTERNAL
+DECLASM(bool) ASMAtomicBitTestAndToggle(volatile void *pvBitmap, int32_t iBit);
+#else
+DECLINLINE(bool) ASMAtomicBitTestAndToggle(volatile void *pvBitmap, int32_t iBit)
+{
+    union { bool f; uint32_t u32; uint8_t u8; } rc;
+    AssertMsg(!((uintptr_t)pvBitmap & 3), ("address %p not 32-bit aligned", pvBitmap));
+# if RT_INLINE_ASM_GNU_STYLE
+    __asm__ __volatile__("lock; btcl %2, %1\n\t"
+                         "setc %b0\n\t"
+                         "andl $1, %0\n\t"
+                         : "=q" (rc.u32),
+                           "=m" (*(volatile long *)pvBitmap)
+                         : "Ir" (iBit),
+                           "m" (*(volatile long *)pvBitmap)
+                         : "memory");
+# else
+    __asm
+    {
+        mov     edx, [iBit]
+#  ifdef RT_ARCH_AMD64
+        mov     rax, [pvBitmap]
+        lock btc [rax], edx
+#  else
+        mov     eax, [pvBitmap]
+        lock btc [eax], edx
+#  endif
+        setc    al
+        and     eax, 1
+        mov     [rc.u32], eax
+    }
+# endif
+    return rc.f;
+}
+#endif
+
+
+/**
+ * Tests if a bit in a bitmap is set.
+ *
+ * @returns true if the bit is set.
+ * @returns false if the bit is clear.
+ *
+ * @param   pvBitmap    Pointer to the bitmap.
+ * @param   iBit        The bit to test.
+ *
+ * @remarks The 32-bit aligning of pvBitmap is not a strict requirement.
+ *          However, doing so will yield better performance as well as avoiding
+ *          traps accessing the last bits in the bitmap.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(bool) ASMBitTest(const volatile void *pvBitmap, int32_t iBit);
+#else
+DECLINLINE(bool) ASMBitTest(const volatile void *pvBitmap, int32_t iBit)
+{
+    union { bool f; uint32_t u32; uint8_t u8; } rc;
+# if RT_INLINE_ASM_USES_INTRIN
+    rc.u32 = _bittest((long *)pvBitmap, iBit);
+# elif RT_INLINE_ASM_GNU_STYLE
+
+    __asm__ __volatile__("btl %2, %1\n\t"
+                         "setc %b0\n\t"
+                         "andl $1, %0\n\t"
+                         : "=q" (rc.u32)
+                         : "m" (*(const volatile long *)pvBitmap),
+                           "Ir" (iBit)
+                         : "memory");
+# else
+    __asm
+    {
+        mov   edx, [iBit]
+#  ifdef RT_ARCH_AMD64
+        mov   rax, [pvBitmap]
+        bt    [rax], edx
+#  else
+        mov   eax, [pvBitmap]
+        bt    [eax], edx
+#  endif
+        setc  al
+        and   eax, 1
+        mov   [rc.u32], eax
+    }
+# endif
+    return rc.f;
+}
+#endif
+
+
+/**
+ * Clears a bit range within a bitmap.
+ *
+ * @param   pvBitmap    Pointer to the bitmap.
+ * @param   iBitStart   The First bit to clear.
+ * @param   iBitEnd     The first bit not to clear.
+ */
+DECLINLINE(void) ASMBitClearRange(volatile void *pvBitmap, int32_t iBitStart, int32_t iBitEnd)
+{
+    if (iBitStart < iBitEnd)
+    {
+        volatile uint32_t *pu32 = (volatile uint32_t *)pvBitmap + (iBitStart >> 5);
+        int iStart = iBitStart & ~31;
+        int iEnd   = iBitEnd & ~31;
+        if (iStart == iEnd)
+            *pu32 &= ((1U << (iBitStart & 31)) - 1) | ~((1U << (iBitEnd & 31)) - 1);
+        else
+        {
+            /* bits in first dword. */
+            if (iBitStart & 31)
+            {
+                *pu32 &= (1U << (iBitStart & 31)) - 1;
+                pu32++;
+                iBitStart = iStart + 32;
+            }
+
+            /* whole dword. */
+            if (iBitStart != iEnd)
+                ASMMemZero32(pu32, (iEnd - iBitStart) >> 3);
+
+            /* bits in last dword. */
+            if (iBitEnd & 31)
+            {
+                pu32 = (volatile uint32_t *)pvBitmap + (iBitEnd >> 5);
+                *pu32 &= ~((1U << (iBitEnd & 31)) - 1);
+            }
+        }
+    }
+}
+
+
+/**
+ * Sets a bit range within a bitmap.
+ *
+ * @param   pvBitmap    Pointer to the bitmap.
+ * @param   iBitStart   The First bit to set.
+ * @param   iBitEnd     The first bit not to set.
+ */
+DECLINLINE(void) ASMBitSetRange(volatile void *pvBitmap, int32_t iBitStart, int32_t iBitEnd)
+{
+    if (iBitStart < iBitEnd)
+    {
+        volatile uint32_t *pu32 = (volatile uint32_t *)pvBitmap + (iBitStart >> 5);
+        int iStart = iBitStart & ~31;
+        int iEnd   = iBitEnd & ~31;
+        if (iStart == iEnd)
+            *pu32 |= ((1U << (iBitEnd - iBitStart)) - 1) << (iBitStart & 31);
+        else
+        {
+            /* bits in first dword. */
+            if (iBitStart & 31)
+            {
+                *pu32 |= ~((1U << (iBitStart & 31)) - 1);
+                pu32++;
+                iBitStart = iStart + 32;
+            }
+
+            /* whole dword. */
+            if (iBitStart != iEnd)
+                ASMMemFill32(pu32, (iEnd - iBitStart) >> 3, ~UINT32_C(0));
+
+            /* bits in last dword. */
+            if (iBitEnd & 31)
+            {
+                pu32 = (volatile uint32_t *)pvBitmap + (iBitEnd >> 5);
+                *pu32 |= (1U << (iBitEnd & 31)) - 1;
+            }
+        }
+    }
+}
+
+
+/**
+ * Finds the first clear bit in a bitmap.
+ *
+ * @returns Index of the first zero bit.
+ * @returns -1 if no clear bit was found.
+ * @param   pvBitmap    Pointer to the bitmap.
+ * @param   cBits       The number of bits in the bitmap. Multiple of 32.
+ */
+#if RT_INLINE_ASM_EXTERNAL
+DECLASM(int) ASMBitFirstClear(const volatile void *pvBitmap, uint32_t cBits);
+#else
+DECLINLINE(int) ASMBitFirstClear(const volatile void *pvBitmap, uint32_t cBits)
+{
+    if (cBits)
+    {
+        int32_t iBit;
+# if RT_INLINE_ASM_GNU_STYLE
+        RTCCUINTREG uEAX, uECX, uEDI;
+        cBits = RT_ALIGN_32(cBits, 32);
+        __asm__ __volatile__("repe; scasl\n\t"
+                             "je    1f\n\t"
+#  ifdef RT_ARCH_AMD64
+                             "lea   -4(%%rdi), %%rdi\n\t"
+                             "xorl  (%%rdi), %%eax\n\t"
+                             "subq  %5, %%rdi\n\t"
+#  else
+                             "lea   -4(%%edi), %%edi\n\t"
+                             "xorl  (%%edi), %%eax\n\t"
+                             "subl  %5, %%edi\n\t"
+#  endif
+                             "shll  $3, %%edi\n\t"
+                             "bsfl  %%eax, %%edx\n\t"
+                             "addl  %%edi, %%edx\n\t"
+                             "1:\t\n"
+                             : "=d" (iBit),
+                               "=&c" (uECX),
+                               "=&D" (uEDI),
+                               "=&a" (uEAX)
+                             : "0" (0xffffffff),
+                               "mr" (pvBitmap),
+                               "1" (cBits >> 5),
+                               "2" (pvBitmap),
+                               "3" (0xffffffff));
+# else
+        cBits = RT_ALIGN_32(cBits, 32);
+        __asm
+        {
+#  ifdef RT_ARCH_AMD64
+            mov     rdi, [pvBitmap]
+            mov     rbx, rdi
+#  else
+            mov     edi, [pvBitmap]
+            mov     ebx, edi
+#  endif
+            mov     edx, 0ffffffffh
+            mov     eax, edx
+            mov     ecx, [cBits]
+            shr     ecx, 5
+            repe    scasd
+            je      done
+
+#  ifdef RT_ARCH_AMD64
+            lea     rdi, [rdi - 4]
+            xor     eax, [rdi]
+            sub     rdi, rbx
+#  else
+            lea     edi, [edi - 4]
+            xor     eax, [edi]
+            sub     edi, ebx
+#  endif
+            shl     edi, 3
+            bsf     edx, eax
+            add     edx, edi
+        done:
+            mov     [iBit], edx
+        }
+# endif
+        return iBit;
+    }
+    return -1;
+}
+#endif
+
+
+/**
+ * Finds the next clear bit in a bitmap.
+ *
+ * @returns Index of the first zero bit.
+ * @returns -1 if no clear bit was found.
+ * @param   pvBitmap    Pointer to the bitmap.
+ * @param   cBits       The number of bits in the bitmap. Multiple of 32.
+ * @param   iBitPrev    The bit returned from the last search.
+ *                      The search will start at iBitPrev + 1.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(int) ASMBitNextClear(const volatile void *pvBitmap, uint32_t cBits, uint32_t iBitPrev);
+#else
+DECLINLINE(int) ASMBitNextClear(const volatile void *pvBitmap, uint32_t cBits, uint32_t iBitPrev)
+{
+    const volatile uint32_t *pau32Bitmap = (const volatile uint32_t *)pvBitmap;
+    int                      iBit = ++iBitPrev & 31;
+    if (iBit)
+    {
+        /*
+         * Inspect the 32-bit word containing the unaligned bit.
+         */
+        uint32_t  u32 = ~pau32Bitmap[iBitPrev / 32] >> iBit;
+
+# if RT_INLINE_ASM_USES_INTRIN
+        unsigned long ulBit = 0;
+        if (_BitScanForward(&ulBit, u32))
+            return ulBit + iBitPrev;
+# else
+#  if RT_INLINE_ASM_GNU_STYLE
+        __asm__ __volatile__("bsf %1, %0\n\t"
+                             "jnz 1f\n\t"
+                             "movl $-1, %0\n\t"
+                             "1:\n\t"
+                             : "=r" (iBit)
+                             : "r" (u32));
+#  else
+        __asm
+        {
+            mov     edx, [u32]
+            bsf     eax, edx
+            jnz     done
+            mov     eax, 0ffffffffh
+        done:
+            mov     [iBit], eax
+        }
+#  endif
+        if (iBit >= 0)
+            return iBit + iBitPrev;
+# endif
+
+        /*
+         * Skip ahead and see if there is anything left to search.
+         */
+        iBitPrev |= 31;
+        iBitPrev++;
+        if (cBits <= (uint32_t)iBitPrev)
+            return -1;
+    }
+
+    /*
+     * 32-bit aligned search, let ASMBitFirstClear do the dirty work.
+     */
+    iBit = ASMBitFirstClear(&pau32Bitmap[iBitPrev / 32], cBits - iBitPrev);
+    if (iBit >= 0)
+        iBit += iBitPrev;
+    return iBit;
+}
+#endif
+
+
+/**
+ * Finds the first set bit in a bitmap.
+ *
+ * @returns Index of the first set bit.
+ * @returns -1 if no clear bit was found.
+ * @param   pvBitmap    Pointer to the bitmap.
+ * @param   cBits       The number of bits in the bitmap. Multiple of 32.
+ */
+#if RT_INLINE_ASM_EXTERNAL
+DECLASM(int) ASMBitFirstSet(const volatile void *pvBitmap, uint32_t cBits);
+#else
+DECLINLINE(int) ASMBitFirstSet(const volatile void *pvBitmap, uint32_t cBits)
+{
+    if (cBits)
+    {
+        int32_t iBit;
+# if RT_INLINE_ASM_GNU_STYLE
+        RTCCUINTREG uEAX, uECX, uEDI;
+        cBits = RT_ALIGN_32(cBits, 32);
+        __asm__ __volatile__("repe; scasl\n\t"
+                             "je    1f\n\t"
+#  ifdef RT_ARCH_AMD64
+                             "lea   -4(%%rdi), %%rdi\n\t"
+                             "movl  (%%rdi), %%eax\n\t"
+                             "subq  %5, %%rdi\n\t"
+#  else
+                             "lea   -4(%%edi), %%edi\n\t"
+                             "movl  (%%edi), %%eax\n\t"
+                             "subl  %5, %%edi\n\t"
+#  endif
+                             "shll  $3, %%edi\n\t"
+                             "bsfl  %%eax, %%edx\n\t"
+                             "addl  %%edi, %%edx\n\t"
+                             "1:\t\n"
+                             : "=d" (iBit),
+                               "=&c" (uECX),
+                               "=&D" (uEDI),
+                               "=&a" (uEAX)
+                             : "0" (0xffffffff),
+                               "mr" (pvBitmap),
+                               "1" (cBits >> 5),
+                               "2" (pvBitmap),
+                               "3" (0));
+# else
+        cBits = RT_ALIGN_32(cBits, 32);
+        __asm
+        {
+#  ifdef RT_ARCH_AMD64
+            mov     rdi, [pvBitmap]
+            mov     rbx, rdi
+#  else
+            mov     edi, [pvBitmap]
+            mov     ebx, edi
+#  endif
+            mov     edx, 0ffffffffh
+            xor     eax, eax
+            mov     ecx, [cBits]
+            shr     ecx, 5
+            repe    scasd
+            je      done
+#  ifdef RT_ARCH_AMD64
+            lea     rdi, [rdi - 4]
+            mov     eax, [rdi]
+            sub     rdi, rbx
+#  else
+            lea     edi, [edi - 4]
+            mov     eax, [edi]
+            sub     edi, ebx
+#  endif
+            shl     edi, 3
+            bsf     edx, eax
+            add     edx, edi
+        done:
+            mov   [iBit], edx
+        }
+# endif
+        return iBit;
+    }
+    return -1;
+}
+#endif
+
+
+/**
+ * Finds the next set bit in a bitmap.
+ *
+ * @returns Index of the next set bit.
+ * @returns -1 if no set bit was found.
+ * @param   pvBitmap    Pointer to the bitmap.
+ * @param   cBits       The number of bits in the bitmap. Multiple of 32.
+ * @param   iBitPrev    The bit returned from the last search.
+ *                      The search will start at iBitPrev + 1.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(int) ASMBitNextSet(const volatile void *pvBitmap, uint32_t cBits, uint32_t iBitPrev);
+#else
+DECLINLINE(int) ASMBitNextSet(const volatile void *pvBitmap, uint32_t cBits, uint32_t iBitPrev)
+{
+    const volatile uint32_t *pau32Bitmap = (const volatile uint32_t *)pvBitmap;
+    int                      iBit = ++iBitPrev & 31;
+    if (iBit)
+    {
+        /*
+         * Inspect the 32-bit word containing the unaligned bit.
+         */
+        uint32_t  u32 = pau32Bitmap[iBitPrev / 32] >> iBit;
+
+# if RT_INLINE_ASM_USES_INTRIN
+        unsigned long ulBit = 0;
+        if (_BitScanForward(&ulBit, u32))
+            return ulBit + iBitPrev;
+# else
+#  if RT_INLINE_ASM_GNU_STYLE
+        __asm__ __volatile__("bsf %1, %0\n\t"
+                             "jnz 1f\n\t"
+                             "movl $-1, %0\n\t"
+                             "1:\n\t"
+                             : "=r" (iBit)
+                             : "r" (u32));
+#  else
+        __asm
+        {
+            mov     edx, [u32]
+            bsf     eax, edx
+            jnz     done
+            mov     eax, 0ffffffffh
+        done:
+            mov     [iBit], eax
+        }
+#  endif
+        if (iBit >= 0)
+            return iBit + iBitPrev;
+# endif
+
+        /*
+         * Skip ahead and see if there is anything left to search.
+         */
+        iBitPrev |= 31;
+        iBitPrev++;
+        if (cBits <= (uint32_t)iBitPrev)
+            return -1;
+    }
+
+    /*
+     * 32-bit aligned search, let ASMBitFirstClear do the dirty work.
+     */
+    iBit = ASMBitFirstSet(&pau32Bitmap[iBitPrev / 32], cBits - iBitPrev);
+    if (iBit >= 0)
+        iBit += iBitPrev;
+    return iBit;
+}
+#endif
+
+
+/**
+ * Finds the first bit which is set in the given 32-bit integer.
+ * Bits are numbered from 1 (least significant) to 32.
+ *
+ * @returns index [1..32] of the first set bit.
+ * @returns 0 if all bits are cleared.
+ * @param   u32     Integer to search for set bits.
+ * @remark  Similar to ffs() in BSD.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(unsigned) ASMBitFirstSetU32(uint32_t u32);
+#else
+DECLINLINE(unsigned) ASMBitFirstSetU32(uint32_t u32)
+{
+# if RT_INLINE_ASM_USES_INTRIN
+    unsigned long iBit;
+    if (_BitScanForward(&iBit, u32))
+        iBit++;
+    else
+        iBit = 0;
+# elif RT_INLINE_ASM_GNU_STYLE
+    uint32_t iBit;
+    __asm__ __volatile__("bsf  %1, %0\n\t"
+                         "jnz  1f\n\t"
+                         "xorl %0, %0\n\t"
+                         "jmp  2f\n"
+                         "1:\n\t"
+                         "incl %0\n"
+                         "2:\n\t"
+                         : "=r" (iBit)
+                         : "rm" (u32));
+# else
+    uint32_t iBit;
+    _asm
+    {
+        bsf     eax, [u32]
+        jnz     found
+        xor     eax, eax
+        jmp     done
+    found:
+        inc     eax
+    done:
+        mov     [iBit], eax
+    }
+# endif
+    return iBit;
+}
+#endif
+
+
+/**
+ * Finds the first bit which is set in the given 32-bit integer.
+ * Bits are numbered from 1 (least significant) to 32.
+ *
+ * @returns index [1..32] of the first set bit.
+ * @returns 0 if all bits are cleared.
+ * @param   i32     Integer to search for set bits.
+ * @remark  Similar to ffs() in BSD.
+ */
+DECLINLINE(unsigned) ASMBitFirstSetS32(int32_t i32)
+{
+    return ASMBitFirstSetU32((uint32_t)i32);
+}
+
+
+/**
+ * Finds the last bit which is set in the given 32-bit integer.
+ * Bits are numbered from 1 (least significant) to 32.
+ *
+ * @returns index [1..32] of the last set bit.
+ * @returns 0 if all bits are cleared.
+ * @param   u32     Integer to search for set bits.
+ * @remark  Similar to fls() in BSD.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(unsigned) ASMBitLastSetU32(uint32_t u32);
+#else
+DECLINLINE(unsigned) ASMBitLastSetU32(uint32_t u32)
+{
+# if RT_INLINE_ASM_USES_INTRIN
+    unsigned long iBit;
+    if (_BitScanReverse(&iBit, u32))
+        iBit++;
+    else
+        iBit = 0;
+# elif RT_INLINE_ASM_GNU_STYLE
+    uint32_t iBit;
+    __asm__ __volatile__("bsrl %1, %0\n\t"
+                         "jnz   1f\n\t"
+                         "xorl %0, %0\n\t"
+                         "jmp  2f\n"
+                         "1:\n\t"
+                         "incl %0\n"
+                         "2:\n\t"
+                         : "=r" (iBit)
+                         : "rm" (u32));
+# else
+    uint32_t iBit;
+    _asm
+    {
+        bsr     eax, [u32]
+        jnz     found
+        xor     eax, eax
+        jmp     done
+    found:
+        inc     eax
+    done:
+        mov     [iBit], eax
+    }
+# endif
+    return iBit;
+}
+#endif
+
+
+/**
+ * Finds the last bit which is set in the given 32-bit integer.
+ * Bits are numbered from 1 (least significant) to 32.
+ *
+ * @returns index [1..32] of the last set bit.
+ * @returns 0 if all bits are cleared.
+ * @param   i32     Integer to search for set bits.
+ * @remark  Similar to fls() in BSD.
+ */
+DECLINLINE(unsigned) ASMBitLastSetS32(int32_t i32)
+{
+    return ASMBitLastSetU32((uint32_t)i32);
+}
+
+/**
+ * Reverse the byte order of the given 16-bit integer.
+ *
+ * @returns Revert
+ * @param   u16     16-bit integer value.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(uint16_t) ASMByteSwapU16(uint16_t u16);
+#else
+DECLINLINE(uint16_t) ASMByteSwapU16(uint16_t u16)
+{
+# if RT_INLINE_ASM_USES_INTRIN
+    u16 = _byteswap_ushort(u16);
+# elif RT_INLINE_ASM_GNU_STYLE
+    __asm__ ("rorw $8, %0" : "=r" (u16) : "0" (u16));
+# else
+    _asm
+    {
+        mov     ax, [u16]
+        ror     ax, 8
+        mov     [u16], ax
+    }
+# endif
+    return u16;
+}
+#endif
+
+
+/**
+ * Reverse the byte order of the given 32-bit integer.
+ *
+ * @returns Revert
+ * @param   u32     32-bit integer value.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(uint32_t) ASMByteSwapU32(uint32_t u32);
+#else
+DECLINLINE(uint32_t) ASMByteSwapU32(uint32_t u32)
+{
+# if RT_INLINE_ASM_USES_INTRIN
+    u32 = _byteswap_ulong(u32);
+# elif RT_INLINE_ASM_GNU_STYLE
+    __asm__ ("bswapl %0" : "=r" (u32) : "0" (u32));
+# else
+    _asm
+    {
+        mov     eax, [u32]
+        bswap   eax
+        mov     [u32], eax
+    }
+# endif
+    return u32;
+}
+#endif
+
+
+/**
+ * Reverse the byte order of the given 64-bit integer.
+ *
+ * @returns Revert
+ * @param   u64     64-bit integer value.
+ */
+DECLINLINE(uint64_t) ASMByteSwapU64(uint64_t u64)
+{
+#if defined(RT_ARCH_AMD64) && RT_INLINE_ASM_USES_INTRIN
+    u64 = _byteswap_uint64(u64);
+#else
+    u64 = (uint64_t)ASMByteSwapU32((uint32_t)u64) << 32
+        | (uint64_t)ASMByteSwapU32((uint32_t)(u64 >> 32));
+#endif
+    return u64;
+}
+
+
+/**
+ * Rotate 32-bit unsigned value to the left by @a cShift.
+ *
+ * @returns Rotated value.
+ * @param   u32                 The value to rotate.
+ * @param   cShift              How many bits to rotate by.
+ */
+DECLINLINE(uint32_t) ASMRotateLeftU32(uint32_t u32, uint32_t cShift)
+{
+#if RT_INLINE_ASM_USES_INTRIN
+    return _rotl(u32, cShift);
+#elif RT_INLINE_ASM_GNU_STYLE && (defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86))
+    __asm__ __volatile__("roll %b1, %0" : "=g" (u32) : "Ic" (cShift), "0" (u32));
+    return u32;
+#else
+    cShift &= 31;
+    return (u32 << cShift) | (u32 >> (32 - cShift));
+#endif
+}
+
+
+/**
+ * Rotate 32-bit unsigned value to the right by @a cShift.
+ *
+ * @returns Rotated value.
+ * @param   u32                 The value to rotate.
+ * @param   cShift              How many bits to rotate by.
+ */
+DECLINLINE(uint32_t) ASMRotateRightU32(uint32_t u32, uint32_t cShift)
+{
+#if RT_INLINE_ASM_USES_INTRIN
+    return _rotr(u32, cShift);
+#elif RT_INLINE_ASM_GNU_STYLE && (defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86))
+    __asm__ __volatile__("rorl %b1, %0" : "=g" (u32) : "Ic" (cShift), "0" (u32));
+    return u32;
+#else
+    cShift &= 31;
+    return (u32 >> cShift) | (u32 << (32 - cShift));
+#endif
+}
+
+
+/**
+ * Rotate 64-bit unsigned value to the left by @a cShift.
+ *
+ * @returns Rotated value.
+ * @param   u64                 The value to rotate.
+ * @param   cShift              How many bits to rotate by.
+ */
+DECLINLINE(uint64_t) ASMRotateLeftU64(uint64_t u64, uint32_t cShift)
+{
+#if RT_INLINE_ASM_USES_INTRIN
+    return _rotl64(u64, cShift);
+#elif RT_INLINE_ASM_GNU_STYLE && defined(RT_ARCH_AMD64)
+    __asm__ __volatile__("rolq %b1, %0" : "=g" (u64) : "Jc" (cShift), "0" (u64));
+    return u64;
+#elif RT_INLINE_ASM_GNU_STYLE && defined(RT_ARCH_X86)
+    uint32_t uSpill;
+    __asm__ __volatile__("testb $0x20, %%cl\n\t"        /* if (cShift >= 0x20) { swap(u64.hi, u64lo); cShift -= 0x20; } */
+                         "jz    1f\n\t"
+                         "xchgl %%eax, %%edx\n\t"
+                         "1:\n\t"
+                         "andb  $0x1f, %%cl\n\t"        /* if (cShift & 0x1f) { */
+                         "jz    2f\n\t"
+                         "movl  %%edx, %2\n\t"          /*   save the hi value in %3. */
+                         "shldl %%cl,%%eax,%%edx\n\t"   /*   shift the hi value left, feeding MSBits from the low value. */
+                         "shldl %%cl,%2,%%eax\n\t"      /*   shift the lo value left, feeding MSBits from the saved hi value. */
+                         "2:\n\t"                       /* } */
+                         : "=A" (u64), "=c" (cShift), "=r" (uSpill)
+                         : "0" (u64),
+                           "1" (cShift));
+    return u64;
+#else
+    cShift &= 63;
+    return (u64 << cShift) | (u64 >> (64 - cShift));
+#endif
+}
+
+
+/**
+ * Rotate 64-bit unsigned value to the right by @a cShift.
+ *
+ * @returns Rotated value.
+ * @param   u64                 The value to rotate.
+ * @param   cShift              How many bits to rotate by.
+ */
+DECLINLINE(uint64_t) ASMRotateRightU64(uint64_t u64, uint32_t cShift)
+{
+#if RT_INLINE_ASM_USES_INTRIN
+    return _rotr64(u64, cShift);
+#elif RT_INLINE_ASM_GNU_STYLE && defined(RT_ARCH_AMD64)
+    __asm__ __volatile__("rorq %b1, %0" : "=g" (u64) : "Jc" (cShift), "0" (u64));
+    return u64;
+#elif RT_INLINE_ASM_GNU_STYLE && defined(RT_ARCH_X86)
+    uint32_t uSpill;
+    __asm__ __volatile__("testb $0x20, %%cl\n\t"        /* if (cShift >= 0x20) { swap(u64.hi, u64lo); cShift -= 0x20; } */
+                         "jz    1f\n\t"
+                         "xchgl %%eax, %%edx\n\t"
+                         "1:\n\t"
+                         "andb  $0x1f, %%cl\n\t"        /* if (cShift & 0x1f) { */
+                         "jz    2f\n\t"
+                         "movl  %%edx, %2\n\t"          /*   save the hi value in %3. */
+                         "shrdl %%cl,%%eax,%%edx\n\t"   /*   shift the hi value right, feeding LSBits from the low value. */
+                         "shrdl %%cl,%2,%%eax\n\t"      /*   shift the lo value right, feeding LSBits from the saved hi value. */
+                         "2:\n\t"                       /* } */
+                         : "=A" (u64), "=c" (cShift), "=r" (uSpill)
+                         : "0" (u64),
+                           "1" (cShift));
+    return u64;
+#else
+    cShift &= 63;
+    return (u64 >> cShift) | (u64 << (64 - cShift));
+#endif
+}
+
+/** @} */
+
+
+/** @} */
+
+#endif
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/include/iprt/assert.h
@@ -0,0 +1,2785 @@
+/** @file
+ * IPRT - Assertions.
+ */
+
+/*
+ * Copyright (C) 2006-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+#ifndef ___iprt_assert_h
+#define ___iprt_assert_h
+
+#include <iprt/cdefs.h>
+#include <iprt/types.h>
+#include <iprt/stdarg.h>
+
+/** @defgroup grp_rt_assert     Assert - Assertions
+ * @ingroup grp_rt
+ *
+ * Assertions are generally used to check preconditions and other
+ * assumptions. Sometimes it is also used to catch odd errors or errors
+ * that one would like to inspect in the debugger. They should not be
+ * used for errors that happen frequently.
+ *
+ * IPRT provides a host of assertion macros, so many that it can be a bit
+ * overwhelming at first. Don't despair, there is a system (surprise).
+ *
+ * First there are four families of assertions:
+ *      - Assert        - The normal strict build only assertions.
+ *      - AssertLogRel  - Calls LogRel() in non-strict builds, otherwise like Assert.
+ *      - AssertRelease - Triggers in all builds.
+ *      - AssertFatal   - Triggers in all builds and cannot be continued.
+ *
+ * Then there are variations wrt to argument list and behavior on failure:
+ *      - Msg           - Custom RTStrPrintf-like message with the assertion message.
+ *      - Return        - Return the specific rc on failure.
+ *      - ReturnVoid    - Return (void) on failure.
+ *      - Break         - Break (out of switch/loop) on failure.
+ *      - Stmt          - Execute the specified statement(s) on failure.
+ *      - RC            - Assert RT_SUCCESS.
+ *      - RCSuccess     - Assert VINF_SUCCESS.
+ *
+ * In addition there is a very special family AssertCompile that can be
+ * used for some limited compile-time checking, like structure sizes and member
+ * alignment. This family doesn't have the same variations.
+ *
+ *
+ * @remarks As you might have noticed, the macros don't follow the
+ * coding guidelines wrt to macros supposedly being all uppercase
+ * and underscored. For various  reasons they don't, and nobody
+ * has complained yet. Wonder why... :-)
+ *
+ * @remarks Each project has its own specific guidelines on how to use
+ * assertions, so the above is just trying to give you the general idea
+ * from the IPRT point of view.
+ *
+ * @{
+ */
+
+RT_C_DECLS_BEGIN
+
+/**
+ * The 1st part of an assert message.
+ *
+ * @param   pszExpr     Expression. Can be NULL.
+ * @param   uLine       Location line number.
+ * @param   pszFile     Location file name.
+ * @param   pszFunction Location function name.
+ */
+RTDECL(void)    RTAssertMsg1(const char *pszExpr, unsigned uLine, const char *pszFile, const char *pszFunction);
+/**
+ * Weak version of RTAssertMsg1 that can be overridden locally in a module to
+ * modify, redirect or otherwise mess with the assertion output.
+ *
+ * @copydoc RTAssertMsg1
+ */
+RTDECL(void)    RTAssertMsg1Weak(const char *pszExpr, unsigned uLine, const char *pszFile, const char *pszFunction);
+
+/**
+ * The 2nd (optional) part of an assert message.
+ *
+ * @param   pszFormat   Printf like format string.
+ * @param   ...         Arguments to that string.
+ */
+RTDECL(void)    RTAssertMsg2(const char *pszFormat, ...) RT_IPRT_FORMAT_ATTR(1, 2);
+/**
+ * Weak version of RTAssertMsg2 that forwards to RTAssertMsg2WeakV.
+ *
+ * There is not need to override this, check out RTAssertMsg2WeakV instead!
+ *
+ * @copydoc RTAssertMsg2
+ */
+RTDECL(void)    RTAssertMsg2Weak(const char *pszFormat, ...) RT_IPRT_FORMAT_ATTR(1, 2);
+
+/**
+ * The 2nd (optional) part of an assert message.
+ *
+ * @param   pszFormat   Printf like format string.
+ * @param   va          Arguments to that string.
+ */
+RTDECL(void)    RTAssertMsg2V(const char *pszFormat, va_list va) RT_IPRT_FORMAT_ATTR(1, 0);
+/**
+ * Weak version of RTAssertMsg2V that can be overridden locally in a module to
+ * modify, redirect or otherwise mess with the assertion output.
+ *
+ * @copydoc RTAssertMsg2V
+ */
+RTDECL(void)    RTAssertMsg2WeakV(const char *pszFormat, va_list va) RT_IPRT_FORMAT_ATTR(1, 0);
+
+/**
+ * Additional information which should be appended to the 2nd part of an
+ * assertion message.
+ *
+ * @param   pszFormat   Printf like format string.
+ * @param   ...         Arguments to that string.
+ */
+RTDECL(void)    RTAssertMsg2Add(const char *pszFormat, ...) RT_IPRT_FORMAT_ATTR(1, 2);
+/**
+ * Weak version of RTAssertMsg2Add that forwards to RTAssertMsg2AddWeakV.
+ *
+ * There is not need to override this, check out RTAssertMsg2AddWeakV instead!
+ *
+ * @copydoc RTAssertMsg2Add
+ */
+RTDECL(void)    RTAssertMsg2AddWeak(const char *pszFormat, ...) RT_IPRT_FORMAT_ATTR(1, 2);
+
+/**
+ * Additional information which should be appended to the 2nd part of an
+ * assertion message.
+ *
+ * @param   pszFormat   Printf like format string.
+ * @param   va          Arguments to that string.
+ */
+RTDECL(void)    RTAssertMsg2AddV(const char *pszFormat, va_list va) RT_IPRT_FORMAT_ATTR(1, 0);
+/**
+ * Weak version of RTAssertMsg2AddV that can be overridden locally in a module
+ * to modify, redirect or otherwise mess with the assertion output.
+ *
+ * @copydoc RTAssertMsg2AddV
+ */
+RTDECL(void)    RTAssertMsg2AddWeakV(const char *pszFormat, va_list va) RT_IPRT_FORMAT_ATTR(1, 0);
+
+#ifdef IN_RING0
+/**
+ * Panics the system as the result of a fail assertion.
+ */
+RTR0DECL(void)  RTR0AssertPanicSystem(void);
+#endif /* IN_RING0 */
+
+/**
+ * Overridable function that decides whether assertions executes the panic
+ * (breakpoint) or not.
+ *
+ * The generic implementation will return true.
+ *
+ * @returns true if the breakpoint should be hit, false if it should be ignored.
+ *
+ * @remark  The RTDECL() makes this a bit difficult to override on Windows. So,
+ *          you'll have to use RTASSERT_HAVE_SHOULD_PANIC or
+ *          RTASSERT_HAVE_SHOULD_PANIC_PRIVATE there to control the kind of
+ *          prototype.
+ */
+#if !defined(RTASSERT_HAVE_SHOULD_PANIC) && !defined(RTASSERT_HAVE_SHOULD_PANIC_PRIVATE)
+RTDECL(bool)    RTAssertShouldPanic(void);
+#elif defined(RTASSERT_HAVE_SHOULD_PANIC_PRIVATE)
+bool            RTAssertShouldPanic(void);
+#else
+DECLEXPORT(bool) RTCALL RTAssertShouldPanic(void);
+#endif
+
+/**
+ * Controls whether the assertions should be quiet or noisy (default).
+ *
+ * @returns The old setting.
+ * @param   fQuiet              The new setting.
+ */
+RTDECL(bool)    RTAssertSetQuiet(bool fQuiet);
+
+/**
+ * Are assertions quiet or noisy?
+ *
+ * @returns True if they are quiet, false if noisy.
+ */
+RTDECL(bool)    RTAssertAreQuiet(void);
+
+/**
+ * Makes the assertions panic (default) or not.
+ *
+ * @returns The old setting.
+ * @param   fPanic              The new setting.
+ */
+RTDECL(bool)    RTAssertSetMayPanic(bool fPanic);
+
+/**
+ * Can assertion panic.
+ *
+ * @returns True if they can, false if not.
+ */
+RTDECL(bool)    RTAssertMayPanic(void);
+
+
+/** @name Globals for crash analysis
+ * @remarks     This is the full potential set, it
+ * @{
+ */
+/** The last assert message, 1st part. */
+extern RTDATADECL(char)                     g_szRTAssertMsg1[1024];
+/** The last assert message, 2nd part. */
+extern RTDATADECL(char)                     g_szRTAssertMsg2[4096];
+/** The last assert message, expression. */
+extern RTDATADECL(const char * volatile)    g_pszRTAssertExpr;
+/** The last assert message, file name. */
+extern RTDATADECL(const char * volatile)    g_pszRTAssertFile;
+/** The last assert message, line number. */
+extern RTDATADECL(uint32_t volatile)        g_u32RTAssertLine;
+/** The last assert message, function name. */
+extern RTDATADECL(const char * volatile)    g_pszRTAssertFunction;
+/** @} */
+
+RT_C_DECLS_END
+
+/** @def RTAssertDebugBreak()
+ * Debugger breakpoint instruction.
+ *
+ * @remarks This macro does not depend on RT_STRICT.
+ */
+#define RTAssertDebugBreak()    do { RT_BREAKPOINT(); } while (0)
+
+
+
+/** @name Compile time assertions.
+ *
+ * These assertions are used to check structure sizes, member/size alignments
+ * and similar compile time expressions.
+ *
+ * @{
+ */
+
+/**
+ * RTASSERTTYPE is the type the AssertCompile() macro redefines.
+ * It has no other function and shouldn't be used.
+ * Visual C++ uses this.
+ */
+typedef int RTASSERTTYPE[1];
+
+/**
+ * RTASSERTVAR is the type the AssertCompile() macro redefines.
+ * It has no other function and shouldn't be used.
+ * GCC uses this.
+ */
+#ifdef __GNUC__
+RT_C_DECLS_BEGIN
+#endif
+extern int RTASSERTVAR[1];
+#ifdef __GNUC__
+RT_C_DECLS_END
+#endif
+
+/** @def RTASSERT_HAVE_STATIC_ASSERT
+ * Indicates that the compiler implements static_assert(expr, msg).
+ */
+#ifdef _MSC_VER
+# if _MSC_VER >= 1600 && defined(__cplusplus)
+#  define RTASSERT_HAVE_STATIC_ASSERT
+# endif
+#endif
+#if defined(__GNUC__) && defined(__GXX_EXPERIMENTAL_CXX0X__)
+# define RTASSERT_HAVE_STATIC_ASSERT
+#endif
+#ifdef DOXYGEN_RUNNING
+# define RTASSERT_HAVE_STATIC_ASSERT
+#endif
+
+/** @def AssertCompileNS
+ * Asserts that a compile-time expression is true. If it's not break the build.
+ *
+ * This differs from AssertCompile in that it accepts some more expressions
+ * than what C++0x allows - NS = Non-standard.
+ *
+ * @param   expr    Expression which should be true.
+ */
+#ifdef __GNUC__
+# define AssertCompileNS(expr)  extern int RTASSERTVAR[1] __attribute__((unused)), RTASSERTVAR[(expr) ? 1 : 0] __attribute__((unused))
+#elif defined(__IBMC__) || defined(__IBMCPP__)
+# define AssertCompileNS(expr)  extern int RTASSERTVAR[(expr) ? 1 : 0]
+#else
+# define AssertCompileNS(expr)  typedef int RTASSERTTYPE[(expr) ? 1 : 0]
+#endif
+
+/** @def AssertCompile
+ * Asserts that a C++0x compile-time expression is true. If it's not break the
+ * build.
+ * @param   expr    Expression which should be true.
+ */
+#ifdef RTASSERT_HAVE_STATIC_ASSERT
+# define AssertCompile(expr)    static_assert(!!(expr), #expr)
+#else
+# define AssertCompile(expr)    AssertCompileNS(expr)
+#endif
+
+/** @def RTASSERT_OFFSET_OF()
+ * A offsetof() macro suitable for compile time assertions.
+ * Both GCC v4 and VisualAge for C++ v3.08 has trouble using RT_OFFSETOF.
+ */
+#if defined(__GNUC__)
+# if __GNUC__ >= 4
+#  define RTASSERT_OFFSET_OF(a_Type, a_Member)  __builtin_offsetof(a_Type, a_Member)
+# else
+#  define RTASSERT_OFFSET_OF(a_Type, a_Member)  RT_OFFSETOF(a_Type, a_Member)
+# endif
+#elif (defined(__IBMC__) || defined(__IBMCPP__)) && defined(RT_OS_OS2)
+# define RTASSERT_OFFSET_OF(a_Type, a_Member)   __offsetof(a_Type, a_Member)
+#else
+# define RTASSERT_OFFSET_OF(a_Type, a_Member)   RT_OFFSETOF(a_Type, a_Member)
+#endif
+
+
+/** @def AssertCompileSize
+ * Asserts a size at compile.
+ * @param   type    The type.
+ * @param   size    The expected type size.
+ */
+#define AssertCompileSize(type, size) \
+    AssertCompile(sizeof(type) == (size))
+
+/** @def AssertCompileSizeAlignment
+ * Asserts a size alignment at compile.
+ * @param   type    The type.
+ * @param   align   The size alignment to assert.
+ */
+#define AssertCompileSizeAlignment(type, align) \
+    AssertCompile(!(sizeof(type) & ((align) - 1)))
+
+/** @def AssertCompileMemberSize
+ * Asserts a member offset alignment at compile.
+ * @param   type    The type.
+ * @param   member  The member.
+ * @param   size    The member size to assert.
+ */
+#define AssertCompileMemberSize(type, member, size) \
+    AssertCompile(RT_SIZEOFMEMB(type, member) == (size))
+
+/** @def AssertCompileMemberSizeAlignment
+ * Asserts a member size alignment at compile.
+ * @param   type    The type.
+ * @param   member  The member.
+ * @param   align   The member size alignment to assert.
+ */
+#define AssertCompileMemberSizeAlignment(type, member, align) \
+    AssertCompile(!(RT_SIZEOFMEMB(type, member) & ((align) - 1)))
+
+/** @def AssertCompileMemberAlignment
+ * Asserts a member offset alignment at compile.
+ * @param   type    The type.
+ * @param   member  The member.
+ * @param   align   The member offset alignment to assert.
+ */
+#define AssertCompileMemberAlignment(type, member, align) \
+    AssertCompile(!(RTASSERT_OFFSET_OF(type, member) & ((align) - 1)))
+
+/** @def AssertCompileMemberOffset
+ * Asserts an offset of a structure member at compile.
+ * @param   type    The type.
+ * @param   member  The member.
+ * @param   off     The expected offset.
+ */
+#define AssertCompileMemberOffset(type, member, off) \
+    AssertCompile(RTASSERT_OFFSET_OF(type, member) == (off))
+
+/** @def AssertCompile2MemberOffsets
+ * Asserts that two (sub-structure) members in union have the same offset.
+ * @param   type    The type.
+ * @param   member1 The first member.
+ * @param   member2 The second member.
+ */
+#define AssertCompile2MemberOffsets(type, member1, member2) \
+    AssertCompile(RTASSERT_OFFSET_OF(type, member1) == RTASSERT_OFFSET_OF(type, member2))
+
+/** @def AssertCompileAdjacentMembers
+ * Asserts that two structure members are adjacent.
+ * @param   type    The type.
+ * @param   member1 The first member.
+ * @param   member2 The second member.
+ */
+#define AssertCompileAdjacentMembers(type, member1, member2) \
+    AssertCompile(RTASSERT_OFFSET_OF(type, member1) + RT_SIZEOFMEMB(type, member1) == RTASSERT_OFFSET_OF(type, member2))
+
+/** @def AssertCompileMembersAtSameOffset
+ * Asserts that members of two different structures are at the same offset.
+ * @param   type1   The first type.
+ * @param   member1 The first member.
+ * @param   type2   The second type.
+ * @param   member2 The second member.
+ */
+#define AssertCompileMembersAtSameOffset(type1, member1, type2, member2) \
+    AssertCompile(RTASSERT_OFFSET_OF(type1, member1) == RTASSERT_OFFSET_OF(type2, member2))
+
+/** @def AssertCompileMembersSameSize
+ * Asserts that members of two different structures have the same size.
+ * @param   type1   The first type.
+ * @param   member1 The first member.
+ * @param   type2   The second type.
+ * @param   member2 The second member.
+ */
+#define AssertCompileMembersSameSize(type1, member1, type2, member2) \
+    AssertCompile(RT_SIZEOFMEMB(type1, member1) == RT_SIZEOFMEMB(type2, member2))
+
+/** @def AssertCompileMembersSameSizeAndOffset
+ * Asserts that members of two different structures have the same size and are
+ * at the same offset.
+ * @param   type1   The first type.
+ * @param   member1 The first member.
+ * @param   type2   The second type.
+ * @param   member2 The second member.
+ */
+#define AssertCompileMembersSameSizeAndOffset(type1, member1, type2, member2) \
+    AssertCompile(   RTASSERT_OFFSET_OF(type1, member1) == RTASSERT_OFFSET_OF(type2, member2) \
+                  && RT_SIZEOFMEMB(type1, member1) == RT_SIZEOFMEMB(type2, member2))
+
+/** @} */
+
+
+
+/** @name Assertions
+ *
+ * These assertions will only trigger when RT_STRICT is defined. When it is
+ * undefined they will all be no-ops and generate no code.
+ *
+ * @{
+ */
+
+
+/** @def RTASSERT_QUIET
+ * This can be defined to shut up the messages for a file where this would be
+ * problematic because the message printing code path passes thru it.
+ * @internal */
+#ifdef DOXYGEN_RUNNING
+# define RTASSERT_QUIET
+#endif
+#if defined(RTASSERT_QUIET) && !defined(DOXYGEN_RUNNING)
+# define RTAssertMsg1Weak(pszExpr, uLine, pszfile, pszFunction) \
+                                do { } while (0)
+# define RTAssertMsg2Weak       if (1) {} else RTAssertMsg2Weak
+#endif
+
+/** @def RTAssertDoPanic
+ * Raises an assertion panic appropriate to the current context.
+ * @remarks This macro does not depend on RT_STRICT.
+ */
+#if defined(IN_RING0) \
+ && (defined(RT_OS_DARWIN) || defined(RT_OS_HAIKU) || defined(RT_OS_SOLARIS))
+# define RTAssertDoPanic()      RTR0AssertPanicSystem()
+#else
+# define RTAssertDoPanic()      RTAssertDebugBreak()
+#endif
+
+/** @def AssertBreakpoint()
+ * Assertion Breakpoint.
+ * @deprecated Use RTAssertPanic or RTAssertDebugBreak instead.
+ */
+#ifdef RT_STRICT
+# define AssertBreakpoint()     RTAssertDebugBreak()
+#else
+# define AssertBreakpoint()     do { } while (0)
+#endif
+
+/** @def RTAssertPanic()
+ * If RT_STRICT is defined this macro will invoke RTAssertDoPanic if
+ * RTAssertShouldPanic returns true. If RT_STRICT isn't defined it won't do any
+ * thing.
+ */
+#if defined(RT_STRICT) && !defined(RTASSERT_DONT_PANIC)
+# define RTAssertPanic()        do { if (RTAssertShouldPanic()) RTAssertDoPanic(); } while (0)
+#else
+# define RTAssertPanic()        do { } while (0)
+#endif
+
+/** @def Assert
+ * Assert that an expression is true. If false, hit breakpoint.
+ * @param   expr    Expression which should be true.
+ */
+#ifdef RT_STRICT
+# define Assert(expr)  \
+    do { \
+        if (RT_LIKELY(!!(expr))) \
+        { /* likely */ } \
+        else \
+        { \
+            RTAssertMsg1Weak(#expr, __LINE__, __FILE__, RT_GCC_EXTENSION __PRETTY_FUNCTION__); \
+            RTAssertPanic(); \
+        } \
+    } while (0)
+#else
+# define Assert(expr)     do { } while (0)
+#endif
+
+
+/** @def AssertStmt
+ * Assert that an expression is true. If false, hit breakpoint and execute the
+ * statement.
+ * @param   expr    Expression which should be true.
+ * @param   stmt    Statement to execute on failure.
+ */
+#ifdef RT_STRICT
+# define AssertStmt(expr, stmt)  \
+    do { \
+        if (RT_LIKELY(!!(expr))) \
+        { /* likely */ } \
+        else \
+        { \
+            RTAssertMsg1Weak(#expr, __LINE__, __FILE__, RT_GCC_EXTENSION __PRETTY_FUNCTION__); \
+            RTAssertPanic(); \
+            stmt; \
+        } \
+    } while (0)
+#else
+# define AssertStmt(expr, stmt)  \
+    do { \
+        if (RT_LIKELY(!!(expr))) \
+        { /* likely */ } \
+        else \
+        { \
+            stmt; \
+        } \
+    } while (0)
+#endif
+
+
+/** @def AssertReturn
+ * Assert that an expression is true and returns if it isn't.
+ * In RT_STRICT mode it will hit a breakpoint before returning.
+ *
+ * @param   expr    Expression which should be true.
+ * @param   rc      What is to be presented to return.
+ */
+#ifdef RT_STRICT
+# define AssertReturn(expr, rc) \
+    do { \
+        if (RT_LIKELY(!!(expr))) \
+        { /* likely */ } \
+        else \
+        { \
+            RTAssertMsg1Weak(#expr, __LINE__, __FILE__, RT_GCC_EXTENSION __PRETTY_FUNCTION__); \
+            RTAssertPanic(); \
+            return (rc); \
+        } \
+    } while (0)
+#else
+# define AssertReturn(expr, rc) \
+    do { \
+        if (RT_LIKELY(!!(expr))) \
+        { /* likely */ } \
+        else \
+            return (rc); \
+    } while (0)
+#endif
+
+/** @def AssertReturnStmt
+ * Assert that an expression is true, if it isn't execute the given statement
+ * and return rc.
+ *
+ * In RT_STRICT mode it will hit a breakpoint before executing the statement and
+ * returning.
+ *
+ * @param   expr    Expression which should be true.
+ * @param   stmt    Statement to execute before returning on failure.
+ * @param   rc      What is to be presented to return.
+ */
+#ifdef RT_STRICT
+# define AssertReturnStmt(expr, stmt, rc) \
+    do { \
+        if (RT_LIKELY(!!(expr))) \
+        { /* likely */ } \
+        else \
+        { \
+            RTAssertMsg1Weak(#expr, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+            RTAssertPanic(); \
+            stmt; \
+            return (rc); \
+        } \
+    } while (0)
+#else
+# define AssertReturnStmt(expr, stmt, rc) \
+    do { \
+        if (RT_LIKELY(!!(expr))) \
+        { /* likely */ } \
+        else \
+        { \
+            stmt; \
+            return (rc); \
+        } \
+    } while (0)
+#endif
+
+/** @def AssertReturnVoid
+ * Assert that an expression is true and returns if it isn't.
+ * In RT_STRICT mode it will hit a breakpoint before returning.
+ *
+ * @param   expr    Expression which should be true.
+ */
+#ifdef RT_STRICT
+# define AssertReturnVoid(expr) \
+    do { \
+        if (RT_LIKELY(!!(expr))) \
+        { /* likely */ } \
+        else \
+        { \
+            RTAssertMsg1Weak(#expr, __LINE__, __FILE__, RT_GCC_EXTENSION __PRETTY_FUNCTION__); \
+            RTAssertPanic(); \
+            return; \
+        } \
+    } while (0)
+#else
+# define AssertReturnVoid(expr) \
+    do { \
+        if (RT_LIKELY(!!(expr))) \
+        { /* likely */ } \
+        else \
+            return; \
+    } while (0)
+#endif
+
+/** @def AssertReturnVoidStmt
+ * Assert that an expression is true, if it isn't execute the given statement
+ * and return.
+ *
+ * In RT_STRICT mode it will hit a breakpoint before returning.
+ *
+ * @param   expr    Expression which should be true.
+ * @param   stmt    Statement to execute before returning on failure.
+ */
+#ifdef RT_STRICT
+# define AssertReturnVoidStmt(expr, stmt) \
+    do { \
+        if (RT_LIKELY(!!(expr))) \
+        { /* likely */ } \
+        else \
+        { \
+            RTAssertMsg1Weak(#expr, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+            RTAssertPanic(); \
+            stmt; \
+            return; \
+        } \
+    } while (0)
+#else
+# define AssertReturnVoidStmt(expr, stmt) \
+    do { \
+        if (RT_LIKELY(!!(expr))) \
+        { /* likely */ } \
+        else \
+        { \
+            stmt; \
+            return; \
+        } \
+    } while (0)
+#endif
+
+
+/** @def AssertBreak
+ * Assert that an expression is true and breaks if it isn't.
+ * In RT_STRICT mode it will hit a breakpoint before breaking.
+ *
+ * @param   expr    Expression which should be true.
+ */
+#ifdef RT_STRICT
+# define AssertBreak(expr) \
+    if (RT_LIKELY(!!(expr))) \
+    { /* likely */ } \
+    else if (1) \
+    { \
+        RTAssertMsg1Weak(#expr, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+        RTAssertPanic(); \
+        break; \
+    } else do {} while (0)
+#else
+# define AssertBreak(expr) \
+    if (RT_LIKELY(!!(expr))) \
+    { /* likely */ } \
+    else \
+        break
+#endif
+
+/** @def AssertContinue
+ * Assert that an expression is true and continue if it isn't.
+ * In RT_STRICT mode it will hit a breakpoint before continuing.
+ *
+ * @param   expr    Expression which should be true.
+ */
+#ifdef RT_STRICT
+# define AssertContinue(expr) \
+    if (RT_LIKELY(!!(expr))) \
+    { /* likely */ } \
+    else if (1) \
+    { \
+        RTAssertMsg1Weak(#expr, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+        RTAssertPanic(); \
+        continue; \
+    } else do {} while (0)
+#else
+# define AssertContinue(expr) \
+    if (RT_LIKELY(!!(expr))) \
+    { /* likely */ } \
+    else \
+        continue
+#endif
+
+/** @def AssertBreakStmt
+ * Assert that an expression is true and breaks if it isn't.
+ * In RT_STRICT mode it will hit a breakpoint before doing break.
+ *
+ * @param   expr    Expression which should be true.
+ * @param   stmt    Statement to execute before break in case of a failed assertion.
+ */
+#ifdef RT_STRICT
+# define AssertBreakStmt(expr, stmt) \
+    if (RT_LIKELY(!!(expr))) \
+    { /* likely */ } \
+    else if (1) \
+    { \
+        RTAssertMsg1Weak(#expr, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+        RTAssertPanic(); \
+        stmt; \
+        break; \
+    } else do {} while (0)
+#else
+# define AssertBreakStmt(expr, stmt) \
+    if (RT_LIKELY(!!(expr))) \
+    { /* likely */ } \
+    else if (1) \
+    { \
+        stmt; \
+        break; \
+    } else do {} while (0)
+#endif
+
+
+/** @def AssertMsg
+ * Assert that an expression is true. If it's not print message and hit breakpoint.
+ * @param   expr    Expression which should be true.
+ * @param   a       printf argument list (in parenthesis).
+ */
+#ifdef RT_STRICT
+# define AssertMsg(expr, a)  \
+    do { \
+        if (RT_LIKELY(!!(expr))) \
+        { /* likely */ } \
+        else \
+        { \
+            RTAssertMsg1Weak(#expr, __LINE__, __FILE__, RT_GCC_EXTENSION __PRETTY_FUNCTION__); \
+            RTAssertMsg2Weak a; \
+            RTAssertPanic(); \
+        } \
+    } while (0)
+#else
+# define AssertMsg(expr, a)  do { } while (0)
+#endif
+
+/** @def AssertMsgStmt
+ * Assert that an expression is true.  If it's not print message and hit
+ * breakpoint and execute the statement.
+ *
+ * @param   expr    Expression which should be true.
+ * @param   a       printf argument list (in parenthesis).
+ * @param   stmt    Statement to execute in case of a failed assertion.
+ *
+ * @remarks The expression and statement will be evaluated in all build types.
+ */
+#ifdef RT_STRICT
+# define AssertMsgStmt(expr, a, stmt)  \
+    do { \
+        if (RT_LIKELY(!!(expr))) \
+        { /* likely */ } \
+        else \
+        { \
+            RTAssertMsg1Weak(#expr, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+            RTAssertMsg2Weak a; \
+            RTAssertPanic(); \
+            stmt; \
+        } \
+    } while (0)
+#else
+# define AssertMsgStmt(expr, a, stmt)  \
+    do { \
+        if (RT_LIKELY(!!(expr))) \
+        { /* likely */ } \
+        else \
+        { \
+            stmt; \
+        } \
+    } while (0)
+#endif
+
+/** @def AssertMsgReturn
+ * Assert that an expression is true and returns if it isn't.
+ * In RT_STRICT mode it will hit a breakpoint before returning.
+ *
+ * @param   expr    Expression which should be true.
+ * @param   a       printf argument list (in parenthesis).
+ * @param   rc      What is to be presented to return.
+ */
+#ifdef RT_STRICT
+# define AssertMsgReturn(expr, a, rc)  \
+    do { \
+        if (RT_LIKELY(!!(expr))) \
+        { /* likely */ } \
+        else \
+        { \
+            RTAssertMsg1Weak(#expr, __LINE__, __FILE__, RT_GCC_EXTENSION __PRETTY_FUNCTION__); \
+            RTAssertMsg2Weak a; \
+            RTAssertPanic(); \
+            return (rc); \
+        } \
+    } while (0)
+#else
+# define AssertMsgReturn(expr, a, rc) \
+    do { \
+        if (RT_LIKELY(!!(expr))) \
+        { /* likely */ } \
+        else \
+            return (rc); \
+    } while (0)
+#endif
+
+/** @def AssertMsgReturnStmt
+ * Assert that an expression is true, if it isn't execute the statement and
+ * return.
+ *
+ * In RT_STRICT mode it will hit a breakpoint before returning.
+ *
+ * @param   expr    Expression which should be true.
+ * @param   a       printf argument list (in parenthesis).
+ * @param   stmt    Statement to execute before returning in case of a failed
+ *                  assertion.
+ * @param   rc      What is to be presented to return.
+ */
+#ifdef RT_STRICT
+# define AssertMsgReturnStmt(expr, a, stmt, rc)  \
+    do { \
+        if (RT_LIKELY(!!(expr))) \
+        { /* likely */ } \
+        else \
+        { \
+            RTAssertMsg1Weak(#expr, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+            RTAssertMsg2Weak a; \
+            RTAssertPanic(); \
+            stmt; \
+            return (rc); \
+        } \
+    } while (0)
+#else
+# define AssertMsgReturnStmt(expr, a, stmt, rc) \
+    do { \
+        if (RT_LIKELY(!!(expr))) \
+        { /* likely */ } \
+        else \
+        { \
+            stmt; \
+            return (rc); \
+        } \
+    } while (0)
+#endif
+
+/** @def AssertMsgReturnVoid
+ * Assert that an expression is true and returns if it isn't.
+ * In RT_STRICT mode it will hit a breakpoint before returning.
+ *
+ * @param   expr    Expression which should be true.
+ * @param   a       printf argument list (in parenthesis).
+ */
+#ifdef RT_STRICT
+# define AssertMsgReturnVoid(expr, a)  \
+    do { \
+        if (RT_LIKELY(!!(expr))) \
+        { /* likely */ } \
+        else \
+        { \
+            RTAssertMsg1Weak(#expr, __LINE__, __FILE__, RT_GCC_EXTENSION __PRETTY_FUNCTION__); \
+            RTAssertMsg2Weak a; \
+            RTAssertPanic(); \
+            return; \
+        } \
+    } while (0)
+#else
+# define AssertMsgReturnVoid(expr, a) \
+    do { \
+        if (RT_LIKELY(!!(expr))) \
+        { /* likely */ } \
+        else \
+            return; \
+    } while (0)
+#endif
+
+/** @def AssertMsgReturnVoidStmt
+ * Assert that an expression is true, if it isn't execute the statement and
+ * return.
+ *
+ * In RT_STRICT mode it will hit a breakpoint before returning.
+ *
+ * @param   expr    Expression which should be true.
+ * @param   a       printf argument list (in parenthesis).
+ * @param   stmt    Statement to execute before return in case of a failed assertion.
+ */
+#ifdef RT_STRICT
+# define AssertMsgReturnVoidStmt(expr, a, stmt)  \
+    do { \
+        if (RT_LIKELY(!!(expr))) \
+        { /* likely */ } \
+        else \
+        { \
+            RTAssertMsg1Weak(#expr, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+            RTAssertMsg2Weak a; \
+            RTAssertPanic(); \
+            stmt; \
+            return; \
+        } \
+    } while (0)
+#else
+# define AssertMsgReturnVoidStmt(expr, a, stmt) \
+    do { \
+        if (RT_LIKELY(!!(expr))) \
+        { /* likely */ } \
+        else \
+        { \
+            stmt; \
+            return; \
+        } \
+    } while (0)
+#endif
+
+
+/** @def AssertMsgBreak
+ * Assert that an expression is true and breaks if it isn't.
+ * In RT_STRICT mode it will hit a breakpoint before returning.
+ *
+ * @param   expr    Expression which should be true.
+ * @param   a       printf argument list (in parenthesis).
+ */
+#ifdef RT_STRICT
+# define AssertMsgBreak(expr, a) \
+    if (RT_LIKELY(!!(expr))) \
+    { /* likely */ } \
+    else if (1) \
+    { \
+        RTAssertMsg1Weak(#expr, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+        RTAssertMsg2Weak a; \
+        RTAssertPanic(); \
+        break; \
+    } else do {} while (0)
+#else
+# define AssertMsgBreak(expr, a) \
+    if (RT_LIKELY(!!(expr))) \
+    { /* likely */ } \
+    else \
+        break
+#endif
+
+/** @def AssertMsgBreakStmt
+ * Assert that an expression is true and breaks if it isn't.
+ * In RT_STRICT mode it will hit a breakpoint before doing break.
+ *
+ * @param   expr    Expression which should be true.
+ * @param   a       printf argument list (in parenthesis).
+ * @param   stmt    Statement to execute before break in case of a failed assertion.
+ */
+#ifdef RT_STRICT
+# define AssertMsgBreakStmt(expr, a, stmt) \
+    if (RT_LIKELY(!!(expr))) \
+    { /* likely */ } \
+    else if (1) \
+    { \
+        RTAssertMsg1Weak(#expr, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+        RTAssertMsg2Weak a; \
+        RTAssertPanic(); \
+        stmt; \
+        break; \
+    } else do {} while (0)
+#else
+# define AssertMsgBreakStmt(expr, a, stmt) \
+    if (RT_LIKELY(!!(expr))) \
+    { /* likely */ } \
+    else if (1) \
+    { \
+        stmt; \
+        break; \
+    } else do {} while (0)
+#endif
+
+/** @def AssertFailed
+ * An assertion failed hit breakpoint.
+ */
+#ifdef RT_STRICT
+# define AssertFailed()  \
+    do { \
+        RTAssertMsg1Weak((const char *)0, __LINE__, __FILE__, RT_GCC_EXTENSION __PRETTY_FUNCTION__); \
+        RTAssertPanic(); \
+    } while (0)
+#else
+# define AssertFailed()         do { } while (0)
+#endif
+
+/** @def AssertFailedReturn
+ * An assertion failed, hit breakpoint (RT_STRICT mode only) and return.
+ *
+ * @param   rc      The rc to return.
+ */
+#ifdef RT_STRICT
+# define AssertFailedReturn(rc)  \
+    do { \
+        RTAssertMsg1Weak((const char *)0, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+        RTAssertPanic(); \
+        return (rc); \
+    } while (0)
+#else
+# define AssertFailedReturn(rc)  \
+    do { \
+        return (rc); \
+    } while (0)
+#endif
+
+/** @def AssertFailedReturnStmt
+ * An assertion failed, hit breakpoint (RT_STRICT mode only), execute a
+ * statement and return a value.
+ *
+ * @param   stmt    The statement to execute before returning.
+ * @param   rc      The value to return.
+ */
+#ifdef RT_STRICT
+# define AssertFailedReturnStmt(stmt, rc)  \
+    do { \
+        RTAssertMsg1Weak((const char *)0, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+        RTAssertPanic(); \
+        stmt; \
+        return (rc); \
+    } while (0)
+#else
+# define AssertFailedReturnStmt(stmt, rc)  \
+    do { \
+        stmt; \
+        return (rc); \
+    } while (0)
+#endif
+
+/** @def AssertFailedReturnVoid
+ * An assertion failed, hit breakpoint (RT_STRICT mode only) and return.
+ */
+#ifdef RT_STRICT
+# define AssertFailedReturnVoid()  \
+    do { \
+        RTAssertMsg1Weak((const char *)0, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+        RTAssertPanic(); \
+        return; \
+    } while (0)
+#else
+# define AssertFailedReturnVoid()  \
+    do { \
+        return; \
+    } while (0)
+#endif
+
+/** @def AssertFailedReturnVoidStmt
+ * An assertion failed, hit breakpoint (RT_STRICT mode only), execute a
+ * statement and return.
+ *
+ * @param stmt The statement to execute before returning.
+ */
+#ifdef RT_STRICT
+# define AssertFailedReturnVoidStmt(stmt)  \
+    do { \
+        RTAssertMsg1Weak((const char *)0, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+        RTAssertPanic(); \
+        stmt; \
+        return; \
+    } while (0)
+#else
+# define AssertFailedReturnVoidStmt(stmt)  \
+    do { \
+        stmt; \
+        return; \
+    } while (0)
+#endif
+
+
+/** @def AssertFailedBreak
+ * An assertion failed, hit breakpoint (RT_STRICT mode only) and break.
+ */
+#ifdef RT_STRICT
+# define AssertFailedBreak()  \
+    if (1) { \
+        RTAssertMsg1Weak((const char *)0, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+        RTAssertPanic(); \
+        break; \
+    } else do {} while (0)
+#else
+# define AssertFailedBreak()  \
+    if (1) \
+        break; \
+    else do {} while (0)
+#endif
+
+/** @def AssertFailedBreakStmt
+ * An assertion failed, hit breakpoint (RT_STRICT mode only), execute
+ * the given statement and break.
+ *
+ * @param   stmt    Statement to execute before break.
+ */
+#ifdef RT_STRICT
+# define AssertFailedBreakStmt(stmt) \
+    if (1) { \
+        RTAssertMsg1Weak((const char *)0, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+        RTAssertPanic(); \
+        stmt; \
+        break; \
+    } else do {} while (0)
+#else
+# define AssertFailedBreakStmt(stmt) \
+    if (1) { \
+        stmt; \
+        break; \
+    } else do {} while (0)
+#endif
+
+
+/** @def AssertMsgFailed
+ * An assertion failed print a message and a hit breakpoint.
+ *
+ * @param   a   printf argument list (in parenthesis).
+ */
+#ifdef RT_STRICT
+# define AssertMsgFailed(a)  \
+    do { \
+        RTAssertMsg1Weak((const char *)0, __LINE__, __FILE__, RT_GCC_EXTENSION __PRETTY_FUNCTION__); \
+        RTAssertMsg2Weak a; \
+        RTAssertPanic(); \
+    } while (0)
+#else
+# define AssertMsgFailed(a)     do { } while (0)
+#endif
+
+/** @def AssertMsgFailedReturn
+ * An assertion failed, hit breakpoint with message (RT_STRICT mode only) and return.
+ *
+ * @param   a       printf argument list (in parenthesis).
+ * @param   rc      What is to be presented to return.
+ */
+#ifdef RT_STRICT
+# define AssertMsgFailedReturn(a, rc)  \
+    do { \
+        RTAssertMsg1Weak((const char *)0, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+        RTAssertMsg2Weak a; \
+        RTAssertPanic(); \
+        return (rc); \
+    } while (0)
+#else
+# define AssertMsgFailedReturn(a, rc)  \
+    do { \
+        return (rc); \
+    } while (0)
+#endif
+
+/** @def AssertMsgFailedReturnVoid
+ * An assertion failed, hit breakpoint with message (RT_STRICT mode only) and return.
+ *
+ * @param   a       printf argument list (in parenthesis).
+ */
+#ifdef RT_STRICT
+# define AssertMsgFailedReturnVoid(a)  \
+    do { \
+        RTAssertMsg1Weak((const char *)0, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+        RTAssertMsg2Weak a; \
+        RTAssertPanic(); \
+        return; \
+    } while (0)
+#else
+# define AssertMsgFailedReturnVoid(a)  \
+    do { \
+        return; \
+    } while (0)
+#endif
+
+
+/** @def AssertMsgFailedBreak
+ * An assertion failed, hit breakpoint with message (RT_STRICT mode only) and break.
+ *
+ * @param   a       printf argument list (in parenthesis).
+ */
+#ifdef RT_STRICT
+# define AssertMsgFailedBreak(a)  \
+    if (1) { \
+        RTAssertMsg1Weak((const char *)0, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+        RTAssertMsg2Weak a; \
+        RTAssertPanic(); \
+        break; \
+    } else do {} while (0)
+#else
+# define AssertMsgFailedBreak(a)  \
+    if (1) \
+        break; \
+    else do {} while (0)
+#endif
+
+/** @def AssertMsgFailedBreakStmt
+ * An assertion failed, hit breakpoint (RT_STRICT mode only), execute
+ * the given statement and break.
+ *
+ * @param   a       printf argument list (in parenthesis).
+ * @param   stmt    Statement to execute before break.
+ */
+#ifdef RT_STRICT
+# define AssertMsgFailedBreakStmt(a, stmt) \
+    if (1) { \
+        RTAssertMsg1Weak((const char *)0, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+        RTAssertMsg2Weak a; \
+        RTAssertPanic(); \
+        stmt; \
+        break; \
+    } else do {} while (0)
+#else
+# define AssertMsgFailedBreakStmt(a, stmt) \
+    if (1) { \
+        stmt; \
+        break; \
+    } else do {} while (0)
+#endif
+
+/** @} */
+
+
+
+/** @name Release Log Assertions
+ *
+ * These assertions will work like normal strict assertion when RT_STRICT is
+ * defined and LogRel statements when RT_STRICT is undefined. Typically used for
+ * things which shouldn't go wrong, but when it does you'd like to know one way
+ * or the other.
+ *
+ * @{
+ */
+
+/** @def RTAssertLogRelMsg1
+ * RTAssertMsg1Weak (strict builds) / LogRel wrapper (non-strict).
+ */
+#ifdef RT_STRICT
+# define RTAssertLogRelMsg1(pszExpr, iLine, pszFile, pszFunction) \
+    RTAssertMsg1Weak(pszExpr, iLine, pszFile, pszFunction)
+#else
+# define RTAssertLogRelMsg1(pszExpr, iLine, pszFile, pszFunction) \
+    LogRel(("AssertLogRel %s(%d) %s: %s\n",\
+            (pszFile), (iLine), (pszFunction), (pszExpr) ))
+#endif
+
+/** @def RTAssertLogRelMsg2
+ * RTAssertMsg2Weak (strict builds) / LogRel wrapper (non-strict).
+ */
+#ifdef RT_STRICT
+# define RTAssertLogRelMsg2(a)  RTAssertMsg2Weak a
+#else
+# define RTAssertLogRelMsg2(a)  LogRel(a)
+#endif
+
+/** @def AssertLogRel
+ * Assert that an expression is true.
+ * Strict builds will hit a breakpoint, non-strict will only do LogRel.
+ *
+ * @param   expr    Expression which should be true.
+ */
+#define AssertLogRel(expr) \
+    do { \
+        if (RT_LIKELY(!!(expr))) \
+        { /* likely */ } \
+        else \
+        { \
+            RTAssertLogRelMsg1(#expr, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+            RTAssertPanic(); \
+        } \
+    } while (0)
+
+/** @def AssertLogRelReturn
+ * Assert that an expression is true, return \a rc if it isn't.
+ * Strict builds will hit a breakpoint, non-strict will only do LogRel.
+ *
+ * @param   expr    Expression which should be true.
+ * @param   rc      What is to be presented to return.
+ */
+#define AssertLogRelReturn(expr, rc) \
+    do { \
+        if (RT_LIKELY(!!(expr))) \
+        { /* likely */ } \
+        else \
+        { \
+            RTAssertLogRelMsg1(#expr, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+            RTAssertPanic(); \
+            return (rc); \
+        } \
+    } while (0)
+
+/** @def AssertLogRelReturnVoid
+ * Assert that an expression is true, return void if it isn't.
+ * Strict builds will hit a breakpoint, non-strict will only do LogRel.
+ *
+ * @param   expr    Expression which should be true.
+ */
+#define AssertLogRelReturnVoid(expr) \
+    do { \
+        if (RT_LIKELY(!!(expr))) \
+        { /* likely */ } \
+        else \
+        { \
+            RTAssertLogRelMsg1(#expr, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+            RTAssertPanic(); \
+            return; \
+        } \
+    } while (0)
+
+/** @def AssertLogRelBreak
+ * Assert that an expression is true, break if it isn't.
+ * Strict builds will hit a breakpoint, non-strict will only do LogRel.
+ *
+ * @param   expr    Expression which should be true.
+ */
+#define AssertLogRelBreak(expr) \
+    if (RT_LIKELY(!!(expr))) \
+    { /* likely */ } \
+    else if (1) \
+    { \
+        RTAssertLogRelMsg1(#expr, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+        RTAssertPanic(); \
+        break; \
+    } \
+    else do {} while (0)
+
+/** @def AssertLogRelBreakStmt
+ * Assert that an expression is true, execute \a stmt and break if it isn't.
+ * Strict builds will hit a breakpoint, non-strict will only do LogRel.
+ *
+ * @param   expr    Expression which should be true.
+ * @param   stmt    Statement to execute before break in case of a failed assertion.
+ */
+#define AssertLogRelBreakStmt(expr, stmt) \
+    if (RT_LIKELY(!!(expr))) \
+    { /* likely */ } \
+    else if (1) \
+    { \
+        RTAssertLogRelMsg1(#expr, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+        RTAssertPanic(); \
+        stmt; \
+        break; \
+    } else do {} while (0)
+
+/** @def AssertLogRelMsg
+ * Assert that an expression is true.
+ * Strict builds will hit a breakpoint, non-strict will only do LogRel.
+ *
+ * @param   expr    Expression which should be true.
+ * @param   a       printf argument list (in parenthesis).
+ */
+#define AssertLogRelMsg(expr, a) \
+    do { \
+        if (RT_LIKELY(!!(expr))) \
+        { /* likely */ } \
+        else\
+        { \
+            RTAssertLogRelMsg1(#expr, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+            RTAssertLogRelMsg2(a); \
+            RTAssertPanic(); \
+        } \
+    } while (0)
+
+/** @def AssertLogRelMsgStmt
+ * Assert that an expression is true, execute \a stmt and break if it isn't
+ * Strict builds will hit a breakpoint, non-strict will only do LogRel.
+ *
+ * @param   expr    Expression which should be true.
+ * @param   a       printf argument list (in parenthesis).
+ * @param   stmt    Statement to execute in case of a failed assertion.
+ */
+#define AssertLogRelMsgStmt(expr, a, stmt) \
+    do { \
+        if (RT_LIKELY(!!(expr))) \
+        { /* likely */ } \
+        else\
+        { \
+            RTAssertLogRelMsg1(#expr, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+            RTAssertLogRelMsg2(a); \
+            RTAssertPanic(); \
+            stmt; \
+        } \
+    } while (0)
+
+/** @def AssertLogRelMsgReturn
+ * Assert that an expression is true, return \a rc if it isn't.
+ * Strict builds will hit a breakpoint, non-strict will only do LogRel.
+ *
+ * @param   expr    Expression which should be true.
+ * @param   a       printf argument list (in parenthesis).
+ * @param   rc      What is to be presented to return.
+ */
+#define AssertLogRelMsgReturn(expr, a, rc) \
+    do { \
+        if (RT_LIKELY(!!(expr))) \
+        { /* likely */ } \
+        else\
+        { \
+            RTAssertLogRelMsg1(#expr, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+            RTAssertLogRelMsg2(a); \
+            RTAssertPanic(); \
+            return (rc); \
+        } \
+    } while (0)
+
+/** @def AssertLogRelMsgReturnStmt
+ * Assert that an expression is true, execute @a stmt and return @a rcRet if it
+ * isn't.
+ * Strict builds will hit a breakpoint, non-strict will only do LogRel.
+ *
+ * @param   expr    Expression which should be true.
+ * @param   a       printf argument list (in parenthesis).
+ * @param   stmt    Statement to execute before returning in case of a failed
+ *                  assertion.
+ * @param   rcRet   What is to be presented to return.
+ */
+#define AssertLogRelMsgReturnStmt(expr, a, stmt, rcRet) \
+    do { \
+        if (RT_LIKELY(!!(expr))) \
+        { /* likely */ } \
+        else\
+        { \
+            RTAssertLogRelMsg1(#expr, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+            RTAssertLogRelMsg2(a); \
+            RTAssertPanic(); \
+            stmt; \
+            return (rcRet); \
+        } \
+    } while (0)
+
+/** @def AssertLogRelMsgReturnVoid
+ * Assert that an expression is true, return (void) if it isn't.
+ * Strict builds will hit a breakpoint, non-strict will only do LogRel.
+ *
+ * @param   expr    Expression which should be true.
+ * @param   a       printf argument list (in parenthesis).
+ */
+#define AssertLogRelMsgReturnVoid(expr, a) \
+    do { \
+        if (RT_LIKELY(!!(expr))) \
+        { /* likely */ } \
+        else\
+        { \
+            RTAssertLogRelMsg1(#expr, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+            RTAssertLogRelMsg2(a); \
+            RTAssertPanic(); \
+            return; \
+        } \
+    } while (0)
+
+/** @def AssertLogRelMsgBreak
+ * Assert that an expression is true, break if it isn't.
+ * Strict builds will hit a breakpoint, non-strict will only do LogRel.
+ *
+ * @param   expr    Expression which should be true.
+ * @param   a       printf argument list (in parenthesis).
+ */
+#define AssertLogRelMsgBreak(expr, a) \
+    if (RT_LIKELY(!!(expr))) \
+    { /* likely */ } \
+    else if (1) \
+    { \
+        RTAssertLogRelMsg1(#expr, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+        RTAssertLogRelMsg2(a); \
+        RTAssertPanic(); \
+        break; \
+    } \
+    else do {} while (0)
+
+/** @def AssertLogRelMsgBreakStmt
+ * Assert that an expression is true, execute \a stmt and break if it isn't.
+ * Strict builds will hit a breakpoint, non-strict will only do LogRel.
+ *
+ * @param   expr    Expression which should be true.
+ * @param   a       printf argument list (in parenthesis).
+ * @param   stmt    Statement to execute before break in case of a failed assertion.
+ */
+#define AssertLogRelMsgBreakStmt(expr, a, stmt) \
+    if (RT_LIKELY(!!(expr))) \
+    { /* likely */ } \
+    else if (1) \
+    { \
+        RTAssertLogRelMsg1(#expr, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+        RTAssertLogRelMsg2(a); \
+        RTAssertPanic(); \
+        stmt; \
+        break; \
+    } else do {} while (0)
+
+/** @def AssertLogRelFailed
+ * An assertion failed.
+ * Strict builds will hit a breakpoint, non-strict will only do LogRel.
+ */
+#define AssertLogRelFailed() \
+    do { \
+        RTAssertLogRelMsg1((const char *)0, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+        RTAssertPanic(); \
+    } while (0)
+
+/** @def AssertLogRelFailedReturn
+ * An assertion failed.
+ * Strict builds will hit a breakpoint, non-strict will only do LogRel.
+ *
+ * @param   rc      What is to be presented to return.
+ */
+#define AssertLogRelFailedReturn(rc) \
+    do { \
+        RTAssertLogRelMsg1((const char *)0, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+        RTAssertPanic(); \
+        return (rc); \
+    } while (0)
+
+/** @def AssertLogRelFailedReturnVoid
+ * An assertion failed, hit a breakpoint and return.
+ * Strict builds will hit a breakpoint, non-strict will only do LogRel.
+ */
+#define AssertLogRelFailedReturnVoid() \
+    do { \
+        RTAssertLogRelMsg1((const char *)0, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+        RTAssertPanic(); \
+        return; \
+    } while (0)
+
+/** @def AssertLogRelFailedBreak
+ * An assertion failed, break.
+ * Strict builds will hit a breakpoint, non-strict will only do LogRel.
+ */
+#define AssertLogRelFailedBreak() \
+    if (1) \
+    { \
+        RTAssertLogRelMsg1((const char *)0, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+        RTAssertPanic(); \
+        break; \
+    } else do {} while (0)
+
+/** @def AssertLogRelFailedBreakStmt
+ * An assertion failed, execute \a stmt and break.
+ * Strict builds will hit a breakpoint, non-strict will only do LogRel.
+ *
+ * @param   stmt    Statement to execute before break.
+ */
+#define AssertLogRelFailedBreakStmt(stmt) \
+    if (1) \
+    { \
+        RTAssertLogRelMsg1((const char *)0, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+        RTAssertPanic(); \
+        stmt; \
+        break; \
+    } else do {} while (0)
+
+/** @def AssertLogRelMsgFailed
+ * An assertion failed.
+ * Strict builds will hit a breakpoint, non-strict will only do LogRel.
+ *
+ * @param   a   printf argument list (in parenthesis).
+ */
+#define AssertLogRelMsgFailed(a) \
+    do { \
+        RTAssertLogRelMsg1((const char *)0, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+        RTAssertLogRelMsg2(a); \
+        RTAssertPanic(); \
+    } while (0)
+
+/** @def AssertLogRelMsgFailedStmt
+ * An assertion failed, execute @a stmt.
+ *
+ * Strict builds will hit a breakpoint, non-strict will only do LogRel. The
+ * statement will be executed in regardless of build type.
+ *
+ * @param   a       printf argument list (in parenthesis).
+ * @param   stmt    Statement to execute after raising/logging the assertion.
+ */
+#define AssertLogRelMsgFailedStmt(a, stmt) \
+    do { \
+        RTAssertLogRelMsg1((const char *)0, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+        RTAssertLogRelMsg2(a); \
+        RTAssertPanic(); \
+        stmt; \
+    } while (0)
+
+/** @def AssertLogRelMsgFailedReturn
+ * An assertion failed, return \a rc.
+ * Strict builds will hit a breakpoint, non-strict will only do LogRel.
+ *
+ * @param   a   printf argument list (in parenthesis).
+ * @param   rc  What is to be presented to return.
+ */
+#define AssertLogRelMsgFailedReturn(a, rc) \
+    do { \
+        RTAssertLogRelMsg1((const char *)0, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+        RTAssertLogRelMsg2(a); \
+        RTAssertPanic(); \
+        return (rc); \
+    } while (0)
+
+/** @def AssertLogRelMsgFailedReturnStmt
+ * An assertion failed, execute @a stmt and return @a rc.
+ * Strict builds will hit a breakpoint, non-strict will only do LogRel.
+ *
+ * @param   a       printf argument list (in parenthesis).
+ * @param   stmt    Statement to execute before returning in case of a failed
+ *                  assertion.
+ * @param   rc      What is to be presented to return.
+ */
+#define AssertLogRelMsgFailedReturnStmt(a, stmt, rc) \
+    do { \
+        RTAssertLogRelMsg1((const char *)0, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+        RTAssertLogRelMsg2(a); \
+        RTAssertPanic(); \
+        stmt; \
+        return (rc); \
+    } while (0)
+
+/** @def AssertLogRelMsgFailedReturnVoid
+ * An assertion failed, return void.
+ * Strict builds will hit a breakpoint, non-strict will only do LogRel.
+ *
+ * @param   a   printf argument list (in parenthesis).
+ */
+#define AssertLogRelMsgFailedReturnVoid(a) \
+    do { \
+        RTAssertLogRelMsg1((const char *)0, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+        RTAssertLogRelMsg2(a); \
+        RTAssertPanic(); \
+        return; \
+    } while (0)
+
+/** @def AssertLogRelMsgFailedReturnVoidStmt
+ * An assertion failed, execute @a stmt and return void.
+ * Strict builds will hit a breakpoint, non-strict will only do LogRel.
+ *
+ * @param   a       printf argument list (in parenthesis).
+ * @param   stmt    Statement to execute before returning in case of a failed
+ *                  assertion.
+ */
+#define AssertLogRelMsgFailedReturnVoidStmt(a, stmt) \
+    do { \
+        RTAssertLogRelMsg1((const char *)0, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+        RTAssertLogRelMsg2(a); \
+        RTAssertPanic(); \
+        stmt; \
+        return; \
+    } while (0)
+
+/** @def AssertLogRelMsgFailedBreak
+ * An assertion failed, break.
+ * Strict builds will hit a breakpoint, non-strict will only do LogRel.
+ *
+ * @param   a   printf argument list (in parenthesis).
+ */
+#define AssertLogRelMsgFailedBreak(a) \
+    if (1)\
+    { \
+        RTAssertLogRelMsg1((const char *)0, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+        RTAssertLogRelMsg2(a); \
+        RTAssertPanic(); \
+        break; \
+    } else do {} while (0)
+
+/** @def AssertLogRelMsgFailedBreakStmt
+ * An assertion failed, execute \a stmt and break.
+ * Strict builds will hit a breakpoint, non-strict will only do LogRel.
+ *
+ * @param   a   printf argument list (in parenthesis).
+ * @param   stmt    Statement to execute before break.
+ */
+#define AssertLogRelMsgFailedBreakStmt(a, stmt) \
+    if (1) \
+    { \
+        RTAssertLogRelMsg1((const char *)0, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+        RTAssertLogRelMsg2(a); \
+        RTAssertPanic(); \
+        stmt; \
+        break; \
+    } else do {} while (0)
+
+/** @} */
+
+
+
+/** @name Release Assertions
+ *
+ * These assertions are always enabled.
+ * @{
+ */
+
+/** @def RTAssertReleasePanic()
+ * Invokes RTAssertShouldPanic and RTAssertDoPanic.
+ *
+ * It might seem odd that RTAssertShouldPanic is necessary when its result isn't
+ * checked, but it's done since RTAssertShouldPanic is overrideable and might be
+ * used to bail out before taking down the system (the VMMR0 case).
+ */
+#define RTAssertReleasePanic()   do { RTAssertShouldPanic(); RTAssertDoPanic(); } while (0)
+
+
+/** @def AssertRelease
+ * Assert that an expression is true. If it's not hit a breakpoint.
+ *
+ * @param   expr    Expression which should be true.
+ */
+#define AssertRelease(expr)  \
+    do { \
+        if (RT_LIKELY(!!(expr))) \
+        { /* likely */ } \
+        else \
+        { \
+            RTAssertMsg1Weak(#expr, __LINE__, __FILE__, RT_GCC_EXTENSION __PRETTY_FUNCTION__); \
+            RTAssertReleasePanic(); \
+        } \
+    } while (0)
+
+/** @def AssertReleaseReturn
+ * Assert that an expression is true, hit a breakpoint and return if it isn't.
+ *
+ * @param   expr    Expression which should be true.
+ * @param   rc      What is to be presented to return.
+ */
+#define AssertReleaseReturn(expr, rc)  \
+    do { \
+        if (RT_LIKELY(!!(expr))) \
+        { /* likely */ } \
+        else \
+        { \
+            RTAssertMsg1Weak(#expr, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+            RTAssertReleasePanic(); \
+            return (rc); \
+        } \
+    } while (0)
+
+/** @def AssertReleaseReturnVoid
+ * Assert that an expression is true, hit a breakpoint and return if it isn't.
+ *
+ * @param   expr    Expression which should be true.
+ */
+#define AssertReleaseReturnVoid(expr)  \
+    do { \
+        if (RT_LIKELY(!!(expr))) \
+        { /* likely */ } \
+        else \
+        { \
+            RTAssertMsg1Weak(#expr, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+            RTAssertReleasePanic(); \
+            return; \
+        } \
+    } while (0)
+
+
+/** @def AssertReleaseBreak
+ * Assert that an expression is true, hit a breakpoint and break if it isn't.
+ *
+ * @param   expr    Expression which should be true.
+ */
+#define AssertReleaseBreak(expr)  \
+    if (RT_LIKELY(!!(expr))) \
+    { /* likely */ } \
+    else if (1) \
+    { \
+        RTAssertMsg1Weak(#expr, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+        RTAssertReleasePanic(); \
+        break; \
+    } else do {} while (0)
+
+/** @def AssertReleaseBreakStmt
+ * Assert that an expression is true, hit a breakpoint and break if it isn't.
+ *
+ * @param   expr    Expression which should be true.
+ * @param   stmt    Statement to execute before break in case of a failed assertion.
+ */
+#define AssertReleaseBreakStmt(expr, stmt)  \
+    if (RT_LIKELY(!!(expr))) \
+    { /* likely */ } \
+    else if (1) \
+    { \
+        RTAssertMsg1Weak(#expr, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+        RTAssertReleasePanic(); \
+        stmt; \
+        break; \
+    } else do {} while (0)
+
+
+/** @def AssertReleaseMsg
+ * Assert that an expression is true, print the message and hit a breakpoint if it isn't.
+ *
+ * @param   expr    Expression which should be true.
+ * @param   a       printf argument list (in parenthesis).
+ */
+#define AssertReleaseMsg(expr, a)  \
+    do { \
+        if (RT_LIKELY(!!(expr))) \
+        { /* likely */ } \
+        else \
+        { \
+            RTAssertMsg1Weak(#expr, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+            RTAssertMsg2Weak a; \
+            RTAssertReleasePanic(); \
+        } \
+    } while (0)
+
+/** @def AssertReleaseMsgReturn
+ * Assert that an expression is true, print the message and hit a breakpoint and return if it isn't.
+ *
+ * @param   expr    Expression which should be true.
+ * @param   a       printf argument list (in parenthesis).
+ * @param   rc      What is to be presented to return.
+ */
+#define AssertReleaseMsgReturn(expr, a, rc)  \
+    do { \
+        if (RT_LIKELY(!!(expr))) \
+        { /* likely */ } \
+        else \
+        { \
+            RTAssertMsg1Weak(#expr, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+            RTAssertMsg2Weak a; \
+            RTAssertReleasePanic(); \
+            return (rc); \
+        } \
+    } while (0)
+
+/** @def AssertReleaseMsgReturnVoid
+ * Assert that an expression is true, print the message and hit a breakpoint and return if it isn't.
+ *
+ * @param   expr    Expression which should be true.
+ * @param   a       printf argument list (in parenthesis).
+ */
+#define AssertReleaseMsgReturnVoid(expr, a)  \
+    do { \
+        if (RT_LIKELY(!!(expr))) \
+        { /* likely */ } \
+        else \
+        { \
+            RTAssertMsg1Weak(#expr, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+            RTAssertMsg2Weak a; \
+            RTAssertReleasePanic(); \
+            return; \
+        } \
+    } while (0)
+
+
+/** @def AssertReleaseMsgBreak
+ * Assert that an expression is true, print the message and hit a breakpoint and break if it isn't.
+ *
+ * @param   expr    Expression which should be true.
+ * @param   a       printf argument list (in parenthesis).
+ */
+#define AssertReleaseMsgBreak(expr, a)  \
+    if (RT_LIKELY(!!(expr))) \
+    { /* likely */ } \
+    else if (1) \
+    { \
+        RTAssertMsg1Weak(#expr, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+        RTAssertMsg2Weak a; \
+        RTAssertReleasePanic(); \
+        break; \
+    } else do {} while (0)
+
+/** @def AssertReleaseMsgBreakStmt
+ * Assert that an expression is true, print the message and hit a breakpoint and break if it isn't.
+ *
+ * @param   expr    Expression which should be true.
+ * @param   a       printf argument list (in parenthesis).
+ * @param   stmt    Statement to execute before break in case of a failed assertion.
+ */
+#define AssertReleaseMsgBreakStmt(expr, a, stmt)  \
+    if (RT_LIKELY(!!(expr))) \
+    { /* likely */ } \
+    else if (1) \
+    { \
+        RTAssertMsg1Weak(#expr, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+        RTAssertMsg2Weak a; \
+        RTAssertReleasePanic(); \
+        stmt; \
+        break; \
+    } else do {} while (0)
+
+
+/** @def AssertReleaseFailed
+ * An assertion failed, hit a breakpoint.
+ */
+#define AssertReleaseFailed()  \
+    do { \
+        RTAssertMsg1Weak((const char *)0, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+        RTAssertReleasePanic(); \
+    } while (0)
+
+/** @def AssertReleaseFailedReturn
+ * An assertion failed, hit a breakpoint and return.
+ *
+ * @param   rc      What is to be presented to return.
+ */
+#define AssertReleaseFailedReturn(rc)  \
+    do { \
+        RTAssertMsg1Weak((const char *)0, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+        RTAssertReleasePanic(); \
+        return (rc); \
+    } while (0)
+
+/** @def AssertReleaseFailedReturnVoid
+ * An assertion failed, hit a breakpoint and return.
+ */
+#define AssertReleaseFailedReturnVoid()  \
+    do { \
+        RTAssertMsg1Weak((const char *)0, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+        RTAssertReleasePanic(); \
+        return; \
+    } while (0)
+
+
+/** @def AssertReleaseFailedBreak
+ * An assertion failed, hit a breakpoint and break.
+ */
+#define AssertReleaseFailedBreak()  \
+    if (1) { \
+        RTAssertMsg1Weak((const char *)0, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+        RTAssertReleasePanic(); \
+        break; \
+    } else do {} while (0)
+
+/** @def AssertReleaseFailedBreakStmt
+ * An assertion failed, hit a breakpoint and break.
+ *
+ * @param   stmt    Statement to execute before break.
+ */
+#define AssertReleaseFailedBreakStmt(stmt)  \
+    if (1) { \
+        RTAssertMsg1Weak((const char *)0, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+        RTAssertReleasePanic(); \
+        stmt; \
+        break; \
+    } else do {} while (0)
+
+
+/** @def AssertReleaseMsgFailed
+ * An assertion failed, print a message and hit a breakpoint.
+ *
+ * @param   a   printf argument list (in parenthesis).
+ */
+#define AssertReleaseMsgFailed(a)  \
+    do { \
+        RTAssertMsg1Weak((const char *)0, __LINE__, __FILE__, RT_GCC_EXTENSION __PRETTY_FUNCTION__); \
+        RTAssertMsg2Weak a; \
+        RTAssertReleasePanic(); \
+    } while (0)
+
+/** @def AssertReleaseMsgFailedReturn
+ * An assertion failed, print a message, hit a breakpoint and return.
+ *
+ * @param   a   printf argument list (in parenthesis).
+ * @param   rc      What is to be presented to return.
+ */
+#define AssertReleaseMsgFailedReturn(a, rc) \
+    do { \
+        RTAssertMsg1Weak((const char *)0, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+        RTAssertMsg2Weak a; \
+        RTAssertReleasePanic(); \
+        return (rc); \
+    } while (0)
+
+/** @def AssertReleaseMsgFailedReturnVoid
+ * An assertion failed, print a message, hit a breakpoint and return.
+ *
+ * @param   a   printf argument list (in parenthesis).
+ */
+#define AssertReleaseMsgFailedReturnVoid(a) \
+    do { \
+        RTAssertMsg1Weak((const char *)0, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+        RTAssertMsg2Weak a; \
+        RTAssertReleasePanic(); \
+        return; \
+    } while (0)
+
+
+/** @def AssertReleaseMsgFailedBreak
+ * An assertion failed, print a message, hit a breakpoint and break.
+ *
+ * @param   a   printf argument list (in parenthesis).
+ */
+#define AssertReleaseMsgFailedBreak(a) \
+    if (1) { \
+        RTAssertMsg1Weak((const char *)0, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+        RTAssertMsg2Weak a; \
+        RTAssertReleasePanic(); \
+        break; \
+    } else do {} while (0)
+
+/** @def AssertReleaseMsgFailedBreakStmt
+ * An assertion failed, print a message, hit a breakpoint and break.
+ *
+ * @param   a   printf argument list (in parenthesis).
+ * @param   stmt    Statement to execute before break.
+ */
+#define AssertReleaseMsgFailedBreakStmt(a, stmt) \
+    if (1) { \
+        RTAssertMsg1Weak((const char *)0, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+        RTAssertMsg2Weak a; \
+        RTAssertReleasePanic(); \
+        stmt; \
+        break; \
+    } else do {} while (0)
+
+/** @} */
+
+
+
+/** @name Fatal Assertions
+ * These are similar to release assertions except that you cannot ignore them in
+ * any way, they will loop for ever if RTAssertDoPanic returns.
+ *
+ * @{
+ */
+
+/** @def AssertFatal
+ * Assert that an expression is true. If it's not hit a breakpoint (for ever).
+ *
+ * @param   expr    Expression which should be true.
+ */
+#define AssertFatal(expr)  \
+    do { \
+        if (RT_LIKELY(!!(expr))) \
+        { /* likely */ } \
+        else \
+            for (;;) \
+            { \
+                RTAssertMsg1Weak(#expr, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+                RTAssertReleasePanic(); \
+            } \
+    } while (0)
+
+/** @def AssertFatalMsg
+ * Assert that an expression is true, print the message and hit a breakpoint (for ever) if it isn't.
+ *
+ * @param   expr    Expression which should be true.
+ * @param   a       printf argument list (in parenthesis).
+ */
+#define AssertFatalMsg(expr, a)  \
+    do { \
+        if (RT_LIKELY(!!(expr))) \
+        { /* likely */ } \
+        else \
+            for (;;) \
+            { \
+                RTAssertMsg1Weak(#expr, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+                RTAssertMsg2Weak a; \
+                RTAssertReleasePanic(); \
+            } \
+    } while (0)
+
+/** @def AssertFatalFailed
+ * An assertion failed, hit a breakpoint (for ever).
+ */
+#define AssertFatalFailed()  \
+    do { \
+        for (;;) \
+        { \
+            RTAssertMsg1Weak((const char *)0, __LINE__, __FILE__, RT_GCC_EXTENSION __PRETTY_FUNCTION__); \
+            RTAssertReleasePanic(); \
+        } \
+    } while (0)
+
+/** @def AssertFatalMsgFailed
+ * An assertion failed, print a message and hit a breakpoint (for ever).
+ *
+ * @param   a   printf argument list (in parenthesis).
+ */
+#define AssertFatalMsgFailed(a)  \
+    do { \
+        for (;;) \
+        { \
+            RTAssertMsg1Weak((const char *)0, __LINE__, __FILE__, RT_GCC_EXTENSION __PRETTY_FUNCTION__); \
+            RTAssertMsg2Weak a; \
+            RTAssertReleasePanic(); \
+        } \
+    } while (0)
+
+/** @} */
+
+
+
+/** @name Convenience Assertions Macros
+ * @{
+ */
+
+/** @def AssertRC
+ * Asserts a iprt status code successful.
+ *
+ * On failure it will print info about the rc and hit a breakpoint.
+ *
+ * @param   rc  iprt status code.
+ * @remark  rc is referenced multiple times. In release mode is NOREF()'ed.
+ */
+#define AssertRC(rc)                AssertMsgRC(rc, ("%Rra\n", (rc)))
+
+/** @def AssertRCReturn
+ * Asserts a iprt status code successful, bitch (RT_STRICT mode only) and return if it isn't.
+ *
+ * @param   rc      iprt status code.
+ * @param   rcRet   What is to be presented to return.
+ * @remark  rc is referenced multiple times. In release mode is NOREF()'ed.
+ */
+#define AssertRCReturn(rc, rcRet)   AssertMsgRCReturn(rc, ("%Rra\n", (rc)), rcRet)
+
+/** @def AssertRCReturnStmt
+ * Asserts a iprt status code successful, bitch (RT_STRICT mode only), execute
+ * @a stmt and returns @a rcRet if it isn't.
+ *
+ * @param   rc      iprt status code.
+ * @param   stmt    Statement to execute before returning in case of a failed
+ *                  assertion.
+ * @param   rcRet   What is to be presented to return.
+ * @remark  rc is referenced multiple times. In release mode is NOREF()'ed.
+ */
+#define AssertRCReturnStmt(rc, stmt, rcRet) AssertMsgRCReturnStmt(rc, ("%Rra\n", (rc)), stmt, rcRet)
+
+/** @def AssertRCReturnVoid
+ * Asserts a iprt status code successful, bitch (RT_STRICT mode only) and return if it isn't.
+ *
+ * @param   rc      iprt status code.
+ * @remark  rc is referenced multiple times. In release mode is NOREF()'ed.
+ */
+#define AssertRCReturnVoid(rc)      AssertMsgRCReturnVoid(rc, ("%Rra\n", (rc)))
+
+/** @def AssertRCReturnVoidStmt
+ * Asserts a iprt status code successful, bitch (RT_STRICT mode only), and
+ * execute the given statement/return if it isn't.
+ *
+ * @param   rc      iprt status code.
+ * @param   stmt    Statement to execute before returning on failure.
+ * @remark  rc is referenced multiple times. In release mode is NOREF()'ed.
+ */
+#define AssertRCReturnVoidStmt(rc, stmt) AssertMsgRCReturnVoidStmt(rc, ("%Rra\n", (rc)), stmt)
+
+/** @def AssertRCBreak
+ * Asserts a iprt status code successful, bitch (RT_STRICT mode only) and break if it isn't.
+ *
+ * @param   rc      iprt status code.
+ * @remark  rc is referenced multiple times. In release mode is NOREF()'ed.
+ */
+#define AssertRCBreak(rc)           AssertMsgRCBreak(rc, ("%Rra\n", (rc)))
+
+/** @def AssertRCBreakStmt
+ * Asserts a iprt status code successful, bitch (RT_STRICT mode only) and break if it isn't.
+ *
+ * @param   rc      iprt status code.
+ * @param   stmt    Statement to execute before break in case of a failed assertion.
+ * @remark  rc is referenced multiple times. In release mode is NOREF()'ed.
+ */
+#define AssertRCBreakStmt(rc, stmt) AssertMsgRCBreakStmt(rc, ("%Rra\n", (rc)), stmt)
+
+/** @def AssertMsgRC
+ * Asserts a iprt status code successful.
+ *
+ * It prints a custom message and hits a breakpoint on FAILURE.
+ *
+ * @param   rc      iprt status code.
+ * @param   msg     printf argument list (in parenthesis).
+ * @remark  rc is referenced multiple times. In release mode is NOREF()'ed.
+ */
+#define AssertMsgRC(rc, msg) \
+    do { AssertMsg(RT_SUCCESS_NP(rc), msg); NOREF(rc); } while (0)
+
+/** @def AssertMsgRCReturn
+ * Asserts a iprt status code successful and if it's not return the specified status code.
+ *
+ * If RT_STRICT is defined the message will be printed and a breakpoint hit before it returns
+ *
+ * @param   rc      iprt status code.
+ * @param   msg     printf argument list (in parenthesis).
+ * @param   rcRet   What is to be presented to return.
+ * @remark  rc is referenced multiple times. In release mode is NOREF()'ed.
+ */
+#define AssertMsgRCReturn(rc, msg, rcRet) \
+    do { AssertMsgReturn(RT_SUCCESS_NP(rc), msg, rcRet); NOREF(rc); } while (0)
+
+/** @def AssertMsgRCReturnStmt
+ * Asserts a iprt status code successful and if it's not execute @a stmt and
+ * return the specified status code (@a rcRet).
+ *
+ * If RT_STRICT is defined the message will be printed and a breakpoint hit before it returns
+ *
+ * @param   rc      iprt status code.
+ * @param   msg     printf argument list (in parenthesis).
+ * @param   stmt    Statement to execute before returning in case of a failed
+ *                  assertion.
+ * @param   rcRet   What is to be presented to return.
+ * @remark  rc is referenced multiple times. In release mode is NOREF()'ed.
+ */
+#define AssertMsgRCReturnStmt(rc, msg, stmt, rcRet) \
+    do { AssertMsgReturnStmt(RT_SUCCESS_NP(rc), msg, stmt, rcRet); NOREF(rc); } while (0)
+
+/** @def AssertMsgRCReturnVoid
+ * Asserts a iprt status code successful and if it's not return.
+ *
+ * If RT_STRICT is defined the message will be printed and a breakpoint hit before it returns
+ *
+ * @param   rc      iprt status code.
+ * @param   msg     printf argument list (in parenthesis).
+ * @remark  rc is referenced multiple times. In release mode is NOREF()'ed.
+ */
+#define AssertMsgRCReturnVoid(rc, msg) \
+    do { AssertMsgReturnVoid(RT_SUCCESS_NP(rc), msg); NOREF(rc); } while (0)
+
+/** @def AssertMsgRCReturnVoidStmt
+ * Asserts a iprt status code successful and execute statement/break if it's not.
+ *
+ * If RT_STRICT is defined the message will be printed and a breakpoint hit before it returns
+ *
+ * @param   rc      iprt status code.
+ * @param   msg     printf argument list (in parenthesis).
+ * @param   stmt    Statement to execute before break in case of a failed assertion.
+ * @remark  rc is referenced multiple times. In release mode is NOREF()'ed.
+ */
+#define AssertMsgRCReturnVoidStmt(rc, msg, stmt) \
+    do { AssertMsgReturnVoidStmt(RT_SUCCESS_NP(rc), msg, stmt); NOREF(rc); } while (0)
+
+/** @def AssertMsgRCBreak
+ * Asserts a iprt status code successful and if it's not break.
+ *
+ * If RT_STRICT is defined the message will be printed and a breakpoint hit before it breaks
+ *
+ * @param   rc      iprt status code.
+ * @param   msg     printf argument list (in parenthesis).
+ * @remark  rc is referenced multiple times. In release mode is NOREF()'ed.
+ */
+#define AssertMsgRCBreak(rc, msg) \
+    if (1) { AssertMsgBreak(RT_SUCCESS(rc), msg); NOREF(rc); } else do {} while (0)
+
+/** @def AssertMsgRCBreakStmt
+ * Asserts a iprt status code successful and execute statement/break if it's not.
+ *
+ * If RT_STRICT is defined the message will be printed and a breakpoint hit before it returns
+ *
+ * @param   rc      iprt status code.
+ * @param   msg     printf argument list (in parenthesis).
+ * @param   stmt    Statement to execute before break in case of a failed assertion.
+ * @remark  rc is referenced multiple times. In release mode is NOREF()'ed.
+ */
+#define AssertMsgRCBreakStmt(rc, msg, stmt) \
+    if (1) { AssertMsgBreakStmt(RT_SUCCESS_NP(rc), msg, stmt); NOREF(rc); } else do {} while (0)
+
+/** @def AssertRCSuccess
+ * Asserts an iprt status code equals VINF_SUCCESS.
+ *
+ * On failure it will print info about the rc and hit a breakpoint.
+ *
+ * @param   rc  iprt status code.
+ * @remark  rc is referenced multiple times. In release mode is NOREF()'ed.
+ */
+#define AssertRCSuccess(rc)                 do { AssertMsg((rc) == VINF_SUCCESS, ("%Rra\n", (rc))); NOREF(rc); } while (0)
+
+/** @def AssertRCSuccessReturn
+ * Asserts that an iprt status code equals VINF_SUCCESS, bitch (RT_STRICT mode only) and return if it isn't.
+ *
+ * @param   rc      iprt status code.
+ * @param   rcRet   What is to be presented to return.
+ * @remark  rc is referenced multiple times. In release mode is NOREF()'ed.
+ */
+#define AssertRCSuccessReturn(rc, rcRet)    AssertMsgReturn((rc) == VINF_SUCCESS, ("%Rra\n", (rc)), rcRet)
+
+/** @def AssertRCSuccessReturnVoid
+ * Asserts that an iprt status code equals VINF_SUCCESS, bitch (RT_STRICT mode only) and return if it isn't.
+ *
+ * @param   rc      iprt status code.
+ * @remark  rc is referenced multiple times. In release mode is NOREF()'ed.
+ */
+#define AssertRCSuccessReturnVoid(rc)       AssertMsgReturnVoid((rc) == VINF_SUCCESS, ("%Rra\n", (rc)))
+
+/** @def AssertRCSuccessBreak
+ * Asserts that an iprt status code equals VINF_SUCCESS, bitch (RT_STRICT mode only) and break if it isn't.
+ *
+ * @param   rc      iprt status code.
+ * @remark  rc is referenced multiple times. In release mode is NOREF()'ed.
+ */
+#define AssertRCSuccessBreak(rc)            AssertMsgBreak((rc) == VINF_SUCCESS, ("%Rra\n", (rc)))
+
+/** @def AssertRCSuccessBreakStmt
+ * Asserts that an iprt status code equals VINF_SUCCESS, bitch (RT_STRICT mode only) and break if it isn't.
+ *
+ * @param   rc      iprt status code.
+ * @param   stmt    Statement to execute before break in case of a failed assertion.
+ * @remark  rc is referenced multiple times. In release mode is NOREF()'ed.
+ */
+#define AssertRCSuccessBreakStmt(rc, stmt)  AssertMsgBreakStmt((rc) == VINF_SUCCESS, ("%Rra\n", (rc)), stmt)
+
+
+/** @def AssertLogRelRC
+ * Asserts a iprt status code successful.
+ *
+ * @param   rc  iprt status code.
+ * @remark  rc is referenced multiple times.
+ */
+#define AssertLogRelRC(rc)                      AssertLogRelMsgRC(rc, ("%Rra\n", (rc)))
+
+/** @def AssertLogRelRCReturn
+ * Asserts a iprt status code successful, returning \a rc if it isn't.
+ *
+ * @param   rc      iprt status code.
+ * @param   rcRet   What is to be presented to return.
+ * @remark  rc is referenced multiple times.
+ */
+#define AssertLogRelRCReturn(rc, rcRet)         AssertLogRelMsgRCReturn(rc, ("%Rra\n", (rc)), rcRet)
+
+/** @def AssertLogRelRCReturnStmt
+ * Asserts a iprt status code successful, executing \a stmt and returning \a rc
+ * if it isn't.
+ *
+ * @param   rc      iprt status code.
+ * @param   stmt    Statement to execute before returning in case of a failed
+ *                  assertion.
+ * @param   rcRet   What is to be presented to return.
+ * @remark  rc is referenced multiple times.
+ */
+#define AssertLogRelRCReturnStmt(rc, stmt, rcRet) AssertLogRelMsgRCReturnStmt(rc, ("%Rra\n", (rc)), stmt, rcRet)
+
+/** @def AssertLogRelRCReturnVoid
+ * Asserts a iprt status code successful, returning (void) if it isn't.
+ *
+ * @param   rc      iprt status code.
+ * @remark  rc is referenced multiple times.
+ */
+#define AssertLogRelRCReturnVoid(rc)            AssertLogRelMsgRCReturnVoid(rc, ("%Rra\n", (rc)))
+
+/** @def AssertLogRelRCBreak
+ * Asserts a iprt status code successful, breaking if it isn't.
+ *
+ * @param   rc      iprt status code.
+ * @remark  rc is referenced multiple times.
+ */
+#define AssertLogRelRCBreak(rc)                 AssertLogRelMsgRCBreak(rc, ("%Rra\n", (rc)))
+
+/** @def AssertLogRelRCBreakStmt
+ * Asserts a iprt status code successful, execute \a statement and break if it isn't.
+ *
+ * @param   rc      iprt status code.
+ * @param   stmt    Statement to execute before break in case of a failed assertion.
+ * @remark  rc is referenced multiple times.
+ */
+#define AssertLogRelRCBreakStmt(rc, stmt)       AssertLogRelMsgRCBreakStmt(rc, ("%Rra\n", (rc)), stmt)
+
+/** @def AssertLogRelMsgRC
+ * Asserts a iprt status code successful.
+ *
+ * @param   rc      iprt status code.
+ * @param   msg     printf argument list (in parenthesis).
+ * @remark  rc is referenced multiple times.
+ */
+#define AssertLogRelMsgRC(rc, msg)              AssertLogRelMsg(RT_SUCCESS_NP(rc), msg)
+
+/** @def AssertLogRelMsgRCReturn
+ * Asserts a iprt status code successful.
+ *
+ * @param   rc      iprt status code.
+ * @param   msg     printf argument list (in parenthesis).
+ * @param   rcRet   What is to be presented to return.
+ * @remark  rc is referenced multiple times.
+ */
+#define AssertLogRelMsgRCReturn(rc, msg, rcRet) AssertLogRelMsgReturn(RT_SUCCESS_NP(rc), msg, rcRet)
+
+/** @def AssertLogRelMsgRCReturnStmt
+ * Asserts a iprt status code successful, execute \a stmt and return on
+ * failure.
+ *
+ * @param   rc      iprt status code.
+ * @param   msg     printf argument list (in parenthesis).
+ * @param   stmt    Statement to execute before returning in case of a failed
+ *                  assertion.
+ * @param   rcRet   What is to be presented to return.
+ * @remark  rc is referenced multiple times.
+ */
+#define AssertLogRelMsgRCReturnStmt(rc, msg, stmt, rcRet) AssertLogRelMsgReturnStmt(RT_SUCCESS_NP(rc), msg, stmt, rcRet)
+
+/** @def AssertLogRelMsgRCReturnVoid
+ * Asserts a iprt status code successful.
+ *
+ * @param   rc      iprt status code.
+ * @param   msg     printf argument list (in parenthesis).
+ * @remark  rc is referenced multiple times.
+ */
+#define AssertLogRelMsgRCReturnVoid(rc, msg)    AssertLogRelMsgReturnVoid(RT_SUCCESS_NP(rc), msg)
+
+/** @def AssertLogRelMsgRCBreak
+ * Asserts a iprt status code successful.
+ *
+ * @param   rc      iprt status code.
+ * @param   msg     printf argument list (in parenthesis).
+ * @remark  rc is referenced multiple times.
+ */
+#define AssertLogRelMsgRCBreak(rc, msg)         AssertLogRelMsgBreak(RT_SUCCESS(rc), msg)
+
+/** @def AssertLogRelMsgRCBreakStmt
+ * Asserts a iprt status code successful, execute \a stmt and break if it isn't.
+ *
+ * @param   rc      iprt status code.
+ * @param   msg     printf argument list (in parenthesis).
+ * @param   stmt    Statement to execute before break in case of a failed assertion.
+ * @remark  rc is referenced multiple times.
+ */
+#define AssertLogRelMsgRCBreakStmt(rc, msg, stmt) AssertLogRelMsgBreakStmt(RT_SUCCESS_NP(rc), msg, stmt)
+
+/** @def AssertLogRelRCSuccess
+ * Asserts that an iprt status code equals VINF_SUCCESS.
+ *
+ * @param   rc  iprt status code.
+ * @remark  rc is referenced multiple times.
+ */
+#define AssertLogRelRCSuccess(rc)               AssertLogRelMsg((rc) == VINF_SUCCESS, ("%Rra\n", (rc)))
+
+/** @def AssertLogRelRCSuccessReturn
+ * Asserts that an iprt status code equals VINF_SUCCESS.
+ *
+ * @param   rc      iprt status code.
+ * @param   rcRet   What is to be presented to return.
+ * @remark  rc is referenced multiple times.
+ */
+#define AssertLogRelRCSuccessReturn(rc, rcRet)  AssertLogRelMsgReturn((rc) == VINF_SUCCESS, ("%Rra\n", (rc)), rcRet)
+
+/** @def AssertLogRelRCSuccessReturnVoid
+ * Asserts that an iprt status code equals VINF_SUCCESS.
+ *
+ * @param   rc      iprt status code.
+ * @remark  rc is referenced multiple times.
+ */
+#define AssertLogRelRCSuccessReturnVoid(rc)     AssertLogRelMsgReturnVoid((rc) == VINF_SUCCESS, ("%Rra\n", (rc)))
+
+/** @def AssertLogRelRCSuccessBreak
+ * Asserts that an iprt status code equals VINF_SUCCESS.
+ *
+ * @param   rc      iprt status code.
+ * @remark  rc is referenced multiple times.
+ */
+#define AssertLogRelRCSuccessBreak(rc)          AssertLogRelMsgBreak((rc) == VINF_SUCCESS, ("%Rra\n", (rc)))
+
+/** @def AssertLogRelRCSuccessBreakStmt
+ * Asserts that an iprt status code equals VINF_SUCCESS.
+ *
+ * @param   rc      iprt status code.
+ * @param   stmt    Statement to execute before break in case of a failed assertion.
+ * @remark  rc is referenced multiple times.
+ */
+#define AssertLogRelRCSuccessBreakStmt(rc, stmt) AssertLogRelMsgBreakStmt((rc) == VINF_SUCCESS, ("%Rra\n", (rc)), stmt)
+
+
+/** @def AssertReleaseRC
+ * Asserts a iprt status code successful.
+ *
+ * On failure information about the error will be printed and a breakpoint hit.
+ *
+ * @param   rc  iprt status code.
+ * @remark  rc is referenced multiple times.
+ */
+#define AssertReleaseRC(rc)                 AssertReleaseMsgRC(rc, ("%Rra\n", (rc)))
+
+/** @def AssertReleaseRCReturn
+ * Asserts a iprt status code successful, returning if it isn't.
+ *
+ * On failure information about the error will be printed, a breakpoint hit
+ * and finally returning from the function if the breakpoint is somehow ignored.
+ *
+ * @param   rc      iprt status code.
+ * @param   rcRet   What is to be presented to return.
+ * @remark  rc is referenced multiple times.
+ */
+#define AssertReleaseRCReturn(rc, rcRet)    AssertReleaseMsgRCReturn(rc, ("%Rra\n", (rc)), rcRet)
+
+/** @def AssertReleaseRCReturnVoid
+ * Asserts a iprt status code successful, returning if it isn't.
+ *
+ * On failure information about the error will be printed, a breakpoint hit
+ * and finally returning from the function if the breakpoint is somehow ignored.
+ *
+ * @param   rc      iprt status code.
+ * @remark  rc is referenced multiple times.
+ */
+#define AssertReleaseRCReturnVoid(rc)       AssertReleaseMsgRCReturnVoid(rc, ("%Rra\n", (rc)))
+
+/** @def AssertReleaseRCBreak
+ * Asserts a iprt status code successful, breaking if it isn't.
+ *
+ * On failure information about the error will be printed, a breakpoint hit
+ * and finally breaking the current statement if the breakpoint is somehow ignored.
+ *
+ * @param   rc      iprt status code.
+ * @remark  rc is referenced multiple times.
+ */
+#define AssertReleaseRCBreak(rc)            AssertReleaseMsgRCBreak(rc, ("%Rra\n", (rc)))
+
+/** @def AssertReleaseRCBreakStmt
+ * Asserts a iprt status code successful, break if it isn't.
+ *
+ * On failure information about the error will be printed, a breakpoint hit
+ * and finally the break statement will be issued if the breakpoint is somehow ignored.
+ *
+ * @param   rc      iprt status code.
+ * @param   stmt    Statement to execute before break in case of a failed assertion.
+ * @remark  rc is referenced multiple times.
+ */
+#define AssertReleaseRCBreakStmt(rc, stmt)  AssertReleaseMsgRCBreakStmt(rc, ("%Rra\n", (rc)), stmt)
+
+/** @def AssertReleaseMsgRC
+ * Asserts a iprt status code successful.
+ *
+ * On failure a custom message is printed and a breakpoint is hit.
+ *
+ * @param   rc      iprt status code.
+ * @param   msg     printf argument list (in parenthesis).
+ * @remark  rc is referenced multiple times.
+ */
+#define AssertReleaseMsgRC(rc, msg)         AssertReleaseMsg(RT_SUCCESS_NP(rc), msg)
+
+/** @def AssertReleaseMsgRCReturn
+ * Asserts a iprt status code successful.
+ *
+ * On failure a custom message is printed, a breakpoint is hit, and finally
+ * returning from the function if the breakpoint is somehow ignored.
+ *
+ * @param   rc      iprt status code.
+ * @param   msg     printf argument list (in parenthesis).
+ * @param   rcRet   What is to be presented to return.
+ * @remark  rc is referenced multiple times.
+ */
+#define AssertReleaseMsgRCReturn(rc, msg, rcRet)    AssertReleaseMsgReturn(RT_SUCCESS_NP(rc), msg, rcRet)
+
+/** @def AssertReleaseMsgRCReturnVoid
+ * Asserts a iprt status code successful.
+ *
+ * On failure a custom message is printed, a breakpoint is hit, and finally
+ * returning from the function if the breakpoint is somehow ignored.
+ *
+ * @param   rc      iprt status code.
+ * @param   msg     printf argument list (in parenthesis).
+ * @remark  rc is referenced multiple times.
+ */
+#define AssertReleaseMsgRCReturnVoid(rc, msg)    AssertReleaseMsgReturnVoid(RT_SUCCESS_NP(rc), msg)
+
+/** @def AssertReleaseMsgRCBreak
+ * Asserts a iprt status code successful.
+ *
+ * On failure a custom message is printed, a breakpoint is hit, and finally
+ * breaking the current status if the breakpoint is somehow ignored.
+ *
+ * @param   rc      iprt status code.
+ * @param   msg     printf argument list (in parenthesis).
+ * @remark  rc is referenced multiple times.
+ */
+#define AssertReleaseMsgRCBreak(rc, msg)        AssertReleaseMsgBreak(RT_SUCCESS(rc), msg)
+
+/** @def AssertReleaseMsgRCBreakStmt
+ * Asserts a iprt status code successful.
+ *
+ * On failure a custom message is printed, a breakpoint is hit, and finally
+ * the break statement is issued if the breakpoint is somehow ignored.
+ *
+ * @param   rc      iprt status code.
+ * @param   msg     printf argument list (in parenthesis).
+ * @param   stmt    Statement to execute before break in case of a failed assertion.
+ * @remark  rc is referenced multiple times.
+ */
+#define AssertReleaseMsgRCBreakStmt(rc, msg, stmt)  AssertReleaseMsgBreakStmt(RT_SUCCESS_NP(rc), msg, stmt)
+
+/** @def AssertReleaseRCSuccess
+ * Asserts that an iprt status code equals VINF_SUCCESS.
+ *
+ * On failure information about the error will be printed and a breakpoint hit.
+ *
+ * @param   rc  iprt status code.
+ * @remark  rc is referenced multiple times.
+ */
+#define AssertReleaseRCSuccess(rc)                  AssertReleaseMsg((rc) == VINF_SUCCESS, ("%Rra\n", (rc)))
+
+/** @def AssertReleaseRCSuccessReturn
+ * Asserts that an iprt status code equals VINF_SUCCESS.
+ *
+ * On failure information about the error will be printed, a breakpoint hit
+ * and finally returning from the function if the breakpoint is somehow ignored.
+ *
+ * @param   rc      iprt status code.
+ * @param   rcRet   What is to be presented to return.
+ * @remark  rc is referenced multiple times.
+ */
+#define AssertReleaseRCSuccessReturn(rc, rcRet)     AssertReleaseMsgReturn((rc) == VINF_SUCCESS, ("%Rra\n", (rc)), rcRet)
+
+/** @def AssertReleaseRCSuccessReturnVoid
+ * Asserts that an iprt status code equals VINF_SUCCESS.
+ *
+ * On failure information about the error will be printed, a breakpoint hit
+ * and finally returning from the function if the breakpoint is somehow ignored.
+ *
+ * @param   rc      iprt status code.
+ * @remark  rc is referenced multiple times.
+ */
+#define AssertReleaseRCSuccessReturnVoid(rc)     AssertReleaseMsgReturnVoid((rc) == VINF_SUCCESS, ("%Rra\n", (rc)))
+
+/** @def AssertReleaseRCSuccessBreak
+ * Asserts that an iprt status code equals VINF_SUCCESS.
+ *
+ * On failure information about the error will be printed, a breakpoint hit
+ * and finally breaking the current statement if the breakpoint is somehow ignored.
+ *
+ * @param   rc      iprt status code.
+ * @remark  rc is referenced multiple times.
+ */
+#define AssertReleaseRCSuccessBreak(rc)         AssertReleaseMsgBreak((rc) == VINF_SUCCESS, ("%Rra\n", (rc)))
+
+/** @def AssertReleaseRCSuccessBreakStmt
+ * Asserts that an iprt status code equals VINF_SUCCESS.
+ *
+ * On failure information about the error will be printed, a breakpoint hit
+ * and finally the break statement will be issued if the breakpoint is somehow ignored.
+ *
+ * @param   rc      iprt status code.
+ * @param   stmt    Statement to execute before break in case of a failed assertion.
+ * @remark  rc is referenced multiple times.
+ */
+#define AssertReleaseRCSuccessBreakStmt(rc, stmt)   AssertReleaseMsgBreakStmt((rc) == VINF_SUCCESS, ("%Rra\n", (rc)), stmt)
+
+
+/** @def AssertFatalRC
+ * Asserts a iprt status code successful.
+ *
+ * On failure information about the error will be printed and a breakpoint hit.
+ *
+ * @param   rc  iprt status code.
+ * @remark  rc is referenced multiple times.
+ */
+#define AssertFatalRC(rc)               AssertFatalMsgRC(rc, ("%Rra\n", (rc)))
+
+/** @def AssertReleaseMsgRC
+ * Asserts a iprt status code successful.
+ *
+ * On failure a custom message is printed and a breakpoint is hit.
+ *
+ * @param   rc      iprt status code.
+ * @param   msg     printf argument list (in parenthesis).
+ * @remark  rc is referenced multiple times.
+ */
+#define AssertFatalMsgRC(rc, msg)       AssertFatalMsg(RT_SUCCESS_NP(rc), msg)
+
+/** @def AssertFatalRCSuccess
+ * Asserts that an iprt status code equals VINF_SUCCESS.
+ *
+ * On failure information about the error will be printed and a breakpoint hit.
+ *
+ * @param   rc  iprt status code.
+ * @remark  rc is referenced multiple times.
+ */
+#define AssertFatalRCSuccess(rc)        AssertFatalMsg((rc) == VINF_SUCCESS, ("%Rra\n", (rc)))
+
+
+/** @def AssertPtr
+ * Asserts that a pointer is valid.
+ *
+ * @param   pv      The pointer.
+ */
+#define AssertPtr(pv)                   AssertMsg(VALID_PTR(pv), ("%p\n", (pv)))
+
+/** @def AssertPtrReturn
+ * Asserts that a pointer is valid.
+ *
+ * @param   pv      The pointer.
+ * @param   rcRet   What is to be presented to return.
+ */
+#define AssertPtrReturn(pv, rcRet)      AssertMsgReturn(VALID_PTR(pv), ("%p\n", (pv)), rcRet)
+
+/** @def AssertPtrReturnVoid
+ * Asserts that a pointer is valid.
+ *
+ * @param   pv      The pointer.
+ */
+#define AssertPtrReturnVoid(pv)         AssertMsgReturnVoid(VALID_PTR(pv), ("%p\n", (pv)))
+
+/** @def AssertPtrBreak
+ * Asserts that a pointer is valid.
+ *
+ * @param   pv      The pointer.
+ */
+#define AssertPtrBreak(pv)              AssertMsgBreak(VALID_PTR(pv), ("%p\n", (pv)))
+
+/** @def AssertPtrBreakStmt
+ * Asserts that a pointer is valid.
+ *
+ * @param   pv      The pointer.
+ * @param   stmt    Statement to execute before break in case of a failed assertion.
+ */
+#define AssertPtrBreakStmt(pv, stmt)    AssertMsgBreakStmt(VALID_PTR(pv), ("%p\n", (pv)), stmt)
+
+/** @def AssertPtrNull
+ * Asserts that a pointer is valid or NULL.
+ *
+ * @param   pv      The pointer.
+ */
+#define AssertPtrNull(pv)               AssertMsg(VALID_PTR(pv) || (pv) == NULL, ("%p\n", (pv)))
+
+/** @def AssertPtrNullReturn
+ * Asserts that a pointer is valid or NULL.
+ *
+ * @param   pv      The pointer.
+ * @param   rcRet   What is to be presented to return.
+ */
+#define AssertPtrNullReturn(pv, rcRet)  AssertMsgReturn(VALID_PTR(pv) || (pv) == NULL, ("%p\n", (pv)), rcRet)
+
+/** @def AssertPtrNullReturnVoid
+ * Asserts that a pointer is valid or NULL.
+ *
+ * @param   pv      The pointer.
+ */
+#define AssertPtrNullReturnVoid(pv)     AssertMsgReturnVoid(VALID_PTR(pv) || (pv) == NULL, ("%p\n", (pv)))
+
+/** @def AssertPtrNullBreak
+ * Asserts that a pointer is valid or NULL.
+ *
+ * @param   pv      The pointer.
+ */
+#define AssertPtrNullBreak(pv)          AssertMsgBreak(VALID_PTR(pv) || (pv) == NULL, ("%p\n", (pv)))
+
+/** @def AssertPtrNullBreakStmt
+ * Asserts that a pointer is valid or NULL.
+ *
+ * @param   pv      The pointer.
+ * @param   stmt    Statement to execute before break in case of a failed assertion.
+ */
+#define AssertPtrNullBreakStmt(pv, stmt) AssertMsgBreakStmt(VALID_PTR(pv) || (pv) == NULL, ("%p\n", (pv)), stmt)
+
+/** @def AssertGCPhys32
+ * Asserts that the high dword of a physical address is zero
+ *
+ * @param   GCPhys      The address (RTGCPHYS).
+ */
+#define AssertGCPhys32(GCPhys)          AssertMsg(VALID_PHYS32(GCPhys), ("%RGp\n", (RTGCPHYS)(GCPhys)))
+
+/** @def AssertGCPtr32
+ * Asserts that the high dword of a physical address is zero
+ *
+ * @param   GCPtr       The address (RTGCPTR).
+ */
+#if GC_ARCH_BITS == 32
+# define AssertGCPtr32(GCPtr)           do { } while (0)
+#else
+# define AssertGCPtr32(GCPtr)           AssertMsg(!((GCPtr) & UINT64_C(0xffffffff00000000)), ("%RGv\n", GCPtr))
+#endif
+
+/** @def AssertForEach
+ * Equivalent to Assert for each value of the variable from the starting
+ * value to the finishing one.
+ *
+ * @param   var     Name of the counter variable.
+ * @param   vartype Type of the counter variable.
+ * @param   first   Lowest inclusive value of the counter variable.
+ *                  This must be free from side effects.
+ * @param   end     Highest exclusive value of the counter variable.
+ *                  This must be free from side effects.
+ * @param   expr    Expression which should be true for each value of @a var.
+ */
+#define AssertForEach(var, vartype, first, end, expr) \
+    do { \
+        vartype var; \
+        Assert((first) == (first) && (end) == (end)); /* partial check for side effects */ \
+        for (var = (first); var < (end); var++) \
+            AssertMsg(expr, ("%s = %#RX64 (%RI64)", #var, (uint64_t)var, (int64_t)var)); \
+    } while (0)
+
+/** @} */
+
+/** @} */
+
+#endif
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/include/iprt/avl.h
@@ -0,0 +1,1136 @@
+/** @file
+ * IPRT - AVL Trees.
+ */
+
+/*
+ * Copyright (C) 1999-2012 knut st. osmundsen <bird-src-spam@anduin.net>
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+#ifndef ___iprt_avl_h
+#define ___iprt_avl_h
+
+#include <iprt/cdefs.h>
+#include <iprt/types.h>
+
+RT_C_DECLS_BEGIN
+
+/** @defgroup grp_rt_avl    RTAvl - AVL Trees
+ * @ingroup grp_rt
+ * @{
+ */
+
+
+/** AVL tree of void pointers.
+ * @{
+ */
+
+/**
+ * AVL key type
+ */
+typedef void *  AVLPVKEY;
+
+/**
+ * AVL Core node.
+ */
+typedef struct _AVLPVNodeCore
+{
+    AVLPVKEY                Key;        /** Key value. */
+    struct _AVLPVNodeCore  *pLeft;      /** Pointer to left leaf node. */
+    struct _AVLPVNodeCore  *pRight;     /** Pointer to right leaf node. */
+    unsigned char           uchHeight;  /** Height of this tree: max(height(left), height(right)) + 1 */
+} AVLPVNODECORE, *PAVLPVNODECORE, **PPAVLPVNODECORE;
+
+/** A tree with void pointer keys. */
+typedef PAVLPVNODECORE     AVLPVTREE;
+/** Pointer to a tree with void pointer keys. */
+typedef PPAVLPVNODECORE    PAVLPVTREE;
+
+/** Callback function for AVLPVDoWithAll().
+ *  @returns IPRT status codes. */
+typedef DECLCALLBACK(int) AVLPVCALLBACK(PAVLPVNODECORE, void *);
+/** Pointer to callback function for AVLPVDoWithAll(). */
+typedef AVLPVCALLBACK *PAVLPVCALLBACK;
+
+/*
+ * Functions.
+ */
+RTDECL(bool)            RTAvlPVInsert(PAVLPVTREE ppTree, PAVLPVNODECORE pNode);
+RTDECL(PAVLPVNODECORE)  RTAvlPVRemove(PAVLPVTREE ppTree, AVLPVKEY Key);
+RTDECL(PAVLPVNODECORE)  RTAvlPVGet(PAVLPVTREE ppTree, AVLPVKEY Key);
+RTDECL(PAVLPVNODECORE)  RTAvlPVGetBestFit(PAVLPVTREE ppTree, AVLPVKEY Key, bool fAbove);
+RTDECL(PAVLPVNODECORE)  RTAvlPVRemoveBestFit(PAVLPVTREE ppTree, AVLPVKEY Key, bool fAbove);
+RTDECL(int)             RTAvlPVDoWithAll(PAVLPVTREE ppTree, int fFromLeft, PAVLPVCALLBACK pfnCallBack, void *pvParam);
+RTDECL(int)             RTAvlPVDestroy(PAVLPVTREE ppTree, PAVLPVCALLBACK pfnCallBack, void *pvParam);
+
+/** @} */
+
+
+/** AVL tree of unsigned long.
+ * @{
+ */
+
+/**
+ * AVL key type
+ */
+typedef unsigned long   AVLULKEY;
+
+/**
+ * AVL Core node.
+ */
+typedef struct _AVLULNodeCore
+{
+    AVLULKEY                Key;        /** Key value. */
+    struct _AVLULNodeCore  *pLeft;      /** Pointer to left leaf node. */
+    struct _AVLULNodeCore  *pRight;     /** Pointer to right leaf node. */
+    unsigned char           uchHeight;  /** Height of this tree: max(height(left), height(right)) + 1 */
+} AVLULNODECORE, *PAVLULNODECORE, **PPAVLULNODECORE;
+
+
+/** Callback function for AVLULDoWithAll().
+ *  @returns IPRT status codes. */
+typedef DECLCALLBACK(int) AVLULCALLBACK(PAVLULNODECORE, void*);
+/** Pointer to callback function for AVLULDoWithAll(). */
+typedef AVLULCALLBACK *PAVLULCALLBACK;
+
+
+/*
+ * Functions.
+ */
+RTDECL(bool)            RTAvlULInsert(PPAVLULNODECORE ppTree, PAVLULNODECORE pNode);
+RTDECL(PAVLULNODECORE)  RTAvlULRemove(PPAVLULNODECORE ppTree, AVLULKEY Key);
+RTDECL(PAVLULNODECORE)  RTAvlULGet(PPAVLULNODECORE ppTree, AVLULKEY Key);
+RTDECL(PAVLULNODECORE)  RTAvlULGetBestFit(PPAVLULNODECORE ppTree, AVLULKEY Key, bool fAbove);
+RTDECL(PAVLULNODECORE)  RTAvlULRemoveBestFit(PPAVLULNODECORE ppTree, AVLULKEY Key, bool fAbove);
+RTDECL(int)             RTAvlULDoWithAll(PPAVLULNODECORE ppTree, int fFromLeft, PAVLULCALLBACK pfnCallBack, void *pvParam);
+RTDECL(int)             RTAvlULDestroy(PPAVLULNODECORE pTree, PAVLULCALLBACK pfnCallBack, void *pvParam);
+
+/** @} */
+
+
+
+/** AVL tree of void pointer ranges.
+ * @{
+ */
+
+/**
+ * AVL key type
+ */
+typedef void *AVLRPVKEY;
+
+/**
+ * AVL Core node.
+ */
+typedef struct AVLRPVNodeCore
+{
+    AVLRPVKEY               Key;        /**< First key value in the range (inclusive). */
+    AVLRPVKEY               KeyLast;    /**< Last key value in the range (inclusive). */
+    struct AVLRPVNodeCore  *pLeft;      /**< Pointer to left leaf node. */
+    struct AVLRPVNodeCore  *pRight;     /**< Pointer to right leaf node. */
+    unsigned char           uchHeight;  /**< Height of this tree: max(height(left), height(right)) + 1 */
+} AVLRPVNODECORE, *PAVLRPVNODECORE, **PPAVLRPVNODECORE;
+
+/** A tree with void pointer keys. */
+typedef PAVLRPVNODECORE    AVLRPVTREE;
+/** Pointer to a tree with void pointer keys. */
+typedef PPAVLRPVNODECORE   PAVLRPVTREE;
+
+/** Callback function for AVLPVDoWithAll().
+ *  @returns IPRT status codes. */
+typedef DECLCALLBACK(int) AVLRPVCALLBACK(PAVLRPVNODECORE, void *);
+/** Pointer to callback function for AVLPVDoWithAll(). */
+typedef AVLRPVCALLBACK *PAVLRPVCALLBACK;
+
+/*
+ * Functions.
+ */
+RTDECL(bool)            RTAvlrPVInsert(PAVLRPVTREE ppTree, PAVLRPVNODECORE pNode);
+RTDECL(PAVLRPVNODECORE) RTAvlrPVRemove(PAVLRPVTREE ppTree, AVLRPVKEY Key);
+RTDECL(PAVLRPVNODECORE) RTAvlrPVGet(PAVLRPVTREE ppTree, AVLRPVKEY Key);
+RTDECL(PAVLRPVNODECORE) RTAvlrPVRangeGet(PAVLRPVTREE ppTree, AVLRPVKEY Key);
+RTDECL(PAVLRPVNODECORE) RTAvlrPVRangeRemove(PAVLRPVTREE ppTree, AVLRPVKEY Key);
+RTDECL(PAVLRPVNODECORE) RTAvlrPVGetBestFit(PAVLRPVTREE ppTree, AVLRPVKEY Key, bool fAbove);
+RTDECL(PAVLRPVNODECORE) RTAvlrPVRemoveBestFit(PAVLRPVTREE ppTree, AVLRPVKEY Key, bool fAbove);
+RTDECL(int)             RTAvlrPVDoWithAll(PAVLRPVTREE ppTree, int fFromLeft, PAVLRPVCALLBACK pfnCallBack, void *pvParam);
+RTDECL(int)             RTAvlrPVDestroy(PAVLRPVTREE ppTree, PAVLRPVCALLBACK pfnCallBack, void *pvParam);
+
+/** @} */
+
+
+
+/** AVL tree of uint32_t
+ * @{
+ */
+
+/** AVL key type. */
+typedef uint32_t    AVLU32KEY;
+
+/** AVL Core node. */
+typedef struct _AVLU32NodeCore
+{
+    AVLU32KEY               Key;        /**< Key value. */
+    struct _AVLU32NodeCore *pLeft;      /**< Pointer to left leaf node. */
+    struct _AVLU32NodeCore *pRight;     /**< Pointer to right leaf node. */
+    unsigned char           uchHeight;  /**< Height of this tree: max(height(left), height(right)) + 1 */
+} AVLU32NODECORE, *PAVLU32NODECORE, **PPAVLU32NODECORE;
+
+/** A tree with void pointer keys. */
+typedef PAVLU32NODECORE     AVLU32TREE;
+/** Pointer to a tree with void pointer keys. */
+typedef PPAVLU32NODECORE    PAVLU32TREE;
+
+/** Callback function for AVLU32DoWithAll() & AVLU32Destroy().
+ *  @returns IPRT status codes. */
+typedef DECLCALLBACK(int) AVLU32CALLBACK(PAVLU32NODECORE, void*);
+/** Pointer to callback function for AVLU32DoWithAll() & AVLU32Destroy(). */
+typedef AVLU32CALLBACK *PAVLU32CALLBACK;
+
+
+/*
+ * Functions.
+ */
+RTDECL(bool)            RTAvlU32Insert(PAVLU32TREE pTree, PAVLU32NODECORE pNode);
+RTDECL(PAVLU32NODECORE) RTAvlU32Remove(PAVLU32TREE pTree, AVLU32KEY Key);
+RTDECL(PAVLU32NODECORE) RTAvlU32Get(PAVLU32TREE pTree, AVLU32KEY Key);
+RTDECL(PAVLU32NODECORE) RTAvlU32GetBestFit(PAVLU32TREE pTree, AVLU32KEY Key, bool fAbove);
+RTDECL(PAVLU32NODECORE) RTAvlU32RemoveBestFit(PAVLU32TREE pTree, AVLU32KEY Key, bool fAbove);
+RTDECL(int)             RTAvlU32DoWithAll(PAVLU32TREE pTree, int fFromLeft, PAVLU32CALLBACK pfnCallBack, void *pvParam);
+RTDECL(int)             RTAvlU32Destroy(PAVLU32TREE pTree, PAVLU32CALLBACK pfnCallBack, void *pvParam);
+
+/** @} */
+
+/**
+ * AVL uint32_t type for the relative offset pointer scheme.
+ */
+typedef int32_t     AVLOU32;
+
+typedef uint32_t     AVLOU32KEY;
+
+/**
+ * AVL Core node.
+ */
+typedef struct _AVLOU32NodeCore
+{
+    /** Key value. */
+    AVLOU32KEY          Key;
+    /** Offset to the left leaf node, relative to this field. */
+    AVLOU32             pLeft;
+    /** Offset to the right leaf node, relative to this field. */
+    AVLOU32             pRight;
+    /** Height of this tree: max(height(left), height(right)) + 1 */
+    unsigned char       uchHeight;
+} AVLOU32NODECORE, *PAVLOU32NODECORE;
+
+/** A offset base tree with uint32_t keys. */
+typedef AVLOU32         AVLOU32TREE;
+/** Pointer to an offset base tree with uint32_t keys. */
+typedef AVLOU32TREE    *PAVLOU32TREE;
+
+/** Pointer to an internal tree pointer.
+ * In this case it's a pointer to a relative offset. */
+typedef AVLOU32TREE    *PPAVLOU32NODECORE;
+
+/** Callback function for RTAvloU32DoWithAll().
+ *  @returns IPRT status codes. */
+typedef DECLCALLBACK(int)   AVLOU32CALLBACK(PAVLOU32NODECORE pNode, void *pvUser);
+/** Pointer to callback function for RTAvloU32DoWithAll(). */
+typedef AVLOU32CALLBACK *PAVLOU32CALLBACK;
+
+RTDECL(bool)                  RTAvloU32Insert(PAVLOU32TREE pTree, PAVLOU32NODECORE pNode);
+RTDECL(PAVLOU32NODECORE)      RTAvloU32Remove(PAVLOU32TREE pTree, AVLOU32KEY Key);
+RTDECL(PAVLOU32NODECORE)      RTAvloU32Get(PAVLOU32TREE pTree, AVLOU32KEY Key);
+RTDECL(int)                   RTAvloU32DoWithAll(PAVLOU32TREE pTree, int fFromLeft, PAVLOU32CALLBACK pfnCallBack, void *pvParam);
+RTDECL(PAVLOU32NODECORE)      RTAvloU32GetBestFit(PAVLOU32TREE ppTree, AVLOU32KEY Key, bool fAbove);
+RTDECL(PAVLOU32NODECORE)      RTAvloU32RemoveBestFit(PAVLOU32TREE ppTree, AVLOU32KEY Key, bool fAbove);
+RTDECL(int)                   RTAvloU32Destroy(PAVLOU32TREE pTree, PAVLOU32CALLBACK pfnCallBack, void *pvParam);
+
+/** @} */
+
+
+/** AVL tree of uint32_t, list duplicates.
+ * @{
+ */
+
+/** AVL key type. */
+typedef uint32_t    AVLLU32KEY;
+
+/** AVL Core node. */
+typedef struct _AVLLU32NodeCore
+{
+    AVLLU32KEY                  Key;        /**< Key value. */
+    unsigned char               uchHeight;  /**< Height of this tree: max(height(left), height(right)) + 1 */
+    struct _AVLLU32NodeCore    *pLeft;      /**< Pointer to left leaf node. */
+    struct _AVLLU32NodeCore    *pRight;     /**< Pointer to right leaf node. */
+    struct _AVLLU32NodeCore    *pList;      /**< Pointer to next node with the same key. */
+} AVLLU32NODECORE, *PAVLLU32NODECORE, **PPAVLLU32NODECORE;
+
+/** Callback function for RTAvllU32DoWithAll() & RTAvllU32Destroy().
+ *  @returns IPRT status codes. */
+typedef DECLCALLBACK(int) AVLLU32CALLBACK(PAVLLU32NODECORE, void*);
+/** Pointer to callback function for RTAvllU32DoWithAll() & RTAvllU32Destroy(). */
+typedef AVLLU32CALLBACK *PAVLLU32CALLBACK;
+
+
+/*
+ * Functions.
+ */
+RTDECL(bool)                RTAvllU32Insert(PPAVLLU32NODECORE ppTree, PAVLLU32NODECORE pNode);
+RTDECL(PAVLLU32NODECORE)    RTAvllU32Remove(PPAVLLU32NODECORE ppTree, AVLLU32KEY Key);
+RTDECL(PAVLLU32NODECORE)    RTAvllU32RemoveNode(PPAVLLU32NODECORE ppTree, PAVLLU32NODECORE pNode);
+RTDECL(PAVLLU32NODECORE)    RTAvllU32Get(PPAVLLU32NODECORE ppTree, AVLLU32KEY Key);
+RTDECL(PAVLLU32NODECORE)    RTAvllU32GetBestFit(PPAVLLU32NODECORE ppTree, AVLLU32KEY Key, bool fAbove);
+RTDECL(PAVLLU32NODECORE)    RTAvllU32RemoveBestFit(PPAVLLU32NODECORE ppTree, AVLLU32KEY Key, bool fAbove);
+RTDECL(int)                 RTAvllU32DoWithAll(PPAVLLU32NODECORE ppTree, int fFromLeft, PAVLLU32CALLBACK pfnCallBack, void *pvParam);
+RTDECL(int)                 RTAvllU32Destroy(PPAVLLU32NODECORE pTree, PAVLLU32CALLBACK pfnCallBack, void *pvParam);
+
+/** @} */
+
+
+
+/** AVL tree of uint64_t ranges.
+ * @{
+ */
+
+/**
+ * AVL key type
+ */
+typedef uint64_t AVLRU64KEY;
+
+/**
+ * AVL Core node.
+ */
+typedef struct AVLRU64NodeCore
+{
+    AVLRU64KEY               Key;        /**< First key value in the range (inclusive). */
+    AVLRU64KEY               KeyLast;    /**< Last key value in the range (inclusive). */
+    struct AVLRU64NodeCore  *pLeft;      /**< Pointer to left leaf node. */
+    struct AVLRU64NodeCore  *pRight;     /**< Pointer to right leaf node. */
+    unsigned char            uchHeight;  /**< Height of this tree: max(height(left), height(right)) + 1 */
+} AVLRU64NODECORE, *PAVLRU64NODECORE, **PPAVLRU64NODECORE;
+
+/** A tree with void pointer keys. */
+typedef PAVLRU64NODECORE    AVLRU64TREE;
+/** Pointer to a tree with void pointer keys. */
+typedef PPAVLRU64NODECORE   PAVLRU64TREE;
+
+/** Callback function for AVLRU64DoWithAll().
+ *  @returns IPRT status codes. */
+typedef DECLCALLBACK(int) AVLRU64CALLBACK(PAVLRU64NODECORE, void *);
+/** Pointer to callback function for AVLU64DoWithAll(). */
+typedef AVLRU64CALLBACK *PAVLRU64CALLBACK;
+
+/*
+ * Functions.
+ */
+RTDECL(bool)             RTAvlrU64Insert(PAVLRU64TREE ppTree, PAVLRU64NODECORE pNode);
+RTDECL(PAVLRU64NODECORE) RTAvlrU64Remove(PAVLRU64TREE ppTree, AVLRU64KEY Key);
+RTDECL(PAVLRU64NODECORE) RTAvlrU64Get(PAVLRU64TREE ppTree, AVLRU64KEY Key);
+RTDECL(PAVLRU64NODECORE) RTAvlrU64RangeGet(PAVLRU64TREE ppTree, AVLRU64KEY Key);
+RTDECL(PAVLRU64NODECORE) RTAvlrU64RangeRemove(PAVLRU64TREE ppTree, AVLRU64KEY Key);
+RTDECL(PAVLRU64NODECORE) RTAvlrU64GetBestFit(PAVLRU64TREE ppTree, AVLRU64KEY Key, bool fAbove);
+RTDECL(PAVLRU64NODECORE) RTAvlrU64RemoveBestFit(PAVLRU64TREE ppTree, AVLRU64KEY Key, bool fAbove);
+RTDECL(int)              RTAvlrU64DoWithAll(PAVLRU64TREE ppTree, int fFromLeft, PAVLRU64CALLBACK pfnCallBack, void *pvParam);
+RTDECL(int)              RTAvlrU64Destroy(PAVLRU64TREE ppTree, PAVLRU64CALLBACK pfnCallBack, void *pvParam);
+
+/** @} */
+
+
+
+/** AVL tree of RTGCPHYSes - using relative offsets internally.
+ * @{
+ */
+
+/**
+ * AVL 'pointer' type for the relative offset pointer scheme.
+ */
+typedef int32_t     AVLOGCPHYS;
+
+/**
+ * AVL Core node.
+ */
+typedef struct _AVLOGCPhysNodeCore
+{
+    /** Key value. */
+    RTGCPHYS            Key;
+    /** Offset to the left leaf node, relative to this field. */
+    AVLOGCPHYS          pLeft;
+    /** Offset to the right leaf node, relative to this field. */
+    AVLOGCPHYS          pRight;
+    /** Height of this tree: max(height(left), height(right)) + 1 */
+    unsigned char       uchHeight;
+    /** Padding */
+    unsigned char       Padding[7];
+} AVLOGCPHYSNODECORE, *PAVLOGCPHYSNODECORE;
+
+/** A offset base tree with uint32_t keys. */
+typedef AVLOGCPHYS         AVLOGCPHYSTREE;
+/** Pointer to an offset base tree with uint32_t keys. */
+typedef AVLOGCPHYSTREE    *PAVLOGCPHYSTREE;
+
+/** Pointer to an internal tree pointer.
+ * In this case it's a pointer to a relative offset. */
+typedef AVLOGCPHYSTREE    *PPAVLOGCPHYSNODECORE;
+
+/** Callback function for RTAvloGCPhysDoWithAll() and RTAvloGCPhysDestroy().
+ *  @returns IPRT status codes. */
+typedef DECLCALLBACK(int)   AVLOGCPHYSCALLBACK(PAVLOGCPHYSNODECORE pNode, void *pvUser);
+/** Pointer to callback function for RTAvloGCPhysDoWithAll() and RTAvloGCPhysDestroy(). */
+typedef AVLOGCPHYSCALLBACK *PAVLOGCPHYSCALLBACK;
+
+RTDECL(bool)                    RTAvloGCPhysInsert(PAVLOGCPHYSTREE pTree, PAVLOGCPHYSNODECORE pNode);
+RTDECL(PAVLOGCPHYSNODECORE)     RTAvloGCPhysRemove(PAVLOGCPHYSTREE pTree, RTGCPHYS Key);
+RTDECL(PAVLOGCPHYSNODECORE)     RTAvloGCPhysGet(PAVLOGCPHYSTREE pTree, RTGCPHYS Key);
+RTDECL(int)                     RTAvloGCPhysDoWithAll(PAVLOGCPHYSTREE pTree, int fFromLeft, PAVLOGCPHYSCALLBACK pfnCallBack, void *pvParam);
+RTDECL(PAVLOGCPHYSNODECORE)     RTAvloGCPhysGetBestFit(PAVLOGCPHYSTREE ppTree, RTGCPHYS Key, bool fAbove);
+RTDECL(PAVLOGCPHYSNODECORE)     RTAvloGCPhysRemoveBestFit(PAVLOGCPHYSTREE ppTree, RTGCPHYS Key, bool fAbove);
+RTDECL(int)                     RTAvloGCPhysDestroy(PAVLOGCPHYSTREE pTree, PAVLOGCPHYSCALLBACK pfnCallBack, void *pvParam);
+
+/** @} */
+
+
+/** AVL tree of RTGCPHYS ranges - using relative offsets internally.
+ * @{
+ */
+
+/**
+ * AVL 'pointer' type for the relative offset pointer scheme.
+ */
+typedef int32_t     AVLROGCPHYS;
+
+/**
+ * AVL Core node.
+ */
+typedef struct _AVLROGCPhysNodeCore
+{
+    /** First key value in the range (inclusive). */
+    RTGCPHYS            Key;
+    /** Last key value in the range (inclusive). */
+    RTGCPHYS            KeyLast;
+    /** Offset to the left leaf node, relative to this field. */
+    AVLROGCPHYS         pLeft;
+    /** Offset to the right leaf node, relative to this field. */
+    AVLROGCPHYS         pRight;
+    /** Height of this tree: max(height(left), height(right)) + 1 */
+    unsigned char       uchHeight;
+    /** Padding */
+    unsigned char       Padding[7];
+} AVLROGCPHYSNODECORE, *PAVLROGCPHYSNODECORE;
+
+/** A offset base tree with uint32_t keys. */
+typedef AVLROGCPHYS         AVLROGCPHYSTREE;
+/** Pointer to an offset base tree with uint32_t keys. */
+typedef AVLROGCPHYSTREE    *PAVLROGCPHYSTREE;
+
+/** Pointer to an internal tree pointer.
+ * In this case it's a pointer to a relative offset. */
+typedef AVLROGCPHYSTREE    *PPAVLROGCPHYSNODECORE;
+
+/** Callback function for RTAvlroGCPhysDoWithAll() and RTAvlroGCPhysDestroy().
+ *  @returns IPRT status codes. */
+typedef DECLCALLBACK(int)   AVLROGCPHYSCALLBACK(PAVLROGCPHYSNODECORE pNode, void *pvUser);
+/** Pointer to callback function for RTAvlroGCPhysDoWithAll() and RTAvlroGCPhysDestroy(). */
+typedef AVLROGCPHYSCALLBACK *PAVLROGCPHYSCALLBACK;
+
+RTDECL(bool)                    RTAvlroGCPhysInsert(PAVLROGCPHYSTREE pTree, PAVLROGCPHYSNODECORE pNode);
+RTDECL(PAVLROGCPHYSNODECORE)    RTAvlroGCPhysRemove(PAVLROGCPHYSTREE pTree, RTGCPHYS Key);
+RTDECL(PAVLROGCPHYSNODECORE)    RTAvlroGCPhysGet(PAVLROGCPHYSTREE pTree, RTGCPHYS Key);
+RTDECL(PAVLROGCPHYSNODECORE)    RTAvlroGCPhysRangeGet(PAVLROGCPHYSTREE pTree, RTGCPHYS Key);
+RTDECL(PAVLROGCPHYSNODECORE)    RTAvlroGCPhysRangeRemove(PAVLROGCPHYSTREE pTree, RTGCPHYS Key);
+RTDECL(PAVLROGCPHYSNODECORE)    RTAvlroGCPhysGetBestFit(PAVLROGCPHYSTREE ppTree, RTGCPHYS Key, bool fAbove);
+RTDECL(int)                     RTAvlroGCPhysDoWithAll(PAVLROGCPHYSTREE pTree, int fFromLeft, PAVLROGCPHYSCALLBACK pfnCallBack, void *pvParam);
+RTDECL(int)                     RTAvlroGCPhysDestroy(PAVLROGCPHYSTREE pTree, PAVLROGCPHYSCALLBACK pfnCallBack, void *pvParam);
+RTDECL(PAVLROGCPHYSNODECORE)    RTAvlroGCPhysGetRoot(PAVLROGCPHYSTREE pTree);
+RTDECL(PAVLROGCPHYSNODECORE)    RTAvlroGCPhysGetLeft(PAVLROGCPHYSNODECORE pNode);
+RTDECL(PAVLROGCPHYSNODECORE)    RTAvlroGCPhysGetRight(PAVLROGCPHYSNODECORE pNode);
+
+/** @} */
+
+
+/** AVL tree of RTGCPTRs.
+ * @{
+ */
+
+/**
+ * AVL Core node.
+ */
+typedef struct _AVLGCPtrNodeCore
+{
+    /** Key value. */
+    RTGCPTR             Key;
+    /** Pointer to the left node. */
+    struct _AVLGCPtrNodeCore *pLeft;
+    /** Pointer to the right node. */
+    struct _AVLGCPtrNodeCore *pRight;
+    /** Height of this tree: max(height(left), height(right)) + 1 */
+    unsigned char       uchHeight;
+} AVLGCPTRNODECORE, *PAVLGCPTRNODECORE, **PPAVLGCPTRNODECORE;
+
+/** A tree of RTGCPTR keys. */
+typedef PAVLGCPTRNODECORE     AVLGCPTRTREE;
+/** Pointer to a tree of RTGCPTR keys. */
+typedef PPAVLGCPTRNODECORE    PAVLGCPTRTREE;
+
+/** Callback function for RTAvlGCPtrDoWithAll().
+ *  @returns IPRT status codes. */
+typedef DECLCALLBACK(int)   AVLGCPTRCALLBACK(PAVLGCPTRNODECORE pNode, void *pvUser);
+/** Pointer to callback function for RTAvlGCPtrDoWithAll(). */
+typedef AVLGCPTRCALLBACK *PAVLGCPTRCALLBACK;
+
+RTDECL(bool)                    RTAvlGCPtrInsert(PAVLGCPTRTREE pTree, PAVLGCPTRNODECORE pNode);
+RTDECL(PAVLGCPTRNODECORE)       RTAvlGCPtrRemove(PAVLGCPTRTREE pTree, RTGCPTR Key);
+RTDECL(PAVLGCPTRNODECORE)       RTAvlGCPtrGet(PAVLGCPTRTREE pTree, RTGCPTR Key);
+RTDECL(int)                     RTAvlGCPtrDoWithAll(PAVLGCPTRTREE pTree, int fFromLeft, PAVLGCPTRCALLBACK pfnCallBack, void *pvParam);
+RTDECL(PAVLGCPTRNODECORE)       RTAvlGCPtrGetBestFit(PAVLGCPTRTREE ppTree, RTGCPTR Key, bool fAbove);
+RTDECL(PAVLGCPTRNODECORE)       RTAvlGCPtrRemoveBestFit(PAVLGCPTRTREE ppTree, RTGCPTR Key, bool fAbove);
+RTDECL(int)                     RTAvlGCPtrDestroy(PAVLGCPTRTREE pTree, PAVLGCPTRCALLBACK pfnCallBack, void *pvParam);
+
+/** @} */
+
+
+/** AVL tree of RTGCPTRs - using relative offsets internally.
+ * @{
+ */
+
+/**
+ * AVL 'pointer' type for the relative offset pointer scheme.
+ */
+typedef int32_t     AVLOGCPTR;
+
+/**
+ * AVL Core node.
+ */
+typedef struct _AVLOGCPtrNodeCore
+{
+    /** Key value. */
+    RTGCPTR             Key;
+    /** Offset to the left leaf node, relative to this field. */
+    AVLOGCPTR           pLeft;
+    /** Offset to the right leaf node, relative to this field. */
+    AVLOGCPTR           pRight;
+    /** Height of this tree: max(height(left), height(right)) + 1 */
+    unsigned char       uchHeight;
+    unsigned char       padding[GC_ARCH_BITS == 64 ? 7 : 3];
+} AVLOGCPTRNODECORE, *PAVLOGCPTRNODECORE;
+
+/** A offset base tree with uint32_t keys. */
+typedef AVLOGCPTR         AVLOGCPTRTREE;
+/** Pointer to an offset base tree with uint32_t keys. */
+typedef AVLOGCPTRTREE    *PAVLOGCPTRTREE;
+
+/** Pointer to an internal tree pointer.
+ * In this case it's a pointer to a relative offset. */
+typedef AVLOGCPTRTREE    *PPAVLOGCPTRNODECORE;
+
+/** Callback function for RTAvloGCPtrDoWithAll().
+ *  @returns IPRT status codes. */
+typedef DECLCALLBACK(int)   AVLOGCPTRCALLBACK(PAVLOGCPTRNODECORE pNode, void *pvUser);
+/** Pointer to callback function for RTAvloGCPtrDoWithAll(). */
+typedef AVLOGCPTRCALLBACK *PAVLOGCPTRCALLBACK;
+
+RTDECL(bool)                    RTAvloGCPtrInsert(PAVLOGCPTRTREE pTree, PAVLOGCPTRNODECORE pNode);
+RTDECL(PAVLOGCPTRNODECORE)      RTAvloGCPtrRemove(PAVLOGCPTRTREE pTree, RTGCPTR Key);
+RTDECL(PAVLOGCPTRNODECORE)      RTAvloGCPtrGet(PAVLOGCPTRTREE pTree, RTGCPTR Key);
+RTDECL(int)                     RTAvloGCPtrDoWithAll(PAVLOGCPTRTREE pTree, int fFromLeft, PAVLOGCPTRCALLBACK pfnCallBack, void *pvParam);
+RTDECL(PAVLOGCPTRNODECORE)      RTAvloGCPtrGetBestFit(PAVLOGCPTRTREE ppTree, RTGCPTR Key, bool fAbove);
+RTDECL(PAVLOGCPTRNODECORE)      RTAvloGCPtrRemoveBestFit(PAVLOGCPTRTREE ppTree, RTGCPTR Key, bool fAbove);
+RTDECL(int)                     RTAvloGCPtrDestroy(PAVLOGCPTRTREE pTree, PAVLOGCPTRCALLBACK pfnCallBack, void *pvParam);
+
+/** @} */
+
+
+/** AVL tree of RTGCPTR ranges.
+ * @{
+ */
+
+/**
+ * AVL Core node.
+ */
+typedef struct _AVLRGCPtrNodeCore
+{
+    /** First key value in the range (inclusive). */
+    RTGCPTR             Key;
+    /** Last key value in the range (inclusive). */
+    RTGCPTR             KeyLast;
+    /** Offset to the left leaf node, relative to this field. */
+    struct _AVLRGCPtrNodeCore  *pLeft;
+    /** Offset to the right leaf node, relative to this field. */
+    struct _AVLRGCPtrNodeCore  *pRight;
+    /** Height of this tree: max(height(left), height(right)) + 1 */
+    unsigned char       uchHeight;
+} AVLRGCPTRNODECORE, *PAVLRGCPTRNODECORE;
+
+/** A offset base tree with RTGCPTR keys. */
+typedef PAVLRGCPTRNODECORE AVLRGCPTRTREE;
+/** Pointer to an offset base tree with RTGCPTR keys. */
+typedef AVLRGCPTRTREE    *PAVLRGCPTRTREE;
+
+/** Pointer to an internal tree pointer.
+ * In this case it's a pointer to a relative offset. */
+typedef AVLRGCPTRTREE    *PPAVLRGCPTRNODECORE;
+
+/** Callback function for RTAvlrGCPtrDoWithAll() and RTAvlrGCPtrDestroy().
+ *  @returns IPRT status codes. */
+typedef DECLCALLBACK(int)   AVLRGCPTRCALLBACK(PAVLRGCPTRNODECORE pNode, void *pvUser);
+/** Pointer to callback function for RTAvlrGCPtrDoWithAll() and RTAvlrGCPtrDestroy(). */
+typedef AVLRGCPTRCALLBACK *PAVLRGCPTRCALLBACK;
+
+RTDECL(bool)                   RTAvlrGCPtrInsert(       PAVLRGCPTRTREE pTree, PAVLRGCPTRNODECORE pNode);
+RTDECL(PAVLRGCPTRNODECORE)     RTAvlrGCPtrRemove(       PAVLRGCPTRTREE pTree, RTGCPTR Key);
+RTDECL(PAVLRGCPTRNODECORE)     RTAvlrGCPtrGet(          PAVLRGCPTRTREE pTree, RTGCPTR Key);
+RTDECL(PAVLRGCPTRNODECORE)     RTAvlrGCPtrGetBestFit(   PAVLRGCPTRTREE pTree, RTGCPTR Key, bool fAbove);
+RTDECL(PAVLRGCPTRNODECORE)     RTAvlrGCPtrRangeGet(     PAVLRGCPTRTREE pTree, RTGCPTR Key);
+RTDECL(PAVLRGCPTRNODECORE)     RTAvlrGCPtrRangeRemove(  PAVLRGCPTRTREE pTree, RTGCPTR Key);
+RTDECL(int)                    RTAvlrGCPtrDoWithAll(    PAVLRGCPTRTREE pTree, int fFromLeft, PAVLRGCPTRCALLBACK pfnCallBack, void *pvParam);
+RTDECL(int)                    RTAvlrGCPtrDestroy(      PAVLRGCPTRTREE pTree, PAVLRGCPTRCALLBACK pfnCallBack, void *pvParam);
+RTDECL(PAVLRGCPTRNODECORE)     RTAvlrGCPtrGetRoot(      PAVLRGCPTRTREE pTree);
+RTDECL(PAVLRGCPTRNODECORE)     RTAvlrGCPtrGetLeft(      PAVLRGCPTRNODECORE pNode);
+RTDECL(PAVLRGCPTRNODECORE)     RTAvlrGCPtrGetRight(     PAVLRGCPTRNODECORE pNode);
+
+/** @} */
+
+
+/** AVL tree of RTGCPTR ranges - using relative offsets internally.
+ * @{
+ */
+
+/**
+ * AVL 'pointer' type for the relative offset pointer scheme.
+ */
+typedef int32_t     AVLROGCPTR;
+
+/**
+ * AVL Core node.
+ */
+typedef struct _AVLROGCPtrNodeCore
+{
+    /** First key value in the range (inclusive). */
+    RTGCPTR             Key;
+    /** Last key value in the range (inclusive). */
+    RTGCPTR             KeyLast;
+    /** Offset to the left leaf node, relative to this field. */
+    AVLROGCPTR          pLeft;
+    /** Offset to the right leaf node, relative to this field. */
+    AVLROGCPTR          pRight;
+    /** Height of this tree: max(height(left), height(right)) + 1 */
+    unsigned char       uchHeight;
+    unsigned char       padding[GC_ARCH_BITS == 64 ? 7 : 7];
+} AVLROGCPTRNODECORE, *PAVLROGCPTRNODECORE;
+
+/** A offset base tree with uint32_t keys. */
+typedef AVLROGCPTR         AVLROGCPTRTREE;
+/** Pointer to an offset base tree with uint32_t keys. */
+typedef AVLROGCPTRTREE    *PAVLROGCPTRTREE;
+
+/** Pointer to an internal tree pointer.
+ * In this case it's a pointer to a relative offset. */
+typedef AVLROGCPTRTREE    *PPAVLROGCPTRNODECORE;
+
+/** Callback function for RTAvlroGCPtrDoWithAll() and RTAvlroGCPtrDestroy().
+ *  @returns IPRT status codes. */
+typedef DECLCALLBACK(int)   AVLROGCPTRCALLBACK(PAVLROGCPTRNODECORE pNode, void *pvUser);
+/** Pointer to callback function for RTAvlroGCPtrDoWithAll() and RTAvlroGCPtrDestroy(). */
+typedef AVLROGCPTRCALLBACK *PAVLROGCPTRCALLBACK;
+
+RTDECL(bool)                    RTAvlroGCPtrInsert(PAVLROGCPTRTREE pTree, PAVLROGCPTRNODECORE pNode);
+RTDECL(PAVLROGCPTRNODECORE)     RTAvlroGCPtrRemove(PAVLROGCPTRTREE pTree, RTGCPTR Key);
+RTDECL(PAVLROGCPTRNODECORE)     RTAvlroGCPtrGet(PAVLROGCPTRTREE pTree, RTGCPTR Key);
+RTDECL(PAVLROGCPTRNODECORE)     RTAvlroGCPtrGetBestFit(PAVLROGCPTRTREE ppTree, RTGCPTR Key, bool fAbove);
+RTDECL(PAVLROGCPTRNODECORE)     RTAvlroGCPtrRangeGet(PAVLROGCPTRTREE pTree, RTGCPTR Key);
+RTDECL(PAVLROGCPTRNODECORE)     RTAvlroGCPtrRangeRemove(PAVLROGCPTRTREE pTree, RTGCPTR Key);
+RTDECL(int)                     RTAvlroGCPtrDoWithAll(PAVLROGCPTRTREE pTree, int fFromLeft, PAVLROGCPTRCALLBACK pfnCallBack, void *pvParam);
+RTDECL(int)                     RTAvlroGCPtrDestroy(PAVLROGCPTRTREE pTree, PAVLROGCPTRCALLBACK pfnCallBack, void *pvParam);
+RTDECL(PAVLROGCPTRNODECORE)     RTAvlroGCPtrGetRoot(PAVLROGCPTRTREE pTree);
+RTDECL(PAVLROGCPTRNODECORE)     RTAvlroGCPtrGetLeft(PAVLROGCPTRNODECORE pNode);
+RTDECL(PAVLROGCPTRNODECORE)     RTAvlroGCPtrGetRight(PAVLROGCPTRNODECORE pNode);
+
+/** @} */
+
+
+/** AVL tree of RTGCPTR ranges (overlapping supported) - using relative offsets internally.
+ * @{
+ */
+
+/**
+ * AVL 'pointer' type for the relative offset pointer scheme.
+ */
+typedef int32_t     AVLROOGCPTR;
+
+/**
+ * AVL Core node.
+ */
+typedef struct _AVLROOGCPtrNodeCore
+{
+    /** First key value in the range (inclusive). */
+    RTGCPTR             Key;
+    /** Last key value in the range (inclusive). */
+    RTGCPTR             KeyLast;
+    /** Offset to the left leaf node, relative to this field. */
+    AVLROOGCPTR         pLeft;
+    /** Offset to the right leaf node, relative to this field. */
+    AVLROOGCPTR         pRight;
+    /** Pointer to the list of string with the same key. Don't touch. */
+    AVLROOGCPTR         pList;
+    /** Height of this tree: max(height(left), height(right)) + 1 */
+    unsigned char       uchHeight;
+} AVLROOGCPTRNODECORE, *PAVLROOGCPTRNODECORE;
+
+/** A offset base tree with uint32_t keys. */
+typedef AVLROOGCPTR         AVLROOGCPTRTREE;
+/** Pointer to an offset base tree with uint32_t keys. */
+typedef AVLROOGCPTRTREE    *PAVLROOGCPTRTREE;
+
+/** Pointer to an internal tree pointer.
+ * In this case it's a pointer to a relative offset. */
+typedef AVLROOGCPTRTREE    *PPAVLROOGCPTRNODECORE;
+
+/** Callback function for RTAvlrooGCPtrDoWithAll() and RTAvlrooGCPtrDestroy().
+ *  @returns IPRT status codes. */
+typedef DECLCALLBACK(int)   AVLROOGCPTRCALLBACK(PAVLROOGCPTRNODECORE pNode, void *pvUser);
+/** Pointer to callback function for RTAvlrooGCPtrDoWithAll() and RTAvlrooGCPtrDestroy(). */
+typedef AVLROOGCPTRCALLBACK *PAVLROOGCPTRCALLBACK;
+
+RTDECL(bool)                    RTAvlrooGCPtrInsert(PAVLROOGCPTRTREE pTree, PAVLROOGCPTRNODECORE pNode);
+RTDECL(PAVLROOGCPTRNODECORE)    RTAvlrooGCPtrRemove(PAVLROOGCPTRTREE pTree, RTGCPTR Key);
+RTDECL(PAVLROOGCPTRNODECORE)    RTAvlrooGCPtrGet(PAVLROOGCPTRTREE pTree, RTGCPTR Key);
+RTDECL(PAVLROOGCPTRNODECORE)    RTAvlrooGCPtrGetBestFit(PAVLROOGCPTRTREE ppTree, RTGCPTR Key, bool fAbove);
+RTDECL(PAVLROOGCPTRNODECORE)    RTAvlrooGCPtrRangeGet(PAVLROOGCPTRTREE pTree, RTGCPTR Key);
+RTDECL(PAVLROOGCPTRNODECORE)    RTAvlrooGCPtrRangeRemove(PAVLROOGCPTRTREE pTree, RTGCPTR Key);
+RTDECL(int)                     RTAvlrooGCPtrDoWithAll(PAVLROOGCPTRTREE pTree, int fFromLeft, PAVLROOGCPTRCALLBACK pfnCallBack, void *pvParam);
+RTDECL(int)                     RTAvlrooGCPtrDestroy(PAVLROOGCPTRTREE pTree, PAVLROOGCPTRCALLBACK pfnCallBack, void *pvParam);
+RTDECL(PAVLROOGCPTRNODECORE)    RTAvlrooGCPtrGetRoot(PAVLROOGCPTRTREE pTree);
+RTDECL(PAVLROOGCPTRNODECORE)    RTAvlrooGCPtrGetLeft(PAVLROOGCPTRNODECORE pNode);
+RTDECL(PAVLROOGCPTRNODECORE)    RTAvlrooGCPtrGetRight(PAVLROOGCPTRNODECORE pNode);
+RTDECL(PAVLROOGCPTRNODECORE)    RTAvlrooGCPtrGetNextEqual(PAVLROOGCPTRNODECORE pNode);
+
+/** @} */
+
+
+/** AVL tree of RTUINTPTR.
+ * @{
+ */
+
+/**
+ * AVL RTUINTPTR node core.
+ */
+typedef struct _AVLUIntPtrNodeCore
+{
+    /** Key value. */
+    RTUINTPTR                   Key;
+    /** Offset to the left leaf node, relative to this field. */
+    struct _AVLUIntPtrNodeCore *pLeft;
+    /** Offset to the right leaf node, relative to this field. */
+    struct _AVLUIntPtrNodeCore *pRight;
+    /** Height of this tree: max(height(left), height(right)) + 1 */
+    unsigned char               uchHeight;
+} AVLUINTPTRNODECORE;
+/** Pointer to a RTUINTPTR AVL node core.*/
+typedef AVLUINTPTRNODECORE *PAVLUINTPTRNODECORE;
+
+/** A pointer based tree with RTUINTPTR keys. */
+typedef PAVLUINTPTRNODECORE AVLUINTPTRTREE;
+/** Pointer to an offset base tree with RTUINTPTR keys. */
+typedef AVLUINTPTRTREE     *PAVLUINTPTRTREE;
+
+/** Pointer to an internal tree pointer.
+ * In this case it's a pointer to a pointer. */
+typedef AVLUINTPTRTREE     *PPAVLUINTPTRNODECORE;
+
+/** Callback function for RTAvlUIntPtrDoWithAll() and RTAvlUIntPtrDestroy().
+ *  @returns IPRT status codes. */
+typedef DECLCALLBACK(int)    AVLUINTPTRCALLBACK(PAVLUINTPTRNODECORE pNode, void *pvUser);
+/** Pointer to callback function for RTAvlUIntPtrDoWithAll() and RTAvlUIntPtrDestroy(). */
+typedef AVLUINTPTRCALLBACK *PAVLUINTPTRCALLBACK;
+
+RTDECL(bool)                    RTAvlUIntPtrInsert(    PAVLUINTPTRTREE pTree, PAVLUINTPTRNODECORE pNode);
+RTDECL(PAVLUINTPTRNODECORE)     RTAvlUIntPtrRemove(    PAVLUINTPTRTREE pTree, RTUINTPTR Key);
+RTDECL(PAVLUINTPTRNODECORE)     RTAvlUIntPtrGet(       PAVLUINTPTRTREE pTree, RTUINTPTR Key);
+RTDECL(PAVLUINTPTRNODECORE)     RTAvlUIntPtrGetBestFit(PAVLUINTPTRTREE pTree, RTUINTPTR Key, bool fAbove);
+RTDECL(int)                     RTAvlUIntPtrDoWithAll( PAVLUINTPTRTREE pTree, int fFromLeft, PAVLUINTPTRCALLBACK pfnCallBack, void *pvParam);
+RTDECL(int)                     RTAvlUIntPtrDestroy(   PAVLUINTPTRTREE pTree, PAVLUINTPTRCALLBACK pfnCallBack, void *pvParam);
+RTDECL(PAVLUINTPTRNODECORE)     RTAvlUIntPtrGetRoot(   PAVLUINTPTRTREE pTree);
+RTDECL(PAVLUINTPTRNODECORE)     RTAvlUIntPtrGetLeft(   PAVLUINTPTRNODECORE pNode);
+RTDECL(PAVLUINTPTRNODECORE)     RTAvlUIntPtrGetRight(  PAVLUINTPTRNODECORE pNode);
+
+/** @} */
+
+
+/** AVL tree of RTUINTPTR ranges.
+ * @{
+ */
+
+/**
+ * AVL RTUINTPTR range node core.
+ */
+typedef struct _AVLRUIntPtrNodeCore
+{
+    /** First key value in the range (inclusive). */
+    RTUINTPTR                       Key;
+    /** Last key value in the range (inclusive). */
+    RTUINTPTR                       KeyLast;
+    /** Offset to the left leaf node, relative to this field. */
+    struct _AVLRUIntPtrNodeCore    *pLeft;
+    /** Offset to the right leaf node, relative to this field. */
+    struct _AVLRUIntPtrNodeCore    *pRight;
+    /** Height of this tree: max(height(left), height(right)) + 1 */
+    unsigned char                   uchHeight;
+} AVLRUINTPTRNODECORE;
+/** Pointer to an AVL RTUINTPTR range node code. */
+typedef AVLRUINTPTRNODECORE *PAVLRUINTPTRNODECORE;
+
+/** A pointer based tree with RTUINTPTR ranges. */
+typedef PAVLRUINTPTRNODECORE AVLRUINTPTRTREE;
+/** Pointer to a pointer based tree with RTUINTPTR ranges. */
+typedef AVLRUINTPTRTREE     *PAVLRUINTPTRTREE;
+
+/** Pointer to an internal tree pointer.
+ * In this case it's a pointer to a pointer. */
+typedef AVLRUINTPTRTREE     *PPAVLRUINTPTRNODECORE;
+
+/** Callback function for RTAvlrUIntPtrDoWithAll() and RTAvlrUIntPtrDestroy().
+ *  @returns IPRT status codes. */
+typedef DECLCALLBACK(int)    AVLRUINTPTRCALLBACK(PAVLRUINTPTRNODECORE pNode, void *pvUser);
+/** Pointer to callback function for RTAvlrUIntPtrDoWithAll() and RTAvlrUIntPtrDestroy(). */
+typedef AVLRUINTPTRCALLBACK *PAVLRUINTPTRCALLBACK;
+
+RTDECL(bool)                   RTAvlrUIntPtrInsert(     PAVLRUINTPTRTREE pTree, PAVLRUINTPTRNODECORE pNode);
+RTDECL(PAVLRUINTPTRNODECORE)   RTAvlrUIntPtrRemove(     PAVLRUINTPTRTREE pTree, RTUINTPTR Key);
+RTDECL(PAVLRUINTPTRNODECORE)   RTAvlrUIntPtrGet(        PAVLRUINTPTRTREE pTree, RTUINTPTR Key);
+RTDECL(PAVLRUINTPTRNODECORE)   RTAvlrUIntPtrGetBestFit( PAVLRUINTPTRTREE pTree, RTUINTPTR Key, bool fAbove);
+RTDECL(PAVLRUINTPTRNODECORE)   RTAvlrUIntPtrRangeGet(   PAVLRUINTPTRTREE pTree, RTUINTPTR Key);
+RTDECL(PAVLRUINTPTRNODECORE)   RTAvlrUIntPtrRangeRemove(PAVLRUINTPTRTREE pTree, RTUINTPTR Key);
+RTDECL(int)                    RTAvlrUIntPtrDoWithAll(  PAVLRUINTPTRTREE pTree, int fFromLeft, PAVLRUINTPTRCALLBACK pfnCallBack, void *pvParam);
+RTDECL(int)                    RTAvlrUIntPtrDestroy(    PAVLRUINTPTRTREE pTree, PAVLRUINTPTRCALLBACK pfnCallBack, void *pvParam);
+RTDECL(PAVLRUINTPTRNODECORE)   RTAvlrUIntPtrGetRoot(    PAVLRUINTPTRTREE pTree);
+RTDECL(PAVLRUINTPTRNODECORE)   RTAvlrUIntPtrGetLeft(    PAVLRUINTPTRNODECORE pNode);
+RTDECL(PAVLRUINTPTRNODECORE)   RTAvlrUIntPtrGetRight(   PAVLRUINTPTRNODECORE pNode);
+
+/** @} */
+
+
+/** AVL tree of RTHCPHYSes - using relative offsets internally.
+ * @{
+ */
+
+/**
+ * AVL 'pointer' type for the relative offset pointer scheme.
+ */
+typedef int32_t     AVLOHCPHYS;
+
+/**
+ * AVL Core node.
+ */
+typedef struct _AVLOHCPhysNodeCore
+{
+    /** Key value. */
+    RTHCPHYS            Key;
+    /** Offset to the left leaf node, relative to this field. */
+    AVLOHCPHYS          pLeft;
+    /** Offset to the right leaf node, relative to this field. */
+    AVLOHCPHYS          pRight;
+    /** Height of this tree: max(height(left), height(right)) + 1 */
+    unsigned char       uchHeight;
+#if HC_ARCH_BITS == 64 || GC_ARCH_BITS == 64
+    unsigned char       Padding[7]; /**< Alignment padding. */
+#endif
+} AVLOHCPHYSNODECORE, *PAVLOHCPHYSNODECORE;
+
+/** A offset base tree with uint32_t keys. */
+typedef AVLOHCPHYS         AVLOHCPHYSTREE;
+/** Pointer to an offset base tree with uint32_t keys. */
+typedef AVLOHCPHYSTREE    *PAVLOHCPHYSTREE;
+
+/** Pointer to an internal tree pointer.
+ * In this case it's a pointer to a relative offset. */
+typedef AVLOHCPHYSTREE    *PPAVLOHCPHYSNODECORE;
+
+/** Callback function for RTAvloHCPhysDoWithAll() and RTAvloHCPhysDestroy().
+ *  @returns IPRT status codes. */
+typedef DECLCALLBACK(int)   AVLOHCPHYSCALLBACK(PAVLOHCPHYSNODECORE pNode, void *pvUser);
+/** Pointer to callback function for RTAvloHCPhysDoWithAll() and RTAvloHCPhysDestroy(). */
+typedef AVLOHCPHYSCALLBACK *PAVLOHCPHYSCALLBACK;
+
+RTDECL(bool)                    RTAvloHCPhysInsert(PAVLOHCPHYSTREE pTree, PAVLOHCPHYSNODECORE pNode);
+RTDECL(PAVLOHCPHYSNODECORE)     RTAvloHCPhysRemove(PAVLOHCPHYSTREE pTree, RTHCPHYS Key);
+RTDECL(PAVLOHCPHYSNODECORE)     RTAvloHCPhysGet(PAVLOHCPHYSTREE pTree, RTHCPHYS Key);
+RTDECL(int)                     RTAvloHCPhysDoWithAll(PAVLOHCPHYSTREE pTree, int fFromLeft, PAVLOHCPHYSCALLBACK pfnCallBack, void *pvParam);
+RTDECL(PAVLOHCPHYSNODECORE)     RTAvloHCPhysGetBestFit(PAVLOHCPHYSTREE ppTree, RTHCPHYS Key, bool fAbove);
+RTDECL(PAVLOHCPHYSNODECORE)     RTAvloHCPhysRemoveBestFit(PAVLOHCPHYSTREE ppTree, RTHCPHYS Key, bool fAbove);
+RTDECL(int)                     RTAvloHCPhysDestroy(PAVLOHCPHYSTREE pTree, PAVLOHCPHYSCALLBACK pfnCallBack, void *pvParam);
+
+/** @} */
+
+
+
+/** AVL tree of RTIOPORTs - using relative offsets internally.
+ * @{
+ */
+
+/**
+ * AVL 'pointer' type for the relative offset pointer scheme.
+ */
+typedef int32_t     AVLOIOPORTPTR;
+
+/**
+ * AVL Core node.
+ */
+typedef struct _AVLOIOPortNodeCore
+{
+    /** Offset to the left leaf node, relative to this field. */
+    AVLOIOPORTPTR       pLeft;
+    /** Offset to the right leaf node, relative to this field. */
+    AVLOIOPORTPTR       pRight;
+    /** Key value. */
+    RTIOPORT            Key;
+    /** Height of this tree: max(height(left), height(right)) + 1 */
+    unsigned char       uchHeight;
+} AVLOIOPORTNODECORE, *PAVLOIOPORTNODECORE;
+
+/** A offset base tree with uint32_t keys. */
+typedef AVLOIOPORTPTR      AVLOIOPORTTREE;
+/** Pointer to an offset base tree with uint32_t keys. */
+typedef AVLOIOPORTTREE    *PAVLOIOPORTTREE;
+
+/** Pointer to an internal tree pointer.
+ * In this case it's a pointer to a relative offset. */
+typedef AVLOIOPORTTREE    *PPAVLOIOPORTNODECORE;
+
+/** Callback function for RTAvloIOPortDoWithAll() and RTAvloIOPortDestroy().
+ *  @returns IPRT status codes. */
+typedef DECLCALLBACK(int)   AVLOIOPORTCALLBACK(PAVLOIOPORTNODECORE pNode, void *pvUser);
+/** Pointer to callback function for RTAvloIOPortDoWithAll() and RTAvloIOPortDestroy(). */
+typedef AVLOIOPORTCALLBACK *PAVLOIOPORTCALLBACK;
+
+RTDECL(bool)                    RTAvloIOPortInsert(PAVLOIOPORTTREE pTree, PAVLOIOPORTNODECORE pNode);
+RTDECL(PAVLOIOPORTNODECORE)     RTAvloIOPortRemove(PAVLOIOPORTTREE pTree, RTIOPORT Key);
+RTDECL(PAVLOIOPORTNODECORE)     RTAvloIOPortGet(PAVLOIOPORTTREE pTree, RTIOPORT Key);
+RTDECL(int)                     RTAvloIOPortDoWithAll(PAVLOIOPORTTREE pTree, int fFromLeft, PAVLOIOPORTCALLBACK pfnCallBack, void *pvParam);
+RTDECL(PAVLOIOPORTNODECORE)     RTAvloIOPortGetBestFit(PAVLOIOPORTTREE ppTree, RTIOPORT Key, bool fAbove);
+RTDECL(PAVLOIOPORTNODECORE)     RTAvloIOPortRemoveBestFit(PAVLOIOPORTTREE ppTree, RTIOPORT Key, bool fAbove);
+RTDECL(int)                     RTAvloIOPortDestroy(PAVLOIOPORTTREE pTree, PAVLOIOPORTCALLBACK pfnCallBack, void *pvParam);
+
+/** @} */
+
+
+/** AVL tree of RTIOPORT ranges - using relative offsets internally.
+ * @{
+ */
+
+/**
+ * AVL 'pointer' type for the relative offset pointer scheme.
+ */
+typedef int32_t     AVLROIOPORTPTR;
+
+/**
+ * AVL Core node.
+ */
+typedef struct _AVLROIOPortNodeCore
+{
+    /** First key value in the range (inclusive). */
+    RTIOPORT            Key;
+    /** Last key value in the range (inclusive). */
+    RTIOPORT            KeyLast;
+    /** Offset to the left leaf node, relative to this field. */
+    AVLROIOPORTPTR      pLeft;
+    /** Offset to the right leaf node, relative to this field. */
+    AVLROIOPORTPTR      pRight;
+    /** Height of this tree: max(height(left), height(right)) + 1 */
+    unsigned char       uchHeight;
+} AVLROIOPORTNODECORE, *PAVLROIOPORTNODECORE;
+
+/** A offset base tree with uint32_t keys. */
+typedef AVLROIOPORTPTR      AVLROIOPORTTREE;
+/** Pointer to an offset base tree with uint32_t keys. */
+typedef AVLROIOPORTTREE    *PAVLROIOPORTTREE;
+
+/** Pointer to an internal tree pointer.
+ * In this case it's a pointer to a relative offset. */
+typedef AVLROIOPORTTREE    *PPAVLROIOPORTNODECORE;
+
+/** Callback function for RTAvlroIOPortDoWithAll() and RTAvlroIOPortDestroy().
+ *  @returns IPRT status codes. */
+typedef DECLCALLBACK(int)   AVLROIOPORTCALLBACK(PAVLROIOPORTNODECORE pNode, void *pvUser);
+/** Pointer to callback function for RTAvlroIOPortDoWithAll() and RTAvlroIOPortDestroy(). */
+typedef AVLROIOPORTCALLBACK *PAVLROIOPORTCALLBACK;
+
+RTDECL(bool)                    RTAvlroIOPortInsert(PAVLROIOPORTTREE pTree, PAVLROIOPORTNODECORE pNode);
+RTDECL(PAVLROIOPORTNODECORE)    RTAvlroIOPortRemove(PAVLROIOPORTTREE pTree, RTIOPORT Key);
+RTDECL(PAVLROIOPORTNODECORE)    RTAvlroIOPortGet(PAVLROIOPORTTREE pTree, RTIOPORT Key);
+RTDECL(PAVLROIOPORTNODECORE)    RTAvlroIOPortRangeGet(PAVLROIOPORTTREE pTree, RTIOPORT Key);
+RTDECL(PAVLROIOPORTNODECORE)    RTAvlroIOPortRangeRemove(PAVLROIOPORTTREE pTree, RTIOPORT Key);
+RTDECL(int)                     RTAvlroIOPortDoWithAll(PAVLROIOPORTTREE pTree, int fFromLeft, PAVLROIOPORTCALLBACK pfnCallBack, void *pvParam);
+RTDECL(int)                     RTAvlroIOPortDestroy(PAVLROIOPORTTREE pTree, PAVLROIOPORTCALLBACK pfnCallBack, void *pvParam);
+
+/** @} */
+
+
+/** AVL tree of RTHCPHYSes.
+ * @{
+ */
+
+/**
+ * AVL 'pointer' type for the relative offset pointer scheme.
+ */
+typedef struct _AVLHCPhysNodeCore  *AVLHCPHYSPTR;
+
+/**
+ * AVL Core node.
+ */
+typedef struct _AVLHCPhysNodeCore
+{
+    /** Offset to the left leaf node, relative to this field. */
+    AVLHCPHYSPTR        pLeft;
+    /** Offset to the right leaf node, relative to this field. */
+    AVLHCPHYSPTR        pRight;
+    /** Key value. */
+    RTHCPHYS            Key;
+    /** Height of this tree: max(height(left), height(right)) + 1 */
+    unsigned char       uchHeight;
+} AVLHCPHYSNODECORE, *PAVLHCPHYSNODECORE;
+
+/** A offset base tree with RTHCPHYS keys. */
+typedef AVLHCPHYSPTR      AVLHCPHYSTREE;
+/** Pointer to an offset base tree with RTHCPHYS keys. */
+typedef AVLHCPHYSTREE    *PAVLHCPHYSTREE;
+
+/** Pointer to an internal tree pointer.
+ * In this case it's a pointer to a relative offset. */
+typedef AVLHCPHYSTREE    *PPAVLHCPHYSNODECORE;
+
+/** Callback function for RTAvlHCPhysDoWithAll() and RTAvlHCPhysDestroy().
+ *  @returns IPRT status codes. */
+typedef DECLCALLBACK(int)   AVLHCPHYSCALLBACK(PAVLHCPHYSNODECORE pNode, void *pvUser);
+/** Pointer to callback function for RTAvlHCPhysDoWithAll() and RTAvlHCPhysDestroy(). */
+typedef AVLHCPHYSCALLBACK *PAVLHCPHYSCALLBACK;
+
+RTDECL(bool)                    RTAvlHCPhysInsert(PAVLHCPHYSTREE pTree, PAVLHCPHYSNODECORE pNode);
+RTDECL(PAVLHCPHYSNODECORE)      RTAvlHCPhysRemove(PAVLHCPHYSTREE pTree, RTHCPHYS Key);
+RTDECL(PAVLHCPHYSNODECORE)      RTAvlHCPhysGet(PAVLHCPHYSTREE pTree, RTHCPHYS Key);
+RTDECL(int)                     RTAvlHCPhysDoWithAll(PAVLHCPHYSTREE pTree, int fFromLeft, PAVLHCPHYSCALLBACK pfnCallBack, void *pvParam);
+RTDECL(PAVLHCPHYSNODECORE)      RTAvlHCPhysGetBestFit(PAVLHCPHYSTREE ppTree, RTHCPHYS Key, bool fAbove);
+RTDECL(PAVLHCPHYSNODECORE)      RTAvlHCPhysRemoveBestFit(PAVLHCPHYSTREE ppTree, RTHCPHYS Key, bool fAbove);
+RTDECL(int)                     RTAvlHCPhysDestroy(PAVLHCPHYSTREE pTree, PAVLHCPHYSCALLBACK pfnCallBack, void *pvParam);
+
+/** @} */
+
+/** AVL tree of RTGCPHYSes.
+ * @{
+ */
+
+/**
+ * AVL 'pointer' type for the relative offset pointer scheme.
+ */
+typedef struct _AVLGCPhysNodeCore  *AVLGCPHYSPTR;
+
+/**
+ * AVL Core node.
+ */
+typedef struct _AVLGCPhysNodeCore
+{
+    /** Offset to the left leaf node, relative to this field. */
+    AVLGCPHYSPTR        pLeft;
+    /** Offset to the right leaf node, relative to this field. */
+    AVLGCPHYSPTR        pRight;
+    /** Key value. */
+    RTGCPHYS            Key;
+    /** Height of this tree: max(height(left), height(right)) + 1 */
+    unsigned char       uchHeight;
+} AVLGCPHYSNODECORE, *PAVLGCPHYSNODECORE;
+
+/** A offset base tree with RTGCPHYS keys. */
+typedef AVLGCPHYSPTR      AVLGCPHYSTREE;
+/** Pointer to an offset base tree with RTGCPHYS keys. */
+typedef AVLGCPHYSTREE    *PAVLGCPHYSTREE;
+
+/** Pointer to an internal tree pointer.
+ * In this case it's a pointer to a relative offset. */
+typedef AVLGCPHYSTREE    *PPAVLGCPHYSNODECORE;
+
+/** Callback function for RTAvlGCPhysDoWithAll() and RTAvlGCPhysDestroy().
+ *  @returns IPRT status codes. */
+typedef DECLCALLBACK(int)   AVLGCPHYSCALLBACK(PAVLGCPHYSNODECORE pNode, void *pvUser);
+/** Pointer to callback function for RTAvlGCPhysDoWithAll() and RTAvlGCPhysDestroy(). */
+typedef AVLGCPHYSCALLBACK *PAVLGCPHYSCALLBACK;
+
+RTDECL(bool)                    RTAvlGCPhysInsert(PAVLGCPHYSTREE pTree, PAVLGCPHYSNODECORE pNode);
+RTDECL(PAVLGCPHYSNODECORE)      RTAvlGCPhysRemove(PAVLGCPHYSTREE pTree, RTGCPHYS Key);
+RTDECL(PAVLGCPHYSNODECORE)      RTAvlGCPhysGet(PAVLGCPHYSTREE pTree, RTGCPHYS Key);
+RTDECL(int)                     RTAvlGCPhysDoWithAll(PAVLGCPHYSTREE pTree, int fFromLeft, PAVLGCPHYSCALLBACK pfnCallBack, void *pvParam);
+RTDECL(PAVLGCPHYSNODECORE)      RTAvlGCPhysGetBestFit(PAVLGCPHYSTREE ppTree, RTGCPHYS Key, bool fAbove);
+RTDECL(PAVLGCPHYSNODECORE)      RTAvlGCPhysRemoveBestFit(PAVLGCPHYSTREE ppTree, RTGCPHYS Key, bool fAbove);
+RTDECL(int)                     RTAvlGCPhysDestroy(PAVLGCPHYSTREE pTree, PAVLGCPHYSCALLBACK pfnCallBack, void *pvParam);
+
+/** @} */
+
+
+/** AVL tree of RTFOFF ranges.
+ * @{
+ */
+
+/**
+ * AVL Core node.
+ */
+typedef struct _AVLRFOFFNodeCore
+{
+    /** First key value in the range (inclusive). */
+    RTFOFF             Key;
+    /** Last key value in the range (inclusive). */
+    RTFOFF             KeyLast;
+    /** Offset to the left leaf node, relative to this field. */
+    struct _AVLRFOFFNodeCore  *pLeft;
+    /** Offset to the right leaf node, relative to this field. */
+    struct _AVLRFOFFNodeCore  *pRight;
+    /** Height of this tree: max(height(left), height(right)) + 1 */
+    unsigned char       uchHeight;
+} AVLRFOFFNODECORE, *PAVLRFOFFNODECORE;
+
+/** A pointer based tree with RTFOFF ranges. */
+typedef PAVLRFOFFNODECORE AVLRFOFFTREE;
+/** Pointer to a pointer based tree with RTFOFF ranges. */
+typedef AVLRFOFFTREE    *PAVLRFOFFTREE;
+
+/** Pointer to an internal tree pointer.
+ * In this case it's a pointer to a relative offset. */
+typedef AVLRFOFFTREE    *PPAVLRFOFFNODECORE;
+
+/** Callback function for RTAvlrGCPtrDoWithAll() and RTAvlrGCPtrDestroy().
+ *  @returns IPRT status codes. */
+typedef DECLCALLBACK(int)   AVLRFOFFCALLBACK(PAVLRFOFFNODECORE pNode, void *pvUser);
+/** Pointer to callback function for RTAvlrGCPtrDoWithAll() and RTAvlrGCPtrDestroy(). */
+typedef AVLRFOFFCALLBACK *PAVLRFOFFCALLBACK;
+
+RTDECL(bool)                  RTAvlrFileOffsetInsert(       PAVLRFOFFTREE pTree, PAVLRFOFFNODECORE pNode);
+RTDECL(PAVLRFOFFNODECORE)     RTAvlrFileOffsetRemove(       PAVLRFOFFTREE pTree, RTFOFF Key);
+RTDECL(PAVLRFOFFNODECORE)     RTAvlrFileOffsetGet(          PAVLRFOFFTREE pTree, RTFOFF Key);
+RTDECL(PAVLRFOFFNODECORE)     RTAvlrFileOffsetGetBestFit(   PAVLRFOFFTREE pTree, RTFOFF Key, bool fAbove);
+RTDECL(PAVLRFOFFNODECORE)     RTAvlrFileOffsetRangeGet(     PAVLRFOFFTREE pTree, RTFOFF Key);
+RTDECL(PAVLRFOFFNODECORE)     RTAvlrFileOffsetRangeRemove(  PAVLRFOFFTREE pTree, RTFOFF Key);
+RTDECL(int)                   RTAvlrFileOffsetDoWithAll(    PAVLRFOFFTREE pTree, int fFromLeft, PAVLRFOFFCALLBACK pfnCallBack, void *pvParam);
+RTDECL(int)                   RTAvlrFileOffsetDestroy(      PAVLRFOFFTREE pTree, PAVLRFOFFCALLBACK pfnCallBack, void *pvParam);
+RTDECL(PAVLRFOFFNODECORE)     RTAvlrFileOffsetGetRoot(      PAVLRFOFFTREE pTree);
+RTDECL(PAVLRFOFFNODECORE)     RTAvlrFileOffsetGetLeft(      PAVLRFOFFNODECORE pNode);
+RTDECL(PAVLRFOFFNODECORE)     RTAvlrFileOffsetGetRight(     PAVLRFOFFNODECORE pNode);
+
+/** @} */
+
+/** @} */
+
+RT_C_DECLS_END
+
+#endif
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/include/iprt/cdefs.h
@@ -0,0 +1,2915 @@
+/** @file
+ * IPRT - Common C and C++ definitions.
+ */
+
+/*
+ * Copyright (C) 2006-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+#ifndef ___iprt_cdefs_h
+#define ___iprt_cdefs_h
+
+
+/** @defgroup grp_rt_cdefs  IPRT Common Definitions and Macros
+ * @{
+ */
+
+/** @def RT_C_DECLS_BEGIN
+ * Used to start a block of function declarations which are shared
+ * between C and C++ program.
+ */
+
+/** @def RT_C_DECLS_END
+ * Used to end a block of function declarations which are shared
+ * between C and C++ program.
+ */
+
+#if defined(__cplusplus)
+# define RT_C_DECLS_BEGIN extern "C" {
+# define RT_C_DECLS_END   }
+#else
+# define RT_C_DECLS_BEGIN
+# define RT_C_DECLS_END
+#endif
+
+
+/*
+ * Shut up DOXYGEN warnings and guide it properly thru the code.
+ */
+#ifdef DOXYGEN_RUNNING
+# define __AMD64__
+# define __X86__
+# define RT_ARCH_AMD64
+# define RT_ARCH_X86
+# define RT_ARCH_SPARC
+# define RT_ARCH_SPARC64
+# define IN_RING0
+# define IN_RING3
+# define IN_RC
+# define IN_RC
+# define IN_RT_RC
+# define IN_RT_R0
+# define IN_RT_R3
+# define IN_RT_STATIC
+# define RT_STRICT
+# define RT_NO_STRICT
+# define RT_LOCK_STRICT
+# define RT_LOCK_NO_STRICT
+# define RT_LOCK_STRICT_ORDER
+# define RT_LOCK_NO_STRICT_ORDER
+# define RT_BREAKPOINT
+# define RT_NO_DEPRECATED_MACROS
+# define RT_EXCEPTIONS_ENABLED
+# define RT_BIG_ENDIAN
+# define RT_LITTLE_ENDIAN
+# define RT_COMPILER_GROKS_64BIT_BITFIELDS
+# define RT_COMPILER_WITH_80BIT_LONG_DOUBLE
+# define RT_NO_VISIBILITY_HIDDEN
+# define RT_GCC_SUPPORTS_VISIBILITY_HIDDEN
+# define RT_COMPILER_SUPPORTS_LAMBDA
+#endif /* DOXYGEN_RUNNING */
+
+/** @def RT_ARCH_X86
+ * Indicates that we're compiling for the X86 architecture.
+ */
+
+/** @def RT_ARCH_AMD64
+ * Indicates that we're compiling for the AMD64 architecture.
+ */
+
+/** @def RT_ARCH_SPARC
+ * Indicates that we're compiling for the SPARC V8 architecture (32-bit).
+ */
+
+/** @def RT_ARCH_SPARC64
+ * Indicates that we're compiling for the SPARC V9 architecture (64-bit).
+ */
+#if !defined(RT_ARCH_X86) \
+ && !defined(RT_ARCH_AMD64) \
+ && !defined(RT_ARCH_SPARC) \
+ && !defined(RT_ARCH_SPARC64) \
+ && !defined(RT_ARCH_ARM)
+# if defined(__amd64__) || defined(__x86_64__) || defined(_M_X64) || defined(__AMD64__)
+#  define RT_ARCH_AMD64
+# elif defined(__i386__) || defined(_M_IX86) || defined(__X86__)
+#  define RT_ARCH_X86
+# elif defined(__sparcv9)
+#  define RT_ARCH_SPARC64
+# elif defined(__sparc__)
+#  define RT_ARCH_SPARC
+# elif defined(__arm__) || defined(__arm32__)
+#  define RT_ARCH_ARM
+# else /* PORTME: append test for new archs. */
+#  error "Check what predefined macros your compiler uses to indicate architecture."
+# endif
+/* PORTME: append new archs checks. */
+#elif defined(RT_ARCH_X86) && defined(RT_ARCH_AMD64)
+# error "Both RT_ARCH_X86 and RT_ARCH_AMD64 cannot be defined at the same time!"
+#elif defined(RT_ARCH_X86) && defined(RT_ARCH_SPARC)
+# error "Both RT_ARCH_X86 and RT_ARCH_SPARC cannot be defined at the same time!"
+#elif defined(RT_ARCH_X86) && defined(RT_ARCH_SPARC64)
+# error "Both RT_ARCH_X86 and RT_ARCH_SPARC64 cannot be defined at the same time!"
+#elif defined(RT_ARCH_AMD64) && defined(RT_ARCH_SPARC)
+# error "Both RT_ARCH_AMD64 and RT_ARCH_SPARC cannot be defined at the same time!"
+#elif defined(RT_ARCH_AMD64) && defined(RT_ARCH_SPARC64)
+# error "Both RT_ARCH_AMD64 and RT_ARCH_SPARC64 cannot be defined at the same time!"
+#elif defined(RT_ARCH_SPARC) && defined(RT_ARCH_SPARC64)
+# error "Both RT_ARCH_SPARC and RT_ARCH_SPARC64 cannot be defined at the same time!"
+#elif defined(RT_ARCH_ARM) && defined(RT_ARCH_AMD64)
+# error "Both RT_ARCH_ARM and RT_ARCH_AMD64 cannot be defined at the same time!"
+#elif defined(RT_ARCH_ARM) && defined(RT_ARCH_X86)
+# error "Both RT_ARCH_ARM and RT_ARCH_X86 cannot be defined at the same time!"
+#elif defined(RT_ARCH_ARM) && defined(RT_ARCH_SPARC64)
+# error "Both RT_ARCH_ARM and RT_ARCH_SPARC64 cannot be defined at the same time!"
+#elif defined(RT_ARCH_ARM) && defined(RT_ARCH_SPARC)
+# error "Both RT_ARCH_ARM and RT_ARCH_SPARC cannot be defined at the same time!"
+#endif
+
+
+/** @def __X86__
+ * Indicates that we're compiling for the X86 architecture.
+ * @deprecated
+ */
+
+/** @def __AMD64__
+ * Indicates that we're compiling for the AMD64 architecture.
+ * @deprecated
+ */
+#if !defined(__X86__) && !defined(__AMD64__) && (defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86))
+# if defined(RT_ARCH_AMD64)
+#  define __AMD64__
+# elif defined(RT_ARCH_X86)
+#  define __X86__
+# else
+#  error "Check what predefined macros your compiler uses to indicate architecture."
+# endif
+#elif defined(__X86__) && defined(__AMD64__)
+# error "Both __X86__ and __AMD64__ cannot be defined at the same time!"
+#elif defined(__X86__) && !defined(RT_ARCH_X86)
+# error "__X86__ without RT_ARCH_X86!"
+#elif defined(__AMD64__) && !defined(RT_ARCH_AMD64)
+# error "__AMD64__ without RT_ARCH_AMD64!"
+#endif
+
+/** @def RT_BIG_ENDIAN
+ * Defined if the architecture is big endian.  */
+/** @def RT_LITTLE_ENDIAN
+ * Defined if the architecture is little endian.  */
+#if defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86) || defined(RT_ARCH_ARM)
+# define RT_LITTLE_ENDIAN
+#elif defined(RT_ARCH_SPARC) || defined(RT_ARCH_SPARC64)
+# define RT_BIG_ENDIAN
+#else
+# error "PORTME: architecture endianess"
+#endif
+#if defined(RT_BIG_ENDIAN) && defined(RT_LITTLE_ENDIAN)
+# error "Both RT_BIG_ENDIAN and RT_LITTLE_ENDIAN are defined"
+#endif
+
+
+/** @def IN_RING0
+ * Used to indicate that we're compiling code which is running
+ * in Ring-0 Host Context.
+ */
+
+/** @def IN_RING3
+ * Used to indicate that we're compiling code which is running
+ * in Ring-3 Host Context.
+ */
+
+/** @def IN_RC
+ * Used to indicate that we're compiling code which is running
+ * in the Raw-mode Context (implies R0).
+ */
+#if !defined(IN_RING3) && !defined(IN_RING0) && !defined(IN_RC) && !defined(IN_RC)
+# error "You must define which context the compiled code should run in; IN_RING3, IN_RING0 or IN_RC"
+#endif
+#if (defined(IN_RING3) && (defined(IN_RING0) || defined(IN_RC)) ) \
+ || (defined(IN_RING0) && (defined(IN_RING3) || defined(IN_RC)) ) \
+ || (defined(IN_RC)    && (defined(IN_RING3) || defined(IN_RING0)) )
+# error "Only one of the IN_RING3, IN_RING0, IN_RC defines should be defined."
+#endif
+
+
+/** @def ARCH_BITS
+ * Defines the bit count of the current context.
+ */
+#if !defined(ARCH_BITS) || defined(DOXYGEN_RUNNING)
+# if defined(RT_ARCH_AMD64) || defined(RT_ARCH_SPARC64)
+#  define ARCH_BITS 64
+# else
+#  define ARCH_BITS 32
+# endif
+#endif
+
+/** @def HC_ARCH_BITS
+ * Defines the host architecture bit count.
+ */
+#if !defined(HC_ARCH_BITS) || defined(DOXYGEN_RUNNING)
+# ifndef IN_RC
+#  define HC_ARCH_BITS ARCH_BITS
+# else
+#  define HC_ARCH_BITS 32
+# endif
+#endif
+
+/** @def GC_ARCH_BITS
+ * Defines the guest architecture bit count.
+ */
+#if !defined(GC_ARCH_BITS) && !defined(DOXYGEN_RUNNING)
+# ifdef VBOX_WITH_64_BITS_GUESTS
+#  define GC_ARCH_BITS  64
+# else
+#  define GC_ARCH_BITS  32
+# endif
+#endif
+
+/** @def R3_ARCH_BITS
+ * Defines the host ring-3 architecture bit count.
+ */
+#if !defined(R3_ARCH_BITS) || defined(DOXYGEN_RUNNING)
+# ifdef IN_RING3
+#  define R3_ARCH_BITS ARCH_BITS
+# else
+#  define R3_ARCH_BITS HC_ARCH_BITS
+# endif
+#endif
+
+/** @def R0_ARCH_BITS
+ * Defines the host ring-0 architecture bit count.
+ */
+#if !defined(R0_ARCH_BITS) || defined(DOXYGEN_RUNNING)
+# ifdef IN_RING0
+#  define R0_ARCH_BITS ARCH_BITS
+# else
+#  define R0_ARCH_BITS HC_ARCH_BITS
+# endif
+#endif
+
+/** @def GC_ARCH_BITS
+ * Defines the guest architecture bit count.
+ */
+#if !defined(GC_ARCH_BITS) || defined(DOXYGEN_RUNNING)
+# ifdef IN_RC
+#  define GC_ARCH_BITS ARCH_BITS
+# else
+#  define GC_ARCH_BITS 32
+# endif
+#endif
+
+
+
+/** @name RT_OPSYS_XXX - Operative System Identifiers.
+ * These are the value that the RT_OPSYS \#define can take. @{
+ */
+/** Unknown OS. */
+#define RT_OPSYS_UNKNOWN    0
+/** OS Agnostic. */
+#define RT_OPSYS_AGNOSTIC   1
+/** Darwin - aka Mac OS X. */
+#define RT_OPSYS_DARWIN     2
+/** DragonFly BSD. */
+#define RT_OPSYS_DRAGONFLY  3
+/** DOS. */
+#define RT_OPSYS_DOS        4
+/** FreeBSD. */
+#define RT_OPSYS_FREEBSD    5
+/** Haiku. */
+#define RT_OPSYS_HAIKU      6
+/** Linux. */
+#define RT_OPSYS_LINUX      7
+/** L4. */
+#define RT_OPSYS_L4         8
+/** Minix. */
+#define RT_OPSYS_MINIX      9
+/** NetBSD. */
+#define RT_OPSYS_NETBSD     11
+/** Netware. */
+#define RT_OPSYS_NETWARE    12
+/** NT (native). */
+#define RT_OPSYS_NT         13
+/** OpenBSD. */
+#define RT_OPSYS_OPENBSD    14
+/** OS/2. */
+#define RT_OPSYS_OS2        15
+/** Plan 9. */
+#define RT_OPSYS_PLAN9      16
+/** QNX. */
+#define RT_OPSYS_QNX        17
+/** Solaris. */
+#define RT_OPSYS_SOLARIS    18
+/** UEFI. */
+#define RT_OPSYS_UEFI       19
+/** Windows. */
+#define RT_OPSYS_WINDOWS    20
+/** The max RT_OPSYS_XXX value (exclusive). */
+#define RT_OPSYS_MAX        21
+/** @} */
+
+/** @def RT_OPSYS
+ * Indicates which OS we're targeting. It's a \#define with is
+ * assigned one of the RT_OPSYS_XXX defines above.
+ *
+ * So to test if we're on FreeBSD do the following:
+ * @code
+ *  #if RT_OPSYS == RT_OPSYS_FREEBSD
+ *  some_funky_freebsd_specific_stuff();
+ *  #endif
+ * @endcode
+ */
+
+/*
+ * Set RT_OPSYS_XXX according to RT_OS_XXX.
+ *
+ * Search:  #define RT_OPSYS_([A-Z0-9]+) .*
+ * Replace: # elif defined(RT_OS_\1)\n#  define RT_OPSYS RT_OPSYS_\1
+ */
+#ifndef RT_OPSYS
+# if defined(RT_OS_UNKNOWN) || defined(DOXYGEN_RUNNING)
+#  define RT_OPSYS RT_OPSYS_UNKNOWN
+# elif defined(RT_OS_AGNOSTIC)
+#  define RT_OPSYS RT_OPSYS_AGNOSTIC
+# elif defined(RT_OS_DARWIN)
+#  define RT_OPSYS RT_OPSYS_DARWIN
+# elif defined(RT_OS_DRAGONFLY)
+#  define RT_OPSYS RT_OPSYS_DRAGONFLY
+# elif defined(RT_OS_DOS)
+#  define RT_OPSYS RT_OPSYS_DOS
+# elif defined(RT_OS_FREEBSD)
+#  define RT_OPSYS RT_OPSYS_FREEBSD
+# elif defined(RT_OS_HAIKU)
+#  define RT_OPSYS RT_OPSYS_HAIKU
+# elif defined(RT_OS_LINUX)
+#  define RT_OPSYS RT_OPSYS_LINUX
+# elif defined(RT_OS_L4)
+#  define RT_OPSYS RT_OPSYS_L4
+# elif defined(RT_OS_MINIX)
+#  define RT_OPSYS RT_OPSYS_MINIX
+# elif defined(RT_OS_NETBSD)
+#  define RT_OPSYS RT_OPSYS_NETBSD
+# elif defined(RT_OS_NETWARE)
+#  define RT_OPSYS RT_OPSYS_NETWARE
+# elif defined(RT_OS_NT)
+#  define RT_OPSYS RT_OPSYS_NT
+# elif defined(RT_OS_OPENBSD)
+#  define RT_OPSYS RT_OPSYS_OPENBSD
+# elif defined(RT_OS_OS2)
+#  define RT_OPSYS RT_OPSYS_OS2
+# elif defined(RT_OS_PLAN9)
+#  define RT_OPSYS RT_OPSYS_PLAN9
+# elif defined(RT_OS_QNX)
+#  define RT_OPSYS RT_OPSYS_QNX
+# elif defined(RT_OS_SOLARIS)
+#  define RT_OPSYS RT_OPSYS_SOLARIS
+# elif defined(RT_OS_UEFI)
+#  define RT_OPSYS RT_OPSYS_UEFI
+# elif defined(RT_OS_WINDOWS)
+#  define RT_OPSYS RT_OPSYS_WINDOWS
+# endif
+#endif
+
+/*
+ * Guess RT_OPSYS based on compiler predefined macros.
+ */
+#ifndef RT_OPSYS
+# if defined(__APPLE__)
+#  define RT_OPSYS      RT_OPSYS_DARWIN
+# elif defined(__DragonFly__)
+#  define RT_OPSYS      RT_OPSYS_DRAGONFLY
+# elif defined(__FreeBSD__) /*??*/
+#  define RT_OPSYS      RT_OPSYS_FREEBSD
+# elif defined(__gnu_linux__)
+#  define RT_OPSYS      RT_OPSYS_LINUX
+# elif defined(__NetBSD__) /*??*/
+#  define RT_OPSYS      RT_OPSYS_NETBSD
+# elif defined(__OpenBSD__) /*??*/
+#  define RT_OPSYS      RT_OPSYS_OPENBSD
+# elif defined(__OS2__)
+#  define RT_OPSYS      RT_OPSYS_OS2
+# elif defined(__sun__) || defined(__SunOS__) || defined(__sun) || defined(__SunOS)
+#  define RT_OPSYS      RT_OPSYS_SOLARIS
+# elif defined(_WIN32) || defined(_WIN64)
+#  define RT_OPSYS      RT_OPSYS_WINDOWS
+# else
+#  error "Port Me"
+# endif
+#endif
+
+#if RT_OPSYS < RT_OPSYS_UNKNOWN || RT_OPSYS >= RT_OPSYS_MAX
+# error "Invalid RT_OPSYS value."
+#endif
+
+/*
+ * Do some consistency checks.
+ *
+ * Search:  #define RT_OPSYS_([A-Z0-9]+) .*
+ * Replace: #if defined(RT_OS_\1) && RT_OPSYS != RT_OPSYS_\1\n# error RT_OPSYS vs RT_OS_\1\n#endif
+ */
+#if defined(RT_OS_UNKNOWN) && RT_OPSYS != RT_OPSYS_UNKNOWN
+# error RT_OPSYS vs RT_OS_UNKNOWN
+#endif
+#if defined(RT_OS_AGNOSTIC) && RT_OPSYS != RT_OPSYS_AGNOSTIC
+# error RT_OPSYS vs RT_OS_AGNOSTIC
+#endif
+#if defined(RT_OS_DARWIN) && RT_OPSYS != RT_OPSYS_DARWIN
+# error RT_OPSYS vs RT_OS_DARWIN
+#endif
+#if defined(RT_OS_DRAGONFLY) && RT_OPSYS != RT_OPSYS_DRAGONFLY
+# error RT_OPSYS vs RT_OS_DRAGONFLY
+#endif
+#if defined(RT_OS_DOS) && RT_OPSYS != RT_OPSYS_DOS
+# error RT_OPSYS vs RT_OS_DOS
+#endif
+#if defined(RT_OS_FREEBSD) && RT_OPSYS != RT_OPSYS_FREEBSD
+# error RT_OPSYS vs RT_OS_FREEBSD
+#endif
+#if defined(RT_OS_HAIKU) && RT_OPSYS != RT_OPSYS_HAIKU
+# error RT_OPSYS vs RT_OS_HAIKU
+#endif
+#if defined(RT_OS_LINUX) && RT_OPSYS != RT_OPSYS_LINUX
+# error RT_OPSYS vs RT_OS_LINUX
+#endif
+#if defined(RT_OS_L4) && RT_OPSYS != RT_OPSYS_L4
+# error RT_OPSYS vs RT_OS_L4
+#endif
+#if defined(RT_OS_MINIX) && RT_OPSYS != RT_OPSYS_MINIX
+# error RT_OPSYS vs RT_OS_MINIX
+#endif
+#if defined(RT_OS_NETBSD) && RT_OPSYS != RT_OPSYS_NETBSD
+# error RT_OPSYS vs RT_OS_NETBSD
+#endif
+#if defined(RT_OS_NETWARE) && RT_OPSYS != RT_OPSYS_NETWARE
+# error RT_OPSYS vs RT_OS_NETWARE
+#endif
+#if defined(RT_OS_NT) && RT_OPSYS != RT_OPSYS_NT
+# error RT_OPSYS vs RT_OS_NT
+#endif
+#if defined(RT_OS_OPENBSD) && RT_OPSYS != RT_OPSYS_OPENBSD
+# error RT_OPSYS vs RT_OS_OPENBSD
+#endif
+#if defined(RT_OS_OS2) && RT_OPSYS != RT_OPSYS_OS2
+# error RT_OPSYS vs RT_OS_OS2
+#endif
+#if defined(RT_OS_PLAN9) && RT_OPSYS != RT_OPSYS_PLAN9
+# error RT_OPSYS vs RT_OS_PLAN9
+#endif
+#if defined(RT_OS_QNX) && RT_OPSYS != RT_OPSYS_QNX
+# error RT_OPSYS vs RT_OS_QNX
+#endif
+#if defined(RT_OS_SOLARIS) && RT_OPSYS != RT_OPSYS_SOLARIS
+# error RT_OPSYS vs RT_OS_SOLARIS
+#endif
+#if defined(RT_OS_UEFI) && RT_OPSYS != RT_OPSYS_UEFI
+# error RT_OPSYS vs RT_OS_UEFI
+#endif
+#if defined(RT_OS_WINDOWS) && RT_OPSYS != RT_OPSYS_WINDOWS
+# error RT_OPSYS vs RT_OS_WINDOWS
+#endif
+
+/*
+ * Make sure the RT_OS_XXX macro is defined.
+ *
+ * Search:  #define RT_OPSYS_([A-Z0-9]+) .*
+ * Replace: #elif RT_OPSYS == RT_OPSYS_\1\n# ifndef RT_OS_\1\n#  define RT_OS_\1\n# endif
+ */
+#if RT_OPSYS == RT_OPSYS_UNKNOWN
+# ifndef RT_OS_UNKNOWN
+#  define RT_OS_UNKNOWN
+# endif
+#elif RT_OPSYS == RT_OPSYS_AGNOSTIC
+# ifndef RT_OS_AGNOSTIC
+#  define RT_OS_AGNOSTIC
+# endif
+#elif RT_OPSYS == RT_OPSYS_DARWIN
+# ifndef RT_OS_DARWIN
+#  define RT_OS_DARWIN
+# endif
+#elif RT_OPSYS == RT_OPSYS_DRAGONFLY
+# ifndef RT_OS_DRAGONFLY
+#  define RT_OS_DRAGONFLY
+# endif
+#elif RT_OPSYS == RT_OPSYS_DOS
+# ifndef RT_OS_DOS
+#  define RT_OS_DOS
+# endif
+#elif RT_OPSYS == RT_OPSYS_FREEBSD
+# ifndef RT_OS_FREEBSD
+#  define RT_OS_FREEBSD
+# endif
+#elif RT_OPSYS == RT_OPSYS_HAIKU
+# ifndef RT_OS_HAIKU
+#  define RT_OS_HAIKU
+# endif
+#elif RT_OPSYS == RT_OPSYS_LINUX
+# ifndef RT_OS_LINUX
+#  define RT_OS_LINUX
+# endif
+#elif RT_OPSYS == RT_OPSYS_L4
+# ifndef RT_OS_L4
+#  define RT_OS_L4
+# endif
+#elif RT_OPSYS == RT_OPSYS_MINIX
+# ifndef RT_OS_MINIX
+#  define RT_OS_MINIX
+# endif
+#elif RT_OPSYS == RT_OPSYS_NETBSD
+# ifndef RT_OS_NETBSD
+#  define RT_OS_NETBSD
+# endif
+#elif RT_OPSYS == RT_OPSYS_NETWARE
+# ifndef RT_OS_NETWARE
+#  define RT_OS_NETWARE
+# endif
+#elif RT_OPSYS == RT_OPSYS_NT
+# ifndef RT_OS_NT
+#  define RT_OS_NT
+# endif
+#elif RT_OPSYS == RT_OPSYS_OPENBSD
+# ifndef RT_OS_OPENBSD
+#  define RT_OS_OPENBSD
+# endif
+#elif RT_OPSYS == RT_OPSYS_OS2
+# ifndef RT_OS_OS2
+#  define RT_OS_OS2
+# endif
+#elif RT_OPSYS == RT_OPSYS_PLAN9
+# ifndef RT_OS_PLAN9
+#  define RT_OS_PLAN9
+# endif
+#elif RT_OPSYS == RT_OPSYS_QNX
+# ifndef RT_OS_QNX
+#  define RT_OS_QNX
+# endif
+#elif RT_OPSYS == RT_OPSYS_SOLARIS
+# ifndef RT_OS_SOLARIS
+#  define RT_OS_SOLARIS
+# endif
+#elif RT_OPSYS == RT_OPSYS_UEFI
+# ifndef RT_OS_UEFI
+#  define RT_OS_UEFI
+# endif
+#elif RT_OPSYS == RT_OPSYS_WINDOWS
+# ifndef RT_OS_WINDOWS
+#  define RT_OS_WINDOWS
+# endif
+#else
+# error "Bad RT_OPSYS value."
+#endif
+
+
+/**
+ * Checks whether the given OpSys uses DOS-style paths or not.
+ *
+ * By DOS-style paths we include drive lettering and UNC paths.
+ *
+ * @returns true / false
+ * @param   a_OpSys     The RT_OPSYS_XXX value to check, will be reference
+ *                      multiple times.
+ */
+#define RT_OPSYS_USES_DOS_PATHS(a_OpSys) \
+    (   (a_OpSys) == RT_OPSYS_WINDOWS \
+     || (a_OpSys) == RT_OPSYS_OS2 \
+     || (a_OpSys) == RT_OPSYS_DOS )
+
+
+
+/** @def CTXTYPE
+ * Declare a type differently in GC, R3 and R0.
+ *
+ * @param   GCType  The GC type.
+ * @param   R3Type  The R3 type.
+ * @param   R0Type  The R0 type.
+ * @remark  For pointers used only in one context use RCPTRTYPE(), R3R0PTRTYPE(), R3PTRTYPE() or R0PTRTYPE().
+ */
+#ifdef IN_RC
+# define CTXTYPE(GCType, R3Type, R0Type)  GCType
+#elif defined(IN_RING3)
+# define CTXTYPE(GCType, R3Type, R0Type)  R3Type
+#else
+# define CTXTYPE(GCType, R3Type, R0Type)  R0Type
+#endif
+
+/** @def RCPTRTYPE
+ * Declare a pointer which is used in the raw mode context but appears in structure(s) used by
+ * both HC and RC. The main purpose is to make sure structures have the same
+ * size when built for different architectures.
+ *
+ * @param   RCType  The RC type.
+ */
+#define RCPTRTYPE(RCType)       CTXTYPE(RCType, RTRCPTR, RTRCPTR)
+
+/** @def R3R0PTRTYPE
+ * Declare a pointer which is used in HC, is explicitly valid in ring 3 and 0,
+ * but appears in structure(s) used by both HC and GC. The main purpose is to
+ * make sure structures have the same size when built for different architectures.
+ *
+ * @param   R3R0Type  The R3R0 type.
+ * @remarks This used to be called HCPTRTYPE.
+ */
+#define R3R0PTRTYPE(R3R0Type)   CTXTYPE(RTHCPTR, R3R0Type, R3R0Type)
+
+/** @def R3PTRTYPE
+ * Declare a pointer which is used in R3 but appears in structure(s) used by
+ * both HC and GC. The main purpose is to make sure structures have the same
+ * size when built for different architectures.
+ *
+ * @param   R3Type  The R3 type.
+ */
+#define R3PTRTYPE(R3Type)       CTXTYPE(RTHCUINTPTR, R3Type, RTHCUINTPTR)
+
+/** @def R0PTRTYPE
+ * Declare a pointer which is used in R0 but appears in structure(s) used by
+ * both HC and GC. The main purpose is to make sure structures have the same
+ * size when built for different architectures.
+ *
+ * @param   R0Type  The R0 type.
+ */
+#define R0PTRTYPE(R0Type)       CTXTYPE(RTHCUINTPTR, RTHCUINTPTR, R0Type)
+
+/** @def CTXSUFF
+ * Adds the suffix of the current context to the passed in
+ * identifier name. The suffix is HC or GC.
+ *
+ * This is macro should only be used in shared code to avoid a forest of ifdefs.
+ * @param   var     Identifier name.
+ * @deprecated Use CTX_SUFF. Do NOT use this for new code.
+ */
+/** @def OTHERCTXSUFF
+ * Adds the suffix of the other context to the passed in
+ * identifier name. The suffix is HC or GC.
+ *
+ * This is macro should only be used in shared code to avoid a forest of ifdefs.
+ * @param   var     Identifier name.
+ * @deprecated Use CTX_SUFF. Do NOT use this for new code.
+ */
+#ifdef IN_RC
+# define CTXSUFF(var)       var##GC
+# define OTHERCTXSUFF(var)  var##HC
+#else
+# define CTXSUFF(var)       var##HC
+# define OTHERCTXSUFF(var)  var##GC
+#endif
+
+/** @def CTXALLSUFF
+ * Adds the suffix of the current context to the passed in
+ * identifier name. The suffix is R3, R0 or GC.
+ *
+ * This is macro should only be used in shared code to avoid a forest of ifdefs.
+ * @param   var     Identifier name.
+ * @deprecated Use CTX_SUFF. Do NOT use this for new code.
+ */
+#ifdef IN_RC
+# define CTXALLSUFF(var)    var##GC
+#elif defined(IN_RING0)
+# define CTXALLSUFF(var)    var##R0
+#else
+# define CTXALLSUFF(var)    var##R3
+#endif
+
+/** @def CTX_SUFF
+ * Adds the suffix of the current context to the passed in
+ * identifier name. The suffix is R3, R0 or RC.
+ *
+ * This is macro should only be used in shared code to avoid a forest of ifdefs.
+ * @param   var     Identifier name.
+ *
+ * @remark  This will replace CTXALLSUFF and CTXSUFF before long.
+ */
+#ifdef IN_RC
+# define CTX_SUFF(var)      var##RC
+#elif defined(IN_RING0)
+# define CTX_SUFF(var)      var##R0
+#else
+# define CTX_SUFF(var)      var##R3
+#endif
+
+/** @def CTX_SUFF_Z
+ * Adds the suffix of the current context to the passed in
+ * identifier name, combining RC and R0 into RZ.
+ * The suffix thus is R3 or RZ.
+ *
+ * This is macro should only be used in shared code to avoid a forest of ifdefs.
+ * @param   var     Identifier name.
+ *
+ * @remark  This will replace CTXALLSUFF and CTXSUFF before long.
+ */
+#ifdef IN_RING3
+# define CTX_SUFF_Z(var)    var##R3
+#else
+# define CTX_SUFF_Z(var)    var##RZ
+#endif
+
+
+/** @def CTXMID
+ * Adds the current context as a middle name of an identifier name
+ * The middle name is HC or GC.
+ *
+ * This is macro should only be used in shared code to avoid a forest of ifdefs.
+ * @param   first   First name.
+ * @param   last    Surname.
+ */
+/** @def OTHERCTXMID
+ * Adds the other context as a middle name of an identifier name
+ * The middle name is HC or GC.
+ *
+ * This is macro should only be used in shared code to avoid a forest of ifdefs.
+ * @param   first   First name.
+ * @param   last    Surname.
+ * @deprecated use CTX_MID or CTX_MID_Z
+ */
+#ifdef IN_RC
+# define CTXMID(first, last)        first##GC##last
+# define OTHERCTXMID(first, last)   first##HC##last
+#else
+# define CTXMID(first, last)        first##HC##last
+# define OTHERCTXMID(first, last)   first##GC##last
+#endif
+
+/** @def CTXALLMID
+ * Adds the current context as a middle name of an identifier name.
+ * The middle name is R3, R0 or GC.
+ *
+ * This is macro should only be used in shared code to avoid a forest of ifdefs.
+ * @param   first   First name.
+ * @param   last    Surname.
+ * @deprecated use CTX_MID or CTX_MID_Z
+ */
+#ifdef IN_RC
+# define CTXALLMID(first, last)     first##GC##last
+#elif defined(IN_RING0)
+# define CTXALLMID(first, last)     first##R0##last
+#else
+# define CTXALLMID(first, last)     first##R3##last
+#endif
+
+/** @def CTX_MID
+ * Adds the current context as a middle name of an identifier name.
+ * The middle name is R3, R0 or RC.
+ *
+ * This is macro should only be used in shared code to avoid a forest of ifdefs.
+ * @param   first   First name.
+ * @param   last    Surname.
+ */
+#ifdef IN_RC
+# define CTX_MID(first, last)       first##RC##last
+#elif defined(IN_RING0)
+# define CTX_MID(first, last)       first##R0##last
+#else
+# define CTX_MID(first, last)       first##R3##last
+#endif
+
+/** @def CTX_MID_Z
+ * Adds the current context as a middle name of an identifier name, combining RC
+ * and R0 into RZ.
+ * The middle name thus is either R3 or RZ.
+ *
+ * This is macro should only be used in shared code to avoid a forest of ifdefs.
+ * @param   first   First name.
+ * @param   last    Surname.
+ */
+#ifdef IN_RING3
+# define CTX_MID_Z(first, last)     first##R3##last
+#else
+# define CTX_MID_Z(first, last)     first##RZ##last
+#endif
+
+
+/** @def R3STRING
+ * A macro which in GC and R0 will return a dummy string while in R3 it will return
+ * the parameter.
+ *
+ * This is typically used to wrap description strings in structures shared
+ * between R3, R0 and/or GC. The intention is to avoid the \#ifdef IN_RING3 mess.
+ *
+ * @param   pR3String   The R3 string. Only referenced in R3.
+ * @see R0STRING and GCSTRING
+ */
+#ifdef IN_RING3
+# define R3STRING(pR3String)    (pR3String)
+#else
+# define R3STRING(pR3String)    ("<R3_STRING>")
+#endif
+
+/** @def R0STRING
+ * A macro which in GC and R3 will return a dummy string while in R0 it will return
+ * the parameter.
+ *
+ * This is typically used to wrap description strings in structures shared
+ * between R3, R0 and/or GC. The intention is to avoid the \#ifdef IN_RING0 mess.
+ *
+ * @param   pR0String   The R0 string. Only referenced in R0.
+ * @see R3STRING and GCSTRING
+ */
+#ifdef IN_RING0
+# define R0STRING(pR0String)    (pR0String)
+#else
+# define R0STRING(pR0String)    ("<R0_STRING>")
+#endif
+
+/** @def RCSTRING
+ * A macro which in R3 and R0 will return a dummy string while in RC it will return
+ * the parameter.
+ *
+ * This is typically used to wrap description strings in structures shared
+ * between R3, R0 and/or RC. The intention is to avoid the \#ifdef IN_RC mess.
+ *
+ * @param   pRCString   The RC string. Only referenced in RC.
+ * @see R3STRING, R0STRING
+ */
+#ifdef IN_RC
+# define RCSTRING(pRCString)    (pRCString)
+#else
+# define RCSTRING(pRCString)    ("<RC_STRING>")
+#endif
+
+
+/** @def RT_NOTHING
+ * A macro that expands to nothing.
+ * This is primarily intended as a dummy argument for macros to avoid the
+ * undefined behavior passing empty arguments to an macro (ISO C90 and C++98,
+ * gcc v4.4 warns about it).
+ */
+#define RT_NOTHING
+
+/** @def RT_GCC_EXTENSION
+ * Macro for shutting up GCC warnings about using language extensions. */
+#ifdef __GNUC__
+# define RT_GCC_EXTENSION       __extension__
+#else
+# define RT_GCC_EXTENSION
+#endif
+
+/** @def RT_COMPILER_GROKS_64BIT_BITFIELDS
+ * Macro that is defined if the compiler understands 64-bit bitfields. */
+#if !defined(RT_OS_OS2) || (!defined(__IBMC__) && !defined(__IBMCPP__))
+# define RT_COMPILER_GROKS_64BIT_BITFIELDS
+#endif
+
+/** @def RT_COMPILER_WITH_80BIT_LONG_DOUBLE
+ * Macro that is defined if the compiler implements long double as the
+ * IEEE extended precision floating. */
+#if (defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86)) && !defined(RT_OS_WINDOWS)
+# define RT_COMPILER_WITH_80BIT_LONG_DOUBLE
+#endif
+
+
+/** @def RT_EXCEPTIONS_ENABLED
+ * Defined when C++ exceptions are enabled.
+ */
+#if !defined(RT_EXCEPTIONS_ENABLED) \
+ &&  defined(__cplusplus) \
+ && (   (defined(_MSC_VER) && defined(_CPPUNWIND)) \
+     || (defined(__GNUC__) && defined(__EXCEPTIONS)))
+# define RT_EXCEPTIONS_ENABLED
+#endif
+
+/** @def RT_NO_THROW_PROTO
+ * How to express that a function doesn't throw C++ exceptions
+ * and the compiler can thus save itself the bother of trying
+ * to catch any of them. Put this between the closing parenthesis
+ * and the semicolon in function prototypes (and implementation if C++).
+ *
+ * @remarks May not work on C++ methods, mainly intented for C-style APIs.
+ *
+ * @remarks The use of the nothrow attribute with GCC is because old compilers
+ *          (4.1.1, 32-bit) leaking the nothrow into global space or something
+ *          when used with RTDECL or similar.  Using this forces use to have two
+ *          macros, as the nothrow attribute is not for the function definition.
+ */
+#ifdef RT_EXCEPTIONS_ENABLED
+# ifdef __GNUC__
+#  define RT_NO_THROW_PROTO     __attribute__((__nothrow__))
+# else
+#  define RT_NO_THROW_PROTO     throw()
+# endif
+#else
+# define RT_NO_THROW_PROTO
+#endif
+
+/** @def RT_NO_THROW_DEF
+ * The counter part to RT_NO_THROW_PROTO that is added to the function
+ * definition.
+ */
+#if defined(RT_EXCEPTIONS_ENABLED) && !defined(__GNUC__)
+# define RT_NO_THROW_DEF        RT_NO_THROW_PROTO
+#else
+# define RT_NO_THROW_DEF
+#endif
+
+/** @def RT_THROW
+ * How to express that a method or function throws a type of exceptions. Some
+ * compilers does not want this kind of information and will warning about it.
+ *
+ * @param   type    The type exception.
+ *
+ * @remarks If the actual throwing is done from the header, enclose it by
+ *          \#ifdef RT_EXCEPTIONS_ENABLED ... \#else ... \#endif so the header
+ *          compiles cleanly without exceptions enabled.
+ *
+ *          Do NOT use this for the actual throwing of exceptions!
+ */
+#ifdef RT_EXCEPTIONS_ENABLED
+# ifdef _MSC_VER
+#  if _MSC_VER >= 1310
+#   define RT_THROW(type)
+#  else
+#   define RT_THROW(type)       throw(type)
+#  endif
+# else
+#  define RT_THROW(type)        throw(type)
+# endif
+#else
+# define RT_THROW(type)
+#endif
+
+/** @def RT_IPRT_FORMAT_ATTR
+ * Identifies a function taking an IPRT format string.
+ * @param   a_iFmt  The index (1-based) of the format string argument.
+ * @param   a_iArgs The index (1-based) of the first format argument, use 0 for
+ *                  va_list.
+ */
+#if defined(__GNUC__) && defined(WITH_IPRT_FORMAT_ATTRIBUTE)
+# define RT_IPRT_FORMAT_ATTR(a_iFmt, a_iArgs)   __attribute__((__iprt_format__(a_iFmt, a_iArgs)))
+#else
+# define RT_IPRT_FORMAT_ATTR(a_iFmt, a_iArgs)
+#endif
+
+/** @def RT_IPRT_FORMAT_ATTR_MAYBE_NULL
+ * Identifies a function taking an IPRT format string, NULL is allowed.
+ * @param   a_iFmt  The index (1-based) of the format string argument.
+ * @param   a_iArgs The index (1-based) of the first format argument, use 0 for
+ *                  va_list.
+ */
+#if defined(__GNUC__) && defined(WITH_IPRT_FORMAT_ATTRIBUTE)
+# define RT_IPRT_FORMAT_ATTR_MAYBE_NULL(a_iFmt, a_iArgs)   __attribute__((__iprt_format_maybe_null__(a_iFmt, a_iArgs)))
+#else
+# define RT_IPRT_FORMAT_ATTR_MAYBE_NULL(a_iFmt, a_iArgs)
+#endif
+
+
+/** @def RT_GCC_SUPPORTS_VISIBILITY_HIDDEN
+ * Indicates that the "hidden" visibility attribute can be used (GCC) */
+#if defined(__GNUC__)
+# if __GNUC__ >= 4 && !defined(RT_OS_OS2) && !defined(RT_OS_WINDOWS)
+#  define RT_GCC_SUPPORTS_VISIBILITY_HIDDEN
+# endif
+#endif
+
+/** @def RTCALL
+ * The standard calling convention for the Runtime interfaces.
+ *
+ * @remarks The regparm(0) in the X86/GNUC variant deals with -mregparm=x use in
+ *          the linux kernel and potentially elsewhere (3rd party).
+ */
+#ifdef _MSC_VER
+# define RTCALL                 __cdecl
+#elif defined(RT_OS_OS2)
+# define RTCALL                 __cdecl
+#elif defined(__GNUC__) && defined(RT_ARCH_X86)
+# define RTCALL                 __attribute__((cdecl,regparm(0)))
+#else
+# define RTCALL
+#endif
+
+/** @def DECLEXPORT
+ * How to declare an exported function.
+ * @param   type    The return type of the function declaration.
+ */
+#if defined(_MSC_VER) || defined(RT_OS_OS2)
+# define DECLEXPORT(type)       __declspec(dllexport) type
+#elif defined(RT_USE_VISIBILITY_DEFAULT)
+# define DECLEXPORT(type)      __attribute__((visibility("default"))) type
+#else
+# define DECLEXPORT(type)      type
+#endif
+
+/** @def DECLIMPORT
+ * How to declare an imported function.
+ * @param   type    The return type of the function declaration.
+ */
+#if defined(_MSC_VER) || (defined(RT_OS_OS2) && !defined(__IBMC__) && !defined(__IBMCPP__))
+# define DECLIMPORT(type)       __declspec(dllimport) type
+#else
+# define DECLIMPORT(type)       type
+#endif
+
+/** @def DECLHIDDEN
+ * How to declare a non-exported function or variable.
+ * @param   type    The return type of the function or the data type of the variable.
+ */
+#if !defined(RT_GCC_SUPPORTS_VISIBILITY_HIDDEN) || defined(RT_NO_VISIBILITY_HIDDEN)
+# define DECLHIDDEN(type)       type
+#else
+# define DECLHIDDEN(type)       __attribute__((visibility("hidden"))) type
+#endif
+
+/** @def DECL_HIDDEN_CONST
+ * Workaround for g++ warnings when applying the hidden attribute to a const
+ * definition.  Use DECLHIDDEN for the declaration.
+ * @param   a_Type      The return type of the function or the data type of
+ *                      the variable.
+ */
+#if defined(__cplusplus) && defined(__GNUC__)
+# define DECL_HIDDEN_CONST(a_Type)   a_Type
+#else
+# define DECL_HIDDEN_CONST(a_Type)   DECLHIDDEN(a_Type)
+#endif
+
+/** @def DECL_INVALID
+ * How to declare a function not available for linking in the current context.
+ * The purpose is to create compile or like time errors when used.  This isn't
+ * possible on all platforms.
+ * @param   type    The return type of the function.
+ */
+#if defined(_MSC_VER)
+# define DECL_INVALID(type)     __declspec(dllimport) type __stdcall
+#elif defined(__GNUC__) && defined(__cplusplus)
+# define DECL_INVALID(type)     extern "C++" type
+#else
+# define DECL_INVALID(type)     type
+#endif
+
+/** @def DECLASM
+ * How to declare an internal assembly function.
+ * @param   type    The return type of the function declaration.
+ */
+#ifdef __cplusplus
+# define DECLASM(type)           extern "C" type RTCALL
+#else
+# define DECLASM(type)           type RTCALL
+#endif
+
+/** @def DECLASMTYPE
+ * How to declare an internal assembly function type.
+ * @param   type    The return type of the function.
+ */
+#define DECLASMTYPE(type)       type RTCALL
+
+/** @def DECLNORETURN
+ * How to declare a function which does not return.
+ * @note: This macro can be combined with other macros, for example
+ * @code
+ *   EMR3DECL(DECLNORETURN(void)) foo(void);
+ * @endcode
+ */
+#ifdef _MSC_VER
+# define DECLNORETURN(type)     __declspec(noreturn) type
+#elif defined(__GNUC__)
+# define DECLNORETURN(type)     __attribute__((noreturn)) type
+#else
+# define DECLNORETURN(type)     type
+#endif
+
+/** @def DECLWEAK
+ * How to declare a variable which is not necessarily resolved at
+ * runtime.
+ * @note: This macro can be combined with other macros, for example
+ * @code
+ *   EMR3DECL(DECLWEAK(int)) foo;
+ * @endcode
+ */
+#if defined(__GNUC__)
+# define DECLWEAK(type)         type __attribute__((weak))
+#else
+# define DECLWEAK(type)         type
+#endif
+
+/** @def DECLCALLBACK
+ * How to declare an call back function type.
+ * @param   type    The return type of the function declaration.
+ */
+#define DECLCALLBACK(type)      type RTCALL
+
+/** @def DECLCALLBACKPTR
+ * How to declare an call back function pointer.
+ * @param   type    The return type of the function declaration.
+ * @param   name    The name of the variable member.
+ */
+#if defined(__IBMC__) || defined(__IBMCPP__)
+# define DECLCALLBACKPTR(type, name)    type (* RTCALL name)
+#else
+# define DECLCALLBACKPTR(type, name)    type (RTCALL * name)
+#endif
+
+/** @def DECLCALLBACKMEMBER
+ * How to declare an call back function pointer member.
+ * @param   type    The return type of the function declaration.
+ * @param   name    The name of the struct/union/class member.
+ */
+#if defined(__IBMC__) || defined(__IBMCPP__)
+# define DECLCALLBACKMEMBER(type, name) type (* RTCALL name)
+#else
+# define DECLCALLBACKMEMBER(type, name) type (RTCALL * name)
+#endif
+
+/** @def DECLR3CALLBACKMEMBER
+ * How to declare an call back function pointer member - R3 Ptr.
+ * @param   type    The return type of the function declaration.
+ * @param   name    The name of the struct/union/class member.
+ * @param   args    The argument list enclosed in parentheses.
+ */
+#ifdef IN_RING3
+# define DECLR3CALLBACKMEMBER(type, name, args)  DECLCALLBACKMEMBER(type, name) args
+#else
+# define DECLR3CALLBACKMEMBER(type, name, args)  RTR3PTR name
+#endif
+
+/** @def DECLRCCALLBACKMEMBER
+ * How to declare an call back function pointer member - RC Ptr.
+ * @param   type    The return type of the function declaration.
+ * @param   name    The name of the struct/union/class member.
+ * @param   args    The argument list enclosed in parentheses.
+ */
+#ifdef IN_RC
+# define DECLRCCALLBACKMEMBER(type, name, args)  DECLCALLBACKMEMBER(type, name)  args
+#else
+# define DECLRCCALLBACKMEMBER(type, name, args)  RTRCPTR name
+#endif
+
+/** @def DECLR0CALLBACKMEMBER
+ * How to declare an call back function pointer member - R0 Ptr.
+ * @param   type    The return type of the function declaration.
+ * @param   name    The name of the struct/union/class member.
+ * @param   args    The argument list enclosed in parentheses.
+ */
+#ifdef IN_RING0
+# define DECLR0CALLBACKMEMBER(type, name, args)  DECLCALLBACKMEMBER(type, name) args
+#else
+# define DECLR0CALLBACKMEMBER(type, name, args)  RTR0PTR name
+#endif
+
+/** @def DECLINLINE
+ * How to declare a function as inline.
+ * @param   type    The return type of the function declaration.
+ * @remarks Don't use this macro on C++ methods.
+ */
+#ifdef __GNUC__
+# define DECLINLINE(type) static __inline__ type
+#elif defined(__cplusplus)
+# define DECLINLINE(type) inline type
+#elif defined(_MSC_VER)
+# define DECLINLINE(type) _inline type
+#elif defined(__IBMC__)
+# define DECLINLINE(type) _Inline type
+#else
+# define DECLINLINE(type) inline type
+#endif
+
+
+/** @def DECL_FORCE_INLINE
+ * How to declare a function as inline and try convince the compiler to always
+ * inline it regardless of optimization switches.
+ * @param   type    The return type of the function declaration.
+ * @remarks Use sparsely and with care. Don't use this macro on C++ methods.
+ */
+#ifdef __GNUC__
+# define DECL_FORCE_INLINE(type)    __attribute__((__always_inline__)) DECLINLINE(type)
+#elif defined(_MSC_VER)
+# define DECL_FORCE_INLINE(type)    __forceinline type
+#else
+# define DECL_FORCE_INLINE(type)    DECLINLINE(type)
+#endif
+
+
+/** @def DECL_NO_INLINE
+ * How to declare a function telling the compiler not to inline it.
+ * @param   scope   The function scope, static or RT_NOTHING.
+ * @param   type    The return type of the function declaration.
+ * @remarks Don't use this macro on C++ methods.
+ */
+#ifdef __GNUC__
+# define DECL_NO_INLINE(scope,type) __attribute__((__noinline__)) scope type
+#elif defined(_MSC_VER)
+# define DECL_NO_INLINE(scope,type) __declspec(noinline) scope type
+#else
+# define DECL_NO_INLINE(scope,type) scope type
+#endif
+
+
+/** @def IN_RT_STATIC
+ * Used to indicate whether we're linking against a static IPRT
+ * or not. The IPRT symbols will be declared as hidden (if
+ * supported). Note that this define has no effect without setting
+ * IN_RT_R0, IN_RT_R3 or IN_RT_RC indicators are set first.
+ */
+
+/** @def IN_RT_R0
+ * Used to indicate whether we're inside the same link module as
+ * the HC Ring-0 Runtime Library.
+ */
+/** @def RTR0DECL(type)
+ * Runtime Library HC Ring-0 export or import declaration.
+ * @param   type    The return type of the function declaration.
+ */
+#ifdef IN_RT_R0
+# ifdef IN_RT_STATIC
+#  define RTR0DECL(type)    DECLHIDDEN(type) RTCALL
+# else
+#  define RTR0DECL(type)    DECLEXPORT(type) RTCALL
+# endif
+#else
+# define RTR0DECL(type)     DECLIMPORT(type) RTCALL
+#endif
+
+/** @def IN_RT_R3
+ * Used to indicate whether we're inside the same link module as
+ * the HC Ring-3 Runtime Library.
+ */
+/** @def RTR3DECL(type)
+ * Runtime Library HC Ring-3 export or import declaration.
+ * @param   type    The return type of the function declaration.
+ */
+#ifdef IN_RT_R3
+# ifdef IN_RT_STATIC
+#  define RTR3DECL(type)    DECLHIDDEN(type) RTCALL
+# else
+#  define RTR3DECL(type)    DECLEXPORT(type) RTCALL
+# endif
+#else
+# define RTR3DECL(type)     DECLIMPORT(type) RTCALL
+#endif
+
+/** @def IN_RT_RC
+ * Used to indicate whether we're inside the same link module as the raw-mode
+ * context (RC) runtime library.
+ */
+/** @def RTRCDECL(type)
+ * Runtime Library raw-mode context export or import declaration.
+ * @param   type    The return type of the function declaration.
+ */
+#ifdef IN_RT_RC
+# ifdef IN_RT_STATIC
+#  define RTRCDECL(type)    DECLHIDDEN(type) RTCALL
+# else
+#  define RTRCDECL(type)    DECLEXPORT(type) RTCALL
+# endif
+#else
+# define RTRCDECL(type)     DECLIMPORT(type) RTCALL
+#endif
+
+/** @def RTDECL(type)
+ * Runtime Library export or import declaration.
+ * Functions declared using this macro exists in all contexts.
+ * @param   type    The return type of the function declaration.
+ */
+#if defined(IN_RT_R3) || defined(IN_RT_RC) || defined(IN_RT_R0)
+# ifdef IN_RT_STATIC
+#  define RTDECL(type)      DECLHIDDEN(type) RTCALL
+# else
+#  define RTDECL(type)      DECLEXPORT(type) RTCALL
+# endif
+#else
+# define RTDECL(type)       DECLIMPORT(type) RTCALL
+#endif
+
+/** @def RTDATADECL(type)
+ * Runtime Library export or import declaration.
+ * Data declared using this macro exists in all contexts.
+ * @param   type    The data type.
+ */
+/** @def RT_DECL_DATA_CONST(type)
+ * Definition of a const variable. See DECL_HIDDEN_CONST.
+ * @param   type    The const data type.
+ */
+#if defined(IN_RT_R3) || defined(IN_RT_RC) || defined(IN_RT_R0)
+# ifdef IN_RT_STATIC
+#  define RTDATADECL(type)          DECLHIDDEN(type)
+#  define RT_DECL_DATA_CONST(type)  DECL_HIDDEN_CONST(type)
+# else
+#  define RTDATADECL(type)          DECLEXPORT(type)
+#  if defined(__cplusplus) && defined(__GNUC__)
+#   define RT_DECL_DATA_CONST(type) type
+#  else
+#   define RT_DECL_DATA_CONST(type) DECLEXPORT(type)
+#  endif
+# endif
+#else
+# define RTDATADECL(type)           DECLIMPORT(type)
+# define RT_DECL_DATA_CONST(type)   DECLIMPORT(type)
+#endif
+
+/** @def RT_DECL_CLASS
+ * Declares an class living in the runtime.
+ */
+#if defined(IN_RT_R3) || defined(IN_RT_RC) || defined(IN_RT_R0)
+# ifdef IN_RT_STATIC
+#  define RT_DECL_CLASS
+# else
+#  define RT_DECL_CLASS     DECLEXPORT_CLASS
+# endif
+#else
+# define RT_DECL_CLASS      DECLIMPORT_CLASS
+#endif
+
+
+/** @def RT_NOCRT
+ * Symbol name wrapper for the No-CRT bits.
+ *
+ * In order to coexist in the same process as other CRTs, we need to
+ * decorate the symbols such that they don't conflict the ones in the
+ * other CRTs. The result of such conflicts / duplicate symbols can
+ * confuse the dynamic loader on Unix like systems.
+ *
+ * Define RT_WITHOUT_NOCRT_WRAPPERS to drop the wrapping.
+ * Define RT_WITHOUT_NOCRT_WRAPPER_ALIASES to drop the aliases to the
+ * wrapped names.
+ */
+/** @def RT_NOCRT_STR
+ * Same as RT_NOCRT only it'll return a double quoted string of the result.
+ */
+#ifndef RT_WITHOUT_NOCRT_WRAPPERS
+# define RT_NOCRT(name) nocrt_ ## name
+# define RT_NOCRT_STR(name) "nocrt_" # name
+#else
+# define RT_NOCRT(name) name
+# define RT_NOCRT_STR(name) #name
+#endif
+
+
+
+/** @def RT_LIKELY
+ * Give the compiler a hint that an expression is very likely to hold true.
+ *
+ * Some compilers support explicit branch prediction so that the CPU backend
+ * can hint the processor and also so that code blocks can be reordered such
+ * that the predicted path sees a more linear flow, thus improving cache
+ * behaviour, etc.
+ *
+ * IPRT provides the macros RT_LIKELY() and RT_UNLIKELY() as a way to utilize
+ * this compiler feature when present.
+ *
+ * A few notes about the usage:
+ *
+ *      - Generally, order your code use RT_LIKELY() instead of RT_UNLIKELY().
+ *
+ *      - Generally, use RT_UNLIKELY() with error condition checks (unless you
+ *        have some _strong_ reason to do otherwise, in which case document it),
+ *        and/or RT_LIKELY() with success condition checks, assuming you want
+ *        to optimize for the success path.
+ *
+ *      - Other than that, if you don't know the likelihood of a test succeeding
+ *        from empirical or other 'hard' evidence, don't make predictions unless
+ *        you happen to be a Dirk Gently character.
+ *
+ *      - These macros are meant to be used in places that get executed a lot. It
+ *        is wasteful to make predictions in code that is executed rarely (e.g.
+ *        at subsystem initialization time) as the basic block reordering that this
+ *        affects can often generate larger code.
+ *
+ *      - Note that RT_SUCCESS() and RT_FAILURE() already makes use of RT_LIKELY()
+ *        and RT_UNLIKELY().  Should you wish for prediction free status checks,
+ *        use the RT_SUCCESS_NP() and RT_FAILURE_NP() macros instead.
+ *
+ *
+ * @returns the boolean result of the expression.
+ * @param   expr        The expression that's very likely to be true.
+ * @see     RT_UNLIKELY
+ */
+/** @def RT_UNLIKELY
+ * Give the compiler a hint that an expression is highly unlikely to hold true.
+ *
+ * See the usage instructions give in the RT_LIKELY() docs.
+ *
+ * @returns the boolean result of the expression.
+ * @param   expr        The expression that's very unlikely to be true.
+ * @see     RT_LIKELY
+ *
+ * @deprecated Please use RT_LIKELY() instead wherever possible!  That gives us
+ *          a better chance of the windows compilers to generate favorable code
+ *          too.  The belief is that the compiler will by default assume the
+ *          if-case is more likely than the else-case.
+ */
+#if defined(__GNUC__)
+# if __GNUC__ >= 3 && !defined(FORTIFY_RUNNING)
+#  define RT_LIKELY(expr)       __builtin_expect(!!(expr), 1)
+#  define RT_UNLIKELY(expr)     __builtin_expect(!!(expr), 0)
+# else
+#  define RT_LIKELY(expr)       (expr)
+#  define RT_UNLIKELY(expr)     (expr)
+# endif
+#else
+# define RT_LIKELY(expr)        (expr)
+# define RT_UNLIKELY(expr)      (expr)
+#endif
+
+
+/** @def RT_STR
+ * Returns the argument as a string constant.
+ * @param   str     Argument to stringify.  */
+#define RT_STR(str)             #str
+/** @def RT_XSTR
+ * Returns the expanded argument as a string.
+ * @param   str     Argument to expand and stringify. */
+#define RT_XSTR(str)            RT_STR(str)
+
+/** @def RT_LSTR_2
+ * Helper for RT_WSTR that gets the expanded @a str.
+ * @param   str     String litteral to prefix with 'L'.  */
+#define RT_LSTR_2(str)          L##str
+/** @def RT_LSTR
+ * Returns the expanded argument with a L string prefix.
+ *
+ * Intended for converting ASCII string \#defines into wide char string
+ * litterals on Windows.
+ *
+ * @param   str     String litteral to . */
+#define RT_LSTR(str)            RT_LSTR_2(str)
+
+/** @def RT_CONCAT
+ * Concatenate the expanded arguments without any extra spaces in between.
+ *
+ * @param   a       The first part.
+ * @param   b       The second part.
+ */
+#define RT_CONCAT(a,b)              RT_CONCAT_HLP(a,b)
+/** RT_CONCAT helper, don't use.  */
+#define RT_CONCAT_HLP(a,b)          a##b
+
+/** @def RT_CONCAT3
+ * Concatenate the expanded arguments without any extra spaces in between.
+ *
+ * @param   a       The 1st part.
+ * @param   b       The 2nd part.
+ * @param   c       The 3rd part.
+ */
+#define RT_CONCAT3(a,b,c)           RT_CONCAT3_HLP(a,b,c)
+/** RT_CONCAT3 helper, don't use.  */
+#define RT_CONCAT3_HLP(a,b,c)       a##b##c
+
+/** @def RT_CONCAT4
+ * Concatenate the expanded arguments without any extra spaces in between.
+ *
+ * @param   a       The 1st part.
+ * @param   b       The 2nd part.
+ * @param   c       The 3rd part.
+ * @param   d       The 4th part.
+ */
+#define RT_CONCAT4(a,b,c,d)         RT_CONCAT4_HLP(a,b,c,d)
+/** RT_CONCAT4 helper, don't use.  */
+#define RT_CONCAT4_HLP(a,b,c,d)     a##b##c##d
+
+/**
+ * String constant tuple - string constant, strlen(string constant).
+ *
+ * @param   a_szConst   String constant.
+ * @sa      RTSTRTUPLE
+ */
+#define RT_STR_TUPLE(a_szConst)  a_szConst, (sizeof(a_szConst) - 1)
+
+
+/**
+ * Macro for using in switch statements that turns constants into strings.
+ *
+ * @param   a_Const     The constant (not string).
+ */
+#define RT_CASE_RET_STR(a_Const)     case a_Const: return #a_Const
+
+
+/** @def RT_BIT
+ * Convert a bit number into an integer bitmask (unsigned).
+ * @param   bit     The bit number.
+ */
+#define RT_BIT(bit)                             ( 1U << (bit) )
+
+/** @def RT_BIT_32
+ * Convert a bit number into a 32-bit bitmask (unsigned).
+ * @param   bit     The bit number.
+ */
+#define RT_BIT_32(bit)                          ( UINT32_C(1) << (bit) )
+
+/** @def RT_BIT_64
+ * Convert a bit number into a 64-bit bitmask (unsigned).
+ * @param   bit     The bit number.
+ */
+#define RT_BIT_64(bit)                          ( UINT64_C(1) << (bit) )
+
+/** @def RT_ALIGN
+ * Align macro.
+ * @param   u           Value to align.
+ * @param   uAlignment  The alignment. Power of two!
+ *
+ * @remark  Be extremely careful when using this macro with type which sizeof != sizeof int.
+ *          When possible use any of the other RT_ALIGN_* macros. And when that's not
+ *          possible, make 101% sure that uAlignment is specified with a right sized type.
+ *
+ *          Specifying an unsigned 32-bit alignment constant with a 64-bit value will give
+ *          you a 32-bit return value!
+ *
+ *          In short: Don't use this macro. Use RT_ALIGN_T() instead.
+ */
+#define RT_ALIGN(u, uAlignment)                 ( ((u) + ((uAlignment) - 1)) & ~((uAlignment) - 1) )
+
+/** @def RT_ALIGN_T
+ * Align macro.
+ * @param   u           Value to align.
+ * @param   uAlignment  The alignment. Power of two!
+ * @param   type        Integer type to use while aligning.
+ * @remark  This macro is the preferred alignment macro, it doesn't have any of the pitfalls RT_ALIGN has.
+ */
+#define RT_ALIGN_T(u, uAlignment, type)         ( ((type)(u) + ((uAlignment) - 1)) & ~(type)((uAlignment) - 1) )
+
+/** @def RT_ALIGN_32
+ * Align macro for a 32-bit value.
+ * @param   u32         Value to align.
+ * @param   uAlignment  The alignment. Power of two!
+ */
+#define RT_ALIGN_32(u32, uAlignment)            RT_ALIGN_T(u32, uAlignment, uint32_t)
+
+/** @def RT_ALIGN_64
+ * Align macro for a 64-bit value.
+ * @param   u64         Value to align.
+ * @param   uAlignment  The alignment. Power of two!
+ */
+#define RT_ALIGN_64(u64, uAlignment)            RT_ALIGN_T(u64, uAlignment, uint64_t)
+
+/** @def RT_ALIGN_Z
+ * Align macro for size_t.
+ * @param   cb          Value to align.
+ * @param   uAlignment  The alignment. Power of two!
+ */
+#define RT_ALIGN_Z(cb, uAlignment)              RT_ALIGN_T(cb, uAlignment, size_t)
+
+/** @def RT_ALIGN_P
+ * Align macro for pointers.
+ * @param   pv          Value to align.
+ * @param   uAlignment  The alignment. Power of two!
+ */
+#define RT_ALIGN_P(pv, uAlignment)              RT_ALIGN_PT(pv, uAlignment, void *)
+
+/** @def RT_ALIGN_PT
+ * Align macro for pointers with type cast.
+ * @param   u           Value to align.
+ * @param   uAlignment  The alignment. Power of two!
+ * @param   CastType    The type to cast the result to.
+ */
+#define RT_ALIGN_PT(u, uAlignment, CastType)    ( (CastType)RT_ALIGN_T(u, uAlignment, uintptr_t) )
+
+/** @def RT_ALIGN_R3PT
+ * Align macro for ring-3 pointers with type cast.
+ * @param   u           Value to align.
+ * @param   uAlignment  The alignment. Power of two!
+ * @param   CastType    The type to cast the result to.
+ */
+#define RT_ALIGN_R3PT(u, uAlignment, CastType)  ( (CastType)RT_ALIGN_T(u, uAlignment, RTR3UINTPTR) )
+
+/** @def RT_ALIGN_R0PT
+ * Align macro for ring-0 pointers with type cast.
+ * @param   u           Value to align.
+ * @param   uAlignment  The alignment. Power of two!
+ * @param   CastType    The type to cast the result to.
+ */
+#define RT_ALIGN_R0PT(u, uAlignment, CastType)  ( (CastType)RT_ALIGN_T(u, uAlignment, RTR0UINTPTR) )
+
+/** @def RT_ALIGN_GCPT
+ * Align macro for GC pointers with type cast.
+ * @param   u           Value to align.
+ * @param   uAlignment  The alignment. Power of two!
+ * @param   CastType        The type to cast the result to.
+ */
+#define RT_ALIGN_GCPT(u, uAlignment, CastType)  ( (CastType)RT_ALIGN_T(u, uAlignment, RTGCUINTPTR) )
+
+
+/** @def RT_OFFSETOF
+ * Our own special offsetof() variant, returns a signed result.
+ *
+ * This differs from the usual offsetof() in that it's not relying on builtin
+ * compiler stuff and thus can use variables in arrays the structure may
+ * contain. This is useful to determine the sizes of structures ending
+ * with a variable length field. For gcc >= 4.4 see @bugref{7775}.
+ *
+ * @returns offset into the structure of the specified member. signed.
+ * @param   type    Structure type.
+ * @param   member  Member.
+ */
+#if defined(__GNUC__) && defined(__cplusplus) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4))
+# define RT_OFFSETOF(type, member)              ( (int)(uintptr_t)&( ((type *)(void *)0x1000)->member) - 0x1000 )
+#else
+# define RT_OFFSETOF(type, member)              ( (int)(uintptr_t)&( ((type *)(void *)0)->member) )
+#endif
+
+/** @def RT_UOFFSETOF
+ * Our own special offsetof() variant, returns an unsigned result.
+ *
+ * This differs from the usual offsetof() in that it's not relying on builtin
+ * compiler stuff and thus can use variables in arrays the structure may
+ * contain. This is useful to determine the sizes of structures ending
+ * with a variable length field. For gcc >= 4.4 see @bugref{7775}.
+ *
+ * @returns offset into the structure of the specified member. unsigned.
+ * @param   type    Structure type.
+ * @param   member  Member.
+ */
+#if defined(__GNUC__) && defined(__cplusplus) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4))
+# define RT_UOFFSETOF(type, member)             ( (uintptr_t)&( ((type *)(void *)0x1000)->member) - 0x1000 )
+#else
+# define RT_UOFFSETOF(type, member)             ( (uintptr_t)&( ((type *)(void *)0)->member) )
+#endif
+
+/** @def RT_OFFSETOF_ADD
+ * RT_OFFSETOF with an addend.
+ *
+ * @returns offset into the structure of the specified member. signed.
+ * @param   type    Structure type.
+ * @param   member  Member.
+ * @param   addend  The addend to add to the offset.
+ */
+#define RT_OFFSETOF_ADD(type, member, addend)   ( (int)RT_UOFFSETOF_ADD(type, member, addend) )
+
+/** @def RT_UOFFSETOF_ADD
+ * RT_UOFFSETOF with an addend.
+ *
+ * @returns offset into the structure of the specified member. signed.
+ * @param   type    Structure type.
+ * @param   member  Member.
+ * @param   addend  The addend to add to the offset.
+ */
+#define RT_UOFFSETOF_ADD(type, member, addend)  ( (uintptr_t)&( ((type *)(void *)(uintptr_t)(addend))->member) )
+
+/** @def RT_SIZEOFMEMB
+ * Get the size of a structure member.
+ *
+ * @returns size of the structure member.
+ * @param   type    Structure type.
+ * @param   member  Member.
+ */
+#define RT_SIZEOFMEMB(type, member)             ( sizeof(((type *)(void *)0)->member) )
+
+/** @def RT_FROM_MEMBER
+ * Convert a pointer to a structure member into a pointer to the structure.
+ *
+ * @returns pointer to the structure.
+ * @param   pMem    Pointer to the member.
+ * @param   Type    Structure type.
+ * @param   Member  Member name.
+ */
+#define RT_FROM_MEMBER(pMem, Type, Member)      ( (Type *) ((uint8_t *)(void *)(pMem) - RT_UOFFSETOF(Type, Member)) )
+
+/** @def RT_FROM_CPP_MEMBER
+ * Same as RT_FROM_MEMBER except it avoids the annoying g++ warnings about
+ * invalid access to non-static data member of NULL object.
+ *
+ * @returns pointer to the structure.
+ * @param   pMem    Pointer to the member.
+ * @param   Type    Structure type.
+ * @param   Member  Member name.
+ *
+ * @remarks Using the __builtin_offsetof does not shut up the compiler.
+ */
+#if defined(__GNUC__) && defined(__cplusplus)
+# define RT_FROM_CPP_MEMBER(pMem, Type, Member) \
+        ( (Type *) ((uintptr_t)(pMem) - (uintptr_t)&((Type *)0x1000)->Member + 0x1000U) )
+#else
+# define RT_FROM_CPP_MEMBER(pMem, Type, Member) RT_FROM_MEMBER(pMem, Type, Member)
+#endif
+
+/** @def RT_ELEMENTS
+ * Calculates the number of elements in a statically sized array.
+ * @returns Element count.
+ * @param   aArray      Array in question.
+ */
+#define RT_ELEMENTS(aArray)                     ( sizeof(aArray) / sizeof((aArray)[0]) )
+
+/**
+ * Checks if the value is a power of two.
+ *
+ * @returns true if power of two, false if not.
+ * @param   uVal                The value to test.
+ * @remarks 0 is a power of two.
+ * @see     VERR_NOT_POWER_OF_TWO
+ */
+#define RT_IS_POWER_OF_TWO(uVal)                ( ((uVal) & ((uVal) - 1)) == 0)
+
+#ifdef RT_OS_OS2
+/* Undefine RT_MAX since there is an unfortunate clash with the max
+   resource type define in os2.h. */
+# undef RT_MAX
+#endif
+
+/** @def RT_MAX
+ * Finds the maximum value.
+ * @returns The higher of the two.
+ * @param   Value1      Value 1
+ * @param   Value2      Value 2
+ */
+#define RT_MAX(Value1, Value2)                  ( (Value1) >= (Value2) ? (Value1) : (Value2) )
+
+/** @def RT_MIN
+ * Finds the minimum value.
+ * @returns The lower of the two.
+ * @param   Value1      Value 1
+ * @param   Value2      Value 2
+ */
+#define RT_MIN(Value1, Value2)                  ( (Value1) <= (Value2) ? (Value1) : (Value2) )
+
+/** @def RT_CLAMP
+ * Clamps the value to minimum and maximum values.
+ * @returns The clamped value.
+ * @param   Value       The value to check.
+ * @param   Min         Minimum value.
+ * @param   Max         Maximum value.
+ */
+#define RT_CLAMP(Value, Min, Max)               ( (Value) > (Max) ? (Max) : (Value) < (Min) ? (Min) : (Value) )
+
+/** @def RT_ABS
+ * Get the absolute (non-negative) value.
+ * @returns The absolute value of Value.
+ * @param   Value       The value.
+ */
+#define RT_ABS(Value)                           ( (Value) >= 0 ? (Value) : -(Value) )
+
+/** @def RT_BOOL
+ * Turn non-zero/zero into true/false
+ * @returns The resulting boolean value.
+ * @param   Value       The value.
+ */
+#define RT_BOOL(Value)                          ( !!(Value) )
+
+/** @def RT_LO_U8
+ * Gets the low uint8_t of a uint16_t or something equivalent. */
+#ifdef __GNUC__
+# define RT_LO_U8(a)    __extension__ ({ AssertCompile(sizeof((a)) == sizeof(uint16_t)); (uint8_t)(a); })
+#else
+# define RT_LO_U8(a)                            ( (uint8_t)(a) )
+#endif
+/** @def RT_HI_U8
+ * Gets the high uint8_t of a uint16_t or something equivalent. */
+#ifdef __GNUC__
+# define RT_HI_U8(a)    __extension__ ({ AssertCompile(sizeof((a)) == sizeof(uint16_t)); (uint8_t)((a) >> 8); })
+#else
+# define RT_HI_U8(a)                            ( (uint8_t)((a) >> 8) )
+#endif
+
+/** @def RT_LO_U16
+ * Gets the low uint16_t of a uint32_t or something equivalent. */
+#ifdef __GNUC__
+# define RT_LO_U16(a)   __extension__ ({ AssertCompile(sizeof((a)) == sizeof(uint32_t)); (uint16_t)(a); })
+#else
+# define RT_LO_U16(a)                           ( (uint16_t)(a) )
+#endif
+/** @def RT_HI_U16
+ * Gets the high uint16_t of a uint32_t or something equivalent. */
+#ifdef __GNUC__
+# define RT_HI_U16(a)   __extension__ ({ AssertCompile(sizeof((a)) == sizeof(uint32_t)); (uint16_t)((a) >> 16); })
+#else
+# define RT_HI_U16(a)                           ( (uint16_t)((a) >> 16) )
+#endif
+
+/** @def RT_LO_U32
+ * Gets the low uint32_t of a uint64_t or something equivalent. */
+#ifdef __GNUC__
+# define RT_LO_U32(a)   __extension__ ({ AssertCompile(sizeof((a)) == sizeof(uint64_t)); (uint32_t)(a); })
+#else
+# define RT_LO_U32(a)                           ( (uint32_t)(a) )
+#endif
+/** @def RT_HI_U32
+ * Gets the high uint32_t of a uint64_t or something equivalent. */
+#ifdef __GNUC__
+# define RT_HI_U32(a)   __extension__ ({ AssertCompile(sizeof((a)) == sizeof(uint64_t)); (uint32_t)((a) >> 32); })
+#else
+# define RT_HI_U32(a)                           ( (uint32_t)((a) >> 32) )
+#endif
+
+/** @def RT_BYTE1
+ * Gets the first byte of something. */
+#define RT_BYTE1(a)                             ( (a)         & 0xff )
+/** @def RT_BYTE2
+ * Gets the second byte of something. */
+#define RT_BYTE2(a)                             ( ((a) >>  8) & 0xff )
+/** @def RT_BYTE3
+ * Gets the second byte of something. */
+#define RT_BYTE3(a)                             ( ((a) >> 16) & 0xff )
+/** @def RT_BYTE4
+ * Gets the fourth byte of something. */
+#define RT_BYTE4(a)                             ( ((a) >> 24) & 0xff )
+/** @def RT_BYTE5
+ * Gets the fifth byte of something. */
+#define RT_BYTE5(a)                             ( ((a) >> 32) & 0xff )
+/** @def RT_BYTE6
+ * Gets the sixth byte of something. */
+#define RT_BYTE6(a)                             ( ((a) >> 40) & 0xff )
+/** @def RT_BYTE7
+ * Gets the seventh byte of something. */
+#define RT_BYTE7(a)                             ( ((a) >> 48) & 0xff )
+/** @def RT_BYTE8
+ * Gets the eight byte of something. */
+#define RT_BYTE8(a)                             ( ((a) >> 56) & 0xff )
+
+
+/** @def RT_LODWORD
+ * Gets the low dword (=uint32_t) of something.
+ * @deprecated  Use RT_LO_U32. */
+#define RT_LODWORD(a)                           ( (uint32_t)(a) )
+/** @def RT_HIDWORD
+ * Gets the high dword (=uint32_t) of a 64-bit of something.
+ * @deprecated  Use RT_HI_U32. */
+#define RT_HIDWORD(a)                           ( (uint32_t)((a) >> 32) )
+
+/** @def RT_LOWORD
+ * Gets the low word (=uint16_t) of something.
+ * @deprecated  Use RT_LO_U16. */
+#define RT_LOWORD(a)                            ( (a) & 0xffff )
+/** @def RT_HIWORD
+ * Gets the high word (=uint16_t) of a 32-bit something.
+ * @deprecated  Use RT_HI_U16. */
+#define RT_HIWORD(a)                            ( (a) >> 16 )
+
+/** @def RT_LOBYTE
+ * Gets the low byte of something.
+ * @deprecated  Use RT_LO_U8. */
+#define RT_LOBYTE(a)                            ( (a) & 0xff )
+/** @def RT_HIBYTE
+ * Gets the high byte of a 16-bit something.
+ * @deprecated  Use RT_HI_U8. */
+#define RT_HIBYTE(a)                            ( (a) >> 8 )
+
+
+/** @def RT_MAKE_U64
+ * Constructs a uint64_t value from two uint32_t values.
+ */
+#define RT_MAKE_U64(Lo, Hi)                     ( (uint64_t)((uint32_t)(Hi)) << 32 | (uint32_t)(Lo) )
+
+/** @def RT_MAKE_U64_FROM_U16
+ * Constructs a uint64_t value from four uint16_t values.
+ */
+#define RT_MAKE_U64_FROM_U16(w0, w1, w2, w3) \
+    ((uint64_t)(  (uint64_t)((uint16_t)(w3)) << 48 \
+                | (uint64_t)((uint16_t)(w2)) << 32 \
+                | (uint32_t)((uint16_t)(w1)) << 16 \
+                |            (uint16_t)(w0) ))
+
+/** @def RT_MAKE_U64_FROM_U8
+ * Constructs a uint64_t value from eight uint8_t values.
+ */
+#define RT_MAKE_U64_FROM_U8(b0, b1, b2, b3, b4, b5, b6, b7) \
+    ((uint64_t)(  (uint64_t)((uint8_t)(b7)) << 56 \
+                | (uint64_t)((uint8_t)(b6)) << 48 \
+                | (uint64_t)((uint8_t)(b5)) << 40 \
+                | (uint64_t)((uint8_t)(b4)) << 32 \
+                | (uint32_t)((uint8_t)(b3)) << 24 \
+                | (uint32_t)((uint8_t)(b2)) << 16 \
+                | (uint16_t)((uint8_t)(b1)) << 8 \
+                |            (uint8_t)(b0) ))
+
+/** @def RT_MAKE_U32
+ * Constructs a uint32_t value from two uint16_t values.
+ */
+#define RT_MAKE_U32(Lo, Hi) \
+    ((uint32_t)(  (uint32_t)((uint16_t)(Hi)) << 16 \
+                | (uint16_t)(Lo) ))
+
+/** @def RT_MAKE_U32_FROM_U8
+ * Constructs a uint32_t value from four uint8_t values.
+ */
+#define RT_MAKE_U32_FROM_U8(b0, b1, b2, b3) \
+    ((uint32_t)(  (uint32_t)((uint8_t)(b3)) << 24 \
+                | (uint32_t)((uint8_t)(b2)) << 16 \
+                | (uint16_t)((uint8_t)(b1)) << 8 \
+                |            (uint8_t)(b0) ))
+
+/** @def RT_MAKE_U16
+ * Constructs a uint16_t value from two uint8_t values.
+ */
+#define RT_MAKE_U16(Lo, Hi) \
+    ((uint16_t)(  (uint16_t)((uint8_t)(Hi)) << 8 \
+                | (uint8_t)(Lo) ))
+
+
+/** @def RT_BSWAP_U64
+ * Reverses the byte order of an uint64_t value. */
+#if 0
+# define RT_BSWAP_U64(u64)  RT_BSWAP_U64_C(u64)
+#elif defined(__GNUC__)
+# define RT_BSWAP_U64(u64)  (__builtin_constant_p((u64)) \
+                            ? RT_BSWAP_U64_C(u64) : ASMByteSwapU64(u64))
+#else
+# define RT_BSWAP_U64(u64)  ASMByteSwapU64(u64)
+#endif
+
+/** @def RT_BSWAP_U32
+ * Reverses the byte order of an uint32_t value. */
+#if 0
+# define RT_BSWAP_U32(u32)  RT_BSWAP_U32_C(u32)
+#elif defined(__GNUC__)
+# define RT_BSWAP_U32(u32)  (__builtin_constant_p((u32)) \
+                            ? RT_BSWAP_U32_C(u32) : ASMByteSwapU32(u32))
+#else
+# define RT_BSWAP_U32(u32)  ASMByteSwapU32(u32)
+#endif
+
+/** @def RT_BSWAP_U16
+ * Reverses the byte order of an uint16_t value. */
+#if 0
+# define RT_BSWAP_U16(u16)  RT_BSWAP_U16_C(u16)
+#elif defined(__GNUC__)
+# define RT_BSWAP_U16(u16)  (__builtin_constant_p((u16)) \
+                            ? RT_BSWAP_U16_C(u16) : ASMByteSwapU16(u16))
+#else
+# define RT_BSWAP_U16(u16)  ASMByteSwapU16(u16)
+#endif
+
+
+/** @def RT_BSWAP_U64_C
+ * Reverses the byte order of an uint64_t constant. */
+#define RT_BSWAP_U64_C(u64) RT_MAKE_U64(RT_BSWAP_U32_C((u64) >> 32), RT_BSWAP_U32_C((u64) & 0xffffffff))
+
+/** @def RT_BSWAP_U32_C
+ * Reverses the byte order of an uint32_t constant. */
+#define RT_BSWAP_U32_C(u32) RT_MAKE_U32_FROM_U8(RT_BYTE4(u32), RT_BYTE3(u32), RT_BYTE2(u32), RT_BYTE1(u32))
+
+/** @def RT_BSWAP_U16_C
+ * Reverses the byte order of an uint16_t constant. */
+#define RT_BSWAP_U16_C(u16) RT_MAKE_U16(RT_HIBYTE(u16), RT_LOBYTE(u16))
+
+
+/** @def RT_H2LE_U64
+ * Converts an uint64_t value from host to little endian byte order. */
+#ifdef RT_BIG_ENDIAN
+# define RT_H2LE_U64(u64)   RT_BSWAP_U64(u64)
+#else
+# define RT_H2LE_U64(u64)   (u64)
+#endif
+
+/** @def RT_H2LE_U64_C
+ * Converts an uint64_t constant from host to little endian byte order. */
+#ifdef RT_BIG_ENDIAN
+# define RT_H2LE_U64_C(u64) RT_BSWAP_U64_C(u64)
+#else
+# define RT_H2LE_U64_C(u64) (u64)
+#endif
+
+/** @def RT_H2LE_U32
+ * Converts an uint32_t value from host to little endian byte order. */
+#ifdef RT_BIG_ENDIAN
+# define RT_H2LE_U32(u32)   RT_BSWAP_U32(u32)
+#else
+# define RT_H2LE_U32(u32)   (u32)
+#endif
+
+/** @def RT_H2LE_U32_C
+ * Converts an uint32_t constant from host to little endian byte order. */
+#ifdef RT_BIG_ENDIAN
+# define RT_H2LE_U32_C(u32) RT_BSWAP_U32_C(u32)
+#else
+# define RT_H2LE_U32_C(u32) (u32)
+#endif
+
+/** @def RT_H2LE_U16
+ * Converts an uint16_t value from host to little endian byte order. */
+#ifdef RT_BIG_ENDIAN
+# define RT_H2LE_U16(u16)   RT_BSWAP_U16(u16)
+#else
+# define RT_H2LE_U16(u16)   (u16)
+#endif
+
+/** @def RT_H2LE_U16_C
+ * Converts an uint16_t constant from host to little endian byte order. */
+#ifdef RT_BIG_ENDIAN
+# define RT_H2LE_U16_C(u16) RT_BSWAP_U16_C(u16)
+#else
+# define RT_H2LE_U16_C(u16) (u16)
+#endif
+
+
+/** @def RT_LE2H_U64
+ * Converts an uint64_t value from little endian to host byte order. */
+#ifdef RT_BIG_ENDIAN
+# define RT_LE2H_U64(u64)   RT_BSWAP_U64(u64)
+#else
+# define RT_LE2H_U64(u64)   (u64)
+#endif
+
+/** @def RT_LE2H_U64_C
+ * Converts an uint64_t constant from little endian to host byte order. */
+#ifdef RT_BIG_ENDIAN
+# define RT_LE2H_U64_C(u64) RT_BSWAP_U64_C(u64)
+#else
+# define RT_LE2H_U64_C(u64) (u64)
+#endif
+
+/** @def RT_LE2H_U32
+ * Converts an uint32_t value from little endian to host byte order. */
+#ifdef RT_BIG_ENDIAN
+# define RT_LE2H_U32(u32)   RT_BSWAP_U32(u32)
+#else
+# define RT_LE2H_U32(u32)   (u32)
+#endif
+
+/** @def RT_LE2H_U32_C
+ * Converts an uint32_t constant from little endian to host byte order. */
+#ifdef RT_BIG_ENDIAN
+# define RT_LE2H_U32_C(u32) RT_BSWAP_U32_C(u32)
+#else
+# define RT_LE2H_U32_C(u32) (u32)
+#endif
+
+/** @def RT_LE2H_U16
+ * Converts an uint16_t value from little endian to host byte order. */
+#ifdef RT_BIG_ENDIAN
+# define RT_LE2H_U16(u16)   RT_BSWAP_U16(u16)
+#else
+# define RT_LE2H_U16(u16)   (u16)
+#endif
+
+/** @def RT_LE2H_U16_C
+ * Converts an uint16_t constant from little endian to host byte order. */
+#ifdef RT_BIG_ENDIAN
+# define RT_LE2H_U16_C(u16) RT_BSWAP_U16_C(u16)
+#else
+# define RT_LE2H_U16_C(u16) (u16)
+#endif
+
+
+/** @def RT_H2BE_U64
+ * Converts an uint64_t value from host to big endian byte order. */
+#ifdef RT_BIG_ENDIAN
+# define RT_H2BE_U64(u64)   (u64)
+#else
+# define RT_H2BE_U64(u64)   RT_BSWAP_U64(u64)
+#endif
+
+/** @def RT_H2BE_U64_C
+ * Converts an uint64_t constant from host to big endian byte order. */
+#ifdef RT_BIG_ENDIAN
+# define RT_H2BE_U64_C(u64) (u64)
+#else
+# define RT_H2BE_U64_C(u64) RT_BSWAP_U64_C(u64)
+#endif
+
+/** @def RT_H2BE_U32
+ * Converts an uint32_t value from host to big endian byte order. */
+#ifdef RT_BIG_ENDIAN
+# define RT_H2BE_U32(u32)   (u32)
+#else
+# define RT_H2BE_U32(u32)   RT_BSWAP_U32(u32)
+#endif
+
+/** @def RT_H2BE_U32_C
+ * Converts an uint32_t constant from host to big endian byte order. */
+#ifdef RT_BIG_ENDIAN
+# define RT_H2BE_U32_C(u32) (u32)
+#else
+# define RT_H2BE_U32_C(u32) RT_BSWAP_U32_C(u32)
+#endif
+
+/** @def RT_H2BE_U16
+ * Converts an uint16_t value from host to big endian byte order. */
+#ifdef RT_BIG_ENDIAN
+# define RT_H2BE_U16(u16)   (u16)
+#else
+# define RT_H2BE_U16(u16)   RT_BSWAP_U16(u16)
+#endif
+
+/** @def RT_H2BE_U16_C
+ * Converts an uint16_t constant from host to big endian byte order. */
+#ifdef RT_BIG_ENDIAN
+# define RT_H2BE_U16_C(u16) (u16)
+#else
+# define RT_H2BE_U16_C(u16) RT_BSWAP_U16_C(u16)
+#endif
+
+/** @def RT_BE2H_U64
+ * Converts an uint64_t value from big endian to host byte order. */
+#ifdef RT_BIG_ENDIAN
+# define RT_BE2H_U64(u64)   (u64)
+#else
+# define RT_BE2H_U64(u64)   RT_BSWAP_U64(u64)
+#endif
+
+/** @def RT_BE2H_U64
+ * Converts an uint64_t constant from big endian to host byte order. */
+#ifdef RT_BIG_ENDIAN
+# define RT_BE2H_U64_C(u64) (u64)
+#else
+# define RT_BE2H_U64_C(u64) RT_BSWAP_U64_C(u64)
+#endif
+
+/** @def RT_BE2H_U32
+ * Converts an uint32_t value from big endian to host byte order. */
+#ifdef RT_BIG_ENDIAN
+# define RT_BE2H_U32(u32)   (u32)
+#else
+# define RT_BE2H_U32(u32)   RT_BSWAP_U32(u32)
+#endif
+
+/** @def RT_BE2H_U32_C
+ * Converts an uint32_t value from big endian to host byte order. */
+#ifdef RT_BIG_ENDIAN
+# define RT_BE2H_U32_C(u32) (u32)
+#else
+# define RT_BE2H_U32_C(u32) RT_BSWAP_U32_C(u32)
+#endif
+
+/** @def RT_BE2H_U16
+ * Converts an uint16_t value from big endian to host byte order. */
+#ifdef RT_BIG_ENDIAN
+# define RT_BE2H_U16(u16)   (u16)
+#else
+# define RT_BE2H_U16(u16)   RT_BSWAP_U16(u16)
+#endif
+
+/** @def RT_BE2H_U16_C
+ * Converts an uint16_t constant from big endian to host byte order. */
+#ifdef RT_BIG_ENDIAN
+# define RT_BE2H_U16_C(u16) (u16)
+#else
+# define RT_BE2H_U16_C(u16) RT_BSWAP_U16_C(u16)
+#endif
+
+
+/** @def RT_H2N_U64
+ * Converts an uint64_t value from host to network byte order. */
+#define RT_H2N_U64(u64)     RT_H2BE_U64(u64)
+
+/** @def RT_H2N_U64_C
+ * Converts an uint64_t constant from host to network byte order. */
+#define RT_H2N_U64_C(u64)   RT_H2BE_U64_C(u64)
+
+/** @def RT_H2N_U32
+ * Converts an uint32_t value from host to network byte order. */
+#define RT_H2N_U32(u32)     RT_H2BE_U32(u32)
+
+/** @def RT_H2N_U32_C
+ * Converts an uint32_t constant from host to network byte order. */
+#define RT_H2N_U32_C(u32)   RT_H2BE_U32_C(u32)
+
+/** @def RT_H2N_U16
+ * Converts an uint16_t value from host to network byte order. */
+#define RT_H2N_U16(u16)     RT_H2BE_U16(u16)
+
+/** @def RT_H2N_U16_C
+ * Converts an uint16_t constant from host to network byte order. */
+#define RT_H2N_U16_C(u16)   RT_H2BE_U16_C(u16)
+
+/** @def RT_N2H_U64
+ * Converts an uint64_t value from network to host byte order. */
+#define RT_N2H_U64(u64)     RT_BE2H_U64(u64)
+
+/** @def RT_N2H_U64_C
+ * Converts an uint64_t constant from network to host byte order. */
+#define RT_N2H_U64_C(u64)   RT_BE2H_U64_C(u64)
+
+/** @def RT_N2H_U32
+ * Converts an uint32_t value from network to host byte order. */
+#define RT_N2H_U32(u32)     RT_BE2H_U32(u32)
+
+/** @def RT_N2H_U32_C
+ * Converts an uint32_t constant from network to host byte order. */
+#define RT_N2H_U32_C(u32)   RT_BE2H_U32_C(u32)
+
+/** @def RT_N2H_U16
+ * Converts an uint16_t value from network to host byte order. */
+#define RT_N2H_U16(u16)     RT_BE2H_U16(u16)
+
+/** @def RT_N2H_U16_C
+ * Converts an uint16_t value from network to host byte order. */
+#define RT_N2H_U16_C(u16)   RT_BE2H_U16_C(u16)
+
+
+/*
+ * The BSD sys/param.h + machine/param.h file is a major source of
+ * namespace pollution. Kill off some of the worse ones unless we're
+ * compiling kernel code.
+ */
+#if defined(RT_OS_DARWIN) \
+  && !defined(KERNEL) \
+  && !defined(RT_NO_BSD_PARAM_H_UNDEFING) \
+  && ( defined(_SYS_PARAM_H_) || defined(_I386_PARAM_H_) )
+/* sys/param.h: */
+# undef PSWP
+# undef PVM
+# undef PINOD
+# undef PRIBO
+# undef PVFS
+# undef PZERO
+# undef PSOCK
+# undef PWAIT
+# undef PLOCK
+# undef PPAUSE
+# undef PUSER
+# undef PRIMASK
+# undef MINBUCKET
+# undef MAXALLOCSAVE
+# undef FSHIFT
+# undef FSCALE
+
+/* i386/machine.h: */
+# undef ALIGN
+# undef ALIGNBYTES
+# undef DELAY
+# undef STATUS_WORD
+# undef USERMODE
+# undef BASEPRI
+# undef MSIZE
+# undef CLSIZE
+# undef CLSIZELOG2
+#endif
+
+/** @def NIL_OFFSET
+ * NIL offset.
+ * Whenever we use offsets instead of pointers to save space and relocation effort
+ * NIL_OFFSET shall be used as the equivalent to NULL.
+ */
+#define NIL_OFFSET   (~0U)
+
+/** @def NOREF
+ * Keeps the compiler from bitching about an unused parameter.
+ */
+#define NOREF(var)               (void)(var)
+
+/** @def RT_BREAKPOINT
+ * Emit a debug breakpoint instruction.
+ *
+ * @remarks In the x86/amd64 gnu world we add a nop instruction after the int3
+ *          to force gdb to remain at the int3 source line.
+ * @remarks The L4 kernel will try make sense of the breakpoint, thus the jmp on
+ *          x86/amd64.
+ */
+#ifdef __GNUC__
+# if defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86)
+#  if !defined(__L4ENV__)
+#   define RT_BREAKPOINT()      __asm__ __volatile__("int $3\n\tnop\n\t")
+#  else
+#   define RT_BREAKPOINT()      __asm__ __volatile__("int3; jmp 1f; 1:\n\t")
+#  endif
+# elif defined(RT_ARCH_SPARC64)
+#  define RT_BREAKPOINT()       __asm__ __volatile__("illtrap 0\n\t")   /** @todo Sparc64: this is just a wild guess. */
+# elif defined(RT_ARCH_SPARC)
+#  define RT_BREAKPOINT()       __asm__ __volatile__("unimp 0\n\t")     /** @todo Sparc: this is just a wild guess (same as Sparc64, just different name). */
+# endif
+#endif
+#ifdef _MSC_VER
+# define RT_BREAKPOINT()        __debugbreak()
+#endif
+#if defined(__IBMC__) || defined(__IBMCPP__)
+# define RT_BREAKPOINT()        __interrupt(3)
+#endif
+#ifndef RT_BREAKPOINT
+# error "This compiler/arch is not supported!"
+#endif
+
+
+/** @defgroup grp_rt_cdefs_size     Size Constants
+ * (Of course, these are binary computer terms, not SI.)
+ * @{
+ */
+/** 1 K (Kilo)                     (1 024). */
+#define _1K                     0x00000400
+/** 2 K (Kilo)                     (2 048). */
+#define _2K                     0x00000800
+/** 4 K (Kilo)                     (4 096). */
+#define _4K                     0x00001000
+/** 8 K (Kilo)                     (8 192). */
+#define _8K                     0x00002000
+/** 16 K (Kilo)                   (16 384). */
+#define _16K                    0x00004000
+/** 32 K (Kilo)                   (32 678). */
+#define _32K                    0x00008000
+/** 64 K (Kilo)                   (65 536). */
+#define _64K                    0x00010000
+/** 128 K (Kilo)                 (131 072). */
+#define _128K                   0x00020000
+/** 256 K (Kilo)                 (262 144). */
+#define _256K                   0x00040000
+/** 512 K (Kilo)                 (524 288). */
+#define _512K                   0x00080000
+/** 1 M (Mega)                 (1 048 576). */
+#define _1M                     0x00100000
+/** 2 M (Mega)                 (2 097 152). */
+#define _2M                     0x00200000
+/** 4 M (Mega)                 (4 194 304). */
+#define _4M                     0x00400000
+/** 1 G (Giga)             (1 073 741 824). (32-bit) */
+#define _1G                     0x40000000
+/** 1 G (Giga)             (1 073 741 824). (64-bit) */
+#define _1G64                   0x40000000LL
+/** 2 G (Giga)             (2 147 483 648). (32-bit) */
+#define _2G32                   0x80000000U
+/** 2 G (Giga)             (2 147 483 648). (64-bit) */
+#define _2G             0x0000000080000000LL
+/** 4 G (Giga)             (4 294 967 296). */
+#define _4G             0x0000000100000000LL
+/** 1 T (Tera)         (1 099 511 627 776). */
+#define _1T             0x0000010000000000LL
+/** 1 P (Peta)     (1 125 899 906 842 624). */
+#define _1P             0x0004000000000000LL
+/** 1 E (Exa)  (1 152 921 504 606 846 976). */
+#define _1E             0x1000000000000000LL
+/** 2 E (Exa)  (2 305 843 009 213 693 952). */
+#define _2E             0x2000000000000000ULL
+/** @} */
+
+/** @defgroup grp_rt_cdefs_decimal_grouping   Decimal Constant Grouping Macros
+ * @{ */
+#define RT_D1(g1)                                   g1
+#define RT_D2(g1, g2)                               g1#g2
+#define RT_D3(g1, g2, g3)                           g1#g2#g3
+#define RT_D4(g1, g2, g3, g4)                       g1#g2#g3#g4
+#define RT_D5(g1, g2, g3, g4, g5)                   g1#g2#g3#g4#g5
+#define RT_D6(g1, g2, g3, g4, g5, g6)               g1#g2#g3#g4#g5#g6
+#define RT_D7(g1, g2, g3, g4, g5, g6, g7)           g1#g2#g3#g4#g5#g6#g7
+
+#define RT_D1_U(g1)                                 UINT32_C(g1)
+#define RT_D2_U(g1, g2)                             UINT32_C(g1#g2)
+#define RT_D3_U(g1, g2, g3)                         UINT32_C(g1#g2#g3)
+#define RT_D4_U(g1, g2, g3, g4)                     UINT64_C(g1#g2#g3#g4)
+#define RT_D5_U(g1, g2, g3, g4, g5)                 UINT64_C(g1#g2#g3#g4#g5)
+#define RT_D6_U(g1, g2, g3, g4, g5, g6)             UINT64_C(g1#g2#g3#g4#g5#g6)
+#define RT_D7_U(g1, g2, g3, g4, g5, g6, g7)         UINT64_C(g1#g2#g3#g4#g5#g6#g7)
+
+#define RT_D1_S(g1)                                 INT32_C(g1)
+#define RT_D2_S(g1, g2)                             INT32_C(g1#g2)
+#define RT_D3_S(g1, g2, g3)                         INT32_C(g1#g2#g3)
+#define RT_D4_S(g1, g2, g3, g4)                     INT64_C(g1#g2#g3#g4)
+#define RT_D5_S(g1, g2, g3, g4, g5)                 INT64_C(g1#g2#g3#g4#g5)
+#define RT_D6_S(g1, g2, g3, g4, g5, g6)             INT64_C(g1#g2#g3#g4#g5#g6)
+#define RT_D7_S(g1, g2, g3, g4, g5, g6, g7)         INT64_C(g1#g2#g3#g4#g5#g6#g7)
+
+#define RT_D1_U32(g1)                               UINT32_C(g1)
+#define RT_D2_U32(g1, g2)                           UINT32_C(g1#g2)
+#define RT_D3_U32(g1, g2, g3)                       UINT32_C(g1#g2#g3)
+#define RT_D4_U32(g1, g2, g3, g4)                   UINT32_C(g1#g2#g3#g4)
+
+#define RT_D1_S32(g1)                               INT32_C(g1)
+#define RT_D2_S32(g1, g2)                           INT32_C(g1#g2)
+#define RT_D3_S32(g1, g2, g3)                       INT32_C(g1#g2#g3)
+#define RT_D4_S32(g1, g2, g3, g4)                   INT32_C(g1#g2#g3#g4)
+
+#define RT_D1_U64(g1)                               UINT64_C(g1)
+#define RT_D2_U64(g1, g2)                           UINT64_C(g1#g2)
+#define RT_D3_U64(g1, g2, g3)                       UINT64_C(g1#g2#g3)
+#define RT_D4_U64(g1, g2, g3, g4)                   UINT64_C(g1#g2#g3#g4)
+#define RT_D5_U64(g1, g2, g3, g4, g5)               UINT64_C(g1#g2#g3#g4#g5)
+#define RT_D6_U64(g1, g2, g3, g4, g5, g6)           UINT64_C(g1#g2#g3#g4#g5#g6)
+#define RT_D7_U64(g1, g2, g3, g4, g5, g6, g7)       UINT64_C(g1#g2#g3#g4#g5#g6#g7)
+
+#define RT_D1_S64(g1)                               INT64_C(g1)
+#define RT_D2_S64(g1, g2)                           INT64_C(g1#g2)
+#define RT_D3_S64(g1, g2, g3)                       INT64_C(g1#g2#g3)
+#define RT_D4_S64(g1, g2, g3, g4)                   INT64_C(g1#g2#g3#g4)
+#define RT_D5_S64(g1, g2, g3, g4, g5)               INT64_C(g1#g2#g3#g4#g5)
+#define RT_D6_S64(g1, g2, g3, g4, g5, g6)           INT64_C(g1#g2#g3#g4#g5#g6)
+#define RT_D7_S64(g1, g2, g3, g4, g5, g6, g7)       INT64_C(g1#g2#g3#g4#g5#g6#g7)
+/** @}  */
+
+
+/** @defgroup grp_rt_cdefs_time     Time Constants
+ * @{
+ */
+/** 1 hour expressed in nanoseconds (64-bit). */
+#define RT_NS_1HOUR             UINT64_C(3600000000000)
+/** 1 minute expressed in nanoseconds (64-bit). */
+#define RT_NS_1MIN              UINT64_C(60000000000)
+/** 45 second expressed in nanoseconds. */
+#define RT_NS_45SEC             UINT64_C(45000000000)
+/** 30 second expressed in nanoseconds. */
+#define RT_NS_30SEC             UINT64_C(30000000000)
+/** 20 second expressed in nanoseconds. */
+#define RT_NS_20SEC             UINT64_C(20000000000)
+/** 15 second expressed in nanoseconds. */
+#define RT_NS_15SEC             UINT64_C(15000000000)
+/** 10 second expressed in nanoseconds. */
+#define RT_NS_10SEC             UINT64_C(10000000000)
+/** 1 second expressed in nanoseconds. */
+#define RT_NS_1SEC              UINT32_C(1000000000)
+/** 100 millsecond expressed in nanoseconds. */
+#define RT_NS_100MS             UINT32_C(100000000)
+/** 10 millsecond expressed in nanoseconds. */
+#define RT_NS_10MS              UINT32_C(10000000)
+/** 1 millsecond expressed in nanoseconds. */
+#define RT_NS_1MS               UINT32_C(1000000)
+/** 100 microseconds expressed in nanoseconds. */
+#define RT_NS_100US             UINT32_C(100000)
+/** 10 microseconds expressed in nanoseconds. */
+#define RT_NS_10US              UINT32_C(10000)
+/** 1 microsecond expressed in nanoseconds. */
+#define RT_NS_1US               UINT32_C(1000)
+
+/** 1 second expressed in nanoseconds - 64-bit type. */
+#define RT_NS_1SEC_64           UINT64_C(1000000000)
+/** 100 millsecond expressed in nanoseconds - 64-bit type. */
+#define RT_NS_100MS_64          UINT64_C(100000000)
+/** 10 millsecond expressed in nanoseconds - 64-bit type. */
+#define RT_NS_10MS_64           UINT64_C(10000000)
+/** 1 millsecond expressed in nanoseconds - 64-bit type. */
+#define RT_NS_1MS_64            UINT64_C(1000000)
+/** 100 microseconds expressed in nanoseconds - 64-bit type. */
+#define RT_NS_100US_64          UINT64_C(100000)
+/** 10 microseconds expressed in nanoseconds - 64-bit type. */
+#define RT_NS_10US_64           UINT64_C(10000)
+/** 1 microsecond expressed in nanoseconds - 64-bit type. */
+#define RT_NS_1US_64            UINT64_C(1000)
+
+/** 1 hour expressed in microseconds. */
+#define RT_US_1HOUR             UINT32_C(3600000000)
+/** 1 minute expressed in microseconds. */
+#define RT_US_1MIN              UINT32_C(60000000)
+/** 1 second expressed in microseconds. */
+#define RT_US_1SEC              UINT32_C(1000000)
+/** 100 millsecond expressed in microseconds. */
+#define RT_US_100MS             UINT32_C(100000)
+/** 10 millsecond expressed in microseconds. */
+#define RT_US_10MS              UINT32_C(10000)
+/** 1 millsecond expressed in microseconds. */
+#define RT_US_1MS               UINT32_C(1000)
+
+/** 1 hour expressed in microseconds - 64-bit type. */
+#define RT_US_1HOUR_64          UINT64_C(3600000000)
+/** 1 minute expressed in microseconds - 64-bit type. */
+#define RT_US_1MIN_64           UINT64_C(60000000)
+/** 1 second expressed in microseconds - 64-bit type. */
+#define RT_US_1SEC_64           UINT64_C(1000000)
+/** 100 millsecond expressed in microseconds - 64-bit type. */
+#define RT_US_100MS_64          UINT64_C(100000)
+/** 10 millsecond expressed in microseconds - 64-bit type. */
+#define RT_US_10MS_64           UINT64_C(10000)
+/** 1 millsecond expressed in microseconds - 64-bit type. */
+#define RT_US_1MS_64            UINT64_C(1000)
+
+/** 1 hour expressed in milliseconds. */
+#define RT_MS_1HOUR             UINT32_C(3600000)
+/** 1 minute expressed in milliseconds. */
+#define RT_MS_1MIN              UINT32_C(60000)
+/** 1 second expressed in milliseconds. */
+#define RT_MS_1SEC              UINT32_C(1000)
+
+/** 1 hour expressed in milliseconds - 64-bit type. */
+#define RT_MS_1HOUR_64          UINT64_C(3600000)
+/** 1 minute expressed in milliseconds - 64-bit type. */
+#define RT_MS_1MIN_64           UINT64_C(60000)
+/** 1 second expressed in milliseconds - 64-bit type. */
+#define RT_MS_1SEC_64           UINT64_C(1000)
+
+/** The number of seconds per week. */
+#define RT_SEC_1WEEK            UINT32_C(604800)
+/** The number of seconds per day. */
+#define RT_SEC_1DAY             UINT32_C(86400)
+/** The number of seconds per hour. */
+#define RT_SEC_1HOUR            UINT32_C(3600)
+
+/** The number of seconds per week - 64-bit type. */
+#define RT_SEC_1WEEK_64         UINT64_C(604800)
+/** The number of seconds per day - 64-bit type. */
+#define RT_SEC_1DAY_64          UINT64_C(86400)
+/** The number of seconds per hour - 64-bit type. */
+#define RT_SEC_1HOUR_64         UINT64_C(3600)
+/** @}  */
+
+
+/** @defgroup grp_rt_cdefs_dbgtype  Debug Info Types
+ * @{ */
+/** Other format. */
+#define RT_DBGTYPE_OTHER        RT_BIT_32(0)
+/** Stabs. */
+#define RT_DBGTYPE_STABS        RT_BIT_32(1)
+/** Debug With Arbitrary Record Format (DWARF). */
+#define RT_DBGTYPE_DWARF        RT_BIT_32(2)
+/** Microsoft Codeview debug info. */
+#define RT_DBGTYPE_CODEVIEW     RT_BIT_32(3)
+/** Watcom debug info. */
+#define RT_DBGTYPE_WATCOM       RT_BIT_32(4)
+/** IBM High Level Language debug info. */
+#define RT_DBGTYPE_HLL          RT_BIT_32(5)
+/** Old OS/2 and Windows symbol file. */
+#define RT_DBGTYPE_SYM          RT_BIT_32(6)
+/** Map file. */
+#define RT_DBGTYPE_MAP          RT_BIT_32(7)
+/** @} */
+
+
+/** @defgroup grp_rt_cdefs_exetype  Executable Image Types
+ * @{ */
+/** Some other format. */
+#define RT_EXETYPE_OTHER        RT_BIT_32(0)
+/** Portable Executable. */
+#define RT_EXETYPE_PE           RT_BIT_32(1)
+/** Linear eXecutable. */
+#define RT_EXETYPE_LX           RT_BIT_32(2)
+/** Linear Executable. */
+#define RT_EXETYPE_LE           RT_BIT_32(3)
+/** New Executable. */
+#define RT_EXETYPE_NE           RT_BIT_32(4)
+/** DOS Executable (Mark Zbikowski). */
+#define RT_EXETYPE_MZ           RT_BIT_32(5)
+/** COM Executable. */
+#define RT_EXETYPE_COM          RT_BIT_32(6)
+/** a.out Executable. */
+#define RT_EXETYPE_AOUT         RT_BIT_32(7)
+/** Executable and Linkable Format. */
+#define RT_EXETYPE_ELF          RT_BIT_32(8)
+/** Mach-O Executable (including FAT ones). */
+#define RT_EXETYPE_MACHO        RT_BIT_32(9)
+/** TE from UEFI. */
+#define RT_EXETYPE_TE           RT_BIT_32(9)
+/** @} */
+
+
+/** @def VALID_PTR
+ * Pointer validation macro.
+ * @param   ptr         The pointer.
+ */
+#if defined(RT_ARCH_AMD64)
+# ifdef IN_RING3
+#  if defined(RT_OS_DARWIN) /* first 4GB is reserved for legacy kernel. */
+#   define RT_VALID_PTR(ptr)    (   (uintptr_t)(ptr) >= _4G \
+                                 && !((uintptr_t)(ptr) & 0xffff800000000000ULL) )
+#  elif defined(RT_OS_SOLARIS) /* The kernel only used the top 2TB, but keep it simple. */
+#   define RT_VALID_PTR(ptr)    (   (uintptr_t)(ptr) + 0x1000U >= 0x2000U \
+                                 && (   ((uintptr_t)(ptr) & 0xffff800000000000ULL) == 0xffff800000000000ULL \
+                                     || ((uintptr_t)(ptr) & 0xffff800000000000ULL) == 0) )
+#  else
+#   define RT_VALID_PTR(ptr)    (   (uintptr_t)(ptr) + 0x1000U >= 0x2000U \
+                                 && !((uintptr_t)(ptr) & 0xffff800000000000ULL) )
+#  endif
+# else /* !IN_RING3 */
+#  define RT_VALID_PTR(ptr)     (   (uintptr_t)(ptr) + 0x1000U >= 0x2000U \
+                                 && (   ((uintptr_t)(ptr) & 0xffff800000000000ULL) == 0xffff800000000000ULL \
+                                     || ((uintptr_t)(ptr) & 0xffff800000000000ULL) == 0) )
+# endif /* !IN_RING3 */
+
+#elif defined(RT_ARCH_X86)
+# define RT_VALID_PTR(ptr)      ( (uintptr_t)(ptr) + 0x1000U >= 0x2000U )
+
+#elif defined(RT_ARCH_SPARC64)
+# ifdef IN_RING3
+#  if defined(RT_OS_SOLARIS)
+/** Sparc64 user mode: According to Figure 9.4 in solaris internals */
+/** @todo #   define RT_VALID_PTR(ptr)    ( (uintptr_t)(ptr) + 0x80004000U >= 0x80004000U + 0x100000000ULL ) - figure this. */
+#   define RT_VALID_PTR(ptr)    ( (uintptr_t)(ptr) + 0x80000000U >= 0x80000000U + 0x100000000ULL )
+#  else
+#   error "Port me"
+#  endif
+# else  /* !IN_RING3 */
+#  if defined(RT_OS_SOLARIS)
+/** @todo Sparc64 kernel mode: This is according to Figure 11.1 in solaris
+ *        internals. Verify in sources. */
+#   define RT_VALID_PTR(ptr)    ( (uintptr_t)(ptr) >= 0x01000000U )
+#  else
+#   error "Port me"
+#  endif
+# endif /* !IN_RING3 */
+
+#elif defined(RT_ARCH_SPARC)
+# ifdef IN_RING3
+#  ifdef RT_OS_SOLARIS
+/** Sparc user mode: According to
+ * http://cvs.opensolaris.org/source/xref/onnv/onnv-gate/usr/src/uts/sun4/os/startup.c#510 */
+#   define RT_VALID_PTR(ptr)    ( (uintptr_t)(ptr) + 0x400000U >= 0x400000U + 0x2000U )
+
+#  else
+#   error "Port me"
+#  endif
+# else  /* !IN_RING3 */
+#  ifdef RT_OS_SOLARIS
+/** @todo Sparc kernel mode: Check the sources! */
+#   define RT_VALID_PTR(ptr)    ( (uintptr_t)(ptr) + 0x1000U >= 0x2000U )
+#  else
+#   error "Port me"
+#  endif
+# endif /* !IN_RING3 */
+
+#elif defined(RT_ARCH_ARM)
+/* ASSUMES that at least the last and first 4K are out of bounds. */
+# define RT_VALID_PTR(ptr)      ( (uintptr_t)(ptr) + 0x1000U >= 0x2000U )
+
+#else
+# error "Architecture identifier missing / not implemented."
+#endif
+
+/** Old name for RT_VALID_PTR.  */
+#define VALID_PTR(ptr)          RT_VALID_PTR(ptr)
+
+/** @def RT_VALID_ALIGNED_PTR
+ * Pointer validation macro that also checks the alignment.
+ * @param   ptr         The pointer.
+ * @param   align       The alignment, must be a power of two.
+ */
+#define RT_VALID_ALIGNED_PTR(ptr, align)   \
+    (   !((uintptr_t)(ptr) & (uintptr_t)((align) - 1)) \
+     && VALID_PTR(ptr) )
+
+
+/** @def VALID_PHYS32
+ * 32 bits physical address validation macro.
+ * @param   Phys          The RTGCPHYS address.
+ */
+#define VALID_PHYS32(Phys)  ( (uint64_t)(Phys) < (uint64_t)_4G )
+
+/** @def N_
+ * The \#define N_ is used to mark a string for translation. This is usable in
+ * any part of the code, as it is only used by the tools that create message
+ * catalogs. This macro is a no-op as far as the compiler and code generation
+ * is concerned.
+ *
+ * If you want to both mark a string for translation and translate it, use _().
+ */
+#define N_(s) (s)
+
+/** @def _
+ * The \#define _ is used to mark a string for translation and to translate it
+ * in one step.
+ *
+ * If you want to only mark a string for translation, use N_().
+ */
+#define _(s) gettext(s)
+
+
+/** @def __PRETTY_FUNCTION__
+ *  With GNU C we'd like to use the builtin __PRETTY_FUNCTION__, so define that
+ *  for the other compilers.
+ */
+#if !defined(__GNUC__) && !defined(__PRETTY_FUNCTION__)
+# ifdef _MSC_VER
+#  define __PRETTY_FUNCTION__    __FUNCSIG__
+# else
+#  define __PRETTY_FUNCTION__    __FUNCTION__
+# endif
+#endif
+
+
+/** @def RT_STRICT
+ * The \#define RT_STRICT controls whether or not assertions and other runtime
+ * checks should be compiled in or not.  This is defined when DEBUG is defined.
+ * If RT_NO_STRICT is defined, it will unconditionally be undefined.
+ *
+ * If you want assertions which are not subject to compile time options use
+ * the AssertRelease*() flavors.
+ */
+#if !defined(RT_STRICT) && defined(DEBUG)
+# define RT_STRICT
+#endif
+#ifdef RT_NO_STRICT
+# undef RT_STRICT
+#endif
+
+/** @todo remove this: */
+#if !defined(RT_LOCK_STRICT) && !defined(DEBUG_bird)
+# define RT_LOCK_NO_STRICT
+#endif
+#if !defined(RT_LOCK_STRICT_ORDER) && !defined(DEBUG_bird)
+# define RT_LOCK_NO_STRICT_ORDER
+#endif
+
+/** @def RT_LOCK_STRICT
+ * The \#define RT_LOCK_STRICT controls whether deadlock detection and related
+ * checks are done in the lock and semaphore code.  It is by default enabled in
+ * RT_STRICT builds, but this behavior can be overridden by defining
+ * RT_LOCK_NO_STRICT. */
+#if !defined(RT_LOCK_STRICT) && !defined(RT_LOCK_NO_STRICT) && defined(RT_STRICT)
+# define RT_LOCK_STRICT
+#endif
+/** @def RT_LOCK_NO_STRICT
+ * The \#define RT_LOCK_NO_STRICT disables RT_LOCK_STRICT.  */
+#if defined(RT_LOCK_NO_STRICT) && defined(RT_LOCK_STRICT)
+# undef RT_LOCK_STRICT
+#endif
+
+/** @def RT_LOCK_STRICT_ORDER
+ * The \#define RT_LOCK_STRICT_ORDER controls whether locking order is checked
+ * by the lock and semaphore code.  It is by default enabled in RT_STRICT
+ * builds, but this behavior can be overridden by defining
+ * RT_LOCK_NO_STRICT_ORDER. */
+#if !defined(RT_LOCK_STRICT_ORDER) && !defined(RT_LOCK_NO_STRICT_ORDER) && defined(RT_STRICT)
+# define RT_LOCK_STRICT_ORDER
+#endif
+/** @def RT_LOCK_NO_STRICT_ORDER
+ * The \#define RT_LOCK_NO_STRICT_ORDER disables RT_LOCK_STRICT_ORDER.  */
+#if defined(RT_LOCK_NO_STRICT_ORDER) && defined(RT_LOCK_STRICT_ORDER)
+# undef RT_LOCK_STRICT_ORDER
+#endif
+
+
+/** Source position. */
+#define RT_SRC_POS         __FILE__, __LINE__, RT_GCC_EXTENSION __PRETTY_FUNCTION__
+
+/** Source position declaration. */
+#define RT_SRC_POS_DECL    const char *pszFile, unsigned iLine, const char *pszFunction
+
+/** Source position arguments. */
+#define RT_SRC_POS_ARGS    pszFile, iLine, pszFunction
+
+/** Applies NOREF() to the source position arguments. */
+#define RT_SRC_POS_NOREF() do { NOREF(pszFile); NOREF(iLine); NOREF(pszFunction); } while (0)
+
+
+/** @def RT_INLINE_ASM_EXTERNAL
+ * Defined as 1 if the compiler does not support inline assembly.
+ * The ASM* functions will then be implemented in external .asm files.
+ */
+#if (defined(_MSC_VER) && defined(RT_ARCH_AMD64)) \
+ || (!defined(RT_ARCH_AMD64) && !defined(RT_ARCH_X86))
+# define RT_INLINE_ASM_EXTERNAL 1
+#else
+# define RT_INLINE_ASM_EXTERNAL 0
+#endif
+
+/** @def RT_INLINE_ASM_GNU_STYLE
+ * Defined as 1 if the compiler understands GNU style inline assembly.
+ */
+#if defined(_MSC_VER)
+# define RT_INLINE_ASM_GNU_STYLE 0
+#else
+# define RT_INLINE_ASM_GNU_STYLE 1
+#endif
+
+/** @def RT_INLINE_ASM_USES_INTRIN
+ * Defined as the major MSC version if the compiler have and uses intrin.h.
+ * Otherwise it is 0. */
+#ifdef _MSC_VER
+# if   _MSC_VER >= 1700 /* Visual C++ v11.0 / 2012 */
+#  define RT_INLINE_ASM_USES_INTRIN 17
+# elif _MSC_VER >= 1600 /* Visual C++ v10.0 / 2010 */
+#  define RT_INLINE_ASM_USES_INTRIN 16
+# elif _MSC_VER >= 1500 /* Visual C++ v9.0 / 2008 */
+#  define RT_INLINE_ASM_USES_INTRIN 15
+# elif _MSC_VER >= 1400 /* Visual C++ v8.0 / 2005 */
+#  define RT_INLINE_ASM_USES_INTRIN 14
+# endif
+#endif
+#ifndef RT_INLINE_ASM_USES_INTRIN
+# define RT_INLINE_ASM_USES_INTRIN 0
+#endif
+
+/** @def RT_COMPILER_SUPPORTS_LAMBDA
+ * If the defined, the compiler supports lambda expressions.   These expressions
+ * are useful for embedding assertions and type checks into macros. */
+#if defined(_MSC_VER) && defined(__cplusplus)
+# if _MSC_VER >= 1600 /* Visual C++ v10.0 / 2010 */
+#  define RT_COMPILER_SUPPORTS_LAMBDA
+# endif
+#elif defined(__GNUC__) && defined(__cplusplus)
+/* 4.5 or later, I think, if in ++11 mode... */
+#endif
+
+/** @} */
+
+
+/** @defgroup grp_rt_cdefs_cpp  Special Macros for C++
+ * @ingroup grp_rt_cdefs
+ * @{
+ */
+
+#ifdef __cplusplus
+
+/** @def DECLEXPORT_CLASS
+ * How to declare an exported class. Place this macro after the 'class'
+ * keyword in the declaration of every class you want to export.
+ *
+ * @note It is necessary to use this macro even for inner classes declared
+ * inside the already exported classes. This is a GCC specific requirement,
+ * but it seems not to harm other compilers.
+ */
+#if defined(_MSC_VER) || defined(RT_OS_OS2)
+# define DECLEXPORT_CLASS       __declspec(dllexport)
+#elif defined(RT_USE_VISIBILITY_DEFAULT)
+# define DECLEXPORT_CLASS       __attribute__((visibility("default")))
+#else
+# define DECLEXPORT_CLASS
+#endif
+
+/** @def DECLIMPORT_CLASS
+ * How to declare an imported class Place this macro after the 'class'
+ * keyword in the declaration of every class you want to export.
+ *
+ * @note It is necessary to use this macro even for inner classes declared
+ * inside the already exported classes. This is a GCC specific requirement,
+ * but it seems not to harm other compilers.
+ */
+#if defined(_MSC_VER) || (defined(RT_OS_OS2) && !defined(__IBMC__) && !defined(__IBMCPP__))
+# define DECLIMPORT_CLASS       __declspec(dllimport)
+#elif defined(RT_USE_VISIBILITY_DEFAULT)
+# define DECLIMPORT_CLASS       __attribute__((visibility("default")))
+#else
+# define DECLIMPORT_CLASS
+#endif
+
+/** @def WORKAROUND_MSVC7_ERROR_C2593_FOR_BOOL_OP
+ * Macro to work around error C2593 of the not-so-smart MSVC 7.x ambiguity
+ * resolver. The following snippet clearly demonstrates the code causing this
+ * error:
+ * @code
+ *      class A
+ *      {
+ *      public:
+ *          operator bool() const { return false; }
+ *          operator int*() const { return NULL; }
+ *      };
+ *      int main()
+ *      {
+ *          A a;
+ *          if (!a);
+ *          if (a && 0);
+ *          return 0;
+ *      }
+ * @endcode
+ * The code itself seems pretty valid to me and GCC thinks the same.
+ *
+ * This macro fixes the compiler error by explicitly overloading implicit
+ * global operators !, && and || that take the given class instance as one of
+ * their arguments.
+ *
+ * The best is to use this macro right after the class declaration.
+ *
+ * @note The macro expands to nothing for compilers other than MSVC.
+ *
+ * @param Cls Class to apply the workaround to
+ */
+#if defined(_MSC_VER)
+# define WORKAROUND_MSVC7_ERROR_C2593_FOR_BOOL_OP(Cls) \
+    inline bool operator! (const Cls &that) { return !bool (that); } \
+    inline bool operator&& (const Cls &that, bool b) { return bool (that) && b; } \
+    inline bool operator|| (const Cls &that, bool b) { return bool (that) || b; } \
+    inline bool operator&& (bool b, const Cls &that) { return b && bool (that); } \
+    inline bool operator|| (bool b, const Cls &that) { return b || bool (that); }
+#else
+# define WORKAROUND_MSVC7_ERROR_C2593_FOR_BOOL_OP(Cls)
+#endif
+
+/** @def WORKAROUND_MSVC7_ERROR_C2593_FOR_BOOL_OP_TPL
+ * Version of WORKAROUND_MSVC7_ERROR_C2593_FOR_BOOL_OP for template classes.
+ *
+ * @param Tpl       Name of the template class to apply the workaround to
+ * @param ArgsDecl  arguments of the template, as declared in |<>| after the
+ *                  |template| keyword, including |<>|
+ * @param Args      arguments of the template, as specified in |<>| after the
+ *                  template class name when using the, including |<>|
+ *
+ * Example:
+ * @code
+ *      // template class declaration
+ *      template <class C>
+ *      class Foo { ... };
+ *      // applied workaround
+ *      WORKAROUND_MSVC7_ERROR_C2593_FOR_BOOL_OP_TPL (Foo, <class C>, <C>)
+ * @endcode
+ */
+#if defined(_MSC_VER)
+# define WORKAROUND_MSVC7_ERROR_C2593_FOR_BOOL_OP_TPL(Tpl, ArgsDecl, Args) \
+    template ArgsDecl \
+    inline bool operator! (const Tpl Args &that) { return !bool (that); } \
+    template ArgsDecl \
+    inline bool operator&& (const Tpl Args  &that, bool b) { return bool (that) && b; } \
+    template ArgsDecl \
+    inline bool operator|| (const Tpl Args  &that, bool b) { return bool (that) || b; } \
+    template ArgsDecl \
+    inline bool operator&& (bool b, const Tpl Args  &that) { return b && bool (that); } \
+    template ArgsDecl \
+    inline bool operator|| (bool b, const Tpl Args  &that) { return b || bool (that); }
+#else
+# define WORKAROUND_MSVC7_ERROR_C2593_FOR_BOOL_OP_TPL(Tpl, ArgsDecl, Args)
+#endif
+
+
+/** @def DECLARE_CLS_COPY_CTOR_ASSIGN_NOOP
+ * Declares the copy constructor and the assignment operation as inlined no-ops
+ * (non-existent functions) for the given class. Use this macro inside the
+ * private section if you want to effectively disable these operations for your
+ * class.
+ *
+ * @param      Cls     class name to declare for
+ */
+
+#define DECLARE_CLS_COPY_CTOR_ASSIGN_NOOP(Cls) \
+    inline Cls (const Cls &); \
+    inline Cls &operator= (const Cls &);
+
+
+/** @def DECLARE_CLS_NEW_DELETE_NOOP
+ * Declares the new and delete operations as no-ops (non-existent functions)
+ * for the given class. Use this macro inside the private section if you want
+ * to effectively limit creating class instances on the stack only.
+ *
+ * @note The destructor of the given class must not be virtual, otherwise a
+ * compile time error will occur. Note that this is not a drawback: having
+ * the virtual destructor for a stack-based class is absolutely useless
+ * (the real class of the stack-based instance is always known to the compiler
+ * at compile time, so it will always call the correct destructor).
+ *
+ * @param      Cls     class name to declare for
+ */
+#define DECLARE_CLS_NEW_DELETE_NOOP(Cls) \
+    inline static void *operator new (size_t); \
+    inline static void operator delete (void *);
+
+#endif /* __cplusplus */
+
+/** @} */
+
+#endif
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/include/iprt/cpuset.h
@@ -0,0 +1,340 @@
+/** @file
+ * IPRT - CPU Set.
+ */
+
+/*
+ * Copyright (C) 2008-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+#ifndef ___iprt_cpuset_h
+#define ___iprt_cpuset_h
+
+#include <iprt/types.h>
+#include <iprt/mp.h> /* RTMpCpuIdToSetIndex */
+#include <iprt/asm.h>
+
+
+RT_C_DECLS_BEGIN
+
+/** @defgroup grp_rt_cpuset RTCpuSet - CPU Set
+ * @ingroup grp_rt
+ * @{
+ */
+
+
+/**
+ * Clear all CPUs.
+ *
+ * @returns pSet.
+ * @param   pSet    Pointer to the set.
+ */
+DECLINLINE(PRTCPUSET) RTCpuSetEmpty(PRTCPUSET pSet)
+{
+    unsigned i;
+    for (i = 0; i < RT_ELEMENTS(pSet->bmSet); i++)
+        pSet->bmSet[i] = 0;
+    return pSet;
+}
+
+
+/**
+ * Set all CPUs.
+ *
+ * @returns pSet.
+ * @param   pSet    Pointer to the set.
+ */
+DECLINLINE(PRTCPUSET) RTCpuSetFill(PRTCPUSET pSet)
+{
+    unsigned i;
+    for (i = 0; i < RT_ELEMENTS(pSet->bmSet); i++)
+        pSet->bmSet[i] = UINT64_MAX;
+    return pSet;
+}
+
+
+/**
+ * Copies one set to another.
+ *
+ * @param   pDst    Pointer to the destination set.
+ * @param   pSrc    Pointer to the source set.
+ */
+DECLINLINE(void) RTCpuSetCopy(PRTCPUSET pDst, PRTCPUSET pSrc)
+{
+    unsigned i;
+    for (i = 0; i < RT_ELEMENTS(pDst->bmSet); i++)
+        pDst->bmSet[i] = pSrc->bmSet[i];
+}
+
+
+/**
+ * ANDs the given CPU set with another.
+ *
+ * @returns pSet.
+ * @param   pSet          Pointer to the set.
+ * @param   pAndMaskSet   Pointer to the AND-mask set.
+ */
+DECLINLINE(PRTCPUSET) RTCpuSetAnd(PRTCPUSET pSet, PRTCPUSET pAndMaskSet)
+{
+    unsigned i;
+    for (i = 0; i < RT_ELEMENTS(pSet->bmSet); i++)
+        ASMAtomicAndU64((volatile uint64_t *)&pSet->bmSet[i], pAndMaskSet->bmSet[i]);
+    return pSet;
+}
+
+
+/**
+ * Adds a CPU given by its identifier to the set.
+ *
+ * @returns 0 on success, -1 if idCpu isn't valid.
+ * @param   pSet    Pointer to the set.
+ * @param   idCpu   The identifier of the CPU to add.
+ * @remarks The modification is atomic.
+ */
+DECLINLINE(int) RTCpuSetAdd(PRTCPUSET pSet, RTCPUID idCpu)
+{
+    int iCpu = RTMpCpuIdToSetIndex(idCpu);
+    if (RT_LIKELY(iCpu >= 0))
+    {
+        ASMAtomicBitSet(pSet, iCpu);
+        return 0;
+    }
+    return -1;
+}
+
+
+/**
+ * Adds a CPU given by its identifier to the set.
+ *
+ * @returns 0 on success, -1 if iCpu isn't valid.
+ * @param   pSet    Pointer to the set.
+ * @param   iCpu    The index of the CPU to add.
+ * @remarks The modification is atomic.
+ */
+DECLINLINE(int) RTCpuSetAddByIndex(PRTCPUSET pSet, int iCpu)
+{
+    if (RT_LIKELY((unsigned)iCpu < RTCPUSET_MAX_CPUS))
+    {
+        ASMAtomicBitSet(pSet, iCpu);
+        return 0;
+    }
+    return -1;
+}
+
+
+/**
+ * Removes a CPU given by its identifier from the set.
+ *
+ * @returns 0 on success, -1 if idCpu isn't valid.
+ * @param   pSet    Pointer to the set.
+ * @param   idCpu   The identifier of the CPU to delete.
+ * @remarks The modification is atomic.
+ */
+DECLINLINE(int) RTCpuSetDel(PRTCPUSET pSet, RTCPUID idCpu)
+{
+    int iCpu = RTMpCpuIdToSetIndex(idCpu);
+    if (RT_LIKELY(iCpu >= 0))
+    {
+        ASMAtomicBitClear(pSet, iCpu);
+        return 0;
+    }
+    return -1;
+}
+
+
+/**
+ * Removes a CPU given by its index from the set.
+ *
+ * @returns 0 on success, -1 if iCpu isn't valid.
+ * @param   pSet    Pointer to the set.
+ * @param   iCpu    The index of the CPU to delete.
+ * @remarks The modification is atomic.
+ */
+DECLINLINE(int) RTCpuSetDelByIndex(PRTCPUSET pSet, int iCpu)
+{
+    if (RT_LIKELY((unsigned)iCpu < RTCPUSET_MAX_CPUS))
+    {
+        ASMAtomicBitClear(pSet, iCpu);
+        return 0;
+    }
+    return -1;
+}
+
+
+/**
+ * Checks if a CPU given by its identifier is a member of the set.
+ *
+ * @returns true / false accordingly.
+ * @param   pSet    Pointer to the set.
+ * @param   idCpu   The identifier of the CPU to look for.
+ * @remarks The test is atomic.
+ */
+DECLINLINE(bool) RTCpuSetIsMember(PCRTCPUSET pSet, RTCPUID idCpu)
+{
+    int iCpu = RTMpCpuIdToSetIndex(idCpu);
+    if (RT_LIKELY(iCpu >= 0))
+        return ASMBitTest((volatile void *)pSet, iCpu);
+    return false;
+}
+
+
+/**
+ * Checks if a CPU given by its index is a member of the set.
+ *
+ * @returns true / false accordingly.
+ * @param   pSet    Pointer to the set.
+ * @param   iCpu    The index of the CPU in the set.
+ * @remarks The test is atomic.
+ */
+DECLINLINE(bool) RTCpuSetIsMemberByIndex(PCRTCPUSET pSet, int iCpu)
+{
+    if (RT_LIKELY((unsigned)iCpu < RTCPUSET_MAX_CPUS))
+        return ASMBitTest((volatile void *)pSet, iCpu);
+    return false;
+}
+
+
+/**
+ * Checks if the two sets match or not.
+ *
+ * @returns true / false accordingly.
+ * @param   pSet1       The first set.
+ * @param   pSet2       The second set.
+ */
+DECLINLINE(bool) RTCpuSetIsEqual(PCRTCPUSET pSet1, PCRTCPUSET pSet2)
+{
+    unsigned i;
+    for (i = 0; i < RT_ELEMENTS(pSet1->bmSet); i++)
+        if (pSet1->bmSet[i] != pSet2->bmSet[i])
+            return false;
+    return true;
+}
+
+
+/**
+ * Checks if the CPU set is empty or not.
+ *
+ * @returns true / false accordingly.
+ * @param   pSet    Pointer to the set.
+ */
+DECLINLINE(bool) RTCpuSetIsEmpty(PRTCPUSET pSet)
+{
+    unsigned i;
+    for (i = 0; i < RT_ELEMENTS(pSet->bmSet); i++)
+        if (pSet->bmSet[i])
+            return false;
+    return true;
+}
+
+
+/**
+ * Converts the CPU set to a 64-bit mask.
+ *
+ * @returns The mask.
+ * @param   pSet    Pointer to the set.
+ * @remarks Use with extreme care as it may lose information!
+ */
+DECLINLINE(uint64_t) RTCpuSetToU64(PCRTCPUSET pSet)
+{
+    return pSet->bmSet[0];
+}
+
+
+/**
+ * Initializes the CPU set from a 64-bit mask.
+ *
+ * @param   pSet    Pointer to the set.
+ * @param   fMask   The mask.
+ */
+DECLINLINE(PRTCPUSET) RTCpuSetFromU64(PRTCPUSET pSet, uint64_t fMask)
+{
+    unsigned i;
+
+    pSet->bmSet[0] = fMask;
+    for (i = 1; i < RT_ELEMENTS(pSet->bmSet); i++)
+        pSet->bmSet[i] = 0;
+
+    return pSet;
+}
+
+
+/**
+ * Count the CPUs in the set.
+ *
+ * @returns CPU count.
+ * @param   pSet    Pointer to the set.
+ */
+DECLINLINE(int) RTCpuSetCount(PCRTCPUSET pSet)
+{
+    int         cCpus = 0;
+    unsigned    i;
+
+    for (i = 0; i < RT_ELEMENTS(pSet->bmSet); i++)
+    {
+        uint64_t u64 = pSet->bmSet[i];
+        if (u64 != 0)
+        {
+            unsigned iCpu = 64;
+            while (iCpu-- > 0)
+            {
+                if (u64 & 1)
+                    cCpus++;
+                u64 >>= 1;
+            }
+        }
+    }
+    return cCpus;
+}
+
+
+/**
+ * Get the highest set index.
+ *
+ * @returns The higest set index, -1 if all bits are clear.
+ * @param   pSet    Pointer to the set.
+ */
+DECLINLINE(int) RTCpuLastIndex(PCRTCPUSET pSet)
+{
+    unsigned i = RT_ELEMENTS(pSet->bmSet);
+    while (i-- > 0)
+    {
+        uint64_t u64 = pSet->bmSet[i];
+        if (u64)
+        {
+            /* There are more efficient ways to do this in asm.h... */
+            unsigned iBit;
+            for (iBit = 63; iBit > 0; iBit--)
+            {
+                if (u64 & RT_BIT_64(63))
+                    break;
+                u64 <<= 1;
+            }
+            return i * 64 + iBit;
+        }
+    }
+    return 0;
+}
+
+
+/** @} */
+
+RT_C_DECLS_END
+
+#endif
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/include/iprt/ctype.h
@@ -0,0 +1,240 @@
+/** @file
+ * IPRT - Simple character type classiciation and conversion.
+ */
+
+/*
+ * Copyright (C) 2006-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+#ifndef ___iprt_ctype_h
+#define ___iprt_ctype_h
+
+#include <iprt/types.h>
+
+/** @name C locale predicates and conversions.
+ *
+ * For most practical purposes, this can safely be used when parsing UTF-8
+ * strings.  Just keep in mind that we only deal with the first 127 chars and
+ * that full correctness is only archived using the non-existing RTLocIs* API.
+ *
+ * @remarks Use the marcros, not the inlined functions.
+ *
+ * @remarks ASSUMES the source code includes the basic ASCII chars. This is a
+ *          general IPRT assumption.
+ * @{ */
+#define RT_C_IS_BLANK(ch)   RTLocCIsBlank((ch))
+#define RT_C_IS_ALNUM(ch)   RTLocCIsAlNum((ch))
+#define RT_C_IS_ALPHA(ch)   RTLocCIsAlpha((ch))
+#define RT_C_IS_CNTRL(ch)   RTLocCIsCntrl((ch))
+#define RT_C_IS_DIGIT(ch)   RTLocCIsDigit((ch))
+#define RT_C_IS_LOWER(ch)   RTLocCIsLower((ch))
+#define RT_C_IS_GRAPH(ch)   RTLocCIsGraph((ch))
+#define RT_C_IS_ODIGIT(ch)  RTLocCIsODigit((ch))
+#define RT_C_IS_PRINT(ch)   RTLocCIsPrint((ch))
+#define RT_C_IS_PUNCT(ch)   RTLocCIsPunct((ch))
+#define RT_C_IS_SPACE(ch)   RTLocCIsSpace((ch))
+#define RT_C_IS_UPPER(ch)   RTLocCIsUpper((ch))
+#define RT_C_IS_XDIGIT(ch)  RTLocCIsXDigit((ch))
+
+#define RT_C_TO_LOWER(ch)   RTLocCToLower((ch))
+#define RT_C_TO_UPPER(ch)   RTLocCToUpper((ch))
+
+/**
+ * Checks for a blank character.
+ *
+ * @returns true / false.
+ * @param   ch      The character to test.
+ */
+DECL_FORCE_INLINE(bool) RTLocCIsBlank(int ch)
+{
+    return ch == 0x20  /* space */
+        || ch == 0x09; /* horizontal tab */
+}
+
+/**
+ * Checks for a control character.
+ *
+ * @returns true / false.
+ * @param   ch      The character to test.
+ *
+ * @note    Will return true of ch is '\0'!
+ */
+DECL_FORCE_INLINE(bool) RTLocCIsCntrl(int ch)
+{
+    return (unsigned)ch < 32U /* 0..2f */
+        || ch == 0x7f;
+}
+
+/**
+ * Checks for a decimal digit.
+ *
+ * @returns true / false.
+ * @param   ch      The character to test.
+ */
+DECL_FORCE_INLINE(bool) RTLocCIsDigit(int ch)
+{
+    return (unsigned)ch - 0x30 < 10U; /* 30..39 */
+}
+
+/**
+ * Checks for a lower case character.
+ *
+ * @returns true / false.
+ * @param   ch      The character to test.
+ */
+DECL_FORCE_INLINE(bool) RTLocCIsLower(int ch)
+{
+    return (unsigned)ch - 0x61U < 26U; /* 61..7a */
+}
+
+/**
+ * Checks for an octal digit.
+ *
+ * @returns true / false.
+ * @param   ch      The character to test.
+ */
+DECL_FORCE_INLINE(bool) RTLocCIsODigit(int ch)
+{
+    return (unsigned)ch - 0x30 < 8U; /* 30..37 */
+}
+
+/**
+ * Checks for a printable character (whitespace included).
+ *
+ * @returns true / false.
+ * @param   ch      The character to test.
+ */
+DECL_FORCE_INLINE(bool) RTLocCIsPrint(int ch)
+{
+    return (unsigned)ch - 0x20U < 95U; /* 20..7e */
+}
+
+/**
+ * Checks for punctuation (?).
+ *
+ * @returns true / false.
+ * @param   ch      The character to test.
+ */
+DECL_FORCE_INLINE(bool) RTLocCIsPunct(int ch)
+{
+    return (unsigned)ch - 0x21U < 15U /* 21..2f */
+        || (unsigned)ch - 0x2aU <  6U /* 2a..2f */
+        || (unsigned)ch - 0x3aU <  7U /* 3a..40 */
+        || (unsigned)ch - 0x5bU <  6U /* 5a..60 */
+        || (unsigned)ch - 0x7bU <  4U /* 7b..7e */;
+}
+
+/**
+ * Checks for a white-space character.
+ *
+ * @returns true / false.
+ * @param   ch      The character to test.
+ */
+DECL_FORCE_INLINE(bool) RTLocCIsSpace(int ch)
+{
+    return ch == 0x20                 /* 20 (space) */
+        || (unsigned)ch - 0x09U < 5U; /* 09..0d */
+}
+
+/**
+ * Checks for an upper case character.
+ *
+ * @returns true / false.
+ * @param   ch      The character to test.
+ */
+DECL_FORCE_INLINE(bool) RTLocCIsUpper(int ch)
+{
+    return (unsigned)ch - 0x41 < 26U; /* 41..5a */
+}
+
+/**
+ * Checks for a hexadecimal digit.
+ *
+ * @returns true / false.
+ * @param   ch      The character to test.
+ */
+DECL_FORCE_INLINE(bool) RTLocCIsXDigit(int ch)
+{
+    return (unsigned)ch - 0x30 < 10U /* 30..39 (0-9) */
+        || (unsigned)ch - 0x41 < 6   /* 41..46 (A-F) */
+        || (unsigned)ch - 0x61 < 6;  /* 61..66 (a-f) */
+}
+
+/**
+ * Checks for an alphabetic character.
+ *
+ * @returns true / false.
+ * @param   ch      The character to test.
+ */
+DECL_FORCE_INLINE(bool) RTLocCIsAlpha(int ch)
+{
+    return RTLocCIsLower(ch) || RTLocCIsUpper(ch);
+}
+
+/**
+ * Checks for an alphanumerical character.
+ *
+ * @returns true / false.
+ * @param   ch      The character to test.
+ */
+DECL_FORCE_INLINE(bool) RTLocCIsAlNum(int ch)
+{
+    return RTLocCIsDigit(ch) || RTLocCIsAlpha(ch);
+}
+
+/**
+ * Checks for a printable character whitespace excluded.
+ *
+ * @returns true / false.
+ * @param   ch      The character to test.
+ */
+DECL_FORCE_INLINE(bool) RTLocCIsGraph(int ch)
+{
+    return RTLocCIsPrint(ch) && !RTLocCIsBlank(ch);
+}
+
+
+/**
+ * Converts the character to lower case if applictable.
+ *
+ * @returns lower cased character or ch.
+ * @param   ch      The character to test.
+ */
+DECL_FORCE_INLINE(int) RTLocCToLower(int ch)
+{
+    return RTLocCIsUpper(ch) ? (ch) + 0x20 : (ch);
+}
+
+/**
+ * Converts the character to upper case if applictable.
+ *
+ * @returns upper cased character or ch.
+ * @param   ch      The character to test.
+ */
+DECL_FORCE_INLINE(int) RTLocCToUpper(int ch)
+{
+    return RTLocCIsLower(ch) ? (ch) - 0x20 : (ch);
+}
+
+
+/** @} */
+
+#endif
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/include/iprt/err.h
@@ -0,0 +1,2551 @@
+/** @file
+ * IPRT - Status Codes.
+ */
+
+/*
+ * Copyright (C) 2006-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+#ifndef ___iprt_err_h
+#define ___iprt_err_h
+
+#include <iprt/cdefs.h>
+#include <iprt/types.h>
+#include <iprt/stdarg.h>
+
+
+/** @defgroup grp_rt_err            RTErr - Status Codes
+ * @ingroup grp_rt
+ *
+ * The IPRT status codes are in two ranges: {0..999} and {22000..32766}.  The
+ * IPRT users are free to use the range {1000..21999}.  See RTERR_RANGE1_FIRST,
+ * RTERR_RANGE1_LAST, RTERR_RANGE2_FIRST, RTERR_RANGE2_LAST, RTERR_USER_FIRST
+ * and RTERR_USER_LAST.
+ *
+ * @{
+ */
+
+/** @defgroup grp_rt_err_hlp        Status Code Helpers
+ * @{
+ */
+
+#ifdef __cplusplus
+/**
+ * Strict type validation class.
+ *
+ * This is only really useful for type checking the arguments to RT_SUCCESS,
+ * RT_SUCCESS_NP, RT_FAILURE and RT_FAILURE_NP.  The RTErrStrictType2
+ * constructor is for integration with external status code strictness regimes.
+ */
+class RTErrStrictType
+{
+protected:
+    int32_t m_rc;
+
+public:
+    /**
+     * Constructor for interaction with external status code strictness regimes.
+     *
+     * This is a special constructor for helping external return code validator
+     * classes interact cleanly with RT_SUCCESS, RT_SUCCESS_NP, RT_FAILURE and
+     * RT_FAILURE_NP while barring automatic cast to integer.
+     *
+     * @param   rcObj       IPRT status code object from an automatic cast.
+     */
+    RTErrStrictType(RTErrStrictType2 const rcObj)
+        : m_rc(rcObj.getValue())
+    {
+    }
+
+    /**
+     * Integer constructor used by RT_SUCCESS_NP.
+     *
+     * @param   rc          IPRT style status code.
+     */
+    RTErrStrictType(int32_t rc)
+        : m_rc(rc)
+    {
+    }
+
+#if 0 /** @todo figure where int32_t is long instead of int. */
+    /**
+     * Integer constructor used by RT_SUCCESS_NP.
+     *
+     * @param   rc          IPRT style status code.
+     */
+    RTErrStrictType(signed int rc)
+        : m_rc(rc)
+    {
+    }
+#endif
+
+    /**
+     * Test for success.
+     */
+    bool success() const
+    {
+        return m_rc >= 0;
+    }
+
+private:
+    /** @name Try ban a number of wrong types.
+     * @{ */
+    RTErrStrictType(uint8_t rc)         : m_rc(-999) { NOREF(rc); }
+    RTErrStrictType(uint16_t rc)        : m_rc(-999) { NOREF(rc); }
+    RTErrStrictType(uint32_t rc)        : m_rc(-999) { NOREF(rc); }
+    RTErrStrictType(uint64_t rc)        : m_rc(-999) { NOREF(rc); }
+    RTErrStrictType(int8_t rc)          : m_rc(-999) { NOREF(rc); }
+    RTErrStrictType(int16_t rc)         : m_rc(-999) { NOREF(rc); }
+    RTErrStrictType(int64_t rc)         : m_rc(-999) { NOREF(rc); }
+    /** @todo fight long here - clashes with int32_t/int64_t on some platforms. */
+    /** @} */
+};
+#endif /* __cplusplus */
+
+
+/** @def RTERR_STRICT_RC
+ * Indicates that RT_SUCCESS_NP, RT_SUCCESS, RT_FAILURE_NP and RT_FAILURE should
+ * make type enforcing at compile time.
+ *
+ * @remarks     Only define this for C++ code.
+ */
+#if defined(__cplusplus) \
+ && !defined(RTERR_STRICT_RC) \
+ && (   defined(DOXYGEN_RUNNING) \
+     || defined(DEBUG) \
+     || defined(RT_STRICT) )
+# define RTERR_STRICT_RC        1
+#endif
+
+
+/** @def RT_SUCCESS
+ * Check for success. We expect success in normal cases, that is the code path depending on
+ * this check is normally taken. To prevent any prediction use RT_SUCCESS_NP instead.
+ *
+ * @returns true if rc indicates success.
+ * @returns false if rc indicates failure.
+ *
+ * @param   rc  The iprt status code to test.
+ */
+#define RT_SUCCESS(rc)      ( RT_LIKELY(RT_SUCCESS_NP(rc)) )
+
+/** @def RT_SUCCESS_NP
+ * Check for success. Don't predict the result.
+ *
+ * @returns true if rc indicates success.
+ * @returns false if rc indicates failure.
+ *
+ * @param   rc  The iprt status code to test.
+ */
+#ifdef RTERR_STRICT_RC
+# define RT_SUCCESS_NP(rc)   ( RTErrStrictType(rc).success() )
+#else
+# define RT_SUCCESS_NP(rc)   ( (int)(rc) >= VINF_SUCCESS )
+#endif
+
+/** @def RT_FAILURE
+ * Check for failure, predicting unlikely.
+ *
+ * We don't expect in normal cases, that is the code path depending on this
+ * check is normally NOT taken. To prevent any prediction use RT_FAILURE_NP
+ * instead.
+ *
+ * @returns true if rc indicates failure.
+ * @returns false if rc indicates success.
+ *
+ * @param   rc  The iprt status code to test.
+ *
+ * @remarks Please structure your code to use the RT_SUCCESS() macro instead of
+ *          RT_FAILURE() where possible, as that gives us a better shot at good
+ *          code with the windows compilers.
+ */
+#define RT_FAILURE(rc)      ( RT_UNLIKELY(!RT_SUCCESS_NP(rc)) )
+
+/** @def RT_FAILURE_NP
+ * Check for failure, no prediction.
+ *
+ * @returns true if rc indicates failure.
+ * @returns false if rc indicates success.
+ *
+ * @param   rc  The iprt status code to test.
+ */
+#define RT_FAILURE_NP(rc)   ( !RT_SUCCESS_NP(rc) )
+
+RT_C_DECLS_BEGIN
+
+/**
+ * Converts a Darwin HRESULT error to an iprt status code.
+ *
+ * @returns iprt status code.
+ * @param   iNativeCode    HRESULT error code.
+ * @remark  Darwin ring-3 only.
+ */
+RTDECL(int)  RTErrConvertFromDarwinCOM(int32_t iNativeCode);
+
+/**
+ * Converts a Darwin IOReturn error to an iprt status code.
+ *
+ * @returns iprt status code.
+ * @param   iNativeCode    IOReturn error code.
+ * @remark  Darwin only.
+ */
+RTDECL(int)  RTErrConvertFromDarwinIO(int iNativeCode);
+
+/**
+ * Converts a Darwin kern_return_t error to an iprt status code.
+ *
+ * @returns iprt status code.
+ * @param   iNativeCode    kern_return_t error code.
+ * @remark  Darwin only.
+ */
+RTDECL(int)  RTErrConvertFromDarwinKern(int iNativeCode);
+
+/**
+ * Converts a Darwin error to an iprt status code.
+ *
+ * This will consult RTErrConvertFromDarwinKern, RTErrConvertFromDarwinIO
+ * and RTErrConvertFromDarwinCOM in this order. The latter is ring-3 only as it
+ * doesn't apply elsewhere.
+ *
+ * @returns iprt status code.
+ * @param   iNativeCode    Darwin error code.
+ * @remarks Darwin only.
+ * @remarks This is recommended over RTErrConvertFromDarwinKern and RTErrConvertFromDarwinIO
+ *          since these are really just subsets of the same error space.
+ */
+RTDECL(int)  RTErrConvertFromDarwin(int iNativeCode);
+
+/**
+ * Converts errno to iprt status code.
+ *
+ * @returns iprt status code.
+ * @param   uNativeCode    errno code.
+ */
+RTDECL(int)  RTErrConvertFromErrno(unsigned uNativeCode);
+
+/**
+ * Converts a L4 errno to a iprt status code.
+ *
+ * @returns iprt status code.
+ * @param   uNativeCode l4 errno.
+ * @remark  L4 only.
+ */
+RTDECL(int)  RTErrConvertFromL4Errno(unsigned uNativeCode);
+
+/**
+ * Converts NT status code to iprt status code.
+ *
+ * Needless to say, this is only available on NT and winXX targets.
+ *
+ * @returns iprt status code.
+ * @param   lNativeCode    NT status code.
+ * @remark  Windows only.
+ */
+RTDECL(int)  RTErrConvertFromNtStatus(long lNativeCode);
+
+/**
+ * Converts OS/2 error code to iprt status code.
+ *
+ * @returns iprt status code.
+ * @param   uNativeCode    OS/2 error code.
+ * @remark  OS/2 only.
+ */
+RTDECL(int)  RTErrConvertFromOS2(unsigned uNativeCode);
+
+/**
+ * Converts Win32 error code to iprt status code.
+ *
+ * @returns iprt status code.
+ * @param   uNativeCode    Win32 error code.
+ * @remark  Windows only.
+ */
+RTDECL(int)  RTErrConvertFromWin32(unsigned uNativeCode);
+
+/**
+ * Converts an iprt status code to a errno status code.
+ *
+ * @returns errno status code.
+ * @param   iErr    iprt status code.
+ */
+RTDECL(int)  RTErrConvertToErrno(int iErr);
+
+#ifdef IN_RING3
+
+/**
+ * iprt status code message.
+ */
+typedef struct RTSTATUSMSG
+{
+    /** Pointer to the short message string. */
+    const char *pszMsgShort;
+    /** Pointer to the full message string. */
+    const char *pszMsgFull;
+    /** Pointer to the define string. */
+    const char *pszDefine;
+    /** Status code number. */
+    int         iCode;
+} RTSTATUSMSG;
+/** Pointer to iprt status code message. */
+typedef RTSTATUSMSG *PRTSTATUSMSG;
+/** Pointer to const iprt status code message. */
+typedef const RTSTATUSMSG *PCRTSTATUSMSG;
+
+/**
+ * Get the message structure corresponding to a given iprt status code.
+ *
+ * @returns Pointer to read-only message description.
+ * @param   rc      The status code.
+ */
+RTDECL(PCRTSTATUSMSG) RTErrGet(int rc);
+
+/**
+ * Get the define corresponding to a given iprt status code.
+ *
+ * @returns Pointer to read-only string with the \#define identifier.
+ * @param   rc      The status code.
+ */
+#define RTErrGetDefine(rc)      (RTErrGet(rc)->pszDefine)
+
+/**
+ * Get the short description corresponding to a given iprt status code.
+ *
+ * @returns Pointer to read-only string with the description.
+ * @param   rc      The status code.
+ */
+#define RTErrGetShort(rc)       (RTErrGet(rc)->pszMsgShort)
+
+/**
+ * Get the full description corresponding to a given iprt status code.
+ *
+ * @returns Pointer to read-only string with the description.
+ * @param   rc      The status code.
+ */
+#define RTErrGetFull(rc)        (RTErrGet(rc)->pszMsgFull)
+
+#ifdef RT_OS_WINDOWS
+/**
+ * Windows error code message.
+ */
+typedef struct RTWINERRMSG
+{
+    /** Pointer to the full message string. */
+    const char *pszMsgFull;
+    /** Pointer to the define string. */
+    const char *pszDefine;
+    /** Error code number. */
+    long        iCode;
+} RTWINERRMSG;
+/** Pointer to Windows error code message. */
+typedef RTWINERRMSG *PRTWINERRMSG;
+/** Pointer to const Windows error code message. */
+typedef const RTWINERRMSG *PCRTWINERRMSG;
+
+/**
+ * Get the message structure corresponding to a given Windows error code.
+ *
+ * @returns Pointer to read-only message description.
+ * @param   rc      The status code.
+ */
+RTDECL(PCRTWINERRMSG) RTErrWinGet(long rc);
+
+/** On windows COM errors are part of the Windows error database. */
+typedef RTWINERRMSG RTCOMERRMSG;
+
+#else  /* !RT_OS_WINDOWS */
+
+/**
+ * COM/XPCOM error code message.
+ */
+typedef struct RTCOMERRMSG
+{
+    /** Pointer to the full message string. */
+    const char *pszMsgFull;
+    /** Pointer to the define string. */
+    const char *pszDefine;
+    /** Error code number. */
+    uint32_t    iCode;
+} RTCOMERRMSG;
+#endif /* !RT_OS_WINDOWS */
+/** Pointer to a XPCOM/COM error code message. */
+typedef RTCOMERRMSG *PRTCOMERRMSG;
+/** Pointer to const a XPCOM/COM error code message. */
+typedef const RTCOMERRMSG *PCRTCOMERRMSG;
+
+/**
+ * Get the message structure corresponding to a given COM/XPCOM error code.
+ *
+ * @returns Pointer to read-only message description.
+ * @param   rc      The status code.
+ */
+RTDECL(PCRTCOMERRMSG) RTErrCOMGet(uint32_t rc);
+
+#endif /* IN_RING3 */
+
+/** @defgroup RTERRINFO_FLAGS_XXX   RTERRINFO::fFlags
+ * @{ */
+/** Custom structure (the default). */
+#define RTERRINFO_FLAGS_T_CUSTOM    UINT32_C(0)
+/** Static structure (RTERRINFOSTATIC). */
+#define RTERRINFO_FLAGS_T_STATIC    UINT32_C(1)
+/** Allocated structure (RTErrInfoAlloc). */
+#define RTERRINFO_FLAGS_T_ALLOC     UINT32_C(2)
+/** Reserved type. */
+#define RTERRINFO_FLAGS_T_RESERVED  UINT32_C(3)
+/** Type mask. */
+#define RTERRINFO_FLAGS_T_MASK      UINT32_C(3)
+/** Error info is set. */
+#define RTERRINFO_FLAGS_SET         RT_BIT_32(2)
+/** Fixed flags (magic). */
+#define RTERRINFO_FLAGS_MAGIC       UINT32_C(0xbabe0000)
+/** The bit mask for the magic value. */
+#define RTERRINFO_FLAGS_MAGIC_MASK  UINT32_C(0xffff0000)
+/** @} */
+
+/**
+ * Initializes an error info structure.
+ *
+ * @returns @a pErrInfo.
+ * @param   pErrInfo            The error info structure to init.
+ * @param   pszMsg              The message buffer.  Must be at least one byte.
+ * @param   cbMsg               The size of the message buffer.
+ */
+DECLINLINE(PRTERRINFO) RTErrInfoInit(PRTERRINFO pErrInfo, char *pszMsg, size_t cbMsg)
+{
+    *pszMsg = '\0';
+
+    pErrInfo->fFlags         = RTERRINFO_FLAGS_T_CUSTOM | RTERRINFO_FLAGS_MAGIC;
+    pErrInfo->rc             = /*VINF_SUCCESS*/ 0;
+    pErrInfo->pszMsg         = pszMsg;
+    pErrInfo->cbMsg          = cbMsg;
+    pErrInfo->apvReserved[0] = NULL;
+    pErrInfo->apvReserved[1] = NULL;
+
+    return pErrInfo;
+}
+
+/**
+ * Initialize a static error info structure.
+ *
+ * @returns Pointer to the core error info structure.
+ * @param   pStaticErrInfo      The static error info structure to init.
+ */
+DECLINLINE(PRTERRINFO) RTErrInfoInitStatic(PRTERRINFOSTATIC pStaticErrInfo)
+{
+    RTErrInfoInit(&pStaticErrInfo->Core, pStaticErrInfo->szMsg, sizeof(pStaticErrInfo->szMsg));
+    pStaticErrInfo->Core.fFlags = RTERRINFO_FLAGS_T_STATIC | RTERRINFO_FLAGS_MAGIC;
+    return &pStaticErrInfo->Core;
+}
+
+/**
+ * Allocates a error info structure with a buffer at least the given size.
+ *
+ * @returns Pointer to an error info structure on success, NULL on failure.
+ *
+ * @param   cbMsg               The minimum message buffer size.  Use 0 to get
+ *                              the default buffer size.
+ */
+RTDECL(PRTERRINFO)  RTErrInfoAlloc(size_t cbMsg);
+
+/**
+ * Same as RTErrInfoAlloc, except that an IPRT status code is returned.
+ *
+ * @returns IPRT status code.
+ *
+ * @param   cbMsg               The minimum message buffer size.  Use 0 to get
+ *                              the default buffer size.
+ * @param   ppErrInfo           Where to store the pointer to the allocated
+ *                              error info structure on success.  This is
+ *                              always set to NULL.
+ */
+RTDECL(int)         RTErrInfoAllocEx(size_t cbMsg, PRTERRINFO *ppErrInfo);
+
+/**
+ * Frees an error info structure allocated by RTErrInfoAlloc or
+ * RTErrInfoAllocEx.
+ *
+ * @param   pErrInfo            The error info structure.
+ */
+RTDECL(void)        RTErrInfoFree(PRTERRINFO pErrInfo);
+
+/**
+ * Fills in the error info details.
+ *
+ * @returns @a rc.
+ *
+ * @param   pErrInfo            The error info structure to fill in.
+ * @param   rc                  The status code to return.
+ * @param   pszMsg              The error message string.
+ */
+RTDECL(int)         RTErrInfoSet(PRTERRINFO pErrInfo, int rc, const char *pszMsg);
+
+/**
+ * Fills in the error info details, with a sprintf style message.
+ *
+ * @returns @a rc.
+ *
+ * @param   pErrInfo            The error info structure to fill in.
+ * @param   rc                  The status code to return.
+ * @param   pszFormat           The format string.
+ * @param   ...                 The format arguments.
+ */
+RTDECL(int)         RTErrInfoSetF(PRTERRINFO pErrInfo, int rc, const char *pszFormat, ...) RT_IPRT_FORMAT_ATTR(3, 4);
+
+/**
+ * Fills in the error info details, with a vsprintf style message.
+ *
+ * @returns @a rc.
+ *
+ * @param   pErrInfo            The error info structure to fill in.
+ * @param   rc                  The status code to return.
+ * @param   pszFormat           The format string.
+ * @param   va                  The format arguments.
+ */
+RTDECL(int)         RTErrInfoSetV(PRTERRINFO pErrInfo, int rc, const char *pszFormat, va_list va) RT_IPRT_FORMAT_ATTR(3, 0);
+
+/**
+ * Adds more error info details.
+ *
+ * @returns @a rc.
+ *
+ * @param   pErrInfo            The error info structure to fill in.
+ * @param   rc                  The status code to return.
+ * @param   pszMsg              The error message string to add.
+ */
+RTDECL(int)         RTErrInfoAdd(PRTERRINFO pErrInfo, int rc, const char *pszMsg);
+
+/**
+ * Adds more error info details, with a sprintf style message.
+ *
+ * @returns @a rc.
+ *
+ * @param   pErrInfo            The error info structure to fill in.
+ * @param   rc                  The status code to return.
+ * @param   pszFormat           The format string to add.
+ * @param   ...                 The format arguments.
+ */
+RTDECL(int)         RTErrInfoAddF(PRTERRINFO pErrInfo, int rc, const char *pszFormat, ...) RT_IPRT_FORMAT_ATTR(3, 4);
+
+/**
+ * Adds more error info details, with a vsprintf style message.
+ *
+ * @returns @a rc.
+ *
+ * @param   pErrInfo            The error info structure to fill in.
+ * @param   rc                  The status code to return.
+ * @param   pszFormat           The format string to add.
+ * @param   va                  The format arguments.
+ */
+RTDECL(int)         RTErrInfoAddV(PRTERRINFO pErrInfo, int rc, const char *pszFormat, va_list va) RT_IPRT_FORMAT_ATTR(3, 0);
+
+/**
+ * Checks if the error info is set.
+ *
+ * @returns true if set, false if not.
+ * @param   pErrInfo            The error info structure. NULL is OK.
+ */
+DECLINLINE(bool)    RTErrInfoIsSet(PCRTERRINFO pErrInfo)
+{
+    if (!pErrInfo)
+        return false;
+    return (pErrInfo->fFlags & (RTERRINFO_FLAGS_MAGIC_MASK | RTERRINFO_FLAGS_SET))
+        == (RTERRINFO_FLAGS_MAGIC | RTERRINFO_FLAGS_SET);
+}
+
+/**
+ * Clears the error info structure.
+ *
+ * @param   pErrInfo            The error info structure. NULL is OK.
+ */
+DECLINLINE(void)    RTErrInfoClear(PRTERRINFO pErrInfo)
+{
+    if (pErrInfo)
+    {
+        pErrInfo->fFlags &= ~RTERRINFO_FLAGS_SET;
+        pErrInfo->rc      = /*VINF_SUCCESS*/0;
+        *pErrInfo->pszMsg = '\0';
+    }
+}
+
+/**
+ * Storage for error variables.
+ *
+ * @remarks Do NOT touch the members!  They are platform specific and what's
+ *          where may change at any time!
+ */
+typedef union RTERRVARS
+{
+    int8_t  ai8Vars[32];
+    int16_t ai16Vars[16];
+    int32_t ai32Vars[8];
+    int64_t ai64Vars[4];
+} RTERRVARS;
+/** Pointer to an error variable storage union.  */
+typedef RTERRVARS *PRTERRVARS;
+/** Pointer to a const error variable storage union.  */
+typedef RTERRVARS const *PCRTERRVARS;
+
+/**
+ * Saves the error variables.
+ *
+ * @returns @a pVars.
+ * @param   pVars       The variable storage union.
+ */
+RTDECL(PRTERRVARS) RTErrVarsSave(PRTERRVARS pVars);
+
+/**
+ * Restores the error variables.
+ *
+ * @param   pVars       The variable storage union.
+ */
+RTDECL(void) RTErrVarsRestore(PCRTERRVARS pVars);
+
+/**
+ * Checks if the first variable set equals the second.
+ *
+ * @returns true if they are equal, false if not.
+ * @param   pVars1      The first variable storage union.
+ * @param   pVars2      The second variable storage union.
+ */
+RTDECL(bool) RTErrVarsAreEqual(PCRTERRVARS pVars1, PCRTERRVARS pVars2);
+
+/**
+ * Checks if the (live) error variables have changed since we saved them.
+ *
+ * @returns @c true if they have changed, @c false if not.
+ * @param   pVars       The saved variables to compare the current state
+ *                      against.
+ */
+RTDECL(bool) RTErrVarsHaveChanged(PCRTERRVARS pVars);
+
+RT_C_DECLS_END
+
+/** @} */
+
+/** @name Status Code Ranges
+ * @{ */
+/** The first status code in the primary IPRT range. */
+#define RTERR_RANGE1_FIRST                  0
+/** The last status code in the primary IPRT range. */
+#define RTERR_RANGE1_LAST                   999
+
+/** The first status code in the secondary IPRT range. */
+#define RTERR_RANGE2_FIRST                  22000
+/** The last status code in the secondary IPRT range. */
+#define RTERR_RANGE2_LAST                   32766
+
+/** The first status code in the user range. */
+#define RTERR_USER_FIRST                    1000
+/** The last status code in the user range. */
+#define RTERR_USER_LAST                     21999
+/** @}  */
+
+
+/* SED-START */
+
+/** @name Misc. Status Codes
+ * @{
+ */
+/** Success. */
+#define VINF_SUCCESS                        0
+
+/** General failure - DON'T USE THIS!!! */
+#define VERR_GENERAL_FAILURE                (-1)
+/** Invalid parameter. */
+#define VERR_INVALID_PARAMETER              (-2)
+/** Invalid parameter. */
+#define VWRN_INVALID_PARAMETER              2
+/** Invalid magic or cookie. */
+#define VERR_INVALID_MAGIC                  (-3)
+/** Invalid magic or cookie. */
+#define VWRN_INVALID_MAGIC                  3
+/** Invalid loader handle. */
+#define VERR_INVALID_HANDLE                 (-4)
+/** Invalid loader handle. */
+#define VWRN_INVALID_HANDLE                 4
+/** Failed to lock the address range. */
+#define VERR_LOCK_FAILED                    (-5)
+/** Invalid memory pointer. */
+#define VERR_INVALID_POINTER                (-6)
+/** Failed to patch the IDT. */
+#define VERR_IDT_FAILED                     (-7)
+/** Memory allocation failed. */
+#define VERR_NO_MEMORY                      (-8)
+/** Already loaded. */
+#define VERR_ALREADY_LOADED                 (-9)
+/** Permission denied. */
+#define VERR_PERMISSION_DENIED              (-10)
+/** Permission denied. */
+#define VINF_PERMISSION_DENIED              10
+/** Version mismatch. */
+#define VERR_VERSION_MISMATCH               (-11)
+/** The request function is not implemented. */
+#define VERR_NOT_IMPLEMENTED                (-12)
+/** Invalid flags was given. */
+#define VERR_INVALID_FLAGS                  (-13)
+
+/** Not equal. */
+#define VERR_NOT_EQUAL                      (-18)
+/** The specified path does not point at a symbolic link. */
+#define VERR_NOT_SYMLINK                    (-19)
+/** Failed to allocate temporary memory. */
+#define VERR_NO_TMP_MEMORY                  (-20)
+/** Invalid file mode mask (RTFMODE). */
+#define VERR_INVALID_FMODE                  (-21)
+/** Incorrect call order. */
+#define VERR_WRONG_ORDER                    (-22)
+/** There is no TLS (thread local storage) available for storing the current thread. */
+#define VERR_NO_TLS_FOR_SELF                (-23)
+/** Failed to set the TLS (thread local storage) entry which points to our thread structure. */
+#define VERR_FAILED_TO_SET_SELF_TLS         (-24)
+/** Not able to allocate contiguous memory. */
+#define VERR_NO_CONT_MEMORY                 (-26)
+/** No memory available for page table or page directory. */
+#define VERR_NO_PAGE_MEMORY                 (-27)
+/** Already initialized. */
+#define VINF_ALREADY_INITIALIZED            28
+/** The specified thread is dead. */
+#define VERR_THREAD_IS_DEAD                 (-29)
+/** The specified thread is not waitable. */
+#define VERR_THREAD_NOT_WAITABLE            (-30)
+/** Pagetable not present. */
+#define VERR_PAGE_TABLE_NOT_PRESENT         (-31)
+/** Invalid context.
+ * Typically an API was used by the wrong thread. */
+#define VERR_INVALID_CONTEXT                (-32)
+/** The per process timer is busy. */
+#define VERR_TIMER_BUSY                     (-33)
+/** Address conflict. */
+#define VERR_ADDRESS_CONFLICT               (-34)
+/** Unresolved (unknown) host platform error. */
+#define VERR_UNRESOLVED_ERROR               (-35)
+/** Invalid function. */
+#define VERR_INVALID_FUNCTION               (-36)
+/** Not supported. */
+#define VERR_NOT_SUPPORTED                  (-37)
+/** Not supported. */
+#define VINF_NOT_SUPPORTED                  37
+/** Access denied. */
+#define VERR_ACCESS_DENIED                  (-38)
+/** Call interrupted. */
+#define VERR_INTERRUPTED                    (-39)
+/** Call interrupted. */
+#define VINF_INTERRUPTED                    39
+/** Timeout. */
+#define VERR_TIMEOUT                        (-40)
+/** Timeout. */
+#define VINF_TIMEOUT                        40
+/** Buffer too small to save result. */
+#define VERR_BUFFER_OVERFLOW                (-41)
+/** Buffer too small to save result. */
+#define VINF_BUFFER_OVERFLOW                41
+/** Data size overflow. */
+#define VERR_TOO_MUCH_DATA                  (-42)
+/** Max threads number reached. */
+#define VERR_MAX_THRDS_REACHED              (-43)
+/** Max process number reached. */
+#define VERR_MAX_PROCS_REACHED              (-44)
+/** The recipient process has refused the signal. */
+#define VERR_SIGNAL_REFUSED                 (-45)
+/** A signal is already pending. */
+#define VERR_SIGNAL_PENDING                 (-46)
+/** The signal being posted is not correct. */
+#define VERR_SIGNAL_INVALID                 (-47)
+/** The state changed.
+ * This is a generic error message and needs a context to make sense. */
+#define VERR_STATE_CHANGED                  (-48)
+/** Warning, the state changed.
+ * This is a generic error message and needs a context to make sense. */
+#define VWRN_STATE_CHANGED                  48
+/** Error while parsing UUID string */
+#define VERR_INVALID_UUID_FORMAT            (-49)
+/** The specified process was not found. */
+#define VERR_PROCESS_NOT_FOUND              (-50)
+/** The process specified to a non-block wait had not exited. */
+#define VERR_PROCESS_RUNNING                (-51)
+/** Retry the operation. */
+#define VERR_TRY_AGAIN                      (-52)
+/** Retry the operation. */
+#define VINF_TRY_AGAIN                      52
+/** Generic parse error. */
+#define VERR_PARSE_ERROR                    (-53)
+/** Value out of range. */
+#define VERR_OUT_OF_RANGE                   (-54)
+/** A numeric conversion encountered a value which was too big for the target. */
+#define VERR_NUMBER_TOO_BIG                 (-55)
+/** A numeric conversion encountered a value which was too big for the target. */
+#define VWRN_NUMBER_TOO_BIG                 55
+/** The number begin converted (string) contained no digits. */
+#define VERR_NO_DIGITS                      (-56)
+/** The number begin converted (string) contained no digits. */
+#define VWRN_NO_DIGITS                      56
+/** Encountered a '-' during conversion to an unsigned value. */
+#define VERR_NEGATIVE_UNSIGNED              (-57)
+/** Encountered a '-' during conversion to an unsigned value. */
+#define VWRN_NEGATIVE_UNSIGNED              57
+/** Error while characters translation (unicode and so). */
+#define VERR_NO_TRANSLATION                 (-58)
+/** Error while characters translation (unicode and so). */
+#define VWRN_NO_TRANSLATION                 58
+/** Encountered unicode code point which is reserved for use as endian indicator (0xffff or 0xfffe). */
+#define VERR_CODE_POINT_ENDIAN_INDICATOR    (-59)
+/** Encountered unicode code point in the surrogate range (0xd800 to 0xdfff). */
+#define VERR_CODE_POINT_SURROGATE           (-60)
+/** A string claiming to be UTF-8 is incorrectly encoded. */
+#define VERR_INVALID_UTF8_ENCODING          (-61)
+/** A string claiming to be in UTF-16 is incorrectly encoded. */
+#define VERR_INVALID_UTF16_ENCODING         (-62)
+/** Encountered a unicode code point which cannot be represented as UTF-16. */
+#define VERR_CANT_RECODE_AS_UTF16           (-63)
+/** Got an out of memory condition trying to allocate a string. */
+#define VERR_NO_STR_MEMORY                  (-64)
+/** Got an out of memory condition trying to allocate a UTF-16 (/UCS-2) string. */
+#define VERR_NO_UTF16_MEMORY                (-65)
+/** Get an out of memory condition trying to allocate a code point array. */
+#define VERR_NO_CODE_POINT_MEMORY           (-66)
+/** Can't free the memory because it's used in mapping. */
+#define VERR_MEMORY_BUSY                    (-67)
+/** The timer can't be started because it's already active. */
+#define VERR_TIMER_ACTIVE                   (-68)
+/** The timer can't be stopped because it's already suspended. */
+#define VERR_TIMER_SUSPENDED                (-69)
+/** The operation was cancelled by the user (copy) or another thread (local ipc). */
+#define VERR_CANCELLED                      (-70)
+/** Failed to initialize a memory object.
+ * Exactly what this means is OS specific. */
+#define VERR_MEMOBJ_INIT_FAILED             (-71)
+/** Out of memory condition when allocating memory with low physical backing. */
+#define VERR_NO_LOW_MEMORY                  (-72)
+/** Out of memory condition when allocating physical memory (without mapping). */
+#define VERR_NO_PHYS_MEMORY                 (-73)
+/** The address (virtual or physical) is too big. */
+#define VERR_ADDRESS_TOO_BIG                (-74)
+/** Failed to map a memory object. */
+#define VERR_MAP_FAILED                     (-75)
+/** Trailing characters. */
+#define VERR_TRAILING_CHARS                 (-76)
+/** Trailing characters. */
+#define VWRN_TRAILING_CHARS                 76
+/** Trailing spaces. */
+#define VERR_TRAILING_SPACES                (-77)
+/** Trailing spaces. */
+#define VWRN_TRAILING_SPACES                77
+/** Generic not found error. */
+#define VERR_NOT_FOUND                      (-78)
+/** Generic not found warning. */
+#define VWRN_NOT_FOUND                      78
+/** Generic invalid state error. */
+#define VERR_INVALID_STATE                  (-79)
+/** Generic invalid state warning. */
+#define VWRN_INVALID_STATE                  79
+/** Generic out of resources error. */
+#define VERR_OUT_OF_RESOURCES               (-80)
+/** Generic out of resources warning. */
+#define VWRN_OUT_OF_RESOURCES               80
+/** No more handles available, too many open handles. */
+#define VERR_NO_MORE_HANDLES                (-81)
+/** Preemption is disabled.
+ * The requested operation can only be performed when preemption is enabled. */
+#define VERR_PREEMPT_DISABLED               (-82)
+/** End of string. */
+#define VERR_END_OF_STRING                  (-83)
+/** End of string. */
+#define VINF_END_OF_STRING                  83
+/** A page count is out of range. */
+#define VERR_PAGE_COUNT_OUT_OF_RANGE        (-84)
+/** Generic object destroyed status. */
+#define VERR_OBJECT_DESTROYED               (-85)
+/** Generic object was destroyed by the call status. */
+#define VINF_OBJECT_DESTROYED               85
+/** Generic dangling objects status. */
+#define VERR_DANGLING_OBJECTS               (-86)
+/** Generic dangling objects status. */
+#define VWRN_DANGLING_OBJECTS               86
+/** Invalid Base64 encoding. */
+#define VERR_INVALID_BASE64_ENCODING        (-87)
+/** Return instigated by a callback or similar. */
+#define VERR_CALLBACK_RETURN                (-88)
+/** Return instigated by a callback or similar. */
+#define VINF_CALLBACK_RETURN                88
+/** Authentication failure. */
+#define VERR_AUTHENTICATION_FAILURE         (-89)
+/** Not a power of two. */
+#define VERR_NOT_POWER_OF_TWO               (-90)
+/** Status code, typically given as a parameter, that isn't supposed to be used. */
+#define VERR_IGNORED                        (-91)
+/** Concurrent access to the object is not allowed. */
+#define VERR_CONCURRENT_ACCESS              (-92)
+/** The caller does not have a reference to the object.
+ * This status is used when two threads is caught sharing the same object
+ * reference. */
+#define VERR_CALLER_NO_REFERENCE            (-93)
+/** Generic no change error. */
+#define VERR_NO_CHANGE                      (-95)
+/** Generic no change info. */
+#define VINF_NO_CHANGE                      95
+/** Out of memory condition when allocating executable memory. */
+#define VERR_NO_EXEC_MEMORY                 (-96)
+/** The alignment is not supported. */
+#define VERR_UNSUPPORTED_ALIGNMENT          (-97)
+/** The alignment is not really supported, however we got lucky with this
+ * allocation. */
+#define VINF_UNSUPPORTED_ALIGNMENT          97
+/** Duplicate something. */
+#define VERR_DUPLICATE                      (-98)
+/** Something is missing. */
+#define VERR_MISSING                        (-99)
+/** An unexpected (/unknown) exception was caught. */
+#define VERR_UNEXPECTED_EXCEPTION           (-22400)
+/** Buffer underflow. */
+#define VERR_BUFFER_UNDERFLOW               (-22401)
+/** Buffer underflow. */
+#define VINF_BUFFER_UNDERFLOW               22401
+/** Uneven input. */
+#define VERR_UNEVEN_INPUT                   (-22402)
+/** Something is not available or not working properly. */
+#define VERR_NOT_AVAILABLE                  (-22403)
+/** The RTPROC_FLAGS_DETACHED flag isn't supported. */
+#define VERR_PROC_DETACH_NOT_SUPPORTED      (-22404)
+/** An account is restricted in a certain way. */
+#define VERR_ACCOUNT_RESTRICTED             (-22405)
+/** An account is restricted in a certain way. */
+#define VINF_ACCOUNT_RESTRICTED             22405
+/** Not able satisfy all the requirements of the request. */
+#define VERR_UNABLE_TO_SATISFY_REQUIREMENTS (-22406)
+/** Not able satisfy all the requirements of the request. */
+#define VWRN_UNABLE_TO_SATISFY_REQUIREMENTS 22406
+/** The requested allocation is too big. */
+#define VERR_ALLOCATION_TOO_BIG             (-22407)
+/** Mismatch. */
+#define VERR_MISMATCH                       (-22408)
+/** Wrong type. */
+#define VERR_WRONG_TYPE                     (-22409)
+/** This indicates that the process does not have sufficient privileges to
+ * perform the operation. */
+#define VERR_PRIVILEGE_NOT_HELD             (-22410)
+/** Process does not have the trusted code base (TCB) privilege needed for user
+ * authentication or/and process creation as a given user.  TCB is also called
+ * 'Act as part of the operating system'. */
+#define VERR_PROC_TCB_PRIV_NOT_HELD         (-22411)
+/** Process does not have the assign primary token (APT) privilege needed
+ * for creating process as a given user.  APT is also called 'Replace a process
+ * level token'. */
+#define VERR_PROC_APT_PRIV_NOT_HELD         (-22412)
+/** Process does not have the increase quota (IQ) privilege needed for
+ * creating a process as a given user. IQ is also called 'Increase quotas'. */
+#define VERR_PROC_IQ_PRIV_NOT_HELD          (-22413)
+/** @} */
+
+
+/** @name Common File/Disk/Pipe/etc Status Codes
+ * @{
+ */
+/** Unresolved (unknown) file i/o error. */
+#define VERR_FILE_IO_ERROR                  (-100)
+/** File/Device open failed. */
+#define VERR_OPEN_FAILED                    (-101)
+/** File not found. */
+#define VERR_FILE_NOT_FOUND                 (-102)
+/** Path not found. */
+#define VERR_PATH_NOT_FOUND                 (-103)
+/** Invalid (malformed) file/path name. */
+#define VERR_INVALID_NAME                   (-104)
+/** The object in question already exists. */
+#define VERR_ALREADY_EXISTS                 (-105)
+/** The object in question already exists. */
+#define VWRN_ALREADY_EXISTS                 105
+/** Too many open files. */
+#define VERR_TOO_MANY_OPEN_FILES            (-106)
+/** Seek error. */
+#define VERR_SEEK                           (-107)
+/** Seek below file start. */
+#define VERR_NEGATIVE_SEEK                  (-108)
+/** Trying to seek on device. */
+#define VERR_SEEK_ON_DEVICE                 (-109)
+/** Reached the end of the file. */
+#define VERR_EOF                            (-110)
+/** Reached the end of the file. */
+#define VINF_EOF                            110
+/** Generic file read error. */
+#define VERR_READ_ERROR                     (-111)
+/** Generic file write error. */
+#define VERR_WRITE_ERROR                    (-112)
+/** Write protect error. */
+#define VERR_WRITE_PROTECT                  (-113)
+/** Sharing violation, file is being used by another process. */
+#define VERR_SHARING_VIOLATION              (-114)
+/** Unable to lock a region of a file. */
+#define VERR_FILE_LOCK_FAILED               (-115)
+/** File access error, another process has locked a portion of the file. */
+#define VERR_FILE_LOCK_VIOLATION            (-116)
+/** File or directory can't be created. */
+#define VERR_CANT_CREATE                    (-117)
+/** Directory can't be deleted. */
+#define VERR_CANT_DELETE_DIRECTORY          (-118)
+/** Can't move file to another disk. */
+#define VERR_NOT_SAME_DEVICE                (-119)
+/** The filename or extension is too long. */
+#define VERR_FILENAME_TOO_LONG              (-120)
+/** Media not present in drive. */
+#define VERR_MEDIA_NOT_PRESENT              (-121)
+/** The type of media was not recognized. Not formatted? */
+#define VERR_MEDIA_NOT_RECOGNIZED           (-122)
+/** Can't unlock - region was not locked. */
+#define VERR_FILE_NOT_LOCKED                (-123)
+/** Unrecoverable error: lock was lost. */
+#define VERR_FILE_LOCK_LOST                 (-124)
+/** Can't delete directory with files. */
+#define VERR_DIR_NOT_EMPTY                  (-125)
+/** A directory operation was attempted on a non-directory object. */
+#define VERR_NOT_A_DIRECTORY                (-126)
+/** A non-directory operation was attempted on a directory object. */
+#define VERR_IS_A_DIRECTORY                 (-127)
+/** Tried to grow a file beyond the limit imposed by the process or the filesystem. */
+#define VERR_FILE_TOO_BIG                   (-128)
+/** No pending request the aio context has to wait for completion. */
+#define VERR_FILE_AIO_NO_REQUEST            (-129)
+/** The request could not be canceled or prepared for another transfer
+ *  because it is still in progress. */
+#define VERR_FILE_AIO_IN_PROGRESS           (-130)
+/** The request could not be canceled because it already completed. */
+#define VERR_FILE_AIO_COMPLETED             (-131)
+/** The I/O context couldn't be destroyed because there are still pending requests. */
+#define VERR_FILE_AIO_BUSY                  (-132)
+/** The requests couldn't be submitted because that would exceed the capacity of the context. */
+#define VERR_FILE_AIO_LIMIT_EXCEEDED        (-133)
+/** The request was canceled. */
+#define VERR_FILE_AIO_CANCELED              (-134)
+/** The request wasn't submitted so it can't be canceled. */
+#define VERR_FILE_AIO_NOT_SUBMITTED         (-135)
+/** A request was not prepared and thus could not be submitted. */
+#define VERR_FILE_AIO_NOT_PREPARED          (-136)
+/** Not all requests could be submitted due to resource shortage. */
+#define VERR_FILE_AIO_INSUFFICIENT_RESSOURCES (-137)
+/** Device or resource is busy. */
+#define VERR_RESOURCE_BUSY                  (-138)
+/** A file operation was attempted on a non-file object. */
+#define VERR_NOT_A_FILE                     (-139)
+/** A non-file operation was attempted on a file object. */
+#define VERR_IS_A_FILE                      (-140)
+/** Unexpected filesystem object type. */
+#define VERR_UNEXPECTED_FS_OBJ_TYPE         (-141)
+/** A path does not start with a root specification. */
+#define VERR_PATH_DOES_NOT_START_WITH_ROOT  (-142)
+/** A path is relative, expected an absolute path. */
+#define VERR_PATH_IS_RELATIVE               (-143)
+/** A path is not relative (start with root), expected an relative path. */
+#define VERR_PATH_IS_NOT_RELATIVE           (-144)
+/** Zero length path. */
+#define VERR_PATH_ZERO_LENGTH               (-145)
+/** There are not enough events available on the host to create the I/O context.
+ * This exact meaning is host platform dependent. */
+#define VERR_FILE_AIO_INSUFFICIENT_EVENTS   (-146)
+/** @} */
+
+
+/** @name Generic Filesystem I/O Status Codes
+ * @{
+ */
+/** Unresolved (unknown) disk i/o error.  */
+#define VERR_DISK_IO_ERROR                  (-150)
+/** Invalid drive number. */
+#define VERR_INVALID_DRIVE                  (-151)
+/** Disk is full. */
+#define VERR_DISK_FULL                      (-152)
+/** Disk was changed. */
+#define VERR_DISK_CHANGE                    (-153)
+/** Drive is locked. */
+#define VERR_DRIVE_LOCKED                   (-154)
+/** The specified disk or diskette cannot be accessed. */
+#define VERR_DISK_INVALID_FORMAT            (-155)
+/** Too many symbolic links. */
+#define VERR_TOO_MANY_SYMLINKS              (-156)
+/** The OS does not support setting the time stamps on a symbolic link. */
+#define VERR_NS_SYMLINK_SET_TIME            (-157)
+/** The OS does not support changing the owner of a symbolic link. */
+#define VERR_NS_SYMLINK_CHANGE_OWNER        (-158)
+/** @} */
+
+
+/** @name Generic Directory Enumeration Status Codes
+ * @{
+ */
+/** Unresolved (unknown) search error. */
+#define VERR_SEARCH_ERROR                   (-200)
+/** No more files found. */
+#define VERR_NO_MORE_FILES                  (-201)
+/** No more search handles available. */
+#define VERR_NO_MORE_SEARCH_HANDLES         (-202)
+/** RTDirReadEx() failed to retrieve the extra data which was requested. */
+#define VWRN_NO_DIRENT_INFO                 203
+/** @} */
+
+
+/** @name Internal Processing Errors
+ * @{
+ */
+/** Internal error - this should never happen.  */
+#define VERR_INTERNAL_ERROR                 (-225)
+/** Internal error no. 2. */
+#define VERR_INTERNAL_ERROR_2               (-226)
+/** Internal error no. 3. */
+#define VERR_INTERNAL_ERROR_3               (-227)
+/** Internal error no. 4. */
+#define VERR_INTERNAL_ERROR_4               (-228)
+/** Internal error no. 5. */
+#define VERR_INTERNAL_ERROR_5               (-229)
+/** Internal error: Unexpected status code. */
+#define VERR_IPE_UNEXPECTED_STATUS          (-230)
+/** Internal error: Unexpected status code. */
+#define VERR_IPE_UNEXPECTED_INFO_STATUS     (-231)
+/** Internal error: Unexpected status code. */
+#define VERR_IPE_UNEXPECTED_ERROR_STATUS    (-232)
+/** Internal error: Uninitialized status code.
+ * @remarks This is used by value elsewhere.  */
+#define VERR_IPE_UNINITIALIZED_STATUS       (-233)
+/** Internal error: Supposedly unreachable default case in a switch. */
+#define VERR_IPE_NOT_REACHED_DEFAULT_CASE   (-234)
+/** @} */
+
+
+/** @name Generic Device I/O Status Codes
+ * @{
+ */
+/** Unresolved (unknown) device i/o error. */
+#define VERR_DEV_IO_ERROR                   (-250)
+/** Device i/o: Bad unit. */
+#define VERR_IO_BAD_UNIT                    (-251)
+/** Device i/o: Not ready. */
+#define VERR_IO_NOT_READY                   (-252)
+/** Device i/o: Bad command. */
+#define VERR_IO_BAD_COMMAND                 (-253)
+/** Device i/o: CRC error. */
+#define VERR_IO_CRC                         (-254)
+/** Device i/o: Bad length. */
+#define VERR_IO_BAD_LENGTH                  (-255)
+/** Device i/o: Sector not found. */
+#define VERR_IO_SECTOR_NOT_FOUND            (-256)
+/** Device i/o: General failure. */
+#define VERR_IO_GEN_FAILURE                 (-257)
+/** @} */
+
+
+/** @name Generic Pipe I/O Status Codes
+ * @{
+ */
+/** Unresolved (unknown) pipe i/o error. */
+#define VERR_PIPE_IO_ERROR                  (-300)
+/** Broken pipe. */
+#define VERR_BROKEN_PIPE                    (-301)
+/** Bad pipe. */
+#define VERR_BAD_PIPE                       (-302)
+/** Pipe is busy. */
+#define VERR_PIPE_BUSY                      (-303)
+/** No data in pipe. */
+#define VERR_NO_DATA                        (-304)
+/** Pipe is not connected. */
+#define VERR_PIPE_NOT_CONNECTED             (-305)
+/** More data available in pipe. */
+#define VERR_MORE_DATA                      (-306)
+/** Expected read pipe, got a write pipe instead. */
+#define VERR_PIPE_NOT_READ                  (-307)
+/** Expected write pipe, got a read pipe instead. */
+#define VERR_PIPE_NOT_WRITE                 (-308)
+/** @} */
+
+
+/** @name Generic Semaphores Status Codes
+ * @{
+ */
+/** Unresolved (unknown) semaphore error. */
+#define VERR_SEM_ERROR                      (-350)
+/** Too many semaphores. */
+#define VERR_TOO_MANY_SEMAPHORES            (-351)
+/** Exclusive semaphore is owned by another process. */
+#define VERR_EXCL_SEM_ALREADY_OWNED         (-352)
+/** The semaphore is set and cannot be closed. */
+#define VERR_SEM_IS_SET                     (-353)
+/** The semaphore cannot be set again. */
+#define VERR_TOO_MANY_SEM_REQUESTS          (-354)
+/** Attempt to release mutex not owned by caller. */
+#define VERR_NOT_OWNER                      (-355)
+/** The semaphore has been opened too many times. */
+#define VERR_TOO_MANY_OPENS                 (-356)
+/** The maximum posts for the event semaphore has been reached. */
+#define VERR_TOO_MANY_POSTS                 (-357)
+/** The event semaphore has already been posted. */
+#define VERR_ALREADY_POSTED                 (-358)
+/** The event semaphore has already been reset. */
+#define VERR_ALREADY_RESET                  (-359)
+/** The semaphore is in use. */
+#define VERR_SEM_BUSY                       (-360)
+/** The previous ownership of this semaphore has ended. */
+#define VERR_SEM_OWNER_DIED                 (-361)
+/** Failed to open semaphore by name - not found. */
+#define VERR_SEM_NOT_FOUND                  (-362)
+/** Semaphore destroyed while waiting. */
+#define VERR_SEM_DESTROYED                  (-363)
+/** Nested ownership requests are not permitted for this semaphore type. */
+#define VERR_SEM_NESTED                     (-364)
+/** The release call only release a semaphore nesting, i.e. the caller is still
+ * holding the semaphore. */
+#define VINF_SEM_NESTED                     (364)
+/** Deadlock detected. */
+#define VERR_DEADLOCK                       (-365)
+/** Ping-Pong listen or speak out of turn error. */
+#define VERR_SEM_OUT_OF_TURN                (-366)
+/** Tried to take a semaphore in a bad context. */
+#define VERR_SEM_BAD_CONTEXT                (-367)
+/** Don't spin for the semaphore, but it is safe to try grab it. */
+#define VINF_SEM_BAD_CONTEXT                (367)
+/** Wrong locking order detected. */
+#define VERR_SEM_LV_WRONG_ORDER             (-368)
+/** Wrong release order detected. */
+#define VERR_SEM_LV_WRONG_RELEASE_ORDER     (-369)
+/** Attempt to recursively enter a non-recursive lock. */
+#define VERR_SEM_LV_NESTED                  (-370)
+/** Invalid parameters passed to the lock validator. */
+#define VERR_SEM_LV_INVALID_PARAMETER       (-371)
+/** The lock validator detected a deadlock. */
+#define VERR_SEM_LV_DEADLOCK                (-372)
+/** The lock validator detected an existing deadlock.
+ * The deadlock was not caused by the current operation, but existed already. */
+#define VERR_SEM_LV_EXISTING_DEADLOCK       (-373)
+/** Not the lock owner according our records. */
+#define VERR_SEM_LV_NOT_OWNER               (-374)
+/** An illegal lock upgrade was attempted. */
+#define VERR_SEM_LV_ILLEGAL_UPGRADE         (-375)
+/** The thread is not a valid signaller of the event. */
+#define VERR_SEM_LV_NOT_SIGNALLER           (-376)
+/** Internal error in the lock validator or related components. */
+#define VERR_SEM_LV_INTERNAL_ERROR          (-377)
+/** @} */
+
+
+/** @name Generic Network I/O Status Codes
+ * @{
+ */
+/** Unresolved (unknown) network error. */
+#define VERR_NET_IO_ERROR                       (-400)
+/** The network is busy or is out of resources. */
+#define VERR_NET_OUT_OF_RESOURCES               (-401)
+/** Net host name not found. */
+#define VERR_NET_HOST_NOT_FOUND                 (-402)
+/** Network path not found. */
+#define VERR_NET_PATH_NOT_FOUND                 (-403)
+/** General network printing error. */
+#define VERR_NET_PRINT_ERROR                    (-404)
+/** The machine is not on the network. */
+#define VERR_NET_NO_NETWORK                     (-405)
+/** Name is not unique on the network. */
+#define VERR_NET_NOT_UNIQUE_NAME                (-406)
+
+/* These are BSD networking error codes - numbers correspond, don't mess! */
+/** Operation in progress. */
+#define VERR_NET_IN_PROGRESS                    (-436)
+/** Operation already in progress. */
+#define VERR_NET_ALREADY_IN_PROGRESS            (-437)
+/** Attempted socket operation with a non-socket handle.
+ * (This includes closed handles.) */
+#define VERR_NET_NOT_SOCKET                     (-438)
+/** Destination address required. */
+#define VERR_NET_DEST_ADDRESS_REQUIRED          (-439)
+/** Message too long. */
+#define VERR_NET_MSG_SIZE                       (-440)
+/** Protocol wrong type for socket. */
+#define VERR_NET_PROTOCOL_TYPE                  (-441)
+/** Protocol not available. */
+#define VERR_NET_PROTOCOL_NOT_AVAILABLE         (-442)
+/** Protocol not supported. */
+#define VERR_NET_PROTOCOL_NOT_SUPPORTED         (-443)
+/** Socket type not supported. */
+#define VERR_NET_SOCKET_TYPE_NOT_SUPPORTED      (-444)
+/** Operation not supported. */
+#define VERR_NET_OPERATION_NOT_SUPPORTED        (-445)
+/** Protocol family not supported. */
+#define VERR_NET_PROTOCOL_FAMILY_NOT_SUPPORTED  (-446)
+/** Address family not supported by protocol family. */
+#define VERR_NET_ADDRESS_FAMILY_NOT_SUPPORTED   (-447)
+/** Address already in use. */
+#define VERR_NET_ADDRESS_IN_USE                 (-448)
+/** Can't assign requested address. */
+#define VERR_NET_ADDRESS_NOT_AVAILABLE          (-449)
+/** Network is down. */
+#define VERR_NET_DOWN                           (-450)
+/** Network is unreachable. */
+#define VERR_NET_UNREACHABLE                    (-451)
+/** Network dropped connection on reset. */
+#define VERR_NET_CONNECTION_RESET               (-452)
+/** Software caused connection abort. */
+#define VERR_NET_CONNECTION_ABORTED             (-453)
+/** Connection reset by peer. */
+#define VERR_NET_CONNECTION_RESET_BY_PEER       (-454)
+/** No buffer space available. */
+#define VERR_NET_NO_BUFFER_SPACE                (-455)
+/** Socket is already connected. */
+#define VERR_NET_ALREADY_CONNECTED              (-456)
+/** Socket is not connected. */
+#define VERR_NET_NOT_CONNECTED                  (-457)
+/** Can't send after socket shutdown. */
+#define VERR_NET_SHUTDOWN                       (-458)
+/** Too many references: can't splice. */
+#define VERR_NET_TOO_MANY_REFERENCES            (-459)
+/** Too many references: can't splice. */
+#define VERR_NET_CONNECTION_TIMED_OUT           (-460)
+/** Connection refused. */
+#define VERR_NET_CONNECTION_REFUSED             (-461)
+/* ELOOP is not net. */
+/* ENAMETOOLONG is not net. */
+/** Host is down. */
+#define VERR_NET_HOST_DOWN                      (-464)
+/** No route to host. */
+#define VERR_NET_HOST_UNREACHABLE               (-465)
+/** Protocol error. */
+#define VERR_NET_PROTOCOL_ERROR                 (-466)
+/** Incomplete packet was submitted by guest. */
+#define VERR_NET_INCOMPLETE_TX_PACKET           (-467)
+/** @} */
+
+
+/** @name TCP Status Codes
+ * @{
+ */
+/** Stop the TCP server. */
+#define VERR_TCP_SERVER_STOP                    (-500)
+/** The server was stopped. */
+#define VINF_TCP_SERVER_STOP                    500
+/** The TCP server was shut down using RTTcpServerShutdown. */
+#define VERR_TCP_SERVER_SHUTDOWN                (-501)
+/** The TCP server was destroyed. */
+#define VERR_TCP_SERVER_DESTROYED               (-502)
+/** The TCP server has no client associated with it. */
+#define VINF_TCP_SERVER_NO_CLIENT               503
+/** @} */
+
+
+/** @name UDP Status Codes
+ * @{
+ */
+/** Stop the UDP server. */
+#define VERR_UDP_SERVER_STOP                    (-520)
+/** The server was stopped. */
+#define VINF_UDP_SERVER_STOP                    520
+/** The UDP server was shut down using RTUdpServerShutdown. */
+#define VERR_UDP_SERVER_SHUTDOWN                (-521)
+/** The UDP server was destroyed. */
+#define VERR_UDP_SERVER_DESTROYED               (-522)
+/** The UDP server has no client associated with it. */
+#define VINF_UDP_SERVER_NO_CLIENT               523
+/** @} */
+
+
+/** @name L4 Specific Status Codes
+ * @{
+ */
+/** Invalid offset in an L4 dataspace */
+#define VERR_L4_INVALID_DS_OFFSET               (-550)
+/** IPC error */
+#define VERR_IPC                                (-551)
+/** Item already used */
+#define VERR_RESOURCE_IN_USE                    (-552)
+/** Source/destination not found */
+#define VERR_IPC_PROCESS_NOT_FOUND              (-553)
+/** Receive timeout */
+#define VERR_IPC_RECEIVE_TIMEOUT                (-554)
+/** Send timeout */
+#define VERR_IPC_SEND_TIMEOUT                   (-555)
+/** Receive cancelled */
+#define VERR_IPC_RECEIVE_CANCELLED              (-556)
+/** Send cancelled */
+#define VERR_IPC_SEND_CANCELLED                 (-557)
+/** Receive aborted */
+#define VERR_IPC_RECEIVE_ABORTED                (-558)
+/** Send aborted */
+#define VERR_IPC_SEND_ABORTED                   (-559)
+/** Couldn't map pages during receive */
+#define VERR_IPC_RECEIVE_MAP_FAILED             (-560)
+/** Couldn't map pages during send */
+#define VERR_IPC_SEND_MAP_FAILED                (-561)
+/** Send pagefault timeout in receive */
+#define VERR_IPC_RECEIVE_SEND_PF_TIMEOUT        (-562)
+/** Send pagefault timeout in send */
+#define VERR_IPC_SEND_SEND_PF_TIMEOUT           (-563)
+/** (One) receive buffer was too small, or too few buffers */
+#define VINF_IPC_RECEIVE_MSG_CUT                564
+/** (One) send buffer was too small, or too few buffers */
+#define VINF_IPC_SEND_MSG_CUT                   565
+/** Dataspace manager server not found */
+#define VERR_L4_DS_MANAGER_NOT_FOUND            (-566)
+/** @} */
+
+
+/** @name Loader Status Codes.
+ * @{
+ */
+/** Invalid executable signature. */
+#define VERR_INVALID_EXE_SIGNATURE              (-600)
+/** The iprt loader recognized a ELF image, but doesn't support loading it. */
+#define VERR_ELF_EXE_NOT_SUPPORTED              (-601)
+/** The iprt loader recognized a PE image, but doesn't support loading it. */
+#define VERR_PE_EXE_NOT_SUPPORTED               (-602)
+/** The iprt loader recognized a LX image, but doesn't support loading it. */
+#define VERR_LX_EXE_NOT_SUPPORTED               (-603)
+/** The iprt loader recognized a LE image, but doesn't support loading it. */
+#define VERR_LE_EXE_NOT_SUPPORTED               (-604)
+/** The iprt loader recognized a NE image, but doesn't support loading it. */
+#define VERR_NE_EXE_NOT_SUPPORTED               (-605)
+/** The iprt loader recognized a MZ image, but doesn't support loading it. */
+#define VERR_MZ_EXE_NOT_SUPPORTED               (-606)
+/** The iprt loader recognized an a.out image, but doesn't support loading it. */
+#define VERR_AOUT_EXE_NOT_SUPPORTED             (-607)
+/** Bad executable. */
+#define VERR_BAD_EXE_FORMAT                     (-608)
+/** Symbol (export) not found. */
+#define VERR_SYMBOL_NOT_FOUND                   (-609)
+/** Module not found. */
+#define VERR_MODULE_NOT_FOUND                   (-610)
+/** The loader resolved an external symbol to an address to big for the image format. */
+#define VERR_SYMBOL_VALUE_TOO_BIG               (-611)
+/** The image is too big. */
+#define VERR_IMAGE_TOO_BIG                      (-612)
+/** The image base address is to high for this image type. */
+#define VERR_IMAGE_BASE_TOO_HIGH                (-614)
+/** Mismatching architecture. */
+#define VERR_LDR_ARCH_MISMATCH                  (-615)
+/** Mismatch between IPRT and native loader. */
+#define VERR_LDR_MISMATCH_NATIVE                (-616)
+/** Failed to resolve an imported (external) symbol. */
+#define VERR_LDR_IMPORTED_SYMBOL_NOT_FOUND      (-617)
+/** Generic loader failure. */
+#define VERR_LDR_GENERAL_FAILURE                (-618)
+/** Code signing error.  */
+#define VERR_LDR_IMAGE_HASH                     (-619)
+/** The PE loader encountered delayed imports, a feature which hasn't been implemented yet. */
+#define VERR_LDRPE_DELAY_IMPORT                 (-620)
+/** The PE loader encountered a malformed certificate. */
+#define VERR_LDRPE_CERT_MALFORMED               (-621)
+/** The PE loader encountered a certificate with an unsupported type or structure revision. */
+#define VERR_LDRPE_CERT_UNSUPPORTED             (-622)
+/** The PE loader doesn't know how to deal with the global pointer data directory entry yet. */
+#define VERR_LDRPE_GLOBALPTR                    (-623)
+/** The PE loader doesn't support the TLS data directory yet. */
+#define VERR_LDRPE_TLS                          (-624)
+/** The PE loader doesn't grok the COM descriptor data directory entry. */
+#define VERR_LDRPE_COM_DESCRIPTOR               (-625)
+/** The PE loader encountered an unknown load config directory/header size. */
+#define VERR_LDRPE_LOAD_CONFIG_SIZE             (-626)
+/** The PE loader encountered a lock prefix table, a feature which hasn't been implemented yet. */
+#define VERR_LDRPE_LOCK_PREFIX_TABLE            (-627)
+/** The PE loader encountered some Guard CF stuff in the load config.   */
+#define VERR_LDRPE_GUARD_CF_STUFF               (-628)
+/** The ELF loader doesn't handle foreign endianness. */
+#define VERR_LDRELF_ODD_ENDIAN                  (-630)
+/** The ELF image is 'dynamic', the ELF loader can only deal with 'relocatable' images at present. */
+#define VERR_LDRELF_DYN                         (-631)
+/** The ELF image is 'executable', the ELF loader can only deal with 'relocatable' images at present. */
+#define VERR_LDRELF_EXEC                        (-632)
+/** The ELF image was created for an unsupported target machine type. */
+#define VERR_LDRELF_MACHINE                     (-633)
+/** The ELF version is not supported. */
+#define VERR_LDRELF_VERSION                     (-634)
+/** The ELF loader cannot handle multiple SYMTAB sections. */
+#define VERR_LDRELF_MULTIPLE_SYMTABS            (-635)
+/** The ELF loader encountered a relocation type which is not implemented. */
+#define VERR_LDRELF_RELOCATION_NOT_SUPPORTED    (-636)
+/** The ELF loader encountered a bad symbol index. */
+#define VERR_LDRELF_INVALID_SYMBOL_INDEX        (-637)
+/** The ELF loader encountered an invalid symbol name offset. */
+#define VERR_LDRELF_INVALID_SYMBOL_NAME_OFFSET  (-638)
+/** The ELF loader encountered an invalid relocation offset. */
+#define VERR_LDRELF_INVALID_RELOCATION_OFFSET   (-639)
+/** The ELF loader didn't find the symbol/string table for the image. */
+#define VERR_LDRELF_NO_SYMBOL_OR_NO_STRING_TABS (-640)
+/** Invalid link address. */
+#define VERR_LDR_INVALID_LINK_ADDRESS           (-647)
+/** Invalid image relative virtual address. */
+#define VERR_LDR_INVALID_RVA                    (-648)
+/** Invalid segment:offset address. */
+#define VERR_LDR_INVALID_SEG_OFFSET             (-649)
+/** @}*/
+
+/** @name Debug Info Reader Status Codes.
+ * @{
+ */
+/** The module contains no line number information. */
+#define VERR_DBG_NO_LINE_NUMBERS                (-650)
+/** The module contains no symbol information. */
+#define VERR_DBG_NO_SYMBOLS                     (-651)
+/** The specified segment:offset address was invalid. Typically an attempt at
+ * addressing outside the segment boundary. */
+#define VERR_DBG_INVALID_ADDRESS                (-652)
+/** Invalid segment index. */
+#define VERR_DBG_INVALID_SEGMENT_INDEX          (-653)
+/** Invalid segment offset. */
+#define VERR_DBG_INVALID_SEGMENT_OFFSET         (-654)
+/** Invalid image relative virtual address. */
+#define VERR_DBG_INVALID_RVA                    (-655)
+/** Invalid image relative virtual address. */
+#define VERR_DBG_SPECIAL_SEGMENT                (-656)
+/** Address conflict within a module/segment.
+ * Attempted to add a segment, symbol or line number that fully or partially
+ * overlaps with an existing one. */
+#define VERR_DBG_ADDRESS_CONFLICT               (-657)
+/** Duplicate symbol within the module.
+ * Attempted to add a symbol which name already exists within the module.  */
+#define VERR_DBG_DUPLICATE_SYMBOL               (-658)
+/** The segment index specified when adding a new segment is already in use. */
+#define VERR_DBG_SEGMENT_INDEX_CONFLICT         (-659)
+/** No line number was found for the specified address/ordinal/whatever. */
+#define VERR_DBG_LINE_NOT_FOUND                 (-660)
+/** The length of the symbol name is out of range.
+ * This means it is an empty string or that it's greater or equal to
+ * RTDBG_SYMBOL_NAME_LENGTH. */
+#define VERR_DBG_SYMBOL_NAME_OUT_OF_RANGE       (-661)
+/** The length of the file name is out of range.
+ * This means it is an empty string or that it's greater or equal to
+ * RTDBG_FILE_NAME_LENGTH. */
+#define VERR_DBG_FILE_NAME_OUT_OF_RANGE         (-662)
+/** The length of the segment name is out of range.
+ * This means it is an empty string or that it is greater or equal to
+ * RTDBG_SEGMENT_NAME_LENGTH. */
+#define VERR_DBG_SEGMENT_NAME_OUT_OF_RANGE      (-663)
+/** The specified address range wraps around. */
+#define VERR_DBG_ADDRESS_WRAP                   (-664)
+/** The file is not a valid NM map file. */
+#define VERR_DBG_NOT_NM_MAP_FILE                (-665)
+/** The file is not a valid /proc/kallsyms file. */
+#define VERR_DBG_NOT_LINUX_KALLSYMS             (-666)
+/** No debug module interpreter matching the debug info. */
+#define VERR_DBG_NO_MATCHING_INTERPRETER        (-667)
+/** Bad DWARF line number header. */
+#define VERR_DWARF_BAD_LINE_NUMBER_HEADER       (-668)
+/** Unexpected end of DWARF unit. */
+#define VERR_DWARF_UNEXPECTED_END               (-669)
+/** DWARF LEB value overflows the decoder type. */
+#define VERR_DWARF_LEB_OVERFLOW                 (-670)
+/** Bad DWARF extended line number opcode. */
+#define VERR_DWARF_BAD_LNE                      (-671)
+/** Bad DWARF string. */
+#define VERR_DWARF_BAD_STRING                   (-672)
+/** Bad DWARF position. */
+#define VERR_DWARF_BAD_POS                      (-673)
+/** Bad DWARF info. */
+#define VERR_DWARF_BAD_INFO                     (-674)
+/** Bad DWARF abbreviation data. */
+#define VERR_DWARF_BAD_ABBREV                   (-675)
+/** A DWARF abbreviation was not found. */
+#define VERR_DWARF_ABBREV_NOT_FOUND             (-676)
+/** Encountered an unknown attribute form. */
+#define VERR_DWARF_UNKNOWN_FORM                 (-677)
+/** Encountered an unexpected attribute form. */
+#define VERR_DWARF_UNEXPECTED_FORM              (-678)
+/** Unfinished code. */
+#define VERR_DWARF_TODO                         (-679)
+/** Unknown location opcode. */
+#define VERR_DWARF_UNKNOWN_LOC_OPCODE           (-680)
+/** Expression stack overflow. */
+#define VERR_DWARF_STACK_OVERFLOW               (-681)
+/** Expression stack underflow. */
+#define VERR_DWARF_STACK_UNDERFLOW              (-682)
+/** Internal processing error in the DWARF code. */
+#define VERR_DWARF_IPE                          (-683)
+/** Invalid configuration property value. */
+#define VERR_DBG_CFG_INVALID_VALUE              (-684)
+/** Not an integer property. */
+#define VERR_DBG_CFG_NOT_UINT_PROP              (-685)
+/** Deferred loading of information failed. */
+#define VERR_DBG_DEFERRED_LOAD_FAILED           (-686)
+/** Unfinished debug info reader code. */
+#define VERR_DBG_TODO                           (-687)
+/** Found file, but it didn't match the search criteria. */
+#define VERR_DBG_FILE_MISMATCH                  (-688)
+/** Internal processing error in the debug module reader code. */
+#define VERR_DBG_MOD_IPE                        (-689)
+/** The symbol size was adjusted while adding it. */
+#define VINF_DBG_ADJUSTED_SYM_SIZE              690
+/** Unable to parse the CodeView debug information. */
+#define VERR_CV_BAD_FORMAT                      (-691)
+/** Unfinished CodeView debug information feature. */
+#define VERR_CV_TODO                            (-692)
+/** Internal processing error the CodeView debug information reader. */
+#define VERR_CV_IPE                             (-693)
+/** @} */
+
+/** @name Request Packet Status Codes.
+ * @{
+ */
+/** Invalid RT request type.
+ * For the RTReqAlloc() case, the caller just specified an illegal enmType. For
+ * all the other occurrences it means indicates corruption, broken logic, or stupid
+ * interface user. */
+#define VERR_RT_REQUEST_INVALID_TYPE            (-700)
+/** Invalid RT request state.
+ * The state of the request packet was not the expected and accepted one(s). Either
+ * the interface user screwed up, or we've got corruption/broken logic. */
+#define VERR_RT_REQUEST_STATE                   (-701)
+/** Invalid RT request packet.
+ * One or more of the RT controlled packet members didn't contain the correct
+ * values. Some thing's broken. */
+#define VERR_RT_REQUEST_INVALID_PACKAGE         (-702)
+/** The status field has not been updated yet as the request is still
+ * pending completion. Someone queried the iStatus field before the request
+ * has been fully processed. */
+#define VERR_RT_REQUEST_STATUS_STILL_PENDING    (-703)
+/** The request has been freed, don't read the status now.
+ * Someone is reading the iStatus field of a freed request packet. */
+#define VERR_RT_REQUEST_STATUS_FREED            (-704)
+/** @} */
+
+/** @name Environment Status Code
+ * @{
+ */
+/** The specified environment variable was not found. (RTEnvGetEx) */
+#define VERR_ENV_VAR_NOT_FOUND                  (-750)
+/** The specified environment variable was not found. (RTEnvUnsetEx) */
+#define VINF_ENV_VAR_NOT_FOUND                  (750)
+/** Unable to translate all the variables in the default environment due to
+ * codeset issues (LANG / LC_ALL / LC_CTYPE). */
+#define VWRN_ENV_NOT_FULLY_TRANSLATED           (751)
+/** Invalid environment variable name. */
+#define VERR_ENV_INVALID_VAR_NAME               (-752)
+/** The environment variable is an unset record. */
+#define VINF_ENV_VAR_UNSET                      (753)
+/** The environment variable has been recorded as being unset. */
+#define VERR_ENV_VAR_UNSET                      (-753)
+/** @} */
+
+/** @name Multiprocessor Status Codes.
+ * @{
+ */
+/** The specified cpu is offline. */
+#define VERR_CPU_OFFLINE                        (-800)
+/** The specified cpu was not found. */
+#define VERR_CPU_NOT_FOUND                      (-801)
+/** Not all of the requested CPUs showed up in the PFNRTMPWORKER. */
+#define VERR_NOT_ALL_CPUS_SHOWED                (-802)
+/** Internal processing error in the RTMp code.*/
+#define VERR_CPU_IPE_1                          (-803)
+/** @} */
+
+/** @name RTGetOpt status codes
+ * @{ */
+/** RTGetOpt: Command line option not recognized. */
+#define VERR_GETOPT_UNKNOWN_OPTION              (-825)
+/** RTGetOpt: Command line option needs argument. */
+#define VERR_GETOPT_REQUIRED_ARGUMENT_MISSING   (-826)
+/** RTGetOpt: Command line option has argument with bad format. */
+#define VERR_GETOPT_INVALID_ARGUMENT_FORMAT     (-827)
+/** RTGetOpt: Not an option. */
+#define VINF_GETOPT_NOT_OPTION                  828
+/** RTGetOpt: Command line option needs an index. */
+#define VERR_GETOPT_INDEX_MISSING               (-829)
+/** @} */
+
+/** @name RTCache status codes
+ * @{ */
+/** RTCache: cache is full. */
+#define VERR_CACHE_FULL                         (-850)
+/** RTCache: cache is empty. */
+#define VERR_CACHE_EMPTY                        (-851)
+/** @} */
+
+/** @name RTMemCache status codes
+ * @{ */
+/** Reached the max cache size. */
+#define VERR_MEM_CACHE_MAX_SIZE                 (-855)
+/** @} */
+
+/** @name RTS3 status codes
+ * @{ */
+/** Access denied error. */
+#define VERR_S3_ACCESS_DENIED                   (-875)
+/** The bucket/key wasn't found. */
+#define VERR_S3_NOT_FOUND                       (-876)
+/** Bucket already exists. */
+#define VERR_S3_BUCKET_ALREADY_EXISTS           (-877)
+/** Can't delete bucket with keys. */
+#define VERR_S3_BUCKET_NOT_EMPTY                (-878)
+/** The current operation was canceled. */
+#define VERR_S3_CANCELED                        (-879)
+/** @} */
+
+/** @name HTTP status codes
+ * @{ */
+/** HTTP initialization failed. */
+#define VERR_HTTP_INIT_FAILED                   (-885)
+/** The server has not found anything matching the URI given. */
+#define VERR_HTTP_NOT_FOUND                     (-886)
+/** The request is for something forbidden. Authorization will not help. */
+#define VERR_HTTP_ACCESS_DENIED                 (-887)
+/** The server did not understand the request due to bad syntax. */
+#define VERR_HTTP_BAD_REQUEST                   (-888)
+/** Couldn't connect to the server (proxy?). */
+#define VERR_HTTP_COULDNT_CONNECT               (-889)
+/** SSL connection error. */
+#define VERR_HTTP_SSL_CONNECT_ERROR             (-890)
+/** CAcert is missing or has the wrong format. */
+#define VERR_HTTP_CACERT_WRONG_FORMAT           (-891)
+/** Certificate cannot be authenticated with the given CA certificates. */
+#define VERR_HTTP_CACERT_CANNOT_AUTHENTICATE    (-892)
+/** The current HTTP request was forcefully aborted */
+#define VERR_HTTP_ABORTED                       (-893)
+/** Request was redirected. */
+#define VERR_HTTP_REDIRECTED                    (-894)
+/** Proxy couldn't be resolved. */
+#define VERR_HTTP_PROXY_NOT_FOUND               (-895)
+/** The remote host couldn't be resolved. */
+#define VERR_HTTP_HOST_NOT_FOUND                (-896)
+/** Unexpected cURL error configure the proxy. */
+#define VERR_HTTP_CURL_PROXY_CONFIG             (-897)
+/** Generic CURL error. */
+#define VERR_HTTP_CURL_ERROR                    (-899)
+/** @} */
+
+/** @name RTManifest status codes
+ * @{ */
+/** A digest type used in the manifest file isn't supported. */
+#define VERR_MANIFEST_UNSUPPORTED_DIGEST_TYPE   (-900)
+/** An entry in the manifest file couldn't be interpreted correctly. */
+#define VERR_MANIFEST_WRONG_FILE_FORMAT         (-901)
+/** A digest doesn't match the corresponding file. */
+#define VERR_MANIFEST_DIGEST_MISMATCH           (-902)
+/** The file list doesn't match to the content of the manifest file. */
+#define VERR_MANIFEST_FILE_MISMATCH             (-903)
+/** The specified attribute (name) was not found in the manifest.  */
+#define VERR_MANIFEST_ATTR_NOT_FOUND            (-904)
+/** The attribute type did not match. */
+#define VERR_MANIFEST_ATTR_TYPE_MISMATCH        (-905)
+/** No attribute of the specified types was found. */
+#define VERR_MANIFEST_ATTR_TYPE_NOT_FOUND        (-906)
+/** @} */
+
+/** @name RTTar status codes
+ * @{ */
+/** The checksum of a tar header record doesn't match. */
+#define VERR_TAR_CHKSUM_MISMATCH                (-925)
+/** The tar end of file record was read. */
+#define VERR_TAR_END_OF_FILE                    (-926)
+/** The tar file ended unexpectedly. */
+#define VERR_TAR_UNEXPECTED_EOS                 (-927)
+/** The tar termination records was encountered without reaching the end of
+  * the input stream. */
+#define VERR_TAR_EOS_MORE_INPUT                 (-928)
+/** A number tar header field was malformed.  */
+#define VERR_TAR_BAD_NUM_FIELD                  (-929)
+/** A numeric tar header field was not terminated correctly. */
+#define VERR_TAR_BAD_NUM_FIELD_TERM             (-930)
+/** A number tar header field was encoded using base-256 which this
+ * tar implementation currently does not support.  */
+#define VERR_TAR_BASE_256_NOT_SUPPORTED         (-931)
+/** A number tar header field yielded a value too large for the internal
+ * variable of the tar interpreter. */
+#define VERR_TAR_NUM_VALUE_TOO_LARGE            (-932)
+/** The combined minor and major device number type is too small to hold the
+ * value stored in the tar header.  */
+#define VERR_TAR_DEV_VALUE_TOO_LARGE            (-933)
+/** The mode field in a tar header is bad. */
+#define VERR_TAR_BAD_MODE_FIELD                 (-934)
+/** The mode field should not include the type. */
+#define VERR_TAR_MODE_WITH_TYPE                 (-935)
+/** The size field should be zero for links and symlinks. */
+#define VERR_TAR_SIZE_NOT_ZERO                  (-936)
+/** Encountered an unknown type flag. */
+#define VERR_TAR_UNKNOWN_TYPE_FLAG              (-937)
+/** The tar header is all zeros. */
+#define VERR_TAR_ZERO_HEADER                    (-938)
+/** Not a uniform standard tape v0.0 archive header. */
+#define VERR_TAR_NOT_USTAR_V00                  (-939)
+/** The name is empty. */
+#define VERR_TAR_EMPTY_NAME                     (-940)
+/** A non-directory entry has a name ending with a slash. */
+#define VERR_TAR_NON_DIR_ENDS_WITH_SLASH        (-941)
+/** Encountered an unsupported portable archive exchange (pax) header. */
+#define VERR_TAR_UNSUPPORTED_PAX_TYPE           (-942)
+/** Encountered an unsupported Solaris Tar extension. */
+#define VERR_TAR_UNSUPPORTED_SOLARIS_HDR_TYPE   (-943)
+/** Encountered an unsupported GNU Tar extension. */
+#define VERR_TAR_UNSUPPORTED_GNU_HDR_TYPE       (-944)
+/** Malformed checksum field in the tar header. */
+#define VERR_TAR_BAD_CHKSUM_FIELD               (-945)
+/** Malformed checksum field in the tar header. */
+#define VERR_TAR_MALFORMED_GNU_LONGXXXX         (-946)
+/** Too long name or link string. */
+#define VERR_TAR_NAME_TOO_LONG                  (-947)
+/** A directory entry in the archive. */
+#define VINF_TAR_DIR_PATH                        (948)
+/** @} */
+
+/** @name RTPoll status codes
+ * @{ */
+/** The handle is not pollable. */
+#define VERR_POLL_HANDLE_NOT_POLLABLE           (-950)
+/** The handle ID is already present in the poll set. */
+#define VERR_POLL_HANDLE_ID_EXISTS              (-951)
+/** The handle ID was not found in the set. */
+#define VERR_POLL_HANDLE_ID_NOT_FOUND           (-952)
+/** The poll set is full. */
+#define VERR_POLL_SET_IS_FULL                   (-953)
+/** @} */
+
+/** @name Pkzip status codes
+ * @{ */
+/** No end of central directory record found. */
+#define VERR_PKZIP_NO_EOCB                      (-960)
+/** Too long name string. */
+#define VERR_PKZIP_NAME_TOO_LONG                (-961)
+/** Local file header corrupt. */
+#define VERR_PKZIP_BAD_LF_HEADER                (-962)
+/** Central directory file header corrupt. */
+#define VERR_PKZIP_BAD_CDF_HEADER               (-963)
+/** Encountered an unknown type flag. */
+#define VERR_PKZIP_UNKNOWN_TYPE_FLAG            (-964)
+/** Found a ZIP64 Extra Information Field in a ZIP32 file. */
+#define VERR_PKZIP_ZIP64EX_IN_ZIP32             (-965)
+
+
+/** @name RTZip status codes
+ * @{ */
+/** Generic zip error. */
+#define VERR_ZIP_ERROR                          (-22000)
+/** The compressed data was corrupted. */
+#define VERR_ZIP_CORRUPTED                      (-22001)
+/** Ran out of memory while compressing or uncompressing. */
+#define VERR_ZIP_NO_MEMORY                      (-22002)
+/** The compression format version is unsupported. */
+#define VERR_ZIP_UNSUPPORTED_VERSION            (-22003)
+/** The compression method is unsupported. */
+#define VERR_ZIP_UNSUPPORTED_METHOD             (-22004)
+/** The compressed data started with a bad header. */
+#define VERR_ZIP_BAD_HEADER                     (-22005)
+/** @} */
+
+/** @name RTVfs status codes
+ * @{ */
+/** The VFS chain specification does not have a valid prefix. */
+#define VERR_VFS_CHAIN_NO_PREFIX                    (-22100)
+/** The VFS chain specification is empty. */
+#define VERR_VFS_CHAIN_EMPTY                        (-22101)
+/** Expected an element. */
+#define VERR_VFS_CHAIN_EXPECTED_ELEMENT             (-22102)
+/** The VFS object type is not known. */
+#define VERR_VFS_CHAIN_UNKNOWN_TYPE                 (-22103)
+/** Expected a left parentheses. */
+#define VERR_VFS_CHAIN_EXPECTED_LEFT_PARENTHESES    (-22104)
+/** Expected a right parentheses. */
+#define VERR_VFS_CHAIN_EXPECTED_RIGHT_PARENTHESES   (-22105)
+/** Expected a provider name. */
+#define VERR_VFS_CHAIN_EXPECTED_PROVIDER_NAME       (-22106)
+/** Expected an action (> or |). */
+#define VERR_VFS_CHAIN_EXPECTED_ACTION              (-22107)
+/** Only one action element is currently supported. */
+#define VERR_VFS_CHAIN_MULTIPLE_ACTIONS             (-22108)
+/** Expected to find a driving action (>), but there is none. */
+#define VERR_VFS_CHAIN_NO_ACTION                    (-22109)
+/** Expected pipe action. */
+#define VERR_VFS_CHAIN_EXPECTED_PIPE                (-22110)
+/** Unexpected action type. */
+#define VERR_VFS_CHAIN_UNEXPECTED_ACTION_TYPE       (-22111)
+/** @} */
+
+/** @name RTDvm status codes
+ * @{ */
+/** The volume map doesn't contain any valid volume. */
+#define VERR_DVM_MAP_EMPTY                          (-22200)
+/** There is no volume behind the current one. */
+#define VERR_DVM_MAP_NO_VOLUME                      (-22201)
+/** @} */
+
+/** @name Logger status codes
+ * @{ */
+/** The internal logger revision did not match. */
+#define VERR_LOG_REVISION_MISMATCH                  (-22300)
+/** @} */
+
+/* see above, 22400..22499 is used for misc codes! */
+
+/** @name Logger status codes
+ * @{ */
+/** Power off is not supported by the hardware or the OS. */
+#define VERR_SYS_CANNOT_POWER_OFF                   (-22500)
+/** The halt action was requested, but the OS may actually power
+ * off the machine. */
+#define VINF_SYS_MAY_POWER_OFF                      (22501)
+/** Shutdown failed. */
+#define VERR_SYS_SHUTDOWN_FAILED                    (-22502)
+/** @} */
+
+/** @name Filesystem status codes
+ * @{ */
+/** Filesystem can't be opened because it is corrupt. */
+#define VERR_FILESYSTEM_CORRUPT                     (-22600)
+/** @} */
+
+/** @name RTZipXar status codes.
+ * @{ */
+/** Wrong magic value. */
+#define VERR_XAR_WRONG_MAGIC                        (-22700)
+/** Bad header size. */
+#define VERR_XAR_BAD_HDR_SIZE                       (-22701)
+/** Unsupported version. */
+#define VERR_XAR_UNSUPPORTED_VERSION                (-22702)
+/** Unsupported hashing function. */
+#define VERR_XAR_UNSUPPORTED_HASH_FUNCTION          (-22703)
+/** The table of content (TOC) is too small and therefore can't be valid. */
+#define VERR_XAR_TOC_TOO_SMALL                      (-22704)
+/** The table of content (TOC) is too big. */
+#define VERR_XAR_TOC_TOO_BIG                        (-22705)
+/** The compressed table of content is too big. */
+#define VERR_XAR_TOC_TOO_BIG_COMPRESSED             (-22706)
+/** The uncompressed table of content size in the header didn't match what
+ * ZLib returned. */
+#define VERR_XAR_TOC_UNCOMP_SIZE_MISMATCH           (-22707)
+/** The table of content string length didn't match the size specified in the
+ *  header. */
+#define VERR_XAR_TOC_STRLEN_MISMATCH                (-22708)
+/** The table of content isn't valid UTF-8. */
+#define VERR_XAR_TOC_UTF8_ENCODING                  (-22709)
+/** XML error while parsing the table of content. */
+#define VERR_XAR_TOC_XML_PARSE_ERROR                (-22710)
+/** The table of content XML document does not have a toc element. */
+#define VERR_XML_TOC_ELEMENT_MISSING                (-22711)
+/** The table of content XML element (toc) has siblings, we expected it to be
+ *  an only child or the root element (xar). */
+#define VERR_XML_TOC_ELEMENT_HAS_SIBLINGS           (-22712)
+/** The XAR table of content digest doesn't match. */
+#define VERR_XAR_TOC_DIGEST_MISMATCH                (-22713)
+/** Bad or missing XAR checksum element. */
+#define VERR_XAR_BAD_CHECKSUM_ELEMENT               (-22714)
+/** The hash function in the header doesn't match the one in the table of
+ *  content. */
+#define VERR_XAR_HASH_FUNCTION_MISMATCH             (-22715)
+/** Bad digest length encountered in the table of content.  */
+#define VERR_XAR_BAD_DIGEST_LENGTH                  (-22716)
+/** The order of elements in the XAR file does not lend it self to expansion
+ *  from via an I/O stream. */
+#define VERR_XAR_NOT_STREAMBLE_ELEMENT_ORDER        (-22717)
+/** Missing offset element in table of content sub-element. */
+#define VERR_XAR_MISSING_OFFSET_ELEMENT             (-22718)
+/** Bad offset element in table of content sub-element. */
+#define VERR_XAR_BAD_OFFSET_ELEMENT                 (-22719)
+/** Missing size element in table of content sub-element. */
+#define VERR_XAR_MISSING_SIZE_ELEMENT               (-22720)
+/** Bad size element in table of content sub-element. */
+#define VERR_XAR_BAD_SIZE_ELEMENT                   (-22721)
+/** Missing length element in table of content sub-element. */
+#define VERR_XAR_MISSING_LENGTH_ELEMENT             (-22722)
+/** Bad length element in table of content sub-element. */
+#define VERR_XAR_BAD_LENGTH_ELEMENT                 (-22723)
+/** Bad file element in XAR table of content. */
+#define VERR_XAR_BAD_FILE_ELEMENT                   (-22724)
+/** Missing data element for XAR file. */
+#define VERR_XAR_MISSING_DATA_ELEMENT               (-22725)
+/** Unknown XAR file type value. */
+#define VERR_XAR_UNKNOWN_FILE_TYPE                  (-22726)
+/** Missing encoding element for XAR data stream. */
+#define VERR_XAR_NO_ENCODING                        (-22727)
+/** Bad timestamp for XAR file. */
+#define VERR_XAR_BAD_FILE_TIMESTAMP                 (-22728)
+/** Bad file mode for XAR file. */
+#define VERR_XAR_BAD_FILE_MODE                      (-22729)
+/** Bad file user id for XAR file. */
+#define VERR_XAR_BAD_FILE_UID                       (-22730)
+/** Bad file group id for XAR file. */
+#define VERR_XAR_BAD_FILE_GID                       (-22731)
+/** Bad file inode device number for XAR file. */
+#define VERR_XAR_BAD_FILE_DEVICE_NO                 (-22732)
+/** Bad file inode number for XAR file. */
+#define VERR_XAR_BAD_FILE_INODE                     (-22733)
+/** Invalid name for XAR file. */
+#define VERR_XAR_INVALID_FILE_NAME                  (-22734)
+/** The message digest of the extracted data does not match the one supplied. */
+#define VERR_XAR_EXTRACTED_HASH_MISMATCH            (-22735)
+/** The extracted data has exceeded the expected size. */
+#define VERR_XAR_EXTRACTED_SIZE_EXCEEDED            (-22736)
+/** The message digest of the archived data does not match the one supplied. */
+#define VERR_XAR_ARCHIVED_HASH_MISMATCH             (-22737)
+/** The decompressor completed without using all the input data. */
+#define VERR_XAR_UNUSED_ARCHIVED_DATA               (-22738)
+/** Expected the archived and extracted XAR data sizes to be the same for
+ * uncompressed data. */
+#define VERR_XAR_ARCHIVED_AND_EXTRACTED_SIZES_MISMATCH (-22739)
+/** @} */
+
+/** @name RTX509 status codes
+ * @{ */
+/** Error reading a certificate in PEM format from BIO. */
+#define VERR_X509_READING_CERT_FROM_BIO                  (-23100)
+/** Error extracting a public key from the certificate. */
+#define VERR_X509_EXTRACT_PUBKEY_FROM_CERT               (-23101)
+/** Error extracting RSA from the public key. */
+#define VERR_X509_EXTRACT_RSA_FROM_PUBLIC_KEY            (-23102)
+/** Signature verification failed. */
+#define VERR_X509_RSA_VERIFICATION_FUILURE               (-23103)
+/** Basic constraints were not found. */
+#define VERR_X509_NO_BASIC_CONSTARAINTS                  (-23104)
+/** Error getting extensions from the certificate. */
+#define VERR_X509_GETTING_EXTENSION_FROM_CERT            (-23105)
+/** Error getting a data from the extension. */
+#define VERR_X509_GETTING_DATA_FROM_EXTENSION            (-23106)
+/** Error formatting an extension. */
+#define VERR_X509_PRINT_EXTENSION_TO_BIO                 (-23107)
+/** X509 certificate verification error. */
+#define VERR_X509_CERTIFICATE_VERIFICATION_FAILURE       (-23108)
+/** X509 certificate isn't self signed. */
+#define VERR_X509_NOT_SELFSIGNED_CERTIFICATE             (-23109)
+/** Warning X509 certificate isn't self signed.  */
+#define VINF_X509_NOT_SELFSIGNED_CERTIFICATE             23109
+/** @} */
+
+/** @name RTAsn1 status codes
+ * @{ */
+/** Temporary place holder.  */
+#define VERR_ASN1_ERROR                             (-22800)
+/** Encountered an ASN.1 string type that is not supported. */
+#define VERR_ASN1_STRING_TYPE_NOT_IMPLEMENTED       (-22801)
+/** Invalid ASN.1 UTF-8 STRING encoding. */
+#define VERR_ASN1_INVALID_UTF8_STRING_ENCODING      (-22802)
+/** Invalid ASN.1 NUMERIC STRING encoding. */
+#define VERR_ASN1_INVALID_NUMERIC_STRING_ENCODING   (-22803)
+/** Invalid ASN.1 PRINTABLE STRING encoding. */
+#define VERR_ASN1_INVALID_PRINTABLE_STRING_ENCODING (-22804)
+/** Invalid ASN.1 T61/TELETEX STRING encoding. */
+#define VERR_ASN1_INVALID_T61_STRING_ENCODING       (-22805)
+/** Invalid ASN.1 VIDEOTEX STRING encoding. */
+#define VERR_ASN1_INVALID_VIDEOTEX_STRING_ENCODING  (-22806)
+/** Invalid ASN.1 IA5 STRING encoding. */
+#define VERR_ASN1_INVALID_IA5_STRING_ENCODING       (-22807)
+/** Invalid ASN.1 GRAPHIC STRING encoding. */
+#define VERR_ASN1_INVALID_GRAPHIC_STRING_ENCODING   (-22808)
+/** Invalid ASN.1 ISO-646/VISIBLE STRING encoding. */
+#define VERR_ASN1_INVALID_VISIBLE_STRING_ENCODING   (-22809)
+/** Invalid ASN.1 GENERAL STRING encoding. */
+#define VERR_ASN1_INVALID_GENERAL_STRING_ENCODING   (-22810)
+/** Invalid ASN.1 UNIVERSAL STRING encoding. */
+#define VERR_ASN1_INVALID_UNIVERSAL_STRING_ENCODING (-22811)
+/** Invalid ASN.1 BMP STRING encoding. */
+#define VERR_ASN1_INVALID_BMP_STRING_ENCODING       (-22812)
+/** Invalid ASN.1 OBJECT IDENTIFIER encoding. */
+#define VERR_ASN1_INVALID_OBJID_ENCODING            (-22813)
+/** A component value of an ASN.1 OBJECT IDENTIFIER is too big for our
+ * internal representation (32-bits). */
+#define VERR_ASN1_OBJID_COMPONENT_TOO_BIG           (-22814)
+/** Too many components in an ASN.1 OBJECT IDENTIFIER for our internal
+ * representation. */
+#define VERR_ASN1_OBJID_TOO_MANY_COMPONENTS         (-22815)
+/** The dotted-string representation of an ASN.1 OBJECT IDENTIFIER would be too
+ * long for our internal representation. */
+#define VERR_ASN1_OBJID_TOO_LONG_STRING_FORM        (-22816)
+/** Invalid dotted string. */
+#define VERR_ASN1_OBJID_INVALID_DOTTED_STRING       (-22817)
+/** Constructed string type not implemented. */
+#define VERR_ASN1_CONSTRUCTED_STRING_NOT_IMPL       (-22818)
+/** Expected a different string tag. */
+#define VERR_ASN1_STRING_TAG_MISMATCH               (-22819)
+/** Expected a different time tag. */
+#define VERR_ASN1_TIME_TAG_MISMATCH                 (-22820)
+/** More unconsumed data available. */
+#define VINF_ASN1_MORE_DATA                         (22821)
+/** RTAsnEncodeWriteHeader return code indicating that nothing was written
+ *  and the content should be skipped as well. */
+#define VINF_ASN1_NOT_ENCODED                       (22822)
+/** Unknown escape sequence encountered in TeletexString. */
+#define VERR_ASN1_TELETEX_UNKNOWN_ESC_SEQ           (-22823)
+/** Unsupported escape sequence encountered in TeletexString. */
+#define VERR_ASN1_TELETEX_UNSUPPORTED_ESC_SEQ       (-22824)
+/** Unsupported character set. */
+#define VERR_ASN1_TELETEX_UNSUPPORTED_CHARSET       (-22825)
+/** ASN.1 object has no virtual method table. */
+#define VERR_ASN1_NO_VTABLE                         (-22826)
+/** ASN.1 object has no pfnCheckSanity method.  */
+#define VERR_ASN1_NO_CHECK_SANITY_METHOD            (-22827)
+/** ASN.1 object is not present */
+#define VERR_ASN1_NOT_PRESENT                       (-22828)
+/** There are unconsumed bytes after decoding an ASN.1 object. */
+#define VERR_ASN1_CURSOR_NOT_AT_END                 (-22829)
+/** Long ASN.1 tag form is not implemented. */
+#define VERR_ASN1_CURSOR_LONG_TAG                   (-22830)
+/** Bad ASN.1 object length encoding. */
+#define VERR_ASN1_CURSOR_BAD_LENGTH_ENCODING        (-22831)
+/** Indefinite length form is against the rules. */
+#define VERR_ASN1_CURSOR_ILLEGAL_IDEFINITE_LENGTH   (-22832)
+/** Indefinite length form is not implemented. */
+#define VERR_ASN1_CURSOR_IDEFINITE_LENGTH_NOT_SUP   (-22833)
+/** ASN.1 object length goes beyond the end of the byte stream being decoded. */
+#define VERR_ASN1_CURSOR_BAD_LENGTH                 (-22834)
+/** Not more data in ASN.1 byte stream. */
+#define VERR_ASN1_CURSOR_NO_MORE_DATA               (-22835)
+/** Too little data in ASN.1 byte stream. */
+#define VERR_ASN1_CURSOR_TOO_LITTLE_DATA_LEFT       (-22836)
+/** Constructed string is not according to the encoding rules. */
+#define VERR_ASN1_CURSOR_ILLEGAL_CONSTRUCTED_STRING (-22837)
+/** Unexpected ASN.1 tag encountered while decoding. */
+#define VERR_ASN1_CURSOR_TAG_MISMATCH               (-22838)
+/** Unexpected ASN.1 tag class/flag encountered while decoding. */
+#define VERR_ASN1_CURSOR_TAG_FLAG_CLASS_MISMATCH    (-22839)
+/** ASN.1 bit string object is out of bounds. */
+#define VERR_ASN1_BITSTRING_OUT_OF_BOUNDS           (-22840)
+/** Bad ASN.1 time object. */
+#define VERR_ASN1_TIME_BAD_NORMALIZE_INPUT          (-22841)
+/** Failed to normalize ASN.1 time object. */
+#define VERR_ASN1_TIME_NORMALIZE_ERROR              (-22842)
+/** Normalization of ASN.1 time object didn't work out. */
+#define VERR_ASN1_TIME_NORMALIZE_MISMATCH           (-22843)
+/** Invalid ASN.1 UTC TIME encoding. */
+#define VERR_ASN1_INVALID_UTC_TIME_ENCODING         (-22844)
+/** Invalid ASN.1 GENERALIZED TIME encoding. */
+#define VERR_ASN1_INVALID_GENERALIZED_TIME_ENCODING (-22845)
+/** Invalid ASN.1 BOOLEAN encoding. */
+#define VERR_ASN1_INVALID_BOOLEAN_ENCODING          (-22846)
+/** Invalid ASN.1 NULL encoding. */
+#define VERR_ASN1_INVALID_NULL_ENCODING             (-22847)
+/** Invalid ASN.1 BIT STRING encoding. */
+#define VERR_ASN1_INVALID_BITSTRING_ENCODING        (-22848)
+/** Unimplemented ASN.1 tag reached the RTAsn1DynType code. */
+#define VERR_ASN1_DYNTYPE_TAG_NOT_IMPL              (-22849)
+/** ASN.1 tag and flags/class mismatch in RTAsn1DynType code. */
+#define VERR_ASN1_DYNTYPE_BAD_TAG                   (-22850)
+/** Unexpected ASN.1 fake/dummy object. */
+#define VERR_ASN1_DUMMY_OBJECT                      (-22851)
+/** ASN.1 object is too long. */
+#define VERR_ASN1_TOO_LONG                          (-22852)
+/** Expected primitive ASN.1 object. */
+#define VERR_ASN1_EXPECTED_PRIMITIVE                (-22853)
+/** Expected valid data pointer for ASN.1 object. */
+#define VERR_ASN1_INVALID_DATA_POINTER              (-22854)
+/** The ASN.1 encoding is too deeply nested for the decoder. */
+#define VERR_ASN1_TOO_DEEPLY_NESTED                 (-22855)
+
+/** ANS.1 internal error 1. */
+#define VERR_ASN1_INTERNAL_ERROR_1                  (-22895)
+/** ANS.1 internal error 2. */
+#define VERR_ASN1_INTERNAL_ERROR_2                  (-22896)
+/** ANS.1 internal error 3. */
+#define VERR_ASN1_INTERNAL_ERROR_3                  (-22897)
+/** ANS.1 internal error 4. */
+#define VERR_ASN1_INTERNAL_ERROR_4                  (-22898)
+/** ANS.1 internal error 5. */
+#define VERR_ASN1_INTERNAL_ERROR_5                  (-22899)
+/** @} */
+
+/** @name More RTLdr status codes.
+ * @{ */
+/** Image Verification Failure: No Authenticode Signature. */
+#define VERR_LDRVI_NOT_SIGNED                       (-22900)
+/** Image Verification Warning: No Authenticode Signature, but on whitelist. */
+#define VINF_LDRVI_NOT_SIGNED                       (22900)
+/** Image Verification Failure: Error reading image headers.  */
+#define VERR_LDRVI_READ_ERROR_HDR                   (-22901)
+/** Image Verification Failure: Error reading section headers. */
+#define VERR_LDRVI_READ_ERROR_SHDRS                 (-22902)
+/** Image Verification Failure: Error reading authenticode signature data. */
+#define VERR_LDRVI_READ_ERROR_SIGNATURE             (-22903)
+/** Image Verification Failure: Error reading file for hashing. */
+#define VERR_LDRVI_READ_ERROR_HASH                  (-22904)
+/** Image Verification Failure: Error determining the file length. */
+#define VERR_LDRVI_FILE_LENGTH_ERROR                (-22905)
+/** Image Verification Failure: Error allocating memory for state data. */
+#define VERR_LDRVI_NO_MEMORY_STATE                  (-22906)
+/** Image Verification Failure: Error allocating memory for authenticode
+ *  signature data. */
+#define VERR_LDRVI_NO_MEMORY_SIGNATURE              (-22907)
+/** Image Verification Failure: Error allocating memory for section headers. */
+#define VERR_LDRVI_NO_MEMORY_SHDRS                  (-22908)
+/** Image Verification Failure: Authenticode parsing output. */
+#define VERR_LDRVI_NO_MEMORY_PARSE_OUTPUT           (-22909)
+/** Image Verification Failure: Invalid security directory entry. */
+#define VERR_LDRVI_INVALID_SECURITY_DIR_ENTRY       (-22910)
+/** Image Verification Failure:  */
+#define VERR_LDRVI_BAD_CERT_HDR_LENGTH              (-22911)
+/** Image Verification Failure:  */
+#define VERR_LDRVI_BAD_CERT_HDR_REVISION            (-22912)
+/** Image Verification Failure:  */
+#define VERR_LDRVI_BAD_CERT_HDR_TYPE                (-22913)
+/** Image Verification Failure: More than one certificate table entry.  */
+#define VERR_LDRVI_BAD_CERT_MULTIPLE                (-22914)
+
+/** Image Verification Failure:  */
+#define VERR_LDRVI_BAD_MZ_OFFSET                    (-22915)
+/** Image Verification Failure: Invalid section count. */
+#define VERR_LDRVI_INVALID_SECTION_COUNT            (-22916)
+/** Image Verification Failure: Raw data offsets and sizes are out of range. */
+#define VERR_LDRVI_SECTION_RAW_DATA_VALUES          (-22917)
+/** Optional header magic and target machine does not match. */
+#define VERR_LDRVI_MACHINE_OPT_HDR_MAGIC_MISMATCH   (-22918)
+/** Unsupported image target architecture. */
+#define VERR_LDRVI_UNSUPPORTED_ARCH                 (-22919)
+
+/** Image Verification Failure: Internal error in signature parser. */
+#define VERR_LDRVI_PARSE_IPE                        (-22921)
+/** Generic BER parse error. Will be refined later. */
+#define VERR_LDRVI_PARSE_BER_ERROR                  (-22922)
+
+/** Expected the signed data content to be the object ID of
+ * SpcIndirectDataContent, found something else instead. */
+#define VERR_LDRVI_EXPECTED_INDIRECT_DATA_CONTENT_OID (-22923)
+/** Page hash table size overflow. */
+#define VERR_LDRVI_PAGE_HASH_TAB_SIZE_OVERFLOW      (-22924)
+/** Page hash table is too long (covers signature data, i.e. itself). */
+#define VERR_LDRVI_PAGE_HASH_TAB_TOO_LONG           (-22925)
+/** The page hash table is not strictly ordered by offset. */
+#define VERR_LDRVI_PAGE_HASH_TAB_NOT_STRICTLY_SORTED (-22926)
+/** The page hash table hashes data outside the defined and implicit sections. */
+#define VERR_PAGE_HASH_TAB_HASHES_NON_SECTION_DATA  (-22927)
+/** Page hash mismatch. */
+#define VERR_LDRVI_PAGE_HASH_MISMATCH               (-22928)
+/** Image hash mismatch. */
+#define VERR_LDRVI_IMAGE_HASH_MISMATCH              (-22929)
+
+/** Cannot resolve symbol because it's a forwarder. */
+#define VERR_LDR_FORWARDER                          (-22950)
+/** The symbol is not a forwarder. */
+#define VERR_LDR_NOT_FORWARDER                      (-22951)
+/** Malformed forwarder entry. */
+#define VERR_LDR_BAD_FORWARDER                      (-22952)
+/** Too long forwarder chain or there is a loop. */
+#define VERR_LDR_FORWARDER_CHAIN_TOO_LONG           (-22953)
+/** Support for forwarders has not been implemented. */
+#define VERR_LDR_FORWARDERS_NOT_SUPPORTED           (-22954)
+/** @} */
+
+/** @name RTCrX509 status codes.
+ * @{ */
+/** Generic X.509 error. */
+#define VERR_CR_X509_GENERIC_ERROR                  (-23000)
+/** Internal error in the X.509 code. */
+#define VERR_CR_X509_INTERNAL_ERROR                 (-23001)
+/** Internal error in the X.509 certificate path building and verification
+ * code. */
+#define VERR_CR_X509_CERTPATHS_INTERNAL_ERROR       (-23002)
+/** Path not verified yet. */
+#define VERR_CR_X509_NOT_VERIFIED                   (-23003)
+/** The certificate path has no trust anchor. */
+#define VERR_CR_X509_NO_TRUST_ANCHOR                (-23004)
+/** Unknown X.509 certificate signature algorithm. */
+#define VERR_CR_X509_UNKNOWN_CERT_SIGN_ALGO         (-23005)
+/** Certificate signature algorithm mismatch. */
+#define VERR_CR_X509_CERT_SIGN_ALGO_MISMATCH        (-23006)
+/** The signature algorithm in the to-be-signed certificate part does not match
+ * the one associated with the signature. */
+#define VERR_CR_X509_CERT_TBS_SIGN_ALGO_MISMATCH    (-23007)
+/** Certificate extensions requires certificate version 3 or later.  */
+#define VERR_CR_X509_TBSCERT_EXTS_REQ_V3            (-23008)
+/** Unique issuer and subject IDs require version certificate 2. */
+#define VERR_CR_X509_TBSCERT_UNIQUE_IDS_REQ_V2      (-23009)
+/** Certificate serial number length is out of bounds. */
+#define VERR_CR_X509_TBSCERT_SERIAL_NUMBER_OUT_OF_BOUNDS (-23010)
+/** Unsupported X.509 certificate version. */
+#define VERR_CR_X509_TBSCERT_UNSUPPORTED_VERSION    (-23011)
+/** Public key is too small. */
+#define VERR_CR_X509_PUBLIC_KEY_TOO_SMALL           (-23012)
+/** Invalid string tag for a X.509 name object. */
+#define VERR_CR_X509_INVALID_NAME_STRING_TAG        (-23013)
+/** Empty string in X.509 name object. */
+#define VERR_CR_X509_NAME_EMPTY_STRING              (-23014)
+/** Non-string object inside X.509 name object. */
+#define VERR_CR_X509_NAME_NOT_STRING                (-23015)
+/** Empty set inside X.509 name. */
+#define VERR_CR_X509_NAME_EMPTY_SET                 (-23016)
+/** Empty sub-string set inside X.509 name. */
+#define VERR_CR_X509_NAME_EMPTY_SUB_SET             (-23017)
+/** The NotBefore and NotAfter values of an X.509 Validity object seems to
+ * have been swapped around. */
+#define VERR_CR_X509_VALIDITY_SWAPPED               (-23018)
+/** Duplicate certificate extension. */
+#define VERR_CR_X509_TBSCERT_DUPLICATE_EXTENSION    (-23019)
+/** Missing relative distinguished name map entry. */
+#define VERR_CR_X509_NAME_MISSING_RDN_MAP_ENTRY     (-23020)
+/** Certificate path validator: No trusted certificate paths. */
+#define VERR_CR_X509_CPV_NO_TRUSTED_PATHS           (-23021)
+/** Certificate path validator: No valid certificate policy. */
+#define VERR_CR_X509_CPV_NO_VALID_POLICY            (-23022)
+/** Certificate path validator: Unknown critical certificate extension. */
+#define VERR_CR_X509_CPV_UNKNOWN_CRITICAL_EXTENSION (-23023)
+/** Certificate path validator: Intermediate certificate is missing the
+ *  KeyCertSign usage flag. */
+#define VERR_CR_X509_CPV_MISSING_KEY_CERT_SIGN      (-23024)
+/** Certificate path validator: Hit the max certificate path length before
+ *  reaching trust anchor. */
+#define VERR_CR_X509_CPV_MAX_PATH_LENGTH            (-23025)
+/** Certificate path validator: Intermediate certificate is not marked as a
+ *  certificate authority (CA). */
+#define VERR_CR_X509_CPV_NOT_CA_CERT                (-23026)
+/** Certificate path validator: Intermediate certificate is not a version 3
+ *  certificate. */
+#define VERR_CR_X509_CPV_NOT_V3_CERT                (-23027)
+/** Certificate path validator: Invalid policy mapping (to/from anyPolicy). */
+#define VERR_CR_X509_CPV_INVALID_POLICY_MAPPING     (-23028)
+/** Certificate path validator: Name constraints permits no names. */
+#define VERR_CR_X509_CPV_NO_PERMITTED_NAMES         (-23029)
+/** Certificate path validator: Name constraints does not permits the
+ *  certificate name. */
+#define VERR_CR_X509_CPV_NAME_NOT_PERMITTED         (-23030)
+/** Certificate path validator: Name constraints does not permits the
+ *  alternative certificate name. */
+#define VERR_CR_X509_CPV_ALT_NAME_NOT_PERMITTED     (-23031)
+/** Certificate path validator: Intermediate certificate subject does not
+ *  match child issuer property. */
+#define VERR_CR_X509_CPV_ISSUER_MISMATCH            (-23032)
+/** Certificate path validator: The certificate is not valid at the
+ *  specified time. */
+#define VERR_CR_X509_CPV_NOT_VALID_AT_TIME          (-23033)
+/** Certificate path validator: Unexpected choice found in general subtree
+ *  object (name constraints). */
+#define VERR_CR_X509_CPV_UNEXP_GENERAL_SUBTREE_CHOICE (-23034)
+/** Certificate path validator: Unexpected minimum value found in general
+ *  subtree object (name constraints). */
+#define VERR_CR_X509_CPV_UNEXP_GENERAL_SUBTREE_MIN  (-23035)
+/** Certificate path validator: Unexpected maximum value found in
+ *  general subtree object (name constraints). */
+#define VERR_CR_X509_CPV_UNEXP_GENERAL_SUBTREE_MAX  (-23036)
+/** Certificate path builder: Encountered bad certificate context. */
+#define VERR_CR_X509_CPB_BAD_CERT_CTX               (-23037)
+/** OpenSSL d2i_X509 failed. */
+#define VERR_CR_X509_OSSL_D2I_FAILED                (-23090)
+/** @} */
+
+/** @name RTCrPkcs7 status codes.
+ * @{ */
+/** Generic PKCS \#7 error. */
+#define VERR_CR_PKCS7_GENERIC_ERROR                             (-23300)
+/** Signed data verification failed because there are zero signer infos. */
+#define VERR_CR_PKCS7_NO_SIGNER_INFOS                           (-23301)
+/** Signed data certificate not found. */
+#define VERR_CR_PKCS7_SIGNED_DATA_CERT_NOT_FOUND                (-23302)
+/** Signed data verification failed due to key usage issues. */
+#define VERR_CR_PKCS7_KEY_USAGE_MISMATCH                        (-23303)
+/** Signed data verification failed because of missing (or duplicate)
+ * authenticated content-type attribute. */
+#define VERR_CR_PKCS7_MISSING_CONTENT_TYPE_ATTRIB               (-23304)
+/** Signed data verification failed because of the authenticated content-type
+ *  attribute did not match. */
+#define VERR_CR_PKCS7_CONTENT_TYPE_ATTRIB_MISMATCH              (-23305)
+/** Signed data verification failed because of a malformed authenticated
+ *  content-type attribute. */
+#define VERR_CR_PKCS7_BAD_CONTENT_TYPE_ATTRIB                   (-23306)
+/** Signed data verification failed because of missing (or duplicate)
+ * authenticated message-digest attribute. */
+#define VERR_CR_PKCS7_MISSING_MESSAGE_DIGEST_ATTRIB             (-23307)
+/** Signed data verification failed because the authenticated message-digest
+ *  attribute did not match. */
+#define VERR_CR_PKCS7_MESSAGE_DIGEST_ATTRIB_MISMATCH            (-23308)
+/** Signed data verification failed because of a malformed authenticated
+ *  message-digest attribute. */
+#define VERR_CR_PKCS7_BAD_MESSAGE_DIGEST_ATTRIB                 (-23309)
+/** Signature verification failed. */
+#define VERR_CR_PKCS7_SIGNATURE_VERIFICATION_FAILED             (-23310)
+/** Internal PKCS \#7 error. */
+#define VERR_CR_PKCS7_INTERNAL_ERROR                            (-22311)
+/** OpenSSL d2i_PKCS7 failed. */
+#define VERR_CR_PKCS7_OSSL_D2I_FAILED                           (-22312)
+/** OpenSSL PKCS \#7 verification failed. */
+#define VERR_CR_PKCS7_OSSL_VERIFY_FAILED                        (-22313)
+/** Digest algorithm parameters are not supported by the PKCS \#7 code. */
+#define VERR_CR_PKCS7_DIGEST_PARAMS_NOT_IMPL                    (-22314)
+/** The digest algorithm of a signer info entry was not found in the list of
+ *  digest algorithms in the signed data. */
+#define VERR_CR_PKCS7_DIGEST_ALGO_NOT_FOUND_IN_LIST             (-22315)
+/** The PKCS \#7 content is not signed data. */
+#define VERR_CR_PKCS7_NOT_SIGNED_DATA                           (-22316)
+/** No digest algorithms listed in PKCS \#7 signed data. */
+#define VERR_CR_PKCS7_NO_DIGEST_ALGORITHMS                      (-22317)
+/** Too many digest algorithms used by PKCS \#7 signed data.  This is an
+ * internal limitation of the code that aims at saving kernel stack space. */
+#define VERR_CR_PKCS7_TOO_MANY_DIGEST_ALGORITHMS                (-22318)
+/** Error creating digest algorithm calculator. */
+#define VERR_CR_PKCS7_DIGEST_CREATE_ERROR                       (-22319)
+/** Error while calculating a digest for a PKCS \#7 verification operation. */
+#define VERR_CR_PKCS7_DIGEST_CALC_ERROR                         (-22320)
+/** Unsupported PKCS \#7 signed data version. */
+#define VERR_CR_PKCS7_SIGNED_DATA_VERSION                       (-22350)
+/** PKCS \#7 signed data has no digest algorithms listed. */
+#define VERR_CR_PKCS7_SIGNED_DATA_NO_DIGEST_ALGOS               (-22351)
+/** Unknown digest algorithm used by PKCS \#7 object. */
+#define VERR_CR_PKCS7_UNKNOWN_DIGEST_ALGORITHM                  (-22352)
+/** Expected PKCS \#7 object to ship at least one certificate. */
+#define VERR_CR_PKCS7_NO_CERTIFICATES                           (-22353)
+/** Expected PKCS \#7 object to not contain any CRLs. */
+#define VERR_CR_PKCS7_EXPECTED_NO_CRLS                          (-22354)
+/** Expected PKCS \#7 object to contain exactly on signer info entry. */
+#define VERR_CR_PKCS7_EXPECTED_ONE_SIGNER_INFO                  (-22355)
+/** Unsupported PKCS \#7 signer info version. */
+#define VERR_CR_PKCS7_SIGNER_INFO_VERSION                       (-22356)
+/** PKCS \#7 singer info contains no issuer serial number. */
+#define VERR_CR_PKCS7_SIGNER_INFO_NO_ISSUER_SERIAL_NO           (-22357)
+/** Expected PKCS \#7 object to ship the signer certificate(s). */
+#define VERR_CR_PKCS7_SIGNER_CERT_NOT_SHIPPED                   (-22358)
+/** The encrypted digest algorithm does not match the one in the certificate. */
+#define VERR_CR_PKCS7_SIGNER_INFO_DIGEST_ENCRYPT_MISMATCH       (-22359)
+/** @} */
+
+/** @name RTCrSpc status codes.
+ * @{ */
+/** Generic SPC error. */
+#define VERR_CR_SPC_GENERIC_ERROR                               (-23400)
+/** SPC requires there to be exactly one SignerInfo entry. */
+#define VERR_CR_SPC_NOT_EXACTLY_ONE_SIGNER_INFOS                (-23401)
+/** There shall be exactly one digest algorithm to go with the single
+ *  SingerInfo entry required by SPC. */
+#define VERR_CR_SPC_NOT_EXACTLY_ONE_DIGEST_ALGO                 (-23402)
+/** The digest algorithm in the SignerInfo does not match the one in the
+ *  indirect data. */
+#define VERR_CR_SPC_SIGNED_IND_DATA_DIGEST_ALGO_MISMATCH        (-23403)
+/** The digest algorithm in the indirect data was not found in the list of
+ * digest algorithms in the signed data structure. */
+#define VERR_CR_SPC_IND_DATA_DIGEST_ALGO_NOT_IN_DIGEST_ALGOS    (-23404)
+/** The digest algorithm is not known to us. */
+#define VERR_CR_SPC_UNKNOWN_DIGEST_ALGO                         (-23405)
+/** The indirect data digest size does not match the digest algorithm. */
+#define VERR_CR_SPC_IND_DATA_DIGEST_SIZE_MISMATCH               (-23406)
+/** Expected PE image data inside indirect data object. */
+#define VERR_CR_SPC_EXPECTED_PE_IMAGE_DATA                      (-23407)
+/** Internal SPC error: The PE image data is missing.  */
+#define VERR_CR_SPC_PEIMAGE_DATA_NOT_PRESENT                    (-23408)
+/** Bad SPC object moniker UUID field. */
+#define VERR_CR_SPC_BAD_MONIKER_UUID                            (-23409)
+/** Unknown SPC object moniker UUID. */
+#define VERR_CR_SPC_UNKNOWN_MONIKER_UUID                        (-23410)
+/** Internal SPC error: Bad object moniker choice value. */
+#define VERR_CR_SPC_BAD_MONIKER_CHOICE                          (-23411)
+/** Internal SPC error: Bad object moniker data pointer. */
+#define VERR_CR_SPC_MONIKER_BAD_DATA                             (-23412)
+/** Multiple PE image page hash tables. */
+#define VERR_CR_SPC_PEIMAGE_MULTIPLE_HASH_TABS                  (-23413)
+/** Unknown SPC PE image attribute. */
+#define VERR_CR_SPC_PEIMAGE_UNKNOWN_ATTRIBUTE                   (-23414)
+/** URL not expected in SPC PE image data. */
+#define VERR_CR_SPC_PEIMAGE_URL_UNEXPECTED                      (-23415)
+/** PE image data without any valid content was not expected. */
+#define VERR_CR_SPC_PEIMAGE_NO_CONTENT                          (-23416)
+/** @} */
+
+/** @name RTCrPkix status codes.
+ * @{ */
+/** Generic PKCS \#7 error. */
+#define VERR_CR_PKIX_GENERIC_ERROR                  (-23500)
+/** Parameters was presented to a signature schema that does not take any. */
+#define VERR_CR_PKIX_SIGNATURE_TAKES_NO_PARAMETERS  (-23501)
+/** Unknown hash digest type. */
+#define VERR_CR_PKIX_UNKNOWN_DIGEST_TYPE            (-23502)
+/** Internal error. */
+#define VERR_CR_PKIX_INTERNAL_ERROR                 (-23503)
+/** The hash is too long for the key used when signing/verifying. */
+#define VERR_CR_PKIX_HASH_TOO_LONG_FOR_KEY          (-23504)
+/** The signature is too long for the scratch buffer. */
+#define VERR_CR_PKIX_SIGNATURE_TOO_LONG             (-23505)
+/** The signature is greater than or equal to the key. */
+#define VERR_CR_PKIX_SIGNATURE_GE_KEY               (-23506)
+/** The signature is negative. */
+#define VERR_CR_PKIX_SIGNATURE_NEGATIVE             (-23507)
+/** Invalid signature length. */
+#define VERR_CR_PKIX_INVALID_SIGNATURE_LENGTH       (-23508)
+/** PKIX signature no does not match up to the current data. */
+#define VERR_CR_PKIX_SIGNATURE_MISMATCH             (-23509)
+/** PKIX cipher algorithm parameters are not implemented. */
+#define VERR_CR_PKIX_CIPHER_ALGO_PARAMS_NOT_IMPL    (-23510)
+/** Cipher algorithm is not known to us. */
+#define VERR_CR_PKIX_CIPHER_ALGO_NOT_KNOWN          (-23511)
+/** PKIX cipher algorithm is not known to OpenSSL. */
+#define VERR_CR_PKIX_OSSL_CIPHER_ALGO_NOT_KNOWN     (-23512)
+/** PKIX cipher algorithm is not known to OpenSSL EVP API. */
+#define VERR_CR_PKIX_OSSL_CIPHER_ALGO_NOT_KNOWN_EVP (-23513)
+/** OpenSSL failed to init PKIX cipher algorithm context. */
+#define VERR_CR_PKIX_OSSL_CIPHER_ALOG_INIT_FAILED   (-23514)
+/** Final OpenSSL PKIX verification failed. */
+#define VERR_CR_PKIX_OSSL_VERIFY_FINAL_FAILED       (-23515)
+/** OpenSSL failed to decode the public key. */
+#define VERR_CR_PKIX_OSSL_D2I_PUBLIC_KEY_FAILED     (-23516)
+/** The EVP_PKEY_type API in OpenSSL failed.  */
+#define VERR_CR_PKIX_OSSL_EVP_PKEY_TYPE_ERROR       (-23517)
+/** @} */
+
+/** @name RTCrStore status codes.
+ * @{ */
+/** Generic store error. */
+#define VERR_CR_STORE_GENERIC_ERROR                 (-23700)
+/** @} */
+
+/** @name RTCrRsa status codes.
+ * @{ */
+/** Generic RSA error. */
+#define VERR_CR_RSA_GENERIC_ERROR                   (-23900)
+/** @} */
+
+/** @name RTBigNum status codes.
+ * @{ */
+/** Sensitive input requires the result(s) to be initialized as sensitive. */
+#define VERR_BIGNUM_SENSITIVE_INPUT                 (-24000)
+/** Attempt to divide by zero. */
+#define VERR_BIGNUM_DIV_BY_ZERO                     (-24001)
+/** Negative exponent makes no sense to integer math. */
+#define VERR_BIGNUM_NEGATIVE_EXPONENT               (-24002)
+
+/** @} */
+
+/** @name RTCrDigest status codes.
+ * @{ */
+/** OpenSSL failed to initialize the digest algorithm context. */
+#define VERR_CR_DIGEST_OSSL_DIGEST_INIT_ERROR       (-24200)
+/** OpenSSL failed to clone the digest algorithm context. */
+#define VERR_CR_DIGEST_OSSL_DIGEST_CTX_COPY_ERROR   (-24201)
+/** @} */
+
+/** @name RTPath  status codes.
+ * @{ */
+/** Unknown glob variable.  */
+#define VERR_PATH_MATCH_UNKNOWN_VARIABLE            (-24400)
+/** The specified glob variable must be first in the pattern. */
+#define VERR_PATH_MATCH_VARIABLE_MUST_BE_FIRST      (-24401)
+/** Hit unimplemented glob pattern matching feature.  */
+#define VERR_PATH_MATCH_FEATURE_NOT_IMPLEMENTED     (-24402)
+/** Unknown character class in glob pattern.   */
+#define VERR_PATH_GLOB_UNKNOWN_CHAR_CLASS           (-24403)
+/** @} */
+
+/** @name RTUri status codes.
+ * @{ */
+/** The URI is empty */
+#define VERR_URI_EMPTY                              (-24600)
+/** The URI is too short to be a valid URI. */
+#define VERR_URI_TOO_SHORT                          (-24601)
+/** Invalid scheme.  */
+#define VERR_URI_INVALID_SCHEME                     (-24602)
+/** Invalid port number.  */
+#define VERR_URI_INVALID_PORT_NUMBER                (-24603)
+/** Invalid escape sequence.  */
+#define VERR_URI_INVALID_ESCAPE_SEQ                 (-24604)
+/** Escape URI char decodes as zero (the C string terminator). */
+#define VERR_URI_ESCAPED_ZERO                       (-24605)
+/** Escaped URI characters does not decode to valid UTF-8. */
+#define VERR_URI_ESCAPED_CHARS_NOT_VALID_UTF8       (-24606)
+/** Escaped URI character is not a valid UTF-8 lead byte. */
+#define VERR_URI_INVALID_ESCAPED_UTF8_LEAD_BYTE     (-24607)
+/** Escaped URI character sequence with invalid UTF-8 continutation byte. */
+#define VERR_URI_INVALID_ESCAPED_UTF8_CONTINUATION_BYTE (-24608)
+/** Missing UTF-8 continutation in escaped URI character sequence. */
+#define VERR_URI_MISSING_UTF8_CONTINUATION_BYTE     (-24609)
+/** Expected URI using the 'file:' scheme. */
+#define VERR_URI_NOT_FILE_SCHEME                    (-24610)
+/** @} */
+
+/* SED-END */
+
+/** @} */
+
+#endif
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/include/iprt/errno.h
@@ -0,0 +1,318 @@
+/** @file
+ * IPRT - errno.h wrapper.
+ */
+
+/*
+ * Copyright (C) 2012-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+
+#ifndef ___iprt_errno_h___
+#define ___iprt_errno_h___
+
+#ifndef IPRT_NO_CRT
+# if defined(RT_OS_DARWIN) && defined(KERNEL)
+#  include <sys/errno.h>
+# elif defined(RT_OS_LINUX) && defined(__KERNEL__)
+#  include <linux/errno.h>
+# elif defined(RT_OS_FREEBSD) && defined(_KERNEL)
+#  include <sys/errno.h>
+# else
+#  include <errno.h>
+# endif
+#endif
+
+
+/*
+ * Supply missing errno values according to the current RT_OS_XXX definition.
+ *
+ * Note! These supplements are for making no-CRT mode, as well as making UNIXy
+ *       code that makes used of odd errno defines internally, work smoothly.
+ *
+ * When adding more error codes, always check the following errno.h sources:
+ *  - RT_OS_DARWIN:  http://fxr.watson.org/fxr/source/bsd/sys/errno.h?v=xnu-1699.24.8
+ *  - RT_OS_FREEBSD: http://fxr.watson.org/fxr/source/sys/errno.h?v=DFBSD
+ *  - RT_OS_NETBSD:  http://fxr.watson.org/fxr/source/sys/errno.h?v=NETBSD
+ *  - RT_OS_OPENBSD: http://fxr.watson.org/fxr/source/sys/errno.h?v=OPENBSD
+ *  - RT_OS_OS2:     http://svn.netlabs.org/libc/browser/trunk/libc/include/sys/errno.h
+ *  - RT_OS_LINUX:   http://fxr.watson.org/fxr/source/include/asm-generic/errno.h?v=linux-2.6
+ *  - RT_OS_SOLARIS: http://fxr.watson.org/fxr/source/common/sys/errno.h?v=OPENSOLARIS
+ *  - RT_OS_WINDOWS: tools/win.x86/vcc/v8sp1/include/errno.h
+ */
+
+#if defined(RT_OS_DARWIN) \
+ || defined(RT_OS_FREEBSD) \
+ || defined(RT_OS_NETBSD) \
+ || defined(RT_OS_OPENBSD) \
+ || defined(RT_OS_OS2)
+# define RT_ERRNO_OS_BSD
+#endif
+#ifdef RT_OS_SOLARIS
+# define RT_ERRNO_OS_SYSV_HARDCORE /* ?? */
+#endif
+
+/* The relatively similar part. */
+#ifndef EPERM
+# define EPERM                  (1)
+#endif
+#ifndef ENOENT
+# define ENOENT                 (2)
+#endif
+#ifndef ESRCH
+# define ESRCH                  (3)
+#endif
+#ifndef EINTR
+# define EINTR                  (4)
+#endif
+#ifndef EIO
+# define EIO                    (5)
+#endif
+#ifndef ENXIO
+# define ENXIO                  (6)
+#endif
+#ifndef E2BIG
+# define E2BIG                  (7)
+#endif
+#ifndef ENOEXEC
+# define ENOEXEC                (8)
+#endif
+#ifndef EBADF
+# define EBADF                  (9)
+#endif
+#ifndef ECHILD
+# define ECHILD                 (10)
+#endif
+#ifndef EAGAIN
+# if defined(RT_ERRNO_OS_BSD)
+#  define EAGAIN                (35)
+# else
+#  define EAGAIN                (11)
+# endif
+#endif
+#ifndef EWOULDBLOCK
+# define EWOULDBLOCK            EAGAIN
+#endif
+#ifndef EDEADLK
+# if defined(RT_ERRNO_OS_BSD)
+#  define EDEADLK               (11)
+# elif defined(RT_OS_LINUX)
+#  define EDEADLK               (35)
+# elif defined(RT_OS_WINDOWS)
+#  define EDEADLK               (36)
+# else
+#  define EDEADLK               (45)
+# endif
+#endif
+#ifndef EDEADLOCK
+# define EDEADLOCK              EDEADLK
+#endif
+#ifndef ENOMEM
+# define ENOMEM                 (12)
+#endif
+#ifndef EACCES
+# define EACCES                 (13)
+#endif
+#ifndef EFAULT
+# define EFAULT                 (14)
+#endif
+#ifndef ENOTBLK
+# define ENOTBLK                (15)
+#endif
+#ifndef EBUSY
+# define EBUSY                  (16)
+#endif
+#ifndef EEXIST
+# define EEXIST                 (17)
+#endif
+#ifndef EXDEV
+# define EXDEV                  (18)
+#endif
+#ifndef ENODEV
+# define ENODEV                 (19)
+#endif
+#ifndef ENOTDIR
+# define ENOTDIR                (20)
+#endif
+#ifndef EISDIR
+# define EISDIR                 (21)
+#endif
+#ifndef EINVAL
+# define EINVAL                 (22)
+#endif
+#ifndef ENFILE
+# define ENFILE                 (23)
+#endif
+#ifndef EMFILE
+# define EMFILE                 (24)
+#endif
+#ifndef ENOTTY
+# define ENOTTY                 (25)
+#endif
+#ifndef ETXTBSY
+# define ETXTBSY                (26)
+#endif
+#ifndef EFBIG
+# define EFBIG                  (27)
+#endif
+#ifndef ENOSPC
+# define ENOSPC                 (28)
+#endif
+#ifndef ESPIPE
+# define ESPIPE                 (29)
+#endif
+#ifndef EROFS
+# define EROFS                  (30)
+#endif
+#ifndef EMLINK
+# define EMLINK                 (31)
+#endif
+#ifndef EPIPE
+# define EPIPE                  (32)
+#endif
+#ifndef EDOM
+# define EDOM                   (33)
+#endif
+#ifndef ERANGE
+# define ERANGE                 (34)
+#endif
+
+/* 35 - also EAGAIN on BSD and EDEADLK on Linux. */
+#ifndef ENOMSG
+# if defined(RT_OS_DARWIN)
+#  define ENOMSG                (91)
+# elif defined(RT_OS_FREEBSD)
+#  define ENOMSG                (83)
+# elif defined(RT_OS_LINUX)
+#  define ENOMSG                (42)
+# else
+#  define ENOMSG                (35)
+# endif
+#endif
+
+/* 36 - Also EDEADLK on Windows.  */
+#ifndef EIDRM
+# if defined(RT_OS_DARWIN)
+#  define EIDRM                 (90)
+# elif defined(RT_OS_FREEBSD) || defined(RT_OS_NETBSD)
+#  define EIDRM                 (82)
+# elif defined(RT_OS_OPENBSD)
+#  define EIDRM                 (89)
+# elif defined(RT_OS_LINUX)
+#  define EIDRM                 (43)
+# elif defined(RT_OS_WINDOWS)
+#  define EIDRM                 (600)
+# else
+#  define EIDRM                 (36)
+# endif
+#endif
+#ifndef EINPROGRESS
+# if defined(RT_ERRNO_OS_BSD)
+#  define EINPROGRESS           (36)
+# elif defined(RT_OS_LINUX)
+#  define EINPROGRESS           (115)
+# else
+#  define EINPROGRESS           (150)
+# endif
+#endif
+#ifndef ENAMETOOLONG
+# if defined(RT_ERRNO_OS_BSD)
+#  define ENAMETOOLONG          (63)
+# elif defined(RT_OS_LINUX)
+#  define ENAMETOOLONG          (36)
+# else
+#  define ENAMETOOLONG          (78)
+# endif
+#endif
+
+/* 37 */
+#ifndef ECHRNG
+# if defined(RT_ERRNO_OS_SYSV_HARDCORE)
+#  define ECHRNG                (37)
+# else
+#  define ECHRNG                (599)
+# endif
+#endif
+#ifndef ENOLCK
+# if defined(RT_ERRNO_OS_BSD)
+#  define ENOLCK                (77)
+# elif defined(RT_OS_LINUX)
+#  define ENOLCK                (37)
+# else
+#  define ENOLCK                (46)
+# endif
+#endif
+#ifndef EALREADY
+# if defined(RT_ERRNO_OS_BSD)
+#  define EALREADY              (37)
+# elif defined(RT_OS_LINUX)
+#  define EALREADY              (114)
+# else
+#  define EALREADY              (149)
+# endif
+#endif
+
+/** @todo errno constants {37..44}. */
+
+/* 45 - also EDEADLK on Solaris, EL2NSYNC on Linux. */
+#ifndef ENOTSUP
+# if defined(RT_ERRNO_OS_BSD)
+#  define ENOTSUP               (45)
+# elif defined(RT_OS_LINUX)
+#  define ENOTSUP               (95)
+# else
+#  define ENOTSUP               (48)
+# endif
+#endif
+#ifndef EOPNOTSUPP
+# if defined(RT_ERRNO_OS_BSD)
+#  define EOPNOTSUPP            ENOTSUP
+# elif defined(RT_OS_LINUX)
+#  define EOPNOTSUPP            ENOTSUP
+# else
+#  define EOPNOTSUPP            (122)
+# endif
+#endif
+
+/** @todo errno constants {46..74}. */
+
+/* 75 - note that Solaris has constant with value 75. */
+#ifndef EOVERFLOW
+# if defined(RT_OS_OPENBSD)
+#  define EOVERFLOW             (87)
+# elif defined(RT_ERRNO_OS_BSD)
+#  define EOVERFLOW             (84)
+# elif defined(RT_OS_LINUX)
+#  define EOVERFLOW             (75)
+# else
+#  define EOVERFLOW             (79)
+# endif
+#endif
+#ifndef EPROGMISMATCH
+# if defined(RT_ERRNO_OS_BSD)
+#  define EPROGMISMATCH         (75)
+# else
+#  define EPROGMISMATCH         (598)
+# endif
+#endif
+
+/** @todo errno constants {76..}. */
+
+
+#endif
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/include/iprt/fs.h
@@ -0,0 +1,637 @@
+/** @file
+ * IPRT - Filesystem.
+ */
+
+/*
+ * Copyright (C) 2006-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+#ifndef ___iprt_fs_h
+#define ___iprt_fs_h
+
+#include <iprt/cdefs.h>
+#include <iprt/types.h>
+#include <iprt/time.h>
+
+
+RT_C_DECLS_BEGIN
+
+/** @defgroup grp_rt_fs    RTFs - Filesystem and Volume
+ * @ingroup grp_rt
+ * @{
+ */
+
+
+/** @name Filesystem Object Mode Flags.
+ *
+ * There are two sets of flags: the unix mode flags and the dos attributes.
+ *
+ * APIs returning mode flags will provide both sets.
+ *
+ * When specifying mode flags to any API at least one of them must be given. If
+ * one set is missing the API will synthesize it from the one given if it
+ * requires it.
+ *
+ * Both sets match their x86 ABIs, the DOS/NT one is simply shifted up 16 bits.
+ * The DOS/NT range is bits 16 to 31 inclusively. The Unix range is bits 0 to 15
+ * (inclusively).
+ *
+ * @remarks These constants have been comitted to a binary format and must not
+ *          be changed in any incompatible ways.
+ *
+ * @{
+ */
+
+/** Set user id on execution (S_ISUID). */
+#define RTFS_UNIX_ISUID             0004000U
+/** Set group id on execution (S_ISGID). */
+#define RTFS_UNIX_ISGID             0002000U
+/** Sticky bit (S_ISVTX / S_ISTXT). */
+#define RTFS_UNIX_ISTXT             0001000U
+
+/** Owner RWX mask (S_IRWXU). */
+#define RTFS_UNIX_IRWXU             0000700U
+/** Owner readable (S_IRUSR). */
+#define RTFS_UNIX_IRUSR             0000400U
+/** Owner writable (S_IWUSR). */
+#define RTFS_UNIX_IWUSR             0000200U
+/** Owner executable (S_IXUSR). */
+#define RTFS_UNIX_IXUSR             0000100U
+
+/** Group RWX mask (S_IRWXG). */
+#define RTFS_UNIX_IRWXG             0000070U
+/** Group readable (S_IRGRP). */
+#define RTFS_UNIX_IRGRP             0000040U
+/** Group writable (S_IWGRP). */
+#define RTFS_UNIX_IWGRP             0000020U
+/** Group executable (S_IXGRP). */
+#define RTFS_UNIX_IXGRP             0000010U
+
+/** Other RWX mask (S_IRWXO). */
+#define RTFS_UNIX_IRWXO             0000007U
+/** Other readable (S_IROTH). */
+#define RTFS_UNIX_IROTH             0000004U
+/** Other writable (S_IWOTH). */
+#define RTFS_UNIX_IWOTH             0000002U
+/** Other executable (S_IXOTH). */
+#define RTFS_UNIX_IXOTH             0000001U
+
+/** All UNIX access permission bits (0777). */
+#define RTFS_UNIX_ALL_ACCESS_PERMS  0000777U
+/** All UNIX permission bits, including set id and sticky bits.  */
+#define RTFS_UNIX_ALL_PERMS         0007777U
+
+/** Named pipe (fifo) (S_IFIFO). */
+#define RTFS_TYPE_FIFO              0010000U
+/** Character device (S_IFCHR). */
+#define RTFS_TYPE_DEV_CHAR          0020000U
+/** Directory (S_IFDIR). */
+#define RTFS_TYPE_DIRECTORY         0040000U
+/** Block device (S_IFBLK). */
+#define RTFS_TYPE_DEV_BLOCK         0060000U
+/** Regular file (S_IFREG). */
+#define RTFS_TYPE_FILE              0100000U
+/** Symbolic link (S_IFLNK). */
+#define RTFS_TYPE_SYMLINK           0120000U
+/** Socket (S_IFSOCK). */
+#define RTFS_TYPE_SOCKET            0140000U
+/** Whiteout (S_IFWHT). */
+#define RTFS_TYPE_WHITEOUT          0160000U
+/** Type mask (S_IFMT). */
+#define RTFS_TYPE_MASK              0170000U
+/** The shift count to convert between RTFS_TYPE_MASK and DIRENTRYTYPE. */
+#define RTFS_TYPE_DIRENTRYTYPE_SHIFT    12
+
+/** Unix attribute mask. */
+#define RTFS_UNIX_MASK              0xffffU
+/** The mask of all the NT, OS/2 and DOS attributes. */
+#define RTFS_DOS_MASK               (0x7fffU << RTFS_DOS_SHIFT)
+
+/** The shift value. */
+#define RTFS_DOS_SHIFT              16
+/** The mask of the OS/2 and DOS attributes. */
+#define RTFS_DOS_MASK_OS2           (0x003fU << RTFS_DOS_SHIFT)
+/** The mask of the NT attributes. */
+#define RTFS_DOS_MASK_NT            (0x7fffU << RTFS_DOS_SHIFT)
+
+/** Readonly object. */
+#define RTFS_DOS_READONLY           (0x0001U << RTFS_DOS_SHIFT)
+/** Hidden object. */
+#define RTFS_DOS_HIDDEN             (0x0002U << RTFS_DOS_SHIFT)
+/** System object. */
+#define RTFS_DOS_SYSTEM             (0x0004U << RTFS_DOS_SHIFT)
+/** Directory. */
+#define RTFS_DOS_DIRECTORY          (0x0010U << RTFS_DOS_SHIFT)
+/** Archived object.
+ * This bit is set by the filesystem after each modification of a file. */
+#define RTFS_DOS_ARCHIVED           (0x0020U << RTFS_DOS_SHIFT)
+/** Undocumented / Reserved, used to be the FAT volume label. */
+#define RTFS_DOS_NT_DEVICE          (0x0040U << RTFS_DOS_SHIFT)
+/** Normal object, no other attribute set (NT). */
+#define RTFS_DOS_NT_NORMAL          (0x0080U << RTFS_DOS_SHIFT)
+/** Temporary object (NT). */
+#define RTFS_DOS_NT_TEMPORARY       (0x0100U << RTFS_DOS_SHIFT)
+/** Sparse file (NT). */
+#define RTFS_DOS_NT_SPARSE_FILE     (0x0200U << RTFS_DOS_SHIFT)
+/** Reparse point (NT). */
+#define RTFS_DOS_NT_REPARSE_POINT   (0x0400U << RTFS_DOS_SHIFT)
+/** Compressed object (NT).
+ * For a directory, compression is the default for new files. */
+#define RTFS_DOS_NT_COMPRESSED      (0x0800U << RTFS_DOS_SHIFT)
+/** Physically offline data (NT).
+ * MSDN say, don't mess with this one. */
+#define RTFS_DOS_NT_OFFLINE         (0x1000U << RTFS_DOS_SHIFT)
+/** Not content indexed by the content indexing service (NT). */
+#define RTFS_DOS_NT_NOT_CONTENT_INDEXED (0x2000U << RTFS_DOS_SHIFT)
+/** Encryped object (NT).
+ * For a directory, encrypted is the default for new files. */
+#define RTFS_DOS_NT_ENCRYPTED       (0x4000U << RTFS_DOS_SHIFT)
+
+/** @} */
+
+
+/** @name Filesystem Object Type Predicates.
+ * @{ */
+/** Checks the mode flags indicate a named pipe (fifo) (S_ISFIFO). */
+#define RTFS_IS_FIFO(fMode)         ( ((fMode) & RTFS_TYPE_MASK) == RTFS_TYPE_FIFO )
+/** Checks the mode flags indicate a character device (S_ISCHR). */
+#define RTFS_IS_DEV_CHAR(fMode)     ( ((fMode) & RTFS_TYPE_MASK) == RTFS_TYPE_DEV_CHAR )
+/** Checks the mode flags indicate a directory (S_ISDIR). */
+#define RTFS_IS_DIRECTORY(fMode)    ( ((fMode) & RTFS_TYPE_MASK) == RTFS_TYPE_DIRECTORY )
+/** Checks the mode flags indicate a block device (S_ISBLK). */
+#define RTFS_IS_DEV_BLOCK(fMode)    ( ((fMode) & RTFS_TYPE_MASK) == RTFS_TYPE_DEV_BLOCK )
+/** Checks the mode flags indicate a regular file (S_ISREG). */
+#define RTFS_IS_FILE(fMode)         ( ((fMode) & RTFS_TYPE_MASK) == RTFS_TYPE_FILE )
+/** Checks the mode flags indicate a symbolic link (S_ISLNK). */
+#define RTFS_IS_SYMLINK(fMode)      ( ((fMode) & RTFS_TYPE_MASK) == RTFS_TYPE_SYMLINK )
+/** Checks the mode flags indicate a socket (S_ISSOCK). */
+#define RTFS_IS_SOCKET(fMode)       ( ((fMode) & RTFS_TYPE_MASK) == RTFS_TYPE_SOCKET )
+/** Checks the mode flags indicate a whiteout (S_ISWHT). */
+#define RTFS_IS_WHITEOUT(fMode)     ( ((fMode) & RTFS_TYPE_MASK) == RTFS_TYPE_WHITEOUT )
+/** @} */
+
+
+/**
+ * Filesystem type IDs returned by RTFsQueryType.
+ *
+ * This enum is subject to changes and must not be used as part of any ABI or
+ * binary format (file, network, etc).
+ *
+ * @remarks When adding new entries, please update RTFsTypeName().  Also, try
+ *          add them to the most natural group.
+ */
+typedef enum RTFSTYPE
+{
+    /** Unknown file system. */
+    RTFSTYPE_UNKNOWN = 0,
+
+    /** Universal Disk Format. */
+    RTFSTYPE_UDF,
+    /** ISO 9660, aka Compact Disc File System (CDFS). */
+    RTFSTYPE_ISO9660,
+    /** Filesystem in Userspace. */
+    RTFSTYPE_FUSE,
+    /** VirtualBox shared folders.  */
+    RTFSTYPE_VBOXSHF,
+
+    /* Linux: */
+    RTFSTYPE_EXT,
+    RTFSTYPE_EXT2,
+    RTFSTYPE_EXT3,
+    RTFSTYPE_EXT4,
+    RTFSTYPE_XFS,
+    RTFSTYPE_CIFS,
+    RTFSTYPE_SMBFS,
+    RTFSTYPE_TMPFS,
+    RTFSTYPE_SYSFS,
+    RTFSTYPE_PROC,
+    RTFSTYPE_OCFS2,
+    RTFSTYPE_BTRFS,
+
+    /* Windows: */
+    /** New Technology File System. */
+    RTFSTYPE_NTFS,
+    /** FAT12, FAT16 and FAT32 lumped into one basket.
+     * The partition size limit of FAT12 and FAT16 will be the factor
+     * limiting the file size (except, perhaps for the 64KB cluster case on
+     * non-Windows hosts). */
+    RTFSTYPE_FAT,
+
+    /* Solaris: */
+    /** Zettabyte File System.  */
+    RTFSTYPE_ZFS,
+    /** Unix File System. */
+    RTFSTYPE_UFS,
+    /** Network File System. */
+    RTFSTYPE_NFS,
+
+    /* Mac OS X: */
+    /** Hierarchical File System. */
+    RTFSTYPE_HFS,
+    /** @todo RTFSTYPE_HFS_PLUS? */
+    RTFSTYPE_AUTOFS,
+    RTFSTYPE_DEVFS,
+
+    /* *BSD: */
+
+    /* OS/2: */
+    /** High Performance File System. */
+    RTFSTYPE_HPFS,
+    /** Journaled File System (v2).  */
+    RTFSTYPE_JFS,
+
+    /** The end of valid Filesystem types IDs. */
+    RTFSTYPE_END,
+    /** The usual 32-bit type blow up. */
+    RTFSTYPE_32BIT_HACK = 0x7fffffff
+} RTFSTYPE;
+/** Pointer to a Filesystem type ID. */
+typedef RTFSTYPE *PRTFSTYPE;
+
+
+/**
+ * The available additional information in a RTFSOBJATTR object.
+ */
+typedef enum RTFSOBJATTRADD
+{
+    /** No additional information is available / requested. */
+    RTFSOBJATTRADD_NOTHING = 1,
+    /** The additional unix attributes (RTFSOBJATTR::u::Unix) are available /
+     *  requested. */
+    RTFSOBJATTRADD_UNIX,
+    /** The additional unix attributes (RTFSOBJATTR::u::UnixOwner) are
+     * available / requested. */
+    RTFSOBJATTRADD_UNIX_OWNER,
+    /** The additional unix attributes (RTFSOBJATTR::u::UnixGroup) are
+     * available / requested. */
+    RTFSOBJATTRADD_UNIX_GROUP,
+    /** The additional extended attribute size (RTFSOBJATTR::u::EASize) is available / requested. */
+    RTFSOBJATTRADD_EASIZE,
+    /** The last valid item (inclusive).
+     * The valid range is RTFSOBJATTRADD_NOTHING thru RTFSOBJATTRADD_LAST.  */
+    RTFSOBJATTRADD_LAST = RTFSOBJATTRADD_EASIZE,
+
+    /** The usual 32-bit hack. */
+    RTFSOBJATTRADD_32BIT_SIZE_HACK = 0x7fffffff
+} RTFSOBJATTRADD;
+
+/** The number of bytes reserved for the additional attribute union. */
+#define RTFSOBJATTRUNION_MAX_SIZE       128
+
+/**
+ * Additional Unix Attributes (RTFSOBJATTRADD_UNIX).
+ */
+typedef struct RTFSOBJATTRUNIX
+{
+    /** The user owning the filesystem object (st_uid).
+     * This field is NIL_UID if not supported. */
+    RTUID           uid;
+
+    /** The group the filesystem object is assigned (st_gid).
+     * This field is NIL_GID if not supported. */
+    RTGID           gid;
+
+    /** Number of hard links to this filesystem object (st_nlink).
+     * This field is 1 if the filesystem doesn't support hardlinking or
+     * the information isn't available.
+     */
+    uint32_t        cHardlinks;
+
+    /** The device number of the device which this filesystem object resides on (st_dev).
+     * This field is 0 if this information is not available. */
+    RTDEV           INodeIdDevice;
+
+    /** The unique identifier (within the filesystem) of this filesystem object (st_ino).
+     * Together with INodeIdDevice, this field can be used as a OS wide unique id
+     * when both their values are not 0.
+     * This field is 0 if the information is not available. */
+    RTINODE         INodeId;
+
+    /** User flags (st_flags).
+     * This field is 0 if this information is not available. */
+    uint32_t        fFlags;
+
+    /** The current generation number (st_gen).
+     * This field is 0 if this information is not available. */
+    uint32_t        GenerationId;
+
+    /** The device number of a character or block device type object (st_rdev).
+     * This field is 0 if the file isn't of a character or block device type and
+     * when the OS doesn't subscribe to the major+minor device idenfication scheme. */
+    RTDEV           Device;
+} RTFSOBJATTRUNIX;
+
+
+/**
+ * Additional Unix Attributes (RTFSOBJATTRADD_UNIX_OWNER).
+ *
+ * @remarks This interface is mainly for TAR.
+ */
+typedef struct RTFSOBJATTRUNIXOWNER
+{
+    /** The user owning the filesystem object (st_uid).
+     * This field is NIL_UID if not supported. */
+    RTUID           uid;
+    /** The user name.
+     * Empty if not available or not supported, truncated if too long. */
+    char            szName[RTFSOBJATTRUNION_MAX_SIZE - sizeof(RTUID)];
+} RTFSOBJATTRUNIXOWNER;
+
+
+/**
+ * Additional Unix Attributes (RTFSOBJATTRADD_UNIX_GROUP).
+ *
+ * @remarks This interface is mainly for TAR.
+ */
+typedef struct RTFSOBJATTRUNIXGROUP
+{
+    /** The user owning the filesystem object (st_uid).
+     * This field is NIL_GID if not supported. */
+    RTGID           gid;
+    /** The group name.
+     * Empty if not available or not supported, truncated if too long. */
+    char            szName[RTFSOBJATTRUNION_MAX_SIZE - sizeof(RTGID)];
+} RTFSOBJATTRUNIXGROUP;
+
+
+/**
+ * Filesystem object attributes.
+ */
+typedef struct RTFSOBJATTR
+{
+    /** Mode flags (st_mode). RTFS_UNIX_*, RTFS_TYPE_*, and RTFS_DOS_*. */
+    RTFMODE         fMode;
+
+    /** The additional attributes available. */
+    RTFSOBJATTRADD  enmAdditional;
+
+    /**
+     * Additional attributes.
+     *
+     * Unless explicitly specified to an API, the API can provide additional
+     * data as it is provided by the underlying OS.
+     */
+    union RTFSOBJATTRUNION
+    {
+        /** Additional Unix Attributes - RTFSOBJATTRADD_UNIX. */
+        RTFSOBJATTRUNIX         Unix;
+        /** Additional Unix Owner Attributes - RTFSOBJATTRADD_UNIX_OWNER. */
+        RTFSOBJATTRUNIXOWNER    UnixOwner;
+        /** Additional Unix Group Attributes - RTFSOBJATTRADD_UNIX_GROUP. */
+        RTFSOBJATTRUNIXGROUP    UnixGroup;
+
+        /**
+         * Extended attribute size is available when RTFS_DOS_HAVE_EA_SIZE is set.
+         */
+        struct RTFSOBJATTREASIZE
+        {
+            /** Size of EAs. */
+            RTFOFF          cb;
+        } EASize;
+        /** Reserved space. */
+        uint8_t         abReserveSpace[128];
+    } u;
+} RTFSOBJATTR;
+/** Pointer to a filesystem object attributes structure. */
+typedef RTFSOBJATTR *PRTFSOBJATTR;
+/** Pointer to a const filesystem object attributes structure. */
+typedef const RTFSOBJATTR *PCRTFSOBJATTR;
+
+
+/**
+ * Filesystem object information structure.
+ *
+ * This is returned by the RTPathQueryInfo(), RTFileQueryInfo() and RTDirRead() APIs.
+ */
+typedef struct RTFSOBJINFO
+{
+   /** Logical size (st_size).
+    * For normal files this is the size of the file.
+    * For symbolic links, this is the length of the path name contained
+    * in the symbolic link.
+    * For other objects this fields needs to be specified.
+    */
+   RTFOFF       cbObject;
+
+   /** Disk allocation size (st_blocks * DEV_BSIZE). */
+   RTFOFF       cbAllocated;
+
+   /** Time of last access (st_atime). */
+   RTTIMESPEC   AccessTime;
+
+   /** Time of last data modification (st_mtime). */
+   RTTIMESPEC   ModificationTime;
+
+   /** Time of last status change (st_ctime).
+    * If not available this is set to ModificationTime.
+    */
+   RTTIMESPEC   ChangeTime;
+
+   /** Time of file birth (st_birthtime).
+    * If not available this is set to ChangeTime.
+    */
+   RTTIMESPEC   BirthTime;
+
+   /** Attributes. */
+   RTFSOBJATTR  Attr;
+
+} RTFSOBJINFO;
+/** Pointer to a filesystem object information structure. */
+typedef RTFSOBJINFO *PRTFSOBJINFO;
+/** Pointer to a const filesystem object information structure. */
+typedef const RTFSOBJINFO *PCRTFSOBJINFO;
+
+
+#ifdef IN_RING3
+
+/**
+ * Query the sizes of a filesystem.
+ *
+ * @returns iprt status code.
+ * @param   pszFsPath       Path within the mounted filesystem.
+ * @param   pcbTotal        Where to store the total filesystem space. (Optional)
+ * @param   pcbFree         Where to store the remaining free space in the filesystem. (Optional)
+ * @param   pcbBlock        Where to store the block size. (Optional)
+ * @param   pcbSector       Where to store the sector size. (Optional)
+ *
+ * @sa      RTFileQueryFsSizes
+ */
+RTR3DECL(int) RTFsQuerySizes(const char *pszFsPath, PRTFOFF pcbTotal, RTFOFF *pcbFree,
+                             uint32_t *pcbBlock, uint32_t *pcbSector);
+
+/**
+ * Query the mountpoint of a filesystem.
+ *
+ * @returns iprt status code.
+ * @returns VERR_BUFFER_OVERFLOW if cbMountpoint isn't enough.
+ * @param   pszFsPath       Path within the mounted filesystem.
+ * @param   pszMountpoint   Where to store the mountpoint path.
+ * @param   cbMountpoint    Size of the buffer pointed to by pszMountpoint.
+ */
+RTR3DECL(int) RTFsQueryMountpoint(const char *pszFsPath, char *pszMountpoint, size_t cbMountpoint);
+
+/**
+ * Query the label of a filesystem.
+ *
+ * @returns iprt status code.
+ * @returns VERR_BUFFER_OVERFLOW if cbLabel isn't enough.
+ * @param   pszFsPath       Path within the mounted filesystem.
+ * @param   pszLabel        Where to store the label.
+ * @param   cbLabel         Size of the buffer pointed to by pszLabel.
+ */
+RTR3DECL(int) RTFsQueryLabel(const char *pszFsPath, char *pszLabel, size_t cbLabel);
+
+/**
+ * Query the serial number of a filesystem.
+ *
+ * @returns iprt status code.
+ * @param   pszFsPath       Path within the mounted filesystem.
+ * @param   pu32Serial      Where to store the serial number.
+ */
+RTR3DECL(int) RTFsQuerySerial(const char *pszFsPath, uint32_t *pu32Serial);
+
+/**
+ * Query the name of the filesystem driver.
+ *
+ * @returns iprt status code.
+ * @returns VERR_BUFFER_OVERFLOW if cbFsDriver isn't enough.
+ * @param   pszFsPath       Path within the mounted filesystem.
+ * @param   pszFsDriver     Where to store the filesystem driver name.
+ * @param   cbFsDriver      Size of the buffer pointed to by pszFsDriver.
+ */
+RTR3DECL(int) RTFsQueryDriver(const char *pszFsPath, char *pszFsDriver, size_t cbFsDriver);
+
+/**
+ * Query the name of the filesystem the file is located on.
+ *
+ * @returns iprt status code.
+ * @param   pszFsPath       Path within the mounted filesystem.  It must exist.
+ *                          In case this is a symlink, the file it refers to is
+ *                          evaluated.
+ * @param   penmType        Where to store the filesystem type, this is always
+ *                          set.  See RTFSTYPE for the values.
+ */
+RTR3DECL(int) RTFsQueryType(const char *pszFsPath, PRTFSTYPE penmType);
+
+#endif /* IN_RING3 */
+
+/**
+ * Gets the name of a filesystem type.
+ *
+ * @returns Pointer to a read-only string containing the name.
+ * @param   enmType         A valid filesystem ID.  If outside the valid range,
+ *                          the returned string will be pointing to a static
+ *                          memory buffer which will be changed on subsequent
+ *                          calls to this function by any thread.
+ */
+RTDECL(const char *) RTFsTypeName(RTFSTYPE enmType);
+
+/**
+ * Filesystem properties.
+ */
+typedef struct RTFSPROPERTIES
+{
+    /** The maximum size of a filesystem object name.
+     * This does not include the '\\0'. */
+    uint32_t cbMaxComponent;
+
+    /** True if the filesystem is remote.
+     * False if the filesystem is local. */
+    bool    fRemote;
+
+    /** True if the filesystem is case sensitive.
+     * False if the filesystem is case insensitive. */
+    bool    fCaseSensitive;
+
+    /** True if the filesystem is mounted read only.
+     * False if the filesystem is mounted read write. */
+    bool    fReadOnly;
+
+    /** True if the filesystem can encode unicode object names.
+     * False if it can't. */
+    bool    fSupportsUnicode;
+
+    /** True if the filesystem is compresses.
+     * False if it isn't or we don't know. */
+    bool    fCompressed;
+
+    /** True if the filesystem compresses of individual files.
+     * False if it doesn't or we don't know. */
+    bool    fFileCompression;
+
+    /** @todo more? */
+} RTFSPROPERTIES;
+/** Pointer to a filesystem properties structure. */
+typedef RTFSPROPERTIES *PRTFSPROPERTIES;
+/** Pointer to a const filesystem properties structure. */
+typedef RTFSPROPERTIES const *PCRTFSPROPERTIES;
+
+#ifdef IN_RING3
+
+/**
+ * Query the properties of a mounted filesystem.
+ *
+ * @returns iprt status code.
+ * @param   pszFsPath       Path within the mounted filesystem.
+ * @param   pProperties     Where to store the properties.
+ */
+RTR3DECL(int) RTFsQueryProperties(const char *pszFsPath, PRTFSPROPERTIES pProperties);
+
+/**
+ * Checks if the given volume is case sensitive or not.
+ *
+ * This may be misleading in some cases as we lack the necessary APIs to query
+ * the information on some system (or choose not to use them) and are instead
+ * returning the general position on case sensitive file name of the system.
+ *
+ * @returns @c true if case sensitive, @c false if not.
+ * @param   pszFsPath       Path within the mounted file system.
+ */
+RTR3DECL(bool) RTFsIsCaseSensitive(const char *pszFsPath);
+
+/**
+ * Mountpoint enumerator callback.
+ *
+ * @returns iprt status code. Failure terminates the enumeration.
+ * @param   pszMountpoint   The mountpoint name.
+ * @param   pvUser          The user argument.
+ */
+typedef DECLCALLBACK(int) FNRTFSMOUNTPOINTENUM(const char *pszMountpoint, void *pvUser);
+/** Pointer to a FNRTFSMOUNTPOINTENUM(). */
+typedef FNRTFSMOUNTPOINTENUM *PFNRTFSMOUNTPOINTENUM;
+
+/**
+ * Enumerate mount points.
+ *
+ * @returns iprt status code.
+ * @param   pfnCallback     The callback function.
+ * @param   pvUser          The user argument to the callback.
+ */
+RTR3DECL(int) RTFsMountpointsEnum(PFNRTFSMOUNTPOINTENUM pfnCallback, void *pvUser);
+
+
+#endif /* IN_RING3 */
+
+/** @} */
+
+RT_C_DECLS_END
+
+#endif /* !___iprt_fs_h */
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/include/iprt/heap.h
@@ -0,0 +1,356 @@
+/** @file
+ * IPRT - Heap Implementations
+ */
+
+/*
+ * Copyright (C) 2006-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+#ifndef ___iprt_heap_h
+#define ___iprt_heap_h
+
+#include <iprt/cdefs.h>
+#include <iprt/types.h>
+
+RT_C_DECLS_BEGIN
+
+/** @defgroup grp_rt_heap       RTHeap - Heap Implementations
+ * @ingroup grp_rt
+ * @{
+ */
+
+
+/** @defgroup grp_rt_heap_simple    RTHeapSimple - Simple Heap
+ * @{
+ */
+
+/**
+ * Initializes the heap.
+ *
+ * @returns IPRT status code.
+ * @param   pHeap       Where to store the heap anchor block on success.
+ * @param   pvMemory    Pointer to the heap memory.
+ * @param   cbMemory    The size of the heap memory.
+ */
+RTDECL(int) RTHeapSimpleInit(PRTHEAPSIMPLE pHeap, void *pvMemory, size_t cbMemory);
+
+/**
+ * Merge two simple heaps into one.
+ *
+ * The requirement is of course that they next two each other memory wise.
+ *
+ * @returns IPRT status code.
+ * @param   pHeap       Where to store the handle to the merged heap on success.
+ * @param   Heap1       Handle to the first heap.
+ * @param   Heap2       Handle to the second heap.
+ * @remark  This API isn't implemented yet.
+ */
+RTDECL(int) RTHeapSimpleMerge(PRTHEAPSIMPLE pHeap, RTHEAPSIMPLE Heap1, RTHEAPSIMPLE Heap2);
+
+/**
+ * Relocater the heap internal structures after copying it to a new location.
+ *
+ * This can be used when loading a saved heap.
+ *
+ * @returns IPRT status code.
+ * @param   hHeap       Heap handle that has already been adjusted by to the new
+ *                      location.  That is to say, when calling
+ *                      RTHeapSimpleInit, the caller must note the offset of the
+ *                      returned heap handle into the heap memory.  This offset
+ *                      must be used when calcuating the handle value for the
+ *                      new location.  The offset may in some cases not be zero!
+ * @param   offDelta    The delta between the new and old location, i.e. what
+ *                      should be added to the internal pointers.
+ */
+RTDECL(int) RTHeapSimpleRelocate(RTHEAPSIMPLE hHeap, uintptr_t offDelta);
+
+/**
+ * Allocates memory from the specified simple heap.
+ *
+ * @returns Pointer to the allocated memory block on success.
+ * @returns NULL if the request cannot be satisfied. (A VERR_NO_MEMORY condition.)
+ *
+ * @param   Heap        The heap to allocate the memory on.
+ * @param   cb          The requested heap block size.
+ * @param   cbAlignment The requested heap block alignment. Pass 0 for default alignment.
+ *                      Must be a power of 2.
+ */
+RTDECL(void *) RTHeapSimpleAlloc(RTHEAPSIMPLE Heap, size_t cb, size_t cbAlignment);
+
+/**
+ * Allocates zeroed memory from the specified simple heap.
+ *
+ * @returns Pointer to the allocated memory block on success.
+ * @returns NULL if the request cannot be satisfied. (A VERR_NO_MEMORY condition.)
+ *
+ * @param   Heap        The heap to allocate the memory on.
+ * @param   cb          The requested heap block size.
+ * @param   cbAlignment The requested heap block alignment. Pass 0 for default alignment.
+ *                      Must be a power of 2.
+ */
+RTDECL(void *) RTHeapSimpleAllocZ(RTHEAPSIMPLE Heap, size_t cb, size_t cbAlignment);
+
+/**
+ * Reallocates / Allocates / Frees a heap block.
+ *
+ * @param   Heap        The heap. This is optional and will only be used for strict assertions.
+ * @param   pv          The heap block returned by RTHeapSimple. If NULL it behaves like RTHeapSimpleAlloc().
+ * @param   cbNew       The new size of the heap block. If NULL it behaves like RTHeapSimpleFree().
+ * @param   cbAlignment The requested heap block alignment. Pass 0 for default alignment.
+ *                      Must be a power of 2.
+ * @remark  This API isn't implemented yet.
+ */
+RTDECL(void *) RTHeapSimpleRealloc(RTHEAPSIMPLE Heap, void *pv, size_t cbNew, size_t cbAlignment);
+
+/**
+ * Reallocates / Allocates / Frees a heap block, zeroing any new bits.
+ *
+ * @param   Heap        The heap. This is optional and will only be used for strict assertions.
+ * @param   pv          The heap block returned by RTHeapSimple. If NULL it behaves like RTHeapSimpleAllocZ().
+ * @param   cbNew       The new size of the heap block. If NULL it behaves like RTHeapSimpleFree().
+ * @param   cbAlignment The requested heap block alignment. Pass 0 for default alignment.
+ *                      Must be a power of 2.
+ * @remark  This API isn't implemented yet.
+ */
+RTDECL(void *) RTHeapSimpleReallocZ(RTHEAPSIMPLE Heap, void *pv, size_t cbNew, size_t cbAlignment);
+
+/**
+ * Frees memory allocated from a simple heap.
+ *
+ * @param   Heap    The heap. This is optional and will only be used for strict assertions.
+ * @param   pv      The heap block returned by RTHeapSimple
+ */
+RTDECL(void) RTHeapSimpleFree(RTHEAPSIMPLE Heap, void *pv);
+
+/**
+ * Gets the size of the specified heap block.
+ *
+ * @returns The actual size of the heap block.
+ * @returns 0 if \a pv is NULL or it doesn't point to a valid heap block. An invalid \a pv
+ *          can also cause traps or trigger assertions.
+ * @param   Heap    The heap. This is optional and will only be used for strict assertions.
+ * @param   pv      The heap block returned by RTHeapSimple
+ */
+RTDECL(size_t) RTHeapSimpleSize(RTHEAPSIMPLE Heap, void *pv);
+
+/**
+ * Gets the size of the heap.
+ *
+ * This size includes all the internal heap structures. So, even if the heap is
+ * empty the RTHeapSimpleGetFreeSize() will never reach the heap size returned
+ * by this function.
+ *
+ * @returns The heap size.
+ * @returns 0 if heap was safely detected as being bad.
+ * @param   Heap    The heap.
+ */
+RTDECL(size_t) RTHeapSimpleGetHeapSize(RTHEAPSIMPLE Heap);
+
+/**
+ * Returns the sum of all free heap blocks.
+ *
+ * This is the amount of memory you can theoretically allocate
+ * if you do allocations exactly matching the free blocks.
+ *
+ * @returns The size of the free blocks.
+ * @returns 0 if heap was safely detected as being bad.
+ * @param   Heap    The heap.
+ */
+RTDECL(size_t) RTHeapSimpleGetFreeSize(RTHEAPSIMPLE Heap);
+
+/**
+ * Printf like callbaclk function for RTHeapSimpleDump.
+ * @param   pszFormat   IPRT format string.
+ * @param   ...         Format arguments.
+ */
+typedef DECLCALLBACK(void) FNRTHEAPSIMPLEPRINTF(const char *pszFormat, ...) RT_IPRT_FORMAT_ATTR(1, 2);
+/** Pointer to a FNRTHEAPSIMPLEPRINTF function. */
+typedef FNRTHEAPSIMPLEPRINTF *PFNRTHEAPSIMPLEPRINTF;
+
+/**
+ * Dumps the hypervisor heap.
+ *
+ * @param   Heap        The heap handle.
+ * @param   pfnPrintf   Printf like function that groks IPRT formatting.
+ */
+RTDECL(void) RTHeapSimpleDump(RTHEAPSIMPLE Heap, PFNRTHEAPSIMPLEPRINTF pfnPrintf);
+
+/** @}  */
+
+
+
+/** @defgroup grp_rt_heap_offset    RTHeapOffset - Offset Based Heap
+ *
+ * This is a variation on the simple heap that doesn't use pointers internally
+ * and therefore can be saved and restored without any extra effort.
+ *
+ * @{
+ */
+
+/**
+ * Initializes the heap.
+ *
+ * @returns IPRT status code.
+ * @param   phHeap      Where to store the heap anchor block on success.
+ * @param   pvMemory    Pointer to the heap memory.
+ * @param   cbMemory    The size of the heap memory.
+ */
+RTDECL(int) RTHeapOffsetInit(PRTHEAPOFFSET phHeap, void *pvMemory, size_t cbMemory);
+
+/**
+ * Merge two simple heaps into one.
+ *
+ * The requirement is of course that they next two each other memory wise.
+ *
+ * @returns IPRT status code.
+ * @param   phHeap      Where to store the handle to the merged heap on success.
+ * @param   hHeap1      Handle to the first heap.
+ * @param   hHeap2      Handle to the second heap.
+ * @remark  This API isn't implemented yet.
+ */
+RTDECL(int) RTHeapOffsetMerge(PRTHEAPOFFSET phHeap, RTHEAPOFFSET hHeap1, RTHEAPOFFSET hHeap2);
+
+/**
+ * Allocates memory from the specified simple heap.
+ *
+ * @returns Pointer to the allocated memory block on success.
+ * @returns NULL if the request cannot be satisfied. (A VERR_NO_MEMORY condition.)
+ *
+ * @param   hHeap       The heap to allocate the memory on.
+ * @param   cb          The requested heap block size.
+ * @param   cbAlignment The requested heap block alignment. Pass 0 for default alignment.
+ *                      Must be a power of 2.
+ */
+RTDECL(void *) RTHeapOffsetAlloc(RTHEAPOFFSET hHeap, size_t cb, size_t cbAlignment);
+
+/**
+ * Allocates zeroed memory from the specified simple heap.
+ *
+ * @returns Pointer to the allocated memory block on success.
+ * @returns NULL if the request cannot be satisfied. (A VERR_NO_MEMORY condition.)
+ *
+ * @param   hHeap       The heap to allocate the memory on.
+ * @param   cb          The requested heap block size.
+ * @param   cbAlignment The requested heap block alignment. Pass 0 for default
+ *                      alignment. Must be a power of 2.
+ */
+RTDECL(void *) RTHeapOffsetAllocZ(RTHEAPOFFSET hHeap, size_t cb, size_t cbAlignment);
+
+/**
+ * Reallocates / Allocates / Frees a heap block.
+ *
+ * @param   hHeap       The heap handle. This is optional and will only be used
+ *                      for strict assertions.
+ * @param   pv          The heap block returned by RTHeapOffset. If NULL it
+ *                      behaves like RTHeapOffsetAlloc().
+ * @param   cbNew       The new size of the heap block. If NULL it behaves like
+ *                      RTHeapOffsetFree().
+ * @param   cbAlignment The requested heap block alignment. Pass 0 for default
+ *                      alignment. Must be a power of 2.
+ * @remark  This API isn't implemented yet.
+ */
+RTDECL(void *) RTHeapOffsetRealloc(RTHEAPOFFSET hHeap, void *pv, size_t cbNew, size_t cbAlignment);
+
+/**
+ * Reallocates / Allocates / Frees a heap block, zeroing any new bits.
+ *
+ * @param   hHeap       The heap handle. This is optional and will only be used
+ *                      for strict assertions.
+ * @param   pv          The heap block returned by RTHeapOffset. If NULL it
+ *                      behaves like RTHeapOffsetAllocZ().
+ * @param   cbNew       The new size of the heap block. If NULL it behaves like
+ *                      RTHeapOffsetFree().
+ * @param   cbAlignment The requested heap block alignment. Pass 0 for default
+ *                      alignment. Must be a power of 2.
+ * @remark  This API isn't implemented yet.
+ */
+RTDECL(void *) RTHeapOffsetReallocZ(RTHEAPOFFSET hHeap, void *pv, size_t cbNew, size_t cbAlignment);
+
+/**
+ * Frees memory allocated from a simple heap.
+ *
+ * @param   hHeap       The heap handle. This is optional and will only be used
+ *                      for strict assertions.
+ * @param   pv          The heap block returned by RTHeapOffset
+ */
+RTDECL(void) RTHeapOffsetFree(RTHEAPOFFSET hHeap, void *pv);
+
+/**
+ * Gets the size of the specified heap block.
+ *
+ * @returns The actual size of the heap block.
+ * @returns 0 if \a pv is NULL or it doesn't point to a valid heap block. An
+ *          invalid \a pv can also cause traps or trigger assertions.
+ *
+ * @param   hHeap       The heap handle. This is optional and will only be used
+ *                      for strict assertions.
+ * @param   pv          The heap block returned by RTHeapOffset
+ */
+RTDECL(size_t) RTHeapOffsetSize(RTHEAPOFFSET hHeap, void *pv);
+
+/**
+ * Gets the size of the heap.
+ *
+ * This size includes all the internal heap structures. So, even if the heap is
+ * empty the RTHeapOffsetGetFreeSize() will never reach the heap size returned
+ * by this function.
+ *
+ * @returns The heap size.
+ * @returns 0 if heap was safely detected as being bad.
+ * @param   hHeap       The heap handle.
+ */
+RTDECL(size_t) RTHeapOffsetGetHeapSize(RTHEAPOFFSET hHeap);
+
+/**
+ * Returns the sum of all free heap blocks.
+ *
+ * This is the amount of memory you can theoretically allocate
+ * if you do allocations exactly matching the free blocks.
+ *
+ * @returns The size of the free blocks.
+ * @returns 0 if heap was safely detected as being bad.
+ * @param   hHeap       The heap handle.
+ */
+RTDECL(size_t) RTHeapOffsetGetFreeSize(RTHEAPOFFSET hHeap);
+
+/**
+ * Printf like callbaclk function for RTHeapOffsetDump.
+ * @param   pszFormat   IPRT format string.
+ * @param   ...         Format arguments.
+ */
+typedef DECLCALLBACK(void) FNRTHEAPOFFSETPRINTF(const char *pszFormat, ...) RT_IPRT_FORMAT_ATTR(1, 2);
+/** Pointer to a FNRTHEAPOFFSETPRINTF function. */
+typedef FNRTHEAPOFFSETPRINTF *PFNRTHEAPOFFSETPRINTF;
+
+/**
+ * Dumps the hypervisor heap.
+ *
+ * @param   hHeap       The heap handle.
+ * @param   pfnPrintf   Printf like function that groks IPRT formatting.
+ */
+RTDECL(void) RTHeapOffsetDump(RTHEAPOFFSET hHeap, PFNRTHEAPOFFSETPRINTF pfnPrintf);
+
+/** @}  */
+
+/** @}  */
+RT_C_DECLS_END
+
+#endif
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/include/iprt/initterm.h
@@ -0,0 +1,263 @@
+/** @file
+ * IPRT - Runtime Init/Term.
+ */
+
+/*
+ * Copyright (C) 2006-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+#ifndef ___iprt_initterm_h
+#define ___iprt_initterm_h
+
+#include <iprt/cdefs.h>
+#include <iprt/types.h>
+
+RT_C_DECLS_BEGIN
+
+/** @defgroup grp_rt    IPRT C/C++ APIs
+ * @{
+ */
+
+/** @defgroup grp_rt_initterm  RTInit/RTTerm - Initialization and Termination
+ *
+ * APIs for initializing and terminating the IPRT, optionally it can also
+ * convert input arguments to UTF-8 (in ring-3).
+ *
+ * @sa RTOnce, RTOnceEx.
+ *
+ * @{
+ */
+
+#ifdef IN_RING3
+/** @name RTR3Init flags (RTR3INIT_XXX).
+ * @{ */
+/** Try initialize SUPLib. */
+#define RTR3INIT_FLAGS_SUPLIB       RT_BIT(0)
+/** Initializing IPRT from a DLL. */
+#define RTR3INIT_FLAGS_DLL          RT_BIT(1)
+/** We are sharing a process space, so we need to behave. */
+#define RTR3INIT_FLAGS_UNOBTRUSIVE  RT_BIT(2)
+/** The caller ensures that the argument bector is UTF-8. */
+#define RTR3INIT_FLAGS_UTF8_ARGV    RT_BIT(3)
+/** Indicates that this is a standalone application without any additional
+ * shared libraries in the application directory. Mainly windows loader mess. */
+#define RTR3INIT_FLAGS_STANDALONE_APP RT_BIT(4)
+/** @} */
+
+/** @name RTR3InitEx version
+ * @{ */
+/** Version 1. */
+#define RTR3INIT_VER_1              UINT32_C(1)
+/** The current version. */
+#define RTR3INIT_VER_CUR            RTR3INIT_VER_1
+/** @} */
+
+/**
+ * Initializes the runtime library.
+ *
+ * @returns iprt status code.
+ * @param   fFlags          Flags, see RTR3INIT_XXX.
+ */
+RTR3DECL(int) RTR3InitExeNoArguments(uint32_t fFlags);
+
+/**
+ * Initializes the runtime library.
+ *
+ * @returns iprt status code.
+ * @param   cArgs           Pointer to the argument count.
+ * @param   ppapszArgs      Pointer to the argument vector pointer.
+ * @param   fFlags          Flags, see RTR3INIT_XXX.
+ */
+RTR3DECL(int) RTR3InitExe(int cArgs, char ***ppapszArgs, uint32_t fFlags);
+
+/**
+ * Initializes the runtime library.
+ *
+ * @returns iprt status code.
+ * @param   fFlags          Flags, see RTR3INIT_XXX.
+ */
+RTR3DECL(int) RTR3InitDll(uint32_t fFlags);
+
+/**
+ * Initializes the runtime library and possibly also SUPLib too.
+ *
+ * Avoid this interface, it's not considered stable.
+ *
+ * @returns IPRT status code.
+ * @param   iVersion        The interface version. Must be 0 atm.
+ * @param   fFlags          Flags, see RTR3INIT_XXX.
+ * @param   cArgs           Pointer to the argument count.
+ * @param   ppapszArgs      Pointer to the argument vector pointer. NULL
+ *                          allowed if @a cArgs is 0.
+ * @param   pszProgramPath  The program path.  Pass NULL if we're to figure it
+ *                          out ourselves.
+ */
+RTR3DECL(int) RTR3InitEx(uint32_t iVersion, uint32_t fFlags, int cArgs, char ***ppapszArgs, const char *pszProgramPath);
+
+/**
+ * Terminates the runtime library.
+ */
+RTR3DECL(void) RTR3Term(void);
+
+/**
+ * Is IPRT succesfully initialized?
+ *
+ * @returns true/false.
+ */
+RTR3DECL(bool) RTR3InitIsInitialized(void);
+
+/**
+ * Are we running in unobtrusive mode?
+ * @returns true/false.
+ */
+RTR3DECL(bool) RTR3InitIsUnobtrusive(void);
+#endif /* IN_RING3 */
+
+
+#ifdef IN_RING0
+/**
+ * Initializes the ring-0 driver runtime library.
+ *
+ * @returns iprt status code.
+ * @param   fReserved       Flags reserved for the future.
+ */
+RTR0DECL(int) RTR0Init(unsigned fReserved);
+
+/**
+ * Terminates the ring-0 driver runtime library.
+ */
+RTR0DECL(void) RTR0Term(void);
+
+/**
+ * Forcibily terminates the ring-0 driver runtime library.
+ *
+ * This should be used when statically linking the IPRT.  Module using dynamic
+ * linking shall use RTR0Term.  If you're not sure, use RTR0Term!
+ */
+RTR0DECL(void) RTR0TermForced(void);
+#endif
+
+#ifdef IN_RC
+/**
+ * Initializes the raw-mode context runtime library.
+ *
+ * @returns iprt status code.
+ *
+ * @param   u64ProgramStartNanoTS  The startup timestamp.
+ */
+RTRCDECL(int) RTRCInit(uint64_t u64ProgramStartNanoTS);
+
+/**
+ * Terminates the raw-mode context runtime library.
+ */
+RTRCDECL(void) RTRCTerm(void);
+#endif
+
+
+/**
+ * Termination reason.
+ */
+typedef enum RTTERMREASON
+{
+    /** Normal exit. iStatus contains the exit code. */
+    RTTERMREASON_EXIT = 1,
+    /** Any abnormal exit. iStatus is 0 and has no meaning. */
+    RTTERMREASON_ABEND,
+    /** Killed by a signal. The iStatus contains the signal number. */
+    RTTERMREASON_SIGNAL,
+    /** The IPRT module is being unloaded. iStatus is 0 and has no meaning. */
+    RTTERMREASON_UNLOAD
+} RTTERMREASON;
+
+/** Whether lazy clean up is Okay or not.
+ * When the process is exiting, it is a waste of time to for instance free heap
+ * memory or close open files. OTOH, when the runtime is unloaded from the
+ * process, it is important to release absolutely all resources to prevent
+ * resource leaks. */
+#define RTTERMREASON_IS_LAZY_CLEANUP_OK(enmReason)  ((enmReason) != RTTERMREASON_UNLOAD)
+
+
+/**
+ * IPRT termination callback function.
+ *
+ * @param   enmReason           The cause of the termination.
+ * @param   iStatus             The meaning of this depends on enmReason.
+ * @param   pvUser              User argument passed to RTTermRegisterCallback.
+ */
+typedef DECLCALLBACK(void) FNRTTERMCALLBACK(RTTERMREASON enmReason, int32_t iStatus, void *pvUser);
+/** Pointer to an IPRT termination callback function. */
+typedef FNRTTERMCALLBACK *PFNRTTERMCALLBACK;
+
+
+/**
+ * Registers a termination callback.
+ *
+ * This is intended for performing clean up during IPRT termination. Frequently
+ * paired with lazy initialization thru RTOnce.
+ *
+ * The callbacks are called in LIFO order.
+ *
+ * @returns IPRT status code.
+ *
+ * @param   pfnCallback         The callback function.
+ * @param   pvUser              The user argument for the callback.
+ *
+ * @remarks May need to acquire a fast mutex or critical section, so use with
+ *          some care in ring-0 context.
+ *
+ * @remarks Be very careful using this from code that may be unloaded before
+ *          IPRT terminates. Unlike some atexit and on_exit implementations,
+ *          IPRT will not automatically unregister callbacks when a module gets
+ *          unloaded.
+ */
+RTDECL(int) RTTermRegisterCallback(PFNRTTERMCALLBACK pfnCallback, void *pvUser);
+
+/**
+ * Deregister a termination callback.
+ *
+ * @returns VINF_SUCCESS if found, VERR_NOT_FOUND if the callback/pvUser pair
+ *          wasn't found.
+ *
+ * @param   pfnCallback         The callback function.
+ * @param   pvUser              The user argument for the callback.
+ */
+RTDECL(int) RTTermDeregisterCallback(PFNRTTERMCALLBACK pfnCallback, void *pvUser);
+
+/**
+ * Runs the termination callback queue.
+ *
+ * Normally called by an internal IPRT termination function, but may also be
+ * called by external code immediately prior to terminating IPRT if it is in a
+ * better position to state the termination reason and/or status.
+ *
+ * @param   enmReason           The reason why it's called.
+ * @param   iStatus             The associated exit status or signal number.
+ */
+RTDECL(void) RTTermRunCallbacks(RTTERMREASON enmReason, int32_t iStatus);
+
+/** @} */
+
+/** @} */
+
+RT_C_DECLS_END
+
+
+#endif
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/include/iprt/latin1.h
@@ -0,0 +1,392 @@
+/** @file
+ * IPRT - String Manipulation, Latin-1 (ISO-8859-1) encoding.
+ */
+
+/*
+ * Copyright (C) 2006-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+#ifndef ___iprt_latin1_h
+#define ___iprt_latin1_h
+
+#include <iprt/string.h>
+
+RT_C_DECLS_BEGIN
+
+
+/** @defgroup rt_str_latin1     Latin-1 (ISO-8859-1) String Manipulation
+ * @ingroup grp_rt_str
+ *
+ * Deals with Latin-1 encoded strings.
+ *
+ * @warning Make sure to name all variables dealing with Latin-1 strings
+ *          suchthat there is no way to mistake them for normal UTF-8 strings.
+ *          There may be severe security issues resulting from mistaking Latin-1
+ *          for UTF-8!
+ *
+ * @{
+ */
+
+/**
+ * Get the unicode code point at the given string position.
+ *
+ * @returns unicode code point.
+ * @returns RTUNICP_INVALID if the encoding is invalid.
+ * @param   pszLatin1   The Latin-1 string.
+ */
+DECLINLINE(RTUNICP) RTLatin1GetCp(const char *pszLatin1)
+{
+    return *(const unsigned char *)pszLatin1;
+}
+
+/**
+ * Get the unicode code point at the given string position.
+ *
+ * @returns iprt status code.
+ * @param   ppszLatin1  Pointer to the string pointer. This will be updated to
+ *                      point to the char following the current code point. This
+ *                      is advanced one character forward on failure.
+ * @param   pCp         Where to store the code point. RTUNICP_INVALID is stored
+ *                      here on failure.
+ */
+DECLINLINE(int) RTLatin1GetCpEx(const char **ppszLatin1, PRTUNICP pCp)
+{
+    const unsigned char uch = **(const unsigned char **)ppszLatin1;
+    (*ppszLatin1)++;
+    *pCp = uch;
+    return VINF_SUCCESS;
+}
+
+/**
+ * Get the unicode code point at the given string position for a string of a
+ * given maximum length.
+ *
+ * @returns iprt status code.
+ * @retval  VERR_END_OF_STRING if *pcch is 0. *pCp is set to RTUNICP_INVALID.
+ *
+ * @param   ppszLatin1  Pointer to the string pointer. This will be updated to
+ *                      point to the char following the current code point.
+ * @param   pcchLatin1  Pointer to the maximum string length.  This will be
+ *                      decremented by the size of the code point found.
+ * @param   pCp         Where to store the code point.
+ *                      RTUNICP_INVALID is stored here on failure.
+ */
+DECLINLINE(int) RTLatin1GetCpNEx(const char **ppszLatin1, size_t *pcchLatin1, PRTUNICP pCp)
+{
+    if (RT_LIKELY(*pcchLatin1 != 0))
+    {
+        const unsigned char uch = **(const unsigned char **)ppszLatin1;
+        (*ppszLatin1)++;
+        (*pcchLatin1)--;
+        *pCp = uch;
+        return VINF_SUCCESS;
+    }
+    *pCp = RTUNICP_INVALID;
+    return VERR_END_OF_STRING;
+}
+
+/**
+ * Get the Latin-1 size in characters of a given Unicode code point.
+ *
+ * The code point is expected to be a valid Unicode one, but not necessarily in
+ * the range supported by Latin-1.
+ *
+ * @returns the size in characters, or zero if there is no Latin-1 encoding
+ */
+DECLINLINE(size_t) RTLatin1CpSize(RTUNICP CodePoint)
+{
+    if (CodePoint < 0x100)
+        return 1;
+    return 0;
+}
+
+/**
+ * Put the unicode code point at the given string position
+ * and return the pointer to the char following it.
+ *
+ * This function will not consider anything at or following the
+ * buffer area pointed to by psz. It is therefore not suitable for
+ * inserting code points into a string, only appending/overwriting.
+ *
+ * @returns pointer to the char following the written code point.
+ * @param   pszLatin1   The string.
+ * @param   CodePoint   The code point to write.
+ *                      This should not be RTUNICP_INVALID or any other
+ *                      character out of the Latin-1 range.
+ */
+DECLINLINE(char *) RTLatin1PutCp(char *pszLatin1, RTUNICP CodePoint)
+{
+    AssertReturn(CodePoint < 0x100, NULL);
+    *pszLatin1++ = (unsigned char)CodePoint;
+    return pszLatin1;
+}
+
+/**
+ * Skips ahead, past the current code point.
+ *
+ * @returns Pointer to the char after the current code point.
+ * @param   pszLatin1   Pointer to the current code point.
+ * @remark  This will not move the next valid code point, only past the current one.
+ */
+DECLINLINE(char *) RTLatin1NextCp(const char *pszLatin1)
+{
+    pszLatin1++;
+    return (char *)pszLatin1;
+}
+
+/**
+ * Skips back to the previous code point.
+ *
+ * @returns Pointer to the char before the current code point.
+ * @returns pszLatin1Start on failure.
+ * @param   pszLatin1Start  Pointer to the start of the string.
+ * @param   pszLatin1       Pointer to the current code point.
+ */
+DECLINLINE(char *) RTLatin1PrevCp(const char *pszLatin1Start, const char *pszLatin1)
+{
+    if ((uintptr_t)pszLatin1 > (uintptr_t)pszLatin1Start)
+    {
+        pszLatin1--;
+        return (char *)pszLatin1;
+    }
+    return (char *)pszLatin1Start;
+}
+
+/**
+ * Translate a Latin1 string into a UTF-8 allocating the result buffer (default
+ * tag).
+ *
+ * @returns iprt status code.
+ * @param   pszLatin1       Latin1 string to convert.
+ * @param   ppszString      Receives pointer of allocated UTF-8 string on
+ *                          success, and is always set to NULL on failure.
+ *                          The returned pointer must be freed using RTStrFree().
+ */
+#define RTLatin1ToUtf8(pszLatin1, ppszString)       RTLatin1ToUtf8Tag((pszLatin1), (ppszString), RTSTR_TAG)
+
+/**
+ * Translate a Latin-1 string into a UTF-8 allocating the result buffer.
+ *
+ * @returns iprt status code.
+ * @param   pszLatin1       Latin-1 string to convert.
+ * @param   ppszString      Receives pointer of allocated UTF-8 string on
+ *                          success, and is always set to NULL on failure.
+ *                          The returned pointer must be freed using RTStrFree().
+ * @param   pszTag          Allocation tag used for statistics and such.
+ */
+RTDECL(int)  RTLatin1ToUtf8Tag(const char *pszLatin1, char **ppszString, const char *pszTag);
+
+/**
+ * Translates Latin-1 to UTF-8 using buffer provided by the caller or a fittingly
+ * sized buffer allocated by the function (default tag).
+ *
+ * @returns iprt status code.
+ * @param   pszLatin1       The Latin-1 string to convert.
+ * @param   cchLatin1       The number of Latin-1 characters to translate from
+ *                          pszLatin1. The translation will stop when reaching
+ *                          cchLatin1 or the terminator ('\\0').  Use RTSTR_MAX
+ *                          to translate the entire string.
+ * @param   ppsz            If @a cch is non-zero, this must either be pointing
+ *                          to a pointer to a buffer of the specified size, or
+ *                          pointer to a NULL pointer.  If *ppsz is NULL or
+ *                          @a cch is zero a buffer of at least @a cch chars
+ *                          will be allocated to hold the translated string. If
+ *                          a buffer was requested it must be freed using
+ *                          RTStrFree().
+ * @param   cch             The buffer size in chars (the type). This includes the terminator.
+ * @param   pcch            Where to store the length of the translated string,
+ *                          excluding the terminator. (Optional)
+ *
+ *                          This may be set under some error conditions,
+ *                          however, only for VERR_BUFFER_OVERFLOW and
+ *                          VERR_NO_STR_MEMORY will it contain a valid string
+ *                          length that can be used to resize the buffer.
+ */
+#define RTLatin1ToUtf8Ex(pszLatin1, cchLatin1, ppsz, cch, pcch) \
+    RTLatin1ToUtf8ExTag((pszLatin1), (cchLatin1), (ppsz), (cch), (pcch), RTSTR_TAG)
+
+/**
+ * Translates Latin1 to UTF-8 using buffer provided by the caller or a fittingly
+ * sized buffer allocated by the function (custom tag).
+ *
+ * @returns iprt status code.
+ * @param   pszLatin1       The Latin1 string to convert.
+ * @param   cchLatin1       The number of Latin1 characters to translate from
+ *                          pwszString.  The translation will stop when
+ *                          reaching cchLatin1 or the terminator ('\\0').  Use
+ *                          RTSTR_MAX to translate the entire string.
+ * @param   ppsz            If cch is non-zero, this must either be pointing to
+ *                          a pointer to a buffer of the specified size, or
+ *                          pointer to a NULL pointer.  If *ppsz is NULL or cch
+ *                          is zero a buffer of at least cch chars will be
+ *                          allocated to hold the translated string.  If a
+ *                          buffer was requested it must be freed using
+ *                          RTStrFree().
+ * @param   cch             The buffer size in chars (the type).  This includes
+ *                          the terminator.
+ * @param   pcch            Where to store the length of the translated string,
+ *                          excluding the terminator. (Optional)
+ *
+ *                          This may be set under some error conditions,
+ *                          however, only for VERR_BUFFER_OVERFLOW and
+ *                          VERR_NO_STR_MEMORY will it contain a valid string
+ *                          length that can be used to resize the buffer.
+ * @param   pszTag          Allocation tag used for statistics and such.
+ */
+RTDECL(int)  RTLatin1ToUtf8ExTag(const char *pszLatin1, size_t cchLatin1, char **ppsz, size_t cch, size_t *pcch,
+                                 const char *pszTag);
+
+/**
+ * Calculates the length of the Latin-1 string in UTF-8 chars (bytes).
+ *
+ * The primary purpose of this function is to help allocate buffers for
+ * RTLatin1ToUtf8() of the correct size. For most other purposes
+ * RTLatin1ToUtf8Ex() should be used.
+ *
+ * @returns Number of chars (bytes).
+ * @returns 0 if the string was incorrectly encoded.
+ * @param   pszLatin1     The Latin-1 string.
+ */
+RTDECL(size_t) RTLatin1CalcUtf8Len(const char *pszLatin1);
+
+/**
+ * Calculates the length of the Latin-1 string in UTF-8 chars (bytes).
+ *
+ * @returns iprt status code.
+ * @param   pszLatin1   The Latin-1 string.
+ * @param   cchLatin1   The max string length. Use RTSTR_MAX to process the
+ *                      entire string.
+ * @param   pcch        Where to store the string length (in bytes).  Optional.
+ *                      This is undefined on failure.
+ */
+RTDECL(int) RTLatin1CalcUtf8LenEx(const char *pszLatin1, size_t cchLatin1, size_t *pcch);
+
+/**
+ * Calculates the length of the Latin-1 (ISO-8859-1) string in RTUTF16 items.
+ *
+ * @returns Number of RTUTF16 items.
+ * @param   pszLatin1       The Latin-1 string.
+ */
+RTDECL(size_t) RTLatin1CalcUtf16Len(const char *pszLatin1);
+
+/**
+ * Calculates the length of the Latin-1 (ISO-8859-1) string in RTUTF16 items.
+ *
+ * @returns iprt status code.
+ * @param   pszLatin1       The Latin-1 string.
+ * @param   cchLatin1       The max string length. Use RTSTR_MAX to process the
+ *                          entire string.
+ * @param   pcwc            Where to store the string length. Optional.
+ *                          This is undefined on failure.
+ */
+RTDECL(int) RTLatin1CalcUtf16LenEx(const char *pszLatin1, size_t cchLatin1, size_t *pcwc);
+
+/**
+ * Translate a Latin-1 (ISO-8859-1) string into a UTF-16 allocating the result
+ * buffer (default tag).
+ *
+ * @returns iprt status code.
+ * @param   pszLatin1       The Latin-1 string to convert.
+ * @param   ppwszString     Receives pointer to the allocated UTF-16 string. The
+ *                          returned string must be freed using RTUtf16Free().
+ */
+#define RTLatin1ToUtf16(pszLatin1, ppwszString)     RTLatin1ToUtf16Tag((pszLatin1), (ppwszString), RTSTR_TAG)
+
+/**
+ * Translate a Latin-1 (ISO-8859-1) string into a UTF-16 allocating the result
+ * buffer (custom tag).
+ *
+ * @returns iprt status code.
+ * @param   pszLatin1       The Latin-1 string to convert.
+ * @param   ppwszString     Receives pointer to the allocated UTF-16 string. The
+ *                          returned string must be freed using RTUtf16Free().
+ * @param   pszTag          Allocation tag used for statistics and such.
+ */
+RTDECL(int) RTLatin1ToUtf16Tag(const char *pszLatin1, PRTUTF16 *ppwszString, const char *pszTag);
+
+/**
+ * Translates pszLatin1 from Latin-1 (ISO-8859-1) to UTF-16, allocating the
+ * result buffer if requested (default tag).
+ *
+ * @returns iprt status code.
+ * @param   pszLatin1       The Latin-1 string to convert.
+ * @param   cchLatin1       The maximum size in chars (the type) to convert. The
+ *                          conversion stops when it reaches cchLatin1 or the
+ *                          string terminator ('\\0'). Use RTSTR_MAX to
+ *                          translate the entire string.
+ * @param   ppwsz           If cwc is non-zero, this must either be pointing
+ *                          to pointer to a buffer of the specified size, or
+ *                          pointer to a NULL pointer.
+ *                          If *ppwsz is NULL or cwc is zero a buffer of at
+ *                          least cwc items will be allocated to hold the
+ *                          translated string. If a buffer was requested it
+ *                          must be freed using RTUtf16Free().
+ * @param   cwc             The buffer size in RTUTF16s. This includes the
+ *                          terminator.
+ * @param   pcwc            Where to store the length of the translated string,
+ *                          excluding the terminator. (Optional)
+ *
+ *                          This may be set under some error conditions,
+ *                          however, only for VERR_BUFFER_OVERFLOW and
+ *                          VERR_NO_STR_MEMORY will it contain a valid string
+ *                          length that can be used to resize the buffer.
+ */
+#define RTLatin1ToUtf16Ex(pszLatin1, cchLatin1, ppwsz, cwc, pcwc) \
+    RTLatin1ToUtf16ExTag((pszLatin1), (cchLatin1), (ppwsz), (cwc), (pcwc), RTSTR_TAG)
+
+/**
+ * Translates pszLatin1 from Latin-1 (ISO-8859-1) to UTF-16, allocating the
+ * result buffer if requested.
+ *
+ * @returns iprt status code.
+ * @param   pszLatin1       The Latin-1 string to convert.
+ * @param   cchLatin1       The maximum size in chars (the type) to convert. The
+ *                          conversion stops when it reaches cchLatin1 or the
+ *                          string terminator ('\\0'). Use RTSTR_MAX to
+ *                          translate the entire string.
+ * @param   ppwsz           If cwc is non-zero, this must either be pointing
+ *                          to pointer to a buffer of the specified size, or
+ *                          pointer to a NULL pointer.
+ *                          If *ppwsz is NULL or cwc is zero a buffer of at
+ *                          least cwc items will be allocated to hold the
+ *                          translated string. If a buffer was requested it
+ *                          must be freed using RTUtf16Free().
+ * @param   cwc             The buffer size in RTUTF16s. This includes the
+ *                          terminator.
+ * @param   pcwc            Where to store the length of the translated string,
+ *                          excluding the terminator. (Optional)
+ *
+ *                          This may be set under some error conditions,
+ *                          however, only for VERR_BUFFER_OVERFLOW and
+ *                          VERR_NO_STR_MEMORY will it contain a valid string
+ *                          length that can be used to resize the buffer.
+ * @param   pszTag          Allocation tag used for statistics and such.
+ */
+RTDECL(int) RTLatin1ToUtf16ExTag(const char *pszLatin1, size_t cchLatin1,
+                                 PRTUTF16 *ppwsz, size_t cwc, size_t *pcwc, const char *pszTag);
+
+/** @} */
+
+RT_C_DECLS_END
+
+/** @} */
+
+#endif
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/include/iprt/list.h
@@ -0,0 +1,448 @@
+/** @file
+ * IPRT - Generic Doubly Linked List.
+ */
+
+/*
+ * Copyright (C) 2010-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+#ifndef ___iprt_list_h
+#define ___iprt_list_h
+
+#include <iprt/types.h>
+
+/** @defgroup grp_rt_list    RTList - Generic Doubly Linked List
+ * @ingroup grp_rt
+ *
+ * The list implementation is circular without any type wise distintion between
+ * the list and its nodes.  This can be confusing since the list head usually
+ * resides in a different structure than the nodes, so care must be taken when
+ * walking the list.
+ *
+ * @{
+ */
+
+RT_C_DECLS_BEGIN
+
+/**
+ * A list node of a doubly linked list.
+ */
+typedef struct RTLISTNODE
+{
+    /** Pointer to the next list node. */
+    struct RTLISTNODE *pNext;
+    /** Pointer to the previous list node. */
+    struct RTLISTNODE *pPrev;
+} RTLISTNODE;
+/** Pointer to a list node. */
+typedef RTLISTNODE *PRTLISTNODE;
+/** Pointer to a const list node. */
+typedef RTLISTNODE const *PCRTLISTNODE;
+/** Pointer to a list node pointer. */
+typedef PRTLISTNODE *PPRTLISTNODE;
+
+/** The anchor (head/tail) of a doubly linked list.
+ *
+ * @remarks Please use this instead of RTLISTNODE to indicate a list
+ *          head/tail.  It makes the code so much easier to read.  Also,
+ *          always mention the actual list node type(s) in the comment.  */
+typedef RTLISTNODE RTLISTANCHOR;
+/** Pointer to a doubly linked list anchor. */
+typedef RTLISTANCHOR *PRTLISTANCHOR;
+/** Pointer to a const doubly linked list anchor. */
+typedef RTLISTANCHOR const *PCRTLISTANCHOR;
+
+/** Version of RTLISTNODE for holding a ring-3 only list in data which gets
+ * shared between multiple contexts */
+#if defined(IN_RING3)
+typedef RTLISTNODE RTLISTNODER3;
+#else
+typedef struct { RTR3PTR aOffLimits[2]; } RTLISTNODER3;
+#endif
+/** Version of RTLISTANCHOR for holding a ring-3 only list in data which gets
+ * shared between multiple contexts */
+typedef RTLISTNODER3 RTLISTANCHORR3;
+
+
+/**
+ * Initialize a list.
+ *
+ * @param   pList               Pointer to an unitialised list.
+ */
+DECLINLINE(void) RTListInit(PRTLISTNODE pList)
+{
+    pList->pNext = pList;
+    pList->pPrev = pList;
+}
+
+/**
+ * Append a node to the end of the list.
+ *
+ * @param   pList               The list to append the node to.
+ * @param   pNode               The node to append.
+ */
+DECLINLINE(void) RTListAppend(PRTLISTNODE pList, PRTLISTNODE pNode)
+{
+    pList->pPrev->pNext = pNode;
+    pNode->pPrev        = pList->pPrev;
+    pNode->pNext        = pList;
+    pList->pPrev        = pNode;
+}
+
+/**
+ * Add a node as the first element of the list.
+ *
+ * @param   pList               The list to prepend the node to.
+ * @param   pNode               The node to prepend.
+ */
+DECLINLINE(void) RTListPrepend(PRTLISTNODE pList, PRTLISTNODE pNode)
+{
+    pList->pNext->pPrev = pNode;
+    pNode->pNext        = pList->pNext;
+    pNode->pPrev        = pList;
+    pList->pNext        = pNode;
+}
+
+/**
+ * Inserts a node after the specified one.
+ *
+ * @param   pCurNode            The current node.
+ * @param   pNewNode            The node to insert.
+ */
+DECLINLINE(void) RTListNodeInsertAfter(PRTLISTNODE pCurNode, PRTLISTNODE pNewNode)
+{
+    RTListPrepend(pCurNode, pNewNode);
+}
+
+/**
+ * Inserts a node before the specified one.
+ *
+ * @param   pCurNode            The current node.
+ * @param   pNewNode            The node to insert.
+ */
+DECLINLINE(void) RTListNodeInsertBefore(PRTLISTNODE pCurNode, PRTLISTNODE pNewNode)
+{
+    RTListAppend(pCurNode, pNewNode);
+}
+
+/**
+ * Remove a node from a list.
+ *
+ * @param   pNode               The node to remove.
+ */
+DECLINLINE(void) RTListNodeRemove(PRTLISTNODE pNode)
+{
+    PRTLISTNODE pPrev = pNode->pPrev;
+    PRTLISTNODE pNext = pNode->pNext;
+
+    pPrev->pNext = pNext;
+    pNext->pPrev = pPrev;
+
+    /* poison */
+    pNode->pNext = NULL;
+    pNode->pPrev = NULL;
+}
+
+/**
+ * Checks if a node is the last element in the list.
+ *
+ * @retval  true if the node is the last element in the list.
+ * @retval  false otherwise
+ *
+ * @param   pList               The list.
+ * @param   pNode               The node to check.
+ */
+#define RTListNodeIsLast(pList, pNode)  ((pNode)->pNext == (pList))
+
+/**
+ * Checks if a node is the first element in the list.
+ *
+ * @retval  true if the node is the first element in the list.
+ * @retval  false otherwise.
+ *
+ * @param   pList               The list.
+ * @param   pNode               The node to check.
+ */
+#define RTListNodeIsFirst(pList, pNode) ((pNode)->pPrev == (pList))
+
+/**
+ * Checks if a type converted node is actually the dummy element (@a pList).
+ *
+ * @retval  true if the node is the dummy element in the list.
+ * @retval  false otherwise.
+ *
+ * @param   pList               The list.
+ * @param   pNode               The node structure to check.  Typically
+ *                              something obtained from RTListNodeGetNext() or
+ *                              RTListNodeGetPrev().  This is NOT a PRTLISTNODE
+ *                              but something that contains a RTLISTNODE member!
+ * @param   Type                Structure the list node is a member of.
+ * @param   Member              The list node member.
+ */
+#define RTListNodeIsDummy(pList, pNode, Type, Member) \
+         ( (pNode) == RT_FROM_MEMBER((pList), Type, Member) )
+/** @copydoc RTListNodeIsDummy */
+#define RTListNodeIsDummyCpp(pList, pNode, Type, Member) \
+         ( (pNode) == RT_FROM_CPP_MEMBER((pList), Type, Member) )
+
+/**
+ * Checks if a list is empty.
+ *
+ * @retval  true if the list is empty.
+ * @retval  false otherwise.
+ *
+ * @param   pList               The list to check.
+ */
+#define RTListIsEmpty(pList)            ((pList)->pPrev == (pList))
+
+/**
+ * Returns the next node in the list.
+ *
+ * @returns The next node.
+ *
+ * @param   pCurNode            The current node.
+ * @param   Type                Structure the list node is a member of.
+ * @param   Member              The list node member.
+ */
+#define RTListNodeGetNext(pCurNode, Type, Member) \
+    RT_FROM_MEMBER((pCurNode)->pNext, Type, Member)
+/** @copydoc RTListNodeGetNext */
+#define RTListNodeGetNextCpp(pCurNode, Type, Member) \
+    RT_FROM_CPP_MEMBER((pCurNode)->pNext, Type, Member)
+
+/**
+ * Returns the previous node in the list.
+ *
+ * @returns The previous node.
+ *
+ * @param   pCurNode            The current node.
+ * @param   Type                Structure the list node is a member of.
+ * @param   Member              The list node member.
+ */
+#define RTListNodeGetPrev(pCurNode, Type, Member) \
+    RT_FROM_MEMBER((pCurNode)->pPrev, Type, Member)
+/** @copydoc RTListNodeGetPrev */
+#define RTListNodeGetPrevCpp(pCurNode, Type, Member) \
+    RT_FROM_CPP_MEMBER((pCurNode)->pPrev, Type, Member)
+
+/**
+ * Returns the first element in the list (checks for empty list).
+ *
+ * @retval  Pointer to the first list element.
+ * @retval  NULL if the list is empty.
+ *
+ * @param   pList               List to get the first element from.
+ * @param   Type                Structure the list node is a member of.
+ * @param   Member              The list node member.
+ */
+#define RTListGetFirst(pList, Type, Member) \
+    (!RTListIsEmpty(pList) ? RTListNodeGetNext(pList, Type, Member) : NULL)
+/** @copydoc RTListGetFirst */
+#define RTListGetFirstCpp(pList, Type, Member) \
+    (!RTListIsEmpty(pList) ? RTListNodeGetNextCpp(pList, Type, Member) : NULL)
+
+/**
+ * Returns the last element in the list (checks for empty list).
+ *
+ * @retval  Pointer to the last list element.
+ * @retval  NULL if the list is empty.
+ *
+ * @param   pList               List to get the last element from.
+ * @param   Type                Structure the list node is a member of.
+ * @param   Member              The list node member.
+ */
+#define RTListGetLast(pList, Type, Member) \
+    (!RTListIsEmpty(pList) ? RTListNodeGetPrev(pList, Type, Member) : NULL)
+/** @copydoc RTListGetLast */
+#define RTListGetLastCpp(pList, Type, Member) \
+    (!RTListIsEmpty(pList) ? RTListNodeGetPrevCpp(pList, Type, Member) : NULL)
+
+/**
+ * Returns the next node in the list or NULL if the end has been reached.
+ *
+ * @returns The next node or NULL.
+ *
+ * @param   pList               The list @a pCurNode is linked on.
+ * @param   pCurNode            The current node, of type @a Type.
+ * @param   Type                Structure the list node is a member of.
+ * @param   Member              The list node member.
+ */
+#define RTListGetNext(pList, pCurNode, Type, Member) \
+    ( (pCurNode)->Member.pNext != (pList) ? RT_FROM_MEMBER((pCurNode)->Member.pNext, Type, Member) : NULL )
+/** @copydoc RTListGetNext */
+#define RTListGetNextCpp(pList, pCurNode, Type, Member) \
+    ( (pCurNode)->Member.pNext != (pList) ? RT_FROM_CPP_MEMBER((pCurNode)->Member.pNext, Type, Member) : NULL )
+
+/**
+ * Returns the previous node in the list or NULL if the start has been reached.
+ *
+ * @returns The previous node or NULL.
+ *
+ * @param   pList               The list @a pCurNode is linked on.
+ * @param   pCurNode            The current node, of type @a Type.
+ * @param   Type                Structure the list node is a member of.
+ * @param   Member              The list node member.
+ */
+#define RTListGetPrev(pList, pCurNode, Type, Member) \
+    ( (pCurNode)->Member.pPrev != (pList) ? RT_FROM_MEMBER((pCurNode)->Member.pPrev, Type, Member) : NULL )
+/** @copydoc RTListGetPrev */
+#define RTListGetPrevCpp(pList, pCurNode, Type, Member) \
+    ( (pCurNode)->Member.pPrev != (pList) ? RT_FROM_CPP_MEMBER((pCurNode)->Member.pPrev, Type, Member) : NULL )
+
+/**
+ * Enumerate the list in head to tail order.
+ *
+ * @param   pList               List to enumerate.
+ * @param   pIterator           The iterator variable name.
+ * @param   Type                Structure the list node is a member of.
+ * @param   Member              The list node member name.
+ */
+#define RTListForEach(pList, pIterator, Type, Member) \
+    for (pIterator = RTListNodeGetNext(pList, Type, Member); \
+         !RTListNodeIsDummy(pList, pIterator, Type, Member); \
+         pIterator = RT_FROM_MEMBER((pIterator)->Member.pNext, Type, Member) )
+/** @copydoc RTListForEach */
+#define RTListForEachCpp(pList, pIterator, Type, Member) \
+    for (pIterator = RTListNodeGetNextCpp(pList, Type, Member); \
+         !RTListNodeIsDummyCpp(pList, pIterator, Type, Member); \
+         pIterator = RT_FROM_CPP_MEMBER((pIterator)->Member.pNext, Type, Member) )
+
+
+/**
+ * Enumerate the list in head to tail order, safe against removal of the
+ * current node.
+ *
+ * @param   pList               List to enumerate.
+ * @param   pIterator           The iterator variable name.
+ * @param   pIterNext           The name of the variable saving the pointer to
+ *                              the next element.
+ * @param   Type                Structure the list node is a member of.
+ * @param   Member              The list node member name.
+ */
+#define RTListForEachSafe(pList, pIterator, pIterNext, Type, Member) \
+    for (pIterator = RTListNodeGetNext(pList, Type, Member), \
+         pIterNext = RT_FROM_MEMBER((pIterator)->Member.pNext, Type, Member); \
+         !RTListNodeIsDummy(pList, pIterator, Type, Member); \
+         pIterator = pIterNext, \
+         pIterNext = RT_FROM_MEMBER((pIterator)->Member.pNext, Type, Member) )
+/** @copydoc RTListForEachSafe */
+#define RTListForEachSafeCpp(pList, pIterator, pIterNext, Type, Member) \
+    for (pIterator = RTListNodeGetNextCpp(pList, Type, Member), \
+         pIterNext = RT_FROM_CPP_MEMBER((pIterator)->Member.pNext, Type, Member); \
+         !RTListNodeIsDummyCpp(pList, pIterator, Type, Member); \
+         pIterator = pIterNext, \
+         pIterNext = RT_FROM_CPP_MEMBER((pIterator)->Member.pNext, Type, Member) )
+
+
+/**
+ * Enumerate the list in reverse order (tail to head).
+ *
+ * @param   pList               List to enumerate.
+ * @param   pIterator           The iterator variable name.
+ * @param   Type                Structure the list node is a member of.
+ * @param   Member              The list node member name.
+ */
+#define RTListForEachReverse(pList, pIterator, Type, Member) \
+    for (pIterator = RTListNodeGetPrev(pList, Type, Member); \
+         !RTListNodeIsDummy(pList, pIterator, Type, Member); \
+         pIterator = RT_FROM_MEMBER((pIterator)->Member.pPrev, Type, Member) )
+/** @copydoc RTListForEachReverse */
+#define RTListForEachReverseCpp(pList, pIterator, Type, Member) \
+    for (pIterator = RTListNodeGetPrevCpp(pList, Type, Member); \
+         !RTListNodeIsDummyCpp(pList, pIterator, Type, Member); \
+         pIterator = RT_FROM_CPP_MEMBER((pIterator)->Member.pPrev, Type, Member) )
+
+
+/**
+ * Enumerate the list in reverse order (tail to head).
+ *
+ * @param   pList               List to enumerate.
+ * @param   pIterator           The iterator variable name.
+ * @param   pIterPrev           The name of the variable saving the pointer to
+ *                              the previous element.
+ * @param   Type                Structure the list node is a member of.
+ * @param   Member              The list node member name.
+ */
+#define RTListForEachReverseSafe(pList, pIterator, pIterPrev, Type, Member) \
+    for (pIterator = RTListNodeGetPrev(pList, Type, Member), \
+         pIterPrev = RT_FROM_MEMBER((pIterator)->Member.pPrev, Type, Member); \
+         !RTListNodeIsDummy(pList, pIterator, Type, Member); \
+         pIterator = pIterPrev, \
+         pIterPrev = RT_FROM_MEMBER((pIterator)->Member.pPrev, Type, Member) )
+/** @copydoc RTListForEachReverseSafe */
+#define RTListForEachReverseSafeCpp(pList, pIterator, pIterPrev, Type, Member) \
+    for (pIterator = RTListNodeGetPrevCpp(pList, Type, Member), \
+         pIterPrev = RT_FROM_CPP_MEMBER((pIterator)->Member.pPrev, Type, Member); \
+         !RTListNodeIsDummyCpp(pList, pIterator, Type, Member); \
+         pIterator = pIterPrev, \
+         pIterPrev = RT_FROM_CPP_MEMBER((pIterator)->Member.pPrev, Type, Member) )
+
+
+/**
+ * Move the given list to a new list header.
+ *
+ * @param   pListDst            The new list.
+ * @param   pListSrc            The list to move.
+ */
+DECLINLINE(void) RTListMove(PRTLISTNODE pListDst, PRTLISTNODE pListSrc)
+{
+    if (!RTListIsEmpty(pListSrc))
+    {
+        pListDst->pNext = pListSrc->pNext;
+        pListDst->pPrev = pListSrc->pPrev;
+
+        /* Adjust the first and last element links */
+        pListDst->pNext->pPrev = pListDst;
+        pListDst->pPrev->pNext = pListDst;
+
+        /* Finally remove the elements from the source list */
+        RTListInit(pListSrc);
+    }
+}
+
+/**
+ * List concatenation.
+ *
+ * @returns nothing.
+ * @param   pListDst            The destination list.
+ * @param   pListSrc            The source list to concatenate.
+ */
+DECLINLINE(void) RTListConcatenate(PRTLISTANCHOR pListDst, PRTLISTANCHOR pListSrc)
+{
+    if (!RTListIsEmpty(pListSrc))
+    {
+        PRTLISTNODE pFirst = pListSrc->pNext;
+        PRTLISTNODE pLast = pListSrc->pPrev;
+
+        pListDst->pPrev->pNext = pFirst;
+        pFirst->pPrev          = pListDst->pPrev;
+        pLast->pNext           = pListDst;
+        pListDst->pPrev        = pLast;
+
+        /* Finally remove the elements from the source list */
+        RTListInit(pListSrc);
+    }
+}
+
+RT_C_DECLS_END
+
+/** @} */
+
+#endif
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/include/iprt/lockvalidator.h
@@ -0,0 +1,1130 @@
+/** @file
+ * IPRT - Lock Validator.
+ */
+
+/*
+ * Copyright (C) 2009-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+#ifndef ___iprt_lockvalidator_h
+#define ___iprt_lockvalidator_h
+
+#include <iprt/cdefs.h>
+#include <iprt/types.h>
+#include <iprt/assert.h>
+#include <iprt/thread.h>
+#include <iprt/stdarg.h>
+
+
+/** @defgroup grp_rtlockval     RTLockValidator - Lock Validator
+ * @ingroup grp_rt
+ * @{
+ */
+
+RT_C_DECLS_BEGIN
+
+/** Pointer to a record union.
+ * @internal  */
+typedef union RTLOCKVALRECUNION *PRTLOCKVALRECUNION;
+
+/**
+ * Source position.
+ */
+typedef struct RTLOCKVALSRCPOS
+{
+    /** The file where the lock was taken. */
+    R3R0PTRTYPE(const char * volatile)  pszFile;
+    /** The function where the lock was taken. */
+    R3R0PTRTYPE(const char * volatile)  pszFunction;
+    /** Some ID indicating where the lock was taken, typically an address. */
+    RTHCUINTPTR volatile                uId;
+    /** The line number in the file. */
+    uint32_t volatile                   uLine;
+#if HC_ARCH_BITS == 64
+    uint32_t                            u32Padding; /**< Alignment padding. */
+#endif
+} RTLOCKVALSRCPOS;
+AssertCompileSize(RTLOCKVALSRCPOS, HC_ARCH_BITS == 32 ? 16 : 32);
+/* The pointer types are defined in iprt/types.h. */
+
+/** @def RTLOCKVALSRCPOS_INIT
+ * Initializer for a RTLOCKVALSRCPOS variable.
+ *
+ * @param   pszFile         The file name.  Optional (NULL).
+ * @param   uLine           The line number in that file. Optional (0).
+ * @param   pszFunction     The function.  Optional (NULL).
+ * @param   uId             Some location ID, normally the return address.
+ *                          Optional (NULL).
+ */
+#if HC_ARCH_BITS == 64
+# define RTLOCKVALSRCPOS_INIT(pszFile, uLine, pszFunction, uId) \
+    { (pszFile), (pszFunction), (uId), (uLine), 0 }
+#else
+# define RTLOCKVALSRCPOS_INIT(pszFile, uLine, pszFunction, uId) \
+    { (pszFile), (pszFunction), (uId), (uLine) }
+#endif
+
+/** @def RTLOCKVALSRCPOS_INIT_DEBUG_API
+ * Initializer for a RTLOCKVALSRCPOS variable in a typicial debug API
+ * variant.  Assumes RT_SRC_POS_DECL and RTHCUINTPTR uId as arguments.
+ */
+#define RTLOCKVALSRCPOS_INIT_DEBUG_API()  \
+    RTLOCKVALSRCPOS_INIT(pszFile, iLine, pszFunction, uId)
+
+/** @def RTLOCKVALSRCPOS_INIT_NORMAL_API
+ * Initializer for a RTLOCKVALSRCPOS variable in a normal API
+ * variant.  Assumes iprt/asm.h is included.
+ */
+#define RTLOCKVALSRCPOS_INIT_NORMAL_API() \
+    RTLOCKVALSRCPOS_INIT(__FILE__, __LINE__, __PRETTY_FUNCTION__, (uintptr_t)ASMReturnAddress())
+
+/** @def RTLOCKVALSRCPOS_INIT_POS_NO_ID
+ * Initializer for a RTLOCKVALSRCPOS variable when no @c uId is present.
+ * Assumes iprt/asm.h is included.
+ */
+#define RTLOCKVALSRCPOS_INIT_POS_NO_ID() \
+    RTLOCKVALSRCPOS_INIT(pszFile, iLine, pszFunction, (uintptr_t)ASMReturnAddress())
+
+
+/**
+ * Lock validator record core.
+ */
+typedef struct RTLOCKVALRECORE
+{
+    /** The magic value indicating the record type. */
+    uint32_t volatile                   u32Magic;
+} RTLOCKVALRECCORE;
+/** Pointer to a lock validator record core. */
+typedef RTLOCKVALRECCORE *PRTLOCKVALRECCORE;
+/** Pointer to a const lock validator record core. */
+typedef RTLOCKVALRECCORE const *PCRTLOCKVALRECCORE;
+
+
+/**
+ * Record recording the exclusive ownership of a lock.
+ *
+ * This is typically part of the per-lock data structure when compiling with
+ * the lock validator.
+ */
+typedef struct RTLOCKVALRECEXCL
+{
+    /** Record core with RTLOCKVALRECEXCL_MAGIC as the magic value. */
+    RTLOCKVALRECCORE                    Core;
+    /** Whether it's enabled or not. */
+    bool                                fEnabled;
+    /** Reserved. */
+    bool                                afReserved[3];
+    /** Source position where the lock was taken. */
+    RTLOCKVALSRCPOS                     SrcPos;
+    /** The current owner thread. */
+    RTTHREAD volatile                   hThread;
+    /** Pointer to the lock record below us. Only accessed by the owner. */
+    R3R0PTRTYPE(PRTLOCKVALRECUNION)     pDown;
+    /** Recursion count */
+    uint32_t                            cRecursion;
+    /** The lock sub-class. */
+    uint32_t volatile                   uSubClass;
+    /** The lock class. */
+    RTLOCKVALCLASS                      hClass;
+    /** Pointer to the lock. */
+    RTHCPTR                             hLock;
+    /** Pointer to the next sibling record.
+     * This is used to find the read side of a read-write lock.  */
+    R3R0PTRTYPE(PRTLOCKVALRECUNION)     pSibling;
+    /** The lock name.
+     * @remarks The bytes beyond 32 are for better size alignment and can be
+     *          taken and used for other purposes if it becomes necessary. */
+    char                                szName[32 + (HC_ARCH_BITS == 32 ? 12 : 8)];
+} RTLOCKVALRECEXCL;
+AssertCompileSize(RTLOCKVALRECEXCL, HC_ARCH_BITS == 32 ? 0x60 : 0x80);
+/* The pointer type is defined in iprt/types.h. */
+
+/**
+ * For recording the one ownership share.
+ */
+typedef struct RTLOCKVALRECSHRDOWN
+{
+    /** Record core with RTLOCKVALRECSHRDOWN_MAGIC as the magic value. */
+    RTLOCKVALRECCORE                    Core;
+    /** Recursion count */
+    uint16_t                            cRecursion;
+    /** Static (true) or dynamic (false) allocated record. */
+    bool                                fStaticAlloc;
+    /** Reserved. */
+    bool                                fReserved;
+    /** The current owner thread. */
+    RTTHREAD volatile                   hThread;
+    /** Pointer to the lock record below us. Only accessed by the owner. */
+    R3R0PTRTYPE(PRTLOCKVALRECUNION)     pDown;
+    /** Pointer back to the shared record. */
+    R3R0PTRTYPE(PRTLOCKVALRECSHRD)      pSharedRec;
+#if HC_ARCH_BITS == 32
+    /** Reserved. */
+    RTHCPTR                             pvReserved;
+#endif
+    /** Source position where the lock was taken. */
+    RTLOCKVALSRCPOS                     SrcPos;
+} RTLOCKVALRECSHRDOWN;
+AssertCompileSize(RTLOCKVALRECSHRDOWN, HC_ARCH_BITS == 32 ? 24 + 16 : 32 + 32);
+/** Pointer to a RTLOCKVALRECSHRDOWN. */
+typedef RTLOCKVALRECSHRDOWN *PRTLOCKVALRECSHRDOWN;
+
+/**
+ * Record recording the shared ownership of a lock.
+ *
+ * This is typically part of the per-lock data structure when compiling with
+ * the lock validator.
+ */
+typedef struct RTLOCKVALRECSHRD
+{
+    /** Record core with RTLOCKVALRECSHRD_MAGIC as the magic value. */
+    RTLOCKVALRECCORE                    Core;
+    /** The lock sub-class. */
+    uint32_t volatile                   uSubClass;
+    /** The lock class. */
+    RTLOCKVALCLASS                      hClass;
+    /** Pointer to the lock. */
+    RTHCPTR                             hLock;
+    /** Pointer to the next sibling record.
+     * This is used to find the write side of a read-write lock.  */
+    R3R0PTRTYPE(PRTLOCKVALRECUNION)     pSibling;
+
+    /** The number of entries in the table.
+     * Updated before inserting and after removal. */
+    uint32_t volatile                   cEntries;
+    /** The index of the last entry (approximately). */
+    uint32_t volatile                   iLastEntry;
+    /** The max table size. */
+    uint32_t volatile                   cAllocated;
+    /** Set if the table is being reallocated, clear if not.
+     * This is used together with rtLockValidatorSerializeDetectionEnter to make
+     * sure there is exactly one thread doing the reallocation and that nobody is
+     * using the table at that point. */
+    bool volatile                       fReallocating;
+    /** Whether it's enabled or not. */
+    bool                                fEnabled;
+    /** Set if event semaphore signaller, clear if read-write semaphore. */
+    bool                                fSignaller;
+    /** Alignment padding. */
+    bool                                fPadding;
+    /** Pointer to a table containing pointers to records of all the owners. */
+    R3R0PTRTYPE(PRTLOCKVALRECSHRDOWN volatile *) papOwners;
+
+    /** The lock name.
+     * @remarks The bytes beyond 32 are for better size alignment and can be
+     *          taken and used for other purposes if it becomes necessary. */
+    char                                szName[32 + (HC_ARCH_BITS == 32 ? 8 : 8)];
+} RTLOCKVALRECSHRD;
+AssertCompileSize(RTLOCKVALRECSHRD, HC_ARCH_BITS == 32 ? 0x50 : 0x60);
+
+
+/**
+ * Makes the two records siblings.
+ *
+ * @returns VINF_SUCCESS on success, VERR_SEM_LV_INVALID_PARAMETER if either of
+ *          the records are invalid.
+ * @param   pRec1               Record 1.
+ * @param   pRec2               Record 2.
+ */
+RTDECL(int) RTLockValidatorRecMakeSiblings(PRTLOCKVALRECCORE pRec1, PRTLOCKVALRECCORE pRec2);
+
+/**
+ * Initialize a lock validator record.
+ *
+ * Use RTLockValidatorRecExclDelete to deinitialize it.
+ *
+ * @param   pRec                The record.
+ * @param   hClass              The class (no reference consumed). If NIL, the
+ *                              no lock order validation will be performed on
+ *                              this lock.
+ * @param   uSubClass           The sub-class.  This is used to define lock
+ *                              order inside the same class.  If you don't know,
+ *                              then pass RTLOCKVAL_SUB_CLASS_NONE.
+ * @param   hLock               The lock handle.
+ * @param   fEnabled            Pass @c false to explicitly disable lock
+ *                              validation, otherwise @c true.
+ * @param   pszNameFmt          Name format string for the lock validator,
+ *                              optional (NULL). Max length is 32 bytes.
+ * @param   ...                 Format string arguments.
+ */
+RTDECL(void) RTLockValidatorRecExclInit(PRTLOCKVALRECEXCL pRec, RTLOCKVALCLASS hClass, uint32_t uSubClass, void *hLock,
+                                        bool fEnabled, const char *pszNameFmt, ...) RT_IPRT_FORMAT_ATTR_MAYBE_NULL(6, 7);
+/**
+ * Initialize a lock validator record.
+ *
+ * Use RTLockValidatorRecExclDelete to deinitialize it.
+ *
+ * @param   pRec                The record.
+ * @param   hClass              The class (no reference consumed). If NIL, the
+ *                              no lock order validation will be performed on
+ *                              this lock.
+ * @param   uSubClass           The sub-class.  This is used to define lock
+ *                              order inside the same class.  If you don't know,
+ *                              then pass RTLOCKVAL_SUB_CLASS_NONE.
+ * @param   hLock               The lock handle.
+ * @param   fEnabled            Pass @c false to explicitly disable lock
+ *                              validation, otherwise @c true.
+ * @param   pszNameFmt          Name format string for the lock validator,
+ *                              optional (NULL). Max length is 32 bytes.
+ * @param   va                  Format string arguments.
+ */
+RTDECL(void) RTLockValidatorRecExclInitV(PRTLOCKVALRECEXCL pRec, RTLOCKVALCLASS hClass, uint32_t uSubClass, void *hLock,
+                                         bool fEnabled, const char *pszNameFmt, va_list va) RT_IPRT_FORMAT_ATTR_MAYBE_NULL(6, 0);
+/**
+ * Uninitialize a lock validator record previously initialized by
+ * RTLockRecValidatorInit.
+ *
+ * @param   pRec                The record.  Must be valid.
+ */
+RTDECL(void) RTLockValidatorRecExclDelete(PRTLOCKVALRECEXCL pRec);
+
+/**
+ * Create and initialize a lock validator record.
+ *
+ * Use RTLockValidatorRecExclDestroy to deinitialize and destroy the returned
+ * record.
+ *
+ * @return VINF_SUCCESS or VERR_NO_MEMORY.
+ * @param   ppRec               Where to return the record pointer.
+ * @param   hClass              The class (no reference consumed). If NIL, the
+ *                              no lock order validation will be performed on
+ *                              this lock.
+ * @param   uSubClass           The sub-class.  This is used to define lock
+ *                              order inside the same class.  If you don't know,
+ *                              then pass RTLOCKVAL_SUB_CLASS_NONE.
+ * @param   hLock               The lock handle.
+ * @param   fEnabled            Pass @c false to explicitly disable lock
+ *                              validation, otherwise @c true.
+ * @param   pszNameFmt          Name format string for the lock validator,
+ *                              optional (NULL). Max length is 32 bytes.
+ * @param   ...                 Format string arguments.
+ */
+RTDECL(int)  RTLockValidatorRecExclCreate(PRTLOCKVALRECEXCL *ppRec, RTLOCKVALCLASS hClass, uint32_t uSubClass, void *hLock,
+                                          bool fEnabled, const char *pszNameFmt, ...) RT_IPRT_FORMAT_ATTR_MAYBE_NULL(6, 7);
+
+/**
+ * Create and initialize a lock validator record.
+ *
+ * Use RTLockValidatorRecExclDestroy to deinitialize and destroy the returned
+ * record.
+ *
+ * @return VINF_SUCCESS or VERR_NO_MEMORY.
+ * @param   ppRec               Where to return the record pointer.
+ * @param   hClass              The class (no reference consumed). If NIL, the
+ *                              no lock order validation will be performed on
+ *                              this lock.
+ * @param   uSubClass           The sub-class.  This is used to define lock
+ *                              order inside the same class.  If you don't know,
+ *                              then pass RTLOCKVAL_SUB_CLASS_NONE.
+ * @param   hLock               The lock handle.
+ * @param   fEnabled            Pass @c false to explicitly disable lock
+ *                              validation, otherwise @c true.
+ * @param   pszNameFmt          Name format string for the lock validator,
+ *                              optional (NULL). Max length is 32 bytes.
+ * @param   va                  Format string arguments.
+ */
+RTDECL(int)  RTLockValidatorRecExclCreateV(PRTLOCKVALRECEXCL *ppRec, RTLOCKVALCLASS hClass, uint32_t uSubClass, void *hLock,
+                                           bool fEnabled, const char *pszNameFmt, va_list va) RT_IPRT_FORMAT_ATTR_MAYBE_NULL(6, 0);
+
+/**
+ * Deinitialize and destroy a record created by RTLockValidatorRecExclCreate.
+ *
+ * @param   ppRec               Pointer to the record pointer.  Will be set to
+ *                              NULL.
+ */
+RTDECL(void) RTLockValidatorRecExclDestroy(PRTLOCKVALRECEXCL *ppRec);
+
+/**
+ * Sets the sub-class of the record.
+ *
+ * It is recommended to try make sure that nobody is using this class while
+ * changing the value.
+ *
+ * @returns The old sub-class.  RTLOCKVAL_SUB_CLASS_INVALID is returns if the
+ *          lock validator isn't compiled in or either of the parameters are
+ *          invalid.
+ * @param   pRec                The validator record.
+ * @param   uSubClass           The new sub-class value.
+ */
+RTDECL(uint32_t) RTLockValidatorRecExclSetSubClass(PRTLOCKVALRECEXCL pRec, uint32_t uSubClass);
+
+/**
+ * Record the specified thread as lock owner and increment the write lock count.
+ *
+ * This function is typically called after acquiring the lock.  It accounts for
+ * recursions so it can be used instead of RTLockValidatorRecExclRecursion.  Use
+ * RTLockValidatorRecExclReleaseOwner to reverse the effect.
+ *
+ * @param   pRec                The validator record.
+ * @param   hThreadSelf         The handle of the calling thread.  If not known,
+ *                              pass NIL_RTTHREAD and we'll figure it out.
+ * @param   pSrcPos             The source position of the lock operation.
+ * @param   fFirstRecursion     Set if it is the first recursion, clear if not
+ *                              sure.
+ */
+RTDECL(void) RTLockValidatorRecExclSetOwner(PRTLOCKVALRECEXCL pRec, RTTHREAD hThreadSelf,
+                                            PCRTLOCKVALSRCPOS pSrcPos, bool fFirstRecursion);
+
+/**
+ * Check the exit order and release (unset) the ownership.
+ *
+ * This is called by routines implementing releasing an exclusive lock,
+ * typically before getting down to the final lock releasing.  Can be used for
+ * recursive releasing instead of RTLockValidatorRecExclUnwind.
+ *
+ * @retval  VINF_SUCCESS on success.
+ * @retval  VERR_SEM_LV_WRONG_RELEASE_ORDER if the order is wrong.  Will have
+ *          done all necessary whining and breakpointing before returning.
+ * @retval  VERR_SEM_LV_INVALID_PARAMETER if the input is invalid.
+ *
+ * @param   pRec                The validator record.
+ * @param   fFinalRecursion     Set if it's the final recursion, clear if not
+ *                              sure.
+ */
+RTDECL(int) RTLockValidatorRecExclReleaseOwner(PRTLOCKVALRECEXCL pRec, bool fFinalRecursion);
+
+/**
+ * Clear the lock ownership and decrement the write lock count.
+ *
+ * This is only for special cases where we wish to drop lock validation
+ * recording.  See RTLockValidatorRecExclCheckAndRelease.
+ *
+ * @param   pRec                The validator record.
+ */
+RTDECL(void) RTLockValidatorRecExclReleaseOwnerUnchecked(PRTLOCKVALRECEXCL pRec);
+
+/**
+ * Checks and records a lock recursion.
+ *
+ * @retval  VINF_SUCCESS on success.
+ * @retval  VERR_SEM_LV_NESTED if the semaphore class forbids recursion.  Gone
+ *          thru the motions.
+ * @retval  VERR_SEM_LV_WRONG_ORDER if the locking order is wrong.  Gone thru
+ *          the motions.
+ * @retval  VERR_SEM_LV_INVALID_PARAMETER if the input is invalid.
+ *
+ * @param   pRec                The validator record.
+ * @param   pSrcPos             The source position of the lock operation.
+ */
+RTDECL(int) RTLockValidatorRecExclRecursion(PRTLOCKVALRECEXCL pRec, PCRTLOCKVALSRCPOS pSrcPos);
+
+/**
+ * Checks and records a lock unwind (releasing one recursion).
+ *
+ * This should be coupled with called to RTLockValidatorRecExclRecursion.
+ *
+ * @retval  VINF_SUCCESS on success.
+ * @retval  VERR_SEM_LV_WRONG_RELEASE_ORDER if the release order is wrong.  Gone
+ *          thru the motions.
+ * @retval  VERR_SEM_LV_INVALID_PARAMETER if the input is invalid.
+ *
+ * @param   pRec                The validator record.
+ */
+RTDECL(int) RTLockValidatorRecExclUnwind(PRTLOCKVALRECEXCL pRec);
+
+/**
+ * Checks and records a mixed recursion.
+ *
+ * An example of a mixed recursion is a writer requesting read access to a
+ * SemRW.
+ *
+ * This should be coupled with called to RTLockValidatorRecExclUnwindMixed.
+ *
+ * @retval  VINF_SUCCESS on success.
+ * @retval  VERR_SEM_LV_NESTED if the semaphore class forbids recursion.  Gone
+ *          thru the motions.
+ * @retval  VERR_SEM_LV_WRONG_ORDER if the locking order is wrong.  Gone thru
+ *          the motions.
+ * @retval  VERR_SEM_LV_INVALID_PARAMETER if the input is invalid.
+ *
+ * @param   pRec                The validator record it to accounted it to.
+ * @param   pRecMixed           The validator record it came in on.
+ * @param   pSrcPos             The source position of the lock operation.
+ */
+RTDECL(int) RTLockValidatorRecExclRecursionMixed(PRTLOCKVALRECEXCL pRec, PRTLOCKVALRECCORE pRecMixed, PCRTLOCKVALSRCPOS pSrcPos);
+
+/**
+ * Checks and records the unwinding of a mixed recursion.
+ *
+ * This should be coupled with called to RTLockValidatorRecExclRecursionMixed.
+ *
+ * @retval  VINF_SUCCESS on success.
+ * @retval  VERR_SEM_LV_WRONG_RELEASE_ORDER if the release order is wrong.  Gone
+ *          thru the motions.
+ * @retval  VERR_SEM_LV_INVALID_PARAMETER if the input is invalid.
+ *
+ * @param   pRec                The validator record it was accounted to.
+ * @param   pRecMixed           The validator record it came in on.
+ */
+RTDECL(int) RTLockValidatorRecExclUnwindMixed(PRTLOCKVALRECEXCL pRec, PRTLOCKVALRECCORE pRecMixed);
+
+/**
+ * Check the exclusive locking order.
+ *
+ * This is called by routines implementing exclusive lock acquisition.
+ *
+ * @retval  VINF_SUCCESS on success.
+ * @retval  VERR_SEM_LV_WRONG_ORDER if the order is wrong.  Will have done all
+ *          necessary whining and breakpointing before returning.
+ * @retval  VERR_SEM_LV_INVALID_PARAMETER if the input is invalid.
+ *
+ * @param   pRec                The validator record.
+ * @param   hThreadSelf         The handle of the calling thread.  If not known,
+ *                              pass NIL_RTTHREAD and we'll figure it out.
+ * @param   pSrcPos             The source position of the lock operation.
+ * @param   cMillies            The timeout, in milliseconds.
+ */
+RTDECL(int)  RTLockValidatorRecExclCheckOrder(PRTLOCKVALRECEXCL pRec, RTTHREAD hThreadSelf,
+                                              PCRTLOCKVALSRCPOS pSrcPos, RTMSINTERVAL cMillies);
+
+/**
+ * Do deadlock detection before blocking on exclusive access to a lock and
+ * change the thread state.
+ *
+ * @retval  VINF_SUCCESS - thread is in the specified sleep state.
+ * @retval  VERR_SEM_LV_DEADLOCK if blocking would deadlock.  Gone thru the
+ *          motions.
+ * @retval  VERR_SEM_LV_NESTED if the semaphore isn't recursive and hThread is
+ *          already the owner.  Gone thru the motions.
+ * @retval  VERR_SEM_LV_ILLEGAL_UPGRADE if it's a deadlock on the same lock.
+ *          The caller must handle any legal upgrades without invoking this
+ *          function (for now).
+ * @retval  VERR_SEM_LV_INVALID_PARAMETER if the input is invalid.
+ *
+ * @param   pRec                The validator record we're blocking on.
+ * @param   hThreadSelf         The current thread.  Shall not be NIL_RTTHREAD!
+ * @param   pSrcPos             The source position of the lock operation.
+ * @param   fRecursiveOk        Whether it's ok to recurse.
+ * @param   cMillies            The timeout, in milliseconds.
+ * @param   enmSleepState       The sleep state to enter on successful return.
+ * @param   fReallySleeping     Is it really going to sleep now or not.  Use
+ *                              false before calls to other IPRT synchronization
+ *                              methods.
+ */
+RTDECL(int) RTLockValidatorRecExclCheckBlocking(PRTLOCKVALRECEXCL pRec, RTTHREAD hThreadSelf,
+                                                PCRTLOCKVALSRCPOS pSrcPos, bool fRecursiveOk, RTMSINTERVAL cMillies,
+                                                RTTHREADSTATE enmSleepState, bool fReallySleeping);
+
+/**
+ * RTLockValidatorRecExclCheckOrder and RTLockValidatorRecExclCheckBlocking
+ * baked into one call.
+ *
+ * @returns Any of the statuses returned by the two APIs.
+ * @param   pRec                The validator record.
+ * @param   hThreadSelf         The current thread.  Shall not be NIL_RTTHREAD!
+ * @param   pSrcPos             The source position of the lock operation.
+ * @param   fRecursiveOk        Whether it's ok to recurse.
+ * @param   cMillies            The timeout, in milliseconds.
+ * @param   enmSleepState       The sleep state to enter on successful return.
+ * @param   fReallySleeping     Is it really going to sleep now or not.  Use
+ *                              false before calls to other IPRT synchronization
+ *                              methods.
+ */
+RTDECL(int) RTLockValidatorRecExclCheckOrderAndBlocking(PRTLOCKVALRECEXCL pRec, RTTHREAD hThreadSelf,
+                                                        PCRTLOCKVALSRCPOS pSrcPos, bool fRecursiveOk, RTMSINTERVAL cMillies,
+                                                        RTTHREADSTATE enmSleepState, bool fReallySleeping);
+
+/**
+ * Initialize a lock validator record for a shared lock.
+ *
+ * Use RTLockValidatorRecSharedDelete to deinitialize it.
+ *
+ * @param   pRec                The shared lock record.
+ * @param   hClass              The class (no reference consumed). If NIL, the
+ *                              no lock order validation will be performed on
+ *                              this lock.
+ * @param   uSubClass           The sub-class.  This is used to define lock
+ *                              order inside the same class.  If you don't know,
+ *                              then pass RTLOCKVAL_SUB_CLASS_NONE.
+ * @param   hLock               The lock handle.
+ * @param   fSignaller          Set if event semaphore signaller logic should be
+ *                              applied to this record, clear if read-write
+ *                              semaphore logic should be used.
+ * @param   fEnabled            Pass @c false to explicitly disable lock
+ *                              validation, otherwise @c true.
+ * @param   pszNameFmt          Name format string for the lock validator,
+ *                              optional (NULL). Max length is 32 bytes.
+ * @param   ...                 Format string arguments.
+ */
+RTDECL(void) RTLockValidatorRecSharedInit(PRTLOCKVALRECSHRD pRec, RTLOCKVALCLASS hClass, uint32_t uSubClass,
+                                          void *hLock, bool fSignaller, bool fEnabled,
+                                          const char *pszNameFmt, ...) RT_IPRT_FORMAT_ATTR_MAYBE_NULL(7, 8);
+
+/**
+ * Initialize a lock validator record for a shared lock.
+ *
+ * Use RTLockValidatorRecSharedDelete to deinitialize it.
+ *
+ * @param   pRec                The shared lock record.
+ * @param   hClass              The class (no reference consumed). If NIL, the
+ *                              no lock order validation will be performed on
+ *                              this lock.
+ * @param   uSubClass           The sub-class.  This is used to define lock
+ *                              order inside the same class.  If you don't know,
+ *                              then pass RTLOCKVAL_SUB_CLASS_NONE.
+ * @param   hLock               The lock handle.
+ * @param   fSignaller          Set if event semaphore signaller logic should be
+ *                              applied to this record, clear if read-write
+ *                              semaphore logic should be used.
+ * @param   fEnabled            Pass @c false to explicitly disable lock
+ *                              validation, otherwise @c true.
+ * @param   pszNameFmt          Name format string for the lock validator,
+ *                              optional (NULL). Max length is 32 bytes.
+ * @param   va                  Format string arguments.
+ */
+RTDECL(void) RTLockValidatorRecSharedInitV(PRTLOCKVALRECSHRD pRec, RTLOCKVALCLASS hClass, uint32_t uSubClass,
+                                           void *hLock, bool fSignaller, bool fEnabled,
+                                           const char *pszNameFmt, va_list va) RT_IPRT_FORMAT_ATTR_MAYBE_NULL(7, 0);
+
+/**
+ * Uninitialize a lock validator record previously initialized by
+ * RTLockValidatorRecSharedInit.
+ *
+ * @param   pRec                The shared lock record.  Must be valid.
+ */
+RTDECL(void) RTLockValidatorRecSharedDelete(PRTLOCKVALRECSHRD pRec);
+
+/**
+ * Create and initialize a lock validator record for a shared lock.
+ *
+ * Use RTLockValidatorRecSharedDestroy to deinitialize and destroy the returned
+ * record.
+ *
+ * @returns IPRT status code.
+ * @param   ppRec               Where to return the record pointer.
+ * @param   hClass              The class (no reference consumed). If NIL, the
+ *                              no lock order validation will be performed on
+ *                              this lock.
+ * @param   uSubClass           The sub-class.  This is used to define lock
+ *                              order inside the same class.  If you don't know,
+ *                              then pass RTLOCKVAL_SUB_CLASS_NONE.
+ * @param   pvLock              The lock handle or address.
+ * @param   fSignaller          Set if event semaphore signaller logic should be
+ *                              applied to this record, clear if read-write
+ *                              semaphore logic should be used.
+ * @param   fEnabled            Pass @c false to explicitly disable lock
+ *                              validation, otherwise @c true.
+ * @param   pszNameFmt          Name format string for the lock validator,
+ *                              optional (NULL). Max length is 32 bytes.
+ * @param   ...                 Format string arguments.
+ */
+RTDECL(int) RTLockValidatorRecSharedCreate(PRTLOCKVALRECSHRD *ppRec, RTLOCKVALCLASS hClass, uint32_t uSubClass,
+                                           void *pvLock, bool fSignaller, bool fEnabled,
+                                           const char *pszNameFmt, ...) RT_IPRT_FORMAT_ATTR_MAYBE_NULL(7, 8);
+
+/**
+ * Create and initialize a lock validator record for a shared lock.
+ *
+ * Use RTLockValidatorRecSharedDestroy to deinitialize and destroy the returned
+ * record.
+ *
+ * @returns IPRT status code.
+ * @param   ppRec               Where to return the record pointer.
+ * @param   hClass              The class (no reference consumed). If NIL, the
+ *                              no lock order validation will be performed on
+ *                              this lock.
+ * @param   uSubClass           The sub-class.  This is used to define lock
+ *                              order inside the same class.  If you don't know,
+ *                              then pass RTLOCKVAL_SUB_CLASS_NONE.
+ * @param   pvLock              The lock handle or address.
+ * @param   fSignaller          Set if event semaphore signaller logic should be
+ *                              applied to this record, clear if read-write
+ *                              semaphore logic should be used.
+ * @param   fEnabled            Pass @c false to explicitly disable lock
+ *                              validation, otherwise @c true.
+ * @param   pszNameFmt          Name format string for the lock validator,
+ *                              optional (NULL). Max length is 32 bytes.
+ * @param   va                  Format string arguments.
+ */
+RTDECL(int) RTLockValidatorRecSharedCreateV(PRTLOCKVALRECSHRD *ppRec, RTLOCKVALCLASS hClass, uint32_t uSubClass,
+                                            void *pvLock, bool fSignaller, bool fEnabled,
+                                            const char *pszNameFmt, va_list va) RT_IPRT_FORMAT_ATTR_MAYBE_NULL(7, 0);
+
+/**
+ * Deinitialize and destroy a record created by RTLockValidatorRecSharedCreate.
+ *
+ * @param   ppRec               Pointer to the record pointer.  Will be set to
+ *                              NULL.
+ */
+RTDECL(void) RTLockValidatorRecSharedDestroy(PRTLOCKVALRECSHRD *ppRec);
+
+/**
+ * Sets the sub-class of the record.
+ *
+ * It is recommended to try make sure that nobody is using this class while
+ * changing the value.
+ *
+ * @returns The old sub-class.  RTLOCKVAL_SUB_CLASS_INVALID is returns if the
+ *          lock validator isn't compiled in or either of the parameters are
+ *          invalid.
+ * @param   pRec                The validator record.
+ * @param   uSubClass           The new sub-class value.
+ */
+RTDECL(uint32_t) RTLockValidatorRecSharedSetSubClass(PRTLOCKVALRECSHRD pRec, uint32_t uSubClass);
+
+/**
+ * Check the shared locking order.
+ *
+ * This is called by routines implementing shared lock acquisition.
+ *
+ * @retval  VINF_SUCCESS on success.
+ * @retval  VERR_SEM_LV_WRONG_ORDER if the order is wrong.  Will have done all
+ *          necessary whining and breakpointing before returning.
+ * @retval  VERR_SEM_LV_INVALID_PARAMETER if the input is invalid.
+ *
+ * @param   pRec                The validator record.
+ * @param   hThreadSelf         The handle of the calling thread.  If not known,
+ *                              pass NIL_RTTHREAD and we'll figure it out.
+ * @param   pSrcPos             The source position of the lock operation.
+ * @param   cMillies            Intended sleep time in milliseconds.
+ */
+RTDECL(int)  RTLockValidatorRecSharedCheckOrder(PRTLOCKVALRECSHRD pRec, RTTHREAD hThreadSelf,
+                                                PCRTLOCKVALSRCPOS pSrcPos, RTMSINTERVAL cMillies);
+
+/**
+ * Do deadlock detection before blocking on shared access to a lock and change
+ * the thread state.
+ *
+ * @retval  VINF_SUCCESS - thread is in the specified sleep state.
+ * @retval  VERR_SEM_LV_DEADLOCK if blocking would deadlock.  Gone thru the
+ *          motions.
+ * @retval  VERR_SEM_LV_NESTED if the semaphore isn't recursive and hThread is
+ *          already the owner.  Gone thru the motions.
+ * @retval  VERR_SEM_LV_ILLEGAL_UPGRADE if it's a deadlock on the same lock.
+ *          The caller must handle any legal upgrades without invoking this
+ *          function (for now).
+ * @retval  VERR_SEM_LV_INVALID_PARAMETER if the input is invalid.
+ *
+ * @param   pRec                The validator record we're blocking on.
+ * @param   hThreadSelf         The current thread.  Shall not be NIL_RTTHREAD!
+ * @param   pSrcPos             The source position of the lock operation.
+ * @param   fRecursiveOk        Whether it's ok to recurse.
+ * @param   cMillies            Intended sleep time in milliseconds.
+ * @param   enmSleepState       The sleep state to enter on successful return.
+ * @param   fReallySleeping     Is it really going to sleep now or not.  Use
+ *                              false before calls to other IPRT synchronization
+ *                              methods.
+ */
+RTDECL(int) RTLockValidatorRecSharedCheckBlocking(PRTLOCKVALRECSHRD pRec, RTTHREAD hThreadSelf,
+                                                  PCRTLOCKVALSRCPOS pSrcPos, bool fRecursiveOk, RTMSINTERVAL cMillies,
+                                                  RTTHREADSTATE enmSleepState, bool fReallySleeping);
+
+/**
+ * RTLockValidatorRecSharedCheckOrder and RTLockValidatorRecSharedCheckBlocking
+ * baked into one call.
+ *
+ * @returns Any of the statuses returned by the two APIs.
+ * @param   pRec                The validator record.
+ * @param   hThreadSelf         The current thread.  Shall not be NIL_RTTHREAD!
+ * @param   pSrcPos             The source position of the lock operation.
+ * @param   fRecursiveOk        Whether it's ok to recurse.
+ * @param   cMillies            Intended sleep time in milliseconds.
+ * @param   enmSleepState       The sleep state to enter on successful return.
+ * @param   fReallySleeping     Is it really going to sleep now or not.  Use
+ *                              false before calls to other IPRT synchronization
+ *                              methods.
+ */
+RTDECL(int) RTLockValidatorRecSharedCheckOrderAndBlocking(PRTLOCKVALRECSHRD pRec, RTTHREAD hThreadSelf,
+                                                          PCRTLOCKVALSRCPOS pSrcPos, bool fRecursiveOk, RTMSINTERVAL cMillies,
+                                                          RTTHREADSTATE enmSleepState, bool fReallySleeping);
+
+/**
+ * Removes all current owners and makes hThread the only owner.
+ *
+ * @param   pRec                The validator record.
+ * @param   hThread             The thread handle of the owner.  NIL_RTTHREAD is
+ *                              an alias for the current thread.
+ * @param   pSrcPos             The source position of the lock operation.
+ */
+RTDECL(void) RTLockValidatorRecSharedResetOwner(PRTLOCKVALRECSHRD pRec, RTTHREAD hThread, PCRTLOCKVALSRCPOS pSrcPos);
+
+/**
+ * Adds an owner to a shared locking record.
+ *
+ * Takes recursion into account.  This function is typically called after
+ * acquiring the lock in shared mode.
+ *
+ * @param   pRec                The validator record.
+ * @param   hThread             The thread handle of the owner.  NIL_RTTHREAD is
+ *                              an alias for the current thread.
+ * @param   pSrcPos             The source position of the lock operation.
+ */
+RTDECL(void) RTLockValidatorRecSharedAddOwner(PRTLOCKVALRECSHRD pRec, RTTHREAD hThread, PCRTLOCKVALSRCPOS pSrcPos);
+
+/**
+ * Removes an owner from a shared locking record.
+ *
+ * Takes recursion into account.  This function is typically called before
+ * releasing the lock.
+ *
+ * @param   pRec                The validator record.
+ * @param   hThread             The thread handle of the owner.  NIL_RTTHREAD is
+ *                              an alias for the current thread.
+ */
+RTDECL(void) RTLockValidatorRecSharedRemoveOwner(PRTLOCKVALRECSHRD pRec, RTTHREAD hThread);
+
+/**
+ * Checks if the specified thread is one of the owners.
+ *
+ * @returns true if it is, false if not.
+ *
+ * @param   pRec                The validator record.
+ * @param   hThread             The thread handle of the owner.  NIL_RTTHREAD is
+ *                              an alias for the current thread.
+ */
+RTDECL(bool) RTLockValidatorRecSharedIsOwner(PRTLOCKVALRECSHRD pRec, RTTHREAD hThread);
+
+/**
+ * Check the exit order and release (unset) the shared ownership.
+ *
+ * This is called by routines implementing releasing the read/write lock.
+ *
+ * @retval  VINF_SUCCESS on success.
+ * @retval  VERR_SEM_LV_WRONG_RELEASE_ORDER if the order is wrong.  Will have
+ *          done all necessary whining and breakpointing before returning.
+ * @retval  VERR_SEM_LV_INVALID_PARAMETER if the input is invalid.
+ *
+ * @param   pRec                The validator record.
+ * @param   hThreadSelf         The handle of the calling thread.  NIL_RTTHREAD
+ *                              is an alias for the current thread.
+ */
+RTDECL(int) RTLockValidatorRecSharedCheckAndRelease(PRTLOCKVALRECSHRD pRec, RTTHREAD hThreadSelf);
+
+/**
+ * Check the signaller of an event.
+ *
+ * This is called by routines implementing releasing the event semaphore (both
+ * kinds).
+ *
+ * @retval  VINF_SUCCESS on success.
+ * @retval  VERR_SEM_LV_NOT_SIGNALLER if the thread is not in the record.  Will
+ *          have done all necessary whining and breakpointing before returning.
+ * @retval  VERR_SEM_LV_INVALID_PARAMETER if the input is invalid.
+ *
+ * @param   pRec                The validator record.
+ * @param   hThreadSelf         The handle of the calling thread.  NIL_RTTHREAD
+ *                              is an alias for the current thread.
+ */
+RTDECL(int) RTLockValidatorRecSharedCheckSignaller(PRTLOCKVALRECSHRD pRec, RTTHREAD hThreadSelf);
+
+/**
+ * Gets the number of write locks and critical sections the specified
+ * thread owns.
+ *
+ * This number does not include any nested lock/critect entries.
+ *
+ * Note that it probably will return 0 for non-strict builds since
+ * release builds doesn't do unnecessary diagnostic counting like this.
+ *
+ * @returns Number of locks on success (0+) and VERR_INVALID_HANDLER on failure
+ * @param   Thread          The thread we're inquiring about.
+ * @remarks Will only work for strict builds.
+ */
+RTDECL(int32_t) RTLockValidatorWriteLockGetCount(RTTHREAD Thread);
+
+/**
+ * Works the THREADINT::cWriteLocks member, mostly internal.
+ *
+ * @param   Thread      The current thread.
+ */
+RTDECL(void) RTLockValidatorWriteLockInc(RTTHREAD Thread);
+
+/**
+ * Works the THREADINT::cWriteLocks member, mostly internal.
+ *
+ * @param   Thread      The current thread.
+ */
+RTDECL(void) RTLockValidatorWriteLockDec(RTTHREAD Thread);
+
+/**
+ * Gets the number of read locks the specified thread owns.
+ *
+ * Note that nesting read lock entry will be included in the
+ * total sum. And that it probably will return 0 for non-strict
+ * builds since release builds doesn't do unnecessary diagnostic
+ * counting like this.
+ *
+ * @returns Number of read locks on success (0+) and VERR_INVALID_HANDLER on failure
+ * @param   Thread          The thread we're inquiring about.
+ */
+RTDECL(int32_t) RTLockValidatorReadLockGetCount(RTTHREAD Thread);
+
+/**
+ * Works the THREADINT::cReadLocks member.
+ *
+ * @param   Thread      The current thread.
+ */
+RTDECL(void) RTLockValidatorReadLockInc(RTTHREAD Thread);
+
+/**
+ * Works the THREADINT::cReadLocks member.
+ *
+ * @param   Thread      The current thread.
+ */
+RTDECL(void) RTLockValidatorReadLockDec(RTTHREAD Thread);
+
+/**
+ * Query which lock the specified thread is waiting on.
+ *
+ * @returns The lock handle value or NULL.
+ * @param   hThread     The thread in question.
+ */
+RTDECL(void *) RTLockValidatorQueryBlocking(RTTHREAD hThread);
+
+/**
+ * Checks if the thread is running in the lock validator after it has entered a
+ * block state.
+ *
+ * @returns true if it is, false if it isn't.
+ * @param   hThread     The thread in question.
+ */
+RTDECL(bool) RTLockValidatorIsBlockedThreadInValidator(RTTHREAD hThread);
+
+/**
+ * Checks if the calling thread is holding a lock in the specified class.
+ *
+ * @returns true if it holds a lock in the specific class, false if it
+ *          doesn't.
+ *
+ * @param   hCurrentThread      The current thread.  Pass NIL_RTTHREAD if you're
+ *                              lazy.
+ * @param   hClass              The class.
+ */
+RTDECL(bool) RTLockValidatorHoldsLocksInClass(RTTHREAD hCurrentThread, RTLOCKVALCLASS hClass);
+
+/**
+ * Checks if the calling thread is holding a lock in the specified sub-class.
+ *
+ * @returns true if it holds a lock in the specific sub-class, false if it
+ *          doesn't.
+ *
+ * @param   hCurrentThread      The current thread.  Pass NIL_RTTHREAD if you're
+ *                              lazy.
+ * @param   hClass              The class.
+ * @param   uSubClass           The new sub-class value.
+ */
+RTDECL(bool) RTLockValidatorHoldsLocksInSubClass(RTTHREAD hCurrentThread, RTLOCKVALCLASS hClass, uint32_t uSubClass);
+
+
+
+/**
+ * Creates a new lock validator class, all properties specified.
+ *
+ * @returns IPRT status code
+ * @param   phClass             Where to return the class handle.
+ * @param   pSrcPos             The source position of the create call.
+ * @param   fAutodidact         Whether the class should be allowed to teach
+ *                              itself new locking order rules (true), or if the
+ *                              user will teach it all it needs to know (false).
+ * @param   fRecursionOk        Whether to allow lock recursion or not.
+ * @param   fStrictReleaseOrder Enforce strict lock release order or not.
+ * @param   cMsMinDeadlock      Used to raise the sleep interval at which
+ *                              deadlock detection kicks in.  Minimum is 1 ms,
+ *                              while RT_INDEFINITE_WAIT will disable it.
+ * @param   cMsMinOrder         Used to raise the sleep interval at which lock
+ *                              order validation kicks in.  Minimum is 1 ms,
+ *                              while RT_INDEFINITE_WAIT will disable it.
+ * @param   pszNameFmt          Class name format string, optional (NULL).  Max
+ *                              length is 32 bytes.
+ * @param   ...                 Format string arguments.
+ *
+ * @remarks The properties can be modified after creation by the
+ *          RTLockValidatorClassSet* methods.
+ */
+RTDECL(int) RTLockValidatorClassCreateEx(PRTLOCKVALCLASS phClass, PCRTLOCKVALSRCPOS pSrcPos,
+                                         bool fAutodidact, bool fRecursionOk, bool fStrictReleaseOrder,
+                                         RTMSINTERVAL cMsMinDeadlock, RTMSINTERVAL cMsMinOrder,
+                                         const char *pszNameFmt, ...) RT_IPRT_FORMAT_ATTR_MAYBE_NULL(8, 9);
+
+/**
+ * Creates a new lock validator class, all properties specified.
+ *
+ * @returns IPRT status code
+ * @param   phClass             Where to return the class handle.
+ * @param   pSrcPos             The source position of the create call.
+ * @param   fAutodidact         Whether the class should be allowed to teach
+ *                              itself new locking order rules (true), or if the
+ *                              user will teach it all it needs to know (false).
+ * @param   fRecursionOk        Whether to allow lock recursion or not.
+ * @param   fStrictReleaseOrder Enforce strict lock release order or not.
+ * @param   cMsMinDeadlock      Used to raise the sleep interval at which
+ *                              deadlock detection kicks in.  Minimum is 1 ms,
+ *                              while RT_INDEFINITE_WAIT will disable it.
+ * @param   cMsMinOrder         Used to raise the sleep interval at which lock
+ *                              order validation kicks in.  Minimum is 1 ms,
+ *                              while RT_INDEFINITE_WAIT will disable it.
+ * @param   pszNameFmt          Class name format string, optional (NULL).  Max
+ *                              length is 32 bytes.
+ * @param   va                  Format string arguments.
+ *
+ * @remarks The properties can be modified after creation by the
+ *          RTLockValidatorClassSet* methods.
+ */
+RTDECL(int) RTLockValidatorClassCreateExV(PRTLOCKVALCLASS phClass, PCRTLOCKVALSRCPOS pSrcPos,
+                                          bool fAutodidact, bool fRecursionOk, bool fStrictReleaseOrder,
+                                          RTMSINTERVAL cMsMinDeadlock, RTMSINTERVAL cMsMinOrder,
+                                          const char *pszNameFmt, va_list va) RT_IPRT_FORMAT_ATTR_MAYBE_NULL(8, 0);
+
+/**
+ * Creates a new lock validator class.
+ *
+ * @returns IPRT status code
+ * @param   phClass             Where to return the class handle.
+ * @param   fAutodidact         Whether the class should be allowed to teach
+ *                              itself new locking order rules (true), or if the
+ *                              user will teach it all it needs to know (false).
+ * @param   SRC_POS             The source position where call is being made from.
+ *                              Use RT_SRC_POS when possible.  Optional.
+ * @param   pszNameFmt          Class name format string, optional (NULL).  Max
+ *                              length is 32 bytes.
+ * @param   ...                 Format string arguments.
+ */
+RTDECL(int) RTLockValidatorClassCreate(PRTLOCKVALCLASS phClass, bool fAutodidact, RT_SRC_POS_DECL,
+                                       const char *pszNameFmt, ...) RT_IPRT_FORMAT_ATTR_MAYBE_NULL(6, 7);
+
+/**
+ * Creates a new lock validator class with a reference that is consumed by the
+ * first call to RTLockValidatorClassRetain.
+ *
+ * This is tailored for use in the parameter list of a semaphore constructor.
+ *
+ * @returns Class handle with a reference that is automatically consumed by the
+ *          first retainer.  NIL_RTLOCKVALCLASS if we run into trouble.
+ *
+ * @param   SRC_POS             The source position where call is being made from.
+ *                              Use RT_SRC_POS when possible.  Optional.
+ * @param   pszNameFmt          Class name format string, optional (NULL).  Max
+ *                              length is 32 bytes.
+ * @param   ...                 Format string arguments.
+ */
+RTDECL(RTLOCKVALCLASS) RTLockValidatorClassCreateUnique(RT_SRC_POS_DECL,
+                                                        const char *pszNameFmt, ...) RT_IPRT_FORMAT_ATTR_MAYBE_NULL(4, 5);
+
+/**
+ * Finds a class for the specified source position.
+ *
+ * @returns A handle to the class (not retained!) or NIL_RTLOCKVALCLASS.
+ * @param   pSrcPos             The source position.
+ */
+RTDECL(RTLOCKVALCLASS) RTLockValidatorClassFindForSrcPos(PRTLOCKVALSRCPOS pSrcPos);
+
+/**
+ * Finds or creates a class given the source position.
+ *
+ * @returns Class handle (not retained!) or NIL_RTLOCKVALCLASS.
+ * @param   SRC_POS             The source position where call is being made from.
+ *                              Use RT_SRC_POS when possible.  Optional.
+ * @param   pszNameFmt          Class name format string, optional (NULL).  Max
+ *                              length is 32 bytes.
+ * @param   ...                 Format string arguments.
+ */
+RTDECL(RTLOCKVALCLASS) RTLockValidatorClassForSrcPos(RT_SRC_POS_DECL,
+                                                     const char *pszNameFmt, ...) RT_IPRT_FORMAT_ATTR_MAYBE_NULL(4, 5);
+
+/**
+ * Retains a reference to a lock validator class.
+ *
+ * @returns New reference count; UINT32_MAX if the handle is invalid.
+ * @param   hClass              Handle to the class.
+ */
+RTDECL(uint32_t) RTLockValidatorClassRetain(RTLOCKVALCLASS hClass);
+
+/**
+ * Releases a reference to a lock validator class.
+ *
+ * @returns New reference count. 0 if hClass is NIL_RTLOCKVALCLASS. UINT32_MAX
+ *          if the handle is invalid.
+ * @param   hClass              Handle to the class.
+ */
+RTDECL(uint32_t) RTLockValidatorClassRelease(RTLOCKVALCLASS hClass);
+
+/**
+ * Teaches the class @a hClass that locks in the class @a hPriorClass can be
+ * held when taking a lock of class @a hClass
+ *
+ * @returns IPRT status.
+ * @param   hClass              Handle to the pupil class.
+ * @param   hPriorClass         Handle to the class that can be held prior to
+ *                              taking a lock in the pupil class.  (No reference
+ *                              is consumed.)
+ */
+RTDECL(int) RTLockValidatorClassAddPriorClass(RTLOCKVALCLASS hClass, RTLOCKVALCLASS hPriorClass);
+
+/**
+ * Enables or disables the strict release order enforcing.
+ *
+ * @returns IPRT status.
+ * @param   hClass              Handle to the class to change.
+ * @param   fEnabled            Enable it (true) or disable it (false).
+ */
+RTDECL(int) RTLockValidatorClassEnforceStrictReleaseOrder(RTLOCKVALCLASS hClass, bool fEnabled);
+
+/**
+ * Enables / disables the lock validator for new locks.
+ *
+ * @returns The old setting.
+ * @param   fEnabled    The new setting.
+ */
+RTDECL(bool) RTLockValidatorSetEnabled(bool fEnabled);
+
+/**
+ * Is the lock validator enabled?
+ *
+ * @returns True if enabled, false if not.
+ */
+RTDECL(bool) RTLockValidatorIsEnabled(void);
+
+/**
+ * Controls whether the lock validator should be quiet or noisy (default).
+ *
+ * @returns The old setting.
+ * @param   fQuiet              The new setting.
+ */
+RTDECL(bool) RTLockValidatorSetQuiet(bool fQuiet);
+
+/**
+ * Is the lock validator quiet or noisy?
+ *
+ * @returns True if it is quiet, false if noisy.
+ */
+RTDECL(bool) RTLockValidatorIsQuiet(void);
+
+/**
+ * Makes the lock validator panic (default) or not.
+ *
+ * @returns The old setting.
+ * @param   fPanic              The new setting.
+ */
+RTDECL(bool) RTLockValidatorSetMayPanic(bool fPanic);
+
+/**
+ * Can the lock validator cause panic.
+ *
+ * @returns True if it can, false if not.
+ */
+RTDECL(bool) RTLockValidatorMayPanic(void);
+
+
+RT_C_DECLS_END
+
+/** @} */
+
+#endif
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/include/iprt/log.h
@@ -0,0 +1,2525 @@
+/** @file
+ * IPRT - Logging.
+ */
+
+/*
+ * Copyright (C) 2006-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+#ifndef ___iprt_log_h
+#define ___iprt_log_h
+
+#include <iprt/cdefs.h>
+#include <iprt/types.h>
+#include <iprt/stdarg.h>
+
+RT_C_DECLS_BEGIN
+
+/** @defgroup grp_rt_log    RTLog - Logging
+ * @ingroup grp_rt
+ * @{
+ */
+
+/**
+ * IPRT Logging Groups.
+ * (Remember to update RT_LOGGROUP_NAMES!)
+ *
+ * @remark It should be pretty obvious, but just to have
+ *         mentioned it, the values are sorted alphabetically (using the
+ *         english alphabet) except for _DEFAULT which is always first.
+ *
+ *         If anyone might be wondering what the alphabet looks like:
+ *              a b c d e f g h i j k l m n o p q r s t u v w x y z
+ */
+typedef enum RTLOGGROUP
+{
+    /** Default logging group. */
+    RTLOGGROUP_DEFAULT,
+    RTLOGGROUP_CRYPTO,
+    RTLOGGROUP_DBG,
+    RTLOGGROUP_DBG_DWARF,
+    RTLOGGROUP_DIR,
+    RTLOGGROUP_FILE,
+    RTLOGGROUP_FS,
+    RTLOGGROUP_HTTP,
+    RTLOGGROUP_LDR,
+    RTLOGGROUP_PATH,
+    RTLOGGROUP_PROCESS,
+    RTLOGGROUP_SYMLINK,
+    RTLOGGROUP_THREAD,
+    RTLOGGROUP_TIME,
+    RTLOGGROUP_TIMER,
+    RTLOGGROUP_ZIP = 31,
+    RTLOGGROUP_FIRST_USER = 32
+} RTLOGGROUP;
+
+/** @def RT_LOGGROUP_NAMES
+ * IPRT Logging group names.
+ *
+ * Must correspond 100% to RTLOGGROUP!
+ * Don't forget commas!
+ *
+ * @remark It should be pretty obvious, but just to have
+ *         mentioned it, the values are sorted alphabetically (using the
+ *         english alphabet) except for _DEFAULT which is always first.
+ *
+ *         If anyone might be wondering what the alphabet looks like:
+ *              a b c d e f g h i j k l m n o p q r s t u v w x y z
+ */
+#define RT_LOGGROUP_NAMES \
+    "DEFAULT",      \
+    "RT_CRYPTO",    \
+    "RT_DBG",       \
+    "RT_DBG_DWARF", \
+    "RT_DIR",       \
+    "RT_FILE",      \
+    "RT_FS",        \
+    "RT_HTTP", \
+    "RT_LDR",       \
+    "RT_PATH",      \
+    "RT_PROCESS",   \
+    "RT_SYMLINK",   \
+    "RT_THREAD",    \
+    "RT_TIME",      \
+    "RT_TIMER",     \
+    "RT_15", \
+    "RT_16", \
+    "RT_17", \
+    "RT_18", \
+    "RT_19", \
+    "RT_20", \
+    "RT_21", \
+    "RT_22", \
+    "RT_23", \
+    "RT_24", \
+    "RT_25", \
+    "RT_26", \
+    "RT_27", \
+    "RT_28", \
+    "RT_29", \
+    "RT_30", \
+    "RT_ZIP"  \
+
+
+/** @def LOG_GROUP
+ * Active logging group.
+ */
+#ifndef LOG_GROUP
+# define LOG_GROUP          RTLOGGROUP_DEFAULT
+#endif
+
+/** @def LOG_FN_FMT
+ * You can use this to specify you desired way of printing __PRETTY_FUNCTION__
+ * if you dislike the default one.
+ */
+#ifndef LOG_FN_FMT
+# define LOG_FN_FMT "%Rfn"
+#endif
+
+#ifdef LOG_INSTANCE
+# error "LOG_INSTANCE is no longer supported."
+#endif
+#ifdef LOG_REL_INSTANCE
+# error "LOG_REL_INSTANCE is no longer supported."
+#endif
+
+/** Logger structure. */
+#ifdef IN_RC
+typedef struct RTLOGGERRC RTLOGGER;
+#else
+typedef struct RTLOGGER RTLOGGER;
+#endif
+/** Pointer to logger structure. */
+typedef RTLOGGER *PRTLOGGER;
+/** Pointer to const logger structure. */
+typedef const RTLOGGER *PCRTLOGGER;
+
+
+/** Guest context logger structure. */
+typedef struct RTLOGGERRC RTLOGGERRC;
+/** Pointer to guest context logger structure. */
+typedef RTLOGGERRC *PRTLOGGERRC;
+/** Pointer to const guest context logger structure. */
+typedef const RTLOGGERRC *PCRTLOGGERRC;
+
+
+/**
+ * Logger phase.
+ *
+ * Used for signalling the log header/footer callback what to do.
+ */
+typedef enum RTLOGPHASE
+{
+    /** Begin of the logging. */
+    RTLOGPHASE_BEGIN = 0,
+    /** End of the logging. */
+    RTLOGPHASE_END,
+    /** Before rotating the log file. */
+    RTLOGPHASE_PREROTATE,
+    /** After rotating the log file. */
+    RTLOGPHASE_POSTROTATE,
+    /** 32-bit type blow up hack.  */
+    RTLOGPHASE_32BIT_HACK = 0x7fffffff
+} RTLOGPHASE;
+
+
+/**
+ * Logger function.
+ *
+ * @param   pszFormat   Format string.
+ * @param   ...         Optional arguments as specified in the format string.
+ */
+typedef DECLCALLBACK(void) FNRTLOGGER(const char *pszFormat, ...) RT_IPRT_FORMAT_ATTR(1, 2);
+/** Pointer to logger function. */
+typedef FNRTLOGGER *PFNRTLOGGER;
+
+/**
+ * Flush function.
+ *
+ * @param   pLogger     Pointer to the logger instance which is to be flushed.
+ */
+typedef DECLCALLBACK(void) FNRTLOGFLUSH(PRTLOGGER pLogger);
+/** Pointer to flush function. */
+typedef FNRTLOGFLUSH *PFNRTLOGFLUSH;
+
+/**
+ * Flush function.
+ *
+ * @param   pLogger     Pointer to the logger instance which is to be flushed.
+ */
+typedef DECLCALLBACK(void) FNRTLOGFLUSHGC(PRTLOGGERRC pLogger);
+/** Pointer to logger function. */
+typedef RCPTRTYPE(FNRTLOGFLUSHGC *) PFNRTLOGFLUSHGC;
+
+/**
+ * Header/footer message callback.
+ *
+ * @param   pLogger     Pointer to the logger instance.
+ * @param   pszFormat   Format string.
+ * @param   ...         Optional arguments specified in the format string.
+ */
+typedef DECLCALLBACK(void) FNRTLOGPHASEMSG(PRTLOGGER pLogger, const char *pszFormat, ...) RT_IPRT_FORMAT_ATTR(2, 3);
+/** Pointer to header/footer message callback function. */
+typedef FNRTLOGPHASEMSG *PFNRTLOGPHASEMSG;
+
+/**
+ * Log file header/footer callback.
+ *
+ * @param   pLogger         Pointer to the logger instance.
+ * @param   enmLogPhase     Indicates at what time the callback is invoked.
+ * @param   pfnLogPhaseMsg  Callback for writing the header/footer (RTLogPrintf
+ *                          and others are out of bounds).
+ */
+typedef DECLCALLBACK(void) FNRTLOGPHASE(PRTLOGGER pLogger, RTLOGPHASE enmLogPhase, PFNRTLOGPHASEMSG pfnLogPhaseMsg);
+/** Pointer to log header/footer callback function. */
+typedef FNRTLOGPHASE *PFNRTLOGPHASE;
+
+/**
+ * Custom log prefix callback.
+ *
+ *
+ * @returns The number of chars written.
+ *
+ * @param   pLogger     Pointer to the logger instance.
+ * @param   pchBuf      Output buffer pointer.
+ *                      No need to terminate the output.
+ * @param   cchBuf      The size of the output buffer.
+ * @param   pvUser      The user argument.
+ */
+typedef DECLCALLBACK(size_t) FNRTLOGPREFIX(PRTLOGGER pLogger, char *pchBuf, size_t cchBuf, void *pvUser);
+/** Pointer to prefix callback function. */
+typedef FNRTLOGPREFIX *PFNRTLOGPREFIX;
+
+
+
+/**
+ * Logger instance structure for raw-mode context (RC).
+ */
+struct RTLOGGERRC
+{
+    /** Pointer to temporary scratch buffer.
+     * This is used to format the log messages. */
+    char                    achScratch[32768];
+    /** Current scratch buffer position. */
+    uint32_t                offScratch;
+    /** This is set if a prefix is pending. */
+    bool                    fPendingPrefix;
+    bool                    afAlignment[3];
+    /** Pointer to the logger function.
+     * This is actually pointer to a wrapper which will push a pointer to the
+     * instance pointer onto the stack before jumping to the real logger function.
+     * A very unfortunate hack to work around the missing variadic macro support in C++. */
+    RCPTRTYPE(PFNRTLOGGER)  pfnLogger;
+    /** Pointer to the flush function. */
+    PFNRTLOGFLUSHGC         pfnFlush;
+    /** Magic number (RTLOGGERRC_MAGIC). */
+    uint32_t                u32Magic;
+    /** Logger instance flags - RTLOGFLAGS. */
+    uint32_t                fFlags;
+    /** Number of groups in the afGroups member. */
+    uint32_t                cGroups;
+    /** Group flags array - RTLOGGRPFLAGS.
+     * This member have variable length and may extend way beyond
+     * the declared size of 1 entry. */
+    uint32_t                afGroups[1];
+};
+
+/** RTLOGGERRC::u32Magic value. (John Rogers Searle) */
+#define RTLOGGERRC_MAGIC    0x19320731
+
+
+
+#ifndef IN_RC
+
+/** Pointer to internal logger bits. */
+typedef struct RTLOGGERINTERNAL *PRTLOGGERINTERNAL;
+
+/**
+ * Logger instance structure.
+ */
+struct RTLOGGER
+{
+    /** Pointer to temporary scratch buffer.
+     * This is used to format the log messages. */
+    char                    achScratch[49152];
+    /** Current scratch buffer position. */
+    uint32_t                offScratch;
+    /** Magic number. */
+    uint32_t                u32Magic;
+    /** Logger instance flags - RTLOGFLAGS. */
+    uint32_t                fFlags;
+    /** Destination flags - RTLOGDEST. */
+    uint32_t                fDestFlags;
+    /** Pointer to the internal bits of the logger.
+     * (The memory is allocated in the same block as RTLOGGER.) */
+    PRTLOGGERINTERNAL       pInt;
+    /** Pointer to the logger function (used in non-C99 mode only).
+     *
+     * This is actually pointer to a wrapper which will push a pointer to the
+     * instance pointer onto the stack before jumping to the real logger function.
+     * A very unfortunate hack to work around the missing variadic macro
+     * support in older C++/C standards.  (The memory is allocated using
+     * RTMemExecAlloc(), except for agnostic R0 code.) */
+    PFNRTLOGGER             pfnLogger;
+    /** Number of groups in the afGroups and papszGroups members. */
+    uint32_t                cGroups;
+    /** Group flags array - RTLOGGRPFLAGS.
+     * This member have variable length and may extend way beyond
+     * the declared size of 1 entry. */
+    uint32_t                afGroups[1];
+};
+
+/** RTLOGGER::u32Magic value. (Avram Noam Chomsky) */
+# define RTLOGGER_MAGIC     UINT32_C(0x19281207)
+
+#endif /* !IN_RC */
+
+
+/**
+ * Logger flags.
+ */
+typedef enum RTLOGFLAGS
+{
+    /** The logger instance is disabled for normal output. */
+    RTLOGFLAGS_DISABLED             = 0x00000001,
+    /** The logger instance is using buffered output. */
+    RTLOGFLAGS_BUFFERED             = 0x00000002,
+    /** The logger instance expands LF to CR/LF. */
+    RTLOGFLAGS_USECRLF              = 0x00000010,
+    /** Append to the log destination where applicable. */
+    RTLOGFLAGS_APPEND               = 0x00000020,
+    /** Show relative timestamps with PREFIX_TSC and PREFIX_TS */
+    RTLOGFLAGS_REL_TS               = 0x00000040,
+    /** Show decimal timestamps with PREFIX_TSC and PREFIX_TS */
+    RTLOGFLAGS_DECIMAL_TS           = 0x00000080,
+    /** Open the file in write through mode. */
+    RTLOGFLAGS_WRITE_THROUGH        = 0x00000100,
+    /** Flush the file to disk when flushing the buffer. */
+    RTLOGFLAGS_FLUSH                = 0x00000200,
+    /** Restrict the number of log entries per group. */
+    RTLOGFLAGS_RESTRICT_GROUPS      = 0x00000400,
+    /** New lines should be prefixed with the write and read lock counts. */
+    RTLOGFLAGS_PREFIX_LOCK_COUNTS   = 0x00008000,
+    /** New lines should be prefixed with the CPU id (ApicID on intel/amd). */
+    RTLOGFLAGS_PREFIX_CPUID         = 0x00010000,
+    /** New lines should be prefixed with the native process id. */
+    RTLOGFLAGS_PREFIX_PID           = 0x00020000,
+    /** New lines should be prefixed with group flag number causing the output. */
+    RTLOGFLAGS_PREFIX_FLAG_NO       = 0x00040000,
+    /** New lines should be prefixed with group flag name causing the output. */
+    RTLOGFLAGS_PREFIX_FLAG          = 0x00080000,
+    /** New lines should be prefixed with group number. */
+    RTLOGFLAGS_PREFIX_GROUP_NO      = 0x00100000,
+    /** New lines should be prefixed with group name. */
+    RTLOGFLAGS_PREFIX_GROUP         = 0x00200000,
+    /** New lines should be prefixed with the native thread id. */
+    RTLOGFLAGS_PREFIX_TID           = 0x00400000,
+    /** New lines should be prefixed with thread name. */
+    RTLOGFLAGS_PREFIX_THREAD        = 0x00800000,
+    /** New lines should be prefixed with data from a custom callback. */
+    RTLOGFLAGS_PREFIX_CUSTOM        = 0x01000000,
+    /** New lines should be prefixed with formatted timestamp since program start. */
+    RTLOGFLAGS_PREFIX_TIME_PROG     = 0x04000000,
+    /** New lines should be prefixed with formatted timestamp (UCT). */
+    RTLOGFLAGS_PREFIX_TIME          = 0x08000000,
+    /** New lines should be prefixed with milliseconds since program start. */
+    RTLOGFLAGS_PREFIX_MS_PROG       = 0x10000000,
+    /** New lines should be prefixed with timestamp. */
+    RTLOGFLAGS_PREFIX_TSC           = 0x20000000,
+    /** New lines should be prefixed with timestamp. */
+    RTLOGFLAGS_PREFIX_TS            = 0x40000000,
+    /** The prefix mask. */
+    RTLOGFLAGS_PREFIX_MASK          = 0x7dff8000
+} RTLOGFLAGS;
+
+/**
+ * Logger per group flags.
+ *
+ * @remarks We only use the lower 16 bits here.  We'll be combining it with the
+ *          group number in a few places.
+ */
+typedef enum RTLOGGRPFLAGS
+{
+    /** Enabled. */
+    RTLOGGRPFLAGS_ENABLED      = 0x0001,
+    /** Flow logging. */
+    RTLOGGRPFLAGS_FLOW         = 0x0002,
+    /** Warnings logging. */
+    RTLOGGRPFLAGS_WARN         = 0x0004,
+    /* 0x0008 for later. */
+    /** Level 1 logging. */
+    RTLOGGRPFLAGS_LEVEL_1      = 0x0010,
+    /** Level 2 logging. */
+    RTLOGGRPFLAGS_LEVEL_2      = 0x0020,
+    /** Level 3 logging. */
+    RTLOGGRPFLAGS_LEVEL_3      = 0x0040,
+    /** Level 4 logging. */
+    RTLOGGRPFLAGS_LEVEL_4      = 0x0080,
+    /** Level 5 logging. */
+    RTLOGGRPFLAGS_LEVEL_5      = 0x0100,
+    /** Level 6 logging. */
+    RTLOGGRPFLAGS_LEVEL_6      = 0x0200,
+    /** Level 7 logging. */
+    RTLOGGRPFLAGS_LEVEL_7      = 0x0400,
+    /** Level 8 logging. */
+    RTLOGGRPFLAGS_LEVEL_8      = 0x0800,
+    /** Level 9 logging. */
+    RTLOGGRPFLAGS_LEVEL_9      = 0x1000,
+    /** Level 10 logging. */
+    RTLOGGRPFLAGS_LEVEL_10     = 0x2000,
+    /** Level 11 logging. */
+    RTLOGGRPFLAGS_LEVEL_11     = 0x4000,
+    /** Level 12 logging. */
+    RTLOGGRPFLAGS_LEVEL_12     = 0x8000,
+
+    /** Restrict the number of log entries. */
+    RTLOGGRPFLAGS_RESTRICT     = 0x40000000,
+    /** Blow up the type. */
+    RTLOGGRPFLAGS_32BIT_HACK   = 0x7fffffff
+} RTLOGGRPFLAGS;
+
+/**
+ * Logger destination type.
+ */
+typedef enum RTLOGDEST
+{
+    /** Log to file. */
+    RTLOGDEST_FILE          = 0x00000001,
+    /** Log to stdout. */
+    RTLOGDEST_STDOUT        = 0x00000002,
+    /** Log to stderr. */
+    RTLOGDEST_STDERR        = 0x00000004,
+    /** Log to debugger (win32 only). */
+    RTLOGDEST_DEBUGGER      = 0x00000008,
+    /** Log to com port. */
+    RTLOGDEST_COM           = 0x00000010,
+    /** Log a memory ring buffer. */
+    RTLOGDEST_RINGBUF       = 0x00000020,
+    /** Just a dummy flag to be used when no other flag applies. */
+    RTLOGDEST_DUMMY         = 0x20000000,
+    /** Log to a user defined output stream. */
+    RTLOGDEST_USER          = 0x40000000
+} RTLOGDEST;
+
+
+RTDECL(void) RTLogPrintfEx(void *pvInstance, unsigned fFlags, unsigned iGroup,
+                           const char *pszFormat, ...) RT_IPRT_FORMAT_ATTR(4, 5);
+
+
+#ifdef DOXYGEN_RUNNING
+# define LOG_DISABLED
+# define LOG_ENABLED
+# define LOG_ENABLE_FLOW
+#endif
+
+/** @def LOG_DISABLED
+ * Use this compile time define to disable all logging macros. It can
+ * be overridden for each of the logging macros by the LOG_ENABLE*
+ * compile time defines.
+ */
+
+/** @def LOG_ENABLED
+ * Use this compile time define to enable logging when not in debug mode
+ * or LOG_DISABLED is set.
+ * This will enabled Log() only.
+ */
+
+/** @def LOG_ENABLE_FLOW
+ * Use this compile time define to enable flow logging when not in
+ * debug mode or LOG_DISABLED is defined.
+ * This will enable LogFlow() only.
+ */
+
+/*
+ * Determine whether logging is enabled and forcefully normalize the indicators.
+ */
+#if (defined(DEBUG) || defined(LOG_ENABLED)) && !defined(LOG_DISABLED)
+# undef  LOG_DISABLED
+# undef  LOG_ENABLED
+# define LOG_ENABLED
+#else
+# undef  LOG_ENABLED
+# undef  LOG_DISABLED
+# define LOG_DISABLED
+#endif
+
+
+/** @def LOG_USE_C99
+ * Governs the use of variadic macros.
+ */
+#ifndef LOG_USE_C99
+# if defined(RT_ARCH_AMD64) || defined(RT_OS_DARWIN) || defined(RT_ARCH_SPARC) || defined(RT_ARCH_SPARC64)
+#  define LOG_USE_C99
+# endif
+#endif
+
+
+/** @name Macros for checking whether a log level is enabled.
+ * @{ */
+/** @def LogIsItEnabled
+ * Checks whether the specified logging group is enabled or not.
+ */
+#ifdef LOG_ENABLED
+# define LogIsItEnabled(a_fFlags, a_iGroup) ( RTLogDefaultInstanceEx(RT_MAKE_U32(a_fFlags, a_iGroup)) != NULL )
+#else
+# define LogIsItEnabled(a_fFlags, a_iGroup) (false)
+#endif
+
+/** @def LogIsEnabled
+ * Checks whether level 1 logging is enabled.
+ */
+#define LogIsEnabled()      LogIsItEnabled(RTLOGGRPFLAGS_LEVEL_1, LOG_GROUP)
+
+/** @def LogIs2Enabled
+ * Checks whether level 2 logging is enabled.
+ */
+#define LogIs2Enabled()     LogIsItEnabled(RTLOGGRPFLAGS_LEVEL_2, LOG_GROUP)
+
+/** @def LogIs3Enabled
+ * Checks whether level 3 logging is enabled.
+ */
+#define LogIs3Enabled()     LogIsItEnabled(RTLOGGRPFLAGS_LEVEL_3, LOG_GROUP)
+
+/** @def LogIs4Enabled
+ * Checks whether level 4 logging is enabled.
+ */
+#define LogIs4Enabled()     LogIsItEnabled(RTLOGGRPFLAGS_LEVEL_4, LOG_GROUP)
+
+/** @def LogIs5Enabled
+ * Checks whether level 5 logging is enabled.
+ */
+#define LogIs5Enabled()     LogIsItEnabled(RTLOGGRPFLAGS_LEVEL_5, LOG_GROUP)
+
+/** @def LogIs6Enabled
+ * Checks whether level 6 logging is enabled.
+ */
+#define LogIs6Enabled()     LogIsItEnabled(RTLOGGRPFLAGS_LEVEL_6, LOG_GROUP)
+
+/** @def LogIs7Enabled
+ * Checks whether level 7 logging is enabled.
+ */
+#define LogIs7Enabled()     LogIsItEnabled(RTLOGGRPFLAGS_LEVEL_7, LOG_GROUP)
+
+/** @def LogIs8Enabled
+ * Checks whether level 8 logging is enabled.
+ */
+#define LogIs8Enabled()     LogIsItEnabled(RTLOGGRPFLAGS_LEVEL_8, LOG_GROUP)
+
+/** @def LogIs9Enabled
+ * Checks whether level 9 logging is enabled.
+ */
+#define LogIs9Enabled()     LogIsItEnabled(RTLOGGRPFLAGS_LEVEL_9, LOG_GROUP)
+
+/** @def LogIs10Enabled
+ * Checks whether level 10 logging is enabled.
+ */
+#define LogIs10Enabled()    LogIsItEnabled(RTLOGGRPFLAGS_LEVEL_10, LOG_GROUP)
+
+/** @def LogIs11Enabled
+ * Checks whether level 11 logging is enabled.
+ */
+#define LogIs11Enabled()    LogIsItEnabled(RTLOGGRPFLAGS_LEVEL_11, LOG_GROUP)
+
+/** @def LogIs12Enabled
+ * Checks whether level 12 logging is enabled.
+ */
+#define LogIs12Enabled()    LogIsItEnabled(RTLOGGRPFLAGS_LEVEL_12, LOG_GROUP)
+
+/** @def LogIsFlowEnabled
+ * Checks whether execution flow logging is enabled.
+ */
+#define LogIsFlowEnabled()  LogIsItEnabled(RTLOGGRPFLAGS_FLOW, LOG_GROUP)
+
+/** @def LogIsWarnEnabled
+ * Checks whether execution flow logging is enabled.
+ */
+#define LogIsWarnEnabled()  LogIsItEnabled(RTLOGGRPFLAGS_WARN, LOG_GROUP)
+/** @} */
+
+
+/** @def LogIt
+ * Write to specific logger if group enabled.
+ */
+#ifdef LOG_ENABLED
+# if defined(LOG_USE_C99)
+#  define _LogRemoveParentheseis(...)                   __VA_ARGS__
+#  define _LogIt(a_fFlags, a_iGroup, ...) \
+   do \
+   { \
+        register PRTLOGGER LogIt_pLogger = RTLogDefaultInstanceEx(RT_MAKE_U32(a_fFlags, a_iGroup)); \
+        if (RT_LIKELY(!LogIt_pLogger)) \
+        {   /* likely */ } \
+        else \
+            RTLogLoggerEx(LogIt_pLogger, a_fFlags, a_iGroup, __VA_ARGS__); \
+   } while (0)
+#  define LogIt(a_fFlags, a_iGroup, fmtargs)            _LogIt(a_fFlags, a_iGroup, _LogRemoveParentheseis fmtargs)
+#  define _LogItAlways(a_fFlags, a_iGroup, ...)          RTLogLoggerEx(NULL, a_fFlags, UINT32_MAX, __VA_ARGS__)
+#  define LogItAlways(a_fFlags, a_iGroup, fmtargs)      _LogItAlways(a_fFlags, a_iGroup, _LogRemoveParentheseis fmtargs)
+        /** @todo invent a flag or something for skipping the group check so we can pass iGroup. LogItAlways. */
+# else
+#  define LogIt(a_fFlags, a_iGroup, fmtargs) \
+    do \
+    { \
+        register PRTLOGGER LogIt_pLogger = RTLogDefaultInstanceEx(RT_MAKE_U32(a_fFlags, a_iGroup)); \
+        if (RT_LIKELY(!LogIt_pLogger)) \
+        {   /* likely */ } \
+        else \
+        { \
+            LogIt_pLogger->pfnLogger fmtargs; \
+        } \
+    } while (0)
+#  define LogItAlways(a_fFlags, a_iGroup, fmtargs) \
+    do \
+    { \
+        register PRTLOGGER LogIt_pLogger = RTLogDefaultInstanceEx(RT_MAKE_U32(0, UINT16_MAX)); \
+        if (LogIt_pLogger) \
+            LogIt_pLogger->pfnLogger fmtargs; \
+    } while (0)
+# endif
+#else
+# define LogIt(a_fFlags, a_iGroup, fmtargs)             do { } while (0)
+# define LogItAlways(a_fFlags, a_iGroup, fmtargs)       do { } while (0)
+# if defined(LOG_USE_C99)
+#  define _LogRemoveParentheseis(...)                   __VA_ARGS__
+#  define _LogIt(a_fFlags, a_iGroup, ...)               do { } while (0)
+#  define _LogItAlways(a_fFlags, a_iGroup, ...)         do { } while (0)
+# endif
+#endif
+
+
+/** @name Basic logging macros
+ * @{ */
+/** @def Log
+ * Level 1 logging that works regardless of the group settings.
+ */
+#define LogAlways(a)    LogItAlways(RTLOGGRPFLAGS_LEVEL_1, LOG_GROUP, a)
+
+/** @def Log
+ * Level 1 logging.
+ */
+#define Log(a)          LogIt(RTLOGGRPFLAGS_LEVEL_1, LOG_GROUP, a)
+
+/** @def Log2
+ * Level 2 logging.
+ */
+#define Log2(a)         LogIt(RTLOGGRPFLAGS_LEVEL_2,  LOG_GROUP, a)
+
+/** @def Log3
+ * Level 3 logging.
+ */
+#define Log3(a)         LogIt(RTLOGGRPFLAGS_LEVEL_3,  LOG_GROUP, a)
+
+/** @def Log4
+ * Level 4 logging.
+ */
+#define Log4(a)         LogIt(RTLOGGRPFLAGS_LEVEL_4,  LOG_GROUP, a)
+
+/** @def Log5
+ * Level 5 logging.
+ */
+#define Log5(a)         LogIt(RTLOGGRPFLAGS_LEVEL_5,  LOG_GROUP, a)
+
+/** @def Log6
+ * Level 6 logging.
+ */
+#define Log6(a)         LogIt(RTLOGGRPFLAGS_LEVEL_6,  LOG_GROUP, a)
+
+/** @def Log7
+ * Level 7 logging.
+ */
+#define Log7(a)         LogIt(RTLOGGRPFLAGS_LEVEL_7,  LOG_GROUP, a)
+
+/** @def Log8
+ * Level 8 logging.
+ */
+#define Log8(a)         LogIt(RTLOGGRPFLAGS_LEVEL_8,  LOG_GROUP, a)
+
+/** @def Log9
+ * Level 9 logging.
+ */
+#define Log9(a)         LogIt(RTLOGGRPFLAGS_LEVEL_9,  LOG_GROUP, a)
+
+/** @def Log10
+ * Level 10 logging.
+ */
+#define Log10(a)        LogIt(RTLOGGRPFLAGS_LEVEL_10, LOG_GROUP, a)
+
+/** @def Log11
+ * Level 11 logging.
+ */
+#define Log11(a)        LogIt(RTLOGGRPFLAGS_LEVEL_11, LOG_GROUP, a)
+
+/** @def Log12
+ * Level 12 logging.
+ */
+#define Log12(a)        LogIt(RTLOGGRPFLAGS_LEVEL_12,  LOG_GROUP, a)
+
+/** @def LogFlow
+ * Logging of execution flow.
+ */
+#define LogFlow(a)      LogIt(RTLOGGRPFLAGS_FLOW,      LOG_GROUP, a)
+
+/** @def LogWarn
+ * Logging of warnings.
+ */
+#define LogWarn(a)      LogIt(RTLOGGRPFLAGS_WARN,      LOG_GROUP, a)
+/** @} */
+
+
+/** @name Logging macros prefixing the current function name.
+ * @{ */
+/** @def LogFunc
+ * Level 1 logging inside C/C++ functions.
+ *
+ * Prepends the given log message with the function name followed by a
+ * semicolon and space.
+ *
+ * @param   a   Log message in format <tt>("string\n" [, args])</tt>.
+ */
+#ifdef LOG_USE_C99
+# define LogFunc(a)   _LogIt(RTLOGGRPFLAGS_LEVEL_1, LOG_GROUP, LOG_FN_FMT ": %M", RT_GCC_EXTENSION __PRETTY_FUNCTION__, _LogRemoveParentheseis a )
+#else
+# define LogFunc(a)   do { Log((LOG_FN_FMT ": ", RT_GCC_EXTENSION __PRETTY_FUNCTION__)); Log(a); } while (0)
+#endif
+
+/** @def Log2Func
+ * Level 2 logging inside C/C++ functions.
+ *
+ * Prepends the given log message with the function name followed by a
+ * semicolon and space.
+ *
+ * @param   a   Log message in format <tt>("string\n" [, args])</tt>.
+ */
+#ifdef LOG_USE_C99
+# define Log2Func(a)  _LogIt(RTLOGGRPFLAGS_LEVEL_2, LOG_GROUP, LOG_FN_FMT ": %M", RT_GCC_EXTENSION __PRETTY_FUNCTION__, _LogRemoveParentheseis a )
+#else
+# define Log2Func(a)  do { Log2((LOG_FN_FMT ": ", RT_GCC_EXTENSION __PRETTY_FUNCTION__)); Log2(a); } while (0)
+#endif
+
+/** @def Log3Func
+ * Level 3 logging inside C/C++ functions.
+ *
+ * Prepends the given log message with the function name followed by a
+ * semicolon and space.
+ *
+ * @param   a   Log message in format <tt>("string\n" [, args])</tt>.
+ */
+#ifdef LOG_USE_C99
+# define Log3Func(a)  _LogIt(RTLOGGRPFLAGS_LEVEL_3, LOG_GROUP, LOG_FN_FMT ": %M", RT_GCC_EXTENSION __PRETTY_FUNCTION__, _LogRemoveParentheseis a )
+#else
+# define Log3Func(a)  do { Log3((LOG_FN_FMT ": ", RT_GCC_EXTENSION __PRETTY_FUNCTION__)); Log3(a); } while (0)
+#endif
+
+/** @def Log4Func
+ * Level 4 logging inside C/C++ functions.
+ *
+ * Prepends the given log message with the function name followed by a
+ * semicolon and space.
+ *
+ * @param   a   Log message in format <tt>("string\n" [, args])</tt>.
+ */
+#ifdef LOG_USE_C99
+# define Log4Func(a)  _LogIt(RTLOGGRPFLAGS_LEVEL_4, LOG_GROUP, LOG_FN_FMT ": %M", RT_GCC_EXTENSION __PRETTY_FUNCTION__, _LogRemoveParentheseis a )
+#else
+# define Log4Func(a)  do { Log4((LOG_FN_FMT ": ", RT_GCC_EXTENSION __PRETTY_FUNCTION__)); Log4(a); } while (0)
+#endif
+
+/** @def Log5Func
+ * Level 5 logging inside C/C++ functions.
+ *
+ * Prepends the given log message with the function name followed by a
+ * semicolon and space.
+ *
+ * @param   a   Log message in format <tt>("string\n" [, args])</tt>.
+ */
+#ifdef LOG_USE_C99
+# define Log5Func(a)  _LogIt(RTLOGGRPFLAGS_LEVEL_5, LOG_GROUP, LOG_FN_FMT ": %M", RT_GCC_EXTENSION __PRETTY_FUNCTION__, _LogRemoveParentheseis a )
+#else
+# define Log5Func(a)  do { Log5((LOG_FN_FMT ": ", RT_GCC_EXTENSION __PRETTY_FUNCTION__)); Log5(a); } while (0)
+#endif
+
+/** @def Log6Func
+ * Level 6 logging inside C/C++ functions.
+ *
+ * Prepends the given log message with the function name followed by a
+ * semicolon and space.
+ *
+ * @param   a   Log message in format <tt>("string\n" [, args])</tt>.
+ */
+#ifdef LOG_USE_C99
+# define Log6Func(a)  _LogIt(RTLOGGRPFLAGS_LEVEL_6, LOG_GROUP, LOG_FN_FMT ": %M", RT_GCC_EXTENSION __PRETTY_FUNCTION__, _LogRemoveParentheseis a )
+#else
+# define Log6Func(a)  do { Log6((LOG_FN_FMT ": ", RT_GCC_EXTENSION __PRETTY_FUNCTION__)); Log6(a); } while (0)
+#endif
+
+/** @def Log7Func
+ * Level 7 logging inside C/C++ functions.
+ *
+ * Prepends the given log message with the function name followed by a
+ * semicolon and space.
+ *
+ * @param   a   Log message in format <tt>("string\n" [, args])</tt>.
+ */
+#ifdef LOG_USE_C99
+# define Log7Func(a)  _LogIt(RTLOGGRPFLAGS_LEVEL_7, LOG_GROUP, LOG_FN_FMT ": %M", RT_GCC_EXTENSION __PRETTY_FUNCTION__, _LogRemoveParentheseis a )
+#else
+# define Log7Func(a)  do { Log7((LOG_FN_FMT ": ", RT_GCC_EXTENSION __PRETTY_FUNCTION__)); Log7(a); } while (0)
+#endif
+
+/** @def Log8Func
+ * Level 8 logging inside C/C++ functions.
+ *
+ * Prepends the given log message with the function name followed by a
+ * semicolon and space.
+ *
+ * @param   a   Log message in format <tt>("string\n" [, args])</tt>.
+ */
+#ifdef LOG_USE_C99
+# define Log8Func(a)  _LogIt(RTLOGGRPFLAGS_LEVEL_8, LOG_GROUP, LOG_FN_FMT ": %M", RT_GCC_EXTENSION __PRETTY_FUNCTION__, _LogRemoveParentheseis a )
+#else
+# define Log8Func(a)  do { Log8((LOG_FN_FMT ": ", RT_GCC_EXTENSION __PRETTY_FUNCTION__)); Log8(a); } while (0)
+#endif
+
+/** @def Log9Func
+ * Level 9 logging inside C/C++ functions.
+ *
+ * Prepends the given log message with the function name followed by a
+ * semicolon and space.
+ *
+ * @param   a   Log message in format <tt>("string\n" [, args])</tt>.
+ */
+#ifdef LOG_USE_C99
+# define Log9Func(a)  _LogIt(RTLOGGRPFLAGS_LEVEL_9, LOG_GROUP, LOG_FN_FMT ": %M", RT_GCC_EXTENSION __PRETTY_FUNCTION__, _LogRemoveParentheseis a )
+#else
+# define Log9Func(a)  do { Log9((LOG_FN_FMT ": ", RT_GCC_EXTENSION __PRETTY_FUNCTION__)); Log9(a); } while (0)
+#endif
+
+/** @def Log10Func
+ * Level 10 logging inside C/C++ functions.
+ *
+ * Prepends the given log message with the function name followed by a
+ * semicolon and space.
+ *
+ * @param   a   Log message in format <tt>("string\n" [, args])</tt>.
+ */
+#ifdef LOG_USE_C99
+# define Log10Func(a) _LogIt(RTLOGGRPFLAGS_LEVEL_10, LOG_GROUP, LOG_FN_FMT ": %M", RT_GCC_EXTENSION __PRETTY_FUNCTION__, _LogRemoveParentheseis a )
+#else
+# define Log10Func(a) do { Log10((LOG_FN_FMT ": ", RT_GCC_EXTENSION __PRETTY_FUNCTION__)); Log10(a); } while (0)
+#endif
+
+/** @def Log11Func
+ * Level 11 logging inside C/C++ functions.
+ *
+ * Prepends the given log message with the function name followed by a
+ * semicolon and space.
+ *
+ * @param   a   Log message in format <tt>("string\n" [, args])</tt>.
+ */
+#ifdef LOG_USE_C99
+# define Log11Func(a) _LogIt(RTLOGGRPFLAGS_LEVEL_11, LOG_GROUP, LOG_FN_FMT ": %M", RT_GCC_EXTENSION __PRETTY_FUNCTION__, _LogRemoveParentheseis a )
+#else
+# define Log11Func(a) do { Log11((LOG_FN_FMT ": ", RT_GCC_EXTENSION __PRETTY_FUNCTION__)); Log11(a); } while (0)
+#endif
+
+/** @def Log12Func
+ * Level 12 logging inside C/C++ functions.
+ *
+ * Prepends the given log message with the function name followed by a
+ * semicolon and space.
+ *
+ * @param   a   Log message in format <tt>("string\n" [, args])</tt>.
+ */
+#ifdef LOG_USE_C99
+# define Log12Func(a) _LogIt(RTLOGGRPFLAGS_LEVEL_12, LOG_GROUP, LOG_FN_FMT ": %M", RT_GCC_EXTENSION __PRETTY_FUNCTION__, _LogRemoveParentheseis a )
+#else
+# define Log12Func(a) do { Log12((LOG_FN_FMT ": ", RT_GCC_EXTENSION __PRETTY_FUNCTION__)); Log12(a); } while (0)
+#endif
+
+/** @def LogFlowFunc
+ * Macro to log the execution flow inside C/C++ functions.
+ *
+ * Prepends the given log message with the function name followed by
+ * a semicolon and space.
+ *
+ * @param   a   Log message in format <tt>("string\n" [, args])</tt>.
+ */
+#ifdef LOG_USE_C99
+# define LogFlowFunc(a) \
+    _LogIt(RTLOGGRPFLAGS_FLOW, LOG_GROUP, LOG_FN_FMT ": %M", RT_GCC_EXTENSION __PRETTY_FUNCTION__, _LogRemoveParentheseis a )
+#else
+# define LogFlowFunc(a) \
+    do { LogFlow((LOG_FN_FMT ": ", RT_GCC_EXTENSION __PRETTY_FUNCTION__)); LogFlow(a); } while (0)
+#endif
+
+/** @def LogWarnFunc
+ * Macro to log a warning inside C/C++ functions.
+ *
+ * Prepends the given log message with the function name followed by
+ * a semicolon and space.
+ *
+ * @param   a   Log message in format <tt>("string\n" [, args])</tt>.
+ */
+#ifdef LOG_USE_C99
+# define LogWarnFunc(a) \
+    _LogIt(RTLOGGRPFLAGS_WARN, LOG_GROUP, LOG_FN_FMT ": %M", __PRETTY_FUNCTION__, _LogRemoveParentheseis a )
+#else
+# define LogWarnFunc(a) \
+    do { LogFlow((LOG_FN_FMT ": ", __PRETTY_FUNCTION__)); LogFlow(a); } while (0)
+#endif
+/** @} */
+
+
+/** @name Logging macros prefixing the this pointer value and method name.
+ * @{ */
+
+/** @def LogThisFunc
+ * Level 1 logging inside a C++ non-static method, with object pointer and
+ * method name prefixed to the given message.
+ * @param   a   Log message in format <tt>("string\n" [, args])</tt>.
+ */
+#ifdef LOG_USE_C99
+# define LogThisFunc(a) \
+    _LogIt(RTLOGGRPFLAGS_LEVEL_1, LOG_GROUP, "{%p} " LOG_FN_FMT ": %M", this, __PRETTY_FUNCTION__, _LogRemoveParentheseis a )
+#else
+# define LogThisFunc(a) do { Log(("{%p} " LOG_FN_FMT ": ", this, __PRETTY_FUNCTION__)); Log(a); } while (0)
+#endif
+
+/** @def Log2ThisFunc
+ * Level 2 logging inside a C++ non-static method, with object pointer and
+ * method name prefixed to the given message.
+ * @param   a   Log message in format <tt>("string\n" [, args])</tt>.
+ */
+#ifdef LOG_USE_C99
+# define Log2ThisFunc(a) \
+    _LogIt(RTLOGGRPFLAGS_LEVEL_2, LOG_GROUP, "{%p} " LOG_FN_FMT ": %M", this, __PRETTY_FUNCTION__, _LogRemoveParentheseis a )
+#else
+# define Log2ThisFunc(a) do { Log2(("{%p} " LOG_FN_FMT ": ", this, __PRETTY_FUNCTION__)); Log2(a); } while (0)
+#endif
+
+/** @def Log3ThisFunc
+ * Level 3 logging inside a C++ non-static method, with object pointer and
+ * method name prefixed to the given message.
+ * @param   a   Log message in format <tt>("string\n" [, args])</tt>.
+ */
+#ifdef LOG_USE_C99
+# define Log3ThisFunc(a) \
+    _LogIt(RTLOGGRPFLAGS_LEVEL_3, LOG_GROUP, "{%p} " LOG_FN_FMT ": %M", this, __PRETTY_FUNCTION__, _LogRemoveParentheseis a )
+#else
+# define Log3ThisFunc(a) do { Log3(("{%p} " LOG_FN_FMT ": ", this, __PRETTY_FUNCTION__)); Log3(a); } while (0)
+#endif
+
+/** @def Log4ThisFunc
+ * Level 4 logging inside a C++ non-static method, with object pointer and
+ * method name prefixed to the given message.
+ * @param   a   Log message in format <tt>("string\n" [, args])</tt>.
+ */
+#ifdef LOG_USE_C99
+# define Log4ThisFunc(a) \
+    _LogIt(RTLOGGRPFLAGS_LEVEL_4, LOG_GROUP, "{%p} " LOG_FN_FMT ": %M", this, __PRETTY_FUNCTION__, _LogRemoveParentheseis a )
+#else
+# define Log4ThisFunc(a) do { Log4(("{%p} " LOG_FN_FMT ": ", this, __PRETTY_FUNCTION__)); Log4(a); } while (0)
+#endif
+
+/** @def Log5ThisFunc
+ * Level 5 logging inside a C++ non-static method, with object pointer and
+ * method name prefixed to the given message.
+ * @param   a   Log message in format <tt>("string\n" [, args])</tt>.
+ */
+#ifdef LOG_USE_C99
+# define Log5ThisFunc(a) \
+    _LogIt(RTLOGGRPFLAGS_LEVEL_5, LOG_GROUP, "{%p} " LOG_FN_FMT ": %M", this, __PRETTY_FUNCTION__, _LogRemoveParentheseis a )
+#else
+# define Log5ThisFunc(a) do { Log5(("{%p} " LOG_FN_FMT ": ", this, __PRETTY_FUNCTION__)); Log5(a); } while (0)
+#endif
+
+/** @def Log6ThisFunc
+ * Level 6 logging inside a C++ non-static method, with object pointer and
+ * method name prefixed to the given message.
+ * @param   a   Log message in format <tt>("string\n" [, args])</tt>.
+ */
+#ifdef LOG_USE_C99
+# define Log6ThisFunc(a) \
+    _LogIt(RTLOGGRPFLAGS_LEVEL_6, LOG_GROUP, "{%p} " LOG_FN_FMT ": %M", this, __PRETTY_FUNCTION__, _LogRemoveParentheseis a )
+#else
+# define Log6ThisFunc(a) do { Log6(("{%p} " LOG_FN_FMT ": ", this, __PRETTY_FUNCTION__)); Log6(a); } while (0)
+#endif
+
+/** @def Log7ThisFunc
+ * Level 7 logging inside a C++ non-static method, with object pointer and
+ * method name prefixed to the given message.
+ * @param   a   Log message in format <tt>("string\n" [, args])</tt>.
+ */
+#ifdef LOG_USE_C99
+# define Log7ThisFunc(a) \
+    _LogIt(RTLOGGRPFLAGS_LEVEL_7, LOG_GROUP, "{%p} " LOG_FN_FMT ": %M", this, __PRETTY_FUNCTION__, _LogRemoveParentheseis a )
+#else
+# define Log7ThisFunc(a) do { Log7(("{%p} " LOG_FN_FMT ": ", this, __PRETTY_FUNCTION__)); Log7(a); } while (0)
+#endif
+
+/** @def Log8ThisFunc
+ * Level 8 logging inside a C++ non-static method, with object pointer and
+ * method name prefixed to the given message.
+ * @param   a   Log message in format <tt>("string\n" [, args])</tt>.
+ */
+#ifdef LOG_USE_C99
+# define Log8ThisFunc(a) \
+    _LogIt(RTLOGGRPFLAGS_LEVEL_8, LOG_GROUP, "{%p} " LOG_FN_FMT ": %M", this, __PRETTY_FUNCTION__, _LogRemoveParentheseis a )
+#else
+# define Log8ThisFunc(a) do { Log8(("{%p} " LOG_FN_FMT ": ", this, __PRETTY_FUNCTION__)); Log8(a); } while (0)
+#endif
+
+/** @def Log9ThisFunc
+ * Level 9 logging inside a C++ non-static method, with object pointer and
+ * method name prefixed to the given message.
+ * @param   a   Log message in format <tt>("string\n" [, args])</tt>.
+ */
+#ifdef LOG_USE_C99
+# define Log9ThisFunc(a) \
+    _LogIt(RTLOGGRPFLAGS_LEVEL_9, LOG_GROUP, "{%p} " LOG_FN_FMT ": %M", this, __PRETTY_FUNCTION__, _LogRemoveParentheseis a )
+#else
+# define Log9ThisFunc(a) do { Log9(("{%p} " LOG_FN_FMT ": ", this, __PRETTY_FUNCTION__)); Log9(a); } while (0)
+#endif
+
+/** @def Log10ThisFunc
+ * Level 10 logging inside a C++ non-static method, with object pointer and
+ * method name prefixed to the given message.
+ * @param   a   Log message in format <tt>("string\n" [, args])</tt>.
+ */
+#ifdef LOG_USE_C99
+# define Log10ThisFunc(a) \
+    _LogIt(RTLOGGRPFLAGS_LEVEL_10, LOG_GROUP, "{%p} " LOG_FN_FMT ": %M", this, __PRETTY_FUNCTION__, _LogRemoveParentheseis a )
+#else
+# define Log10ThisFunc(a) do { Log10(("{%p} " LOG_FN_FMT ": ", this, __PRETTY_FUNCTION__)); Log10(a); } while (0)
+#endif
+
+/** @def Log11ThisFunc
+ * Level 11 logging inside a C++ non-static method, with object pointer and
+ * method name prefixed to the given message.
+ * @param   a   Log message in format <tt>("string\n" [, args])</tt>.
+ */
+#ifdef LOG_USE_C99
+# define Log11ThisFunc(a) \
+    _LogIt(RTLOGGRPFLAGS_LEVEL_11, LOG_GROUP, "{%p} " LOG_FN_FMT ": %M", this, __PRETTY_FUNCTION__, _LogRemoveParentheseis a )
+#else
+# define Log11ThisFunc(a) do { Log11(("{%p} " LOG_FN_FMT ": ", this, __PRETTY_FUNCTION__)); Log11(a); } while (0)
+#endif
+
+/** @def Log12ThisFunc
+ * Level 12 logging inside a C++ non-static method, with object pointer and
+ * method name prefixed to the given message.
+ * @param   a   Log message in format <tt>("string\n" [, args])</tt>.
+ */
+#ifdef LOG_USE_C99
+# define Log12ThisFunc(a) \
+    _LogIt(RTLOGGRPFLAGS_LEVEL_12, LOG_GROUP, "{%p} " LOG_FN_FMT ": %M", this, __PRETTY_FUNCTION__, _LogRemoveParentheseis a )
+#else
+# define Log12ThisFunc(a) do { Log12(("{%p} " LOG_FN_FMT ": ", this, __PRETTY_FUNCTION__)); Log12(a); } while (0)
+#endif
+
+/** @def LogFlowThisFunc
+ * Flow level logging inside a C++ non-static method, with object pointer and
+ * method name prefixed to the given message.
+ * @param   a   Log message in format <tt>("string\n" [, args])</tt>.
+ */
+#ifdef LOG_USE_C99
+# define LogFlowThisFunc(a) \
+    _LogIt(RTLOGGRPFLAGS_FLOW, LOG_GROUP, "{%p} " LOG_FN_FMT ": %M", this, __PRETTY_FUNCTION__, _LogRemoveParentheseis a )
+#else
+# define LogFlowThisFunc(a) do { LogFlow(("{%p} " LOG_FN_FMT ": ", this, __PRETTY_FUNCTION__)); LogFlow(a); } while (0)
+#endif
+
+/** @def LogWarnThisFunc
+ * Warning level logging inside a C++ non-static method, with object pointer and
+ * method name prefixed to the given message.
+ * @param   a   Log message in format <tt>("string\n" [, args])</tt>.
+ */
+#ifdef LOG_USE_C99
+# define LogWarnThisFunc(a) \
+    _LogIt(RTLOGGRPFLAGS_WARN, LOG_GROUP, "{%p} " LOG_FN_FMT ": %M", this, __PRETTY_FUNCTION__, _LogRemoveParentheseis a )
+#else
+# define LogWarnThisFunc(a) do { LogWarn(("{%p} " LOG_FN_FMT ": ", this, __PRETTY_FUNCTION__)); LogWarn(a); } while (0)
+#endif
+/** @} */
+
+
+/** @name Misc Logging Macros
+ * @{ */
+
+/** @def Log1Warning
+ * The same as Log(), but prepents a <tt>"WARNING! "</tt> string to the message.
+ *
+ * @param   a   Custom log message in format <tt>("string\n" [, args])</tt>.
+ */
+#if defined(LOG_USE_C99)
+# define Log1Warning(a)     _LogIt(RTLOGGRPFLAGS_LEVEL_1, LOG_GROUP, "WARNING! %M", _LogRemoveParentheseis a )
+#else
+# define Log1Warning(a)     do { Log(("WARNING! ")); Log(a); } while (0)
+#endif
+
+/** @def Log1WarningFunc
+ * The same as LogWarning(), but prepents the log message with the function name.
+ *
+ * @param   a   Log message in format <tt>("string\n" [, args])</tt>.
+ */
+#ifdef LOG_USE_C99
+# define Log1WarningFunc(a) \
+    _LogIt(RTLOGGRPFLAGS_LEVEL_1, LOG_GROUP, LOG_FN_FMT ": WARNING! %M", __PRETTY_FUNCTION__, _LogRemoveParentheseis a )
+#else
+# define Log1WarningFunc(a) \
+    do { Log((LOG_FN_FMT ": WARNING! ", __PRETTY_FUNCTION__)); Log(a); } while (0)
+#endif
+
+/** @def Log1WarningThisFunc
+ * The same as LogWarningFunc() but for class functions (methods): the resulting
+ * log line is additionally prepended with a hex value of |this| pointer.
+ *
+ * @param   a   Log message in format <tt>("string\n" [, args])</tt>.
+ */
+#ifdef LOG_USE_C99
+# define Log1WarningThisFunc(a) \
+    _LogIt(RTLOGGRPFLAGS_LEVEL_1, LOG_GROUP, "{%p} " LOG_FN_FMT ": WARNING! %M", this, __PRETTY_FUNCTION__, _LogRemoveParentheseis a )
+#else
+# define Log1WarningThisFunc(a) \
+    do { Log(("{%p} " LOG_FN_FMT ": WARNING! ", this, __PRETTY_FUNCTION__)); Log(a); } while (0)
+#endif
+
+
+/** Shortcut to |LogFlowFunc ("ENTER\n")|, marks the beginnig of the function. */
+#define LogFlowFuncEnter()      LogFlowFunc(("ENTER\n"))
+
+/** Shortcut to |LogFlowFunc ("LEAVE\n")|, marks the end of the function. */
+#define LogFlowFuncLeave()      LogFlowFunc(("LEAVE\n"))
+
+/** Shortcut to |LogFlowFunc ("LEAVE: %Rrc\n")|, marks the end of the function. */
+#define LogFlowFuncLeaveRC(rc)  LogFlowFunc(("LEAVE: %Rrc\n", (rc)))
+
+/** Shortcut to |LogFlowThisFunc ("ENTER\n")|, marks the beginnig of the function. */
+#define LogFlowThisFuncEnter()  LogFlowThisFunc(("ENTER\n"))
+
+/** Shortcut to |LogFlowThisFunc ("LEAVE\n")|, marks the end of the function. */
+#define LogFlowThisFuncLeave()  LogFlowThisFunc(("LEAVE\n"))
+
+
+/** @def LogObjRefCnt
+ * Helper macro to print the current reference count of the given COM object
+ * to the log file.
+ *
+ * @param pObj  Pointer to the object in question (must be a pointer to an
+ *              IUnknown subclass or simply define COM-style AddRef() and
+ *              Release() methods)
+ */
+#define LogObjRefCnt(pObj) \
+    do { \
+        if (LogIsFlowEnabled()) \
+        { \
+            int cRefsForLog = (pObj)->AddRef(); \
+            LogFlow((#pObj "{%p}.refCnt=%d\n", (pObj), cRefsForLog - 1)); \
+            (pObj)->Release(); \
+        } \
+    } while (0)
+/** @} */
+
+
+
+/** @name Passing Function Call Position When Logging.
+ *
+ * This is a little bit ugly as we have to omit the comma before the
+ * position parameters so that we don't inccur any overhead in non-logging
+ * builds (!defined(LOG_ENABLED).
+ *
+ * @{  */
+/** Source position for passing to a function call. */
+#ifdef LOG_ENABLED
+# define RTLOG_COMMA_SRC_POS        , __FILE__, __LINE__, __PRETTY_FUNCTION__
+#else
+# define RTLOG_COMMA_SRC_POS        RT_NOTHING
+#endif
+/** Source position declaration. */
+#ifdef LOG_ENABLED
+# define RTLOG_COMMA_SRC_POS_DECL   , const char *pszFile, unsigned iLine, const char *pszFunction
+#else
+# define RTLOG_COMMA_SRC_POS_DECL   RT_NOTHING
+#endif
+/** Source position arguments. */
+#ifdef LOG_ENABLED
+# define RTLOG_COMMA_SRC_POS_ARGS   , pszFile, iLine, pszFunction
+#else
+# define RTLOG_COMMA_SRC_POS_ARGS   RT_NOTHING
+#endif
+/** Applies NOREF() to the source position arguments. */
+#ifdef LOG_ENABLED
+# define RTLOG_SRC_POS_NOREF()      do { NOREF(pszFile); NOREF(iLine); NOREF(pszFunction); } while (0)
+#else
+# define RTLOG_SRC_POS_NOREF()      do { } while (0)
+#endif
+/** @}  */
+
+
+
+/** @name Release Logging
+ * @{
+ */
+
+#ifdef DOXYGEN_RUNNING
+# define RTLOG_REL_DISABLED
+# define RTLOG_REL_ENABLED
+#endif
+
+/** @def RTLOG_REL_DISABLED
+ * Use this compile time define to disable all release logging
+ * macros.
+ */
+
+/** @def RTLOG_REL_ENABLED
+ * Use this compile time define to override RTLOG_REL_DISABLE.
+ */
+
+/*
+ * Determine whether release logging is enabled and forcefully normalize the indicators.
+ */
+#if !defined(RTLOG_REL_DISABLED) || defined(RTLOG_REL_ENABLED)
+# undef  RTLOG_REL_DISABLED
+# undef  RTLOG_REL_ENABLED
+# define RTLOG_REL_ENABLED
+#else
+# undef  RTLOG_REL_ENABLED
+# undef  RTLOG_REL_DISABLED
+# define RTLOG_REL_DISABLED
+#endif
+
+/** @name Macros for checking whether a release log level is enabled.
+ * @{ */
+/** @def LogRelIsItEnabled
+ * Checks whether the specified release logging group is enabled or not.
+ */
+#define LogRelIsItEnabled(a_fFlags, a_iGroup) ( RTLogRelGetDefaultInstanceEx(RT_MAKE_U32(a_fFlags, a_iGroup)) != NULL )
+
+/** @def LogRelIsEnabled
+ * Checks whether level 1 release logging is enabled.
+ */
+#define LogRelIsEnabled()      LogRelIsItEnabled(RTLOGGRPFLAGS_LEVEL_1, LOG_GROUP)
+
+/** @def LogRelIs2Enabled
+ * Checks whether level 2 release logging is enabled.
+ */
+#define LogRelIs2Enabled()     LogRelIsItEnabled(RTLOGGRPFLAGS_LEVEL_2, LOG_GROUP)
+
+/** @def LogRelIs3Enabled
+ * Checks whether level 3 release logging is enabled.
+ */
+#define LogRelIs3Enabled()     LogRelIsItEnabled(RTLOGGRPFLAGS_LEVEL_3, LOG_GROUP)
+
+/** @def LogRelIs4Enabled
+ * Checks whether level 4 release logging is enabled.
+ */
+#define LogRelIs4Enabled()     LogRelIsItEnabled(RTLOGGRPFLAGS_LEVEL_4, LOG_GROUP)
+
+/** @def LogRelIs5Enabled
+ * Checks whether level 5 release logging is enabled.
+ */
+#define LogRelIs5Enabled()     LogRelIsItEnabled(RTLOGGRPFLAGS_LEVEL_5, LOG_GROUP)
+
+/** @def LogRelIs6Enabled
+ * Checks whether level 6 release logging is enabled.
+ */
+#define LogRelIs6Enabled()     LogRelIsItEnabled(RTLOGGRPFLAGS_LEVEL_6, LOG_GROUP)
+
+/** @def LogRelIs7Enabled
+ * Checks whether level 7 release logging is enabled.
+ */
+#define LogRelIs7Enabled()     LogRelIsItEnabled(RTLOGGRPFLAGS_LEVEL_7, LOG_GROUP)
+
+/** @def LogRelIs8Enabled
+ * Checks whether level 8 release logging is enabled.
+ */
+#define LogRelIs8Enabled()     LogRelIsItEnabled(RTLOGGRPFLAGS_LEVEL_8, LOG_GROUP)
+
+/** @def LogRelIs2Enabled
+ * Checks whether level 9 release logging is enabled.
+ */
+#define LogRelIs9Enabled()     LogRelIsItEnabled(RTLOGGRPFLAGS_LEVEL_9, LOG_GROUP)
+
+/** @def LogRelIs10Enabled
+ * Checks whether level 10 release logging is enabled.
+ */
+#define LogRelIs10Enabled()    LogRelIsItEnabled(RTLOGGRPFLAGS_LEVEL_10, LOG_GROUP)
+
+/** @def LogRelIs11Enabled
+ * Checks whether level 10 release logging is enabled.
+ */
+#define LogRelIs11Enabled()    LogRelIsItEnabled(RTLOGGRPFLAGS_LEVEL_11, LOG_GROUP)
+
+/** @def LogRelIs12Enabled
+ * Checks whether level 12 release logging is enabled.
+ */
+#define LogRelIs12Enabled()    LogRelIsItEnabled(RTLOGGRPFLAGS_LEVEL_12, LOG_GROUP)
+
+/** @def LogRelIsFlowEnabled
+ * Checks whether execution flow release logging is enabled.
+ */
+#define LogRelIsFlowEnabled()  LogRelIsItEnabled(RTLOGGRPFLAGS_FLOW, LOG_GROUP)
+
+/** @def LogRelIsWarnEnabled
+ * Checks whether warning level release logging is enabled.
+ */
+#define LogRelIsWarnEnabled()  LogRelIsItEnabled(RTLOGGRPFLAGS_FLOW, LOG_GROUP)
+/** @} */
+
+
+/** @def LogRelIt
+ * Write to specific logger if group enabled.
+ */
+/** @def LogRelItLikely
+ * Write to specific logger if group enabled, assuming it likely it is enabled.
+ */
+/** @def LogRelMaxIt
+ * Write to specific logger if group enabled and at less than a_cMax messages
+ * have hit the log.  Uses a static variable to count.
+ */
+#ifdef RTLOG_REL_ENABLED
+# if defined(LOG_USE_C99)
+#  define _LogRelRemoveParentheseis(...)                    __VA_ARGS__
+#  define _LogRelIt(a_fFlags, a_iGroup, ...) \
+    do \
+    { \
+        PRTLOGGER LogRelIt_pLogger = RTLogRelGetDefaultInstanceEx(RT_MAKE_U32(a_fFlags, a_iGroup)); \
+        if (RT_LIKELY(!LogRelIt_pLogger)) \
+        { /* likely */ } \
+        else \
+            RTLogLoggerEx(LogRelIt_pLogger, a_fFlags, a_iGroup, __VA_ARGS__); \
+        _LogIt(a_fFlags, a_iGroup, __VA_ARGS__); \
+    } while (0)
+#  define LogRelIt(a_fFlags, a_iGroup, fmtargs) \
+    _LogRelIt(a_fFlags, a_iGroup, _LogRelRemoveParentheseis fmtargs)
+#  define _LogRelItLikely(a_fFlags, a_iGroup, ...) \
+    do \
+    { \
+        PRTLOGGER LogRelIt_pLogger = RTLogRelGetDefaultInstanceEx(RT_MAKE_U32(a_fFlags, a_iGroup)); \
+        if (LogRelIt_pLogger) \
+            RTLogLoggerEx(LogRelIt_pLogger, a_fFlags, a_iGroup, __VA_ARGS__); \
+        _LogIt(a_fFlags, a_iGroup, __VA_ARGS__); \
+    } while (0)
+#  define LogRelItLikely(a_fFlags, a_iGroup, fmtargs) \
+    _LogRelItLikely(a_fFlags, a_iGroup, _LogRelRemoveParentheseis fmtargs)
+#  define _LogRelMaxIt(a_cMax, a_fFlags, a_iGroup, ...) \
+    do \
+    { \
+        PRTLOGGER LogRelIt_pLogger = RTLogRelGetDefaultInstanceEx(RT_MAKE_U32(a_fFlags, a_iGroup)); \
+        if (LogRelIt_pLogger) \
+        { \
+            static uint32_t s_LogRelMaxIt_cLogged = 0; \
+            if (s_LogRelMaxIt_cLogged < (a_cMax)) \
+            { \
+                s_LogRelMaxIt_cLogged++; \
+                RTLogLoggerEx(LogRelIt_pLogger, a_fFlags, a_iGroup, __VA_ARGS__); \
+            } \
+        } \
+        _LogIt(a_fFlags, a_iGroup, __VA_ARGS__); \
+    } while (0)
+#  define LogRelMaxIt(a_cMax, a_fFlags, a_iGroup, fmtargs) \
+    _LogRelMaxIt(a_cMax, a_fFlags, a_iGroup, _LogRelRemoveParentheseis fmtargs)
+# else
+#  define LogRelItLikely(a_fFlags, a_iGroup, fmtargs) \
+   do \
+   { \
+       PRTLOGGER LogRelIt_pLogger = RTLogRelGetDefaultInstanceEx(RT_MAKE_U32(a_fFlags, a_iGroup)); \
+       if (LogRelIt_pLogger) \
+       { \
+           LogRelIt_pLogger->pfnLogger fmtargs; \
+       } \
+       LogIt(a_fFlags, a_iGroup, fmtargs); \
+  } while (0)
+#  define LogRelIt(a_fFlags, a_iGroup, fmtargs) \
+   do \
+   { \
+       PRTLOGGER LogRelIt_pLogger = RTLogRelGetDefaultInstanceEx(RT_MAKE_U32(a_fFlags, a_iGroup)); \
+       if (RT_LIKELY(!LogRelIt_pLogger)) \
+       { /* likely */ } \
+       else \
+       { \
+           LogRelIt_pLogger->pfnLogger fmtargs; \
+       } \
+       LogIt(a_fFlags, a_iGroup, fmtargs); \
+  } while (0)
+#  define LogRelMaxIt(a_cMax, a_fFlags, a_iGroup, fmtargs) \
+   do \
+   { \
+       PRTLOGGER LogRelIt_pLogger = RTLogRelGetDefaultInstanceEx(RT_MAKE_U32(a_fFlags, a_iGroup)); \
+       if (LogRelIt_pLogger) \
+       { \
+           static uint32_t s_LogRelMaxIt_cLogged = 0; \
+           if (s_LogRelMaxIt_cLogged < (a_cMax)) \
+           { \
+               s_LogRelMaxIt_cLogged++; \
+               LogRelIt_pLogger->pfnLogger fmtargs; \
+           } \
+       } \
+       LogIt(a_fFlags, a_iGroup, fmtargs); \
+  } while (0)
+# endif
+#else   /* !RTLOG_REL_ENABLED */
+# define LogRelIt(a_fFlags, a_iGroup, fmtargs)              do { } while (0)
+# define LogRelItLikely(a_fFlags, a_iGroup, fmtargs)        do { } while (0)
+# define LogRelMaxIt(a_cMax, a_fFlags, a_iGroup, fmtargs)   do { } while (0)
+# if defined(LOG_USE_C99)
+#  define _LogRelRemoveParentheseis(...)                    __VA_ARGS__
+#  define _LogRelIt(a_fFlags, a_iGroup, ...)                do { } while (0)
+#  define _LogRelItLikely(a_fFlags, a_iGroup, ...)          do { } while (0)
+#  define _LogRelMaxIt(a_cMax, a_fFlags, a_iGroup, ...)     do { } while (0)
+# endif
+#endif  /* !RTLOG_REL_ENABLED */
+
+
+/** @name Basic release logging macros
+ * @{ */
+/** @def LogRel
+ * Level 1 release logging.
+ */
+#define LogRel(a)           LogRelItLikely(RTLOGGRPFLAGS_LEVEL_1, LOG_GROUP, a)
+
+/** @def LogRel2
+ * Level 2 release logging.
+ */
+#define LogRel2(a)          LogRelIt(RTLOGGRPFLAGS_LEVEL_2,  LOG_GROUP, a)
+
+/** @def LogRel3
+ * Level 3 release logging.
+ */
+#define LogRel3(a)          LogRelIt(RTLOGGRPFLAGS_LEVEL_3,  LOG_GROUP, a)
+
+/** @def LogRel4
+ * Level 4 release logging.
+ */
+#define LogRel4(a)          LogRelIt(RTLOGGRPFLAGS_LEVEL_4,  LOG_GROUP, a)
+
+/** @def LogRel5
+ * Level 5 release logging.
+ */
+#define LogRel5(a)          LogRelIt(RTLOGGRPFLAGS_LEVEL_5,  LOG_GROUP, a)
+
+/** @def LogRel6
+ * Level 6 release logging.
+ */
+#define LogRel6(a)          LogRelIt(RTLOGGRPFLAGS_LEVEL_6,  LOG_GROUP, a)
+
+/** @def LogRel7
+ * Level 7 release logging.
+ */
+#define LogRel7(a)          LogRelIt(RTLOGGRPFLAGS_LEVEL_7,  LOG_GROUP, a)
+
+/** @def LogRel8
+ * Level 8 release logging.
+ */
+#define LogRel8(a)          LogRelIt(RTLOGGRPFLAGS_LEVEL_8,  LOG_GROUP, a)
+
+/** @def LogRel9
+ * Level 9 release logging.
+ */
+#define LogRel9(a)          LogRelIt(RTLOGGRPFLAGS_LEVEL_9,  LOG_GROUP, a)
+
+/** @def LogRel10
+ * Level 10 release logging.
+ */
+#define LogRel10(a)         LogRelIt(RTLOGGRPFLAGS_LEVEL_10, LOG_GROUP, a)
+
+/** @def LogRel11
+ * Level 11 release logging.
+ */
+#define LogRel11(a)         LogRelIt(RTLOGGRPFLAGS_LEVEL_11, LOG_GROUP, a)
+
+/** @def LogRel12
+ * Level 12 release logging.
+ */
+#define LogRel12(a)         LogRelIt(RTLOGGRPFLAGS_LEVEL_12, LOG_GROUP, a)
+
+/** @def LogRelFlow
+ * Logging of execution flow.
+ */
+#define LogRelFlow(a)       LogRelIt(RTLOGGRPFLAGS_FLOW,     LOG_GROUP, a)
+
+/** @def LogRelWarn
+ * Warning level release logging.
+ */
+#define LogRelWarn(a)       LogRelIt(RTLOGGRPFLAGS_WARN,     LOG_GROUP, a)
+/** @} */
+
+
+
+/** @name Basic release logging macros with local max
+ * @{ */
+/** @def LogRelMax
+ * Level 1 release logging with a max number of log entries.
+ */
+#define LogRelMax(a_cMax, a)        LogRelMaxIt(a_cMax, RTLOGGRPFLAGS_LEVEL_1, LOG_GROUP, a)
+
+/** @def LogRelMax2
+ * Level 2 release logging with a max number of log entries.
+ */
+#define LogRelMax2(a_cMax, a)       LogRelMaxIt(a_cMax, RTLOGGRPFLAGS_LEVEL_2,  LOG_GROUP, a)
+
+/** @def LogRelMax3
+ * Level 3 release logging with a max number of log entries.
+ */
+#define LogRelMax3(a_cMax, a)       LogRelMaxIt(a_cMax, RTLOGGRPFLAGS_LEVEL_3,  LOG_GROUP, a)
+
+/** @def LogRelMax4
+ * Level 4 release logging with a max number of log entries.
+ */
+#define LogRelMax4(a_cMax, a)       LogRelMaxIt(a_cMax, RTLOGGRPFLAGS_LEVEL_4,  LOG_GROUP, a)
+
+/** @def LogRelMax5
+ * Level 5 release logging with a max number of log entries.
+ */
+#define LogRelMax5(a_cMax, a)       LogRelMaxIt(a_cMax, RTLOGGRPFLAGS_LEVEL_5,  LOG_GROUP, a)
+
+/** @def LogRelMax6
+ * Level 6 release logging with a max number of log entries.
+ */
+#define LogRelMax6(a_cMax, a)       LogRelMaxIt(a_cMax, RTLOGGRPFLAGS_LEVEL_6,  LOG_GROUP, a)
+
+/** @def LogRelMax7
+ * Level 7 release logging with a max number of log entries.
+ */
+#define LogRelMax7(a_cMax, a)       LogRelMaxIt(a_cMax, RTLOGGRPFLAGS_LEVEL_7,  LOG_GROUP, a)
+
+/** @def LogRelMax8
+ * Level 8 release logging with a max number of log entries.
+ */
+#define LogRelMax8(a_cMax, a)       LogRelMaxIt(a_cMax, RTLOGGRPFLAGS_LEVEL_8,  LOG_GROUP, a)
+
+/** @def LogRelMax9
+ * Level 9 release logging with a max number of log entries.
+ */
+#define LogRelMax9(a_cMax, a)       LogRelMaxIt(a_cMax, RTLOGGRPFLAGS_LEVEL_9,  LOG_GROUP, a)
+
+/** @def LogRelMax10
+ * Level 10 release logging with a max number of log entries.
+ */
+#define LogRelMax10(a_cMax, a)      LogRelMaxIt(a_cMax, RTLOGGRPFLAGS_LEVEL_10, LOG_GROUP, a)
+
+/** @def LogRelMax11
+ * Level 11 release logging with a max number of log entries.
+ */
+#define LogRelMax11(a_cMax, a)      LogRelMaxIt(a_cMax, RTLOGGRPFLAGS_LEVEL_11, LOG_GROUP, a)
+
+/** @def LogRelMax12
+ * Level 12 release logging with a max number of log entries.
+ */
+#define LogRelMax12(a_cMax, a)      LogRelMaxIt(a_cMax, RTLOGGRPFLAGS_LEVEL_12, LOG_GROUP, a)
+
+/** @def LogRelFlow
+ * Logging of execution flow with a max number of log entries.
+ */
+#define LogRelMaxFlow(a_cMax, a)    LogRelMaxIt(a_cMax, RTLOGGRPFLAGS_FLOW,     LOG_GROUP, a)
+/** @} */
+
+
+/** @name Release logging macros prefixing the current function name.
+ * @{ */
+
+/** @def LogRelFunc
+ * Release logging.  Prepends the given log message with the function name
+ * followed by a semicolon and space.
+ */
+#ifdef LOG_USE_C99
+# define LogRelFunc(a) \
+    _LogRelItLikely(RTLOGGRPFLAGS_LEVEL_1, LOG_GROUP, LOG_FN_FMT ": %M", RT_GCC_EXTENSION __PRETTY_FUNCTION__, _LogRemoveParentheseis a )
+#else
+# define LogRelFunc(a)      do { LogRel((LOG_FN_FMT ": ", RT_GCC_EXTENSION __PRETTY_FUNCTION__)); LogRel(a); } while (0)
+#endif
+
+/** @def LogRelFlowFunc
+ * Release logging.  Macro to log the execution flow inside C/C++ functions.
+ *
+ * Prepends the given log message with the function name followed by
+ * a semicolon and space.
+ *
+ * @param   a   Log message in format <tt>("string\n" [, args])</tt>.
+ */
+#ifdef LOG_USE_C99
+# define LogRelFlowFunc(a)  _LogRelIt(RTLOGGRPFLAGS_FLOW, LOG_GROUP, LOG_FN_FMT ": %M", __PRETTY_FUNCTION__, _LogRemoveParentheseis a )
+#else
+# define LogRelFlowFunc(a)  do { LogRelFlow((LOG_FN_FMT ": ", __PRETTY_FUNCTION__)); LogRelFlow(a); } while (0)
+#endif
+
+/** @def LogRelMaxFunc
+ * Release logging.  Prepends the given log message with the function name
+ * followed by a semicolon and space.
+ */
+#ifdef LOG_USE_C99
+# define LogRelMaxFunc(a_cMax, a) \
+    _LogRelMaxIt(a_cMax, RTLOGGRPFLAGS_LEVEL_1, LOG_GROUP, LOG_FN_FMT ": %M", __PRETTY_FUNCTION__, _LogRemoveParentheseis a )
+#else
+# define LogRelMaxFunc(a_cMax, a) \
+    do { LogRelMax(a_cMax, (LOG_FN_FMT ": ", __PRETTY_FUNCTION__)); LogRelMax(a_cMax, a); } while (0)
+#endif
+
+/** @def LogRelMaxFlowFunc
+ * Release logging.  Macro to log the execution flow inside C/C++ functions.
+ *
+ * Prepends the given log message with the function name followed by
+ * a semicolon and space.
+ *
+ * @param   a_cMax  Max number of times this should hit the log.
+ * @param   a       Log message in format <tt>("string\n" [, args])</tt>.
+ */
+#ifdef LOG_USE_C99
+# define LogRelMaxFlowFunc(a_cMax, a) \
+    _LogRelMaxIt(a_cMax, RTLOGGRPFLAGS_FLOW, LOG_GROUP, LOG_FN_FMT ": %M", __PRETTY_FUNCTION__, _LogRemoveParentheseis a )
+#else
+# define LogRelMaxFlowFunc(a_cMax, a) \
+    do { LogRelMaxFlow(a_cMax, (LOG_FN_FMT ": ", __PRETTY_FUNCTION__)); LogRelFlow(a_cMax, a); } while (0)
+#endif
+
+/** @} */
+
+
+/** @name Release Logging macros prefixing the this pointer value and method name.
+ * @{ */
+
+/** @def LogRelThisFunc
+ * The same as LogRelFunc but for class functions (methods): the resulting log
+ * line is additionally prepended with a hex value of |this| pointer.
+ */
+#ifdef LOG_USE_C99
+# define LogRelThisFunc(a) \
+    _LogRelItLikely(RTLOGGRPFLAGS_LEVEL_1, LOG_GROUP, "{%p} " LOG_FN_FMT ": %M", this, __PRETTY_FUNCTION__, _LogRemoveParentheseis a )
+#else
+# define LogRelThisFunc(a) \
+    do { LogRel(("{%p} " LOG_FN_FMT ": ", this, __PRETTY_FUNCTION__)); LogRel(a); } while (0)
+#endif
+
+/** @def LogRelMaxThisFunc
+ * The same as LogRelFunc but for class functions (methods): the resulting log
+ * line is additionally prepended with a hex value of |this| pointer.
+ * @param   a_cMax  Max number of times this should hit the log.
+ * @param   a       Log message in format <tt>("string\n" [, args])</tt>.
+ */
+#ifdef LOG_USE_C99
+# define LogRelMaxThisFunc(a_cMax, a) \
+    _LogRelMaxIt(a_cMax, RTLOGGRPFLAGS_LEVEL_1, LOG_GROUP, "{%p} " LOG_FN_FMT ": %M", this, __PRETTY_FUNCTION__, _LogRemoveParentheseis a )
+#else
+# define LogRelMaxThisFunc(a_cMax, a) \
+    do { LogRelMax(a_cMax, ("{%p} " LOG_FN_FMT ": ", this, __PRETTY_FUNCTION__)); LogRelMax(a_cMax, a); } while (0)
+#endif
+
+/** @} */
+
+
+#ifndef IN_RC
+/**
+ * Sets the default release logger instance.
+ *
+ * @returns The old default instance.
+ * @param   pLogger     The new default release logger instance.
+ */
+RTDECL(PRTLOGGER) RTLogRelSetDefaultInstance(PRTLOGGER pLogger);
+#endif /* !IN_RC */
+
+/**
+ * Gets the default release logger instance.
+ *
+ * @returns Pointer to default release logger instance if availble, otherwise NULL.
+ */
+RTDECL(PRTLOGGER) RTLogRelGetDefaultInstance(void);
+
+/**
+ * Gets the default release logger instance.
+ *
+ * @returns Pointer to default release logger instance if availble, otherwise NULL.
+ * @param   fFlagsAndGroup  The flags in the lower 16 bits, the group number in
+ *                          the high 16 bits.
+ */
+RTDECL(PRTLOGGER) RTLogRelGetDefaultInstanceEx(uint32_t fFlagsAndGroup);
+
+/**
+ * Write to a logger instance, defaulting to the release one.
+ *
+ * This function will check whether the instance, group and flags makes up a
+ * logging kind which is currently enabled before writing anything to the log.
+ *
+ * @param   pLogger     Pointer to logger instance.
+ * @param   fFlags      The logging flags.
+ * @param   iGroup      The group.
+ *                      The value ~0U is reserved for compatibility with RTLogLogger[V] and is
+ *                      only for internal usage!
+ * @param   pszFormat   Format string.
+ * @param   ...         Format arguments.
+ * @remark  This is a worker function for LogRelIt.
+ */
+RTDECL(void) RTLogRelLogger(PRTLOGGER pLogger, unsigned fFlags, unsigned iGroup,
+                            const char *pszFormat, ...) RT_IPRT_FORMAT_ATTR(4, 5);
+
+/**
+ * Write to a logger instance, defaulting to the release one.
+ *
+ * This function will check whether the instance, group and flags makes up a
+ * logging kind which is currently enabled before writing anything to the log.
+ *
+ * @param   pLogger     Pointer to logger instance. If NULL the default release instance is attempted.
+ * @param   fFlags      The logging flags.
+ * @param   iGroup      The group.
+ *                      The value ~0U is reserved for compatibility with RTLogLogger[V] and is
+ *                      only for internal usage!
+ * @param   pszFormat   Format string.
+ * @param   args        Format arguments.
+ */
+RTDECL(void) RTLogRelLoggerV(PRTLOGGER pLogger, unsigned fFlags, unsigned iGroup,
+                             const char *pszFormat, va_list args) RT_IPRT_FORMAT_ATTR(4, 0);
+
+/**
+ * printf like function for writing to the default release log.
+ *
+ * @param   pszFormat   Printf like format string.
+ * @param   ...         Optional arguments as specified in pszFormat.
+ *
+ * @remark The API doesn't support formatting of floating point numbers at the moment.
+ */
+RTDECL(void) RTLogRelPrintf(const char *pszFormat, ...)  RT_IPRT_FORMAT_ATTR(1, 2);
+
+/**
+ * vprintf like function for writing to the default release log.
+ *
+ * @param   pszFormat   Printf like format string.
+ * @param   args        Optional arguments as specified in pszFormat.
+ *
+ * @remark The API doesn't support formatting of floating point numbers at the moment.
+ */
+RTDECL(void) RTLogRelPrintfV(const char *pszFormat, va_list args) RT_IPRT_FORMAT_ATTR(1, 0);
+
+/**
+ * Changes the buffering setting of the default release logger.
+ *
+ * This can be used for optimizing longish logging sequences.
+ *
+ * @returns The old state.
+ * @param   fBuffered       The new state.
+ */
+RTDECL(bool) RTLogRelSetBuffering(bool fBuffered);
+
+/** @} */
+
+
+
+/** @name COM port logging
+ * {
+ */
+
+#ifdef DOXYGEN_RUNNING
+# define LOG_TO_COM
+# define LOG_NO_COM
+#endif
+
+/** @def LOG_TO_COM
+ * Redirects the normal logging macros to the serial versions.
+ */
+
+/** @def LOG_NO_COM
+ * Disables all LogCom* macros.
+ */
+
+/** @def LogCom
+ * Generic logging to serial port.
+ */
+#if defined(LOG_ENABLED) && !defined(LOG_NO_COM)
+# define LogCom(a) RTLogComPrintf a
+#else
+# define LogCom(a) do { } while (0)
+#endif
+
+/** @def LogComFlow
+ * Logging to serial port of execution flow.
+ */
+#if defined(LOG_ENABLED) && defined(LOG_ENABLE_FLOW) && !defined(LOG_NO_COM)
+# define LogComFlow(a) RTLogComPrintf a
+#else
+# define LogComFlow(a) do { } while (0)
+#endif
+
+#ifdef LOG_TO_COM
+# undef Log
+# define Log(a)             LogCom(a)
+# undef LogFlow
+# define LogFlow(a)         LogComFlow(a)
+#endif
+
+/** @} */
+
+
+/** @name Backdoor Logging
+ * @{
+ */
+
+#ifdef DOXYGEN_RUNNING
+# define LOG_TO_BACKDOOR
+# define LOG_NO_BACKDOOR
+#endif
+
+/** @def LOG_TO_BACKDOOR
+ * Redirects the normal logging macros to the backdoor versions.
+ */
+
+/** @def LOG_NO_BACKDOOR
+ * Disables all LogBackdoor* macros.
+ */
+
+/** @def LogBackdoor
+ * Generic logging to the VBox backdoor via port I/O.
+ */
+#if defined(LOG_ENABLED) && !defined(LOG_NO_BACKDOOR)
+# define LogBackdoor(a)     RTLogBackdoorPrintf a
+#else
+# define LogBackdoor(a)     do { } while (0)
+#endif
+
+/** @def LogBackdoorFlow
+ * Logging of execution flow messages to the backdoor I/O port.
+ */
+#if defined(LOG_ENABLED) && !defined(LOG_NO_BACKDOOR)
+# define LogBackdoorFlow(a) RTLogBackdoorPrintf a
+#else
+# define LogBackdoorFlow(a) do { } while (0)
+#endif
+
+/** @def LogRelBackdoor
+ * Release logging to the VBox backdoor via port I/O.
+ */
+#if !defined(LOG_NO_BACKDOOR)
+# define LogRelBackdoor(a)  RTLogBackdoorPrintf a
+#else
+# define LogRelBackdoor(a)  do { } while (0)
+#endif
+
+#ifdef LOG_TO_BACKDOOR
+# undef Log
+# define Log(a)         LogBackdoor(a)
+# undef LogFlow
+# define LogFlow(a)     LogBackdoorFlow(a)
+# undef LogRel
+# define LogRel(a)      LogRelBackdoor(a)
+# if defined(LOG_USE_C99)
+#  undef _LogIt
+#  define _LogIt(a_fFlags, a_iGroup, ...)  LogBackdoor((__VA_ARGS__))
+# endif
+#endif
+
+/** @} */
+
+
+
+/**
+ * Gets the default logger instance, creating it if necessary.
+ *
+ * @returns Pointer to default logger instance if availble, otherwise NULL.
+ */
+RTDECL(PRTLOGGER)   RTLogDefaultInstance(void);
+
+/**
+ * Gets the logger instance if enabled, creating it if necessary.
+ *
+ * @returns Pointer to default logger instance, if group has the specified
+ *          flags enabled.  Otherwise NULL is returned.
+ * @param   fFlagsAndGroup  The flags in the lower 16 bits, the group number in
+ *                          the high 16 bits.
+ */
+RTDECL(PRTLOGGER)   RTLogDefaultInstanceEx(uint32_t fFlagsAndGroup);
+
+/**
+ * Gets the default logger instance.
+ *
+ * @returns Pointer to default logger instance if availble, otherwise NULL.
+ */
+RTDECL(PRTLOGGER)   RTLogGetDefaultInstance(void);
+
+/**
+ * Gets the default logger instance if enabled.
+ *
+ * @returns Pointer to default logger instance, if group has the specified
+ *          flags enabled.  Otherwise NULL is returned.
+ * @param   fFlagsAndGroup  The flags in the lower 16 bits, the group number in
+ *                          the high 16 bits.
+ */
+RTDECL(PRTLOGGER)   RTLogGetDefaultInstanceEx(uint32_t fFlagsAndGroup);
+
+#ifndef IN_RC
+/**
+ * Sets the default logger instance.
+ *
+ * @returns The old default instance.
+ * @param   pLogger     The new default logger instance.
+ */
+RTDECL(PRTLOGGER)   RTLogSetDefaultInstance(PRTLOGGER pLogger);
+#endif /* !IN_RC */
+
+#ifdef IN_RING0
+/**
+ * Changes the default logger instance for the current thread.
+ *
+ * @returns IPRT status code.
+ * @param   pLogger     The logger instance. Pass NULL for deregistration.
+ * @param   uKey        Associated key for cleanup purposes. If pLogger is NULL,
+ *                      all instances with this key will be deregistered. So in
+ *                      order to only deregister the instance associated with the
+ *                      current thread use 0.
+ */
+RTDECL(int)         RTLogSetDefaultInstanceThread(PRTLOGGER pLogger, uintptr_t uKey);
+#endif /* IN_RING0 */
+
+
+#ifndef IN_RC
+/**
+ * Creates the default logger instance for a iprt users.
+ *
+ * Any user of the logging features will need to implement
+ * this or use the generic dummy.
+ *
+ * @returns Pointer to the logger instance.
+ */
+RTDECL(PRTLOGGER) RTLogDefaultInit(void);
+
+/**
+ * Create a logger instance.
+ *
+ * @returns iprt status code.
+ *
+ * @param   ppLogger            Where to store the logger instance.
+ * @param   fFlags              Logger instance flags, a combination of the
+ *                              RTLOGFLAGS_* values.
+ * @param   pszGroupSettings    The initial group settings.
+ * @param   pszEnvVarBase       Base name for the environment variables for
+ *                              this instance.
+ * @param   cGroups             Number of groups in the array.
+ * @param   papszGroups         Pointer to array of groups.  This must stick
+ *                              around for the life of the logger instance.
+ * @param   fDestFlags          The destination flags.  RTLOGDEST_FILE is ORed
+ *                              if pszFilenameFmt specified.
+ * @param   pszFilenameFmt      Log filename format string.  Standard
+ *                              RTStrFormat().
+ * @param   ...                 Format arguments.
+ */
+RTDECL(int) RTLogCreate(PRTLOGGER *ppLogger, uint32_t fFlags, const char *pszGroupSettings,
+                        const char *pszEnvVarBase, unsigned cGroups, const char * const * papszGroups,
+                        uint32_t fDestFlags, const char *pszFilenameFmt, ...) RT_IPRT_FORMAT_ATTR_MAYBE_NULL(8, 9);
+
+/**
+ * Create a logger instance.
+ *
+ * @returns iprt status code.
+ *
+ * @param   ppLogger            Where to store the logger instance.
+ * @param   fFlags              Logger instance flags, a combination of the
+ *                              RTLOGFLAGS_* values.
+ * @param   pszGroupSettings    The initial group settings.
+ * @param   pszEnvVarBase       Base name for the environment variables for
+ *                              this instance.
+ * @param   cGroups             Number of groups in the array.
+ * @param   papszGroups         Pointer to array of groups.  This must stick
+ *                              around for the life of the logger instance.
+ * @param   fDestFlags          The destination flags.  RTLOGDEST_FILE is ORed
+ *                              if pszFilenameFmt specified.
+ * @param   pfnPhase            Callback function for starting logging and for
+ *                              ending or starting a new file for log history
+ *                              rotation.  NULL is OK.
+ * @param   cHistory            Number of old log files to keep when performing
+ *                              log history rotation.  0 means no history.
+ * @param   cbHistoryFileMax    Maximum size of log file when performing
+ *                              history rotation. 0 means no size limit.
+ * @param   cSecsHistoryTimeSlot Maximum time interval per log file when
+ *                              performing history rotation, in seconds.
+ *                              0 means time limit.
+ * @param   pszErrorMsg         A buffer which is filled with an error message if something fails. May be NULL.
+ * @param   cchErrorMsg         The size of the error message buffer.
+ * @param   pszFilenameFmt      Log filename format string. Standard RTStrFormat().
+ * @param   ...                 Format arguments.
+ */
+RTDECL(int) RTLogCreateEx(PRTLOGGER *ppLogger, uint32_t fFlags, const char *pszGroupSettings,
+                          const char *pszEnvVarBase, unsigned cGroups, const char * const * papszGroups,
+                          uint32_t fDestFlags, PFNRTLOGPHASE pfnPhase, uint32_t cHistory,
+                          uint64_t cbHistoryFileMax, uint32_t cSecsHistoryTimeSlot, char *pszErrorMsg, size_t cchErrorMsg,
+                          const char *pszFilenameFmt, ...) RT_IPRT_FORMAT_ATTR_MAYBE_NULL(14, 15);
+
+/**
+ * Create a logger instance.
+ *
+ * @returns iprt status code.
+ *
+ * @param   ppLogger            Where to store the logger instance.
+ * @param   fFlags              Logger instance flags, a combination of the
+ *                              RTLOGFLAGS_* values.
+ * @param   pszGroupSettings    The initial group settings.
+ * @param   pszEnvVarBase       Base name for the environment variables for
+ *                              this instance.
+ * @param   cGroups             Number of groups in the array.
+ * @param   papszGroups         Pointer to array of groups.  This must stick
+ *                              around for the life of the logger instance.
+ * @param   fDestFlags          The destination flags.  RTLOGDEST_FILE is ORed
+ *                              if pszFilenameFmt specified.
+ * @param   pfnPhase            Callback function for starting logging and for
+ *                              ending or starting a new file for log history
+ *                              rotation.
+ * @param   cHistory            Number of old log files to keep when performing
+ *                              log history rotation.  0 means no history.
+ * @param   cbHistoryFileMax    Maximum size of log file when performing
+ *                              history rotation.  0 means no size limit.
+ * @param   cSecsHistoryTimeSlot  Maximum time interval per log file when
+ *                              performing history rotation, in seconds.
+ *                              0 means no time limit.
+ * @param   pszErrorMsg         A buffer which is filled with an error message
+ *                              if something fails.  May be NULL.
+ * @param   cchErrorMsg         The size of the error message buffer.
+ * @param   pszFilenameFmt      Log filename format string.  Standard
+ *                              RTStrFormat().
+ * @param   args                Format arguments.
+ */
+RTDECL(int) RTLogCreateExV(PRTLOGGER *ppLogger, uint32_t fFlags, const char *pszGroupSettings,
+                           const char *pszEnvVarBase, unsigned cGroups, const char * const * papszGroups,
+                           uint32_t fDestFlags, PFNRTLOGPHASE pfnPhase, uint32_t cHistory,
+                           uint64_t cbHistoryFileMax, uint32_t cSecsHistoryTimeSlot, char *pszErrorMsg, size_t cchErrorMsg,
+                           const char *pszFilenameFmt, va_list args) RT_IPRT_FORMAT_ATTR_MAYBE_NULL(14, 0);
+
+/**
+ * Create a logger instance for singled threaded ring-0 usage.
+ *
+ * @returns iprt status code.
+ *
+ * @param   pLogger             Where to create the logger instance.
+ * @param   cbLogger            The amount of memory available for the logger instance.
+ * @param   pLoggerR0Ptr        The ring-0 address corresponding to @a pLogger.
+ * @param   pfnLoggerR0Ptr      Pointer to logger wrapper function.
+ * @param   pfnFlushR0Ptr       Pointer to flush function.
+ * @param   fFlags              Logger instance flags, a combination of the RTLOGFLAGS_* values.
+ * @param   fDestFlags          The destination flags.
+ */
+RTDECL(int) RTLogCreateForR0(PRTLOGGER pLogger, size_t cbLogger,
+                             RTR0PTR pLoggerR0Ptr, RTR0PTR pfnLoggerR0Ptr, RTR0PTR pfnFlushR0Ptr,
+                             uint32_t fFlags, uint32_t fDestFlags);
+
+/**
+ * Calculates the minimum size of a ring-0 logger instance.
+ *
+ * @returns The minimum size.
+ * @param   cGroups             The number of groups.
+ * @param   fFlags              Relevant flags.
+ */
+RTDECL(size_t) RTLogCalcSizeForR0(uint32_t cGroups, uint32_t fFlags);
+
+/**
+ * Destroys a logger instance.
+ *
+ * The instance is flushed and all output destinations closed (where applicable).
+ *
+ * @returns iprt status code.
+ * @param   pLogger             The logger instance which close destroyed. NULL is fine.
+ */
+RTDECL(int) RTLogDestroy(PRTLOGGER pLogger);
+
+/**
+ * Create a logger instance clone for RC usage.
+ *
+ * @returns iprt status code.
+ *
+ * @param   pLogger             The logger instance to be cloned.
+ * @param   pLoggerRC           Where to create the RC logger instance.
+ * @param   cbLoggerRC          Amount of memory allocated to for the RC logger
+ *                              instance clone.
+ * @param   pfnLoggerRCPtr      Pointer to logger wrapper function for this
+ *                              instance (RC Ptr).
+ * @param   pfnFlushRCPtr       Pointer to flush function (RC Ptr).
+ * @param   fFlags              Logger instance flags, a combination of the RTLOGFLAGS_* values.
+ */
+RTDECL(int) RTLogCloneRC(PRTLOGGER pLogger, PRTLOGGERRC pLoggerRC, size_t cbLoggerRC,
+                         RTRCPTR pfnLoggerRCPtr, RTRCPTR pfnFlushRCPtr, uint32_t fFlags);
+
+/**
+ * Flushes a RC logger instance to a R3 logger.
+ *
+ * @returns iprt status code.
+ * @param   pLogger     The R3 logger instance to flush pLoggerRC to. If NULL
+ *                      the default logger is used.
+ * @param   pLoggerRC   The RC logger instance to flush.
+ */
+RTDECL(void) RTLogFlushRC(PRTLOGGER pLogger, PRTLOGGERRC pLoggerRC);
+
+/**
+ * Flushes the buffer in one logger instance onto another logger.
+ *
+ * @returns iprt status code.
+ *
+ * @param   pSrcLogger   The logger instance to flush.
+ * @param   pDstLogger   The logger instance to flush onto.
+ *                       If NULL the default logger will be used.
+ */
+RTDECL(void) RTLogFlushToLogger(PRTLOGGER pSrcLogger, PRTLOGGER pDstLogger);
+
+/**
+ * Flushes a R0 logger instance to a R3 logger.
+ *
+ * @returns iprt status code.
+ * @param   pLogger      The R3 logger instance to flush pLoggerR0 to. If NULL
+ *                       the default logger is used.
+ * @param   pLoggerR0    The R0 logger instance to flush.
+ */
+RTDECL(void) RTLogFlushR0(PRTLOGGER pLogger, PRTLOGGER pLoggerR0);
+
+/**
+ * Sets the custom prefix callback.
+ *
+ * @returns IPRT status code.
+ * @param   pLogger     The logger instance.
+ * @param   pfnCallback The callback.
+ * @param   pvUser      The user argument for the callback.
+ *  */
+RTDECL(int) RTLogSetCustomPrefixCallback(PRTLOGGER pLogger, PFNRTLOGPREFIX pfnCallback, void *pvUser);
+
+/**
+ * Same as RTLogSetCustomPrefixCallback for loggers created by
+ * RTLogCreateForR0.
+ *
+ * @returns IPRT status code.
+ * @param   pLogger             The logger instance.
+ * @param   pLoggerR0Ptr        The ring-0 address corresponding to @a pLogger.
+ * @param   pfnCallbackR0Ptr    The callback.
+ * @param   pvUserR0Ptr         The user argument for the callback.
+ *  */
+RTDECL(int) RTLogSetCustomPrefixCallbackForR0(PRTLOGGER pLogger, RTR0PTR pLoggerR0Ptr,
+                                              RTR0PTR pfnCallbackR0Ptr, RTR0PTR pvUserR0Ptr);
+
+/**
+ * Copies the group settings and flags from logger instance to another.
+ *
+ * @returns IPRT status code.
+ * @param   pDstLogger      The destination logger instance.
+ * @param   pDstLoggerR0Ptr The ring-0 address corresponding to @a pDstLogger.
+ * @param   pSrcLogger      The source logger instance. If NULL the default one is used.
+ * @param   fFlagsOr        OR mask for the flags.
+ * @param   fFlagsAnd       AND mask for the flags.
+ */
+RTDECL(int) RTLogCopyGroupsAndFlagsForR0(PRTLOGGER pDstLogger, RTR0PTR pDstLoggerR0Ptr,
+                                         PCRTLOGGER pSrcLogger, uint32_t fFlagsOr, uint32_t fFlagsAnd);
+
+/**
+ * Get the current log group settings as a string.
+ *
+ * @returns VINF_SUCCESS or VERR_BUFFER_OVERFLOW.
+ * @param   pLogger             Logger instance (NULL for default logger).
+ * @param   pszBuf              The output buffer.
+ * @param   cchBuf              The size of the output buffer. Must be greater
+ *                              than zero.
+ */
+RTDECL(int) RTLogGetGroupSettings(PRTLOGGER pLogger, char *pszBuf, size_t cchBuf);
+
+/**
+ * Updates the group settings for the logger instance using the specified
+ * specification string.
+ *
+ * @returns iprt status code.
+ *          Failures can safely be ignored.
+ * @param   pLogger     Logger instance (NULL for default logger).
+ * @param   pszValue    Value to parse.
+ */
+RTDECL(int) RTLogGroupSettings(PRTLOGGER pLogger, const char *pszValue);
+#endif /* !IN_RC */
+
+/**
+ * Updates the flags for the logger instance using the specified
+ * specification string.
+ *
+ * @returns iprt status code.
+ *          Failures can safely be ignored.
+ * @param   pLogger     Logger instance (NULL for default logger).
+ * @param   pszValue    Value to parse.
+ */
+RTDECL(int) RTLogFlags(PRTLOGGER pLogger, const char *pszValue);
+
+/**
+ * Changes the buffering setting of the specified logger.
+ *
+ * This can be used for optimizing longish logging sequences.
+ *
+ * @returns The old state.
+ * @param   pLogger         The logger instance (NULL is an alias for the
+ *                          default logger).
+ * @param   fBuffered       The new state.
+ */
+RTDECL(bool) RTLogSetBuffering(PRTLOGGER pLogger, bool fBuffered);
+
+/**
+ * Sets the max number of entries per group.
+ *
+ * @returns Old restriction.
+ *
+ * @param   pLogger             The logger instance (NULL is an alias for the
+ *                              default logger).
+ * @param   cMaxEntriesPerGroup The max number of entries per group.
+ *
+ * @remarks Lowering the limit of an active logger may quietly mute groups.
+ *          Raising it may reactive already muted groups.
+ */
+RTDECL(uint32_t) RTLogSetGroupLimit(PRTLOGGER pLogger, uint32_t cMaxEntriesPerGroup);
+
+#ifndef IN_RC
+/**
+ * Get the current log flags as a string.
+ *
+ * @returns VINF_SUCCESS or VERR_BUFFER_OVERFLOW.
+ * @param   pLogger             Logger instance (NULL for default logger).
+ * @param   pszBuf              The output buffer.
+ * @param   cchBuf              The size of the output buffer. Must be greater
+ *                              than zero.
+ */
+RTDECL(int) RTLogGetFlags(PRTLOGGER pLogger, char *pszBuf, size_t cchBuf);
+
+/**
+ * Updates the logger destination using the specified string.
+ *
+ * @returns VINF_SUCCESS or VERR_BUFFER_OVERFLOW.
+ * @param   pLogger             Logger instance (NULL for default logger).
+ * @param   pszValue            The value to parse.
+ */
+RTDECL(int) RTLogDestinations(PRTLOGGER pLogger, char const *pszValue);
+
+/**
+ * Get the current log destinations as a string.
+ *
+ * @returns VINF_SUCCESS or VERR_BUFFER_OVERFLOW.
+ * @param   pLogger             Logger instance (NULL for default logger).
+ * @param   pszBuf              The output buffer.
+ * @param   cchBuf              The size of the output buffer. Must be greater
+ *                              than 0.
+ */
+RTDECL(int) RTLogGetDestinations(PRTLOGGER pLogger, char *pszBuf, size_t cchBuf);
+#endif /* !IN_RC */
+
+/**
+ * Flushes the specified logger.
+ *
+ * @param   pLogger     The logger instance to flush.
+ *                      If NULL the default instance is used. The default instance
+ *                      will not be initialized by this call.
+ */
+RTDECL(void) RTLogFlush(PRTLOGGER pLogger);
+
+/**
+ * Write to a logger instance.
+ *
+ * @param   pLogger     Pointer to logger instance.
+ * @param   pvCallerRet Ignored.
+ * @param   pszFormat   Format string.
+ * @param   ...         Format arguments.
+ */
+RTDECL(void) RTLogLogger(PRTLOGGER pLogger, void *pvCallerRet, const char *pszFormat, ...) RT_IPRT_FORMAT_ATTR(3, 4);
+
+/**
+ * Write to a logger instance.
+ *
+ * @param   pLogger     Pointer to logger instance.
+ * @param   pszFormat   Format string.
+ * @param   args        Format arguments.
+ */
+RTDECL(void) RTLogLoggerV(PRTLOGGER pLogger, const char *pszFormat, va_list args) RT_IPRT_FORMAT_ATTR(3, 0);
+
+/**
+ * Write to a logger instance.
+ *
+ * This function will check whether the instance, group and flags makes up a
+ * logging kind which is currently enabled before writing anything to the log.
+ *
+ * @param   pLogger     Pointer to logger instance. If NULL the default logger instance will be attempted.
+ * @param   fFlags      The logging flags.
+ * @param   iGroup      The group.
+ *                      The value ~0U is reserved for compatibility with RTLogLogger[V] and is
+ *                      only for internal usage!
+ * @param   pszFormat   Format string.
+ * @param   ...         Format arguments.
+ * @remark  This is a worker function of LogIt.
+ */
+RTDECL(void) RTLogLoggerEx(PRTLOGGER pLogger, unsigned fFlags, unsigned iGroup,
+                           const char *pszFormat, ...) RT_IPRT_FORMAT_ATTR(4, 5);
+
+/**
+ * Write to a logger instance.
+ *
+ * This function will check whether the instance, group and flags makes up a
+ * logging kind which is currently enabled before writing anything to the log.
+ *
+ * @param   pLogger     Pointer to logger instance. If NULL the default logger instance will be attempted.
+ * @param   fFlags      The logging flags.
+ * @param   iGroup      The group.
+ *                      The value ~0U is reserved for compatibility with RTLogLogger[V] and is
+ *                      only for internal usage!
+ * @param   pszFormat   Format string.
+ * @param   args        Format arguments.
+ */
+RTDECL(void) RTLogLoggerExV(PRTLOGGER pLogger, unsigned fFlags, unsigned iGroup,
+                            const char *pszFormat, va_list args) RT_IPRT_FORMAT_ATTR(4, 0);
+
+/**
+ * printf like function for writing to the default log.
+ *
+ * @param   pszFormat   Printf like format string.
+ * @param   ...         Optional arguments as specified in pszFormat.
+ *
+ * @remark The API doesn't support formatting of floating point numbers at the moment.
+ */
+RTDECL(void) RTLogPrintf(const char *pszFormat, ...) RT_IPRT_FORMAT_ATTR(1, 2);
+
+/**
+ * vprintf like function for writing to the default log.
+ *
+ * @param   pszFormat   Printf like format string.
+ * @param   va          Optional arguments as specified in pszFormat.
+ *
+ * @remark The API doesn't support formatting of floating point numbers at the moment.
+ */
+RTDECL(void) RTLogPrintfV(const char *pszFormat, va_list va)  RT_IPRT_FORMAT_ATTR(1, 0);
+
+/**
+ * Dumper vprintf-like function outputting to a logger.
+ *
+ * @param   pvUser          Pointer to the logger instance to use, NULL for
+ *                          default instance.
+ * @param   pszFormat       Format string.
+ * @param   va              Format arguments.
+ */
+RTDECL(void) RTLogDumpPrintfV(void *pvUser, const char *pszFormat, va_list va) RT_IPRT_FORMAT_ATTR(2, 0);
+
+
+#ifndef DECLARED_FNRTSTROUTPUT          /* duplicated in iprt/string.h */
+#define DECLARED_FNRTSTROUTPUT
+/**
+ * Output callback.
+ *
+ * @returns number of bytes written.
+ * @param   pvArg       User argument.
+ * @param   pachChars   Pointer to an array of utf-8 characters.
+ * @param   cbChars     Number of bytes in the character array pointed to by pachChars.
+ */
+typedef DECLCALLBACK(size_t) FNRTSTROUTPUT(void *pvArg, const char *pachChars, size_t cbChars);
+/** Pointer to callback function. */
+typedef FNRTSTROUTPUT *PFNRTSTROUTPUT;
+#endif
+
+/**
+ * Partial vsprintf worker implementation.
+ *
+ * @returns number of bytes formatted.
+ * @param   pfnOutput   Output worker.
+ *                      Called in two ways. Normally with a string an it's length.
+ *                      For termination, it's called with NULL for string, 0 for length.
+ * @param   pvArg       Argument to output worker.
+ * @param   pszFormat   Format string.
+ * @param   args        Argument list.
+ */
+RTDECL(size_t) RTLogFormatV(PFNRTSTROUTPUT pfnOutput, void *pvArg, const char *pszFormat, va_list args) RT_IPRT_FORMAT_ATTR(3, 0);
+
+/**
+ * Write log buffer to COM port.
+ *
+ * @param   pach        Pointer to the buffer to write.
+ * @param   cb          Number of bytes to write.
+ */
+RTDECL(void) RTLogWriteCom(const char *pach, size_t cb);
+
+/**
+ * Prints a formatted string to the serial port used for logging.
+ *
+ * @returns Number of bytes written.
+ * @param   pszFormat   Format string.
+ * @param   ...         Optional arguments specified in the format string.
+ */
+RTDECL(size_t) RTLogComPrintf(const char *pszFormat, ...) RT_IPRT_FORMAT_ATTR(1, 2);
+
+/**
+ * Prints a formatted string to the serial port used for logging.
+ *
+ * @returns Number of bytes written.
+ * @param   pszFormat   Format string.
+ * @param   args        Optional arguments specified in the format string.
+ */
+RTDECL(size_t)  RTLogComPrintfV(const char *pszFormat, va_list args) RT_IPRT_FORMAT_ATTR(1, 0);
+
+
+#if 0 /* not implemented yet */
+
+/** Indicates that the semaphores shall be used to notify the other
+ * part about buffer changes. */
+#define LOGHOOKBUFFER_FLAGS_SEMAPHORED      1
+
+/**
+ * Log Hook Buffer.
+ * Use to communicate between the logger and a log consumer.
+ */
+typedef struct RTLOGHOOKBUFFER
+{
+    /** Write pointer. */
+    volatile void          *pvWrite;
+    /** Read pointer. */
+    volatile void          *pvRead;
+    /** Buffer start. */
+    void                   *pvStart;
+    /** Buffer end (exclusive). */
+    void                   *pvEnd;
+    /** Signaling semaphore used by the writer to wait on a full buffer.
+     * Only used when indicated in flags. */
+    void                   *pvSemWriter;
+    /** Signaling semaphore used by the read to wait on an empty buffer.
+     * Only used when indicated in flags. */
+    void                   *pvSemReader;
+    /** Buffer flags. Current reserved and set to zero. */
+    volatile unsigned       fFlags;
+} RTLOGHOOKBUFFER;
+/** Pointer to a log hook buffer. */
+typedef RTLOGHOOKBUFFER *PRTLOGHOOKBUFFER;
+
+
+/**
+ * Register a logging hook.
+ *
+ * This type of logging hooks are expecting different threads acting
+ * producer and consumer. They share a circular buffer which have two
+ * pointers one for each end. When the buffer is full there are two
+ * alternatives (indicated by a buffer flag), either wait for the
+ * consumer to get it's job done, or to write a generic message saying
+ * buffer overflow.
+ *
+ * Since the waiting would need a signal semaphore, we'll skip that for now.
+ *
+ * @returns iprt status code.
+ * @param   pBuffer     Pointer to a logger hook buffer.
+ */
+RTDECL(int)     RTLogRegisterHook(PRTLOGGER pLogger, PRTLOGHOOKBUFFER pBuffer);
+
+/**
+ * Deregister a logging hook registered with RTLogRegisterHook().
+ *
+ * @returns iprt status code.
+ * @param   pBuffer     Pointer to a logger hook buffer.
+ */
+RTDECL(int)     RTLogDeregisterHook(PRTLOGGER pLogger, PRTLOGHOOKBUFFER pBuffer);
+
+#endif /* not implemented yet */
+
+
+
+/**
+ * Write log buffer to a debugger (RTLOGDEST_DEBUGGER).
+ *
+ * @param   pach        What to write.
+ * @param   cb          How much to write.
+ * @remark  When linking statically, this function can be replaced by defining your own.
+ */
+RTDECL(void) RTLogWriteDebugger(const char *pach, size_t cb);
+
+/**
+ * Write log buffer to a user defined output stream (RTLOGDEST_USER).
+ *
+ * @param   pach        What to write.
+ * @param   cb          How much to write.
+ * @remark  When linking statically, this function can be replaced by defining your own.
+ */
+RTDECL(void) RTLogWriteUser(const char *pach, size_t cb);
+
+/**
+ * Write log buffer to stdout (RTLOGDEST_STDOUT).
+ *
+ * @param   pach        What to write.
+ * @param   cb          How much to write.
+ * @remark  When linking statically, this function can be replaced by defining your own.
+ */
+RTDECL(void) RTLogWriteStdOut(const char *pach, size_t cb);
+
+/**
+ * Write log buffer to stdout (RTLOGDEST_STDERR).
+ *
+ * @param   pach        What to write.
+ * @param   cb          How much to write.
+ * @remark  When linking statically, this function can be replaced by defining your own.
+ */
+RTDECL(void) RTLogWriteStdErr(const char *pach, size_t cb);
+
+#ifdef VBOX
+
+/**
+ * Prints a formatted string to the backdoor port.
+ *
+ * @returns Number of bytes written.
+ * @param   pszFormat   Format string.
+ * @param   ...         Optional arguments specified in the format string.
+ */
+RTDECL(size_t) RTLogBackdoorPrintf(const char *pszFormat, ...) RT_IPRT_FORMAT_ATTR(1, 2);
+
+/**
+ * Prints a formatted string to the backdoor port.
+ *
+ * @returns Number of bytes written.
+ * @param   pszFormat   Format string.
+ * @param   args        Optional arguments specified in the format string.
+ */
+RTDECL(size_t)  RTLogBackdoorPrintfV(const char *pszFormat, va_list args) RT_IPRT_FORMAT_ATTR(1, 0);
+
+#endif /* VBOX */
+
+RT_C_DECLS_END
+
+/** @} */
+
+#endif
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/include/iprt/mangling.h
@@ -0,0 +1,3047 @@
+/** @file
+ * IPRT - Symbol Mangling.
+ *
+ * This header is used to mangle public IPRT symbol to make it possible to have
+ * several IPRT version loaded into one symbol space at the same time.  To
+ * enable symbol mangling you create a header which the compiler includes for
+ * every compilation unit (check out the -include option of gcc).  Your header
+ * will define RT_MANGLER(name) and then include this header to set up the
+ * actual mappings.
+ */
+
+/*
+ * Copyright (C) 2011-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+#ifndef ___iprt_mangling_h
+#define ___iprt_mangling_h
+
+#ifndef RT_MANGLER
+# error "RT_MANGLER is not defined."
+#endif
+
+#ifndef DOXYGEN_RUNNING
+
+/** @def RT_WITH_MANGLING
+ * Indicates that we're mangling symbols.  */
+# define RT_WITH_MANGLING
+
+
+/*
+ * Stable functions (alphabetical order):
+ */
+# define ASMAtomicCmpXchgExU64                          RT_MANGLER(ASMAtomicCmpXchgExU64)   /* not-some-systems... */
+# define ASMAtomicCmpXchgExU64_EndProc                  RT_MANGLER(ASMAtomicCmpXchgExU64_EndProc)
+# define ASMAtomicCmpXchgU64                            RT_MANGLER(ASMAtomicCmpXchgU64)     /* not-some-systems... */
+# define ASMAtomicCmpXchgU64_EndProc                    RT_MANGLER(ASMAtomicCmpXchgU64_EndProc)
+# define ASMAtomicReadU64                               RT_MANGLER(ASMAtomicReadU64)        /* not-some-systems... */
+# define ASMAtomicReadU64_EndProc                       RT_MANGLER(ASMAtomicReadU64_EndProc)
+# define ASMAtomicUoAndU32                              RT_MANGLER(ASMAtomicUoAndU32)       /* not-some-systems... */
+# define ASMAtomicUoAndU32_EndProc                      RT_MANGLER(ASMAtomicUoAndU32_EndProc)
+# define ASMAtomicUoAndU64                              RT_MANGLER(ASMAtomicUoAndU64)       /* not-some-systems... */
+# define ASMAtomicUoAndU64_EndProc                      RT_MANGLER(ASMAtomicUoAndU64_EndProc)
+# define ASMAtomicUoDecU32                              RT_MANGLER(ASMAtomicUoDecU32)       /* not-some-systems... */
+# define ASMAtomicUoDecU32_EndProc                      RT_MANGLER(ASMAtomicUoDecU32_EndProc)
+# define ASMAtomicUoIncU32                              RT_MANGLER(ASMAtomicUoIncU32)       /* not-some-systems... */
+# define ASMAtomicUoIncU32_EndProc                      RT_MANGLER(ASMAtomicUoIncU32_EndProc)
+# define ASMAtomicUoOrU32                               RT_MANGLER(ASMAtomicUoOrU32)        /* not-some-systems... */
+# define ASMAtomicUoOrU32_EndProc                       RT_MANGLER(ASMAtomicUoOrU32_EndProc)
+# define ASMAtomicUoOrU64                               RT_MANGLER(ASMAtomicUoOrU64)        /* not-some-systems... */
+# define ASMAtomicUoOrU64_EndProc                       RT_MANGLER(ASMAtomicUoOrU64_EndProc)
+# define ASMAtomicUoReadU64                             RT_MANGLER(ASMAtomicUoReadU64)      /* not-some-systems... */
+# define ASMAtomicUoReadU64_EndProc                     RT_MANGLER(ASMAtomicUoReadU64_EndProc)
+# define ASMAtomicXchgU64                               RT_MANGLER(ASMAtomicXchgU64)        /* not-some-systems... */
+# define ASMAtomicXchgU64_EndProc                       RT_MANGLER(ASMAtomicXchgU64_EndProc)
+# define ASMCpuIdExSlow                                 RT_MANGLER(ASMCpuIdExSlow)
+# define ASMCpuIdExSlow_EndProc                         RT_MANGLER(ASMCpuIdExSlow_EndProc)
+# define ASMGetXcr0                                     RT_MANGLER(ASMGetXcr0)
+# define ASMGetXcr0_EndProc                             RT_MANGLER(ASMGetXcr0_EndProc)
+# define ASMRdMsrEx                                     RT_MANGLER(ASMRdMsrEx)
+# define ASMRdMsrEx_EndProc                             RT_MANGLER(ASMRdMsrEx_EndProc)
+# define ASMSetXcr0                                     RT_MANGLER(ASMSetXcr0)
+# define ASMSetXcr0_EndProc                             RT_MANGLER(ASMSetXcr0_EndProc)
+# define ASMWrMsrEx                                     RT_MANGLER(ASMWrMsrEx)
+# define ASMWrMsrEx_EndProc                             RT_MANGLER(ASMWrMsrEx_EndProc)
+# define ASMXRstor                                      RT_MANGLER(ASMXRstor)
+# define ASMXRstor_EndProc                              RT_MANGLER(ASMXRstor_EndProc)
+# define ASMXSave                                       RT_MANGLER(ASMXSave)
+# define ASMXSave_EndProc                               RT_MANGLER(ASMXSave_EndProc)
+# define RTAssertAreQuiet                               RT_MANGLER(RTAssertAreQuiet)
+# define RTAssertMayPanic                               RT_MANGLER(RTAssertMayPanic)
+# define RTAssertMsg1                                   RT_MANGLER(RTAssertMsg1)
+# define RTAssertMsg1Weak                               RT_MANGLER(RTAssertMsg1Weak)
+# define RTAssertMsg2                                   RT_MANGLER(RTAssertMsg2)
+# define RTAssertMsg2Add                                RT_MANGLER(RTAssertMsg2Add)
+# define RTAssertMsg2AddV                               RT_MANGLER(RTAssertMsg2AddV)
+# define RTAssertMsg2AddWeak                            RT_MANGLER(RTAssertMsg2AddWeak)
+# define RTAssertMsg2AddWeakV                           RT_MANGLER(RTAssertMsg2AddWeakV)
+# define RTAssertMsg2V                                  RT_MANGLER(RTAssertMsg2V)
+# define RTAssertMsg2Weak                               RT_MANGLER(RTAssertMsg2Weak)
+# define RTAssertMsg2WeakV                              RT_MANGLER(RTAssertMsg2WeakV)
+# define RTAssertSetMayPanic                            RT_MANGLER(RTAssertSetMayPanic)
+# define RTAssertSetQuiet                               RT_MANGLER(RTAssertSetQuiet)
+# define RTAssertShouldPanic                            RT_MANGLER(RTAssertShouldPanic)
+# define RTAvlGCPhysDestroy                             RT_MANGLER(RTAvlGCPhysDestroy)
+# define RTAvlGCPhysDoWithAll                           RT_MANGLER(RTAvlGCPhysDoWithAll)
+# define RTAvlGCPhysGet                                 RT_MANGLER(RTAvlGCPhysGet)
+# define RTAvlGCPhysGetBestFit                          RT_MANGLER(RTAvlGCPhysGetBestFit)
+# define RTAvlGCPhysInsert                              RT_MANGLER(RTAvlGCPhysInsert)
+# define RTAvlGCPhysRemove                              RT_MANGLER(RTAvlGCPhysRemove)
+# define RTAvlGCPhysRemoveBestFit                       RT_MANGLER(RTAvlGCPhysRemoveBestFit)
+# define RTAvlGCPtrDestroy                              RT_MANGLER(RTAvlGCPtrDestroy)
+# define RTAvlGCPtrDoWithAll                            RT_MANGLER(RTAvlGCPtrDoWithAll)
+# define RTAvlGCPtrGet                                  RT_MANGLER(RTAvlGCPtrGet)
+# define RTAvlGCPtrGetBestFit                           RT_MANGLER(RTAvlGCPtrGetBestFit)
+# define RTAvlGCPtrInsert                               RT_MANGLER(RTAvlGCPtrInsert)
+# define RTAvlGCPtrRemove                               RT_MANGLER(RTAvlGCPtrRemove)
+# define RTAvlGCPtrRemoveBestFit                        RT_MANGLER(RTAvlGCPtrRemoveBestFit)
+# define RTAvlHCPhysDestroy                             RT_MANGLER(RTAvlHCPhysDestroy)
+# define RTAvlHCPhysDoWithAll                           RT_MANGLER(RTAvlHCPhysDoWithAll)
+# define RTAvlHCPhysGet                                 RT_MANGLER(RTAvlHCPhysGet)
+# define RTAvlHCPhysGetBestFit                          RT_MANGLER(RTAvlHCPhysGetBestFit)
+# define RTAvlHCPhysInsert                              RT_MANGLER(RTAvlHCPhysInsert)
+# define RTAvlHCPhysRemove                              RT_MANGLER(RTAvlHCPhysRemove)
+# define RTAvlHCPhysRemoveBestFit                       RT_MANGLER(RTAvlHCPhysRemoveBestFit)
+# define RTAvllU32Destroy                               RT_MANGLER(RTAvllU32Destroy)
+# define RTAvllU32DoWithAll                             RT_MANGLER(RTAvllU32DoWithAll)
+# define RTAvllU32Get                                   RT_MANGLER(RTAvllU32Get)
+# define RTAvllU32GetBestFit                            RT_MANGLER(RTAvllU32GetBestFit)
+# define RTAvllU32Insert                                RT_MANGLER(RTAvllU32Insert)
+# define RTAvllU32Remove                                RT_MANGLER(RTAvllU32Remove)
+# define RTAvllU32RemoveBestFit                         RT_MANGLER(RTAvllU32RemoveBestFit)
+# define RTAvllU32RemoveNode                            RT_MANGLER(RTAvllU32RemoveNode)
+# define RTAvloGCPhysDestroy                            RT_MANGLER(RTAvloGCPhysDestroy)
+# define RTAvloGCPhysDoWithAll                          RT_MANGLER(RTAvloGCPhysDoWithAll)
+# define RTAvloGCPhysGet                                RT_MANGLER(RTAvloGCPhysGet)
+# define RTAvloGCPhysGetBestFit                         RT_MANGLER(RTAvloGCPhysGetBestFit)
+# define RTAvloGCPhysInsert                             RT_MANGLER(RTAvloGCPhysInsert)
+# define RTAvloGCPhysRemove                             RT_MANGLER(RTAvloGCPhysRemove)
+# define RTAvloGCPhysRemoveBestFit                      RT_MANGLER(RTAvloGCPhysRemoveBestFit)
+# define RTAvloGCPtrDestroy                             RT_MANGLER(RTAvloGCPtrDestroy)
+# define RTAvloGCPtrDoWithAll                           RT_MANGLER(RTAvloGCPtrDoWithAll)
+# define RTAvloGCPtrGet                                 RT_MANGLER(RTAvloGCPtrGet)
+# define RTAvloGCPtrGetBestFit                          RT_MANGLER(RTAvloGCPtrGetBestFit)
+# define RTAvloGCPtrInsert                              RT_MANGLER(RTAvloGCPtrInsert)
+# define RTAvloGCPtrRemove                              RT_MANGLER(RTAvloGCPtrRemove)
+# define RTAvloGCPtrRemoveBestFit                       RT_MANGLER(RTAvloGCPtrRemoveBestFit)
+# define RTAvloHCPhysDestroy                            RT_MANGLER(RTAvloHCPhysDestroy)
+# define RTAvloHCPhysDoWithAll                          RT_MANGLER(RTAvloHCPhysDoWithAll)
+# define RTAvloHCPhysGet                                RT_MANGLER(RTAvloHCPhysGet)
+# define RTAvloHCPhysGetBestFit                         RT_MANGLER(RTAvloHCPhysGetBestFit)
+# define RTAvloHCPhysInsert                             RT_MANGLER(RTAvloHCPhysInsert)
+# define RTAvloHCPhysRemove                             RT_MANGLER(RTAvloHCPhysRemove)
+# define RTAvloHCPhysRemoveBestFit                      RT_MANGLER(RTAvloHCPhysRemoveBestFit)
+# define RTAvloIOPortDestroy                            RT_MANGLER(RTAvloIOPortDestroy)
+# define RTAvloIOPortDoWithAll                          RT_MANGLER(RTAvloIOPortDoWithAll)
+# define RTAvloIOPortGet                                RT_MANGLER(RTAvloIOPortGet)
+# define RTAvloIOPortGetBestFit                         RT_MANGLER(RTAvloIOPortGetBestFit)
+# define RTAvloIOPortInsert                             RT_MANGLER(RTAvloIOPortInsert)
+# define RTAvloIOPortRemove                             RT_MANGLER(RTAvloIOPortRemove)
+# define RTAvloIOPortRemoveBestFit                      RT_MANGLER(RTAvloIOPortRemoveBestFit)
+# define RTAvloU32Destroy                               RT_MANGLER(RTAvloU32Destroy)
+# define RTAvloU32DoWithAll                             RT_MANGLER(RTAvloU32DoWithAll)
+# define RTAvloU32Get                                   RT_MANGLER(RTAvloU32Get)
+# define RTAvloU32GetBestFit                            RT_MANGLER(RTAvloU32GetBestFit)
+# define RTAvloU32Insert                                RT_MANGLER(RTAvloU32Insert)
+# define RTAvloU32Remove                                RT_MANGLER(RTAvloU32Remove)
+# define RTAvloU32RemoveBestFit                         RT_MANGLER(RTAvloU32RemoveBestFit)
+# define RTAvlPVDestroy                                 RT_MANGLER(RTAvlPVDestroy)
+# define RTAvlPVDoWithAll                               RT_MANGLER(RTAvlPVDoWithAll)
+# define RTAvlPVGet                                     RT_MANGLER(RTAvlPVGet)
+# define RTAvlPVGetBestFit                              RT_MANGLER(RTAvlPVGetBestFit)
+# define RTAvlPVInsert                                  RT_MANGLER(RTAvlPVInsert)
+# define RTAvlPVRemove                                  RT_MANGLER(RTAvlPVRemove)
+# define RTAvlPVRemoveBestFit                           RT_MANGLER(RTAvlPVRemoveBestFit)
+# define RTAvlrFileOffsetDestroy                        RT_MANGLER(RTAvlrFileOffsetDestroy)
+# define RTAvlrFileOffsetDoWithAll                      RT_MANGLER(RTAvlrFileOffsetDoWithAll)
+# define RTAvlrFileOffsetGet                            RT_MANGLER(RTAvlrFileOffsetGet)
+# define RTAvlrFileOffsetGetBestFit                     RT_MANGLER(RTAvlrFileOffsetGetBestFit)
+# define RTAvlrFileOffsetGetLeft                        RT_MANGLER(RTAvlrFileOffsetGetLeft)
+# define RTAvlrFileOffsetGetRight                       RT_MANGLER(RTAvlrFileOffsetGetRight)
+# define RTAvlrFileOffsetGetRoot                        RT_MANGLER(RTAvlrFileOffsetGetRoot)
+# define RTAvlrFileOffsetInsert                         RT_MANGLER(RTAvlrFileOffsetInsert)
+# define RTAvlrFileOffsetRangeGet                       RT_MANGLER(RTAvlrFileOffsetRangeGet)
+# define RTAvlrFileOffsetRangeRemove                    RT_MANGLER(RTAvlrFileOffsetRangeRemove)
+# define RTAvlrFileOffsetRemove                         RT_MANGLER(RTAvlrFileOffsetRemove)
+# define RTAvlrGCPtrDestroy                             RT_MANGLER(RTAvlrGCPtrDestroy)
+# define RTAvlrGCPtrDoWithAll                           RT_MANGLER(RTAvlrGCPtrDoWithAll)
+# define RTAvlrGCPtrGet                                 RT_MANGLER(RTAvlrGCPtrGet)
+# define RTAvlrGCPtrGetBestFit                          RT_MANGLER(RTAvlrGCPtrGetBestFit)
+# define RTAvlrGCPtrGetLeft                             RT_MANGLER(RTAvlrGCPtrGetLeft)
+# define RTAvlrGCPtrGetRight                            RT_MANGLER(RTAvlrGCPtrGetRight)
+# define RTAvlrGCPtrGetRoot                             RT_MANGLER(RTAvlrGCPtrGetRoot)
+# define RTAvlrGCPtrInsert                              RT_MANGLER(RTAvlrGCPtrInsert)
+# define RTAvlrGCPtrRangeGet                            RT_MANGLER(RTAvlrGCPtrRangeGet)
+# define RTAvlrGCPtrRangeRemove                         RT_MANGLER(RTAvlrGCPtrRangeRemove)
+# define RTAvlrGCPtrRemove                              RT_MANGLER(RTAvlrGCPtrRemove)
+# define RTAvlroGCPhysDestroy                           RT_MANGLER(RTAvlroGCPhysDestroy)
+# define RTAvlroGCPhysDoWithAll                         RT_MANGLER(RTAvlroGCPhysDoWithAll)
+# define RTAvlroGCPhysGet                               RT_MANGLER(RTAvlroGCPhysGet)
+# define RTAvlroGCPhysGetBestFit                        RT_MANGLER(RTAvlroGCPhysGetBestFit)
+# define RTAvlroGCPhysGetLeft                           RT_MANGLER(RTAvlroGCPhysGetLeft)
+# define RTAvlroGCPhysGetRight                          RT_MANGLER(RTAvlroGCPhysGetRight)
+# define RTAvlroGCPhysGetRoot                           RT_MANGLER(RTAvlroGCPhysGetRoot)
+# define RTAvlroGCPhysInsert                            RT_MANGLER(RTAvlroGCPhysInsert)
+# define RTAvlroGCPhysRangeGet                          RT_MANGLER(RTAvlroGCPhysRangeGet)
+# define RTAvlroGCPhysRangeRemove                       RT_MANGLER(RTAvlroGCPhysRangeRemove)
+# define RTAvlroGCPhysRemove                            RT_MANGLER(RTAvlroGCPhysRemove)
+# define RTAvlroGCPtrDestroy                            RT_MANGLER(RTAvlroGCPtrDestroy)
+# define RTAvlroGCPtrDoWithAll                          RT_MANGLER(RTAvlroGCPtrDoWithAll)
+# define RTAvlroGCPtrGet                                RT_MANGLER(RTAvlroGCPtrGet)
+# define RTAvlroGCPtrGetBestFit                         RT_MANGLER(RTAvlroGCPtrGetBestFit)
+# define RTAvlroGCPtrGetLeft                            RT_MANGLER(RTAvlroGCPtrGetLeft)
+# define RTAvlroGCPtrGetRight                           RT_MANGLER(RTAvlroGCPtrGetRight)
+# define RTAvlroGCPtrGetRoot                            RT_MANGLER(RTAvlroGCPtrGetRoot)
+# define RTAvlroGCPtrInsert                             RT_MANGLER(RTAvlroGCPtrInsert)
+# define RTAvlroGCPtrRangeGet                           RT_MANGLER(RTAvlroGCPtrRangeGet)
+# define RTAvlroGCPtrRangeRemove                        RT_MANGLER(RTAvlroGCPtrRangeRemove)
+# define RTAvlroGCPtrRemove                             RT_MANGLER(RTAvlroGCPtrRemove)
+# define RTAvlroIOPortDestroy                           RT_MANGLER(RTAvlroIOPortDestroy)
+# define RTAvlroIOPortDoWithAll                         RT_MANGLER(RTAvlroIOPortDoWithAll)
+# define RTAvlroIOPortGet                               RT_MANGLER(RTAvlroIOPortGet)
+# define RTAvlroIOPortInsert                            RT_MANGLER(RTAvlroIOPortInsert)
+# define RTAvlroIOPortRangeGet                          RT_MANGLER(RTAvlroIOPortRangeGet)
+# define RTAvlroIOPortRangeRemove                       RT_MANGLER(RTAvlroIOPortRangeRemove)
+# define RTAvlroIOPortRemove                            RT_MANGLER(RTAvlroIOPortRemove)
+# define RTAvlrooGCPtrDestroy                           RT_MANGLER(RTAvlrooGCPtrDestroy)
+# define RTAvlrooGCPtrDoWithAll                         RT_MANGLER(RTAvlrooGCPtrDoWithAll)
+# define RTAvlrooGCPtrGet                               RT_MANGLER(RTAvlrooGCPtrGet)
+# define RTAvlrooGCPtrGetBestFit                        RT_MANGLER(RTAvlrooGCPtrGetBestFit)
+# define RTAvlrooGCPtrGetLeft                           RT_MANGLER(RTAvlrooGCPtrGetLeft)
+# define RTAvlrooGCPtrGetNextEqual                      RT_MANGLER(RTAvlrooGCPtrGetNextEqual)
+# define RTAvlrooGCPtrGetRight                          RT_MANGLER(RTAvlrooGCPtrGetRight)
+# define RTAvlrooGCPtrGetRoot                           RT_MANGLER(RTAvlrooGCPtrGetRoot)
+# define RTAvlrooGCPtrInsert                            RT_MANGLER(RTAvlrooGCPtrInsert)
+# define RTAvlrooGCPtrRangeGet                          RT_MANGLER(RTAvlrooGCPtrRangeGet)
+# define RTAvlrooGCPtrRangeRemove                       RT_MANGLER(RTAvlrooGCPtrRangeRemove)
+# define RTAvlrooGCPtrRemove                            RT_MANGLER(RTAvlrooGCPtrRemove)
+# define RTAvlrPVDestroy                                RT_MANGLER(RTAvlrPVDestroy)
+# define RTAvlrPVDoWithAll                              RT_MANGLER(RTAvlrPVDoWithAll)
+# define RTAvlrPVGet                                    RT_MANGLER(RTAvlrPVGet)
+# define RTAvlrPVGetBestFit                             RT_MANGLER(RTAvlrPVGetBestFit)
+# define RTAvlrPVInsert                                 RT_MANGLER(RTAvlrPVInsert)
+# define RTAvlrPVRangeGet                               RT_MANGLER(RTAvlrPVRangeGet)
+# define RTAvlrPVRangeRemove                            RT_MANGLER(RTAvlrPVRangeRemove)
+# define RTAvlrPVRemove                                 RT_MANGLER(RTAvlrPVRemove)
+# define RTAvlrPVRemoveBestFit                          RT_MANGLER(RTAvlrPVRemoveBestFit)
+# define RTAvlrU64Destroy                               RT_MANGLER(RTAvlrU64Destroy)
+# define RTAvlrU64DoWithAll                             RT_MANGLER(RTAvlrU64DoWithAll)
+# define RTAvlrU64Get                                   RT_MANGLER(RTAvlrU64Get)
+# define RTAvlrU64GetBestFit                            RT_MANGLER(RTAvlrU64GetBestFit)
+# define RTAvlrU64Insert                                RT_MANGLER(RTAvlrU64Insert)
+# define RTAvlrU64RangeGet                              RT_MANGLER(RTAvlrU64RangeGet)
+# define RTAvlrU64RangeRemove                           RT_MANGLER(RTAvlrU64RangeRemove)
+# define RTAvlrU64Remove                                RT_MANGLER(RTAvlrU64Remove)
+# define RTAvlrU64RemoveBestFit                         RT_MANGLER(RTAvlrU64RemoveBestFit)
+# define RTAvlrUIntPtrDestroy                           RT_MANGLER(RTAvlrUIntPtrDestroy)
+# define RTAvlrUIntPtrDoWithAll                         RT_MANGLER(RTAvlrUIntPtrDoWithAll)
+# define RTAvlrUIntPtrGet                               RT_MANGLER(RTAvlrUIntPtrGet)
+# define RTAvlrUIntPtrGetBestFit                        RT_MANGLER(RTAvlrUIntPtrGetBestFit)
+# define RTAvlrUIntPtrGetLeft                           RT_MANGLER(RTAvlrUIntPtrGetLeft)
+# define RTAvlrUIntPtrGetRight                          RT_MANGLER(RTAvlrUIntPtrGetRight)
+# define RTAvlrUIntPtrGetRoot                           RT_MANGLER(RTAvlrUIntPtrGetRoot)
+# define RTAvlrUIntPtrInsert                            RT_MANGLER(RTAvlrUIntPtrInsert)
+# define RTAvlrUIntPtrRangeGet                          RT_MANGLER(RTAvlrUIntPtrRangeGet)
+# define RTAvlrUIntPtrRangeRemove                       RT_MANGLER(RTAvlrUIntPtrRangeRemove)
+# define RTAvlrUIntPtrRemove                            RT_MANGLER(RTAvlrUIntPtrRemove)
+# define RTAvlU32Destroy                                RT_MANGLER(RTAvlU32Destroy)
+# define RTAvlU32DoWithAll                              RT_MANGLER(RTAvlU32DoWithAll)
+# define RTAvlU32Get                                    RT_MANGLER(RTAvlU32Get)
+# define RTAvlU32GetBestFit                             RT_MANGLER(RTAvlU32GetBestFit)
+# define RTAvlU32Insert                                 RT_MANGLER(RTAvlU32Insert)
+# define RTAvlU32Remove                                 RT_MANGLER(RTAvlU32Remove)
+# define RTAvlU32RemoveBestFit                          RT_MANGLER(RTAvlU32RemoveBestFit)
+# define RTAvlUIntPtrDestroy                            RT_MANGLER(RTAvlUIntPtrDestroy)
+# define RTAvlUIntPtrDoWithAll                          RT_MANGLER(RTAvlUIntPtrDoWithAll)
+# define RTAvlUIntPtrGet                                RT_MANGLER(RTAvlUIntPtrGet)
+# define RTAvlUIntPtrGetBestFit                         RT_MANGLER(RTAvlUIntPtrGetBestFit)
+# define RTAvlUIntPtrGetLeft                            RT_MANGLER(RTAvlUIntPtrGetLeft)
+# define RTAvlUIntPtrGetRight                           RT_MANGLER(RTAvlUIntPtrGetRight)
+# define RTAvlUIntPtrGetRoot                            RT_MANGLER(RTAvlUIntPtrGetRoot)
+# define RTAvlUIntPtrInsert                             RT_MANGLER(RTAvlUIntPtrInsert)
+# define RTAvlUIntPtrRemove                             RT_MANGLER(RTAvlUIntPtrRemove)
+# define RTAvlULDestroy                                 RT_MANGLER(RTAvlULDestroy)
+# define RTAvlULDoWithAll                               RT_MANGLER(RTAvlULDoWithAll)
+# define RTAvlULGet                                     RT_MANGLER(RTAvlULGet)
+# define RTAvlULGetBestFit                              RT_MANGLER(RTAvlULGetBestFit)
+# define RTAvlULInsert                                  RT_MANGLER(RTAvlULInsert)
+# define RTAvlULRemove                                  RT_MANGLER(RTAvlULRemove)
+# define RTAvlULRemoveBestFit                           RT_MANGLER(RTAvlULRemoveBestFit)
+# define RTBase64Decode                                 RT_MANGLER(RTBase64Decode)
+# define RTBase64DecodeEx                               RT_MANGLER(RTBase64DecodeEx)
+# define RTBase64DecodedSize                            RT_MANGLER(RTBase64DecodedSize)
+# define RTBase64DecodedSizeEx                          RT_MANGLER(RTBase64DecodedSizeEx)
+# define RTBase64Encode                                 RT_MANGLER(RTBase64Encode)
+# define RTBase64EncodedLength                          RT_MANGLER(RTBase64EncodedLength)
+# define RTBldCfgCompiler                               RT_MANGLER(RTBldCfgCompiler)
+# define RTBldCfgRevision                               RT_MANGLER(RTBldCfgRevision)
+# define RTBldCfgRevisionStr                            RT_MANGLER(RTBldCfgRevisionStr)
+# define RTBldCfgTarget                                 RT_MANGLER(RTBldCfgTarget)
+# define RTBldCfgTargetArch                             RT_MANGLER(RTBldCfgTargetArch)
+# define RTBldCfgTargetDotArch                          RT_MANGLER(RTBldCfgTargetDotArch)
+# define RTBldCfgType                                   RT_MANGLER(RTBldCfgType)
+# define RTBldCfgVersion                                RT_MANGLER(RTBldCfgVersion)
+# define RTBldCfgVersionBuild                           RT_MANGLER(RTBldCfgVersionBuild)
+# define RTBldCfgVersionMajor                           RT_MANGLER(RTBldCfgVersionMajor)
+# define RTBldCfgVersionMinor                           RT_MANGLER(RTBldCfgVersionMinor)
+# define RTCdromOpen                                    RT_MANGLER(RTCdromOpen)
+# define RTCdromRetain                                  RT_MANGLER(RTCdromRetain)
+# define RTCdromRelease                                 RT_MANGLER(RTCdromRelease)
+# define RTCdromQueryMountPoint                         RT_MANGLER(RTCdromQueryMountPoint)
+# define RTCdromUnmount                                 RT_MANGLER(RTCdromUnmount)
+# define RTCdromEject                                   RT_MANGLER(RTCdromEject)
+# define RTCdromLock                                    RT_MANGLER(RTCdromLock)
+# define RTCdromUnlock                                  RT_MANGLER(RTCdromUnlock)
+# define RTCdromCount                                   RT_MANGLER(RTCdromCount)
+# define RTCdromOrdinalToName                           RT_MANGLER(RTCdromOrdinalToName)
+# define RTCdromOpenByOrdinal                           RT_MANGLER(RTCdromOpenByOrdinal)
+# define RTCidrStrToIPv4                                RT_MANGLER(RTCidrStrToIPv4)
+# define RTCircBufAcquireReadBlock                      RT_MANGLER(RTCircBufAcquireReadBlock)
+# define RTCircBufAcquireWriteBlock                     RT_MANGLER(RTCircBufAcquireWriteBlock)
+# define RTCircBufCreate                                RT_MANGLER(RTCircBufCreate)
+# define RTCircBufDestroy                               RT_MANGLER(RTCircBufDestroy)
+# define RTCircBufFree                                  RT_MANGLER(RTCircBufFree)
+# define RTCircBufIsReading                             RT_MANGLER(RTCircBufIsReading)
+# define RTCircBufIsWriting                             RT_MANGLER(RTCircBufIsWriting)
+# define RTCircBufReleaseReadBlock                      RT_MANGLER(RTCircBufReleaseReadBlock)
+# define RTCircBufReleaseWriteBlock                     RT_MANGLER(RTCircBufReleaseWriteBlock)
+# define RTCircBufReset                                 RT_MANGLER(RTCircBufReset)
+# define RTCircBufSize                                  RT_MANGLER(RTCircBufSize)
+# define RTCircBufUsed                                  RT_MANGLER(RTCircBufUsed)
+# define RTCoreDumperDisable                            RT_MANGLER(RTCoreDumperDisable)  /* solaris */
+# define RTCoreDumperSetup                              RT_MANGLER(RTCoreDumperSetup)    /* solaris */
+# define RTCoreDumperTakeDump                           RT_MANGLER(RTCoreDumperTakeDump) /* solaris */
+# define RTCrc32                                        RT_MANGLER(RTCrc32)
+# define RTCrc32Finish                                  RT_MANGLER(RTCrc32Finish)
+# define RTCrc32Process                                 RT_MANGLER(RTCrc32Process)
+# define RTCrc32Start                                   RT_MANGLER(RTCrc32Start)
+# define RTCrc32C                                       RT_MANGLER(RTCrc32C)
+# define RTCrc32CFinish                                 RT_MANGLER(RTCrc32CFinish)
+# define RTCrc32CProcess                                RT_MANGLER(RTCrc32CProcess)
+# define RTCrc32CStart                                  RT_MANGLER(RTCrc32CStart)
+# define RTCrc64                                        RT_MANGLER(RTCrc64)
+# define RTCrc64Finish                                  RT_MANGLER(RTCrc64Finish)
+# define RTCrc64Process                                 RT_MANGLER(RTCrc64Process)
+# define RTCrc64Start                                   RT_MANGLER(RTCrc64Start)
+# define RTCrcAdler32                                   RT_MANGLER(RTCrcAdler32)
+# define RTCrcAdler32Finish                             RT_MANGLER(RTCrcAdler32Finish)
+# define RTCrcAdler32Process                            RT_MANGLER(RTCrcAdler32Process)
+# define RTCrcAdler32Start                              RT_MANGLER(RTCrcAdler32Start)
+# define RTCritSectDelete                               RT_MANGLER(RTCritSectDelete)
+# define RTCritSectEnter                                RT_MANGLER(RTCritSectEnter)
+# define RTCritSectEnterDebug                           RT_MANGLER(RTCritSectEnterDebug)
+# define RTCritSectEnterMultiple                        RT_MANGLER(RTCritSectEnterMultiple)
+# define RTCritSectEnterMultipleDebug                   RT_MANGLER(RTCritSectEnterMultipleDebug)
+# define RTCritSectInit                                 RT_MANGLER(RTCritSectInit)
+# define RTCritSectInitEx                               RT_MANGLER(RTCritSectInitEx)
+# define RTCritSectLeave                                RT_MANGLER(RTCritSectLeave)
+# define RTCritSectLeaveMultiple                        RT_MANGLER(RTCritSectLeaveMultiple)
+# define RTCritSectSetSubClass                          RT_MANGLER(RTCritSectSetSubClass)
+# define RTCritSectTryEnter                             RT_MANGLER(RTCritSectTryEnter)
+# define RTCritSectTryEnterDebug                        RT_MANGLER(RTCritSectTryEnterDebug)
+# define RTCritSectRwDelete                             RT_MANGLER(RTCritSectRwDelete)
+# define RTCritSectRwEnterExcl                          RT_MANGLER(RTCritSectRwEnterExcl)
+# define RTCritSectRwEnterExclDebug                     RT_MANGLER(RTCritSectRwEnterExclDebug)
+# define RTCritSectRwEnterShared                        RT_MANGLER(RTCritSectRwEnterShared)
+# define RTCritSectRwEnterSharedDebug                   RT_MANGLER(RTCritSectRwEnterSharedDebug)
+# define RTCritSectRwGetReadCount                       RT_MANGLER(RTCritSectRwGetReadCount)
+# define RTCritSectRwGetWriteRecursion                  RT_MANGLER(RTCritSectRwGetWriteRecursion)
+# define RTCritSectRwGetWriterReadRecursion             RT_MANGLER(RTCritSectRwGetWriterReadRecursion)
+# define RTCritSectRwInit                               RT_MANGLER(RTCritSectRwInit)
+# define RTCritSectRwInitEx                             RT_MANGLER(RTCritSectRwInitEx)
+# define RTCritSectRwIsReadOwner                        RT_MANGLER(RTCritSectRwIsReadOwner)
+# define RTCritSectRwIsWriteOwner                       RT_MANGLER(RTCritSectRwIsWriteOwner)
+# define RTCritSectRwLeaveExcl                          RT_MANGLER(RTCritSectRwLeaveExcl)
+# define RTCritSectRwLeaveShared                        RT_MANGLER(RTCritSectRwLeaveShared)
+# define RTCritSectRwSetSubClass                        RT_MANGLER(RTCritSectRwSetSubClass)
+# define RTCritSectRwTryEnterExcl                       RT_MANGLER(RTCritSectRwTryEnterExcl)
+# define RTCritSectRwTryEnterExclDebug                  RT_MANGLER(RTCritSectRwTryEnterExclDebug)
+# define RTCritSectRwTryEnterShared                     RT_MANGLER(RTCritSectRwTryEnterShared)
+# define RTCritSectRwTryEnterSharedDebug                RT_MANGLER(RTCritSectRwTryEnterSharedDebug)
+# define RTDbgAsCreate                                  RT_MANGLER(RTDbgAsCreate)
+# define RTDbgAsCreateF                                 RT_MANGLER(RTDbgAsCreateF)
+# define RTDbgAsCreateV                                 RT_MANGLER(RTDbgAsCreateV)
+# define RTDbgAsFirstAddr                               RT_MANGLER(RTDbgAsFirstAddr)
+# define RTDbgAsLastAddr                                RT_MANGLER(RTDbgAsLastAddr)
+# define RTDbgAsLineAdd                                 RT_MANGLER(RTDbgAsLineAdd)
+# define RTDbgAsLineByAddr                              RT_MANGLER(RTDbgAsLineByAddr)
+# define RTDbgAsLineByAddrA                             RT_MANGLER(RTDbgAsLineByAddrA)
+# define RTDbgAsLockExcl                                RT_MANGLER(RTDbgAsLockExcl)
+# define RTDbgAsModuleByAddr                            RT_MANGLER(RTDbgAsModuleByAddr)
+# define RTDbgAsModuleByIndex                           RT_MANGLER(RTDbgAsModuleByIndex)
+# define RTDbgAsModuleByName                            RT_MANGLER(RTDbgAsModuleByName)
+# define RTDbgAsModuleCount                             RT_MANGLER(RTDbgAsModuleCount)
+# define RTDbgAsModuleLink                              RT_MANGLER(RTDbgAsModuleLink)
+# define RTDbgAsModuleLinkSeg                           RT_MANGLER(RTDbgAsModuleLinkSeg)
+# define RTDbgAsModuleQueryMapByIndex                   RT_MANGLER(RTDbgAsModuleQueryMapByIndex)
+# define RTDbgAsModuleUnlink                            RT_MANGLER(RTDbgAsModuleUnlink)
+# define RTDbgAsModuleUnlinkByAddr                      RT_MANGLER(RTDbgAsModuleUnlinkByAddr)
+# define RTDbgAsName                                    RT_MANGLER(RTDbgAsName)
+# define RTDbgAsRelease                                 RT_MANGLER(RTDbgAsRelease)
+# define RTDbgAsRetain                                  RT_MANGLER(RTDbgAsRetain)
+# define RTDbgAsSymbolAdd                               RT_MANGLER(RTDbgAsSymbolAdd)
+# define RTDbgAsSymbolByAddr                            RT_MANGLER(RTDbgAsSymbolByAddr)
+# define RTDbgAsSymbolByAddrA                           RT_MANGLER(RTDbgAsSymbolByAddrA)
+# define RTDbgAsSymbolByName                            RT_MANGLER(RTDbgAsSymbolByName)
+# define RTDbgAsSymbolByNameA                           RT_MANGLER(RTDbgAsSymbolByNameA)
+# define RTDbgAsUnlockExcl                              RT_MANGLER(RTDbgAsUnlockExcl)
+# define RTDbgCfgCreate                                 RT_MANGLER(RTDbgCfgCreate)
+# define RTDbgCfgRetain                                 RT_MANGLER(RTDbgCfgRetain)
+# define RTDbgCfgRelease                                RT_MANGLER(RTDbgCfgRelease)
+# define RTDbgCfgChangeString                           RT_MANGLER(RTDbgCfgChangeString)
+# define RTDbgCfgChangeUInt                             RT_MANGLER(RTDbgCfgChangeUInt)
+# define RTDbgCfgQueryString                            RT_MANGLER(RTDbgCfgQueryString)
+# define RTDbgCfgQueryUInt                              RT_MANGLER(RTDbgCfgQueryUInt)
+# define RTDbgCfgOpenDbg                                RT_MANGLER(RTDbgCfgOpenDbg)
+# define RTDbgCfgOpenDsymBundle                         RT_MANGLER(RTDbgCfgOpenDsymBundle)
+# define RTDbgCfgOpenMachOImage                         RT_MANGLER(RTDbgCfgOpenMachOImage)
+# define RTDbgCfgOpenDwo                                RT_MANGLER(RTDbgCfgOpenDwo)
+# define RTDbgCfgOpenPdb70                              RT_MANGLER(RTDbgCfgOpenPdb70)
+# define RTDbgCfgOpenPdb20                              RT_MANGLER(RTDbgCfgOpenPdb20)
+# define RTDbgCfgOpenPeImage                            RT_MANGLER(RTDbgCfgOpenPeImage)
+# define RTDbgCfgSetLogCallback                         RT_MANGLER(RTDbgCfgSetLogCallback)
+# define RTDbgLineAlloc                                 RT_MANGLER(RTDbgLineAlloc)
+# define RTDbgLineDup                                   RT_MANGLER(RTDbgLineDup)
+# define RTDbgLineFree                                  RT_MANGLER(RTDbgLineFree)
+# define RTDbgModCreate                                 RT_MANGLER(RTDbgModCreate)
+# define RTDbgModCreateFromDbg                          RT_MANGLER(RTDbgModCreateFromDbg)
+# define RTDbgModCreateFromDwo                          RT_MANGLER(RTDbgModCreateFromDwo)
+# define RTDbgModCreateFromImage                        RT_MANGLER(RTDbgModCreateFromImage)
+# define RTDbgModCreateFromMap                          RT_MANGLER(RTDbgModCreateFromMap)
+# define RTDbgModCreateFromPdb                          RT_MANGLER(RTDbgModCreateFromPdb)
+# define RTDbgModCreateFromPeImage                      RT_MANGLER(RTDbgModCreateFromPeImage)
+# define RTDbgModCreateFromMachOImage                   RT_MANGLER(RTDbgModCreateFromMachOImage)
+# define RTDbgModGetTag                                 RT_MANGLER(RTDbgModGetTag)
+# define RTDbgModImageSize                              RT_MANGLER(RTDbgModImageSize)
+# define RTDbgModIsDeferred                             RT_MANGLER(RTDbgModIsDeferred)
+# define RTDbgModIsExports                              RT_MANGLER(RTDbgModIsExports)
+# define RTDbgModLineAdd                                RT_MANGLER(RTDbgModLineAdd)
+# define RTDbgModLineByAddr                             RT_MANGLER(RTDbgModLineByAddr)
+# define RTDbgModLineByAddrA                            RT_MANGLER(RTDbgModLineByAddrA)
+# define RTDbgModLineByOrdinal                          RT_MANGLER(RTDbgModLineByOrdinal)
+# define RTDbgModLineByOrdinalA                         RT_MANGLER(RTDbgModLineByOrdinalA)
+# define RTDbgModLineCount                              RT_MANGLER(RTDbgModLineCount)
+# define RTDbgModName                                   RT_MANGLER(RTDbgModName)
+# define RTDbgModDebugFile                              RT_MANGLER(RTDbgModDebugFile)
+# define RTDbgModImageFile                              RT_MANGLER(RTDbgModImageFile)
+# define RTDbgModImageFileUsed                          RT_MANGLER(RTDbgModImageFileUsed)
+# define RTDbgModRelease                                RT_MANGLER(RTDbgModRelease)
+# define RTDbgModRemoveAll                              RT_MANGLER(RTDbgModRemoveAll)
+# define RTDbgModRetain                                 RT_MANGLER(RTDbgModRetain)
+# define RTDbgModRvaToSegOff                            RT_MANGLER(RTDbgModRvaToSegOff)
+# define RTDbgModSegmentAdd                             RT_MANGLER(RTDbgModSegmentAdd)
+# define RTDbgModSegmentByIndex                         RT_MANGLER(RTDbgModSegmentByIndex)
+# define RTDbgModSegmentCount                           RT_MANGLER(RTDbgModSegmentCount)
+# define RTDbgModSegmentRva                             RT_MANGLER(RTDbgModSegmentRva)
+# define RTDbgModSegmentSize                            RT_MANGLER(RTDbgModSegmentSize)
+# define RTDbgModSetTag                                 RT_MANGLER(RTDbgModSetTag)
+# define RTDbgModSymbolAdd                              RT_MANGLER(RTDbgModSymbolAdd)
+# define RTDbgModSymbolByAddr                           RT_MANGLER(RTDbgModSymbolByAddr)
+# define RTDbgModSymbolByAddrA                          RT_MANGLER(RTDbgModSymbolByAddrA)
+# define RTDbgModSymbolByName                           RT_MANGLER(RTDbgModSymbolByName)
+# define RTDbgModSymbolByNameA                          RT_MANGLER(RTDbgModSymbolByNameA)
+# define RTDbgModSymbolByOrdinal                        RT_MANGLER(RTDbgModSymbolByOrdinal)
+# define RTDbgModSymbolByOrdinalA                       RT_MANGLER(RTDbgModSymbolByOrdinalA)
+# define RTDbgModSymbolCount                            RT_MANGLER(RTDbgModSymbolCount)
+# define RTDbgSymbolAlloc                               RT_MANGLER(RTDbgSymbolAlloc)
+# define RTDbgSymbolDup                                 RT_MANGLER(RTDbgSymbolDup)
+# define RTDbgSymbolFree                                RT_MANGLER(RTDbgSymbolFree)
+# define RTDirClose                                     RT_MANGLER(RTDirClose)
+# define RTDirCreate                                    RT_MANGLER(RTDirCreate)
+# define RTDirCreateFullPath                            RT_MANGLER(RTDirCreateFullPath)
+# define RTDirCreateTemp                                RT_MANGLER(RTDirCreateTemp)
+# define RTDirCreateTempSecure                          RT_MANGLER(RTDirCreateTempSecure)
+# define RTDirCreateUniqueNumbered                      RT_MANGLER(RTDirCreateUniqueNumbered)
+# define RTDirEntryIsStdDotLink                         RT_MANGLER(RTDirEntryIsStdDotLink)
+# define RTDirEntryExIsStdDotLink                       RT_MANGLER(RTDirEntryExIsStdDotLink)
+# define RTDirExists                                    RT_MANGLER(RTDirExists)
+# define RTDirFlush                                     RT_MANGLER(RTDirFlush)
+# define RTDirFlushParent                               RT_MANGLER(RTDirFlushParent)
+# define RTDirOpen                                      RT_MANGLER(RTDirOpen)
+# define RTDirOpenFiltered                              RT_MANGLER(RTDirOpenFiltered)
+# define RTDirQueryInfo                                 RT_MANGLER(RTDirQueryInfo)
+# define RTDirQueryUnknownType                          RT_MANGLER(RTDirQueryUnknownType)
+# define RTDirQueryUnknownTypeEx                        RT_MANGLER(RTDirQueryUnknownTypeEx)
+# define RTDirRead                                      RT_MANGLER(RTDirRead)
+# define RTDirReadEx                                    RT_MANGLER(RTDirReadEx)
+# define RTDirRemove                                    RT_MANGLER(RTDirRemove)
+# define RTDirRemoveRecursive                           RT_MANGLER(RTDirRemoveRecursive)
+# define RTDirRename                                    RT_MANGLER(RTDirRename)
+# define RTDirSetTimes                                  RT_MANGLER(RTDirSetTimes)
+# define RTDvmCreate                                    RT_MANGLER(RTDvmCreate)
+# define RTDvmRetain                                    RT_MANGLER(RTDvmRetain)
+# define RTDvmRelease                                   RT_MANGLER(RTDvmRelease)
+# define RTDvmMapOpen                                   RT_MANGLER(RTDvmMapOpen)
+# define RTDvmMapInitialize                             RT_MANGLER(RTDvmMapInitialize)
+# define RTDvmMapGetFormat                              RT_MANGLER(RTDvmMapGetFormat)
+# define RTDvmMapGetValidVolumes                        RT_MANGLER(RTDvmMapGetValidVolumes)
+# define RTDvmMapGetMaxVolumes                          RT_MANGLER(RTDvmMapGetMaxVolumes)
+# define RTDvmMapQueryBlockStatus                       RT_MANGLER(RTDvmMapQueryBlockStatus)
+# define RTDvmMapQueryFirstVolume                       RT_MANGLER(RTDvmMapQueryFirstVolume)
+# define RTDvmMapQueryNextVolume                        RT_MANGLER(RTDvmMapQueryNextVolume)
+# define RTDvmVolumeRetain                              RT_MANGLER(RTDvmVolumeRetain)
+# define RTDvmVolumeRelease                             RT_MANGLER(RTDvmVolumeRelease)
+# define RTDvmVolumeGetSize                             RT_MANGLER(RTDvmVolumeGetSize)
+# define RTDvmVolumeQueryName                           RT_MANGLER(RTDvmVolumeQueryName)
+# define RTDvmVolumeGetType                             RT_MANGLER(RTDvmVolumeGetType)
+# define RTDvmVolumeGetFlags                            RT_MANGLER(RTDvmVolumeGetFlags)
+# define RTDvmVolumeRead                                RT_MANGLER(RTDvmVolumeRead)
+# define RTDvmVolumeWrite                               RT_MANGLER(RTDvmVolumeWrite)
+# define RTDvmVolumeSetQueryBlockStatusCallback         RT_MANGLER(RTDvmVolumeSetQueryBlockStatusCallback)
+# define RTDvmVolumeTypeGetDescr                        RT_MANGLER(RTDvmVolumeTypeGetDescr)
+# define RTDvmVolumeCreateVfsFile                       RT_MANGLER(RTDvmVolumeCreateVfsFile)
+# define RTEnvApplyChanges                              RT_MANGLER(RTEnvApplyChanges)
+# define RTEnvClone                                     RT_MANGLER(RTEnvClone)
+# define RTEnvCloneUtf16Block                           RT_MANGLER(RTEnvCloneUtf16Block)
+# define RTEnvCountEx                                   RT_MANGLER(RTEnvCountEx)
+# define RTEnvCreate                                    RT_MANGLER(RTEnvCreate)
+# define RTEnvCreateChangeRecord                        RT_MANGLER(RTEnvCreateChangeRecord)
+# define RTEnvDestroy                                   RT_MANGLER(RTEnvDestroy)
+# define RTEnvDupEx                                     RT_MANGLER(RTEnvDupEx)
+# define RTEnvExist                                     RT_MANGLER(RTEnvExist)
+# define RTEnvExistsBad                                 RT_MANGLER(RTEnvExistsBad)
+# define RTEnvExistsUtf8                                RT_MANGLER(RTEnvExistsUtf8)
+# define RTEnvExistEx                                   RT_MANGLER(RTEnvExistEx)
+# define RTEnvFreeUtf8Block                             RT_MANGLER(RTEnvFreeUtf8Block)
+# define RTEnvFreeUtf16Block                            RT_MANGLER(RTEnvFreeUtf16Block)
+# define RTEnvGet                                       RT_MANGLER(RTEnvGet)
+# define RTEnvGetBad                                    RT_MANGLER(RTEnvGetBad)
+# define RTEnvGetByIndexEx                              RT_MANGLER(RTEnvGetByIndexEx)
+# define RTEnvGetByIndexRawEx                           RT_MANGLER(RTEnvGetByIndexRawEx)
+# define RTEnvGetUtf8                                   RT_MANGLER(RTEnvGetUtf8)
+# define RTEnvGetEx                                     RT_MANGLER(RTEnvGetEx)
+# define RTEnvGetExecEnvP                               RT_MANGLER(RTEnvGetExecEnvP)
+# define RTEnvIsChangeRecord                            RT_MANGLER(RTEnvIsChangeRecord)
+# define RTEnvPut                                       RT_MANGLER(RTEnvPut)
+# define RTEnvPutBad                                    RT_MANGLER(RTEnvPutBad)
+# define RTEnvPutUtf8                                   RT_MANGLER(RTEnvPutUtf8)
+# define RTEnvPutEx                                     RT_MANGLER(RTEnvPutEx)
+# define RTEnvQueryUtf16Block                           RT_MANGLER(RTEnvQueryUtf16Block)
+# define RTEnvQueryUtf8Block                            RT_MANGLER(RTEnvQueryUtf8Block)
+# define RTEnvReset                                     RT_MANGLER(RTEnvReset)
+# define RTEnvSet                                       RT_MANGLER(RTEnvSet)
+# define RTEnvSetBad                                    RT_MANGLER(RTEnvSetBad)
+# define RTEnvSetUtf8                                   RT_MANGLER(RTEnvSetUtf8)
+# define RTEnvSetEx                                     RT_MANGLER(RTEnvSetEx)
+# define RTEnvUnset                                     RT_MANGLER(RTEnvUnset)
+# define RTEnvUnsetBad                                  RT_MANGLER(RTEnvUnsetBad)
+# define RTEnvUnsetUtf8                                 RT_MANGLER(RTEnvUnsetUtf8)
+# define RTEnvUnsetEx                                   RT_MANGLER(RTEnvUnsetEx)
+# define RTErrCOMGet                                    RT_MANGLER(RTErrCOMGet)
+# define RTErrConvertFromErrno                          RT_MANGLER(RTErrConvertFromErrno)
+# define RTErrConvertToErrno                            RT_MANGLER(RTErrConvertToErrno)
+# define RTErrGet                                       RT_MANGLER(RTErrGet)
+# define RTErrInfoAlloc                                 RT_MANGLER(RTErrInfoAlloc)
+# define RTErrInfoAllocEx                               RT_MANGLER(RTErrInfoAllocEx)
+# define RTErrInfoFree                                  RT_MANGLER(RTErrInfoFree)
+# define RTErrInfoSet                                   RT_MANGLER(RTErrInfoSet)
+# define RTErrInfoSetF                                  RT_MANGLER(RTErrInfoSetF)
+# define RTErrInfoSetV                                  RT_MANGLER(RTErrInfoSetV)
+# define RTErrVarsAreEqual                              RT_MANGLER(RTErrVarsAreEqual)
+# define RTErrVarsHaveChanged                           RT_MANGLER(RTErrVarsHaveChanged)
+# define RTErrVarsRestore                               RT_MANGLER(RTErrVarsRestore)
+# define RTErrVarsSave                                  RT_MANGLER(RTErrVarsSave)
+# define RTFileAioCtxAssociateWithFile                  RT_MANGLER(RTFileAioCtxAssociateWithFile)
+# define RTFileAioCtxCreate                             RT_MANGLER(RTFileAioCtxCreate)
+# define RTFileAioCtxDestroy                            RT_MANGLER(RTFileAioCtxDestroy)
+# define RTFileAioCtxGetMaxReqCount                     RT_MANGLER(RTFileAioCtxGetMaxReqCount)
+# define RTFileAioCtxSubmit                             RT_MANGLER(RTFileAioCtxSubmit)
+# define RTFileAioCtxWait                               RT_MANGLER(RTFileAioCtxWait)
+# define RTFileAioCtxWakeup                             RT_MANGLER(RTFileAioCtxWakeup)
+# define RTFileAioGetLimits                             RT_MANGLER(RTFileAioGetLimits)
+# define RTFileAioReqCancel                             RT_MANGLER(RTFileAioReqCancel)
+# define RTFileAioReqCreate                             RT_MANGLER(RTFileAioReqCreate)
+# define RTFileAioReqDestroy                            RT_MANGLER(RTFileAioReqDestroy)
+# define RTFileAioReqGetRC                              RT_MANGLER(RTFileAioReqGetRC)
+# define RTFileAioReqGetUser                            RT_MANGLER(RTFileAioReqGetUser)
+# define RTFileAioReqPrepareFlush                       RT_MANGLER(RTFileAioReqPrepareFlush)
+# define RTFileAioReqPrepareRead                        RT_MANGLER(RTFileAioReqPrepareRead)
+# define RTFileAioReqPrepareWrite                       RT_MANGLER(RTFileAioReqPrepareWrite)
+# define RTFileChangeLock                               RT_MANGLER(RTFileChangeLock)
+# define RTFileClose                                    RT_MANGLER(RTFileClose)
+# define RTFileCompare                                  RT_MANGLER(RTFileCompare)
+# define RTFileCompareByHandles                         RT_MANGLER(RTFileCompareByHandles)
+# define RTFileCompareByHandlesEx                       RT_MANGLER(RTFileCompareByHandlesEx)
+# define RTFileCompareEx                                RT_MANGLER(RTFileCompareEx)
+# define RTFileCopy                                     RT_MANGLER(RTFileCopy)
+# define RTFileCopyByHandles                            RT_MANGLER(RTFileCopyByHandles)
+# define RTFileCopyByHandlesEx                          RT_MANGLER(RTFileCopyByHandlesEx)
+# define RTFileCopyEx                                   RT_MANGLER(RTFileCopyEx)
+# define RTFileCreateTemp                               RT_MANGLER(RTFileCreateTemp)
+# define RTFileCreateTempSecure                         RT_MANGLER(RTFileCreateTempSecure)
+# define RTFileDelete                                   RT_MANGLER(RTFileDelete)
+# define RTFileExists                                   RT_MANGLER(RTFileExists)
+# define RTFileFlush                                    RT_MANGLER(RTFileFlush)
+# define RTFileFromNative                               RT_MANGLER(RTFileFromNative)
+# define RTFileGetMaxSize                               RT_MANGLER(RTFileGetMaxSize)
+# define RTFileGetMaxSizeEx                             RT_MANGLER(RTFileGetMaxSizeEx)
+# define RTFileGetSize                                  RT_MANGLER(RTFileGetSize)
+# define RTFileIoCtl                                    RT_MANGLER(RTFileIoCtl)
+# define RTFileIsValid                                  RT_MANGLER(RTFileIsValid)
+# define RTFileLock                                     RT_MANGLER(RTFileLock)
+# define RTFileModeToFlags                              RT_MANGLER(RTFileModeToFlags)
+# define RTFileModeToFlagsEx                            RT_MANGLER(RTFileModeToFlagsEx)
+# define RTFileMove                                     RT_MANGLER(RTFileMove)
+# define RTFileOpen                                     RT_MANGLER(RTFileOpen)
+# define RTFileOpenBitBucket                            RT_MANGLER(RTFileOpenBitBucket)
+# define RTFileOpenF                                    RT_MANGLER(RTFileOpenF)
+# define RTFileOpenV                                    RT_MANGLER(RTFileOpenV)
+# define RTFileOpenTemp                                 RT_MANGLER(RTFileOpenTemp)
+# define RTFileQueryFsSizes                             RT_MANGLER(RTFileQueryFsSizes)
+# define RTFileQueryInfo                                RT_MANGLER(RTFileQueryInfo)
+# define RTFileQuerySize                                RT_MANGLER(RTFileQuerySize)
+# define RTFileRead                                     RT_MANGLER(RTFileRead)
+# define RTFileReadAll                                  RT_MANGLER(RTFileReadAll)
+# define RTFileReadAllByHandle                          RT_MANGLER(RTFileReadAllByHandle)
+# define RTFileReadAllByHandleEx                        RT_MANGLER(RTFileReadAllByHandleEx)
+# define RTFileReadAllEx                                RT_MANGLER(RTFileReadAllEx)
+# define RTFileReadAllFree                              RT_MANGLER(RTFileReadAllFree)
+# define RTFileReadAt                                   RT_MANGLER(RTFileReadAt)
+# define RTFileRename                                   RT_MANGLER(RTFileRename)
+# define RTFileSeek                                     RT_MANGLER(RTFileSeek)
+# define RTFileSetForceFlags                            RT_MANGLER(RTFileSetForceFlags)
+# define RTFileSetMode                                  RT_MANGLER(RTFileSetMode)
+# define RTFileSetOwner                                 RT_MANGLER(RTFileSetOwner)
+# define RTFileSetSize                                  RT_MANGLER(RTFileSetSize)
+# define RTFileSetTimes                                 RT_MANGLER(RTFileSetTimes)
+# define RTFileSgReadAt                                 RT_MANGLER(RTFileSgReadAt)
+# define RTFileSgWriteAt                                RT_MANGLER(RTFileSgWriteAt)
+# define RTFileTell                                     RT_MANGLER(RTFileTell)
+# define RTFileToNative                                 RT_MANGLER(RTFileToNative)
+# define RTFileUnlock                                   RT_MANGLER(RTFileUnlock)
+# define RTFileWrite                                    RT_MANGLER(RTFileWrite)
+# define RTFileWriteAt                                  RT_MANGLER(RTFileWriteAt)
+# define RTFilesystemVfsFromFile                        RT_MANGLER(RTFilesystemVfsFromFile)
+# define RTFsIsCaseSensitive                            RT_MANGLER(RTFsIsCaseSensitive)
+# define RTFsQueryProperties                            RT_MANGLER(RTFsQueryProperties)
+# define RTFsQuerySerial                                RT_MANGLER(RTFsQuerySerial)
+# define RTFsQuerySizes                                 RT_MANGLER(RTFsQuerySizes)
+# define RTFsQueryType                                  RT_MANGLER(RTFsQueryType)
+# define RTFsTypeName                                   RT_MANGLER(RTFsTypeName)
+# define RTGetOpt                                       RT_MANGLER(RTGetOpt)
+# define RTGetOptArgvFree                               RT_MANGLER(RTGetOptArgvFree)
+# define RTGetOptArgvFromString                         RT_MANGLER(RTGetOptArgvFromString)
+# define RTGetOptArgvToString                           RT_MANGLER(RTGetOptArgvToString)
+# define RTGetOptArgvToUtf16String                      RT_MANGLER(RTGetOptArgvToUtf16String)
+# define RTGetOptFetchValue                             RT_MANGLER(RTGetOptFetchValue)
+# define RTGetOptInit                                   RT_MANGLER(RTGetOptInit)
+# define RTGetOptPrintError                             RT_MANGLER(RTGetOptPrintError)
+# define RTHandleClose                                  RT_MANGLER(RTHandleClose)
+# define RTHandleGetStandard                            RT_MANGLER(RTHandleGetStandard)
+# define RTHandleTableAlloc                             RT_MANGLER(RTHandleTableAlloc)
+# define RTHandleTableAllocWithCtx                      RT_MANGLER(RTHandleTableAllocWithCtx)
+# define RTHandleTableCreate                            RT_MANGLER(RTHandleTableCreate)
+# define RTHandleTableCreateEx                          RT_MANGLER(RTHandleTableCreateEx)
+# define RTHandleTableDestroy                           RT_MANGLER(RTHandleTableDestroy)
+# define RTHandleTableFree                              RT_MANGLER(RTHandleTableFree)
+# define RTHandleTableFreeWithCtx                       RT_MANGLER(RTHandleTableFreeWithCtx)
+# define RTHandleTableLookup                            RT_MANGLER(RTHandleTableLookup)
+# define RTHandleTableLookupWithCtx                     RT_MANGLER(RTHandleTableLookupWithCtx)
+# define RTHeapOffsetAlloc                              RT_MANGLER(RTHeapOffsetAlloc)
+# define RTHeapOffsetAllocZ                             RT_MANGLER(RTHeapOffsetAllocZ)
+# define RTHeapOffsetDump                               RT_MANGLER(RTHeapOffsetDump)
+# define RTHeapOffsetFree                               RT_MANGLER(RTHeapOffsetFree)
+# define RTHeapOffsetGetFreeSize                        RT_MANGLER(RTHeapOffsetGetFreeSize)
+# define RTHeapOffsetGetHeapSize                        RT_MANGLER(RTHeapOffsetGetHeapSize)
+# define RTHeapOffsetInit                               RT_MANGLER(RTHeapOffsetInit)
+# define RTHeapOffsetSize                               RT_MANGLER(RTHeapOffsetSize)
+# define RTHeapSimpleAlloc                              RT_MANGLER(RTHeapSimpleAlloc)
+# define RTHeapSimpleAllocZ                             RT_MANGLER(RTHeapSimpleAllocZ)
+# define RTHeapSimpleDump                               RT_MANGLER(RTHeapSimpleDump)
+# define RTHeapSimpleFree                               RT_MANGLER(RTHeapSimpleFree)
+# define RTHeapSimpleGetFreeSize                        RT_MANGLER(RTHeapSimpleGetFreeSize)
+# define RTHeapSimpleGetHeapSize                        RT_MANGLER(RTHeapSimpleGetHeapSize)
+# define RTHeapSimpleInit                               RT_MANGLER(RTHeapSimpleInit)
+# define RTHeapSimpleRelocate                           RT_MANGLER(RTHeapSimpleRelocate)
+# define RTHeapSimpleSize                               RT_MANGLER(RTHeapSimpleSize)
+# define RTHttpGetFile                                  RT_MANGLER(RTHttpGetFile)
+# define RTHttpUseSystemProxySettings                   RT_MANGLER(RTHttpUseSystemProxySettings)
+# define RTIsoFsClose                                   RT_MANGLER(RTIsoFsClose)
+# define RTIsoFsExtractFile                             RT_MANGLER(RTIsoFsExtractFile)
+# define RTIsoFsGetFileInfo                             RT_MANGLER(RTIsoFsGetFileInfo)
+# define RTIsoFsOpen                                    RT_MANGLER(RTIsoFsOpen)
+# define RTLatin1CalcUtf16Len                           RT_MANGLER(RTLatin1CalcUtf16Len)
+# define RTLatin1CalcUtf16LenEx                         RT_MANGLER(RTLatin1CalcUtf16LenEx)
+# define RTLatin1CalcUtf8Len                            RT_MANGLER(RTLatin1CalcUtf8Len)
+# define RTLatin1CalcUtf8LenEx                          RT_MANGLER(RTLatin1CalcUtf8LenEx)
+# define RTLatin1ToUtf16ExTag                           RT_MANGLER(RTLatin1ToUtf16ExTag)
+# define RTLatin1ToUtf16Tag                             RT_MANGLER(RTLatin1ToUtf16Tag)
+# define RTLatin1ToUtf8ExTag                            RT_MANGLER(RTLatin1ToUtf8ExTag)
+# define RTLatin1ToUtf8Tag                              RT_MANGLER(RTLatin1ToUtf8Tag)
+# define RTLdrClose                                     RT_MANGLER(RTLdrClose)
+# define RTLdrEnumDbgInfo                               RT_MANGLER(RTLdrEnumDbgInfo)
+# define RTLdrEnumSegments                              RT_MANGLER(RTLdrEnumSegments)
+# define RTLdrEnumSymbols                               RT_MANGLER(RTLdrEnumSymbols)
+# define RTLdrGetArch                                   RT_MANGLER(RTLdrGetArch)
+# define RTLdrGetBits                                   RT_MANGLER(RTLdrGetBits)
+# define RTLdrGetEndian                                 RT_MANGLER(RTLdrGetEndian)
+# define RTLdrGetFormat                                 RT_MANGLER(RTLdrGetFormat)
+# define RTLdrGetFunction                               RT_MANGLER(RTLdrGetFunction)
+# define RTLdrGetNativeHandle                           RT_MANGLER(RTLdrGetNativeHandle)
+# define RTLdrGetSuff                                   RT_MANGLER(RTLdrGetSuff)
+# define RTLdrGetSymbol                                 RT_MANGLER(RTLdrGetSymbol)
+# define RTLdrGetSymbolEx                               RT_MANGLER(RTLdrGetSymbolEx)
+# define RTLdrGetSystemSymbol                           RT_MANGLER(RTLdrGetSystemSymbol)
+# define RTLdrGetType                                   RT_MANGLER(RTLdrGetType)
+# define RTLdrIsLoadable                                RT_MANGLER(RTLdrIsLoadable)
+# define RTLdrLinkAddressToRva                          RT_MANGLER(RTLdrLinkAddressToRva)
+# define RTLdrLinkAddressToSegOffset                    RT_MANGLER(RTLdrLinkAddressToSegOffset)
+# define RTLdrLoad                                      RT_MANGLER(RTLdrLoad)
+# define RTLdrLoadAppPriv                               RT_MANGLER(RTLdrLoadAppPriv)
+# define RTLdrLoadEx                                    RT_MANGLER(RTLdrLoadEx)
+# define RTLdrLoadSystem                                RT_MANGLER(RTLdrLoadSystem)
+# define RTLdrOpen                                      RT_MANGLER(RTLdrOpen)
+# define RTLdrOpenInMemory                              RT_MANGLER(RTLdrOpenInMemory)
+# define RTLdrOpenkLdr                                  RT_MANGLER(RTLdrOpenkLdr)
+# define RTLdrRelocate                                  RT_MANGLER(RTLdrRelocate)
+# define RTLdrRvaToSegOffset                            RT_MANGLER(RTLdrRvaToSegOffset)
+# define RTLdrQueryForwarderInfo                        RT_MANGLER(RTLdrQueryForwarderInfo)
+# define RTLdrQueryProp                                 RT_MANGLER(RTLdrQueryProp)
+# define RTLdrSegOffsetToRva                            RT_MANGLER(RTLdrSegOffsetToRva)
+# define RTLdrSize                                      RT_MANGLER(RTLdrSize)
+# define RTLinuxCheckDevicePath                         RT_MANGLER(RTLinuxCheckDevicePath)
+# define RTLinuxCheckDevicePathV                        RT_MANGLER(RTLinuxCheckDevicePathV)
+# define RTLinuxSysFsClose                              RT_MANGLER(RTLinuxSysFsClose)
+# define RTLinuxSysFsExists                             RT_MANGLER(RTLinuxSysFsExists)
+# define RTLinuxSysFsExistsV                            RT_MANGLER(RTLinuxSysFsExistsV)
+# define RTLinuxSysFsGetLinkDest                        RT_MANGLER(RTLinuxSysFsGetLinkDest)
+# define RTLinuxSysFsGetLinkDestV                       RT_MANGLER(RTLinuxSysFsGetLinkDestV)
+# define RTLinuxSysFsOpen                               RT_MANGLER(RTLinuxSysFsOpen)
+# define RTLinuxSysFsOpenV                              RT_MANGLER(RTLinuxSysFsOpenV)
+# define RTLinuxSysFsReadDevNumFile                     RT_MANGLER(RTLinuxSysFsReadDevNumFile)
+# define RTLinuxSysFsReadDevNumFileV                    RT_MANGLER(RTLinuxSysFsReadDevNumFileV)
+# define RTLinuxSysFsReadFile                           RT_MANGLER(RTLinuxSysFsReadFile)
+# define RTLinuxSysFsReadIntFile                        RT_MANGLER(RTLinuxSysFsReadIntFile)
+# define RTLinuxSysFsReadIntFileV                       RT_MANGLER(RTLinuxSysFsReadIntFileV)
+# define RTLinuxSysFsReadStr                            RT_MANGLER(RTLinuxSysFsReadStr)
+# define RTLinuxSysFsReadStrFile                        RT_MANGLER(RTLinuxSysFsReadStrFile)
+# define RTLinuxSysFsReadStrFileV                       RT_MANGLER(RTLinuxSysFsReadStrFileV)
+# define RTLockValidatorClassAddPriorClass              RT_MANGLER(RTLockValidatorClassAddPriorClass)
+# define RTLockValidatorClassCreate                     RT_MANGLER(RTLockValidatorClassCreate)
+# define RTLockValidatorClassCreateEx                   RT_MANGLER(RTLockValidatorClassCreateEx)
+# define RTLockValidatorClassCreateExV                  RT_MANGLER(RTLockValidatorClassCreateExV)
+# define RTLockValidatorClassCreateUnique               RT_MANGLER(RTLockValidatorClassCreateUnique)
+# define RTLockValidatorClassEnforceStrictReleaseOrder  RT_MANGLER(RTLockValidatorClassEnforceStrictReleaseOrder)
+# define RTLockValidatorClassFindForSrcPos              RT_MANGLER(RTLockValidatorClassFindForSrcPos)
+# define RTLockValidatorClassForSrcPos                  RT_MANGLER(RTLockValidatorClassForSrcPos)
+# define RTLockValidatorClassRelease                    RT_MANGLER(RTLockValidatorClassRelease)
+# define RTLockValidatorClassRetain                     RT_MANGLER(RTLockValidatorClassRetain)
+# define RTLockValidatorHoldsLocksInClass               RT_MANGLER(RTLockValidatorHoldsLocksInClass)
+# define RTLockValidatorHoldsLocksInSubClass            RT_MANGLER(RTLockValidatorHoldsLocksInSubClass)
+# define RTLockValidatorIsBlockedThreadInValidator      RT_MANGLER(RTLockValidatorIsBlockedThreadInValidator)
+# define RTLockValidatorIsEnabled                       RT_MANGLER(RTLockValidatorIsEnabled)
+# define RTLockValidatorIsQuiet                         RT_MANGLER(RTLockValidatorIsQuiet)
+# define RTLockValidatorMayPanic                        RT_MANGLER(RTLockValidatorMayPanic)
+# define RTLockValidatorQueryBlocking                   RT_MANGLER(RTLockValidatorQueryBlocking)
+# define RTLockValidatorReadLockDec                     RT_MANGLER(RTLockValidatorReadLockDec)
+# define RTLockValidatorReadLockGetCount                RT_MANGLER(RTLockValidatorReadLockGetCount)
+# define RTLockValidatorReadLockInc                     RT_MANGLER(RTLockValidatorReadLockInc)
+# define RTLockValidatorRecExclCheckBlocking            RT_MANGLER(RTLockValidatorRecExclCheckBlocking)
+# define RTLockValidatorRecExclCheckOrder               RT_MANGLER(RTLockValidatorRecExclCheckOrder)
+# define RTLockValidatorRecExclCheckOrderAndBlocking    RT_MANGLER(RTLockValidatorRecExclCheckOrderAndBlocking)
+# define RTLockValidatorRecExclCreate                   RT_MANGLER(RTLockValidatorRecExclCreate)
+# define RTLockValidatorRecExclCreateV                  RT_MANGLER(RTLockValidatorRecExclCreateV)
+# define RTLockValidatorRecExclDelete                   RT_MANGLER(RTLockValidatorRecExclDelete)
+# define RTLockValidatorRecExclDestroy                  RT_MANGLER(RTLockValidatorRecExclDestroy)
+# define RTLockValidatorRecExclInit                     RT_MANGLER(RTLockValidatorRecExclInit)
+# define RTLockValidatorRecExclInitV                    RT_MANGLER(RTLockValidatorRecExclInitV)
+# define RTLockValidatorRecExclRecursion                RT_MANGLER(RTLockValidatorRecExclRecursion)
+# define RTLockValidatorRecExclRecursionMixed           RT_MANGLER(RTLockValidatorRecExclRecursionMixed)
+# define RTLockValidatorRecExclReleaseOwner             RT_MANGLER(RTLockValidatorRecExclReleaseOwner)
+# define RTLockValidatorRecExclReleaseOwnerUnchecked    RT_MANGLER(RTLockValidatorRecExclReleaseOwnerUnchecked)
+# define RTLockValidatorRecExclSetOwner                 RT_MANGLER(RTLockValidatorRecExclSetOwner)
+# define RTLockValidatorRecExclSetSubClass              RT_MANGLER(RTLockValidatorRecExclSetSubClass)
+# define RTLockValidatorRecExclUnwind                   RT_MANGLER(RTLockValidatorRecExclUnwind)
+# define RTLockValidatorRecExclUnwindMixed              RT_MANGLER(RTLockValidatorRecExclUnwindMixed)
+# define RTLockValidatorRecMakeSiblings                 RT_MANGLER(RTLockValidatorRecMakeSiblings)
+# define RTLockValidatorRecSharedAddOwner               RT_MANGLER(RTLockValidatorRecSharedAddOwner)
+# define RTLockValidatorRecSharedCheckAndRelease        RT_MANGLER(RTLockValidatorRecSharedCheckAndRelease)
+# define RTLockValidatorRecSharedCheckBlocking          RT_MANGLER(RTLockValidatorRecSharedCheckBlocking)
+# define RTLockValidatorRecSharedCheckOrder             RT_MANGLER(RTLockValidatorRecSharedCheckOrder)
+# define RTLockValidatorRecSharedCheckOrderAndBlocking  RT_MANGLER(RTLockValidatorRecSharedCheckOrderAndBlocking)
+# define RTLockValidatorRecSharedCheckSignaller         RT_MANGLER(RTLockValidatorRecSharedCheckSignaller)
+# define RTLockValidatorRecSharedCreate                 RT_MANGLER(RTLockValidatorRecSharedCreate)
+# define RTLockValidatorRecSharedCreateV                RT_MANGLER(RTLockValidatorRecSharedCreateV)
+# define RTLockValidatorRecSharedDelete                 RT_MANGLER(RTLockValidatorRecSharedDelete)
+# define RTLockValidatorRecSharedDestroy                RT_MANGLER(RTLockValidatorRecSharedDestroy)
+# define RTLockValidatorRecSharedInit                   RT_MANGLER(RTLockValidatorRecSharedInit)
+# define RTLockValidatorRecSharedInitV                  RT_MANGLER(RTLockValidatorRecSharedInitV)
+# define RTLockValidatorRecSharedIsOwner                RT_MANGLER(RTLockValidatorRecSharedIsOwner)
+# define RTLockValidatorRecSharedRemoveOwner            RT_MANGLER(RTLockValidatorRecSharedRemoveOwner)
+# define RTLockValidatorRecSharedResetOwner             RT_MANGLER(RTLockValidatorRecSharedResetOwner)
+# define RTLockValidatorRecSharedSetSubClass            RT_MANGLER(RTLockValidatorRecSharedSetSubClass)
+# define RTLockValidatorSetEnabled                      RT_MANGLER(RTLockValidatorSetEnabled)
+# define RTLockValidatorSetMayPanic                     RT_MANGLER(RTLockValidatorSetMayPanic)
+# define RTLockValidatorSetQuiet                        RT_MANGLER(RTLockValidatorSetQuiet)
+# define RTLockValidatorWriteLockDec                    RT_MANGLER(RTLockValidatorWriteLockDec)
+# define RTLockValidatorWriteLockGetCount               RT_MANGLER(RTLockValidatorWriteLockGetCount)
+# define RTLockValidatorWriteLockInc                    RT_MANGLER(RTLockValidatorWriteLockInc)
+# define RTLogBackdoorPrintf                            RT_MANGLER(RTLogBackdoorPrintf) /* r0drv-guest */
+# define RTLogBackdoorPrintfV                           RT_MANGLER(RTLogBackdoorPrintfV) /* r0drv-guest */
+# define RTLogCalcSizeForR0                             RT_MANGLER(RTLogCalcSizeForR0)
+# define RTLogCloneRC                                   RT_MANGLER(RTLogCloneRC)
+# define RTLogComPrintf                                 RT_MANGLER(RTLogComPrintf)
+# define RTLogComPrintfV                                RT_MANGLER(RTLogComPrintfV)
+# define RTLogCopyGroupsAndFlagsForR0                   RT_MANGLER(RTLogCopyGroupsAndFlagsForR0)
+# define RTLogCreate                                    RT_MANGLER(RTLogCreate)
+# define RTLogCreateEx                                  RT_MANGLER(RTLogCreateEx)
+# define RTLogCreateExV                                 RT_MANGLER(RTLogCreateExV)
+# define RTLogCreateForR0                               RT_MANGLER(RTLogCreateForR0)
+# define RTLogDefaultInit                               RT_MANGLER(RTLogDefaultInit)
+# define RTLogDefaultInstance                           RT_MANGLER(RTLogDefaultInstance)
+# define RTLogDefaultInstanceEx                         RT_MANGLER(RTLogDefaultInstanceEx)
+# define RTLogDestinations                              RT_MANGLER(RTLogDestinations)
+# define RTLogDestroy                                   RT_MANGLER(RTLogDestroy)
+# define RTLogFlags                                     RT_MANGLER(RTLogFlags)
+# define RTLogFlush                                     RT_MANGLER(RTLogFlush)
+# define RTLogFlushRC                                   RT_MANGLER(RTLogFlushRC)
+# define RTLogFlushR0                                   RT_MANGLER(RTLogFlushR0)
+# define RTLogFlushToLogger                             RT_MANGLER(RTLogFlushToLogger)
+# define RTLogFormatV                                   RT_MANGLER(RTLogFormatV)
+# define RTLogGetDefaultInstance                        RT_MANGLER(RTLogGetDefaultInstance)
+# define RTLogGetDefaultInstanceEx                      RT_MANGLER(RTLogGetDefaultInstanceEx)
+# define RTLogGetDestinations                           RT_MANGLER(RTLogGetDestinations)
+# define RTLogGetFlags                                  RT_MANGLER(RTLogGetFlags)
+# define RTLogGetGroupSettings                          RT_MANGLER(RTLogGetGroupSettings)
+# define RTLogGroupSettings                             RT_MANGLER(RTLogGroupSettings)
+# define RTLogLogger                                    RT_MANGLER(RTLogLogger)
+# define RTLogLoggerEx                                  RT_MANGLER(RTLogLoggerEx)
+# define RTLogLoggerExV                                 RT_MANGLER(RTLogLoggerExV)
+# define RTLogLoggerV                                   RT_MANGLER(RTLogLoggerV)
+# define RTLogPrintf                                    RT_MANGLER(RTLogPrintf)
+# define RTLogPrintfV                                   RT_MANGLER(RTLogPrintfV)
+# define RTLogDumpPrintfV                               RT_MANGLER(RTLogDumpPrintfV)
+# define RTLogRelGetDefaultInstance                     RT_MANGLER(RTLogRelGetDefaultInstance)
+# define RTLogRelGetDefaultInstanceEx                   RT_MANGLER(RTLogRelGetDefaultInstanceEx)
+# define RTLogRelLogger                                 RT_MANGLER(RTLogRelLogger)
+# define RTLogRelLoggerV                                RT_MANGLER(RTLogRelLoggerV)
+# define RTLogRelPrintf                                 RT_MANGLER(RTLogRelPrintf)
+# define RTLogRelPrintfV                                RT_MANGLER(RTLogRelPrintfV)
+# define RTLogRelSetBuffering                           RT_MANGLER(RTLogRelSetBuffering)
+# define RTLogRelSetDefaultInstance                     RT_MANGLER(RTLogRelSetDefaultInstance)
+# define RTLogSetBuffering                              RT_MANGLER(RTLogSetBuffering)
+# define RTLogSetCustomPrefixCallback                   RT_MANGLER(RTLogSetCustomPrefixCallback)
+# define RTLogSetCustomPrefixCallbackForR0              RT_MANGLER(RTLogSetCustomPrefixCallbackForR0)
+# define RTLogSetDefaultInstance                        RT_MANGLER(RTLogSetDefaultInstance)
+# define RTLogSetDefaultInstanceThread                  RT_MANGLER(RTLogSetDefaultInstanceThread) /* r0drv */
+# define RTLogSetGroupLimit                             RT_MANGLER(RTLogSetGroupLimit)
+# define RTLogWriteCom                                  RT_MANGLER(RTLogWriteCom)
+# define RTLogWriteCom                                  RT_MANGLER(RTLogWriteCom)
+# define RTLogWriteDebugger                             RT_MANGLER(RTLogWriteDebugger)
+# define RTLogWriteStdErr                               RT_MANGLER(RTLogWriteStdErr)
+# define RTLogWriteStdOut                               RT_MANGLER(RTLogWriteStdOut)
+# define RTLogWriteUser                                 RT_MANGLER(RTLogWriteUser)
+# define RTManifestCreate                               RT_MANGLER(RTManifestCreate)
+# define RTManifestDup                                  RT_MANGLER(RTManifestDup)
+# define RTManifestEntryAdd                             RT_MANGLER(RTManifestEntryAdd)
+# define RTManifestEntryAddIoStream                     RT_MANGLER(RTManifestEntryAddIoStream)
+# define RTManifestEntryAddPassthruIoStream             RT_MANGLER(RTManifestEntryAddPassthruIoStream)
+# define RTManifestEntryExists                          RT_MANGLER(RTManifestEntryExists)
+# define RTManifestEntryRemove                          RT_MANGLER(RTManifestEntryRemove)
+# define RTManifestEntryQueryAttr                       RT_MANGLER(RTManifestEntryQueryAttr)
+# define RTManifestEntrySetAttr                         RT_MANGLER(RTManifestEntrySetAttr)
+# define RTManifestEntryUnsetAttr                       RT_MANGLER(RTManifestEntryUnsetAttr)
+# define RTManifestEquals                               RT_MANGLER(RTManifestEquals)
+# define RTManifestEqualsEx                             RT_MANGLER(RTManifestEqualsEx)
+# define RTManifestPtIosAddEntryNow                     RT_MANGLER(RTManifestPtIosAddEntryNow)
+# define RTManifestQueryAttr                            RT_MANGLER(RTManifestQueryAttr)
+# define RTManifestReadStandard                         RT_MANGLER(RTManifestReadStandard)
+# define RTManifestReadStandardEx                       RT_MANGLER(RTManifestReadStandardEx)
+# define RTManifestReadStandardFromFile                 RT_MANGLER(RTManifestReadStandardFromFile)
+# define RTManifestRelease                              RT_MANGLER(RTManifestRelease)
+# define RTManifestRetain                               RT_MANGLER(RTManifestRetain)
+# define RTManifestSetAttr                              RT_MANGLER(RTManifestSetAttr)
+# define RTManifestUnsetAttr                            RT_MANGLER(RTManifestUnsetAttr)
+# define RTManifestVerify                               RT_MANGLER(RTManifestVerify)
+# define RTManifestVerifyDigestType                     RT_MANGLER(RTManifestVerifyDigestType)
+# define RTManifestVerifyFiles                          RT_MANGLER(RTManifestVerifyFiles)
+# define RTManifestVerifyFilesBuf                       RT_MANGLER(RTManifestVerifyFilesBuf)
+# define RTManifestWriteFiles                           RT_MANGLER(RTManifestWriteFiles)
+# define RTManifestWriteFilesBuf                        RT_MANGLER(RTManifestWriteFilesBuf)
+# define RTManifestWriteStandard                        RT_MANGLER(RTManifestWriteStandard)
+# define RTManifestWriteStandardToFile                  RT_MANGLER(RTManifestWriteStandardToFile)
+# define RTMd5                                          RT_MANGLER(RTMd5)
+# define RTMd5Final                                     RT_MANGLER(RTMd5Final)
+# define RTMd5FromString                                RT_MANGLER(RTMd5FromString)
+# define RTMd5Init                                      RT_MANGLER(RTMd5Init)
+# define RTMd5ToString                                  RT_MANGLER(RTMd5ToString)
+# define RTMd5Update                                    RT_MANGLER(RTMd5Update)
+# define RTMemAllocExTag                                RT_MANGLER(RTMemAllocExTag)
+# define RTMemAllocTag                                  RT_MANGLER(RTMemAllocTag)
+# define RTMemAllocVarTag                               RT_MANGLER(RTMemAllocVarTag)
+# define RTMemAllocZTag                                 RT_MANGLER(RTMemAllocZTag)
+# define RTMemAllocZVarTag                              RT_MANGLER(RTMemAllocZVarTag)
+# define RTMemCacheAlloc                                RT_MANGLER(RTMemCacheAlloc)
+# define RTMemCacheAllocEx                              RT_MANGLER(RTMemCacheAllocEx)
+# define RTMemCacheCreate                               RT_MANGLER(RTMemCacheCreate)
+# define RTMemCacheDestroy                              RT_MANGLER(RTMemCacheDestroy)
+# define RTMemCacheFree                                 RT_MANGLER(RTMemCacheFree)
+# define RTMemContAlloc                                 RT_MANGLER(RTMemContAlloc) /* r0drv */
+# define RTMemContFree                                  RT_MANGLER(RTMemContFree) /* r0drv */
+# define RTMemDump                                      RT_MANGLER(RTMemDump)
+# define RTMemDupExTag                                  RT_MANGLER(RTMemDupExTag)
+# define RTMemDupTag                                    RT_MANGLER(RTMemDupTag)
+# define RTMemEfAlloc                                   RT_MANGLER(RTMemEfAlloc)
+# define RTMemEfAllocNP                                 RT_MANGLER(RTMemEfAllocNP)
+# define RTMemEfAllocVar                                RT_MANGLER(RTMemEfAllocVar)
+# define RTMemEfAllocVarNP                              RT_MANGLER(RTMemEfAllocVarNP)
+# define RTMemEfAllocZ                                  RT_MANGLER(RTMemEfAllocZ)
+# define RTMemEfAllocZNP                                RT_MANGLER(RTMemEfAllocZNP)
+# define RTMemEfAllocZVar                               RT_MANGLER(RTMemEfAllocZVar)
+# define RTMemEfAllocZVarNP                             RT_MANGLER(RTMemEfAllocZVarNP)
+# define RTMemEfDup                                     RT_MANGLER(RTMemEfDup)
+# define RTMemEfDupEx                                   RT_MANGLER(RTMemEfDupEx)
+# define RTMemEfDupExNP                                 RT_MANGLER(RTMemEfDupExNP)
+# define RTMemEfDupNP                                   RT_MANGLER(RTMemEfDupNP)
+# define RTMemEfFree                                    RT_MANGLER(RTMemEfFree)
+# define RTMemEfFreeNP                                  RT_MANGLER(RTMemEfFreeNP)
+# define RTMemEfRealloc                                 RT_MANGLER(RTMemEfRealloc)
+# define RTMemEfReallocNP                               RT_MANGLER(RTMemEfReallocNP)
+# define RTMemEfTmpAlloc                                RT_MANGLER(RTMemEfTmpAlloc)
+# define RTMemEfTmpAllocNP                              RT_MANGLER(RTMemEfTmpAllocNP)
+# define RTMemEfTmpAllocZ                               RT_MANGLER(RTMemEfTmpAllocZ)
+# define RTMemEfTmpAllocZNP                             RT_MANGLER(RTMemEfTmpAllocZNP)
+# define RTMemEfTmpFree                                 RT_MANGLER(RTMemEfTmpFree)
+# define RTMemEfTmpFreeNP                               RT_MANGLER(RTMemEfTmpFreeNP)
+# define RTMemExecAllocTag                              RT_MANGLER(RTMemExecAllocTag)
+# define RTMemExecFree                                  RT_MANGLER(RTMemExecFree)
+# define RTMemFree                                      RT_MANGLER(RTMemFree)
+# define RTMemFreeEx                                    RT_MANGLER(RTMemFreeEx)
+# define RTMemLockedAllocExTag                          RT_MANGLER(RTMemLockedAllocExTag)
+# define RTMemLockedAllocZExTag                         RT_MANGLER(RTMemLockedAllocZExTag)
+# define RTMemLockedAllocTag                            RT_MANGLER(RTMemLockedAllocTag)
+# define RTMemLockedAllocZTag                           RT_MANGLER(RTMemLockedAllocZTag)
+# define RTMemLockedFree                                RT_MANGLER(RTMemLockedFree)
+# define RTMemPageAllocTag                              RT_MANGLER(RTMemPageAllocTag)
+# define RTMemPageAllocZTag                             RT_MANGLER(RTMemPageAllocZTag)
+# define RTMemPageFree                                  RT_MANGLER(RTMemPageFree)
+# define RTMemPoolAlloc                                 RT_MANGLER(RTMemPoolAlloc)
+# define RTMemPoolAllocZ                                RT_MANGLER(RTMemPoolAllocZ)
+# define RTMemPoolCreate                                RT_MANGLER(RTMemPoolCreate)
+# define RTMemPoolDestroy                               RT_MANGLER(RTMemPoolDestroy)
+# define RTMemPoolDup                                   RT_MANGLER(RTMemPoolDup)
+# define RTMemPoolDupEx                                 RT_MANGLER(RTMemPoolDupEx)
+# define RTMemPoolFree                                  RT_MANGLER(RTMemPoolFree)
+# define RTMemPoolRealloc                               RT_MANGLER(RTMemPoolRealloc)
+# define RTMemPoolRefCount                              RT_MANGLER(RTMemPoolRefCount)
+# define RTMemPoolRelease                               RT_MANGLER(RTMemPoolRelease)
+# define RTMemPoolRetain                                RT_MANGLER(RTMemPoolRetain)
+# define RTMemProtect                                   RT_MANGLER(RTMemProtect)
+# define RTMemReallocTag                                RT_MANGLER(RTMemReallocTag)
+# define RTMemTmpAllocTag                               RT_MANGLER(RTMemTmpAllocTag)
+# define RTMemTmpAllocZTag                              RT_MANGLER(RTMemTmpAllocZTag)
+# define RTMemTmpFree                                   RT_MANGLER(RTMemTmpFree)
+# define RTMemTrackerDumpAllToFile                      RT_MANGLER(RTMemTrackerDumpAllToFile)
+# define RTMemTrackerDumpAllToLog                       RT_MANGLER(RTMemTrackerDumpAllToLog)
+# define RTMemTrackerDumpAllToLogRel                    RT_MANGLER(RTMemTrackerDumpAllToLogRel)
+# define RTMemTrackerDumpAllToStdErr                    RT_MANGLER(RTMemTrackerDumpAllToStdErr)
+# define RTMemTrackerDumpAllToStdOut                    RT_MANGLER(RTMemTrackerDumpAllToStdOut)
+# define RTMemTrackerDumpStatsToFile                    RT_MANGLER(RTMemTrackerDumpStatsToFile)
+# define RTMemTrackerDumpStatsToLog                     RT_MANGLER(RTMemTrackerDumpStatsToLog)
+# define RTMemTrackerDumpStatsToLogRel                  RT_MANGLER(RTMemTrackerDumpStatsToLogRel)
+# define RTMemTrackerDumpStatsToStdErr                  RT_MANGLER(RTMemTrackerDumpStatsToStdErr)
+# define RTMemTrackerDumpStatsToStdOut                  RT_MANGLER(RTMemTrackerDumpStatsToStdOut)
+# define RTMemTrackerHdrAlloc                           RT_MANGLER(RTMemTrackerHdrAlloc)
+# define RTMemTrackerHdrFree                            RT_MANGLER(RTMemTrackerHdrFree)
+# define RTMemTrackerHdrReallocDone                     RT_MANGLER(RTMemTrackerHdrReallocDone)
+# define RTMemTrackerHdrReallocPrep                     RT_MANGLER(RTMemTrackerHdrReallocPrep)
+# define RTMemWipeThoroughly                            RT_MANGLER(RTMemWipeThoroughly)
+# define RTMpCpuId                                      RT_MANGLER(RTMpCpuId)
+# define RTMpCpuIdFromSetIndex                          RT_MANGLER(RTMpCpuIdFromSetIndex)
+# define RTMpCpuIdToSetIndex                            RT_MANGLER(RTMpCpuIdToSetIndex)
+# define RTMpCurSetIndex                                RT_MANGLER(RTMpCurSetIndex)
+# define RTMpCurSetIndexAndId                           RT_MANGLER(RTMpCurSetIndexAndId)
+# define RTMpGetArraySize                               RT_MANGLER(RTMpGetArraySize)
+# define RTMpGetCount                                   RT_MANGLER(RTMpGetCount)
+# define RTMpGetCurFrequency                            RT_MANGLER(RTMpGetCurFrequency)
+# define RTMpGetDescription                             RT_MANGLER(RTMpGetDescription)
+# define RTMpGetMaxCpuId                                RT_MANGLER(RTMpGetMaxCpuId)
+# define RTMpGetMaxFrequency                            RT_MANGLER(RTMpGetMaxFrequency)
+# define RTMpGetOnlineCount                             RT_MANGLER(RTMpGetOnlineCount)
+# define RTMpGetOnlineCoreCount                         RT_MANGLER(RTMpGetOnlineCoreCount)
+# define RTMpGetOnlineSet                               RT_MANGLER(RTMpGetOnlineSet)
+# define RTMpGetPresentCount                            RT_MANGLER(RTMpGetPresentCount)
+# define RTMpGetPresentCoreCount                        RT_MANGLER(RTMpGetPresentCoreCount)
+# define RTMpGetPresentSet                              RT_MANGLER(RTMpGetPresentSet)
+# define RTMpGetSet                                     RT_MANGLER(RTMpGetSet)
+# define RTMpGetCoreCount                               RT_MANGLER(RTMpGetCoreCount)
+# define RTMpIsCpuOnline                                RT_MANGLER(RTMpIsCpuOnline)
+# define RTMpIsCpuPossible                              RT_MANGLER(RTMpIsCpuPossible) /* r0drv */
+# define RTMpIsCpuPresent                               RT_MANGLER(RTMpIsCpuPresent)
+# define RTMpIsCpuWorkPending                           RT_MANGLER(RTMpIsCpuWorkPending)
+# define RTMpNotificationDeregister                     RT_MANGLER(RTMpNotificationDeregister) /* r0drv */
+# define RTMpNotificationRegister                       RT_MANGLER(RTMpNotificationRegister)   /* r0drv */
+# define RTMpOnAll                                      RT_MANGLER(RTMpOnAll)                  /* r0drv */
+# define RTMpOnAllIsConcurrentSafe                      RT_MANGLER(RTMpOnAllIsConcurrentSafe)  /* r0drv */
+# define RTMpOnOthers                                   RT_MANGLER(RTMpOnOthers)               /* r0drv */
+# define RTMpOnPair                                     RT_MANGLER(RTMpOnPair)                 /* r0drv */
+# define RTMpOnPairIsConcurrentExecSupported            RT_MANGLER(RTMpOnPairIsConcurrentExecSupported) /* r0drv */
+# define RTMpOnSpecific                                 RT_MANGLER(RTMpOnSpecific)             /* r0drv */
+# define RTMpPokeCpu                                    RT_MANGLER(RTMpPokeCpu)                /* r0drv */
+# define RTMsgError                                     RT_MANGLER(RTMsgError)
+# define RTMsgErrorExit                                 RT_MANGLER(RTMsgErrorExit)
+# define RTMsgErrorExitV                                RT_MANGLER(RTMsgErrorExitV)
+# define RTMsgErrorRc                                   RT_MANGLER(RTMsgErrorRc)
+# define RTMsgErrorRcV                                  RT_MANGLER(RTMsgErrorRcV)
+# define RTMsgErrorV                                    RT_MANGLER(RTMsgErrorV)
+# define RTMsgInfo                                      RT_MANGLER(RTMsgInfo)
+# define RTMsgInfoV                                     RT_MANGLER(RTMsgInfoV)
+# define RTMsgInitFailure                               RT_MANGLER(RTMsgInitFailure)
+# define RTMsgSetProgName                               RT_MANGLER(RTMsgSetProgName)
+# define RTMsgWarning                                   RT_MANGLER(RTMsgWarning)
+# define RTMsgWarningV                                  RT_MANGLER(RTMsgWarningV)
+# define RTNetIPv4AddDataChecksum                       RT_MANGLER(RTNetIPv4AddDataChecksum)
+# define RTNetIPv4AddTCPChecksum                        RT_MANGLER(RTNetIPv4AddTCPChecksum)
+# define RTNetIPv4AddUDPChecksum                        RT_MANGLER(RTNetIPv4AddUDPChecksum)
+# define RTNetIPv4FinalizeChecksum                      RT_MANGLER(RTNetIPv4FinalizeChecksum)
+# define RTNetIPv4HdrChecksum                           RT_MANGLER(RTNetIPv4HdrChecksum)
+# define RTNetIPv4IsDHCPValid                           RT_MANGLER(RTNetIPv4IsDHCPValid)
+# define RTNetIPv4IsHdrValid                            RT_MANGLER(RTNetIPv4IsHdrValid)
+# define RTNetIPv4IsTCPSizeValid                        RT_MANGLER(RTNetIPv4IsTCPSizeValid)
+# define RTNetIPv4IsTCPValid                            RT_MANGLER(RTNetIPv4IsTCPValid)
+# define RTNetIPv4IsUDPSizeValid                        RT_MANGLER(RTNetIPv4IsUDPSizeValid)
+# define RTNetIPv4IsUDPValid                            RT_MANGLER(RTNetIPv4IsUDPValid)
+# define RTNetIPv4PseudoChecksum                        RT_MANGLER(RTNetIPv4PseudoChecksum)
+# define RTNetIPv4PseudoChecksumBits                    RT_MANGLER(RTNetIPv4PseudoChecksumBits)
+# define RTNetIPv4TCPChecksum                           RT_MANGLER(RTNetIPv4TCPChecksum)
+# define RTNetIPv4UDPChecksum                           RT_MANGLER(RTNetIPv4UDPChecksum)
+# define RTNetIPv6PseudoChecksum                        RT_MANGLER(RTNetIPv6PseudoChecksum)
+# define RTNetIPv6PseudoChecksumBits                    RT_MANGLER(RTNetIPv6PseudoChecksumBits)
+# define RTNetIPv6PseudoChecksumEx                      RT_MANGLER(RTNetIPv6PseudoChecksumEx)
+# define RTNetTCPChecksum                               RT_MANGLER(RTNetTCPChecksum)
+# define RTNetUDPChecksum                               RT_MANGLER(RTNetUDPChecksum)
+# define RTNetStrToMacAddr                              RT_MANGLER(RTNetStrToMacAddr)
+# define RTNetIsIPv4AddrStr                             RT_MANGLER(RTNetIsIPv4AddrStr)
+# define RTNetStrIsIPv4AddrAny                          RT_MANGLER(RTNetStrIsIPv4AddrAny)
+# define RTNetStrToIPv4AddrEx                           RT_MANGLER(RTNetStrToIPv4AddrEx)
+# define RTNetStrToIPv4Addr                             RT_MANGLER(RTNetStrToIPv4Addr)
+# define RTNetIsIPv6AddrStr                             RT_MANGLER(RTNetIsIPv6AddrStr)
+# define RTNetStrIsIPv6AddrAny                          RT_MANGLER(RTNetStrIsIPv6AddrAny)
+# define RTNetStrToIPv6AddrEx                           RT_MANGLER(RTNetStrToIPv6AddrEx)
+# define RTNetStrToIPv6Addr                             RT_MANGLER(RTNetStrToIPv6Addr)
+# define RTOnceSlow                                     RT_MANGLER(RTOnceSlow)
+# define RTOnceReset                                    RT_MANGLER(RTOnceReset)
+# define RTPathAbs                                      RT_MANGLER(RTPathAbs)
+# define RTPathAbsDup                                   RT_MANGLER(RTPathAbsDup)
+# define RTPathAbsEx                                    RT_MANGLER(RTPathAbsEx)
+# define RTPathAbsExDup                                 RT_MANGLER(RTPathAbsExDup)
+# define RTPathAppDocs                                  RT_MANGLER(RTPathAppDocs)
+# define RTPathAppend                                   RT_MANGLER(RTPathAppend)
+# define RTPathAppendEx                                 RT_MANGLER(RTPathAppendEx)
+# define RTPathAppPrivateArch                           RT_MANGLER(RTPathAppPrivateArch)
+# define RTPathAppPrivateArchTop                        RT_MANGLER(RTPathAppPrivateArchTop)
+# define RTPathAppPrivateNoArch                         RT_MANGLER(RTPathAppPrivateNoArch)
+# define RTPathCalcRelative                             RT_MANGLER(RTPathCalcRelative)
+# define RTPathChangeToDosSlashes                       RT_MANGLER(RTPathChangeToDosSlashes)
+# define RTPathChangeToUnixSlashes                      RT_MANGLER(RTPathChangeToUnixSlashes)
+# define RTPathCompare                                  RT_MANGLER(RTPathCompare)
+# define RTPathCopyComponents                           RT_MANGLER(RTPathCopyComponents)
+# define RTPathCountComponents                          RT_MANGLER(RTPathCountComponents)
+# define RTPathEnsureTrailingSeparator                  RT_MANGLER(RTPathEnsureTrailingSeparator)
+# define RTPathExecDir                                  RT_MANGLER(RTPathExecDir)
+# define RTPathExists                                   RT_MANGLER(RTPathExists)
+# define RTPathExistsEx                                 RT_MANGLER(RTPathExistsEx)
+# define RTPathSuffix                                   RT_MANGLER(RTPathSuffix)
+# define RTPathFilename                                 RT_MANGLER(RTPathFilename)
+# define RTPathFilenameEx                               RT_MANGLER(RTPathFilenameEx)
+# define RTPathGetCurrent                               RT_MANGLER(RTPathGetCurrent)
+# define RTPathGetCurrentDrive                          RT_MANGLER(RTPathGetCurrentDrive)
+# define RTPathGetCurrentOnDrive                        RT_MANGLER(RTPathGetCurrentOnDrive)
+# define RTPathGetMode                                  RT_MANGLER(RTPathGetMode)
+# define RTPathGlob                                     RT_MANGLER(RTPathGlob)
+# define RTPathGlobFree                                 RT_MANGLER(RTPathGlobFree)
+# define RTPathHasSuffix                                RT_MANGLER(RTPathHasSuffix)
+# define RTPathHasPath                                  RT_MANGLER(RTPathHasPath)
+# define RTPathIsSame                                   RT_MANGLER(RTPathIsSame)
+# define RTPathJoin                                     RT_MANGLER(RTPathJoin)
+# define RTPathJoinA                                    RT_MANGLER(RTPathJoinA)
+# define RTPathJoinEx                                   RT_MANGLER(RTPathJoinEx)
+# define RTPathParse                                    RT_MANGLER(RTPathParse)
+# define RTPathParsedReassemble                         RT_MANGLER(RTPathParsedReassemble)
+# define RTPathParseSimple                              RT_MANGLER(RTPathParseSimple)
+# define RTPathQueryInfo                                RT_MANGLER(RTPathQueryInfo)
+# define RTPathQueryInfoEx                              RT_MANGLER(RTPathQueryInfoEx)
+# define RTPathReal                                     RT_MANGLER(RTPathReal)
+# define RTPathRealDup                                  RT_MANGLER(RTPathRealDup)
+# define RTPathRename                                   RT_MANGLER(RTPathRename)
+# define RTPathRmCmd                                    RT_MANGLER(RTPathRmCmd)
+# define RTPathSetCurrent                               RT_MANGLER(RTPathSetCurrent)
+# define RTPathSetMode                                  RT_MANGLER(RTPathSetMode)                   /* not-win */
+# define RTPathSetOwner                                 RT_MANGLER(RTPathSetOwner)                  /* not-win */
+# define RTPathSetOwnerEx                               RT_MANGLER(RTPathSetOwnerEx)                /* not-win */
+# define RTPathSetTimes                                 RT_MANGLER(RTPathSetTimes)
+# define RTPathSetTimesEx                               RT_MANGLER(RTPathSetTimesEx)
+# define RTPathSharedLibs                               RT_MANGLER(RTPathSharedLibs)
+# define RTPathSplit                                    RT_MANGLER(RTPathSplit)
+# define RTPathSplitATag                                RT_MANGLER(RTPathSplitATag)
+# define RTPathSplitFree                                RT_MANGLER(RTPathSplitFree)
+# define RTPathSplitReassemble                          RT_MANGLER(RTPathSplitReassemble)
+# define RTPathStartsWith                               RT_MANGLER(RTPathStartsWith)
+# define RTPathStartsWithRoot                           RT_MANGLER(RTPathStartsWithRoot)
+# define RTPathStripSuffix                              RT_MANGLER(RTPathStripSuffix)
+# define RTPathStripFilename                            RT_MANGLER(RTPathStripFilename)
+# define RTPathStripTrailingSlash                       RT_MANGLER(RTPathStripTrailingSlash)
+# define RTPathTemp                                     RT_MANGLER(RTPathTemp)
+# define RTPathTraverseList                             RT_MANGLER(RTPathTraverseList)
+# define RTPathUnlink                                   RT_MANGLER(RTPathUnlink)
+# define RTPathUserDocuments                            RT_MANGLER(RTPathUserDocuments)
+# define RTPathUserHome                                 RT_MANGLER(RTPathUserHome)
+# define RTPipeClose                                    RT_MANGLER(RTPipeClose)
+# define RTPipeCreate                                   RT_MANGLER(RTPipeCreate)
+# define RTPipeFlush                                    RT_MANGLER(RTPipeFlush)
+# define RTPipeFromNative                               RT_MANGLER(RTPipeFromNative)
+# define RTPipeQueryInfo                                RT_MANGLER(RTPipeQueryInfo)
+# define RTPipeQueryReadable                            RT_MANGLER(RTPipeQueryReadable)
+# define RTPipeRead                                     RT_MANGLER(RTPipeRead)
+# define RTPipeReadBlocking                             RT_MANGLER(RTPipeReadBlocking)
+# define RTPipeSelectOne                                RT_MANGLER(RTPipeSelectOne)
+# define RTPipeToNative                                 RT_MANGLER(RTPipeToNative)
+# define RTPipeWrite                                    RT_MANGLER(RTPipeWrite)
+# define RTPipeWriteBlocking                            RT_MANGLER(RTPipeWriteBlocking)
+# define RTPoll                                         RT_MANGLER(RTPoll)
+# define RTPollNoResume                                 RT_MANGLER(RTPollNoResume)
+# define RTPollSetAdd                                   RT_MANGLER(RTPollSetAdd)
+# define RTPollSetCreate                                RT_MANGLER(RTPollSetCreate)
+# define RTPollSetDestroy                               RT_MANGLER(RTPollSetDestroy)
+# define RTPollSetEventsChange                          RT_MANGLER(RTPollSetEventsChange)
+# define RTPollSetGetCount                              RT_MANGLER(RTPollSetGetCount)
+# define RTPollSetQueryHandle                           RT_MANGLER(RTPollSetQueryHandle)
+# define RTPollSetRemove                                RT_MANGLER(RTPollSetRemove)
+# define RTPowerNotificationDeregister                  RT_MANGLER(RTPowerNotificationDeregister) /* r0drv */
+# define RTPowerNotificationRegister                    RT_MANGLER(RTPowerNotificationRegister) /* r0drv */
+# define RTPowerSignalEvent                             RT_MANGLER(RTPowerSignalEvent)         /* r0drv */
+# define RTPrintf                                       RT_MANGLER(RTPrintf)
+# define RTPrintfV                                      RT_MANGLER(RTPrintfV)
+# define RTProcCreate                                   RT_MANGLER(RTProcCreate)
+# define RTProcCreateEx                                 RT_MANGLER(RTProcCreateEx)
+# define RTProcDaemonize                                RT_MANGLER(RTProcDaemonize)
+# define RTProcDaemonizeUsingFork                       RT_MANGLER(RTProcDaemonizeUsingFork)
+# define RTProcGetAffinityMask                          RT_MANGLER(RTProcGetAffinityMask)
+# define RTProcGetExecutablePath                        RT_MANGLER(RTProcGetExecutablePath)
+# define RTProcGetPriority                              RT_MANGLER(RTProcGetPriority)
+# define RTProcIsRunningByName                          RT_MANGLER(RTProcIsRunningByName)
+# define RTProcQueryParent                              RT_MANGLER(RTProcQueryParent)
+# define RTProcQueryUsername                            RT_MANGLER(RTProcQueryUsername)
+# define RTProcQueryUsernameA                           RT_MANGLER(RTProcQueryUsernameA)
+# define RTProcSelf                                     RT_MANGLER(RTProcSelf)
+# define RTProcSetPriority                              RT_MANGLER(RTProcSetPriority)
+# define RTProcShortName                                RT_MANGLER(RTProcShortName)
+# define RTProcTerminate                                RT_MANGLER(RTProcTerminate)
+# define RTProcWait                                     RT_MANGLER(RTProcWait)
+# define RTProcWaitNoResume                             RT_MANGLER(RTProcWaitNoResume)
+# define RTR0AssertPanicSystem                          RT_MANGLER(RTR0AssertPanicSystem)      /* r0drv */
+# define RTR0DbgKrnlInfoOpen                            RT_MANGLER(RTR0DbgKrnlInfoOpen)        /* r0drv */
+# define RTR0DbgKrnlInfoQueryMember                     RT_MANGLER(RTR0DbgKrnlInfoQueryMember) /* r0drv */
+# define RTR0DbgKrnlInfoQuerySize                       RT_MANGLER(RTR0DbgKrnlInfoQuerySize)   /* r0drv */
+# define RTR0DbgKrnlInfoQuerySymbol                     RT_MANGLER(RTR0DbgKrnlInfoQuerySymbol) /* r0drv */
+# define RTR0DbgKrnlInfoRelease                         RT_MANGLER(RTR0DbgKrnlInfoRelease)     /* r0drv */
+# define RTR0DbgKrnlInfoRetain                          RT_MANGLER(RTR0DbgKrnlInfoRetain)      /* r0drv */
+# define RTR0Init                                       RT_MANGLER(RTR0Init)                   /* r0drv */
+# define RTR0MemAreKrnlAndUsrDifferent                  RT_MANGLER(RTR0MemAreKrnlAndUsrDifferent) /* r0drv */
+# define RTR0MemExecDonate                              RT_MANGLER(RTR0MemExecDonate)          /* r0drv */
+# define RTR0MemKernelIsValidAddr                       RT_MANGLER(RTR0MemKernelIsValidAddr)   /* r0drv */
+# define RTR0MemObjAddress                              RT_MANGLER(RTR0MemObjAddress)          /* r0drv */
+# define RTR0MemObjAddressR3                            RT_MANGLER(RTR0MemObjAddressR3)        /* r0drv */
+# define RTR0MemKernelCopyFrom                          RT_MANGLER(RTR0MemKernelCopyFrom)      /* r0drv */
+# define RTR0MemKernelCopyTo                            RT_MANGLER(RTR0MemKernelCopyTo)        /* r0drv */
+# define RTR0MemObjAllocContTag                         RT_MANGLER(RTR0MemObjAllocContTag)     /* r0drv */
+# define RTR0MemObjAllocLowTag                          RT_MANGLER(RTR0MemObjAllocLowTag)      /* r0drv */
+# define RTR0MemObjAllocPageTag                         RT_MANGLER(RTR0MemObjAllocPageTag)     /* r0drv */
+# define RTR0MemObjAllocPhysExTag                       RT_MANGLER(RTR0MemObjAllocPhysExTag)   /* r0drv */
+# define RTR0MemObjAllocPhysNCTag                       RT_MANGLER(RTR0MemObjAllocPhysNCTag)   /* r0drv */
+# define RTR0MemObjAllocPhysTag                         RT_MANGLER(RTR0MemObjAllocPhysTag)     /* r0drv */
+# define RTR0MemObjEnterPhysTag                         RT_MANGLER(RTR0MemObjEnterPhysTag)     /* r0drv */
+# define RTR0MemObjFree                                 RT_MANGLER(RTR0MemObjFree)             /* r0drv */
+# define RTR0MemObjGetPagePhysAddr                      RT_MANGLER(RTR0MemObjGetPagePhysAddr)  /* r0drv */
+# define RTR0MemObjIsMapping                            RT_MANGLER(RTR0MemObjIsMapping)        /* r0drv */
+# define RTR0MemObjLockKernelTag                        RT_MANGLER(RTR0MemObjLockKernelTag)    /* r0drv */
+# define RTR0MemObjLockUserTag                          RT_MANGLER(RTR0MemObjLockUserTag)      /* r0drv */
+# define RTR0MemObjMapKernelExTag                       RT_MANGLER(RTR0MemObjMapKernelExTag)   /* r0drv */
+# define RTR0MemObjMapKernelTag                         RT_MANGLER(RTR0MemObjMapKernelTag)     /* r0drv */
+# define RTR0MemObjMapUserTag                           RT_MANGLER(RTR0MemObjMapUserTag)       /* r0drv */
+# define RTR0MemObjProtect                              RT_MANGLER(RTR0MemObjProtect)          /* r0drv */
+# define RTR0MemObjReserveKernelTag                     RT_MANGLER(RTR0MemObjReserveKernelTag) /* r0drv */
+# define RTR0MemObjReserveUserTag                       RT_MANGLER(RTR0MemObjReserveUserTag)   /* r0drv */
+# define RTR0MemObjSize                                 RT_MANGLER(RTR0MemObjSize)             /* r0drv */
+# define RTR0MemUserCopyFrom                            RT_MANGLER(RTR0MemUserCopyFrom)        /* r0drv */
+# define RTR0MemUserCopyTo                              RT_MANGLER(RTR0MemUserCopyTo)          /* r0drv */
+# define RTR0MemUserIsValidAddr                         RT_MANGLER(RTR0MemUserIsValidAddr)     /* r0drv */
+# define RTR0ProcHandleSelf                             RT_MANGLER(RTR0ProcHandleSelf)         /* r0drv */
+# define RTR0Term                                       RT_MANGLER(RTR0Term)                   /* r0drv */
+# define RTR0TermForced                                 RT_MANGLER(RTR0TermForced)             /* r0drv */
+# define RTR3InitDll                                    RT_MANGLER(RTR3InitDll)
+# define RTR3InitExe                                    RT_MANGLER(RTR3InitExe)
+# define RTR3InitExeNoArguments                         RT_MANGLER(RTR3InitExeNoArguments)
+# define RTR3InitEx                                     RT_MANGLER(RTR3InitEx)
+# define RTR3InitIsInitialized                          RT_MANGLER(RTR3InitIsInitialized)
+# define RTR3InitIsUnobtrusive                          RT_MANGLER(RTR3InitIsUnobtrusive)
+# define rtR3MemAlloc                                   RT_MANGLER(rtR3MemAlloc)
+# define rtR3MemFree                                    RT_MANGLER(rtR3MemFree)
+# define rtR3MemRealloc                                 RT_MANGLER(rtR3MemRealloc)
+# define RTRCInit                                       RT_MANGLER(RTRCInit)
+# define RTRCTerm                                       RT_MANGLER(RTRCTerm)
+# define RTRandAdvBytes                                 RT_MANGLER(RTRandAdvBytes)
+# define RTRandAdvCreateParkMiller                      RT_MANGLER(RTRandAdvCreateParkMiller)
+# define RTRandAdvCreateSystemFaster                    RT_MANGLER(RTRandAdvCreateSystemFaster)
+# define RTRandAdvCreateSystemTruer                     RT_MANGLER(RTRandAdvCreateSystemTruer)
+# define RTRandAdvDestroy                               RT_MANGLER(RTRandAdvDestroy)
+# define RTRandAdvRestoreState                          RT_MANGLER(RTRandAdvRestoreState)
+# define RTRandAdvS32                                   RT_MANGLER(RTRandAdvS32)
+# define RTRandAdvS32Ex                                 RT_MANGLER(RTRandAdvS32Ex)
+# define RTRandAdvS64                                   RT_MANGLER(RTRandAdvS64)
+# define RTRandAdvS64Ex                                 RT_MANGLER(RTRandAdvS64Ex)
+# define RTRandAdvSaveState                             RT_MANGLER(RTRandAdvSaveState)
+# define RTRandAdvSeed                                  RT_MANGLER(RTRandAdvSeed)
+# define RTRandAdvU32                                   RT_MANGLER(RTRandAdvU32)
+# define RTRandAdvU32Ex                                 RT_MANGLER(RTRandAdvU32Ex)
+# define RTRandAdvU64                                   RT_MANGLER(RTRandAdvU64)
+# define RTRandAdvU64Ex                                 RT_MANGLER(RTRandAdvU64Ex)
+# define RTRandBytes                                    RT_MANGLER(RTRandBytes)
+# define RTRandS32                                      RT_MANGLER(RTRandS32)
+# define RTRandS32Ex                                    RT_MANGLER(RTRandS32Ex)
+# define RTRandS64                                      RT_MANGLER(RTRandS64)
+# define RTRandS64Ex                                    RT_MANGLER(RTRandS64Ex)
+# define RTRandU32                                      RT_MANGLER(RTRandU32)
+# define RTRandU32Ex                                    RT_MANGLER(RTRandU32Ex)
+# define RTRandU64                                      RT_MANGLER(RTRandU64)
+# define RTRandU64Ex                                    RT_MANGLER(RTRandU64Ex)
+# define RTReqPoolAlloc                                 RT_MANGLER(RTReqPoolAlloc)
+# define RTReqPoolCallEx                                RT_MANGLER(RTReqPoolCallEx)
+# define RTReqPoolCallExV                               RT_MANGLER(RTReqPoolCallExV)
+# define RTReqPoolCallWait                              RT_MANGLER(RTReqPoolCallWait)
+# define RTReqPoolCallNoWait                            RT_MANGLER(RTReqPoolCallNoWait)
+# define RTReqPoolCallVoidWait                          RT_MANGLER(RTReqPoolCallVoidWait)
+# define RTReqPoolCallVoidNoWait                        RT_MANGLER(RTReqPoolCallVoidNoWait)
+# define RTReqPoolCreate                                RT_MANGLER(RTReqPoolCreate)
+# define RTReqPoolGetCfgVar                             RT_MANGLER(RTReqPoolGetCfgVar)
+# define RTReqPoolGetStat                               RT_MANGLER(RTReqPoolGetStat)
+# define RTReqPoolRetain                                RT_MANGLER(RTReqPoolRetain)
+# define RTReqPoolRelease                               RT_MANGLER(RTReqPoolRelease)
+# define RTReqPoolSetCfgVar                             RT_MANGLER(RTReqPoolSetCfgVar)
+# define RTReqQueueAlloc                                RT_MANGLER(RTReqQueueAlloc)
+# define RTReqQueueCall                                 RT_MANGLER(RTReqQueueCall)
+# define RTReqQueueCallEx                               RT_MANGLER(RTReqQueueCallEx)
+# define RTReqQueueCallV                                RT_MANGLER(RTReqQueueCallV)
+# define RTReqQueueCallVoid                             RT_MANGLER(RTReqQueueCallVoid)
+# define RTReqQueueCreate                               RT_MANGLER(RTReqQueueCreate)
+# define RTReqQueueDestroy                              RT_MANGLER(RTReqQueueDestroy)
+# define RTReqQueueIsBusy                               RT_MANGLER(RTReqQueueIsBusy)
+# define RTReqQueueProcess                              RT_MANGLER(RTReqQueueProcess)
+# define RTReqSubmit                                    RT_MANGLER(RTReqSubmit)
+# define RTReqRelease                                   RT_MANGLER(RTReqRelease)
+# define RTReqRetain                                    RT_MANGLER(RTReqRetain)
+# define RTReqWait                                      RT_MANGLER(RTReqWait)
+# define RTRSAVerify                                    RT_MANGLER(RTRSAVerify)
+# define RTReqGetStatus                                 RT_MANGLER(RTReqGetStatus)
+# define RTS3BucketsDestroy                             RT_MANGLER(RTS3BucketsDestroy)
+# define RTS3Create                                     RT_MANGLER(RTS3Create)
+# define RTS3CreateBucket                               RT_MANGLER(RTS3CreateBucket)
+# define RTS3DeleteBucket                               RT_MANGLER(RTS3DeleteBucket)
+# define RTS3DeleteKey                                  RT_MANGLER(RTS3DeleteKey)
+# define RTS3Destroy                                    RT_MANGLER(RTS3Destroy)
+# define RTS3GetBucketKeys                              RT_MANGLER(RTS3GetBucketKeys)
+# define RTS3GetBuckets                                 RT_MANGLER(RTS3GetBuckets)
+# define RTS3GetKey                                     RT_MANGLER(RTS3GetKey)
+# define RTS3KeysDestroy                                RT_MANGLER(RTS3KeysDestroy)
+# define RTS3PutKey                                     RT_MANGLER(RTS3PutKey)
+# define RTS3SetProgressCallback                        RT_MANGLER(RTS3SetProgressCallback)
+# define RTSemEventAddSignaller                         RT_MANGLER(RTSemEventAddSignaller)
+# define RTSemEventCreate                               RT_MANGLER(RTSemEventCreate)
+# define RTSemEventCreateEx                             RT_MANGLER(RTSemEventCreateEx)
+# define RTSemEventDestroy                              RT_MANGLER(RTSemEventDestroy)
+# define RTSemEventGetResolution                        RT_MANGLER(RTSemEventGetResolution)    /* r0drv */
+# define RTSemEventMultiAddSignaller                    RT_MANGLER(RTSemEventMultiAddSignaller)
+# define RTSemEventMultiCreate                          RT_MANGLER(RTSemEventMultiCreate)
+# define RTSemEventMultiCreateEx                        RT_MANGLER(RTSemEventMultiCreateEx)
+# define RTSemEventMultiDestroy                         RT_MANGLER(RTSemEventMultiDestroy)
+# define RTSemEventMultiGetResolution                   RT_MANGLER(RTSemEventMultiGetResolution) /* r0drv */
+# define RTSemEventMultiRemoveSignaller                 RT_MANGLER(RTSemEventMultiRemoveSignaller)
+# define RTSemEventMultiReset                           RT_MANGLER(RTSemEventMultiReset)
+# define RTSemEventMultiSetSignaller                    RT_MANGLER(RTSemEventMultiSetSignaller)
+# define RTSemEventMultiSignal                          RT_MANGLER(RTSemEventMultiSignal)
+# define RTSemEventMultiWait                            RT_MANGLER(RTSemEventMultiWait)
+# define RTSemEventMultiWaitEx                          RT_MANGLER(RTSemEventMultiWaitEx)
+# define RTSemEventMultiWaitEx                          RT_MANGLER(RTSemEventMultiWaitEx)      /* r0drv */
+# define RTSemEventMultiWaitExDebug                     RT_MANGLER(RTSemEventMultiWaitExDebug)
+# define RTSemEventMultiWaitExDebug                     RT_MANGLER(RTSemEventMultiWaitExDebug) /* r0drv */
+# define RTSemEventMultiWaitNoResume                    RT_MANGLER(RTSemEventMultiWaitNoResume)
+# define RTSemEventRemoveSignaller                      RT_MANGLER(RTSemEventRemoveSignaller)
+# define RTSemEventSetSignaller                         RT_MANGLER(RTSemEventSetSignaller)
+# define RTSemEventSignal                               RT_MANGLER(RTSemEventSignal)
+# define RTSemEventWait                                 RT_MANGLER(RTSemEventWait)
+# define RTSemEventWaitEx                               RT_MANGLER(RTSemEventWaitEx)           /* r0drv */
+# define RTSemEventWaitExDebug                          RT_MANGLER(RTSemEventWaitExDebug)      /* r0drv */
+# define RTSemEventWaitNoResume                         RT_MANGLER(RTSemEventWaitNoResume)
+# define RTSemFastMutexCreate                           RT_MANGLER(RTSemFastMutexCreate)
+# define RTSemFastMutexDestroy                          RT_MANGLER(RTSemFastMutexDestroy)
+# define RTSemFastMutexRelease                          RT_MANGLER(RTSemFastMutexRelease)
+# define RTSemFastMutexRequest                          RT_MANGLER(RTSemFastMutexRequest)
+# define RTSemMutexCreate                               RT_MANGLER(RTSemMutexCreate)
+# define RTSemMutexCreateEx                             RT_MANGLER(RTSemMutexCreateEx)
+# define RTSemMutexDestroy                              RT_MANGLER(RTSemMutexDestroy)
+# define RTSemMutexIsOwned                              RT_MANGLER(RTSemMutexIsOwned)
+# define RTSemMutexRelease                              RT_MANGLER(RTSemMutexRelease)
+# define RTSemMutexRequest                              RT_MANGLER(RTSemMutexRequest)
+# define RTSemMutexRequestDebug                         RT_MANGLER(RTSemMutexRequestDebug)
+# define RTSemMutexRequestNoResume                      RT_MANGLER(RTSemMutexRequestNoResume)
+# define RTSemMutexRequestNoResumeDebug                 RT_MANGLER(RTSemMutexRequestNoResumeDebug)
+# define RTSemMutexSetSubClass                          RT_MANGLER(RTSemMutexSetSubClass)
+# define RTSemPing                                      RT_MANGLER(RTSemPing)
+# define RTSemPingPongDelete                            RT_MANGLER(RTSemPingPongDelete)
+# define RTSemPingPongInit                              RT_MANGLER(RTSemPingPongInit)
+# define RTSemPingWait                                  RT_MANGLER(RTSemPingWait)
+# define RTSemPong                                      RT_MANGLER(RTSemPong)
+# define RTSemPongWait                                  RT_MANGLER(RTSemPongWait)
+# define RTSemRWCreate                                  RT_MANGLER(RTSemRWCreate)
+# define RTSemRWCreateEx                                RT_MANGLER(RTSemRWCreateEx)
+# define RTSemRWDestroy                                 RT_MANGLER(RTSemRWDestroy)
+# define RTSemRWGetReadCount                            RT_MANGLER(RTSemRWGetReadCount)
+# define RTSemRWGetWriteRecursion                       RT_MANGLER(RTSemRWGetWriteRecursion)
+# define RTSemRWGetWriterReadRecursion                  RT_MANGLER(RTSemRWGetWriterReadRecursion)
+# define RTSemRWIsReadOwner                             RT_MANGLER(RTSemRWIsReadOwner)
+# define RTSemRWIsWriteOwner                            RT_MANGLER(RTSemRWIsWriteOwner)
+# define RTSemRWReleaseRead                             RT_MANGLER(RTSemRWReleaseRead)
+# define RTSemRWReleaseWrite                            RT_MANGLER(RTSemRWReleaseWrite)
+# define RTSemRWRequestRead                             RT_MANGLER(RTSemRWRequestRead)
+# define RTSemRWRequestReadDebug                        RT_MANGLER(RTSemRWRequestReadDebug)
+# define RTSemRWRequestReadNoResume                     RT_MANGLER(RTSemRWRequestReadNoResume)
+# define RTSemRWRequestReadNoResumeDebug                RT_MANGLER(RTSemRWRequestReadNoResumeDebug)
+# define RTSemRWRequestWrite                            RT_MANGLER(RTSemRWRequestWrite)
+# define RTSemRWRequestWriteDebug                       RT_MANGLER(RTSemRWRequestWriteDebug)
+# define RTSemRWRequestWriteNoResume                    RT_MANGLER(RTSemRWRequestWriteNoResume)
+# define RTSemRWRequestWriteNoResumeDebug               RT_MANGLER(RTSemRWRequestWriteNoResumeDebug)
+# define RTSemRWSetSubClass                             RT_MANGLER(RTSemRWSetSubClass)
+# define RTSemSpinMutexCreate                           RT_MANGLER(RTSemSpinMutexCreate)
+# define RTSemSpinMutexDestroy                          RT_MANGLER(RTSemSpinMutexDestroy)
+# define RTSemSpinMutexRelease                          RT_MANGLER(RTSemSpinMutexRelease)
+# define RTSemSpinMutexRequest                          RT_MANGLER(RTSemSpinMutexRequest)
+# define RTSemSpinMutexTryRequest                       RT_MANGLER(RTSemSpinMutexTryRequest)
+# define RTSemXRoadsCreate                              RT_MANGLER(RTSemXRoadsCreate)
+# define RTSemXRoadsDestroy                             RT_MANGLER(RTSemXRoadsDestroy)
+# define RTSemXRoadsEWEnter                             RT_MANGLER(RTSemXRoadsEWEnter)
+# define RTSemXRoadsEWLeave                             RT_MANGLER(RTSemXRoadsEWLeave)
+# define RTSemXRoadsNSEnter                             RT_MANGLER(RTSemXRoadsNSEnter)
+# define RTSemXRoadsNSLeave                             RT_MANGLER(RTSemXRoadsNSLeave)
+# define RTSgBufAdvance                                 RT_MANGLER(RTSgBufAdvance)
+# define RTSgBufClone                                   RT_MANGLER(RTSgBufClone)
+# define RTSgBufCmp                                     RT_MANGLER(RTSgBufCmp)
+# define RTSgBufCmpEx                                   RT_MANGLER(RTSgBufCmpEx)
+# define RTSgBufCopy                                    RT_MANGLER(RTSgBufCopy)
+# define RTSgBufCopyFromBuf                             RT_MANGLER(RTSgBufCopyFromBuf)
+# define RTSgBufCopyToBuf                               RT_MANGLER(RTSgBufCopyToBuf)
+# define RTSgBufInit                                    RT_MANGLER(RTSgBufInit)
+# define RTSgBufIsZero                                  RT_MANGLER(RTSgBufIsZero)
+# define RTSgBufReset                                   RT_MANGLER(RTSgBufReset)
+# define RTSgBufSegArrayCreate                          RT_MANGLER(RTSgBufSegArrayCreate)
+# define RTSgBufSet                                     RT_MANGLER(RTSgBufSet)
+# define RTSgBufGetNextSegment                          RT_MANGLER(RTSgBufGetNextSegment)
+# define RTSha1                                         RT_MANGLER(RTSha1)
+# define RTSha1Check                                    RT_MANGLER(RTSha1Check)
+# define RTSha1Digest                                   RT_MANGLER(RTSha1Digest)
+# define RTSha1DigestFromFile                           RT_MANGLER(RTSha1DigestFromFile)
+# define RTSha1Final                                    RT_MANGLER(RTSha1Final)
+# define RTSha1FromString                               RT_MANGLER(RTSha1FromString)
+# define RTSha1Init                                     RT_MANGLER(RTSha1Init)
+# define RTSha1ToString                                 RT_MANGLER(RTSha1ToString)
+# define RTSha1Update                                   RT_MANGLER(RTSha1Update)
+# define RTSha224                                       RT_MANGLER(RTSha224)
+# define RTSha224Check                                  RT_MANGLER(RTSha224Check)
+# define RTSha224Final                                  RT_MANGLER(RTSha224Final)
+# define RTSha224FromString                             RT_MANGLER(RTSha224FromString)
+# define RTSha224Init                                   RT_MANGLER(RTSha224Init)
+# define RTSha224ToString                               RT_MANGLER(RTSha224ToString)
+# define RTSha224Update                                 RT_MANGLER(RTSha224Update)
+# define RTSha224Digest                                 RT_MANGLER(RTSha224Digest)
+# define RTSha224DigestFromFile                         RT_MANGLER(RTSha224DigestFromFile)
+# define RTSha256                                       RT_MANGLER(RTSha256)
+# define RTSha256Check                                  RT_MANGLER(RTSha256Check)
+# define RTSha256Final                                  RT_MANGLER(RTSha256Final)
+# define RTSha256FromString                             RT_MANGLER(RTSha256FromString)
+# define RTSha256Init                                   RT_MANGLER(RTSha256Init)
+# define RTSha256ToString                               RT_MANGLER(RTSha256ToString)
+# define RTSha256Update                                 RT_MANGLER(RTSha256Update)
+# define RTSha256Digest                                 RT_MANGLER(RTSha256Digest)
+# define RTSha256DigestFromFile                         RT_MANGLER(RTSha256DigestFromFile)
+# define RTSha384                                       RT_MANGLER(RTSha384)
+# define RTSha384Check                                  RT_MANGLER(RTSha384Check)
+# define RTSha384Final                                  RT_MANGLER(RTSha384Final)
+# define RTSha384FromString                             RT_MANGLER(RTSha384FromString)
+# define RTSha384Init                                   RT_MANGLER(RTSha384Init)
+# define RTSha384ToString                               RT_MANGLER(RTSha384ToString)
+# define RTSha384Update                                 RT_MANGLER(RTSha384Update)
+# define RTSha512                                       RT_MANGLER(RTSha512)
+# define RTSha512Check                                  RT_MANGLER(RTSha512Check)
+# define RTSha512Final                                  RT_MANGLER(RTSha512Final)
+# define RTSha512FromString                             RT_MANGLER(RTSha512FromString)
+# define RTSha512Init                                   RT_MANGLER(RTSha512Init)
+# define RTSha512ToString                               RT_MANGLER(RTSha512ToString)
+# define RTSha512Update                                 RT_MANGLER(RTSha512Update)
+# define RTSha512t224                                   RT_MANGLER(RTSha512t224)
+# define RTSha512t224Check                              RT_MANGLER(RTSha512t224Check)
+# define RTSha512t224Final                              RT_MANGLER(RTSha512t224Final)
+# define RTSha512t224FromString                         RT_MANGLER(RTSha512t224FromString)
+# define RTSha512t224Init                               RT_MANGLER(RTSha512t224Init)
+# define RTSha512t224ToString                           RT_MANGLER(RTSha512t224ToString)
+# define RTSha512t224Update                             RT_MANGLER(RTSha512t224Update)
+# define RTSha512t256                                   RT_MANGLER(RTSha512t256)
+# define RTSha512t256Check                              RT_MANGLER(RTSha512t256Check)
+# define RTSha512t256Final                              RT_MANGLER(RTSha512t256Final)
+# define RTSha512t256FromString                         RT_MANGLER(RTSha512t256FromString)
+# define RTSha512t256Init                               RT_MANGLER(RTSha512t256Init)
+# define RTSha512t256ToString                           RT_MANGLER(RTSha512t256ToString)
+# define RTSha512t256Update                             RT_MANGLER(RTSha512t256Update)
+# define RTSocketClose                                  RT_MANGLER(RTSocketClose)
+# define RTSocketFromNative                             RT_MANGLER(RTSocketFromNative)
+# define RTSocketQueryAddressStr                        RT_MANGLER(RTSocketQueryAddressStr)
+# define RTSocketGetLocalAddress                        RT_MANGLER(RTSocketGetLocalAddress)
+# define RTSocketGetPeerAddress                         RT_MANGLER(RTSocketGetPeerAddress)
+# define RTSocketParseInetAddress                       RT_MANGLER(RTSocketParseInetAddress)
+# define RTSocketRead                                   RT_MANGLER(RTSocketRead)
+# define RTSocketReadFrom                               RT_MANGLER(RTSocketReadFrom)
+# define RTSocketReadNB                                 RT_MANGLER(RTSocketReadNB)
+# define RTSocketRelease                                RT_MANGLER(RTSocketRelease)
+# define RTSocketRetain                                 RT_MANGLER(RTSocketRetain)
+# define RTSocketSelectOne                              RT_MANGLER(RTSocketSelectOne)
+# define RTSocketSelectOneEx                            RT_MANGLER(RTSocketSelectOneEx)
+# define RTSocketSetInheritance                         RT_MANGLER(RTSocketSetInheritance)
+# define RTSocketSgWrite                                RT_MANGLER(RTSocketSgWrite)
+# define RTSocketSgWriteL                               RT_MANGLER(RTSocketSgWriteL)
+# define RTSocketSgWriteLNB                             RT_MANGLER(RTSocketSgWriteLNB)
+# define RTSocketSgWriteLV                              RT_MANGLER(RTSocketSgWriteLV)
+# define RTSocketSgWriteLVNB                            RT_MANGLER(RTSocketSgWriteLVNB)
+# define RTSocketSgWriteNB                              RT_MANGLER(RTSocketSgWriteNB)
+# define RTSocketShutdown                               RT_MANGLER(RTSocketShutdown)
+# define RTSocketToNative                               RT_MANGLER(RTSocketToNative)
+# define RTSocketWrite                                  RT_MANGLER(RTSocketWrite)
+# define RTSocketWriteNB                                RT_MANGLER(RTSocketWriteNB)
+# define RTSocketWriteTo                                RT_MANGLER(RTSocketWriteTo)
+# define RTSortApvIsSorted                              RT_MANGLER(RTSortApvIsSorted)
+# define RTSortApvShell                                 RT_MANGLER(RTSortApvShell)
+# define RTSortIsSorted                                 RT_MANGLER(RTSortIsSorted)
+# define RTSpinlockAcquire                              RT_MANGLER(RTSpinlockAcquire)
+# define RTSpinlockAcquireNoInts                        RT_MANGLER(RTSpinlockAcquireNoInts)
+# define RTSpinlockCreate                               RT_MANGLER(RTSpinlockCreate)
+# define RTSpinlockDestroy                              RT_MANGLER(RTSpinlockDestroy)
+# define RTSpinlockRelease                              RT_MANGLER(RTSpinlockRelease)
+# define RTStrAAppendExNVTag                            RT_MANGLER(RTStrAAppendExNVTag)
+# define RTStrAAppendNTag                               RT_MANGLER(RTStrAAppendNTag)
+# define RTStrAAppendTag                                RT_MANGLER(RTStrAAppendTag)
+# define RTStrAllocExTag                                RT_MANGLER(RTStrAllocExTag)
+# define RTStrAllocTag                                  RT_MANGLER(RTStrAllocTag)
+# define RTStrAPrintf2VTag                              RT_MANGLER(RTStrAPrintf2VTag)
+# define RTStrAPrintfVTag                               RT_MANGLER(RTStrAPrintfVTag)
+# define RTStrATruncateTag                              RT_MANGLER(RTStrATruncateTag)
+# define RTStrCacheCreate                               RT_MANGLER(RTStrCacheCreate)
+# define RTStrCacheDestroy                              RT_MANGLER(RTStrCacheDestroy)
+# define RTStrCacheEnter                                RT_MANGLER(RTStrCacheEnter)
+# define RTStrCacheEnterLower                           RT_MANGLER(RTStrCacheEnterLower)
+# define RTStrCacheEnterLowerN                          RT_MANGLER(RTStrCacheEnterLowerN)
+# define RTStrCacheEnterN                               RT_MANGLER(RTStrCacheEnterN)
+# define RTStrCacheGetStats                             RT_MANGLER(RTStrCacheGetStats)
+# define RTStrCacheIsRealImpl                           RT_MANGLER(RTStrCacheIsRealImpl)
+# define RTStrCacheLength                               RT_MANGLER(RTStrCacheLength)
+# define RTStrCacheRelease                              RT_MANGLER(RTStrCacheRelease)
+# define RTStrCacheRetain                               RT_MANGLER(RTStrCacheRetain)
+# define RTStrCalcLatin1Len                             RT_MANGLER(RTStrCalcLatin1Len)
+# define RTStrCalcLatin1LenEx                           RT_MANGLER(RTStrCalcLatin1LenEx)
+# define RTStrCalcUtf16Len                              RT_MANGLER(RTStrCalcUtf16Len)
+# define RTStrCalcUtf16LenEx                            RT_MANGLER(RTStrCalcUtf16LenEx)
+# define RTStrCat                                       RT_MANGLER(RTStrCat)
+# define RTStrCatEx                                     RT_MANGLER(RTStrCatEx)
+# define RTStrCatP                                      RT_MANGLER(RTStrCatP)
+# define RTStrCatPEx                                    RT_MANGLER(RTStrCatPEx)
+# define RTStrCmp                                       RT_MANGLER(RTStrCmp)
+# define RTStrConvertHexBytes                           RT_MANGLER(RTStrConvertHexBytes)
+# define RTStrCopy                                      RT_MANGLER(RTStrCopy)
+# define RTStrCopyEx                                    RT_MANGLER(RTStrCopyEx)
+# define RTStrCopyP                                     RT_MANGLER(RTStrCopyP)
+# define RTStrCopyPEx                                   RT_MANGLER(RTStrCopyPEx)
+# define RTStrCurrentCPToUtf8Tag                        RT_MANGLER(RTStrCurrentCPToUtf8Tag)
+# define RTStrDupExTag                                  RT_MANGLER(RTStrDupExTag)
+# define RTStrDupNTag                                   RT_MANGLER(RTStrDupNTag)
+# define RTStrDupTag                                    RT_MANGLER(RTStrDupTag)
+# define RTStrFormat                                    RT_MANGLER(RTStrFormat)
+# define RTStrFormatNumber                              RT_MANGLER(RTStrFormatNumber)
+# define RTStrFormatR80                                 RT_MANGLER(RTStrFormatR80)
+# define RTStrFormatR80u2                               RT_MANGLER(RTStrFormatR80u2)
+# define RTStrFormatTypeDeregister                      RT_MANGLER(RTStrFormatTypeDeregister)
+# define RTStrFormatTypeRegister                        RT_MANGLER(RTStrFormatTypeRegister)
+# define RTStrFormatTypeSetUser                         RT_MANGLER(RTStrFormatTypeSetUser)
+# define RTStrFormatU128                                RT_MANGLER(RTStrFormatU128)
+# define RTStrFormatU16                                 RT_MANGLER(RTStrFormatU16)
+# define RTStrFormatU32                                 RT_MANGLER(RTStrFormatU32)
+# define RTStrFormatU64                                 RT_MANGLER(RTStrFormatU64)
+# define RTStrFormatU8                                  RT_MANGLER(RTStrFormatU8)
+# define RTStrFormatV                                   RT_MANGLER(RTStrFormatV)
+# define RTStrFree                                      RT_MANGLER(RTStrFree)
+# define RTStrGetCpExInternal                           RT_MANGLER(RTStrGetCpExInternal)
+# define RTStrGetCpInternal                             RT_MANGLER(RTStrGetCpInternal)
+# define RTStrGetCpNExInternal                          RT_MANGLER(RTStrGetCpNExInternal)
+# define RTStrHash1                                     RT_MANGLER(RTStrHash1)
+# define RTStrHash1ExN                                  RT_MANGLER(RTStrHash1ExN)
+# define RTStrHash1ExNV                                 RT_MANGLER(RTStrHash1ExNV)
+# define RTStrHash1N                                    RT_MANGLER(RTStrHash1N)
+# define RTStrICmp                                      RT_MANGLER(RTStrICmp)
+# define RTStrIStr                                      RT_MANGLER(RTStrIStr)
+# define RTStrIsCaseFoldable                            RT_MANGLER(RTStrIsCaseFoldable)
+# define RTStrIsLowerCased                              RT_MANGLER(RTStrIsLowerCased)
+# define RTStrIsUpperCased                              RT_MANGLER(RTStrIsUpperCased)
+# define RTStrIsValidEncoding                           RT_MANGLER(RTStrIsValidEncoding)
+# define RTStrmClearError                               RT_MANGLER(RTStrmClearError)
+# define RTStrmClose                                    RT_MANGLER(RTStrmClose)
+# define RTStrmError                                    RT_MANGLER(RTStrmError)
+# define RTStrmFlush                                    RT_MANGLER(RTStrmFlush)
+# define RTStrmGetCh                                    RT_MANGLER(RTStrmGetCh)
+# define RTStrmInputGetEchoChars                        RT_MANGLER(RTStrmInputGetEchoChars)
+# define RTStrmGetLine                                  RT_MANGLER(RTStrmGetLine)
+# define RTStrmOpen                                     RT_MANGLER(RTStrmOpen)
+# define RTStrmOpenF                                    RT_MANGLER(RTStrmOpenF)
+# define RTStrmOpenFV                                   RT_MANGLER(RTStrmOpenFV)
+# define RTStrmPrintf                                   RT_MANGLER(RTStrmPrintf)
+# define RTStrmPrintfV                                  RT_MANGLER(RTStrmPrintfV)
+# define RTStrmDumpPrintfV                              RT_MANGLER(RTStrmDumpPrintfV)
+# define RTStrmPutCh                                    RT_MANGLER(RTStrmPutCh)
+# define RTStrmPutStr                                   RT_MANGLER(RTStrmPutStr)
+# define RTStrmReadEx                                   RT_MANGLER(RTStrmReadEx)
+# define RTStrmRewind                                   RT_MANGLER(RTStrmRewind)
+# define RTStrmInputSetEchoChars                        RT_MANGLER(RTStrmInputSetEchoChars)
+# define RTStrmSetMode                                  RT_MANGLER(RTStrmSetMode)
+# define RTStrmWriteEx                                  RT_MANGLER(RTStrmWriteEx)
+# define RTStrNCmp                                      RT_MANGLER(RTStrNCmp)
+# define RTStrNICmp                                     RT_MANGLER(RTStrNICmp)
+# define RTStrNLen                                      RT_MANGLER(RTStrNLen)
+# define RTStrNLenEx                                    RT_MANGLER(RTStrNLenEx)
+# define RTStrPrevCp                                    RT_MANGLER(RTStrPrevCp)
+# define RTStrPrintf                                    RT_MANGLER(RTStrPrintf)
+# define RTStrPrintfEx                                  RT_MANGLER(RTStrPrintfEx)
+# define RTStrPrintfExV                                 RT_MANGLER(RTStrPrintfExV)
+# define RTStrPrintfV                                   RT_MANGLER(RTStrPrintfV)
+# define RTStrPrintHexBytes                             RT_MANGLER(RTStrPrintHexBytes)
+# define RTStrPurgeEncoding                             RT_MANGLER(RTStrPurgeEncoding)
+# define RTStrPurgeComplementSet                        RT_MANGLER(RTStrPurgeComplementSet)
+# define RTStrPutCpInternal                             RT_MANGLER(RTStrPutCpInternal)
+# define RTStrReallocTag                                RT_MANGLER(RTStrReallocTag)
+# define RTStrSimplePatternMatch                        RT_MANGLER(RTStrSimplePatternMatch)
+# define RTStrSimplePatternMultiMatch                   RT_MANGLER(RTStrSimplePatternMultiMatch)
+# define RTStrSimplePatternNMatch                       RT_MANGLER(RTStrSimplePatternNMatch)
+# define RTStrSpaceDestroy                              RT_MANGLER(RTStrSpaceDestroy)
+# define RTStrSpaceEnumerate                            RT_MANGLER(RTStrSpaceEnumerate)
+# define RTStrSpaceGet                                  RT_MANGLER(RTStrSpaceGet)
+# define RTStrSpaceGetN                                 RT_MANGLER(RTStrSpaceGetN)
+# define RTStrSpaceInsert                               RT_MANGLER(RTStrSpaceInsert)
+# define RTStrSpaceRemove                               RT_MANGLER(RTStrSpaceRemove)
+# define RTStrStr                                       RT_MANGLER(RTStrStr)
+# define RTStrStrip                                     RT_MANGLER(RTStrStrip)
+# define RTStrStripL                                    RT_MANGLER(RTStrStripL)
+# define RTStrStripR                                    RT_MANGLER(RTStrStripR)
+# define RTStrToInt16                                   RT_MANGLER(RTStrToInt16)
+# define RTStrToInt16Ex                                 RT_MANGLER(RTStrToInt16Ex)
+# define RTStrToInt16Full                               RT_MANGLER(RTStrToInt16Full)
+# define RTStrToInt32                                   RT_MANGLER(RTStrToInt32)
+# define RTStrToInt32Ex                                 RT_MANGLER(RTStrToInt32Ex)
+# define RTStrToInt32Full                               RT_MANGLER(RTStrToInt32Full)
+# define RTStrToInt64                                   RT_MANGLER(RTStrToInt64)
+# define RTStrToInt64Ex                                 RT_MANGLER(RTStrToInt64Ex)
+# define RTStrToInt64Full                               RT_MANGLER(RTStrToInt64Full)
+# define RTStrToInt8                                    RT_MANGLER(RTStrToInt8)
+# define RTStrToInt8Ex                                  RT_MANGLER(RTStrToInt8Ex)
+# define RTStrToInt8Full                                RT_MANGLER(RTStrToInt8Full)
+# define RTStrToLatin1ExTag                             RT_MANGLER(RTStrToLatin1ExTag)
+# define RTStrToLatin1Tag                               RT_MANGLER(RTStrToLatin1Tag)
+# define RTStrToLower                                   RT_MANGLER(RTStrToLower)
+# define RTStrToUInt16                                  RT_MANGLER(RTStrToUInt16)
+# define RTStrToUInt16Ex                                RT_MANGLER(RTStrToUInt16Ex)
+# define RTStrToUInt16Full                              RT_MANGLER(RTStrToUInt16Full)
+# define RTStrToUInt32                                  RT_MANGLER(RTStrToUInt32)
+# define RTStrToUInt32Ex                                RT_MANGLER(RTStrToUInt32Ex)
+# define RTStrToUInt32Full                              RT_MANGLER(RTStrToUInt32Full)
+# define RTStrToUInt64                                  RT_MANGLER(RTStrToUInt64)
+# define RTStrToUInt64Ex                                RT_MANGLER(RTStrToUInt64Ex)
+# define RTStrToUInt64Full                              RT_MANGLER(RTStrToUInt64Full)
+# define RTStrToUInt8                                   RT_MANGLER(RTStrToUInt8)
+# define RTStrToUInt8Ex                                 RT_MANGLER(RTStrToUInt8Ex)
+# define RTStrToUInt8Full                               RT_MANGLER(RTStrToUInt8Full)
+# define RTStrToUni                                     RT_MANGLER(RTStrToUni)
+# define RTStrToUniEx                                   RT_MANGLER(RTStrToUniEx)
+# define RTStrToUpper                                   RT_MANGLER(RTStrToUpper)
+# define RTStrToUtf16ExTag                              RT_MANGLER(RTStrToUtf16ExTag)
+# define RTStrToUtf16Tag                                RT_MANGLER(RTStrToUtf16Tag)
+# define RTStrUniLen                                    RT_MANGLER(RTStrUniLen)
+# define RTStrUniLenEx                                  RT_MANGLER(RTStrUniLenEx)
+# define RTStrUtf8ToCurrentCPTag                        RT_MANGLER(RTStrUtf8ToCurrentCPTag)
+# define RTStrValidateEncoding                          RT_MANGLER(RTStrValidateEncoding)
+# define RTStrValidateEncodingEx                        RT_MANGLER(RTStrValidateEncodingEx)
+# define RTStrVersionCompare                            RT_MANGLER(RTStrVersionCompare)
+# define RTSymlinkCreate                                RT_MANGLER(RTSymlinkCreate)
+# define RTSymlinkDelete                                RT_MANGLER(RTSymlinkDelete)
+# define RTSymlinkExists                                RT_MANGLER(RTSymlinkExists)
+# define RTSymlinkIsDangling                            RT_MANGLER(RTSymlinkIsDangling)
+# define RTSymlinkRead                                  RT_MANGLER(RTSymlinkRead)
+# define RTSymlinkReadA                                 RT_MANGLER(RTSymlinkReadA)
+# define RTSystemIsInsideVM                             RT_MANGLER(RTSystemIsInsideVM)
+# define RTSystemQueryAvailableRam                      RT_MANGLER(RTSystemQueryAvailableRam)
+# define RTSystemQueryDmiString                         RT_MANGLER(RTSystemQueryDmiString)
+# define RTSystemQueryOSInfo                            RT_MANGLER(RTSystemQueryOSInfo)
+# define RTSystemQueryTotalRam                          RT_MANGLER(RTSystemQueryTotalRam)
+# define RTSystemShutdown                               RT_MANGLER(RTSystemShutdown)
+# define RTTarClose                                     RT_MANGLER(RTTarClose)
+# define RTTarFileClose                                 RT_MANGLER(RTTarFileClose)
+# define RTTarFileGetSize                               RT_MANGLER(RTTarFileGetSize)
+# define RTTarFileOpen                                  RT_MANGLER(RTTarFileOpen)
+# define RTTarFileReadAt                                RT_MANGLER(RTTarFileReadAt)
+# define RTTarFileSetSize                               RT_MANGLER(RTTarFileSetSize)
+# define RTTarFileWriteAt                               RT_MANGLER(RTTarFileWriteAt)
+# define RTTarOpen                                      RT_MANGLER(RTTarOpen)
+# define RTTcpClientCancelConnect                       RT_MANGLER(RTTcpClientCancelConnect)
+# define RTTcpClientClose                               RT_MANGLER(RTTcpClientClose)
+# define RTTcpClientCloseEx                             RT_MANGLER(RTTcpClientCloseEx)
+# define RTTcpClientConnect                             RT_MANGLER(RTTcpClientConnect)
+# define RTTcpClientConnectEx                           RT_MANGLER(RTTcpClientConnectEx)
+# define RTTcpFlush                                     RT_MANGLER(RTTcpFlush)
+# define RTTcpGetLocalAddress                           RT_MANGLER(RTTcpGetLocalAddress)
+# define RTTcpGetPeerAddress                            RT_MANGLER(RTTcpGetPeerAddress)
+# define RTTcpRead                                      RT_MANGLER(RTTcpRead)
+# define RTTcpReadNB                                    RT_MANGLER(RTTcpReadNB)
+# define RTTcpSelectOne                                 RT_MANGLER(RTTcpSelectOne)
+# define RTTcpSelectOneEx                               RT_MANGLER(RTTcpSelectOneEx)
+# define RTTcpServerCreate                              RT_MANGLER(RTTcpServerCreate)
+# define RTTcpServerCreateEx                            RT_MANGLER(RTTcpServerCreateEx)
+# define RTTcpServerDestroy                             RT_MANGLER(RTTcpServerDestroy)
+# define RTTcpServerDisconnectClient                    RT_MANGLER(RTTcpServerDisconnectClient)
+# define RTTcpServerDisconnectClient2                   RT_MANGLER(RTTcpServerDisconnectClient2)
+# define RTTcpServerListen                              RT_MANGLER(RTTcpServerListen)
+# define RTTcpServerListen2                             RT_MANGLER(RTTcpServerListen2)
+# define RTTcpServerShutdown                            RT_MANGLER(RTTcpServerShutdown)
+# define RTTcpSetSendCoalescing                         RT_MANGLER(RTTcpSetSendCoalescing)
+# define RTTcpSgWrite                                   RT_MANGLER(RTTcpSgWrite)
+# define RTTcpSgWriteL                                  RT_MANGLER(RTTcpSgWriteL)
+# define RTTcpSgWriteLNB                                RT_MANGLER(RTTcpSgWriteLNB)
+# define RTTcpSgWriteLV                                 RT_MANGLER(RTTcpSgWriteLV)
+# define RTTcpSgWriteLVNB                               RT_MANGLER(RTTcpSgWriteLVNB)
+# define RTTcpSgWriteNB                                 RT_MANGLER(RTTcpSgWriteNB)
+# define RTTcpWrite                                     RT_MANGLER(RTTcpWrite)
+# define RTTcpWriteNB                                   RT_MANGLER(RTTcpWriteNB)
+# define RTTermDeregisterCallback                       RT_MANGLER(RTTermDeregisterCallback)
+# define RTTermRegisterCallback                         RT_MANGLER(RTTermRegisterCallback)
+# define RTTermRunCallbacks                             RT_MANGLER(RTTermRunCallbacks)
+# define RTTestBanner                                   RT_MANGLER(RTTestBanner)
+# define RTTestChangeName                               RT_MANGLER(RTTestChangeName)
+# define RTTestCreate                                   RT_MANGLER(RTTestCreate)
+# define RTTestCreateEx                                 RT_MANGLER(RTTestCreateEx)
+# define RTTestDestroy                                  RT_MANGLER(RTTestDestroy)
+# define RTTestErrorCount                               RT_MANGLER(RTTestErrorCount)
+# define RTTestErrorInc                                 RT_MANGLER(RTTestErrorInc)
+# define RTTestFailed                                   RT_MANGLER(RTTestFailed)
+# define RTTestFailedV                                  RT_MANGLER(RTTestFailedV)
+# define RTTestFailureDetails                           RT_MANGLER(RTTestFailureDetails)
+# define RTTestFailureDetailsV                          RT_MANGLER(RTTestFailureDetailsV)
+# define RTTestGuardedAlloc                             RT_MANGLER(RTTestGuardedAlloc)
+# define RTTestGuardedAllocHead                         RT_MANGLER(RTTestGuardedAllocHead)
+# define RTTestGuardedAllocTail                         RT_MANGLER(RTTestGuardedAllocTail)
+# define RTTestGuardedFree                              RT_MANGLER(RTTestGuardedFree)
+# define RTTestIErrorCount                              RT_MANGLER(RTTestIErrorCount)
+# define RTTestIErrorInc                                RT_MANGLER(RTTestIErrorInc)
+# define RTTestIFailed                                  RT_MANGLER(RTTestIFailed)
+# define RTTestIFailedRc                                RT_MANGLER(RTTestIFailedRc)
+# define RTTestIFailedRcV                               RT_MANGLER(RTTestIFailedRcV)
+# define RTTestIFailedV                                 RT_MANGLER(RTTestIFailedV)
+# define RTTestIFailureDetails                          RT_MANGLER(RTTestIFailureDetails)
+# define RTTestIFailureDetailsV                         RT_MANGLER(RTTestIFailureDetailsV)
+# define RTTestInitAndCreate                            RT_MANGLER(RTTestInitAndCreate)
+# define RTTestInitExAndCreate                          RT_MANGLER(RTTestInitExAndCreate)
+# define RTTestIPassed                                  RT_MANGLER(RTTestIPassed)
+# define RTTestIPassedV                                 RT_MANGLER(RTTestIPassedV)
+# define RTTestIPrintf                                  RT_MANGLER(RTTestIPrintf)
+# define RTTestIPrintfV                                 RT_MANGLER(RTTestIPrintfV)
+# define RTTestISub                                     RT_MANGLER(RTTestISub)
+# define RTTestISubDone                                 RT_MANGLER(RTTestISubDone)
+# define RTTestISubF                                    RT_MANGLER(RTTestISubF)
+# define RTTestISubV                                    RT_MANGLER(RTTestISubV)
+# define RTTestIValue                                   RT_MANGLER(RTTestIValue)
+# define RTTestIValueF                                  RT_MANGLER(RTTestIValueF)
+# define RTTestIValueV                                  RT_MANGLER(RTTestIValueV)
+# define RTTestPassed                                   RT_MANGLER(RTTestPassed)
+# define RTTestPassedV                                  RT_MANGLER(RTTestPassedV)
+# define RTTestPrintf                                   RT_MANGLER(RTTestPrintf)
+# define RTTestPrintfNl                                 RT_MANGLER(RTTestPrintfNl)
+# define RTTestPrintfNlV                                RT_MANGLER(RTTestPrintfNlV)
+# define RTTestPrintfV                                  RT_MANGLER(RTTestPrintfV)
+# define RTTestSetDefault                               RT_MANGLER(RTTestSetDefault)
+# define RTTestSkipAndDestroy                           RT_MANGLER(RTTestSkipAndDestroy)
+# define RTTestSkipAndDestroyV                          RT_MANGLER(RTTestSkipAndDestroyV)
+# define RTTestSkipped                                  RT_MANGLER(RTTestSkipped)
+# define RTTestSkippedV                                 RT_MANGLER(RTTestSkippedV)
+# define RTTestSub                                      RT_MANGLER(RTTestSub)
+# define RTTestSubDone                                  RT_MANGLER(RTTestSubDone)
+# define RTTestSubErrorCount                            RT_MANGLER(RTTestSubErrorCount)
+# define RTTestSubF                                     RT_MANGLER(RTTestSubF)
+# define RTTestSubV                                     RT_MANGLER(RTTestSubV)
+# define RTTestSummaryAndDestroy                        RT_MANGLER(RTTestSummaryAndDestroy)
+# define RTTestValue                                    RT_MANGLER(RTTestValue)
+# define RTTestValueF                                   RT_MANGLER(RTTestValueF)
+# define RTTestValueV                                   RT_MANGLER(RTTestValueV)
+# define RTThreadAdopt                                  RT_MANGLER(RTThreadAdopt)
+# define RTThreadBlocking                               RT_MANGLER(RTThreadBlocking)
+# define RTThreadCreate                                 RT_MANGLER(RTThreadCreate)
+# define RTThreadCreateF                                RT_MANGLER(RTThreadCreateF)
+# define RTThreadCreateV                                RT_MANGLER(RTThreadCreateV)
+# define RTThreadCtxHookIsEnabled                       RT_MANGLER(RTThreadCtxHookIsEnabled)    /* r0drv */
+# define RTThreadCtxHookCreate                          RT_MANGLER(RTThreadCtxHookCreate)       /* r0drv */
+# define RTThreadCtxHookDestroy                         RT_MANGLER(RTThreadCtxHookDestroy)      /* r0drv */
+# define RTThreadCtxHookDisable                         RT_MANGLER(RTThreadCtxHookDisable)      /* r0drv */
+# define RTThreadCtxHookEnable                          RT_MANGLER(RTThreadCtxHookEnable)       /* r0drv */
+# define RTThreadFromNative                             RT_MANGLER(RTThreadFromNative)
+# define RTThreadGetAffinity                            RT_MANGLER(RTThreadGetAffinity)
+# define RTThreadGetExecutionTimeMilli                  RT_MANGLER(RTThreadGetExecutionTimeMilli)
+# define RTThreadGetName                                RT_MANGLER(RTThreadGetName)
+# define RTThreadGetNative                              RT_MANGLER(RTThreadGetNative)
+# define RTThreadGetNativeState                         RT_MANGLER(RTThreadGetNativeState)
+# define RTThreadGetReallySleeping                      RT_MANGLER(RTThreadGetReallySleeping)
+# define RTThreadGetState                               RT_MANGLER(RTThreadGetState)
+# define RTThreadGetType                                RT_MANGLER(RTThreadGetType)
+# define RTThreadIsInInterrupt                          RT_MANGLER(RTThreadIsInInterrupt)      /* r0drv */
+# define RTThreadIsInitialized                          RT_MANGLER(RTThreadIsInitialized)
+# define RTThreadIsMain                                 RT_MANGLER(RTThreadIsMain)
+# define RTThreadIsSelfAlive                            RT_MANGLER(RTThreadIsSelfAlive)
+# define RTThreadIsSelfKnown                            RT_MANGLER(RTThreadIsSelfKnown)
+# define RTThreadNativeSelf                             RT_MANGLER(RTThreadNativeSelf)
+# define RTThreadPoke                                   RT_MANGLER(RTThreadPoke) /* not-win not-os2 */
+# define RTThreadPreemptDisable                         RT_MANGLER(RTThreadPreemptDisable)     /* r0drv */
+# define RTThreadPreemptIsEnabled                       RT_MANGLER(RTThreadPreemptIsEnabled)   /* r0drv */
+# define RTThreadPreemptIsPending                       RT_MANGLER(RTThreadPreemptIsPending)   /* r0drv */
+# define RTThreadPreemptIsPendingTrusty                 RT_MANGLER(RTThreadPreemptIsPendingTrusty) /* r0drv */
+# define RTThreadPreemptIsPossible                      RT_MANGLER(RTThreadPreemptIsPossible)  /* r0drv */
+# define RTThreadPreemptRestore                         RT_MANGLER(RTThreadPreemptRestore)     /* r0drv */
+# define RTThreadSelf                                   RT_MANGLER(RTThreadSelf)
+# define RTThreadSelfAutoAdopt                          RT_MANGLER(RTThreadSelfAutoAdopt)
+# define RTThreadSelfName                               RT_MANGLER(RTThreadSelfName)
+# define RTThreadSetAffinity                            RT_MANGLER(RTThreadSetAffinity)
+# define RTThreadSetAffinityToCpu                       RT_MANGLER(RTThreadSetAffinityToCpu)
+# define RTThreadSetName                                RT_MANGLER(RTThreadSetName)
+# define RTThreadSetType                                RT_MANGLER(RTThreadSetType)
+# define RTThreadSleep                                  RT_MANGLER(RTThreadSleep)
+# define RTThreadSleepNoLog                             RT_MANGLER(RTThreadSleepNoLog)
+# define RTThreadStateName                              RT_MANGLER(RTThreadStateName)
+# define RTThreadUnblocked                              RT_MANGLER(RTThreadUnblocked)
+# define RTThreadUserReset                              RT_MANGLER(RTThreadUserReset)
+# define RTThreadUserSignal                             RT_MANGLER(RTThreadUserSignal)
+# define RTThreadUserWait                               RT_MANGLER(RTThreadUserWait)
+# define RTThreadUserWaitNoResume                       RT_MANGLER(RTThreadUserWaitNoResume)
+# define RTThreadWait                                   RT_MANGLER(RTThreadWait)
+# define RTThreadWaitNoResume                           RT_MANGLER(RTThreadWaitNoResume)
+# define RTThreadYield                                  RT_MANGLER(RTThreadYield)
+# define RTTimeDbgBad                                   RT_MANGLER(RTTimeDbgBad)
+# define RTTimeDbgExpired                               RT_MANGLER(RTTimeDbgExpired)
+# define RTTimeDbgRaces                                 RT_MANGLER(RTTimeDbgRaces)
+# define RTTimeDbgSteps                                 RT_MANGLER(RTTimeDbgSteps)
+# define RTTimeExplode                                  RT_MANGLER(RTTimeExplode)
+# define RTTimeImplode                                  RT_MANGLER(RTTimeImplode)
+# define RTTimeIsLeapYear                               RT_MANGLER(RTTimeIsLeapYear)
+# define RTTimeLocalDeltaNano                           RT_MANGLER(RTTimeLocalDeltaNano)
+# define RTTimeLocalExplode                             RT_MANGLER(RTTimeLocalExplode)
+# define RTTimeLocalNow                                 RT_MANGLER(RTTimeLocalNow)
+# define RTTimeMilliTS                                  RT_MANGLER(RTTimeMilliTS)
+# define RTTimeNanoTS                                   RT_MANGLER(RTTimeNanoTS)
+# define RTTimeNanoTSLegacyAsync                                RT_MANGLER(RTTimeNanoTSLegacyAsync)
+# define RTTimeNanoTSLegacyAsync_EndProc                        RT_MANGLER(RTTimeNanoTSLegacyAsync_EndProc)
+# define RTTimeNanoTSLegacyAsyncUseApicId                       RT_MANGLER(RTTimeNanoTSLegacyAsyncUseApicId)
+# define RTTimeNanoTSLegacyAsyncUseApicId_EndProc               RT_MANGLER(RTTimeNanoTSLegacyAsyncUseApicId_EndProc)
+# define RTTimeNanoTSLegacyAsyncUseRdtscp                       RT_MANGLER(RTTimeNanoTSLegacyAsyncUseRdtscp)
+# define RTTimeNanoTSLegacyAsyncUseRdtscp_EndProc               RT_MANGLER(RTTimeNanoTSLegacyAsyncUseRdtscp_EndProc)
+# define RTTimeNanoTSLegacyAsyncUseIdtrLim                      RT_MANGLER(RTTimeNanoTSLegacyAsyncUseIdtrLim)
+# define RTTimeNanoTSLegacyAsyncUseIdtrLim_EndProc              RT_MANGLER(RTTimeNanoTSLegacyAsyncUseIdtrLim_EndProc)
+# define RTTimeNanoTSLegacySyncInvarNoDelta                     RT_MANGLER(RTTimeNanoTSLegacySyncInvarNoDelta)
+# define RTTimeNanoTSLegacySyncInvarNoDelta_EndProc             RT_MANGLER(RTTimeNanoTSLegacySyncInvarNoDelta_EndProc)
+# define RTTimeNanoTSLegacySyncInvarWithDelta                   RT_MANGLER(RTTimeNanoTSLegacySyncInvarWithDelta)
+# define RTTimeNanoTSLegacySyncInvarWithDelta_EndProc           RT_MANGLER(RTTimeNanoTSLegacySyncInvarWithDelta_EndProc)
+# define RTTimeNanoTSLegacySyncInvarWithDeltaUseApicId          RT_MANGLER(RTTimeNanoTSLegacySyncInvarWithDeltaUseApicId)
+# define RTTimeNanoTSLegacySyncInvarWithDeltaUseApicId_EndProc  RT_MANGLER(RTTimeNanoTSLegacySyncInvarWithDeltaUseApicId_EndProc)
+# define RTTimeNanoTSLegacySyncInvarWithDeltaUseRdtscp          RT_MANGLER(RTTimeNanoTSLegacySyncInvarWithDeltaUseRdtscp)
+# define RTTimeNanoTSLegacySyncInvarWithDeltaUseRdtscp_EndProc  RT_MANGLER(RTTimeNanoTSLegacySyncInvarWithDeltaUseRdtscp_EndProc)
+# define RTTimeNanoTSLegacySyncInvarWithDeltaUseIdtrLim         RT_MANGLER(RTTimeNanoTSLegacySyncInvarWithDeltaUseIdtrLim)
+# define RTTimeNanoTSLegacySyncInvarWithDeltaUseIdtrLim_EndProc RT_MANGLER(RTTimeNanoTSLegacySyncInvarWithDeltaUseIdtrLim_EndProc)
+# define RTTimeNanoTSLFenceAsync                                RT_MANGLER(RTTimeNanoTSLFenceAsync)
+# define RTTimeNanoTSLFenceAsync_EndProc                        RT_MANGLER(RTTimeNanoTSLFenceAsync_EndProc)
+# define RTTimeNanoTSLFenceAsyncUseApicId                       RT_MANGLER(RTTimeNanoTSLFenceAsyncUseApicId)
+# define RTTimeNanoTSLFenceAsyncUseApicId_EndProc               RT_MANGLER(RTTimeNanoTSLFenceAsyncUseApicId_EndProc)
+# define RTTimeNanoTSLFenceAsyncUseRdtscp                       RT_MANGLER(RTTimeNanoTSLFenceAsyncUseRdtscp)
+# define RTTimeNanoTSLFenceAsyncUseRdtscp_EndProc               RT_MANGLER(RTTimeNanoTSLFenceAsyncUseRdtscp_EndProc)
+# define RTTimeNanoTSLFenceAsyncUseIdtrLim                      RT_MANGLER(RTTimeNanoTSLFenceAsyncUseIdtrLim)
+# define RTTimeNanoTSLFenceAsyncUseIdtrLim_EndProc              RT_MANGLER(RTTimeNanoTSLFenceAsyncUseIdtrLim_EndProc)
+# define RTTimeNanoTSLFenceSyncInvarNoDelta                     RT_MANGLER(RTTimeNanoTSLFenceSyncInvarNoDelta)
+# define RTTimeNanoTSLFenceSyncInvarNoDelta_EndProc             RT_MANGLER(RTTimeNanoTSLFenceSyncInvarNoDelta_EndProc)
+# define RTTimeNanoTSLFenceSyncInvarWithDelta                   RT_MANGLER(RTTimeNanoTSLFenceSyncInvarWithDelta)
+# define RTTimeNanoTSLFenceSyncInvarWithDelta_EndProc           RT_MANGLER(RTTimeNanoTSLFenceSyncInvarWithDelta_EndProc)
+# define RTTimeNanoTSLFenceSyncInvarWithDeltaUseApicId          RT_MANGLER(RTTimeNanoTSLFenceSyncInvarWithDeltaUseApicId)
+# define RTTimeNanoTSLFenceSyncInvarWithDeltaUseApicId_EndProc  RT_MANGLER(RTTimeNanoTSLFenceSyncInvarWithDeltaUseApicId_EndProc)
+# define RTTimeNanoTSLFenceSyncInvarWithDeltaUseRdtscp          RT_MANGLER(RTTimeNanoTSLFenceSyncInvarWithDeltaUseRdtscp)
+# define RTTimeNanoTSLFenceSyncInvarWithDeltaUseRdtscp_EndProc  RT_MANGLER(RTTimeNanoTSLFenceSyncInvarWithDeltaUseRdtscp_EndProc)
+# define RTTimeNanoTSLFenceSyncInvarWithDeltaUseIdtrLim         RT_MANGLER(RTTimeNanoTSLFenceSyncInvarWithDeltaUseIdtrLim)
+# define RTTimeNanoTSLFenceSyncInvarWithDeltaUseIdtrLim_EndProc RT_MANGLER(RTTimeNanoTSLFenceSyncInvarWithDeltaUseIdtrLim_EndProc)
+# define RTTimeNormalize                                RT_MANGLER(RTTimeNormalize)
+# define RTTimeNow                                      RT_MANGLER(RTTimeNow)
+# define RTTimeProgramMicroTS                           RT_MANGLER(RTTimeProgramMicroTS)
+# define RTTimeProgramMilliTS                           RT_MANGLER(RTTimeProgramMilliTS)
+# define RTTimeProgramNanoTS                            RT_MANGLER(RTTimeProgramNanoTS)
+# define RTTimeProgramSecTS                             RT_MANGLER(RTTimeProgramSecTS)
+# define RTTimeProgramStartNanoTS                       RT_MANGLER(RTTimeProgramStartNanoTS)
+# define RTTimerCanDoHighResolution                     RT_MANGLER(RTTimerCanDoHighResolution)
+# define RTTimerChangeInterval                          RT_MANGLER(RTTimerChangeInterval)
+# define RTTimerCreate                                  RT_MANGLER(RTTimerCreate)
+# define RTTimerCreateEx                                RT_MANGLER(RTTimerCreateEx)
+# define RTTimerDestroy                                 RT_MANGLER(RTTimerDestroy)
+# define RTTimerGetSystemGranularity                    RT_MANGLER(RTTimerGetSystemGranularity) /* r0drv */
+# define RTTimerLRCreate                                RT_MANGLER(RTTimerLRCreate)
+# define RTTimerLRCreateEx                              RT_MANGLER(RTTimerLRCreateEx)
+# define RTTimerLRDestroy                               RT_MANGLER(RTTimerLRDestroy)
+# define RTTimerLRStart                                 RT_MANGLER(RTTimerLRStart)
+# define RTTimerLRStop                                  RT_MANGLER(RTTimerLRStop)
+# define RTTimerLRChangeInterval                        RT_MANGLER(RTTimerLRChangeInterval)
+# define RTTimerReleaseSystemGranularity                RT_MANGLER(RTTimerReleaseSystemGranularity) /* r0drv */
+# define RTTimerRequestSystemGranularity                RT_MANGLER(RTTimerRequestSystemGranularity) /* r0drv */
+# define RTTimerStart                                   RT_MANGLER(RTTimerStart)
+# define RTTimerStop                                    RT_MANGLER(RTTimerStop)
+# define RTTimeSet                                      RT_MANGLER(RTTimeSet)
+# define RTTimeSpecFromString                           RT_MANGLER(RTTimeSpecFromString)
+# define RTTimeSpecToString                             RT_MANGLER(RTTimeSpecToString)
+# define RTTimeSystemMilliTS                            RT_MANGLER(RTTimeSystemMilliTS)
+# define RTTimeSystemNanoTS                             RT_MANGLER(RTTimeSystemNanoTS)
+# define RTTimeFromString                               RT_MANGLER(RTTimeFromString)
+# define RTTimeToString                                 RT_MANGLER(RTTimeToString)
+# define RTTlsAlloc                                     RT_MANGLER(RTTlsAlloc)
+# define RTTlsAllocEx                                   RT_MANGLER(RTTlsAllocEx)
+# define RTTlsFree                                      RT_MANGLER(RTTlsFree)
+# define RTTlsGet                                       RT_MANGLER(RTTlsGet)
+# define RTTlsGetEx                                     RT_MANGLER(RTTlsGetEx)
+# define RTTlsSet                                       RT_MANGLER(RTTlsSet)
+# define RTTraceBufAddMsg                               RT_MANGLER(RTTraceBufAddMsg)
+# define RTTraceBufAddMsgEx                             RT_MANGLER(RTTraceBufAddMsgEx)
+# define RTTraceBufAddMsgF                              RT_MANGLER(RTTraceBufAddMsgF)
+# define RTTraceBufAddMsgV                              RT_MANGLER(RTTraceBufAddMsgV)
+# define RTTraceBufAddPos                               RT_MANGLER(RTTraceBufAddPos)
+# define RTTraceBufAddPosMsg                            RT_MANGLER(RTTraceBufAddPosMsg)
+# define RTTraceBufAddPosMsgEx                          RT_MANGLER(RTTraceBufAddPosMsgEx)
+# define RTTraceBufAddPosMsgF                           RT_MANGLER(RTTraceBufAddPosMsgF)
+# define RTTraceBufAddPosMsgV                           RT_MANGLER(RTTraceBufAddPosMsgV)
+# define RTTraceBufCarve                                RT_MANGLER(RTTraceBufCarve)
+# define RTTraceBufCreate                               RT_MANGLER(RTTraceBufCreate)
+# define RTTraceBufDisable                              RT_MANGLER(RTTraceBufDisable)
+# define RTTraceBufDumpToAssert                         RT_MANGLER(RTTraceBufDumpToAssert)
+# define RTTraceBufDumpToLog                            RT_MANGLER(RTTraceBufDumpToLog)
+# define RTTraceBufEnable                               RT_MANGLER(RTTraceBufEnable)
+# define RTTraceBufEnumEntries                          RT_MANGLER(RTTraceBufEnumEntries)
+# define RTTraceBufGetEntryCount                        RT_MANGLER(RTTraceBufGetEntryCount)
+# define RTTraceBufGetEntrySize                         RT_MANGLER(RTTraceBufGetEntrySize)
+# define RTTraceBufRelease                              RT_MANGLER(RTTraceBufRelease)
+# define RTTraceBufRetain                               RT_MANGLER(RTTraceBufRetain)
+# define RTTraceGetDefaultBuf                           RT_MANGLER(RTTraceGetDefaultBuf)
+# define RTTraceSetDefaultBuf                           RT_MANGLER(RTTraceSetDefaultBuf)
+# define RTUdpRead                                      RT_MANGLER(RTUdpRead)
+# define RTUdpServerCreate                              RT_MANGLER(RTUdpServerCreate)
+# define RTUdpServerCreateEx                            RT_MANGLER(RTUdpServerCreateEx)
+# define RTUdpServerDestroy                             RT_MANGLER(RTUdpServerDestroy)
+# define RTUdpServerListen                              RT_MANGLER(RTUdpServerListen)
+# define RTUdpServerShutdown                            RT_MANGLER(RTUdpServerShutdown)
+# define RTUdpWrite                                     RT_MANGLER(RTUdpWrite)
+# define RTUniFree                                      RT_MANGLER(RTUniFree)
+# define RTUriCreate                                    RT_MANGLER(RTUriCreate)
+# define RTUriFileCreate                                RT_MANGLER(RTUriFileCreate)
+# define RTUriFileCreateEx                              RT_MANGLER(RTUriFileCreateEx)
+# define RTUriFilePath                                  RT_MANGLER(RTUriFilePath)
+# define RTUriFilePathEx                                RT_MANGLER(RTUriFilePathEx)
+# define RTUriParse                                     RT_MANGLER(RTUriParse)
+# define RTUriParsedAuthority                           RT_MANGLER(RTUriParsedAuthority)
+# define RTUriParsedAuthorityHost                       RT_MANGLER(RTUriParsedAuthorityHost)
+# define RTUriParsedAuthorityPassword                   RT_MANGLER(RTUriParsedAuthorityPassword)
+# define RTUriParsedAuthorityPort                       RT_MANGLER(RTUriParsedAuthorityPort)
+# define RTUriParsedAuthorityUsername                   RT_MANGLER(RTUriParsedAuthorityUsername)
+# define RTUriParsedFragment                            RT_MANGLER(RTUriParsedFragment)
+# define RTUriParsedPath                                RT_MANGLER(RTUriParsedPath)
+# define RTUriParsedScheme                              RT_MANGLER(RTUriParsedScheme)
+# define RTUriParsedQuery                               RT_MANGLER(RTUriParsedQuery)
+# define RTUriIsSchemeMatch                             RT_MANGLER(RTUriIsSchemeMatch)
+# define RTUtf16AllocTag                                RT_MANGLER(RTUtf16AllocTag)
+# define RTUtf16ReallocTag                              RT_MANGLER(RTUtf16ReallocTag)
+# define RTUtf16CalcLatin1Len                           RT_MANGLER(RTUtf16CalcLatin1Len)
+# define RTUtf16CalcLatin1LenEx                         RT_MANGLER(RTUtf16CalcLatin1LenEx)
+# define RTUtf16CalcUtf8Len                             RT_MANGLER(RTUtf16CalcUtf8Len)
+# define RTUtf16CalcUtf8LenEx                           RT_MANGLER(RTUtf16CalcUtf8LenEx)
+# define RTUtf16Cmp                                     RT_MANGLER(RTUtf16Cmp)
+# define RTUtf16CmpAscii                                RT_MANGLER(RTUtf16CmpAscii)
+# define RTUtf16CmpUtf8                                 RT_MANGLER(RTUtf16CmpUtf8)
+# define RTUtf16DupExTag                                RT_MANGLER(RTUtf16DupExTag)
+# define RTUtf16DupTag                                  RT_MANGLER(RTUtf16DupTag)
+# define RTUtf16Free                                    RT_MANGLER(RTUtf16Free)
+# define RTUtf16GetCpExInternal                         RT_MANGLER(RTUtf16GetCpExInternal)
+# define RTUtf16GetCpInternal                           RT_MANGLER(RTUtf16GetCpInternal)
+# define RTUtf16ICmp                                    RT_MANGLER(RTUtf16ICmp)
+# define RTUtf16ICmpUtf8                                RT_MANGLER(RTUtf16ICmpUtf8)
+# define RTUtf16IsValidEncoding                         RT_MANGLER(RTUtf16IsValidEncoding)
+# define RTUtf16Len                                     RT_MANGLER(RTUtf16Len)
+# define RTUtf16LocaleICmp                              RT_MANGLER(RTUtf16LocaleICmp)
+# define RTUtf16PutCpInternal                           RT_MANGLER(RTUtf16PutCpInternal)
+# define RTUtf16ToLatin1ExTag                           RT_MANGLER(RTUtf16ToLatin1ExTag)
+# define RTUtf16ToLatin1Tag                             RT_MANGLER(RTUtf16ToLatin1Tag)
+# define RTUtf16ToLower                                 RT_MANGLER(RTUtf16ToLower)
+# define RTUtf16ToUpper                                 RT_MANGLER(RTUtf16ToUpper)
+# define RTUtf16PurgeComplementSet                      RT_MANGLER(RTUtf16PurgeComplementSet)
+# define RTUtf16ToUtf8ExTag                             RT_MANGLER(RTUtf16ToUtf8ExTag)
+# define RTUtf16ToUtf8Tag                               RT_MANGLER(RTUtf16ToUtf8Tag)
+# define RTUtf16ValidateEncoding                        RT_MANGLER(RTUtf16ValidateEncoding)
+# define RTUtf16ValidateEncodingEx                      RT_MANGLER(RTUtf16ValidateEncodingEx)
+# define RTUuidClear                                    RT_MANGLER(RTUuidClear)
+# define RTUuidCompare                                  RT_MANGLER(RTUuidCompare)
+# define RTUuidCompare2Strs                             RT_MANGLER(RTUuidCompare2Strs)
+# define RTUuidCompareStr                               RT_MANGLER(RTUuidCompareStr)
+# define RTUuidCreate                                   RT_MANGLER(RTUuidCreate)
+# define RTUuidFromStr                                  RT_MANGLER(RTUuidFromStr)
+# define RTUuidFromUtf16                                RT_MANGLER(RTUuidFromUtf16)
+# define RTUuidIsNull                                   RT_MANGLER(RTUuidIsNull)
+# define RTUuidToStr                                    RT_MANGLER(RTUuidToStr)
+# define RTUuidToUtf16                                  RT_MANGLER(RTUuidToUtf16)
+# define RTVfsChainElementDeregisterProvider            RT_MANGLER(RTVfsChainElementDeregisterProvider)
+# define RTVfsChainElementRegisterProvider              RT_MANGLER(RTVfsChainElementRegisterProvider)
+# define RTVfsChainIsSpec                               RT_MANGLER(RTVfsChainIsSpec)
+# define RTVfsChainOpenFile                             RT_MANGLER(RTVfsChainOpenFile)
+# define RTVfsChainOpenIoStream                         RT_MANGLER(RTVfsChainOpenIoStream)
+# define RTVfsChainSpecFree                             RT_MANGLER(RTVfsChainSpecFree)
+# define RTVfsChainSpecParse                            RT_MANGLER(RTVfsChainSpecParse)
+# define RTVfsDirRelease                                RT_MANGLER(RTVfsDirRelease)
+# define RTVfsDirRetain                                 RT_MANGLER(RTVfsDirRetain)
+# define RTVfsFileFlush                                 RT_MANGLER(RTVfsFileFlush)
+# define RTVfsFileFromRTFile                            RT_MANGLER(RTVfsFileFromRTFile)
+# define RTVfsFileGetSize                               RT_MANGLER(RTVfsFileGetSize)
+# define RTVfsFileOpen                                  RT_MANGLER(RTVfsFileOpen)
+# define RTVfsFileOpenNormal                            RT_MANGLER(RTVfsFileOpenNormal)
+# define RTVfsFilePoll                                  RT_MANGLER(RTVfsFilePoll)
+# define RTVfsFileQueryInfo                             RT_MANGLER(RTVfsFileQueryInfo)
+# define RTVfsFileRead                                  RT_MANGLER(RTVfsFileRead)
+# define RTVfsFileReadAt                                RT_MANGLER(RTVfsFileReadAt)
+# define RTVfsFileRelease                               RT_MANGLER(RTVfsFileRelease)
+# define RTVfsFileRetain                                RT_MANGLER(RTVfsFileRetain)
+# define RTVfsFileSeek                                  RT_MANGLER(RTVfsFileSeek)
+# define RTVfsFileTell                                  RT_MANGLER(RTVfsFileTell)
+# define RTVfsFileToIoStream                            RT_MANGLER(RTVfsFileToIoStream)
+# define RTVfsFileWrite                                 RT_MANGLER(RTVfsFileWrite)
+# define RTVfsFileWriteAt                               RT_MANGLER(RTVfsFileWriteAt)
+# define RTVfsFsStrmNext                                RT_MANGLER(RTVfsFsStrmNext)
+# define RTVfsFsStrmQueryInfo                           RT_MANGLER(RTVfsFsStrmQueryInfo)
+# define RTVfsFsStrmRelease                             RT_MANGLER(RTVfsFsStrmRelease)
+# define RTVfsFsStrmRetain                              RT_MANGLER(RTVfsFsStrmRetain)
+# define RTVfsIoStreamToPrivate                         RT_MANGLER(RTVfsIoStreamToPrivate)
+# define RTVfsIoStrmFlush                               RT_MANGLER(RTVfsIoStrmFlush)
+# define RTVfsIoStrmFromRTFile                          RT_MANGLER(RTVfsIoStrmFromRTFile)
+# define RTVfsIoStrmFromRTPipe                          RT_MANGLER(RTVfsIoStrmFromRTPipe)
+# define RTVfsIoStrmFromStdHandle                       RT_MANGLER(RTVfsIoStrmFromStdHandle)
+# define RTVfsIoStrmIsAtEnd                             RT_MANGLER(RTVfsIoStrmIsAtEnd)
+# define RTVfsIoStrmOpenNormal                          RT_MANGLER(RTVfsIoStrmOpenNormal)
+# define RTVfsIoStrmPoll                                RT_MANGLER(RTVfsIoStrmPoll)
+# define RTVfsIoStrmQueryInfo                           RT_MANGLER(RTVfsIoStrmQueryInfo)
+# define RTVfsIoStrmRead                                RT_MANGLER(RTVfsIoStrmRead)
+# define RTVfsIoStrmReadAt                              RT_MANGLER(RTVfsIoStrmReadAt)
+# define RTVfsIoStrmRelease                             RT_MANGLER(RTVfsIoStrmRelease)
+# define RTVfsIoStrmRetain                              RT_MANGLER(RTVfsIoStrmRetain)
+# define RTVfsIoStrmSgRead                              RT_MANGLER(RTVfsIoStrmSgRead)
+# define RTVfsIoStrmSgWrite                             RT_MANGLER(RTVfsIoStrmSgWrite)
+# define RTVfsIoStrmSkip                                RT_MANGLER(RTVfsIoStrmSkip)
+# define RTVfsIoStrmTell                                RT_MANGLER(RTVfsIoStrmTell)
+# define RTVfsIoStrmToFile                              RT_MANGLER(RTVfsIoStrmToFile)
+# define RTVfsIoStrmValidateUtf8Encoding                RT_MANGLER(RTVfsIoStrmValidateUtf8Encoding)
+# define RTVfsIoStrmWrite                               RT_MANGLER(RTVfsIoStrmWrite)
+# define RTVfsIoStrmWriteAt                             RT_MANGLER(RTVfsIoStrmWriteAt)
+# define RTVfsIoStrmZeroFill                            RT_MANGLER(RTVfsIoStrmZeroFill)
+# define RTVfsIsRangeInUse                              RT_MANGLER(RTVfsIsRangeInUse)
+# define RTVfsLockAcquireReadSlow                       RT_MANGLER(RTVfsLockAcquireReadSlow)
+# define RTVfsLockAcquireWriteSlow                      RT_MANGLER(RTVfsLockAcquireWriteSlow)
+# define RTVfsLockRelease                               RT_MANGLER(RTVfsLockRelease)
+# define RTVfsLockReleaseReadSlow                       RT_MANGLER(RTVfsLockReleaseReadSlow)
+# define RTVfsLockReleaseWriteSlow                      RT_MANGLER(RTVfsLockReleaseWriteSlow)
+# define RTVfsLockRetain                                RT_MANGLER(RTVfsLockRetain)
+# define RTVfsMemorizeIoStreamAsFile                    RT_MANGLER(RTVfsMemorizeIoStreamAsFile)
+# define RTVfsNew                                       RT_MANGLER(RTVfsNew)
+# define RTVfsNewBaseObj                                RT_MANGLER(RTVfsNewBaseObj)
+# define RTVfsNewFile                                   RT_MANGLER(RTVfsNewFile)
+# define RTVfsNewFsStream                               RT_MANGLER(RTVfsNewFsStream)
+# define RTVfsNewIoStream                               RT_MANGLER(RTVfsNewIoStream)
+# define RTVfsNewSymlink                                RT_MANGLER(RTVfsNewSymlink)
+# define RTVfsObjFromDir                                RT_MANGLER(RTVfsObjFromDir)
+# define RTVfsObjFromFile                               RT_MANGLER(RTVfsObjFromFile)
+# define RTVfsObjFromFsStream                           RT_MANGLER(RTVfsObjFromFsStream)
+# define RTVfsObjFromIoStream                           RT_MANGLER(RTVfsObjFromIoStream)
+# define RTVfsObjFromSymlink                            RT_MANGLER(RTVfsObjFromSymlink)
+# define RTVfsObjFromVfs                                RT_MANGLER(RTVfsObjFromVfs)
+# define RTVfsObjQueryInfo                              RT_MANGLER(RTVfsObjQueryInfo)
+# define RTVfsObjRelease                                RT_MANGLER(RTVfsObjRelease)
+# define RTVfsObjRetain                                 RT_MANGLER(RTVfsObjRetain)
+# define RTVfsObjToDir                                  RT_MANGLER(RTVfsObjToDir)
+# define RTVfsObjToFile                                 RT_MANGLER(RTVfsObjToFile)
+# define RTVfsObjToFsStream                             RT_MANGLER(RTVfsObjToFsStream)
+# define RTVfsObjToIoStream                             RT_MANGLER(RTVfsObjToIoStream)
+# define RTVfsObjToSymlink                              RT_MANGLER(RTVfsObjToSymlink)
+# define RTVfsObjToVfs                                  RT_MANGLER(RTVfsObjToVfs)
+# define RTVfsParsePath                                 RT_MANGLER(RTVfsParsePath)
+# define RTVfsParsePathA                                RT_MANGLER(RTVfsParsePathA)
+# define RTVfsParsePathAppend                           RT_MANGLER(RTVfsParsePathAppend)
+# define RTVfsParsePathFree                             RT_MANGLER(RTVfsParsePathFree)
+# define RTVfsRelease                                   RT_MANGLER(RTVfsRelease)
+# define RTVfsRetain                                    RT_MANGLER(RTVfsRetain)
+# define RTVfsSymlinkQueryInfo                          RT_MANGLER(RTVfsSymlinkQueryInfo)
+# define RTVfsSymlinkRead                               RT_MANGLER(RTVfsSymlinkRead)
+# define RTVfsSymlinkRelease                            RT_MANGLER(RTVfsSymlinkRelease)
+# define RTVfsSymlinkRetain                             RT_MANGLER(RTVfsSymlinkRetain)
+# define RTVfsSymlinkSetMode                            RT_MANGLER(RTVfsSymlinkSetMode)
+# define RTVfsSymlinkSetOwner                           RT_MANGLER(RTVfsSymlinkSetOwner)
+# define RTVfsSymlinkSetTimes                           RT_MANGLER(RTVfsSymlinkSetTimes)
+# define RTVfsUtilDummyPollOne                          RT_MANGLER(RTVfsUtilDummyPollOne)
+# define RTVfsUtilPumpIoStreams                         RT_MANGLER(RTVfsUtilPumpIoStreams)
+# define RTX509PrepareOpenSSL                           RT_MANGLER(RTX509PrepareOpenSSL)
+# define RTX509CertificateVerify                        RT_MANGLER(RTX509CertificateVerify)
+# define RTX509GetErrorDescription                      RT_MANGLER(RTX509GetErrorDescription)
+# define RTZipBlockCompress                             RT_MANGLER(RTZipBlockCompress)
+# define RTZipBlockDecompress                           RT_MANGLER(RTZipBlockDecompress)
+# define RTZipCompCreate                                RT_MANGLER(RTZipCompCreate)
+# define RTZipCompDestroy                               RT_MANGLER(RTZipCompDestroy)
+# define RTZipCompFinish                                RT_MANGLER(RTZipCompFinish)
+# define RTZipCompress                                  RT_MANGLER(RTZipCompress)
+# define RTZipDecompCreate                              RT_MANGLER(RTZipDecompCreate)
+# define RTZipDecompDestroy                             RT_MANGLER(RTZipDecompDestroy)
+# define RTZipDecompress                                RT_MANGLER(RTZipDecompress)
+# define RTZipGzipCompressIoStream                      RT_MANGLER(RTZipGzipCompressIoStream)
+# define RTZipGzipDecompressIoStream                    RT_MANGLER(RTZipGzipDecompressIoStream)
+# define RTZipPkzipFsStreamFromIoStream                 RT_MANGLER(RTZipPkzipFsStreamFromIoStream)
+# define RTZipPkzipMemDecompress                        RT_MANGLER(RTZipPkzipMemDecompress)
+# define RTZipTarCmd                                    RT_MANGLER(RTZipTarCmd)
+# define RTZipUnzipCmd                                  RT_MANGLER(RTZipUnzipCmd)
+# define RTZipTarFsStreamFromIoStream                   RT_MANGLER(RTZipTarFsStreamFromIoStream)
+# define RTZipXarFsStreamFromIoStream                   RT_MANGLER(RTZipXarFsStreamFromIoStream)
+
+/* sort/merge into the above later: */
+# define RTAsn1ContentAllocZ                            RT_MANGLER(RTAsn1ContentAllocZ)
+# define RTAsn1ContentDup                               RT_MANGLER(RTAsn1ContentDup)
+# define RTAsn1ContentFree                              RT_MANGLER(RTAsn1ContentFree)
+# define RTAsn1ContentReallocZ                          RT_MANGLER(RTAsn1ContentReallocZ)
+# define RTAsn1ContextTagN_Clone                        RT_MANGLER(RTAsn1ContextTagN_Clone)
+# define RTAsn1ContextTagN_Init                         RT_MANGLER(RTAsn1ContextTagN_Init)
+# define RTAsn1Dummy_InitEx                             RT_MANGLER(RTAsn1Dummy_InitEx)
+# define RTAsn1MemAllocZ                                RT_MANGLER(RTAsn1MemAllocZ)
+# define RTAsn1MemDup                                   RT_MANGLER(RTAsn1MemDup)
+# define RTAsn1MemFree                                  RT_MANGLER(RTAsn1MemFree)
+# define RTAsn1MemGrowArray                             RT_MANGLER(RTAsn1MemGrowArray)
+# define RTAsn1MemInitAllocation                        RT_MANGLER(RTAsn1MemInitAllocation)
+# define RTAsn1SeqOfCore_Clone                          RT_MANGLER(RTAsn1SeqOfCore_Clone)
+# define RTAsn1SeqOfCore_Init                           RT_MANGLER(RTAsn1SeqOfCore_Init)
+# define RTAsn1SequenceCore_Clone                       RT_MANGLER(RTAsn1SequenceCore_Clone)
+# define RTAsn1SequenceCore_Init                        RT_MANGLER(RTAsn1SequenceCore_Init)
+# define RTAsn1SetCore_Clone                            RT_MANGLER(RTAsn1SetCore_Clone)
+# define RTAsn1SetCore_Init                             RT_MANGLER(RTAsn1SetCore_Init)
+# define RTAsn1SetOfCore_Clone                          RT_MANGLER(RTAsn1SetOfCore_Clone)
+# define RTAsn1SetOfCore_Init                           RT_MANGLER(RTAsn1SetOfCore_Init)
+# define RTAsn1VtCheckSanity                            RT_MANGLER(RTAsn1VtCheckSanity)
+# define RTAsn1VtClone                                  RT_MANGLER(RTAsn1VtClone)
+# define RTAsn1VtCompare                                RT_MANGLER(RTAsn1VtCompare)
+# define RTAsn1VtDeepEnum                               RT_MANGLER(RTAsn1VtDeepEnum)
+# define RTAsn1VtDelete                                 RT_MANGLER(RTAsn1VtDelete)
+# define RTAsn1CursorCheckEnd                           RT_MANGLER(RTAsn1CursorCheckEnd)
+# define RTAsn1CursorGetBitString                       RT_MANGLER(RTAsn1CursorGetBitString)
+# define RTAsn1CursorGetBitStringEx                     RT_MANGLER(RTAsn1CursorGetBitStringEx)
+# define RTAsn1CursorGetBmpString                       RT_MANGLER(RTAsn1CursorGetBmpString)
+# define RTAsn1CursorGetBoolean                         RT_MANGLER(RTAsn1CursorGetBoolean)
+# define RTAsn1CursorGetContextTagNCursor               RT_MANGLER(RTAsn1CursorGetContextTagNCursor)
+# define RTAsn1CursorGetCore                            RT_MANGLER(RTAsn1CursorGetCore)
+# define RTAsn1CursorGetDynType                         RT_MANGLER(RTAsn1CursorGetDynType)
+# define RTAsn1CursorGetIa5String                       RT_MANGLER(RTAsn1CursorGetIa5String)
+# define RTAsn1CursorGetInteger                         RT_MANGLER(RTAsn1CursorGetInteger)
+# define RTAsn1CursorGetNull                            RT_MANGLER(RTAsn1CursorGetNull)
+# define RTAsn1CursorGetObjId                           RT_MANGLER(RTAsn1CursorGetObjId)
+# define RTAsn1CursorGetOctetString                     RT_MANGLER(RTAsn1CursorGetOctetString)
+# define RTAsn1CursorGetSequenceCursor                  RT_MANGLER(RTAsn1CursorGetSequenceCursor)
+# define RTAsn1CursorGetSetCursor                       RT_MANGLER(RTAsn1CursorGetSetCursor)
+# define RTAsn1CursorGetString                          RT_MANGLER(RTAsn1CursorGetString)
+# define RTAsn1CursorGetTime                            RT_MANGLER(RTAsn1CursorGetTime)
+# define RTAsn1CursorGetUtf8String                      RT_MANGLER(RTAsn1CursorGetUtf8String)
+# define RTAsn1CursorInitAllocation                     RT_MANGLER(RTAsn1CursorInitAllocation)
+# define RTAsn1CursorInitPrimary                        RT_MANGLER(RTAsn1CursorInitPrimary)
+# define RTAsn1CursorInitSubFromCore                    RT_MANGLER(RTAsn1CursorInitSubFromCore)
+# define RTAsn1CursorIsNextEx                           RT_MANGLER(RTAsn1CursorIsNextEx)
+# define RTAsn1CursorMatchTagClassFlagsEx               RT_MANGLER(RTAsn1CursorMatchTagClassFlagsEx)
+# define RTAsn1CursorPeek                               RT_MANGLER(RTAsn1CursorPeek)
+# define RTAsn1CursorReadHdr                            RT_MANGLER(RTAsn1CursorReadHdr)
+# define RTAsn1CursorSetInfo                            RT_MANGLER(RTAsn1CursorSetInfo)
+# define RTAsn1CursorSetInfoV                           RT_MANGLER(RTAsn1CursorSetInfoV)
+# define RTAsn1Dump                                     RT_MANGLER(RTAsn1Dump)
+# define RTAsn1EncodePrepare                            RT_MANGLER(RTAsn1EncodePrepare)
+# define RTAsn1EncodeRecalcHdrSize                      RT_MANGLER(RTAsn1EncodeRecalcHdrSize)
+# define RTAsn1EncodeWrite                              RT_MANGLER(RTAsn1EncodeWrite)
+# define RTAsnEncodeWriteHeader                         RT_MANGLER(RTAsnEncodeWriteHeader)
+# define RTAsn1BitString_CheckSanity                    RT_MANGLER(RTAsn1BitString_CheckSanity)
+# define RTAsn1BitString_Clone                          RT_MANGLER(RTAsn1BitString_Clone)
+# define RTAsn1BitString_Compare                        RT_MANGLER(RTAsn1BitString_Compare)
+# define RTAsn1BitString_Delete                         RT_MANGLER(RTAsn1BitString_Delete)
+# define RTAsn1BitString_Enum                           RT_MANGLER(RTAsn1BitString_Enum)
+# define RTAsn1BitString_GetAsUInt64                    RT_MANGLER(RTAsn1BitString_GetAsUInt64)
+# define RTAsn1BitString_Init                           RT_MANGLER(RTAsn1BitString_Init)
+# define RTAsn1SeqOfBitStrings_CheckSanity              RT_MANGLER(RTAsn1SeqOfBitStrings_CheckSanity)
+# define RTAsn1SeqOfBitStrings_Clone                    RT_MANGLER(RTAsn1SeqOfBitStrings_Clone)
+# define RTAsn1SeqOfBitStrings_Compare                  RT_MANGLER(RTAsn1SeqOfBitStrings_Compare)
+# define RTAsn1SeqOfBitStrings_Delete                   RT_MANGLER(RTAsn1SeqOfBitStrings_Delete)
+# define RTAsn1SeqOfBitStrings_Enum                     RT_MANGLER(RTAsn1SeqOfBitStrings_Enum)
+# define RTAsn1SeqOfBitStrings_Init                     RT_MANGLER(RTAsn1SeqOfBitStrings_Init)
+# define RTAsn1SetOfBitStrings_CheckSanity              RT_MANGLER(RTAsn1SetOfBitStrings_CheckSanity)
+# define RTAsn1SetOfBitStrings_Clone                    RT_MANGLER(RTAsn1SetOfBitStrings_Clone)
+# define RTAsn1SetOfBitStrings_Compare                  RT_MANGLER(RTAsn1SetOfBitStrings_Compare)
+# define RTAsn1SetOfBitStrings_Delete                   RT_MANGLER(RTAsn1SetOfBitStrings_Delete)
+# define RTAsn1SetOfBitStrings_Enum                     RT_MANGLER(RTAsn1SetOfBitStrings_Enum)
+# define RTAsn1SetOfBitStrings_Init                     RT_MANGLER(RTAsn1SetOfBitStrings_Init)
+# define RTAsn1BitString_DecodeAsn1                     RT_MANGLER(RTAsn1BitString_DecodeAsn1)
+# define RTAsn1BitString_DecodeAsn1Ex                   RT_MANGLER(RTAsn1BitString_DecodeAsn1Ex)
+# define RTAsn1SeqOfBitStrings_DecodeAsn1               RT_MANGLER(RTAsn1SeqOfBitStrings_DecodeAsn1)
+# define RTAsn1SetOfBitStrings_DecodeAsn1               RT_MANGLER(RTAsn1SetOfBitStrings_DecodeAsn1)
+# define RTAsn1Boolean_CheckSanity                      RT_MANGLER(RTAsn1Boolean_CheckSanity)
+# define RTAsn1Boolean_Clone                            RT_MANGLER(RTAsn1Boolean_Clone)
+# define RTAsn1Boolean_Compare                          RT_MANGLER(RTAsn1Boolean_Compare)
+# define RTAsn1Boolean_Delete                           RT_MANGLER(RTAsn1Boolean_Delete)
+# define RTAsn1Boolean_Enum                             RT_MANGLER(RTAsn1Boolean_Enum)
+# define RTAsn1Boolean_Init                             RT_MANGLER(RTAsn1Boolean_Init)
+# define RTAsn1Boolean_InitDefault                      RT_MANGLER(RTAsn1Boolean_InitDefault)
+# define RTAsn1Boolean_Set                              RT_MANGLER(RTAsn1Boolean_Set)
+# define RTAsn1SeqOfBooleans_CheckSanity                RT_MANGLER(RTAsn1SeqOfBooleans_CheckSanity)
+# define RTAsn1SeqOfBooleans_Clone                      RT_MANGLER(RTAsn1SeqOfBooleans_Clone)
+# define RTAsn1SeqOfBooleans_Compare                    RT_MANGLER(RTAsn1SeqOfBooleans_Compare)
+# define RTAsn1SeqOfBooleans_Delete                     RT_MANGLER(RTAsn1SeqOfBooleans_Delete)
+# define RTAsn1SeqOfBooleans_Enum                       RT_MANGLER(RTAsn1SeqOfBooleans_Enum)
+# define RTAsn1SeqOfBooleans_Init                       RT_MANGLER(RTAsn1SeqOfBooleans_Init)
+# define RTAsn1SetOfBooleans_CheckSanity                RT_MANGLER(RTAsn1SetOfBooleans_CheckSanity)
+# define RTAsn1SetOfBooleans_Clone                      RT_MANGLER(RTAsn1SetOfBooleans_Clone)
+# define RTAsn1SetOfBooleans_Compare                    RT_MANGLER(RTAsn1SetOfBooleans_Compare)
+# define RTAsn1SetOfBooleans_Delete                     RT_MANGLER(RTAsn1SetOfBooleans_Delete)
+# define RTAsn1SetOfBooleans_Enum                       RT_MANGLER(RTAsn1SetOfBooleans_Enum)
+# define RTAsn1SetOfBooleans_Init                       RT_MANGLER(RTAsn1SetOfBooleans_Init)
+# define RTAsn1Boolean_DecodeAsn1                       RT_MANGLER(RTAsn1Boolean_DecodeAsn1)
+# define RTAsn1SeqOfBooleans_DecodeAsn1                 RT_MANGLER(RTAsn1SeqOfBooleans_DecodeAsn1)
+# define RTAsn1SetOfBooleans_DecodeAsn1                 RT_MANGLER(RTAsn1SetOfBooleans_DecodeAsn1)
+# define RTAsn1Core_ChangeTag                           RT_MANGLER(RTAsn1Core_ChangeTag)
+# define RTAsn1Core_CheckSanity                         RT_MANGLER(RTAsn1Core_CheckSanity)
+# define RTAsn1Core_Clone                               RT_MANGLER(RTAsn1Core_Clone)
+# define RTAsn1Core_CloneContent                        RT_MANGLER(RTAsn1Core_CloneContent)
+# define RTAsn1Core_CloneNoContent                      RT_MANGLER(RTAsn1Core_CloneNoContent)
+# define RTAsn1Core_Compare                             RT_MANGLER(RTAsn1Core_Compare)
+# define RTAsn1Core_CompareEx                           RT_MANGLER(RTAsn1Core_CompareEx)
+# define RTAsn1Core_Delete                              RT_MANGLER(RTAsn1Core_Delete)
+# define RTAsn1Core_Enum                                RT_MANGLER(RTAsn1Core_Enum)
+# define RTAsn1Core_Init                                RT_MANGLER(RTAsn1Core_Init)
+# define RTAsn1Core_InitDefault                         RT_MANGLER(RTAsn1Core_InitDefault)
+# define RTAsn1Core_InitEx                              RT_MANGLER(RTAsn1Core_InitEx)
+# define RTAsn1Core_ResetImplict                        RT_MANGLER(RTAsn1Core_ResetImplict)
+# define RTAsn1Core_SetTagAndFlags                      RT_MANGLER(RTAsn1Core_SetTagAndFlags)
+# define RTAsn1SeqOfCores_CheckSanity                   RT_MANGLER(RTAsn1SeqOfCores_CheckSanity)
+# define RTAsn1SeqOfCores_Clone                         RT_MANGLER(RTAsn1SeqOfCores_Clone)
+# define RTAsn1SeqOfCores_Compare                       RT_MANGLER(RTAsn1SeqOfCores_Compare)
+# define RTAsn1SeqOfCores_Delete                        RT_MANGLER(RTAsn1SeqOfCores_Delete)
+# define RTAsn1SeqOfCores_Enum                          RT_MANGLER(RTAsn1SeqOfCores_Enum)
+# define RTAsn1SeqOfCores_Init                          RT_MANGLER(RTAsn1SeqOfCores_Init)
+# define RTAsn1SetOfCores_CheckSanity                   RT_MANGLER(RTAsn1SetOfCores_CheckSanity)
+# define RTAsn1SetOfCores_Clone                         RT_MANGLER(RTAsn1SetOfCores_Clone)
+# define RTAsn1SetOfCores_Compare                       RT_MANGLER(RTAsn1SetOfCores_Compare)
+# define RTAsn1SetOfCores_Delete                        RT_MANGLER(RTAsn1SetOfCores_Delete)
+# define RTAsn1SetOfCores_Enum                          RT_MANGLER(RTAsn1SetOfCores_Enum)
+# define RTAsn1SetOfCores_Init                          RT_MANGLER(RTAsn1SetOfCores_Init)
+# define RTAsn1Core_DecodeAsn1                          RT_MANGLER(RTAsn1Core_DecodeAsn1)
+# define RTAsn1SeqOfCores_DecodeAsn1                    RT_MANGLER(RTAsn1SeqOfCores_DecodeAsn1)
+# define RTAsn1SetOfCores_DecodeAsn1                    RT_MANGLER(RTAsn1SetOfCores_DecodeAsn1)
+# define RTAsn1DynType_CheckSanity                      RT_MANGLER(RTAsn1DynType_CheckSanity)
+# define RTAsn1DynType_Clone                            RT_MANGLER(RTAsn1DynType_Clone)
+# define RTAsn1DynType_Compare                          RT_MANGLER(RTAsn1DynType_Compare)
+# define RTAsn1DynType_Delete                           RT_MANGLER(RTAsn1DynType_Delete)
+# define RTAsn1DynType_Enum                             RT_MANGLER(RTAsn1DynType_Enum)
+# define RTAsn1DynType_Init                             RT_MANGLER(RTAsn1DynType_Init)
+# define RTAsn1DynType_DecodeAsn1                       RT_MANGLER(RTAsn1DynType_DecodeAsn1)
+# define RTAsn1Integer_CheckSanity                      RT_MANGLER(RTAsn1Integer_CheckSanity)
+# define RTAsn1Integer_Clone                            RT_MANGLER(RTAsn1Integer_Clone)
+# define RTAsn1Integer_Compare                          RT_MANGLER(RTAsn1Integer_Compare)
+# define RTAsn1Integer_Delete                           RT_MANGLER(RTAsn1Integer_Delete)
+# define RTAsn1Integer_Enum                             RT_MANGLER(RTAsn1Integer_Enum)
+# define RTAsn1Integer_FromBigNum                       RT_MANGLER(RTAsn1Integer_FromBigNum)
+# define RTAsn1Integer_Init                             RT_MANGLER(RTAsn1Integer_Init)
+# define RTAsn1Integer_InitDefault                      RT_MANGLER(RTAsn1Integer_InitDefault)
+# define RTAsn1Integer_InitU64                          RT_MANGLER(RTAsn1Integer_InitU64)
+# define RTAsn1Integer_ToBigNum                         RT_MANGLER(RTAsn1Integer_ToBigNum)
+# define RTAsn1Integer_UnsignedCompare                  RT_MANGLER(RTAsn1Integer_UnsignedCompare)
+# define RTAsn1Integer_UnsignedCompareWithU32           RT_MANGLER(RTAsn1Integer_UnsignedCompareWithU32)
+# define RTAsn1Integer_UnsignedCompareWithU64           RT_MANGLER(RTAsn1Integer_UnsignedCompareWithU64)
+# define RTAsn1Integer_UnsignedLastBit                  RT_MANGLER(RTAsn1Integer_UnsignedLastBit)
+# define RTAsn1SeqOfIntegers_CheckSanity                RT_MANGLER(RTAsn1SeqOfIntegers_CheckSanity)
+# define RTAsn1SeqOfIntegers_Clone                      RT_MANGLER(RTAsn1SeqOfIntegers_Clone)
+# define RTAsn1SeqOfIntegers_Compare                    RT_MANGLER(RTAsn1SeqOfIntegers_Compare)
+# define RTAsn1SeqOfIntegers_Delete                     RT_MANGLER(RTAsn1SeqOfIntegers_Delete)
+# define RTAsn1SeqOfIntegers_Enum                       RT_MANGLER(RTAsn1SeqOfIntegers_Enum)
+# define RTAsn1SeqOfIntegers_Init                       RT_MANGLER(RTAsn1SeqOfIntegers_Init)
+# define RTAsn1SetOfIntegers_CheckSanity                RT_MANGLER(RTAsn1SetOfIntegers_CheckSanity)
+# define RTAsn1SetOfIntegers_Clone                      RT_MANGLER(RTAsn1SetOfIntegers_Clone)
+# define RTAsn1SetOfIntegers_Compare                    RT_MANGLER(RTAsn1SetOfIntegers_Compare)
+# define RTAsn1SetOfIntegers_Delete                     RT_MANGLER(RTAsn1SetOfIntegers_Delete)
+# define RTAsn1SetOfIntegers_Enum                       RT_MANGLER(RTAsn1SetOfIntegers_Enum)
+# define RTAsn1SetOfIntegers_Init                       RT_MANGLER(RTAsn1SetOfIntegers_Init)
+# define RTAsn1Integer_DecodeAsn1                       RT_MANGLER(RTAsn1Integer_DecodeAsn1)
+# define RTAsn1SeqOfIntegers_DecodeAsn1                 RT_MANGLER(RTAsn1SeqOfIntegers_DecodeAsn1)
+# define RTAsn1SetOfIntegers_DecodeAsn1                 RT_MANGLER(RTAsn1SetOfIntegers_DecodeAsn1)
+# define RTAsn1Null_CheckSanity                         RT_MANGLER(RTAsn1Null_CheckSanity)
+# define RTAsn1Null_Clone                               RT_MANGLER(RTAsn1Null_Clone)
+# define RTAsn1Null_Compare                             RT_MANGLER(RTAsn1Null_Compare)
+# define RTAsn1Null_Delete                              RT_MANGLER(RTAsn1Null_Delete)
+# define RTAsn1Null_Enum                                RT_MANGLER(RTAsn1Null_Enum)
+# define RTAsn1Null_Init                                RT_MANGLER(RTAsn1Null_Init)
+# define RTAsn1Null_DecodeAsn1                          RT_MANGLER(RTAsn1Null_DecodeAsn1)
+# define RTAsn1ObjIdCountComponents                     RT_MANGLER(RTAsn1ObjIdCountComponents)
+# define RTAsn1ObjIdGetComponentsAsUInt32               RT_MANGLER(RTAsn1ObjIdGetComponentsAsUInt32)
+# define RTAsn1ObjIdGetLastComponentsAsUInt32           RT_MANGLER(RTAsn1ObjIdGetLastComponentsAsUInt32)
+# define RTAsn1ObjId_CheckSanity                        RT_MANGLER(RTAsn1ObjId_CheckSanity)
+# define RTAsn1ObjId_Clone                              RT_MANGLER(RTAsn1ObjId_Clone)
+# define RTAsn1ObjId_Compare                            RT_MANGLER(RTAsn1ObjId_Compare)
+# define RTAsn1ObjId_CompareWithString                  RT_MANGLER(RTAsn1ObjId_CompareWithString)
+# define RTAsn1ObjId_Delete                             RT_MANGLER(RTAsn1ObjId_Delete)
+# define RTAsn1ObjId_Enum                               RT_MANGLER(RTAsn1ObjId_Enum)
+# define RTAsn1ObjId_Init                               RT_MANGLER(RTAsn1ObjId_Init)
+# define RTAsn1ObjId_InitFromString                     RT_MANGLER(RTAsn1ObjId_InitFromString)
+# define RTAsn1ObjId_StartsWith                         RT_MANGLER(RTAsn1ObjId_StartsWith)
+# define RTAsn1SeqOfObjIds_CheckSanity                  RT_MANGLER(RTAsn1SeqOfObjIds_CheckSanity)
+# define RTAsn1SeqOfObjIds_Clone                        RT_MANGLER(RTAsn1SeqOfObjIds_Clone)
+# define RTAsn1SeqOfObjIds_Compare                      RT_MANGLER(RTAsn1SeqOfObjIds_Compare)
+# define RTAsn1SeqOfObjIds_Delete                       RT_MANGLER(RTAsn1SeqOfObjIds_Delete)
+# define RTAsn1SeqOfObjIds_Enum                         RT_MANGLER(RTAsn1SeqOfObjIds_Enum)
+# define RTAsn1SeqOfObjIds_Init                         RT_MANGLER(RTAsn1SeqOfObjIds_Init)
+# define RTAsn1SetOfObjIds_CheckSanity                  RT_MANGLER(RTAsn1SetOfObjIds_CheckSanity)
+# define RTAsn1SetOfObjIds_Clone                        RT_MANGLER(RTAsn1SetOfObjIds_Clone)
+# define RTAsn1SetOfObjIds_Compare                      RT_MANGLER(RTAsn1SetOfObjIds_Compare)
+# define RTAsn1SetOfObjIds_Delete                       RT_MANGLER(RTAsn1SetOfObjIds_Delete)
+# define RTAsn1SetOfObjIds_Enum                         RT_MANGLER(RTAsn1SetOfObjIds_Enum)
+# define RTAsn1SetOfObjIds_Init                         RT_MANGLER(RTAsn1SetOfObjIds_Init)
+# define RTAsn1ObjId_DecodeAsn1                         RT_MANGLER(RTAsn1ObjId_DecodeAsn1)
+# define RTAsn1SeqOfObjIds_DecodeAsn1                   RT_MANGLER(RTAsn1SeqOfObjIds_DecodeAsn1)
+# define RTAsn1SetOfObjIds_DecodeAsn1                   RT_MANGLER(RTAsn1SetOfObjIds_DecodeAsn1)
+# define RTAsn1OctetString_CheckSanity                  RT_MANGLER(RTAsn1OctetString_CheckSanity)
+# define RTAsn1OctetString_Clone                        RT_MANGLER(RTAsn1OctetString_Clone)
+# define RTAsn1OctetString_Compare                      RT_MANGLER(RTAsn1OctetString_Compare)
+# define RTAsn1OctetString_Delete                       RT_MANGLER(RTAsn1OctetString_Delete)
+# define RTAsn1OctetString_Enum                         RT_MANGLER(RTAsn1OctetString_Enum)
+# define RTAsn1OctetString_Init                         RT_MANGLER(RTAsn1OctetString_Init)
+# define RTAsn1SeqOfOctetStrings_CheckSanity            RT_MANGLER(RTAsn1SeqOfOctetStrings_CheckSanity)
+# define RTAsn1SeqOfOctetStrings_Clone                  RT_MANGLER(RTAsn1SeqOfOctetStrings_Clone)
+# define RTAsn1SeqOfOctetStrings_Compare                RT_MANGLER(RTAsn1SeqOfOctetStrings_Compare)
+# define RTAsn1SeqOfOctetStrings_Delete                 RT_MANGLER(RTAsn1SeqOfOctetStrings_Delete)
+# define RTAsn1SeqOfOctetStrings_Enum                   RT_MANGLER(RTAsn1SeqOfOctetStrings_Enum)
+# define RTAsn1SeqOfOctetStrings_Init                   RT_MANGLER(RTAsn1SeqOfOctetStrings_Init)
+# define RTAsn1SetOfOctetStrings_CheckSanity            RT_MANGLER(RTAsn1SetOfOctetStrings_CheckSanity)
+# define RTAsn1SetOfOctetStrings_Clone                  RT_MANGLER(RTAsn1SetOfOctetStrings_Clone)
+# define RTAsn1SetOfOctetStrings_Compare                RT_MANGLER(RTAsn1SetOfOctetStrings_Compare)
+# define RTAsn1SetOfOctetStrings_Delete                 RT_MANGLER(RTAsn1SetOfOctetStrings_Delete)
+# define RTAsn1SetOfOctetStrings_Enum                   RT_MANGLER(RTAsn1SetOfOctetStrings_Enum)
+# define RTAsn1SetOfOctetStrings_Init                   RT_MANGLER(RTAsn1SetOfOctetStrings_Init)
+# define RTAsn1OctetString_DecodeAsn1                   RT_MANGLER(RTAsn1OctetString_DecodeAsn1)
+# define RTAsn1SeqOfOctetStrings_DecodeAsn1             RT_MANGLER(RTAsn1SeqOfOctetStrings_DecodeAsn1)
+# define RTAsn1SetOfOctetStrings_DecodeAsn1             RT_MANGLER(RTAsn1SetOfOctetStrings_DecodeAsn1)
+# define RTAsn1BmpString_CheckSanity                    RT_MANGLER(RTAsn1BmpString_CheckSanity)
+# define RTAsn1BmpString_Clone                          RT_MANGLER(RTAsn1BmpString_Clone)
+# define RTAsn1BmpString_Compare                        RT_MANGLER(RTAsn1BmpString_Compare)
+# define RTAsn1BmpString_Delete                         RT_MANGLER(RTAsn1BmpString_Delete)
+# define RTAsn1BmpString_Enum                           RT_MANGLER(RTAsn1BmpString_Enum)
+# define RTAsn1BmpString_Init                           RT_MANGLER(RTAsn1BmpString_Init)
+# define RTAsn1GeneralString_CheckSanity                RT_MANGLER(RTAsn1GeneralString_CheckSanity)
+# define RTAsn1GeneralString_Clone                      RT_MANGLER(RTAsn1GeneralString_Clone)
+# define RTAsn1GeneralString_Compare                    RT_MANGLER(RTAsn1GeneralString_Compare)
+# define RTAsn1GeneralString_Delete                     RT_MANGLER(RTAsn1GeneralString_Delete)
+# define RTAsn1GeneralString_Enum                       RT_MANGLER(RTAsn1GeneralString_Enum)
+# define RTAsn1GeneralString_Init                       RT_MANGLER(RTAsn1GeneralString_Init)
+# define RTAsn1GraphicString_CheckSanity                RT_MANGLER(RTAsn1GraphicString_CheckSanity)
+# define RTAsn1GraphicString_Clone                      RT_MANGLER(RTAsn1GraphicString_Clone)
+# define RTAsn1GraphicString_Compare                    RT_MANGLER(RTAsn1GraphicString_Compare)
+# define RTAsn1GraphicString_Delete                     RT_MANGLER(RTAsn1GraphicString_Delete)
+# define RTAsn1GraphicString_Enum                       RT_MANGLER(RTAsn1GraphicString_Enum)
+# define RTAsn1GraphicString_Init                       RT_MANGLER(RTAsn1GraphicString_Init)
+# define RTAsn1Ia5String_CheckSanity                    RT_MANGLER(RTAsn1Ia5String_CheckSanity)
+# define RTAsn1Ia5String_Clone                          RT_MANGLER(RTAsn1Ia5String_Clone)
+# define RTAsn1Ia5String_Compare                        RT_MANGLER(RTAsn1Ia5String_Compare)
+# define RTAsn1Ia5String_Delete                         RT_MANGLER(RTAsn1Ia5String_Delete)
+# define RTAsn1Ia5String_Enum                           RT_MANGLER(RTAsn1Ia5String_Enum)
+# define RTAsn1Ia5String_Init                           RT_MANGLER(RTAsn1Ia5String_Init)
+# define RTAsn1NumericString_CheckSanity                RT_MANGLER(RTAsn1NumericString_CheckSanity)
+# define RTAsn1NumericString_Clone                      RT_MANGLER(RTAsn1NumericString_Clone)
+# define RTAsn1NumericString_Compare                    RT_MANGLER(RTAsn1NumericString_Compare)
+# define RTAsn1NumericString_Delete                     RT_MANGLER(RTAsn1NumericString_Delete)
+# define RTAsn1NumericString_Enum                       RT_MANGLER(RTAsn1NumericString_Enum)
+# define RTAsn1NumericString_Init                       RT_MANGLER(RTAsn1NumericString_Init)
+# define RTAsn1PrintableString_CheckSanity              RT_MANGLER(RTAsn1PrintableString_CheckSanity)
+# define RTAsn1PrintableString_Clone                    RT_MANGLER(RTAsn1PrintableString_Clone)
+# define RTAsn1PrintableString_Compare                  RT_MANGLER(RTAsn1PrintableString_Compare)
+# define RTAsn1PrintableString_Delete                   RT_MANGLER(RTAsn1PrintableString_Delete)
+# define RTAsn1PrintableString_Enum                     RT_MANGLER(RTAsn1PrintableString_Enum)
+# define RTAsn1PrintableString_Init                     RT_MANGLER(RTAsn1PrintableString_Init)
+# define RTAsn1SeqOfStrings_CheckSanity                 RT_MANGLER(RTAsn1SeqOfStrings_CheckSanity)
+# define RTAsn1SeqOfStrings_Clone                       RT_MANGLER(RTAsn1SeqOfStrings_Clone)
+# define RTAsn1SeqOfStrings_Compare                     RT_MANGLER(RTAsn1SeqOfStrings_Compare)
+# define RTAsn1SeqOfStrings_Delete                      RT_MANGLER(RTAsn1SeqOfStrings_Delete)
+# define RTAsn1SeqOfStrings_Enum                        RT_MANGLER(RTAsn1SeqOfStrings_Enum)
+# define RTAsn1SeqOfStrings_Init                        RT_MANGLER(RTAsn1SeqOfStrings_Init)
+# define RTAsn1SetOfStrings_CheckSanity                 RT_MANGLER(RTAsn1SetOfStrings_CheckSanity)
+# define RTAsn1SetOfStrings_Clone                       RT_MANGLER(RTAsn1SetOfStrings_Clone)
+# define RTAsn1SetOfStrings_Compare                     RT_MANGLER(RTAsn1SetOfStrings_Compare)
+# define RTAsn1SetOfStrings_Delete                      RT_MANGLER(RTAsn1SetOfStrings_Delete)
+# define RTAsn1SetOfStrings_Enum                        RT_MANGLER(RTAsn1SetOfStrings_Enum)
+# define RTAsn1SetOfStrings_Init                        RT_MANGLER(RTAsn1SetOfStrings_Init)
+# define RTAsn1String_CheckSanity                       RT_MANGLER(RTAsn1String_CheckSanity)
+# define RTAsn1String_Clone                             RT_MANGLER(RTAsn1String_Clone)
+# define RTAsn1String_Compare                           RT_MANGLER(RTAsn1String_Compare)
+# define RTAsn1String_CompareEx                         RT_MANGLER(RTAsn1String_CompareEx)
+# define RTAsn1String_CompareWithString                 RT_MANGLER(RTAsn1String_CompareWithString)
+# define RTAsn1String_Delete                            RT_MANGLER(RTAsn1String_Delete)
+# define RTAsn1String_Enum                              RT_MANGLER(RTAsn1String_Enum)
+# define RTAsn1String_Init                              RT_MANGLER(RTAsn1String_Init)
+# define RTAsn1String_InitEx                            RT_MANGLER(RTAsn1String_InitEx)
+# define RTAsn1String_InitWithValue                     RT_MANGLER(RTAsn1String_InitWithValue)
+# define RTAsn1String_QueryUtf8                         RT_MANGLER(RTAsn1String_QueryUtf8)
+# define RTAsn1String_QueryUtf8Len                      RT_MANGLER(RTAsn1String_QueryUtf8Len)
+# define RTAsn1String_RecodeAsUtf8                      RT_MANGLER(RTAsn1String_RecodeAsUtf8)
+# define RTAsn1T61String_CheckSanity                    RT_MANGLER(RTAsn1T61String_CheckSanity)
+# define RTAsn1T61String_Clone                          RT_MANGLER(RTAsn1T61String_Clone)
+# define RTAsn1T61String_Compare                        RT_MANGLER(RTAsn1T61String_Compare)
+# define RTAsn1T61String_Delete                         RT_MANGLER(RTAsn1T61String_Delete)
+# define RTAsn1T61String_Enum                           RT_MANGLER(RTAsn1T61String_Enum)
+# define RTAsn1T61String_Init                           RT_MANGLER(RTAsn1T61String_Init)
+# define RTAsn1UniversalString_CheckSanity              RT_MANGLER(RTAsn1UniversalString_CheckSanity)
+# define RTAsn1UniversalString_Clone                    RT_MANGLER(RTAsn1UniversalString_Clone)
+# define RTAsn1UniversalString_Compare                  RT_MANGLER(RTAsn1UniversalString_Compare)
+# define RTAsn1UniversalString_Delete                   RT_MANGLER(RTAsn1UniversalString_Delete)
+# define RTAsn1UniversalString_Enum                     RT_MANGLER(RTAsn1UniversalString_Enum)
+# define RTAsn1UniversalString_Init                     RT_MANGLER(RTAsn1UniversalString_Init)
+# define RTAsn1Utf8String_CheckSanity                   RT_MANGLER(RTAsn1Utf8String_CheckSanity)
+# define RTAsn1Utf8String_Clone                         RT_MANGLER(RTAsn1Utf8String_Clone)
+# define RTAsn1Utf8String_Compare                       RT_MANGLER(RTAsn1Utf8String_Compare)
+# define RTAsn1Utf8String_Delete                        RT_MANGLER(RTAsn1Utf8String_Delete)
+# define RTAsn1Utf8String_Enum                          RT_MANGLER(RTAsn1Utf8String_Enum)
+# define RTAsn1Utf8String_Init                          RT_MANGLER(RTAsn1Utf8String_Init)
+# define RTAsn1VisibleString_CheckSanity                RT_MANGLER(RTAsn1VisibleString_CheckSanity)
+# define RTAsn1VisibleString_Clone                      RT_MANGLER(RTAsn1VisibleString_Clone)
+# define RTAsn1VisibleString_Compare                    RT_MANGLER(RTAsn1VisibleString_Compare)
+# define RTAsn1VisibleString_Delete                     RT_MANGLER(RTAsn1VisibleString_Delete)
+# define RTAsn1VisibleString_Enum                       RT_MANGLER(RTAsn1VisibleString_Enum)
+# define RTAsn1VisibleString_Init                       RT_MANGLER(RTAsn1VisibleString_Init)
+# define RTAsn1BmpString_DecodeAsn1                     RT_MANGLER(RTAsn1BmpString_DecodeAsn1)
+# define RTAsn1GeneralString_DecodeAsn1                 RT_MANGLER(RTAsn1GeneralString_DecodeAsn1)
+# define RTAsn1GraphicString_DecodeAsn1                 RT_MANGLER(RTAsn1GraphicString_DecodeAsn1)
+# define RTAsn1Ia5String_DecodeAsn1                     RT_MANGLER(RTAsn1Ia5String_DecodeAsn1)
+# define RTAsn1NumericString_DecodeAsn1                 RT_MANGLER(RTAsn1NumericString_DecodeAsn1)
+# define RTAsn1PrintableString_DecodeAsn1               RT_MANGLER(RTAsn1PrintableString_DecodeAsn1)
+# define RTAsn1SeqOfStrings_DecodeAsn1                  RT_MANGLER(RTAsn1SeqOfStrings_DecodeAsn1)
+# define RTAsn1SetOfStrings_DecodeAsn1                  RT_MANGLER(RTAsn1SetOfStrings_DecodeAsn1)
+# define RTAsn1String_DecodeAsn1                        RT_MANGLER(RTAsn1String_DecodeAsn1)
+# define RTAsn1T61String_DecodeAsn1                     RT_MANGLER(RTAsn1T61String_DecodeAsn1)
+# define RTAsn1UniversalString_DecodeAsn1               RT_MANGLER(RTAsn1UniversalString_DecodeAsn1)
+# define RTAsn1Utf8String_DecodeAsn1                    RT_MANGLER(RTAsn1Utf8String_DecodeAsn1)
+# define RTAsn1VisibleString_DecodeAsn1                 RT_MANGLER(RTAsn1VisibleString_DecodeAsn1)
+# define RTAsn1GeneralizedTime_CheckSanity              RT_MANGLER(RTAsn1GeneralizedTime_CheckSanity)
+# define RTAsn1GeneralizedTime_Clone                    RT_MANGLER(RTAsn1GeneralizedTime_Clone)
+# define RTAsn1GeneralizedTime_Compare                  RT_MANGLER(RTAsn1GeneralizedTime_Compare)
+# define RTAsn1GeneralizedTime_Delete                   RT_MANGLER(RTAsn1GeneralizedTime_Delete)
+# define RTAsn1GeneralizedTime_Enum                     RT_MANGLER(RTAsn1GeneralizedTime_Enum)
+# define RTAsn1GeneralizedTime_Init                     RT_MANGLER(RTAsn1GeneralizedTime_Init)
+# define RTAsn1SeqOfTimes_CheckSanity                   RT_MANGLER(RTAsn1SeqOfTimes_CheckSanity)
+# define RTAsn1SeqOfTimes_Clone                         RT_MANGLER(RTAsn1SeqOfTimes_Clone)
+# define RTAsn1SeqOfTimes_Compare                       RT_MANGLER(RTAsn1SeqOfTimes_Compare)
+# define RTAsn1SeqOfTimes_Delete                        RT_MANGLER(RTAsn1SeqOfTimes_Delete)
+# define RTAsn1SeqOfTimes_Enum                          RT_MANGLER(RTAsn1SeqOfTimes_Enum)
+# define RTAsn1SeqOfTimes_Init                          RT_MANGLER(RTAsn1SeqOfTimes_Init)
+# define RTAsn1SetOfTimes_CheckSanity                   RT_MANGLER(RTAsn1SetOfTimes_CheckSanity)
+# define RTAsn1SetOfTimes_Clone                         RT_MANGLER(RTAsn1SetOfTimes_Clone)
+# define RTAsn1SetOfTimes_Compare                       RT_MANGLER(RTAsn1SetOfTimes_Compare)
+# define RTAsn1SetOfTimes_Delete                        RT_MANGLER(RTAsn1SetOfTimes_Delete)
+# define RTAsn1SetOfTimes_Enum                          RT_MANGLER(RTAsn1SetOfTimes_Enum)
+# define RTAsn1SetOfTimes_Init                          RT_MANGLER(RTAsn1SetOfTimes_Init)
+# define RTAsn1Time_CheckSanity                         RT_MANGLER(RTAsn1Time_CheckSanity)
+# define RTAsn1Time_Clone                               RT_MANGLER(RTAsn1Time_Clone)
+# define RTAsn1Time_Compare                             RT_MANGLER(RTAsn1Time_Compare)
+# define RTAsn1Time_CompareWithTimeSpec                 RT_MANGLER(RTAsn1Time_CompareWithTimeSpec)
+# define RTAsn1Time_Delete                              RT_MANGLER(RTAsn1Time_Delete)
+# define RTAsn1Time_Enum                                RT_MANGLER(RTAsn1Time_Enum)
+# define RTAsn1Time_Init                                RT_MANGLER(RTAsn1Time_Init)
+# define RTAsn1UtcTime_CheckSanity                      RT_MANGLER(RTAsn1UtcTime_CheckSanity)
+# define RTAsn1UtcTime_Clone                            RT_MANGLER(RTAsn1UtcTime_Clone)
+# define RTAsn1UtcTime_Compare                          RT_MANGLER(RTAsn1UtcTime_Compare)
+# define RTAsn1UtcTime_Delete                           RT_MANGLER(RTAsn1UtcTime_Delete)
+# define RTAsn1UtcTime_Enum                             RT_MANGLER(RTAsn1UtcTime_Enum)
+# define RTAsn1UtcTime_Init                             RT_MANGLER(RTAsn1UtcTime_Init)
+# define RTAsn1GeneralizedTime_DecodeAsn1               RT_MANGLER(RTAsn1GeneralizedTime_DecodeAsn1)
+# define RTAsn1SeqOfTimes_DecodeAsn1                    RT_MANGLER(RTAsn1SeqOfTimes_DecodeAsn1)
+# define RTAsn1SetOfTimes_DecodeAsn1                    RT_MANGLER(RTAsn1SetOfTimes_DecodeAsn1)
+# define RTAsn1Time_DecodeAsn1                          RT_MANGLER(RTAsn1Time_DecodeAsn1)
+# define RTAsn1UtcTime_DecodeAsn1                       RT_MANGLER(RTAsn1UtcTime_DecodeAsn1)
+# define RTMd2                                          RT_MANGLER(RTMd2)
+# define RTMd2Final                                     RT_MANGLER(RTMd2Final)
+# define RTMd2Init                                      RT_MANGLER(RTMd2Init)
+# define RTMd2Update                                    RT_MANGLER(RTMd2Update)
+# define RTMd2FromString                                RT_MANGLER(RTMd2FromString)
+# define RTMd2ToString                                  RT_MANGLER(RTMd2ToString)
+# define RTCrDigestClone                                RT_MANGLER(RTCrDigestClone)
+# define RTCrDigestCreate                               RT_MANGLER(RTCrDigestCreate)
+# define RTCrDigestFinal                                RT_MANGLER(RTCrDigestFinal)
+# define RTCrDigestGetConsumedSize                      RT_MANGLER(RTCrDigestGetConsumedSize)
+# define RTCrDigestGetHash                              RT_MANGLER(RTCrDigestGetHash)
+# define RTCrDigestGetHashSize                          RT_MANGLER(RTCrDigestGetHashSize)
+# define RTCrDigestGetType                              RT_MANGLER(RTCrDigestGetType)
+# define RTCrDigestIsFinalized                          RT_MANGLER(RTCrDigestIsFinalized)
+# define RTCrDigestMatch                                RT_MANGLER(RTCrDigestMatch)
+# define RTCrDigestRelease                              RT_MANGLER(RTCrDigestRelease)
+# define RTCrDigestReset                                RT_MANGLER(RTCrDigestReset)
+# define RTCrDigestRetain                               RT_MANGLER(RTCrDigestRetain)
+# define RTCrDigestUpdate                               RT_MANGLER(RTCrDigestUpdate)
+# define RTCrDigestCreateByObjId                        RT_MANGLER(RTCrDigestCreateByObjId)
+# define RTCrDigestCreateByObjIdString                  RT_MANGLER(RTCrDigestCreateByObjIdString)
+# define RTCrDigestCreateByType                         RT_MANGLER(RTCrDigestCreateByType)
+# define RTCrDigestFindByObjId                          RT_MANGLER(RTCrDigestFindByObjId)
+# define RTCrDigestFindByObjIdString                    RT_MANGLER(RTCrDigestFindByObjIdString)
+# define RTCrDigestFindByType                           RT_MANGLER(RTCrDigestFindByType)
+# define RTCrRsaDigestInfo_DecodeAsn1                   RT_MANGLER(RTCrRsaDigestInfo_DecodeAsn1)
+# define RTCrRsaOtherPrimeInfo_DecodeAsn1               RT_MANGLER(RTCrRsaOtherPrimeInfo_DecodeAsn1)
+# define RTCrRsaOtherPrimeInfos_DecodeAsn1              RT_MANGLER(RTCrRsaOtherPrimeInfos_DecodeAsn1)
+# define RTCrRsaPrivateKey_DecodeAsn1                   RT_MANGLER(RTCrRsaPrivateKey_DecodeAsn1)
+# define RTCrRsaPublicKey_DecodeAsn1                    RT_MANGLER(RTCrRsaPublicKey_DecodeAsn1)
+# define RTCrRsaDigestInfo_Compare                      RT_MANGLER(RTCrRsaDigestInfo_Compare)
+# define RTCrRsaDigestInfo_Delete                       RT_MANGLER(RTCrRsaDigestInfo_Delete)
+# define RTCrRsaDigestInfo_Enum                         RT_MANGLER(RTCrRsaDigestInfo_Enum)
+# define RTCrRsaOtherPrimeInfo_Compare                  RT_MANGLER(RTCrRsaOtherPrimeInfo_Compare)
+# define RTCrRsaOtherPrimeInfo_Delete                   RT_MANGLER(RTCrRsaOtherPrimeInfo_Delete)
+# define RTCrRsaOtherPrimeInfo_Enum                     RT_MANGLER(RTCrRsaOtherPrimeInfo_Enum)
+# define RTCrRsaOtherPrimeInfos_Compare                 RT_MANGLER(RTCrRsaOtherPrimeInfos_Compare)
+# define RTCrRsaOtherPrimeInfos_Delete                  RT_MANGLER(RTCrRsaOtherPrimeInfos_Delete)
+# define RTCrRsaOtherPrimeInfos_Enum                    RT_MANGLER(RTCrRsaOtherPrimeInfos_Enum)
+# define RTCrRsaPrivateKey_Compare                      RT_MANGLER(RTCrRsaPrivateKey_Compare)
+# define RTCrRsaPrivateKey_Delete                       RT_MANGLER(RTCrRsaPrivateKey_Delete)
+# define RTCrRsaPrivateKey_Enum                         RT_MANGLER(RTCrRsaPrivateKey_Enum)
+# define RTCrRsaPublicKey_Compare                       RT_MANGLER(RTCrRsaPublicKey_Compare)
+# define RTCrRsaPublicKey_Delete                        RT_MANGLER(RTCrRsaPublicKey_Delete)
+# define RTCrRsaPublicKey_Enum                          RT_MANGLER(RTCrRsaPublicKey_Enum)
+# define RTCrRsaDigestInfo_Clone                        RT_MANGLER(RTCrRsaDigestInfo_Clone)
+# define RTCrRsaDigestInfo_Init                         RT_MANGLER(RTCrRsaDigestInfo_Init)
+# define RTCrRsaOtherPrimeInfo_Clone                    RT_MANGLER(RTCrRsaOtherPrimeInfo_Clone)
+# define RTCrRsaOtherPrimeInfo_Init                     RT_MANGLER(RTCrRsaOtherPrimeInfo_Init)
+# define RTCrRsaOtherPrimeInfos_Clone                   RT_MANGLER(RTCrRsaOtherPrimeInfos_Clone)
+# define RTCrRsaOtherPrimeInfos_Init                    RT_MANGLER(RTCrRsaOtherPrimeInfos_Init)
+# define RTCrRsaPrivateKey_Clone                        RT_MANGLER(RTCrRsaPrivateKey_Clone)
+# define RTCrRsaPrivateKey_Init                         RT_MANGLER(RTCrRsaPrivateKey_Init)
+# define RTCrRsaPublicKey_Clone                         RT_MANGLER(RTCrRsaPublicKey_Clone)
+# define RTCrRsaPublicKey_Init                          RT_MANGLER(RTCrRsaPublicKey_Init)
+# define RTCrRsaDigestInfo_CheckSanity                  RT_MANGLER(RTCrRsaDigestInfo_CheckSanity)
+# define RTCrRsaOtherPrimeInfo_CheckSanity              RT_MANGLER(RTCrRsaOtherPrimeInfo_CheckSanity)
+# define RTCrRsaOtherPrimeInfos_CheckSanity             RT_MANGLER(RTCrRsaOtherPrimeInfos_CheckSanity)
+# define RTCrRsaPrivateKey_CheckSanity                  RT_MANGLER(RTCrRsaPrivateKey_CheckSanity)
+# define RTCrRsaPublicKey_CheckSanity                   RT_MANGLER(RTCrRsaPublicKey_CheckSanity)
+# define RTCrPemFreeSections                            RT_MANGLER(RTCrPemFreeSections)
+# define RTCrPemParseContent                            RT_MANGLER(RTCrPemParseContent)
+# define RTCrPemReadFile                                RT_MANGLER(RTCrPemReadFile)
+# define RTCrPkcs7Attribute_DecodeAsn1                  RT_MANGLER(RTCrPkcs7Attribute_DecodeAsn1)
+# define RTCrPkcs7Attributes_DecodeAsn1                 RT_MANGLER(RTCrPkcs7Attributes_DecodeAsn1)
+# define RTCrPkcs7ContentInfo_DecodeAsn1                RT_MANGLER(RTCrPkcs7ContentInfo_DecodeAsn1)
+# define RTCrPkcs7DigestInfo_DecodeAsn1                 RT_MANGLER(RTCrPkcs7DigestInfo_DecodeAsn1)
+# define RTCrPkcs7IssuerAndSerialNumber_DecodeAsn1      RT_MANGLER(RTCrPkcs7IssuerAndSerialNumber_DecodeAsn1)
+# define RTCrPkcs7SignedData_DecodeAsn1                 RT_MANGLER(RTCrPkcs7SignedData_DecodeAsn1)
+# define RTCrPkcs7SignerInfo_DecodeAsn1                 RT_MANGLER(RTCrPkcs7SignerInfo_DecodeAsn1)
+# define RTCrPkcs7SignerInfos_DecodeAsn1                RT_MANGLER(RTCrPkcs7SignerInfos_DecodeAsn1)
+# define RTCrPkcs7Attribute_Compare                     RT_MANGLER(RTCrPkcs7Attribute_Compare)
+# define RTCrPkcs7Attribute_Delete                      RT_MANGLER(RTCrPkcs7Attribute_Delete)
+# define RTCrPkcs7Attribute_Enum                        RT_MANGLER(RTCrPkcs7Attribute_Enum)
+# define RTCrPkcs7Attributes_Compare                    RT_MANGLER(RTCrPkcs7Attributes_Compare)
+# define RTCrPkcs7Attributes_Delete                     RT_MANGLER(RTCrPkcs7Attributes_Delete)
+# define RTCrPkcs7Attributes_Enum                       RT_MANGLER(RTCrPkcs7Attributes_Enum)
+# define RTCrPkcs7ContentInfo_Compare                   RT_MANGLER(RTCrPkcs7ContentInfo_Compare)
+# define RTCrPkcs7ContentInfo_Delete                    RT_MANGLER(RTCrPkcs7ContentInfo_Delete)
+# define RTCrPkcs7ContentInfo_Enum                      RT_MANGLER(RTCrPkcs7ContentInfo_Enum)
+# define RTCrPkcs7ContentInfo_IsSignedData              RT_MANGLER(RTCrPkcs7ContentInfo_IsSignedData)
+# define RTCrPkcs7DigestInfo_Compare                    RT_MANGLER(RTCrPkcs7DigestInfo_Compare)
+# define RTCrPkcs7DigestInfo_Delete                     RT_MANGLER(RTCrPkcs7DigestInfo_Delete)
+# define RTCrPkcs7DigestInfo_Enum                       RT_MANGLER(RTCrPkcs7DigestInfo_Enum)
+# define RTCrPkcs7IssuerAndSerialNumber_Compare         RT_MANGLER(RTCrPkcs7IssuerAndSerialNumber_Compare)
+# define RTCrPkcs7IssuerAndSerialNumber_Delete          RT_MANGLER(RTCrPkcs7IssuerAndSerialNumber_Delete)
+# define RTCrPkcs7IssuerAndSerialNumber_Enum            RT_MANGLER(RTCrPkcs7IssuerAndSerialNumber_Enum)
+# define RTCrPkcs7SignedData_Compare                    RT_MANGLER(RTCrPkcs7SignedData_Compare)
+# define RTCrPkcs7SignedData_Delete                     RT_MANGLER(RTCrPkcs7SignedData_Delete)
+# define RTCrPkcs7SignedData_Enum                       RT_MANGLER(RTCrPkcs7SignedData_Enum)
+# define RTCrPkcs7SignerInfo_Compare                    RT_MANGLER(RTCrPkcs7SignerInfo_Compare)
+# define RTCrPkcs7SignerInfo_Delete                     RT_MANGLER(RTCrPkcs7SignerInfo_Delete)
+# define RTCrPkcs7SignerInfo_Enum                       RT_MANGLER(RTCrPkcs7SignerInfo_Enum)
+# define RTCrPkcs7SignerInfo_GetSigningTime             RT_MANGLER(RTCrPkcs7SignerInfo_GetSigningTime)
+# define RTCrPkcs7SignerInfo_GetMsTimestamp             RT_MANGLER(RTCrPkcs7SignerInfo_GetMsTimestamp)
+# define RTCrPkcs7SignerInfos_Compare                   RT_MANGLER(RTCrPkcs7SignerInfos_Compare)
+# define RTCrPkcs7SignerInfos_Delete                    RT_MANGLER(RTCrPkcs7SignerInfos_Delete)
+# define RTCrPkcs7SignerInfos_Enum                      RT_MANGLER(RTCrPkcs7SignerInfos_Enum)
+# define RTCrPkcs7Attribute_Clone                       RT_MANGLER(RTCrPkcs7Attribute_Clone)
+# define RTCrPkcs7Attribute_Init                        RT_MANGLER(RTCrPkcs7Attribute_Init)
+# define RTCrPkcs7Attributes_Clone                      RT_MANGLER(RTCrPkcs7Attributes_Clone)
+# define RTCrPkcs7Attributes_Init                       RT_MANGLER(RTCrPkcs7Attributes_Init)
+# define RTCrPkcs7ContentInfo_Clone                     RT_MANGLER(RTCrPkcs7ContentInfo_Clone)
+# define RTCrPkcs7ContentInfo_Init                      RT_MANGLER(RTCrPkcs7ContentInfo_Init)
+# define RTCrPkcs7DigestInfo_Clone                      RT_MANGLER(RTCrPkcs7DigestInfo_Clone)
+# define RTCrPkcs7DigestInfo_Init                       RT_MANGLER(RTCrPkcs7DigestInfo_Init)
+# define RTCrPkcs7IssuerAndSerialNumber_Clone           RT_MANGLER(RTCrPkcs7IssuerAndSerialNumber_Clone)
+# define RTCrPkcs7IssuerAndSerialNumber_Init            RT_MANGLER(RTCrPkcs7IssuerAndSerialNumber_Init)
+# define RTCrPkcs7SignedData_Clone                      RT_MANGLER(RTCrPkcs7SignedData_Clone)
+# define RTCrPkcs7SignedData_Init                       RT_MANGLER(RTCrPkcs7SignedData_Init)
+# define RTCrPkcs7SignerInfo_Clone                      RT_MANGLER(RTCrPkcs7SignerInfo_Clone)
+# define RTCrPkcs7SignerInfo_Init                       RT_MANGLER(RTCrPkcs7SignerInfo_Init)
+# define RTCrPkcs7SignerInfos_Clone                     RT_MANGLER(RTCrPkcs7SignerInfos_Clone)
+# define RTCrPkcs7SignerInfos_Init                      RT_MANGLER(RTCrPkcs7SignerInfos_Init)
+# define RTCrPkcs7Attribute_CheckSanity                 RT_MANGLER(RTCrPkcs7Attribute_CheckSanity)
+# define RTCrPkcs7Attributes_CheckSanity                RT_MANGLER(RTCrPkcs7Attributes_CheckSanity)
+# define RTCrPkcs7ContentInfo_CheckSanity               RT_MANGLER(RTCrPkcs7ContentInfo_CheckSanity)
+# define RTCrPkcs7DigestInfo_CheckSanity                RT_MANGLER(RTCrPkcs7DigestInfo_CheckSanity)
+# define RTCrPkcs7IssuerAndSerialNumber_CheckSanity     RT_MANGLER(RTCrPkcs7IssuerAndSerialNumber_CheckSanity)
+# define RTCrPkcs7SignedData_CheckSanity                RT_MANGLER(RTCrPkcs7SignedData_CheckSanity)
+# define RTCrPkcs7SignerInfo_CheckSanity                RT_MANGLER(RTCrPkcs7SignerInfo_CheckSanity)
+# define RTCrPkcs7SignerInfos_CheckSanity               RT_MANGLER(RTCrPkcs7SignerInfos_CheckSanity)
+# define RTCrPkcs7VerifyCertCallbackCodeSigning         RT_MANGLER(RTCrPkcs7VerifyCertCallbackCodeSigning)
+# define RTCrPkcs7VerifyCertCallbackDefault             RT_MANGLER(RTCrPkcs7VerifyCertCallbackDefault)
+# define RTCrPkcs7VerifySignedData                      RT_MANGLER(RTCrPkcs7VerifySignedData)
+# define RTCrPkcs7Cert_CheckSanity                      RT_MANGLER(RTCrPkcs7Cert_CheckSanity)
+# define RTCrPkcs7Cert_Clone                            RT_MANGLER(RTCrPkcs7Cert_Clone)
+# define RTCrPkcs7Cert_Compare                          RT_MANGLER(RTCrPkcs7Cert_Compare)
+# define RTCrPkcs7Cert_DecodeAsn1                       RT_MANGLER(RTCrPkcs7Cert_DecodeAsn1)
+# define RTCrPkcs7Cert_Delete                           RT_MANGLER(RTCrPkcs7Cert_Delete)
+# define RTCrPkcs7Cert_Enum                             RT_MANGLER(RTCrPkcs7Cert_Enum)
+# define RTCrPkcs7Cert_Init                             RT_MANGLER(RTCrPkcs7Cert_Init)
+# define RTCrPkcs7SetOfCerts_CheckSanity                RT_MANGLER(RTCrPkcs7SetOfCerts_CheckSanity)
+# define RTCrPkcs7SetOfCerts_Clone                      RT_MANGLER(RTCrPkcs7SetOfCerts_Clone)
+# define RTCrPkcs7SetOfCerts_Compare                    RT_MANGLER(RTCrPkcs7SetOfCerts_Compare)
+# define RTCrPkcs7SetOfCerts_DecodeAsn1                 RT_MANGLER(RTCrPkcs7SetOfCerts_DecodeAsn1)
+# define RTCrPkcs7SetOfCerts_Delete                     RT_MANGLER(RTCrPkcs7SetOfCerts_Delete)
+# define RTCrPkcs7SetOfCerts_Enum                       RT_MANGLER(RTCrPkcs7SetOfCerts_Enum)
+# define RTCrPkcs7SetOfCerts_Init                       RT_MANGLER(RTCrPkcs7SetOfCerts_Init)
+# define RTCrPkcs7SetOfCerts_FindX509ByIssuerAndSerialNumber RT_MANGLER(RTCrPkcs7SetOfCerts_FindX509ByIssuerAndSerialNumber)
+# define RTCrPkcs7SetOfContentInfos_CheckSanity         RT_MANGLER(RTCrPkcs7SetOfContentInfos_CheckSanity)
+# define RTCrPkcs7SetOfContentInfos_Clone               RT_MANGLER(RTCrPkcs7SetOfContentInfos_Clone)
+# define RTCrPkcs7SetOfContentInfos_Compare             RT_MANGLER(RTCrPkcs7SetOfContentInfos_Compare)
+# define RTCrPkcs7SetOfContentInfos_DecodeAsn1          RT_MANGLER(RTCrPkcs7SetOfContentInfos_DecodeAsn1)
+# define RTCrPkcs7SetOfContentInfos_Delete              RT_MANGLER(RTCrPkcs7SetOfContentInfos_Delete)
+# define RTCrPkcs7SetOfContentInfos_Enum                RT_MANGLER(RTCrPkcs7SetOfContentInfos_Enum)
+# define RTCrPkcs7SetOfContentInfos_Init                RT_MANGLER(RTCrPkcs7SetOfContentInfos_Init)
+# define RTCrPkcs7SetOfSignedData_CheckSanity           RT_MANGLER(RTCrPkcs7SetOfSignedData_CheckSanity)
+# define RTCrPkcs7SetOfSignedData_Clone                 RT_MANGLER(RTCrPkcs7SetOfSignedData_Clone)
+# define RTCrPkcs7SetOfSignedData_Compare               RT_MANGLER(RTCrPkcs7SetOfSignedData_Compare)
+# define RTCrPkcs7SetOfSignedData_DecodeAsn1            RT_MANGLER(RTCrPkcs7SetOfSignedData_DecodeAsn1)
+# define RTCrPkcs7SetOfSignedData_Delete                RT_MANGLER(RTCrPkcs7SetOfSignedData_Delete)
+# define RTCrPkcs7SetOfSignedData_Enum                  RT_MANGLER(RTCrPkcs7SetOfSignedData_Enum)
+# define RTCrPkcs7SetOfSignedData_Init                  RT_MANGLER(RTCrPkcs7SetOfSignedData_Init)
+# define RTCrPkixSignatureCreateByObjId                 RT_MANGLER(RTCrPkixSignatureCreateByObjId)
+# define RTCrPkixSignatureCreateByObjIdString           RT_MANGLER(RTCrPkixSignatureCreateByObjIdString)
+# define RTCrPkixSignatureCreate                        RT_MANGLER(RTCrPkixSignatureCreate)
+# define RTCrPkixSignatureRelease                       RT_MANGLER(RTCrPkixSignatureRelease)
+# define RTCrPkixSignatureRetain                        RT_MANGLER(RTCrPkixSignatureRetain)
+# define RTCrPkixSignatureSign                          RT_MANGLER(RTCrPkixSignatureSign)
+# define RTCrPkixSignatureVerify                        RT_MANGLER(RTCrPkixSignatureVerify)
+# define RTCrPkixSignatureVerifyBitString               RT_MANGLER(RTCrPkixSignatureVerifyBitString)
+# define RTCrPkixSignatureVerifyOctetString             RT_MANGLER(RTCrPkixSignatureVerifyOctetString)
+# define RTCrPkixGetCiperOidFromSignatureAlgorithm      RT_MANGLER(RTCrPkixGetCiperOidFromSignatureAlgorithm)
+# define RTCrPkixPubKeyVerifySignature                  RT_MANGLER(RTCrPkixPubKeyVerifySignature)
+# define RTCrSpcAttributeTypeAndOptionalValue_DecodeAsn1 RT_MANGLER(RTCrSpcAttributeTypeAndOptionalValue_DecodeAsn1)
+# define RTCrSpcIndirectDataContent_DecodeAsn1          RT_MANGLER(RTCrSpcIndirectDataContent_DecodeAsn1)
+# define RTCrSpcLink_DecodeAsn1                         RT_MANGLER(RTCrSpcLink_DecodeAsn1)
+# define RTCrSpcPeImageData_DecodeAsn1                  RT_MANGLER(RTCrSpcPeImageData_DecodeAsn1)
+# define RTCrSpcSerializedObjectAttribute_DecodeAsn1    RT_MANGLER(RTCrSpcSerializedObjectAttribute_DecodeAsn1)
+# define RTCrSpcSerializedObjectAttributes_DecodeAsn1   RT_MANGLER(RTCrSpcSerializedObjectAttributes_DecodeAsn1)
+# define RTCrSpcSerializedObject_DecodeAsn1             RT_MANGLER(RTCrSpcSerializedObject_DecodeAsn1)
+# define RTCrSpcSerializedPageHashes_DecodeAsn1         RT_MANGLER(RTCrSpcSerializedPageHashes_DecodeAsn1)
+# define RTCrSpcString_DecodeAsn1                       RT_MANGLER(RTCrSpcString_DecodeAsn1)
+# define RTCrSpcAttributeTypeAndOptionalValue_Compare   RT_MANGLER(RTCrSpcAttributeTypeAndOptionalValue_Compare)
+# define RTCrSpcAttributeTypeAndOptionalValue_Delete    RT_MANGLER(RTCrSpcAttributeTypeAndOptionalValue_Delete)
+# define RTCrSpcAttributeTypeAndOptionalValue_Enum      RT_MANGLER(RTCrSpcAttributeTypeAndOptionalValue_Enum)
+# define RTCrSpcIndirectDataContent_Compare             RT_MANGLER(RTCrSpcIndirectDataContent_Compare)
+# define RTCrSpcIndirectDataContent_Delete              RT_MANGLER(RTCrSpcIndirectDataContent_Delete)
+# define RTCrSpcIndirectDataContent_Enum                RT_MANGLER(RTCrSpcIndirectDataContent_Enum)
+# define RTCrSpcIndirectDataContent_GetPeImageObjAttrib RT_MANGLER(RTCrSpcIndirectDataContent_GetPeImageObjAttrib)
+# define RTCrSpcLink_Compare                            RT_MANGLER(RTCrSpcLink_Compare)
+# define RTCrSpcLink_Delete                             RT_MANGLER(RTCrSpcLink_Delete)
+# define RTCrSpcLink_Enum                               RT_MANGLER(RTCrSpcLink_Enum)
+# define RTCrSpcPeImageData_Compare                     RT_MANGLER(RTCrSpcPeImageData_Compare)
+# define RTCrSpcPeImageData_Delete                      RT_MANGLER(RTCrSpcPeImageData_Delete)
+# define RTCrSpcPeImageData_Enum                        RT_MANGLER(RTCrSpcPeImageData_Enum)
+# define RTCrSpcSerializedObjectAttribute_Compare       RT_MANGLER(RTCrSpcSerializedObjectAttribute_Compare)
+# define RTCrSpcSerializedObjectAttribute_Delete        RT_MANGLER(RTCrSpcSerializedObjectAttribute_Delete)
+# define RTCrSpcSerializedObjectAttribute_Enum          RT_MANGLER(RTCrSpcSerializedObjectAttribute_Enum)
+# define RTCrSpcSerializedObjectAttributes_Compare      RT_MANGLER(RTCrSpcSerializedObjectAttributes_Compare)
+# define RTCrSpcSerializedObjectAttributes_Delete       RT_MANGLER(RTCrSpcSerializedObjectAttributes_Delete)
+# define RTCrSpcSerializedObjectAttributes_Enum         RT_MANGLER(RTCrSpcSerializedObjectAttributes_Enum)
+# define RTCrSpcSerializedObject_Compare                RT_MANGLER(RTCrSpcSerializedObject_Compare)
+# define RTCrSpcSerializedObject_Delete                 RT_MANGLER(RTCrSpcSerializedObject_Delete)
+# define RTCrSpcSerializedObject_Enum                   RT_MANGLER(RTCrSpcSerializedObject_Enum)
+# define RTCrSpcSerializedPageHashes_Compare            RT_MANGLER(RTCrSpcSerializedPageHashes_Compare)
+# define RTCrSpcSerializedPageHashes_Delete             RT_MANGLER(RTCrSpcSerializedPageHashes_Delete)
+# define RTCrSpcSerializedPageHashes_Enum               RT_MANGLER(RTCrSpcSerializedPageHashes_Enum)
+# define RTCrSpcSerializedPageHashes_UpdateDerivedData  RT_MANGLER(RTCrSpcSerializedPageHashes_UpdateDerivedData)
+# define RTCrSpcString_Compare                          RT_MANGLER(RTCrSpcString_Compare)
+# define RTCrSpcString_Delete                           RT_MANGLER(RTCrSpcString_Delete)
+# define RTCrSpcString_Enum                             RT_MANGLER(RTCrSpcString_Enum)
+# define RTCrSpcAttributeTypeAndOptionalValue_Clone     RT_MANGLER(RTCrSpcAttributeTypeAndOptionalValue_Clone)
+# define RTCrSpcAttributeTypeAndOptionalValue_Init      RT_MANGLER(RTCrSpcAttributeTypeAndOptionalValue_Init)
+# define RTCrSpcIndirectDataContent_Clone               RT_MANGLER(RTCrSpcIndirectDataContent_Clone)
+# define RTCrSpcIndirectDataContent_Init                RT_MANGLER(RTCrSpcIndirectDataContent_Init)
+# define RTCrSpcLink_Clone                              RT_MANGLER(RTCrSpcLink_Clone)
+# define RTCrSpcLink_Init                               RT_MANGLER(RTCrSpcLink_Init)
+# define RTCrSpcPeImageData_Clone                       RT_MANGLER(RTCrSpcPeImageData_Clone)
+# define RTCrSpcPeImageData_Init                        RT_MANGLER(RTCrSpcPeImageData_Init)
+# define RTCrSpcSerializedObjectAttribute_Clone         RT_MANGLER(RTCrSpcSerializedObjectAttribute_Clone)
+# define RTCrSpcSerializedObjectAttribute_Init          RT_MANGLER(RTCrSpcSerializedObjectAttribute_Init)
+# define RTCrSpcSerializedObjectAttributes_Clone        RT_MANGLER(RTCrSpcSerializedObjectAttributes_Clone)
+# define RTCrSpcSerializedObjectAttributes_Init         RT_MANGLER(RTCrSpcSerializedObjectAttributes_Init)
+# define RTCrSpcSerializedObject_Clone                  RT_MANGLER(RTCrSpcSerializedObject_Clone)
+# define RTCrSpcSerializedObject_Init                   RT_MANGLER(RTCrSpcSerializedObject_Init)
+# define RTCrSpcSerializedPageHashes_Clone              RT_MANGLER(RTCrSpcSerializedPageHashes_Clone)
+# define RTCrSpcSerializedPageHashes_Init               RT_MANGLER(RTCrSpcSerializedPageHashes_Init)
+# define RTCrSpcString_Clone                            RT_MANGLER(RTCrSpcString_Clone)
+# define RTCrSpcString_Init                             RT_MANGLER(RTCrSpcString_Init)
+# define RTCrSpcAttributeTypeAndOptionalValue_CheckSanity RT_MANGLER(RTCrSpcAttributeTypeAndOptionalValue_CheckSanity)
+# define RTCrSpcIndirectDataContent_CheckSanity         RT_MANGLER(RTCrSpcIndirectDataContent_CheckSanity)
+# define RTCrSpcIndirectDataContent_CheckSanityEx       RT_MANGLER(RTCrSpcIndirectDataContent_CheckSanityEx)
+# define RTCrSpcLink_CheckSanity                        RT_MANGLER(RTCrSpcLink_CheckSanity)
+# define RTCrSpcPeImageData_CheckSanity                 RT_MANGLER(RTCrSpcPeImageData_CheckSanity)
+# define RTCrSpcSerializedObjectAttribute_CheckSanity   RT_MANGLER(RTCrSpcSerializedObjectAttribute_CheckSanity)
+# define RTCrSpcSerializedObjectAttributes_CheckSanity  RT_MANGLER(RTCrSpcSerializedObjectAttributes_CheckSanity)
+# define RTCrSpcSerializedObject_CheckSanity            RT_MANGLER(RTCrSpcSerializedObject_CheckSanity)
+# define RTCrSpcSerializedPageHashes_CheckSanity        RT_MANGLER(RTCrSpcSerializedPageHashes_CheckSanity)
+# define RTCrSpcString_CheckSanity                      RT_MANGLER(RTCrSpcString_CheckSanity)
+# define RTCrX509AlgorithmIdentifier_DecodeAsn1         RT_MANGLER(RTCrX509AlgorithmIdentifier_DecodeAsn1)
+# define RTCrX509AlgorithmIdentifiers_DecodeAsn1        RT_MANGLER(RTCrX509AlgorithmIdentifiers_DecodeAsn1)
+# define RTCrX509AttributeTypeAndValue_DecodeAsn1       RT_MANGLER(RTCrX509AttributeTypeAndValue_DecodeAsn1)
+# define RTCrX509AttributeTypeAndValues_DecodeAsn1      RT_MANGLER(RTCrX509AttributeTypeAndValues_DecodeAsn1)
+# define RTCrX509AuthorityKeyIdentifier_DecodeAsn1      RT_MANGLER(RTCrX509AuthorityKeyIdentifier_DecodeAsn1)
+# define RTCrX509BasicConstraints_DecodeAsn1            RT_MANGLER(RTCrX509BasicConstraints_DecodeAsn1)
+# define RTCrX509CertificatePolicies_DecodeAsn1         RT_MANGLER(RTCrX509CertificatePolicies_DecodeAsn1)
+# define RTCrX509Certificate_DecodeAsn1                 RT_MANGLER(RTCrX509Certificate_DecodeAsn1)
+# define RTCrX509Certificates_DecodeAsn1                RT_MANGLER(RTCrX509Certificates_DecodeAsn1)
+# define RTCrX509Extension_DecodeAsn1                   RT_MANGLER(RTCrX509Extension_DecodeAsn1)
+# define RTCrX509Extension_ExtnValue_DecodeAsn1         RT_MANGLER(RTCrX509Extension_ExtnValue_DecodeAsn1)
+# define RTCrX509Extensions_DecodeAsn1                  RT_MANGLER(RTCrX509Extensions_DecodeAsn1)
+# define RTCrX509GeneralName_DecodeAsn1                 RT_MANGLER(RTCrX509GeneralName_DecodeAsn1)
+# define RTCrX509GeneralNames_DecodeAsn1                RT_MANGLER(RTCrX509GeneralNames_DecodeAsn1)
+# define RTCrX509GeneralSubtree_DecodeAsn1              RT_MANGLER(RTCrX509GeneralSubtree_DecodeAsn1)
+# define RTCrX509GeneralSubtrees_DecodeAsn1             RT_MANGLER(RTCrX509GeneralSubtrees_DecodeAsn1)
+# define RTCrX509NameConstraints_DecodeAsn1             RT_MANGLER(RTCrX509NameConstraints_DecodeAsn1)
+# define RTCrX509Name_DecodeAsn1                        RT_MANGLER(RTCrX509Name_DecodeAsn1)
+# define RTCrX509OldAuthorityKeyIdentifier_DecodeAsn1   RT_MANGLER(RTCrX509OldAuthorityKeyIdentifier_DecodeAsn1)
+# define RTCrX509OtherName_DecodeAsn1                   RT_MANGLER(RTCrX509OtherName_DecodeAsn1)
+# define RTCrX509PolicyConstraints_DecodeAsn1           RT_MANGLER(RTCrX509PolicyConstraints_DecodeAsn1)
+# define RTCrX509PolicyInformation_DecodeAsn1           RT_MANGLER(RTCrX509PolicyInformation_DecodeAsn1)
+# define RTCrX509PolicyMapping_DecodeAsn1               RT_MANGLER(RTCrX509PolicyMapping_DecodeAsn1)
+# define RTCrX509PolicyMappings_DecodeAsn1              RT_MANGLER(RTCrX509PolicyMappings_DecodeAsn1)
+# define RTCrX509PolicyQualifierInfo_DecodeAsn1         RT_MANGLER(RTCrX509PolicyQualifierInfo_DecodeAsn1)
+# define RTCrX509PolicyQualifierInfos_DecodeAsn1        RT_MANGLER(RTCrX509PolicyQualifierInfos_DecodeAsn1)
+# define RTCrX509SubjectPublicKeyInfo_DecodeAsn1        RT_MANGLER(RTCrX509SubjectPublicKeyInfo_DecodeAsn1)
+# define RTCrX509TbsCertificate_DecodeAsn1              RT_MANGLER(RTCrX509TbsCertificate_DecodeAsn1)
+# define RTCrX509Validity_DecodeAsn1                    RT_MANGLER(RTCrX509Validity_DecodeAsn1)
+# define RTCrX509CertPathsBuild                         RT_MANGLER(RTCrX509CertPathsBuild)
+# define RTCrX509CertPathsCreate                        RT_MANGLER(RTCrX509CertPathsCreate)
+# define RTCrX509CertPathsCreateEx                      RT_MANGLER(RTCrX509CertPathsCreateEx)
+# define RTCrX509CertPathsDumpAll                       RT_MANGLER(RTCrX509CertPathsDumpAll)
+# define RTCrX509CertPathsDumpOne                       RT_MANGLER(RTCrX509CertPathsDumpOne)
+# define RTCrX509CertPathsGetPathCount                  RT_MANGLER(RTCrX509CertPathsGetPathCount)
+# define RTCrX509CertPathsGetPathLength                 RT_MANGLER(RTCrX509CertPathsGetPathLength)
+# define RTCrX509CertPathsGetPathNodeCert               RT_MANGLER(RTCrX509CertPathsGetPathNodeCert)
+# define RTCrX509CertPathsGetPathVerifyResult           RT_MANGLER(RTCrX509CertPathsGetPathVerifyResult)
+# define RTCrX509CertPathsQueryPathInfo                 RT_MANGLER(RTCrX509CertPathsQueryPathInfo)
+# define RTCrX509CertPathsRelease                       RT_MANGLER(RTCrX509CertPathsRelease)
+# define RTCrX509CertPathsRetain                        RT_MANGLER(RTCrX509CertPathsRetain)
+# define RTCrX509CertPathsSetTrustedStore               RT_MANGLER(RTCrX509CertPathsSetTrustedStore)
+# define RTCrX509CertPathsSetUntrustedArray             RT_MANGLER(RTCrX509CertPathsSetUntrustedArray)
+# define RTCrX509CertPathsSetUntrustedSet               RT_MANGLER(RTCrX509CertPathsSetUntrustedSet)
+# define RTCrX509CertPathsSetUntrustedStore             RT_MANGLER(RTCrX509CertPathsSetUntrustedStore)
+# define RTCrX509CertPathsSetValidTime                  RT_MANGLER(RTCrX509CertPathsSetValidTime)
+# define RTCrX509CertPathsSetValidTimeSpec              RT_MANGLER(RTCrX509CertPathsSetValidTimeSpec)
+# define RTCrX509CertPathsValidateAll                   RT_MANGLER(RTCrX509CertPathsValidateAll)
+# define RTCrX509CertPathsValidateOne                   RT_MANGLER(RTCrX509CertPathsValidateOne)
+# define RTCrX509AlgorithmIdentifier_Compare            RT_MANGLER(RTCrX509AlgorithmIdentifier_Compare)
+# define RTCrX509AlgorithmIdentifier_CompareDigestAndEncryptedDigest RT_MANGLER(RTCrX509AlgorithmIdentifier_CompareDigestAndEncryptedDigest)
+# define RTCrX509AlgorithmIdentifier_CompareWithString  RT_MANGLER(RTCrX509AlgorithmIdentifier_CompareWithString)
+# define RTCrX509AlgorithmIdentifier_Delete             RT_MANGLER(RTCrX509AlgorithmIdentifier_Delete)
+# define RTCrX509AlgorithmIdentifier_Enum               RT_MANGLER(RTCrX509AlgorithmIdentifier_Enum)
+# define RTCrX509AlgorithmIdentifier_QueryDigestSize    RT_MANGLER(RTCrX509AlgorithmIdentifier_QueryDigestSize)
+# define RTCrX509AlgorithmIdentifier_QueryDigestType    RT_MANGLER(RTCrX509AlgorithmIdentifier_QueryDigestType)
+# define RTCrX509AlgorithmIdentifiers_Compare           RT_MANGLER(RTCrX509AlgorithmIdentifiers_Compare)
+# define RTCrX509AlgorithmIdentifiers_Delete            RT_MANGLER(RTCrX509AlgorithmIdentifiers_Delete)
+# define RTCrX509AlgorithmIdentifiers_Enum              RT_MANGLER(RTCrX509AlgorithmIdentifiers_Enum)
+# define RTCrX509AttributeTypeAndValue_Compare          RT_MANGLER(RTCrX509AttributeTypeAndValue_Compare)
+# define RTCrX509AttributeTypeAndValue_Delete           RT_MANGLER(RTCrX509AttributeTypeAndValue_Delete)
+# define RTCrX509AttributeTypeAndValue_Enum             RT_MANGLER(RTCrX509AttributeTypeAndValue_Enum)
+# define RTCrX509AttributeTypeAndValues_Compare         RT_MANGLER(RTCrX509AttributeTypeAndValues_Compare)
+# define RTCrX509AttributeTypeAndValues_Delete          RT_MANGLER(RTCrX509AttributeTypeAndValues_Delete)
+# define RTCrX509AttributeTypeAndValues_Enum            RT_MANGLER(RTCrX509AttributeTypeAndValues_Enum)
+# define RTCrX509AuthorityKeyIdentifier_Compare         RT_MANGLER(RTCrX509AuthorityKeyIdentifier_Compare)
+# define RTCrX509AuthorityKeyIdentifier_Delete          RT_MANGLER(RTCrX509AuthorityKeyIdentifier_Delete)
+# define RTCrX509AuthorityKeyIdentifier_Enum            RT_MANGLER(RTCrX509AuthorityKeyIdentifier_Enum)
+# define RTCrX509BasicConstraints_Compare               RT_MANGLER(RTCrX509BasicConstraints_Compare)
+# define RTCrX509BasicConstraints_Delete                RT_MANGLER(RTCrX509BasicConstraints_Delete)
+# define RTCrX509BasicConstraints_Enum                  RT_MANGLER(RTCrX509BasicConstraints_Enum)
+# define RTCrX509CertificatePolicies_Compare            RT_MANGLER(RTCrX509CertificatePolicies_Compare)
+# define RTCrX509CertificatePolicies_Delete             RT_MANGLER(RTCrX509CertificatePolicies_Delete)
+# define RTCrX509CertificatePolicies_Enum               RT_MANGLER(RTCrX509CertificatePolicies_Enum)
+# define RTCrX509Certificate_Compare                    RT_MANGLER(RTCrX509Certificate_Compare)
+# define RTCrX509Certificate_Delete                     RT_MANGLER(RTCrX509Certificate_Delete)
+# define RTCrX509Certificate_Enum                       RT_MANGLER(RTCrX509Certificate_Enum)
+# define RTCrX509Certificate_IsSelfSigned               RT_MANGLER(RTCrX509Certificate_IsSelfSigned)
+# define RTCrX509Certificate_MatchIssuerAndSerialNumber RT_MANGLER(RTCrX509Certificate_MatchIssuerAndSerialNumber)
+# define RTCrX509Certificate_MatchSubjectOrAltSubjectByRfc5280 RT_MANGLER(RTCrX509Certificate_MatchSubjectOrAltSubjectByRfc5280)
+# define RTCrX509Certificates_Compare                   RT_MANGLER(RTCrX509Certificates_Compare)
+# define RTCrX509Certificates_Delete                    RT_MANGLER(RTCrX509Certificates_Delete)
+# define RTCrX509Certificates_Enum                      RT_MANGLER(RTCrX509Certificates_Enum)
+# define RTCrX509Certificates_FindByIssuerAndSerialNumber RT_MANGLER(RTCrX509Certificates_FindByIssuerAndSerialNumber)
+# define RTCrX509Extension_Compare                      RT_MANGLER(RTCrX509Extension_Compare)
+# define RTCrX509Extension_Delete                       RT_MANGLER(RTCrX509Extension_Delete)
+# define RTCrX509Extension_Enum                         RT_MANGLER(RTCrX509Extension_Enum)
+# define RTCrX509Extensions_Compare                     RT_MANGLER(RTCrX509Extensions_Compare)
+# define RTCrX509Extensions_Delete                      RT_MANGLER(RTCrX509Extensions_Delete)
+# define RTCrX509Extensions_Enum                        RT_MANGLER(RTCrX509Extensions_Enum)
+# define RTCrX509GeneralName_Compare                    RT_MANGLER(RTCrX509GeneralName_Compare)
+# define RTCrX509GeneralName_ConstraintMatch            RT_MANGLER(RTCrX509GeneralName_ConstraintMatch)
+# define RTCrX509GeneralName_Delete                     RT_MANGLER(RTCrX509GeneralName_Delete)
+# define RTCrX509GeneralName_Enum                       RT_MANGLER(RTCrX509GeneralName_Enum)
+# define RTCrX509GeneralNames_Compare                   RT_MANGLER(RTCrX509GeneralNames_Compare)
+# define RTCrX509GeneralNames_Delete                    RT_MANGLER(RTCrX509GeneralNames_Delete)
+# define RTCrX509GeneralNames_Enum                      RT_MANGLER(RTCrX509GeneralNames_Enum)
+# define RTCrX509GeneralSubtree_Compare                 RT_MANGLER(RTCrX509GeneralSubtree_Compare)
+# define RTCrX509GeneralSubtree_ConstraintMatch         RT_MANGLER(RTCrX509GeneralSubtree_ConstraintMatch)
+# define RTCrX509GeneralSubtree_Delete                  RT_MANGLER(RTCrX509GeneralSubtree_Delete)
+# define RTCrX509GeneralSubtree_Enum                    RT_MANGLER(RTCrX509GeneralSubtree_Enum)
+# define RTCrX509GeneralSubtrees_Compare                RT_MANGLER(RTCrX509GeneralSubtrees_Compare)
+# define RTCrX509GeneralSubtrees_Delete                 RT_MANGLER(RTCrX509GeneralSubtrees_Delete)
+# define RTCrX509GeneralSubtrees_Enum                   RT_MANGLER(RTCrX509GeneralSubtrees_Enum)
+# define RTCrX509NameConstraints_Compare                RT_MANGLER(RTCrX509NameConstraints_Compare)
+# define RTCrX509NameConstraints_Delete                 RT_MANGLER(RTCrX509NameConstraints_Delete)
+# define RTCrX509NameConstraints_Enum                   RT_MANGLER(RTCrX509NameConstraints_Enum)
+# define RTCrX509Name_Compare                           RT_MANGLER(RTCrX509Name_Compare)
+# define RTCrX509Name_ConstraintMatch                   RT_MANGLER(RTCrX509Name_ConstraintMatch)
+# define RTCrX509Name_Delete                            RT_MANGLER(RTCrX509Name_Delete)
+# define RTCrX509Name_Enum                              RT_MANGLER(RTCrX509Name_Enum)
+# define RTCrX509Name_FormatAsString                    RT_MANGLER(RTCrX509Name_FormatAsString)
+# define RTCrX509Name_MatchByRfc5280                    RT_MANGLER(RTCrX509Name_MatchByRfc5280)
+# define RTCrX509Name_MatchWithString                   RT_MANGLER(RTCrX509Name_MatchWithString)
+# define RTCrX509OldAuthorityKeyIdentifier_Compare      RT_MANGLER(RTCrX509OldAuthorityKeyIdentifier_Compare)
+# define RTCrX509OldAuthorityKeyIdentifier_Delete       RT_MANGLER(RTCrX509OldAuthorityKeyIdentifier_Delete)
+# define RTCrX509OldAuthorityKeyIdentifier_Enum         RT_MANGLER(RTCrX509OldAuthorityKeyIdentifier_Enum)
+# define RTCrX509OtherName_Compare                      RT_MANGLER(RTCrX509OtherName_Compare)
+# define RTCrX509OtherName_Delete                       RT_MANGLER(RTCrX509OtherName_Delete)
+# define RTCrX509OtherName_Enum                         RT_MANGLER(RTCrX509OtherName_Enum)
+# define RTCrX509PolicyConstraints_Compare              RT_MANGLER(RTCrX509PolicyConstraints_Compare)
+# define RTCrX509PolicyConstraints_Delete               RT_MANGLER(RTCrX509PolicyConstraints_Delete)
+# define RTCrX509PolicyConstraints_Enum                 RT_MANGLER(RTCrX509PolicyConstraints_Enum)
+# define RTCrX509PolicyInformation_Compare              RT_MANGLER(RTCrX509PolicyInformation_Compare)
+# define RTCrX509PolicyInformation_Delete               RT_MANGLER(RTCrX509PolicyInformation_Delete)
+# define RTCrX509PolicyInformation_Enum                 RT_MANGLER(RTCrX509PolicyInformation_Enum)
+# define RTCrX509PolicyMapping_Compare                  RT_MANGLER(RTCrX509PolicyMapping_Compare)
+# define RTCrX509PolicyMapping_Delete                   RT_MANGLER(RTCrX509PolicyMapping_Delete)
+# define RTCrX509PolicyMapping_Enum                     RT_MANGLER(RTCrX509PolicyMapping_Enum)
+# define RTCrX509PolicyMappings_Compare                 RT_MANGLER(RTCrX509PolicyMappings_Compare)
+# define RTCrX509PolicyMappings_Delete                  RT_MANGLER(RTCrX509PolicyMappings_Delete)
+# define RTCrX509PolicyMappings_Enum                    RT_MANGLER(RTCrX509PolicyMappings_Enum)
+# define RTCrX509PolicyQualifierInfo_Compare            RT_MANGLER(RTCrX509PolicyQualifierInfo_Compare)
+# define RTCrX509PolicyQualifierInfo_Delete             RT_MANGLER(RTCrX509PolicyQualifierInfo_Delete)
+# define RTCrX509PolicyQualifierInfo_Enum               RT_MANGLER(RTCrX509PolicyQualifierInfo_Enum)
+# define RTCrX509PolicyQualifierInfos_Compare           RT_MANGLER(RTCrX509PolicyQualifierInfos_Compare)
+# define RTCrX509PolicyQualifierInfos_Delete            RT_MANGLER(RTCrX509PolicyQualifierInfos_Delete)
+# define RTCrX509PolicyQualifierInfos_Enum              RT_MANGLER(RTCrX509PolicyQualifierInfos_Enum)
+# define RTCrX509SubjectPublicKeyInfo_Compare           RT_MANGLER(RTCrX509SubjectPublicKeyInfo_Compare)
+# define RTCrX509SubjectPublicKeyInfo_Delete            RT_MANGLER(RTCrX509SubjectPublicKeyInfo_Delete)
+# define RTCrX509SubjectPublicKeyInfo_Enum              RT_MANGLER(RTCrX509SubjectPublicKeyInfo_Enum)
+# define RTCrX509TbsCertificate_Compare                 RT_MANGLER(RTCrX509TbsCertificate_Compare)
+# define RTCrX509TbsCertificate_Delete                  RT_MANGLER(RTCrX509TbsCertificate_Delete)
+# define RTCrX509TbsCertificate_Enum                    RT_MANGLER(RTCrX509TbsCertificate_Enum)
+# define RTCrX509TbsCertificate_ReprocessExtensions     RT_MANGLER(RTCrX509TbsCertificate_ReprocessExtensions)
+# define RTCrX509Validity_Compare                       RT_MANGLER(RTCrX509Validity_Compare)
+# define RTCrX509Validity_Delete                        RT_MANGLER(RTCrX509Validity_Delete)
+# define RTCrX509Validity_Enum                          RT_MANGLER(RTCrX509Validity_Enum)
+# define RTCrX509Validity_IsValidAtTimeSpec             RT_MANGLER(RTCrX509Validity_IsValidAtTimeSpec)
+# define RTCrX509Certificate_ReadFromFile               RT_MANGLER(RTCrX509Certificate_ReadFromFile)
+# define RTCrX509AlgorithmIdentifier_Clone              RT_MANGLER(RTCrX509AlgorithmIdentifier_Clone)
+# define RTCrX509AlgorithmIdentifier_Init               RT_MANGLER(RTCrX509AlgorithmIdentifier_Init)
+# define RTCrX509AlgorithmIdentifiers_Clone             RT_MANGLER(RTCrX509AlgorithmIdentifiers_Clone)
+# define RTCrX509AlgorithmIdentifiers_Init              RT_MANGLER(RTCrX509AlgorithmIdentifiers_Init)
+# define RTCrX509AttributeTypeAndValue_Clone            RT_MANGLER(RTCrX509AttributeTypeAndValue_Clone)
+# define RTCrX509AttributeTypeAndValue_Init             RT_MANGLER(RTCrX509AttributeTypeAndValue_Init)
+# define RTCrX509AttributeTypeAndValues_Clone           RT_MANGLER(RTCrX509AttributeTypeAndValues_Clone)
+# define RTCrX509AttributeTypeAndValues_Init            RT_MANGLER(RTCrX509AttributeTypeAndValues_Init)
+# define RTCrX509AuthorityKeyIdentifier_Clone           RT_MANGLER(RTCrX509AuthorityKeyIdentifier_Clone)
+# define RTCrX509AuthorityKeyIdentifier_Init            RT_MANGLER(RTCrX509AuthorityKeyIdentifier_Init)
+# define RTCrX509BasicConstraints_Clone                 RT_MANGLER(RTCrX509BasicConstraints_Clone)
+# define RTCrX509BasicConstraints_Init                  RT_MANGLER(RTCrX509BasicConstraints_Init)
+# define RTCrX509CertificatePolicies_Clone              RT_MANGLER(RTCrX509CertificatePolicies_Clone)
+# define RTCrX509CertificatePolicies_Init               RT_MANGLER(RTCrX509CertificatePolicies_Init)
+# define RTCrX509Certificate_Clone                      RT_MANGLER(RTCrX509Certificate_Clone)
+# define RTCrX509Certificate_Init                       RT_MANGLER(RTCrX509Certificate_Init)
+# define RTCrX509Certificates_Clone                     RT_MANGLER(RTCrX509Certificates_Clone)
+# define RTCrX509Certificates_Init                      RT_MANGLER(RTCrX509Certificates_Init)
+# define RTCrX509Extension_Clone                        RT_MANGLER(RTCrX509Extension_Clone)
+# define RTCrX509Extension_Init                         RT_MANGLER(RTCrX509Extension_Init)
+# define RTCrX509Extensions_Clone                       RT_MANGLER(RTCrX509Extensions_Clone)
+# define RTCrX509Extensions_Init                        RT_MANGLER(RTCrX509Extensions_Init)
+# define RTCrX509GeneralName_Clone                      RT_MANGLER(RTCrX509GeneralName_Clone)
+# define RTCrX509GeneralName_Init                       RT_MANGLER(RTCrX509GeneralName_Init)
+# define RTCrX509GeneralNames_Clone                     RT_MANGLER(RTCrX509GeneralNames_Clone)
+# define RTCrX509GeneralNames_Init                      RT_MANGLER(RTCrX509GeneralNames_Init)
+# define RTCrX509GeneralSubtree_Clone                   RT_MANGLER(RTCrX509GeneralSubtree_Clone)
+# define RTCrX509GeneralSubtree_Init                    RT_MANGLER(RTCrX509GeneralSubtree_Init)
+# define RTCrX509GeneralSubtrees_Clone                  RT_MANGLER(RTCrX509GeneralSubtrees_Clone)
+# define RTCrX509GeneralSubtrees_Init                   RT_MANGLER(RTCrX509GeneralSubtrees_Init)
+# define RTCrX509NameConstraints_Clone                  RT_MANGLER(RTCrX509NameConstraints_Clone)
+# define RTCrX509NameConstraints_Init                   RT_MANGLER(RTCrX509NameConstraints_Init)
+# define RTCrX509Name_Clone                             RT_MANGLER(RTCrX509Name_Clone)
+# define RTCrX509Name_Init                              RT_MANGLER(RTCrX509Name_Init)
+# define RTCrX509Name_RecodeAsUtf8                      RT_MANGLER(RTCrX509Name_RecodeAsUtf8)
+# define RTCrX509OldAuthorityKeyIdentifier_Clone        RT_MANGLER(RTCrX509OldAuthorityKeyIdentifier_Clone)
+# define RTCrX509OldAuthorityKeyIdentifier_Init         RT_MANGLER(RTCrX509OldAuthorityKeyIdentifier_Init)
+# define RTCrX509OtherName_Clone                        RT_MANGLER(RTCrX509OtherName_Clone)
+# define RTCrX509OtherName_Init                         RT_MANGLER(RTCrX509OtherName_Init)
+# define RTCrX509PolicyConstraints_Clone                RT_MANGLER(RTCrX509PolicyConstraints_Clone)
+# define RTCrX509PolicyConstraints_Init                 RT_MANGLER(RTCrX509PolicyConstraints_Init)
+# define RTCrX509PolicyInformation_Clone                RT_MANGLER(RTCrX509PolicyInformation_Clone)
+# define RTCrX509PolicyInformation_Init                 RT_MANGLER(RTCrX509PolicyInformation_Init)
+# define RTCrX509PolicyMapping_Clone                    RT_MANGLER(RTCrX509PolicyMapping_Clone)
+# define RTCrX509PolicyMapping_Init                     RT_MANGLER(RTCrX509PolicyMapping_Init)
+# define RTCrX509PolicyMappings_Clone                   RT_MANGLER(RTCrX509PolicyMappings_Clone)
+# define RTCrX509PolicyMappings_Init                    RT_MANGLER(RTCrX509PolicyMappings_Init)
+# define RTCrX509PolicyQualifierInfo_Clone              RT_MANGLER(RTCrX509PolicyQualifierInfo_Clone)
+# define RTCrX509PolicyQualifierInfo_Init               RT_MANGLER(RTCrX509PolicyQualifierInfo_Init)
+# define RTCrX509PolicyQualifierInfos_Clone             RT_MANGLER(RTCrX509PolicyQualifierInfos_Clone)
+# define RTCrX509PolicyQualifierInfos_Init              RT_MANGLER(RTCrX509PolicyQualifierInfos_Init)
+# define RTCrX509SubjectPublicKeyInfo_Clone             RT_MANGLER(RTCrX509SubjectPublicKeyInfo_Clone)
+# define RTCrX509SubjectPublicKeyInfo_Init              RT_MANGLER(RTCrX509SubjectPublicKeyInfo_Init)
+# define RTCrX509TbsCertificate_Clone                   RT_MANGLER(RTCrX509TbsCertificate_Clone)
+# define RTCrX509TbsCertificate_Init                    RT_MANGLER(RTCrX509TbsCertificate_Init)
+# define RTCrX509Validity_Clone                         RT_MANGLER(RTCrX509Validity_Clone)
+# define RTCrX509Validity_Init                          RT_MANGLER(RTCrX509Validity_Init)
+# define RTCrX509AlgorithmIdentifier_CheckSanity        RT_MANGLER(RTCrX509AlgorithmIdentifier_CheckSanity)
+# define RTCrX509AlgorithmIdentifiers_CheckSanity       RT_MANGLER(RTCrX509AlgorithmIdentifiers_CheckSanity)
+# define RTCrX509AttributeTypeAndValue_CheckSanity      RT_MANGLER(RTCrX509AttributeTypeAndValue_CheckSanity)
+# define RTCrX509AttributeTypeAndValues_CheckSanity     RT_MANGLER(RTCrX509AttributeTypeAndValues_CheckSanity)
+# define RTCrX509AuthorityKeyIdentifier_CheckSanity     RT_MANGLER(RTCrX509AuthorityKeyIdentifier_CheckSanity)
+# define RTCrX509BasicConstraints_CheckSanity           RT_MANGLER(RTCrX509BasicConstraints_CheckSanity)
+# define RTCrX509CertificatePolicies_CheckSanity        RT_MANGLER(RTCrX509CertificatePolicies_CheckSanity)
+# define RTCrX509Certificate_CheckSanity                RT_MANGLER(RTCrX509Certificate_CheckSanity)
+# define RTCrX509Certificates_CheckSanity               RT_MANGLER(RTCrX509Certificates_CheckSanity)
+# define RTCrX509Extension_CheckSanity                  RT_MANGLER(RTCrX509Extension_CheckSanity)
+# define RTCrX509Extensions_CheckSanity                 RT_MANGLER(RTCrX509Extensions_CheckSanity)
+# define RTCrX509GeneralName_CheckSanity                RT_MANGLER(RTCrX509GeneralName_CheckSanity)
+# define RTCrX509GeneralNames_CheckSanity               RT_MANGLER(RTCrX509GeneralNames_CheckSanity)
+# define RTCrX509GeneralSubtree_CheckSanity             RT_MANGLER(RTCrX509GeneralSubtree_CheckSanity)
+# define RTCrX509GeneralSubtrees_CheckSanity            RT_MANGLER(RTCrX509GeneralSubtrees_CheckSanity)
+# define RTCrX509NameConstraints_CheckSanity            RT_MANGLER(RTCrX509NameConstraints_CheckSanity)
+# define RTCrX509Name_CheckSanity                       RT_MANGLER(RTCrX509Name_CheckSanity)
+# define RTCrX509OldAuthorityKeyIdentifier_CheckSanity  RT_MANGLER(RTCrX509OldAuthorityKeyIdentifier_CheckSanity)
+# define RTCrX509OtherName_CheckSanity                  RT_MANGLER(RTCrX509OtherName_CheckSanity)
+# define RTCrX509PolicyConstraints_CheckSanity          RT_MANGLER(RTCrX509PolicyConstraints_CheckSanity)
+# define RTCrX509PolicyInformation_CheckSanity          RT_MANGLER(RTCrX509PolicyInformation_CheckSanity)
+# define RTCrX509PolicyMapping_CheckSanity              RT_MANGLER(RTCrX509PolicyMapping_CheckSanity)
+# define RTCrX509PolicyMappings_CheckSanity             RT_MANGLER(RTCrX509PolicyMappings_CheckSanity)
+# define RTCrX509PolicyQualifierInfo_CheckSanity        RT_MANGLER(RTCrX509PolicyQualifierInfo_CheckSanity)
+# define RTCrX509PolicyQualifierInfos_CheckSanity       RT_MANGLER(RTCrX509PolicyQualifierInfos_CheckSanity)
+# define RTCrX509SubjectPublicKeyInfo_CheckSanity       RT_MANGLER(RTCrX509SubjectPublicKeyInfo_CheckSanity)
+# define RTCrX509TbsCertificate_CheckSanity             RT_MANGLER(RTCrX509TbsCertificate_CheckSanity)
+# define RTCrX509Validity_CheckSanity                   RT_MANGLER(RTCrX509Validity_CheckSanity)
+# define RTCrX509Certificate_VerifySignature            RT_MANGLER(RTCrX509Certificate_VerifySignature)
+# define RTCrTafCertPathControls_DecodeAsn1             RT_MANGLER(RTCrTafCertPathControls_DecodeAsn1)
+# define RTCrTafTrustAnchorChoice_DecodeAsn1            RT_MANGLER(RTCrTafTrustAnchorChoice_DecodeAsn1)
+# define RTCrTafTrustAnchorInfo_DecodeAsn1              RT_MANGLER(RTCrTafTrustAnchorInfo_DecodeAsn1)
+# define RTCrTafTrustAnchorList_DecodeAsn1              RT_MANGLER(RTCrTafTrustAnchorList_DecodeAsn1)
+# define RTCrTafCertPathControls_Compare                RT_MANGLER(RTCrTafCertPathControls_Compare)
+# define RTCrTafCertPathControls_Delete                 RT_MANGLER(RTCrTafCertPathControls_Delete)
+# define RTCrTafCertPathControls_Enum                   RT_MANGLER(RTCrTafCertPathControls_Enum)
+# define RTCrTafTrustAnchorChoice_Compare               RT_MANGLER(RTCrTafTrustAnchorChoice_Compare)
+# define RTCrTafTrustAnchorChoice_Delete                RT_MANGLER(RTCrTafTrustAnchorChoice_Delete)
+# define RTCrTafTrustAnchorChoice_Enum                  RT_MANGLER(RTCrTafTrustAnchorChoice_Enum)
+# define RTCrTafTrustAnchorInfo_Compare                 RT_MANGLER(RTCrTafTrustAnchorInfo_Compare)
+# define RTCrTafTrustAnchorInfo_Delete                  RT_MANGLER(RTCrTafTrustAnchorInfo_Delete)
+# define RTCrTafTrustAnchorInfo_Enum                    RT_MANGLER(RTCrTafTrustAnchorInfo_Enum)
+# define RTCrTafTrustAnchorList_Compare                 RT_MANGLER(RTCrTafTrustAnchorList_Compare)
+# define RTCrTafTrustAnchorList_Delete                  RT_MANGLER(RTCrTafTrustAnchorList_Delete)
+# define RTCrTafTrustAnchorList_Enum                    RT_MANGLER(RTCrTafTrustAnchorList_Enum)
+# define RTCrTafCertPathControls_Clone                  RT_MANGLER(RTCrTafCertPathControls_Clone)
+# define RTCrTafCertPathControls_Init                   RT_MANGLER(RTCrTafCertPathControls_Init)
+# define RTCrTafTrustAnchorChoice_Clone                 RT_MANGLER(RTCrTafTrustAnchorChoice_Clone)
+# define RTCrTafTrustAnchorChoice_Init                  RT_MANGLER(RTCrTafTrustAnchorChoice_Init)
+# define RTCrTafTrustAnchorInfo_Clone                   RT_MANGLER(RTCrTafTrustAnchorInfo_Clone)
+# define RTCrTafTrustAnchorInfo_Init                    RT_MANGLER(RTCrTafTrustAnchorInfo_Init)
+# define RTCrTafTrustAnchorList_Clone                   RT_MANGLER(RTCrTafTrustAnchorList_Clone)
+# define RTCrTafTrustAnchorList_Init                    RT_MANGLER(RTCrTafTrustAnchorList_Init)
+# define RTCrTafCertPathControls_CheckSanity            RT_MANGLER(RTCrTafCertPathControls_CheckSanity)
+# define RTCrTafTrustAnchorChoice_CheckSanity           RT_MANGLER(RTCrTafTrustAnchorChoice_CheckSanity)
+# define RTCrTafTrustAnchorInfo_CheckSanity             RT_MANGLER(RTCrTafTrustAnchorInfo_CheckSanity)
+# define RTCrTafTrustAnchorList_CheckSanity             RT_MANGLER(RTCrTafTrustAnchorList_CheckSanity)
+# define RTCrTspAccuracy_CheckSanity                    RT_MANGLER(RTCrTspAccuracy_CheckSanity)
+# define RTCrTspAccuracy_Clone                          RT_MANGLER(RTCrTspAccuracy_Clone)
+# define RTCrTspAccuracy_Compare                        RT_MANGLER(RTCrTspAccuracy_Compare)
+# define RTCrTspAccuracy_DecodeAsn1                     RT_MANGLER(RTCrTspAccuracy_DecodeAsn1)
+# define RTCrTspAccuracy_Delete                         RT_MANGLER(RTCrTspAccuracy_Delete)
+# define RTCrTspAccuracy_Enum                           RT_MANGLER(RTCrTspAccuracy_Enum)
+# define RTCrTspAccuracy_Init                           RT_MANGLER(RTCrTspAccuracy_Init)
+# define RTCrTspMessageImprint_CheckSanity              RT_MANGLER(RTCrTspMessageImprint_CheckSanity)
+# define RTCrTspMessageImprint_Clone                    RT_MANGLER(RTCrTspMessageImprint_Clone)
+# define RTCrTspMessageImprint_Compare                  RT_MANGLER(RTCrTspMessageImprint_Compare)
+# define RTCrTspMessageImprint_DecodeAsn1               RT_MANGLER(RTCrTspMessageImprint_DecodeAsn1)
+# define RTCrTspMessageImprint_Delete                   RT_MANGLER(RTCrTspMessageImprint_Delete)
+# define RTCrTspMessageImprint_Enum                     RT_MANGLER(RTCrTspMessageImprint_Enum)
+# define RTCrTspMessageImprint_Init                     RT_MANGLER(RTCrTspMessageImprint_Init)
+# define RTCrTspTstInfo_CheckSanity                     RT_MANGLER(RTCrTspTstInfo_CheckSanity)
+# define RTCrTspTstInfo_Clone                           RT_MANGLER(RTCrTspTstInfo_Clone)
+# define RTCrTspTstInfo_Compare                         RT_MANGLER(RTCrTspTstInfo_Compare)
+# define RTCrTspTstInfo_DecodeAsn1                      RT_MANGLER(RTCrTspTstInfo_DecodeAsn1)
+# define RTCrTspTstInfo_Delete                          RT_MANGLER(RTCrTspTstInfo_Delete)
+# define RTCrTspTstInfo_Enum                            RT_MANGLER(RTCrTspTstInfo_Enum)
+# define RTCrTspTstInfo_Init                            RT_MANGLER(RTCrTspTstInfo_Init)
+# define RTCrCertCtxRelease                             RT_MANGLER(RTCrCertCtxRelease)
+# define RTCrCertCtxRetain                              RT_MANGLER(RTCrCertCtxRetain)
+# define RTCrStoreCertAddEncoded                        RT_MANGLER(RTCrStoreCertAddEncoded)
+# define RTCrStoreCertByIssuerAndSerialNo               RT_MANGLER(RTCrStoreCertByIssuerAndSerialNo)
+# define RTCrStoreCertCount                             RT_MANGLER(RTCrStoreCertCount)
+# define RTCrStoreCertFindAll                           RT_MANGLER(RTCrStoreCertFindAll)
+# define RTCrStoreCertFindBySubjectOrAltSubjectByRfc5280 RT_MANGLER(RTCrStoreCertFindBySubjectOrAltSubjectByRfc5280)
+# define RTCrStoreCertSearchDestroy                     RT_MANGLER(RTCrStoreCertSearchDestroy)
+# define RTCrStoreCertSearchNext                        RT_MANGLER(RTCrStoreCertSearchNext)
+# define RTCrStoreConvertToOpenSslCertStack             RT_MANGLER(RTCrStoreConvertToOpenSslCertStack)
+# define RTCrStoreConvertToOpenSslCertStore             RT_MANGLER(RTCrStoreConvertToOpenSslCertStore)
+# define RTCrStoreRelease                               RT_MANGLER(RTCrStoreRelease)
+# define RTCrStoreRetain                                RT_MANGLER(RTCrStoreRetain)
+# define RTCrStoreCreateInMem                           RT_MANGLER(RTCrStoreCreateInMem)
+# define RTCrStoreCreateSnapshotById                    RT_MANGLER(RTCrStoreCreateSnapshotById)
+# define RTCrStoreCertAddFromDir                        RT_MANGLER(RTCrStoreCertAddFromDir)
+# define RTCrStoreCertAddFromFile                       RT_MANGLER(RTCrStoreCertAddFromFile)
+# define RTCrStoreCertAddFromJavaKeyStore               RT_MANGLER(RTCrStoreCertAddFromJavaKeyStore)
+# define RTCrStoreCertAddFromJavaKeyStoreInMem          RT_MANGLER(RTCrStoreCertAddFromJavaKeyStoreInMem)
+# define RTCrStoreCertAddFromStore                      RT_MANGLER(RTCrStoreCertAddFromStore)
+# define RTCrStoreCertAddWantedFromDir                  RT_MANGLER(RTCrStoreCertAddWantedFromDir)
+# define RTCrStoreCertAddWantedFromFile                 RT_MANGLER(RTCrStoreCertAddWantedFromFile)
+# define RTCrStoreCertAddWantedFromStore                RT_MANGLER(RTCrStoreCertAddWantedFromStore)
+# define RTCrStoreCertAddWantedFromFishingExpedition    RT_MANGLER(RTCrStoreCertAddWantedFromFishingExpedition)
+# define RTCrStoreCertCheckWanted                       RT_MANGLER(RTCrStoreCertCheckWanted)
+# define RTCrStoreCertExportAsPem                       RT_MANGLER(RTCrStoreCertExportAsPem)
+# define RTErrInfoAdd                                   RT_MANGLER(RTErrInfoAdd)
+# define RTErrInfoAddF                                  RT_MANGLER(RTErrInfoAddF)
+# define RTErrInfoAddV                                  RT_MANGLER(RTErrInfoAddV)
+# define RTLdrHashImage                                 RT_MANGLER(RTLdrHashImage)
+# define RTLdrOpenWithReader                            RT_MANGLER(RTLdrOpenWithReader)
+# define RTLdrQueryPropEx                               RT_MANGLER(RTLdrQueryPropEx)
+# define RTLdrVerifySignature                           RT_MANGLER(RTLdrVerifySignature)
+# define RTBigNumAdd                                    RT_MANGLER(RTBigNumAdd)
+# define RTBigNumAssign                                 RT_MANGLER(RTBigNumAssign)
+# define RTBigNumBitWidth                               RT_MANGLER(RTBigNumBitWidth)
+# define RTBigNumByteWidth                              RT_MANGLER(RTBigNumByteWidth)
+# define RTBigNumClone                                  RT_MANGLER(RTBigNumClone)
+# define RTBigNumCompare                                RT_MANGLER(RTBigNumCompare)
+# define RTBigNumCompareWithS64                         RT_MANGLER(RTBigNumCompareWithS64)
+# define RTBigNumCompareWithU64                         RT_MANGLER(RTBigNumCompareWithU64)
+# define RTBigNumDestroy                                RT_MANGLER(RTBigNumDestroy)
+# define RTBigNumDivide                                 RT_MANGLER(RTBigNumDivide)
+# define RTBigNumDivideKnuth                            RT_MANGLER(RTBigNumDivideKnuth)
+# define RTBigNumDivideLong                             RT_MANGLER(RTBigNumDivideLong)
+# define RTBigNumExponentiate                           RT_MANGLER(RTBigNumExponentiate)
+# define RTBigNumInit                                   RT_MANGLER(RTBigNumInit)
+# define RTBigNumInitZero                               RT_MANGLER(RTBigNumInitZero)
+# define RTBigNumModExp                                 RT_MANGLER(RTBigNumModExp)
+# define RTBigNumModulo                                 RT_MANGLER(RTBigNumModulo)
+# define RTBigNumMultiply                               RT_MANGLER(RTBigNumMultiply)
+# define RTBigNumNegate                                 RT_MANGLER(RTBigNumNegate)
+# define RTBigNumNegateThis                             RT_MANGLER(RTBigNumNegateThis)
+# define RTBigNumShiftLeft                              RT_MANGLER(RTBigNumShiftLeft)
+# define RTBigNumShiftRight                             RT_MANGLER(RTBigNumShiftRight)
+# define RTBigNumSubtract                               RT_MANGLER(RTBigNumSubtract)
+# define RTBigNumToBytesBigEndian                       RT_MANGLER(RTBigNumToBytesBigEndian)
+# define RTUInt128MulByU64                              RT_MANGLER(RTUInt128MulByU64)
+# define RTUInt128MulByU64_EndProc                      RT_MANGLER(RTUInt128MulByU64_EndProc)
+# define RTUtf16Copy                                    RT_MANGLER(RTUtf16Copy)
+# define RTUtf16CopyAscii                               RT_MANGLER(RTUtf16CopyAscii)
+# define RTUtf16Cat                                     RT_MANGLER(RTUtf16Cat)
+# define RTUtf16CatAscii                                RT_MANGLER(RTUtf16CatAscii)
+# define RTUtf16End                                     RT_MANGLER(RTUtf16End)
+# define RTUtf16ICmpAscii                               RT_MANGLER(RTUtf16ICmpAscii)
+# define RTUtf16NLen                                    RT_MANGLER(RTUtf16NLen)
+# define RTUtf16NLenEx                                  RT_MANGLER(RTUtf16NLenEx)
+# define RTUtf16PrintHexBytes                           RT_MANGLER(RTUtf16PrintHexBytes)
+# define RTMemSaferAllocZExTag                          RT_MANGLER(RTMemSaferAllocZExTag)
+# define RTMemSaferAllocZTag                            RT_MANGLER(RTMemSaferAllocZTag)
+# define RTMemSaferFree                                 RT_MANGLER(RTMemSaferFree)
+# define RTMemSaferReallocZExTag                        RT_MANGLER(RTMemSaferReallocZExTag)
+# define RTMemSaferReallocZTag                          RT_MANGLER(RTMemSaferReallocZTag)
+# define RTMemSaferScramble                             RT_MANGLER(RTMemSaferScramble)
+# define RTMemSaferUnscramble                           RT_MANGLER(RTMemSaferUnscramble)
+# define RTErrConvertFromDarwin                         RT_MANGLER(RTErrConvertFromDarwin)
+# define RTErrConvertFromDarwinCOM                      RT_MANGLER(RTErrConvertFromDarwinCOM)
+# define RTErrConvertFromDarwinIO                       RT_MANGLER(RTErrConvertFromDarwinIO)
+# define RTErrConvertFromDarwinKern                     RT_MANGLER(RTErrConvertFromDarwinKern)
+# define RTErrConvertFromDarwin                         RT_MANGLER(RTErrConvertFromDarwin)
+# define RTErrConvertFromDarwinIO                       RT_MANGLER(RTErrConvertFromDarwinIO)
+# define RTErrConvertFromDarwinKern                     RT_MANGLER(RTErrConvertFromDarwinKern)
+
+/*
+ * Stable variables (alphabetical order):
+ */
+# define g_apfnRTZlibDeps                               RT_MANGLER(g_apfnRTZlibDeps) /* os2 win solaris */
+# define g_aRTUniFlagsRanges                            RT_MANGLER(g_aRTUniFlagsRanges)
+# define g_aRTUniLowerRanges                            RT_MANGLER(g_aRTUniLowerRanges)
+# define g_aRTUniUpperRanges                            RT_MANGLER(g_aRTUniUpperRanges)
+# define g_fRTAlignmentChecks                           RT_MANGLER(g_fRTAlignmentChecks)
+# define g_hKrnlDbgInfo                                 RT_MANGLER(g_hKrnlDbgInfo) /* solaris */
+# define g_pStdErr                                      RT_MANGLER(g_pStdErr)
+# define g_pStdIn                                       RT_MANGLER(g_pStdIn)
+# define g_pStdOut                                      RT_MANGLER(g_pStdOut)
+# define g_pszRTAssertExpr                              RT_MANGLER(g_pszRTAssertExpr)
+# define g_pszRTAssertFile                              RT_MANGLER(g_pszRTAssertFile)
+# define g_pszRTAssertFunction                          RT_MANGLER(g_pszRTAssertFunction)
+# define g_szRTAssertMsg1                               RT_MANGLER(g_szRTAssertMsg1)
+# define g_szRTAssertMsg2                               RT_MANGLER(g_szRTAssertMsg2)
+# define g_u32RTAssertLine                              RT_MANGLER(g_u32RTAssertLine)
+
+/* sort/merge into the above later: */
+# define g_RTAsn1Time_Vtable                            RT_MANGLER(g_RTAsn1Time_Vtable)
+# define g_RTAsn1String_Vtable                          RT_MANGLER(g_RTAsn1String_Vtable)
+# define g_RTAsn1OctetString_Vtable                     RT_MANGLER(g_RTAsn1OctetString_Vtable)
+# define g_RTAsn1ObjId_Vtable                           RT_MANGLER(g_RTAsn1ObjId_Vtable)
+# define g_RTAsn1Null_Vtable                            RT_MANGLER(g_RTAsn1Null_Vtable)
+# define g_RTAsn1Integer_Vtable                         RT_MANGLER(g_RTAsn1Integer_Vtable)
+# define g_RTAsn1Core_Vtable                            RT_MANGLER(g_RTAsn1Core_Vtable)
+# define g_RTAsn1Boolean_Vtable                         RT_MANGLER(g_RTAsn1Boolean_Vtable)
+# define g_RTAsn1BitString_Vtable                       RT_MANGLER(g_RTAsn1BitString_Vtable)
+# define g_RTAsn1DefaultAllocator                       RT_MANGLER(g_RTAsn1DefaultAllocator)
+# define g_RTAsn1EFenceAllocator                        RT_MANGLER(g_RTAsn1EFenceAllocator)
+#if 0 /* Disabled for now as I'm not sure the assmbler supports mangling yet. */
+# define g_abRTZeroPage                                 RT_MANGLER(g_abRTZeroPage)
+# define g_abRTZero4K                                   RT_MANGLER(g_abRTZero4K)
+# define g_abRTZero8K                                   RT_MANGLER(g_abRTZero8K)
+# define g_abRTZero16K                                  RT_MANGLER(g_abRTZero16K)
+# define g_abRTZero32K                                  RT_MANGLER(g_abRTZero32K)
+# define g_abRTZero64K                                  RT_MANGLER(g_abRTZero64K)
+#endif
+
+
+/*
+ * Unstable functions (alphabetical order):
+ */
+/** @todo the list is incomplete! See the .def files + libraries. */
+
+
+/*
+ * Unstable variables (alphabetical order):
+ */
+/* none */
+
+#endif /* !DOXYGEN_RUNNING */
+
+#endif
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/include/iprt/mem.h
@@ -0,0 +1,956 @@
+/** @file
+ * IPRT - Memory Management and Manipulation.
+ */
+
+/*
+ * Copyright (C) 2006-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+#ifndef ___iprt_mem_h
+#define ___iprt_mem_h
+
+
+#include <iprt/cdefs.h>
+#include <iprt/types.h>
+
+
+#ifdef IN_RC
+# error "There are no RTMem APIs available Guest Context!"
+#endif
+
+
+/** @defgroup grp_rt_mem    RTMem - Memory Management and Manipulation
+ * @ingroup grp_rt
+ * @{
+ */
+
+RT_C_DECLS_BEGIN
+
+/** @def RTMEM_ALIGNMENT
+ * The alignment of the memory blocks returned by RTMemAlloc(), RTMemAllocZ(),
+ * RTMemRealloc(), RTMemTmpAlloc() and RTMemTmpAllocZ() for allocations greater
+ * than RTMEM_ALIGNMENT.
+ *
+ * @note This alignment is not forced if the electric fence is active!
+ */
+#if defined(RT_OS_OS2)
+# define RTMEM_ALIGNMENT    4
+#else
+# define RTMEM_ALIGNMENT    8
+#endif
+
+/** @def RTMEM_TAG
+ * The default allocation tag used by the RTMem allocation APIs.
+ *
+ * When not defined before the inclusion of iprt/mem.h or iprt/memobj.h, this
+ * will default to the pointer to the current file name.  The memory API will
+ * make of use of this as pointer to a volatile but read-only string.
+ * The alternative tag includes the line number for a more-detailed analysis.
+ */
+#ifndef RTMEM_TAG
+# if 0
+#  define RTMEM_TAG   (__FILE__ ":" RT_XSTR(__LINE__))
+# else
+#  define RTMEM_TAG   (__FILE__)
+# endif
+#endif
+
+
+/** @name Allocate temporary memory.
+ * @{ */
+/**
+ * Allocates temporary memory with default tag.
+ *
+ * Temporary memory blocks are used for not too large memory blocks which
+ * are believed not to stick around for too long. Using this API instead
+ * of RTMemAlloc() not only gives the heap manager room for optimization
+ * but makes the code easier to read.
+ *
+ * @returns Pointer to the allocated memory.
+ * @returns NULL on failure, assertion raised in strict builds.
+ * @param   cb      Size in bytes of the memory block to allocated.
+ */
+#define RTMemTmpAlloc(cb)               RTMemTmpAllocTag((cb), RTMEM_TAG)
+
+/**
+ * Allocates temporary memory with custom tag.
+ *
+ * Temporary memory blocks are used for not too large memory blocks which
+ * are believed not to stick around for too long. Using this API instead
+ * of RTMemAlloc() not only gives the heap manager room for optimization
+ * but makes the code easier to read.
+ *
+ * @returns Pointer to the allocated memory.
+ * @returns NULL on failure, assertion raised in strict builds.
+ * @param   cb      Size in bytes of the memory block to allocated.
+ * @param   pszTag  Allocation tag used for statistics and such.
+ */
+RTDECL(void *)  RTMemTmpAllocTag(size_t cb, const char *pszTag) RT_NO_THROW_PROTO;
+
+/**
+ * Allocates zero'd temporary memory with default tag.
+ *
+ * Same as RTMemTmpAlloc() but the memory will be zero'd.
+ *
+ * @returns Pointer to the allocated memory.
+ * @returns NULL on failure, assertion raised in strict builds.
+ * @param   cb      Size in bytes of the memory block to allocated.
+ */
+#define RTMemTmpAllocZ(cb)              RTMemTmpAllocZTag((cb), RTMEM_TAG)
+
+/**
+ * Allocates zero'd temporary memory with custom tag.
+ *
+ * Same as RTMemTmpAlloc() but the memory will be zero'd.
+ *
+ * @returns Pointer to the allocated memory.
+ * @returns NULL on failure, assertion raised in strict builds.
+ * @param   cb      Size in bytes of the memory block to allocated.
+ * @param   pszTag  Allocation tag used for statistics and such.
+ */
+RTDECL(void *)  RTMemTmpAllocZTag(size_t cb, const char *pszTag) RT_NO_THROW_PROTO;
+
+/**
+ * Free temporary memory.
+ *
+ * @param   pv      Pointer to memory block.
+ */
+RTDECL(void)    RTMemTmpFree(void *pv) RT_NO_THROW_PROTO;
+
+/** @}  */
+
+
+/**
+ * Allocates memory with default tag.
+ *
+ * @returns Pointer to the allocated memory.
+ * @returns NULL on failure, assertion raised in strict builds.
+ * @param   cb      Size in bytes of the memory block to allocated.
+ */
+#define RTMemAlloc(cb)                  RTMemAllocTag((cb), RTMEM_TAG)
+
+/**
+ * Allocates memory with custom tag.
+ *
+ * @returns Pointer to the allocated memory.
+ * @returns NULL on failure, assertion raised in strict builds.
+ * @param   cb      Size in bytes of the memory block to allocated.
+ * @param   pszTag  Allocation tag used for statistics and such.
+ */
+RTDECL(void *)  RTMemAllocTag(size_t cb, const char *pszTag) RT_NO_THROW_PROTO;
+
+/**
+ * Allocates zero'd memory with default tag.
+ *
+ * Instead of memset(pv, 0, sizeof()) use this when you want zero'd
+ * memory. This keeps the code smaller and the heap can skip the memset
+ * in about 0.42% of calls :-).
+ *
+ * @returns Pointer to the allocated memory.
+ * @returns NULL on failure.
+ * @param   cb      Size in bytes of the memory block to allocated.
+ */
+#define RTMemAllocZ(cb)                 RTMemAllocZTag((cb), RTMEM_TAG)
+
+/**
+ * Allocates zero'd memory with custom tag.
+ *
+ * Instead of memset(pv, 0, sizeof()) use this when you want zero'd
+ * memory. This keeps the code smaller and the heap can skip the memset
+ * in about 0.42% of calls :-).
+ *
+ * @returns Pointer to the allocated memory.
+ * @returns NULL on failure.
+ * @param   cb      Size in bytes of the memory block to allocated.
+ * @param   pszTag  Allocation tag used for statistics and such.
+ */
+RTDECL(void *)  RTMemAllocZTag(size_t cb, const char *pszTag) RT_NO_THROW_PROTO;
+
+/**
+ * Wrapper around RTMemAlloc for automatically aligning variable sized
+ * allocations so that the various electric fence heaps works correctly.
+ *
+ * @returns See RTMemAlloc.
+ * @param   cbUnaligned         The unaligned size.
+ */
+#define RTMemAllocVar(cbUnaligned)      RTMemAllocVarTag((cbUnaligned), RTMEM_TAG)
+
+/**
+ * Wrapper around RTMemAllocTag for automatically aligning variable sized
+ * allocations so that the various electric fence heaps works correctly.
+ *
+ * @returns See RTMemAlloc.
+ * @param   cbUnaligned         The unaligned size.
+ * @param   pszTag              Allocation tag used for statistics and such.
+ */
+RTDECL(void *) RTMemAllocVarTag(size_t cbUnaligned, const char *pszTag) RT_NO_THROW_PROTO;
+
+/**
+ * Wrapper around RTMemAllocZ for automatically aligning variable sized
+ * allocations so that the various electric fence heaps works correctly.
+ *
+ * @returns See RTMemAllocZ.
+ * @param   cbUnaligned         The unaligned size.
+ */
+#define RTMemAllocZVar(cbUnaligned)     RTMemAllocZVarTag((cbUnaligned), RTMEM_TAG)
+
+/**
+ * Wrapper around RTMemAllocZTag for automatically aligning variable sized
+ * allocations so that the various electric fence heaps works correctly.
+ *
+ * @returns See RTMemAllocZ.
+ * @param   cbUnaligned         The unaligned size.
+ * @param   pszTag              Allocation tag used for statistics and such.
+ */
+RTDECL(void *) RTMemAllocZVarTag(size_t cbUnaligned, const char *pszTag) RT_NO_THROW_PROTO;
+
+/**
+ * Duplicates a chunk of memory into a new heap block (default tag).
+ *
+ * @returns New heap block with the duplicate data.
+ * @returns NULL if we're out of memory.
+ * @param   pvSrc   The memory to duplicate.
+ * @param   cb      The amount of memory to duplicate.
+ */
+#define RTMemDup(pvSrc, cb)             RTMemDupTag((pvSrc), (cb), RTMEM_TAG)
+
+/**
+ * Duplicates a chunk of memory into a new heap block (custom tag).
+ *
+ * @returns New heap block with the duplicate data.
+ * @returns NULL if we're out of memory.
+ * @param   pvSrc   The memory to duplicate.
+ * @param   cb      The amount of memory to duplicate.
+ * @param   pszTag  Allocation tag used for statistics and such.
+ */
+RTDECL(void *) RTMemDupTag(const void *pvSrc, size_t cb, const char *pszTag) RT_NO_THROW_PROTO;
+
+/**
+ * Duplicates a chunk of memory into a new heap block with some additional
+ * zeroed memory (default tag).
+ *
+ * @returns New heap block with the duplicate data.
+ * @returns NULL if we're out of memory.
+ * @param   pvSrc   The memory to duplicate.
+ * @param   cbSrc   The amount of memory to duplicate.
+ * @param   cbExtra The amount of extra memory to allocate and zero.
+ */
+#define RTMemDupEx(pvSrc, cbSrc, cbExtra)   RTMemDupExTag((pvSrc), (cbSrc), (cbExtra), RTMEM_TAG)
+
+/**
+ * Duplicates a chunk of memory into a new heap block with some additional
+ * zeroed memory (default tag).
+ *
+ * @returns New heap block with the duplicate data.
+ * @returns NULL if we're out of memory.
+ * @param   pvSrc   The memory to duplicate.
+ * @param   cbSrc   The amount of memory to duplicate.
+ * @param   cbExtra The amount of extra memory to allocate and zero.
+ * @param   pszTag  Allocation tag used for statistics and such.
+ */
+RTDECL(void *) RTMemDupExTag(const void *pvSrc, size_t cbSrc, size_t cbExtra, const char *pszTag) RT_NO_THROW_PROTO;
+
+/**
+ * Reallocates memory with default tag.
+ *
+ * @returns Pointer to the allocated memory.
+ * @returns NULL on failure.
+ * @param   pvOld   The memory block to reallocate.
+ * @param   cbNew   The new block size (in bytes).
+ */
+#define RTMemRealloc(pvOld, cbNew)          RTMemReallocTag((pvOld), (cbNew), RTMEM_TAG)
+
+/**
+ * Reallocates memory with custom tag.
+ *
+ * @returns Pointer to the allocated memory.
+ * @returns NULL on failure.
+ * @param   pvOld   The memory block to reallocate.
+ * @param   cbNew   The new block size (in bytes).
+ * @param   pszTag  Allocation tag used for statistics and such.
+ */
+RTDECL(void *)  RTMemReallocTag(void *pvOld, size_t cbNew, const char *pszTag) RT_NO_THROW_PROTO;
+
+/**
+ * Frees memory.
+ *
+ * @param   pv      Pointer to memory block.
+ */
+RTDECL(void)    RTMemFree(void *pv) RT_NO_THROW_PROTO;
+
+
+
+/** @name RTR0MemAllocEx and RTR0MemAllocExTag flags.
+ * @{ */
+/** The returned memory should be zeroed. */
+#define RTMEMALLOCEX_FLAGS_ZEROED           RT_BIT(0)
+/** It must be load code into the returned memory block and execute it. */
+#define RTMEMALLOCEX_FLAGS_EXEC             RT_BIT(1)
+/** Allocation from any context.
+ * Will return VERR_NOT_SUPPORTED if not supported.  */
+#define RTMEMALLOCEX_FLAGS_ANY_CTX_ALLOC    RT_BIT(2)
+/** Allocate the memory such that it can be freed from any context.
+ * Will return VERR_NOT_SUPPORTED if not supported. */
+#define RTMEMALLOCEX_FLAGS_ANY_CTX_FREE     RT_BIT(3)
+/** Allocate and free from any context.
+ * Will return VERR_NOT_SUPPORTED if not supported. */
+#define RTMEMALLOCEX_FLAGS_ANY_CTX          (RTMEMALLOCEX_FLAGS_ANY_CTX_ALLOC | RTMEMALLOCEX_FLAGS_ANY_CTX_FREE)
+/** Reachable by 16-bit address.
+ * Will return VERR_NOT_SUPPORTED if not supported.  */
+#define RTMEMALLOCEX_FLAGS_16BIT_REACH      RT_BIT(4)
+/** Reachable by 32-bit address.
+ * Will return VERR_NOT_SUPPORTED if not supported.  */
+#define RTMEMALLOCEX_FLAGS_32BIT_REACH      RT_BIT(5)
+/** Mask of valid flags. */
+#define RTMEMALLOCEX_FLAGS_VALID_MASK       UINT32_C(0x0000003f)
+/** Mask of valid flags for ring-0. */
+#define RTMEMALLOCEX_FLAGS_VALID_MASK_R0    UINT32_C(0x0000000f)
+/** @}  */
+
+/**
+ * Extended heap allocation API, default tag.
+ *
+ * @returns IPRT status code.
+ * @retval  VERR_NO_MEMORY if we're out of memory.
+ * @retval  VERR_NO_EXEC_MEMORY if we're out of executable memory.
+ * @retval  VERR_NOT_SUPPORTED if any of the specified flags are unsupported.
+ *
+ * @param   cb                  The amount of memory to allocate.
+ * @param   cbAlignment         The alignment requirements.  Use 0 to indicate
+ *                              default alignment.
+ * @param   fFlags              A combination of the RTMEMALLOCEX_FLAGS_XXX
+ *                              defines.
+ * @param   ppv                 Where to return the memory.
+ */
+#define RTMemAllocEx(cb, cbAlignment, fFlags, ppv) RTMemAllocExTag((cb), (cbAlignment), (fFlags), RTMEM_TAG, (ppv))
+
+/**
+ * Extended heap allocation API, custom tag.
+ *
+ * Depending on the implementation, using this function may add extra overhead,
+ * so use the simpler APIs where ever possible.
+ *
+ * @returns IPRT status code.
+ * @retval  VERR_NO_MEMORY if we're out of memory.
+ * @retval  VERR_NO_EXEC_MEMORY if we're out of executable memory.
+ * @retval  VERR_NOT_SUPPORTED if any of the specified flags are unsupported.
+ *
+ * @param   cb                  The amount of memory to allocate.
+ * @param   cbAlignment         The alignment requirements.  Use 0 to indicate
+ *                              default alignment.
+ * @param   fFlags              A combination of the RTMEMALLOCEX_FLAGS_XXX
+ *                              defines.
+ * @param   pszTag              The tag.
+ * @param   ppv                 Where to return the memory.
+ */
+RTDECL(int) RTMemAllocExTag(size_t cb, size_t cbAlignment, uint32_t fFlags, const char *pszTag, void **ppv) RT_NO_THROW_PROTO;
+
+/**
+ * For freeing memory allocated by RTMemAllocEx or RTMemAllocExTag.
+ *
+ * @param   pv                  What to free, NULL is fine.
+ * @param   cb                  The amount of allocated memory.
+ */
+RTDECL(void) RTMemFreeEx(void *pv, size_t cb) RT_NO_THROW_PROTO;
+
+
+
+/**
+ * Allocates memory which may contain code (default tag).
+ *
+ * @returns Pointer to the allocated memory.
+ * @returns NULL on failure.
+ * @param   cb      Size in bytes of the memory block to allocate.
+ */
+#define RTMemExecAlloc(cb)              RTMemExecAllocTag((cb), RTMEM_TAG)
+
+/**
+ * Allocates memory which may contain code (custom tag).
+ *
+ * @returns Pointer to the allocated memory.
+ * @returns NULL on failure.
+ * @param   cb      Size in bytes of the memory block to allocate.
+ * @param   pszTag  Allocation tag used for statistics and such.
+ */
+RTDECL(void *)  RTMemExecAllocTag(size_t cb, const char *pszTag) RT_NO_THROW_PROTO;
+
+/**
+ * Free executable/read/write memory allocated by RTMemExecAlloc().
+ *
+ * @param   pv      Pointer to memory block.
+ * @param   cb      The allocation size.
+ */
+RTDECL(void)    RTMemExecFree(void *pv, size_t cb) RT_NO_THROW_PROTO;
+
+#if defined(IN_RING0) && defined(RT_ARCH_AMD64) && defined(RT_OS_LINUX)
+/**
+ * Donate read+write+execute memory to the exec heap.
+ *
+ * This API is specific to AMD64 and Linux/GNU. A kernel module that desires to
+ * use RTMemExecAlloc on AMD64 Linux/GNU will have to donate some statically
+ * allocated memory in the module if it wishes for GCC generated code to work.
+ * GCC can only generate modules that work in the address range ~2GB to ~0
+ * currently.
+ *
+ * The API only accept one single donation.
+ *
+ * @returns IPRT status code.
+ * @param   pvMemory    Pointer to the memory block.
+ * @param   cb          The size of the memory block.
+ */
+RTR0DECL(int) RTR0MemExecDonate(void *pvMemory, size_t cb) RT_NO_THROW_PROTO;
+#endif /* R0+AMD64+LINUX */
+
+/**
+ * Allocate page aligned memory with default tag.
+ *
+ * @returns Pointer to the allocated memory.
+ * @returns NULL if we're out of memory.
+ * @param   cb  Size of the memory block. Will be rounded up to page size.
+ */
+#define RTMemPageAlloc(cb)              RTMemPageAllocTag((cb), RTMEM_TAG)
+
+/**
+ * Allocate page aligned memory with custom tag.
+ *
+ * @returns Pointer to the allocated memory.
+ * @returns NULL if we're out of memory.
+ * @param   cb  Size of the memory block. Will be rounded up to page size.
+ * @param   pszTag  Allocation tag used for statistics and such.
+ */
+RTDECL(void *) RTMemPageAllocTag(size_t cb, const char *pszTag) RT_NO_THROW_PROTO;
+
+/**
+ * Allocate zero'd page aligned memory with default tag.
+ *
+ * @returns Pointer to the allocated memory.
+ * @returns NULL if we're out of memory.
+ * @param   cb  Size of the memory block. Will be rounded up to page size.
+ */
+#define RTMemPageAllocZ(cb)             RTMemPageAllocZTag((cb), RTMEM_TAG)
+
+/**
+ * Allocate zero'd page aligned memory with custom tag.
+ *
+ * @returns Pointer to the allocated memory.
+ * @returns NULL if we're out of memory.
+ * @param   cb  Size of the memory block. Will be rounded up to page size.
+ * @param   pszTag  Allocation tag used for statistics and such.
+ */
+RTDECL(void *) RTMemPageAllocZTag(size_t cb, const char *pszTag) RT_NO_THROW_PROTO;
+
+/**
+ * Free a memory block allocated with RTMemPageAlloc() or RTMemPageAllocZ().
+ *
+ * @param   pv      Pointer to the block as it was returned by the allocation function.
+ *                  NULL will be ignored.
+ * @param   cb      The allocation size.  Will be rounded up to page size.
+ *                  Ignored if @a pv is NULL.
+ */
+RTDECL(void) RTMemPageFree(void *pv, size_t cb) RT_NO_THROW_PROTO;
+
+/** Page level protection flags for RTMemProtect().
+ * @{
+ */
+/** No access at all. */
+#define RTMEM_PROT_NONE   0
+/** Read access. */
+#define RTMEM_PROT_READ   1
+/** Write access. */
+#define RTMEM_PROT_WRITE  2
+/** Execute access. */
+#define RTMEM_PROT_EXEC   4
+/** @} */
+
+/**
+ * Change the page level protection of a memory region.
+ *
+ * @returns iprt status code.
+ * @param   pv          Start of the region. Will be rounded down to nearest page boundary.
+ * @param   cb          Size of the region. Will be rounded up to the nearest page boundary.
+ * @param   fProtect    The new protection, a combination of the RTMEM_PROT_* defines.
+ */
+RTDECL(int) RTMemProtect(void *pv, size_t cb, unsigned fProtect) RT_NO_THROW_PROTO;
+
+/**
+ * Goes thru some pains to make sure the specified memory block is thoroughly
+ * scrambled.
+ *
+ * @param   pv          The start of the memory block.
+ * @param   cb          The size of the memory block.
+ * @param   cMinPasses  The minimum number of passes to make.
+ */
+RTDECL(void) RTMemWipeThoroughly(void *pv, size_t cb, size_t cMinPasses) RT_NO_THROW_PROTO;
+
+#ifdef IN_RING0
+
+/**
+ * Allocates physical contiguous memory (below 4GB).
+ * The allocation is page aligned and the content is undefined.
+ *
+ * @returns Pointer to the memory block. This is page aligned.
+ * @param   pPhys   Where to store the physical address.
+ * @param   cb      The allocation size in bytes. This is always
+ *                  rounded up to PAGE_SIZE.
+ */
+RTR0DECL(void *) RTMemContAlloc(PRTCCPHYS pPhys, size_t cb) RT_NO_THROW_PROTO;
+
+/**
+ * Frees memory allocated ysing RTMemContAlloc().
+ *
+ * @param   pv      Pointer to return from RTMemContAlloc().
+ * @param   cb      The cb parameter passed to RTMemContAlloc().
+ */
+RTR0DECL(void) RTMemContFree(void *pv, size_t cb) RT_NO_THROW_PROTO;
+
+/**
+ * Copy memory from an user mode buffer into a kernel buffer.
+ *
+ * @retval  VINF_SUCCESS on success.
+ * @retval  VERR_ACCESS_DENIED on error.
+ *
+ * @param   pvDst       The kernel mode destination address.
+ * @param   R3PtrSrc    The user mode source address.
+ * @param   cb          The number of bytes to copy.
+ */
+RTR0DECL(int) RTR0MemUserCopyFrom(void *pvDst, RTR3PTR R3PtrSrc, size_t cb);
+
+/**
+ * Copy memory from a kernel buffer into a user mode one.
+ *
+ * @retval  VINF_SUCCESS on success.
+ * @retval  VERR_ACCESS_DENIED on error.
+ *
+ * @param   R3PtrDst    The user mode destination address.
+ * @param   pvSrc       The kernel mode source address.
+ * @param   cb          The number of bytes to copy.
+ */
+RTR0DECL(int) RTR0MemUserCopyTo(RTR3PTR R3PtrDst, void const *pvSrc, size_t cb);
+
+/**
+ * Tests if the specified address is in the user addressable range.
+ *
+ * This function does not check whether the memory at that address is accessible
+ * or anything of that sort, only if the address it self is in the user mode
+ * range.
+ *
+ * @returns true if it's in the user addressable range. false if not.
+ * @param   R3Ptr       The user mode pointer to test.
+ *
+ * @remarks Some systems may have overlapping kernel and user address ranges.
+ *          One prominent example of this is the x86 version of Mac OS X. Use
+ *          RTR0MemAreKrnlAndUsrDifferent() to check.
+ */
+RTR0DECL(bool) RTR0MemUserIsValidAddr(RTR3PTR R3Ptr);
+
+/**
+ * Tests if the specified address is in the kernel mode range.
+ *
+ * This function does not check whether the memory at that address is accessible
+ * or anything of that sort, only if the address it self is in the kernel mode
+ * range.
+ *
+ * @returns true if it's in the kernel range. false if not.
+ * @param   pv          The alleged kernel mode pointer.
+ *
+ * @remarks Some systems may have overlapping kernel and user address ranges.
+ *          One prominent example of this is the x86 version of Mac OS X. Use
+ *          RTR0MemAreKrnlAndUsrDifferent() to check.
+ */
+RTR0DECL(bool) RTR0MemKernelIsValidAddr(void *pv);
+
+/**
+ * Are user mode and kernel mode address ranges distinctly different.
+ *
+ * This determines whether RTR0MemKernelIsValidAddr and RTR0MemUserIsValidAddr
+ * can be used for deciding whether some arbitrary address is a user mode or a
+ * kernel mode one.
+ *
+ * @returns true if they are, false if not.
+ */
+RTR0DECL(bool) RTR0MemAreKrnlAndUsrDifferent(void);
+
+/**
+ * Copy memory from an potentially unsafe kernel mode location and into a safe
+ * (kernel) buffer.
+ *
+ * @retval  VINF_SUCCESS on success.
+ * @retval  VERR_ACCESS_DENIED on error.
+ * @retval  VERR_NOT_SUPPORTED if not (yet) supported.
+ *
+ * @param   pvDst       The destination address (safe).
+ * @param   pvSrc       The source address (potentially unsafe).
+ * @param   cb          The number of bytes to copy.
+ */
+RTR0DECL(int) RTR0MemKernelCopyFrom(void *pvDst, void const *pvSrc, size_t cb);
+
+/**
+ * Copy from a safe (kernel) buffer and to a potentially unsafe kenrel mode
+ * location.
+ *
+ * @retval  VINF_SUCCESS on success.
+ * @retval  VERR_ACCESS_DENIED on error.
+ * @retval  VERR_NOT_SUPPORTED if not (yet) supported.
+ *
+ * @param   pvDst       The destination address (potentially unsafe).
+ * @param   pvSrc       The source address (safe).
+ * @param   cb          The number of bytes to copy.
+ */
+RTR0DECL(int) RTR0MemKernelCopyTo(void *pvDst, void const *pvSrc, size_t cb);
+
+#endif /* IN_RING0 */
+
+
+/** @name Electrical Fence Version of some APIs.
+ * @{
+ */
+
+/**
+ * Same as RTMemTmpAllocTag() except that it's fenced.
+ *
+ * @returns Pointer to the allocated memory.
+ * @returns NULL on failure.
+ * @param   cb      Size in bytes of the memory block to allocate.
+ * @param   pszTag  Allocation tag used for statistics and such.
+ * @param   SRC_POS The source position where call is being made from.
+ *                  Use RT_SRC_POS when possible.  Optional.
+ */
+RTDECL(void *)  RTMemEfTmpAlloc(size_t cb, const char *pszTag, RT_SRC_POS_DECL) RT_NO_THROW_PROTO;
+
+/**
+ * Same as RTMemTmpAllocZTag() except that it's fenced.
+ *
+ * @returns Pointer to the allocated memory.
+ * @returns NULL on failure.
+ * @param   cb      Size in bytes of the memory block to allocate.
+ * @param   pszTag  Allocation tag used for statistics and such.
+ * @param   SRC_POS The source position where call is being made from.  Use
+ *                  RT_SRC_POS when possible.  Optional.
+ */
+RTDECL(void *)  RTMemEfTmpAllocZ(size_t cb, const char *pszTag, RT_SRC_POS_DECL) RT_NO_THROW_PROTO;
+
+/**
+ * Same as RTMemTmpFree() except that it's for fenced memory.
+ *
+ * @param   pv      Pointer to memory block.
+ * @param   SRC_POS The source position where call is being made from.  Use
+ *                  RT_SRC_POS when possible.  Optional.
+ */
+RTDECL(void)    RTMemEfTmpFree(void *pv, RT_SRC_POS_DECL) RT_NO_THROW_PROTO;
+
+/**
+ * Same as RTMemAllocTag() except that it's fenced.
+ *
+ * @returns Pointer to the allocated memory. Free with RTMemEfFree().
+ * @returns NULL on failure.
+ * @param   cb      Size in bytes of the memory block to allocate.
+ * @param   pszTag  Allocation tag used for statistics and such.
+ * @param   SRC_POS The source position where call is being made from.  Use
+ *                  RT_SRC_POS when possible.  Optional.
+ */
+RTDECL(void *)  RTMemEfAlloc(size_t cb, const char *pszTag, RT_SRC_POS_DECL) RT_NO_THROW_PROTO;
+
+/**
+ * Same as RTMemAllocZTag() except that it's fenced.
+ *
+ * @returns Pointer to the allocated memory.
+ * @returns NULL on failure.
+ * @param   cb      Size in bytes of the memory block to allocate.
+ * @param   pszTag  Allocation tag used for statistics and such.
+ * @param   SRC_POS The source position where call is being made from.  Use
+ *                  RT_SRC_POS when possible.  Optional.
+ */
+RTDECL(void *)  RTMemEfAllocZ(size_t cb, const char *pszTag, RT_SRC_POS_DECL) RT_NO_THROW_PROTO;
+
+/**
+ * Same as RTMemAllocVarTag() except that it's fenced.
+ *
+ * @returns Pointer to the allocated memory. Free with RTMemEfFree().
+ * @returns NULL on failure.
+ * @param   cbUnaligned Size in bytes of the memory block to allocate.
+ * @param   pszTag  Allocation tag used for statistics and such.
+ * @param   SRC_POS The source position where call is being made from.  Use
+ *                  RT_SRC_POS when possible.  Optional.
+ */
+RTDECL(void *)  RTMemEfAllocVar(size_t cbUnaligned, const char *pszTag, RT_SRC_POS_DECL) RT_NO_THROW_PROTO;
+
+/**
+ * Same as RTMemAllocZVarTag() except that it's fenced.
+ *
+ * @returns Pointer to the allocated memory.
+ * @returns NULL on failure.
+ * @param   cbUnaligned Size in bytes of the memory block to allocate.
+ * @param   pszTag  Allocation tag used for statistics and such.
+ * @param   SRC_POS The source position where call is being made from.  Use
+ *                  RT_SRC_POS when possible.  Optional.
+ */
+RTDECL(void *)  RTMemEfAllocZVar(size_t cbUnaligned, const char *pszTag, RT_SRC_POS_DECL) RT_NO_THROW_PROTO;
+
+/**
+ * Same as RTMemReallocTag() except that it's fenced.
+ *
+ * @returns Pointer to the allocated memory.
+ * @returns NULL on failure.
+ * @param   pvOld   The memory block to reallocate.
+ * @param   cbNew   The new block size (in bytes).
+ * @param   pszTag  Allocation tag used for statistics and such.
+ * @param   SRC_POS The source position where call is being made from.  Use
+ *                  RT_SRC_POS when possible.  Optional.
+ */
+RTDECL(void *)  RTMemEfRealloc(void *pvOld, size_t cbNew, const char *pszTag, RT_SRC_POS_DECL) RT_NO_THROW_PROTO;
+
+/**
+ * Free memory allocated by any of the RTMemEf* allocators.
+ *
+ * @param   pv      Pointer to memory block.
+ * @param   SRC_POS The source position where call is being made from.  Use
+ *                  RT_SRC_POS when possible.  Optional.
+ */
+RTDECL(void)    RTMemEfFree(void *pv, RT_SRC_POS_DECL) RT_NO_THROW_PROTO;
+
+/**
+ * Same as RTMemDupTag() except that it's fenced.
+ *
+ * @returns New heap block with the duplicate data.
+ * @returns NULL if we're out of memory.
+ * @param   pvSrc   The memory to duplicate.
+ * @param   cb      The amount of memory to duplicate.
+ * @param   pszTag  Allocation tag used for statistics and such.
+ * @param   SRC_POS The source position where call is being made from.  Use
+ *                  RT_SRC_POS when possible.  Optional.
+ */
+RTDECL(void *) RTMemEfDup(const void *pvSrc, size_t cb, const char *pszTag, RT_SRC_POS_DECL) RT_NO_THROW_PROTO;
+
+/**
+ * Same as RTMemEfDupExTag except that it's fenced.
+ *
+ * @returns New heap block with the duplicate data.
+ * @returns NULL if we're out of memory.
+ * @param   pvSrc   The memory to duplicate.
+ * @param   cbSrc   The amount of memory to duplicate.
+ * @param   cbExtra The amount of extra memory to allocate and zero.
+ * @param   pszTag  Allocation tag used for statistics and such.
+ * @param   SRC_POS The source position where call is being made from.  Use
+ *                  RT_SRC_POS when possible.  Optional.
+ */
+RTDECL(void *) RTMemEfDupEx(const void *pvSrc, size_t cbSrc, size_t cbExtra, const char *pszTag, RT_SRC_POS_DECL) RT_NO_THROW_PROTO;
+
+/** @def RTMEM_WRAP_SOME_NEW_AND_DELETE_TO_EF
+ * Define RTMEM_WRAP_SOME_NEW_AND_DELETE_TO_EF to enable electric fence new and
+ * delete operators for classes which uses the RTMEMEF_NEW_AND_DELETE_OPERATORS
+ * macro.
+ */
+/** @def RTMEMEF_NEW_AND_DELETE_OPERATORS
+ * Defines the electric fence new and delete operators for a class when
+ * RTMEM_WRAP_SOME_NEW_AND_DELETE_TO_EF is define.
+ */
+#if defined(RTMEM_WRAP_SOME_NEW_AND_DELETE_TO_EF) && !defined(RTMEM_NO_WRAP_SOME_NEW_AND_DELETE_TO_EF)
+# if defined(RT_EXCEPTIONS_ENABLED)
+#  define RTMEMEF_NEW_AND_DELETE_OPERATORS() \
+        void *operator new(size_t cb) RT_THROW(std::bad_alloc) \
+        { \
+            void *pv = RTMemEfAlloc(cb, RTMEM_TAG, RT_SRC_POS); \
+            if (RT_LIKELY(pv)) \
+                return pv; \
+            throw std::bad_alloc(); \
+        } \
+        void *operator new(size_t cb, const std::nothrow_t &nothrow_constant) RT_NO_THROW_DEF \
+        { \
+            NOREF(nothrow_constant); \
+            return RTMemEfAlloc(cb, RTMEM_TAG, RT_SRC_POS); \
+        } \
+        void *operator new[](size_t cb) RT_THROW(std::bad_alloc) \
+        { \
+            void *pv = RTMemEfAlloc(cb, RTMEM_TAG, RT_SRC_POS); \
+            if (RT_LIKELY(pv)) \
+                return pv; \
+            throw std::bad_alloc(); \
+        } \
+        void *operator new[](size_t cb, const std::nothrow_t &nothrow_constant) RT_NO_THROW_DEF \
+        { \
+            NOREF(nothrow_constant); \
+            return RTMemEfAlloc(cb, RTMEM_TAG, RT_SRC_POS); \
+        } \
+        \
+        void operator delete(void *pv) RT_NO_THROW_DEF \
+        { \
+            RTMemEfFree(pv, RT_SRC_POS); \
+        } \
+        void operator delete(void *pv, const std::nothrow_t &nothrow_constant) RT_NO_THROW_DEF \
+        { \
+            NOREF(nothrow_constant); \
+            RTMemEfFree(pv, RT_SRC_POS); \
+        } \
+        void operator delete[](void *pv) RT_NO_THROW_DEF \
+        { \
+            RTMemEfFree(pv, RT_SRC_POS); \
+        } \
+        void operator delete[](void *pv, const std::nothrow_t &nothrow_constant) RT_NO_THROW_DEF \
+        { \
+            NOREF(nothrow_constant); \
+            RTMemEfFree(pv, RT_SRC_POS); \
+        } \
+        \
+        typedef int UsingElectricNewAndDeleteOperators
+# else
+#  define RTMEMEF_NEW_AND_DELETE_OPERATORS() \
+        void *operator new(size_t cb) \
+        { \
+            return RTMemEfAlloc(cb, RTMEM_TAG, RT_SRC_POS); \
+        } \
+        void *operator new(size_t cb, const std::nothrow_t &nothrow_constant) \
+        { \
+            NOREF(nothrow_constant); \
+            return RTMemEfAlloc(cb, RTMEM_TAG, RT_SRC_POS); \
+        } \
+        void *operator new[](size_t cb) \
+        { \
+            return RTMemEfAlloc(cb, RTMEM_TAG, RT_SRC_POS); \
+        } \
+        void *operator new[](size_t cb, const std::nothrow_t &nothrow_constant) \
+        { \
+            NOREF(nothrow_constant); \
+            return RTMemEfAlloc(cb, RTMEM_TAG, RT_SRC_POS); \
+        } \
+        \
+        void operator delete(void *pv) \
+        { \
+            RTMemEfFree(pv, RT_SRC_POS); \
+        } \
+        void operator delete(void *pv, const std::nothrow_t &nothrow_constant) \
+        { \
+            NOREF(nothrow_constant); \
+            RTMemEfFree(pv, RT_SRC_POS); \
+        } \
+        void operator delete[](void *pv) \
+        { \
+            RTMemEfFree(pv, RT_SRC_POS); \
+        } \
+        void operator delete[](void *pv, const std::nothrow_t &nothrow_constant) \
+        { \
+            NOREF(nothrow_constant); \
+            RTMemEfFree(pv, RT_SRC_POS); \
+        } \
+        \
+        typedef int UsingElectricNewAndDeleteOperators
+# endif
+#else
+# define RTMEMEF_NEW_AND_DELETE_OPERATORS() \
+        typedef int UsingDefaultNewAndDeleteOperators
+#endif
+#ifdef DOXYGEN_RUNNING
+# define RTMEM_WRAP_SOME_NEW_AND_DELETE_TO_EF
+#endif
+
+/** @def RTMEM_WRAP_TO_EF_APIS
+ * Define RTMEM_WRAP_TO_EF_APIS to wrap RTMem APIs to RTMemEf APIs.
+ */
+#if defined(RTMEM_WRAP_TO_EF_APIS) && defined(IN_RING3) && !defined(RTMEM_NO_WRAP_TO_EF_APIS)
+# define RTMemTmpAllocTag(cb, pszTag)                   RTMemEfTmpAlloc((cb), (pszTag), RT_SRC_POS)
+# define RTMemTmpAllocZTag(cb, pszTag)                  RTMemEfTmpAllocZ((cb), (pszTag), RT_SRC_POS)
+# define RTMemTmpFree(pv)                               RTMemEfTmpFree((pv), RT_SRC_POS)
+# define RTMemAllocTag(cb, pszTag)                      RTMemEfAlloc((cb), (pszTag), RT_SRC_POS)
+# define RTMemAllocZTag(cb, pszTag)                     RTMemEfAllocZ((cb), (pszTag), RT_SRC_POS)
+# define RTMemAllocVarTag(cbUnaligned, pszTag)          RTMemEfAllocVar((cbUnaligned), (pszTag), RT_SRC_POS)
+# define RTMemAllocZVarTag(cbUnaligned, pszTag)         RTMemEfAllocZVar((cbUnaligned), (pszTag), RT_SRC_POS)
+# define RTMemReallocTag(pvOld, cbNew, pszTag)          RTMemEfRealloc((pvOld), (cbNew), (pszTag), RT_SRC_POS)
+# define RTMemFree(pv)                                  RTMemEfFree((pv), RT_SRC_POS)
+# define RTMemDupTag(pvSrc, cb, pszTag)                 RTMemEfDup((pvSrc), (cb), (pszTag), RT_SRC_POS)
+# define RTMemDupExTag(pvSrc, cbSrc, cbExtra, pszTag)   RTMemEfDupEx((pvSrc), (cbSrc), (cbExtra), (pszTag), RT_SRC_POS)
+#endif
+#ifdef DOXYGEN_RUNNING
+# define RTMEM_WRAP_TO_EF_APIS
+#endif
+
+/**
+ * Fenced drop-in replacement for RTMemTmpAllocTag.
+ * @copydoc RTMemTmpAllocTag
+ */
+RTDECL(void *)  RTMemEfTmpAllocNP(size_t cb, const char *pszTag) RT_NO_THROW_PROTO;
+
+/**
+ * Fenced drop-in replacement for RTMemTmpAllocZTag.
+ * @copydoc RTMemTmpAllocZTag
+ */
+RTDECL(void *)  RTMemEfTmpAllocZNP(size_t cb, const char *pszTag) RT_NO_THROW_PROTO;
+
+/**
+ * Fenced drop-in replacement for RTMemTmpFreeTag.
+ * @copydoc RTMemTmpFree
+ */
+RTDECL(void)    RTMemEfTmpFreeNP(void *pv) RT_NO_THROW_PROTO;
+
+/**
+ * Fenced drop-in replacement for RTMemAllocTag.
+ * @copydoc RTMemAllocTag
+ */
+RTDECL(void *)  RTMemEfAllocNP(size_t cb, const char *pszTag) RT_NO_THROW_PROTO;
+
+/**
+ * Fenced drop-in replacement for RTMemAllocZTag.
+ * @copydoc RTMemAllocZTag
+ */
+RTDECL(void *)  RTMemEfAllocZNP(size_t cb, const char *pszTag) RT_NO_THROW_PROTO;
+
+/**
+ * Fenced drop-in replacement for RTMemAllocVarTag
+ * @copydoc RTMemAllocVarTag
+ */
+RTDECL(void *)  RTMemEfAllocVarNP(size_t cbUnaligned, const char *pszTag) RT_NO_THROW_PROTO;
+
+/**
+ * Fenced drop-in replacement for RTMemAllocZVarTag.
+ * @copydoc RTMemAllocZVarTag
+ */
+RTDECL(void *)  RTMemEfAllocZVarNP(size_t cbUnaligned, const char *pszTag) RT_NO_THROW_PROTO;
+
+/**
+ * Fenced drop-in replacement for RTMemReallocTag.
+ * @copydoc RTMemReallocTag
+ */
+RTDECL(void *)  RTMemEfReallocNP(void *pvOld, size_t cbNew, const char *pszTag) RT_NO_THROW_PROTO;
+
+/**
+ * Fenced drop-in replacement for RTMemFree.
+ * @copydoc RTMemFree
+ */
+RTDECL(void)    RTMemEfFreeNP(void *pv) RT_NO_THROW_PROTO;
+
+/**
+ * Fenced drop-in replacement for RTMemDupExTag.
+ * @copydoc RTMemDupTag
+ */
+RTDECL(void *) RTMemEfDupNP(const void *pvSrc, size_t cb, const char *pszTag) RT_NO_THROW_PROTO;
+
+/**
+ * Fenced drop-in replacement for RTMemDupExTag.
+ * @copydoc RTMemDupExTag
+ */
+RTDECL(void *) RTMemEfDupExNP(const void *pvSrc, size_t cbSrc, size_t cbExtra, const char *pszTag) RT_NO_THROW_PROTO;
+
+/** @} */
+
+RT_C_DECLS_END
+
+/** @} */
+
+
+#endif
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/include/iprt/memobj.h
@@ -0,0 +1,629 @@
+/** @file
+ * IPRT - Memory Objects (Ring-0).
+ */
+
+/*
+ * Copyright (C) 2006-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+#ifndef ___iprt_memobj_h
+#define ___iprt_memobj_h
+
+#include <iprt/cdefs.h>
+#include <iprt/types.h>
+
+RT_C_DECLS_BEGIN
+
+/** @defgroup grp_rt_memobj     RTMemObj - Memory Object Manipulation (Ring-0)
+ * @ingroup grp_rt
+ * @{
+ */
+
+/** @def RTMEM_TAG
+ * The default allocation tag used by the RTMem allocation APIs.
+ *
+ * When not defined before the inclusion of iprt/memobj.h or iprt/mem.h, this
+ * will default to the pointer to the current file name.  The memory API will
+ * make of use of this as pointer to a volatile but read-only string.
+ */
+#ifndef RTMEM_TAG
+# define RTMEM_TAG   (__FILE__)
+#endif
+
+#ifdef IN_RING0
+
+/**
+ * Checks if this is mapping or not.
+ *
+ * @returns true if it's a mapping, otherwise false.
+ * @param   MemObj  The ring-0 memory object handle.
+ */
+RTR0DECL(bool) RTR0MemObjIsMapping(RTR0MEMOBJ MemObj);
+
+/**
+ * Gets the address of a ring-0 memory object.
+ *
+ * @returns The address of the memory object.
+ * @returns NULL if the handle is invalid (asserts in strict builds) or if there isn't any mapping.
+ * @param   MemObj  The ring-0 memory object handle.
+ */
+RTR0DECL(void *) RTR0MemObjAddress(RTR0MEMOBJ MemObj);
+
+/**
+ * Gets the ring-3 address of a ring-0 memory object.
+ *
+ * This only applies to ring-0 memory object with ring-3 mappings of some kind, i.e.
+ * locked user memory, reserved user address space and user mappings. This API should
+ * not be used on any other objects.
+ *
+ * @returns The address of the memory object.
+ * @returns NIL_RTR3PTR if the handle is invalid or if it's not an object with a ring-3 mapping.
+ *          Strict builds will assert in both cases.
+ * @param   MemObj  The ring-0 memory object handle.
+ */
+RTR0DECL(RTR3PTR) RTR0MemObjAddressR3(RTR0MEMOBJ MemObj);
+
+/**
+ * Gets the size of a ring-0 memory object.
+ *
+ * The returned value may differ from the one specified to the API creating the
+ * object because of alignment adjustments.  The minimal alignment currently
+ * employed by any API is PAGE_SIZE, so the result can safely be shifted by
+ * PAGE_SHIFT to calculate a page count.
+ *
+ * @returns The object size.
+ * @returns 0 if the handle is invalid (asserts in strict builds) or if there isn't any mapping.
+ * @param   MemObj  The ring-0 memory object handle.
+ */
+RTR0DECL(size_t) RTR0MemObjSize(RTR0MEMOBJ MemObj);
+
+/**
+ * Get the physical address of an page in the memory object.
+ *
+ * @returns The physical address.
+ * @returns NIL_RTHCPHYS if the object doesn't contain fixed physical pages.
+ * @returns NIL_RTHCPHYS if the iPage is out of range.
+ * @returns NIL_RTHCPHYS if the object handle isn't valid.
+ * @param   MemObj  The ring-0 memory object handle.
+ * @param   iPage   The page number within the object.
+ */
+RTR0DECL(RTHCPHYS) RTR0MemObjGetPagePhysAddr(RTR0MEMOBJ MemObj, size_t iPage);
+
+/**
+ * Frees a ring-0 memory object.
+ *
+ * @returns IPRT status code.
+ * @retval  VERR_INVALID_HANDLE if
+ * @param   MemObj          The ring-0 memory object to be freed. NULL is accepted.
+ * @param   fFreeMappings   Whether or not to free mappings of the object.
+ */
+RTR0DECL(int) RTR0MemObjFree(RTR0MEMOBJ MemObj, bool fFreeMappings);
+
+/**
+ * Allocates page aligned virtual kernel memory (default tag).
+ *
+ * The memory is taken from a non paged (= fixed physical memory backing) pool.
+ *
+ * @returns IPRT status code.
+ * @param   pMemObj         Where to store the ring-0 memory object handle.
+ * @param   cb              Number of bytes to allocate. This is rounded up to nearest page.
+ * @param   fExecutable     Flag indicating whether it should be permitted to executed code in the memory object.
+ */
+#define RTR0MemObjAllocPage(pMemObj, cb, fExecutable) \
+    RTR0MemObjAllocPageTag((pMemObj), (cb), (fExecutable), RTMEM_TAG)
+
+/**
+ * Allocates page aligned virtual kernel memory (custom tag).
+ *
+ * The memory is taken from a non paged (= fixed physical memory backing) pool.
+ *
+ * @returns IPRT status code.
+ * @param   pMemObj         Where to store the ring-0 memory object handle.
+ * @param   cb              Number of bytes to allocate. This is rounded up to nearest page.
+ * @param   fExecutable     Flag indicating whether it should be permitted to executed code in the memory object.
+ * @param   pszTag          Allocation tag used for statistics and such.
+ */
+RTR0DECL(int) RTR0MemObjAllocPageTag(PRTR0MEMOBJ pMemObj, size_t cb, bool fExecutable, const char *pszTag);
+
+/**
+ * Allocates page aligned virtual kernel memory with physical backing below 4GB
+ * (default tag).
+ *
+ * The physical memory backing the allocation is fixed.
+ *
+ * @returns IPRT status code.
+ * @param   pMemObj         Where to store the ring-0 memory object handle.
+ * @param   cb              Number of bytes to allocate. This is rounded up to nearest page.
+ * @param   fExecutable     Flag indicating whether it should be permitted to executed code in the memory object.
+ */
+#define RTR0MemObjAllocLow(pMemObj, cb, fExecutable) \
+    RTR0MemObjAllocLowTag((pMemObj), (cb), (fExecutable), RTMEM_TAG)
+
+/**
+ * Allocates page aligned virtual kernel memory with physical backing below 4GB
+ * (custom tag).
+ *
+ * The physical memory backing the allocation is fixed.
+ *
+ * @returns IPRT status code.
+ * @param   pMemObj         Where to store the ring-0 memory object handle.
+ * @param   cb              Number of bytes to allocate. This is rounded up to nearest page.
+ * @param   fExecutable     Flag indicating whether it should be permitted to executed code in the memory object.
+ * @param   pszTag          Allocation tag used for statistics and such.
+ */
+RTR0DECL(int) RTR0MemObjAllocLowTag(PRTR0MEMOBJ pMemObj, size_t cb, bool fExecutable, const char *pszTag);
+
+/**
+ * Allocates page aligned virtual kernel memory with contiguous physical backing
+ * below 4GB (default tag).
+ *
+ * The physical memory backing the allocation is fixed.
+ *
+ * @returns IPRT status code.
+ * @param   pMemObj         Where to store the ring-0 memory object handle.
+ * @param   cb              Number of bytes to allocate. This is rounded up to nearest page.
+ * @param   fExecutable     Flag indicating whether it should be permitted to executed code in the memory object.
+ */
+#define RTR0MemObjAllocCont(pMemObj, cb, fExecutable) \
+    RTR0MemObjAllocContTag((pMemObj), (cb), (fExecutable), RTMEM_TAG)
+
+/**
+ * Allocates page aligned virtual kernel memory with contiguous physical backing
+ * below 4GB (custom tag).
+ *
+ * The physical memory backing the allocation is fixed.
+ *
+ * @returns IPRT status code.
+ * @param   pMemObj         Where to store the ring-0 memory object handle.
+ * @param   cb              Number of bytes to allocate. This is rounded up to nearest page.
+ * @param   fExecutable     Flag indicating whether it should be permitted to executed code in the memory object.
+ * @param   pszTag          Allocation tag used for statistics and such.
+ */
+RTR0DECL(int) RTR0MemObjAllocContTag(PRTR0MEMOBJ pMemObj, size_t cb, bool fExecutable, const char *pszTag);
+
+/**
+ * Locks a range of user virtual memory (default tag).
+ *
+ * @returns IPRT status code.
+ * @param   pMemObj         Where to store the ring-0 memory object handle.
+ * @param   R3Ptr           User virtual address. This is rounded down to a page
+ *                          boundary.
+ * @param   cb              Number of bytes to lock. This is rounded up to
+ *                          nearest page boundary.
+ * @param   fAccess         The desired access, a combination of RTMEM_PROT_READ
+ *                          and RTMEM_PROT_WRITE.
+ * @param   R0Process       The process to lock pages in. NIL_R0PROCESS is an
+ *                          alias for the current one.
+ *
+ * @remarks RTR0MemGetAddressR3() and RTR0MemGetAddress() will return therounded
+ *          down address.
+ *
+ * @remarks Linux: This API requires that the memory begin locked is in a memory
+ *          mapping that is not required in any forked off child process. This
+ *          is not intented as permanent restriction, feel free to help out
+ *          lifting it.
+ */
+#define RTR0MemObjLockUser(pMemObj, R3Ptr, cb, fAccess, R0Process) \
+    RTR0MemObjLockUserTag((pMemObj), (R3Ptr), (cb), (fAccess), (R0Process), RTMEM_TAG)
+
+/**
+ * Locks a range of user virtual memory (custom tag).
+ *
+ * @returns IPRT status code.
+ * @param   pMemObj         Where to store the ring-0 memory object handle.
+ * @param   R3Ptr           User virtual address. This is rounded down to a page
+ *                          boundary.
+ * @param   cb              Number of bytes to lock. This is rounded up to
+ *                          nearest page boundary.
+ * @param   fAccess         The desired access, a combination of RTMEM_PROT_READ
+ *                          and RTMEM_PROT_WRITE.
+ * @param   R0Process       The process to lock pages in. NIL_R0PROCESS is an
+ *                          alias for the current one.
+ * @param   pszTag          Allocation tag used for statistics and such.
+ *
+ * @remarks RTR0MemGetAddressR3() and RTR0MemGetAddress() will return therounded
+ *          down address.
+ *
+ * @remarks Linux: This API requires that the memory begin locked is in a memory
+ *          mapping that is not required in any forked off child process. This
+ *          is not intented as permanent restriction, feel free to help out
+ *          lifting it.
+ */
+RTR0DECL(int) RTR0MemObjLockUserTag(PRTR0MEMOBJ pMemObj, RTR3PTR R3Ptr, size_t cb, uint32_t fAccess,
+                                    RTR0PROCESS R0Process, const char *pszTag);
+
+/**
+ * Locks a range of kernel virtual memory (default tag).
+ *
+ * @returns IPRT status code.
+ * @param   pMemObj         Where to store the ring-0 memory object handle.
+ * @param   pv              Kernel virtual address. This is rounded down to a page boundary.
+ * @param   cb              Number of bytes to lock. This is rounded up to nearest page boundary.
+ * @param   fAccess         The desired access, a combination of RTMEM_PROT_READ
+ *                          and RTMEM_PROT_WRITE.
+ *
+ * @remark  RTR0MemGetAddress() will return the rounded down address.
+ */
+#define RTR0MemObjLockKernel(pMemObj, pv, cb, fAccess) \
+    RTR0MemObjLockKernelTag((pMemObj), (pv), (cb), (fAccess), RTMEM_TAG)
+
+/**
+ * Locks a range of kernel virtual memory (custom tag).
+ *
+ * @returns IPRT status code.
+ * @param   pMemObj         Where to store the ring-0 memory object handle.
+ * @param   pv              Kernel virtual address. This is rounded down to a page boundary.
+ * @param   cb              Number of bytes to lock. This is rounded up to nearest page boundary.
+ * @param   fAccess         The desired access, a combination of RTMEM_PROT_READ
+ *                          and RTMEM_PROT_WRITE.
+ * @param   pszTag          Allocation tag used for statistics and such.
+ *
+ * @remark  RTR0MemGetAddress() will return the rounded down address.
+ */
+RTR0DECL(int) RTR0MemObjLockKernelTag(PRTR0MEMOBJ pMemObj, void *pv, size_t cb, uint32_t fAccess, const char *pszTag);
+
+/**
+ * Allocates contiguous page aligned physical memory without (necessarily) any
+ * kernel mapping (default tag).
+ *
+ * @returns IPRT status code.
+ * @param   pMemObj         Where to store the ring-0 memory object handle.
+ * @param   cb              Number of bytes to allocate. This is rounded up to nearest page.
+ * @param   PhysHighest     The highest permitable address (inclusive).
+ *                          Pass NIL_RTHCPHYS if any address is acceptable.
+ */
+#define RTR0MemObjAllocPhys(pMemObj, cb, PhysHighest) \
+    RTR0MemObjAllocPhysTag((pMemObj), (cb), (PhysHighest), RTMEM_TAG)
+
+/**
+ * Allocates contiguous page aligned physical memory without (necessarily) any
+ * kernel mapping (custom tag).
+ *
+ * @returns IPRT status code.
+ * @param   pMemObj         Where to store the ring-0 memory object handle.
+ * @param   cb              Number of bytes to allocate. This is rounded up to nearest page.
+ * @param   PhysHighest     The highest permitable address (inclusive).
+ *                          Pass NIL_RTHCPHYS if any address is acceptable.
+ * @param   pszTag          Allocation tag used for statistics and such.
+ */
+RTR0DECL(int) RTR0MemObjAllocPhysTag(PRTR0MEMOBJ pMemObj, size_t cb, RTHCPHYS PhysHighest, const char *pszTag);
+
+/**
+ * Allocates contiguous physical memory without (necessarily) any kernel mapping
+ * (default tag).
+ *
+ * @returns IPRT status code.
+ * @param   pMemObj         Where to store the ring-0 memory object handle.
+ * @param   cb              Number of bytes to allocate. This is rounded up to nearest page.
+ * @param   PhysHighest     The highest permitable address (inclusive).
+ *                          Pass NIL_RTHCPHYS if any address is acceptable.
+ * @param   uAlignment      The alignment of the reserved memory.
+ *                          Supported values are 0 (alias for PAGE_SIZE), PAGE_SIZE, _2M, _4M and _1G.
+ */
+#define RTR0MemObjAllocPhysEx(pMemObj, cb, PhysHighest, uAlignment) \
+    RTR0MemObjAllocPhysExTag((pMemObj), (cb), (PhysHighest), (uAlignment), RTMEM_TAG)
+
+/**
+ * Allocates contiguous physical memory without (necessarily) any kernel mapping
+ * (custom tag).
+ *
+ * @returns IPRT status code.
+ * @param   pMemObj         Where to store the ring-0 memory object handle.
+ * @param   cb              Number of bytes to allocate. This is rounded up to nearest page.
+ * @param   PhysHighest     The highest permitable address (inclusive).
+ *                          Pass NIL_RTHCPHYS if any address is acceptable.
+ * @param   uAlignment      The alignment of the reserved memory.
+ *                          Supported values are 0 (alias for PAGE_SIZE), PAGE_SIZE, _2M, _4M and _1G.
+ * @param   pszTag          Allocation tag used for statistics and such.
+ */
+RTR0DECL(int) RTR0MemObjAllocPhysExTag(PRTR0MEMOBJ pMemObj, size_t cb, RTHCPHYS PhysHighest, size_t uAlignment, const char *pszTag);
+
+/**
+ * Allocates non-contiguous page aligned physical memory without (necessarily)
+ * any kernel mapping (default tag).
+ *
+ * This API is for allocating huge amounts of pages and will return
+ * VERR_NOT_SUPPORTED if this cannot be implemented in a satisfactory
+ * manner.
+ *
+ * @returns IPRT status code.
+ * @retval  VERR_NOT_SUPPORTED if it's not possible to allocated unmapped
+ *          physical memory on this platform. The caller should expect
+ *          this error and have a fallback strategy for it.
+ *
+ * @param   pMemObj         Where to store the ring-0 memory object handle.
+ * @param   cb              Number of bytes to allocate. This is rounded up to nearest page.
+ * @param   PhysHighest     The highest permitable address (inclusive).
+ *                          Pass NIL_RTHCPHYS if any address is acceptable.
+ */
+#define RTR0MemObjAllocPhysNC(pMemObj, cb, PhysHighest) \
+    RTR0MemObjAllocPhysNCTag((pMemObj), (cb), (PhysHighest), RTMEM_TAG)
+
+/**
+ * Allocates non-contiguous page aligned physical memory without (necessarily)
+ * any kernel mapping (custom tag).
+ *
+ * This API is for allocating huge amounts of pages and will return
+ * VERR_NOT_SUPPORTED if this cannot be implemented in a satisfactory
+ * manner.
+ *
+ * @returns IPRT status code.
+ * @retval  VERR_NOT_SUPPORTED if it's not possible to allocated unmapped
+ *          physical memory on this platform. The caller should expect
+ *          this error and have a fallback strategy for it.
+ *
+ * @param   pMemObj         Where to store the ring-0 memory object handle.
+ * @param   cb              Number of bytes to allocate. This is rounded up to nearest page.
+ * @param   PhysHighest     The highest permitable address (inclusive).
+ *                          Pass NIL_RTHCPHYS if any address is acceptable.
+ * @param   pszTag          Allocation tag used for statistics and such.
+ */
+RTR0DECL(int) RTR0MemObjAllocPhysNCTag(PRTR0MEMOBJ pMemObj, size_t cb, RTHCPHYS PhysHighest, const char *pszTag);
+
+/** Memory cache policy for RTR0MemObjEnterPhys.
+ * @{
+ */
+/** Default caching policy -- don't care. */
+#define RTMEM_CACHE_POLICY_DONT_CARE    UINT32_C(0)
+/** MMIO caching policy -- uncachable. */
+#define RTMEM_CACHE_POLICY_MMIO         UINT32_C(1)
+/** @} */
+
+/**
+ * Creates a page aligned, contiguous, physical memory object (default tag).
+ *
+ * No physical memory is allocated, we trust you do know what you're doing.
+ *
+ * @returns IPRT status code.
+ * @param   pMemObj         Where to store the ring-0 memory object handle.
+ * @param   Phys            The physical address to start at. This is rounded down to the
+ *                          nearest page boundary.
+ * @param   cb              The size of the object in bytes. This is rounded up to nearest page boundary.
+ * @param   uCachePolicy    One of the RTMEM_CACHE_XXX modes.
+ */
+#define RTR0MemObjEnterPhys(pMemObj, Phys, cb, uCachePolicy) \
+    RTR0MemObjEnterPhysTag((pMemObj), (Phys), (cb), (uCachePolicy), RTMEM_TAG)
+
+/**
+ * Creates a page aligned, contiguous, physical memory object (custom tag).
+ *
+ * No physical memory is allocated, we trust you do know what you're doing.
+ *
+ * @returns IPRT status code.
+ * @param   pMemObj         Where to store the ring-0 memory object handle.
+ * @param   Phys            The physical address to start at. This is rounded down to the
+ *                          nearest page boundary.
+ * @param   cb              The size of the object in bytes. This is rounded up to nearest page boundary.
+ * @param   uCachePolicy    One of the RTMEM_CACHE_XXX modes.
+ * @param   pszTag          Allocation tag used for statistics and such.
+ */
+RTR0DECL(int) RTR0MemObjEnterPhysTag(PRTR0MEMOBJ pMemObj, RTHCPHYS Phys, size_t cb, uint32_t uCachePolicy, const char *pszTag);
+
+/**
+ * Reserves kernel virtual address space (default tag).
+ *
+ * If this function fails with VERR_NOT_SUPPORTED, the idea is that you
+ * can use RTR0MemObjEnterPhys() + RTR0MemObjMapKernel() as a fallback if
+ * you have a safe physical address range to make use of...
+ *
+ * @returns IPRT status code.
+ * @param   pMemObj         Where to store the ring-0 memory object handle.
+ * @param   pvFixed         Requested address. (void *)-1 means any address. This must match the alignment.
+ * @param   cb              The number of bytes to reserve. This is rounded up to nearest page.
+ * @param   uAlignment      The alignment of the reserved memory.
+ *                          Supported values are 0 (alias for PAGE_SIZE), PAGE_SIZE, _2M and _4M.
+ */
+#define RTR0MemObjReserveKernel(pMemObj, pvFixed, cb, uAlignment) \
+    RTR0MemObjReserveKernelTag((pMemObj), (pvFixed), (cb), (uAlignment), RTMEM_TAG)
+
+/**
+ * Reserves kernel virtual address space (custom tag).
+ *
+ * If this function fails with VERR_NOT_SUPPORTED, the idea is that you
+ * can use RTR0MemObjEnterPhys() + RTR0MemObjMapKernel() as a fallback if
+ * you have a safe physical address range to make use of...
+ *
+ * @returns IPRT status code.
+ * @param   pMemObj         Where to store the ring-0 memory object handle.
+ * @param   pvFixed         Requested address. (void *)-1 means any address. This must match the alignment.
+ * @param   cb              The number of bytes to reserve. This is rounded up to nearest page.
+ * @param   uAlignment      The alignment of the reserved memory.
+ *                          Supported values are 0 (alias for PAGE_SIZE), PAGE_SIZE, _2M and _4M.
+ * @param   pszTag          Allocation tag used for statistics and such.
+ */
+RTR0DECL(int) RTR0MemObjReserveKernelTag(PRTR0MEMOBJ pMemObj, void *pvFixed, size_t cb, size_t uAlignment, const char *pszTag);
+
+/**
+ * Reserves user virtual address space in the current process (default tag).
+ *
+ * @returns IPRT status code.
+ * @param   pMemObj         Where to store the ring-0 memory object handle.
+ * @param   R3PtrFixed      Requested address. (RTR3PTR)-1 means any address. This must match the alignment.
+ * @param   cb              The number of bytes to reserve. This is rounded up to nearest PAGE_SIZE.
+ * @param   uAlignment      The alignment of the reserved memory.
+ *                          Supported values are 0 (alias for PAGE_SIZE), PAGE_SIZE, _2M and _4M.
+ * @param   R0Process       The process to reserve the memory in. NIL_R0PROCESS is an alias for the current one.
+ */
+#define RTR0MemObjReserveUser(pMemObj, R3PtrFixed, cb, uAlignment, R0Process) \
+    RTR0MemObjReserveUserTag((pMemObj), (R3PtrFixed), (cb), (uAlignment), (R0Process), RTMEM_TAG)
+
+/**
+ * Reserves user virtual address space in the current process (custom tag).
+ *
+ * @returns IPRT status code.
+ * @param   pMemObj         Where to store the ring-0 memory object handle.
+ * @param   R3PtrFixed      Requested address. (RTR3PTR)-1 means any address. This must match the alignment.
+ * @param   cb              The number of bytes to reserve. This is rounded up to nearest PAGE_SIZE.
+ * @param   uAlignment      The alignment of the reserved memory.
+ *                          Supported values are 0 (alias for PAGE_SIZE), PAGE_SIZE, _2M and _4M.
+ * @param   R0Process       The process to reserve the memory in. NIL_R0PROCESS is an alias for the current one.
+ * @param   pszTag          Allocation tag used for statistics and such.
+ */
+RTR0DECL(int) RTR0MemObjReserveUserTag(PRTR0MEMOBJ pMemObj, RTR3PTR R3PtrFixed, size_t cb, size_t uAlignment,
+                                       RTR0PROCESS R0Process, const char *pszTag);
+
+/**
+ * Maps a memory object into kernel virtual address space (default tag).
+ *
+ * This is the same as calling RTR0MemObjMapKernelEx with cbSub and offSub set
+ * to zero.
+ *
+ * @returns IPRT status code.
+ * @param   pMemObj         Where to store the ring-0 memory object handle of the mapping object.
+ * @param   MemObjToMap     The object to be map.
+ * @param   pvFixed         Requested address. (void *)-1 means any address. This must match the alignment.
+ * @param   uAlignment      The alignment of the reserved memory.
+ *                          Supported values are 0 (alias for PAGE_SIZE), PAGE_SIZE, _2M and _4M.
+ * @param   fProt           Combination of RTMEM_PROT_* flags (except RTMEM_PROT_NONE).
+ */
+#define RTR0MemObjMapKernel(pMemObj, MemObjToMap, pvFixed, uAlignment, fProt) \
+    RTR0MemObjMapKernelTag((pMemObj), (MemObjToMap), (pvFixed), (uAlignment), (fProt), RTMEM_TAG)
+
+/**
+ * Maps a memory object into kernel virtual address space (custom tag).
+ *
+ * This is the same as calling RTR0MemObjMapKernelEx with cbSub and offSub set
+ * to zero.
+ *
+ * @returns IPRT status code.
+ * @param   pMemObj         Where to store the ring-0 memory object handle of the mapping object.
+ * @param   MemObjToMap     The object to be map.
+ * @param   pvFixed         Requested address. (void *)-1 means any address. This must match the alignment.
+ * @param   uAlignment      The alignment of the reserved memory.
+ *                          Supported values are 0 (alias for PAGE_SIZE), PAGE_SIZE, _2M and _4M.
+ * @param   fProt           Combination of RTMEM_PROT_* flags (except RTMEM_PROT_NONE).
+ * @param   pszTag          Allocation tag used for statistics and such.
+ */
+RTR0DECL(int) RTR0MemObjMapKernelTag(PRTR0MEMOBJ pMemObj, RTR0MEMOBJ MemObjToMap, void *pvFixed,
+                                     size_t uAlignment, unsigned fProt, const char *pszTag);
+
+/**
+ * Maps a memory object into kernel virtual address space (default tag).
+ *
+ * The ability to map subsections of the object into kernel space is currently
+ * not implemented on all platforms. All/Most of platforms supports mapping the
+ * whole object into  kernel space.
+ *
+ * @returns IPRT status code.
+ * @retval  VERR_NOT_SUPPORTED if it's not possible to map a subsection of a
+ *          memory object on this platform. When you hit this, try implement it.
+ *
+ * @param   pMemObj         Where to store the ring-0 memory object handle of the mapping object.
+ * @param   MemObjToMap     The object to be map.
+ * @param   pvFixed         Requested address. (void *)-1 means any address. This must match the alignment.
+ * @param   uAlignment      The alignment of the reserved memory.
+ *                          Supported values are 0 (alias for PAGE_SIZE), PAGE_SIZE, _2M and _4M.
+ * @param   fProt           Combination of RTMEM_PROT_* flags (except RTMEM_PROT_NONE).
+ * @param   offSub          Where in the object to start mapping. If non-zero
+ *                          the value must be page aligned and cbSub must be
+ *                          non-zero as well.
+ * @param   cbSub           The size of the part of the object to be mapped. If
+ *                          zero the entire object is mapped. The value must be
+ *                          page aligned.
+ */
+#define RTR0MemObjMapKernelEx(pMemObj, MemObjToMap, pvFixed, uAlignment, fProt, offSub, cbSub) \
+    RTR0MemObjMapKernelExTag((pMemObj), (MemObjToMap), (pvFixed), (uAlignment), (fProt), (offSub), (cbSub), RTMEM_TAG)
+
+/**
+ * Maps a memory object into kernel virtual address space (custom tag).
+ *
+ * The ability to map subsections of the object into kernel space is currently
+ * not implemented on all platforms. All/Most of platforms supports mapping the
+ * whole object into  kernel space.
+ *
+ * @returns IPRT status code.
+ * @retval  VERR_NOT_SUPPORTED if it's not possible to map a subsection of a
+ *          memory object on this platform. When you hit this, try implement it.
+ *
+ * @param   pMemObj         Where to store the ring-0 memory object handle of the mapping object.
+ * @param   MemObjToMap     The object to be map.
+ * @param   pvFixed         Requested address. (void *)-1 means any address. This must match the alignment.
+ * @param   uAlignment      The alignment of the reserved memory.
+ *                          Supported values are 0 (alias for PAGE_SIZE), PAGE_SIZE, _2M and _4M.
+ * @param   fProt           Combination of RTMEM_PROT_* flags (except RTMEM_PROT_NONE).
+ * @param   offSub          Where in the object to start mapping. If non-zero
+ *                          the value must be page aligned and cbSub must be
+ *                          non-zero as well.
+ * @param   cbSub           The size of the part of the object to be mapped. If
+ *                          zero the entire object is mapped. The value must be
+ *                          page aligned.
+ * @param   pszTag          Allocation tag used for statistics and such.
+ */
+RTR0DECL(int) RTR0MemObjMapKernelExTag(PRTR0MEMOBJ pMemObj, RTR0MEMOBJ MemObjToMap, void *pvFixed, size_t uAlignment,
+                                       unsigned fProt, size_t offSub, size_t cbSub, const char *pszTag);
+
+/**
+ * Maps a memory object into user virtual address space in the current process
+ * (default tag).
+ *
+ * @returns IPRT status code.
+ * @param   pMemObj         Where to store the ring-0 memory object handle of the mapping object.
+ * @param   MemObjToMap     The object to be map.
+ * @param   R3PtrFixed      Requested address. (RTR3PTR)-1 means any address. This must match the alignment.
+ * @param   uAlignment      The alignment of the reserved memory.
+ *                          Supported values are 0 (alias for PAGE_SIZE), PAGE_SIZE, _2M and _4M.
+ * @param   fProt           Combination of RTMEM_PROT_* flags (except RTMEM_PROT_NONE).
+ * @param   R0Process       The process to map the memory into. NIL_R0PROCESS is an alias for the current one.
+ */
+#define RTR0MemObjMapUser(pMemObj, MemObjToMap, R3PtrFixed, uAlignment, fProt, R0Process) \
+    RTR0MemObjMapUserTag((pMemObj), (MemObjToMap), (R3PtrFixed), (uAlignment), (fProt), (R0Process), RTMEM_TAG)
+
+/**
+ * Maps a memory object into user virtual address space in the current process
+ * (custom tag).
+ *
+ * @returns IPRT status code.
+ * @param   pMemObj         Where to store the ring-0 memory object handle of the mapping object.
+ * @param   MemObjToMap     The object to be map.
+ * @param   R3PtrFixed      Requested address. (RTR3PTR)-1 means any address. This must match the alignment.
+ * @param   uAlignment      The alignment of the reserved memory.
+ *                          Supported values are 0 (alias for PAGE_SIZE), PAGE_SIZE, _2M and _4M.
+ * @param   fProt           Combination of RTMEM_PROT_* flags (except RTMEM_PROT_NONE).
+ * @param   R0Process       The process to map the memory into. NIL_R0PROCESS is an alias for the current one.
+ * @param   pszTag          Allocation tag used for statistics and such.
+ */
+RTR0DECL(int) RTR0MemObjMapUserTag(PRTR0MEMOBJ pMemObj, RTR0MEMOBJ MemObjToMap, RTR3PTR R3PtrFixed,
+                                   size_t uAlignment, unsigned fProt, RTR0PROCESS R0Process, const char *pszTag);
+
+/**
+ * Change the page level protection of one or more pages in a memory object.
+ *
+ * @returns IPRT status code.
+ * @retval  VERR_NOT_SUPPORTED if the OS doesn't provide any way to manipulate
+ *          page level protection. The caller must handle this status code
+ *          gracefully. (Note that it may also occur if the implementation is
+ *          missing, in which case just go ahead and implement it.)
+ *
+ * @param   hMemObj         Memory object handle.
+ * @param   offSub          Offset into the memory object. Must be page aligned.
+ * @param   cbSub           Number of bytes to change the protection of. Must be
+ *                          page aligned.
+ * @param   fProt           Combination of RTMEM_PROT_* flags.
+ */
+RTR0DECL(int) RTR0MemObjProtect(RTR0MEMOBJ hMemObj, size_t offSub, size_t cbSub, uint32_t fProt);
+
+#endif /* IN_RING0 */
+
+/** @} */
+
+RT_C_DECLS_END
+
+#endif
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/include/iprt/mp.h
@@ -0,0 +1,477 @@
+/** @file
+ * IPRT - Multiprocessor.
+ */
+
+/*
+ * Copyright (C) 2008-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+#ifndef ___iprt_mp_h
+#define ___iprt_mp_h
+
+#include <iprt/cdefs.h>
+#include <iprt/types.h>
+
+
+RT_C_DECLS_BEGIN
+
+/** @defgroup grp_rt_mp RTMp - Multiprocessor
+ * @ingroup grp_rt
+ * @{
+ */
+
+/**
+ * Gets the identifier of the CPU executing the call.
+ *
+ * When called from a system mode where scheduling is active, like ring-3 or
+ * kernel mode with interrupts enabled on some systems, no assumptions should
+ * be made about the current CPU when the call returns.
+ *
+ * @returns CPU Id.
+ */
+RTDECL(RTCPUID) RTMpCpuId(void);
+
+/**
+ * Get the CPU set index of the CPU executing the call.
+ *
+ * Same scheduling warnings as for RTMpCpuId().
+ *
+ * @returns CPU set index.
+ */
+RTDECL(int) RTMpCurSetIndex(void);
+
+/**
+ * Get the CPU set index and identifier of the CPU executing the call.
+ *
+ * Same scheduling warnings as for RTMpCpuId().
+ *
+ * @returns CPU set index.
+ * @param   pidCpu      Where to return the CPU identifier. (not optional)
+ */
+RTDECL(int) RTMpCurSetIndexAndId(PRTCPUID pidCpu);
+
+/**
+ * Converts a CPU identifier to a CPU set index.
+ *
+ * This may or may not validate the presence of the CPU.
+ *
+ * @returns The CPU set index on success, -1 on failure.
+ * @param   idCpu       The identifier of the CPU.
+ */
+RTDECL(int) RTMpCpuIdToSetIndex(RTCPUID idCpu);
+
+/**
+ * Converts a CPU set index to a a CPU identifier.
+ *
+ * This may or may not validate the presence of the CPU, so, use
+ * RTMpIsCpuPossible for that.
+ *
+ * @returns The corresponding CPU identifier, NIL_RTCPUID on failure.
+ * @param   iCpu    The CPU set index.
+ */
+RTDECL(RTCPUID) RTMpCpuIdFromSetIndex(int iCpu);
+
+/**
+ * Gets the max CPU identifier (inclusive).
+ *
+ * Intended for brute force enumerations, but use with
+ * care as it may be expensive.
+ *
+ * @returns The current higest CPU identifier value.
+ */
+RTDECL(RTCPUID) RTMpGetMaxCpuId(void);
+
+/**
+ * Gets the size of a CPU array that is indexed by CPU set index.
+ *
+ * This takes both online, offline and hot-plugged cpus into account.
+ *
+ * @returns Number of elements.
+ *
+ * @remarks Use RTMpCpuIdToSetIndex to convert a RTCPUID into an array index.
+ */
+RTDECL(uint32_t) RTMpGetArraySize(void);
+
+/**
+ * Checks if a CPU exists in the system or may possibly be hotplugged later.
+ *
+ * @returns true/false accordingly.
+ * @param   idCpu       The identifier of the CPU.
+ */
+RTDECL(bool) RTMpIsCpuPossible(RTCPUID idCpu);
+
+/**
+ * Gets set of the CPUs present in the system plus any that may
+ * possibly be hotplugged later.
+ *
+ * @returns pSet.
+ * @param   pSet    Where to put the set.
+ */
+RTDECL(PRTCPUSET) RTMpGetSet(PRTCPUSET pSet);
+
+/**
+ * Get the count of CPUs present in the system plus any that may
+ * possibly be hotplugged later.
+ *
+ * @returns The count.
+ * @remarks Don't use this for CPU array sizing, use RTMpGetArraySize instead.
+ */
+RTDECL(RTCPUID) RTMpGetCount(void);
+
+/**
+ * Get the count of physical CPU cores present in the system plus any that may
+ * possibly be hotplugged later.
+ *
+ * @returns The number of cores.
+ */
+RTDECL(RTCPUID) RTMpGetCoreCount(void);
+
+/**
+ * Gets set of the CPUs present that are currently online.
+ *
+ * @returns pSet.
+ * @param   pSet    Where to put the set.
+ */
+RTDECL(PRTCPUSET) RTMpGetOnlineSet(PRTCPUSET pSet);
+
+/**
+ * Get the count of CPUs that are currently online.
+ *
+ * @return The count.
+ */
+RTDECL(RTCPUID) RTMpGetOnlineCount(void);
+
+/**
+ * Get the count of physical CPU cores in the system with one or more online
+ * threads.
+ *
+ * @returns The number of online cores.
+ */
+RTDECL(RTCPUID) RTMpGetOnlineCoreCount(void);
+
+/**
+ * Checks if a CPU is online or not.
+ *
+ * @returns true/false accordingly.
+ * @param   idCpu       The identifier of the CPU.
+ */
+RTDECL(bool) RTMpIsCpuOnline(RTCPUID idCpu);
+
+
+/**
+ * Gets set of the CPUs present in the system.
+ *
+ * @returns pSet.
+ * @param   pSet    Where to put the set.
+ */
+RTDECL(PRTCPUSET) RTMpGetPresentSet(PRTCPUSET pSet);
+
+/**
+ * Get the count of CPUs that are present in the system.
+ *
+ * @return The count.
+ */
+RTDECL(RTCPUID) RTMpGetPresentCount(void);
+
+/**
+ * Get the count of physical CPU cores present in the system.
+ *
+ * @returns The number of cores.
+ */
+RTDECL(RTCPUID) RTMpGetPresentCoreCount(void);
+
+/**
+ * Checks if a CPU is present in the system.
+ *
+ * @returns true/false accordingly.
+ * @param   idCpu       The identifier of the CPU.
+ */
+RTDECL(bool) RTMpIsCpuPresent(RTCPUID idCpu);
+
+
+/**
+ * Get the current frequency of a CPU.
+ *
+ * The CPU must be online.
+ *
+ * @returns The frequency as MHz. 0 if the CPU is offline
+ *          or the information is not available.
+ * @param   idCpu       The identifier of the CPU.
+ */
+RTDECL(uint32_t) RTMpGetCurFrequency(RTCPUID idCpu);
+
+/**
+ * Get the maximum frequency of a CPU.
+ *
+ * The CPU must be online.
+ *
+ * @returns The frequency as MHz. 0 if the CPU is offline
+ *          or the information is not available.
+ * @param   idCpu       The identifier of the CPU.
+ */
+RTDECL(uint32_t) RTMpGetMaxFrequency(RTCPUID idCpu);
+
+/**
+ * Get the CPU description string.
+ *
+ * The CPU must be online.
+ *
+ * @returns IPRT status code.
+ * @param   idCpu       The identifier of the CPU.  NIL_RTCPUID can be used to
+ *                      indicate the current CPU.
+ * @param   pszBuf      The output buffer.
+ * @param   cbBuf       The size of the output buffer.
+ */
+RTDECL(int) RTMpGetDescription(RTCPUID idCpu, char *pszBuf, size_t cbBuf);
+
+
+#ifdef IN_RING0
+
+/**
+ * Check if there's work (DPCs on Windows) pending on the current CPU.
+ *
+ * @return true if there's pending work on the current CPU, false otherwise.
+ */
+RTDECL(bool) RTMpIsCpuWorkPending(void);
+
+
+/**
+ * Worker function passed to RTMpOnAll, RTMpOnOthers and RTMpOnSpecific that
+ * is to be called on the target cpus.
+ *
+ * @param   idCpu       The identifier for the CPU the function is called on.
+ * @param   pvUser1     The 1st user argument.
+ * @param   pvUser2     The 2nd user argument.
+ */
+typedef DECLCALLBACK(void) FNRTMPWORKER(RTCPUID idCpu, void *pvUser1, void *pvUser2);
+/** Pointer to a FNRTMPWORKER. */
+typedef FNRTMPWORKER *PFNRTMPWORKER;
+
+/** @name RTMPON_F_XXX - RTMpOn flags.
+ * @{ */
+/** Caller doesn't care if pfnWorker is executed at the same time on the
+ *  specified CPUs or not, as long as it gets executed. */
+#define RTMPON_F_WHATEVER_EXEC      0
+/** The caller insists on pfnWorker being executed more or less concurrently
+ * on the specified CPUs. */
+#define RTMPON_F_CONCURRENT_EXEC    RT_BIT_32(1)
+/** Mask of valid bits. */
+#define RTMPON_F_VALID_MASK         UINT32_C(0x00000001)
+/** @}*/
+
+/**
+ * Checks if the RTMpOnAll() is safe with regards to all threads executing
+ * concurrently.
+ *
+ * If for instance, the RTMpOnAll() is implemented in a way where the threads
+ * might cause a classic deadlock, it is considered -not- concurrent safe.
+ * Windows currently is one such platform where it isn't safe.
+ *
+ * @returns true if RTMpOnAll() is concurrent safe, false otherwise.
+ */
+RTDECL(bool) RTMpOnAllIsConcurrentSafe(void);
+
+/**
+ * Executes a function on each (online) CPU in the system.
+ *
+ * @returns IPRT status code.
+ * @retval  VINF_SUCCESS on success.
+ * @retval  VERR_NOT_SUPPORTED if this kind of operation isn't supported by the system.
+ *
+ * @param   pfnWorker       The worker function.
+ * @param   pvUser1         The first user argument for the worker.
+ * @param   pvUser2         The second user argument for the worker.
+ *
+ * @remarks The execution isn't in any way guaranteed to be simultaneous,
+ *          it might even be serial (cpu by cpu).
+ */
+RTDECL(int) RTMpOnAll(PFNRTMPWORKER pfnWorker, void *pvUser1, void *pvUser2);
+
+/**
+ * Executes a function on a all other (online) CPUs in the system.
+ *
+ * The caller must disable preemption prior to calling this API if the outcome
+ * is to make any sense. But do *not* disable interrupts.
+ *
+ * @returns IPRT status code.
+ * @retval  VINF_SUCCESS on success.
+ * @retval  VERR_NOT_SUPPORTED if this kind of operation isn't supported by the system.
+ *
+ * @param   pfnWorker       The worker function.
+ * @param   pvUser1         The first user argument for the worker.
+ * @param   pvUser2         The second user argument for the worker.
+ *
+ * @remarks The execution isn't in any way guaranteed to be simultaneous,
+ *          it might even be serial (cpu by cpu).
+ */
+RTDECL(int) RTMpOnOthers(PFNRTMPWORKER pfnWorker, void *pvUser1, void *pvUser2);
+
+/**
+ * Executes a function on a specific CPU in the system.
+ *
+ * @returns IPRT status code.
+ * @retval  VINF_SUCCESS on success.
+ * @retval  VERR_NOT_SUPPORTED if this kind of operation isn't supported by the system.
+ * @retval  VERR_CPU_OFFLINE if the CPU is offline.
+ * @retval  VERR_CPU_NOT_FOUND if the CPU wasn't found.
+ *
+ * @param   idCpu           The id of the CPU.
+ * @param   pfnWorker       The worker function.
+ * @param   pvUser1         The first user argument for the worker.
+ * @param   pvUser2         The second user argument for the worker.
+ */
+RTDECL(int) RTMpOnSpecific(RTCPUID idCpu, PFNRTMPWORKER pfnWorker, void *pvUser1, void *pvUser2);
+
+/**
+ * Executes a function on two specific CPUs in the system.
+ *
+ * @returns IPRT status code.
+ * @retval  VINF_SUCCESS on success.
+ * @retval  VERR_NOT_SUPPORTED if this kind of operation isn't supported by the
+ *          system or if the specified modifier flag isn't supported.
+ * @retval  VERR_CPU_OFFLINE if one or more of the CPUs are offline (see
+ *          remarks).
+ * @retval  VERR_CPU_NOT_FOUND if on or both of the CPUs weren't found.
+ * @retval  VERR_NOT_ALL_CPUS_SHOWED if one of the CPUs didn't show.
+ *
+ * @param   idCpu1          The id of the first CPU.
+ * @param   idCpu2          The id of the second CPU.
+ * @param   fFlags          Combination of RTMPON_F_XXX flags.
+ * @param   pfnWorker       The worker function.
+ * @param   pvUser1         The first user argument for the worker.
+ * @param   pvUser2         The second user argument for the worker.
+ *
+ * @remarks There is a possible race between one (or both) of the CPUs going
+ *          offline while setting up the call.  The worker function must take
+ *          this into account.
+ */
+RTDECL(int) RTMpOnPair(RTCPUID idCpu1, RTCPUID idCpu2, uint32_t fFlags, PFNRTMPWORKER pfnWorker, void *pvUser1, void *pvUser2);
+
+/**
+ * Indicates whether RTMpOnPair supports running the pfnWorker concurrently on
+ * both CPUs using RTMPON_F_CONCURRENT_EXEC.
+ *
+ * @returns true if supported, false if not.
+ */
+RTDECL(bool) RTMpOnPairIsConcurrentExecSupported(void);
+
+
+/**
+ * Pokes the specified CPU.
+ *
+ * This should cause the execution on the CPU to be interrupted and forcing it
+ * to enter kernel context. It is optimized version of a RTMpOnSpecific call
+ * with a worker which returns immediately.
+ *
+ * @returns IPRT status code.
+ * @retval  VERR_NOT_SUPPORTED if this kind of operation isn't supported by the
+ *          system. The caller must not automatically assume that this API works
+ *          when any of the RTMpOn* APIs works. This is because not all systems
+ *          supports unicast MP events and this API will not be implemented as a
+ *          broadcast.
+ * @retval  VERR_CPU_OFFLINE if the CPU is offline.
+ * @retval  VERR_CPU_NOT_FOUND if the CPU wasn't found.
+ *
+ * @param   idCpu           The id of the CPU to poke.
+ */
+RTDECL(int) RTMpPokeCpu(RTCPUID idCpu);
+
+
+/**
+ * MP event, see FNRTMPNOTIFICATION.
+ */
+typedef enum RTMPEVENT
+{
+    /** The CPU goes online. */
+    RTMPEVENT_ONLINE = 1,
+    /** The CPU goes offline. */
+    RTMPEVENT_OFFLINE
+} RTMPEVENT;
+
+/**
+ * Notification callback.
+ *
+ * The context this is called in differs a bit from platform to platform, so be
+ * careful while in here.
+ *
+ * On Windows we're running with IRQL=PASSIVE_LEVEL (reschedulable) according to
+ * the KeRegisterProcessorChangeCallback documentation - unrestricted API
+ * access. Probably not being called on the onlined/offlined CPU...
+ *
+ * On Solaris we're holding the cpu_lock, IPL/SPL/PIL is not yet known, however
+ * we will most likely -not- be firing on the CPU going offline/online.
+ *
+ * On Linux it looks like we're called with preemption enabled on any CPU and
+ * not necessarily on the CPU going offline/online.
+ *
+ * There is no callbacks for darwin at the moment, due to lack of suitable KPI.
+ *
+ * @param   idCpu       The CPU this applies to.
+ * @param   enmEvent    The event.
+ * @param   pvUser      The user argument.
+ */
+typedef DECLCALLBACK(void) FNRTMPNOTIFICATION(RTMPEVENT enmEvent, RTCPUID idCpu, void *pvUser);
+/** Pointer to a FNRTMPNOTIFICATION(). */
+typedef FNRTMPNOTIFICATION *PFNRTMPNOTIFICATION;
+
+/**
+ * Registers a notification callback for cpu events.
+ *
+ * On platforms which doesn't do cpu offline/online events this API
+ * will just be a no-op that pretends to work.
+ *
+ * @todo We'll be adding a flag to this soon to indicate whether the callback should be called on all
+ *       CPUs that are currently online while it's being registered. This is to help avoid some race
+ *       conditions (we'll hopefully be able to implement this on linux, solaris/win is no issue).
+ *
+ * @returns IPRT status code.
+ * @retval  VINF_SUCCESS on success.
+ * @retval  VERR_NO_MEMORY if a registration record cannot be allocated.
+ * @retval  VERR_ALREADY_EXISTS if the pfnCallback and pvUser already exist
+ *          in the callback list.
+ *
+ * @param   pfnCallback     The callback.
+ * @param   pvUser          The user argument to the callback function.
+ */
+RTDECL(int) RTMpNotificationRegister(PFNRTMPNOTIFICATION pfnCallback, void *pvUser);
+
+/**
+ * This deregisters a notification callback registered via RTMpNotificationRegister().
+ *
+ * The pfnCallback and pvUser arguments must be identical to the registration call
+ * of we won't find the right entry.
+ *
+ * @returns IPRT status code.
+ * @retval  VINF_SUCCESS on success.
+ * @retval  VERR_NOT_FOUND if no matching entry was found.
+ *
+ * @param   pfnCallback     The callback.
+ * @param   pvUser          The user argument to the callback function.
+ */
+RTDECL(int) RTMpNotificationDeregister(PFNRTMPNOTIFICATION pfnCallback, void *pvUser);
+
+#endif /* IN_RING0 */
+
+/** @} */
+
+RT_C_DECLS_END
+
+#endif
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/include/iprt/net.h
@@ -0,0 +1,962 @@
+/** @file
+ * IPRT - Network Protocols.
+ */
+
+/*
+ * Copyright (C) 2008-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+#ifndef ___iprt_net_h
+#define ___iprt_net_h
+
+#include <iprt/cdefs.h>
+#include <iprt/types.h>
+#include <iprt/assert.h>
+
+
+RT_C_DECLS_BEGIN
+
+/** @defgroup grp_rt_net     RTNet - Network Protocols
+ * @ingroup grp_rt
+ * @{
+ */
+
+/**
+ * Converts an stringified Ethernet MAC address into the RTMAC representation.
+ *
+ * @todo This should be move to some generic part of the runtime.
+ *
+ * @returns VINF_SUCCESS on success, VERR_GETOPT_INVALID_ARGUMENT_FORMAT on
+ *          failure.
+ *
+ * @param   pszAddr         The address string to convert.
+ * @param   pMacAddr        Where to store the result.
+ */
+RTDECL(int) RTNetStrToMacAddr(const char *pszAddr, PRTMAC pMacAddr);
+
+/**
+ * IPv4 address.
+ */
+typedef RTUINT32U RTNETADDRIPV4;
+AssertCompileSize(RTNETADDRIPV4, 4);
+/** Pointer to a IPv4 address. */
+typedef RTNETADDRIPV4 *PRTNETADDRIPV4;
+/** Pointer to a const IPv4 address. */
+typedef RTNETADDRIPV4 const *PCRTNETADDRIPV4;
+
+/**
+ * Tests if the given string is an IPv4 address.
+ *
+ * @returns boolean.
+ * @param   pcszAddr        String which may be an IPv4 address.
+ */
+RTDECL(bool) RTNetIsIPv4AddrStr(const char *pcszAddr);
+
+/**
+ * Tests if the given string is a wildcard IPv4 address.
+ *
+ * @returns boolean.
+ * @param   pcszAddr        String which may be an IPv4 address.
+ */
+RTDECL(bool) RTNetStrIsIPv4AddrAny(const char *pcszAddr);
+
+/**
+ * Parses dotted-decimal IPv4 address into RTNETADDRIPV4 representation.
+ *
+ * @returns VINF_SUCCESS on success, VERR_INVALID_PARAMETER on
+ *          failure.
+ *
+ * @param   pcszAddr        The value to convert.
+ * @param   ppszNext        Where to store the pointer to the first char
+ *                            following the address. (Optional)
+ * @param   pAddr           Where to store the result.
+ */
+RTDECL(int) RTNetStrToIPv4AddrEx(const char *pcszAddr, PRTNETADDRIPV4 pAddr, char **ppszNext);
+
+/**
+ * Parses dotted-decimal IPv4 address into RTNETADDRIPV4 representation.
+ * Leading and trailing whitespace is ignored.
+ *
+ * @returns VINF_SUCCESS on success, VERR_INVALID_PARAMETER on
+ *          failure.
+ *
+ * @param   pcszAddr        The value to convert.
+ * @param   pAddr           Where to store the result.
+ */
+RTDECL(int) RTNetStrToIPv4Addr(const char *pcszAddr, PRTNETADDRIPV4 pAddr);
+
+/**
+ * IPv6 address.
+ */
+typedef RTUINT128U RTNETADDRIPV6;
+AssertCompileSize(RTNETADDRIPV6, 16);
+/** Pointer to a IPv6 address. */
+typedef RTNETADDRIPV6 *PRTNETADDRIPV6;
+/** Pointer to a const IPv6 address. */
+typedef RTNETADDRIPV6 const *PCRTNETADDRIPV6;
+
+/**
+ * Tests if the given string is a valid IPv6 address.
+ *
+ * @returns @c true if it is, @c false if not.
+ * @param   pszAddress          String which may be an IPv6 address.
+ */
+RTDECL(bool) RTNetIsIPv6AddrStr(const char *pszAddress);
+
+/**
+ * Tests if the given string is a wildcard IPv6 address.
+ *
+ * @returns @c true if it is, @c false if not.
+ * @param   pszAddress          String which may be an IPv6 address.
+ */
+RTDECL(bool) RTNetStrIsIPv6AddrAny(const char *pszAddress);
+
+/**
+ * Parses IPv6 address into RTNETADDRIPV6 representation.
+ *
+ * @returns VINF_SUCCESS on success, VERR_INVALID_PARAMETER on
+ *          failure.
+ *
+ * @param   pcszAddr        The value to convert.
+ * @param   ppszNext        Where to store the pointer to the first char
+ *                            following the address. (Optional)
+ * @param   pAddr           Where to store the result.
+ */
+RTDECL(int) RTNetStrToIPv6AddrEx(const char *pcszAddr, PRTNETADDRIPV6 pAddr, char **ppszNext);
+
+/**
+ * Parses IPv6 address into RTNETADDRIPV6 representation.
+ * Leading and trailing whitespace is ignored.
+ *
+ * @returns VINF_SUCCESS on success, VERR_INVALID_PARAMETER on
+ *          failure.
+ *
+ * @param   pcszAddr        The value to convert.
+ * @param   ppszZone        Where to store the pointer to the first char
+ *                            of the zone id.  NULL is stored if there is
+ *                            no zone id.
+ * @param   pAddr           Where to store the result.
+ */
+RTDECL(int) RTNetStrToIPv6Addr(const char *pcszAddr, PRTNETADDRIPV6 pAddr, char **ppszZone);
+
+/**
+ * IPX address.
+ */
+#pragma pack(1)
+typedef struct RTNETADDRIPX
+{
+    /** The network ID. */
+    uint32_t Network;
+    /** The node ID. (Defaults to the MAC address apparently.) */
+    RTMAC Node;
+} RTNETADDRIPX;
+#pragma pack()
+AssertCompileSize(RTNETADDRIPX, 4+6);
+/** Pointer to an IPX address. */
+typedef RTNETADDRIPX *PRTNETADDRIPX;
+/** Pointer to a const IPX address. */
+typedef RTNETADDRIPX const *PCRTNETADDRIPX;
+
+/**
+ * Network address union.
+ *
+ * @remarks The size of this structure may change in the future.
+ */
+typedef union RTNETADDRU
+{
+    /** 64-bit view. */
+    uint64_t au64[2];
+    /** 32-bit view. */
+    uint32_t au32[4];
+    /** 16-bit view. */
+    uint16_t au16[8];
+    /** 8-bit view. */
+    uint8_t  au8[16];
+    /** IPv4 view. */
+    RTNETADDRIPV4 IPv4;
+#ifndef IPv6 /* Work around X11 and RDP defining IPv6 to 1. */
+    /** IPv6 view. */
+    RTNETADDRIPV6 IPv6;
+#endif
+    /** IPX view. */
+    RTNETADDRIPX Ipx;
+    /** MAC address view. */
+    RTMAC Mac;
+} RTNETADDRU;
+AssertCompileSize(RTNETADDRU, 16);
+/** Pointer to an address union. */
+typedef RTNETADDRU *PRTNETADDRU;
+/** Pointer to a const address union. */
+typedef RTNETADDRU const *PCRTNETADDRU;
+
+/**
+ * Network address type.
+ *
+ * @remarks The value assignments may change in the future.
+ */
+typedef enum RTNETADDRTYPE
+{
+    /** The invalid 0 entry. */
+    RTNETADDRTYPE_INVALID = 0,
+    /** IP version 4. */
+    RTNETADDRTYPE_IPV4,
+    /** IP version 6. */
+    RTNETADDRTYPE_IPV6,
+    /** IPX. */
+    RTNETADDRTYPE_IPX,
+    /** MAC address. */
+    RTNETADDRTYPE_MAC,
+    /** The end of the valid values. */
+    RTNETADDRTYPE_END,
+    /** The usual 32-bit hack. */
+    RTNETADDRTYPE_32_BIT_HACK = 0x7fffffff
+} RTNETADDRTYPE;
+/** Pointer to a network address type. */
+typedef RTNETADDRTYPE *PRTNETADDRTYPE;
+/** Pointer to a const network address type. */
+typedef RTNETADDRTYPE const  *PCRTNETADDRTYPE;
+
+/**
+ * Network address.
+ *
+ * @remarks The size and type values may change.
+ */
+typedef struct RTNETADDR
+{
+    /** The address union. */
+    RTNETADDRU      uAddr;
+    /** Indicates which view of @a u that is valid. */
+    RTNETADDRTYPE   enmType;
+    /** The port number for IPv4 and IPv6 addresses.  This is set to
+     *  RTNETADDR_NA_PORT if not applicable. */
+    uint32_t        uPort;
+} RTNETADDR;
+/** Pointer to a network address. */
+typedef RTNETADDR *PRTNETADDR;
+/** Pointer to a const network address. */
+typedef RTNETADDR const *PCRTNETADDR;
+
+/** The not applicable value of  RTNETADDR::uPort value use to inid. */
+#define RTNETADDR_PORT_NA       UINT32_MAX
+
+/**
+ * Ethernet header.
+ */
+#pragma pack(1)
+typedef struct RTNETETHERHDR
+{
+    RTMAC       DstMac;
+    RTMAC       SrcMac;
+    /** Ethernet frame type or frame size, depending on the kind of ethernet.
+     * This is big endian on the wire. */
+    uint16_t    EtherType;
+} RTNETETHERHDR;
+#pragma pack()
+AssertCompileSize(RTNETETHERHDR, 14);
+/** Pointer to an ethernet header. */
+typedef RTNETETHERHDR *PRTNETETHERHDR;
+/** Pointer to a const ethernet header. */
+typedef RTNETETHERHDR const *PCRTNETETHERHDR;
+
+/** @name EtherType (RTNETETHERHDR::EtherType)
+ * @{ */
+#define RTNET_ETHERTYPE_IPV4    UINT16_C(0x0800)
+#define RTNET_ETHERTYPE_ARP     UINT16_C(0x0806)
+#define RTNET_ETHERTYPE_IPV6    UINT16_C(0x86dd)
+#define RTNET_ETHERTYPE_VLAN    UINT16_C(0x8100)
+#define RTNET_ETHERTYPE_IPX_1   UINT16_C(0x8037)
+#define RTNET_ETHERTYPE_IPX_2   UINT16_C(0x8137)
+#define RTNET_ETHERTYPE_IPX_3   UINT16_C(0x8138)
+/** @} */
+
+
+/**
+ * IPv4 header.
+ * All is bigendian on the wire.
+ */
+#pragma pack(1)
+typedef struct RTNETIPV4
+{
+#ifdef RT_BIG_ENDIAN
+    unsigned int    ip_v : 4;
+    unsigned int    ip_hl : 4;
+    unsigned int    ip_tos : 8;
+    unsigned int    ip_len : 16;
+#else
+    /** 00:0 - Header length given as a 32-bit word count. */
+    unsigned int    ip_hl : 4;
+    /** 00:4 - Header version. */
+    unsigned int    ip_v : 4;
+    /** 01 - Type of service. */
+    unsigned int    ip_tos : 8;
+    /** 02 - Total length (header + data). */
+    unsigned int    ip_len : 16;
+#endif
+    /** 04 - Packet idenficiation. */
+    uint16_t        ip_id;
+    /** 06 - Offset if fragmented. */
+    uint16_t        ip_off;
+    /** 08 - Time to live. */
+    uint8_t         ip_ttl;
+    /** 09 - Protocol. */
+    uint8_t         ip_p;
+    /** 0a - Header check sum. */
+    uint16_t        ip_sum;
+    /** 0c - Source address. */
+    RTNETADDRIPV4   ip_src;
+    /** 10 - Destination address. */
+    RTNETADDRIPV4   ip_dst;
+    /** 14 - Options (optional). */
+    uint32_t        ip_options[1];
+} RTNETIPV4;
+#pragma pack()
+AssertCompileSize(RTNETIPV4, 6 * 4);
+/** Pointer to a IPv4 header. */
+typedef RTNETIPV4 *PRTNETIPV4;
+/** Pointer to a const IPv4 header. */
+typedef RTNETIPV4 const *PCRTNETIPV4;
+
+/** The minimum IPv4 header length (in bytes).
+ * Up to and including RTNETIPV4::ip_dst. */
+#define RTNETIPV4_MIN_LEN   (20)
+
+
+/** @name IPv4 Protocol Numbers
+ * @{ */
+/** IPv4: ICMP */
+#define RTNETIPV4_PROT_ICMP     (1)
+/** IPv4: TCP */
+#define RTNETIPV4_PROT_TCP      (6)
+/** IPv4: UDP */
+#define RTNETIPV4_PROT_UDP      (17)
+/** @} */
+
+/** @name Common IPv4 Port Assignments
+ * @{
+ */
+/** Boostrap Protocol / DHCP) Server. */
+#define RTNETIPV4_PORT_BOOTPS   (67)
+/** Boostrap Protocol / DHCP) Client. */
+#define RTNETIPV4_PORT_BOOTPC   (68)
+/** @} */
+
+/** @name IPv4 Flags
+ * @{ */
+/** IPv4: Don't fragment */
+#define RTNETIPV4_FLAGS_DF      (0x4000)
+/** IPv4: More fragments */
+#define RTNETIPV4_FLAGS_MF      (0x2000)
+/** @} */
+
+RTDECL(uint16_t) RTNetIPv4HdrChecksum(PCRTNETIPV4 pIpHdr);
+RTDECL(bool)     RTNetIPv4IsHdrValid(PCRTNETIPV4 pIpHdr, size_t cbHdrMax, size_t cbPktMax, bool fChecksum);
+RTDECL(uint32_t) RTNetIPv4PseudoChecksum(PCRTNETIPV4 pIpHdr);
+RTDECL(uint32_t) RTNetIPv4PseudoChecksumBits(RTNETADDRIPV4 SrcAddr, RTNETADDRIPV4 DstAddr, uint8_t bProtocol, uint16_t cbPkt);
+RTDECL(uint32_t) RTNetIPv4AddDataChecksum(void const *pvData, size_t cbData, uint32_t u32Sum, bool *pfOdd);
+RTDECL(uint16_t) RTNetIPv4FinalizeChecksum(uint32_t u32Sum);
+
+
+/**
+ * IPv6 header.
+ * All is bigendian on the wire.
+ */
+#pragma pack(1)
+typedef struct RTNETIPV6
+{
+    /** Version (4 bits), Traffic Class (8 bits) and Flow Lable (20 bits).
+     * @todo this is probably mislabeled - ip6_flow vs. ip6_vfc, fix later. */
+    uint32_t        ip6_vfc;
+    /** 04 - Payload length, including extension headers. */
+    uint16_t        ip6_plen;
+    /** 06 - Next header type (RTNETIPV4_PROT_XXX). */
+    uint8_t         ip6_nxt;
+    /** 07 - Hop limit. */
+    uint8_t         ip6_hlim;
+    /** xx - Source address. */
+    RTNETADDRIPV6   ip6_src;
+    /** xx - Destination address. */
+    RTNETADDRIPV6   ip6_dst;
+} RTNETIPV6;
+#pragma pack()
+AssertCompileSize(RTNETIPV6, 8 + 16 + 16);
+/** Pointer to a IPv6 header. */
+typedef RTNETIPV6 *PRTNETIPV6;
+/** Pointer to a const IPv6 header. */
+typedef RTNETIPV6 const *PCRTNETIPV6;
+
+/** The minimum IPv6 header length (in bytes).
+ * Up to and including RTNETIPV6::ip6_dst. */
+#define RTNETIPV6_MIN_LEN                           (40)
+#define RTNETIPV6_ICMPV6_ND_WITH_LLA_OPT_MIN_LEN    (32)
+
+RTDECL(uint32_t) RTNetIPv6PseudoChecksum(PCRTNETIPV6 pIpHdr);
+RTDECL(uint32_t) RTNetIPv6PseudoChecksumEx(PCRTNETIPV6 pIpHdr, uint8_t bProtocol, uint16_t cbPkt);
+RTDECL(uint32_t) RTNetIPv6PseudoChecksumBits(PCRTNETADDRIPV6 pSrcAddr, PCRTNETADDRIPV6 pDstAddr,
+                                             uint8_t bProtocol, uint16_t cbPkt);
+
+
+/**
+ * UDP header.
+ */
+#pragma pack(1)
+typedef struct RTNETUDP
+{
+    /** The source port. */
+    uint16_t    uh_sport;
+    /** The destination port. */
+    uint16_t    uh_dport;
+    /** The length of the UDP header and associated data. */
+    uint16_t    uh_ulen;
+    /** The checksum of the pseudo header, the UDP header and the data. */
+    uint16_t    uh_sum;
+} RTNETUDP;
+#pragma pack()
+AssertCompileSize(RTNETUDP, 8);
+/** Pointer to an UDP header. */
+typedef RTNETUDP *PRTNETUDP;
+/** Pointer to a const UDP header. */
+typedef RTNETUDP const *PCRTNETUDP;
+
+/** The minimum UDP packet length (in bytes). (RTNETUDP::uh_ulen) */
+#define RTNETUDP_MIN_LEN   (8)
+
+RTDECL(uint16_t) RTNetUDPChecksum(uint32_t u32Sum, PCRTNETUDP pUdpHdr);
+RTDECL(uint32_t) RTNetIPv4AddUDPChecksum(PCRTNETUDP pUdpHdr, uint32_t u32Sum);
+RTDECL(uint16_t) RTNetIPv4UDPChecksum(PCRTNETIPV4 pIpHdr, PCRTNETUDP pUdpHdr, void const *pvData);
+RTDECL(bool)     RTNetIPv4IsUDPSizeValid(PCRTNETIPV4 pIpHdr, PCRTNETUDP pUdpHdr, size_t cbPktMax);
+RTDECL(bool)     RTNetIPv4IsUDPValid(PCRTNETIPV4 pIpHdr, PCRTNETUDP pUdpHdr, void const *pvData, size_t cbPktMax, bool fChecksum);
+
+
+/**
+ * IPv4 BOOTP / DHCP packet.
+ */
+#pragma pack(1)
+typedef struct RTNETBOOTP
+{
+    /** 00 - The packet opcode (RTNETBOOTP_OP_*). */
+    uint8_t         bp_op;
+    /** 01 - Hardware address type. Same as RTNETARPHDR::ar_htype.  */
+    uint8_t         bp_htype;
+    /** 02 - Hardware address length. */
+    uint8_t         bp_hlen;
+    /** 03 - Gateway hops. */
+    uint8_t         bp_hops;
+    /** 04 - Transaction ID. */
+    uint32_t        bp_xid;
+    /** 08 - Seconds since boot started. */
+    uint16_t        bp_secs;
+    /** 0a - Unused (BOOTP) / Flags (DHCP) (RTNET_DHCP_FLAGS_*).  */
+    uint16_t        bp_flags;
+    /** 0c - Client IPv4 address. */
+    RTNETADDRIPV4   bp_ciaddr;
+    /** 10 - Your IPv4 address. */
+    RTNETADDRIPV4   bp_yiaddr;
+    /** 14 - Server IPv4 address. */
+    RTNETADDRIPV4   bp_siaddr;
+    /** 18 - Gateway IPv4 address. */
+    RTNETADDRIPV4   bp_giaddr;
+    /** 1c - Client hardware address. */
+    union
+    {
+        uint8_t     au8[16];
+        RTMAC       Mac;
+    }               bp_chaddr;
+    /** 2c - Server name. */
+    uint8_t         bp_sname[64];
+    /** 6c - File name / more DHCP options. */
+    uint8_t         bp_file[128];
+    /** ec - Vendor specific area (BOOTP) / Options (DHCP).
+     * @remark This is really 312 bytes in the DHCP version. */
+    union
+    {
+        uint8_t         au8[128];
+        struct DHCP
+        {
+            /** ec - The DHCP cookie (RTNET_DHCP_COOKIE). */
+            uint32_t    dhcp_cookie;
+            /** f0 - The DHCP options. */
+            uint8_t     dhcp_opts[124];
+        }           Dhcp;
+    }               bp_vend;
+
+} RTNETBOOTP;
+#pragma pack()
+AssertCompileSize(RTNETBOOTP, 0xec + 128);
+/** Pointer to a BOOTP / DHCP packet. */
+typedef RTNETBOOTP *PRTNETBOOTP;
+/** Pointer to a const BOOTP / DHCP packet. */
+typedef RTNETBOOTP const *PCRTNETBOOTP;
+
+/** Minimum BOOTP packet length. For quick validation, no standard thing really. */
+#define RTNETBOOTP_MIN_LEN          0xec
+/** Minimum DHCP packet length. For quick validation, no standard thing really. */
+#define RTNETBOOTP_DHCP_MIN_LEN     0xf1
+
+/** The normal size of the a DHCP packet (i.e. a RTNETBOOTP).
+ * Same as RTNET_DHCP_OPT_SIZE, just expressed differently.  */
+#define RTNET_DHCP_NORMAL_SIZE      (0xec + 4 + RTNET_DHCP_OPT_SIZE)
+/** The normal size of RTNETBOOTP::bp_vend::Dhcp::dhcp_opts.  */
+#define RTNET_DHCP_OPT_SIZE         (312 - 4)
+
+/** @name BOOTP packet opcode values
+ * @{ */
+#define RTNETBOOTP_OP_REQUEST       1
+#define RTNETBOOTP_OP_REPLY         2
+/** @} */
+
+/** @name DHCP flags (RTNETBOOTP::bp_flags)
+ * @{ */
+#define RTNET_DHCP_FLAGS_NO_BROADCAST   UINT16_C(0x8000) /** @todo check test!!! */
+/** @} */
+
+/** The DHCP cookie (network endian). */
+#define RTNET_DHCP_COOKIE           UINT32_C(0x63825363)
+
+/**
+ * An IPv4 DHCP option header.
+ */
+typedef struct RTNETDHCPOPT
+{
+    /** 00 - The DHCP option. */
+    uint8_t     dhcp_opt;
+    /** 01 - The data length (excluding this header). */
+    uint8_t     dhcp_len;
+    /*  02 - The option data follows here, optional and of variable length. */
+} RTNETDHCPOPT;
+AssertCompileSize(RTNETDHCPOPT, 2);
+/** Pointer to a DHCP option header. */
+typedef RTNETDHCPOPT *PRTNETDHCPOPT;
+/** Pointer to a const DHCP option header. */
+typedef RTNETDHCPOPT const *PCRTNETDHCPOPT;
+
+/** @name DHCP options
+ * @{ */
+/** 1 byte padding, this has no dhcp_len field. */
+#define RTNET_DHCP_OPT_PAD                  0
+
+/** The subnet mask. */
+#define RTNET_DHCP_OPT_SUBNET_MASK          1
+/** The time offset. */
+#define RTNET_DHCP_OPT_TIME_OFFSET          2
+/** The routers for the subnet. */
+#define RTNET_DHCP_OPT_ROUTERS              3
+/** Domain Name Server. */
+#define RTNET_DHCP_OPT_DNS                  6
+/** Host name. */
+#define RTNET_DHCP_OPT_HOST_NAME            12
+/** Domain name. */
+#define RTNET_DHCP_OPT_DOMAIN_NAME          15
+
+/** The requested address. */
+#define RTNET_DHCP_OPT_REQ_ADDR             50
+/** The lease time in seconds. */
+#define RTNET_DHCP_OPT_LEASE_TIME           51
+/** Option overload.
+ *  Indicates that the bp_file and/or bp_sname holds contains DHCP options. */
+#define RTNET_DHCP_OPT_OPTION_OVERLOAD      52
+/** Have a 8-bit message type value as data, see RTNET_DHCP_MT_*. */
+#define RTNET_DHCP_OPT_MSG_TYPE             53
+/** Server ID. */
+#define RTNET_DHCP_OPT_SERVER_ID            54
+/** Parameter request list. */
+#define RTNET_DHCP_OPT_PARAM_REQ_LIST       55
+/** The maximum DHCP message size a client is willing to accept. */
+#define RTNET_DHCP_OPT_MAX_DHCP_MSG_SIZE    57
+/** Client ID. */
+#define RTNET_DHCP_OPT_CLIENT_ID            61
+/** TFTP server name. */
+#define RTNET_DHCP_OPT_TFTP_SERVER_NAME     66
+/** Bootfile name. */
+#define RTNET_DHCP_OPT_BOOTFILE_NAME        67
+
+/** Marks the end of the DHCP options, this has no dhcp_len field. */
+#define RTNET_DHCP_OPT_END                  255
+/** @} */
+
+/** @name DHCP Message Types (option 53)
+ * @{ */
+#define RTNET_DHCP_MT_DISCOVER      1
+#define RTNET_DHCP_MT_OFFER         2
+#define RTNET_DHCP_MT_REQUEST       3
+#define RTNET_DHCP_MT_DECLINE       4
+#define RTNET_DHCP_MT_ACK           5
+#define RTNET_DHCP_MT_NAC           6
+#define RTNET_DHCP_MT_RELEASE       7
+#define RTNET_DHCP_MT_INFORM        8
+/** @} */
+
+/** @name DHCP Flags
+ * @{ */
+#define RTNET_DHCP_FLAG_BROADCAST   0x8000
+/** @} */
+
+RTDECL(bool) RTNetIPv4IsDHCPValid(PCRTNETUDP pUdpHdr, PCRTNETBOOTP pDhcp, size_t cbDhcp, uint8_t *pMsgType);
+
+
+/**
+ * IPv4 DHCP packet.
+ * @deprecated Use RTNETBOOTP.
+ */
+#pragma pack(1)
+typedef struct RTNETDHCP
+{
+    /** 00 - The packet opcode. */
+    uint8_t         Op;
+    /** Hardware address type. */
+    uint8_t         HType;
+    /** Hardware address length. */
+    uint8_t         HLen;
+    uint8_t         Hops;
+    uint32_t        XID;
+    uint16_t        Secs;
+    uint16_t        Flags;
+    /** Client IPv4 address. */
+    RTNETADDRIPV4   CIAddr;
+    /** Your IPv4 address. */
+    RTNETADDRIPV4   YIAddr;
+    /** Server IPv4 address. */
+    RTNETADDRIPV4   SIAddr;
+    /** Gateway IPv4 address. */
+    RTNETADDRIPV4   GIAddr;
+    /** Client hardware address. */
+    uint8_t         CHAddr[16];
+    /** Server name. */
+    uint8_t         SName[64];
+    uint8_t         File[128];
+    uint8_t         abMagic[4];
+    uint8_t         DhcpOpt;
+    uint8_t         DhcpLen; /* 1 */
+    uint8_t         DhcpReq;
+    uint8_t         abOptions[57];
+} RTNETDHCP;
+#pragma pack()
+/** @todo AssertCompileSize(RTNETDHCP, ); */
+/** Pointer to a DHCP packet. */
+typedef RTNETDHCP *PRTNETDHCP;
+/** Pointer to a const DHCP packet. */
+typedef RTNETDHCP const *PCRTNETDHCP;
+
+
+/**
+ * TCP packet.
+ */
+#pragma pack(1)
+typedef struct RTNETTCP
+{
+    /** 00 - The source port. */
+    uint16_t        th_sport;
+    /** 02 - The destination port. */
+    uint16_t        th_dport;
+    /** 04 - The sequence number. */
+    uint32_t        th_seq;
+    /** 08 - The acknowledgement number. */
+    uint32_t        th_ack;
+#ifdef RT_BIG_ENDIAN
+    unsigned int    th_win : 16;
+    unsigned int    th_flags : 8;
+    unsigned int    th_off : 4;
+    unsigned int    th_x2 : 4;
+#else
+    /** 0c:0 - Reserved. */
+    unsigned int    th_x2 : 4;
+    /** 0c:4 - The data offset given as a dword count from the start of this header. */
+    unsigned int    th_off : 4;
+    /** 0d - flags. */
+    unsigned int    th_flags : 8;
+    /** 0e - The window. */
+    unsigned int    th_win : 16;
+#endif
+    /** 10 - The checksum of the pseudo header, the TCP header and the data. */
+    uint16_t        th_sum;
+    /** 12 - The urgent pointer. */
+    uint16_t        th_urp;
+    /* (options follows here and then the data (aka text).) */
+} RTNETTCP;
+#pragma pack()
+AssertCompileSize(RTNETTCP, 20);
+/** Pointer to a TCP packet. */
+typedef RTNETTCP *PRTNETTCP;
+/** Pointer to a const TCP packet. */
+typedef RTNETTCP const *PCRTNETTCP;
+
+/** The minimum TCP header length (in bytes). (RTNETTCP::th_off * 4) */
+#define RTNETTCP_MIN_LEN    (20)
+
+/** @name TCP flags (RTNETTCP::th_flags)
+ * @{ */
+#define RTNETTCP_F_FIN      0x01
+#define RTNETTCP_F_SYN      0x02
+#define RTNETTCP_F_RST      0x04
+#define RTNETTCP_F_PSH      0x08
+#define RTNETTCP_F_ACK      0x10
+#define RTNETTCP_F_URG      0x20
+#define RTNETTCP_F_ECE      0x40
+#define RTNETTCP_F_CWR      0x80
+/** @} */
+
+RTDECL(uint16_t) RTNetTCPChecksum(uint32_t u32Sum, PCRTNETTCP pTcpHdr, void const *pvData, size_t cbData);
+RTDECL(uint32_t) RTNetIPv4AddTCPChecksum(PCRTNETTCP pTcpHdr, uint32_t u32Sum);
+RTDECL(uint16_t) RTNetIPv4TCPChecksum(PCRTNETIPV4 pIpHdr, PCRTNETTCP pTcpHdr, void const *pvData);
+RTDECL(bool)     RTNetIPv4IsTCPSizeValid(PCRTNETIPV4 pIpHdr, PCRTNETTCP pTcpHdr, size_t cbHdrMax, size_t cbPktMax);
+RTDECL(bool)     RTNetIPv4IsTCPValid(PCRTNETIPV4 pIpHdr, PCRTNETTCP pTcpHdr, size_t cbHdrMax, void const *pvData,
+                                     size_t cbPktMax, bool fChecksum);
+
+
+/**
+ * IPv4 ICMP packet header.
+ */
+#pragma pack(1)
+typedef struct RTNETICMPV4HDR
+{
+    /** 00 - The ICMP message type. */
+    uint8_t         icmp_type;
+    /** 01 - Type specific code that further qualifies the message. */
+    uint8_t         icmp_code;
+    /** 02 - Checksum of the ICMP message. */
+    uint16_t        icmp_cksum;
+} RTNETICMPV4HDR;
+#pragma pack()
+AssertCompileSize(RTNETICMPV4HDR, 4);
+/** Pointer to an ICMP packet header. */
+typedef RTNETICMPV4HDR *PRTNETICMPV4HDR;
+/** Pointer to a const ICMP packet header. */
+typedef RTNETICMPV4HDR const *PCRTNETICMPV4HDR;
+
+/** @name ICMP (v4) message types.
+ * @{  */
+#define RTNETICMPV4_TYPE_ECHO_REPLY     0
+#define RTNETICMPV4_TYPE_ECHO_REQUEST   8
+#define RTNETICMPV4_TYPE_TRACEROUTE     30
+/** @} */
+
+/**
+ * IPv4 ICMP ECHO Reply & Request packet.
+ */
+#pragma pack(1)
+typedef struct RTNETICMPV4ECHO
+{
+    /** 00 - The ICMP header. */
+    RTNETICMPV4HDR  Hdr;
+    /** 04 - The identifier to help the requestor match up the reply.
+     *       Can be 0. Typically fixed value. */
+    uint16_t        icmp_id;
+    /** 06 - The sequence number to help the requestor match up the reply.
+     *       Can be 0. Typically incrementing between requests. */
+    uint16_t        icmp_seq;
+    /** 08 - Variable length data that is to be returned unmodified in the reply. */
+    uint8_t         icmp_data[1];
+} RTNETICMPV4ECHO;
+#pragma pack()
+AssertCompileSize(RTNETICMPV4ECHO, 9);
+/** Pointer to an ICMP ECHO packet. */
+typedef RTNETICMPV4ECHO *PRTNETICMPV4ECHO;
+/** Pointer to a const ICMP ECHO packet. */
+typedef RTNETICMPV4ECHO const *PCRTNETICMPV4ECHO;
+
+/**
+ * IPv4 ICMP TRACEROUTE packet.
+ * This is an reply to an IP packet with the traceroute option set.
+ */
+#pragma pack(1)
+typedef struct RTNETICMPV4TRACEROUTE
+{
+    /** 00 - The ICMP header. */
+    RTNETICMPV4HDR  Hdr;
+    /** 04 - Identifier copied from the traceroute option's ID number. */
+    uint16_t        icmp_id;
+    /** 06 - Unused. (Possibly an icmp_seq?) */
+    uint16_t        icmp_void;
+    /** 08 - Outbound hop count. From the IP packet causing this message. */
+    uint16_t        icmp_ohc;
+    /** 0a - Return hop count. From the IP packet causing this message. */
+    uint16_t        icmp_rhc;
+    /** 0c - Output link speed, 0 if not known. */
+    uint32_t        icmp_speed;
+    /** 10 - Output link MTU, 0 if not known. */
+    uint32_t        icmp_mtu;
+} RTNETICMPV4TRACEROUTE;
+#pragma pack()
+AssertCompileSize(RTNETICMPV4TRACEROUTE, 20);
+/** Pointer to an ICMP TRACEROUTE packet. */
+typedef RTNETICMPV4TRACEROUTE *PRTNETICMPV4TRACEROUTE;
+/** Pointer to a const ICMP TRACEROUTE packet. */
+typedef RTNETICMPV4TRACEROUTE const *PCRTNETICMPV4TRACEROUTE;
+
+/** @todo add more ICMPv4 as needed. */
+
+/**
+ * IPv4 ICMP union packet.
+ */
+typedef union RTNETICMPV4
+{
+    RTNETICMPV4HDR Hdr;
+    RTNETICMPV4ECHO Echo;
+    RTNETICMPV4TRACEROUTE Traceroute;
+} RTNETICMPV4;
+/** Pointer to an ICMP union packet. */
+typedef RTNETICMPV4 *PRTNETICMPV4;
+/** Pointer to a const ICMP union packet. */
+typedef RTNETICMPV4 const *PCRTNETICMPV4;
+
+
+/**
+ * IPv6 ICMP packet header.
+ */
+#pragma pack(1)
+typedef struct RTNETICMPV6HDR
+{
+    /** 00 - The ICMPv6 message type. */
+    uint8_t         icmp6_type;
+    /** 01 - Type specific code that further qualifies the message. */
+    uint8_t         icmp6_code;
+    /** 02 - Checksum of the ICMPv6 message. */
+    uint16_t        icmp6_cksum;
+} RTNETICMPV6HDR;
+#pragma pack()
+AssertCompileSize(RTNETICMPV6HDR, 4);
+/** Pointer to an ICMPv6 packet header. */
+typedef RTNETICMPV6HDR *PRTNETICMPV6HDR;
+/** Pointer to a const ICMP packet header. */
+typedef RTNETICMPV6HDR const *PCRTNETICMPV6HDR;
+
+#define RTNETIPV6_PROT_ICMPV6       (58)
+
+/** @name Internet Control Message Protocol version 6 (ICMPv6) message types.
+ * @{ */
+#define RTNETIPV6_ICMP_TYPE_RS      133
+#define RTNETIPV6_ICMP_TYPE_RA      134
+#define RTNETIPV6_ICMP_TYPE_NS      135
+#define RTNETIPV6_ICMP_TYPE_NA      136
+#define RTNETIPV6_ICMP_TYPE_RDR     137
+/** @} */
+
+/** @name Neighbor Discovery option types
+ * @{ */
+#define RTNETIPV6_ICMP_ND_SLLA_OPT  (1)
+#define RTNETIPV6_ICMP_ND_TLLA_OPT  (2)
+/** @} */
+
+/** ICMPv6 ND Source/Target Link Layer Address option */
+#pragma pack(1)
+typedef struct RTNETNDP_LLA_OPT
+{
+    uint8_t type;
+    uint8_t len;
+    RTMAC lla;
+} RTNETNDP_LLA_OPT;
+#pragma pack()
+
+AssertCompileSize(RTNETNDP_LLA_OPT, 1+1+6);
+
+typedef RTNETNDP_LLA_OPT *PRTNETNDP_LLA_OPT;
+typedef RTNETNDP_LLA_OPT const *PCRTNETNDP_LLA_OPT;
+
+/** ICMPv6 ND Neighbor Sollicitation */
+#pragma pack(1)
+typedef struct RTNETNDP
+{
+    /** 00 - The ICMPv6 header. */
+    RTNETICMPV6HDR Hdr;
+    /** 04 - reserved */
+    uint32_t reserved;
+    /** 08 - target address */
+    RTNETADDRIPV6 target_address;
+} RTNETNDP;
+#pragma pack()
+AssertCompileSize(RTNETNDP, 4+4+16);
+/** Pointer to a NDP ND packet. */
+typedef RTNETNDP *PRTNETNDP;
+/** Pointer to a const NDP NS packet. */
+typedef RTNETNDP const *PCRTNETNDP;
+
+
+/**
+ * Ethernet ARP header.
+ */
+#pragma pack(1)
+typedef struct RTNETARPHDR
+{
+    /** The hardware type. */
+    uint16_t    ar_htype;
+    /** The protocol type (ethertype). */
+    uint16_t    ar_ptype;
+    /** The hardware address length. */
+    uint8_t     ar_hlen;
+    /** The protocol address length. */
+    uint8_t     ar_plen;
+    /** The operation. */
+    uint16_t    ar_oper;
+} RTNETARPHDR;
+#pragma pack()
+AssertCompileSize(RTNETARPHDR, 8);
+/** Pointer to an ethernet ARP header. */
+typedef RTNETARPHDR *PRTNETARPHDR;
+/** Pointer to a const ethernet ARP header. */
+typedef RTNETARPHDR const *PCRTNETARPHDR;
+
+/** ARP hardware type - ethernet. */
+#define RTNET_ARP_ETHER            UINT16_C(1)
+
+/** @name ARP operations
+ * @{ */
+#define RTNET_ARPOP_REQUEST        UINT16_C(1) /**< Request hardware address given a protocol address (ARP). */
+#define RTNET_ARPOP_REPLY          UINT16_C(2)
+#define RTNET_ARPOP_REVREQUEST     UINT16_C(3) /**< Request protocol address given a hardware address (RARP). */
+#define RTNET_ARPOP_REVREPLY       UINT16_C(4)
+#define RTNET_ARPOP_INVREQUEST     UINT16_C(8) /**< Inverse ARP.  */
+#define RTNET_ARPOP_INVREPLY       UINT16_C(9)
+/** Check if an ARP operation is a request or not. */
+#define RTNET_ARPOP_IS_REQUEST(Op) ((Op) & 1)
+/** Check if an ARP operation is a reply or not. */
+#define RTNET_ARPOP_IS_REPLY(Op)   (!RTNET_ARPOP_IS_REQUEST(Op))
+/** @} */
+
+
+/**
+ * Ethernet IPv4 + 6-byte MAC ARP request packet.
+ */
+#pragma pack(1)
+typedef struct RTNETARPIPV4
+{
+    /** ARP header. */
+    RTNETARPHDR     Hdr;
+    /** The sender hardware address. */
+    RTMAC           ar_sha;
+    /** The sender protocol address. */
+    RTNETADDRIPV4   ar_spa;
+    /** The target hardware address. */
+    RTMAC           ar_tha;
+    /** The target protocol address. */
+    RTNETADDRIPV4   ar_tpa;
+} RTNETARPIPV4;
+#pragma pack()
+AssertCompileSize(RTNETARPIPV4, 8+6+4+6+4);
+/** Pointer to an ethernet IPv4+MAC ARP request packet. */
+typedef RTNETARPIPV4 *PRTNETARPIPV4;
+/** Pointer to a const ethernet IPv4+MAC ARP request packet. */
+typedef RTNETARPIPV4 const *PCRTNETARPIPV4;
+
+
+/** @} */
+
+RT_C_DECLS_END
+
+#endif
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/include/iprt/nocrt/limits.h
@@ -0,0 +1,86 @@
+/** @file
+ * IPRT / No-CRT - Our own limits header.
+ */
+
+/*
+ * Copyright (C) 2006-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+#ifndef ___iprt_nocrt_limits_h
+#define ___iprt_nocrt_limits_h
+
+#include <iprt/types.h>
+
+#define CHAR_BIT        8
+#define SCHAR_MAX       0x7f
+#define SCHAR_MIN       (-0x7f - 1)
+#define UCHAR_MAX       0xff
+#if 1 /* ASSUMES: signed char */
+# define CHAR_MAX       SCHAR_MAX
+# define CHAR_MIN       SCHAR_MIN
+#else
+# define CHAR_MAX       UCHAR_MAX
+# define CHAR_MIN       0
+#endif
+
+#define WORD_BIT        16
+#define USHRT_MAX       0xffff
+#define SHRT_MAX        0x7fff
+#define SHRT_MIN        (-0x7fff - 1)
+
+/* ASSUMES 32-bit int */
+#define UINT_MAX        0xffffffffU
+#define INT_MAX         0x7fffffff
+#define INT_MIN         (-0x7fffffff - 1)
+
+#if defined(RT_ARCH_X86) || defined(RT_OS_WINDOWS) || defined(RT_ARCH_SPARC)
+# define LONG_BIT       32
+# define ULONG_MAX      0xffffffffU
+# define LONG_MAX       0x7fffffff
+# define LONG_MIN       (-0x7fffffff - 1)
+#elif defined(RT_ARCH_AMD64) || defined(RT_ARCH_SPARC64)
+# define LONG_BIT       64
+# define ULONG_MAX      UINT64_C(0xffffffffffffffff)
+# define LONG_MAX       INT64_C(0x7fffffffffffffff)
+# define LONG_MIN       (INT64_C(-0x7fffffffffffffff) - 1)
+#else
+# error "PORTME"
+#endif
+
+#define LLONG_BIT       64
+#define ULLONG_MAX      UINT64_C(0xffffffffffffffff)
+#define LLONG_MAX       INT64_C(0x7fffffffffffffff)
+#define LLONG_MIN       (INT64_C(-0x7fffffffffffffff) - 1)
+
+#if ARCH_BITS == 32
+# define SIZE_T_MAX     0xffffffffU
+# define SSIZE_MAX      0x7fffffff
+#elif ARCH_BITS == 64
+# define SIZE_T_MAX     UINT64_C(0xffffffffffffffff)
+# define SSIZE_MAX      INT64_C(0x7fffffffffffffff)
+#else
+# error "huh?"
+#endif
+
+/*#define OFF_MAX         __OFF_MAX
+#define OFF_MIN         __OFF_MIN*/
+
+#endif
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/include/iprt/param.h
@@ -0,0 +1,131 @@
+/** @file
+ * IPRT - Parameter Definitions.
+ */
+
+/*
+ * Copyright (C) 2006-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+#ifndef ___iprt_param_h
+#define ___iprt_param_h
+
+/** @todo Much of the PAGE_* stuff here is obsolete and highly risky to have around.
+ * As for component configs (MM_*), either we gather all in here or we move those bits away! */
+
+/** @defgroup   grp_rt_param    System Parameter Definitions
+ * @ingroup grp_rt_cdefs
+ * @{
+ */
+
+/* Undefine PAGE_SIZE and PAGE_SHIFT to avoid unnecessary noice when clashing
+ * with system headers. Include system headers before / after iprt depending
+ * on which you wish to take precedence. */
+#undef PAGE_SIZE
+#undef PAGE_SHIFT
+
+/* Undefine PAGE_OFFSET_MASK to avoid the conflict with the-linux-kernel.h */
+#undef PAGE_OFFSET_MASK
+
+/**
+ * i386 Page size.
+ */
+#if defined(RT_ARCH_SPARC64)
+# define PAGE_SIZE          8192
+#else
+# define PAGE_SIZE          4096
+#endif
+
+/**
+ * i386 Page shift.
+ * This is used to convert between size (in bytes) and page count.
+ */
+#if defined(RT_ARCH_SPARC64)
+# define PAGE_SHIFT         13
+#else
+# define PAGE_SHIFT         12
+#endif
+
+/**
+ * i386 Page offset mask.
+ *
+ * Do NOT one-complement this for whatever purpose. You may get a 32-bit const when you want a 64-bit one.
+ * Use PAGE_BASE_MASK, PAGE_BASE_GC_MASK, PAGE_BASE_HC_MASK, PAGE_ADDRESS() or X86_PTE_PAE_PG_MASK.
+ */
+#if defined(RT_ARCH_SPARC64)
+# define PAGE_OFFSET_MASK    0x1fff
+#else
+# define PAGE_OFFSET_MASK    0xfff
+#endif
+
+/**
+ * Page address mask for the guest context POINTERS.
+ * @remark  Physical addresses are always masked using X86_PTE_PAE_PG_MASK!
+ */
+#define PAGE_BASE_GC_MASK   (~(RTGCUINTPTR)PAGE_OFFSET_MASK)
+
+/**
+ * Page address mask for the host context POINTERS.
+ * @remark  Physical addresses are always masked using X86_PTE_PAE_PG_MASK!
+ */
+#define PAGE_BASE_HC_MASK   (~(RTHCUINTPTR)PAGE_OFFSET_MASK)
+
+/**
+ * Page address mask for the both context POINTERS.
+ *
+ * Be careful when using this since it may be a size too big!
+ * @remark  Physical addresses are always masked using X86_PTE_PAE_PG_MASK!
+ */
+#define PAGE_BASE_MASK      (~(RTUINTPTR)PAGE_OFFSET_MASK)
+
+/**
+ * Get the page aligned address of a POINTER in the CURRENT context.
+ *
+ * @returns Page aligned address (it's an uintptr_t).
+ * @param   pv      The virtual address to align.
+ *
+ * @remarks Physical addresses are always masked using X86_PTE_PAE_PG_MASK!
+ * @remarks This only works with POINTERS in the current context.
+ *          Do NOT use on guest address or physical address!
+ */
+#define PAGE_ADDRESS(pv)    ((uintptr_t)(pv) & ~(uintptr_t)PAGE_OFFSET_MASK)
+
+/**
+ * Get the page aligned address of a physical address
+ *
+ * @returns Page aligned address (it's an RTHCPHYS or RTGCPHYS).
+ * @param   Phys    The physical address to align.
+ */
+#define PHYS_PAGE_ADDRESS(Phys) ((Phys) & X86_PTE_PAE_PG_MASK)
+
+/**
+ * Host max path (the reasonable value).
+ * @remarks defined both by iprt/param.h and iprt/path.h.
+ */
+#if !defined(___iprt_path_h) || defined(DOXYGEN_RUNNING)
+# define RTPATH_MAX         (4096 + 4)    /* (PATH_MAX + 1) on linux w/ some alignment */
+#endif
+
+/** @} */
+
+
+/** @} */
+
+#endif
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/include/iprt/path.h
@@ -0,0 +1,1478 @@
+/** @file
+ * IPRT - Path Manipulation.
+ */
+
+/*
+ * Copyright (C) 2006-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+#ifndef ___iprt_path_h
+#define ___iprt_path_h
+
+#include <iprt/cdefs.h>
+#include <iprt/types.h>
+#ifdef IN_RING3
+# include <iprt/fs.h>
+#endif
+
+
+
+RT_C_DECLS_BEGIN
+
+/** @defgroup grp_rt_path   RTPath - Path Manipulation
+ * @ingroup grp_rt
+ * @{
+ */
+
+/**
+ * Host max path (the reasonable value).
+ * @remarks defined both by iprt/param.h and iprt/path.h.
+ */
+#if !defined(___iprt_param_h) || defined(DOXYGEN_RUNNING)
+# define RTPATH_MAX         (4096 + 4)    /* (PATH_MAX + 1) on linux w/ some alignment */
+#endif
+
+/** @def RTPATH_TAG
+ * The default allocation tag used by the RTPath allocation APIs.
+ *
+ * When not defined before the inclusion of iprt/string.h, this will default to
+ * the pointer to the current file name.  The string API will make of use of
+ * this as pointer to a volatile but read-only string.
+ */
+#ifndef RTPATH_TAG
+# define RTPATH_TAG     (__FILE__)
+#endif
+
+
+/** @name RTPATH_F_XXX - Generic flags for APIs working on the file system.
+ * @{ */
+/** Last component: Work on the link. */
+#define RTPATH_F_ON_LINK          RT_BIT_32(0)
+/** Last component: Follow if link. */
+#define RTPATH_F_FOLLOW_LINK      RT_BIT_32(1)
+/** Don't allow symbolic links as part of the path.
+ * @remarks this flag is currently not implemented and will be ignored. */
+#define RTPATH_F_NO_SYMLINKS      RT_BIT_32(2)
+/** @} */
+
+/** Validates a flags parameter containing RTPATH_F_*.
+ * @remarks The parameters will be referenced multiple times. */
+#define RTPATH_F_IS_VALID(a_fFlags, a_fIgnore) \
+    (    ((a_fFlags) & ~(uint32_t)((a_fIgnore) | RTPATH_F_NO_SYMLINKS)) == RTPATH_F_ON_LINK \
+      || ((a_fFlags) & ~(uint32_t)((a_fIgnore) | RTPATH_F_NO_SYMLINKS)) == RTPATH_F_FOLLOW_LINK )
+
+
+/** @name RTPATH_STR_F_XXX - Generic flags for APIs working with path strings.
+ * @{
+ */
+/** Host OS path style (default 0 value). */
+#define RTPATH_STR_F_STYLE_HOST         UINT32_C(0x00000000)
+/** DOS, OS/2 and Windows path style. */
+#define RTPATH_STR_F_STYLE_DOS          UINT32_C(0x00000001)
+/** Unix path style. */
+#define RTPATH_STR_F_STYLE_UNIX         UINT32_C(0x00000002)
+/** Reserved path style. */
+#define RTPATH_STR_F_STYLE_RESERVED     UINT32_C(0x00000003)
+/** The path style mask. */
+#define RTPATH_STR_F_STYLE_MASK         UINT32_C(0x00000003)
+/** Partial path - no start.
+ * This causes the API to skip the root specification parsing.  */
+#define RTPATH_STR_F_NO_START           UINT32_C(0x00000010)
+/** Partial path - no end.
+ * This causes the API to skip the filename and dir-slash parsing.  */
+#define RTPATH_STR_F_NO_END             UINT32_C(0x00000020)
+/** Partial path - no start and no end. */
+#define RTPATH_STR_F_MIDDLE             (RTPATH_STR_F_NO_START | RTPATH_STR_F_NO_END)
+
+/** Reserved for future use. */
+#define RTPATH_STR_F_RESERVED_MASK      UINT32_C(0x0000ffcc)
+/** @} */
+
+/** Validates a flags parameter containing RTPATH_FSTR_.
+ * @remarks The parameters will be references multiple times.  */
+#define RTPATH_STR_F_IS_VALID(a_fFlags, a_fIgnore) \
+      (   ((a_fFlags) & ~((uint32_t)(a_fIgnore) | RTPATH_STR_F_STYLE_MASK | RTPATH_STR_F_MIDDLE)) == 0 \
+       && ((a_fFlags) & RTPATH_STR_F_STYLE_MASK) != RTPATH_STR_F_STYLE_RESERVED \
+       && ((a_fFlags) & RTPATH_STR_F_RESERVED_MASK) == 0 )
+
+
+/** @def RTPATH_STYLE
+ * The host path style. This is set to RTPATH_STR_F_STYLE_DOS,
+ * RTPATH_STR_F_STYLE_UNIX, or other future styles. */
+#if defined(RT_OS_OS2) || defined(RT_OS_WINDOWS)
+# define RTPATH_STYLE       RTPATH_STR_F_STYLE_DOS
+#else
+# define RTPATH_STYLE       RTPATH_STR_F_STYLE_UNIX
+#endif
+
+
+/** @def RTPATH_SLASH
+ * The preferred slash character.
+ *
+ * @remark IPRT will always accept unix slashes. So, normally you would
+ *         never have to use this define.
+ */
+#if RTPATH_STYLE == RTPATH_STR_F_STYLE_DOS
+# define RTPATH_SLASH       '\\'
+#elif RTPATH_STYLE == RTPATH_STR_F_STYLE_UNIX
+# define RTPATH_SLASH       '/'
+#else
+# error "Unsupported RTPATH_STYLE value."
+#endif
+
+/** @deprecated Use '/'! */
+#define RTPATH_DELIMITER    RTPATH_SLASH
+
+
+/** @def RTPATH_SLASH_STR
+ * The preferred slash character as a string, handy for concatenations
+ * with other strings.
+ *
+ * @remark IPRT will always accept unix slashes. So, normally you would
+ *         never have to use this define.
+ */
+#if RTPATH_STYLE == RTPATH_STR_F_STYLE_DOS
+# define RTPATH_SLASH_STR   "\\"
+#elif RTPATH_STYLE == RTPATH_STR_F_STYLE_UNIX
+# define RTPATH_SLASH_STR   "/"
+#else
+# error "Unsupported RTPATH_STYLE value."
+#endif
+
+
+/** @def RTPATH_IS_SLASH
+ * Checks if a character is a slash.
+ *
+ * @returns true if it's a slash and false if not.
+ * @returns @param      a_ch    Char to check.
+ */
+#if RTPATH_STYLE == RTPATH_STR_F_STYLE_DOS
+# define RTPATH_IS_SLASH(a_ch)      ( (a_ch) == '\\' || (a_ch) == '/' )
+#elif RTPATH_STYLE == RTPATH_STR_F_STYLE_UNIX
+# define RTPATH_IS_SLASH(a_ch)      ( (a_ch) == '/' )
+#else
+# error "Unsupported RTPATH_STYLE value."
+#endif
+
+
+/** @def RTPATH_IS_VOLSEP
+ * Checks if a character marks the end of the volume specification.
+ *
+ * @remark  This is sufficient for the drive letter concept on PC.
+ *          However it might be insufficient on other platforms
+ *          and even on PC a UNC volume spec won't be detected this way.
+ *          Use the RTPath@<too be created@>() instead.
+ *
+ * @returns true if it is and false if it isn't.
+ * @returns @param      a_ch    Char to check.
+ */
+#if RTPATH_STYLE == RTPATH_STR_F_STYLE_DOS
+# define RTPATH_IS_VOLSEP(a_ch)   ( (a_ch) == ':' )
+#elif RTPATH_STYLE == RTPATH_STR_F_STYLE_UNIX
+# define RTPATH_IS_VOLSEP(a_ch)   (false)
+#else
+# error "Unsupported RTPATH_STYLE value."
+#endif
+
+
+/** @def RTPATH_IS_SEP
+ * Checks if a character is path component separator
+ *
+ * @returns true if it is and false if it isn't.
+ * @returns @param      a_ch    Char to check.
+ * @
+ */
+#define RTPATH_IS_SEP(a_ch)     ( RTPATH_IS_SLASH(a_ch) || RTPATH_IS_VOLSEP(a_ch) )
+
+
+/**
+ * Checks if the path exists.
+ *
+ * Symbolic links will all be attempted resolved and broken links means false.
+ *
+ * @returns true if it exists and false if it doesn't.
+ * @param   pszPath     The path to check.
+ */
+RTDECL(bool) RTPathExists(const char *pszPath);
+
+/**
+ * Checks if the path exists.
+ *
+ * @returns true if it exists and false if it doesn't.
+ * @param   pszPath     The path to check.
+ * @param   fFlags      RTPATH_F_ON_LINK or RTPATH_F_FOLLOW_LINK.
+ */
+RTDECL(bool) RTPathExistsEx(const char *pszPath, uint32_t fFlags);
+
+/**
+ * Sets the current working directory of the process.
+ *
+ * @returns IPRT status code.
+ * @param   pszPath         The path to the new working directory.
+ */
+RTDECL(int)  RTPathSetCurrent(const char *pszPath);
+
+/**
+ * Gets the current working directory of the process.
+ *
+ * @returns IPRT status code.
+ * @param   pszPath         Where to store the path.
+ * @param   cchPath         The size of the buffer pszPath points to.
+ */
+RTDECL(int)  RTPathGetCurrent(char *pszPath, size_t cchPath);
+
+/**
+ * Gets the current working directory on the specified drive.
+ *
+ * On systems without drive letters, the root slash will be returned.
+ *
+ * @returns IPRT status code.
+ * @param   chDrive         The drive we're querying the driver letter on.
+ * @param   pszPath         Where to store the working directroy path.
+ * @param   cbPath          The size of the buffer pszPath points to.
+ */
+RTDECL(int) RTPathGetCurrentOnDrive(char chDrive, char *pszPath, size_t cbPath);
+
+/**
+ * Gets the current working drive of the process.
+ *
+ * Normally drive letter and colon will be returned, never trailing a root
+ * slash.  If the current directory is on a UNC share, the root of the share
+ * will be returned.  On systems without drive letters, an empty string is
+ * returned for consistency.
+ *
+ * @returns IPRT status code.
+ * @param   pszPath         Where to store the working drive or UNC root.
+ * @param   cbPath          The size of the buffer pszPath points to.
+ */
+RTDECL(int) RTPathGetCurrentDrive(char *pszPath, size_t cbPath);
+
+/**
+ * Get the real path (no symlinks, no . or .. components), must exist.
+ *
+ * @returns iprt status code.
+ * @param   pszPath         The path to resolve.
+ * @param   pszRealPath     Where to store the real path.
+ * @param   cchRealPath     Size of the buffer.
+ */
+RTDECL(int) RTPathReal(const char *pszPath, char *pszRealPath, size_t cchRealPath);
+
+/**
+ * Same as RTPathReal only the result is RTStrDup()'ed.
+ *
+ * @returns Pointer to real path. Use RTStrFree() to free this string.
+ * @returns NULL if RTPathReal() or RTStrDup() fails.
+ * @param   pszPath         The path to resolve.
+ */
+RTDECL(char *) RTPathRealDup(const char *pszPath);
+
+/**
+ * Get the absolute path (starts from root, no . or .. components), doesn't have
+ * to exist. Note that this method is designed to never perform actual file
+ * system access, therefore symlinks are not resolved.
+ *
+ * @returns iprt status code.
+ * @param   pszPath         The path to resolve.
+ * @param   pszAbsPath      Where to store the absolute path.
+ * @param   cchAbsPath      Size of the buffer.
+ */
+RTDECL(int) RTPathAbs(const char *pszPath, char *pszAbsPath, size_t cchAbsPath);
+
+/**
+ * Same as RTPathAbs only the result is RTStrDup()'ed.
+ *
+ * @returns Pointer to the absolute path. Use RTStrFree() to free this string.
+ * @returns NULL if RTPathAbs() or RTStrDup() fails.
+ * @param   pszPath         The path to resolve.
+ */
+RTDECL(char *) RTPathAbsDup(const char *pszPath);
+
+/**
+ * Get the absolute path (no symlinks, no . or .. components), assuming the
+ * given base path as the current directory. The resulting path doesn't have
+ * to exist.
+ *
+ * @returns iprt status code.
+ * @param   pszBase         The base path to act like a current directory.
+ *                          When NULL, the actual cwd is used (i.e. the call
+ *                          is equivalent to RTPathAbs(pszPath, ...).
+ * @param   pszPath         The path to resolve.
+ * @param   pszAbsPath      Where to store the absolute path.
+ * @param   cchAbsPath      Size of the buffer.
+ */
+RTDECL(int) RTPathAbsEx(const char *pszBase, const char *pszPath, char *pszAbsPath, size_t cchAbsPath);
+
+/**
+ * Same as RTPathAbsEx only the result is RTStrDup()'ed.
+ *
+ * @returns Pointer to the absolute path. Use RTStrFree() to free this string.
+ * @returns NULL if RTPathAbsEx() or RTStrDup() fails.
+ * @param   pszBase         The base path to act like a current directory.
+ *                          When NULL, the actual cwd is used (i.e. the call
+ *                          is equivalent to RTPathAbs(pszPath, ...).
+ * @param   pszPath         The path to resolve.
+ */
+RTDECL(char *) RTPathAbsExDup(const char *pszBase, const char *pszPath);
+
+/**
+ * Strips the filename from a path. Truncates the given string in-place by overwriting the
+ * last path separator character with a null byte in a platform-neutral way.
+ *
+ * @param   pszPath     Path from which filename should be extracted, will be truncated.
+ *                      If the string contains no path separator, it will be changed to a "." string.
+ */
+RTDECL(void) RTPathStripFilename(char *pszPath);
+
+/**
+ * Strips the last suffix from a path.
+ *
+ * @param   pszPath     Path which suffix should be stripped.
+ */
+RTDECL(void) RTPathStripSuffix(char *pszPath);
+
+/**
+ * Strips the trailing slashes of a path name.
+ *
+ * Won't strip root slashes.
+ *
+ * @returns The new length of pszPath.
+ * @param   pszPath     Path to strip.
+ */
+RTDECL(size_t) RTPathStripTrailingSlash(char *pszPath);
+
+/**
+ * Ensures that the path has a trailing path separator such that file names can
+ * be appended without further work.
+ *
+ * This can be helpful when preparing for efficiently combining a directory path
+ * with the filenames returned by RTDirRead.  The return value gives you the
+ * position at which you copy the RTDIRENTRY::szName to construct a valid path
+ * to it.
+ *
+ * @returns The length of the path, 0 on buffer overflow.
+ * @param   pszPath     The path.
+ * @param   cbPath      The length of the path buffer @a pszPath points to.
+ */
+RTDECL(size_t) RTPathEnsureTrailingSeparator(char *pszPath, size_t cbPath);
+
+/**
+ * Changes all the slashes in the specified path to DOS style.
+ *
+ * Unless @a fForce is set, nothing will be done when on a UNIX flavored system
+ * since paths wont work with DOS style slashes there.
+ *
+ * @returns @a pszPath.
+ * @param   pszPath             The path to modify.
+ * @param   fForce              Whether to force the conversion on non-DOS OSes.
+ */
+RTDECL(char *) RTPathChangeToDosSlashes(char *pszPath, bool fForce);
+
+/**
+ * Changes all the slashes in the specified path to unix style.
+ *
+ * Unless @a fForce is set, nothing will be done when on a UNIX flavored system
+ * since paths wont work with DOS style slashes there.
+ *
+ * @returns @a pszPath.
+ * @param   pszPath             The path to modify.
+ * @param   fForce              Whether to force the conversion on non-DOS OSes.
+ */
+RTDECL(char *) RTPathChangeToUnixSlashes(char *pszPath, bool fForce);
+
+/**
+ * Simple parsing of the a path.
+ *
+ * It figures the length of the directory component, the offset of
+ * the file name and the location of the suffix dot.
+ *
+ * @returns The path length.
+ *
+ * @param   pszPath     Path to find filename in.
+ * @param   pcchDir     Where to put the length of the directory component. If
+ *                      no directory, this will be 0. Optional.
+ * @param   poffName    Where to store the filename offset.
+ *                      If empty string or if it's ending with a slash this
+ *                      will be set to -1. Optional.
+ * @param   poffSuff    Where to store the suffix offset (the last dot).
+ *                      If empty string or if it's ending with a slash this
+ *                      will be set to -1. Optional.
+ */
+RTDECL(size_t) RTPathParseSimple(const char *pszPath, size_t *pcchDir, ssize_t *poffName, ssize_t *poffSuff);
+
+/**
+ * Finds the filename in a path.
+ *
+ * @returns Pointer to filename within pszPath.
+ * @returns NULL if no filename (i.e. empty string or ends with a slash).
+ * @param   pszPath     Path to find filename in.
+ */
+RTDECL(char *) RTPathFilename(const char *pszPath);
+
+/**
+ * Finds the filename in a path, extended version.
+ *
+ * @returns Pointer to filename within pszPath.
+ * @returns NULL if no filename (i.e. empty string or ends with a slash).
+ * @param   pszPath     Path to find filename in.
+ * @param   fFlags      RTPATH_STR_F_STYLE_XXX. Other RTPATH_STR_F_XXX flags
+ *                      will be ignored.
+ */
+RTDECL(char *) RTPathFilenameEx(const char *pszPath, uint32_t fFlags);
+
+/**
+ * Finds the suffix part of in a path (last dot and onwards).
+ *
+ * @returns Pointer to suffix within pszPath.
+ * @returns NULL if no suffix
+ * @param   pszPath     Path to find suffix in.
+ *
+ * @remarks IPRT terminology: A suffix includes the dot, the extension starts
+ *          after the dot. For instance suffix '.txt' and extension 'txt'.
+ */
+RTDECL(char *) RTPathSuffix(const char *pszPath);
+
+/**
+ * Checks if a path has an extension / suffix.
+ *
+ * @returns true if extension / suffix present.
+ * @returns false if no extension / suffix.
+ * @param   pszPath     Path to check.
+ */
+RTDECL(bool) RTPathHasSuffix(const char *pszPath);
+/** Same thing, different name.  */
+#define RTPathHasExt RTPathHasSuffix
+
+/**
+ * Checks if a path includes more than a filename.
+ *
+ * @returns true if path present.
+ * @returns false if no path.
+ * @param   pszPath     Path to check.
+ */
+RTDECL(bool) RTPathHasPath(const char *pszPath);
+/** Misspelled, don't use.  */
+#define RTPathHavePath  RTPathHasPath
+
+/**
+ * Checks if the path starts with a root specifier or not.
+ *
+ * @returns @c true if it starts with root, @c false if not.
+ *
+ * @param   pszPath     Path to check.
+ */
+RTDECL(bool) RTPathStartsWithRoot(const char *pszPath);
+
+/**
+ * Counts the components in the specified path.
+ *
+ * An empty string has zero components.  A lone root slash is considered have
+ * one.  The paths "/init" and "/bin/" are considered having two components.  An
+ * UNC share specifier like "\\myserver\share" will be considered as one single
+ * component.
+ *
+ * @returns The number of path components.
+ * @param   pszPath     The path to parse.
+ */
+RTDECL(size_t) RTPathCountComponents(const char *pszPath);
+
+/**
+ * Copies the specified number of path components from @a pszSrc and into @a
+ * pszDst.
+ *
+ * @returns VINF_SUCCESS or VERR_BUFFER_OVERFLOW.  In the latter case the buffer
+ *          is not touched.
+ *
+ * @param   pszDst      The destination buffer.
+ * @param   cbDst       The size of the destination buffer.
+ * @param   pszSrc      The source path.
+ * @param   cComponents The number of components to copy from @a pszSrc.
+ */
+RTDECL(int) RTPathCopyComponents(char *pszDst, size_t cbDst, const char *pszSrc, size_t cComponents);
+
+/** @name Path properties returned by RTPathParse and RTPathSplit.
+ * @{ */
+
+/** Indicates that there is a filename.
+ * If not set, either a lone root spec was given (RTPATH_PROP_UNC,
+ * RTPATH_PROP_ROOT_SLASH, or RTPATH_PROP_VOLUME) or the final component had a
+ * trailing slash (RTPATH_PROP_DIR_SLASH). */
+#define RTPATH_PROP_FILENAME        UINT16_C(0x0001)
+/** Indicates that a directory was specified using a trailing slash.
+ * @note This is not set for lone root specifications (RTPATH_PROP_UNC,
+ *       RTPATH_PROP_ROOT_SLASH, or RTPATH_PROP_VOLUME).
+ * @note The slash is not counted into the last component. However, it is
+ *       counted into cchPath. */
+#define RTPATH_PROP_DIR_SLASH       UINT16_C(0x0002)
+
+/** The filename has a suffix (extension). */
+#define RTPATH_PROP_SUFFIX          UINT16_C(0x0004)
+/** Indicates that this is an UNC path (Windows and OS/2 only).
+ *
+ * UNC = Universal Naming Convention.  It is on the form '//Computer/',
+ * '//Namespace/', '//ComputerName/Resource' and '//Namespace/Resource'.
+ * RTPathParse, RTPathSplit and friends does not consider the 'Resource'  as
+ * part of the UNC root specifier.  Thus the root specs for the above examples
+ * would be '//ComputerName/' or '//Namespace/'.
+ *
+ * Please note that  '//something' is not a UNC path, there must be a slash
+ * following the computer or namespace.
+ */
+#define RTPATH_PROP_UNC             UINT16_C(0x0010)
+/** A root slash was specified (unix style root).
+ * (While the path must relative if not set, this being set doesn't make it
+ * absolute.)
+ *
+ * This will be set in the following examples: '/', '/bin', 'C:/', 'C:/Windows',
+ * '//./', '//./PhysicalDisk0', '//example.org/', and '//example.org/share'.
+ *
+ * It will not be set for the following examples: '.', 'bin/ls', 'C:', and
+ * 'C:Windows'.
+ */
+#define RTPATH_PROP_ROOT_SLASH      UINT16_C(0x0020)
+/** A volume is specified (Windows, DOS and OS/2).
+ * For examples: 'C:', 'C:/', and 'A:/AutoExec.bat'. */
+#define RTPATH_PROP_VOLUME          UINT16_C(0x0040)
+/** The path is absolute, i.e. has a root specifier (root-slash,
+ * volume or UNC) and contains no winding '..' bits, though it may contain
+ * unnecessary slashes (RTPATH_PROP_EXTRA_SLASHES) and '.' components
+ * (RTPATH_PROP_DOT_REFS).
+ *
+ * On systems without volumes and UNC (unix style) it will be set for '/',
+ * '/bin/ls', and '/bin//./ls', but not for 'bin/ls', /bin/../usr/bin/env',
+ * '/./bin/ls' or '/.'.
+ *
+ * On systems with volumes, it will be set for 'C:/', C:/Windows', and
+ * 'C:/./Windows//', but not for 'C:', 'C:Windows', or 'C:/Windows/../boot.ini'.
+ *
+ * On systems with UNC paths, it will be set for '//localhost/',
+ * '//localhost/C$', '//localhost/C$/Windows/System32', '//localhost/.', and
+ * '//localhost/C$//./AutoExec.bat', but not for
+ * '//localhost/C$/Windows/../AutoExec.bat'.
+ *
+ * @note For the RTPathAbs definition, this flag needs to be set while both
+ *       RTPATH_PROP_EXTRA_SLASHES and RTPATH_PROP_DOT_REFS must be cleared.
+ */
+#define RTPATH_PROP_ABSOLUTE        UINT16_C(0x0100)
+/** Relative path. Inverse of RTPATH_PROP_ABSOLUTE. */
+#define RTPATH_PROP_RELATIVE        UINT16_C(0x0200)
+/** The path contains unnecessary slashes. Meaning, that if  */
+#define RTPATH_PROP_EXTRA_SLASHES   UINT16_C(0x0400)
+/** The path contains references to the special '.' (dot) directory link. */
+#define RTPATH_PROP_DOT_REFS        UINT16_C(0x0800)
+/** The path contains references to the special '..' (dot) directory link.
+ * RTPATH_PROP_RELATIVE will always be set together with this.  */
+#define RTPATH_PROP_DOTDOT_REFS     UINT16_C(0x1000)
+
+
+/** Macro to determin whether to insert a slash after the first component when
+ * joining it with something else.
+ * (All other components in a split or parsed path requies slashes added.) */
+#define RTPATH_PROP_FIRST_NEEDS_NO_SLASH(a_fProps) \
+    RT_BOOL( (a_fProps) & (RTPATH_PROP_ROOT_SLASH | RTPATH_PROP_VOLUME | RTPATH_PROP_UNC) )
+
+/** Macro to determin whether there is a root specification of any kind
+ * (unix, volumes, unc). */
+#define RTPATH_PROP_HAS_ROOT_SPEC(a_fProps) \
+    RT_BOOL( (a_fProps) & (RTPATH_PROP_ROOT_SLASH | RTPATH_PROP_VOLUME | RTPATH_PROP_UNC) )
+
+/** @} */
+
+
+/**
+ * Parsed path.
+ *
+ * The first component is the root, volume or UNC specifier, if present.  Use
+ * RTPATH_PROP_HAS_ROOT_SPEC() on RTPATHPARSED::fProps to determine its
+ * presence.
+ *
+ * Other than the root component, no component will include directory separators
+ * (slashes).
+ */
+typedef struct RTPATHPARSED
+{
+    /** Number of path components.
+     * This will always be set on VERR_BUFFER_OVERFLOW returns from RTPathParsed
+     * so the caller can calculate the required buffer size. */
+    uint16_t    cComps;
+    /** Path property flags, RTPATH_PROP_XXX */
+    uint16_t    fProps;
+    /** On success this is the length of the described path, i.e. sum of all
+     * component lengths and necessary separators.
+     * Do NOT use this to index in the source path in case it contains
+     * unnecessary slashes that RTPathParsed has ignored here. */
+    uint16_t    cchPath;
+    /** Reserved for future use. */
+    uint16_t    u16Reserved;
+    /** The offset of the filename suffix, offset of the NUL char if none. */
+    uint16_t    offSuffix;
+    /** The lenght of the suffix. */
+    uint16_t    cchSuffix;
+    /** Array of component descriptors (variable size).
+     * @note Don't try figure the end of the input path by adding up off and cch
+     *       of the last component.  If RTPATH_PROP_DIR_SLASH is set, there may
+     *       be one or more trailing slashes that are unaccounted for! */
+    struct
+    {
+        /** The offset of the component. */
+        uint16_t    off;
+        /** The length of the component. */
+        uint16_t    cch;
+    } aComps[1];
+} RTPATHPARSED;
+/** Pointer to to a parsed path result. */
+typedef RTPATHPARSED *PRTPATHPARSED;
+/** Pointer to to a const parsed path result. */
+typedef RTPATHPARSED *PCRTPATHPARSED;
+
+
+/**
+ * Parses the path.
+ *
+ * @returns IPRT status code.
+ * @retval  VERR_INVALID_POINTER if pParsed or pszPath is an invalid pointer.
+ * @retval  VERR_INVALID_PARAMETER if cbOutput is less than the RTPATHPARSED
+ *          strucuture. No output. (asserted)
+ * @retval  VERR_BUFFER_OVERFLOW there are more components in the path than
+ *          there is space in aComps. The required amount of space can be
+ *          determined from the pParsed->cComps:
+ *          @code
+ *              RT_OFFSETOF(RTPATHPARSED, aComps[pParsed->cComps])
+ *          @endcode
+ * @retval  VERR_PATH_ZERO_LENGTH if the path is empty.
+ *
+ * @param   pszPath             The path to parse.
+ * @param   pParsed             Where to store the details of the parsed path.
+ * @param   cbParsed            The size of the buffer. Must be at least the
+ *                              size of RTPATHPARSED.
+ * @param   fFlags              Combination of RTPATH_STR_F_XXX flags.
+ *                              Most users will pass 0.
+ * @sa      RTPathSplit, RTPathSplitA.
+ */
+RTDECL(int) RTPathParse(const char *pszPath, PRTPATHPARSED pParsed, size_t cbParsed, uint32_t fFlags);
+
+/**
+ * Reassembles a path parsed by RTPathParse.
+ *
+ * This will be more useful as more APIs manipulating the RTPATHPARSED output
+ * are added.
+ *
+ * @returns IPRT status code.
+ * @retval  VERR_BUFFER_OVERFLOW if @a cbDstPath is less than or equal to
+ *          RTPATHPARSED::cchPath.
+ *
+ * @param   pszSrcPath          The source path.
+ * @param   pParsed             The parser output for @a pszSrcPath.
+ * @param   fFlags              Combination of RTPATH_STR_F_STYLE_XXX.
+ *                              Most users will pass 0.
+ * @param   pszDstPath          Pointer to the buffer where the path is to be
+ *                              reassembled.
+ * @param   cbDstPath           The size of the output buffer.
+ */
+RTDECL(int) RTPathParsedReassemble(const char *pszSrcPath, PRTPATHPARSED pParsed, uint32_t fFlags,
+                                   char *pszDstPath, size_t cbDstPath);
+
+
+/**
+ * Output buffer for RTPathSplit and RTPathSplitA.
+ */
+typedef struct RTPATHSPLIT
+{
+    /** Number of path components.
+     * This will always be set on VERR_BUFFER_OVERFLOW returns from RTPathParsed
+     * so the caller can calculate the required buffer size. */
+    uint16_t    cComps;
+    /** Path property flags, RTPATH_PROP_XXX */
+    uint16_t    fProps;
+    /** On success this is the length of the described path, i.e. sum of all
+     * component lengths and necessary separators.
+     * Do NOT use this to index in the source path in case it contains
+     * unnecessary slashes that RTPathSplit has ignored here. */
+    uint16_t    cchPath;
+    /** Reserved (internal use).  */
+    uint16_t    u16Reserved;
+    /** The amount of memory used (on success) or required (on
+     *  VERR_BUFFER_OVERFLOW) of this structure and it's strings. */
+    uint32_t    cbNeeded;
+    /** Pointer to the filename suffix (the dot), if any. Points to the NUL
+     * character of the last component if none or if RTPATH_PROP_DIR_SLASH is
+     * present. */
+    const char *pszSuffix;
+    /** Array of component strings (variable size). */
+    char       *apszComps[1];
+} RTPATHSPLIT;
+/** Pointer to a split path buffer. */
+typedef RTPATHSPLIT *PRTPATHSPLIT;
+/** Pointer to a const split path buffer. */
+typedef RTPATHSPLIT const *PCRTPATHSPLIT;
+
+/**
+ * Splits the path into individual component strings, carved from user supplied
+ * the given buffer block.
+ *
+ * @returns IPRT status code.
+ * @retval  VERR_INVALID_POINTER if pParsed or pszPath is an invalid pointer.
+ * @retval  VERR_INVALID_PARAMETER if cbOutput is less than the RTPATHSPLIT
+ *          strucuture. No output. (asserted)
+ * @retval  VERR_BUFFER_OVERFLOW there are more components in the path than
+ *          there is space in aComps. The required amount of space can be
+ *          determined from the pParsed->cComps:
+ *          @code
+ *              RT_OFFSETOF(RTPATHPARSED, aComps[pParsed->cComps])
+ *          @endcode
+ * @retval  VERR_PATH_ZERO_LENGTH if the path is empty.
+ * @retval  VERR_FILENAME_TOO_LONG if the filename is too long (close to 64 KB).
+ *
+ * @param   pszPath             The path to parse.
+ * @param   pSplit              Where to store the details of the parsed path.
+ * @param   cbSplit             The size of the buffer pointed to by @a pSplit
+ *                              (variable sized array at the end).  Must be at
+ *                              least the size of RTPATHSPLIT.
+ * @param   fFlags              Combination of RTPATH_STR_F_XXX flags.
+ *                              Most users will pass 0.
+ *
+ * @sa      RTPathSplitA, RTPathParse.
+ */
+RTDECL(int) RTPathSplit(const char *pszPath, PRTPATHSPLIT pSplit, size_t cbSplit, uint32_t fFlags);
+
+/**
+ * Splits the path into individual component strings, allocating the buffer on
+ * the default thread heap.
+ *
+ * @returns IPRT status code.
+ * @retval  VERR_INVALID_POINTER if pParsed or pszPath is an invalid pointer.
+ * @retval  VERR_PATH_ZERO_LENGTH if the path is empty.
+ *
+ * @param   pszPath             The path to parse.
+ * @param   ppSplit             Where to return the pointer to the output on
+ *                              success.  This must be freed by calling
+ *                              RTPathSplitFree().
+ * @param   fFlags              Combination of RTPATH_STR_F_XXX flags.
+ *                              Most users will pass 0.
+ * @sa      RTPathSplitFree, RTPathSplit, RTPathParse.
+ */
+#define RTPathSplitA(pszPath, ppSplit, fFlags)      RTPathSplitATag(pszPath, ppSplit, fFlags, RTPATH_TAG)
+
+/**
+ * Splits the path into individual component strings, allocating the buffer on
+ * the default thread heap.
+ *
+ * @returns IPRT status code.
+ * @retval  VERR_INVALID_POINTER if pParsed or pszPath is an invalid pointer.
+ * @retval  VERR_PATH_ZERO_LENGTH if the path is empty.
+ *
+ * @param   pszPath             The path to parse.
+ * @param   ppSplit             Where to return the pointer to the output on
+ *                              success.  This must be freed by calling
+ *                              RTPathSplitFree().
+ * @param   fFlags              Combination of RTPATH_STR_F_XXX flags.
+ *                              Most users will pass 0.
+ * @param   pszTag              Allocation tag used for statistics and such.
+ * @sa      RTPathSplitFree, RTPathSplit, RTPathParse.
+ */
+RTDECL(int) RTPathSplitATag(const char *pszPath, PRTPATHSPLIT *ppSplit, uint32_t fFlags, const char *pszTag);
+
+/**
+ * Frees buffer returned by RTPathSplitA.
+ *
+ * @param   pSplit              What RTPathSplitA returned.
+ * @sa      RTPathSplitA
+ */
+RTDECL(void) RTPathSplitFree(PRTPATHSPLIT pSplit);
+
+/**
+ * Reassembles a path parsed by RTPathSplit.
+ *
+ * This will be more useful as more APIs manipulating the RTPATHSPLIT output are
+ * added.
+ *
+ * @returns IPRT status code.
+ * @retval  VERR_BUFFER_OVERFLOW if @a cbDstPath is less than or equal to
+ *          RTPATHSPLIT::cchPath.
+ *
+ * @param   pSplit              A split path (see RTPathSplit, RTPathSplitA).
+ * @param   fFlags              Combination of RTPATH_STR_F_STYLE_XXX.
+ *                              Most users will pass 0.
+ * @param   pszDstPath          Pointer to the buffer where the path is to be
+ *                              reassembled.
+ * @param   cbDstPath           The size of the output buffer.
+ */
+RTDECL(int) RTPathSplitReassemble(PRTPATHSPLIT pSplit, uint32_t fFlags, char *pszDstPath, size_t cbDstPath);
+
+/**
+ * Checks if the two paths leads to the file system object.
+ *
+ * If the objects exist, we'll query attributes for them.  If that's not
+ * conclusive (some OSes) or one of them doesn't exist, we'll use a combination
+ * of RTPathAbs and RTPathCompare to determine the result.
+ *
+ * @returns true, false, or VERR_FILENAME_TOO_LONG.
+ * @param   pszPath1            The first path.
+ * @param   pszPath2            The seoncd path.
+ */
+RTDECL(int) RTPathIsSame(const char *pszPath1, const char *pszPath2);
+
+
+/**
+ * Compares two paths.
+ *
+ * The comparison takes platform-dependent details into account,
+ * such as:
+ * <ul>
+ * <li>On DOS-like platforms, both separator chars (|\| and |/|) are considered
+ *     to be equal.
+ * <li>On platforms with case-insensitive file systems, mismatching characters
+ *     are uppercased and compared again.
+ * </ul>
+ *
+ * @returns @< 0 if the first path less than the second path.
+ * @returns 0 if the first path identical to the second path.
+ * @returns @> 0 if the first path greater than the second path.
+ *
+ * @param   pszPath1    Path to compare (must be an absolute path).
+ * @param   pszPath2    Path to compare (must be an absolute path).
+ *
+ * @remarks File system details are currently ignored. This means that you won't
+ *          get case-insensitive compares on unix systems when a path goes into a
+ *          case-insensitive filesystem like FAT, HPFS, HFS, NTFS, JFS, or
+ *          similar. For NT, OS/2 and similar you'll won't get case-sensitive
+ *          compares on a case-sensitive file system.
+ */
+RTDECL(int) RTPathCompare(const char *pszPath1, const char *pszPath2);
+
+/**
+ * Checks if a path starts with the given parent path.
+ *
+ * This means that either the path and the parent path matches completely, or
+ * that the path is to some file or directory residing in the tree given by the
+ * parent directory.
+ *
+ * The path comparison takes platform-dependent details into account,
+ * see RTPathCompare() for details.
+ *
+ * @returns |true| when \a pszPath starts with \a pszParentPath (or when they
+ *          are identical), or |false| otherwise.
+ *
+ * @param   pszPath         Path to check, must be an absolute path.
+ * @param   pszParentPath   Parent path, must be an absolute path.
+ *                          No trailing directory slash!
+ *
+ * @remarks This API doesn't currently handle root directory compares in a
+ *          manner consistent with the other APIs. RTPathStartsWith(pszSomePath,
+ *          "/") will not work if pszSomePath isn't "/".
+ */
+RTDECL(bool) RTPathStartsWith(const char *pszPath, const char *pszParentPath);
+
+/**
+ * Appends one partial path to another.
+ *
+ * The main purpose of this function is to deal correctly with the slashes when
+ * concatenating the two partial paths.
+ *
+ * @retval  VINF_SUCCESS on success.
+ * @retval  VERR_BUFFER_OVERFLOW if the result is too big to fit within
+ *          cbPathDst bytes. No changes has been made.
+ * @retval  VERR_INVALID_PARAMETER if the string pointed to by pszPath is longer
+ *          than cbPathDst-1 bytes (failed to find terminator). Asserted.
+ *
+ * @param   pszPath         The path to append pszAppend to. This serves as both
+ *                          input and output. This can be empty, in which case
+ *                          pszAppend is just copied over.
+ * @param   cbPathDst       The size of the buffer pszPath points to, terminator
+ *                          included. This should NOT be strlen(pszPath).
+ * @param   pszAppend       The partial path to append to pszPath. This can be
+ *                          NULL, in which case nothing is done.
+ *
+ * @remarks See the RTPathAppendEx remarks.
+ */
+RTDECL(int) RTPathAppend(char *pszPath, size_t cbPathDst, const char *pszAppend);
+
+/**
+ * Appends one partial path to another.
+ *
+ * The main purpose of this function is to deal correctly with the slashes when
+ * concatenating the two partial paths.
+ *
+ * @retval  VINF_SUCCESS on success.
+ * @retval  VERR_BUFFER_OVERFLOW if the result is too big to fit within
+ *          cbPathDst bytes. No changes has been made.
+ * @retval  VERR_INVALID_PARAMETER if the string pointed to by pszPath is longer
+ *          than cbPathDst-1 bytes (failed to find terminator). Asserted.
+ *
+ * @param   pszPath         The path to append pszAppend to. This serves as both
+ *                          input and output. This can be empty, in which case
+ *                          pszAppend is just copied over.
+ * @param   cbPathDst       The size of the buffer pszPath points to, terminator
+ *                          included. This should NOT be strlen(pszPath).
+ * @param   pszAppend       The partial path to append to pszPath. This can be
+ *                          NULL, in which case nothing is done.
+ * @param   cchAppendMax    The maximum number or characters to take from @a
+ *                          pszAppend.  RTSTR_MAX is fine.
+ *
+ * @remarks On OS/2, Window and similar systems, concatenating a drive letter
+ *          specifier with a slash prefixed path will result in an absolute
+ *          path. Meaning, RTPathAppend(strcpy(szBuf, "C:"), sizeof(szBuf),
+ *          "/bar") will result in "C:/bar". (This follows directly from the
+ *          behavior when pszPath is empty.)
+ *
+ *          On the other hand, when joining a drive letter specifier with a
+ *          partial path that does not start with a slash, the result is not an
+ *          absolute path. Meaning, RTPathAppend(strcpy(szBuf, "C:"),
+ *          sizeof(szBuf), "bar") will result in "C:bar".
+ */
+RTDECL(int) RTPathAppendEx(char *pszPath, size_t cbPathDst, const char *pszAppend, size_t cchAppendMax);
+
+/**
+ * Like RTPathAppend, but with the base path as a separate argument instead of
+ * in the path buffer.
+ *
+ * @retval  VINF_SUCCESS on success.
+ * @retval  VERR_BUFFER_OVERFLOW if the result is too big to fit within
+ *          cbPathDst bytes.
+ * @retval  VERR_INVALID_PARAMETER if the string pointed to by pszPath is longer
+ *          than cbPathDst-1 bytes (failed to find terminator). Asserted.
+ *
+ * @param   pszPathDst      Where to store the resulting path.
+ * @param   cbPathDst       The size of the buffer pszPathDst points to,
+ *                          terminator included.
+ * @param   pszPathSrc      The base path to copy into @a pszPathDst before
+ *                          appending @a pszAppend.
+ * @param   pszAppend       The partial path to append to pszPathSrc. This can
+ *                          be NULL, in which case nothing is done.
+ *
+ */
+RTDECL(int) RTPathJoin(char *pszPathDst, size_t cbPathDst, const char *pszPathSrc,
+                       const char *pszAppend);
+
+/**
+ * Same as RTPathJoin, except that the output buffer is allocated.
+ *
+ * @returns Buffer containing the joined up path, call RTStrFree to free.  NULL
+ *          on allocation failure.
+ * @param   pszPathSrc      The base path to copy into @a pszPathDst before
+ *                          appending @a pszAppend.
+ * @param   pszAppend       The partial path to append to pszPathSrc. This can
+ *                          be NULL, in which case nothing is done.
+ *
+ */
+RTDECL(char *) RTPathJoinA(const char *pszPathSrc, const char *pszAppend);
+
+/**
+ * Extended version of RTPathJoin, both inputs can be specified as substrings.
+ *
+ * @retval  VINF_SUCCESS on success.
+ * @retval  VERR_BUFFER_OVERFLOW if the result is too big to fit within
+ *          cbPathDst bytes.
+ * @retval  VERR_INVALID_PARAMETER if the string pointed to by pszPath is longer
+ *          than cbPathDst-1 bytes (failed to find terminator). Asserted.
+ *
+ * @param   pszPathDst      Where to store the resulting path.
+ * @param   cbPathDst       The size of the buffer pszPathDst points to,
+ *                          terminator included.
+ * @param   pszPathSrc      The base path to copy into @a pszPathDst before
+ *                          appending @a pszAppend.
+ * @param   cchPathSrcMax   The maximum number of bytes to copy from @a
+ *                          pszPathSrc.  RTSTR_MAX is find.
+ * @param   pszAppend       The partial path to append to pszPathSrc. This can
+ *                          be NULL, in which case nothing is done.
+ * @param   cchAppendMax    The maximum number of bytes to copy from @a
+ *                          pszAppend.  RTSTR_MAX is find.
+ *
+ */
+RTDECL(int) RTPathJoinEx(char *pszPathDst, size_t cbPathDst,
+                         const char *pszPathSrc, size_t cchPathSrcMax,
+                         const char *pszAppend, size_t cchAppendMax);
+
+/**
+ * Callback for RTPathTraverseList that's called for each element.
+ *
+ * @returns IPRT style status code. Return VERR_TRY_AGAIN to continue, any other
+ *          value will abort the traversing and be returned to the caller.
+ *
+ * @param   pchPath         Pointer to the start of the current path. This is
+ *                          not null terminated.
+ * @param   cchPath         The length of the path.
+ * @param   pvUser1         The first user parameter.
+ * @param   pvUser2         The second user parameter.
+ */
+typedef DECLCALLBACK(int) FNRTPATHTRAVERSER(char const *pchPath, size_t cchPath, void *pvUser1, void *pvUser2);
+/** Pointer to a FNRTPATHTRAVERSER. */
+typedef FNRTPATHTRAVERSER *PFNRTPATHTRAVERSER;
+
+/**
+ * Traverses a string that can contain multiple paths separated by a special
+ * character.
+ *
+ * @returns IPRT style status code from the callback or VERR_END_OF_STRING if
+ *          the callback returned VERR_TRY_AGAIN for all paths in the string.
+ *
+ * @param   pszPathList     The string to traverse.
+ * @param   chSep           The separator character.  Using the null terminator
+ *                          is fine, but the result will simply be that there
+ *                          will only be one callback for the entire string
+ *                          (save any leading white space).
+ * @param   pfnCallback     The callback.
+ * @param   pvUser1         First user argument for the callback.
+ * @param   pvUser2         Second user argument for the callback.
+ */
+RTDECL(int) RTPathTraverseList(const char *pszPathList, char chSep, PFNRTPATHTRAVERSER pfnCallback, void *pvUser1, void *pvUser2);
+
+
+/**
+ * Calculate a relative path between the two given paths.
+ *
+ * @returns IPRT status code.
+ * @retval  VINF_SUCCESS on success.
+ * @retval  VERR_BUFFER_OVERFLOW if the result is too big to fit within
+ *          cbPathDst bytes.
+ * @retval  VERR_NOT_SUPPORTED if both paths start with different volume specifiers.
+ * @param   pszPathDst      Where to store the resulting path.
+ * @param   cbPathDst       The size of the buffer pszPathDst points to,
+ *                          terminator included.
+ * @param   pszPathFrom     The path to start from creating the relative path.
+ * @param   pszPathTo       The path to reach with the created relative path.
+ */
+RTDECL(int) RTPathCalcRelative(char *pszPathDst, size_t cbPathDst,
+                               const char *pszPathFrom,
+                               const char *pszPathTo);
+
+#ifdef IN_RING3
+
+/**
+ * Gets the path to the directory containing the executable.
+ *
+ * @returns iprt status code.
+ * @param   pszPath     Buffer where to store the path.
+ * @param   cchPath     Buffer size in bytes.
+ */
+RTDECL(int) RTPathExecDir(char *pszPath, size_t cchPath);
+
+/**
+ * Gets the user home directory.
+ *
+ * @returns iprt status code.
+ * @param   pszPath     Buffer where to store the path.
+ * @param   cchPath     Buffer size in bytes.
+ */
+RTDECL(int) RTPathUserHome(char *pszPath, size_t cchPath);
+
+/**
+ * Gets the user documents directory.
+ *
+ * The returned path isn't guaranteed to exist.
+ *
+ * @returns iprt status code.
+ * @param   pszPath     Buffer where to store the path.
+ * @param   cchPath     Buffer size in bytes.
+ */
+RTDECL(int) RTPathUserDocuments(char *pszPath, size_t cchPath);
+
+/**
+ * Gets the directory of shared libraries.
+ *
+ * This is not the same as RTPathAppPrivateArch() as Linux depends all shared
+ * libraries in a common global directory where ld.so can find them.
+ *
+ * Linux:    /usr/lib
+ * Solaris:  /opt/@<application@>/@<arch>@ or something
+ * Windows:  @<program files directory@>/@<application@>
+ * Old path: same as RTPathExecDir()
+ *
+ * @returns iprt status code.
+ * @param   pszPath     Buffer where to store the path.
+ * @param   cchPath     Buffer size in bytes.
+ */
+RTDECL(int) RTPathSharedLibs(char *pszPath, size_t cchPath);
+
+/**
+ * Gets the directory for architecture-independent application data, for
+ * example NLS files, module sources, ...
+ *
+ * Linux:    /usr/shared/@<application@>
+ * Solaris:  /opt/@<application@>
+ * Windows:  @<program files directory@>/@<application@>
+ * Old path: same as RTPathExecDir()
+ *
+ * @returns iprt status code.
+ * @param   pszPath     Buffer where to store the path.
+ * @param   cchPath     Buffer size in bytes.
+ */
+RTDECL(int) RTPathAppPrivateNoArch(char *pszPath, size_t cchPath);
+
+/**
+ * Gets the directory for architecture-dependent application data, for
+ * example modules which can be loaded at runtime.
+ *
+ * Linux:    /usr/lib/@<application@>
+ * Solaris:  /opt/@<application@>/@<arch>@ or something
+ * Windows:  @<program files directory@>/@<application@>
+ * Old path: same as RTPathExecDir()
+ *
+ * @returns iprt status code.
+ * @param   pszPath     Buffer where to store the path.
+ * @param   cchPath     Buffer size in bytes.
+ */
+RTDECL(int) RTPathAppPrivateArch(char *pszPath, size_t cchPath);
+
+/**
+ * Gets the toplevel directory for architecture-dependent application data.
+ *
+ * This differs from RTPathAppPrivateArch on Solaris only where it will work
+ * around the /opt/@<application@>/amd64 and /opt/@<application@>/i386 multi
+ * architecture installation style.
+ *
+ * Linux:    /usr/lib/@<application@>
+ * Solaris:  /opt/@<application@>
+ * Windows:  @<program files directory@>/@<application@>
+ * Old path: same as RTPathExecDir()
+ *
+ * @returns iprt status code.
+ * @param   pszPath     Buffer where to store the path.
+ * @param   cchPath     Buffer size in bytes.
+ */
+RTDECL(int) RTPathAppPrivateArchTop(char *pszPath, size_t cchPath);
+
+/**
+ * Gets the directory for documentation.
+ *
+ * Linux:    /usr/share/doc/@<application@>
+ * Solaris:  /opt/@<application@>
+ * Windows:  @<program files directory@>/@<application@>
+ * Old path: same as RTPathExecDir()
+ *
+ * @returns iprt status code.
+ * @param   pszPath     Buffer where to store the path.
+ * @param   cchPath     Buffer size in bytes.
+ */
+RTDECL(int) RTPathAppDocs(char *pszPath, size_t cchPath);
+
+/**
+ * Gets the temporary directory path.
+ *
+ * @returns iprt status code.
+ * @param   pszPath     Buffer where to store the path.
+ * @param   cchPath     Buffer size in bytes.
+ */
+RTDECL(int) RTPathTemp(char *pszPath, size_t cchPath);
+
+
+/**
+ * RTPathGlobl result entry.
+ */
+typedef struct RTPATHGLOBENTRY
+{
+    /** List entry. */
+    struct RTPATHGLOBENTRY *pNext;
+    /** RTDIRENTRYTYPE value. */
+    uint8_t                 uType;
+    /** Unused explicit padding. */
+    uint8_t                 bUnused;
+    /** The length of the path. */
+    uint16_t                cchPath;
+    /** The path to the file (variable length). */
+    char                    szPath[1];
+} RTPATHGLOBENTRY;
+/** Pointer to a GLOB result entry. */
+typedef RTPATHGLOBENTRY *PRTPATHGLOBENTRY;
+/** Pointer to a const GLOB result entry. */
+typedef RTPATHGLOBENTRY const *PCRTPATHGLOBENTRY;
+/** Pointer to a GLOB result entry pointer. */
+typedef PCRTPATHGLOBENTRY *PPCRTPATHGLOBENTRY;
+
+/**
+ * Performs wildcard expansion on a path pattern.
+ *
+ * @returns IPRT status code.
+ *
+ * @param   pszPattern      The pattern to expand.
+ * @param   fFlags          RTPATHGLOB_F_XXX.
+ * @param   ppHead          Where to return the head of the result list.  This
+ *                          is always set to NULL on failure.
+ * @param   pcResults       Where to return the number of the result. Optional.
+ */
+RTDECL(int) RTPathGlob(const char *pszPattern, uint32_t fFlags, PPCRTPATHGLOBENTRY ppHead, uint32_t *pcResults);
+
+/** @name RTPATHGLOB_F_XXX - RTPathGlob flags
+ *  @{ */
+/** Case insensitive. */
+#define RTPATHGLOB_F_IGNORE_CASE        RT_BIT_32(0)
+/** Do not expand \${EnvOrSpecialVariable} in the pattern. */
+#define RTPATHGLOB_F_NO_VARIABLES       RT_BIT_32(1)
+/** Do not interpret a leading tilde as a home directory reference. */
+#define RTPATHGLOB_F_NO_TILDE           RT_BIT_32(2)
+/** Only return the first match. */
+#define RTPATHGLOB_F_FIRST_ONLY         RT_BIT_32(3)
+/** Only match directories (implied if pattern ends with slash). */
+#define RTPATHGLOB_F_ONLY_DIRS          RT_BIT_32(4)
+/** Do not match directories.  (Can't be used with RTPATHGLOB_F_ONLY_DIRS or
+ * patterns containing a trailing slash.) */
+#define RTPATHGLOB_F_NO_DIRS            RT_BIT_32(5)
+/** Disables the '**' wildcard pattern for matching zero or more subdirs. */
+#define RTPATHGLOB_F_NO_STARSTAR        RT_BIT_32(6)
+/** Mask of valid flags. */
+#define RTPATHGLOB_F_MASK               UINT32_C(0x0000007f)
+/** @} */
+
+/**
+ * Frees the results produced by RTPathGlob.
+ *
+ * @param   pHead           What RTPathGlob returned.  NULL ignored.
+ */
+RTDECL(void) RTPathGlobFree(PCRTPATHGLOBENTRY pHead);
+
+
+/**
+ * Query information about a file system object.
+ *
+ * This API will resolve NOT symbolic links in the last component (just like
+ * unix lstat()).
+ *
+ * @returns IPRT status code.
+ * @retval  VINF_SUCCESS if the object exists, information returned.
+ * @retval  VERR_PATH_NOT_FOUND if any but the last component in the specified
+ *          path was not found or was not a directory.
+ * @retval  VERR_FILE_NOT_FOUND if the object does not exist (but path to the
+ *          parent directory exists).
+ *
+ * @param   pszPath     Path to the file system object.
+ * @param   pObjInfo    Object information structure to be filled on successful
+ *                      return.
+ * @param   enmAdditionalAttribs
+ *                      Which set of additional attributes to request.
+ *                      Use RTFSOBJATTRADD_NOTHING if this doesn't matter.
+ */
+RTR3DECL(int) RTPathQueryInfo(const char *pszPath, PRTFSOBJINFO pObjInfo, RTFSOBJATTRADD enmAdditionalAttribs);
+
+/**
+ * Query information about a file system object.
+ *
+ * @returns IPRT status code.
+ * @retval  VINF_SUCCESS if the object exists, information returned.
+ * @retval  VERR_PATH_NOT_FOUND if any but the last component in the specified
+ *          path was not found or was not a directory.
+ * @retval  VERR_FILE_NOT_FOUND if the object does not exist (but path to the
+ *          parent directory exists).
+ *
+ * @param   pszPath     Path to the file system object.
+ * @param   pObjInfo    Object information structure to be filled on successful return.
+ * @param   enmAdditionalAttribs
+ *                      Which set of additional attributes to request.
+ *                      Use RTFSOBJATTRADD_NOTHING if this doesn't matter.
+ * @param   fFlags      RTPATH_F_ON_LINK or RTPATH_F_FOLLOW_LINK.
+ */
+RTR3DECL(int) RTPathQueryInfoEx(const char *pszPath, PRTFSOBJINFO pObjInfo, RTFSOBJATTRADD enmAdditionalAttribs, uint32_t fFlags);
+
+/**
+ * Changes the mode flags of a file system object.
+ *
+ * The API requires at least one of the mode flag sets (Unix/Dos) to
+ * be set. The type is ignored.
+ *
+ * This API will resolve symbolic links in the last component since
+ * mode isn't important for symbolic links.
+ *
+ * @returns iprt status code.
+ * @param   pszPath     Path to the file system object.
+ * @param   fMode       The new file mode, see @ref grp_rt_fs for details.
+ */
+RTR3DECL(int) RTPathSetMode(const char *pszPath, RTFMODE fMode);
+
+/**
+ * Gets the mode flags of a file system object.
+ *
+ * @returns iprt status code.
+ * @param   pszPath     Path to the file system object.
+ * @param   pfMode      Where to store the file mode, see @ref grp_rt_fs for details.
+ *
+ * @remark  This is wrapper around RTPathQueryInfoEx(RTPATH_F_FOLLOW_LINK) and
+ *          exists to complement RTPathSetMode().
+ */
+RTR3DECL(int) RTPathGetMode(const char *pszPath, PRTFMODE pfMode);
+
+/**
+ * Changes one or more of the timestamps associated of file system object.
+ *
+ * This API will not resolve symbolic links in the last component (just
+ * like unix lutimes()).
+ *
+ * @returns iprt status code.
+ * @param   pszPath             Path to the file system object.
+ * @param   pAccessTime         Pointer to the new access time.
+ * @param   pModificationTime   Pointer to the new modification time.
+ * @param   pChangeTime         Pointer to the new change time. NULL if not to be changed.
+ * @param   pBirthTime          Pointer to the new time of birth. NULL if not to be changed.
+ *
+ * @remark  The file system might not implement all these time attributes,
+ *          the API will ignore the ones which aren't supported.
+ *
+ * @remark  The file system might not implement the time resolution
+ *          employed by this interface, the time will be chopped to fit.
+ *
+ * @remark  The file system may update the change time even if it's
+ *          not specified.
+ *
+ * @remark  POSIX can only set Access & Modification and will always set both.
+ */
+RTR3DECL(int) RTPathSetTimes(const char *pszPath, PCRTTIMESPEC pAccessTime, PCRTTIMESPEC pModificationTime,
+                             PCRTTIMESPEC pChangeTime, PCRTTIMESPEC pBirthTime);
+
+/**
+ * Changes one or more of the timestamps associated of file system object.
+ *
+ * @returns iprt status code.
+ * @param   pszPath             Path to the file system object.
+ * @param   pAccessTime         Pointer to the new access time.
+ * @param   pModificationTime   Pointer to the new modification time.
+ * @param   pChangeTime         Pointer to the new change time. NULL if not to be changed.
+ * @param   pBirthTime          Pointer to the new time of birth. NULL if not to be changed.
+ * @param   fFlags              RTPATH_F_ON_LINK or RTPATH_F_FOLLOW_LINK.
+ *
+ * @remark  The file system might not implement all these time attributes,
+ *          the API will ignore the ones which aren't supported.
+ *
+ * @remark  The file system might not implement the time resolution
+ *          employed by this interface, the time will be chopped to fit.
+ *
+ * @remark  The file system may update the change time even if it's
+ *          not specified.
+ *
+ * @remark  POSIX can only set Access & Modification and will always set both.
+ */
+RTR3DECL(int) RTPathSetTimesEx(const char *pszPath, PCRTTIMESPEC pAccessTime, PCRTTIMESPEC pModificationTime,
+                               PCRTTIMESPEC pChangeTime, PCRTTIMESPEC pBirthTime, uint32_t fFlags);
+
+/**
+ * Gets one or more of the timestamps associated of file system object.
+ *
+ * @returns iprt status code.
+ * @param   pszPath             Path to the file system object.
+ * @param   pAccessTime         Where to store the access time. NULL is ok.
+ * @param   pModificationTime   Where to store the modification time. NULL is ok.
+ * @param   pChangeTime         Where to store the change time. NULL is ok.
+ * @param   pBirthTime          Where to store the creation time. NULL is ok.
+ *
+ * @remark  This is wrapper around RTPathQueryInfo() and exists to complement
+ *          RTPathSetTimes().  If the last component is a symbolic link, it will
+ *          not be resolved.
+ */
+RTR3DECL(int) RTPathGetTimes(const char *pszPath, PRTTIMESPEC pAccessTime, PRTTIMESPEC pModificationTime,
+                             PRTTIMESPEC pChangeTime, PRTTIMESPEC pBirthTime);
+
+/**
+ * Changes the owner and/or group of a file system object.
+ *
+ * This API will not resolve symbolic links in the last component (just
+ * like unix lchown()).
+ *
+ * @returns iprt status code.
+ * @param   pszPath     Path to the file system object.
+ * @param   uid         The new file owner user id.  Pass NIL_RTUID to leave
+ *                      this unchanged.
+ * @param   gid         The new group id.  Pass NIL_RTGUID to leave this
+ *                      unchanged.
+ */
+RTR3DECL(int) RTPathSetOwner(const char *pszPath, uint32_t uid, uint32_t gid);
+
+/**
+ * Changes the owner and/or group of a file system object.
+ *
+ * @returns iprt status code.
+ * @param   pszPath     Path to the file system object.
+ * @param   uid         The new file owner user id.  Pass NIL_RTUID to leave
+ *                      this unchanged.
+ * @param   gid         The new group id.  Pass NIL_RTGID to leave this
+ *                      unchanged.
+ * @param   fFlags      RTPATH_F_ON_LINK or RTPATH_F_FOLLOW_LINK.
+ */
+RTR3DECL(int) RTPathSetOwnerEx(const char *pszPath, uint32_t uid, uint32_t gid, uint32_t fFlags);
+
+/**
+ * Gets the owner and/or group of a file system object.
+ *
+ * @returns iprt status code.
+ * @param   pszPath     Path to the file system object.
+ * @param   pUid        Where to store the owner user id. NULL is ok.
+ * @param   pGid        Where to store the group id. NULL is ok.
+ *
+ * @remark  This is wrapper around RTPathQueryInfo() and exists to complement
+ *          RTPathGetOwner().  If the last component is a symbolic link, it will
+ *          not be resolved.
+ */
+RTR3DECL(int) RTPathGetOwner(const char *pszPath, uint32_t *pUid, uint32_t *pGid);
+
+
+/** @name RTPathRename, RTDirRename & RTFileRename flags.
+ * @{ */
+/** Do not replace anything. */
+#define RTPATHRENAME_FLAGS_NO_REPLACE   UINT32_C(0)
+/** This will replace attempt any target which isn't a directory. */
+#define RTPATHRENAME_FLAGS_REPLACE      RT_BIT(0)
+/** Don't allow symbolic links as part of the path.
+ * @remarks this flag is currently not implemented and will be ignored. */
+#define RTPATHRENAME_FLAGS_NO_SYMLINKS  RT_BIT(1)
+/** @} */
+
+/**
+ * Renames a path within a filesystem.
+ *
+ * This will rename symbolic links.  If RTPATHRENAME_FLAGS_REPLACE is used and
+ * pszDst is a symbolic link, it will be replaced and not its target.
+ *
+ * @returns IPRT status code.
+ * @param   pszSrc      The source path.
+ * @param   pszDst      The destination path.
+ * @param   fRename     Rename flags, RTPATHRENAME_FLAGS_*.
+ */
+RTR3DECL(int) RTPathRename(const char *pszSrc,  const char *pszDst, unsigned fRename);
+
+/** @name RTPathUnlink flags.
+ * @{ */
+/** Don't allow symbolic links as part of the path.
+ * @remarks this flag is currently not implemented and will be ignored. */
+#define RTPATHUNLINK_FLAGS_NO_SYMLINKS  RT_BIT(0)
+/** @} */
+
+/**
+ * Removes the last component of the path.
+ *
+ * @returns IPRT status code.
+ * @param   pszPath     The path.
+ * @param   fUnlink     Unlink flags, RTPATHUNLINK_FLAGS_*.
+ */
+RTR3DECL(int) RTPathUnlink(const char *pszPath, uint32_t fUnlink);
+
+/**
+ * A /bin/rm tool.
+ *
+ * @returns Program exit code.
+ *
+ * @param   cArgs               The number of arguments.
+ * @param   papszArgs           The argument vector.  (Note that this may be
+ *                              reordered, so the memory must be writable.)
+ */
+RTDECL(RTEXITCODE) RTPathRmCmd(unsigned cArgs, char **papszArgs);
+
+#endif /* IN_RING3 */
+
+/** @} */
+
+RT_C_DECLS_END
+
+#endif
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/include/iprt/power.h
@@ -0,0 +1,112 @@
+/** @file
+ * IPRT - Power management.
+ */
+
+/*
+ * Copyright (C) 2008-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+#ifndef ___iprt_power_h
+#define ___iprt_power_h
+
+#include <iprt/cdefs.h>
+#include <iprt/types.h>
+
+
+RT_C_DECLS_BEGIN
+
+/** @defgroup grp_rt_power RTPower - Power management
+ * @ingroup grp_rt
+ * @{
+ */
+
+#ifdef IN_RING0
+
+/**
+ * MP event, see FNRTPOWERNOTIFICATION.
+ */
+typedef enum RTPOWEREVENT
+{
+    /** The system will go into suspend mode. */
+    RTPOWEREVENT_SUSPEND = 1,
+    /** The system has resumed. */
+    RTPOWEREVENT_RESUME
+} RTPOWEREVENT;
+
+/**
+ * Notification callback.
+ *
+ * The context this is called in differs a bit from platform to
+ * platform, so be careful while in here.
+ *
+ * @param   enmEvent    The event.
+ * @param   pvUser      The user argument.
+ */
+typedef DECLCALLBACK(void) FNRTPOWERNOTIFICATION(RTPOWEREVENT enmEvent, void *pvUser);
+/** Pointer to a FNRTPOWERNOTIFICATION(). */
+typedef FNRTPOWERNOTIFICATION *PFNRTPOWERNOTIFICATION;
+
+/**
+ * Registers a notification callback for power events.
+ *
+ * @returns IPRT status code.
+ * @retval  VINF_SUCCESS on success.
+ * @retval  VERR_NO_MEMORY if a registration record cannot be allocated.
+ * @retval  VERR_ALREADY_EXISTS if the pfnCallback and pvUser already exist
+ *          in the callback list.
+ *
+ * @param   pfnCallback     The callback.
+ * @param   pvUser          The user argument to the callback function.
+ */
+RTDECL(int) RTPowerNotificationRegister(PFNRTPOWERNOTIFICATION pfnCallback, void *pvUser);
+
+/**
+ * This deregisters a notification callback registered via RTPowerNotificationRegister().
+ *
+ * The pfnCallback and pvUser arguments must be identical to the registration call
+ * of we won't find the right entry.
+ *
+ * @returns IPRT status code.
+ * @retval  VINF_SUCCESS on success.
+ * @retval  VERR_NOT_FOUND if no matching entry was found.
+ *
+ * @param   pfnCallback     The callback.
+ * @param   pvUser          The user argument to the callback function.
+ */
+RTDECL(int) RTPowerNotificationDeregister(PFNRTPOWERNOTIFICATION pfnCallback, void *pvUser);
+
+/**
+ * This calls all registered power management callback handlers registered via RTPowerNotificationRegister().
+ *
+ * @returns IPRT status code.
+ * @retval  VINF_SUCCESS on success.
+ *
+ * @param   enmEvent        Power Management event
+ */
+RTDECL(int) RTPowerSignalEvent(RTPOWEREVENT enmEvent);
+
+#endif /* IN_RING0 */
+
+/** @} */
+
+RT_C_DECLS_END
+
+#endif
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/include/iprt/process.h
@@ -0,0 +1,421 @@
+/** @file
+ * IPRT - Process Management.
+ */
+
+/*
+ * Copyright (C) 2006-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+#ifndef ___iprt_process_h
+#define ___iprt_process_h
+
+#include <iprt/cdefs.h>
+#include <iprt/types.h>
+
+RT_C_DECLS_BEGIN
+
+/** @defgroup grp_rt_process    RTProc - Process Management
+ * @ingroup grp_rt
+ * @{
+ */
+
+
+/**
+ * Process priority.
+ *
+ * The process priority is used to select how scheduling properties
+ * are assigned to the different thread types (see THREADTYPE).
+ *
+ * In addition to using the policy assigned to the process at startup (DEFAULT)
+ * it is possible to change the process priority at runtime. This allows for
+ * a GUI, resource manager or admin to adjust the general priority of a task
+ * without upsetting the fine-tuned priority of the threads within.
+ */
+typedef enum RTPROCPRIORITY
+{
+    /** Invalid priority. */
+    RTPROCPRIORITY_INVALID = 0,
+    /** Default priority.
+     * Derive the scheduling policy from the priority of the RTR3Init()
+     * and RTProcSetPriority() callers and the rights the process have
+     * to alter its own priority.
+     */
+    RTPROCPRIORITY_DEFAULT,
+    /** Flat priority.
+     * Assumes a scheduling policy which puts the process at the default priority
+     * and with all thread at the same priority.
+     */
+    RTPROCPRIORITY_FLAT,
+    /** Low priority.
+     * Assumes a scheduling policy which puts the process mostly below the
+     * default priority of the host OS.
+     */
+    RTPROCPRIORITY_LOW,
+    /** Normal priority.
+     * Assume a scheduling policy which shares the CPU resources fairly with
+     * other processes running with the default priority of the host OS.
+     */
+    RTPROCPRIORITY_NORMAL,
+    /** High priority.
+     * Assumes a scheduling policy which puts the task above the default
+     * priority of the host OS. This policy might easily cause other tasks
+     * in the system to starve.
+     */
+    RTPROCPRIORITY_HIGH,
+    /** Last priority, used for validation. */
+    RTPROCPRIORITY_LAST
+} RTPROCPRIORITY;
+
+
+/**
+ * Get the current process identifier.
+ *
+ * @returns Process identifier.
+ */
+RTDECL(RTPROCESS) RTProcSelf(void);
+
+
+#ifdef IN_RING0
+/**
+ * Get the current process handle.
+ *
+ * @returns Ring-0 process handle.
+ */
+RTR0DECL(RTR0PROCESS) RTR0ProcHandleSelf(void);
+#endif
+
+
+#ifdef IN_RING3
+
+/**
+ * Attempts to alter the priority of the current process.
+ *
+ * @returns iprt status code.
+ * @param   enmPriority     The new priority.
+ */
+RTR3DECL(int) RTProcSetPriority(RTPROCPRIORITY enmPriority);
+
+/**
+ * Gets the current priority of this process.
+ *
+ * @returns The priority (see RTPROCPRIORITY).
+ */
+RTR3DECL(RTPROCPRIORITY) RTProcGetPriority(void);
+
+/**
+ * Create a child process.
+ *
+ * @returns iprt status code.
+ * @param   pszExec     Executable image to use to create the child process.
+ * @param   papszArgs   Pointer to an array of arguments to the child. The array terminated by an entry containing NULL.
+ * @param   Env         Handle to the environment block for the child.
+ * @param   fFlags      Flags, one of the RTPROC_FLAGS_* defines.
+ * @param   pProcess    Where to store the process identifier on successful return.
+ *                      The content is not changed on failure. NULL is allowed.
+ */
+RTR3DECL(int)   RTProcCreate(const char *pszExec, const char * const *papszArgs, RTENV Env, unsigned fFlags, PRTPROCESS pProcess);
+
+
+/**
+ * Create a child process.
+ *
+ * @returns IPRT status code.
+ *
+ * @param   pszExec     Executable image to use to create the child process.
+ * @param   papszArgs   Pointer to an array of arguments to the child.  The
+ *                      array terminated by an entry containing NULL.
+ * @param   hEnv        Handle to the environment block for the child.  Pass
+ *                      RTENV_DEFAULT to use the environment of the current
+ *                      process.
+ * @param   fFlags      Flags, one of the RTPROC_FLAGS_* defines.
+ * @param   phStdIn     The standard in handle to assign the new process. Pass
+ *                      NULL to use the same as the current process.  If the
+ *                      handle is NIL, we'll close the standard input of the
+ *                      guest.
+ * @param   phStdOut    The standard out handle to assign the new process.  Pass
+ *                      NULL to use the same as the current process.  If the
+ *                      handle is NIL, we'll close the standard output of the
+ *                      guest.
+ * @param   phStdErr    The standard error handle to assign the new process.  Pass
+ *                      NULL to use the same as the current process.  If the
+ *                      handle is NIL, we'll close the standard error of the
+ *                      guest.
+ * @param   pszAsUser   User to run the process as.  Pass NULL to use the same
+ *                      user as the current process.
+ *                      Windows: Use user\@domain (UPN, User Principal Name)
+ *                      format to specify a domain.
+ * @param   pszPassword Password to use to authenticate @a pszAsUser.  Must be
+ *                      NULL wif pszAsUser is NULL.  Whether this is actually
+ *                      used or not depends on the platform.
+ * @param   phProcess   Where to store the process handle on successful return.
+ *                      The content is not changed on failure.  NULL is allowed.
+ *
+ * @remarks The handles does not have to be created as inheritable, but it
+ *          doesn't hurt if they are as it may avoid race conditions on some
+ *          platforms.
+ *
+ * @remarks The as-user feature isn't supported/implemented on all platforms and
+ *          will cause a-yet-to-be-determined-error-status on these.
+ */
+RTR3DECL(int)   RTProcCreateEx(const char *pszExec, const char * const *papszArgs, RTENV hEnv, uint32_t fFlags,
+                               PCRTHANDLE phStdIn, PCRTHANDLE phStdOut, PCRTHANDLE phStdErr, const char *pszAsUser,
+                               const char *pszPassword, PRTPROCESS phProcess);
+
+/** @name RTProcCreate and RTProcCreateEx flags
+ * @{ */
+/** Detach the child process from the parents process tree and process group,
+ * session or/and console (depends on the platform what's done applicable).
+ *
+ * The new process will not be a direct decendent of the parent and it will not
+ * be possible to wait for it, i.e. @a phProcess shall be NULL. */
+#define RTPROC_FLAGS_DETACHED               RT_BIT(0)
+/** Don't show the started process.
+ * This is a Windows (and maybe OS/2) concept, do not use on other platforms. */
+#define RTPROC_FLAGS_HIDDEN                 RT_BIT(1)
+/** Use special code path for starting child processes from a service (daemon).
+ * This is a windows concept for dealing with the so called "Session 0"
+ * isolation which was introduced with Windows Vista. Do not use on other
+ * platforms. */
+#define RTPROC_FLAGS_SERVICE                RT_BIT(2)
+/** Suppress changing the process contract id for the child process
+ * on Solaris.  Without this flag the contract id is always changed, as that's
+ * the more frequently used case. */
+#define RTPROC_FLAGS_SAME_CONTRACT          RT_BIT(3)
+/** Load user profile data when executing a process.
+ * This redefines the meaning of RTENV_DEFAULT to the profile environment.
+ * @remarks On non-windows platforms, the resulting environment maybe very
+ *          different from what you see in your shell.  Among other reasons,
+ *          we cannot run shell profile scripts which typically sets up the
+ *          environment. */
+#define RTPROC_FLAGS_PROFILE                RT_BIT(4)
+/** Create process without a console window.
+ * This is a Windows (and OS/2) concept, do not use on other platforms. */
+#define RTPROC_FLAGS_NO_WINDOW              RT_BIT(5)
+/** Search the PATH for the executable.  */
+#define RTPROC_FLAGS_SEARCH_PATH            RT_BIT(6)
+/** Don't quote and escape arguments on Windows and similar platforms where a
+ * command line is passed to the child process instead of an argument vector,
+ * just join up argv with a space between each.  Ignored on platforms
+ * passing argument the vector. */
+#define RTPROC_FLAGS_UNQUOTED_ARGS          RT_BIT(7)
+/** Consider hEnv an environment change record to be applied to RTENV_DEFAULT.
+ * If hEnv is RTENV_DEFAULT, the flag has no effect. */
+#define RTPROC_FLAGS_ENV_CHANGE_RECORD      RT_BIT(8)
+/** Valid flag mask. */
+#define RTPROC_FLAGS_VALID_MASK             UINT32_C(0x1ff)
+/** @}  */
+
+
+/**
+ * Process exit reason.
+ */
+typedef enum RTPROCEXITREASON
+{
+    /** Normal exit. iStatus contains the exit code. */
+    RTPROCEXITREASON_NORMAL = 1,
+    /** Any abnormal exit. iStatus is undefined. */
+    RTPROCEXITREASON_ABEND,
+    /** Killed by a signal. The iStatus field contains the signal number. */
+    RTPROCEXITREASON_SIGNAL
+} RTPROCEXITREASON;
+
+/**
+ * Process exit status.
+ */
+typedef struct RTPROCSTATUS
+{
+    /** The process exit status if the exit was a normal one. */
+    int                 iStatus;
+    /** The reason the process terminated. */
+    RTPROCEXITREASON    enmReason;
+} RTPROCSTATUS;
+/** Pointer to a process exit status structure. */
+typedef RTPROCSTATUS *PRTPROCSTATUS;
+/** Pointer to a const process exit status structure. */
+typedef const RTPROCSTATUS *PCRTPROCSTATUS;
+
+
+/** Flags for RTProcWait().
+ * @{ */
+/** Block indefinitly waiting for the process to exit. */
+#define RTPROCWAIT_FLAGS_BLOCK      0
+/** Don't block, just check if the process have exited. */
+#define RTPROCWAIT_FLAGS_NOBLOCK    1
+/** @} */
+
+/**
+ * Waits for a process, resumes on interruption.
+ *
+ * @returns VINF_SUCCESS when the status code for the process was collected and
+ *          put in *pProcStatus.
+ * @returns VERR_PROCESS_NOT_FOUND if the specified process wasn't found.
+ * @returns VERR_PROCESS_RUNNING when the RTPROCWAIT_FLAGS_NOBLOCK and the
+ *          process haven't exited yet.
+ *
+ * @param   Process         The process to wait for.
+ * @param   fFlags          The wait flags, any of the RTPROCWAIT_FLAGS_ \#defines.
+ * @param   pProcStatus     Where to store the exit status on success.
+ *                          Optional.
+ */
+RTR3DECL(int) RTProcWait(RTPROCESS Process, unsigned fFlags, PRTPROCSTATUS pProcStatus);
+
+/**
+ * Waits for a process, returns on interruption.
+ *
+ * @returns VINF_SUCCESS when the status code for the process was collected and
+ *          put in *pProcStatus.
+ * @returns VERR_PROCESS_NOT_FOUND if the specified process wasn't found.
+ * @returns VERR_PROCESS_RUNNING when the RTPROCWAIT_FLAGS_NOBLOCK and the
+ *          process haven't exited yet.
+ * @returns VERR_INTERRUPTED when the wait was interrupted by the arrival of a
+ *          signal or other async event.
+ *
+ * @param   Process         The process to wait for.
+ * @param   fFlags          The wait flags, any of the RTPROCWAIT_FLAGS_ \#defines.
+ * @param   pProcStatus     Where to store the exit status on success.
+ *                          Optional.
+ */
+RTR3DECL(int) RTProcWaitNoResume(RTPROCESS Process, unsigned fFlags, PRTPROCSTATUS pProcStatus);
+
+/**
+ * Terminates (kills) a running process.
+ *
+ * @returns IPRT status code.
+ * @param   Process     The process to terminate.
+ */
+RTR3DECL(int) RTProcTerminate(RTPROCESS Process);
+
+/**
+ * Gets the processor affinity mask of the current process.
+ *
+ * @returns The affinity mask.
+ */
+RTR3DECL(uint64_t) RTProcGetAffinityMask(void);
+
+/**
+ * Gets the short process name.
+ *
+ * @returns Pointer to read-only name string.
+ */
+RTR3DECL(const char *) RTProcShortName(void);
+
+/**
+ * Gets the path to the executable image of the current process.
+ *
+ * @returns pszExecPath on success. NULL on buffer overflow or other errors.
+ *
+ * @param   pszExecPath     Where to store the path.
+ * @param   cbExecPath      The size of the buffer.
+ */
+RTR3DECL(char *) RTProcGetExecutablePath(char *pszExecPath, size_t cbExecPath);
+
+/**
+ * Daemonize the current process, making it a background process.
+ *
+ * The way this work is that it will spawn a detached / backgrounded /
+ * daemonized / call-it-what-you-want process that isn't a direct child of the
+ * current process.  The spawned will have the same arguments a the caller,
+ * except that the @a pszDaemonizedOpt is appended to prevent that the new
+ * process calls this API again.
+ *
+ * The new process will have the standard handles directed to/from the
+ * bitbucket.
+ *
+ * @returns IPRT status code.  On success it is normal for the caller to exit
+ *          the process by returning from main().
+ *
+ * @param   papszArgs           The argument vector of the calling process.
+ * @param   pszDaemonizedOpt    The daemonized option.  This is appended to the
+ *                              end of the parameter list of the daemonized process.
+ */
+RTR3DECL(int)   RTProcDaemonize(const char * const *papszArgs, const char *pszDaemonizedOpt);
+
+/**
+ * Daemonize the current process, making it a background process. The current
+ * process will exit if daemonizing is successful.
+ *
+ * @returns IPRT status code.   On success it will only return in the child
+ *          process, the parent will exit.  On failure, it will return in the
+ *          parent process and no child has been spawned.
+ *
+ * @param   fNoChDir    Pass false to change working directory to "/".
+ * @param   fNoClose    Pass false to redirect standard file streams to the null device.
+ * @param   pszPidfile  Path to a file to write the process id of the daemon
+ *                      process to. Daemonizing will fail if this file already
+ *                      exists or cannot be written. May be NULL.
+ */
+RTR3DECL(int)   RTProcDaemonizeUsingFork(bool fNoChDir, bool fNoClose, const char *pszPidfile);
+
+/**
+ * Check if the given process is running on the system.
+ *
+ * This check is case sensitive on most systems, except for Windows, OS/2 and
+ * Darwin.
+ *
+ * @returns true if the process is running & false otherwise.
+ * @param   pszName     Process name to search for. If no path is given only the
+ *                      filename part of the running process set will be
+ *                      matched. If a path is specified, the full path will be
+ *                      matched.
+ */
+RTR3DECL(bool)  RTProcIsRunningByName(const char *pszName);
+
+/**
+ * Queries the parent process ID.
+ *
+ * @returns IPRT status code
+ * @param   hProcess     The process to query the parent of.
+ * @param   phParent     Where to return the parent process ID.
+ */
+RTR3DECL(int) RTProcQueryParent(RTPROCESS hProcess, PRTPROCESS phParent);
+
+/**
+ * Query the username of the given process.
+ *
+ * @returns IPRT status code.
+ * @retval VERR_BUFFER_OVERFLOW if the given buffer size is to small for the username.
+ * @param   hProcess     The process handle to query the username for.
+ *                       NIL_PROCESS is an alias for the current process.
+ * @param   pszUser      Where to store the user name on success.
+ * @param   cbUser       The size of the user name buffer.
+ * @param   pcbUser      Where to store the username length on success
+ *                       or the required buffer size if VERR_BUFFER_OVERFLOW
+ *                       is returned.
+ */
+RTR3DECL(int)   RTProcQueryUsername(RTPROCESS hProcess, char *pszUser, size_t cbUser, size_t *pcbUser);
+
+/**
+ * Query the username of the given process allocating the string for the username.
+ *
+ * @returns IPRT status code.
+ * @param   hProcess     The process handle to query the username for.
+ * @param   ppszUser     Where to store the pointer to the string containing
+ *                       the username on success. Free with RTStrFree().
+ */
+RTR3DECL(int)   RTProcQueryUsernameA(RTPROCESS hProcess, char **ppszUser);
+
+#endif /* IN_RING3 */
+
+/** @} */
+
+RT_C_DECLS_END
+
+#endif
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/include/iprt/semaphore.h
@@ -0,0 +1,1409 @@
+/** @file
+ * IPRT - Semaphore.
+ */
+
+/*
+ * Copyright (C) 2006-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+#ifndef ___iprt_semaphore_h
+#define ___iprt_semaphore_h
+
+#include <iprt/cdefs.h>
+#include <iprt/types.h>
+#if defined(RT_LOCK_STRICT_ORDER) && defined(IN_RING3)
+# include <iprt/lockvalidator.h>
+#endif
+
+
+RT_C_DECLS_BEGIN
+
+/** @defgroup grp_rt_sems    RTSem - Semaphores
+ *
+ * This module implements all kinds of event and mutex semaphores; in addition
+ * to these, IPRT implements "critical sections", which are fast recursive
+ * mutexes (see @ref grp_rt_critsect ).  C++ users may find @ref grp_rt_cpp_lock
+ * interesting.
+ *
+ * @ingroup grp_rt
+ * @{
+ */
+
+
+/** @name Generic Semaphore Wait Flags.
+ *
+ * @remarks Exactly one of RTSEMWAIT_FLAGS_RELATIVE and
+ *          RTSEMWAIT_FLAGS_ABSOLUTE must be set, unless
+ *          RTSEMWAIT_FLAGS_INDEFINITE is used.
+ *
+ *          Exactly one of RTSEMWAIT_FLAGS_NANOSECS and
+ *          RTSEMWAIT_FLAGS_MILLISECS must be set, unless
+ *          RTSEMWAIT_FLAGS_INDEFINITE is used.
+ *
+ *          Exactly one of RTSEMWAIT_FLAGS_RESUME and RTSEMWAIT_FLAGS_NORESUME
+ *          must be set.
+ *
+ *          The interruptible vs resume stuff is ring-0 vs ring-3 semantics.
+ *
+ * @{ */
+/** The timeout is relative. */
+#define RTSEMWAIT_FLAGS_RELATIVE            RT_BIT_32(0)
+/** The timeout is absolute. */
+#define RTSEMWAIT_FLAGS_ABSOLUTE            RT_BIT_32(1)
+/** The timeout is specified in nanoseconds. */
+#define RTSEMWAIT_FLAGS_NANOSECS            RT_BIT_32(2)
+/** The timeout is specified in milliseconds. */
+#define RTSEMWAIT_FLAGS_MILLISECS           RT_BIT_32(3)
+/** Indefinite wait.
+ * The relative/absolute and nano-/millisecond flags are ignored. */
+#define RTSEMWAIT_FLAGS_INDEFINITE          RT_BIT_32(4)
+/** Mask covering the time related bits. */
+#define RTSEMWAIT_FLAGS_TIME_MASK           UINT32_C(0x0000001f)
+
+/** Interruptible wait. */
+#define RTSEMWAIT_FLAGS_INTERRUPTIBLE       RT_BIT_32(5)
+/** No automatic resume, same as interruptible. */
+#define RTSEMWAIT_FLAGS_NORESUME            RTSEMWAIT_FLAGS_INTERRUPTIBLE
+/** Uninterruptible wait. */
+#define RTSEMWAIT_FLAGS_UNINTERRUPTIBLE     RT_BIT_32(6)
+/** Resume on interrupt, same as uninterruptible. */
+#define RTSEMWAIT_FLAGS_RESUME              RTSEMWAIT_FLAGS_UNINTERRUPTIBLE
+
+/** Macro for validate the flags. */
+#define RTSEMWAIT_FLAGS_ARE_VALID(fFlags) \
+    (   !((fFlags) & UINT32_C(0xffffff80)) \
+     &&  (  ((fFlags) & RTSEMWAIT_FLAGS_INDEFINITE) \
+          ? ( (((fFlags) & UINT32_C(0x20))) ^ (((fFlags) >> 1) & UINT32_C(0x20)) ) == UINT32_C(0x20) \
+          : ( (((fFlags) & UINT32_C(0x25))) ^ (((fFlags) >> 1) & UINT32_C(0x25)) ) == UINT32_C(0x25) ))
+/** @}  */
+
+
+
+/** @defgroup grp_rt_sems_event    RTSemEvent - Single Release Event Semaphores
+ *
+ * Event semaphores can be used for inter-thread communication when one thread
+ * wants to notify another thread that something happened.  A thread can block
+ * ("wait") on an event semaphore until it is signalled by another thread; see
+ * RTSemEventCreate, RTSemEventSignal and RTSemEventWait.
+ *
+ * @{ */
+
+/**
+ * Create an event semaphore.
+ *
+ * @returns iprt status code.
+ * @param   phEventSem          Where to store the handle to the newly created
+ *                              event semaphore.
+ */
+RTDECL(int)  RTSemEventCreate(PRTSEMEVENT phEventSem);
+
+/**
+ * Create an event semaphore.
+ *
+ * @returns iprt status code.
+ * @param   phEventSem          Where to store the handle to the newly created
+ *                              event semaphore.
+ * @param   fFlags              Flags, any combination of the
+ *                              RTSEMEVENT_FLAGS_XXX \#defines.
+ * @param   hClass              The class (no reference consumed).  Since we
+ *                              don't do order checks on event semaphores, the
+ *                              use of the class is limited to controlling the
+ *                              timeout threshold for deadlock detection.
+ * @param   pszNameFmt          Name format string for the lock validator,
+ *                              optional (NULL).  Max length is 32 bytes.
+ * @param   ...                 Format string arguments.
+ */
+RTDECL(int)  RTSemEventCreateEx(PRTSEMEVENT phEventSem, uint32_t fFlags, RTLOCKVALCLASS hClass,
+                                const char *pszNameFmt, ...) RT_IPRT_FORMAT_ATTR_MAYBE_NULL(4, 5);
+
+/** @name RTSemMutexCreateEx flags
+ * @{ */
+/** Disables lock validation. */
+#define RTSEMEVENT_FLAGS_NO_LOCK_VAL    UINT32_C(0x00000001)
+/** Bootstrap hack for use with certain memory allocator locks only! */
+#define RTSEMEVENT_FLAGS_BOOTSTRAP_HACK UINT32_C(0x00000004)
+/** @} */
+
+/**
+ * Destroy an event semaphore.
+ *
+ * @returns iprt status code.
+ * @param   hEventSem           Handle of the event semaphore.  NIL_RTSEMEVENT
+ *                              is quietly ignored (VINF_SUCCESS).
+ */
+RTDECL(int)  RTSemEventDestroy(RTSEMEVENT hEventSem);
+
+/**
+ * Signal an event semaphore.
+ *
+ * The event semaphore will be signaled and automatically reset after exactly
+ * one thread have successfully returned from RTSemEventWait() after
+ * waiting/polling on that semaphore.
+ *
+ * @returns iprt status code.
+ * @param   hEventSem           The event semaphore to signal.
+ *
+ * @remarks ring-0: This works when preemption is disabled.  However it is
+ *          system specific whether it works in interrupt context or with
+ *          interrupts disabled.
+ */
+RTDECL(int)  RTSemEventSignal(RTSEMEVENT hEventSem);
+
+/**
+ * Wait for the event semaphore to be signaled, resume on interruption.
+ *
+ * This function will resume if the wait is interrupted by an async system event
+ * (like a unix signal) or similar.
+ *
+ * @returns iprt status code.
+ *          Will not return VERR_INTERRUPTED.
+ * @param   hEventSem           The event semaphore to wait on.
+ * @param   cMillies            Number of milliseconds to wait.
+ */
+RTDECL(int)  RTSemEventWait(RTSEMEVENT hEventSem, RTMSINTERVAL cMillies);
+
+/**
+ * Wait for the event semaphore to be signaled, return on interruption.
+ *
+ * This function will not resume the wait if interrupted.
+ *
+ * @returns iprt status code.
+ * @param   hEventSem           The event semaphore to wait on.
+ * @param   cMillies            Number of milliseconds to wait.
+ */
+RTDECL(int)  RTSemEventWaitNoResume(RTSEMEVENT hEventSem, RTMSINTERVAL cMillies);
+
+/**
+ * Extended API for waiting on an event semaphore to be signaled.
+ *
+ * @returns IPRT status code.
+ * @param   hEventSem           The event semaphore to wait on.
+ * @param   fFlags              Combination of RTSEMWAIT_FLAGS_XXX.
+ * @param   uTimeout            The timeout, ignored if
+ *                              RTSEMWAIT_FLAGS_INDEFINITE is set in @a flags.
+ *                              Whether this is absolute or relative,
+ *                              milliseconds or nanoseconds depends on the @a
+ *                              fFlags value.  Do not pass RT_INDEFINITE_WAIT
+ *                              here, use RTSEMWAIT_FLAGS_INDEFINITE instead.
+ */
+RTDECL(int)  RTSemEventWaitEx(RTSEMEVENT hEventSem, uint32_t fFlags, uint64_t uTimeout);
+
+/**
+ * Debug version of RTSemEventWaitEx that tracks the location.
+ *
+ * @returns IPRT status code, see RTSemEventWaitEx.
+ * @param   hEventSem           The event semaphore to wait on.
+ * @param   fFlags              See RTSemEventWaitEx.
+ * @param   uTimeout            See RTSemEventWaitEx.
+ * @param   uId                 Some kind of locking location ID.  Typically a
+ *                              return address up the stack.  Optional (0).
+ * @param   SRC_POS             The source position where call is being made
+ *                              from.  Use RT_SRC_POS when possible.  Optional.
+ */
+RTDECL(int)  RTSemEventWaitExDebug(RTSEMEVENT hEventSem, uint32_t fFlags, uint64_t uTimeout,
+                                   RTHCUINTPTR uId, RT_SRC_POS_DECL);
+
+/**
+ * Gets the best timeout resolution that RTSemEventWaitEx can do.
+ *
+ * @returns The resolution in nanoseconds.
+ */
+RTDECL(uint32_t) RTSemEventGetResolution(void);
+
+/**
+ * Sets the signaller thread to one specific thread.
+ *
+ * This is only used for validating usage and deadlock detection.  When used
+ * after calls to RTSemEventAddSignaller, the specified thread will be the only
+ * signalling thread.
+ *
+ * @param   hEventSem           The event semaphore.
+ * @param   hThread             The thread that will signal it.  Pass
+ *                              NIL_RTTHREAD to indicate that there is no
+ *                              special signalling thread.
+ */
+RTDECL(void) RTSemEventSetSignaller(RTSEMEVENT hEventSem, RTTHREAD hThread);
+
+/**
+ * To add more signalling threads.
+ *
+ * First call RTSemEventSetSignaller then add further threads with this.
+ *
+ * @param   hEventSem           The event semaphore.
+ * @param   hThread             The thread that will signal it. NIL_RTTHREAD is
+ *                              not accepted.
+ */
+RTDECL(void) RTSemEventAddSignaller(RTSEMEVENT hEventSem, RTTHREAD hThread);
+
+/**
+ * To remove a signalling thread.
+ *
+ * Reverts work done by RTSemEventAddSignaller and RTSemEventSetSignaller.
+ *
+ * @param   hEventSem           The event semaphore.
+ * @param   hThread             A previously added thread.
+ */
+RTDECL(void) RTSemEventRemoveSignaller(RTSEMEVENT hEventSem, RTTHREAD hThread);
+
+/** @} */
+
+
+/** @defgroup grp_rt_sems_event_multi   RTSemEventMulti - Multiple Release Event Semaphores
+ *
+ * A variant of @ref  grp_rt_sems_event where all threads will be unblocked when
+ * signalling the semaphore.
+ *
+ * @{ */
+
+/**
+ * Creates a multiple release event semaphore.
+ *
+ * @returns iprt status code.
+ * @param   phEventMultiSem     Where to store the handle to the newly created
+ *                              multiple release event semaphore.
+ */
+RTDECL(int)  RTSemEventMultiCreate(PRTSEMEVENTMULTI phEventMultiSem);
+
+/**
+ * Creates a multiple release event semaphore.
+ *
+ * @returns iprt status code.
+ * @param   phEventMultiSem     Where to store the handle to the newly created
+ *                              multiple release event semaphore.
+ * @param   fFlags              Flags, any combination of the
+ *                              RTSEMEVENTMULTI_FLAGS_XXX \#defines.
+ * @param   hClass              The class (no reference consumed).  Since we
+ *                              don't do order checks on event semaphores, the
+ *                              use of the class is limited to controlling the
+ *                              timeout threshold for deadlock detection.
+ * @param   pszNameFmt          Name format string for the lock validator,
+ *                              optional (NULL).  Max length is 32 bytes.
+ * @param   ...                 Format string arguments.
+ */
+RTDECL(int)  RTSemEventMultiCreateEx(PRTSEMEVENTMULTI phEventMultiSem, uint32_t fFlags, RTLOCKVALCLASS hClass,
+                                     const char *pszNameFmt, ...) RT_IPRT_FORMAT_ATTR_MAYBE_NULL(4, 5);
+
+/** @name RTSemMutexCreateEx flags
+ * @{ */
+/** Disables lock validation. */
+#define RTSEMEVENTMULTI_FLAGS_NO_LOCK_VAL   UINT32_C(0x00000001)
+/** @} */
+
+/**
+ * Destroy an event multi semaphore.
+ *
+ * @returns iprt status code.
+ * @param   hEventMultiSem      The multiple release event semaphore.  NIL is
+ *                              quietly ignored (VINF_SUCCESS).
+ */
+RTDECL(int)  RTSemEventMultiDestroy(RTSEMEVENTMULTI hEventMultiSem);
+
+/**
+ * Signal an event multi semaphore.
+ *
+ * @returns iprt status code.
+ * @param   hEventMultiSem      The multiple release event semaphore.
+ *
+ * @remarks ring-0: This works when preemption is disabled.  However it is
+ *          system specific whether it works in interrupt context or with
+ *          interrupts disabled.
+ */
+RTDECL(int)  RTSemEventMultiSignal(RTSEMEVENTMULTI hEventMultiSem);
+
+/**
+ * Resets an event multi semaphore to non-signaled state.
+ *
+ * @returns iprt status code.
+ * @param   hEventMultiSem      The multiple release event semaphore.
+ */
+RTDECL(int)  RTSemEventMultiReset(RTSEMEVENTMULTI hEventMultiSem);
+
+/**
+ * Wait for the event multi semaphore to be signaled, resume on interruption.
+ *
+ * This function will resume if the wait is interrupted by an async
+ * system event (like a unix signal) or similar.
+ *
+ * @returns iprt status code.
+ *          Will not return VERR_INTERRUPTED.
+ * @param   hEventMultiSem      The multiple release event semaphore.
+ * @param   cMillies            Number of milliseconds to wait.
+ */
+RTDECL(int)  RTSemEventMultiWait(RTSEMEVENTMULTI hEventMultiSem, RTMSINTERVAL cMillies);
+
+/**
+ * Wait for the event multi semaphore to be signaled, return on interruption.
+ *
+ * This function will not resume the wait if interrupted.
+ *
+ * @returns iprt status code.
+ * @param   hEventMultiSem      The multiple release event semaphore.
+ * @param   cMillies            Number of milliseconds to wait.
+ * @todo    Rename to RTSemEventMultiWaitIntr since it is mainly for
+ *          ring-0 consumption.
+ */
+RTDECL(int)  RTSemEventMultiWaitNoResume(RTSEMEVENTMULTI hEventMultiSem, RTMSINTERVAL cMillies);
+
+/**
+ * Extended API for waiting on an event semaphore to be signaled.
+ *
+ * @returns IPRT status code.
+ * @param   hEventMultiSem      The multiple release event semaphore to wait
+ *                              on.
+ * @param   fFlags              Combination of the RTSEMWAIT_FLAGS_XXX.
+ * @param   uTimeout            The timeout, ignored if
+ *                              RTSEMWAIT_FLAGS_INDEFINITE is set in @a flags.
+ *                              Whether this is absolute or relative,
+ *                              milliseconds or nanoseconds depends on the @a
+ *                              fFlags value.  Do not pass RT_INDEFINITE_WAIT
+ *                              here, use RTSEMWAIT_FLAGS_INDEFINITE instead.
+ */
+RTDECL(int)  RTSemEventMultiWaitEx(RTSEMEVENTMULTI hEventMultiSem, uint32_t fFlags, uint64_t uTimeout);
+
+/**
+ * Debug version of RTSemEventMultiWaitEx that tracks the location.
+
+ * @returns IPRT status code, see RTSemEventMultiWaitEx.
+ * @param   hEventMultiSem      The multiple release event semaphore handle.
+ * @param   fFlags              See RTSemEventMultiWaitEx.
+ * @param   uTimeout            See RTSemEventMultiWaitEx.
+ * @param   uId                 Some kind of locking location ID.  Typically a
+ *                              return address up the stack.  Optional (0).
+ * @param   SRC_POS             The source position where call is being made
+ *                              from.  Use RT_SRC_POS when possible.  Optional.
+ */
+RTDECL(int)  RTSemEventMultiWaitExDebug(RTSEMEVENTMULTI hEventMultiSem, uint32_t fFlags, uint64_t uTimeout,
+                                        RTHCUINTPTR uId, RT_SRC_POS_DECL);
+
+/**
+ * Gets the best timeout resolution that RTSemEventMultiWaitEx can do.
+ *
+ * @returns The resolution in nanoseconds.
+ */
+RTDECL(uint32_t) RTSemEventMultiGetResolution(void);
+
+/**
+ * Sets the signaller thread to one specific thread.
+ *
+ * This is only used for validating usage and deadlock detection.  When used
+ * after calls to RTSemEventAddSignaller, the specified thread will be the only
+ * signalling thread.
+ *
+ * @param   hEventMultiSem      The multiple release event semaphore.
+ * @param   hThread             The thread that will signal it.  Pass
+ *                              NIL_RTTHREAD to indicate that there is no
+ *                              special signalling thread.
+ */
+RTDECL(void) RTSemEventMultiSetSignaller(RTSEMEVENTMULTI hEventMultiSem, RTTHREAD hThread);
+
+/**
+ * To add more signalling threads.
+ *
+ * First call RTSemEventSetSignaller then add further threads with this.
+ *
+ * @param   hEventMultiSem      The multiple release event semaphore.
+ * @param   hThread             The thread that will signal it. NIL_RTTHREAD is
+ *                              not accepted.
+ */
+RTDECL(void) RTSemEventMultiAddSignaller(RTSEMEVENTMULTI hEventMultiSem, RTTHREAD hThread);
+
+/**
+ * To remove a signalling thread.
+ *
+ * Reverts work done by RTSemEventAddSignaller and RTSemEventSetSignaller.
+ *
+ * @param   hEventMultiSem      The multiple release event semaphore.
+ * @param   hThread             A previously added thread.
+ */
+RTDECL(void) RTSemEventMultiRemoveSignaller(RTSEMEVENTMULTI hEventMultiSem, RTTHREAD hThread);
+
+/** @} */
+
+
+/** @defgroup grp_rt_sems_mutex     RTSemMutex - Mutex semaphores.
+ *
+ * Mutex semaphores protect a section of code or data to which access must be
+ * exclusive.  Only one thread can hold access to a critical section at one
+ * time.  See RTSemMutexCreate, RTSemMutexRequest and RTSemMutexRelease.
+ *
+ * @remarks These are less efficient than "fast mutexes" and "critical
+ *          sections", which IPRT implements as well; see @ref
+ *          grp_rt_sems_fast_mutex and @ref grp_rt_critsect .
+ *
+ * @{ */
+
+/**
+ * Create a mutex semaphore.
+ *
+ * @returns iprt status code.
+ * @param   phMutexSem      Where to store the mutex semaphore handle.
+ */
+RTDECL(int)  RTSemMutexCreate(PRTSEMMUTEX phMutexSem);
+
+/**
+ * Creates a read/write semaphore.
+ *
+ * @returns iprt status code.
+ * @param   phMutexSem          Where to store the handle to the newly created
+ *                              mutex semaphore.
+ * @param   fFlags              Flags, any combination of the
+ *                              RTSEMMUTEX_FLAGS_XXX \#defines.
+ * @param   hClass              The class (no reference consumed).  If NIL, no
+ *                              lock order validation will be performed on this
+ *                              lock.
+ * @param   uSubClass           The sub-class.  This is used to define lock
+ *                              order within a class.  RTLOCKVAL_SUB_CLASS_NONE
+ *                              is the recommended value here.
+ * @param   pszNameFmt          Name format string for the lock validator,
+ *                              optional (NULL).  Max length is 32 bytes.
+ * @param   ...                 Format string arguments.
+ */
+RTDECL(int) RTSemMutexCreateEx(PRTSEMMUTEX phMutexSem, uint32_t fFlags, RTLOCKVALCLASS hClass, uint32_t uSubClass,
+                               const char *pszNameFmt, ...) RT_IPRT_FORMAT_ATTR_MAYBE_NULL(5, 6);
+
+/** @name RTSemMutexCreateEx flags
+ * @{ */
+/** Disables lock validation. */
+#define RTSEMMUTEX_FLAGS_NO_LOCK_VAL    UINT32_C(0x00000001)
+/** @} */
+
+
+/**
+ * Destroy a mutex semaphore.
+ *
+ * @returns iprt status code.
+ * @param   hMutexSem           The mutex semaphore to destroy.  NIL is quietly
+ *                              ignored (VINF_SUCCESS).
+ */
+RTDECL(int)  RTSemMutexDestroy(RTSEMMUTEX hMutexSem);
+
+/**
+ * Changes the lock validator sub-class of the mutex semaphore.
+ *
+ * It is recommended to try make sure that nobody is using this semaphore while
+ * changing the value.
+ *
+ * @returns The old sub-class.  RTLOCKVAL_SUB_CLASS_INVALID is returns if the
+ *          lock validator isn't compiled in or either of the parameters are
+ *          invalid.
+ * @param   hMutexSem           The handle to the mutex semaphore.
+ * @param   uSubClass           The new sub-class value.
+ */
+RTDECL(uint32_t) RTSemMutexSetSubClass(RTSEMMUTEX hMutexSem, uint32_t uSubClass);
+
+/**
+ * Request ownership of a mutex semaphore, resume on interruption.
+ *
+ * This function will resume if the wait is interrupted by an async
+ * system event (like a unix signal) or similar.
+ *
+ * The same thread may request a mutex semaphore multiple times,
+ * a nested counter is kept to make sure it's released on the right
+ * RTSemMutexRelease() call.
+ *
+ * @returns iprt status code.
+ *          Will not return VERR_INTERRUPTED.
+ * @param   hMutexSem           The mutex semaphore to request ownership over.
+ * @param   cMillies            The number of milliseconds to wait.
+ */
+RTDECL(int)  RTSemMutexRequest(RTSEMMUTEX hMutexSem, RTMSINTERVAL cMillies);
+
+/**
+ * Request ownership of a mutex semaphore, return on interruption.
+ *
+ * This function will not resume the wait if interrupted.
+ *
+ * The same thread may request a mutex semaphore multiple times,
+ * a nested counter is kept to make sure it's released on the right
+ * RTSemMutexRelease() call.
+ *
+ * @returns iprt status code.
+ * @param   hMutexSem           The mutex semaphore to request ownership over.
+ * @param   cMillies            The number of milliseconds to wait.
+ */
+RTDECL(int)  RTSemMutexRequestNoResume(RTSEMMUTEX hMutexSem, RTMSINTERVAL cMillies);
+
+/**
+ * Debug version of RTSemMutexRequest that tracks the location.
+ *
+ * @returns iprt status code.
+ *          Will not return VERR_INTERRUPTED.
+ * @param   hMutexSem           The mutex semaphore to request ownership over.
+ * @param   cMillies            The number of milliseconds to wait.
+ * @param   uId                 Some kind of locking location ID.  Typically a
+ *                              return address up the stack.  Optional (0).
+ * @param   SRC_POS             The source position where call is being made
+ *                              from.  Use RT_SRC_POS when possible.  Optional.
+ */
+RTDECL(int)  RTSemMutexRequestDebug(RTSEMMUTEX hMutexSem, RTMSINTERVAL cMillies, RTHCUINTPTR uId, RT_SRC_POS_DECL);
+
+/**
+ * Debug version of RTSemMutexRequestNoResume that tracks the location.
+ *
+ * @returns iprt status code.
+ * @param   hMutexSem           The mutex semaphore to request ownership over.
+ * @param   cMillies            The number of milliseconds to wait.
+ * @param   uId                 Some kind of locking location ID.  Typically a
+ *                              return address up the stack.  Optional (0).
+ * @param   SRC_POS             The source position where call is being made
+ *                              from.  Use RT_SRC_POS when possible.  Optional.
+ */
+RTDECL(int)  RTSemMutexRequestNoResumeDebug(RTSEMMUTEX hMutexSem, RTMSINTERVAL cMillies, RTHCUINTPTR uId, RT_SRC_POS_DECL);
+
+/**
+ * Request ownership of a mutex semaphore, extended edition.
+ *
+ * The same thread may request a mutex semaphore multiple times,
+ * a nested counter is kept to make sure it's released on the right
+ * RTSemMutexRelease() call.
+ *
+ * @returns iprt status code.
+ * @param   hMutexSem           The mutex semaphore to request ownership over.
+ * @param   fFlags              Combination of the RTSEMWAIT_FLAGS_XXX.
+ * @param   uTimeout            The timeout, ignored if
+ *                              RTSEMWAIT_FLAGS_INDEFINITE is set in @a flags.
+ *                              Whether this is absolute or relative,
+ *                              milliseconds or nanoseconds depends on the @a
+ *                              fFlags value.  Do not pass RT_INDEFINITE_WAIT
+ *                              here, use RTSEMWAIT_FLAGS_INDEFINITE instead.
+ */
+RTDECL(int)  RTSemMutexRequestEx(RTSEMMUTEX hMutexSem, uint32_t fFlags, uint64_t uTimeout);
+
+/**
+ * Debug version of RTSemMutexRequestEx that tracks the location.
+ *
+ * @returns iprt status code.
+ * @param   hMutexSem           The mutex semaphore to request ownership over.
+ * @param   fFlags              See RTSemMutexRequestEx.
+ * @param   uTimeout            See RTSemMutexRequestEx.
+ * @param   uId                 Some kind of locking location ID.  Typically a
+ *                              return address up the stack.  Optional (0).
+ * @param   SRC_POS             The source position where call is being made
+ *                              from.  Use RT_SRC_POS when possible.  Optional.
+ */
+RTDECL(int)  RTSemMutexRequestExDebug(RTSEMMUTEX hMutexSem, uint32_t fFlags, uint64_t uTimeout,
+                                      RTHCUINTPTR uId, RT_SRC_POS_DECL);
+
+/**
+ * Release the ownership of a mutex semaphore.
+ *
+ * @returns iprt status code.
+ * @param   hMutexSem           The mutex to release the ownership of.  It goes
+ *                              without saying the the calling thread must own
+ *                              it.
+ */
+RTDECL(int)  RTSemMutexRelease(RTSEMMUTEX hMutexSem);
+
+/**
+ * Checks if the mutex semaphore is owned or not.
+ *
+ * @returns true if owned, false if not.
+ * @param   hMutexSem           The mutex semaphore.
+ */
+RTDECL(bool) RTSemMutexIsOwned(RTSEMMUTEX hMutexSem);
+
+/* Strict build: Remap the two request calls to the debug versions. */
+#if   defined(RT_STRICT) && !defined(RTSEMMUTEX_WITHOUT_REMAPPING) && !defined(RT_WITH_MANGLING)
+# ifdef ___iprt_asm_h
+#  define RTSemMutexRequest(hMutexSem, cMillies)            RTSemMutexRequestDebug((hMutexSem), (cMillies), (uintptr_t)ASMReturnAddress(), RT_SRC_POS)
+#  define RTSemMutexRequestNoResume(hMutexSem, cMillies)    RTSemMutexRequestNoResumeDebug((hMutexSem), (cMillies), (uintptr_t)ASMReturnAddress(), RT_SRC_POS)
+#  define RTSemMutexRequestEx(hMutexSem, fFlags, uTimeout)  RTSemMutexRequestExDebug((hMutexSem), (fFlags), (uTimeout), (uintptr_t)ASMReturnAddress(), RT_SRC_POS)
+# else
+#  define RTSemMutexRequest(hMutexSem, cMillies)            RTSemMutexRequestDebug((hMutexSem), (cMillies), 0, RT_SRC_POS)
+#  define RTSemMutexRequestNoResume(hMutexSem, cMillies)    RTSemMutexRequestNoResumeDebug((hMutexSem), (cMillies), 0, RT_SRC_POS)
+#  define RTSemMutexRequestEx(hMutexSem, fFlags, uTimeout)  RTSemMutexRequestExDebug((hMutexSem), (fFlags), (uTimeout), 0, RT_SRC_POS)
+# endif
+#endif
+
+/* Strict lock order: Automatically classify locks by init location. */
+#if   defined(RT_LOCK_STRICT_ORDER) && defined(IN_RING3) && !defined(RTSEMMUTEX_WITHOUT_REMAPPING) && !defined(RT_WITH_MANGLING)
+# define RTSemMutexCreate(phMutexSem) \
+    RTSemMutexCreateEx((phMutexSem), 0 /*fFlags*/, \
+                       RTLockValidatorClassForSrcPos(RT_SRC_POS, NULL), \
+                       RTLOCKVAL_SUB_CLASS_NONE, NULL)
+#endif
+
+/** @} */
+
+
+/** @defgroup grp_rt_sems_fast_mutex    RTSemFastMutex - Fast Mutex Semaphores
+ *
+ * Fast mutexes work like regular mutexes in that they allow only a single
+ * thread access to a critical piece of code or data.  As opposed to mutexes,
+ * they require no syscall if the fast mutex is not held (like critical
+ * sections).  Unlike critical sections however, they are *not* recursive.
+ *
+ * @remarks The fast mutexes has sideeffects on IRQL on Windows hosts.  So use
+ *          with care and test on windows with driver verifier.
+ *
+ * @{ */
+
+/**
+ * Create a fast mutex semaphore.
+ *
+ * @returns iprt status code.
+ * @param   phFastMtx           Where to store the handle to the newly created
+ *                              fast mutex semaphore.
+ *
+ * @remarks Fast mutex semaphores are not recursive.
+ */
+RTDECL(int)  RTSemFastMutexCreate(PRTSEMFASTMUTEX phFastMtx);
+
+/**
+ * Destroy a fast mutex semaphore.
+ *
+ * @returns iprt status code.
+ * @param   hFastMtx            Handle to the fast mutex semaphore.  NIL is
+ *                              quietly ignored (VINF_SUCCESS).
+ */
+RTDECL(int)  RTSemFastMutexDestroy(RTSEMFASTMUTEX hFastMtx);
+
+/**
+ * Request ownership of a fast mutex semaphore.
+ *
+ * The same thread may request a mutex semaphore multiple times,
+ * a nested counter is kept to make sure it's released on the right
+ * RTSemMutexRelease() call.
+ *
+ * @returns iprt status code.
+ * @param   hFastMtx            Handle to the fast mutex semaphore.
+ */
+RTDECL(int)  RTSemFastMutexRequest(RTSEMFASTMUTEX hFastMtx);
+
+/**
+ * Release the ownership of a fast mutex semaphore.
+ *
+ * @returns iprt status code.
+ * @param   hFastMtx            Handle to the fast mutex semaphore.  It goes
+ *                              without saying the the calling thread must own
+ *                              it.
+ */
+RTDECL(int)  RTSemFastMutexRelease(RTSEMFASTMUTEX hFastMtx);
+
+/** @} */
+
+
+/** @defgroup grp_rt_sems_spin_mutex RTSemSpinMutex - Spinning Mutex Semaphores
+ *
+ * A very adaptive variant of mutex semaphore that is tailored for the ring-0
+ * logger.
+ *
+ * @{ */
+
+/**
+ * Creates a spinning mutex semaphore.
+ *
+ * @returns iprt status code.
+ * @retval  VERR_INVALID_PARAMETER on invalid flags.
+ * @retval  VERR_NO_MEMORY if out of memory for the semaphore structure and
+ *          handle.
+ *
+ * @param   phSpinMtx   Where to return the handle to the create semaphore.
+ * @param   fFlags      Flags, see RTSEMSPINMUTEX_FLAGS_XXX.
+ */
+RTDECL(int) RTSemSpinMutexCreate(PRTSEMSPINMUTEX phSpinMtx, uint32_t fFlags);
+
+/** @name RTSemSpinMutexCreate flags.
+ * @{ */
+/** Always take the semaphore in a IRQ safe way.
+ * (In plain words: always disable interrupts.) */
+#define RTSEMSPINMUTEX_FLAGS_IRQ_SAFE       RT_BIT_32(0)
+/** Mask of valid flags. */
+#define RTSEMSPINMUTEX_FLAGS_VALID_MASK     UINT32_C(0x00000001)
+/** @} */
+
+/**
+ * Destroys a spinning mutex semaphore.
+ *
+ * @returns iprt status code.
+ * @retval  VERR_INVALID_HANDLE (or crash) if the handle is invalid. (NIL will
+ *          not cause this status.)
+ *
+ * @param   hSpinMtx    The semaphore handle. NIL_RTSEMSPINMUTEX is ignored
+ *                      quietly (VINF_SUCCESS).
+ */
+RTDECL(int) RTSemSpinMutexDestroy(RTSEMSPINMUTEX hSpinMtx);
+
+/**
+ * Request the spinning mutex semaphore.
+ *
+ * This may block if the context we're called in allows this. If not it will
+ * spin. If called in an interrupt context, we will only spin if the current
+ * owner isn't interrupted. Also, on some systems it is not always possible to
+ * wake up blocking threads in all contexts, so, which will either be indicated
+ * by returning VERR_SEM_BAD_CONTEXT or by temporarily switching the semaphore
+ * into pure spinlock state.
+ *
+ * Preemption will be disabled upon return. IRQs may also be disabled.
+ *
+ * @returns iprt status code.
+ * @retval  VERR_SEM_BAD_CONTEXT if the context it's called in isn't suitable
+ *          for releasing it if someone is sleeping on it.
+ * @retval  VERR_SEM_DESTROYED if destroyed.
+ * @retval  VERR_SEM_NESTED if held by the caller. Asserted.
+ * @retval  VERR_INVALID_HANDLE if the handle is invalid. Asserted
+ *
+ * @param   hSpinMtx    The semaphore handle.
+ */
+RTDECL(int) RTSemSpinMutexRequest(RTSEMSPINMUTEX hSpinMtx);
+
+/**
+ * Like RTSemSpinMutexRequest but it won't block or spin if the semaphore is
+ * held by someone else.
+ *
+ * @returns iprt status code.
+ * @retval  VERR_SEM_BUSY if held by someone else.
+ * @retval  VERR_SEM_DESTROYED if destroyed.
+ * @retval  VERR_SEM_NESTED if held by the caller. Asserted.
+ * @retval  VERR_INVALID_HANDLE if the handle is invalid. Asserted
+ *
+ * @param   hSpinMtx    The semaphore handle.
+ */
+RTDECL(int) RTSemSpinMutexTryRequest(RTSEMSPINMUTEX hSpinMtx);
+
+/**
+ * Releases the semaphore previously acquired by RTSemSpinMutexRequest or
+ * RTSemSpinMutexTryRequest.
+ *
+ * @returns iprt status code.
+ * @retval  VERR_SEM_DESTROYED if destroyed.
+ * @retval  VERR_NOT_OWNER if not owner. Asserted.
+ * @retval  VERR_INVALID_HANDLE if the handle is invalid. Asserted.
+ *
+ * @param   hSpinMtx    The semaphore handle.
+ */
+RTDECL(int) RTSemSpinMutexRelease(RTSEMSPINMUTEX hSpinMtx);
+
+/** @} */
+
+
+/** @defgroup grp_rt_sem_rw             RTSemRW - Read / Write Semaphores
+ *
+ * Read/write semaphores are a fancier version of mutexes in that they grant
+ * read access to the protected data to several threads at the same time but
+ * allow only one writer at a time.  This can make code scale better at the
+ * expense of slightly more overhead in mutex management.
+ *
+ * @{ */
+
+/**
+ * Creates a read/write semaphore.
+ *
+ * @returns iprt status code.
+ * @param   phRWSem             Where to store the handle to the newly created
+ *                              RW semaphore.
+ */
+RTDECL(int)   RTSemRWCreate(PRTSEMRW phRWSem);
+
+/**
+ * Creates a read/write semaphore.
+ *
+ * @returns iprt status code.
+ * @param   phRWSem             Where to store the handle to the newly created
+ *                              RW semaphore.
+ * @param   fFlags              Flags, any combination of the RTSEMRW_FLAGS_XXX
+ *                              \#defines.
+ * @param   hClass              The class (no reference consumed).  If NIL, no
+ *                              lock order validation will be performed on this
+ *                              lock.
+ * @param   uSubClass           The sub-class.  This is used to define lock
+ *                              order within a class.  RTLOCKVAL_SUB_CLASS_NONE
+ *                              is the recommended value here.
+ * @param   pszNameFmt          Name format string for the lock validator,
+ *                              optional (NULL).  Max length is 32 bytes.
+ * @param   ...                 Format string arguments.
+ */
+RTDECL(int)   RTSemRWCreateEx(PRTSEMRW phRWSem, uint32_t fFlags, RTLOCKVALCLASS hClass, uint32_t uSubClass,
+                              const char *pszNameFmt, ...) RT_IPRT_FORMAT_ATTR_MAYBE_NULL(5, 6);
+
+/** @name RTSemRWCreateEx flags
+ * @{ */
+/** Disables lock validation. */
+#define RTSEMRW_FLAGS_NO_LOCK_VAL   UINT32_C(0x00000001)
+/** @} */
+
+/**
+ * Destroys a read/write semaphore.
+ *
+ * @returns iprt status code.
+ * @param   hRWSem              Handle to the read/write semaphore.  NIL is
+ *                              quietly ignored (VINF_SUCCESS).
+ */
+RTDECL(int)   RTSemRWDestroy(RTSEMRW hRWSem);
+
+/**
+ * Changes the lock validator sub-class of the read/write semaphore.
+ *
+ * It is recommended to try make sure that nobody is using this semaphore while
+ * changing the value.
+ *
+ * @returns The old sub-class.  RTLOCKVAL_SUB_CLASS_INVALID is returns if the
+ *          lock validator isn't compiled in or either of the parameters are
+ *          invalid.
+ * @param   hRWSem              Handle to the read/write semaphore.
+ * @param   uSubClass           The new sub-class value.
+ */
+RTDECL(uint32_t) RTSemRWSetSubClass(RTSEMRW hRWSem, uint32_t uSubClass);
+
+/**
+ * Request read access to a read/write semaphore, resume on interruption
+ *
+ * @returns iprt status code.
+ * @retval  VINF_SUCCESS on success.
+ * @retval  VERR_INTERRUPT if the wait was interrupted.
+ * @retval  VERR_INVALID_HANDLE if hRWSem is invalid.
+ *
+ * @param   hRWSem              Handle to the read/write semaphore.
+ * @param   cMillies            The number of milliseconds to wait.
+ */
+RTDECL(int)   RTSemRWRequestRead(RTSEMRW hRWSem, RTMSINTERVAL cMillies);
+
+/**
+ * Request read access to a read/write semaphore, return on interruption
+ *
+ * @returns iprt status code.
+ * @retval  VINF_SUCCESS on success.
+ * @retval  VERR_INTERRUPT if the wait was interrupted.
+ * @retval  VERR_INVALID_HANDLE if hRWSem is invalid.
+ *
+ * @param   hRWSem              Handle to the read/write semaphore.
+ * @param   cMillies            The number of milliseconds to wait.
+ */
+RTDECL(int)   RTSemRWRequestReadNoResume(RTSEMRW hRWSem, RTMSINTERVAL cMillies);
+
+/**
+ * Debug version of RTSemRWRequestRead that tracks the location.
+ *
+ * @returns iprt status code.
+ * @retval  VINF_SUCCESS on success.
+ * @retval  VERR_INTERRUPT if the wait was interrupted.
+ * @retval  VERR_INVALID_HANDLE if hRWSem is invalid.
+ *
+ * @param   hRWSem              Handle to the read/write semaphore.
+ * @param   cMillies            The number of milliseconds to wait.
+ * @param   uId                 Some kind of locking location ID.  Typically a
+ *                              return address up the stack.  Optional (0).
+ * @param   SRC_POS             The source position where call is being made
+ *                              from.  Use RT_SRC_POS when possible.  Optional.
+ */
+RTDECL(int)   RTSemRWRequestReadDebug(RTSEMRW hRWSem, RTMSINTERVAL cMillies, RTHCUINTPTR uId, RT_SRC_POS_DECL);
+
+/**
+ * Debug version of RTSemRWRequestWriteNoResume that tracks the location.
+ *
+ * @returns iprt status code.
+ * @retval  VINF_SUCCESS on success.
+ * @retval  VERR_INTERRUPT if the wait was interrupted.
+ * @retval  VERR_INVALID_HANDLE if hRWSem is invalid.
+ *
+ * @param   hRWSem              Handle to the read/write semaphore.
+ * @param   cMillies            The number of milliseconds to wait.
+ * @param   uId                 Some kind of locking location ID.  Typically a
+ *                              return address up the stack.  Optional (0).
+ * @param   SRC_POS             The source position where call is being made
+ *                              from.  Use RT_SRC_POS when possible.  Optional.
+ */
+RTDECL(int)   RTSemRWRequestReadNoResumeDebug(RTSEMRW hRWSem, RTMSINTERVAL cMillies, RTHCUINTPTR uId, RT_SRC_POS_DECL);
+
+/**
+ * Request read access to a read/write semaphore, extended edition.
+ *
+ * @returns iprt status code.
+ * @retval  VINF_SUCCESS on success.
+ * @retval  VERR_INTERRUPT if the wait was interrupted.
+ * @retval  VERR_TIMEOUT if the wait timed out.
+ * @retval  VERR_INVALID_HANDLE if hRWSem is invalid.
+ *
+ * @param   hRWSem              Handle to the read/write semaphore.
+ * @param   fFlags              Combination of the RTSEMWAIT_FLAGS_XXX.
+ * @param   uTimeout            The timeout, ignored if
+ *                              RTSEMWAIT_FLAGS_INDEFINITE is set in @a flags.
+ *                              Whether this is absolute or relative,
+ *                              milliseconds or nanoseconds depends on the @a
+ *                              fFlags value.  Do not pass RT_INDEFINITE_WAIT
+ *                              here, use RTSEMWAIT_FLAGS_INDEFINITE instead.
+ */
+RTDECL(int)   RTSemRWRequestReadEx(RTSEMRW hRWSem, uint32_t fFlags, uint64_t uTimeout);
+
+
+/**
+ * Debug version of RTSemRWRequestReadEx that tracks the location.
+ *
+ * @returns iprt status code.
+ * @retval  VINF_SUCCESS on success.
+ * @retval  VERR_INTERRUPT if the wait was interrupted.
+ * @retval  VERR_TIMEOUT if the wait timed out.
+ * @retval  VERR_INVALID_HANDLE if hRWSem is invalid.
+ *
+ * @param   hRWSem              Handle to the read/write semaphore.
+ * @param   fFlags              See RTSemRWRequestReadEx.
+ * @param   uTimeout            See RTSemRWRequestReadEx.
+ * @param   uId                 Some kind of locking location ID.  Typically a
+ *                              return address up the stack.  Optional (0).
+ * @param   SRC_POS             The source position where call is being made
+ *                              from.  Use RT_SRC_POS when possible.  Optional.
+ */
+RTDECL(int)   RTSemRWRequestReadExDebug(RTSEMRW hRWSem, uint32_t fFlags, uint64_t uTimeout,
+                                        RTHCUINTPTR uId, RT_SRC_POS_DECL);
+
+/**
+ * Release read access to a read/write semaphore.
+ *
+ * @returns iprt status code.
+ * @param   hRWSem              Handle to the read/write semaphore.  It goes
+ *                              without saying that caller must own read
+ *                              privileges to the semaphore.
+ */
+RTDECL(int)   RTSemRWReleaseRead(RTSEMRW hRWSem);
+
+/**
+ * Request write access to a read/write semaphore, resume on interruption.
+ *
+ * @returns iprt status code.
+ * @retval  VINF_SUCCESS on success.
+ * @retval  VERR_DEADLOCK if the caller owned the read lock.
+ * @retval  VERR_INVALID_HANDLE if hRWSem is invalid.
+ *
+ * @param   hRWSem              Handle to the read/write semaphore.
+ * @param   cMillies            The number of milliseconds to wait.
+ */
+RTDECL(int)   RTSemRWRequestWrite(RTSEMRW hRWSem, RTMSINTERVAL cMillies);
+
+/**
+ * Request write access to a read/write semaphore, return on interruption.
+ *
+ * @returns iprt status code.
+ * @retval  VINF_SUCCESS on success.
+ * @retval  VERR_INTERRUPT if the wait was interrupted.
+ * @retval  VERR_DEADLOCK if the caller owned the read lock.
+ * @retval  VERR_INVALID_HANDLE if hRWSem is invalid.
+ *
+ * @param   hRWSem              Handle to the read/write semaphore.
+ * @param   cMillies            The number of milliseconds to wait.
+ */
+RTDECL(int)   RTSemRWRequestWriteNoResume(RTSEMRW hRWSem, RTMSINTERVAL cMillies);
+
+/**
+ * Debug version of RTSemRWRequestWrite that tracks the location.
+ *
+ * @returns IPRT status code, see RTSemRWRequestWrite.
+ * @param   hRWSem              Handle to the read/write semaphore.
+ * @param   cMillies            The number of milliseconds to wait.
+ * @param   uId                 Some kind of locking location ID.  Typically a
+ *                              return address up the stack.  Optional (0).
+ * @param   SRC_POS             The source position where call is being made
+ *                              from.  Use RT_SRC_POS when possible.  Optional.
+ */
+RTDECL(int)  RTSemRWRequestWriteDebug(RTSEMRW hRWSem, RTMSINTERVAL cMillies, RTHCUINTPTR uId, RT_SRC_POS_DECL);
+
+/**
+ * Debug version of RTSemRWRequestWriteNoResume that tracks the location.
+ *
+ * @returns IPRT status code, see RTSemRWRequestWriteNoResume.
+ * @param   hRWSem              Handle to the read/write semaphore.
+ * @param   cMillies            The number of milliseconds to wait.
+ * @param   uId                 Some kind of locking location ID.  Typically a
+ *                              return address up the stack.  Optional (0).
+ * @param   SRC_POS             The source position where call is being made
+ *                              from.  Use RT_SRC_POS when possible.  Optional.
+ */
+RTDECL(int)  RTSemRWRequestWriteNoResumeDebug(RTSEMRW hRWSem, RTMSINTERVAL cMillies, RTHCUINTPTR uId, RT_SRC_POS_DECL);
+
+/**
+ * Request write access to a read/write semaphore, extended edition.
+ *
+ * @returns iprt status code.
+ * @retval  VINF_SUCCESS on success.
+ * @retval  VERR_INTERRUPTED if the wait was interrupted.
+ * @retval  VERR_TIMEOUT if the wait timed out.
+ * @retval  VERR_DEADLOCK if the caller owned the read lock.  Do not depend on
+ *          this as it is implementation specific.
+ * @retval  VERR_INVALID_HANDLE if hRWSem is invalid.
+ *
+ * @param   hRWSem              Handle to the read/write semaphore.
+ * @param   fFlags              Combination of the RTSEMWAIT_FLAGS_XXX.
+ * @param   uTimeout            The timeout, ignored if
+ *                              RTSEMWAIT_FLAGS_INDEFINITE is set in @a flags.
+ *                              Whether this is absolute or relative,
+ *                              milliseconds or nanoseconds depends on the @a
+ *                              fFlags value.  Do not pass RT_INDEFINITE_WAIT
+ *                              here, use RTSEMWAIT_FLAGS_INDEFINITE instead.
+ */
+RTDECL(int)   RTSemRWRequestWriteEx(RTSEMRW hRWSem, uint32_t fFlags, uint64_t uTimeout);
+
+/**
+ * Debug version of RTSemRWRequestWriteEx that tracks the location.
+ *
+ * @returns IPRT status code, see RTSemRWRequestWriteEx.
+ * @param   hRWSem              Handle to the read/write semaphore.
+ * @param   fFlags              See RTSemRWRequestWriteEx.
+ * @param   uTimeout            See RTSemRWRequestWriteEx.
+ * @param   uId                 Some kind of locking location ID.  Typically a
+ *                              return address up the stack.  Optional (0).
+ * @param   SRC_POS             The source position where call is being made
+ *                              from.  Use RT_SRC_POS when possible.  Optional.
+ */
+RTDECL(int)  RTSemRWRequestWriteExDebug(RTSEMRW hRWSem, uint32_t fFlags, uint64_t uTimeout,
+                                        RTHCUINTPTR uId, RT_SRC_POS_DECL);
+
+/**
+ * Release write access to a read/write semaphore.
+ *
+ * @returns iprt status code.
+ * @param   hRWSem              Handle to the read/write semaphore.  Goes
+ *                              without saying that caller must have write
+ *                              access to the semaphore.
+ */
+RTDECL(int)   RTSemRWReleaseWrite(RTSEMRW hRWSem);
+
+/**
+ * Checks if the caller is the exclusive semaphore owner.
+ *
+ * @returns true / false accoringly.
+ * @param   hRWSem              Handle to the read/write semaphore.
+ */
+RTDECL(bool)  RTSemRWIsWriteOwner(RTSEMRW hRWSem);
+
+/**
+ * Checks if the caller is one of the read owners of the semaphore.
+ *
+ * @note    !CAUTION!  This API doesn't work reliably if lock validation isn't
+ *          enabled. Meaning, the answer is not trustworhty unless
+ *          RT_LOCK_STRICT or RTSEMRW_STRICT was defined at build time.  Also,
+ *          make sure you do not use RTSEMRW_FLAGS_NO_LOCK_VAL when creating
+ *          the semaphore.  And finally, if you used a locking class, don't
+ *          disable deadlock detection by setting cMsMinDeadlock to
+ *          RT_INDEFINITE_WAIT.
+ *
+ *          In short, only use this for assertions.
+ *
+ * @returns true if reader, false if not.
+ * @param   hRWSem              Handle to the read/write semaphore.
+ * @param   fWannaHear          What you'd like to hear when lock validation is
+ *                              not available.  (For avoiding asserting all over
+ *                              the place.)
+ */
+RTDECL(bool)  RTSemRWIsReadOwner(RTSEMRW hRWSem, bool fWannaHear);
+
+/**
+ * Gets the write recursion count.
+ *
+ * @returns The write recursion count (0 if bad semaphore handle).
+ * @param   hRWSem              Handle to the read/write semaphore.
+ */
+RTDECL(uint32_t) RTSemRWGetWriteRecursion(RTSEMRW hRWSem);
+
+/**
+ * Gets the read recursion count of the current writer.
+ *
+ * @returns The read recursion count (0 if bad semaphore handle).
+ * @param   hRWSem              Handle to the read/write semaphore.
+ */
+RTDECL(uint32_t) RTSemRWGetWriterReadRecursion(RTSEMRW hRWSem);
+
+/**
+ * Gets the current number of reads.
+ *
+ * This includes all read recursions, so it might be higher than the number of
+ * read owners.  It does not include reads done by the current writer.
+ *
+ * @returns The read count (0 if bad semaphore handle).
+ * @param   hRWSem              Handle to the read/write semaphore.
+ */
+RTDECL(uint32_t) RTSemRWGetReadCount(RTSEMRW hRWSem);
+
+/* Strict build: Remap the four request calls to the debug versions. */
+#if defined(RT_STRICT) && !defined(RTSEMRW_WITHOUT_REMAPPING) && !defined(RT_WITH_MANGLING)
+# ifdef ___iprt_asm_h
+#  define RTSemRWRequestRead(hRWSem, cMillies)              RTSemRWRequestReadDebug((hRWSem), (cMillies), (uintptr_t)ASMReturnAddress(), RT_SRC_POS)
+#  define RTSemRWRequestReadNoResume(hRWSem, cMillies)      RTSemRWRequestReadNoResumeDebug((hRWSem), (cMillies), (uintptr_t)ASMReturnAddress(), RT_SRC_POS)
+#  define RTSemRWRequestWrite(hRWSem, cMillies)             RTSemRWRequestWriteDebug((hRWSem), (cMillies), (uintptr_t)ASMReturnAddress(), RT_SRC_POS)
+#  define RTSemRWRequestWriteNoResume(hRWSem, cMillies)     RTSemRWRequestWriteNoResumeDebug((hRWSem), (cMillies), (uintptr_t)ASMReturnAddress(), RT_SRC_POS)
+#  define RTSemRWRequestWriteEx(hRWSem, fFlags, uTimeout)   RTSemRWRequestWriteExDebug((hRWSem), (fFlags), (uTimeout), (uintptr_t)ASMReturnAddress(), RT_SRC_POS)
+# else
+#  define RTSemRWRequestRead(hRWSem, cMillies)              RTSemRWRequestReadDebug((hRWSem), (cMillies), 0, RT_SRC_POS)
+#  define RTSemRWRequestReadNoResume(hRWSem, cMillies)      RTSemRWRequestReadNoResumeDebug((hRWSem), (cMillies), 0, RT_SRC_POS)
+#  define RTSemRWRequestWrite(hRWSem, cMillies)             RTSemRWRequestWriteDebug((hRWSem), (cMillies), 0, RT_SRC_POS)
+#  define RTSemRWRequestWriteNoResume(hRWSem, cMillies)     RTSemRWRequestWriteNoResumeDebug((hRWSem), (cMillies), 0, RT_SRC_POS)
+#  define RTSemRWRequestWriteEx(hRWSem, fFlags, uTimeout)   RTSemRWRequestWriteExDebug((hRWSem), (fFlags), (uTimeout), 0, RT_SRC_POS)
+# endif
+#endif
+
+/* Strict lock order: Automatically classify locks by init location. */
+#if defined(RT_LOCK_STRICT_ORDER) && defined(IN_RING3) && !defined(RTSEMRW_WITHOUT_REMAPPING) && !defined(RT_WITH_MANGLING)
+# define RTSemRWCreate(phSemRW) \
+    RTSemRWCreateEx((phSemRW), 0 /*fFlags*/, \
+                    RTLockValidatorClassForSrcPos(RT_SRC_POS, NULL), \
+                    RTLOCKVAL_SUB_CLASS_NONE, NULL)
+#endif
+
+/** @} */
+
+
+/** @defgroup grp_rt_sems_pingpong      RTSemPingPong - Ping-Pong Construct
+ *
+ * Serialization of a two way communication.
+ *
+ * @{ */
+
+/**
+ * Ping-pong speaker
+ */
+typedef enum RTPINGPONGSPEAKER
+{
+    /** Not initialized. */
+    RTPINGPONGSPEAKER_UNINITIALIZE = 0,
+    /** Ping is speaking, Pong is waiting. */
+    RTPINGPONGSPEAKER_PING,
+    /** Pong is signaled, Ping is waiting. */
+    RTPINGPONGSPEAKER_PONG_SIGNALED,
+    /** Pong is speaking, Ping is waiting. */
+    RTPINGPONGSPEAKER_PONG,
+    /** Ping is signaled, Pong is waiting. */
+    RTPINGPONGSPEAKER_PING_SIGNALED,
+    /** Hack to ensure that it's at least 32-bits wide. */
+    RTPINGPONGSPEAKER_HACK = 0x7fffffff
+} RTPINGPONGSPEAKER;
+
+/**
+ * Ping-Pong construct.
+ *
+ * Two threads, one saying Ping and the other saying Pong. The construct
+ * makes sure they don't speak out of turn and that they can wait and poll
+ * on the conversation.
+ */
+typedef struct RTPINGPONG
+{
+    /** The semaphore the Ping thread waits on. */
+    RTSEMEVENT                  Ping;
+    /** The semaphore the Pong thread waits on. */
+    RTSEMEVENT                  Pong;
+    /** The current speaker. */
+    volatile RTPINGPONGSPEAKER  enmSpeaker;
+#if HC_ARCH_BITS == 64
+    /** Padding the structure to become a multiple of sizeof(RTHCPTR). */
+    uint32_t                    u32Padding;
+#endif
+} RTPINGPONG;
+/** Pointer to Ping-Pong construct. */
+typedef RTPINGPONG *PRTPINGPONG;
+
+/**
+ * Init a Ping-Pong construct.
+ *
+ * @returns iprt status code.
+ * @param   pPP         Pointer to the ping-pong structure which needs initialization.
+ */
+RTDECL(int) RTSemPingPongInit(PRTPINGPONG pPP);
+
+/**
+ * Deletes a Ping-Pong construct.
+ *
+ * @returns iprt status code.
+ * @param   pPP         Pointer to the ping-pong structure which is to be destroyed.
+ *                      (I.e. put into uninitialized state.)
+ */
+RTDECL(int) RTSemPingPongDelete(PRTPINGPONG pPP);
+
+/**
+ * Signals the pong thread in a ping-pong construct. (I.e. sends ping.)
+ * This is called by the ping thread.
+ *
+ * @returns iprt status code.
+ * @param   pPP         Pointer to the ping-pong structure to ping.
+ */
+RTDECL(int) RTSemPing(PRTPINGPONG pPP);
+
+/**
+ * Signals the ping thread in a ping-pong construct. (I.e. sends pong.)
+ * This is called by the pong thread.
+ *
+ * @returns iprt status code.
+ * @param   pPP         Pointer to the ping-pong structure to pong.
+ */
+RTDECL(int) RTSemPong(PRTPINGPONG pPP);
+
+/**
+ * Wait function for the ping thread.
+ *
+ * @returns iprt status code.
+ *          Will not return VERR_INTERRUPTED.
+ * @param   pPP         Pointer to the ping-pong structure to wait on.
+ * @param   cMillies    Number of milliseconds to wait.
+ */
+RTDECL(int) RTSemPingWait(PRTPINGPONG pPP, RTMSINTERVAL cMillies);
+
+/**
+ * Wait function for the pong thread.
+ *
+ * @returns iprt status code.
+ *          Will not return VERR_INTERRUPTED.
+ * @param   pPP         Pointer to the ping-pong structure to wait on.
+ * @param   cMillies    Number of milliseconds to wait.
+ */
+RTDECL(int) RTSemPongWait(PRTPINGPONG pPP, RTMSINTERVAL cMillies);
+
+
+/**
+ * Checks if the pong thread is speaking.
+ *
+ * @returns true / false.
+ * @param   pPP         Pointer to the ping-pong structure.
+ * @remark  This is NOT the same as !RTSemPongIsSpeaker().
+ */
+DECLINLINE(bool) RTSemPingIsSpeaker(PRTPINGPONG pPP)
+{
+    RTPINGPONGSPEAKER enmSpeaker = pPP->enmSpeaker;
+    return enmSpeaker == RTPINGPONGSPEAKER_PING;
+}
+
+
+/**
+ * Checks if the pong thread is speaking.
+ *
+ * @returns true / false.
+ * @param   pPP         Pointer to the ping-pong structure.
+ * @remark  This is NOT the same as !RTSemPingIsSpeaker().
+ */
+DECLINLINE(bool) RTSemPongIsSpeaker(PRTPINGPONG pPP)
+{
+    RTPINGPONGSPEAKER enmSpeaker = pPP->enmSpeaker;
+    return enmSpeaker == RTPINGPONGSPEAKER_PONG;
+}
+
+
+/**
+ * Checks whether the ping thread should wait.
+ *
+ * @returns true / false.
+ * @param   pPP         Pointer to the ping-pong structure.
+ * @remark  This is NOT the same as !RTSemPongShouldWait().
+ */
+DECLINLINE(bool) RTSemPingShouldWait(PRTPINGPONG pPP)
+{
+    RTPINGPONGSPEAKER enmSpeaker = pPP->enmSpeaker;
+    return enmSpeaker == RTPINGPONGSPEAKER_PONG
+        || enmSpeaker == RTPINGPONGSPEAKER_PONG_SIGNALED
+        || enmSpeaker == RTPINGPONGSPEAKER_PING_SIGNALED;
+}
+
+
+/**
+ * Checks whether the pong thread should wait.
+ *
+ * @returns true / false.
+ * @param   pPP         Pointer to the ping-pong structure.
+ * @remark  This is NOT the same as !RTSemPingShouldWait().
+ */
+DECLINLINE(bool) RTSemPongShouldWait(PRTPINGPONG pPP)
+{
+    RTPINGPONGSPEAKER enmSpeaker = pPP->enmSpeaker;
+    return enmSpeaker == RTPINGPONGSPEAKER_PING
+        || enmSpeaker == RTPINGPONGSPEAKER_PING_SIGNALED
+        || enmSpeaker == RTPINGPONGSPEAKER_PONG_SIGNALED;
+}
+
+/** @} */
+
+
+/** @defgroup grp_rt_sems_xroads    RTSemXRoads - Crossroads
+ *
+ * The crossroads semaphore is intended to prevent two classes of incompatible
+ * events from occurring simultaneously, like south/north bound traffic and
+ * west/east bound traffic at a 4-way junction.
+ *
+ * @remarks In order to simplify the implementation, the current flow is always
+ *          given priority.  So, it won't work at all well when busy!
+ *
+ * @remarks "XRoads" is used as a name because it is briefer than "crossroads"
+ *          and it slightly stresses that is a 4 way crossing to the users of
+ *          American English.
+ * @{
+ */
+
+/**
+ * Creates a crossroads semaphore.
+ *
+ * @returns IPRT status code.
+ *
+ * @param   phXRoads            Where to return the handle to the newly created
+ *                              crossroads semaphore.
+ */
+RTDECL(int) RTSemXRoadsCreate(PRTSEMXROADS phXRoads);
+
+/**
+ * Destroys a crossroads semaphore.
+ *
+ * @returns IPRT status code.
+ *
+ * @param   hXRoads             Handle to the crossroads semaphore that is to be
+ *                              destroyed.  NIL_RTSEMXROADS is quitetly ignored
+ *                              (VINF_SUCCESS).
+ */
+RTDECL(int) RTSemXRoadsDestroy(RTSEMXROADS hXRoads);
+
+/**
+ * Enter the crossroads from the south or north.
+ *
+ * (Coupled with RTSemXRoadsNSLeave.)
+ *
+ * @returns IPRT status code.
+ * @param   hXRoads             Handle to the crossroads semaphore.
+ */
+RTDECL(int) RTSemXRoadsNSEnter(RTSEMXROADS hXRoads);
+
+/**
+ * Leave the crossroads to the north or south.
+ *
+ * (Coupled with RTSemXRoadsNSEnter.)
+ *
+ * @returns IPRT status code.
+ * @param   hXRoads             Handle to the crossroads semaphore.
+ */
+RTDECL(int) RTSemXRoadsNSLeave(RTSEMXROADS hXRoads);
+
+/**
+ * Leave the crossroads from the east or west.
+ *
+ * (Coupled with RTSemXRoadsEWLeave.)
+ *
+ * @returns IPRT status code.
+ * @param   hXRoads             Handle to the crossroads semaphore.
+ */
+RTDECL(int) RTSemXRoadsEWEnter(RTSEMXROADS hXRoads);
+
+/**
+ * Leave the crossroads to the west or east.
+ *
+ * (Coupled with RTSemXRoadsEWEnter.)
+ *
+ * @returns IPRT status code.
+ * @param   hXRoads             Handle to the crossroads semaphore.
+ */
+RTDECL(int) RTSemXRoadsEWLeave(RTSEMXROADS hXRoads);
+
+/** @} */
+
+/** @} */
+
+RT_C_DECLS_END
+
+#endif
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/include/iprt/spinlock.h
@@ -0,0 +1,92 @@
+/** @file
+ * IPRT - Spinlocks.
+ */
+
+/*
+ * Copyright (C) 2006-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+#ifndef ___iprt_spinlock_h
+#define ___iprt_spinlock_h
+
+#include <iprt/cdefs.h>
+#include <iprt/types.h>
+
+RT_C_DECLS_BEGIN
+
+
+/** @defgroup grp_rt_spinlock   RTSpinlock - Spinlocks
+ * @ingroup grp_rt
+ * @{
+ */
+
+/**
+ * Creates a spinlock.
+ *
+ * @returns iprt status code.
+ * @param   pSpinlock   Where to store the spinlock handle.
+ * @param   fFlags      Creation flags, see RTSPINLOCK_FLAGS_XXX.
+ * @param   pszName     Spinlock name, for debugging purposes.  String lifetime
+ *                      must be the same as the lock as it won't be copied.
+ */
+RTDECL(int)  RTSpinlockCreate(PRTSPINLOCK pSpinlock, uint32_t fFlags, const char *pszName);
+
+/** @name RTSPINLOCK_FLAGS_XXX
+ * @{ */
+/** Disable interrupts when taking the spinlock, making it interrupt safe
+ * (sans NMI of course).
+ *
+ * This is generally the safest option, though it isn't really required unless
+ * the data being protect is also accessed from interrupt handler context. */
+#define RTSPINLOCK_FLAGS_INTERRUPT_SAFE     RT_BIT(1)
+/** No need to disable interrupts, the protect code/data is not used by
+ * interrupt handlers. */
+#define RTSPINLOCK_FLAGS_INTERRUPT_UNSAFE   RT_BIT(2)
+/** @}  */
+
+/**
+ * Destroys a spinlock created by RTSpinlockCreate().
+ *
+ * @returns iprt status code.
+ * @param   Spinlock    Spinlock returned by RTSpinlockCreate().
+ */
+RTDECL(int)  RTSpinlockDestroy(RTSPINLOCK Spinlock);
+
+/**
+ * Acquires the spinlock.
+ *
+ * @param   Spinlock    The spinlock to acquire.
+ */
+RTDECL(void) RTSpinlockAcquire(RTSPINLOCK Spinlock);
+
+/**
+ * Releases the spinlock.
+ *
+ * @param   Spinlock    The spinlock to acquire.
+ */
+RTDECL(void) RTSpinlockRelease(RTSPINLOCK Spinlock);
+
+
+/** @} */
+
+RT_C_DECLS_END
+
+#endif
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/include/iprt/stdarg.h
@@ -0,0 +1,54 @@
+/** @file
+ * IPRT - stdarg.h wrapper.
+ */
+
+/*
+ * Copyright (C) 2006-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+#ifndef ___iprt_stdarg_h
+#define ___iprt_stdarg_h
+
+#ifdef IPRT_NO_CRT
+# include <iprt/types.h>
+# include <iprt/nocrt/compiler/compiler.h>
+#else
+# include <iprt/cdefs.h>
+# if defined(RT_OS_FREEBSD) && defined(_KERNEL)
+#  include <machine/stdarg.h>
+# elif defined(RT_OS_SOLARIS) && defined(_KERNEL) && defined(__GNUC__)
+#  include <stdarg.h>
+#  if __GNUC__ >= 4 /* System headers refers to __builtin_stdarg_start. */
+#   define __builtin_stdarg_start __builtin_va_start
+#  endif
+# else
+#  include <stdarg.h>
+# endif
+#endif
+
+/*
+ * MSC doesn't implement va_copy.
+ */
+#ifndef va_copy
+# define va_copy(dst, src) do { (dst) = (src); } while (0) /** @todo check AMD64 */
+#endif
+
+#endif
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/include/iprt/stdint.h
@@ -0,0 +1,244 @@
+/** @file
+ * IPRT - stdint.h wrapper (for backlevel compilers like MSC).
+ */
+
+/*
+ * Copyright (C) 2009-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+#ifndef __iprt_stdint_h
+#define __iprt_stdint_h
+
+#include <iprt/cdefs.h>
+
+
+/*
+ * Use the stdint.h on systems that have one.
+ */
+#if !(defined(RT_OS_LINUX) && defined(__KERNEL__))  \
+  && !(defined(RT_OS_FREEBSD) && defined(_KERNEL)) \
+  && !defined(_MSC_VER) \
+  && !defined(__IBMC__) \
+  && !defined(__IBMCPP__) \
+  && !defined(IPRT_NO_CRT) \
+  && !defined(IPRT_DONT_USE_SYSTEM_STDINT_H) \
+  && !defined(DOXYGEN_RUNNING)
+
+# ifndef __STDC_CONSTANT_MACROS
+#  define __STDC_CONSTANT_MACROS
+# endif
+# ifndef __STDC_LIMIT_MACROS
+#  define __STDC_LIMIT_MACROS
+# endif
+# include <stdint.h>
+
+# if defined(RT_OS_DARWIN) && defined(KERNEL) && defined(RT_ARCH_AMD64)
+ /*
+  * Kludge to fix the incorrect 32-bit constant macros in
+  * Kernel.framework/Headers/stdin.h. uint32_t and int32_t are
+  * int not long as these macros use, which is significant when
+  * targeting AMD64. (10a222)
+  */
+#  undef  INT32_C
+#  define INT32_C(Value)    (Value)
+#  undef  UINT32_C
+#  define UINT32_C(Value)   (Value ## U)
+# endif /* 64-bit darwin kludge. */
+
+#elif defined(RT_OS_FREEBSD) && defined(_KERNEL)
+
+# ifndef __STDC_CONSTANT_MACROS
+#  define __STDC_CONSTANT_MACROS
+# endif
+# ifndef __STDC_LIMIT_MACROS
+#  define __STDC_LIMIT_MACROS
+# endif
+# include <sys/stdint.h>
+
+#else /* No system stdint.h */
+
+/*
+ * Define the types we use.
+ * The linux kernel defines all these in linux/types.h, so skip it.
+ */
+# if !(defined(RT_OS_LINUX) && defined(__KERNEL__)) \
+  || defined(IPRT_NO_CRT) \
+  || defined(IPRT_DONT_USE_SYSTEM_STDINT_H) \
+  || defined(DOXGEN_RUNNING)
+
+    /* Simplify the [u]int64_t type detection mess. */
+# undef IPRT_STDINT_USE_STRUCT_FOR_64_BIT_TYPES
+# ifdef __IBMCPP__
+#  if __IBMCPP__ < 350 && (defined(__WINDOWS__) || defined(_AIX) || defined(__OS2__))
+#   define IPRT_STDINT_USE_STRUCT_FOR_64_BIT_TYPES
+#  endif
+# endif
+# ifdef __IBMC__
+#  if __IBMC__   < 350 && (defined(__WINDOWS__) || defined(_AIX) || defined(__OS2__))
+#   define IPRT_STDINT_USE_STRUCT_FOR_64_BIT_TYPES
+#  endif
+# endif
+
+    /* x-bit types */
+#  if defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86) || defined(RT_ARCH_SPARC) || defined(RT_ARCH_SPARC64)
+#   if !defined(_INT8_T_DECLARED)   && !defined(_INT8_T)
+typedef signed char         int8_t;
+#   endif
+#   if !defined(_UINT8_T_DECLARED)  && !defined(_UINT8_T)
+typedef unsigned char       uint8_t;
+#   endif
+#   if !defined(_INT16_T_DECLARED)  && !defined(_INT16_T)
+typedef signed short        int16_t;
+#   endif
+#   if !defined(_UINT16_T_DECLARED) && !defined(_UINT16_T)
+typedef unsigned short      uint16_t;
+#   endif
+#   if !defined(_INT32_T_DECLARED)  && !defined(_INT32_T)
+typedef signed int          int32_t;
+#   endif
+#   if !defined(_UINT32_T_DECLARED) && !defined(_UINT32_T)
+typedef unsigned int        uint32_t;
+#   endif
+#   if defined(_MSC_VER)
+#    if !defined(_INT64_T_DECLARED)  && !defined(_INT64_T)
+typedef signed _int64       int64_t;
+#    endif
+#    if !defined(_UINT64_T_DECLARED) && !defined(_UINT64_T)
+typedef unsigned _int64     uint64_t;
+#    endif
+#   elif defined(IPRT_STDINT_USE_STRUCT_FOR_64_BIT_TYPES)
+#    if !defined(_INT64_T_DECLARED)  && !defined(_INT64_T)
+typedef struct { uint32_t lo; int32_t hi; }     int64_t;
+#    endif
+#    if !defined(_UINT64_T_DECLARED) && !defined(_UINT64_T)
+typedef struct { uint32_t lo; uint32_t hi; }    uint64_t;
+#    endif
+#   else /* Use long long for 64-bit types */
+#    if !defined(_INT64_T_DECLARED)  && !defined(_INT64_T)
+typedef signed long long    int64_t;
+#    endif
+#    if !defined(_UINT64_T_DECLARED) && !defined(_UINT64_T)
+typedef unsigned long long  uint64_t;
+#    endif
+#   endif
+
+    /* max integer types */
+#   if !defined(_INTMAX_T_DECLARED)  && !defined(_INTMAX_T)
+typedef int64_t             intmax_t;
+#   endif
+#   if !defined(_UINTMAX_T_DECLARED) && !defined(_UINTMAX_T)
+typedef uint64_t            uintmax_t;
+#   endif
+
+#  else
+#   error "PORTME: Add architecture. Don't forget to check the [U]INTx_C() and [U]INTMAX_MIN/MAX macros."
+#  endif
+
+# endif /* !linux kernel or stuff */
+
+    /* pointer <-> integer types */
+# if !defined(_MSC_VER) || defined(DOXYGEN_RUNNING)
+#  if ARCH_BITS == 32 \
+   || defined(RT_OS_LINUX) \
+   || defined(RT_OS_FREEBSD)
+#   if !defined(_INTPTR_T_DECLARED)  && !defined(_INTPTR_T)
+typedef signed long         intptr_t;
+#   endif
+#   if !defined(_UINTPTR_T_DECLARED) && !defined(_UINTPTR_T)
+typedef unsigned long       uintptr_t;
+#   endif
+#  else
+#   if !defined(_INTPTR_T_DECLARED)  && !defined(_INTPTR_T)
+typedef int64_t             intptr_t;
+#   endif
+#   if !defined(_UINTPTR_T_DECLARED) && !defined(_UINTPTR_T)
+typedef uint64_t            uintptr_t;
+#   endif
+#  endif
+# endif /* !_MSC_VER */
+
+#endif /* no system stdint.h */
+
+
+/*
+ * Make sure the [U]INTx_C(c) macros are present.
+ * For In C++ source the system stdint.h may have skipped these if it was
+ * included before we managed to define __STDC_CONSTANT_MACROS. (Kludge alert!)
+ */
+#if !defined(INT8_C) \
+ || !defined(INT16_C) \
+ || !defined(INT32_C) \
+ || !defined(INT64_C) \
+ || !defined(INTMAX_C) \
+ || !defined(UINT8_C) \
+ || !defined(UINT16_C) \
+ || !defined(UINT32_C) \
+ || !defined(UINT64_C) \
+ || !defined(UINTMAX_C)
+# define INT8_C(Value)      (Value)
+# define INT16_C(Value)     (Value)
+# define INT32_C(Value)     (Value)
+# define INT64_C(Value)     (Value ## LL)
+# define UINT8_C(Value)     (Value)
+# define UINT16_C(Value)    (Value)
+# define UINT32_C(Value)    (Value ## U)
+# define UINT64_C(Value)    (Value ## ULL)
+# define INTMAX_C(Value)    INT64_C(Value)
+# define UINTMAX_C(Value)   UINT64_C(Value)
+#endif
+
+
+/*
+ * Make sure the INTx_MIN and [U]INTx_MAX macros are present.
+ * For In C++ source the system stdint.h may have skipped these if it was
+ * included before we managed to define __STDC_LIMIT_MACROS. (Kludge alert!)
+ */
+#if !defined(INT8_MIN) \
+ || !defined(INT16_MIN) \
+ || !defined(INT32_MIN) \
+ || !defined(INT64_MIN) \
+ || !defined(INT8_MAX) \
+ || !defined(INT16_MAX) \
+ || !defined(INT32_MAX) \
+ || !defined(INT64_MAX) \
+ || !defined(UINT8_MAX) \
+ || !defined(UINT16_MAX) \
+ || !defined(UINT32_MAX) \
+ || !defined(UINT64_MAX)
+# define INT8_MIN           (INT8_C(-0x7f)                - 1)
+# define INT16_MIN          (INT16_C(-0x7fff)             - 1)
+# define INT32_MIN          (INT32_C(-0x7fffffff)         - 1)
+# define INT64_MIN          (INT64_C(-0x7fffffffffffffff) - 1)
+# define INT8_MAX           INT8_C(0x7f)
+# define INT16_MAX          INT16_C(0x7fff)
+# define INT32_MAX          INT32_C(0x7fffffff)
+# define INT64_MAX          INT64_C(0x7fffffffffffffff)
+# define UINT8_MAX          UINT8_C(0xff)
+# define UINT16_MAX         UINT16_C(0xffff)
+# define UINT32_MAX         UINT32_C(0xffffffff)
+# define UINT64_MAX         UINT64_C(0xffffffffffffffff)
+
+# define INTMAX_MIN         INT64_MIN
+# define INTMAX_MAX         INT64_MAX
+# define UINTMAX_MAX        UINT64_MAX
+#endif
+
+#endif
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/include/iprt/string.h
@@ -0,0 +1,3021 @@
+/** @file
+ * IPRT - String Manipulation.
+ */
+
+/*
+ * Copyright (C) 2006-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+#ifndef ___iprt_string_h
+#define ___iprt_string_h
+
+#include <iprt/cdefs.h>
+#include <iprt/types.h>
+#include <iprt/assert.h>
+#include <iprt/stdarg.h>
+#include <iprt/err.h> /* for VINF_SUCCESS */
+#if defined(RT_OS_LINUX) && defined(__KERNEL__)
+  RT_C_DECLS_BEGIN
+# define new newhack /* string.h: strreplace */
+# include <linux/string.h>
+# undef new
+  RT_C_DECLS_END
+
+#elif defined(IN_XF86_MODULE) && !defined(NO_ANSIC)
+  RT_C_DECLS_BEGIN
+# include "xf86_ansic.h"
+  RT_C_DECLS_END
+
+#elif defined(RT_OS_FREEBSD) && defined(_KERNEL)
+  RT_C_DECLS_BEGIN
+  /** @todo
+   * XXX: Very ugly hack to get things build on recent FreeBSD builds. They have
+   * memchr now and we need to include param.h to get __FreeBSD_version and make
+   * memchr available based on the version below or we can't compile the kernel
+   * module on older versions anymore.
+   *
+   * But including param.h here opens Pandora's box because we clash with a few
+   * defines namely PVM and PAGE_SIZE. We can safely undefine PVM here but not
+   * PAGE_SIZE because this results in build errors sooner or later. Luckily this
+   * define is in a header included by param.h (machine/param.h). We define the
+   * guards here to prevent inclusion of it if PAGE_SIZE was defined already.
+   *
+   * @todo aeichner: Search for an elegant solution and cleanup this mess ASAP!
+   */
+# ifdef PAGE_SIZE
+#  define _AMD64_INCLUDE_PARAM_H_
+#  define _I386_INCLUDE_PARAM_H_
+#  define _MACHINE_PARAM_H_
+# endif
+# include <sys/param.h> /* __FreeBSD_version */
+# undef PVM
+# include <sys/libkern.h>
+  /*
+   * No memmove on versions < 7.2
+   * Defining a macro using bcopy here
+   */
+# define memmove(dst, src, size) bcopy(src, dst, size)
+  RT_C_DECLS_END
+
+#elif defined(RT_OS_SOLARIS) && defined(_KERNEL)
+  /*
+   * Same case as with FreeBSD kernel:
+   * The string.h stuff clashes with sys/system.h
+   * ffs = find first set bit.
+   */
+# define ffs ffs_string_h
+# include <string.h>
+# undef ffs
+# undef strpbrk
+
+#else
+# include <string.h>
+#endif
+
+/* For the time being: */
+#include <iprt/utf16.h>
+#include <iprt/latin1.h>
+
+/*
+ * Supply prototypes for standard string functions provided by
+ * IPRT instead of the operating environment.
+ */
+#if defined(RT_OS_DARWIN) && defined(KERNEL)
+RT_C_DECLS_BEGIN
+void *memchr(const void *pv, int ch, size_t cb);
+char *strpbrk(const char *pszStr, const char *pszChars);
+RT_C_DECLS_END
+#endif
+
+#if defined(RT_OS_FREEBSD) && defined(_KERNEL)
+RT_C_DECLS_BEGIN
+#if __FreeBSD_version < 900000
+void *memchr(const void *pv, int ch, size_t cb);
+#endif
+char *strpbrk(const char *pszStr, const char *pszChars);
+RT_C_DECLS_END
+#endif
+
+#if !defined(RT_OS_LINUX) || !defined(_GNU_SOURCE)
+RT_C_DECLS_BEGIN
+void *memrchr(const char *pv, int ch, size_t cb);
+RT_C_DECLS_END
+#endif
+
+
+/** @def RT_USE_RTC_3629
+ * When defined the UTF-8 range will stop at  0x10ffff.  If not defined, the
+ * range stops at 0x7fffffff.
+ * @remarks Must be defined both when building and using the IPRT.  */
+#ifdef DOXYGEN_RUNNING
+# define RT_USE_RTC_3629
+#endif
+
+
+/**
+ * Byte zero the specified object.
+ *
+ * This will use sizeof(Obj) to figure the size and will call memset, bzero
+ * or some compiler intrinsic to perform the actual zeroing.
+ *
+ * @param   Obj     The object to zero. Make sure to dereference pointers.
+ *
+ * @remarks Because the macro may use memset it has been placed in string.h
+ *          instead of cdefs.h to avoid build issues because someone forgot
+ *          to include this header.
+ *
+ * @ingroup grp_rt_cdefs
+ */
+#define RT_ZERO(Obj)        RT_BZERO(&(Obj), sizeof(Obj))
+
+/**
+ * Byte zero the specified memory area.
+ *
+ * This will call memset, bzero or some compiler intrinsic to clear the
+ * specified bytes of memory.
+ *
+ * @param   pv          Pointer to the memory.
+ * @param   cb          The number of bytes to clear. Please, don't pass 0.
+ *
+ * @remarks Because the macro may use memset it has been placed in string.h
+ *          instead of cdefs.h to avoid build issues because someone forgot
+ *          to include this header.
+ *
+ * @ingroup grp_rt_cdefs
+ */
+#define RT_BZERO(pv, cb)    do { memset((pv), 0, cb); } while (0)
+
+
+
+/** @defgroup grp_rt_str    RTStr - String Manipulation
+ * Mostly UTF-8 related helpers where the standard string functions won't do.
+ * @ingroup grp_rt
+ * @{
+ */
+
+RT_C_DECLS_BEGIN
+
+
+/**
+ * The maximum string length.
+ */
+#define RTSTR_MAX       (~(size_t)0)
+
+
+/** @def RTSTR_TAG
+ * The default allocation tag used by the RTStr allocation APIs.
+ *
+ * When not defined before the inclusion of iprt/string.h, this will default to
+ * the pointer to the current file name.  The string API will make of use of
+ * this as pointer to a volatile but read-only string.
+ */
+#if !defined(RTSTR_TAG) || defined(DOXYGEN_RUNNING)
+# define RTSTR_TAG      (__FILE__)
+#endif
+
+
+#ifdef IN_RING3
+
+/**
+ * Allocates tmp buffer with default tag, translates pszString from UTF8 to
+ * current codepage.
+ *
+ * @returns iprt status code.
+ * @param   ppszString      Receives pointer of allocated native CP string.
+ *                          The returned pointer must be freed using RTStrFree().
+ * @param   pszString       UTF-8 string to convert.
+ */
+#define RTStrUtf8ToCurrentCP(ppszString, pszString)     RTStrUtf8ToCurrentCPTag((ppszString), (pszString), RTSTR_TAG)
+
+/**
+ * Allocates tmp buffer with custom tag, translates pszString from UTF8 to
+ * current codepage.
+ *
+ * @returns iprt status code.
+ * @param   ppszString      Receives pointer of allocated native CP string.
+ *                          The returned pointer must be freed using
+ *                          RTStrFree()., const char *pszTag
+ * @param   pszString       UTF-8 string to convert.
+ * @param   pszTag          Allocation tag used for statistics and such.
+ */
+RTR3DECL(int)  RTStrUtf8ToCurrentCPTag(char **ppszString, const char *pszString, const char *pszTag);
+
+/**
+ * Allocates tmp buffer, translates pszString from current codepage to UTF-8.
+ *
+ * @returns iprt status code.
+ * @param   ppszString      Receives pointer of allocated UTF-8 string.
+ *                          The returned pointer must be freed using RTStrFree().
+ * @param   pszString       Native string to convert.
+ */
+#define RTStrCurrentCPToUtf8(ppszString, pszString)     RTStrCurrentCPToUtf8Tag((ppszString), (pszString), RTSTR_TAG)
+
+/**
+ * Allocates tmp buffer, translates pszString from current codepage to UTF-8.
+ *
+ * @returns iprt status code.
+ * @param   ppszString      Receives pointer of allocated UTF-8 string.
+ *                          The returned pointer must be freed using RTStrFree().
+ * @param   pszString       Native string to convert.
+ * @param   pszTag          Allocation tag used for statistics and such.
+ */
+RTR3DECL(int)  RTStrCurrentCPToUtf8Tag(char **ppszString, const char *pszString, const char *pszTag);
+
+#endif /* IN_RING3 */
+
+/**
+ * Free string allocated by any of the non-UCS-2 string functions.
+ *
+ * @returns iprt status code.
+ * @param   pszString      Pointer to buffer with string to free.
+ *                         NULL is accepted.
+ */
+RTDECL(void)  RTStrFree(char *pszString);
+
+/**
+ * Allocates a new copy of the given UTF-8 string (default tag).
+ *
+ * @returns Pointer to the allocated UTF-8 string.
+ * @param   pszString       UTF-8 string to duplicate.
+ */
+#define RTStrDup(pszString)             RTStrDupTag((pszString), RTSTR_TAG)
+
+/**
+ * Allocates a new copy of the given UTF-8 string (custom tag).
+ *
+ * @returns Pointer to the allocated UTF-8 string.
+ * @param   pszString       UTF-8 string to duplicate.
+ * @param   pszTag          Allocation tag used for statistics and such.
+ */
+RTDECL(char *) RTStrDupTag(const char *pszString, const char *pszTag);
+
+/**
+ * Allocates a new copy of the given UTF-8 string (default tag).
+ *
+ * @returns iprt status code.
+ * @param   ppszString      Receives pointer of the allocated UTF-8 string.
+ *                          The returned pointer must be freed using RTStrFree().
+ * @param   pszString       UTF-8 string to duplicate.
+ */
+#define RTStrDupEx(ppszString, pszString)   RTStrDupExTag((ppszString), (pszString), RTSTR_TAG)
+
+/**
+ * Allocates a new copy of the given UTF-8 string (custom tag).
+ *
+ * @returns iprt status code.
+ * @param   ppszString      Receives pointer of the allocated UTF-8 string.
+ *                          The returned pointer must be freed using RTStrFree().
+ * @param   pszString       UTF-8 string to duplicate.
+ * @param   pszTag          Allocation tag used for statistics and such.
+ */
+RTDECL(int)  RTStrDupExTag(char **ppszString, const char *pszString, const char *pszTag);
+
+/**
+ * Allocates a new copy of the given UTF-8 substring (default tag).
+ *
+ * @returns Pointer to the allocated UTF-8 substring.
+ * @param   pszString       UTF-8 string to duplicate.
+ * @param   cchMax          The max number of chars to duplicate, not counting
+ *                          the terminator.
+ */
+#define RTStrDupN(pszString, cchMax)        RTStrDupNTag((pszString), (cchMax), RTSTR_TAG)
+
+/**
+ * Allocates a new copy of the given UTF-8 substring (custom tag).
+ *
+ * @returns Pointer to the allocated UTF-8 substring.
+ * @param   pszString       UTF-8 string to duplicate.
+ * @param   cchMax          The max number of chars to duplicate, not counting
+ *                          the terminator.
+ * @param   pszTag          Allocation tag used for statistics and such.
+ */
+RTDECL(char *) RTStrDupNTag(const char *pszString, size_t cchMax, const char *pszTag);
+
+/**
+ * Appends a string onto an existing IPRT allocated string (default tag).
+ *
+ * @retval  VINF_SUCCESS
+ * @retval  VERR_NO_STR_MEMORY if we failed to reallocate the string, @a *ppsz
+ *          remains unchanged.
+ *
+ * @param   ppsz                Pointer to the string pointer.  The string
+ *                              pointer must either be NULL or point to a string
+ *                              returned by an IPRT string API.  (In/Out)
+ * @param   pszAppend           The string to append.  NULL and empty strings
+ *                              are quietly ignored.
+ */
+#define RTStrAAppend(ppsz, pszAppend)   RTStrAAppendTag((ppsz), (pszAppend), RTSTR_TAG)
+
+/**
+ * Appends a string onto an existing IPRT allocated string (custom tag).
+ *
+ * @retval  VINF_SUCCESS
+ * @retval  VERR_NO_STR_MEMORY if we failed to reallocate the string, @a *ppsz
+ *          remains unchanged.
+ *
+ * @param   ppsz                Pointer to the string pointer.  The string
+ *                              pointer must either be NULL or point to a string
+ *                              returned by an IPRT string API.  (In/Out)
+ * @param   pszAppend           The string to append.  NULL and empty strings
+ *                              are quietly ignored.
+ * @param   pszTag              Allocation tag used for statistics and such.
+ */
+RTDECL(int) RTStrAAppendTag(char **ppsz, const char *pszAppend, const char *pszTag);
+
+/**
+ * Appends N bytes from a strings onto an existing IPRT allocated string
+ * (default tag).
+ *
+ * @retval  VINF_SUCCESS
+ * @retval  VERR_NO_STR_MEMORY if we failed to reallocate the string, @a *ppsz
+ *          remains unchanged.
+ *
+ * @param   ppsz                Pointer to the string pointer.  The string
+ *                              pointer must either be NULL or point to a string
+ *                              returned by an IPRT string API.  (In/Out)
+ * @param   pszAppend           The string to append.  Can be NULL if cchAppend
+ *                              is NULL.
+ * @param   cchAppend           The number of chars (not code points) to append
+ *                              from pszAppend.   Must not be more than
+ *                              @a pszAppend contains, except for the special
+ *                              value RTSTR_MAX that can be used to indicate all
+ *                              of @a pszAppend without having to strlen it.
+ */
+#define RTStrAAppendN(ppsz, pszAppend, cchAppend)   RTStrAAppendNTag((ppsz), (pszAppend), (cchAppend), RTSTR_TAG)
+
+/**
+ * Appends N bytes from a strings onto an existing IPRT allocated string (custom
+ * tag).
+ *
+ * @retval  VINF_SUCCESS
+ * @retval  VERR_NO_STR_MEMORY if we failed to reallocate the string, @a *ppsz
+ *          remains unchanged.
+ *
+ * @param   ppsz                Pointer to the string pointer.  The string
+ *                              pointer must either be NULL or point to a string
+ *                              returned by an IPRT string API.  (In/Out)
+ * @param   pszAppend           The string to append.  Can be NULL if cchAppend
+ *                              is NULL.
+ * @param   cchAppend           The number of chars (not code points) to append
+ *                              from pszAppend.   Must not be more than
+ *                              @a pszAppend contains, except for the special
+ *                              value RTSTR_MAX that can be used to indicate all
+ *                              of @a pszAppend without having to strlen it.
+ * @param   pszTag              Allocation tag used for statistics and such.
+ */
+RTDECL(int) RTStrAAppendNTag(char **ppsz, const char *pszAppend, size_t cchAppend, const char *pszTag);
+
+/**
+ * Appends one or more strings onto an existing IPRT allocated string.
+ *
+ * This is a very flexible and efficient alternative to using RTStrAPrintf to
+ * combine several strings together.
+ *
+ * @retval  VINF_SUCCESS
+ * @retval  VERR_NO_STR_MEMORY if we failed to reallocate the string, @a *ppsz
+ *          remains unchanged.
+ *
+ * @param   ppsz                Pointer to the string pointer.  The string
+ *                              pointer must either be NULL or point to a string
+ *                              returned by an IPRT string API.  (In/Out)
+ * @param   cPairs              The number of string / length pairs in the
+ *                              @a va.
+ * @param   va                  List of string (const char *) and length
+ *                              (size_t) pairs.  The strings will be appended to
+ *                              the string in the first argument.
+ */
+#define RTStrAAppendExNV(ppsz, cPairs, va)  RTStrAAppendExNVTag((ppsz), (cPairs), (va), RTSTR_TAG)
+
+/**
+ * Appends one or more strings onto an existing IPRT allocated string.
+ *
+ * This is a very flexible and efficient alternative to using RTStrAPrintf to
+ * combine several strings together.
+ *
+ * @retval  VINF_SUCCESS
+ * @retval  VERR_NO_STR_MEMORY if we failed to reallocate the string, @a *ppsz
+ *          remains unchanged.
+ *
+ * @param   ppsz                Pointer to the string pointer.  The string
+ *                              pointer must either be NULL or point to a string
+ *                              returned by an IPRT string API.  (In/Out)
+ * @param   cPairs              The number of string / length pairs in the
+ *                              @a va.
+ * @param   va                  List of string (const char *) and length
+ *                              (size_t) pairs.  The strings will be appended to
+ *                              the string in the first argument.
+ * @param   pszTag              Allocation tag used for statistics and such.
+ */
+RTDECL(int) RTStrAAppendExNVTag(char **ppsz, size_t cPairs, va_list va, const char *pszTag);
+
+/**
+ * Appends one or more strings onto an existing IPRT allocated string
+ * (untagged).
+ *
+ * This is a very flexible and efficient alternative to using RTStrAPrintf to
+ * combine several strings together.
+ *
+ * @retval  VINF_SUCCESS
+ * @retval  VERR_NO_STR_MEMORY if we failed to reallocate the string, @a *ppsz
+ *          remains unchanged.
+ *
+ * @param   ppsz                Pointer to the string pointer.  The string
+ *                              pointer must either be NULL or point to a string
+ *                              returned by an IPRT string API.  (In/Out)
+ * @param   cPairs              The number of string / length pairs in the
+ *                              ellipsis.
+ * @param   ...                 List of string (const char *) and length
+ *                              (size_t) pairs.  The strings will be appended to
+ *                              the string in the first argument.
+ */
+DECLINLINE(int) RTStrAAppendExN(char **ppsz, size_t cPairs, ...)
+{
+    int     rc;
+    va_list va;
+    va_start(va, cPairs);
+    rc = RTStrAAppendExNVTag(ppsz, cPairs, va, RTSTR_TAG);
+    va_end(va);
+    return rc;
+}
+
+/**
+ * Appends one or more strings onto an existing IPRT allocated string (custom
+ * tag).
+ *
+ * This is a very flexible and efficient alternative to using RTStrAPrintf to
+ * combine several strings together.
+ *
+ * @retval  VINF_SUCCESS
+ * @retval  VERR_NO_STR_MEMORY if we failed to reallocate the string, @a *ppsz
+ *          remains unchanged.
+ *
+ * @param   ppsz                Pointer to the string pointer.  The string
+ *                              pointer must either be NULL or point to a string
+ *                              returned by an IPRT string API.  (In/Out)
+ * @param   pszTag              Allocation tag used for statistics and such.
+ * @param   cPairs              The number of string / length pairs in the
+ *                              ellipsis.
+ * @param   ...                 List of string (const char *) and length
+ *                              (size_t) pairs.  The strings will be appended to
+ *                              the string in the first argument.
+ */
+DECLINLINE(int) RTStrAAppendExNTag(char **ppsz, const char *pszTag, size_t cPairs, ...)
+{
+    int     rc;
+    va_list va;
+    va_start(va, cPairs);
+    rc = RTStrAAppendExNVTag(ppsz, cPairs, va, pszTag);
+    va_end(va);
+    return rc;
+}
+
+/**
+ * Truncates an IPRT allocated string (default tag).
+ *
+ * @retval  VINF_SUCCESS.
+ * @retval  VERR_OUT_OF_RANGE if cchNew is too long.  Nothing is done.
+ *
+ * @param   ppsz                Pointer to the string pointer.  The string
+ *                              pointer can be NULL if @a cchNew is 0, no change
+ *                              is made then.  If we actually reallocate the
+ *                              string, the string pointer might be changed by
+ *                              this call.  (In/Out)
+ * @param   cchNew              The new string length (excluding the
+ *                              terminator).  The string must be at least this
+ *                              long or we'll return VERR_OUT_OF_RANGE and
+ *                              assert on you.
+ */
+#define RTStrATruncate(ppsz, cchNew)    RTStrATruncateTag((ppsz), (cchNew), RTSTR_TAG)
+
+/**
+ * Truncates an IPRT allocated string.
+ *
+ * @retval  VINF_SUCCESS.
+ * @retval  VERR_OUT_OF_RANGE if cchNew is too long.  Nothing is done.
+ *
+ * @param   ppsz                Pointer to the string pointer.  The string
+ *                              pointer can be NULL if @a cchNew is 0, no change
+ *                              is made then.  If we actually reallocate the
+ *                              string, the string pointer might be changed by
+ *                              this call.  (In/Out)
+ * @param   cchNew              The new string length (excluding the
+ *                              terminator).  The string must be at least this
+ *                              long or we'll return VERR_OUT_OF_RANGE and
+ *                              assert on you.
+ * @param   pszTag              Allocation tag used for statistics and such.
+ */
+RTDECL(int) RTStrATruncateTag(char **ppsz, size_t cchNew, const char *pszTag);
+
+/**
+ * Allocates memory for string storage (default tag).
+ *
+ * You should normally not use this function, except if there is some very
+ * custom string handling you need doing that isn't covered by any of the other
+ * APIs.
+ *
+ * @returns Pointer to the allocated string.  The first byte is always set
+ *          to the string terminator char, the contents of the remainder of the
+ *          memory is undefined.  The string must be freed by calling RTStrFree.
+ *
+ *          NULL is returned if the allocation failed.  Please translate this to
+ *          VERR_NO_STR_MEMORY and not VERR_NO_MEMORY.  Also consider
+ *          RTStrAllocEx if an IPRT status code is required.
+ *
+ * @param   cb                  How many bytes to allocate.  If this is zero, we
+ *                              will allocate a terminator byte anyway.
+ */
+#define RTStrAlloc(cb)                  RTStrAllocTag((cb), RTSTR_TAG)
+
+/**
+ * Allocates memory for string storage (custom tag).
+ *
+ * You should normally not use this function, except if there is some very
+ * custom string handling you need doing that isn't covered by any of the other
+ * APIs.
+ *
+ * @returns Pointer to the allocated string.  The first byte is always set
+ *          to the string terminator char, the contents of the remainder of the
+ *          memory is undefined.  The string must be freed by calling RTStrFree.
+ *
+ *          NULL is returned if the allocation failed.  Please translate this to
+ *          VERR_NO_STR_MEMORY and not VERR_NO_MEMORY.  Also consider
+ *          RTStrAllocEx if an IPRT status code is required.
+ *
+ * @param   cb                  How many bytes to allocate.  If this is zero, we
+ *                              will allocate a terminator byte anyway.
+ * @param   pszTag              Allocation tag used for statistics and such.
+ */
+RTDECL(char *) RTStrAllocTag(size_t cb, const char *pszTag);
+
+/**
+ * Allocates memory for string storage, with status code (default tag).
+ *
+ * You should normally not use this function, except if there is some very
+ * custom string handling you need doing that isn't covered by any of the other
+ * APIs.
+ *
+ * @retval  VINF_SUCCESS
+ * @retval  VERR_NO_STR_MEMORY
+ *
+ * @param   ppsz                Where to return the allocated string.  This will
+ *                              be set to NULL on failure.  On success, the
+ *                              returned memory will always start with a
+ *                              terminator char so that it is considered a valid
+ *                              C string, the contents of rest of the memory is
+ *                              undefined.
+ * @param   cb                  How many bytes to allocate.  If this is zero, we
+ *                              will allocate a terminator byte anyway.
+ */
+#define RTStrAllocEx(ppsz, cb)      RTStrAllocExTag((ppsz), (cb), RTSTR_TAG)
+
+/**
+ * Allocates memory for string storage, with status code (custom tag).
+ *
+ * You should normally not use this function, except if there is some very
+ * custom string handling you need doing that isn't covered by any of the other
+ * APIs.
+ *
+ * @retval  VINF_SUCCESS
+ * @retval  VERR_NO_STR_MEMORY
+ *
+ * @param   ppsz                Where to return the allocated string.  This will
+ *                              be set to NULL on failure.  On success, the
+ *                              returned memory will always start with a
+ *                              terminator char so that it is considered a valid
+ *                              C string, the contents of rest of the memory is
+ *                              undefined.
+ * @param   cb                  How many bytes to allocate.  If this is zero, we
+ *                              will allocate a terminator byte anyway.
+ * @param   pszTag              Allocation tag used for statistics and such.
+ */
+RTDECL(int) RTStrAllocExTag(char **ppsz, size_t cb, const char *pszTag);
+
+/**
+ * Reallocates the specified string (default tag).
+ *
+ * You should normally not have use this function, except perhaps to truncate a
+ * really long string you've got from some IPRT string API, but then you should
+ * use RTStrATruncate.
+ *
+ * @returns VINF_SUCCESS.
+ * @retval  VERR_NO_STR_MEMORY if we failed to reallocate the string, @a *ppsz
+ *          remains unchanged.
+ *
+ * @param   ppsz                Pointer to the string variable containing the
+ *                              input and output string.
+ *
+ *                              When not freeing the string, the result will
+ *                              always have the last byte set to the terminator
+ *                              character so that when used for string
+ *                              truncation the result will be a valid C string
+ *                              (your job to keep it a valid UTF-8 string).
+ *
+ *                              When the input string is NULL and we're supposed
+ *                              to reallocate, the returned string will also
+ *                              have the first byte set to the terminator char
+ *                              so it will be a valid C string.
+ *
+ * @param   cbNew               When @a cbNew is zero, we'll behave like
+ *                              RTStrFree and @a *ppsz will be set to NULL.
+ *
+ *                              When not zero, this will be the new size of the
+ *                              memory backing the string, i.e. it includes the
+ *                              terminator char.
+ */
+#define RTStrRealloc(ppsz, cbNew)       RTStrReallocTag((ppsz), (cbNew), RTSTR_TAG)
+
+/**
+ * Reallocates the specified string (custom tag).
+ *
+ * You should normally not have use this function, except perhaps to truncate a
+ * really long string you've got from some IPRT string API, but then you should
+ * use RTStrATruncate.
+ *
+ * @returns VINF_SUCCESS.
+ * @retval  VERR_NO_STR_MEMORY if we failed to reallocate the string, @a *ppsz
+ *          remains unchanged.
+ *
+ * @param   ppsz                Pointer to the string variable containing the
+ *                              input and output string.
+ *
+ *                              When not freeing the string, the result will
+ *                              always have the last byte set to the terminator
+ *                              character so that when used for string
+ *                              truncation the result will be a valid C string
+ *                              (your job to keep it a valid UTF-8 string).
+ *
+ *                              When the input string is NULL and we're supposed
+ *                              to reallocate, the returned string will also
+ *                              have the first byte set to the terminator char
+ *                              so it will be a valid C string.
+ *
+ * @param   cbNew               When @a cbNew is zero, we'll behave like
+ *                              RTStrFree and @a *ppsz will be set to NULL.
+ *
+ *                              When not zero, this will be the new size of the
+ *                              memory backing the string, i.e. it includes the
+ *                              terminator char.
+ * @param   pszTag              Allocation tag used for statistics and such.
+ */
+RTDECL(int) RTStrReallocTag(char **ppsz, size_t cbNew, const char *pszTag);
+
+/**
+ * Validates the UTF-8 encoding of the string.
+ *
+ * @returns iprt status code.
+ * @param   psz         The string.
+ */
+RTDECL(int) RTStrValidateEncoding(const char *psz);
+
+/** @name Flags for RTStrValidateEncodingEx and RTUtf16ValidateEncodingEx
+ * @{
+ */
+/** Check that the string is zero terminated within the given size.
+ * VERR_BUFFER_OVERFLOW will be returned if the check fails. */
+#define RTSTR_VALIDATE_ENCODING_ZERO_TERMINATED     RT_BIT_32(0)
+/** Check that the string is exactly the given length.
+ * If it terminates early, VERR_BUFFER_UNDERFLOW will be returned.  When used
+ * together with RTSTR_VALIDATE_ENCODING_ZERO_TERMINATED, the given length must
+ * include the terminator or VERR_BUFFER_OVERFLOW will be returned. */
+#define RTSTR_VALIDATE_ENCODING_EXACT_LENGTH        RT_BIT_32(1)
+/** @} */
+
+/**
+ * Validates the UTF-8 encoding of the string.
+ *
+ * @returns iprt status code.
+ * @param   psz         The string.
+ * @param   cch         The max string length (/ size).  Use RTSTR_MAX to
+ *                      process the entire string.
+ * @param   fFlags      Combination of RTSTR_VALIDATE_ENCODING_XXX flags.
+ */
+RTDECL(int) RTStrValidateEncodingEx(const char *psz, size_t cch, uint32_t fFlags);
+
+/**
+ * Checks if the UTF-8 encoding is valid.
+ *
+ * @returns true / false.
+ * @param   psz         The string.
+ */
+RTDECL(bool) RTStrIsValidEncoding(const char *psz);
+
+/**
+ * Purge all bad UTF-8 encoding in the string, replacing it with '?'.
+ *
+ * @returns The number of bad characters (0 if nothing was done).
+ * @param   psz         The string to purge.
+ */
+RTDECL(size_t) RTStrPurgeEncoding(char *psz);
+
+/**
+ * Sanitise a (valid) UTF-8 string by replacing all characters outside a white
+ * list in-place by an ASCII replacement character.  Multi-byte characters will
+ * be replaced byte by byte.
+ *
+ * @returns The number of code points replaced, or a negative value if the
+ *          string is not correctly encoded.  In this last case the string
+ *          may be partially processed.
+ * @param   psz            The string to sanitise.
+ * @param   puszValidSet   A zero-terminated array of pairs of Unicode points.
+ *                         Each pair is the start and end point of a range,
+ *                         and the union of these ranges forms the white list.
+ * @param   chReplacement  The ASCII replacement character.
+ */
+RTDECL(ssize_t) RTStrPurgeComplementSet(char *psz, PCRTUNICP puszValidSet, char chReplacement);
+
+/**
+ * Gets the number of code points the string is made up of, excluding
+ * the terminator.
+ *
+ *
+ * @returns Number of code points (RTUNICP).
+ * @returns 0 if the string was incorrectly encoded.
+ * @param   psz         The string.
+ */
+RTDECL(size_t) RTStrUniLen(const char *psz);
+
+/**
+ * Gets the number of code points the string is made up of, excluding
+ * the terminator.
+ *
+ * This function will validate the string, and incorrectly encoded UTF-8
+ * strings will be rejected.
+ *
+ * @returns iprt status code.
+ * @param   psz         The string.
+ * @param   cch         The max string length. Use RTSTR_MAX to process the entire string.
+ * @param   pcuc        Where to store the code point count.
+ *                      This is undefined on failure.
+ */
+RTDECL(int) RTStrUniLenEx(const char *psz, size_t cch, size_t *pcuc);
+
+/**
+ * Translate a UTF-8 string into an unicode string (i.e. RTUNICPs), allocating the string buffer.
+ *
+ * @returns iprt status code.
+ * @param   pszString       UTF-8 string to convert.
+ * @param   ppUniString     Receives pointer to the allocated unicode string.
+ *                          The returned string must be freed using RTUniFree().
+ */
+RTDECL(int) RTStrToUni(const char *pszString, PRTUNICP *ppUniString);
+
+/**
+ * Translates pszString from UTF-8 to an array of code points, allocating the result
+ * array if requested.
+ *
+ * @returns iprt status code.
+ * @param   pszString       UTF-8 string to convert.
+ * @param   cchString       The maximum size in chars (the type) to convert. The conversion stop
+ *                          when it reaches cchString or the string terminator ('\\0').
+ *                          Use RTSTR_MAX to translate the entire string.
+ * @param   ppaCps          If cCps is non-zero, this must either be pointing to pointer to
+ *                          a buffer of the specified size, or pointer to a NULL pointer.
+ *                          If *ppusz is NULL or cCps is zero a buffer of at least cCps items
+ *                          will be allocated to hold the translated string.
+ *                          If a buffer was requested it must be freed using RTUtf16Free().
+ * @param   cCps            The number of code points in the unicode string. This includes the terminator.
+ * @param   pcCps           Where to store the length of the translated string,
+ *                          excluding the terminator. (Optional)
+ *
+ *                          This may be set under some error conditions,
+ *                          however, only for VERR_BUFFER_OVERFLOW and
+ *                          VERR_NO_STR_MEMORY will it contain a valid string
+ *                          length that can be used to resize the buffer.
+ */
+RTDECL(int)  RTStrToUniEx(const char *pszString, size_t cchString, PRTUNICP *ppaCps, size_t cCps, size_t *pcCps);
+
+/**
+ * Calculates the length of the string in RTUTF16 items.
+ *
+ * This function will validate the string, and incorrectly encoded UTF-8
+ * strings will be rejected. The primary purpose of this function is to
+ * help allocate buffers for RTStrToUtf16Ex of the correct size. For most
+ * other purposes RTStrCalcUtf16LenEx() should be used.
+ *
+ * @returns Number of RTUTF16 items.
+ * @returns 0 if the string was incorrectly encoded.
+ * @param   psz         The string.
+ */
+RTDECL(size_t) RTStrCalcUtf16Len(const char *psz);
+
+/**
+ * Calculates the length of the string in RTUTF16 items.
+ *
+ * This function will validate the string, and incorrectly encoded UTF-8
+ * strings will be rejected.
+ *
+ * @returns iprt status code.
+ * @param   psz         The string.
+ * @param   cch         The max string length. Use RTSTR_MAX to process the entire string.
+ * @param   pcwc        Where to store the string length. Optional.
+ *                      This is undefined on failure.
+ */
+RTDECL(int) RTStrCalcUtf16LenEx(const char *psz, size_t cch, size_t *pcwc);
+
+/**
+ * Translate a UTF-8 string into a UTF-16 allocating the result buffer (default
+ * tag).
+ *
+ * @returns iprt status code.
+ * @param   pszString       UTF-8 string to convert.
+ * @param   ppwszString     Receives pointer to the allocated UTF-16 string.
+ *                          The returned string must be freed using RTUtf16Free().
+ */
+#define RTStrToUtf16(pszString, ppwszString)    RTStrToUtf16Tag((pszString), (ppwszString), RTSTR_TAG)
+
+/**
+ * Translate a UTF-8 string into a UTF-16 allocating the result buffer (custom
+ * tag).
+ *
+ * @returns iprt status code.
+ * @param   pszString       UTF-8 string to convert.
+ * @param   ppwszString     Receives pointer to the allocated UTF-16 string.
+ *                          The returned string must be freed using RTUtf16Free().
+ * @param   pszTag          Allocation tag used for statistics and such.
+ */
+RTDECL(int) RTStrToUtf16Tag(const char *pszString, PRTUTF16 *ppwszString, const char *pszTag);
+
+/**
+ * Translates pszString from UTF-8 to UTF-16, allocating the result buffer if requested.
+ *
+ * @returns iprt status code.
+ * @param   pszString       UTF-8 string to convert.
+ * @param   cchString       The maximum size in chars (the type) to convert. The conversion stop
+ *                          when it reaches cchString or the string terminator ('\\0').
+ *                          Use RTSTR_MAX to translate the entire string.
+ * @param   ppwsz           If cwc is non-zero, this must either be pointing to pointer to
+ *                          a buffer of the specified size, or pointer to a NULL pointer.
+ *                          If *ppwsz is NULL or cwc is zero a buffer of at least cwc items
+ *                          will be allocated to hold the translated string.
+ *                          If a buffer was requested it must be freed using RTUtf16Free().
+ * @param   cwc             The buffer size in RTUTF16s. This includes the terminator.
+ * @param   pcwc            Where to store the length of the translated string,
+ *                          excluding the terminator. (Optional)
+ *
+ *                          This may be set under some error conditions,
+ *                          however, only for VERR_BUFFER_OVERFLOW and
+ *                          VERR_NO_STR_MEMORY will it contain a valid string
+ *                          length that can be used to resize the buffer.
+ */
+#define RTStrToUtf16Ex(pszString, cchString, ppwsz, cwc, pcwc) \
+    RTStrToUtf16ExTag((pszString), (cchString), (ppwsz), (cwc), (pcwc), RTSTR_TAG)
+
+/**
+ * Translates pszString from UTF-8 to UTF-16, allocating the result buffer if
+ * requested (custom tag).
+ *
+ * @returns iprt status code.
+ * @param   pszString       UTF-8 string to convert.
+ * @param   cchString       The maximum size in chars (the type) to convert. The conversion stop
+ *                          when it reaches cchString or the string terminator ('\\0').
+ *                          Use RTSTR_MAX to translate the entire string.
+ * @param   ppwsz           If cwc is non-zero, this must either be pointing to pointer to
+ *                          a buffer of the specified size, or pointer to a NULL pointer.
+ *                          If *ppwsz is NULL or cwc is zero a buffer of at least cwc items
+ *                          will be allocated to hold the translated string.
+ *                          If a buffer was requested it must be freed using RTUtf16Free().
+ * @param   cwc             The buffer size in RTUTF16s. This includes the terminator.
+ * @param   pcwc            Where to store the length of the translated string,
+ *                          excluding the terminator. (Optional)
+ *
+ *                          This may be set under some error conditions,
+ *                          however, only for VERR_BUFFER_OVERFLOW and
+ *                          VERR_NO_STR_MEMORY will it contain a valid string
+ *                          length that can be used to resize the buffer.
+ * @param   pszTag          Allocation tag used for statistics and such.
+ */
+RTDECL(int)  RTStrToUtf16ExTag(const char *pszString, size_t cchString, PRTUTF16 *ppwsz, size_t cwc, size_t *pcwc, const char *pszTag);
+
+
+/**
+ * Calculates the length of the string in Latin-1 characters.
+ *
+ * This function will validate the string, and incorrectly encoded UTF-8
+ * strings as well as string with codepoints outside the latin-1 range will be
+ * rejected.  The primary purpose of this function is to help allocate buffers
+ * for RTStrToLatin1Ex of the correct size.  For most other purposes
+ * RTStrCalcLatin1LenEx() should be used.
+ *
+ * @returns Number of Latin-1 characters.
+ * @returns 0 if the string was incorrectly encoded.
+ * @param   psz         The string.
+ */
+RTDECL(size_t) RTStrCalcLatin1Len(const char *psz);
+
+/**
+ * Calculates the length of the string in Latin-1 characters.
+ *
+ * This function will validate the string, and incorrectly encoded UTF-8
+ * strings as well as string with codepoints outside the latin-1 range will be
+ * rejected.
+ *
+ * @returns iprt status code.
+ * @param   psz         The string.
+ * @param   cch         The max string length. Use RTSTR_MAX to process the
+ *                      entire string.
+ * @param   pcch        Where to store the string length. Optional.
+ *                      This is undefined on failure.
+ */
+RTDECL(int) RTStrCalcLatin1LenEx(const char *psz, size_t cch, size_t *pcch);
+
+/**
+ * Translate a UTF-8 string into a Latin-1 allocating the result buffer (default
+ * tag).
+ *
+ * @returns iprt status code.
+ * @param   pszString       UTF-8 string to convert.
+ * @param   ppszString      Receives pointer to the allocated Latin-1 string.
+ *                          The returned string must be freed using RTStrFree().
+ */
+#define RTStrToLatin1(pszString, ppszString)    RTStrToLatin1Tag((pszString), (ppszString), RTSTR_TAG)
+
+/**
+ * Translate a UTF-8 string into a Latin-1 allocating the result buffer (custom
+ * tag).
+ *
+ * @returns iprt status code.
+ * @param   pszString       UTF-8 string to convert.
+ * @param   ppszString      Receives pointer to the allocated Latin-1 string.
+ *                          The returned string must be freed using RTStrFree().
+ * @param   pszTag          Allocation tag used for statistics and such.
+ */
+RTDECL(int) RTStrToLatin1Tag(const char *pszString, char **ppszString, const char *pszTag);
+
+/**
+ * Translates pszString from UTF-8 to Latin-1, allocating the result buffer if requested.
+ *
+ * @returns iprt status code.
+ * @param   pszString       UTF-8 string to convert.
+ * @param   cchString       The maximum size in chars (the type) to convert.
+ *                          The conversion stop when it reaches cchString or
+ *                          the string terminator ('\\0'). Use RTSTR_MAX to
+ *                          translate the entire string.
+ * @param   ppsz            If cch is non-zero, this must either be pointing to
+ *                          pointer to a buffer of the specified size, or
+ *                          pointer to a NULL pointer.  If *ppsz is NULL or cch
+ *                          is zero a buffer of at least cch items will be
+ *                          allocated to hold the translated string. If a
+ *                          buffer was requested it must be freed using
+ *                          RTStrFree().
+ * @param   cch             The buffer size in bytes. This includes the
+ *                          terminator.
+ * @param   pcch            Where to store the length of the translated string,
+ *                          excluding the terminator. (Optional)
+ *
+ *                          This may be set under some error conditions,
+ *                          however, only for VERR_BUFFER_OVERFLOW and
+ *                          VERR_NO_STR_MEMORY will it contain a valid string
+ *                          length that can be used to resize the buffer.
+ */
+#define RTStrToLatin1Ex(pszString, cchString, ppsz, cch, pcch) \
+    RTStrToLatin1ExTag((pszString), (cchString), (ppsz), (cch), (pcch), RTSTR_TAG)
+
+/**
+ * Translates pszString from UTF-8 to Latin1, allocating the result buffer if
+ * requested (custom tag).
+ *
+ * @returns iprt status code.
+ * @param   pszString       UTF-8 string to convert.
+ * @param   cchString       The maximum size in chars (the type) to convert.
+ *                          The conversion stop when it reaches cchString or
+ *                          the string terminator ('\\0'). Use RTSTR_MAX to
+ *                          translate the entire string.
+ * @param   ppsz            If cch is non-zero, this must either be pointing to
+ *                          pointer to a buffer of the specified size, or
+ *                          pointer to a NULL pointer.  If *ppsz is NULL or cch
+ *                          is zero a buffer of at least cch items will be
+ *                          allocated to hold the translated string. If a
+ *                          buffer was requested it must be freed using
+ *                          RTStrFree().
+ * @param   cch             The buffer size in bytes.  This includes the
+ *                          terminator.
+ * @param   pcch            Where to store the length of the translated string,
+ *                          excluding the terminator. (Optional)
+ *
+ *                          This may be set under some error conditions,
+ *                          however, only for VERR_BUFFER_OVERFLOW and
+ *                          VERR_NO_STR_MEMORY will it contain a valid string
+ *                          length that can be used to resize the buffer.
+ * @param   pszTag          Allocation tag used for statistics and such.
+ */
+RTDECL(int)  RTStrToLatin1ExTag(const char *pszString, size_t cchString, char **ppsz, size_t cch, size_t *pcch, const char *pszTag);
+
+/**
+ * Get the unicode code point at the given string position.
+ *
+ * @returns unicode code point.
+ * @returns RTUNICP_INVALID if the encoding is invalid.
+ * @param   psz         The string.
+ */
+RTDECL(RTUNICP) RTStrGetCpInternal(const char *psz);
+
+/**
+ * Get the unicode code point at the given string position.
+ *
+ * @returns iprt status code
+ * @returns VERR_INVALID_UTF8_ENCODING if the encoding is invalid.
+ * @param   ppsz        The string cursor.
+ *                      This is advanced one character forward on failure.
+ * @param   pCp         Where to store the unicode code point.
+ *                      Stores RTUNICP_INVALID if the encoding is invalid.
+ */
+RTDECL(int) RTStrGetCpExInternal(const char **ppsz, PRTUNICP pCp);
+
+/**
+ * Get the unicode code point at the given string position for a string of a
+ * given length.
+ *
+ * @returns iprt status code
+ * @retval  VERR_INVALID_UTF8_ENCODING if the encoding is invalid.
+ * @retval  VERR_END_OF_STRING if *pcch is 0. *pCp is set to RTUNICP_INVALID.
+ *
+ * @param   ppsz        The string.
+ * @param   pcch        Pointer to the length of the string.  This will be
+ *                      decremented by the size of the code point.
+ * @param   pCp         Where to store the unicode code point.
+ *                      Stores RTUNICP_INVALID if the encoding is invalid.
+ */
+RTDECL(int) RTStrGetCpNExInternal(const char **ppsz, size_t *pcch, PRTUNICP pCp);
+
+/**
+ * Put the unicode code point at the given string position
+ * and return the pointer to the char following it.
+ *
+ * This function will not consider anything at or following the
+ * buffer area pointed to by psz. It is therefore not suitable for
+ * inserting code points into a string, only appending/overwriting.
+ *
+ * @returns pointer to the char following the written code point.
+ * @param   psz         The string.
+ * @param   CodePoint   The code point to write.
+ *                      This should not be RTUNICP_INVALID or any other
+ *                      character out of the UTF-8 range.
+ *
+ * @remark  This is a worker function for RTStrPutCp().
+ *
+ */
+RTDECL(char *) RTStrPutCpInternal(char *psz, RTUNICP CodePoint);
+
+/**
+ * Get the unicode code point at the given string position.
+ *
+ * @returns unicode code point.
+ * @returns RTUNICP_INVALID if the encoding is invalid.
+ * @param   psz         The string.
+ *
+ * @remark  We optimize this operation by using an inline function for
+ *          the most frequent and simplest sequence, the rest is
+ *          handled by RTStrGetCpInternal().
+ */
+DECLINLINE(RTUNICP) RTStrGetCp(const char *psz)
+{
+    const unsigned char uch = *(const unsigned char *)psz;
+    if (!(uch & RT_BIT(7)))
+        return uch;
+    return RTStrGetCpInternal(psz);
+}
+
+/**
+ * Get the unicode code point at the given string position.
+ *
+ * @returns iprt status code.
+ * @param   ppsz        Pointer to the string pointer. This will be updated to
+ *                      point to the char following the current code point.
+ *                      This is advanced one character forward on failure.
+ * @param   pCp         Where to store the code point.
+ *                      RTUNICP_INVALID is stored here on failure.
+ *
+ * @remark  We optimize this operation by using an inline function for
+ *          the most frequent and simplest sequence, the rest is
+ *          handled by RTStrGetCpExInternal().
+ */
+DECLINLINE(int) RTStrGetCpEx(const char **ppsz, PRTUNICP pCp)
+{
+    const unsigned char uch = **(const unsigned char **)ppsz;
+    if (!(uch & RT_BIT(7)))
+    {
+        (*ppsz)++;
+        *pCp = uch;
+        return VINF_SUCCESS;
+    }
+    return RTStrGetCpExInternal(ppsz, pCp);
+}
+
+/**
+ * Get the unicode code point at the given string position for a string of a
+ * given maximum length.
+ *
+ * @returns iprt status code.
+ * @retval  VERR_INVALID_UTF8_ENCODING if the encoding is invalid.
+ * @retval  VERR_END_OF_STRING if *pcch is 0. *pCp is set to RTUNICP_INVALID.
+ *
+ * @param   ppsz        Pointer to the string pointer. This will be updated to
+ *                      point to the char following the current code point.
+ * @param   pcch        Pointer to the maximum string length.  This will be
+ *                      decremented by the size of the code point found.
+ * @param   pCp         Where to store the code point.
+ *                      RTUNICP_INVALID is stored here on failure.
+ *
+ * @remark  We optimize this operation by using an inline function for
+ *          the most frequent and simplest sequence, the rest is
+ *          handled by RTStrGetCpNExInternal().
+ */
+DECLINLINE(int) RTStrGetCpNEx(const char **ppsz, size_t *pcch, PRTUNICP pCp)
+{
+    if (RT_LIKELY(*pcch != 0))
+    {
+        const unsigned char uch = **(const unsigned char **)ppsz;
+        if (!(uch & RT_BIT(7)))
+        {
+            (*ppsz)++;
+            (*pcch)--;
+            *pCp = uch;
+            return VINF_SUCCESS;
+        }
+    }
+    return RTStrGetCpNExInternal(ppsz, pcch, pCp);
+}
+
+/**
+ * Get the UTF-8 size in characters of a given Unicode code point.
+ *
+ * The code point is expected to be a valid Unicode one, but not necessarily in
+ * the range supported by UTF-8.
+ *
+ * @returns The number of chars (bytes) required to encode the code point, or
+ *          zero if there is no UTF-8 encoding.
+ * @param   CodePoint       The unicode code point.
+ */
+DECLINLINE(size_t) RTStrCpSize(RTUNICP CodePoint)
+{
+    if (CodePoint < 0x00000080)
+        return 1;
+    if (CodePoint < 0x00000800)
+        return 2;
+    if (CodePoint < 0x00010000)
+        return 3;
+#ifdef RT_USE_RTC_3629
+    if (CodePoint < 0x00011000)
+        return 4;
+#else
+    if (CodePoint < 0x00200000)
+        return 4;
+    if (CodePoint < 0x04000000)
+        return 5;
+    if (CodePoint < 0x7fffffff)
+        return 6;
+#endif
+    return 0;
+}
+
+/**
+ * Put the unicode code point at the given string position
+ * and return the pointer to the char following it.
+ *
+ * This function will not consider anything at or following the
+ * buffer area pointed to by psz. It is therefore not suitable for
+ * inserting code points into a string, only appending/overwriting.
+ *
+ * @returns pointer to the char following the written code point.
+ * @param   psz         The string.
+ * @param   CodePoint   The code point to write.
+ *                      This should not be RTUNICP_INVALID or any other
+ *                      character out of the UTF-8 range.
+ *
+ * @remark  We optimize this operation by using an inline function for
+ *          the most frequent and simplest sequence, the rest is
+ *          handled by RTStrPutCpInternal().
+ */
+DECLINLINE(char *) RTStrPutCp(char *psz, RTUNICP CodePoint)
+{
+    if (CodePoint < 0x80)
+    {
+        *psz++ = (unsigned char)CodePoint;
+        return psz;
+    }
+    return RTStrPutCpInternal(psz, CodePoint);
+}
+
+/**
+ * Skips ahead, past the current code point.
+ *
+ * @returns Pointer to the char after the current code point.
+ * @param   psz     Pointer to the current code point.
+ * @remark  This will not move the next valid code point, only past the current one.
+ */
+DECLINLINE(char *) RTStrNextCp(const char *psz)
+{
+    RTUNICP Cp;
+    RTStrGetCpEx(&psz, &Cp);
+    return (char *)psz;
+}
+
+/**
+ * Skips back to the previous code point.
+ *
+ * @returns Pointer to the char before the current code point.
+ * @returns pszStart on failure.
+ * @param   pszStart    Pointer to the start of the string.
+ * @param   psz         Pointer to the current code point.
+ */
+RTDECL(char *) RTStrPrevCp(const char *pszStart, const char *psz);
+
+
+/** @page pg_rt_str_format  The IPRT Format Strings
+ *
+ * IPRT implements most of the commonly used format types and flags with the
+ * exception of floating point which is completely missing.  In addition IPRT
+ * provides a number of IPRT specific format types for the IPRT typedefs and
+ * other useful things.  Note that several of these extensions are similar to
+ * \%p and doesn't care much if you try add formating flags/width/precision.
+ *
+ *
+ * Group 0a, The commonly used format types:
+ *      - \%s   - Takes a pointer to a zero terminated string (UTF-8) and
+ *                prints it with the optionally adjustment (width, -) and
+ *                length restriction (precision).
+ *      - \%ls  - Same as \%s except that the input is UTF-16 (output UTF-8).
+ *      - \%Ls  - Same as \%s except that the input is UCS-32 (output UTF-8).
+ *      - \%S   - Same as \%s, used to convert to current codeset but this is
+ *                now done by the streams code.  Deprecated, use \%s.
+ *      - \%lS  - Ditto. Deprecated, use \%ls.
+ *      - \%LS  - Ditto. Deprecated, use \%Ls.
+ *      - \%c   - Takes a char and prints it.
+ *      - \%d   - Takes a signed integer and prints it as decimal. Thousand
+ *                separator (\'), zero padding (0), adjustment (-+), width,
+ *                precision
+ *      - \%i   - Same as \%d.
+ *      - \%u   - Takes an unsigned integer and prints it as decimal. Thousand
+ *                separator (\'), zero padding (0), adjustment (-+), width,
+ *                precision
+ *      - \%x   - Takes an unsigned integer and prints it as lowercased
+ *                hexadecimal.  The special hash (\#) flag causes a '0x'
+ *                prefixed to be printed. Zero padding (0), adjustment (-+),
+ *                width, precision.
+ *      - \%X   - Same as \%x except that it is uppercased.
+ *      - \%o   - Takes an unsigned (?) integer and prints it as octal. Zero
+ *                padding (0), adjustment (-+), width, precision.
+ *      - \%p   - Takes a pointer (void technically) and prints it. Zero
+ *                padding (0), adjustment (-+), width, precision.
+ *
+ * The \%d, \%i, \%u, \%x, \%X and \%o format types support the following
+ * argument type specifiers:
+ *      - \%ll  - long long (uint64_t).
+ *      - \%L   - long long (uint64_t).
+ *      - \%l   - long (uint32_t, uint64_t)
+ *      - \%h   - short (int16_t).
+ *      - \%hh  - char (int8_t).
+ *      - \%H   - char (int8_t).
+ *      - \%z   - size_t.
+ *      - \%j   - intmax_t (int64_t).
+ *      - \%t   - ptrdiff_t.
+ * The type in parentheses is typical sizes, however when printing those types
+ * you are better off using the special group 2 format types below (\%RX32 and
+ * such).
+ *
+ *
+ * Group 0b, IPRT format tricks:
+ *      - %M    - Replaces the format string, takes a string pointer.
+ *      - %N    - Nested formatting, takes a pointer to a format string
+ *                followed by the pointer to a va_list variable.  The va_list
+ *                variable will not be modified and the caller must do va_end()
+ *                on it.  Make sure the va_list variable is NOT in a parameter
+ *                list or some gcc versions/targets may get it all wrong.
+ *
+ *
+ * Group 1, the basic runtime typedefs (excluding those which obviously are
+ * pointer):
+ *      - \%RTbool          - Takes a bool value and prints 'true', 'false', or '!%d!'.
+ *      - \%RTfile          - Takes a #RTFILE value.
+ *      - \%RTfmode         - Takes a #RTFMODE value.
+ *      - \%RTfoff          - Takes a #RTFOFF value.
+ *      - \%RTfp16          - Takes a #RTFAR16 value.
+ *      - \%RTfp32          - Takes a #RTFAR32 value.
+ *      - \%RTfp64          - Takes a #RTFAR64 value.
+ *      - \%RTgid           - Takes a #RTGID value.
+ *      - \%RTino           - Takes a #RTINODE value.
+ *      - \%RTint           - Takes a #RTINT value.
+ *      - \%RTiop           - Takes a #RTIOPORT value.
+ *      - \%RTldrm          - Takes a #RTLDRMOD value.
+ *      - \%RTmac           - Takes a #PCRTMAC pointer.
+ *      - \%RTnaddr         - Takes a #PCRTNETADDR value.
+ *      - \%RTnaipv4        - Takes a #RTNETADDRIPV4 value.
+ *      - \%RTnaipv6        - Takes a #PCRTNETADDRIPV6 value.
+ *      - \%RTnthrd         - Takes a #RTNATIVETHREAD value.
+ *      - \%RTnthrd         - Takes a #RTNATIVETHREAD value.
+ *      - \%RTproc          - Takes a #RTPROCESS value.
+ *      - \%RTptr           - Takes a #RTINTPTR or #RTUINTPTR value (but not void *).
+ *      - \%RTreg           - Takes a #RTCCUINTREG value.
+ *      - \%RTsel           - Takes a #RTSEL value.
+ *      - \%RTsem           - Takes a #RTSEMEVENT, #RTSEMEVENTMULTI, #RTSEMMUTEX, #RTSEMFASTMUTEX, or #RTSEMRW value.
+ *      - \%RTsock          - Takes a #RTSOCKET value.
+ *      - \%RTthrd          - Takes a #RTTHREAD value.
+ *      - \%RTuid           - Takes a #RTUID value.
+ *      - \%RTuint          - Takes a #RTUINT value.
+ *      - \%RTunicp         - Takes a #RTUNICP value.
+ *      - \%RTutf16         - Takes a #RTUTF16 value.
+ *      - \%RTuuid          - Takes a #PCRTUUID and will print the UUID as a string.
+ *      - \%RTxuint         - Takes a #RTUINT or #RTINT value, formatting it as hex.
+ *      - \%RGi             - Takes a #RTGCINT value.
+ *      - \%RGp             - Takes a #RTGCPHYS value.
+ *      - \%RGr             - Takes a #RTGCUINTREG value.
+ *      - \%RGu             - Takes a #RTGCUINT value.
+ *      - \%RGv             - Takes a #RTGCPTR, #RTGCINTPTR or #RTGCUINTPTR value.
+ *      - \%RGx             - Takes a #RTGCUINT or #RTGCINT value, formatting it as hex.
+ *      - \%RHi             - Takes a #RTHCINT value.
+ *      - \%RHp             - Takes a #RTHCPHYS value.
+ *      - \%RHr             - Takes a #RTHCUINTREG value.
+ *      - \%RHu             - Takes a #RTHCUINT value.
+ *      - \%RHv             - Takes a #RTHCPTR, #RTHCINTPTR or #RTHCUINTPTR value.
+ *      - \%RHx             - Takes a #RTHCUINT or #RTHCINT value, formatting it as hex.
+ *      - \%RRv             - Takes a #RTRCPTR, #RTRCINTPTR or #RTRCUINTPTR value.
+ *      - \%RCi             - Takes a #RTINT value.
+ *      - \%RCp             - Takes a #RTCCPHYS value.
+ *      - \%RCr             - Takes a #RTCCUINTREG value.
+ *      - \%RCu             - Takes a #RTUINT value.
+ *      - \%RCv             - Takes a #uintptr_t, #intptr_t, void * value.
+ *      - \%RCx             - Takes a #RTUINT or #RTINT value, formatting it as hex.
+ *
+ *
+ * Group 2, the generic integer types which are prefered over relying on what
+ * bit-count a 'long', 'short',  or 'long long' has on a platform. This are
+ * highly prefered for the [u]intXX_t kind of types:
+ *      - \%RI[8|16|32|64]  - Signed integer value of the specifed bit count.
+ *      - \%RU[8|16|32|64]  - Unsigned integer value of the specifed bit count.
+ *      - \%RX[8|16|32|64]  - Hexadecimal integer value of the specifed bit count.
+ *
+ *
+ * Group 3, hex dumpers and other complex stuff which requires more than simple
+ * formatting:
+ *      - \%Rhxd            - Takes a pointer to the memory which is to be dumped in typical
+ *                            hex format. Use the precision to specify the length, and the width to
+ *                            set the number of bytes per line. Default width and precision is 16.
+ *      - \%Rhxs            - Takes a pointer to the memory to be displayed as a hex string,
+ *                            i.e. a series of space separated bytes formatted as two digit hex value.
+ *                            Use the precision to specify the length. Default length is 16 bytes.
+ *                            The width, if specified, is ignored.
+ *      - \%Rrc             - Takes an integer iprt status code as argument. Will insert the
+ *                            status code define corresponding to the iprt status code.
+ *      - \%Rrs             - Takes an integer iprt status code as argument. Will insert the
+ *                            short description of the specified status code.
+ *      - \%Rrf             - Takes an integer iprt status code as argument. Will insert the
+ *                            full description of the specified status code.
+ *      - \%Rra             - Takes an integer iprt status code as argument. Will insert the
+ *                            status code define + full description.
+ *      - \%Rwc             - Takes a long Windows error code as argument. Will insert the status
+ *                            code define corresponding to the Windows error code.
+ *      - \%Rwf             - Takes a long Windows error code as argument. Will insert the
+ *                            full description of the specified status code.
+ *      - \%Rwa             - Takes a long Windows error code as argument. Will insert the
+ *                            error code define + full description.
+ *
+ *      - \%Rhrc            - Takes a COM/XPCOM status code as argument. Will insert the status
+ *                            code define corresponding to the Windows error code.
+ *      - \%Rhrf            - Takes a COM/XPCOM status code as argument. Will insert the
+ *                            full description of the specified status code.
+ *      - \%Rhra            - Takes a COM/XPCOM error code as argument. Will insert the
+ *                            error code define + full description.
+ *
+ *      - \%Rfn             - Pretty printing of a function or method. It drops the
+ *                            return code and parameter list.
+ *      - \%Rbn             - Prints the base name.  For dropping the path in
+ *                            order to save space when printing a path name.
+ *
+ * On other platforms, \%Rw? simply prints the argument in a form of 0xXXXXXXXX.
+ *
+ *
+ * Group 4, structure dumpers:
+ *      - \%RDtimespec      - Takes a PCRTTIMESPEC.
+ *
+ *
+ * Group 5, XML / HTML escapers:
+ *      - \%RMas            - Takes a string pointer (const char *) and outputs
+ *                            it as an attribute value with the proper escaping.
+ *                            This typically ends up in double quotes.
+ *
+ *      - \%RMes            - Takes a string pointer (const char *) and outputs
+ *                            it as an element with the necessary escaping.
+ *
+ * Group 6, CPU Architecture Register dumpers:
+ *      - \%RAx86[reg]      - Takes a 64-bit register value if the register is
+ *                            64-bit or smaller.  Check the code wrt which
+ *                            registers are implemented.
+ *
+ */
+
+#ifndef DECLARED_FNRTSTROUTPUT          /* duplicated in iprt/log.h */
+# define DECLARED_FNRTSTROUTPUT
+/**
+ * Output callback.
+ *
+ * @returns number of bytes written.
+ * @param   pvArg       User argument.
+ * @param   pachChars   Pointer to an array of utf-8 characters.
+ * @param   cbChars     Number of bytes in the character array pointed to by pachChars.
+ */
+typedef DECLCALLBACK(size_t) FNRTSTROUTPUT(void *pvArg, const char *pachChars, size_t cbChars);
+/** Pointer to callback function. */
+typedef FNRTSTROUTPUT *PFNRTSTROUTPUT;
+#endif
+
+/** @name Format flag.
+ * These are used by RTStrFormat extensions and RTStrFormatNumber, mind
+ * that not all flags makes sense to both of the functions.
+ * @{ */
+#define RTSTR_F_CAPITAL         0x0001
+#define RTSTR_F_LEFT            0x0002
+#define RTSTR_F_ZEROPAD         0x0004
+#define RTSTR_F_SPECIAL         0x0008
+#define RTSTR_F_VALSIGNED       0x0010
+#define RTSTR_F_PLUS            0x0020
+#define RTSTR_F_BLANK           0x0040
+#define RTSTR_F_WIDTH           0x0080
+#define RTSTR_F_PRECISION       0x0100
+#define RTSTR_F_THOUSAND_SEP    0x0200
+
+#define RTSTR_F_BIT_MASK        0xf800
+#define RTSTR_F_8BIT            0x0800
+#define RTSTR_F_16BIT           0x1000
+#define RTSTR_F_32BIT           0x2000
+#define RTSTR_F_64BIT           0x4000
+#define RTSTR_F_128BIT          0x8000
+/** @} */
+
+/** @def RTSTR_GET_BIT_FLAG
+ * Gets the bit flag for the specified type.
+ */
+#define RTSTR_GET_BIT_FLAG(type) \
+    ( sizeof(type) * 8 == 32  ? RTSTR_F_32BIT \
+    : sizeof(type) * 8 == 64  ? RTSTR_F_64BIT \
+    : sizeof(type) * 8 == 16  ? RTSTR_F_16BIT \
+    : sizeof(type) * 8 == 8   ? RTSTR_F_8BIT \
+    : sizeof(type) * 8 == 128 ? RTSTR_F_128BIT \
+    : 0)
+
+
+/**
+ * Callback to format non-standard format specifiers.
+ *
+ * @returns The number of bytes formatted.
+ * @param   pvArg           Formatter argument.
+ * @param   pfnOutput       Pointer to output function.
+ * @param   pvArgOutput     Argument for the output function.
+ * @param   ppszFormat      Pointer to the format string pointer. Advance this till the char
+ *                          after the format specifier.
+ * @param   pArgs           Pointer to the argument list. Use this to fetch the arguments.
+ * @param   cchWidth        Format Width. -1 if not specified.
+ * @param   cchPrecision    Format Precision. -1 if not specified.
+ * @param   fFlags          Flags (RTSTR_NTFS_*).
+ * @param   chArgSize       The argument size specifier, 'l' or 'L'.
+ */
+typedef DECLCALLBACK(size_t) FNSTRFORMAT(void *pvArg, PFNRTSTROUTPUT pfnOutput, void *pvArgOutput,
+                                         const char **ppszFormat, va_list *pArgs, int cchWidth,
+                                         int cchPrecision, unsigned fFlags, char chArgSize);
+/** Pointer to a FNSTRFORMAT() function. */
+typedef FNSTRFORMAT *PFNSTRFORMAT;
+
+
+/**
+ * Partial implementation of a printf like formatter.
+ * It doesn't do everything correct, and there is no floating point support.
+ * However, it supports custom formats by the means of a format callback.
+ *
+ * @returns number of bytes formatted.
+ * @param   pfnOutput   Output worker.
+ *                      Called in two ways. Normally with a string and its length.
+ *                      For termination, it's called with NULL for string, 0 for length.
+ * @param   pvArgOutput Argument to the output worker.
+ * @param   pfnFormat   Custom format worker.
+ * @param   pvArgFormat Argument to the format worker.
+ * @param   pszFormat   Pointer to the format string, @see pg_rt_str_format.
+ * @param   InArgs      Argument list.
+ */
+RTDECL(size_t) RTStrFormatV(PFNRTSTROUTPUT pfnOutput, void *pvArgOutput, PFNSTRFORMAT pfnFormat, void *pvArgFormat,
+                            const char *pszFormat, va_list InArgs) RT_IPRT_FORMAT_ATTR(5, 0);
+
+/**
+ * Partial implementation of a printf like formatter.
+ * It doesn't do everything correct, and there is no floating point support.
+ * However, it supports custom formats by the means of a format callback.
+ *
+ * @returns number of bytes formatted.
+ * @param   pfnOutput   Output worker.
+ *                      Called in two ways. Normally with a string and its length.
+ *                      For termination, it's called with NULL for string, 0 for length.
+ * @param   pvArgOutput Argument to the output worker.
+ * @param   pfnFormat   Custom format worker.
+ * @param   pvArgFormat Argument to the format worker.
+ * @param   pszFormat   Pointer to the format string, @see pg_rt_str_format.
+ * @param   ...         Argument list.
+ */
+RTDECL(size_t) RTStrFormat(PFNRTSTROUTPUT pfnOutput, void *pvArgOutput, PFNSTRFORMAT pfnFormat, void *pvArgFormat,
+                           const char *pszFormat, ...) RT_IPRT_FORMAT_ATTR(5, 6);
+
+/**
+ * Formats an integer number according to the parameters.
+ *
+ * @returns Length of the formatted number.
+ * @param   psz             Pointer to output string buffer of sufficient size.
+ * @param   u64Value        Value to format.
+ * @param   uiBase          Number representation base.
+ * @param   cchWidth        Width.
+ * @param   cchPrecision    Precision.
+ * @param   fFlags          Flags, RTSTR_F_XXX.
+ */
+RTDECL(int) RTStrFormatNumber(char *psz, uint64_t u64Value, unsigned int uiBase, signed int cchWidth, signed int cchPrecision,
+                              unsigned int fFlags);
+
+/**
+ * Formats an unsigned 8-bit number.
+ *
+ * @returns The length of the formatted number or VERR_BUFFER_OVERFLOW.
+ * @param   pszBuf          The output buffer.
+ * @param   cbBuf           The size of the output buffer.
+ * @param   u8Value         The value to format.
+ * @param   uiBase          Number representation base.
+ * @param   cchWidth        Width.
+ * @param   cchPrecision    Precision.
+ * @param   fFlags          Flags, RTSTR_F_XXX.
+ */
+RTDECL(ssize_t) RTStrFormatU8(char *pszBuf, size_t cbBuf, uint8_t u8Value, unsigned int uiBase,
+                              signed int cchWidth, signed int cchPrecision, uint32_t fFlags);
+
+/**
+ * Formats an unsigned 16-bit number.
+ *
+ * @returns The length of the formatted number or VERR_BUFFER_OVERFLOW.
+ * @param   pszBuf          The output buffer.
+ * @param   cbBuf           The size of the output buffer.
+ * @param   u16Value        The value to format.
+ * @param   uiBase          Number representation base.
+ * @param   cchWidth        Width.
+ * @param   cchPrecision    Precision.
+ * @param   fFlags          Flags, RTSTR_F_XXX.
+ */
+RTDECL(ssize_t) RTStrFormatU16(char *pszBuf, size_t cbBuf, uint16_t u16Value, unsigned int uiBase,
+                               signed int cchWidth, signed int cchPrecision, uint32_t fFlags);
+
+/**
+ * Formats an unsigned 32-bit number.
+ *
+ * @returns The length of the formatted number or VERR_BUFFER_OVERFLOW.
+ * @param   pszBuf          The output buffer.
+ * @param   cbBuf           The size of the output buffer.
+ * @param   u32Value        The value to format.
+ * @param   uiBase          Number representation base.
+ * @param   cchWidth        Width.
+ * @param   cchPrecision    Precision.
+ * @param   fFlags          Flags, RTSTR_F_XXX.
+ */
+RTDECL(ssize_t) RTStrFormatU32(char *pszBuf, size_t cbBuf, uint32_t u32Value, unsigned int uiBase,
+                               signed int cchWidth, signed int cchPrecision, uint32_t fFlags);
+
+/**
+ * Formats an unsigned 64-bit number.
+ *
+ * @returns The length of the formatted number or VERR_BUFFER_OVERFLOW.
+ * @param   pszBuf          The output buffer.
+ * @param   cbBuf           The size of the output buffer.
+ * @param   u64Value        The value to format.
+ * @param   uiBase          Number representation base.
+ * @param   cchWidth        Width.
+ * @param   cchPrecision    Precision.
+ * @param   fFlags          Flags, RTSTR_F_XXX.
+ */
+RTDECL(ssize_t) RTStrFormatU64(char *pszBuf, size_t cbBuf, uint64_t u64Value, unsigned int uiBase,
+                               signed int cchWidth, signed int cchPrecision, uint32_t fFlags);
+
+/**
+ * Formats an unsigned 128-bit number.
+ *
+ * @returns The length of the formatted number or VERR_BUFFER_OVERFLOW.
+ * @param   pszBuf          The output buffer.
+ * @param   cbBuf           The size of the output buffer.
+ * @param   pu128Value      The value to format.
+ * @param   uiBase          Number representation base.
+ * @param   cchWidth        Width.
+ * @param   cchPrecision    Precision.
+ * @param   fFlags          Flags, RTSTR_F_XXX.
+ */
+RTDECL(ssize_t) RTStrFormatU128(char *pszBuf, size_t cbBuf, PCRTUINT128U pu128Value, unsigned int uiBase,
+                                signed int cchWidth, signed int cchPrecision, uint32_t fFlags);
+
+/**
+ * Formats an 80-bit extended floating point number.
+ *
+ * @returns The length of the formatted number or VERR_BUFFER_OVERFLOW.
+ * @param   pszBuf          The output buffer.
+ * @param   cbBuf           The size of the output buffer.
+ * @param   pr80Value       The value to format.
+ * @param   cchWidth        Width.
+ * @param   cchPrecision    Precision.
+ * @param   fFlags          Flags, RTSTR_F_XXX.
+ */
+RTDECL(ssize_t) RTStrFormatR80(char *pszBuf, size_t cbBuf, PCRTFLOAT80U pr80Value, signed int cchWidth,
+                               signed int cchPrecision, uint32_t fFlags);
+
+/**
+ * Formats an 80-bit extended floating point number, version 2.
+ *
+ * @returns The length of the formatted number or VERR_BUFFER_OVERFLOW.
+ * @param   pszBuf          The output buffer.
+ * @param   cbBuf           The size of the output buffer.
+ * @param   pr80Value       The value to format.
+ * @param   cchWidth        Width.
+ * @param   cchPrecision    Precision.
+ * @param   fFlags          Flags, RTSTR_F_XXX.
+ */
+RTDECL(ssize_t) RTStrFormatR80u2(char *pszBuf, size_t cbBuf, PCRTFLOAT80U2 pr80Value, signed int cchWidth,
+                                 signed int cchPrecision, uint32_t fFlags);
+
+
+
+/**
+ * Callback for formatting a type.
+ *
+ * This is registered using the RTStrFormatTypeRegister function and will
+ * be called during string formatting to handle the specified %R[type].
+ * The argument for this format type is assumed to be a pointer and it's
+ * passed in the @a pvValue argument.
+ *
+ * @returns Length of the formatted output.
+ * @param   pfnOutput       Output worker.
+ * @param   pvArgOutput     Argument to the output worker.
+ * @param   pszType         The type name.
+ * @param   pvValue         The argument value.
+ * @param   cchWidth        Width.
+ * @param   cchPrecision    Precision.
+ * @param   fFlags          Flags (NTFS_*).
+ * @param   pvUser          The user argument.
+ */
+typedef DECLCALLBACK(size_t) FNRTSTRFORMATTYPE(PFNRTSTROUTPUT pfnOutput, void *pvArgOutput,
+                                               const char *pszType, void const *pvValue,
+                                               int cchWidth, int cchPrecision, unsigned fFlags,
+                                               void *pvUser);
+/** Pointer to a FNRTSTRFORMATTYPE. */
+typedef FNRTSTRFORMATTYPE *PFNRTSTRFORMATTYPE;
+
+
+/**
+ * Register a format handler for a type.
+ *
+ * The format handler is used to handle '%R[type]' format types, where the argument
+ * in the vector is a pointer value (a bit restrictive, but keeps it simple).
+ *
+ * The caller must ensure that no other thread will be making use of any of
+ * the dynamic formatting type facilities simultaneously with this call.
+ *
+ * @returns IPRT status code.
+ * @retval  VINF_SUCCESS on success.
+ * @retval  VERR_ALREADY_EXISTS if the type has already been registered.
+ * @retval  VERR_TOO_MANY_OPEN_FILES if all the type slots has been allocated already.
+ *
+ * @param   pszType         The type name.
+ * @param   pfnHandler      The handler address. See FNRTSTRFORMATTYPE for details.
+ * @param   pvUser          The user argument to pass to the handler. See RTStrFormatTypeSetUser
+ *                          for how to update this later.
+ */
+RTDECL(int) RTStrFormatTypeRegister(const char *pszType, PFNRTSTRFORMATTYPE pfnHandler, void *pvUser);
+
+/**
+ * Deregisters a format type.
+ *
+ * The caller must ensure that no other thread will be making use of any of
+ * the dynamic formatting type facilities simultaneously with this call.
+ *
+ * @returns IPRT status code.
+ * @retval  VINF_SUCCESS on success.
+ * @retval  VERR_FILE_NOT_FOUND if not found.
+ *
+ * @param   pszType     The type to deregister.
+ */
+RTDECL(int) RTStrFormatTypeDeregister(const char *pszType);
+
+/**
+ * Sets the user argument for a type.
+ *
+ * This can be used if a user argument needs relocating in GC.
+ *
+ * @returns IPRT status code.
+ * @retval  VINF_SUCCESS on success.
+ * @retval  VERR_FILE_NOT_FOUND if not found.
+ *
+ * @param   pszType     The type to update.
+ * @param   pvUser      The new user argument value.
+ */
+RTDECL(int) RTStrFormatTypeSetUser(const char *pszType, void *pvUser);
+
+
+/**
+ * String printf.
+ *
+ * @returns The length of the returned string (in pszBuffer) excluding the
+ *          terminator.
+ * @param   pszBuffer   Output buffer.
+ * @param   cchBuffer   Size of the output buffer.
+ * @param   pszFormat   Pointer to the format string, @see pg_rt_str_format.
+ * @param   args        The format argument.
+ */
+RTDECL(size_t) RTStrPrintfV(char *pszBuffer, size_t cchBuffer, const char *pszFormat, va_list args) RT_IPRT_FORMAT_ATTR(3, 0);
+
+/**
+ * String printf.
+ *
+ * @returns The length of the returned string (in pszBuffer) excluding the
+ *          terminator.
+ * @param   pszBuffer   Output buffer.
+ * @param   cchBuffer   Size of the output buffer.
+ * @param   pszFormat   Pointer to the format string, @see pg_rt_str_format.
+ * @param   ...         The format argument.
+ */
+RTDECL(size_t) RTStrPrintf(char *pszBuffer, size_t cchBuffer, const char *pszFormat, ...) RT_IPRT_FORMAT_ATTR(3, 4);
+
+
+/**
+ * String printf with custom formatting.
+ *
+ * @returns The length of the returned string (in pszBuffer) excluding the
+ *          terminator.
+ * @param   pfnFormat   Pointer to handler function for the custom formats.
+ * @param   pvArg       Argument to the pfnFormat function.
+ * @param   pszBuffer   Output buffer.
+ * @param   cchBuffer   Size of the output buffer.
+ * @param   pszFormat   Pointer to the format string, @see pg_rt_str_format.
+ * @param   args        The format argument.
+ */
+RTDECL(size_t) RTStrPrintfExV(PFNSTRFORMAT pfnFormat, void *pvArg, char *pszBuffer, size_t cchBuffer,
+                              const char *pszFormat, va_list args)  RT_IPRT_FORMAT_ATTR(5, 0);
+
+/**
+ * String printf with custom formatting.
+ *
+ * @returns The length of the returned string (in pszBuffer) excluding the
+ *          terminator.
+ * @param   pfnFormat   Pointer to handler function for the custom formats.
+ * @param   pvArg       Argument to the pfnFormat function.
+ * @param   pszBuffer   Output buffer.
+ * @param   cchBuffer   Size of the output buffer.
+ * @param   pszFormat   Pointer to the format string, @see pg_rt_str_format.
+ * @param   ...         The format argument.
+ */
+RTDECL(size_t) RTStrPrintfEx(PFNSTRFORMAT pfnFormat, void *pvArg, char *pszBuffer, size_t cchBuffer,
+                             const char *pszFormat, ...)  RT_IPRT_FORMAT_ATTR(5, 6);
+
+
+/**
+ * Allocating string printf (default tag).
+ *
+ * @returns The length of the string in the returned *ppszBuffer excluding the
+ *          terminator.
+ * @returns -1 on failure.
+ * @param   ppszBuffer  Where to store the pointer to the allocated output buffer.
+ *                      The buffer should be freed using RTStrFree().
+ *                      On failure *ppszBuffer will be set to NULL.
+ * @param   pszFormat   Pointer to the format string, @see pg_rt_str_format.
+ * @param   args        The format argument.
+ */
+#define RTStrAPrintfV(ppszBuffer, pszFormat, args)      RTStrAPrintfVTag((ppszBuffer), (pszFormat), (args), RTSTR_TAG)
+
+/**
+ * Allocating string printf (custom tag).
+ *
+ * @returns The length of the string in the returned *ppszBuffer excluding the
+ *          terminator.
+ * @returns -1 on failure.
+ * @param   ppszBuffer  Where to store the pointer to the allocated output buffer.
+ *                      The buffer should be freed using RTStrFree().
+ *                      On failure *ppszBuffer will be set to NULL.
+ * @param   pszFormat   Pointer to the format string, @see pg_rt_str_format.
+ * @param   args        The format argument.
+ * @param   pszTag      Allocation tag used for statistics and such.
+ */
+RTDECL(int) RTStrAPrintfVTag(char **ppszBuffer, const char *pszFormat, va_list args, const char *pszTag) RT_IPRT_FORMAT_ATTR(2, 0);
+
+/**
+ * Allocating string printf.
+ *
+ * @returns The length of the string in the returned *ppszBuffer excluding the
+ *          terminator.
+ * @returns -1 on failure.
+ * @param   ppszBuffer  Where to store the pointer to the allocated output buffer.
+ *                      The buffer should be freed using RTStrFree().
+ *                      On failure *ppszBuffer will be set to NULL.
+ * @param   pszFormat   Pointer to the format string, @see pg_rt_str_format.
+ * @param   ...         The format argument.
+ */
+DECLINLINE(int) RT_IPRT_FORMAT_ATTR(2, 3) RTStrAPrintf(char **ppszBuffer, const char *pszFormat, ...)
+{
+    int     cbRet;
+    va_list va;
+    va_start(va, pszFormat);
+    cbRet = RTStrAPrintfVTag(ppszBuffer, pszFormat, va, RTSTR_TAG);
+    va_end(va);
+    return cbRet;
+}
+
+/**
+ * Allocating string printf (custom tag).
+ *
+ * @returns The length of the string in the returned *ppszBuffer excluding the
+ *          terminator.
+ * @returns -1 on failure.
+ * @param   ppszBuffer  Where to store the pointer to the allocated output buffer.
+ *                      The buffer should be freed using RTStrFree().
+ *                      On failure *ppszBuffer will be set to NULL.
+ * @param   pszTag      Allocation tag used for statistics and such.
+ * @param   pszFormat   Pointer to the format string, @see pg_rt_str_format.
+ * @param   ...         The format argument.
+ */
+DECLINLINE(int) RT_IPRT_FORMAT_ATTR(3, 4) RTStrAPrintfTag(char **ppszBuffer, const char *pszTag, const char *pszFormat, ...)
+{
+    int     cbRet;
+    va_list va;
+    va_start(va, pszFormat);
+    cbRet = RTStrAPrintfVTag(ppszBuffer, pszFormat, va, pszTag);
+    va_end(va);
+    return cbRet;
+}
+
+/**
+ * Allocating string printf, version 2.
+ *
+ * @returns Formatted string. Use RTStrFree() to free it. NULL when out of
+ *          memory.
+ * @param   pszFormat   Pointer to the format string, @see pg_rt_str_format.
+ * @param   args        The format argument.
+ */
+#define RTStrAPrintf2V(pszFormat, args)     RTStrAPrintf2VTag((pszFormat), (args), RTSTR_TAG)
+
+/**
+ * Allocating string printf, version 2.
+ *
+ * @returns Formatted string. Use RTStrFree() to free it. NULL when out of
+ *          memory.
+ * @param   pszFormat   Pointer to the format string, @see pg_rt_str_format.
+ * @param   args        The format argument.
+ * @param   pszTag      Allocation tag used for statistics and such.
+ */
+RTDECL(char *) RTStrAPrintf2VTag(const char *pszFormat, va_list args, const char *pszTag) RT_IPRT_FORMAT_ATTR(1, 0);
+
+/**
+ * Allocating string printf, version 2 (default tag).
+ *
+ * @returns Formatted string. Use RTStrFree() to free it. NULL when out of
+ *          memory.
+ * @param   pszFormat   Pointer to the format string, @see pg_rt_str_format.
+ * @param   ...         The format argument.
+ */
+DECLINLINE(char *) RT_IPRT_FORMAT_ATTR(1, 2) RTStrAPrintf2(const char *pszFormat, ...)
+{
+    char   *pszRet;
+    va_list va;
+    va_start(va, pszFormat);
+    pszRet = RTStrAPrintf2VTag(pszFormat, va, RTSTR_TAG);
+    va_end(va);
+    return pszRet;
+}
+
+/**
+ * Allocating string printf, version 2 (custom tag).
+ *
+ * @returns Formatted string. Use RTStrFree() to free it. NULL when out of
+ *          memory.
+ * @param   pszTag      Allocation tag used for statistics and such.
+ * @param   pszFormat   Pointer to the format string, @see pg_rt_str_format.
+ * @param   ...         The format argument.
+ */
+DECLINLINE(char *) RT_IPRT_FORMAT_ATTR(2, 3) RTStrAPrintf2Tag(const char *pszTag, const char *pszFormat, ...)
+{
+    char   *pszRet;
+    va_list va;
+    va_start(va, pszFormat);
+    pszRet = RTStrAPrintf2VTag(pszFormat, va, pszTag);
+    va_end(va);
+    return pszRet;
+}
+
+/**
+ * Strips blankspaces from both ends of the string.
+ *
+ * @returns Pointer to first non-blank char in the string.
+ * @param   psz     The string to strip.
+ */
+RTDECL(char *) RTStrStrip(char *psz);
+
+/**
+ * Strips blankspaces from the start of the string.
+ *
+ * @returns Pointer to first non-blank char in the string.
+ * @param   psz     The string to strip.
+ */
+RTDECL(char *) RTStrStripL(const char *psz);
+
+/**
+ * Strips blankspaces from the end of the string.
+ *
+ * @returns psz.
+ * @param   psz     The string to strip.
+ */
+RTDECL(char *) RTStrStripR(char *psz);
+
+/**
+ * String copy with overflow handling.
+ *
+ * @retval  VINF_SUCCESS on success.
+ * @retval  VERR_BUFFER_OVERFLOW if the destination buffer is too small.  The
+ *          buffer will contain as much of the string as it can hold, fully
+ *          terminated.
+ *
+ * @param   pszDst              The destination buffer.
+ * @param   cbDst               The size of the destination buffer (in bytes).
+ * @param   pszSrc              The source string.  NULL is not OK.
+ */
+RTDECL(int) RTStrCopy(char *pszDst, size_t cbDst, const char *pszSrc);
+
+/**
+ * String copy with overflow handling.
+ *
+ * @retval  VINF_SUCCESS on success.
+ * @retval  VERR_BUFFER_OVERFLOW if the destination buffer is too small.  The
+ *          buffer will contain as much of the string as it can hold, fully
+ *          terminated.
+ *
+ * @param   pszDst              The destination buffer.
+ * @param   cbDst               The size of the destination buffer (in bytes).
+ * @param   pszSrc              The source string.  NULL is not OK.
+ * @param   cchSrcMax           The maximum number of chars (not code points) to
+ *                              copy from the source string, not counting the
+ *                              terminator as usual.
+ */
+RTDECL(int) RTStrCopyEx(char *pszDst, size_t cbDst, const char *pszSrc, size_t cchSrcMax);
+
+/**
+ * String copy with overflow handling and buffer advancing.
+ *
+ * @retval  VINF_SUCCESS on success.
+ * @retval  VERR_BUFFER_OVERFLOW if the destination buffer is too small.  The
+ *          buffer will contain as much of the string as it can hold, fully
+ *          terminated.
+ *
+ * @param   ppszDst             Pointer to the destination buffer pointer.
+ *                              This will be advanced to the end of the copied
+ *                              bytes (points at the terminator).  This is also
+ *                              updated on overflow.
+ * @param   pcbDst              Pointer to the destination buffer size
+ *                              variable.  This will be updated in accord with
+ *                              the buffer pointer.
+ * @param   pszSrc              The source string.  NULL is not OK.
+ */
+RTDECL(int) RTStrCopyP(char **ppszDst, size_t *pcbDst, const char *pszSrc);
+
+/**
+ * String copy with overflow handling.
+ *
+ * @retval  VINF_SUCCESS on success.
+ * @retval  VERR_BUFFER_OVERFLOW if the destination buffer is too small.  The
+ *          buffer will contain as much of the string as it can hold, fully
+ *          terminated.
+ *
+ * @param   ppszDst             Pointer to the destination buffer pointer.
+ *                              This will be advanced to the end of the copied
+ *                              bytes (points at the terminator).  This is also
+ *                              updated on overflow.
+ * @param   pcbDst              Pointer to the destination buffer size
+ *                              variable.  This will be updated in accord with
+ *                              the buffer pointer.
+ * @param   pszSrc              The source string.  NULL is not OK.
+ * @param   cchSrcMax           The maximum number of chars (not code points) to
+ *                              copy from the source string, not counting the
+ *                              terminator as usual.
+ */
+RTDECL(int) RTStrCopyPEx(char **ppszDst, size_t *pcbDst, const char *pszSrc, size_t cchSrcMax);
+
+/**
+ * String concatenation with overflow handling.
+ *
+ * @retval  VINF_SUCCESS on success.
+ * @retval  VERR_BUFFER_OVERFLOW if the destination buffer is too small.  The
+ *          buffer will contain as much of the string as it can hold, fully
+ *          terminated.
+ *
+ * @param   pszDst              The destination buffer.
+ * @param   cbDst               The size of the destination buffer (in bytes).
+ * @param   pszSrc              The source string.  NULL is not OK.
+ */
+RTDECL(int) RTStrCat(char *pszDst, size_t cbDst, const char *pszSrc);
+
+/**
+ * String concatenation with overflow handling.
+ *
+ * @retval  VINF_SUCCESS on success.
+ * @retval  VERR_BUFFER_OVERFLOW if the destination buffer is too small.  The
+ *          buffer will contain as much of the string as it can hold, fully
+ *          terminated.
+ *
+ * @param   pszDst              The destination buffer.
+ * @param   cbDst               The size of the destination buffer (in bytes).
+ * @param   pszSrc              The source string.  NULL is not OK.
+ * @param   cchSrcMax           The maximum number of chars (not code points) to
+ *                              copy from the source string, not counting the
+ *                              terminator as usual.
+ */
+RTDECL(int) RTStrCatEx(char *pszDst, size_t cbDst, const char *pszSrc, size_t cchSrcMax);
+
+/**
+ * String concatenation with overflow handling.
+ *
+ * @retval  VINF_SUCCESS on success.
+ * @retval  VERR_BUFFER_OVERFLOW if the destination buffer is too small.  The
+ *          buffer will contain as much of the string as it can hold, fully
+ *          terminated.
+ *
+ * @param   ppszDst             Pointer to the destination buffer pointer.
+ *                              This will be advanced to the end of the copied
+ *                              bytes (points at the terminator).  This is also
+ *                              updated on overflow.
+ * @param   pcbDst              Pointer to the destination buffer size
+ *                              variable.  This will be updated in accord with
+ *                              the buffer pointer.
+ * @param   pszSrc              The source string.  NULL is not OK.
+ */
+RTDECL(int) RTStrCatP(char **ppszDst, size_t *pcbDst, const char *pszSrc);
+
+/**
+ * String concatenation with overflow handling and buffer advancing.
+ *
+ * @retval  VINF_SUCCESS on success.
+ * @retval  VERR_BUFFER_OVERFLOW if the destination buffer is too small.  The
+ *          buffer will contain as much of the string as it can hold, fully
+ *          terminated.
+ *
+ * @param   ppszDst             Pointer to the destination buffer pointer.
+ *                              This will be advanced to the end of the copied
+ *                              bytes (points at the terminator).  This is also
+ *                              updated on overflow.
+ * @param   pcbDst              Pointer to the destination buffer size
+ *                              variable.  This will be updated in accord with
+ *                              the buffer pointer.
+ * @param   pszSrc              The source string.  NULL is not OK.
+ * @param   cchSrcMax           The maximum number of chars (not code points) to
+ *                              copy from the source string, not counting the
+ *                              terminator as usual.
+ */
+RTDECL(int) RTStrCatPEx(char **ppszDst, size_t *pcbDst, const char *pszSrc, size_t cchSrcMax);
+
+/**
+ * Performs a case sensitive string compare between two UTF-8 strings.
+ *
+ * Encoding errors are ignored by the current implementation. So, the only
+ * difference between this and the CRT strcmp function is the handling of
+ * NULL arguments.
+ *
+ * @returns < 0 if the first string less than the second string.
+ * @returns 0 if the first string identical to the second string.
+ * @returns > 0 if the first string greater than the second string.
+ * @param   psz1        First UTF-8 string. Null is allowed.
+ * @param   psz2        Second UTF-8 string. Null is allowed.
+ */
+RTDECL(int) RTStrCmp(const char *psz1, const char *psz2);
+
+/**
+ * Performs a case sensitive string compare between two UTF-8 strings, given
+ * a maximum string length.
+ *
+ * Encoding errors are ignored by the current implementation. So, the only
+ * difference between this and the CRT strncmp function is the handling of
+ * NULL arguments.
+ *
+ * @returns < 0 if the first string less than the second string.
+ * @returns 0 if the first string identical to the second string.
+ * @returns > 0 if the first string greater than the second string.
+ * @param   psz1        First UTF-8 string. Null is allowed.
+ * @param   psz2        Second UTF-8 string. Null is allowed.
+ * @param   cchMax      The maximum string length
+ */
+RTDECL(int) RTStrNCmp(const char *psz1, const char *psz2, size_t cchMax);
+
+/**
+ * Performs a case insensitive string compare between two UTF-8 strings.
+ *
+ * This is a simplified compare, as only the simplified lower/upper case folding
+ * specified by the unicode specs are used. It does not consider character pairs
+ * as they are used in some languages, just simple upper & lower case compares.
+ *
+ * The result is the difference between the mismatching codepoints after they
+ * both have been lower cased.
+ *
+ * If the string encoding is invalid the function will assert (strict builds)
+ * and use RTStrCmp for the remainder of the string.
+ *
+ * @returns < 0 if the first string less than the second string.
+ * @returns 0 if the first string identical to the second string.
+ * @returns > 0 if the first string greater than the second string.
+ * @param   psz1        First UTF-8 string. Null is allowed.
+ * @param   psz2        Second UTF-8 string. Null is allowed.
+ */
+RTDECL(int) RTStrICmp(const char *psz1, const char *psz2);
+
+/**
+ * Performs a case insensitive string compare between two UTF-8 strings, given a
+ * maximum string length.
+ *
+ * This is a simplified compare, as only the simplified lower/upper case folding
+ * specified by the unicode specs are used. It does not consider character pairs
+ * as they are used in some languages, just simple upper & lower case compares.
+ *
+ * The result is the difference between the mismatching codepoints after they
+ * both have been lower cased.
+ *
+ * If the string encoding is invalid the function will assert (strict builds)
+ * and use RTStrCmp for the remainder of the string.
+ *
+ * @returns < 0 if the first string less than the second string.
+ * @returns 0 if the first string identical to the second string.
+ * @returns > 0 if the first string greater than the second string.
+ * @param   psz1        First UTF-8 string. Null is allowed.
+ * @param   psz2        Second UTF-8 string. Null is allowed.
+ * @param   cchMax      Maximum string length
+ */
+RTDECL(int) RTStrNICmp(const char *psz1, const char *psz2, size_t cchMax);
+
+/**
+ * Locates a case sensitive substring.
+ *
+ * If any of the two strings are NULL, then NULL is returned. If the needle is
+ * an empty string, then the haystack is returned (i.e. matches anything).
+ *
+ * @returns Pointer to the first occurrence of the substring if found, NULL if
+ *          not.
+ *
+ * @param   pszHaystack The string to search.
+ * @param   pszNeedle   The substring to search for.
+ *
+ * @remarks The difference between this and strstr is the handling of NULL
+ *          pointers.
+ */
+RTDECL(char *) RTStrStr(const char *pszHaystack, const char *pszNeedle);
+
+/**
+ * Locates a case insensitive substring.
+ *
+ * If any of the two strings are NULL, then NULL is returned. If the needle is
+ * an empty string, then the haystack is returned (i.e. matches anything).
+ *
+ * @returns Pointer to the first occurrence of the substring if found, NULL if
+ *          not.
+ *
+ * @param   pszHaystack The string to search.
+ * @param   pszNeedle   The substring to search for.
+ *
+ */
+RTDECL(char *) RTStrIStr(const char *pszHaystack, const char *pszNeedle);
+
+/**
+ * Converts the string to lower case.
+ *
+ * @returns Pointer to the converted string.
+ * @param   psz     The string to convert.
+ */
+RTDECL(char *) RTStrToLower(char *psz);
+
+/**
+ * Converts the string to upper case.
+ *
+ * @returns Pointer to the converted string.
+ * @param   psz     The string to convert.
+ */
+RTDECL(char *) RTStrToUpper(char *psz);
+
+/**
+ * Checks if the string is case foldable, i.e. whether it would change if
+ * subject to RTStrToLower or RTStrToUpper.
+ *
+ * @returns true / false
+ * @param   psz     The string in question.
+ */
+RTDECL(bool) RTStrIsCaseFoldable(const char *psz);
+
+/**
+ * Checks if the string is upper cased (no lower case chars in it).
+ *
+ * @returns true / false
+ * @param   psz     The string in question.
+ */
+RTDECL(bool) RTStrIsUpperCased(const char *psz);
+
+/**
+ * Checks if the string is lower cased (no upper case chars in it).
+ *
+ * @returns true / false
+ * @param   psz     The string in question.
+ */
+RTDECL(bool) RTStrIsLowerCased(const char *psz);
+
+/**
+ * Find the length of a zero-terminated byte string, given
+ * a max string length.
+ *
+ * See also RTStrNLenEx.
+ *
+ * @returns The string length or cbMax. The returned length does not include
+ *          the zero terminator if it was found.
+ *
+ * @param   pszString   The string.
+ * @param   cchMax      The max string length.
+ */
+RTDECL(size_t) RTStrNLen(const char *pszString, size_t cchMax);
+
+/**
+ * Find the length of a zero-terminated byte string, given
+ * a max string length.
+ *
+ * See also RTStrNLen.
+ *
+ * @returns IPRT status code.
+ * @retval  VINF_SUCCESS if the string has a length less than cchMax.
+ * @retval  VERR_BUFFER_OVERFLOW if the end of the string wasn't found
+ *          before cchMax was reached.
+ *
+ * @param   pszString   The string.
+ * @param   cchMax      The max string length.
+ * @param   pcch        Where to store the string length excluding the
+ *                      terminator. This is set to cchMax if the terminator
+ *                      isn't found.
+ */
+RTDECL(int) RTStrNLenEx(const char *pszString, size_t cchMax, size_t *pcch);
+
+RT_C_DECLS_END
+
+/** The maximum size argument of a memchr call. */
+#define RTSTR_MEMCHR_MAX            ((~(size_t)0 >> 1) - 15)
+
+/**
+ * Find the zero terminator in a string with a limited length.
+ *
+ * @returns Pointer to the zero terminator.
+ * @returns NULL if the zero terminator was not found.
+ *
+ * @param   pszString   The string.
+ * @param   cchMax      The max string length.  RTSTR_MAX is fine.
+ */
+#if defined(__cplusplus) && !defined(DOXYGEN_RUNNING)
+DECLINLINE(char const *) RTStrEnd(char const *pszString, size_t cchMax)
+{
+    /* Avoid potential issues with memchr seen in glibc.
+     * See sysdeps/x86_64/memchr.S in glibc versions older than 2.11 */
+    while (cchMax > RTSTR_MEMCHR_MAX)
+    {
+        char const *pszRet = (char const *)memchr(pszString, '\0', RTSTR_MEMCHR_MAX);
+        if (RT_LIKELY(pszRet))
+            return pszRet;
+        pszString += RTSTR_MEMCHR_MAX;
+        cchMax    -= RTSTR_MEMCHR_MAX;
+    }
+    return (char const *)memchr(pszString, '\0', cchMax);
+}
+
+DECLINLINE(char *) RTStrEnd(char *pszString, size_t cchMax)
+#else
+DECLINLINE(char *) RTStrEnd(const char *pszString, size_t cchMax)
+#endif
+{
+    /* Avoid potential issues with memchr seen in glibc.
+     * See sysdeps/x86_64/memchr.S in glibc versions older than 2.11 */
+    while (cchMax > RTSTR_MEMCHR_MAX)
+    {
+        char *pszRet = (char *)memchr(pszString, '\0', RTSTR_MEMCHR_MAX);
+        if (RT_LIKELY(pszRet))
+            return pszRet;
+        pszString += RTSTR_MEMCHR_MAX;
+        cchMax    -= RTSTR_MEMCHR_MAX;
+    }
+    return (char *)memchr(pszString, '\0', cchMax);
+}
+
+RT_C_DECLS_BEGIN
+
+/**
+ * Finds the offset at which a simple character first occurs in a string.
+ *
+ * @returns The offset of the first occurence or the terminator offset.
+ * @param   pszHaystack The string to search.
+ * @param   chNeedle    The character to search for.
+ */
+DECLINLINE(size_t) RTStrOffCharOrTerm(const char *pszHaystack, char chNeedle)
+{
+    const char *psz = pszHaystack;
+    char ch;
+    while (   (ch = *psz) != chNeedle
+           && ch != '\0')
+        psz++;
+    return psz - pszHaystack;
+}
+
+
+/**
+ * Matches a simple string pattern.
+ *
+ * @returns true if the string matches the pattern, otherwise false.
+ *
+ * @param  pszPattern   The pattern. Special chars are '*' and '?', where the
+ *                      asterisk matches zero or more characters and question
+ *                      mark matches exactly one character.
+ * @param  pszString    The string to match against the pattern.
+ */
+RTDECL(bool) RTStrSimplePatternMatch(const char *pszPattern, const char *pszString);
+
+/**
+ * Matches a simple string pattern, neither which needs to be zero terminated.
+ *
+ * This is identical to RTStrSimplePatternMatch except that you can optionally
+ * specify the length of both the pattern and the string.  The function will
+ * stop when it hits a string terminator or either of the lengths.
+ *
+ * @returns true if the string matches the pattern, otherwise false.
+ *
+ * @param  pszPattern   The pattern. Special chars are '*' and '?', where the
+ *                      asterisk matches zero or more characters and question
+ *                      mark matches exactly one character.
+ * @param  cchPattern   The pattern length. Pass RTSTR_MAX if you don't know the
+ *                      length and wish to stop at the string terminator.
+ * @param  pszString    The string to match against the pattern.
+ * @param  cchString    The string length. Pass RTSTR_MAX if you don't know the
+ *                      length and wish to match up to the string terminator.
+ */
+RTDECL(bool) RTStrSimplePatternNMatch(const char *pszPattern, size_t cchPattern,
+                                      const char *pszString, size_t cchString);
+
+/**
+ * Matches multiple patterns against a string.
+ *
+ * The patterns are separated by the pipe character (|).
+ *
+ * @returns true if the string matches the pattern, otherwise false.
+ *
+ * @param   pszPatterns The patterns.
+ * @param   cchPatterns The lengths of the patterns to use. Pass RTSTR_MAX to
+ *                      stop at the terminator.
+ * @param   pszString   The string to match against the pattern.
+ * @param   cchString   The string length. Pass RTSTR_MAX stop stop at the
+ *                      terminator.
+ * @param   poffPattern Offset into the patterns string of the patttern that
+ *                      matched. If no match, this will be set to RTSTR_MAX.
+ *                      This is optional, NULL is fine.
+ */
+RTDECL(bool) RTStrSimplePatternMultiMatch(const char *pszPatterns, size_t cchPatterns,
+                                          const char *pszString, size_t cchString,
+                                          size_t *poffPattern);
+
+/**
+ * Compares two version strings RTStrICmp fashion.
+ *
+ * The version string is split up into sections at punctuation, spaces,
+ * underscores, dashes and plus signs.  The sections are then split up into
+ * numeric and string sub-sections.  Finally, the sub-sections are compared
+ * in a numeric or case insesntivie fashion depending on what they are.
+ *
+ * The following strings are considered to be equal: "1.0.0", "1.00.0", "1.0",
+ * "1".  These aren't: "1.0.0r993", "1.0", "1.0r993", "1.0_Beta3", "1.1"
+ *
+ * @returns < 0 if the first string less than the second string.
+ * @returns 0 if the first string identical to the second string.
+ * @returns > 0 if the first string greater than the second string.
+ *
+ * @param   pszVer1     First version string to compare.
+ * @param   pszVer2     Second version string to compare first version with.
+ */
+RTDECL(int) RTStrVersionCompare(const char *pszVer1, const char *pszVer2);
+
+
+/** @defgroup rt_str_conv   String To/From Number Conversions
+ * @{ */
+
+/**
+ * Converts a string representation of a number to a 64-bit unsigned number.
+ *
+ * @returns iprt status code.
+ *          Warnings are used to indicate conversion problems.
+ * @retval  VWRN_NUMBER_TOO_BIG
+ * @retval  VWRN_NEGATIVE_UNSIGNED
+ * @retval  VWRN_TRAILING_CHARS
+ * @retval  VWRN_TRAILING_SPACES
+ * @retval  VINF_SUCCESS
+ * @retval  VERR_NO_DIGITS
+ *
+ * @param   pszValue    Pointer to the string value.
+ * @param   ppszNext    Where to store the pointer to the first char following the number. (Optional)
+ * @param   uBase       The base of the representation used.
+ *                      If 0 the function will look for known prefixes before defaulting to 10.
+ * @param   pu64        Where to store the converted number. (optional)
+ */
+RTDECL(int) RTStrToUInt64Ex(const char *pszValue, char **ppszNext, unsigned uBase, uint64_t *pu64);
+
+/**
+ * Converts a string representation of a number to a 64-bit unsigned number,
+ * making sure the full string is converted.
+ *
+ * @returns iprt status code.
+ *          Warnings are used to indicate conversion problems.
+ * @retval  VWRN_NUMBER_TOO_BIG
+ * @retval  VWRN_NEGATIVE_UNSIGNED
+ * @retval  VINF_SUCCESS
+ * @retval  VERR_NO_DIGITS
+ * @retval  VERR_TRAILING_SPACES
+ * @retval  VERR_TRAILING_CHARS
+ *
+ * @param   pszValue    Pointer to the string value.
+ * @param   uBase       The base of the representation used.
+ *                      If 0 the function will look for known prefixes before defaulting to 10.
+ * @param   pu64        Where to store the converted number. (optional)
+ */
+RTDECL(int) RTStrToUInt64Full(const char *pszValue, unsigned uBase, uint64_t *pu64);
+
+/**
+ * Converts a string representation of a number to a 64-bit unsigned number.
+ * The base is guessed.
+ *
+ * @returns 64-bit unsigned number on success.
+ * @returns 0 on failure.
+ * @param   pszValue    Pointer to the string value.
+ */
+RTDECL(uint64_t) RTStrToUInt64(const char *pszValue);
+
+/**
+ * Converts a string representation of a number to a 32-bit unsigned number.
+ *
+ * @returns iprt status code.
+ *          Warnings are used to indicate conversion problems.
+ * @retval  VWRN_NUMBER_TOO_BIG
+ * @retval  VWRN_NEGATIVE_UNSIGNED
+ * @retval  VWRN_TRAILING_CHARS
+ * @retval  VWRN_TRAILING_SPACES
+ * @retval  VINF_SUCCESS
+ * @retval  VERR_NO_DIGITS
+ *
+ * @param   pszValue    Pointer to the string value.
+ * @param   ppszNext    Where to store the pointer to the first char following the number. (Optional)
+ * @param   uBase       The base of the representation used.
+ *                      If 0 the function will look for known prefixes before defaulting to 10.
+ * @param   pu32        Where to store the converted number. (optional)
+ */
+RTDECL(int) RTStrToUInt32Ex(const char *pszValue, char **ppszNext, unsigned uBase, uint32_t *pu32);
+
+/**
+ * Converts a string representation of a number to a 32-bit unsigned number,
+ * making sure the full string is converted.
+ *
+ * @returns iprt status code.
+ *          Warnings are used to indicate conversion problems.
+ * @retval  VWRN_NUMBER_TOO_BIG
+ * @retval  VWRN_NEGATIVE_UNSIGNED
+ * @retval  VINF_SUCCESS
+ * @retval  VERR_NO_DIGITS
+ * @retval  VERR_TRAILING_SPACES
+ * @retval  VERR_TRAILING_CHARS
+ *
+ * @param   pszValue    Pointer to the string value.
+ * @param   uBase       The base of the representation used.
+ *                      If 0 the function will look for known prefixes before defaulting to 10.
+ * @param   pu32        Where to store the converted number. (optional)
+ */
+RTDECL(int) RTStrToUInt32Full(const char *pszValue, unsigned uBase, uint32_t *pu32);
+
+/**
+ * Converts a string representation of a number to a 64-bit unsigned number.
+ * The base is guessed.
+ *
+ * @returns 32-bit unsigned number on success.
+ * @returns 0 on failure.
+ * @param   pszValue    Pointer to the string value.
+ */
+RTDECL(uint32_t) RTStrToUInt32(const char *pszValue);
+
+/**
+ * Converts a string representation of a number to a 16-bit unsigned number.
+ *
+ * @returns iprt status code.
+ *          Warnings are used to indicate conversion problems.
+ * @retval  VWRN_NUMBER_TOO_BIG
+ * @retval  VWRN_NEGATIVE_UNSIGNED
+ * @retval  VWRN_TRAILING_CHARS
+ * @retval  VWRN_TRAILING_SPACES
+ * @retval  VINF_SUCCESS
+ * @retval  VERR_NO_DIGITS
+ *
+ * @param   pszValue    Pointer to the string value.
+ * @param   ppszNext    Where to store the pointer to the first char following the number. (Optional)
+ * @param   uBase       The base of the representation used.
+ *                      If 0 the function will look for known prefixes before defaulting to 10.
+ * @param   pu16        Where to store the converted number. (optional)
+ */
+RTDECL(int) RTStrToUInt16Ex(const char *pszValue, char **ppszNext, unsigned uBase, uint16_t *pu16);
+
+/**
+ * Converts a string representation of a number to a 16-bit unsigned number,
+ * making sure the full string is converted.
+ *
+ * @returns iprt status code.
+ *          Warnings are used to indicate conversion problems.
+ * @retval  VWRN_NUMBER_TOO_BIG
+ * @retval  VWRN_NEGATIVE_UNSIGNED
+ * @retval  VINF_SUCCESS
+ * @retval  VERR_NO_DIGITS
+ * @retval  VERR_TRAILING_SPACES
+ * @retval  VERR_TRAILING_CHARS
+ *
+ * @param   pszValue    Pointer to the string value.
+ * @param   uBase       The base of the representation used.
+ *                      If 0 the function will look for known prefixes before defaulting to 10.
+ * @param   pu16        Where to store the converted number. (optional)
+ */
+RTDECL(int) RTStrToUInt16Full(const char *pszValue, unsigned uBase, uint16_t *pu16);
+
+/**
+ * Converts a string representation of a number to a 16-bit unsigned number.
+ * The base is guessed.
+ *
+ * @returns 16-bit unsigned number on success.
+ * @returns 0 on failure.
+ * @param   pszValue    Pointer to the string value.
+ */
+RTDECL(uint16_t) RTStrToUInt16(const char *pszValue);
+
+/**
+ * Converts a string representation of a number to a 8-bit unsigned number.
+ *
+ * @returns iprt status code.
+ *          Warnings are used to indicate conversion problems.
+ * @retval  VWRN_NUMBER_TOO_BIG
+ * @retval  VWRN_NEGATIVE_UNSIGNED
+ * @retval  VWRN_TRAILING_CHARS
+ * @retval  VWRN_TRAILING_SPACES
+ * @retval  VINF_SUCCESS
+ * @retval  VERR_NO_DIGITS
+ *
+ * @param   pszValue    Pointer to the string value.
+ * @param   ppszNext    Where to store the pointer to the first char following the number. (Optional)
+ * @param   uBase       The base of the representation used.
+ *                      If 0 the function will look for known prefixes before defaulting to 10.
+ * @param   pu8         Where to store the converted number. (optional)
+ */
+RTDECL(int) RTStrToUInt8Ex(const char *pszValue, char **ppszNext, unsigned uBase, uint8_t *pu8);
+
+/**
+ * Converts a string representation of a number to a 8-bit unsigned number,
+ * making sure the full string is converted.
+ *
+ * @returns iprt status code.
+ *          Warnings are used to indicate conversion problems.
+ * @retval  VWRN_NUMBER_TOO_BIG
+ * @retval  VWRN_NEGATIVE_UNSIGNED
+ * @retval  VINF_SUCCESS
+ * @retval  VERR_NO_DIGITS
+ * @retval  VERR_TRAILING_SPACES
+ * @retval  VERR_TRAILING_CHARS
+ *
+ * @param   pszValue    Pointer to the string value.
+ * @param   uBase       The base of the representation used.
+ *                      If 0 the function will look for known prefixes before defaulting to 10.
+ * @param   pu8         Where to store the converted number. (optional)
+ */
+RTDECL(int) RTStrToUInt8Full(const char *pszValue, unsigned uBase, uint8_t *pu8);
+
+/**
+ * Converts a string representation of a number to a 8-bit unsigned number.
+ * The base is guessed.
+ *
+ * @returns 8-bit unsigned number on success.
+ * @returns 0 on failure.
+ * @param   pszValue    Pointer to the string value.
+ */
+RTDECL(uint8_t) RTStrToUInt8(const char *pszValue);
+
+/**
+ * Converts a string representation of a number to a 64-bit signed number.
+ *
+ * @returns iprt status code.
+ *          Warnings are used to indicate conversion problems.
+ * @retval  VWRN_NUMBER_TOO_BIG
+ * @retval  VWRN_TRAILING_CHARS
+ * @retval  VWRN_TRAILING_SPACES
+ * @retval  VINF_SUCCESS
+ * @retval  VERR_NO_DIGITS
+ *
+ * @param   pszValue    Pointer to the string value.
+ * @param   ppszNext    Where to store the pointer to the first char following the number. (Optional)
+ * @param   uBase       The base of the representation used.
+ *                      If 0 the function will look for known prefixes before defaulting to 10.
+ * @param   pi64        Where to store the converted number. (optional)
+ */
+RTDECL(int) RTStrToInt64Ex(const char *pszValue, char **ppszNext, unsigned uBase, int64_t *pi64);
+
+/**
+ * Converts a string representation of a number to a 64-bit signed number,
+ * making sure the full string is converted.
+ *
+ * @returns iprt status code.
+ *          Warnings are used to indicate conversion problems.
+ * @retval  VWRN_NUMBER_TOO_BIG
+ * @retval  VINF_SUCCESS
+ * @retval  VERR_TRAILING_CHARS
+ * @retval  VERR_TRAILING_SPACES
+ * @retval  VERR_NO_DIGITS
+ *
+ * @param   pszValue    Pointer to the string value.
+ * @param   uBase       The base of the representation used.
+ *                      If 0 the function will look for known prefixes before defaulting to 10.
+ * @param   pi64        Where to store the converted number. (optional)
+ */
+RTDECL(int) RTStrToInt64Full(const char *pszValue, unsigned uBase, int64_t *pi64);
+
+/**
+ * Converts a string representation of a number to a 64-bit signed number.
+ * The base is guessed.
+ *
+ * @returns 64-bit signed number on success.
+ * @returns 0 on failure.
+ * @param   pszValue    Pointer to the string value.
+ */
+RTDECL(int64_t) RTStrToInt64(const char *pszValue);
+
+/**
+ * Converts a string representation of a number to a 32-bit signed number.
+ *
+ * @returns iprt status code.
+ *          Warnings are used to indicate conversion problems.
+ * @retval  VWRN_NUMBER_TOO_BIG
+ * @retval  VWRN_TRAILING_CHARS
+ * @retval  VWRN_TRAILING_SPACES
+ * @retval  VINF_SUCCESS
+ * @retval  VERR_NO_DIGITS
+ *
+ * @param   pszValue    Pointer to the string value.
+ * @param   ppszNext    Where to store the pointer to the first char following the number. (Optional)
+ * @param   uBase       The base of the representation used.
+ *                      If 0 the function will look for known prefixes before defaulting to 10.
+ * @param   pi32        Where to store the converted number. (optional)
+ */
+RTDECL(int) RTStrToInt32Ex(const char *pszValue, char **ppszNext, unsigned uBase, int32_t *pi32);
+
+/**
+ * Converts a string representation of a number to a 32-bit signed number,
+ * making sure the full string is converted.
+ *
+ * @returns iprt status code.
+ *          Warnings are used to indicate conversion problems.
+ * @retval  VWRN_NUMBER_TOO_BIG
+ * @retval  VINF_SUCCESS
+ * @retval  VERR_TRAILING_CHARS
+ * @retval  VERR_TRAILING_SPACES
+ * @retval  VERR_NO_DIGITS
+ *
+ * @param   pszValue    Pointer to the string value.
+ * @param   uBase       The base of the representation used.
+ *                      If 0 the function will look for known prefixes before defaulting to 10.
+ * @param   pi32        Where to store the converted number. (optional)
+ */
+RTDECL(int) RTStrToInt32Full(const char *pszValue, unsigned uBase, int32_t *pi32);
+
+/**
+ * Converts a string representation of a number to a 32-bit signed number.
+ * The base is guessed.
+ *
+ * @returns 32-bit signed number on success.
+ * @returns 0 on failure.
+ * @param   pszValue    Pointer to the string value.
+ */
+RTDECL(int32_t) RTStrToInt32(const char *pszValue);
+
+/**
+ * Converts a string representation of a number to a 16-bit signed number.
+ *
+ * @returns iprt status code.
+ *          Warnings are used to indicate conversion problems.
+ * @retval  VWRN_NUMBER_TOO_BIG
+ * @retval  VWRN_TRAILING_CHARS
+ * @retval  VWRN_TRAILING_SPACES
+ * @retval  VINF_SUCCESS
+ * @retval  VERR_NO_DIGITS
+ *
+ * @param   pszValue    Pointer to the string value.
+ * @param   ppszNext    Where to store the pointer to the first char following the number. (Optional)
+ * @param   uBase       The base of the representation used.
+ *                      If 0 the function will look for known prefixes before defaulting to 10.
+ * @param   pi16        Where to store the converted number. (optional)
+ */
+RTDECL(int) RTStrToInt16Ex(const char *pszValue, char **ppszNext, unsigned uBase, int16_t *pi16);
+
+/**
+ * Converts a string representation of a number to a 16-bit signed number,
+ * making sure the full string is converted.
+ *
+ * @returns iprt status code.
+ *          Warnings are used to indicate conversion problems.
+ * @retval  VWRN_NUMBER_TOO_BIG
+ * @retval  VINF_SUCCESS
+ * @retval  VERR_TRAILING_CHARS
+ * @retval  VERR_TRAILING_SPACES
+ * @retval  VERR_NO_DIGITS
+ *
+ * @param   pszValue    Pointer to the string value.
+ * @param   uBase       The base of the representation used.
+ *                      If 0 the function will look for known prefixes before defaulting to 10.
+ * @param   pi16        Where to store the converted number. (optional)
+ */
+RTDECL(int) RTStrToInt16Full(const char *pszValue, unsigned uBase, int16_t *pi16);
+
+/**
+ * Converts a string representation of a number to a 16-bit signed number.
+ * The base is guessed.
+ *
+ * @returns 16-bit signed number on success.
+ * @returns 0 on failure.
+ * @param   pszValue    Pointer to the string value.
+ */
+RTDECL(int16_t) RTStrToInt16(const char *pszValue);
+
+/**
+ * Converts a string representation of a number to a 8-bit signed number.
+ *
+ * @returns iprt status code.
+ *          Warnings are used to indicate conversion problems.
+ * @retval  VWRN_NUMBER_TOO_BIG
+ * @retval  VWRN_TRAILING_CHARS
+ * @retval  VWRN_TRAILING_SPACES
+ * @retval  VINF_SUCCESS
+ * @retval  VERR_NO_DIGITS
+ *
+ * @param   pszValue    Pointer to the string value.
+ * @param   ppszNext    Where to store the pointer to the first char following the number. (Optional)
+ * @param   uBase       The base of the representation used.
+ *                      If 0 the function will look for known prefixes before defaulting to 10.
+ * @param   pi8         Where to store the converted number. (optional)
+ */
+RTDECL(int) RTStrToInt8Ex(const char *pszValue, char **ppszNext, unsigned uBase, int8_t *pi8);
+
+/**
+ * Converts a string representation of a number to a 8-bit signed number,
+ * making sure the full string is converted.
+ *
+ * @returns iprt status code.
+ *          Warnings are used to indicate conversion problems.
+ * @retval  VWRN_NUMBER_TOO_BIG
+ * @retval  VINF_SUCCESS
+ * @retval  VERR_TRAILING_CHARS
+ * @retval  VERR_TRAILING_SPACES
+ * @retval  VERR_NO_DIGITS
+ *
+ * @param   pszValue    Pointer to the string value.
+ * @param   uBase       The base of the representation used.
+ *                      If 0 the function will look for known prefixes before defaulting to 10.
+ * @param   pi8         Where to store the converted number. (optional)
+ */
+RTDECL(int) RTStrToInt8Full(const char *pszValue, unsigned uBase, int8_t *pi8);
+
+/**
+ * Converts a string representation of a number to a 8-bit signed number.
+ * The base is guessed.
+ *
+ * @returns 8-bit signed number on success.
+ * @returns 0 on failure.
+ * @param   pszValue    Pointer to the string value.
+ */
+RTDECL(int8_t) RTStrToInt8(const char *pszValue);
+
+/**
+ * Formats a buffer stream as hex bytes.
+ *
+ * The default is no separating spaces or line breaks or anything.
+ *
+ * @returns IPRT status code.
+ * @retval  VERR_INVALID_POINTER if any of the pointers are wrong.
+ * @retval  VERR_BUFFER_OVERFLOW if the buffer is insufficent to hold the bytes.
+ *
+ * @param   pszBuf      Output string buffer.
+ * @param   cchBuf      The size of the output buffer.
+ * @param   pv          Pointer to the bytes to stringify.
+ * @param   cb          The number of bytes to stringify.
+ * @param   fFlags      Combination of RTSTRPRINTHEXBYTES_F_XXX values.
+ * @sa      RTUtf16PrintHexBytes.
+ */
+RTDECL(int) RTStrPrintHexBytes(char *pszBuf, size_t cchBuf, void const *pv, size_t cb, uint32_t fFlags);
+/** @name RTSTRPRINTHEXBYTES_F_XXX - flags for RTStrPrintHexBytes and RTUtf16PritnHexBytes.
+ * @{ */
+/** Upper case hex digits, the default is lower case. */
+#define RTSTRPRINTHEXBYTES_F_UPPER      RT_BIT(0)
+/** @} */
+
+/**
+ * Converts a string of hex bytes back into binary data.
+ *
+ * @returns IPRT status code.
+ * @retval  VERR_INVALID_POINTER if any of the pointers are wrong.
+ * @retval  VERR_BUFFER_OVERFLOW if the string contains too many hex bytes.
+ * @retval  VERR_BUFFER_UNDERFLOW if there aren't enough hex bytes to fill up
+ *          the output buffer.
+ * @retval  VERR_UNEVEN_INPUT if the input contains a half byte.
+ * @retval  VERR_NO_DIGITS
+ * @retval  VWRN_TRAILING_CHARS
+ * @retval  VWRN_TRAILING_SPACES
+ *
+ * @param   pszHex      The string containing the hex bytes.
+ * @param   pv          Output buffer.
+ * @param   cb          The size of the output buffer.
+ * @param   fFlags      Must be zero, reserved for future use.
+ */
+RTDECL(int) RTStrConvertHexBytes(char const *pszHex, void *pv, size_t cb, uint32_t fFlags);
+
+/** @} */
+
+
+/** @defgroup rt_str_space  Unique String Space
+ * @{
+ */
+
+/** Pointer to a string name space container node core. */
+typedef struct RTSTRSPACECORE *PRTSTRSPACECORE;
+/** Pointer to a pointer to a string name space container node core. */
+typedef PRTSTRSPACECORE *PPRTSTRSPACECORE;
+
+/**
+ * String name space container node core.
+ */
+typedef struct RTSTRSPACECORE
+{
+    /** Hash key. Don't touch. */
+    uint32_t        Key;
+    /** Pointer to the left leaf node. Don't touch. */
+    PRTSTRSPACECORE pLeft;
+    /** Pointer to the left right node. Don't touch. */
+    PRTSTRSPACECORE pRight;
+    /** Pointer to the list of string with the same key. Don't touch. */
+    PRTSTRSPACECORE pList;
+    /** Height of this tree: max(heigth(left), heigth(right)) + 1. Don't touch */
+    unsigned char   uchHeight;
+    /** The string length. Read only! */
+    size_t          cchString;
+    /** Pointer to the string. Read only! */
+    const char     *pszString;
+} RTSTRSPACECORE;
+
+/** String space. (Initialize with NULL.) */
+typedef PRTSTRSPACECORE     RTSTRSPACE;
+/** Pointer to a string space. */
+typedef PPRTSTRSPACECORE    PRTSTRSPACE;
+
+
+/**
+ * Inserts a string into a unique string space.
+ *
+ * @returns true on success.
+ * @returns false if the string collided with an existing string.
+ * @param   pStrSpace       The space to insert it into.
+ * @param   pStr            The string node.
+ */
+RTDECL(bool) RTStrSpaceInsert(PRTSTRSPACE pStrSpace, PRTSTRSPACECORE pStr);
+
+/**
+ * Removes a string from a unique string space.
+ *
+ * @returns Pointer to the removed string node.
+ * @returns NULL if the string was not found in the string space.
+ * @param   pStrSpace       The space to remove it from.
+ * @param   pszString       The string to remove.
+ */
+RTDECL(PRTSTRSPACECORE) RTStrSpaceRemove(PRTSTRSPACE pStrSpace, const char *pszString);
+
+/**
+ * Gets a string from a unique string space.
+ *
+ * @returns Pointer to the string node.
+ * @returns NULL if the string was not found in the string space.
+ * @param   pStrSpace       The space to get it from.
+ * @param   pszString       The string to get.
+ */
+RTDECL(PRTSTRSPACECORE) RTStrSpaceGet(PRTSTRSPACE pStrSpace, const char *pszString);
+
+/**
+ * Gets a string from a unique string space.
+ *
+ * @returns Pointer to the string node.
+ * @returns NULL if the string was not found in the string space.
+ * @param   pStrSpace       The space to get it from.
+ * @param   pszString       The string to get.
+ * @param   cchMax          The max string length to evaluate.  Passing
+ *                          RTSTR_MAX is ok and makes it behave just like
+ *                          RTStrSpaceGet.
+ */
+RTDECL(PRTSTRSPACECORE) RTStrSpaceGetN(PRTSTRSPACE pStrSpace, const char *pszString, size_t cchMax);
+
+/**
+ * Callback function for RTStrSpaceEnumerate() and RTStrSpaceDestroy().
+ *
+ * @returns 0 on continue.
+ * @returns Non-zero to aborts the operation.
+ * @param   pStr        The string node
+ * @param   pvUser      The user specified argument.
+ */
+typedef DECLCALLBACK(int)   FNRTSTRSPACECALLBACK(PRTSTRSPACECORE pStr, void *pvUser);
+/** Pointer to callback function for RTStrSpaceEnumerate() and RTStrSpaceDestroy(). */
+typedef FNRTSTRSPACECALLBACK *PFNRTSTRSPACECALLBACK;
+
+/**
+ * Destroys the string space.
+ *
+ * The caller supplies a callback which will be called for each of the string
+ * nodes in for freeing their memory and other resources.
+ *
+ * @returns 0 or what ever non-zero return value pfnCallback returned
+ *          when aborting the destruction.
+ * @param   pStrSpace       The space to destroy.
+ * @param   pfnCallback     The callback.
+ * @param   pvUser          The user argument.
+ */
+RTDECL(int) RTStrSpaceDestroy(PRTSTRSPACE pStrSpace, PFNRTSTRSPACECALLBACK pfnCallback, void *pvUser);
+
+/**
+ * Enumerates the string space.
+ * The caller supplies a callback which will be called for each of
+ * the string nodes.
+ *
+ * @returns 0 or what ever non-zero return value pfnCallback returned
+ *          when aborting the destruction.
+ * @param   pStrSpace       The space to enumerate.
+ * @param   pfnCallback     The callback.
+ * @param   pvUser          The user argument.
+ */
+RTDECL(int) RTStrSpaceEnumerate(PRTSTRSPACE pStrSpace, PFNRTSTRSPACECALLBACK pfnCallback, void *pvUser);
+
+/** @} */
+
+
+/** @defgroup rt_str_hash       Sting hashing
+ * @{ */
+
+/**
+ * Hashes the given string using algorithm \#1.
+ *
+ * @returns String hash.
+ * @param   pszString       The string to hash.
+ */
+RTDECL(uint32_t)    RTStrHash1(const char *pszString);
+
+/**
+ * Hashes the given string using algorithm \#1.
+ *
+ * @returns String hash.
+ * @param   pszString       The string to hash.
+ * @param   cchString       The max length to hash. Hashing will stop if the
+ *                          terminator character is encountered first. Passing
+ *                          RTSTR_MAX is fine.
+ */
+RTDECL(uint32_t)    RTStrHash1N(const char *pszString, size_t cchString);
+
+/**
+ * Hashes the given strings as if they were concatenated using algorithm \#1.
+ *
+ * @returns String hash.
+ * @param   cPairs          The number of string / length pairs in the
+ *                          ellipsis.
+ * @param   ...             List of string (const char *) and length
+ *                          (size_t) pairs.  Passing RTSTR_MAX as the size is
+ *                          fine.
+ */
+RTDECL(uint32_t)    RTStrHash1ExN(size_t cPairs, ...);
+
+/**
+ * Hashes the given strings as if they were concatenated using algorithm \#1.
+ *
+ * @returns String hash.
+ * @param   cPairs          The number of string / length pairs in the @a va.
+ * @param   va              List of string (const char *) and length
+ *                          (size_t) pairs.  Passing RTSTR_MAX as the size is
+ *                          fine.
+ */
+RTDECL(uint32_t)    RTStrHash1ExNV(size_t cPairs, va_list va);
+
+/** @}  */
+
+/** @} */
+
+RT_C_DECLS_END
+
+#endif
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/include/iprt/thread.h
@@ -0,0 +1,943 @@
+/** @file
+ * IPRT - Threads.
+ */
+
+/*
+ * Copyright (C) 2006-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+#ifndef ___iprt_thread_h
+#define ___iprt_thread_h
+
+#include <iprt/cdefs.h>
+#include <iprt/types.h>
+#include <iprt/stdarg.h>
+
+
+RT_C_DECLS_BEGIN
+
+/** @defgroup grp_rt_thread    RTThread - Thread Management
+ * @ingroup grp_rt
+ * @{
+ */
+
+/**
+ * The thread state.
+ */
+typedef enum RTTHREADSTATE
+{
+    /** The usual invalid 0 value. */
+    RTTHREADSTATE_INVALID = 0,
+    /** The thread is being initialized. */
+    RTTHREADSTATE_INITIALIZING,
+    /** The thread has terminated */
+    RTTHREADSTATE_TERMINATED,
+    /** Probably running. */
+    RTTHREADSTATE_RUNNING,
+
+    /** Waiting on a critical section. */
+    RTTHREADSTATE_CRITSECT,
+    /** Waiting on a event semaphore. */
+    RTTHREADSTATE_EVENT,
+    /** Waiting on a event multiple wakeup semaphore. */
+    RTTHREADSTATE_EVENT_MULTI,
+    /** Waiting on a fast mutex. */
+    RTTHREADSTATE_FAST_MUTEX,
+    /** Waiting on a mutex. */
+    RTTHREADSTATE_MUTEX,
+    /** Waiting on a read write semaphore, read (shared) access. */
+    RTTHREADSTATE_RW_READ,
+    /** Waiting on a read write semaphore, write (exclusive) access. */
+    RTTHREADSTATE_RW_WRITE,
+    /** The thread is sleeping. */
+    RTTHREADSTATE_SLEEP,
+    /** Waiting on a spin mutex. */
+    RTTHREADSTATE_SPIN_MUTEX,
+    /** End of the thread states. */
+    RTTHREADSTATE_END,
+
+    /** The usual 32-bit size hack. */
+    RTTHREADSTATE_32BIT_HACK = 0x7fffffff
+} RTTHREADSTATE;
+
+/** Checks if a thread state indicates that the thread is sleeping. */
+#define RTTHREAD_IS_SLEEPING(enmState) ((enmState) >= RTTHREADSTATE_CRITSECT)
+
+/**
+ * Thread types.
+ * Besides identifying the purpose of the thread, the thread type is
+ * used to select the scheduling properties.
+ *
+ * The types in are placed in a rough order of ascending priority.
+ */
+typedef enum RTTHREADTYPE
+{
+    /** Invalid type. */
+    RTTHREADTYPE_INVALID = 0,
+    /** Infrequent poller thread.
+     * This type of thread will sleep for the most of the time, and do
+     * infrequent polls on resources at 0.5 sec or higher intervals.
+     */
+    RTTHREADTYPE_INFREQUENT_POLLER,
+    /** Main heavy worker thread.
+     * Thread of this type is driving asynchronous tasks in the Main
+     * API which takes a long time and might involve a bit of CPU. Like
+     * for instance creating a fixed sized VDI.
+     */
+    RTTHREADTYPE_MAIN_HEAVY_WORKER,
+    /** The emulation thread type.
+     * While being a thread with very high workload it still is vital
+     * that it gets scheduled frequently. When possible all other thread
+     * types except DEFAULT and GUI should interrupt this one ASAP when
+     * they become ready.
+     */
+    RTTHREADTYPE_EMULATION,
+    /** The default thread type.
+     * Since it doesn't say much about the purpose of the thread
+     * nothing special is normally done to the scheduling. This type
+     * should be avoided.
+     * The main thread is registered with default type during RTR3Init()
+     * and that's what the default process priority is derived from.
+     */
+    RTTHREADTYPE_DEFAULT,
+    /** The GUI thread type
+     * The GUI normally have a low workload but is frequently scheduled
+     * to handle events. When possible the scheduler should not leave
+     * threads of this kind waiting for too long (~50ms).
+     */
+    RTTHREADTYPE_GUI,
+    /** Main worker thread.
+     * Thread of this type is driving asynchronous tasks in the Main API.
+     * In most cases this means little work an a lot of waiting.
+     */
+    RTTHREADTYPE_MAIN_WORKER,
+    /** VRDP I/O thread.
+     * These threads are I/O threads in the RDP server will hang around
+     * waiting for data, process it and pass it on.
+     */
+    RTTHREADTYPE_VRDP_IO,
+    /** The debugger type.
+     * Threads involved in servicing the debugger. It must remain
+     * responsive even when things are running wild in.
+     */
+    RTTHREADTYPE_DEBUGGER,
+    /** Message pump thread.
+     * Thread pumping messages from one thread/process to another
+     * thread/process. The workload is very small, most of the time
+     * it's blocked waiting for messages to be produced or processed.
+     * This type of thread will be favored after I/O threads.
+     */
+    RTTHREADTYPE_MSG_PUMP,
+    /** The I/O thread type.
+     * Doing I/O means shuffling data, waiting for request to arrive and
+     * for them to complete. The thread should be favored when competing
+     * with any other threads except timer threads.
+     */
+    RTTHREADTYPE_IO,
+    /** The timer thread type.
+     * A timer thread is mostly waiting for the timer to tick
+     * and then perform a little bit of work. Accuracy is important here,
+     * so the thread should be favoured over all threads. If premention can
+     * be configured at thread level, it could be made very short.
+     */
+    RTTHREADTYPE_TIMER,
+    /** Only used for validation. */
+    RTTHREADTYPE_END
+} RTTHREADTYPE;
+
+
+#ifndef IN_RC
+
+/**
+ * Checks if the IPRT thread component has been initialized.
+ *
+ * This is used to avoid calling into RTThread before the runtime has been
+ * initialized.
+ *
+ * @returns @c true if it's initialized, @c false if not.
+ */
+RTDECL(bool) RTThreadIsInitialized(void);
+
+/**
+ * Get the thread handle of the current thread.
+ *
+ * @returns Thread handle.
+ */
+RTDECL(RTTHREAD) RTThreadSelf(void);
+
+/**
+ * Get the native thread handle of the current thread.
+ *
+ * @returns Native thread handle.
+ */
+RTDECL(RTNATIVETHREAD) RTThreadNativeSelf(void);
+
+/**
+ * Millisecond granular sleep function.
+ *
+ * @returns VINF_SUCCESS on success.
+ * @returns VERR_INTERRUPTED if a signal or other asynchronous stuff happened
+ *          which interrupt the peaceful sleep.
+ * @param   cMillies    Number of milliseconds to sleep.
+ *                      0 milliseconds means yielding the timeslice - deprecated!
+ * @remark  See RTThreadNanoSleep() for sleeping for smaller periods of time.
+ */
+RTDECL(int) RTThreadSleep(RTMSINTERVAL cMillies);
+
+/**
+ * Millisecond granular sleep function, no logger calls.
+ *
+ * Same as RTThreadSleep, except it will never call into the IPRT logger.  It
+ * can therefore safely be used in places where the logger is off limits, like
+ * at termination or init time.  The electric fence heap is one consumer of
+ * this API.
+ *
+ * @returns VINF_SUCCESS on success.
+ * @returns VERR_INTERRUPTED if a signal or other asynchronous stuff happened
+ *          which interrupt the peaceful sleep.
+ * @param   cMillies    Number of milliseconds to sleep.
+ *                      0 milliseconds means yielding the timeslice - deprecated!
+ */
+RTDECL(int) RTThreadSleepNoLog(RTMSINTERVAL cMillies);
+
+/**
+ * Yields the CPU.
+ *
+ * @returns true if we yielded.
+ * @returns false if it's probable that we didn't yield.
+ */
+RTDECL(bool) RTThreadYield(void);
+
+
+
+/**
+ * Thread function.
+ *
+ * @returns 0 on success.
+ * @param   ThreadSelf  Thread handle to this thread.
+ * @param   pvUser      User argument.
+ */
+typedef DECLCALLBACK(int) FNRTTHREAD(RTTHREAD ThreadSelf, void *pvUser);
+/** Pointer to a FNRTTHREAD(). */
+typedef FNRTTHREAD *PFNRTTHREAD;
+
+/**
+ * Thread creation flags.
+ */
+typedef enum RTTHREADFLAGS
+{
+    /** This flag is used to keep the thread structure around so it can
+     * be waited on after termination.  @sa RTThreadWait and
+     * RTThreadWaitNoResume.  Not required for RTThreadUserWait and friends!
+     */
+    RTTHREADFLAGS_WAITABLE = RT_BIT(0),
+    /** The bit number corresponding to the RTTHREADFLAGS_WAITABLE mask. */
+    RTTHREADFLAGS_WAITABLE_BIT = 0,
+
+    /** Mask of valid flags, use for validation. */
+    RTTHREADFLAGS_MASK = RT_BIT(0)
+} RTTHREADFLAGS;
+
+
+/**
+ * Create a new thread.
+ *
+ * @returns iprt status code.
+ * @param   pThread     Where to store the thread handle to the new thread. (optional)
+ * @param   pfnThread   The thread function.
+ * @param   pvUser      User argument.
+ * @param   cbStack     The size of the stack for the new thread.
+ *                      Use 0 for the default stack size.
+ * @param   enmType     The thread type. Used for deciding scheduling attributes
+ *                      of the thread.
+ * @param   fFlags      Flags of the RTTHREADFLAGS type (ORed together).
+ * @param   pszName     Thread name.
+ *
+ * @remark  When called in Ring-0, this API will create a new kernel thread and not a thread in
+ *          the context of the calling process.
+ */
+RTDECL(int) RTThreadCreate(PRTTHREAD pThread, PFNRTTHREAD pfnThread, void *pvUser, size_t cbStack,
+                           RTTHREADTYPE enmType, unsigned fFlags, const char *pszName);
+#ifndef RT_OS_LINUX /* XXX crashes genksyms at least on 32-bit Linux hosts */
+/** @copydoc RTThreadCreate */
+typedef DECLCALLBACKPTR(int, PFNRTTHREADCREATE)(PRTTHREAD pThread, PFNRTTHREAD pfnThread, void *pvUser, size_t cbStack,
+                                                RTTHREADTYPE enmType, unsigned fFlags, const char *pszName);
+#endif
+
+
+/**
+ * Create a new thread.
+ *
+ * Same as RTThreadCreate except the name is given in the RTStrPrintfV form.
+ *
+ * @returns iprt status code.
+ * @param   pThread     See RTThreadCreate.
+ * @param   pfnThread   See RTThreadCreate.
+ * @param   pvUser      See RTThreadCreate.
+ * @param   cbStack     See RTThreadCreate.
+ * @param   enmType     See RTThreadCreate.
+ * @param   fFlags      See RTThreadCreate.
+ * @param   pszName     Thread name format.
+ * @param   va          Format arguments.
+ */
+RTDECL(int) RTThreadCreateV(PRTTHREAD pThread, PFNRTTHREAD pfnThread, void *pvUser, size_t cbStack,
+                            RTTHREADTYPE enmType, uint32_t fFlags, const char *pszNameFmt, va_list va) RT_IPRT_FORMAT_ATTR(7, 0);
+
+/**
+ * Create a new thread.
+ *
+ * Same as RTThreadCreate except the name is given in the RTStrPrintf form.
+ *
+ * @returns iprt status code.
+ * @param   pThread     See RTThreadCreate.
+ * @param   pfnThread   See RTThreadCreate.
+ * @param   pvUser      See RTThreadCreate.
+ * @param   cbStack     See RTThreadCreate.
+ * @param   enmType     See RTThreadCreate.
+ * @param   fFlags      See RTThreadCreate.
+ * @param   pszName     Thread name format.
+ * @param   ...         Format arguments.
+ */
+RTDECL(int) RTThreadCreateF(PRTTHREAD pThread, PFNRTTHREAD pfnThread, void *pvUser, size_t cbStack,
+                            RTTHREADTYPE enmType, uint32_t fFlags, const char *pszNameFmt, ...) RT_IPRT_FORMAT_ATTR(7, 8);
+
+/**
+ * Gets the native thread id of a IPRT thread.
+ *
+ * @returns The native thread id.
+ * @param   Thread      The IPRT thread.
+ */
+RTDECL(RTNATIVETHREAD) RTThreadGetNative(RTTHREAD Thread);
+
+/**
+ * Gets the IPRT thread of a native thread.
+ *
+ * @returns The IPRT thread handle
+ * @returns NIL_RTTHREAD if not a thread known to IPRT.
+ * @param   NativeThread        The native thread handle/id.
+ */
+RTDECL(RTTHREAD) RTThreadFromNative(RTNATIVETHREAD NativeThread);
+
+/**
+ * Changes the type of the specified thread.
+ *
+ * @returns iprt status code.
+ * @param   Thread      The thread which type should be changed.
+ * @param   enmType     The new thread type.
+ * @remark  In Ring-0 it only works if Thread == RTThreadSelf().
+ */
+RTDECL(int) RTThreadSetType(RTTHREAD Thread, RTTHREADTYPE enmType);
+
+/**
+ * Wait for the thread to terminate, resume on interruption.
+ *
+ * @returns     iprt status code.
+ *              Will not return VERR_INTERRUPTED.
+ * @param       Thread          The thread to wait for.
+ * @param       cMillies        The number of milliseconds to wait. Use RT_INDEFINITE_WAIT for
+ *                              an indefinite wait.
+ * @param       prc             Where to store the return code of the thread. Optional.
+ */
+RTDECL(int) RTThreadWait(RTTHREAD Thread, RTMSINTERVAL cMillies, int *prc);
+
+/**
+ * Wait for the thread to terminate, return on interruption.
+ *
+ * @returns     iprt status code.
+ * @param       Thread          The thread to wait for.
+ * @param       cMillies        The number of milliseconds to wait. Use RT_INDEFINITE_WAIT for
+ *                              an indefinite wait.
+ * @param       prc             Where to store the return code of the thread. Optional.
+ */
+RTDECL(int) RTThreadWaitNoResume(RTTHREAD Thread, RTMSINTERVAL cMillies, int *prc);
+
+/**
+ * Gets the name of the current thread thread.
+ *
+ * @returns Pointer to readonly name string.
+ * @returns NULL on failure.
+ */
+RTDECL(const char *) RTThreadSelfName(void);
+
+/**
+ * Gets the name of a thread.
+ *
+ * @returns Pointer to readonly name string.
+ * @returns NULL on failure.
+ * @param   Thread      Thread handle of the thread to query the name of.
+ */
+RTDECL(const char *) RTThreadGetName(RTTHREAD Thread);
+
+/**
+ * Gets the type of the specified thread.
+ *
+ * @returns The thread type.
+ * @returns RTTHREADTYPE_INVALID if the thread handle is invalid.
+ * @param   Thread      The thread in question.
+ */
+RTDECL(RTTHREADTYPE) RTThreadGetType(RTTHREAD Thread);
+
+/**
+ * Sets the name of a thread.
+ *
+ * @returns iprt status code.
+ * @param   Thread      Thread handle of the thread to query the name of.
+ * @param   pszName     The thread name.
+ */
+RTDECL(int) RTThreadSetName(RTTHREAD Thread, const char *pszName);
+
+/**
+ * Checks if the specified thread is the main thread.
+ *
+ * @returns true if it is, false if it isn't.
+ *
+ * @param   hThread     The thread handle.
+ */
+RTDECL(bool) RTThreadIsMain(RTTHREAD hThread);
+
+/**
+ * Checks if the calling thread is known to IPRT.
+ *
+ * @returns @c true if it is, @c false if it isn't.
+ */
+RTDECL(bool) RTThreadIsSelfKnown(void);
+
+/**
+ * Checks if the calling thread is know to IPRT and is alive.
+ *
+ * @returns @c true if it is, @c false if it isn't.
+ */
+RTDECL(bool) RTThreadIsSelfAlive(void);
+
+/**
+ * Checks if the calling thread is known to IPRT.
+ *
+ * @returns @c true if it is, @c false if it isn't.
+ */
+RTDECL(bool) RTThreadIsOperational(void);
+
+/**
+ * Signal the user event.
+ *
+ * @returns     iprt status code.
+ */
+RTDECL(int) RTThreadUserSignal(RTTHREAD Thread);
+
+/**
+ * Wait for the user event.
+ *
+ * @returns     iprt status code.
+ * @param       Thread          The thread to wait for.
+ * @param       cMillies        The number of milliseconds to wait. Use RT_INDEFINITE_WAIT for
+ *                              an indefinite wait.
+ */
+RTDECL(int) RTThreadUserWait(RTTHREAD Thread, RTMSINTERVAL cMillies);
+
+/**
+ * Wait for the user event, return on interruption.
+ *
+ * @returns     iprt status code.
+ * @param       Thread          The thread to wait for.
+ * @param       cMillies        The number of milliseconds to wait. Use RT_INDEFINITE_WAIT for
+ *                              an indefinite wait.
+ */
+RTDECL(int) RTThreadUserWaitNoResume(RTTHREAD Thread, RTMSINTERVAL cMillies);
+
+/**
+ * Reset the user event.
+ *
+ * @returns     iprt status code.
+ * @param       Thread          The thread to reset.
+ */
+RTDECL(int) RTThreadUserReset(RTTHREAD Thread);
+
+/**
+ * Pokes the thread.
+ *
+ * This will signal the thread, attempting to interrupt whatever it's currently
+ * doing.  This is *NOT* implemented on all platforms and may cause unresolved
+ * symbols during linking or VERR_NOT_IMPLEMENTED at runtime.
+ *
+ * @returns IPRT status code.
+ *
+ * @param   hThread             The thread to poke.  This must not be the
+ *                              calling thread.
+ */
+RTDECL(int) RTThreadPoke(RTTHREAD hThread);
+
+# ifdef IN_RING0
+
+/**
+ * Check if preemption is currently enabled or not for the current thread.
+ *
+ * @note    This may return true even on systems where preemption isn't
+ *          possible. In that case, it means no call to RTThreadPreemptDisable
+ *          has been made and interrupts are still enabled.
+ *
+ * @returns true if preemption is enabled, false if preemetion is disabled.
+ * @param   hThread             Must be NIL_RTTHREAD for now.
+ */
+RTDECL(bool) RTThreadPreemptIsEnabled(RTTHREAD hThread);
+
+/**
+ * Check if preemption is pending for the current thread.
+ *
+ * This function should be called regularly when executing larger portions of
+ * code with preemption disabled.
+ *
+ * @returns true if pending, false if not.
+ * @param       hThread         Must be NIL_RTTHREAD for now.
+ */
+RTDECL(bool) RTThreadPreemptIsPending(RTTHREAD hThread);
+
+/**
+ * Is RTThreadPreemptIsPending reliable?
+ *
+ * @returns true if reliable, false if not.
+ */
+RTDECL(bool) RTThreadPreemptIsPendingTrusty(void);
+
+/**
+ * Is preemption possible on this system.
+ *
+ * @returns true if possible, false if not.
+ */
+RTDECL(bool) RTThreadPreemptIsPossible(void);
+
+/**
+ * Preemption state saved by RTThreadPreemptDisable and used by
+ * RTThreadPreemptRestore to restore the previous state.
+ */
+typedef struct RTTHREADPREEMPTSTATE
+{
+    /** In debug builds this will be used to check for cpu migration. */
+    RTCPUID         idCpu;
+#  ifdef RT_OS_WINDOWS
+    /** The old IRQL. Don't touch! */
+    unsigned char   uchOldIrql;
+    /** Reserved, MBZ. */
+    uint8_t         bReserved1;
+    /** Reserved, MBZ. */
+    uint8_t         bReserved2;
+    /** Reserved, MBZ. */
+    uint8_t         bReserved3;
+#   define RTTHREADPREEMPTSTATE_INITIALIZER { NIL_RTCPUID, 255, 0, 0, 0 }
+#  elif defined(RT_OS_HAIKU)
+    /** The cpu_state. Don't touch! */
+    uint32_t        uOldCpuState;
+#   define RTTHREADPREEMPTSTATE_INITIALIZER { NIL_RTCPUID, 0 }
+#  elif defined(RT_OS_SOLARIS)
+    /** The Old PIL. Don't touch! */
+    uint32_t        uOldPil;
+#   define RTTHREADPREEMPTSTATE_INITIALIZER { NIL_RTCPUID, UINT32_MAX }
+#  else
+    /** Reserved, MBZ. */
+    uint32_t        u32Reserved;
+#   define RTTHREADPREEMPTSTATE_INITIALIZER { NIL_RTCPUID, 0 }
+#  endif
+} RTTHREADPREEMPTSTATE;
+/** Pointer to a preemption state. */
+typedef RTTHREADPREEMPTSTATE *PRTTHREADPREEMPTSTATE;
+
+/**
+ * Disable preemption.
+ *
+ * A call to this function must be matched by exactly one call to
+ * RTThreadPreemptRestore().
+ *
+ * @param   pState              Where to store the preemption state.
+ */
+RTDECL(void) RTThreadPreemptDisable(PRTTHREADPREEMPTSTATE pState);
+
+/**
+ * Restores the preemption state, undoing a previous call to
+ * RTThreadPreemptDisable.
+ *
+ * A call to this function must be matching a previous call to
+ * RTThreadPreemptDisable.
+ *
+ * @param  pState               The state return by RTThreadPreemptDisable.
+ */
+RTDECL(void) RTThreadPreemptRestore(PRTTHREADPREEMPTSTATE pState);
+
+/**
+ * Check if the thread is executing in interrupt context.
+ *
+ * @returns true if in interrupt context, false if not.
+ * @param       hThread         Must be NIL_RTTHREAD for now.
+ */
+RTDECL(bool) RTThreadIsInInterrupt(RTTHREAD hThread);
+
+
+/**
+ * Thread context swithcing events.
+ */
+typedef enum RTTHREADCTXEVENT
+{
+    /** This thread is being scheduled out on the current CPU (includes preemption,
+     * waiting, sleep and whatever else may trigger scheduling). */
+    RTTHREADCTXEVENT_OUT = 0,
+    /** This thread is being scheduled in on the current CPU and will resume
+     * execution. */
+    RTTHREADCTXEVENT_IN,
+    /** The usual 32-bit size hack. */
+    RTTHREADCTXEVENT_32BIT_HACK = 0x7fffffff
+} RTTHREADCTXEVENT;
+
+/**
+ * Thread context switching hook callback.
+ *
+ * This hook function is called when a thread is scheduled and preempted.  Check
+ * @a enmEvent to see which it is.  Since the function is being called from
+ * hooks inside the scheduler, it is limited what you can do from this function.
+ * Do NOT acquire locks, sleep or yield the thread for instance.  IRQ safe
+ * spinlocks are fine though.
+ *
+ * @returns IPRT status code.
+ * @param   enmEvent    The thread-context event.  Please quitely ignore unknown
+ *                      events, we may add more (thread exit, ++) later.
+ * @param   pvUser      User argument.
+ */
+typedef DECLCALLBACK(void) FNRTTHREADCTXHOOK(RTTHREADCTXEVENT enmEvent, void *pvUser);
+/** Pointer to a context switching hook. */
+typedef FNRTTHREADCTXHOOK *PFNRTTHREADCTXHOOK;
+
+/**
+ * Initializes a thread context switching hook for the current thread.
+ *
+ * The hook is created as disabled, use RTThreadCtxHookEnable to enable it.
+ *
+ * @returns IPRT status code.
+ * @param   phCtxHook       Where to store the hook handle.
+ * @param   fFlags          Reserved for future extensions, must be zero.
+ * @param   pfnCallback     Pointer to a the hook function (callback) that
+ *                          should be called for all context switching events
+ *                          involving the current thread.
+ * @param   pvUser          User argument that will be passed to @a pfnCallback.
+ * @remarks Preemption must be enabled.
+ */
+RTDECL(int) RTThreadCtxHookCreate(PRTTHREADCTXHOOK phCtxHook, uint32_t fFlags, PFNRTTHREADCTXHOOK pfnCallback, void *pvUser);
+
+/**
+ * Destroys a thread context switching hook.
+ *
+ * Caller must make sure the hook is disabled before the final reference is
+ * released.  Recommended to call this on the owning thread, otherwise the
+ * memory backing it may on some systems only be released when the thread
+ * terminates.
+ *
+ * @returns IPRT status code.
+ *
+ * @param   hCtxHook        The context hook handle.  NIL_RTTHREADCTXHOOK is
+ *                          ignored and the function will return VINF_SUCCESS.
+ * @remarks Preemption must be enabled.
+ * @remarks Do not call from FNRTTHREADCTXHOOK.
+ */
+RTDECL(int) RTThreadCtxHookDestroy(RTTHREADCTXHOOK hCtxHook);
+
+/**
+ * Enables the context switching hooks for the current thread.
+ *
+ * @returns IPRT status code.
+ * @param   hCtxHook        The context hook handle.
+ * @remarks Should be called with preemption disabled.
+ */
+RTDECL(int) RTThreadCtxHookEnable(RTTHREADCTXHOOK hCtxHook);
+
+/**
+ * Disables the thread context switching hook for the current thread.
+ *
+ * Will not assert or fail if called twice or with a NIL handle.
+ *
+ * @returns IPRT status code.
+ * @param   hCtxHook        The context hook handle. NIL_RTTHREADCTXHOOK is
+ *                          ignored and the function wil return VINF_SUCCESS.
+ * @remarks Should be called with preemption disabled.
+ * @remarks Do not call from FNRTTHREADCTXHOOK.
+ */
+RTDECL(int) RTThreadCtxHookDisable(RTTHREADCTXHOOK hCtxHook);
+
+/**
+ * Is the thread context switching hook enabled?
+ *
+ * @returns true if registered, false if not supported or not registered.
+ * @param   hCtxHook        The context hook handle.   NIL_RTTHREADCTXHOOK is
+ *                          ignored and the function will return false.
+ *
+ * @remarks Can be called from any thread, though is naturally subject to races
+ *          when not called from the thread associated with the hook.
+ */
+RTDECL(bool) RTThreadCtxHookIsEnabled(RTTHREADCTXHOOK hCtxHook);
+
+# endif /* IN_RING0 */
+
+
+# ifdef IN_RING3
+
+/**
+ * Adopts a non-IPRT thread.
+ *
+ * @returns IPRT status code.
+ * @param   enmType         The thread type.
+ * @param   fFlags          The thread flags. RTTHREADFLAGS_WAITABLE is not currently allowed.
+ * @param   pszName         The thread name. Optional
+ * @param   pThread         Where to store the thread handle. Optional.
+ */
+RTDECL(int) RTThreadAdopt(RTTHREADTYPE enmType, unsigned fFlags, const char *pszName, PRTTHREAD pThread);
+
+/**
+ * Get the thread handle of the current thread, automatically adopting alien
+ * threads.
+ *
+ * @returns Thread handle.
+ */
+RTDECL(RTTHREAD) RTThreadSelfAutoAdopt(void);
+
+/**
+ * Gets the affinity mask of the current thread.
+ *
+ * @returns IPRT status code.
+ * @param   pCpuSet         Where to return the CPU affienty set of the calling
+ *                          thread.
+ */
+RTR3DECL(int) RTThreadGetAffinity(PRTCPUSET pCpuSet);
+
+/**
+ * Sets the affinity mask of the current thread.
+ *
+ * @returns iprt status code.
+ * @param   pCpuSet         The set of CPUs this thread can run on.  NULL means
+ *                          all CPUs.
+ */
+RTR3DECL(int) RTThreadSetAffinity(PCRTCPUSET pCpuSet);
+
+/**
+ * Binds the thread to one specific CPU.
+ *
+ * @returns iprt status code.
+ * @param   idCpu           The ID of the CPU to bind this thread to.  Use
+ *                          NIL_RTCPUID to unbind it.
+ */
+RTR3DECL(int) RTThreadSetAffinityToCpu(RTCPUID idCpu);
+
+/**
+ * Unblocks a thread.
+ *
+ * This function is paired with RTThreadBlocking and RTThreadBlockingDebug.
+ *
+ * @param   hThread     The current thread.
+ * @param   enmCurState The current state, used to check for nested blocking.
+ *                      The new state will be running.
+ */
+RTDECL(void) RTThreadUnblocked(RTTHREAD hThread, RTTHREADSTATE enmCurState);
+
+/**
+ * Change the thread state to blocking.
+ *
+ * @param   hThread         The current thread.
+ * @param   enmState        The sleep state.
+ * @param   fReallySleeping Really going to sleep now.  Use false before calls
+ *                          to other IPRT synchronization methods.
+ */
+RTDECL(void) RTThreadBlocking(RTTHREAD hThread, RTTHREADSTATE enmState, bool fReallySleeping);
+
+/**
+ * Get the current thread state.
+ *
+ * A thread that is reported as sleeping may actually still be running inside
+ * the lock validator or/and in the code of some other IPRT synchronization
+ * primitive.  Use RTThreadGetReallySleeping
+ *
+ * @returns The thread state.
+ * @param   hThread         The thread.
+ */
+RTDECL(RTTHREADSTATE) RTThreadGetState(RTTHREAD hThread);
+
+/**
+ * Checks if the thread is really sleeping or not.
+ *
+ * @returns RTTHREADSTATE_RUNNING if not really sleeping, otherwise the state it
+ *          is sleeping in.
+ * @param   hThread         The thread.
+ */
+RTDECL(RTTHREADSTATE) RTThreadGetReallySleeping(RTTHREAD hThread);
+
+/**
+ * Translate a thread state into a string.
+ *
+ * @returns Pointer to a read-only string containing the state name.
+ * @param   enmState            The state.
+ */
+RTDECL(const char *) RTThreadStateName(RTTHREADSTATE enmState);
+
+
+/**
+ * Native thread states returned by RTThreadNativeState.
+ */
+typedef enum RTTHREADNATIVESTATE
+{
+    /** Invalid thread handle. */
+    RTTHREADNATIVESTATE_INVALID = 0,
+    /** Unable to determine the thread state. */
+    RTTHREADNATIVESTATE_UNKNOWN,
+    /** The thread is running. */
+    RTTHREADNATIVESTATE_RUNNING,
+    /** The thread is blocked. */
+    RTTHREADNATIVESTATE_BLOCKED,
+    /** The thread is suspended / stopped. */
+    RTTHREADNATIVESTATE_SUSPENDED,
+    /** The thread has terminated. */
+    RTTHREADNATIVESTATE_TERMINATED,
+    /** Make sure it's a 32-bit type. */
+    RTTHREADNATIVESTATE_32BIT_HACK = 0x7fffffff
+} RTTHREADNATIVESTATE;
+
+
+/**
+ * Get the native state of a thread.
+ *
+ * @returns Native state.
+ * @param   hThread             The thread handle.
+ *
+ * @remarks Not yet implemented on all systems, so have a backup plan for
+ *          RTTHREADNATIVESTATE_UNKNOWN.
+ */
+RTDECL(RTTHREADNATIVESTATE) RTThreadGetNativeState(RTTHREAD hThread);
+
+
+/**
+ * Get the execution times of the specified thread
+ *
+ * @returns IPRT status code.
+ * @param   pKernelTime         Kernel execution time in ms (out)
+ * @param   pUserTime           User execution time in ms (out)
+ *
+ */
+RTR3DECL(int) RTThreadGetExecutionTimeMilli(uint64_t *pKernelTime, uint64_t *pUserTime);
+
+/** @name Thread Local Storage
+ * @{
+ */
+/**
+ * Thread termination callback for destroying a non-zero TLS entry.
+ *
+ * @remarks It is not permitable to use any RTTls APIs at this time. Doing so
+ *          may lead to endless loops, crashes, and other bad stuff.
+ *
+ * @param   pvValue     The current value.
+ */
+typedef DECLCALLBACK(void) FNRTTLSDTOR(void *pvValue);
+/** Pointer to a FNRTTLSDTOR. */
+typedef FNRTTLSDTOR *PFNRTTLSDTOR;
+
+/**
+ * Allocates a TLS entry (index).
+ *
+ * Example code:
+ * @code
+    RTTLS g_iTls = NIL_RTTLS;
+
+    ...
+
+    // once for the process, allocate the TLS index
+    if (g_iTls == NIL_RTTLS)
+         g_iTls = RTTlsAlloc();
+
+    // set the thread-local value.
+    RTTlsSet(g_iTls, pMyData);
+
+    ...
+
+    // get the thread-local value
+    PMYDATA pMyData = (PMYDATA)RTTlsGet(g_iTls);
+
+   @endcode
+ *
+ * @returns the index of the allocated TLS entry.
+ * @returns NIL_RTTLS on failure.
+ */
+RTR3DECL(RTTLS) RTTlsAlloc(void);
+
+/**
+ * Variant of RTTlsAlloc that returns a status code.
+ *
+ * @returns IPRT status code.
+ * @retval  VERR_NOT_SUPPORTED if pfnDestructor is non-NULL and the platform
+ *          doesn't support this feature.
+ *
+ * @param   piTls           Where to store the index of the allocated TLS entry.
+ *                          This is set to NIL_RTTLS on failure.
+ * @param   pfnDestructor   Optional callback function for cleaning up on
+ *                          thread termination. WARNING! This feature may not
+ *                          be implemented everywhere.
+ */
+RTR3DECL(int) RTTlsAllocEx(PRTTLS piTls, PFNRTTLSDTOR pfnDestructor);
+
+/**
+ * Frees a TLS entry.
+ *
+ * @returns IPRT status code.
+ * @param   iTls        The index of the TLS entry.
+ */
+RTR3DECL(int) RTTlsFree(RTTLS iTls);
+
+/**
+ * Get the (thread-local) value stored in a TLS entry.
+ *
+ * @returns value in given TLS entry.
+ * @retval  NULL if RTTlsSet() has not yet been called on this thread, or if the
+ *          TLS index is invalid.
+ *
+ * @param   iTls        The index of the TLS entry.
+ */
+RTR3DECL(void *) RTTlsGet(RTTLS iTls);
+
+/**
+ * Get the value stored in a TLS entry.
+ *
+ * @returns IPRT status code.
+ * @param   iTls        The index of the TLS entry.
+ * @param   ppvValue    Where to store the value.  The value will be NULL if
+ *                      RTTlsSet has not yet been called on this thread.
+ */
+RTR3DECL(int) RTTlsGetEx(RTTLS iTls, void **ppvValue);
+
+/**
+ * Set the value stored in an allocated TLS entry.
+ *
+ * @returns IPRT status.
+ * @param   iTls        The index of the TLS entry.
+ * @param   pvValue     The value to store.
+ *
+ * @remarks Note that NULL is considered a special value.
+ */
+RTR3DECL(int) RTTlsSet(RTTLS iTls, void *pvValue);
+
+/** @} */
+
+# endif /* IN_RING3 */
+# endif /* !IN_RC */
+
+/** @} */
+
+RT_C_DECLS_END
+
+#endif
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/include/iprt/time.h
@@ -0,0 +1,1034 @@
+/** @file
+ * IPRT - Time.
+ */
+
+/*
+ * Copyright (C) 2006-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+#ifndef ___iprt_time_h
+#define ___iprt_time_h
+
+#include <iprt/cdefs.h>
+#include <iprt/types.h>
+
+RT_C_DECLS_BEGIN
+
+/** @defgroup grp_rt_time   RTTime - Time
+ * @ingroup grp_rt
+ * @{
+ */
+
+/** Time Specification.
+ *
+ * Use the inline RTTimeSpecGet/Set to operate on structure this so we
+ * can easily change the representation if required later.
+ *
+ * The current representation is in nanoseconds relative to the unix epoch
+ * (1970-01-01 00:00:00 UTC). This gives us an approximate span from
+ * 1678 to 2262 without sacrificing the resolution offered by the various
+ * host OSes (BSD & LINUX 1ns, NT 100ns).
+ */
+typedef struct RTTIMESPEC
+{
+    /** Nanoseconds since epoch.
+     * The name is intentially too long to be comfortable to use because you should be
+     * using inline helpers! */
+    int64_t     i64NanosecondsRelativeToUnixEpoch;
+} RTTIMESPEC;
+
+
+/** @name RTTIMESPEC methods
+ * @{ */
+
+/**
+ * Gets the time as nanoseconds relative to the unix epoch.
+ *
+ * @returns Nanoseconds relative to unix epoch.
+ * @param   pTime       The time spec to interpret.
+ */
+DECLINLINE(int64_t) RTTimeSpecGetNano(PCRTTIMESPEC pTime)
+{
+    return pTime->i64NanosecondsRelativeToUnixEpoch;
+}
+
+
+/**
+ * Sets the time give by nanoseconds relative to the unix epoch.
+ *
+ * @returns pTime.
+ * @param   pTime       The time spec to modify.
+ * @param   i64Nano     The new time in nanoseconds.
+ */
+DECLINLINE(PRTTIMESPEC) RTTimeSpecSetNano(PRTTIMESPEC pTime, int64_t i64Nano)
+{
+    pTime->i64NanosecondsRelativeToUnixEpoch = i64Nano;
+    return pTime;
+}
+
+
+/**
+ * Gets the time as microseconds relative to the unix epoch.
+ *
+ * @returns microseconds relative to unix epoch.
+ * @param   pTime       The time spec to interpret.
+ */
+DECLINLINE(int64_t) RTTimeSpecGetMicro(PCRTTIMESPEC pTime)
+{
+    return pTime->i64NanosecondsRelativeToUnixEpoch / RT_NS_1US;
+}
+
+
+/**
+ * Sets the time given by microseconds relative to the unix epoch.
+ *
+ * @returns pTime.
+ * @param   pTime       The time spec to modify.
+ * @param   i64Micro    The new time in microsecond.
+ */
+DECLINLINE(PRTTIMESPEC) RTTimeSpecSetMicro(PRTTIMESPEC pTime, int64_t i64Micro)
+{
+    pTime->i64NanosecondsRelativeToUnixEpoch = i64Micro * RT_NS_1US;
+    return pTime;
+}
+
+
+/**
+ * Gets the time as milliseconds relative to the unix epoch.
+ *
+ * @returns milliseconds relative to unix epoch.
+ * @param   pTime       The time spec to interpret.
+ */
+DECLINLINE(int64_t) RTTimeSpecGetMilli(PCRTTIMESPEC pTime)
+{
+    return pTime->i64NanosecondsRelativeToUnixEpoch / RT_NS_1MS;
+}
+
+
+/**
+ * Sets the time given by milliseconds relative to the unix epoch.
+ *
+ * @returns pTime.
+ * @param   pTime       The time spec to modify.
+ * @param   i64Milli    The new time in milliseconds.
+ */
+DECLINLINE(PRTTIMESPEC) RTTimeSpecSetMilli(PRTTIMESPEC pTime, int64_t i64Milli)
+{
+    pTime->i64NanosecondsRelativeToUnixEpoch = i64Milli * RT_NS_1MS;
+    return pTime;
+}
+
+
+/**
+ * Gets the time as seconds relative to the unix epoch.
+ *
+ * @returns seconds relative to unix epoch.
+ * @param   pTime       The time spec to interpret.
+ */
+DECLINLINE(int64_t) RTTimeSpecGetSeconds(PCRTTIMESPEC pTime)
+{
+    return pTime->i64NanosecondsRelativeToUnixEpoch / RT_NS_1SEC;
+}
+
+
+/**
+ * Sets the time given by seconds relative to the unix epoch.
+ *
+ * @returns pTime.
+ * @param   pTime       The time spec to modify.
+ * @param   i64Seconds  The new time in seconds.
+ */
+DECLINLINE(PRTTIMESPEC) RTTimeSpecSetSeconds(PRTTIMESPEC pTime, int64_t i64Seconds)
+{
+    pTime->i64NanosecondsRelativeToUnixEpoch = i64Seconds * RT_NS_1SEC;
+    return pTime;
+}
+
+
+/**
+ * Makes the time spec absolute like abs() does (i.e. a positive value).
+ *
+ * @returns pTime.
+ * @param   pTime       The time spec to modify.
+ */
+DECLINLINE(PRTTIMESPEC) RTTimeSpecAbsolute(PRTTIMESPEC pTime)
+{
+    if (pTime->i64NanosecondsRelativeToUnixEpoch < 0)
+        pTime->i64NanosecondsRelativeToUnixEpoch = -pTime->i64NanosecondsRelativeToUnixEpoch;
+    return pTime;
+}
+
+
+/**
+ * Negates the time.
+ *
+ * @returns pTime.
+ * @param   pTime       The time spec to modify.
+ */
+DECLINLINE(PRTTIMESPEC) RTTimeSpecNegate(PRTTIMESPEC pTime)
+{
+    pTime->i64NanosecondsRelativeToUnixEpoch = -pTime->i64NanosecondsRelativeToUnixEpoch;
+    return pTime;
+}
+
+
+/**
+ * Adds a time period to the time.
+ *
+ * @returns pTime.
+ * @param   pTime       The time spec to modify.
+ * @param   pTimeAdd    The time spec to add to pTime.
+ */
+DECLINLINE(PRTTIMESPEC) RTTimeSpecAdd(PRTTIMESPEC pTime, PCRTTIMESPEC pTimeAdd)
+{
+    pTime->i64NanosecondsRelativeToUnixEpoch += pTimeAdd->i64NanosecondsRelativeToUnixEpoch;
+    return pTime;
+}
+
+
+/**
+ * Adds a time period give as nanoseconds from the time.
+ *
+ * @returns pTime.
+ * @param   pTime       The time spec to modify.
+ * @param   i64Nano     The time period in nanoseconds.
+ */
+DECLINLINE(PRTTIMESPEC) RTTimeSpecAddNano(PRTTIMESPEC pTime, int64_t i64Nano)
+{
+    pTime->i64NanosecondsRelativeToUnixEpoch += i64Nano;
+    return pTime;
+}
+
+
+/**
+ * Adds a time period give as microseconds from the time.
+ *
+ * @returns pTime.
+ * @param   pTime       The time spec to modify.
+ * @param   i64Micro    The time period in microseconds.
+ */
+DECLINLINE(PRTTIMESPEC) RTTimeSpecAddMicro(PRTTIMESPEC pTime, int64_t i64Micro)
+{
+    pTime->i64NanosecondsRelativeToUnixEpoch += i64Micro * RT_NS_1US;
+    return pTime;
+}
+
+
+/**
+ * Adds a time period give as milliseconds from the time.
+ *
+ * @returns pTime.
+ * @param   pTime       The time spec to modify.
+ * @param   i64Milli    The time period in milliseconds.
+ */
+DECLINLINE(PRTTIMESPEC) RTTimeSpecAddMilli(PRTTIMESPEC pTime, int64_t i64Milli)
+{
+    pTime->i64NanosecondsRelativeToUnixEpoch += i64Milli * RT_NS_1MS;
+    return pTime;
+}
+
+
+/**
+ * Adds a time period give as seconds from the time.
+ *
+ * @returns pTime.
+ * @param   pTime       The time spec to modify.
+ * @param   i64Seconds  The time period in seconds.
+ */
+DECLINLINE(PRTTIMESPEC) RTTimeSpecAddSeconds(PRTTIMESPEC pTime, int64_t i64Seconds)
+{
+    pTime->i64NanosecondsRelativeToUnixEpoch += i64Seconds * RT_NS_1SEC;
+    return pTime;
+}
+
+
+/**
+ * Subtracts a time period from the time.
+ *
+ * @returns pTime.
+ * @param   pTime       The time spec to modify.
+ * @param   pTimeSub    The time spec to subtract from pTime.
+ */
+DECLINLINE(PRTTIMESPEC) RTTimeSpecSub(PRTTIMESPEC pTime, PCRTTIMESPEC pTimeSub)
+{
+    pTime->i64NanosecondsRelativeToUnixEpoch -= pTimeSub->i64NanosecondsRelativeToUnixEpoch;
+    return pTime;
+}
+
+
+/**
+ * Subtracts a time period give as nanoseconds from the time.
+ *
+ * @returns pTime.
+ * @param   pTime       The time spec to modify.
+ * @param   i64Nano     The time period in nanoseconds.
+ */
+DECLINLINE(PRTTIMESPEC) RTTimeSpecSubNano(PRTTIMESPEC pTime, int64_t i64Nano)
+{
+    pTime->i64NanosecondsRelativeToUnixEpoch -= i64Nano;
+    return pTime;
+}
+
+
+/**
+ * Subtracts a time period give as microseconds from the time.
+ *
+ * @returns pTime.
+ * @param   pTime       The time spec to modify.
+ * @param   i64Micro    The time period in microseconds.
+ */
+DECLINLINE(PRTTIMESPEC) RTTimeSpecSubMicro(PRTTIMESPEC pTime, int64_t i64Micro)
+{
+    pTime->i64NanosecondsRelativeToUnixEpoch -= i64Micro * RT_NS_1US;
+    return pTime;
+}
+
+
+/**
+ * Subtracts a time period give as milliseconds from the time.
+ *
+ * @returns pTime.
+ * @param   pTime       The time spec to modify.
+ * @param   i64Milli    The time period in milliseconds.
+ */
+DECLINLINE(PRTTIMESPEC) RTTimeSpecSubMilli(PRTTIMESPEC pTime, int64_t i64Milli)
+{
+    pTime->i64NanosecondsRelativeToUnixEpoch -= i64Milli * RT_NS_1MS;
+    return pTime;
+}
+
+
+/**
+ * Subtracts a time period give as seconds from the time.
+ *
+ * @returns pTime.
+ * @param   pTime       The time spec to modify.
+ * @param   i64Seconds  The time period in seconds.
+ */
+DECLINLINE(PRTTIMESPEC) RTTimeSpecSubSeconds(PRTTIMESPEC pTime, int64_t i64Seconds)
+{
+    pTime->i64NanosecondsRelativeToUnixEpoch -= i64Seconds * RT_NS_1SEC;
+    return pTime;
+}
+
+
+/**
+ * Gives the time in seconds and nanoseconds.
+ *
+ * @returns pTime.
+ * @param   pTime           The time spec to interpret.
+ * @param   *pi32Seconds    Where to store the time period in seconds.
+ * @param   *pi32Nano       Where to store the time period in nanoseconds.
+ */
+DECLINLINE(void) RTTimeSpecGetSecondsAndNano(PRTTIMESPEC pTime, int32_t *pi32Seconds, int32_t *pi32Nano)
+{
+    int64_t i64 = RTTimeSpecGetNano(pTime);
+    int32_t i32Nano = (int32_t)(i64 % RT_NS_1SEC);
+    i64 /= RT_NS_1SEC;
+    if (i32Nano < 0)
+    {
+        i32Nano += RT_NS_1SEC;
+        i64--;
+    }
+    *pi32Seconds = (int32_t)i64;
+    *pi32Nano    = i32Nano;
+}
+
+
+/* PORTME: Add struct timeval guard macro here. */
+#if defined(RTTIME_INCL_TIMEVAL) || defined(_STRUCT_TIMEVAL) || defined(_SYS__TIMEVAL_H_) || defined(_SYS_TIME_H) || defined(_TIMEVAL) || defined(_LINUX_TIME_H)
+/**
+ * Gets the time as POSIX timeval.
+ *
+ * @returns pTime.
+ * @param   pTime       The time spec to interpret.
+ * @param   pTimeval    Where to store the time as POSIX timeval.
+ */
+DECLINLINE(struct timeval *) RTTimeSpecGetTimeval(PCRTTIMESPEC pTime, struct timeval *pTimeval)
+{
+    int64_t i64 = RTTimeSpecGetMicro(pTime);
+    int32_t i32Micro = (int32_t)(i64 % RT_US_1SEC);
+    i64 /= RT_US_1SEC;
+    if (i32Micro < 0)
+    {
+        i32Micro += RT_US_1SEC;
+        i64--;
+    }
+    pTimeval->tv_sec = (time_t)i64;
+    pTimeval->tv_usec = i32Micro;
+    return pTimeval;
+}
+
+/**
+ * Sets the time as POSIX timeval.
+ *
+ * @returns pTime.
+ * @param   pTime       The time spec to modify.
+ * @param   pTimeval    Pointer to the POSIX timeval struct with the new time.
+ */
+DECLINLINE(PRTTIMESPEC) RTTimeSpecSetTimeval(PRTTIMESPEC pTime, const struct timeval *pTimeval)
+{
+    return RTTimeSpecAddMicro(RTTimeSpecSetSeconds(pTime, pTimeval->tv_sec), pTimeval->tv_usec);
+}
+#endif /* various ways of detecting struct timeval */
+
+
+/* PORTME: Add struct timespec guard macro here. */
+#if defined(RTTIME_INCL_TIMESPEC) || defined(_STRUCT_TIMESPEC) || defined(_SYS__TIMESPEC_H_) || defined(TIMEVAL_TO_TIMESPEC) || defined(_TIMESPEC)
+/**
+ * Gets the time as POSIX timespec.
+ *
+ * @returns pTime.
+ * @param   pTime       The time spec to interpret.
+ * @param   pTimespec   Where to store the time as POSIX timespec.
+ */
+DECLINLINE(struct timespec *) RTTimeSpecGetTimespec(PCRTTIMESPEC pTime, struct timespec *pTimespec)
+{
+    int64_t i64 = RTTimeSpecGetNano(pTime);
+    int32_t i32Nano = (int32_t)(i64 % RT_NS_1SEC);
+    i64 /= RT_NS_1SEC;
+    if (i32Nano < 0)
+    {
+        i32Nano += RT_NS_1SEC;
+        i64--;
+    }
+    pTimespec->tv_sec = (time_t)i64;
+    pTimespec->tv_nsec = i32Nano;
+    return pTimespec;
+}
+
+/**
+ * Sets the time as POSIX timespec.
+ *
+ * @returns pTime.
+ * @param   pTime       The time spec to modify.
+ * @param   pTimespec   Pointer to the POSIX timespec struct with the new time.
+ */
+DECLINLINE(PRTTIMESPEC) RTTimeSpecSetTimespec(PRTTIMESPEC pTime, const struct timespec *pTimespec)
+{
+    return RTTimeSpecAddNano(RTTimeSpecSetSeconds(pTime, pTimespec->tv_sec), pTimespec->tv_nsec);
+}
+#endif /* various ways of detecting struct timespec */
+
+
+
+/** The offset of the unix epoch and the base for NT time (in 100ns units).
+ * Nt time starts at 1601-01-01 00:00:00. */
+#define RTTIME_NT_TIME_OFFSET_UNIX      (116444736000000000LL)
+
+
+/**
+ * Gets the time as NT time.
+ *
+ * @returns Nt time.
+ * @param   pTime       The time spec to interpret.
+ */
+DECLINLINE(uint64_t) RTTimeSpecGetNtTime(PCRTTIMESPEC pTime)
+{
+    return pTime->i64NanosecondsRelativeToUnixEpoch / 100
+        + RTTIME_NT_TIME_OFFSET_UNIX;
+}
+
+
+/**
+ * Sets the time given by Nt time.
+ *
+ * @returns pTime.
+ * @param   pTime       The time spec to modify.
+ * @param   u64NtTime   The new time in Nt time.
+ */
+DECLINLINE(PRTTIMESPEC) RTTimeSpecSetNtTime(PRTTIMESPEC pTime, uint64_t u64NtTime)
+{
+    pTime->i64NanosecondsRelativeToUnixEpoch =
+        ((int64_t)u64NtTime - RTTIME_NT_TIME_OFFSET_UNIX) * 100;
+    return pTime;
+}
+
+
+#ifdef _FILETIME_
+/**
+ * Gets the time as NT file time.
+ *
+ * @returns pFileTime.
+ * @param   pTime       The time spec to interpret.
+ * @param   pFileTime   Pointer to NT filetime structure.
+ */
+DECLINLINE(PFILETIME) RTTimeSpecGetNtFileTime(PCRTTIMESPEC pTime, PFILETIME pFileTime)
+{
+    *((uint64_t *)pFileTime) = RTTimeSpecGetNtTime(pTime);
+    return pFileTime;
+}
+
+/**
+ * Sets the time as NT file time.
+ *
+ * @returns pTime.
+ * @param   pTime       The time spec to modify.
+ * @param   pFileTime   Where to store the time as Nt file time.
+ */
+DECLINLINE(PRTTIMESPEC) RTTimeSpecSetNtFileTime(PRTTIMESPEC pTime, const FILETIME *pFileTime)
+{
+    return RTTimeSpecSetNtTime(pTime, *(const uint64_t *)pFileTime);
+}
+#endif
+
+
+/** The offset to the start of DOS time.
+ * DOS time starts 1980-01-01 00:00:00.  */
+#define RTTIME_OFFSET_DOS_TIME          (315532800000000000LL)
+
+
+/**
+ * Gets the time as seconds relative to the start of dos time.
+ *
+ * @returns seconds relative to the start of dos time.
+ * @param   pTime       The time spec to interpret.
+ */
+DECLINLINE(int64_t) RTTimeSpecGetDosSeconds(PCRTTIMESPEC pTime)
+{
+    return (pTime->i64NanosecondsRelativeToUnixEpoch - RTTIME_OFFSET_DOS_TIME)
+        / RT_NS_1SEC;
+}
+
+
+/**
+ * Sets the time given by seconds relative to the start of dos time.
+ *
+ * @returns pTime.
+ * @param   pTime       The time spec to modify.
+ * @param   i64Seconds  The new time in seconds relative to the start of dos time.
+ */
+DECLINLINE(PRTTIMESPEC) RTTimeSpecSetDosSeconds(PRTTIMESPEC pTime, int64_t i64Seconds)
+{
+    pTime->i64NanosecondsRelativeToUnixEpoch = i64Seconds * RT_NS_1SEC
+        + RTTIME_OFFSET_DOS_TIME;
+    return pTime;
+}
+
+
+/**
+ * Compare two time specs.
+ *
+ * @returns true they are equal.
+ * @returns false they are not equal.
+ * @param   pTime1  The 1st time spec.
+ * @param   pTime2  The 2nd time spec.
+ */
+DECLINLINE(bool) RTTimeSpecIsEqual(PCRTTIMESPEC pTime1, PCRTTIMESPEC pTime2)
+{
+    return pTime1->i64NanosecondsRelativeToUnixEpoch == pTime2->i64NanosecondsRelativeToUnixEpoch;
+}
+
+
+/**
+ * Compare two time specs.
+ *
+ * @returns 0 if equal, -1 if @a pLeft is smaller, 1 if @a pLeft is larger.
+ * @returns false they are not equal.
+ * @param   pLeft       The 1st time spec.
+ * @param   pRight      The 2nd time spec.
+ */
+DECLINLINE(int) RTTimeSpecCompare(PCRTTIMESPEC pLeft, PCRTTIMESPEC pRight)
+{
+    if (pLeft->i64NanosecondsRelativeToUnixEpoch == pRight->i64NanosecondsRelativeToUnixEpoch)
+        return 0;
+    return pLeft->i64NanosecondsRelativeToUnixEpoch < pRight->i64NanosecondsRelativeToUnixEpoch ? -1 : 1;
+}
+
+
+/**
+ * Converts a time spec to a ISO date string.
+ *
+ * @returns psz on success.
+ * @returns NULL on buffer underflow.
+ * @param   pTime       The time spec.
+ * @param   psz         Where to store the string.
+ * @param   cb          The size of the buffer.
+ */
+RTDECL(char *) RTTimeSpecToString(PCRTTIMESPEC pTime, char *psz, size_t cb);
+
+/**
+ * Attempts to convert an ISO date string to a time structure.
+ *
+ * We're a little forgiving with zero padding, unspecified parts, and leading
+ * and trailing spaces.
+ *
+ * @retval  pTime on success,
+ * @retval  NULL on failure.
+ * @param   pTime       The time spec.
+ * @param   pszString   The ISO date string to convert.
+ */
+RTDECL(PRTTIMESPEC) RTTimeSpecFromString(PRTTIMESPEC pTime, const char *pszString);
+
+/** @} */
+
+
+/**
+ * Exploded time.
+ */
+#pragma pack(1)
+typedef struct RTTIME
+{
+    /** The year number. */
+    int32_t     i32Year;
+    /** The month of the year (1-12). January is 1. */
+    uint8_t     u8Month;
+    /** The day of the week (0-6). Monday is 0. */
+    uint8_t     u8WeekDay;
+    /** The day of the year (1-366). January the 1st is 1. */
+    uint16_t    u16YearDay;
+    /** The day of the month (1-31). */
+    uint8_t     u8MonthDay;
+    /** Hour of the day (0-23). */
+    uint8_t     u8Hour;
+    /** The minute of the hour (0-59). */
+    uint8_t     u8Minute;
+    /** The second of the minute (0-60).
+     * (u32Nanosecond / 1000000) */
+    uint8_t     u8Second;
+    /** The nanoseconds of the second (0-999999999). */
+    uint32_t    u32Nanosecond;
+    /** Flags, of the RTTIME_FLAGS_* \#defines. */
+    uint32_t    fFlags;
+    /** UCT time offset in minutes (-840-840).
+     * @remarks The implementation of RTTimeLocal* isn't quite there yet, so this might not be 100% correct. */
+    int32_t     offUTC;
+} RTTIME;
+#pragma pack()
+/** Pointer to a exploded time structure. */
+typedef RTTIME *PRTTIME;
+/** Pointer to a const exploded time structure. */
+typedef const RTTIME *PCRTTIME;
+
+/** @name RTTIME::fFlags values.
+ * @{ */
+/** Set if the time is UTC. If clear the time local time. */
+#define RTTIME_FLAGS_TYPE_MASK      3
+/** the time is UTC time. */
+#define RTTIME_FLAGS_TYPE_UTC       2
+/** The time is local time. */
+#define RTTIME_FLAGS_TYPE_LOCAL     3
+
+/** Set if the time is local and daylight saving time is in effect.
+ * Not bit is not valid if RTTIME_FLAGS_NO_DST_DATA is set. */
+#define RTTIME_FLAGS_DST            RT_BIT(4)
+/** Set if the time is local and there is no data available on daylight saving time. */
+#define RTTIME_FLAGS_NO_DST_DATA    RT_BIT(5)
+/** Set if the year is a leap year.
+ * This is mutual exclusiv with RTTIME_FLAGS_COMMON_YEAR. */
+#define RTTIME_FLAGS_LEAP_YEAR      RT_BIT(6)
+/** Set if the year is a common year.
+ * This is mutual exclusiv with RTTIME_FLAGS_LEAP_YEAR. */
+#define RTTIME_FLAGS_COMMON_YEAR    RT_BIT(7)
+/** The mask of valid flags. */
+#define RTTIME_FLAGS_MASK           UINT32_C(0xff)
+/** @} */
+
+
+/**
+ * Gets the current system time (UTC).
+ *
+ * @returns pTime.
+ * @param   pTime       Where to store the time.
+ */
+RTDECL(PRTTIMESPEC) RTTimeNow(PRTTIMESPEC pTime);
+
+/**
+ * Sets the system time.
+ *
+ * @returns IPRT status code
+ * @param   pTime       The new system time (UTC).
+ *
+ * @remarks This will usually fail because changing the wall time is usually
+ *          requires extra privileges.
+ */
+RTDECL(int) RTTimeSet(PCRTTIMESPEC pTime);
+
+/**
+ * Explodes a time spec (UTC).
+ *
+ * @returns pTime.
+ * @param   pTime       Where to store the exploded time.
+ * @param   pTimeSpec   The time spec to exploded.
+ */
+RTDECL(PRTTIME) RTTimeExplode(PRTTIME pTime, PCRTTIMESPEC pTimeSpec);
+
+/**
+ * Implodes exploded time to a time spec (UTC).
+ *
+ * @returns pTime on success.
+ * @returns NULL if the pTime data is invalid.
+ * @param   pTimeSpec   Where to store the imploded UTC time.
+ *                      If pTime specifies a time which outside the range, maximum or
+ *                      minimum values will be returned.
+ * @param   pTime       Pointer to the exploded time to implode.
+ *                      The fields u8Month, u8WeekDay and u8MonthDay are not used,
+ *                      and all the other fields are expected to be within their
+ *                      bounds. Use RTTimeNormalize() to calculate u16YearDay and
+ *                      normalize the ranges of the fields.
+ */
+RTDECL(PRTTIMESPEC) RTTimeImplode(PRTTIMESPEC pTimeSpec, PCRTTIME pTime);
+
+/**
+ * Normalizes the fields of a time structure.
+ *
+ * It is possible to calculate year-day from month/day and vice
+ * versa. If you adjust any of of these, make sure to zero the
+ * other so you make it clear which of the fields to use. If
+ * it's ambiguous, the year-day field is used (and you get
+ * assertions in debug builds).
+ *
+ * All the time fields and the year-day or month/day fields will
+ * be adjusted for overflows. (Since all fields are unsigned, there
+ * is no underflows.) It is possible to exploit this for simple
+ * date math, though the recommended way of doing that to implode
+ * the time into a timespec and do the math on that.
+ *
+ * @returns pTime on success.
+ * @returns NULL if the data is invalid.
+ *
+ * @param   pTime       The time structure to normalize.
+ *
+ * @remarks This function doesn't work with local time, only with UTC time.
+ */
+RTDECL(PRTTIME) RTTimeNormalize(PRTTIME pTime);
+
+/**
+ * Gets the current local system time.
+ *
+ * @returns pTime.
+ * @param   pTime   Where to store the local time.
+ */
+RTDECL(PRTTIMESPEC) RTTimeLocalNow(PRTTIMESPEC pTime);
+
+/**
+ * Gets the delta between UTC and local time.
+ *
+ * @code
+ *      RTTIMESPEC LocalTime;
+ *      RTTimeSpecAddNano(RTTimeNow(&LocalTime), RTTimeLocalDeltaNano());
+ * @endcode
+ *
+ * @returns Returns the nanosecond delta between UTC and local time.
+ */
+RTDECL(int64_t) RTTimeLocalDeltaNano(void);
+
+/**
+ * Explodes a time spec to the localized timezone.
+ *
+ * @returns pTime.
+ * @param   pTime       Where to store the exploded time.
+ * @param   pTimeSpec   The time spec to exploded (UTC).
+ */
+RTDECL(PRTTIME) RTTimeLocalExplode(PRTTIME pTime, PCRTTIMESPEC pTimeSpec);
+
+/**
+ * Normalizes the fields of a time structure containing local time.
+ *
+ * See RTTimeNormalize for details.
+ *
+ * @returns pTime on success.
+ * @returns NULL if the data is invalid.
+ * @param   pTime       The time structure to normalize.
+ */
+RTDECL(PRTTIME) RTTimeLocalNormalize(PRTTIME pTime);
+
+/**
+ * Converts a time spec to a ISO date string.
+ *
+ * @returns psz on success.
+ * @returns NULL on buffer underflow.
+ * @param   pTime       The time. Caller should've normalized this.
+ * @param   psz         Where to store the string.
+ * @param   cb          The size of the buffer.
+ */
+RTDECL(char *) RTTimeToString(PCRTTIME pTime, char *psz, size_t cb);
+
+/**
+ * Attempts to convert an ISO date string to a time structure.
+ *
+ * We're a little forgiving with zero padding, unspecified parts, and leading
+ * and trailing spaces.
+ *
+ * @retval  pTime on success,
+ * @retval  NULL on failure.
+ * @param   pTime       Where to store the time on success.
+ * @param   pszString   The ISO date string to convert.
+ */
+RTDECL(PRTTIME) RTTimeFromString(PRTTIME pTime, const char *pszString);
+
+/**
+ * Checks if a year is a leap year or not.
+ *
+ * @returns true if it's a leap year.
+ * @returns false if it's a common year.
+ * @param   i32Year     The year in question.
+ */
+RTDECL(bool) RTTimeIsLeapYear(int32_t i32Year);
+
+/**
+ * Gets the current nanosecond timestamp.
+ *
+ * @returns nanosecond timestamp.
+ */
+RTDECL(uint64_t) RTTimeNanoTS(void);
+
+/**
+ * Gets the current millisecond timestamp.
+ *
+ * @returns millisecond timestamp.
+ */
+RTDECL(uint64_t) RTTimeMilliTS(void);
+
+/**
+ * Debugging the time api.
+ *
+ * @returns the number of 1ns steps which has been applied by RTTimeNanoTS().
+ */
+RTDECL(uint32_t) RTTimeDbgSteps(void);
+
+/**
+ * Debugging the time api.
+ *
+ * @returns the number of times the TSC interval expired RTTimeNanoTS().
+ */
+RTDECL(uint32_t) RTTimeDbgExpired(void);
+
+/**
+ * Debugging the time api.
+ *
+ * @returns the number of bad previous values encountered by RTTimeNanoTS().
+ */
+RTDECL(uint32_t) RTTimeDbgBad(void);
+
+/**
+ * Debugging the time api.
+ *
+ * @returns the number of update races in RTTimeNanoTS().
+ */
+RTDECL(uint32_t) RTTimeDbgRaces(void);
+
+/** @name RTTimeNanoTS GIP worker functions, for TM.
+ * @{ */
+/** Pointer to a RTTIMENANOTSDATA structure. */
+typedef struct RTTIMENANOTSDATA *PRTTIMENANOTSDATA;
+
+/**
+ * Nanosecond timestamp data.
+ *
+ * This is used to keep track of statistics and callback so IPRT
+ * and TM (VirtualBox) can share code.
+ *
+ * @remark Keep this in sync with the assembly version in timesupA.asm.
+ */
+typedef struct RTTIMENANOTSDATA
+{
+    /** Where the previous timestamp is stored.
+     * This is maintained to ensure that time doesn't go backwards or anything. */
+    uint64_t volatile  *pu64Prev;
+
+    /**
+     * Helper function that's used by the assembly routines when something goes bust.
+     *
+     * @param   pData           Pointer to this structure.
+     * @param   u64NanoTS       The calculated nano ts.
+     * @param   u64DeltaPrev    The delta relative to the previously returned timestamp.
+     * @param   u64PrevNanoTS   The previously returned timestamp (as it was read it).
+     */
+    DECLCALLBACKMEMBER(void, pfnBad)(PRTTIMENANOTSDATA pData, uint64_t u64NanoTS, uint64_t u64DeltaPrev, uint64_t u64PrevNanoTS);
+
+    /**
+     * Callback for when rediscovery is required.
+     *
+     * @returns Nanosecond timestamp.
+     * @param   pData           Pointer to this structure.
+     */
+    DECLCALLBACKMEMBER(uint64_t, pfnRediscover)(PRTTIMENANOTSDATA pData);
+
+    /**
+     * Callback for when some CPU index related stuff goes wrong.
+     *
+     * @returns Nanosecond timestamp.
+     * @param   pData           Pointer to this structure.
+     * @param   idApic          The APIC ID if available, otherwise (UINT16_MAX-1).
+     * @param   iCpuSet         The CPU set index if available, otherwise
+     *                          (UINT16_MAX-1).
+     * @param   iGipCpu         The GIP CPU array index if available, otherwise
+     *                          (UINT16_MAX-1).
+     */
+    DECLCALLBACKMEMBER(uint64_t, pfnBadCpuIndex)(PRTTIMENANOTSDATA pData, uint16_t idApic, uint16_t iCpuSet, uint16_t iGipCpu);
+
+    /** Number of 1ns steps because of overshooting the period. */
+    uint32_t            c1nsSteps;
+    /** The number of times the interval expired (overflow). */
+    uint32_t            cExpired;
+    /** Number of "bad" previous values. */
+    uint32_t            cBadPrev;
+    /** The number of update races. */
+    uint32_t            cUpdateRaces;
+} RTTIMENANOTSDATA;
+
+#ifndef IN_RING3
+/**
+ * The Ring-3 layout of the RTTIMENANOTSDATA structure.
+ */
+typedef struct RTTIMENANOTSDATAR3
+{
+    R3PTRTYPE(uint64_t volatile  *) pu64Prev;
+    DECLR3CALLBACKMEMBER(void, pfnBad,(PRTTIMENANOTSDATA pData, uint64_t u64NanoTS, uint64_t u64DeltaPrev, uint64_t u64PrevNanoTS));
+    DECLR3CALLBACKMEMBER(uint64_t, pfnRediscover,(PRTTIMENANOTSDATA pData));
+    DECLR3CALLBACKMEMBER(uint64_t, pfnBadCpuIndex,(PRTTIMENANOTSDATA pData, uint16_t idApic, uint16_t iCpuSet, uint16_t iGipCpu));
+    uint32_t            c1nsSteps;
+    uint32_t            cExpired;
+    uint32_t            cBadPrev;
+    uint32_t            cUpdateRaces;
+} RTTIMENANOTSDATAR3;
+#else
+typedef RTTIMENANOTSDATA RTTIMENANOTSDATAR3;
+#endif
+
+#ifndef IN_RING0
+/**
+ * The Ring-3 layout of the RTTIMENANOTSDATA structure.
+ */
+typedef struct RTTIMENANOTSDATAR0
+{
+    R0PTRTYPE(uint64_t volatile  *) pu64Prev;
+    DECLR0CALLBACKMEMBER(void, pfnBad,(PRTTIMENANOTSDATA pData, uint64_t u64NanoTS, uint64_t u64DeltaPrev, uint64_t u64PrevNanoTS));
+    DECLR0CALLBACKMEMBER(uint64_t, pfnRediscover,(PRTTIMENANOTSDATA pData));
+    DECLR0CALLBACKMEMBER(uint64_t, pfnBadCpuIndex,(PRTTIMENANOTSDATA pData, uint16_t idApic, uint16_t iCpuSet, uint16_t iGipCpu));
+    uint32_t            c1nsSteps;
+    uint32_t            cExpired;
+    uint32_t            cBadPrev;
+    uint32_t            cUpdateRaces;
+} RTTIMENANOTSDATAR0;
+#else
+typedef RTTIMENANOTSDATA RTTIMENANOTSDATAR0;
+#endif
+
+#ifndef IN_RC
+/**
+ * The RC layout of the RTTIMENANOTSDATA structure.
+ */
+typedef struct RTTIMENANOTSDATARC
+{
+    RCPTRTYPE(uint64_t volatile  *) pu64Prev;
+    DECLRCCALLBACKMEMBER(void, pfnBad,(PRTTIMENANOTSDATA pData, uint64_t u64NanoTS, uint64_t u64DeltaPrev, uint64_t u64PrevNanoTS));
+    DECLRCCALLBACKMEMBER(uint64_t, pfnRediscover,(PRTTIMENANOTSDATA pData));
+    DECLRCCALLBACKMEMBER(uint64_t, pfnBadCpuIndex,(PRTTIMENANOTSDATA pData, uint16_t idApic, uint16_t iCpuSet, uint16_t iGipCpu));
+    uint32_t            c1nsSteps;
+    uint32_t            cExpired;
+    uint32_t            cBadPrev;
+    uint32_t            cUpdateRaces;
+} RTTIMENANOTSDATARC;
+#else
+typedef RTTIMENANOTSDATA RTTIMENANOTSDATARC;
+#endif
+
+/** Internal RTTimeNanoTS worker (assembly). */
+typedef DECLCALLBACK(uint64_t) FNTIMENANOTSINTERNAL(PRTTIMENANOTSDATA pData);
+/** Pointer to an internal RTTimeNanoTS worker (assembly). */
+typedef FNTIMENANOTSINTERNAL *PFNTIMENANOTSINTERNAL;
+RTDECL(uint64_t) RTTimeNanoTSLegacySyncInvarNoDelta(PRTTIMENANOTSDATA pData);
+RTDECL(uint64_t) RTTimeNanoTSLFenceSyncInvarNoDelta(PRTTIMENANOTSDATA pData);
+#ifdef IN_RING3
+RTDECL(uint64_t) RTTimeNanoTSLegacyAsyncUseApicId(PRTTIMENANOTSDATA pData);
+RTDECL(uint64_t) RTTimeNanoTSLegacyAsyncUseRdtscp(PRTTIMENANOTSDATA pData);
+RTDECL(uint64_t) RTTimeNanoTSLegacyAsyncUseIdtrLim(PRTTIMENANOTSDATA pData);
+RTDECL(uint64_t) RTTimeNanoTSLegacySyncInvarWithDeltaUseApicId(PRTTIMENANOTSDATA pData);
+RTDECL(uint64_t) RTTimeNanoTSLegacySyncInvarWithDeltaUseRdtscp(PRTTIMENANOTSDATA pData);
+RTDECL(uint64_t) RTTimeNanoTSLegacySyncInvarWithDeltaUseIdtrLim(PRTTIMENANOTSDATA pData);
+RTDECL(uint64_t) RTTimeNanoTSLFenceAsyncUseApicId(PRTTIMENANOTSDATA pData);
+RTDECL(uint64_t) RTTimeNanoTSLFenceAsyncUseRdtscp(PRTTIMENANOTSDATA pData);
+RTDECL(uint64_t) RTTimeNanoTSLFenceAsyncUseIdtrLim(PRTTIMENANOTSDATA pData);
+RTDECL(uint64_t) RTTimeNanoTSLFenceSyncInvarWithDeltaUseApicId(PRTTIMENANOTSDATA pData);
+RTDECL(uint64_t) RTTimeNanoTSLFenceSyncInvarWithDeltaUseRdtscp(PRTTIMENANOTSDATA pData);
+RTDECL(uint64_t) RTTimeNanoTSLFenceSyncInvarWithDeltaUseIdtrLim(PRTTIMENANOTSDATA pData);
+#else
+RTDECL(uint64_t) RTTimeNanoTSLegacyAsync(PRTTIMENANOTSDATA pData);
+RTDECL(uint64_t) RTTimeNanoTSLegacySyncInvarWithDelta(PRTTIMENANOTSDATA pData);
+RTDECL(uint64_t) RTTimeNanoTSLFenceAsync(PRTTIMENANOTSDATA pData);
+RTDECL(uint64_t) RTTimeNanoTSLFenceSyncInvarWithDelta(PRTTIMENANOTSDATA pData);
+#endif
+
+/** @} */
+
+
+/**
+ * Gets the current nanosecond timestamp.
+ *
+ * This differs from RTTimeNanoTS in that it will use system APIs and not do any
+ * resolution or performance optimizations.
+ *
+ * @returns nanosecond timestamp.
+ */
+RTDECL(uint64_t) RTTimeSystemNanoTS(void);
+
+/**
+ * Gets the current millisecond timestamp.
+ *
+ * This differs from RTTimeNanoTS in that it will use system APIs and not do any
+ * resolution or performance optimizations.
+ *
+ * @returns millisecond timestamp.
+ */
+RTDECL(uint64_t) RTTimeSystemMilliTS(void);
+
+/**
+ * Get the nanosecond timestamp relative to program startup.
+ *
+ * @returns Timestamp relative to program startup.
+ */
+RTDECL(uint64_t)  RTTimeProgramNanoTS(void);
+
+/**
+ * Get the microsecond timestamp relative to program startup.
+ *
+ * @returns Timestamp relative to program startup.
+ */
+RTDECL(uint64_t)  RTTimeProgramMicroTS(void);
+
+/**
+ * Get the millisecond timestamp relative to program startup.
+ *
+ * @returns Timestamp relative to program startup.
+ */
+RTDECL(uint64_t)  RTTimeProgramMilliTS(void);
+
+/**
+ * Get the second timestamp relative to program startup.
+ *
+ * @returns Timestamp relative to program startup.
+ */
+RTDECL(uint32_t)  RTTimeProgramSecTS(void);
+
+/**
+ * Get the RTTimeNanoTS() of when the program started.
+ *
+ * @returns Program startup timestamp.
+ */
+RTDECL(uint64_t) RTTimeProgramStartNanoTS(void);
+
+/** @} */
+
+RT_C_DECLS_END
+
+#endif
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/include/iprt/timer.h
@@ -0,0 +1,387 @@
+/** @file
+ * IPRT - Timer.
+ */
+
+/*
+ * Copyright (C) 2006-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+#ifndef ___iprt_timer_h
+#define ___iprt_timer_h
+
+
+#include <iprt/cdefs.h>
+#include <iprt/types.h>
+
+
+RT_C_DECLS_BEGIN
+
+/** @defgroup grp_rt_timer      RTTimer - Timer
+ *
+ * The IPRT timer API provides a simple abstraction of recurring and one-shot callback timers.
+ *
+ * Because of the great variation in the native APIs and the quality of
+ * the service delivered by those native APIs, the timers are operated
+ * on at best effort basis.
+ *
+ * All the ring-3 implementations are naturally at the mercy of the scheduler,
+ * which means that the callback rate might vary quite a bit and we might skip
+ * ticks. Many systems have a restriction that a process can only have one
+ * timer. IPRT currently makes no efforts at multiplexing timers in those kind
+ * of situations and will simply fail if you try to create more than one timer.
+ *
+ * Things are generally better in ring-0. The implementations will use interrupt
+ * time callbacks wherever available, and if not, resort to a high priority
+ * kernel thread.
+ *
+ * @ingroup grp_rt
+ * @{
+ */
+
+
+/** Timer handle. */
+typedef struct RTTIMER   *PRTTIMER;
+
+/**
+ * Timer callback function.
+ *
+ * The context this call is made in varies with different platforms and
+ * kernel / user mode IPRT.
+ *
+ * In kernel mode a timer callback should not waste time, it shouldn't
+ * waste stack and it should be prepared that some APIs might not work
+ * correctly because of weird OS restrictions in this context that we
+ * haven't discovered and avoided yet. Please fix those APIs so they
+ * at least avoid panics and weird behaviour.
+ *
+ * @param   pTimer      Timer handle.
+ * @param   pvUser      User argument.
+ * @param   iTick       The current timer tick. This is always 1 on the first
+ *                      callback after the timer was started. For omni timers
+ *                      this will be 1 when a cpu comes back online.
+ */
+typedef DECLCALLBACK(void) FNRTTIMER(PRTTIMER pTimer, void *pvUser, uint64_t iTick);
+/** Pointer to FNRTTIMER() function. */
+typedef FNRTTIMER *PFNRTTIMER;
+
+
+/**
+ * Create a recurring timer.
+ *
+ * @returns iprt status code.
+ * @param   ppTimer             Where to store the timer handle.
+ * @param   uMilliesInterval    Milliseconds between the timer ticks.
+ *                              This is rounded up to the system granularity.
+ * @param   pfnTimer            Callback function which shall be scheduled for execution
+ *                              on every timer tick.
+ * @param   pvUser              User argument for the callback.
+ * @see     RTTimerCreateEx, RTTimerStart, RTTimerStop, RTTimerChangeInterval,
+ *          RTTimerDestroy, RTTimerGetSystemGranularity
+ */
+RTDECL(int) RTTimerCreate(PRTTIMER *ppTimer, unsigned uMilliesInterval, PFNRTTIMER pfnTimer, void *pvUser);
+
+/**
+ * Create a suspended timer.
+ *
+ * @returns iprt status code.
+ * @retval  VERR_NOT_SUPPORTED if an unsupported flag was specfied.
+ * @retval  VERR_CPU_NOT_FOUND if the specified CPU
+ *
+ * @param   ppTimer             Where to store the timer handle.
+ * @param   u64NanoInterval     The interval between timer ticks specified in nanoseconds if it's
+ *                              a recurring timer. This is rounded to the fit the system timer granularity.
+ *                              For one shot timers, pass 0.
+ * @param   fFlags              Timer flags.
+ * @param   pfnTimer            Callback function which shall be scheduled for execution
+ *                              on every timer tick.
+ * @param   pvUser              User argument for the callback.
+ * @see     RTTimerStart, RTTimerStop, RTTimerChangeInterval, RTTimerDestroy,
+ *          RTTimerGetSystemGranularity, RTTimerCanDoHighResolution
+ */
+RTDECL(int) RTTimerCreateEx(PRTTIMER *ppTimer, uint64_t u64NanoInterval, uint32_t fFlags, PFNRTTIMER pfnTimer, void *pvUser);
+
+/** @name RTTimerCreateEx flags
+ * @{ */
+/** Any CPU is fine. (Must be 0.) */
+#define RTTIMER_FLAGS_CPU_ANY       UINT32_C(0)
+/** One specific CPU */
+#define RTTIMER_FLAGS_CPU_SPECIFIC  RT_BIT(16)
+/** Omni timer, run on all online CPUs.
+ * @remarks The timer callback isn't necessarily running at the time same time on each CPU. */
+#define RTTIMER_FLAGS_CPU_ALL       ( RTTIMER_FLAGS_CPU_MASK | RTTIMER_FLAGS_CPU_SPECIFIC )
+/** CPU mask. */
+#define RTTIMER_FLAGS_CPU_MASK      UINT32_C(0xffff)
+/** Desire a high resolution timer that works with RTTimerChangeInterval and
+ * isn't subject to RTTimerGetSystemGranularity rounding.
+ * @remarks This is quietly ignored if the feature isn't supported. */
+#define RTTIMER_FLAGS_HIGH_RES      RT_BIT(17)
+/** Convert a CPU set index (0-based) to RTTimerCreateEx flags.
+ * This will automatically OR in the RTTIMER_FLAGS_CPU_SPECIFIC flag. */
+#define RTTIMER_FLAGS_CPU(iCpu)     ( (iCpu) | RTTIMER_FLAGS_CPU_SPECIFIC )
+/** Macro that validates the flags. */
+#define RTTIMER_FLAGS_ARE_VALID(fFlags) \
+    ( !((fFlags) & ~((fFlags) & RTTIMER_FLAGS_CPU_SPECIFIC ? UINT32_C(0x3ffff) : UINT32_C(0x30000))) )
+/** @} */
+
+/**
+ * Stops and destroys a running timer.
+ *
+ * @returns iprt status code.
+ * @retval  VERR_INVALID_CONTEXT if executing at the wrong IRQL (windows), PIL
+ *          (solaris), or similar.  Portable code does not destroy timers with
+ *          preemption (or interrupts) disabled.
+ * @param   pTimer      Timer to stop and destroy. NULL is ok.
+ */
+RTDECL(int) RTTimerDestroy(PRTTIMER pTimer);
+
+/**
+ * Starts a suspended timer.
+ *
+ * @returns IPRT status code.
+ * @retval  VERR_INVALID_HANDLE if pTimer isn't valid.
+ * @retval  VERR_TIMER_ACTIVE if the timer isn't suspended.
+ * @retval  VERR_CPU_OFFLINE if the CPU the timer was created to run on is not
+ *          online (this include the case where it's not present in the
+ *          system).
+ *
+ * @param   pTimer      The timer to activate.
+ * @param   u64First    The RTTimeSystemNanoTS() for when the timer should start
+ *                      firing (relative).  If 0 is specified, the timer will
+ *                      fire ASAP.
+ * @remarks When RTTimerCanDoHighResolution returns true, this API is
+ *          callable with preemption disabled in ring-0.
+ * @see     RTTimerStop
+ */
+RTDECL(int) RTTimerStart(PRTTIMER pTimer, uint64_t u64First);
+
+/**
+ * Stops an active timer.
+ *
+ * @todo    May return while the timer callback function is being services on
+ *          some platforms (ring-0 Windows, ring-0 linux).  This needs to be
+ *          addressed at some point...
+ *
+ * @returns IPRT status code.
+ * @retval  VERR_INVALID_HANDLE if pTimer isn't valid.
+ * @retval  VERR_TIMER_SUSPENDED if the timer isn't active.
+ * @retval  VERR_NOT_SUPPORTED if the IPRT implementation doesn't support
+ *          stopping a timer.
+ *
+ * @param   pTimer  The timer to suspend.
+ * @remarks Can be called from the timer callback function to stop it.
+ * @see     RTTimerStart
+ */
+RTDECL(int) RTTimerStop(PRTTIMER pTimer);
+
+/**
+ * Changes the interval of a periodic timer.
+ *
+ * If the timer is active, it is implementation dependent whether the change
+ * takes place immediately or after the next tick.  To get defined behavior,
+ * stop the timer before calling this API.
+ *
+ * @returns IPRT status code.
+ * @retval  VERR_INVALID_HANDLE if pTimer isn't valid.
+ * @retval  VERR_NOT_SUPPORTED if not supported.
+ * @retval  VERR_INVALID_STATE if not a periodic timer.
+ *
+ * @param   pTimer              The timer to activate.
+ * @param   u64NanoInterval     The interval between timer ticks specified in
+ *                              nanoseconds.  This is rounded to the fit the
+ *                              system timer granularity.
+ * @remarks Callable from the timer callback.  Callable with preemption
+ *          disabled in ring-0.
+ */
+RTDECL(int) RTTimerChangeInterval(PRTTIMER pTimer, uint64_t u64NanoInterval);
+
+/**
+ * Gets the (current) timer granularity of the system.
+ *
+ * @returns The timer granularity of the system in nanoseconds.
+ * @see     RTTimerRequestSystemGranularity
+ */
+RTDECL(uint32_t) RTTimerGetSystemGranularity(void);
+
+/**
+ * Requests a specific system timer granularity.
+ *
+ * Successfull calls to this API must be coupled with the exact same number of
+ * calls to RTTimerReleaseSystemGranularity() in order to undo any changes made.
+ *
+ *
+ * @returns IPRT status code.
+ * @retval  VERR_NOT_SUPPORTED if the requested value isn't supported by the host platform
+ *          or if the host platform doesn't support modifying the system timer granularity.
+ * @retval  VERR_PERMISSION_DENIED if the caller doesn't have the necessary privilege to
+ *          modify the system timer granularity.
+ *
+ * @param   u32Request      The requested system timer granularity in nanoseconds.
+ * @param   pu32Granted     Where to store the granted system granularity. This is the value
+ *                          that should be passed to  RTTimerReleaseSystemGranularity(). It
+ *                          is what RTTimerGetSystemGranularity() would return immediately
+ *                          after the change was made.
+ *
+ *                          The value differ from the request in two ways; rounding and
+ *                          scale. Meaning if your request is for 10.000.000 you might
+ *                          be granted 10.000.055 or 1.000.000.
+ * @see     RTTimerReleaseSystemGranularity, RTTimerGetSystemGranularity
+ */
+RTDECL(int) RTTimerRequestSystemGranularity(uint32_t u32Request, uint32_t *pu32Granted);
+
+/**
+ * Releases a system timer granularity grant acquired by RTTimerRequestSystemGranularity().
+ *
+ * @returns IPRT status code.
+ * @retval  VERR_NOT_SUPPORTED if the host platform doesn't have any way of modifying
+ *          the system timer granularity.
+ * @retval  VERR_WRONG_ORDER if nobody call RTTimerRequestSystemGranularity() with the
+ *          given grant value.
+ * @param   u32Granted      The granted system granularity.
+ * @see     RTTimerRequestSystemGranularity
+ */
+RTDECL(int) RTTimerReleaseSystemGranularity(uint32_t u32Granted);
+
+/**
+ * Checks if the system support high resolution timers.
+ *
+ * The kind of support we are checking for is the kind of dynamically
+ * reprogrammable timers employed by recent Solaris and Linux kernels.  It also
+ * implies that we can specify microsecond (or even better maybe) intervals
+ * without getting into trouble.
+ *
+ * @returns true if supported, false it not.
+ *
+ * @remarks Returning true also means RTTimerChangeInterval must be implemented
+ *          and RTTimerStart be callable with preemption disabled.
+ */
+RTDECL(bool) RTTimerCanDoHighResolution(void);
+
+
+/**
+ * Timer callback function for low res timers.
+ *
+ * This is identical to FNRTTIMER except for the first parameter, so
+ * see FNRTTIMER for details.
+ *
+ * @param   hTimerLR    The low resolution timer handle.
+ * @param   pvUser      User argument.
+ * @param   iTick       The current timer tick. This is always 1 on the first
+ *                      callback after the timer was started. Will jump if we've
+ *                      skipped ticks when lagging behind.
+ */
+typedef DECLCALLBACK(void) FNRTTIMERLR(RTTIMERLR hTimerLR, void *pvUser, uint64_t iTick);
+/** Pointer to FNRTTIMER() function. */
+typedef FNRTTIMERLR *PFNRTTIMERLR;
+
+
+/**
+ * Create a recurring low resolution timer.
+ *
+ * @returns iprt status code.
+ * @param   phTimerLR           Where to store the timer handle.
+ * @param   uMilliesInterval    Milliseconds between the timer ticks, at least 100 ms.
+ *                              If higher resolution is required use the other API.
+ * @param   pfnTimer            Callback function which shall be scheduled for execution
+ *                              on every timer tick.
+ * @param   pvUser              User argument for the callback.
+ * @see     RTTimerLRCreateEx, RTTimerLRDestroy, RTTimerLRStop
+ */
+RTDECL(int) RTTimerLRCreate(PRTTIMERLR phTimerLR, uint32_t uMilliesInterval, PFNRTTIMERLR pfnTimer, void *pvUser);
+
+/**
+ * Create a suspended low resolution timer.
+ *
+ * @returns iprt status code.
+ * @retval  VERR_NOT_SUPPORTED if an unsupported flag was specfied.
+ *
+ * @param   phTimerLR           Where to store the timer handle.
+ * @param   u64NanoInterval     The interval between timer ticks specified in nanoseconds if it's
+ *                              a recurring timer, the minimum for is 100000000 ns.
+ *                              For one shot timers, pass 0.
+ * @param   fFlags              Timer flags. Same as RTTimerCreateEx.
+ * @param   pfnTimer            Callback function which shall be scheduled for execution
+ *                              on every timer tick.
+ * @param   pvUser              User argument for the callback.
+ * @see     RTTimerLRStart, RTTimerLRStop, RTTimerLRDestroy
+ */
+RTDECL(int) RTTimerLRCreateEx(PRTTIMERLR phTimerLR, uint64_t u64NanoInterval, uint32_t fFlags, PFNRTTIMERLR pfnTimer, void *pvUser);
+
+/**
+ * Stops and destroys a running low resolution timer.
+ *
+ * @returns iprt status code.
+ * @param   hTimerLR            The low resolution timer to stop and destroy.
+ *                              NIL_RTTIMERLR is accepted.
+ */
+RTDECL(int) RTTimerLRDestroy(RTTIMERLR hTimerLR);
+
+/**
+ * Starts a low resolution timer.
+ *
+ * @returns IPRT status code.
+ * @retval  VERR_INVALID_HANDLE if pTimer isn't valid.
+ * @retval  VERR_TIMER_ACTIVE if the timer isn't suspended.
+ *
+ * @param   hTimerLR            The low resolution timer to activate.
+ * @param   u64First            The RTTimeSystemNanoTS() for when the timer should start
+ *                              firing (relative), the minimum is 100000000 ns.
+ *                              If 0 is specified, the timer will fire ASAP.
+ *
+ * @see     RTTimerLRStop
+ */
+RTDECL(int) RTTimerLRStart(RTTIMERLR hTimerLR, uint64_t u64First);
+
+/**
+ * Stops an active low resolution timer.
+ *
+ * @returns IPRT status code.
+ * @retval  VERR_INVALID_HANDLE if pTimer isn't valid.
+ * @retval  VERR_TIMER_SUSPENDED if the timer isn't active.
+ * @retval  VERR_NOT_SUPPORTED if the IPRT implementation doesn't support stopping a timer.
+ *
+ * @param   hTimerLR            The low resolution timer to suspend.
+ *
+ * @see     RTTimerLRStart
+ */
+RTDECL(int) RTTimerLRStop(RTTIMERLR hTimerLR);
+
+/**
+ * Changes the interval of a low resolution timer.
+ *
+ * If the timer is active, the next tick will occure immediately just like with
+ * RTTimerLRStart() when u64First parameter is zero.
+ *
+ * @returns IPRT status code.
+ * @retval  VERR_INVALID_HANDLE if pTimer isn't valid.
+ * @retval  VERR_NOT_SUPPORTED if not supported.
+ *
+ * @param   hTimerLR            The low resolution timer to update.
+ * @param   u64NanoInterval     The interval between timer ticks specified in
+ *                              nanoseconds.  This is rounded to the fit the
+ *                              system timer granularity.
+ * @remarks Callable from the timer callback.
+ */
+RTDECL(int) RTTimerLRChangeInterval(RTTIMERLR hTimerLR, uint64_t u64NanoInterval);
+
+/** @} */
+
+RT_C_DECLS_END
+
+#endif
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/include/iprt/types.h
@@ -0,0 +1,2620 @@
+/** @file
+ * IPRT - Types.
+ */
+
+/*
+ * Copyright (C) 2006-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+#ifndef ___iprt_types_h
+#define ___iprt_types_h
+
+#include <iprt/cdefs.h>
+#include <iprt/stdint.h>
+#include <iprt/stdarg.h>
+
+/*
+ * Include standard C types.
+ */
+#ifndef IPRT_NO_CRT
+
+# if defined(IN_XF86_MODULE) && !defined(NO_ANSIC)
+    /*
+     * Kludge for xfree86 modules: size_t and other types are redefined.
+     */
+RT_C_DECLS_BEGIN
+#  include "xf86_ansic.h"
+#  undef NULL
+RT_C_DECLS_END
+
+# elif defined(RT_OS_DARWIN) && defined(KERNEL)
+    /*
+     * Kludge for the darwin kernel:
+     *  stddef.h is missing IIRC.
+     */
+#  ifndef _PTRDIFF_T
+#  define _PTRDIFF_T
+    typedef __darwin_ptrdiff_t ptrdiff_t;
+#  endif
+#  include <sys/types.h>
+
+# elif defined(RT_OS_FREEBSD) && defined(_KERNEL)
+    /*
+     * Kludge for the FreeBSD kernel:
+     *  stddef.h and sys/types.h have slightly different offsetof definitions
+     *  when compiling in kernel mode. This is just to make GCC shut up.
+     */
+#  ifndef _STDDEF_H_
+#   undef offsetof
+#  endif
+#  include <sys/stddef.h>
+#  ifndef _SYS_TYPES_H_
+#   undef offsetof
+#  endif
+#  include <sys/types.h>
+#  ifndef offsetof
+#   error "offsetof is not defined!"
+#  endif
+
+# elif defined(RT_OS_FREEBSD) && HC_ARCH_BITS == 64 && defined(RT_ARCH_X86)
+    /*
+     * Kludge for compiling 32-bit code on a 64-bit FreeBSD:
+     *  FreeBSD declares uint64_t and int64_t wrong (long unsigned and long int
+     *  though they need to be long long unsigned and long long int). These
+     *  defines conflict with our declaration in stdint.h. Adding the defines
+     *  below omits the definitions in the system header.
+     */
+#  include <stddef.h>
+#  define _UINT64_T_DECLARED
+#  define _INT64_T_DECLARED
+#  define _UINTPTR_T_DECLARED
+#  define _INTPTR_T_DECLARED
+#  include <sys/types.h>
+
+# elif defined(RT_OS_LINUX) && defined(__KERNEL__)
+    /*
+     * Kludge for the linux kernel:
+     *   1. sys/types.h doesn't mix with the kernel.
+     *   2. Starting with 2.6.19, linux/types.h typedefs bool and linux/stddef.h
+     *      declares false and true as enum values.
+     *   3. Starting with 2.6.24, linux/types.h typedefs uintptr_t.
+     * We work around these issues here and nowhere else.
+     */
+#  include <stddef.h>
+#  if defined(__cplusplus)
+    typedef bool _Bool;
+#  endif
+#  define bool linux_bool
+#  define true linux_true
+#  define false linux_false
+#  define uintptr_t linux_uintptr_t
+#  include <linux/version.h>
+#  if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,33)
+#   include <generated/autoconf.h>
+#  else
+#   ifndef AUTOCONF_INCLUDED
+#    include <linux/autoconf.h>
+#   endif
+#  endif
+#  include <linux/compiler.h>
+#  if defined(__cplusplus)
+    /*
+     * Starting with 3.3, <linux/compiler-gcc.h> appends 'notrace' (which
+     * expands to __attribute__((no_instrument_function))) to inline,
+     * __inline and __inline__. Revert that.
+     */
+#   undef inline
+#   define inline inline
+#   undef __inline__
+#   define __inline__ __inline__
+#   undef __inline
+#   define __inline __inline
+#  endif
+#  include <linux/types.h>
+#  include <linux/stddef.h>
+    /*
+     * Starting with 3.4, <linux/stddef.h> defines NULL as '((void*)0)' which
+     * does not work for C++ code.
+     */
+#  undef NULL
+#  undef uintptr_t
+#  ifdef __GNUC__
+#   if (__GNUC__ * 100 + __GNUC_MINOR__) <= 400
+     /*
+      * <linux/compiler-gcc{3,4}.h> does
+      *   #define __inline__  __inline__ __attribute__((always_inline))
+      * in some older Linux kernels. Forcing inlining will fail for some RTStrA*
+      * functions with gcc <= 4.0 due to passing variable argument lists.
+      */
+#    undef __inline__
+#    define __inline__ __inline__
+#   endif
+#  endif
+#  undef false
+#  undef true
+#  undef bool
+# else
+#  include <stddef.h>
+#  include <sys/types.h>
+# endif
+
+
+/* Define any types missing from sys/types.h on windows. */
+# ifdef _MSC_VER
+#  undef ssize_t
+   typedef intptr_t ssize_t;
+# endif
+
+#else  /* no crt */
+# include <iprt/nocrt/compiler/compiler.h>
+#endif /* no crt */
+
+
+
+/** @def NULL
+ * NULL pointer.
+ */
+#ifndef NULL
+# ifdef __cplusplus
+#  define NULL 0
+# else
+#  define NULL ((void*)0)
+# endif
+#endif
+
+
+
+/** @defgroup grp_rt_types  IPRT Base Types
+ * @{
+ */
+
+/* define wchar_t, we don't wanna include all the wcsstuff to get this. */
+#ifdef _MSC_VER
+# ifndef _WCHAR_T_DEFINED
+  typedef unsigned short wchar_t;
+# define _WCHAR_T_DEFINED
+# endif
+#endif
+#ifdef __GNUC__
+/** @todo wchar_t on GNUC */
+#endif
+
+/*
+ * C doesn't have bool, nor does VisualAge for C++ v3.08.
+ */
+#if !defined(__cplusplus) || (defined(__IBMCPP__) && defined(RT_OS_OS2))
+# if defined(__GNUC__)
+#  if defined(RT_OS_LINUX) && __GNUC__ < 3
+typedef uint8_t bool;
+#  elif defined(RT_OS_FREEBSD)
+#   ifndef __bool_true_false_are_defined
+typedef _Bool bool;
+#   endif
+#  else
+#   if (defined(RT_OS_DARWIN) || defined(RT_OS_HAIKU)) && (defined(_STDBOOL_H) || defined(__STDBOOL_H))
+#    undef bool
+#   endif
+typedef _Bool bool;
+#  endif
+# else
+typedef unsigned char bool;
+# endif
+# ifndef true
+#  define true  (1)
+# endif
+# ifndef false
+#  define false (0)
+# endif
+#endif
+
+/**
+ * 128-bit unsigned integer.
+ */
+#if defined(__GNUC__) && defined(RT_ARCH_AMD64)
+typedef __uint128_t uint128_t;
+#else
+typedef struct uint128_s
+{
+# ifdef RT_BIG_ENDIAN
+    uint64_t    Hi;
+    uint64_t    Lo;
+# else
+    uint64_t    Lo;
+    uint64_t    Hi;
+# endif
+} uint128_t;
+#endif
+
+
+/**
+ * 128-bit signed integer.
+ */
+#if defined(__GNUC__) && defined(RT_ARCH_AMD64)
+typedef __int128_t int128_t;
+#else
+typedef struct int128_s
+{
+# ifdef RT_BIG_ENDIAN
+    int64_t     Hi;
+    uint64_t    Lo;
+# else
+    uint64_t    Lo;
+    int64_t     Hi;
+# endif
+} int128_t;
+#endif
+
+
+/**
+ * 16-bit unsigned integer union.
+ */
+typedef union RTUINT16U
+{
+    /** natural view. */
+    uint16_t    u;
+
+    /** 16-bit view. */
+    uint16_t    au16[1];
+    /** 8-bit view. */
+    uint8_t     au8[2];
+    /** 16-bit hi/lo view. */
+    struct
+    {
+#ifdef RT_BIG_ENDIAN
+        uint8_t    Hi;
+        uint8_t    Lo;
+#else
+        uint8_t    Lo;
+        uint8_t    Hi;
+#endif
+    } s;
+} RTUINT16U;
+/** Pointer to a 16-bit unsigned integer union. */
+typedef RTUINT16U *PRTUINT16U;
+/** Pointer to a const 32-bit unsigned integer union. */
+typedef const RTUINT16U *PCRTUINT16U;
+
+
+/**
+ * 32-bit unsigned integer union.
+ */
+typedef union RTUINT32U
+{
+    /** natural view. */
+    uint32_t    u;
+    /** Hi/Low view. */
+    struct
+    {
+#ifdef RT_BIG_ENDIAN
+        uint16_t    Hi;
+        uint16_t    Lo;
+#else
+        uint16_t    Lo;
+        uint16_t    Hi;
+#endif
+    } s;
+    /** Word view. */
+    struct
+    {
+#ifdef RT_BIG_ENDIAN
+        uint16_t    w1;
+        uint16_t    w0;
+#else
+        uint16_t    w0;
+        uint16_t    w1;
+#endif
+    } Words;
+
+    /** 32-bit view. */
+    uint32_t    au32[1];
+    /** 16-bit view. */
+    uint16_t    au16[2];
+    /** 8-bit view. */
+    uint8_t     au8[4];
+} RTUINT32U;
+/** Pointer to a 32-bit unsigned integer union. */
+typedef RTUINT32U *PRTUINT32U;
+/** Pointer to a const 32-bit unsigned integer union. */
+typedef const RTUINT32U *PCRTUINT32U;
+
+
+/**
+ * 64-bit unsigned integer union.
+ */
+typedef union RTUINT64U
+{
+    /** Natural view. */
+    uint64_t    u;
+    /** Hi/Low view. */
+    struct
+    {
+#ifdef RT_BIG_ENDIAN
+        uint32_t    Hi;
+        uint32_t    Lo;
+#else
+        uint32_t    Lo;
+        uint32_t    Hi;
+#endif
+    } s;
+    /** Double-Word view. */
+    struct
+    {
+#ifdef RT_BIG_ENDIAN
+        uint32_t    dw1;
+        uint32_t    dw0;
+#else
+        uint32_t    dw0;
+        uint32_t    dw1;
+#endif
+    } DWords;
+    /** Word view. */
+    struct
+    {
+#ifdef RT_BIG_ENDIAN
+        uint16_t    w3;
+        uint16_t    w2;
+        uint16_t    w1;
+        uint16_t    w0;
+#else
+        uint16_t    w0;
+        uint16_t    w1;
+        uint16_t    w2;
+        uint16_t    w3;
+#endif
+    } Words;
+
+    /** 64-bit view. */
+    uint64_t    au64[1];
+    /** 32-bit view. */
+    uint32_t    au32[2];
+    /** 16-bit view. */
+    uint16_t    au16[4];
+    /** 8-bit view. */
+    uint8_t     au8[8];
+} RTUINT64U;
+/** Pointer to a 64-bit unsigned integer union. */
+typedef RTUINT64U *PRTUINT64U;
+/** Pointer to a const 64-bit unsigned integer union. */
+typedef const RTUINT64U *PCRTUINT64U;
+
+
+/**
+ * 128-bit unsigned integer union.
+ */
+#pragma pack(1)
+typedef union RTUINT128U
+{
+    /** Hi/Low view.
+     * @remarks We put this first so we can have portable initializers
+     *          (RTUINT128_INIT) */
+    struct
+    {
+#ifdef RT_BIG_ENDIAN
+        uint64_t    Hi;
+        uint64_t    Lo;
+#else
+        uint64_t    Lo;
+        uint64_t    Hi;
+#endif
+    } s;
+
+    /** Natural view.
+     * WARNING! This member depends on the compiler supporting 128-bit stuff. */
+    uint128_t   u;
+
+    /** Quad-Word view. */
+    struct
+    {
+#ifdef RT_BIG_ENDIAN
+        uint64_t    qw1;
+        uint64_t    qw0;
+#else
+        uint64_t    qw0;
+        uint64_t    qw1;
+#endif
+    } QWords;
+    /** Double-Word view. */
+    struct
+    {
+#ifdef RT_BIG_ENDIAN
+        uint32_t    dw3;
+        uint32_t    dw2;
+        uint32_t    dw1;
+        uint32_t    dw0;
+#else
+        uint32_t    dw0;
+        uint32_t    dw1;
+        uint32_t    dw2;
+        uint32_t    dw3;
+#endif
+    } DWords;
+    /** Word view. */
+    struct
+    {
+#ifdef RT_BIG_ENDIAN
+        uint16_t    w7;
+        uint16_t    w6;
+        uint16_t    w5;
+        uint16_t    w4;
+        uint16_t    w3;
+        uint16_t    w2;
+        uint16_t    w1;
+        uint16_t    w0;
+#else
+        uint16_t    w0;
+        uint16_t    w1;
+        uint16_t    w2;
+        uint16_t    w3;
+        uint16_t    w4;
+        uint16_t    w5;
+        uint16_t    w6;
+        uint16_t    w7;
+#endif
+    } Words;
+
+    /** 64-bit view. */
+    uint64_t    au64[2];
+    /** 32-bit view. */
+    uint32_t    au32[4];
+    /** 16-bit view. */
+    uint16_t    au16[8];
+    /** 8-bit view. */
+    uint8_t     au8[16];
+} RTUINT128U;
+#pragma pack()
+/** Pointer to a 64-bit unsigned integer union. */
+typedef RTUINT128U *PRTUINT128U;
+/** Pointer to a const 64-bit unsigned integer union. */
+typedef const RTUINT128U *PCRTUINT128U;
+
+/** @def RTUINT128_INIT
+ * Portable RTUINT128U initializer. */
+#ifdef RT_BIG_ENDIAN
+# define RTUINT128_INIT(a_Hi, a_Lo) { { a_Hi, a_Lo } }
+#else
+# define RTUINT128_INIT(a_Hi, a_Lo) { { a_Lo, a_Hi } }
+#endif
+
+/** @def RTUINT128_INIT_C
+ * Portable RTUINT128U initializer for 64-bit constants. */
+#ifdef RT_BIG_ENDIAN
+# define RTUINT128_INIT_C(a_Hi, a_Lo) { { UINT64_C(a_Hi), UINT64_C(a_Lo) } }
+#else
+# define RTUINT128_INIT_C(a_Hi, a_Lo) { { UINT64_C(a_Lo), UINT64_C(a_Hi) } }
+#endif
+
+
+/**
+ * Double precision floating point format (64-bit).
+ */
+typedef union RTFLOAT64U
+{
+#if defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86)
+    /** Double view. */
+    double      rd;
+#endif
+    /** Format using regular bitfields.  */
+    struct
+    {
+# ifdef RT_BIG_ENDIAN
+        /** The sign indicator. */
+        uint32_t    fSign : 1;
+        /** The exponent (offseted by 1023). */
+        uint32_t    uExponent : 11;
+        /** The fraction, bits 32 thru 51. */
+        uint32_t    u20FractionHigh : 20;
+        /** The fraction, bits 0 thru 31. */
+        uint32_t    u32FractionLow;
+# else
+        /** The fraction, bits 0 thru 31. */
+        uint32_t    u32FractionLow;
+        /** The fraction, bits 32 thru 51. */
+        uint32_t    u20FractionHigh : 20;
+        /** The exponent (offseted by 1023). */
+        uint32_t    uExponent : 11;
+        /** The sign indicator. */
+        uint32_t    fSign : 1;
+# endif
+    } s;
+
+#ifdef RT_COMPILER_GROKS_64BIT_BITFIELDS
+    /** Format using 64-bit bitfields.  */
+    RT_GCC_EXTENSION struct
+    {
+# ifdef RT_BIG_ENDIAN
+        /** The sign indicator. */
+        RT_GCC_EXTENSION uint64_t    fSign : 1;
+        /** The exponent (offseted by 1023). */
+        RT_GCC_EXTENSION uint64_t    uExponent : 11;
+        /** The fraction. */
+        RT_GCC_EXTENSION uint64_t    uFraction : 52;
+# else
+        /** The fraction. */
+        RT_GCC_EXTENSION uint64_t    uFraction : 52;
+        /** The exponent (offseted by 1023). */
+        RT_GCC_EXTENSION uint64_t    uExponent : 11;
+        /** The sign indicator. */
+        RT_GCC_EXTENSION uint64_t    fSign : 1;
+# endif
+    } s64;
+#endif
+
+    /** 64-bit view. */
+    uint64_t    au64[1];
+    /** 32-bit view. */
+    uint32_t    au32[2];
+    /** 16-bit view. */
+    uint16_t    au16[4];
+    /** 8-bit view. */
+    uint8_t     au8[8];
+} RTFLOAT64U;
+/** Pointer to a double precision floating point format union. */
+typedef RTFLOAT64U *PRTFLOAT64U;
+/** Pointer to a const double precision floating point format union. */
+typedef const RTFLOAT64U *PCRTFLOAT64U;
+
+
+#if !defined(__IBMCPP__) && !defined(__IBMC__)
+
+/**
+ * Extended Double precision floating point format (80-bit).
+ */
+#pragma pack(1)
+typedef union RTFLOAT80U
+{
+    /** Format using bitfields.  */
+    RT_GCC_EXTENSION struct
+    {
+# ifdef RT_BIG_ENDIAN
+        /** The sign indicator. */
+        RT_GCC_EXTENSION uint16_t   fSign : 1;
+        /** The exponent (offseted by 16383). */
+        RT_GCC_EXTENSION uint16_t   uExponent : 15;
+        /** The mantissa. */
+        uint64_t                    u64Mantissa;
+# else
+        /** The mantissa. */
+        uint64_t                    u64Mantissa;
+        /** The exponent (offseted by 16383). */
+        RT_GCC_EXTENSION uint16_t   uExponent : 15;
+        /** The sign indicator. */
+        RT_GCC_EXTENSION uint16_t   fSign : 1;
+# endif
+    } s;
+
+    /** 64-bit view. */
+    uint64_t    au64[1];
+    /** 32-bit view. */
+    uint32_t    au32[2];
+    /** 16-bit view. */
+    uint16_t    au16[5];
+    /** 8-bit view. */
+    uint8_t     au8[10];
+} RTFLOAT80U;
+#pragma pack()
+/** Pointer to a extended precision floating point format union. */
+typedef RTFLOAT80U *PRTFLOAT80U;
+/** Pointer to a const extended precision floating point format union. */
+typedef const RTFLOAT80U *PCRTFLOAT80U;
+
+
+/**
+ * A variant of RTFLOAT80U that may be larger than 80-bits depending on how the
+ * compiler implements long double.
+ */
+#pragma pack(1)
+typedef union RTFLOAT80U2
+{
+#ifdef RT_COMPILER_WITH_80BIT_LONG_DOUBLE
+    /** Long double view. */
+    long double     lrd;
+#endif
+    /** Format using bitfields.  */
+    RT_GCC_EXTENSION struct
+    {
+#ifdef RT_BIG_ENDIAN
+        /** The sign indicator. */
+        RT_GCC_EXTENSION uint16_t   fSign : 1;
+        /** The exponent (offseted by 16383). */
+        RT_GCC_EXTENSION uint16_t   uExponent : 15;
+        /** The mantissa. */
+        uint64_t                    u64Mantissa;
+#else
+        /** The mantissa. */
+        uint64_t                    u64Mantissa;
+        /** The exponent (offseted by 16383). */
+        RT_GCC_EXTENSION uint16_t   uExponent : 15;
+        /** The sign indicator. */
+        RT_GCC_EXTENSION uint16_t   fSign : 1;
+#endif
+    } s;
+
+    /** Bitfield exposing the J bit and the fraction.  */
+    RT_GCC_EXTENSION struct
+    {
+#ifdef RT_BIG_ENDIAN
+        /** The sign indicator. */
+        RT_GCC_EXTENSION uint16_t   fSign : 1;
+        /** The exponent (offseted by 16383). */
+        RT_GCC_EXTENSION uint16_t   uExponent : 15;
+        /** The J bit, aka the integer bit. */
+        uint32_t                    fInteger;
+        /** The fraction, bits 32 thru 62. */
+        uint32_t                    u31FractionHigh : 31;
+        /** The fraction, bits 0 thru 31. */
+        uint32_t                    u32FractionLow : 32;
+#else
+        /** The fraction, bits 0 thru 31. */
+        uint32_t                    u32FractionLow : 32;
+        /** The fraction, bits 32 thru 62. */
+        uint32_t                    u31FractionHigh : 31;
+        /** The J bit, aka the integer bit. */
+        uint32_t                    fInteger;
+        /** The exponent (offseted by 16383). */
+        RT_GCC_EXTENSION uint16_t   uExponent : 15;
+        /** The sign indicator. */
+        RT_GCC_EXTENSION uint16_t   fSign : 1;
+#endif
+    } sj;
+
+#ifdef RT_COMPILER_GROKS_64BIT_BITFIELDS
+    /** 64-bit bitfields exposing the J bit and the fraction.  */
+    RT_GCC_EXTENSION struct
+    {
+# ifdef RT_BIG_ENDIAN
+        /** The sign indicator. */
+        RT_GCC_EXTENSION uint16_t   fSign : 1;
+        /** The exponent (offseted by 16383). */
+        RT_GCC_EXTENSION uint16_t   uExponent : 15;
+        /** The J bit, aka the integer bit. */
+        RT_GCC_EXTENSION uint64_t   fInteger : 1;
+        /** The fraction. */
+        RT_GCC_EXTENSION uint64_t   u63Fraction : 63;
+# else
+        /** The fraction. */
+        RT_GCC_EXTENSION uint64_t   u63Fraction : 63;
+        /** The J bit, aka the integer bit. */
+        RT_GCC_EXTENSION uint64_t   fInteger : 1;
+        /** The exponent (offseted by 16383). */
+        RT_GCC_EXTENSION uint16_t   uExponent : 15;
+        /** The sign indicator. */
+        RT_GCC_EXTENSION uint16_t   fSign : 1;
+# endif
+    } sj64;
+#endif
+
+    /** 64-bit view. */
+    uint64_t    au64[1];
+    /** 32-bit view. */
+    uint32_t    au32[2];
+    /** 16-bit view. */
+    uint16_t    au16[5];
+    /** 8-bit view. */
+    uint8_t     au8[10];
+} RTFLOAT80U2;
+#pragma pack()
+/** Pointer to a extended precision floating point format union, 2nd
+ * variant. */
+typedef RTFLOAT80U2 *PRTFLOAT80U2;
+/** Pointer to a const extended precision floating point format union, 2nd
+ * variant. */
+typedef const RTFLOAT80U2 *PCRTFLOAT80U2;
+
+#endif /* uint16_t bitfields doesn't work */
+
+
+/** Generic function type.
+ * @see PFNRT
+ */
+typedef DECLCALLBACK(void) FNRT(void);
+
+/** Generic function pointer.
+ * With -pedantic, gcc-4 complains when casting a function to a data object, for
+ * example:
+ *
+ * @code
+ *    void foo(void)
+ *    {
+ *    }
+ *
+ *    void *bar = (void *)foo;
+ * @endcode
+ *
+ * The compiler would warn with "ISO C++ forbids casting between
+ * pointer-to-function and pointer-to-object".  The purpose of this warning is
+ * not to bother the programmer but to point out that he is probably doing
+ * something dangerous, assigning a pointer to executable code to a data object.
+ */
+typedef FNRT *PFNRT;
+
+/** Millisecond interval. */
+typedef uint32_t            RTMSINTERVAL;
+/** Pointer to a millisecond interval. */
+typedef RTMSINTERVAL       *PRTMSINTERVAL;
+/** Pointer to a const millisecond interval. */
+typedef const RTMSINTERVAL *PCRTMSINTERVAL;
+
+/** Pointer to a time spec structure. */
+typedef struct RTTIMESPEC  *PRTTIMESPEC;
+/** Pointer to a const time spec structure. */
+typedef const struct RTTIMESPEC *PCRTTIMESPEC;
+
+
+
+/** @defgroup grp_rt_types_both  Common Guest and Host Context Basic Types
+ * @{
+ */
+
+/** Signed integer which can contain both GC and HC pointers. */
+#if (HC_ARCH_BITS == 32 && GC_ARCH_BITS == 32)
+typedef int32_t         RTINTPTR;
+#elif (HC_ARCH_BITS == 64 || GC_ARCH_BITS == 64)
+typedef int64_t         RTINTPTR;
+#else
+#  error Unsupported HC_ARCH_BITS and/or GC_ARCH_BITS values.
+#endif
+/** Pointer to signed integer which can contain both GC and HC pointers. */
+typedef RTINTPTR       *PRTINTPTR;
+/** Pointer const to signed integer which can contain both GC and HC pointers. */
+typedef const RTINTPTR *PCRTINTPTR;
+/** The maximum value the RTINTPTR type can hold. */
+#if (HC_ARCH_BITS == 32 && GC_ARCH_BITS == 32)
+# define RTINTPTR_MAX   INT32_MAX
+#elif (HC_ARCH_BITS == 64 || GC_ARCH_BITS == 64)
+# define RTINTPTR_MAX   INT64_MAX
+#else
+#  error Unsupported HC_ARCH_BITS and/or GC_ARCH_BITS values.
+#endif
+/** The minimum value the RTINTPTR type can hold. */
+#if (HC_ARCH_BITS == 32 && GC_ARCH_BITS == 32)
+# define RTINTPTR_MIN   INT32_MIN
+#elif (HC_ARCH_BITS == 64 || GC_ARCH_BITS == 64)
+# define RTINTPTR_MIN   INT64_MIN
+#else
+#  error Unsupported HC_ARCH_BITS and/or GC_ARCH_BITS values.
+#endif
+
+/** Unsigned integer which can contain both GC and HC pointers. */
+#if (HC_ARCH_BITS == 32 && GC_ARCH_BITS == 32)
+typedef uint32_t        RTUINTPTR;
+#elif (HC_ARCH_BITS == 64 || GC_ARCH_BITS == 64)
+typedef uint64_t        RTUINTPTR;
+#else
+#  error Unsupported HC_ARCH_BITS and/or GC_ARCH_BITS values.
+#endif
+/** Pointer to unsigned integer which can contain both GC and HC pointers. */
+typedef RTUINTPTR      *PRTUINTPTR;
+/** Pointer const to unsigned integer which can contain both GC and HC pointers. */
+typedef const RTUINTPTR *PCRTUINTPTR;
+/** The maximum value the RTUINTPTR type can hold. */
+#if (HC_ARCH_BITS == 32 && GC_ARCH_BITS == 32)
+# define RTUINTPTR_MAX  UINT32_MAX
+#elif (HC_ARCH_BITS == 64 || GC_ARCH_BITS == 64)
+# define RTUINTPTR_MAX  UINT64_MAX
+#else
+#  error Unsupported HC_ARCH_BITS and/or GC_ARCH_BITS values.
+#endif
+
+/** Signed integer. */
+typedef int32_t         RTINT;
+/** Pointer to signed integer. */
+typedef RTINT          *PRTINT;
+/** Pointer to const signed integer. */
+typedef const RTINT    *PCRTINT;
+
+/** Unsigned integer. */
+typedef uint32_t        RTUINT;
+/** Pointer to unsigned integer. */
+typedef RTUINT         *PRTUINT;
+/** Pointer to const unsigned integer. */
+typedef const RTUINT   *PCRTUINT;
+
+/** A file offset / size (off_t). */
+typedef int64_t         RTFOFF;
+/** Pointer to a file offset / size. */
+typedef RTFOFF         *PRTFOFF;
+/** The max value for RTFOFF. */
+#define RTFOFF_MAX      INT64_MAX
+/** The min value for RTFOFF. */
+#define RTFOFF_MIN      INT64_MIN
+
+/** File mode (see iprt/fs.h). */
+typedef uint32_t        RTFMODE;
+/** Pointer to file mode. */
+typedef RTFMODE        *PRTFMODE;
+
+/** Device unix number. */
+typedef uint32_t        RTDEV;
+/** Pointer to a device unix number. */
+typedef RTDEV          *PRTDEV;
+
+/** @name RTDEV Macros
+ * @{  */
+/**
+ * Our makedev macro.
+ * @returns RTDEV
+ * @param   uMajor          The major device number.
+ * @param   uMinor          The minor device number.
+ */
+#define RTDEV_MAKE(uMajor, uMinor)      ((RTDEV)( ((RTDEV)(uMajor) << 24) | (uMinor & UINT32_C(0x00ffffff)) ))
+/**
+ * Get the major device node number from an RTDEV type.
+ * @returns The major device number of @a uDev
+ * @param   uDev            The device number.
+ */
+#define RTDEV_MAJOR(uDev)               ((uDev) >> 24)
+/**
+ * Get the minor device node number from an RTDEV type.
+ * @returns The minor device number of @a uDev
+ * @param   uDev            The device number.
+ */
+#define RTDEV_MINOR(uDev)               ((uDev) & UINT32_C(0x00ffffff))
+/** @}  */
+
+/** i-node number. */
+typedef uint64_t        RTINODE;
+/** Pointer to a i-node number. */
+typedef RTINODE        *PRTINODE;
+
+/** User id. */
+typedef uint32_t        RTUID;
+/** Pointer to a user id. */
+typedef RTUID          *PRTUID;
+/** NIL user id.
+ * @todo check this for portability! */
+#define NIL_RTUID       (~(RTUID)0)
+
+/** Group id. */
+typedef uint32_t        RTGID;
+/** Pointer to a group id. */
+typedef RTGID          *PRTGID;
+/** NIL group id.
+ * @todo check this for portability! */
+#define NIL_RTGID       (~(RTGID)0)
+
+/** I/O Port. */
+typedef uint16_t        RTIOPORT;
+/** Pointer to I/O Port. */
+typedef RTIOPORT       *PRTIOPORT;
+/** Pointer to const I/O Port. */
+typedef const RTIOPORT *PCRTIOPORT;
+
+/** Selector. */
+typedef uint16_t        RTSEL;
+/** Pointer to selector. */
+typedef RTSEL          *PRTSEL;
+/** Pointer to const selector. */
+typedef const RTSEL    *PCRTSEL;
+/** Max selector value. */
+#define RTSEL_MAX       UINT16_MAX
+
+/** Far 16-bit pointer. */
+#pragma pack(1)
+typedef struct RTFAR16
+{
+    uint16_t        off;
+    RTSEL           sel;
+} RTFAR16;
+#pragma pack()
+/** Pointer to Far 16-bit pointer. */
+typedef RTFAR16 *PRTFAR16;
+/** Pointer to const Far 16-bit pointer. */
+typedef const RTFAR16 *PCRTFAR16;
+
+/** Far 32-bit pointer. */
+#pragma pack(1)
+typedef struct RTFAR32
+{
+    uint32_t        off;
+    RTSEL           sel;
+} RTFAR32;
+#pragma pack()
+/** Pointer to Far 32-bit pointer. */
+typedef RTFAR32 *PRTFAR32;
+/** Pointer to const Far 32-bit pointer. */
+typedef const RTFAR32 *PCRTFAR32;
+
+/** Far 64-bit pointer. */
+#pragma pack(1)
+typedef struct RTFAR64
+{
+    uint64_t        off;
+    RTSEL           sel;
+} RTFAR64;
+#pragma pack()
+/** Pointer to Far 64-bit pointer. */
+typedef RTFAR64 *PRTFAR64;
+/** Pointer to const Far 64-bit pointer. */
+typedef const RTFAR64 *PCRTFAR64;
+
+/** @} */
+
+
+/** @defgroup grp_rt_types_hc  Host Context Basic Types
+ * @{
+ */
+
+/** HC Natural signed integer.
+ * @deprecated silly type. */
+typedef int32_t             RTHCINT;
+/** Pointer to HC Natural signed integer.
+ * @deprecated silly type. */
+typedef RTHCINT            *PRTHCINT;
+/** Pointer to const HC Natural signed integer.
+ * @deprecated silly type. */
+typedef const RTHCINT      *PCRTHCINT;
+
+/** HC Natural unsigned integer.
+ * @deprecated silly type. */
+typedef uint32_t            RTHCUINT;
+/** Pointer to HC Natural unsigned integer.
+ * @deprecated silly type. */
+typedef RTHCUINT           *PRTHCUINT;
+/** Pointer to const HC Natural unsigned integer.
+ * @deprecated silly type. */
+typedef const RTHCUINT     *PCRTHCUINT;
+
+
+/** Signed integer which can contain a HC pointer. */
+#if HC_ARCH_BITS == 32
+typedef int32_t             RTHCINTPTR;
+#elif HC_ARCH_BITS == 64
+typedef int64_t             RTHCINTPTR;
+#else
+# error Unsupported HC_ARCH_BITS value.
+#endif
+/** Pointer to signed integer which can contain a HC pointer. */
+typedef RTHCINTPTR         *PRTHCINTPTR;
+/** Pointer to const signed integer which can contain a HC pointer. */
+typedef const RTHCINTPTR   *PCRTHCINTPTR;
+/** Max RTHCINTPTR value. */
+#if HC_ARCH_BITS == 32
+# define RTHCINTPTR_MAX     INT32_MAX
+#else
+# define RTHCINTPTR_MAX     INT64_MAX
+#endif
+/** Min RTHCINTPTR value. */
+#if HC_ARCH_BITS == 32
+# define RTHCINTPTR_MIN     INT32_MIN
+#else
+# define RTHCINTPTR_MIN     INT64_MIN
+#endif
+
+/** Signed integer which can contain a HC ring-3 pointer. */
+#if R3_ARCH_BITS == 32
+typedef int32_t             RTR3INTPTR;
+#elif R3_ARCH_BITS == 64
+typedef int64_t             RTR3INTPTR;
+#else
+#  error Unsupported R3_ARCH_BITS value.
+#endif
+/** Pointer to signed integer which can contain a HC ring-3 pointer. */
+typedef RTR3INTPTR         *PRTR3INTPTR;
+/** Pointer to const signed integer which can contain a HC ring-3 pointer. */
+typedef const RTR3INTPTR   *PCRTR3INTPTR;
+/** Max RTR3INTPTR value. */
+#if R3_ARCH_BITS == 32
+# define RTR3INTPTR_MAX     INT32_MAX
+#else
+# define RTR3INTPTR_MAX     INT64_MAX
+#endif
+/** Min RTR3INTPTR value. */
+#if R3_ARCH_BITS == 32
+# define RTR3INTPTR_MIN     INT32_MIN
+#else
+# define RTR3INTPTR_MIN     INT64_MIN
+#endif
+
+/** Signed integer which can contain a HC ring-0 pointer. */
+#if R0_ARCH_BITS == 32
+typedef int32_t             RTR0INTPTR;
+#elif R0_ARCH_BITS == 64
+typedef int64_t             RTR0INTPTR;
+#else
+# error Unsupported R0_ARCH_BITS value.
+#endif
+/** Pointer to signed integer which can contain a HC ring-0 pointer. */
+typedef RTR0INTPTR         *PRTR0INTPTR;
+/** Pointer to const signed integer which can contain a HC ring-0 pointer. */
+typedef const RTR0INTPTR   *PCRTR0INTPTR;
+/** Max RTR0INTPTR value. */
+#if R0_ARCH_BITS == 32
+# define RTR0INTPTR_MAX     INT32_MAX
+#else
+# define RTR0INTPTR_MAX     INT64_MAX
+#endif
+/** Min RTHCINTPTR value. */
+#if R0_ARCH_BITS == 32
+# define RTR0INTPTR_MIN     INT32_MIN
+#else
+# define RTR0INTPTR_MIN     INT64_MIN
+#endif
+
+
+/** Unsigned integer which can contain a HC pointer. */
+#if HC_ARCH_BITS == 32
+typedef uint32_t            RTHCUINTPTR;
+#elif HC_ARCH_BITS == 64
+typedef uint64_t            RTHCUINTPTR;
+#else
+# error Unsupported HC_ARCH_BITS value.
+#endif
+/** Pointer to unsigned integer which can contain a HC pointer. */
+typedef RTHCUINTPTR        *PRTHCUINTPTR;
+/** Pointer to unsigned integer which can contain a HC pointer. */
+typedef const RTHCUINTPTR  *PCRTHCUINTPTR;
+/** Max RTHCUINTTPR value. */
+#if HC_ARCH_BITS == 32
+# define RTHCUINTPTR_MAX    UINT32_MAX
+#else
+# define RTHCUINTPTR_MAX    UINT64_MAX
+#endif
+
+/** Unsigned integer which can contain a HC ring-3 pointer. */
+#if R3_ARCH_BITS == 32
+typedef uint32_t            RTR3UINTPTR;
+#elif R3_ARCH_BITS == 64
+typedef uint64_t            RTR3UINTPTR;
+#else
+# error Unsupported R3_ARCH_BITS value.
+#endif
+/** Pointer to unsigned integer which can contain a HC ring-3 pointer. */
+typedef RTR3UINTPTR        *PRTR3UINTPTR;
+/** Pointer to unsigned integer which can contain a HC ring-3 pointer. */
+typedef const RTR3UINTPTR  *PCRTR3UINTPTR;
+/** Max RTHCUINTTPR value. */
+#if R3_ARCH_BITS == 32
+# define RTR3UINTPTR_MAX    UINT32_MAX
+#else
+# define RTR3UINTPTR_MAX    UINT64_MAX
+#endif
+
+/** Unsigned integer which can contain a HC ring-0 pointer. */
+#if R0_ARCH_BITS == 32
+typedef uint32_t            RTR0UINTPTR;
+#elif R0_ARCH_BITS == 64
+typedef uint64_t            RTR0UINTPTR;
+#else
+# error Unsupported R0_ARCH_BITS value.
+#endif
+/** Pointer to unsigned integer which can contain a HC ring-0 pointer. */
+typedef RTR0UINTPTR        *PRTR0UINTPTR;
+/** Pointer to unsigned integer which can contain a HC ring-0 pointer. */
+typedef const RTR0UINTPTR  *PCRTR0UINTPTR;
+/** Max RTR0UINTTPR value. */
+#if HC_ARCH_BITS == 32
+# define RTR0UINTPTR_MAX    UINT32_MAX
+#else
+# define RTR0UINTPTR_MAX    UINT64_MAX
+#endif
+
+
+/** Host Physical Memory Address. */
+typedef uint64_t            RTHCPHYS;
+/** Pointer to Host Physical Memory Address. */
+typedef RTHCPHYS           *PRTHCPHYS;
+/** Pointer to const Host Physical Memory Address. */
+typedef const RTHCPHYS     *PCRTHCPHYS;
+/** @def NIL_RTHCPHYS
+ * NIL HC Physical Address.
+ * NIL_RTHCPHYS is used to signal an invalid physical address, similar
+ * to the NULL pointer.
+ */
+#define NIL_RTHCPHYS        (~(RTHCPHYS)0)
+/** Max RTHCPHYS value. */
+#define RTHCPHYS_MAX        UINT64_MAX
+
+
+/** HC pointer. */
+#ifndef IN_RC
+typedef void *              RTHCPTR;
+#else
+typedef RTHCUINTPTR         RTHCPTR;
+#endif
+/** Pointer to HC pointer. */
+typedef RTHCPTR            *PRTHCPTR;
+/** Pointer to const HC pointer. */
+typedef const RTHCPTR      *PCRTHCPTR;
+/** @def NIL_RTHCPTR
+ * NIL HC pointer.
+ */
+#define NIL_RTHCPTR         ((RTHCPTR)0)
+/** Max RTHCPTR value. */
+#define RTHCPTR_MAX         ((RTHCPTR)RTHCUINTPTR_MAX)
+
+
+/** HC ring-3 pointer. */
+#ifdef IN_RING3
+typedef void *              RTR3PTR;
+#else
+typedef RTR3UINTPTR         RTR3PTR;
+#endif
+/** Pointer to HC ring-3 pointer. */
+typedef RTR3PTR            *PRTR3PTR;
+/** Pointer to const HC ring-3 pointer. */
+typedef const RTR3PTR      *PCRTR3PTR;
+/** @def NIL_RTR3PTR
+ * NIL HC ring-3 pointer.
+ */
+#ifndef IN_RING3
+# define NIL_RTR3PTR        ((RTR3PTR)0)
+#else
+# define NIL_RTR3PTR        (NULL)
+#endif
+/** Max RTR3PTR value. */
+#define RTR3PTR_MAX         ((RTR3PTR)RTR3UINTPTR_MAX)
+
+/** HC ring-0 pointer. */
+#ifdef  IN_RING0
+typedef void *              RTR0PTR;
+#else
+typedef RTR0UINTPTR         RTR0PTR;
+#endif
+/** Pointer to HC ring-0 pointer. */
+typedef RTR0PTR            *PRTR0PTR;
+/** Pointer to const HC ring-0 pointer. */
+typedef const RTR0PTR      *PCRTR0PTR;
+/** @def NIL_RTR0PTR
+ * NIL HC ring-0 pointer.
+ */
+#ifndef IN_RING0
+# define NIL_RTR0PTR        ((RTR0PTR)0)
+#else
+# define NIL_RTR0PTR        (NULL)
+#endif
+/** Max RTR3PTR value. */
+#define RTR0PTR_MAX         ((RTR0PTR)RTR0UINTPTR_MAX)
+
+
+/** Unsigned integer register in the host context. */
+#if HC_ARCH_BITS == 32
+typedef uint32_t            RTHCUINTREG;
+#elif HC_ARCH_BITS == 64
+typedef uint64_t            RTHCUINTREG;
+#else
+# error "Unsupported HC_ARCH_BITS!"
+#endif
+/** Pointer to an unsigned integer register in the host context. */
+typedef RTHCUINTREG        *PRTHCUINTREG;
+/** Pointer to a const unsigned integer register in the host context. */
+typedef const RTHCUINTREG  *PCRTHCUINTREG;
+
+/** Unsigned integer register in the host ring-3 context. */
+#if R3_ARCH_BITS == 32
+typedef uint32_t            RTR3UINTREG;
+#elif R3_ARCH_BITS == 64
+typedef uint64_t            RTR3UINTREG;
+#else
+# error "Unsupported R3_ARCH_BITS!"
+#endif
+/** Pointer to an unsigned integer register in the host ring-3 context. */
+typedef RTR3UINTREG        *PRTR3UINTREG;
+/** Pointer to a const unsigned integer register in the host ring-3 context. */
+typedef const RTR3UINTREG  *PCRTR3UINTREG;
+
+/** Unsigned integer register in the host ring-3 context. */
+#if R0_ARCH_BITS == 32
+typedef uint32_t            RTR0UINTREG;
+#elif R0_ARCH_BITS == 64
+typedef uint64_t            RTR0UINTREG;
+#else
+# error "Unsupported R3_ARCH_BITS!"
+#endif
+/** Pointer to an unsigned integer register in the host ring-3 context. */
+typedef RTR0UINTREG        *PRTR0UINTREG;
+/** Pointer to a const unsigned integer register in the host ring-3 context. */
+typedef const RTR0UINTREG  *PCRTR0UINTREG;
+
+/** @} */
+
+
+/** @defgroup grp_rt_types_gc  Guest Context Basic Types
+ * @{
+ */
+
+/** Natural signed integer in the GC.
+ * @deprecated silly type. */
+#if GC_ARCH_BITS == 32
+typedef int32_t         RTGCINT;
+#elif GC_ARCH_BITS == 64 /** @todo this isn't right, natural int is 32-bit, see RTHCINT. */
+typedef int64_t         RTGCINT;
+#endif
+/** Pointer to natural signed integer in GC.
+ * @deprecated silly type. */
+typedef RTGCINT        *PRTGCINT;
+/** Pointer to const natural signed integer in GC.
+ * @deprecated silly type. */
+typedef const RTGCINT  *PCRTGCINT;
+
+/** Natural unsigned integer in the GC.
+ * @deprecated silly type. */
+#if GC_ARCH_BITS == 32
+typedef uint32_t        RTGCUINT;
+#elif GC_ARCH_BITS == 64 /** @todo this isn't right, natural int is 32-bit, see RTHCUINT. */
+typedef uint64_t        RTGCUINT;
+#endif
+/** Pointer to natural unsigned integer in GC.
+ * @deprecated silly type. */
+typedef RTGCUINT       *PRTGCUINT;
+/** Pointer to const natural unsigned integer in GC.
+ * @deprecated silly type. */
+typedef const RTGCUINT *PCRTGCUINT;
+
+/** Signed integer which can contain a GC pointer. */
+#if GC_ARCH_BITS == 32
+typedef int32_t         RTGCINTPTR;
+#elif GC_ARCH_BITS == 64
+typedef int64_t         RTGCINTPTR;
+#endif
+/** Pointer to signed integer which can contain a GC pointer. */
+typedef RTGCINTPTR     *PRTGCINTPTR;
+/** Pointer to const signed integer which can contain a GC pointer. */
+typedef const RTGCINTPTR *PCRTGCINTPTR;
+
+/** Unsigned integer which can contain a GC pointer. */
+#if GC_ARCH_BITS == 32
+typedef uint32_t        RTGCUINTPTR;
+#elif GC_ARCH_BITS == 64
+typedef uint64_t        RTGCUINTPTR;
+#else
+#  error Unsupported GC_ARCH_BITS value.
+#endif
+/** Pointer to unsigned integer which can contain a GC pointer. */
+typedef RTGCUINTPTR     *PRTGCUINTPTR;
+/** Pointer to unsigned integer which can contain a GC pointer. */
+typedef const RTGCUINTPTR *PCRTGCUINTPTR;
+
+/** Unsigned integer which can contain a 32 bits GC pointer. */
+typedef uint32_t        RTGCUINTPTR32;
+/** Pointer to unsigned integer which can contain a 32 bits GC pointer. */
+typedef RTGCUINTPTR32   *PRTGCUINTPTR32;
+/** Pointer to unsigned integer which can contain a 32 bits GC pointer. */
+typedef const RTGCUINTPTR32 *PCRTGCUINTPTR32;
+
+/** Unsigned integer which can contain a 64 bits GC pointer. */
+typedef uint64_t        RTGCUINTPTR64;
+/** Pointer to unsigned integer which can contain a 32 bits GC pointer. */
+typedef RTGCUINTPTR64   *PRTGCUINTPTR64;
+/** Pointer to unsigned integer which can contain a 32 bits GC pointer. */
+typedef const RTGCUINTPTR64 *PCRTGCUINTPTR64;
+
+/** Guest Physical Memory Address.*/
+typedef uint64_t            RTGCPHYS;
+/** Pointer to Guest Physical Memory Address. */
+typedef RTGCPHYS           *PRTGCPHYS;
+/** Pointer to const Guest Physical Memory Address. */
+typedef const RTGCPHYS     *PCRTGCPHYS;
+/** @def NIL_RTGCPHYS
+ * NIL GC Physical Address.
+ * NIL_RTGCPHYS is used to signal an invalid physical address, similar
+ * to the NULL pointer. Note that this value may actually be valid in
+ * some contexts.
+ */
+#define NIL_RTGCPHYS        (~(RTGCPHYS)0U)
+/** Max guest physical memory address value. */
+#define RTGCPHYS_MAX        UINT64_MAX
+
+
+/** Guest Physical Memory Address; limited to 32 bits.*/
+typedef uint32_t            RTGCPHYS32;
+/** Pointer to Guest Physical Memory Address. */
+typedef RTGCPHYS32         *PRTGCPHYS32;
+/** Pointer to const Guest Physical Memory Address. */
+typedef const RTGCPHYS32    *PCRTGCPHYS32;
+/** @def NIL_RTGCPHYS32
+ * NIL GC Physical Address.
+ * NIL_RTGCPHYS32 is used to signal an invalid physical address, similar
+ * to the NULL pointer. Note that this value may actually be valid in
+ * some contexts.
+ */
+#define NIL_RTGCPHYS32     (~(RTGCPHYS32)0)
+
+
+/** Guest Physical Memory Address; limited to 64 bits.*/
+typedef uint64_t        RTGCPHYS64;
+/** Pointer to Guest Physical Memory Address. */
+typedef RTGCPHYS64     *PRTGCPHYS64;
+/** Pointer to const Guest Physical Memory Address. */
+typedef const RTGCPHYS64 *PCRTGCPHYS64;
+/** @def NIL_RTGCPHYS64
+ * NIL GC Physical Address.
+ * NIL_RTGCPHYS64 is used to signal an invalid physical address, similar
+ * to the NULL pointer. Note that this value may actually be valid in
+ * some contexts.
+ */
+#define NIL_RTGCPHYS64     (~(RTGCPHYS64)0)
+
+/** Guest context pointer, 32 bits.
+ * Keep in mind that this type is an unsigned integer in
+ * HC and void pointer in GC.
+ */
+typedef RTGCUINTPTR32   RTGCPTR32;
+/** Pointer to a guest context pointer. */
+typedef RTGCPTR32      *PRTGCPTR32;
+/** Pointer to a const guest context pointer. */
+typedef const RTGCPTR32 *PCRTGCPTR32;
+/** @def NIL_RTGCPTR32
+ * NIL GC pointer.
+ */
+#define NIL_RTGCPTR32   ((RTGCPTR32)0)
+
+/** Guest context pointer, 64 bits.
+ */
+typedef RTGCUINTPTR64   RTGCPTR64;
+/** Pointer to a guest context pointer. */
+typedef RTGCPTR64      *PRTGCPTR64;
+/** Pointer to a const guest context pointer. */
+typedef const RTGCPTR64 *PCRTGCPTR64;
+/** @def NIL_RTGCPTR64
+ * NIL GC pointer.
+ */
+#define NIL_RTGCPTR64   ((RTGCPTR64)0)
+
+/** Guest context pointer.
+ * Keep in mind that this type is an unsigned integer in
+ * HC and void pointer in GC.
+ */
+#if GC_ARCH_BITS == 64
+typedef RTGCPTR64       RTGCPTR;
+/** Pointer to a guest context pointer. */
+typedef PRTGCPTR64      PRTGCPTR;
+/** Pointer to a const guest context pointer. */
+typedef PCRTGCPTR64     PCRTGCPTR;
+/** @def NIL_RTGCPTR
+ * NIL GC pointer.
+ */
+# define NIL_RTGCPTR    NIL_RTGCPTR64
+/** Max RTGCPTR value. */
+# define RTGCPTR_MAX    UINT64_MAX
+#elif GC_ARCH_BITS == 32
+typedef RTGCPTR32       RTGCPTR;
+/** Pointer to a guest context pointer. */
+typedef PRTGCPTR32      PRTGCPTR;
+/** Pointer to a const guest context pointer. */
+typedef PCRTGCPTR32     PCRTGCPTR;
+/** @def NIL_RTGCPTR
+ * NIL GC pointer.
+ */
+# define NIL_RTGCPTR     NIL_RTGCPTR32
+/** Max RTGCPTR value. */
+# define RTGCPTR_MAX    UINT32_MAX
+#else
+# error "Unsupported GC_ARCH_BITS!"
+#endif
+
+/** Unsigned integer register in the guest context. */
+typedef uint32_t              RTGCUINTREG32;
+/** Pointer to an unsigned integer register in the guest context. */
+typedef RTGCUINTREG32        *PRTGCUINTREG32;
+/** Pointer to a const unsigned integer register in the guest context. */
+typedef const RTGCUINTREG32  *PCRTGCUINTREG32;
+
+typedef uint64_t              RTGCUINTREG64;
+/** Pointer to an unsigned integer register in the guest context. */
+typedef RTGCUINTREG64        *PRTGCUINTREG64;
+/** Pointer to a const unsigned integer register in the guest context. */
+typedef const RTGCUINTREG64  *PCRTGCUINTREG64;
+
+#if GC_ARCH_BITS == 64
+typedef RTGCUINTREG64           RTGCUINTREG;
+#elif GC_ARCH_BITS == 32
+typedef RTGCUINTREG32           RTGCUINTREG;
+#else
+# error "Unsupported GC_ARCH_BITS!"
+#endif
+/** Pointer to an unsigned integer register in the guest context. */
+typedef RTGCUINTREG            *PRTGCUINTREG;
+/** Pointer to a const unsigned integer register in the guest context. */
+typedef const RTGCUINTREG      *PCRTGCUINTREG;
+
+/** @} */
+
+/** @defgroup grp_rt_types_rc  Raw mode Context Basic Types
+ * @{
+ */
+
+/** Raw mode context pointer; a 32 bits guest context pointer.
+ * Keep in mind that this type is an unsigned integer in
+ * HC and void pointer in RC.
+ */
+#ifdef IN_RC
+typedef void *          RTRCPTR;
+#else
+typedef uint32_t        RTRCPTR;
+#endif
+/** Pointer to a raw mode context pointer. */
+typedef RTRCPTR        *PRTRCPTR;
+/** Pointer to a const raw mode context pointer. */
+typedef const RTRCPTR  *PCRTRCPTR;
+/** @def NIL_RTGCPTR
+ * NIL RC pointer.
+ */
+#ifndef IN_RC
+# define NIL_RTRCPTR   ((RTRCPTR)0)
+#else
+# define NIL_RTRCPTR   (NULL)
+#endif
+/** @def RTRCPTR_MAX
+ * The maximum value a RTRCPTR can have. Mostly used as INVALID value.
+ */
+#define RTRCPTR_MAX    ((RTRCPTR)UINT32_MAX)
+
+/** Raw mode context pointer, unsigned integer variant. */
+typedef int32_t         RTRCINTPTR;
+/** @def RTRCUINTPTR_MAX
+ * The maximum value a RTRCUINPTR can have.
+ */
+#define RTRCUINTPTR_MAX ((RTRCUINTPTR)UINT32_MAX)
+
+/** Raw mode context pointer, signed integer variant. */
+typedef uint32_t        RTRCUINTPTR;
+/** @def RTRCINTPTR_MIN
+ * The minimum value a RTRCINPTR can have.
+ */
+#define RTRCINTPTR_MIN ((RTRCINTPTR)INT32_MIN)
+/** @def RTRCINTPTR_MAX
+ * The maximum value a RTRCINPTR can have.
+ */
+#define RTRCINTPTR_MAX ((RTRCINTPTR)INT32_MAX)
+
+/** @} */
+
+
+/** @defgroup grp_rt_types_cc  Current Context Basic Types
+ * @{
+ */
+
+/** Current Context Physical Memory Address.*/
+#ifdef IN_RC
+typedef RTGCPHYS RTCCPHYS;
+#else
+typedef RTHCPHYS RTCCPHYS;
+#endif
+/** Pointer to Current Context Physical Memory Address. */
+typedef RTCCPHYS       *PRTCCPHYS;
+/** Pointer to const Current Context Physical Memory Address. */
+typedef const RTCCPHYS *PCRTCCPHYS;
+/** @def NIL_RTCCPHYS
+ * NIL CC Physical Address.
+ * NIL_RTCCPHYS is used to signal an invalid physical address, similar
+ * to the NULL pointer.
+ */
+#ifdef IN_RC
+# define NIL_RTCCPHYS   NIL_RTGCPHYS
+#else
+# define NIL_RTCCPHYS   NIL_RTHCPHYS
+#endif
+
+/** Unsigned integer register in the current context. */
+#if ARCH_BITS == 32
+typedef uint32_t                RTCCUINTREG;
+#elif ARCH_BITS == 64
+typedef uint64_t                RTCCUINTREG;
+#else
+# error "Unsupported ARCH_BITS!"
+#endif
+/** Pointer to an unsigned integer register in the current context. */
+typedef RTCCUINTREG            *PRTCCUINTREG;
+/** Pointer to a const unsigned integer register in the current context. */
+typedef RTCCUINTREG const      *PCRTCCUINTREG;
+
+/** Signed integer register in the current context. */
+#if ARCH_BITS == 32
+typedef int32_t                 RTCCINTREG;
+#elif ARCH_BITS == 64
+typedef int64_t                 RTCCINTREG;
+#endif
+/** Pointer to a signed integer register in the current context. */
+typedef RTCCINTREG             *PRTCCINTREG;
+/** Pointer to a const signed integer register in the current context. */
+typedef RTCCINTREG const       *PCRTCCINTREG;
+
+/** @} */
+
+
+
+/** Pointer to a big integer number. */
+typedef struct RTBIGNUM                            *PRTBIGNUM;
+/** Pointer to a const big integer number. */
+typedef struct RTBIGNUM const                      *PCRTBIGNUM;
+
+
+/** Pointer to a critical section. */
+typedef struct RTCRITSECT                          *PRTCRITSECT;
+/** Pointer to a const critical section. */
+typedef const struct RTCRITSECT                    *PCRTCRITSECT;
+
+/** Pointer to a read/write critical section. */
+typedef struct RTCRITSECTRW                        *PRTCRITSECTRW;
+/** Pointer to a const read/write critical section. */
+typedef const struct RTCRITSECTRW                  *PCRTCRITSECTRW;
+
+
+/** Condition variable handle. */
+typedef R3PTRTYPE(struct RTCONDVARINTERNAL *)       RTCONDVAR;
+/** Pointer to a condition variable handle. */
+typedef RTCONDVAR                                  *PRTCONDVAR;
+/** Nil condition variable handle. */
+#define NIL_RTCONDVAR                               0
+
+/** Cryptographic (certificate) store handle. */
+typedef R3R0PTRTYPE(struct RTCRSTOREINT *)          RTCRSTORE;
+/** Pointer to a Cryptographic (certificate) store handle. */
+typedef RTCRSTORE                                  *PRTCRSTORE;
+/** Nil Cryptographic (certificate) store handle. */
+#define NIL_RTCRSTORE                               0
+
+/** Pointer to a const (store) certificate context. */
+typedef struct RTCRCERTCTX const                   *PCRTCRCERTCTX;
+
+/** Cryptographic message digest handle. */
+typedef R3R0PTRTYPE(struct RTCRDIGESTINT *)         RTCRDIGEST;
+/** Pointer to a cryptographic message digest handle. */
+typedef RTCRDIGEST                                 *PRTCRDIGEST;
+/** NIL cryptographic message digest handle. */
+#define NIL_RTCRDIGEST                              (0)
+
+/** Public key encryption schema handle. */
+typedef R3R0PTRTYPE(struct RTCRPKIXENCRYPTIONINT *) RTCRPKIXENCRYPTION;
+/** Pointer to a public key encryption schema handle. */
+typedef RTCRPKIXENCRYPTION                         *PRTCRPKIXENCRYPTION;
+/** NIL public key encryption schema handle */
+#define NIL_RTCRPKIXENCRYPTION                      (0)
+
+/** Public key signature schema handle. */
+typedef R3R0PTRTYPE(struct RTCRPKIXSIGNATUREINT *)  RTCRPKIXSIGNATURE;
+/** Pointer to a public key signature schema handle. */
+typedef RTCRPKIXSIGNATURE                          *PRTCRPKIXSIGNATURE;
+/** NIL public key signature schema handle */
+#define NIL_RTCRPKIXSIGNATURE                       (0)
+
+/** X.509 certificate paths builder & validator handle. */
+typedef R3R0PTRTYPE(struct RTCRX509CERTPATHSINT *)  RTCRX509CERTPATHS;
+/** Pointer to a certificate paths builder & validator handle. */
+typedef RTCRX509CERTPATHS                          *PRTCRX509CERTPATHS;
+/** Nil certificate paths builder & validator handle. */
+#define NIL_RTCRX509CERTPATHS                       0
+
+/** File handle. */
+typedef R3R0PTRTYPE(struct RTFILEINT *)             RTFILE;
+/** Pointer to file handle. */
+typedef RTFILE                                     *PRTFILE;
+/** Nil file handle. */
+#define NIL_RTFILE                                  ((RTFILE)~(RTHCINTPTR)0)
+
+/** Async I/O request handle. */
+typedef R3PTRTYPE(struct RTFILEAIOREQINTERNAL *)    RTFILEAIOREQ;
+/** Pointer to an async I/O request handle. */
+typedef RTFILEAIOREQ                               *PRTFILEAIOREQ;
+/** Nil request handle. */
+#define NIL_RTFILEAIOREQ                            0
+
+/** Async I/O completion context handle. */
+typedef R3PTRTYPE(struct RTFILEAIOCTXINTERNAL *)    RTFILEAIOCTX;
+/** Pointer to an async I/O completion context handle. */
+typedef RTFILEAIOCTX                               *PRTFILEAIOCTX;
+/** Nil context handle. */
+#define NIL_RTFILEAIOCTX                            0
+
+/** Loader module handle. */
+typedef R3R0PTRTYPE(struct RTLDRMODINTERNAL *)      RTLDRMOD;
+/** Pointer to a loader module handle. */
+typedef RTLDRMOD                                   *PRTLDRMOD;
+/** Nil loader module handle. */
+#define NIL_RTLDRMOD                                0
+
+/** Lock validator class handle. */
+typedef R3R0PTRTYPE(struct RTLOCKVALCLASSINT *)     RTLOCKVALCLASS;
+/** Pointer to a lock validator class handle. */
+typedef RTLOCKVALCLASS                             *PRTLOCKVALCLASS;
+/** Nil lock validator class handle. */
+#define NIL_RTLOCKVALCLASS                         ((RTLOCKVALCLASS)0)
+
+/** Ring-0 memory object handle. */
+typedef R0PTRTYPE(struct RTR0MEMOBJINTERNAL *)      RTR0MEMOBJ;
+/** Pointer to a Ring-0 memory object handle. */
+typedef RTR0MEMOBJ                                 *PRTR0MEMOBJ;
+/** Nil ring-0 memory object handle. */
+#define NIL_RTR0MEMOBJ                              0
+
+/** Native thread handle. */
+typedef RTHCUINTPTR                                 RTNATIVETHREAD;
+/** Pointer to an native thread handle. */
+typedef RTNATIVETHREAD                             *PRTNATIVETHREAD;
+/** Nil native thread handle. */
+#define NIL_RTNATIVETHREAD                          (~(RTNATIVETHREAD)0)
+
+/** Pipe handle. */
+typedef R3R0PTRTYPE(struct RTPIPEINTERNAL *)        RTPIPE;
+/** Pointer to a pipe handle. */
+typedef RTPIPE                                     *PRTPIPE;
+/** Nil pipe handle.
+ * @remarks This is not 0 because of UNIX and OS/2 handle values. Take care! */
+#define NIL_RTPIPE                                 ((RTPIPE)RTHCUINTPTR_MAX)
+
+/** @typedef RTPOLLSET
+ * Poll set handle. */
+typedef R3R0PTRTYPE(struct RTPOLLSETINTERNAL *)     RTPOLLSET;
+/** Pointer to a poll set handle. */
+typedef RTPOLLSET                                  *PRTPOLLSET;
+/** Nil poll set handle handle. */
+#define NIL_RTPOLLSET                               ((RTPOLLSET)0)
+
+/** Process identifier. */
+typedef uint32_t                                    RTPROCESS;
+/** Pointer to a process identifier. */
+typedef RTPROCESS                                  *PRTPROCESS;
+/** Nil process identifier. */
+#define NIL_RTPROCESS                               (~(RTPROCESS)0)
+
+/** Process ring-0 handle. */
+typedef RTR0UINTPTR                                 RTR0PROCESS;
+/** Pointer to a ring-0 process handle. */
+typedef RTR0PROCESS                                *PRTR0PROCESS;
+/** Nil ring-0 process handle. */
+#define NIL_RTR0PROCESS                             (~(RTR0PROCESS)0)
+
+/** @typedef RTSEMEVENT
+ * Event Semaphore handle. */
+typedef R3R0PTRTYPE(struct RTSEMEVENTINTERNAL *)    RTSEMEVENT;
+/** Pointer to an event semaphore handle. */
+typedef RTSEMEVENT                                 *PRTSEMEVENT;
+/** Nil event semaphore handle. */
+#define NIL_RTSEMEVENT                              0
+
+/** @typedef RTSEMEVENTMULTI
+ * Event Multiple Release Semaphore handle. */
+typedef R3R0PTRTYPE(struct RTSEMEVENTMULTIINTERNAL *) RTSEMEVENTMULTI;
+/** Pointer to an event multiple release semaphore handle. */
+typedef RTSEMEVENTMULTI                            *PRTSEMEVENTMULTI;
+/** Nil multiple release event semaphore handle. */
+#define NIL_RTSEMEVENTMULTI                         0
+
+/** @typedef RTSEMFASTMUTEX
+ * Fast mutex Semaphore handle. */
+typedef R3R0PTRTYPE(struct RTSEMFASTMUTEXINTERNAL *) RTSEMFASTMUTEX;
+/** Pointer to a fast mutex semaphore handle. */
+typedef RTSEMFASTMUTEX                             *PRTSEMFASTMUTEX;
+/** Nil fast mutex semaphore handle. */
+#define NIL_RTSEMFASTMUTEX                          0
+
+/** @typedef RTSEMMUTEX
+ * Mutex Semaphore handle. */
+typedef R3R0PTRTYPE(struct RTSEMMUTEXINTERNAL *)    RTSEMMUTEX;
+/** Pointer to a mutex semaphore handle. */
+typedef RTSEMMUTEX                                 *PRTSEMMUTEX;
+/** Nil mutex semaphore handle. */
+#define NIL_RTSEMMUTEX                              0
+
+/** @typedef RTSEMSPINMUTEX
+ * Spinning mutex Semaphore handle. */
+typedef R3R0PTRTYPE(struct RTSEMSPINMUTEXINTERNAL *) RTSEMSPINMUTEX;
+/** Pointer to a spinning mutex semaphore handle. */
+typedef RTSEMSPINMUTEX                             *PRTSEMSPINMUTEX;
+/** Nil spinning mutex semaphore handle. */
+#define NIL_RTSEMSPINMUTEX                          0
+
+/** @typedef RTSEMRW
+ * Read/Write Semaphore handle. */
+typedef R3R0PTRTYPE(struct RTSEMRWINTERNAL *)       RTSEMRW;
+/** Pointer to a read/write semaphore handle. */
+typedef RTSEMRW                                    *PRTSEMRW;
+/** Nil read/write semaphore handle. */
+#define NIL_RTSEMRW                                 0
+
+/** @typedef RTSEMXROADS
+ * Crossroads semaphore handle. */
+typedef R3R0PTRTYPE(struct RTSEMXROADSINTERNAL *)   RTSEMXROADS;
+/** Pointer to a crossroads semaphore handle. */
+typedef RTSEMXROADS                                *PRTSEMXROADS;
+/** Nil crossroads semaphore handle. */
+#define NIL_RTSEMXROADS                             ((RTSEMXROADS)0)
+
+/** Spinlock handle. */
+typedef R3R0PTRTYPE(struct RTSPINLOCKINTERNAL *)    RTSPINLOCK;
+/** Pointer to a spinlock handle. */
+typedef RTSPINLOCK                                 *PRTSPINLOCK;
+/** Nil spinlock handle. */
+#define NIL_RTSPINLOCK                              0
+
+/** Socket handle. */
+typedef R3R0PTRTYPE(struct RTSOCKETINT *)           RTSOCKET;
+/** Pointer to socket handle. */
+typedef RTSOCKET                                   *PRTSOCKET;
+/** Nil socket handle. */
+#define NIL_RTSOCKET                                ((RTSOCKET)0)
+
+/** Pointer to a RTTCPSERVER handle. */
+typedef struct RTTCPSERVER                         *PRTTCPSERVER;
+/** Pointer to a RTTCPSERVER handle. */
+typedef PRTTCPSERVER                               *PPRTTCPSERVER;
+/** Nil RTTCPSERVER handle. */
+#define NIL_RTTCPSERVER                            ((PRTTCPSERVER)0)
+
+/** Pointer to a RTUDPSERVER handle. */
+typedef struct RTUDPSERVER                         *PRTUDPSERVER;
+/** Pointer to a RTUDPSERVER handle. */
+typedef PRTUDPSERVER                               *PPRTUDPSERVER;
+/** Nil RTUDPSERVER handle. */
+#define NIL_RTUDPSERVER                            ((PRTUDPSERVER)0)
+
+/** Thread handle.*/
+typedef R3R0PTRTYPE(struct RTTHREADINT *)           RTTHREAD;
+/** Pointer to thread handle. */
+typedef RTTHREAD                                   *PRTTHREAD;
+/** Nil thread handle. */
+#define NIL_RTTHREAD                                0
+
+/** Thread context switching hook handle.   */
+typedef R0PTRTYPE(struct RTTHREADCTXHOOKINT *)      RTTHREADCTXHOOK;
+/** Pointer to Thread context switching hook handle. */
+typedef RTTHREADCTXHOOK                            *PRTTHREADCTXHOOK;
+/** Nil Thread context switching hook handle. */
+#define NIL_RTTHREADCTXHOOK                         ((RTTHREADCTXHOOK)0)
+
+/** A TLS index. */
+typedef RTHCINTPTR                                  RTTLS;
+/** Pointer to a TLS index. */
+typedef RTTLS                                      *PRTTLS;
+/** Pointer to a const TLS index. */
+typedef RTTLS const                                *PCRTTLS;
+/** NIL TLS index value. */
+#define NIL_RTTLS                                   ((RTTLS)-1)
+
+/** Trace buffer handle.
+ * @remarks This is not a R3/R0 type like most other handles!
+ */
+typedef struct RTTRACEBUFINT                        *RTTRACEBUF;
+/** Pointer to a trace buffer handle. */
+typedef RTTRACEBUF                                  *PRTTRACEBUF;
+/** Nil trace buffer handle. */
+#define NIL_RTTRACEBUF                              ((RTTRACEBUF)0)
+/** The handle of the default trace buffer.
+ * This can be used with any of the RTTraceBufAdd APIs. */
+#define RTTRACEBUF_DEFAULT                          ((RTTRACEBUF)-2)
+
+/** Handle to a simple heap. */
+typedef R3R0PTRTYPE(struct RTHEAPSIMPLEINTERNAL *)  RTHEAPSIMPLE;
+/** Pointer to a handle to a simple heap. */
+typedef RTHEAPSIMPLE                               *PRTHEAPSIMPLE;
+/** NIL simple heap handle. */
+#define NIL_RTHEAPSIMPLE                            ((RTHEAPSIMPLE)0)
+
+/** Handle to an offset based heap. */
+typedef R3R0PTRTYPE(struct RTHEAPOFFSETINTERNAL *)  RTHEAPOFFSET;
+/** Pointer to a handle to an offset based heap. */
+typedef RTHEAPOFFSET                               *PRTHEAPOFFSET;
+/** NIL offset based heap handle. */
+#define NIL_RTHEAPOFFSET                            ((RTHEAPOFFSET)0)
+
+/** Handle to an environment block. */
+typedef R3PTRTYPE(struct RTENVINTERNAL *)           RTENV;
+/** Pointer to a handle to an environment block. */
+typedef RTENV                                      *PRTENV;
+/** NIL simple heap handle. */
+#define NIL_RTENV                                   ((RTENV)0)
+
+/** A CPU identifier.
+ * @remarks This doesn't have to correspond to the APIC ID (intel/amd). Nor
+ *          does it have to correspond to the bits in the affinity mask, at
+ *          least not until we've sorted out Windows NT. */
+typedef uint32_t                                    RTCPUID;
+/** Pointer to a CPU identifier. */
+typedef RTCPUID                                    *PRTCPUID;
+/** Pointer to a const CPU identifier. */
+typedef RTCPUID const                              *PCRTCPUID;
+/** Nil CPU Id. */
+#define NIL_RTCPUID                                 ((RTCPUID)~0)
+
+/** The maximum number of CPUs a set can contain and IPRT is able
+ * to reference. (Should be max of support arch/platforms.)
+ * @remarks Must be a multiple of 64 (see RTCPUSET).  */
+#if defined(RT_ARCH_X86) || defined(RT_ARCH_AMD64)
+# define RTCPUSET_MAX_CPUS      256
+#elif defined(RT_ARCH_SPARC) || defined(RT_ARCH_SPARC64)
+# define RTCPUSET_MAX_CPUS      1024
+#else
+# define RTCPUSET_MAX_CPUS      64
+#endif
+/** A CPU set.
+ * @note    Treat this as an opaque type and always use RTCpuSet* for
+ *          manipulating it. */
+typedef struct RTCPUSET
+{
+    /** The bitmap.  */
+    uint64_t bmSet[RTCPUSET_MAX_CPUS / 64];
+} RTCPUSET;
+/** Pointer to a CPU set. */
+typedef RTCPUSET                                   *PRTCPUSET;
+/** Pointer to a const CPU set. */
+typedef RTCPUSET const                             *PCRTCPUSET;
+
+/** A handle table handle. */
+typedef R3R0PTRTYPE(struct RTHANDLETABLEINT *)      RTHANDLETABLE;
+/** A pointer to a handle table handle. */
+typedef RTHANDLETABLE                              *PRTHANDLETABLE;
+/** @def NIL_RTHANDLETABLE
+ * NIL handle table handle. */
+#define NIL_RTHANDLETABLE                           ((RTHANDLETABLE)0)
+
+/** A handle to a low resolution timer. */
+typedef R3R0PTRTYPE(struct RTTIMERLRINT *)          RTTIMERLR;
+/** A pointer to a low resolution timer handle. */
+typedef RTTIMERLR                                  *PRTTIMERLR;
+/** @def NIL_RTTIMERLR
+ * NIL low resolution timer handle value. */
+#define NIL_RTTIMERLR                               ((RTTIMERLR)0)
+
+/** Handle to a random number generator. */
+typedef R3R0PTRTYPE(struct RTRANDINT *)             RTRAND;
+/** Pointer to a random number generator handle. */
+typedef RTRAND                                     *PRTRAND;
+/** NIL random number generator handle value. */
+#define NIL_RTRAND                                  ((RTRAND)0)
+
+/** Debug address space handle. */
+typedef R3R0PTRTYPE(struct RTDBGASINT *)            RTDBGAS;
+/** Pointer to a debug address space handle. */
+typedef RTDBGAS                                    *PRTDBGAS;
+/** NIL debug address space handle. */
+#define NIL_RTDBGAS                                 ((RTDBGAS)0)
+
+/** Debug module handle. */
+typedef R3R0PTRTYPE(struct RTDBGMODINT *)           RTDBGMOD;
+/** Pointer to a debug module handle. */
+typedef RTDBGMOD                                   *PRTDBGMOD;
+/** NIL debug module handle. */
+#define NIL_RTDBGMOD                                ((RTDBGMOD)0)
+
+/** Manifest handle. */
+typedef struct RTMANIFESTINT                       *RTMANIFEST;
+/** Pointer to a manifest handle. */
+typedef RTMANIFEST                                 *PRTMANIFEST;
+/** NIL manifest handle. */
+#define NIL_RTMANIFEST                              ((RTMANIFEST)~(uintptr_t)0)
+
+/** Memory pool handle. */
+typedef R3R0PTRTYPE(struct RTMEMPOOLINT *)          RTMEMPOOL;
+/** Pointer to a memory pool handle. */
+typedef RTMEMPOOL                                  *PRTMEMPOOL;
+/** NIL memory pool handle. */
+#define NIL_RTMEMPOOL                               ((RTMEMPOOL)0)
+/** The default memory pool handle. */
+#define RTMEMPOOL_DEFAULT                           ((RTMEMPOOL)-2)
+
+/** String cache handle. */
+typedef R3R0PTRTYPE(struct RTSTRCACHEINT *)         RTSTRCACHE;
+/** Pointer to a string cache handle. */
+typedef RTSTRCACHE                                 *PRTSTRCACHE;
+/** NIL string cache handle. */
+#define NIL_RTSTRCACHE                              ((RTSTRCACHE)0)
+/** The default string cache handle. */
+#define RTSTRCACHE_DEFAULT                          ((RTSTRCACHE)-2)
+
+
+/** Virtual Filesystem handle. */
+typedef struct RTVFSINTERNAL                       *RTVFS;
+/** Pointer to a VFS handle. */
+typedef RTVFS                                      *PRTVFS;
+/** A NIL VFS handle. */
+#define NIL_RTVFS                                   ((RTVFS)~(uintptr_t)0)
+
+/** Virtual Filesystem base object handle. */
+typedef struct RTVFSOBJINTERNAL                    *RTVFSOBJ;
+/** Pointer to a VFS base object handle. */
+typedef RTVFSOBJ                                   *PRTVFSOBJ;
+/** A NIL VFS base object handle. */
+#define NIL_RTVFSOBJ                                ((RTVFSOBJ)~(uintptr_t)0)
+
+/** Virtual Filesystem directory handle. */
+typedef struct RTVFSDIRINTERNAL                    *RTVFSDIR;
+/** Pointer to a VFS directory handle. */
+typedef RTVFSDIR                                   *PRTVFSDIR;
+/** A NIL VFS directory handle. */
+#define NIL_RTVFSDIR                                ((RTVFSDIR)~(uintptr_t)0)
+
+/** Virtual Filesystem filesystem stream handle. */
+typedef struct RTVFSFSSTREAMINTERNAL               *RTVFSFSSTREAM;
+/** Pointer to a VFS filesystem stream handle. */
+typedef RTVFSFSSTREAM                              *PRTVFSFSSTREAM;
+/** A NIL VFS filesystem stream handle. */
+#define NIL_RTVFSFSSTREAM                           ((RTVFSFSSTREAM)~(uintptr_t)0)
+
+/** Virtual Filesystem I/O stream handle. */
+typedef struct RTVFSIOSTREAMINTERNAL               *RTVFSIOSTREAM;
+/** Pointer to a VFS I/O stream handle. */
+typedef RTVFSIOSTREAM                              *PRTVFSIOSTREAM;
+/** A NIL VFS I/O stream handle. */
+#define NIL_RTVFSIOSTREAM                           ((RTVFSIOSTREAM)~(uintptr_t)0)
+
+/** Virtual Filesystem file handle. */
+typedef struct RTVFSFILEINTERNAL                   *RTVFSFILE;
+/** Pointer to a VFS file handle. */
+typedef RTVFSFILE                                  *PRTVFSFILE;
+/** A NIL VFS file handle. */
+#define NIL_RTVFSFILE                               ((RTVFSFILE)~(uintptr_t)0)
+
+/** Virtual Filesystem symbolic link handle. */
+typedef struct RTVFSSYMLINKINTERNAL                *RTVFSSYMLINK;
+/** Pointer to a VFS symbolic link handle. */
+typedef RTVFSSYMLINK                               *PRTVFSSYMLINK;
+/** A NIL VFS symbolic link handle. */
+#define NIL_RTVFSSYMLINK                            ((RTVFSSYMLINK)~(uintptr_t)0)
+
+/** Async I/O manager handle. */
+typedef struct RTAIOMGRINT                         *RTAIOMGR;
+/** Pointer to a async I/O manager handle. */
+typedef RTAIOMGR                                   *PRTAIOMGR;
+/** A NIL async I/O manager handle. */
+#define NIL_RTAIOMGR                                ((RTAIOMGR)~(uintptr_t)0)
+
+/** Async I/O manager file handle. */
+typedef struct RTAIOMGRFILEINT                     *RTAIOMGRFILE;
+/** Pointer to a async I/O manager file handle. */
+typedef RTAIOMGRFILE                               *PRTAIOMGRFILE;
+/** A NIL async I/O manager file handle. */
+#define NIL_RTAIOMGRFILE                            ((RTAIOMGRFILE)~(uintptr_t)0)
+
+/**
+ * Handle type.
+ *
+ * This is usually used together with RTHANDLEUNION.
+ */
+typedef enum RTHANDLETYPE
+{
+    /** The invalid zero value. */
+    RTHANDLETYPE_INVALID = 0,
+    /** File handle. */
+    RTHANDLETYPE_FILE,
+    /** Pipe handle */
+    RTHANDLETYPE_PIPE,
+    /** Socket handle. */
+    RTHANDLETYPE_SOCKET,
+    /** Thread handle. */
+    RTHANDLETYPE_THREAD,
+    /** The end of the valid values. */
+    RTHANDLETYPE_END,
+    /** The 32-bit type blow up. */
+    RTHANDLETYPE_32BIT_HACK = 0x7fffffff
+} RTHANDLETYPE;
+/** Pointer to a handle type. */
+typedef RTHANDLETYPE *PRTHANDLETYPE;
+
+/**
+ * Handle union.
+ *
+ * This is usually used together with RTHANDLETYPE or as RTHANDLE.
+ */
+typedef union RTHANDLEUNION
+{
+    RTFILE          hFile;              /**< File handle. */
+    RTPIPE          hPipe;              /**< Pipe handle. */
+    RTSOCKET        hSocket;            /**< Socket handle. */
+    RTTHREAD        hThread;            /**< Thread handle. */
+    /** Generic integer handle value.
+     * Note that RTFILE is not yet pointer sized, so accessing it via this member
+     * isn't necessarily safe or fully portable. */
+    RTHCUINTPTR     uInt;
+} RTHANDLEUNION;
+/** Pointer to a handle union. */
+typedef RTHANDLEUNION *PRTHANDLEUNION;
+/** Pointer to a const handle union. */
+typedef RTHANDLEUNION const *PCRTHANDLEUNION;
+
+/**
+ * Generic handle.
+ */
+typedef struct RTHANDLE
+{
+    /** The handle type. */
+    RTHANDLETYPE    enmType;
+    /** The handle value. */
+    RTHANDLEUNION   u;
+} RTHANDLE;
+/** Pointer to a generic handle. */
+typedef RTHANDLE *PRTHANDLE;
+/** Pointer to a const generic handle. */
+typedef RTHANDLE const *PCRTHANDLE;
+
+
+/**
+ * Standard handles.
+ *
+ * @remarks These have the correct file descriptor values for unixy systems and
+ *          can be used directly in code specific to those platforms.
+ */
+typedef enum RTHANDLESTD
+{
+    /** Invalid standard handle. */
+    RTHANDLESTD_INVALID = -1,
+    /** The standard input handle. */
+    RTHANDLESTD_INPUT = 0,
+    /** The standard output handle. */
+    RTHANDLESTD_OUTPUT,
+    /** The standard error handle. */
+    RTHANDLESTD_ERROR,
+    /** The typical 32-bit type hack. */
+    RTHANDLESTD_32BIT_HACK = 0x7fffffff
+} RTHANDLESTD;
+
+
+/**
+ * Error info.
+ *
+ * See RTErrInfo*.
+ */
+typedef struct RTERRINFO
+{
+    /** Flags, see RTERRINFO_FLAGS_XXX. */
+    uint32_t    fFlags;
+    /** The status code. */
+    int32_t     rc;
+    /** The size of the message  */
+    size_t      cbMsg;
+    /** The error buffer. */
+    char       *pszMsg;
+    /** Reserved for future use. */
+    void       *apvReserved[2];
+} RTERRINFO;
+/** Pointer to an error info structure. */
+typedef RTERRINFO *PRTERRINFO;
+/** Pointer to a const error info structure. */
+typedef RTERRINFO const *PCRTERRINFO;
+
+/**
+ * Static error info structure, see RTErrInfoInitStatic.
+ */
+typedef struct RTERRINFOSTATIC
+{
+    /** The core error info. */
+    RTERRINFO   Core;
+    /** The static message buffer. */
+    char        szMsg[3072];
+} RTERRINFOSTATIC;
+/** Pointer to a error info buffer. */
+typedef RTERRINFOSTATIC *PRTERRINFOSTATIC;
+/** Pointer to a const static error info buffer. */
+typedef RTERRINFOSTATIC const *PCRTERRINFOSTATIC;
+
+
+/**
+ * UUID data type.
+ *
+ * See RTUuid*.
+ *
+ * @remarks IPRT defines that the first three integers in the @c Gen struct
+ *          interpretation are in little endian representation.  This is
+ *          different to many other UUID implementation, and requires
+ *          conversion if you need to achieve consistent results.
+ */
+typedef union RTUUID
+{
+    /** 8-bit view. */
+    uint8_t     au8[16];
+    /** 16-bit view. */
+    uint16_t    au16[8];
+    /** 32-bit view. */
+    uint32_t    au32[4];
+    /** 64-bit view. */
+    uint64_t    au64[2];
+    /** The way the UUID is declared by the DCE specification. */
+    struct
+    {
+        uint32_t    u32TimeLow;
+        uint16_t    u16TimeMid;
+        uint16_t    u16TimeHiAndVersion;
+        uint8_t     u8ClockSeqHiAndReserved;
+        uint8_t     u8ClockSeqLow;
+        uint8_t     au8Node[6];
+    } Gen;
+} RTUUID;
+/** Pointer to UUID data. */
+typedef RTUUID *PRTUUID;
+/** Pointer to readonly UUID data. */
+typedef const RTUUID *PCRTUUID;
+
+/** Initializes a RTUUID structure with all zeros (RTUuidIsNull() true). */
+#define RTUUID_INITIALIZE_NULL  { { 0, 0, 0, 0,  0, 0, 0, 0,  0, 0, 0, 0,  0, 0, 0, 0 } }
+
+/** UUID string maximum length. */
+#define RTUUID_STR_LENGTH       37
+
+
+/** Compression handle. */
+typedef struct RTZIPCOMP   *PRTZIPCOMP;
+/** Decompressor handle. */
+typedef struct RTZIPDECOMP *PRTZIPDECOMP;
+
+
+/**
+ * Unicode Code Point.
+ */
+typedef uint32_t            RTUNICP;
+/** Pointer to an Unicode Code Point. */
+typedef RTUNICP            *PRTUNICP;
+/** Pointer to an Unicode Code Point. */
+typedef const RTUNICP      *PCRTUNICP;
+/** Max value a RTUNICP type can hold. */
+#define RTUNICP_MAX         ( ~(RTUNICP)0 )
+/** Invalid code point.
+ * This is returned when encountered invalid encodings or invalid
+ * unicode code points. */
+#define RTUNICP_INVALID     ( UINT32_C(0xfffffffe) )
+
+
+/**
+ * UTF-16 character.
+ * @remark  wchar_t is not usable since it's compiler defined.
+ * @remark  When we use the term character we're not talking about unicode code point, but
+ *          the basic unit of the string encoding. Thus cwc - count of wide chars - means
+ *          count of RTUTF16; cuc - count of unicode chars - means count of RTUNICP;
+ *          and cch means count of the typedef 'char', which is assumed to be an octet.
+ */
+typedef uint16_t        RTUTF16;
+/** Pointer to a UTF-16 character. */
+typedef RTUTF16        *PRTUTF16;
+/** Pointer to a const UTF-16 character. */
+typedef const RTUTF16  *PCRTUTF16;
+
+
+/**
+ * String tuple to go with the RT_STR_TUPLE macro.
+ */
+typedef struct RTSTRTUPLE
+{
+    /** The string. */
+    const char *psz;
+    /** The string length. */
+    size_t      cch;
+} RTSTRTUPLE;
+/** Pointer to a string tuple. */
+typedef RTSTRTUPLE *PRTSTRTUPLE;
+/** Pointer to a const string tuple. */
+typedef RTSTRTUPLE const *PCRTSTRTUPLE;
+
+/**
+ * Wait for ever if we have to.
+ */
+#define RT_INDEFINITE_WAIT      (~0U)
+
+
+/**
+ * Generic process callback.
+ *
+ * @returns VBox status code. Failure will cancel the operation.
+ * @param   uPercentage     The percentage of the operation which has been completed.
+ * @param   pvUser          The user specified argument.
+ */
+typedef DECLCALLBACK(int) FNRTPROGRESS(unsigned uPrecentage, void *pvUser);
+/** Pointer to a generic progress callback function, FNRTPROCESS(). */
+typedef FNRTPROGRESS *PFNRTPROGRESS;
+
+/**
+ * Generic vprintf-like callback function for dumpers.
+ *
+ * @param   pvUser          User argument.
+ * @param   pszFormat       The format string.
+ * @param   va              Arguments for the format string.
+ */
+typedef DECLCALLBACK(void) FNRTDUMPPRINTFV(void *pvUser, const char *pszFormat, va_list va) RT_IPRT_FORMAT_ATTR(2, 0);
+/** Pointer to a generic printf-like function for dumping. */
+typedef FNRTDUMPPRINTFV *PFNRTDUMPPRINTFV;
+
+
+/**
+ * A point in a two dimentional coordinate system.
+ */
+typedef struct RTPOINT
+{
+    /** X coordinate. */
+    int32_t     x;
+    /** Y coordinate. */
+    int32_t     y;
+} RTPOINT;
+/** Pointer to a point. */
+typedef RTPOINT *PRTPOINT;
+/** Pointer to a const point. */
+typedef const RTPOINT *PCRTPOINT;
+
+
+/**
+ * Rectangle data type, double point.
+ */
+typedef struct RTRECT
+{
+    /** left X coordinate. */
+    int32_t     xLeft;
+    /** top Y coordinate. */
+    int32_t     yTop;
+    /** right X coordinate. (exclusive) */
+    int32_t     xRight;
+    /** bottom Y coordinate. (exclusive) */
+    int32_t     yBottom;
+} RTRECT;
+/** Pointer to a double point rectangle. */
+typedef RTRECT *PRTRECT;
+/** Pointer to a const double point rectangle. */
+typedef const RTRECT *PCRTRECT;
+
+
+/**
+ * Rectangle data type, point + size.
+ */
+typedef struct RTRECT2
+{
+    /** X coordinate.
+     * Unless stated otherwise, this is the top left corner. */
+    int32_t     x;
+    /** Y coordinate.
+     * Unless stated otherwise, this is the top left corner.  */
+    int32_t     y;
+    /** The width.
+     * Unless stated otherwise, this is to the right of (x,y) and will not
+     * be a negative number. */
+    int32_t     cx;
+    /** The height.
+     * Unless stated otherwise, this is down from (x,y) and will not be a
+     * negative number. */
+    int32_t     cy;
+} RTRECT2;
+/** Pointer to a point + size rectangle. */
+typedef RTRECT2 *PRTRECT2;
+/** Pointer to a const point + size rectangle. */
+typedef const RTRECT2 *PCRTRECT2;
+
+
+/**
+ * The size of a rectangle.
+ */
+typedef struct RTRECTSIZE
+{
+    /** The width (along the x-axis). */
+    uint32_t    cx;
+    /** The height (along the y-axis). */
+    uint32_t    cy;
+} RTRECTSIZE;
+/** Pointer to a rectangle size. */
+typedef RTRECTSIZE *PRTRECTSIZE;
+/** Pointer to a const rectangle size. */
+typedef const RTRECTSIZE *PCRTRECTSIZE;
+
+
+/**
+ * Ethernet MAC address.
+ *
+ * The first 24 bits make up the Organisationally Unique Identifier (OUI),
+ * where the first bit (little endian) indicates multicast (set) / unicast,
+ * and the second bit indicates locally (set) / global administered. If all
+ * bits are set, it's a broadcast.
+ */
+typedef union RTMAC
+{
+    /** @todo add a bitfield view of this stuff. */
+    /** 8-bit view. */
+    uint8_t     au8[6];
+    /** 16-bit view. */
+    uint16_t    au16[3];
+} RTMAC;
+/** Pointer to a MAC address. */
+typedef RTMAC *PRTMAC;
+/** Pointer to a readonly MAC address. */
+typedef const RTMAC *PCRTMAC;
+
+
+/** Pointer to a lock validator record.
+ * The structure definition is found in iprt/lockvalidator.h.  */
+typedef struct RTLOCKVALRECEXCL        *PRTLOCKVALRECEXCL;
+/** Pointer to a record of one ownership share.
+ * The structure definition is found in iprt/lockvalidator.h.  */
+typedef struct RTLOCKVALRECSHRD        *PRTLOCKVALRECSHRD;
+/** Pointer to a lock validator source position.
+ * The structure definition is found in iprt/lockvalidator.h.  */
+typedef struct RTLOCKVALSRCPOS         *PRTLOCKVALSRCPOS;
+/** Pointer to a const lock validator source position.
+ * The structure definition is found in iprt/lockvalidator.h.  */
+typedef struct RTLOCKVALSRCPOS const   *PCRTLOCKVALSRCPOS;
+
+/** @name   Special sub-class values.
+ * The range 16..UINT32_MAX is available to the user, the range 0..15 is
+ * reserved for the lock validator.  In the user range the locks can only be
+ * taking in ascending order.
+ * @{ */
+/** Invalid value.  */
+#define RTLOCKVAL_SUB_CLASS_INVALID     UINT32_C(0)
+/** Not allowed to be taken with any other locks in the same class.
+  * This is the recommended value.  */
+#define RTLOCKVAL_SUB_CLASS_NONE        UINT32_C(1)
+/** Any order is allowed within the class. */
+#define RTLOCKVAL_SUB_CLASS_ANY         UINT32_C(2)
+/** The first user value. */
+#define RTLOCKVAL_SUB_CLASS_USER        UINT32_C(16)
+/** @} */
+
+
+/**
+ * Digest types.
+ */
+typedef enum RTDIGESTTYPE
+{
+    /** Invalid digest value.  */
+    RTDIGESTTYPE_INVALID = 0,
+    /** Unknown digest type. */
+    RTDIGESTTYPE_UNKNOWN,
+    /** CRC32 checksum. */
+    RTDIGESTTYPE_CRC32,
+    /** CRC64 checksum. */
+    RTDIGESTTYPE_CRC64,
+    /** MD2 checksum (unsafe!). */
+    RTDIGESTTYPE_MD2,
+    /** MD4 checksum (unsafe!!). */
+    RTDIGESTTYPE_MD4,
+    /** MD5 checksum (unsafe!). */
+    RTDIGESTTYPE_MD5,
+    /** SHA-1 checksum (unsafe!). */
+    RTDIGESTTYPE_SHA1,
+    /** SHA-224 checksum. */
+    RTDIGESTTYPE_SHA224,
+    /** SHA-256 checksum. */
+    RTDIGESTTYPE_SHA256,
+    /** SHA-384 checksum. */
+    RTDIGESTTYPE_SHA384,
+    /** SHA-512 checksum. */
+    RTDIGESTTYPE_SHA512,
+    /** SHA-512/224 checksum. */
+    RTDIGESTTYPE_SHA512T224,
+    /** SHA-512/256 checksum. */
+    RTDIGESTTYPE_SHA512T256,
+    /** End of valid types. */
+    RTDIGESTTYPE_END,
+    /** Usual 32-bit type blowup. */
+    RTDIGESTTYPE_32BIT_HACK = 0x7fffffff
+} RTDIGESTTYPE;
+
+/**
+ * Process exit codes.
+ */
+typedef enum RTEXITCODE
+{
+    /** Success. */
+    RTEXITCODE_SUCCESS = 0,
+    /** General failure. */
+    RTEXITCODE_FAILURE = 1,
+    /** Invalid arguments.  */
+    RTEXITCODE_SYNTAX = 2,
+    /** Initialization failure (usually IPRT, but could be used for other
+     *  components as well). */
+    RTEXITCODE_INIT = 3,
+    /** Test skipped. */
+    RTEXITCODE_SKIPPED = 4,
+    /** The end of valid exit codes. */
+    RTEXITCODE_END,
+    /** The usual 32-bit type hack. */
+    RTEXITCODE_32BIT_HACK = 0x7fffffff
+} RTEXITCODE;
+
+/**
+ * Range descriptor.
+ */
+typedef struct RTRANGE
+{
+    /** Start offset. */
+    uint64_t    offStart;
+    /** Range size. */
+    size_t      cbRange;
+} RTRANGE;
+/** Pointer to a range descriptor. */
+typedef RTRANGE *PRTRANGE;
+/** Pointer to a readonly range descriptor. */
+typedef const RTRANGE *PCRTRANGE;
+
+
+/**
+ * Generic pointer union.
+ */
+typedef union RTPTRUNION
+{
+    /** Pointer into the void. */
+    void                   *pv;
+    /** As a signed integer. */
+    intptr_t                i;
+    /** As an unsigned integer. */
+    intptr_t                u;
+    /** Pointer to char value. */
+    char                   *pch;
+    /** Pointer to char value. */
+    unsigned char          *puch;
+    /** Pointer to a int value. */
+    int                    *pi;
+    /** Pointer to a unsigned int value. */
+    unsigned int           *pu;
+    /** Pointer to a long value. */
+    long                   *pl;
+    /** Pointer to a long value. */
+    unsigned long          *pul;
+    /** Pointer to a 8-bit unsigned value. */
+    uint8_t                *pu8;
+    /** Pointer to a 16-bit unsigned value. */
+    uint16_t               *pu16;
+    /** Pointer to a 32-bit unsigned value. */
+    uint32_t               *pu32;
+    /** Pointer to a 64-bit unsigned value. */
+    uint64_t               *pu64;
+    /** Pointer to a UTF-16 character. */
+    PRTUTF16                pwc;
+    /** Pointer to a UUID character. */
+    PRTUUID                 pUuid;
+} RTPTRUNION;
+/** Pointer to a pointer union. */
+typedef RTPTRUNION *PRTPTRUNION;
+
+/**
+ * Generic const pointer union.
+ */
+typedef union RTCPTRUNION
+{
+    /** Pointer into the void. */
+    void const             *pv;
+    /** As a signed integer. */
+    intptr_t                i;
+    /** As an unsigned integer. */
+    intptr_t                u;
+    /** Pointer to char value. */
+    char const             *pch;
+    /** Pointer to char value. */
+    unsigned char const    *puch;
+    /** Pointer to a int value. */
+    int const              *pi;
+    /** Pointer to a unsigned int value. */
+    unsigned int const     *pu;
+    /** Pointer to a long value. */
+    long const             *pl;
+    /** Pointer to a long value. */
+    unsigned long const    *pul;
+    /** Pointer to a 8-bit unsigned value. */
+    uint8_t const          *pu8;
+    /** Pointer to a 16-bit unsigned value. */
+    uint16_t const         *pu16;
+    /** Pointer to a 32-bit unsigned value. */
+    uint32_t const         *pu32;
+    /** Pointer to a 64-bit unsigned value. */
+    uint64_t const         *pu64;
+    /** Pointer to a UTF-16 character. */
+    PCRTUTF16               pwc;
+    /** Pointer to a UUID character. */
+    PCRTUUID                pUuid;
+} RTCPTRUNION;
+/** Pointer to a const pointer union. */
+typedef RTCPTRUNION *PRTCPTRUNION;
+
+/**
+ * Generic volatile pointer union.
+ */
+typedef union RTVPTRUNION
+{
+    /** Pointer into the void. */
+    void volatile          *pv;
+    /** As a signed integer. */
+    intptr_t                i;
+    /** As an unsigned integer. */
+    intptr_t                u;
+    /** Pointer to char value. */
+    char volatile          *pch;
+    /** Pointer to char value. */
+    unsigned char volatile *puch;
+    /** Pointer to a int value. */
+    int volatile           *pi;
+    /** Pointer to a unsigned int value. */
+    unsigned int volatile  *pu;
+    /** Pointer to a long value. */
+    long volatile          *pl;
+    /** Pointer to a long value. */
+    unsigned long volatile *pul;
+    /** Pointer to a 8-bit unsigned value. */
+    uint8_t volatile       *pu8;
+    /** Pointer to a 16-bit unsigned value. */
+    uint16_t volatile      *pu16;
+    /** Pointer to a 32-bit unsigned value. */
+    uint32_t volatile      *pu32;
+    /** Pointer to a 64-bit unsigned value. */
+    uint64_t volatile      *pu64;
+    /** Pointer to a UTF-16 character. */
+    RTUTF16 volatile       *pwc;
+    /** Pointer to a UUID character. */
+    RTUUID volatile        *pUuid;
+} RTVPTRUNION;
+/** Pointer to a const pointer union. */
+typedef RTVPTRUNION *PRTVPTRUNION;
+
+/**
+ * Generic const volatile pointer union.
+ */
+typedef union RTCVPTRUNION
+{
+    /** Pointer into the void. */
+    void const volatile            *pv;
+    /** As a signed integer. */
+    intptr_t                        i;
+    /** As an unsigned integer. */
+    intptr_t                        u;
+    /** Pointer to char value. */
+    char const volatile            *pch;
+    /** Pointer to char value. */
+    unsigned char const volatile   *puch;
+    /** Pointer to a int value. */
+    int const volatile             *pi;
+    /** Pointer to a unsigned int value. */
+    unsigned int const volatile    *pu;
+    /** Pointer to a long value. */
+    long const volatile            *pl;
+    /** Pointer to a long value. */
+    unsigned long const volatile   *pul;
+    /** Pointer to a 8-bit unsigned value. */
+    uint8_t const volatile         *pu8;
+    /** Pointer to a 16-bit unsigned value. */
+    uint16_t const volatile        *pu16;
+    /** Pointer to a 32-bit unsigned value. */
+    uint32_t const volatile        *pu32;
+    /** Pointer to a 64-bit unsigned value. */
+    uint64_t const volatile        *pu64;
+    /** Pointer to a UTF-16 character. */
+    RTUTF16 const volatile         *pwc;
+    /** Pointer to a UUID character. */
+    RTUUID const volatile          *pUuid;
+} RTCVPTRUNION;
+/** Pointer to a const pointer union. */
+typedef RTCVPTRUNION *PRTCVPTRUNION;
+
+
+
+#ifdef __cplusplus
+/**
+ * Strict type validation helper class.
+ *
+ * See RTErrStrictType and RT_SUCCESS_NP.
+ */
+class RTErrStrictType2
+{
+protected:
+    /** The status code.  */
+    int32_t m_rc;
+
+public:
+    /**
+     * Constructor.
+     * @param   rc      IPRT style status code.
+     */
+    RTErrStrictType2(int32_t rc) : m_rc(rc)
+    {
+    }
+
+    /**
+     * Get the status code.
+     * @returns IPRT style status code.
+     */
+    int32_t getValue() const
+    {
+        return m_rc;
+    }
+};
+#endif /* __cplusplus */
+/** @} */
+
+#endif
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/include/iprt/uni.h
@@ -0,0 +1,478 @@
+/** @file
+ * IPRT - Unicode Code Points.
+ */
+
+/*
+ * Copyright (C) 2006-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+#ifndef ___iprt_uni_h
+#define ___iprt_uni_h
+
+/** @defgroup grp_rt_uni    RTUniCp - Unicode Code Points
+ * @ingroup grp_rt
+ * @{
+ */
+
+/** @def RTUNI_USE_WCTYPE
+ * Define RTUNI_USE_WCTYPE to not use the IPRT unicode data but the
+ * data which the C runtime library provides. */
+#ifdef DOXYGEN_RUNNING
+# define RTUNI_USE_WCTYPE
+#endif
+
+#include <iprt/types.h>
+#ifdef RTUNI_USE_WCTYPE
+# include <wctype.h>
+#endif
+
+RT_C_DECLS_BEGIN
+
+
+#ifndef RTUNI_USE_WCTYPE
+
+/**
+ * A unicode flags range.
+ * @internal
+ */
+typedef struct RTUNIFLAGSRANGE
+{
+    /** The first code point of the range. */
+    RTUNICP         BeginCP;
+    /** The last + 1 code point of the range. */
+    RTUNICP         EndCP;
+    /** Pointer to the array of case folded code points. */
+    const uint8_t  *pafFlags;
+} RTUNIFLAGSRANGE;
+/** Pointer to a flags range.
+ * @internal */
+typedef RTUNIFLAGSRANGE *PRTUNIFLAGSRANGE;
+/** Pointer to a const flags range.
+ * @internal */
+typedef const RTUNIFLAGSRANGE *PCRTUNIFLAGSRANGE;
+
+/**
+ * A unicode case folded range.
+ * @internal
+ */
+typedef struct RTUNICASERANGE
+{
+    /** The first code point of the range. */
+    RTUNICP         BeginCP;
+    /** The last + 1 code point of the range. */
+    RTUNICP         EndCP;
+    /** Pointer to the array of case folded code points. */
+    PCRTUNICP       paFoldedCPs;
+} RTUNICASERANGE;
+/** Pointer to a case folded range.
+ * @internal */
+typedef RTUNICASERANGE *PRTUNICASERANGE;
+/** Pointer to a const case folded range.
+ * @internal */
+typedef const RTUNICASERANGE *PCRTUNICASERANGE;
+
+/** @name Unicode Code Point Flags.
+ * @internal
+ * @{ */
+#define RTUNI_UPPER         RT_BIT(0)
+#define RTUNI_LOWER         RT_BIT(1)
+#define RTUNI_ALPHA         RT_BIT(2)
+#define RTUNI_XDIGIT        RT_BIT(3)
+#define RTUNI_DDIGIT        RT_BIT(4)
+#define RTUNI_WSPACE        RT_BIT(5)
+/*#define RTUNI_BSPACE RT_BIT(6) - later */
+/** When set, the codepoint requires further checking wrt NFC and NFD
+ * normalization. I.e. set when either of QC_NFD and QC_NFC are not Y. */
+#define RTUNI_QC_NFX        RT_BIT(7)
+/** @} */
+
+
+/**
+ * Array of flags ranges.
+ * @internal
+ */
+extern RTDATADECL(const RTUNIFLAGSRANGE) g_aRTUniFlagsRanges[];
+
+/**
+ * Gets the flags for a unicode code point.
+ *
+ * @returns The flag mask. (RTUNI_*)
+ * @param   CodePoint       The unicode code point.
+ * @internal
+ */
+DECLINLINE(RTUNICP) rtUniCpFlags(RTUNICP CodePoint)
+{
+    PCRTUNIFLAGSRANGE pCur = &g_aRTUniFlagsRanges[0];
+    do
+    {
+        if (pCur->EndCP > CodePoint)
+        {
+            if (pCur->BeginCP <= CodePoint)
+                return pCur->pafFlags[CodePoint - pCur->BeginCP];
+            break;
+        }
+        pCur++;
+    } while (pCur->EndCP != RTUNICP_MAX);
+    return 0;
+}
+
+
+/**
+ * Checks if a unicode code point is upper case.
+ *
+ * @returns true if it is.
+ * @returns false if it isn't.
+ * @param   CodePoint       The code point.
+ */
+DECLINLINE(bool) RTUniCpIsUpper(RTUNICP CodePoint)
+{
+    return (rtUniCpFlags(CodePoint) & RTUNI_UPPER) != 0;
+}
+
+
+/**
+ * Checks if a unicode code point is lower case.
+ *
+ * @returns true if it is.
+ * @returns false if it isn't.
+ * @param   CodePoint       The code point.
+ */
+DECLINLINE(bool) RTUniCpIsLower(RTUNICP CodePoint)
+{
+    return (rtUniCpFlags(CodePoint) & RTUNI_LOWER) != 0;
+}
+
+
+/**
+ * Checks if a unicode code point is case foldable.
+ *
+ * @returns true if it is.
+ * @returns false if it isn't.
+ * @param   CodePoint       The code point.
+ */
+DECLINLINE(bool) RTUniCpIsFoldable(RTUNICP CodePoint)
+{
+    /* Right enough. */
+    return (rtUniCpFlags(CodePoint) & (RTUNI_LOWER | RTUNI_UPPER)) != 0;
+}
+
+
+/**
+ * Checks if a unicode code point is alphabetic.
+ *
+ * @returns true if it is.
+ * @returns false if it isn't.
+ * @param   CodePoint       The code point.
+ */
+DECLINLINE(bool) RTUniCpIsAlphabetic(RTUNICP CodePoint)
+{
+    return (rtUniCpFlags(CodePoint) & RTUNI_ALPHA) != 0;
+}
+
+
+/**
+ * Checks if a unicode code point is a decimal digit.
+ *
+ * @returns true if it is.
+ * @returns false if it isn't.
+ * @param   CodePoint       The code point.
+ */
+DECLINLINE(bool) RTUniCpIsDecDigit(RTUNICP CodePoint)
+{
+    return (rtUniCpFlags(CodePoint) & RTUNI_DDIGIT) != 0;
+}
+
+
+/**
+ * Checks if a unicode code point is a hexadecimal digit.
+ *
+ * @returns true if it is.
+ * @returns false if it isn't.
+ * @param   CodePoint       The code point.
+ */
+DECLINLINE(bool) RTUniCpIsHexDigit(RTUNICP CodePoint)
+{
+    return (rtUniCpFlags(CodePoint) & RTUNI_XDIGIT) != 0;
+}
+
+
+/**
+ * Checks if a unicode code point is white space.
+ *
+ * @returns true if it is.
+ * @returns false if it isn't.
+ * @param   CodePoint       The code point.
+ */
+DECLINLINE(bool) RTUniCpIsSpace(RTUNICP CodePoint)
+{
+    return (rtUniCpFlags(CodePoint) & RTUNI_WSPACE) != 0;
+}
+
+
+
+/**
+ * Array of uppercase ranges.
+ * @internal
+ */
+extern RTDATADECL(const RTUNICASERANGE) g_aRTUniUpperRanges[];
+
+/**
+ * Array of lowercase ranges.
+ * @internal
+ */
+extern RTDATADECL(const RTUNICASERANGE) g_aRTUniLowerRanges[];
+
+
+/**
+ * Folds a unicode code point using the specified range array.
+ *
+ * @returns FOlded code point.
+ * @param   CodePoint       The unicode code point to fold.
+ * @param   pCur            The case folding range to use.
+ */
+DECLINLINE(RTUNICP) rtUniCpFold(RTUNICP CodePoint, PCRTUNICASERANGE pCur)
+{
+    do
+    {
+        if (pCur->EndCP > CodePoint)
+        {
+            if (pCur->BeginCP <= CodePoint)
+                CodePoint = pCur->paFoldedCPs[CodePoint - pCur->BeginCP];
+            break;
+        }
+        pCur++;
+    } while (pCur->EndCP != RTUNICP_MAX);
+    return CodePoint;
+}
+
+
+/**
+ * Folds a unicode code point to upper case.
+ *
+ * @returns Folded code point.
+ * @param   CodePoint       The unicode code point to fold.
+ */
+DECLINLINE(RTUNICP) RTUniCpToUpper(RTUNICP CodePoint)
+{
+    return rtUniCpFold(CodePoint, &g_aRTUniUpperRanges[0]);
+}
+
+
+/**
+ * Folds a unicode code point to lower case.
+ *
+ * @returns Folded code point.
+ * @param   CodePoint       The unicode code point to fold.
+ */
+DECLINLINE(RTUNICP) RTUniCpToLower(RTUNICP CodePoint)
+{
+    return rtUniCpFold(CodePoint, &g_aRTUniLowerRanges[0]);
+}
+
+
+#else /* RTUNI_USE_WCTYPE */
+
+
+/**
+ * Checks if a unicode code point is upper case.
+ *
+ * @returns true if it is.
+ * @returns false if it isn't.
+ * @param   CodePoint       The code point.
+ */
+DECLINLINE(bool) RTUniCpIsUpper(RTUNICP CodePoint)
+{
+    return !!iswupper(CodePoint);
+}
+
+
+/**
+ * Checks if a unicode code point is lower case.
+ *
+ * @returns true if it is.
+ * @returns false if it isn't.
+ * @param   CodePoint       The code point.
+ */
+DECLINLINE(bool) RTUniCpIsLower(RTUNICP CodePoint)
+{
+    return !!iswlower(CodePoint);
+}
+
+
+/**
+ * Checks if a unicode code point is case foldable.
+ *
+ * @returns true if it is.
+ * @returns false if it isn't.
+ * @param   CodePoint       The code point.
+ */
+DECLINLINE(bool) RTUniCpIsFoldable(RTUNICP CodePoint)
+{
+    /* Right enough. */
+    return iswupper(CodePoint) || iswlower(CodePoint);
+}
+
+
+/**
+ * Checks if a unicode code point is alphabetic.
+ *
+ * @returns true if it is.
+ * @returns false if it isn't.
+ * @param   CodePoint       The code point.
+ */
+DECLINLINE(bool) RTUniCpIsAlphabetic(RTUNICP CodePoint)
+{
+    return !!iswalpha(CodePoint);
+}
+
+
+/**
+ * Checks if a unicode code point is a decimal digit.
+ *
+ * @returns true if it is.
+ * @returns false if it isn't.
+ * @param   CodePoint       The code point.
+ */
+DECLINLINE(bool) RTUniCpIsDecDigit(RTUNICP CodePoint)
+{
+    return !!iswdigit(CodePoint);
+}
+
+
+/**
+ * Checks if a unicode code point is a hexadecimal digit.
+ *
+ * @returns true if it is.
+ * @returns false if it isn't.
+ * @param   CodePoint       The code point.
+ */
+DECLINLINE(bool) RTUniCpIsHexDigit(RTUNICP CodePoint)
+{
+    return !!iswxdigit(CodePoint);
+}
+
+
+/**
+ * Checks if a unicode code point is white space.
+ *
+ * @returns true if it is.
+ * @returns false if it isn't.
+ * @param   CodePoint       The code point.
+ */
+DECLINLINE(bool) RTUniCpIsSpace(RTUNICP CodePoint)
+{
+    return !!iswspace(CodePoint);
+}
+
+
+/**
+ * Folds a unicode code point to upper case.
+ *
+ * @returns Folded code point.
+ * @param   CodePoint       The unicode code point to fold.
+ */
+DECLINLINE(RTUNICP) RTUniCpToUpper(RTUNICP CodePoint)
+{
+    return towupper(CodePoint);
+}
+
+
+/**
+ * Folds a unicode code point to lower case.
+ *
+ * @returns Folded code point.
+ * @param   CodePoint       The unicode code point to fold.
+ */
+DECLINLINE(RTUNICP) RTUniCpToLower(RTUNICP CodePoint)
+{
+    return towlower(CodePoint);
+}
+
+
+#endif /* RTUNI_USE_WCTYPE */
+
+
+/**
+ * Frees a unicode string.
+ *
+ * @param   pusz        The string to free.
+ */
+RTDECL(void) RTUniFree(PRTUNICP pusz);
+
+
+/**
+ * Checks if a code point valid.
+ *
+ * Any code point (defined or not) within the 17 unicode planes (0 thru 16),
+ * except surrogates will be considered valid code points by this function.
+ *
+ * @returns true if in range, false if not.
+ * @param   CodePoint       The unicode code point to validate.
+ */
+DECLINLINE(bool) RTUniCpIsValid(RTUNICP CodePoint)
+{
+    return CodePoint <= 0x00d7ff
+        || (   CodePoint <= 0x10ffff
+            && CodePoint >= 0x00e000);
+}
+
+
+/**
+ * Checks if the given code point is in the BMP range.
+ *
+ * Surrogates are not considered in the BMP range by this function.
+ *
+ * @returns true if in BMP, false if not.
+ * @param   CodePoint       The unicode code point to consider.
+ */
+DECLINLINE(bool) RTUniCpIsBMP(RTUNICP CodePoint)
+{
+    return CodePoint <= 0xd7ff
+        || (   CodePoint <= 0xffff
+            && CodePoint >= 0xe000);
+}
+
+
+/**
+ * Folds a unicode code point to lower case.
+ *
+ * @returns Folded code point.
+ * @param   CodePoint       The unicode code point to fold.
+ */
+DECLINLINE(size_t) RTUniCpCalcUtf8Len(RTUNICP CodePoint)
+{
+    if (CodePoint < 0x80)
+        return 1;
+    return 2
+        + (CodePoint >= 0x00000800)
+        + (CodePoint >= 0x00010000)
+        + (CodePoint >= 0x00200000)
+        + (CodePoint >= 0x04000000)
+        + (CodePoint >= 0x80000000) /* illegal */;
+}
+
+
+
+RT_C_DECLS_END
+/** @} */
+
+
+#endif
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/include/iprt/utf16.h
@@ -0,0 +1,983 @@
+/** @file
+ * IPRT - String Manipulation, UTF-16 encoding.
+ */
+
+/*
+ * Copyright (C) 2006-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+#ifndef ___iprt_utf16_h
+#define ___iprt_utf16_h
+
+#include <iprt/string.h>
+
+RT_C_DECLS_BEGIN
+
+
+/** @defgroup rt_str_utf16      UTF-16 String Manipulation
+ * @ingroup grp_rt_str
+ * @{
+ */
+
+/**
+ * Allocates memory for UTF-16 string storage (default tag).
+ *
+ * You should normally not use this function, except if there is some very
+ * custom string handling you need doing that isn't covered by any of the other
+ * APIs.
+ *
+ * @returns Pointer to the allocated UTF-16 string.  The first wide char is
+ *          always set to the string terminator char, the contents of the
+ *          remainder of the memory is undefined.  The string must be freed by
+ *          calling RTUtf16Free.
+ *
+ *          NULL is returned if the allocation failed.  Please translate this to
+ *          VERR_NO_UTF16_MEMORY and not VERR_NO_MEMORY.  Also consider
+ *          RTUtf16AllocEx if an IPRT status code is required.
+ *
+ * @param   cb                  How many bytes to allocate, will be rounded up
+ *                              to a multiple of two. If this is zero, we will
+ *                              allocate a terminator wide char anyway.
+ */
+#define RTUtf16Alloc(cb)                    RTUtf16AllocTag((cb), RTSTR_TAG)
+
+/**
+ * Allocates memory for UTF-16 string storage (custom tag).
+ *
+ * You should normally not use this function, except if there is some very
+ * custom string handling you need doing that isn't covered by any of the other
+ * APIs.
+ *
+ * @returns Pointer to the allocated UTF-16 string.  The first wide char is
+ *          always set to the string terminator char, the contents of the
+ *          remainder of the memory is undefined.  The string must be freed by
+ *          calling RTUtf16Free.
+ *
+ *          NULL is returned if the allocation failed.  Please translate this to
+ *          VERR_NO_UTF16_MEMORY and not VERR_NO_MEMORY.  Also consider
+ *          RTUtf16AllocExTag if an IPRT status code is required.
+ *
+ * @param   cb                  How many bytes to allocate, will be rounded up
+ *                              to a multiple of two. If this is zero, we will
+ *                              allocate a terminator wide char anyway.
+ * @param   pszTag              Allocation tag used for statistics and such.
+ */
+RTDECL(PRTUTF16) RTUtf16AllocTag(size_t cb, const char *pszTag);
+
+/**
+ * Reallocates the specified UTF-16 string (default tag).
+ *
+ * You should normally not use this function, except if there is some very
+ * custom string handling you need doing that isn't covered by any of the other
+ * APIs.
+ *
+ * @returns VINF_SUCCESS.
+ * @retval  VERR_NO_UTF16_MEMORY if we failed to reallocate the string, @a
+ *          *ppwsz remains unchanged.
+ *
+ * @param   ppwsz               Pointer to the string variable containing the
+ *                              input and output string.
+ *
+ *                              When not freeing the string, the result will
+ *                              always have the last RTUTF16 set to the
+ *                              terminator character so that when used for
+ *                              string truncation the result will be a valid
+ *                              C-style string (your job to keep it a valid
+ *                              UTF-16 string).
+ *
+ *                              When the input string is NULL and we're supposed
+ *                              to reallocate, the returned string will also
+ *                              have the first RTUTF16 set to the terminator
+ *                              char so it will be a valid C-style string.
+ *
+ * @param   cbNew               When @a cbNew is zero, we'll behave like
+ *                              RTUtf16Free and @a *ppwsz will be set to NULL.
+ *
+ *                              When not zero, this will be rounded up to a
+ *                              multiple of two, and used as the new size of the
+ *                              memory backing the string, i.e. it includes the
+ *                              terminator (RTUTF16) char.
+ */
+#define RTUtf16Realloc(ppwsz, cb)       RTUtf16ReallocTag((ppwsz), (cb), RTSTR_TAG)
+
+/**
+ * Reallocates the specified UTF-16 string (custom tag).
+ *
+ * You should normally not use this function, except if there is some very
+ * custom string handling you need doing that isn't covered by any of the other
+ * APIs.
+ *
+ * @returns VINF_SUCCESS.
+ * @retval  VERR_NO_UTF16_MEMORY if we failed to reallocate the string, @a
+ *          *ppwsz remains unchanged.
+ *
+ * @param   ppwsz               Pointer to the string variable containing the
+ *                              input and output string.
+ *
+ *                              When not freeing the string, the result will
+ *                              always have the last RTUTF16 set to the
+ *                              terminator character so that when used for
+ *                              string truncation the result will be a valid
+ *                              C-style string (your job to keep it a valid
+ *                              UTF-16 string).
+ *
+ *                              When the input string is NULL and we're supposed
+ *                              to reallocate, the returned string will also
+ *                              have the first RTUTF16 set to the terminator
+ *                              char so it will be a valid C-style string.
+ *
+ * @param   cbNew               When @a cbNew is zero, we'll behave like
+ *                              RTUtf16Free and @a *ppwsz will be set to NULL.
+ *
+ *                              When not zero, this will be rounded up to a
+ *                              multiple of two, and used as the new size of the
+ *                              memory backing the string, i.e. it includes the
+ *                              terminator (RTUTF16) char.
+ * @param   pszTag              Allocation tag used for statistics and such.
+ */
+RTDECL(int) RTUtf16ReallocTag(PRTUTF16 *ppwsz, size_t cbNew, const char *pszTag);
+
+/**
+ * Free a UTF-16 string allocated by RTStrToUtf16(), RTStrToUtf16Ex(),
+ * RTLatin1ToUtf16(), RTLatin1ToUtf16Ex(), RTUtf16Dup() or RTUtf16DupEx().
+ *
+ * @returns iprt status code.
+ * @param   pwszString      The UTF-16 string to free. NULL is accepted.
+ */
+RTDECL(void)  RTUtf16Free(PRTUTF16 pwszString);
+
+/**
+ * Allocates a new copy of the specified UTF-16 string (default tag).
+ *
+ * @returns Pointer to the allocated string copy. Use RTUtf16Free() to free it.
+ * @returns NULL when out of memory.
+ * @param   pwszString      UTF-16 string to duplicate.
+ * @remark  This function will not make any attempt to validate the encoding.
+ */
+#define RTUtf16Dup(pwszString)          RTUtf16DupTag((pwszString), RTSTR_TAG)
+
+/**
+ * Allocates a new copy of the specified UTF-16 string (custom tag).
+ *
+ * @returns Pointer to the allocated string copy. Use RTUtf16Free() to free it.
+ * @returns NULL when out of memory.
+ * @param   pwszString      UTF-16 string to duplicate.
+ * @param   pszTag          Allocation tag used for statistics and such.
+ * @remark  This function will not make any attempt to validate the encoding.
+ */
+RTDECL(PRTUTF16) RTUtf16DupTag(PCRTUTF16 pwszString, const char *pszTag);
+
+/**
+ * Allocates a new copy of the specified UTF-16 string (default tag).
+ *
+ * @returns iprt status code.
+ * @param   ppwszString     Receives pointer of the allocated UTF-16 string.
+ *                          The returned pointer must be freed using RTUtf16Free().
+ * @param   pwszString      UTF-16 string to duplicate.
+ * @param   cwcExtra        Number of extra RTUTF16 items to allocate.
+ * @remark  This function will not make any attempt to validate the encoding.
+ */
+#define RTUtf16DupEx(ppwszString, pwszString, cwcExtra) \
+    RTUtf16DupExTag((ppwszString), (pwszString), (cwcExtra), RTSTR_TAG)
+
+/**
+ * Allocates a new copy of the specified UTF-16 string (custom tag).
+ *
+ * @returns iprt status code.
+ * @param   ppwszString     Receives pointer of the allocated UTF-16 string.
+ *                          The returned pointer must be freed using RTUtf16Free().
+ * @param   pwszString      UTF-16 string to duplicate.
+ * @param   cwcExtra        Number of extra RTUTF16 items to allocate.
+ * @param   pszTag          Allocation tag used for statistics and such.
+ * @remark  This function will not make any attempt to validate the encoding.
+ */
+RTDECL(int) RTUtf16DupExTag(PRTUTF16 *ppwszString, PCRTUTF16 pwszString, size_t cwcExtra, const char *pszTag);
+
+/**
+ * Returns the length of a UTF-16 string in UTF-16 characters
+ * without trailing '\\0'.
+ *
+ * Surrogate pairs counts as two UTF-16 characters here. Use RTUtf16CpCnt()
+ * to get the exact number of code points in the string.
+ *
+ * @returns The number of RTUTF16 items in the string.
+ * @param   pwszString  Pointer the UTF-16 string.
+ * @remark  This function will not make any attempt to validate the encoding.
+ */
+RTDECL(size_t) RTUtf16Len(PCRTUTF16 pwszString);
+
+/**
+ * Find the length of a zero-terminated byte string, given a max string length.
+ *
+ * @returns The string length or cbMax. The returned length does not include
+ *          the zero terminator if it was found.
+ *
+ * @param   pwszString  The string.
+ * @param   cwcMax      The max string length in RTUTF16s.
+ * @sa      RTUtf16NLenEx, RTStrNLen.
+ */
+RTDECL(size_t) RTUtf16NLen(PCRTUTF16 pwszString, size_t cwcMax);
+
+/**
+ * Find the length of a zero-terminated byte string, given
+ * a max string length.
+ *
+ * @returns IPRT status code.
+ * @retval  VINF_SUCCESS if the string has a length less than cchMax.
+ * @retval  VERR_BUFFER_OVERFLOW if the end of the string wasn't found
+ *          before cwcMax was reached.
+ *
+ * @param   pwszString  The string.
+ * @param   cwcMax      The max string length in RTUTF16s.
+ * @param   pcwc        Where to store the string length excluding the
+ *                      terminator.  This is set to cwcMax if the terminator
+ *                      isn't found.
+ * @sa      RTUtf16NLen, RTStrNLenEx.
+ */
+RTDECL(int) RTUtf16NLenEx(PCRTUTF16 pwszString, size_t cwcMax, size_t *pcwc);
+
+/**
+ * Find the zero terminator in a string with a limited length.
+ *
+ * @returns Pointer to the zero terminator.
+ * @returns NULL if the zero terminator was not found.
+ *
+ * @param   pwszString  The string.
+ * @param   cwcMax      The max string length.  RTSTR_MAX is fine.
+ */
+RTDECL(PCRTUTF16) RTUtf16End(PCRTUTF16 pwszString, size_t cwcMax);
+
+/**
+ * Strips blankspaces from both ends of the string.
+ *
+ * @returns Pointer to first non-blank char in the string.
+ * @param   pwsz    The string to strip.
+ */
+RTDECL(PRTUTF16) RTUtf16Strip(PRTUTF16 pwsz);
+
+/**
+ * Strips blankspaces from the start of the string.
+ *
+ * @returns Pointer to first non-blank char in the string.
+ * @param   pwsz    The string to strip.
+ */
+RTDECL(PRTUTF16) RTUtf16StripL(PCRTUTF16 pwsz);
+
+/**
+ * Strips blankspaces from the end of the string.
+ *
+ * @returns pwsz.
+ * @param   pwsz    The string to strip.
+ */
+RTDECL(PRTUTF16) RTUtf16StripR(PRTUTF16 pwsz);
+
+/**
+ * String copy with overflow handling.
+ *
+ * @retval  VINF_SUCCESS on success.
+ * @retval  VERR_BUFFER_OVERFLOW if the destination buffer is too small.  The
+ *          buffer will contain as much of the string as it can hold, fully
+ *          terminated.
+ *
+ * @param   pwszDst             The destination buffer.
+ * @param   cwcDst              The size of the destination buffer in RTUTF16s.
+ * @param   pwszSrc             The source string.  NULL is not OK.
+ */
+RTDECL(int) RTUtf16Copy(PRTUTF16 pwszDst, size_t cwcDst, PCRTUTF16 pwszSrc);
+
+/**
+ * String copy with overflow handling, ASCII source.
+ *
+ * @retval  VINF_SUCCESS on success.
+ * @retval  VERR_BUFFER_OVERFLOW if the destination buffer is too small.  The
+ *          buffer will contain as much of the string as it can hold, fully
+ *          terminated.
+ *
+ * @param   pwszDst             The destination buffer.
+ * @param   cwcDst              The size of the destination buffer in RTUTF16s.
+ * @param   pszSrc              The source string, pure ASCII.  NULL is not OK.
+ */
+RTDECL(int) RTUtf16CopyAscii(PRTUTF16 pwszDst, size_t cwcDst, const char *pszSrc);
+
+/**
+ * String copy with overflow handling.
+ *
+ * @retval  VINF_SUCCESS on success.
+ * @retval  VERR_BUFFER_OVERFLOW if the destination buffer is too small.  The
+ *          buffer will contain as much of the string as it can hold, fully
+ *          terminated.
+ *
+ * @param   pwszDst             The destination buffer.
+ * @param   cwcDst              The size of the destination buffer in RTUTF16s.
+ * @param   pwszSrc             The source string.  NULL is not OK.
+ * @param   cwcSrcMax           The maximum number of chars (not code points) to
+ *                              copy from the source string, not counting the
+ *                              terminator as usual.
+ */
+RTDECL(int) RTUtf16CopyEx(PRTUTF16 pwszDst, size_t cwcDst, PCRTUTF16 pwszSrc, size_t cwcSrcMax);
+
+/**
+ * String concatenation with overflow handling.
+ *
+ * @retval  VINF_SUCCESS on success.
+ * @retval  VERR_BUFFER_OVERFLOW if the destination buffer is too small.  The
+ *          buffer will contain as much of the string as it can hold, fully
+ *          terminated.
+ *
+ * @param   pwszDst             The destination buffer.
+ * @param   cwcDst              The size of the destination buffer in RTUTF16s.
+ * @param   pwszSrc             The source string.  NULL is not OK.
+ */
+RTDECL(int) RTUtf16Cat(PRTUTF16 pwszDst, size_t cwcDst, PCRTUTF16 pwszSrc);
+
+/**
+ * String concatenation with overflow handling, ASCII source.
+ *
+ * @retval  VINF_SUCCESS on success.
+ * @retval  VERR_BUFFER_OVERFLOW if the destination buffer is too small.  The
+ *          buffer will contain as much of the string as it can hold, fully
+ *          terminated.
+ *
+ * @param   pwszDst             The destination buffer.
+ * @param   cwcDst              The size of the destination buffer in RTUTF16s.
+ * @param   pszSrc              The source string, pure ASCII.  NULL is not OK.
+ */
+RTDECL(int) RTUtf16CatAscii(PRTUTF16 pwszDst, size_t cwcDst, const char *pszSrc);
+
+/**
+ * String concatenation with overflow handling.
+ *
+ * @retval  VINF_SUCCESS on success.
+ * @retval  VERR_BUFFER_OVERFLOW if the destination buffer is too small.  The
+ *          buffer will contain as much of the string as it can hold, fully
+ *          terminated.
+ *
+ * @param   pwszDst             The destination buffer.
+ * @param   cwcDst              The size of the destination buffer in RTUTF16s.
+ * @param   pwszSrc             The source string.  NULL is not OK.
+ * @param   cwcSrcMax           The maximum number of UTF-16 chars (not code
+ *                              points) to copy from the source string, not
+ *                              counting the terminator as usual.
+ */
+RTDECL(int) RTUtf16CatEx(PRTUTF16 pwszDst, size_t cwcDst, PCRTUTF16 pwszSrc, size_t cwcSrcMax);
+
+/**
+ * Performs a case sensitive string compare between two UTF-16 strings.
+ *
+ * @returns < 0 if the first string less than the second string.s
+ * @returns 0 if the first string identical to the second string.
+ * @returns > 0 if the first string greater than the second string.
+ * @param   pwsz1       First UTF-16 string. Null is allowed.
+ * @param   pwsz2       Second UTF-16 string. Null is allowed.
+ * @remark  This function will not make any attempt to validate the encoding.
+ */
+RTDECL(int) RTUtf16Cmp(PCRTUTF16 pwsz1, PCRTUTF16 pwsz2);
+
+/**
+ * Performs a case sensitive string compare between an UTF-16 string and a pure
+ * ASCII string.
+ *
+ * @returns < 0 if the first string less than the second string.s
+ * @returns 0 if the first string identical to the second string.
+ * @returns > 0 if the first string greater than the second string.
+ * @param   pwsz1       First UTF-16 string. Null is allowed.
+ * @param   psz2        Second string, pure ASCII. Null is allowed.
+ * @remark  This function will not make any attempt to validate the encoding.
+ */
+RTDECL(int) RTUtf16CmpAscii(PCRTUTF16 pwsz1, const char *psz2);
+
+/**
+ * Performs a case sensitive string compare between an UTF-16 string and a UTF-8
+ * string.
+ *
+ * @returns < 0 if the first string less than the second string.s
+ * @returns 0 if the first string identical to the second string.
+ * @returns > 0 if the first string greater than the second string.
+ * @param   pwsz1       First UTF-16 string. Null is allowed.
+ * @param   psz2        Second string, UTF-8. Null is allowed.
+ * @remarks NULL and empty strings are treated equally.
+ */
+RTDECL(int) RTUtf16CmpUtf8(PCRTUTF16 pwsz1, const char *psz2);
+
+/**
+ * Performs a case insensitive string compare between two UTF-16 strings.
+ *
+ * This is a simplified compare, as only the simplified lower/upper case folding
+ * specified by the unicode specs are used. It does not consider character pairs
+ * as they are used in some languages, just simple upper & lower case compares.
+ *
+ * @returns < 0 if the first string less than the second string.
+ * @returns 0 if the first string identical to the second string.
+ * @returns > 0 if the first string greater than the second string.
+ * @param   pwsz1       First UTF-16 string. Null is allowed.
+ * @param   pwsz2       Second UTF-16 string. Null is allowed.
+ */
+RTDECL(int) RTUtf16ICmp(PCRTUTF16 pwsz1, PCRTUTF16 pwsz2);
+
+/**
+ * Performs a case insensitive string compare between an UTF-16 string and a
+ * UTF-8 string.
+ *
+ * @returns < 0 if the first string less than the second string.s
+ * @returns 0 if the first string identical to the second string.
+ * @returns > 0 if the first string greater than the second string.
+ * @param   pwsz1       First UTF-16 string. Null is allowed.
+ * @param   psz2        Second string, UTF-8. Null is allowed.
+ * @remarks NULL and empty strings are treated equally.
+ */
+RTDECL(int) RTUtf16ICmpUtf8(PCRTUTF16 pwsz1, const char *psz2);
+
+/**
+ * Performs a case insensitive string compare between an UTF-16 string and an
+ * pure ASCII string.
+ *
+ * Since this compare only takes cares about the first 128 codepoints in
+ * unicode, no tables are needed and there aren't any real complications.
+ *
+ * @returns < 0 if the first string less than the second string.
+ * @returns 0 if the first string identical to the second string.
+ * @returns > 0 if the first string greater than the second string.
+ * @param   pwsz1       First UTF-16 string. Null is allowed.
+ * @param   psz2        Second string, pure ASCII. Null is allowed.
+ */
+RTDECL(int) RTUtf16ICmpAscii(PCRTUTF16 pwsz1, const char *psz2);
+
+/**
+ * Performs a case insensitive string compare between two UTF-16 strings
+ * using the current locale of the process (if applicable).
+ *
+ * This differs from RTUtf16ICmp() in that it will try, if a locale with the
+ * required data is available, to do a correct case-insensitive compare. It
+ * follows that it is more complex and thereby likely to be more expensive.
+ *
+ * @returns < 0 if the first string less than the second string.
+ * @returns 0 if the first string identical to the second string.
+ * @returns > 0 if the first string greater than the second string.
+ * @param   pwsz1       First UTF-16 string. Null is allowed.
+ * @param   pwsz2       Second UTF-16 string. Null is allowed.
+ */
+RTDECL(int) RTUtf16LocaleICmp(PCRTUTF16 pwsz1, PCRTUTF16 pwsz2);
+
+/**
+ * Folds a UTF-16 string to lowercase.
+ *
+ * This is a very simple folding; is uses the simple lowercase
+ * code point, it is not related to any locale just the most common
+ * lowercase codepoint setup by the unicode specs, and it will not
+ * create new surrogate pairs or remove existing ones.
+ *
+ * @returns Pointer to the passed in string.
+ * @param   pwsz        The string to fold.
+ */
+RTDECL(PRTUTF16) RTUtf16ToLower(PRTUTF16 pwsz);
+
+/**
+ * Folds a UTF-16 string to uppercase.
+ *
+ * This is a very simple folding; is uses the simple uppercase
+ * code point, it is not related to any locale just the most common
+ * uppercase codepoint setup by the unicode specs, and it will not
+ * create new surrogate pairs or remove existing ones.
+ *
+ * @returns Pointer to the passed in string.
+ * @param   pwsz        The string to fold.
+ */
+RTDECL(PRTUTF16) RTUtf16ToUpper(PRTUTF16 pwsz);
+
+/**
+ * Validates the UTF-16 encoding of the string.
+ *
+ * @returns iprt status code.
+ * @param   pwsz        The string.
+ */
+RTDECL(int) RTUtf16ValidateEncoding(PCRTUTF16 pwsz);
+
+/**
+ * Validates the UTF-16 encoding of the string.
+ *
+ * @returns iprt status code.
+ * @param   pwsz        The string.
+ * @param   cwc         The max string length (/ size) in UTF-16 units. Use
+ *                      RTSTR_MAX to process the entire string.
+ * @param   fFlags      Combination of RTSTR_VALIDATE_ENCODING_XXX flags.
+ */
+RTDECL(int) RTUtf16ValidateEncodingEx(PCRTUTF16 pwsz, size_t cwc, uint32_t fFlags);
+
+/**
+ * Checks if the UTF-16 encoding is valid.
+ *
+ * @returns true / false.
+ * @param   pwsz        The string.
+ */
+RTDECL(bool) RTUtf16IsValidEncoding(PCRTUTF16 pwsz);
+
+/**
+ * Sanitise a (valid) UTF-16 string by replacing all characters outside a white
+ * list in-place by an ASCII replacement character.  Multi-byte characters will
+ * be replaced byte by byte.
+ *
+ * @returns The number of code points replaced, or a negative value if the
+ *          string is not correctly encoded.  In this last case the string
+ *          may be partially processed.
+ * @param   pwsz           The string to sanitise.
+ * @param   puszValidSet   A zero-terminated array of pairs of Unicode points.
+ *                         Each pair is the start and end point of a range,
+ *                         and the union of these ranges forms the white list.
+ * @param   chReplacement  The ASCII replacement character.
+ */
+RTDECL(ssize_t) RTUtf16PurgeComplementSet(PRTUTF16 pwsz, PCRTUNICP puszValidSet, char chReplacement);
+
+/**
+ * Translate a UTF-16 string into a UTF-8 allocating the result buffer (default
+ * tag).
+ *
+ * @returns iprt status code.
+ * @param   pwszString      UTF-16 string to convert.
+ * @param   ppszString      Receives pointer of allocated UTF-8 string on
+ *                          success, and is always set to NULL on failure.
+ *                          The returned pointer must be freed using RTStrFree().
+ */
+#define RTUtf16ToUtf8(pwszString, ppszString)       RTUtf16ToUtf8Tag((pwszString), (ppszString), RTSTR_TAG)
+
+/**
+ * Translate a UTF-16 string into a UTF-8 allocating the result buffer.
+ *
+ * @returns iprt status code.
+ * @param   pwszString      UTF-16 string to convert.
+ * @param   ppszString      Receives pointer of allocated UTF-8 string on
+ *                          success, and is always set to NULL on failure.
+ *                          The returned pointer must be freed using RTStrFree().
+ * @param   pszTag          Allocation tag used for statistics and such.
+ */
+RTDECL(int)  RTUtf16ToUtf8Tag(PCRTUTF16 pwszString, char **ppszString, const char *pszTag);
+
+/**
+ * Translates UTF-16 to UTF-8 using buffer provided by the caller or a fittingly
+ * sized buffer allocated by the function (default tag).
+ *
+ * @returns iprt status code.
+ * @param   pwszString      The UTF-16 string to convert.
+ * @param   cwcString       The number of RTUTF16 items to translate from pwszString.
+ *                          The translation will stop when reaching cwcString or the terminator ('\\0').
+ *                          Use RTSTR_MAX to translate the entire string.
+ * @param   ppsz            If cch is non-zero, this must either be pointing to a pointer to
+ *                          a buffer of the specified size, or pointer to a NULL pointer.
+ *                          If *ppsz is NULL or cch is zero a buffer of at least cch chars
+ *                          will be allocated to hold the translated string.
+ *                          If a buffer was requested it must be freed using RTStrFree().
+ * @param   cch             The buffer size in chars (the type). This includes the terminator.
+ * @param   pcch            Where to store the length of the translated string,
+ *                          excluding the terminator. (Optional)
+ *
+ *                          This may be set under some error conditions,
+ *                          however, only for VERR_BUFFER_OVERFLOW and
+ *                          VERR_NO_STR_MEMORY will it contain a valid string
+ *                          length that can be used to resize the buffer.
+ */
+#define RTUtf16ToUtf8Ex(pwszString, cwcString, ppsz, cch, pcch) \
+    RTUtf16ToUtf8ExTag((pwszString), (cwcString), (ppsz), (cch), (pcch), RTSTR_TAG)
+
+/**
+ * Translates UTF-16 to UTF-8 using buffer provided by the caller or a fittingly
+ * sized buffer allocated by the function (custom tag).
+ *
+ * @returns iprt status code.
+ * @param   pwszString      The UTF-16 string to convert.
+ * @param   cwcString       The number of RTUTF16 items to translate from pwszString.
+ *                          The translation will stop when reaching cwcString or the terminator ('\\0').
+ *                          Use RTSTR_MAX to translate the entire string.
+ * @param   ppsz            If cch is non-zero, this must either be pointing to a pointer to
+ *                          a buffer of the specified size, or pointer to a NULL pointer.
+ *                          If *ppsz is NULL or cch is zero a buffer of at least cch chars
+ *                          will be allocated to hold the translated string.
+ *                          If a buffer was requested it must be freed using RTStrFree().
+ * @param   cch             The buffer size in chars (the type). This includes the terminator.
+ * @param   pcch            Where to store the length of the translated string,
+ *                          excluding the terminator. (Optional)
+ *
+ *                          This may be set under some error conditions,
+ *                          however, only for VERR_BUFFER_OVERFLOW and
+ *                          VERR_NO_STR_MEMORY will it contain a valid string
+ *                          length that can be used to resize the buffer.
+ * @param   pszTag          Allocation tag used for statistics and such.
+ */
+RTDECL(int)  RTUtf16ToUtf8ExTag(PCRTUTF16 pwszString, size_t cwcString, char **ppsz, size_t cch, size_t *pcch, const char *pszTag);
+
+/**
+ * Calculates the length of the UTF-16 string in UTF-8 chars (bytes).
+ *
+ * This function will validate the string, and incorrectly encoded UTF-16
+ * strings will be rejected. The primary purpose of this function is to
+ * help allocate buffers for RTUtf16ToUtf8() of the correct size. For most
+ * other purposes RTUtf16ToUtf8Ex() should be used.
+ *
+ * @returns Number of char (bytes).
+ * @returns 0 if the string was incorrectly encoded.
+ * @param   pwsz        The UTF-16 string.
+ */
+RTDECL(size_t) RTUtf16CalcUtf8Len(PCRTUTF16 pwsz);
+
+/**
+ * Calculates the length of the UTF-16 string in UTF-8 chars (bytes).
+ *
+ * This function will validate the string, and incorrectly encoded UTF-16
+ * strings will be rejected.
+ *
+ * @returns iprt status code.
+ * @param   pwsz        The string.
+ * @param   cwc         The max string length. Use RTSTR_MAX to process the entire string.
+ * @param   pcch        Where to store the string length (in bytes). Optional.
+ *                      This is undefined on failure.
+ */
+RTDECL(int) RTUtf16CalcUtf8LenEx(PCRTUTF16 pwsz, size_t cwc, size_t *pcch);
+
+/**
+ * Translate a UTF-16 string into a Latin-1 (ISO-8859-1) allocating the result
+ * buffer (default tag).
+ *
+ * @returns iprt status code.
+ * @param   pwszString      UTF-16 string to convert.
+ * @param   ppszString      Receives pointer of allocated Latin1 string on
+ *                          success, and is always set to NULL on failure.
+ *                          The returned pointer must be freed using RTStrFree().
+ */
+#define RTUtf16ToLatin1(pwszString, ppszString)     RTUtf16ToLatin1Tag((pwszString), (ppszString), RTSTR_TAG)
+
+/**
+ * Translate a UTF-16 string into a Latin-1 (ISO-8859-1) allocating the result
+ * buffer (custom tag).
+ *
+ * @returns iprt status code.
+ * @param   pwszString      UTF-16 string to convert.
+ * @param   ppszString      Receives pointer of allocated Latin1 string on
+ *                          success, and is always set to NULL on failure.
+ *                          The returned pointer must be freed using RTStrFree().
+ * @param   pszTag          Allocation tag used for statistics and such.
+ */
+RTDECL(int)  RTUtf16ToLatin1Tag(PCRTUTF16 pwszString, char **ppszString, const char *pszTag);
+
+/**
+ * Translates UTF-16 to Latin-1 (ISO-8859-1) using buffer provided by the caller
+ * or a fittingly sized buffer allocated by the function (default tag).
+ *
+ * @returns iprt status code.
+ * @param   pwszString      The UTF-16 string to convert.
+ * @param   cwcString       The number of RTUTF16 items to translate from
+ *                          pwszString. The translation will stop when reaching
+ *                          cwcString or the terminator ('\\0'). Use RTSTR_MAX
+ *                          to translate the entire string.
+ * @param   ppsz            Pointer to the pointer to the Latin-1 string. The
+ *                          buffer can optionally be preallocated by the caller.
+ *
+ *                          If cch is zero, *ppsz is undefined.
+ *
+ *                          If cch is non-zero and *ppsz is not NULL, then this
+ *                          will be used as the output buffer.
+ *                          VERR_BUFFER_OVERFLOW will be returned if this is
+ *                          insufficient.
+ *
+ *                          If cch is zero or *ppsz is NULL, then a buffer of
+ *                          sufficient size is allocated. cch can be used to
+ *                          specify a minimum size of this buffer. Use
+ *                          RTUtf16Free() to free the result.
+ *
+ * @param   cch             The buffer size in chars (the type). This includes
+ *                          the terminator.
+ * @param   pcch            Where to store the length of the translated string,
+ *                          excluding the terminator. (Optional)
+ *
+ *                          This may be set under some error conditions,
+ *                          however, only for VERR_BUFFER_OVERFLOW and
+ *                          VERR_NO_STR_MEMORY will it contain a valid string
+ *                          length that can be used to resize the buffer.
+ */
+#define RTUtf16ToLatin1Ex(pwszString, cwcString, ppsz, cch, pcch) \
+    RTUtf16ToLatin1ExTag((pwszString), (cwcString), (ppsz), (cch), (pcch), RTSTR_TAG)
+
+/**
+ * Translates UTF-16 to Latin-1 (ISO-8859-1) using buffer provided by the caller
+ * or a fittingly sized buffer allocated by the function (custom tag).
+ *
+ * @returns iprt status code.
+ * @param   pwszString      The UTF-16 string to convert.
+ * @param   cwcString       The number of RTUTF16 items to translate from
+ *                          pwszString. The translation will stop when reaching
+ *                          cwcString or the terminator ('\\0'). Use RTSTR_MAX
+ *                          to translate the entire string.
+ * @param   ppsz            Pointer to the pointer to the Latin-1 string. The
+ *                          buffer can optionally be preallocated by the caller.
+ *
+ *                          If cch is zero, *ppsz is undefined.
+ *
+ *                          If cch is non-zero and *ppsz is not NULL, then this
+ *                          will be used as the output buffer.
+ *                          VERR_BUFFER_OVERFLOW will be returned if this is
+ *                          insufficient.
+ *
+ *                          If cch is zero or *ppsz is NULL, then a buffer of
+ *                          sufficient size is allocated. cch can be used to
+ *                          specify a minimum size of this buffer. Use
+ *                          RTUtf16Free() to free the result.
+ *
+ * @param   cch             The buffer size in chars (the type). This includes
+ *                          the terminator.
+ * @param   pcch            Where to store the length of the translated string,
+ *                          excluding the terminator. (Optional)
+ *
+ *                          This may be set under some error conditions,
+ *                          however, only for VERR_BUFFER_OVERFLOW and
+ *                          VERR_NO_STR_MEMORY will it contain a valid string
+ *                          length that can be used to resize the buffer.
+ * @param   pszTag          Allocation tag used for statistics and such.
+ */
+RTDECL(int)  RTUtf16ToLatin1ExTag(PCRTUTF16 pwszString, size_t cwcString, char **ppsz, size_t cch, size_t *pcch, const char *pszTag);
+
+/**
+ * Calculates the length of the UTF-16 string in Latin-1 (ISO-8859-1) chars.
+ *
+ * This function will validate the string, and incorrectly encoded UTF-16
+ * strings will be rejected. The primary purpose of this function is to
+ * help allocate buffers for RTUtf16ToLatin1() of the correct size. For most
+ * other purposes RTUtf16ToLatin1Ex() should be used.
+ *
+ * @returns Number of char (bytes).
+ * @returns 0 if the string was incorrectly encoded.
+ * @param   pwsz        The UTF-16 string.
+ */
+RTDECL(size_t) RTUtf16CalcLatin1Len(PCRTUTF16 pwsz);
+
+/**
+ * Calculates the length of the UTF-16 string in Latin-1 (ISO-8859-1) chars.
+ *
+ * This function will validate the string, and incorrectly encoded UTF-16
+ * strings will be rejected.
+ *
+ * @returns iprt status code.
+ * @param   pwsz        The string.
+ * @param   cwc         The max string length. Use RTSTR_MAX to process the
+ *                      entire string.
+ * @param   pcch        Where to store the string length (in bytes). Optional.
+ *                      This is undefined on failure.
+ */
+RTDECL(int) RTUtf16CalcLatin1LenEx(PCRTUTF16 pwsz, size_t cwc, size_t *pcch);
+
+/**
+ * Get the unicode code point at the given string position.
+ *
+ * @returns unicode code point.
+ * @returns RTUNICP_INVALID if the encoding is invalid.
+ * @param   pwsz        The string.
+ *
+ * @remark  This is an internal worker for RTUtf16GetCp().
+ */
+RTDECL(RTUNICP) RTUtf16GetCpInternal(PCRTUTF16 pwsz);
+
+/**
+ * Get the unicode code point at the given string position.
+ *
+ * @returns iprt status code.
+ * @param   ppwsz       Pointer to the string pointer. This will be updated to
+ *                      point to the char following the current code point.
+ * @param   pCp         Where to store the code point.
+ *                      RTUNICP_INVALID is stored here on failure.
+ *
+ * @remark  This is an internal worker for RTUtf16GetCpEx().
+ */
+RTDECL(int) RTUtf16GetCpExInternal(PCRTUTF16 *ppwsz, PRTUNICP pCp);
+
+/**
+ * Put the unicode code point at the given string position
+ * and return the pointer to the char following it.
+ *
+ * This function will not consider anything at or following the
+ * buffer area pointed to by pwsz. It is therefore not suitable for
+ * inserting code points into a string, only appending/overwriting.
+ *
+ * @returns pointer to the char following the written code point.
+ * @param   pwsz        The string.
+ * @param   CodePoint   The code point to write.
+ *                      This should not be RTUNICP_INVALID or any other
+ *                      character out of the UTF-16 range.
+ *
+ * @remark  This is an internal worker for RTUtf16GetCpEx().
+ */
+RTDECL(PRTUTF16) RTUtf16PutCpInternal(PRTUTF16 pwsz, RTUNICP CodePoint);
+
+/**
+ * Get the unicode code point at the given string position.
+ *
+ * @returns unicode code point.
+ * @returns RTUNICP_INVALID if the encoding is invalid.
+ * @param   pwsz        The string.
+ *
+ * @remark  We optimize this operation by using an inline function for
+ *          everything which isn't a surrogate pair or an endian indicator.
+ */
+DECLINLINE(RTUNICP) RTUtf16GetCp(PCRTUTF16 pwsz)
+{
+    const RTUTF16 wc = *pwsz;
+    if (wc < 0xd800 || (wc > 0xdfff && wc < 0xfffe))
+        return wc;
+    return RTUtf16GetCpInternal(pwsz);
+}
+
+/**
+ * Get the unicode code point at the given string position.
+ *
+ * @returns iprt status code.
+ * @param   ppwsz       Pointer to the string pointer. This will be updated to
+ *                      point to the char following the current code point.
+ * @param   pCp         Where to store the code point.
+ *                      RTUNICP_INVALID is stored here on failure.
+ *
+ * @remark  We optimize this operation by using an inline function for
+ *          everything which isn't a surrogate pair or and endian indicator.
+ */
+DECLINLINE(int) RTUtf16GetCpEx(PCRTUTF16 *ppwsz, PRTUNICP pCp)
+{
+    const RTUTF16 wc = **ppwsz;
+    if (wc < 0xd800 || (wc > 0xdfff && wc < 0xfffe))
+    {
+        (*ppwsz)++;
+        *pCp = wc;
+        return VINF_SUCCESS;
+    }
+    return RTUtf16GetCpExInternal(ppwsz, pCp);
+}
+
+/**
+ * Put the unicode code point at the given string position
+ * and return the pointer to the char following it.
+ *
+ * This function will not consider anything at or following the
+ * buffer area pointed to by pwsz. It is therefore not suitable for
+ * inserting code points into a string, only appending/overwriting.
+ *
+ * @returns pointer to the char following the written code point.
+ * @param   pwsz        The string.
+ * @param   CodePoint   The code point to write.
+ *                      This should not be RTUNICP_INVALID or any other
+ *                      character out of the UTF-16 range.
+ *
+ * @remark  We optimize this operation by using an inline function for
+ *          everything which isn't a surrogate pair or and endian indicator.
+ */
+DECLINLINE(PRTUTF16) RTUtf16PutCp(PRTUTF16 pwsz, RTUNICP CodePoint)
+{
+    if (CodePoint < 0xd800 || (CodePoint > 0xd800 && CodePoint < 0xfffe))
+    {
+        *pwsz++ = (RTUTF16)CodePoint;
+        return pwsz;
+    }
+    return RTUtf16PutCpInternal(pwsz, CodePoint);
+}
+
+/**
+ * Skips ahead, past the current code point.
+ *
+ * @returns Pointer to the char after the current code point.
+ * @param   pwsz    Pointer to the current code point.
+ * @remark  This will not move the next valid code point, only past the current one.
+ */
+DECLINLINE(PRTUTF16) RTUtf16NextCp(PCRTUTF16 pwsz)
+{
+    RTUNICP Cp;
+    RTUtf16GetCpEx(&pwsz, &Cp);
+    return (PRTUTF16)pwsz;
+}
+
+/**
+ * Skips backwards, to the previous code point.
+ *
+ * @returns Pointer to the char after the current code point.
+ * @param   pwszStart   Pointer to the start of the string.
+ * @param   pwsz        Pointer to the current code point.
+ */
+RTDECL(PRTUTF16) RTUtf16PrevCp(PCRTUTF16 pwszStart, PCRTUTF16 pwsz);
+
+
+/**
+ * Checks if the UTF-16 char is the high surrogate char (i.e.
+ * the 1st char in the pair).
+ *
+ * @returns true if it is.
+ * @returns false if it isn't.
+ * @param   wc      The character to investigate.
+ */
+DECLINLINE(bool) RTUtf16IsHighSurrogate(RTUTF16 wc)
+{
+    return wc >= 0xd800 && wc <= 0xdbff;
+}
+
+/**
+ * Checks if the UTF-16 char is the low surrogate char (i.e.
+ * the 2nd char in the pair).
+ *
+ * @returns true if it is.
+ * @returns false if it isn't.
+ * @param   wc      The character to investigate.
+ */
+DECLINLINE(bool) RTUtf16IsLowSurrogate(RTUTF16 wc)
+{
+    return wc >= 0xdc00 && wc <= 0xdfff;
+}
+
+
+/**
+ * Checks if the two UTF-16 chars form a valid surrogate pair.
+ *
+ * @returns true if they do.
+ * @returns false if they doesn't.
+ * @param   wcHigh      The high (1st) character.
+ * @param   wcLow       The low (2nd) character.
+ */
+DECLINLINE(bool) RTUtf16IsSurrogatePair(RTUTF16 wcHigh, RTUTF16 wcLow)
+{
+    return RTUtf16IsHighSurrogate(wcHigh)
+        && RTUtf16IsLowSurrogate(wcLow);
+}
+
+/**
+ * Formats a buffer stream as hex bytes.
+ *
+ * The default is no separating spaces or line breaks or anything.
+ *
+ * @returns IPRT status code.
+ * @retval  VERR_INVALID_POINTER if any of the pointers are wrong.
+ * @retval  VERR_BUFFER_OVERFLOW if the buffer is insufficent to hold the bytes.
+ *
+ * @param   pwszBuf     Output string buffer.
+ * @param   cwcBuf      The size of the output buffer in RTUTF16 units.
+ * @param   pv          Pointer to the bytes to stringify.
+ * @param   cb          The number of bytes to stringify.
+ * @param   fFlags      Combination of RTSTRPRINTHEXBYTES_F_XXX values.
+ * @sa      RTStrPrintHexBytes.
+ */
+RTDECL(int) RTUtf16PrintHexBytes(PRTUTF16 pwszBuf, size_t cwcBuf, void const *pv, size_t cb, uint32_t fFlags);
+
+/** @} */
+
+
+RT_C_DECLS_END
+
+/** @} */
+
+#endif
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/include/iprt/x86.h
@@ -0,0 +1,3983 @@
+/** @file
+ * IPRT - X86 and AMD64 Structures and Definitions.
+ *
+ * @note x86.mac is generated from this file by running 'kmk incs' in the root.
+ */
+
+/*
+ * Copyright (C) 2006-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+#ifndef ___iprt_x86_h
+#define ___iprt_x86_h
+
+#ifndef VBOX_FOR_DTRACE_LIB
+# include <iprt/types.h>
+# include <iprt/assert.h>
+#else
+# pragma D depends_on library vbox-types.d
+#endif
+
+/* Workaround for Solaris sys/regset.h defining CS, DS */
+#ifdef RT_OS_SOLARIS
+# undef CS
+# undef DS
+#endif
+
+/** @defgroup grp_rt_x86   x86 Types and Definitions
+ * @ingroup grp_rt
+ * @{
+ */
+
+#ifndef VBOX_FOR_DTRACE_LIB
+/**
+ * EFLAGS Bits.
+ */
+typedef struct X86EFLAGSBITS
+{
+    /** Bit 0 - CF - Carry flag - Status flag. */
+    unsigned    u1CF : 1;
+    /** Bit 1 -  1 - Reserved flag. */
+    unsigned    u1Reserved0 : 1;
+    /** Bit 2 - PF - Parity flag - Status flag. */
+    unsigned    u1PF : 1;
+    /** Bit 3 -  0 - Reserved flag. */
+    unsigned    u1Reserved1 : 1;
+    /** Bit 4 - AF - Auxiliary carry flag - Status flag. */
+    unsigned    u1AF : 1;
+    /** Bit 5 -  0 - Reserved flag. */
+    unsigned    u1Reserved2 : 1;
+    /** Bit 6 - ZF - Zero flag - Status flag. */
+    unsigned    u1ZF : 1;
+    /** Bit 7 - SF - Signed flag - Status flag. */
+    unsigned    u1SF : 1;
+    /** Bit 8 - TF - Trap flag - System flag. */
+    unsigned    u1TF : 1;
+    /** Bit 9 - IF - Interrupt flag - System flag. */
+    unsigned    u1IF : 1;
+    /** Bit 10 - DF - Direction flag - Control flag. */
+    unsigned    u1DF : 1;
+    /** Bit 11 - OF - Overflow flag - Status flag. */
+    unsigned    u1OF : 1;
+    /** Bit 12-13 - IOPL - I/O privilege level flag - System flag. */
+    unsigned    u2IOPL : 2;
+    /** Bit 14 - NT - Nested task flag - System flag. */
+    unsigned    u1NT : 1;
+    /** Bit 15 -  0 - Reserved flag. */
+    unsigned    u1Reserved3 : 1;
+    /** Bit 16 - RF - Resume flag - System flag. */
+    unsigned    u1RF : 1;
+    /** Bit 17 - VM - Virtual 8086 mode - System flag. */
+    unsigned    u1VM : 1;
+    /** Bit 18 - AC - Alignment check flag - System flag. Works with CR0.AM. */
+    unsigned    u1AC : 1;
+    /** Bit 19 - VIF - Virtual interrupt flag - System flag. */
+    unsigned    u1VIF : 1;
+    /** Bit 20 - VIP - Virtual interrupt pending flag - System flag. */
+    unsigned    u1VIP : 1;
+    /** Bit 21 - ID - CPUID flag - System flag. If this responds to flipping CPUID is supported. */
+    unsigned    u1ID : 1;
+    /** Bit 22-31 - 0 - Reserved flag. */
+    unsigned    u10Reserved4 : 10;
+} X86EFLAGSBITS;
+/** Pointer to EFLAGS bits. */
+typedef X86EFLAGSBITS *PX86EFLAGSBITS;
+/** Pointer to const EFLAGS bits. */
+typedef const X86EFLAGSBITS *PCX86EFLAGSBITS;
+#endif /* !VBOX_FOR_DTRACE_LIB */
+
+/**
+ * EFLAGS.
+ */
+typedef union X86EFLAGS
+{
+    /** The plain unsigned view. */
+    uint32_t        u;
+#ifndef VBOX_FOR_DTRACE_LIB
+    /** The bitfield view. */
+    X86EFLAGSBITS   Bits;
+#endif
+    /** The 8-bit view. */
+    uint8_t         au8[4];
+    /** The 16-bit view. */
+    uint16_t        au16[2];
+    /** The 32-bit view. */
+    uint32_t        au32[1];
+    /** The 32-bit view. */
+    uint32_t        u32;
+} X86EFLAGS;
+/** Pointer to EFLAGS. */
+typedef X86EFLAGS *PX86EFLAGS;
+/** Pointer to const EFLAGS. */
+typedef const X86EFLAGS *PCX86EFLAGS;
+
+/**
+ * RFLAGS (32 upper bits are reserved).
+ */
+typedef union X86RFLAGS
+{
+    /** The plain unsigned view. */
+    uint64_t        u;
+#ifndef VBOX_FOR_DTRACE_LIB
+    /** The bitfield view. */
+    X86EFLAGSBITS   Bits;
+#endif
+    /** The 8-bit view. */
+    uint8_t         au8[8];
+    /** The 16-bit view. */
+    uint16_t        au16[4];
+    /** The 32-bit view. */
+    uint32_t        au32[2];
+    /** The 64-bit view. */
+    uint64_t        au64[1];
+    /** The 64-bit view. */
+    uint64_t        u64;
+} X86RFLAGS;
+/** Pointer to RFLAGS. */
+typedef X86RFLAGS *PX86RFLAGS;
+/** Pointer to const RFLAGS. */
+typedef const X86RFLAGS *PCX86RFLAGS;
+
+
+/** @name EFLAGS
+ * @{
+ */
+/** Bit 0 - CF - Carry flag - Status flag. */
+#define X86_EFL_CF          RT_BIT(0)
+#define X86_EFL_CF_BIT      0
+/** Bit 1 - Reserved, reads as 1. */
+#define X86_EFL_1           RT_BIT(1)
+/** Bit 2 - PF - Parity flag - Status flag. */
+#define X86_EFL_PF          RT_BIT(2)
+/** Bit 4 - AF - Auxiliary carry flag - Status flag. */
+#define X86_EFL_AF          RT_BIT(4)
+#define X86_EFL_AF_BIT      4
+/** Bit 6 - ZF - Zero flag - Status flag. */
+#define X86_EFL_ZF          RT_BIT(6)
+#define X86_EFL_ZF_BIT      6
+/** Bit 7 - SF - Signed flag - Status flag. */
+#define X86_EFL_SF          RT_BIT(7)
+#define X86_EFL_SF_BIT      7
+/** Bit 8 - TF - Trap flag - System flag. */
+#define X86_EFL_TF          RT_BIT(8)
+/** Bit 9 - IF - Interrupt flag - System flag. */
+#define X86_EFL_IF          RT_BIT(9)
+/** Bit 10 - DF - Direction flag - Control flag. */
+#define X86_EFL_DF          RT_BIT(10)
+/** Bit 11 - OF - Overflow flag - Status flag. */
+#define X86_EFL_OF          RT_BIT(11)
+#define X86_EFL_OF_BIT      11
+/** Bit 12-13 - IOPL - I/O privilege level flag - System flag. */
+#define X86_EFL_IOPL        (RT_BIT(12) | RT_BIT(13))
+/** Bit 14 - NT - Nested task flag - System flag. */
+#define X86_EFL_NT          RT_BIT(14)
+/** Bit 16 - RF - Resume flag - System flag. */
+#define X86_EFL_RF          RT_BIT(16)
+/** Bit 17 - VM - Virtual 8086 mode - System flag. */
+#define X86_EFL_VM          RT_BIT(17)
+/** Bit 18 - AC - Alignment check flag - System flag. Works with CR0.AM. */
+#define X86_EFL_AC          RT_BIT(18)
+/** Bit 19 - VIF - Virtual interrupt flag - System flag. */
+#define X86_EFL_VIF         RT_BIT(19)
+/** Bit 20 - VIP - Virtual interrupt pending flag - System flag. */
+#define X86_EFL_VIP         RT_BIT(20)
+/** Bit 21 - ID - CPUID flag - System flag. If this responds to flipping CPUID is supported. */
+#define X86_EFL_ID          RT_BIT(21)
+/** All live bits. */
+#define X86_EFL_LIVE_MASK   UINT32_C(0x003f7fd5)
+/** Read as 1 bits. */
+#define X86_EFL_RA1_MASK    RT_BIT_32(1)
+/** IOPL shift. */
+#define X86_EFL_IOPL_SHIFT  12
+/** The IOPL level from the flags. */
+#define X86_EFL_GET_IOPL(efl)   (((efl) >> X86_EFL_IOPL_SHIFT) & 3)
+/** Bits restored by popf */
+#define X86_EFL_POPF_BITS       (  X86_EFL_CF | X86_EFL_PF | X86_EFL_AF | X86_EFL_ZF | X86_EFL_SF | X86_EFL_TF | X86_EFL_IF \
+                                 | X86_EFL_DF | X86_EFL_OF | X86_EFL_IOPL | X86_EFL_NT | X86_EFL_AC | X86_EFL_ID )
+/** The status bits commonly updated by arithmetic instructions. */
+#define X86_EFL_STATUS_BITS     ( X86_EFL_CF | X86_EFL_PF | X86_EFL_AF | X86_EFL_ZF | X86_EFL_SF | X86_EFL_OF )
+/** @} */
+
+
+/** CPUID Feature information - ECX.
+ * CPUID query with EAX=1.
+ */
+#ifndef VBOX_FOR_DTRACE_LIB
+typedef struct X86CPUIDFEATECX
+{
+    /** Bit 0 - SSE3 - Supports SSE3 or not. */
+    unsigned    u1SSE3 : 1;
+    /** Bit 1 - PCLMULQDQ. */
+    unsigned    u1PCLMULQDQ : 1;
+    /** Bit 2 - DS Area 64-bit layout. */
+    unsigned    u1DTE64 : 1;
+    /** Bit 3 - MONITOR - Supports MONITOR/MWAIT. */
+    unsigned    u1Monitor : 1;
+    /** Bit 4 - CPL-DS - CPL Qualified Debug Store. */
+    unsigned    u1CPLDS : 1;
+    /** Bit 5 - VMX - Virtual Machine Technology. */
+    unsigned    u1VMX : 1;
+    /** Bit 6 - SMX: Safer Mode Extensions. */
+    unsigned    u1SMX : 1;
+    /** Bit 7 - EST - Enh. SpeedStep Tech. */
+    unsigned    u1EST : 1;
+    /** Bit 8 - TM2 - Terminal Monitor 2. */
+    unsigned    u1TM2 : 1;
+    /** Bit 9 - SSSE3 - Supplemental Streaming SIMD Extensions 3. */
+    unsigned    u1SSSE3 : 1;
+    /** Bit 10 - CNTX-ID - L1 Context ID. */
+    unsigned    u1CNTXID : 1;
+    /** Bit 11 - Reserved. */
+    unsigned    u1Reserved1 : 1;
+    /** Bit 12 - FMA. */
+    unsigned    u1FMA : 1;
+    /** Bit 13 - CX16 - CMPXCHG16B. */
+    unsigned    u1CX16 : 1;
+    /** Bit 14 - xTPR Update Control. Processor supports changing IA32_MISC_ENABLES[bit 23]. */
+    unsigned    u1TPRUpdate : 1;
+    /** Bit 15 - PDCM - Perf/Debug Capability MSR. */
+    unsigned    u1PDCM : 1;
+    /** Bit 16 - Reserved. */
+    unsigned    u1Reserved2 : 1;
+    /** Bit 17 - PCID - Process-context identifiers. */
+    unsigned    u1PCID : 1;
+    /** Bit 18 - Direct Cache Access. */
+    unsigned    u1DCA : 1;
+    /** Bit 19 - SSE4_1 - Supports SSE4_1 or not. */
+    unsigned    u1SSE4_1 : 1;
+    /** Bit 20 - SSE4_2 - Supports SSE4_2 or not. */
+    unsigned    u1SSE4_2 : 1;
+    /** Bit 21 - x2APIC. */
+    unsigned    u1x2APIC : 1;
+    /** Bit 22 - MOVBE - Supports MOVBE. */
+    unsigned    u1MOVBE : 1;
+    /** Bit 23 - POPCNT - Supports POPCNT. */
+    unsigned    u1POPCNT : 1;
+    /** Bit 24 - TSC-Deadline. */
+    unsigned    u1TSCDEADLINE : 1;
+    /** Bit 25 - AES. */
+    unsigned    u1AES : 1;
+    /** Bit 26 - XSAVE - Supports XSAVE. */
+    unsigned    u1XSAVE : 1;
+    /** Bit 27 - OSXSAVE - Supports OSXSAVE. */
+    unsigned    u1OSXSAVE : 1;
+    /** Bit 28 - AVX - Supports AVX instruction extensions. */
+    unsigned    u1AVX : 1;
+    /** Bit 29 - F16C - Supports 16-bit floating point conversion instructions. */
+    unsigned    u1F16C : 1;
+    /** Bit 30 - RDRAND - Supports RDRAND. */
+    unsigned    u1RDRAND : 1;
+    /** Bit 31 - Hypervisor present (we're a guest). */
+    unsigned    u1HVP : 1;
+} X86CPUIDFEATECX;
+#else  /* VBOX_FOR_DTRACE_LIB */
+typedef uint32_t X86CPUIDFEATECX;
+#endif /* VBOX_FOR_DTRACE_LIB */
+/** Pointer to CPUID Feature Information - ECX. */
+typedef X86CPUIDFEATECX *PX86CPUIDFEATECX;
+/** Pointer to const CPUID Feature Information - ECX. */
+typedef const X86CPUIDFEATECX *PCX86CPUIDFEATECX;
+
+
+/** CPUID Feature Information - EDX.
+ * CPUID query with EAX=1.
+ */
+#ifndef VBOX_FOR_DTRACE_LIB /* DTrace different (brain-dead from a C pov) bitfield implementation */
+typedef struct X86CPUIDFEATEDX
+{
+    /** Bit 0 - FPU - x87 FPU on Chip. */
+    unsigned    u1FPU : 1;
+    /** Bit 1 - VME - Virtual 8086 Mode Enhancements. */
+    unsigned    u1VME : 1;
+    /** Bit 2 - DE - Debugging extensions. */
+    unsigned    u1DE : 1;
+    /** Bit 3 - PSE - Page Size Extension. */
+    unsigned    u1PSE : 1;
+    /** Bit 4 - TSC - Time Stamp Counter. */
+    unsigned    u1TSC : 1;
+    /** Bit 5 - MSR - Model Specific Registers RDMSR and WRMSR Instructions. */
+    unsigned    u1MSR : 1;
+    /** Bit 6 - PAE - Physical Address Extension. */
+    unsigned    u1PAE : 1;
+    /** Bit 7 - MCE - Machine Check Exception. */
+    unsigned    u1MCE : 1;
+    /** Bit 8 - CX8 - CMPXCHG8B instruction. */
+    unsigned    u1CX8 : 1;
+    /** Bit 9 - APIC - APIC On-Chip. */
+    unsigned    u1APIC : 1;
+    /** Bit 10 - Reserved. */
+    unsigned    u1Reserved1 : 1;
+    /** Bit 11 - SEP - SYSENTER and SYSEXIT. */
+    unsigned    u1SEP : 1;
+    /** Bit 12 - MTRR - Memory Type Range Registers. */
+    unsigned    u1MTRR : 1;
+    /** Bit 13 - PGE - PTE Global Bit. */
+    unsigned    u1PGE : 1;
+    /** Bit 14 - MCA - Machine Check Architecture. */
+    unsigned    u1MCA : 1;
+    /** Bit 15 - CMOV - Conditional Move Instructions. */
+    unsigned    u1CMOV : 1;
+    /** Bit 16 - PAT - Page Attribute Table. */
+    unsigned    u1PAT : 1;
+    /** Bit 17 - PSE-36 - 36-bit Page Size Extension. */
+    unsigned    u1PSE36 : 1;
+    /** Bit 18 - PSN - Processor Serial Number. */
+    unsigned    u1PSN : 1;
+    /** Bit 19 - CLFSH - CLFLUSH Instruction. */
+    unsigned    u1CLFSH : 1;
+    /** Bit 20 - Reserved. */
+    unsigned    u1Reserved2 : 1;
+    /** Bit 21 - DS - Debug Store. */
+    unsigned    u1DS : 1;
+    /** Bit 22 - ACPI - Thermal Monitor and Software Controlled Clock Facilities. */
+    unsigned    u1ACPI : 1;
+    /** Bit 23 - MMX - Intel MMX 'Technology'. */
+    unsigned    u1MMX : 1;
+    /** Bit 24 - FXSR - FXSAVE and FXRSTOR Instructions. */
+    unsigned    u1FXSR : 1;
+    /** Bit 25 - SSE - SSE Support. */
+    unsigned    u1SSE : 1;
+    /** Bit 26 - SSE2 - SSE2 Support. */
+    unsigned    u1SSE2 : 1;
+    /** Bit 27 - SS - Self Snoop. */
+    unsigned    u1SS : 1;
+    /** Bit 28 - HTT - Hyper-Threading Technology. */
+    unsigned    u1HTT : 1;
+    /** Bit 29 - TM - Thermal Monitor. */
+    unsigned    u1TM : 1;
+    /** Bit 30 - Reserved - . */
+    unsigned    u1Reserved3 : 1;
+    /** Bit 31 - PBE - Pending Break Enabled. */
+    unsigned    u1PBE : 1;
+} X86CPUIDFEATEDX;
+#else  /* VBOX_FOR_DTRACE_LIB */
+typedef uint32_t X86CPUIDFEATEDX;
+#endif /* VBOX_FOR_DTRACE_LIB */
+/** Pointer to CPUID Feature Information - EDX. */
+typedef X86CPUIDFEATEDX *PX86CPUIDFEATEDX;
+/** Pointer to const CPUID Feature Information - EDX. */
+typedef const X86CPUIDFEATEDX *PCX86CPUIDFEATEDX;
+
+/** @name CPUID Vendor information.
+ * CPUID query with EAX=0.
+ * @{
+ */
+#define X86_CPUID_VENDOR_INTEL_EBX      0x756e6547      /* Genu */
+#define X86_CPUID_VENDOR_INTEL_ECX      0x6c65746e      /* ntel */
+#define X86_CPUID_VENDOR_INTEL_EDX      0x49656e69      /* ineI */
+
+#define X86_CPUID_VENDOR_AMD_EBX        0x68747541      /* Auth */
+#define X86_CPUID_VENDOR_AMD_ECX        0x444d4163      /* cAMD */
+#define X86_CPUID_VENDOR_AMD_EDX        0x69746e65      /* enti */
+
+#define X86_CPUID_VENDOR_VIA_EBX        0x746e6543      /* Cent */
+#define X86_CPUID_VENDOR_VIA_ECX        0x736c7561      /* auls */
+#define X86_CPUID_VENDOR_VIA_EDX        0x48727561      /* aurH */
+/** @} */
+
+
+/** @name CPUID Feature information.
+ * CPUID query with EAX=1.
+ * @{
+ */
+/** ECX Bit 0 - SSE3 - Supports SSE3 or not. */
+#define X86_CPUID_FEATURE_ECX_SSE3      RT_BIT(0)
+/** ECX Bit 1 - PCLMUL - PCLMULQDQ support (for AES-GCM). */
+#define X86_CPUID_FEATURE_ECX_PCLMUL    RT_BIT(1)
+/** ECX Bit 2 - DTES64 - DS Area 64-bit Layout. */
+#define X86_CPUID_FEATURE_ECX_DTES64    RT_BIT(2)
+/** ECX Bit 3 - MONITOR - Supports MONITOR/MWAIT. */
+#define X86_CPUID_FEATURE_ECX_MONITOR   RT_BIT(3)
+/** ECX Bit 4 - CPL-DS - CPL Qualified Debug Store. */
+#define X86_CPUID_FEATURE_ECX_CPLDS     RT_BIT(4)
+/** ECX Bit 5 - VMX - Virtual Machine Technology. */
+#define X86_CPUID_FEATURE_ECX_VMX       RT_BIT(5)
+/** ECX Bit 6 - SMX - Safer Mode Extensions. */
+#define X86_CPUID_FEATURE_ECX_SMX       RT_BIT(6)
+/** ECX Bit 7 - EST - Enh. SpeedStep Tech. */
+#define X86_CPUID_FEATURE_ECX_EST       RT_BIT(7)
+/** ECX Bit 8 - TM2 - Terminal Monitor 2. */
+#define X86_CPUID_FEATURE_ECX_TM2       RT_BIT(8)
+/** ECX Bit 9 - SSSE3 - Supplemental Streaming SIMD Extensions 3. */
+#define X86_CPUID_FEATURE_ECX_SSSE3     RT_BIT(9)
+/** ECX Bit 10 - CNTX-ID - L1 Context ID. */
+#define X86_CPUID_FEATURE_ECX_CNTXID    RT_BIT(10)
+/** ECX Bit 11 - SDBG - Sillicon debug interface (IA32_DEBUG_INTERFACE MSR).
+ * See figure 3-6 and table 3-10, in intel Vol. 2A. from 2015-01-01. */
+#define X86_CPUID_FEATURE_ECX_SDBG      RT_BIT(11)
+/** ECX Bit 12 - FMA. */
+#define X86_CPUID_FEATURE_ECX_FMA       RT_BIT(12)
+/** ECX Bit 13 - CX16 - CMPXCHG16B. */
+#define X86_CPUID_FEATURE_ECX_CX16      RT_BIT(13)
+/** ECX Bit 14 - xTPR Update Control. Processor supports changing IA32_MISC_ENABLES[bit 23]. */
+#define X86_CPUID_FEATURE_ECX_TPRUPDATE RT_BIT(14)
+/** ECX Bit 15 - PDCM - Perf/Debug Capability MSR. */
+#define X86_CPUID_FEATURE_ECX_PDCM      RT_BIT(15)
+/** ECX Bit 17 - PCID - Process-context identifiers. */
+#define X86_CPUID_FEATURE_ECX_PCID      RT_BIT(17)
+/** ECX Bit 18 - DCA - Direct Cache Access. */
+#define X86_CPUID_FEATURE_ECX_DCA       RT_BIT(18)
+/** ECX Bit 19 - SSE4_1 - Supports SSE4_1 or not. */
+#define X86_CPUID_FEATURE_ECX_SSE4_1    RT_BIT(19)
+/** ECX Bit 20 - SSE4_2 - Supports SSE4_2 or not. */
+#define X86_CPUID_FEATURE_ECX_SSE4_2    RT_BIT(20)
+/** ECX Bit 21 - x2APIC support. */
+#define X86_CPUID_FEATURE_ECX_X2APIC    RT_BIT(21)
+/** ECX Bit 22 - MOVBE instruction. */
+#define X86_CPUID_FEATURE_ECX_MOVBE     RT_BIT(22)
+/** ECX Bit 23 - POPCNT instruction. */
+#define X86_CPUID_FEATURE_ECX_POPCNT    RT_BIT(23)
+/** ECX Bir 24 - TSC-Deadline. */
+#define X86_CPUID_FEATURE_ECX_TSCDEADL  RT_BIT(24)
+/** ECX Bit 25 - AES instructions. */
+#define X86_CPUID_FEATURE_ECX_AES       RT_BIT(25)
+/** ECX Bit 26 - XSAVE instruction. */
+#define X86_CPUID_FEATURE_ECX_XSAVE     RT_BIT(26)
+/** ECX Bit 27 - OSXSAVE instruction. */
+#define X86_CPUID_FEATURE_ECX_OSXSAVE   RT_BIT(27)
+/** ECX Bit 28 - AVX. */
+#define X86_CPUID_FEATURE_ECX_AVX       RT_BIT(28)
+/** ECX Bit 29 - F16C - Half-precision convert instruction support. */
+#define X86_CPUID_FEATURE_ECX_F16C      RT_BIT(29)
+/** ECX Bit 30 - RDRAND instruction. */
+#define X86_CPUID_FEATURE_ECX_RDRAND    RT_BIT(30)
+/** ECX Bit 31 - Hypervisor Present (software only). */
+#define X86_CPUID_FEATURE_ECX_HVP       RT_BIT(31)
+
+
+/** Bit 0 - FPU - x87 FPU on Chip. */
+#define X86_CPUID_FEATURE_EDX_FPU       RT_BIT(0)
+/** Bit 1 - VME - Virtual 8086 Mode Enhancements. */
+#define X86_CPUID_FEATURE_EDX_VME       RT_BIT(1)
+/** Bit 2 - DE - Debugging extensions. */
+#define X86_CPUID_FEATURE_EDX_DE        RT_BIT(2)
+/** Bit 3 - PSE - Page Size Extension. */
+#define X86_CPUID_FEATURE_EDX_PSE       RT_BIT(3)
+/** Bit 4 - TSC - Time Stamp Counter. */
+#define X86_CPUID_FEATURE_EDX_TSC       RT_BIT(4)
+/** Bit 5 - MSR - Model Specific Registers RDMSR and WRMSR Instructions. */
+#define X86_CPUID_FEATURE_EDX_MSR       RT_BIT(5)
+/** Bit 6 - PAE - Physical Address Extension. */
+#define X86_CPUID_FEATURE_EDX_PAE       RT_BIT(6)
+/** Bit 7 - MCE - Machine Check Exception. */
+#define X86_CPUID_FEATURE_EDX_MCE       RT_BIT(7)
+/** Bit 8 - CX8 - CMPXCHG8B instruction. */
+#define X86_CPUID_FEATURE_EDX_CX8       RT_BIT(8)
+/** Bit 9 - APIC - APIC On-Chip. */
+#define X86_CPUID_FEATURE_EDX_APIC      RT_BIT(9)
+/** Bit 11 - SEP - SYSENTER and SYSEXIT Present. */
+#define X86_CPUID_FEATURE_EDX_SEP       RT_BIT(11)
+/** Bit 12 - MTRR - Memory Type Range Registers. */
+#define X86_CPUID_FEATURE_EDX_MTRR      RT_BIT(12)
+/** Bit 13 - PGE - PTE Global Bit. */
+#define X86_CPUID_FEATURE_EDX_PGE       RT_BIT(13)
+/** Bit 14 - MCA - Machine Check Architecture. */
+#define X86_CPUID_FEATURE_EDX_MCA       RT_BIT(14)
+/** Bit 15 - CMOV - Conditional Move Instructions. */
+#define X86_CPUID_FEATURE_EDX_CMOV      RT_BIT(15)
+/** Bit 16 - PAT - Page Attribute Table. */
+#define X86_CPUID_FEATURE_EDX_PAT       RT_BIT(16)
+/** Bit 17 - PSE-36 - 36-bit Page Size Extension. */
+#define X86_CPUID_FEATURE_EDX_PSE36     RT_BIT(17)
+/** Bit 18 - PSN - Processor Serial Number. */
+#define X86_CPUID_FEATURE_EDX_PSN       RT_BIT(18)
+/** Bit 19 - CLFSH - CLFLUSH Instruction. */
+#define X86_CPUID_FEATURE_EDX_CLFSH     RT_BIT(19)
+/** Bit 21 - DS - Debug Store. */
+#define X86_CPUID_FEATURE_EDX_DS        RT_BIT(21)
+/** Bit 22 - ACPI - Thermal Monitor and Software Controlled Clock Facilities. */
+#define X86_CPUID_FEATURE_EDX_ACPI      RT_BIT(22)
+/** Bit 23 - MMX - Intel MMX Technology. */
+#define X86_CPUID_FEATURE_EDX_MMX       RT_BIT(23)
+/** Bit 24 - FXSR - FXSAVE and FXRSTOR Instructions. */
+#define X86_CPUID_FEATURE_EDX_FXSR      RT_BIT(24)
+/** Bit 25 - SSE - SSE Support. */
+#define X86_CPUID_FEATURE_EDX_SSE       RT_BIT(25)
+/** Bit 26 - SSE2 - SSE2 Support. */
+#define X86_CPUID_FEATURE_EDX_SSE2      RT_BIT(26)
+/** Bit 27 - SS - Self Snoop. */
+#define X86_CPUID_FEATURE_EDX_SS        RT_BIT(27)
+/** Bit 28 - HTT - Hyper-Threading Technology. */
+#define X86_CPUID_FEATURE_EDX_HTT       RT_BIT(28)
+/** Bit 29 - TM - Therm. Monitor. */
+#define X86_CPUID_FEATURE_EDX_TM        RT_BIT(29)
+/** Bit 31 - PBE - Pending Break Enabled. */
+#define X86_CPUID_FEATURE_EDX_PBE       RT_BIT(31)
+/** @} */
+
+/** @name CPUID mwait/monitor information.
+ * CPUID query with EAX=5.
+ * @{
+ */
+/** ECX Bit 0 - MWAITEXT - Supports mwait/monitor extensions or not. */
+#define X86_CPUID_MWAIT_ECX_EXT            RT_BIT(0)
+/** ECX Bit 1 - MWAITBREAK - Break mwait for external interrupt even if EFLAGS.IF=0. */
+#define X86_CPUID_MWAIT_ECX_BREAKIRQIF0    RT_BIT(1)
+/** @} */
+
+
+/** @name CPUID Structured Extended Feature information.
+ * CPUID query with EAX=7.
+ * @{
+ */
+/** EBX Bit 0 - FSGSBASE - Supports RDFSBASE/RDGSBASE/WRFSBASE/WRGSBASE. */
+#define X86_CPUID_STEXT_FEATURE_EBX_FSGSBASE          RT_BIT(0)
+/** EBX Bit 1 - TSCADJUST - Supports MSR_IA32_TSC_ADJUST. */
+#define X86_CPUID_STEXT_FEATURE_EBX_TSC_ADJUST        RT_BIT(1)
+/** EBX Bit 3 - BMI1 - Advanced Bit Manipulation extension 1. */
+#define X86_CPUID_STEXT_FEATURE_EBX_BMI1              RT_BIT(3)
+/** EBX Bit 4 - HLE - Hardware Lock Elision. */
+#define X86_CPUID_STEXT_FEATURE_EBX_HLE               RT_BIT(4)
+/** EBX Bit 5 - AVX2 - Advanced Vector Extensions 2. */
+#define X86_CPUID_STEXT_FEATURE_EBX_AVX2              RT_BIT(5)
+/** EBX Bit 7 - SMEP - Supervisor Mode Execution Prevention. */
+#define X86_CPUID_STEXT_FEATURE_EBX_SMEP              RT_BIT(7)
+/** EBX Bit 8 - BMI2 - Advanced Bit Manipulation extension 2. */
+#define X86_CPUID_STEXT_FEATURE_EBX_BMI2              RT_BIT(8)
+/** EBX Bit 9 - ERMS - Supports Enhanced REP MOVSB/STOSB. */
+#define X86_CPUID_STEXT_FEATURE_EBX_ERMS              RT_BIT(9)
+/** EBX Bit 10 - INVPCID - Supports INVPCID. */
+#define X86_CPUID_STEXT_FEATURE_EBX_INVPCID           RT_BIT(10)
+/** EBX Bit 11 - RTM - Supports Restricted Transactional Memory. */
+#define X86_CPUID_STEXT_FEATURE_EBX_RTM               RT_BIT(11)
+/** EBX Bit 12 - PQM - Supports Platform Quality of Service Monitoring. */
+#define X86_CPUID_STEXT_FEATURE_EBX_PQM               RT_BIT(12)
+/** EBX Bit 13 - DEPFPU_CS_DS - Deprecates FPU CS, FPU DS values if set. */
+#define X86_CPUID_STEXT_FEATURE_EBX_DEPR_FPU_CS_DS    RT_BIT(13)
+/** EBX Bit 14 - MPE - Supports Intel Memory Protection Extensions. */
+#define X86_CPUID_STEXT_FEATURE_EBX_MPE               RT_BIT(14)
+/** EBX Bit 15 - PQE - Supports Platform Quality of Service Enforcement. */
+#define X86_CPUID_STEXT_FEATURE_EBX_PQE               RT_BIT(15)
+/** EBX Bit 16 - AVX512F - Supports AVX512F. */
+#define X86_CPUID_STEXT_FEATURE_EBX_AVX512F           RT_BIT(16)
+/** EBX Bit 18 - RDSEED - Supports RDSEED. */
+#define X86_CPUID_STEXT_FEATURE_EBX_RDSEED            RT_BIT(18)
+/** EBX Bit 19 - ADX - Supports ADCX/ADOX. */
+#define X86_CPUID_STEXT_FEATURE_EBX_ADX               RT_BIT(19)
+/** EBX Bit 20 - SMAP - Supports Supervisor Mode Access Prevention. */
+#define X86_CPUID_STEXT_FEATURE_EBX_SMAP              RT_BIT(20)
+/** EBX Bit 23 - CLFLUSHOPT - Supports CLFLUSHOPT (Cache Line Flush). */
+#define X86_CPUID_STEXT_FEATURE_EBX_CLFLUSHOPT        RT_BIT(23)
+/** EBX Bit 25 - INTEL_PT - Supports Intel Processor Trace. */
+#define X86_CPUID_STEXT_FEATURE_EBX_INTEL_PT          RT_BIT(25)
+/** EBX Bit 26 - AVX512PF - Supports AVX512PF. */
+#define X86_CPUID_STEXT_FEATURE_EBX_AVX512PF          RT_BIT(26)
+/** EBX Bit 27 - AVX512ER - Supports AVX512ER. */
+#define X86_CPUID_STEXT_FEATURE_EBX_AVX512ER          RT_BIT(27)
+/** EBX Bit 28 - AVX512CD - Supports AVX512CD. */
+#define X86_CPUID_STEXT_FEATURE_EBX_AVX512CD          RT_BIT(28)
+/** EBX Bit 29 - SHA - Supports Secure Hash Algorithm extensions. */
+#define X86_CPUID_STEXT_FEATURE_EBX_SHA               RT_BIT(29)
+
+/** ECX Bit 0 - PREFETCHWT1 - Supports the PREFETCHWT1 instruction. */
+#define X86_CPUID_STEXT_FEATURE_ECX_PREFETCHWT1       RT_BIT(0)
+/** @} */
+
+
+/** @name CPUID Extended Feature information.
+ *  CPUID query with EAX=0x80000001.
+ *  @{
+ */
+/** ECX Bit 0 - LAHF/SAHF support in 64-bit mode. */
+#define X86_CPUID_EXT_FEATURE_ECX_LAHF_SAHF     RT_BIT(0)
+
+/** EDX Bit 11 - SYSCALL/SYSRET. */
+#define X86_CPUID_EXT_FEATURE_EDX_SYSCALL       RT_BIT(11)
+/** EDX Bit 20 - No-Execute/Execute-Disable. */
+#define X86_CPUID_EXT_FEATURE_EDX_NX            RT_BIT(20)
+/** EDX Bit 26 - 1 GB large page. */
+#define X86_CPUID_EXT_FEATURE_EDX_PAGE1GB       RT_BIT(26)
+/** EDX Bit 27 - RDTSCP. */
+#define X86_CPUID_EXT_FEATURE_EDX_RDTSCP        RT_BIT(27)
+/** EDX Bit 29 - AMD Long Mode/Intel-64 Instructions. */
+#define X86_CPUID_EXT_FEATURE_EDX_LONG_MODE     RT_BIT(29)
+/** @}*/
+
+/** @name CPUID AMD Feature information.
+ * CPUID query with EAX=0x80000001.
+ * @{
+ */
+/** Bit 0 - FPU - x87 FPU on Chip. */
+#define X86_CPUID_AMD_FEATURE_EDX_FPU       RT_BIT(0)
+/** Bit 1 - VME - Virtual 8086 Mode Enhancements. */
+#define X86_CPUID_AMD_FEATURE_EDX_VME       RT_BIT(1)
+/** Bit 2 - DE - Debugging extensions. */
+#define X86_CPUID_AMD_FEATURE_EDX_DE        RT_BIT(2)
+/** Bit 3 - PSE - Page Size Extension. */
+#define X86_CPUID_AMD_FEATURE_EDX_PSE       RT_BIT(3)
+/** Bit 4 - TSC - Time Stamp Counter. */
+#define X86_CPUID_AMD_FEATURE_EDX_TSC       RT_BIT(4)
+/** Bit 5 - MSR - K86 Model Specific Registers RDMSR and WRMSR Instructions. */
+#define X86_CPUID_AMD_FEATURE_EDX_MSR       RT_BIT(5)
+/** Bit 6 - PAE - Physical Address Extension. */
+#define X86_CPUID_AMD_FEATURE_EDX_PAE       RT_BIT(6)
+/** Bit 7 - MCE - Machine Check Exception. */
+#define X86_CPUID_AMD_FEATURE_EDX_MCE       RT_BIT(7)
+/** Bit 8 - CX8 - CMPXCHG8B instruction. */
+#define X86_CPUID_AMD_FEATURE_EDX_CX8       RT_BIT(8)
+/** Bit 9 - APIC - APIC On-Chip. */
+#define X86_CPUID_AMD_FEATURE_EDX_APIC      RT_BIT(9)
+/** Bit 12 - MTRR - Memory Type Range Registers. */
+#define X86_CPUID_AMD_FEATURE_EDX_MTRR      RT_BIT(12)
+/** Bit 13 - PGE - PTE Global Bit. */
+#define X86_CPUID_AMD_FEATURE_EDX_PGE       RT_BIT(13)
+/** Bit 14 - MCA - Machine Check Architecture. */
+#define X86_CPUID_AMD_FEATURE_EDX_MCA       RT_BIT(14)
+/** Bit 15 - CMOV - Conditional Move Instructions. */
+#define X86_CPUID_AMD_FEATURE_EDX_CMOV      RT_BIT(15)
+/** Bit 16 - PAT - Page Attribute Table. */
+#define X86_CPUID_AMD_FEATURE_EDX_PAT       RT_BIT(16)
+/** Bit 17 - PSE-36 - 36-bit Page Size Extension. */
+#define X86_CPUID_AMD_FEATURE_EDX_PSE36     RT_BIT(17)
+/** Bit 22 - AXMMX - AMD Extensions to MMX Instructions. */
+#define X86_CPUID_AMD_FEATURE_EDX_AXMMX     RT_BIT(22)
+/** Bit 23 - MMX - Intel MMX Technology. */
+#define X86_CPUID_AMD_FEATURE_EDX_MMX       RT_BIT(23)
+/** Bit 24 - FXSR - FXSAVE and FXRSTOR Instructions. */
+#define X86_CPUID_AMD_FEATURE_EDX_FXSR      RT_BIT(24)
+/** Bit 25 - FFXSR - AMD fast FXSAVE and FXRSTOR Instructions. */
+#define X86_CPUID_AMD_FEATURE_EDX_FFXSR     RT_BIT(25)
+/** Bit 30 - 3DNOWEXT - AMD Extensions to 3DNow. */
+#define X86_CPUID_AMD_FEATURE_EDX_3DNOW_EX  RT_BIT(30)
+/** Bit 31 - 3DNOW - AMD 3DNow. */
+#define X86_CPUID_AMD_FEATURE_EDX_3DNOW     RT_BIT(31)
+
+/** Bit 1 - CmpLegacy - Core multi-processing legacy mode. */
+#define X86_CPUID_AMD_FEATURE_ECX_CMPL      RT_BIT(1)
+/** Bit 2 - SVM - AMD VM extensions. */
+#define X86_CPUID_AMD_FEATURE_ECX_SVM       RT_BIT(2)
+/** Bit 3 - EXTAPIC - AMD extended APIC registers starting at 0x400. */
+#define X86_CPUID_AMD_FEATURE_ECX_EXT_APIC  RT_BIT(3)
+/** Bit 4 - CR8L - AMD LOCK MOV CR0 means MOV CR8. */
+#define X86_CPUID_AMD_FEATURE_ECX_CR8L      RT_BIT(4)
+/** Bit 5 - ABM - AMD Advanced bit manipulation. LZCNT instruction support. */
+#define X86_CPUID_AMD_FEATURE_ECX_ABM       RT_BIT(5)
+/** Bit 6 - SSE4A - AMD EXTRQ, INSERTQ, MOVNTSS, and MOVNTSD instruction support. */
+#define X86_CPUID_AMD_FEATURE_ECX_SSE4A     RT_BIT(6)
+/** Bit 7 - MISALIGNSSE - AMD Misaligned SSE mode. */
+#define X86_CPUID_AMD_FEATURE_ECX_MISALNSSE RT_BIT(7)
+/** Bit 8 - 3DNOWPRF - AMD PREFETCH and PREFETCHW instruction support. */
+#define X86_CPUID_AMD_FEATURE_ECX_3DNOWPRF  RT_BIT(8)
+/** Bit 9 - OSVW - AMD OS visible workaround. */
+#define X86_CPUID_AMD_FEATURE_ECX_OSVW      RT_BIT(9)
+/** Bit 10 - IBS - Instruct based sampling. */
+#define X86_CPUID_AMD_FEATURE_ECX_IBS       RT_BIT(10)
+/** Bit 11 - XOP - Extended operation support (see APM6). */
+#define X86_CPUID_AMD_FEATURE_ECX_XOP       RT_BIT(11)
+/** Bit 12 - SKINIT - AMD SKINIT: SKINIT, STGI, and DEV support. */
+#define X86_CPUID_AMD_FEATURE_ECX_SKINIT    RT_BIT(12)
+/** Bit 13 - WDT - AMD Watchdog timer support. */
+#define X86_CPUID_AMD_FEATURE_ECX_WDT       RT_BIT(13)
+/** Bit 15 - LWP - Lightweight profiling support. */
+#define X86_CPUID_AMD_FEATURE_ECX_LWP       RT_BIT(15)
+/** Bit 16 - FMA4 - Four operand FMA instruction support. */
+#define X86_CPUID_AMD_FEATURE_ECX_FMA4      RT_BIT(16)
+/** Bit 19 - NodeId - Indicates support for
+ * MSR_C001_100C[NodeId,NodesPerProcessr]. */
+#define X86_CPUID_AMD_FEATURE_ECX_NODEID    RT_BIT(19)
+/** Bit 21 - TBM - Trailing bit manipulation instruction support. */
+#define X86_CPUID_AMD_FEATURE_ECX_TBM       RT_BIT(21)
+/** Bit 22 - TopologyExtensions - . */
+#define X86_CPUID_AMD_FEATURE_ECX_TOPOEXT   RT_BIT(22)
+/** @} */
+
+
+/** @name CPUID AMD Feature information.
+ * CPUID query with EAX=0x80000007.
+ * @{
+ */
+/** Bit 0 - TS - Temperature Sensor. */
+#define X86_CPUID_AMD_ADVPOWER_EDX_TS        RT_BIT(0)
+/** Bit 1 - FID - Frequency ID Control. */
+#define X86_CPUID_AMD_ADVPOWER_EDX_FID       RT_BIT(1)
+/** Bit 2 - VID - Voltage ID Control. */
+#define X86_CPUID_AMD_ADVPOWER_EDX_VID       RT_BIT(2)
+/** Bit 3 - TTP - THERMTRIP. */
+#define X86_CPUID_AMD_ADVPOWER_EDX_TTP       RT_BIT(3)
+/** Bit 4 - TM - Hardware Thermal Control. */
+#define X86_CPUID_AMD_ADVPOWER_EDX_TM        RT_BIT(4)
+/** Bit 5 - STC - Software Thermal Control. */
+#define X86_CPUID_AMD_ADVPOWER_EDX_STC       RT_BIT(5)
+/** Bit 6 - MC - 100 Mhz Multiplier Control. */
+#define X86_CPUID_AMD_ADVPOWER_EDX_MC        RT_BIT(6)
+/** Bit 7 - HWPSTATE - Hardware P-State Control. */
+#define X86_CPUID_AMD_ADVPOWER_EDX_HWPSTATE  RT_BIT(7)
+/** Bit 8 - TSCINVAR - TSC Invariant. */
+#define X86_CPUID_AMD_ADVPOWER_EDX_TSCINVAR  RT_BIT(8)
+/** Bit 9 - CPB - TSC Invariant. */
+#define X86_CPUID_AMD_ADVPOWER_EDX_CPB       RT_BIT(9)
+/** Bit 10 - EffFreqRO - MPERF/APERF. */
+#define X86_CPUID_AMD_ADVPOWER_EDX_EFRO      RT_BIT(10)
+/** Bit 11 - PFI - Processor feedback interface (see EAX). */
+#define X86_CPUID_AMD_ADVPOWER_EDX_PFI       RT_BIT(11)
+/** Bit 12 - PA - Processor accumulator (MSR c001_007a). */
+#define X86_CPUID_AMD_ADVPOWER_EDX_PA        RT_BIT(12)
+/** @} */
+
+
+/** @name CR0
+ * @{ */
+/** Bit 0 - PE - Protection Enabled */
+#define X86_CR0_PE                          RT_BIT(0)
+#define X86_CR0_PROTECTION_ENABLE           RT_BIT(0)
+/** Bit 1 - MP - Monitor Coprocessor */
+#define X86_CR0_MP                          RT_BIT(1)
+#define X86_CR0_MONITOR_COPROCESSOR         RT_BIT(1)
+/** Bit 2 - EM - Emulation. */
+#define X86_CR0_EM                          RT_BIT(2)
+#define X86_CR0_EMULATE_FPU                 RT_BIT(2)
+/** Bit 3 - TS - Task Switch. */
+#define X86_CR0_TS                          RT_BIT(3)
+#define X86_CR0_TASK_SWITCH                 RT_BIT(3)
+/** Bit 4 - ET - Extension flag. ('hardcoded' to 1) */
+#define X86_CR0_ET                          RT_BIT(4)
+#define X86_CR0_EXTENSION_TYPE              RT_BIT(4)
+/** Bit 5 - NE - Numeric error. */
+#define X86_CR0_NE                          RT_BIT(5)
+#define X86_CR0_NUMERIC_ERROR               RT_BIT(5)
+/** Bit 16 - WP - Write Protect. */
+#define X86_CR0_WP                          RT_BIT(16)
+#define X86_CR0_WRITE_PROTECT               RT_BIT(16)
+/** Bit 18 - AM - Alignment Mask. */
+#define X86_CR0_AM                          RT_BIT(18)
+#define X86_CR0_ALIGMENT_MASK               RT_BIT(18)
+/** Bit 29 - NW - Not Write-though. */
+#define X86_CR0_NW                          RT_BIT(29)
+#define X86_CR0_NOT_WRITE_THROUGH           RT_BIT(29)
+/** Bit 30 - WP - Cache Disable. */
+#define X86_CR0_CD                          RT_BIT(30)
+#define X86_CR0_CACHE_DISABLE               RT_BIT(30)
+/** Bit 31 - PG - Paging. */
+#define X86_CR0_PG                          RT_BIT(31)
+#define X86_CR0_PAGING                      RT_BIT(31)
+/** @} */
+
+
+/** @name CR3
+ * @{ */
+/** Bit 3 - PWT - Page-level Writes Transparent. */
+#define X86_CR3_PWT                         RT_BIT(3)
+/** Bit 4 - PCD - Page-level Cache Disable. */
+#define X86_CR3_PCD                         RT_BIT(4)
+/** Bits 12-31 - - Page directory page number. */
+#define X86_CR3_PAGE_MASK                   (0xfffff000)
+/** Bits  5-31 - - PAE Page directory page number. */
+#define X86_CR3_PAE_PAGE_MASK               (0xffffffe0)
+/** Bits 12-51 - - AMD64 Page directory page number. */
+#define X86_CR3_AMD64_PAGE_MASK             UINT64_C(0x000ffffffffff000)
+/** @} */
+
+
+/** @name CR4
+ * @{ */
+/** Bit 0 - VME - Virtual-8086 Mode Extensions. */
+#define X86_CR4_VME                         RT_BIT(0)
+/** Bit 1 - PVI - Protected-Mode Virtual Interrupts. */
+#define X86_CR4_PVI                         RT_BIT(1)
+/** Bit 2 - TSD - Time Stamp Disable. */
+#define X86_CR4_TSD                         RT_BIT(2)
+/** Bit 3 - DE - Debugging Extensions. */
+#define X86_CR4_DE                          RT_BIT(3)
+/** Bit 4 - PSE - Page Size Extension. */
+#define X86_CR4_PSE                         RT_BIT(4)
+/** Bit 5 - PAE - Physical Address Extension. */
+#define X86_CR4_PAE                         RT_BIT(5)
+/** Bit 6 - MCE - Machine-Check Enable. */
+#define X86_CR4_MCE                         RT_BIT(6)
+/** Bit 7 - PGE - Page Global Enable. */
+#define X86_CR4_PGE                         RT_BIT(7)
+/** Bit 8 - PCE - Performance-Monitoring Counter Enable. */
+#define X86_CR4_PCE                         RT_BIT(8)
+/** Bit 9 - OSFXSR - Operating System Support for FXSAVE and FXRSTORE instructions. */
+#define X86_CR4_OSFXSR                      RT_BIT(9)
+/** Bit 10 - OSXMMEEXCPT - Operating System Support for Unmasked SIMD Floating-Point Exceptions. */
+#define X86_CR4_OSXMMEEXCPT                 RT_BIT(10)
+/** Bit 13 - VMXE - VMX mode is enabled. */
+#define X86_CR4_VMXE                        RT_BIT(13)
+/** Bit 14 - SMXE - Safer Mode Extensions Enabled. */
+#define X86_CR4_SMXE                        RT_BIT(14)
+/** Bit 17 - PCIDE - Process-Context Identifiers Enabled. */
+#define X86_CR4_PCIDE                       RT_BIT(17)
+/** Bit 18 - OSXSAVE - Operating System Support for XSAVE and processor
+ * extended states. */
+#define X86_CR4_OSXSAVE                     RT_BIT(18)
+/** Bit 20 - SMEP - Supervisor-mode Execution Prevention enabled. */
+#define X86_CR4_SMEP                        RT_BIT(20)
+/** Bit 21 - SMAP - Supervisor-mode Access Prevention enabled. */
+#define X86_CR4_SMAP                        RT_BIT(21)
+/** Bit 22 - PKE - Protection Key Enable. */
+#define X86_CR4_PKE                         RT_BIT(22)
+/** @} */
+
+
+/** @name DR6
+ * @{ */
+/** Bit 0 - B0 - Breakpoint 0 condition detected. */
+#define X86_DR6_B0                          RT_BIT(0)
+/** Bit 1 - B1 - Breakpoint 1 condition detected. */
+#define X86_DR6_B1                          RT_BIT(1)
+/** Bit 2 - B2 - Breakpoint 2 condition detected. */
+#define X86_DR6_B2                          RT_BIT(2)
+/** Bit 3 - B3 - Breakpoint 3 condition detected. */
+#define X86_DR6_B3                          RT_BIT(3)
+/** Mask of all the Bx bits. */
+#define X86_DR6_B_MASK                      UINT64_C(0x0000000f)
+/** Bit 13 - BD - Debug register access detected. Corresponds to the X86_DR7_GD bit. */
+#define X86_DR6_BD                          RT_BIT(13)
+/** Bit 14 - BS - Single step */
+#define X86_DR6_BS                          RT_BIT(14)
+/** Bit 15 - BT - Task switch. (TSS T bit.) */
+#define X86_DR6_BT                          RT_BIT(15)
+/** Value of DR6 after powerup/reset. */
+#define X86_DR6_INIT_VAL                    UINT64_C(0xFFFF0FF0)
+/** Bits which must be 1s in DR6. */
+#define X86_DR6_RA1_MASK                    UINT64_C(0xffff0ff0)
+/** Bits which must be 0s in DR6. */
+#define X86_DR6_RAZ_MASK                    RT_BIT_64(12)
+/** Bits which must be 0s on writes to DR6. */
+#define X86_DR6_MBZ_MASK                    UINT64_C(0xffffffff00000000)
+/** @} */
+
+/** Get the DR6.Bx bit for a the given breakpoint. */
+#define X86_DR6_B(iBp)                      RT_BIT_64(iBp)
+
+
+/** @name DR7
+ * @{ */
+/** Bit 0 - L0 - Local breakpoint enable. Cleared on task switch. */
+#define X86_DR7_L0                          RT_BIT(0)
+/** Bit 1 - G0 - Global breakpoint enable. Not cleared on task switch. */
+#define X86_DR7_G0                          RT_BIT(1)
+/** Bit 2 - L1 - Local breakpoint enable. Cleared on task switch. */
+#define X86_DR7_L1                          RT_BIT(2)
+/** Bit 3 - G1 - Global breakpoint enable. Not cleared on task switch. */
+#define X86_DR7_G1                          RT_BIT(3)
+/** Bit 4 - L2 - Local breakpoint enable. Cleared on task switch. */
+#define X86_DR7_L2                          RT_BIT(4)
+/** Bit 5 - G2 - Global breakpoint enable. Not cleared on task switch. */
+#define X86_DR7_G2                          RT_BIT(5)
+/** Bit 6 - L3 - Local breakpoint enable. Cleared on task switch. */
+#define X86_DR7_L3                          RT_BIT(6)
+/** Bit 7 - G3 - Global breakpoint enable. Not cleared on task switch. */
+#define X86_DR7_G3                          RT_BIT(7)
+/** Bit 8 - LE - Local breakpoint exact. (Not supported (read ignored) by P6 and later.) */
+#define X86_DR7_LE                          RT_BIT(8)
+/** Bit 9 - GE - Local breakpoint exact. (Not supported (read ignored) by P6 and later.) */
+#define X86_DR7_GE                          RT_BIT(9)
+
+/** L0, L1, L2, and L3.  */
+#define X86_DR7_LE_ALL                      UINT64_C(0x0000000000000055)
+/** L0, L1, L2, and L3.  */
+#define X86_DR7_GE_ALL                      UINT64_C(0x00000000000000aa)
+
+/** Bit 12 - IR (ICE) - Interrupt redirection on Pentium.  When set, the in
+ * Circuit Emulator (ICE) will break emulation on breakpoints and stuff.
+ * May cause CPU hang if enabled without ICE attached when the ICEBP/INT1
+ * instruction is executed.
+ * @see http://www.rcollins.org/secrets/DR7.html  */
+#define X86_DR7_ICE_IR                      RT_BIT(12)
+/** Bit 13 - GD - General detect enable. Enables emulators to get exceptions when
+ * any DR register is accessed. */
+#define X86_DR7_GD                          RT_BIT(13)
+/** Bit 14 - TR1 (ICE) - Code discontinuity trace for use with ICE on
+ *  Pentium. */
+#define X86_DR7_ICE_TR1                     RT_BIT(14)
+/** Bit 15 - TR2 (ICE) - Controls unknown ICE trace feature of the pentium. */
+#define X86_DR7_ICE_TR2                     RT_BIT(15)
+/** Bit 16 & 17 - R/W0 - Read write field 0. Values X86_DR7_RW_*. */
+#define X86_DR7_RW0_MASK                    (3 << 16)
+/** Bit 18 & 19 - LEN0 - Length field 0. Values X86_DR7_LEN_*. */
+#define X86_DR7_LEN0_MASK                   (3 << 18)
+/** Bit 20 & 21 - R/W1 - Read write field 0. Values X86_DR7_RW_*. */
+#define X86_DR7_RW1_MASK                    (3 << 20)
+/** Bit 22 & 23 - LEN1 - Length field 0. Values X86_DR7_LEN_*. */
+#define X86_DR7_LEN1_MASK                   (3 << 22)
+/** Bit 24 & 25 - R/W2 - Read write field 0. Values X86_DR7_RW_*. */
+#define X86_DR7_RW2_MASK                    (3 << 24)
+/** Bit 26 & 27 - LEN2 - Length field 0. Values X86_DR7_LEN_*. */
+#define X86_DR7_LEN2_MASK                   (3 << 26)
+/** Bit 28 & 29 - R/W3 - Read write field 0. Values X86_DR7_RW_*. */
+#define X86_DR7_RW3_MASK                    (3 << 28)
+/** Bit 30 & 31 - LEN3 - Length field 0. Values X86_DR7_LEN_*. */
+#define X86_DR7_LEN3_MASK                   (3 << 30)
+
+/** Bits which reads as 1s. */
+#define X86_DR7_RA1_MASK                    (RT_BIT(10))
+/** Bits which reads as zeros.  These are related to ICE (bits 12, 14, 15). */
+#define X86_DR7_RAZ_MASK                    UINT64_C(0x0000d800)
+/** Bits which must be 0s when writing to DR7. */
+#define X86_DR7_MBZ_MASK                    UINT64_C(0xffffffff00000000)
+
+/** Calcs the L bit of Nth breakpoint.
+ * @param   iBp     The breakpoint number [0..3].
+ */
+#define X86_DR7_L(iBp)                      ( UINT32_C(1) << (iBp * 2) )
+
+/** Calcs the G bit of Nth breakpoint.
+ * @param   iBp     The breakpoint number [0..3].
+ */
+#define X86_DR7_G(iBp)                      ( UINT32_C(1) << (iBp * 2 + 1) )
+
+/** Calcs the L and G bits of Nth breakpoint.
+ * @param   iBp     The breakpoint number [0..3].
+ */
+#define X86_DR7_L_G(iBp)                    ( UINT32_C(3) << (iBp * 2) )
+
+/** @name Read/Write values.
+ * @{ */
+/** Break on instruction fetch only. */
+#define X86_DR7_RW_EO                       0U
+/** Break on write only. */
+#define X86_DR7_RW_WO                       1U
+/** Break on I/O read/write. This is only defined if CR4.DE is set. */
+#define X86_DR7_RW_IO                       2U
+/** Break on read or write (but not instruction fetches). */
+#define X86_DR7_RW_RW                       3U
+/** @} */
+
+/** Shifts a X86_DR7_RW_* value to its right place.
+ * @param   iBp     The breakpoint number [0..3].
+ * @param   fRw     One of the X86_DR7_RW_* value.
+ */
+#define X86_DR7_RW(iBp, fRw)                ( (fRw) << ((iBp) * 4 + 16) )
+
+/** Fetch the R/Wx bits for a given breakpoint (so it can be compared with
+ * one of the X86_DR7_RW_XXX constants).
+ *
+ * @returns X86_DR7_RW_XXX
+ * @param   uDR7    DR7 value
+ * @param   iBp     The breakpoint number [0..3].
+ */
+#define X86_DR7_GET_RW(uDR7, iBp)            ( ( (uDR7) >> ((iBp) * 4 + 16) ) & UINT32_C(3) )
+
+/** R/W0, R/W1, R/W2, and R/W3. */
+#define X86_DR7_RW_ALL_MASKS                UINT32_C(0x33330000)
+
+#ifndef VBOX_FOR_DTRACE_LIB
+/** Checks if there are any I/O breakpoint types configured in the RW
+ * registers.  Does NOT check if these are enabled, sorry. */
+# define X86_DR7_ANY_RW_IO(uDR7) \
+    (   (    UINT32_C(0x22220000) & (uDR7) ) /* any candidates? */ \
+     && ( ( (UINT32_C(0x22220000) & (uDR7) ) >> 1 )  &  ~(uDR7) ) )
+AssertCompile(X86_DR7_ANY_RW_IO(UINT32_C(0x33330000)) == 0);
+AssertCompile(X86_DR7_ANY_RW_IO(UINT32_C(0x22220000)) == 1);
+AssertCompile(X86_DR7_ANY_RW_IO(UINT32_C(0x32320000)) == 1);
+AssertCompile(X86_DR7_ANY_RW_IO(UINT32_C(0x23230000)) == 1);
+AssertCompile(X86_DR7_ANY_RW_IO(UINT32_C(0x00000000)) == 0);
+AssertCompile(X86_DR7_ANY_RW_IO(UINT32_C(0x00010000)) == 0);
+AssertCompile(X86_DR7_ANY_RW_IO(UINT32_C(0x00020000)) == 1);
+AssertCompile(X86_DR7_ANY_RW_IO(UINT32_C(0x00030000)) == 0);
+AssertCompile(X86_DR7_ANY_RW_IO(UINT32_C(0x00040000)) == 0);
+#endif /* !VBOX_FOR_DTRACE_LIB */
+
+/** @name Length values.
+ * @{ */
+#define X86_DR7_LEN_BYTE                    0U
+#define X86_DR7_LEN_WORD                    1U
+#define X86_DR7_LEN_QWORD                   2U /**< AMD64 long mode only. */
+#define X86_DR7_LEN_DWORD                   3U
+/** @} */
+
+/** Shifts a X86_DR7_LEN_* value to its right place.
+ * @param   iBp     The breakpoint number [0..3].
+ * @param   cb      One of the X86_DR7_LEN_* values.
+ */
+#define X86_DR7_LEN(iBp, cb)                ( (cb) << ((iBp) * 4 + 18) )
+
+/** Fetch the breakpoint length bits from the DR7 value.
+ * @param   uDR7    DR7 value
+ * @param   iBp     The breakpoint number [0..3].
+ */
+#define X86_DR7_GET_LEN(uDR7, iBp)          ( ( (uDR7) >> ((iBp) * 4 + 18) ) & UINT32_C(0x3) )
+
+/** Mask used to check if any breakpoints are enabled. */
+#define X86_DR7_ENABLED_MASK                UINT32_C(0x000000ff)
+
+/** LEN0, LEN1, LEN2, and LEN3. */
+#define X86_DR7_LEN_ALL_MASKS               UINT32_C(0xcccc0000)
+/** R/W0, R/W1, R/W2, R/W3,LEN0, LEN1, LEN2, and LEN3. */
+#define X86_DR7_RW_LEN_ALL_MASKS            UINT32_C(0xffff0000)
+
+/** Value of DR7 after powerup/reset. */
+#define X86_DR7_INIT_VAL                    0x400
+/** @} */
+
+
+/** @name Machine Specific Registers
+ * @{
+ */
+/** Machine check address register (P5). */
+#define MSR_P5_MC_ADDR                      UINT32_C(0x00000000)
+/** Machine check type register (P5). */
+#define MSR_P5_MC_TYPE                      UINT32_C(0x00000001)
+/** Time Stamp Counter. */
+#define MSR_IA32_TSC                        0x10
+#define MSR_IA32_CESR                       UINT32_C(0x00000011)
+#define MSR_IA32_CTR0                       UINT32_C(0x00000012)
+#define MSR_IA32_CTR1                       UINT32_C(0x00000013)
+
+#define MSR_IA32_PLATFORM_ID                0x17
+
+#ifndef MSR_IA32_APICBASE /* qemu cpu.h kludge */
+# define MSR_IA32_APICBASE                  0x1b
+/** Local APIC enabled. */
+# define MSR_IA32_APICBASE_EN               RT_BIT_64(11)
+/** X2APIC enabled (requires the EN bit to be set). */
+# define MSR_IA32_APICBASE_EXTD             RT_BIT_64(10)
+/** The processor is the boot strap processor (BSP). */
+# define MSR_IA32_APICBASE_BSP              RT_BIT_64(8)
+/** Minimum base address mask, consult CPUID leaf 0x80000008 for the actual
+ *  width. */
+# define MSR_IA32_APICBASE_BASE_MIN         UINT64_C(0x0000000ffffff000)
+#endif
+
+/** Undocumented intel MSR for reporting thread and core counts.
+ * Judging from the XNU sources, it seems to be introduced in Nehalem. The
+ * first 16 bits is the thread count. The next 16 bits the core count, except
+ * on Westmere where it seems it's only the next 4 bits for some reason. */
+#define MSR_CORE_THREAD_COUNT               0x35
+
+/** CPU Feature control. */
+#define MSR_IA32_FEATURE_CONTROL            0x3A
+#define MSR_IA32_FEATURE_CONTROL_LOCK       RT_BIT(0)
+#define MSR_IA32_FEATURE_CONTROL_SMX_VMXON  RT_BIT(1)
+#define MSR_IA32_FEATURE_CONTROL_VMXON      RT_BIT(2)
+
+/** Per-processor TSC adjust MSR. */
+#define MSR_IA32_TSC_ADJUST                 0x3B
+
+/** BIOS update trigger (microcode update). */
+#define MSR_IA32_BIOS_UPDT_TRIG             0x79
+
+/** BIOS update signature (microcode). */
+#define MSR_IA32_BIOS_SIGN_ID               0x8B
+
+/** SMM monitor control. */
+#define MSR_IA32_SMM_MONITOR_CTL            0x9B
+
+/** General performance counter no. 0. */
+#define MSR_IA32_PMC0                       0xC1
+/** General performance counter no. 1. */
+#define MSR_IA32_PMC1                       0xC2
+/** General performance counter no. 2. */
+#define MSR_IA32_PMC2                       0xC3
+/** General performance counter no. 3. */
+#define MSR_IA32_PMC3                       0xC4
+
+/** Nehalem power control. */
+#define MSR_IA32_PLATFORM_INFO              0xCE
+
+/** Get FSB clock status (Intel-specific). */
+#define MSR_IA32_FSB_CLOCK_STS              0xCD
+
+/** C-State configuration control. Intel specific: Nehalem, Sandy Bridge. */
+#define MSR_PKG_CST_CONFIG_CONTROL          UINT32_C(0x000000e2)
+
+/** C0 Maximum Frequency Clock Count */
+#define MSR_IA32_MPERF                      0xE7
+/** C0 Actual Frequency Clock Count */
+#define MSR_IA32_APERF                      0xE8
+
+/** MTRR Capabilities. */
+#define MSR_IA32_MTRR_CAP                   0xFE
+
+/** Cache control/info. */
+#define MSR_BBL_CR_CTL3                     UINT32_C(0x11e)
+
+#ifndef MSR_IA32_SYSENTER_CS /* qemu cpu.h kludge */
+/** SYSENTER_CS - the R0 CS, indirectly giving R0 SS, R3 CS and R3 DS.
+ * R0 SS == CS + 8
+ * R3 CS == CS + 16
+ * R3 SS == CS + 24
+ */
+#define MSR_IA32_SYSENTER_CS                0x174
+/** SYSENTER_ESP - the R0 ESP. */
+#define MSR_IA32_SYSENTER_ESP               0x175
+/** SYSENTER_EIP - the R0 EIP. */
+#define MSR_IA32_SYSENTER_EIP               0x176
+#endif
+
+/** Machine Check Global Capabilities Register. */
+#define MSR_IA32_MCG_CAP                    0x179
+/** Machine Check Global Status Register. */
+#define MSR_IA32_MCG_STATUS                 0x17A
+/** Machine Check Global Control Register. */
+#define MSR_IA32_MCG_CTRL                   0x17B
+
+/** Page Attribute Table. */
+#define MSR_IA32_CR_PAT                     0x277
+
+/** Performance counter MSRs. (Intel only) */
+#define MSR_IA32_PERFEVTSEL0                0x186
+#define MSR_IA32_PERFEVTSEL1                0x187
+/** Flexible ratio, seems to be undocumented, used by XNU (tsc.c).
+ * The 16th bit whether flex ratio is being used, in which case bits 15:8
+ * holds a ratio that Apple takes for TSC granularity.
+ *
+ * @note This MSR conflicts the P4 MSR_MCG_R12 register. */
+#define MSR_FLEX_RATIO                      0x194
+/** Performance state value and starting with Intel core more.
+ * Apple uses the >=core features to determine TSC granularity on older CPUs. */
+#define MSR_IA32_PERF_STATUS                0x198
+#define MSR_IA32_PERF_CTL                   0x199
+#define MSR_IA32_THERM_STATUS               0x19c
+
+/** Enable misc. processor features (R/W). */
+#define MSR_IA32_MISC_ENABLE                   0x1A0
+/** Enable fast-strings feature (for REP MOVS and REP STORS). */
+#define MSR_IA32_MISC_ENABLE_FAST_STRINGS      RT_BIT_64(0)
+/** Automatic Thermal Control Circuit Enable (R/W). */
+#define MSR_IA32_MISC_ENABLE_TCC               RT_BIT_64(3)
+/** Performance Monitoring Available (R). */
+#define MSR_IA32_MISC_ENABLE_PERF_MON          RT_BIT_64(7)
+/** Branch Trace Storage Unavailable (R/O). */
+#define MSR_IA32_MISC_ENABLE_BTS_UNAVAIL       RT_BIT_64(11)
+/** Precise Event Based Sampling (PEBS) Unavailable (R/O). */
+#define MSR_IA32_MISC_ENABLE_PEBS_UNAVAIL      RT_BIT_64(12)
+/** Enhanced Intel SpeedStep Technology Enable (R/W). */
+#define MSR_IA32_MISC_ENABLE_SST_ENABLE        RT_BIT_64(16)
+/** If MONITOR/MWAIT is supported (R/W). */
+#define MSR_IA32_MISC_ENABLE_MONITOR           RT_BIT_64(18)
+/** Limit CPUID Maxval to 3 leafs (R/W). */
+#define MSR_IA32_MISC_ENABLE_LIMIT_CPUID       RT_BIT_64(22)
+/** When set to 1, xTPR messages are disabled (R/W). */
+#define MSR_IA32_MISC_ENABLE_XTPR_MSG_DISABLE  RT_BIT_64(23)
+/** When set to 1, the Execute Disable Bit feature (XD Bit) is disabled (R/W). */
+#define MSR_IA32_MISC_ENABLE_XD_DISABLE        RT_BIT_64(34)
+
+/** Trace/Profile Resource Control (R/W) */
+#define MSR_IA32_DEBUGCTL                   UINT32_C(0x000001d9)
+/** The number (0..3 or 0..15) of the last branch record register on P4 and
+ * related Xeons. */
+#define MSR_P4_LASTBRANCH_TOS               UINT32_C(0x000001da)
+/** @name Last branch registers for P4 and Xeon, models 0 thru 2.
+ * @{ */
+#define MSR_P4_LASTBRANCH_0                 UINT32_C(0x000001db)
+#define MSR_P4_LASTBRANCH_1                 UINT32_C(0x000001dc)
+#define MSR_P4_LASTBRANCH_2                 UINT32_C(0x000001dd)
+#define MSR_P4_LASTBRANCH_3                 UINT32_C(0x000001de)
+/** @} */
+
+
+#define IA32_MTRR_PHYSBASE0                 0x200
+#define IA32_MTRR_PHYSMASK0                 0x201
+#define IA32_MTRR_PHYSBASE1                 0x202
+#define IA32_MTRR_PHYSMASK1                 0x203
+#define IA32_MTRR_PHYSBASE2                 0x204
+#define IA32_MTRR_PHYSMASK2                 0x205
+#define IA32_MTRR_PHYSBASE3                 0x206
+#define IA32_MTRR_PHYSMASK3                 0x207
+#define IA32_MTRR_PHYSBASE4                 0x208
+#define IA32_MTRR_PHYSMASK4                 0x209
+#define IA32_MTRR_PHYSBASE5                 0x20a
+#define IA32_MTRR_PHYSMASK5                 0x20b
+#define IA32_MTRR_PHYSBASE6                 0x20c
+#define IA32_MTRR_PHYSMASK6                 0x20d
+#define IA32_MTRR_PHYSBASE7                 0x20e
+#define IA32_MTRR_PHYSMASK7                 0x20f
+#define IA32_MTRR_PHYSBASE8                 0x210
+#define IA32_MTRR_PHYSMASK8                 0x211
+#define IA32_MTRR_PHYSBASE9                 0x212
+#define IA32_MTRR_PHYSMASK9                 0x213
+
+/** Fixed range MTRRs.
+ * @{  */
+#define IA32_MTRR_FIX64K_00000              0x250
+#define IA32_MTRR_FIX16K_80000              0x258
+#define IA32_MTRR_FIX16K_A0000              0x259
+#define IA32_MTRR_FIX4K_C0000               0x268
+#define IA32_MTRR_FIX4K_C8000               0x269
+#define IA32_MTRR_FIX4K_D0000               0x26a
+#define IA32_MTRR_FIX4K_D8000               0x26b
+#define IA32_MTRR_FIX4K_E0000               0x26c
+#define IA32_MTRR_FIX4K_E8000               0x26d
+#define IA32_MTRR_FIX4K_F0000               0x26e
+#define IA32_MTRR_FIX4K_F8000               0x26f
+/** @}  */
+
+/** MTRR Default Range. */
+#define MSR_IA32_MTRR_DEF_TYPE              0x2FF
+
+#define MSR_IA32_MC0_CTL                    0x400
+#define MSR_IA32_MC0_STATUS                 0x401
+
+/** Basic VMX information. */
+#define MSR_IA32_VMX_BASIC_INFO             0x480
+/** Allowed settings for pin-based VM execution controls */
+#define MSR_IA32_VMX_PINBASED_CTLS          0x481
+/** Allowed settings for proc-based VM execution controls */
+#define MSR_IA32_VMX_PROCBASED_CTLS         0x482
+/** Allowed settings for the VMX exit controls. */
+#define MSR_IA32_VMX_EXIT_CTLS              0x483
+/** Allowed settings for the VMX entry controls. */
+#define MSR_IA32_VMX_ENTRY_CTLS             0x484
+/** Misc VMX info. */
+#define MSR_IA32_VMX_MISC                   0x485
+/** Fixed cleared bits in CR0. */
+#define MSR_IA32_VMX_CR0_FIXED0             0x486
+/** Fixed set bits in CR0. */
+#define MSR_IA32_VMX_CR0_FIXED1             0x487
+/** Fixed cleared bits in CR4. */
+#define MSR_IA32_VMX_CR4_FIXED0             0x488
+/** Fixed set bits in CR4. */
+#define MSR_IA32_VMX_CR4_FIXED1             0x489
+/** Information for enumerating fields in the VMCS. */
+#define MSR_IA32_VMX_VMCS_ENUM              0x48A
+/** Allowed settings for the VM-functions controls. */
+#define MSR_IA32_VMX_VMFUNC                 0x491
+/** Allowed settings for secondary proc-based VM execution controls */
+#define MSR_IA32_VMX_PROCBASED_CTLS2        0x48B
+/** EPT capabilities. */
+#define MSR_IA32_VMX_EPT_VPID_CAP           0x48C
+/** DS Save Area (R/W). */
+#define MSR_IA32_DS_AREA                    0x600
+/** Running Average Power Limit (RAPL) power units. */
+#define MSR_RAPL_POWER_UNIT                 0x606
+
+/** X2APIC MSR range start. */
+#define MSR_IA32_X2APIC_START               0x800
+/** X2APIC MSR -  APIC ID Register. */
+#define MSR_IA32_X2APIC_ID                  0x802
+/** X2APIC MSR -  APIC Version Register. */
+#define MSR_IA32_X2APIC_VERSION             0x803
+/** X2APIC MSR -  Task Priority Register. */
+#define MSR_IA32_X2APIC_TPR                 0x808
+/** X2APIC MSR -  Processor Priority register. */
+#define MSR_IA32_X2APIC_PPR                 0x80A
+/** X2APIC MSR -  End Of Interrupt register. */
+#define MSR_IA32_X2APIC_EOI                 0x80B
+/** X2APIC MSR -  Logical Destination Register. */
+#define MSR_IA32_X2APIC_LDR                 0x80D
+/** X2APIC MSR -  Spurious Interrupt Vector Register. */
+#define MSR_IA32_X2APIC_SVR                 0x80F
+/** X2APIC MSR -  In-service Register (bits 31:0). */
+#define MSR_IA32_X2APIC_ISR0                0x810
+/** X2APIC MSR -  In-service Register (bits 63:32). */
+#define MSR_IA32_X2APIC_ISR1                0x811
+/** X2APIC MSR -  In-service Register (bits 95:64). */
+#define MSR_IA32_X2APIC_ISR2                0x812
+/** X2APIC MSR -  In-service Register (bits 127:96). */
+#define MSR_IA32_X2APIC_ISR3                0x813
+/** X2APIC MSR -  In-service Register (bits 159:128). */
+#define MSR_IA32_X2APIC_ISR4                0x814
+/** X2APIC MSR -  In-service Register (bits 191:160). */
+#define MSR_IA32_X2APIC_ISR5                0x815
+/** X2APIC MSR -  In-service Register (bits 223:192). */
+#define MSR_IA32_X2APIC_ISR6                0x816
+/** X2APIC MSR -  In-service Register (bits 255:224). */
+#define MSR_IA32_X2APIC_ISR7                0x817
+/** X2APIC MSR -  Trigger Mode Register (bits 31:0). */
+#define MSR_IA32_X2APIC_TMR0                0x818
+/** X2APIC MSR -  Trigger Mode Register (bits 63:32). */
+#define MSR_IA32_X2APIC_TMR1                0x819
+/** X2APIC MSR -  Trigger Mode Register (bits 95:64). */
+#define MSR_IA32_X2APIC_TMR2                0x81A
+/** X2APIC MSR -  Trigger Mode Register (bits 127:96). */
+#define MSR_IA32_X2APIC_TMR3                0x81B
+/** X2APIC MSR -  Trigger Mode Register (bits 159:128). */
+#define MSR_IA32_X2APIC_TMR4                0x81C
+/** X2APIC MSR -  Trigger Mode Register (bits 191:160). */
+#define MSR_IA32_X2APIC_TMR5                0x81D
+/** X2APIC MSR -  Trigger Mode Register (bits 223:192). */
+#define MSR_IA32_X2APIC_TMR6                0x81E
+/** X2APIC MSR -  Trigger Mode Register (bits 255:224). */
+#define MSR_IA32_X2APIC_TMR7                0x81F
+/** X2APIC MSR -  Interrupt Request Register (bits 31:0). */
+#define MSR_IA32_X2APIC_IRR0                0x820
+/** X2APIC MSR -  Interrupt Request Register (bits 63:32). */
+#define MSR_IA32_X2APIC_IRR1                0x821
+/** X2APIC MSR -  Interrupt Request Register (bits 95:64). */
+#define MSR_IA32_X2APIC_IRR2                0x822
+/** X2APIC MSR -  Interrupt Request Register (bits 127:96). */
+#define MSR_IA32_X2APIC_IRR3                0x823
+/** X2APIC MSR -  Interrupt Request Register (bits 159:128). */
+#define MSR_IA32_X2APIC_IRR4                0x824
+/** X2APIC MSR -  Interrupt Request Register (bits 191:160). */
+#define MSR_IA32_X2APIC_IRR5                0x825
+/** X2APIC MSR -  Interrupt Request Register (bits 223:192). */
+#define MSR_IA32_X2APIC_IRR6                0x826
+/** X2APIC MSR -  Interrupt Request Register (bits 255:224). */
+#define MSR_IA32_X2APIC_IRR7                0x827
+/** X2APIC MSR -  Error Status Register. */
+#define MSR_IA32_X2APIC_ESR                 0x828
+/** X2APIC MSR - LVT CMCI Register. */
+#define MSR_IA32_X2APIC_LVT_CMCI            0x82F
+/** X2APIC MSR -  Interrupt Command Register. */
+#define MSR_IA32_X2APIC_ICR                 0x830
+/** X2APIC MSR -  LVT Timer Register. */
+#define MSR_IA32_X2APIC_LVT_TIMER           0x832
+/** X2APIC MSR -  LVT Thermal Sensor Register. */
+#define MSR_IA32_X2APIC_LVT_THERMAL         0x833
+/** X2APIC MSR -  LVT Performance Counter Register. */
+#define MSR_IA32_X2APIC_LVT_PERF            0x834
+/** X2APIC MSR -  LVT LINT0 Register. */
+#define MSR_IA32_X2APIC_LVT_LINT0           0x835
+/** X2APIC MSR -  LVT LINT1 Register. */
+#define MSR_IA32_X2APIC_LVT_LINT1           0x836
+/** X2APIC MSR -  LVT Error Register . */
+#define MSR_IA32_X2APIC_LVT_ERROR           0x837
+/** X2APIC MSR -  Timer Initial Count Register. */
+#define MSR_IA32_X2APIC_TIMER_ICR           0x838
+/** X2APIC MSR -  Timer Current Count Register. */
+#define MSR_IA32_X2APIC_TIMER_CCR           0x839
+/** X2APIC MSR -  Timer Divide Configuration Register. */
+#define MSR_IA32_X2APIC_TIMER_DFR           0x83E
+/** X2APIC MSR - Self IPI. */
+#define MSR_IA32_X2APIC_SELF_IPI            0x83F
+/** X2APIC MSR range end. */
+#define MSR_IA32_X2APIC_END                 0xBFF
+
+/** K6 EFER - Extended Feature Enable Register. */
+#define MSR_K6_EFER                         UINT32_C(0xc0000080)
+/** @todo document EFER */
+/** Bit 0 - SCE - System call extensions (SYSCALL / SYSRET). (R/W) */
+#define  MSR_K6_EFER_SCE                     RT_BIT(0)
+/** Bit 8 - LME - Long mode enabled. (R/W) */
+#define  MSR_K6_EFER_LME                     RT_BIT(8)
+/** Bit 10 - LMA - Long mode active. (R) */
+#define  MSR_K6_EFER_LMA                     RT_BIT(10)
+/** Bit 11 - NXE - No-Execute Page Protection Enabled. (R/W) */
+#define  MSR_K6_EFER_NXE                     RT_BIT(11)
+/** Bit 12 - SVME - Secure VM Extension Enabled. (R/W) */
+#define  MSR_K6_EFER_SVME                    RT_BIT(12)
+/** Bit 13 - LMSLE - Long Mode Segment Limit Enable. (R/W?) */
+#define  MSR_K6_EFER_LMSLE                   RT_BIT(13)
+/** Bit 14 - FFXSR - Fast FXSAVE / FXRSTOR (skip XMM*). (R/W) */
+#define  MSR_K6_EFER_FFXSR                   RT_BIT(14)
+/** Bit 15 - TCE - Translation Cache Extension. (R/W) */
+#define  MSR_K6_EFER_TCE                     RT_BIT(15)
+/** K6 STAR - SYSCALL/RET targets. */
+#define MSR_K6_STAR                         UINT32_C(0xc0000081)
+/** Shift value for getting the SYSRET CS and SS value. */
+#define  MSR_K6_STAR_SYSRET_CS_SS_SHIFT     48
+/** Shift value for getting the SYSCALL CS and SS value. */
+#define  MSR_K6_STAR_SYSCALL_CS_SS_SHIFT    32
+/** Selector mask for use after shifting. */
+#define  MSR_K6_STAR_SEL_MASK               UINT32_C(0xffff)
+/** The mask which give the SYSCALL EIP. */
+#define  MSR_K6_STAR_SYSCALL_EIP_MASK       UINT32_C(0xffffffff)
+/** K6 WHCR - Write Handling Control Register. */
+#define MSR_K6_WHCR                         UINT32_C(0xc0000082)
+/** K6 UWCCR - UC/WC Cacheability Control Register. */
+#define MSR_K6_UWCCR                        UINT32_C(0xc0000085)
+/** K6 PSOR - Processor State Observability Register. */
+#define MSR_K6_PSOR                         UINT32_C(0xc0000087)
+/** K6 PFIR - Page Flush/Invalidate Register. */
+#define MSR_K6_PFIR                         UINT32_C(0xc0000088)
+
+/** Performance counter MSRs. (AMD only) */
+#define MSR_K7_EVNTSEL0                     UINT32_C(0xc0010000)
+#define MSR_K7_EVNTSEL1                     UINT32_C(0xc0010001)
+#define MSR_K7_EVNTSEL2                     UINT32_C(0xc0010002)
+#define MSR_K7_EVNTSEL3                     UINT32_C(0xc0010003)
+#define MSR_K7_PERFCTR0                     UINT32_C(0xc0010004)
+#define MSR_K7_PERFCTR1                     UINT32_C(0xc0010005)
+#define MSR_K7_PERFCTR2                     UINT32_C(0xc0010006)
+#define MSR_K7_PERFCTR3                     UINT32_C(0xc0010007)
+
+/** K8 LSTAR - Long mode SYSCALL target (RIP). */
+#define MSR_K8_LSTAR                        UINT32_C(0xc0000082)
+/** K8 CSTAR - Compatibility mode SYSCALL target (RIP). */
+#define MSR_K8_CSTAR                        UINT32_C(0xc0000083)
+/** K8 SF_MASK - SYSCALL flag mask. (aka SFMASK) */
+#define MSR_K8_SF_MASK                      UINT32_C(0xc0000084)
+/** K8 FS.base - The 64-bit base FS register. */
+#define MSR_K8_FS_BASE                      UINT32_C(0xc0000100)
+/** K8 GS.base - The 64-bit base GS register. */
+#define MSR_K8_GS_BASE                      UINT32_C(0xc0000101)
+/** K8 KernelGSbase - Used with SWAPGS. */
+#define MSR_K8_KERNEL_GS_BASE               UINT32_C(0xc0000102)
+/** K8 TSC_AUX - Used with RDTSCP. */
+#define MSR_K8_TSC_AUX                      UINT32_C(0xc0000103)
+#define MSR_K8_SYSCFG                       UINT32_C(0xc0010010)
+#define MSR_K8_HWCR                         UINT32_C(0xc0010015)
+#define MSR_K8_IORRBASE0                    UINT32_C(0xc0010016)
+#define MSR_K8_IORRMASK0                    UINT32_C(0xc0010017)
+#define MSR_K8_IORRBASE1                    UINT32_C(0xc0010018)
+#define MSR_K8_IORRMASK1                    UINT32_C(0xc0010019)
+#define MSR_K8_TOP_MEM1                     UINT32_C(0xc001001a)
+#define MSR_K8_TOP_MEM2                     UINT32_C(0xc001001d)
+/** North bridge config? See BIOS & Kernel dev guides for
+ * details. */
+#define MSR_K8_NB_CFG                       UINT32_C(0xc001001f)
+
+/** Hypertransport interrupt pending register.
+ * "BIOS and Kernel Developer's Guide for AMD NPT Family 0Fh Processors" */
+#define MSR_K8_INT_PENDING                  UINT32_C(0xc0010055)
+#define MSR_K8_VM_CR                        UINT32_C(0xc0010114)
+#define MSR_K8_VM_CR_SVM_DISABLE            RT_BIT(4)
+
+#define MSR_K8_IGNNE                        UINT32_C(0xc0010115)
+#define MSR_K8_SMM_CTL                      UINT32_C(0xc0010116)
+/** SVM - VM_HSAVE_PA - Physical address for saving and restoring
+ *                      host state during world switch. */
+#define MSR_K8_VM_HSAVE_PA                  UINT32_C(0xc0010117)
+
+/** @} */
+
+
+/** @name Page Table / Directory / Directory Pointers / L4.
+ * @{
+ */
+
+/** Page table/directory  entry as an unsigned integer. */
+typedef uint32_t X86PGUINT;
+/** Pointer to a page table/directory table entry as an unsigned integer. */
+typedef X86PGUINT *PX86PGUINT;
+/** Pointer to an const page table/directory table entry as an unsigned integer. */
+typedef X86PGUINT const *PCX86PGUINT;
+
+/** Number of entries in a 32-bit PT/PD. */
+#define X86_PG_ENTRIES                      1024
+
+
+/** PAE page table/page directory/pdpt/l4/l5 entry as an unsigned integer. */
+typedef uint64_t X86PGPAEUINT;
+/** Pointer to a PAE page table/page directory/pdpt/l4/l5 entry as an unsigned integer. */
+typedef X86PGPAEUINT *PX86PGPAEUINT;
+/** Pointer to an const PAE page table/page directory/pdpt/l4/l5 entry as an unsigned integer. */
+typedef X86PGPAEUINT const *PCX86PGPAEUINT;
+
+/** Number of entries in a PAE PT/PD. */
+#define X86_PG_PAE_ENTRIES                  512
+/** Number of entries in a PAE PDPT. */
+#define X86_PG_PAE_PDPE_ENTRIES             4
+
+/** Number of entries in an AMD64 PT/PD/PDPT/L4/L5. */
+#define X86_PG_AMD64_ENTRIES                X86_PG_PAE_ENTRIES
+/** Number of entries in an AMD64 PDPT.
+ * Just for complementing X86_PG_PAE_PDPE_ENTRIES, using X86_PG_AMD64_ENTRIES for this is fine too. */
+#define X86_PG_AMD64_PDPE_ENTRIES           X86_PG_AMD64_ENTRIES
+
+/** The size of a 4KB page. */
+#define X86_PAGE_4K_SIZE                    _4K
+/** The page shift of a 4KB page. */
+#define X86_PAGE_4K_SHIFT                   12
+/** The 4KB page offset mask. */
+#define X86_PAGE_4K_OFFSET_MASK             0xfff
+/** The 4KB page base mask for virtual addresses. */
+#define X86_PAGE_4K_BASE_MASK               0xfffffffffffff000ULL
+/** The 4KB page base mask for virtual addresses - 32bit version. */
+#define X86_PAGE_4K_BASE_MASK_32            0xfffff000U
+
+/** The size of a 2MB page. */
+#define X86_PAGE_2M_SIZE                    _2M
+/** The page shift of a 2MB page. */
+#define X86_PAGE_2M_SHIFT                   21
+/** The 2MB page offset mask. */
+#define X86_PAGE_2M_OFFSET_MASK             0x001fffff
+/** The 2MB page base mask for virtual addresses. */
+#define X86_PAGE_2M_BASE_MASK               0xffffffffffe00000ULL
+/** The 2MB page base mask for virtual addresses - 32bit version. */
+#define X86_PAGE_2M_BASE_MASK_32            0xffe00000U
+
+/** The size of a 4MB page. */
+#define X86_PAGE_4M_SIZE                    _4M
+/** The page shift of a 4MB page. */
+#define X86_PAGE_4M_SHIFT                   22
+/** The 4MB page offset mask. */
+#define X86_PAGE_4M_OFFSET_MASK             0x003fffff
+/** The 4MB page base mask for virtual addresses. */
+#define X86_PAGE_4M_BASE_MASK               0xffffffffffc00000ULL
+/** The 4MB page base mask for virtual addresses - 32bit version. */
+#define X86_PAGE_4M_BASE_MASK_32            0xffc00000U
+
+/**
+ * Check if the given address is canonical.
+ */
+#define X86_IS_CANONICAL(a_u64Addr)         ((uint64_t)(a_u64Addr) + UINT64_C(0x800000000000) < UINT64_C(0x1000000000000))
+
+
+/** @name Page Table Entry
+ * @{
+ */
+/** Bit 0 -  P  - Present bit. */
+#define X86_PTE_BIT_P                       0
+/** Bit 1 - R/W - Read (clear) / Write (set) bit. */
+#define X86_PTE_BIT_RW                      1
+/** Bit 2 - U/S - User (set) / Supervisor (clear) bit. */
+#define X86_PTE_BIT_US                      2
+/** Bit 3 - PWT - Page level write thru bit. */
+#define X86_PTE_BIT_PWT                     3
+/** Bit 4 - PCD - Page level cache disable bit. */
+#define X86_PTE_BIT_PCD                     4
+/** Bit 5 -  A  - Access bit. */
+#define X86_PTE_BIT_A                       5
+/** Bit 6 -  D  - Dirty bit. */
+#define X86_PTE_BIT_D                       6
+/** Bit 7 - PAT - Page Attribute Table index bit. Reserved and 0 if not supported. */
+#define X86_PTE_BIT_PAT                     7
+/** Bit 8 -  G  - Global flag. */
+#define X86_PTE_BIT_G                       8
+
+/** Bit 0 -  P  - Present bit mask. */
+#define X86_PTE_P                           RT_BIT(0)
+/** Bit 1 - R/W - Read (clear) / Write (set) bit mask. */
+#define X86_PTE_RW                          RT_BIT(1)
+/** Bit 2 - U/S - User (set) / Supervisor (clear) bit mask. */
+#define X86_PTE_US                          RT_BIT(2)
+/** Bit 3 - PWT - Page level write thru bit mask. */
+#define X86_PTE_PWT                         RT_BIT(3)
+/** Bit 4 - PCD - Page level cache disable bit mask. */
+#define X86_PTE_PCD                         RT_BIT(4)
+/** Bit 5 -  A  - Access bit mask. */
+#define X86_PTE_A                           RT_BIT(5)
+/** Bit 6 -  D  - Dirty bit mask. */
+#define X86_PTE_D                           RT_BIT(6)
+/** Bit 7 - PAT - Page Attribute Table index bit mask. Reserved and 0 if not supported. */
+#define X86_PTE_PAT                         RT_BIT(7)
+/** Bit 8 -  G  - Global bit mask. */
+#define X86_PTE_G                           RT_BIT(8)
+
+/** Bits 9-11 - - Available for use to system software. */
+#define X86_PTE_AVL_MASK                    (RT_BIT(9) | RT_BIT(10) | RT_BIT(11))
+/** Bits 12-31 - - Physical Page number of the next level. */
+#define X86_PTE_PG_MASK                     ( 0xfffff000 )
+
+/** Bits 12-51 - - PAE - Physical Page number of the next level. */
+#define X86_PTE_PAE_PG_MASK                 UINT64_C(0x000ffffffffff000)
+/** Bits 63 - NX - PAE/LM - No execution flag. */
+#define X86_PTE_PAE_NX                      RT_BIT_64(63)
+/** Bits 62-52 - - PAE - MBZ bits when NX is active. */
+#define X86_PTE_PAE_MBZ_MASK_NX             UINT64_C(0x7ff0000000000000)
+/** Bits 63-52 - - PAE - MBZ bits when no NX. */
+#define X86_PTE_PAE_MBZ_MASK_NO_NX          UINT64_C(0xfff0000000000000)
+/** No bits -    - LM  - MBZ bits when NX is active. */
+#define X86_PTE_LM_MBZ_MASK_NX              UINT64_C(0x0000000000000000)
+/** Bits 63 -    - LM  - MBZ bits when no NX. */
+#define X86_PTE_LM_MBZ_MASK_NO_NX           UINT64_C(0x8000000000000000)
+
+/**
+ * Page table entry.
+ */
+typedef struct X86PTEBITS
+{
+    /** Flags whether(=1) or not the page is present. */
+    unsigned    u1Present : 1;
+    /** Read(=0) / Write(=1) flag. */
+    unsigned    u1Write : 1;
+    /** User(=1) / Supervisor (=0) flag. */
+    unsigned    u1User : 1;
+    /** Write Thru flag. If PAT enabled, bit 0 of the index. */
+    unsigned    u1WriteThru : 1;
+    /** Cache disabled flag. If PAT enabled, bit 1 of the index. */
+    unsigned    u1CacheDisable : 1;
+    /** Accessed flag.
+     * Indicates that the page have been read or written to. */
+    unsigned    u1Accessed : 1;
+    /** Dirty flag.
+     * Indicates that the page has been written to. */
+    unsigned    u1Dirty : 1;
+    /** Reserved / If PAT enabled, bit 2 of the index.  */
+    unsigned    u1PAT : 1;
+    /** Global flag. (Ignored in all but final level.) */
+    unsigned    u1Global : 1;
+    /** Available for use to system software. */
+    unsigned    u3Available : 3;
+    /** Physical Page number of the next level. */
+    unsigned    u20PageNo : 20;
+} X86PTEBITS;
+/** Pointer to a page table entry. */
+typedef X86PTEBITS *PX86PTEBITS;
+/** Pointer to a const page table entry. */
+typedef const X86PTEBITS *PCX86PTEBITS;
+
+/**
+ * Page table entry.
+ */
+typedef union X86PTE
+{
+    /** Unsigned integer view */
+    X86PGUINT       u;
+    /** Bit field view. */
+    X86PTEBITS      n;
+    /** 32-bit view. */
+    uint32_t        au32[1];
+    /** 16-bit view. */
+    uint16_t        au16[2];
+    /** 8-bit view. */
+    uint8_t         au8[4];
+} X86PTE;
+/** Pointer to a page table entry. */
+typedef X86PTE *PX86PTE;
+/** Pointer to a const page table entry. */
+typedef const X86PTE *PCX86PTE;
+
+
+/**
+ * PAE page table entry.
+ */
+typedef struct X86PTEPAEBITS
+{
+    /** Flags whether(=1) or not the page is present. */
+    uint32_t    u1Present : 1;
+    /** Read(=0) / Write(=1) flag. */
+    uint32_t    u1Write : 1;
+    /** User(=1) / Supervisor(=0) flag. */
+    uint32_t    u1User : 1;
+    /** Write Thru flag. If PAT enabled, bit 0 of the index. */
+    uint32_t    u1WriteThru : 1;
+    /** Cache disabled flag. If PAT enabled, bit 1 of the index. */
+    uint32_t    u1CacheDisable : 1;
+    /** Accessed flag.
+     * Indicates that the page have been read or written to. */
+    uint32_t    u1Accessed : 1;
+    /** Dirty flag.
+     * Indicates that the page has been written to. */
+    uint32_t    u1Dirty : 1;
+    /** Reserved / If PAT enabled, bit 2 of the index.  */
+    uint32_t    u1PAT : 1;
+    /** Global flag. (Ignored in all but final level.) */
+    uint32_t    u1Global : 1;
+    /** Available for use to system software. */
+    uint32_t    u3Available : 3;
+    /** Physical Page number of the next level - Low Part. Don't use this. */
+    uint32_t    u20PageNoLow : 20;
+    /** Physical Page number of the next level - High Part. Don't use this. */
+    uint32_t    u20PageNoHigh : 20;
+    /** MBZ bits */
+    uint32_t    u11Reserved : 11;
+    /** No Execute flag. */
+    uint32_t    u1NoExecute : 1;
+} X86PTEPAEBITS;
+/** Pointer to a page table entry. */
+typedef X86PTEPAEBITS *PX86PTEPAEBITS;
+/** Pointer to a page table entry. */
+typedef const X86PTEPAEBITS *PCX86PTEPAEBITS;
+
+/**
+ * PAE Page table entry.
+ */
+typedef union X86PTEPAE
+{
+    /** Unsigned integer view */
+    X86PGPAEUINT    u;
+    /** Bit field view. */
+    X86PTEPAEBITS   n;
+    /** 32-bit view. */
+    uint32_t        au32[2];
+    /** 16-bit view. */
+    uint16_t        au16[4];
+    /** 8-bit view. */
+    uint8_t         au8[8];
+} X86PTEPAE;
+/** Pointer to a PAE page table entry. */
+typedef X86PTEPAE *PX86PTEPAE;
+/** Pointer to a const PAE page table entry. */
+typedef const X86PTEPAE *PCX86PTEPAE;
+/** @} */
+
+/**
+ * Page table.
+ */
+typedef struct X86PT
+{
+    /** PTE Array. */
+    X86PTE     a[X86_PG_ENTRIES];
+} X86PT;
+/** Pointer to a page table. */
+typedef X86PT *PX86PT;
+/** Pointer to a const page table. */
+typedef const X86PT *PCX86PT;
+
+/** The page shift to get the PT index. */
+#define X86_PT_SHIFT                        12
+/** The PT index mask (apply to a shifted page address). */
+#define X86_PT_MASK                         0x3ff
+
+
+/**
+ * Page directory.
+ */
+typedef struct X86PTPAE
+{
+    /** PTE Array. */
+    X86PTEPAE  a[X86_PG_PAE_ENTRIES];
+} X86PTPAE;
+/** Pointer to a page table. */
+typedef X86PTPAE *PX86PTPAE;
+/** Pointer to a const page table. */
+typedef const X86PTPAE *PCX86PTPAE;
+
+/** The page shift to get the PA PTE index. */
+#define X86_PT_PAE_SHIFT                    12
+/** The PAE PT index mask (apply to a shifted page address). */
+#define X86_PT_PAE_MASK                     0x1ff
+
+
+/** @name 4KB Page Directory Entry
+ * @{
+ */
+/** Bit 0 -  P  - Present bit. */
+#define X86_PDE_P                           RT_BIT(0)
+/** Bit 1 - R/W - Read (clear) / Write (set) bit. */
+#define X86_PDE_RW                          RT_BIT(1)
+/** Bit 2 - U/S - User (set) / Supervisor (clear) bit. */
+#define X86_PDE_US                          RT_BIT(2)
+/** Bit 3 - PWT - Page level write thru bit. */
+#define X86_PDE_PWT                         RT_BIT(3)
+/** Bit 4 - PCD - Page level cache disable bit. */
+#define X86_PDE_PCD                         RT_BIT(4)
+/** Bit 5 -  A  - Access bit. */
+#define X86_PDE_A                           RT_BIT(5)
+/** Bit 7 - PS  - Page size attribute.
+ * Clear mean 4KB pages, set means large pages (2/4MB). */
+#define X86_PDE_PS                          RT_BIT(7)
+/** Bits 9-11 - - Available for use to system software. */
+#define X86_PDE_AVL_MASK                    (RT_BIT(9) | RT_BIT(10) | RT_BIT(11))
+/** Bits 12-31 -  - Physical Page number of the next level. */
+#define X86_PDE_PG_MASK                     ( 0xfffff000 )
+
+/** Bits 12-51 - - PAE - Physical Page number of the next level. */
+#define X86_PDE_PAE_PG_MASK                 UINT64_C(0x000ffffffffff000)
+/** Bits 63 - NX - PAE/LM - No execution flag. */
+#define X86_PDE_PAE_NX                      RT_BIT_64(63)
+/** Bits 62-52, 7 - - PAE - MBZ bits when NX is active. */
+#define X86_PDE_PAE_MBZ_MASK_NX             UINT64_C(0x7ff0000000000080)
+/** Bits 63-52, 7 - - PAE - MBZ bits when no NX. */
+#define X86_PDE_PAE_MBZ_MASK_NO_NX          UINT64_C(0xfff0000000000080)
+/** Bit 7 -         - LM  - MBZ bits when NX is active. */
+#define X86_PDE_LM_MBZ_MASK_NX              UINT64_C(0x0000000000000080)
+/** Bits 63, 7 -    - LM  - MBZ bits when no NX. */
+#define X86_PDE_LM_MBZ_MASK_NO_NX           UINT64_C(0x8000000000000080)
+
+/**
+ * Page directory entry.
+ */
+typedef struct X86PDEBITS
+{
+    /** Flags whether(=1) or not the page is present. */
+    unsigned    u1Present : 1;
+    /** Read(=0) / Write(=1) flag. */
+    unsigned    u1Write : 1;
+    /** User(=1) / Supervisor (=0) flag. */
+    unsigned    u1User : 1;
+    /** Write Thru flag. If PAT enabled, bit 0 of the index. */
+    unsigned    u1WriteThru : 1;
+    /** Cache disabled flag. If PAT enabled, bit 1 of the index. */
+    unsigned    u1CacheDisable : 1;
+    /** Accessed flag.
+     * Indicates that the page has been read or written to. */
+    unsigned    u1Accessed : 1;
+    /** Reserved / Ignored (dirty bit). */
+    unsigned    u1Reserved0 : 1;
+    /** Size bit if PSE is enabled - in any event it's 0. */
+    unsigned    u1Size : 1;
+    /** Reserved / Ignored (global bit). */
+    unsigned    u1Reserved1 : 1;
+    /** Available for use to system software. */
+    unsigned    u3Available : 3;
+    /** Physical Page number of the next level. */
+    unsigned    u20PageNo : 20;
+} X86PDEBITS;
+/** Pointer to a page directory entry. */
+typedef X86PDEBITS *PX86PDEBITS;
+/** Pointer to a const page directory entry. */
+typedef const X86PDEBITS *PCX86PDEBITS;
+
+
+/**
+ * PAE page directory entry.
+ */
+typedef struct X86PDEPAEBITS
+{
+    /** Flags whether(=1) or not the page is present. */
+    uint32_t    u1Present : 1;
+    /** Read(=0) / Write(=1) flag. */
+    uint32_t    u1Write : 1;
+    /** User(=1) / Supervisor (=0) flag. */
+    uint32_t    u1User : 1;
+    /** Write Thru flag. If PAT enabled, bit 0 of the index. */
+    uint32_t    u1WriteThru : 1;
+    /** Cache disabled flag. If PAT enabled, bit 1 of the index. */
+    uint32_t    u1CacheDisable : 1;
+    /** Accessed flag.
+     * Indicates that the page has been read or written to. */
+    uint32_t    u1Accessed : 1;
+    /** Reserved / Ignored (dirty bit). */
+    uint32_t    u1Reserved0 : 1;
+    /** Size bit if PSE is enabled - in any event it's 0. */
+    uint32_t    u1Size : 1;
+    /** Reserved / Ignored (global bit). /  */
+    uint32_t    u1Reserved1 : 1;
+    /** Available for use to system software. */
+    uint32_t    u3Available : 3;
+    /** Physical Page number of the next level - Low Part. Don't use! */
+    uint32_t    u20PageNoLow : 20;
+    /** Physical Page number of the next level - High Part. Don't use! */
+    uint32_t    u20PageNoHigh : 20;
+    /** MBZ bits */
+    uint32_t    u11Reserved : 11;
+    /** No Execute flag. */
+    uint32_t    u1NoExecute : 1;
+} X86PDEPAEBITS;
+/** Pointer to a page directory entry. */
+typedef X86PDEPAEBITS *PX86PDEPAEBITS;
+/** Pointer to a const page directory entry. */
+typedef const X86PDEPAEBITS *PCX86PDEPAEBITS;
+
+/** @} */
+
+
+/** @name 2/4MB Page Directory Entry
+ * @{
+ */
+/** Bit 0 -  P  - Present bit. */
+#define X86_PDE4M_P                         RT_BIT(0)
+/** Bit 1 - R/W - Read (clear) / Write (set) bit. */
+#define X86_PDE4M_RW                        RT_BIT(1)
+/** Bit 2 - U/S - User (set) / Supervisor (clear) bit. */
+#define X86_PDE4M_US                        RT_BIT(2)
+/** Bit 3 - PWT - Page level write thru bit. */
+#define X86_PDE4M_PWT                       RT_BIT(3)
+/** Bit 4 - PCD - Page level cache disable bit. */
+#define X86_PDE4M_PCD                       RT_BIT(4)
+/** Bit 5 -  A  - Access bit. */
+#define X86_PDE4M_A                         RT_BIT(5)
+/** Bit 6 -  D  - Dirty bit. */
+#define X86_PDE4M_D                         RT_BIT(6)
+/** Bit 7 - PS  - Page size attribute. Clear mean 4KB pages, set means large pages (2/4MB). */
+#define X86_PDE4M_PS                        RT_BIT(7)
+/** Bit 8 -  G  - Global flag. */
+#define X86_PDE4M_G                         RT_BIT(8)
+/** Bits 9-11 - AVL - Available for use to system software. */
+#define X86_PDE4M_AVL                       (RT_BIT(9) | RT_BIT(10) | RT_BIT(11))
+/** Bit 12 - PAT - Page Attribute Table index bit. Reserved and 0 if not supported. */
+#define X86_PDE4M_PAT                       RT_BIT(12)
+/** Shift to get from X86_PTE_PAT to X86_PDE4M_PAT. */
+#define X86_PDE4M_PAT_SHIFT                 (12 - 7)
+/** Bits 22-31 - - Physical Page number. */
+#define X86_PDE4M_PG_MASK                   ( 0xffc00000 )
+/** Bits 20-13 - - Physical Page number high part (32-39 bits). AMD64 hack. */
+#define X86_PDE4M_PG_HIGH_MASK              ( 0x001fe000 )
+/** The number of bits to the high part of the page number. */
+#define X86_PDE4M_PG_HIGH_SHIFT             19
+/** Bit 21 -     - MBZ bits for AMD CPUs, no PSE36. */
+#define X86_PDE4M_MBZ_MASK                  RT_BIT_32(21)
+
+/** Bits 21-51 - - PAE/LM - Physical Page number.
+ * (Bits 40-51 (long mode) & bits 36-51 (pae legacy) are reserved according to the Intel docs; AMD allows for more.) */
+#define X86_PDE2M_PAE_PG_MASK               UINT64_C(0x000fffffffe00000)
+/** Bits 63 - NX - PAE/LM - No execution flag. */
+#define X86_PDE2M_PAE_NX                    RT_BIT_64(63)
+/** Bits 62-52, 20-13 - - PAE - MBZ bits when NX is active. */
+#define X86_PDE2M_PAE_MBZ_MASK_NX           UINT64_C(0x7ff00000001fe000)
+/** Bits 63-52, 20-13 - - PAE - MBZ bits when no NX. */
+#define X86_PDE2M_PAE_MBZ_MASK_NO_NX        UINT64_C(0xfff00000001fe000)
+/** Bits 20-13        - - LM  - MBZ bits when NX is active. */
+#define X86_PDE2M_LM_MBZ_MASK_NX            UINT64_C(0x00000000001fe000)
+/** Bits 63, 20-13    - - LM  - MBZ bits when no NX. */
+#define X86_PDE2M_LM_MBZ_MASK_NO_NX         UINT64_C(0x80000000001fe000)
+
+/**
+ * 4MB page directory entry.
+ */
+typedef struct X86PDE4MBITS
+{
+    /** Flags whether(=1) or not the page is present. */
+    unsigned    u1Present : 1;
+    /** Read(=0) / Write(=1) flag. */
+    unsigned    u1Write : 1;
+    /** User(=1) / Supervisor (=0) flag. */
+    unsigned    u1User : 1;
+    /** Write Thru flag. If PAT enabled, bit 0 of the index. */
+    unsigned    u1WriteThru : 1;
+    /** Cache disabled flag. If PAT enabled, bit 1 of the index. */
+    unsigned    u1CacheDisable : 1;
+    /** Accessed flag.
+     * Indicates that the page have been read or written to. */
+    unsigned    u1Accessed : 1;
+    /** Dirty flag.
+     * Indicates that the page has been written to. */
+    unsigned    u1Dirty : 1;
+    /** Page size flag - always 1 for 4MB entries. */
+    unsigned    u1Size : 1;
+    /** Global flag.  */
+    unsigned    u1Global : 1;
+    /** Available for use to system software. */
+    unsigned    u3Available : 3;
+    /** Reserved / If PAT enabled, bit 2 of the index.  */
+    unsigned    u1PAT : 1;
+    /** Bits 32-39 of the page number on AMD64.
+     * This AMD64 hack allows accessing 40bits of physical memory without PAE. */
+    unsigned    u8PageNoHigh : 8;
+    /** Reserved. */
+    unsigned    u1Reserved : 1;
+    /** Physical Page number of the page. */
+    unsigned    u10PageNo : 10;
+} X86PDE4MBITS;
+/** Pointer to a page table entry. */
+typedef X86PDE4MBITS *PX86PDE4MBITS;
+/** Pointer to a const page table entry. */
+typedef const X86PDE4MBITS *PCX86PDE4MBITS;
+
+
+/**
+ * 2MB PAE page directory entry.
+ */
+typedef struct X86PDE2MPAEBITS
+{
+    /** Flags whether(=1) or not the page is present. */
+    uint32_t    u1Present : 1;
+    /** Read(=0) / Write(=1) flag. */
+    uint32_t    u1Write : 1;
+    /** User(=1) / Supervisor(=0) flag. */
+    uint32_t    u1User : 1;
+    /** Write Thru flag. If PAT enabled, bit 0 of the index. */
+    uint32_t    u1WriteThru : 1;
+    /** Cache disabled flag. If PAT enabled, bit 1 of the index. */
+    uint32_t    u1CacheDisable : 1;
+    /** Accessed flag.
+     * Indicates that the page have been read or written to. */
+    uint32_t    u1Accessed : 1;
+    /** Dirty flag.
+     * Indicates that the page has been written to. */
+    uint32_t    u1Dirty : 1;
+    /** Page size flag - always 1 for 2MB entries. */
+    uint32_t    u1Size : 1;
+    /** Global flag.  */
+    uint32_t    u1Global : 1;
+    /** Available for use to system software. */
+    uint32_t    u3Available : 3;
+    /** Reserved / If PAT enabled, bit 2 of the index.  */
+    uint32_t    u1PAT : 1;
+    /** Reserved. */
+    uint32_t    u9Reserved : 9;
+    /** Physical Page number of the next level - Low part. Don't use! */
+    uint32_t    u10PageNoLow : 10;
+    /** Physical Page number of the next level - High part. Don't use! */
+    uint32_t    u20PageNoHigh : 20;
+    /** MBZ bits */
+    uint32_t    u11Reserved : 11;
+    /** No Execute flag. */
+    uint32_t    u1NoExecute : 1;
+} X86PDE2MPAEBITS;
+/** Pointer to a 2MB PAE page table entry. */
+typedef X86PDE2MPAEBITS *PX86PDE2MPAEBITS;
+/** Pointer to a 2MB PAE page table entry. */
+typedef const X86PDE2MPAEBITS *PCX86PDE2MPAEBITS;
+
+/** @} */
+
+/**
+ * Page directory entry.
+ */
+typedef union X86PDE
+{
+    /** Unsigned integer view. */
+    X86PGUINT       u;
+    /** Normal view. */
+    X86PDEBITS      n;
+    /** 4MB view (big). */
+    X86PDE4MBITS    b;
+    /** 8 bit unsigned integer view. */
+    uint8_t         au8[4];
+    /** 16 bit unsigned integer view. */
+    uint16_t        au16[2];
+    /** 32 bit unsigned integer view. */
+    uint32_t        au32[1];
+} X86PDE;
+/** Pointer to a page directory entry. */
+typedef X86PDE *PX86PDE;
+/** Pointer to a const page directory entry. */
+typedef const X86PDE *PCX86PDE;
+
+/**
+ * PAE page directory entry.
+ */
+typedef union X86PDEPAE
+{
+    /** Unsigned integer view. */
+    X86PGPAEUINT    u;
+    /** Normal view. */
+    X86PDEPAEBITS   n;
+    /** 2MB page view (big). */
+    X86PDE2MPAEBITS b;
+    /** 8 bit unsigned integer view. */
+    uint8_t         au8[8];
+    /** 16 bit unsigned integer view. */
+    uint16_t        au16[4];
+    /** 32 bit unsigned integer view. */
+    uint32_t        au32[2];
+} X86PDEPAE;
+/** Pointer to a page directory entry. */
+typedef X86PDEPAE *PX86PDEPAE;
+/** Pointer to a const page directory entry. */
+typedef const X86PDEPAE *PCX86PDEPAE;
+
+/**
+ * Page directory.
+ */
+typedef struct X86PD
+{
+    /** PDE Array. */
+    X86PDE      a[X86_PG_ENTRIES];
+} X86PD;
+/** Pointer to a page directory. */
+typedef X86PD *PX86PD;
+/** Pointer to a const page directory. */
+typedef const X86PD *PCX86PD;
+
+/** The page shift to get the PD index. */
+#define X86_PD_SHIFT                        22
+/** The PD index mask (apply to a shifted page address). */
+#define X86_PD_MASK                         0x3ff
+
+
+/**
+ * PAE page directory.
+ */
+typedef struct X86PDPAE
+{
+    /** PDE Array. */
+    X86PDEPAE   a[X86_PG_PAE_ENTRIES];
+} X86PDPAE;
+/** Pointer to a PAE page directory. */
+typedef X86PDPAE *PX86PDPAE;
+/** Pointer to a const PAE page directory. */
+typedef const X86PDPAE *PCX86PDPAE;
+
+/** The page shift to get the PAE PD index. */
+#define X86_PD_PAE_SHIFT                    21
+/** The PAE PD index mask (apply to a shifted page address). */
+#define X86_PD_PAE_MASK                     0x1ff
+
+
+/** @name Page Directory Pointer Table Entry (PAE)
+ * @{
+ */
+/** Bit 0 -  P  - Present bit. */
+#define X86_PDPE_P                          RT_BIT(0)
+/** Bit 1 - R/W - Read (clear) / Write (set) bit. Long Mode only. */
+#define X86_PDPE_RW                         RT_BIT(1)
+/** Bit 2 - U/S - User (set) / Supervisor (clear) bit. Long Mode only. */
+#define X86_PDPE_US                         RT_BIT(2)
+/** Bit 3 - PWT - Page level write thru bit. */
+#define X86_PDPE_PWT                        RT_BIT(3)
+/** Bit 4 - PCD - Page level cache disable bit. */
+#define X86_PDPE_PCD                        RT_BIT(4)
+/** Bit 5 -  A  - Access bit. Long Mode only. */
+#define X86_PDPE_A                          RT_BIT(5)
+/** Bit 7 - PS  - Page size (1GB). Long Mode only. */
+#define X86_PDPE_LM_PS                      RT_BIT(7)
+/** Bits 9-11 - - Available for use to system software. */
+#define X86_PDPE_AVL_MASK                   (RT_BIT(9) | RT_BIT(10) | RT_BIT(11))
+/** Bits 12-51 - - PAE - Physical Page number of the next level. */
+#define X86_PDPE_PG_MASK                    UINT64_C(0x000ffffffffff000)
+/** Bits 63-52, 8-5, 2-1 - - PAE - MBZ bits (NX is long mode only). */
+#define X86_PDPE_PAE_MBZ_MASK               UINT64_C(0xfff00000000001e6)
+/** Bits 63 - NX - LM - No execution flag. Long Mode only. */
+#define X86_PDPE_LM_NX                      RT_BIT_64(63)
+/** Bits 8, 7 - - LM - MBZ bits when NX is active. */
+#define X86_PDPE_LM_MBZ_MASK_NX             UINT64_C(0x0000000000000180)
+/** Bits 63, 8, 7 - - LM - MBZ bits when no NX. */
+#define X86_PDPE_LM_MBZ_MASK_NO_NX          UINT64_C(0x8000000000000180)
+/** Bits 29-13 - - LM - MBZ bits for 1GB page entry when NX is active. */
+#define X86_PDPE1G_LM_MBZ_MASK_NX           UINT64_C(0x000000003fffe000)
+/** Bits 63, 29-13 - - LM - MBZ bits for 1GB page entry when no NX. */
+#define X86_PDPE1G_LM_MBZ_MASK_NO_NX        UINT64_C(0x800000003fffe000)
+
+
+/**
+ * Page directory pointer table entry.
+ */
+typedef struct X86PDPEBITS
+{
+    /** Flags whether(=1) or not the page is present. */
+    uint32_t    u1Present : 1;
+    /** Chunk of reserved bits. */
+    uint32_t    u2Reserved : 2;
+    /** Write Thru flag. If PAT enabled, bit 0 of the index. */
+    uint32_t    u1WriteThru : 1;
+    /** Cache disabled flag. If PAT enabled, bit 1 of the index. */
+    uint32_t    u1CacheDisable : 1;
+    /** Chunk of reserved bits. */
+    uint32_t    u4Reserved : 4;
+    /** Available for use to system software. */
+    uint32_t    u3Available : 3;
+    /** Physical Page number of the next level - Low Part. Don't use! */
+    uint32_t    u20PageNoLow : 20;
+    /** Physical Page number of the next level - High Part. Don't use! */
+    uint32_t    u20PageNoHigh : 20;
+    /** MBZ bits */
+    uint32_t    u12Reserved : 12;
+} X86PDPEBITS;
+/** Pointer to a page directory pointer table entry. */
+typedef X86PDPEBITS *PX86PTPEBITS;
+/** Pointer to a const page directory pointer table entry. */
+typedef const X86PDPEBITS *PCX86PTPEBITS;
+
+/**
+ * Page directory pointer table entry. AMD64 version
+ */
+typedef struct X86PDPEAMD64BITS
+{
+    /** Flags whether(=1) or not the page is present. */
+    uint32_t    u1Present : 1;
+    /** Read(=0) / Write(=1) flag. */
+    uint32_t    u1Write : 1;
+    /** User(=1) / Supervisor (=0) flag. */
+    uint32_t    u1User : 1;
+    /** Write Thru flag. If PAT enabled, bit 0 of the index. */
+    uint32_t    u1WriteThru : 1;
+    /** Cache disabled flag. If PAT enabled, bit 1 of the index. */
+    uint32_t    u1CacheDisable : 1;
+    /** Accessed flag.
+     * Indicates that the page have been read or written to. */
+    uint32_t    u1Accessed : 1;
+    /** Chunk of reserved bits. */
+    uint32_t    u3Reserved : 3;
+    /** Available for use to system software. */
+    uint32_t    u3Available : 3;
+    /** Physical Page number of the next level - Low Part. Don't use! */
+    uint32_t    u20PageNoLow : 20;
+    /** Physical Page number of the next level - High Part. Don't use! */
+    uint32_t    u20PageNoHigh : 20;
+    /** MBZ bits */
+    uint32_t    u11Reserved : 11;
+    /** No Execute flag. */
+    uint32_t    u1NoExecute : 1;
+} X86PDPEAMD64BITS;
+/** Pointer to a page directory pointer table entry. */
+typedef X86PDPEAMD64BITS *PX86PDPEAMD64BITS;
+/** Pointer to a const page directory pointer table entry. */
+typedef const X86PDPEAMD64BITS *PCX86PDPEAMD64BITS;
+
+/**
+ * Page directory pointer table entry.
+ */
+typedef union X86PDPE
+{
+    /** Unsigned integer view. */
+    X86PGPAEUINT    u;
+    /** Normal view. */
+    X86PDPEBITS     n;
+    /** AMD64 view. */
+    X86PDPEAMD64BITS lm;
+    /** 8 bit unsigned integer view. */
+    uint8_t         au8[8];
+    /** 16 bit unsigned integer view. */
+    uint16_t        au16[4];
+    /** 32 bit unsigned integer view. */
+    uint32_t        au32[2];
+} X86PDPE;
+/** Pointer to a page directory pointer table entry. */
+typedef X86PDPE *PX86PDPE;
+/** Pointer to a const page directory pointer table entry. */
+typedef const X86PDPE *PCX86PDPE;
+
+
+/**
+ * Page directory pointer table.
+ */
+typedef struct X86PDPT
+{
+    /** PDE Array. */
+    X86PDPE         a[X86_PG_AMD64_PDPE_ENTRIES];
+} X86PDPT;
+/** Pointer to a page directory pointer table. */
+typedef X86PDPT *PX86PDPT;
+/** Pointer to a const page directory pointer table. */
+typedef const X86PDPT *PCX86PDPT;
+
+/** The page shift to get the PDPT index. */
+#define X86_PDPT_SHIFT             30
+/** The PDPT index mask (apply to a shifted page address). (32 bits PAE) */
+#define X86_PDPT_MASK_PAE          0x3
+/** The PDPT index mask (apply to a shifted page address). (64 bits PAE)*/
+#define X86_PDPT_MASK_AMD64        0x1ff
+
+/** @} */
+
+
+/** @name Page Map Level-4 Entry (Long Mode PAE)
+ * @{
+ */
+/** Bit 0 -  P  - Present bit. */
+#define X86_PML4E_P                         RT_BIT(0)
+/** Bit 1 - R/W - Read (clear) / Write (set) bit. */
+#define X86_PML4E_RW                        RT_BIT(1)
+/** Bit 2 - U/S - User (set) / Supervisor (clear) bit. */
+#define X86_PML4E_US                        RT_BIT(2)
+/** Bit 3 - PWT - Page level write thru bit. */
+#define X86_PML4E_PWT                       RT_BIT(3)
+/** Bit 4 - PCD - Page level cache disable bit. */
+#define X86_PML4E_PCD                       RT_BIT(4)
+/** Bit 5 -  A  - Access bit. */
+#define X86_PML4E_A                         RT_BIT(5)
+/** Bits 9-11 - - Available for use to system software. */
+#define X86_PML4E_AVL_MASK                  (RT_BIT(9) | RT_BIT(10) | RT_BIT(11))
+/** Bits 12-51 - - PAE - Physical Page number of the next level. */
+#define X86_PML4E_PG_MASK                   UINT64_C(0x000ffffffffff000)
+/** Bits 8, 7 - - MBZ bits when NX is active. */
+#define X86_PML4E_MBZ_MASK_NX               UINT64_C(0x0000000000000080)
+/** Bits 63, 7 - - MBZ bits when no NX. */
+#define X86_PML4E_MBZ_MASK_NO_NX            UINT64_C(0x8000000000000080)
+/** Bits 63 - NX - PAE - No execution flag. */
+#define X86_PML4E_NX                        RT_BIT_64(63)
+
+/**
+ * Page Map Level-4 Entry
+ */
+typedef struct X86PML4EBITS
+{
+    /** Flags whether(=1) or not the page is present. */
+    uint32_t    u1Present : 1;
+    /** Read(=0) / Write(=1) flag. */
+    uint32_t    u1Write : 1;
+    /** User(=1) / Supervisor (=0) flag. */
+    uint32_t    u1User : 1;
+    /** Write Thru flag. If PAT enabled, bit 0 of the index. */
+    uint32_t    u1WriteThru : 1;
+    /** Cache disabled flag. If PAT enabled, bit 1 of the index. */
+    uint32_t    u1CacheDisable : 1;
+    /** Accessed flag.
+     * Indicates that the page have been read or written to. */
+    uint32_t    u1Accessed : 1;
+    /** Chunk of reserved bits. */
+    uint32_t    u3Reserved : 3;
+    /** Available for use to system software. */
+    uint32_t    u3Available : 3;
+    /** Physical Page number of the next level - Low Part. Don't use! */
+    uint32_t    u20PageNoLow : 20;
+    /** Physical Page number of the next level - High Part. Don't use! */
+    uint32_t    u20PageNoHigh : 20;
+    /** MBZ bits */
+    uint32_t    u11Reserved : 11;
+    /** No Execute flag. */
+    uint32_t    u1NoExecute : 1;
+} X86PML4EBITS;
+/** Pointer to a page map level-4 entry. */
+typedef X86PML4EBITS *PX86PML4EBITS;
+/** Pointer to a const page map level-4 entry. */
+typedef const X86PML4EBITS *PCX86PML4EBITS;
+
+/**
+ * Page Map Level-4 Entry.
+ */
+typedef union X86PML4E
+{
+    /** Unsigned integer view. */
+    X86PGPAEUINT    u;
+    /** Normal view. */
+    X86PML4EBITS    n;
+    /** 8 bit unsigned integer view. */
+    uint8_t         au8[8];
+    /** 16 bit unsigned integer view. */
+    uint16_t        au16[4];
+    /** 32 bit unsigned integer view. */
+    uint32_t        au32[2];
+} X86PML4E;
+/** Pointer to a page map level-4 entry. */
+typedef X86PML4E *PX86PML4E;
+/** Pointer to a const page map level-4 entry. */
+typedef const X86PML4E *PCX86PML4E;
+
+
+/**
+ * Page Map Level-4.
+ */
+typedef struct X86PML4
+{
+    /** PDE Array. */
+    X86PML4E        a[X86_PG_PAE_ENTRIES];
+} X86PML4;
+/** Pointer to a page map level-4. */
+typedef X86PML4 *PX86PML4;
+/** Pointer to a const page map level-4. */
+typedef const X86PML4 *PCX86PML4;
+
+/** The page shift to get the PML4 index. */
+#define X86_PML4_SHIFT              39
+/** The PML4 index mask (apply to a shifted page address). */
+#define X86_PML4_MASK               0x1ff
+
+/** @} */
+
+/** @} */
+
+/**
+ * 32-bit protected mode FSTENV image.
+ */
+typedef struct X86FSTENV32P
+{
+    uint16_t    FCW;
+    uint16_t    padding1;
+    uint16_t    FSW;
+    uint16_t    padding2;
+    uint16_t    FTW;
+    uint16_t    padding3;
+    uint32_t    FPUIP;
+    uint16_t    FPUCS;
+    uint16_t    FOP;
+    uint32_t    FPUDP;
+    uint16_t    FPUDS;
+    uint16_t    padding4;
+} X86FSTENV32P;
+/** Pointer to a 32-bit protected mode FSTENV image. */
+typedef X86FSTENV32P *PX86FSTENV32P;
+/** Pointer to a const 32-bit protected mode FSTENV image. */
+typedef X86FSTENV32P const *PCX86FSTENV32P;
+
+
+/**
+ * 80-bit MMX/FPU register type.
+ */
+typedef struct X86FPUMMX
+{
+    uint8_t reg[10];
+} X86FPUMMX;
+#ifndef VBOX_FOR_DTRACE_LIB
+AssertCompileSize(X86FPUMMX, 10);
+#endif
+/** Pointer to a 80-bit MMX/FPU register type. */
+typedef X86FPUMMX *PX86FPUMMX;
+/** Pointer to a const 80-bit MMX/FPU register type. */
+typedef const X86FPUMMX *PCX86FPUMMX;
+
+/** FPU (x87) register. */
+typedef union X86FPUREG
+{
+    /** MMX view. */
+    uint64_t    mmx;
+    /** FPU view - todo. */
+    X86FPUMMX   fpu;
+    /** Extended precision floating point view. */
+    RTFLOAT80U  r80;
+    /** Extended precision floating point view v2 */
+    RTFLOAT80U2 r80Ex;
+    /** 8-bit view. */
+    uint8_t     au8[16];
+    /** 16-bit view. */
+    uint16_t    au16[8];
+    /** 32-bit view. */
+    uint32_t    au32[4];
+    /** 64-bit view. */
+    uint64_t    au64[2];
+    /** 128-bit view. (yeah, very helpful) */
+    uint128_t   au128[1];
+} X86FPUREG;
+#ifndef VBOX_FOR_DTRACE_LIB
+AssertCompileSize(X86FPUREG, 16);
+#endif
+/** Pointer to a FPU register. */
+typedef X86FPUREG *PX86FPUREG;
+/** Pointer to a const FPU register. */
+typedef X86FPUREG const *PCX86FPUREG;
+
+/**
+ * XMM register union.
+ */
+typedef union X86XMMREG
+{
+    /** XMM Register view *. */
+    uint128_t   xmm;
+    /** 8-bit view. */
+    uint8_t     au8[16];
+    /** 16-bit view. */
+    uint16_t    au16[8];
+    /** 32-bit view. */
+    uint32_t    au32[4];
+    /** 64-bit view. */
+    uint64_t    au64[2];
+    /** 128-bit view. (yeah, very helpful) */
+    uint128_t   au128[1];
+} X86XMMREG;
+#ifndef VBOX_FOR_DTRACE_LIB
+AssertCompileSize(X86XMMREG, 16);
+#endif
+/** Pointer to an XMM register state. */
+typedef X86XMMREG *PX86XMMREG;
+/** Pointer to a const XMM register state. */
+typedef X86XMMREG const *PCX86XMMREG;
+
+/**
+ * YMM register union.
+ */
+typedef union X86YMMREG
+{
+    /** 8-bit view. */
+    uint8_t     au8[32];
+    /** 16-bit view. */
+    uint16_t    au16[16];
+    /** 32-bit view. */
+    uint32_t    au32[8];
+    /** 64-bit view. */
+    uint64_t    au64[4];
+    /** 128-bit view. (yeah, very helpful) */
+    uint128_t   au128[2];
+    /** XMM sub register view. */
+    X86XMMREG   aXmm[2];
+} X86YMMREG;
+#ifndef VBOX_FOR_DTRACE_LIB
+AssertCompileSize(X86YMMREG, 32);
+#endif
+/** Pointer to an YMM register state. */
+typedef X86YMMREG *PX86YMMREG;
+/** Pointer to a const YMM register state. */
+typedef X86YMMREG const *PCX86YMMREG;
+
+/**
+ * ZMM register union.
+ */
+typedef union X86ZMMREG
+{
+    /** 8-bit view. */
+    uint8_t     au8[64];
+    /** 16-bit view. */
+    uint16_t    au16[32];
+    /** 32-bit view. */
+    uint32_t    au32[16];
+    /** 64-bit view. */
+    uint64_t    au64[8];
+    /** 128-bit view. (yeah, very helpful) */
+    uint128_t   au128[4];
+    /** XMM sub register view. */
+    X86XMMREG   aXmm[4];
+    /** YMM sub register view. */
+    X86YMMREG   aYmm[2];
+} X86ZMMREG;
+#ifndef VBOX_FOR_DTRACE_LIB
+AssertCompileSize(X86ZMMREG, 64);
+#endif
+/** Pointer to an ZMM register state. */
+typedef X86ZMMREG *PX86ZMMREG;
+/** Pointer to a const ZMM register state. */
+typedef X86ZMMREG const *PCX86ZMMREG;
+
+
+/**
+ * 32-bit FPU state (aka FSAVE/FRSTOR Memory Region).
+ * @todo verify this...
+ */
+#pragma pack(1)
+typedef struct X86FPUSTATE
+{
+    /** 0x00 - Control word. */
+    uint16_t    FCW;
+    /** 0x02 - Alignment word */
+    uint16_t    Dummy1;
+    /** 0x04 - Status word. */
+    uint16_t    FSW;
+    /** 0x06 - Alignment word */
+    uint16_t    Dummy2;
+    /** 0x08 - Tag word */
+    uint16_t    FTW;
+    /** 0x0a - Alignment word */
+    uint16_t    Dummy3;
+
+    /** 0x0c - Instruction pointer. */
+    uint32_t    FPUIP;
+    /** 0x10 - Code selector. */
+    uint16_t    CS;
+    /** 0x12 - Opcode. */
+    uint16_t    FOP;
+    /** 0x14 - FOO. */
+    uint32_t    FPUOO;
+    /** 0x18 - FOS. */
+    uint32_t    FPUOS;
+    /** 0x1c - FPU register. */
+    X86FPUREG   regs[8];
+} X86FPUSTATE;
+#pragma pack()
+/** Pointer to a FPU state. */
+typedef X86FPUSTATE  *PX86FPUSTATE;
+/** Pointer to a const FPU state. */
+typedef const X86FPUSTATE  *PCX86FPUSTATE;
+
+/**
+ * FPU Extended state (aka FXSAVE/FXRSTORE Memory Region).
+ */
+#pragma pack(1)
+typedef struct X86FXSTATE
+{
+    /** 0x00 - Control word. */
+    uint16_t    FCW;
+    /** 0x02 - Status word. */
+    uint16_t    FSW;
+    /** 0x04 - Tag word. (The upper byte is always zero.) */
+    uint16_t    FTW;
+    /** 0x06 - Opcode. */
+    uint16_t    FOP;
+    /** 0x08 - Instruction pointer. */
+    uint32_t    FPUIP;
+    /** 0x0c - Code selector. */
+    uint16_t    CS;
+    uint16_t    Rsrvd1;
+    /** 0x10 - Data pointer. */
+    uint32_t    FPUDP;
+    /** 0x14 - Data segment */
+    uint16_t    DS;
+    /** 0x16 */
+    uint16_t    Rsrvd2;
+    /** 0x18 */
+    uint32_t    MXCSR;
+    /** 0x1c */
+    uint32_t    MXCSR_MASK;
+    /** 0x20 - FPU registers. */
+    X86FPUREG   aRegs[8];
+    /** 0xA0 - XMM registers - 8 registers in 32 bits mode, 16 in long mode. */
+    X86XMMREG   aXMM[16];
+    /* - offset 416 - */
+    uint32_t    au32RsrvdRest[(464 - 416) / sizeof(uint32_t)];
+    /* - offset 464 - Software usable reserved bits. */
+    uint32_t    au32RsrvdForSoftware[(512 - 464) / sizeof(uint32_t)];
+} X86FXSTATE;
+#pragma pack()
+/** Pointer to a FPU Extended state. */
+typedef X86FXSTATE *PX86FXSTATE;
+/** Pointer to a const FPU Extended state. */
+typedef const X86FXSTATE *PCX86FXSTATE;
+
+/** Offset for software usable reserved bits (464:511) where we store a 32-bit
+ *  magic. Don't forget to update x86.mac if you change this! */
+#define X86_OFF_FXSTATE_RSVD            0x1d0
+/** The 32-bit magic used to recognize if this a 32-bit FPU state. Don't
+ *  forget to update x86.mac if you change this!
+ * @todo r=bird: This has nothing what-so-ever to do here.... */
+#define X86_FXSTATE_RSVD_32BIT_MAGIC    0x32b3232b
+#ifndef VBOX_FOR_DTRACE_LIB
+AssertCompileSize(X86FXSTATE, 512);
+AssertCompileMemberOffset(X86FXSTATE, au32RsrvdForSoftware, X86_OFF_FXSTATE_RSVD);
+#endif
+
+/** @name FPU status word flags.
+ * @{ */
+/** Exception Flag: Invalid operation.  */
+#define X86_FSW_IE          RT_BIT(0)
+/** Exception Flag: Denormalized operand.  */
+#define X86_FSW_DE          RT_BIT(1)
+/** Exception Flag: Zero divide.  */
+#define X86_FSW_ZE          RT_BIT(2)
+/** Exception Flag: Overflow.  */
+#define X86_FSW_OE          RT_BIT(3)
+/** Exception Flag: Underflow.  */
+#define X86_FSW_UE          RT_BIT(4)
+/** Exception Flag: Precision.  */
+#define X86_FSW_PE          RT_BIT(5)
+/** Stack fault. */
+#define X86_FSW_SF          RT_BIT(6)
+/** Error summary status. */
+#define X86_FSW_ES          RT_BIT(7)
+/** Mask of exceptions flags, excluding the summary bit. */
+#define X86_FSW_XCPT_MASK   UINT16_C(0x007f)
+/** Mask of exceptions flags, including the summary bit. */
+#define X86_FSW_XCPT_ES_MASK UINT16_C(0x00ff)
+/** Condition code 0. */
+#define X86_FSW_C0          RT_BIT(8)
+/** Condition code 1. */
+#define X86_FSW_C1          RT_BIT(9)
+/** Condition code 2. */
+#define X86_FSW_C2          RT_BIT(10)
+/** Top of the stack mask. */
+#define X86_FSW_TOP_MASK    UINT16_C(0x3800)
+/** TOP shift value. */
+#define X86_FSW_TOP_SHIFT   11
+/** Mask for getting TOP value after shifting it right. */
+#define X86_FSW_TOP_SMASK   UINT16_C(0x0007)
+/** Get the TOP value. */
+#define X86_FSW_TOP_GET(a_uFsw) (((a_uFsw) >> X86_FSW_TOP_SHIFT) & X86_FSW_TOP_SMASK)
+/** Condition code 3. */
+#define X86_FSW_C3          RT_BIT(14)
+/** Mask of exceptions flags, including the summary bit. */
+#define X86_FSW_C_MASK      UINT16_C(0x4700)
+/** FPU busy. */
+#define X86_FSW_B           RT_BIT(15)
+/** @} */
+
+
+/** @name FPU control word flags.
+ * @{ */
+/** Exception Mask: Invalid operation.  */
+#define X86_FCW_IM          RT_BIT(0)
+/** Exception Mask: Denormalized operand.  */
+#define X86_FCW_DM          RT_BIT(1)
+/** Exception Mask: Zero divide.  */
+#define X86_FCW_ZM          RT_BIT(2)
+/** Exception Mask: Overflow.  */
+#define X86_FCW_OM          RT_BIT(3)
+/** Exception Mask: Underflow.  */
+#define X86_FCW_UM          RT_BIT(4)
+/** Exception Mask: Precision.  */
+#define X86_FCW_PM          RT_BIT(5)
+/** Mask all exceptions, the value typically loaded (by for instance fninit).
+ * @remarks This includes reserved bit 6.  */
+#define X86_FCW_MASK_ALL    UINT16_C(0x007f)
+/** Mask all exceptions. Same as X86_FSW_XCPT_MASK. */
+#define X86_FCW_XCPT_MASK    UINT16_C(0x003f)
+/** Precision control mask. */
+#define X86_FCW_PC_MASK     UINT16_C(0x0300)
+/** Precision control: 24-bit. */
+#define X86_FCW_PC_24       UINT16_C(0x0000)
+/** Precision control: Reserved. */
+#define X86_FCW_PC_RSVD     UINT16_C(0x0100)
+/** Precision control: 53-bit. */
+#define X86_FCW_PC_53       UINT16_C(0x0200)
+/** Precision control: 64-bit. */
+#define X86_FCW_PC_64       UINT16_C(0x0300)
+/** Rounding control mask. */
+#define X86_FCW_RC_MASK     UINT16_C(0x0c00)
+/** Rounding control: To nearest. */
+#define X86_FCW_RC_NEAREST  UINT16_C(0x0000)
+/** Rounding control: Down. */
+#define X86_FCW_RC_DOWN     UINT16_C(0x0400)
+/** Rounding control: Up. */
+#define X86_FCW_RC_UP       UINT16_C(0x0800)
+/** Rounding control: Towards zero. */
+#define X86_FCW_RC_ZERO     UINT16_C(0x0c00)
+/** Bits which should be zero, apparently. */
+#define X86_FCW_ZERO_MASK   UINT16_C(0xf080)
+/** @} */
+
+/** @name SSE MXCSR
+ * @{ */
+/** Exception Flag: Invalid operation.  */
+#define X86_MXSCR_IE          RT_BIT(0)
+/** Exception Flag: Denormalized operand.  */
+#define X86_MXSCR_DE          RT_BIT(1)
+/** Exception Flag: Zero divide.  */
+#define X86_MXSCR_ZE          RT_BIT(2)
+/** Exception Flag: Overflow.  */
+#define X86_MXSCR_OE          RT_BIT(3)
+/** Exception Flag: Underflow.  */
+#define X86_MXSCR_UE          RT_BIT(4)
+/** Exception Flag: Precision.  */
+#define X86_MXSCR_PE          RT_BIT(5)
+
+/** Denormals are zero. */
+#define X86_MXSCR_DAZ         RT_BIT(6)
+
+/** Exception Mask: Invalid operation. */
+#define X86_MXSCR_IM          RT_BIT(7)
+/** Exception Mask: Denormalized operand. */
+#define X86_MXSCR_DM          RT_BIT(8)
+/** Exception Mask: Zero divide.  */
+#define X86_MXSCR_ZM          RT_BIT(9)
+/** Exception Mask: Overflow.  */
+#define X86_MXSCR_OM          RT_BIT(10)
+/** Exception Mask: Underflow.  */
+#define X86_MXSCR_UM          RT_BIT(11)
+/** Exception Mask: Precision.  */
+#define X86_MXSCR_PM          RT_BIT(12)
+
+/** Rounding control mask. */
+#define X86_MXSCR_RC_MASK     UINT16_C(0x6000)
+/** Rounding control: To nearest. */
+#define X86_MXSCR_RC_NEAREST  UINT16_C(0x0000)
+/** Rounding control: Down. */
+#define X86_MXSCR_RC_DOWN     UINT16_C(0x2000)
+/** Rounding control: Up. */
+#define X86_MXSCR_RC_UP       UINT16_C(0x4000)
+/** Rounding control: Towards zero. */
+#define X86_MXSCR_RC_ZERO     UINT16_C(0x6000)
+
+/** Flush-to-zero for masked underflow.  */
+#define X86_MXSCR_FZ          RT_BIT(15)
+
+/** Misaligned Exception Mask (AMD MISALIGNSSE).  */
+#define X86_MXSCR_MM          RT_BIT(17)
+/** @} */
+
+/**
+ * XSAVE header.
+ */
+typedef struct X86XSAVEHDR
+{
+    /** XTATE_BV - Bitmap indicating whether a component is in the state. */
+    uint64_t        bmXState;
+    /** XCOMP_BC - Bitmap used by instructions applying structure compaction. */
+    uint64_t        bmXComp;
+    /** Reserved for furture extensions, probably MBZ. */
+    uint64_t        au64Reserved[6];
+} X86XSAVEHDR;
+#ifndef VBOX_FOR_DTRACE_LIB
+AssertCompileSize(X86XSAVEHDR, 64);
+#endif
+/** Pointer to an XSAVE header. */
+typedef X86XSAVEHDR *PX86XSAVEHDR;
+/** Pointer to a const XSAVE header. */
+typedef X86XSAVEHDR const *PCX86XSAVEHDR;
+
+
+/**
+ * The high 128-bit YMM register state (XSAVE_C_YMM).
+ * (The lower 128-bits being in X86FXSTATE.)
+ */
+typedef struct X86XSAVEYMMHI
+{
+    /** 16 registers in 64-bit mode, 8 in 32-bit mode. */
+    X86XMMREG       aYmmHi[16];
+} X86XSAVEYMMHI;
+#ifndef VBOX_FOR_DTRACE_LIB
+AssertCompileSize(X86XSAVEYMMHI, 256);
+#endif
+/** Pointer to a high 128-bit YMM register state. */
+typedef X86XSAVEYMMHI *PX86XSAVEYMMHI;
+/** Pointer to a const high 128-bit YMM register state. */
+typedef X86XSAVEYMMHI const *PCX86XSAVEYMMHI;
+
+/**
+ * Intel MPX bound registers state (XSAVE_C_BNDREGS).
+ */
+typedef struct X86XSAVEBNDREGS
+{
+    /** Array of registers (BND0...BND3). */
+    struct
+    {
+        /** Lower bound. */
+        uint64_t    uLowerBound;
+        /** Upper bound. */
+        uint64_t    uUpperBound;
+    } aRegs[4];
+} X86XSAVEBNDREGS;
+#ifndef VBOX_FOR_DTRACE_LIB
+AssertCompileSize(X86XSAVEBNDREGS, 64);
+#endif
+/** Pointer to a MPX bound register state. */
+typedef X86XSAVEBNDREGS *PX86XSAVEBNDREGS;
+/** Pointer to a const MPX bound register state. */
+typedef X86XSAVEBNDREGS const *PCX86XSAVEBNDREGS;
+
+/**
+ * Intel MPX bound config and status register state (XSAVE_C_BNDCSR).
+ */
+typedef struct X86XSAVEBNDCFG
+{
+    uint64_t        fConfig;
+    uint64_t        fStatus;
+} X86XSAVEBNDCFG;
+#ifndef VBOX_FOR_DTRACE_LIB
+AssertCompileSize(X86XSAVEBNDCFG, 16);
+#endif
+/** Pointer to a MPX bound config and status register state. */
+typedef X86XSAVEBNDCFG *PX86XSAVEBNDCFG;
+/** Pointer to a const MPX bound config and status register state. */
+typedef X86XSAVEBNDCFG *PCX86XSAVEBNDCFG;
+
+/**
+ * AVX-512 opmask state (XSAVE_C_OPMASK).
+ */
+typedef struct X86XSAVEOPMASK
+{
+    /** The K0..K7 values. */
+    uint64_t    aKRegs[8];
+} X86XSAVEOPMASK;
+#ifndef VBOX_FOR_DTRACE_LIB
+AssertCompileSize(X86XSAVEOPMASK, 64);
+#endif
+/** Pointer to a AVX-512 opmask state. */
+typedef X86XSAVEOPMASK *PX86XSAVEOPMASK;
+/** Pointer to a const AVX-512 opmask state. */
+typedef X86XSAVEOPMASK const *PCX86XSAVEOPMASK;
+
+/**
+ * ZMM0-15 upper 256 bits introduced in AVX-512 (XSAVE_C_ZMM_HI256).
+ */
+typedef struct X86XSAVEZMMHI256
+{
+    /** Upper 256-bits of ZMM0-15. */
+    X86YMMREG   aHi256Regs[16];
+} X86XSAVEZMMHI256;
+#ifndef VBOX_FOR_DTRACE_LIB
+AssertCompileSize(X86XSAVEZMMHI256, 512);
+#endif
+/** Pointer to a state comprising the upper 256-bits of ZMM0-15. */
+typedef X86XSAVEZMMHI256 *PX86XSAVEZMMHI256;
+/** Pointer to a const state comprising the upper 256-bits of ZMM0-15. */
+typedef X86XSAVEZMMHI256 const *PCX86XSAVEZMMHI256;
+
+/**
+ * ZMM16-31 register state introduced in AVX-512 (XSAVE_C_ZMM_16HI).
+ */
+typedef struct X86XSAVEZMM16HI
+{
+    /** ZMM16 thru ZMM31. */
+    X86ZMMREG   aRegs[16];
+} X86XSAVEZMM16HI;
+#ifndef VBOX_FOR_DTRACE_LIB
+AssertCompileSize(X86XSAVEZMM16HI, 1024);
+#endif
+/** Pointer to a state comprising ZMM16-32. */
+typedef X86XSAVEZMM16HI *PX86XSAVEZMM16HI;
+/** Pointer to a const state comprising ZMM16-32. */
+typedef X86XSAVEZMM16HI const *PCX86XSAVEZMM16HI;
+
+/**
+ * AMD Light weight profiling state (XSAVE_C_LWP).
+ *
+ * We probably won't play with this as AMD seems to be dropping from their "zen"
+ * processor micro architecture.
+ */
+typedef struct X86XSAVELWP
+{
+    /** Details when needed. */
+    uint64_t        auLater[128/8];
+} X86XSAVELWP;
+#ifndef VBOX_FOR_DTRACE_LIB
+AssertCompileSize(X86XSAVELWP, 128);
+#endif
+
+
+/**
+ * x86 FPU/SSE/AVX/XXXX state.
+ *
+ * Please bump DBGFCORE_FMT_VERSION by 1 in dbgfcorefmt.h if you make any
+ * changes to this structure.
+ */
+typedef struct X86XSAVEAREA
+{
+    /** The x87 and SSE region (or legacy region if you like).  */
+    X86FXSTATE      x87;
+    /** The XSAVE header. */
+    X86XSAVEHDR     Hdr;
+    /** Beyond the header, there isn't really a fixed layout, but we can
+       generally assume the YMM (AVX) register extensions are present and
+       follows immediately. */
+    union
+    {
+        /** This is a typical layout on intel CPUs (good for debuggers). */
+        struct
+        {
+            X86XSAVEYMMHI       YmmHi;
+            X86XSAVEBNDREGS     BndRegs;
+            X86XSAVEBNDCFG      BndCfg;
+            uint8_t             abFudgeToMatchDocs[0xB0];
+            X86XSAVEOPMASK      Opmask;
+            X86XSAVEZMMHI256    ZmmHi256;
+            X86XSAVEZMM16HI     Zmm16Hi;
+        } Intel;
+
+        /** This is a typical layout on AMD Bulldozer type CPUs (good for debuggers). */
+        struct
+        {
+            X86XSAVEYMMHI       YmmHi;
+            X86XSAVELWP         Lwp;
+        } AmdBd;
+
+        /** To enbling static deployments that have a reasonable chance of working for
+         * the next 3-6 CPU generations without running short on space, we allocate a
+         * lot of extra space here, making the structure a round 8KB in size.  This
+         * leaves us 7616 bytes for extended state.  The skylake xeons are likely to use
+         * 2112 of these, leaving us with 5504 bytes for future Intel generations. */
+        uint8_t         ab[8192 - 512 - 64];
+    } u;
+} X86XSAVEAREA;
+#ifndef VBOX_FOR_DTRACE_LIB
+AssertCompileSize(X86XSAVEAREA, 8192);
+AssertCompileMemberSize(X86XSAVEAREA, u.Intel, 0x840 /*2112 => total 0xa80 (2688) */);
+AssertCompileMemberOffset(X86XSAVEAREA, Hdr,                0x200);
+AssertCompileMemberOffset(X86XSAVEAREA, u.Intel.YmmHi,      0x240);
+AssertCompileMemberOffset(X86XSAVEAREA, u.Intel.BndRegs,    0x340);
+AssertCompileMemberOffset(X86XSAVEAREA, u.Intel.BndCfg,     0x380);
+AssertCompileMemberOffset(X86XSAVEAREA, u.Intel.Opmask,     0x440 /* 1088 */);
+AssertCompileMemberOffset(X86XSAVEAREA, u.Intel.ZmmHi256,   0x480 /* 1152 */);
+AssertCompileMemberOffset(X86XSAVEAREA, u.Intel.Zmm16Hi,    0x680 /* 1664 */);
+#endif
+/** Pointer to a XSAVE area. */
+typedef X86XSAVEAREA *PX86XSAVEAREA;
+/** Pointer to a const XSAVE area. */
+typedef X86XSAVEAREA const *PCX86XSAVEAREA;
+
+
+/** @name XSAVE_C_XXX - XSAVE State Components Bits.
+ * @{ */
+/** Bit 0 - x87 - Legacy FPU state (bit number) */
+#define XSAVE_C_X87_BIT         0
+/** Bit 0 - x87 - Legacy FPU state. */
+#define XSAVE_C_X87             RT_BIT_64(XSAVE_C_X87_BIT)
+/** Bit 1 - SSE - 128-bit SSE state (bit number). */
+#define XSAVE_C_SSE_BIT         1
+/** Bit 1 - SSE - 128-bit SSE state. */
+#define XSAVE_C_SSE             RT_BIT_64(XSAVE_C_SSE_BIT)
+/** Bit 2 - YMM_Hi128 - Upper 128 bits of YMM0-15 (AVX) (bit number). */
+#define XSAVE_C_YMM_BIT         2
+/** Bit 2 - YMM_Hi128 - Upper 128 bits of YMM0-15 (AVX). */
+#define XSAVE_C_YMM             RT_BIT_64(XSAVE_C_YMM_BIT)
+/** Bit 3 - BNDREGS - MPX bound register state (bit number). */
+#define XSAVE_C_BNDREGS_BIT     3
+/** Bit 3 - BNDREGS - MPX bound register state. */
+#define XSAVE_C_BNDREGS         RT_BIT_64(XSAVE_C_BNDREGS_BIT)
+/** Bit 4 - BNDCSR - MPX bound config and status state (bit number). */
+#define XSAVE_C_BNDCSR_BIT      4
+/** Bit 4 - BNDCSR - MPX bound config and status state. */
+#define XSAVE_C_BNDCSR          RT_BIT_64(XSAVE_C_BNDCSR_BIT)
+/** Bit 5 - Opmask - opmask state (bit number). */
+#define XSAVE_C_OPMASK_BIT      5
+/** Bit 5 - Opmask - opmask state. */
+#define XSAVE_C_OPMASK          RT_BIT_64(XSAVE_C_OPMASK_BIT)
+/** Bit 6 - ZMM_Hi256 - Upper 256 bits of ZMM0-15 (AVX-512) (bit number). */
+#define XSAVE_C_ZMM_HI256_BIT   6
+/** Bit 6 - ZMM_Hi256 - Upper 256 bits of ZMM0-15 (AVX-512). */
+#define XSAVE_C_ZMM_HI256       RT_BIT_64(XSAVE_C_ZMM_HI256_BIT)
+/** Bit 7 - Hi16_ZMM - 512-bits ZMM16-31 state (AVX-512) (bit number). */
+#define XSAVE_C_ZMM_16HI_BIT    7
+/** Bit 7 - Hi16_ZMM - 512-bits ZMM16-31 state (AVX-512). */
+#define XSAVE_C_ZMM_16HI        RT_BIT_64(XSAVE_C_ZMM_16HI_BIT)
+/** Bit 9 - PKRU - Protection-key state (bit number). */
+#define XSAVE_C_PKRU_BIT        9
+/** Bit 9 - PKRU - Protection-key state. */
+#define XSAVE_C_PKRU            RT_BIT_64(XSAVE_C_PKRU_BIT)
+/** Bit 62 - LWP - Lightweight Profiling (AMD) (bit number). */
+#define XSAVE_C_LWP_BIT         62
+/** Bit 62 - LWP - Lightweight Profiling (AMD). */
+#define XSAVE_C_LWP             RT_BIT_64(XSAVE_C_LWP_BIT)
+/** @} */
+
+
+
+/** @name Selector Descriptor
+ * @{
+ */
+
+#ifndef VBOX_FOR_DTRACE_LIB
+/**
+ * Descriptor attributes (as seen by VT-x).
+ */
+typedef struct X86DESCATTRBITS
+{
+    /** 00 - Segment Type. */
+    unsigned    u4Type : 4;
+    /** 04 - Descriptor Type. System(=0) or code/data selector */
+    unsigned    u1DescType : 1;
+    /** 05 - Descriptor Privilege level. */
+    unsigned    u2Dpl : 2;
+    /** 07 - Flags selector present(=1) or not. */
+    unsigned    u1Present : 1;
+    /** 08 - Segment limit 16-19. */
+    unsigned    u4LimitHigh : 4;
+    /** 0c - Available for system software. */
+    unsigned    u1Available : 1;
+    /** 0d - 32 bits mode: Reserved - 0, long mode: Long Attribute Bit. */
+    unsigned    u1Long : 1;
+    /** 0e - This flags meaning depends on the segment type. Try make sense out
+     * of the intel manual yourself.  */
+    unsigned    u1DefBig : 1;
+    /** 0f - Granularity of the limit. If set 4KB granularity is used, if
+     * clear byte. */
+    unsigned    u1Granularity : 1;
+    /** 10 - "Unusable" selector, special Intel (VT-x only?) bit. */
+    unsigned    u1Unusable : 1;
+} X86DESCATTRBITS;
+#endif /* !VBOX_FOR_DTRACE_LIB */
+
+/** @name X86DESCATTR masks
+ * @{ */
+#define X86DESCATTR_TYPE            UINT32_C(0x0000000f)
+#define X86DESCATTR_DT              UINT32_C(0x00000010)
+#define X86DESCATTR_DPL             UINT32_C(0x00000060)
+#define X86DESCATTR_DPL_SHIFT       5 /**< Shift count for the DPL value. */
+#define X86DESCATTR_P               UINT32_C(0x00000080)
+#define X86DESCATTR_LIMIT_HIGH      UINT32_C(0x00000f00)
+#define X86DESCATTR_AVL             UINT32_C(0x00001000)
+#define X86DESCATTR_L               UINT32_C(0x00002000)
+#define X86DESCATTR_D               UINT32_C(0x00004000)
+#define X86DESCATTR_G               UINT32_C(0x00008000)
+#define X86DESCATTR_UNUSABLE        UINT32_C(0x00010000)
+/** @}  */
+
+#pragma pack(1)
+typedef union X86DESCATTR
+{
+    /** Unsigned integer view. */
+    uint32_t           u;
+#ifndef VBOX_FOR_DTRACE_LIB
+    /** Normal view. */
+    X86DESCATTRBITS    n;
+#endif
+} X86DESCATTR;
+#pragma pack()
+/** Pointer to descriptor attributes. */
+typedef X86DESCATTR *PX86DESCATTR;
+/** Pointer to const descriptor attributes. */
+typedef const X86DESCATTR *PCX86DESCATTR;
+
+#ifndef VBOX_FOR_DTRACE_LIB
+
+/**
+ * Generic descriptor table entry
+ */
+#pragma pack(1)
+typedef struct X86DESCGENERIC
+{
+    /** 00 - Limit - Low word. */
+    unsigned    u16LimitLow : 16;
+    /** 10 - Base address - lowe word.
+     * Don't try set this to 24 because MSC is doing stupid things then. */
+    unsigned    u16BaseLow : 16;
+    /** 20 - Base address - first 8 bits of high word. */
+    unsigned    u8BaseHigh1 : 8;
+    /** 28 - Segment Type. */
+    unsigned    u4Type : 4;
+    /** 2c - Descriptor Type. System(=0) or code/data selector */
+    unsigned    u1DescType : 1;
+    /** 2d - Descriptor Privilege level. */
+    unsigned    u2Dpl : 2;
+    /** 2f - Flags selector present(=1) or not. */
+    unsigned    u1Present : 1;
+    /** 30 - Segment limit 16-19. */
+    unsigned    u4LimitHigh : 4;
+    /** 34 - Available for system software. */
+    unsigned    u1Available : 1;
+    /** 35 - 32 bits mode: Reserved - 0, long mode: Long Attribute Bit. */
+    unsigned    u1Long : 1;
+    /** 36 - This flags meaning depends on the segment type. Try make sense out
+     * of the intel manual yourself.  */
+    unsigned    u1DefBig : 1;
+    /** 37 - Granularity of the limit. If set 4KB granularity is used, if
+     * clear byte. */
+    unsigned    u1Granularity : 1;
+    /** 38 - Base address - highest 8 bits. */
+    unsigned    u8BaseHigh2 : 8;
+} X86DESCGENERIC;
+#pragma pack()
+/** Pointer to a generic descriptor entry. */
+typedef X86DESCGENERIC *PX86DESCGENERIC;
+/** Pointer to a const generic descriptor entry. */
+typedef const X86DESCGENERIC *PCX86DESCGENERIC;
+
+/** @name Bit offsets of X86DESCGENERIC members.
+ * @{*/
+#define X86DESCGENERIC_BIT_OFF_LIMIT_LOW        (0)   /**< Bit offset of X86DESCGENERIC::u16LimitLow. */
+#define X86DESCGENERIC_BIT_OFF_BASE_LOW         (16)  /**< Bit offset of X86DESCGENERIC::u16BaseLow. */
+#define X86DESCGENERIC_BIT_OFF_BASE_HIGH1       (32)  /**< Bit offset of X86DESCGENERIC::u8BaseHigh1. */
+#define X86DESCGENERIC_BIT_OFF_TYPE             (40)  /**< Bit offset of X86DESCGENERIC::u4Type. */
+#define X86DESCGENERIC_BIT_OFF_DESC_TYPE        (44)  /**< Bit offset of X86DESCGENERIC::u1DescType. */
+#define X86DESCGENERIC_BIT_OFF_DPL              (45)  /**< Bit offset of X86DESCGENERIC::u2Dpl. */
+#define X86DESCGENERIC_BIT_OFF_PRESENT          (47)  /**< Bit offset of X86DESCGENERIC::uu1Present. */
+#define X86DESCGENERIC_BIT_OFF_LIMIT_HIGH       (48)  /**< Bit offset of X86DESCGENERIC::u4LimitHigh. */
+#define X86DESCGENERIC_BIT_OFF_AVAILABLE        (52)  /**< Bit offset of X86DESCGENERIC::u1Available. */
+#define X86DESCGENERIC_BIT_OFF_LONG             (53)  /**< Bit offset of X86DESCGENERIC::u1Long. */
+#define X86DESCGENERIC_BIT_OFF_DEF_BIG          (54)  /**< Bit offset of X86DESCGENERIC::u1DefBig. */
+#define X86DESCGENERIC_BIT_OFF_GRANULARITY      (55)  /**< Bit offset of X86DESCGENERIC::u1Granularity. */
+#define X86DESCGENERIC_BIT_OFF_BASE_HIGH2       (56)  /**< Bit offset of X86DESCGENERIC::u8BaseHigh2. */
+/** @}  */
+
+/**
+ * Call-, Interrupt-, Trap- or Task-gate descriptor (legacy).
+ */
+typedef struct X86DESCGATE
+{
+    /** 00 - Target code segment offset - Low word.
+     * Ignored if task-gate. */
+    unsigned    u16OffsetLow : 16;
+    /** 10 - Target code segment selector for call-, interrupt- and trap-gates,
+     * TSS selector if task-gate. */
+    unsigned    u16Sel : 16;
+    /** 20 - Number of parameters for a call-gate.
+     * Ignored if interrupt-, trap- or task-gate. */
+    unsigned    u4ParmCount : 4;
+    /** 24 - Reserved / ignored. */
+    unsigned    u4Reserved : 4;
+    /** 28 - Segment Type. */
+    unsigned    u4Type : 4;
+    /** 2c - Descriptor Type (0 = system). */
+    unsigned    u1DescType : 1;
+    /** 2d - Descriptor Privilege level. */
+    unsigned    u2Dpl : 2;
+    /** 2f - Flags selector present(=1) or not. */
+    unsigned    u1Present : 1;
+    /** 30 - Target code segment offset - High word.
+     * Ignored if task-gate. */
+    unsigned    u16OffsetHigh : 16;
+} X86DESCGATE;
+/** Pointer to a Call-, Interrupt-, Trap- or Task-gate descriptor entry. */
+typedef X86DESCGATE *PX86DESCGATE;
+/** Pointer to a const Call-, Interrupt-, Trap- or Task-gate descriptor entry. */
+typedef const X86DESCGATE *PCX86DESCGATE;
+
+#endif /* VBOX_FOR_DTRACE_LIB */
+
+/**
+ * Descriptor table entry.
+ */
+#pragma pack(1)
+typedef union X86DESC
+{
+#ifndef VBOX_FOR_DTRACE_LIB
+    /** Generic descriptor view. */
+    X86DESCGENERIC  Gen;
+    /** Gate descriptor view. */
+    X86DESCGATE     Gate;
+#endif
+
+    /** 8 bit unsigned integer view. */
+    uint8_t         au8[8];
+    /** 16 bit unsigned integer view. */
+    uint16_t        au16[4];
+    /** 32 bit unsigned integer view. */
+    uint32_t        au32[2];
+    /** 64 bit unsigned integer view. */
+    uint64_t        au64[1];
+    /** Unsigned integer view. */
+    uint64_t        u;
+} X86DESC;
+#ifndef VBOX_FOR_DTRACE_LIB
+AssertCompileSize(X86DESC, 8);
+#endif
+#pragma pack()
+/** Pointer to descriptor table entry. */
+typedef X86DESC *PX86DESC;
+/** Pointer to const descriptor table entry. */
+typedef const X86DESC *PCX86DESC;
+
+/** @def X86DESC_BASE
+ * Return the base address of a descriptor.
+ */
+#define X86DESC_BASE(a_pDesc) /*ASM-NOINC*/ \
+        (  ((uint32_t)((a_pDesc)->Gen.u8BaseHigh2) << 24) \
+         | (           (a_pDesc)->Gen.u8BaseHigh1  << 16) \
+         | (           (a_pDesc)->Gen.u16BaseLow        ) )
+
+/** @def X86DESC_LIMIT
+ * Return the limit of a descriptor.
+ */
+#define X86DESC_LIMIT(a_pDesc) /*ASM-NOINC*/ \
+        (  ((uint32_t)((a_pDesc)->Gen.u4LimitHigh) << 16) \
+         | (           (a_pDesc)->Gen.u16LimitLow       ) )
+
+/** @def X86DESC_LIMIT_G
+ * Return the limit of a descriptor with the granularity bit taken into account.
+ * @returns Selector limit (uint32_t).
+ * @param   a_pDesc     Pointer to the descriptor.
+ */
+#define X86DESC_LIMIT_G(a_pDesc) /*ASM-NOINC*/ \
+        ( (a_pDesc)->Gen.u1Granularity \
+         ? ( ( ((uint32_t)(a_pDesc)->Gen.u4LimitHigh << 16) | (a_pDesc)->Gen.u16LimitLow ) << 12 ) | UINT32_C(0xfff) \
+         :     ((uint32_t)(a_pDesc)->Gen.u4LimitHigh << 16) | (a_pDesc)->Gen.u16LimitLow \
+        )
+
+/** @def X86DESC_GET_HID_ATTR
+ * Get the descriptor attributes for the hidden register.
+ */
+#define X86DESC_GET_HID_ATTR(a_pDesc) /*ASM-NOINC*/ \
+        ( ((a_pDesc)->u >> (16+16+8)) & UINT32_C(0xf0ff) ) /** @todo do we have a define for 0xf0ff? */
+
+#ifndef VBOX_FOR_DTRACE_LIB
+
+/**
+ * 64 bits generic descriptor table entry
+ * Note: most of these bits have no meaning in long mode.
+ */
+#pragma pack(1)
+typedef struct X86DESC64GENERIC
+{
+    /** Limit - Low word - *IGNORED*. */
+    unsigned    u16LimitLow : 16;
+    /** Base address - low word. - *IGNORED*
+     * Don't try set this to 24 because MSC is doing stupid things then. */
+    unsigned    u16BaseLow : 16;
+    /** Base address - first 8 bits of high word. - *IGNORED* */
+    unsigned    u8BaseHigh1 : 8;
+    /** Segment Type. */
+    unsigned    u4Type : 4;
+    /** Descriptor Type. System(=0) or code/data selector */
+    unsigned    u1DescType : 1;
+    /** Descriptor Privilege level. */
+    unsigned    u2Dpl : 2;
+    /** Flags selector present(=1) or not. */
+    unsigned    u1Present : 1;
+    /** Segment limit 16-19. - *IGNORED* */
+    unsigned    u4LimitHigh : 4;
+    /** Available for system software. - *IGNORED* */
+    unsigned    u1Available : 1;
+    /** Long mode flag. */
+    unsigned    u1Long : 1;
+    /** This flags meaning depends on the segment type. Try make sense out
+     * of the intel manual yourself.  */
+    unsigned    u1DefBig : 1;
+    /** Granularity of the limit. If set 4KB granularity is used, if
+     * clear byte. - *IGNORED* */
+    unsigned    u1Granularity : 1;
+    /** Base address - highest 8 bits. - *IGNORED* */
+    unsigned    u8BaseHigh2 : 8;
+    /** Base address - bits 63-32. */
+    unsigned    u32BaseHigh3    : 32;
+    unsigned    u8Reserved      : 8;
+    unsigned    u5Zeros         : 5;
+    unsigned    u19Reserved     : 19;
+} X86DESC64GENERIC;
+#pragma pack()
+/** Pointer to a generic descriptor entry. */
+typedef X86DESC64GENERIC *PX86DESC64GENERIC;
+/** Pointer to a const generic descriptor entry. */
+typedef const X86DESC64GENERIC *PCX86DESC64GENERIC;
+
+/**
+ * System descriptor table entry (64 bits)
+ *
+ * @remarks This is, save a couple of comments, identical to X86DESC64GENERIC...
+ */
+#pragma pack(1)
+typedef struct X86DESC64SYSTEM
+{
+    /** Limit - Low word. */
+    unsigned    u16LimitLow     : 16;
+    /** Base address - lowe word.
+     * Don't try set this to 24 because MSC is doing stupid things then. */
+    unsigned    u16BaseLow      : 16;
+    /** Base address - first 8 bits of high word. */
+    unsigned    u8BaseHigh1     : 8;
+    /** Segment Type. */
+    unsigned    u4Type          : 4;
+    /** Descriptor Type. System(=0) or code/data selector */
+    unsigned    u1DescType      : 1;
+    /** Descriptor Privilege level. */
+    unsigned    u2Dpl           : 2;
+    /** Flags selector present(=1) or not. */
+    unsigned    u1Present       : 1;
+    /** Segment limit 16-19. */
+    unsigned    u4LimitHigh     : 4;
+    /** Available for system software. */
+    unsigned    u1Available     : 1;
+    /** Reserved - 0. */
+    unsigned    u1Reserved      : 1;
+    /** This flags meaning depends on the segment type. Try make sense out
+     * of the intel manual yourself.  */
+    unsigned    u1DefBig        : 1;
+    /** Granularity of the limit. If set 4KB granularity is used, if
+     * clear byte. */
+    unsigned    u1Granularity   : 1;
+    /** Base address - bits 31-24. */
+    unsigned    u8BaseHigh2     : 8;
+    /** Base address - bits 63-32. */
+    unsigned    u32BaseHigh3    : 32;
+    unsigned    u8Reserved      : 8;
+    unsigned    u5Zeros         : 5;
+    unsigned    u19Reserved     : 19;
+} X86DESC64SYSTEM;
+#pragma pack()
+/** Pointer to a system descriptor entry. */
+typedef X86DESC64SYSTEM *PX86DESC64SYSTEM;
+/** Pointer to a const system descriptor entry. */
+typedef const X86DESC64SYSTEM *PCX86DESC64SYSTEM;
+
+/**
+ * Call-, Interrupt-, Trap- or Task-gate descriptor (64-bit).
+ */
+typedef struct X86DESC64GATE
+{
+    /** Target code segment offset - Low word. */
+    unsigned    u16OffsetLow : 16;
+    /** Target code segment selector. */
+    unsigned    u16Sel : 16;
+    /** Interrupt stack table for interrupt- and trap-gates.
+     * Ignored by call-gates. */
+    unsigned    u3IST : 3;
+    /** Reserved / ignored. */
+    unsigned    u5Reserved : 5;
+    /** Segment Type. */
+    unsigned    u4Type : 4;
+    /** Descriptor Type (0 = system). */
+    unsigned    u1DescType : 1;
+    /** Descriptor Privilege level. */
+    unsigned    u2Dpl : 2;
+    /** Flags selector present(=1) or not. */
+    unsigned    u1Present : 1;
+    /** Target code segment offset - High word.
+     * Ignored if task-gate. */
+    unsigned    u16OffsetHigh : 16;
+    /** Target code segment offset - Top dword.
+     * Ignored if task-gate. */
+    unsigned    u32OffsetTop : 32;
+    /** Reserved / ignored / must be zero.
+     * For call-gates bits 8 thru 12 must be zero, the other gates ignores this. */
+    unsigned    u32Reserved : 32;
+} X86DESC64GATE;
+AssertCompileSize(X86DESC64GATE, 16);
+/** Pointer to a Call-, Interrupt-, Trap- or Task-gate descriptor entry. */
+typedef X86DESC64GATE *PX86DESC64GATE;
+/** Pointer to a const Call-, Interrupt-, Trap- or Task-gate descriptor entry. */
+typedef const X86DESC64GATE *PCX86DESC64GATE;
+
+#endif /* VBOX_FOR_DTRACE_LIB */
+
+/**
+ * Descriptor table entry.
+ */
+#pragma pack(1)
+typedef union X86DESC64
+{
+#ifndef VBOX_FOR_DTRACE_LIB
+    /** Generic descriptor view. */
+    X86DESC64GENERIC    Gen;
+    /** System descriptor view. */
+    X86DESC64SYSTEM     System;
+    /** Gate descriptor view. */
+    X86DESC64GATE       Gate;
+#endif
+
+    /** 8 bit unsigned integer view. */
+    uint8_t             au8[16];
+    /** 16 bit unsigned integer view. */
+    uint16_t            au16[8];
+    /** 32 bit unsigned integer view. */
+    uint32_t            au32[4];
+    /** 64 bit unsigned integer view. */
+    uint64_t            au64[2];
+} X86DESC64;
+#ifndef VBOX_FOR_DTRACE_LIB
+AssertCompileSize(X86DESC64, 16);
+#endif
+#pragma pack()
+/** Pointer to descriptor table entry. */
+typedef X86DESC64 *PX86DESC64;
+/** Pointer to const descriptor table entry. */
+typedef const X86DESC64 *PCX86DESC64;
+
+/** @def X86DESC64_BASE
+ * Return the base of a 64-bit descriptor.
+ */
+#define X86DESC64_BASE(a_pDesc) /*ASM-NOINC*/ \
+        (  ((uint64_t)((a_pDesc)->Gen.u32BaseHigh3) << 32) \
+         | ((uint32_t)((a_pDesc)->Gen.u8BaseHigh2)  << 24) \
+         | (           (a_pDesc)->Gen.u8BaseHigh1   << 16) \
+         | (           (a_pDesc)->Gen.u16BaseLow         ) )
+
+
+
+/** @name Host system descriptor table entry - Use with care!
+ * @{ */
+/** Host system descriptor table entry. */
+#if HC_ARCH_BITS == 64
+typedef X86DESC64   X86DESCHC;
+#else
+typedef X86DESC     X86DESCHC;
+#endif
+/** Pointer to a host system descriptor table entry. */
+#if HC_ARCH_BITS == 64
+typedef PX86DESC64  PX86DESCHC;
+#else
+typedef PX86DESC    PX86DESCHC;
+#endif
+/** Pointer to a const host system descriptor table entry. */
+#if HC_ARCH_BITS == 64
+typedef PCX86DESC64 PCX86DESCHC;
+#else
+typedef PCX86DESC   PCX86DESCHC;
+#endif
+/** @} */
+
+
+/** @name Selector Descriptor Types.
+ * @{
+ */
+
+/** @name Non-System Selector Types.
+ * @{ */
+/** Code(=set)/Data(=clear) bit. */
+#define X86_SEL_TYPE_CODE                   8
+/** Memory(=set)/System(=clear) bit. */
+#define X86_SEL_TYPE_MEMORY                 RT_BIT(4)
+/** Accessed bit. */
+#define X86_SEL_TYPE_ACCESSED               1
+/** Expand down bit (for data selectors only). */
+#define X86_SEL_TYPE_DOWN                   4
+/** Conforming bit (for code selectors only). */
+#define X86_SEL_TYPE_CONF                   4
+/** Write bit (for data selectors only). */
+#define X86_SEL_TYPE_WRITE                  2
+/** Read bit (for code selectors only). */
+#define X86_SEL_TYPE_READ                   2
+/** The bit number of the code segment read bit (relative to u4Type). */
+#define X86_SEL_TYPE_READ_BIT               1
+
+/** Read only selector type. */
+#define X86_SEL_TYPE_RO                     0
+/** Accessed read only selector type. */
+#define X86_SEL_TYPE_RO_ACC                (0 | X86_SEL_TYPE_ACCESSED)
+/** Read write selector type. */
+#define X86_SEL_TYPE_RW                     2
+/** Accessed read write selector type. */
+#define X86_SEL_TYPE_RW_ACC                (2 | X86_SEL_TYPE_ACCESSED)
+/** Expand down read only selector type. */
+#define X86_SEL_TYPE_RO_DOWN                4
+/** Accessed expand down read only selector type. */
+#define X86_SEL_TYPE_RO_DOWN_ACC           (4 | X86_SEL_TYPE_ACCESSED)
+/** Expand down read write selector type. */
+#define X86_SEL_TYPE_RW_DOWN                6
+/** Accessed expand down read write selector type. */
+#define X86_SEL_TYPE_RW_DOWN_ACC           (6 | X86_SEL_TYPE_ACCESSED)
+/** Execute only selector type. */
+#define X86_SEL_TYPE_EO                    (0 | X86_SEL_TYPE_CODE)
+/** Accessed execute only selector type. */
+#define X86_SEL_TYPE_EO_ACC                (0 | X86_SEL_TYPE_CODE | X86_SEL_TYPE_ACCESSED)
+/** Execute and read selector type. */
+#define X86_SEL_TYPE_ER                    (2 | X86_SEL_TYPE_CODE)
+/** Accessed execute and read selector type. */
+#define X86_SEL_TYPE_ER_ACC                (2 | X86_SEL_TYPE_CODE | X86_SEL_TYPE_ACCESSED)
+/** Conforming execute only selector type. */
+#define X86_SEL_TYPE_EO_CONF               (4 | X86_SEL_TYPE_CODE)
+/** Accessed Conforming execute only selector type. */
+#define X86_SEL_TYPE_EO_CONF_ACC           (4 | X86_SEL_TYPE_CODE | X86_SEL_TYPE_ACCESSED)
+/** Conforming execute and write selector type. */
+#define X86_SEL_TYPE_ER_CONF               (6 | X86_SEL_TYPE_CODE)
+/** Accessed Conforming execute and write selector type. */
+#define X86_SEL_TYPE_ER_CONF_ACC           (6 | X86_SEL_TYPE_CODE | X86_SEL_TYPE_ACCESSED)
+/** @} */
+
+
+/** @name System Selector Types.
+ * @{ */
+/** The TSS busy bit mask. */
+#define X86_SEL_TYPE_SYS_TSS_BUSY_MASK      2
+
+/** Undefined system selector type. */
+#define X86_SEL_TYPE_SYS_UNDEFINED          0
+/** 286 TSS selector. */
+#define X86_SEL_TYPE_SYS_286_TSS_AVAIL      1
+/** LDT selector. */
+#define X86_SEL_TYPE_SYS_LDT                2
+/** 286 TSS selector - Busy. */
+#define X86_SEL_TYPE_SYS_286_TSS_BUSY       3
+/** 286 Callgate selector. */
+#define X86_SEL_TYPE_SYS_286_CALL_GATE      4
+/** Taskgate selector. */
+#define X86_SEL_TYPE_SYS_TASK_GATE          5
+/** 286 Interrupt gate selector. */
+#define X86_SEL_TYPE_SYS_286_INT_GATE       6
+/** 286 Trapgate selector. */
+#define X86_SEL_TYPE_SYS_286_TRAP_GATE      7
+/** Undefined system selector. */
+#define X86_SEL_TYPE_SYS_UNDEFINED2         8
+/** 386 TSS selector. */
+#define X86_SEL_TYPE_SYS_386_TSS_AVAIL      9
+/** Undefined system selector. */
+#define X86_SEL_TYPE_SYS_UNDEFINED3         0xA
+/** 386 TSS selector - Busy. */
+#define X86_SEL_TYPE_SYS_386_TSS_BUSY       0xB
+/** 386 Callgate selector. */
+#define X86_SEL_TYPE_SYS_386_CALL_GATE      0xC
+/** Undefined system selector. */
+#define X86_SEL_TYPE_SYS_UNDEFINED4         0xD
+/** 386 Interruptgate selector. */
+#define X86_SEL_TYPE_SYS_386_INT_GATE       0xE
+/** 386 Trapgate selector. */
+#define X86_SEL_TYPE_SYS_386_TRAP_GATE      0xF
+/** @} */
+
+/** @name AMD64 System Selector Types.
+ * @{ */
+/** LDT selector. */
+#define AMD64_SEL_TYPE_SYS_LDT              2
+/** TSS selector - Busy. */
+#define AMD64_SEL_TYPE_SYS_TSS_AVAIL        9
+/** TSS selector - Busy. */
+#define AMD64_SEL_TYPE_SYS_TSS_BUSY         0xB
+/** Callgate selector. */
+#define AMD64_SEL_TYPE_SYS_CALL_GATE        0xC
+/** Interruptgate selector. */
+#define AMD64_SEL_TYPE_SYS_INT_GATE         0xE
+/** Trapgate selector. */
+#define AMD64_SEL_TYPE_SYS_TRAP_GATE        0xF
+/** @} */
+
+/** @} */
+
+
+/** @name Descriptor Table Entry Flag Masks.
+ * These are for the 2nd 32-bit word of a descriptor.
+ * @{ */
+/** Bits 8-11 - TYPE - Descriptor type mask. */
+#define X86_DESC_TYPE_MASK                  (RT_BIT(8) | RT_BIT(9) | RT_BIT(10) | RT_BIT(11))
+/** Bit 12 - S - System (=0) or Code/Data (=1). */
+#define X86_DESC_S                          RT_BIT(12)
+/** Bits 13-14 - DPL - Descriptor Privilege Level. */
+#define X86_DESC_DPL                       (RT_BIT(13) | RT_BIT(14))
+/** Bit 15 - P - Present. */
+#define X86_DESC_P                          RT_BIT(15)
+/** Bit 20 - AVL - Available for system software. */
+#define X86_DESC_AVL                        RT_BIT(20)
+/** Bit 22 - DB - Default operation size. 0 = 16 bit, 1 = 32 bit. */
+#define X86_DESC_DB                         RT_BIT(22)
+/** Bit 23 - G - Granularity of the limit. If set 4KB granularity is
+ * used, if clear byte. */
+#define X86_DESC_G                          RT_BIT(23)
+/** @} */
+
+/** @} */
+
+
+/** @name Task Segments.
+ * @{
+ */
+
+/**
+ * The minimum TSS descriptor limit for 286 tasks.
+ */
+#define X86_SEL_TYPE_SYS_286_TSS_LIMIT_MIN      0x2b
+
+/**
+ * The minimum TSS descriptor segment limit for 386 tasks.
+ */
+#define X86_SEL_TYPE_SYS_386_TSS_LIMIT_MIN      0x67
+
+/**
+ * 16-bit Task Segment (TSS).
+ */
+#pragma pack(1)
+typedef struct X86TSS16
+{
+    /** Back link to previous task. (static) */
+    RTSEL       selPrev;
+    /** Ring-0 stack pointer. (static) */
+    uint16_t    sp0;
+    /** Ring-0 stack segment. (static) */
+    RTSEL       ss0;
+    /** Ring-1 stack pointer. (static) */
+    uint16_t    sp1;
+    /** Ring-1 stack segment. (static) */
+    RTSEL       ss1;
+    /** Ring-2 stack pointer. (static) */
+    uint16_t    sp2;
+    /** Ring-2 stack segment. (static) */
+    RTSEL       ss2;
+    /** IP before task switch. */
+    uint16_t    ip;
+    /** FLAGS before task switch. */
+    uint16_t    flags;
+    /** AX before task switch. */
+    uint16_t    ax;
+    /** CX before task switch. */
+    uint16_t    cx;
+    /** DX before task switch. */
+    uint16_t    dx;
+    /** BX before task switch. */
+    uint16_t    bx;
+    /** SP before task switch. */
+    uint16_t    sp;
+    /** BP before task switch. */
+    uint16_t    bp;
+    /** SI before task switch. */
+    uint16_t    si;
+    /** DI before task switch. */
+    uint16_t    di;
+    /** ES before task switch. */
+    RTSEL       es;
+    /** CS before task switch. */
+    RTSEL       cs;
+    /** SS before task switch. */
+    RTSEL       ss;
+    /** DS before task switch. */
+    RTSEL       ds;
+    /** LDTR before task switch. */
+    RTSEL       selLdt;
+} X86TSS16;
+#ifndef VBOX_FOR_DTRACE_LIB
+AssertCompileSize(X86TSS16, X86_SEL_TYPE_SYS_286_TSS_LIMIT_MIN + 1);
+#endif
+#pragma pack()
+/** Pointer to a 16-bit task segment. */
+typedef X86TSS16 *PX86TSS16;
+/** Pointer to a const 16-bit task segment. */
+typedef const X86TSS16 *PCX86TSS16;
+
+
+/**
+ * 32-bit Task Segment (TSS).
+ */
+#pragma pack(1)
+typedef struct X86TSS32
+{
+    /** Back link to previous task. (static) */
+    RTSEL       selPrev;
+    uint16_t    padding1;
+    /** Ring-0 stack pointer. (static) */
+    uint32_t    esp0;
+    /** Ring-0 stack segment. (static) */
+    RTSEL       ss0;
+    uint16_t    padding_ss0;
+    /** Ring-1 stack pointer. (static) */
+    uint32_t    esp1;
+    /** Ring-1 stack segment. (static) */
+    RTSEL       ss1;
+    uint16_t    padding_ss1;
+    /** Ring-2 stack pointer. (static) */
+    uint32_t    esp2;
+    /** Ring-2 stack segment. (static) */
+    RTSEL       ss2;
+    uint16_t    padding_ss2;
+    /** Page directory for the task. (static) */
+    uint32_t    cr3;
+    /** EIP before task switch. */
+    uint32_t    eip;
+    /** EFLAGS before task switch. */
+    uint32_t    eflags;
+    /** EAX before task switch. */
+    uint32_t    eax;
+    /** ECX before task switch. */
+    uint32_t    ecx;
+    /** EDX before task switch. */
+    uint32_t    edx;
+    /** EBX before task switch. */
+    uint32_t    ebx;
+    /** ESP before task switch. */
+    uint32_t    esp;
+    /** EBP before task switch. */
+    uint32_t    ebp;
+    /** ESI before task switch. */
+    uint32_t    esi;
+    /** EDI before task switch. */
+    uint32_t    edi;
+    /** ES before task switch. */
+    RTSEL       es;
+    uint16_t    padding_es;
+    /** CS before task switch. */
+    RTSEL       cs;
+    uint16_t    padding_cs;
+    /** SS before task switch. */
+    RTSEL       ss;
+    uint16_t    padding_ss;
+    /** DS before task switch. */
+    RTSEL       ds;
+    uint16_t    padding_ds;
+    /** FS before task switch. */
+    RTSEL       fs;
+    uint16_t    padding_fs;
+    /** GS before task switch. */
+    RTSEL       gs;
+    uint16_t    padding_gs;
+    /** LDTR before task switch. */
+    RTSEL       selLdt;
+    uint16_t    padding_ldt;
+    /** Debug trap flag */
+    uint16_t    fDebugTrap;
+    /** Offset relative to the TSS of the start of the I/O Bitmap
+     * and the end of the interrupt redirection bitmap. */
+    uint16_t    offIoBitmap;
+    /** 32 bytes for the virtual interrupt redirection bitmap. (VME) */
+    uint8_t     IntRedirBitmap[32];
+} X86TSS32;
+#pragma pack()
+/** Pointer to task segment. */
+typedef X86TSS32 *PX86TSS32;
+/** Pointer to const task segment. */
+typedef const X86TSS32 *PCX86TSS32;
+
+/**
+ * 64-bit Task segment.
+ */
+#pragma pack(1)
+typedef struct X86TSS64
+{
+    /** Reserved. */
+    uint32_t    u32Reserved;
+    /** Ring-0 stack pointer. (static) */
+    uint64_t    rsp0;
+    /** Ring-1 stack pointer. (static) */
+    uint64_t    rsp1;
+    /** Ring-2 stack pointer. (static) */
+    uint64_t    rsp2;
+    /** Reserved. */
+    uint32_t    u32Reserved2[2];
+    /* IST */
+    uint64_t    ist1;
+    uint64_t    ist2;
+    uint64_t    ist3;
+    uint64_t    ist4;
+    uint64_t    ist5;
+    uint64_t    ist6;
+    uint64_t    ist7;
+    /* Reserved. */
+    uint16_t    u16Reserved[5];
+    /** Offset relative to the TSS of the start of the I/O Bitmap
+     * and the end of the interrupt redirection bitmap. */
+    uint16_t    offIoBitmap;
+    /** 32 bytes for the virtual interrupt redirection bitmap. (VME) */
+    uint8_t     IntRedirBitmap[32];
+} X86TSS64;
+#pragma pack()
+/** Pointer to a 64-bit task segment. */
+typedef X86TSS64 *PX86TSS64;
+/** Pointer to a const 64-bit task segment. */
+typedef const X86TSS64 *PCX86TSS64;
+#ifndef VBOX_FOR_DTRACE_LIB
+AssertCompileSize(X86TSS64, 136);
+#endif
+
+/** @} */
+
+
+/** @name Selectors.
+ * @{
+ */
+
+/**
+ * The shift used to convert a selector from and to index an index (C).
+ */
+#define X86_SEL_SHIFT           3
+
+/**
+ * The mask used to mask off the table indicator and RPL of an selector.
+ */
+#define X86_SEL_MASK            0xfff8U
+
+/**
+ * The mask used to mask off the RPL of an selector.
+ * This is suitable for checking for NULL selectors.
+ */
+#define X86_SEL_MASK_OFF_RPL    0xfffcU
+
+/**
+ * The bit indicating that a selector is in the LDT and not in the GDT.
+ */
+#define X86_SEL_LDT             0x0004U
+
+/**
+ * The bit mask for getting the RPL of a selector.
+ */
+#define X86_SEL_RPL             0x0003U
+
+/**
+ * The mask covering both RPL and LDT.
+ * This is incidentally the same as sizeof(X86DESC) - 1, so good for limit
+ * checks.
+ */
+#define X86_SEL_RPL_LDT         0x0007U
+
+/** @} */
+
+
+/**
+ * x86 Exceptions/Faults/Traps.
+ */
+typedef enum X86XCPT
+{
+    /** \#DE - Divide error. */
+    X86_XCPT_DE = 0x00,
+    /** \#DB - Debug event (single step, DRx, ..) */
+    X86_XCPT_DB = 0x01,
+    /** NMI - Non-Maskable Interrupt */
+    X86_XCPT_NMI = 0x02,
+    /** \#BP - Breakpoint (INT3). */
+    X86_XCPT_BP = 0x03,
+    /** \#OF - Overflow (INTO). */
+    X86_XCPT_OF = 0x04,
+    /** \#BR - Bound range exceeded (BOUND). */
+    X86_XCPT_BR = 0x05,
+    /** \#UD - Undefined opcode. */
+    X86_XCPT_UD = 0x06,
+    /** \#NM - Device not available (math coprocessor device). */
+    X86_XCPT_NM = 0x07,
+    /** \#DF - Double fault. */
+    X86_XCPT_DF = 0x08,
+    /** ??? - Coprocessor segment overrun (obsolete). */
+    X86_XCPT_CO_SEG_OVERRUN = 0x09,
+    /** \#TS - Taskswitch (TSS). */
+    X86_XCPT_TS = 0x0a,
+    /** \#NP - Segment no present. */
+    X86_XCPT_NP = 0x0b,
+    /** \#SS - Stack segment fault. */
+    X86_XCPT_SS = 0x0c,
+    /** \#GP - General protection fault. */
+    X86_XCPT_GP = 0x0d,
+    /** \#PF - Page fault. */
+    X86_XCPT_PF = 0x0e,
+    /* 0x0f is reserved (to avoid conflict with spurious interrupts in BIOS setup). */
+    /** \#MF - Math fault (FPU). */
+    X86_XCPT_MF = 0x10,
+    /** \#AC - Alignment check. */
+    X86_XCPT_AC = 0x11,
+    /** \#MC - Machine check. */
+    X86_XCPT_MC = 0x12,
+    /** \#XF - SIMD Floating-Pointer Exception. */
+    X86_XCPT_XF = 0x13,
+    /** \#VE - Virtualization Exception. */
+    X86_XCPT_VE = 0x14,
+    /** \#SX - Security Exception. */
+    X86_XCPT_SX = 0x1f
+} X86XCPT;
+/** Pointer to a x86 exception code. */
+typedef X86XCPT *PX86XCPT;
+/** Pointer to a const x86 exception code. */
+typedef const X86XCPT *PCX86XCPT;
+/** The maximum exception value. */
+#define X86_XCPT_MAX                (X86_XCPT_SX)
+
+
+/** @name Trap Error Codes
+ * @{
+ */
+/** External indicator. */
+#define X86_TRAP_ERR_EXTERNAL       1
+/** IDT indicator. */
+#define X86_TRAP_ERR_IDT            2
+/** Descriptor table indicator - If set LDT, if clear GDT. */
+#define X86_TRAP_ERR_TI             4
+/** Mask for getting the selector. */
+#define X86_TRAP_ERR_SEL_MASK       0xfff8
+/** Shift for getting the selector table index (C type index). */
+#define X86_TRAP_ERR_SEL_SHIFT      3
+/** @} */
+
+
+/** @name \#PF Trap Error Codes
+ * @{
+ */
+/** Bit 0 -   P - Not present (clear) or page level protection (set) fault. */
+#define X86_TRAP_PF_P               RT_BIT(0)
+/** Bit 1 - R/W - Read (clear) or write (set) access. */
+#define X86_TRAP_PF_RW              RT_BIT(1)
+/** Bit 2 - U/S - CPU executing in user mode (set) or supervisor mode (clear). */
+#define X86_TRAP_PF_US              RT_BIT(2)
+/** Bit 3 - RSVD- Reserved bit violation (set), i.e. reserved bit was set to 1. */
+#define X86_TRAP_PF_RSVD            RT_BIT(3)
+/** Bit 4 - I/D - Instruction fetch (set) / Data access (clear) - PAE + NXE. */
+#define X86_TRAP_PF_ID              RT_BIT(4)
+/** Bit 5 - PK - Protection-key violation (AMD64 mode only). */
+#define X86_TRAP_PF_PK              RT_BIT(5)
+/** @} */
+
+#pragma pack(1)
+/**
+ * 16-bit IDTR.
+ */
+typedef struct X86IDTR16
+{
+    /** Offset. */
+    uint16_t    offSel;
+    /** Selector. */
+    uint16_t    uSel;
+} X86IDTR16, *PX86IDTR16;
+#pragma pack()
+
+#pragma pack(1)
+/**
+ * 32-bit IDTR/GDTR.
+ */
+typedef struct X86XDTR32
+{
+    /** Size of the descriptor table. */
+    uint16_t    cb;
+    /** Address of the descriptor table. */
+#ifndef VBOX_FOR_DTRACE_LIB
+    uint32_t    uAddr;
+#else
+    uint16_t    au16Addr[2];
+#endif
+} X86XDTR32, *PX86XDTR32;
+#pragma pack()
+
+#pragma pack(1)
+/**
+ * 64-bit IDTR/GDTR.
+ */
+typedef struct X86XDTR64
+{
+    /** Size of the descriptor table. */
+    uint16_t    cb;
+    /** Address of the descriptor table. */
+#ifndef VBOX_FOR_DTRACE_LIB
+    uint64_t    uAddr;
+#else
+    uint16_t    au16Addr[4];
+#endif
+} X86XDTR64, *PX86XDTR64;
+#pragma pack()
+
+
+/** @name ModR/M
+ * @{ */
+#define X86_MODRM_RM_MASK       UINT8_C(0x07)
+#define X86_MODRM_REG_MASK      UINT8_C(0x38)
+#define X86_MODRM_REG_SMASK     UINT8_C(0x07)
+#define X86_MODRM_REG_SHIFT     3
+#define X86_MODRM_MOD_MASK      UINT8_C(0xc0)
+#define X86_MODRM_MOD_SMASK     UINT8_C(0x03)
+#define X86_MODRM_MOD_SHIFT     6
+#ifndef VBOX_FOR_DTRACE_LIB
+AssertCompile((X86_MODRM_RM_MASK | X86_MODRM_REG_MASK | X86_MODRM_MOD_MASK) == 0xff);
+AssertCompile((X86_MODRM_REG_MASK >> X86_MODRM_REG_SHIFT) == X86_MODRM_REG_SMASK);
+AssertCompile((X86_MODRM_MOD_MASK >> X86_MODRM_MOD_SHIFT) == X86_MODRM_MOD_SMASK);
+#endif
+/** @} */
+
+/** @name SIB
+ * @{ */
+#define X86_SIB_BASE_MASK     UINT8_C(0x07)
+#define X86_SIB_INDEX_MASK    UINT8_C(0x38)
+#define X86_SIB_INDEX_SMASK   UINT8_C(0x07)
+#define X86_SIB_INDEX_SHIFT   3
+#define X86_SIB_SCALE_MASK    UINT8_C(0xc0)
+#define X86_SIB_SCALE_SMASK   UINT8_C(0x03)
+#define X86_SIB_SCALE_SHIFT   6
+#ifndef VBOX_FOR_DTRACE_LIB
+AssertCompile((X86_SIB_BASE_MASK | X86_SIB_INDEX_MASK | X86_SIB_SCALE_MASK) == 0xff);
+AssertCompile((X86_SIB_INDEX_MASK >> X86_SIB_INDEX_SHIFT) == X86_SIB_INDEX_SMASK);
+AssertCompile((X86_SIB_SCALE_MASK >> X86_SIB_SCALE_SHIFT) == X86_SIB_SCALE_SMASK);
+#endif
+/** @} */
+
+/** @name General register indexes
+ * @{ */
+#define X86_GREG_xAX            0
+#define X86_GREG_xCX            1
+#define X86_GREG_xDX            2
+#define X86_GREG_xBX            3
+#define X86_GREG_xSP            4
+#define X86_GREG_xBP            5
+#define X86_GREG_xSI            6
+#define X86_GREG_xDI            7
+#define X86_GREG_x8             8
+#define X86_GREG_x9             9
+#define X86_GREG_x10            10
+#define X86_GREG_x11            11
+#define X86_GREG_x12            12
+#define X86_GREG_x13            13
+#define X86_GREG_x14            14
+#define X86_GREG_x15            15
+/** @} */
+
+/** @name X86_SREG_XXX - Segment register indexes.
+ * @{ */
+#define X86_SREG_ES             0
+#define X86_SREG_CS             1
+#define X86_SREG_SS             2
+#define X86_SREG_DS             3
+#define X86_SREG_FS             4
+#define X86_SREG_GS             5
+/** @} */
+/** Segment register count. */
+#define X86_SREG_COUNT          6
+
+
+/** @name X86_OP_XXX - Prefixes
+ * @{ */
+#define X86_OP_PRF_CS           UINT8_C(0x2e)
+#define X86_OP_PRF_SS           UINT8_C(0x36)
+#define X86_OP_PRF_DS           UINT8_C(0x3e)
+#define X86_OP_PRF_ES           UINT8_C(0x26)
+#define X86_OP_PRF_FS           UINT8_C(0x64)
+#define X86_OP_PRF_GS           UINT8_C(0x65)
+#define X86_OP_PRF_SIZE_OP      UINT8_C(0x66)
+#define X86_OP_PRF_SIZE_ADDR    UINT8_C(0x67)
+#define X86_OP_PRF_LOCK         UINT8_C(0xf0)
+#define X86_OP_PRF_REPZ         UINT8_C(0xf2)
+#define X86_OP_PRF_REPNZ        UINT8_C(0xf3)
+#define X86_OP_REX_B            UINT8_C(0x41)
+#define X86_OP_REX_X            UINT8_C(0x42)
+#define X86_OP_REX_R            UINT8_C(0x44)
+#define X86_OP_REX_W            UINT8_C(0x48)
+/** @} */
+
+
+/** @} */
+
+#endif
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/include/the-linux-kernel.h
@@ -0,0 +1,429 @@
+/* $Id: the-linux-kernel.h $ */
+/** @file
+ * IPRT - Include all necessary headers for the Linux kernel.
+ */
+
+/*
+ * Copyright (C) 2006-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+#ifndef ___the_linux_kernel_h
+#define ___the_linux_kernel_h
+
+/*
+ * Include iprt/types.h to install the bool wrappers.
+ * Then use the linux bool type for all the stuff include here.
+ */
+#include <iprt/types.h>
+#define bool linux_bool
+
+#include <linux/version.h>
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 33)
+# include <generated/autoconf.h>
+#else
+# ifndef AUTOCONF_INCLUDED
+#  include <linux/autoconf.h>
+# endif
+#endif
+
+/* We only support 2.4 and 2.6 series kernels */
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0)
+# error We only support 2.4 and 2.6 series kernels
+#endif
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 0) && LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0)
+# error We only support 2.4 and 2.6 series kernels
+#endif
+
+#if defined(CONFIG_MODVERSIONS) && !defined(MODVERSIONS)
+# define MODVERSIONS
+# if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 71)
+#  include <linux/modversions.h>
+# endif
+#endif
+#ifndef KBUILD_STR
+# if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 16)
+#  define KBUILD_STR(s) s
+# else
+#  define KBUILD_STR(s) #s
+# endif
+#endif
+# if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0)
+#  include <linux/kconfig.h> /* for macro IS_ENABLED */
+# endif
+#include <linux/string.h>
+#include <linux/spinlock.h>
+#include <linux/slab.h>
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)
+# include <linux/semaphore.h>
+#else /* older kernels */
+# include <asm/semaphore.h>
+#endif /* older kernels */
+#include <linux/module.h>
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)
+# include <linux/moduleparam.h>
+#endif
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/fs.h>
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)
+# include <linux/namei.h>
+#endif
+#include <linux/mm.h>
+#include <linux/pagemap.h>
+#include <linux/slab.h>
+#include <linux/time.h>
+#include <linux/sched.h>
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0)
+# include <linux/sched/rt.h>
+#endif
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 7)
+# include <linux/jiffies.h>
+#endif
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 16)
+# include <linux/ktime.h>
+# include <linux/hrtimer.h>
+#endif
+#include <linux/wait.h>
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 71)
+# include <linux/cpu.h>
+# include <linux/notifier.h>
+#endif
+/* For the basic additions module */
+#include <linux/pci.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/completion.h>
+#include <linux/compiler.h>
+#ifndef HAVE_UNLOCKED_IOCTL /* linux/fs.h defines this */
+# include <linux/smp_lock.h>
+#endif
+/* For the shared folders module */
+#include <linux/vmalloc.h>
+#define wchar_t linux_wchar_t
+#include <linux/nls.h>
+#undef wchar_t
+#include <asm/mman.h>
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include <asm/div64.h>
+
+/* For thread-context hooks. */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 18) && defined(CONFIG_PREEMPT_NOTIFIERS)
+# include <linux/preempt.h>
+#endif
+
+/* for workqueue / task queues. */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 41)
+# include <linux/workqueue.h>
+#else
+# include <linux/tqueue.h>
+#endif
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)
+# include <linux/kthread.h>
+#endif
+
+/* for cr4_init_shadow() / cpu_tlbstate. */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 20, 0)
+# include <asm/tlbflush.h>
+#endif
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 7, 0)
+# include <asm/smap.h>
+#else
+static inline void clac(void) { }
+static inline void stac(void) { }
+#endif
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0)
+# ifndef page_to_pfn
+#  define page_to_pfn(page) ((page) - mem_map)
+# endif
+#endif
+
+#ifndef DEFINE_WAIT
+# define DEFINE_WAIT(name) DECLARE_WAITQUEUE(name, current)
+#endif
+
+#ifndef __GFP_NOWARN
+# define __GFP_NOWARN 0
+#endif
+
+/*
+ * 2.4 / early 2.6 compatibility wrappers
+ */
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 7)
+
+# ifndef MAX_JIFFY_OFFSET
+#  define MAX_JIFFY_OFFSET ((~0UL >> 1)-1)
+# endif
+
+# if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 29) || LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)
+
+DECLINLINE(unsigned int) jiffies_to_msecs(unsigned long cJiffies)
+{
+#  if HZ <= 1000 && !(1000 % HZ)
+    return (1000 / HZ) * cJiffies;
+#  elif HZ > 1000 && !(HZ % 1000)
+    return (cJiffies + (HZ / 1000) - 1) / (HZ / 1000);
+#  else
+    return (cJiffies * 1000) / HZ;
+#  endif
+}
+
+DECLINLINE(unsigned long) msecs_to_jiffies(unsigned int cMillies)
+{
+#  if HZ > 1000
+    if (cMillies > jiffies_to_msecs(MAX_JIFFY_OFFSET))
+        return MAX_JIFFY_OFFSET;
+#  endif
+#  if HZ <= 1000 && !(1000 % HZ)
+    return (cMillies + (1000 / HZ) - 1) / (1000 / HZ);
+#  elif HZ > 1000 && !(HZ % 1000)
+    return cMillies * (HZ / 1000);
+#  else
+    return (cMillies * HZ + 999) / 1000;
+#  endif
+}
+
+# endif  /* < 2.4.29 || >= 2.6.0 */
+
+#endif /* < 2.6.7 */
+
+/*
+ * 2.4 compatibility wrappers
+ */
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0)
+
+# define prepare_to_wait(q, wait, state) \
+    do { \
+        add_wait_queue(q, wait); \
+        set_current_state(state); \
+    } while (0)
+
+# define after_wait(wait) \
+    do { \
+        list_del_init(&(wait)->task_list); \
+    } while (0)
+
+# define finish_wait(q, wait) \
+    do { \
+        set_current_state(TASK_RUNNING); \
+        remove_wait_queue(q, wait); \
+    } while (0)
+
+#else /* >= 2.6.0 */
+
+# define after_wait(wait)       do {} while (0)
+
+#endif /* >= 2.6.0 */
+
+/** @def TICK_NSEC
+ * The time between ticks in nsec */
+#ifndef TICK_NSEC
+# define TICK_NSEC (1000000000UL / HZ)
+#endif
+
+/*
+ * This sucks soooo badly on x86! Why don't they export __PAGE_KERNEL_EXEC so PAGE_KERNEL_EXEC would be usable?
+ */
+#if   LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 8) && defined(RT_ARCH_AMD64)
+# define MY_PAGE_KERNEL_EXEC    PAGE_KERNEL_EXEC
+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 8) && defined(PAGE_KERNEL_EXEC) && defined(CONFIG_X86_PAE)
+# ifdef __PAGE_KERNEL_EXEC
+   /* >= 2.6.27 */
+#  define MY_PAGE_KERNEL_EXEC   __pgprot(cpu_has_pge ? __PAGE_KERNEL_EXEC | _PAGE_GLOBAL : __PAGE_KERNEL_EXEC)
+# else
+#  define MY_PAGE_KERNEL_EXEC   __pgprot(cpu_has_pge ? _PAGE_KERNEL_EXEC | _PAGE_GLOBAL : _PAGE_KERNEL_EXEC)
+# endif
+#else
+# define MY_PAGE_KERNEL_EXEC    PAGE_KERNEL
+#endif
+
+
+/*
+ * The redhat hack section.
+ *  - The current hacks are for 2.4.21-15.EL only.
+ */
+#ifndef NO_REDHAT_HACKS
+/* accounting. */
+# if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0)
+#  ifdef VM_ACCOUNT
+#   define USE_RHEL4_MUNMAP
+#  endif
+# endif
+
+/* backported remap_page_range. */
+# if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0)
+#  include <asm/tlb.h>
+#  ifdef tlb_vma /* probably not good enough... */
+#   define HAVE_26_STYLE_REMAP_PAGE_RANGE 1
+#  endif
+# endif
+
+# ifndef RT_ARCH_AMD64
+/* In 2.6.9-22.ELsmp we have to call change_page_attr() twice when changing
+ * the page attributes from PAGE_KERNEL to something else, because there appears
+ * to be a bug in one of the many patches that redhat applied.
+ * It should be safe to do this on less buggy linux kernels too. ;-)
+ */
+#  define MY_CHANGE_PAGE_ATTR(pPages, cPages, prot) \
+    do { \
+        if (pgprot_val(prot) != pgprot_val(PAGE_KERNEL)) \
+            change_page_attr(pPages, cPages, prot); \
+        change_page_attr(pPages, cPages, prot); \
+    } while (0)
+# endif  /* !RT_ARCH_AMD64 */
+#endif /* !NO_REDHAT_HACKS */
+
+#ifndef MY_CHANGE_PAGE_ATTR
+# ifdef RT_ARCH_AMD64 /** @todo This is a cheap hack, but it'll get around that 'else BUG();' in __change_page_attr().  */
+#  define MY_CHANGE_PAGE_ATTR(pPages, cPages, prot) \
+    do { \
+        change_page_attr(pPages, cPages, PAGE_KERNEL_NOCACHE); \
+        change_page_attr(pPages, cPages, prot); \
+    } while (0)
+# else
+#  define MY_CHANGE_PAGE_ATTR(pPages, cPages, prot) change_page_attr(pPages, cPages, prot)
+# endif
+#endif
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)
+# define MY_SET_PAGES_EXEC(pPages, cPages)    set_pages_x(pPages, cPages)
+# define MY_SET_PAGES_NOEXEC(pPages, cPages)  set_pages_nx(pPages, cPages)
+#else
+# define MY_SET_PAGES_EXEC(pPages, cPages) \
+    do { \
+        if (pgprot_val(MY_PAGE_KERNEL_EXEC) != pgprot_val(PAGE_KERNEL)) \
+            MY_CHANGE_PAGE_ATTR(pPages, cPages, MY_PAGE_KERNEL_EXEC); \
+    } while (0)
+# define MY_SET_PAGES_NOEXEC(pPages, cPages) \
+    do { \
+        if (pgprot_val(MY_PAGE_KERNEL_EXEC) != pgprot_val(PAGE_KERNEL)) \
+            MY_CHANGE_PAGE_ATTR(pPages, cPages, PAGE_KERNEL); \
+    } while (0)
+#endif
+
+/** @def ONE_MSEC_IN_JIFFIES
+ * The number of jiffies that make up 1 millisecond. Must be at least 1! */
+#if HZ <= 1000
+# define ONE_MSEC_IN_JIFFIES       1
+#elif !(HZ % 1000)
+# define ONE_MSEC_IN_JIFFIES       (HZ / 1000)
+#else
+# define ONE_MSEC_IN_JIFFIES       ((HZ + 999) / 1000)
+# error "HZ is not a multiple of 1000, the GIP stuff won't work right!"
+#endif
+
+/*
+ * Stop using the linux bool type.
+ */
+#undef bool
+
+/*
+ * There are post-2.6.24 kernels (confusingly with unchanged version number)
+ * which eliminate macros which were marked as deprecated.
+ */
+#ifndef __attribute_used__
+#define __attribute_used__ __used
+#endif
+
+/**
+ * Hack for shortening pointers on linux so we can stuff more stuff into the
+ * task_struct::comm field. This is used by the semaphore code but put here
+ * because we don't have any better place atm. Don't use outside IPRT, please.
+ */
+#ifdef RT_ARCH_AMD64
+# define IPRT_DEBUG_SEMS_ADDRESS(addr)  ( ((long)(addr) & (long)~UINT64_C(0xfffffff000000000)) )
+#else
+# define IPRT_DEBUG_SEMS_ADDRESS(addr)  ( (long)(addr) )
+#endif
+
+/**
+ * Puts semaphore info into the task_struct::comm field if IPRT_DEBUG_SEMS is
+ * defined.
+ */
+#ifdef IPRT_DEBUG_SEMS
+# define IPRT_DEBUG_SEMS_STATE(pThis, chState) \
+    snprintf(current->comm, sizeof(current->comm), "%c%lx", (chState), IPRT_DEBUG_SEMS_ADDRESS(pThis));
+#else
+# define IPRT_DEBUG_SEMS_STATE(pThis, chState)  do {  } while (0)
+#endif
+
+/**
+ * Puts semaphore info into the task_struct::comm field if IPRT_DEBUG_SEMS is
+ * defined.
+ */
+#ifdef IPRT_DEBUG_SEMS
+# define IPRT_DEBUG_SEMS_STATE_RC(pThis, chState, rc) \
+    snprintf(current->comm, sizeof(current->comm), "%c%lx:%d", (chState), IPRT_DEBUG_SEMS_ADDRESS(pThis), rc);
+#else
+# define IPRT_DEBUG_SEMS_STATE_RC(pThis, chState, rc)  do {  } while (0)
+#endif
+
+/** @name Macros for preserving EFLAGS.AC on 3.19+/amd64  paranoid.
+ * The AMD 64 switch_to in macro in arch/x86/include/asm/switch_to.h stopped
+ * restoring flags.
+ * @{ */
+#if defined(CONFIG_X86_SMAP) || defined(RT_STRICT) || defined(IPRT_WITH_EFLAGS_AC_PRESERVING)
+# include <iprt/asm-amd64-x86.h>
+# define IPRT_X86_EFL_AC                    RT_BIT(18)
+# define IPRT_LINUX_SAVE_EFL_AC()           RTCCUINTREG fSavedEfl = ASMGetFlags()
+# define IPRT_LINUX_RESTORE_EFL_AC()        ASMSetFlags(fSavedEfl)
+# define IPRT_LINUX_RESTORE_EFL_ONLY_AC()   ASMChangeFlags(~IPRT_X86_EFL_AC, fSavedEfl & IPRT_X86_EFL_AC)
+#else
+# define IPRT_LINUX_SAVE_EFL_AC()           do { } while (0)
+# define IPRT_LINUX_RESTORE_EFL_AC()        do { } while (0)
+# define IPRT_LINUX_RESTORE_EFL_ONLY_AC()   do { } while (0)
+#endif
+/** @} */
+
+/*
+ * There are some conflicting defines in iprt/param.h, sort them out here.
+ */
+#ifndef ___iprt_param_h
+# undef PAGE_SIZE
+# undef PAGE_OFFSET_MASK
+# include <iprt/param.h>
+#endif
+
+/*
+ * Some global indicator macros.
+ */
+/** @def IPRT_LINUX_HAS_HRTIMER
+ * Whether the kernel support high resolution timers (Linux kernel versions
+ * 2.6.28 and later (hrtimer_add_expires_ns() & schedule_hrtimeout). */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28)
+# define IPRT_LINUX_HAS_HRTIMER
+#endif
+
+/*
+ * Workqueue stuff, see initterm-r0drv-linux.c.
+ */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 41)
+typedef struct work_struct  RTR0LNXWORKQUEUEITEM;
+#else
+typedef struct tq_struct    RTR0LNXWORKQUEUEITEM;
+#endif
+DECLHIDDEN(void) rtR0LnxWorkqueuePush(RTR0LNXWORKQUEUEITEM *pWork, void (*pfnWorker)(RTR0LNXWORKQUEUEITEM *));
+DECLHIDDEN(void) rtR0LnxWorkqueueFlush(void);
+
+
+#endif
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/r0drv/alloc-r0drv.c
@@ -0,0 +1,430 @@
+/* $Id: alloc-r0drv.cpp $ */
+/** @file
+ * IPRT - Memory Allocation, Ring-0 Driver.
+ */
+
+/*
+ * Copyright (C) 2006-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+
+/*********************************************************************************************************************************
+*   Header Files                                                                                                                 *
+*********************************************************************************************************************************/
+#define RTMEM_NO_WRAP_TO_EF_APIS
+#include <iprt/mem.h>
+#include "internal/iprt.h"
+
+#if defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86)
+# include <iprt/asm-amd64-x86.h>
+#endif
+#include <iprt/assert.h>
+#ifdef RT_MORE_STRICT
+# include <iprt/mp.h>
+#endif
+#include <iprt/param.h>
+#include <iprt/string.h>
+#include <iprt/thread.h>
+#include "r0drv/alloc-r0drv.h"
+
+
+/*********************************************************************************************************************************
+*   Defined Constants And Macros                                                                                                 *
+*********************************************************************************************************************************/
+#ifdef RT_STRICT
+# define RTR0MEM_STRICT
+#endif
+
+#ifdef RTR0MEM_STRICT
+# define RTR0MEM_FENCE_EXTRA    16
+#else
+# define RTR0MEM_FENCE_EXTRA    0
+#endif
+
+
+/*********************************************************************************************************************************
+*   Global Variables                                                                                                             *
+*********************************************************************************************************************************/
+#ifdef RTR0MEM_STRICT
+/** Fence data. */
+static uint8_t const g_abFence[RTR0MEM_FENCE_EXTRA] =
+{
+    0x77, 0x88, 0x66, 0x99,  0x55, 0xaa, 0x44, 0xbb,
+    0x33, 0xcc, 0x22, 0xdd,  0x11, 0xee, 0x00, 0xff
+};
+#endif
+
+
+/**
+ * Wrapper around rtR0MemAllocEx.
+ *
+ * @returns Pointer to the allocated memory block header.
+ * @param   cb                  The number of bytes to allocate (sans header).
+ * @param   fFlags              The allocation flags.
+ */
+DECLINLINE(PRTMEMHDR) rtR0MemAlloc(size_t cb, uint32_t fFlags)
+{
+    PRTMEMHDR pHdr;
+    int rc = rtR0MemAllocEx(cb, fFlags, &pHdr);
+    if (RT_FAILURE(rc))
+        return NULL;
+    return pHdr;
+}
+
+
+RTDECL(void *)  RTMemTmpAllocTag(size_t cb, const char *pszTag) RT_NO_THROW_DEF
+{
+    return RTMemAllocTag(cb, pszTag);
+}
+RT_EXPORT_SYMBOL(RTMemTmpAllocTag);
+
+
+RTDECL(void *)  RTMemTmpAllocZTag(size_t cb, const char *pszTag) RT_NO_THROW_DEF
+{
+    return RTMemAllocZTag(cb, pszTag);
+}
+RT_EXPORT_SYMBOL(RTMemTmpAllocZTag);
+
+
+RTDECL(void)    RTMemTmpFree(void *pv) RT_NO_THROW_DEF
+{
+    return RTMemFree(pv);
+}
+RT_EXPORT_SYMBOL(RTMemTmpFree);
+
+
+
+
+
+RTDECL(void *)  RTMemAllocTag(size_t cb, const char *pszTag) RT_NO_THROW_DEF
+{
+    PRTMEMHDR pHdr;
+    RT_ASSERT_INTS_ON();
+
+    pHdr = rtR0MemAlloc(cb + RTR0MEM_FENCE_EXTRA, 0);
+    if (pHdr)
+    {
+#ifdef RTR0MEM_STRICT
+        pHdr->cbReq = (uint32_t)cb; Assert(pHdr->cbReq == cb);
+        memcpy((uint8_t *)(pHdr + 1) + cb, &g_abFence[0], RTR0MEM_FENCE_EXTRA);
+#endif
+        return pHdr + 1;
+    }
+    return NULL;
+}
+RT_EXPORT_SYMBOL(RTMemAllocTag);
+
+
+RTDECL(void *)  RTMemAllocZTag(size_t cb, const char *pszTag) RT_NO_THROW_DEF
+{
+    PRTMEMHDR pHdr;
+    RT_ASSERT_INTS_ON();
+
+    pHdr = rtR0MemAlloc(cb + RTR0MEM_FENCE_EXTRA, RTMEMHDR_FLAG_ZEROED);
+    if (pHdr)
+    {
+#ifdef RTR0MEM_STRICT
+        pHdr->cbReq = (uint32_t)cb; Assert(pHdr->cbReq == cb);
+        memcpy((uint8_t *)(pHdr + 1) + cb, &g_abFence[0], RTR0MEM_FENCE_EXTRA);
+        return memset(pHdr + 1, 0, cb);
+#else
+        return memset(pHdr + 1, 0, pHdr->cb);
+#endif
+    }
+    return NULL;
+}
+RT_EXPORT_SYMBOL(RTMemAllocZTag);
+
+
+RTDECL(void *) RTMemAllocVarTag(size_t cbUnaligned, const char *pszTag)
+{
+    size_t cbAligned;
+    if (cbUnaligned >= 16)
+        cbAligned = RT_ALIGN_Z(cbUnaligned, 16);
+    else
+        cbAligned = RT_ALIGN_Z(cbUnaligned, sizeof(void *));
+    return RTMemAllocTag(cbAligned, pszTag);
+}
+RT_EXPORT_SYMBOL(RTMemAllocVarTag);
+
+
+RTDECL(void *) RTMemAllocZVarTag(size_t cbUnaligned, const char *pszTag)
+{
+    size_t cbAligned;
+    if (cbUnaligned >= 16)
+        cbAligned = RT_ALIGN_Z(cbUnaligned, 16);
+    else
+        cbAligned = RT_ALIGN_Z(cbUnaligned, sizeof(void *));
+    return RTMemAllocZTag(cbAligned, pszTag);
+}
+RT_EXPORT_SYMBOL(RTMemAllocZVarTag);
+
+
+RTDECL(void *) RTMemReallocTag(void *pvOld, size_t cbNew, const char *pszTag) RT_NO_THROW_DEF
+{
+    PRTMEMHDR pHdrOld;
+
+    /* Free. */
+    if (!cbNew && pvOld)
+    {
+        RTMemFree(pvOld);
+        return NULL;
+    }
+
+    /* Alloc. */
+    if (!pvOld)
+        return RTMemAllocTag(cbNew, pszTag);
+
+    /*
+     * Realloc.
+     */
+    pHdrOld = (PRTMEMHDR)pvOld - 1;
+    RT_ASSERT_PREEMPTIBLE();
+
+    if (pHdrOld->u32Magic == RTMEMHDR_MAGIC)
+    {
+        PRTMEMHDR pHdrNew;
+
+        /* If there is sufficient space in the old block and we don't cause
+           substantial internal fragmentation, reuse the old block. */
+        if (   pHdrOld->cb >= cbNew + RTR0MEM_FENCE_EXTRA
+            && pHdrOld->cb - (cbNew + RTR0MEM_FENCE_EXTRA) <= 128)
+        {
+            pHdrOld->cbReq = (uint32_t)cbNew; Assert(pHdrOld->cbReq == cbNew);
+#ifdef RTR0MEM_STRICT
+            memcpy((uint8_t *)(pHdrOld + 1) + cbNew, &g_abFence[0], RTR0MEM_FENCE_EXTRA);
+#endif
+            return pvOld;
+        }
+
+        /* Allocate a new block and copy over the content. */
+        pHdrNew = rtR0MemAlloc(cbNew + RTR0MEM_FENCE_EXTRA, 0);
+        if (pHdrNew)
+        {
+            size_t cbCopy = RT_MIN(pHdrOld->cb, pHdrNew->cb);
+            memcpy(pHdrNew + 1, pvOld, cbCopy);
+#ifdef RTR0MEM_STRICT
+            pHdrNew->cbReq = (uint32_t)cbNew; Assert(pHdrNew->cbReq == cbNew);
+            memcpy((uint8_t *)(pHdrNew + 1) + cbNew, &g_abFence[0], RTR0MEM_FENCE_EXTRA);
+            AssertReleaseMsg(!memcmp((uint8_t *)(pHdrOld + 1) + pHdrOld->cbReq, &g_abFence[0], RTR0MEM_FENCE_EXTRA),
+                             ("pHdr=%p pvOld=%p cbReq=%u cb=%u cbNew=%zu fFlags=%#x\n"
+                              "fence:    %.*Rhxs\n"
+                              "expected: %.*Rhxs\n",
+                              pHdrOld, pvOld, pHdrOld->cbReq, pHdrOld->cb, cbNew, pHdrOld->fFlags,
+                              RTR0MEM_FENCE_EXTRA, (uint8_t *)(pHdrOld + 1) + pHdrOld->cbReq,
+                              RTR0MEM_FENCE_EXTRA, &g_abFence[0]));
+#endif
+            rtR0MemFree(pHdrOld);
+            return pHdrNew + 1;
+        }
+    }
+    else
+        AssertMsgFailed(("pHdrOld->u32Magic=%RX32 pvOld=%p cbNew=%#zx\n", pHdrOld->u32Magic, pvOld, cbNew));
+
+    return NULL;
+}
+RT_EXPORT_SYMBOL(RTMemReallocTag);
+
+
+RTDECL(void) RTMemFree(void *pv) RT_NO_THROW_DEF
+{
+    PRTMEMHDR pHdr;
+    RT_ASSERT_INTS_ON();
+
+    if (!pv)
+        return;
+    pHdr = (PRTMEMHDR)pv - 1;
+    if (pHdr->u32Magic == RTMEMHDR_MAGIC)
+    {
+        Assert(!(pHdr->fFlags & RTMEMHDR_FLAG_ALLOC_EX));
+        Assert(!(pHdr->fFlags & RTMEMHDR_FLAG_EXEC));
+#ifdef RTR0MEM_STRICT
+        AssertReleaseMsg(!memcmp((uint8_t *)(pHdr + 1) + pHdr->cbReq, &g_abFence[0], RTR0MEM_FENCE_EXTRA),
+                         ("pHdr=%p pv=%p cbReq=%u cb=%u fFlags=%#x\n"
+                          "fence:    %.*Rhxs\n"
+                          "expected: %.*Rhxs\n",
+                          pHdr, pv, pHdr->cbReq, pHdr->cb, pHdr->fFlags,
+                          RTR0MEM_FENCE_EXTRA, (uint8_t *)(pHdr + 1) + pHdr->cbReq,
+                          RTR0MEM_FENCE_EXTRA, &g_abFence[0]));
+#endif
+        rtR0MemFree(pHdr);
+    }
+    else
+        AssertMsgFailed(("pHdr->u32Magic=%RX32 pv=%p\n", pHdr->u32Magic, pv));
+}
+RT_EXPORT_SYMBOL(RTMemFree);
+
+
+
+
+
+
+RTDECL(void *)    RTMemExecAllocTag(size_t cb, const char *pszTag) RT_NO_THROW_DEF
+{
+    PRTMEMHDR pHdr;
+#ifdef RT_OS_SOLARIS /** @todo figure out why */
+    RT_ASSERT_INTS_ON();
+#else
+    RT_ASSERT_PREEMPTIBLE();
+#endif
+
+    pHdr = rtR0MemAlloc(cb + RTR0MEM_FENCE_EXTRA, RTMEMHDR_FLAG_EXEC);
+    if (pHdr)
+    {
+#ifdef RTR0MEM_STRICT
+        pHdr->cbReq = (uint32_t)cb; Assert(pHdr->cbReq == cb);
+        memcpy((uint8_t *)(pHdr + 1) + cb, &g_abFence[0], RTR0MEM_FENCE_EXTRA);
+#endif
+        return pHdr + 1;
+    }
+    return NULL;
+}
+RT_EXPORT_SYMBOL(RTMemExecAllocTag);
+
+
+RTDECL(void)      RTMemExecFree(void *pv, size_t cb) RT_NO_THROW_DEF
+{
+    PRTMEMHDR pHdr;
+    RT_ASSERT_INTS_ON();
+
+    if (!pv)
+        return;
+    pHdr = (PRTMEMHDR)pv - 1;
+    if (pHdr->u32Magic == RTMEMHDR_MAGIC)
+    {
+        Assert(!(pHdr->fFlags & RTMEMHDR_FLAG_ALLOC_EX));
+#ifdef RTR0MEM_STRICT
+        AssertReleaseMsg(!memcmp((uint8_t *)(pHdr + 1) + pHdr->cbReq, &g_abFence[0], RTR0MEM_FENCE_EXTRA),
+                         ("pHdr=%p pv=%p cbReq=%u cb=%u fFlags=%#x\n"
+                          "fence:    %.*Rhxs\n"
+                          "expected: %.*Rhxs\n",
+                          pHdr, pv, pHdr->cbReq, pHdr->cb, pHdr->fFlags,
+                          RTR0MEM_FENCE_EXTRA, (uint8_t *)(pHdr + 1) + pHdr->cbReq,
+                          RTR0MEM_FENCE_EXTRA, &g_abFence[0]));
+#endif
+        rtR0MemFree(pHdr);
+    }
+    else
+        AssertMsgFailed(("pHdr->u32Magic=%RX32 pv=%p\n", pHdr->u32Magic, pv));
+}
+RT_EXPORT_SYMBOL(RTMemExecFree);
+
+
+
+
+RTDECL(int) RTMemAllocExTag(size_t cb, size_t cbAlignment, uint32_t fFlags, const char *pszTag, void **ppv) RT_NO_THROW_DEF
+{
+    uint32_t    fHdrFlags = RTMEMHDR_FLAG_ALLOC_EX;
+    PRTMEMHDR   pHdr;
+    int         rc;
+
+    RT_ASSERT_PREEMPT_CPUID_VAR();
+    if (!(fFlags & RTMEMALLOCEX_FLAGS_ANY_CTX_ALLOC))
+        RT_ASSERT_INTS_ON();
+
+    /*
+     * Fake up some alignment support.
+     */
+    AssertMsgReturn(cbAlignment <= sizeof(void *), ("%zu (%#x)\n", cbAlignment, cbAlignment), VERR_UNSUPPORTED_ALIGNMENT);
+    if (cb < cbAlignment)
+        cb = cbAlignment;
+
+    /*
+     * Validate and convert flags.
+     */
+    AssertMsgReturn(!(fFlags & ~RTMEMALLOCEX_FLAGS_VALID_MASK_R0), ("%#x\n", fFlags), VERR_INVALID_PARAMETER);
+    if (fFlags & RTMEMALLOCEX_FLAGS_ZEROED)
+        fHdrFlags |= RTMEMHDR_FLAG_ZEROED;
+    if (fFlags & RTMEMALLOCEX_FLAGS_EXEC)
+        fHdrFlags |= RTMEMHDR_FLAG_EXEC;
+    if (fFlags & RTMEMALLOCEX_FLAGS_ANY_CTX_ALLOC)
+        fHdrFlags |= RTMEMHDR_FLAG_ANY_CTX_ALLOC;
+    if (fFlags & RTMEMALLOCEX_FLAGS_ANY_CTX_FREE)
+        fHdrFlags |= RTMEMHDR_FLAG_ANY_CTX_FREE;
+
+    /*
+     * Do the allocation.
+     */
+    rc = rtR0MemAllocEx(cb + RTR0MEM_FENCE_EXTRA, fHdrFlags, &pHdr);
+    if (RT_SUCCESS(rc))
+    {
+        void *pv;
+
+        Assert(pHdr->cbReq  == cb + RTR0MEM_FENCE_EXTRA);
+        Assert((pHdr->fFlags & fFlags) == fFlags);
+
+        /*
+         * Calc user pointer, initialize the memory if requested, and if
+         * memory strictness is enable set up the fence.
+         */
+        pv = pHdr + 1;
+        *ppv = pv;
+        if (fFlags & RTMEMHDR_FLAG_ZEROED)
+            memset(pv, 0, pHdr->cb);
+
+#ifdef RTR0MEM_STRICT
+        pHdr->cbReq = (uint32_t)cb;
+        memcpy((uint8_t *)pv + cb, &g_abFence[0], RTR0MEM_FENCE_EXTRA);
+#endif
+    }
+    else if (rc == VERR_NO_MEMORY && (fFlags & RTMEMALLOCEX_FLAGS_EXEC))
+        rc = VERR_NO_EXEC_MEMORY;
+
+    RT_ASSERT_PREEMPT_CPUID();
+    return rc;
+}
+RT_EXPORT_SYMBOL(RTMemAllocExTag);
+
+
+RTDECL(void) RTMemFreeEx(void *pv, size_t cb) RT_NO_THROW_DEF
+{
+    PRTMEMHDR pHdr;
+
+    if (!pv)
+        return;
+
+    AssertPtr(pv);
+    pHdr = (PRTMEMHDR)pv - 1;
+    if (pHdr->u32Magic == RTMEMHDR_MAGIC)
+    {
+        RT_ASSERT_PREEMPT_CPUID_VAR();
+
+        Assert(pHdr->fFlags & RTMEMHDR_FLAG_ALLOC_EX);
+        if (!(pHdr->fFlags & RTMEMHDR_FLAG_ANY_CTX_FREE))
+            RT_ASSERT_INTS_ON();
+        AssertMsg(pHdr->cbReq == cb, ("cbReq=%zu cb=%zu\n", pHdr->cb, cb));
+
+#ifdef RTR0MEM_STRICT
+        AssertReleaseMsg(!memcmp((uint8_t *)(pHdr + 1) + pHdr->cbReq, &g_abFence[0], RTR0MEM_FENCE_EXTRA),
+                         ("pHdr=%p pv=%p cbReq=%u cb=%u fFlags=%#x\n"
+                          "fence:    %.*Rhxs\n"
+                          "expected: %.*Rhxs\n",
+                          pHdr, pv, pHdr->cbReq, pHdr->cb, pHdr->fFlags,
+                          RTR0MEM_FENCE_EXTRA, (uint8_t *)(pHdr + 1) + pHdr->cbReq,
+                          RTR0MEM_FENCE_EXTRA, &g_abFence[0]));
+#endif
+        rtR0MemFree(pHdr);
+        RT_ASSERT_PREEMPT_CPUID();
+    }
+    else
+        AssertMsgFailed(("pHdr->u32Magic=%RX32 pv=%p\n", pHdr->u32Magic, pv));
+}
+RT_EXPORT_SYMBOL(RTMemFreeEx);
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/r0drv/alloc-r0drv.h
@@ -0,0 +1,101 @@
+/* $Id: alloc-r0drv.h $ */
+/** @file
+ * IPRT - Memory Allocation, Ring-0 Driver.
+ */
+
+/*
+ * Copyright (C) 2006-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+#ifndef ___r0drv_alloc_r0drv_h
+#define ___r0drv_alloc_r0drv_h
+
+#include <iprt/cdefs.h>
+#include <iprt/types.h>
+#include <iprt/mem.h>
+#include "internal/magics.h"
+
+RT_C_DECLS_BEGIN
+
+/**
+ * Header which heading all memory blocks.
+ */
+typedef struct RTMEMHDR
+{
+    /** Magic (RTMEMHDR_MAGIC). */
+    uint32_t    u32Magic;
+    /** Block flags (RTMEMHDR_FLAG_*). */
+    uint32_t    fFlags;
+    /** The actual size of the block, header not included. */
+    uint32_t    cb;
+    /** The requested allocation size. */
+    uint32_t    cbReq;
+} RTMEMHDR, *PRTMEMHDR;
+
+
+/** @name RTMEMHDR::fFlags.
+ * @{ */
+/** Clear the allocated memory. */
+#define RTMEMHDR_FLAG_ZEROED        RT_BIT(0)
+/** Executable flag. */
+#define RTMEMHDR_FLAG_EXEC          RT_BIT(1)
+/** Use allocation method suitable for any context. */
+#define RTMEMHDR_FLAG_ANY_CTX_ALLOC RT_BIT(2)
+/** Use allocation method which allow for freeing in any context. */
+#define RTMEMHDR_FLAG_ANY_CTX_FREE  RT_BIT(3)
+/** Both alloc and free in any context (or we're just darn lazy). */
+#define RTMEMHDR_FLAG_ANY_CTX       (RTMEMHDR_FLAG_ANY_CTX_ALLOC | RTMEMHDR_FLAG_ANY_CTX_FREE)
+/** Indicate that it was allocated by rtR0MemAllocExTag. */
+#define RTMEMHDR_FLAG_ALLOC_EX      RT_BIT(4)
+#ifdef RT_OS_LINUX
+/** Linux: Allocated using vm_area hacks. */
+# define RTMEMHDR_FLAG_EXEC_VM_AREA RT_BIT(29)
+/** Linux: Allocated from the special heap for executable memory. */
+# define RTMEMHDR_FLAG_EXEC_HEAP    RT_BIT(30)
+/** Linux: Allocated by kmalloc() instead of vmalloc(). */
+# define RTMEMHDR_FLAG_KMALLOC      RT_BIT(31)
+#endif
+/** @} */
+
+
+/**
+ * Heap allocation back end for ring-0.
+ *
+ * @returns IPRT status code.  VERR_NO_MEMORY suffices for RTMEMHDR_FLAG_EXEC,
+ *          the caller will change it to VERR_NO_EXEC_MEMORY when appropriate.
+ *
+ * @param   cb          The amount of memory requested by the user.  This does
+ *                      not include the header.
+ * @param   fFlags      The allocation flags and more.  These should be
+ *                      assigned to RTMEMHDR::fFlags together with any flags
+ *                      the backend might be using.
+ * @param   ppHdr       Where to return the memory header on success.
+ */
+DECLHIDDEN(int)     rtR0MemAllocEx(size_t cb, uint32_t fFlags, PRTMEMHDR *ppHdr);
+
+/**
+ * Free memory allocated by rtR0MemAllocEx.
+ * @param   pHdr        The memory block to free.  (Never NULL.)
+ */
+DECLHIDDEN(void)    rtR0MemFree(PRTMEMHDR pHdr);
+
+RT_C_DECLS_END
+#endif
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/r0drv/generic/semspinmutex-r0drv-generic.c
@@ -0,0 +1,503 @@
+/* $Id: semspinmutex-r0drv-generic.c $ */
+/** @file
+ * IPRT - Spinning Mutex Semaphores, Ring-0 Driver, Generic.
+ */
+
+/*
+ * Copyright (C) 2009-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+
+/*********************************************************************************************************************************
+*   Header Files                                                                                                                 *
+*********************************************************************************************************************************/
+#ifdef RT_OS_WINDOWS
+# include "../nt/the-nt-kernel.h"
+#endif
+#include "internal/iprt.h"
+
+#include <iprt/semaphore.h>
+#include <iprt/asm.h>
+#include <iprt/asm-amd64-x86.h>
+#include <iprt/assert.h>
+#include <iprt/err.h>
+#include <iprt/mem.h>
+#include <iprt/thread.h>
+#include "internal/magics.h"
+
+
+/*********************************************************************************************************************************
+*   Structures and Typedefs                                                                                                      *
+*********************************************************************************************************************************/
+/**
+ * Saved state information.
+ */
+typedef struct RTSEMSPINMUTEXSTATE
+{
+    /** Saved flags register. */
+    RTCCUINTREG             fSavedFlags;
+    /** Preemption state.  */
+    RTTHREADPREEMPTSTATE    PreemptState;
+    /** Whether to spin or sleep. */
+    bool                    fSpin;
+    /** Whether the flags have been saved. */
+    bool                    fValidFlags;
+} RTSEMSPINMUTEXSTATE;
+
+/**
+ * Spinning mutex semaphore.
+ */
+typedef struct RTSEMSPINMUTEXINTERNAL
+{
+    /** Magic value (RTSEMSPINMUTEX_MAGIC)
+     * RTCRITSECT_MAGIC is the value of an initialized & operational section. */
+    uint32_t volatile       u32Magic;
+    /** Flags. This is a combination of RTSEMSPINMUTEX_FLAGS_XXX and
+     *  RTSEMSPINMUTEX_INT_FLAGS_XXX. */
+    uint32_t volatile       fFlags;
+    /** The owner thread.
+     * This is NIL if the semaphore is not owned by anyone. */
+    RTNATIVETHREAD volatile hOwner;
+    /** Number of threads that are fighting for the lock. */
+    int32_t volatile        cLockers;
+    /** The semaphore to block on. */
+    RTSEMEVENT              hEventSem;
+    /** Saved state information of the owner.
+     * This will be restored by RTSemSpinRelease. */
+    RTSEMSPINMUTEXSTATE     SavedState;
+} RTSEMSPINMUTEXINTERNAL;
+
+
+/*********************************************************************************************************************************
+*   Defined Constants And Macros                                                                                                 *
+*********************************************************************************************************************************/
+/*#define RTSEMSPINMUTEX_INT_FLAGS_MUST*/
+
+/** Validates the handle, returning if invalid. */
+#define RTSEMSPINMUTEX_VALIDATE_RETURN(pThis) \
+    do \
+    { \
+        uint32_t u32Magic; \
+        AssertPtr(pThis); \
+        u32Magic = (pThis)->u32Magic; \
+        if (u32Magic != RTSEMSPINMUTEX_MAGIC) \
+        { \
+            AssertMsgFailed(("u32Magic=%#x pThis=%p\n", u32Magic, pThis)); \
+            return u32Magic == RTSEMSPINMUTEX_MAGIC_DEAD ? VERR_SEM_DESTROYED : VERR_INVALID_HANDLE; \
+        } \
+    } while (0)
+
+
+RTDECL(int) RTSemSpinMutexCreate(PRTSEMSPINMUTEX phSpinMtx, uint32_t fFlags)
+{
+    RTSEMSPINMUTEXINTERNAL *pThis;
+    int                     rc;
+
+    AssertReturn(!(fFlags & ~RTSEMSPINMUTEX_FLAGS_VALID_MASK), VERR_INVALID_PARAMETER);
+    AssertPtr(phSpinMtx);
+
+    /*
+     * Allocate and initialize the structure.
+     */
+    pThis = (RTSEMSPINMUTEXINTERNAL *)RTMemAllocZ(sizeof(*pThis));
+    if (!pThis)
+        return VERR_NO_MEMORY;
+    pThis->u32Magic   = RTSEMSPINMUTEX_MAGIC;
+    pThis->fFlags     = fFlags;
+    pThis->hOwner     = NIL_RTNATIVETHREAD;
+    pThis->cLockers   = 0;
+    rc = RTSemEventCreateEx(&pThis->hEventSem, RTSEMEVENT_FLAGS_NO_LOCK_VAL, NIL_RTLOCKVALCLASS, NULL);
+    if (RT_SUCCESS(rc))
+    {
+        *phSpinMtx = pThis;
+        return VINF_SUCCESS;
+    }
+
+    RTMemFree(pThis);
+    return rc;
+}
+RT_EXPORT_SYMBOL(RTSemSpinMutexCreate);
+
+
+/**
+ * Helper for RTSemSpinMutexTryRequest and RTSemSpinMutexRequest.
+ *
+ * This will check the current context and see if it's usui
+ *
+ * @returns VINF_SUCCESS or VERR_SEM_BAD_CONTEXT.
+ * @param   pState      Output structure.
+ */
+static int rtSemSpinMutexEnter(RTSEMSPINMUTEXSTATE *pState, RTSEMSPINMUTEXINTERNAL *pThis)
+{
+#ifndef RT_OS_WINDOWS
+    RTTHREADPREEMPTSTATE const StateInit = RTTHREADPREEMPTSTATE_INITIALIZER;
+#endif
+    int rc  = VINF_SUCCESS;
+
+    /** @todo Later #1: When entering in interrupt context and we're not able to
+     *        wake up threads from it, we could try switch the lock into pure
+     *        spinlock mode. This would require that there are no other threads
+     *        currently waiting on it and that the RTSEMSPINMUTEX_FLAGS_IRQ_SAFE
+     *        flag is set.
+     *
+     *        Later #2: Similarly, it is possible to turn on the
+     *        RTSEMSPINMUTEX_FLAGS_IRQ_SAFE at run time if we manage to grab the
+     *        semaphore ownership at interrupt time. We might want to try delay the
+     *        RTSEMSPINMUTEX_FLAGS_IRQ_SAFE even, since we're fine if we get it...
+     */
+
+#ifdef RT_OS_WINDOWS
+    /*
+     * NT: IRQL <= DISPATCH_LEVEL for waking up threads; IRQL < DISPATCH_LEVEL for sleeping.
+     */
+    pState->PreemptState.uchOldIrql = KeGetCurrentIrql();
+    if (pState->PreemptState.uchOldIrql > DISPATCH_LEVEL)
+        return VERR_SEM_BAD_CONTEXT;
+
+    if (pState->PreemptState.uchOldIrql >= DISPATCH_LEVEL)
+        pState->fSpin = true;
+    else
+    {
+        pState->fSpin = false;
+        KeRaiseIrql(DISPATCH_LEVEL, &pState->PreemptState.uchOldIrql);
+        Assert(pState->PreemptState.uchOldIrql < DISPATCH_LEVEL);
+    }
+
+#elif defined(RT_OS_SOLARIS)
+    /*
+     * Solaris:  RTSemEventSignal will do bad stuff on S10 if interrupts are disabled.
+     */
+    if (!ASMIntAreEnabled())
+        return VERR_SEM_BAD_CONTEXT;
+
+    pState->fSpin = !RTThreadPreemptIsEnabled(NIL_RTTHREAD);
+    if (RTThreadIsInInterrupt(NIL_RTTHREAD))
+    {
+        if (!(pThis->fFlags & RTSEMSPINMUTEX_FLAGS_IRQ_SAFE))
+            rc = VINF_SEM_BAD_CONTEXT; /* Try, but owner might be interrupted. */
+        pState->fSpin = true;
+    }
+    pState->PreemptState = StateInit;
+    RTThreadPreemptDisable(&pState->PreemptState);
+
+#elif defined(RT_OS_LINUX) || defined(RT_OS_OS2)
+    /*
+     * OSes on which RTSemEventSignal can be called from any context.
+     */
+    pState->fSpin = !RTThreadPreemptIsEnabled(NIL_RTTHREAD);
+    if (RTThreadIsInInterrupt(NIL_RTTHREAD))
+    {
+        if (!(pThis->fFlags & RTSEMSPINMUTEX_FLAGS_IRQ_SAFE))
+            rc = VINF_SEM_BAD_CONTEXT; /* Try, but owner might be interrupted. */
+        pState->fSpin = true;
+    }
+    pState->PreemptState = StateInit;
+    RTThreadPreemptDisable(&pState->PreemptState);
+
+#else /* PORTME: Check for context where we cannot wake up threads. */
+    /*
+     * Default: ASSUME thread can be woken up if interrupts are enabled and
+     *          we're not in an interrupt context.
+     *          ASSUME that we can go to sleep if preemption is enabled.
+     */
+    if (    RTThreadIsInInterrupt(NIL_RTTHREAD)
+        ||  !ASMIntAreEnabled())
+        return VERR_SEM_BAD_CONTEXT;
+
+    pState->fSpin = !RTThreadPreemptIsEnabled(NIL_RTTHREAD);
+    pState->PreemptState = StateInit;
+    RTThreadPreemptDisable(&pState->PreemptState);
+#endif
+
+    /*
+     * Disable interrupts if necessary.
+     */
+    pState->fValidFlags = !!(pThis->fFlags & RTSEMSPINMUTEX_FLAGS_IRQ_SAFE);
+    if (pState->fValidFlags)
+        pState->fSavedFlags = ASMIntDisableFlags();
+    else
+        pState->fSavedFlags = 0;
+
+    return rc;
+}
+
+
+/**
+ * Helper for RTSemSpinMutexTryRequest, RTSemSpinMutexRequest and
+ * RTSemSpinMutexRelease.
+ *
+ * @param  pState
+ */
+DECL_FORCE_INLINE(void) rtSemSpinMutexLeave(RTSEMSPINMUTEXSTATE *pState)
+{
+    /*
+     * Restore the interrupt flag.
+     */
+    if (pState->fValidFlags)
+        ASMSetFlags(pState->fSavedFlags);
+
+#ifdef RT_OS_WINDOWS
+    /*
+     * NT: Lower the IRQL if we raised it.
+     */
+    if (pState->PreemptState.uchOldIrql < DISPATCH_LEVEL)
+        KeLowerIrql(pState->PreemptState.uchOldIrql);
+#else
+    /*
+     * Default: Restore preemption.
+     */
+    RTThreadPreemptRestore(&pState->PreemptState);
+#endif
+}
+
+
+RTDECL(int) RTSemSpinMutexTryRequest(RTSEMSPINMUTEX hSpinMtx)
+{
+    RTSEMSPINMUTEXINTERNAL *pThis = hSpinMtx;
+    RTNATIVETHREAD          hSelf = RTThreadNativeSelf();
+    RTSEMSPINMUTEXSTATE     State;
+    bool                    fRc;
+    int                     rc;
+
+    Assert(hSelf != NIL_RTNATIVETHREAD);
+    RTSEMSPINMUTEX_VALIDATE_RETURN(pThis);
+
+    /*
+     * Check context, disable preemption and save flags if necessary.
+     */
+    rc = rtSemSpinMutexEnter(&State, pThis);
+    if (RT_FAILURE(rc))
+        return rc;
+
+    /*
+     * Try take the ownership.
+     */
+    ASMAtomicCmpXchgHandle(&pThis->hOwner, hSelf, NIL_RTNATIVETHREAD, fRc);
+    if (!fRc)
+    {
+        /* Busy, too bad. Check for attempts at nested access. */
+        rc = VERR_SEM_BUSY;
+        if (RT_UNLIKELY(pThis->hOwner == hSelf))
+        {
+            AssertMsgFailed(("%p attempt at nested access\n"));
+            rc = VERR_SEM_NESTED;
+        }
+
+        rtSemSpinMutexLeave(&State);
+        return rc;
+    }
+
+    /*
+     * We're the semaphore owner.
+     */
+    ASMAtomicIncS32(&pThis->cLockers);
+    pThis->SavedState = State;
+    return VINF_SUCCESS;
+}
+RT_EXPORT_SYMBOL(RTSemSpinMutexTryRequest);
+
+
+RTDECL(int) RTSemSpinMutexRequest(RTSEMSPINMUTEX hSpinMtx)
+{
+    RTSEMSPINMUTEXINTERNAL *pThis = hSpinMtx;
+    RTNATIVETHREAD          hSelf = RTThreadNativeSelf();
+    RTSEMSPINMUTEXSTATE     State;
+    bool                    fRc;
+    int                     rc;
+
+    Assert(hSelf != NIL_RTNATIVETHREAD);
+    RTSEMSPINMUTEX_VALIDATE_RETURN(pThis);
+
+    /*
+     * Check context, disable preemption and save flags if necessary.
+     */
+    rc = rtSemSpinMutexEnter(&State, pThis);
+    if (RT_FAILURE(rc))
+        return rc;
+
+    /*
+     * Try take the ownership.
+     */
+    ASMAtomicIncS32(&pThis->cLockers);
+    ASMAtomicCmpXchgHandle(&pThis->hOwner, hSelf, NIL_RTNATIVETHREAD, fRc);
+    if (!fRc)
+    {
+        uint32_t cSpins;
+
+        /*
+         * It's busy. Check if it's an attempt at nested access.
+         */
+        if (RT_UNLIKELY(pThis->hOwner == hSelf))
+        {
+            AssertMsgFailed(("%p attempt at nested access\n"));
+            rtSemSpinMutexLeave(&State);
+            return VERR_SEM_NESTED;
+        }
+
+        /*
+         * Return if we're in interrupt context and the semaphore isn't
+         * configure to be interrupt safe.
+         */
+        if (rc == VINF_SEM_BAD_CONTEXT)
+        {
+            rtSemSpinMutexLeave(&State);
+            return VERR_SEM_BAD_CONTEXT;
+        }
+
+        /*
+         * Ok, we have to wait.
+         */
+        if (State.fSpin)
+        {
+            for (cSpins = 0; ; cSpins++)
+            {
+                ASMAtomicCmpXchgHandle(&pThis->hOwner, hSelf, NIL_RTNATIVETHREAD, fRc);
+                if (fRc)
+                    break;
+                ASMNopPause();
+                if (RT_UNLIKELY(pThis->u32Magic != RTSEMSPINMUTEX_MAGIC))
+                {
+                    rtSemSpinMutexLeave(&State);
+                    return VERR_SEM_DESTROYED;
+                }
+
+                /*
+                 * "Yield" once in a while. This may lower our IRQL/PIL which
+                 * may preempting us, and it will certainly stop the hammering
+                 * of hOwner for a little while.
+                 */
+                if ((cSpins & 0x7f) == 0x1f)
+                {
+                    rtSemSpinMutexLeave(&State);
+                    rtSemSpinMutexEnter(&State, pThis);
+                    Assert(State.fSpin);
+                }
+            }
+        }
+        else
+        {
+            for (cSpins = 0;; cSpins++)
+            {
+                ASMAtomicCmpXchgHandle(&pThis->hOwner, hSelf, NIL_RTNATIVETHREAD, fRc);
+                if (fRc)
+                    break;
+                ASMNopPause();
+                if (RT_UNLIKELY(pThis->u32Magic != RTSEMSPINMUTEX_MAGIC))
+                {
+                    rtSemSpinMutexLeave(&State);
+                    return VERR_SEM_DESTROYED;
+                }
+
+                if ((cSpins & 15) == 15) /* spin a bit before going sleep (again). */
+                {
+                    rtSemSpinMutexLeave(&State);
+
+                    rc = RTSemEventWait(pThis->hEventSem, RT_INDEFINITE_WAIT);
+                    ASMCompilerBarrier();
+                    if (RT_SUCCESS(rc))
+                        AssertReturn(pThis->u32Magic == RTSEMSPINMUTEX_MAGIC, VERR_SEM_DESTROYED);
+                    else if (rc == VERR_INTERRUPTED)
+                        AssertRC(rc);       /* shouldn't happen */
+                    else
+                    {
+                        AssertRC(rc);
+                        return rc;
+                    }
+
+                    rc = rtSemSpinMutexEnter(&State, pThis);
+                    AssertRCReturn(rc, rc);
+                    Assert(!State.fSpin);
+                }
+            }
+        }
+    }
+
+    /*
+     * We're the semaphore owner.
+     */
+    pThis->SavedState = State;
+    Assert(pThis->hOwner == hSelf);
+    return VINF_SUCCESS;
+}
+RT_EXPORT_SYMBOL(RTSemSpinMutexRequest);
+
+
+RTDECL(int) RTSemSpinMutexRelease(RTSEMSPINMUTEX hSpinMtx)
+{
+    RTSEMSPINMUTEXINTERNAL *pThis = hSpinMtx;
+    RTNATIVETHREAD          hSelf = RTThreadNativeSelf();
+    uint32_t                cLockers;
+    RTSEMSPINMUTEXSTATE     State;
+    bool                    fRc;
+
+    Assert(hSelf != NIL_RTNATIVETHREAD);
+    RTSEMSPINMUTEX_VALIDATE_RETURN(pThis);
+
+    /*
+     * Get the saved state and try release the semaphore.
+     */
+    State = pThis->SavedState;
+    ASMCompilerBarrier();
+    ASMAtomicCmpXchgHandle(&pThis->hOwner, NIL_RTNATIVETHREAD, hSelf, fRc);
+    AssertMsgReturn(fRc,
+                    ("hOwner=%p hSelf=%p cLockers=%d\n", pThis->hOwner, hSelf, pThis->cLockers),
+                    VERR_NOT_OWNER);
+
+    cLockers = ASMAtomicDecS32(&pThis->cLockers);
+    rtSemSpinMutexLeave(&State);
+    if (cLockers > 0)
+    {
+        int rc = RTSemEventSignal(pThis->hEventSem);
+        AssertReleaseMsg(RT_SUCCESS(rc), ("RTSemEventSignal -> %Rrc\n", rc));
+    }
+    return VINF_SUCCESS;
+}
+RT_EXPORT_SYMBOL(RTSemSpinMutexRelease);
+
+
+RTDECL(int) RTSemSpinMutexDestroy(RTSEMSPINMUTEX hSpinMtx)
+{
+    RTSEMSPINMUTEXINTERNAL *pThis;
+    RTSEMEVENT              hEventSem;
+    int                     rc;
+
+    if (hSpinMtx == NIL_RTSEMSPINMUTEX)
+        return VINF_SUCCESS;
+    pThis = hSpinMtx;
+    RTSEMSPINMUTEX_VALIDATE_RETURN(pThis);
+
+    /* No destruction races allowed! */
+    AssertMsg(   pThis->cLockers  == 0
+              && pThis->hOwner    == NIL_RTNATIVETHREAD,
+              ("pThis=%p cLockers=%d hOwner=%p\n", pThis, pThis->cLockers, pThis->hOwner));
+
+    /*
+     * Invalidate the structure, free the mutex and free the structure.
+     */
+    ASMAtomicWriteU32(&pThis->u32Magic, RTSEMSPINMUTEX_MAGIC_DEAD);
+    hEventSem        = pThis->hEventSem;
+    pThis->hEventSem = NIL_RTSEMEVENT;
+    rc = RTSemEventDestroy(hEventSem); AssertRC(rc);
+
+    RTMemFree(pThis);
+    return rc;
+}
+RT_EXPORT_SYMBOL(RTSemSpinMutexDestroy);
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/r0drv/initterm-r0drv.c
@@ -0,0 +1,154 @@
+/* $Id: initterm-r0drv.cpp $ */
+/** @file
+ * IPRT - Initialization & Termination, R0 Driver, Common.
+ */
+
+/*
+ * Copyright (C) 2006-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+
+/*********************************************************************************************************************************
+*   Header Files                                                                                                                 *
+*********************************************************************************************************************************/
+#include <iprt/initterm.h>
+#include "internal/iprt.h"
+
+#include <iprt/asm.h>
+#include <iprt/assert.h>
+#include <iprt/err.h>
+#include <iprt/mp.h>
+#include <iprt/thread.h>
+#ifndef IN_GUEST /* play safe for now */
+# include "r0drv/mp-r0drv.h"
+# include "r0drv/power-r0drv.h"
+#endif
+
+#include "internal/initterm.h"
+#include "internal/thread.h"
+
+
+/*********************************************************************************************************************************
+*   Global Variables                                                                                                             *
+*********************************************************************************************************************************/
+/** Count of current IPRT users.
+ * In ring-0 several drivers / kmods / kexts / wossnames may share the
+ * same runtime code. So, we need to keep count in order not to terminate
+ * it prematurely. */
+static int32_t volatile g_crtR0Users = 0;
+
+
+/**
+ * Initializes the ring-0 driver runtime library.
+ *
+ * @returns iprt status code.
+ * @param   fReserved       Flags reserved for the future.
+ */
+RTR0DECL(int) RTR0Init(unsigned fReserved)
+{
+    int rc;
+    uint32_t cNewUsers;
+    Assert(fReserved == 0);
+#ifndef RT_OS_SOLARIS       /* On Solaris our thread preemption information is only obtained in rtR0InitNative().*/
+    RT_ASSERT_PREEMPTIBLE();
+#endif
+
+    /*
+     * The first user initializes it.
+     * We rely on the module loader to ensure that there are no
+     * initialization races should two modules share the IPRT.
+     */
+    cNewUsers = ASMAtomicIncS32(&g_crtR0Users);
+    if (cNewUsers != 1)
+    {
+        if (cNewUsers > 1)
+            return VINF_SUCCESS;
+        ASMAtomicDecS32(&g_crtR0Users);
+        return VERR_INTERNAL_ERROR_3;
+    }
+
+    rc = rtR0InitNative();
+    if (RT_SUCCESS(rc))
+    {
+        rc = rtThreadInit();
+        if (RT_SUCCESS(rc))
+        {
+#ifndef IN_GUEST /* play safe for now */
+            rc = rtR0MpNotificationInit();
+            if (RT_SUCCESS(rc))
+            {
+                rc = rtR0PowerNotificationInit();
+                if (RT_SUCCESS(rc))
+                    return rc;
+                rtR0MpNotificationTerm();
+            }
+#else
+            if (RT_SUCCESS(rc))
+                return rc;
+#endif
+            rtThreadTerm();
+        }
+        rtR0TermNative();
+    }
+    return rc;
+}
+RT_EXPORT_SYMBOL(RTR0Init);
+
+
+static void rtR0Term(void)
+{
+    rtThreadTerm();
+#ifndef IN_GUEST /* play safe for now */
+    rtR0PowerNotificationTerm();
+    rtR0MpNotificationTerm();
+#endif
+    rtR0TermNative();
+}
+
+
+/**
+ * Terminates the ring-0 driver runtime library.
+ */
+RTR0DECL(void) RTR0Term(void)
+{
+    int32_t cNewUsers;
+    RT_ASSERT_PREEMPTIBLE();
+
+    cNewUsers = ASMAtomicDecS32(&g_crtR0Users);
+    Assert(cNewUsers >= 0);
+    if (cNewUsers == 0)
+        rtR0Term();
+    else if (cNewUsers < 0)
+        ASMAtomicIncS32(&g_crtR0Users);
+}
+RT_EXPORT_SYMBOL(RTR0Term);
+
+
+/* Note! Should *not* be exported since it's only for static linking. */
+RTR0DECL(void) RTR0TermForced(void)
+{
+    RT_ASSERT_PREEMPTIBLE();
+
+    AssertMsg(g_crtR0Users == 1, ("%d\n", g_crtR0Users));
+    ASMAtomicWriteS32(&g_crtR0Users, 0);
+
+    rtR0Term();
+}
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/r0drv/linux/RTLogWriteDebugger-r0drv-linux.c
@@ -0,0 +1,43 @@
+/* $Id: RTLogWriteDebugger-r0drv-linux.c $ */
+/** @file
+ * IPRT - Log To Debugger, Ring-0 Driver, Linux.
+ */
+
+/*
+ * Copyright (C) 2006-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+
+/*********************************************************************************************************************************
+*   Header Files                                                                                                                 *
+*********************************************************************************************************************************/
+#include "the-linux-kernel.h"
+#include "internal/iprt.h"
+#include <iprt/log.h>
+
+
+RTDECL(void) RTLogWriteDebugger(const char *pch, size_t cb)
+{
+    IPRT_LINUX_SAVE_EFL_AC();
+    printk("%.*s", (int)cb, pch);
+    IPRT_LINUX_RESTORE_EFL_AC();
+}
+RT_EXPORT_SYMBOL(RTLogWriteDebugger);
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/r0drv/linux/alloc-r0drv-linux.c
@@ -0,0 +1,500 @@
+/* $Id: alloc-r0drv-linux.c $ */
+/** @file
+ * IPRT - Memory Allocation, Ring-0 Driver, Linux.
+ */
+
+/*
+ * Copyright (C) 2006-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+
+/*********************************************************************************************************************************
+*   Header Files                                                                                                                 *
+*********************************************************************************************************************************/
+#include "the-linux-kernel.h"
+#include "internal/iprt.h"
+#include <iprt/mem.h>
+
+#include <iprt/assert.h>
+#include <iprt/err.h>
+#include "r0drv/alloc-r0drv.h"
+
+
+#if (defined(RT_ARCH_AMD64) || defined(DOXYGEN_RUNNING)) && !defined(RTMEMALLOC_EXEC_HEAP)
+# if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 23)
+/**
+ * Starting with 2.6.23 we can use __get_vm_area and map_vm_area to allocate
+ * memory in the moduel range.  This is preferrable to the exec heap below.
+ */
+#  define RTMEMALLOC_EXEC_VM_AREA
+# else
+/**
+ * We need memory in the module range (~2GB to ~0) this can only be obtained
+ * thru APIs that are not exported (see module_alloc()).
+ *
+ * So, we'll have to create a quick and dirty heap here using BSS memory.
+ * Very annoying and it's going to restrict us!
+ */
+#  define RTMEMALLOC_EXEC_HEAP
+# endif
+#endif
+
+#ifdef RTMEMALLOC_EXEC_HEAP
+# include <iprt/heap.h>
+# include <iprt/spinlock.h>
+# include <iprt/err.h>
+#endif
+
+
+/*********************************************************************************************************************************
+*   Structures and Typedefs                                                                                                      *
+*********************************************************************************************************************************/
+#ifdef RTMEMALLOC_EXEC_VM_AREA
+/**
+ * Extended header used for headers marked with RTMEMHDR_FLAG_EXEC_VM_AREA.
+ *
+ * This is used with allocating executable memory, for things like generated
+ * code and loaded modules.
+ */
+typedef struct RTMEMLNXHDREX
+{
+    /** The VM area for this allocation. */
+    struct vm_struct   *pVmArea;
+    void               *pvDummy;
+    /** The header we present to the generic API. */
+    RTMEMHDR            Hdr;
+} RTMEMLNXHDREX;
+AssertCompileSize(RTMEMLNXHDREX, 32);
+/** Pointer to an extended memory header. */
+typedef RTMEMLNXHDREX *PRTMEMLNXHDREX;
+#endif
+
+
+/*********************************************************************************************************************************
+*   Global Variables                                                                                                             *
+*********************************************************************************************************************************/
+#ifdef RTMEMALLOC_EXEC_HEAP
+/** The heap. */
+static RTHEAPSIMPLE g_HeapExec = NIL_RTHEAPSIMPLE;
+/** Spinlock protecting the heap. */
+static RTSPINLOCK   g_HeapExecSpinlock = NIL_RTSPINLOCK;
+#endif
+
+
+/**
+ * API for cleaning up the heap spinlock on IPRT termination.
+ * This is as RTMemExecDonate specific to AMD64 Linux/GNU.
+ */
+DECLHIDDEN(void) rtR0MemExecCleanup(void)
+{
+#ifdef RTMEMALLOC_EXEC_HEAP
+    RTSpinlockDestroy(g_HeapExecSpinlock);
+    g_HeapExecSpinlock = NIL_RTSPINLOCK;
+#endif
+}
+
+
+/**
+ * Donate read+write+execute memory to the exec heap.
+ *
+ * This API is specific to AMD64 and Linux/GNU. A kernel module that desires to
+ * use RTMemExecAlloc on AMD64 Linux/GNU will have to donate some statically
+ * allocated memory in the module if it wishes for GCC generated code to work.
+ * GCC can only generate modules that work in the address range ~2GB to ~0
+ * currently.
+ *
+ * The API only accept one single donation.
+ *
+ * @returns IPRT status code.
+ * @retval  VERR_NOT_SUPPORTED if the code isn't enabled.
+ * @param   pvMemory    Pointer to the memory block.
+ * @param   cb          The size of the memory block.
+ */
+RTR0DECL(int) RTR0MemExecDonate(void *pvMemory, size_t cb)
+{
+#ifdef RTMEMALLOC_EXEC_HEAP
+    int rc;
+    AssertReturn(g_HeapExec == NIL_RTHEAPSIMPLE, VERR_WRONG_ORDER);
+
+    rc = RTSpinlockCreate(&g_HeapExecSpinlock, RTSPINLOCK_FLAGS_INTERRUPT_SAFE, "RTR0MemExecDonate");
+    if (RT_SUCCESS(rc))
+    {
+        rc = RTHeapSimpleInit(&g_HeapExec, pvMemory, cb);
+        if (RT_FAILURE(rc))
+            rtR0MemExecCleanup();
+    }
+    return rc;
+#else
+    return VERR_NOT_SUPPORTED;
+#endif
+}
+RT_EXPORT_SYMBOL(RTR0MemExecDonate);
+
+
+
+#ifdef RTMEMALLOC_EXEC_VM_AREA
+/**
+ * Allocate executable kernel memory in the module range.
+ *
+ * @returns Pointer to a allocation header success.  NULL on failure.
+ *
+ * @param   cb          The size the user requested.
+ */
+static PRTMEMHDR rtR0MemAllocExecVmArea(size_t cb)
+{
+    size_t const        cbAlloc = RT_ALIGN_Z(sizeof(RTMEMLNXHDREX) + cb, PAGE_SIZE);
+    size_t const        cPages  = cbAlloc >> PAGE_SHIFT;
+    struct page       **papPages;
+    struct vm_struct   *pVmArea;
+    size_t              iPage;
+
+    pVmArea = __get_vm_area(cbAlloc, VM_ALLOC, MODULES_VADDR, MODULES_END);
+    if (!pVmArea)
+        return NULL;
+    pVmArea->nr_pages = 0;    /* paranoia? */
+    pVmArea->pages    = NULL; /* paranoia? */
+
+    papPages = (struct page **)kmalloc(cPages * sizeof(papPages[0]), GFP_KERNEL | __GFP_NOWARN);
+    if (!papPages)
+    {
+        vunmap(pVmArea->addr);
+        return NULL;
+    }
+
+    for (iPage = 0; iPage < cPages; iPage++)
+    {
+        papPages[iPage] = alloc_page(GFP_KERNEL | __GFP_HIGHMEM | __GFP_NOWARN);
+        if (!papPages[iPage])
+            break;
+    }
+    if (iPage == cPages)
+    {
+        /*
+         * Map the pages.
+         *
+         * Not entirely sure we really need to set nr_pages and pages here, but
+         * they provide a very convenient place for storing something we need
+         * in the free function, if nothing else...
+         */
+# if LINUX_VERSION_CODE < KERNEL_VERSION(3, 17, 0)
+        struct page **papPagesIterator = papPages;
+# endif
+        pVmArea->nr_pages = cPages;
+        pVmArea->pages    = papPages;
+        if (!map_vm_area(pVmArea, PAGE_KERNEL_EXEC,
+# if LINUX_VERSION_CODE < KERNEL_VERSION(3, 17, 0)
+                         &papPagesIterator
+# else
+                         papPages
+# endif
+                         ))
+        {
+            PRTMEMLNXHDREX pHdrEx = (PRTMEMLNXHDREX)pVmArea->addr;
+            pHdrEx->pVmArea     = pVmArea;
+            pHdrEx->pvDummy     = NULL;
+            return &pHdrEx->Hdr;
+        }
+        /* bail out */
+# if LINUX_VERSION_CODE < KERNEL_VERSION(3, 17, 0)
+        pVmArea->nr_pages = papPagesIterator - papPages;
+# endif
+    }
+
+    vunmap(pVmArea->addr);
+
+    while (iPage-- > 0)
+        __free_page(papPages[iPage]);
+    kfree(papPages);
+
+    return NULL;
+}
+#endif /* RTMEMALLOC_EXEC_VM_AREA */
+
+
+/**
+ * OS specific allocation function.
+ */
+DECLHIDDEN(int) rtR0MemAllocEx(size_t cb, uint32_t fFlags, PRTMEMHDR *ppHdr)
+{
+    PRTMEMHDR pHdr;
+    IPRT_LINUX_SAVE_EFL_AC();
+
+    /*
+     * Allocate.
+     */
+    if (fFlags & RTMEMHDR_FLAG_EXEC)
+    {
+        if (fFlags & RTMEMHDR_FLAG_ANY_CTX)
+            return VERR_NOT_SUPPORTED;
+
+#if defined(RT_ARCH_AMD64)
+# ifdef RTMEMALLOC_EXEC_HEAP
+        if (g_HeapExec != NIL_RTHEAPSIMPLE)
+        {
+            RTSpinlockAcquire(g_HeapExecSpinlock);
+            pHdr = (PRTMEMHDR)RTHeapSimpleAlloc(g_HeapExec, cb + sizeof(*pHdr), 0);
+            RTSpinlockRelease(g_HeapExecSpinlock);
+            fFlags |= RTMEMHDR_FLAG_EXEC_HEAP;
+        }
+        else
+            pHdr = NULL;
+
+# elif defined(RTMEMALLOC_EXEC_VM_AREA)
+        pHdr = rtR0MemAllocExecVmArea(cb);
+        fFlags |= RTMEMHDR_FLAG_EXEC_VM_AREA;
+
+# else  /* !RTMEMALLOC_EXEC_HEAP */
+# error "you don not want to go here..."
+        pHdr = (PRTMEMHDR)__vmalloc(cb + sizeof(*pHdr), GFP_KERNEL | __GFP_HIGHMEM | __GFP_NOWARN, MY_PAGE_KERNEL_EXEC);
+# endif /* !RTMEMALLOC_EXEC_HEAP */
+
+#elif defined(PAGE_KERNEL_EXEC) && defined(CONFIG_X86_PAE)
+        pHdr = (PRTMEMHDR)__vmalloc(cb + sizeof(*pHdr), GFP_KERNEL | __GFP_HIGHMEM | __GFP_NOWARN, MY_PAGE_KERNEL_EXEC);
+#else
+        pHdr = (PRTMEMHDR)vmalloc(cb + sizeof(*pHdr));
+#endif
+    }
+    else
+    {
+        if (
+#if 1 /* vmalloc has serious performance issues, avoid it. */
+               cb <= PAGE_SIZE*16 - sizeof(*pHdr)
+#else
+               cb <= PAGE_SIZE
+#endif
+            || (fFlags & RTMEMHDR_FLAG_ANY_CTX)
+           )
+        {
+            fFlags |= RTMEMHDR_FLAG_KMALLOC;
+            pHdr = kmalloc(cb + sizeof(*pHdr),
+                           (fFlags & RTMEMHDR_FLAG_ANY_CTX_ALLOC) ? (GFP_ATOMIC | __GFP_NOWARN)
+                                                                  : (GFP_KERNEL | __GFP_NOWARN));
+            if (RT_UNLIKELY(   !pHdr
+                            && cb > PAGE_SIZE
+                            && !(fFlags & RTMEMHDR_FLAG_ANY_CTX) ))
+            {
+                fFlags &= ~RTMEMHDR_FLAG_KMALLOC;
+                pHdr = vmalloc(cb + sizeof(*pHdr));
+            }
+        }
+        else
+            pHdr = vmalloc(cb + sizeof(*pHdr));
+    }
+    if (RT_UNLIKELY(!pHdr))
+    {
+        IPRT_LINUX_RESTORE_EFL_AC();
+        return VERR_NO_MEMORY;
+    }
+
+    /*
+     * Initialize.
+     */
+    pHdr->u32Magic  = RTMEMHDR_MAGIC;
+    pHdr->fFlags    = fFlags;
+    pHdr->cb        = cb;
+    pHdr->cbReq     = cb;
+
+    *ppHdr = pHdr;
+    IPRT_LINUX_RESTORE_EFL_AC();
+    return VINF_SUCCESS;
+}
+
+
+/**
+ * OS specific free function.
+ */
+DECLHIDDEN(void) rtR0MemFree(PRTMEMHDR pHdr)
+{
+    IPRT_LINUX_SAVE_EFL_AC();
+
+    pHdr->u32Magic += 1;
+    if (pHdr->fFlags & RTMEMHDR_FLAG_KMALLOC)
+        kfree(pHdr);
+#ifdef RTMEMALLOC_EXEC_HEAP
+    else if (pHdr->fFlags & RTMEMHDR_FLAG_EXEC_HEAP)
+    {
+        RTSpinlockAcquire(g_HeapExecSpinlock);
+        RTHeapSimpleFree(g_HeapExec, pHdr);
+        RTSpinlockRelease(g_HeapExecSpinlock);
+    }
+#endif
+#ifdef RTMEMALLOC_EXEC_VM_AREA
+    else if (pHdr->fFlags & RTMEMHDR_FLAG_EXEC_VM_AREA)
+    {
+        PRTMEMLNXHDREX pHdrEx    = RT_FROM_MEMBER(pHdr, RTMEMLNXHDREX, Hdr);
+        size_t         iPage     = pHdrEx->pVmArea->nr_pages;
+        struct page  **papPages  = pHdrEx->pVmArea->pages;
+        void          *pvMapping = pHdrEx->pVmArea->addr;
+
+        vunmap(pvMapping);
+
+        while (iPage-- > 0)
+            __free_page(papPages[iPage]);
+        kfree(papPages);
+    }
+#endif
+    else
+        vfree(pHdr);
+
+    IPRT_LINUX_RESTORE_EFL_AC();
+}
+
+
+
+/**
+ * Compute order. Some functions allocate 2^order pages.
+ *
+ * @returns order.
+ * @param   cPages      Number of pages.
+ */
+static int CalcPowerOf2Order(unsigned long cPages)
+{
+    int             iOrder;
+    unsigned long   cTmp;
+
+    for (iOrder = 0, cTmp = cPages; cTmp >>= 1; ++iOrder)
+        ;
+    if (cPages & ~(1 << iOrder))
+        ++iOrder;
+
+    return iOrder;
+}
+
+
+/**
+ * Allocates physical contiguous memory (below 4GB).
+ * The allocation is page aligned and the content is undefined.
+ *
+ * @returns Pointer to the memory block. This is page aligned.
+ * @param   pPhys   Where to store the physical address.
+ * @param   cb      The allocation size in bytes. This is always
+ *                  rounded up to PAGE_SIZE.
+ */
+RTR0DECL(void *) RTMemContAlloc(PRTCCPHYS pPhys, size_t cb)
+{
+    int             cOrder;
+    unsigned        cPages;
+    struct page    *paPages;
+    void           *pvRet;
+    IPRT_LINUX_SAVE_EFL_AC();
+
+    /*
+     * validate input.
+     */
+    Assert(VALID_PTR(pPhys));
+    Assert(cb > 0);
+
+    /*
+     * Allocate page pointer array.
+     */
+    cb = RT_ALIGN_Z(cb, PAGE_SIZE);
+    cPages = cb >> PAGE_SHIFT;
+    cOrder = CalcPowerOf2Order(cPages);
+#if (defined(RT_ARCH_AMD64) || defined(CONFIG_X86_PAE)) && defined(GFP_DMA32)
+    /* ZONE_DMA32: 0-4GB */
+    paPages = alloc_pages(GFP_DMA32 | __GFP_NOWARN, cOrder);
+    if (!paPages)
+#endif
+#ifdef RT_ARCH_AMD64
+        /* ZONE_DMA; 0-16MB */
+        paPages = alloc_pages(GFP_DMA | __GFP_NOWARN, cOrder);
+#else
+        /* ZONE_NORMAL: 0-896MB */
+        paPages = alloc_pages(GFP_USER | __GFP_NOWARN, cOrder);
+#endif
+    if (paPages)
+    {
+        /*
+         * Reserve the pages and mark them executable.
+         */
+        unsigned iPage;
+        for (iPage = 0; iPage < cPages; iPage++)
+        {
+            Assert(!PageHighMem(&paPages[iPage]));
+            if (iPage + 1 < cPages)
+            {
+                AssertMsg(          (uintptr_t)phys_to_virt(page_to_phys(&paPages[iPage])) + PAGE_SIZE
+                                ==  (uintptr_t)phys_to_virt(page_to_phys(&paPages[iPage + 1]))
+                          &&        page_to_phys(&paPages[iPage]) + PAGE_SIZE
+                                ==  page_to_phys(&paPages[iPage + 1]),
+                          ("iPage=%i cPages=%u [0]=%#llx,%p [1]=%#llx,%p\n", iPage, cPages,
+                           (long long)page_to_phys(&paPages[iPage]),     phys_to_virt(page_to_phys(&paPages[iPage])),
+                           (long long)page_to_phys(&paPages[iPage + 1]), phys_to_virt(page_to_phys(&paPages[iPage + 1])) ));
+            }
+
+            SetPageReserved(&paPages[iPage]);
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 4, 20) /** @todo find the exact kernel where change_page_attr was introduced. */
+            MY_SET_PAGES_EXEC(&paPages[iPage], 1);
+#endif
+        }
+        *pPhys = page_to_phys(paPages);
+        pvRet = phys_to_virt(page_to_phys(paPages));
+    }
+    else
+        pvRet = NULL;
+
+    IPRT_LINUX_RESTORE_EFL_AC();
+    return pvRet;
+}
+RT_EXPORT_SYMBOL(RTMemContAlloc);
+
+
+/**
+ * Frees memory allocated using RTMemContAlloc().
+ *
+ * @param   pv      Pointer to return from RTMemContAlloc().
+ * @param   cb      The cb parameter passed to RTMemContAlloc().
+ */
+RTR0DECL(void) RTMemContFree(void *pv, size_t cb)
+{
+    if (pv)
+    {
+        int             cOrder;
+        unsigned        cPages;
+        unsigned        iPage;
+        struct page    *paPages;
+        IPRT_LINUX_SAVE_EFL_AC();
+
+        /* validate */
+        AssertMsg(!((uintptr_t)pv & PAGE_OFFSET_MASK), ("pv=%p\n", pv));
+        Assert(cb > 0);
+
+        /* calc order and get pages */
+        cb = RT_ALIGN_Z(cb, PAGE_SIZE);
+        cPages = cb >> PAGE_SHIFT;
+        cOrder = CalcPowerOf2Order(cPages);
+        paPages = virt_to_page(pv);
+
+        /*
+         * Restore page attributes freeing the pages.
+         */
+        for (iPage = 0; iPage < cPages; iPage++)
+        {
+            ClearPageReserved(&paPages[iPage]);
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 4, 20) /** @todo find the exact kernel where change_page_attr was introduced. */
+            MY_SET_PAGES_NOEXEC(&paPages[iPage], 1);
+#endif
+        }
+        __free_pages(paPages, cOrder);
+        IPRT_LINUX_RESTORE_EFL_AC();
+    }
+}
+RT_EXPORT_SYMBOL(RTMemContFree);
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/r0drv/linux/assert-r0drv-linux.c
@@ -0,0 +1,74 @@
+/* $Id: assert-r0drv-linux.c $ */
+/** @file
+ * IPRT -  Assertion Workers, Ring-0 Drivers, Linux.
+ */
+
+/*
+ * Copyright (C) 2007-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+
+/*********************************************************************************************************************************
+*   Header Files                                                                                                                 *
+*********************************************************************************************************************************/
+#include "the-linux-kernel.h"
+#include "internal/iprt.h"
+
+#include <iprt/assert.h>
+#include <iprt/log.h>
+#include <iprt/string.h>
+#include <iprt/stdarg.h>
+#include <iprt/asm.h>
+
+#include "internal/assert.h"
+
+
+DECLHIDDEN(void) rtR0AssertNativeMsg1(const char *pszExpr, unsigned uLine, const char *pszFile, const char *pszFunction)
+{
+    IPRT_LINUX_SAVE_EFL_AC();
+    printk(KERN_EMERG
+           "\r\n!!Assertion Failed!!\r\n"
+           "Expression: %s\r\n"
+           "Location  : %s(%d) %s\r\n",
+           pszExpr, pszFile, uLine, pszFunction);
+    IPRT_LINUX_RESTORE_EFL_AC();
+}
+
+
+DECLHIDDEN(void) rtR0AssertNativeMsg2V(bool fInitial, const char *pszFormat, va_list va)
+{
+    char szMsg[256];
+    IPRT_LINUX_SAVE_EFL_AC();
+
+    RTStrPrintfV(szMsg, sizeof(szMsg) - 1, pszFormat, va);
+    szMsg[sizeof(szMsg) - 1] = '\0';
+    printk(KERN_EMERG "%s", szMsg);
+
+    NOREF(fInitial);
+    IPRT_LINUX_RESTORE_EFL_AC();
+}
+
+
+RTR0DECL(void) RTR0AssertPanicSystem(void)
+{
+    panic("%s%s", g_szRTAssertMsg1, g_szRTAssertMsg2);
+}
+RT_EXPORT_SYMBOL(RTR0AssertPanicSystem);
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/r0drv/linux/initterm-r0drv-linux.c
@@ -0,0 +1,137 @@
+/* $Id: initterm-r0drv-linux.c $ */
+/** @file
+ * IPRT - Initialization & Termination, R0 Driver, Linux.
+ */
+
+/*
+ * Copyright (C) 2006-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+
+/*********************************************************************************************************************************
+*   Header Files                                                                                                                 *
+*********************************************************************************************************************************/
+#include "the-linux-kernel.h"
+#include "internal/iprt.h"
+#include <iprt/err.h>
+#include <iprt/assert.h>
+#include "internal/initterm.h"
+
+
+/*********************************************************************************************************************************
+*   Global Variables                                                                                                             *
+*********************************************************************************************************************************/
+/** The IPRT work queue. */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 41)
+static struct workqueue_struct *g_prtR0LnxWorkQueue;
+#else
+static DECLARE_TASK_QUEUE(g_rtR0LnxWorkQueue);
+#endif
+
+
+/*********************************************************************************************************************************
+*   Internal Functions                                                                                                           *
+*********************************************************************************************************************************/
+/* in alloc-r0drv0-linux.c */
+DECLHIDDEN(void) rtR0MemExecCleanup(void);
+
+
+/**
+ * Pushes an item onto the IPRT work queue.
+ *
+ * @param   pWork               The work item.
+ * @param   pfnWorker           The callback function.  It will be called back
+ *                              with @a pWork as argument.
+ */
+DECLHIDDEN(void) rtR0LnxWorkqueuePush(RTR0LNXWORKQUEUEITEM *pWork, void (*pfnWorker)(RTR0LNXWORKQUEUEITEM *))
+{
+    IPRT_LINUX_SAVE_EFL_AC();
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 41)
+# if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 20)
+    INIT_WORK(pWork, pfnWorker);
+# else
+    INIT_WORK(pWork, pfnWorker, pWork);
+# endif
+    queue_work(g_prtR0LnxWorkQueue, pWork);
+#else
+    INIT_TQUEUE(pWork, (void (*)(void *))pfnWorker, pWork);
+    queue_task(pWork, &g_rtR0LnxWorkQueue);
+#endif
+
+    IPRT_LINUX_RESTORE_EFL_AC();
+}
+
+
+/**
+ * Flushes all items in the IPRT work queue.
+ *
+ * @remarks This is mostly for 2.4.x compatability.  Must not be called from
+ *          atomic contexts or with unncessary locks held.
+ */
+DECLHIDDEN(void) rtR0LnxWorkqueueFlush(void)
+{
+    IPRT_LINUX_SAVE_EFL_AC();
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 41)
+    flush_workqueue(g_prtR0LnxWorkQueue);
+#else
+    run_task_queue(&g_rtR0LnxWorkQueue);
+#endif
+
+    IPRT_LINUX_RESTORE_EFL_AC();
+}
+
+
+DECLHIDDEN(int) rtR0InitNative(void)
+{
+    int rc = VINF_SUCCESS;
+    IPRT_LINUX_SAVE_EFL_AC();
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 41)
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 13)
+    g_prtR0LnxWorkQueue = create_workqueue("iprt-VBoxWQueue");
+ #else
+    g_prtR0LnxWorkQueue = create_workqueue("iprt-VBoxQ");
+ #endif
+    if (!g_prtR0LnxWorkQueue)
+        rc = VERR_NO_MEMORY;
+#endif
+
+    IPRT_LINUX_RESTORE_EFL_AC();
+    return rc;
+}
+
+
+DECLHIDDEN(void) rtR0TermNative(void)
+{
+    IPRT_LINUX_SAVE_EFL_AC();
+
+    rtR0LnxWorkqueueFlush();
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 41)
+    destroy_workqueue(g_prtR0LnxWorkQueue);
+    g_prtR0LnxWorkQueue = NULL;
+#endif
+
+    rtR0MemExecCleanup();
+
+    IPRT_LINUX_RESTORE_EFL_AC();
+}
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/r0drv/linux/memobj-r0drv-linux.c
@@ -0,0 +1,1719 @@
+/* $Id: memobj-r0drv-linux.c $ */
+/** @file
+ * IPRT - Ring-0 Memory Objects, Linux.
+ */
+
+/*
+ * Copyright (C) 2006-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+
+/*********************************************************************************************************************************
+*   Header Files                                                                                                                 *
+*********************************************************************************************************************************/
+#include "the-linux-kernel.h"
+
+#include <iprt/memobj.h>
+#include <iprt/alloc.h>
+#include <iprt/assert.h>
+#include <iprt/log.h>
+#include <iprt/process.h>
+#include <iprt/string.h>
+#include "internal/memobj.h"
+
+
+/*********************************************************************************************************************************
+*   Defined Constants And Macros                                                                                                 *
+*********************************************************************************************************************************/
+/* early 2.6 kernels */
+#ifndef PAGE_SHARED_EXEC
+# define PAGE_SHARED_EXEC PAGE_SHARED
+#endif
+#ifndef PAGE_READONLY_EXEC
+# define PAGE_READONLY_EXEC PAGE_READONLY
+#endif
+
+/*
+ * 2.6.29+ kernels don't work with remap_pfn_range() anymore because
+ * track_pfn_vma_new() is apparently not defined for non-RAM pages.
+ * It should be safe to use vm_insert_page() older kernels as well.
+ */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 23)
+# define VBOX_USE_INSERT_PAGE
+#endif
+#if    defined(CONFIG_X86_PAE) \
+    && (   defined(HAVE_26_STYLE_REMAP_PAGE_RANGE) \
+        || (   LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) \
+            && LINUX_VERSION_CODE <  KERNEL_VERSION(2, 6, 11)))
+# define VBOX_USE_PAE_HACK
+#endif
+
+
+/*********************************************************************************************************************************
+*   Structures and Typedefs                                                                                                      *
+*********************************************************************************************************************************/
+/**
+ * The Darwin version of the memory object structure.
+ */
+typedef struct RTR0MEMOBJLNX
+{
+    /** The core structure. */
+    RTR0MEMOBJINTERNAL  Core;
+    /** Set if the allocation is contiguous.
+     * This means it has to be given back as one chunk. */
+    bool                fContiguous;
+    /** Set if we've vmap'ed the memory into ring-0. */
+    bool                fMappedToRing0;
+    /** The pages in the apPages array. */
+    size_t              cPages;
+    /** Array of struct page pointers. (variable size) */
+    struct page        *apPages[1];
+} RTR0MEMOBJLNX, *PRTR0MEMOBJLNX;
+
+
+static void rtR0MemObjLinuxFreePages(PRTR0MEMOBJLNX pMemLnx);
+
+
+/**
+ * Helper that converts from a RTR0PROCESS handle to a linux task.
+ *
+ * @returns The corresponding Linux task.
+ * @param   R0Process   IPRT ring-0 process handle.
+ */
+static struct task_struct *rtR0ProcessToLinuxTask(RTR0PROCESS R0Process)
+{
+    /** @todo fix rtR0ProcessToLinuxTask!! */
+    /** @todo many (all?) callers currently assume that we return 'current'! */
+    return R0Process == RTR0ProcHandleSelf() ? current : NULL;
+}
+
+
+/**
+ * Compute order. Some functions allocate 2^order pages.
+ *
+ * @returns order.
+ * @param   cPages      Number of pages.
+ */
+static int rtR0MemObjLinuxOrder(size_t cPages)
+{
+    int     iOrder;
+    size_t  cTmp;
+
+    for (iOrder = 0, cTmp = cPages; cTmp >>= 1; ++iOrder)
+        ;
+    if (cPages & ~((size_t)1 << iOrder))
+        ++iOrder;
+
+    return iOrder;
+}
+
+
+/**
+ * Converts from RTMEM_PROT_* to Linux PAGE_*.
+ *
+ * @returns Linux page protection constant.
+ * @param   fProt       The IPRT protection mask.
+ * @param   fKernel     Whether it applies to kernel or user space.
+ */
+static pgprot_t rtR0MemObjLinuxConvertProt(unsigned fProt, bool fKernel)
+{
+    switch (fProt)
+    {
+        default:
+            AssertMsgFailed(("%#x %d\n", fProt, fKernel));
+        case RTMEM_PROT_NONE:
+            return PAGE_NONE;
+
+        case RTMEM_PROT_READ:
+            return fKernel ? PAGE_KERNEL_RO         : PAGE_READONLY;
+
+        case RTMEM_PROT_WRITE:
+        case RTMEM_PROT_WRITE | RTMEM_PROT_READ:
+            return fKernel ? PAGE_KERNEL            : PAGE_SHARED;
+
+        case RTMEM_PROT_EXEC:
+        case RTMEM_PROT_EXEC | RTMEM_PROT_READ:
+#if defined(RT_ARCH_X86) || defined(RT_ARCH_AMD64)
+            if (fKernel)
+            {
+                pgprot_t fPg = MY_PAGE_KERNEL_EXEC;
+                pgprot_val(fPg) &= ~_PAGE_RW;
+                return fPg;
+            }
+            return PAGE_READONLY_EXEC;
+#else
+            return fKernel ? MY_PAGE_KERNEL_EXEC    : PAGE_READONLY_EXEC;
+#endif
+
+        case RTMEM_PROT_WRITE | RTMEM_PROT_EXEC:
+        case RTMEM_PROT_WRITE | RTMEM_PROT_EXEC | RTMEM_PROT_READ:
+            return fKernel ? MY_PAGE_KERNEL_EXEC    : PAGE_SHARED_EXEC;
+    }
+}
+
+
+/**
+ * Worker for rtR0MemObjNativeReserveUser and rtR0MemObjNativerMapUser that creates
+ * an empty user space mapping.
+ *
+ * We acquire the mmap_sem of the task!
+ *
+ * @returns Pointer to the mapping.
+ *          (void *)-1 on failure.
+ * @param   R3PtrFixed  (RTR3PTR)-1 if anywhere, otherwise a specific location.
+ * @param   cb          The size of the mapping.
+ * @param   uAlignment  The alignment of the mapping.
+ * @param   pTask       The Linux task to create this mapping in.
+ * @param   fProt       The RTMEM_PROT_* mask.
+ */
+static void *rtR0MemObjLinuxDoMmap(RTR3PTR R3PtrFixed, size_t cb, size_t uAlignment, struct task_struct *pTask, unsigned fProt)
+{
+    unsigned fLnxProt;
+    unsigned long ulAddr;
+
+    Assert((pTask == current)); /* do_mmap */
+
+    /*
+     * Convert from IPRT protection to mman.h PROT_ and call do_mmap.
+     */
+    fProt &= (RTMEM_PROT_NONE | RTMEM_PROT_READ | RTMEM_PROT_WRITE | RTMEM_PROT_EXEC);
+    if (fProt == RTMEM_PROT_NONE)
+        fLnxProt = PROT_NONE;
+    else
+    {
+        fLnxProt = 0;
+        if (fProt & RTMEM_PROT_READ)
+            fLnxProt |= PROT_READ;
+        if (fProt & RTMEM_PROT_WRITE)
+            fLnxProt |= PROT_WRITE;
+        if (fProt & RTMEM_PROT_EXEC)
+            fLnxProt |= PROT_EXEC;
+    }
+
+    if (R3PtrFixed != (RTR3PTR)-1)
+    {
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)
+        ulAddr = vm_mmap(NULL, R3PtrFixed, cb, fLnxProt, MAP_SHARED | MAP_ANONYMOUS | MAP_FIXED, 0);
+#else
+        down_write(&pTask->mm->mmap_sem);
+        ulAddr = do_mmap(NULL, R3PtrFixed, cb, fLnxProt, MAP_SHARED | MAP_ANONYMOUS | MAP_FIXED, 0);
+        up_write(&pTask->mm->mmap_sem);
+#endif
+    }
+    else
+    {
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)
+        ulAddr = vm_mmap(NULL, 0, cb, fLnxProt, MAP_SHARED | MAP_ANONYMOUS, 0);
+#else
+        down_write(&pTask->mm->mmap_sem);
+        ulAddr = do_mmap(NULL, 0, cb, fLnxProt, MAP_SHARED | MAP_ANONYMOUS, 0);
+        up_write(&pTask->mm->mmap_sem);
+#endif
+        if (    !(ulAddr & ~PAGE_MASK)
+            &&  (ulAddr & (uAlignment - 1)))
+        {
+            /** @todo implement uAlignment properly... We'll probably need to make some dummy mappings to fill
+             * up alignment gaps. This is of course complicated by fragmentation (which we might have cause
+             * ourselves) and further by there begin two mmap strategies (top / bottom). */
+            /* For now, just ignore uAlignment requirements... */
+        }
+    }
+
+
+    if (ulAddr & ~PAGE_MASK) /* ~PAGE_MASK == PAGE_OFFSET_MASK */
+        return (void *)-1;
+    return (void *)ulAddr;
+}
+
+
+/**
+ * Worker that destroys a user space mapping.
+ * Undoes what rtR0MemObjLinuxDoMmap did.
+ *
+ * We acquire the mmap_sem of the task!
+ *
+ * @param   pv          The ring-3 mapping.
+ * @param   cb          The size of the mapping.
+ * @param   pTask       The Linux task to destroy this mapping in.
+ */
+static void rtR0MemObjLinuxDoMunmap(void *pv, size_t cb, struct task_struct *pTask)
+{
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)
+    Assert(pTask == current);
+    vm_munmap((unsigned long)pv, cb);
+#elif defined(USE_RHEL4_MUNMAP)
+    down_write(&pTask->mm->mmap_sem);
+    do_munmap(pTask->mm, (unsigned long)pv, cb, 0); /* should it be 1 or 0? */
+    up_write(&pTask->mm->mmap_sem);
+#else
+    down_write(&pTask->mm->mmap_sem);
+    do_munmap(pTask->mm, (unsigned long)pv, cb);
+    up_write(&pTask->mm->mmap_sem);
+#endif
+}
+
+
+/**
+ * Internal worker that allocates physical pages and creates the memory object for them.
+ *
+ * @returns IPRT status code.
+ * @param   ppMemLnx    Where to store the memory object pointer.
+ * @param   enmType     The object type.
+ * @param   cb          The number of bytes to allocate.
+ * @param   uAlignment  The alignment of the physical memory.
+ *                      Only valid if fContiguous == true, ignored otherwise.
+ * @param   fFlagsLnx   The page allocation flags (GPFs).
+ * @param   fContiguous Whether the allocation must be contiguous.
+ * @param   rcNoMem     What to return when we're out of pages.
+ */
+static int rtR0MemObjLinuxAllocPages(PRTR0MEMOBJLNX *ppMemLnx, RTR0MEMOBJTYPE enmType, size_t cb,
+                                     size_t uAlignment, unsigned fFlagsLnx, bool fContiguous, int rcNoMem)
+{
+    size_t          iPage;
+    size_t const    cPages = cb >> PAGE_SHIFT;
+    struct page    *paPages;
+
+    /*
+     * Allocate a memory object structure that's large enough to contain
+     * the page pointer array.
+     */
+    PRTR0MEMOBJLNX  pMemLnx = (PRTR0MEMOBJLNX)rtR0MemObjNew(RT_OFFSETOF(RTR0MEMOBJLNX, apPages[cPages]), enmType, NULL, cb);
+    if (!pMemLnx)
+        return VERR_NO_MEMORY;
+    pMemLnx->cPages = cPages;
+
+     if (cPages > 255)
+     {
+# ifdef __GFP_REPEAT
+         /* Try hard to allocate the memory, but the allocation attempt might fail. */
+        fFlagsLnx |= __GFP_REPEAT;
+# endif
+# ifdef __GFP_NOMEMALLOC
+        /* Introduced with Linux 2.6.12: Don't use emergency reserves */
+        fFlagsLnx |= __GFP_NOMEMALLOC;
+# endif
+     }
+
+    /*
+     * Allocate the pages.
+     * For small allocations we'll try contiguous first and then fall back on page by page.
+     */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 22)
+    if (    fContiguous
+        ||  cb <= PAGE_SIZE * 2)
+    {
+# ifdef VBOX_USE_INSERT_PAGE
+        paPages = alloc_pages(fFlagsLnx | __GFP_COMP | __GFP_NOWARN, rtR0MemObjLinuxOrder(cPages));
+# else
+        paPages = alloc_pages(fFlagsLnx | __GFP_NOWARN, rtR0MemObjLinuxOrder(cPages));
+# endif
+        if (paPages)
+        {
+            fContiguous = true;
+            for (iPage = 0; iPage < cPages; iPage++)
+                pMemLnx->apPages[iPage] = &paPages[iPage];
+        }
+        else if (fContiguous)
+        {
+            rtR0MemObjDelete(&pMemLnx->Core);
+            return rcNoMem;
+        }
+    }
+
+    if (!fContiguous)
+    {
+        for (iPage = 0; iPage < cPages; iPage++)
+        {
+            pMemLnx->apPages[iPage] = alloc_page(fFlagsLnx | __GFP_NOWARN);
+            if (RT_UNLIKELY(!pMemLnx->apPages[iPage]))
+            {
+                while (iPage-- > 0)
+                    __free_page(pMemLnx->apPages[iPage]);
+                rtR0MemObjDelete(&pMemLnx->Core);
+                return rcNoMem;
+            }
+        }
+    }
+
+#else /* < 2.4.22 */
+    /** @todo figure out why we didn't allocate page-by-page on 2.4.21 and older... */
+    paPages = alloc_pages(fFlagsLnx, rtR0MemObjLinuxOrder(cPages));
+    if (!paPages)
+    {
+        rtR0MemObjDelete(&pMemLnx->Core);
+        return rcNoMem;
+    }
+    for (iPage = 0; iPage < cPages; iPage++)
+    {
+        pMemLnx->apPages[iPage] = &paPages[iPage];
+        MY_SET_PAGES_EXEC(pMemLnx->apPages[iPage], 1);
+        if (PageHighMem(pMemLnx->apPages[iPage]))
+            BUG();
+    }
+
+    fContiguous = true;
+#endif /* < 2.4.22 */
+    pMemLnx->fContiguous = fContiguous;
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 5, 0)
+    /*
+     * Reserve the pages.
+     * 
+     * Linux >= 4.5 with CONFIG_DEBUG_VM panics when setting PG_reserved on compound
+     * pages. According to Michal Hocko this shouldn't be necessary anyway because
+     * as pages which are not on the LRU list are never evictable.
+     */
+    for (iPage = 0; iPage < cPages; iPage++)
+        SetPageReserved(pMemLnx->apPages[iPage]);
+#endif
+
+    /*
+     * Note that the physical address of memory allocated with alloc_pages(flags, order)
+     * is always 2^(PAGE_SHIFT+order)-aligned.
+     */
+    if (   fContiguous
+        && uAlignment > PAGE_SIZE)
+    {
+        /*
+         * Check for alignment constraints. The physical address of memory allocated with
+         * alloc_pages(flags, order) is always 2^(PAGE_SHIFT+order)-aligned.
+         */
+        if (RT_UNLIKELY(page_to_phys(pMemLnx->apPages[0]) & (uAlignment - 1)))
+        {
+            /*
+             * This should never happen!
+             */
+            printk("rtR0MemObjLinuxAllocPages(cb=0x%lx, uAlignment=0x%lx): alloc_pages(..., %d) returned physical memory at 0x%lx!\n",
+                    (unsigned long)cb, (unsigned long)uAlignment, rtR0MemObjLinuxOrder(cPages), (unsigned long)page_to_phys(pMemLnx->apPages[0]));
+            rtR0MemObjLinuxFreePages(pMemLnx);
+            return rcNoMem;
+        }
+    }
+
+    *ppMemLnx = pMemLnx;
+    return VINF_SUCCESS;
+}
+
+
+/**
+ * Frees the physical pages allocated by the rtR0MemObjLinuxAllocPages() call.
+ *
+ * This method does NOT free the object.
+ *
+ * @param   pMemLnx     The object which physical pages should be freed.
+ */
+static void rtR0MemObjLinuxFreePages(PRTR0MEMOBJLNX pMemLnx)
+{
+    size_t iPage = pMemLnx->cPages;
+    if (iPage > 0)
+    {
+        /*
+         * Restore the page flags.
+         */
+        while (iPage-- > 0)
+        {
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 5, 0)
+            /*
+             * See SetPageReserved() in rtR0MemObjLinuxAllocPages()
+             */
+            ClearPageReserved(pMemLnx->apPages[iPage]);
+#endif
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 22)
+#else
+            MY_SET_PAGES_NOEXEC(pMemLnx->apPages[iPage], 1);
+#endif
+        }
+
+        /*
+         * Free the pages.
+         */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 22)
+        if (!pMemLnx->fContiguous)
+        {
+            iPage = pMemLnx->cPages;
+            while (iPage-- > 0)
+                __free_page(pMemLnx->apPages[iPage]);
+        }
+        else
+#endif
+            __free_pages(pMemLnx->apPages[0], rtR0MemObjLinuxOrder(pMemLnx->cPages));
+
+        pMemLnx->cPages = 0;
+    }
+}
+
+
+/**
+ * Maps the allocation into ring-0.
+ *
+ * This will update the RTR0MEMOBJLNX::Core.pv and RTR0MEMOBJ::fMappedToRing0 members.
+ *
+ * Contiguous mappings that isn't in 'high' memory will already be mapped into kernel
+ * space, so we'll use that mapping if possible. If execute access is required, we'll
+ * play safe and do our own mapping.
+ *
+ * @returns IPRT status code.
+ * @param   pMemLnx     The linux memory object to map.
+ * @param   fExecutable Whether execute access is required.
+ */
+static int rtR0MemObjLinuxVMap(PRTR0MEMOBJLNX pMemLnx, bool fExecutable)
+{
+    int rc = VINF_SUCCESS;
+
+    /*
+     * Choose mapping strategy.
+     */
+    bool fMustMap = fExecutable
+                 || !pMemLnx->fContiguous;
+    if (!fMustMap)
+    {
+        size_t iPage = pMemLnx->cPages;
+        while (iPage-- > 0)
+            if (PageHighMem(pMemLnx->apPages[iPage]))
+            {
+                fMustMap = true;
+                break;
+            }
+    }
+
+    Assert(!pMemLnx->Core.pv);
+    Assert(!pMemLnx->fMappedToRing0);
+
+    if (fMustMap)
+    {
+        /*
+         * Use vmap - 2.4.22 and later.
+         */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 22)
+        pgprot_t fPg;
+        pgprot_val(fPg) = _PAGE_PRESENT | _PAGE_RW;
+# ifdef _PAGE_NX
+        if (!fExecutable)
+            pgprot_val(fPg) |= _PAGE_NX;
+# endif
+
+# ifdef VM_MAP
+        pMemLnx->Core.pv = vmap(&pMemLnx->apPages[0], pMemLnx->cPages, VM_MAP, fPg);
+# else
+        pMemLnx->Core.pv = vmap(&pMemLnx->apPages[0], pMemLnx->cPages, VM_ALLOC, fPg);
+# endif
+        if (pMemLnx->Core.pv)
+            pMemLnx->fMappedToRing0 = true;
+        else
+            rc = VERR_MAP_FAILED;
+#else   /* < 2.4.22 */
+        rc = VERR_NOT_SUPPORTED;
+#endif
+    }
+    else
+    {
+        /*
+         * Use the kernel RAM mapping.
+         */
+        pMemLnx->Core.pv = phys_to_virt(page_to_phys(pMemLnx->apPages[0]));
+        Assert(pMemLnx->Core.pv);
+    }
+
+    return rc;
+}
+
+
+/**
+ * Undoes what rtR0MemObjLinuxVMap() did.
+ *
+ * @param   pMemLnx     The linux memory object.
+ */
+static void rtR0MemObjLinuxVUnmap(PRTR0MEMOBJLNX pMemLnx)
+{
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 22)
+    if (pMemLnx->fMappedToRing0)
+    {
+        Assert(pMemLnx->Core.pv);
+        vunmap(pMemLnx->Core.pv);
+        pMemLnx->fMappedToRing0 = false;
+    }
+#else /* < 2.4.22 */
+    Assert(!pMemLnx->fMappedToRing0);
+#endif
+    pMemLnx->Core.pv = NULL;
+}
+
+
+DECLHIDDEN(int) rtR0MemObjNativeFree(RTR0MEMOBJ pMem)
+{
+    IPRT_LINUX_SAVE_EFL_AC();
+    PRTR0MEMOBJLNX pMemLnx = (PRTR0MEMOBJLNX)pMem;
+
+    /*
+     * Release any memory that we've allocated or locked.
+     */
+    switch (pMemLnx->Core.enmType)
+    {
+        case RTR0MEMOBJTYPE_LOW:
+        case RTR0MEMOBJTYPE_PAGE:
+        case RTR0MEMOBJTYPE_CONT:
+        case RTR0MEMOBJTYPE_PHYS:
+        case RTR0MEMOBJTYPE_PHYS_NC:
+            rtR0MemObjLinuxVUnmap(pMemLnx);
+            rtR0MemObjLinuxFreePages(pMemLnx);
+            break;
+
+        case RTR0MEMOBJTYPE_LOCK:
+            if (pMemLnx->Core.u.Lock.R0Process != NIL_RTR0PROCESS)
+            {
+                struct task_struct *pTask = rtR0ProcessToLinuxTask(pMemLnx->Core.u.Lock.R0Process);
+                size_t              iPage;
+                Assert(pTask);
+                if (pTask && pTask->mm)
+                    down_read(&pTask->mm->mmap_sem);
+
+                iPage = pMemLnx->cPages;
+                while (iPage-- > 0)
+                {
+                    if (!PageReserved(pMemLnx->apPages[iPage]))
+                        SetPageDirty(pMemLnx->apPages[iPage]);
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 6, 0)
+                    put_page(pMemLnx->apPages[iPage]);
+#else
+                    page_cache_release(pMemLnx->apPages[iPage]);
+#endif
+                }
+
+                if (pTask && pTask->mm)
+                    up_read(&pTask->mm->mmap_sem);
+            }
+            /* else: kernel memory - nothing to do here. */
+            break;
+
+        case RTR0MEMOBJTYPE_RES_VIRT:
+            Assert(pMemLnx->Core.pv);
+            if (pMemLnx->Core.u.ResVirt.R0Process != NIL_RTR0PROCESS)
+            {
+                struct task_struct *pTask = rtR0ProcessToLinuxTask(pMemLnx->Core.u.Lock.R0Process);
+                Assert(pTask);
+                if (pTask && pTask->mm)
+                    rtR0MemObjLinuxDoMunmap(pMemLnx->Core.pv, pMemLnx->Core.cb, pTask);
+            }
+            else
+            {
+                vunmap(pMemLnx->Core.pv);
+
+                Assert(pMemLnx->cPages == 1 && pMemLnx->apPages[0] != NULL);
+                __free_page(pMemLnx->apPages[0]);
+                pMemLnx->apPages[0] = NULL;
+                pMemLnx->cPages = 0;
+            }
+            pMemLnx->Core.pv = NULL;
+            break;
+
+        case RTR0MEMOBJTYPE_MAPPING:
+            Assert(pMemLnx->cPages == 0); Assert(pMemLnx->Core.pv);
+            if (pMemLnx->Core.u.ResVirt.R0Process != NIL_RTR0PROCESS)
+            {
+                struct task_struct *pTask = rtR0ProcessToLinuxTask(pMemLnx->Core.u.Lock.R0Process);
+                Assert(pTask);
+                if (pTask && pTask->mm)
+                    rtR0MemObjLinuxDoMunmap(pMemLnx->Core.pv, pMemLnx->Core.cb, pTask);
+            }
+            else
+                vunmap(pMemLnx->Core.pv);
+            pMemLnx->Core.pv = NULL;
+            break;
+
+        default:
+            AssertMsgFailed(("enmType=%d\n", pMemLnx->Core.enmType));
+            return VERR_INTERNAL_ERROR;
+    }
+    IPRT_LINUX_RESTORE_EFL_ONLY_AC();
+    return VINF_SUCCESS;
+}
+
+
+DECLHIDDEN(int) rtR0MemObjNativeAllocPage(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, bool fExecutable)
+{
+    IPRT_LINUX_SAVE_EFL_AC();
+    PRTR0MEMOBJLNX pMemLnx;
+    int rc;
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 22)
+    rc = rtR0MemObjLinuxAllocPages(&pMemLnx, RTR0MEMOBJTYPE_PAGE, cb, PAGE_SIZE, GFP_HIGHUSER,
+                                   false /* non-contiguous */, VERR_NO_MEMORY);
+#else
+    rc = rtR0MemObjLinuxAllocPages(&pMemLnx, RTR0MEMOBJTYPE_PAGE, cb, PAGE_SIZE, GFP_USER,
+                                   false /* non-contiguous */, VERR_NO_MEMORY);
+#endif
+    if (RT_SUCCESS(rc))
+    {
+        rc = rtR0MemObjLinuxVMap(pMemLnx, fExecutable);
+        if (RT_SUCCESS(rc))
+        {
+            *ppMem = &pMemLnx->Core;
+            IPRT_LINUX_RESTORE_EFL_AC();
+            return rc;
+        }
+
+        rtR0MemObjLinuxFreePages(pMemLnx);
+        rtR0MemObjDelete(&pMemLnx->Core);
+    }
+
+    IPRT_LINUX_RESTORE_EFL_AC();
+    return rc;
+}
+
+
+DECLHIDDEN(int) rtR0MemObjNativeAllocLow(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, bool fExecutable)
+{
+    IPRT_LINUX_SAVE_EFL_AC();
+    PRTR0MEMOBJLNX pMemLnx;
+    int rc;
+
+    /* Try to avoid GFP_DMA. GFM_DMA32 was introduced with Linux 2.6.15. */
+#if (defined(RT_ARCH_AMD64) || defined(CONFIG_X86_PAE)) && defined(GFP_DMA32)
+    /* ZONE_DMA32: 0-4GB */
+    rc = rtR0MemObjLinuxAllocPages(&pMemLnx, RTR0MEMOBJTYPE_LOW, cb, PAGE_SIZE, GFP_DMA32,
+                                   false /* non-contiguous */, VERR_NO_LOW_MEMORY);
+    if (RT_FAILURE(rc))
+#endif
+#ifdef RT_ARCH_AMD64
+        /* ZONE_DMA: 0-16MB */
+        rc = rtR0MemObjLinuxAllocPages(&pMemLnx, RTR0MEMOBJTYPE_LOW, cb, PAGE_SIZE, GFP_DMA,
+                                       false /* non-contiguous */, VERR_NO_LOW_MEMORY);
+#else
+# ifdef CONFIG_X86_PAE
+# endif
+        /* ZONE_NORMAL: 0-896MB */
+        rc = rtR0MemObjLinuxAllocPages(&pMemLnx, RTR0MEMOBJTYPE_LOW, cb, PAGE_SIZE, GFP_USER,
+                                       false /* non-contiguous */, VERR_NO_LOW_MEMORY);
+#endif
+    if (RT_SUCCESS(rc))
+    {
+        rc = rtR0MemObjLinuxVMap(pMemLnx, fExecutable);
+        if (RT_SUCCESS(rc))
+        {
+            *ppMem = &pMemLnx->Core;
+            IPRT_LINUX_RESTORE_EFL_AC();
+            return rc;
+        }
+
+        rtR0MemObjLinuxFreePages(pMemLnx);
+        rtR0MemObjDelete(&pMemLnx->Core);
+    }
+
+    IPRT_LINUX_RESTORE_EFL_AC();
+    return rc;
+}
+
+
+DECLHIDDEN(int) rtR0MemObjNativeAllocCont(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, bool fExecutable)
+{
+    IPRT_LINUX_SAVE_EFL_AC();
+    PRTR0MEMOBJLNX pMemLnx;
+    int rc;
+
+#if (defined(RT_ARCH_AMD64) || defined(CONFIG_X86_PAE)) && defined(GFP_DMA32)
+    /* ZONE_DMA32: 0-4GB */
+    rc = rtR0MemObjLinuxAllocPages(&pMemLnx, RTR0MEMOBJTYPE_CONT, cb, PAGE_SIZE, GFP_DMA32,
+                                   true /* contiguous */, VERR_NO_CONT_MEMORY);
+    if (RT_FAILURE(rc))
+#endif
+#ifdef RT_ARCH_AMD64
+        /* ZONE_DMA: 0-16MB */
+        rc = rtR0MemObjLinuxAllocPages(&pMemLnx, RTR0MEMOBJTYPE_CONT, cb, PAGE_SIZE, GFP_DMA,
+                                       true /* contiguous */, VERR_NO_CONT_MEMORY);
+#else
+        /* ZONE_NORMAL (32-bit hosts): 0-896MB */
+        rc = rtR0MemObjLinuxAllocPages(&pMemLnx, RTR0MEMOBJTYPE_CONT, cb, PAGE_SIZE, GFP_USER,
+                                       true /* contiguous */, VERR_NO_CONT_MEMORY);
+#endif
+    if (RT_SUCCESS(rc))
+    {
+        rc = rtR0MemObjLinuxVMap(pMemLnx, fExecutable);
+        if (RT_SUCCESS(rc))
+        {
+#if defined(RT_STRICT) && (defined(RT_ARCH_AMD64) || defined(CONFIG_HIGHMEM64G))
+            size_t iPage = pMemLnx->cPages;
+            while (iPage-- > 0)
+                Assert(page_to_phys(pMemLnx->apPages[iPage]) < _4G);
+#endif
+            pMemLnx->Core.u.Cont.Phys = page_to_phys(pMemLnx->apPages[0]);
+            *ppMem = &pMemLnx->Core;
+            IPRT_LINUX_RESTORE_EFL_AC();
+            return rc;
+        }
+
+        rtR0MemObjLinuxFreePages(pMemLnx);
+        rtR0MemObjDelete(&pMemLnx->Core);
+    }
+
+    IPRT_LINUX_RESTORE_EFL_AC();
+    return rc;
+}
+
+
+/**
+ * Worker for rtR0MemObjLinuxAllocPhysSub that tries one allocation strategy.
+ *
+ * @returns IPRT status code.
+ * @param   ppMemLnx    Where to
+ * @param   enmType     The object type.
+ * @param   cb          The size of the allocation.
+ * @param   uAlignment  The alignment of the physical memory.
+ *                      Only valid for fContiguous == true, ignored otherwise.
+ * @param   PhysHighest See rtR0MemObjNativeAllocPhys.
+ * @param   fGfp        The Linux GFP flags to use for the allocation.
+ */
+static int rtR0MemObjLinuxAllocPhysSub2(PPRTR0MEMOBJINTERNAL ppMem, RTR0MEMOBJTYPE enmType,
+                                        size_t cb, size_t uAlignment, RTHCPHYS PhysHighest, unsigned fGfp)
+{
+    PRTR0MEMOBJLNX pMemLnx;
+    int rc;
+
+    rc = rtR0MemObjLinuxAllocPages(&pMemLnx, enmType, cb, uAlignment, fGfp,
+                                   enmType == RTR0MEMOBJTYPE_PHYS /* contiguous / non-contiguous */,
+                                   VERR_NO_PHYS_MEMORY);
+    if (RT_FAILURE(rc))
+        return rc;
+
+    /*
+     * Check the addresses if necessary. (Can be optimized a bit for PHYS.)
+     */
+    if (PhysHighest != NIL_RTHCPHYS)
+    {
+        size_t iPage = pMemLnx->cPages;
+        while (iPage-- > 0)
+            if (page_to_phys(pMemLnx->apPages[iPage]) > PhysHighest)
+            {
+                rtR0MemObjLinuxFreePages(pMemLnx);
+                rtR0MemObjDelete(&pMemLnx->Core);
+                return VERR_NO_MEMORY;
+            }
+    }
+
+    /*
+     * Complete the object.
+     */
+    if (enmType == RTR0MEMOBJTYPE_PHYS)
+    {
+        pMemLnx->Core.u.Phys.PhysBase = page_to_phys(pMemLnx->apPages[0]);
+        pMemLnx->Core.u.Phys.fAllocated = true;
+    }
+    *ppMem = &pMemLnx->Core;
+    return rc;
+}
+
+
+/**
+ * Worker for rtR0MemObjNativeAllocPhys and rtR0MemObjNativeAllocPhysNC.
+ *
+ * @returns IPRT status code.
+ * @param   ppMem       Where to store the memory object pointer on success.
+ * @param   enmType     The object type.
+ * @param   cb          The size of the allocation.
+ * @param   uAlignment  The alignment of the physical memory.
+ *                      Only valid for enmType == RTR0MEMOBJTYPE_PHYS, ignored otherwise.
+ * @param   PhysHighest See rtR0MemObjNativeAllocPhys.
+ */
+static int rtR0MemObjLinuxAllocPhysSub(PPRTR0MEMOBJINTERNAL ppMem, RTR0MEMOBJTYPE enmType,
+                                       size_t cb, size_t uAlignment, RTHCPHYS PhysHighest)
+{
+    int rc;
+    IPRT_LINUX_SAVE_EFL_AC();
+
+    /*
+     * There are two clear cases and that's the <=16MB and anything-goes ones.
+     * When the physical address limit is somewhere in-between those two we'll
+     * just have to try, starting with HIGHUSER and working our way thru the
+     * different types, hoping we'll get lucky.
+     *
+     * We should probably move this physical address restriction logic up to
+     * the page alloc function as it would be more efficient there. But since
+     * we don't expect this to be a performance issue just yet it can wait.
+     */
+    if (PhysHighest == NIL_RTHCPHYS)
+        /* ZONE_HIGHMEM: the whole physical memory */
+        rc = rtR0MemObjLinuxAllocPhysSub2(ppMem, enmType, cb, uAlignment, PhysHighest, GFP_HIGHUSER);
+    else if (PhysHighest <= _1M * 16)
+        /* ZONE_DMA: 0-16MB */
+        rc = rtR0MemObjLinuxAllocPhysSub2(ppMem, enmType, cb, uAlignment, PhysHighest, GFP_DMA);
+    else
+    {
+        rc = VERR_NO_MEMORY;
+        if (RT_FAILURE(rc))
+            /* ZONE_HIGHMEM: the whole physical memory */
+            rc = rtR0MemObjLinuxAllocPhysSub2(ppMem, enmType, cb, uAlignment, PhysHighest, GFP_HIGHUSER);
+        if (RT_FAILURE(rc))
+            /* ZONE_NORMAL: 0-896MB */
+            rc = rtR0MemObjLinuxAllocPhysSub2(ppMem, enmType, cb, uAlignment, PhysHighest, GFP_USER);
+#ifdef GFP_DMA32
+        if (RT_FAILURE(rc))
+            /* ZONE_DMA32: 0-4GB */
+            rc = rtR0MemObjLinuxAllocPhysSub2(ppMem, enmType, cb, uAlignment, PhysHighest, GFP_DMA32);
+#endif
+        if (RT_FAILURE(rc))
+            /* ZONE_DMA: 0-16MB */
+            rc = rtR0MemObjLinuxAllocPhysSub2(ppMem, enmType, cb, uAlignment, PhysHighest, GFP_DMA);
+    }
+    IPRT_LINUX_RESTORE_EFL_AC();
+    return rc;
+}
+
+
+/**
+ * Translates a kernel virtual address to a linux page structure by walking the
+ * page tables.
+ *
+ * @note    We do assume that the page tables will not change as we are walking
+ *          them.  This assumption is rather forced by the fact that I could not
+ *          immediately see any way of preventing this from happening.  So, we
+ *          take some extra care when accessing them.
+ *
+ *          Because of this, we don't want to use this function on memory where
+ *          attribute changes to nearby pages is likely to cause large pages to
+ *          be used or split up. So, don't use this for the linear mapping of
+ *          physical memory.
+ *
+ * @returns Pointer to the page structur or NULL if it could not be found.
+ * @param   pv      The kernel virtual address.
+ */
+static struct page *rtR0MemObjLinuxVirtToPage(void *pv)
+{
+    unsigned long   ulAddr = (unsigned long)pv;
+    unsigned long   pfn;
+    struct page    *pPage;
+    pte_t          *pEntry;
+    union
+    {
+        pgd_t       Global;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 11)
+        pud_t       Upper;
+#endif
+        pmd_t       Middle;
+        pte_t       Entry;
+    } u;
+
+    /* Should this happen in a situation this code will be called in?  And if
+     * so, can it change under our feet?  See also
+     * "Documentation/vm/active_mm.txt" in the kernel sources. */
+    if (RT_UNLIKELY(!current->active_mm))
+        return NULL;
+    u.Global = *pgd_offset(current->active_mm, ulAddr);
+    if (RT_UNLIKELY(pgd_none(u.Global)))
+        return NULL;
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 11)
+    u.Upper = *pud_offset(&u.Global, ulAddr);
+    if (RT_UNLIKELY(pud_none(u.Upper)))
+        return NULL;
+# if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)
+    if (pud_large(u.Upper))
+    {
+        pPage = pud_page(u.Upper);
+        AssertReturn(pPage, NULL);
+        pfn  = page_to_pfn(pPage);      /* doing the safe way... */
+        pfn += (ulAddr >> PAGE_SHIFT) & ((UINT32_C(1) << (PUD_SHIFT - PAGE_SHIFT)) - 1);
+        return pfn_to_page(pfn);
+    }
+# endif
+
+    u.Middle = *pmd_offset(&u.Upper, ulAddr);
+#else  /* < 2.6.11 */
+    u.Middle = *pmd_offset(&u.Global, ulAddr);
+#endif /* < 2.6.11 */
+    if (RT_UNLIKELY(pmd_none(u.Middle)))
+        return NULL;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)
+    if (pmd_large(u.Middle))
+    {
+        pPage = pmd_page(u.Middle);
+        AssertReturn(pPage, NULL);
+        pfn  = page_to_pfn(pPage);      /* doing the safe way... */
+        pfn += (ulAddr >> PAGE_SHIFT) & ((UINT32_C(1) << (PMD_SHIFT - PAGE_SHIFT)) - 1);
+        return pfn_to_page(pfn);
+    }
+#endif
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 5) || defined(pte_offset_map) /* As usual, RHEL 3 had pte_offset_map earlier. */
+    pEntry = pte_offset_map(&u.Middle, ulAddr);
+#else
+    pEntry = pte_offset(&u.Middle, ulAddr);
+#endif
+    if (RT_UNLIKELY(!pEntry))
+        return NULL;
+    u.Entry = *pEntry;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 5) || defined(pte_offset_map)
+    pte_unmap(pEntry);
+#endif
+
+    if (RT_UNLIKELY(!pte_present(u.Entry)))
+        return NULL;
+    return pte_page(u.Entry);
+}
+
+
+DECLHIDDEN(int) rtR0MemObjNativeAllocPhys(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, RTHCPHYS PhysHighest, size_t uAlignment)
+{
+    return rtR0MemObjLinuxAllocPhysSub(ppMem, RTR0MEMOBJTYPE_PHYS, cb, uAlignment, PhysHighest);
+}
+
+
+DECLHIDDEN(int) rtR0MemObjNativeAllocPhysNC(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, RTHCPHYS PhysHighest)
+{
+    return rtR0MemObjLinuxAllocPhysSub(ppMem, RTR0MEMOBJTYPE_PHYS_NC, cb, PAGE_SIZE, PhysHighest);
+}
+
+
+DECLHIDDEN(int) rtR0MemObjNativeEnterPhys(PPRTR0MEMOBJINTERNAL ppMem, RTHCPHYS Phys, size_t cb, uint32_t uCachePolicy)
+{
+    IPRT_LINUX_SAVE_EFL_AC();
+
+    /*
+     * All we need to do here is to validate that we can use
+     * ioremap on the specified address (32/64-bit dma_addr_t).
+     */
+    PRTR0MEMOBJLNX  pMemLnx;
+    dma_addr_t      PhysAddr = Phys;
+    AssertMsgReturn(PhysAddr == Phys, ("%#llx\n", (unsigned long long)Phys), VERR_ADDRESS_TOO_BIG);
+
+    pMemLnx = (PRTR0MEMOBJLNX)rtR0MemObjNew(sizeof(*pMemLnx), RTR0MEMOBJTYPE_PHYS, NULL, cb);
+    if (!pMemLnx)
+    {
+        IPRT_LINUX_RESTORE_EFL_AC();
+        return VERR_NO_MEMORY;
+    }
+
+    pMemLnx->Core.u.Phys.PhysBase = PhysAddr;
+    pMemLnx->Core.u.Phys.fAllocated = false;
+    pMemLnx->Core.u.Phys.uCachePolicy = uCachePolicy;
+    Assert(!pMemLnx->cPages);
+    *ppMem = &pMemLnx->Core;
+    IPRT_LINUX_RESTORE_EFL_AC();
+    return VINF_SUCCESS;
+}
+
+
+DECLHIDDEN(int) rtR0MemObjNativeLockUser(PPRTR0MEMOBJINTERNAL ppMem, RTR3PTR R3Ptr, size_t cb, uint32_t fAccess, RTR0PROCESS R0Process)
+{
+    IPRT_LINUX_SAVE_EFL_AC();
+    const int cPages = cb >> PAGE_SHIFT;
+    struct task_struct *pTask = rtR0ProcessToLinuxTask(R0Process);
+    struct vm_area_struct **papVMAs;
+    PRTR0MEMOBJLNX pMemLnx;
+    int             rc      = VERR_NO_MEMORY;
+    int  const      fWrite  = fAccess & RTMEM_PROT_WRITE ? 1 : 0;
+
+    /*
+     * Check for valid task and size overflows.
+     */
+    if (!pTask)
+        return VERR_NOT_SUPPORTED;
+    if (((size_t)cPages << PAGE_SHIFT) != cb)
+        return VERR_OUT_OF_RANGE;
+
+    /*
+     * Allocate the memory object and a temporary buffer for the VMAs.
+     */
+    pMemLnx = (PRTR0MEMOBJLNX)rtR0MemObjNew(RT_OFFSETOF(RTR0MEMOBJLNX, apPages[cPages]), RTR0MEMOBJTYPE_LOCK, (void *)R3Ptr, cb);
+    if (!pMemLnx)
+    {
+        IPRT_LINUX_RESTORE_EFL_AC();
+        return VERR_NO_MEMORY;
+    }
+
+    papVMAs = (struct vm_area_struct **)RTMemAlloc(sizeof(*papVMAs) * cPages);
+    if (papVMAs)
+    {
+        down_read(&pTask->mm->mmap_sem);
+
+        /*
+         * Get user pages.
+         */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 6, 0)
+        if (R0Process == RTR0ProcHandleSelf())
+            rc = get_user_pages(R3Ptr,                  /* Where from. */
+                                cPages,                 /* How many pages. */
+                                fWrite,                 /* Write to memory. */
+                                fWrite,                 /* force write access. */
+                                &pMemLnx->apPages[0],   /* Page array. */
+                                papVMAs);               /* vmas */
+        /*
+         * Actually this should not happen at the moment as call this function
+         * only for our own process.
+         */
+        else
+            rc = get_user_pages_remote(
+                                pTask,                  /* Task for fault accounting. */
+                                pTask->mm,              /* Whose pages. */
+                                R3Ptr,                  /* Where from. */
+                                cPages,                 /* How many pages. */
+                                fWrite,                 /* Write to memory. */
+                                fWrite,                 /* force write access. */
+                                &pMemLnx->apPages[0],   /* Page array. */
+                                papVMAs);               /* vmas */
+#else /* LINUX_VERSION_CODE < KERNEL_VERSION(4, 6, 0) */
+            rc = get_user_pages(pTask,                  /* Task for fault accounting. */
+                                pTask->mm,              /* Whose pages. */
+                                R3Ptr,                  /* Where from. */
+                                cPages,                 /* How many pages. */
+                                fWrite,                 /* Write to memory. */
+                                fWrite,                 /* force write access. */
+                                &pMemLnx->apPages[0],   /* Page array. */
+                                papVMAs);               /* vmas */
+#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(4, 6, 0) */
+        if (rc == cPages)
+        {
+            /*
+             * Flush dcache (required?), protect against fork and _really_ pin the page
+             * table entries. get_user_pages() will protect against swapping out the
+             * pages but it will NOT protect against removing page table entries. This
+             * can be achieved with
+             *   - using mlock / mmap(..., MAP_LOCKED, ...) from userland. This requires
+             *     an appropriate limit set up with setrlimit(..., RLIMIT_MEMLOCK, ...).
+             *     Usual Linux distributions support only a limited size of locked pages
+             *     (e.g. 32KB).
+             *   - setting the PageReserved bit (as we do in rtR0MemObjLinuxAllocPages()
+             *     or by
+             *   - setting the VM_LOCKED flag. This is the same as doing mlock() without
+             *     a range check.
+             */
+            /** @todo The Linux fork() protection will require more work if this API
+             * is to be used for anything but locking VM pages. */
+            while (rc-- > 0)
+            {
+                flush_dcache_page(pMemLnx->apPages[rc]);
+                papVMAs[rc]->vm_flags |= (VM_DONTCOPY | VM_LOCKED);
+            }
+
+            up_read(&pTask->mm->mmap_sem);
+
+            RTMemFree(papVMAs);
+
+            pMemLnx->Core.u.Lock.R0Process = R0Process;
+            pMemLnx->cPages = cPages;
+            Assert(!pMemLnx->fMappedToRing0);
+            *ppMem = &pMemLnx->Core;
+
+            IPRT_LINUX_RESTORE_EFL_AC();
+            return VINF_SUCCESS;
+        }
+
+        /*
+         * Failed - we need to unlock any pages that we succeeded to lock.
+         */
+        while (rc-- > 0)
+        {
+            if (!PageReserved(pMemLnx->apPages[rc]))
+                SetPageDirty(pMemLnx->apPages[rc]);
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 6, 0)
+            put_page(pMemLnx->apPages[rc]);
+#else
+            page_cache_release(pMemLnx->apPages[rc]);
+#endif
+        }
+
+        up_read(&pTask->mm->mmap_sem);
+
+        RTMemFree(papVMAs);
+        rc = VERR_LOCK_FAILED;
+    }
+
+    rtR0MemObjDelete(&pMemLnx->Core);
+    IPRT_LINUX_RESTORE_EFL_AC();
+    return rc;
+}
+
+
+DECLHIDDEN(int) rtR0MemObjNativeLockKernel(PPRTR0MEMOBJINTERNAL ppMem, void *pv, size_t cb, uint32_t fAccess)
+{
+    IPRT_LINUX_SAVE_EFL_AC();
+    void           *pvLast = (uint8_t *)pv + cb - 1;
+    size_t const    cPages = cb >> PAGE_SHIFT;
+    PRTR0MEMOBJLNX  pMemLnx;
+    bool            fLinearMapping;
+    int             rc;
+    uint8_t        *pbPage;
+    size_t          iPage;
+    NOREF(fAccess);
+
+    if (   !RTR0MemKernelIsValidAddr(pv)
+        || !RTR0MemKernelIsValidAddr(pv + cb))
+        return VERR_INVALID_PARAMETER;
+
+    /*
+     * The lower part of the kernel memory has a linear mapping between
+     * physical and virtual addresses. So we take a short cut here.  This is
+     * assumed to be the cleanest way to handle those addresses (and the code
+     * is well tested, though the test for determining it is not very nice).
+     * If we ever decide it isn't we can still remove it.
+     */
+#if 0
+    fLinearMapping = (unsigned long)pvLast < VMALLOC_START;
+#else
+    fLinearMapping = (unsigned long)pv     >= (unsigned long)__va(0)
+                  && (unsigned long)pvLast <  (unsigned long)high_memory;
+#endif
+
+    /*
+     * Allocate the memory object.
+     */
+    pMemLnx = (PRTR0MEMOBJLNX)rtR0MemObjNew(RT_OFFSETOF(RTR0MEMOBJLNX, apPages[cPages]), RTR0MEMOBJTYPE_LOCK, pv, cb);
+    if (!pMemLnx)
+    {
+        IPRT_LINUX_RESTORE_EFL_AC();
+        return VERR_NO_MEMORY;
+    }
+
+    /*
+     * Gather the pages.
+     * We ASSUME all kernel pages are non-swappable and non-movable.
+     */
+    rc     = VINF_SUCCESS;
+    pbPage = (uint8_t *)pvLast;
+    iPage  = cPages;
+    if (!fLinearMapping)
+    {
+        while (iPage-- > 0)
+        {
+            struct page *pPage = rtR0MemObjLinuxVirtToPage(pbPage);
+            if (RT_UNLIKELY(!pPage))
+            {
+                rc = VERR_LOCK_FAILED;
+                break;
+            }
+            pMemLnx->apPages[iPage] = pPage;
+            pbPage -= PAGE_SIZE;
+        }
+    }
+    else
+    {
+        while (iPage-- > 0)
+        {
+            pMemLnx->apPages[iPage] = virt_to_page(pbPage);
+            pbPage -= PAGE_SIZE;
+        }
+    }
+    if (RT_SUCCESS(rc))
+    {
+        /*
+         * Complete the memory object and return.
+         */
+        pMemLnx->Core.u.Lock.R0Process = NIL_RTR0PROCESS;
+        pMemLnx->cPages = cPages;
+        Assert(!pMemLnx->fMappedToRing0);
+        *ppMem = &pMemLnx->Core;
+
+        IPRT_LINUX_RESTORE_EFL_AC();
+        return VINF_SUCCESS;
+    }
+
+    rtR0MemObjDelete(&pMemLnx->Core);
+    IPRT_LINUX_RESTORE_EFL_AC();
+    return rc;
+}
+
+
+DECLHIDDEN(int) rtR0MemObjNativeReserveKernel(PPRTR0MEMOBJINTERNAL ppMem, void *pvFixed, size_t cb, size_t uAlignment)
+{
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 22)
+    IPRT_LINUX_SAVE_EFL_AC();
+    const size_t cPages = cb >> PAGE_SHIFT;
+    struct page *pDummyPage;
+    struct page **papPages;
+
+    /* check for unsupported stuff. */
+    AssertMsgReturn(pvFixed == (void *)-1, ("%p\n", pvFixed), VERR_NOT_SUPPORTED);
+    if (uAlignment > PAGE_SIZE)
+        return VERR_NOT_SUPPORTED;
+
+    /*
+     * Allocate a dummy page and create a page pointer array for vmap such that
+     * the dummy page is mapped all over the reserved area.
+     */
+    pDummyPage = alloc_page(GFP_HIGHUSER | __GFP_NOWARN);
+    if (pDummyPage)
+    {
+        papPages = RTMemAlloc(sizeof(*papPages) * cPages);
+        if (papPages)
+        {
+            void *pv;
+            size_t iPage = cPages;
+            while (iPage-- > 0)
+                papPages[iPage] = pDummyPage;
+# ifdef VM_MAP
+            pv = vmap(papPages, cPages, VM_MAP, PAGE_KERNEL_RO);
+# else
+            pv = vmap(papPages, cPages, VM_ALLOC, PAGE_KERNEL_RO);
+# endif
+            RTMemFree(papPages);
+            if (pv)
+            {
+                PRTR0MEMOBJLNX pMemLnx = (PRTR0MEMOBJLNX)rtR0MemObjNew(sizeof(*pMemLnx), RTR0MEMOBJTYPE_RES_VIRT, pv, cb);
+                if (pMemLnx)
+                {
+                    pMemLnx->Core.u.ResVirt.R0Process = NIL_RTR0PROCESS;
+                    pMemLnx->cPages = 1;
+                    pMemLnx->apPages[0] = pDummyPage;
+                    *ppMem = &pMemLnx->Core;
+                    IPRT_LINUX_RESTORE_EFL_AC();
+                    return VINF_SUCCESS;
+                }
+                vunmap(pv);
+            }
+        }
+        __free_page(pDummyPage);
+    }
+    IPRT_LINUX_RESTORE_EFL_AC();
+    return VERR_NO_MEMORY;
+
+#else   /* < 2.4.22 */
+    /*
+     * Could probably use ioremap here, but the caller is in a better position than us
+     * to select some safe physical memory.
+     */
+    return VERR_NOT_SUPPORTED;
+#endif
+}
+
+
+DECLHIDDEN(int) rtR0MemObjNativeReserveUser(PPRTR0MEMOBJINTERNAL ppMem, RTR3PTR R3PtrFixed, size_t cb, size_t uAlignment, RTR0PROCESS R0Process)
+{
+    IPRT_LINUX_SAVE_EFL_AC();
+    PRTR0MEMOBJLNX      pMemLnx;
+    void               *pv;
+    struct task_struct *pTask = rtR0ProcessToLinuxTask(R0Process);
+    if (!pTask)
+        return VERR_NOT_SUPPORTED;
+
+    /*
+     * Check that the specified alignment is supported.
+     */
+    if (uAlignment > PAGE_SIZE)
+        return VERR_NOT_SUPPORTED;
+
+    /*
+     * Let rtR0MemObjLinuxDoMmap do the difficult bits.
+     */
+    pv = rtR0MemObjLinuxDoMmap(R3PtrFixed, cb, uAlignment, pTask, RTMEM_PROT_NONE);
+    if (pv == (void *)-1)
+    {
+        IPRT_LINUX_RESTORE_EFL_AC();
+        return VERR_NO_MEMORY;
+    }
+
+    pMemLnx = (PRTR0MEMOBJLNX)rtR0MemObjNew(sizeof(*pMemLnx), RTR0MEMOBJTYPE_RES_VIRT, pv, cb);
+    if (!pMemLnx)
+    {
+        rtR0MemObjLinuxDoMunmap(pv, cb, pTask);
+        IPRT_LINUX_RESTORE_EFL_AC();
+        return VERR_NO_MEMORY;
+    }
+
+    pMemLnx->Core.u.ResVirt.R0Process = R0Process;
+    *ppMem = &pMemLnx->Core;
+    IPRT_LINUX_RESTORE_EFL_AC();
+    return VINF_SUCCESS;
+}
+
+
+DECLHIDDEN(int) rtR0MemObjNativeMapKernel(PPRTR0MEMOBJINTERNAL ppMem, RTR0MEMOBJ pMemToMap,
+                                          void *pvFixed, size_t uAlignment,
+                                          unsigned fProt, size_t offSub, size_t cbSub)
+{
+    int rc = VERR_NO_MEMORY;
+    PRTR0MEMOBJLNX pMemLnxToMap = (PRTR0MEMOBJLNX)pMemToMap;
+    PRTR0MEMOBJLNX pMemLnx;
+    IPRT_LINUX_SAVE_EFL_AC();
+
+    /* Fail if requested to do something we can't. */
+    AssertMsgReturn(!offSub && !cbSub, ("%#x %#x\n", offSub, cbSub), VERR_NOT_SUPPORTED);
+    AssertMsgReturn(pvFixed == (void *)-1, ("%p\n", pvFixed), VERR_NOT_SUPPORTED);
+    if (uAlignment > PAGE_SIZE)
+        return VERR_NOT_SUPPORTED;
+
+    /*
+     * Create the IPRT memory object.
+     */
+    pMemLnx = (PRTR0MEMOBJLNX)rtR0MemObjNew(sizeof(*pMemLnx), RTR0MEMOBJTYPE_MAPPING, NULL, pMemLnxToMap->Core.cb);
+    if (pMemLnx)
+    {
+        if (pMemLnxToMap->cPages)
+        {
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 22)
+            /*
+             * Use vmap - 2.4.22 and later.
+             */
+            pgprot_t fPg = rtR0MemObjLinuxConvertProt(fProt, true /* kernel */);
+# ifdef VM_MAP
+            pMemLnx->Core.pv = vmap(&pMemLnxToMap->apPages[0], pMemLnxToMap->cPages, VM_MAP, fPg);
+# else
+            pMemLnx->Core.pv = vmap(&pMemLnxToMap->apPages[0], pMemLnxToMap->cPages, VM_ALLOC, fPg);
+# endif
+            if (pMemLnx->Core.pv)
+            {
+                pMemLnx->fMappedToRing0 = true;
+                rc = VINF_SUCCESS;
+            }
+            else
+                rc = VERR_MAP_FAILED;
+
+#else   /* < 2.4.22 */
+            /*
+             * Only option here is to share mappings if possible and forget about fProt.
+             */
+            if (rtR0MemObjIsRing3(pMemToMap))
+                rc = VERR_NOT_SUPPORTED;
+            else
+            {
+                rc = VINF_SUCCESS;
+                if (!pMemLnxToMap->Core.pv)
+                    rc = rtR0MemObjLinuxVMap(pMemLnxToMap, !!(fProt & RTMEM_PROT_EXEC));
+                if (RT_SUCCESS(rc))
+                {
+                    Assert(pMemLnxToMap->Core.pv);
+                    pMemLnx->Core.pv = pMemLnxToMap->Core.pv;
+                }
+            }
+#endif
+        }
+        else
+        {
+            /*
+             * MMIO / physical memory.
+             */
+            Assert(pMemLnxToMap->Core.enmType == RTR0MEMOBJTYPE_PHYS && !pMemLnxToMap->Core.u.Phys.fAllocated);
+            pMemLnx->Core.pv = pMemLnxToMap->Core.u.Phys.uCachePolicy == RTMEM_CACHE_POLICY_MMIO
+                             ? ioremap_nocache(pMemLnxToMap->Core.u.Phys.PhysBase, pMemLnxToMap->Core.cb)
+                             : ioremap(pMemLnxToMap->Core.u.Phys.PhysBase, pMemLnxToMap->Core.cb);
+            if (pMemLnx->Core.pv)
+            {
+                /** @todo fix protection. */
+                rc = VINF_SUCCESS;
+            }
+        }
+        if (RT_SUCCESS(rc))
+        {
+            pMemLnx->Core.u.Mapping.R0Process = NIL_RTR0PROCESS;
+            *ppMem = &pMemLnx->Core;
+            IPRT_LINUX_RESTORE_EFL_AC();
+            return VINF_SUCCESS;
+        }
+        rtR0MemObjDelete(&pMemLnx->Core);
+    }
+
+    IPRT_LINUX_RESTORE_EFL_AC();
+    return rc;
+}
+
+
+#ifdef VBOX_USE_PAE_HACK
+/**
+ * Replace the PFN of a PTE with the address of the actual page.
+ *
+ * The caller maps a reserved dummy page at the address with the desired access
+ * and flags.
+ *
+ * This hack is required for older Linux kernels which don't provide
+ * remap_pfn_range().
+ *
+ * @returns 0 on success, -ENOMEM on failure.
+ * @param   mm          The memory context.
+ * @param   ulAddr      The mapping address.
+ * @param   Phys        The physical address of the page to map.
+ */
+static int rtR0MemObjLinuxFixPte(struct mm_struct *mm, unsigned long ulAddr, RTHCPHYS Phys)
+{
+    int rc = -ENOMEM;
+    pgd_t *pgd;
+
+    spin_lock(&mm->page_table_lock);
+
+    pgd = pgd_offset(mm, ulAddr);
+    if (!pgd_none(*pgd) && !pgd_bad(*pgd))
+    {
+        pmd_t *pmd = pmd_offset(pgd, ulAddr);
+        if (!pmd_none(*pmd))
+        {
+            pte_t *ptep = pte_offset_map(pmd, ulAddr);
+            if (ptep)
+            {
+                pte_t pte = *ptep;
+                pte.pte_high &= 0xfff00000;
+                pte.pte_high |= ((Phys >> 32) & 0x000fffff);
+                pte.pte_low  &= 0x00000fff;
+                pte.pte_low  |= (Phys & 0xfffff000);
+                set_pte(ptep, pte);
+                pte_unmap(ptep);
+                rc = 0;
+            }
+        }
+    }
+
+    spin_unlock(&mm->page_table_lock);
+    return rc;
+}
+#endif /* VBOX_USE_PAE_HACK */
+
+
+DECLHIDDEN(int) rtR0MemObjNativeMapUser(PPRTR0MEMOBJINTERNAL ppMem, RTR0MEMOBJ pMemToMap, RTR3PTR R3PtrFixed,
+                                        size_t uAlignment, unsigned fProt, RTR0PROCESS R0Process)
+{
+    struct task_struct *pTask        = rtR0ProcessToLinuxTask(R0Process);
+    PRTR0MEMOBJLNX      pMemLnxToMap = (PRTR0MEMOBJLNX)pMemToMap;
+    int                 rc           = VERR_NO_MEMORY;
+    PRTR0MEMOBJLNX      pMemLnx;
+#ifdef VBOX_USE_PAE_HACK
+    struct page        *pDummyPage;
+    RTHCPHYS            DummyPhys;
+#endif
+    IPRT_LINUX_SAVE_EFL_AC();
+
+    /*
+     * Check for restrictions.
+     */
+    if (!pTask)
+        return VERR_NOT_SUPPORTED;
+    if (uAlignment > PAGE_SIZE)
+        return VERR_NOT_SUPPORTED;
+
+#ifdef VBOX_USE_PAE_HACK
+    /*
+     * Allocate a dummy page for use when mapping the memory.
+     */
+    pDummyPage = alloc_page(GFP_USER | __GFP_NOWARN);
+    if (!pDummyPage)
+    {
+        IPRT_LINUX_RESTORE_EFL_AC();
+        return VERR_NO_MEMORY;
+    }
+    SetPageReserved(pDummyPage);
+    DummyPhys = page_to_phys(pDummyPage);
+#endif
+
+    /*
+     * Create the IPRT memory object.
+     */
+    pMemLnx = (PRTR0MEMOBJLNX)rtR0MemObjNew(sizeof(*pMemLnx), RTR0MEMOBJTYPE_MAPPING, NULL, pMemLnxToMap->Core.cb);
+    if (pMemLnx)
+    {
+        /*
+         * Allocate user space mapping.
+         */
+        void *pv;
+        pv = rtR0MemObjLinuxDoMmap(R3PtrFixed, pMemLnxToMap->Core.cb, uAlignment, pTask, fProt);
+        if (pv != (void *)-1)
+        {
+            /*
+             * Map page by page into the mmap area.
+             * This is generic, paranoid and not very efficient.
+             */
+            pgprot_t        fPg = rtR0MemObjLinuxConvertProt(fProt, false /* user */);
+            unsigned long   ulAddrCur = (unsigned long)pv;
+            const size_t    cPages = pMemLnxToMap->Core.cb >> PAGE_SHIFT;
+            size_t          iPage;
+
+            down_write(&pTask->mm->mmap_sem);
+
+            rc = VINF_SUCCESS;
+            if (pMemLnxToMap->cPages)
+            {
+                for (iPage = 0; iPage < cPages; iPage++, ulAddrCur += PAGE_SIZE)
+                {
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 11)
+                    RTHCPHYS Phys = page_to_phys(pMemLnxToMap->apPages[iPage]);
+#endif
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) || defined(HAVE_26_STYLE_REMAP_PAGE_RANGE)
+                    struct vm_area_struct *vma = find_vma(pTask->mm, ulAddrCur); /* this is probably the same for all the pages... */
+                    AssertBreakStmt(vma, rc = VERR_INTERNAL_ERROR);
+#endif
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0) && defined(RT_ARCH_X86)
+                    /* remap_page_range() limitation on x86 */
+                    AssertBreakStmt(Phys < _4G, rc = VERR_NO_MEMORY);
+#endif
+
+#if   defined(VBOX_USE_INSERT_PAGE) && LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 22)
+                    rc = vm_insert_page(vma, ulAddrCur, pMemLnxToMap->apPages[iPage]);
+                    /* Thes flags help making 100% sure some bad stuff wont happen (swap, core, ++).
+                     * See remap_pfn_range() in mm/memory.c */
+#if    LINUX_VERSION_CODE >= KERNEL_VERSION(3, 7, 0)
+                    vma->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP;
+#else
+                    vma->vm_flags |= VM_RESERVED;
+#endif
+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 11)
+                    rc = remap_pfn_range(vma, ulAddrCur, page_to_pfn(pMemLnxToMap->apPages[iPage]), PAGE_SIZE, fPg);
+#elif defined(VBOX_USE_PAE_HACK)
+                    rc = remap_page_range(vma, ulAddrCur, DummyPhys, PAGE_SIZE, fPg);
+                    if (!rc)
+                        rc = rtR0MemObjLinuxFixPte(pTask->mm, ulAddrCur, Phys);
+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) || defined(HAVE_26_STYLE_REMAP_PAGE_RANGE)
+                    rc = remap_page_range(vma, ulAddrCur, Phys, PAGE_SIZE, fPg);
+#else /* 2.4 */
+                    rc = remap_page_range(ulAddrCur, Phys, PAGE_SIZE, fPg);
+#endif
+                    if (rc)
+                    {
+                        rc = VERR_NO_MEMORY;
+                        break;
+                    }
+                }
+            }
+            else
+            {
+                RTHCPHYS Phys;
+                if (pMemLnxToMap->Core.enmType == RTR0MEMOBJTYPE_PHYS)
+                    Phys = pMemLnxToMap->Core.u.Phys.PhysBase;
+                else if (pMemLnxToMap->Core.enmType == RTR0MEMOBJTYPE_CONT)
+                    Phys = pMemLnxToMap->Core.u.Cont.Phys;
+                else
+                {
+                    AssertMsgFailed(("%d\n", pMemLnxToMap->Core.enmType));
+                    Phys = NIL_RTHCPHYS;
+                }
+                if (Phys != NIL_RTHCPHYS)
+                {
+                    for (iPage = 0; iPage < cPages; iPage++, ulAddrCur += PAGE_SIZE, Phys += PAGE_SIZE)
+                    {
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) || defined(HAVE_26_STYLE_REMAP_PAGE_RANGE)
+                        struct vm_area_struct *vma = find_vma(pTask->mm, ulAddrCur); /* this is probably the same for all the pages... */
+                        AssertBreakStmt(vma, rc = VERR_INTERNAL_ERROR);
+#endif
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0) && defined(RT_ARCH_X86)
+                        /* remap_page_range() limitation on x86 */
+                        AssertBreakStmt(Phys < _4G, rc = VERR_NO_MEMORY);
+#endif
+
+#if   LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 11)
+                        rc = remap_pfn_range(vma, ulAddrCur, Phys, PAGE_SIZE, fPg);
+#elif defined(VBOX_USE_PAE_HACK)
+                        rc = remap_page_range(vma, ulAddrCur, DummyPhys, PAGE_SIZE, fPg);
+                        if (!rc)
+                            rc = rtR0MemObjLinuxFixPte(pTask->mm, ulAddrCur, Phys);
+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) || defined(HAVE_26_STYLE_REMAP_PAGE_RANGE)
+                        rc = remap_page_range(vma, ulAddrCur, Phys, PAGE_SIZE, fPg);
+#else /* 2.4 */
+                        rc = remap_page_range(ulAddrCur, Phys, PAGE_SIZE, fPg);
+#endif
+                        if (rc)
+                        {
+                            rc = VERR_NO_MEMORY;
+                            break;
+                        }
+                    }
+                }
+            }
+
+#ifdef CONFIG_NUMA_BALANCING
+# if LINUX_VERSION_CODE < KERNEL_VERSION(3, 13, 0)
+#  ifdef RHEL_RELEASE_CODE
+#   if RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(7, 0)
+#    define VBOX_NUMA_HACK_OLD
+#   endif
+#  endif
+# endif
+            if (RT_SUCCESS(rc))
+            {
+                /** @todo Ugly hack! But right now we have no other means to
+                 *        disable automatic NUMA page balancing. */
+# ifdef RT_OS_X86
+#  ifdef VBOX_NUMA_HACK_OLD
+                pTask->mm->numa_next_reset = jiffies + 0x7fffffffUL;
+#  endif
+                pTask->mm->numa_next_scan  = jiffies + 0x7fffffffUL;
+# else
+#  ifdef VBOX_NUMA_HACK_OLD
+                pTask->mm->numa_next_reset = jiffies + 0x7fffffffffffffffUL;
+#  endif
+                pTask->mm->numa_next_scan  = jiffies + 0x7fffffffffffffffUL;
+# endif
+            }
+#endif /* CONFIG_NUMA_BALANCING */
+
+            up_write(&pTask->mm->mmap_sem);
+
+            if (RT_SUCCESS(rc))
+            {
+#ifdef VBOX_USE_PAE_HACK
+                __free_page(pDummyPage);
+#endif
+                pMemLnx->Core.pv = pv;
+                pMemLnx->Core.u.Mapping.R0Process = R0Process;
+                *ppMem = &pMemLnx->Core;
+                IPRT_LINUX_RESTORE_EFL_AC();
+                return VINF_SUCCESS;
+            }
+
+            /*
+             * Bail out.
+             */
+            rtR0MemObjLinuxDoMunmap(pv, pMemLnxToMap->Core.cb, pTask);
+        }
+        rtR0MemObjDelete(&pMemLnx->Core);
+    }
+#ifdef VBOX_USE_PAE_HACK
+    __free_page(pDummyPage);
+#endif
+
+    IPRT_LINUX_RESTORE_EFL_AC();
+    return rc;
+}
+
+
+DECLHIDDEN(int) rtR0MemObjNativeProtect(PRTR0MEMOBJINTERNAL pMem, size_t offSub, size_t cbSub, uint32_t fProt)
+{
+    NOREF(pMem);
+    NOREF(offSub);
+    NOREF(cbSub);
+    NOREF(fProt);
+    return VERR_NOT_SUPPORTED;
+}
+
+
+DECLHIDDEN(RTHCPHYS) rtR0MemObjNativeGetPagePhysAddr(PRTR0MEMOBJINTERNAL pMem, size_t iPage)
+{
+    PRTR0MEMOBJLNX  pMemLnx = (PRTR0MEMOBJLNX)pMem;
+
+    if (pMemLnx->cPages)
+        return page_to_phys(pMemLnx->apPages[iPage]);
+
+    switch (pMemLnx->Core.enmType)
+    {
+        case RTR0MEMOBJTYPE_CONT:
+            return pMemLnx->Core.u.Cont.Phys     + (iPage << PAGE_SHIFT);
+
+        case RTR0MEMOBJTYPE_PHYS:
+            return pMemLnx->Core.u.Phys.PhysBase + (iPage << PAGE_SHIFT);
+
+            /* the parent knows */
+        case RTR0MEMOBJTYPE_MAPPING:
+            return rtR0MemObjNativeGetPagePhysAddr(pMemLnx->Core.uRel.Child.pParent, iPage);
+
+            /* cPages > 0 */
+        case RTR0MEMOBJTYPE_LOW:
+        case RTR0MEMOBJTYPE_LOCK:
+        case RTR0MEMOBJTYPE_PHYS_NC:
+        case RTR0MEMOBJTYPE_PAGE:
+        default:
+            AssertMsgFailed(("%d\n", pMemLnx->Core.enmType));
+            /* fall thru */
+
+        case RTR0MEMOBJTYPE_RES_VIRT:
+            return NIL_RTHCPHYS;
+    }
+}
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/r0drv/linux/memuserkernel-r0drv-linux.c
@@ -0,0 +1,172 @@
+/* $Id: memuserkernel-r0drv-linux.c $ */
+/** @file
+ * IPRT - User & Kernel Memory, Ring-0 Driver, Linux.
+ */
+
+/*
+ * Copyright (C) 2009-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+
+/*********************************************************************************************************************************
+*   Header Files                                                                                                                 *
+*********************************************************************************************************************************/
+#include "the-linux-kernel.h"
+#include "internal/iprt.h"
+
+#include <iprt/mem.h>
+#include <iprt/err.h>
+
+
+RTR0DECL(int) RTR0MemUserCopyFrom(void *pvDst, RTR3PTR R3PtrSrc, size_t cb)
+{
+    IPRT_LINUX_SAVE_EFL_AC();
+    if (RT_LIKELY(copy_from_user(pvDst, (void *)R3PtrSrc, cb) == 0))
+    {
+        IPRT_LINUX_RESTORE_EFL_AC();
+        return VINF_SUCCESS;
+    }
+    IPRT_LINUX_RESTORE_EFL_AC();
+    return VERR_ACCESS_DENIED;
+}
+RT_EXPORT_SYMBOL(RTR0MemUserCopyFrom);
+
+
+RTR0DECL(int) RTR0MemUserCopyTo(RTR3PTR R3PtrDst, void const *pvSrc, size_t cb)
+{
+    IPRT_LINUX_SAVE_EFL_AC();
+    if (RT_LIKELY(copy_to_user((void *)R3PtrDst, pvSrc, cb) == 0))
+    {
+        IPRT_LINUX_RESTORE_EFL_AC();
+        return VINF_SUCCESS;
+    }
+    IPRT_LINUX_RESTORE_EFL_AC();
+    return VERR_ACCESS_DENIED;
+}
+RT_EXPORT_SYMBOL(RTR0MemUserCopyTo);
+
+
+RTR0DECL(bool) RTR0MemUserIsValidAddr(RTR3PTR R3Ptr)
+{
+    IPRT_LINUX_SAVE_EFL_AC();
+    bool fRc = access_ok(VERIFY_READ, (void *)R3Ptr, 1);
+    IPRT_LINUX_RESTORE_EFL_AC();
+    return fRc;
+}
+RT_EXPORT_SYMBOL(RTR0MemUserIsValidAddr);
+
+
+RTR0DECL(bool) RTR0MemKernelIsValidAddr(void *pv)
+{
+    /* Couldn't find a straight forward way of doing this... */
+#if defined(RT_ARCH_X86) && defined(CONFIG_X86_HIGH_ENTRY)
+    return true; /* ?? */
+#elif defined(RT_ARCH_X86) || defined(RT_ARCH_AMD64)
+    return (uintptr_t)pv >= PAGE_OFFSET;
+#else
+# error "PORT ME"
+    return !access_ok(VERIFY_READ, pv, 1);
+#endif
+}
+RT_EXPORT_SYMBOL(RTR0MemKernelIsValidAddr);
+
+
+RTR0DECL(bool) RTR0MemAreKrnlAndUsrDifferent(void)
+{
+#if defined(RT_ARCH_X86) && defined(CONFIG_X86_HIGH_ENTRY) /* ?? */
+    return false;
+#else
+    return true;
+#endif
+}
+RT_EXPORT_SYMBOL(RTR0MemAreKrnlAndUsrDifferent);
+
+
+/**
+ * Treats both source and destination as unsafe buffers.
+ */
+static int rtR0MemKernelCopyLnxWorker(void *pvDst, void const *pvSrc, size_t cb)
+{
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 55)
+/* _ASM_EXTABLE was introduced in 2.6.25 from what I can tell. Using #ifndef
+   here since it has to be a macro and you never know what someone might have
+   backported to an earlier kernel release. */
+# ifndef _ASM_EXTABLE
+#  if ARCH_BITS == 32
+#   define _ASM_EXTABLE(a_Instr, a_Resume) \
+    ".section __ex_table,\"a\"\n" \
+    ".balign 4\n" \
+    ".long   " #a_Instr "\n" \
+    ".long   " #a_Resume "\n" \
+    ".previous\n"
+#  else
+#   define _ASM_EXTABLE(a_Instr, a_Resume) \
+    ".section __ex_table,\"a\"\n" \
+    ".balign 8\n" \
+    ".quad   " #a_Instr "\n" \
+    ".quad   " #a_Resume "\n" \
+    ".previous\n"
+#  endif
+# endif /* !_ASM_EXTABLE */
+    int rc;
+    IPRT_LINUX_SAVE_EFL_AC(); /* paranoia */
+    if (!cb)
+        return VINF_SUCCESS;
+
+    __asm__ __volatile__ ("cld\n"
+                          "1:\n\t"
+                          "rep; movsb\n"
+                          "2:\n\t"
+                          ".section .fixup,\"ax\"\n"
+                          "3:\n\t"
+                          "movl %4, %0\n"
+                          ".previous\n"
+                          _ASM_EXTABLE(1b, 3b)
+                          : "=r" (rc),
+                            "=D" (pvDst),
+                            "=S" (pvSrc),
+                            "=c" (cb)
+                          : "i" (VERR_ACCESS_DENIED),
+                            "0" (VINF_SUCCESS),
+                            "1" (pvDst),
+                            "2" (pvSrc),
+                            "3" (cb)
+                          : "memory");
+    IPRT_LINUX_RESTORE_EFL_AC();
+    return rc;
+#else
+    return VERR_NOT_SUPPORTED;
+#endif
+}
+
+
+RTR0DECL(int) RTR0MemKernelCopyFrom(void *pvDst, void const *pvSrc, size_t cb)
+{
+    return rtR0MemKernelCopyLnxWorker(pvDst, pvSrc, cb);
+}
+RT_EXPORT_SYMBOL(RTR0MemKernelCopyFrom);
+
+
+RTR0DECL(int) RTR0MemKernelCopyTo(void *pvDst, void const *pvSrc, size_t cb)
+{
+    return rtR0MemKernelCopyLnxWorker(pvDst, pvSrc, cb);
+}
+RT_EXPORT_SYMBOL(RTR0MemKernelCopyTo);
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/r0drv/linux/mp-r0drv-linux.c
@@ -0,0 +1,581 @@
+/* $Id: mp-r0drv-linux.c $ */
+/** @file
+ * IPRT - Multiprocessor, Ring-0 Driver, Linux.
+ */
+
+/*
+ * Copyright (C) 2008-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+
+/*********************************************************************************************************************************
+*   Header Files                                                                                                                 *
+*********************************************************************************************************************************/
+#include "the-linux-kernel.h"
+#include "internal/iprt.h"
+
+#include <iprt/mp.h>
+#include <iprt/cpuset.h>
+#include <iprt/err.h>
+#include <iprt/asm.h>
+#include <iprt/thread.h>
+#include "r0drv/mp-r0drv.h"
+
+
+RTDECL(RTCPUID) RTMpCpuId(void)
+{
+    return smp_processor_id();
+}
+RT_EXPORT_SYMBOL(RTMpCpuId);
+
+
+RTDECL(int) RTMpCurSetIndex(void)
+{
+    return smp_processor_id();
+}
+RT_EXPORT_SYMBOL(RTMpCurSetIndex);
+
+
+RTDECL(int) RTMpCurSetIndexAndId(PRTCPUID pidCpu)
+{
+    return *pidCpu = smp_processor_id();
+}
+RT_EXPORT_SYMBOL(RTMpCurSetIndexAndId);
+
+
+RTDECL(int) RTMpCpuIdToSetIndex(RTCPUID idCpu)
+{
+    return idCpu < RTCPUSET_MAX_CPUS && idCpu < NR_CPUS ? (int)idCpu : -1;
+}
+RT_EXPORT_SYMBOL(RTMpCpuIdToSetIndex);
+
+
+RTDECL(RTCPUID) RTMpCpuIdFromSetIndex(int iCpu)
+{
+    return iCpu < NR_CPUS ? (RTCPUID)iCpu : NIL_RTCPUID;
+}
+RT_EXPORT_SYMBOL(RTMpCpuIdFromSetIndex);
+
+
+RTDECL(RTCPUID) RTMpGetMaxCpuId(void)
+{
+    return NR_CPUS - 1; //???
+}
+RT_EXPORT_SYMBOL(RTMpGetMaxCpuId);
+
+
+RTDECL(bool) RTMpIsCpuPossible(RTCPUID idCpu)
+{
+#if defined(CONFIG_SMP)
+    if (RT_UNLIKELY(idCpu >= NR_CPUS))
+        return false;
+
+# if defined(cpu_possible)
+    return cpu_possible(idCpu);
+# else /* < 2.5.29 */
+    return idCpu < (RTCPUID)smp_num_cpus;
+# endif
+#else
+    return idCpu == RTMpCpuId();
+#endif
+}
+RT_EXPORT_SYMBOL(RTMpIsCpuPossible);
+
+
+RTDECL(PRTCPUSET) RTMpGetSet(PRTCPUSET pSet)
+{
+    RTCPUID idCpu;
+
+    RTCpuSetEmpty(pSet);
+    idCpu = RTMpGetMaxCpuId();
+    do
+    {
+        if (RTMpIsCpuPossible(idCpu))
+            RTCpuSetAdd(pSet, idCpu);
+    } while (idCpu-- > 0);
+    return pSet;
+}
+RT_EXPORT_SYMBOL(RTMpGetSet);
+
+
+RTDECL(RTCPUID) RTMpGetCount(void)
+{
+#ifdef CONFIG_SMP
+# if defined(CONFIG_HOTPLUG_CPU) /* introduced & uses cpu_present */
+    return num_present_cpus();
+# elif defined(num_possible_cpus)
+    return num_possible_cpus();
+# elif LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0)
+    return smp_num_cpus;
+# else
+    RTCPUSET Set;
+    RTMpGetSet(&Set);
+    return RTCpuSetCount(&Set);
+# endif
+#else
+    return 1;
+#endif
+}
+RT_EXPORT_SYMBOL(RTMpGetCount);
+
+
+RTDECL(bool) RTMpIsCpuOnline(RTCPUID idCpu)
+{
+#ifdef CONFIG_SMP
+    if (RT_UNLIKELY(idCpu >= NR_CPUS))
+        return false;
+# ifdef cpu_online
+    return cpu_online(idCpu);
+# else /* 2.4: */
+    return cpu_online_map & RT_BIT_64(idCpu);
+# endif
+#else
+    return idCpu == RTMpCpuId();
+#endif
+}
+RT_EXPORT_SYMBOL(RTMpIsCpuOnline);
+
+
+RTDECL(PRTCPUSET) RTMpGetOnlineSet(PRTCPUSET pSet)
+{
+#ifdef CONFIG_SMP
+    RTCPUID idCpu;
+
+    RTCpuSetEmpty(pSet);
+    idCpu = RTMpGetMaxCpuId();
+    do
+    {
+        if (RTMpIsCpuOnline(idCpu))
+            RTCpuSetAdd(pSet, idCpu);
+    } while (idCpu-- > 0);
+#else
+    RTCpuSetEmpty(pSet);
+    RTCpuSetAdd(pSet, RTMpCpuId());
+#endif
+    return pSet;
+}
+RT_EXPORT_SYMBOL(RTMpGetOnlineSet);
+
+
+RTDECL(RTCPUID) RTMpGetOnlineCount(void)
+{
+#ifdef CONFIG_SMP
+# if defined(num_online_cpus)
+    return num_online_cpus();
+# else
+    RTCPUSET Set;
+    RTMpGetOnlineSet(&Set);
+    return RTCpuSetCount(&Set);
+# endif
+#else
+    return 1;
+#endif
+}
+RT_EXPORT_SYMBOL(RTMpGetOnlineCount);
+
+
+RTDECL(bool) RTMpIsCpuWorkPending(void)
+{
+    /** @todo (not used on non-Windows platforms yet). */
+    return false;
+}
+RT_EXPORT_SYMBOL(RTMpIsCpuWorkPending);
+
+
+/**
+ * Wrapper between the native linux per-cpu callbacks and PFNRTWORKER.
+ *
+ * @param   pvInfo      Pointer to the RTMPARGS package.
+ */
+static void rtmpLinuxWrapper(void *pvInfo)
+{
+    PRTMPARGS pArgs = (PRTMPARGS)pvInfo;
+    ASMAtomicIncU32(&pArgs->cHits);
+    pArgs->pfnWorker(RTMpCpuId(), pArgs->pvUser1, pArgs->pvUser2);
+}
+
+
+/**
+ * Wrapper between the native linux per-cpu callbacks and PFNRTWORKER, does hit
+ * increment after calling the worker.
+ *
+ * @param   pvInfo      Pointer to the RTMPARGS package.
+ */
+static void rtmpLinuxWrapperPostInc(void *pvInfo)
+{
+    PRTMPARGS pArgs = (PRTMPARGS)pvInfo;
+    pArgs->pfnWorker(RTMpCpuId(), pArgs->pvUser1, pArgs->pvUser2);
+    ASMAtomicIncU32(&pArgs->cHits);
+}
+
+
+/**
+ * Wrapper between the native linux all-cpu callbacks and PFNRTWORKER.
+ *
+ * @param   pvInfo      Pointer to the RTMPARGS package.
+ */
+static void rtmpLinuxAllWrapper(void *pvInfo)
+{
+    PRTMPARGS  pArgs      = (PRTMPARGS)pvInfo;
+    PRTCPUSET  pWorkerSet = pArgs->pWorkerSet;
+    RTCPUID    idCpu      = RTMpCpuId();
+    Assert(!RTThreadPreemptIsEnabled(NIL_RTTHREAD));
+
+    if (RTCpuSetIsMember(pWorkerSet, idCpu))
+    {
+        pArgs->pfnWorker(idCpu, pArgs->pvUser1, pArgs->pvUser2);
+        RTCpuSetDel(pWorkerSet, idCpu);
+    }
+}
+
+
+RTDECL(int) RTMpOnAll(PFNRTMPWORKER pfnWorker, void *pvUser1, void *pvUser2)
+{
+    IPRT_LINUX_SAVE_EFL_AC();
+    int rc;
+    RTMPARGS Args;
+    RTCPUSET OnlineSet;
+    RTCPUID  idCpu;
+    uint32_t cLoops;
+
+    RTTHREADPREEMPTSTATE PreemptState = RTTHREADPREEMPTSTATE_INITIALIZER;
+
+    Args.pfnWorker  = pfnWorker;
+    Args.pvUser1    = pvUser1;
+    Args.pvUser2    = pvUser2;
+    Args.idCpu      = NIL_RTCPUID;
+    Args.cHits      = 0;
+
+    RTThreadPreemptDisable(&PreemptState);
+    RTMpGetOnlineSet(&OnlineSet);
+    Args.pWorkerSet = &OnlineSet;
+    idCpu = RTMpCpuId();
+
+    if (RTCpuSetCount(&OnlineSet) > 1)
+    {
+        /* Fire the function on all other CPUs without waiting for completion. */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)
+        rc = smp_call_function(rtmpLinuxAllWrapper, &Args, 0 /* wait */);
+#else
+        rc = smp_call_function(rtmpLinuxAllWrapper, &Args, 0 /* retry */, 0 /* wait */);
+#endif
+        Assert(!rc); NOREF(rc);
+    }
+
+    /* Fire the function on this CPU. */
+    Args.pfnWorker(idCpu, Args.pvUser1, Args.pvUser2);
+    RTCpuSetDel(Args.pWorkerSet, idCpu);
+
+    /* Wait for all of them finish. */
+    cLoops = 64000;
+    while (!RTCpuSetIsEmpty(Args.pWorkerSet))
+    {
+        /* Periodically check if any CPU in the wait set has gone offline, if so update the wait set. */
+        if (!cLoops--)
+        {
+            RTCPUSET OnlineSetNow;
+            RTMpGetOnlineSet(&OnlineSetNow);
+            RTCpuSetAnd(Args.pWorkerSet, &OnlineSetNow);
+
+            cLoops = 64000;
+        }
+
+        ASMNopPause();
+    }
+
+    RTThreadPreemptRestore(&PreemptState);
+    IPRT_LINUX_RESTORE_EFL_AC();
+    return VINF_SUCCESS;
+}
+RT_EXPORT_SYMBOL(RTMpOnAll);
+
+
+RTDECL(int) RTMpOnOthers(PFNRTMPWORKER pfnWorker, void *pvUser1, void *pvUser2)
+{
+    IPRT_LINUX_SAVE_EFL_AC();
+    int rc;
+    RTMPARGS Args;
+
+    RTTHREADPREEMPTSTATE PreemptState = RTTHREADPREEMPTSTATE_INITIALIZER;
+    Args.pfnWorker = pfnWorker;
+    Args.pvUser1 = pvUser1;
+    Args.pvUser2 = pvUser2;
+    Args.idCpu = NIL_RTCPUID;
+    Args.cHits = 0;
+
+    RTThreadPreemptDisable(&PreemptState);
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)
+    rc = smp_call_function(rtmpLinuxWrapper, &Args, 1 /* wait */);
+#else /* older kernels */
+    rc = smp_call_function(rtmpLinuxWrapper, &Args, 0 /* retry */, 1 /* wait */);
+#endif /* older kernels */
+    RTThreadPreemptRestore(&PreemptState);
+
+    Assert(rc == 0); NOREF(rc);
+    IPRT_LINUX_RESTORE_EFL_AC();
+    return VINF_SUCCESS;
+}
+RT_EXPORT_SYMBOL(RTMpOnOthers);
+
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 27)
+/**
+ * Wrapper between the native linux per-cpu callbacks and PFNRTWORKER
+ * employed by RTMpOnPair on older kernels that lacks smp_call_function_many.
+ *
+ * @param   pvInfo      Pointer to the RTMPARGS package.
+ */
+static void rtMpLinuxOnPairWrapper(void *pvInfo)
+{
+    PRTMPARGS pArgs = (PRTMPARGS)pvInfo;
+    RTCPUID   idCpu = RTMpCpuId();
+
+    if (   idCpu == pArgs->idCpu
+        || idCpu == pArgs->idCpu2)
+    {
+        pArgs->pfnWorker(idCpu, pArgs->pvUser1, pArgs->pvUser2);
+        ASMAtomicIncU32(&pArgs->cHits);
+    }
+}
+#endif
+
+
+RTDECL(int) RTMpOnPair(RTCPUID idCpu1, RTCPUID idCpu2, uint32_t fFlags, PFNRTMPWORKER pfnWorker, void *pvUser1, void *pvUser2)
+{
+    IPRT_LINUX_SAVE_EFL_AC();
+    int rc;
+    RTTHREADPREEMPTSTATE PreemptState = RTTHREADPREEMPTSTATE_INITIALIZER;
+
+    AssertReturn(idCpu1 != idCpu2, VERR_INVALID_PARAMETER);
+    AssertReturn(!(fFlags & RTMPON_F_VALID_MASK), VERR_INVALID_FLAGS);
+
+    /*
+     * Check that both CPUs are online before doing the broadcast call.
+     */
+    RTThreadPreemptDisable(&PreemptState);
+    if (   RTMpIsCpuOnline(idCpu1)
+        && RTMpIsCpuOnline(idCpu2))
+    {
+        /*
+         * Use the smp_call_function variant taking a cpu mask where available,
+         * falling back on broadcast with filter.  Slight snag if one of the
+         * CPUs is the one we're running on, we must do the call and the post
+         * call wait ourselves.
+         */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)
+        cpumask_t   DstCpuMask;
+#endif
+        RTCPUID     idCpuSelf = RTMpCpuId();
+        bool const  fCallSelf = idCpuSelf == idCpu1 || idCpuSelf == idCpu2;
+        RTMPARGS    Args;
+        Args.pfnWorker = pfnWorker;
+        Args.pvUser1 = pvUser1;
+        Args.pvUser2 = pvUser2;
+        Args.idCpu   = idCpu1;
+        Args.idCpu2  = idCpu2;
+        Args.cHits   = 0;
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28)
+        cpumask_clear(&DstCpuMask);
+        cpumask_set_cpu(idCpu1, &DstCpuMask);
+        cpumask_set_cpu(idCpu2, &DstCpuMask);
+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)
+        cpus_clear(DstCpuMask);
+        cpu_set(idCpu1, DstCpuMask);
+        cpu_set(idCpu2, DstCpuMask);
+#endif
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29)
+        smp_call_function_many(&DstCpuMask, rtmpLinuxWrapperPostInc, &Args, !fCallSelf /* wait */);
+        rc = 0;
+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28)
+        rc = smp_call_function_many(&DstCpuMask, rtmpLinuxWrapperPostInc, &Args, !fCallSelf /* wait */);
+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)
+        rc = smp_call_function_mask(DstCpuMask, rtmpLinuxWrapperPostInc, &Args, !fCallSelf /* wait */);
+#else /* older kernels */
+        rc = smp_call_function(rtMpLinuxOnPairWrapper, &Args, 0 /* retry */, !fCallSelf /* wait */);
+#endif /* older kernels */
+        Assert(rc == 0);
+
+        /* Call ourselves if necessary and wait for the other party to be done. */
+        if (fCallSelf)
+        {
+            uint32_t cLoops = 0;
+            rtmpLinuxWrapper(&Args);
+            while (ASMAtomicReadU32(&Args.cHits) < 2)
+            {
+                if ((cLoops & 0x1ff) == 0 && !RTMpIsCpuOnline(idCpuSelf == idCpu1 ? idCpu2 : idCpu1))
+                    break;
+                cLoops++;
+                ASMNopPause();
+            }
+        }
+
+        Assert(Args.cHits <= 2);
+        if (Args.cHits == 2)
+            rc = VINF_SUCCESS;
+        else if (Args.cHits == 1)
+            rc = VERR_NOT_ALL_CPUS_SHOWED;
+        else if (Args.cHits == 0)
+            rc = VERR_CPU_OFFLINE;
+        else
+            rc = VERR_CPU_IPE_1;
+    }
+    /*
+     * A CPU must be present to be considered just offline.
+     */
+    else if (   RTMpIsCpuPresent(idCpu1)
+             && RTMpIsCpuPresent(idCpu2))
+        rc = VERR_CPU_OFFLINE;
+    else
+        rc = VERR_CPU_NOT_FOUND;
+    RTThreadPreemptRestore(&PreemptState);;
+    IPRT_LINUX_RESTORE_EFL_AC();
+    return rc;
+}
+RT_EXPORT_SYMBOL(RTMpOnPair);
+
+
+RTDECL(bool) RTMpOnPairIsConcurrentExecSupported(void)
+{
+    return true;
+}
+RT_EXPORT_SYMBOL(RTMpOnPairIsConcurrentExecSupported);
+
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19)
+/**
+ * Wrapper between the native linux per-cpu callbacks and PFNRTWORKER
+ * employed by RTMpOnSpecific on older kernels that lacks smp_call_function_single.
+ *
+ * @param   pvInfo      Pointer to the RTMPARGS package.
+ */
+static void rtmpOnSpecificLinuxWrapper(void *pvInfo)
+{
+    PRTMPARGS pArgs = (PRTMPARGS)pvInfo;
+    RTCPUID idCpu = RTMpCpuId();
+
+    if (idCpu == pArgs->idCpu)
+    {
+        pArgs->pfnWorker(idCpu, pArgs->pvUser1, pArgs->pvUser2);
+        ASMAtomicIncU32(&pArgs->cHits);
+    }
+}
+#endif
+
+
+RTDECL(int) RTMpOnSpecific(RTCPUID idCpu, PFNRTMPWORKER pfnWorker, void *pvUser1, void *pvUser2)
+{
+    IPRT_LINUX_SAVE_EFL_AC();
+    int rc;
+    RTMPARGS Args;
+
+    RTTHREADPREEMPTSTATE PreemptState = RTTHREADPREEMPTSTATE_INITIALIZER;
+    Args.pfnWorker = pfnWorker;
+    Args.pvUser1 = pvUser1;
+    Args.pvUser2 = pvUser2;
+    Args.idCpu = idCpu;
+    Args.cHits = 0;
+
+    if (!RTMpIsCpuPossible(idCpu))
+        return VERR_CPU_NOT_FOUND;
+
+    RTThreadPreemptDisable(&PreemptState);
+    if (idCpu != RTMpCpuId())
+    {
+        if (RTMpIsCpuOnline(idCpu))
+        {
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)
+            rc = smp_call_function_single(idCpu, rtmpLinuxWrapper, &Args, 1 /* wait */);
+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
+            rc = smp_call_function_single(idCpu, rtmpLinuxWrapper, &Args, 0 /* retry */, 1 /* wait */);
+#else /* older kernels */
+            rc = smp_call_function(rtmpOnSpecificLinuxWrapper, &Args, 0 /* retry */, 1 /* wait */);
+#endif /* older kernels */
+            Assert(rc == 0);
+            rc = Args.cHits ? VINF_SUCCESS : VERR_CPU_OFFLINE;
+        }
+        else
+            rc = VERR_CPU_OFFLINE;
+    }
+    else
+    {
+        rtmpLinuxWrapper(&Args);
+        rc = VINF_SUCCESS;
+    }
+    RTThreadPreemptRestore(&PreemptState);;
+
+    NOREF(rc);
+    IPRT_LINUX_RESTORE_EFL_AC();
+    return rc;
+}
+RT_EXPORT_SYMBOL(RTMpOnSpecific);
+
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
+/**
+ * Dummy callback used by RTMpPokeCpu.
+ *
+ * @param   pvInfo      Ignored.
+ */
+static void rtmpLinuxPokeCpuCallback(void *pvInfo)
+{
+    NOREF(pvInfo);
+}
+#endif
+
+
+RTDECL(int) RTMpPokeCpu(RTCPUID idCpu)
+{
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
+    int rc;
+    IPRT_LINUX_SAVE_EFL_AC();
+
+    if (!RTMpIsCpuPossible(idCpu))
+        return VERR_CPU_NOT_FOUND;
+    if (!RTMpIsCpuOnline(idCpu))
+        return VERR_CPU_OFFLINE;
+
+# if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)
+    rc = smp_call_function_single(idCpu, rtmpLinuxPokeCpuCallback, NULL, 0 /* wait */);
+# elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
+    rc = smp_call_function_single(idCpu, rtmpLinuxPokeCpuCallback, NULL, 0 /* retry */, 0 /* wait */);
+# else  /* older kernels */
+#  error oops
+# endif /* older kernels */
+    NOREF(rc);
+    Assert(rc == 0);
+    IPRT_LINUX_RESTORE_EFL_AC();
+    return VINF_SUCCESS;
+
+#else  /* older kernels */
+    /* no unicast here? */
+    return VERR_NOT_SUPPORTED;
+#endif /* older kernels */
+}
+RT_EXPORT_SYMBOL(RTMpPokeCpu);
+
+
+RTDECL(bool) RTMpOnAllIsConcurrentSafe(void)
+{
+    return true;
+}
+RT_EXPORT_SYMBOL(RTMpOnAllIsConcurrentSafe);
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/r0drv/linux/mpnotification-r0drv-linux.c
@@ -0,0 +1,209 @@
+/* $Id: mpnotification-r0drv-linux.c $ */
+/** @file
+ * IPRT - Multiprocessor Event Notifications, Ring-0 Driver, Linux.
+ */
+
+/*
+ * Copyright (C) 2008-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+
+/*********************************************************************************************************************************
+*   Header Files                                                                                                                 *
+*********************************************************************************************************************************/
+#include "the-linux-kernel.h"
+#include "internal/iprt.h"
+
+#include <iprt/asm-amd64-x86.h>
+#include <iprt/err.h>
+#include <iprt/cpuset.h>
+#include <iprt/thread.h>
+#include "r0drv/mp-r0drv.h"
+
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 71) && defined(CONFIG_SMP)
+
+
+/*********************************************************************************************************************************
+*   Internal Functions                                                                                                           *
+*********************************************************************************************************************************/
+static int rtMpNotificationLinuxCallback(struct notifier_block *pNotifierBlock, unsigned long ulNativeEvent, void *pvCpu);
+
+
+/*********************************************************************************************************************************
+*   Global Variables                                                                                                             *
+*********************************************************************************************************************************/
+/**
+ * The notifier block we use for registering the callback.
+ */
+static struct notifier_block g_NotifierBlock =
+{
+    .notifier_call = rtMpNotificationLinuxCallback,
+    .next = NULL,
+    .priority = 0
+};
+
+# ifdef CPU_DOWN_FAILED
+/**
+ * The set of CPUs we've seen going offline recently.
+ */
+static RTCPUSET g_MpPendingOfflineSet;
+# endif
+
+
+/**
+ * The native callback.
+ *
+ * @returns NOTIFY_DONE.
+ * @param   pNotifierBlock  Pointer to g_NotifierBlock.
+ * @param   ulNativeEvent   The native event.
+ * @param   pvCpu           The cpu id cast into a pointer value.
+ *
+ * @remarks This can fire with preemption enabled and on any CPU.
+ */
+static int rtMpNotificationLinuxCallback(struct notifier_block *pNotifierBlock, unsigned long ulNativeEvent, void *pvCpu)
+{
+    bool fProcessEvent = false;
+    RTCPUID idCpu      = (uintptr_t)pvCpu;
+    NOREF(pNotifierBlock);
+
+    /*
+     * Note that redhat/CentOS ported _some_ of the FROZEN macros
+     * back to their 2.6.18-92.1.10.el5 kernel but actually don't
+     * use them. Thus we have to test for both CPU_TASKS_FROZEN and
+     * the individual event variants.
+     */
+    switch (ulNativeEvent)
+    {
+        /*
+         * Pick up online events or failures to go offline.
+         * Ignore failure events for CPUs we didn't see go offline.
+         */
+# ifdef CPU_DOWN_FAILED
+        case CPU_DOWN_FAILED:
+#  if defined(CPU_TASKS_FROZEN) && defined(CPU_DOWN_FAILED_FROZEN)
+        case CPU_DOWN_FAILED_FROZEN:
+#  endif
+            if (!RTCpuSetIsMember(&g_MpPendingOfflineSet, idCpu))
+                break;      /* fProcessEvents = false */
+        /* fall thru */
+# endif
+        case CPU_ONLINE:
+# if defined(CPU_TASKS_FROZEN) && defined(CPU_ONLINE_FROZEN)
+        case CPU_ONLINE_FROZEN:
+# endif
+# ifdef CPU_DOWN_FAILED
+            RTCpuSetDel(&g_MpPendingOfflineSet, idCpu);
+# endif
+            fProcessEvent = true;
+            break;
+
+        /*
+         * Pick the earliest possible offline event.
+         * The only important thing here is that we get the event and that
+         * it's exactly one.
+         */
+# ifdef CPU_DOWN_PREPARE
+        case CPU_DOWN_PREPARE:
+#  if defined(CPU_TASKS_FROZEN) && defined(CPU_DOWN_PREPARE_FROZEN)
+        case CPU_DOWN_PREPARE_FROZEN:
+#  endif
+            fProcessEvent = true;
+# else
+        case CPU_DEAD:
+#  if defined(CPU_TASKS_FROZEN) && defined(CPU_DEAD_FROZEN)
+        case CPU_DEAD_FROZEN:
+#  endif
+            /* Don't process CPU_DEAD notifications. */
+# endif
+# ifdef CPU_DOWN_FAILED
+            RTCpuSetAdd(&g_MpPendingOfflineSet, idCpu);
+# endif
+            break;
+    }
+
+    if (!fProcessEvent)
+        return NOTIFY_DONE;
+
+    switch (ulNativeEvent)
+    {
+# ifdef CPU_DOWN_FAILED
+        case CPU_DOWN_FAILED:
+#  if defined(CPU_TASKS_FROZEN) && defined(CPU_DOWN_FAILED_FROZEN)
+        case CPU_DOWN_FAILED_FROZEN:
+#  endif
+# endif
+        case CPU_ONLINE:
+# if defined(CPU_TASKS_FROZEN) && defined(CPU_ONLINE_FROZEN)
+        case CPU_ONLINE_FROZEN:
+# endif
+            rtMpNotificationDoCallbacks(RTMPEVENT_ONLINE, idCpu);
+            break;
+
+# ifdef CPU_DOWN_PREPARE
+        case CPU_DOWN_PREPARE:
+#  if defined(CPU_TASKS_FROZEN) && defined(CPU_DOWN_PREPARE_FROZEN)
+        case CPU_DOWN_PREPARE_FROZEN:
+#  endif
+            rtMpNotificationDoCallbacks(RTMPEVENT_OFFLINE, idCpu);
+            break;
+# endif
+    }
+
+    return NOTIFY_DONE;
+}
+
+
+DECLHIDDEN(int) rtR0MpNotificationNativeInit(void)
+{
+    int rc;
+    IPRT_LINUX_SAVE_EFL_AC();
+
+# ifdef CPU_DOWN_FAILED
+    RTCpuSetEmpty(&g_MpPendingOfflineSet);
+# endif
+
+    rc = register_cpu_notifier(&g_NotifierBlock);
+    IPRT_LINUX_RESTORE_EFL_AC();
+    AssertMsgReturn(!rc, ("%d\n", rc), RTErrConvertFromErrno(rc));
+    return VINF_SUCCESS;
+}
+
+
+DECLHIDDEN(void) rtR0MpNotificationNativeTerm(void)
+{
+    IPRT_LINUX_SAVE_EFL_AC();
+    unregister_cpu_notifier(&g_NotifierBlock);
+    IPRT_LINUX_RESTORE_EFL_AC();
+}
+
+#else   /* Not supported / Not needed */
+
+DECLHIDDEN(int) rtR0MpNotificationNativeInit(void)
+{
+    return VINF_SUCCESS;
+}
+
+DECLHIDDEN(void) rtR0MpNotificationNativeTerm(void)
+{
+}
+
+#endif  /* Not supported / Not needed */
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/r0drv/linux/process-r0drv-linux.c
@@ -0,0 +1,49 @@
+/* $Id: process-r0drv-linux.c $ */
+/** @file
+ * IPRT - Process, Ring-0 Driver, Linux.
+ */
+
+/*
+ * Copyright (C) 2006-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+
+/*********************************************************************************************************************************
+*   Header Files                                                                                                                 *
+*********************************************************************************************************************************/
+#include "the-linux-kernel.h"
+#include "internal/iprt.h"
+
+#include <iprt/process.h>
+
+
+RTDECL(RTPROCESS) RTProcSelf(void)
+{
+    return (RTPROCESS)current->tgid;
+}
+RT_EXPORT_SYMBOL(RTProcSelf);
+
+
+RTR0DECL(RTR0PROCESS) RTR0ProcHandleSelf(void)
+{
+    return (RTR0PROCESS)current->tgid;
+}
+RT_EXPORT_SYMBOL(RTR0ProcHandleSelf);
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/r0drv/linux/semevent-r0drv-linux.c
@@ -0,0 +1,277 @@
+/* $Id: semevent-r0drv-linux.c $ */
+/** @file
+ * IPRT - Single Release Event Semaphores, Ring-0 Driver, Linux.
+ */
+
+/*
+ * Copyright (C) 2006-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+
+/*********************************************************************************************************************************
+*   Header Files                                                                                                                 *
+*********************************************************************************************************************************/
+#define RTSEMEVENT_WITHOUT_REMAPPING
+#include "the-linux-kernel.h"
+#include "internal/iprt.h"
+#include <iprt/semaphore.h>
+
+#include <iprt/asm.h>
+#include <iprt/assert.h>
+#include <iprt/err.h>
+#include <iprt/lockvalidator.h>
+#include <iprt/mem.h>
+
+#include "waitqueue-r0drv-linux.h"
+#include "internal/magics.h"
+
+
+/*********************************************************************************************************************************
+*   Structures and Typedefs                                                                                                      *
+*********************************************************************************************************************************/
+/**
+ * Linux event semaphore.
+ */
+typedef struct RTSEMEVENTINTERNAL
+{
+    /** Magic value (RTSEMEVENT_MAGIC). */
+    uint32_t volatile   u32Magic;
+    /** The object status - !0 when signaled and 0 when reset. */
+    uint32_t volatile   fState;
+    /** Reference counter. */
+    uint32_t volatile   cRefs;
+    /** The wait queue. */
+    wait_queue_head_t   Head;
+} RTSEMEVENTINTERNAL, *PRTSEMEVENTINTERNAL;
+
+
+
+RTDECL(int)  RTSemEventCreate(PRTSEMEVENT phEventSem)
+{
+    return RTSemEventCreateEx(phEventSem, 0 /*fFlags*/, NIL_RTLOCKVALCLASS, NULL);
+}
+
+
+RTDECL(int)  RTSemEventCreateEx(PRTSEMEVENT phEventSem, uint32_t fFlags, RTLOCKVALCLASS hClass, const char *pszNameFmt, ...)
+{
+    PRTSEMEVENTINTERNAL pThis;
+    IPRT_LINUX_SAVE_EFL_AC();
+
+    AssertReturn(!(fFlags & ~(RTSEMEVENT_FLAGS_NO_LOCK_VAL | RTSEMEVENT_FLAGS_BOOTSTRAP_HACK)), VERR_INVALID_PARAMETER);
+    Assert(!(fFlags & RTSEMEVENT_FLAGS_BOOTSTRAP_HACK) || (fFlags & RTSEMEVENT_FLAGS_NO_LOCK_VAL));
+
+    pThis = (PRTSEMEVENTINTERNAL)RTMemAlloc(sizeof(*pThis));
+    if (!pThis)
+        return VERR_NO_MEMORY;
+
+    pThis->u32Magic = RTSEMEVENT_MAGIC;
+    pThis->fState   = 0;
+    pThis->cRefs    = 1;
+    init_waitqueue_head(&pThis->Head);
+
+    *phEventSem = pThis;
+    IPRT_LINUX_RESTORE_EFL_AC();
+    return VINF_SUCCESS;
+}
+RT_EXPORT_SYMBOL(RTSemEventCreate);
+
+
+/**
+ * Retains a reference to the event semaphore.
+ *
+ * @param   pThis       The event semaphore.
+ */
+DECLINLINE(void) rtR0SemEventLnxRetain(PRTSEMEVENTINTERNAL pThis)
+{
+    uint32_t cRefs = ASMAtomicIncU32(&pThis->cRefs);
+    Assert(cRefs < 100000); NOREF(cRefs);
+}
+
+
+/**
+ * Releases a reference to the event semaphore.
+ *
+ * @param   pThis       The event semaphore.
+ */
+DECLINLINE(void) rtR0SemEventLnxRelease(PRTSEMEVENTINTERNAL pThis)
+{
+    if (RT_UNLIKELY(ASMAtomicDecU32(&pThis->cRefs) == 0))
+        RTMemFree(pThis);
+}
+
+
+RTDECL(int)  RTSemEventDestroy(RTSEMEVENT hEventSem)
+{
+    IPRT_LINUX_SAVE_EFL_AC();
+
+    /*
+     * Validate input.
+     */
+    PRTSEMEVENTINTERNAL pThis = hEventSem;
+    if (pThis == NIL_RTSEMEVENT)
+        return VINF_SUCCESS;
+    AssertMsgReturn(pThis->u32Magic == RTSEMEVENT_MAGIC, ("pThis->u32Magic=%RX32 pThis=%p\n", pThis->u32Magic, pThis), VERR_INVALID_HANDLE);
+    Assert(pThis->cRefs > 0);
+
+    /*
+     * Invalidate it and signal the object just in case.
+     */
+    ASMAtomicWriteU32(&pThis->u32Magic, ~RTSEMEVENT_MAGIC);
+    ASMAtomicWriteU32(&pThis->fState, 0);
+    Assert(!waitqueue_active(&pThis->Head));
+    wake_up_all(&pThis->Head);
+    rtR0SemEventLnxRelease(pThis);
+
+    IPRT_LINUX_RESTORE_EFL_AC();
+    return VINF_SUCCESS;
+}
+RT_EXPORT_SYMBOL(RTSemEventDestroy);
+
+
+RTDECL(int)  RTSemEventSignal(RTSEMEVENT hEventSem)
+{
+    IPRT_LINUX_SAVE_EFL_AC();
+
+    /*
+     * Validate input.
+     */
+    PRTSEMEVENTINTERNAL pThis = (PRTSEMEVENTINTERNAL)hEventSem;
+    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
+    AssertMsgReturn(pThis->u32Magic == RTSEMEVENT_MAGIC, ("pThis->u32Magic=%RX32 pThis=%p\n", pThis->u32Magic, pThis), VERR_INVALID_HANDLE);
+    rtR0SemEventLnxRetain(pThis);
+
+    /*
+     * Signal the event object.
+     */
+    ASMAtomicWriteU32(&pThis->fState, 1);
+    wake_up(&pThis->Head);
+
+    rtR0SemEventLnxRelease(pThis);
+    IPRT_LINUX_RESTORE_EFL_AC();
+    return VINF_SUCCESS;
+}
+RT_EXPORT_SYMBOL(RTSemEventSignal);
+
+
+/**
+ * Worker for RTSemEventWaitEx and RTSemEventWaitExDebug.
+ *
+ * @returns VBox status code.
+ * @param   pThis           The event semaphore.
+ * @param   fFlags          See RTSemEventWaitEx.
+ * @param   uTimeout        See RTSemEventWaitEx.
+ * @param   pSrcPos         The source code position of the wait.
+ */
+static int rtR0SemEventLnxWait(PRTSEMEVENTINTERNAL pThis, uint32_t fFlags, uint64_t uTimeout,
+                               PCRTLOCKVALSRCPOS pSrcPos)
+{
+    int rc;
+
+    /*
+     * Validate the input.
+     */
+    AssertPtrReturn(pThis, VERR_INVALID_PARAMETER);
+    AssertMsgReturn(pThis->u32Magic == RTSEMEVENT_MAGIC, ("%p u32Magic=%RX32\n", pThis, pThis->u32Magic), VERR_INVALID_PARAMETER);
+    AssertReturn(RTSEMWAIT_FLAGS_ARE_VALID(fFlags), VERR_INVALID_PARAMETER);
+    rtR0SemEventLnxRetain(pThis);
+
+    /*
+     * Try grab the event without setting up the wait.
+     */
+    if (   1 /** @todo check if there are someone waiting already - waitqueue_active, but then what do we do below? */
+        && ASMAtomicCmpXchgU32(&pThis->fState, 0, 1))
+        rc = VINF_SUCCESS;
+    else
+    {
+        /*
+         * We have to wait.
+         */
+        IPRT_LINUX_SAVE_EFL_AC();
+        RTR0SEMLNXWAIT Wait;
+        rc = rtR0SemLnxWaitInit(&Wait, fFlags, uTimeout, &pThis->Head);
+        if (RT_SUCCESS(rc))
+        {
+            IPRT_DEBUG_SEMS_STATE(pThis, 'E');
+            for (;;)
+            {
+                /* The destruction test. */
+                if (RT_UNLIKELY(pThis->u32Magic != RTSEMEVENT_MAGIC))
+                    rc = VERR_SEM_DESTROYED;
+                else
+                {
+                    rtR0SemLnxWaitPrepare(&Wait);
+
+                    /* Check the exit conditions. */
+                    if (RT_UNLIKELY(pThis->u32Magic != RTSEMEVENT_MAGIC))
+                        rc = VERR_SEM_DESTROYED;
+                    else if (ASMAtomicCmpXchgU32(&pThis->fState, 0, 1))
+                        rc = VINF_SUCCESS;
+                    else if (rtR0SemLnxWaitHasTimedOut(&Wait))
+                        rc = VERR_TIMEOUT;
+                    else if (rtR0SemLnxWaitWasInterrupted(&Wait))
+                        rc = VERR_INTERRUPTED;
+                    else
+                    {
+                        /* Do the wait and then recheck the conditions. */
+                        rtR0SemLnxWaitDoIt(&Wait);
+                        continue;
+                    }
+                }
+                break;
+            }
+
+            rtR0SemLnxWaitDelete(&Wait);
+            IPRT_DEBUG_SEMS_STATE_RC(pThis, 'E', rc);
+        }
+        IPRT_LINUX_RESTORE_EFL_AC();
+    }
+
+    rtR0SemEventLnxRelease(pThis);
+    return rc;
+}
+
+
+RTDECL(int)  RTSemEventWaitEx(RTSEMEVENT hEventSem, uint32_t fFlags, uint64_t uTimeout)
+{
+#ifndef RTSEMEVENT_STRICT
+    return rtR0SemEventLnxWait(hEventSem, fFlags, uTimeout, NULL);
+#else
+    RTLOCKVALSRCPOS SrcPos = RTLOCKVALSRCPOS_INIT_NORMAL_API();
+    return rtR0SemEventLnxWait(hEventSem, fFlags, uTimeout, &SrcPos);
+#endif
+}
+RT_EXPORT_SYMBOL(RTSemEventWaitEx);
+
+
+RTDECL(int)  RTSemEventWaitExDebug(RTSEMEVENT hEventSem, uint32_t fFlags, uint64_t uTimeout,
+                                   RTHCUINTPTR uId, RT_SRC_POS_DECL)
+{
+    RTLOCKVALSRCPOS SrcPos = RTLOCKVALSRCPOS_INIT_DEBUG_API();
+    return rtR0SemEventLnxWait(hEventSem, fFlags, uTimeout, &SrcPos);
+}
+RT_EXPORT_SYMBOL(RTSemEventWaitExDebug);
+
+
+RTDECL(uint32_t) RTSemEventGetResolution(void)
+{
+    return rtR0SemLnxWaitGetResolution();
+}
+RT_EXPORT_SYMBOL(RTSemEventGetResolution);
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/r0drv/linux/semeventmulti-r0drv-linux.c
@@ -0,0 +1,342 @@
+/* $Id: semeventmulti-r0drv-linux.c $ */
+/** @file
+ * IPRT - Multiple Release Event Semaphores, Ring-0 Driver, Linux.
+ */
+
+/*
+ * Copyright (C) 2006-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+
+/*********************************************************************************************************************************
+*   Header Files                                                                                                                 *
+*********************************************************************************************************************************/
+#define RTSEMEVENTMULTI_WITHOUT_REMAPPING
+#include "the-linux-kernel.h"
+#include "internal/iprt.h"
+#include <iprt/semaphore.h>
+
+#include <iprt/assert.h>
+#include <iprt/asm.h>
+#include <iprt/err.h>
+#include <iprt/mem.h>
+#include <iprt/lockvalidator.h>
+
+#include "waitqueue-r0drv-linux.h"
+#include "internal/magics.h"
+
+
+/*********************************************************************************************************************************
+*   Defined Constants And Macros                                                                                                 *
+*********************************************************************************************************************************/
+/** @name fStateAndGen values
+ * @{ */
+/** The state bit number. */
+#define RTSEMEVENTMULTILNX_STATE_BIT        0
+/** The state mask. */
+#define RTSEMEVENTMULTILNX_STATE_MASK       RT_BIT_32(RTSEMEVENTMULTILNX_STATE_BIT)
+/** The generation mask. */
+#define RTSEMEVENTMULTILNX_GEN_MASK         ~RTSEMEVENTMULTILNX_STATE_MASK
+/** The generation shift. */
+#define RTSEMEVENTMULTILNX_GEN_SHIFT        1
+/** The initial variable value. */
+#define RTSEMEVENTMULTILNX_STATE_GEN_INIT   UINT32_C(0xfffffffc)
+/** @}  */
+
+
+/*********************************************************************************************************************************
+*   Structures and Typedefs                                                                                                      *
+*********************************************************************************************************************************/
+/**
+ * Linux event semaphore.
+ */
+typedef struct RTSEMEVENTMULTIINTERNAL
+{
+    /** Magic value (RTSEMEVENTMULTI_MAGIC). */
+    uint32_t volatile   u32Magic;
+    /** The object state bit and generation counter.
+     * The generation counter is incremented every time the object is
+     * signalled. */
+    uint32_t volatile   fStateAndGen;
+    /** Reference counter. */
+    uint32_t volatile   cRefs;
+    /** The wait queue. */
+    wait_queue_head_t   Head;
+} RTSEMEVENTMULTIINTERNAL, *PRTSEMEVENTMULTIINTERNAL;
+
+
+
+
+
+RTDECL(int)  RTSemEventMultiCreate(PRTSEMEVENTMULTI phEventMultiSem)
+{
+    return RTSemEventMultiCreateEx(phEventMultiSem, 0 /*fFlags*/, NIL_RTLOCKVALCLASS, NULL);
+}
+
+
+RTDECL(int)  RTSemEventMultiCreateEx(PRTSEMEVENTMULTI phEventMultiSem, uint32_t fFlags, RTLOCKVALCLASS hClass,
+                                     const char *pszNameFmt, ...)
+{
+    PRTSEMEVENTMULTIINTERNAL pThis;
+    IPRT_LINUX_SAVE_EFL_AC();
+
+    AssertReturn(!(fFlags & ~RTSEMEVENTMULTI_FLAGS_NO_LOCK_VAL), VERR_INVALID_PARAMETER);
+    pThis = (PRTSEMEVENTMULTIINTERNAL)RTMemAlloc(sizeof(*pThis));
+    if (pThis)
+    {
+        pThis->u32Magic     = RTSEMEVENTMULTI_MAGIC;
+        pThis->fStateAndGen = RTSEMEVENTMULTILNX_STATE_GEN_INIT;
+        pThis->cRefs        = 1;
+        init_waitqueue_head(&pThis->Head);
+
+        *phEventMultiSem = pThis;
+        IPRT_LINUX_RESTORE_EFL_AC();
+        return VINF_SUCCESS;
+    }
+    IPRT_LINUX_RESTORE_EFL_AC();
+    return VERR_NO_MEMORY;
+}
+RT_EXPORT_SYMBOL(RTSemEventMultiCreate);
+
+
+/**
+ * Retain a reference to the semaphore.
+ *
+ * @param   pThis       The semaphore.
+ */
+DECLINLINE(void) rtR0SemEventMultiLnxRetain(PRTSEMEVENTMULTIINTERNAL pThis)
+{
+    uint32_t cRefs = ASMAtomicIncU32(&pThis->cRefs);
+    NOREF(cRefs);
+    Assert(cRefs && cRefs < 100000);
+}
+
+
+/**
+ * Release a reference, destroy the thing if necessary.
+ *
+ * @param   pThis       The semaphore.
+ */
+DECLINLINE(void) rtR0SemEventMultiLnxRelease(PRTSEMEVENTMULTIINTERNAL pThis)
+{
+    if (RT_UNLIKELY(ASMAtomicDecU32(&pThis->cRefs) == 0))
+    {
+        Assert(pThis->u32Magic != RTSEMEVENTMULTI_MAGIC);
+        RTMemFree(pThis);
+    }
+}
+
+
+RTDECL(int) RTSemEventMultiDestroy(RTSEMEVENTMULTI hEventMultiSem)
+{
+    IPRT_LINUX_SAVE_EFL_AC();
+
+    /*
+     * Validate input.
+     */
+    PRTSEMEVENTMULTIINTERNAL pThis = (PRTSEMEVENTMULTIINTERNAL)hEventMultiSem;
+    if (pThis == NIL_RTSEMEVENTMULTI)
+        return VINF_SUCCESS;
+    AssertPtrReturn(pThis, VERR_INVALID_PARAMETER);
+    AssertMsgReturn(pThis->u32Magic == RTSEMEVENTMULTI_MAGIC, ("%p u32Magic=%RX32\n", pThis, pThis->u32Magic), VERR_INVALID_PARAMETER);
+    Assert(pThis->cRefs > 0);
+
+    /*
+     * Invalidate it and signal the object just in case.
+     */
+    ASMAtomicWriteU32(&pThis->u32Magic, ~RTSEMEVENTMULTI_MAGIC);
+    ASMAtomicAndU32(&pThis->fStateAndGen, RTSEMEVENTMULTILNX_GEN_MASK);
+    Assert(!waitqueue_active(&pThis->Head));
+    wake_up_all(&pThis->Head);
+    rtR0SemEventMultiLnxRelease(pThis);
+
+    IPRT_LINUX_RESTORE_EFL_AC();
+    return VINF_SUCCESS;
+}
+RT_EXPORT_SYMBOL(RTSemEventMultiDestroy);
+
+
+RTDECL(int) RTSemEventMultiSignal(RTSEMEVENTMULTI hEventMultiSem)
+{
+    IPRT_LINUX_SAVE_EFL_AC();
+    uint32_t fNew;
+    uint32_t fOld;
+
+    /*
+     * Validate input.
+     */
+    PRTSEMEVENTMULTIINTERNAL pThis = (PRTSEMEVENTMULTIINTERNAL)hEventMultiSem;
+    if (!pThis)
+        return VERR_INVALID_PARAMETER;
+    AssertPtrReturn(pThis, VERR_INVALID_PARAMETER);
+    AssertMsgReturn(pThis->u32Magic == RTSEMEVENTMULTI_MAGIC, ("%p u32Magic=%RX32\n", pThis, pThis->u32Magic), VERR_INVALID_PARAMETER);
+    rtR0SemEventMultiLnxRetain(pThis);
+
+    /*
+     * Signal the event object.  The cause of the paranoia here is racing to try
+     * deal with racing RTSemEventMultiSignal calls (should probably be
+     * forbidden, but it's relatively easy to handle).
+     */
+    do
+    {
+        fNew = fOld = ASMAtomicUoReadU32(&pThis->fStateAndGen);
+        fNew += 1 << RTSEMEVENTMULTILNX_GEN_SHIFT;
+        fNew |= RTSEMEVENTMULTILNX_STATE_MASK;
+    }
+    while (!ASMAtomicCmpXchgU32(&pThis->fStateAndGen, fNew, fOld));
+
+    wake_up_all(&pThis->Head);
+
+    rtR0SemEventMultiLnxRelease(pThis);
+    IPRT_LINUX_RESTORE_EFL_AC();
+    return VINF_SUCCESS;
+}
+RT_EXPORT_SYMBOL(RTSemEventMultiSignal);
+
+
+RTDECL(int) RTSemEventMultiReset(RTSEMEVENTMULTI hEventMultiSem)
+{
+    /*
+     * Validate input.
+     */
+    PRTSEMEVENTMULTIINTERNAL pThis = (PRTSEMEVENTMULTIINTERNAL)hEventMultiSem;
+    if (!pThis)
+        return VERR_INVALID_PARAMETER;
+    AssertPtrReturn(pThis, VERR_INVALID_PARAMETER);
+    AssertMsgReturn(pThis->u32Magic == RTSEMEVENTMULTI_MAGIC, ("%p u32Magic=%RX32\n", pThis, pThis->u32Magic), VERR_INVALID_PARAMETER);
+    rtR0SemEventMultiLnxRetain(pThis);
+
+    /*
+     * Reset it.
+     */
+    ASMAtomicAndU32(&pThis->fStateAndGen, ~RTSEMEVENTMULTILNX_STATE_MASK);
+
+    rtR0SemEventMultiLnxRelease(pThis);
+    return VINF_SUCCESS;
+}
+RT_EXPORT_SYMBOL(RTSemEventMultiReset);
+
+
+/**
+ * Worker for RTSemEventMultiWaitEx and RTSemEventMultiWaitExDebug.
+ *
+ * @returns VBox status code.
+ * @param   pThis           The event semaphore.
+ * @param   fFlags          See RTSemEventMultiWaitEx.
+ * @param   uTimeout        See RTSemEventMultiWaitEx.
+ * @param   pSrcPos         The source code position of the wait.
+ */
+static int rtR0SemEventMultiLnxWait(PRTSEMEVENTMULTIINTERNAL pThis, uint32_t fFlags, uint64_t uTimeout,
+                                    PCRTLOCKVALSRCPOS pSrcPos)
+{
+    uint32_t    fOrgStateAndGen;
+    int         rc;
+
+    /*
+     * Validate the input.
+     */
+    AssertPtrReturn(pThis, VERR_INVALID_PARAMETER);
+    AssertMsgReturn(pThis->u32Magic == RTSEMEVENTMULTI_MAGIC, ("%p u32Magic=%RX32\n", pThis, pThis->u32Magic), VERR_INVALID_PARAMETER);
+    AssertReturn(RTSEMWAIT_FLAGS_ARE_VALID(fFlags), VERR_INVALID_PARAMETER);
+    rtR0SemEventMultiLnxRetain(pThis);
+
+    /*
+     * Is the event already signalled or do we have to wait?
+     */
+    fOrgStateAndGen = ASMAtomicUoReadU32(&pThis->fStateAndGen);
+    if (fOrgStateAndGen & RTSEMEVENTMULTILNX_STATE_MASK)
+        rc = VINF_SUCCESS;
+    else
+    {
+        /*
+         * We have to wait.
+         */
+        RTR0SEMLNXWAIT Wait;
+        IPRT_LINUX_SAVE_EFL_AC();
+        rc = rtR0SemLnxWaitInit(&Wait, fFlags, uTimeout, &pThis->Head);
+        if (RT_SUCCESS(rc))
+        {
+            IPRT_DEBUG_SEMS_STATE(pThis, 'E');
+            for (;;)
+            {
+                /* The destruction test. */
+                if (RT_UNLIKELY(pThis->u32Magic != RTSEMEVENTMULTI_MAGIC))
+                    rc = VERR_SEM_DESTROYED;
+                else
+                {
+                    rtR0SemLnxWaitPrepare(&Wait);
+
+                    /* Check the exit conditions. */
+                    if (RT_UNLIKELY(pThis->u32Magic != RTSEMEVENTMULTI_MAGIC))
+                        rc = VERR_SEM_DESTROYED;
+                    else if (ASMAtomicUoReadU32(&pThis->fStateAndGen) != fOrgStateAndGen)
+                        rc = VINF_SUCCESS;
+                    else if (rtR0SemLnxWaitHasTimedOut(&Wait))
+                        rc = VERR_TIMEOUT;
+                    else if (rtR0SemLnxWaitWasInterrupted(&Wait))
+                        rc = VERR_INTERRUPTED;
+                    else
+                    {
+                        /* Do the wait and then recheck the conditions. */
+                        rtR0SemLnxWaitDoIt(&Wait);
+                        continue;
+                    }
+                }
+                break;
+            }
+
+            rtR0SemLnxWaitDelete(&Wait);
+            IPRT_DEBUG_SEMS_STATE_RC(pThis, 'E', rc);
+        }
+        IPRT_LINUX_RESTORE_EFL_AC();
+    }
+
+    rtR0SemEventMultiLnxRelease(pThis);
+    return rc;
+}
+
+
+RTDECL(int)  RTSemEventMultiWaitEx(RTSEMEVENTMULTI hEventMultiSem, uint32_t fFlags, uint64_t uTimeout)
+{
+#ifndef RTSEMEVENT_STRICT
+    return rtR0SemEventMultiLnxWait(hEventMultiSem, fFlags, uTimeout, NULL);
+#else
+    RTLOCKVALSRCPOS SrcPos = RTLOCKVALSRCPOS_INIT_NORMAL_API();
+    return rtR0SemEventMultiLnxWait(hEventMultiSem, fFlags, uTimeout, &SrcPos);
+#endif
+}
+RT_EXPORT_SYMBOL(RTSemEventMultiWaitEx);
+
+
+RTDECL(int)  RTSemEventMultiWaitExDebug(RTSEMEVENTMULTI hEventMultiSem, uint32_t fFlags, uint64_t uTimeout,
+                                        RTHCUINTPTR uId, RT_SRC_POS_DECL)
+{
+    RTLOCKVALSRCPOS SrcPos = RTLOCKVALSRCPOS_INIT_DEBUG_API();
+    return rtR0SemEventMultiLnxWait(hEventMultiSem, fFlags, uTimeout, &SrcPos);
+}
+RT_EXPORT_SYMBOL(RTSemEventMultiWaitExDebug);
+
+
+RTDECL(uint32_t) RTSemEventMultiGetResolution(void)
+{
+    return rtR0SemLnxWaitGetResolution();
+}
+RT_EXPORT_SYMBOL(RTSemEventMultiGetResolution);
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/r0drv/linux/semfastmutex-r0drv-linux.c
@@ -0,0 +1,157 @@
+/* $Id: semfastmutex-r0drv-linux.c $ */
+/** @file
+ * IPRT - Fast Mutex Semaphores, Ring-0 Driver, Linux.
+ */
+
+/*
+ * Copyright (C) 2006-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+
+/*********************************************************************************************************************************
+*   Header Files                                                                                                                 *
+*********************************************************************************************************************************/
+#include "the-linux-kernel.h"
+#include "internal/iprt.h"
+#include <iprt/semaphore.h>
+#include <iprt/alloc.h>
+#include <iprt/assert.h>
+#include <iprt/asm.h>
+#include <iprt/err.h>
+#if defined(RT_STRICT) || defined(IPRT_DEBUG_SEMS)
+# include <iprt/thread.h>
+#endif
+
+#include "internal/magics.h"
+
+
+/*********************************************************************************************************************************
+*   Structures and Typedefs                                                                                                      *
+*********************************************************************************************************************************/
+/**
+ * Wrapper for the linux semaphore structure.
+ */
+typedef struct RTSEMFASTMUTEXINTERNAL
+{
+    /** Magic value (RTSEMFASTMUTEX_MAGIC). */
+    uint32_t            u32Magic;
+    /** the linux semaphore. */
+    struct semaphore    Semaphore;
+#if defined(RT_STRICT) || defined(IPRT_DEBUG_SEMS)
+    /** For check. */
+    RTNATIVETHREAD volatile Owner;
+#endif
+} RTSEMFASTMUTEXINTERNAL, *PRTSEMFASTMUTEXINTERNAL;
+
+
+RTDECL(int)  RTSemFastMutexCreate(PRTSEMFASTMUTEX phFastMtx)
+{
+    IPRT_LINUX_SAVE_EFL_AC();
+
+    /*
+     * Allocate.
+     */
+    PRTSEMFASTMUTEXINTERNAL pThis;
+    pThis = (PRTSEMFASTMUTEXINTERNAL)RTMemAlloc(sizeof(*pThis));
+    if (!pThis)
+        return VERR_NO_MEMORY;
+
+    /*
+     * Initialize.
+     */
+    pThis->u32Magic = RTSEMFASTMUTEX_MAGIC;
+    sema_init(&pThis->Semaphore, 1);
+#if defined(RT_STRICT) || defined(IPRT_DEBUG_SEMS)
+    pThis->Owner = NIL_RTNATIVETHREAD;
+#endif
+
+    *phFastMtx = pThis;
+    IPRT_LINUX_RESTORE_EFL_AC();
+    return VINF_SUCCESS;
+}
+RT_EXPORT_SYMBOL(RTSemFastMutexCreate);
+
+
+RTDECL(int)  RTSemFastMutexDestroy(RTSEMFASTMUTEX hFastMtx)
+{
+    /*
+     * Validate.
+     */
+    PRTSEMFASTMUTEXINTERNAL pThis = hFastMtx;
+    if (pThis == NIL_RTSEMFASTMUTEX)
+        return VINF_SUCCESS;
+    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
+    AssertMsgReturn(pThis->u32Magic == RTSEMFASTMUTEX_MAGIC, ("u32Magic=%RX32 pThis=%p\n", pThis->u32Magic, pThis), VERR_INVALID_HANDLE);
+
+    ASMAtomicWriteU32(&pThis->u32Magic, RTSEMFASTMUTEX_MAGIC_DEAD);
+    RTMemFree(pThis);
+    return VINF_SUCCESS;
+}
+RT_EXPORT_SYMBOL(RTSemFastMutexDestroy);
+
+
+RTDECL(int)  RTSemFastMutexRequest(RTSEMFASTMUTEX hFastMtx)
+{
+    IPRT_LINUX_SAVE_EFL_AC();
+
+    /*
+     * Validate.
+     */
+    PRTSEMFASTMUTEXINTERNAL pThis = hFastMtx;
+    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
+    AssertMsgReturn(pThis->u32Magic == RTSEMFASTMUTEX_MAGIC, ("u32Magic=%RX32 pThis=%p\n", pThis->u32Magic, pThis), VERR_INVALID_HANDLE);
+
+    IPRT_DEBUG_SEMS_STATE(pThis, 'd');
+    down(&pThis->Semaphore);
+#if defined(RT_STRICT) || defined(IPRT_DEBUG_SEMS)
+    IPRT_DEBUG_SEMS_STATE(pThis, 'o');
+    AssertRelease(pThis->Owner == NIL_RTNATIVETHREAD);
+    ASMAtomicUoWriteSize(&pThis->Owner, RTThreadNativeSelf());
+#endif
+
+    IPRT_LINUX_RESTORE_EFL_ONLY_AC();
+    return VINF_SUCCESS;
+}
+RT_EXPORT_SYMBOL(RTSemFastMutexRequest);
+
+
+RTDECL(int)  RTSemFastMutexRelease(RTSEMFASTMUTEX hFastMtx)
+{
+    IPRT_LINUX_SAVE_EFL_AC();
+
+    /*
+     * Validate.
+     */
+    PRTSEMFASTMUTEXINTERNAL pThis = hFastMtx;
+    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
+    AssertMsgReturn(pThis->u32Magic == RTSEMFASTMUTEX_MAGIC, ("u32Magic=%RX32 pThis=%p\n", pThis->u32Magic, pThis), VERR_INVALID_HANDLE);
+
+#if defined(RT_STRICT) || defined(IPRT_DEBUG_SEMS)
+    AssertRelease(pThis->Owner == RTThreadNativeSelf());
+    ASMAtomicUoWriteSize(&pThis->Owner, NIL_RTNATIVETHREAD);
+#endif
+    up(&pThis->Semaphore);
+    IPRT_DEBUG_SEMS_STATE(pThis, 'u');
+
+    IPRT_LINUX_RESTORE_EFL_ONLY_AC();
+    return VINF_SUCCESS;
+}
+RT_EXPORT_SYMBOL(RTSemFastMutexRelease);
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/r0drv/linux/semmutex-r0drv-linux.c
@@ -0,0 +1,419 @@
+/* $Id: semmutex-r0drv-linux.c $ */
+/** @file
+ * IPRT - Mutex Semaphores, Ring-0 Driver, Linux.
+ */
+
+/*
+ * Copyright (C) 2006-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+
+/*********************************************************************************************************************************
+*   Header Files                                                                                                                 *
+*********************************************************************************************************************************/
+#define RTSEMMUTEX_WITHOUT_REMAPPING
+#include "the-linux-kernel.h"
+#include "internal/iprt.h"
+#include <iprt/semaphore.h>
+
+#include <iprt/assert.h>
+#include <iprt/asm.h>
+#include <iprt/mem.h>
+#include <iprt/err.h>
+#include <iprt/list.h>
+
+#include "internal/magics.h"
+
+
+/*********************************************************************************************************************************
+*   Structures and Typedefs                                                                                                      *
+*********************************************************************************************************************************/
+typedef struct RTSEMMUTEXLNXWAITER
+{
+    /** The list entry. */
+    RTLISTNODE                  ListEntry;
+    /** The waiting task. */
+    struct task_struct         *pTask;
+    /** Why did we wake up? */
+    enum
+    {
+        /** Wakeup to take the semaphore. */
+        RTSEMMUTEXLNXWAITER_WAKEUP,
+        /** Mutex is being destroyed. */
+        RTSEMMUTEXLNXWAITER_DESTROYED,
+        /** Some other reason. */
+        RTSEMMUTEXLNXWAITER_OTHER
+    } volatile                  enmReason;
+} RTSEMMUTEXLNXWAITER, *PRTSEMMUTEXLNXWAITER;
+
+/**
+ * Wrapper for the linux semaphore structure.
+ */
+typedef struct RTSEMMUTEXINTERNAL
+{
+    /** Magic value (RTSEMMUTEX_MAGIC). */
+    uint32_t                    u32Magic;
+    /** The number of recursions. */
+    uint32_t                    cRecursions;
+    /** The list of waiting threads. */
+    RTLISTANCHOR                WaiterList;
+    /** The current owner, NULL if none. */
+    struct task_struct         *pOwnerTask;
+    /** The number of references to this piece of memory.  This is used to
+     *  prevent it from being kicked from underneath us while waiting. */
+    uint32_t volatile           cRefs;
+    /** The spinlock protecting the members and falling asleep. */
+    spinlock_t                  Spinlock;
+} RTSEMMUTEXINTERNAL, *PRTSEMMUTEXINTERNAL;
+
+
+RTDECL(int) RTSemMutexCreate(PRTSEMMUTEX phMtx)
+{
+    int rc = VINF_SUCCESS;
+    IPRT_LINUX_SAVE_EFL_AC();
+
+    /*
+     * Allocate.
+     */
+    PRTSEMMUTEXINTERNAL pThis;
+    pThis = (PRTSEMMUTEXINTERNAL)RTMemAlloc(sizeof(*pThis));
+    if (pThis)
+    {
+        /*
+         * Initialize.
+         */
+        pThis->u32Magic     = RTSEMMUTEX_MAGIC;
+        pThis->cRecursions  = 0;
+        pThis->pOwnerTask   = NULL;
+        pThis->cRefs        = 1;
+        RTListInit(&pThis->WaiterList);
+        spin_lock_init(&pThis->Spinlock);
+
+        *phMtx = pThis;
+    }
+    else
+        rc = VERR_NO_MEMORY;
+
+    IPRT_LINUX_RESTORE_EFL_AC();
+    return rc;
+}
+RT_EXPORT_SYMBOL(RTSemMutexCreate);
+
+
+RTDECL(int) RTSemMutexDestroy(RTSEMMUTEX hMtx)
+{
+    PRTSEMMUTEXINTERNAL     pThis = hMtx;
+    PRTSEMMUTEXLNXWAITER    pCur;
+    unsigned long           fSavedIrq;
+
+    /*
+     * Validate.
+     */
+    if (pThis == NIL_RTSEMMUTEX)
+        return VINF_SUCCESS;
+    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
+    AssertMsgReturn(pThis->u32Magic == RTSEMMUTEX_MAGIC, ("u32Magic=%RX32 pThis=%p\n", pThis->u32Magic, pThis), VERR_INVALID_HANDLE);
+
+    /*
+     * Kill it, kick waiters and release it.
+     */
+    AssertReturn(ASMAtomicCmpXchgU32(&pThis->u32Magic, RTSEMMUTEX_MAGIC_DEAD, RTSEMMUTEX_MAGIC), VERR_INVALID_HANDLE);
+
+    IPRT_LINUX_SAVE_EFL_AC();
+
+    spin_lock_irqsave(&pThis->Spinlock, fSavedIrq);
+    RTListForEach(&pThis->WaiterList, pCur, RTSEMMUTEXLNXWAITER, ListEntry)
+    {
+        pCur->enmReason = RTSEMMUTEXLNXWAITER_DESTROYED;
+        wake_up_process(pCur->pTask);
+    }
+
+    if (ASMAtomicDecU32(&pThis->cRefs) != 0)
+        spin_unlock_irqrestore(&pThis->Spinlock, fSavedIrq);
+    else
+    {
+        spin_unlock_irqrestore(&pThis->Spinlock, fSavedIrq);
+        RTMemFree(pThis);
+    }
+
+    IPRT_LINUX_RESTORE_EFL_AC();
+
+    return VINF_SUCCESS;
+}
+RT_EXPORT_SYMBOL(RTSemMutexDestroy);
+
+
+/**
+ * Worker for rtSemMutexLinuxRequest that handles the case where we go to sleep.
+ *
+ * @returns VINF_SUCCESS, VERR_INTERRUPTED, VERR_TIMEOUT or VERR_SEM_DESTROYED.
+ *          Returns without owning the spinlock.
+ * @param   pThis           The mutex instance.
+ * @param   cMillies        The timeout.
+ * @param   fInterruptible  The wait type.
+ * @param   fSavedIrq       The saved IRQ flags.
+ */
+static int rtSemMutexLinuxRequestSleep(PRTSEMMUTEXINTERNAL pThis, RTMSINTERVAL cMillies,
+                                       bool fInterruptible, unsigned long fSavedIrq)
+{
+    struct task_struct *pSelf    = current;
+    int                 rc       = VERR_TIMEOUT;
+    long                lTimeout = cMillies == RT_INDEFINITE_WAIT ? MAX_SCHEDULE_TIMEOUT : msecs_to_jiffies(cMillies);
+    RTSEMMUTEXLNXWAITER Waiter;
+
+    IPRT_DEBUG_SEMS_STATE(pThis, 'm');
+
+    /*
+     * Grab a reference to the mutex and add ourselves to the waiter list.
+     */
+    ASMAtomicIncU32(&pThis->cRefs);
+
+    Waiter.pTask     = pSelf;
+    Waiter.enmReason = RTSEMMUTEXLNXWAITER_OTHER;
+    RTListAppend(&pThis->WaiterList, &Waiter.ListEntry);
+
+    /*
+     * Do the waiting.
+     */
+    for (;;)
+    {
+        /* Check signal and timeout conditions. */
+        if (    fInterruptible
+            &&  signal_pending(pSelf))
+        {
+            rc = VERR_INTERRUPTED;
+            break;
+        }
+
+        if (!lTimeout)
+            break;
+
+        /* Go to sleep. */
+        set_task_state(pSelf, fInterruptible ? TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE);
+        spin_unlock_irq(&pThis->Spinlock);
+
+        lTimeout = schedule_timeout(lTimeout);
+
+        spin_lock_irq(&pThis->Spinlock);
+        set_current_state(TASK_RUNNING);
+
+        /* Did someone wake us up? */
+        if (Waiter.enmReason == RTSEMMUTEXLNXWAITER_WAKEUP)
+        {
+            Assert(pThis->cRecursions == 0);
+            pThis->cRecursions = 1;
+            pThis->pOwnerTask  = pSelf;
+            rc = VINF_SUCCESS;
+            break;
+        }
+
+        /* Is the mutex being destroyed? */
+        if (RT_UNLIKELY(   Waiter.enmReason == RTSEMMUTEXLNXWAITER_DESTROYED
+                        || pThis->u32Magic != RTSEMMUTEX_MAGIC))
+        {
+            rc = VERR_SEM_DESTROYED;
+            break;
+        }
+    }
+
+    /*
+     * Unlink ourself from the waiter list, dereference the mutex and exit the
+     * lock.  We might have to free the mutex if it was the destroyed.
+     */
+    RTListNodeRemove(&Waiter.ListEntry);
+    IPRT_DEBUG_SEMS_STATE_RC(pThis, 'M', rc);
+
+    if (RT_LIKELY(ASMAtomicDecU32(&pThis->cRefs) != 0))
+        spin_unlock_irqrestore(&pThis->Spinlock, fSavedIrq);
+    else
+    {
+        Assert(RT_FAILURE_NP(rc));
+        spin_unlock_irqrestore(&pThis->Spinlock, fSavedIrq);
+        RTMemFree(pThis);
+    }
+    return rc;
+}
+
+
+/**
+ * Internal worker.
+ */
+DECLINLINE(int) rtSemMutexLinuxRequest(RTSEMMUTEX hMutexSem, RTMSINTERVAL cMillies, bool fInterruptible)
+{
+    PRTSEMMUTEXINTERNAL pThis = hMutexSem;
+    struct task_struct *pSelf = current;
+    unsigned long       fSavedIrq;
+    int                 rc;
+    IPRT_LINUX_SAVE_EFL_AC();
+
+    /*
+     * Validate.
+     */
+    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
+    AssertMsgReturn(pThis->u32Magic == RTSEMMUTEX_MAGIC, ("u32Magic=%RX32 pThis=%p\n", pThis->u32Magic, pThis), VERR_INVALID_HANDLE);
+    Assert(pThis->cRefs >= 1);
+
+    /*
+     * Lock it and check if it's a recursion.
+     */
+    spin_lock_irqsave(&pThis->Spinlock, fSavedIrq);
+    if (pThis->pOwnerTask == pSelf)
+    {
+        pThis->cRecursions++;
+        Assert(pThis->cRecursions > 1);
+        Assert(pThis->cRecursions < 256);
+        rc = VINF_SUCCESS;
+    }
+    /*
+     * Not a recursion, maybe it's not owned by anyone then?
+     */
+    else if (   pThis->pOwnerTask == NULL
+             && RTListIsEmpty(&pThis->WaiterList))
+    {
+        Assert(pThis->cRecursions == 0);
+        pThis->cRecursions = 1;
+        pThis->pOwnerTask  = pSelf;
+        rc = VINF_SUCCESS;
+    }
+    /*
+     * Was it a polling call?
+     */
+    else if (cMillies == 0)
+        rc = VERR_TIMEOUT;
+    /*
+     * No, so go to sleep.
+     */
+    else
+    {
+        rc = rtSemMutexLinuxRequestSleep(pThis, cMillies, fInterruptible, fSavedIrq);
+        IPRT_LINUX_RESTORE_EFL_ONLY_AC();
+        return rc;
+    }
+
+    IPRT_DEBUG_SEMS_STATE_RC(pThis, 'M', rc);
+    spin_unlock_irqrestore(&pThis->Spinlock, fSavedIrq);
+    IPRT_LINUX_RESTORE_EFL_ONLY_AC();
+    return rc;
+}
+
+
+RTDECL(int) RTSemMutexRequest(RTSEMMUTEX hMutexSem, RTMSINTERVAL cMillies)
+{
+    return rtSemMutexLinuxRequest(hMutexSem, cMillies, false /*fInterruptible*/);
+}
+RT_EXPORT_SYMBOL(RTSemMutexRequest);
+
+
+RTDECL(int) RTSemMutexRequestDebug(RTSEMMUTEX hMutexSem, RTMSINTERVAL cMillies, RTHCUINTPTR uId, RT_SRC_POS_DECL)
+{
+    return RTSemMutexRequest(hMutexSem, cMillies);
+}
+RT_EXPORT_SYMBOL(RTSemMutexRequestDebug);
+
+
+RTDECL(int) RTSemMutexRequestNoResume(RTSEMMUTEX hMutexSem, RTMSINTERVAL cMillies)
+{
+    return rtSemMutexLinuxRequest(hMutexSem, cMillies, true /*fInterruptible*/);
+}
+RT_EXPORT_SYMBOL(RTSemMutexRequestNoResume);
+
+
+RTDECL(int) RTSemMutexRequestNoResumeDebug(RTSEMMUTEX hMutexSem, RTMSINTERVAL cMillies, RTHCUINTPTR uId, RT_SRC_POS_DECL)
+{
+    return RTSemMutexRequestNoResume(hMutexSem, cMillies);
+}
+RT_EXPORT_SYMBOL(RTSemMutexRequestNoResumeDebug);
+
+
+RTDECL(int) RTSemMutexRelease(RTSEMMUTEX hMtx)
+{
+    PRTSEMMUTEXINTERNAL pThis = hMtx;
+    struct task_struct *pSelf = current;
+    unsigned long       fSavedIrq;
+    int                 rc;
+    IPRT_LINUX_SAVE_EFL_AC();
+
+    /*
+     * Validate.
+     */
+    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
+    AssertMsgReturn(pThis->u32Magic == RTSEMMUTEX_MAGIC, ("u32Magic=%RX32 pThis=%p\n", pThis->u32Magic, pThis), VERR_INVALID_HANDLE);
+    Assert(pThis->cRefs >= 1);
+
+    /*
+     * Take the lock and release one recursion.
+     */
+    spin_lock_irqsave(&pThis->Spinlock, fSavedIrq);
+    if (pThis->pOwnerTask == pSelf)
+    {
+        Assert(pThis->cRecursions > 0);
+        if (--pThis->cRecursions == 0)
+        {
+            pThis->pOwnerTask = NULL;
+
+            /* anyone to wake up? */
+            if (!RTListIsEmpty(&pThis->WaiterList))
+            {
+                PRTSEMMUTEXLNXWAITER pWaiter = RTListGetFirst(&pThis->WaiterList, RTSEMMUTEXLNXWAITER, ListEntry);
+                pWaiter->enmReason = RTSEMMUTEXLNXWAITER_WAKEUP;
+                wake_up_process(pWaiter->pTask);
+            }
+            IPRT_DEBUG_SEMS_STATE(pThis, 'u');
+        }
+        rc = VINF_SUCCESS;
+    }
+    else
+        rc = VERR_NOT_OWNER;
+    spin_unlock_irqrestore(&pThis->Spinlock, fSavedIrq);
+
+    AssertRC(rc);
+    IPRT_LINUX_RESTORE_EFL_AC();
+    return rc;
+}
+RT_EXPORT_SYMBOL(RTSemMutexRelease);
+
+
+RTDECL(bool) RTSemMutexIsOwned(RTSEMMUTEX hMutexSem)
+{
+    PRTSEMMUTEXINTERNAL pThis = hMutexSem;
+    unsigned long       fSavedIrq;
+    bool                fOwned;
+    IPRT_LINUX_SAVE_EFL_AC();
+
+    /*
+     * Validate.
+     */
+    AssertPtrReturn(pThis, false);
+    AssertMsgReturn(pThis->u32Magic == RTSEMMUTEX_MAGIC, ("u32Magic=%RX32 pThis=%p\n", pThis->u32Magic, pThis), false);
+    Assert(pThis->cRefs >= 1);
+
+    /*
+     * Take the lock and release one recursion.
+     */
+    spin_lock_irqsave(&pThis->Spinlock, fSavedIrq);
+    fOwned = pThis->pOwnerTask != NULL;
+    spin_unlock_irqrestore(&pThis->Spinlock, fSavedIrq);
+
+    IPRT_LINUX_RESTORE_EFL_AC();
+    return fOwned;
+
+}
+RT_EXPORT_SYMBOL(RTSemMutexIsOwned);
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/r0drv/linux/spinlock-r0drv-linux.c
@@ -0,0 +1,185 @@
+/* $Id: spinlock-r0drv-linux.c $ */
+/** @file
+ * IPRT - Spinlocks, Ring-0 Driver, Linux.
+ */
+
+/*
+ * Copyright (C) 2006-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+
+/*********************************************************************************************************************************
+*   Header Files                                                                                                                 *
+*********************************************************************************************************************************/
+#include "the-linux-kernel.h"
+#include "internal/iprt.h"
+#include <iprt/spinlock.h>
+
+#include <iprt/asm.h>
+#if defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86)
+# include <iprt/asm-amd64-x86.h>
+#endif
+#include <iprt/assert.h>
+#include <iprt/err.h>
+#include <iprt/mem.h>
+#include <iprt/mp.h>
+#include <iprt/thread.h>
+#include "internal/magics.h"
+
+
+/*********************************************************************************************************************************
+*   Structures and Typedefs                                                                                                      *
+*********************************************************************************************************************************/
+/**
+ * Wrapper for the spinlock_t structure.
+ */
+typedef struct RTSPINLOCKINTERNAL
+{
+    /** Spinlock magic value (RTSPINLOCK_MAGIC). */
+    uint32_t volatile       u32Magic;
+    /** The spinlock creation flags.  */
+    uint32_t                fFlags;
+    /** The saved interrupt flag. */
+    unsigned long volatile  fIntSaved;
+    /** The linux spinlock structure. */
+    spinlock_t              Spinlock;
+#ifdef RT_MORE_STRICT
+    /** The idAssertCpu variable before acquring the lock for asserting after
+     *  releasing the spinlock. */
+    RTCPUID volatile        idAssertCpu;
+    /** The CPU that owns the lock. */
+    RTCPUID volatile        idCpuOwner;
+#endif
+} RTSPINLOCKINTERNAL, *PRTSPINLOCKINTERNAL;
+
+
+
+RTDECL(int)  RTSpinlockCreate(PRTSPINLOCK pSpinlock, uint32_t fFlags, const char *pszName)
+{
+    IPRT_LINUX_SAVE_EFL_AC();
+    PRTSPINLOCKINTERNAL pThis;
+    AssertReturn(fFlags == RTSPINLOCK_FLAGS_INTERRUPT_SAFE || fFlags == RTSPINLOCK_FLAGS_INTERRUPT_UNSAFE, VERR_INVALID_PARAMETER);
+
+    /*
+     * Allocate.
+     */
+    Assert(sizeof(RTSPINLOCKINTERNAL) > sizeof(void *));
+    pThis = (PRTSPINLOCKINTERNAL)RTMemAlloc(sizeof(*pThis));
+    if (!pThis)
+        return VERR_NO_MEMORY;
+    /*
+     * Initialize and return.
+     */
+    pThis->u32Magic     = RTSPINLOCK_MAGIC;
+    pThis->fFlags       = fFlags;
+    pThis->fIntSaved    = 0;
+#ifdef RT_MORE_STRICT
+    pThis->idCpuOwner   = NIL_RTCPUID;
+    pThis->idAssertCpu  = NIL_RTCPUID;
+#endif
+
+    spin_lock_init(&pThis->Spinlock);
+
+    *pSpinlock = pThis;
+    IPRT_LINUX_RESTORE_EFL_AC();
+    return VINF_SUCCESS;
+}
+RT_EXPORT_SYMBOL(RTSpinlockCreate);
+
+
+RTDECL(int)  RTSpinlockDestroy(RTSPINLOCK Spinlock)
+{
+    /*
+     * Validate input.
+     */
+    PRTSPINLOCKINTERNAL pThis = (PRTSPINLOCKINTERNAL)Spinlock;
+    if (!pThis)
+        return VERR_INVALID_PARAMETER;
+    if (pThis->u32Magic != RTSPINLOCK_MAGIC)
+    {
+        AssertMsgFailed(("Invalid spinlock %p magic=%#x\n", pThis, pThis->u32Magic));
+        return VERR_INVALID_PARAMETER;
+    }
+
+    ASMAtomicIncU32(&pThis->u32Magic);
+    RTMemFree(pThis);
+    return VINF_SUCCESS;
+}
+RT_EXPORT_SYMBOL(RTSpinlockDestroy);
+
+
+RTDECL(void) RTSpinlockAcquire(RTSPINLOCK Spinlock)
+{
+    PRTSPINLOCKINTERNAL pThis = (PRTSPINLOCKINTERNAL)Spinlock;
+    IPRT_LINUX_SAVE_EFL_AC();
+    RT_ASSERT_PREEMPT_CPUID_VAR();
+    AssertMsg(pThis && pThis->u32Magic == RTSPINLOCK_MAGIC,
+              ("pThis=%p u32Magic=%08x\n", pThis, pThis ? (int)pThis->u32Magic : 0));
+
+#ifdef CONFIG_PROVE_LOCKING
+    lockdep_off();
+#endif
+    if (pThis->fFlags & RTSPINLOCK_FLAGS_INTERRUPT_SAFE)
+    {
+        unsigned long fIntSaved;
+        spin_lock_irqsave(&pThis->Spinlock, fIntSaved);
+        pThis->fIntSaved = fIntSaved;
+    }
+    else
+        spin_lock(&pThis->Spinlock);
+#ifdef CONFIG_PROVE_LOCKING
+    lockdep_on();
+#endif
+
+    IPRT_LINUX_RESTORE_EFL_ONLY_AC();
+    RT_ASSERT_PREEMPT_CPUID_SPIN_ACQUIRED(pThis);
+}
+RT_EXPORT_SYMBOL(RTSpinlockAcquire);
+
+
+RTDECL(void) RTSpinlockRelease(RTSPINLOCK Spinlock)
+{
+    PRTSPINLOCKINTERNAL pThis = (PRTSPINLOCKINTERNAL)Spinlock;
+    IPRT_LINUX_SAVE_EFL_AC();           /* spin_unlock* may preempt and trash eflags.ac. */
+    RT_ASSERT_PREEMPT_CPUID_SPIN_RELEASE_VARS();
+    AssertMsg(pThis && pThis->u32Magic == RTSPINLOCK_MAGIC,
+              ("pThis=%p u32Magic=%08x\n", pThis, pThis ? (int)pThis->u32Magic : 0));
+    RT_ASSERT_PREEMPT_CPUID_SPIN_RELEASE(pThis);
+
+#ifdef CONFIG_PROVE_LOCKING
+    lockdep_off();
+#endif
+    if (pThis->fFlags & RTSPINLOCK_FLAGS_INTERRUPT_SAFE)
+    {
+        unsigned long fIntSaved = pThis->fIntSaved;
+        pThis->fIntSaved = 0;
+        spin_unlock_irqrestore(&pThis->Spinlock, fIntSaved);
+    }
+    else
+        spin_unlock(&pThis->Spinlock);
+#ifdef CONFIG_PROVE_LOCKING
+    lockdep_on();
+#endif
+
+    IPRT_LINUX_RESTORE_EFL_ONLY_AC();
+    RT_ASSERT_PREEMPT_CPUID();
+}
+RT_EXPORT_SYMBOL(RTSpinlockRelease);
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/r0drv/linux/string.h
@@ -0,0 +1,57 @@
+/* $Id: string.h $ */
+/** @file
+ * IPRT - wrapper for the linux kernel asm/string.h.
+ */
+
+/*
+ * Copyright (C) 2006-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+#ifndef ___string_h
+#define ___string_h
+
+#include <iprt/cdefs.h>
+
+RT_C_DECLS_BEGIN
+#ifndef bool /* Linux 2.6.19 C++ nightmare */
+#define bool bool_type
+#define true true_type
+#define false false_type
+#define _Bool int
+#define bool_type_r0drv_string_h__
+#endif
+#include <linux/types.h>
+#include <linux/string.h>
+#ifdef bool_type_r0drv_string_h__
+#undef bool
+#undef true
+#undef false
+#undef bool_type_r0drv_string_h__
+#endif
+char *strpbrk(const char *pszStr, const char *pszChars)
+#if defined(__THROW)
+    __THROW
+#endif
+    ;
+
+RT_C_DECLS_END
+
+#endif
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/r0drv/linux/the-linux-kernel.h
@@ -0,0 +1,429 @@
+/* $Id: the-linux-kernel.h $ */
+/** @file
+ * IPRT - Include all necessary headers for the Linux kernel.
+ */
+
+/*
+ * Copyright (C) 2006-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+#ifndef ___the_linux_kernel_h
+#define ___the_linux_kernel_h
+
+/*
+ * Include iprt/types.h to install the bool wrappers.
+ * Then use the linux bool type for all the stuff include here.
+ */
+#include <iprt/types.h>
+#define bool linux_bool
+
+#include <linux/version.h>
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 33)
+# include <generated/autoconf.h>
+#else
+# ifndef AUTOCONF_INCLUDED
+#  include <linux/autoconf.h>
+# endif
+#endif
+
+/* We only support 2.4 and 2.6 series kernels */
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0)
+# error We only support 2.4 and 2.6 series kernels
+#endif
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 0) && LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0)
+# error We only support 2.4 and 2.6 series kernels
+#endif
+
+#if defined(CONFIG_MODVERSIONS) && !defined(MODVERSIONS)
+# define MODVERSIONS
+# if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 71)
+#  include <linux/modversions.h>
+# endif
+#endif
+#ifndef KBUILD_STR
+# if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 16)
+#  define KBUILD_STR(s) s
+# else
+#  define KBUILD_STR(s) #s
+# endif
+#endif
+# if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0)
+#  include <linux/kconfig.h> /* for macro IS_ENABLED */
+# endif
+#include <linux/string.h>
+#include <linux/spinlock.h>
+#include <linux/slab.h>
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)
+# include <linux/semaphore.h>
+#else /* older kernels */
+# include <asm/semaphore.h>
+#endif /* older kernels */
+#include <linux/module.h>
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)
+# include <linux/moduleparam.h>
+#endif
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/fs.h>
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)
+# include <linux/namei.h>
+#endif
+#include <linux/mm.h>
+#include <linux/pagemap.h>
+#include <linux/slab.h>
+#include <linux/time.h>
+#include <linux/sched.h>
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0)
+# include <linux/sched/rt.h>
+#endif
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 7)
+# include <linux/jiffies.h>
+#endif
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 16)
+# include <linux/ktime.h>
+# include <linux/hrtimer.h>
+#endif
+#include <linux/wait.h>
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 71)
+# include <linux/cpu.h>
+# include <linux/notifier.h>
+#endif
+/* For the basic additions module */
+#include <linux/pci.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/completion.h>
+#include <linux/compiler.h>
+#ifndef HAVE_UNLOCKED_IOCTL /* linux/fs.h defines this */
+# include <linux/smp_lock.h>
+#endif
+/* For the shared folders module */
+#include <linux/vmalloc.h>
+#define wchar_t linux_wchar_t
+#include <linux/nls.h>
+#undef wchar_t
+#include <asm/mman.h>
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include <asm/div64.h>
+
+/* For thread-context hooks. */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 18) && defined(CONFIG_PREEMPT_NOTIFIERS)
+# include <linux/preempt.h>
+#endif
+
+/* for workqueue / task queues. */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 41)
+# include <linux/workqueue.h>
+#else
+# include <linux/tqueue.h>
+#endif
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)
+# include <linux/kthread.h>
+#endif
+
+/* for cr4_init_shadow() / cpu_tlbstate. */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 20, 0)
+# include <asm/tlbflush.h>
+#endif
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 7, 0)
+# include <asm/smap.h>
+#else
+static inline void clac(void) { }
+static inline void stac(void) { }
+#endif
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0)
+# ifndef page_to_pfn
+#  define page_to_pfn(page) ((page) - mem_map)
+# endif
+#endif
+
+#ifndef DEFINE_WAIT
+# define DEFINE_WAIT(name) DECLARE_WAITQUEUE(name, current)
+#endif
+
+#ifndef __GFP_NOWARN
+# define __GFP_NOWARN 0
+#endif
+
+/*
+ * 2.4 / early 2.6 compatibility wrappers
+ */
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 7)
+
+# ifndef MAX_JIFFY_OFFSET
+#  define MAX_JIFFY_OFFSET ((~0UL >> 1)-1)
+# endif
+
+# if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 29) || LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)
+
+DECLINLINE(unsigned int) jiffies_to_msecs(unsigned long cJiffies)
+{
+#  if HZ <= 1000 && !(1000 % HZ)
+    return (1000 / HZ) * cJiffies;
+#  elif HZ > 1000 && !(HZ % 1000)
+    return (cJiffies + (HZ / 1000) - 1) / (HZ / 1000);
+#  else
+    return (cJiffies * 1000) / HZ;
+#  endif
+}
+
+DECLINLINE(unsigned long) msecs_to_jiffies(unsigned int cMillies)
+{
+#  if HZ > 1000
+    if (cMillies > jiffies_to_msecs(MAX_JIFFY_OFFSET))
+        return MAX_JIFFY_OFFSET;
+#  endif
+#  if HZ <= 1000 && !(1000 % HZ)
+    return (cMillies + (1000 / HZ) - 1) / (1000 / HZ);
+#  elif HZ > 1000 && !(HZ % 1000)
+    return cMillies * (HZ / 1000);
+#  else
+    return (cMillies * HZ + 999) / 1000;
+#  endif
+}
+
+# endif  /* < 2.4.29 || >= 2.6.0 */
+
+#endif /* < 2.6.7 */
+
+/*
+ * 2.4 compatibility wrappers
+ */
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0)
+
+# define prepare_to_wait(q, wait, state) \
+    do { \
+        add_wait_queue(q, wait); \
+        set_current_state(state); \
+    } while (0)
+
+# define after_wait(wait) \
+    do { \
+        list_del_init(&(wait)->task_list); \
+    } while (0)
+
+# define finish_wait(q, wait) \
+    do { \
+        set_current_state(TASK_RUNNING); \
+        remove_wait_queue(q, wait); \
+    } while (0)
+
+#else /* >= 2.6.0 */
+
+# define after_wait(wait)       do {} while (0)
+
+#endif /* >= 2.6.0 */
+
+/** @def TICK_NSEC
+ * The time between ticks in nsec */
+#ifndef TICK_NSEC
+# define TICK_NSEC (1000000000UL / HZ)
+#endif
+
+/*
+ * This sucks soooo badly on x86! Why don't they export __PAGE_KERNEL_EXEC so PAGE_KERNEL_EXEC would be usable?
+ */
+#if   LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 8) && defined(RT_ARCH_AMD64)
+# define MY_PAGE_KERNEL_EXEC    PAGE_KERNEL_EXEC
+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 8) && defined(PAGE_KERNEL_EXEC) && defined(CONFIG_X86_PAE)
+# ifdef __PAGE_KERNEL_EXEC
+   /* >= 2.6.27 */
+#  define MY_PAGE_KERNEL_EXEC   __pgprot(cpu_has_pge ? __PAGE_KERNEL_EXEC | _PAGE_GLOBAL : __PAGE_KERNEL_EXEC)
+# else
+#  define MY_PAGE_KERNEL_EXEC   __pgprot(cpu_has_pge ? _PAGE_KERNEL_EXEC | _PAGE_GLOBAL : _PAGE_KERNEL_EXEC)
+# endif
+#else
+# define MY_PAGE_KERNEL_EXEC    PAGE_KERNEL
+#endif
+
+
+/*
+ * The redhat hack section.
+ *  - The current hacks are for 2.4.21-15.EL only.
+ */
+#ifndef NO_REDHAT_HACKS
+/* accounting. */
+# if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0)
+#  ifdef VM_ACCOUNT
+#   define USE_RHEL4_MUNMAP
+#  endif
+# endif
+
+/* backported remap_page_range. */
+# if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0)
+#  include <asm/tlb.h>
+#  ifdef tlb_vma /* probably not good enough... */
+#   define HAVE_26_STYLE_REMAP_PAGE_RANGE 1
+#  endif
+# endif
+
+# ifndef RT_ARCH_AMD64
+/* In 2.6.9-22.ELsmp we have to call change_page_attr() twice when changing
+ * the page attributes from PAGE_KERNEL to something else, because there appears
+ * to be a bug in one of the many patches that redhat applied.
+ * It should be safe to do this on less buggy linux kernels too. ;-)
+ */
+#  define MY_CHANGE_PAGE_ATTR(pPages, cPages, prot) \
+    do { \
+        if (pgprot_val(prot) != pgprot_val(PAGE_KERNEL)) \
+            change_page_attr(pPages, cPages, prot); \
+        change_page_attr(pPages, cPages, prot); \
+    } while (0)
+# endif  /* !RT_ARCH_AMD64 */
+#endif /* !NO_REDHAT_HACKS */
+
+#ifndef MY_CHANGE_PAGE_ATTR
+# ifdef RT_ARCH_AMD64 /** @todo This is a cheap hack, but it'll get around that 'else BUG();' in __change_page_attr().  */
+#  define MY_CHANGE_PAGE_ATTR(pPages, cPages, prot) \
+    do { \
+        change_page_attr(pPages, cPages, PAGE_KERNEL_NOCACHE); \
+        change_page_attr(pPages, cPages, prot); \
+    } while (0)
+# else
+#  define MY_CHANGE_PAGE_ATTR(pPages, cPages, prot) change_page_attr(pPages, cPages, prot)
+# endif
+#endif
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)
+# define MY_SET_PAGES_EXEC(pPages, cPages)    set_pages_x(pPages, cPages)
+# define MY_SET_PAGES_NOEXEC(pPages, cPages)  set_pages_nx(pPages, cPages)
+#else
+# define MY_SET_PAGES_EXEC(pPages, cPages) \
+    do { \
+        if (pgprot_val(MY_PAGE_KERNEL_EXEC) != pgprot_val(PAGE_KERNEL)) \
+            MY_CHANGE_PAGE_ATTR(pPages, cPages, MY_PAGE_KERNEL_EXEC); \
+    } while (0)
+# define MY_SET_PAGES_NOEXEC(pPages, cPages) \
+    do { \
+        if (pgprot_val(MY_PAGE_KERNEL_EXEC) != pgprot_val(PAGE_KERNEL)) \
+            MY_CHANGE_PAGE_ATTR(pPages, cPages, PAGE_KERNEL); \
+    } while (0)
+#endif
+
+/** @def ONE_MSEC_IN_JIFFIES
+ * The number of jiffies that make up 1 millisecond. Must be at least 1! */
+#if HZ <= 1000
+# define ONE_MSEC_IN_JIFFIES       1
+#elif !(HZ % 1000)
+# define ONE_MSEC_IN_JIFFIES       (HZ / 1000)
+#else
+# define ONE_MSEC_IN_JIFFIES       ((HZ + 999) / 1000)
+# error "HZ is not a multiple of 1000, the GIP stuff won't work right!"
+#endif
+
+/*
+ * Stop using the linux bool type.
+ */
+#undef bool
+
+/*
+ * There are post-2.6.24 kernels (confusingly with unchanged version number)
+ * which eliminate macros which were marked as deprecated.
+ */
+#ifndef __attribute_used__
+#define __attribute_used__ __used
+#endif
+
+/**
+ * Hack for shortening pointers on linux so we can stuff more stuff into the
+ * task_struct::comm field. This is used by the semaphore code but put here
+ * because we don't have any better place atm. Don't use outside IPRT, please.
+ */
+#ifdef RT_ARCH_AMD64
+# define IPRT_DEBUG_SEMS_ADDRESS(addr)  ( ((long)(addr) & (long)~UINT64_C(0xfffffff000000000)) )
+#else
+# define IPRT_DEBUG_SEMS_ADDRESS(addr)  ( (long)(addr) )
+#endif
+
+/**
+ * Puts semaphore info into the task_struct::comm field if IPRT_DEBUG_SEMS is
+ * defined.
+ */
+#ifdef IPRT_DEBUG_SEMS
+# define IPRT_DEBUG_SEMS_STATE(pThis, chState) \
+    snprintf(current->comm, sizeof(current->comm), "%c%lx", (chState), IPRT_DEBUG_SEMS_ADDRESS(pThis));
+#else
+# define IPRT_DEBUG_SEMS_STATE(pThis, chState)  do {  } while (0)
+#endif
+
+/**
+ * Puts semaphore info into the task_struct::comm field if IPRT_DEBUG_SEMS is
+ * defined.
+ */
+#ifdef IPRT_DEBUG_SEMS
+# define IPRT_DEBUG_SEMS_STATE_RC(pThis, chState, rc) \
+    snprintf(current->comm, sizeof(current->comm), "%c%lx:%d", (chState), IPRT_DEBUG_SEMS_ADDRESS(pThis), rc);
+#else
+# define IPRT_DEBUG_SEMS_STATE_RC(pThis, chState, rc)  do {  } while (0)
+#endif
+
+/** @name Macros for preserving EFLAGS.AC on 3.19+/amd64  paranoid.
+ * The AMD 64 switch_to in macro in arch/x86/include/asm/switch_to.h stopped
+ * restoring flags.
+ * @{ */
+#if defined(CONFIG_X86_SMAP) || defined(RT_STRICT) || defined(IPRT_WITH_EFLAGS_AC_PRESERVING)
+# include <iprt/asm-amd64-x86.h>
+# define IPRT_X86_EFL_AC                    RT_BIT(18)
+# define IPRT_LINUX_SAVE_EFL_AC()           RTCCUINTREG fSavedEfl = ASMGetFlags()
+# define IPRT_LINUX_RESTORE_EFL_AC()        ASMSetFlags(fSavedEfl)
+# define IPRT_LINUX_RESTORE_EFL_ONLY_AC()   ASMChangeFlags(~IPRT_X86_EFL_AC, fSavedEfl & IPRT_X86_EFL_AC)
+#else
+# define IPRT_LINUX_SAVE_EFL_AC()           do { } while (0)
+# define IPRT_LINUX_RESTORE_EFL_AC()        do { } while (0)
+# define IPRT_LINUX_RESTORE_EFL_ONLY_AC()   do { } while (0)
+#endif
+/** @} */
+
+/*
+ * There are some conflicting defines in iprt/param.h, sort them out here.
+ */
+#ifndef ___iprt_param_h
+# undef PAGE_SIZE
+# undef PAGE_OFFSET_MASK
+# include <iprt/param.h>
+#endif
+
+/*
+ * Some global indicator macros.
+ */
+/** @def IPRT_LINUX_HAS_HRTIMER
+ * Whether the kernel support high resolution timers (Linux kernel versions
+ * 2.6.28 and later (hrtimer_add_expires_ns() & schedule_hrtimeout). */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28)
+# define IPRT_LINUX_HAS_HRTIMER
+#endif
+
+/*
+ * Workqueue stuff, see initterm-r0drv-linux.c.
+ */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 41)
+typedef struct work_struct  RTR0LNXWORKQUEUEITEM;
+#else
+typedef struct tq_struct    RTR0LNXWORKQUEUEITEM;
+#endif
+DECLHIDDEN(void) rtR0LnxWorkqueuePush(RTR0LNXWORKQUEUEITEM *pWork, void (*pfnWorker)(RTR0LNXWORKQUEUEITEM *));
+DECLHIDDEN(void) rtR0LnxWorkqueueFlush(void);
+
+
+#endif
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/r0drv/linux/thread-r0drv-linux.c
@@ -0,0 +1,236 @@
+/* $Id: thread-r0drv-linux.c $ */
+/** @file
+ * IPRT - Threads, Ring-0 Driver, Linux.
+ */
+
+/*
+ * Copyright (C) 2006-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+
+/*********************************************************************************************************************************
+*   Header Files                                                                                                                 *
+*********************************************************************************************************************************/
+#include "the-linux-kernel.h"
+#include "internal/iprt.h"
+#include <iprt/thread.h>
+
+#include <iprt/asm.h>
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 28) || defined(CONFIG_X86_SMAP)
+# include <iprt/asm-amd64-x86.h>
+#endif
+#include <iprt/assert.h>
+#include <iprt/err.h>
+#include <iprt/mp.h>
+
+
+/*********************************************************************************************************************************
+*   Global Variables                                                                                                             *
+*********************************************************************************************************************************/
+#ifndef CONFIG_PREEMPT
+/** Per-cpu preemption counters. */
+static int32_t volatile g_acPreemptDisabled[NR_CPUS];
+#endif
+
+
+RTDECL(RTNATIVETHREAD) RTThreadNativeSelf(void)
+{
+    return (RTNATIVETHREAD)current;
+}
+RT_EXPORT_SYMBOL(RTThreadNativeSelf);
+
+
+static int rtR0ThreadLnxSleepCommon(RTMSINTERVAL cMillies)
+{
+    IPRT_LINUX_SAVE_EFL_AC();
+    long cJiffies = msecs_to_jiffies(cMillies);
+    set_current_state(TASK_INTERRUPTIBLE);
+    cJiffies = schedule_timeout(cJiffies);
+    IPRT_LINUX_RESTORE_EFL_AC();
+    if (!cJiffies)
+        return VINF_SUCCESS;
+    return VERR_INTERRUPTED;
+}
+
+
+RTDECL(int) RTThreadSleep(RTMSINTERVAL cMillies)
+{
+    return rtR0ThreadLnxSleepCommon(cMillies);
+}
+RT_EXPORT_SYMBOL(RTThreadSleep);
+
+
+RTDECL(int) RTThreadSleepNoLog(RTMSINTERVAL cMillies)
+{
+    return rtR0ThreadLnxSleepCommon(cMillies);
+}
+RT_EXPORT_SYMBOL(RTThreadSleepNoLog);
+
+
+RTDECL(bool) RTThreadYield(void)
+{
+    IPRT_LINUX_SAVE_EFL_AC();
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 20)
+    yield();
+#else
+    /** @todo r=ramshankar: Can we use cond_resched() instead?  */
+    set_current_state(TASK_RUNNING);
+    sys_sched_yield();
+    schedule();
+#endif
+    IPRT_LINUX_RESTORE_EFL_AC();
+    return true;
+}
+RT_EXPORT_SYMBOL(RTThreadYield);
+
+
+RTDECL(bool) RTThreadPreemptIsEnabled(RTTHREAD hThread)
+{
+#ifdef CONFIG_PREEMPT
+    Assert(hThread == NIL_RTTHREAD);
+# ifdef preemptible
+    return preemptible();
+# else
+    return preempt_count() == 0 && !in_atomic() && !irqs_disabled();
+# endif
+#else
+    int32_t c;
+
+    Assert(hThread == NIL_RTTHREAD);
+    c = g_acPreemptDisabled[smp_processor_id()];
+    AssertMsg(c >= 0 && c < 32, ("%d\n", c));
+    if (c != 0)
+        return false;
+# if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 32)
+    if (in_atomic())
+        return false;
+# endif
+# if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 28)
+    if (irqs_disabled())
+        return false;
+# else
+    if (!ASMIntAreEnabled())
+        return false;
+# endif
+    return true;
+#endif
+}
+RT_EXPORT_SYMBOL(RTThreadPreemptIsEnabled);
+
+
+RTDECL(bool) RTThreadPreemptIsPending(RTTHREAD hThread)
+{
+    Assert(hThread == NIL_RTTHREAD);
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 4)
+    return !!test_tsk_thread_flag(current, TIF_NEED_RESCHED);
+
+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 20)
+    return !!need_resched();
+
+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 1, 110)
+    return current->need_resched != 0;
+
+#else
+    return need_resched != 0;
+#endif
+}
+RT_EXPORT_SYMBOL(RTThreadPreemptIsPending);
+
+
+RTDECL(bool) RTThreadPreemptIsPendingTrusty(void)
+{
+    /* yes, RTThreadPreemptIsPending is reliable. */
+    return true;
+}
+RT_EXPORT_SYMBOL(RTThreadPreemptIsPendingTrusty);
+
+
+RTDECL(bool) RTThreadPreemptIsPossible(void)
+{
+    /** @todo r=ramshankar: What about CONFIG_PREEMPT_VOLUNTARY? That can preempt
+     *        too but does so in voluntarily in explicit preemption points. */
+#ifdef CONFIG_PREEMPT
+    return true;    /* yes, kernel preemption is possible. */
+#else
+    return false;   /* no kernel preemption */
+#endif
+}
+RT_EXPORT_SYMBOL(RTThreadPreemptIsPossible);
+
+
+RTDECL(void) RTThreadPreemptDisable(PRTTHREADPREEMPTSTATE pState)
+{
+#ifdef CONFIG_PREEMPT
+    AssertPtr(pState);
+    Assert(pState->u32Reserved == 0);
+    pState->u32Reserved = 42;
+    /* This ASSUMES that CONFIG_PREEMPT_COUNT is always defined with CONFIG_PREEMPT. */
+    preempt_disable();
+    RT_ASSERT_PREEMPT_CPUID_DISABLE(pState);
+
+#else /* !CONFIG_PREEMPT */
+    int32_t c;
+    AssertPtr(pState);
+    Assert(pState->u32Reserved == 0);
+
+    /* Do our own accounting. */
+    c = ASMAtomicIncS32(&g_acPreemptDisabled[smp_processor_id()]);
+    AssertMsg(c > 0 && c < 32, ("%d\n", c));
+    pState->u32Reserved = c;
+    RT_ASSERT_PREEMPT_CPUID_DISABLE(pState);
+#endif
+}
+RT_EXPORT_SYMBOL(RTThreadPreemptDisable);
+
+
+RTDECL(void) RTThreadPreemptRestore(PRTTHREADPREEMPTSTATE pState)
+{
+#ifdef CONFIG_PREEMPT
+    IPRT_LINUX_SAVE_EFL_AC(); /* paranoia */
+    AssertPtr(pState);
+    Assert(pState->u32Reserved == 42);
+    RT_ASSERT_PREEMPT_CPUID_RESTORE(pState);
+    preempt_enable();
+    IPRT_LINUX_RESTORE_EFL_ONLY_AC();  /* paranoia */
+
+#else
+    int32_t volatile *pc;
+    AssertPtr(pState);
+    AssertMsg(pState->u32Reserved > 0 && pState->u32Reserved < 32, ("%d\n", pState->u32Reserved));
+    RT_ASSERT_PREEMPT_CPUID_RESTORE(pState);
+
+    /* Do our own accounting. */
+    pc = &g_acPreemptDisabled[smp_processor_id()];
+    AssertMsg(pState->u32Reserved == (uint32_t)*pc, ("u32Reserved=%d *pc=%d \n", pState->u32Reserved, *pc));
+    ASMAtomicUoWriteS32(pc, pState->u32Reserved - 1);
+#endif
+    pState->u32Reserved = 0;
+}
+RT_EXPORT_SYMBOL(RTThreadPreemptRestore);
+
+
+RTDECL(bool) RTThreadIsInInterrupt(RTTHREAD hThread)
+{
+    Assert(hThread == NIL_RTTHREAD); NOREF(hThread);
+
+    return in_interrupt() != 0;
+}
+RT_EXPORT_SYMBOL(RTThreadIsInInterrupt);
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/r0drv/linux/thread2-r0drv-linux.c
@@ -0,0 +1,158 @@
+/* $Id: thread2-r0drv-linux.c $ */
+/** @file
+ * IPRT - Threads (Part 2), Ring-0 Driver, Linux.
+ */
+
+/*
+ * Copyright (C) 2006-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+
+/*********************************************************************************************************************************
+*   Header Files                                                                                                                 *
+*********************************************************************************************************************************/
+#include "the-linux-kernel.h"
+#include "internal/iprt.h"
+
+#include <iprt/assert.h>
+#include <iprt/thread.h>
+#include <iprt/err.h>
+#include "internal/thread.h"
+
+
+RTDECL(RTTHREAD) RTThreadSelf(void)
+{
+    return rtThreadGetByNative((RTNATIVETHREAD)current);
+}
+
+
+DECLHIDDEN(int) rtThreadNativeInit(void)
+{
+    return VINF_SUCCESS;
+}
+
+
+DECLHIDDEN(int) rtThreadNativeSetPriority(PRTTHREADINT pThread, RTTHREADTYPE enmType)
+{
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 11)
+    /* See comment near MAX_RT_PRIO in linux/sched.h for details on
+       sched_priority. */
+    int                 iSchedClass = SCHED_NORMAL;
+    struct sched_param  Param       = { .sched_priority = MAX_PRIO - 1 };
+    switch (enmType)
+    {
+        case RTTHREADTYPE_INFREQUENT_POLLER:
+            Param.sched_priority = MAX_RT_PRIO + 5;
+            break;
+
+        case RTTHREADTYPE_EMULATION:
+            Param.sched_priority = MAX_RT_PRIO + 4;
+            break;
+
+        case RTTHREADTYPE_DEFAULT:
+            Param.sched_priority = MAX_RT_PRIO + 3;
+            break;
+
+        case RTTHREADTYPE_MSG_PUMP:
+            Param.sched_priority = MAX_RT_PRIO + 2;
+            break;
+
+        case RTTHREADTYPE_IO:
+            iSchedClass = SCHED_FIFO;
+            Param.sched_priority = MAX_RT_PRIO - 1;
+            break;
+
+        case RTTHREADTYPE_TIMER:
+            iSchedClass = SCHED_FIFO;
+            Param.sched_priority = 1; /* not 0 just in case */
+            break;
+
+        default:
+            AssertMsgFailed(("enmType=%d\n", enmType));
+            return VERR_INVALID_PARAMETER;
+    }
+
+    sched_setscheduler(current, iSchedClass, &Param);
+#endif
+
+    return VINF_SUCCESS;
+}
+
+
+DECLHIDDEN(int) rtThreadNativeAdopt(PRTTHREADINT pThread)
+{
+    return VERR_NOT_IMPLEMENTED;
+}
+
+
+DECLHIDDEN(void) rtThreadNativeWaitKludge(PRTTHREADINT pThread)
+{
+    /** @todo fix RTThreadWait/RTR0Term race on linux. */
+    RTThreadSleep(1); NOREF(pThread);
+}
+
+
+DECLHIDDEN(void) rtThreadNativeDestroy(PRTTHREADINT pThread)
+{
+    NOREF(pThread);
+}
+
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 4)
+/**
+ * Native kernel thread wrapper function.
+ *
+ * This will forward to rtThreadMain and do termination upon return.
+ *
+ * @param pvArg         Pointer to the argument package.
+ */
+static int rtThreadNativeMain(void *pvArg)
+{
+    PRTTHREADINT pThread = (PRTTHREADINT)pvArg;
+
+    rtThreadMain(pThread, (RTNATIVETHREAD)current, &pThread->szName[0]);
+    return 0;
+}
+#endif
+
+
+DECLHIDDEN(int) rtThreadNativeCreate(PRTTHREADINT pThreadInt, PRTNATIVETHREAD pNativeThread)
+{
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 4)
+    struct task_struct *NativeThread;
+    IPRT_LINUX_SAVE_EFL_AC();
+
+    RT_ASSERT_PREEMPTIBLE();
+
+    NativeThread = kthread_run(rtThreadNativeMain, pThreadInt, "iprt-%s", pThreadInt->szName);
+
+    if (!IS_ERR(NativeThread))
+    {
+        *pNativeThread = (RTNATIVETHREAD)NativeThread;
+        IPRT_LINUX_RESTORE_EFL_AC();
+        return VINF_SUCCESS;
+    }
+    IPRT_LINUX_RESTORE_EFL_AC();
+    return VERR_GENERAL_FAILURE;
+#else
+    return VERR_NOT_IMPLEMENTED;
+#endif
+}
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/r0drv/linux/time-r0drv-linux.c
@@ -0,0 +1,187 @@
+/* $Id: time-r0drv-linux.c $ */
+/** @file
+ * IPRT - Time, Ring-0 Driver, Linux.
+ */
+
+/*
+ * Copyright (C) 2006-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+
+/*********************************************************************************************************************************
+*   Header Files                                                                                                                 *
+*********************************************************************************************************************************/
+#define LOG_GROUP RTLOGGROUP_TIME
+#include "the-linux-kernel.h"
+#include "internal/iprt.h"
+#include <iprt/time.h>
+#include <iprt/asm.h>
+
+
+
+DECLINLINE(uint64_t) rtTimeGetSystemNanoTS(void)
+{
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 16) /* This must match timer-r0drv-linux.c! */
+    /*
+     * Use ktime_get_ts, this is also what clock_gettime(CLOCK_MONOTONIC,) is using.
+     */
+    uint64_t u64;
+    struct timespec Ts;
+    ktime_get_ts(&Ts);
+    u64 = Ts.tv_sec * RT_NS_1SEC_64 + Ts.tv_nsec;
+    return u64;
+
+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 60)
+    /*
+     * Seems there is no way of getting to the exact source of
+     * sys_clock_gettime(CLOCK_MONOTONIC, &ts) here, I think. But
+     * 64-bit jiffies adjusted for the initial value should be pretty
+     * much the same I hope.
+     */
+    uint64_t u64 = get_jiffies_64();
+# ifdef INITIAL_JIFFIES
+    u64 += INITIAL_JIFFIES;
+# endif
+    u64 *= TICK_NSEC;
+    return u64;
+
+#else   /* < 2.5.60 */
+# if BITS_PER_LONG >= 64
+    /*
+     * This is the same as above, except that there is no get_jiffies_64()
+     * here and we rely on long, and therefor jiffies, being 64-bit instead.
+     */
+    uint64_t u64 = jiffies;
+# ifdef INITIAL_JIFFIES
+    u64 += INITIAL_JIFFIES;
+# endif
+    u64 *= TICK_NSEC;
+    return u64;
+
+# else /* 32 bit jiffies */
+    /*
+     * We'll have to try track jiffy rollovers here or we'll be
+     * in trouble every time it flips.
+     *
+     * The high dword of the s_u64Last is the rollover count, the
+     * low dword is the previous jiffies.  Updating is done by
+     * atomic compare & exchange of course.
+     */
+    static uint64_t volatile s_u64Last = 0;
+    uint64_t u64;
+
+    for (;;)
+    {
+        uint64_t u64NewLast;
+        int32_t iDelta;
+        uint32_t cRollovers;
+        uint32_t u32LastJiffies;
+
+        /* sample the values */
+        unsigned long ulNow = jiffies;
+        uint64_t u64Last = s_u64Last;
+        if (ulNow != jiffies)
+            continue; /* try again */
+#  ifdef INITIAL_JIFFIES
+        ulNow += INITIAL_JIFFIES;
+#  endif
+
+        u32LastJiffies = (uint32_t)u64Last;
+        cRollovers = u64Last >> 32;
+
+        /*
+         * Check for rollover and update the static last value.
+         *
+         * We have to make sure we update it successfully to rule out
+         * an underrun because of racing someone.
+         */
+        iDelta = ulNow - u32LastJiffies;
+        if (iDelta < 0)
+        {
+            cRollovers++;
+            u64NewLast = RT_MAKE_U64(ulNow, cRollovers);
+            if (!ASMAtomicCmpXchgU64(&s_u64Last, u64NewLast, u64Last))
+                continue; /* race, try again */
+        }
+        else
+        {
+            u64NewLast = RT_MAKE_U64(ulNow, cRollovers);
+            ASMAtomicCmpXchgU64(&s_u64Last, u64NewLast, u64Last);
+        }
+
+        /* calculate the return value */
+        u64 = ulNow;
+        u64 *= TICK_NSEC;
+        u64 += cRollovers * (_4G * TICK_NSEC);
+        break;
+    }
+
+    return u64;
+# endif /* 32 bit jiffies */
+#endif  /* < 2.5.60 */
+}
+
+
+RTDECL(uint64_t) RTTimeNanoTS(void)
+{
+    return rtTimeGetSystemNanoTS();
+}
+RT_EXPORT_SYMBOL(RTTimeNanoTS);
+
+
+RTDECL(uint64_t) RTTimeMilliTS(void)
+{
+    return rtTimeGetSystemNanoTS() / RT_NS_1MS;
+}
+RT_EXPORT_SYMBOL(RTTimeMilliTS);
+
+
+RTDECL(uint64_t) RTTimeSystemNanoTS(void)
+{
+    return rtTimeGetSystemNanoTS();
+}
+RT_EXPORT_SYMBOL(RTTimeSystemNanoTS);
+
+
+RTDECL(uint64_t) RTTimeSystemMilliTS(void)
+{
+    return rtTimeGetSystemNanoTS() / RT_NS_1MS;
+}
+RT_EXPORT_SYMBOL(RTTimeSystemMilliTS);
+
+
+RTDECL(PRTTIMESPEC) RTTimeNow(PRTTIMESPEC pTime)
+{
+    IPRT_LINUX_SAVE_EFL_AC();
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 16)
+    struct timespec Ts;
+    ktime_get_real_ts(&Ts);
+    IPRT_LINUX_RESTORE_EFL_AC();
+    return RTTimeSpecSetTimespec(pTime, &Ts);
+
+#else   /* < 2.6.16 */
+    struct timeval Tv;
+    do_gettimeofday(&Tv);
+    IPRT_LINUX_RESTORE_EFL_AC();
+    return RTTimeSpecSetTimeval(pTime, &Tv);
+#endif
+}
+RT_EXPORT_SYMBOL(RTTimeNow);
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/r0drv/linux/timer-r0drv-linux.c
@@ -0,0 +1,1653 @@
+/* $Id: timer-r0drv-linux.c $ */
+/** @file
+ * IPRT - Timers, Ring-0 Driver, Linux.
+ */
+
+/*
+ * Copyright (C) 2006-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+
+/*********************************************************************************************************************************
+*   Header Files                                                                                                                 *
+*********************************************************************************************************************************/
+#include "the-linux-kernel.h"
+#include "internal/iprt.h"
+
+#include <iprt/timer.h>
+#include <iprt/time.h>
+#include <iprt/mp.h>
+#include <iprt/cpuset.h>
+#include <iprt/spinlock.h>
+#include <iprt/err.h>
+#include <iprt/asm.h>
+#include <iprt/assert.h>
+#include <iprt/alloc.h>
+
+#include "internal/magics.h"
+
+/** @def RTTIMER_LINUX_WITH_HRTIMER
+ * Whether to use high resolution timers.  */
+#if !defined(RTTIMER_LINUX_WITH_HRTIMER) \
+    && defined(IPRT_LINUX_HAS_HRTIMER)
+# define RTTIMER_LINUX_WITH_HRTIMER
+#endif
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 31)
+# define mod_timer_pinned               mod_timer
+# define HRTIMER_MODE_ABS_PINNED        HRTIMER_MODE_ABS
+#endif
+
+
+/*********************************************************************************************************************************
+*   Structures and Typedefs                                                                                                      *
+*********************************************************************************************************************************/
+/**
+ * Timer state machine.
+ *
+ * This is used to try handle the issues with MP events and
+ * timers that runs on all CPUs. It's relatively nasty :-/
+ */
+typedef enum RTTIMERLNXSTATE
+{
+    /** Stopped. */
+    RTTIMERLNXSTATE_STOPPED = 0,
+    /** Transient state; next ACTIVE. */
+    RTTIMERLNXSTATE_STARTING,
+    /** Transient state; next ACTIVE. (not really necessary) */
+    RTTIMERLNXSTATE_MP_STARTING,
+    /** Active. */
+    RTTIMERLNXSTATE_ACTIVE,
+    /** Active and in callback; next ACTIVE, STOPPED or CALLBACK_DESTROYING. */
+    RTTIMERLNXSTATE_CALLBACK,
+    /** Stopped while in the callback; next STOPPED. */
+    RTTIMERLNXSTATE_CB_STOPPING,
+    /** Restarted while in the callback; next ACTIVE, STOPPED, DESTROYING. */
+    RTTIMERLNXSTATE_CB_RESTARTING,
+    /** The callback shall destroy the timer; next STOPPED. */
+    RTTIMERLNXSTATE_CB_DESTROYING,
+    /** Transient state; next STOPPED. */
+    RTTIMERLNXSTATE_STOPPING,
+    /** Transient state; next STOPPED. */
+    RTTIMERLNXSTATE_MP_STOPPING,
+    /** The usual 32-bit hack. */
+    RTTIMERLNXSTATE_32BIT_HACK = 0x7fffffff
+} RTTIMERLNXSTATE;
+
+
+/**
+ * A Linux sub-timer.
+ */
+typedef struct RTTIMERLNXSUBTIMER
+{
+    /** Timer specific data.  */
+    union
+    {
+#if defined(RTTIMER_LINUX_WITH_HRTIMER)
+        /** High resolution timer. */
+        struct
+        {
+            /** The linux timer structure. */
+            struct hrtimer          LnxTimer;
+        } Hr;
+#endif
+        /** Standard timer. */
+        struct
+        {
+            /** The linux timer structure. */
+            struct timer_list       LnxTimer;
+            /** The start of the current run (ns).
+             * This is used to calculate when the timer ought to fire the next time. */
+            uint64_t                u64NextTS;
+            /** The u64NextTS in jiffies. */
+            unsigned long           ulNextJiffies;
+            /** Set when starting or changing the timer so that u64StartTs
+             *  and u64NextTS gets reinitialized (eliminating some jitter). */
+            bool volatile           fFirstAfterChg;
+        } Std;
+    } u;
+    /** The current tick number. */
+    uint64_t                iTick;
+    /** Restart the single shot timer at this specific time.
+     * Used when a single shot timer is restarted from the callback. */
+    uint64_t volatile       uNsRestartAt;
+    /** Pointer to the parent timer. */
+    PRTTIMER                pParent;
+    /** The current sub-timer state. */
+    RTTIMERLNXSTATE volatile enmState;
+} RTTIMERLNXSUBTIMER;
+/** Pointer to a linux sub-timer. */
+typedef RTTIMERLNXSUBTIMER *PRTTIMERLNXSUBTIMER;
+
+
+/**
+ * The internal representation of an Linux timer handle.
+ */
+typedef struct RTTIMER
+{
+    /** Magic.
+     * This is RTTIMER_MAGIC, but changes to something else before the timer
+     * is destroyed to indicate clearly that thread should exit. */
+    uint32_t volatile       u32Magic;
+    /** Spinlock synchronizing the fSuspended and MP event handling.
+     * This is NIL_RTSPINLOCK if cCpus == 1. */
+    RTSPINLOCK              hSpinlock;
+    /** Flag indicating that the timer is suspended. */
+    bool volatile           fSuspended;
+    /** Whether the timer must run on one specific CPU or not. */
+    bool                    fSpecificCpu;
+#ifdef CONFIG_SMP
+    /** Whether the timer must run on all CPUs or not. */
+    bool                    fAllCpus;
+#endif /* else: All -> specific on non-SMP kernels */
+    /** Whether it is a high resolution timer or a standard one. */
+    bool                    fHighRes;
+    /** The id of the CPU it must run on if fSpecificCpu is set. */
+    RTCPUID                 idCpu;
+    /** The number of CPUs this timer should run on. */
+    RTCPUID                 cCpus;
+    /** Callback. */
+    PFNRTTIMER              pfnTimer;
+    /** User argument. */
+    void                   *pvUser;
+    /** The timer interval. 0 if one-shot. */
+    uint64_t volatile       u64NanoInterval;
+    /** This is set to the number of jiffies between ticks if the interval is
+     * an exact number of jiffies. (Standard timers only.) */
+    unsigned long volatile  cJiffies;
+    /** The change interval spinlock for standard timers only. */
+    spinlock_t              ChgIntLock;
+    /** Workqueue item for delayed destruction. */
+    RTR0LNXWORKQUEUEITEM    DtorWorkqueueItem;
+    /** Sub-timers.
+     * Normally there is just one, but for RTTIMER_FLAGS_CPU_ALL this will contain
+     * an entry for all possible cpus. In that case the index will be the same as
+     * for the RTCpuSet. */
+    RTTIMERLNXSUBTIMER      aSubTimers[1];
+} RTTIMER;
+
+
+/**
+ * A rtTimerLinuxStartOnCpu and rtTimerLinuxStartOnCpu argument package.
+ */
+typedef struct RTTIMERLINUXSTARTONCPUARGS
+{
+    /** The current time (RTTimeSystemNanoTS). */
+    uint64_t                u64Now;
+    /** When to start firing (delta). */
+    uint64_t                u64First;
+} RTTIMERLINUXSTARTONCPUARGS;
+/** Pointer to a rtTimerLinuxStartOnCpu argument package. */
+typedef RTTIMERLINUXSTARTONCPUARGS *PRTTIMERLINUXSTARTONCPUARGS;
+
+
+/*********************************************************************************************************************************
+*   Internal Functions                                                                                                           *
+*********************************************************************************************************************************/
+#ifdef CONFIG_SMP
+static DECLCALLBACK(void) rtTimerLinuxMpEvent(RTMPEVENT enmEvent, RTCPUID idCpu, void *pvUser);
+#endif
+
+#if 0
+#define DEBUG_HACKING
+#include <iprt/string.h>
+#include <iprt/asm-amd64-x86.h>
+static void myLogBackdoorPrintf(const char *pszFormat, ...)
+{
+    char        szTmp[256];
+    va_list     args;
+    size_t      cb;
+
+    cb = RTStrPrintf(szTmp, sizeof(szTmp) - 10, "%d: ", RTMpCpuId());
+    va_start(args, pszFormat);
+    cb += RTStrPrintfV(&szTmp[cb], sizeof(szTmp) - cb, pszFormat, args);
+    va_end(args);
+
+    ASMOutStrU8(0x504, (uint8_t *)&szTmp[0], cb);
+}
+# define RTAssertMsg1Weak(pszExpr, uLine, pszFile, pszFunction) \
+    myLogBackdoorPrintf("\n!!Guest Assertion failed!!\n%s(%d) %s\n%s\n", uLine, pszFile, pszFunction, (pszExpr))
+# define RTAssertMsg2Weak myLogBackdoorPrintf
+# define RTTIMERLNX_LOG(a)          myLogBackdoorPrintf a
+#else
+# define RTTIMERLNX_LOG(a)          do { } while (0)
+#endif
+
+/**
+ * Sets the state.
+ */
+DECLINLINE(void) rtTimerLnxSetState(RTTIMERLNXSTATE volatile *penmState, RTTIMERLNXSTATE enmNewState)
+{
+#ifdef DEBUG_HACKING
+    RTTIMERLNX_LOG(("set %d -> %d\n", *penmState, enmNewState));
+#endif
+    ASMAtomicWriteU32((uint32_t volatile *)penmState, enmNewState);
+}
+
+
+/**
+ * Sets the state if it has a certain value.
+ *
+ * @return true if xchg was done.
+ * @return false if xchg wasn't done.
+ */
+#ifdef DEBUG_HACKING
+#define rtTimerLnxCmpXchgState(penmState, enmNewState, enmCurState) rtTimerLnxCmpXchgStateDebug(penmState, enmNewState, enmCurState, __LINE__)
+static bool rtTimerLnxCmpXchgStateDebug(RTTIMERLNXSTATE volatile *penmState, RTTIMERLNXSTATE enmNewState,
+                                        RTTIMERLNXSTATE enmCurState, uint32_t uLine)
+{
+    RTTIMERLNXSTATE enmOldState = enmCurState;
+    bool fRc = ASMAtomicCmpXchgExU32((uint32_t volatile *)penmState, enmNewState, enmCurState, (uint32_t *)&enmOldState);
+    RTTIMERLNX_LOG(("cxg %d -> %d - %d at %u\n", enmOldState, enmNewState, fRc, uLine));
+    return fRc;
+}
+#else
+DECLINLINE(bool) rtTimerLnxCmpXchgState(RTTIMERLNXSTATE volatile *penmState, RTTIMERLNXSTATE enmNewState,
+                                        RTTIMERLNXSTATE enmCurState)
+{
+    return ASMAtomicCmpXchgU32((uint32_t volatile *)penmState, enmNewState, enmCurState);
+}
+#endif
+
+
+/**
+ * Gets the state.
+ */
+DECLINLINE(RTTIMERLNXSTATE) rtTimerLnxGetState(RTTIMERLNXSTATE volatile *penmState)
+{
+    return (RTTIMERLNXSTATE)ASMAtomicUoReadU32((uint32_t volatile *)penmState);
+}
+
+#ifdef RTTIMER_LINUX_WITH_HRTIMER
+
+/**
+ * Converts a nano second time stamp to ktime_t.
+ *
+ * ASSUMES RTTimeSystemNanoTS() is implemented using ktime_get_ts().
+ *
+ * @returns ktime_t.
+ * @param   cNanoSecs   Nanoseconds.
+ */
+DECLINLINE(ktime_t) rtTimerLnxNanoToKt(uint64_t cNanoSecs)
+{
+    /* With some luck the compiler optimizes the division out of this... (Bet it doesn't.) */
+    return ktime_set(cNanoSecs / 1000000000, cNanoSecs % 1000000000);
+}
+
+/**
+ * Converts ktime_t to a nano second time stamp.
+ *
+ * ASSUMES RTTimeSystemNanoTS() is implemented using ktime_get_ts().
+ *
+ * @returns nano second time stamp.
+ * @param   Kt          ktime_t.
+ */
+DECLINLINE(uint64_t) rtTimerLnxKtToNano(ktime_t Kt)
+{
+    return ktime_to_ns(Kt);
+}
+
+#endif /* RTTIMER_LINUX_WITH_HRTIMER */
+
+/**
+ * Converts a nano second interval to jiffies.
+ *
+ * @returns Jiffies.
+ * @param   cNanoSecs   Nanoseconds.
+ */
+DECLINLINE(unsigned long) rtTimerLnxNanoToJiffies(uint64_t cNanoSecs)
+{
+    /* this can be made even better... */
+    if (cNanoSecs > (uint64_t)TICK_NSEC * MAX_JIFFY_OFFSET)
+        return MAX_JIFFY_OFFSET;
+# if ARCH_BITS == 32
+    if (RT_LIKELY(cNanoSecs <= UINT32_MAX))
+        return ((uint32_t)cNanoSecs + (TICK_NSEC-1)) / TICK_NSEC;
+# endif
+    return (cNanoSecs + (TICK_NSEC-1)) / TICK_NSEC;
+}
+
+
+/**
+ * Starts a sub-timer (RTTimerStart).
+ *
+ * @param   pSubTimer   The sub-timer to start.
+ * @param   u64Now      The current timestamp (RTTimeSystemNanoTS()).
+ * @param   u64First    The interval from u64Now to the first time the timer should fire.
+ * @param   fPinned     true = timer pinned to a specific CPU,
+ *                      false = timer can migrate between CPUs
+ * @param   fHighRes    Whether the user requested a high resolution timer or not.
+ * @param   enmOldState The old timer state.
+ */
+static void rtTimerLnxStartSubTimer(PRTTIMERLNXSUBTIMER pSubTimer, uint64_t u64Now, uint64_t u64First,
+                                    bool fPinned, bool fHighRes)
+{
+    /*
+     * Calc when it should start firing.
+     */
+    uint64_t u64NextTS = u64Now + u64First;
+    if (!fHighRes)
+        pSubTimer->u.Std.u64NextTS = u64NextTS;
+    RTTIMERLNX_LOG(("startsubtimer %p\n", pSubTimer->pParent));
+
+    pSubTimer->iTick = 0;
+
+#ifdef RTTIMER_LINUX_WITH_HRTIMER
+    if (fHighRes)
+        hrtimer_start(&pSubTimer->u.Hr.LnxTimer, rtTimerLnxNanoToKt(u64NextTS),
+                      fPinned ? HRTIMER_MODE_ABS_PINNED : HRTIMER_MODE_ABS);
+    else
+#endif
+    {
+        unsigned long cJiffies = !u64First ? 0 : rtTimerLnxNanoToJiffies(u64First);
+        pSubTimer->u.Std.ulNextJiffies  = jiffies + cJiffies;
+        pSubTimer->u.Std.fFirstAfterChg = true;
+#ifdef CONFIG_SMP
+        if (fPinned)
+            mod_timer_pinned(&pSubTimer->u.Std.LnxTimer, pSubTimer->u.Std.ulNextJiffies);
+        else
+#endif
+            mod_timer(&pSubTimer->u.Std.LnxTimer, pSubTimer->u.Std.ulNextJiffies);
+    }
+
+    /* Be a bit careful here since we could be racing the callback. */
+    if (!rtTimerLnxCmpXchgState(&pSubTimer->enmState, RTTIMERLNXSTATE_ACTIVE, RTTIMERLNXSTATE_STARTING))
+        rtTimerLnxCmpXchgState(&pSubTimer->enmState, RTTIMERLNXSTATE_ACTIVE, RTTIMERLNXSTATE_MP_STARTING);
+}
+
+
+/**
+ * Stops a sub-timer (RTTimerStart and rtTimerLinuxMpEvent()).
+ *
+ * The caller has already changed the state, so we will not be in a callback
+ * situation wrt to the calling thread.
+ *
+ * @param   pSubTimer   The sub-timer.
+ * @param   fHighRes    Whether the user requested a high resolution timer or not.
+ */
+static void rtTimerLnxStopSubTimer(PRTTIMERLNXSUBTIMER pSubTimer, bool fHighRes)
+{
+    RTTIMERLNX_LOG(("stopsubtimer %p %d\n", pSubTimer->pParent, fHighRes));
+#ifdef RTTIMER_LINUX_WITH_HRTIMER
+    if (fHighRes)
+    {
+        /* There is no equivalent to del_timer in the hrtimer API,
+           hrtimer_cancel() == del_timer_sync().  Just like the WARN_ON in
+           del_timer_sync() asserts, waiting for a timer callback to complete
+           is deadlock prone, so don't do it.  */
+        int rc = hrtimer_try_to_cancel(&pSubTimer->u.Hr.LnxTimer);
+        if (rc < 0)
+        {
+            hrtimer_start(&pSubTimer->u.Hr.LnxTimer, ktime_set(KTIME_SEC_MAX, 0), HRTIMER_MODE_ABS);
+            hrtimer_try_to_cancel(&pSubTimer->u.Hr.LnxTimer);
+        }
+    }
+    else
+#endif
+        del_timer(&pSubTimer->u.Std.LnxTimer);
+
+    rtTimerLnxSetState(&pSubTimer->enmState, RTTIMERLNXSTATE_STOPPED);
+}
+
+
+/**
+ * Used by RTTimerDestroy and rtTimerLnxCallbackDestroy to do the actual work.
+ *
+ * @param   pTimer  The timer in question.
+ */
+static void rtTimerLnxDestroyIt(PRTTIMER pTimer)
+{
+    RTSPINLOCK  hSpinlock = pTimer->hSpinlock;
+    RTCPUID     iCpu;
+    Assert(pTimer->fSuspended);
+    RTTIMERLNX_LOG(("destroyit %p\n", pTimer));
+
+    /*
+     * Remove the MP notifications first because it'll reduce the risk of
+     * us overtaking any MP event that might theoretically be racing us here.
+     */
+#ifdef CONFIG_SMP
+    if (    pTimer->cCpus > 1
+        &&  hSpinlock != NIL_RTSPINLOCK)
+    {
+        int rc = RTMpNotificationDeregister(rtTimerLinuxMpEvent, pTimer);
+        AssertRC(rc);
+    }
+#endif /* CONFIG_SMP */
+
+    /*
+     * Invalidate the handle.
+     */
+    ASMAtomicWriteU32(&pTimer->u32Magic, ~RTTIMER_MAGIC);
+
+    /*
+     * Make sure all timers have stopped executing since we're stopping them in
+     * an asynchronous manner up in rtTimerLnxStopSubTimer.
+     */
+    iCpu = pTimer->cCpus;
+    while (iCpu-- > 0)
+    {
+#ifdef RTTIMER_LINUX_WITH_HRTIMER
+        if (pTimer->fHighRes)
+            hrtimer_cancel(&pTimer->aSubTimers[iCpu].u.Hr.LnxTimer);
+        else
+#endif
+            del_timer_sync(&pTimer->aSubTimers[iCpu].u.Std.LnxTimer);
+    }
+
+    /*
+     * Finally, free the resources.
+     */
+    RTMemFreeEx(pTimer, RT_OFFSETOF(RTTIMER, aSubTimers[pTimer->cCpus]));
+    if (hSpinlock != NIL_RTSPINLOCK)
+        RTSpinlockDestroy(hSpinlock);
+}
+
+
+/**
+ * Workqueue callback (no DECLCALLBACK!) for deferred destruction.
+ *
+ * @param   pWork        Pointer to the DtorWorkqueueItem member of our timer
+ *                       structure.
+ */
+static void rtTimerLnxDestroyDeferred(RTR0LNXWORKQUEUEITEM *pWork)
+{
+    PRTTIMER pTimer = RT_FROM_MEMBER(pWork, RTTIMER, DtorWorkqueueItem);
+    rtTimerLnxDestroyIt(pTimer);
+}
+
+
+/**
+ * Called when the timer was destroyed by the callback function.
+ *
+ * @param   pTimer      The timer.
+ * @param   pSubTimer   The sub-timer which we're handling, the state of this
+ *                      will be RTTIMERLNXSTATE_CALLBACK_DESTROYING.
+ */
+static void rtTimerLnxCallbackDestroy(PRTTIMER pTimer, PRTTIMERLNXSUBTIMER pSubTimer)
+{
+    /*
+     * If it's an omni timer, the last dude does the destroying.
+     */
+    if (pTimer->cCpus > 1)
+    {
+        uint32_t        iCpu        = pTimer->cCpus;
+        RTSpinlockAcquire(pTimer->hSpinlock);
+
+        Assert(pSubTimer->enmState == RTTIMERLNXSTATE_CB_DESTROYING);
+        rtTimerLnxSetState(&pSubTimer->enmState, RTTIMERLNXSTATE_STOPPED);
+
+        while (iCpu-- > 0)
+            if (rtTimerLnxGetState(&pTimer->aSubTimers[iCpu].enmState) != RTTIMERLNXSTATE_STOPPED)
+            {
+                RTSpinlockRelease(pTimer->hSpinlock);
+                return;
+            }
+
+        RTSpinlockRelease(pTimer->hSpinlock);
+    }
+
+    /*
+     * Destroying a timer from the callback is unsafe since the callout code
+     * might be touching the timer structure upon return (hrtimer does!).  So,
+     * we have to defer the actual destruction to the IRPT workqueue.
+     */
+    rtR0LnxWorkqueuePush(&pTimer->DtorWorkqueueItem, rtTimerLnxDestroyDeferred);
+}
+
+
+#ifdef CONFIG_SMP
+/**
+ * Deal with a sub-timer that has migrated.
+ *
+ * @param   pTimer          The timer.
+ * @param   pSubTimer       The sub-timer.
+ */
+static void rtTimerLnxCallbackHandleMigration(PRTTIMER pTimer, PRTTIMERLNXSUBTIMER pSubTimer)
+{
+    RTTIMERLNXSTATE enmState;
+    if (pTimer->cCpus > 1)
+        RTSpinlockAcquire(pTimer->hSpinlock);
+
+    do
+    {
+        enmState = rtTimerLnxGetState(&pSubTimer->enmState);
+        switch (enmState)
+        {
+            case RTTIMERLNXSTATE_STOPPING:
+            case RTTIMERLNXSTATE_MP_STOPPING:
+                enmState = RTTIMERLNXSTATE_STOPPED;
+            case RTTIMERLNXSTATE_STOPPED:
+                break;
+
+            default:
+                AssertMsgFailed(("%d\n", enmState));
+            case RTTIMERLNXSTATE_STARTING:
+            case RTTIMERLNXSTATE_MP_STARTING:
+            case RTTIMERLNXSTATE_ACTIVE:
+            case RTTIMERLNXSTATE_CALLBACK:
+            case RTTIMERLNXSTATE_CB_STOPPING:
+            case RTTIMERLNXSTATE_CB_RESTARTING:
+                if (rtTimerLnxCmpXchgState(&pSubTimer->enmState, RTTIMERLNXSTATE_STOPPED, enmState))
+                    enmState = RTTIMERLNXSTATE_STOPPED;
+                break;
+
+            case RTTIMERLNXSTATE_CB_DESTROYING:
+            {
+                if (pTimer->cCpus > 1)
+                    RTSpinlockRelease(pTimer->hSpinlock);
+
+                rtTimerLnxCallbackDestroy(pTimer, pSubTimer);
+                return;
+            }
+        }
+    } while (enmState != RTTIMERLNXSTATE_STOPPED);
+
+    if (pTimer->cCpus > 1)
+        RTSpinlockRelease(pTimer->hSpinlock);
+}
+#endif /* CONFIG_SMP */
+
+
+/**
+ * The slow path of rtTimerLnxChangeToCallbackState.
+ *
+ * @returns true if changed successfully, false if not.
+ * @param   pSubTimer       The sub-timer.
+ */
+static bool rtTimerLnxChangeToCallbackStateSlow(PRTTIMERLNXSUBTIMER pSubTimer)
+{
+    for (;;)
+    {
+        RTTIMERLNXSTATE enmState = rtTimerLnxGetState(&pSubTimer->enmState);
+        switch (enmState)
+        {
+            case RTTIMERLNXSTATE_ACTIVE:
+            case RTTIMERLNXSTATE_STARTING:
+            case RTTIMERLNXSTATE_MP_STARTING:
+                if (rtTimerLnxCmpXchgState(&pSubTimer->enmState, RTTIMERLNXSTATE_CALLBACK, enmState))
+                    return true;
+                break;
+
+            case RTTIMERLNXSTATE_CALLBACK:
+            case RTTIMERLNXSTATE_CB_STOPPING:
+            case RTTIMERLNXSTATE_CB_RESTARTING:
+            case RTTIMERLNXSTATE_CB_DESTROYING:
+                AssertMsgFailed(("%d\n", enmState));
+            default:
+                return false;
+        }
+        ASMNopPause();
+    }
+}
+
+
+/**
+ * Tries to change the sub-timer state to 'callback'.
+ *
+ * @returns true if changed successfully, false if not.
+ * @param   pSubTimer       The sub-timer.
+ */
+DECLINLINE(bool) rtTimerLnxChangeToCallbackState(PRTTIMERLNXSUBTIMER pSubTimer)
+{
+    if (RT_LIKELY(rtTimerLnxCmpXchgState(&pSubTimer->enmState, RTTIMERLNXSTATE_CALLBACK, RTTIMERLNXSTATE_ACTIVE)))
+        return true;
+    return rtTimerLnxChangeToCallbackStateSlow(pSubTimer);
+}
+
+
+#ifdef RTTIMER_LINUX_WITH_HRTIMER
+/**
+ * Timer callback function for high resolution timers.
+ *
+ * @returns HRTIMER_NORESTART or HRTIMER_RESTART depending on whether it's a
+ *          one-shot or interval timer.
+ * @param   pHrTimer    Pointer to the sub-timer structure.
+ */
+static enum hrtimer_restart rtTimerLinuxHrCallback(struct hrtimer *pHrTimer)
+{
+    PRTTIMERLNXSUBTIMER     pSubTimer = RT_FROM_MEMBER(pHrTimer, RTTIMERLNXSUBTIMER, u.Hr.LnxTimer);
+    PRTTIMER                pTimer    = pSubTimer->pParent;
+
+
+    RTTIMERLNX_LOG(("hrcallback %p\n", pTimer));
+    if (RT_UNLIKELY(!rtTimerLnxChangeToCallbackState(pSubTimer)))
+        return HRTIMER_NORESTART;
+
+#ifdef CONFIG_SMP
+    /*
+     * Check for unwanted migration.
+     */
+    if (pTimer->fAllCpus || pTimer->fSpecificCpu)
+    {
+        RTCPUID idCpu = RTMpCpuId();
+        if (RT_UNLIKELY(  pTimer->fAllCpus
+                        ? (RTCPUID)(pSubTimer - &pTimer->aSubTimers[0]) != idCpu
+                        : pTimer->idCpu != idCpu))
+        {
+            rtTimerLnxCallbackHandleMigration(pTimer, pSubTimer);
+            return HRTIMER_NORESTART;
+        }
+    }
+#endif
+
+    if (pTimer->u64NanoInterval)
+    {
+        /*
+         * Periodic timer, run it and update the native timer afterwards so
+         * we can handle RTTimerStop and RTTimerChangeInterval from the
+         * callback as well as a racing control thread.
+         */
+        pTimer->pfnTimer(pTimer, pTimer->pvUser, ++pSubTimer->iTick);
+        hrtimer_add_expires_ns(&pSubTimer->u.Hr.LnxTimer, ASMAtomicReadU64(&pTimer->u64NanoInterval));
+        if (RT_LIKELY(rtTimerLnxCmpXchgState(&pSubTimer->enmState, RTTIMERLNXSTATE_ACTIVE, RTTIMERLNXSTATE_CALLBACK)))
+            return HRTIMER_RESTART;
+    }
+    else
+    {
+        /*
+         * One shot timer (no omni), stop it before dispatching it.
+         * Allow RTTimerStart as well as RTTimerDestroy to be called from
+         * the callback.
+         */
+        ASMAtomicWriteBool(&pTimer->fSuspended, true);
+        pTimer->pfnTimer(pTimer, pTimer->pvUser, ++pSubTimer->iTick);
+        if (RT_LIKELY(rtTimerLnxCmpXchgState(&pSubTimer->enmState, RTTIMERLNXSTATE_STOPPED, RTTIMERLNXSTATE_CALLBACK)))
+            return HRTIMER_NORESTART;
+    }
+
+    /*
+     * Some state change occurred while we were in the callback routine.
+     */
+    for (;;)
+    {
+        RTTIMERLNXSTATE enmState = rtTimerLnxGetState(&pSubTimer->enmState);
+        switch (enmState)
+        {
+            case RTTIMERLNXSTATE_CB_DESTROYING:
+                rtTimerLnxCallbackDestroy(pTimer, pSubTimer);
+                return HRTIMER_NORESTART;
+
+            case RTTIMERLNXSTATE_CB_STOPPING:
+                if (rtTimerLnxCmpXchgState(&pSubTimer->enmState, RTTIMERLNXSTATE_STOPPED, RTTIMERLNXSTATE_CB_STOPPING))
+                    return HRTIMER_NORESTART;
+                break;
+
+            case RTTIMERLNXSTATE_CB_RESTARTING:
+                if (rtTimerLnxCmpXchgState(&pSubTimer->enmState, RTTIMERLNXSTATE_ACTIVE, RTTIMERLNXSTATE_CB_RESTARTING))
+                {
+                    pSubTimer->iTick = 0;
+                    hrtimer_set_expires(&pSubTimer->u.Hr.LnxTimer, rtTimerLnxNanoToKt(pSubTimer->uNsRestartAt));
+                    return HRTIMER_RESTART;
+                }
+                break;
+
+            default:
+                AssertMsgFailed(("%d\n", enmState));
+                return HRTIMER_NORESTART;
+        }
+        ASMNopPause();
+    }
+}
+#endif /* RTTIMER_LINUX_WITH_HRTIMER */
+
+
+/**
+ * Timer callback function for standard timers.
+ *
+ * @param   ulUser      Address of the sub-timer structure.
+ */
+static void rtTimerLinuxStdCallback(unsigned long ulUser)
+{
+    PRTTIMERLNXSUBTIMER pSubTimer = (PRTTIMERLNXSUBTIMER)ulUser;
+    PRTTIMER            pTimer    = pSubTimer->pParent;
+
+    RTTIMERLNX_LOG(("stdcallback %p\n", pTimer));
+    if (RT_UNLIKELY(!rtTimerLnxChangeToCallbackState(pSubTimer)))
+        return;
+
+#ifdef CONFIG_SMP
+    /*
+     * Check for unwanted migration.
+     */
+    if (pTimer->fAllCpus || pTimer->fSpecificCpu)
+    {
+        RTCPUID idCpu = RTMpCpuId();
+        if (RT_UNLIKELY(  pTimer->fAllCpus
+                        ? (RTCPUID)(pSubTimer - &pTimer->aSubTimers[0]) != idCpu
+                        : pTimer->idCpu != idCpu))
+        {
+            rtTimerLnxCallbackHandleMigration(pTimer, pSubTimer);
+            return;
+        }
+    }
+#endif
+
+    if (pTimer->u64NanoInterval)
+    {
+        /*
+         * Interval timer, calculate the next timeout.
+         *
+         * The first time around, we'll re-adjust the u.Std.u64NextTS to
+         * try prevent some jittering if we were started at a bad time.
+         */
+        const uint64_t  iTick = ++pSubTimer->iTick;
+        uint64_t        u64NanoInterval;
+        unsigned long   cJiffies;
+        unsigned long   flFlags;
+
+        spin_lock_irqsave(&pTimer->ChgIntLock, flFlags);
+        u64NanoInterval = pTimer->u64NanoInterval;
+        cJiffies        = pTimer->cJiffies;
+        if (RT_UNLIKELY(pSubTimer->u.Std.fFirstAfterChg))
+        {
+            pSubTimer->u.Std.fFirstAfterChg = false;
+            pSubTimer->u.Std.u64NextTS      = RTTimeSystemNanoTS();
+            pSubTimer->u.Std.ulNextJiffies  = jiffies;
+        }
+        spin_unlock_irqrestore(&pTimer->ChgIntLock, flFlags);
+
+        pSubTimer->u.Std.u64NextTS += u64NanoInterval;
+        if (cJiffies)
+        {
+            pSubTimer->u.Std.ulNextJiffies += cJiffies;
+            /* Prevent overflows when the jiffies counter wraps around.
+             * Special thanks to Ken Preslan for helping debugging! */
+            while (time_before(pSubTimer->u.Std.ulNextJiffies, jiffies))
+            {
+                pSubTimer->u.Std.ulNextJiffies += cJiffies;
+                pSubTimer->u.Std.u64NextTS     += u64NanoInterval;
+            }
+        }
+        else
+        {
+            const uint64_t u64NanoTS = RTTimeSystemNanoTS();
+            while (pSubTimer->u.Std.u64NextTS < u64NanoTS)
+                pSubTimer->u.Std.u64NextTS += u64NanoInterval;
+            pSubTimer->u.Std.ulNextJiffies = jiffies + rtTimerLnxNanoToJiffies(pSubTimer->u.Std.u64NextTS - u64NanoTS);
+        }
+
+        /*
+         * Run the timer and re-arm it unless the state changed                                                                                                        .
+         *                                                                                                                                                             .
+         * We must re-arm it afterwards as we're not in a position to undo this                                                                                        .
+         * operation if for instance someone stopped or destroyed us while we                                                                                          .
+         * were in the callback.  (Linux takes care of any races here.)
+         */
+        pTimer->pfnTimer(pTimer, pTimer->pvUser, iTick);
+        if (RT_LIKELY(rtTimerLnxCmpXchgState(&pSubTimer->enmState, RTTIMERLNXSTATE_ACTIVE, RTTIMERLNXSTATE_CALLBACK)))
+        {
+#ifdef CONFIG_SMP
+            if (pTimer->fSpecificCpu || pTimer->fAllCpus)
+                mod_timer_pinned(&pSubTimer->u.Std.LnxTimer, pSubTimer->u.Std.ulNextJiffies);
+            else
+#endif
+                mod_timer(&pSubTimer->u.Std.LnxTimer, pSubTimer->u.Std.ulNextJiffies);
+            return;
+        }
+    }
+    else
+    {
+        /*
+         * One shot timer, stop it before dispatching it.
+         * Allow RTTimerStart as well as RTTimerDestroy to be called from
+         * the callback.
+         */
+        ASMAtomicWriteBool(&pTimer->fSuspended, true);
+        pTimer->pfnTimer(pTimer, pTimer->pvUser, ++pSubTimer->iTick);
+        if (RT_LIKELY(rtTimerLnxCmpXchgState(&pSubTimer->enmState, RTTIMERLNXSTATE_STOPPED, RTTIMERLNXSTATE_CALLBACK)))
+            return;
+    }
+
+    /*
+     * Some state change occurred while we were in the callback routine.
+     */
+    for (;;)
+    {
+        RTTIMERLNXSTATE enmState = rtTimerLnxGetState(&pSubTimer->enmState);
+        switch (enmState)
+        {
+            case RTTIMERLNXSTATE_CB_DESTROYING:
+                rtTimerLnxCallbackDestroy(pTimer, pSubTimer);
+                return;
+
+            case RTTIMERLNXSTATE_CB_STOPPING:
+                if (rtTimerLnxCmpXchgState(&pSubTimer->enmState, RTTIMERLNXSTATE_STOPPED, RTTIMERLNXSTATE_CB_STOPPING))
+                    return;
+                break;
+
+            case RTTIMERLNXSTATE_CB_RESTARTING:
+                if (rtTimerLnxCmpXchgState(&pSubTimer->enmState, RTTIMERLNXSTATE_ACTIVE, RTTIMERLNXSTATE_CB_RESTARTING))
+                {
+                    uint64_t        u64NanoTS;
+                    uint64_t        u64NextTS;
+                    unsigned long   flFlags;
+
+                    spin_lock_irqsave(&pTimer->ChgIntLock, flFlags);
+                    u64NextTS = pSubTimer->uNsRestartAt;
+                    u64NanoTS = RTTimeSystemNanoTS();
+                    pSubTimer->iTick                = 0;
+                    pSubTimer->u.Std.u64NextTS      = u64NextTS;
+                    pSubTimer->u.Std.fFirstAfterChg = true;
+                    pSubTimer->u.Std.ulNextJiffies  = u64NextTS > u64NanoTS
+                                                    ? jiffies + rtTimerLnxNanoToJiffies(u64NextTS - u64NanoTS)
+                                                    : jiffies;
+                    spin_unlock_irqrestore(&pTimer->ChgIntLock, flFlags);
+
+#ifdef CONFIG_SMP
+                    if (pTimer->fSpecificCpu || pTimer->fAllCpus)
+                        mod_timer_pinned(&pSubTimer->u.Std.LnxTimer, pSubTimer->u.Std.ulNextJiffies);
+                    else
+#endif
+                        mod_timer(&pSubTimer->u.Std.LnxTimer, pSubTimer->u.Std.ulNextJiffies);
+                    return;
+                }
+                break;
+
+            default:
+                AssertMsgFailed(("%d\n", enmState));
+                return;
+        }
+        ASMNopPause();
+    }
+}
+
+
+#ifdef CONFIG_SMP
+
+/**
+ * Per-cpu callback function (RTMpOnAll/RTMpOnSpecific).
+ *
+ * @param   idCpu       The current CPU.
+ * @param   pvUser1     Pointer to the timer.
+ * @param   pvUser2     Pointer to the argument structure.
+ */
+static DECLCALLBACK(void) rtTimerLnxStartAllOnCpu(RTCPUID idCpu, void *pvUser1, void *pvUser2)
+{
+    PRTTIMERLINUXSTARTONCPUARGS pArgs = (PRTTIMERLINUXSTARTONCPUARGS)pvUser2;
+    PRTTIMER pTimer = (PRTTIMER)pvUser1;
+    Assert(idCpu < pTimer->cCpus);
+    rtTimerLnxStartSubTimer(&pTimer->aSubTimers[idCpu], pArgs->u64Now, pArgs->u64First, true /*fPinned*/, pTimer->fHighRes);
+}
+
+
+/**
+ * Worker for RTTimerStart() that takes care of the ugly bits.
+ *
+ * @returns RTTimerStart() return value.
+ * @param   pTimer      The timer.
+ * @param   pArgs       The argument structure.
+ */
+static int rtTimerLnxOmniStart(PRTTIMER pTimer, PRTTIMERLINUXSTARTONCPUARGS pArgs)
+{
+    RTCPUID         iCpu;
+    RTCPUSET        OnlineSet;
+    RTCPUSET        OnlineSet2;
+    int             rc2;
+
+    /*
+     * Prepare all the sub-timers for the startup and then flag the timer
+     * as a whole as non-suspended, make sure we get them all before
+     * clearing fSuspended as the MP handler will be waiting on this
+     * should something happen while we're looping.
+     */
+    RTSpinlockAcquire(pTimer->hSpinlock);
+
+    /* Just make it a omni timer restriction that no stop/start races are allowed. */
+    for (iCpu = 0; iCpu < pTimer->cCpus; iCpu++)
+        if (rtTimerLnxGetState(&pTimer->aSubTimers[iCpu].enmState) != RTTIMERLNXSTATE_STOPPED)
+        {
+            RTSpinlockRelease(pTimer->hSpinlock);
+            return VERR_TIMER_BUSY;
+        }
+
+    do
+    {
+        RTMpGetOnlineSet(&OnlineSet);
+        for (iCpu = 0; iCpu < pTimer->cCpus; iCpu++)
+        {
+            Assert(pTimer->aSubTimers[iCpu].enmState != RTTIMERLNXSTATE_MP_STOPPING);
+            rtTimerLnxSetState(&pTimer->aSubTimers[iCpu].enmState,
+                               RTCpuSetIsMember(&OnlineSet, iCpu)
+                               ? RTTIMERLNXSTATE_STARTING
+                               : RTTIMERLNXSTATE_STOPPED);
+        }
+    } while (!RTCpuSetIsEqual(&OnlineSet, RTMpGetOnlineSet(&OnlineSet2)));
+
+    ASMAtomicWriteBool(&pTimer->fSuspended, false);
+
+    RTSpinlockRelease(pTimer->hSpinlock);
+
+    /*
+     * Start them (can't find any exported function that allows me to
+     * do this without the cross calls).
+     */
+    pArgs->u64Now = RTTimeSystemNanoTS();
+    rc2 = RTMpOnAll(rtTimerLnxStartAllOnCpu, pTimer, pArgs);
+    AssertRC(rc2); /* screw this if it fails. */
+
+    /*
+     * Reset the sub-timers who didn't start up (ALL CPUs case).
+     */
+    RTSpinlockAcquire(pTimer->hSpinlock);
+
+    for (iCpu = 0; iCpu < pTimer->cCpus; iCpu++)
+        if (rtTimerLnxCmpXchgState(&pTimer->aSubTimers[iCpu].enmState, RTTIMERLNXSTATE_STOPPED, RTTIMERLNXSTATE_STARTING))
+        {
+            /** @todo very odd case for a rainy day. Cpus that temporarily went offline while
+             * we were between calls needs to nudged as the MP handler will ignore events for
+             * them because of the STARTING state. This is an extremely unlikely case - not that
+             * that means anything in my experience... ;-) */
+            RTTIMERLNX_LOG(("what!? iCpu=%u -> didn't start\n", iCpu));
+        }
+
+    RTSpinlockRelease(pTimer->hSpinlock);
+
+    return VINF_SUCCESS;
+}
+
+
+/**
+ * Worker for RTTimerStop() that takes care of the ugly SMP bits.
+ *
+ * @returns true if there was any active callbacks, false if not.
+ * @param   pTimer      The timer (valid).
+ * @param   fForDestroy Whether this is for RTTimerDestroy or not.
+ */
+static bool rtTimerLnxOmniStop(PRTTIMER pTimer, bool fForDestroy)
+{
+    bool            fActiveCallbacks = false;
+    RTCPUID         iCpu;
+    RTTIMERLNXSTATE enmState;
+
+
+    /*
+     * Mark the timer as suspended and flag all timers as stopping, except
+     * for those being stopped by an MP event.
+     */
+    RTSpinlockAcquire(pTimer->hSpinlock);
+
+    ASMAtomicWriteBool(&pTimer->fSuspended, true);
+    for (iCpu = 0; iCpu < pTimer->cCpus; iCpu++)
+    {
+        for (;;)
+        {
+            enmState = rtTimerLnxGetState(&pTimer->aSubTimers[iCpu].enmState);
+            if (    enmState == RTTIMERLNXSTATE_STOPPED
+                ||  enmState == RTTIMERLNXSTATE_MP_STOPPING)
+                break;
+            if (   enmState == RTTIMERLNXSTATE_CALLBACK
+                || enmState == RTTIMERLNXSTATE_CB_STOPPING
+                || enmState == RTTIMERLNXSTATE_CB_RESTARTING)
+            {
+                Assert(enmState != RTTIMERLNXSTATE_CB_STOPPING || fForDestroy);
+                if (rtTimerLnxCmpXchgState(&pTimer->aSubTimers[iCpu].enmState,
+                                           !fForDestroy ? RTTIMERLNXSTATE_CB_STOPPING : RTTIMERLNXSTATE_CB_DESTROYING,
+                                           enmState))
+                {
+                    fActiveCallbacks = true;
+                    break;
+                }
+            }
+            else
+            {
+                Assert(enmState == RTTIMERLNXSTATE_ACTIVE);
+                if (rtTimerLnxCmpXchgState(&pTimer->aSubTimers[iCpu].enmState, RTTIMERLNXSTATE_STOPPING, enmState))
+                    break;
+            }
+            ASMNopPause();
+        }
+    }
+
+    RTSpinlockRelease(pTimer->hSpinlock);
+
+    /*
+     * Do the actual stopping. Fortunately, this doesn't require any IPIs.
+     * Unfortunately it cannot be done synchronously.
+     */
+    for (iCpu = 0; iCpu < pTimer->cCpus; iCpu++)
+        if (rtTimerLnxGetState(&pTimer->aSubTimers[iCpu].enmState) == RTTIMERLNXSTATE_STOPPING)
+            rtTimerLnxStopSubTimer(&pTimer->aSubTimers[iCpu], pTimer->fHighRes);
+
+    return fActiveCallbacks;
+}
+
+
+/**
+ * Per-cpu callback function (RTMpOnSpecific) used by rtTimerLinuxMpEvent()
+ * to start a sub-timer on a cpu that just have come online.
+ *
+ * @param   idCpu       The current CPU.
+ * @param   pvUser1     Pointer to the timer.
+ * @param   pvUser2     Pointer to the argument structure.
+ */
+static DECLCALLBACK(void) rtTimerLinuxMpStartOnCpu(RTCPUID idCpu, void *pvUser1, void *pvUser2)
+{
+    PRTTIMERLINUXSTARTONCPUARGS pArgs = (PRTTIMERLINUXSTARTONCPUARGS)pvUser2;
+    PRTTIMER pTimer = (PRTTIMER)pvUser1;
+    RTSPINLOCK hSpinlock;
+    Assert(idCpu < pTimer->cCpus);
+
+    /*
+     * We have to be kind of careful here as we might be racing RTTimerStop
+     * (and/or RTTimerDestroy, thus the paranoia.
+     */
+    hSpinlock = pTimer->hSpinlock;
+    if (    hSpinlock != NIL_RTSPINLOCK
+        &&  pTimer->u32Magic == RTTIMER_MAGIC)
+    {
+        RTSpinlockAcquire(hSpinlock);
+
+        if (    !ASMAtomicUoReadBool(&pTimer->fSuspended)
+            &&  pTimer->u32Magic == RTTIMER_MAGIC)
+        {
+            /* We're sane and the timer is not suspended yet. */
+            PRTTIMERLNXSUBTIMER pSubTimer = &pTimer->aSubTimers[idCpu];
+            if (rtTimerLnxCmpXchgState(&pSubTimer->enmState, RTTIMERLNXSTATE_MP_STARTING, RTTIMERLNXSTATE_STOPPED))
+                rtTimerLnxStartSubTimer(pSubTimer, pArgs->u64Now, pArgs->u64First, true /*fPinned*/, pTimer->fHighRes);
+        }
+
+        RTSpinlockRelease(hSpinlock);
+    }
+}
+
+
+/**
+ * MP event notification callback.
+ *
+ * @param   enmEvent    The event.
+ * @param   idCpu       The cpu it applies to.
+ * @param   pvUser      The timer.
+ */
+static DECLCALLBACK(void) rtTimerLinuxMpEvent(RTMPEVENT enmEvent, RTCPUID idCpu, void *pvUser)
+{
+    PRTTIMER            pTimer    = (PRTTIMER)pvUser;
+    PRTTIMERLNXSUBTIMER pSubTimer = &pTimer->aSubTimers[idCpu];
+    RTSPINLOCK          hSpinlock;
+
+    Assert(idCpu < pTimer->cCpus);
+
+    /*
+     * Some initial paranoia.
+     */
+    if (pTimer->u32Magic != RTTIMER_MAGIC)
+        return;
+    hSpinlock = pTimer->hSpinlock;
+    if (hSpinlock == NIL_RTSPINLOCK)
+        return;
+
+    RTSpinlockAcquire(hSpinlock);
+
+    /* Is it active? */
+    if (    !ASMAtomicUoReadBool(&pTimer->fSuspended)
+        &&  pTimer->u32Magic == RTTIMER_MAGIC)
+    {
+        switch (enmEvent)
+        {
+            /*
+             * Try do it without leaving the spin lock, but if we have to, retake it
+             * when we're on the right cpu.
+             */
+            case RTMPEVENT_ONLINE:
+                if (rtTimerLnxCmpXchgState(&pSubTimer->enmState, RTTIMERLNXSTATE_MP_STARTING, RTTIMERLNXSTATE_STOPPED))
+                {
+                    RTTIMERLINUXSTARTONCPUARGS Args;
+                    Args.u64Now = RTTimeSystemNanoTS();
+                    Args.u64First = 0;
+
+                    if (RTMpCpuId() == idCpu)
+                        rtTimerLnxStartSubTimer(pSubTimer, Args.u64Now, Args.u64First, true /*fPinned*/, pTimer->fHighRes);
+                    else
+                    {
+                        rtTimerLnxSetState(&pSubTimer->enmState, RTTIMERLNXSTATE_STOPPED); /* we'll recheck it. */
+                        RTSpinlockRelease(hSpinlock);
+
+                        RTMpOnSpecific(idCpu, rtTimerLinuxMpStartOnCpu, pTimer, &Args);
+                        return; /* we've left the spinlock */
+                    }
+                }
+                break;
+
+            /*
+             * The CPU is (going) offline, make sure the sub-timer is stopped.
+             *
+             * Linux will migrate it to a different CPU, but we don't want this. The
+             * timer function is checking for this.
+             */
+            case RTMPEVENT_OFFLINE:
+            {
+                RTTIMERLNXSTATE enmState;
+                while (   (enmState = rtTimerLnxGetState(&pSubTimer->enmState)) == RTTIMERLNXSTATE_ACTIVE
+                       || enmState == RTTIMERLNXSTATE_CALLBACK
+                       || enmState == RTTIMERLNXSTATE_CB_RESTARTING)
+                {
+                    if (enmState == RTTIMERLNXSTATE_ACTIVE)
+                    {
+                        if (rtTimerLnxCmpXchgState(&pSubTimer->enmState, RTTIMERLNXSTATE_MP_STOPPING, RTTIMERLNXSTATE_ACTIVE))
+                        {
+                            RTSpinlockRelease(hSpinlock);
+
+                            rtTimerLnxStopSubTimer(pSubTimer, pTimer->fHighRes);
+                            return; /* we've left the spinlock */
+                        }
+                    }
+                    else if (rtTimerLnxCmpXchgState(&pSubTimer->enmState, RTTIMERLNXSTATE_CB_STOPPING, enmState))
+                        break;
+
+                    /* State not stable, try again. */
+                    ASMNopPause();
+                }
+                break;
+            }
+        }
+    }
+
+    RTSpinlockRelease(hSpinlock);
+}
+
+#endif /* CONFIG_SMP */
+
+
+/**
+ * Callback function use by RTTimerStart via RTMpOnSpecific to start a timer
+ * running on a specific CPU.
+ *
+ * @param   idCpu       The current CPU.
+ * @param   pvUser1     Pointer to the timer.
+ * @param   pvUser2     Pointer to the argument structure.
+ */
+static DECLCALLBACK(void) rtTimerLnxStartOnSpecificCpu(RTCPUID idCpu, void *pvUser1, void *pvUser2)
+{
+    PRTTIMERLINUXSTARTONCPUARGS pArgs = (PRTTIMERLINUXSTARTONCPUARGS)pvUser2;
+    PRTTIMER pTimer = (PRTTIMER)pvUser1;
+    rtTimerLnxStartSubTimer(&pTimer->aSubTimers[0], pArgs->u64Now, pArgs->u64First, true /*fPinned*/, pTimer->fHighRes);
+}
+
+
+RTDECL(int) RTTimerStart(PRTTIMER pTimer, uint64_t u64First)
+{
+    RTTIMERLINUXSTARTONCPUARGS Args;
+    int rc2;
+    IPRT_LINUX_SAVE_EFL_AC();
+
+    /*
+     * Validate.
+     */
+    AssertPtrReturn(pTimer, VERR_INVALID_HANDLE);
+    AssertReturn(pTimer->u32Magic == RTTIMER_MAGIC, VERR_INVALID_HANDLE);
+
+    if (!ASMAtomicUoReadBool(&pTimer->fSuspended))
+        return VERR_TIMER_ACTIVE;
+    RTTIMERLNX_LOG(("start %p cCpus=%d\n", pTimer, pTimer->cCpus));
+
+    Args.u64First = u64First;
+#ifdef CONFIG_SMP
+    /*
+     * Omni timer?
+     */
+    if (pTimer->fAllCpus)
+    {
+        rc2 = rtTimerLnxOmniStart(pTimer, &Args);
+        IPRT_LINUX_RESTORE_EFL_AC();
+        return rc2;
+    }
+#endif
+
+    /*
+     * Simple timer - Pretty straight forward if it wasn't for restarting.
+     */
+    Args.u64Now = RTTimeSystemNanoTS();
+    ASMAtomicWriteU64(&pTimer->aSubTimers[0].uNsRestartAt, Args.u64Now + u64First);
+    for (;;)
+    {
+        RTTIMERLNXSTATE enmState = rtTimerLnxGetState(&pTimer->aSubTimers[0].enmState);
+        switch (enmState)
+        {
+            case RTTIMERLNXSTATE_STOPPED:
+                if (rtTimerLnxCmpXchgState(&pTimer->aSubTimers[0].enmState, RTTIMERLNXSTATE_STARTING, RTTIMERLNXSTATE_STOPPED))
+                {
+                    ASMAtomicWriteBool(&pTimer->fSuspended, false);
+                    if (!pTimer->fSpecificCpu)
+                        rtTimerLnxStartSubTimer(&pTimer->aSubTimers[0], Args.u64Now, Args.u64First,
+                                                false /*fPinned*/, pTimer->fHighRes);
+                    else
+                    {
+                        rc2 = RTMpOnSpecific(pTimer->idCpu, rtTimerLnxStartOnSpecificCpu, pTimer, &Args);
+                        if (RT_FAILURE(rc2))
+                        {
+                            /* Suspend it, the cpu id is probably invalid or offline. */
+                            ASMAtomicWriteBool(&pTimer->fSuspended, true);
+                            rtTimerLnxSetState(&pTimer->aSubTimers[0].enmState, RTTIMERLNXSTATE_STOPPED);
+                            return rc2;
+                        }
+                    }
+                    IPRT_LINUX_RESTORE_EFL_AC();
+                    return VINF_SUCCESS;
+                }
+                break;
+
+            case RTTIMERLNXSTATE_CALLBACK:
+            case RTTIMERLNXSTATE_CB_STOPPING:
+                if (rtTimerLnxCmpXchgState(&pTimer->aSubTimers[0].enmState, RTTIMERLNXSTATE_CB_RESTARTING, enmState))
+                {
+                    ASMAtomicWriteBool(&pTimer->fSuspended, false);
+                    IPRT_LINUX_RESTORE_EFL_AC();
+                    return VINF_SUCCESS;
+                }
+                break;
+
+            default:
+                AssertMsgFailed(("%d\n", enmState));
+                IPRT_LINUX_RESTORE_EFL_AC();
+                return VERR_INTERNAL_ERROR_4;
+        }
+        ASMNopPause();
+    }
+}
+RT_EXPORT_SYMBOL(RTTimerStart);
+
+
+/**
+ * Common worker for RTTimerStop and RTTimerDestroy.
+ *
+ * @returns true if there was any active callbacks, false if not.
+ * @param   pTimer              The timer to stop.
+ * @param   fForDestroy         Whether it's RTTimerDestroy calling or not.
+ */
+static bool rtTimerLnxStop(PRTTIMER pTimer, bool fForDestroy)
+{
+    RTTIMERLNX_LOG(("lnxstop %p %d\n", pTimer, fForDestroy));
+#ifdef CONFIG_SMP
+    /*
+     * Omni timer?
+     */
+    if (pTimer->fAllCpus)
+        return rtTimerLnxOmniStop(pTimer, fForDestroy);
+#endif
+
+    /*
+     * Simple timer.
+     */
+    ASMAtomicWriteBool(&pTimer->fSuspended, true);
+    for (;;)
+    {
+        RTTIMERLNXSTATE enmState = rtTimerLnxGetState(&pTimer->aSubTimers[0].enmState);
+        switch (enmState)
+        {
+            case RTTIMERLNXSTATE_ACTIVE:
+                if (rtTimerLnxCmpXchgState(&pTimer->aSubTimers[0].enmState, RTTIMERLNXSTATE_STOPPING, RTTIMERLNXSTATE_ACTIVE))
+                {
+                    rtTimerLnxStopSubTimer(&pTimer->aSubTimers[0], pTimer->fHighRes);
+                    return false;
+                }
+                break;
+
+            case RTTIMERLNXSTATE_CALLBACK:
+            case RTTIMERLNXSTATE_CB_RESTARTING:
+            case RTTIMERLNXSTATE_CB_STOPPING:
+                Assert(enmState != RTTIMERLNXSTATE_CB_STOPPING || fForDestroy);
+                if (rtTimerLnxCmpXchgState(&pTimer->aSubTimers[0].enmState,
+                                           !fForDestroy ? RTTIMERLNXSTATE_CB_STOPPING : RTTIMERLNXSTATE_CB_DESTROYING,
+                                           enmState))
+                    return true;
+                break;
+
+            case RTTIMERLNXSTATE_STOPPED:
+                return VINF_SUCCESS;
+
+            case RTTIMERLNXSTATE_CB_DESTROYING:
+                AssertMsgFailed(("enmState=%d pTimer=%p\n", enmState, pTimer));
+                return true;
+
+            default:
+            case RTTIMERLNXSTATE_STARTING:
+            case RTTIMERLNXSTATE_MP_STARTING:
+            case RTTIMERLNXSTATE_STOPPING:
+            case RTTIMERLNXSTATE_MP_STOPPING:
+                AssertMsgFailed(("enmState=%d pTimer=%p\n", enmState, pTimer));
+                return false;
+        }
+
+        /* State not stable, try again. */
+        ASMNopPause();
+    }
+}
+
+
+RTDECL(int) RTTimerStop(PRTTIMER pTimer)
+{
+    /*
+     * Validate.
+     */
+    IPRT_LINUX_SAVE_EFL_AC();
+    AssertPtrReturn(pTimer, VERR_INVALID_HANDLE);
+    AssertReturn(pTimer->u32Magic == RTTIMER_MAGIC, VERR_INVALID_HANDLE);
+    RTTIMERLNX_LOG(("stop %p\n", pTimer));
+
+    if (ASMAtomicUoReadBool(&pTimer->fSuspended))
+        return VERR_TIMER_SUSPENDED;
+
+    rtTimerLnxStop(pTimer, false /*fForDestroy*/);
+
+    IPRT_LINUX_RESTORE_EFL_AC();
+    return VINF_SUCCESS;
+}
+RT_EXPORT_SYMBOL(RTTimerStop);
+
+
+RTDECL(int) RTTimerChangeInterval(PRTTIMER pTimer, uint64_t u64NanoInterval)
+{
+    unsigned long cJiffies;
+    unsigned long flFlags;
+    IPRT_LINUX_SAVE_EFL_AC();
+
+    /*
+     * Validate.
+     */
+    AssertPtrReturn(pTimer, VERR_INVALID_HANDLE);
+    AssertReturn(pTimer->u32Magic == RTTIMER_MAGIC, VERR_INVALID_HANDLE);
+    AssertReturn(u64NanoInterval, VERR_INVALID_PARAMETER);
+    AssertReturn(u64NanoInterval < UINT64_MAX / 8, VERR_INVALID_PARAMETER);
+    AssertReturn(pTimer->u64NanoInterval, VERR_INVALID_STATE);
+    RTTIMERLNX_LOG(("change %p %llu\n", pTimer, u64NanoInterval));
+
+#ifdef RTTIMER_LINUX_WITH_HRTIMER
+    /*
+     * For the high resolution timers it is easy since we don't care so much
+     * about when it is applied to the sub-timers.
+     */
+    if (pTimer->fHighRes)
+    {
+        ASMAtomicWriteU64(&pTimer->u64NanoInterval, u64NanoInterval);
+        IPRT_LINUX_RESTORE_EFL_AC();
+        return VINF_SUCCESS;
+    }
+#endif
+
+    /*
+     * Standard timers have a bit more complicated way of calculating
+     * their interval and such. So, forget omni timers for now.
+     */
+    if (pTimer->cCpus > 1)
+        return VERR_NOT_SUPPORTED;
+
+    cJiffies = u64NanoInterval / RTTimerGetSystemGranularity();
+    if (cJiffies * RTTimerGetSystemGranularity() != u64NanoInterval)
+        cJiffies = 0;
+
+    spin_lock_irqsave(&pTimer->ChgIntLock, flFlags);
+    pTimer->aSubTimers[0].u.Std.fFirstAfterChg = true;
+    pTimer->cJiffies = cJiffies;
+    ASMAtomicWriteU64(&pTimer->u64NanoInterval, u64NanoInterval);
+    spin_unlock_irqrestore(&pTimer->ChgIntLock, flFlags);
+    IPRT_LINUX_RESTORE_EFL_AC();
+    return VINF_SUCCESS;
+}
+RT_EXPORT_SYMBOL(RTTimerChangeInterval);
+
+
+RTDECL(int) RTTimerDestroy(PRTTIMER pTimer)
+{
+    bool fCanDestroy;
+    IPRT_LINUX_SAVE_EFL_AC();
+
+    /*
+     * Validate. It's ok to pass NULL pointer.
+     */
+    if (pTimer == /*NIL_RTTIMER*/ NULL)
+        return VINF_SUCCESS;
+    AssertPtrReturn(pTimer, VERR_INVALID_HANDLE);
+    AssertReturn(pTimer->u32Magic == RTTIMER_MAGIC, VERR_INVALID_HANDLE);
+    RTTIMERLNX_LOG(("destroy %p\n", pTimer));
+/** @todo We should invalidate the magic here! */
+
+    /*
+     * Stop the timer if it's still active, then destroy it if we can.
+     */
+    if (!ASMAtomicUoReadBool(&pTimer->fSuspended))
+        fCanDestroy = rtTimerLnxStop(pTimer, true /*fForDestroy*/);
+    else
+    {
+        uint32_t        iCpu = pTimer->cCpus;
+        if (pTimer->cCpus > 1)
+            RTSpinlockAcquire(pTimer->hSpinlock);
+
+        fCanDestroy = true;
+        while (iCpu-- > 0)
+        {
+            for (;;)
+            {
+                RTTIMERLNXSTATE enmState = rtTimerLnxGetState(&pTimer->aSubTimers[iCpu].enmState);
+                switch (enmState)
+                {
+                    case RTTIMERLNXSTATE_CALLBACK:
+                    case RTTIMERLNXSTATE_CB_RESTARTING:
+                    case RTTIMERLNXSTATE_CB_STOPPING:
+                        if (!rtTimerLnxCmpXchgState(&pTimer->aSubTimers[iCpu].enmState, RTTIMERLNXSTATE_CB_DESTROYING, enmState))
+                            continue;
+                        fCanDestroy = false;
+                        break;
+
+                    case RTTIMERLNXSTATE_CB_DESTROYING:
+                        AssertMsgFailed(("%d\n", enmState));
+                        fCanDestroy = false;
+                        break;
+                    default:
+                        break;
+                }
+                break;
+            }
+        }
+
+        if (pTimer->cCpus > 1)
+            RTSpinlockRelease(pTimer->hSpinlock);
+    }
+
+    if (fCanDestroy)
+    {
+        /* For paranoid reasons, defer actually destroying the semaphore when
+           in atomic or interrupt context. */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 32)
+        if (in_atomic() || in_interrupt())
+#else
+        if (in_interrupt())
+#endif
+            rtR0LnxWorkqueuePush(&pTimer->DtorWorkqueueItem, rtTimerLnxDestroyDeferred);
+        else
+            rtTimerLnxDestroyIt(pTimer);
+    }
+
+    IPRT_LINUX_RESTORE_EFL_AC();
+    return VINF_SUCCESS;
+}
+RT_EXPORT_SYMBOL(RTTimerDestroy);
+
+
+RTDECL(int) RTTimerCreateEx(PRTTIMER *ppTimer, uint64_t u64NanoInterval, uint32_t fFlags, PFNRTTIMER pfnTimer, void *pvUser)
+{
+    PRTTIMER    pTimer;
+    RTCPUID     iCpu;
+    unsigned    cCpus;
+    int         rc;
+    IPRT_LINUX_SAVE_EFL_AC();
+
+    rtR0LnxWorkqueueFlush();                /* for 2.4 */
+    *ppTimer = NULL;
+
+    /*
+     * Validate flags.
+     */
+    if (!RTTIMER_FLAGS_ARE_VALID(fFlags))
+    {
+        IPRT_LINUX_RESTORE_EFL_AC();
+        return VERR_INVALID_PARAMETER;
+    }
+    if (    (fFlags & RTTIMER_FLAGS_CPU_SPECIFIC)
+        &&  (fFlags & RTTIMER_FLAGS_CPU_ALL) != RTTIMER_FLAGS_CPU_ALL
+        &&  !RTMpIsCpuPossible(RTMpCpuIdFromSetIndex(fFlags & RTTIMER_FLAGS_CPU_MASK)))
+    {
+        IPRT_LINUX_RESTORE_EFL_AC();
+        return VERR_CPU_NOT_FOUND;
+    }
+
+    /*
+     * Allocate the timer handler.
+     */
+    cCpus = 1;
+#ifdef CONFIG_SMP
+    if ((fFlags & RTTIMER_FLAGS_CPU_ALL) == RTTIMER_FLAGS_CPU_ALL)
+    {
+        cCpus = RTMpGetMaxCpuId() + 1;
+        Assert(cCpus <= RTCPUSET_MAX_CPUS); /* On linux we have a 1:1 relationship between cpuid and set index. */
+        AssertReturnStmt(u64NanoInterval, IPRT_LINUX_RESTORE_EFL_AC(), VERR_NOT_IMPLEMENTED); /* We don't implement single shot on all cpus, sorry. */
+    }
+#endif
+
+    rc = RTMemAllocEx(RT_OFFSETOF(RTTIMER, aSubTimers[cCpus]), 0,
+                      RTMEMALLOCEX_FLAGS_ZEROED | RTMEMALLOCEX_FLAGS_ANY_CTX_FREE, (void **)&pTimer);
+    if (RT_FAILURE(rc))
+    {
+        IPRT_LINUX_RESTORE_EFL_AC();
+        return rc;
+    }
+
+    /*
+     * Initialize it.
+     */
+    pTimer->u32Magic        = RTTIMER_MAGIC;
+    pTimer->hSpinlock       = NIL_RTSPINLOCK;
+    pTimer->fSuspended      = true;
+    pTimer->fHighRes        = !!(fFlags & RTTIMER_FLAGS_HIGH_RES);
+#ifdef CONFIG_SMP
+    pTimer->fSpecificCpu    = (fFlags & RTTIMER_FLAGS_CPU_SPECIFIC) && (fFlags & RTTIMER_FLAGS_CPU_ALL) != RTTIMER_FLAGS_CPU_ALL;
+    pTimer->fAllCpus        = (fFlags & RTTIMER_FLAGS_CPU_ALL) == RTTIMER_FLAGS_CPU_ALL;
+    pTimer->idCpu           = pTimer->fSpecificCpu
+                            ? RTMpCpuIdFromSetIndex(fFlags & RTTIMER_FLAGS_CPU_MASK)
+                            : NIL_RTCPUID;
+#else
+    pTimer->fSpecificCpu    = !!(fFlags & RTTIMER_FLAGS_CPU_SPECIFIC);
+    pTimer->idCpu           = RTMpCpuId();
+#endif
+    pTimer->cCpus           = cCpus;
+    pTimer->pfnTimer        = pfnTimer;
+    pTimer->pvUser          = pvUser;
+    pTimer->u64NanoInterval = u64NanoInterval;
+    pTimer->cJiffies        = u64NanoInterval / RTTimerGetSystemGranularity();
+    if (pTimer->cJiffies * RTTimerGetSystemGranularity() != u64NanoInterval)
+        pTimer->cJiffies    = 0;
+    spin_lock_init(&pTimer->ChgIntLock);
+
+    for (iCpu = 0; iCpu < cCpus; iCpu++)
+    {
+#ifdef RTTIMER_LINUX_WITH_HRTIMER
+        if (pTimer->fHighRes)
+        {
+            hrtimer_init(&pTimer->aSubTimers[iCpu].u.Hr.LnxTimer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
+            pTimer->aSubTimers[iCpu].u.Hr.LnxTimer.function     = rtTimerLinuxHrCallback;
+        }
+        else
+#endif
+        {
+            init_timer(&pTimer->aSubTimers[iCpu].u.Std.LnxTimer);
+            pTimer->aSubTimers[iCpu].u.Std.LnxTimer.data        = (unsigned long)&pTimer->aSubTimers[iCpu];
+            pTimer->aSubTimers[iCpu].u.Std.LnxTimer.function    = rtTimerLinuxStdCallback;
+            pTimer->aSubTimers[iCpu].u.Std.LnxTimer.expires     = jiffies;
+            pTimer->aSubTimers[iCpu].u.Std.u64NextTS            = 0;
+        }
+        pTimer->aSubTimers[iCpu].iTick      = 0;
+        pTimer->aSubTimers[iCpu].pParent    = pTimer;
+        pTimer->aSubTimers[iCpu].enmState   = RTTIMERLNXSTATE_STOPPED;
+    }
+
+#ifdef CONFIG_SMP
+    /*
+     * If this is running on ALL cpus, we'll have to register a callback
+     * for MP events (so timers can be started/stopped on cpus going
+     * online/offline). We also create the spinlock for synchronizing
+     * stop/start/mp-event.
+     */
+    if (cCpus > 1)
+    {
+        int rc = RTSpinlockCreate(&pTimer->hSpinlock, RTSPINLOCK_FLAGS_INTERRUPT_SAFE, "RTTimerLnx");
+        if (RT_SUCCESS(rc))
+            rc = RTMpNotificationRegister(rtTimerLinuxMpEvent, pTimer);
+        else
+            pTimer->hSpinlock = NIL_RTSPINLOCK;
+        if (RT_FAILURE(rc))
+        {
+            RTTimerDestroy(pTimer);
+            IPRT_LINUX_RESTORE_EFL_AC();
+            return rc;
+        }
+    }
+#endif /* CONFIG_SMP */
+
+    RTTIMERLNX_LOG(("create %p hires=%d fFlags=%#x cCpus=%u\n", pTimer, pTimer->fHighRes, fFlags, cCpus));
+    *ppTimer = pTimer;
+    IPRT_LINUX_RESTORE_EFL_AC();
+    return VINF_SUCCESS;
+}
+RT_EXPORT_SYMBOL(RTTimerCreateEx);
+
+
+RTDECL(uint32_t) RTTimerGetSystemGranularity(void)
+{
+#if 0 /** @todo Not sure if this is what we want or not... Add new API for
+       *        querying the resolution of the high res timers? */
+    struct timespec Ts;
+    int rc;
+    IPRT_LINUX_SAVE_EFL_AC();
+    rc = hrtimer_get_res(CLOCK_MONOTONIC, &Ts);
+    IPRT_LINUX_RESTORE_EFL_AC();
+    if (!rc)
+    {
+        Assert(!Ts.tv_sec);
+        return Ts.tv_nsec;
+    }
+#endif
+    return RT_NS_1SEC / HZ; /* ns */
+}
+RT_EXPORT_SYMBOL(RTTimerGetSystemGranularity);
+
+
+RTDECL(int) RTTimerRequestSystemGranularity(uint32_t u32Request, uint32_t *pu32Granted)
+{
+    return VERR_NOT_SUPPORTED;
+}
+RT_EXPORT_SYMBOL(RTTimerRequestSystemGranularity);
+
+
+RTDECL(int) RTTimerReleaseSystemGranularity(uint32_t u32Granted)
+{
+    return VERR_NOT_SUPPORTED;
+}
+RT_EXPORT_SYMBOL(RTTimerReleaseSystemGranularity);
+
+
+RTDECL(bool) RTTimerCanDoHighResolution(void)
+{
+#ifdef RTTIMER_LINUX_WITH_HRTIMER
+    return true;
+#else
+    return false;
+#endif
+}
+RT_EXPORT_SYMBOL(RTTimerCanDoHighResolution);
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/r0drv/linux/waitqueue-r0drv-linux.h
@@ -0,0 +1,286 @@
+/* $Id: waitqueue-r0drv-linux.h $ */
+/** @file
+ * IPRT - Linux Ring-0 Driver Helpers for Abstracting Wait Queues,
+ */
+
+/*
+ * Copyright (C) 2006-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+
+#ifndef ___r0drv_linux_waitqueue_r0drv_linux_h
+#define ___r0drv_linux_waitqueue_r0drv_linux_h
+
+#include "the-linux-kernel.h"
+
+#include <iprt/asm-math.h>
+#include <iprt/err.h>
+#include <iprt/string.h>
+#include <iprt/time.h>
+
+/** The resolution (nanoseconds) specified when using
+ *  schedule_hrtimeout_range. */
+#define RTR0SEMLNXWAIT_RESOLUTION   50000
+
+
+/**
+ * Kernel mode Linux wait state structure.
+ */
+typedef struct RTR0SEMLNXWAIT
+{
+    /** The wait queue entry. */
+    wait_queue_t    WaitQE;
+    /** The absolute timeout given as nano seconds since the start of the
+     *  monotonic clock. */
+    uint64_t        uNsAbsTimeout;
+    /** The timeout in nano seconds relative to the start of the wait. */
+    uint64_t        cNsRelTimeout;
+    /** The native timeout value. */
+    union
+    {
+#ifdef IPRT_LINUX_HAS_HRTIMER
+        /** The timeout when fHighRes is true. Absolute, so no updating. */
+        ktime_t     KtTimeout;
+#endif
+        /** The timeout when fHighRes is false.  Updated after waiting. */
+        long        lTimeout;
+    } u;
+    /** Set if we use high resolution timeouts. */
+    bool            fHighRes;
+    /** Set if it's an indefinite wait. */
+    bool            fIndefinite;
+    /** Set if we've already timed out.
+     * Set by rtR0SemLnxWaitDoIt and read by rtR0SemLnxWaitHasTimedOut. */
+    bool            fTimedOut;
+    /** TASK_INTERRUPTIBLE or TASK_UNINTERRUPTIBLE. */
+    int             iWaitState;
+    /** The wait queue. */
+    wait_queue_head_t *pWaitQueue;
+} RTR0SEMLNXWAIT;
+/** Pointer to a linux wait state. */
+typedef RTR0SEMLNXWAIT *PRTR0SEMLNXWAIT;
+
+
+/**
+ * Initializes a wait.
+ *
+ * The caller MUST check the wait condition BEFORE calling this function or the
+ * timeout logic will be flawed.
+ *
+ * @returns VINF_SUCCESS or VERR_TIMEOUT.
+ * @param   pWait               The wait structure.
+ * @param   fFlags              The wait flags.
+ * @param   uTimeout            The timeout.
+ * @param   pWaitQueue          The wait queue head.
+ */
+DECLINLINE(int) rtR0SemLnxWaitInit(PRTR0SEMLNXWAIT pWait, uint32_t fFlags, uint64_t uTimeout,
+                                   wait_queue_head_t *pWaitQueue)
+{
+    /*
+     * Process the flags and timeout.
+     */
+    if (!(fFlags & RTSEMWAIT_FLAGS_INDEFINITE))
+    {
+/** @todo optimize: millisecs -> nanosecs -> millisec -> jiffies */
+        if (fFlags & RTSEMWAIT_FLAGS_MILLISECS)
+            uTimeout = uTimeout < UINT64_MAX / RT_US_1SEC * RT_US_1SEC
+                     ? uTimeout * RT_US_1SEC
+                     : UINT64_MAX;
+        if (uTimeout == UINT64_MAX)
+            fFlags |= RTSEMWAIT_FLAGS_INDEFINITE;
+        else
+        {
+            uint64_t u64Now;
+            if (fFlags & RTSEMWAIT_FLAGS_RELATIVE)
+            {
+                if (uTimeout == 0)
+                    return VERR_TIMEOUT;
+
+                u64Now = RTTimeSystemNanoTS();
+                pWait->cNsRelTimeout = uTimeout;
+                pWait->uNsAbsTimeout = u64Now + uTimeout;
+                if (pWait->uNsAbsTimeout < u64Now) /* overflow */
+                    fFlags |= RTSEMWAIT_FLAGS_INDEFINITE;
+            }
+            else
+            {
+                u64Now = RTTimeSystemNanoTS();
+                if (u64Now >= uTimeout)
+                    return VERR_TIMEOUT;
+
+                pWait->cNsRelTimeout = uTimeout - u64Now;
+                pWait->uNsAbsTimeout = uTimeout;
+            }
+        }
+    }
+
+    if (!(fFlags & RTSEMWAIT_FLAGS_INDEFINITE))
+    {
+        pWait->fIndefinite      = false;
+#ifdef IPRT_LINUX_HAS_HRTIMER
+        if (   (fFlags & (RTSEMWAIT_FLAGS_NANOSECS | RTSEMWAIT_FLAGS_ABSOLUTE))
+            || pWait->cNsRelTimeout < RT_NS_1SEC / HZ * 4)
+        {
+            pWait->fHighRes     = true;
+# if BITS_PER_LONG < 64
+            if (   KTIME_SEC_MAX <= LONG_MAX
+                && pWait->uNsAbsTimeout >= KTIME_SEC_MAX * RT_NS_1SEC_64 + (RT_NS_1SEC - 1))
+                fFlags |= RTSEMWAIT_FLAGS_INDEFINITE;
+            else
+# endif
+                pWait->u.KtTimeout  = ns_to_ktime(pWait->uNsAbsTimeout);
+        }
+        else
+#endif
+        {
+            uint64_t cJiffies = ASMMultU64ByU32DivByU32(pWait->cNsRelTimeout, HZ, RT_NS_1SEC);
+            if (cJiffies >= MAX_JIFFY_OFFSET)
+                fFlags |= RTSEMWAIT_FLAGS_INDEFINITE;
+            else
+            {
+                pWait->u.lTimeout   = (long)cJiffies;
+                pWait->fHighRes     = false;
+            }
+        }
+    }
+
+    if (fFlags & RTSEMWAIT_FLAGS_INDEFINITE)
+    {
+        pWait->fIndefinite      = true;
+        pWait->fHighRes         = false;
+        pWait->uNsAbsTimeout    = UINT64_MAX;
+        pWait->cNsRelTimeout    = UINT64_MAX;
+        pWait->u.lTimeout       = LONG_MAX;
+    }
+
+    pWait->fTimedOut   = false;
+
+    /*
+     * Initialize the wait queue related bits.
+     */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 39)
+    init_wait((&pWait->WaitQE));
+#else
+    RT_ZERO(pWait->WaitQE);
+    init_waitqueue_entry((&pWait->WaitQE), current);
+#endif
+    pWait->pWaitQueue = pWaitQueue;
+    pWait->iWaitState = fFlags & RTSEMWAIT_FLAGS_INTERRUPTIBLE
+                      ? TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE;
+
+    return VINF_SUCCESS;
+}
+
+
+/**
+ * Prepares the next wait.
+ *
+ * This must be called before rtR0SemLnxWaitDoIt, and the caller should check
+ * the exit conditions in-between the two calls.
+ *
+ * @param   pWait               The wait structure.
+ */
+DECLINLINE(void) rtR0SemLnxWaitPrepare(PRTR0SEMLNXWAIT pWait)
+{
+    /* Make everything thru schedule*() atomic scheduling wise. (Is this correct?) */
+    prepare_to_wait(pWait->pWaitQueue, &pWait->WaitQE, pWait->iWaitState);
+}
+
+
+/**
+ * Do the actual wait.
+ *
+ * @param   pWait               The wait structure.
+ */
+DECLINLINE(void) rtR0SemLnxWaitDoIt(PRTR0SEMLNXWAIT pWait)
+{
+    if (pWait->fIndefinite)
+        schedule();
+#ifdef IPRT_LINUX_HAS_HRTIMER
+    else if (pWait->fHighRes)
+    {
+        int rc = schedule_hrtimeout_range(&pWait->u.KtTimeout, HRTIMER_MODE_ABS, RTR0SEMLNXWAIT_RESOLUTION);
+        if (!rc)
+            pWait->fTimedOut = true;
+    }
+#endif
+    else
+    {
+        pWait->u.lTimeout = schedule_timeout(pWait->u.lTimeout);
+        if (pWait->u.lTimeout <= 0)
+            pWait->fTimedOut = true;
+    }
+    after_wait((&pWait->WaitQE));
+}
+
+
+/**
+ * Checks if a linux wait was interrupted.
+ *
+ * @returns true / false
+ * @param   pWait               The wait structure.
+ * @remarks This shall be called before the first rtR0SemLnxWaitDoIt().
+ */
+DECLINLINE(bool) rtR0SemLnxWaitWasInterrupted(PRTR0SEMLNXWAIT pWait)
+{
+    return pWait->iWaitState == TASK_INTERRUPTIBLE
+        && signal_pending(current);
+}
+
+
+/**
+ * Checks if a linux wait has timed out.
+ *
+ * @returns true / false
+ * @param   pWait               The wait structure.
+ */
+DECLINLINE(bool) rtR0SemLnxWaitHasTimedOut(PRTR0SEMLNXWAIT pWait)
+{
+    return pWait->fTimedOut;
+}
+
+
+/**
+ * Deletes a linux wait.
+ *
+ * @param   pWait               The wait structure.
+ */
+DECLINLINE(void) rtR0SemLnxWaitDelete(PRTR0SEMLNXWAIT pWait)
+{
+    finish_wait(pWait->pWaitQueue, &pWait->WaitQE);
+}
+
+
+/**
+ * Gets the max resolution of the timeout machinery.
+ *
+ * @returns Resolution specified in nanoseconds.
+ */
+DECLINLINE(uint32_t) rtR0SemLnxWaitGetResolution(void)
+{
+#ifdef IPRT_LINUX_HAS_HRTIMER
+    return RTR0SEMLNXWAIT_RESOLUTION;
+#else
+    return RT_NS_1SEC / HZ; /* ns */
+#endif
+}
+
+#endif
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/r0drv/memobj-r0drv.c
@@ -0,0 +1,783 @@
+/* $Id: memobj-r0drv.cpp $ */
+/** @file
+ * IPRT - Ring-0 Memory Objects, Common Code.
+ */
+
+/*
+ * Copyright (C) 2006-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+
+/*********************************************************************************************************************************
+*   Header Files                                                                                                                 *
+*********************************************************************************************************************************/
+#define LOG_GROUP RTLOGGROUP_DEFAULT ///@todo RTLOGGROUP_MEM
+#include <iprt/memobj.h>
+#include "internal/iprt.h"
+
+#include <iprt/alloc.h>
+#include <iprt/asm.h>
+#include <iprt/assert.h>
+#include <iprt/err.h>
+#include <iprt/log.h>
+#include <iprt/mp.h>
+#include <iprt/param.h>
+#include <iprt/process.h>
+#include <iprt/thread.h>
+
+#include "internal/memobj.h"
+
+
+/**
+ * Internal function for allocating a new memory object.
+ *
+ * @returns The allocated and initialized handle.
+ * @param   cbSelf      The size of the memory object handle. 0 mean default size.
+ * @param   enmType     The memory object type.
+ * @param   pv          The memory object mapping.
+ * @param   cb          The size of the memory object.
+ */
+DECLHIDDEN(PRTR0MEMOBJINTERNAL) rtR0MemObjNew(size_t cbSelf, RTR0MEMOBJTYPE enmType, void *pv, size_t cb)
+{
+    PRTR0MEMOBJINTERNAL pNew;
+
+    /* validate the size */
+    if (!cbSelf)
+        cbSelf = sizeof(*pNew);
+    Assert(cbSelf >= sizeof(*pNew));
+    Assert(cbSelf == (uint32_t)cbSelf);
+    AssertMsg(RT_ALIGN_Z(cb, PAGE_SIZE) == cb, ("%#zx\n", cb));
+
+    /*
+     * Allocate and initialize the object.
+     */
+    pNew = (PRTR0MEMOBJINTERNAL)RTMemAllocZ(cbSelf);
+    if (pNew)
+    {
+        pNew->u32Magic  = RTR0MEMOBJ_MAGIC;
+        pNew->cbSelf    = (uint32_t)cbSelf;
+        pNew->enmType   = enmType;
+        pNew->fFlags    = 0;
+        pNew->cb        = cb;
+        pNew->pv        = pv;
+    }
+    return pNew;
+}
+
+
+/**
+ * Deletes an incomplete memory object.
+ *
+ * This is for cleaning up after failures during object creation.
+ *
+ * @param   pMem    The incomplete memory object to delete.
+ */
+DECLHIDDEN(void) rtR0MemObjDelete(PRTR0MEMOBJINTERNAL pMem)
+{
+    if (pMem)
+    {
+        ASMAtomicUoWriteU32(&pMem->u32Magic, ~RTR0MEMOBJ_MAGIC);
+        pMem->enmType = RTR0MEMOBJTYPE_END;
+        RTMemFree(pMem);
+    }
+}
+
+
+/**
+ * Links a mapping object to a primary object.
+ *
+ * @returns IPRT status code.
+ * @retval  VINF_SUCCESS on success.
+ * @retval  VINF_NO_MEMORY if we couldn't expand the mapping array of the parent.
+ * @param   pParent     The parent (primary) memory object.
+ * @param   pChild      The child (mapping) memory object.
+ */
+static int rtR0MemObjLink(PRTR0MEMOBJINTERNAL pParent, PRTR0MEMOBJINTERNAL pChild)
+{
+    uint32_t i;
+
+    /* sanity */
+    Assert(rtR0MemObjIsMapping(pChild));
+    Assert(!rtR0MemObjIsMapping(pParent));
+
+    /* expand the array? */
+    i = pParent->uRel.Parent.cMappings;
+    if (i >= pParent->uRel.Parent.cMappingsAllocated)
+    {
+        void *pv = RTMemRealloc(pParent->uRel.Parent.papMappings,
+                                (i + 32) * sizeof(pParent->uRel.Parent.papMappings[0]));
+        if (!pv)
+            return VERR_NO_MEMORY;
+        pParent->uRel.Parent.papMappings = (PPRTR0MEMOBJINTERNAL)pv;
+        pParent->uRel.Parent.cMappingsAllocated = i + 32;
+        Assert(i == pParent->uRel.Parent.cMappings);
+    }
+
+    /* do the linking. */
+    pParent->uRel.Parent.papMappings[i] = pChild;
+    pParent->uRel.Parent.cMappings++;
+    pChild->uRel.Child.pParent = pParent;
+
+    return VINF_SUCCESS;
+}
+
+
+/**
+ * Checks if this is mapping or not.
+ *
+ * @returns true if it's a mapping, otherwise false.
+ * @param   MemObj      The ring-0 memory object handle.
+ */
+RTR0DECL(bool) RTR0MemObjIsMapping(RTR0MEMOBJ MemObj)
+{
+    /* Validate the object handle. */
+    PRTR0MEMOBJINTERNAL pMem;
+    AssertPtrReturn(MemObj, false);
+    pMem = (PRTR0MEMOBJINTERNAL)MemObj;
+    AssertMsgReturn(pMem->u32Magic == RTR0MEMOBJ_MAGIC, ("%p: %#x\n", pMem, pMem->u32Magic), false);
+    AssertMsgReturn(pMem->enmType > RTR0MEMOBJTYPE_INVALID && pMem->enmType < RTR0MEMOBJTYPE_END, ("%p: %d\n", pMem, pMem->enmType), false);
+
+    /* hand it on to the inlined worker. */
+    return rtR0MemObjIsMapping(pMem);
+}
+RT_EXPORT_SYMBOL(RTR0MemObjIsMapping);
+
+
+/**
+ * Gets the address of a ring-0 memory object.
+ *
+ * @returns The address of the memory object.
+ * @returns NULL if the handle is invalid (asserts in strict builds) or if there isn't any mapping.
+ * @param   MemObj  The ring-0 memory object handle.
+ */
+RTR0DECL(void *) RTR0MemObjAddress(RTR0MEMOBJ MemObj)
+{
+    /* Validate the object handle. */
+    PRTR0MEMOBJINTERNAL pMem;
+    if (RT_UNLIKELY(MemObj == NIL_RTR0MEMOBJ))
+        return NULL;
+    AssertPtrReturn(MemObj, NULL);
+    pMem = (PRTR0MEMOBJINTERNAL)MemObj;
+    AssertMsgReturn(pMem->u32Magic == RTR0MEMOBJ_MAGIC, ("%p: %#x\n", pMem, pMem->u32Magic), NULL);
+    AssertMsgReturn(pMem->enmType > RTR0MEMOBJTYPE_INVALID && pMem->enmType < RTR0MEMOBJTYPE_END, ("%p: %d\n", pMem, pMem->enmType), NULL);
+
+    /* return the mapping address. */
+    return pMem->pv;
+}
+RT_EXPORT_SYMBOL(RTR0MemObjAddress);
+
+
+/**
+ * Gets the ring-3 address of a ring-0 memory object.
+ *
+ * This only applies to ring-0 memory object with ring-3 mappings of some kind, i.e.
+ * locked user memory, reserved user address space and user mappings. This API should
+ * not be used on any other objects.
+ *
+ * @returns The address of the memory object.
+ * @returns NIL_RTR3PTR if the handle is invalid or if it's not an object with a ring-3 mapping.
+ *          Strict builds will assert in both cases.
+ * @param   MemObj  The ring-0 memory object handle.
+ */
+RTR0DECL(RTR3PTR) RTR0MemObjAddressR3(RTR0MEMOBJ MemObj)
+{
+    PRTR0MEMOBJINTERNAL pMem;
+
+    /* Validate the object handle. */
+    if (RT_UNLIKELY(MemObj == NIL_RTR0MEMOBJ))
+        return NIL_RTR3PTR;
+    AssertPtrReturn(MemObj, NIL_RTR3PTR);
+    pMem = (PRTR0MEMOBJINTERNAL)MemObj;
+    AssertMsgReturn(pMem->u32Magic == RTR0MEMOBJ_MAGIC, ("%p: %#x\n", pMem, pMem->u32Magic), NIL_RTR3PTR);
+    AssertMsgReturn(pMem->enmType > RTR0MEMOBJTYPE_INVALID && pMem->enmType < RTR0MEMOBJTYPE_END, ("%p: %d\n", pMem, pMem->enmType), NIL_RTR3PTR);
+    if (RT_UNLIKELY(    (   pMem->enmType != RTR0MEMOBJTYPE_MAPPING
+                         || pMem->u.Mapping.R0Process == NIL_RTR0PROCESS)
+                    &&  (   pMem->enmType != RTR0MEMOBJTYPE_LOCK
+                         || pMem->u.Lock.R0Process == NIL_RTR0PROCESS)
+                    &&  (   pMem->enmType != RTR0MEMOBJTYPE_PHYS_NC
+                         || pMem->u.Lock.R0Process == NIL_RTR0PROCESS)
+                    &&  (   pMem->enmType != RTR0MEMOBJTYPE_RES_VIRT
+                         || pMem->u.ResVirt.R0Process == NIL_RTR0PROCESS)))
+        return NIL_RTR3PTR;
+
+    /* return the mapping address. */
+    return (RTR3PTR)pMem->pv;
+}
+RT_EXPORT_SYMBOL(RTR0MemObjAddressR3);
+
+
+/**
+ * Gets the size of a ring-0 memory object.
+ *
+ * The returned value may differ from the one specified to the API creating the
+ * object because of alignment adjustments.  The minimal alignment currently
+ * employed by any API is PAGE_SIZE, so the result can safely be shifted by
+ * PAGE_SHIFT to calculate a page count.
+ *
+ * @returns The object size.
+ * @returns 0 if the handle is invalid (asserts in strict builds) or if there isn't any mapping.
+ * @param   MemObj  The ring-0 memory object handle.
+ */
+RTR0DECL(size_t) RTR0MemObjSize(RTR0MEMOBJ MemObj)
+{
+    PRTR0MEMOBJINTERNAL pMem;
+
+    /* Validate the object handle. */
+    if (RT_UNLIKELY(MemObj == NIL_RTR0MEMOBJ))
+        return 0;
+    AssertPtrReturn(MemObj, 0);
+    pMem = (PRTR0MEMOBJINTERNAL)MemObj;
+    AssertMsgReturn(pMem->u32Magic == RTR0MEMOBJ_MAGIC, ("%p: %#x\n", pMem, pMem->u32Magic), 0);
+    AssertMsgReturn(pMem->enmType > RTR0MEMOBJTYPE_INVALID && pMem->enmType < RTR0MEMOBJTYPE_END, ("%p: %d\n", pMem, pMem->enmType), 0);
+    AssertMsg(RT_ALIGN_Z(pMem->cb, PAGE_SIZE) == pMem->cb, ("%#zx\n", pMem->cb));
+
+    /* return the size. */
+    return pMem->cb;
+}
+RT_EXPORT_SYMBOL(RTR0MemObjSize);
+
+
+/**
+ * Get the physical address of an page in the memory object.
+ *
+ * @returns The physical address.
+ * @returns NIL_RTHCPHYS if the object doesn't contain fixed physical pages.
+ * @returns NIL_RTHCPHYS if the iPage is out of range.
+ * @returns NIL_RTHCPHYS if the object handle isn't valid.
+ * @param   MemObj  The ring-0 memory object handle.
+ * @param   iPage   The page number within the object.
+ */
+/* Work around gcc bug 55940 */
+#if defined(__GNUC__) && defined(RT_ARCH_X86)
+# if (__GNUC__ * 100 + __GNUC_MINOR__) == 407
+ __attribute__((__optimize__ ("no-shrink-wrap")))
+# endif
+#endif
+RTR0DECL(RTHCPHYS) RTR0MemObjGetPagePhysAddr(RTR0MEMOBJ MemObj, size_t iPage)
+{
+    /* Validate the object handle. */
+    PRTR0MEMOBJINTERNAL pMem;
+    size_t cPages;
+    AssertPtrReturn(MemObj, NIL_RTHCPHYS);
+    pMem = (PRTR0MEMOBJINTERNAL)MemObj;
+    AssertReturn(pMem->u32Magic == RTR0MEMOBJ_MAGIC, NIL_RTHCPHYS);
+    AssertReturn(pMem->enmType > RTR0MEMOBJTYPE_INVALID && pMem->enmType < RTR0MEMOBJTYPE_END, NIL_RTHCPHYS);
+    AssertMsgReturn(pMem->u32Magic == RTR0MEMOBJ_MAGIC, ("%p: %#x\n", pMem, pMem->u32Magic), NIL_RTHCPHYS);
+    AssertMsgReturn(pMem->enmType > RTR0MEMOBJTYPE_INVALID && pMem->enmType < RTR0MEMOBJTYPE_END, ("%p: %d\n", pMem, pMem->enmType), NIL_RTHCPHYS);
+    cPages = (pMem->cb >> PAGE_SHIFT);
+    if (iPage >= cPages)
+    {
+        /* permit: while (RTR0MemObjGetPagePhysAddr(pMem, iPage++) != NIL_RTHCPHYS) {} */
+        if (iPage == cPages)
+            return NIL_RTHCPHYS;
+        AssertReturn(iPage < (pMem->cb >> PAGE_SHIFT), NIL_RTHCPHYS);
+    }
+
+    /*
+     * We know the address of physically contiguous allocations and mappings.
+     */
+    if (pMem->enmType == RTR0MEMOBJTYPE_CONT)
+        return pMem->u.Cont.Phys + iPage * PAGE_SIZE;
+    if (pMem->enmType == RTR0MEMOBJTYPE_PHYS)
+        return pMem->u.Phys.PhysBase + iPage * PAGE_SIZE;
+
+    /*
+     * Do the job.
+     */
+    return rtR0MemObjNativeGetPagePhysAddr(pMem, iPage);
+}
+RT_EXPORT_SYMBOL(RTR0MemObjGetPagePhysAddr);
+
+
+/**
+ * Frees a ring-0 memory object.
+ *
+ * @returns IPRT status code.
+ * @retval  VERR_INVALID_HANDLE if
+ * @param   MemObj          The ring-0 memory object to be freed. NULL is accepted.
+ * @param   fFreeMappings   Whether or not to free mappings of the object.
+ */
+RTR0DECL(int) RTR0MemObjFree(RTR0MEMOBJ MemObj, bool fFreeMappings)
+{
+    /*
+     * Validate the object handle.
+     */
+    PRTR0MEMOBJINTERNAL pMem;
+    int rc;
+
+    if (MemObj == NIL_RTR0MEMOBJ)
+        return VINF_SUCCESS;
+    AssertPtrReturn(MemObj, VERR_INVALID_HANDLE);
+    pMem = (PRTR0MEMOBJINTERNAL)MemObj;
+    AssertReturn(pMem->u32Magic == RTR0MEMOBJ_MAGIC, VERR_INVALID_HANDLE);
+    AssertReturn(pMem->enmType > RTR0MEMOBJTYPE_INVALID && pMem->enmType < RTR0MEMOBJTYPE_END, VERR_INVALID_HANDLE);
+    RT_ASSERT_PREEMPTIBLE();
+
+    /*
+     * Deal with mappings according to fFreeMappings.
+     */
+    if (    !rtR0MemObjIsMapping(pMem)
+        &&  pMem->uRel.Parent.cMappings > 0)
+    {
+        /* fail if not requested to free mappings. */
+        if (!fFreeMappings)
+            return VERR_MEMORY_BUSY;
+
+        while (pMem->uRel.Parent.cMappings > 0)
+        {
+            PRTR0MEMOBJINTERNAL pChild = pMem->uRel.Parent.papMappings[--pMem->uRel.Parent.cMappings];
+            pMem->uRel.Parent.papMappings[pMem->uRel.Parent.cMappings] = NULL;
+
+            /* sanity checks. */
+            AssertPtr(pChild);
+            AssertFatal(pChild->u32Magic == RTR0MEMOBJ_MAGIC);
+            AssertFatal(pChild->enmType > RTR0MEMOBJTYPE_INVALID && pChild->enmType < RTR0MEMOBJTYPE_END);
+            AssertFatal(rtR0MemObjIsMapping(pChild));
+
+            /* free the mapping. */
+            rc = rtR0MemObjNativeFree(pChild);
+            if (RT_FAILURE(rc))
+            {
+                Log(("RTR0MemObjFree: failed to free mapping %p: %p %#zx; rc=%Rrc\n", pChild, pChild->pv, pChild->cb, rc));
+                pMem->uRel.Parent.papMappings[pMem->uRel.Parent.cMappings++] = pChild;
+                return rc;
+            }
+        }
+    }
+
+    /*
+     * Free this object.
+     */
+    rc = rtR0MemObjNativeFree(pMem);
+    if (RT_SUCCESS(rc))
+    {
+        /*
+         * Ok, it was freed just fine. Now, if it's a mapping we'll have to remove it from the parent.
+         */
+        if (rtR0MemObjIsMapping(pMem))
+        {
+            PRTR0MEMOBJINTERNAL pParent = pMem->uRel.Child.pParent;
+            uint32_t i;
+
+            /* sanity checks */
+            AssertPtr(pParent);
+            AssertFatal(pParent->u32Magic == RTR0MEMOBJ_MAGIC);
+            AssertFatal(pParent->enmType > RTR0MEMOBJTYPE_INVALID && pParent->enmType < RTR0MEMOBJTYPE_END);
+            AssertFatal(!rtR0MemObjIsMapping(pParent));
+            AssertFatal(pParent->uRel.Parent.cMappings > 0);
+            AssertPtr(pParent->uRel.Parent.papMappings);
+
+            /* locate and remove from the array of mappings. */
+            i = pParent->uRel.Parent.cMappings;
+            while (i-- > 0)
+            {
+                if (pParent->uRel.Parent.papMappings[i] == pMem)
+                {
+                    pParent->uRel.Parent.papMappings[i] = pParent->uRel.Parent.papMappings[--pParent->uRel.Parent.cMappings];
+                    break;
+                }
+            }
+            Assert(i != UINT32_MAX);
+        }
+        else
+            Assert(pMem->uRel.Parent.cMappings == 0);
+
+        /*
+         * Finally, destroy the handle.
+         */
+        pMem->u32Magic++;
+        pMem->enmType = RTR0MEMOBJTYPE_END;
+        if (!rtR0MemObjIsMapping(pMem))
+            RTMemFree(pMem->uRel.Parent.papMappings);
+        RTMemFree(pMem);
+    }
+    else
+        Log(("RTR0MemObjFree: failed to free %p: %d %p %#zx; rc=%Rrc\n",
+             pMem, pMem->enmType, pMem->pv, pMem->cb, rc));
+    return rc;
+}
+RT_EXPORT_SYMBOL(RTR0MemObjFree);
+
+
+
+RTR0DECL(int) RTR0MemObjAllocPageTag(PRTR0MEMOBJ pMemObj, size_t cb, bool fExecutable, const char *pszTag)
+{
+    /* sanity checks. */
+    const size_t cbAligned = RT_ALIGN_Z(cb, PAGE_SIZE);
+    AssertPtrReturn(pMemObj, VERR_INVALID_POINTER);
+    *pMemObj = NIL_RTR0MEMOBJ;
+    AssertReturn(cb > 0, VERR_INVALID_PARAMETER);
+    AssertReturn(cb <= cbAligned, VERR_INVALID_PARAMETER);
+    RT_ASSERT_PREEMPTIBLE();
+
+    /* do the allocation. */
+    return rtR0MemObjNativeAllocPage(pMemObj, cbAligned, fExecutable);
+}
+RT_EXPORT_SYMBOL(RTR0MemObjAllocPageTag);
+
+
+RTR0DECL(int) RTR0MemObjAllocLowTag(PRTR0MEMOBJ pMemObj, size_t cb, bool fExecutable, const char *pszTag)
+{
+    /* sanity checks. */
+    const size_t cbAligned = RT_ALIGN_Z(cb, PAGE_SIZE);
+    AssertPtrReturn(pMemObj, VERR_INVALID_POINTER);
+    *pMemObj = NIL_RTR0MEMOBJ;
+    AssertReturn(cb > 0, VERR_INVALID_PARAMETER);
+    AssertReturn(cb <= cbAligned, VERR_INVALID_PARAMETER);
+    RT_ASSERT_PREEMPTIBLE();
+
+    /* do the allocation. */
+    return rtR0MemObjNativeAllocLow(pMemObj, cbAligned, fExecutable);
+}
+RT_EXPORT_SYMBOL(RTR0MemObjAllocLowTag);
+
+
+RTR0DECL(int) RTR0MemObjAllocContTag(PRTR0MEMOBJ pMemObj, size_t cb, bool fExecutable, const char *pszTag)
+{
+    /* sanity checks. */
+    const size_t cbAligned = RT_ALIGN_Z(cb, PAGE_SIZE);
+    AssertPtrReturn(pMemObj, VERR_INVALID_POINTER);
+    *pMemObj = NIL_RTR0MEMOBJ;
+    AssertReturn(cb > 0, VERR_INVALID_PARAMETER);
+    AssertReturn(cb <= cbAligned, VERR_INVALID_PARAMETER);
+    RT_ASSERT_PREEMPTIBLE();
+
+    /* do the allocation. */
+    return rtR0MemObjNativeAllocCont(pMemObj, cbAligned, fExecutable);
+}
+RT_EXPORT_SYMBOL(RTR0MemObjAllocContTag);
+
+
+RTR0DECL(int) RTR0MemObjLockUserTag(PRTR0MEMOBJ pMemObj, RTR3PTR R3Ptr, size_t cb,
+                                    uint32_t fAccess, RTR0PROCESS R0Process, const char *pszTag)
+{
+    /* sanity checks. */
+    const size_t cbAligned = RT_ALIGN_Z(cb + (R3Ptr & PAGE_OFFSET_MASK), PAGE_SIZE);
+    RTR3PTR const R3PtrAligned = (R3Ptr & ~(RTR3PTR)PAGE_OFFSET_MASK);
+    AssertPtrReturn(pMemObj, VERR_INVALID_POINTER);
+    *pMemObj = NIL_RTR0MEMOBJ;
+    AssertReturn(cb > 0, VERR_INVALID_PARAMETER);
+    AssertReturn(cb <= cbAligned, VERR_INVALID_PARAMETER);
+    if (R0Process == NIL_RTR0PROCESS)
+        R0Process = RTR0ProcHandleSelf();
+    AssertReturn(!(fAccess & ~(RTMEM_PROT_READ | RTMEM_PROT_WRITE)), VERR_INVALID_PARAMETER);
+    AssertReturn(fAccess, VERR_INVALID_PARAMETER);
+    RT_ASSERT_PREEMPTIBLE();
+
+    /* do the locking. */
+    return rtR0MemObjNativeLockUser(pMemObj, R3PtrAligned, cbAligned, fAccess, R0Process);
+}
+RT_EXPORT_SYMBOL(RTR0MemObjLockUserTag);
+
+
+RTR0DECL(int) RTR0MemObjLockKernelTag(PRTR0MEMOBJ pMemObj, void *pv, size_t cb, uint32_t fAccess, const char *pszTag)
+{
+    /* sanity checks. */
+    const size_t cbAligned = RT_ALIGN_Z(cb + ((uintptr_t)pv & PAGE_OFFSET_MASK), PAGE_SIZE);
+    void * const pvAligned = (void *)((uintptr_t)pv & ~(uintptr_t)PAGE_OFFSET_MASK);
+    AssertPtrReturn(pMemObj, VERR_INVALID_POINTER);
+    *pMemObj = NIL_RTR0MEMOBJ;
+    AssertReturn(cb > 0, VERR_INVALID_PARAMETER);
+    AssertReturn(cb <= cbAligned, VERR_INVALID_PARAMETER);
+    AssertPtrReturn(pvAligned, VERR_INVALID_POINTER);
+    AssertReturn(!(fAccess & ~(RTMEM_PROT_READ | RTMEM_PROT_WRITE)), VERR_INVALID_PARAMETER);
+    AssertReturn(fAccess, VERR_INVALID_PARAMETER);
+    RT_ASSERT_PREEMPTIBLE();
+
+    /* do the allocation. */
+    return rtR0MemObjNativeLockKernel(pMemObj, pvAligned, cbAligned, fAccess);
+}
+RT_EXPORT_SYMBOL(RTR0MemObjLockKernelTag);
+
+
+RTR0DECL(int) RTR0MemObjAllocPhysTag(PRTR0MEMOBJ pMemObj, size_t cb, RTHCPHYS PhysHighest, const char *pszTag)
+{
+    /* sanity checks. */
+    const size_t cbAligned = RT_ALIGN_Z(cb, PAGE_SIZE);
+    AssertPtrReturn(pMemObj, VERR_INVALID_POINTER);
+    *pMemObj = NIL_RTR0MEMOBJ;
+    AssertReturn(cb > 0, VERR_INVALID_PARAMETER);
+    AssertReturn(cb <= cbAligned, VERR_INVALID_PARAMETER);
+    AssertReturn(PhysHighest >= cb, VERR_INVALID_PARAMETER);
+    RT_ASSERT_PREEMPTIBLE();
+
+    /* do the allocation. */
+    return rtR0MemObjNativeAllocPhys(pMemObj, cbAligned, PhysHighest, PAGE_SIZE /* page aligned */);
+}
+RT_EXPORT_SYMBOL(RTR0MemObjAllocPhysTag);
+
+
+RTR0DECL(int) RTR0MemObjAllocPhysExTag(PRTR0MEMOBJ pMemObj, size_t cb, RTHCPHYS PhysHighest, size_t uAlignment, const char *pszTag)
+{
+    /* sanity checks. */
+    const size_t cbAligned = RT_ALIGN_Z(cb, PAGE_SIZE);
+    AssertPtrReturn(pMemObj, VERR_INVALID_POINTER);
+    *pMemObj = NIL_RTR0MEMOBJ;
+    AssertReturn(cb > 0, VERR_INVALID_PARAMETER);
+    AssertReturn(cb <= cbAligned, VERR_INVALID_PARAMETER);
+    AssertReturn(PhysHighest >= cb, VERR_INVALID_PARAMETER);
+    if (uAlignment == 0)
+        uAlignment = PAGE_SIZE;
+    AssertReturn(    uAlignment == PAGE_SIZE
+                 ||  uAlignment == _2M
+                 ||  uAlignment == _4M
+                 ||  uAlignment == _1G,
+                 VERR_INVALID_PARAMETER);
+#if HC_ARCH_BITS == 32
+    /* Memory allocated in this way is typically mapped into kernel space as well; simply
+       don't allow this on 32 bits hosts as the kernel space is too crowded already. */
+    if (uAlignment != PAGE_SIZE)
+        return VERR_NOT_SUPPORTED;
+#endif
+    RT_ASSERT_PREEMPTIBLE();
+
+    /* do the allocation. */
+    return rtR0MemObjNativeAllocPhys(pMemObj, cbAligned, PhysHighest, uAlignment);
+}
+RT_EXPORT_SYMBOL(RTR0MemObjAllocPhysExTag);
+
+
+RTR0DECL(int) RTR0MemObjAllocPhysNCTag(PRTR0MEMOBJ pMemObj, size_t cb, RTHCPHYS PhysHighest, const char *pszTag)
+{
+    /* sanity checks. */
+    const size_t cbAligned = RT_ALIGN_Z(cb, PAGE_SIZE);
+    AssertPtrReturn(pMemObj, VERR_INVALID_POINTER);
+    *pMemObj = NIL_RTR0MEMOBJ;
+    AssertReturn(cb > 0, VERR_INVALID_PARAMETER);
+    AssertReturn(cb <= cbAligned, VERR_INVALID_PARAMETER);
+    AssertReturn(PhysHighest >= cb, VERR_INVALID_PARAMETER);
+    RT_ASSERT_PREEMPTIBLE();
+
+    /* do the allocation. */
+    return rtR0MemObjNativeAllocPhysNC(pMemObj, cbAligned, PhysHighest);
+}
+RT_EXPORT_SYMBOL(RTR0MemObjAllocPhysNCTag);
+
+
+RTR0DECL(int) RTR0MemObjEnterPhysTag(PRTR0MEMOBJ pMemObj, RTHCPHYS Phys, size_t cb, uint32_t uCachePolicy, const char *pszTag)
+{
+    /* sanity checks. */
+    const size_t cbAligned = RT_ALIGN_Z(cb + (Phys & PAGE_OFFSET_MASK), PAGE_SIZE);
+    const RTHCPHYS PhysAligned = Phys & ~(RTHCPHYS)PAGE_OFFSET_MASK;
+    AssertPtrReturn(pMemObj, VERR_INVALID_POINTER);
+    *pMemObj = NIL_RTR0MEMOBJ;
+    AssertReturn(cb > 0, VERR_INVALID_PARAMETER);
+    AssertReturn(cb <= cbAligned, VERR_INVALID_PARAMETER);
+    AssertReturn(Phys != NIL_RTHCPHYS, VERR_INVALID_PARAMETER);
+    AssertReturn(   uCachePolicy == RTMEM_CACHE_POLICY_DONT_CARE
+                 || uCachePolicy == RTMEM_CACHE_POLICY_MMIO,
+                 VERR_INVALID_PARAMETER);
+    RT_ASSERT_PREEMPTIBLE();
+
+    /* do the allocation. */
+    return rtR0MemObjNativeEnterPhys(pMemObj, PhysAligned, cbAligned, uCachePolicy);
+}
+RT_EXPORT_SYMBOL(RTR0MemObjEnterPhysTag);
+
+
+RTR0DECL(int) RTR0MemObjReserveKernelTag(PRTR0MEMOBJ pMemObj, void *pvFixed, size_t cb, size_t uAlignment, const char *pszTag)
+{
+    /* sanity checks. */
+    const size_t cbAligned = RT_ALIGN_Z(cb, PAGE_SIZE);
+    AssertPtrReturn(pMemObj, VERR_INVALID_POINTER);
+    *pMemObj = NIL_RTR0MEMOBJ;
+    if (uAlignment == 0)
+        uAlignment = PAGE_SIZE;
+    AssertReturn(uAlignment == PAGE_SIZE || uAlignment == _2M || uAlignment == _4M, VERR_INVALID_PARAMETER);
+    AssertReturn(cb > 0, VERR_INVALID_PARAMETER);
+    AssertReturn(cb <= cbAligned, VERR_INVALID_PARAMETER);
+    if (pvFixed != (void *)-1)
+        AssertReturn(!((uintptr_t)pvFixed & (uAlignment - 1)), VERR_INVALID_PARAMETER);
+    RT_ASSERT_PREEMPTIBLE();
+
+    /* do the reservation. */
+    return rtR0MemObjNativeReserveKernel(pMemObj, pvFixed, cbAligned, uAlignment);
+}
+RT_EXPORT_SYMBOL(RTR0MemObjReserveKernelTag);
+
+
+RTR0DECL(int) RTR0MemObjReserveUserTag(PRTR0MEMOBJ pMemObj, RTR3PTR R3PtrFixed, size_t cb,
+                                       size_t uAlignment, RTR0PROCESS R0Process, const char *pszTag)
+{
+    /* sanity checks. */
+    const size_t cbAligned = RT_ALIGN_Z(cb, PAGE_SIZE);
+    AssertPtrReturn(pMemObj, VERR_INVALID_POINTER);
+    *pMemObj = NIL_RTR0MEMOBJ;
+    if (uAlignment == 0)
+        uAlignment = PAGE_SIZE;
+    AssertReturn(uAlignment == PAGE_SIZE || uAlignment == _2M || uAlignment == _4M, VERR_INVALID_PARAMETER);
+    AssertReturn(cb > 0, VERR_INVALID_PARAMETER);
+    AssertReturn(cb <= cbAligned, VERR_INVALID_PARAMETER);
+    if (R3PtrFixed != (RTR3PTR)-1)
+        AssertReturn(!(R3PtrFixed & (uAlignment - 1)), VERR_INVALID_PARAMETER);
+    if (R0Process == NIL_RTR0PROCESS)
+        R0Process = RTR0ProcHandleSelf();
+    RT_ASSERT_PREEMPTIBLE();
+
+    /* do the reservation. */
+    return rtR0MemObjNativeReserveUser(pMemObj, R3PtrFixed, cbAligned, uAlignment, R0Process);
+}
+RT_EXPORT_SYMBOL(RTR0MemObjReserveUserTag);
+
+
+RTR0DECL(int) RTR0MemObjMapKernelTag(PRTR0MEMOBJ pMemObj, RTR0MEMOBJ MemObjToMap, void *pvFixed,
+                                     size_t uAlignment, unsigned fProt, const char *pszTag)
+{
+    return RTR0MemObjMapKernelExTag(pMemObj, MemObjToMap, pvFixed, uAlignment, fProt, 0, 0, pszTag);
+}
+RT_EXPORT_SYMBOL(RTR0MemObjMapKernelTag);
+
+
+RTR0DECL(int) RTR0MemObjMapKernelExTag(PRTR0MEMOBJ pMemObj, RTR0MEMOBJ MemObjToMap, void *pvFixed, size_t uAlignment,
+                                       unsigned fProt, size_t offSub, size_t cbSub, const char *pszTag)
+{
+    PRTR0MEMOBJINTERNAL pMemToMap;
+    PRTR0MEMOBJINTERNAL pNew;
+    int                 rc;
+
+    /* sanity checks. */
+    AssertPtrReturn(pMemObj, VERR_INVALID_POINTER);
+    *pMemObj = NIL_RTR0MEMOBJ;
+    AssertPtrReturn(MemObjToMap, VERR_INVALID_HANDLE);
+    pMemToMap = (PRTR0MEMOBJINTERNAL)MemObjToMap;
+    AssertReturn(pMemToMap->u32Magic == RTR0MEMOBJ_MAGIC, VERR_INVALID_HANDLE);
+    AssertReturn(pMemToMap->enmType > RTR0MEMOBJTYPE_INVALID && pMemToMap->enmType < RTR0MEMOBJTYPE_END, VERR_INVALID_HANDLE);
+    AssertReturn(!rtR0MemObjIsMapping(pMemToMap), VERR_INVALID_PARAMETER);
+    AssertReturn(pMemToMap->enmType != RTR0MEMOBJTYPE_RES_VIRT, VERR_INVALID_PARAMETER);
+    if (uAlignment == 0)
+        uAlignment = PAGE_SIZE;
+    AssertReturn(uAlignment == PAGE_SIZE || uAlignment == _2M || uAlignment == _4M, VERR_INVALID_PARAMETER);
+    if (pvFixed != (void *)-1)
+        AssertReturn(!((uintptr_t)pvFixed & (uAlignment - 1)), VERR_INVALID_PARAMETER);
+    AssertReturn(fProt != RTMEM_PROT_NONE, VERR_INVALID_PARAMETER);
+    AssertReturn(!(fProt & ~(RTMEM_PROT_READ | RTMEM_PROT_WRITE | RTMEM_PROT_EXEC)), VERR_INVALID_PARAMETER);
+    AssertReturn(!(offSub & PAGE_OFFSET_MASK), VERR_INVALID_PARAMETER);
+    AssertReturn(offSub < pMemToMap->cb, VERR_INVALID_PARAMETER);
+    AssertReturn(!(cbSub & PAGE_OFFSET_MASK), VERR_INVALID_PARAMETER);
+    AssertReturn(cbSub <= pMemToMap->cb, VERR_INVALID_PARAMETER);
+    AssertReturn((!offSub && !cbSub) || (offSub + cbSub) <= pMemToMap->cb, VERR_INVALID_PARAMETER);
+    RT_ASSERT_PREEMPTIBLE();
+
+    /* adjust the request to simplify the native code. */
+    if (offSub == 0 && cbSub == pMemToMap->cb)
+        cbSub = 0;
+
+    /* do the mapping. */
+    rc = rtR0MemObjNativeMapKernel(&pNew, pMemToMap, pvFixed, uAlignment, fProt, offSub, cbSub);
+    if (RT_SUCCESS(rc))
+    {
+        /* link it. */
+        rc = rtR0MemObjLink(pMemToMap, pNew);
+        if (RT_SUCCESS(rc))
+            *pMemObj = pNew;
+        else
+        {
+            /* damn, out of memory. bail out. */
+            int rc2 = rtR0MemObjNativeFree(pNew);
+            AssertRC(rc2);
+            pNew->u32Magic++;
+            pNew->enmType = RTR0MEMOBJTYPE_END;
+            RTMemFree(pNew);
+        }
+    }
+
+    return rc;
+}
+RT_EXPORT_SYMBOL(RTR0MemObjMapKernelExTag);
+
+
+RTR0DECL(int) RTR0MemObjMapUserTag(PRTR0MEMOBJ pMemObj, RTR0MEMOBJ MemObjToMap, RTR3PTR R3PtrFixed,
+                                   size_t uAlignment, unsigned fProt, RTR0PROCESS R0Process, const char *pszTag)
+{
+    /* sanity checks. */
+    PRTR0MEMOBJINTERNAL pMemToMap;
+    PRTR0MEMOBJINTERNAL pNew;
+    int rc;
+    AssertPtrReturn(pMemObj, VERR_INVALID_POINTER);
+    pMemToMap = (PRTR0MEMOBJINTERNAL)MemObjToMap;
+    *pMemObj = NIL_RTR0MEMOBJ;
+    AssertPtrReturn(MemObjToMap, VERR_INVALID_HANDLE);
+    AssertReturn(pMemToMap->u32Magic == RTR0MEMOBJ_MAGIC, VERR_INVALID_HANDLE);
+    AssertReturn(pMemToMap->enmType > RTR0MEMOBJTYPE_INVALID && pMemToMap->enmType < RTR0MEMOBJTYPE_END, VERR_INVALID_HANDLE);
+    AssertReturn(!rtR0MemObjIsMapping(pMemToMap), VERR_INVALID_PARAMETER);
+    AssertReturn(pMemToMap->enmType != RTR0MEMOBJTYPE_RES_VIRT, VERR_INVALID_PARAMETER);
+    if (uAlignment == 0)
+        uAlignment = PAGE_SIZE;
+    AssertReturn(uAlignment == PAGE_SIZE || uAlignment == _2M || uAlignment == _4M, VERR_INVALID_PARAMETER);
+    if (R3PtrFixed != (RTR3PTR)-1)
+        AssertReturn(!(R3PtrFixed & (uAlignment - 1)), VERR_INVALID_PARAMETER);
+    AssertReturn(fProt != RTMEM_PROT_NONE, VERR_INVALID_PARAMETER);
+    AssertReturn(!(fProt & ~(RTMEM_PROT_READ | RTMEM_PROT_WRITE | RTMEM_PROT_EXEC)), VERR_INVALID_PARAMETER);
+    if (R0Process == NIL_RTR0PROCESS)
+        R0Process = RTR0ProcHandleSelf();
+    RT_ASSERT_PREEMPTIBLE();
+
+    /* do the mapping. */
+    rc = rtR0MemObjNativeMapUser(&pNew, pMemToMap, R3PtrFixed, uAlignment, fProt, R0Process);
+    if (RT_SUCCESS(rc))
+    {
+        /* link it. */
+        rc = rtR0MemObjLink(pMemToMap, pNew);
+        if (RT_SUCCESS(rc))
+            *pMemObj = pNew;
+        else
+        {
+            /* damn, out of memory. bail out. */
+            int rc2 = rtR0MemObjNativeFree(pNew);
+            AssertRC(rc2);
+            pNew->u32Magic++;
+            pNew->enmType = RTR0MEMOBJTYPE_END;
+            RTMemFree(pNew);
+        }
+    }
+
+    return rc;
+}
+RT_EXPORT_SYMBOL(RTR0MemObjMapUserTag);
+
+
+RTR0DECL(int) RTR0MemObjProtect(RTR0MEMOBJ hMemObj, size_t offSub, size_t cbSub, uint32_t fProt)
+{
+    PRTR0MEMOBJINTERNAL pMemObj;
+    int                 rc;
+
+    /* sanity checks. */
+    pMemObj = (PRTR0MEMOBJINTERNAL)hMemObj;
+    AssertPtrReturn(pMemObj, VERR_INVALID_HANDLE);
+    AssertReturn(pMemObj->u32Magic == RTR0MEMOBJ_MAGIC, VERR_INVALID_HANDLE);
+    AssertReturn(pMemObj->enmType > RTR0MEMOBJTYPE_INVALID && pMemObj->enmType < RTR0MEMOBJTYPE_END, VERR_INVALID_HANDLE);
+    AssertReturn(rtR0MemObjIsProtectable(pMemObj), VERR_INVALID_PARAMETER);
+    AssertReturn(!(offSub & PAGE_OFFSET_MASK), VERR_INVALID_PARAMETER);
+    AssertReturn(offSub < pMemObj->cb, VERR_INVALID_PARAMETER);
+    AssertReturn(!(cbSub  & PAGE_OFFSET_MASK), VERR_INVALID_PARAMETER);
+    AssertReturn(cbSub <= pMemObj->cb, VERR_INVALID_PARAMETER);
+    AssertReturn(offSub + cbSub <= pMemObj->cb, VERR_INVALID_PARAMETER);
+    AssertReturn(!(fProt & ~(RTMEM_PROT_NONE | RTMEM_PROT_READ | RTMEM_PROT_WRITE | RTMEM_PROT_EXEC)), VERR_INVALID_PARAMETER);
+    RT_ASSERT_PREEMPTIBLE();
+
+    /* do the job */
+    rc = rtR0MemObjNativeProtect(pMemObj, offSub, cbSub, fProt);
+    if (RT_SUCCESS(rc))
+        pMemObj->fFlags |= RTR0MEMOBJ_FLAGS_PROT_CHANGED; /* record it */
+
+    return rc;
+}
+RT_EXPORT_SYMBOL(RTR0MemObjProtect);
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/r0drv/mp-r0drv.h
@@ -0,0 +1,82 @@
+/* $Id: mp-r0drv.h $ */
+/** @file
+ * IPRT - Multiprocessor, Ring-0 Driver, Internal Header.
+ */
+
+/*
+ * Copyright (C) 2008-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+#ifndef ___r0drv_mp_r0drv_h
+#define ___r0drv_mp_r0drv_h
+
+#include <iprt/mp.h>
+
+RT_C_DECLS_BEGIN
+
+/**
+ * MP callback
+ *
+ * @param   idCpu       CPU id
+ * @param   pvUser1     The first user argument.
+ * @param   pvUser2     The second user argument.
+ */
+typedef DECLCALLBACK(void) FNMPWORKER(RTCPUID idCpu, void *pvUser1, void *pvUser2);
+/** Pointer to a FNMPWORKER(). */
+typedef FNMPWORKER *PFNMPWORKER;
+
+/**
+ * RTMpOn* argument packet used by the host specific callback
+ * wrapper functions.
+ */
+typedef struct RTMPARGS
+{
+    PFNMPWORKER pfnWorker;
+    void       *pvUser1;
+    void       *pvUser2;
+    RTCPUID     idCpu;
+    RTCPUID     idCpu2;
+    uint32_t volatile cHits;
+#ifdef RT_OS_WINDOWS
+    /** Turns out that KeFlushQueuedDpcs doesn't necessarily wait till all
+     * callbacks are done.  So, do reference counting to make sure we don't free
+     * this structure befor all CPUs have completely handled their requests.  */
+    int32_t volatile  cRefs;
+#endif
+#ifdef RT_OS_LINUX
+    PRTCPUSET   pWorkerSet;
+#endif
+} RTMPARGS;
+/** Pointer to a RTMpOn* argument packet. */
+typedef RTMPARGS *PRTMPARGS;
+
+/* Called from initterm-r0drv.cpp: */
+DECLHIDDEN(int)  rtR0MpNotificationInit(void);
+DECLHIDDEN(void) rtR0MpNotificationTerm(void);
+
+/* The following is only relevant when using mpnotifcation-r0drv.cpp: */
+DECLHIDDEN(int)  rtR0MpNotificationNativeInit(void);
+DECLHIDDEN(void) rtR0MpNotificationNativeTerm(void);
+DECLHIDDEN(void) rtMpNotificationDoCallbacks(RTMPEVENT enmEvent, RTCPUID idCpu);
+
+RT_C_DECLS_END
+
+#endif
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/r0drv/mpnotification-r0drv.c
@@ -0,0 +1,322 @@
+/* $Id: mpnotification-r0drv.c $ */
+/** @file
+ * IPRT - Multiprocessor, Ring-0 Driver, Event Notifications.
+ */
+
+/*
+ * Copyright (C) 2008-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+
+/*********************************************************************************************************************************
+*   Header Files                                                                                                                 *
+*********************************************************************************************************************************/
+#include <iprt/mp.h>
+#include "internal/iprt.h"
+
+#include <iprt/asm.h>
+#if defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86)
+# include <iprt/asm-amd64-x86.h>
+#endif
+#include <iprt/assert.h>
+#include <iprt/err.h>
+#include <iprt/mem.h>
+#include <iprt/spinlock.h>
+#include <iprt/string.h>
+#include <iprt/thread.h>
+#include "r0drv/mp-r0drv.h"
+
+
+/*********************************************************************************************************************************
+*   Structures and Typedefs                                                                                                      *
+*********************************************************************************************************************************/
+/**
+ * Notification registration record tracking
+ * RTMpRegisterNotification() calls.
+ */
+typedef struct RTMPNOTIFYREG
+{
+    /** Pointer to the next record. */
+    struct RTMPNOTIFYREG * volatile pNext;
+    /** The callback. */
+    PFNRTMPNOTIFICATION pfnCallback;
+    /** The user argument. */
+    void *pvUser;
+    /** Bit mask indicating whether we've done this callback or not. */
+    uint8_t bmDone[sizeof(void *)];
+} RTMPNOTIFYREG;
+/** Pointer to a registration record. */
+typedef RTMPNOTIFYREG *PRTMPNOTIFYREG;
+
+
+/*********************************************************************************************************************************
+*   Global Variables                                                                                                             *
+*********************************************************************************************************************************/
+/** The spinlock protecting the list. */
+static RTSPINLOCK volatile g_hRTMpNotifySpinLock = NIL_RTSPINLOCK;
+/** List of callbacks, in registration order. */
+static PRTMPNOTIFYREG volatile g_pRTMpCallbackHead = NULL;
+/** The current done bit. */
+static uint32_t volatile g_iRTMpDoneBit;
+/** The list generation.
+ * This is increased whenever the list has been modified. The callback routine
+ * make use of this to avoid having restart at the list head after each callback. */
+static uint32_t volatile g_iRTMpGeneration;
+
+
+
+
+/**
+ * This is called by the native code.
+ *
+ * @param   idCpu           The CPU id the event applies to.
+ * @param   enmEvent        The event.
+ */
+DECLHIDDEN(void) rtMpNotificationDoCallbacks(RTMPEVENT enmEvent, RTCPUID idCpu)
+{
+    PRTMPNOTIFYREG  pCur;
+    RTSPINLOCK      hSpinlock;
+
+    /*
+     * This is a little bit tricky as we cannot be holding the spinlock
+     * while calling the callback. This means that the list might change
+     * while we're walking it, and that multiple events might be running
+     * concurrently (depending on the OS).
+     *
+     * So, the first measure is to employ a 32-bitmask for each
+     * record where we'll use a bit that rotates for each call to
+     * this function to indicate which records that has been
+     * processed. This will take care of both changes to the list
+     * and a reasonable amount of concurrent events.
+     *
+     * In order to avoid having to restart the list walks for every
+     * callback we make, we'll make use a list generation number that is
+     * incremented everytime the list is changed. So, if it remains
+     * unchanged over a callback we can safely continue the iteration.
+     */
+    uint32_t iDone = ASMAtomicIncU32(&g_iRTMpDoneBit);
+    iDone %= RT_SIZEOFMEMB(RTMPNOTIFYREG, bmDone) * 8;
+
+    hSpinlock = g_hRTMpNotifySpinLock;
+    if (hSpinlock == NIL_RTSPINLOCK)
+        return;
+    RTSpinlockAcquire(hSpinlock);
+
+    /* Clear the bit. */
+    for (pCur = g_pRTMpCallbackHead; pCur; pCur = pCur->pNext)
+        ASMAtomicBitClear(&pCur->bmDone[0], iDone);
+
+    /* Iterate the records and perform the callbacks. */
+    do
+    {
+        uint32_t const iGeneration = ASMAtomicUoReadU32(&g_iRTMpGeneration);
+
+        pCur = g_pRTMpCallbackHead;
+        while (pCur)
+        {
+            if (!ASMAtomicBitTestAndSet(&pCur->bmDone[0], iDone))
+            {
+                PFNRTMPNOTIFICATION pfnCallback = pCur->pfnCallback;
+                void *pvUser = pCur->pvUser;
+                pCur = pCur->pNext;
+                RTSpinlockRelease(g_hRTMpNotifySpinLock);
+
+                pfnCallback(enmEvent, idCpu, pvUser);
+
+                /* carefully require the lock here, see RTR0MpNotificationTerm(). */
+                hSpinlock = g_hRTMpNotifySpinLock;
+                if (hSpinlock == NIL_RTSPINLOCK)
+                    return;
+                RTSpinlockAcquire(hSpinlock);
+                if (ASMAtomicUoReadU32(&g_iRTMpGeneration) != iGeneration)
+                    break;
+            }
+            else
+                pCur = pCur->pNext;
+        }
+    } while (pCur);
+
+    RTSpinlockRelease(hSpinlock);
+}
+
+
+
+RTDECL(int) RTMpNotificationRegister(PFNRTMPNOTIFICATION pfnCallback, void *pvUser)
+{
+    PRTMPNOTIFYREG  pCur;
+    PRTMPNOTIFYREG  pNew;
+
+    /*
+     * Validation.
+     */
+    AssertPtrReturn(pfnCallback, VERR_INVALID_POINTER);
+    AssertReturn(g_hRTMpNotifySpinLock != NIL_RTSPINLOCK, VERR_WRONG_ORDER);
+    RT_ASSERT_PREEMPTIBLE();
+
+    RTSpinlockAcquire(g_hRTMpNotifySpinLock);
+    for (pCur = g_pRTMpCallbackHead; pCur; pCur = pCur->pNext)
+        if (    pCur->pvUser == pvUser
+            &&  pCur->pfnCallback == pfnCallback)
+            break;
+    RTSpinlockRelease(g_hRTMpNotifySpinLock);
+    AssertMsgReturn(!pCur, ("pCur=%p pfnCallback=%p pvUser=%p\n", pCur, pfnCallback, pvUser), VERR_ALREADY_EXISTS);
+
+    /*
+     * Allocate a new record and attempt to insert it.
+     */
+    pNew = (PRTMPNOTIFYREG)RTMemAlloc(sizeof(*pNew));
+    if (!pNew)
+        return VERR_NO_MEMORY;
+
+    pNew->pNext = NULL;
+    pNew->pfnCallback = pfnCallback;
+    pNew->pvUser = pvUser;
+    memset(&pNew->bmDone[0], 0xff, sizeof(pNew->bmDone));
+
+    RTSpinlockAcquire(g_hRTMpNotifySpinLock);
+
+    pCur = g_pRTMpCallbackHead;
+    if (!pCur)
+        g_pRTMpCallbackHead = pNew;
+    else
+    {
+        for (pCur = g_pRTMpCallbackHead; ; pCur = pCur->pNext)
+            if (    pCur->pvUser == pvUser
+                &&  pCur->pfnCallback == pfnCallback)
+                break;
+            else if (!pCur->pNext)
+            {
+                pCur->pNext = pNew;
+                pCur = NULL;
+                break;
+            }
+    }
+
+    ASMAtomicIncU32(&g_iRTMpGeneration);
+
+    RTSpinlockRelease(g_hRTMpNotifySpinLock);
+
+    /* duplicate? */
+    if (pCur)
+    {
+        RTMemFree(pCur);
+        AssertMsgFailedReturn(("pCur=%p pfnCallback=%p pvUser=%p\n", pCur, pfnCallback, pvUser), VERR_ALREADY_EXISTS);
+    }
+
+    return VINF_SUCCESS;
+}
+RT_EXPORT_SYMBOL(RTMpNotificationRegister);
+
+
+RTDECL(int) RTMpNotificationDeregister(PFNRTMPNOTIFICATION pfnCallback, void *pvUser)
+{
+    PRTMPNOTIFYREG  pPrev;
+    PRTMPNOTIFYREG  pCur;
+
+    /*
+     * Validation.
+     */
+    AssertPtrReturn(pfnCallback, VERR_INVALID_POINTER);
+    AssertReturn(g_hRTMpNotifySpinLock != NIL_RTSPINLOCK, VERR_WRONG_ORDER);
+    RT_ASSERT_INTS_ON();
+
+    /*
+     * Find and unlink the record from the list.
+     */
+    RTSpinlockAcquire(g_hRTMpNotifySpinLock);
+    pPrev = NULL;
+    for (pCur = g_pRTMpCallbackHead; pCur; pCur = pCur->pNext)
+    {
+        if (    pCur->pvUser == pvUser
+            &&  pCur->pfnCallback == pfnCallback)
+            break;
+        pPrev = pCur;
+    }
+    if (pCur)
+    {
+        if (pPrev)
+            pPrev->pNext = pCur->pNext;
+        else
+            g_pRTMpCallbackHead = pCur->pNext;
+        ASMAtomicIncU32(&g_iRTMpGeneration);
+    }
+    RTSpinlockRelease(g_hRTMpNotifySpinLock);
+
+    if (!pCur)
+        return VERR_NOT_FOUND;
+
+    /*
+     * Invalidate and free the record.
+     */
+    pCur->pNext = NULL;
+    pCur->pfnCallback = NULL;
+    RTMemFree(pCur);
+
+    return VINF_SUCCESS;
+}
+RT_EXPORT_SYMBOL(RTMpNotificationDeregister);
+
+
+DECLHIDDEN(int) rtR0MpNotificationInit(void)
+{
+    int rc = RTSpinlockCreate((PRTSPINLOCK)&g_hRTMpNotifySpinLock, RTSPINLOCK_FLAGS_INTERRUPT_SAFE, "RTR0Mp");
+    if (RT_SUCCESS(rc))
+    {
+        rc = rtR0MpNotificationNativeInit();
+        if (RT_SUCCESS(rc))
+            return rc;
+
+        RTSpinlockDestroy(g_hRTMpNotifySpinLock);
+        g_hRTMpNotifySpinLock = NIL_RTSPINLOCK;
+    }
+    return rc;
+}
+
+
+DECLHIDDEN(void) rtR0MpNotificationTerm(void)
+{
+    PRTMPNOTIFYREG  pHead;
+    RTSPINLOCK      hSpinlock = g_hRTMpNotifySpinLock;
+    AssertReturnVoid(hSpinlock != NIL_RTSPINLOCK);
+
+    rtR0MpNotificationNativeTerm();
+
+    /* pick up the list and the spinlock. */
+    RTSpinlockAcquire(hSpinlock);
+    ASMAtomicWriteHandle(&g_hRTMpNotifySpinLock, NIL_RTSPINLOCK);
+    pHead = g_pRTMpCallbackHead;
+    g_pRTMpCallbackHead = NULL;
+    ASMAtomicIncU32(&g_iRTMpGeneration);
+    RTSpinlockRelease(hSpinlock);
+
+    /* free the list. */
+    while (pHead)
+    {
+        PRTMPNOTIFYREG pFree = pHead;
+        pHead = pHead->pNext;
+
+        pFree->pNext = NULL;
+        pFree->pfnCallback = NULL;
+        RTMemFree(pFree);
+    }
+
+    RTSpinlockDestroy(hSpinlock);
+}
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/r0drv/power-r0drv.h
@@ -0,0 +1,41 @@
+/* $Id: power-r0drv.h $ */
+/** @file
+ * IPRT - Power Management, Ring-0 Driver, Internal Header.
+ */
+
+/*
+ * Copyright (C) 2008-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+#ifndef ___r0drv_powermgt_r0drv_h
+#define ___r0drv_powermgt_r0drv_h
+
+#include <iprt/power.h>
+
+RT_C_DECLS_BEGIN
+
+/* Called from initterm-r0drv.cpp: */
+DECLHIDDEN(int)  rtR0PowerNotificationInit(void);
+DECLHIDDEN(void) rtR0PowerNotificationTerm(void);
+
+RT_C_DECLS_END
+
+#endif
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/r0drv/powernotification-r0drv.c
@@ -0,0 +1,318 @@
+/* $Id: powernotification-r0drv.c $ */
+/** @file
+ * IPRT - Power Management, Ring-0 Driver, Event Notifications.
+ */
+
+/*
+ * Copyright (C) 2008-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+
+/*********************************************************************************************************************************
+*   Header Files                                                                                                                 *
+*********************************************************************************************************************************/
+#include <iprt/power.h>
+#include "internal/iprt.h"
+
+#include <iprt/asm.h>
+#if defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86)
+# include <iprt/asm-amd64-x86.h>
+#endif
+#include <iprt/assert.h>
+#include <iprt/err.h>
+#include <iprt/mem.h>
+#include <iprt/spinlock.h>
+#include <iprt/string.h>
+#include <iprt/thread.h>
+#include "r0drv/mp-r0drv.h"
+#include "r0drv/power-r0drv.h"
+
+
+/*********************************************************************************************************************************
+*   Structures and Typedefs                                                                                                      *
+*********************************************************************************************************************************/
+/**
+ * Notification registration record tracking
+ * RTPowerRegisterNotification() calls.
+ */
+typedef struct RTPOWERNOTIFYREG
+{
+    /** Pointer to the next record. */
+    struct RTPOWERNOTIFYREG * volatile pNext;
+    /** The callback. */
+    PFNRTPOWERNOTIFICATION pfnCallback;
+    /** The user argument. */
+    void *pvUser;
+    /** Bit mask indicating whether we've done this callback or not. */
+    uint8_t bmDone[sizeof(void *)];
+} RTPOWERNOTIFYREG;
+/** Pointer to a registration record. */
+typedef RTPOWERNOTIFYREG *PRTPOWERNOTIFYREG;
+
+
+/*********************************************************************************************************************************
+*   Global Variables                                                                                                             *
+*********************************************************************************************************************************/
+/** The spinlock protecting the list. */
+static RTSPINLOCK volatile g_hRTPowerNotifySpinLock = NIL_RTSPINLOCK;
+/** List of callbacks, in registration order. */
+static PRTPOWERNOTIFYREG volatile g_pRTPowerCallbackHead = NULL;
+/** The current done bit. */
+static uint32_t volatile g_iRTPowerDoneBit;
+/** The list generation.
+ * This is increased whenever the list has been modified. The callback routine
+ * make use of this to avoid having restart at the list head after each callback. */
+static uint32_t volatile g_iRTPowerGeneration;
+
+
+
+
+RTDECL(int) RTPowerSignalEvent(RTPOWEREVENT enmEvent)
+{
+    PRTPOWERNOTIFYREG pCur;
+    RTSPINLOCK        hSpinlock;
+
+    /*
+     * This is a little bit tricky as we cannot be holding the spinlock
+     * while calling the callback. This means that the list might change
+     * while we're walking it, and that multiple events might be running
+     * concurrently (depending on the OS).
+     *
+     * So, the first measure is to employ a 32-bitmask for each
+     * record where we'll use a bit that rotates for each call to
+     * this function to indicate which records that has been
+     * processed. This will take care of both changes to the list
+     * and a reasonable amount of concurrent events.
+     *
+     * In order to avoid having to restart the list walks for every
+     * callback we make, we'll make use a list generation number that is
+     * incremented everytime the list is changed. So, if it remains
+     * unchanged over a callback we can safely continue the iteration.
+     */
+    uint32_t iDone = ASMAtomicIncU32(&g_iRTPowerDoneBit);
+    iDone %= RT_SIZEOFMEMB(RTPOWERNOTIFYREG, bmDone) * 8;
+
+    hSpinlock = g_hRTPowerNotifySpinLock;
+    if (hSpinlock == NIL_RTSPINLOCK)
+        return VERR_ACCESS_DENIED;
+    RTSpinlockAcquire(hSpinlock);
+
+    /* Clear the bit. */
+    for (pCur = g_pRTPowerCallbackHead; pCur; pCur = pCur->pNext)
+        ASMAtomicBitClear(&pCur->bmDone[0], iDone);
+
+    /* Iterate the records and perform the callbacks. */
+    do
+    {
+        uint32_t const iGeneration = ASMAtomicUoReadU32(&g_iRTPowerGeneration);
+
+        pCur = g_pRTPowerCallbackHead;
+        while (pCur)
+        {
+            if (!ASMAtomicBitTestAndSet(&pCur->bmDone[0], iDone))
+            {
+                PFNRTPOWERNOTIFICATION pfnCallback = pCur->pfnCallback;
+                void *pvUser = pCur->pvUser;
+                pCur = pCur->pNext;
+                RTSpinlockRelease(g_hRTPowerNotifySpinLock);
+
+                pfnCallback(enmEvent, pvUser);
+
+                /* carefully require the lock here, see RTR0MpNotificationTerm(). */
+                hSpinlock = g_hRTPowerNotifySpinLock;
+                if (hSpinlock == NIL_RTSPINLOCK)
+                    return VERR_ACCESS_DENIED;
+                RTSpinlockAcquire(hSpinlock);
+                if (ASMAtomicUoReadU32(&g_iRTPowerGeneration) != iGeneration)
+                    break;
+            }
+            else
+                pCur = pCur->pNext;
+        }
+    } while (pCur);
+
+    RTSpinlockRelease(hSpinlock);
+    return VINF_SUCCESS;
+}
+RT_EXPORT_SYMBOL(RTPowerSignalEvent);
+
+
+RTDECL(int) RTPowerNotificationRegister(PFNRTPOWERNOTIFICATION pfnCallback, void *pvUser)
+{
+    PRTPOWERNOTIFYREG   pCur;
+    PRTPOWERNOTIFYREG   pNew;
+
+    /*
+     * Validation.
+     */
+    AssertPtrReturn(pfnCallback, VERR_INVALID_POINTER);
+    AssertReturn(g_hRTPowerNotifySpinLock != NIL_RTSPINLOCK, VERR_WRONG_ORDER);
+    RT_ASSERT_PREEMPTIBLE();
+
+    RTSpinlockAcquire(g_hRTPowerNotifySpinLock);
+    for (pCur = g_pRTPowerCallbackHead; pCur; pCur = pCur->pNext)
+        if (    pCur->pvUser == pvUser
+            &&  pCur->pfnCallback == pfnCallback)
+            break;
+    RTSpinlockRelease(g_hRTPowerNotifySpinLock);
+    AssertMsgReturn(!pCur, ("pCur=%p pfnCallback=%p pvUser=%p\n", pCur, pfnCallback, pvUser), VERR_ALREADY_EXISTS);
+
+    /*
+     * Allocate a new record and attempt to insert it.
+     */
+    pNew = (PRTPOWERNOTIFYREG)RTMemAlloc(sizeof(*pNew));
+    if (!pNew)
+        return VERR_NO_MEMORY;
+
+    pNew->pNext = NULL;
+    pNew->pfnCallback = pfnCallback;
+    pNew->pvUser = pvUser;
+    memset(&pNew->bmDone[0], 0xff, sizeof(pNew->bmDone));
+
+    RTSpinlockAcquire(g_hRTPowerNotifySpinLock);
+
+    pCur = g_pRTPowerCallbackHead;
+    if (!pCur)
+        g_pRTPowerCallbackHead = pNew;
+    else
+    {
+        for (pCur = g_pRTPowerCallbackHead; ; pCur = pCur->pNext)
+            if (    pCur->pvUser == pvUser
+                &&  pCur->pfnCallback == pfnCallback)
+                break;
+            else if (!pCur->pNext)
+            {
+                pCur->pNext = pNew;
+                pCur = NULL;
+                break;
+            }
+    }
+
+    ASMAtomicIncU32(&g_iRTPowerGeneration);
+
+    RTSpinlockRelease(g_hRTPowerNotifySpinLock);
+
+    /* duplicate? */
+    if (pCur)
+    {
+        RTMemFree(pCur);
+        AssertMsgFailedReturn(("pCur=%p pfnCallback=%p pvUser=%p\n", pCur, pfnCallback, pvUser), VERR_ALREADY_EXISTS);
+    }
+
+    return VINF_SUCCESS;
+}
+RT_EXPORT_SYMBOL(RTPowerNotificationRegister);
+
+
+RTDECL(int) RTPowerNotificationDeregister(PFNRTPOWERNOTIFICATION pfnCallback, void *pvUser)
+{
+    PRTPOWERNOTIFYREG   pPrev;
+    PRTPOWERNOTIFYREG   pCur;
+
+    /*
+     * Validation.
+     */
+    AssertPtrReturn(pfnCallback, VERR_INVALID_POINTER);
+    AssertReturn(g_hRTPowerNotifySpinLock != NIL_RTSPINLOCK, VERR_WRONG_ORDER);
+    RT_ASSERT_INTS_ON();
+
+    /*
+     * Find and unlink the record from the list.
+     */
+    RTSpinlockAcquire(g_hRTPowerNotifySpinLock);
+    pPrev = NULL;
+    for (pCur = g_pRTPowerCallbackHead; pCur; pCur = pCur->pNext)
+    {
+        if (    pCur->pvUser == pvUser
+            &&  pCur->pfnCallback == pfnCallback)
+            break;
+        pPrev = pCur;
+    }
+    if (pCur)
+    {
+        if (pPrev)
+            pPrev->pNext = pCur->pNext;
+        else
+            g_pRTPowerCallbackHead = pCur->pNext;
+        ASMAtomicIncU32(&g_iRTPowerGeneration);
+    }
+    RTSpinlockRelease(g_hRTPowerNotifySpinLock);
+
+    if (!pCur)
+        return VERR_NOT_FOUND;
+
+    /*
+     * Invalidate and free the record.
+     */
+    pCur->pNext = NULL;
+    pCur->pfnCallback = NULL;
+    RTMemFree(pCur);
+
+    return VINF_SUCCESS;
+}
+RT_EXPORT_SYMBOL(RTPowerNotificationDeregister);
+
+
+DECLHIDDEN(int) rtR0PowerNotificationInit(void)
+{
+    int rc = RTSpinlockCreate((PRTSPINLOCK)&g_hRTPowerNotifySpinLock, RTSPINLOCK_FLAGS_INTERRUPT_SAFE, "RTR0Power");
+    if (RT_SUCCESS(rc))
+    {
+        /** @todo OS specific init here */
+        return rc;
+#if 0
+        RTSpinlockDestroy(g_hRTPowerNotifySpinLock);
+        g_hRTPowerNotifySpinLock = NIL_RTSPINLOCK;
+#endif
+    }
+    return rc;
+}
+
+
+DECLHIDDEN(void) rtR0PowerNotificationTerm(void)
+{
+    PRTPOWERNOTIFYREG   pHead;
+    RTSPINLOCK          hSpinlock = g_hRTPowerNotifySpinLock;
+    AssertReturnVoid(hSpinlock != NIL_RTSPINLOCK);
+
+    /** @todo OS specific term here */
+
+    /* pick up the list and the spinlock. */
+    RTSpinlockAcquire(hSpinlock);
+    ASMAtomicWriteHandle(&g_hRTPowerNotifySpinLock, NIL_RTSPINLOCK);
+    pHead = g_pRTPowerCallbackHead;
+    g_pRTPowerCallbackHead = NULL;
+    ASMAtomicIncU32(&g_iRTPowerGeneration);
+    RTSpinlockRelease(hSpinlock);
+
+    /* free the list. */
+    while (pHead)
+    {
+        PRTPOWERNOTIFYREG pFree = pHead;
+        pHead = pHead->pNext;
+
+        pFree->pNext = NULL;
+        pFree->pfnCallback = NULL;
+        RTMemFree(pFree);
+    }
+
+    RTSpinlockDestroy(hSpinlock);
+}
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/vboxguest/GenericRequest.c
@@ -0,0 +1,170 @@
+/* $Id: GenericRequest.cpp $ */
+/** @file
+ * VBoxGuestLibR0 - Generic VMMDev request management.
+ */
+
+/*
+ * Copyright (C) 2006-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+#include "VBGLInternal.h"
+#include <iprt/asm.h>
+#include <iprt/asm-amd64-x86.h>
+#include <iprt/assert.h>
+#include <iprt/string.h>
+
+
+DECLVBGL(int) VbglGRVerify(const VMMDevRequestHeader *pReq, size_t cbReq)
+{
+    size_t cbReqExpected;
+
+    if (RT_UNLIKELY(!pReq || cbReq < sizeof(VMMDevRequestHeader)))
+    {
+        dprintf(("VbglGRVerify: Invalid parameter: pReq = %p, cbReq = %zu\n", pReq, cbReq));
+        return VERR_INVALID_PARAMETER;
+    }
+
+    if (RT_UNLIKELY(pReq->size > cbReq))
+    {
+        dprintf(("VbglGRVerify: request size %u > buffer size %zu\n", pReq->size, cbReq));
+        return VERR_INVALID_PARAMETER;
+    }
+
+    /* The request size must correspond to the request type. */
+    cbReqExpected = vmmdevGetRequestSize(pReq->requestType);
+    if (RT_UNLIKELY(cbReq < cbReqExpected))
+    {
+        dprintf(("VbglGRVerify: buffer size %zu < expected size %zu\n", cbReq, cbReqExpected));
+        return VERR_INVALID_PARAMETER;
+    }
+
+    if (cbReqExpected == cbReq)
+    {
+        /*
+         * This is most likely a fixed size request, and in this case the
+         * request size must be also equal to the expected size.
+         */
+        if (RT_UNLIKELY(pReq->size != cbReqExpected))
+        {
+            dprintf(("VbglGRVerify: request size %u != expected size %zu\n", pReq->size, cbReqExpected));
+            return VERR_INVALID_PARAMETER;
+        }
+
+        return VINF_SUCCESS;
+    }
+
+    /*
+     * This can be a variable size request. Check the request type and limit the size
+     * to VMMDEV_MAX_VMMDEVREQ_SIZE, which is max size supported by the host.
+     *
+     * Note: Keep this list sorted for easier human lookup!
+     */
+    if (   pReq->requestType == VMMDevReq_ChangeMemBalloon
+#ifdef VBOX_WITH_64_BITS_GUESTS
+        || pReq->requestType == VMMDevReq_HGCMCall32
+        || pReq->requestType == VMMDevReq_HGCMCall64
+#else
+        || pReq->requestType == VMMDevReq_HGCMCall
+#endif
+        || pReq->requestType == VMMDevReq_RegisterSharedModule
+        || pReq->requestType == VMMDevReq_ReportGuestUserState
+        || pReq->requestType == VMMDevReq_LogString
+        || pReq->requestType == VMMDevReq_SetPointerShape
+        || pReq->requestType == VMMDevReq_VideoSetVisibleRegion)
+    {
+        if (RT_UNLIKELY(cbReq > VMMDEV_MAX_VMMDEVREQ_SIZE))
+        {
+            dprintf(("VbglGRVerify: VMMDevReq_LogString: buffer size %zu too big\n", cbReq));
+            return VERR_BUFFER_OVERFLOW; /** @todo is this error code ok? */
+        }
+    }
+    else
+    {
+        dprintf(("VbglGRVerify: request size %u > buffer size %zu\n", pReq->size, cbReq));
+        return VERR_IO_BAD_LENGTH; /** @todo is this error code ok? */
+    }
+
+    return VINF_SUCCESS;
+}
+
+DECLVBGL(int) VbglGRAlloc(VMMDevRequestHeader **ppReq, size_t cbReq, VMMDevRequestType enmReqType)
+{
+    int rc = vbglR0Enter();
+    if (RT_SUCCESS(rc))
+    {
+        if (   ppReq
+            && cbReq >= sizeof(VMMDevRequestHeader)
+            && cbReq == (uint32_t)cbReq)
+        {
+            VMMDevRequestHeader *pReq = (VMMDevRequestHeader *)VbglPhysHeapAlloc((uint32_t)cbReq);
+            AssertMsgReturn(pReq, ("VbglGRAlloc: no memory (cbReq=%u)\n", cbReq), VERR_NO_MEMORY);
+            memset(pReq, 0xAA, cbReq);
+
+            pReq->size        = (uint32_t)cbReq;
+            pReq->version     = VMMDEV_REQUEST_HEADER_VERSION;
+            pReq->requestType = enmReqType;
+            pReq->rc          = VERR_GENERAL_FAILURE;
+            pReq->reserved1   = 0;
+            pReq->reserved2   = 0;
+
+            *ppReq = pReq;
+            rc = VINF_SUCCESS;
+        }
+        else
+        {
+            dprintf(("VbglGRAlloc: Invalid parameter: ppReq=%p cbReq=%u\n", ppReq, cbReq));
+            rc = VERR_INVALID_PARAMETER;
+        }
+    }
+    return rc;
+}
+
+DECLVBGL(int) VbglGRPerform(VMMDevRequestHeader *pReq)
+{
+    int rc = vbglR0Enter();
+    if (RT_SUCCESS(rc))
+    {
+        if (pReq)
+        {
+            RTCCPHYS PhysAddr = VbglPhysHeapGetPhysAddr(pReq);
+            if (   PhysAddr != 0
+                && PhysAddr < _4G) /* Port IO is 32 bit. */
+            {
+                ASMOutU32(g_vbgldata.portVMMDev + VMMDEV_PORT_OFF_REQUEST, (uint32_t)PhysAddr);
+                /* Make the compiler aware that the host has changed memory. */
+                ASMCompilerBarrier();
+                rc = pReq->rc;
+            }
+            else
+                rc = VERR_VBGL_INVALID_ADDR;
+        }
+        else
+            rc = VERR_INVALID_PARAMETER;
+    }
+    return rc;
+}
+
+DECLVBGL(void) VbglGRFree(VMMDevRequestHeader *pReq)
+{
+    int rc = vbglR0Enter();
+    if (RT_SUCCESS(rc))
+        VbglPhysHeapFree(pReq);
+}
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/vboxguest/HGCMInternal.c
@@ -0,0 +1,1075 @@
+/* $Id: HGCMInternal.cpp $ */
+/** @file
+ * VBoxGuestLib - Host-Guest Communication Manager internal functions, implemented by VBoxGuest
+ */
+
+/*
+ * Copyright (C) 2006-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+/* Entire file is ifdef'ed with VBGL_VBOXGUEST */
+#ifdef VBGL_VBOXGUEST
+
+
+/*********************************************************************************************************************************
+*   Header Files                                                                                                                 *
+*********************************************************************************************************************************/
+#define LOG_GROUP LOG_GROUP_HGCM
+
+#include "VBGLInternal.h"
+#include <iprt/alloca.h>
+#include <iprt/asm.h>
+#include <iprt/assert.h>
+#include <iprt/mem.h>
+#include <iprt/memobj.h>
+#include <iprt/string.h>
+#include <iprt/thread.h>
+#include <iprt/time.h>
+
+
+/*********************************************************************************************************************************
+*   Defined Constants And Macros                                                                                                 *
+*********************************************************************************************************************************/
+/** The max parameter buffer size for a user request. */
+#define VBGLR0_MAX_HGCM_USER_PARM       (24*_1M)
+/** The max parameter buffer size for a kernel request. */
+#define VBGLR0_MAX_HGCM_KERNEL_PARM     (16*_1M)
+#if defined(RT_OS_LINUX) || defined(RT_OS_DARWIN)
+/** Linux needs to use bounce buffers since RTR0MemObjLockUser has unwanted
+ * side effects.
+ * Darwin 32bit & 64bit also needs this because of 4GB/4GB user/kernel space. */
+# define USE_BOUNCE_BUFFERS
+#endif
+
+
+/*********************************************************************************************************************************
+*   Structures and Typedefs                                                                                                      *
+*********************************************************************************************************************************/
+/**
+ * Lock info structure used by VbglR0HGCMInternalCall and its helpers.
+ */
+struct VbglR0ParmInfo
+{
+    uint32_t cLockBufs;
+    struct
+    {
+        uint32_t    iParm;
+        RTR0MEMOBJ  hObj;
+#ifdef USE_BOUNCE_BUFFERS
+        void       *pvSmallBuf;
+#endif
+    } aLockBufs[10];
+};
+
+
+
+/* These functions can be only used by VBoxGuest. */
+
+DECLVBGL(int) VbglR0HGCMInternalConnect (VBoxGuestHGCMConnectInfo *pConnectInfo,
+                                         PFNVBGLHGCMCALLBACK pfnAsyncCallback, void *pvAsyncData, uint32_t u32AsyncData)
+{
+    VMMDevHGCMConnect *pHGCMConnect;
+    int rc;
+
+    if (!pConnectInfo || !pfnAsyncCallback)
+        return VERR_INVALID_PARAMETER;
+
+    pHGCMConnect = NULL;
+
+    /* Allocate request */
+    rc = VbglGRAlloc ((VMMDevRequestHeader **)&pHGCMConnect, sizeof (VMMDevHGCMConnect), VMMDevReq_HGCMConnect);
+
+    if (RT_SUCCESS(rc))
+    {
+        /* Initialize request memory */
+        pHGCMConnect->header.fu32Flags = 0;
+
+        memcpy (&pHGCMConnect->loc, &pConnectInfo->Loc, sizeof (HGCMServiceLocation));
+        pHGCMConnect->u32ClientID = 0;
+
+        /* Issue request */
+        rc = VbglGRPerform (&pHGCMConnect->header.header);
+
+        if (RT_SUCCESS(rc))
+        {
+            /* Check if host decides to process the request asynchronously. */
+            if (rc == VINF_HGCM_ASYNC_EXECUTE)
+            {
+                /* Wait for request completion interrupt notification from host */
+                pfnAsyncCallback (&pHGCMConnect->header, pvAsyncData, u32AsyncData);
+            }
+
+            pConnectInfo->result = pHGCMConnect->header.result;
+
+            if (RT_SUCCESS (pConnectInfo->result))
+                pConnectInfo->u32ClientID = pHGCMConnect->u32ClientID;
+        }
+
+        VbglGRFree (&pHGCMConnect->header.header);
+    }
+
+    return rc;
+}
+
+
+DECLR0VBGL(int) VbglR0HGCMInternalDisconnect (VBoxGuestHGCMDisconnectInfo *pDisconnectInfo,
+                                              PFNVBGLHGCMCALLBACK pfnAsyncCallback, void *pvAsyncData, uint32_t u32AsyncData)
+{
+    VMMDevHGCMDisconnect *pHGCMDisconnect;
+    int rc;
+
+    if (!pDisconnectInfo || !pfnAsyncCallback)
+        return VERR_INVALID_PARAMETER;
+
+    pHGCMDisconnect = NULL;
+
+    /* Allocate request */
+    rc = VbglGRAlloc ((VMMDevRequestHeader **)&pHGCMDisconnect, sizeof (VMMDevHGCMDisconnect), VMMDevReq_HGCMDisconnect);
+
+    if (RT_SUCCESS(rc))
+    {
+        /* Initialize request memory */
+        pHGCMDisconnect->header.fu32Flags = 0;
+
+        pHGCMDisconnect->u32ClientID = pDisconnectInfo->u32ClientID;
+
+        /* Issue request */
+        rc = VbglGRPerform (&pHGCMDisconnect->header.header);
+
+        if (RT_SUCCESS(rc))
+        {
+            /* Check if host decides to process the request asynchronously. */
+            if (rc == VINF_HGCM_ASYNC_EXECUTE)
+            {
+                /* Wait for request completion interrupt notification from host */
+                pfnAsyncCallback (&pHGCMDisconnect->header, pvAsyncData, u32AsyncData);
+            }
+
+            pDisconnectInfo->result = pHGCMDisconnect->header.result;
+        }
+
+        VbglGRFree (&pHGCMDisconnect->header.header);
+    }
+
+    return rc;
+}
+
+
+/**
+ * Preprocesses the HGCM call, validating and locking/buffering parameters.
+ *
+ * @returns VBox status code.
+ *
+ * @param   pCallInfo       The call info.
+ * @param   cbCallInfo      The size of the call info structure.
+ * @param   fIsUser         Is it a user request or kernel request.
+ * @param   pcbExtra        Where to return the extra request space needed for
+ *                          physical page lists.
+ */
+static int vbglR0HGCMInternalPreprocessCall(VBoxGuestHGCMCallInfo const *pCallInfo, uint32_t cbCallInfo,
+                                            bool fIsUser, struct VbglR0ParmInfo *pParmInfo,  size_t *pcbExtra)
+{
+    HGCMFunctionParameter const *pSrcParm = VBOXGUEST_HGCM_CALL_PARMS(pCallInfo);
+    uint32_t    cParms = pCallInfo->cParms;
+    uint32_t    iParm;
+    uint32_t    cb;
+
+    /*
+     * Lock down the any linear buffers so we can get their addresses
+     * and figure out how much extra storage we need for page lists.
+     *
+     * Note! With kernel mode users we can be assertive. For user mode users
+     *       we should just (debug) log it and fail without any fanfare.
+     */
+    *pcbExtra = 0;
+    pParmInfo->cLockBufs = 0;
+    for (iParm = 0; iParm < cParms; iParm++, pSrcParm++)
+    {
+        switch (pSrcParm->type)
+        {
+            case VMMDevHGCMParmType_32bit:
+                Log4(("GstHGCMCall: parm=%u type=32bit: %#010x\n", iParm, pSrcParm->u.value32));
+                break;
+
+            case VMMDevHGCMParmType_64bit:
+                Log4(("GstHGCMCall: parm=%u type=64bit: %#018RX64\n", iParm, pSrcParm->u.value64));
+                break;
+
+            case VMMDevHGCMParmType_PageList:
+                if (fIsUser)
+                    return VERR_INVALID_PARAMETER;
+                cb = pSrcParm->u.PageList.size;
+                if (cb)
+                {
+                    uint32_t            off = pSrcParm->u.PageList.offset;
+                    HGCMPageListInfo   *pPgLst;
+                    uint32_t            cPages;
+                    uint32_t            u32;
+
+                    AssertMsgReturn(cb <= VBGLR0_MAX_HGCM_KERNEL_PARM, ("%#x > %#x\n", cb, VBGLR0_MAX_HGCM_KERNEL_PARM),
+                                    VERR_OUT_OF_RANGE);
+                    AssertMsgReturn(   off >= pCallInfo->cParms * sizeof(HGCMFunctionParameter)
+                                    && off <= cbCallInfo - sizeof(HGCMPageListInfo),
+                                    ("offset=%#x cParms=%#x cbCallInfo=%#x\n", off, pCallInfo->cParms, cbCallInfo),
+                                    VERR_INVALID_PARAMETER);
+
+                    pPgLst = (HGCMPageListInfo *)((uint8_t *)pCallInfo + off);
+                    cPages = pPgLst->cPages;
+                    u32    = RT_OFFSETOF(HGCMPageListInfo, aPages[cPages]) + off;
+                    AssertMsgReturn(u32 <= cbCallInfo,
+                                    ("u32=%#x (cPages=%#x offset=%#x) cbCallInfo=%#x\n", u32, cPages, off, cbCallInfo),
+                                    VERR_INVALID_PARAMETER);
+                    AssertMsgReturn(pPgLst->offFirstPage < PAGE_SIZE, ("#x\n", pPgLst->offFirstPage), VERR_INVALID_PARAMETER);
+                    u32 = RT_ALIGN_32(pPgLst->offFirstPage + cb, PAGE_SIZE) >> PAGE_SHIFT;
+                    AssertMsgReturn(cPages == u32, ("cPages=%#x u32=%#x\n", cPages, u32), VERR_INVALID_PARAMETER);
+                    AssertMsgReturn(VBOX_HGCM_F_PARM_ARE_VALID(pPgLst->flags), ("%#x\n", pPgLst->flags), VERR_INVALID_PARAMETER);
+                    Log4(("GstHGCMCall: parm=%u type=pglst: cb=%#010x cPgs=%u offPg0=%#x flags=%#x\n",
+                          iParm, cb, cPages, pPgLst->offFirstPage, pPgLst->flags));
+                    u32 = cPages;
+                    while (u32-- > 0)
+                    {
+                        Log4(("GstHGCMCall:   pg#%u=%RHp\n", u32, pPgLst->aPages[u32]));
+                        AssertMsgReturn(!(pPgLst->aPages[u32] & (PAGE_OFFSET_MASK | UINT64_C(0xfff0000000000000))),
+                                        ("pg#%u=%RHp\n", u32, pPgLst->aPages[u32]),
+                                        VERR_INVALID_PARAMETER);
+                    }
+
+                    *pcbExtra += RT_OFFSETOF(HGCMPageListInfo, aPages[pPgLst->cPages]);
+                }
+                else
+                    Log4(("GstHGCMCall: parm=%u type=pglst: cb=0\n", iParm));
+                break;
+
+            case VMMDevHGCMParmType_LinAddr_Locked_In:
+            case VMMDevHGCMParmType_LinAddr_Locked_Out:
+            case VMMDevHGCMParmType_LinAddr_Locked:
+                if (fIsUser)
+                    return VERR_INVALID_PARAMETER;
+                if (!VBGLR0_CAN_USE_PHYS_PAGE_LIST(/*a_fLocked =*/ true))
+                {
+                    cb = pSrcParm->u.Pointer.size;
+                    AssertMsgReturn(cb <= VBGLR0_MAX_HGCM_KERNEL_PARM, ("%#x > %#x\n", cb, VBGLR0_MAX_HGCM_KERNEL_PARM),
+                                    VERR_OUT_OF_RANGE);
+                    if (cb != 0)
+                        Log4(("GstHGCMCall: parm=%u type=%#x: cb=%#010x pv=%p\n",
+                              iParm, pSrcParm->type, cb, pSrcParm->u.Pointer.u.linearAddr));
+                    else
+                        Log4(("GstHGCMCall: parm=%u type=%#x: cb=0\n", iParm, pSrcParm->type));
+                    break;
+                }
+                /* fall thru */
+
+            case VMMDevHGCMParmType_LinAddr_In:
+            case VMMDevHGCMParmType_LinAddr_Out:
+            case VMMDevHGCMParmType_LinAddr:
+                cb = pSrcParm->u.Pointer.size;
+                if (cb != 0)
+                {
+#ifdef USE_BOUNCE_BUFFERS
+                    void       *pvSmallBuf = NULL;
+#endif
+                    uint32_t    iLockBuf   = pParmInfo->cLockBufs;
+                    RTR0MEMOBJ  hObj;
+                    int         rc;
+                    uint32_t    fAccess =    pSrcParm->type == VMMDevHGCMParmType_LinAddr_In
+                                          || pSrcParm->type == VMMDevHGCMParmType_LinAddr_Locked_In
+                                        ? RTMEM_PROT_READ
+                                        : RTMEM_PROT_READ | RTMEM_PROT_WRITE;
+
+                    AssertReturn(iLockBuf < RT_ELEMENTS(pParmInfo->aLockBufs), VERR_INVALID_PARAMETER);
+                    if (!fIsUser)
+                    {
+                        AssertMsgReturn(cb <= VBGLR0_MAX_HGCM_KERNEL_PARM, ("%#x > %#x\n", cb, VBGLR0_MAX_HGCM_KERNEL_PARM),
+                                        VERR_OUT_OF_RANGE);
+                        rc = RTR0MemObjLockKernel(&hObj, (void *)pSrcParm->u.Pointer.u.linearAddr, cb, fAccess);
+                        if (RT_FAILURE(rc))
+                        {
+                            Log(("GstHGCMCall: id=%#x fn=%u parm=%u RTR0MemObjLockKernel(,%p,%#x) -> %Rrc\n",
+                                 pCallInfo->u32ClientID, pCallInfo->u32Function, iParm, pSrcParm->u.Pointer.u.linearAddr, cb, rc));
+                            return rc;
+                        }
+                        Log3(("GstHGCMCall: parm=%u type=%#x: cb=%#010x pv=%p locked kernel -> %p\n",
+                              iParm, pSrcParm->type, cb, pSrcParm->u.Pointer.u.linearAddr, hObj));
+                    }
+                    else if (cb > VBGLR0_MAX_HGCM_USER_PARM)
+                    {
+                        Log(("GstHGCMCall: id=%#x fn=%u parm=%u pv=%p cb=%#x > %#x -> out of range\n",
+                             pCallInfo->u32ClientID, pCallInfo->u32Function, iParm, pSrcParm->u.Pointer.u.linearAddr,
+                             cb, VBGLR0_MAX_HGCM_USER_PARM));
+                        return VERR_OUT_OF_RANGE;
+                    }
+                    else
+                    {
+#ifndef USE_BOUNCE_BUFFERS
+                        rc = RTR0MemObjLockUser(&hObj, (RTR3PTR)pSrcParm->u.Pointer.u.linearAddr, cb, fAccess, NIL_RTR0PROCESS);
+                        if (RT_FAILURE(rc))
+                        {
+                            Log(("GstHGCMCall: id=%#x fn=%u parm=%u RTR0MemObjLockUser(,%p,%#x,nil) -> %Rrc\n",
+                                 pCallInfo->u32ClientID, pCallInfo->u32Function, iParm, pSrcParm->u.Pointer.u.linearAddr, cb, rc));
+                            return rc;
+                        }
+                        Log3(("GstHGCMCall: parm=%u type=%#x: cb=%#010x pv=%p locked user -> %p\n",
+                              iParm, pSrcParm->type, cb, pSrcParm->u.Pointer.u.linearAddr, hObj));
+
+#else  /* USE_BOUNCE_BUFFERS */
+                        /*
+                         * This is a bit massive, but we don't want to waste a
+                         * whole page for a 3 byte string buffer (guest props).
+                         *
+                         * The threshold is ASSUMING sizeof(RTMEMHDR) == 16 and
+                         * the system is using some power of two allocator.
+                         */
+                        /** @todo A more efficient strategy would be to combine buffers. However it
+                         *        is probably going to be more massive than the current code, so
+                         *        it can wait till later. */
+                        bool fCopyIn = pSrcParm->type != VMMDevHGCMParmType_LinAddr_Out
+                                    && pSrcParm->type != VMMDevHGCMParmType_LinAddr_Locked_Out;
+                        if (cb <= PAGE_SIZE / 2 - 16)
+                        {
+                            pvSmallBuf = fCopyIn ? RTMemTmpAlloc(cb) : RTMemTmpAllocZ(cb);
+                            if (RT_UNLIKELY(!pvSmallBuf))
+                                return VERR_NO_MEMORY;
+                            if (fCopyIn)
+                            {
+                                rc = RTR0MemUserCopyFrom(pvSmallBuf, pSrcParm->u.Pointer.u.linearAddr, cb);
+                                if (RT_FAILURE(rc))
+                                {
+                                    RTMemTmpFree(pvSmallBuf);
+                                    Log(("GstHGCMCall: id=%#x fn=%u parm=%u RTR0MemUserCopyFrom(,%p,%#x) -> %Rrc\n",
+                                         pCallInfo->u32ClientID, pCallInfo->u32Function, iParm,
+                                         pSrcParm->u.Pointer.u.linearAddr, cb, rc));
+                                    return rc;
+                                }
+                            }
+                            rc = RTR0MemObjLockKernel(&hObj, pvSmallBuf, cb, fAccess);
+                            if (RT_FAILURE(rc))
+                            {
+                                RTMemTmpFree(pvSmallBuf);
+                                Log(("GstHGCMCall: RTR0MemObjLockKernel failed for small buffer: rc=%Rrc pvSmallBuf=%p cb=%#x\n",
+                                     rc, pvSmallBuf, cb));
+                                return rc;
+                            }
+                            Log3(("GstHGCMCall: parm=%u type=%#x: cb=%#010x pv=%p small buffer %p -> %p\n",
+                                  iParm, pSrcParm->type, cb, pSrcParm->u.Pointer.u.linearAddr, pvSmallBuf, hObj));
+                        }
+                        else
+                        {
+                            rc = RTR0MemObjAllocPage(&hObj, cb, false /*fExecutable*/);
+                            if (RT_FAILURE(rc))
+                                return rc;
+                            if (!fCopyIn)
+                                memset(RTR0MemObjAddress(hObj), '\0', cb);
+                            else
+                            {
+                                rc = RTR0MemUserCopyFrom(RTR0MemObjAddress(hObj), pSrcParm->u.Pointer.u.linearAddr, cb);
+                                if (RT_FAILURE(rc))
+                                {
+                                    RTR0MemObjFree(hObj, false /*fFreeMappings*/);
+                                    Log(("GstHGCMCall: id=%#x fn=%u parm=%u RTR0MemUserCopyFrom(,%p,%#x) -> %Rrc\n",
+                                         pCallInfo->u32ClientID, pCallInfo->u32Function, iParm,
+                                         pSrcParm->u.Pointer.u.linearAddr, cb, rc));
+                                    return rc;
+                                }
+                            }
+                            Log3(("GstHGCMCall: parm=%u type=%#x: cb=%#010x pv=%p big buffer -> %p\n",
+                                  iParm, pSrcParm->type, cb, pSrcParm->u.Pointer.u.linearAddr, hObj));
+                        }
+#endif /* USE_BOUNCE_BUFFERS */
+                    }
+
+                    pParmInfo->aLockBufs[iLockBuf].iParm      = iParm;
+                    pParmInfo->aLockBufs[iLockBuf].hObj       = hObj;
+#ifdef USE_BOUNCE_BUFFERS
+                    pParmInfo->aLockBufs[iLockBuf].pvSmallBuf = pvSmallBuf;
+#endif
+                    pParmInfo->cLockBufs = iLockBuf + 1;
+
+                    if (VBGLR0_CAN_USE_PHYS_PAGE_LIST(/*a_fLocked =*/ false))
+                    {
+                        size_t const cPages = RTR0MemObjSize(hObj) >> PAGE_SHIFT;
+                        *pcbExtra += RT_OFFSETOF(HGCMPageListInfo, aPages[cPages]);
+                    }
+                }
+                else
+                    Log4(("GstHGCMCall: parm=%u type=%#x: cb=0\n", iParm, pSrcParm->type));
+                break;
+
+            default:
+                return VERR_INVALID_PARAMETER;
+        }
+    }
+
+    return VINF_SUCCESS;
+}
+
+
+/**
+ * Translates locked linear address to the normal type.
+ * The locked types are only for the guest side and not handled by the host.
+ *
+ * @returns normal linear address type.
+ * @param   enmType     The type.
+ */
+static HGCMFunctionParameterType vbglR0HGCMInternalConvertLinAddrType(HGCMFunctionParameterType enmType)
+{
+    switch (enmType)
+    {
+        case VMMDevHGCMParmType_LinAddr_Locked_In:
+            return VMMDevHGCMParmType_LinAddr_In;
+        case VMMDevHGCMParmType_LinAddr_Locked_Out:
+            return VMMDevHGCMParmType_LinAddr_Out;
+        case VMMDevHGCMParmType_LinAddr_Locked:
+            return VMMDevHGCMParmType_LinAddr;
+        default:
+            return enmType;
+    }
+}
+
+
+/**
+ * Translates linear address types to page list direction flags.
+ *
+ * @returns page list flags.
+ * @param   enmType     The type.
+ */
+static uint32_t vbglR0HGCMInternalLinAddrTypeToPageListFlags(HGCMFunctionParameterType enmType)
+{
+    switch (enmType)
+    {
+        case VMMDevHGCMParmType_LinAddr_In:
+        case VMMDevHGCMParmType_LinAddr_Locked_In:
+            return VBOX_HGCM_F_PARM_DIRECTION_TO_HOST;
+
+        case VMMDevHGCMParmType_LinAddr_Out:
+        case VMMDevHGCMParmType_LinAddr_Locked_Out:
+            return VBOX_HGCM_F_PARM_DIRECTION_FROM_HOST;
+
+        default: AssertFailed();
+        case VMMDevHGCMParmType_LinAddr:
+        case VMMDevHGCMParmType_LinAddr_Locked:
+            return VBOX_HGCM_F_PARM_DIRECTION_BOTH;
+    }
+}
+
+
+/**
+ * Initializes the call request that we're sending to the host.
+ *
+ * @returns VBox status code.
+ *
+ * @param   pCallInfo       The call info.
+ * @param   cbCallInfo      The size of the call info structure.
+ * @param   fIsUser         Is it a user request or kernel request.
+ * @param   pcbExtra        Where to return the extra request space needed for
+ *                          physical page lists.
+ */
+static void vbglR0HGCMInternalInitCall(VMMDevHGCMCall *pHGCMCall, VBoxGuestHGCMCallInfo const *pCallInfo,
+                                       uint32_t cbCallInfo, bool fIsUser, struct VbglR0ParmInfo *pParmInfo)
+{
+    HGCMFunctionParameter const *pSrcParm = VBOXGUEST_HGCM_CALL_PARMS(pCallInfo);
+    HGCMFunctionParameter       *pDstParm = VMMDEV_HGCM_CALL_PARMS(pHGCMCall);
+    uint32_t    cParms   = pCallInfo->cParms;
+    uint32_t    offExtra = (uint32_t)((uintptr_t)(pDstParm + cParms) - (uintptr_t)pHGCMCall);
+    uint32_t    iLockBuf = 0;
+    uint32_t    iParm;
+
+
+    /*
+     * The call request headers.
+     */
+    pHGCMCall->header.fu32Flags = 0;
+    pHGCMCall->header.result    = VINF_SUCCESS;
+
+    pHGCMCall->u32ClientID = pCallInfo->u32ClientID;
+    pHGCMCall->u32Function = pCallInfo->u32Function;
+    pHGCMCall->cParms      = cParms;
+
+    /*
+     * The parameters.
+     */
+    for (iParm = 0; iParm < pCallInfo->cParms; iParm++, pSrcParm++, pDstParm++)
+    {
+        switch (pSrcParm->type)
+        {
+            case VMMDevHGCMParmType_32bit:
+            case VMMDevHGCMParmType_64bit:
+                *pDstParm = *pSrcParm;
+                break;
+
+            case VMMDevHGCMParmType_PageList:
+                pDstParm->type = VMMDevHGCMParmType_PageList;
+                pDstParm->u.PageList.size = pSrcParm->u.PageList.size;
+                if (pSrcParm->u.PageList.size)
+                {
+                    HGCMPageListInfo const *pSrcPgLst = (HGCMPageListInfo *)((uint8_t *)pCallInfo + pSrcParm->u.PageList.offset);
+                    HGCMPageListInfo       *pDstPgLst = (HGCMPageListInfo *)((uint8_t *)pHGCMCall + offExtra);
+                    uint32_t const          cPages    = pSrcPgLst->cPages;
+                    uint32_t                iPage;
+
+                    pDstParm->u.PageList.offset = offExtra;
+                    pDstPgLst->flags            = pSrcPgLst->flags;
+                    pDstPgLst->offFirstPage     = pSrcPgLst->offFirstPage;
+                    pDstPgLst->cPages           = cPages;
+                    for (iPage = 0; iPage < cPages; iPage++)
+                        pDstPgLst->aPages[iPage] = pSrcPgLst->aPages[iPage];
+
+                    offExtra += RT_OFFSETOF(HGCMPageListInfo, aPages[cPages]);
+                }
+                else
+                    pDstParm->u.PageList.offset = 0;
+                break;
+
+            case VMMDevHGCMParmType_LinAddr_Locked_In:
+            case VMMDevHGCMParmType_LinAddr_Locked_Out:
+            case VMMDevHGCMParmType_LinAddr_Locked:
+                if (!VBGLR0_CAN_USE_PHYS_PAGE_LIST(/*a_fLocked =*/ true))
+                {
+                    *pDstParm = *pSrcParm;
+                    pDstParm->type = vbglR0HGCMInternalConvertLinAddrType(pSrcParm->type);
+                    break;
+                }
+                /* fall thru */
+
+            case VMMDevHGCMParmType_LinAddr_In:
+            case VMMDevHGCMParmType_LinAddr_Out:
+            case VMMDevHGCMParmType_LinAddr:
+                if (pSrcParm->u.Pointer.size != 0)
+                {
+#ifdef USE_BOUNCE_BUFFERS
+                    void      *pvSmallBuf = pParmInfo->aLockBufs[iLockBuf].pvSmallBuf;
+#endif
+                    RTR0MEMOBJ hObj       = pParmInfo->aLockBufs[iLockBuf].hObj;
+                    Assert(iParm == pParmInfo->aLockBufs[iLockBuf].iParm);
+
+                    if (VBGLR0_CAN_USE_PHYS_PAGE_LIST(/*a_fLocked =*/ false))
+                    {
+                        HGCMPageListInfo   *pDstPgLst = (HGCMPageListInfo *)((uint8_t *)pHGCMCall + offExtra);
+                        size_t const        cPages    = RTR0MemObjSize(hObj) >> PAGE_SHIFT;
+                        size_t              iPage;
+
+                        pDstParm->type = VMMDevHGCMParmType_PageList;
+                        pDstParm->u.PageList.size   = pSrcParm->u.Pointer.size;
+                        pDstParm->u.PageList.offset = offExtra;
+                        pDstPgLst->flags            = vbglR0HGCMInternalLinAddrTypeToPageListFlags(pSrcParm->type);
+#ifdef USE_BOUNCE_BUFFERS
+                        if (fIsUser)
+                            pDstPgLst->offFirstPage = (uintptr_t)pvSmallBuf & PAGE_OFFSET_MASK;
+                        else
+#endif
+                            pDstPgLst->offFirstPage = pSrcParm->u.Pointer.u.linearAddr & PAGE_OFFSET_MASK;
+                        pDstPgLst->cPages           = (uint32_t)cPages; Assert(pDstPgLst->cPages == cPages);
+                        for (iPage = 0; iPage < cPages; iPage++)
+                        {
+                            pDstPgLst->aPages[iPage] = RTR0MemObjGetPagePhysAddr(hObj, iPage);
+                            Assert(pDstPgLst->aPages[iPage] != NIL_RTHCPHYS);
+                        }
+
+                        offExtra += RT_OFFSETOF(HGCMPageListInfo, aPages[cPages]);
+                    }
+                    else
+                    {
+                        pDstParm->type = vbglR0HGCMInternalConvertLinAddrType(pSrcParm->type);
+                        pDstParm->u.Pointer.size = pSrcParm->u.Pointer.size;
+#ifdef USE_BOUNCE_BUFFERS
+                        if (fIsUser)
+                            pDstParm->u.Pointer.u.linearAddr = pvSmallBuf
+                                                             ? (uintptr_t)pvSmallBuf
+                                                             : (uintptr_t)RTR0MemObjAddress(hObj);
+                        else
+#endif
+                            pDstParm->u.Pointer.u.linearAddr = pSrcParm->u.Pointer.u.linearAddr;
+                    }
+                    iLockBuf++;
+                }
+                else
+                {
+                    pDstParm->type = vbglR0HGCMInternalConvertLinAddrType(pSrcParm->type);
+                    pDstParm->u.Pointer.size = 0;
+                    pDstParm->u.Pointer.u.linearAddr = 0;
+                }
+                break;
+
+            default:
+                AssertFailed();
+                pDstParm->type = VMMDevHGCMParmType_Invalid;
+                break;
+        }
+    }
+}
+
+
+/**
+ * Performs the call and completion wait.
+ *
+ * @returns VBox status code of this operation, not necessarily the call.
+ *
+ * @param   pHGCMCall           The HGCM call info.
+ * @param   pfnAsyncCallback    The async callback that will wait for the call
+ *                              to complete.
+ * @param   pvAsyncData         Argument for the callback.
+ * @param   u32AsyncData        Argument for the callback.
+ * @param   pfLeakIt            Where to return the leak it / free it,
+ *                              indicator. Cancellation fun.
+ */
+static int vbglR0HGCMInternalDoCall(VMMDevHGCMCall *pHGCMCall, PFNVBGLHGCMCALLBACK pfnAsyncCallback,
+                                    void *pvAsyncData, uint32_t u32AsyncData, bool *pfLeakIt)
+{
+    int rc;
+
+    Log(("calling VbglGRPerform\n"));
+    rc = VbglGRPerform(&pHGCMCall->header.header);
+    Log(("VbglGRPerform rc = %Rrc (header rc=%d)\n", rc, pHGCMCall->header.result));
+
+    /*
+     * If the call failed, but as a result of the request itself, then pretend
+     * success. Upper layers will interpret the result code in the packet.
+     */
+    if (    RT_FAILURE(rc)
+        &&  rc == pHGCMCall->header.result)
+    {
+        Assert(pHGCMCall->header.fu32Flags & VBOX_HGCM_REQ_DONE);
+        rc = VINF_SUCCESS;
+    }
+
+    /*
+     * Check if host decides to process the request asynchronously,
+     * if so, we wait for it to complete using the caller supplied callback.
+     */
+    *pfLeakIt = false;
+    if (rc == VINF_HGCM_ASYNC_EXECUTE)
+    {
+        Log(("Processing HGCM call asynchronously\n"));
+        rc = pfnAsyncCallback(&pHGCMCall->header, pvAsyncData, u32AsyncData);
+        if (pHGCMCall->header.fu32Flags & VBOX_HGCM_REQ_DONE)
+        {
+            Assert(!(pHGCMCall->header.fu32Flags & VBOX_HGCM_REQ_CANCELLED));
+            rc = VINF_SUCCESS;
+        }
+        else
+        {
+            /*
+             * The request didn't complete in time or the call was interrupted,
+             * the RC from the callback indicates which. Try cancel the request.
+             *
+             * This is a bit messy because we're racing request completion. Sorry.
+             */
+            /** @todo It would be nice if we could use the waiter callback to do further
+             *  waiting in case of a completion race. If it wasn't for WINNT having its own
+             *  version of all that stuff, I would've done it already. */
+            VMMDevHGCMCancel2 *pCancelReq;
+            int rc2 = VbglGRAlloc((VMMDevRequestHeader **)&pCancelReq, sizeof(*pCancelReq), VMMDevReq_HGCMCancel2);
+            if (RT_SUCCESS(rc2))
+            {
+                pCancelReq->physReqToCancel = VbglPhysHeapGetPhysAddr(pHGCMCall);
+                rc2 = VbglGRPerform(&pCancelReq->header);
+                VbglGRFree(&pCancelReq->header);
+            }
+#if 1 /** @todo ADDVER: Remove this on next minor version change. */
+            if (rc2 == VERR_NOT_IMPLEMENTED)
+            {
+                /* host is too old, or we're out of heap. */
+                pHGCMCall->header.fu32Flags |= VBOX_HGCM_REQ_CANCELLED;
+                pHGCMCall->header.header.requestType = VMMDevReq_HGCMCancel;
+                rc2 = VbglGRPerform(&pHGCMCall->header.header);
+                if (rc2 == VERR_INVALID_PARAMETER)
+                    rc2 = VERR_NOT_FOUND;
+                else if (RT_SUCCESS(rc))
+                    RTThreadSleep(1);
+            }
+#endif
+            if (RT_SUCCESS(rc)) rc = VERR_INTERRUPTED; /** @todo weed this out from the WINNT VBoxGuest code. */
+            if (RT_SUCCESS(rc2))
+            {
+                Log(("vbglR0HGCMInternalDoCall: successfully cancelled\n"));
+                pHGCMCall->header.fu32Flags |= VBOX_HGCM_REQ_CANCELLED;
+            }
+            else
+            {
+                /*
+                 * Wait for a bit while the host (hopefully) completes it.
+                 */
+                uint64_t u64Start       = RTTimeSystemMilliTS();
+                uint32_t cMilliesToWait = rc2 == VERR_NOT_FOUND || rc2 == VERR_SEM_DESTROYED ? 500 : 2000;
+                uint64_t cElapsed       = 0;
+                if (rc2 != VERR_NOT_FOUND)
+                {
+                    static unsigned s_cErrors = 0;
+                    if (s_cErrors++ < 32)
+                        LogRel(("vbglR0HGCMInternalDoCall: Failed to cancel the HGCM call on %Rrc: rc2=%Rrc\n", rc, rc2));
+                }
+                else
+                    Log(("vbglR0HGCMInternalDoCall: Cancel race rc=%Rrc rc2=%Rrc\n", rc, rc2));
+
+                do
+                {
+                    ASMCompilerBarrier();       /* paranoia */
+                    if (pHGCMCall->header.fu32Flags & VBOX_HGCM_REQ_DONE)
+                        break;
+                    RTThreadSleep(1);
+                    cElapsed = RTTimeSystemMilliTS() - u64Start;
+                } while (cElapsed < cMilliesToWait);
+
+                ASMCompilerBarrier();           /* paranoia^2 */
+                if (pHGCMCall->header.fu32Flags & VBOX_HGCM_REQ_DONE)
+                    rc = VINF_SUCCESS;
+                else
+                {
+                    LogRel(("vbglR0HGCMInternalDoCall: Leaking %u bytes. Pending call to %u with %u parms. (rc2=%Rrc)\n",
+                            pHGCMCall->header.header.size, pHGCMCall->u32Function, pHGCMCall->cParms, rc2));
+                    *pfLeakIt = true;
+                }
+                Log(("vbglR0HGCMInternalDoCall: Cancel race ended with rc=%Rrc (rc2=%Rrc) after %llu ms\n", rc, rc2, cElapsed));
+            }
+        }
+    }
+
+    Log(("GstHGCMCall: rc=%Rrc result=%Rrc fu32Flags=%#x fLeakIt=%d\n",
+         rc, pHGCMCall->header.result, pHGCMCall->header.fu32Flags, *pfLeakIt));
+    return rc;
+}
+
+
+/**
+ * Copies the result of the call back to the caller info structure and user
+ * buffers (if using bounce buffers).
+ *
+ * @returns rc, unless RTR0MemUserCopyTo fails.
+ * @param   pCallInfo           Call info structure to update.
+ * @param   pHGCMCall           HGCM call request.
+ * @param   pParmInfo           Parameter locking/buffering info.
+ * @param   fIsUser             Is it a user (true) or kernel request.
+ * @param   rc                  The current result code. Passed along to
+ *                              preserve informational status codes.
+ */
+static int vbglR0HGCMInternalCopyBackResult(VBoxGuestHGCMCallInfo *pCallInfo, VMMDevHGCMCall const *pHGCMCall,
+                                            struct VbglR0ParmInfo *pParmInfo, bool fIsUser, int rc)
+{
+    HGCMFunctionParameter const *pSrcParm = VMMDEV_HGCM_CALL_PARMS(pHGCMCall);
+    HGCMFunctionParameter       *pDstParm = VBOXGUEST_HGCM_CALL_PARMS(pCallInfo);
+    uint32_t    cParms   = pCallInfo->cParms;
+#ifdef USE_BOUNCE_BUFFERS
+    uint32_t    iLockBuf = 0;
+#endif
+    uint32_t    iParm;
+
+    /*
+     * The call result.
+     */
+    pCallInfo->result = pHGCMCall->header.result;
+
+    /*
+     * Copy back parameters.
+     */
+    for (iParm = 0; iParm < cParms; iParm++, pSrcParm++, pDstParm++)
+    {
+        switch (pDstParm->type)
+        {
+            case VMMDevHGCMParmType_32bit:
+            case VMMDevHGCMParmType_64bit:
+                *pDstParm = *pSrcParm;
+                break;
+
+            case VMMDevHGCMParmType_PageList:
+                pDstParm->u.PageList.size = pSrcParm->u.PageList.size;
+                break;
+
+            case VMMDevHGCMParmType_LinAddr_Locked_In:
+            case VMMDevHGCMParmType_LinAddr_In:
+#ifdef USE_BOUNCE_BUFFERS
+                if (    fIsUser
+                    &&  iLockBuf < pParmInfo->cLockBufs
+                    &&  iParm   == pParmInfo->aLockBufs[iLockBuf].iParm)
+                    iLockBuf++;
+#endif
+                pDstParm->u.Pointer.size = pSrcParm->u.Pointer.size;
+                break;
+
+            case VMMDevHGCMParmType_LinAddr_Locked_Out:
+            case VMMDevHGCMParmType_LinAddr_Locked:
+                if (!VBGLR0_CAN_USE_PHYS_PAGE_LIST(/*a_fLocked =*/ true))
+                {
+                    pDstParm->u.Pointer.size = pSrcParm->u.Pointer.size;
+                    break;
+                }
+                /* fall thru */
+
+            case VMMDevHGCMParmType_LinAddr_Out:
+            case VMMDevHGCMParmType_LinAddr:
+            {
+#ifdef USE_BOUNCE_BUFFERS
+                if (fIsUser)
+                {
+                    size_t cbOut = RT_MIN(pSrcParm->u.Pointer.size, pDstParm->u.Pointer.size);
+                    if (cbOut)
+                    {
+                        int rc2;
+                        Assert(pParmInfo->aLockBufs[iLockBuf].iParm == iParm);
+                        rc2 = RTR0MemUserCopyTo((RTR3PTR)pDstParm->u.Pointer.u.linearAddr,
+                                                pParmInfo->aLockBufs[iLockBuf].pvSmallBuf
+                                                ? pParmInfo->aLockBufs[iLockBuf].pvSmallBuf
+                                                : RTR0MemObjAddress(pParmInfo->aLockBufs[iLockBuf].hObj),
+                                                cbOut);
+                        if (RT_FAILURE(rc2))
+                            return rc2;
+                        iLockBuf++;
+                    }
+                    else if (   iLockBuf < pParmInfo->cLockBufs
+                             && iParm   == pParmInfo->aLockBufs[iLockBuf].iParm)
+                        iLockBuf++;
+                }
+#endif
+                pDstParm->u.Pointer.size = pSrcParm->u.Pointer.size;
+                break;
+            }
+
+            default:
+                AssertFailed();
+                rc = VERR_INTERNAL_ERROR_4;
+                break;
+        }
+    }
+
+#ifdef USE_BOUNCE_BUFFERS
+    Assert(!fIsUser || pParmInfo->cLockBufs == iLockBuf);
+#endif
+    return rc;
+}
+
+
+DECLR0VBGL(int) VbglR0HGCMInternalCall(VBoxGuestHGCMCallInfo *pCallInfo, uint32_t cbCallInfo, uint32_t fFlags,
+                                       PFNVBGLHGCMCALLBACK pfnAsyncCallback, void *pvAsyncData, uint32_t u32AsyncData)
+{
+    bool                    fIsUser = (fFlags & VBGLR0_HGCMCALL_F_MODE_MASK) == VBGLR0_HGCMCALL_F_USER;
+    struct VbglR0ParmInfo   ParmInfo;
+    size_t                  cbExtra;
+    int                     rc;
+
+    /*
+     * Basic validation.
+     */
+    AssertMsgReturn(   !pCallInfo
+                    || !pfnAsyncCallback
+                    || pCallInfo->cParms > VBOX_HGCM_MAX_PARMS
+                    || !(fFlags & ~VBGLR0_HGCMCALL_F_MODE_MASK),
+                    ("pCallInfo=%p pfnAsyncCallback=%p fFlags=%#x\n", pCallInfo, pfnAsyncCallback, fFlags),
+                    VERR_INVALID_PARAMETER);
+    AssertReturn(   cbCallInfo >= sizeof(VBoxGuestHGCMCallInfo)
+                 || cbCallInfo >= pCallInfo->cParms * sizeof(HGCMFunctionParameter),
+                 VERR_INVALID_PARAMETER);
+
+    Log(("GstHGCMCall: u32ClientID=%#x u32Function=%u cParms=%u cbCallInfo=%#x fFlags=%#x\n",
+         pCallInfo->u32ClientID, pCallInfo->u32ClientID, pCallInfo->u32Function, pCallInfo->cParms, cbCallInfo, fFlags));
+
+    /*
+     * Validate, lock and buffer the parameters for the call.
+     * This will calculate the amount of extra space for physical page list.
+     */
+    rc = vbglR0HGCMInternalPreprocessCall(pCallInfo, cbCallInfo, fIsUser, &ParmInfo, &cbExtra);
+    if (RT_SUCCESS(rc))
+    {
+        /*
+         * Allocate the request buffer and recreate the call request.
+         */
+        VMMDevHGCMCall *pHGCMCall;
+        rc = VbglGRAlloc((VMMDevRequestHeader **)&pHGCMCall,
+                         sizeof(VMMDevHGCMCall) + pCallInfo->cParms * sizeof(HGCMFunctionParameter) + cbExtra,
+                         VMMDevReq_HGCMCall);
+        if (RT_SUCCESS(rc))
+        {
+            bool fLeakIt;
+            vbglR0HGCMInternalInitCall(pHGCMCall, pCallInfo, cbCallInfo, fIsUser, &ParmInfo);
+
+            /*
+             * Perform the call.
+             */
+            rc = vbglR0HGCMInternalDoCall(pHGCMCall, pfnAsyncCallback, pvAsyncData, u32AsyncData, &fLeakIt);
+            if (RT_SUCCESS(rc))
+            {
+                /*
+                 * Copy back the result (parameters and buffers that changed).
+                 */
+                rc = vbglR0HGCMInternalCopyBackResult(pCallInfo, pHGCMCall, &ParmInfo, fIsUser, rc);
+            }
+            else
+            {
+                if (   rc != VERR_INTERRUPTED
+                    && rc != VERR_TIMEOUT)
+                {
+                    static unsigned s_cErrors = 0;
+                    if (s_cErrors++ < 32)
+                        LogRel(("VbglR0HGCMInternalCall: vbglR0HGCMInternalDoCall failed. rc=%Rrc\n", rc));
+                }
+            }
+
+            if (!fLeakIt)
+                VbglGRFree(&pHGCMCall->header.header);
+        }
+    }
+    else
+        LogRel(("VbglR0HGCMInternalCall: vbglR0HGCMInternalPreprocessCall failed. rc=%Rrc\n", rc));
+
+    /*
+     * Release locks and free bounce buffers.
+     */
+    if (ParmInfo.cLockBufs)
+        while (ParmInfo.cLockBufs-- > 0)
+        {
+            RTR0MemObjFree(ParmInfo.aLockBufs[ParmInfo.cLockBufs].hObj, false /*fFreeMappings*/);
+#ifdef USE_BOUNCE_BUFFERS
+            RTMemTmpFree(ParmInfo.aLockBufs[ParmInfo.cLockBufs].pvSmallBuf);
+#endif
+        }
+
+    return rc;
+}
+
+
+#if ARCH_BITS == 64
+DECLR0VBGL(int) VbglR0HGCMInternalCall32(VBoxGuestHGCMCallInfo *pCallInfo, uint32_t cbCallInfo, uint32_t fFlags,
+                                         PFNVBGLHGCMCALLBACK pfnAsyncCallback, void *pvAsyncData, uint32_t u32AsyncData)
+{
+    VBoxGuestHGCMCallInfo   *pCallInfo64 = NULL;
+    HGCMFunctionParameter   *pParm64 = NULL;
+    HGCMFunctionParameter32 *pParm32 = NULL;
+    uint32_t                 cParms = 0;
+    uint32_t                 iParm = 0;
+    int                      rc = VINF_SUCCESS;
+
+    /*
+     * Input validation.
+     */
+    AssertMsgReturn(    !pCallInfo
+                    ||  !pfnAsyncCallback
+                    ||  pCallInfo->cParms > VBOX_HGCM_MAX_PARMS
+                    || !(fFlags & ~VBGLR0_HGCMCALL_F_MODE_MASK),
+                    ("pCallInfo=%p pfnAsyncCallback=%p fFlags=%#x\n", pCallInfo, pfnAsyncCallback, fFlags),
+                    VERR_INVALID_PARAMETER);
+    AssertReturn(   cbCallInfo >= sizeof(VBoxGuestHGCMCallInfo)
+                 || cbCallInfo >= pCallInfo->cParms * sizeof(HGCMFunctionParameter32),
+                 VERR_INVALID_PARAMETER);
+
+    /* This Assert does not work on Solaris/Windows 64/32 mixed mode, not sure why, skipping for now */
+#if !defined(RT_OS_SOLARIS) && !defined(RT_OS_WINDOWS)
+    AssertReturn((fFlags & VBGLR0_HGCMCALL_F_MODE_MASK) == VBGLR0_HGCMCALL_F_KERNEL, VERR_WRONG_ORDER);
+#endif
+
+    cParms = pCallInfo->cParms;
+    Log(("VbglR0HGCMInternalCall32: cParms=%d, u32Function=%d, fFlags=%#x\n", cParms, pCallInfo->u32Function, fFlags));
+
+    /*
+     * The simple approach, allocate a temporary request and convert the parameters.
+     */
+    pCallInfo64 = (VBoxGuestHGCMCallInfo *)RTMemTmpAllocZ(sizeof(*pCallInfo64) + cParms * sizeof(HGCMFunctionParameter));
+    if (!pCallInfo64)
+        return VERR_NO_TMP_MEMORY;
+
+    *pCallInfo64 = *pCallInfo;
+    pParm32 = VBOXGUEST_HGCM_CALL_PARMS32(pCallInfo);
+    pParm64 = VBOXGUEST_HGCM_CALL_PARMS(pCallInfo64);
+    for (iParm = 0; iParm < cParms; iParm++, pParm32++, pParm64++)
+    {
+        switch (pParm32->type)
+        {
+            case VMMDevHGCMParmType_32bit:
+                pParm64->type      = VMMDevHGCMParmType_32bit;
+                pParm64->u.value32 = pParm32->u.value32;
+                break;
+
+            case VMMDevHGCMParmType_64bit:
+                pParm64->type      = VMMDevHGCMParmType_64bit;
+                pParm64->u.value64 = pParm32->u.value64;
+                break;
+
+            case VMMDevHGCMParmType_LinAddr_Out:
+            case VMMDevHGCMParmType_LinAddr:
+            case VMMDevHGCMParmType_LinAddr_In:
+                pParm64->type                   = pParm32->type;
+                pParm64->u.Pointer.size         = pParm32->u.Pointer.size;
+                pParm64->u.Pointer.u.linearAddr = pParm32->u.Pointer.u.linearAddr;
+                break;
+
+            default:
+                rc = VERR_INVALID_PARAMETER;
+                LogRel(("VbglR0HGCMInternalCall32: pParm32 type %#x invalid.\n", pParm32->type));
+                break;
+        }
+        if (RT_FAILURE(rc))
+            break;
+    }
+    if (RT_SUCCESS(rc))
+    {
+        rc = VbglR0HGCMInternalCall(pCallInfo64, sizeof(*pCallInfo64) + cParms * sizeof(HGCMFunctionParameter), fFlags,
+                                    pfnAsyncCallback, pvAsyncData, u32AsyncData);
+
+        if (RT_SUCCESS(rc))
+        {
+            *pCallInfo = *pCallInfo64;
+
+            /*
+             * Copy back.
+             */
+            pParm32 = VBOXGUEST_HGCM_CALL_PARMS32(pCallInfo);
+            pParm64 = VBOXGUEST_HGCM_CALL_PARMS(pCallInfo64);
+            for (iParm = 0; iParm < cParms; iParm++, pParm32++, pParm64++)
+            {
+                switch (pParm64->type)
+                {
+                    case VMMDevHGCMParmType_32bit:
+                        pParm32->u.value32 = pParm64->u.value32;
+                        break;
+
+                    case VMMDevHGCMParmType_64bit:
+                        pParm32->u.value64 = pParm64->u.value64;
+                        break;
+
+                    case VMMDevHGCMParmType_LinAddr_Out:
+                    case VMMDevHGCMParmType_LinAddr:
+                    case VMMDevHGCMParmType_LinAddr_In:
+                        pParm32->u.Pointer.size = pParm64->u.Pointer.size;
+                        break;
+
+                    default:
+                        LogRel(("VbglR0HGCMInternalCall32: failed invalid pParm32 type %d\n", pParm32->type));
+                        rc = VERR_INTERNAL_ERROR_3;
+                        break;
+                }
+            }
+        }
+        else
+        {
+            static unsigned s_cErrors = 0;
+            if (s_cErrors++ < 32)
+                LogRel(("VbglR0HGCMInternalCall32: VbglR0HGCMInternalCall failed. rc=%Rrc\n", rc));
+        }
+    }
+    else
+    {
+        static unsigned s_cErrors = 0;
+        if (s_cErrors++ < 32)
+            LogRel(("VbglR0HGCMInternalCall32: failed. rc=%Rrc\n", rc));
+    }
+
+    RTMemTmpFree(pCallInfo64);
+    return rc;
+}
+#endif /* ARCH_BITS == 64 */
+
+#endif /* VBGL_VBOXGUEST */
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/vboxguest/Init.c
@@ -0,0 +1,310 @@
+/* $Id: Init.cpp $ */
+/** @file
+ * VBoxGuestLibR0 - Library initialization.
+ */
+
+/*
+ * Copyright (C) 2006-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+
+/*********************************************************************************************************************************
+*   Header Files                                                                                                                 *
+*********************************************************************************************************************************/
+#define VBGL_DECL_DATA
+#include "VBGLInternal.h"
+
+#include <iprt/string.h>
+#include <iprt/assert.h>
+#include <iprt/semaphore.h>
+
+
+/*********************************************************************************************************************************
+*   Global Variables                                                                                                             *
+*********************************************************************************************************************************/
+/** The global VBGL instance data.  */
+VBGLDATA g_vbgldata;
+
+/**
+ * Used by vbglQueryDriverInfo and VbglInit to try get the host feature mask and
+ * version information (g_vbgldata::hostVersion).
+ *
+ * This was first implemented by the host in 3.1 and we quietly ignore failures
+ * for that reason.
+ */
+static void vbglR0QueryHostVersion (void)
+{
+    VMMDevReqHostVersion *pReq;
+
+    int rc = VbglGRAlloc ((VMMDevRequestHeader **) &pReq, sizeof (*pReq), VMMDevReq_GetHostVersion);
+
+    if (RT_SUCCESS (rc))
+    {
+        rc = VbglGRPerform (&pReq->header);
+
+        if (RT_SUCCESS (rc))
+        {
+            g_vbgldata.hostVersion = *pReq;
+            Log (("vbglR0QueryHostVersion: %u.%u.%ur%u %#x\n",
+                  pReq->major, pReq->minor, pReq->build, pReq->revision, pReq->features));
+        }
+
+        VbglGRFree (&pReq->header);
+    }
+}
+
+#ifndef VBGL_VBOXGUEST
+/**
+ * The guest library uses lazy initialization for VMMDev port and memory,
+ * because these values are provided by the VBoxGuest driver and it might
+ * be loaded later than other drivers.
+ *
+ * The VbglEnter checks the current library status, tries to retrieve these
+ * values and fails if they are unavailable.
+ *
+ */
+static void vbglQueryDriverInfo (void)
+{
+    int rc = VINF_SUCCESS;
+
+    rc = RTSemMutexRequest(g_vbgldata.mutexDriverInit, RT_INDEFINITE_WAIT);
+
+    if (RT_FAILURE(rc))
+        return;
+
+    if (g_vbgldata.status == VbglStatusReady)
+    {
+        RTSemMutexRelease(g_vbgldata.mutexDriverInit);
+        return;
+    }
+
+    rc = vbglDriverOpen(&g_vbgldata.driver);
+
+    if (RT_SUCCESS(rc))
+    {
+        /*
+         * Try query the port info.
+         */
+        VBoxGuestPortInfo port;
+
+        rc = vbglDriverIOCtl (&g_vbgldata.driver,
+                              VBOXGUEST_IOCTL_GETVMMDEVPORT, &port,
+                              sizeof (port));
+
+        if (RT_SUCCESS (rc))
+        {
+            dprintf (("port = 0x%04X, mem = %p\n", port.portAddress, port.pVMMDevMemory));
+
+            g_vbgldata.portVMMDev = (RTIOPORT)port.portAddress;
+            g_vbgldata.pVMMDevMemory = port.pVMMDevMemory;
+
+            g_vbgldata.status = VbglStatusReady;
+
+            vbglR0QueryHostVersion();
+        }
+    }
+    RTSemMutexRelease(g_vbgldata.mutexDriverInit);
+    dprintf (("vbglQueryDriverInfo rc = %d\n", rc));
+}
+#endif /* !VBGL_VBOXGUEST */
+
+/**
+ * Checks if VBGL has been initialized.
+ *
+ * The client library, this will lazily complete the initialization.
+ *
+ * @return VINF_SUCCESS or VERR_VBGL_NOT_INITIALIZED.
+ */
+int vbglR0Enter (void)
+{
+    int rc;
+
+#ifndef VBGL_VBOXGUEST
+    if (g_vbgldata.status == VbglStatusInitializing)
+    {
+        vbglQueryDriverInfo ();
+    }
+#endif
+
+    rc = g_vbgldata.status == VbglStatusReady? VINF_SUCCESS: VERR_VBGL_NOT_INITIALIZED;
+
+    // dprintf(("VbglEnter: rc = %d\n", rc));
+
+    return rc;
+}
+
+int vbglInitCommon (void)
+{
+    int rc = VINF_SUCCESS;
+
+    RT_ZERO(g_vbgldata);
+
+    g_vbgldata.status = VbglStatusInitializing;
+
+    rc = VbglPhysHeapInit ();
+
+    if (RT_SUCCESS(rc))
+    {
+        /* other subsystems, none yet */
+        ;
+    }
+    else
+    {
+        LogRel(("vbglInitCommon: VbglPhysHeapInit failed. rc=%Rrc\n", rc));
+        g_vbgldata.status = VbglStatusNotInitialized;
+    }
+
+    dprintf(("vbglInitCommon: rc = %d\n", rc));
+
+    return rc;
+}
+
+DECLVBGL(void) vbglTerminateCommon (void)
+{
+    VbglPhysHeapTerminate ();
+    g_vbgldata.status = VbglStatusNotInitialized;
+
+    return;
+}
+
+#ifdef VBGL_VBOXGUEST
+
+DECLVBGL(int) VbglInitPrimary(RTIOPORT portVMMDev, VMMDevMemory *pVMMDevMemory)
+{
+    int rc = VINF_SUCCESS;
+
+# ifdef RT_OS_WINDOWS /** @todo r=bird: this doesn't make sense. Is there something special going on on windows? */
+    dprintf(("vbglInit: starts g_vbgldata.status %d\n", g_vbgldata.status));
+
+    if (   g_vbgldata.status == VbglStatusInitializing
+        || g_vbgldata.status == VbglStatusReady)
+    {
+        /* Initialization is already in process. */
+        return rc;
+    }
+# else
+    dprintf(("vbglInit: starts\n"));
+# endif
+
+    rc = vbglInitCommon ();
+
+    if (RT_SUCCESS(rc))
+    {
+        g_vbgldata.portVMMDev = portVMMDev;
+        g_vbgldata.pVMMDevMemory = pVMMDevMemory;
+
+        g_vbgldata.status = VbglStatusReady;
+
+        vbglR0QueryHostVersion();
+    }
+    else
+    {
+        g_vbgldata.status = VbglStatusNotInitialized;
+    }
+
+    return rc;
+}
+
+DECLVBGL(void) VbglTerminate (void)
+{
+    vbglTerminateCommon ();
+
+    return;
+}
+
+
+#else /* !VBGL_VBOXGUEST */
+
+DECLVBGL(int) VbglInitClient(void)
+{
+    int rc = VINF_SUCCESS;
+
+    if (   g_vbgldata.status == VbglStatusInitializing
+        || g_vbgldata.status == VbglStatusReady)
+    {
+        /* Initialization is already in process. */
+        return rc;
+    }
+
+    rc = vbglInitCommon ();
+
+    if (RT_SUCCESS(rc))
+    {
+        rc = RTSemMutexCreate(&g_vbgldata.mutexDriverInit);
+        if (RT_SUCCESS(rc))
+        {
+            /* Try to obtain VMMDev port via IOCTL to VBoxGuest main driver. */
+            vbglQueryDriverInfo ();
+
+# ifdef VBOX_WITH_HGCM
+            rc = vbglR0HGCMInit ();
+# endif /* VBOX_WITH_HGCM */
+
+            if (RT_FAILURE(rc))
+            {
+                RTSemMutexDestroy(g_vbgldata.mutexDriverInit);
+                g_vbgldata.mutexDriverInit = NIL_RTSEMMUTEX;
+            }
+        }
+
+        if (RT_FAILURE(rc))
+        {
+            vbglTerminateCommon ();
+        }
+
+    }
+
+    return rc;
+}
+
+DECLVBGL(void) VbglTerminate (void)
+{
+# ifdef VBOX_WITH_HGCM
+    vbglR0HGCMTerminate ();
+# endif
+
+    /* driver open could fail, which does not prevent VbglInit from succeeding,
+     * close the driver only if it is opened */
+    if (vbglDriverIsOpened(&g_vbgldata.driver))
+        vbglDriverClose(&g_vbgldata.driver);
+    RTSemMutexDestroy(g_vbgldata.mutexDriverInit);
+    g_vbgldata.mutexDriverInit = NIL_RTSEMMUTEX;
+
+    /* note: do vbglTerminateCommon as a last step since it zeroez up the g_vbgldata
+     * conceptually, doing vbglTerminateCommon last is correct
+     * since this is the reverse order to how init is done */
+    vbglTerminateCommon ();
+
+    return;
+}
+
+int vbglGetDriver(VBGLDRIVER **ppDriver)
+{
+    if (g_vbgldata.status != VbglStatusReady)
+    {
+        vbglQueryDriverInfo();
+        if (g_vbgldata.status != VbglStatusReady)
+            return VERR_TRY_AGAIN;
+    }
+    *ppDriver = &g_vbgldata.driver;
+    return VINF_SUCCESS;
+}
+
+#endif /* !VBGL_VBOXGUEST */
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/vboxguest/Makefile
@@ -0,0 +1,148 @@
+KBUILD_EXTMOD=${srctree}/ubuntu/vbox
+# $Revision: 98752 $
+## @file
+# VirtualBox Guest Additions Module Makefile.
+#
+
+#
+# Copyright (C) 2006-2015 Oracle Corporation
+#
+# This file is part of VirtualBox Open Source Edition (OSE), as
+# available from http://www.virtualbox.org. This file is free software;
+# you can redistribute it and/or modify it under the terms of the GNU
+# General Public License (GPL) as published by the Free Software
+# Foundation, in version 2 as it comes in the "COPYING" file of the
+# VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+# hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+#
+
+# Linux kbuild sets this to our source directory if we are called from there
+obj ?= $(CURDIR)
+include $(obj)/Makefile.include.header
+
+MOD_NAME = vboxguest
+
+MOD_OBJS   = \
+	VBoxGuest-linux.o \
+	VBoxGuest.o \
+	GenericRequest.o \
+	HGCMInternal.o \
+	Init.o \
+	PhysHeap.o \
+	SysHlp.o \
+	VMMDev.o \
+	r0drv/alloc-r0drv.o \
+	r0drv/initterm-r0drv.o \
+	r0drv/memobj-r0drv.o \
+	r0drv/mpnotification-r0drv.o \
+	r0drv/powernotification-r0drv.o \
+	r0drv/linux/alloc-r0drv-linux.o \
+	r0drv/linux/assert-r0drv-linux.o \
+	r0drv/linux/initterm-r0drv-linux.o \
+	r0drv/linux/memobj-r0drv-linux.o \
+	r0drv/linux/memuserkernel-r0drv-linux.o \
+	r0drv/linux/mp-r0drv-linux.o \
+	r0drv/linux/mpnotification-r0drv-linux.o \
+	r0drv/linux/process-r0drv-linux.o \
+	r0drv/linux/semevent-r0drv-linux.o \
+	r0drv/linux/semeventmulti-r0drv-linux.o \
+	r0drv/linux/semfastmutex-r0drv-linux.o \
+	r0drv/linux/semmutex-r0drv-linux.o \
+	r0drv/linux/spinlock-r0drv-linux.o \
+	r0drv/linux/thread-r0drv-linux.o \
+	r0drv/linux/thread2-r0drv-linux.o \
+	r0drv/linux/time-r0drv-linux.o \
+	r0drv/linux/timer-r0drv-linux.o \
+	r0drv/linux/RTLogWriteDebugger-r0drv-linux.o \
+	r0drv/generic/semspinmutex-r0drv-generic.o \
+	common/alloc/alloc.o \
+	common/err/RTErrConvertFromErrno.o \
+	common/err/RTErrConvertToErrno.o \
+	common/log/log.o \
+        common/log/logellipsis.o \
+        common/log/logrel.o \
+        common/log/logrelellipsis.o \
+        common/log/logcom.o \
+	common/log/logformat.o \
+	common/misc/RTAssertMsg1Weak.o \
+	common/misc/RTAssertMsg2.o \
+	common/misc/RTAssertMsg2Add.o \
+	common/misc/RTAssertMsg2AddWeak.o \
+	common/misc/RTAssertMsg2AddWeakV.o \
+	common/misc/RTAssertMsg2Weak.o \
+	common/misc/RTAssertMsg2WeakV.o \
+	common/misc/assert.o \
+	common/misc/thread.o \
+	common/string/RTStrCopy.o \
+	common/string/RTStrCopyEx.o \
+	common/string/RTStrCopyP.o \
+	common/string/strformat.o \
+	common/string/strformatrt.o \
+	common/string/strformattype.o \
+	common/string/strprintf.o \
+	common/string/strtonum.o \
+	common/table/avlpv.o \
+	common/time/time.o \
+	generic/RTAssertShouldPanic-generic.o \
+        generic/RTLogWriteStdErr-stub-generic.o \
+        generic/RTLogWriteStdOut-stub-generic.o \
+	generic/RTMpGetCoreCount-generic.o \
+	generic/RTSemEventWait-2-ex-generic.o \
+	generic/RTSemEventWaitNoResume-2-ex-generic.o \
+	generic/RTSemEventMultiWait-2-ex-generic.o \
+	generic/RTSemEventMultiWaitNoResume-2-ex-generic.o \
+	generic/errvars-generic.o \
+	generic/mppresent-generic.o \
+	VBox/log-vbox.o \
+	VBox/logbackdoor.o
+ifeq ($(BUILD_TARGET_ARCH),x86)
+MOD_OBJS += \
+	common/math/gcc/divdi3.o \
+	common/math/gcc/moddi3.o \
+	common/math/gcc/udivdi3.o \
+	common/math/gcc/umoddi3.o \
+	common/math/gcc/qdivrem.o
+endif
+ifeq ($(BUILD_TARGET_ARCH),amd64)
+MOD_OBJS +=	common/alloc/heapsimple.o
+endif
+
+MOD_DEFS = -DVBOX -DRT_OS_LINUX -DIN_RING0 -DIN_RT_R0 -DIN_GUEST \
+            -DIN_GUEST_R0 -DIN_MODULE -DRT_WITH_VBOX -DVBGL_VBOXGUEST \
+            -DVBOX_WITH_HGCM
+ifeq ($(BUILD_TARGET_ARCH),amd64)
+ MOD_DEFS  += -DRT_ARCH_AMD64
+else
+ MOD_DEFS  += -DRT_ARCH_X86
+endif
+ifeq ($(BUILD_TARGET_ARCH),amd64)
+ MOD_DEFS += -DVBOX_WITH_64_BITS_GUESTS
+endif
+MOD_INCL  = $(addprefix -I$(KBUILD_EXTMOD),/ /include /r0drv/linux)
+MOD_INCL += $(addprefix -I$(KBUILD_EXTMOD)/vboxguest,/ /include /r0drv/linux)
+
+ifneq ($(wildcard $(KBUILD_EXTMOD)/vboxguest),)
+ MANGLING := $(KBUILD_EXTMOD)/vboxguest/include/VBox/VBoxGuestMangling.h
+else
+ MANGLING := $(KBUILD_EXTMOD)/include/VBox/VBoxGuestMangling.h
+endif
+ifeq ($(KERN_VERSION),24)
+ ## @todo move to MOD_DEFS when we have finished refactoring
+ MOD_CFLAGS = -DEXPORT_SYMTAB
+else
+ MOD_CFLAGS = -Wno-declaration-after-statement -include $(MANGLING)
+endif
+
+MOD_CLEAN = . linux r0drv generic r0drv/linux r0drv/generic VBox \
+		common/alloc common/err common/log common/math/gcc common/misc \
+		common/string common/time
+
+include $(obj)/Makefile.include.footer
+
+check: $(MOD_NAME)
+	@if ! readelf -p __ksymtab_strings vboxguest.ko | grep -E "\[.*\]  *(RT|g_..*RT.*)"; then \
+	    echo "All exported IPRT symbols are properly renamed!"; \
+	 else \
+	    echo "error: Some exported IPRT symbols was not properly renamed! See above." >&2; \
+	    false; \
+	 fi
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/vboxguest/Makefile.include.footer
@@ -0,0 +1,96 @@
+#
+# VirtualBox Guest Additions kernel module Makefile, common parts.
+#
+# See Makefile.include.header for details of how to use this.
+#
+# Copyright (C) 2006-2015 Oracle Corporation
+#
+# This file is part of VirtualBox Open Source Edition (OSE), as
+# available from http://www.virtualbox.org. This file is free software;
+# you can redistribute it and/or modify it under the terms of the GNU
+# General Public License (GPL) as published by the Free Software
+# Foundation, in version 2 as it comes in the "COPYING" file of the
+# VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+# hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+#
+
+# override is required by the Debian guys
+override MODULE = $(MOD_NAME)
+OBJS   = $(MOD_OBJS)
+
+ifneq ($(MAKECMDGOALS),clean)
+
+KBUILD_VERBOSE ?= 1
+
+#
+# Compiler options
+#
+ifndef INCL
+ INCL    := $(addprefix -I,$(KERN_INCL) $(EXTRA_INCL))
+ ifndef KBUILD_EXTMOD
+  KBUILD_EXTMOD := $(shell pwd)
+ endif
+ INCL    += $(MOD_INCL)
+ export INCL
+endif
+KFLAGS   := -D__KERNEL__ -DMODULE $(MOD_DEFS)
+ifeq ($(BUILD_TYPE),debug)
+ KFLAGS  += -DDEBUG -DDEBUG_$(subst $(subst _, ,_),_,$(USERNAME)) -DDEBUG_USERNAME=$(subst $(subst _, ,_),_,$(USERNAME))
+endif
+
+ifeq ($(KERN_VERSION), 24)
+#
+# 2.4
+#
+
+ifeq ($(BUILD_TARGET_ARCH),amd64)
+ KFLAGS  += -mcmodel=kernel
+endif
+
+CFLAGS := -O2 -DVBOX_LINUX_2_4 $(MOD_CFLAGS) $(INCL) $(KFLAGS) $(MOD_EXTRA) $(KDEBUG)
+MODULE_EXT := o
+
+# 2.4 Module linking
+$(MODULE).o: $(OBJS)
+	$(LD) -o $@ -r $(OBJS)
+
+.PHONY: $(MODULE)
+all: $(MODULE)
+$(MODULE): $(MODULE).o
+
+else
+#
+# 2.6 and later
+#
+
+MODULE_EXT := ko
+
+$(MODULE)-y  := $(OBJS)
+
+# build defs
+EXTRA_CFLAGS += $(MOD_CFLAGS) $(INCL) $(KFLAGS) $(MOD_EXTRA) $(KDEBUG)
+
+all: $(MODULE)
+
+obj-m += $(MODULE).o
+
+# OL/UEK: disable module signing for external modules -- we don't have any private key
+$(MODULE):
+	$(MAKE) KBUILD_VERBOSE=$(KBUILD_VERBOSE) CONFIG_MODULE_SIG= -C $(KERN_DIR) SUBDIRS=$(CURDIR) SRCROOT=$(CURDIR) modules
+
+modules_install:
+	$(MAKE) KBUILD_VERBOSE=$(KBUILD_VERBOSE) CONFIG_MODULE_SIG= -C $(KERN_DIR) SUBDIRS=$(CURDIR) SRCROOT=$(CURDIR) modules_install
+
+endif
+
+install: $(MODULE)
+	@mkdir -p $(MODULE_DIR); \
+	install -m 0644 -o root -g root $(MODULE).$(MODULE_EXT) $(MODULE_DIR); \
+	PATH="$(PATH):/bin:/sbin" depmod -a;
+
+endif # eq($(MAKECMDGOALS),clean)
+
+# important: Don't remove Module.symvers! DKMS does 'make clean' before building ...
+clean:
+	for f in $(MOD_CLEAN); do rm -f $$f/*.o $$f/.*.cmd $$f/.*.flags; done
+	rm -rf .$(MOD_NAME)* .tmp_ver* $(MOD_NAME).* Modules.symvers modules.order
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/vboxguest/Makefile.include.header
@@ -0,0 +1,173 @@
+#
+# VirtualBox Guest Additions kernel module Makefile, common parts.
+#
+# (For 2.6.x, the main file must be called 'Makefile'!)
+#
+# Copyright (C) 2006-2015 Oracle Corporation
+#
+# This file is part of VirtualBox Open Source Edition (OSE), as
+# available from http://www.virtualbox.org. This file is free software;
+# you can redistribute it and/or modify it under the terms of the GNU
+# General Public License (GPL) as published by the Free Software
+# Foundation, in version 2 as it comes in the "COPYING" file of the
+# VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+# hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+#
+
+#
+# These file should be included by the Makefiles for any kernel modules we
+# build as part of the Guest Additions.  The intended way of doing this is as
+# follows:
+#
+# # Linux kbuild sets this to our source directory if we are called from
+# # there
+# obj ?= $(CURDIR)
+# include $(obj)/Makefile.include.header
+# MOD_NAME = <name of the module to be built, without extension>
+# MOD_OBJS = <list of object files which should be included>
+# MOD_DEFS = <any additional defines which this module needs>
+# MOD_INCL = <any additional include paths which this module needs>
+# MOD_CFLAGS = <any additional CFLAGS which this module needs>
+# MOD_CLEAN = <list of directories that the clean target should look at>
+# include $(obj)/Makefile.include.footer
+#
+# The kmk kBuild define KBUILD_TARGET_ARCH is available.
+#
+
+
+#
+# First, figure out which architecture we're targeting and the build type.
+# (We have to support basic cross building (ARCH=i386|x86_64).)
+# While at it, warn about BUILD_* vars found to help with user problems.
+#
+ifeq ($(filter-out x86_64 amd64 AMD64,$(shell uname -m)),)
+ BUILD_TARGET_ARCH_DEF := amd64
+else
+ BUILD_TARGET_ARCH_DEF := x86
+endif
+ifneq ($(filter-out amd64 x86,$(BUILD_TARGET_ARCH)),)
+ $(warning Ignoring unknown BUILD_TARGET_ARCH value '$(BUILD_TARGET_ARCH)'.)
+ BUILD_TARGET_ARCH :=
+endif
+ifeq ($(BUILD_TARGET_ARCH),)
+ ifeq ($(ARCH),x86_64)
+  BUILD_TARGET_ARCH := amd64
+ else
+  ifeq ($(ARCH),i386)
+   ifeq ($(CONFIG_X86_32),y)
+     BUILD_TARGET_ARCH := x86
+   else
+     BUILD_TARGET_ARCH := amd64
+   endif
+  else
+    ifeq ($(ARCH),x86)
+      ifeq ($(CONFIG_X86_32),y)
+        BUILD_TARGET_ARCH := x86
+      else
+        BUILD_TARGET_ARCH := amd64
+      endif
+    else
+      BUILD_TARGET_ARCH := $(BUILD_TARGET_ARCH_DEF)
+    endif
+  endif
+ endif
+else
+ ifneq ($(BUILD_TARGET_ARCH),$(BUILD_TARGET_ARCH_DEF))
+  $(warning Using BUILD_TARGET_ARCH='$(BUILD_TARGET_ARCH)' from the $(origin BUILD_TARGET_ARCH).)
+ endif
+endif
+
+ifneq ($(filter-out release profile debug strict,$(BUILD_TYPE)),)
+ $(warning Ignoring unknown BUILD_TYPE value '$(BUILD_TYPE)'.)
+ BUILD_TYPE :=
+endif
+ifeq ($(BUILD_TYPE),)
+ BUILD_TYPE := release
+else
+ ifneq ($(BUILD_TYPE),release)
+  $(warning Using BUILD_TYPE='$(BUILD_TYPE)' from the $(origin BUILD_TYPE).)
+ endif
+endif
+ifeq ($(USERNAME),)
+ USERNAME := noname
+endif
+
+ifneq ($(MAKECMDGOALS),clean)
+
+ifeq ($(KERNELRELEASE),)
+
+ #
+ # building from this directory
+ #
+
+ # kernel base directory
+ ifndef KERN_DIR
+  KERN_DIR := /lib/modules/$(shell uname -r)/build
+  ifneq ($(shell if test -d $(KERN_DIR); then echo yes; fi),yes)
+   KERN_DIR := /usr/src/linux
+   ifneq ($(shell if test -d $(KERN_DIR); then echo yes; fi),yes)
+    $(error Error: unable to find the sources of your current Linux kernel. \
+	           Specify KERN_DIR=<directory> and run Make again)
+   endif
+   $(warning Warning: using /usr/src/linux as the source directory of your \
+                      Linux kernel. If this is not correct, specify \
+		      KERN_DIR=<directory> and run Make again.)
+  endif
+ else
+  ifneq ($(shell if test -d $(KERN_DIR); then echo yes; fi),yes)
+   $(error Error: KERN_DIR does not point to a directory)
+  endif
+ endif
+
+ # includes
+ ifndef KERN_INCL
+  KERN_INCL = $(KERN_DIR)/include
+ endif
+ ifneq ($(shell if test -d $(KERN_INCL); then echo yes; fi),yes)
+  $(error Error: unable to find the include directory for your current Linux \
+                 kernel. Specify KERN_INCL=<directory> and run Make again)
+ endif
+
+ # module install dir, only for current kernel
+ ifneq ($(filter install install_rpm,$(MAKECMDGOALS)),)
+  ifndef MODULE_DIR
+   MODULE_DIR_TST := /lib/modules/$(shell uname -r)
+   ifeq ($(shell if test -d $(MODULE_DIR_TST); then echo yes; fi),yes)
+    MODULE_DIR := $(MODULE_DIR_TST)/misc
+   else
+    $(error Unable to find the folder to install the module to)
+   endif
+  endif # MODULE_DIR unspecified
+ endif
+
+ # guess kernel version (24 or 26)
+ ifeq ($(shell if grep '"2\.4\.' $(KERN_INCL)/linux/version.h > /dev/null; then echo yes; fi),yes)
+  KERN_VERSION := 24
+ else
+  KERN_VERSION := 26
+ endif
+
+else # neq($(KERNELRELEASE),)
+
+ #
+ # building from kbuild (make -C <kernel_directory> M=`pwd`)
+ #
+
+ # guess kernel version (24 or 26)
+ ifeq ($(shell if echo "$(VERSION).$(PATCHLEVEL)." | grep '2\.4\.' > /dev/null; then echo yes; fi),yes)
+  KERN_VERSION := 24
+ else
+  KERN_VERSION := 26
+ endif
+
+endif # neq($(KERNELRELEASE),)
+
+# debug - show guesses.
+ifdef DEBUG
+$(warning dbg: KERN_DIR     = $(KERN_DIR))
+$(warning dbg: KERN_INCL    = $(KERN_INCL))
+$(warning dbg: MODULE_DIR   = $(MODULE_DIR))
+$(warning dbg: KERN_VERSION = $(KERN_VERSION))
+endif
+
+endif # eq($(MAKECMDGOALS),clean)
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/vboxguest/PhysHeap.c
@@ -0,0 +1,636 @@
+/* $Id: PhysHeap.cpp $ */
+/** @file
+ * VBoxGuestLibR0 - Physical memory heap.
+ */
+
+/*
+ * Copyright (C) 2006-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+#include "VBGLInternal.h"
+
+#include <iprt/assert.h>
+#include <iprt/semaphore.h>
+#include <iprt/alloc.h>
+
+/* Physical memory heap consists of double linked list
+ * of chunks. Memory blocks are allocated inside these chunks
+ * and are members of Allocated and Free double linked lists.
+ *
+ * When allocating a block, we search in Free linked
+ * list for a suitable free block. If there is no such block,
+ * a new chunk is allocated and the new block is taken from
+ * the new chunk as the only chunk-sized free block.
+ * Allocated block is excluded from the Free list and goes to
+ * Alloc list.
+ *
+ * When freeing block, we check the pointer and then
+ * exclude block from Alloc list and move it to free list.
+ *
+ * For each chunk we maintain the allocated blocks counter.
+ * if 2 (or more) entire chunks are free they are immediately
+ * deallocated, so we always have at most 1 free chunk.
+ *
+ * When freeing blocks, two subsequent free blocks are always
+ * merged together. Current implementation merges blocks only
+ * when there is a block after the just freed one.
+ *
+ */
+
+#define VBGL_PH_ASSERT      Assert
+#define VBGL_PH_ASSERTMsg   AssertMsg
+
+// #define DUMPHEAP
+
+#ifdef DUMPHEAP
+# define VBGL_PH_dprintf(a) RTAssertMsg2Weak a
+#else
+# define VBGL_PH_dprintf(a)
+#endif
+
+/* Heap block signature */
+#define VBGL_PH_BLOCKSIGNATURE (0xADDBBBBB)
+
+
+/* Heap chunk signature */
+#define VBGL_PH_CHUNKSIGNATURE (0xADDCCCCC)
+/* Heap chunk allocation unit */
+#define VBGL_PH_CHUNKSIZE (0x10000)
+
+/* Heap block bit flags */
+#define VBGL_PH_BF_ALLOCATED (0x1)
+
+struct _VBGLPHYSHEAPBLOCK
+{
+    uint32_t u32Signature;
+
+    /* Size of user data in the block. Does not include the block header. */
+    uint32_t cbDataSize;
+
+    uint32_t fu32Flags;
+
+    struct _VBGLPHYSHEAPBLOCK *pNext;
+    struct _VBGLPHYSHEAPBLOCK *pPrev;
+
+    struct _VBGLPHYSHEAPCHUNK *pChunk;
+};
+
+struct _VBGLPHYSHEAPCHUNK
+{
+    uint32_t u32Signature;
+
+    /* Size of the chunk. Includes the chunk header. */
+    uint32_t cbSize;
+
+    /* Physical address of the chunk */
+    uint32_t physAddr;
+
+    /* Number of allocated blocks in the chunk */
+    int32_t cAllocatedBlocks;
+
+    struct _VBGLPHYSHEAPCHUNK *pNext;
+    struct _VBGLPHYSHEAPCHUNK *pPrev;
+};
+
+
+#ifndef DUMPHEAP
+#define dumpheap(a)
+#else
+void dumpheap (char *point)
+{
+   VBGL_PH_dprintf(("VBGL_PH dump at '%s'\n", point));
+
+   VBGL_PH_dprintf(("Chunks:\n"));
+
+   VBGLPHYSHEAPCHUNK *pChunk = g_vbgldata.pChunkHead;
+
+   while (pChunk)
+   {
+       VBGL_PH_dprintf(("%p: pNext = %p, pPrev = %p, sign = %08X, size = %8d, allocated = %8d, phys = %08X\n",
+                        pChunk, pChunk->pNext, pChunk->pPrev, pChunk->u32Signature, pChunk->cbSize, pChunk->cAllocatedBlocks, pChunk->physAddr));
+
+       pChunk = pChunk->pNext;
+   }
+
+   VBGL_PH_dprintf(("Allocated blocks:\n"));
+
+   VBGLPHYSHEAPBLOCK *pBlock = g_vbgldata.pAllocBlocksHead;
+
+   while (pBlock)
+   {
+       VBGL_PH_dprintf(("%p: pNext = %p, pPrev = %p, sign = %08X, size = %8d, flags = %08X, pChunk = %p\n",
+                        pBlock, pBlock->pNext, pBlock->pPrev, pBlock->u32Signature, pBlock->cbDataSize, pBlock->fu32Flags, pBlock->pChunk));
+
+       pBlock = pBlock->pNext;
+   }
+
+   VBGL_PH_dprintf(("Free blocks:\n"));
+
+   pBlock = g_vbgldata.pFreeBlocksHead;
+
+   while (pBlock)
+   {
+       VBGL_PH_dprintf(("%p: pNext = %p, pPrev = %p, sign = %08X, size = %8d, flags = %08X, pChunk = %p\n",
+                        pBlock, pBlock->pNext, pBlock->pPrev, pBlock->u32Signature, pBlock->cbDataSize, pBlock->fu32Flags, pBlock->pChunk));
+
+       pBlock = pBlock->pNext;
+   }
+
+   VBGL_PH_dprintf(("VBGL_PH dump at '%s' done\n", point));
+}
+#endif
+
+
+DECLINLINE(void *) vbglPhysHeapBlock2Data (VBGLPHYSHEAPBLOCK *pBlock)
+{
+    return (void *)(pBlock? (char *)pBlock + sizeof (VBGLPHYSHEAPBLOCK): NULL);
+}
+
+DECLINLINE(VBGLPHYSHEAPBLOCK *) vbglPhysHeapData2Block (void *p)
+{
+    VBGLPHYSHEAPBLOCK *pBlock = (VBGLPHYSHEAPBLOCK *)(p? (char *)p - sizeof (VBGLPHYSHEAPBLOCK): NULL);
+
+    VBGL_PH_ASSERTMsg(pBlock == NULL || pBlock->u32Signature == VBGL_PH_BLOCKSIGNATURE,
+                     ("pBlock->u32Signature = %08X\n", pBlock->u32Signature));
+
+    return pBlock;
+}
+
+DECLINLINE(int) vbglPhysHeapEnter (void)
+{
+    int rc = RTSemFastMutexRequest(g_vbgldata.mutexHeap);
+
+    VBGL_PH_ASSERTMsg(RT_SUCCESS(rc),
+                     ("Failed to request heap mutex, rc = %Rrc\n", rc));
+
+    return rc;
+}
+
+DECLINLINE(void) vbglPhysHeapLeave (void)
+{
+    RTSemFastMutexRelease(g_vbgldata.mutexHeap);
+}
+
+
+static void vbglPhysHeapInitBlock (VBGLPHYSHEAPBLOCK *pBlock, VBGLPHYSHEAPCHUNK *pChunk, uint32_t cbDataSize)
+{
+    VBGL_PH_ASSERT(pBlock != NULL);
+    VBGL_PH_ASSERT(pChunk != NULL);
+
+    pBlock->u32Signature = VBGL_PH_BLOCKSIGNATURE;
+    pBlock->cbDataSize   = cbDataSize;
+    pBlock->fu32Flags    = 0;
+    pBlock->pNext        = NULL;
+    pBlock->pPrev        = NULL;
+    pBlock->pChunk       = pChunk;
+}
+
+
+static void vbglPhysHeapInsertBlock (VBGLPHYSHEAPBLOCK *pInsertAfter, VBGLPHYSHEAPBLOCK *pBlock)
+{
+    VBGL_PH_ASSERTMsg(pBlock->pNext == NULL,
+                     ("pBlock->pNext = %p\n", pBlock->pNext));
+    VBGL_PH_ASSERTMsg(pBlock->pPrev == NULL,
+                     ("pBlock->pPrev = %p\n", pBlock->pPrev));
+
+    if (pInsertAfter)
+    {
+        pBlock->pNext = pInsertAfter->pNext;
+        pBlock->pPrev = pInsertAfter;
+
+        if (pInsertAfter->pNext)
+        {
+            pInsertAfter->pNext->pPrev = pBlock;
+        }
+
+        pInsertAfter->pNext = pBlock;
+    }
+    else
+    {
+        /* inserting to head of list */
+        pBlock->pPrev = NULL;
+
+        if (pBlock->fu32Flags & VBGL_PH_BF_ALLOCATED)
+        {
+            pBlock->pNext = g_vbgldata.pAllocBlocksHead;
+
+            if (g_vbgldata.pAllocBlocksHead)
+            {
+                g_vbgldata.pAllocBlocksHead->pPrev = pBlock;
+            }
+
+            g_vbgldata.pAllocBlocksHead = pBlock;
+        }
+        else
+        {
+            pBlock->pNext = g_vbgldata.pFreeBlocksHead;
+
+            if (g_vbgldata.pFreeBlocksHead)
+            {
+                g_vbgldata.pFreeBlocksHead->pPrev = pBlock;
+            }
+
+            g_vbgldata.pFreeBlocksHead = pBlock;
+        }
+    }
+}
+
+static void vbglPhysHeapExcludeBlock (VBGLPHYSHEAPBLOCK *pBlock)
+{
+    if (pBlock->pNext)
+    {
+        pBlock->pNext->pPrev = pBlock->pPrev;
+    }
+    else
+    {
+        /* this is tail of list but we do not maintain tails of block lists.
+         * so do nothing.
+         */
+        ;
+    }
+
+    if (pBlock->pPrev)
+    {
+        pBlock->pPrev->pNext = pBlock->pNext;
+    }
+    else
+    {
+        /* this is head of list but we do not maintain tails of block lists. */
+        if (pBlock->fu32Flags & VBGL_PH_BF_ALLOCATED)
+        {
+            g_vbgldata.pAllocBlocksHead = pBlock->pNext;
+        }
+        else
+        {
+            g_vbgldata.pFreeBlocksHead = pBlock->pNext;
+        }
+    }
+
+    pBlock->pNext = NULL;
+    pBlock->pPrev = NULL;
+}
+
+static VBGLPHYSHEAPBLOCK *vbglPhysHeapChunkAlloc (uint32_t cbSize)
+{
+    RTCCPHYS physAddr;
+    VBGLPHYSHEAPCHUNK *pChunk;
+    VBGLPHYSHEAPBLOCK *pBlock;
+    VBGL_PH_dprintf(("Allocating new chunk of size %d\n", cbSize));
+
+    /* Compute chunk size to allocate */
+    if (cbSize < VBGL_PH_CHUNKSIZE)
+    {
+        /* Includes case of block size 0 during initialization */
+        cbSize = VBGL_PH_CHUNKSIZE;
+    }
+    else
+    {
+        /* Round up to next chunk size, which must be power of 2 */
+        cbSize = (cbSize + (VBGL_PH_CHUNKSIZE - 1)) & ~(VBGL_PH_CHUNKSIZE - 1);
+    }
+
+    physAddr = 0;
+    /* This function allocates physical contiguous memory (below 4GB) according to the IPRT docs.
+     * Address < 4G is required for the port IO.
+     */
+    pChunk = (VBGLPHYSHEAPCHUNK *)RTMemContAlloc (&physAddr, cbSize);
+
+    if (!pChunk)
+    {
+        LogRel(("vbglPhysHeapChunkAlloc: failed to alloc %u contiguous bytes.\n", cbSize));
+        return NULL;
+    }
+
+    AssertRelease(physAddr < _4G && physAddr + cbSize <= _4G);
+
+    pChunk->u32Signature     = VBGL_PH_CHUNKSIGNATURE;
+    pChunk->cbSize           = cbSize;
+    pChunk->physAddr         = (uint32_t)physAddr;
+    pChunk->cAllocatedBlocks = 0;
+    pChunk->pNext            = g_vbgldata.pChunkHead;
+    pChunk->pPrev            = NULL;
+
+    /* Initialize the free block, which now occupies entire chunk. */
+    pBlock = (VBGLPHYSHEAPBLOCK *)((char *)pChunk + sizeof (VBGLPHYSHEAPCHUNK));
+
+    vbglPhysHeapInitBlock (pBlock, pChunk, cbSize - sizeof (VBGLPHYSHEAPCHUNK) - sizeof (VBGLPHYSHEAPBLOCK));
+
+    vbglPhysHeapInsertBlock (NULL, pBlock);
+
+    g_vbgldata.pChunkHead = pChunk;
+
+    VBGL_PH_dprintf(("Allocated chunk %p, block = %p size=%x\n", pChunk, pBlock, cbSize));
+
+    return pBlock;
+}
+
+
+void vbglPhysHeapChunkDelete (VBGLPHYSHEAPCHUNK *pChunk)
+{
+    char *p;
+    VBGL_PH_ASSERT(pChunk != NULL);
+    VBGL_PH_ASSERTMsg(pChunk->u32Signature == VBGL_PH_CHUNKSIGNATURE,
+                     ("pChunk->u32Signature = %08X\n", pChunk->u32Signature));
+
+    VBGL_PH_dprintf(("Deleting chunk %p size %x\n", pChunk, pChunk->cbSize));
+
+    /* first scan the chunk and exclude all blocks from lists */
+
+    p = (char *)pChunk + sizeof (VBGLPHYSHEAPCHUNK);
+
+    while (p < (char *)pChunk + pChunk->cbSize)
+    {
+        VBGLPHYSHEAPBLOCK *pBlock = (VBGLPHYSHEAPBLOCK *)p;
+
+        p += pBlock->cbDataSize + sizeof (VBGLPHYSHEAPBLOCK);
+
+        vbglPhysHeapExcludeBlock (pBlock);
+    }
+
+    VBGL_PH_ASSERTMsg(p == (char *)pChunk + pChunk->cbSize,
+                      ("p = %p, (char *)pChunk + pChunk->cbSize = %p, pChunk->cbSize = %08X\n",
+                       p, (char *)pChunk + pChunk->cbSize, pChunk->cbSize));
+
+    /* Exclude chunk from the chunk list */
+    if (pChunk->pNext)
+    {
+        pChunk->pNext->pPrev = pChunk->pPrev;
+    }
+    else
+    {
+        /* we do not maintain tail */
+        ;
+    }
+
+    if (pChunk->pPrev)
+    {
+        pChunk->pPrev->pNext = pChunk->pNext;
+    }
+    else
+    {
+        /* the chunk was head */
+        g_vbgldata.pChunkHead = pChunk->pNext;
+    }
+
+    RTMemContFree (pChunk, pChunk->cbSize);
+}
+
+
+DECLVBGL(void *) VbglPhysHeapAlloc (uint32_t cbSize)
+{
+    VBGLPHYSHEAPBLOCK *pBlock, *iter;
+    int rc = vbglPhysHeapEnter ();
+
+    if (RT_FAILURE(rc))
+        return NULL;
+
+    dumpheap ("pre alloc");
+
+    pBlock = NULL;
+
+    /* If there are free blocks in the heap, look at them. */
+    iter = g_vbgldata.pFreeBlocksHead;
+
+    /* There will be not many blocks in the heap, so
+     * linear search would be fast enough.
+     */
+
+    while (iter)
+    {
+        if (iter->cbDataSize == cbSize)
+        {
+            /* exact match */
+            pBlock = iter;
+            break;
+        }
+
+        /* Looking for a free block with nearest size */
+        if (iter->cbDataSize > cbSize)
+        {
+            if (pBlock)
+            {
+                if (iter->cbDataSize < pBlock->cbDataSize)
+                {
+                    pBlock = iter;
+                }
+            }
+            else
+            {
+                pBlock = iter;
+            }
+        }
+
+        iter = iter->pNext;
+    }
+
+    if (!pBlock)
+    {
+        /* No free blocks, allocate a new chunk,
+         * the only free block of the chunk will
+         * be returned.
+         */
+        pBlock = vbglPhysHeapChunkAlloc (cbSize);
+    }
+
+    if (pBlock)
+    {
+        VBGL_PH_ASSERTMsg(pBlock->u32Signature == VBGL_PH_BLOCKSIGNATURE,
+                         ("pBlock = %p, pBlock->u32Signature = %08X\n", pBlock, pBlock->u32Signature));
+        VBGL_PH_ASSERTMsg((pBlock->fu32Flags & VBGL_PH_BF_ALLOCATED) == 0,
+                         ("pBlock = %p, pBlock->fu32Flags = %08X\n", pBlock, pBlock->fu32Flags));
+
+        /* We have a free block, either found or allocated. */
+
+        if (pBlock->cbDataSize > 2*(cbSize + sizeof (VBGLPHYSHEAPBLOCK)))
+        {
+            /* Data will occupy less than a half of the block,
+             * the block should be split.
+             */
+            iter = (VBGLPHYSHEAPBLOCK *)((char *)pBlock + sizeof (VBGLPHYSHEAPBLOCK) + cbSize);
+
+            /* Init the new 'iter' block, initialized blocks are always marked as free. */
+            vbglPhysHeapInitBlock (iter, pBlock->pChunk, pBlock->cbDataSize - cbSize - sizeof (VBGLPHYSHEAPBLOCK));
+
+            pBlock->cbDataSize = cbSize;
+
+            /* Insert the new 'iter' block after the 'pBlock' in the free list */
+            vbglPhysHeapInsertBlock (pBlock, iter);
+        }
+
+        /* Exclude pBlock from free list */
+        vbglPhysHeapExcludeBlock (pBlock);
+
+        /* Mark as allocated */
+        pBlock->fu32Flags |= VBGL_PH_BF_ALLOCATED;
+
+        /* Insert to allocated list */
+        vbglPhysHeapInsertBlock (NULL, pBlock);
+
+        /* Adjust the chunk allocated blocks counter */
+        pBlock->pChunk->cAllocatedBlocks++;
+    }
+
+    dumpheap ("post alloc");
+
+    vbglPhysHeapLeave ();
+    VBGL_PH_dprintf(("VbglPhysHeapAlloc %x size %x\n", vbglPhysHeapBlock2Data (pBlock), pBlock->cbDataSize));
+
+    return vbglPhysHeapBlock2Data (pBlock);
+}
+
+DECLVBGL(uint32_t) VbglPhysHeapGetPhysAddr (void *p)
+{
+    uint32_t physAddr = 0;
+    VBGLPHYSHEAPBLOCK *pBlock = vbglPhysHeapData2Block (p);
+
+    if (pBlock)
+    {
+        VBGL_PH_ASSERTMsg((pBlock->fu32Flags & VBGL_PH_BF_ALLOCATED) != 0,
+                         ("pBlock = %p, pBlock->fu32Flags = %08X\n", pBlock, pBlock->fu32Flags));
+
+        if (pBlock->fu32Flags & VBGL_PH_BF_ALLOCATED)
+            physAddr = pBlock->pChunk->physAddr + (uint32_t)((uintptr_t)p - (uintptr_t)pBlock->pChunk);
+    }
+
+    return physAddr;
+}
+
+DECLVBGL(void) VbglPhysHeapFree(void *p)
+{
+    VBGLPHYSHEAPBLOCK *pBlock;
+    VBGLPHYSHEAPBLOCK *pNeighbour;
+
+    int rc = vbglPhysHeapEnter ();
+    if (RT_FAILURE(rc))
+        return;
+
+    dumpheap ("pre free");
+
+    pBlock = vbglPhysHeapData2Block (p);
+
+    if (!pBlock)
+    {
+        vbglPhysHeapLeave ();
+        return;
+    }
+
+    VBGL_PH_ASSERTMsg((pBlock->fu32Flags & VBGL_PH_BF_ALLOCATED) != 0,
+                     ("pBlock = %p, pBlock->fu32Flags = %08X\n", pBlock, pBlock->fu32Flags));
+
+    /* Exclude from allocated list */
+    vbglPhysHeapExcludeBlock (pBlock);
+
+    dumpheap ("post exclude");
+
+    VBGL_PH_dprintf(("VbglPhysHeapFree %x size %x\n", p, pBlock->cbDataSize));
+
+    /* Mark as free */
+    pBlock->fu32Flags &= ~VBGL_PH_BF_ALLOCATED;
+
+    /* Insert to free list */
+    vbglPhysHeapInsertBlock (NULL, pBlock);
+
+    dumpheap ("post insert");
+
+    /* Adjust the chunk allocated blocks counter */
+    pBlock->pChunk->cAllocatedBlocks--;
+
+    VBGL_PH_ASSERT(pBlock->pChunk->cAllocatedBlocks >= 0);
+
+    /* Check if we can merge 2 free blocks. To simplify heap maintenance,
+     * we will look at block after the just freed one.
+     * This will not prevent us from detecting free memory chunks.
+     * Also in most cases blocks are deallocated in reverse allocation order
+     * and in that case the merging will work.
+     */
+
+    pNeighbour = (VBGLPHYSHEAPBLOCK *)((char *)p + pBlock->cbDataSize);
+
+    if ((char *)pNeighbour < (char *)pBlock->pChunk + pBlock->pChunk->cbSize
+        && (pNeighbour->fu32Flags & VBGL_PH_BF_ALLOCATED) == 0)
+    {
+        /* The next block is free as well. */
+
+        /* Adjust size of current memory block */
+        pBlock->cbDataSize += pNeighbour->cbDataSize + sizeof (VBGLPHYSHEAPBLOCK);
+
+        /* Exclude the next neighbour */
+        vbglPhysHeapExcludeBlock (pNeighbour);
+    }
+
+    dumpheap ("post merge");
+
+    /* now check if there are 2 or more free chunks */
+    if (pBlock->pChunk->cAllocatedBlocks == 0)
+    {
+        VBGLPHYSHEAPCHUNK *pChunk = g_vbgldata.pChunkHead;
+
+        uint32_t u32FreeChunks = 0;
+
+        while (pChunk)
+        {
+            if (pChunk->cAllocatedBlocks == 0)
+            {
+                u32FreeChunks++;
+            }
+
+            pChunk = pChunk->pNext;
+        }
+
+        if (u32FreeChunks > 1)
+        {
+            /* Delete current chunk, it will also exclude all free blocks
+             * remaining in the chunk from the free list, so the pBlock
+             * will also be invalid after this.
+             */
+            vbglPhysHeapChunkDelete (pBlock->pChunk);
+        }
+    }
+
+    dumpheap ("post free");
+
+    vbglPhysHeapLeave ();
+}
+
+DECLVBGL(int) VbglPhysHeapInit (void)
+{
+    int rc = VINF_SUCCESS;
+
+    /* Allocate the first chunk of the heap. */
+    VBGLPHYSHEAPBLOCK *pBlock = vbglPhysHeapChunkAlloc (0);
+
+    if (!pBlock)
+        rc = VERR_NO_MEMORY;
+
+    RTSemFastMutexCreate(&g_vbgldata.mutexHeap);
+
+    return rc;
+}
+
+DECLVBGL(void) VbglPhysHeapTerminate (void)
+{
+    while (g_vbgldata.pChunkHead)
+    {
+        vbglPhysHeapChunkDelete (g_vbgldata.pChunkHead);
+    }
+
+    RTSemFastMutexDestroy(g_vbgldata.mutexHeap);
+}
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/vboxguest/SysHlp.c
@@ -0,0 +1,343 @@
+/* $Id: SysHlp.cpp $ */
+/** @file
+ * VBoxGuestLibR0 - IDC with VBoxGuest and HGCM helpers.
+ */
+
+/*
+ * Copyright (C) 2006-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+#define LOG_GROUP LOG_GROUP_HGCM
+#include <VBox/log.h>
+
+#include <VBox/VBoxGuestLib.h>
+#include "SysHlp.h"
+
+#include <iprt/assert.h>
+
+#ifdef VBGL_VBOXGUEST
+
+#if !defined (RT_OS_WINDOWS)
+# include <iprt/memobj.h>
+# include <iprt/mem.h>
+#endif
+
+
+/**
+ * Internal worker for locking a range of linear addresses.
+ *
+ * @returns VBox status code.
+ * @param   ppvCtx          Where to store context data.
+ * @param   pv              The start of the range.
+ * @param   u32Size         The size of the range.
+ * @param   fWriteAccess    Lock for read-write (true) or readonly (false).
+ * @param   fFlags          HGCM call flags, VBGLR0_HGCM_F_XXX.
+ */
+int vbglLockLinear(void **ppvCtx, void *pv, uint32_t u32Size, bool fWriteAccess, uint32_t fFlags)
+{
+    int         rc      = VINF_SUCCESS;
+#ifndef RT_OS_WINDOWS
+    RTR0MEMOBJ  MemObj  = NIL_RTR0MEMOBJ;
+    uint32_t    fAccess = RTMEM_PROT_READ | (fWriteAccess ? RTMEM_PROT_WRITE : 0);
+#endif
+
+    /* Zero size buffers shouldn't be locked. */
+    if (u32Size == 0)
+    {
+        Assert(pv == NULL);
+#ifdef RT_OS_WINDOWS
+        *ppvCtx = NULL;
+#else
+        *ppvCtx = NIL_RTR0MEMOBJ;
+#endif
+        return VINF_SUCCESS;
+    }
+
+    /** @todo just use IPRT here. the extra allocation shouldn't matter much...
+     *        Then we can move all this up one level even. */
+#ifdef RT_OS_WINDOWS
+    PMDL pMdl = IoAllocateMdl(pv, u32Size, FALSE, FALSE, NULL);
+
+    if (pMdl == NULL)
+    {
+        rc = VERR_NOT_SUPPORTED;
+        AssertMsgFailed(("IoAllocateMdl %p %x failed!!\n", pv, u32Size));
+    }
+    else
+    {
+        __try {
+            /* Calls to MmProbeAndLockPages must be enclosed in a try/except block. */
+            MmProbeAndLockPages(pMdl,
+                                /** @todo (fFlags & VBGLR0_HGCMCALL_F_MODE_MASK) == VBGLR0_HGCMCALL_F_USER? UserMode: KernelMode */
+                                KernelMode,
+                                (fWriteAccess) ? IoModifyAccess : IoReadAccess);
+
+            *ppvCtx = pMdl;
+
+        } __except(EXCEPTION_EXECUTE_HANDLER) {
+
+            IoFreeMdl(pMdl);
+            /** @todo  */
+            rc = VERR_INVALID_PARAMETER;
+            AssertMsgFailed(("MmProbeAndLockPages %p %x failed!!\n", pv, u32Size));
+        }
+    }
+
+#else
+    /*
+     * Lock depending on context.
+     *
+     * Note: We will later use the memory object here to convert the HGCM
+     *       linear buffer parameter into a physical page list. This is why
+     *       we lock both kernel pages on all systems, even those where we
+     *       know they aren't pageable.
+     */
+    if ((fFlags & VBGLR0_HGCMCALL_F_MODE_MASK) == VBGLR0_HGCMCALL_F_USER)
+        rc = RTR0MemObjLockUser(&MemObj, (RTR3PTR)pv, u32Size, fAccess, NIL_RTR0PROCESS);
+    else
+        rc = RTR0MemObjLockKernel(&MemObj, pv, u32Size, fAccess);
+    if (RT_SUCCESS(rc))
+        *ppvCtx = MemObj;
+    else
+        *ppvCtx = NIL_RTR0MEMOBJ;
+
+#endif
+
+    return rc;
+}
+
+void vbglUnlockLinear(void *pvCtx, void *pv, uint32_t u32Size)
+{
+#ifdef RT_OS_WINDOWS
+    PMDL pMdl = (PMDL)pvCtx;
+
+    Assert(pMdl);
+    if (pMdl != NULL)
+    {
+        MmUnlockPages(pMdl);
+        IoFreeMdl(pMdl);
+    }
+
+#else
+    RTR0MEMOBJ MemObj = (RTR0MEMOBJ)pvCtx;
+    int rc = RTR0MemObjFree(MemObj, false);
+    AssertRC(rc);
+
+#endif
+
+    NOREF(pv);
+    NOREF(u32Size);
+}
+
+#else  /* !VBGL_VBOXGUEST */
+
+# ifdef RT_OS_OS2
+#  include <VBox/VBoxGuest.h> /* for VBOXGUESTOS2IDCCONNECT */
+RT_C_DECLS_BEGIN
+/*
+ * On OS/2 we'll do the connecting in the assembly code of the
+ * client driver, exporting a g_VBoxGuestIDC symbol containing
+ * the connection information obtained from the 16-bit IDC.
+ */
+extern VBOXGUESTOS2IDCCONNECT g_VBoxGuestIDC;
+RT_C_DECLS_END
+# endif
+
+# if !defined(RT_OS_OS2) \
+  && !defined(RT_OS_WINDOWS)
+RT_C_DECLS_BEGIN
+extern DECLVBGL(void *) VBoxGuestIDCOpen(uint32_t *pu32Version);
+extern DECLVBGL(void)   VBoxGuestIDCClose(void *pvOpaque);
+extern DECLVBGL(int)    VBoxGuestIDCCall(void *pvOpaque, unsigned int iCmd, void *pvData, size_t cbSize, size_t *pcbReturn);
+RT_C_DECLS_END
+# endif
+
+bool vbglDriverIsOpened(VBGLDRIVER *pDriver)
+{
+# ifdef RT_OS_WINDOWS
+    return pDriver->pFileObject != NULL;
+# elif defined (RT_OS_OS2)
+    return pDriver->u32Session != UINT32_MAX && pDriver->u32Session != 0;
+# else
+    return pDriver->pvOpaque != NULL;
+# endif
+}
+
+int vbglDriverOpen(VBGLDRIVER *pDriver)
+{
+# ifdef RT_OS_WINDOWS
+    UNICODE_STRING uszDeviceName;
+    RtlInitUnicodeString(&uszDeviceName, L"\\Device\\VBoxGuest");
+
+    PDEVICE_OBJECT pDeviceObject = NULL;
+    PFILE_OBJECT pFileObject = NULL;
+
+    NTSTATUS rc = IoGetDeviceObjectPointer(&uszDeviceName, FILE_ALL_ACCESS, &pFileObject, &pDeviceObject);
+    if (NT_SUCCESS(rc))
+    {
+        Log(("vbglDriverOpen VBoxGuest successful pDeviceObject=%x\n", pDeviceObject));
+        pDriver->pDeviceObject = pDeviceObject;
+        pDriver->pFileObject = pFileObject;
+        return VINF_SUCCESS;
+    }
+    /** @todo return RTErrConvertFromNtStatus(rc)! */
+    Log(("vbglDriverOpen VBoxGuest failed with ntstatus=%x\n", rc));
+    return rc;
+
+# elif defined (RT_OS_OS2)
+    /*
+     * Just check whether the connection was made or not.
+     */
+    if (   g_VBoxGuestIDC.u32Version == VMMDEV_VERSION
+        && RT_VALID_PTR(g_VBoxGuestIDC.u32Session)
+        && RT_VALID_PTR(g_VBoxGuestIDC.pfnServiceEP))
+    {
+        pDriver->u32Session = g_VBoxGuestIDC.u32Session;
+        return VINF_SUCCESS;
+    }
+    pDriver->u32Session = UINT32_MAX;
+    Log(("vbglDriverOpen: failed\n"));
+    return VERR_FILE_NOT_FOUND;
+
+# else
+    uint32_t u32VMMDevVersion;
+    pDriver->pvOpaque = VBoxGuestIDCOpen(&u32VMMDevVersion);
+    if (   pDriver->pvOpaque
+        && u32VMMDevVersion == VMMDEV_VERSION)
+        return VINF_SUCCESS;
+
+    Log(("vbglDriverOpen: failed\n"));
+    return VERR_FILE_NOT_FOUND;
+# endif
+}
+
+# ifdef RT_OS_WINDOWS
+static NTSTATUS vbglDriverIOCtlCompletion(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context)
+{
+    Log(("VBGL completion %x\n", Irp));
+
+    KEVENT *pEvent = (KEVENT *)Context;
+    KeSetEvent(pEvent, IO_NO_INCREMENT, FALSE);
+
+    return STATUS_MORE_PROCESSING_REQUIRED;
+}
+# endif
+
+int vbglDriverIOCtl(VBGLDRIVER *pDriver, uint32_t u32Function, void *pvData, uint32_t cbData)
+{
+    Log(("vbglDriverIOCtl: pDriver: %p, Func: %x, pvData: %p, cbData: %d\n", pDriver, u32Function, pvData, cbData));
+
+# ifdef RT_OS_WINDOWS
+    KEVENT Event;
+
+    KeInitializeEvent(&Event, NotificationEvent, FALSE);
+
+    /* Have to use the IoAllocateIRP method because this code is generic and
+     * must work in any thread context.
+     * The IoBuildDeviceIoControlRequest, which was used here, does not work
+     * when APCs are disabled, for example.
+     */
+    PIRP irp = IoAllocateIrp(pDriver->pDeviceObject->StackSize, FALSE);
+
+    Log(("vbglDriverIOCtl: irp %p, IRQL = %d\n", irp, KeGetCurrentIrql()));
+
+    if (irp == NULL)
+    {
+        Log(("vbglDriverIOCtl: IRP allocation failed!\n"));
+        return VERR_NO_MEMORY;
+    }
+
+    /*
+     * Setup the IRP_MJ_DEVICE_CONTROL IRP.
+     */
+
+    PIO_STACK_LOCATION nextStack = IoGetNextIrpStackLocation(irp);
+
+    nextStack->MajorFunction = IRP_MJ_DEVICE_CONTROL;
+    nextStack->MinorFunction = 0;
+    nextStack->DeviceObject = pDriver->pDeviceObject;
+    nextStack->Parameters.DeviceIoControl.OutputBufferLength = cbData;
+    nextStack->Parameters.DeviceIoControl.InputBufferLength = cbData;
+    nextStack->Parameters.DeviceIoControl.IoControlCode = u32Function;
+    nextStack->Parameters.DeviceIoControl.Type3InputBuffer = pvData;
+
+    irp->AssociatedIrp.SystemBuffer = pvData; /* Output buffer. */
+    irp->MdlAddress = NULL;
+
+    /* A completion routine is required to signal the Event. */
+    IoSetCompletionRoutine(irp, vbglDriverIOCtlCompletion, &Event, TRUE, TRUE, TRUE);
+
+    NTSTATUS rc = IoCallDriver(pDriver->pDeviceObject, irp);
+
+    if (NT_SUCCESS (rc))
+    {
+        /* Wait the event to be signalled by the completion routine. */
+        KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
+
+        rc = irp->IoStatus.Status;
+
+        Log(("vbglDriverIOCtl: wait completed IRQL = %d\n", KeGetCurrentIrql()));
+    }
+
+    IoFreeIrp(irp);
+
+    if (rc != STATUS_SUCCESS)
+        Log(("vbglDriverIOCtl: ntstatus=%x\n", rc));
+
+    if (NT_SUCCESS(rc))
+        return VINF_SUCCESS;
+    if (rc == STATUS_INVALID_PARAMETER)
+        return VERR_INVALID_PARAMETER;
+    if (rc == STATUS_INVALID_BUFFER_SIZE)
+        return VERR_OUT_OF_RANGE;
+    return VERR_VBGL_IOCTL_FAILED;
+
+# elif defined (RT_OS_OS2)
+    if (    pDriver->u32Session
+        &&  pDriver->u32Session == g_VBoxGuestIDC.u32Session)
+        return g_VBoxGuestIDC.pfnServiceEP(pDriver->u32Session, u32Function, pvData, cbData, NULL);
+
+    Log(("vbglDriverIOCtl: No connection\n"));
+    return VERR_WRONG_ORDER;
+
+# else
+    return VBoxGuestIDCCall(pDriver->pvOpaque, u32Function, pvData, cbData, NULL);
+# endif
+}
+
+void vbglDriverClose(VBGLDRIVER *pDriver)
+{
+# ifdef RT_OS_WINDOWS
+    Log(("vbglDriverClose pDeviceObject=%x\n", pDriver->pDeviceObject));
+    ObDereferenceObject(pDriver->pFileObject);
+    pDriver->pFileObject = NULL;
+    pDriver->pDeviceObject = NULL;
+
+# elif defined (RT_OS_OS2)
+    pDriver->u32Session = 0;
+
+# else
+    VBoxGuestIDCClose(pDriver->pvOpaque);
+    pDriver->pvOpaque = NULL;
+# endif
+}
+
+#endif /* !VBGL_VBOXGUEST */
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/vboxguest/SysHlp.h
@@ -0,0 +1,122 @@
+/* $Id: SysHlp.h $ */
+/** @file
+ * VBoxGuestLibR0 - System dependent helpers internal header.
+ */
+
+/*
+ * Copyright (C) 2006-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+#ifndef ___VBoxGuestLib_SysHlp_h
+#define ___VBoxGuestLib_SysHlp_h
+
+#include <iprt/types.h>
+
+#ifdef RT_OS_WINDOWS
+# undef PAGE_SIZE
+# undef PAGE_SHIFT
+# if (_MSC_VER >= 1400) && !defined(VBOX_WITH_PATCHED_DDK)
+#  include <iprt/asm.h>
+#  define _InterlockedExchange           _InterlockedExchange_StupidDDKVsCompilerCrap
+#  define _InterlockedExchangeAdd        _InterlockedExchangeAdd_StupidDDKVsCompilerCrap
+#  define _InterlockedCompareExchange    _InterlockedCompareExchange_StupidDDKVsCompilerCrap
+#  define _InterlockedAddLargeStatistic  _InterlockedAddLargeStatistic_StupidDDKVsCompilerCrap
+#  pragma warning(disable : 4163)
+RT_C_DECLS_BEGIN
+#  include <ntddk.h>
+RT_C_DECLS_END
+#  pragma warning(default : 4163)
+#  undef  _InterlockedExchange
+#  undef  _InterlockedExchangeAdd
+#  undef  _InterlockedCompareExchange
+#  undef  _InterlockedAddLargeStatistic
+# else
+RT_C_DECLS_BEGIN
+#  include <ntddk.h>
+RT_C_DECLS_END
+# endif
+/* XP DDK #defines ExFreePool to ExFreePoolWithTag. The latter does not exist on NT4, so...
+ * The same for ExAllocatePool.
+ */
+# undef ExAllocatePool
+# undef ExFreePool
+#endif
+
+typedef struct _VBGLDRIVER
+{
+#ifdef RT_OS_WINDOWS
+    PDEVICE_OBJECT pDeviceObject;
+    PFILE_OBJECT pFileObject;
+#elif defined (RT_OS_OS2)
+    uint32_t u32Session; /**< just for sanity checking. */
+#else /* PORTME */
+    void *pvOpaque;
+#endif
+} VBGLDRIVER;
+
+int  vbglLockLinear(void **ppvCtx, void *pv, uint32_t cb, bool fWriteAccess, uint32_t fFlags);
+void vbglUnlockLinear(void *pvCtx, void *pv, uint32_t cb);
+
+
+#ifndef VBGL_VBOXGUEST
+
+/**
+ * Open VBoxGuest driver.
+ *
+ * @param pDriver      Pointer to the driver structure.
+ *
+ * @return VBox status code
+ */
+int vbglDriverOpen(VBGLDRIVER *pDriver);
+
+/**
+ * Answers whether the VBoxGuest driver is opened
+ *
+ * @param pDriver      Pointer to the driver structure.
+ *
+ * @return true - if opened, false - otherwise
+ */
+bool vbglDriverIsOpened(VBGLDRIVER *pDriver);
+
+/**
+ * Call VBoxGuest driver.
+ *
+ * @param pDriver      Pointer to the driver structure.
+ * @param u32Function  Function code.
+ * @param pvData       Pointer to supplied in/out data buffer.
+ * @param cbData       Size of data buffer.
+ *
+ * @returns VBox status code
+ */
+int vbglDriverIOCtl(VBGLDRIVER *pDriver, uint32_t u32Function, void *pvData, uint32_t cbData);
+
+/**
+ * Close VBoxGuest driver.
+ *
+ * @param pDriver      Pointer to the driver structure.
+ *
+ * @returns VBox status code
+ */
+void vbglDriverClose(VBGLDRIVER *pDriver);
+
+#endif
+
+#endif
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/vboxguest/VBGLInternal.h
@@ -0,0 +1,173 @@
+/* $Id: VBGLInternal.h $ */
+/** @file
+ * VBoxGuestLibR0 - Internal header.
+ */
+
+/*
+ * Copyright (C) 2006-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+#ifndef ___VBoxGuestLib_VBGLInternal_h
+#define ___VBoxGuestLib_VBGLInternal_h
+
+#include <VBox/VMMDev.h>
+#include <VBox/VBoxGuest.h>
+#include <VBox/VBoxGuestLib.h>
+
+#include <VBox/log.h>
+
+
+#ifdef RT_OS_WINDOWS /** @todo dprintf() -> Log() */
+# if (defined(DEBUG) && !defined(NO_LOGGING)) || defined(LOG_ENABLED)
+#  define dprintf(a) RTLogBackdoorPrintf a
+# else
+#  define dprintf(a) do {} while (0)
+# endif
+#else
+# define dprintf(a) Log(a)
+#endif
+
+#include "SysHlp.h"
+
+#pragma pack(4) /** @todo r=bird: What do we need packing for here? None of these structures are shared between drivers AFAIK. */
+
+struct _VBGLPHYSHEAPBLOCK;
+typedef struct _VBGLPHYSHEAPBLOCK VBGLPHYSHEAPBLOCK;
+struct _VBGLPHYSHEAPCHUNK;
+typedef struct _VBGLPHYSHEAPCHUNK VBGLPHYSHEAPCHUNK;
+
+#ifndef VBGL_VBOXGUEST
+struct VBGLHGCMHANDLEDATA
+{
+    uint32_t fAllocated;
+    VBGLDRIVER driver;
+};
+#endif
+
+enum VbglLibStatus
+{
+    VbglStatusNotInitialized = 0,
+    VbglStatusInitializing,
+    VbglStatusReady
+};
+
+/**
+ * Global VBGL ring-0 data.
+ * Lives in VbglR0Init.cpp.
+ */
+typedef struct VBGLDATA
+{
+    enum VbglLibStatus status;
+
+    RTIOPORT portVMMDev;
+
+    VMMDevMemory *pVMMDevMemory;
+
+    /**
+     * Physical memory heap data.
+     * @{
+     */
+
+    VBGLPHYSHEAPBLOCK *pFreeBlocksHead;
+    VBGLPHYSHEAPBLOCK *pAllocBlocksHead;
+    VBGLPHYSHEAPCHUNK *pChunkHead;
+
+    RTSEMFASTMUTEX mutexHeap;
+    /** @} */
+
+    /**
+     * The host version data.
+     */
+    VMMDevReqHostVersion hostVersion;
+
+
+#ifndef VBGL_VBOXGUEST
+    /**
+     * Handle for the main driver instance.
+     * @{
+     */
+
+    RTSEMMUTEX mutexDriverInit;
+
+    VBGLDRIVER driver;
+
+    /** @} */
+
+    /**
+     * Fast heap for HGCM handles data.
+     * @{
+     */
+
+    RTSEMFASTMUTEX mutexHGCMHandle;
+
+    struct VBGLHGCMHANDLEDATA aHGCMHandleData[64];
+
+    /** @} */
+#endif
+} VBGLDATA;
+
+
+#pragma pack()
+
+#ifndef VBGL_DECL_DATA
+extern VBGLDATA g_vbgldata;
+#endif
+
+/**
+ * Internal macro for checking whether we can pass physical page lists to the
+ * host.
+ *
+ * ASSUMES that vbglR0Enter has been called already.
+ *
+ * @param   a_fLocked       For the windows shared folders workarounds.
+ *
+ * @remarks Disabled the PageList feature for locked memory on Windows,
+ *          because a new MDL is created by VBGL to get the page addresses
+ *          and the pages from the MDL are marked as dirty when they should not.
+ */
+#if defined(RT_OS_WINDOWS)
+# define VBGLR0_CAN_USE_PHYS_PAGE_LIST(a_fLocked) \
+    ( !(a_fLocked) && (g_vbgldata.hostVersion.features & VMMDEV_HVF_HGCM_PHYS_PAGE_LIST) )
+#else
+# define VBGLR0_CAN_USE_PHYS_PAGE_LIST(a_fLocked) \
+    ( !!(g_vbgldata.hostVersion.features & VMMDEV_HVF_HGCM_PHYS_PAGE_LIST) )
+#endif
+
+int vbglR0Enter (void);
+
+#ifdef VBOX_WITH_HGCM
+# ifndef VBGL_VBOXGUEST
+int                         vbglR0HGCMInit(void);
+int                         vbglR0HGCMTerminate(void);
+# endif
+struct VBGLHGCMHANDLEDATA  *vbglHGCMHandleAlloc(void);
+void                        vbglHGCMHandleFree(struct VBGLHGCMHANDLEDATA *pHandle);
+#endif /* VBOX_WITH_HGCM */
+
+#ifndef VBGL_VBOXGUEST
+/**
+ * Get a handle to the main VBoxGuest driver.
+ * @returns VERR_TRY_AGAIN if the main driver has not yet been loaded.
+ */
+int vbglGetDriver(VBGLDRIVER **ppDriver);
+#endif
+
+#endif /* !___VBoxGuestLib_VBGLInternal_h */
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/vboxguest/VBox/log-vbox.c
@@ -0,0 +1,506 @@
+/* $Id: log-vbox.cpp $ */
+/** @file
+ * VirtualBox Runtime - Logging configuration.
+ */
+
+/*
+ * Copyright (C) 2006-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+/** @page pg_rtlog      Runtime - Logging
+ *
+ * VBox uses the IPRT logging system which supports group level flags and multiple
+ * destinations. The GC logging is making it even more interesting since GC logging will
+ * have to be buffered and written when back in host context.
+ *
+ * [more later]
+ *
+ *
+ * @section sec_logging_destination     The Destination Specifier.
+ *
+ * The {logger-env-base}_DEST environment variable can be used to specify where
+ * the log output goes. The following specifiers are recognized:
+ *
+ *      - file=\<filename\>
+ *        This sets the logger output filename to \<filename\>. Not formatting
+ *        or anything is supported. Each logger specifies a default name if
+ *        file logging should be enabled by default.
+ *
+ *      - nofile
+ *        This disables the file output.
+ *
+ *      - stdout
+ *        Enables logger output to stdout.
+ *
+ *      - nostdout
+ *        Disables logger output to stdout.
+ *
+ *      - stderr
+ *        Enables logger output to stderr.
+ *
+ *      - nostderr
+ *        Disables logger output to stderr.
+ *
+ *      - debugger
+ *        Enables logger output to native debugger. (Win32/64 only)
+ *
+ *      - nodebugger
+ *        Disables logger output to native debugger. (Win32/64 only)
+ *
+ *      - user
+ *        Enables logger output to special backdoor if in guest r0.
+ *
+ *      - nodebugger
+ *        Disables logger output to special user stream.
+ *
+ *
+ *
+ * @section sec_logging_group           The Group Specifier.
+ *
+ * The {logger-env-base} environment variable can be used to specify which
+ * logger groups to enable and which to disable. By default all groups are
+ * disabled. For your convenience this specifier is case in-sensitive (ASCII).
+ *
+ * The specifier is evaluated from left to right.
+ *
+ * [more later]
+ *
+ * The groups settings can be reprogrammed during execution using the
+ * RTLogGroupSettings() command and a group specifier.
+ *
+ *
+ *
+ * @section sec_logging_default         The Default Logger
+ *
+ * The default logger uses VBOX_LOG_DEST as destination specifier. File output is
+ * enabled by default and goes to a file "./VBox-\<pid\>.log".
+ *
+ * The default logger have all groups turned off by default to force the developer
+ * to be careful with what log information to collect - logging everything is
+ * generally NOT a good idea.
+ *
+ * The log groups of the default logger can be found in the LOGGROUP in enum. The
+ * VBOX_LOG environment variable and the .log debugger command can be used to
+ * configure the groups.
+ *
+ * Each group have flags in addition to the enable/disable flag. These flags can
+ * be appended to the group name using dot separators. The flags correspond to
+ * RTLOGGRPFLAGS and have a short and a long version:
+ *
+ *      - e - Enabled:  Whether the group is enabled at all.
+ *      - l - Level2:   Level-2 logging.
+ *      - f - Flow:     Execution flow logging (entry messages)
+ *      - s - Sander:   Special Sander logging messages.
+ *      - b - Bird:     Special Bird logging messages.
+ *
+ * @todo Update this section...
+ *
+ * Example:
+ *
+ *      VBOX_LOG=+all+pgm.e.s.b.z.l-qemu
+ *
+ * Space and ';' separators are allowed:
+ *
+ *      VBOX_LOG=+all +pgm.e.s.b.z.l ; - qemu
+ *
+ */
+
+
+/*********************************************************************************************************************************
+*   Header Files                                                                                                                 *
+*********************************************************************************************************************************/
+#ifdef IN_RING3
+# if defined(RT_OS_WINDOWS)
+#  include <Windows.h>
+# elif defined(RT_OS_LINUX)
+#  include <unistd.h>
+# elif defined(RT_OS_FREEBSD)
+#  include <sys/param.h>
+#  include <sys/sysctl.h>
+#  include <sys/user.h>
+#  include <stdlib.h>
+#  include <unistd.h>
+# elif defined(RT_OS_HAIKU)
+#  include <OS.h>
+# elif defined(RT_OS_SOLARIS)
+#  define _STRUCTURED_PROC 1
+#  undef _FILE_OFFSET_BITS /* procfs doesn't like this */
+#  include <sys/procfs.h>
+#  include <unistd.h>
+# elif defined(RT_OS_OS2)
+#  include <stdlib.h>
+# endif
+#endif
+
+#include <VBox/log.h>
+#include <iprt/asm.h>
+#include <iprt/err.h>
+#include <iprt/time.h>
+#ifdef IN_RING3
+# include <iprt/param.h>
+# include <iprt/assert.h>
+# include <iprt/path.h>
+# include <iprt/process.h>
+# include <iprt/string.h>
+# include <iprt/mem.h>
+# include <stdio.h>
+#endif
+#if defined(IN_RING0) && defined(RT_OS_DARWIN)
+# include <iprt/asm-amd64-x86.h>
+# include <iprt/thread.h>
+#endif
+
+
+/*********************************************************************************************************************************
+*   Global Variables                                                                                                             *
+*********************************************************************************************************************************/
+/** The default logger. */
+static PRTLOGGER                    g_pLogger = NULL;
+/** The default logger groups.
+ * This must match LOGGROUP! */
+static const char                  *g_apszGroups[] =
+VBOX_LOGGROUP_NAMES;
+
+
+/**
+ * Creates the default logger instance for a VBox process.
+ *
+ * @returns Pointer to the logger instance.
+ */
+RTDECL(PRTLOGGER) RTLogDefaultInit(void)
+{
+    /*
+     * Initialize the default logger instance.
+     * Take care to do this once and not recursively.
+     */
+    static volatile uint32_t fInitializing = 0;
+    PRTLOGGER pLogger;
+    int rc;
+
+    if (g_pLogger || !ASMAtomicCmpXchgU32(&fInitializing, 1, 0))
+        return g_pLogger;
+
+#ifdef IN_RING3
+    /*
+     * Assert the group definitions.
+     */
+#define ASSERT_LOG_GROUP(grp)  ASSERT_LOG_GROUP2(LOG_GROUP_##grp, #grp)
+#define ASSERT_LOG_GROUP2(def, str) \
+    do { if (strcmp(g_apszGroups[def], str)) {printf("%s='%s' expects '%s'\n", #def, g_apszGroups[def], str); RTAssertDoPanic(); } } while (0)
+    ASSERT_LOG_GROUP(DEFAULT);
+    ASSERT_LOG_GROUP(AUDIO_MIXER);
+    ASSERT_LOG_GROUP(AUDIO_MIXER_BUFFER);
+    ASSERT_LOG_GROUP(CFGM);
+    ASSERT_LOG_GROUP(CPUM);
+    ASSERT_LOG_GROUP(CSAM);
+    ASSERT_LOG_GROUP(DBGC);
+    ASSERT_LOG_GROUP(DBGF);
+    ASSERT_LOG_GROUP(DBGF_INFO);
+    ASSERT_LOG_GROUP(DEV);
+    ASSERT_LOG_GROUP(DEV_AC97);
+    ASSERT_LOG_GROUP(DEV_ACPI);
+    ASSERT_LOG_GROUP(DEV_APIC);
+    ASSERT_LOG_GROUP(DEV_FDC);
+    ASSERT_LOG_GROUP(DEV_HDA);
+    ASSERT_LOG_GROUP(DEV_HDA_CODEC);
+    ASSERT_LOG_GROUP(DEV_HPET);
+    ASSERT_LOG_GROUP(DEV_IDE);
+    ASSERT_LOG_GROUP(DEV_KBD);
+    ASSERT_LOG_GROUP(DEV_LPC);
+    ASSERT_LOG_GROUP(DEV_NE2000);
+    ASSERT_LOG_GROUP(DEV_PC);
+    ASSERT_LOG_GROUP(DEV_PC_ARCH);
+    ASSERT_LOG_GROUP(DEV_PC_BIOS);
+    ASSERT_LOG_GROUP(DEV_PCI);
+    ASSERT_LOG_GROUP(DEV_PCNET);
+    ASSERT_LOG_GROUP(DEV_PIC);
+    ASSERT_LOG_GROUP(DEV_PIT);
+    ASSERT_LOG_GROUP(DEV_RTC);
+    ASSERT_LOG_GROUP(DEV_SB16);
+    ASSERT_LOG_GROUP(DEV_SERIAL);
+    ASSERT_LOG_GROUP(DEV_SMC);
+    ASSERT_LOG_GROUP(DEV_VGA);
+    ASSERT_LOG_GROUP(DEV_VMM);
+    ASSERT_LOG_GROUP(DEV_VMM_STDERR);
+    ASSERT_LOG_GROUP(DIS);
+    ASSERT_LOG_GROUP(DRV);
+    ASSERT_LOG_GROUP(DRV_ACPI);
+    ASSERT_LOG_GROUP(DRV_AUDIO);
+    ASSERT_LOG_GROUP(DRV_BLOCK);
+    ASSERT_LOG_GROUP(DRV_FLOPPY);
+    ASSERT_LOG_GROUP(DRV_HOST_AUDIO);
+    ASSERT_LOG_GROUP(DRV_HOST_DVD);
+    ASSERT_LOG_GROUP(DRV_HOST_FLOPPY);
+    ASSERT_LOG_GROUP(DRV_ISO);
+    ASSERT_LOG_GROUP(DRV_KBD_QUEUE);
+    ASSERT_LOG_GROUP(DRV_MOUSE_QUEUE);
+    ASSERT_LOG_GROUP(DRV_NAT);
+    ASSERT_LOG_GROUP(DRV_RAW_IMAGE);
+    ASSERT_LOG_GROUP(DRV_TUN);
+    ASSERT_LOG_GROUP(DRV_USBPROXY);
+    ASSERT_LOG_GROUP(DRV_VBOXHDD);
+    ASSERT_LOG_GROUP(DRV_VRDE_AUDIO);
+    ASSERT_LOG_GROUP(DRV_VSWITCH);
+    ASSERT_LOG_GROUP(DRV_VUSB);
+    ASSERT_LOG_GROUP(EM);
+    ASSERT_LOG_GROUP(GUI);
+    ASSERT_LOG_GROUP(HGCM);
+    ASSERT_LOG_GROUP(HM);
+    ASSERT_LOG_GROUP(IOM);
+    ASSERT_LOG_GROUP(LWIP);
+    ASSERT_LOG_GROUP(MAIN);
+    ASSERT_LOG_GROUP(MM);
+    ASSERT_LOG_GROUP(MM_HEAP);
+    ASSERT_LOG_GROUP(MM_HYPER);
+    ASSERT_LOG_GROUP(MM_HYPER_HEAP);
+    ASSERT_LOG_GROUP(MM_PHYS);
+    ASSERT_LOG_GROUP(MM_POOL);
+    ASSERT_LOG_GROUP(NAT_SERVICE);
+    ASSERT_LOG_GROUP(NET_SERVICE);
+    ASSERT_LOG_GROUP(PATM);
+    ASSERT_LOG_GROUP(PDM);
+    ASSERT_LOG_GROUP(PDM_DEVICE);
+    ASSERT_LOG_GROUP(PDM_DRIVER);
+    ASSERT_LOG_GROUP(PDM_LDR);
+    ASSERT_LOG_GROUP(PDM_QUEUE);
+    ASSERT_LOG_GROUP(PGM);
+    ASSERT_LOG_GROUP(PGM_POOL);
+    ASSERT_LOG_GROUP(REM);
+    ASSERT_LOG_GROUP(REM_DISAS);
+    ASSERT_LOG_GROUP(REM_HANDLER);
+    ASSERT_LOG_GROUP(REM_IOPORT);
+    ASSERT_LOG_GROUP(REM_MMIO);
+    ASSERT_LOG_GROUP(REM_PRINTF);
+    ASSERT_LOG_GROUP(REM_RUN);
+    ASSERT_LOG_GROUP(SELM);
+    ASSERT_LOG_GROUP(SSM);
+    ASSERT_LOG_GROUP(STAM);
+    ASSERT_LOG_GROUP(SUP);
+    ASSERT_LOG_GROUP(TM);
+    ASSERT_LOG_GROUP(TRPM);
+    ASSERT_LOG_GROUP(VM);
+    ASSERT_LOG_GROUP(VMM);
+    ASSERT_LOG_GROUP(VRDP);
+#undef ASSERT_LOG_GROUP
+#undef ASSERT_LOG_GROUP2
+#endif /* IN_RING3 */
+
+    /*
+     * Create the default logging instance.
+     */
+#ifdef IN_RING3
+# ifndef IN_GUEST
+    char szExecName[RTPATH_MAX];
+    if (!RTProcGetExecutablePath(szExecName, sizeof(szExecName)))
+        strcpy(szExecName, "VBox");
+    RTTIMESPEC TimeSpec;
+    RTTIME Time;
+    RTTimeExplode(&Time, RTTimeNow(&TimeSpec));
+    rc = RTLogCreate(&pLogger, 0, NULL, "VBOX_LOG", RT_ELEMENTS(g_apszGroups), &g_apszGroups[0], RTLOGDEST_FILE,
+                     "./%04d-%02d-%02d-%02d-%02d-%02d.%03d-%s-%d.log",
+                     Time.i32Year, Time.u8Month, Time.u8MonthDay, Time.u8Hour, Time.u8Minute, Time.u8Second, Time.u32Nanosecond / 10000000,
+                     RTPathFilename(szExecName), RTProcSelf());
+    if (RT_SUCCESS(rc))
+    {
+        /*
+         * Write a log header.
+         */
+        char szBuf[RTPATH_MAX];
+        RTTimeSpecToString(&TimeSpec, szBuf, sizeof(szBuf));
+        RTLogLoggerEx(pLogger, 0, ~0U, "Log created: %s\n", szBuf);
+        RTLogLoggerEx(pLogger, 0, ~0U, "Executable: %s\n", szExecName);
+
+        /* executable and arguments - tricky and all platform specific. */
+#  if defined(RT_OS_WINDOWS)
+        RTLogLoggerEx(pLogger, 0, ~0U, "Commandline: %ls\n", GetCommandLineW());
+
+#  elif defined(RT_OS_SOLARIS)
+        psinfo_t psi;
+        char szArgFileBuf[80];
+        RTStrPrintf(szArgFileBuf, sizeof(szArgFileBuf), "/proc/%ld/psinfo", (long)getpid());
+        FILE* pFile = fopen(szArgFileBuf, "rb");
+        if (pFile)
+        {
+            if (fread(&psi, sizeof(psi), 1, pFile) == 1)
+            {
+#   if 0     /* 100% safe:*/
+                RTLogLoggerEx(pLogger, 0, ~0U, "Args: %s\n", psi.pr_psargs);
+#   else     /* probably safe: */
+                const char * const *argv = (const char * const *)psi.pr_argv;
+                for (int iArg = 0; iArg < psi.pr_argc; iArg++)
+                    RTLogLoggerEx(pLogger, 0, ~0U, "Arg[%d]: %s\n", iArg, argv[iArg]);
+#   endif
+
+            }
+            fclose(pFile);
+        }
+
+#  elif defined(RT_OS_LINUX)
+        FILE *pFile = fopen("/proc/self/cmdline", "r");
+        if (pFile)
+        {
+            /* braindead */
+            unsigned iArg = 0;
+            int ch;
+            bool fNew = true;
+            while (!feof(pFile) && (ch = fgetc(pFile)) != EOF)
+            {
+                if (fNew)
+                {
+                    RTLogLoggerEx(pLogger, 0, ~0U, "Arg[%u]: ", iArg++);
+                    fNew = false;
+                }
+                if (ch)
+                    RTLogLoggerEx(pLogger, 0, ~0U, "%c", ch);
+                else
+                {
+                    RTLogLoggerEx(pLogger, 0, ~0U, "\n");
+                    fNew = true;
+                }
+            }
+            if (!fNew)
+                RTLogLoggerEx(pLogger, 0, ~0U, "\n");
+            fclose(pFile);
+        }
+
+#  elif defined(RT_OS_HAIKU)
+        team_info info;
+        if (get_team_info(0, &info) == B_OK)
+        {
+            /* there is an info.argc, but no way to know arg boundaries */
+            RTLogLoggerEx(pLogger, 0, ~0U, "Commandline: %.64s\n", info.args);
+        }
+
+#  elif defined(RT_OS_FREEBSD)
+        /* Retrieve the required length first */
+        int aiName[4];
+        aiName[0] = CTL_KERN;
+        aiName[1] = KERN_PROC;
+        aiName[2] = KERN_PROC_ARGS;     /* Introduced in FreeBSD 4.0 */
+        aiName[3] = getpid();
+        size_t cchArgs = 0;
+        int rcBSD = sysctl(aiName, RT_ELEMENTS(aiName), NULL, &cchArgs, NULL, 0);
+        if (cchArgs > 0)
+        {
+            char *pszArgFileBuf = (char *)RTMemAllocZ(cchArgs + 1 /* Safety */);
+            if (pszArgFileBuf)
+            {
+                /* Retrieve the argument list */
+                rcBSD = sysctl(aiName, RT_ELEMENTS(aiName), pszArgFileBuf, &cchArgs, NULL, 0);
+                if (!rcBSD)
+                {
+                    unsigned    iArg = 0;
+                    size_t      off = 0;
+                    while (off < cchArgs)
+                    {
+                        size_t cchArg = strlen(&pszArgFileBuf[off]);
+                        RTLogLoggerEx(pLogger, 0, ~0U, "Arg[%u]: %s\n", iArg, &pszArgFileBuf[off]);
+
+                        /* advance */
+                        off += cchArg + 1;
+                        iArg++;
+                    }
+                }
+                RTMemFree(pszArgFileBuf);
+            }
+        }
+
+#  elif defined(RT_OS_OS2) || defined(RT_OS_DARWIN)
+        /* commandline? */
+#  else
+#   error needs porting.
+#  endif
+    }
+
+# else  /* IN_GUEST */
+    /* The user destination is backdoor logging. */
+    rc = RTLogCreate(&pLogger, 0, NULL, "VBOX_LOG", RT_ELEMENTS(g_apszGroups), &g_apszGroups[0], RTLOGDEST_USER, "VBox.log");
+# endif /* IN_GUEST */
+
+#else /* IN_RING0 */
+
+    /* Some platforms has trouble allocating memory with interrupts and/or
+       preemption disabled. Check and fail before we panic. */
+# if defined(RT_OS_DARWIN)
+    if (   !ASMIntAreEnabled()
+        || !RTThreadPreemptIsEnabled(NIL_RTTHREAD))
+        return NULL;
+# endif
+
+# ifndef IN_GUEST
+    rc = RTLogCreate(&pLogger, 0, NULL, "VBOX_LOG", RT_ELEMENTS(g_apszGroups), &g_apszGroups[0], RTLOGDEST_FILE, "VBox-ring0.log");
+# else  /* IN_GUEST */
+    rc = RTLogCreate(&pLogger, 0, NULL, "VBOX_LOG", RT_ELEMENTS(g_apszGroups), &g_apszGroups[0], RTLOGDEST_USER, "VBox-ring0.log");
+# endif /* IN_GUEST */
+    if (RT_SUCCESS(rc))
+    {
+        /*
+         * This is where you set your ring-0 logging preferences.
+         *
+         * On platforms which don't differ between debugger and kernel
+         * log printing, STDOUT is gonna be a stub and the DEBUGGER
+         * destination is the one doing all the work. On platforms
+         * that do differ (like Darwin), STDOUT is the kernel log.
+         */
+# if defined(DEBUG_bird)
+        /*RTLogGroupSettings(pLogger, "all=~0 -default.l6.l5.l4.l3");*/
+        RTLogFlags(pLogger, "enabled unbuffered pid tid");
+#  ifndef IN_GUEST
+        pLogger->fDestFlags |= RTLOGDEST_DEBUGGER | RTLOGDEST_STDOUT;
+#  endif
+# endif
+# if defined(DEBUG_sandervl) && !defined(IN_GUEST)
+        RTLogGroupSettings(pLogger, "+all");
+        RTLogFlags(pLogger, "enabled unbuffered");
+        pLogger->fDestFlags |= RTLOGDEST_DEBUGGER;
+# endif
+# if defined(DEBUG_ramshankar)  /* Guest ring-0 as well */
+        RTLogGroupSettings(pLogger, "+all.e.l.f");
+        RTLogFlags(pLogger, "enabled unbuffered");
+        pLogger->fDestFlags |= RTLOGDEST_DEBUGGER;
+# endif
+# if defined(DEBUG_aleksey)  /* Guest ring-0 as well */
+        RTLogGroupSettings(pLogger, "net_flt_drv.e.l.f.l3.l4.l5 +net_adp_drv.e.l.f.l3.l4.l5");
+        RTLogFlags(pLogger, "enabled unbuffered");
+        pLogger->fDestFlags |= RTLOGDEST_DEBUGGER | RTLOGDEST_STDOUT;
+# endif
+# if defined(DEBUG_andy)  /* Guest ring-0 as well */
+        RTLogGroupSettings(pLogger, "+all.e.l.f");
+        RTLogFlags(pLogger, "enabled unbuffered pid tid");
+        pLogger->fDestFlags |= RTLOGDEST_DEBUGGER | RTLOGDEST_STDOUT;
+# endif
+# if defined(DEBUG_misha) /* Guest ring-0 as well */
+        RTLogFlags(pLogger, "enabled unbuffered");
+        pLogger->fDestFlags |= RTLOGDEST_DEBUGGER;
+# endif
+# if defined(DEBUG_michael) && defined(IN_GUEST)
+        RTLogGroupSettings(pLogger, "+all.e.l.f");
+        RTLogFlags(pLogger, "enabled unbuffered");
+        pLogger->fDestFlags |= RTLOGDEST_DEBUGGER | RTLOGDEST_STDOUT;
+# endif
+# if 0 /* vboxdrv logging - ATTENTION: this is what we're referring to guys! Change to '# if 1'. */
+        RTLogGroupSettings(pLogger, "all=~0 -default.l6.l5.l4.l3");
+        RTLogFlags(pLogger, "enabled unbuffered tid");
+        pLogger->fDestFlags |= RTLOGDEST_DEBUGGER | RTLOGDEST_STDOUT;
+# endif
+    }
+#endif /* IN_RING0 */
+    return g_pLogger = RT_SUCCESS(rc) ? pLogger : NULL;
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/vboxguest/VBox/logbackdoor.c
@@ -0,0 +1,94 @@
+/* $Id: logbackdoor.cpp $ */
+/** @file
+ * VirtualBox Runtime - Guest Backdoor Logging.
+ */
+
+/*
+ * Copyright (C) 2006-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+
+/*********************************************************************************************************************************
+*   Header Files                                                                                                                 *
+*********************************************************************************************************************************/
+#include <VBox/log.h>
+#include "internal/iprt.h"
+#include <iprt/asm-amd64-x86.h>
+#include <iprt/string.h>
+#ifdef IN_GUEST_R3
+# include <VBox/VBoxGuestLib.h>
+#endif
+
+
+/*********************************************************************************************************************************
+*   Internal Functions                                                                                                           *
+*********************************************************************************************************************************/
+static DECLCALLBACK(size_t) rtLogBackdoorOutput(void *pv, const char *pachChars, size_t cbChars);
+
+
+RTDECL(size_t) RTLogBackdoorPrintf(const char *pszFormat, ...)
+{
+    va_list args;
+    size_t cb;
+
+    va_start(args, pszFormat);
+    cb = RTLogBackdoorPrintfV(pszFormat, args);
+    va_end(args);
+
+    return cb;
+}
+
+RT_EXPORT_SYMBOL(RTLogBackdoorPrintf);
+
+
+RTDECL(size_t) RTLogBackdoorPrintfV(const char *pszFormat, va_list args)
+{
+    return RTLogFormatV(rtLogBackdoorOutput, NULL, pszFormat, args);
+}
+
+RT_EXPORT_SYMBOL(RTLogBackdoorPrintfV);
+
+
+/**
+ * Callback for RTLogFormatV which writes to the backdoor.
+ * See PFNLOGOUTPUT() for details.
+ */
+static DECLCALLBACK(size_t) rtLogBackdoorOutput(void *pv, const char *pachChars, size_t cbChars)
+{
+    RTLogWriteUser(pachChars, cbChars);
+    return cbChars;
+}
+
+
+RTDECL(void) RTLogWriteUser(const char *pch, size_t cb)
+{
+#ifdef IN_GUEST_R3
+    VbglR3WriteLog(pch, cb);
+#else  /* !IN_GUEST_R3 */
+    const uint8_t *pau8 = (const uint8_t *)pch;
+    if (cb > 1)
+        ASMOutStrU8(RTLOG_DEBUG_PORT, pau8, cb);
+    else if (cb)
+        ASMOutU8(RTLOG_DEBUG_PORT, *pau8);
+#endif /* !IN_GUEST_R3 */
+}
+
+RT_EXPORT_SYMBOL(RTLogWriteUser);
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/vboxguest/VBoxGuest-linux.c
@@ -0,0 +1,1086 @@
+/* $Rev: 103598 $ */
+/** @file
+ * VBoxGuest - Linux specifics.
+ *
+ * Note. Unfortunately, the difference between this and SUPDrv-linux.c is
+ *       a little bit too big to be helpful.
+ */
+
+/*
+ * Copyright (C) 2006-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+  */
+
+
+/*********************************************************************************************************************************
+*   Header Files                                                                                                                 *
+*********************************************************************************************************************************/
+#define LOG_GROUP LOG_GROUP_SUP_DRV
+
+#include "the-linux-kernel.h"
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 15)
+# define VBOXGUEST_WITH_INPUT_DRIVER
+#endif
+
+#include "VBoxGuestInternal.h"
+#ifdef VBOXGUEST_WITH_INPUT_DRIVER
+# include <linux/input.h>
+#endif
+#include <linux/miscdevice.h>
+#include <linux/poll.h>
+#include <VBox/version.h>
+
+#include <iprt/assert.h>
+#include <iprt/asm.h>
+#include <iprt/err.h>
+#include <iprt/initterm.h>
+#include <iprt/mem.h>
+#include <iprt/mp.h>
+#include <iprt/process.h>
+#include <iprt/spinlock.h>
+#include <iprt/semaphore.h>
+#include <VBox/log.h>
+
+
+/*********************************************************************************************************************************
+*   Defined Constants And Macros                                                                                                 *
+*********************************************************************************************************************************/
+/** The device name. */
+#define DEVICE_NAME             "vboxguest"
+/** The device name for the device node open to everyone. */
+#define DEVICE_NAME_USER        "vboxuser"
+/** The name of the PCI driver */
+#define DRIVER_NAME             DEVICE_NAME
+
+
+/* 2.4.x compatibility macros that may or may not be defined. */
+#ifndef IRQ_RETVAL
+# define irqreturn_t            void
+# define IRQ_RETVAL(n)
+#endif
+
+
+/*********************************************************************************************************************************
+*   Internal Functions                                                                                                           *
+*********************************************************************************************************************************/
+static void vgdrvLinuxTermPci(struct pci_dev *pPciDev);
+static int  vgdrvLinuxProbePci(struct pci_dev *pPciDev, const struct pci_device_id *id);
+static int  vgdrvLinuxModInit(void);
+static void vgdrvLinuxModExit(void);
+static int  vgdrvLinuxOpen(struct inode *pInode, struct file *pFilp);
+static int  vgdrvLinuxRelease(struct inode *pInode, struct file *pFilp);
+#ifdef HAVE_UNLOCKED_IOCTL
+static long vgdrvLinuxIOCtl(struct file *pFilp, unsigned int uCmd, unsigned long ulArg);
+#else
+static int  vgdrvLinuxIOCtl(struct inode *pInode, struct file *pFilp, unsigned int uCmd, unsigned long ulArg);
+#endif
+static int  vgdrvLinuxFAsync(int fd, struct file *pFile, int fOn);
+static unsigned int vgdrvLinuxPoll(struct file *pFile, poll_table *pPt);
+static ssize_t vgdrvLinuxRead(struct file *pFile, char *pbBuf, size_t cbRead, loff_t *poff);
+
+
+/*********************************************************************************************************************************
+*   Global Variables                                                                                                             *
+*********************************************************************************************************************************/
+/**
+ * Device extention & session data association structure.
+ */
+static VBOXGUESTDEVEXT          g_DevExt;
+/** The PCI device. */
+static struct pci_dev          *g_pPciDev = NULL;
+/** The base of the I/O port range. */
+static RTIOPORT                 g_IOPortBase;
+/** The base of the MMIO range. */
+static RTHCPHYS                 g_MMIOPhysAddr = NIL_RTHCPHYS;
+/** The size of the MMIO range as seen by PCI. */
+static uint32_t                 g_cbMMIO;
+/** The pointer to the mapping of the MMIO range. */
+static void                    *g_pvMMIOBase;
+/** Wait queue used by polling. */
+static wait_queue_head_t        g_PollEventQueue;
+/** Asynchronous notification stuff.  */
+static struct fasync_struct    *g_pFAsyncQueue;
+#ifdef VBOXGUEST_WITH_INPUT_DRIVER
+/** Pre-allocated mouse status VMMDev request for use in the IRQ
+ * handler. */
+static VMMDevReqMouseStatus    *g_pMouseStatusReq;
+#endif
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)
+/** Whether we've create the logger or not. */
+static volatile bool            g_fLoggerCreated;
+/** Release logger group settings. */
+static char                     g_szLogGrp[128];
+/** Release logger flags settings. */
+static char                     g_szLogFlags[128];
+/** Release logger destination settings. */
+static char                     g_szLogDst[128];
+# if 0
+/** Debug logger group settings. */
+static char                     g_szDbgLogGrp[128];
+/** Debug logger flags settings. */
+static char                     g_szDbgLogFlags[128];
+/** Debug logger destination settings. */
+static char                     g_szDbgLogDst[128];
+# endif
+#endif
+
+/** The input device handle */
+#ifdef VBOXGUEST_WITH_INPUT_DRIVER
+static struct input_dev        *g_pInputDevice = NULL;
+#endif
+
+/** The file_operations structure. */
+static struct file_operations   g_FileOps =
+{
+    owner:          THIS_MODULE,
+    open:           vgdrvLinuxOpen,
+    release:        vgdrvLinuxRelease,
+#ifdef HAVE_UNLOCKED_IOCTL
+    unlocked_ioctl: vgdrvLinuxIOCtl,
+#else
+    ioctl:          vgdrvLinuxIOCtl,
+#endif
+    fasync:         vgdrvLinuxFAsync,
+    read:           vgdrvLinuxRead,
+    poll:           vgdrvLinuxPoll,
+    llseek:         no_llseek,
+};
+
+/** The miscdevice structure. */
+static struct miscdevice        g_MiscDevice =
+{
+    minor:          MISC_DYNAMIC_MINOR,
+    name:           DEVICE_NAME,
+    fops:           &g_FileOps,
+};
+
+/** The file_operations structure for the user device.
+ * @remarks For the time being we'll be using the same implementation as
+ *          /dev/vboxguest here. */
+static struct file_operations   g_FileOpsUser =
+{
+    owner:          THIS_MODULE,
+    open:           vgdrvLinuxOpen,
+    release:        vgdrvLinuxRelease,
+#ifdef HAVE_UNLOCKED_IOCTL
+    unlocked_ioctl: vgdrvLinuxIOCtl,
+#else
+    ioctl:          vgdrvLinuxIOCtl,
+#endif
+};
+
+/** The miscdevice structure for the user device. */
+static struct miscdevice        g_MiscDeviceUser =
+{
+    minor:          MISC_DYNAMIC_MINOR,
+    name:           DEVICE_NAME_USER,
+    fops:           &g_FileOpsUser,
+};
+
+
+/** PCI hotplug structure. */
+static const struct pci_device_id
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0)
+__devinitdata
+#endif
+g_VBoxGuestPciId[] =
+{
+    {
+        vendor:     VMMDEV_VENDORID,
+        device:     VMMDEV_DEVICEID
+    },
+    {
+        /* empty entry */
+    }
+};
+
+MODULE_DEVICE_TABLE(pci, g_VBoxGuestPciId);
+
+/** Structure for registering the PCI driver. */
+static struct pci_driver  g_PciDriver =
+{
+    name:           DRIVER_NAME,
+    id_table:       g_VBoxGuestPciId,
+    probe:          vgdrvLinuxProbePci,
+    remove:         vgdrvLinuxTermPci
+};
+
+static PVBOXGUESTSESSION        g_pKernelSession = NULL;
+
+
+
+/**
+ * Converts a VBox status code to a linux error code.
+ *
+ * @returns corresponding negative linux error code.
+ * @param   rc  supdrv error code (SUPDRV_ERR_* defines).
+ */
+static int vgdrvLinuxConvertToNegErrno(int rc)
+{
+    if (   rc > -1000
+        && rc < 1000)
+        return -RTErrConvertToErrno(rc);
+    switch (rc)
+    {
+        case VERR_HGCM_SERVICE_NOT_FOUND:      return -ESRCH;
+        case VINF_HGCM_CLIENT_REJECTED:        return 0;
+        case VERR_HGCM_INVALID_CMD_ADDRESS:    return -EFAULT;
+        case VINF_HGCM_ASYNC_EXECUTE:          return 0;
+        case VERR_HGCM_INTERNAL:               return -EPROTO;
+        case VERR_HGCM_INVALID_CLIENT_ID:      return -EINVAL;
+        case VINF_HGCM_SAVE_STATE:             return 0;
+        /* No reason to return this to a guest */
+        // case VERR_HGCM_SERVICE_EXISTS:         return -EEXIST;
+        default:
+            AssertMsgFailed(("Unhandled error code %Rrc\n", rc));
+            return -EPROTO;
+    }
+}
+
+
+/**
+ * Does the PCI detection and init of the device.
+ *
+ * @returns 0 on success, negated errno on failure.
+ */
+static int vgdrvLinuxProbePci(struct pci_dev *pPciDev, const struct pci_device_id *id)
+{
+    int rc;
+
+    NOREF(id);
+    AssertReturn(!g_pPciDev, -EINVAL);
+    rc = pci_enable_device(pPciDev);
+    if (rc >= 0)
+    {
+        /* I/O Ports are mandatory, the MMIO bit is not. */
+        g_IOPortBase = pci_resource_start(pPciDev, 0);
+        if (g_IOPortBase != 0)
+        {
+            /*
+             * Map the register address space.
+             */
+            g_MMIOPhysAddr = pci_resource_start(pPciDev, 1);
+            g_cbMMIO       = pci_resource_len(pPciDev, 1);
+            if (request_mem_region(g_MMIOPhysAddr, g_cbMMIO, DEVICE_NAME) != NULL)
+            {
+                g_pvMMIOBase = ioremap(g_MMIOPhysAddr, g_cbMMIO);
+                if (g_pvMMIOBase)
+                {
+                    /** @todo why aren't we requesting ownership of the I/O ports as well? */
+                    g_pPciDev = pPciDev;
+                    return 0;
+                }
+
+                /* failure cleanup path */
+                LogRel((DEVICE_NAME ": ioremap failed; MMIO Addr=%RHp cb=%#x\n", g_MMIOPhysAddr, g_cbMMIO));
+                rc = -ENOMEM;
+                release_mem_region(g_MMIOPhysAddr, g_cbMMIO);
+            }
+            else
+            {
+                LogRel((DEVICE_NAME ": failed to obtain adapter memory\n"));
+                rc = -EBUSY;
+            }
+            g_MMIOPhysAddr = NIL_RTHCPHYS;
+            g_cbMMIO       = 0;
+            g_IOPortBase   = 0;
+        }
+        else
+        {
+            LogRel((DEVICE_NAME ": did not find expected hardware resources\n"));
+            rc = -ENXIO;
+        }
+        pci_disable_device(pPciDev);
+    }
+    else
+        LogRel((DEVICE_NAME ": could not enable device: %d\n", rc));
+    return rc;
+}
+
+
+/**
+ * Clean up the usage of the PCI device.
+ */
+static void vgdrvLinuxTermPci(struct pci_dev *pPciDev)
+{
+    g_pPciDev = NULL;
+    if (pPciDev)
+    {
+        iounmap(g_pvMMIOBase);
+        g_pvMMIOBase = NULL;
+
+        release_mem_region(g_MMIOPhysAddr, g_cbMMIO);
+        g_MMIOPhysAddr = NIL_RTHCPHYS;
+        g_cbMMIO = 0;
+
+        pci_disable_device(pPciDev);
+    }
+}
+
+
+/**
+ * Interrupt service routine.
+ *
+ * @returns In 2.4 it returns void.
+ *          In 2.6 we indicate whether we've handled the IRQ or not.
+ *
+ * @param   iIrq            The IRQ number.
+ * @param   pvDevId         The device ID, a pointer to g_DevExt.
+ * @param   pRegs           Register set. Removed in 2.6.19.
+ */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19) && !defined(DOXYGEN_RUNNING)
+static irqreturn_t vgdrvLinuxISR(int iIrq, void *pvDevId)
+#else
+static irqreturn_t vgdrvLinuxISR(int iIrq, void *pvDevId, struct pt_regs *pRegs)
+#endif
+{
+    bool fTaken = VGDrvCommonISR(&g_DevExt);
+    return IRQ_RETVAL(fTaken);
+}
+
+
+/**
+ * Registers the ISR and initializes the poll wait queue.
+ */
+static int __init vgdrvLinuxInitISR(void)
+{
+    int rc;
+
+    init_waitqueue_head(&g_PollEventQueue);
+    rc = request_irq(g_pPciDev->irq,
+                     vgdrvLinuxISR,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 20)
+                     IRQF_SHARED,
+#else
+                     SA_SHIRQ,
+#endif
+                     DEVICE_NAME,
+                     &g_DevExt);
+    if (rc)
+    {
+        LogRel((DEVICE_NAME ": could not request IRQ %d: err=%d\n", g_pPciDev->irq, rc));
+        return rc;
+    }
+    return 0;
+}
+
+
+/**
+ * Deregisters the ISR.
+ */
+static void vgdrvLinuxTermISR(void)
+{
+    free_irq(g_pPciDev->irq, &g_DevExt);
+}
+
+
+#ifdef VBOXGUEST_WITH_INPUT_DRIVER
+
+/**
+ * Reports the mouse integration status to the host.
+ *
+ * Calls the kernel IOCtl to report mouse status to the host on behalf of
+ * our kernel session.
+ *
+ * @param   fStatus     The mouse status to report.
+ */
+static int vgdrvLinuxSetMouseStatus(uint32_t fStatus)
+{
+    return VGDrvCommonIoCtl(VBOXGUEST_IOCTL_SET_MOUSE_STATUS, &g_DevExt, g_pKernelSession, &fStatus, sizeof(fStatus), NULL);
+}
+
+
+/**
+ * Called when the input device is first opened.
+ *
+ * Sets up absolute mouse reporting.
+ */
+static int vboxguestOpenInputDevice(struct input_dev *pDev)
+{
+    int rc = vgdrvLinuxSetMouseStatus(VMMDEV_MOUSE_GUEST_CAN_ABSOLUTE | VMMDEV_MOUSE_NEW_PROTOCOL);
+    if (RT_FAILURE(rc))
+        return ENODEV;
+    NOREF(pDev);
+    return 0;
+}
+
+
+/**
+ * Called if all open handles to the input device are closed.
+ *
+ * Disables absolute reporting.
+ */
+static void vboxguestCloseInputDevice(struct input_dev *pDev)
+{
+    NOREF(pDev);
+    vgdrvLinuxSetMouseStatus(0);
+}
+
+
+/**
+ * Creates the kernel input device.
+ */
+static int __init vgdrvLinuxCreateInputDevice(void)
+{
+    int rc = VbglGRAlloc((VMMDevRequestHeader **)&g_pMouseStatusReq, sizeof(*g_pMouseStatusReq), VMMDevReq_GetMouseStatus);
+    if (RT_SUCCESS(rc))
+    {
+        g_pInputDevice = input_allocate_device();
+        if (g_pInputDevice)
+        {
+            g_pInputDevice->id.bustype = BUS_PCI;
+            g_pInputDevice->id.vendor  = VMMDEV_VENDORID;
+            g_pInputDevice->id.product = VMMDEV_DEVICEID;
+            g_pInputDevice->id.version = VBOX_SHORT_VERSION;
+            g_pInputDevice->open       = vboxguestOpenInputDevice;
+            g_pInputDevice->close      = vboxguestCloseInputDevice;
+# if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 22)
+            g_pInputDevice->cdev.dev   = &g_pPciDev->dev;
+# else
+            g_pInputDevice->dev.parent = &g_pPciDev->dev;
+# endif
+            rc = input_register_device(g_pInputDevice);
+            if (rc == 0)
+            {
+                /* Do what one of our competitors apparently does as that works. */
+                ASMBitSet(g_pInputDevice->evbit, EV_ABS);
+                ASMBitSet(g_pInputDevice->evbit, EV_KEY);
+# ifdef EV_SYN
+                ASMBitSet(g_pInputDevice->evbit, EV_SYN);
+# endif
+                input_set_abs_params(g_pInputDevice, ABS_X, VMMDEV_MOUSE_RANGE_MIN, VMMDEV_MOUSE_RANGE_MAX, 0, 0);
+                input_set_abs_params(g_pInputDevice, ABS_Y, VMMDEV_MOUSE_RANGE_MIN, VMMDEV_MOUSE_RANGE_MAX, 0, 0);
+                ASMBitSet(g_pInputDevice->keybit, BTN_MOUSE);
+                /** @todo this string should be in a header file somewhere. */
+                g_pInputDevice->name = "VirtualBox mouse integration";
+                return 0;
+            }
+
+            input_free_device(g_pInputDevice);
+        }
+        else
+            rc = -ENOMEM;
+        VbglGRFree(&g_pMouseStatusReq->header);
+        g_pMouseStatusReq = NULL;
+    }
+    else
+        rc = -ENOMEM;
+    return rc;
+}
+
+
+/**
+ * Terminates the kernel input device.
+ */
+static void vgdrvLinuxTermInputDevice(void)
+{
+    VbglGRFree(&g_pMouseStatusReq->header);
+    g_pMouseStatusReq = NULL;
+
+    /* See documentation of input_register_device(): input_free_device()
+     * should not be called after a device has been registered. */
+    input_unregister_device(g_pInputDevice);
+}
+
+#endif /* VBOXGUEST_WITH_INPUT_DRIVER */
+
+
+/**
+ * Creates the device nodes.
+ *
+ * @returns 0 on success, negated errno on failure.
+ */
+static int __init vgdrvLinuxInitDeviceNodes(void)
+{
+    /*
+     * The full feature device node.
+     */
+    int rc = misc_register(&g_MiscDevice);
+    if (!rc)
+    {
+        /*
+         * The device node intended to be accessible by all users.
+         */
+        rc = misc_register(&g_MiscDeviceUser);
+        if (!rc)
+            return 0;
+        LogRel((DEVICE_NAME ": misc_register failed for %s (rc=%d)\n", DEVICE_NAME_USER, rc));
+        misc_deregister(&g_MiscDevice);
+    }
+    else
+        LogRel((DEVICE_NAME ": misc_register failed for %s (rc=%d)\n", DEVICE_NAME, rc));
+    return rc;
+}
+
+
+/**
+ * Deregisters the device nodes.
+ */
+static void vgdrvLinuxTermDeviceNodes(void)
+{
+    misc_deregister(&g_MiscDevice);
+    misc_deregister(&g_MiscDeviceUser);
+}
+
+
+/**
+ * Initialize module.
+ *
+ * @returns appropriate status code.
+ */
+static int __init vgdrvLinuxModInit(void)
+{
+    static const char * const   s_apszGroups[] = VBOX_LOGGROUP_NAMES;
+    PRTLOGGER                   pRelLogger;
+    int                         rc;
+
+    /*
+     * Initialize IPRT first.
+     */
+    rc = RTR0Init(0);
+    if (RT_FAILURE(rc))
+    {
+        printk(KERN_ERR DEVICE_NAME ": RTR0Init failed, rc=%d.\n", rc);
+        return -EINVAL;
+    }
+
+    /*
+     * Create the release log.
+     * (We do that here instead of common code because we want to log
+     * early failures using the LogRel macro.)
+     */
+    rc = RTLogCreate(&pRelLogger, 0 /* fFlags */, "all",
+                     "VBOX_RELEASE_LOG", RT_ELEMENTS(s_apszGroups), s_apszGroups,
+                     RTLOGDEST_STDOUT | RTLOGDEST_DEBUGGER | RTLOGDEST_USER, NULL);
+    if (RT_SUCCESS(rc))
+    {
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)
+        RTLogGroupSettings(pRelLogger, g_szLogGrp);
+        RTLogFlags(pRelLogger, g_szLogFlags);
+        RTLogDestinations(pRelLogger, g_szLogDst);
+#endif
+        RTLogRelSetDefaultInstance(pRelLogger);
+    }
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)
+    g_fLoggerCreated = true;
+#endif
+
+    /*
+     * Locate and initialize the PCI device.
+     */
+    rc = pci_register_driver(&g_PciDriver);
+    if (rc >= 0 && g_pPciDev)
+    {
+        /*
+         * Register the interrupt service routine for it.
+         */
+        rc = vgdrvLinuxInitISR();
+        if (rc >= 0)
+        {
+            /*
+             * Call the common device extension initializer.
+             */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) && defined(RT_ARCH_X86)
+            VBOXOSTYPE enmOSType = VBOXOSTYPE_Linux26;
+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) && defined(RT_ARCH_AMD64)
+            VBOXOSTYPE enmOSType = VBOXOSTYPE_Linux26_x64;
+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 0) && defined(RT_ARCH_X86)
+            VBOXOSTYPE enmOSType = VBOXOSTYPE_Linux24;
+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 0) && defined(RT_ARCH_AMD64)
+            VBOXOSTYPE enmOSType = VBOXOSTYPE_Linux24_x64;
+#else
+# warning "huh? which arch + version is this?"
+            VBOXOSTYPE enmOsType = VBOXOSTYPE_Linux;
+#endif
+            rc = VGDrvCommonInitDevExt(&g_DevExt,
+                                       g_IOPortBase,
+                                       g_pvMMIOBase,
+                                       g_cbMMIO,
+                                       enmOSType,
+                                       VMMDEV_EVENT_MOUSE_POSITION_CHANGED);
+            if (RT_SUCCESS(rc))
+            {
+                /*
+                 * Create the kernel session for this driver.
+                 */
+                rc = VGDrvCommonCreateKernelSession(&g_DevExt, &g_pKernelSession);
+                if (RT_SUCCESS(rc))
+                {
+                    /*
+                     * Create the kernel input device.
+                     */
+#ifdef VBOXGUEST_WITH_INPUT_DRIVER
+                    rc = vgdrvLinuxCreateInputDevice();
+                    if (rc >= 0)
+                    {
+#endif
+                        /*
+                         * Finally, create the device nodes.
+                         */
+                        rc = vgdrvLinuxInitDeviceNodes();
+                        if (rc >= 0)
+                        {
+                            /* some useful information for the user but don't show this on the console */
+                            LogRel((DEVICE_NAME ": misc device minor %d, IRQ %d, I/O port %RTiop, MMIO at %RHp (size 0x%x)\n",
+                                    g_MiscDevice.minor, g_pPciDev->irq, g_IOPortBase, g_MMIOPhysAddr, g_cbMMIO));
+                            printk(KERN_DEBUG DEVICE_NAME ": Successfully loaded version "
+                                   VBOX_VERSION_STRING " (interface " RT_XSTR(VMMDEV_VERSION) ")\n");
+                            return rc;
+                        }
+
+                        /* bail out */
+#ifdef VBOXGUEST_WITH_INPUT_DRIVER
+                        vgdrvLinuxTermInputDevice();
+                    }
+                    else
+                    {
+                        LogRel((DEVICE_NAME ": vboxguestCreateInputDevice failed with rc=%Rrc\n", rc));
+                        rc = RTErrConvertFromErrno(rc);
+                    }
+#endif
+                    VGDrvCommonCloseSession(&g_DevExt, g_pKernelSession);
+                }
+                VGDrvCommonDeleteDevExt(&g_DevExt);
+            }
+            else
+            {
+                LogRel((DEVICE_NAME ": VGDrvCommonInitDevExt failed with rc=%Rrc\n", rc));
+                rc = RTErrConvertFromErrno(rc);
+            }
+            vgdrvLinuxTermISR();
+        }
+    }
+    else
+    {
+        LogRel((DEVICE_NAME ": PCI device not found, probably running on physical hardware.\n"));
+        rc = -ENODEV;
+    }
+    pci_unregister_driver(&g_PciDriver);
+    RTLogDestroy(RTLogRelSetDefaultInstance(NULL));
+    RTLogDestroy(RTLogSetDefaultInstance(NULL));
+    RTR0Term();
+    return rc;
+}
+
+
+/**
+ * Unload the module.
+ */
+static void __exit vgdrvLinuxModExit(void)
+{
+    /*
+     * Inverse order of init.
+     */
+    vgdrvLinuxTermDeviceNodes();
+#ifdef VBOXGUEST_WITH_INPUT_DRIVER
+    vgdrvLinuxTermInputDevice();
+#endif
+    VGDrvCommonCloseSession(&g_DevExt, g_pKernelSession);
+    VGDrvCommonDeleteDevExt(&g_DevExt);
+    vgdrvLinuxTermISR();
+    pci_unregister_driver(&g_PciDriver);
+    RTLogDestroy(RTLogRelSetDefaultInstance(NULL));
+    RTLogDestroy(RTLogSetDefaultInstance(NULL));
+    RTR0Term();
+}
+
+
+/**
+ * Device open. Called on open /dev/vboxdrv
+ *
+ * @param   pInode      Pointer to inode info structure.
+ * @param   pFilp       Associated file pointer.
+ */
+static int vgdrvLinuxOpen(struct inode *pInode, struct file *pFilp)
+{
+    int                 rc;
+    PVBOXGUESTSESSION   pSession;
+    Log((DEVICE_NAME ": pFilp=%p pid=%d/%d %s\n", pFilp, RTProcSelf(), current->pid, current->comm));
+
+    /*
+     * Call common code to create the user session. Associate it with
+     * the file so we can access it in the other methods.
+     */
+    rc = VGDrvCommonCreateUserSession(&g_DevExt, &pSession);
+    if (RT_SUCCESS(rc))
+    {
+        pFilp->private_data = pSession;
+        if (MINOR(pInode->i_rdev) == g_MiscDeviceUser.minor)
+            pSession->fUserSession = true;
+    }
+
+    Log(("vgdrvLinuxOpen: g_DevExt=%p pSession=%p rc=%d/%d (pid=%d/%d %s)\n",
+         &g_DevExt, pSession, rc, vgdrvLinuxConvertToNegErrno(rc), RTProcSelf(), current->pid, current->comm));
+    return vgdrvLinuxConvertToNegErrno(rc);
+}
+
+
+/**
+ * Close device.
+ *
+ * @param   pInode      Pointer to inode info structure.
+ * @param   pFilp       Associated file pointer.
+ */
+static int vgdrvLinuxRelease(struct inode *pInode, struct file *pFilp)
+{
+    Log(("vgdrvLinuxRelease: pFilp=%p pSession=%p pid=%d/%d %s\n",
+         pFilp, pFilp->private_data, RTProcSelf(), current->pid, current->comm));
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 28)
+    /* This housekeeping was needed in older kernel versions to ensure that
+     * the file pointer didn't get left on the polling queue. */
+    vgdrvLinuxFAsync(-1, pFilp, 0);
+#endif
+    VGDrvCommonCloseSession(&g_DevExt, (PVBOXGUESTSESSION)pFilp->private_data);
+    pFilp->private_data = NULL;
+    return 0;
+}
+
+
+/**
+ * Device I/O Control entry point.
+ *
+ * @param   pInode      Associated inode pointer.
+ * @param   pFilp       Associated file pointer.
+ * @param   uCmd        The function specified to ioctl().
+ * @param   ulArg       The argument specified to ioctl().
+ */
+#ifdef HAVE_UNLOCKED_IOCTL
+static long vgdrvLinuxIOCtl(struct file *pFilp, unsigned int uCmd, unsigned long ulArg)
+#else
+static int vgdrvLinuxIOCtl(struct inode *pInode, struct file *pFilp, unsigned int uCmd, unsigned long ulArg)
+#endif
+{
+    PVBOXGUESTSESSION   pSession = (PVBOXGUESTSESSION)pFilp->private_data;
+    uint32_t            cbData   = _IOC_SIZE(uCmd);
+    void               *pvBufFree;
+    void               *pvBuf;
+    int                 rc;
+    uint64_t            au64Buf[32/sizeof(uint64_t)];
+
+    Log6(("vgdrvLinuxIOCtl: pFilp=%p uCmd=%#x ulArg=%p pid=%d/%d\n", pFilp, uCmd, (void *)ulArg, RTProcSelf(), current->pid));
+
+    /*
+     * Buffer the request.
+     */
+    if (cbData <= sizeof(au64Buf))
+    {
+        pvBufFree = NULL;
+        pvBuf = &au64Buf[0];
+    }
+    else
+    {
+        pvBufFree = pvBuf = RTMemTmpAlloc(cbData);
+        if (RT_UNLIKELY(!pvBuf))
+        {
+            LogRel((DEVICE_NAME "::IOCtl: RTMemTmpAlloc failed to alloc %u bytes.\n", cbData));
+            return -ENOMEM;
+        }
+    }
+    if (RT_LIKELY(copy_from_user(pvBuf, (void *)ulArg, cbData) == 0))
+    {
+        /*
+         * Process the IOCtl.
+         */
+        size_t cbDataReturned;
+        rc = VGDrvCommonIoCtl(uCmd, &g_DevExt, pSession, pvBuf, cbData, &cbDataReturned);
+
+        /*
+         * Copy ioctl data and output buffer back to user space.
+         */
+        if (RT_SUCCESS(rc))
+        {
+            rc = 0;
+            if (RT_UNLIKELY(cbDataReturned > cbData))
+            {
+                LogRel((DEVICE_NAME "::IOCtl: too much output data %u expected %u\n", cbDataReturned, cbData));
+                cbDataReturned = cbData;
+            }
+            if (cbDataReturned > 0)
+            {
+                if (RT_UNLIKELY(copy_to_user((void *)ulArg, pvBuf, cbDataReturned) != 0))
+                {
+                    LogRel((DEVICE_NAME "::IOCtl: copy_to_user failed; pvBuf=%p ulArg=%p cbDataReturned=%u uCmd=%d\n",
+                            pvBuf, (void *)ulArg, cbDataReturned, uCmd, rc));
+                    rc = -EFAULT;
+                }
+            }
+        }
+        else
+        {
+            Log(("vgdrvLinuxIOCtl: pFilp=%p uCmd=%#x ulArg=%p failed, rc=%d\n", pFilp, uCmd, (void *)ulArg, rc));
+            rc = -rc; Assert(rc > 0); /* Positive returns == negated VBox error status codes. */
+        }
+    }
+    else
+    {
+        Log((DEVICE_NAME "::IOCtl: copy_from_user(,%#lx, %#x) failed; uCmd=%#x.\n", ulArg, cbData, uCmd));
+        rc = -EFAULT;
+    }
+    if (pvBufFree)
+        RTMemFree(pvBufFree);
+
+    Log6(("vgdrvLinuxIOCtl: returns %d (pid=%d/%d)\n", rc, RTProcSelf(), current->pid));
+    return rc;
+}
+
+
+/**
+ * Asynchronous notification activation method.
+ *
+ * @returns 0 on success, negative errno on failure.
+ *
+ * @param   fd          The file descriptor.
+ * @param   pFile       The file structure.
+ * @param   fOn         On/off indicator.
+ */
+static int vgdrvLinuxFAsync(int fd, struct file *pFile, int fOn)
+{
+    return fasync_helper(fd, pFile, fOn, &g_pFAsyncQueue);
+}
+
+
+/**
+ * Poll function.
+ *
+ * This returns ready to read if the mouse pointer mode or the pointer position
+ * has changed since last call to read.
+ *
+ * @returns 0 if no changes, POLLIN | POLLRDNORM if there are unseen changes.
+ *
+ * @param   pFile       The file structure.
+ * @param   pPt         The poll table.
+ *
+ * @remarks This is probably not really used, X11 is said to use the fasync
+ *          interface instead.
+ */
+static unsigned int vgdrvLinuxPoll(struct file *pFile, poll_table *pPt)
+{
+    PVBOXGUESTSESSION   pSession  = (PVBOXGUESTSESSION)pFile->private_data;
+    uint32_t            u32CurSeq = ASMAtomicUoReadU32(&g_DevExt.u32MousePosChangedSeq);
+    unsigned int        fMask     = pSession->u32MousePosChangedSeq != u32CurSeq
+                                  ? POLLIN | POLLRDNORM
+                                  : 0;
+    poll_wait(pFile, &g_PollEventQueue, pPt);
+    return fMask;
+}
+
+
+/**
+ * Read to go with our poll/fasync response.
+ *
+ * @returns 1 or -EINVAL.
+ *
+ * @param   pFile       The file structure.
+ * @param   pbBuf       The buffer to read into.
+ * @param   cbRead      The max number of bytes to read.
+ * @param   poff        The current file position.
+ *
+ * @remarks This is probably not really used as X11 lets the driver do its own
+ *          event reading. The poll condition is therefore also cleared when we
+ *          see VMMDevReq_GetMouseStatus in vgdrvIoCtl_VMMRequest.
+ */
+static ssize_t vgdrvLinuxRead(struct file *pFile, char *pbBuf, size_t cbRead, loff_t *poff)
+{
+    PVBOXGUESTSESSION   pSession  = (PVBOXGUESTSESSION)pFile->private_data;
+    uint32_t            u32CurSeq = ASMAtomicUoReadU32(&g_DevExt.u32MousePosChangedSeq);
+
+    if (*poff != 0)
+        return -EINVAL;
+
+    /*
+     * Fake a single byte read if we're not up to date with the current mouse position.
+     */
+    if (    pSession->u32MousePosChangedSeq != u32CurSeq
+        &&  cbRead > 0)
+    {
+        pSession->u32MousePosChangedSeq = u32CurSeq;
+        pbBuf[0] = 0;
+        return 1;
+    }
+    return 0;
+}
+
+
+void VGDrvNativeISRMousePollEvent(PVBOXGUESTDEVEXT pDevExt)
+{
+#ifdef VBOXGUEST_WITH_INPUT_DRIVER
+    int rc;
+#endif
+    NOREF(pDevExt);
+
+    /*
+     * Wake up everyone that's in a poll() and post anyone that has
+     * subscribed to async notifications.
+     */
+    Log3(("VGDrvNativeISRMousePollEvent: wake_up_all\n"));
+    wake_up_all(&g_PollEventQueue);
+    Log3(("VGDrvNativeISRMousePollEvent: kill_fasync\n"));
+    kill_fasync(&g_pFAsyncQueue, SIGIO, POLL_IN);
+#ifdef VBOXGUEST_WITH_INPUT_DRIVER
+    /* Report events to the kernel input device */
+    g_pMouseStatusReq->mouseFeatures = 0;
+    g_pMouseStatusReq->pointerXPos = 0;
+    g_pMouseStatusReq->pointerYPos = 0;
+    rc = VbglGRPerform(&g_pMouseStatusReq->header);
+    if (RT_SUCCESS(rc))
+    {
+        input_report_abs(g_pInputDevice, ABS_X,
+                         g_pMouseStatusReq->pointerXPos);
+        input_report_abs(g_pInputDevice, ABS_Y,
+                         g_pMouseStatusReq->pointerYPos);
+# ifdef EV_SYN
+        input_sync(g_pInputDevice);
+# endif
+    }
+#endif
+    Log3(("VGDrvNativeISRMousePollEvent: done\n"));
+}
+
+
+/* Common code that depend on g_DevExt. */
+#include "VBoxGuestIDC-unix.c.h"
+
+EXPORT_SYMBOL(VBoxGuestIDCOpen);
+EXPORT_SYMBOL(VBoxGuestIDCClose);
+EXPORT_SYMBOL(VBoxGuestIDCCall);
+
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)
+
+/** log and dbg_log parameter setter. */
+static int vgdrvLinuxParamLogGrpSet(const char *pszValue, struct kernel_param *pParam)
+{
+    if (g_fLoggerCreated)
+    {
+        PRTLOGGER pLogger = pParam->name[0] == 'd' ? RTLogDefaultInstance() : RTLogRelGetDefaultInstance();
+        if (pLogger)
+            RTLogGroupSettings(pLogger, pszValue);
+    }
+    else if (pParam->name[0] != 'd')
+        strlcpy(&g_szLogGrp[0], pszValue, sizeof(g_szLogGrp));
+
+    return 0;
+}
+
+/** log and dbg_log parameter getter. */
+static int vgdrvLinuxParamLogGrpGet(char *pszBuf, struct kernel_param *pParam)
+{
+    PRTLOGGER pLogger = pParam->name[0] == 'd' ? RTLogDefaultInstance() : RTLogRelGetDefaultInstance();
+    *pszBuf = '\0';
+    if (pLogger)
+        RTLogGetGroupSettings(pLogger, pszBuf, _4K);
+    return strlen(pszBuf);
+}
+
+
+/** log and dbg_log_flags parameter setter. */
+static int vgdrvLinuxParamLogFlagsSet(const char *pszValue, struct kernel_param *pParam)
+{
+    if (g_fLoggerCreated)
+    {
+        PRTLOGGER pLogger = pParam->name[0] == 'd' ? RTLogDefaultInstance() : RTLogRelGetDefaultInstance();
+        if (pLogger)
+            RTLogFlags(pLogger, pszValue);
+    }
+    else if (pParam->name[0] != 'd')
+        strlcpy(&g_szLogFlags[0], pszValue, sizeof(g_szLogFlags));
+    return 0;
+}
+
+/** log and dbg_log_flags parameter getter. */
+static int vgdrvLinuxParamLogFlagsGet(char *pszBuf, struct kernel_param *pParam)
+{
+    PRTLOGGER pLogger = pParam->name[0] == 'd' ? RTLogDefaultInstance() : RTLogRelGetDefaultInstance();
+    *pszBuf = '\0';
+    if (pLogger)
+        RTLogGetFlags(pLogger, pszBuf, _4K);
+    return strlen(pszBuf);
+}
+
+
+/** log and dbg_log_dest parameter setter. */
+static int vgdrvLinuxParamLogDstSet(const char *pszValue, struct kernel_param *pParam)
+{
+    if (g_fLoggerCreated)
+    {
+        PRTLOGGER pLogger = pParam->name[0] == 'd' ? RTLogDefaultInstance() : RTLogRelGetDefaultInstance();
+        if (pLogger)
+            RTLogDestinations(pLogger, pszValue);
+    }
+    else if (pParam->name[0] != 'd')
+        strlcpy(&g_szLogDst[0], pszValue, sizeof(g_szLogDst));
+    return 0;
+}
+
+/** log and dbg_log_dest parameter getter. */
+static int vgdrvLinuxParamLogDstGet(char *pszBuf, struct kernel_param *pParam)
+{
+    PRTLOGGER pLogger = pParam->name[0] == 'd' ? RTLogDefaultInstance() : RTLogRelGetDefaultInstance();
+    *pszBuf = '\0';
+    if (pLogger)
+        RTLogGetDestinations(pLogger, pszBuf, _4K);
+    return strlen(pszBuf);
+}
+
+
+/** r3_log_to_host parameter setter. */
+static int vgdrvLinuxParamR3LogToHostSet(const char *pszValue, struct kernel_param *pParam)
+{
+    if (    pszValue == NULL
+        || *pszValue == '\0'
+        || *pszValue == 'n'
+        || *pszValue == 'N'
+        || *pszValue == 'd'
+        || *pszValue == 'D'
+        || (   (*pszValue == 'o' || *pszValue == 'O')
+            && (*pszValue == 'f' || *pszValue == 'F') )
+       )
+        g_DevExt.fLoggingEnabled = false;
+    else
+        g_DevExt.fLoggingEnabled = true;
+    return 0;
+}
+
+/** r3_log_to_host parameter getter. */
+static int vgdrvLinuxParamR3LogToHostGet(char *pszBuf, struct kernel_param *pParam)
+{
+    strcpy(pszBuf, g_DevExt.fLoggingEnabled ? "enabled" : "disabled");
+    return strlen(pszBuf);
+}
+
+
+/*
+ * Define module parameters.
+ */
+module_param_call(log,            vgdrvLinuxParamLogGrpSet,   vgdrvLinuxParamLogGrpGet,   NULL, 0664);
+module_param_call(log_flags,      vgdrvLinuxParamLogFlagsSet, vgdrvLinuxParamLogFlagsGet, NULL, 0664);
+module_param_call(log_dest,       vgdrvLinuxParamLogDstSet,   vgdrvLinuxParamLogDstGet,   NULL, 0664);
+# ifdef LOG_ENABLED
+module_param_call(dbg_log,        vgdrvLinuxParamLogGrpSet,   vgdrvLinuxParamLogGrpGet,   NULL, 0664);
+module_param_call(dbg_log_flags,  vgdrvLinuxParamLogFlagsSet, vgdrvLinuxParamLogFlagsGet, NULL, 0664);
+module_param_call(dbg_log_dest,   vgdrvLinuxParamLogDstSet,   vgdrvLinuxParamLogDstGet,   NULL, 0664);
+# endif
+module_param_call(r3_log_to_host, vgdrvLinuxParamR3LogToHostSet, vgdrvLinuxParamR3LogToHostGet, NULL, 0664);
+
+#endif /* 2.6.0 and later */
+
+
+module_init(vgdrvLinuxModInit);
+module_exit(vgdrvLinuxModExit);
+
+MODULE_AUTHOR(VBOX_VENDOR);
+MODULE_DESCRIPTION(VBOX_PRODUCT " Guest Additions for Linux Module");
+MODULE_LICENSE("GPL");
+#ifdef MODULE_VERSION
+MODULE_VERSION(VBOX_VERSION_STRING);
+#endif
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/vboxguest/VBoxGuest.c
@@ -0,0 +1,3748 @@
+/* $Id: VBoxGuest.cpp $ */
+/** @file
+ * VBoxGuest - Guest Additions Driver, Common Code.
+ */
+
+/*
+ * Copyright (C) 2007-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+/** @page pg_vbdrv VBoxGuest
+ *
+ * VBoxGuest is the device driver for VMMDev.
+ *
+ * The device driver is shipped as part of the guest additions.  It has roots in
+ * the host VMM support driver (usually known as VBoxDrv), so fixes in platform
+ * specific code may apply to both drivers.
+ *
+ * The common code lives in VBoxGuest.cpp and is compiled both as C++ and C.
+ * The VBoxGuest.cpp source file shall not contain platform specific code,
+ * though it must occationally do a few \#ifdef RT_OS_XXX tests to cater for
+ * platform differences.  Though, in those cases, it is common that more than
+ * one platform needs special handling.
+ *
+ * On most platforms the device driver should create two device nodes, one for
+ * full (unrestricted) access to the feature set, and one which only provides a
+ * restrict set of functions.  These are generally referred to as 'vboxguest'
+ * and 'vboxuser' respectively.  Currently, this two device approach is only
+ * implemented on Linux!
+ *
+ */
+
+
+/*********************************************************************************************************************************
+*   Header Files                                                                                                                 *
+*********************************************************************************************************************************/
+#define LOG_GROUP   LOG_GROUP_DEFAULT
+#include "VBoxGuestInternal.h"
+#include <VBox/VMMDev.h> /* for VMMDEV_RAM_SIZE */
+#include <VBox/log.h>
+#include <iprt/mem.h>
+#include <iprt/time.h>
+#include <iprt/memobj.h>
+#include <iprt/asm.h>
+#include <iprt/asm-amd64-x86.h>
+#include <iprt/string.h>
+#include <iprt/process.h>
+#include <iprt/assert.h>
+#include <iprt/param.h>
+#include <iprt/timer.h>
+#ifdef VBOX_WITH_HGCM
+# include <iprt/thread.h>
+#endif
+#include "version-generated.h"
+#if defined(RT_OS_LINUX) || defined(RT_OS_FREEBSD)
+# include "revision-generated.h"
+#endif
+#ifdef RT_OS_WINDOWS
+# ifndef CTL_CODE
+#  include <Windows.h>
+# endif
+#endif
+#if defined(RT_OS_SOLARIS) || defined(RT_OS_DARWIN)
+# include <iprt/rand.h>
+#endif
+
+
+/*********************************************************************************************************************************
+*   Defined Constants And Macros                                                                                                 *
+*********************************************************************************************************************************/
+#define VBOXGUEST_ACQUIRE_STYLE_EVENTS (VMMDEV_EVENT_DISPLAY_CHANGE_REQUEST | VMMDEV_EVENT_SEAMLESS_MODE_CHANGE_REQUEST)
+
+
+/*********************************************************************************************************************************
+*   Internal Functions                                                                                                           *
+*********************************************************************************************************************************/
+#ifdef VBOX_WITH_HGCM
+static DECLCALLBACK(int) vgdrvHgcmAsyncWaitCallback(VMMDevHGCMRequestHeader *pHdrNonVolatile, void *pvUser, uint32_t u32User);
+#endif
+static int      vgdrvIoCtl_CancelAllWaitEvents(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION pSession);
+static void     vgdrvBitUsageTrackerClear(PVBOXGUESTBITUSAGETRACER pTracker);
+static uint32_t vgdrvGetAllowedEventMaskForSession(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION pSession);
+static int      vgdrvResetEventFilterOnHost(PVBOXGUESTDEVEXT pDevExt, uint32_t fFixedEvents);
+static int      vgdrvResetMouseStatusOnHost(PVBOXGUESTDEVEXT pDevExt);
+static int      vgdrvResetCapabilitiesOnHost(PVBOXGUESTDEVEXT pDevExt);
+static int      vgdrvSetSessionEventFilter(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION pSession,
+                                           uint32_t fOrMask, uint32_t fNotMask, bool fSessionTermination);
+static int      vgdrvSetSessionMouseStatus(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION pSession,
+                                           uint32_t fOrMask, uint32_t fNotMask, bool fSessionTermination);
+static int      vgdrvSetSessionCapabilities(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION pSession,
+                                            uint32_t fOrMask, uint32_t fNoMask, bool fSessionTermination);
+static int      vgdrvAcquireSessionCapabilities(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION pSession, uint32_t fOrMask,
+                                                uint32_t fNotMask, VBOXGUESTCAPSACQUIRE_FLAGS enmFlags, bool fSessionTermination);
+static int      vgdrvDispatchEventsLocked(PVBOXGUESTDEVEXT pDevExt, uint32_t fEvents);
+
+
+/*********************************************************************************************************************************
+*   Global Variables                                                                                                             *
+*********************************************************************************************************************************/
+static const uint32_t g_cbChangeMemBalloonReq = RT_OFFSETOF(VMMDevChangeMemBalloon, aPhysPage[VMMDEV_MEMORY_BALLOON_CHUNK_PAGES]);
+
+#if defined(RT_OS_DARWIN) || defined(RT_OS_SOLARIS)
+/**
+ * Drag in the rest of IRPT since we share it with the
+ * rest of the kernel modules on Solaris.
+ */
+PFNRT g_apfnVBoxGuestIPRTDeps[] =
+{
+    /* VirtioNet */
+    (PFNRT)RTRandBytes,
+    /* RTSemMutex* */
+    (PFNRT)RTSemMutexCreate,
+    (PFNRT)RTSemMutexDestroy,
+    (PFNRT)RTSemMutexRequest,
+    (PFNRT)RTSemMutexRequestNoResume,
+    (PFNRT)RTSemMutexRequestDebug,
+    (PFNRT)RTSemMutexRequestNoResumeDebug,
+    (PFNRT)RTSemMutexRelease,
+    (PFNRT)RTSemMutexIsOwned,
+    NULL
+};
+#endif  /* RT_OS_DARWIN || RT_OS_SOLARIS  */
+
+
+/**
+ * Reserves memory in which the VMM can relocate any guest mappings
+ * that are floating around.
+ *
+ * This operation is a little bit tricky since the VMM might not accept
+ * just any address because of address clashes between the three contexts
+ * it operates in, so use a small stack to perform this operation.
+ *
+ * @returns VBox status code (ignored).
+ * @param   pDevExt     The device extension.
+ */
+static int vgdrvInitFixateGuestMappings(PVBOXGUESTDEVEXT pDevExt)
+{
+    /*
+     * Query the required space.
+     */
+    VMMDevReqHypervisorInfo *pReq;
+    int rc = VbglGRAlloc((VMMDevRequestHeader **)&pReq, sizeof(VMMDevReqHypervisorInfo), VMMDevReq_GetHypervisorInfo);
+    if (RT_FAILURE(rc))
+        return rc;
+    pReq->hypervisorStart = 0;
+    pReq->hypervisorSize  = 0;
+    rc = VbglGRPerform(&pReq->header);
+    if (RT_FAILURE(rc)) /* this shouldn't happen! */
+    {
+        VbglGRFree(&pReq->header);
+        return rc;
+    }
+
+    /*
+     * The VMM will report back if there is nothing it wants to map, like for
+     * instance in VT-x and AMD-V mode.
+     */
+    if (pReq->hypervisorSize == 0)
+        Log(("vgdrvInitFixateGuestMappings: nothing to do\n"));
+    else
+    {
+        /*
+         * We have to try several times since the host can be picky
+         * about certain addresses.
+         */
+        RTR0MEMOBJ  hFictive     = NIL_RTR0MEMOBJ;
+        uint32_t    cbHypervisor = pReq->hypervisorSize;
+        RTR0MEMOBJ  ahTries[5];
+        uint32_t    iTry;
+        bool        fBitched = false;
+        Log(("vgdrvInitFixateGuestMappings: cbHypervisor=%#x\n", cbHypervisor));
+        for (iTry = 0; iTry < RT_ELEMENTS(ahTries); iTry++)
+        {
+            /*
+             * Reserve space, or if that isn't supported, create a object for
+             * some fictive physical memory and map that in to kernel space.
+             *
+             * To make the code a bit uglier, most systems cannot help with
+             * 4MB alignment, so we have to deal with that in addition to
+             * having two ways of getting the memory.
+             */
+            uint32_t    uAlignment = _4M;
+            RTR0MEMOBJ  hObj;
+            rc = RTR0MemObjReserveKernel(&hObj, (void *)-1, RT_ALIGN_32(cbHypervisor, _4M), uAlignment);
+            if (rc == VERR_NOT_SUPPORTED)
+            {
+                uAlignment = PAGE_SIZE;
+                rc = RTR0MemObjReserveKernel(&hObj, (void *)-1, RT_ALIGN_32(cbHypervisor, _4M) + _4M, uAlignment);
+            }
+            /*
+             * If both RTR0MemObjReserveKernel calls above failed because either not supported or
+             * not implemented at all at the current platform, try to map the memory object into the
+             * virtual kernel space.
+             */
+            if (rc == VERR_NOT_SUPPORTED)
+            {
+                if (hFictive == NIL_RTR0MEMOBJ)
+                {
+                    rc = RTR0MemObjEnterPhys(&hObj, VBOXGUEST_HYPERVISOR_PHYSICAL_START, cbHypervisor + _4M, RTMEM_CACHE_POLICY_DONT_CARE);
+                    if (RT_FAILURE(rc))
+                        break;
+                    hFictive = hObj;
+                }
+                uAlignment = _4M;
+                rc = RTR0MemObjMapKernel(&hObj, hFictive, (void *)-1, uAlignment, RTMEM_PROT_READ | RTMEM_PROT_WRITE);
+                if (rc == VERR_NOT_SUPPORTED)
+                {
+                    uAlignment = PAGE_SIZE;
+                    rc = RTR0MemObjMapKernel(&hObj, hFictive, (void *)-1, uAlignment, RTMEM_PROT_READ | RTMEM_PROT_WRITE);
+                }
+            }
+            if (RT_FAILURE(rc))
+            {
+                LogRel(("VBoxGuest: Failed to reserve memory for the hypervisor: rc=%Rrc (cbHypervisor=%#x uAlignment=%#x iTry=%u)\n",
+                        rc, cbHypervisor, uAlignment, iTry));
+                fBitched = true;
+                break;
+            }
+
+            /*
+             * Try set it.
+             */
+            pReq->header.requestType = VMMDevReq_SetHypervisorInfo;
+            pReq->header.rc          = VERR_INTERNAL_ERROR;
+            pReq->hypervisorSize     = cbHypervisor;
+            pReq->hypervisorStart    = (RTGCPTR32)(uintptr_t)RTR0MemObjAddress(hObj);
+            if (    uAlignment == PAGE_SIZE
+                &&  pReq->hypervisorStart & (_4M - 1))
+                pReq->hypervisorStart = RT_ALIGN_32(pReq->hypervisorStart, _4M);
+            AssertMsg(RT_ALIGN_32(pReq->hypervisorStart, _4M) == pReq->hypervisorStart, ("%#x\n", pReq->hypervisorStart));
+
+            rc = VbglGRPerform(&pReq->header);
+            if (RT_SUCCESS(rc))
+            {
+                pDevExt->hGuestMappings = hFictive != NIL_RTR0MEMOBJ ? hFictive : hObj;
+                Log(("VBoxGuest: %p LB %#x; uAlignment=%#x iTry=%u hGuestMappings=%p (%s)\n",
+                     RTR0MemObjAddress(pDevExt->hGuestMappings),
+                     RTR0MemObjSize(pDevExt->hGuestMappings),
+                     uAlignment, iTry, pDevExt->hGuestMappings, hFictive != NIL_RTR0PTR ? "fictive" : "reservation"));
+                break;
+            }
+            ahTries[iTry] = hObj;
+        }
+
+        /*
+         * Cleanup failed attempts.
+         */
+        while (iTry-- > 0)
+            RTR0MemObjFree(ahTries[iTry], false /* fFreeMappings */);
+        if (    RT_FAILURE(rc)
+            &&  hFictive != NIL_RTR0PTR)
+            RTR0MemObjFree(hFictive, false /* fFreeMappings */);
+        if (RT_FAILURE(rc) && !fBitched)
+            LogRel(("VBoxGuest: Warning: failed to reserve %#d of memory for guest mappings.\n", cbHypervisor));
+    }
+    VbglGRFree(&pReq->header);
+
+    /*
+     * We ignore failed attempts for now.
+     */
+    return VINF_SUCCESS;
+}
+
+
+/**
+ * Undo what vgdrvInitFixateGuestMappings did.
+ *
+ * @param   pDevExt     The device extension.
+ */
+static void vgdrvTermUnfixGuestMappings(PVBOXGUESTDEVEXT pDevExt)
+{
+    if (pDevExt->hGuestMappings != NIL_RTR0PTR)
+    {
+        /*
+         * Tell the host that we're going to free the memory we reserved for
+         * it, the free it up. (Leak the memory if anything goes wrong here.)
+         */
+        VMMDevReqHypervisorInfo *pReq;
+        int rc = VbglGRAlloc((VMMDevRequestHeader **)&pReq, sizeof(VMMDevReqHypervisorInfo), VMMDevReq_SetHypervisorInfo);
+        if (RT_SUCCESS(rc))
+        {
+            pReq->hypervisorStart = 0;
+            pReq->hypervisorSize  = 0;
+            rc = VbglGRPerform(&pReq->header);
+            VbglGRFree(&pReq->header);
+        }
+        if (RT_SUCCESS(rc))
+        {
+            rc = RTR0MemObjFree(pDevExt->hGuestMappings, true /* fFreeMappings */);
+            AssertRC(rc);
+        }
+        else
+            LogRel(("vgdrvTermUnfixGuestMappings: Failed to unfix the guest mappings! rc=%Rrc\n", rc));
+
+        pDevExt->hGuestMappings = NIL_RTR0MEMOBJ;
+    }
+}
+
+
+
+/**
+ * Report the guest information to the host.
+ *
+ * @returns IPRT status code.
+ * @param   enmOSType       The OS type to report.
+ */
+static int vgdrvReportGuestInfo(VBOXOSTYPE enmOSType)
+{
+    /*
+     * Allocate and fill in the two guest info reports.
+     */
+    VMMDevReportGuestInfo2 *pReqInfo2 = NULL;
+    VMMDevReportGuestInfo  *pReqInfo1 = NULL;
+    int rc = VbglGRAlloc((VMMDevRequestHeader **)&pReqInfo2, sizeof (VMMDevReportGuestInfo2), VMMDevReq_ReportGuestInfo2);
+    Log(("vgdrvReportGuestInfo: VbglGRAlloc VMMDevReportGuestInfo2 completed with rc=%Rrc\n", rc));
+    if (RT_SUCCESS(rc))
+    {
+        pReqInfo2->guestInfo.additionsMajor    = VBOX_VERSION_MAJOR;
+        pReqInfo2->guestInfo.additionsMinor    = VBOX_VERSION_MINOR;
+        pReqInfo2->guestInfo.additionsBuild    = VBOX_VERSION_BUILD;
+        pReqInfo2->guestInfo.additionsRevision = VBOX_SVN_REV;
+        pReqInfo2->guestInfo.additionsFeatures = 0; /* (no features defined yet) */
+        RTStrCopy(pReqInfo2->guestInfo.szName, sizeof(pReqInfo2->guestInfo.szName), VBOX_VERSION_STRING);
+
+        rc = VbglGRAlloc((VMMDevRequestHeader **)&pReqInfo1, sizeof (VMMDevReportGuestInfo), VMMDevReq_ReportGuestInfo);
+        Log(("vgdrvReportGuestInfo: VbglGRAlloc VMMDevReportGuestInfo completed with rc=%Rrc\n", rc));
+        if (RT_SUCCESS(rc))
+        {
+            pReqInfo1->guestInfo.interfaceVersion = VMMDEV_VERSION;
+            pReqInfo1->guestInfo.osType           = enmOSType;
+
+            /*
+             * There are two protocols here:
+             *      1. Info2 + Info1. Supported by >=3.2.51.
+             *      2. Info1 and optionally Info2. The old protocol.
+             *
+             * We try protocol 1 first.  It will fail with VERR_NOT_SUPPORTED
+             * if not supported by the VMMDev (message ordering requirement).
+             */
+            rc = VbglGRPerform(&pReqInfo2->header);
+            Log(("vgdrvReportGuestInfo: VbglGRPerform VMMDevReportGuestInfo2 completed with rc=%Rrc\n", rc));
+            if (RT_SUCCESS(rc))
+            {
+                rc = VbglGRPerform(&pReqInfo1->header);
+                Log(("vgdrvReportGuestInfo: VbglGRPerform VMMDevReportGuestInfo completed with rc=%Rrc\n", rc));
+            }
+            else if (   rc == VERR_NOT_SUPPORTED
+                     || rc == VERR_NOT_IMPLEMENTED)
+            {
+                rc = VbglGRPerform(&pReqInfo1->header);
+                Log(("vgdrvReportGuestInfo: VbglGRPerform VMMDevReportGuestInfo completed with rc=%Rrc\n", rc));
+                if (RT_SUCCESS(rc))
+                {
+                    rc = VbglGRPerform(&pReqInfo2->header);
+                    Log(("vgdrvReportGuestInfo: VbglGRPerform VMMDevReportGuestInfo2 completed with rc=%Rrc\n", rc));
+                    if (rc == VERR_NOT_IMPLEMENTED)
+                        rc = VINF_SUCCESS;
+                }
+            }
+            VbglGRFree(&pReqInfo1->header);
+        }
+        VbglGRFree(&pReqInfo2->header);
+    }
+
+    return rc;
+}
+
+
+/**
+ * Report the guest driver status to the host.
+ *
+ * @returns IPRT status code.
+ * @param   fActive         Flag whether the driver is now active or not.
+ */
+static int vgdrvReportDriverStatus(bool fActive)
+{
+    /*
+     * Report guest status of the VBox driver to the host.
+     */
+    VMMDevReportGuestStatus *pReq2 = NULL;
+    int rc = VbglGRAlloc((VMMDevRequestHeader **)&pReq2, sizeof(*pReq2), VMMDevReq_ReportGuestStatus);
+    Log(("vgdrvReportDriverStatus: VbglGRAlloc VMMDevReportGuestStatus completed with rc=%Rrc\n", rc));
+    if (RT_SUCCESS(rc))
+    {
+        pReq2->guestStatus.facility = VBoxGuestFacilityType_VBoxGuestDriver;
+        pReq2->guestStatus.status = fActive ?
+                                    VBoxGuestFacilityStatus_Active
+                                  : VBoxGuestFacilityStatus_Inactive;
+        pReq2->guestStatus.flags = 0;
+        rc = VbglGRPerform(&pReq2->header);
+        Log(("vgdrvReportDriverStatus: VbglGRPerform VMMDevReportGuestStatus completed with fActive=%d, rc=%Rrc\n",
+             fActive ? 1 : 0, rc));
+        if (rc == VERR_NOT_IMPLEMENTED) /* Compatibility with older hosts. */
+            rc = VINF_SUCCESS;
+        VbglGRFree(&pReq2->header);
+    }
+
+    return rc;
+}
+
+
+/** @name Memory Ballooning
+ * @{
+ */
+
+/**
+ * Inflate the balloon by one chunk represented by an R0 memory object.
+ *
+ * The caller owns the balloon mutex.
+ *
+ * @returns IPRT status code.
+ * @param   pMemObj     Pointer to the R0 memory object.
+ * @param   pReq        The pre-allocated request for performing the VMMDev call.
+ */
+static int vgdrvBalloonInflate(PRTR0MEMOBJ pMemObj, VMMDevChangeMemBalloon *pReq)
+{
+    uint32_t iPage;
+    int rc;
+
+    for (iPage = 0; iPage < VMMDEV_MEMORY_BALLOON_CHUNK_PAGES; iPage++)
+    {
+        RTHCPHYS phys = RTR0MemObjGetPagePhysAddr(*pMemObj, iPage);
+        pReq->aPhysPage[iPage] = phys;
+    }
+
+    pReq->fInflate = true;
+    pReq->header.size = g_cbChangeMemBalloonReq;
+    pReq->cPages = VMMDEV_MEMORY_BALLOON_CHUNK_PAGES;
+
+    rc = VbglGRPerform(&pReq->header);
+    if (RT_FAILURE(rc))
+        LogRel(("vgdrvBalloonInflate: VbglGRPerform failed. rc=%Rrc\n", rc));
+    return rc;
+}
+
+
+/**
+ * Deflate the balloon by one chunk - info the host and free the memory object.
+ *
+ * The caller owns the balloon mutex.
+ *
+ * @returns IPRT status code.
+ * @param   pMemObj     Pointer to the R0 memory object.
+ *                      The memory object will be freed afterwards.
+ * @param   pReq        The pre-allocated request for performing the VMMDev call.
+ */
+static int vgdrvBalloonDeflate(PRTR0MEMOBJ pMemObj, VMMDevChangeMemBalloon *pReq)
+{
+    uint32_t iPage;
+    int rc;
+
+    for (iPage = 0; iPage < VMMDEV_MEMORY_BALLOON_CHUNK_PAGES; iPage++)
+    {
+        RTHCPHYS phys = RTR0MemObjGetPagePhysAddr(*pMemObj, iPage);
+        pReq->aPhysPage[iPage] = phys;
+    }
+
+    pReq->fInflate = false;
+    pReq->header.size = g_cbChangeMemBalloonReq;
+    pReq->cPages = VMMDEV_MEMORY_BALLOON_CHUNK_PAGES;
+
+    rc = VbglGRPerform(&pReq->header);
+    if (RT_FAILURE(rc))
+    {
+        LogRel(("vgdrvBalloonDeflate: VbglGRPerform failed. rc=%Rrc\n", rc));
+        return rc;
+    }
+
+    rc = RTR0MemObjFree(*pMemObj, true);
+    if (RT_FAILURE(rc))
+    {
+        LogRel(("vgdrvBalloonDeflate: RTR0MemObjFree(%p,true) -> %Rrc; this is *BAD*!\n", *pMemObj, rc));
+        return rc;
+    }
+
+    *pMemObj = NIL_RTR0MEMOBJ;
+    return VINF_SUCCESS;
+}
+
+
+/**
+ * Inflate/deflate the memory balloon and notify the host.
+ *
+ * This is a worker used by vgdrvIoCtl_CheckMemoryBalloon - it takes the mutex.
+ *
+ * @returns VBox status code.
+ * @param   pDevExt         The device extension.
+ * @param   cBalloonChunks  The new size of the balloon in chunks of 1MB.
+ * @param   pfHandleInR3    Where to return the handle-in-ring3 indicator
+ *                          (VINF_SUCCESS if set).
+ */
+static int vgdrvSetBalloonSizeKernel(PVBOXGUESTDEVEXT pDevExt, uint32_t cBalloonChunks, uint32_t *pfHandleInR3)
+{
+    int rc = VINF_SUCCESS;
+
+    if (pDevExt->MemBalloon.fUseKernelAPI)
+    {
+        VMMDevChangeMemBalloon *pReq;
+        uint32_t i;
+
+        if (cBalloonChunks > pDevExt->MemBalloon.cMaxChunks)
+        {
+            LogRel(("vgdrvSetBalloonSizeKernel: illegal balloon size %u (max=%u)\n",
+                    cBalloonChunks, pDevExt->MemBalloon.cMaxChunks));
+            return VERR_INVALID_PARAMETER;
+        }
+
+        if (cBalloonChunks == pDevExt->MemBalloon.cMaxChunks)
+            return VINF_SUCCESS;   /* nothing to do */
+
+        if (   cBalloonChunks > pDevExt->MemBalloon.cChunks
+            && !pDevExt->MemBalloon.paMemObj)
+        {
+            pDevExt->MemBalloon.paMemObj = (PRTR0MEMOBJ)RTMemAllocZ(sizeof(RTR0MEMOBJ) * pDevExt->MemBalloon.cMaxChunks);
+            if (!pDevExt->MemBalloon.paMemObj)
+            {
+                LogRel(("vgdrvSetBalloonSizeKernel: no memory for paMemObj!\n"));
+                return VERR_NO_MEMORY;
+            }
+        }
+
+        rc = VbglGRAlloc((VMMDevRequestHeader **)&pReq, g_cbChangeMemBalloonReq, VMMDevReq_ChangeMemBalloon);
+        if (RT_FAILURE(rc))
+            return rc;
+
+        if (cBalloonChunks > pDevExt->MemBalloon.cChunks)
+        {
+            /* inflate */
+            for (i = pDevExt->MemBalloon.cChunks; i < cBalloonChunks; i++)
+            {
+                rc = RTR0MemObjAllocPhysNC(&pDevExt->MemBalloon.paMemObj[i],
+                                           VMMDEV_MEMORY_BALLOON_CHUNK_SIZE, NIL_RTHCPHYS);
+                if (RT_FAILURE(rc))
+                {
+                    if (rc == VERR_NOT_SUPPORTED)
+                    {
+                        /* not supported -- fall back to the R3-allocated memory. */
+                        rc = VINF_SUCCESS;
+                        pDevExt->MemBalloon.fUseKernelAPI = false;
+                        Assert(pDevExt->MemBalloon.cChunks == 0);
+                        Log(("VBoxGuestSetBalloonSizeKernel: PhysNC allocs not supported, falling back to R3 allocs.\n"));
+                    }
+                    /* else if (rc == VERR_NO_MEMORY || rc == VERR_NO_PHYS_MEMORY):
+                     *      cannot allocate more memory => don't try further, just stop here */
+                    /* else: XXX what else can fail?  VERR_MEMOBJ_INIT_FAILED for instance. just stop. */
+                    break;
+                }
+
+                rc = vgdrvBalloonInflate(&pDevExt->MemBalloon.paMemObj[i], pReq);
+                if (RT_FAILURE(rc))
+                {
+                    Log(("vboxGuestSetBalloonSize(inflate): failed, rc=%Rrc!\n", rc));
+                    RTR0MemObjFree(pDevExt->MemBalloon.paMemObj[i], true);
+                    pDevExt->MemBalloon.paMemObj[i] = NIL_RTR0MEMOBJ;
+                    break;
+                }
+                pDevExt->MemBalloon.cChunks++;
+            }
+        }
+        else
+        {
+            /* deflate */
+            for (i = pDevExt->MemBalloon.cChunks; i-- > cBalloonChunks;)
+            {
+                rc = vgdrvBalloonDeflate(&pDevExt->MemBalloon.paMemObj[i], pReq);
+                if (RT_FAILURE(rc))
+                {
+                    Log(("vboxGuestSetBalloonSize(deflate): failed, rc=%Rrc!\n", rc));
+                    break;
+                }
+                pDevExt->MemBalloon.cChunks--;
+            }
+        }
+
+        VbglGRFree(&pReq->header);
+    }
+
+    /*
+     * Set the handle-in-ring3 indicator.  When set Ring-3 will have to work
+     * the balloon changes via the other API.
+     */
+    *pfHandleInR3 = pDevExt->MemBalloon.fUseKernelAPI ? false : true;
+
+    return rc;
+}
+
+
+/**
+ * Inflate/deflate the balloon by one chunk.
+ *
+ * Worker for vgdrvIoCtl_ChangeMemoryBalloon - it takes the mutex.
+ *
+ * @returns VBox status code.
+ * @param   pDevExt         The device extension.
+ * @param   pSession        The session.
+ * @param   u64ChunkAddr    The address of the chunk to add to / remove from the
+ *                          balloon.
+ * @param   fInflate        Inflate if true, deflate if false.
+ */
+static int vgdrvSetBalloonSizeFromUser(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION pSession, uint64_t u64ChunkAddr, bool fInflate)
+{
+    VMMDevChangeMemBalloon *pReq;
+    int rc = VINF_SUCCESS;
+    uint32_t i;
+    PRTR0MEMOBJ pMemObj = NULL;
+
+    if (fInflate)
+    {
+        if (   pDevExt->MemBalloon.cChunks > pDevExt->MemBalloon.cMaxChunks - 1
+            || pDevExt->MemBalloon.cMaxChunks == 0 /* If called without first querying. */)
+        {
+            LogRel(("vboxGuestSetBalloonSize: cannot inflate balloon, already have %u chunks (max=%u)\n",
+                    pDevExt->MemBalloon.cChunks, pDevExt->MemBalloon.cMaxChunks));
+            return VERR_INVALID_PARAMETER;
+        }
+
+        if (!pDevExt->MemBalloon.paMemObj)
+        {
+            pDevExt->MemBalloon.paMemObj = (PRTR0MEMOBJ)RTMemAlloc(sizeof(RTR0MEMOBJ) * pDevExt->MemBalloon.cMaxChunks);
+            if (!pDevExt->MemBalloon.paMemObj)
+            {
+                LogRel(("VBoxGuestSetBalloonSizeFromUser: no memory for paMemObj!\n"));
+                return VERR_NO_MEMORY;
+            }
+            for (i = 0; i < pDevExt->MemBalloon.cMaxChunks; i++)
+                pDevExt->MemBalloon.paMemObj[i] = NIL_RTR0MEMOBJ;
+        }
+    }
+    else
+    {
+        if (pDevExt->MemBalloon.cChunks == 0)
+        {
+            AssertMsgFailed(("vboxGuestSetBalloonSize: cannot decrease balloon, already at size 0\n"));
+            return VERR_INVALID_PARAMETER;
+        }
+    }
+
+    /*
+     * Enumerate all memory objects and check if the object is already registered.
+     */
+    for (i = 0; i < pDevExt->MemBalloon.cMaxChunks; i++)
+    {
+        if (   fInflate
+            && !pMemObj
+            && pDevExt->MemBalloon.paMemObj[i] == NIL_RTR0MEMOBJ)
+            pMemObj = &pDevExt->MemBalloon.paMemObj[i]; /* found free object pointer */
+        if (RTR0MemObjAddressR3(pDevExt->MemBalloon.paMemObj[i]) == u64ChunkAddr)
+        {
+            if (fInflate)
+                return VERR_ALREADY_EXISTS; /* don't provide the same memory twice */
+            pMemObj = &pDevExt->MemBalloon.paMemObj[i];
+            break;
+        }
+    }
+    if (!pMemObj)
+    {
+        if (fInflate)
+        {
+            /* no free object pointer found -- should not happen */
+            return VERR_NO_MEMORY;
+        }
+
+        /* cannot free this memory as it wasn't provided before */
+        return VERR_NOT_FOUND;
+    }
+
+    /*
+     * Try inflate / default the balloon as requested.
+     */
+    rc = VbglGRAlloc((VMMDevRequestHeader **)&pReq, g_cbChangeMemBalloonReq, VMMDevReq_ChangeMemBalloon);
+    if (RT_FAILURE(rc))
+        return rc;
+
+    if (fInflate)
+    {
+        rc = RTR0MemObjLockUser(pMemObj, (RTR3PTR)u64ChunkAddr, VMMDEV_MEMORY_BALLOON_CHUNK_SIZE,
+                                RTMEM_PROT_READ | RTMEM_PROT_WRITE, NIL_RTR0PROCESS);
+        if (RT_SUCCESS(rc))
+        {
+            rc = vgdrvBalloonInflate(pMemObj, pReq);
+            if (RT_SUCCESS(rc))
+                pDevExt->MemBalloon.cChunks++;
+            else
+            {
+                Log(("vboxGuestSetBalloonSize(inflate): failed, rc=%Rrc!\n", rc));
+                RTR0MemObjFree(*pMemObj, true);
+                *pMemObj = NIL_RTR0MEMOBJ;
+            }
+        }
+    }
+    else
+    {
+        rc = vgdrvBalloonDeflate(pMemObj, pReq);
+        if (RT_SUCCESS(rc))
+            pDevExt->MemBalloon.cChunks--;
+        else
+            Log(("vboxGuestSetBalloonSize(deflate): failed, rc=%Rrc!\n", rc));
+    }
+
+    VbglGRFree(&pReq->header);
+    return rc;
+}
+
+
+/**
+ * Cleanup the memory balloon of a session.
+ *
+ * Will request the balloon mutex, so it must be valid and the caller must not
+ * own it already.
+ *
+ * @param   pDevExt     The device extension.
+ * @param   pSession    The session.  Can be NULL at unload.
+ */
+static void vgdrvCloseMemBalloon(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION pSession)
+{
+    RTSemFastMutexRequest(pDevExt->MemBalloon.hMtx);
+    if (    pDevExt->MemBalloon.pOwner == pSession
+        ||  pSession == NULL /*unload*/)
+    {
+        if (pDevExt->MemBalloon.paMemObj)
+        {
+            VMMDevChangeMemBalloon *pReq;
+            int rc = VbglGRAlloc((VMMDevRequestHeader **)&pReq, g_cbChangeMemBalloonReq, VMMDevReq_ChangeMemBalloon);
+            if (RT_SUCCESS(rc))
+            {
+                uint32_t i;
+                for (i = pDevExt->MemBalloon.cChunks; i-- > 0;)
+                {
+                    rc = vgdrvBalloonDeflate(&pDevExt->MemBalloon.paMemObj[i], pReq);
+                    if (RT_FAILURE(rc))
+                    {
+                        LogRel(("vgdrvCloseMemBalloon: Deflate failed with rc=%Rrc.  Will leak %u chunks.\n",
+                                rc, pDevExt->MemBalloon.cChunks));
+                        break;
+                    }
+                    pDevExt->MemBalloon.paMemObj[i] = NIL_RTR0MEMOBJ;
+                    pDevExt->MemBalloon.cChunks--;
+                }
+                VbglGRFree(&pReq->header);
+            }
+            else
+                LogRel(("vgdrvCloseMemBalloon: Failed to allocate VMMDev request buffer (rc=%Rrc).  Will leak %u chunks.\n",
+                        rc, pDevExt->MemBalloon.cChunks));
+            RTMemFree(pDevExt->MemBalloon.paMemObj);
+            pDevExt->MemBalloon.paMemObj = NULL;
+        }
+
+        pDevExt->MemBalloon.pOwner = NULL;
+    }
+    RTSemFastMutexRelease(pDevExt->MemBalloon.hMtx);
+}
+
+/** @} */
+
+
+
+/** @name Heartbeat
+ * @{
+ */
+
+/**
+ * Sends heartbeat to host.
+ *
+ * @returns VBox status code.
+ */
+static int vgdrvHeartbeatSend(PVBOXGUESTDEVEXT pDevExt)
+{
+    int rc;
+    if (pDevExt->pReqGuestHeartbeat)
+    {
+        rc = VbglGRPerform(pDevExt->pReqGuestHeartbeat);
+        Log(("vgdrvHeartbeatSend: VbglGRPerform vgdrvHeartbeatSend completed with rc=%Rrc\n", rc));
+    }
+    else
+        rc = VERR_INVALID_STATE;
+    return rc;
+}
+
+
+/**
+ * Callback for heartbeat timer.
+ */
+static DECLCALLBACK(void) vgdrvHeartbeatTimerHandler(PRTTIMER hTimer, void *pvUser, uint64_t iTick)
+{
+    PVBOXGUESTDEVEXT pDevExt = (PVBOXGUESTDEVEXT)pvUser;
+    int rc;
+    AssertReturnVoid(pDevExt);
+
+    rc = vgdrvHeartbeatSend(pDevExt);
+    if (RT_FAILURE(rc))
+        Log(("HB Timer: vgdrvHeartbeatSend failed: rc=%Rrc\n", rc));
+
+    NOREF(hTimer); NOREF(iTick);
+}
+
+
+/**
+ * Configure the host to check guest's heartbeat
+ * and get heartbeat interval from the host.
+ *
+ * @returns VBox status code.
+ * @param   pDevExt         The device extension.
+ * @param   fEnabled        Set true to enable guest heartbeat checks on host.
+ */
+static int vgdrvHeartbeatHostConfigure(PVBOXGUESTDEVEXT pDevExt, bool fEnabled)
+{
+    VMMDevReqHeartbeat *pReq;
+    int rc = VbglGRAlloc((VMMDevRequestHeader **)&pReq, sizeof(*pReq), VMMDevReq_HeartbeatConfigure);
+    Log(("vgdrvHeartbeatHostConfigure: VbglGRAlloc vgdrvHeartbeatHostConfigure completed with rc=%Rrc\n", rc));
+    if (RT_SUCCESS(rc))
+    {
+        pReq->fEnabled = fEnabled;
+        pReq->cNsInterval = 0;
+        rc = VbglGRPerform(&pReq->header);
+        Log(("vgdrvHeartbeatHostConfigure: VbglGRPerform vgdrvHeartbeatHostConfigure completed with rc=%Rrc\n", rc));
+        pDevExt->cNsHeartbeatInterval = pReq->cNsInterval;
+        VbglGRFree(&pReq->header);
+    }
+    return rc;
+}
+
+
+/**
+ * Initializes the heartbeat timer.
+ *
+ * This feature may be disabled by the host.
+ *
+ * @returns VBox status (ignored).
+ * @param   pDevExt             The device extension.
+ */
+static int vgdrvHeartbeatInit(PVBOXGUESTDEVEXT pDevExt)
+{
+    /*
+     * Make sure that heartbeat checking is disabled.
+     */
+    int rc = vgdrvHeartbeatHostConfigure(pDevExt, false);
+    if (RT_SUCCESS(rc))
+    {
+        rc = vgdrvHeartbeatHostConfigure(pDevExt, true);
+        if (RT_SUCCESS(rc))
+        {
+            /*
+             * Preallocate the request to use it from the timer callback because:
+             *    1) on Windows VbglGRAlloc must be called at IRQL <= APC_LEVEL
+             *       and the timer callback runs at DISPATCH_LEVEL;
+             *    2) avoid repeated allocations.
+             */
+            rc = VbglGRAlloc(&pDevExt->pReqGuestHeartbeat, sizeof(*pDevExt->pReqGuestHeartbeat), VMMDevReq_GuestHeartbeat);
+            if (RT_SUCCESS(rc))
+            {
+                LogRel(("vgdrvHeartbeatInit: Setting up heartbeat to trigger every %RU64 milliseconds\n",
+                        pDevExt->cNsHeartbeatInterval / RT_NS_1MS));
+                rc = RTTimerCreateEx(&pDevExt->pHeartbeatTimer, pDevExt->cNsHeartbeatInterval, 0 /*fFlags*/,
+                                     (PFNRTTIMER)vgdrvHeartbeatTimerHandler, pDevExt);
+                if (RT_SUCCESS(rc))
+                {
+                    rc = RTTimerStart(pDevExt->pHeartbeatTimer, 0);
+                    if (RT_SUCCESS(rc))
+                        return VINF_SUCCESS;
+
+                    LogRel(("vgdrvHeartbeatInit: Heartbeat timer failed to start, rc=%Rrc\n", rc));
+                }
+                else
+                    LogRel(("vgdrvHeartbeatInit: Failed to create heartbeat timer: %Rrc\n", rc));
+
+                VbglGRFree(pDevExt->pReqGuestHeartbeat);
+                pDevExt->pReqGuestHeartbeat = NULL;
+            }
+            else
+                LogRel(("vgdrvHeartbeatInit: VbglGRAlloc(VMMDevReq_GuestHeartbeat): %Rrc\n", rc));
+
+            LogRel(("vgdrvHeartbeatInit: Failed to set up the timer, guest heartbeat is disabled\n"));
+            vgdrvHeartbeatHostConfigure(pDevExt, false);
+        }
+        else
+            LogRel(("vgdrvHeartbeatInit: Failed to configure host for heartbeat checking: rc=%Rrc\n", rc));
+    }
+    return rc;
+}
+
+/** @} */
+
+
+/**
+ * Helper to reinit the VMMDev communication after hibernation.
+ *
+ * @returns VBox status code.
+ * @param   pDevExt         The device extension.
+ * @param   enmOSType       The OS type.
+ *
+ * @todo Call this on all platforms, not just windows.
+ */
+int VGDrvCommonReinitDevExtAfterHibernation(PVBOXGUESTDEVEXT pDevExt, VBOXOSTYPE enmOSType)
+{
+    int rc = vgdrvReportGuestInfo(enmOSType);
+    if (RT_SUCCESS(rc))
+    {
+        rc = vgdrvReportDriverStatus(true /* Driver is active */);
+        if (RT_FAILURE(rc))
+            Log(("VGDrvCommonReinitDevExtAfterHibernation: could not report guest driver status, rc=%Rrc\n", rc));
+    }
+    else
+        Log(("VGDrvCommonReinitDevExtAfterHibernation: could not report guest information to host, rc=%Rrc\n", rc));
+    LogFlow(("VGDrvCommonReinitDevExtAfterHibernation: returned with rc=%Rrc\n", rc));
+    return rc;
+}
+
+
+/**
+ * Initializes the VBoxGuest device extension when the
+ * device driver is loaded.
+ *
+ * The native code locates the VMMDev on the PCI bus and retrieve
+ * the MMIO and I/O port ranges, this function will take care of
+ * mapping the MMIO memory (if present). Upon successful return
+ * the native code should set up the interrupt handler.
+ *
+ * @returns VBox status code.
+ *
+ * @param   pDevExt         The device extension. Allocated by the native code.
+ * @param   IOPortBase      The base of the I/O port range.
+ * @param   pvMMIOBase      The base of the MMIO memory mapping.
+ *                          This is optional, pass NULL if not present.
+ * @param   cbMMIO          The size of the MMIO memory mapping.
+ *                          This is optional, pass 0 if not present.
+ * @param   enmOSType       The guest OS type to report to the VMMDev.
+ * @param   fFixedEvents    Events that will be enabled upon init and no client
+ *                          will ever be allowed to mask.
+ */
+int VGDrvCommonInitDevExt(PVBOXGUESTDEVEXT pDevExt, uint16_t IOPortBase,
+                          void *pvMMIOBase, uint32_t cbMMIO, VBOXOSTYPE enmOSType, uint32_t fFixedEvents)
+{
+    int rc, rc2;
+
+#ifdef VBOX_GUESTDRV_WITH_RELEASE_LOGGER
+    /*
+     * Create the release log.
+     */
+    static const char * const s_apszGroups[] = VBOX_LOGGROUP_NAMES;
+    PRTLOGGER pRelLogger;
+    rc = RTLogCreate(&pRelLogger, 0 /*fFlags*/, "all", "VBOXGUEST_RELEASE_LOG", RT_ELEMENTS(s_apszGroups), s_apszGroups,
+                     RTLOGDEST_STDOUT | RTLOGDEST_DEBUGGER, NULL);
+    if (RT_SUCCESS(rc))
+        RTLogRelSetDefaultInstance(pRelLogger);
+    /** @todo Add native hook for getting logger config parameters and setting
+     *        them.  On linux we should use the module parameter stuff... */
+#endif
+
+    /*
+     * Adjust fFixedEvents.
+     */
+#ifdef VBOX_WITH_HGCM
+    fFixedEvents |= VMMDEV_EVENT_HGCM;
+#endif
+
+    /*
+     * Initialize the data.
+     */
+    pDevExt->IOPortBase = IOPortBase;
+    pDevExt->pVMMDevMemory = NULL;
+    pDevExt->hGuestMappings = NIL_RTR0MEMOBJ;
+    pDevExt->EventSpinlock = NIL_RTSPINLOCK;
+    pDevExt->pIrqAckEvents = NULL;
+    pDevExt->PhysIrqAckEvents = NIL_RTCCPHYS;
+    RTListInit(&pDevExt->WaitList);
+#ifdef VBOX_WITH_HGCM
+    RTListInit(&pDevExt->HGCMWaitList);
+#endif
+#ifdef VBOXGUEST_USE_DEFERRED_WAKE_UP
+    RTListInit(&pDevExt->WakeUpList);
+#endif
+    RTListInit(&pDevExt->WokenUpList);
+    RTListInit(&pDevExt->FreeList);
+    RTListInit(&pDevExt->SessionList);
+    pDevExt->cSessions = 0;
+    pDevExt->fLoggingEnabled = false;
+    pDevExt->f32PendingEvents = 0;
+    pDevExt->u32MousePosChangedSeq = 0;
+    pDevExt->SessionSpinlock = NIL_RTSPINLOCK;
+    pDevExt->MemBalloon.hMtx = NIL_RTSEMFASTMUTEX;
+    pDevExt->MemBalloon.cChunks = 0;
+    pDevExt->MemBalloon.cMaxChunks = 0;
+    pDevExt->MemBalloon.fUseKernelAPI = true;
+    pDevExt->MemBalloon.paMemObj = NULL;
+    pDevExt->MemBalloon.pOwner = NULL;
+    pDevExt->MouseNotifyCallback.pfnNotify = NULL;
+    pDevExt->MouseNotifyCallback.pvUser = NULL;
+    pDevExt->pReqGuestHeartbeat = NULL;
+
+    pDevExt->fFixedEvents = fFixedEvents;
+    vgdrvBitUsageTrackerClear(&pDevExt->EventFilterTracker);
+    pDevExt->fEventFilterHost = UINT32_MAX;  /* forces a report */
+
+    vgdrvBitUsageTrackerClear(&pDevExt->MouseStatusTracker);
+    pDevExt->fMouseStatusHost = UINT32_MAX;  /* forces a report */
+
+    pDevExt->fAcquireModeGuestCaps = 0;
+    pDevExt->fSetModeGuestCaps = 0;
+    pDevExt->fAcquiredGuestCaps = 0;
+    vgdrvBitUsageTrackerClear(&pDevExt->SetGuestCapsTracker);
+    pDevExt->fGuestCapsHost = UINT32_MAX; /* forces a report */
+
+    /*
+     * If there is an MMIO region validate the version and size.
+     */
+    if (pvMMIOBase)
+    {
+        VMMDevMemory *pVMMDev = (VMMDevMemory *)pvMMIOBase;
+        Assert(cbMMIO);
+        if (    pVMMDev->u32Version == VMMDEV_MEMORY_VERSION
+            &&  pVMMDev->u32Size >= 32
+            &&  pVMMDev->u32Size <= cbMMIO)
+        {
+            pDevExt->pVMMDevMemory = pVMMDev;
+            Log(("VGDrvCommonInitDevExt: VMMDevMemory: mapping=%p size=%#RX32 (%#RX32) version=%#RX32\n",
+                 pVMMDev, pVMMDev->u32Size, cbMMIO, pVMMDev->u32Version));
+        }
+        else /* try live without it. */
+            LogRel(("VGDrvCommonInitDevExt: Bogus VMMDev memory; u32Version=%RX32 (expected %RX32) u32Size=%RX32 (expected <= %RX32)\n",
+                    pVMMDev->u32Version, VMMDEV_MEMORY_VERSION, pVMMDev->u32Size, cbMMIO));
+    }
+
+    /*
+     * Create the wait and session spinlocks as well as the ballooning mutex.
+     */
+    rc = RTSpinlockCreate(&pDevExt->EventSpinlock, RTSPINLOCK_FLAGS_INTERRUPT_SAFE, "VBoxGuestEvent");
+    if (RT_SUCCESS(rc))
+        rc = RTSpinlockCreate(&pDevExt->SessionSpinlock, RTSPINLOCK_FLAGS_INTERRUPT_SAFE, "VBoxGuestSession");
+    if (RT_FAILURE(rc))
+    {
+        LogRel(("VGDrvCommonInitDevExt: failed to create spinlock, rc=%Rrc!\n", rc));
+        if (pDevExt->EventSpinlock != NIL_RTSPINLOCK)
+            RTSpinlockDestroy(pDevExt->EventSpinlock);
+        return rc;
+    }
+
+    rc = RTSemFastMutexCreate(&pDevExt->MemBalloon.hMtx);
+    if (RT_FAILURE(rc))
+    {
+        LogRel(("VGDrvCommonInitDevExt: failed to create mutex, rc=%Rrc!\n", rc));
+        RTSpinlockDestroy(pDevExt->SessionSpinlock);
+        RTSpinlockDestroy(pDevExt->EventSpinlock);
+        return rc;
+    }
+
+    /*
+     * Initialize the guest library and report the guest info back to VMMDev,
+     * set the interrupt control filter mask, and fixate the guest mappings
+     * made by the VMM.
+     */
+    rc = VbglInitPrimary(pDevExt->IOPortBase, (VMMDevMemory *)pDevExt->pVMMDevMemory);
+    if (RT_SUCCESS(rc))
+    {
+        rc = VbglGRAlloc((VMMDevRequestHeader **)&pDevExt->pIrqAckEvents, sizeof(VMMDevEvents), VMMDevReq_AcknowledgeEvents);
+        if (RT_SUCCESS(rc))
+        {
+            pDevExt->PhysIrqAckEvents = VbglPhysHeapGetPhysAddr(pDevExt->pIrqAckEvents);
+            Assert(pDevExt->PhysIrqAckEvents != 0);
+
+            rc = vgdrvReportGuestInfo(enmOSType);
+            if (RT_SUCCESS(rc))
+            {
+                /*
+                 * Set the fixed event and make sure the host doesn't have any lingering
+                 * the guest capabilities or mouse status bits set.
+                 */
+                rc = vgdrvResetEventFilterOnHost(pDevExt, pDevExt->fFixedEvents);
+                if (RT_SUCCESS(rc))
+                {
+                    rc = vgdrvResetCapabilitiesOnHost(pDevExt);
+                    if (RT_SUCCESS(rc))
+                    {
+                        rc = vgdrvResetMouseStatusOnHost(pDevExt);
+                        if (RT_SUCCESS(rc))
+                        {
+                            /*
+                             * Initialize stuff which may fail without requiring the driver init to fail.
+                             */
+                            vgdrvInitFixateGuestMappings(pDevExt);
+                            vgdrvHeartbeatInit(pDevExt);
+
+                            /*
+                             * Done!
+                             */
+                            rc = vgdrvReportDriverStatus(true /* Driver is active */);
+                            if (RT_FAILURE(rc))
+                                LogRel(("VGDrvCommonInitDevExt: VBoxReportGuestDriverStatus failed, rc=%Rrc\n", rc));
+
+                            LogFlowFunc(("VGDrvCommonInitDevExt: returns success\n"));
+                            return VINF_SUCCESS;
+                        }
+                        LogRel(("VGDrvCommonInitDevExt: failed to clear mouse status: rc=%Rrc\n", rc));
+                    }
+                    else
+                        LogRel(("VGDrvCommonInitDevExt: failed to clear guest capabilities: rc=%Rrc\n", rc));
+                }
+                else
+                    LogRel(("VGDrvCommonInitDevExt: failed to set fixed event filter: rc=%Rrc\n", rc));
+            }
+            else
+                LogRel(("VGDrvCommonInitDevExt: VBoxReportGuestInfo failed: rc=%Rrc\n", rc));
+            VbglGRFree((VMMDevRequestHeader *)pDevExt->pIrqAckEvents);
+        }
+        else
+            LogRel(("VGDrvCommonInitDevExt: VBoxGRAlloc failed: rc=%Rrc\n", rc));
+
+        VbglTerminate();
+    }
+    else
+        LogRel(("VGDrvCommonInitDevExt: VbglInit failed: rc=%Rrc\n", rc));
+
+    rc2 = RTSemFastMutexDestroy(pDevExt->MemBalloon.hMtx); AssertRC(rc2);
+    rc2 = RTSpinlockDestroy(pDevExt->EventSpinlock); AssertRC(rc2);
+    rc2 = RTSpinlockDestroy(pDevExt->SessionSpinlock); AssertRC(rc2);
+
+#ifdef VBOX_GUESTDRV_WITH_RELEASE_LOGGER
+    RTLogDestroy(RTLogRelSetDefaultInstance(NULL));
+    RTLogDestroy(RTLogSetDefaultInstance(NULL));
+#endif
+    return rc; /* (failed) */
+}
+
+
+/**
+ * Deletes all the items in a wait chain.
+ * @param   pList       The head of the chain.
+ */
+static void vgdrvDeleteWaitList(PRTLISTNODE pList)
+{
+    while (!RTListIsEmpty(pList))
+    {
+        int             rc2;
+        PVBOXGUESTWAIT  pWait = RTListGetFirst(pList, VBOXGUESTWAIT, ListNode);
+        RTListNodeRemove(&pWait->ListNode);
+
+        rc2 = RTSemEventMultiDestroy(pWait->Event); AssertRC(rc2);
+        pWait->Event = NIL_RTSEMEVENTMULTI;
+        pWait->pSession = NULL;
+        RTMemFree(pWait);
+    }
+}
+
+
+/**
+ * Destroys the VBoxGuest device extension.
+ *
+ * The native code should call this before the driver is loaded,
+ * but don't call this on shutdown.
+ *
+ * @param   pDevExt         The device extension.
+ */
+void VGDrvCommonDeleteDevExt(PVBOXGUESTDEVEXT pDevExt)
+{
+    int rc2;
+    Log(("VGDrvCommonDeleteDevExt:\n"));
+    Log(("VBoxGuest: The additions driver is terminating.\n"));
+
+    /*
+     * Stop and destroy HB timer and
+     * disable host heartbeat checking.
+     */
+    if (pDevExt->pHeartbeatTimer)
+    {
+        RTTimerDestroy(pDevExt->pHeartbeatTimer);
+        vgdrvHeartbeatHostConfigure(pDevExt, false);
+    }
+
+    VbglGRFree(pDevExt->pReqGuestHeartbeat);
+    pDevExt->pReqGuestHeartbeat = NULL;
+
+    /*
+     * Clean up the bits that involves the host first.
+     */
+    vgdrvTermUnfixGuestMappings(pDevExt);
+    if (!RTListIsEmpty(&pDevExt->SessionList))
+    {
+        LogRelFunc(("session list not empty!\n"));
+        RTListInit(&pDevExt->SessionList);
+    }
+    /* Update the host flags (mouse status etc) not to reflect this session. */
+    pDevExt->fFixedEvents = 0;
+    vgdrvResetEventFilterOnHost(pDevExt, 0 /*fFixedEvents*/);
+    vgdrvResetCapabilitiesOnHost(pDevExt);
+    vgdrvResetMouseStatusOnHost(pDevExt);
+
+    vgdrvCloseMemBalloon(pDevExt, (PVBOXGUESTSESSION)NULL);
+
+    /*
+     * Cleanup all the other resources.
+     */
+    rc2 = RTSpinlockDestroy(pDevExt->EventSpinlock); AssertRC(rc2);
+    rc2 = RTSpinlockDestroy(pDevExt->SessionSpinlock); AssertRC(rc2);
+    rc2 = RTSemFastMutexDestroy(pDevExt->MemBalloon.hMtx); AssertRC(rc2);
+
+    vgdrvDeleteWaitList(&pDevExt->WaitList);
+#ifdef VBOX_WITH_HGCM
+    vgdrvDeleteWaitList(&pDevExt->HGCMWaitList);
+#endif
+#ifdef VBOXGUEST_USE_DEFERRED_WAKE_UP
+    vgdrvDeleteWaitList(&pDevExt->WakeUpList);
+#endif
+    vgdrvDeleteWaitList(&pDevExt->WokenUpList);
+    vgdrvDeleteWaitList(&pDevExt->FreeList);
+
+    VbglTerminate();
+
+    pDevExt->pVMMDevMemory = NULL;
+
+    pDevExt->IOPortBase = 0;
+    pDevExt->pIrqAckEvents = NULL;
+
+#ifdef VBOX_GUESTDRV_WITH_RELEASE_LOGGER
+    RTLogDestroy(RTLogRelSetDefaultInstance(NULL));
+    RTLogDestroy(RTLogSetDefaultInstance(NULL));
+#endif
+
+}
+
+
+/**
+ * Creates a VBoxGuest user session.
+ *
+ * The native code calls this when a ring-3 client opens the device.
+ * Use VGDrvCommonCreateKernelSession when a ring-0 client connects.
+ *
+ * @returns VBox status code.
+ * @param   pDevExt         The device extension.
+ * @param   ppSession       Where to store the session on success.
+ */
+int VGDrvCommonCreateUserSession(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION *ppSession)
+{
+    PVBOXGUESTSESSION pSession = (PVBOXGUESTSESSION)RTMemAllocZ(sizeof(*pSession));
+    if (RT_UNLIKELY(!pSession))
+    {
+        LogRel(("VGDrvCommonCreateUserSession: no memory!\n"));
+        return VERR_NO_MEMORY;
+    }
+
+    pSession->Process = RTProcSelf();
+    pSession->R0Process = RTR0ProcHandleSelf();
+    pSession->pDevExt = pDevExt;
+    RTSpinlockAcquire(pDevExt->SessionSpinlock);
+    RTListAppend(&pDevExt->SessionList, &pSession->ListNode);
+    pDevExt->cSessions++;
+    RTSpinlockRelease(pDevExt->SessionSpinlock);
+
+    *ppSession = pSession;
+    LogFlow(("VGDrvCommonCreateUserSession: pSession=%p proc=%RTproc (%d) r0proc=%p\n",
+             pSession, pSession->Process, (int)pSession->Process, (uintptr_t)pSession->R0Process)); /** @todo %RTr0proc */
+    return VINF_SUCCESS;
+}
+
+
+/**
+ * Creates a VBoxGuest kernel session.
+ *
+ * The native code calls this when a ring-0 client connects to the device.
+ * Use VGDrvCommonCreateUserSession when a ring-3 client opens the device.
+ *
+ * @returns VBox status code.
+ * @param   pDevExt         The device extension.
+ * @param   ppSession       Where to store the session on success.
+ */
+int VGDrvCommonCreateKernelSession(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION *ppSession)
+{
+    PVBOXGUESTSESSION pSession = (PVBOXGUESTSESSION)RTMemAllocZ(sizeof(*pSession));
+    if (RT_UNLIKELY(!pSession))
+    {
+        LogRel(("VGDrvCommonCreateKernelSession: no memory!\n"));
+        return VERR_NO_MEMORY;
+    }
+
+    pSession->Process = NIL_RTPROCESS;
+    pSession->R0Process = NIL_RTR0PROCESS;
+    pSession->pDevExt = pDevExt;
+    RTSpinlockAcquire(pDevExt->SessionSpinlock);
+    RTListAppend(&pDevExt->SessionList, &pSession->ListNode);
+    pDevExt->cSessions++;
+    RTSpinlockRelease(pDevExt->SessionSpinlock);
+
+    *ppSession = pSession;
+    LogFlow(("VGDrvCommonCreateKernelSession: pSession=%p proc=%RTproc (%d) r0proc=%p\n",
+             pSession, pSession->Process, (int)pSession->Process, (uintptr_t)pSession->R0Process)); /** @todo %RTr0proc */
+    return VINF_SUCCESS;
+}
+
+
+/**
+ * Closes a VBoxGuest session.
+ *
+ * @param   pDevExt         The device extension.
+ * @param   pSession        The session to close (and free).
+ */
+void VGDrvCommonCloseSession(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION pSession)
+{
+#ifdef VBOX_WITH_HGCM
+    unsigned i;
+#endif
+    LogFlow(("VGDrvCommonCloseSession: pSession=%p proc=%RTproc (%d) r0proc=%p\n",
+             pSession, pSession->Process, (int)pSession->Process, (uintptr_t)pSession->R0Process)); /** @todo %RTr0proc */
+
+    RTSpinlockAcquire(pDevExt->SessionSpinlock);
+    RTListNodeRemove(&pSession->ListNode);
+    pDevExt->cSessions--;
+    RTSpinlockRelease(pDevExt->SessionSpinlock);
+    vgdrvAcquireSessionCapabilities(pDevExt, pSession, 0, UINT32_MAX, VBOXGUESTCAPSACQUIRE_FLAGS_NONE,
+                                   true /*fSessionTermination*/);
+    vgdrvSetSessionCapabilities(pDevExt, pSession, 0 /*fOrMask*/, UINT32_MAX /*fNotMask*/, true /*fSessionTermination*/);
+    vgdrvSetSessionEventFilter(pDevExt, pSession, 0 /*fOrMask*/, UINT32_MAX /*fNotMask*/, true /*fSessionTermination*/);
+    vgdrvSetSessionMouseStatus(pDevExt, pSession, 0 /*fOrMask*/, UINT32_MAX /*fNotMask*/, true /*fSessionTermination*/);
+
+    vgdrvIoCtl_CancelAllWaitEvents(pDevExt, pSession);
+
+#ifdef VBOX_WITH_HGCM
+    for (i = 0; i < RT_ELEMENTS(pSession->aHGCMClientIds); i++)
+        if (pSession->aHGCMClientIds[i])
+        {
+            VBoxGuestHGCMDisconnectInfo Info;
+            Info.result = 0;
+            Info.u32ClientID = pSession->aHGCMClientIds[i];
+            pSession->aHGCMClientIds[i] = 0;
+            Log(("VGDrvCommonCloseSession: disconnecting client id %#RX32\n", Info.u32ClientID));
+            VbglR0HGCMInternalDisconnect(&Info, vgdrvHgcmAsyncWaitCallback, pDevExt, RT_INDEFINITE_WAIT);
+        }
+#endif
+
+    pSession->pDevExt = NULL;
+    pSession->Process = NIL_RTPROCESS;
+    pSession->R0Process = NIL_RTR0PROCESS;
+    vgdrvCloseMemBalloon(pDevExt, pSession);
+    RTMemFree(pSession);
+}
+
+
+/**
+ * Allocates a wait-for-event entry.
+ *
+ * @returns The wait-for-event entry.
+ * @param   pDevExt         The device extension.
+ * @param   pSession        The session that's allocating this. Can be NULL.
+ */
+static PVBOXGUESTWAIT vgdrvWaitAlloc(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION pSession)
+{
+    /*
+     * Allocate it one way or the other.
+     */
+    PVBOXGUESTWAIT pWait = RTListGetFirst(&pDevExt->FreeList, VBOXGUESTWAIT, ListNode);
+    if (pWait)
+    {
+        RTSpinlockAcquire(pDevExt->EventSpinlock);
+
+        pWait = RTListGetFirst(&pDevExt->FreeList, VBOXGUESTWAIT, ListNode);
+        if (pWait)
+            RTListNodeRemove(&pWait->ListNode);
+
+        RTSpinlockRelease(pDevExt->EventSpinlock);
+    }
+    if (!pWait)
+    {
+        int rc;
+
+        pWait = (PVBOXGUESTWAIT)RTMemAlloc(sizeof(*pWait));
+        if (!pWait)
+        {
+            LogRelMax(32, ("vgdrvWaitAlloc: out-of-memory!\n"));
+            return NULL;
+        }
+
+        rc = RTSemEventMultiCreate(&pWait->Event);
+        if (RT_FAILURE(rc))
+        {
+            LogRelMax(32, ("vgdrvWaitAlloc: RTSemEventMultiCreate failed with rc=%Rrc!\n", rc));
+            RTMemFree(pWait);
+            return NULL;
+        }
+
+        pWait->ListNode.pNext = NULL;
+        pWait->ListNode.pPrev = NULL;
+    }
+
+    /*
+     * Zero members just as an precaution.
+     */
+    pWait->fReqEvents = 0;
+    pWait->fResEvents = 0;
+#ifdef VBOXGUEST_USE_DEFERRED_WAKE_UP
+    pWait->fPendingWakeUp = false;
+    pWait->fFreeMe = false;
+#endif
+    pWait->pSession = pSession;
+#ifdef VBOX_WITH_HGCM
+    pWait->pHGCMReq = NULL;
+#endif
+    RTSemEventMultiReset(pWait->Event);
+    return pWait;
+}
+
+
+/**
+ * Frees the wait-for-event entry.
+ *
+ * The caller must own the wait spinlock !
+ * The entry must be in a list!
+ *
+ * @param   pDevExt         The device extension.
+ * @param   pWait           The wait-for-event entry to free.
+ */
+static void vgdrvWaitFreeLocked(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTWAIT pWait)
+{
+    pWait->fReqEvents = 0;
+    pWait->fResEvents = 0;
+#ifdef VBOX_WITH_HGCM
+    pWait->pHGCMReq = NULL;
+#endif
+#ifdef VBOXGUEST_USE_DEFERRED_WAKE_UP
+    Assert(!pWait->fFreeMe);
+    if (pWait->fPendingWakeUp)
+        pWait->fFreeMe = true;
+    else
+#endif
+    {
+        RTListNodeRemove(&pWait->ListNode);
+        RTListAppend(&pDevExt->FreeList, &pWait->ListNode);
+    }
+}
+
+
+/**
+ * Frees the wait-for-event entry.
+ *
+ * @param   pDevExt         The device extension.
+ * @param   pWait           The wait-for-event entry to free.
+ */
+static void vgdrvWaitFreeUnlocked(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTWAIT pWait)
+{
+    RTSpinlockAcquire(pDevExt->EventSpinlock);
+    vgdrvWaitFreeLocked(pDevExt, pWait);
+    RTSpinlockRelease(pDevExt->EventSpinlock);
+}
+
+
+#ifdef VBOXGUEST_USE_DEFERRED_WAKE_UP
+/**
+ * Processes the wake-up list.
+ *
+ * All entries in the wake-up list gets signalled and moved to the woken-up
+ * list.
+ *
+ * @param   pDevExt         The device extension.
+ */
+void VGDrvCommonWaitDoWakeUps(PVBOXGUESTDEVEXT pDevExt)
+{
+    if (!RTListIsEmpty(&pDevExt->WakeUpList))
+    {
+        RTSpinlockAcquire(pDevExt->EventSpinlock);
+        for (;;)
+        {
+            int            rc;
+            PVBOXGUESTWAIT pWait = RTListGetFirst(&pDevExt->WakeUpList, VBOXGUESTWAIT, ListNode);
+            if (!pWait)
+                break;
+            pWait->fPendingWakeUp = true;
+            RTSpinlockRelease(pDevExt->EventSpinlock);
+
+            rc = RTSemEventMultiSignal(pWait->Event);
+            AssertRC(rc);
+
+            RTSpinlockAcquire(pDevExt->EventSpinlock);
+            pWait->fPendingWakeUp = false;
+            if (!pWait->fFreeMe)
+            {
+                RTListNodeRemove(&pWait->ListNode);
+                RTListAppend(&pDevExt->WokenUpList, &pWait->ListNode);
+            }
+            else
+            {
+                pWait->fFreeMe = false;
+                vgdrvWaitFreeLocked(pDevExt, pWait);
+            }
+        }
+        RTSpinlockRelease(pDevExt->EventSpinlock);
+    }
+}
+#endif /* VBOXGUEST_USE_DEFERRED_WAKE_UP */
+
+
+/**
+ * Implements the fast (no input or output) type of IOCtls.
+ *
+ * This is currently just a placeholder stub inherited from the support driver code.
+ *
+ * @returns VBox status code.
+ * @param   iFunction   The IOCtl function number.
+ * @param   pDevExt     The device extension.
+ * @param   pSession    The session.
+ */
+int VGDrvCommonIoCtlFast(unsigned iFunction, PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION pSession)
+{
+    LogFlow(("VGDrvCommonIoCtlFast: iFunction=%#x pDevExt=%p pSession=%p\n", iFunction, pDevExt, pSession));
+
+    NOREF(iFunction);
+    NOREF(pDevExt);
+    NOREF(pSession);
+    return VERR_NOT_SUPPORTED;
+}
+
+
+/**
+ * Return the VMM device port.
+ *
+ * returns IPRT status code.
+ * @param   pDevExt         The device extension.
+ * @param   pInfo           The request info.
+ * @param   pcbDataReturned (out) contains the number of bytes to return.
+ */
+static int vgdrvIoCtl_GetVMMDevPort(PVBOXGUESTDEVEXT pDevExt, VBoxGuestPortInfo *pInfo, size_t *pcbDataReturned)
+{
+    LogFlow(("VBOXGUEST_IOCTL_GETVMMDEVPORT\n"));
+
+    pInfo->portAddress = pDevExt->IOPortBase;
+    pInfo->pVMMDevMemory = (VMMDevMemory *)pDevExt->pVMMDevMemory;
+    if (pcbDataReturned)
+        *pcbDataReturned = sizeof(*pInfo);
+    return VINF_SUCCESS;
+}
+
+
+#ifndef RT_OS_WINDOWS
+/**
+ * Set the callback for the kernel mouse handler.
+ *
+ * returns IPRT status code.
+ * @param   pDevExt         The device extension.
+ * @param   pNotify         The new callback information.
+ */
+int vgdrvIoCtl_SetMouseNotifyCallback(PVBOXGUESTDEVEXT pDevExt, VBoxGuestMouseSetNotifyCallback *pNotify)
+{
+    LogFlow(("VBOXGUEST_IOCTL_SET_MOUSE_NOTIFY_CALLBACK: pfnNotify=%p pvUser=%p\n", pNotify->pfnNotify, pNotify->pvUser));
+
+    RTSpinlockAcquire(pDevExt->EventSpinlock);
+    pDevExt->MouseNotifyCallback = *pNotify;
+    RTSpinlockRelease(pDevExt->EventSpinlock);
+    return VINF_SUCCESS;
+}
+#endif
+
+
+/**
+ * Worker vgdrvIoCtl_WaitEvent.
+ *
+ * The caller enters the spinlock, we leave it.
+ *
+ * @returns VINF_SUCCESS if we've left the spinlock and can return immediately.
+ */
+DECLINLINE(int) vbdgCheckWaitEventCondition(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION pSession,
+                                            VBoxGuestWaitEventInfo *pInfo, int iEvent, const uint32_t fReqEvents)
+{
+    uint32_t fMatches = pDevExt->f32PendingEvents & fReqEvents;
+    if (fMatches & VBOXGUEST_ACQUIRE_STYLE_EVENTS)
+        fMatches &= vgdrvGetAllowedEventMaskForSession(pDevExt, pSession);
+    if (fMatches || pSession->fPendingCancelWaitEvents)
+    {
+        ASMAtomicAndU32(&pDevExt->f32PendingEvents, ~fMatches);
+        RTSpinlockRelease(pDevExt->EventSpinlock);
+
+        pInfo->u32EventFlagsOut = fMatches;
+        pInfo->u32Result = VBOXGUEST_WAITEVENT_OK;
+        if (fReqEvents & ~((uint32_t)1 << iEvent))
+            LogFlow(("VBOXGUEST_IOCTL_WAITEVENT: returns %#x\n", pInfo->u32EventFlagsOut));
+        else
+            LogFlow(("VBOXGUEST_IOCTL_WAITEVENT: returns %#x/%d\n", pInfo->u32EventFlagsOut, iEvent));
+        pSession->fPendingCancelWaitEvents = false;
+        return VINF_SUCCESS;
+    }
+
+    RTSpinlockRelease(pDevExt->EventSpinlock);
+    return VERR_TIMEOUT;
+}
+
+
+static int vgdrvIoCtl_WaitEvent(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION pSession,
+                                VBoxGuestWaitEventInfo *pInfo,  size_t *pcbDataReturned, bool fInterruptible)
+{
+    const uint32_t  fReqEvents = pInfo->u32EventMaskIn;
+    uint32_t        fResEvents;
+    int             iEvent;
+    PVBOXGUESTWAIT  pWait;
+    int             rc;
+
+    pInfo->u32EventFlagsOut = 0;
+    pInfo->u32Result = VBOXGUEST_WAITEVENT_ERROR;
+    if (pcbDataReturned)
+        *pcbDataReturned = sizeof(*pInfo);
+
+    /*
+     * Copy and verify the input mask.
+     */
+    iEvent = ASMBitFirstSetU32(fReqEvents) - 1;
+    if (RT_UNLIKELY(iEvent < 0))
+    {
+        LogRel(("VBOXGUEST_IOCTL_WAITEVENT: Invalid input mask %#x!!\n", fReqEvents));
+        return VERR_INVALID_PARAMETER;
+    }
+
+    /*
+     * Check the condition up front, before doing the wait-for-event allocations.
+     */
+    RTSpinlockAcquire(pDevExt->EventSpinlock);
+    rc = vbdgCheckWaitEventCondition(pDevExt, pSession, pInfo, iEvent, fReqEvents);
+    if (rc == VINF_SUCCESS)
+        return rc;
+
+    if (!pInfo->u32TimeoutIn)
+    {
+        pInfo->u32Result = VBOXGUEST_WAITEVENT_TIMEOUT;
+        LogFlow(("VBOXGUEST_IOCTL_WAITEVENT: returns VERR_TIMEOUT\n"));
+        return VERR_TIMEOUT;
+    }
+
+    pWait = vgdrvWaitAlloc(pDevExt, pSession);
+    if (!pWait)
+        return VERR_NO_MEMORY;
+    pWait->fReqEvents = fReqEvents;
+
+    /*
+     * We've got the wait entry now, re-enter the spinlock and check for the condition.
+     * If the wait condition is met, return.
+     * Otherwise enter into the list and go to sleep waiting for the ISR to signal us.
+     */
+    RTSpinlockAcquire(pDevExt->EventSpinlock);
+    RTListAppend(&pDevExt->WaitList, &pWait->ListNode);
+    rc = vbdgCheckWaitEventCondition(pDevExt, pSession, pInfo, iEvent, fReqEvents);
+    if (rc == VINF_SUCCESS)
+    {
+        vgdrvWaitFreeUnlocked(pDevExt, pWait);
+        return rc;
+    }
+
+    if (fInterruptible)
+        rc = RTSemEventMultiWaitNoResume(pWait->Event,
+                                         pInfo->u32TimeoutIn == UINT32_MAX ? RT_INDEFINITE_WAIT : pInfo->u32TimeoutIn);
+    else
+        rc = RTSemEventMultiWait(pWait->Event,
+                                 pInfo->u32TimeoutIn == UINT32_MAX ? RT_INDEFINITE_WAIT : pInfo->u32TimeoutIn);
+
+    /*
+     * There is one special case here and that's when the semaphore is
+     * destroyed upon device driver unload. This shouldn't happen of course,
+     * but in case it does, just get out of here ASAP.
+     */
+    if (rc == VERR_SEM_DESTROYED)
+        return rc;
+
+    /*
+     * Unlink the wait item and dispose of it.
+     */
+    RTSpinlockAcquire(pDevExt->EventSpinlock);
+    fResEvents = pWait->fResEvents;
+    vgdrvWaitFreeLocked(pDevExt, pWait);
+    RTSpinlockRelease(pDevExt->EventSpinlock);
+
+    /*
+     * Now deal with the return code.
+     */
+    if (    fResEvents
+        &&  fResEvents != UINT32_MAX)
+    {
+        pInfo->u32EventFlagsOut = fResEvents;
+        pInfo->u32Result = VBOXGUEST_WAITEVENT_OK;
+        if (fReqEvents & ~((uint32_t)1 << iEvent))
+            LogFlow(("VBOXGUEST_IOCTL_WAITEVENT: returns %#x\n", pInfo->u32EventFlagsOut));
+        else
+            LogFlow(("VBOXGUEST_IOCTL_WAITEVENT: returns %#x/%d\n", pInfo->u32EventFlagsOut, iEvent));
+        rc = VINF_SUCCESS;
+    }
+    else if (   fResEvents == UINT32_MAX
+             || rc == VERR_INTERRUPTED)
+    {
+        pInfo->u32Result = VBOXGUEST_WAITEVENT_INTERRUPTED;
+        rc = VERR_INTERRUPTED;
+        LogFlow(("VBOXGUEST_IOCTL_WAITEVENT: returns VERR_INTERRUPTED\n"));
+    }
+    else if (rc == VERR_TIMEOUT)
+    {
+        pInfo->u32Result = VBOXGUEST_WAITEVENT_TIMEOUT;
+        LogFlow(("VBOXGUEST_IOCTL_WAITEVENT: returns VERR_TIMEOUT (2)\n"));
+    }
+    else
+    {
+        if (RT_SUCCESS(rc))
+        {
+            LogRelMax(32, ("VBOXGUEST_IOCTL_WAITEVENT: returns %Rrc but no events!\n", rc));
+            rc = VERR_INTERNAL_ERROR;
+        }
+        pInfo->u32Result = VBOXGUEST_WAITEVENT_ERROR;
+        LogFlow(("VBOXGUEST_IOCTL_WAITEVENT: returns %Rrc\n", rc));
+    }
+
+    return rc;
+}
+
+
+static int vgdrvIoCtl_CancelAllWaitEvents(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION pSession)
+{
+    PVBOXGUESTWAIT          pWait;
+    PVBOXGUESTWAIT          pSafe;
+    int                     rc = 0;
+    /* Was as least one WAITEVENT in process for this session?  If not we
+     * set a flag that the next call should be interrupted immediately.  This
+     * is needed so that a user thread can reliably interrupt another one in a
+     * WAITEVENT loop. */
+    bool                    fCancelledOne = false;
+
+    LogFlow(("VBOXGUEST_IOCTL_CANCEL_ALL_WAITEVENTS\n"));
+
+    /*
+     * Walk the event list and wake up anyone with a matching session.
+     */
+    RTSpinlockAcquire(pDevExt->EventSpinlock);
+    RTListForEachSafe(&pDevExt->WaitList, pWait, pSafe, VBOXGUESTWAIT, ListNode)
+    {
+        if (pWait->pSession == pSession)
+        {
+            fCancelledOne = true;
+            pWait->fResEvents = UINT32_MAX;
+            RTListNodeRemove(&pWait->ListNode);
+#ifdef VBOXGUEST_USE_DEFERRED_WAKE_UP
+            RTListAppend(&pDevExt->WakeUpList, &pWait->ListNode);
+#else
+            rc |= RTSemEventMultiSignal(pWait->Event);
+            RTListAppend(&pDevExt->WokenUpList, &pWait->ListNode);
+#endif
+        }
+    }
+    if (!fCancelledOne)
+        pSession->fPendingCancelWaitEvents = true;
+    RTSpinlockRelease(pDevExt->EventSpinlock);
+    Assert(rc == 0);
+    NOREF(rc);
+
+#ifdef VBOXGUEST_USE_DEFERRED_WAKE_UP
+    VGDrvCommonWaitDoWakeUps(pDevExt);
+#endif
+
+    return VINF_SUCCESS;
+}
+
+
+/**
+ * Checks if the VMM request is allowed in the context of the given session.
+ *
+ * @returns VINF_SUCCESS or VERR_PERMISSION_DENIED.
+ * @param   pDevExt             The device extension.
+ * @param   pSession            The calling session.
+ * @param   enmType             The request type.
+ * @param   pReqHdr             The request.
+ */
+static int vgdrvCheckIfVmmReqIsAllowed(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION pSession, VMMDevRequestType enmType,
+                                       VMMDevRequestHeader const *pReqHdr)
+{
+    /*
+     * Categorize the request being made.
+     */
+    /** @todo This need quite some more work! */
+    enum
+    {
+        kLevel_Invalid, kLevel_NoOne, kLevel_OnlyVBoxGuest, kLevel_OnlyKernel, kLevel_TrustedUsers, kLevel_AllUsers
+    } enmRequired;
+    switch (enmType)
+    {
+        /*
+         * Deny access to anything we don't know or provide specialized I/O controls for.
+         */
+#ifdef VBOX_WITH_HGCM
+        case VMMDevReq_HGCMConnect:
+        case VMMDevReq_HGCMDisconnect:
+# ifdef VBOX_WITH_64_BITS_GUESTS
+        case VMMDevReq_HGCMCall32:
+        case VMMDevReq_HGCMCall64:
+# else
+        case VMMDevReq_HGCMCall:
+# endif /* VBOX_WITH_64_BITS_GUESTS */
+        case VMMDevReq_HGCMCancel:
+        case VMMDevReq_HGCMCancel2:
+#endif /* VBOX_WITH_HGCM */
+        case VMMDevReq_SetGuestCapabilities:
+        default:
+            enmRequired = kLevel_NoOne;
+            break;
+
+        /*
+         * There are a few things only this driver can do (and it doesn't use
+         * the VMMRequst I/O control route anyway, but whatever).
+         */
+        case VMMDevReq_ReportGuestInfo:
+        case VMMDevReq_ReportGuestInfo2:
+        case VMMDevReq_GetHypervisorInfo:
+        case VMMDevReq_SetHypervisorInfo:
+        case VMMDevReq_RegisterPatchMemory:
+        case VMMDevReq_DeregisterPatchMemory:
+        case VMMDevReq_GetMemBalloonChangeRequest:
+            enmRequired = kLevel_OnlyVBoxGuest;
+            break;
+
+        /*
+         * Trusted users apps only.
+         */
+        case VMMDevReq_QueryCredentials:
+        case VMMDevReq_ReportCredentialsJudgement:
+        case VMMDevReq_RegisterSharedModule:
+        case VMMDevReq_UnregisterSharedModule:
+        case VMMDevReq_WriteCoreDump:
+        case VMMDevReq_GetCpuHotPlugRequest:
+        case VMMDevReq_SetCpuHotPlugStatus:
+        case VMMDevReq_CheckSharedModules:
+        case VMMDevReq_GetPageSharingStatus:
+        case VMMDevReq_DebugIsPageShared:
+        case VMMDevReq_ReportGuestStats:
+        case VMMDevReq_ReportGuestUserState:
+        case VMMDevReq_GetStatisticsChangeRequest:
+        case VMMDevReq_ChangeMemBalloon:
+            enmRequired = kLevel_TrustedUsers;
+            break;
+
+        /*
+         * Anyone.
+         */
+        case VMMDevReq_GetMouseStatus:
+        case VMMDevReq_SetMouseStatus:
+        case VMMDevReq_SetPointerShape:
+        case VMMDevReq_GetHostVersion:
+        case VMMDevReq_Idle:
+        case VMMDevReq_GetHostTime:
+        case VMMDevReq_SetPowerStatus:
+        case VMMDevReq_AcknowledgeEvents:
+        case VMMDevReq_CtlGuestFilterMask:
+        case VMMDevReq_ReportGuestStatus:
+        case VMMDevReq_GetDisplayChangeRequest:
+        case VMMDevReq_VideoModeSupported:
+        case VMMDevReq_GetHeightReduction:
+        case VMMDevReq_GetDisplayChangeRequest2:
+        case VMMDevReq_VideoModeSupported2:
+        case VMMDevReq_VideoAccelEnable:
+        case VMMDevReq_VideoAccelFlush:
+        case VMMDevReq_VideoSetVisibleRegion:
+        case VMMDevReq_GetDisplayChangeRequestEx:
+        case VMMDevReq_GetSeamlessChangeRequest:
+        case VMMDevReq_GetVRDPChangeRequest:
+        case VMMDevReq_LogString:
+        case VMMDevReq_GetSessionId:
+            enmRequired = kLevel_AllUsers;
+            break;
+
+        /*
+         * Depends on the request parameters...
+         */
+        /** @todo this have to be changed into an I/O control and the facilities
+         *        tracked in the session so they can automatically be failed when the
+         *        session terminates without reporting the new status.
+         *
+         *  The information presented by IGuest is not reliable without this! */
+        case VMMDevReq_ReportGuestCapabilities:
+            switch (((VMMDevReportGuestStatus const *)pReqHdr)->guestStatus.facility)
+            {
+                case VBoxGuestFacilityType_All:
+                case VBoxGuestFacilityType_VBoxGuestDriver:
+                    enmRequired = kLevel_OnlyVBoxGuest;
+                    break;
+                case VBoxGuestFacilityType_VBoxService:
+                    enmRequired = kLevel_TrustedUsers;
+                    break;
+                case VBoxGuestFacilityType_VBoxTrayClient:
+                case VBoxGuestFacilityType_Seamless:
+                case VBoxGuestFacilityType_Graphics:
+                default:
+                    enmRequired = kLevel_AllUsers;
+                    break;
+            }
+            break;
+    }
+
+    /*
+     * Check against the session.
+     */
+    switch (enmRequired)
+    {
+        default:
+        case kLevel_NoOne:
+            break;
+        case kLevel_OnlyVBoxGuest:
+        case kLevel_OnlyKernel:
+            if (pSession->R0Process == NIL_RTR0PROCESS)
+                return VINF_SUCCESS;
+            break;
+        case kLevel_TrustedUsers:
+        case kLevel_AllUsers:
+            return VINF_SUCCESS;
+    }
+
+    return VERR_PERMISSION_DENIED;
+}
+
+static int vgdrvIoCtl_VMMRequest(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION pSession,
+                                 VMMDevRequestHeader *pReqHdr, size_t cbData, size_t *pcbDataReturned)
+{
+    int                     rc;
+    VMMDevRequestHeader    *pReqCopy;
+
+    /*
+     * Validate the header and request size.
+     */
+    const VMMDevRequestType enmType   = pReqHdr->requestType;
+    const uint32_t          cbReq     = pReqHdr->size;
+    const uint32_t          cbMinSize = (uint32_t)vmmdevGetRequestSize(enmType);
+
+    LogFlow(("VBOXGUEST_IOCTL_VMMREQUEST: type %d\n", pReqHdr->requestType));
+
+    if (cbReq < cbMinSize)
+    {
+        LogRel(("VBOXGUEST_IOCTL_VMMREQUEST: invalid hdr size %#x, expected >= %#x; type=%#x!!\n",
+                cbReq, cbMinSize, enmType));
+        return VERR_INVALID_PARAMETER;
+    }
+    if (cbReq > cbData)
+    {
+        LogRel(("VBOXGUEST_IOCTL_VMMREQUEST: invalid size %#x, expected >= %#x (hdr); type=%#x!!\n",
+                cbData, cbReq, enmType));
+        return VERR_INVALID_PARAMETER;
+    }
+    rc = VbglGRVerify(pReqHdr, cbData);
+    if (RT_FAILURE(rc))
+    {
+        Log(("VBOXGUEST_IOCTL_VMMREQUEST: invalid header: size %#x, expected >= %#x (hdr); type=%#x; rc=%Rrc!!\n",
+             cbData, cbReq, enmType, rc));
+        return rc;
+    }
+
+    rc = vgdrvCheckIfVmmReqIsAllowed(pDevExt, pSession, enmType, pReqHdr);
+    if (RT_FAILURE(rc))
+    {
+        Log(("VBOXGUEST_IOCTL_VMMREQUEST: Operation not allowed! type=%#x rc=%Rrc\n", enmType, rc));
+        return rc;
+    }
+
+    /*
+     * Make a copy of the request in the physical memory heap so
+     * the VBoxGuestLibrary can more easily deal with the request.
+     * (This is really a waste of time since the OS or the OS specific
+     * code has already buffered or locked the input/output buffer, but
+     * it does makes things a bit simpler wrt to phys address.)
+     */
+    rc = VbglGRAlloc(&pReqCopy, cbReq, enmType);
+    if (RT_FAILURE(rc))
+    {
+        Log(("VBOXGUEST_IOCTL_VMMREQUEST: failed to allocate %u (%#x) bytes to cache the request. rc=%Rrc!!\n",
+             cbReq, cbReq, rc));
+        return rc;
+    }
+    memcpy(pReqCopy, pReqHdr, cbReq);
+
+    if (enmType == VMMDevReq_GetMouseStatus) /* clear poll condition. */
+        pSession->u32MousePosChangedSeq = ASMAtomicUoReadU32(&pDevExt->u32MousePosChangedSeq);
+
+    rc = VbglGRPerform(pReqCopy);
+    if (   RT_SUCCESS(rc)
+        && RT_SUCCESS(pReqCopy->rc))
+    {
+        Assert(rc != VINF_HGCM_ASYNC_EXECUTE);
+        Assert(pReqCopy->rc != VINF_HGCM_ASYNC_EXECUTE);
+
+        memcpy(pReqHdr, pReqCopy, cbReq);
+        if (pcbDataReturned)
+            *pcbDataReturned = cbReq;
+    }
+    else if (RT_FAILURE(rc))
+        Log(("VBOXGUEST_IOCTL_VMMREQUEST: VbglGRPerform - rc=%Rrc!\n", rc));
+    else
+    {
+        Log(("VBOXGUEST_IOCTL_VMMREQUEST: request execution failed; VMMDev rc=%Rrc!\n", pReqCopy->rc));
+        rc = pReqCopy->rc;
+    }
+
+    VbglGRFree(pReqCopy);
+    return rc;
+}
+
+
+#ifdef VBOX_WITH_HGCM
+
+AssertCompile(RT_INDEFINITE_WAIT == (uint32_t)RT_INDEFINITE_WAIT); /* assumed by code below */
+
+/** Worker for vgdrvHgcmAsyncWaitCallback*. */
+static int vgdrvHgcmAsyncWaitCallbackWorker(VMMDevHGCMRequestHeader volatile *pHdr, PVBOXGUESTDEVEXT pDevExt,
+                                            bool fInterruptible, uint32_t cMillies)
+{
+    int rc;
+
+    /*
+     * Check to see if the condition was met by the time we got here.
+     *
+     * We create a simple poll loop here for dealing with out-of-memory
+     * conditions since the caller isn't necessarily able to deal with
+     * us returning too early.
+     */
+    PVBOXGUESTWAIT pWait;
+    for (;;)
+    {
+        RTSpinlockAcquire(pDevExt->EventSpinlock);
+        if ((pHdr->fu32Flags & VBOX_HGCM_REQ_DONE) != 0)
+        {
+            RTSpinlockRelease(pDevExt->EventSpinlock);
+            return VINF_SUCCESS;
+        }
+        RTSpinlockRelease(pDevExt->EventSpinlock);
+
+        pWait = vgdrvWaitAlloc(pDevExt, NULL);
+        if (pWait)
+            break;
+        if (fInterruptible)
+            return VERR_INTERRUPTED;
+        RTThreadSleep(1);
+    }
+    pWait->fReqEvents = VMMDEV_EVENT_HGCM;
+    pWait->pHGCMReq = pHdr;
+
+    /*
+     * Re-enter the spinlock and re-check for the condition.
+     * If the condition is met, return.
+     * Otherwise link us into the HGCM wait list and go to sleep.
+     */
+    RTSpinlockAcquire(pDevExt->EventSpinlock);
+    RTListAppend(&pDevExt->HGCMWaitList, &pWait->ListNode);
+    if ((pHdr->fu32Flags & VBOX_HGCM_REQ_DONE) != 0)
+    {
+        vgdrvWaitFreeLocked(pDevExt, pWait);
+        RTSpinlockRelease(pDevExt->EventSpinlock);
+        return VINF_SUCCESS;
+    }
+    RTSpinlockRelease(pDevExt->EventSpinlock);
+
+    if (fInterruptible)
+        rc = RTSemEventMultiWaitNoResume(pWait->Event, cMillies);
+    else
+        rc = RTSemEventMultiWait(pWait->Event, cMillies);
+    if (rc == VERR_SEM_DESTROYED)
+        return rc;
+
+    /*
+     * Unlink, free and return.
+     */
+    if (   RT_FAILURE(rc)
+        && rc != VERR_TIMEOUT
+        && (   !fInterruptible
+            || rc != VERR_INTERRUPTED))
+        LogRel(("vgdrvHgcmAsyncWaitCallback: wait failed! %Rrc\n", rc));
+
+    vgdrvWaitFreeUnlocked(pDevExt, pWait);
+    return rc;
+}
+
+
+/**
+ * This is a callback for dealing with async waits.
+ *
+ * It operates in a manner similar to vgdrvIoCtl_WaitEvent.
+ */
+static DECLCALLBACK(int) vgdrvHgcmAsyncWaitCallback(VMMDevHGCMRequestHeader *pHdr, void *pvUser, uint32_t u32User)
+{
+    PVBOXGUESTDEVEXT pDevExt = (PVBOXGUESTDEVEXT)pvUser;
+    LogFlow(("vgdrvHgcmAsyncWaitCallback: requestType=%d\n", pHdr->header.requestType));
+    return vgdrvHgcmAsyncWaitCallbackWorker((VMMDevHGCMRequestHeader volatile *)pHdr, pDevExt,
+                                            false /* fInterruptible */, u32User  /* cMillies */);
+}
+
+
+/**
+ * This is a callback for dealing with async waits with a timeout.
+ *
+ * It operates in a manner similar to vgdrvIoCtl_WaitEvent.
+ */
+static DECLCALLBACK(int) vgdrvHgcmAsyncWaitCallbackInterruptible(VMMDevHGCMRequestHeader *pHdr, void *pvUser, uint32_t u32User)
+{
+    PVBOXGUESTDEVEXT pDevExt = (PVBOXGUESTDEVEXT)pvUser;
+    LogFlow(("vgdrvHgcmAsyncWaitCallbackInterruptible: requestType=%d\n", pHdr->header.requestType));
+    return vgdrvHgcmAsyncWaitCallbackWorker((VMMDevHGCMRequestHeader volatile *)pHdr, pDevExt,
+                                            true /* fInterruptible */, u32User /* cMillies */);
+}
+
+
+static int vgdrvIoCtl_HGCMConnect(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION pSession,
+                                  VBoxGuestHGCMConnectInfo *pInfo, size_t *pcbDataReturned)
+{
+    int rc;
+
+    /*
+     * The VbglHGCMConnect call will invoke the callback if the HGCM
+     * call is performed in an ASYNC fashion. The function is not able
+     * to deal with cancelled requests.
+     */
+    Log(("VBOXGUEST_IOCTL_HGCM_CONNECT: %.128s\n",
+         pInfo->Loc.type == VMMDevHGCMLoc_LocalHost || pInfo->Loc.type == VMMDevHGCMLoc_LocalHost_Existing
+         ? pInfo->Loc.u.host.achName : "<not local host>"));
+
+    rc = VbglR0HGCMInternalConnect(pInfo, vgdrvHgcmAsyncWaitCallback, pDevExt, RT_INDEFINITE_WAIT);
+    if (RT_SUCCESS(rc))
+    {
+        Log(("VBOXGUEST_IOCTL_HGCM_CONNECT: u32Client=%RX32 result=%Rrc (rc=%Rrc)\n",
+             pInfo->u32ClientID, pInfo->result, rc));
+        if (RT_SUCCESS(pInfo->result))
+        {
+            /*
+             * Append the client id to the client id table.
+             * If the table has somehow become filled up, we'll disconnect the session.
+             */
+            unsigned i;
+            RTSpinlockAcquire(pDevExt->SessionSpinlock);
+            for (i = 0; i < RT_ELEMENTS(pSession->aHGCMClientIds); i++)
+                if (!pSession->aHGCMClientIds[i])
+                {
+                    pSession->aHGCMClientIds[i] = pInfo->u32ClientID;
+                    break;
+                }
+            RTSpinlockRelease(pDevExt->SessionSpinlock);
+            if (i >= RT_ELEMENTS(pSession->aHGCMClientIds))
+            {
+                VBoxGuestHGCMDisconnectInfo Info;
+                LogRelMax(32, ("VBOXGUEST_IOCTL_HGCM_CONNECT: too many HGCMConnect calls for one session!\n"));
+                Info.result = 0;
+                Info.u32ClientID = pInfo->u32ClientID;
+                VbglR0HGCMInternalDisconnect(&Info, vgdrvHgcmAsyncWaitCallback, pDevExt, RT_INDEFINITE_WAIT);
+                return VERR_TOO_MANY_OPEN_FILES;
+            }
+        }
+        else
+            rc = pInfo->result;
+        if (pcbDataReturned)
+            *pcbDataReturned = sizeof(*pInfo);
+    }
+    return rc;
+}
+
+
+static int vgdrvIoCtl_HGCMDisconnect(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION pSession,
+                                     VBoxGuestHGCMDisconnectInfo *pInfo, size_t *pcbDataReturned)
+{
+    /*
+     * Validate the client id and invalidate its entry while we're in the call.
+     */
+    int             rc;
+    const uint32_t  u32ClientId = pInfo->u32ClientID;
+    unsigned        i;
+    RTSpinlockAcquire(pDevExt->SessionSpinlock);
+    for (i = 0; i < RT_ELEMENTS(pSession->aHGCMClientIds); i++)
+        if (pSession->aHGCMClientIds[i] == u32ClientId)
+        {
+            pSession->aHGCMClientIds[i] = UINT32_MAX;
+            break;
+        }
+    RTSpinlockRelease(pDevExt->SessionSpinlock);
+    if (i >= RT_ELEMENTS(pSession->aHGCMClientIds))
+    {
+        LogRelMax(32, ("VBOXGUEST_IOCTL_HGCM_DISCONNECT: u32Client=%RX32\n", u32ClientId));
+        return VERR_INVALID_HANDLE;
+    }
+
+    /*
+     * The VbglHGCMConnect call will invoke the callback if the HGCM
+     * call is performed in an ASYNC fashion. The function is not able
+     * to deal with cancelled requests.
+     */
+    Log(("VBOXGUEST_IOCTL_HGCM_DISCONNECT: u32Client=%RX32\n", pInfo->u32ClientID));
+    rc = VbglR0HGCMInternalDisconnect(pInfo, vgdrvHgcmAsyncWaitCallback, pDevExt, RT_INDEFINITE_WAIT);
+    if (RT_SUCCESS(rc))
+    {
+        LogFlow(("VBOXGUEST_IOCTL_HGCM_DISCONNECT: result=%Rrc\n", pInfo->result));
+        if (pcbDataReturned)
+            *pcbDataReturned = sizeof(*pInfo);
+    }
+
+    /* Update the client id array according to the result. */
+    RTSpinlockAcquire(pDevExt->SessionSpinlock);
+    if (pSession->aHGCMClientIds[i] == UINT32_MAX)
+        pSession->aHGCMClientIds[i] = RT_SUCCESS(rc) && RT_SUCCESS(pInfo->result) ? 0 : u32ClientId;
+    RTSpinlockRelease(pDevExt->SessionSpinlock);
+
+    return rc;
+}
+
+
+static int vgdrvIoCtl_HGCMCall(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION pSession, VBoxGuestHGCMCallInfo *pInfo,
+                               uint32_t cMillies, bool fInterruptible, bool f32bit, bool fUserData,
+                               size_t cbExtra, size_t cbData, size_t *pcbDataReturned)
+{
+    const uint32_t  u32ClientId = pInfo->u32ClientID;
+    uint32_t        fFlags;
+    size_t          cbActual;
+    unsigned        i;
+    int             rc;
+
+    /*
+     * Some more validations.
+     */
+    if (pInfo->cParms > 4096) /* (Just make sure it doesn't overflow the next check.) */
+    {
+        LogRel(("VBOXGUEST_IOCTL_HGCM_CALL: cParm=%RX32 is not sane\n", pInfo->cParms));
+        return VERR_INVALID_PARAMETER;
+    }
+
+    cbActual = cbExtra + sizeof(*pInfo);
+#ifdef RT_ARCH_AMD64
+    if (f32bit)
+        cbActual += pInfo->cParms * sizeof(HGCMFunctionParameter32);
+    else
+#endif
+        cbActual += pInfo->cParms * sizeof(HGCMFunctionParameter);
+    if (cbData < cbActual)
+    {
+        LogRel(("VBOXGUEST_IOCTL_HGCM_CALL: cbData=%#zx (%zu) required size is %#zx (%zu)\n",
+               cbData, cbData, cbActual, cbActual));
+        return VERR_INVALID_PARAMETER;
+    }
+
+    /*
+     * Validate the client id.
+     */
+    RTSpinlockAcquire(pDevExt->SessionSpinlock);
+    for (i = 0; i < RT_ELEMENTS(pSession->aHGCMClientIds); i++)
+        if (pSession->aHGCMClientIds[i] == u32ClientId)
+            break;
+    RTSpinlockRelease(pDevExt->SessionSpinlock);
+    if (RT_UNLIKELY(i >= RT_ELEMENTS(pSession->aHGCMClientIds)))
+    {
+        LogRelMax(32, ("VBOXGUEST_IOCTL_HGCM_CALL: Invalid handle. u32Client=%RX32\n", u32ClientId));
+        return VERR_INVALID_HANDLE;
+    }
+
+    /*
+     * The VbglHGCMCall call will invoke the callback if the HGCM
+     * call is performed in an ASYNC fashion. This function can
+     * deal with cancelled requests, so we let user more requests
+     * be interruptible (should add a flag for this later I guess).
+     */
+    LogFlow(("VBOXGUEST_IOCTL_HGCM_CALL: u32Client=%RX32\n", pInfo->u32ClientID));
+    fFlags = !fUserData && pSession->R0Process == NIL_RTR0PROCESS ? VBGLR0_HGCMCALL_F_KERNEL : VBGLR0_HGCMCALL_F_USER;
+    uint32_t cbInfo = (uint32_t)(cbData - cbExtra);
+#ifdef RT_ARCH_AMD64
+    if (f32bit)
+    {
+        if (fInterruptible)
+            rc = VbglR0HGCMInternalCall32(pInfo, cbInfo, fFlags, vgdrvHgcmAsyncWaitCallbackInterruptible, pDevExt, cMillies);
+        else
+            rc = VbglR0HGCMInternalCall32(pInfo, cbInfo, fFlags, vgdrvHgcmAsyncWaitCallback, pDevExt, cMillies);
+    }
+    else
+#endif
+    {
+        if (fInterruptible)
+            rc = VbglR0HGCMInternalCall(pInfo, cbInfo, fFlags, vgdrvHgcmAsyncWaitCallbackInterruptible, pDevExt, cMillies);
+        else
+            rc = VbglR0HGCMInternalCall(pInfo, cbInfo, fFlags, vgdrvHgcmAsyncWaitCallback, pDevExt, cMillies);
+    }
+    if (RT_SUCCESS(rc))
+    {
+        LogFlow(("VBOXGUEST_IOCTL_HGCM_CALL: result=%Rrc\n", pInfo->result));
+        if (pcbDataReturned)
+            *pcbDataReturned = cbActual;
+    }
+    else
+    {
+        if (   rc != VERR_INTERRUPTED
+            && rc != VERR_TIMEOUT)
+            LogRelMax(32, ("VBOXGUEST_IOCTL_HGCM_CALL: %s Failed. rc=%Rrc.\n", f32bit ? "32" : "64", rc));
+        else
+            Log(("VBOXGUEST_IOCTL_HGCM_CALL: %s Failed. rc=%Rrc.\n", f32bit ? "32" : "64", rc));
+    }
+    return rc;
+}
+
+#endif /* VBOX_WITH_HGCM */
+
+/**
+ * Handle VBOXGUEST_IOCTL_CHECK_BALLOON from R3.
+ *
+ * Ask the host for the size of the balloon and try to set it accordingly.  If
+ * this approach fails because it's not supported, return with fHandleInR3 set
+ * and let the user land supply memory we can lock via the other ioctl.
+ *
+ * @returns VBox status code.
+ *
+ * @param   pDevExt             The device extension.
+ * @param   pSession            The session.
+ * @param   pInfo               The output buffer.
+ * @param   pcbDataReturned     Where to store the amount of returned data. Can
+ *                              be NULL.
+ */
+static int vgdrvIoCtl_CheckMemoryBalloon(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION pSession,
+                                         VBoxGuestCheckBalloonInfo *pInfo, size_t *pcbDataReturned)
+{
+    VMMDevGetMemBalloonChangeRequest *pReq;
+    int rc;
+
+    LogFlow(("VBOXGUEST_IOCTL_CHECK_BALLOON:\n"));
+    rc = RTSemFastMutexRequest(pDevExt->MemBalloon.hMtx);
+    AssertRCReturn(rc, rc);
+
+    /*
+     * The first user trying to query/change the balloon becomes the
+     * owner and owns it until the session is closed (vgdrvCloseMemBalloon).
+     */
+    if (   pDevExt->MemBalloon.pOwner != pSession
+        && pDevExt->MemBalloon.pOwner == NULL)
+        pDevExt->MemBalloon.pOwner = pSession;
+
+    if (pDevExt->MemBalloon.pOwner == pSession)
+    {
+        rc = VbglGRAlloc((VMMDevRequestHeader **)&pReq, sizeof(VMMDevGetMemBalloonChangeRequest), VMMDevReq_GetMemBalloonChangeRequest);
+        if (RT_SUCCESS(rc))
+        {
+            /*
+             * This is a response to that event. Setting this bit means that
+             * we request the value from the host and change the guest memory
+             * balloon according to this value.
+             */
+            pReq->eventAck = VMMDEV_EVENT_BALLOON_CHANGE_REQUEST;
+            rc = VbglGRPerform(&pReq->header);
+            if (RT_SUCCESS(rc))
+            {
+                Assert(pDevExt->MemBalloon.cMaxChunks == pReq->cPhysMemChunks || pDevExt->MemBalloon.cMaxChunks == 0);
+                pDevExt->MemBalloon.cMaxChunks = pReq->cPhysMemChunks;
+
+                pInfo->cBalloonChunks = pReq->cBalloonChunks;
+                pInfo->fHandleInR3    = false;
+
+                rc = vgdrvSetBalloonSizeKernel(pDevExt, pReq->cBalloonChunks, &pInfo->fHandleInR3);
+                /* Ignore various out of memory failures. */
+                if (   rc == VERR_NO_MEMORY
+                    || rc == VERR_NO_PHYS_MEMORY
+                    || rc == VERR_NO_CONT_MEMORY)
+                    rc = VINF_SUCCESS;
+
+                if (pcbDataReturned)
+                    *pcbDataReturned = sizeof(VBoxGuestCheckBalloonInfo);
+            }
+            else
+                LogRel(("VBOXGUEST_IOCTL_CHECK_BALLOON: VbglGRPerform failed. rc=%Rrc\n", rc));
+            VbglGRFree(&pReq->header);
+        }
+    }
+    else
+        rc = VERR_PERMISSION_DENIED;
+
+    RTSemFastMutexRelease(pDevExt->MemBalloon.hMtx);
+    LogFlow(("VBOXGUEST_IOCTL_CHECK_BALLOON returns %Rrc\n", rc));
+    return rc;
+}
+
+
+/**
+ * Handle a request for changing the memory balloon.
+ *
+ * @returns VBox status code.
+ *
+ * @param   pDevExt             The device extention.
+ * @param   pSession            The session.
+ * @param   pInfo               The change request structure (input).
+ * @param   pcbDataReturned     Where to store the amount of returned data. Can
+ *                              be NULL.
+ */
+static int vgdrvIoCtl_ChangeMemoryBalloon(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION pSession,
+                                          VBoxGuestChangeBalloonInfo *pInfo, size_t *pcbDataReturned)
+{
+    int rc;
+    LogFlow(("VBOXGUEST_IOCTL_CHANGE_BALLOON: fInflate=%RTbool u64ChunkAddr=%#RX64\n", pInfo->fInflate, pInfo->u64ChunkAddr));
+
+    rc = RTSemFastMutexRequest(pDevExt->MemBalloon.hMtx);
+    AssertRCReturn(rc, rc);
+
+    if (!pDevExt->MemBalloon.fUseKernelAPI)
+    {
+        /*
+         * The first user trying to query/change the balloon becomes the
+         * owner and owns it until the session is closed (vgdrvCloseMemBalloon).
+         */
+        if (   pDevExt->MemBalloon.pOwner != pSession
+            && pDevExt->MemBalloon.pOwner == NULL)
+            pDevExt->MemBalloon.pOwner = pSession;
+
+        if (pDevExt->MemBalloon.pOwner == pSession)
+        {
+            rc = vgdrvSetBalloonSizeFromUser(pDevExt, pSession, pInfo->u64ChunkAddr, !!pInfo->fInflate);
+            if (pcbDataReturned)
+                *pcbDataReturned = 0;
+        }
+        else
+            rc = VERR_PERMISSION_DENIED;
+    }
+    else
+        rc = VERR_PERMISSION_DENIED;
+
+    RTSemFastMutexRelease(pDevExt->MemBalloon.hMtx);
+    return rc;
+}
+
+
+/**
+ * Handle a request for writing a core dump of the guest on the host.
+ *
+ * @returns VBox status code.
+ *
+ * @param pDevExt               The device extension.
+ * @param pInfo                 The output buffer.
+ */
+static int vgdrvIoCtl_WriteCoreDump(PVBOXGUESTDEVEXT pDevExt, VBoxGuestWriteCoreDump *pInfo)
+{
+    VMMDevReqWriteCoreDump *pReq = NULL;
+    int rc;
+    LogFlow(("VBOXGUEST_IOCTL_WRITE_CORE_DUMP\n"));
+
+    rc = VbglGRAlloc((VMMDevRequestHeader **)&pReq, sizeof(*pReq), VMMDevReq_WriteCoreDump);
+    if (RT_SUCCESS(rc))
+    {
+        pReq->fFlags = pInfo->fFlags;
+        rc = VbglGRPerform(&pReq->header);
+        if (RT_FAILURE(rc))
+            Log(("VBOXGUEST_IOCTL_WRITE_CORE_DUMP: VbglGRPerform failed, rc=%Rrc!\n", rc));
+
+        VbglGRFree(&pReq->header);
+    }
+    else
+        Log(("VBOXGUEST_IOCTL_WRITE_CORE_DUMP: failed to allocate %u (%#x) bytes to cache the request. rc=%Rrc!!\n",
+             sizeof(*pReq), sizeof(*pReq), rc));
+    return rc;
+}
+
+
+/**
+ * Guest backdoor logging.
+ *
+ * @returns VBox status code.
+ *
+ * @param   pDevExt             The device extension.
+ * @param   pch                 The log message (need not be NULL terminated).
+ * @param   cbData              Size of the buffer.
+ * @param   pcbDataReturned     Where to store the amount of returned data. Can be NULL.
+ * @param   fUserSession        Copy of VBOXGUESTSESSION::fUserSession for the
+ *                              call.  True normal user, false root user.
+ */
+static int vgdrvIoCtl_Log(PVBOXGUESTDEVEXT pDevExt, const char *pch, size_t cbData, size_t *pcbDataReturned, bool fUserSession)
+{
+    if (pDevExt->fLoggingEnabled)
+        RTLogBackdoorPrintf("%.*s", cbData, pch);
+    else if (!fUserSession)
+        LogRel(("%.*s", cbData, pch));
+    else
+        Log(("%.*s", cbData, pch));
+    if (pcbDataReturned)
+        *pcbDataReturned = 0;
+    return VINF_SUCCESS;
+}
+
+
+/** @name Guest Capabilities, Mouse Status and Event Filter
+ * @{
+ */
+
+/**
+ * Clears a bit usage tracker (init time).
+ *
+ * @param   pTracker            The tracker to clear.
+ */
+static void vgdrvBitUsageTrackerClear(PVBOXGUESTBITUSAGETRACER pTracker)
+{
+    uint32_t iBit;
+    AssertCompile(sizeof(pTracker->acPerBitUsage) == 32 * sizeof(uint32_t));
+
+    for (iBit = 0; iBit < 32; iBit++)
+        pTracker->acPerBitUsage[iBit] = 0;
+    pTracker->fMask = 0;
+}
+
+
+#ifdef VBOX_STRICT
+/**
+ * Checks that pTracker->fMask is correct and that the usage values are within
+ * the valid range.
+ *
+ * @param   pTracker            The tracker.
+ * @param   cMax                Max valid usage value.
+ * @param   pszWhat             Identifies the tracker in assertions.
+ */
+static void vgdrvBitUsageTrackerCheckMask(PCVBOXGUESTBITUSAGETRACER pTracker, uint32_t cMax, const char *pszWhat)
+{
+    uint32_t fMask = 0;
+    uint32_t iBit;
+    AssertCompile(sizeof(pTracker->acPerBitUsage) == 32 * sizeof(uint32_t));
+
+    for (iBit = 0; iBit < 32; iBit++)
+        if (pTracker->acPerBitUsage[iBit])
+        {
+            fMask |= RT_BIT_32(iBit);
+            AssertMsg(pTracker->acPerBitUsage[iBit] <= cMax,
+                      ("%s: acPerBitUsage[%u]=%#x cMax=%#x\n", pszWhat, iBit, pTracker->acPerBitUsage[iBit], cMax));
+        }
+
+    AssertMsg(fMask == pTracker->fMask, ("%s: %#x vs %#x\n", pszWhat, fMask, pTracker->fMask));
+}
+#endif
+
+
+/**
+ * Applies a change to the bit usage tracker.
+ *
+ *
+ * @returns true if the mask changed, false if not.
+ * @param   pTracker            The bit usage tracker.
+ * @param   fChanged            The bits to change.
+ * @param   fPrevious           The previous value of the bits.
+ * @param   cMax                The max valid usage value for assertions.
+ * @param   pszWhat             Identifies the tracker in assertions.
+ */
+static bool vgdrvBitUsageTrackerChange(PVBOXGUESTBITUSAGETRACER pTracker, uint32_t fChanged, uint32_t fPrevious,
+                                       uint32_t cMax, const char *pszWhat)
+{
+    bool fGlobalChange = false;
+    AssertCompile(sizeof(pTracker->acPerBitUsage) == 32 * sizeof(uint32_t));
+
+    while (fChanged)
+    {
+        uint32_t const iBit     = ASMBitFirstSetU32(fChanged) - 1;
+        uint32_t const fBitMask = RT_BIT_32(iBit);
+        Assert(iBit < 32); Assert(fBitMask & fChanged);
+
+        if (fBitMask & fPrevious)
+        {
+            pTracker->acPerBitUsage[iBit] -= 1;
+            AssertMsg(pTracker->acPerBitUsage[iBit] <= cMax,
+                      ("%s: acPerBitUsage[%u]=%#x cMax=%#x\n", pszWhat, iBit, pTracker->acPerBitUsage[iBit], cMax));
+            if (pTracker->acPerBitUsage[iBit] == 0)
+            {
+                fGlobalChange = true;
+                pTracker->fMask &= ~fBitMask;
+            }
+        }
+        else
+        {
+            pTracker->acPerBitUsage[iBit] += 1;
+            AssertMsg(pTracker->acPerBitUsage[iBit] > 0 && pTracker->acPerBitUsage[iBit] <= cMax,
+                      ("pTracker->acPerBitUsage[%u]=%#x cMax=%#x\n", pszWhat, iBit, pTracker->acPerBitUsage[iBit], cMax));
+            if (pTracker->acPerBitUsage[iBit] == 1)
+            {
+                fGlobalChange = true;
+                pTracker->fMask |= fBitMask;
+            }
+        }
+
+        fChanged &= ~fBitMask;
+    }
+
+#ifdef VBOX_STRICT
+    vgdrvBitUsageTrackerCheckMask(pTracker, cMax, pszWhat);
+#endif
+    NOREF(pszWhat); NOREF(cMax);
+    return fGlobalChange;
+}
+
+
+/**
+ * Init and termination worker for resetting the (host) event filter on the host
+ *
+ * @returns VBox status code.
+ * @param   pDevExt         The device extension.
+ * @param   fFixedEvents    Fixed events (init time).
+ */
+static int vgdrvResetEventFilterOnHost(PVBOXGUESTDEVEXT pDevExt, uint32_t fFixedEvents)
+{
+    VMMDevCtlGuestFilterMask *pReq;
+    int rc = VbglGRAlloc((VMMDevRequestHeader **)&pReq, sizeof(*pReq), VMMDevReq_CtlGuestFilterMask);
+    if (RT_SUCCESS(rc))
+    {
+        pReq->u32NotMask = UINT32_MAX & ~fFixedEvents;
+        pReq->u32OrMask  = fFixedEvents;
+        rc = VbglGRPerform(&pReq->header);
+        if (RT_FAILURE(rc))
+            LogRelFunc(("failed with rc=%Rrc\n", rc));
+        VbglGRFree(&pReq->header);
+    }
+    return rc;
+}
+
+
+/**
+ * Changes the event filter mask for the given session.
+ *
+ * This is called in response to VBOXGUEST_IOCTL_CTL_FILTER_MASK as well as to
+ * do session cleanup.
+ *
+ * @returns VBox status code.
+ * @param   pDevExt             The device extension.
+ * @param   pSession            The session.
+ * @param   fOrMask             The events to add.
+ * @param   fNotMask            The events to remove.
+ * @param   fSessionTermination Set if we're called by the session cleanup code.
+ *                              This tweaks the error handling so we perform
+ *                              proper session cleanup even if the host
+ *                              misbehaves.
+ *
+ * @remarks Takes the session spinlock.
+ */
+static int vgdrvSetSessionEventFilter(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION pSession,
+                                      uint32_t fOrMask, uint32_t fNotMask, bool fSessionTermination)
+{
+    VMMDevCtlGuestFilterMask   *pReq;
+    uint32_t                    fChanged;
+    uint32_t                    fPrevious;
+    int                         rc;
+
+    /*
+     * Preallocate a request buffer so we can do all in one go without leaving the spinlock.
+     */
+    rc = VbglGRAlloc((VMMDevRequestHeader **)&pReq, sizeof(*pReq), VMMDevReq_CtlGuestFilterMask);
+    if (RT_SUCCESS(rc))
+    { /* nothing */ }
+    else if (!fSessionTermination)
+    {
+        LogRel(("vgdrvSetSessionFilterMask: VbglGRAlloc failure: %Rrc\n", rc));
+        return rc;
+    }
+    else
+        pReq = NULL; /* Ignore failure, we must do session cleanup. */
+
+
+    RTSpinlockAcquire(pDevExt->SessionSpinlock);
+
+    /*
+     * Apply the changes to the session mask.
+     */
+    fPrevious = pSession->fEventFilter;
+    pSession->fEventFilter |= fOrMask;
+    pSession->fEventFilter &= ~fNotMask;
+
+    /*
+     * If anything actually changed, update the global usage counters.
+     */
+    fChanged = fPrevious ^ pSession->fEventFilter;
+    if (fChanged)
+    {
+        bool fGlobalChange = vgdrvBitUsageTrackerChange(&pDevExt->EventFilterTracker, fChanged, fPrevious,
+                                                        pDevExt->cSessions, "EventFilterTracker");
+
+        /*
+         * If there are global changes, update the event filter on the host.
+         */
+        if (fGlobalChange || pDevExt->fEventFilterHost == UINT32_MAX)
+        {
+            Assert(pReq || fSessionTermination);
+            if (pReq)
+            {
+                pReq->u32OrMask = pDevExt->fFixedEvents | pDevExt->EventFilterTracker.fMask;
+                if (pReq->u32OrMask == pDevExt->fEventFilterHost)
+                    rc = VINF_SUCCESS;
+                else
+                {
+                    pDevExt->fEventFilterHost = pReq->u32OrMask;
+                    pReq->u32NotMask = ~pReq->u32OrMask;
+                    rc = VbglGRPerform(&pReq->header);
+                    if (RT_FAILURE(rc))
+                    {
+                        /*
+                         * Failed, roll back (unless it's session termination time).
+                         */
+                        pDevExt->fEventFilterHost = UINT32_MAX;
+                        if (!fSessionTermination)
+                        {
+                            vgdrvBitUsageTrackerChange(&pDevExt->EventFilterTracker, fChanged, pSession->fEventFilter,
+                                                       pDevExt->cSessions, "EventFilterTracker");
+                            pSession->fEventFilter = fPrevious;
+                        }
+                    }
+                }
+            }
+            else
+                rc = VINF_SUCCESS;
+        }
+    }
+
+    RTSpinlockRelease(pDevExt->SessionSpinlock);
+    if (pReq)
+        VbglGRFree(&pReq->header);
+    return rc;
+}
+
+
+/**
+ * Handle VBOXGUEST_IOCTL_CTL_FILTER_MASK.
+ *
+ * @returns VBox status code.
+ *
+ * @param   pDevExt             The device extension.
+ * @param   pSession            The session.
+ * @param   pInfo               The request.
+ */
+static int vgdrvIoCtl_CtlFilterMask(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION pSession, VBoxGuestFilterMaskInfo *pInfo)
+{
+    LogFlow(("VBOXGUEST_IOCTL_CTL_FILTER_MASK: or=%#x not=%#x\n", pInfo->u32OrMask, pInfo->u32NotMask));
+
+    if ((pInfo->u32OrMask | pInfo->u32NotMask) & ~VMMDEV_EVENT_VALID_EVENT_MASK)
+    {
+        Log(("VBOXGUEST_IOCTL_CTL_FILTER_MASK: or=%#x not=%#x: Invalid masks!\n", pInfo->u32OrMask, pInfo->u32NotMask));
+        return VERR_INVALID_PARAMETER;
+    }
+
+    return vgdrvSetSessionEventFilter(pDevExt, pSession, pInfo->u32OrMask, pInfo->u32NotMask, false /*fSessionTermination*/);
+}
+
+
+/**
+ * Init and termination worker for set mouse feature status to zero on the host.
+ *
+ * @returns VBox status code.
+ * @param   pDevExt         The device extension.
+ */
+static int vgdrvResetMouseStatusOnHost(PVBOXGUESTDEVEXT pDevExt)
+{
+    VMMDevReqMouseStatus *pReq;
+    int rc = VbglGRAlloc((VMMDevRequestHeader **)&pReq, sizeof(*pReq), VMMDevReq_SetMouseStatus);
+    if (RT_SUCCESS(rc))
+    {
+        pReq->mouseFeatures = 0;
+        pReq->pointerXPos   = 0;
+        pReq->pointerYPos   = 0;
+        rc = VbglGRPerform(&pReq->header);
+        if (RT_FAILURE(rc))
+            LogRelFunc(("failed with rc=%Rrc\n", rc));
+        VbglGRFree(&pReq->header);
+    }
+    return rc;
+}
+
+
+/**
+ * Changes the mouse status mask for the given session.
+ *
+ * This is called in response to VBOXGUEST_IOCTL_SET_MOUSE_STATUS as well as to
+ * do session cleanup.
+ *
+ * @returns VBox status code.
+ * @param   pDevExt             The device extension.
+ * @param   pSession            The session.
+ * @param   fOrMask             The status flags to add.
+ * @param   fNotMask            The status flags to remove.
+ * @param   fSessionTermination Set if we're called by the session cleanup code.
+ *                              This tweaks the error handling so we perform
+ *                              proper session cleanup even if the host
+ *                              misbehaves.
+ *
+ * @remarks Takes the session spinlock.
+ */
+static int vgdrvSetSessionMouseStatus(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION pSession,
+                                      uint32_t fOrMask, uint32_t fNotMask, bool fSessionTermination)
+{
+    VMMDevReqMouseStatus   *pReq;
+    uint32_t                fChanged;
+    uint32_t                fPrevious;
+    int                     rc;
+
+    /*
+     * Preallocate a request buffer so we can do all in one go without leaving the spinlock.
+     */
+    rc = VbglGRAlloc((VMMDevRequestHeader **)&pReq, sizeof(*pReq), VMMDevReq_SetMouseStatus);
+    if (RT_SUCCESS(rc))
+    { /* nothing */ }
+    else if (!fSessionTermination)
+    {
+        LogRel(("vgdrvSetSessionMouseStatus: VbglGRAlloc failure: %Rrc\n", rc));
+        return rc;
+    }
+    else
+        pReq = NULL; /* Ignore failure, we must do session cleanup. */
+
+
+    RTSpinlockAcquire(pDevExt->SessionSpinlock);
+
+    /*
+     * Apply the changes to the session mask.
+     */
+    fPrevious = pSession->fMouseStatus;
+    pSession->fMouseStatus |= fOrMask;
+    pSession->fMouseStatus &= ~fNotMask;
+
+    /*
+     * If anything actually changed, update the global usage counters.
+     */
+    fChanged = fPrevious ^ pSession->fMouseStatus;
+    if (fChanged)
+    {
+        bool fGlobalChange = vgdrvBitUsageTrackerChange(&pDevExt->MouseStatusTracker, fChanged, fPrevious,
+                                                        pDevExt->cSessions, "MouseStatusTracker");
+
+        /*
+         * If there are global changes, update the event filter on the host.
+         */
+        if (fGlobalChange || pDevExt->fMouseStatusHost == UINT32_MAX)
+        {
+            Assert(pReq || fSessionTermination);
+            if (pReq)
+            {
+                pReq->mouseFeatures = pDevExt->MouseStatusTracker.fMask;
+                if (pReq->mouseFeatures == pDevExt->fMouseStatusHost)
+                    rc = VINF_SUCCESS;
+                else
+                {
+                    pDevExt->fMouseStatusHost = pReq->mouseFeatures;
+                    pReq->pointerXPos = 0;
+                    pReq->pointerYPos = 0;
+                    rc = VbglGRPerform(&pReq->header);
+                    if (RT_FAILURE(rc))
+                    {
+                        /*
+                         * Failed, roll back (unless it's session termination time).
+                         */
+                        pDevExt->fMouseStatusHost = UINT32_MAX;
+                        if (!fSessionTermination)
+                        {
+                            vgdrvBitUsageTrackerChange(&pDevExt->MouseStatusTracker, fChanged, pSession->fMouseStatus,
+                                                       pDevExt->cSessions, "MouseStatusTracker");
+                            pSession->fMouseStatus = fPrevious;
+                        }
+                    }
+                }
+            }
+            else
+                rc = VINF_SUCCESS;
+        }
+    }
+
+    RTSpinlockRelease(pDevExt->SessionSpinlock);
+    if (pReq)
+        VbglGRFree(&pReq->header);
+    return rc;
+}
+
+
+/**
+ * Sets the mouse status features for this session and updates them globally.
+ *
+ * @returns VBox status code.
+ *
+ * @param   pDevExt             The device extention.
+ * @param   pSession            The session.
+ * @param   fFeatures           New bitmap of enabled features.
+ */
+static int vgdrvIoCtl_SetMouseStatus(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION pSession, uint32_t fFeatures)
+{
+    LogFlow(("VBOXGUEST_IOCTL_SET_MOUSE_STATUS: features=%#x\n", fFeatures));
+
+    if (fFeatures & ~VMMDEV_MOUSE_GUEST_MASK)
+        return VERR_INVALID_PARAMETER;
+
+    return vgdrvSetSessionMouseStatus(pDevExt, pSession, fFeatures, ~fFeatures, false /*fSessionTermination*/);
+}
+
+
+/**
+ * Return the mask of VMM device events that this session is allowed to see (wrt
+ * to "acquire" mode guest capabilities).
+ *
+ * The events associated with guest capabilities in "acquire" mode will be
+ * restricted to sessions which has acquired the respective capabilities.
+ * If someone else tries to wait for acquired events, they won't be woken up
+ * when the event becomes pending.  Should some other thread in the session
+ * acquire the capability while the corresponding event is pending, the waiting
+ * thread will woken up.
+ *
+ * @returns Mask of events valid for the given session.
+ * @param   pDevExt             The device extension.
+ * @param   pSession            The session.
+ *
+ * @remarks Needs only be called when dispatching events in the
+ *          VBOXGUEST_ACQUIRE_STYLE_EVENTS mask.
+ */
+static uint32_t vgdrvGetAllowedEventMaskForSession(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION pSession)
+{
+    uint32_t fAcquireModeGuestCaps;
+    uint32_t fAcquiredGuestCaps;
+    uint32_t fAllowedEvents;
+
+    /*
+     * Note! Reads pSession->fAcquiredGuestCaps and pDevExt->fAcquireModeGuestCaps
+     *       WITHOUT holding VBOXGUESTDEVEXT::SessionSpinlock.
+     */
+    fAcquireModeGuestCaps = ASMAtomicUoReadU32(&pDevExt->fAcquireModeGuestCaps);
+    if (fAcquireModeGuestCaps == 0)
+        return VMMDEV_EVENT_VALID_EVENT_MASK;
+    fAcquiredGuestCaps = ASMAtomicUoReadU32(&pSession->fAcquiredGuestCaps);
+
+    /*
+     * Calculate which events to allow according to the cap config and caps
+     * acquired by the session.
+     */
+    fAllowedEvents = VMMDEV_EVENT_VALID_EVENT_MASK;
+    if (   !(fAcquiredGuestCaps   & VMMDEV_GUEST_SUPPORTS_GRAPHICS)
+        && (fAcquireModeGuestCaps & VMMDEV_GUEST_SUPPORTS_GRAPHICS))
+        fAllowedEvents &= ~VMMDEV_EVENT_DISPLAY_CHANGE_REQUEST;
+
+    if (   !(fAcquiredGuestCaps   & VMMDEV_GUEST_SUPPORTS_SEAMLESS)
+        && (fAcquireModeGuestCaps & VMMDEV_GUEST_SUPPORTS_SEAMLESS))
+        fAllowedEvents &= ~VMMDEV_EVENT_SEAMLESS_MODE_CHANGE_REQUEST;
+
+    return fAllowedEvents;
+}
+
+
+/**
+ * Init and termination worker for set guest capabilities to zero on the host.
+ *
+ * @returns VBox status code.
+ * @param   pDevExt         The device extension.
+ */
+static int vgdrvResetCapabilitiesOnHost(PVBOXGUESTDEVEXT pDevExt)
+{
+    VMMDevReqGuestCapabilities2 *pReq;
+    int rc = VbglGRAlloc((VMMDevRequestHeader **)&pReq, sizeof(*pReq), VMMDevReq_SetGuestCapabilities);
+    if (RT_SUCCESS(rc))
+    {
+        pReq->u32NotMask = UINT32_MAX;
+        pReq->u32OrMask  = 0;
+        rc = VbglGRPerform(&pReq->header);
+
+        if (RT_FAILURE(rc))
+            LogRelFunc(("failed with rc=%Rrc\n", rc));
+        VbglGRFree(&pReq->header);
+    }
+    return rc;
+}
+
+
+/**
+ * Sets the guest capabilities to the host while holding the lock.
+ *
+ * This will ASSUME that we're the ones in charge of the mask, so
+ * we'll simply clear all bits we don't set.
+ *
+ * @returns VBox status code.
+ * @param   pDevExt             The device extension.
+ * @param   pReq                The request.
+ */
+static int vgdrvUpdateCapabilitiesOnHostWithReqAndLock(PVBOXGUESTDEVEXT pDevExt, VMMDevReqGuestCapabilities2 *pReq)
+{
+    int rc;
+
+    pReq->u32OrMask = pDevExt->fAcquiredGuestCaps | pDevExt->SetGuestCapsTracker.fMask;
+    if (pReq->u32OrMask == pDevExt->fGuestCapsHost)
+        rc = VINF_SUCCESS;
+    else
+    {
+        pDevExt->fGuestCapsHost = pReq->u32OrMask;
+        pReq->u32NotMask = ~pReq->u32OrMask;
+        rc = VbglGRPerform(&pReq->header);
+        if (RT_FAILURE(rc))
+            pDevExt->fGuestCapsHost = UINT32_MAX;
+    }
+
+    return rc;
+}
+
+
+/**
+ * Switch a set of capabilities into "acquire" mode and (maybe) acquire them for
+ * the given session.
+ *
+ * This is called in response to VBOXGUEST_IOCTL_GUEST_CAPS_ACQUIRE as well as
+ * to do session cleanup.
+ *
+ * @returns VBox status code.
+ * @param   pDevExt             The device extension.
+ * @param   pSession            The session.
+ * @param   fOrMask             The capabilities to add .
+ * @param   fNotMask            The capabilities to remove.  Ignored in
+ *                              VBOXGUESTCAPSACQUIRE_FLAGS_CONFIG_ACQUIRE_MODE.
+ * @param   enmFlags            Confusing operation modifier.
+ *                              VBOXGUESTCAPSACQUIRE_FLAGS_NONE means to both
+ *                              configure and acquire/release the capabilities.
+ *                              VBOXGUESTCAPSACQUIRE_FLAGS_CONFIG_ACQUIRE_MODE
+ *                              means only configure capabilities in the
+ *                              @a fOrMask capabilities for "acquire" mode.
+ * @param   fSessionTermination Set if we're called by the session cleanup code.
+ *                              This tweaks the error handling so we perform
+ *                              proper session cleanup even if the host
+ *                              misbehaves.
+ *
+ * @remarks Takes both the session and event spinlocks.
+ */
+static int vgdrvAcquireSessionCapabilities(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION pSession,
+                                           uint32_t fOrMask, uint32_t fNotMask, VBOXGUESTCAPSACQUIRE_FLAGS enmFlags,
+                                           bool fSessionTermination)
+{
+    uint32_t fCurrentOwnedCaps;
+    uint32_t fSessionRemovedCaps;
+    uint32_t fSessionAddedCaps;
+    uint32_t fOtherConflictingCaps;
+    VMMDevReqGuestCapabilities2 *pReq = NULL;
+    int rc;
+
+
+    /*
+     * Validate and adjust input.
+     */
+    if (fOrMask & ~(  VMMDEV_GUEST_SUPPORTS_SEAMLESS
+                    | VMMDEV_GUEST_SUPPORTS_GUEST_HOST_WINDOW_MAPPING
+                    | VMMDEV_GUEST_SUPPORTS_GRAPHICS ) )
+    {
+        LogRel(("vgdrvAcquireSessionCapabilities: pSession=%p fOrMask=%#x fNotMask=%#x enmFlags=%#x -- invalid fOrMask\n",
+                pSession, fOrMask, fNotMask, enmFlags));
+        return VERR_INVALID_PARAMETER;
+    }
+
+    if (   enmFlags != VBOXGUESTCAPSACQUIRE_FLAGS_CONFIG_ACQUIRE_MODE
+        && enmFlags != VBOXGUESTCAPSACQUIRE_FLAGS_NONE)
+    {
+        LogRel(("vgdrvAcquireSessionCapabilities: pSession=%p fOrMask=%#x fNotMask=%#x enmFlags=%#x: invalid enmFlags %d\n",
+                pSession, fOrMask, fNotMask, enmFlags));
+        return VERR_INVALID_PARAMETER;
+    }
+    Assert(!fOrMask || !fSessionTermination);
+
+    /* The fNotMask no need to have all values valid, invalid ones will simply be ignored. */
+    fNotMask &= ~fOrMask;
+
+    /*
+     * Preallocate a update request if we're about to do more than just configure
+     * the capability mode.
+     */
+    if (enmFlags != VBOXGUESTCAPSACQUIRE_FLAGS_CONFIG_ACQUIRE_MODE)
+    {
+        rc = VbglGRAlloc((VMMDevRequestHeader **)&pReq, sizeof(*pReq), VMMDevReq_SetGuestCapabilities);
+        if (RT_SUCCESS(rc))
+        { /* do nothing */ }
+        else if (!fSessionTermination)
+        {
+            LogRel(("vgdrvAcquireSessionCapabilities: pSession=%p fOrMask=%#x fNotMask=%#x enmFlags=%#x: VbglGRAlloc failure: %Rrc\n",
+                    pSession, fOrMask, fNotMask, enmFlags, rc));
+            return rc;
+        }
+        else
+            pReq = NULL; /* Ignore failure, we must do session cleanup. */
+    }
+
+    /*
+     * Try switch the capabilities in the OR mask into "acquire" mode.
+     *
+     * Note! We currently ignore anyone which may already have "set" the capabilities
+     *       in fOrMask.  Perhaps not the best way to handle it, but it's simple...
+     */
+    RTSpinlockAcquire(pDevExt->EventSpinlock);
+
+    if (!(pDevExt->fSetModeGuestCaps & fOrMask))
+        pDevExt->fAcquireModeGuestCaps |= fOrMask;
+    else
+    {
+        RTSpinlockRelease(pDevExt->EventSpinlock);
+
+        if (pReq)
+            VbglGRFree(&pReq->header);
+        AssertMsgFailed(("Trying to change caps mode: %#x\n", fOrMask));
+        LogRel(("vgdrvAcquireSessionCapabilities: pSession=%p fOrMask=%#x fNotMask=%#x enmFlags=%#x: calling caps acquire for set caps\n",
+                pSession, fOrMask, fNotMask, enmFlags));
+        return VERR_INVALID_STATE;
+    }
+
+    /*
+     * If we only wanted to switch the capabilities into "acquire" mode, we're done now.
+     */
+    if (enmFlags & VBOXGUESTCAPSACQUIRE_FLAGS_CONFIG_ACQUIRE_MODE)
+    {
+        RTSpinlockRelease(pDevExt->EventSpinlock);
+
+        Assert(!pReq);
+        Log(("vgdrvAcquireSessionCapabilities: pSession=%p fOrMask=%#x fNotMask=%#x enmFlags=%#x: configured acquire caps: 0x%x\n",
+             pSession, fOrMask, fNotMask, enmFlags));
+        return VINF_SUCCESS;
+    }
+    Assert(pReq || fSessionTermination);
+
+    /*
+     * Caller wants to acquire/release the capabilities too.
+     *
+     * Note! The mode change of the capabilities above won't be reverted on
+     *       failure, this is intentional.
+     */
+    fCurrentOwnedCaps      = pSession->fAcquiredGuestCaps;
+    fSessionRemovedCaps    = fCurrentOwnedCaps & fNotMask;
+    fSessionAddedCaps      = fOrMask & ~fCurrentOwnedCaps;
+    fOtherConflictingCaps  = pDevExt->fAcquiredGuestCaps & ~fCurrentOwnedCaps;
+    fOtherConflictingCaps &= fSessionAddedCaps;
+
+    if (!fOtherConflictingCaps)
+    {
+        if (fSessionAddedCaps)
+        {
+            pSession->fAcquiredGuestCaps |= fSessionAddedCaps;
+            pDevExt->fAcquiredGuestCaps  |= fSessionAddedCaps;
+        }
+
+        if (fSessionRemovedCaps)
+        {
+            pSession->fAcquiredGuestCaps &= ~fSessionRemovedCaps;
+            pDevExt->fAcquiredGuestCaps  &= ~fSessionRemovedCaps;
+        }
+
+        /*
+         * If something changes (which is very likely), tell the host.
+         */
+        if (fSessionAddedCaps || fSessionRemovedCaps || pDevExt->fGuestCapsHost == UINT32_MAX)
+        {
+            Assert(pReq || fSessionTermination);
+            if (pReq)
+            {
+                rc = vgdrvUpdateCapabilitiesOnHostWithReqAndLock(pDevExt, pReq);
+                if (RT_FAILURE(rc) && !fSessionTermination)
+                {
+                    /* Failed, roll back. */
+                    if (fSessionAddedCaps)
+                    {
+                        pSession->fAcquiredGuestCaps &= ~fSessionAddedCaps;
+                        pDevExt->fAcquiredGuestCaps  &= ~fSessionAddedCaps;
+                    }
+                    if (fSessionRemovedCaps)
+                    {
+                        pSession->fAcquiredGuestCaps |= fSessionRemovedCaps;
+                        pDevExt->fAcquiredGuestCaps  |= fSessionRemovedCaps;
+                    }
+
+                    RTSpinlockRelease(pDevExt->EventSpinlock);
+                    LogRel(("vgdrvAcquireSessionCapabilities: vgdrvUpdateCapabilitiesOnHostWithReqAndLock failed: rc=%Rrc\n", rc));
+                    VbglGRFree(&pReq->header);
+                    return rc;
+                }
+            }
+        }
+    }
+    else
+    {
+        RTSpinlockRelease(pDevExt->EventSpinlock);
+
+        Log(("vgdrvAcquireSessionCapabilities: Caps %#x were busy\n", fOtherConflictingCaps));
+        VbglGRFree(&pReq->header);
+        return VERR_RESOURCE_BUSY;
+    }
+
+    RTSpinlockRelease(pDevExt->EventSpinlock);
+    if (pReq)
+        VbglGRFree(&pReq->header);
+
+    /*
+     * If we added a capability, check if that means some other thread in our
+     * session should be unblocked because there are events pending.
+     *
+     * HACK ALERT! When the seamless support capability is added we generate a
+     *             seamless change event so that the ring-3 client can sync with
+     *             the seamless state. Although this introduces a spurious
+     *             wakeups of the ring-3 client, it solves the problem of client
+     *             state inconsistency in multiuser environment (on Windows).
+     */
+    if (fSessionAddedCaps)
+    {
+        uint32_t fGenFakeEvents = 0;
+        if (fSessionAddedCaps & VMMDEV_GUEST_SUPPORTS_SEAMLESS)
+            fGenFakeEvents |= VMMDEV_EVENT_SEAMLESS_MODE_CHANGE_REQUEST;
+
+        RTSpinlockAcquire(pDevExt->EventSpinlock);
+        if (fGenFakeEvents || pDevExt->f32PendingEvents)
+            vgdrvDispatchEventsLocked(pDevExt, fGenFakeEvents);
+        RTSpinlockRelease(pDevExt->EventSpinlock);
+
+#ifdef VBOXGUEST_USE_DEFERRED_WAKE_UP
+        VGDrvCommonWaitDoWakeUps(pDevExt);
+#endif
+    }
+
+    return VINF_SUCCESS;
+}
+
+
+/**
+ * Handle VBOXGUEST_IOCTL_GUEST_CAPS_ACQUIRE.
+ *
+ * @returns VBox status code.
+ *
+ * @param   pDevExt             The device extension.
+ * @param   pSession            The session.
+ * @param   pAcquire            The request.
+ */
+static int vgdrvIoCtl_GuestCapsAcquire(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION pSession, VBoxGuestCapsAquire *pAcquire)
+{
+    int rc;
+    LogFlow(("VBOXGUEST_IOCTL_GUEST_CAPS_ACQUIRE: or=%#x not=%#x flags=%#x\n",
+             pAcquire->u32OrMask, pAcquire->u32NotMask, pAcquire->enmFlags));
+
+    rc = vgdrvAcquireSessionCapabilities(pDevExt, pSession, pAcquire->u32OrMask, pAcquire->u32NotMask, pAcquire->enmFlags,
+                                         false /*fSessionTermination*/);
+    if (RT_FAILURE(rc))
+        LogRel(("VGDrvCommonIoCtl: GUEST_CAPS_ACQUIRE failed rc=%Rrc\n", rc));
+    pAcquire->rc = rc;
+    return VINF_SUCCESS;
+}
+
+
+/**
+ * Sets the guest capabilities for a session.
+ *
+ * @returns VBox status code.
+ * @param   pDevExt             The device extension.
+ * @param   pSession            The session.
+ * @param   fOrMask             The capabilities to add.
+ * @param   fNotMask            The capabilities to remove.
+ * @param   fSessionTermination Set if we're called by the session cleanup code.
+ *                              This tweaks the error handling so we perform
+ *                              proper session cleanup even if the host
+ *                              misbehaves.
+ *
+ * @remarks Takes the session spinlock.
+ */
+static int vgdrvSetSessionCapabilities(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION pSession,
+                                       uint32_t fOrMask, uint32_t fNotMask, bool fSessionTermination)
+{
+    /*
+     * Preallocate a request buffer so we can do all in one go without leaving the spinlock.
+     */
+    VMMDevReqGuestCapabilities2 *pReq;
+    int rc = VbglGRAlloc((VMMDevRequestHeader **)&pReq, sizeof(*pReq), VMMDevReq_SetGuestCapabilities);
+    if (RT_SUCCESS(rc))
+    { /* nothing */ }
+    else if (!fSessionTermination)
+    {
+        LogRel(("vgdrvSetSessionCapabilities: VbglGRAlloc failure: %Rrc\n", rc));
+        return rc;
+    }
+    else
+        pReq = NULL; /* Ignore failure, we must do session cleanup. */
+
+
+    RTSpinlockAcquire(pDevExt->SessionSpinlock);
+
+#ifndef VBOXGUEST_DISREGARD_ACQUIRE_MODE_GUEST_CAPS
+    /*
+     * Capabilities in "acquire" mode cannot be set via this API.
+     * (Acquire mode is only used on windows at the time of writing.)
+     */
+    if (!(fOrMask & pDevExt->fAcquireModeGuestCaps))
+#endif
+    {
+        /*
+         * Apply the changes to the session mask.
+         */
+        uint32_t fChanged;
+        uint32_t fPrevious = pSession->fCapabilities;
+        pSession->fCapabilities |= fOrMask;
+        pSession->fCapabilities &= ~fNotMask;
+
+        /*
+         * If anything actually changed, update the global usage counters.
+         */
+        fChanged = fPrevious ^ pSession->fCapabilities;
+        if (fChanged)
+        {
+            bool fGlobalChange = vgdrvBitUsageTrackerChange(&pDevExt->SetGuestCapsTracker, fChanged, fPrevious,
+                                                            pDevExt->cSessions, "SetGuestCapsTracker");
+
+            /*
+             * If there are global changes, update the capabilities on the host.
+             */
+            if (fGlobalChange || pDevExt->fGuestCapsHost == UINT32_MAX)
+            {
+                Assert(pReq || fSessionTermination);
+                if (pReq)
+                {
+                    rc = vgdrvUpdateCapabilitiesOnHostWithReqAndLock(pDevExt, pReq);
+
+                    /* On failure, roll back (unless it's session termination time). */
+                    if (RT_FAILURE(rc) && !fSessionTermination)
+                    {
+                        vgdrvBitUsageTrackerChange(&pDevExt->SetGuestCapsTracker, fChanged, pSession->fCapabilities,
+                                                   pDevExt->cSessions, "SetGuestCapsTracker");
+                        pSession->fCapabilities = fPrevious;
+                    }
+                }
+            }
+        }
+    }
+#ifndef VBOXGUEST_DISREGARD_ACQUIRE_MODE_GUEST_CAPS
+    else
+        rc = VERR_RESOURCE_BUSY;
+#endif
+
+    RTSpinlockRelease(pDevExt->SessionSpinlock);
+    if (pReq)
+        VbglGRFree(&pReq->header);
+    return rc;
+}
+
+
+/**
+ * Handle VBOXGUEST_IOCTL_SET_GUEST_CAPABILITIES.
+ *
+ * @returns VBox status code.
+ *
+ * @param   pDevExt             The device extension.
+ * @param   pSession            The session.
+ * @param   pInfo               The request.
+ */
+static int vgdrvIoCtl_SetCapabilities(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION pSession, VBoxGuestSetCapabilitiesInfo *pInfo)
+{
+    int rc;
+    LogFlow(("VBOXGUEST_IOCTL_SET_GUEST_CAPABILITIES: or=%#x not=%#x\n", pInfo->u32OrMask, pInfo->u32NotMask));
+
+    if (!((pInfo->u32OrMask | pInfo->u32NotMask) & ~VMMDEV_GUEST_CAPABILITIES_MASK))
+        rc = vgdrvSetSessionCapabilities(pDevExt, pSession, pInfo->u32OrMask, pInfo->u32NotMask, false /*fSessionTermination*/);
+    else
+        rc = VERR_INVALID_PARAMETER;
+
+    return rc;
+}
+
+/** @} */
+
+
+/**
+ * Common IOCtl for user to kernel and kernel to kernel communication.
+ *
+ * This function only does the basic validation and then invokes
+ * worker functions that takes care of each specific function.
+ *
+ * @returns VBox status code.
+ *
+ * @param   iFunction           The requested function.
+ * @param   pDevExt             The device extension.
+ * @param   pSession            The client session.
+ * @param   pvData              The input/output data buffer. Can be NULL depending on the function.
+ * @param   cbData              The max size of the data buffer.
+ * @param   pcbDataReturned     Where to store the amount of returned data. Can be NULL.
+ */
+int VGDrvCommonIoCtl(unsigned iFunction, PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION pSession,
+                     void *pvData, size_t cbData, size_t *pcbDataReturned)
+{
+    int rc;
+    LogFlow(("VGDrvCommonIoCtl: iFunction=%#x pDevExt=%p pSession=%p pvData=%p cbData=%zu\n",
+             iFunction, pDevExt, pSession, pvData, cbData));
+
+    /*
+     * Make sure the returned data size is set to zero.
+     */
+    if (pcbDataReturned)
+        *pcbDataReturned = 0;
+
+    /*
+     * Define some helper macros to simplify validation.
+     */
+#define CHECKRET_RING0(mnemonic) \
+    do { \
+        if (pSession->R0Process != NIL_RTR0PROCESS) \
+        { \
+            LogFunc((mnemonic ": Ring-0 only, caller is %RTproc/%p\n", \
+                     pSession->Process, (uintptr_t)pSession->R0Process)); \
+            return VERR_PERMISSION_DENIED; \
+        } \
+    } while (0)
+#define CHECKRET_MIN_SIZE(mnemonic, cbMin) \
+    do { \
+        if (cbData < (cbMin)) \
+        { \
+            LogFunc((mnemonic ": cbData=%#zx (%zu) min is %#zx (%zu)\n", \
+                     cbData, cbData, (size_t)(cbMin), (size_t)(cbMin))); \
+            return VERR_BUFFER_OVERFLOW; \
+        } \
+        if ((cbMin) != 0 && !VALID_PTR(pvData)) \
+        { \
+            LogFunc((mnemonic ": Invalid pointer %p\n", pvData)); \
+            return VERR_INVALID_POINTER; \
+        } \
+    } while (0)
+#define CHECKRET_SIZE(mnemonic, cb) \
+    do { \
+        if (cbData != (cb)) \
+        { \
+            LogFunc((mnemonic ": cbData=%#zx (%zu) expected is %#zx (%zu)\n", \
+                     cbData, cbData, (size_t)(cb), (size_t)(cb))); \
+            return VERR_BUFFER_OVERFLOW; \
+        } \
+        if ((cb) != 0 && !VALID_PTR(pvData)) \
+        { \
+            LogFunc((mnemonic ": Invalid pointer %p\n", pvData)); \
+            return VERR_INVALID_POINTER; \
+        } \
+    } while (0)
+
+
+    /*
+     * Deal with variably sized requests first.
+     */
+    rc = VINF_SUCCESS;
+    if (VBOXGUEST_IOCTL_STRIP_SIZE(iFunction) == VBOXGUEST_IOCTL_STRIP_SIZE(VBOXGUEST_IOCTL_VMMREQUEST(0)))
+    {
+        CHECKRET_MIN_SIZE("VMMREQUEST", sizeof(VMMDevRequestHeader));
+        rc = vgdrvIoCtl_VMMRequest(pDevExt, pSession, (VMMDevRequestHeader *)pvData, cbData, pcbDataReturned);
+    }
+#ifdef VBOX_WITH_HGCM
+    /*
+     * These ones are a bit tricky.
+     */
+    else if (VBOXGUEST_IOCTL_STRIP_SIZE(iFunction) == VBOXGUEST_IOCTL_STRIP_SIZE(VBOXGUEST_IOCTL_HGCM_CALL(0)))
+    {
+        bool fInterruptible = pSession->R0Process != NIL_RTR0PROCESS;
+        CHECKRET_MIN_SIZE("HGCM_CALL", sizeof(VBoxGuestHGCMCallInfo));
+        rc = vgdrvIoCtl_HGCMCall(pDevExt, pSession, (VBoxGuestHGCMCallInfo *)pvData, RT_INDEFINITE_WAIT,
+                                 fInterruptible, false /*f32bit*/, false /* fUserData */,
+                                 0, cbData, pcbDataReturned);
+    }
+    else if (VBOXGUEST_IOCTL_STRIP_SIZE(iFunction) == VBOXGUEST_IOCTL_STRIP_SIZE(VBOXGUEST_IOCTL_HGCM_CALL_TIMED(0)))
+    {
+        VBoxGuestHGCMCallInfoTimed *pInfo = (VBoxGuestHGCMCallInfoTimed *)pvData;
+        CHECKRET_MIN_SIZE("HGCM_CALL_TIMED", sizeof(VBoxGuestHGCMCallInfoTimed));
+        rc = vgdrvIoCtl_HGCMCall(pDevExt, pSession, &pInfo->info, pInfo->u32Timeout,
+                                 !!pInfo->fInterruptible || pSession->R0Process != NIL_RTR0PROCESS,
+                                 false /*f32bit*/, false /* fUserData */,
+                                 RT_OFFSETOF(VBoxGuestHGCMCallInfoTimed, info), cbData, pcbDataReturned);
+    }
+    else if (VBOXGUEST_IOCTL_STRIP_SIZE(iFunction) == VBOXGUEST_IOCTL_STRIP_SIZE(VBOXGUEST_IOCTL_HGCM_CALL_USERDATA(0)))
+    {
+        bool fInterruptible = true;
+        CHECKRET_MIN_SIZE("HGCM_CALL", sizeof(VBoxGuestHGCMCallInfo));
+        rc = vgdrvIoCtl_HGCMCall(pDevExt, pSession, (VBoxGuestHGCMCallInfo *)pvData, RT_INDEFINITE_WAIT,
+                                 fInterruptible, false /*f32bit*/, true /* fUserData */,
+                                 0, cbData, pcbDataReturned);
+    }
+# ifdef RT_ARCH_AMD64
+    else if (VBOXGUEST_IOCTL_STRIP_SIZE(iFunction) == VBOXGUEST_IOCTL_STRIP_SIZE(VBOXGUEST_IOCTL_HGCM_CALL_32(0)))
+    {
+        bool fInterruptible = pSession->R0Process != NIL_RTR0PROCESS;
+        CHECKRET_MIN_SIZE("HGCM_CALL", sizeof(VBoxGuestHGCMCallInfo));
+        rc = vgdrvIoCtl_HGCMCall(pDevExt, pSession, (VBoxGuestHGCMCallInfo *)pvData, RT_INDEFINITE_WAIT,
+                                 fInterruptible, true /*f32bit*/, false /* fUserData */,
+                                 0, cbData, pcbDataReturned);
+    }
+    else if (VBOXGUEST_IOCTL_STRIP_SIZE(iFunction) == VBOXGUEST_IOCTL_STRIP_SIZE(VBOXGUEST_IOCTL_HGCM_CALL_TIMED_32(0)))
+    {
+        CHECKRET_MIN_SIZE("HGCM_CALL_TIMED", sizeof(VBoxGuestHGCMCallInfoTimed));
+        VBoxGuestHGCMCallInfoTimed *pInfo = (VBoxGuestHGCMCallInfoTimed *)pvData;
+        rc = vgdrvIoCtl_HGCMCall(pDevExt, pSession, &pInfo->info, pInfo->u32Timeout,
+                                 !!pInfo->fInterruptible || pSession->R0Process != NIL_RTR0PROCESS,
+                                 true /*f32bit*/, false /* fUserData */,
+                                 RT_OFFSETOF(VBoxGuestHGCMCallInfoTimed, info), cbData, pcbDataReturned);
+    }
+# endif
+#endif /* VBOX_WITH_HGCM */
+    else if (VBOXGUEST_IOCTL_STRIP_SIZE(iFunction) == VBOXGUEST_IOCTL_STRIP_SIZE(VBOXGUEST_IOCTL_LOG(0)))
+    {
+        CHECKRET_MIN_SIZE("LOG", 1);
+        rc = vgdrvIoCtl_Log(pDevExt, (char *)pvData, cbData, pcbDataReturned, pSession->fUserSession);
+    }
+    else
+    {
+        switch (iFunction)
+        {
+            case VBOXGUEST_IOCTL_GETVMMDEVPORT:
+                CHECKRET_RING0("GETVMMDEVPORT");
+                CHECKRET_MIN_SIZE("GETVMMDEVPORT", sizeof(VBoxGuestPortInfo));
+                rc = vgdrvIoCtl_GetVMMDevPort(pDevExt, (VBoxGuestPortInfo *)pvData, pcbDataReturned);
+                break;
+
+#ifndef RT_OS_WINDOWS  /* Windows has its own implementation of this. */
+            case VBOXGUEST_IOCTL_SET_MOUSE_NOTIFY_CALLBACK:
+                CHECKRET_RING0("SET_MOUSE_NOTIFY_CALLBACK");
+                CHECKRET_SIZE("SET_MOUSE_NOTIFY_CALLBACK", sizeof(VBoxGuestMouseSetNotifyCallback));
+                rc = vgdrvIoCtl_SetMouseNotifyCallback(pDevExt, (VBoxGuestMouseSetNotifyCallback *)pvData);
+                break;
+#endif
+
+            case VBOXGUEST_IOCTL_WAITEVENT:
+                CHECKRET_MIN_SIZE("WAITEVENT", sizeof(VBoxGuestWaitEventInfo));
+                rc = vgdrvIoCtl_WaitEvent(pDevExt, pSession, (VBoxGuestWaitEventInfo *)pvData,
+                                          pcbDataReturned, pSession->R0Process != NIL_RTR0PROCESS);
+                break;
+
+            case VBOXGUEST_IOCTL_CANCEL_ALL_WAITEVENTS:
+                CHECKRET_SIZE("CANCEL_ALL_WAITEVENTS", 0);
+                rc = vgdrvIoCtl_CancelAllWaitEvents(pDevExt, pSession);
+                break;
+
+            case VBOXGUEST_IOCTL_CTL_FILTER_MASK:
+                CHECKRET_MIN_SIZE("CTL_FILTER_MASK", sizeof(VBoxGuestFilterMaskInfo));
+                rc = vgdrvIoCtl_CtlFilterMask(pDevExt, pSession, (VBoxGuestFilterMaskInfo *)pvData);
+                break;
+
+#ifdef VBOX_WITH_HGCM
+            case VBOXGUEST_IOCTL_HGCM_CONNECT:
+# ifdef RT_ARCH_AMD64
+            case VBOXGUEST_IOCTL_HGCM_CONNECT_32:
+# endif
+                CHECKRET_MIN_SIZE("HGCM_CONNECT", sizeof(VBoxGuestHGCMConnectInfo));
+                rc = vgdrvIoCtl_HGCMConnect(pDevExt, pSession, (VBoxGuestHGCMConnectInfo *)pvData, pcbDataReturned);
+                break;
+
+            case VBOXGUEST_IOCTL_HGCM_DISCONNECT:
+# ifdef RT_ARCH_AMD64
+            case VBOXGUEST_IOCTL_HGCM_DISCONNECT_32:
+# endif
+                CHECKRET_MIN_SIZE("HGCM_DISCONNECT", sizeof(VBoxGuestHGCMDisconnectInfo));
+                rc = vgdrvIoCtl_HGCMDisconnect(pDevExt, pSession, (VBoxGuestHGCMDisconnectInfo *)pvData, pcbDataReturned);
+                break;
+#endif /* VBOX_WITH_HGCM */
+
+            case VBOXGUEST_IOCTL_CHECK_BALLOON:
+                CHECKRET_MIN_SIZE("CHECK_MEMORY_BALLOON", sizeof(VBoxGuestCheckBalloonInfo));
+                rc = vgdrvIoCtl_CheckMemoryBalloon(pDevExt, pSession, (VBoxGuestCheckBalloonInfo *)pvData, pcbDataReturned);
+                break;
+
+            case VBOXGUEST_IOCTL_CHANGE_BALLOON:
+                CHECKRET_MIN_SIZE("CHANGE_MEMORY_BALLOON", sizeof(VBoxGuestChangeBalloonInfo));
+                rc = vgdrvIoCtl_ChangeMemoryBalloon(pDevExt, pSession, (VBoxGuestChangeBalloonInfo *)pvData, pcbDataReturned);
+                break;
+
+            case VBOXGUEST_IOCTL_WRITE_CORE_DUMP:
+                CHECKRET_MIN_SIZE("WRITE_CORE_DUMP", sizeof(VBoxGuestWriteCoreDump));
+                rc = vgdrvIoCtl_WriteCoreDump(pDevExt, (VBoxGuestWriteCoreDump *)pvData);
+                break;
+
+            case VBOXGUEST_IOCTL_SET_MOUSE_STATUS:
+                CHECKRET_SIZE("SET_MOUSE_STATUS", sizeof(uint32_t));
+                rc = vgdrvIoCtl_SetMouseStatus(pDevExt, pSession, *(uint32_t *)pvData);
+                break;
+
+#ifdef VBOX_WITH_DPC_LATENCY_CHECKER
+            case VBOXGUEST_IOCTL_DPC_LATENCY_CHECKER:
+                CHECKRET_SIZE("DPC_LATENCY_CHECKER", 0);
+                rc = VGDrvNtIOCtl_DpcLatencyChecker();
+                break;
+#endif
+
+            case VBOXGUEST_IOCTL_GUEST_CAPS_ACQUIRE:
+                CHECKRET_SIZE("GUEST_CAPS_ACQUIRE", sizeof(VBoxGuestCapsAquire));
+                rc = vgdrvIoCtl_GuestCapsAcquire(pDevExt, pSession, (VBoxGuestCapsAquire *)pvData);
+                *pcbDataReturned = sizeof(VBoxGuestCapsAquire);
+                break;
+
+            case VBOXGUEST_IOCTL_SET_GUEST_CAPABILITIES:
+                CHECKRET_MIN_SIZE("SET_GUEST_CAPABILITIES", sizeof(VBoxGuestSetCapabilitiesInfo));
+                rc = vgdrvIoCtl_SetCapabilities(pDevExt, pSession, (VBoxGuestSetCapabilitiesInfo *)pvData);
+                break;
+
+            default:
+            {
+                LogRel(("VGDrvCommonIoCtl: Unknown request iFunction=%#x stripped size=%#x\n",
+                        iFunction, VBOXGUEST_IOCTL_STRIP_SIZE(iFunction)));
+                rc = VERR_NOT_SUPPORTED;
+                break;
+            }
+        }
+    }
+
+    LogFlow(("VGDrvCommonIoCtl: returns %Rrc *pcbDataReturned=%zu\n", rc, pcbDataReturned ? *pcbDataReturned : 0));
+    return rc;
+}
+
+
+/**
+ * Used by VGDrvCommonISR as well as the acquire guest capability code.
+ *
+ * @returns VINF_SUCCESS on success. On failure, ORed together
+ *          RTSemEventMultiSignal errors (completes processing despite errors).
+ * @param   pDevExt             The VBoxGuest device extension.
+ * @param   fEvents             The events to dispatch.
+ */
+static int vgdrvDispatchEventsLocked(PVBOXGUESTDEVEXT pDevExt, uint32_t fEvents)
+{
+    PVBOXGUESTWAIT  pWait;
+    PVBOXGUESTWAIT  pSafe;
+    int             rc = VINF_SUCCESS;
+
+    fEvents |= pDevExt->f32PendingEvents;
+
+    RTListForEachSafe(&pDevExt->WaitList, pWait, pSafe, VBOXGUESTWAIT, ListNode)
+    {
+        uint32_t fHandledEvents = pWait->fReqEvents & fEvents;
+        if (    fHandledEvents != 0
+            &&  !pWait->fResEvents)
+        {
+            /* Does this one wait on any of the events we're dispatching?  We do a quick
+               check first, then deal with VBOXGUEST_ACQUIRE_STYLE_EVENTS as applicable. */
+            if (fHandledEvents & VBOXGUEST_ACQUIRE_STYLE_EVENTS)
+                fHandledEvents &= vgdrvGetAllowedEventMaskForSession(pDevExt, pWait->pSession);
+            if (fHandledEvents)
+            {
+                pWait->fResEvents = pWait->fReqEvents & fEvents & fHandledEvents;
+                fEvents &= ~pWait->fResEvents;
+                RTListNodeRemove(&pWait->ListNode);
+#ifdef VBOXGUEST_USE_DEFERRED_WAKE_UP
+                RTListAppend(&pDevExt->WakeUpList, &pWait->ListNode);
+#else
+                RTListAppend(&pDevExt->WokenUpList, &pWait->ListNode);
+                rc |= RTSemEventMultiSignal(pWait->Event);
+#endif
+                if (!fEvents)
+                    break;
+            }
+        }
+    }
+
+    ASMAtomicWriteU32(&pDevExt->f32PendingEvents, fEvents);
+    return rc;
+}
+
+
+/**
+ * Common interrupt service routine.
+ *
+ * This deals with events and with waking up thread waiting for those events.
+ *
+ * @returns true if it was our interrupt, false if it wasn't.
+ * @param   pDevExt     The VBoxGuest device extension.
+ */
+bool VGDrvCommonISR(PVBOXGUESTDEVEXT pDevExt)
+{
+    VMMDevEvents volatile  *pReq                  = pDevExt->pIrqAckEvents;
+    bool                    fMousePositionChanged = false;
+    int                     rc                    = 0;
+    bool                    fOurIrq;
+
+    /*
+     * Make sure we've initialized the device extension.
+     */
+    if (RT_UNLIKELY(!pReq))
+        return false;
+
+    /*
+     * Enter the spinlock and check if it's our IRQ or not.
+     */
+    RTSpinlockAcquire(pDevExt->EventSpinlock);
+    fOurIrq = pDevExt->pVMMDevMemory->V.V1_04.fHaveEvents;
+    if (fOurIrq)
+    {
+        /*
+         * Acknowlegde events.
+         * We don't use VbglGRPerform here as it may take another spinlocks.
+         */
+        pReq->header.rc = VERR_INTERNAL_ERROR;
+        pReq->events    = 0;
+        ASMCompilerBarrier();
+        ASMOutU32(pDevExt->IOPortBase + VMMDEV_PORT_OFF_REQUEST, (uint32_t)pDevExt->PhysIrqAckEvents);
+        ASMCompilerBarrier();   /* paranoia */
+        if (RT_SUCCESS(pReq->header.rc))
+        {
+            uint32_t        fEvents = pReq->events;
+
+            Log3(("VGDrvCommonISR: acknowledge events succeeded %#RX32\n", fEvents));
+
+            /*
+             * VMMDEV_EVENT_MOUSE_POSITION_CHANGED can only be polled for.
+             */
+            if (fEvents & VMMDEV_EVENT_MOUSE_POSITION_CHANGED)
+            {
+                fMousePositionChanged = true;
+                fEvents &= ~VMMDEV_EVENT_MOUSE_POSITION_CHANGED;
+#ifndef RT_OS_WINDOWS
+                if (pDevExt->MouseNotifyCallback.pfnNotify)
+                    pDevExt->MouseNotifyCallback.pfnNotify(pDevExt->MouseNotifyCallback.pvUser);
+#endif
+            }
+
+#ifdef VBOX_WITH_HGCM
+            /*
+             * The HGCM event/list is kind of different in that we evaluate all entries.
+             */
+            if (fEvents & VMMDEV_EVENT_HGCM)
+            {
+                PVBOXGUESTWAIT pWait;
+                PVBOXGUESTWAIT pSafe;
+                RTListForEachSafe(&pDevExt->HGCMWaitList, pWait, pSafe, VBOXGUESTWAIT, ListNode)
+                {
+                    if (pWait->pHGCMReq->fu32Flags & VBOX_HGCM_REQ_DONE)
+                    {
+                        pWait->fResEvents = VMMDEV_EVENT_HGCM;
+                        RTListNodeRemove(&pWait->ListNode);
+# ifdef VBOXGUEST_USE_DEFERRED_WAKE_UP
+                        RTListAppend(&pDevExt->WakeUpList, &pWait->ListNode);
+# else
+                        RTListAppend(&pDevExt->WokenUpList, &pWait->ListNode);
+                        rc |= RTSemEventMultiSignal(pWait->Event);
+# endif
+                    }
+                }
+                fEvents &= ~VMMDEV_EVENT_HGCM;
+            }
+#endif
+
+            /*
+             * Normal FIFO waiter evaluation.
+             */
+            rc |= vgdrvDispatchEventsLocked(pDevExt, fEvents);
+        }
+        else /* something is serious wrong... */
+            Log(("VGDrvCommonISR: acknowledge events failed rc=%Rrc (events=%#x)!!\n",
+                 pReq->header.rc, pReq->events));
+    }
+    else
+        Log3(("VGDrvCommonISR: not ours\n"));
+
+    RTSpinlockRelease(pDevExt->EventSpinlock);
+
+#if defined(VBOXGUEST_USE_DEFERRED_WAKE_UP) && !defined(RT_OS_DARWIN) && !defined(RT_OS_WINDOWS)
+    /*
+     * Do wake-ups.
+     * Note. On Windows this isn't possible at this IRQL, so a DPC will take
+     *       care of it.  Same on darwin, doing it in the work loop callback.
+     */
+    VGDrvCommonWaitDoWakeUps(pDevExt);
+#endif
+
+    /*
+     * Work the poll and async notification queues on OSes that implements that.
+     * (Do this outside the spinlock to prevent some recursive spinlocking.)
+     */
+    if (fMousePositionChanged)
+    {
+        ASMAtomicIncU32(&pDevExt->u32MousePosChangedSeq);
+        VGDrvNativeISRMousePollEvent(pDevExt);
+    }
+
+    Assert(rc == 0);
+    NOREF(rc);
+    return fOurIrq;
+}
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/vboxguest/VBoxGuestIDC-unix.c.h
@@ -0,0 +1,147 @@
+/* $Rev: 103598 $ */
+/** @file
+ * VBoxGuest - Inter Driver Communication, unix implementation.
+ *
+ * This file is included by the platform specific source file.
+ */
+
+/*
+ * Copyright (C) 2006-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+
+/** @todo Use some header that we have in common with VBoxGuestLib.h... */
+/** @todo fix DECLVBGL usage. */
+RT_C_DECLS_BEGIN
+DECLEXPORT(void *) VBOXCALL VBoxGuestIDCOpen(uint32_t *pu32Version);
+DECLEXPORT(int) VBOXCALL VBoxGuestIDCClose(void *pvSession);
+DECLEXPORT(int) VBOXCALL VBoxGuestIDCCall(void *pvSession, unsigned iCmd, void *pvData, size_t cbData, size_t *pcbDataReturned);
+RT_C_DECLS_END
+
+
+/**
+ * Open a new IDC connection.
+ *
+ * @returns Opaque pointer to session object.
+ * @param   pu32Version         Where to store VMMDev version.
+ */
+DECLEXPORT(void *) VBOXCALL VBoxGuestIDCOpen(uint32_t *pu32Version)
+{
+    PVBOXGUESTSESSION   pSession;
+    int                 rc;
+    LogFlow(("VBoxGuestIDCOpen: Version=%#x\n", pu32Version ? *pu32Version : 0));
+
+    AssertPtrReturn(pu32Version, NULL);
+
+#ifdef RT_OS_SOLARIS
+    mutex_enter(&g_LdiMtx);
+    if (!g_LdiHandle)
+    {
+        ldi_ident_t DevIdent = ldi_ident_from_anon();
+        rc = ldi_open_by_name(VBOXGUEST_DEVICE_NAME, FREAD, kcred, &g_LdiHandle, DevIdent);
+        ldi_ident_release(DevIdent);
+        if (rc)
+        {
+            LogRel(("VBoxGuestIDCOpen: ldi_open_by_name failed. rc=%d\n", rc));
+            mutex_exit(&g_LdiMtx);
+            return NULL;
+        }
+    }
+    ++g_cLdiOpens;
+    mutex_exit(&g_LdiMtx);
+#endif
+
+    rc = VGDrvCommonCreateKernelSession(&g_DevExt, &pSession);
+    if (RT_SUCCESS(rc))
+    {
+        *pu32Version = VMMDEV_VERSION;
+        return pSession;
+    }
+
+#ifdef RT_OS_SOLARIS
+    mutex_enter(&g_LdiMtx);
+    if (g_cLdiOpens > 0)
+        --g_cLdiOpens;
+    if (   g_cLdiOpens == 0
+        && g_LdiHandle)
+    {
+        ldi_close(g_LdiHandle, FREAD, kcred);
+        g_LdiHandle = NULL;
+    }
+    mutex_exit(&g_LdiMtx);
+#endif
+
+    LogRel(("VBoxGuestIDCOpen: VGDrvCommonCreateKernelSession failed. rc=%d\n", rc));
+    return NULL;
+}
+
+
+/**
+ * Close an IDC connection.
+ *
+ * @returns VBox error code.
+ * @param   pvSession           Opaque pointer to the session object.
+ */
+DECLEXPORT(int) VBOXCALL VBoxGuestIDCClose(void *pvSession)
+{
+    PVBOXGUESTSESSION pSession = (PVBOXGUESTSESSION)pvSession;
+    LogFlow(("VBoxGuestIDCClose: pvSession=%p\n", pvSession));
+
+    AssertPtrReturn(pSession, VERR_INVALID_POINTER);
+    VGDrvCommonCloseSession(&g_DevExt, pSession);
+
+#ifdef RT_OS_SOLARIS
+    mutex_enter(&g_LdiMtx);
+    if (g_cLdiOpens > 0)
+        --g_cLdiOpens;
+    if (   g_cLdiOpens == 0
+        && g_LdiHandle)
+    {
+        ldi_close(g_LdiHandle, FREAD, kcred);
+        g_LdiHandle = NULL;
+    }
+    mutex_exit(&g_LdiMtx);
+#endif
+
+    return VINF_SUCCESS;
+}
+
+
+/**
+ * Perform an IDC call.
+ *
+ * @returns VBox error code.
+ * @param   pvSession           Opaque pointer to the session.
+ * @param   iCmd                Requested function.
+ * @param   pvData              IO data buffer.
+ * @param   cbData              Size of the data buffer.
+ * @param   pcbDataReturned     Where to store the amount of returned data.
+ */
+DECLEXPORT(int) VBOXCALL VBoxGuestIDCCall(void *pvSession, unsigned iCmd, void *pvData, size_t cbData, size_t *pcbDataReturned)
+{
+    PVBOXGUESTSESSION pSession = (PVBOXGUESTSESSION)pvSession;
+    LogFlow(("VBoxGuestIDCCall: %pvSession=%p Cmd=%u pvData=%p cbData=%d\n", pvSession, iCmd, pvData, cbData));
+
+    AssertPtrReturn(pSession, VERR_INVALID_POINTER);
+    AssertMsgReturn(pSession->pDevExt == &g_DevExt, ("SC: %p != %p\n", pSession->pDevExt, &g_DevExt), VERR_INVALID_HANDLE);
+
+    return VGDrvCommonIoCtl(iCmd, &g_DevExt, pSession, pvData, cbData, pcbDataReturned);
+}
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/vboxguest/VBoxGuestInternal.h
@@ -0,0 +1,351 @@
+/* $Id: VBoxGuestInternal.h $ */
+/** @file
+ * VBoxGuest - Guest Additions Driver, Internal Header.
+ */
+
+/*
+ * Copyright (C) 2010-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+#ifndef ___VBoxGuestInternal_h
+#define ___VBoxGuestInternal_h
+
+#include <iprt/types.h>
+#include <iprt/list.h>
+#include <iprt/semaphore.h>
+#include <iprt/spinlock.h>
+#include <iprt/timer.h>
+#include <VBox/VMMDev.h>
+#include <VBox/VBoxGuest.h>
+#include <VBox/VBoxGuestLib.h>
+
+/** @def VBOXGUEST_USE_DEFERRED_WAKE_UP
+ * Defer wake-up of waiting thread when defined. */
+#if defined(RT_OS_DARWIN) || defined(RT_OS_SOLARIS) || defined(RT_OS_WINDOWS) || defined(DOXYGEN_RUNNING)
+# define VBOXGUEST_USE_DEFERRED_WAKE_UP
+#endif
+
+
+/** Pointer to the VBoxGuest per session data. */
+typedef struct VBOXGUESTSESSION *PVBOXGUESTSESSION;
+
+/** Pointer to a wait-for-event entry. */
+typedef struct VBOXGUESTWAIT *PVBOXGUESTWAIT;
+
+/**
+ * VBox guest wait for event entry.
+ *
+ * Each waiting thread allocates one of these items and adds
+ * it to the wait list before going to sleep on the event sem.
+ */
+typedef struct VBOXGUESTWAIT
+{
+    /** The list node. */
+    RTLISTNODE                  ListNode;
+    /** The events we are waiting on. */
+    uint32_t                    fReqEvents;
+    /** The events we received. */
+    uint32_t volatile           fResEvents;
+#ifdef VBOXGUEST_USE_DEFERRED_WAKE_UP
+    /** Set by VGDrvCommonWaitDoWakeUps before leaving the spinlock to call
+     *  RTSemEventMultiSignal. */
+    bool volatile               fPendingWakeUp;
+    /** Set by the requestor thread if it got the spinlock before the
+     * signaller.  Deals with the race in VGDrvCommonWaitDoWakeUps. */
+    bool volatile               fFreeMe;
+#endif
+    /** The event semaphore. */
+    RTSEMEVENTMULTI             Event;
+    /** The session that's waiting. */
+    PVBOXGUESTSESSION           pSession;
+#ifdef VBOX_WITH_HGCM
+    /** The HGCM request we're waiting for to complete. */
+    VMMDevHGCMRequestHeader volatile *pHGCMReq;
+#endif
+} VBOXGUESTWAIT;
+
+
+/**
+ * VBox guest memory balloon.
+ */
+typedef struct VBOXGUESTMEMBALLOON
+{
+    /** Mutex protecting the members below from concurrent access. */
+    RTSEMFASTMUTEX              hMtx;
+    /** The current number of chunks in the balloon. */
+    uint32_t                    cChunks;
+    /** The maximum number of chunks in the balloon (typically the amount of guest
+     * memory / chunksize). */
+    uint32_t                    cMaxChunks;
+    /** This is true if we are using RTR0MemObjAllocPhysNC() / RTR0MemObjGetPagePhysAddr()
+     * and false otherwise. */
+    bool                        fUseKernelAPI;
+    /** The current owner of the balloon.
+     * This is automatically assigned to the first session using the ballooning
+     * API and first released when the session closes. */
+    PVBOXGUESTSESSION           pOwner;
+    /** The pointer to the array of memory objects holding the chunks of the
+     *  balloon.  This array is cMaxChunks in size when present. */
+    PRTR0MEMOBJ                 paMemObj;
+} VBOXGUESTMEMBALLOON;
+/** Pointer to a memory balloon. */
+typedef VBOXGUESTMEMBALLOON *PVBOXGUESTMEMBALLOON;
+
+
+/**
+ * Per bit usage tracker for a uint32_t mask.
+ *
+ * Used for optimal handling of guest properties, mouse status and event filter.
+ */
+typedef struct VBOXGUESTBITUSAGETRACER
+{
+    /** Per bit usage counters. */
+    uint32_t        acPerBitUsage[32];
+    /** The current mask according to acPerBitUsage. */
+    uint32_t        fMask;
+} VBOXGUESTBITUSAGETRACER;
+/** Pointer to a per bit usage tracker.  */
+typedef VBOXGUESTBITUSAGETRACER *PVBOXGUESTBITUSAGETRACER;
+/** Pointer to a const per bit usage tracker.  */
+typedef VBOXGUESTBITUSAGETRACER const *PCVBOXGUESTBITUSAGETRACER;
+
+
+/**
+ * VBox guest device (data) extension.
+ */
+typedef struct VBOXGUESTDEVEXT
+{
+    /** The base of the adapter I/O ports. */
+    RTIOPORT                    IOPortBase;
+    /** Pointer to the mapping of the VMMDev adapter memory. */
+    VMMDevMemory volatile      *pVMMDevMemory;
+    /** The memory object reserving space for the guest mappings. */
+    RTR0MEMOBJ                  hGuestMappings;
+    /** Spinlock protecting the signaling and resetting of the wait-for-event
+     * semaphores as well as the event acking in the ISR. */
+    RTSPINLOCK                  EventSpinlock;
+    /** Preallocated VMMDevEvents for the IRQ handler. */
+    VMMDevEvents               *pIrqAckEvents;
+    /** The physical address of pIrqAckEvents. */
+    RTCCPHYS                    PhysIrqAckEvents;
+    /** Wait-for-event list for threads waiting for multiple events
+     * (VBOXGUESTWAIT). */
+    RTLISTANCHOR                WaitList;
+#ifdef VBOX_WITH_HGCM
+    /** Wait-for-event list for threads waiting on HGCM async completion
+     * (VBOXGUESTWAIT).
+     *
+     * The entire list is evaluated upon the arrival of an HGCM event, unlike
+     * the other lists which are only evaluated till the first thread has
+     * been woken up. */
+    RTLISTANCHOR                HGCMWaitList;
+#endif
+#ifdef VBOXGUEST_USE_DEFERRED_WAKE_UP
+    /** List of wait-for-event entries that needs waking up
+     * (VBOXGUESTWAIT). */
+    RTLISTANCHOR                WakeUpList;
+#endif
+    /** List of wait-for-event entries that has been woken up
+     * (VBOXGUESTWAIT). */
+    RTLISTANCHOR                WokenUpList;
+    /** List of free wait-for-event entries (VBOXGUESTWAIT). */
+    RTLISTANCHOR                FreeList;
+    /** Mask of pending events. */
+    uint32_t volatile           f32PendingEvents;
+    /** Current VMMDEV_EVENT_MOUSE_POSITION_CHANGED sequence number.
+     * Used to implement polling.  */
+    uint32_t volatile           u32MousePosChangedSeq;
+
+    /** Spinlock various items in the VBOXGUESTSESSION. */
+    RTSPINLOCK                  SessionSpinlock;
+    /** List of guest sessions (VBOXGUESTSESSION).  We currently traverse this
+     * but do not search it, so a list data type should be fine.  Use under the
+     * #SessionSpinlock lock. */
+    RTLISTANCHOR                SessionList;
+    /** Number of session. */
+    uint32_t                    cSessions;
+    /** Flag indicating whether logging to the release log
+     *  is enabled. */
+    bool                        fLoggingEnabled;
+    /** Memory balloon information for RTR0MemObjAllocPhysNC(). */
+    VBOXGUESTMEMBALLOON         MemBalloon;
+    /** Callback and user data for a kernel mouse handler. */
+    VBoxGuestMouseSetNotifyCallback MouseNotifyCallback;
+
+    /** @name Host Event Filtering
+     * @{ */
+    /** Events we won't permit anyone to filter out. */
+    uint32_t                    fFixedEvents;
+    /** Usage counters for the host events. (Fixed events are not included.) */
+    VBOXGUESTBITUSAGETRACER     EventFilterTracker;
+    /** The event filter last reported to the host (UINT32_MAX on failure). */
+    uint32_t                    fEventFilterHost;
+    /** @} */
+
+    /** @name Mouse Status
+     * @{ */
+    /** Usage counters for the mouse statuses (VMMDEV_MOUSE_XXX). */
+    VBOXGUESTBITUSAGETRACER     MouseStatusTracker;
+    /** The mouse status last reported to the host (UINT32_MAX on failure). */
+    uint32_t                    fMouseStatusHost;
+    /** @} */
+
+    /** @name Guest Capabilities
+     * @{ */
+    /** Guest capabilities which have been set to "acquire" mode.  This means
+     * that only one session can use them at a time, and that they will be
+     * automatically cleaned up if that session exits without doing so.
+     *
+     * Protected by VBOXGUESTDEVEXT::SessionSpinlock, but is unfortunately read
+     * without holding the lock in a couple of places. */
+    uint32_t volatile           fAcquireModeGuestCaps;
+    /** Guest capabilities which have been set to "set" mode.  This just means
+     * that they have been blocked from ever being set to "acquire" mode. */
+    uint32_t                    fSetModeGuestCaps;
+    /** Mask of all capabilities which are currently acquired by some session
+     * and as such reported to the host. */
+    uint32_t                    fAcquiredGuestCaps;
+    /** Usage counters for guest capabilities in "set" mode. Indexed by
+     *  capability bit number, one count per session using a capability. */
+    VBOXGUESTBITUSAGETRACER     SetGuestCapsTracker;
+    /** The guest capabilities last reported to the host (UINT32_MAX on failure). */
+    uint32_t                    fGuestCapsHost;
+    /** @} */
+
+    /** Heartbeat timer which fires with interval
+      * cNsHearbeatInterval and its handler sends
+      * VMMDevReq_GuestHeartbeat to VMMDev. */
+    PRTTIMER                    pHeartbeatTimer;
+    /** Heartbeat timer interval in nanoseconds. */
+    uint64_t                    cNsHeartbeatInterval;
+    /** Preallocated VMMDevReq_GuestHeartbeat request. */
+    VMMDevRequestHeader         *pReqGuestHeartbeat;
+} VBOXGUESTDEVEXT;
+/** Pointer to the VBoxGuest driver data. */
+typedef VBOXGUESTDEVEXT *PVBOXGUESTDEVEXT;
+
+
+/**
+ * The VBoxGuest per session data.
+ */
+typedef struct VBOXGUESTSESSION
+{
+    /** The list node. */
+    RTLISTNODE                  ListNode;
+#if defined(RT_OS_DARWIN) || defined(RT_OS_FREEBSD) || defined(RT_OS_OS2) || defined(RT_OS_SOLARIS)
+    /** Pointer to the next session with the same hash. */
+    PVBOXGUESTSESSION           pNextHash;
+#endif
+#if defined(RT_OS_OS2)
+    /** The system file number of this session. */
+    uint16_t                    sfn;
+    uint16_t                    Alignment; /**< Alignment */
+#endif
+    /** The process (id) of the session.
+     * This is NIL if it's a kernel session. */
+    RTPROCESS                   Process;
+    /** Which process this session is associated with.
+     * This is NIL if it's a kernel session. */
+    RTR0PROCESS                 R0Process;
+    /** Pointer to the device extension. */
+    PVBOXGUESTDEVEXT            pDevExt;
+
+#ifdef VBOX_WITH_HGCM
+    /** Array containing HGCM client IDs associated with this session.
+     * This will be automatically disconnected when the session is closed. */
+    uint32_t volatile           aHGCMClientIds[64];
+#endif
+    /** The last consumed VMMDEV_EVENT_MOUSE_POSITION_CHANGED sequence number.
+     * Used to implement polling.  */
+    uint32_t volatile           u32MousePosChangedSeq;
+    /** Host events requested by the session.
+     * An event type requested in any guest session will be added to the host
+     * filter.  Protected by VBOXGUESTDEVEXT::SessionSpinlock. */
+    uint32_t                    fEventFilter;
+    /** Guest capabilities held in "acquired" by this session.
+     * Protected by VBOXGUESTDEVEXT::SessionSpinlock, but is unfortunately read
+     * without holding the lock in a couple of places. */
+    uint32_t volatile           fAcquiredGuestCaps;
+    /** Guest capabilities in "set" mode for this session.
+     * These accumulated for sessions via VBOXGUESTDEVEXT::acGuestCapsSet and
+     * reported to the host.  Protected by VBOXGUESTDEVEXT::SessionSpinlock.  */
+    uint32_t                    fCapabilities;
+    /** Mouse features supported.  A feature enabled in any guest session will
+     * be enabled for the host.
+     * @note We invert the VMMDEV_MOUSE_GUEST_NEEDS_HOST_CURSOR feature in this
+     * bitmap.  The logic of this is that the real feature is when the host
+     * cursor is not needed, and we tell the host it is not needed if any
+     * session explicitly fails to assert it.  Storing it inverted simplifies
+     * the checks.
+     * Use under the VBOXGUESTDEVEXT#SessionSpinlock lock. */
+    uint32_t                    fMouseStatus;
+#ifdef RT_OS_DARWIN
+    /** Pointer to the associated org_virtualbox_VBoxGuestClient object. */
+    void                       *pvVBoxGuestClient;
+    /** Whether this session has been opened or not. */
+    bool                        fOpened;
+#endif
+    /** Whether a CANCEL_ALL_WAITEVENTS is pending.  This happens when
+     * CANCEL_ALL_WAITEVENTS is called, but no call to WAITEVENT is in process
+     * in the current session.  In that case the next call will be interrupted
+     * at once. */
+    bool volatile               fPendingCancelWaitEvents;
+    /** Does this session belong to a root process or a user one? */
+    bool                        fUserSession;
+} VBOXGUESTSESSION;
+
+RT_C_DECLS_BEGIN
+
+int  VGDrvCommonInitDevExt(PVBOXGUESTDEVEXT pDevExt, uint16_t IOPortBase, void *pvMMIOBase, uint32_t cbMMIO,
+                           VBOXOSTYPE enmOSType, uint32_t fEvents);
+bool VGDrvCommonISR(PVBOXGUESTDEVEXT pDevExt);
+void VGDrvCommonDeleteDevExt(PVBOXGUESTDEVEXT pDevExt);
+int  VGDrvCommonReinitDevExtAfterHibernation(PVBOXGUESTDEVEXT pDevExt, VBOXOSTYPE enmOSType);
+#ifdef VBOXGUEST_USE_DEFERRED_WAKE_UP
+void VGDrvCommonWaitDoWakeUps(PVBOXGUESTDEVEXT pDevExt);
+#endif
+
+int  VGDrvCommonCreateUserSession(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION *ppSession);
+int  VGDrvCommonCreateKernelSession(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION *ppSession);
+void VGDrvCommonCloseSession(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION pSession);
+
+int  VGDrvCommonIoCtlFast(unsigned iFunction, PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION pSession);
+int  VGDrvCommonIoCtl(unsigned iFunction, PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION pSession,
+                      void *pvData, size_t cbData, size_t *pcbDataReturned);
+
+/**
+ * ISR callback for notifying threads polling for mouse events.
+ *
+ * This is called at the end of the ISR, after leaving the event spinlock, if
+ * VMMDEV_EVENT_MOUSE_POSITION_CHANGED was raised by the host.
+ *
+ * @param   pDevExt     The device extension.
+ */
+void VGDrvNativeISRMousePollEvent(PVBOXGUESTDEVEXT pDevExt);
+
+
+#ifdef VBOX_WITH_DPC_LATENCY_CHECKER
+int VGDrvNtIOCtl_DpcLatencyChecker(void);
+#endif
+
+RT_C_DECLS_END
+
+#endif
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/vboxguest/VBoxGuestLog.h
@@ -0,0 +1,59 @@
+/* $Id: VBoxGuestLog.h $ */
+/** @file
+ * VBoxGuestLibR0 - Guest Logging facility.
+ */
+
+/*
+ * Copyright (C) 2006-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+#ifndef __VBOXGUESTLOG__H
+#define __VBOXGUESTLOG__H
+
+#ifndef RT_OS_WINDOWS
+# error "Don't include this file."
+#else  /* RT_OS_WINDOWS */
+/* Save LOG_ENABLED state, because "VBox/rt/log.h"
+ * may undefine it for IN_RING0 code.
+ */
+# if (defined(DEBUG) && !defined(NO_LOGGING)) || defined(LOG_ENABLED)
+#  define __LOG_ENABLED_SAVED__
+# endif
+
+# if (defined(DEBUG) && !defined(NO_LOGGING)) || defined(LOG_ENABLED)
+#  ifdef VBOX_GUEST
+#   include <VBox/log.h>
+#   undef Log
+#   define Log(a)  RTLogBackdoorPrintf a
+#  else
+#   define Log(a)  DbgPrint a
+#  endif
+# else
+#  define Log(a)
+# endif
+
+# ifdef __LOG_ENABLED_SAVED__
+#  define LOG_ENABLED
+#  undef __LOG_ENABLED_SAVED__
+# endif
+
+#endif  /* RT_OS_WINDOWS */
+
+#endif /* !__VBOXGUESTLOG__H */
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/vboxguest/VMMDev.c
@@ -0,0 +1,43 @@
+/* $Id: VMMDev.cpp $ */
+/** @file
+ * VBoxGuestLibR0 - VMMDev device related functions.
+ */
+
+/*
+ * Copyright (C) 2006-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+#include "VBGLInternal.h"
+
+
+DECLVBGL(int) VbglQueryVMMDevMemory(VMMDevMemory **ppVMMDevMemory)
+{
+    int rc = vbglR0Enter();
+    if (RT_FAILURE(rc))
+        return rc;
+
+    /* If the memory was not found, return an error. */
+    if (!g_vbgldata.pVMMDevMemory)
+        return VERR_NOT_SUPPORTED;
+
+    *ppVMMDevMemory = g_vbgldata.pVMMDevMemory;
+    return rc;
+}
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/vboxguest/common/alloc/alloc.c
@@ -0,0 +1,63 @@
+/* $Id: alloc.cpp $ */
+/** @file
+ * IPRT - Memory Allocation.
+ */
+
+/*
+ * Copyright (C) 2006-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+
+/*********************************************************************************************************************************
+*   Header Files                                                                                                                 *
+*********************************************************************************************************************************/
+#ifndef RTMEM_NO_WRAP_TO_EF_APIS
+# define RTMEM_NO_WRAP_TO_EF_APIS
+#endif
+#include <iprt/mem.h>
+#include "internal/iprt.h"
+
+#include <iprt/assert.h>
+#include <iprt/string.h>
+
+
+
+RTDECL(void *) RTMemDupTag(const void *pvSrc, size_t cb, const char *pszTag) RT_NO_THROW_DEF
+{
+    void *pvDst = RTMemAllocTag(cb, pszTag);
+    if (pvDst)
+        memcpy(pvDst, pvSrc, cb);
+    return pvDst;
+}
+RT_EXPORT_SYMBOL(RTMemDupTag);
+
+
+RTDECL(void *) RTMemDupExTag(const void *pvSrc, size_t cbSrc, size_t cbExtra, const char *pszTag) RT_NO_THROW_DEF
+{
+    void *pvDst = RTMemAllocTag(cbSrc + cbExtra, pszTag);
+    if (pvDst)
+    {
+        memcpy(pvDst, pvSrc, cbSrc);
+        memset((uint8_t *)pvDst + cbSrc, 0, cbExtra);
+    }
+    return pvDst;
+}
+RT_EXPORT_SYMBOL(RTMemDupExTag);
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/vboxguest/common/alloc/heapsimple.c
@@ -0,0 +1,920 @@
+/* $Id: heapsimple.cpp $ */
+/** @file
+ * IPRT - A Simple Heap.
+ */
+
+/*
+ * Copyright (C) 2006-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+
+/*********************************************************************************************************************************
+*   Header Files                                                                                                                 *
+*********************************************************************************************************************************/
+#define LOG_GROUP RTLOGGROUP_DEFAULT
+#include <iprt/heap.h>
+#include "internal/iprt.h"
+
+#include <iprt/assert.h>
+#include <iprt/asm.h>
+#include <iprt/err.h>
+#include <iprt/log.h>
+#include <iprt/string.h>
+#include <iprt/param.h>
+
+#include "internal/magics.h"
+
+
+/*********************************************************************************************************************************
+*   Structures and Typedefs                                                                                                      *
+*********************************************************************************************************************************/
+/** Pointer to the heap anchor block. */
+typedef struct RTHEAPSIMPLEINTERNAL *PRTHEAPSIMPLEINTERNAL;
+/** Pointer to a heap block. */
+typedef struct RTHEAPSIMPLEBLOCK *PRTHEAPSIMPLEBLOCK;
+/** Pointer to a free heap block. */
+typedef struct RTHEAPSIMPLEFREE *PRTHEAPSIMPLEFREE;
+
+/**
+ * Structure describing a simple heap block.
+ * If this block is allocated, it is followed by the user data.
+ * If this block is free, see RTHEAPSIMPLEFREE.
+ */
+typedef struct RTHEAPSIMPLEBLOCK
+{
+    /** The next block in the global block list. */
+    PRTHEAPSIMPLEBLOCK      pNext;
+    /** The previous block in the global block list. */
+    PRTHEAPSIMPLEBLOCK      pPrev;
+    /** Pointer to the heap anchor block. */
+    PRTHEAPSIMPLEINTERNAL   pHeap;
+    /** Flags + magic. */
+    uintptr_t               fFlags;
+} RTHEAPSIMPLEBLOCK;
+AssertCompileSizeAlignment(RTHEAPSIMPLEBLOCK, 16);
+
+/** The block is free if this flag is set. When cleared it's allocated. */
+#define RTHEAPSIMPLEBLOCK_FLAGS_FREE        ((uintptr_t)RT_BIT(0))
+/** The magic value. */
+#define RTHEAPSIMPLEBLOCK_FLAGS_MAGIC       ((uintptr_t)0xabcdef00)
+/** The mask that needs to be applied to RTHEAPSIMPLEBLOCK::fFlags to obtain the magic value. */
+#define RTHEAPSIMPLEBLOCK_FLAGS_MAGIC_MASK  (~(uintptr_t)RT_BIT(0))
+
+/**
+ * Checks if the specified block is valid or not.
+ * @returns boolean answer.
+ * @param   pBlock      Pointer to a RTHEAPSIMPLEBLOCK structure.
+ */
+#define RTHEAPSIMPLEBLOCK_IS_VALID(pBlock)  \
+    ( ((pBlock)->fFlags & RTHEAPSIMPLEBLOCK_FLAGS_MAGIC_MASK) == RTHEAPSIMPLEBLOCK_FLAGS_MAGIC )
+
+/**
+ * Checks if the specified block is valid and in use.
+ * @returns boolean answer.
+ * @param   pBlock      Pointer to a RTHEAPSIMPLEBLOCK structure.
+ */
+#define RTHEAPSIMPLEBLOCK_IS_VALID_USED(pBlock)  \
+    ( ((pBlock)->fFlags & (RTHEAPSIMPLEBLOCK_FLAGS_MAGIC_MASK | RTHEAPSIMPLEBLOCK_FLAGS_FREE)) \
+       == RTHEAPSIMPLEBLOCK_FLAGS_MAGIC )
+
+/**
+ * Checks if the specified block is valid and free.
+ * @returns boolean answer.
+ * @param   pBlock      Pointer to a RTHEAPSIMPLEBLOCK structure.
+ */
+#define RTHEAPSIMPLEBLOCK_IS_VALID_FREE(pBlock)  \
+    ( ((pBlock)->fFlags & (RTHEAPSIMPLEBLOCK_FLAGS_MAGIC_MASK | RTHEAPSIMPLEBLOCK_FLAGS_FREE)) \
+       == (RTHEAPSIMPLEBLOCK_FLAGS_MAGIC | RTHEAPSIMPLEBLOCK_FLAGS_FREE) )
+
+/**
+ * Checks if the specified block is free or not.
+ * @returns boolean answer.
+ * @param   pBlock      Pointer to a valid RTHEAPSIMPLEBLOCK structure.
+ */
+#define RTHEAPSIMPLEBLOCK_IS_FREE(pBlock)   (!!((pBlock)->fFlags & RTHEAPSIMPLEBLOCK_FLAGS_FREE))
+
+/**
+ * A free heap block.
+ * This is an extended version of RTHEAPSIMPLEBLOCK that takes the unused
+ * user data to store free list pointers and a cached size value.
+ */
+typedef struct RTHEAPSIMPLEFREE
+{
+    /** Core stuff. */
+    RTHEAPSIMPLEBLOCK       Core;
+    /** Pointer to the next free block. */
+    PRTHEAPSIMPLEFREE       pNext;
+    /** Pointer to the previous free block. */
+    PRTHEAPSIMPLEFREE       pPrev;
+    /** The size of the block (excluding the RTHEAPSIMPLEBLOCK part). */
+    size_t                  cb;
+    /** An alignment filler to make it a multiple of (sizeof(void *) * 2). */
+    size_t                  Alignment;
+} RTHEAPSIMPLEFREE;
+
+
+/**
+ * The heap anchor block.
+ * This structure is placed at the head of the memory block specified to RTHeapSimpleInit(),
+ * which means that the first RTHEAPSIMPLEBLOCK appears immediately after this structure.
+ */
+typedef struct RTHEAPSIMPLEINTERNAL
+{
+    /** The typical magic (RTHEAPSIMPLE_MAGIC). */
+    size_t                  uMagic;
+    /** The heap size. (This structure is included!) */
+    size_t                  cbHeap;
+    /** Pointer to the end of the heap. */
+    void                   *pvEnd;
+    /** The amount of free memory in the heap. */
+    size_t                  cbFree;
+    /** Free head pointer. */
+    PRTHEAPSIMPLEFREE       pFreeHead;
+    /** Free tail pointer. */
+    PRTHEAPSIMPLEFREE       pFreeTail;
+    /** Make the size of this structure is a multiple of 32. */
+    size_t                  auAlignment[2];
+} RTHEAPSIMPLEINTERNAL;
+AssertCompileSizeAlignment(RTHEAPSIMPLEINTERNAL, 32);
+
+
+/** The minimum allocation size. */
+#define RTHEAPSIMPLE_MIN_BLOCK  (sizeof(RTHEAPSIMPLEBLOCK))
+AssertCompile(RTHEAPSIMPLE_MIN_BLOCK >= sizeof(RTHEAPSIMPLEBLOCK));
+AssertCompile(RTHEAPSIMPLE_MIN_BLOCK >= sizeof(RTHEAPSIMPLEFREE) - sizeof(RTHEAPSIMPLEBLOCK));
+
+/** The minimum and default alignment.  */
+#define RTHEAPSIMPLE_ALIGNMENT  (sizeof(RTHEAPSIMPLEBLOCK))
+
+
+/*********************************************************************************************************************************
+*   Defined Constants And Macros                                                                                                 *
+*********************************************************************************************************************************/
+#ifdef RT_STRICT
+# define RTHEAPSIMPLE_STRICT 1
+#endif
+
+#define ASSERT_L(a, b)    AssertMsg((uintptr_t)(a) <  (uintptr_t)(b), ("a=%p b=%p\n", (uintptr_t)(a), (uintptr_t)(b)))
+#define ASSERT_LE(a, b)   AssertMsg((uintptr_t)(a) <= (uintptr_t)(b), ("a=%p b=%p\n", (uintptr_t)(a), (uintptr_t)(b)))
+#define ASSERT_G(a, b)    AssertMsg((uintptr_t)(a) >  (uintptr_t)(b), ("a=%p b=%p\n", (uintptr_t)(a), (uintptr_t)(b)))
+#define ASSERT_GE(a, b)   AssertMsg((uintptr_t)(a) >= (uintptr_t)(b), ("a=%p b=%p\n", (uintptr_t)(a), (uintptr_t)(b)))
+#define ASSERT_ALIGN(a)   AssertMsg(!((uintptr_t)(a) & (RTHEAPSIMPLE_ALIGNMENT - 1)), ("a=%p\n", (uintptr_t)(a)))
+
+#define ASSERT_PREV(pHeapInt, pBlock)  \
+    do { ASSERT_ALIGN((pBlock)->pPrev); \
+         if ((pBlock)->pPrev) \
+         { \
+             ASSERT_L((pBlock)->pPrev, (pBlock)); \
+             ASSERT_GE((pBlock)->pPrev, (pHeapInt) + 1); \
+         } \
+         else \
+             Assert((pBlock) == (PRTHEAPSIMPLEBLOCK)((pHeapInt) + 1)); \
+    } while (0)
+
+#define ASSERT_NEXT(pHeap, pBlock) \
+    do { ASSERT_ALIGN((pBlock)->pNext); \
+         if ((pBlock)->pNext) \
+         { \
+             ASSERT_L((pBlock)->pNext, (pHeapInt)->pvEnd); \
+             ASSERT_G((pBlock)->pNext, (pBlock)); \
+         } \
+    } while (0)
+
+#define ASSERT_BLOCK(pHeapInt, pBlock) \
+    do { AssertMsg(RTHEAPSIMPLEBLOCK_IS_VALID(pBlock), ("%#x\n", (pBlock)->fFlags)); \
+         AssertMsg((pBlock)->pHeap == (pHeapInt), ("%p != %p\n", (pBlock)->pHeap, (pHeapInt))); \
+         ASSERT_GE((pBlock), (pHeapInt) + 1); \
+         ASSERT_L((pBlock), (pHeapInt)->pvEnd); \
+         ASSERT_NEXT(pHeapInt, pBlock); \
+         ASSERT_PREV(pHeapInt, pBlock); \
+    } while (0)
+
+#define ASSERT_BLOCK_USED(pHeapInt, pBlock) \
+    do { AssertMsg(RTHEAPSIMPLEBLOCK_IS_VALID_USED((pBlock)), ("%#x\n", (pBlock)->fFlags)); \
+         AssertMsg((pBlock)->pHeap == (pHeapInt), ("%p != %p\n", (pBlock)->pHeap, (pHeapInt))); \
+         ASSERT_GE((pBlock), (pHeapInt) + 1); \
+         ASSERT_L((pBlock), (pHeapInt)->pvEnd); \
+         ASSERT_NEXT(pHeapInt, pBlock); \
+         ASSERT_PREV(pHeapInt, pBlock); \
+    } while (0)
+
+#define ASSERT_FREE_PREV(pHeapInt, pBlock) \
+    do { ASSERT_ALIGN((pBlock)->pPrev); \
+         if ((pBlock)->pPrev) \
+         { \
+             ASSERT_GE((pBlock)->pPrev, (pHeapInt)->pFreeHead); \
+             ASSERT_L((pBlock)->pPrev, (pBlock)); \
+             ASSERT_LE((pBlock)->pPrev, (pBlock)->Core.pPrev); \
+         } \
+         else \
+             Assert((pBlock) == (pHeapInt)->pFreeHead); \
+    } while (0)
+
+#define ASSERT_FREE_NEXT(pHeapInt, pBlock) \
+    do { ASSERT_ALIGN((pBlock)->pNext); \
+         if ((pBlock)->pNext) \
+         { \
+             ASSERT_LE((pBlock)->pNext, (pHeapInt)->pFreeTail); \
+             ASSERT_G((pBlock)->pNext, (pBlock)); \
+             ASSERT_GE((pBlock)->pNext, (pBlock)->Core.pNext); \
+         } \
+         else \
+             Assert((pBlock) == (pHeapInt)->pFreeTail); \
+    } while (0)
+
+#ifdef RTHEAPSIMPLE_STRICT
+# define ASSERT_FREE_CB(pHeapInt, pBlock) \
+    do { size_t cbCalc = ((pBlock)->Core.pNext ? (uintptr_t)(pBlock)->Core.pNext : (uintptr_t)(pHeapInt)->pvEnd) \
+                       - (uintptr_t)(pBlock) - sizeof(RTHEAPSIMPLEBLOCK); \
+         AssertMsg((pBlock)->cb == cbCalc, ("cb=%#zx cbCalc=%#zx\n", (pBlock)->cb, cbCalc)); \
+    } while (0)
+#else
+# define ASSERT_FREE_CB(pHeapInt, pBlock) do {} while (0)
+#endif
+
+/** Asserts that a free block is valid. */
+#define ASSERT_BLOCK_FREE(pHeapInt, pBlock) \
+    do { ASSERT_BLOCK(pHeapInt, &(pBlock)->Core); \
+         Assert(RTHEAPSIMPLEBLOCK_IS_VALID_FREE(&(pBlock)->Core)); \
+         ASSERT_GE((pBlock), (pHeapInt)->pFreeHead); \
+         ASSERT_LE((pBlock), (pHeapInt)->pFreeTail); \
+         ASSERT_FREE_NEXT(pHeapInt, pBlock); \
+         ASSERT_FREE_PREV(pHeapInt, pBlock); \
+         ASSERT_FREE_CB(pHeapInt, pBlock); \
+    } while (0)
+
+/** Asserts that the heap anchor block is ok. */
+#define ASSERT_ANCHOR(pHeapInt) \
+    do { AssertPtr(pHeapInt);\
+         Assert((pHeapInt)->uMagic == RTHEAPSIMPLE_MAGIC); \
+    } while (0)
+
+
+/*********************************************************************************************************************************
+*   Internal Functions                                                                                                           *
+*********************************************************************************************************************************/
+#ifdef RTHEAPSIMPLE_STRICT
+static void rtHeapSimpleAssertAll(PRTHEAPSIMPLEINTERNAL pHeapInt);
+#endif
+static PRTHEAPSIMPLEBLOCK rtHeapSimpleAllocBlock(PRTHEAPSIMPLEINTERNAL pHeapInt, size_t cb, size_t uAlignment);
+static void rtHeapSimpleFreeBlock(PRTHEAPSIMPLEINTERNAL pHeapInt, PRTHEAPSIMPLEBLOCK pBlock);
+
+
+RTDECL(int) RTHeapSimpleInit(PRTHEAPSIMPLE phHeap, void *pvMemory, size_t cbMemory)
+{
+    PRTHEAPSIMPLEINTERNAL pHeapInt;
+    PRTHEAPSIMPLEFREE pFree;
+    unsigned i;
+
+    /*
+     * Validate input. The imposed minimum heap size is just a convenient value.
+     */
+    AssertReturn(cbMemory >= PAGE_SIZE, VERR_INVALID_PARAMETER);
+    AssertPtrReturn(pvMemory, VERR_INVALID_POINTER);
+    AssertReturn((uintptr_t)pvMemory + (cbMemory - 1) > (uintptr_t)cbMemory, VERR_INVALID_PARAMETER);
+
+    /*
+     * Place the heap anchor block at the start of the heap memory,
+     * enforce 32 byte alignment of it. Also align the heap size correctly.
+     */
+    pHeapInt = (PRTHEAPSIMPLEINTERNAL)pvMemory;
+    if ((uintptr_t)pvMemory & 31)
+    {
+        const uintptr_t off = 32 - ((uintptr_t)pvMemory & 31);
+        cbMemory -= off;
+        pHeapInt = (PRTHEAPSIMPLEINTERNAL)((uintptr_t)pvMemory + off);
+    }
+    cbMemory &= ~(RTHEAPSIMPLE_ALIGNMENT - 1);
+
+
+    /* Init the heap anchor block. */
+    pHeapInt->uMagic = RTHEAPSIMPLE_MAGIC;
+    pHeapInt->pvEnd = (uint8_t *)pHeapInt + cbMemory;
+    pHeapInt->cbHeap = cbMemory;
+    pHeapInt->cbFree = cbMemory
+                     - sizeof(RTHEAPSIMPLEBLOCK)
+                     - sizeof(RTHEAPSIMPLEINTERNAL);
+    pHeapInt->pFreeTail = pHeapInt->pFreeHead = (PRTHEAPSIMPLEFREE)(pHeapInt + 1);
+    for (i = 0; i < RT_ELEMENTS(pHeapInt->auAlignment); i++)
+        pHeapInt->auAlignment[i] = ~(size_t)0;
+
+    /* Init the single free block. */
+    pFree = pHeapInt->pFreeHead;
+    pFree->Core.pNext = NULL;
+    pFree->Core.pPrev = NULL;
+    pFree->Core.pHeap = pHeapInt;
+    pFree->Core.fFlags = RTHEAPSIMPLEBLOCK_FLAGS_MAGIC | RTHEAPSIMPLEBLOCK_FLAGS_FREE;
+    pFree->pNext = NULL;
+    pFree->pPrev = NULL;
+    pFree->cb = pHeapInt->cbFree;
+
+    *phHeap = pHeapInt;
+
+#ifdef RTHEAPSIMPLE_STRICT
+    rtHeapSimpleAssertAll(pHeapInt);
+#endif
+    return VINF_SUCCESS;
+}
+RT_EXPORT_SYMBOL(RTHeapSimpleInit);
+
+
+RTDECL(int) RTHeapSimpleRelocate(RTHEAPSIMPLE hHeap, uintptr_t offDelta)
+{
+    PRTHEAPSIMPLEINTERNAL   pHeapInt = hHeap;
+    PRTHEAPSIMPLEFREE       pCur;
+
+    /*
+     * Validate input.
+     */
+    AssertPtrReturn(pHeapInt, VERR_INVALID_HANDLE);
+    AssertReturn(pHeapInt->uMagic == RTHEAPSIMPLE_MAGIC, VERR_INVALID_HANDLE);
+    AssertMsgReturn((uintptr_t)pHeapInt - (uintptr_t)pHeapInt->pvEnd + pHeapInt->cbHeap == offDelta,
+                    ("offDelta=%p, expected=%p\n", offDelta, (uintptr_t)pHeapInt->pvEnd - pHeapInt->cbHeap - (uintptr_t)pHeapInt),
+                    VERR_INVALID_PARAMETER);
+
+    /*
+     * Relocate the heap anchor block.
+     */
+#define RELOCATE_IT(var, type, offDelta)    do { if (RT_UNLIKELY((var) != NULL)) { (var) = (type)((uintptr_t)(var) + offDelta); } } while (0)
+    RELOCATE_IT(pHeapInt->pvEnd,     void *,            offDelta);
+    RELOCATE_IT(pHeapInt->pFreeHead, PRTHEAPSIMPLEFREE, offDelta);
+    RELOCATE_IT(pHeapInt->pFreeTail, PRTHEAPSIMPLEFREE, offDelta);
+
+    /*
+     * Walk the heap blocks.
+     */
+    for (pCur = (PRTHEAPSIMPLEFREE)(pHeapInt + 1);
+         pCur && (uintptr_t)pCur < (uintptr_t)pHeapInt->pvEnd;
+         pCur = (PRTHEAPSIMPLEFREE)pCur->Core.pNext)
+    {
+        RELOCATE_IT(pCur->Core.pNext, PRTHEAPSIMPLEBLOCK,    offDelta);
+        RELOCATE_IT(pCur->Core.pPrev, PRTHEAPSIMPLEBLOCK,    offDelta);
+        RELOCATE_IT(pCur->Core.pHeap, PRTHEAPSIMPLEINTERNAL, offDelta);
+        if (RTHEAPSIMPLEBLOCK_IS_FREE(&pCur->Core))
+        {
+            RELOCATE_IT(pCur->pNext, PRTHEAPSIMPLEFREE, offDelta);
+            RELOCATE_IT(pCur->pPrev, PRTHEAPSIMPLEFREE, offDelta);
+        }
+    }
+#undef RELOCATE_IT
+
+#ifdef RTHEAPSIMPLE_STRICT
+    /*
+     * Give it a once over before we return.
+     */
+    rtHeapSimpleAssertAll(pHeapInt);
+#endif
+    return VINF_SUCCESS;
+}
+RT_EXPORT_SYMBOL(RTHeapSimpleRelocate);
+
+
+RTDECL(void *) RTHeapSimpleAlloc(RTHEAPSIMPLE hHeap, size_t cb, size_t cbAlignment)
+{
+    PRTHEAPSIMPLEINTERNAL pHeapInt = hHeap;
+    PRTHEAPSIMPLEBLOCK pBlock;
+
+    /*
+     * Validate and adjust the input.
+     */
+    AssertPtrReturn(pHeapInt, NULL);
+    if (cb < RTHEAPSIMPLE_MIN_BLOCK)
+        cb = RTHEAPSIMPLE_MIN_BLOCK;
+    else
+        cb = RT_ALIGN_Z(cb, RTHEAPSIMPLE_ALIGNMENT);
+    if (!cbAlignment)
+        cbAlignment = RTHEAPSIMPLE_ALIGNMENT;
+    else
+    {
+        Assert(!(cbAlignment & (cbAlignment - 1)));
+        Assert((cbAlignment & ~(cbAlignment - 1)) == cbAlignment);
+        if (cbAlignment < RTHEAPSIMPLE_ALIGNMENT)
+            cbAlignment = RTHEAPSIMPLE_ALIGNMENT;
+    }
+
+    /*
+     * Do the allocation.
+     */
+    pBlock = rtHeapSimpleAllocBlock(pHeapInt, cb, cbAlignment);
+    if (RT_LIKELY(pBlock))
+    {
+        void *pv = pBlock + 1;
+        return pv;
+    }
+    return NULL;
+}
+RT_EXPORT_SYMBOL(RTHeapSimpleAlloc);
+
+
+RTDECL(void *) RTHeapSimpleAllocZ(RTHEAPSIMPLE hHeap, size_t cb, size_t cbAlignment)
+{
+    PRTHEAPSIMPLEINTERNAL pHeapInt = hHeap;
+    PRTHEAPSIMPLEBLOCK pBlock;
+
+    /*
+     * Validate and adjust the input.
+     */
+    AssertPtrReturn(pHeapInt, NULL);
+    if (cb < RTHEAPSIMPLE_MIN_BLOCK)
+        cb = RTHEAPSIMPLE_MIN_BLOCK;
+    else
+        cb = RT_ALIGN_Z(cb, RTHEAPSIMPLE_ALIGNMENT);
+    if (!cbAlignment)
+        cbAlignment = RTHEAPSIMPLE_ALIGNMENT;
+    else
+    {
+        Assert(!(cbAlignment & (cbAlignment - 1)));
+        Assert((cbAlignment & ~(cbAlignment - 1)) == cbAlignment);
+        if (cbAlignment < RTHEAPSIMPLE_ALIGNMENT)
+            cbAlignment = RTHEAPSIMPLE_ALIGNMENT;
+    }
+
+    /*
+     * Do the allocation.
+     */
+    pBlock = rtHeapSimpleAllocBlock(pHeapInt, cb, cbAlignment);
+    if (RT_LIKELY(pBlock))
+    {
+        void *pv = pBlock + 1;
+        memset(pv, 0, cb);
+        return pv;
+    }
+    return NULL;
+}
+RT_EXPORT_SYMBOL(RTHeapSimpleAllocZ);
+
+
+/**
+ * Allocates a block of memory from the specified heap.
+ *
+ * No parameter validation or adjustment is performed.
+ *
+ * @returns Pointer to the allocated block.
+ * @returns NULL on failure.
+ *
+ * @param   pHeapInt    The heap.
+ * @param   cb          Size of the memory block to allocate.
+ * @param   uAlignment  The alignment specifications for the allocated block.
+ */
+static PRTHEAPSIMPLEBLOCK rtHeapSimpleAllocBlock(PRTHEAPSIMPLEINTERNAL pHeapInt, size_t cb, size_t uAlignment)
+{
+    PRTHEAPSIMPLEBLOCK  pRet = NULL;
+    PRTHEAPSIMPLEFREE   pFree;
+
+#ifdef RTHEAPSIMPLE_STRICT
+    rtHeapSimpleAssertAll(pHeapInt);
+#endif
+
+    /*
+     * Search for a fitting block from the lower end of the heap.
+     */
+    for (pFree = pHeapInt->pFreeHead;
+         pFree;
+         pFree = pFree->pNext)
+    {
+        uintptr_t offAlign;
+        ASSERT_BLOCK_FREE(pHeapInt, pFree);
+
+        /*
+         * Match for size and alignment.
+         */
+        if (pFree->cb < cb)
+            continue;
+        offAlign = (uintptr_t)(&pFree->Core + 1) & (uAlignment - 1);
+        if (offAlign)
+        {
+            RTHEAPSIMPLEFREE Free;
+            PRTHEAPSIMPLEBLOCK pPrev;
+
+            offAlign = uAlignment - offAlign;
+            if (pFree->cb - offAlign < cb)
+                continue;
+
+            /*
+             * Make a stack copy of the free block header and adjust the pointer.
+             */
+            Free = *pFree;
+            pFree = (PRTHEAPSIMPLEFREE)((uintptr_t)pFree + offAlign);
+
+            /*
+             * Donate offAlign bytes to the node in front of us.
+             * If we're the head node, we'll have to create a fake node. We'll
+             * mark it USED for simplicity.
+             *
+             * (Should this policy of donating memory to the guy in front of us
+             * cause big 'leaks', we could create a new free node if there is room
+             * for that.)
+             */
+            pPrev = Free.Core.pPrev;
+            if (pPrev)
+            {
+                AssertMsg(!RTHEAPSIMPLEBLOCK_IS_FREE(pPrev), ("Impossible!\n"));
+                pPrev->pNext = &pFree->Core;
+            }
+            else
+            {
+                pPrev = (PRTHEAPSIMPLEBLOCK)(pHeapInt + 1);
+                Assert(pPrev == &pFree->Core);
+                pPrev->pPrev = NULL;
+                pPrev->pNext = &pFree->Core;
+                pPrev->pHeap = pHeapInt;
+                pPrev->fFlags = RTHEAPSIMPLEBLOCK_FLAGS_MAGIC;
+            }
+            pHeapInt->cbFree -= offAlign;
+
+            /*
+             * Recreate pFree in the new position and adjust the neighbors.
+             */
+            *pFree = Free;
+
+            /* the core */
+            if (pFree->Core.pNext)
+                pFree->Core.pNext->pPrev = &pFree->Core;
+            pFree->Core.pPrev = pPrev;
+
+            /* the free part */
+            pFree->cb -= offAlign;
+            if (pFree->pNext)
+                pFree->pNext->pPrev = pFree;
+            else
+                pHeapInt->pFreeTail = pFree;
+            if (pFree->pPrev)
+                pFree->pPrev->pNext = pFree;
+            else
+                pHeapInt->pFreeHead = pFree;
+            ASSERT_BLOCK_FREE(pHeapInt, pFree);
+            ASSERT_BLOCK_USED(pHeapInt, pPrev);
+        }
+
+        /*
+         * Split off a new FREE block?
+         */
+        if (pFree->cb >= cb + RT_ALIGN_Z(sizeof(RTHEAPSIMPLEFREE), RTHEAPSIMPLE_ALIGNMENT))
+        {
+            /*
+             * Move the FREE block up to make room for the new USED block.
+             */
+            PRTHEAPSIMPLEFREE   pNew = (PRTHEAPSIMPLEFREE)((uintptr_t)&pFree->Core + cb + sizeof(RTHEAPSIMPLEBLOCK));
+
+            pNew->Core.pNext = pFree->Core.pNext;
+            if (pFree->Core.pNext)
+                pFree->Core.pNext->pPrev = &pNew->Core;
+            pNew->Core.pPrev = &pFree->Core;
+            pNew->Core.pHeap = pHeapInt;
+            pNew->Core.fFlags = RTHEAPSIMPLEBLOCK_FLAGS_MAGIC | RTHEAPSIMPLEBLOCK_FLAGS_FREE;
+
+            pNew->pNext = pFree->pNext;
+            if (pNew->pNext)
+                pNew->pNext->pPrev = pNew;
+            else
+                pHeapInt->pFreeTail = pNew;
+            pNew->pPrev = pFree->pPrev;
+            if (pNew->pPrev)
+                pNew->pPrev->pNext = pNew;
+            else
+                pHeapInt->pFreeHead = pNew;
+            pNew->cb    = (pNew->Core.pNext ? (uintptr_t)pNew->Core.pNext : (uintptr_t)pHeapInt->pvEnd) \
+                        - (uintptr_t)pNew - sizeof(RTHEAPSIMPLEBLOCK);
+            ASSERT_BLOCK_FREE(pHeapInt, pNew);
+
+            /*
+             * Update the old FREE node making it a USED node.
+             */
+            pFree->Core.fFlags &= ~RTHEAPSIMPLEBLOCK_FLAGS_FREE;
+            pFree->Core.pNext = &pNew->Core;
+            pHeapInt->cbFree -= pFree->cb;
+            pHeapInt->cbFree += pNew->cb;
+            pRet = &pFree->Core;
+            ASSERT_BLOCK_USED(pHeapInt, pRet);
+        }
+        else
+        {
+            /*
+             * Link it out of the free list.
+             */
+            if (pFree->pNext)
+                pFree->pNext->pPrev = pFree->pPrev;
+            else
+                pHeapInt->pFreeTail = pFree->pPrev;
+            if (pFree->pPrev)
+                pFree->pPrev->pNext = pFree->pNext;
+            else
+                pHeapInt->pFreeHead = pFree->pNext;
+
+            /*
+             * Convert it to a used block.
+             */
+            pHeapInt->cbFree -= pFree->cb;
+            pFree->Core.fFlags &= ~RTHEAPSIMPLEBLOCK_FLAGS_FREE;
+            pRet = &pFree->Core;
+            ASSERT_BLOCK_USED(pHeapInt, pRet);
+        }
+        break;
+    }
+
+#ifdef RTHEAPSIMPLE_STRICT
+    rtHeapSimpleAssertAll(pHeapInt);
+#endif
+    return pRet;
+}
+
+
+RTDECL(void) RTHeapSimpleFree(RTHEAPSIMPLE hHeap, void *pv)
+{
+    PRTHEAPSIMPLEINTERNAL pHeapInt;
+    PRTHEAPSIMPLEBLOCK pBlock;
+
+    /*
+     * Validate input.
+     */
+    if (!pv)
+        return;
+    AssertPtr(pv);
+    Assert(RT_ALIGN_P(pv, RTHEAPSIMPLE_ALIGNMENT) == pv);
+
+    /*
+     * Get the block and heap. If in strict mode, validate these.
+     */
+    pBlock = (PRTHEAPSIMPLEBLOCK)pv - 1;
+    pHeapInt = pBlock->pHeap;
+    ASSERT_BLOCK_USED(pHeapInt, pBlock);
+    ASSERT_ANCHOR(pHeapInt);
+    Assert(pHeapInt == (PRTHEAPSIMPLEINTERNAL)hHeap || !hHeap);
+
+#ifdef RTHEAPSIMPLE_FREE_POISON
+    /*
+     * Poison the block.
+     */
+    const size_t cbBlock = (pBlock->pNext ? (uintptr_t)pBlock->pNext : (uintptr_t)pHeapInt->pvEnd)
+                         - (uintptr_t)pBlock - sizeof(RTHEAPSIMPLEBLOCK);
+    memset(pBlock + 1, RTHEAPSIMPLE_FREE_POISON, cbBlock);
+#endif
+
+    /*
+     * Call worker which does the actual job.
+     */
+    rtHeapSimpleFreeBlock(pHeapInt, pBlock);
+}
+RT_EXPORT_SYMBOL(RTHeapSimpleFree);
+
+
+/**
+ * Free a memory block.
+ *
+ * @param   pHeapInt       The heap.
+ * @param   pBlock         The memory block to free.
+ */
+static void rtHeapSimpleFreeBlock(PRTHEAPSIMPLEINTERNAL pHeapInt, PRTHEAPSIMPLEBLOCK pBlock)
+{
+    PRTHEAPSIMPLEFREE   pFree = (PRTHEAPSIMPLEFREE)pBlock;
+    PRTHEAPSIMPLEFREE   pLeft;
+    PRTHEAPSIMPLEFREE   pRight;
+
+#ifdef RTHEAPSIMPLE_STRICT
+    rtHeapSimpleAssertAll(pHeapInt);
+#endif
+
+    /*
+     * Look for the closest free list blocks by walking the blocks right
+     * of us (both lists are sorted by address).
+     */
+    pLeft = NULL;
+    pRight = NULL;
+    if (pHeapInt->pFreeTail)
+    {
+        pRight = (PRTHEAPSIMPLEFREE)pFree->Core.pNext;
+        while (pRight && !RTHEAPSIMPLEBLOCK_IS_FREE(&pRight->Core))
+        {
+            ASSERT_BLOCK(pHeapInt, &pRight->Core);
+            pRight = (PRTHEAPSIMPLEFREE)pRight->Core.pNext;
+        }
+        if (!pRight)
+            pLeft = pHeapInt->pFreeTail;
+        else
+        {
+            ASSERT_BLOCK_FREE(pHeapInt, pRight);
+            pLeft = pRight->pPrev;
+        }
+        if (pLeft)
+            ASSERT_BLOCK_FREE(pHeapInt, pLeft);
+    }
+    AssertMsgReturnVoid(pLeft != pFree, ("Freed twice! pv=%p (pBlock=%p)\n", pBlock + 1, pBlock));
+    ASSERT_L(pLeft, pFree);
+    Assert(!pRight || (uintptr_t)pRight > (uintptr_t)pFree);
+    Assert(!pLeft || pLeft->pNext == pRight);
+
+    /*
+     * Insert at the head of the free block list?
+     */
+    if (!pLeft)
+    {
+        Assert(pRight == pHeapInt->pFreeHead);
+        pFree->Core.fFlags |= RTHEAPSIMPLEBLOCK_FLAGS_FREE;
+        pFree->pPrev = NULL;
+        pFree->pNext = pRight;
+        if (pRight)
+            pRight->pPrev = pFree;
+        else
+            pHeapInt->pFreeTail = pFree;
+        pHeapInt->pFreeHead = pFree;
+    }
+    else
+    {
+        /*
+         * Can we merge with left hand free block?
+         */
+        if (pLeft->Core.pNext == &pFree->Core)
+        {
+            pLeft->Core.pNext = pFree->Core.pNext;
+            if (pFree->Core.pNext)
+                pFree->Core.pNext->pPrev = &pLeft->Core;
+            pHeapInt->cbFree -= pLeft->cb;
+            pFree = pLeft;
+        }
+        /*
+         * No, just link it into the free list then.
+         */
+        else
+        {
+            pFree->Core.fFlags |= RTHEAPSIMPLEBLOCK_FLAGS_FREE;
+            pFree->pNext = pRight;
+            pFree->pPrev = pLeft;
+            pLeft->pNext = pFree;
+            if (pRight)
+                pRight->pPrev = pFree;
+            else
+                pHeapInt->pFreeTail = pFree;
+        }
+    }
+
+    /*
+     * Can we merge with right hand free block?
+     */
+    if (    pRight
+        &&  pRight->Core.pPrev == &pFree->Core)
+    {
+        /* core */
+        pFree->Core.pNext = pRight->Core.pNext;
+        if (pRight->Core.pNext)
+            pRight->Core.pNext->pPrev = &pFree->Core;
+
+        /* free */
+        pFree->pNext = pRight->pNext;
+        if (pRight->pNext)
+            pRight->pNext->pPrev = pFree;
+        else
+            pHeapInt->pFreeTail = pFree;
+        pHeapInt->cbFree -= pRight->cb;
+    }
+
+    /*
+     * Calculate the size and update free stats.
+     */
+    pFree->cb = (pFree->Core.pNext ? (uintptr_t)pFree->Core.pNext : (uintptr_t)pHeapInt->pvEnd)
+              - (uintptr_t)pFree - sizeof(RTHEAPSIMPLEBLOCK);
+    pHeapInt->cbFree += pFree->cb;
+    ASSERT_BLOCK_FREE(pHeapInt, pFree);
+
+#ifdef RTHEAPSIMPLE_STRICT
+    rtHeapSimpleAssertAll(pHeapInt);
+#endif
+}
+
+
+#ifdef RTHEAPSIMPLE_STRICT
+/**
+ * Internal consistency check (relying on assertions).
+ * @param   pHeapInt
+ */
+static void rtHeapSimpleAssertAll(PRTHEAPSIMPLEINTERNAL pHeapInt)
+{
+    PRTHEAPSIMPLEFREE pPrev = NULL;
+    PRTHEAPSIMPLEFREE pPrevFree = NULL;
+    PRTHEAPSIMPLEFREE pBlock;
+    for (pBlock = (PRTHEAPSIMPLEFREE)(pHeapInt + 1);
+         pBlock;
+         pBlock = (PRTHEAPSIMPLEFREE)pBlock->Core.pNext)
+    {
+        if (RTHEAPSIMPLEBLOCK_IS_FREE(&pBlock->Core))
+        {
+            ASSERT_BLOCK_FREE(pHeapInt, pBlock);
+            Assert(pBlock->pPrev == pPrevFree);
+            Assert(pPrevFree || pHeapInt->pFreeHead == pBlock);
+            pPrevFree = pBlock;
+        }
+        else
+            ASSERT_BLOCK_USED(pHeapInt, &pBlock->Core);
+        Assert(!pPrev || pPrev == (PRTHEAPSIMPLEFREE)pBlock->Core.pPrev);
+        pPrev = pBlock;
+    }
+    Assert(pHeapInt->pFreeTail == pPrevFree);
+}
+#endif
+
+
+RTDECL(size_t) RTHeapSimpleSize(RTHEAPSIMPLE hHeap, void *pv)
+{
+    PRTHEAPSIMPLEINTERNAL pHeapInt;
+    PRTHEAPSIMPLEBLOCK pBlock;
+    size_t cbBlock;
+
+    /*
+     * Validate input.
+     */
+    if (!pv)
+        return 0;
+    AssertPtrReturn(pv, 0);
+    AssertReturn(RT_ALIGN_P(pv, RTHEAPSIMPLE_ALIGNMENT) == pv, 0);
+
+    /*
+     * Get the block and heap. If in strict mode, validate these.
+     */
+    pBlock = (PRTHEAPSIMPLEBLOCK)pv - 1;
+    pHeapInt = pBlock->pHeap;
+    ASSERT_BLOCK_USED(pHeapInt, pBlock);
+    ASSERT_ANCHOR(pHeapInt);
+    Assert(pHeapInt == (PRTHEAPSIMPLEINTERNAL)hHeap || !hHeap);
+
+    /*
+     * Calculate the block size.
+     */
+    cbBlock = (pBlock->pNext ? (uintptr_t)pBlock->pNext : (uintptr_t)pHeapInt->pvEnd)
+            - (uintptr_t)pBlock- sizeof(RTHEAPSIMPLEBLOCK);
+    return cbBlock;
+}
+RT_EXPORT_SYMBOL(RTHeapSimpleSize);
+
+
+RTDECL(size_t) RTHeapSimpleGetHeapSize(RTHEAPSIMPLE hHeap)
+{
+    PRTHEAPSIMPLEINTERNAL pHeapInt;
+
+    if (hHeap == NIL_RTHEAPSIMPLE)
+        return 0;
+
+    pHeapInt = hHeap;
+    AssertPtrReturn(pHeapInt, 0);
+    ASSERT_ANCHOR(pHeapInt);
+    return pHeapInt->cbHeap;
+}
+RT_EXPORT_SYMBOL(RTHeapSimpleGetHeapSize);
+
+
+RTDECL(size_t) RTHeapSimpleGetFreeSize(RTHEAPSIMPLE hHeap)
+{
+    PRTHEAPSIMPLEINTERNAL pHeapInt;
+
+    if (hHeap == NIL_RTHEAPSIMPLE)
+        return 0;
+
+    pHeapInt = hHeap;
+    AssertPtrReturn(pHeapInt, 0);
+    ASSERT_ANCHOR(pHeapInt);
+    return pHeapInt->cbFree;
+}
+RT_EXPORT_SYMBOL(RTHeapSimpleGetFreeSize);
+
+
+RTDECL(void) RTHeapSimpleDump(RTHEAPSIMPLE hHeap, PFNRTHEAPSIMPLEPRINTF pfnPrintf)
+{
+    PRTHEAPSIMPLEINTERNAL pHeapInt = (PRTHEAPSIMPLEINTERNAL)hHeap;
+    PRTHEAPSIMPLEFREE pBlock;
+
+    pfnPrintf("**** Dumping Heap %p - cbHeap=%zx cbFree=%zx ****\n",
+              hHeap, pHeapInt->cbHeap, pHeapInt->cbFree);
+
+    for (pBlock = (PRTHEAPSIMPLEFREE)(pHeapInt + 1);
+         pBlock;
+         pBlock = (PRTHEAPSIMPLEFREE)pBlock->Core.pNext)
+    {
+        size_t cb = (pBlock->pNext ? (uintptr_t)pBlock->Core.pNext : (uintptr_t)pHeapInt->pvEnd)
+                  - (uintptr_t)pBlock - sizeof(RTHEAPSIMPLEBLOCK);
+        if (RTHEAPSIMPLEBLOCK_IS_FREE(&pBlock->Core))
+            pfnPrintf("%p  %06x FREE pNext=%p pPrev=%p fFlags=%#x cb=%#06x : cb=%#06x pNext=%p pPrev=%p\n",
+                      pBlock, (uintptr_t)pBlock - (uintptr_t)(pHeapInt + 1), pBlock->Core.pNext, pBlock->Core.pPrev, pBlock->Core.fFlags, cb,
+                      pBlock->cb, pBlock->pNext, pBlock->pPrev);
+        else
+            pfnPrintf("%p  %06x USED pNext=%p pPrev=%p fFlags=%#x cb=%#06x\n",
+                      pBlock, (uintptr_t)pBlock - (uintptr_t)(pHeapInt + 1), pBlock->Core.pNext, pBlock->Core.pPrev, pBlock->Core.fFlags, cb);
+    }
+    pfnPrintf("**** Done dumping Heap %p ****\n", hHeap);
+}
+RT_EXPORT_SYMBOL(RTHeapSimpleDump);
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/vboxguest/common/err/RTErrConvertFromErrno.c
@@ -0,0 +1,452 @@
+/* $Id: RTErrConvertFromErrno.cpp $ */
+/** @file
+ * IPRT - Convert errno to iprt status codes.
+ */
+
+/*
+ * Copyright (C) 2006-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+
+/*********************************************************************************************************************************
+*   Header Files                                                                                                                 *
+*********************************************************************************************************************************/
+#include <iprt/err.h>
+#include "internal/iprt.h"
+
+#include <iprt/assert.h>
+#include <iprt/errno.h>
+
+
+RTDECL(int)  RTErrConvertFromErrno(unsigned uNativeCode)
+{
+    /* very fast check for no error. */
+    if (uNativeCode == 0)
+        return VINF_SUCCESS;
+
+    /*
+     * Process error codes.
+     *
+     * (Use a switch and not a table since the numbers vary among compilers
+     * and OSes. So we let the compiler switch optimizer handle speed issues.)
+     *
+     * This switch is arranged like the Linux i386 errno.h! This switch is mirrored
+     * by RTErrConvertToErrno.
+     */
+    switch (uNativeCode)
+    {                                                                           /* Linux number */
+#ifdef EPERM
+        case EPERM:             return VERR_ACCESS_DENIED;                      /*   1 */
+#endif
+#ifdef ENOENT
+        case ENOENT:            return VERR_FILE_NOT_FOUND;
+#endif
+#ifdef ESRCH
+        case ESRCH:             return VERR_PROCESS_NOT_FOUND;
+#endif
+#ifdef EINTR
+        case EINTR:             return VERR_INTERRUPTED;
+#endif
+#ifdef EIO
+        case EIO:               return VERR_DEV_IO_ERROR;
+#endif
+#ifdef ENXIO
+        case ENXIO:             return VERR_DEV_IO_ERROR; /**@todo fix this duplicate error */
+#endif
+#ifdef E2BIG
+        case E2BIG:             return VERR_TOO_MUCH_DATA;
+#endif
+#ifdef ENOEXEC
+        case ENOEXEC:           return VERR_BAD_EXE_FORMAT;
+#endif
+#ifdef EBADF
+        case EBADF:             return VERR_INVALID_HANDLE;
+#endif
+#ifdef ECHILD
+        case ECHILD:            return VERR_PROCESS_NOT_FOUND;                  /*  10 */ /**@todo fix duplicate error */
+#endif
+#ifdef EAGAIN
+        case EAGAIN:            return VERR_TRY_AGAIN;
+#endif
+#ifdef ENOMEM
+        case ENOMEM:            return VERR_NO_MEMORY;
+#endif
+#ifdef EACCES
+        case EACCES:            return VERR_ACCESS_DENIED; /**@todo fix duplicate error */
+#endif
+#ifdef EFAULT
+        case EFAULT:            return VERR_INVALID_POINTER;
+#endif
+#ifdef ENOTBLK
+        //case ENOTBLK:           return VERR_;
+#endif
+#ifdef EBUSY
+        case EBUSY:             return VERR_RESOURCE_BUSY;
+#endif
+#ifdef EEXIST
+        case EEXIST:            return VERR_ALREADY_EXISTS;
+#endif
+#ifdef EXDEV
+        case EXDEV:             return VERR_NOT_SAME_DEVICE;
+#endif
+#ifdef ENODEV
+        case ENODEV:            return VERR_NOT_SUPPORTED; /**@todo fix duplicate error */
+#endif
+#ifdef ENOTDIR
+        case ENOTDIR:           return VERR_PATH_NOT_FOUND;                     /*  20 */
+#endif
+#ifdef EISDIR
+        case EISDIR:            return VERR_IS_A_DIRECTORY;
+#endif
+#ifdef EINVAL
+        case EINVAL:            return VERR_INVALID_PARAMETER;
+#endif
+#ifdef ENFILE
+        case ENFILE:            return VERR_TOO_MANY_OPEN_FILES; /** @todo fix duplicate error */
+#endif
+#ifdef EMFILE
+        case EMFILE:            return VERR_TOO_MANY_OPEN_FILES;
+#endif
+#ifdef ENOTTY
+        case ENOTTY:            return VERR_INVALID_FUNCTION;
+#endif
+#ifdef ETXTBSY
+        case ETXTBSY:           return VERR_SHARING_VIOLATION;
+#endif
+#ifdef EFBIG
+        case EFBIG:             return VERR_FILE_TOO_BIG;
+#endif
+#ifdef ENOSPC
+        case ENOSPC:            return VERR_DISK_FULL;
+#endif
+#ifdef ESPIPE
+        case ESPIPE:            return VERR_SEEK_ON_DEVICE;
+#endif
+#ifdef EROFS
+        case EROFS:             return VERR_WRITE_PROTECT;                      /*  30 */
+#endif
+#ifdef EMLINK
+        //case EMLINK:
+#endif
+#ifdef EPIPE
+        case EPIPE:             return VERR_BROKEN_PIPE;
+#endif
+#ifdef EDOM
+        case EDOM:              return VERR_INVALID_PARAMETER;  /**@todo fix duplicate error */
+#endif
+#ifdef ERANGE
+        case ERANGE:            return VERR_INVALID_PARAMETER;  /**@todo fix duplicate error */
+#endif
+#ifdef EDEADLK
+        case EDEADLK:           return VERR_DEADLOCK;
+#endif
+#ifdef ENAMETOOLONG
+        case ENAMETOOLONG:      return VERR_FILENAME_TOO_LONG;
+#endif
+#ifdef ENOLCK
+        case ENOLCK:            return VERR_FILE_LOCK_FAILED;
+#endif
+#ifdef ENOSYS /** @todo map this differently on solaris. */
+        case ENOSYS:            return VERR_NOT_SUPPORTED;
+#endif
+#ifdef ENOTEMPTY
+        case ENOTEMPTY:         return VERR_DIR_NOT_EMPTY;
+#endif
+#ifdef ELOOP
+        case ELOOP:             return VERR_TOO_MANY_SYMLINKS;                  /*  40 */
+#endif
+        //41??
+#ifdef ENOMSG
+        //case ENOMSG           42      /* No message of desired type */
+#endif
+#ifdef EIDRM
+        //case EIDRM            43      /* Identifier removed */
+#endif
+#ifdef ECHRNG
+        //case ECHRNG           44      /* Channel number out of range */
+#endif
+#ifdef EL2NSYNC
+        //case EL2NSYNC 45      /* Level 2 not synchronized */
+#endif
+#ifdef EL3HLT
+        //case EL3HLT           46      /* Level 3 halted */
+#endif
+#ifdef EL3RST
+        //case EL3RST           47      /* Level 3 reset */
+#endif
+#ifdef ELNRNG
+        //case ELNRNG           48      /* Link number out of range */
+#endif
+#ifdef EUNATCH
+        //case EUNATCH          49      /* Protocol driver not attached */
+#endif
+#ifdef ENOCSI
+        //case ENOCSI           50      /* No CSI structure available */
+#endif
+#ifdef EL2HLT
+        //case EL2HLT           51      /* Level 2 halted */
+#endif
+#ifdef EBADE
+        //case EBADE            52      /* Invalid exchange */
+#endif
+#ifdef EBADR
+        //case EBADR            53      /* Invalid request descriptor */
+#endif
+#ifdef EXFULL
+        //case EXFULL           54      /* Exchange full */
+#endif
+#ifdef ENOANO
+        //case ENOANO           55      /* No anode */
+#endif
+#ifdef EBADRQC
+        //case EBADRQC          56      /* Invalid request code */
+#endif
+#ifdef EBADSLT
+        //case EBADSLT          57      /* Invalid slot */
+#endif
+        //case 58:
+#ifdef EBFONT
+        //case EBFONT           59      /* Bad font file format */
+#endif
+#ifdef ENOSTR
+        //case ENOSTR           60      /* Device not a stream */
+#endif
+#ifdef ENODATA
+        case ENODATA:           return  VERR_NO_DATA;
+#endif
+#ifdef ETIME
+        //case ETIME            62      /* Timer expired */
+#endif
+#ifdef ENOSR
+        //case ENOSR            63      /* Out of streams resources */
+#endif
+#ifdef ENONET
+        case ENONET:            return VERR_NET_NO_NETWORK;
+#endif
+#ifdef ENOPKG
+        //case ENOPKG           65      /* Package not installed */
+#endif
+#ifdef EREMOTE
+        //case EREMOTE          66      /* Object is remote */
+#endif
+#ifdef ENOLINK
+        //case ENOLINK          67      /* Link has been severed */
+#endif
+#ifdef EADV
+        //case EADV             68      /* Advertise error */
+#endif
+#ifdef ESRMNT
+        //case ESRMNT           69      /* Srmount error */
+#endif
+#ifdef ECOMM
+        //case ECOMM            70      /* Communication error on send */
+#endif
+#ifdef EPROTO
+        case EPROTO:            return VERR_NET_PROTOCOL_ERROR;
+#endif
+#ifdef EMULTIHOP
+        //case EMULTIHOP        72      /* Multihop attempted */
+#endif
+#ifdef EDOTDOT
+        //case EDOTDOT          73      /* RFS specific error */
+#endif
+#ifdef EBADMSG
+        //case EBADMSG          74      /* Not a data message */
+#endif
+#ifdef EOVERFLOW
+        case EOVERFLOW:         return VERR_TOO_MUCH_DATA;   /**@todo fix duplicate error */
+#endif
+#ifdef ENOTUNIQ
+        case ENOTUNIQ:          return VERR_NET_NOT_UNIQUE_NAME;
+#endif
+#ifdef EBADFD
+        case EBADFD:            return VERR_INVALID_HANDLE; /**@todo fix duplicate error? */
+#endif
+#ifdef EREMCHG
+        //case EREMCHG          78      /* Remote address changed */
+#endif
+#ifdef ELIBACC
+        //case ELIBACC          79      /* Can not access a needed shared library */
+#endif
+#ifdef ELIBBAD
+        //case ELIBBAD          80      /* Accessing a corrupted shared library */
+#endif
+#ifdef ELIBSCN
+        //case ELIBSCN          81      /* .lib section in a.out corrupted */
+#endif
+#ifdef ELIBMAX
+        //case ELIBMAX          82      /* Attempting to link in too many shared libraries */
+#endif
+#ifdef ELIBEXEC
+        //case ELIBEXEC 83      /* Cannot exec a shared library directly */
+#endif
+#ifdef EILSEQ
+        case EILSEQ:            return VERR_NO_TRANSLATION;
+#endif
+#ifdef ERESTART
+        case ERESTART:          return VERR_INTERRUPTED;/**@todo fix duplicate error?*/
+#endif
+#ifdef ESTRPIPE
+        //case ESTRPIPE 86      /* Streams pipe error */
+#endif
+#ifdef EUSERS
+        //case EUSERS           87      /* Too many users */
+#endif
+#ifdef ENOTSOCK
+        case ENOTSOCK:          return VERR_NET_NOT_SOCKET;
+#endif
+#ifdef EDESTADDRREQ
+        case EDESTADDRREQ:      return VERR_NET_DEST_ADDRESS_REQUIRED;
+#endif
+#ifdef EMSGSIZE
+        case EMSGSIZE:          return VERR_NET_MSG_SIZE;
+#endif
+#ifdef EPROTOTYPE
+        case EPROTOTYPE:        return VERR_NET_PROTOCOL_TYPE;
+#endif
+#ifdef ENOPROTOOPT
+        case ENOPROTOOPT:       return VERR_NET_PROTOCOL_NOT_AVAILABLE;
+#endif
+#ifdef EPROTONOSUPPORT
+        case EPROTONOSUPPORT:   return VERR_NET_PROTOCOL_NOT_SUPPORTED;
+#endif
+#ifdef ESOCKTNOSUPPORT
+        case ESOCKTNOSUPPORT:   return VERR_NET_SOCKET_TYPE_NOT_SUPPORTED;
+#endif
+#ifdef EOPNOTSUPP /** @todo map this differently on solaris. */
+        case EOPNOTSUPP:        return VERR_NET_OPERATION_NOT_SUPPORTED;
+#endif
+#ifdef EPFNOSUPPORT
+        case EPFNOSUPPORT:      return VERR_NET_PROTOCOL_FAMILY_NOT_SUPPORTED;
+#endif
+#ifdef EAFNOSUPPORT
+        case EAFNOSUPPORT:      return VERR_NET_ADDRESS_FAMILY_NOT_SUPPORTED;
+#endif
+#ifdef EADDRINUSE
+        case EADDRINUSE:        return VERR_NET_ADDRESS_IN_USE;
+#endif
+#ifdef EADDRNOTAVAIL
+        case EADDRNOTAVAIL:     return VERR_NET_ADDRESS_NOT_AVAILABLE;
+#endif
+#ifdef ENETDOWN
+        case ENETDOWN:          return VERR_NET_DOWN;
+#endif
+#ifdef ENETUNREACH
+        case ENETUNREACH:       return VERR_NET_UNREACHABLE;
+#endif
+#ifdef ENETRESET
+        case ENETRESET:         return VERR_NET_CONNECTION_RESET;
+#endif
+#ifdef ECONNABORTED
+        case ECONNABORTED:      return VERR_NET_CONNECTION_ABORTED;
+#endif
+#ifdef ECONNRESET
+        case ECONNRESET:        return VERR_NET_CONNECTION_RESET_BY_PEER;
+#endif
+#ifdef ENOBUFS
+        case ENOBUFS:           return VERR_NET_NO_BUFFER_SPACE;
+#endif
+#ifdef EISCONN
+        case EISCONN:           return VERR_NET_ALREADY_CONNECTED;
+#endif
+#ifdef ENOTCONN
+        case ENOTCONN:          return VERR_NET_NOT_CONNECTED;
+#endif
+#ifdef ESHUTDOWN
+        case ESHUTDOWN:         return VERR_NET_SHUTDOWN;
+#endif
+#ifdef ETOOMANYREFS
+        case ETOOMANYREFS:      return VERR_NET_TOO_MANY_REFERENCES;
+#endif
+#ifdef ETIMEDOUT
+        case ETIMEDOUT:         return VERR_TIMEOUT;
+#endif
+#ifdef ECONNREFUSED
+        case ECONNREFUSED:      return VERR_NET_CONNECTION_REFUSED;
+#endif
+#ifdef EHOSTDOWN
+        case EHOSTDOWN:         return VERR_NET_HOST_DOWN;
+#endif
+#ifdef EHOSTUNREACH
+        case EHOSTUNREACH:      return VERR_NET_HOST_UNREACHABLE;
+#endif
+#ifdef EALREADY
+        case EALREADY:          return VERR_NET_ALREADY_IN_PROGRESS;
+#endif
+#ifdef EINPROGRESS
+        case EINPROGRESS:       return VERR_NET_IN_PROGRESS;
+#endif
+#ifdef ESTALE
+        //case ESTALE           116     /* Stale NFS file handle */
+#endif
+#ifdef EUCLEAN
+        //case EUCLEAN          117     /* Structure needs cleaning */
+#endif
+#ifdef ENOTNAM
+        //case ENOTNAM          118     /* Not a XENIX named type file */
+#endif
+#ifdef ENAVAIL
+        //case ENAVAIL          119     /* No XENIX semaphores available */
+#endif
+#ifdef EISNAM
+        //case EISNAM           120     /* Is a named type file */
+#endif
+#ifdef EREMOTEIO
+        //case EREMOTEIO        121     /* Remote I/O error */
+#endif
+#ifdef EDQUOT
+        case EDQUOT:            return VERR_DISK_FULL; /**@todo fix duplicate error */
+#endif
+#ifdef ENOMEDIUM
+        case ENOMEDIUM:         return VERR_MEDIA_NOT_PRESENT;
+#endif
+#ifdef EMEDIUMTYPE
+        case EMEDIUMTYPE:       return VERR_MEDIA_NOT_RECOGNIZED;
+#endif
+#if defined(EWOULDBLOCK) && (EWOULDBLOCK != EAGAIN)
+        case EWOULDBLOCK:       return VERR_TRY_AGAIN;
+#endif
+
+        /* Non-linux */
+
+#ifdef EPROCLIM
+        case EPROCLIM:          return VERR_MAX_PROCS_REACHED;
+#endif
+#ifdef EDOOFUS
+# if EDOOFUS != EINVAL
+        case EDOOFUS:           return VERR_INTERNAL_ERROR;
+# endif
+#endif
+#ifdef ENOTSUP
+# ifndef EOPNOTSUPP
+        case ENOTSUP:           return VERR_NOT_SUPPORTED;
+# else
+#  if ENOTSUP != EOPNOTSUPP
+        case ENOTSUP:           return VERR_NOT_SUPPORTED;
+#  endif
+# endif
+#endif
+        default:
+            AssertMsgFailed(("Unhandled error code %d\n", uNativeCode));
+            return VERR_UNRESOLVED_ERROR;
+    }
+}
+RT_EXPORT_SYMBOL(RTErrConvertFromErrno);
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/vboxguest/common/err/RTErrConvertToErrno.c
@@ -0,0 +1,451 @@
+/* $Id: RTErrConvertToErrno.cpp $ */
+/** @file
+ * IPRT - Convert iprt status codes to errno.
+ */
+
+/*
+ * Copyright (C) 2007-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+
+/*********************************************************************************************************************************
+*   Header Files                                                                                                                 *
+*********************************************************************************************************************************/
+#include <iprt/err.h>
+#include "internal/iprt.h"
+
+#include <iprt/assert.h>
+#include <iprt/err.h>
+#include <iprt/errno.h>
+
+
+RTDECL(int) RTErrConvertToErrno(int iErr)
+{
+    /* very fast check for no error. */
+    if (RT_SUCCESS(iErr))
+        return 0;
+
+    /*
+     * Process error codes.
+     *
+     * (Use a switch and not a table since the numbers vary among compilers
+     * and OSes. So we let the compiler switch optimizer handle speed issues.)
+     *
+     * This switch is arranged like the Linux i386 errno.h! It also mirrors the
+     * conversions performed by RTErrConvertFromErrno with a few extra case since
+     * there are far more IPRT status codes than Unix ones.
+     */
+    switch (iErr)
+    {
+#ifdef EPERM
+        case VERR_ACCESS_DENIED:                    return EPERM;
+#endif
+#ifdef ENOENT
+        case VERR_FILE_NOT_FOUND:                   return ENOENT;
+#endif
+#ifdef ESRCH
+        case VERR_PROCESS_NOT_FOUND:                return ESRCH;
+#endif
+#ifdef EINTR
+        case VERR_INTERRUPTED:                      return EINTR;
+#endif
+#ifdef EIO
+        case VERR_DEV_IO_ERROR:                     return EIO;
+#endif
+#ifdef ENXIO
+        //case VERR_DEV_IO_ERROR:                     return ENXIO;
+#endif
+#ifdef E2BIG
+        case VERR_TOO_MUCH_DATA:                    return E2BIG;
+#endif
+#ifdef ENOEXEC
+        case VERR_BAD_EXE_FORMAT:                   return ENOEXEC;
+#endif
+#ifdef EBADF
+        case VERR_INVALID_HANDLE:                   return EBADF;
+#endif
+#ifdef ECHILD
+        //case VERR_PROCESS_NOT_FOUND:                return ECHILD;
+#endif
+#ifdef EAGAIN
+        case VERR_TRY_AGAIN:                        return EAGAIN;
+#endif
+#ifdef ENOMEM
+        case VERR_NO_MEMORY:                        return ENOMEM;
+#endif
+#ifdef EACCES
+        //case VERR_ACCESS_DENIED:                    return EACCES;
+#endif
+#ifdef EFAULT
+        case VERR_INVALID_POINTER:                  return EFAULT;
+#endif
+#ifdef ENOTBLK
+        //case ENOTBLK:           return VERR_;
+#endif
+#ifdef EBUSY
+        case VERR_RESOURCE_BUSY:                    return EBUSY;
+#endif
+#ifdef EEXIST
+        case VERR_ALREADY_EXISTS:                   return EEXIST;
+#endif
+#ifdef EXDEV
+        case VERR_NOT_SAME_DEVICE:                  return EXDEV;
+#endif
+#ifdef ENODEV
+        //case VERR_NOT_SUPPORTED:                    return ENODEV;
+#endif
+#ifdef ENOTDIR
+        case VERR_NOT_A_DIRECTORY:
+        case VERR_PATH_NOT_FOUND:                   return ENOTDIR;
+#endif
+#ifdef EISDIR
+        case VERR_IS_A_DIRECTORY:                   return EISDIR;
+#endif
+#ifdef EINVAL
+        case VERR_INVALID_PARAMETER:                return EINVAL;
+#endif
+#ifdef ENFILE
+        case VERR_TOO_MANY_OPEN_FILES:              return ENFILE;
+#endif
+#ifdef EMFILE
+        //case VERR_TOO_MANY_OPEN_FILES:              return EMFILE;
+#endif
+#ifdef ENOTTY
+        case VERR_INVALID_FUNCTION:                 return ENOTTY;
+#endif
+#ifdef ETXTBSY
+        case VERR_SHARING_VIOLATION:                return ETXTBSY;
+#endif
+#ifdef EFBIG
+        case VERR_FILE_TOO_BIG:                     return EFBIG;
+#endif
+#ifdef ENOSPC
+        case VERR_DISK_FULL:                        return ENOSPC;
+#endif
+#ifdef ESPIPE
+        case VERR_SEEK_ON_DEVICE:                   return ESPIPE;
+#endif
+#ifdef EROFS
+        case VERR_WRITE_PROTECT:                    return EROFS;
+#endif
+#ifdef EMLINK
+        //case EMLINK:
+#endif
+#ifdef EPIPE
+        case VERR_BROKEN_PIPE:                      return EPIPE;
+#endif
+#ifdef EDOM
+        //case VERR_INVALID_PARAMETER:    return EDOM;
+#endif
+#ifdef ERANGE
+        //case VERR_INVALID_PARAMETER:    return ERANGE;
+#endif
+#ifdef EDEADLK
+        case VERR_DEADLOCK:                         return EDEADLK;
+#endif
+#ifdef ENAMETOOLONG
+        case VERR_FILENAME_TOO_LONG:                return ENAMETOOLONG;
+#endif
+#ifdef ENOLCK
+        case VERR_FILE_LOCK_FAILED:                 return ENOLCK;
+#endif
+#ifdef ENOSYS
+        case VERR_NOT_IMPLEMENTED:
+        case VERR_NOT_SUPPORTED:                    return ENOSYS;
+#endif
+#ifdef ENOTEMPTY
+        case VERR_DIR_NOT_EMPTY:                    return ENOTEMPTY;
+#endif
+#ifdef ELOOP
+        case VERR_TOO_MANY_SYMLINKS:                return ELOOP;
+#endif
+        //41??
+#ifdef ENOMSG
+        //case ENOMSG           42      /* No message of desired type */
+#endif
+#ifdef EIDRM
+        //case EIDRM            43      /* Identifier removed */
+#endif
+#ifdef ECHRNG
+        //case ECHRNG           44      /* Channel number out of range */
+#endif
+#ifdef EL2NSYNC
+        //case EL2NSYNC 45      /* Level 2 not synchronized */
+#endif
+#ifdef EL3HLT
+        //case EL3HLT           46      /* Level 3 halted */
+#endif
+#ifdef EL3RST
+        //case EL3RST           47      /* Level 3 reset */
+#endif
+#ifdef ELNRNG
+        //case ELNRNG           48      /* Link number out of range */
+#endif
+#ifdef EUNATCH
+        //case EUNATCH          49      /* Protocol driver not attached */
+#endif
+#ifdef ENOCSI
+        //case ENOCSI           50      /* No CSI structure available */
+#endif
+#ifdef EL2HLT
+        //case EL2HLT           51      /* Level 2 halted */
+#endif
+#ifdef EBADE
+        //case EBADE            52      /* Invalid exchange */
+#endif
+#ifdef EBADR
+        //case EBADR            53      /* Invalid request descriptor */
+#endif
+#ifdef EXFULL
+        //case EXFULL           54      /* Exchange full */
+#endif
+#ifdef ENOANO
+        //case ENOANO           55      /* No anode */
+#endif
+#ifdef EBADRQC
+        //case EBADRQC          56      /* Invalid request code */
+#endif
+#ifdef EBADSLT
+        //case EBADSLT          57      /* Invalid slot */
+#endif
+        //case 58:
+#ifdef EBFONT
+        //case EBFONT           59      /* Bad font file format */
+#endif
+#ifdef ENOSTR
+        //case ENOSTR           60      /* Device not a stream */
+#endif
+#ifdef ENODATA
+        case VERR_NO_DATA:                          return ENODATA;
+#endif
+#ifdef ETIME
+        //case ETIME            62      /* Timer expired */
+#endif
+#ifdef ENOSR
+        //case ENOSR            63      /* Out of streams resources */
+#endif
+#ifdef ENONET
+        case VERR_NET_NO_NETWORK:                   return ENONET;
+#endif
+#ifdef ENOPKG
+        //case ENOPKG           65      /* Package not installed */
+#endif
+#ifdef EREMOTE
+        //case EREMOTE          66      /* Object is remote */
+#endif
+#ifdef ENOLINK
+        //case ENOLINK          67      /* Link has been severed */
+#endif
+#ifdef EADV
+        //case EADV             68      /* Advertise error */
+#endif
+#ifdef ESRMNT
+        //case ESRMNT           69      /* Srmount error */
+#endif
+#ifdef ECOMM
+        //case ECOMM            70      /* Communication error on send */
+#endif
+#ifdef EPROTO
+        //case EPROTO           71      /* Protocol error */
+#endif
+#ifdef EMULTIHOP
+        //case EMULTIHOP        72      /* Multihop attempted */
+#endif
+#ifdef EDOTDOT
+        //case EDOTDOT          73      /* RFS specific error */
+#endif
+#ifdef EBADMSG
+        //case EBADMSG          74      /* Not a data message */
+#endif
+#ifdef EOVERFLOW
+        //case VERR_TOO_MUCH_DATA:                    return EOVERFLOW;
+#endif
+#ifdef ENOTUNIQ
+        case VERR_NET_NOT_UNIQUE_NAME:              return ENOTUNIQ;
+#endif
+#ifdef EBADFD
+        //case VERR_INVALID_HANDLE:                   return EBADFD;
+#endif
+#ifdef EREMCHG
+        //case EREMCHG          78      /* Remote address changed */
+#endif
+#ifdef ELIBACC
+        //case ELIBACC          79      /* Can not access a needed shared library */
+#endif
+#ifdef ELIBBAD
+        //case ELIBBAD          80      /* Accessing a corrupted shared library */
+#endif
+#ifdef ELIBSCN
+        //case ELIBSCN          81      /* .lib section in a.out corrupted */
+#endif
+#ifdef ELIBMAX
+        //case ELIBMAX          82      /* Attempting to link in too many shared libraries */
+#endif
+#ifdef ELIBEXEC
+        //case ELIBEXEC 83      /* Cannot exec a shared library directly */
+#endif
+#ifdef EILSEQ
+        case VERR_NO_TRANSLATION:                   return EILSEQ;
+#endif
+#ifdef ERESTART
+        //case VERR_INTERRUPTED:                      return ERESTART;
+#endif
+#ifdef ESTRPIPE
+        //case ESTRPIPE 86      /* Streams pipe error */
+#endif
+#ifdef EUSERS
+        //case EUSERS           87      /* Too many users */
+#endif
+#ifdef ENOTSOCK
+        case VERR_NET_NOT_SOCKET:                   return ENOTSOCK;
+#endif
+#ifdef EDESTADDRREQ
+        case VERR_NET_DEST_ADDRESS_REQUIRED:        return EDESTADDRREQ;
+#endif
+#ifdef EMSGSIZE
+        case VERR_NET_MSG_SIZE:                     return EMSGSIZE;
+#endif
+#ifdef EPROTOTYPE
+        case VERR_NET_PROTOCOL_TYPE:                return EPROTOTYPE;
+#endif
+#ifdef ENOPROTOOPT
+        case VERR_NET_PROTOCOL_NOT_AVAILABLE:       return ENOPROTOOPT;
+#endif
+#ifdef EPROTONOSUPPORT
+        case VERR_NET_PROTOCOL_NOT_SUPPORTED:       return EPROTONOSUPPORT;
+#endif
+#ifdef ESOCKTNOSUPPORT
+        case VERR_NET_SOCKET_TYPE_NOT_SUPPORTED:    return ESOCKTNOSUPPORT;
+#endif
+#ifdef EOPNOTSUPP
+        case VERR_NET_OPERATION_NOT_SUPPORTED:      return EOPNOTSUPP;
+#endif
+#ifdef EPFNOSUPPORT
+        case VERR_NET_PROTOCOL_FAMILY_NOT_SUPPORTED: return EPFNOSUPPORT;
+#endif
+#ifdef EAFNOSUPPORT
+        case VERR_NET_ADDRESS_FAMILY_NOT_SUPPORTED: return EAFNOSUPPORT;
+#endif
+#ifdef EADDRINUSE
+        case VERR_NET_ADDRESS_IN_USE:               return EADDRINUSE;
+#endif
+#ifdef EADDRNOTAVAIL
+        case VERR_NET_ADDRESS_NOT_AVAILABLE:        return EADDRNOTAVAIL;
+#endif
+#ifdef ENETDOWN
+        case VERR_NET_DOWN:                         return ENETDOWN;
+#endif
+#ifdef ENETUNREACH
+        case VERR_NET_UNREACHABLE:                  return ENETUNREACH;
+#endif
+#ifdef ENETRESET
+        case VERR_NET_CONNECTION_RESET:             return ENETRESET;
+#endif
+#ifdef ECONNABORTED
+        case VERR_NET_CONNECTION_ABORTED:           return ECONNABORTED;
+#endif
+#ifdef ECONNRESET
+        case VERR_NET_CONNECTION_RESET_BY_PEER:     return ECONNRESET;
+#endif
+#ifdef ENOBUFS
+        case VERR_NET_NO_BUFFER_SPACE:              return ENOBUFS;
+#endif
+#ifdef EISCONN
+        case VERR_NET_ALREADY_CONNECTED:            return EISCONN;
+#endif
+#ifdef ENOTCONN
+        case VERR_NET_NOT_CONNECTED:                return ENOTCONN;
+#endif
+#ifdef ESHUTDOWN
+        case VERR_NET_SHUTDOWN:                     return ESHUTDOWN;
+#endif
+#ifdef ETOOMANYREFS
+        case VERR_NET_TOO_MANY_REFERENCES:          return ETOOMANYREFS;
+#endif
+#ifdef ETIMEDOUT
+        case VERR_TIMEOUT:                          return ETIMEDOUT;
+#endif
+#ifdef ECONNREFUSED
+        case VERR_NET_CONNECTION_REFUSED:           return ECONNREFUSED;
+#endif
+#ifdef EHOSTDOWN
+        case VERR_NET_HOST_DOWN:                    return EHOSTDOWN;
+#endif
+#ifdef EHOSTUNREACH
+        case VERR_NET_HOST_UNREACHABLE:             return EHOSTUNREACH;
+#endif
+#ifdef EALREADY
+        case VERR_NET_ALREADY_IN_PROGRESS:          return EALREADY;
+#endif
+#ifdef EINPROGRESS
+        case VERR_NET_IN_PROGRESS:                  return EINPROGRESS;
+#endif
+#ifdef ESTALE
+        //case ESTALE           116     /* Stale NFS file handle */
+#endif
+#ifdef EUCLEAN
+        //case EUCLEAN          117     /* Structure needs cleaning */
+#endif
+#ifdef ENOTNAM
+        //case ENOTNAM          118     /* Not a XENIX named type file */
+#endif
+#ifdef ENAVAIL
+        //case ENAVAIL          119     /* No XENIX semaphores available */
+#endif
+#ifdef EISNAM
+        //case EISNAM           120     /* Is a named type file */
+#endif
+#ifdef EREMOTEIO
+        //case EREMOTEIO        121     /* Remote I/O error */
+#endif
+#ifdef EDQUOT
+        //case VERR_DISK_FULL:                        return EDQUOT;
+#endif
+#ifdef ENOMEDIUM
+        case VERR_MEDIA_NOT_PRESENT:                return ENOMEDIUM;
+#endif
+#ifdef EMEDIUMTYPE
+        case VERR_MEDIA_NOT_RECOGNIZED:             return EMEDIUMTYPE;
+#endif
+
+        /* Non-linux */
+
+#ifdef EPROCLIM
+        case VERR_MAX_PROCS_REACHED:                return EPROCLIM;
+#endif
+#ifdef EDOOFUS
+        case VERR_INTERNAL_ERROR:
+        case VERR_INTERNAL_ERROR_2:
+        case VERR_INTERNAL_ERROR_3:                 return EDOOFUS;
+#endif
+
+        default:
+            /* The idea here is that if you hit this, you will have to
+               translate the status code yourself. */
+            AssertMsgFailed(("Unhandled error code %Rrc\n", iErr));
+#ifdef EPROTO
+            return EPROTO;
+#else
+            return EINVAL;
+#endif
+    }
+}
+RT_EXPORT_SYMBOL(RTErrConvertToErrno);
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/vboxguest/common/log/log.c
@@ -0,0 +1,3922 @@
+/* $Id: log.cpp $ */
+/** @file
+ * Runtime VBox - Logger.
+ */
+
+/*
+ * Copyright (C) 2006-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+
+/*********************************************************************************************************************************
+*   Header Files                                                                                                                 *
+*********************************************************************************************************************************/
+#include <iprt/log.h>
+#include "internal/iprt.h"
+
+#ifndef IN_RC
+# include <iprt/alloc.h>
+# include <iprt/process.h>
+# include <iprt/semaphore.h>
+# include <iprt/thread.h>
+# include <iprt/mp.h>
+#endif
+#ifdef IN_RING3
+# include <iprt/env.h>
+# include <iprt/file.h>
+# include <iprt/lockvalidator.h>
+# include <iprt/path.h>
+#endif
+#include <iprt/time.h>
+#include <iprt/asm.h>
+#if defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86)
+# include <iprt/asm-amd64-x86.h>
+#endif
+#include <iprt/assert.h>
+#include <iprt/err.h>
+#include <iprt/param.h>
+
+#include <iprt/stdarg.h>
+#include <iprt/string.h>
+#include <iprt/ctype.h>
+#ifdef IN_RING3
+# include <iprt/alloca.h>
+# include <stdio.h>
+#endif
+
+
+/*********************************************************************************************************************************
+*   Defined Constants And Macros                                                                                                 *
+*********************************************************************************************************************************/
+/** @def RTLOG_RINGBUF_DEFAULT_SIZE
+ * The default ring buffer size. */
+/** @def RTLOG_RINGBUF_MAX_SIZE
+ * The max ring buffer size. */
+/** @def RTLOG_RINGBUF_MIN_SIZE
+ * The min ring buffer size. */
+#ifdef IN_RING0
+# define RTLOG_RINGBUF_DEFAULT_SIZE     _64K
+# define RTLOG_RINGBUF_MAX_SIZE         _4M
+# define RTLOG_RINGBUF_MIN_SIZE         _1K
+#elif defined(IN_RING3) || defined(DOXYGEN_RUNNING)
+# define RTLOG_RINGBUF_DEFAULT_SIZE     _512K
+# define RTLOG_RINGBUF_MAX_SIZE         _1G
+# define RTLOG_RINGBUF_MIN_SIZE         _4K
+#endif
+/** The start of ring buffer eye catcher (16 bytes). */
+#define RTLOG_RINGBUF_EYE_CATCHER           "START RING BUF\0"
+AssertCompile(sizeof(RTLOG_RINGBUF_EYE_CATCHER) == 16);
+/** The end of ring buffer eye catcher (16 bytes).  This also ensures that the ring buffer
+ * forms are properly terminated C string (leading zero chars).  */
+#define RTLOG_RINGBUF_EYE_CATCHER_END    "\0\0\0END RING BUF"
+AssertCompile(sizeof(RTLOG_RINGBUF_EYE_CATCHER_END) == 16);
+
+
+/*********************************************************************************************************************************
+*   Structures and Typedefs                                                                                                      *
+*********************************************************************************************************************************/
+/**
+ * Arguments passed to the output function.
+ */
+typedef struct RTLOGOUTPUTPREFIXEDARGS
+{
+    /** The logger instance. */
+    PRTLOGGER               pLogger;
+    /** The flags. (used for prefixing.) */
+    unsigned                fFlags;
+    /** The group. (used for prefixing.) */
+    unsigned                iGroup;
+} RTLOGOUTPUTPREFIXEDARGS, *PRTLOGOUTPUTPREFIXEDARGS;
+
+#ifndef IN_RC
+
+/**
+ * Internal logger data.
+ *
+ * @remarks Don't make casual changes to this structure.
+ */
+typedef struct RTLOGGERINTERNAL
+{
+    /** The structure revision (RTLOGGERINTERNAL_REV). */
+    uint32_t                uRevision;
+    /** The size of the internal logger structure. */
+    uint32_t                cbSelf;
+
+    /** Spinning mutex semaphore.  Can be NIL. */
+    RTSEMSPINMUTEX          hSpinMtx;
+    /** Pointer to the flush function. */
+    PFNRTLOGFLUSH           pfnFlush;
+
+    /** Custom prefix callback. */
+    PFNRTLOGPREFIX          pfnPrefix;
+    /** Prefix callback argument. */
+    void                   *pvPrefixUserArg;
+    /** This is set if a prefix is pending. */
+    bool                    fPendingPrefix;
+    /** Alignment padding. */
+    bool                    afPadding1[2];
+    /** Set if fully created.  Used to avoid confusing in a few functions used to
+     * parse logger settings from environment variables. */
+    bool                    fCreated;
+
+    /** The max number of groups that there is room for in afGroups and papszGroups.
+     * Used by RTLogCopyGroupAndFlags(). */
+    uint32_t                cMaxGroups;
+    /** Pointer to the group name array.
+     * (The data is readonly and provided by the user.) */
+    const char * const     *papszGroups;
+
+    /** The number of log entries per group.  NULL if
+     * RTLOGFLAGS_RESTRICT_GROUPS is not specified. */
+    uint32_t               *pacEntriesPerGroup;
+    /** The max number of entries per group. */
+    uint32_t                cMaxEntriesPerGroup;
+
+    /** @name Ring buffer logging
+     * The ring buffer records the last cbRingBuf - 1 of log output.  The
+     * other configured log destinations are not touched until someone calls
+     * RTLogFlush(), when the ring buffer content is written to them all.
+     *
+     * The aim here is a fast logging destination, that avoids wasting storage
+     * space saving disk space when dealing with huge log volumes where the
+     * interesting bits usually are found near the end of the log.  This is
+     * typically the case for scenarios that crashes or hits assertions.
+     *
+     * RTLogFlush() is called implicitly when hitting an assertion.  While on a
+     * crash the most debuggers are able to make calls these days, it's usually
+     * possible to view the ring buffer memory.
+     *
+     * @{ */
+    /** Ring buffer size (including both eye catchers). */
+    uint32_t                cbRingBuf;
+    /** Number of bytes passing thru the ring buffer since last RTLogFlush call.
+     * (This is used to avoid writing out the same bytes twice.) */
+    uint64_t volatile       cbRingBufUnflushed;
+    /** Ring buffer pointer (points at RTLOG_RINGBUF_EYE_CATCHER). */
+    char                   *pszRingBuf;
+    /** Current ring buffer position (where to write the next char). */
+    char * volatile         pchRingBufCur;
+    /** @} */
+
+# ifdef IN_RING3 /* Note! Must be at the end! */
+    /** @name File logging bits for the logger.
+     * @{ */
+    /** Pointer to the function called when starting logging, and when
+     * ending or starting a new log file as part of history rotation.
+     * This can be NULL. */
+    PFNRTLOGPHASE           pfnPhase;
+
+    /** Handle to log file (if open). */
+    RTFILE                  hFile;
+    /** Log file history settings: maximum amount of data to put in a file. */
+    uint64_t                cbHistoryFileMax;
+    /** Log file history settings: current amount of data in a file. */
+    uint64_t                cbHistoryFileWritten;
+    /** Log file history settings: maximum time to use a file (in seconds). */
+    uint32_t                cSecsHistoryTimeSlot;
+    /** Log file history settings: in what time slot was the file created. */
+    uint32_t                uHistoryTimeSlotStart;
+    /** Log file history settings: number of older files to keep.
+     * 0 means no history. */
+    uint32_t                cHistory;
+    /** Pointer to filename. */
+    char                    szFilename[RTPATH_MAX];
+    /** @} */
+# endif /* IN_RING3 */
+} RTLOGGERINTERNAL;
+
+/** The revision of the internal logger structure. */
+# define RTLOGGERINTERNAL_REV    UINT32_C(10)
+
+# ifdef IN_RING3
+/** The size of the RTLOGGERINTERNAL structure in ring-0.  */
+#  define RTLOGGERINTERNAL_R0_SIZE       RT_OFFSETOF(RTLOGGERINTERNAL, pfnPhase)
+AssertCompileMemberAlignment(RTLOGGERINTERNAL, hFile, sizeof(void *));
+AssertCompileMemberAlignment(RTLOGGERINTERNAL, cbHistoryFileMax, sizeof(uint64_t));
+# endif
+AssertCompileMemberAlignment(RTLOGGERINTERNAL, cbRingBufUnflushed, sizeof(uint64_t));
+
+#endif /* !IN_RC */
+
+
+/*********************************************************************************************************************************
+*   Internal Functions                                                                                                           *
+*********************************************************************************************************************************/
+#ifndef IN_RC
+static unsigned rtlogGroupFlags(const char *psz);
+#endif
+#ifdef IN_RING0
+static void rtR0LogLoggerExFallback(uint32_t fDestFlags, uint32_t fFlags, PRTLOGGERINTERNAL pInt,
+                                    const char *pszFormat, va_list va);
+#endif
+#ifdef IN_RING3
+static int rtlogFileOpen(PRTLOGGER pLogger, char *pszErrorMsg, size_t cchErrorMsg);
+static void rtlogRotate(PRTLOGGER pLogger, uint32_t uTimeSlot, bool fFirst);
+#endif
+#ifndef IN_RC
+static void rtLogRingBufFlush(PRTLOGGER pLogger);
+#endif
+static void rtlogFlush(PRTLOGGER pLogger);
+static DECLCALLBACK(size_t) rtLogOutput(void *pv, const char *pachChars, size_t cbChars);
+static DECLCALLBACK(size_t) rtLogOutputPrefixed(void *pv, const char *pachChars, size_t cbChars);
+static void rtlogLoggerExVLocked(PRTLOGGER pLogger, unsigned fFlags, unsigned iGroup, const char *pszFormat, va_list args);
+#ifndef IN_RC
+static void rtlogLoggerExFLocked(PRTLOGGER pLogger, unsigned fFlags, unsigned iGroup, const char *pszFormat, ...);
+#endif
+
+
+/*********************************************************************************************************************************
+*   Global Variables                                                                                                             *
+*********************************************************************************************************************************/
+#ifdef IN_RC
+/** Default logger instance. Make it weak because our RC module loader does not
+ *  necessarily resolve this symbol and the compiler _must_ check if this is
+ *  the case or not. That doesn't work for Darwin (``incompatible feature used:
+ *  .weak_reference (must specify "-dynamic" to be used'') */
+# ifdef RT_OS_DARWIN
+extern "C" DECLIMPORT(RTLOGGERRC) g_Logger;
+# else
+extern "C" DECLWEAK(DECLIMPORT(RTLOGGERRC)) g_Logger;
+# endif
+#else /* !IN_RC */
+/** Default logger instance. */
+static PRTLOGGER                    g_pLogger;
+#endif /* !IN_RC */
+#ifdef IN_RING3
+/** The RTThreadGetWriteLockCount() change caused by the logger mutex semaphore. */
+static uint32_t volatile            g_cLoggerLockCount;
+#endif
+
+#ifdef IN_RING0
+/** Number of per-thread loggers. */
+static int32_t volatile             g_cPerThreadLoggers;
+/** Per-thread loggers.
+ * This is just a quick TLS hack suitable for debug logging only.
+ * If we run out of entries, just unload and reload the driver. */
+static struct RTLOGGERPERTHREAD
+{
+    /** The thread. */
+    RTNATIVETHREAD volatile NativeThread;
+    /** The (process / session) key. */
+    uintptr_t volatile      uKey;
+    /** The logger instance.*/
+    PRTLOGGER volatile      pLogger;
+} g_aPerThreadLoggers[8] =
+{
+    { NIL_RTNATIVETHREAD, 0, 0},
+    { NIL_RTNATIVETHREAD, 0, 0},
+    { NIL_RTNATIVETHREAD, 0, 0},
+    { NIL_RTNATIVETHREAD, 0, 0},
+    { NIL_RTNATIVETHREAD, 0, 0},
+    { NIL_RTNATIVETHREAD, 0, 0},
+    { NIL_RTNATIVETHREAD, 0, 0},
+    { NIL_RTNATIVETHREAD, 0, 0}
+};
+#endif /* IN_RING0 */
+
+/**
+ * Logger flags instructions.
+ */
+static struct
+{
+    const char *pszInstr;               /**< The name  */
+    size_t      cchInstr;               /**< The size of the name. */
+    uint32_t    fFlag;                  /**< The flag value. */
+    bool        fInverted;              /**< Inverse meaning? */
+} const g_aLogFlags[] =
+{
+    { "disabled",     sizeof("disabled"    ) - 1,   RTLOGFLAGS_DISABLED,            false },
+    { "enabled",      sizeof("enabled"     ) - 1,   RTLOGFLAGS_DISABLED,            true  },
+    { "buffered",     sizeof("buffered"    ) - 1,   RTLOGFLAGS_BUFFERED,            false },
+    { "unbuffered",   sizeof("unbuffered"  ) - 1,   RTLOGFLAGS_BUFFERED,            true  },
+    { "usecrlf",      sizeof("usecrlf"     ) - 1,   RTLOGFLAGS_USECRLF,             false },
+    { "uself",        sizeof("uself"       ) - 1,   RTLOGFLAGS_USECRLF,             true  },
+    { "append",       sizeof("append"      ) - 1,   RTLOGFLAGS_APPEND,              false },
+    { "overwrite",    sizeof("overwrite"   ) - 1,   RTLOGFLAGS_APPEND,              true  },
+    { "rel",          sizeof("rel"         ) - 1,   RTLOGFLAGS_REL_TS,              false },
+    { "abs",          sizeof("abs"         ) - 1,   RTLOGFLAGS_REL_TS,              true  },
+    { "dec",          sizeof("dec"         ) - 1,   RTLOGFLAGS_DECIMAL_TS,          false },
+    { "hex",          sizeof("hex"         ) - 1,   RTLOGFLAGS_DECIMAL_TS,          true  },
+    { "writethru",    sizeof("writethru"   ) - 1,   RTLOGFLAGS_WRITE_THROUGH,       false },
+    { "writethrough", sizeof("writethrough") - 1,   RTLOGFLAGS_WRITE_THROUGH,       false },
+    { "flush",        sizeof("flush"       ) - 1,   RTLOGFLAGS_FLUSH,               false },
+    { "lockcnts",     sizeof("lockcnts"    ) - 1,   RTLOGFLAGS_PREFIX_LOCK_COUNTS,  false },
+    { "cpuid",        sizeof("cpuid"       ) - 1,   RTLOGFLAGS_PREFIX_CPUID,        false },
+    { "pid",          sizeof("pid"         ) - 1,   RTLOGFLAGS_PREFIX_PID,          false },
+    { "flagno",       sizeof("flagno"      ) - 1,   RTLOGFLAGS_PREFIX_FLAG_NO,      false },
+    { "flag",         sizeof("flag"        ) - 1,   RTLOGFLAGS_PREFIX_FLAG,         false },
+    { "groupno",      sizeof("groupno"     ) - 1,   RTLOGFLAGS_PREFIX_GROUP_NO,     false },
+    { "group",        sizeof("group"       ) - 1,   RTLOGFLAGS_PREFIX_GROUP,        false },
+    { "tid",          sizeof("tid"         ) - 1,   RTLOGFLAGS_PREFIX_TID,          false },
+    { "thread",       sizeof("thread"      ) - 1,   RTLOGFLAGS_PREFIX_THREAD,       false },
+    { "custom",       sizeof("custom"      ) - 1,   RTLOGFLAGS_PREFIX_CUSTOM,       false },
+    { "timeprog",     sizeof("timeprog"    ) - 1,   RTLOGFLAGS_PREFIX_TIME_PROG,    false },
+    { "time",         sizeof("time"        ) - 1,   RTLOGFLAGS_PREFIX_TIME,         false },
+    { "msprog",       sizeof("msprog"      ) - 1,   RTLOGFLAGS_PREFIX_MS_PROG,      false },
+    { "tsc",          sizeof("tsc"         ) - 1,   RTLOGFLAGS_PREFIX_TSC,          false }, /* before ts! */
+    { "ts",           sizeof("ts"          ) - 1,   RTLOGFLAGS_PREFIX_TS,           false },
+    /* We intentionally omit RTLOGFLAGS_RESTRICT_GROUPS. */
+};
+
+/**
+ * Logger destination instructions.
+ */
+static struct
+{
+    const char *pszInstr;               /**< The name. */
+    size_t      cchInstr;               /**< The size of the name. */
+    uint32_t    fFlag;                  /**< The corresponding destination flag. */
+} const s_aLogDst[] =
+{
+    { RT_STR_TUPLE("file"),         RTLOGDEST_FILE },       /* Must be 1st! */
+    { RT_STR_TUPLE("dir"),          RTLOGDEST_FILE },       /* Must be 2nd! */
+    { RT_STR_TUPLE("history"),      0 },                    /* Must be 3rd! */
+    { RT_STR_TUPLE("histsize"),     0 },                    /* Must be 4th! */
+    { RT_STR_TUPLE("histtime"),     0 },                    /* Must be 5th! */
+    { RT_STR_TUPLE("ringbuf"),      RTLOGDEST_RINGBUF },    /* Must be 6th! */
+    { RT_STR_TUPLE("stdout"),       RTLOGDEST_STDOUT },
+    { RT_STR_TUPLE("stderr"),       RTLOGDEST_STDERR },
+    { RT_STR_TUPLE("debugger"),     RTLOGDEST_DEBUGGER },
+    { RT_STR_TUPLE("com"),          RTLOGDEST_COM },
+    { RT_STR_TUPLE("user"),         RTLOGDEST_USER },
+};
+
+/** Log rotation backoff table - millisecond sleep intervals.
+ * Important on Windows host, especially for VBoxSVC release logging.  Only a
+ * medium term solution, until a proper fix for log file handling is available.
+ * 10 seconds total.
+ */
+static const uint32_t g_acMsLogBackoff[] =
+{ 10, 10, 10, 20, 50, 100, 200, 200, 200, 200, 500, 500, 500, 500, 1000, 1000, 1000, 1000, 1000, 1000, 1000 };
+
+
+/**
+ * Locks the logger instance.
+ *
+ * @returns See RTSemSpinMutexRequest().
+ * @param   pLogger     The logger instance.
+ */
+DECLINLINE(int) rtlogLock(PRTLOGGER pLogger)
+{
+#ifndef IN_RC
+    PRTLOGGERINTERNAL pInt = pLogger->pInt;
+    AssertMsgReturn(pInt->uRevision == RTLOGGERINTERNAL_REV, ("%#x != %#x\n", pInt->uRevision, RTLOGGERINTERNAL_REV),
+                    VERR_LOG_REVISION_MISMATCH);
+    AssertMsgReturn(pInt->cbSelf == sizeof(*pInt), ("%#x != %#x\n", pInt->cbSelf, sizeof(*pInt)),
+                    VERR_LOG_REVISION_MISMATCH);
+    if (pInt->hSpinMtx != NIL_RTSEMSPINMUTEX)
+    {
+        int rc = RTSemSpinMutexRequest(pInt->hSpinMtx);
+        if (RT_FAILURE(rc))
+            return rc;
+    }
+#else
+    NOREF(pLogger);
+#endif
+    return VINF_SUCCESS;
+}
+
+
+/**
+ * Unlocks the logger instance.
+ * @param   pLogger     The logger instance.
+ */
+DECLINLINE(void) rtlogUnlock(PRTLOGGER pLogger)
+{
+#ifndef IN_RC
+    if (pLogger->pInt->hSpinMtx != NIL_RTSEMSPINMUTEX)
+        RTSemSpinMutexRelease(pLogger->pInt->hSpinMtx);
+#else
+    NOREF(pLogger);
+#endif
+    return;
+}
+
+#ifndef IN_RC
+# ifdef IN_RING3
+
+#  ifdef SOME_UNUSED_FUNCTION
+/**
+ * Logging to file, output callback.
+ *
+ * @param  pvArg        User argument.
+ * @param  pachChars    Pointer to an array of utf-8 characters.
+ * @param  cbChars      Number of bytes in the character array pointed to by pachChars.
+ */
+static DECLCALLBACK(size_t) rtlogPhaseWrite(void *pvArg, const char *pachChars, size_t cbChars)
+{
+    PRTLOGGER pLogger = (PRTLOGGER)pvArg;
+    RTFileWrite(pLogger->pInt->hFile, pachChars, cbChars, NULL);
+    return cbChars;
+}
+
+
+/**
+ * Callback to format VBox formatting extentions.
+ * See @ref pg_rt_str_format for a reference on the format types.
+ *
+ * @returns The number of bytes formatted.
+ * @param   pvArg           Formatter argument.
+ * @param   pfnOutput       Pointer to output function.
+ * @param   pvArgOutput     Argument for the output function.
+ * @param   ppszFormat      Pointer to the format string pointer. Advance this till the char
+ *                          after the format specifier.
+ * @param   pArgs           Pointer to the argument list. Use this to fetch the arguments.
+ * @param   cchWidth        Format Width. -1 if not specified.
+ * @param   cchPrecision    Format Precision. -1 if not specified.
+ * @param   fFlags          Flags (RTSTR_NTFS_*).
+ * @param   chArgSize       The argument size specifier, 'l' or 'L'.
+ */
+static DECLCALLBACK(size_t) rtlogPhaseFormatStr(void *pvArg, PFNRTSTROUTPUT pfnOutput, void *pvArgOutput,
+                                                const char **ppszFormat, va_list *pArgs, int cchWidth,
+                                                int cchPrecision, unsigned fFlags, char chArgSize)
+{
+    char ch = *(*ppszFormat)++;
+
+    AssertMsgFailed(("Invalid logger phase format type '%%%c%.10s'!\n", ch, *ppszFormat)); NOREF(ch);
+
+    return 0;
+}
+
+#  endif /* SOME_UNUSED_FUNCTION */
+
+
+/**
+ * Log phase callback function, assumes the lock is already held
+ *
+ * @param   pLogger     The logger instance.
+ * @param   pszFormat   Format string.
+ * @param   ...         Optional arguments as specified in the format string.
+ */
+static DECLCALLBACK(void) rtlogPhaseMsgLocked(PRTLOGGER pLogger, const char *pszFormat, ...)
+{
+    va_list args;
+    AssertPtrReturnVoid(pLogger);
+    AssertPtrReturnVoid(pLogger->pInt);
+    Assert(pLogger->pInt->hSpinMtx != NIL_RTSEMSPINMUTEX);
+
+    va_start(args, pszFormat);
+    rtlogLoggerExVLocked(pLogger, 0, ~0, pszFormat, args);
+    va_end(args);
+}
+
+
+/**
+ * Log phase callback function, assumes the lock is not held.
+ *
+ * @param   pLogger     The logger instance.
+ * @param   pszFormat   Format string.
+ * @param   ...         Optional arguments as specified in the format string.
+ */
+static DECLCALLBACK(void) rtlogPhaseMsgNormal(PRTLOGGER pLogger, const char *pszFormat, ...)
+{
+    va_list args;
+    AssertPtrReturnVoid(pLogger);
+    AssertPtrReturnVoid(pLogger->pInt);
+    Assert(pLogger->pInt->hSpinMtx != NIL_RTSEMSPINMUTEX);
+
+    va_start(args, pszFormat);
+    RTLogLoggerExV(pLogger, 0, ~0, pszFormat, args);
+    va_end(args);
+}
+
+# endif /* IN_RING3 */
+
+/**
+ * Adjusts the ring buffer.
+ *
+ * @returns IPRT status code.
+ * @param   pLogger     The logger instance.
+ * @param   cbNewSize   The new ring buffer size (0 == default).
+ * @param   fForce      Whether to do this even if the logger instance hasn't
+ *                      really been fully created yet (i.e. during RTLogCreate).
+ */
+static int rtLogRingBufAdjust(PRTLOGGER pLogger, uint32_t cbNewSize, bool fForce)
+{
+    /*
+     * If this is early logger init, don't do anything.
+     */
+    if (!pLogger->pInt->fCreated && !fForce)
+        return VINF_SUCCESS;
+
+    /*
+     * Lock the logger and make the necessary changes.
+     */
+    int rc = rtlogLock(pLogger);
+    if (RT_SUCCESS(rc))
+    {
+        if (cbNewSize == 0)
+            cbNewSize = RTLOG_RINGBUF_DEFAULT_SIZE;
+        if (   pLogger->pInt->cbRingBuf != cbNewSize
+            || !pLogger->pInt->pchRingBufCur)
+        {
+            uintptr_t offOld = pLogger->pInt->pchRingBufCur - pLogger->pInt->pszRingBuf;
+            if (offOld < sizeof(RTLOG_RINGBUF_EYE_CATCHER))
+                offOld = sizeof(RTLOG_RINGBUF_EYE_CATCHER);
+            else if (offOld >= cbNewSize)
+            {
+                memmove(pLogger->pInt->pszRingBuf, &pLogger->pInt->pszRingBuf[offOld - cbNewSize], cbNewSize);
+                offOld = sizeof(RTLOG_RINGBUF_EYE_CATCHER);
+            }
+
+            void *pvNew = RTMemRealloc(pLogger->pInt->pchRingBufCur, cbNewSize);
+            if (pvNew)
+            {
+                pLogger->pInt->pszRingBuf    = (char *)pvNew;
+                pLogger->pInt->pchRingBufCur = (char *)pvNew + offOld;
+                pLogger->pInt->cbRingBuf     = cbNewSize;
+                memcpy(pvNew, RTLOG_RINGBUF_EYE_CATCHER, sizeof(RTLOG_RINGBUF_EYE_CATCHER));
+                memcpy((char *)pvNew + cbNewSize - sizeof(RTLOG_RINGBUF_EYE_CATCHER_END),
+                       RTLOG_RINGBUF_EYE_CATCHER_END, sizeof(RTLOG_RINGBUF_EYE_CATCHER_END));
+                rc = VINF_SUCCESS;
+            }
+            else
+                rc = VERR_NO_MEMORY;
+        }
+        rtlogUnlock(pLogger);
+    }
+
+    return rc;
+}
+
+
+/**
+ * Writes text to the ring buffer.
+ *
+ * @param   pInt                The internal logger data structure.
+ * @param   pachText            The text to write.
+ * @param   cchText             The number of chars (bytes) to write.
+ */
+static void rtLogRingBufWrite(PRTLOGGERINTERNAL pInt, const char *pachText, size_t cchText)
+{
+    /*
+     * Get the ring buffer data, adjusting it to only describe the writable
+     * part of the buffer.
+     */
+    char * const pchStart = &pInt->pszRingBuf[sizeof(RTLOG_RINGBUF_EYE_CATCHER)];
+    size_t const cchBuf   = pInt->cbRingBuf - sizeof(RTLOG_RINGBUF_EYE_CATCHER) - sizeof(RTLOG_RINGBUF_EYE_CATCHER_END);
+    char        *pchCur   = pInt->pchRingBufCur;
+    size_t       cchLeft  = pchCur - pchStart;
+    if (RT_LIKELY(cchLeft < cchBuf))
+        cchLeft = cchBuf - cchLeft;
+    else
+    {
+        /* May happen in ring-0 where a thread or two went ahead without getting the lock. */
+        pchCur = pchStart;
+        cchLeft = cchBuf;
+    }
+    Assert(cchBuf < pInt->cbRingBuf);
+
+    if (cchText < cchLeft)
+    {
+        /*
+         * The text fits in the remaining space.
+         */
+        memcpy(pchCur, pachText, cchText);
+        pchCur[cchText] = '\0';
+        pInt->pchRingBufCur = &pchCur[cchText];
+        pInt->cbRingBufUnflushed += cchText;
+    }
+    else
+    {
+        /*
+         * The text wraps around.  Taking the simple but inefficient approach
+         * to input texts that are longer than the ring buffer since that
+         * is unlikely to the be a frequent case.
+         */
+        /* Fill to the end of the buffer. */
+        memcpy(pchCur, pachText, cchLeft);
+        pachText += cchLeft;
+        cchText  -= cchLeft;
+        pInt->cbRingBufUnflushed += cchLeft;
+        pInt->pchRingBufCur       = pchStart;
+
+        /* Ring buffer overflows (the plainly inefficient bit). */
+        while (cchText >= cchBuf)
+        {
+            memcpy(pchStart, pachText, cchBuf);
+            pachText += cchBuf;
+            cchText  -= cchBuf;
+            pInt->cbRingBufUnflushed += cchBuf;
+        }
+
+        /* The final bit, if any. */
+        if (cchText > 0)
+        {
+            memcpy(pchStart, pachText, cchText);
+            pInt->cbRingBufUnflushed += cchText;
+        }
+        pchStart[cchText] = '\0';
+        pInt->pchRingBufCur = &pchStart[cchText];
+    }
+}
+
+
+/**
+ * Flushes the ring buffer to all the other log destinations.
+ *
+ * @param   pLogger     The logger instance which ring buffer should be flushed.
+ */
+static void rtLogRingBufFlush(PRTLOGGER pLogger)
+{
+    const char  *pszPreamble;
+    size_t       cchPreamble;
+    const char  *pszFirst;
+    size_t       cchFirst;
+    const char  *pszSecond;
+    size_t       cchSecond;
+
+    /*
+     * Get the ring buffer data, adjusting it to only describe the writable
+     * part of the buffer.
+     */
+    uint64_t     cchUnflushed = pLogger->pInt->cbRingBufUnflushed;
+    char * const pszBuf   = &pLogger->pInt->pszRingBuf[sizeof(RTLOG_RINGBUF_EYE_CATCHER)];
+    size_t const cchBuf   = pLogger->pInt->cbRingBuf - sizeof(RTLOG_RINGBUF_EYE_CATCHER) - sizeof(RTLOG_RINGBUF_EYE_CATCHER_END);
+    size_t       offCur   = pLogger->pInt->pchRingBufCur - pszBuf;
+    size_t       cchAfter;
+    if (RT_LIKELY(offCur < cchBuf))
+        cchAfter = cchBuf - offCur;
+    else /* May happen in ring-0 where a thread or two went ahead without getting the lock. */
+    {
+        offCur   = 0;
+        cchAfter = cchBuf;
+    }
+
+    pLogger->pInt->cbRingBufUnflushed = 0;
+
+    /*
+     * Figure out whether there are one or two segments that needs writing,
+     * making the last segment is terminated.  (The first is always
+     * terminated because of the eye-catcher at the end of the buffer.)
+     */
+    if (cchUnflushed == 0)
+        return;
+    pszBuf[offCur] = '\0';
+    if (cchUnflushed >= cchBuf)
+    {
+        pszFirst    = &pszBuf[offCur + 1];
+        cchFirst    = cchAfter ? cchAfter - 1 : 0;
+        pszSecond   = pszBuf;
+        cchSecond   = offCur;
+        pszPreamble =        "\n*FLUSH RING BUF*\n";
+        cchPreamble = sizeof("\n*FLUSH RING BUF*\n") - 1;
+    }
+    else if ((size_t)cchUnflushed <= offCur)
+    {
+        cchFirst    = (size_t)cchUnflushed;
+        pszFirst    = &pszBuf[offCur - cchFirst];
+        pszSecond   = "";
+        cchSecond   = 0;
+        pszPreamble = "";
+        cchPreamble = 0;
+    }
+    else
+    {
+        cchFirst    = (size_t)cchUnflushed - offCur;
+        pszFirst    = &pszBuf[cchBuf - cchFirst];
+        pszSecond   = pszBuf;
+        cchSecond   = offCur;
+        pszPreamble = "";
+        cchPreamble = 0;
+    }
+
+    /*
+     * Write the ring buffer to all other destiations.
+     */
+    if (pLogger->fDestFlags & RTLOGDEST_USER)
+    {
+        if (cchPreamble)
+            RTLogWriteUser(pszPreamble, cchPreamble);
+        if (cchFirst)
+            RTLogWriteUser(pszFirst, cchFirst);
+        if (cchSecond)
+            RTLogWriteUser(pszSecond, cchSecond);
+    }
+
+    if (pLogger->fDestFlags & RTLOGDEST_DEBUGGER)
+    {
+        if (cchPreamble)
+            RTLogWriteDebugger(pszPreamble, cchPreamble);
+        if (cchFirst)
+            RTLogWriteDebugger(pszFirst, cchFirst);
+        if (cchSecond)
+            RTLogWriteDebugger(pszSecond, cchSecond);
+    }
+
+# ifdef IN_RING3
+    if (pLogger->fDestFlags & RTLOGDEST_FILE)
+    {
+        if (pLogger->pInt->hFile != NIL_RTFILE)
+        {
+            if (cchPreamble)
+                RTFileWrite(pLogger->pInt->hFile, pszPreamble, cchPreamble, NULL);
+            if (cchFirst)
+                RTFileWrite(pLogger->pInt->hFile, pszFirst, cchFirst, NULL);
+            if (cchSecond)
+                RTFileWrite(pLogger->pInt->hFile, pszSecond, cchSecond, NULL);
+            if (pLogger->fFlags & RTLOGFLAGS_FLUSH)
+                RTFileFlush(pLogger->pInt->hFile);
+        }
+        if (pLogger->pInt->cHistory)
+            pLogger->pInt->cbHistoryFileWritten += cchFirst + cchSecond;
+    }
+# endif
+
+    if (pLogger->fDestFlags & RTLOGDEST_STDOUT)
+    {
+        if (cchPreamble)
+            RTLogWriteStdOut(pszPreamble, cchPreamble);
+        if (cchFirst)
+            RTLogWriteStdOut(pszFirst, cchFirst);
+        if (cchSecond)
+            RTLogWriteStdOut(pszSecond, cchSecond);
+    }
+
+    if (pLogger->fDestFlags & RTLOGDEST_STDERR)
+    {
+        if (cchPreamble)
+            RTLogWriteStdErr(pszPreamble, cchPreamble);
+        if (cchFirst)
+            RTLogWriteStdErr(pszFirst, cchFirst);
+        if (cchSecond)
+            RTLogWriteStdErr(pszSecond, cchSecond);
+    }
+
+# if defined(IN_RING0) && !defined(LOG_NO_COM)
+    if (pLogger->fDestFlags & RTLOGDEST_COM)
+    {
+        if (cchPreamble)
+            RTLogWriteCom(pszPreamble, cchPreamble);
+        if (cchFirst)
+            RTLogWriteCom(pszFirst, cchFirst);
+        if (cchSecond)
+            RTLogWriteCom(pszSecond, cchSecond);
+    }
+# endif
+}
+
+
+
+
+RTDECL(int) RTLogCreateExV(PRTLOGGER *ppLogger, uint32_t fFlags, const char *pszGroupSettings,
+                           const char *pszEnvVarBase, unsigned cGroups, const char * const *papszGroups,
+                           uint32_t fDestFlags, PFNRTLOGPHASE pfnPhase, uint32_t cHistory,
+                           uint64_t cbHistoryFileMax, uint32_t cSecsHistoryTimeSlot,
+                           char *pszErrorMsg, size_t cchErrorMsg, const char *pszFilenameFmt, va_list args)
+{
+    int         rc;
+    size_t      offInternal;
+    size_t      cbLogger;
+    PRTLOGGER   pLogger;
+
+    /*
+     * Validate input.
+     */
+    if (    (cGroups && !papszGroups)
+        ||  !VALID_PTR(ppLogger) )
+    {
+        AssertMsgFailed(("Invalid parameters!\n"));
+        return VERR_INVALID_PARAMETER;
+    }
+    *ppLogger = NULL;
+
+    if (pszErrorMsg)
+        RTStrPrintf(pszErrorMsg, cchErrorMsg, N_("unknown error"));
+
+    AssertMsgReturn(cHistory < _1M, ("%#x", cHistory), VERR_OUT_OF_RANGE);
+
+    /*
+     * Allocate a logger instance.
+     */
+    offInternal = RT_OFFSETOF(RTLOGGER, afGroups[cGroups]);
+    offInternal = RT_ALIGN_Z(offInternal, sizeof(uint64_t));
+    cbLogger = offInternal + sizeof(RTLOGGERINTERNAL);
+    if (fFlags & RTLOGFLAGS_RESTRICT_GROUPS)
+        cbLogger += cGroups * sizeof(uint32_t);
+    pLogger = (PRTLOGGER)RTMemAllocZVar(cbLogger);
+    if (pLogger)
+    {
+# if defined(RT_ARCH_X86) && (!defined(LOG_USE_C99) || !defined(RT_WITHOUT_EXEC_ALLOC))
+        uint8_t *pu8Code;
+# endif
+        pLogger->u32Magic       = RTLOGGER_MAGIC;
+        pLogger->cGroups        = cGroups;
+        pLogger->fFlags         = fFlags;
+        pLogger->fDestFlags     = fDestFlags;
+        pLogger->pInt           = (PRTLOGGERINTERNAL)((uintptr_t)pLogger + offInternal);
+        pLogger->pInt->uRevision                = RTLOGGERINTERNAL_REV;
+        pLogger->pInt->cbSelf                   = sizeof(RTLOGGERINTERNAL);
+        pLogger->pInt->hSpinMtx                 = NIL_RTSEMSPINMUTEX;
+        pLogger->pInt->pfnFlush                 = NULL;
+        pLogger->pInt->pfnPrefix                = NULL;
+        pLogger->pInt->pvPrefixUserArg          = NULL;
+        pLogger->pInt->afPadding1[0]            = false;
+        pLogger->pInt->afPadding1[1]            = false;
+        pLogger->pInt->fCreated                 = false;
+        pLogger->pInt->cMaxGroups               = cGroups;
+        pLogger->pInt->papszGroups              = papszGroups;
+        if (fFlags & RTLOGFLAGS_RESTRICT_GROUPS)
+            pLogger->pInt->pacEntriesPerGroup   = (uint32_t *)(pLogger->pInt + 1);
+        else
+            pLogger->pInt->pacEntriesPerGroup   = NULL;
+        pLogger->pInt->cMaxEntriesPerGroup      = UINT32_MAX;
+# ifdef IN_RING3
+        pLogger->pInt->pfnPhase                 = pfnPhase;
+        pLogger->pInt->hFile                    = NIL_RTFILE;
+        pLogger->pInt->cHistory                 = cHistory;
+        if (cbHistoryFileMax == 0)
+            pLogger->pInt->cbHistoryFileMax     = UINT64_MAX;
+        else
+            pLogger->pInt->cbHistoryFileMax     = cbHistoryFileMax;
+        if (cSecsHistoryTimeSlot == 0)
+            pLogger->pInt->cSecsHistoryTimeSlot = UINT32_MAX;
+        else
+            pLogger->pInt->cSecsHistoryTimeSlot = cSecsHistoryTimeSlot;
+# endif  /* IN_RING3 */
+        if (pszGroupSettings)
+            RTLogGroupSettings(pLogger, pszGroupSettings);
+
+# if defined(RT_ARCH_X86) && (!defined(LOG_USE_C99) || !defined(RT_WITHOUT_EXEC_ALLOC))
+        /*
+         * Emit wrapper code.
+         */
+        pu8Code = (uint8_t *)RTMemExecAlloc(64);
+        if (pu8Code)
+        {
+            pLogger->pfnLogger = *(PFNRTLOGGER*)&pu8Code;
+            *pu8Code++ = 0x68;          /* push imm32 */
+            *(void **)pu8Code = pLogger;
+            pu8Code += sizeof(void *);
+            *pu8Code++ = 0xe8;          /* call rel32 */
+            *(uint32_t *)pu8Code = (uintptr_t)RTLogLogger - ((uintptr_t)pu8Code + sizeof(uint32_t));
+            pu8Code += sizeof(uint32_t);
+            *pu8Code++ = 0x8d;          /* lea esp, [esp + 4] */
+            *pu8Code++ = 0x64;
+            *pu8Code++ = 0x24;
+            *pu8Code++ = 0x04;
+            *pu8Code++ = 0xc3;          /* ret near */
+            AssertMsg((uintptr_t)pu8Code - (uintptr_t)pLogger->pfnLogger <= 64,
+                      ("Wrapper assembly is too big! %d bytes\n", (uintptr_t)pu8Code - (uintptr_t)pLogger->pfnLogger));
+            rc = VINF_SUCCESS;
+        }
+        else
+        {
+#  ifdef RT_OS_LINUX
+            if (pszErrorMsg) /* Most probably SELinux causing trouble since the larger RTMemAlloc succeeded. */
+                RTStrPrintf(pszErrorMsg, cchErrorMsg, N_("mmap(PROT_WRITE | PROT_EXEC) failed -- SELinux?"));
+#  endif
+            rc = VERR_NO_MEMORY;
+        }
+        if (RT_SUCCESS(rc))
+# endif /* X86 wrapper code*/
+        {
+# ifdef IN_RING3 /* files and env.vars. are only accessible when in R3 at the present time. */
+            /*
+             * Format the filename.
+             */
+            if (pszFilenameFmt)
+            {
+                /** @todo validate the length, fail on overflow. */
+                RTStrPrintfV(pLogger->pInt->szFilename, sizeof(pLogger->pInt->szFilename), pszFilenameFmt, args);
+                pLogger->fDestFlags |= RTLOGDEST_FILE;
+            }
+
+            /*
+             * Parse the environment variables.
+             */
+            if (pszEnvVarBase)
+            {
+                /* make temp copy of environment variable base. */
+                size_t  cchEnvVarBase = strlen(pszEnvVarBase);
+                char   *pszEnvVar = (char *)alloca(cchEnvVarBase + 16);
+                memcpy(pszEnvVar, pszEnvVarBase, cchEnvVarBase);
+
+                /*
+                 * Destination.
+                 */
+                strcpy(pszEnvVar + cchEnvVarBase, "_DEST");
+                const char *pszValue = RTEnvGet(pszEnvVar);
+                if (pszValue)
+                    RTLogDestinations(pLogger, pszValue);
+
+                /*
+                 * The flags.
+                 */
+                strcpy(pszEnvVar + cchEnvVarBase, "_FLAGS");
+                pszValue = RTEnvGet(pszEnvVar);
+                if (pszValue)
+                    RTLogFlags(pLogger, pszValue);
+
+                /*
+                 * The group settings.
+                 */
+                pszEnvVar[cchEnvVarBase] = '\0';
+                pszValue = RTEnvGet(pszEnvVar);
+                if (pszValue)
+                    RTLogGroupSettings(pLogger, pszValue);
+            }
+# endif /* IN_RING3 */
+
+            /*
+             * Open the destination(s).
+             */
+            rc = VINF_SUCCESS;
+# ifdef IN_RING3
+            if (pLogger->fDestFlags & RTLOGDEST_FILE)
+            {
+                if (pLogger->fFlags & RTLOGFLAGS_APPEND)
+                {
+                    rc = rtlogFileOpen(pLogger, pszErrorMsg, cchErrorMsg);
+
+                    /* Rotate in case of appending to a too big log file,
+                       otherwise this simply doesn't do anything. */
+                    rtlogRotate(pLogger, 0, true /* fFirst */);
+                }
+                else
+                {
+                    /* Force rotation if it is configured. */
+                    pLogger->pInt->cbHistoryFileWritten = UINT64_MAX;
+                    rtlogRotate(pLogger, 0, true /* fFirst */);
+
+                    /* If the file is not open then rotation is not set up. */
+                    if (pLogger->pInt->hFile == NIL_RTFILE)
+                    {
+                        pLogger->pInt->cbHistoryFileWritten = 0;
+                        rc = rtlogFileOpen(pLogger, pszErrorMsg, cchErrorMsg);
+                    }
+                }
+            }
+# endif  /* IN_RING3 */
+
+            if ((pLogger->fDestFlags & RTLOGDEST_RINGBUF) && RT_SUCCESS(rc))
+                rc = rtLogRingBufAdjust(pLogger, pLogger->pInt->cbRingBuf, true /*fForce*/);
+
+            /*
+             * Create mutex and check how much it counts when entering the lock
+             * so that we can report the values for RTLOGFLAGS_PREFIX_LOCK_COUNTS.
+             */
+            if (RT_SUCCESS(rc))
+            {
+                rc = RTSemSpinMutexCreate(&pLogger->pInt->hSpinMtx, RTSEMSPINMUTEX_FLAGS_IRQ_SAFE);
+                if (RT_SUCCESS(rc))
+                {
+# ifdef IN_RING3 /** @todo do counters in ring-0 too? */
+                    RTTHREAD Thread = RTThreadSelf();
+                    if (Thread != NIL_RTTHREAD)
+                    {
+                        int32_t c = RTLockValidatorWriteLockGetCount(Thread);
+                        RTSemSpinMutexRequest(pLogger->pInt->hSpinMtx);
+                        c = RTLockValidatorWriteLockGetCount(Thread) - c;
+                        RTSemSpinMutexRelease(pLogger->pInt->hSpinMtx);
+                        ASMAtomicWriteU32(&g_cLoggerLockCount, c);
+                    }
+
+                    /* Use the callback to generate some initial log contents. */
+                    Assert(VALID_PTR(pLogger->pInt->pfnPhase) || pLogger->pInt->pfnPhase == NULL);
+                    if (pLogger->pInt->pfnPhase)
+                        pLogger->pInt->pfnPhase(pLogger, RTLOGPHASE_BEGIN, rtlogPhaseMsgNormal);
+# endif
+                    pLogger->pInt->fCreated = true;
+                    *ppLogger = pLogger;
+                    return VINF_SUCCESS;
+                }
+
+                if (pszErrorMsg)
+                    RTStrPrintf(pszErrorMsg, cchErrorMsg, N_("failed to create semaphore"));
+            }
+# ifdef IN_RING3
+            RTFileClose(pLogger->pInt->hFile);
+# endif
+# if defined(LOG_USE_C99) && defined(RT_WITHOUT_EXEC_ALLOC)
+            RTMemFree(*(void **)&pLogger->pfnLogger);
+# else
+            RTMemExecFree(*(void **)&pLogger->pfnLogger, 64);
+# endif
+        }
+        RTMemFree(pLogger);
+    }
+    else
+        rc = VERR_NO_MEMORY;
+
+    return rc;
+}
+RT_EXPORT_SYMBOL(RTLogCreateExV);
+
+
+RTDECL(int) RTLogCreate(PRTLOGGER *ppLogger, uint32_t fFlags, const char *pszGroupSettings,
+                        const char *pszEnvVarBase, unsigned cGroups, const char * const * papszGroups,
+                        uint32_t fDestFlags, const char *pszFilenameFmt, ...)
+{
+    va_list args;
+    int rc;
+
+    va_start(args, pszFilenameFmt);
+    rc = RTLogCreateExV(ppLogger, fFlags, pszGroupSettings, pszEnvVarBase, cGroups, papszGroups,
+                        fDestFlags, NULL /*pfnPhase*/, 0 /*cHistory*/, 0 /*cbHistoryFileMax*/, 0 /*cSecsHistoryTimeSlot*/,
+                        NULL /*pszErrorMsg*/, 0 /*cchErrorMsg*/, pszFilenameFmt, args);
+    va_end(args);
+    return rc;
+}
+RT_EXPORT_SYMBOL(RTLogCreate);
+
+
+RTDECL(int) RTLogCreateEx(PRTLOGGER *ppLogger, uint32_t fFlags, const char *pszGroupSettings,
+                          const char *pszEnvVarBase, unsigned cGroups, const char * const * papszGroups,
+                          uint32_t fDestFlags, PFNRTLOGPHASE pfnPhase, uint32_t cHistory,
+                          uint64_t cbHistoryFileMax, uint32_t cSecsHistoryTimeSlot,
+                          char *pszErrorMsg, size_t cchErrorMsg, const char *pszFilenameFmt, ...)
+{
+    va_list args;
+    int rc;
+
+    va_start(args, pszFilenameFmt);
+    rc = RTLogCreateExV(ppLogger, fFlags, pszGroupSettings, pszEnvVarBase, cGroups, papszGroups,
+                        fDestFlags, pfnPhase, cHistory, cbHistoryFileMax, cSecsHistoryTimeSlot,
+                        pszErrorMsg, cchErrorMsg, pszFilenameFmt, args);
+    va_end(args);
+    return rc;
+}
+RT_EXPORT_SYMBOL(RTLogCreateEx);
+
+
+/**
+ * Destroys a logger instance.
+ *
+ * The instance is flushed and all output destinations closed (where applicable).
+ *
+ * @returns iprt status code.
+ * @param   pLogger             The logger instance which close destroyed. NULL is fine.
+ */
+RTDECL(int) RTLogDestroy(PRTLOGGER pLogger)
+{
+    int             rc;
+    uint32_t        iGroup;
+    RTSEMSPINMUTEX  hSpinMtx;
+
+    /*
+     * Validate input.
+     */
+    if (!pLogger)
+        return VINF_SUCCESS;
+    AssertPtrReturn(pLogger, VERR_INVALID_POINTER);
+    AssertReturn(pLogger->u32Magic == RTLOGGER_MAGIC, VERR_INVALID_MAGIC);
+    AssertPtrReturn(pLogger->pInt, VERR_INVALID_POINTER);
+
+    /*
+     * Acquire logger instance sem and disable all logging. (paranoia)
+     */
+    rc = rtlogLock(pLogger);
+    AssertMsgRCReturn(rc, ("%Rrc\n", rc), rc);
+
+    pLogger->fFlags |= RTLOGFLAGS_DISABLED;
+    iGroup = pLogger->cGroups;
+    while (iGroup-- > 0)
+        pLogger->afGroups[iGroup] = 0;
+
+    /*
+     * Flush it.
+     */
+    rtlogFlush(pLogger);
+
+# ifdef IN_RING3
+    /*
+     * Add end of logging message.
+     */
+    if (   (pLogger->fDestFlags & RTLOGDEST_FILE)
+        && pLogger->pInt->hFile != NIL_RTFILE)
+        pLogger->pInt->pfnPhase(pLogger, RTLOGPHASE_END, rtlogPhaseMsgLocked);
+
+    /*
+     * Close output stuffs.
+     */
+    if (pLogger->pInt->hFile != NIL_RTFILE)
+    {
+        int rc2 = RTFileClose(pLogger->pInt->hFile);
+        AssertRC(rc2);
+        if (RT_FAILURE(rc2) && RT_SUCCESS(rc))
+            rc = rc2;
+        pLogger->pInt->hFile = NIL_RTFILE;
+    }
+# endif
+
+    /*
+     * Free the mutex, the wrapper and the instance memory.
+     */
+    hSpinMtx = pLogger->pInt->hSpinMtx;
+    pLogger->pInt->hSpinMtx = NIL_RTSEMSPINMUTEX;
+    if (hSpinMtx != NIL_RTSEMSPINMUTEX)
+    {
+        int rc2;
+        RTSemSpinMutexRelease(hSpinMtx);
+        rc2 = RTSemSpinMutexDestroy(hSpinMtx);
+        AssertRC(rc2);
+        if (RT_FAILURE(rc2) && RT_SUCCESS(rc))
+            rc = rc2;
+    }
+
+    if (pLogger->pfnLogger)
+    {
+# if defined(LOG_USE_C99) && defined(RT_WITHOUT_EXEC_ALLOC)
+        RTMemFree(*(void **)&pLogger->pfnLogger);
+# else
+        RTMemExecFree(*(void **)&pLogger->pfnLogger, 64);
+# endif
+        pLogger->pfnLogger = NULL;
+    }
+    RTMemFree(pLogger);
+
+    return rc;
+}
+RT_EXPORT_SYMBOL(RTLogDestroy);
+
+
+/**
+ * Create a logger instance clone for RC usage.
+ *
+ * @returns iprt status code.
+ *
+ * @param   pLogger             The logger instance to be cloned.
+ * @param   pLoggerRC           Where to create the RC logger instance.
+ * @param   cbLoggerRC          Amount of memory allocated to for the RC logger
+ *                              instance clone.
+ * @param   pfnLoggerRCPtr      Pointer to logger wrapper function for this
+ *                              instance (RC Ptr).
+ * @param   pfnFlushRCPtr       Pointer to flush function (RC Ptr).
+ * @param   fFlags              Logger instance flags, a combination of the RTLOGFLAGS_* values.
+ */
+RTDECL(int) RTLogCloneRC(PRTLOGGER pLogger, PRTLOGGERRC pLoggerRC, size_t cbLoggerRC,
+                         RTRCPTR pfnLoggerRCPtr, RTRCPTR pfnFlushRCPtr, uint32_t fFlags)
+{
+    /*
+     * Validate input.
+     */
+   if (    !pLoggerRC
+       ||  !pfnFlushRCPtr
+       ||  !pfnLoggerRCPtr)
+    {
+       AssertMsgFailed(("Invalid parameters!\n"));
+       return VERR_INVALID_PARAMETER;
+    }
+    if (cbLoggerRC < sizeof(*pLoggerRC))
+    {
+        AssertMsgFailed(("%d min=%d\n", cbLoggerRC, sizeof(*pLoggerRC)));
+        return VERR_INVALID_PARAMETER;
+    }
+
+    /*
+     * Initialize GC instance.
+     */
+    pLoggerRC->offScratch   = 0;
+    pLoggerRC->fPendingPrefix = false;
+    pLoggerRC->pfnLogger    = pfnLoggerRCPtr;
+    pLoggerRC->pfnFlush     = pfnFlushRCPtr;
+    pLoggerRC->u32Magic     = RTLOGGERRC_MAGIC;
+    pLoggerRC->fFlags       = fFlags | RTLOGFLAGS_DISABLED;
+    pLoggerRC->cGroups      = 1;
+    pLoggerRC->afGroups[0]  = 0;
+
+    /*
+     * Resolve defaults.
+     */
+    if (!pLogger)
+    {
+        pLogger = RTLogDefaultInstance();
+        if (!pLogger)
+            return VINF_SUCCESS;
+    }
+
+    /*
+     * Check if there's enough space for the groups.
+     */
+    if (cbLoggerRC < (size_t)RT_OFFSETOF(RTLOGGERRC, afGroups[pLogger->cGroups]))
+    {
+        AssertMsgFailed(("%d req=%d cGroups=%d\n", cbLoggerRC, RT_OFFSETOF(RTLOGGERRC, afGroups[pLogger->cGroups]), pLogger->cGroups));
+        return VERR_BUFFER_OVERFLOW;
+    }
+    memcpy(&pLoggerRC->afGroups[0], &pLogger->afGroups[0], pLogger->cGroups * sizeof(pLoggerRC->afGroups[0]));
+    pLoggerRC->cGroups = pLogger->cGroups;
+
+    /*
+     * Copy bits from the HC instance.
+     */
+    pLoggerRC->fPendingPrefix = pLogger->pInt->fPendingPrefix;
+    pLoggerRC->fFlags |= pLogger->fFlags;
+
+    /*
+     * Check if we can remove the disabled flag.
+     */
+    if (    pLogger->fDestFlags
+        &&  !((pLogger->fFlags | fFlags) & RTLOGFLAGS_DISABLED))
+        pLoggerRC->fFlags &= ~RTLOGFLAGS_DISABLED;
+
+    return VINF_SUCCESS;
+}
+RT_EXPORT_SYMBOL(RTLogCloneRC);
+
+
+/**
+ * Flushes a RC logger instance to a R3 logger.
+ *
+ *
+ * @returns iprt status code.
+ * @param   pLogger     The R3 logger instance to flush pLoggerRC to. If NULL
+ *                      the default logger is used.
+ * @param   pLoggerRC   The RC logger instance to flush.
+ */
+RTDECL(void) RTLogFlushRC(PRTLOGGER pLogger, PRTLOGGERRC pLoggerRC)
+{
+    /*
+     * Resolve defaults.
+     */
+    if (!pLogger)
+    {
+        pLogger = RTLogDefaultInstance();
+        if (!pLogger)
+        {
+            pLoggerRC->offScratch = 0;
+            return;
+        }
+    }
+
+    /*
+     * Any thing to flush?
+     */
+    if (    pLogger->offScratch
+        ||  pLoggerRC->offScratch)
+    {
+        /*
+         * Acquire logger instance sem.
+         */
+        int rc = rtlogLock(pLogger);
+        if (RT_FAILURE(rc))
+            return;
+
+        /*
+         * Write whatever the GC instance contains to the HC one, and then
+         * flush the HC instance.
+         */
+        if (pLoggerRC->offScratch)
+        {
+            rtLogOutput(pLogger, pLoggerRC->achScratch, pLoggerRC->offScratch);
+            rtLogOutput(pLogger, NULL, 0);
+            pLoggerRC->offScratch = 0;
+        }
+
+        /*
+         * Release the semaphore.
+         */
+        rtlogUnlock(pLogger);
+    }
+}
+RT_EXPORT_SYMBOL(RTLogFlushRC);
+
+# ifdef IN_RING3
+
+RTDECL(int) RTLogCreateForR0(PRTLOGGER pLogger, size_t cbLogger,
+                             RTR0PTR pLoggerR0Ptr, RTR0PTR pfnLoggerR0Ptr, RTR0PTR pfnFlushR0Ptr,
+                             uint32_t fFlags, uint32_t fDestFlags)
+{
+    /*
+     * Validate input.
+     */
+    AssertPtrReturn(pLogger, VERR_INVALID_PARAMETER);
+    size_t const cbRequired = sizeof(*pLogger) + RTLOGGERINTERNAL_R0_SIZE;
+    AssertReturn(cbLogger >= cbRequired, VERR_BUFFER_OVERFLOW);
+    AssertReturn(pLoggerR0Ptr != NIL_RTR0PTR, VERR_INVALID_PARAMETER);
+    AssertReturn(pfnLoggerR0Ptr != NIL_RTR0PTR, VERR_INVALID_PARAMETER);
+
+    /*
+     * Initialize the ring-0 instance.
+     */
+    pLogger->achScratch[0]  = 0;
+    pLogger->offScratch     = 0;
+    pLogger->pfnLogger      = (PFNRTLOGGER)pfnLoggerR0Ptr;
+    pLogger->fFlags         = fFlags;
+    pLogger->fDestFlags     = fDestFlags & ~RTLOGDEST_FILE;
+    pLogger->pInt           = NULL;
+    pLogger->cGroups        = 1;
+    pLogger->afGroups[0]    = 0;
+
+    uint32_t cMaxGroups     = (uint32_t)((cbLogger - cbRequired) / sizeof(pLogger->afGroups[0]));
+    if (fFlags & RTLOGFLAGS_RESTRICT_GROUPS)
+        cMaxGroups /= 2;
+    PRTLOGGERINTERNAL pInt;
+    for (;;)
+    {
+        AssertReturn(cMaxGroups > 0, VERR_BUFFER_OVERFLOW);
+        pInt = (PRTLOGGERINTERNAL)&pLogger->afGroups[cMaxGroups];
+        if (!((uintptr_t)pInt & (sizeof(uint64_t) - 1)))
+            break;
+        cMaxGroups--;
+    }
+    pLogger->pInt               = (PRTLOGGERINTERNAL)(pLoggerR0Ptr + (uintptr_t)pInt - (uintptr_t)pLogger);
+    pInt->uRevision             = RTLOGGERINTERNAL_REV;
+    pInt->cbSelf                = RTLOGGERINTERNAL_R0_SIZE;
+    pInt->hSpinMtx              = NIL_RTSEMSPINMUTEX; /* Not serialized. */
+    pInt->pfnFlush              = (PFNRTLOGFLUSH)pfnFlushR0Ptr;
+    pInt->pfnPrefix             = NULL;
+    pInt->pvPrefixUserArg       = NULL;
+    pInt->fPendingPrefix        = false;
+    pInt->cMaxGroups            = cMaxGroups;
+    pInt->papszGroups           = NULL;
+    pInt->cMaxEntriesPerGroup   = UINT32_MAX;
+    if (fFlags & RTLOGFLAGS_RESTRICT_GROUPS)
+    {
+        memset(pInt + 1, 0, sizeof(uint32_t) * cMaxGroups);
+        pInt->pacEntriesPerGroup= (uint32_t *)(pLogger->pInt + 1);
+    }
+    else
+        pInt->pacEntriesPerGroup= NULL;
+
+    pInt->fCreated              = true;
+    pLogger->u32Magic           = RTLOGGER_MAGIC;
+    return VINF_SUCCESS;
+}
+RT_EXPORT_SYMBOL(RTLogCreateForR0);
+
+
+RTDECL(size_t) RTLogCalcSizeForR0(uint32_t cGroups, uint32_t fFlags)
+{
+    size_t cb = RT_OFFSETOF(RTLOGGER, afGroups[cGroups]);
+    cb = RT_ALIGN_Z(cb, sizeof(uint64_t));
+    cb += sizeof(RTLOGGERINTERNAL);
+    if (fFlags & RTLOGFLAGS_RESTRICT_GROUPS)
+        cb += sizeof(uint32_t) * cGroups;
+    return cb;
+}
+RT_EXPORT_SYMBOL(RTLogCalcSizeForR0);
+
+
+RTDECL(int) RTLogCopyGroupsAndFlagsForR0(PRTLOGGER pDstLogger, RTR0PTR pDstLoggerR0Ptr,
+                                         PCRTLOGGER pSrcLogger, uint32_t fFlagsOr, uint32_t fFlagsAnd)
+{
+    /*
+     * Validate input.
+     */
+    AssertPtrReturn(pDstLogger, VERR_INVALID_PARAMETER);
+    AssertPtrNullReturn(pSrcLogger, VERR_INVALID_PARAMETER);
+
+    /*
+     * Resolve defaults.
+     */
+    if (!pSrcLogger)
+    {
+        pSrcLogger = RTLogDefaultInstance();
+        if (!pSrcLogger)
+        {
+            pDstLogger->fFlags |= RTLOGFLAGS_DISABLED | fFlagsOr;
+            pDstLogger->cGroups = 1;
+            pDstLogger->afGroups[0] = 0;
+            return VINF_SUCCESS;
+        }
+    }
+
+    /*
+     * Copy flags and group settings.
+     */
+    pDstLogger->fFlags = (pSrcLogger->fFlags & fFlagsAnd & ~RTLOGFLAGS_RESTRICT_GROUPS) | fFlagsOr;
+
+    PRTLOGGERINTERNAL   pDstInt = (PRTLOGGERINTERNAL)((uintptr_t)pDstLogger->pInt - pDstLoggerR0Ptr + (uintptr_t)pDstLogger);
+    int                 rc      = VINF_SUCCESS;
+    uint32_t            cGroups = pSrcLogger->cGroups;
+    if (cGroups > pDstInt->cMaxGroups)
+    {
+        AssertMsgFailed(("cMaxGroups=%zd cGroups=%zd (min size %d)\n", pDstInt->cMaxGroups,
+                         pSrcLogger->cGroups, RT_OFFSETOF(RTLOGGER, afGroups[pSrcLogger->cGroups]) + RTLOGGERINTERNAL_R0_SIZE));
+        rc = VERR_INVALID_PARAMETER;
+        cGroups = pDstInt->cMaxGroups;
+    }
+    memcpy(&pDstLogger->afGroups[0], &pSrcLogger->afGroups[0], cGroups * sizeof(pDstLogger->afGroups[0]));
+    pDstLogger->cGroups = cGroups;
+
+    return rc;
+}
+RT_EXPORT_SYMBOL(RTLogCopyGroupsAndFlagsForR0);
+
+
+RTDECL(int) RTLogSetCustomPrefixCallbackForR0(PRTLOGGER pLogger, RTR0PTR pLoggerR0Ptr,
+                                              RTR0PTR pfnCallbackR0Ptr, RTR0PTR pvUserR0Ptr)
+{
+    AssertPtrReturn(pLogger, VERR_INVALID_POINTER);
+    AssertReturn(pLogger->u32Magic == RTLOGGER_MAGIC, VERR_INVALID_MAGIC);
+
+    /*
+     * Do the work.
+     */
+    PRTLOGGERINTERNAL pInt = (PRTLOGGERINTERNAL)((uintptr_t)pLogger->pInt - pLoggerR0Ptr + (uintptr_t)pLogger);
+    AssertReturn(pInt->uRevision == RTLOGGERINTERNAL_REV, VERR_LOG_REVISION_MISMATCH);
+    pInt->pvPrefixUserArg = (void *)pvUserR0Ptr;
+    pInt->pfnPrefix       = (PFNRTLOGPREFIX)pfnCallbackR0Ptr;
+
+    return VINF_SUCCESS;
+}
+RT_EXPORT_SYMBOL(RTLogSetCustomPrefixCallbackForR0);
+
+RTDECL(void) RTLogFlushR0(PRTLOGGER pLogger, PRTLOGGER pLoggerR0)
+{
+    /*
+     * Resolve defaults.
+     */
+    if (!pLogger)
+    {
+        pLogger = RTLogDefaultInstance();
+        if (!pLogger)
+        {
+            /* flushing to "/dev/null". */
+            if (pLoggerR0->offScratch)
+                    pLoggerR0->offScratch = 0;
+            return;
+        }
+    }
+
+    /*
+     * Anything to flush?
+     */
+    if (    pLoggerR0->offScratch
+        ||  pLogger->offScratch)
+    {
+        /*
+         * Acquire logger semaphores.
+         */
+        int rc = rtlogLock(pLogger);
+        if (RT_FAILURE(rc))
+            return;
+        if (RT_SUCCESS(rc))
+        {
+            /*
+             * Write whatever the GC instance contains to the HC one, and then
+             * flush the HC instance.
+             */
+            if (pLoggerR0->offScratch)
+            {
+                rtLogOutput(pLogger, pLoggerR0->achScratch, pLoggerR0->offScratch);
+                rtLogOutput(pLogger, NULL, 0);
+                pLoggerR0->offScratch = 0;
+            }
+        }
+        rtlogUnlock(pLogger);
+    }
+}
+RT_EXPORT_SYMBOL(RTLogFlushR0);
+
+# endif /* IN_RING3 */
+
+
+/**
+ * Flushes the buffer in one logger instance onto another logger.
+ *
+ * @returns iprt status code.
+ *
+ * @param   pSrcLogger   The logger instance to flush.
+ * @param   pDstLogger   The logger instance to flush onto.
+ *                       If NULL the default logger will be used.
+ */
+RTDECL(void) RTLogFlushToLogger(PRTLOGGER pSrcLogger, PRTLOGGER pDstLogger)
+{
+    /*
+     * Resolve defaults.
+     */
+    if (!pDstLogger)
+    {
+        pDstLogger = RTLogDefaultInstance();
+        if (!pDstLogger)
+        {
+            /* flushing to "/dev/null". */
+            if (pSrcLogger->offScratch)
+            {
+                int rc = rtlogLock(pSrcLogger);
+                if (RT_SUCCESS(rc))
+                {
+                    pSrcLogger->offScratch = 0;
+                    rtlogUnlock(pSrcLogger);
+                }
+            }
+            return;
+        }
+    }
+
+    /*
+     * Any thing to flush?
+     */
+    if (    pSrcLogger->offScratch
+        ||  pDstLogger->offScratch)
+    {
+        /*
+         * Acquire logger semaphores.
+         */
+        int rc = rtlogLock(pDstLogger);
+        if (RT_FAILURE(rc))
+            return;
+        rc = rtlogLock(pSrcLogger);
+        if (RT_SUCCESS(rc))
+        {
+            /*
+             * Write whatever the GC instance contains to the HC one, and then
+             * flush the HC instance.
+             */
+            if (pSrcLogger->offScratch)
+            {
+                rtLogOutput(pDstLogger, pSrcLogger->achScratch, pSrcLogger->offScratch);
+                rtLogOutput(pDstLogger, NULL, 0);
+                pSrcLogger->offScratch = 0;
+            }
+
+            /*
+             * Release the semaphores.
+             */
+            rtlogUnlock(pSrcLogger);
+        }
+        rtlogUnlock(pDstLogger);
+    }
+}
+RT_EXPORT_SYMBOL(RTLogFlushToLogger);
+
+
+/**
+ * Sets the custom prefix callback.
+ *
+ * @returns IPRT status code.
+ * @param   pLogger     The logger instance.
+ * @param   pfnCallback The callback.
+ * @param   pvUser      The user argument for the callback.
+ *  */
+RTDECL(int) RTLogSetCustomPrefixCallback(PRTLOGGER pLogger, PFNRTLOGPREFIX pfnCallback, void *pvUser)
+{
+    /*
+     * Resolve defaults.
+     */
+    if (!pLogger)
+    {
+        pLogger = RTLogDefaultInstance();
+        if (!pLogger)
+            return VINF_SUCCESS;
+    }
+    AssertReturn(pLogger->u32Magic == RTLOGGER_MAGIC, VERR_INVALID_MAGIC);
+
+    /*
+     * Do the work.
+     */
+    rtlogLock(pLogger);
+    pLogger->pInt->pvPrefixUserArg = pvUser;
+    pLogger->pInt->pfnPrefix       = pfnCallback;
+    rtlogUnlock(pLogger);
+
+    return VINF_SUCCESS;
+}
+RT_EXPORT_SYMBOL(RTLogSetCustomPrefixCallback);
+
+
+/**
+ * Matches a group name with a pattern mask in an case insensitive manner (ASCII).
+ *
+ * @returns true if matching and *ppachMask set to the end of the pattern.
+ * @returns false if no match.
+ * @param   pszGrp      The group name.
+ * @param   ppachMask   Pointer to the pointer to the mask. Only wildcard supported is '*'.
+ * @param   cchMask     The length of the mask, including modifiers. The modifiers is why
+ *                      we update *ppachMask on match.
+ */
+static bool rtlogIsGroupMatching(const char *pszGrp, const char **ppachMask, size_t cchMask)
+{
+    const char *pachMask;
+
+    if (!pszGrp || !*pszGrp)
+        return false;
+    pachMask = *ppachMask;
+    for (;;)
+    {
+        if (RT_C_TO_LOWER(*pszGrp) != RT_C_TO_LOWER(*pachMask))
+        {
+            const char *pszTmp;
+
+            /*
+             * Check for wildcard and do a minimal match if found.
+             */
+            if (*pachMask != '*')
+                return false;
+
+            /* eat '*'s. */
+            do  pachMask++;
+            while (--cchMask && *pachMask == '*');
+
+            /* is there more to match? */
+            if (    !cchMask
+                ||  *pachMask == '.'
+                ||  *pachMask == '=')
+                break; /* we're good */
+
+            /* do extremely minimal matching (fixme) */
+            pszTmp = strchr(pszGrp, RT_C_TO_LOWER(*pachMask));
+            if (!pszTmp)
+                pszTmp = strchr(pszGrp, RT_C_TO_UPPER(*pachMask));
+            if (!pszTmp)
+                return false;
+            pszGrp = pszTmp;
+            continue;
+        }
+
+        /* done? */
+        if (!*++pszGrp)
+        {
+            /* trailing wildcard is ok. */
+            do
+            {
+                pachMask++;
+                cchMask--;
+            } while (cchMask && *pachMask == '*');
+            if (    !cchMask
+                ||  *pachMask == '.'
+                ||  *pachMask == '=')
+                break; /* we're good */
+            return false;
+        }
+
+        if (!--cchMask)
+            return false;
+        pachMask++;
+    }
+
+    /* match */
+    *ppachMask = pachMask;
+    return true;
+}
+
+
+/**
+ * Updates the group settings for the logger instance using the specified
+ * specification string.
+ *
+ * @returns iprt status code.
+ *          Failures can safely be ignored.
+ * @param   pLogger     Logger instance.
+ * @param   pszValue    Value to parse.
+ */
+RTDECL(int) RTLogGroupSettings(PRTLOGGER pLogger, const char *pszValue)
+{
+    /*
+     * Resolve defaults.
+     */
+    if (!pLogger)
+    {
+        pLogger = RTLogDefaultInstance();
+        if (!pLogger)
+            return VINF_SUCCESS;
+    }
+
+    /*
+     * Iterate the string.
+     */
+    while (*pszValue)
+    {
+        /*
+         * Skip prefixes (blanks, ;, + and -).
+         */
+        bool    fEnabled = true;
+        char    ch;
+        const char *pszStart;
+        unsigned i;
+        size_t cch;
+
+        while ((ch = *pszValue) == '+' || ch == '-' || ch == ' ' || ch == '\t' || ch == '\n' || ch == ';')
+        {
+            if (ch == '+' || ch == '-' || ch == ';')
+                fEnabled = ch != '-';
+            pszValue++;
+        }
+        if (!*pszValue)
+            break;
+
+        /*
+         * Find end.
+         */
+        pszStart = pszValue;
+        while ((ch = *pszValue) != '\0' && ch != '+' && ch != '-' && ch != ' ' && ch != '\t')
+            pszValue++;
+
+        /*
+         * Find the group (ascii case insensitive search).
+         * Special group 'all'.
+         */
+        cch = pszValue - pszStart;
+        if (    cch >= 3
+            &&  (pszStart[0] == 'a' || pszStart[0] == 'A')
+            &&  (pszStart[1] == 'l' || pszStart[1] == 'L')
+            &&  (pszStart[2] == 'l' || pszStart[2] == 'L')
+            &&  (cch == 3 || pszStart[3] == '.' || pszStart[3] == '='))
+        {
+            /*
+             * All.
+             */
+            unsigned fFlags = cch == 3
+                            ? RTLOGGRPFLAGS_ENABLED | RTLOGGRPFLAGS_LEVEL_1
+                            : rtlogGroupFlags(&pszStart[3]);
+            for (i = 0; i < pLogger->cGroups; i++)
+            {
+                if (fEnabled)
+                    pLogger->afGroups[i] |= fFlags;
+                else
+                    pLogger->afGroups[i] &= ~fFlags;
+            }
+        }
+        else
+        {
+            /*
+             * Specific group(s).
+             */
+            for (i = 0; i < pLogger->cGroups; i++)
+            {
+                const char *psz2 = (const char*)pszStart;
+                if (rtlogIsGroupMatching(pLogger->pInt->papszGroups[i], &psz2, cch))
+                {
+                    unsigned fFlags = RTLOGGRPFLAGS_ENABLED | RTLOGGRPFLAGS_LEVEL_1;
+                    if (*psz2 == '.' || *psz2 == '=')
+                        fFlags = rtlogGroupFlags(psz2);
+                    if (fEnabled)
+                        pLogger->afGroups[i] |= fFlags;
+                    else
+                        pLogger->afGroups[i] &= ~fFlags;
+                }
+            } /* for each group */
+        }
+
+    } /* parse specification */
+
+    return VINF_SUCCESS;
+}
+RT_EXPORT_SYMBOL(RTLogGroupSettings);
+
+
+/**
+ * Interprets the group flags suffix.
+ *
+ * @returns Flags specified. (0 is possible!)
+ * @param   psz     Start of Suffix. (Either dot or equal sign.)
+ */
+static unsigned rtlogGroupFlags(const char *psz)
+{
+    unsigned fFlags = 0;
+
+    /*
+     * Literal flags.
+     */
+    while (*psz == '.')
+    {
+        static struct
+        {
+            const char *pszFlag;        /* lowercase!! */
+            unsigned    fFlag;
+        } aFlags[] =
+        {
+            { "eo",         RTLOGGRPFLAGS_ENABLED },
+            { "enabledonly",RTLOGGRPFLAGS_ENABLED },
+            { "e",          RTLOGGRPFLAGS_ENABLED | RTLOGGRPFLAGS_LEVEL_1 | RTLOGGRPFLAGS_WARN },
+            { "enabled",    RTLOGGRPFLAGS_ENABLED | RTLOGGRPFLAGS_LEVEL_1 | RTLOGGRPFLAGS_WARN },
+            { "l1",         RTLOGGRPFLAGS_LEVEL_1 },
+            { "level1",     RTLOGGRPFLAGS_LEVEL_1 },
+            { "l",          RTLOGGRPFLAGS_LEVEL_2 },
+            { "l2",         RTLOGGRPFLAGS_LEVEL_2 },
+            { "level2",     RTLOGGRPFLAGS_LEVEL_2 },
+            { "l3",         RTLOGGRPFLAGS_LEVEL_3 },
+            { "level3",     RTLOGGRPFLAGS_LEVEL_3 },
+            { "l4",         RTLOGGRPFLAGS_LEVEL_4 },
+            { "level4",     RTLOGGRPFLAGS_LEVEL_4 },
+            { "l5",         RTLOGGRPFLAGS_LEVEL_5 },
+            { "level5",     RTLOGGRPFLAGS_LEVEL_5 },
+            { "l6",         RTLOGGRPFLAGS_LEVEL_6 },
+            { "level6",     RTLOGGRPFLAGS_LEVEL_6 },
+            { "l7",         RTLOGGRPFLAGS_LEVEL_7 },
+            { "level7",     RTLOGGRPFLAGS_LEVEL_7 },
+            { "l8",         RTLOGGRPFLAGS_LEVEL_8 },
+            { "level8",     RTLOGGRPFLAGS_LEVEL_8 },
+            { "l9",         RTLOGGRPFLAGS_LEVEL_9 },
+            { "level9",     RTLOGGRPFLAGS_LEVEL_9 },
+            { "l10",        RTLOGGRPFLAGS_LEVEL_10 },
+            { "level10",    RTLOGGRPFLAGS_LEVEL_10 },
+            { "l11",        RTLOGGRPFLAGS_LEVEL_11 },
+            { "level11",    RTLOGGRPFLAGS_LEVEL_11 },
+            { "l12",        RTLOGGRPFLAGS_LEVEL_12 },
+            { "level12",    RTLOGGRPFLAGS_LEVEL_12 },
+            { "f",          RTLOGGRPFLAGS_FLOW },
+            { "flow",       RTLOGGRPFLAGS_FLOW },
+            { "w",          RTLOGGRPFLAGS_WARN },
+            { "warn",       RTLOGGRPFLAGS_WARN },
+            { "warning",    RTLOGGRPFLAGS_WARN },
+            { "restrict",   RTLOGGRPFLAGS_RESTRICT },
+
+        };
+        unsigned    i;
+        bool        fFound = false;
+        psz++;
+        for (i = 0; i < RT_ELEMENTS(aFlags) && !fFound; i++)
+        {
+            const char *psz1 = aFlags[i].pszFlag;
+            const char *psz2 = psz;
+            while (*psz1 == RT_C_TO_LOWER(*psz2))
+            {
+                psz1++;
+                psz2++;
+                if (!*psz1)
+                {
+                    if (    (*psz2 >= 'a' && *psz2 <= 'z')
+                        ||  (*psz2 >= 'A' && *psz2 <= 'Z')
+                        ||  (*psz2 >= '0' && *psz2 <= '9') )
+                        break;
+                    fFlags |= aFlags[i].fFlag;
+                    fFound = true;
+                    psz = psz2;
+                    break;
+                }
+            } /* strincmp */
+        } /* for each flags */
+        AssertMsg(fFound, ("%.15s...", psz));
+    }
+
+    /*
+     * Flag value.
+     */
+    if (*psz == '=')
+    {
+        psz++;
+        if (*psz == '~')
+            fFlags = ~RTStrToInt32(psz + 1);
+        else
+            fFlags = RTStrToInt32(psz);
+    }
+
+    return fFlags;
+}
+
+/**
+ * Helper for RTLogGetGroupSettings.
+ */
+static int rtLogGetGroupSettingsAddOne(const char *pszName, uint32_t fGroup, char **ppszBuf, size_t *pcchBuf, bool *pfNotFirst)
+{
+# define APPEND_PSZ(psz,cch) do { memcpy(*ppszBuf, (psz), (cch)); *ppszBuf += (cch); *pcchBuf -= (cch); } while (0)
+# define APPEND_SZ(sz)       APPEND_PSZ(sz, sizeof(sz) - 1)
+# define APPEND_CH(ch)       do { **ppszBuf = (ch); *ppszBuf += 1; *pcchBuf -= 1; } while (0)
+
+    /*
+     * Add the name.
+     */
+    size_t cchName = strlen(pszName);
+    if (cchName + 1 + *pfNotFirst > *pcchBuf)
+        return VERR_BUFFER_OVERFLOW;
+    if (*pfNotFirst)
+        APPEND_CH(' ');
+    else
+        *pfNotFirst = true;
+    APPEND_PSZ(pszName, cchName);
+
+    /*
+     * Only generate mnemonics for the simple+common bits.
+     */
+    if (fGroup == (RTLOGGRPFLAGS_ENABLED | RTLOGGRPFLAGS_LEVEL_1))
+        /* nothing */;
+    else if (    fGroup == (RTLOGGRPFLAGS_ENABLED | RTLOGGRPFLAGS_LEVEL_1 | RTLOGGRPFLAGS_LEVEL_2 |  RTLOGGRPFLAGS_FLOW)
+             &&  *pcchBuf >= sizeof(".e.l.f"))
+        APPEND_SZ(".e.l.f");
+    else if (    fGroup == (RTLOGGRPFLAGS_ENABLED | RTLOGGRPFLAGS_LEVEL_1 | RTLOGGRPFLAGS_FLOW)
+             &&  *pcchBuf >= sizeof(".e.f"))
+        APPEND_SZ(".e.f");
+    else if (*pcchBuf >= 1 + 10 + 1)
+    {
+        size_t cch;
+        APPEND_CH('=');
+        cch = RTStrFormatNumber(*ppszBuf, fGroup, 16, 0, 0, RTSTR_F_SPECIAL | RTSTR_F_32BIT);
+        *ppszBuf += cch;
+        *pcchBuf -= cch;
+    }
+    else
+        return VERR_BUFFER_OVERFLOW;
+
+# undef APPEND_PSZ
+# undef APPEND_SZ
+# undef APPEND_CH
+    return VINF_SUCCESS;
+}
+
+
+/**
+ * Get the current log group settings as a string.
+ *
+ * @returns VINF_SUCCESS or VERR_BUFFER_OVERFLOW.
+ * @param   pLogger             Logger instance (NULL for default logger).
+ * @param   pszBuf              The output buffer.
+ * @param   cchBuf              The size of the output buffer. Must be greater
+ *                              than zero.
+ */
+RTDECL(int) RTLogGetGroupSettings(PRTLOGGER pLogger, char *pszBuf, size_t cchBuf)
+{
+    bool        fNotFirst = false;
+    int         rc        = VINF_SUCCESS;
+    uint32_t    cGroups;
+    uint32_t    fGroup;
+    uint32_t    i;
+
+    Assert(cchBuf);
+
+    /*
+     * Resolve defaults.
+     */
+    if (!pLogger)
+    {
+        pLogger = RTLogDefaultInstance();
+        if (!pLogger)
+        {
+            *pszBuf = '\0';
+            return VINF_SUCCESS;
+        }
+    }
+
+    cGroups = pLogger->cGroups;
+
+    /*
+     * Check if all are the same.
+     */
+    fGroup = pLogger->afGroups[0];
+    for (i = 1; i < cGroups; i++)
+        if (pLogger->afGroups[i] != fGroup)
+            break;
+    if (i >= cGroups)
+        rc = rtLogGetGroupSettingsAddOne("all", fGroup, &pszBuf, &cchBuf, &fNotFirst);
+    else
+    {
+
+        /*
+         * Iterate all the groups and print all that are enabled.
+         */
+        for (i = 0; i < cGroups; i++)
+        {
+            fGroup = pLogger->afGroups[i];
+            if (fGroup)
+            {
+                const char *pszName = pLogger->pInt->papszGroups[i];
+                if (pszName)
+                {
+                    rc = rtLogGetGroupSettingsAddOne(pszName, fGroup, &pszBuf, &cchBuf, &fNotFirst);
+                    if (rc)
+                        break;
+                }
+            }
+        }
+    }
+
+    *pszBuf = '\0';
+    return rc;
+}
+RT_EXPORT_SYMBOL(RTLogGetGroupSettings);
+
+#endif /* !IN_RC */
+
+/**
+ * Updates the flags for the logger instance using the specified
+ * specification string.
+ *
+ * @returns iprt status code.
+ *          Failures can safely be ignored.
+ * @param   pLogger     Logger instance (NULL for default logger).
+ * @param   pszValue    Value to parse.
+ */
+RTDECL(int) RTLogFlags(PRTLOGGER pLogger, const char *pszValue)
+{
+    int rc = VINF_SUCCESS;
+
+    /*
+     * Resolve defaults.
+     */
+    if (!pLogger)
+    {
+        pLogger = RTLogDefaultInstance();
+        if (!pLogger)
+            return VINF_SUCCESS;
+    }
+
+    /*
+     * Iterate the string.
+     */
+    while (*pszValue)
+    {
+        /* check no prefix. */
+        bool fNo = false;
+        char ch;
+        unsigned i;
+
+        /* skip blanks. */
+        while (RT_C_IS_SPACE(*pszValue))
+            pszValue++;
+        if (!*pszValue)
+            return rc;
+
+        while ((ch = *pszValue) != '\0')
+        {
+            if (ch == 'n' && pszValue[1] == 'o')
+            {
+                pszValue += 2;
+                fNo = !fNo;
+            }
+            else if (ch == '+')
+            {
+                pszValue++;
+                fNo = true;
+            }
+            else if (ch == '-' || ch == '!' || ch == '~')
+            {
+                pszValue++;
+                fNo = !fNo;
+            }
+            else
+                break;
+        }
+
+        /* instruction. */
+        for (i = 0; i < RT_ELEMENTS(g_aLogFlags); i++)
+        {
+            if (!strncmp(pszValue, g_aLogFlags[i].pszInstr, g_aLogFlags[i].cchInstr))
+            {
+                if (fNo == g_aLogFlags[i].fInverted)
+                    pLogger->fFlags |= g_aLogFlags[i].fFlag;
+                else
+                    pLogger->fFlags &= ~g_aLogFlags[i].fFlag;
+                pszValue += g_aLogFlags[i].cchInstr;
+                break;
+            }
+        }
+
+        /* unknown instruction? */
+        if (i >= RT_ELEMENTS(g_aLogFlags))
+        {
+            AssertMsgFailed(("Invalid flags! unknown instruction %.20s\n", pszValue));
+            pszValue++;
+        }
+
+        /* skip blanks and delimiters. */
+        while (RT_C_IS_SPACE(*pszValue) || *pszValue == ';')
+            pszValue++;
+    } /* while more environment variable value left */
+
+    return rc;
+}
+RT_EXPORT_SYMBOL(RTLogFlags);
+
+
+/**
+ * Changes the buffering setting of the specified logger.
+ *
+ * This can be used for optimizing longish logging sequences.
+ *
+ * @returns The old state.
+ * @param   pLogger         The logger instance (NULL is an alias for the
+ *                          default logger).
+ * @param   fBuffered       The new state.
+ */
+RTDECL(bool) RTLogSetBuffering(PRTLOGGER pLogger, bool fBuffered)
+{
+    bool fOld;
+
+    /*
+     * Resolve the logger instance.
+     */
+    if (!pLogger)
+    {
+        pLogger = RTLogDefaultInstance();
+        if (!pLogger)
+            return false;
+    }
+
+    rtlogLock(pLogger);
+    fOld  = !!(pLogger->fFlags & RTLOGFLAGS_BUFFERED);
+    if (fBuffered)
+        pLogger->fFlags |= RTLOGFLAGS_BUFFERED;
+    else
+        pLogger->fFlags &= ~RTLOGFLAGS_BUFFERED;
+    rtlogUnlock(pLogger);
+
+    return fOld;
+}
+RT_EXPORT_SYMBOL(RTLogSetBuffering);
+
+
+#ifdef IN_RING3
+RTDECL(uint32_t) RTLogSetGroupLimit(PRTLOGGER pLogger, uint32_t cMaxEntriesPerGroup)
+{
+    /*
+     * Resolve the logger instance.
+     */
+    if (!pLogger)
+    {
+        pLogger = RTLogDefaultInstance();
+        if (!pLogger)
+            return UINT32_MAX;
+    }
+
+    rtlogLock(pLogger);
+    uint32_t cOld = pLogger->pInt->cMaxEntriesPerGroup;
+    pLogger->pInt->cMaxEntriesPerGroup = cMaxEntriesPerGroup;
+    rtlogUnlock(pLogger);
+
+    return cOld;
+}
+#endif
+
+#ifndef IN_RC
+
+/**
+ * Get the current log flags as a string.
+ *
+ * @returns VINF_SUCCESS or VERR_BUFFER_OVERFLOW.
+ * @param   pLogger             Logger instance (NULL for default logger).
+ * @param   pszBuf              The output buffer.
+ * @param   cchBuf              The size of the output buffer. Must be greater
+ *                              than zero.
+ */
+RTDECL(int) RTLogGetFlags(PRTLOGGER pLogger, char *pszBuf, size_t cchBuf)
+{
+    bool        fNotFirst = false;
+    int         rc        = VINF_SUCCESS;
+    uint32_t    fFlags;
+    unsigned    i;
+
+    Assert(cchBuf);
+
+    /*
+     * Resolve defaults.
+     */
+    if (!pLogger)
+    {
+        pLogger = RTLogDefaultInstance();
+        if (!pLogger)
+        {
+            *pszBuf = '\0';
+            return VINF_SUCCESS;
+        }
+    }
+
+    /*
+     * Add the flags in the list.
+     */
+    fFlags = pLogger->fFlags;
+    for (i = 0; i < RT_ELEMENTS(g_aLogFlags); i++)
+        if (    !g_aLogFlags[i].fInverted
+            ?   (g_aLogFlags[i].fFlag & fFlags)
+            :   !(g_aLogFlags[i].fFlag & fFlags))
+        {
+            size_t cchInstr = g_aLogFlags[i].cchInstr;
+            if (cchInstr + fNotFirst + 1 > cchBuf)
+            {
+                rc = VERR_BUFFER_OVERFLOW;
+                break;
+            }
+            if (fNotFirst)
+            {
+                *pszBuf++ = ' ';
+                cchBuf--;
+            }
+            memcpy(pszBuf, g_aLogFlags[i].pszInstr, cchInstr);
+            pszBuf += cchInstr;
+            cchBuf -= cchInstr;
+            fNotFirst = true;
+        }
+    *pszBuf = '\0';
+    return rc;
+}
+RT_EXPORT_SYMBOL(RTLogGetFlags);
+
+
+/**
+ * Updates the logger destination using the specified string.
+ *
+ * @returns VINF_SUCCESS or VERR_BUFFER_OVERFLOW.
+ * @param   pLogger             Logger instance (NULL for default logger).
+ * @param   pszValue            The value to parse.
+ */
+RTDECL(int) RTLogDestinations(PRTLOGGER pLogger, char const *pszValue)
+{
+    /*
+     * Resolve defaults.
+     */
+    if (!pLogger)
+    {
+        pLogger = RTLogDefaultInstance();
+        if (!pLogger)
+            return VINF_SUCCESS;
+    }
+
+    /*
+     * Do the parsing.
+     */
+    while (*pszValue)
+    {
+        bool fNo;
+        unsigned i;
+
+        /* skip blanks. */
+        while (RT_C_IS_SPACE(*pszValue))
+            pszValue++;
+        if (!*pszValue)
+            break;
+
+        /* check no prefix. */
+        fNo = false;
+        if (pszValue[0] == 'n' && pszValue[1] == 'o')
+        {
+            fNo = true;
+            pszValue += 2;
+        }
+
+        /* instruction. */
+        for (i = 0; i < RT_ELEMENTS(s_aLogDst); i++)
+        {
+            size_t cchInstr = strlen(s_aLogDst[i].pszInstr);
+            if (!strncmp(pszValue, s_aLogDst[i].pszInstr, cchInstr))
+            {
+                if (!fNo)
+                    pLogger->fDestFlags |= s_aLogDst[i].fFlag;
+                else
+                    pLogger->fDestFlags &= ~s_aLogDst[i].fFlag;
+                pszValue += cchInstr;
+
+                /* check for value. */
+                while (RT_C_IS_SPACE(*pszValue))
+                    pszValue++;
+                if (*pszValue == '=' || *pszValue == ':')
+                {
+                    const char *pszEnd;
+
+                    pszValue++;
+                    pszEnd = strchr(pszValue, ';');
+                    if (!pszEnd)
+                        pszEnd = strchr(pszValue, '\0');
+                    size_t cch = pszEnd - pszValue;
+# ifdef IN_RING3
+                    char szTmp[sizeof(pLogger->pInt->szFilename)];
+# else
+                    char szTmp[32];
+# endif
+                    if (0)
+                    { /* nothing */ }
+#ifdef IN_RING3
+
+                    /* log file name */
+                    else if (i == 0 /* file */ && !fNo)
+                    {
+                        AssertReturn(cch < sizeof(pLogger->pInt->szFilename), VERR_OUT_OF_RANGE);
+                        memcpy(pLogger->pInt->szFilename, pszValue, cch);
+                        pLogger->pInt->szFilename[cch] = '\0';
+                        /** @todo reopen log file if pLogger->pInt->fCreated is true ... */
+                    }
+                    /* log directory */
+                    else if (i == 1 /* dir */ && !fNo)
+                    {
+                        const char *pszFile = RTPathFilename(pLogger->pInt->szFilename);
+                        size_t      cchFile = pszFile ? strlen(pszFile) : 0;
+                        AssertReturn(cchFile + cch + 1 < sizeof(pLogger->pInt->szFilename), VERR_OUT_OF_RANGE);
+                        memcpy(szTmp, cchFile ? pszFile : "", cchFile + 1);
+
+                        memcpy(pLogger->pInt->szFilename, pszValue, cch);
+                        pLogger->pInt->szFilename[cch] = '\0';
+                        RTPathStripTrailingSlash(pLogger->pInt->szFilename);
+
+                        cch = strlen(pLogger->pInt->szFilename);
+                        pLogger->pInt->szFilename[cch++] = '/';
+                        memcpy(&pLogger->pInt->szFilename[cch], szTmp, cchFile);
+                        pLogger->pInt->szFilename[cch + cchFile] = '\0';
+                        /** @todo reopen log file if pLogger->pInt->fCreated is true ... */
+                    }
+                    else if (i == 2 /* history */)
+                    {
+                        if (!fNo)
+                        {
+                            uint32_t cHistory = 0;
+                            int rc = RTStrCopyEx(szTmp, sizeof(szTmp), pszValue, cch);
+                            if (RT_SUCCESS(rc))
+                                rc = RTStrToUInt32Full(szTmp, 0, &cHistory);
+                            AssertMsgReturn(RT_SUCCESS(rc) && cHistory < _1M, ("Invalid history value %s (%Rrc)!\n", szTmp, rc), rc);
+                            pLogger->pInt->cHistory = cHistory;
+                        }
+                        else
+                            pLogger->pInt->cHistory = 0;
+                    }
+                    else if (i == 3 /* histsize */)
+                    {
+                        if (!fNo)
+                        {
+                            int rc = RTStrCopyEx(szTmp, sizeof(szTmp), pszValue, cch);
+                            if (RT_SUCCESS(rc))
+                                rc = RTStrToUInt64Full(szTmp, 0, &pLogger->pInt->cbHistoryFileMax);
+                            AssertMsgRCReturn(rc, ("Invalid history file size value %s (%Rrc)!\n", szTmp, rc), rc);
+                            if (pLogger->pInt->cbHistoryFileMax == 0)
+                                pLogger->pInt->cbHistoryFileMax = UINT64_MAX;
+                        }
+                        else
+                            pLogger->pInt->cbHistoryFileMax = UINT64_MAX;
+                    }
+                    else if (i == 4 /* histtime */)
+                    {
+                        if (!fNo)
+                        {
+                            int rc = RTStrCopyEx(szTmp, sizeof(szTmp), pszValue, cch);
+                            if (RT_SUCCESS(rc))
+                                rc = RTStrToUInt32Full(szTmp, 0, &pLogger->pInt->cSecsHistoryTimeSlot);
+                            AssertMsgRCReturn(rc, ("Invalid history time slot value %s (%Rrc)!\n", szTmp, rc), rc);
+                            if (pLogger->pInt->cSecsHistoryTimeSlot == 0)
+                                pLogger->pInt->cSecsHistoryTimeSlot = UINT32_MAX;
+                        }
+                        else
+                            pLogger->pInt->cSecsHistoryTimeSlot = UINT32_MAX;
+                    }
+# endif /* IN_RING3 */
+                    else if (i == 5 /* ringbuf */ && !fNo)
+                    {
+                        int rc = RTStrCopyEx(szTmp, sizeof(szTmp), pszValue, cch);
+                        uint32_t cbRingBuf;
+                        if (RT_SUCCESS(rc))
+                            rc = RTStrToUInt32Full(szTmp, 0, &cbRingBuf);
+                        AssertMsgRCReturn(rc, ("Invalid ring buffer size value '%s' (%Rrc)!\n", szTmp, rc), rc);
+
+                        if (cbRingBuf == 0)
+                            cbRingBuf = RTLOG_RINGBUF_DEFAULT_SIZE;
+                        else if (cbRingBuf < RTLOG_RINGBUF_MIN_SIZE)
+                            cbRingBuf = RTLOG_RINGBUF_MIN_SIZE;
+                        else if (cbRingBuf > RTLOG_RINGBUF_MAX_SIZE)
+                            cbRingBuf = RTLOG_RINGBUF_MAX_SIZE;
+                        else
+                            cbRingBuf = RT_ALIGN_32(cbRingBuf, 64);
+                        rc = rtLogRingBufAdjust(pLogger, cbRingBuf, false /*fForce*/);
+                        if (RT_FAILURE(rc))
+                            return rc;
+                    }
+                    else
+                        AssertMsgFailedReturn(("Invalid destination value! %s%s doesn't take a value!\n",
+                                               fNo ? "no" : "", s_aLogDst[i].pszInstr),
+                                              VERR_INVALID_PARAMETER);
+
+                    pszValue = pszEnd + (*pszEnd != '\0');
+                }
+                else if (i == 5 /* ringbuf */ && !fNo && !pLogger->pInt->pszRingBuf)
+                {
+                    int rc = rtLogRingBufAdjust(pLogger, pLogger->pInt->cbRingBuf, false /*fForce*/);
+                    if (RT_FAILURE(rc))
+                        return rc;
+                }
+                break;
+            }
+        }
+
+        /* assert known instruction */
+        AssertMsgReturn(i < RT_ELEMENTS(s_aLogDst),
+                        ("Invalid destination value! unknown instruction %.20s\n", pszValue),
+                        VERR_INVALID_PARAMETER);
+
+        /* skip blanks and delimiters. */
+        while (RT_C_IS_SPACE(*pszValue) || *pszValue == ';')
+            pszValue++;
+    } /* while more environment variable value left */
+
+    return VINF_SUCCESS;
+}
+RT_EXPORT_SYMBOL(RTLogDestinations);
+
+
+/**
+ * Get the current log destinations as a string.
+ *
+ * @returns VINF_SUCCESS or VERR_BUFFER_OVERFLOW.
+ * @param   pLogger             Logger instance (NULL for default logger).
+ * @param   pszBuf              The output buffer.
+ * @param   cchBuf              The size of the output buffer. Must be greater
+ *                              than 0.
+ */
+RTDECL(int) RTLogGetDestinations(PRTLOGGER pLogger, char *pszBuf, size_t cchBuf)
+{
+    bool        fNotFirst = false;
+    int         rc        = VINF_SUCCESS;
+    uint32_t    fDestFlags;
+    unsigned    i;
+
+    AssertReturn(cchBuf, VERR_INVALID_PARAMETER);
+    *pszBuf = '\0';
+
+    /*
+     * Resolve defaults.
+     */
+    if (!pLogger)
+    {
+        pLogger = RTLogDefaultInstance();
+        if (!pLogger)
+            return VINF_SUCCESS;
+    }
+
+    /*
+     * Add the flags in the list.
+     */
+    fDestFlags = pLogger->fDestFlags;
+    for (i = 6; i < RT_ELEMENTS(s_aLogDst); i++)
+        if (s_aLogDst[i].fFlag & fDestFlags)
+        {
+            if (fNotFirst)
+            {
+                rc = RTStrCopyP(&pszBuf, &cchBuf, " ");
+                if (RT_FAILURE(rc))
+                    return rc;
+            }
+            rc = RTStrCopyP(&pszBuf, &cchBuf, s_aLogDst[i].pszInstr);
+            if (RT_FAILURE(rc))
+                return rc;
+            fNotFirst = true;
+        }
+
+    char szNum[32];
+
+# ifdef IN_RING3
+    /*
+     * Add the filename.
+     */
+    if (fDestFlags & RTLOGDEST_FILE)
+    {
+        rc = RTStrCopyP(&pszBuf, &cchBuf, fNotFirst ? " file=" : "file=");
+        if (RT_FAILURE(rc))
+            return rc;
+        rc = RTStrCopyP(&pszBuf, &cchBuf, pLogger->pInt->szFilename);
+        if (RT_FAILURE(rc))
+            return rc;
+        fNotFirst = true;
+
+        if (pLogger->pInt->cHistory)
+        {
+            RTStrPrintf(szNum, sizeof(szNum), fNotFirst ? " history=%u" : "history=%u", pLogger->pInt->cHistory);
+            rc = RTStrCopyP(&pszBuf, &cchBuf, szNum);
+            if (RT_FAILURE(rc))
+                return rc;
+            fNotFirst = true;
+        }
+        if (pLogger->pInt->cbHistoryFileMax != UINT64_MAX)
+        {
+            RTStrPrintf(szNum, sizeof(szNum), fNotFirst ? " histsize=%llu" : "histsize=%llu", pLogger->pInt->cbHistoryFileMax);
+            rc = RTStrCopyP(&pszBuf, &cchBuf, szNum);
+            if (RT_FAILURE(rc))
+                return rc;
+            fNotFirst = true;
+        }
+        if (pLogger->pInt->cSecsHistoryTimeSlot != UINT32_MAX)
+        {
+            RTStrPrintf(szNum, sizeof(szNum), fNotFirst ? " histtime=%llu" : "histtime=%llu", pLogger->pInt->cSecsHistoryTimeSlot);
+            rc = RTStrCopyP(&pszBuf, &cchBuf, szNum);
+            if (RT_FAILURE(rc))
+                return rc;
+            fNotFirst = true;
+        }
+    }
+# endif /* IN_RING3 */
+
+    /*
+     * Add the ring buffer.
+     */
+    if (fDestFlags & RTLOGDEST_RINGBUF)
+    {
+        if (pLogger->pInt->cbRingBuf == RTLOG_RINGBUF_DEFAULT_SIZE)
+            rc = RTStrCopyP(&pszBuf, &cchBuf, fNotFirst ? " ringbuf" : "ringbuf");
+        else
+        {
+            RTStrPrintf(szNum, sizeof(szNum), fNotFirst ? " ringbuf=%#x" : "ringbuf=%#x", pLogger->pInt->cbRingBuf);
+            rc = RTStrCopyP(&pszBuf, &cchBuf, szNum);
+        }
+        if (RT_FAILURE(rc))
+            return rc;
+        fNotFirst = true;
+    }
+
+    return VINF_SUCCESS;
+}
+RT_EXPORT_SYMBOL(RTLogGetDestinations);
+
+#endif /* !IN_RC */
+
+/**
+ * Flushes the specified logger.
+ *
+ * @param   pLogger     The logger instance to flush.
+ *                      If NULL the default instance is used. The default instance
+ *                      will not be initialized by this call.
+ */
+RTDECL(void) RTLogFlush(PRTLOGGER pLogger)
+{
+    /*
+     * Resolve defaults.
+     */
+    if (!pLogger)
+    {
+#ifdef IN_RC
+        pLogger = &g_Logger;
+#else
+        pLogger = g_pLogger;
+#endif
+        if (!pLogger)
+            return;
+    }
+
+    /*
+     * Any thing to flush?
+     */
+    if (   pLogger->offScratch
+#ifndef IN_RC
+        || (pLogger->fDestFlags & RTLOGDEST_RINGBUF)
+#endif
+       )
+    {
+#ifndef IN_RC
+        /*
+         * Acquire logger instance sem.
+         */
+        int rc = rtlogLock(pLogger);
+        if (RT_FAILURE(rc))
+            return;
+#endif
+        /*
+         * Call worker.
+         */
+        rtlogFlush(pLogger);
+
+#ifndef IN_RC
+        /*
+         * Since this is an explicit flush call, the ring buffer content should
+         * be flushed to the other destinations if active.
+         */
+        if (   (pLogger->fDestFlags & RTLOGDEST_RINGBUF)
+            && pLogger->pInt->pszRingBuf /* paranoia */)
+            rtLogRingBufFlush(pLogger);
+
+        /*
+         * Release the semaphore.
+         */
+        rtlogUnlock(pLogger);
+#endif
+    }
+}
+RT_EXPORT_SYMBOL(RTLogFlush);
+
+
+/**
+ * Common worker for RTLogDefaultInstance and RTLogDefaultInstanceEx.
+ */
+DECL_FORCE_INLINE(PRTLOGGER) rtLogDefaultInstanceCommon(void)
+{
+#ifdef IN_RC
+    return &g_Logger;
+
+#else /* !IN_RC */
+# ifdef IN_RING0
+    /*
+     * Check per thread loggers first.
+     */
+    if (g_cPerThreadLoggers)
+    {
+        const RTNATIVETHREAD Self = RTThreadNativeSelf();
+        int32_t i = RT_ELEMENTS(g_aPerThreadLoggers);
+        while (i-- > 0)
+            if (g_aPerThreadLoggers[i].NativeThread == Self)
+                return g_aPerThreadLoggers[i].pLogger;
+    }
+# endif /* IN_RING0 */
+
+    /*
+     * If no per thread logger, use the default one.
+     */
+    if (!g_pLogger)
+        g_pLogger = RTLogDefaultInit();
+    return g_pLogger;
+#endif /* !IN_RC */
+}
+
+
+RTDECL(PRTLOGGER)   RTLogDefaultInstance(void)
+{
+    return rtLogDefaultInstanceCommon();
+}
+RT_EXPORT_SYMBOL(RTLogDefaultInstance);
+
+
+RTDECL(PRTLOGGER)   RTLogDefaultInstanceEx(uint32_t fFlagsAndGroup)
+{
+    PRTLOGGER pLogger = rtLogDefaultInstanceCommon();
+    if (pLogger)
+    {
+        if (pLogger->fFlags & RTLOGFLAGS_DISABLED)
+            pLogger = NULL;
+        else
+        {
+            uint16_t const fFlags = RT_LO_U16(fFlagsAndGroup);
+            uint16_t const iGroup = RT_HI_U16(fFlagsAndGroup);
+            if (   iGroup != UINT16_MAX
+                 && (   (pLogger->afGroups[iGroup < pLogger->cGroups ? iGroup : 0] & (fFlags | RTLOGGRPFLAGS_ENABLED))
+                     != (fFlags | RTLOGGRPFLAGS_ENABLED)))
+            pLogger = NULL;
+        }
+    }
+    return pLogger;
+}
+RT_EXPORT_SYMBOL(RTLogDefaultInstanceEx);
+
+
+/**
+ * Common worker for RTLogGetDefaultInstance and RTLogGetDefaultInstanceEx.
+ */
+DECL_FORCE_INLINE(PRTLOGGER) rtLogGetDefaultInstanceCommon(void)
+{
+#ifdef IN_RC
+    return &g_Logger;
+#else
+# ifdef IN_RING0
+    /*
+     * Check per thread loggers first.
+     */
+    if (g_cPerThreadLoggers)
+    {
+        const RTNATIVETHREAD Self = RTThreadNativeSelf();
+        int32_t i = RT_ELEMENTS(g_aPerThreadLoggers);
+        while (i-- > 0)
+            if (g_aPerThreadLoggers[i].NativeThread == Self)
+                return g_aPerThreadLoggers[i].pLogger;
+    }
+# endif /* IN_RING0 */
+
+    return g_pLogger;
+#endif
+}
+
+
+RTDECL(PRTLOGGER) RTLogGetDefaultInstance(void)
+{
+    return rtLogGetDefaultInstanceCommon();
+}
+RT_EXPORT_SYMBOL(RTLogGetDefaultInstance);
+
+
+RTDECL(PRTLOGGER) RTLogGetDefaultInstanceEx(uint32_t fFlagsAndGroup)
+{
+    PRTLOGGER pLogger = rtLogGetDefaultInstanceCommon();
+    if (pLogger)
+    {
+        if (pLogger->fFlags & RTLOGFLAGS_DISABLED)
+            pLogger = NULL;
+        else
+        {
+            uint32_t const fFlags = RT_LO_U16(fFlagsAndGroup);
+            uint16_t const iGroup = RT_HI_U16(fFlagsAndGroup);
+            if (   iGroup != UINT16_MAX
+                 && (   (pLogger->afGroups[iGroup < pLogger->cGroups ? iGroup : 0] & (fFlags | RTLOGGRPFLAGS_ENABLED))
+                     != (fFlags | RTLOGGRPFLAGS_ENABLED)))
+            pLogger = NULL;
+        }
+    }
+    return pLogger;
+}
+RT_EXPORT_SYMBOL(RTLogGetDefaultInstanceEx);
+
+
+#ifndef IN_RC
+/**
+ * Sets the default logger instance.
+ *
+ * @returns iprt status code.
+ * @param   pLogger     The new default logger instance.
+ */
+RTDECL(PRTLOGGER) RTLogSetDefaultInstance(PRTLOGGER pLogger)
+{
+    return ASMAtomicXchgPtrT(&g_pLogger, pLogger, PRTLOGGER);
+}
+RT_EXPORT_SYMBOL(RTLogSetDefaultInstance);
+#endif /* !IN_RC */
+
+
+#ifdef IN_RING0
+/**
+ * Changes the default logger instance for the current thread.
+ *
+ * @returns IPRT status code.
+ * @param   pLogger     The logger instance. Pass NULL for deregistration.
+ * @param   uKey        Associated key for cleanup purposes. If pLogger is NULL,
+ *                      all instances with this key will be deregistered. So in
+ *                      order to only deregister the instance associated with the
+ *                      current thread use 0.
+ */
+RTDECL(int) RTLogSetDefaultInstanceThread(PRTLOGGER pLogger, uintptr_t uKey)
+{
+    int             rc;
+    RTNATIVETHREAD  Self = RTThreadNativeSelf();
+    if (pLogger)
+    {
+        int32_t i;
+        unsigned j;
+
+        AssertReturn(pLogger->u32Magic == RTLOGGER_MAGIC, VERR_INVALID_MAGIC);
+
+        /*
+         * Iterate the table to see if there is already an entry for this thread.
+         */
+        i = RT_ELEMENTS(g_aPerThreadLoggers);
+        while (i-- > 0)
+            if (g_aPerThreadLoggers[i].NativeThread == Self)
+            {
+                ASMAtomicWritePtr((void * volatile *)&g_aPerThreadLoggers[i].uKey, (void *)uKey);
+                g_aPerThreadLoggers[i].pLogger = pLogger;
+                return VINF_SUCCESS;
+            }
+
+        /*
+         * Allocate a new table entry.
+         */
+        i = ASMAtomicIncS32(&g_cPerThreadLoggers);
+        if (i > (int32_t)RT_ELEMENTS(g_aPerThreadLoggers))
+        {
+            ASMAtomicDecS32(&g_cPerThreadLoggers);
+            return VERR_BUFFER_OVERFLOW; /* horrible error code! */
+        }
+
+        for (j = 0; j < 10; j++)
+        {
+            i = RT_ELEMENTS(g_aPerThreadLoggers);
+            while (i-- > 0)
+            {
+                AssertCompile(sizeof(RTNATIVETHREAD) == sizeof(void*));
+                if (    g_aPerThreadLoggers[i].NativeThread == NIL_RTNATIVETHREAD
+                    &&  ASMAtomicCmpXchgPtr((void * volatile *)&g_aPerThreadLoggers[i].NativeThread, (void *)Self, (void *)NIL_RTNATIVETHREAD))
+                {
+                    ASMAtomicWritePtr((void * volatile *)&g_aPerThreadLoggers[i].uKey, (void *)uKey);
+                    ASMAtomicWritePtr(&g_aPerThreadLoggers[i].pLogger, pLogger);
+                    return VINF_SUCCESS;
+                }
+            }
+        }
+
+        ASMAtomicDecS32(&g_cPerThreadLoggers);
+        rc = VERR_INTERNAL_ERROR;
+    }
+    else
+    {
+        /*
+         * Search the array for the current thread.
+         */
+        int32_t i = RT_ELEMENTS(g_aPerThreadLoggers);
+        while (i-- > 0)
+            if (    g_aPerThreadLoggers[i].NativeThread == Self
+                ||  g_aPerThreadLoggers[i].uKey == uKey)
+            {
+                ASMAtomicWriteNullPtr((void * volatile *)&g_aPerThreadLoggers[i].uKey);
+                ASMAtomicWriteNullPtr(&g_aPerThreadLoggers[i].pLogger);
+                ASMAtomicWriteHandle(&g_aPerThreadLoggers[i].NativeThread, NIL_RTNATIVETHREAD);
+                ASMAtomicDecS32(&g_cPerThreadLoggers);
+            }
+
+        rc = VINF_SUCCESS;
+    }
+    return rc;
+}
+RT_EXPORT_SYMBOL(RTLogSetDefaultInstanceThread);
+#endif /* IN_RING0 */
+
+
+/**
+ * Write to a logger instance.
+ *
+ * @param   pLogger     Pointer to logger instance.
+ * @param   pszFormat   Format string.
+ * @param   args        Format arguments.
+ */
+RTDECL(void) RTLogLoggerV(PRTLOGGER pLogger, const char *pszFormat, va_list args)
+{
+    RTLogLoggerExV(pLogger, 0, ~0U, pszFormat, args);
+}
+RT_EXPORT_SYMBOL(RTLogLoggerV);
+
+
+/**
+ * Write to a logger instance.
+ *
+ * This function will check whether the instance, group and flags makes up a
+ * logging kind which is currently enabled before writing anything to the log.
+ *
+ * @param   pLogger     Pointer to logger instance. If NULL the default logger instance will be attempted.
+ * @param   fFlags      The logging flags.
+ * @param   iGroup      The group.
+ *                      The value ~0U is reserved for compatibility with RTLogLogger[V] and is
+ *                      only for internal usage!
+ * @param   pszFormat   Format string.
+ * @param   args        Format arguments.
+ */
+RTDECL(void) RTLogLoggerExV(PRTLOGGER pLogger, unsigned fFlags, unsigned iGroup, const char *pszFormat, va_list args)
+{
+    int rc;
+
+    /*
+     * A NULL logger means default instance.
+     */
+    if (!pLogger)
+    {
+        pLogger = RTLogDefaultInstance();
+        if (!pLogger)
+            return;
+    }
+
+    /*
+     * Validate and correct iGroup.
+     */
+    if (iGroup != ~0U && iGroup >= pLogger->cGroups)
+        iGroup = 0;
+
+    /*
+     * If no output, then just skip it.
+     */
+    if (    (pLogger->fFlags & RTLOGFLAGS_DISABLED)
+#ifndef IN_RC
+        || !pLogger->fDestFlags
+#endif
+        || !pszFormat || !*pszFormat)
+        return;
+    if (    iGroup != ~0U
+        &&  (pLogger->afGroups[iGroup] & (fFlags | RTLOGGRPFLAGS_ENABLED)) != (fFlags | RTLOGGRPFLAGS_ENABLED))
+        return;
+
+    /*
+     * Acquire logger instance sem.
+     */
+    rc = rtlogLock(pLogger);
+    if (RT_FAILURE(rc))
+    {
+#ifdef IN_RING0
+        if (pLogger->fDestFlags & ~RTLOGDEST_FILE)
+            rtR0LogLoggerExFallback(pLogger->fDestFlags, pLogger->fFlags, pLogger->pInt, pszFormat, args);
+#endif
+        return;
+    }
+
+    /*
+     * Check restrictions and call worker.
+     */
+#ifndef IN_RC
+    if (RT_UNLIKELY(   (pLogger->fFlags & RTLOGFLAGS_RESTRICT_GROUPS)
+                    && iGroup < pLogger->cGroups
+                    && (pLogger->afGroups[iGroup] & RTLOGGRPFLAGS_RESTRICT)
+                    && ++pLogger->pInt->pacEntriesPerGroup[iGroup] >= pLogger->pInt->cMaxEntriesPerGroup ))
+    {
+        uint32_t cEntries = pLogger->pInt->pacEntriesPerGroup[iGroup];
+        if (cEntries > pLogger->pInt->cMaxEntriesPerGroup)
+            pLogger->pInt->pacEntriesPerGroup[iGroup] = cEntries - 1;
+        else
+        {
+            rtlogLoggerExVLocked(pLogger, fFlags, iGroup, pszFormat, args);
+            if (   pLogger->pInt->papszGroups
+                && pLogger->pInt->papszGroups[iGroup])
+                rtlogLoggerExFLocked(pLogger, fFlags, iGroup, "%u messages from group %s (#%u), muting it.\n",
+                                     cEntries, pLogger->pInt->papszGroups[iGroup], iGroup);
+            else
+                rtlogLoggerExFLocked(pLogger, fFlags, iGroup, "%u messages from group #%u, muting it.\n",
+                                     cEntries, iGroup);
+        }
+    }
+    else
+#endif
+        rtlogLoggerExVLocked(pLogger, fFlags, iGroup, pszFormat, args);
+
+    /*
+     * Release the semaphore.
+     */
+    rtlogUnlock(pLogger);
+}
+RT_EXPORT_SYMBOL(RTLogLoggerExV);
+
+
+#ifdef IN_RING0
+/**
+ * For rtR0LogLoggerExFallbackOutput and rtR0LogLoggerExFallbackFlush.
+ */
+typedef struct RTR0LOGLOGGERFALLBACK
+{
+    /** The current scratch buffer offset. */
+    uint32_t            offScratch;
+    /** The destination flags. */
+    uint32_t            fDestFlags;
+    /** For ring buffer output. */
+    PRTLOGGERINTERNAL   pInt;
+    /** The scratch buffer. */
+    char                achScratch[80];
+} RTR0LOGLOGGERFALLBACK;
+/** Pointer to RTR0LOGLOGGERFALLBACK which is used by
+ * rtR0LogLoggerExFallbackOutput. */
+typedef RTR0LOGLOGGERFALLBACK *PRTR0LOGLOGGERFALLBACK;
+
+
+/**
+ * Flushes the fallback buffer.
+ *
+ * @param   pThis       The scratch buffer.
+ */
+static void rtR0LogLoggerExFallbackFlush(PRTR0LOGLOGGERFALLBACK pThis)
+{
+    if (!pThis->offScratch)
+        return;
+
+    if (   (pThis->fDestFlags & RTLOGDEST_RINGBUF)
+        && pThis->pInt
+        && pThis->pInt->pszRingBuf /* paranoia */)
+        rtLogRingBufWrite(pThis->pInt, pThis->achScratch, pThis->offScratch);
+    else
+    {
+        if (pThis->fDestFlags & RTLOGDEST_USER)
+            RTLogWriteUser(pThis->achScratch, pThis->offScratch);
+
+        if (pThis->fDestFlags & RTLOGDEST_DEBUGGER)
+            RTLogWriteDebugger(pThis->achScratch, pThis->offScratch);
+
+        if (pThis->fDestFlags & RTLOGDEST_STDOUT)
+            RTLogWriteStdOut(pThis->achScratch, pThis->offScratch);
+
+        if (pThis->fDestFlags & RTLOGDEST_STDERR)
+            RTLogWriteStdErr(pThis->achScratch, pThis->offScratch);
+
+# ifndef LOG_NO_COM
+        if (pThis->fDestFlags & RTLOGDEST_COM)
+            RTLogWriteCom(pThis->achScratch, pThis->offScratch);
+# endif
+    }
+
+    /* empty the buffer. */
+    pThis->offScratch = 0;
+}
+
+
+/**
+ * Callback for RTLogFormatV used by rtR0LogLoggerExFallback.
+ * See PFNLOGOUTPUT() for details.
+ */
+static DECLCALLBACK(size_t) rtR0LogLoggerExFallbackOutput(void *pv, const char *pachChars, size_t cbChars)
+{
+    PRTR0LOGLOGGERFALLBACK pThis = (PRTR0LOGLOGGERFALLBACK)pv;
+    if (cbChars)
+    {
+        size_t cbRet = 0;
+        for (;;)
+        {
+            /* how much */
+            uint32_t cb = sizeof(pThis->achScratch) - pThis->offScratch - 1; /* minus 1 - for the string terminator. */
+            if (cb > cbChars)
+                cb = (uint32_t)cbChars;
+
+            /* copy */
+            memcpy(&pThis->achScratch[pThis->offScratch], pachChars, cb);
+
+            /* advance */
+            pThis->offScratch += cb;
+            cbRet += cb;
+            cbChars -= cb;
+
+            /* done? */
+            if (cbChars <= 0)
+                return cbRet;
+
+            pachChars += cb;
+
+            /* flush */
+            pThis->achScratch[pThis->offScratch] = '\0';
+            rtR0LogLoggerExFallbackFlush(pThis);
+        }
+
+        /* won't ever get here! */
+    }
+    else
+    {
+        /*
+         * Termination call, flush the log.
+         */
+        pThis->achScratch[pThis->offScratch] = '\0';
+        rtR0LogLoggerExFallbackFlush(pThis);
+        return 0;
+    }
+}
+
+
+/**
+ * Ring-0 fallback for cases where we're unable to grab the lock.
+ *
+ * This will happen when we're at a too high IRQL on Windows for instance and
+ * needs to be dealt with or we'll drop a lot of log output. This fallback will
+ * only output to some of the log destinations as a few of them may be doing
+ * dangerous things. We won't be doing any prefixing here either, at least not
+ * for the present, because it's too much hassle.
+ *
+ * @param   fDestFlags  The destination flags.
+ * @param   fFlags      The logger flags.
+ * @param   pInt        The internal logger data, for ring buffer output.
+ * @param   pszFormat   The format string.
+ * @param   va          The format arguments.
+ */
+static void rtR0LogLoggerExFallback(uint32_t fDestFlags, uint32_t fFlags, PRTLOGGERINTERNAL pInt,
+                                    const char *pszFormat, va_list va)
+{
+    RTR0LOGLOGGERFALLBACK This;
+    This.fDestFlags = fDestFlags;
+    This.pInt = pInt;
+
+    /* fallback indicator. */
+    This.offScratch = 2;
+    This.achScratch[0] = '[';
+    This.achScratch[1] = 'F';
+
+    /* selected prefixes */
+    if (fFlags & RTLOGFLAGS_PREFIX_PID)
+    {
+        RTPROCESS Process = RTProcSelf();
+        This.achScratch[This.offScratch++] = ' ';
+        This.offScratch += RTStrFormatNumber(&This.achScratch[This.offScratch], Process, 16, sizeof(RTPROCESS) * 2, 0, RTSTR_F_ZEROPAD);
+    }
+    if (fFlags & RTLOGFLAGS_PREFIX_TID)
+    {
+        RTNATIVETHREAD Thread = RTThreadNativeSelf();
+        This.achScratch[This.offScratch++] = ' ';
+        This.offScratch += RTStrFormatNumber(&This.achScratch[This.offScratch], Thread, 16, sizeof(RTNATIVETHREAD) * 2, 0, RTSTR_F_ZEROPAD);
+    }
+
+    This.achScratch[This.offScratch++] = ']';
+    This.achScratch[This.offScratch++] = ' ';
+
+    RTLogFormatV(rtR0LogLoggerExFallbackOutput, &This, pszFormat, va);
+}
+#endif /* IN_RING0 */
+
+
+/**
+ * vprintf like function for writing to the default log.
+ *
+ * @param   pszFormat   Printf like format string.
+ * @param   va          Optional arguments as specified in pszFormat.
+ *
+ * @remark The API doesn't support formatting of floating point numbers at the moment.
+ */
+RTDECL(void) RTLogPrintfV(const char *pszFormat, va_list va)
+{
+    RTLogLoggerV(NULL, pszFormat, va);
+}
+RT_EXPORT_SYMBOL(RTLogPrintfV);
+
+
+/**
+ * Dumper vprintf-like function outputting to a logger.
+ *
+ * @param   pvUser          Pointer to the logger instance to use, NULL for
+ *                          default instance.
+ * @param   pszFormat       Format string.
+ * @param   va              Format arguments.
+ */
+RTDECL(void) RTLogDumpPrintfV(void *pvUser, const char *pszFormat, va_list va)
+{
+    RTLogLoggerV((PRTLOGGER)pvUser, pszFormat, va);
+}
+RT_EXPORT_SYMBOL(RTLogDumpPrintfV);
+
+
+#ifdef IN_RING3
+
+/**
+ * Opens/creates the log file.
+ *
+ * @param   pLogger         The logger instance to update. NULL is not allowed!
+ * @param   pszErrorMsg     A buffer which is filled with an error message if
+ *                          something fails.  May be NULL.
+ * @param   cchErrorMsg     The size of the error message buffer.
+ */
+static int rtlogFileOpen(PRTLOGGER pLogger, char *pszErrorMsg, size_t cchErrorMsg)
+{
+    uint32_t fOpen = RTFILE_O_WRITE | RTFILE_O_DENY_NONE;
+    if (pLogger->fFlags & RTLOGFLAGS_APPEND)
+        fOpen |= RTFILE_O_OPEN_CREATE | RTFILE_O_APPEND;
+    else
+        fOpen |= RTFILE_O_CREATE_REPLACE;
+    if (pLogger->fFlags & RTLOGFLAGS_WRITE_THROUGH)
+        fOpen |= RTFILE_O_WRITE_THROUGH;
+
+    unsigned cBackoff = 0;
+    int rc = RTFileOpen(&pLogger->pInt->hFile, pLogger->pInt->szFilename, fOpen);
+    while (   rc == VERR_SHARING_VIOLATION
+           && cBackoff < RT_ELEMENTS(g_acMsLogBackoff))
+    {
+        RTThreadSleep(g_acMsLogBackoff[cBackoff++]);
+        rc = RTFileOpen(&pLogger->pInt->hFile, pLogger->pInt->szFilename, fOpen);
+    }
+    if (RT_SUCCESS(rc))
+    {
+        rc = RTFileGetSize(pLogger->pInt->hFile, &pLogger->pInt->cbHistoryFileWritten);
+        if (RT_FAILURE(rc))
+        {
+            /* Don't complain if this fails, assume the file is empty. */
+            pLogger->pInt->cbHistoryFileWritten = 0;
+            rc = VINF_SUCCESS;
+        }
+    }
+    else
+    {
+        pLogger->pInt->hFile = NIL_RTFILE;
+        if (pszErrorMsg)
+            RTStrPrintf(pszErrorMsg, cchErrorMsg, N_("could not open file '%s' (fOpen=%#x)"), pLogger->pInt->szFilename, fOpen);
+    }
+    return rc;
+}
+
+
+/**
+ * Closes, rotates and opens the log files if necessary.
+ *
+ * Used by the rtlogFlush() function as well as RTLogCreateExV.
+ *
+ * @param   pLogger     The logger instance to update. NULL is not allowed!
+ * @param   uTimeSlot   Current time slot (for tikme based rotation).
+ * @param   fFirst      Flag whether this is the beginning of logging, i.e.
+ *                      called from RTLogCreateExV.  Prevents pfnPhase from
+ *                      being called.
+ */
+static void rtlogRotate(PRTLOGGER pLogger, uint32_t uTimeSlot, bool fFirst)
+{
+    /* Suppress rotating empty log files simply because the time elapsed. */
+    if (RT_UNLIKELY(!pLogger->pInt->cbHistoryFileWritten))
+        pLogger->pInt->uHistoryTimeSlotStart = uTimeSlot;
+
+    /* Check rotation condition: file still small enough and not too old? */
+    if (RT_LIKELY(   pLogger->pInt->cbHistoryFileWritten < pLogger->pInt->cbHistoryFileMax
+                  && uTimeSlot == pLogger->pInt->uHistoryTimeSlotStart))
+        return;
+
+    /*
+     * Save "disabled" log flag and make sure logging is disabled.
+     * The logging in the functions called during log file history
+     * rotation would cause severe trouble otherwise.
+     */
+    uint32_t const fSavedFlags = pLogger->fFlags;
+    pLogger->fFlags |= RTLOGFLAGS_DISABLED;
+
+    /*
+     * Disable log rotation temporarily, otherwise with extreme settings and
+     * chatty phase logging we could run into endless rotation.
+     */
+    uint32_t const cSavedHistory = pLogger->pInt->cHistory;
+    pLogger->pInt->cHistory = 0;
+
+    /*
+     * Close the old log file.
+     */
+    if (pLogger->pInt->hFile != NIL_RTFILE)
+    {
+        /* Use the callback to generate some final log contents, but only if
+         * this is a rotation with a fully set up logger. Leave the other case
+         * to the RTLogCreateExV function. */
+        if (pLogger->pInt->pfnPhase && !fFirst)
+        {
+            uint32_t fODestFlags = pLogger->fDestFlags;
+            pLogger->fDestFlags &= RTLOGDEST_FILE;
+            pLogger->pInt->pfnPhase(pLogger, RTLOGPHASE_PREROTATE, rtlogPhaseMsgLocked);
+            pLogger->fDestFlags = fODestFlags;
+        }
+        RTFileClose(pLogger->pInt->hFile);
+        pLogger->pInt->hFile = NIL_RTFILE;
+    }
+
+    if (cSavedHistory)
+    {
+        /*
+         * Rotate the log files.
+         */
+        for (uint32_t i = cSavedHistory - 1; i + 1 > 0; i--)
+        {
+            char szOldName[sizeof(pLogger->pInt->szFilename) + 32];
+            if (i > 0)
+                RTStrPrintf(szOldName, sizeof(szOldName), "%s.%u", pLogger->pInt->szFilename, i);
+            else
+                RTStrCopy(szOldName, sizeof(szOldName), pLogger->pInt->szFilename);
+
+            char szNewName[sizeof(pLogger->pInt->szFilename) + 32];
+            RTStrPrintf(szNewName, sizeof(szNewName), "%s.%u", pLogger->pInt->szFilename, i + 1);
+
+            unsigned cBackoff = 0;
+            int rc = RTFileRename(szOldName, szNewName, RTFILEMOVE_FLAGS_REPLACE);
+            while (   rc == VERR_SHARING_VIOLATION
+                   && cBackoff < RT_ELEMENTS(g_acMsLogBackoff))
+            {
+                RTThreadSleep(g_acMsLogBackoff[cBackoff++]);
+                rc = RTFileRename(szOldName, szNewName, RTFILEMOVE_FLAGS_REPLACE);
+            }
+
+            if (rc == VERR_FILE_NOT_FOUND)
+                RTFileDelete(szNewName);
+        }
+
+        /*
+         * Delete excess log files.
+         */
+        for (uint32_t i = cSavedHistory + 1; ; i++)
+        {
+            char szExcessName[sizeof(pLogger->pInt->szFilename) + 32];
+            RTStrPrintf(szExcessName, sizeof(szExcessName), "%s.%u", pLogger->pInt->szFilename, i);
+            int rc = RTFileDelete(szExcessName);
+            if (RT_FAILURE(rc))
+                break;
+        }
+    }
+
+    /*
+     * Update logger state and create new log file.
+     */
+    pLogger->pInt->cbHistoryFileWritten = 0;
+    pLogger->pInt->uHistoryTimeSlotStart = uTimeSlot;
+    rtlogFileOpen(pLogger, NULL, 0);
+
+    /*
+     * Use the callback to generate some initial log contents, but only if this
+     * is a rotation with a fully set up logger.  Leave the other case to the
+     * RTLogCreateExV function.
+     */
+    if (pLogger->pInt->pfnPhase && !fFirst)
+    {
+        uint32_t const fSavedDestFlags = pLogger->fDestFlags;
+        pLogger->fDestFlags &= RTLOGDEST_FILE;
+        pLogger->pInt->pfnPhase(pLogger, RTLOGPHASE_POSTROTATE, rtlogPhaseMsgLocked);
+        pLogger->fDestFlags = fSavedDestFlags;
+    }
+
+    /* Restore saved values. */
+    pLogger->pInt->cHistory = cSavedHistory;
+    pLogger->fFlags         = fSavedFlags;
+}
+
+#endif /* IN_RING3 */
+
+
+/**
+ * Writes the buffer to the given log device without checking for buffered
+ * data or anything.
+ * Used by the RTLogFlush() function.
+ *
+ * @param   pLogger     The logger instance to write to. NULL is not allowed!
+ */
+static void rtlogFlush(PRTLOGGER pLogger)
+{
+    uint32_t const cchScratch = pLogger->offScratch;
+    if (cchScratch == 0)
+        return; /* nothing to flush. */
+
+#ifndef IN_RC
+    /*
+     * If the ring buffer is active, the other destinations are only written
+     * to when the ring buffer is flushed by RTLogFlush().
+     */
+    if (   (pLogger->fDestFlags & RTLOGDEST_RINGBUF)
+        && pLogger->pInt
+        && pLogger->pInt->pszRingBuf /* paraoia */)
+    {
+        rtLogRingBufWrite(pLogger->pInt, pLogger->achScratch, pLogger->offScratch);
+        pLogger->offScratch = 0; /* empty the buffer. */
+    }
+    else
+#endif
+    {
+        /* Make sure the string is terminated.  On Windows, RTLogWriteDebugger
+           will get upset if it isn't. */
+        if (RT_LIKELY(cchScratch < sizeof(pLogger->achScratch)))
+            pLogger->achScratch[cchScratch] = '\0';
+        else
+            AssertFailed();
+
+#ifndef IN_RC
+        if (pLogger->fDestFlags & RTLOGDEST_USER)
+            RTLogWriteUser(pLogger->achScratch, cchScratch);
+
+        if (pLogger->fDestFlags & RTLOGDEST_DEBUGGER)
+            RTLogWriteDebugger(pLogger->achScratch, cchScratch);
+
+# ifdef IN_RING3
+        if ((pLogger->fDestFlags & (RTLOGDEST_FILE | RTLOGDEST_RINGBUF)) == RTLOGDEST_FILE)
+        {
+            if (pLogger->pInt->hFile != NIL_RTFILE)
+            {
+                RTFileWrite(pLogger->pInt->hFile, pLogger->achScratch, cchScratch, NULL);
+                if (pLogger->fFlags & RTLOGFLAGS_FLUSH)
+                    RTFileFlush(pLogger->pInt->hFile);
+            }
+            if (pLogger->pInt->cHistory)
+                pLogger->pInt->cbHistoryFileWritten += cchScratch;
+        }
+# endif
+
+        if (pLogger->fDestFlags & RTLOGDEST_STDOUT)
+            RTLogWriteStdOut(pLogger->achScratch, cchScratch);
+
+        if (pLogger->fDestFlags & RTLOGDEST_STDERR)
+            RTLogWriteStdErr(pLogger->achScratch, cchScratch);
+
+# if (defined(IN_RING0) || defined(IN_RC)) && !defined(LOG_NO_COM)
+        if (pLogger->fDestFlags & RTLOGDEST_COM)
+            RTLogWriteCom(pLogger->achScratch, cchScratch);
+# endif
+#endif /* !IN_RC */
+
+#ifdef IN_RC
+        if (pLogger->pfnFlush)
+            pLogger->pfnFlush(pLogger);
+#else
+        if (pLogger->pInt->pfnFlush)
+            pLogger->pInt->pfnFlush(pLogger);
+#endif
+
+        /* empty the buffer. */
+        pLogger->offScratch = 0;
+
+#ifdef IN_RING3
+        /*
+         * Rotate the log file if configured.  Must be done after everything is
+         * flushed, since this will also use logging/flushing to write the header
+         * and footer messages.
+         */
+        if (   (pLogger->fDestFlags & RTLOGDEST_FILE)
+            && pLogger->pInt->cHistory)
+            rtlogRotate(pLogger, RTTimeProgramSecTS() / pLogger->pInt->cSecsHistoryTimeSlot, false /* fFirst */);
+#endif
+    }
+}
+
+
+/**
+ * Callback for RTLogFormatV which writes to the com port.
+ * See PFNLOGOUTPUT() for details.
+ */
+static DECLCALLBACK(size_t) rtLogOutput(void *pv, const char *pachChars, size_t cbChars)
+{
+    PRTLOGGER pLogger = (PRTLOGGER)pv;
+    if (cbChars)
+    {
+        size_t cbRet = 0;
+        for (;;)
+        {
+#if defined(DEBUG) && defined(IN_RING3)
+            /* sanity */
+            if (pLogger->offScratch >= sizeof(pLogger->achScratch))
+            {
+                fprintf(stderr, "pLogger->offScratch >= sizeof(pLogger->achScratch) (%#x >= %#x)\n",
+                        pLogger->offScratch, (unsigned)sizeof(pLogger->achScratch));
+                AssertBreakpoint(); AssertBreakpoint();
+            }
+#endif
+
+            /* how much */
+            size_t cb = sizeof(pLogger->achScratch) - pLogger->offScratch - 1;
+            if (cb > cbChars)
+                cb = cbChars;
+
+            /* copy */
+            memcpy(&pLogger->achScratch[pLogger->offScratch], pachChars, cb);
+
+            /* advance */
+            pLogger->offScratch += (uint32_t)cb;
+            cbRet += cb;
+            cbChars -= cb;
+
+            /* done? */
+            if (cbChars <= 0)
+                return cbRet;
+
+            pachChars += cb;
+
+            /* flush */
+            rtlogFlush(pLogger);
+        }
+
+        /* won't ever get here! */
+    }
+    else
+    {
+        /*
+         * Termination call.
+         * There's always space for a terminator, and it's not counted.
+         */
+        pLogger->achScratch[pLogger->offScratch] = '\0';
+        return 0;
+    }
+}
+
+
+/**
+ * stpncpy implementation for use in rtLogOutputPrefixed w/ padding.
+ *
+ * @returns Pointer to the destination buffer byte following the copied string.
+ * @param   pszDst              The destination buffer.
+ * @param   pszSrc              The source string.
+ * @param   cchSrcMax           The maximum number of characters to copy from
+ *                              the string.
+ * @param   cchMinWidth         The minimum field with, padd with spaces to
+ *                              reach this.
+ */
+DECLINLINE(char *) rtLogStPNCpyPad(char *pszDst, const char *pszSrc, size_t cchSrcMax, size_t cchMinWidth)
+{
+    size_t cchSrc = 0;
+    if (pszSrc)
+    {
+        cchSrc = strlen(pszSrc);
+        if (cchSrc > cchSrcMax)
+            cchSrc = cchSrcMax;
+
+        memcpy(pszDst, pszSrc, cchSrc);
+        pszDst += cchSrc;
+    }
+    do
+        *pszDst++ = ' ';
+    while (cchSrc++ < cchMinWidth);
+
+    return pszDst;
+}
+
+
+
+/**
+ * Callback for RTLogFormatV which writes to the logger instance.
+ * This version supports prefixes.
+ *
+ * See PFNLOGOUTPUT() for details.
+ */
+static DECLCALLBACK(size_t) rtLogOutputPrefixed(void *pv, const char *pachChars, size_t cbChars)
+{
+    PRTLOGOUTPUTPREFIXEDARGS    pArgs = (PRTLOGOUTPUTPREFIXEDARGS)pv;
+    PRTLOGGER                   pLogger = pArgs->pLogger;
+    if (cbChars)
+    {
+        size_t cbRet = 0;
+        for (;;)
+        {
+            size_t      cb = sizeof(pLogger->achScratch) - pLogger->offScratch - 1;
+            const char *pszNewLine;
+            char       *psz;
+#ifdef IN_RC
+            bool       *pfPendingPrefix = &pLogger->fPendingPrefix;
+#else
+            bool       *pfPendingPrefix = &pLogger->pInt->fPendingPrefix;
+#endif
+
+            /*
+             * Pending prefix?
+             */
+            if (*pfPendingPrefix)
+            {
+                *pfPendingPrefix = false;
+
+#if defined(DEBUG) && defined(IN_RING3)
+                /* sanity */
+                if (pLogger->offScratch >= sizeof(pLogger->achScratch))
+                {
+                    fprintf(stderr, "pLogger->offScratch >= sizeof(pLogger->achScratch) (%#x >= %#x)\n",
+                            pLogger->offScratch, (unsigned)sizeof(pLogger->achScratch));
+                    AssertBreakpoint(); AssertBreakpoint();
+                }
+#endif
+
+                /*
+                 * Flush the buffer if there isn't enough room for the maximum prefix config.
+                 * Max is 256, add a couple of extra bytes.  See CCH_PREFIX check way below.
+                 */
+                if (cb < 256 + 16)
+                {
+                    rtlogFlush(pLogger);
+                    cb = sizeof(pLogger->achScratch) - pLogger->offScratch - 1;
+                }
+
+                /*
+                 * Write the prefixes.
+                 * psz is pointing to the current position.
+                 */
+                psz = &pLogger->achScratch[pLogger->offScratch];
+                if (pLogger->fFlags & RTLOGFLAGS_PREFIX_TS)
+                {
+                    uint64_t     u64    = RTTimeNanoTS();
+                    int          iBase  = 16;
+                    unsigned int fFlags = RTSTR_F_ZEROPAD;
+                    if (pLogger->fFlags & RTLOGFLAGS_DECIMAL_TS)
+                    {
+                        iBase = 10;
+                        fFlags = 0;
+                    }
+                    if (pLogger->fFlags & RTLOGFLAGS_REL_TS)
+                    {
+                        static volatile uint64_t s_u64LastTs;
+                        uint64_t        u64DiffTs = u64 - s_u64LastTs;
+                        s_u64LastTs = u64;
+                        /* We could have been preempted just before reading of s_u64LastTs by
+                         * another thread which wrote s_u64LastTs. In that case the difference
+                         * is negative which we simply ignore. */
+                        u64         = (int64_t)u64DiffTs < 0 ? 0 : u64DiffTs;
+                    }
+                    /* 1E15 nanoseconds = 11 days */
+                    psz += RTStrFormatNumber(psz, u64, iBase, 16, 0, fFlags);
+                    *psz++ = ' ';
+                }
+#define CCH_PREFIX_01   0 + 17
+
+                if (pLogger->fFlags & RTLOGFLAGS_PREFIX_TSC)
+                {
+#if defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86)
+                    uint64_t     u64    = ASMReadTSC();
+#else
+                    uint64_t     u64    = RTTimeNanoTS();
+#endif
+                    int          iBase  = 16;
+                    unsigned int fFlags = RTSTR_F_ZEROPAD;
+                    if (pLogger->fFlags & RTLOGFLAGS_DECIMAL_TS)
+                    {
+                        iBase = 10;
+                        fFlags = 0;
+                    }
+                    if (pLogger->fFlags & RTLOGFLAGS_REL_TS)
+                    {
+                        static volatile uint64_t s_u64LastTsc;
+                        int64_t        i64DiffTsc = u64 - s_u64LastTsc;
+                        s_u64LastTsc = u64;
+                        /* We could have been preempted just before reading of s_u64LastTsc by
+                         * another thread which wrote s_u64LastTsc. In that case the difference
+                         * is negative which we simply ignore. */
+                        u64          = i64DiffTsc < 0 ? 0 : i64DiffTsc;
+                    }
+                    /* 1E15 ticks at 4GHz = 69 hours */
+                    psz += RTStrFormatNumber(psz, u64, iBase, 16, 0, fFlags);
+                    *psz++ = ' ';
+                }
+#define CCH_PREFIX_02   CCH_PREFIX_01 + 17
+
+                if (pLogger->fFlags & RTLOGFLAGS_PREFIX_MS_PROG)
+                {
+#if defined(IN_RING3) || defined(IN_RC)
+                    uint64_t u64 = RTTimeProgramMilliTS();
+#else
+                    uint64_t u64 = 0;
+#endif
+                    /* 1E8 milliseconds = 27 hours */
+                    psz += RTStrFormatNumber(psz, u64, 10, 9, 0, RTSTR_F_ZEROPAD);
+                    *psz++ = ' ';
+                }
+#define CCH_PREFIX_03   CCH_PREFIX_02 + 21
+
+                if (pLogger->fFlags & RTLOGFLAGS_PREFIX_TIME)
+                {
+#if defined(IN_RING3) || defined(IN_RING0)
+                    RTTIMESPEC TimeSpec;
+                    RTTIME Time;
+                    RTTimeExplode(&Time, RTTimeNow(&TimeSpec));
+                    psz += RTStrFormatNumber(psz, Time.u8Hour, 10, 2, 0, RTSTR_F_ZEROPAD);
+                    *psz++ = ':';
+                    psz += RTStrFormatNumber(psz, Time.u8Minute, 10, 2, 0, RTSTR_F_ZEROPAD);
+                    *psz++ = ':';
+                    psz += RTStrFormatNumber(psz, Time.u8Second, 10, 2, 0, RTSTR_F_ZEROPAD);
+                    *psz++ = '.';
+                    psz += RTStrFormatNumber(psz, Time.u32Nanosecond / 1000, 10, 6, 0, RTSTR_F_ZEROPAD);
+                    *psz++ = ' ';
+#else
+                    memset(psz, ' ', 16);
+                    psz += 16;
+#endif
+                }
+#define CCH_PREFIX_04   CCH_PREFIX_03 + (3+1+3+1+3+1+7+1)
+
+                if (pLogger->fFlags & RTLOGFLAGS_PREFIX_TIME_PROG)
+                {
+
+#if defined(IN_RING3) || defined(IN_RC)
+                    uint64_t u64 = RTTimeProgramMicroTS();
+                    psz += RTStrFormatNumber(psz, (uint32_t)(u64 / RT_US_1HOUR), 10, 2, 0, RTSTR_F_ZEROPAD);
+                    *psz++ = ':';
+                    uint32_t u32 = (uint32_t)(u64 % RT_US_1HOUR);
+                    psz += RTStrFormatNumber(psz, u32 / RT_US_1MIN, 10, 2, 0, RTSTR_F_ZEROPAD);
+                    *psz++ = ':';
+                    u32 %= RT_US_1MIN;
+
+                    psz += RTStrFormatNumber(psz, u32 / RT_US_1SEC, 10, 2, 0, RTSTR_F_ZEROPAD);
+                    *psz++ = '.';
+                    psz += RTStrFormatNumber(psz, u32 % RT_US_1SEC, 10, 6, 0, RTSTR_F_ZEROPAD);
+                    *psz++ = ' ';
+#else
+                    memset(psz, ' ', 16);
+                    psz += 16;
+#endif
+                }
+#define CCH_PREFIX_05   CCH_PREFIX_04 + (9+1+2+1+2+1+6+1)
+
+# if 0
+                if (pLogger->fFlags & RTLOGFLAGS_PREFIX_DATETIME)
+                {
+                    char szDate[32];
+                    RTTIMESPEC Time;
+                    RTTimeSpecToString(RTTimeNow(&Time), szDate, sizeof(szDate));
+                    size_t cch = strlen(szDate);
+                    memcpy(psz, szDate, cch);
+                    psz += cch;
+                    *psz++ = ' ';
+                }
+#  define CCH_PREFIX_06   CCH_PREFIX_05 + 32
+# else
+#  define CCH_PREFIX_06   CCH_PREFIX_05 + 0
+# endif
+
+                if (pLogger->fFlags & RTLOGFLAGS_PREFIX_PID)
+                {
+#ifndef IN_RC
+                    RTPROCESS Process = RTProcSelf();
+#else
+                    RTPROCESS Process = NIL_RTPROCESS;
+#endif
+                    psz += RTStrFormatNumber(psz, Process, 16, sizeof(RTPROCESS) * 2, 0, RTSTR_F_ZEROPAD);
+                    *psz++ = ' ';
+                }
+#define CCH_PREFIX_07   CCH_PREFIX_06 + 9
+
+                if (pLogger->fFlags & RTLOGFLAGS_PREFIX_TID)
+                {
+#ifndef IN_RC
+                    RTNATIVETHREAD Thread = RTThreadNativeSelf();
+#else
+                    RTNATIVETHREAD Thread = NIL_RTNATIVETHREAD;
+#endif
+                    psz += RTStrFormatNumber(psz, Thread, 16, sizeof(RTNATIVETHREAD) * 2, 0, RTSTR_F_ZEROPAD);
+                    *psz++ = ' ';
+                }
+#define CCH_PREFIX_08   CCH_PREFIX_07 + 17
+
+                if (pLogger->fFlags & RTLOGFLAGS_PREFIX_THREAD)
+                {
+#ifdef IN_RING3
+                    const char *pszName = RTThreadSelfName();
+#elif defined IN_RC
+                    const char *pszName = "EMT-RC";
+#else
+                    const char *pszName = "R0";
+#endif
+                    psz = rtLogStPNCpyPad(psz, pszName, 16, 8);
+                }
+#define CCH_PREFIX_09   CCH_PREFIX_08 + 17
+
+                if (pLogger->fFlags & RTLOGFLAGS_PREFIX_CPUID)
+                {
+#if defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86)
+                    const uint8_t idCpu = ASMGetApicId();
+#else
+                    const RTCPUID idCpu = RTMpCpuId();
+#endif
+                    psz += RTStrFormatNumber(psz, idCpu, 16, sizeof(idCpu) * 2, 0, RTSTR_F_ZEROPAD);
+                    *psz++ = ' ';
+                }
+#define CCH_PREFIX_10   CCH_PREFIX_09 + 17
+
+#ifndef IN_RC
+                if (    (pLogger->fFlags & RTLOGFLAGS_PREFIX_CUSTOM)
+                    &&  pLogger->pInt->pfnPrefix)
+                {
+                    psz += pLogger->pInt->pfnPrefix(pLogger, psz, 31, pLogger->pInt->pvPrefixUserArg);
+                    *psz++ = ' ';                                                               /* +32 */
+                }
+#endif
+#define CCH_PREFIX_11   CCH_PREFIX_10 + 32
+
+                if (pLogger->fFlags & RTLOGFLAGS_PREFIX_LOCK_COUNTS)
+                {
+#ifdef IN_RING3 /** @todo implement these counters in ring-0 too? */
+                    RTTHREAD Thread = RTThreadSelf();
+                    if (Thread != NIL_RTTHREAD)
+                    {
+                        uint32_t cReadLocks  = RTLockValidatorReadLockGetCount(Thread);
+                        uint32_t cWriteLocks = RTLockValidatorWriteLockGetCount(Thread) - g_cLoggerLockCount;
+                        cReadLocks  = RT_MIN(0xfff, cReadLocks);
+                        cWriteLocks = RT_MIN(0xfff, cWriteLocks);
+                        psz += RTStrFormatNumber(psz, cReadLocks,  16, 1, 0, RTSTR_F_ZEROPAD);
+                        *psz++ = '/';
+                        psz += RTStrFormatNumber(psz, cWriteLocks, 16, 1, 0, RTSTR_F_ZEROPAD);
+                    }
+                    else
+#endif
+                    {
+                        *psz++ = '?';
+                        *psz++ = '/';
+                        *psz++ = '?';
+                    }
+                    *psz++ = ' ';
+                }
+#define CCH_PREFIX_12   CCH_PREFIX_11 + 8
+
+                if (pLogger->fFlags & RTLOGFLAGS_PREFIX_FLAG_NO)
+                {
+                    psz += RTStrFormatNumber(psz, pArgs->fFlags, 16, 8, 0, RTSTR_F_ZEROPAD);
+                    *psz++ = ' ';
+                }
+#define CCH_PREFIX_13   CCH_PREFIX_12 + 9
+
+                if (pLogger->fFlags & RTLOGFLAGS_PREFIX_FLAG)
+                {
+#ifdef IN_RING3
+                    const char *pszGroup = pArgs->iGroup != ~0U ? pLogger->pInt->papszGroups[pArgs->iGroup] : NULL;
+#else
+                    const char *pszGroup = NULL;
+#endif
+                    psz = rtLogStPNCpyPad(psz, pszGroup, 16, 8);
+                }
+#define CCH_PREFIX_14   CCH_PREFIX_13 + 17
+
+                if (pLogger->fFlags & RTLOGFLAGS_PREFIX_GROUP_NO)
+                {
+                    if (pArgs->iGroup != ~0U)
+                    {
+                        psz += RTStrFormatNumber(psz, pArgs->iGroup, 16, 3, 0, RTSTR_F_ZEROPAD);
+                        *psz++ = ' ';
+                    }
+                    else
+                    {
+                        memcpy(psz, "-1  ", sizeof("-1  ") - 1);
+                        psz += sizeof("-1  ") - 1;
+                    }                                                                           /* +9 */
+                }
+#define CCH_PREFIX_15   CCH_PREFIX_14 + 9
+
+                if (pLogger->fFlags & RTLOGFLAGS_PREFIX_GROUP)
+                {
+                    const unsigned fGrp = pLogger->afGroups[pArgs->iGroup != ~0U ? pArgs->iGroup : 0];
+                    const char *pszGroup;
+                    size_t cch;
+                    switch (pArgs->fFlags & fGrp)
+                    {
+                        case 0:                         pszGroup = "--------";  cch = sizeof("--------") - 1; break;
+                        case RTLOGGRPFLAGS_ENABLED:     pszGroup = "enabled" ;  cch = sizeof("enabled" ) - 1; break;
+                        case RTLOGGRPFLAGS_LEVEL_1:     pszGroup = "level 1" ;  cch = sizeof("level 1" ) - 1; break;
+                        case RTLOGGRPFLAGS_LEVEL_2:     pszGroup = "level 2" ;  cch = sizeof("level 2" ) - 1; break;
+                        case RTLOGGRPFLAGS_LEVEL_3:     pszGroup = "level 3" ;  cch = sizeof("level 3" ) - 1; break;
+                        case RTLOGGRPFLAGS_LEVEL_4:     pszGroup = "level 4" ;  cch = sizeof("level 4" ) - 1; break;
+                        case RTLOGGRPFLAGS_LEVEL_5:     pszGroup = "level 5" ;  cch = sizeof("level 5" ) - 1; break;
+                        case RTLOGGRPFLAGS_LEVEL_6:     pszGroup = "level 6" ;  cch = sizeof("level 6" ) - 1; break;
+                        case RTLOGGRPFLAGS_LEVEL_7:     pszGroup = "level 7" ;  cch = sizeof("level 7" ) - 1; break;
+                        case RTLOGGRPFLAGS_LEVEL_8:     pszGroup = "level 8" ;  cch = sizeof("level 8" ) - 1; break;
+                        case RTLOGGRPFLAGS_LEVEL_9:     pszGroup = "level 9" ;  cch = sizeof("level 9" ) - 1; break;
+                        case RTLOGGRPFLAGS_LEVEL_10:    pszGroup = "level 10";  cch = sizeof("level 10") - 1; break;
+                        case RTLOGGRPFLAGS_LEVEL_11:    pszGroup = "level 11";  cch = sizeof("level 11") - 1; break;
+                        case RTLOGGRPFLAGS_LEVEL_12:    pszGroup = "level 12";  cch = sizeof("level 12") - 1; break;
+                        case RTLOGGRPFLAGS_FLOW:        pszGroup = "flow"    ;  cch = sizeof("flow"    ) - 1; break;
+                        case RTLOGGRPFLAGS_WARN:        pszGroup = "warn"    ;  cch = sizeof("warn"    ) - 1; break;
+                        default:                        pszGroup = "????????";  cch = sizeof("????????") - 1; break;
+                    }
+                    psz = rtLogStPNCpyPad(psz, pszGroup, 16, 8);
+                }
+#define CCH_PREFIX_16   CCH_PREFIX_15 + 17
+
+#define CCH_PREFIX      ( CCH_PREFIX_16 )
+                { AssertCompile(CCH_PREFIX < 256); }
+
+                /*
+                 * Done, figure what we've used and advance the buffer and free size.
+                 */
+                cb = psz - &pLogger->achScratch[pLogger->offScratch];
+                AssertMsg(cb <= 223, ("%#zx (%zd) - fFlags=%#x\n", cb, cb, pLogger->fFlags));
+                pLogger->offScratch += (uint32_t)cb;
+                cb = sizeof(pLogger->achScratch) - pLogger->offScratch - 1;
+            }
+            else if (cb <= 0)
+            {
+                rtlogFlush(pLogger);
+                cb = sizeof(pLogger->achScratch) - pLogger->offScratch - 1;
+            }
+
+#if defined(DEBUG) && defined(IN_RING3)
+            /* sanity */
+            if (pLogger->offScratch >= sizeof(pLogger->achScratch))
+            {
+                fprintf(stderr, "pLogger->offScratch >= sizeof(pLogger->achScratch) (%#x >= %#x)\n",
+                        pLogger->offScratch, (unsigned)sizeof(pLogger->achScratch));
+                AssertBreakpoint(); AssertBreakpoint();
+            }
+#endif
+
+            /* how much */
+            if (cb > cbChars)
+                cb = cbChars;
+
+            /* have newline? */
+            pszNewLine = (const char *)memchr(pachChars, '\n', cb);
+            if (pszNewLine)
+            {
+                if (pLogger->fFlags & RTLOGFLAGS_USECRLF)
+                    cb = pszNewLine - pachChars;
+                else
+                {
+                    cb = pszNewLine - pachChars + 1;
+                    *pfPendingPrefix = true;
+                }
+            }
+
+            /* copy */
+            memcpy(&pLogger->achScratch[pLogger->offScratch], pachChars, cb);
+
+            /* advance */
+            pLogger->offScratch += (uint32_t)cb;
+            cbRet += cb;
+            cbChars -= cb;
+
+            if (    pszNewLine
+                &&  (pLogger->fFlags & RTLOGFLAGS_USECRLF)
+                &&  pLogger->offScratch + 2 < sizeof(pLogger->achScratch))
+            {
+                memcpy(&pLogger->achScratch[pLogger->offScratch], "\r\n", 2);
+                pLogger->offScratch += 2;
+                cbRet++;
+                cbChars--;
+                cb++;
+                *pfPendingPrefix = true;
+            }
+
+            /* done? */
+            if (cbChars <= 0)
+                return cbRet;
+            pachChars += cb;
+        }
+
+        /* won't ever get here! */
+    }
+    else
+    {
+        /*
+         * Termination call.
+         * There's always space for a terminator, and it's not counted.
+         */
+        pLogger->achScratch[pLogger->offScratch] = '\0';
+        return 0;
+    }
+}
+
+
+/**
+ * Write to a logger instance (worker function).
+ *
+ * This function will check whether the instance, group and flags makes up a
+ * logging kind which is currently enabled before writing anything to the log.
+ *
+ * @param   pLogger     Pointer to logger instance. Must be non-NULL.
+ * @param   fFlags      The logging flags.
+ * @param   iGroup      The group.
+ *                      The value ~0U is reserved for compatibility with RTLogLogger[V] and is
+ *                      only for internal usage!
+ * @param   pszFormat   Format string.
+ * @param   args        Format arguments.
+ */
+static void rtlogLoggerExVLocked(PRTLOGGER pLogger, unsigned fFlags, unsigned iGroup, const char *pszFormat, va_list args)
+{
+    /*
+     * Format the message and perhaps flush it.
+     */
+    if (pLogger->fFlags & (RTLOGFLAGS_PREFIX_MASK | RTLOGFLAGS_USECRLF))
+    {
+        RTLOGOUTPUTPREFIXEDARGS OutputArgs;
+        OutputArgs.pLogger = pLogger;
+        OutputArgs.iGroup  = iGroup;
+        OutputArgs.fFlags  = fFlags;
+        RTLogFormatV(rtLogOutputPrefixed, &OutputArgs, pszFormat, args);
+    }
+    else
+        RTLogFormatV(rtLogOutput, pLogger, pszFormat, args);
+    if (    !(pLogger->fFlags & RTLOGFLAGS_BUFFERED)
+        &&  pLogger->offScratch)
+        rtlogFlush(pLogger);
+}
+
+
+#ifndef IN_RC
+/**
+ * For calling rtlogLoggerExVLocked.
+ *
+ * @param   pLogger     The logger.
+ * @param   fFlags      The logging flags.
+ * @param   iGroup      The group.
+ *                      The value ~0U is reserved for compatibility with RTLogLogger[V] and is
+ *                      only for internal usage!
+ * @param   pszFormat   Format string.
+ * @param   ...         Format arguments.
+ */
+static void rtlogLoggerExFLocked(PRTLOGGER pLogger, unsigned fFlags, unsigned iGroup, const char *pszFormat, ...)
+{
+    va_list va;
+    va_start(va, pszFormat);
+    rtlogLoggerExVLocked(pLogger, fFlags, iGroup, pszFormat, va);
+    va_end(va);
+}
+#endif /* !IN_RC */
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/vboxguest/common/log/logcom.c
@@ -0,0 +1,146 @@
+/* $Id: logcom.cpp $ */
+/** @file
+ * IPRT - Logging to Serial Port.
+ */
+
+/*
+ * Copyright (C) 2006-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+
+/*********************************************************************************************************************************
+*   Defined Constants And Macros                                                                                                 *
+*********************************************************************************************************************************/
+#ifndef IPRT_UART_BASE
+/** The port address of the COM port to log to.
+ *
+ * To override the default (COM1) append IPRT_UART_BASE=0xWXYZ to DEFS in your
+ * LocalConfig.kmk. Alternatively you can edit this file, but the don't forget
+ * to also update the default found in VBox/asmdefs.h.
+ *
+ * Standard port assignments are: COM1=0x3f8, COM2=0x2f8, COM3=0x3e8, COM4=0x2e8.
+ */
+# define IPRT_UART_BASE 0x3f8
+#endif
+
+
+/*********************************************************************************************************************************
+*   Header Files                                                                                                                 *
+*********************************************************************************************************************************/
+#include <iprt/log.h>
+#include "internal/iprt.h"
+
+#include <iprt/asm.h>
+#if defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86) /** @todo consider fixing the config instead. */
+# include <iprt/asm-amd64-x86.h>
+#endif
+#include <iprt/stdarg.h>
+#include <iprt/string.h>
+
+
+/*********************************************************************************************************************************
+*   Internal Functions                                                                                                           *
+*********************************************************************************************************************************/
+static DECLCALLBACK(size_t) rtLogComOutput(void *pv, const char *pachChars, size_t cbChars);
+
+
+/**
+ * Prints a formatted string to the serial port used for logging.
+ *
+ * @returns Number of bytes written.
+ * @param   pszFormat   Format string.
+ * @param   ...         Optional arguments specified in the format string.
+ */
+RTDECL(size_t) RTLogComPrintf(const char *pszFormat, ...)
+{
+    va_list     args;
+    size_t      cb;
+    va_start(args, pszFormat);
+    cb = RTLogComPrintfV(pszFormat, args);
+    va_end(args);
+
+    return cb;
+}
+RT_EXPORT_SYMBOL(RTLogComPrintf);
+
+
+/**
+ * Prints a formatted string to the serial port used for logging.
+ *
+ * @returns Number of bytes written.
+ * @param   pszFormat   Format string.
+ * @param   args        Optional arguments specified in the format string.
+ */
+RTDECL(size_t) RTLogComPrintfV(const char *pszFormat, va_list args)
+{
+    return RTLogFormatV(rtLogComOutput, NULL, pszFormat, args);
+}
+RT_EXPORT_SYMBOL(RTLogComPrintfV);
+
+
+/**
+ * Callback for RTLogFormatV which writes to the com port.
+ * See PFNLOGOUTPUT() for details.
+ */
+static DECLCALLBACK(size_t) rtLogComOutput(void *pv, const char *pachChars, size_t cbChars)
+{
+    NOREF(pv);
+    if (cbChars)
+        RTLogWriteCom(pachChars, cbChars);
+    return cbChars;
+}
+
+
+/**
+ * Write log buffer to COM port.
+ *
+ * @param   pach        Pointer to the buffer to write.
+ * @param   cb          Number of bytes to write.
+ */
+RTDECL(void) RTLogWriteCom(const char *pach, size_t cb)
+{
+#if defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86)
+    const uint8_t *pu8;
+    for (pu8 = (const uint8_t *)pach; cb-- > 0; pu8++)
+    {
+        register unsigned cMaxWait;
+        register uint8_t  u8;
+
+        /* expand \n -> \r\n */
+        if (*pu8 == '\n')
+            RTLogWriteCom("\r", 1);
+
+        /* Check if port is ready. */
+        cMaxWait = ~0U;
+        do
+        {
+            u8 = ASMInU8(IPRT_UART_BASE + 5);
+            cMaxWait--;
+        } while (!(u8 & 0x20) && u8 != 0xff && cMaxWait);
+
+        /* write */
+        ASMOutU8(IPRT_UART_BASE, *pu8);
+    }
+#else
+    /* PORTME? */
+#endif
+}
+RT_EXPORT_SYMBOL(RTLogWriteCom);
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/vboxguest/common/log/logellipsis.c
@@ -0,0 +1,105 @@
+/* $Id: logellipsis.cpp $ */
+/** @file
+ * Runtime VBox - Logger, the ellipsis variants.
+ */
+
+/*
+ * Copyright (C) 2006-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+
+/*********************************************************************************************************************************
+*   Header Files                                                                                                                 *
+*********************************************************************************************************************************/
+#include <iprt/log.h>
+#include "internal/iprt.h"
+
+#include <iprt/asm.h>
+#include <iprt/stdarg.h>
+
+
+/**
+ * Write to a logger instance.
+ *
+ * @param   pLogger     Pointer to logger instance.
+ * @param   pvCallerRet Ignored.
+ * @param   pszFormat   Format string.
+ * @param   ...         Format arguments.
+ */
+RTDECL(void) RTLogLogger(PRTLOGGER pLogger, void *pvCallerRet, const char *pszFormat, ...)
+{
+    va_list args;
+    va_start(args, pszFormat);
+#if defined(RT_OS_DARWIN) && defined(RT_ARCH_X86) && defined(IN_RING3)
+    /* manually align the stack before doing the call.
+     * We boldly assume that there is a stack frame here! */
+    __asm__ __volatile__("andl $-32, %%esp\t\n" ::: "%esp");
+    RTLogLoggerExV(pLogger, 0, ~0U, pszFormat, args);
+#else
+    RTLogLoggerExV(pLogger, 0, ~0U, pszFormat, args);
+#endif
+    va_end(args);
+    NOREF(pvCallerRet);
+}
+RT_EXPORT_SYMBOL(RTLogLogger);
+
+
+/**
+ * Write to a logger instance.
+ *
+ * This function will check whether the instance, group and flags makes up a
+ * logging kind which is currently enabled before writing anything to the log.
+ *
+ * @param   pLogger     Pointer to logger instance. If NULL the default logger instance will be attempted.
+ * @param   fFlags      The logging flags.
+ * @param   iGroup      The group.
+ *                      The value ~0U is reserved for compatibility with RTLogLogger[V] and is
+ *                      only for internal usage!
+ * @param   pszFormat   Format string.
+ * @param   ...         Format arguments.
+ * @remark  This is a worker function of LogIt.
+ */
+RTDECL(void) RTLogLoggerEx(PRTLOGGER pLogger, unsigned fFlags, unsigned iGroup, const char *pszFormat, ...)
+{
+    va_list args;
+    va_start(args, pszFormat);
+    RTLogLoggerExV(pLogger, fFlags, iGroup, pszFormat, args);
+    va_end(args);
+}
+RT_EXPORT_SYMBOL(RTLogLoggerEx);
+
+
+/**
+ * printf like function for writing to the default log.
+ *
+ * @param   pszFormat   Printf like format string.
+ * @param   ...         Optional arguments as specified in pszFormat.
+ *
+ * @remark The API doesn't support formatting of floating point numbers at the moment.
+ */
+RTDECL(void) RTLogPrintf(const char *pszFormat, ...)
+{
+    va_list args;
+    va_start(args, pszFormat);
+    RTLogPrintfV(pszFormat, args);
+    va_end(args);
+}
+RT_EXPORT_SYMBOL(RTLogPrintf);
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/vboxguest/common/log/logformat.c
@@ -0,0 +1,100 @@
+/* $Id: logformat.cpp $ */
+/** @file
+ * IPRT - Log Formatter.
+ */
+
+/*
+ * Copyright (C) 2006-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+
+/*********************************************************************************************************************************
+*   Header Files                                                                                                                 *
+*********************************************************************************************************************************/
+#include <iprt/log.h>
+#include "internal/iprt.h"
+
+#include <iprt/string.h>
+#include <iprt/assert.h>
+#ifdef IN_RING3
+# include <iprt/thread.h>
+# include <iprt/err.h>
+#endif
+
+#include <iprt/stdarg.h>
+#include <iprt/string.h>
+
+
+/*********************************************************************************************************************************
+*   Internal Functions                                                                                                           *
+*********************************************************************************************************************************/
+static DECLCALLBACK(size_t) rtlogFormatStr(void *pvArg, PFNRTSTROUTPUT pfnOutput,
+                                           void *pvArgOutput, const char **ppszFormat,
+                                           va_list *pArgs, int cchWidth, int cchPrecision,
+                                           unsigned fFlags, char chArgSize);
+
+
+/**
+ * Partial vsprintf worker implementation.
+ *
+ * @returns number of bytes formatted.
+ * @param   pfnOutput   Output worker.
+ *                      Called in two ways. Normally with a string an it's length.
+ *                      For termination, it's called with NULL for string, 0 for length.
+ * @param   pvArg       Argument to output worker.
+ * @param   pszFormat   Format string.
+ * @param   args        Argument list.
+ */
+RTDECL(size_t) RTLogFormatV(PFNRTSTROUTPUT pfnOutput, void *pvArg, const char *pszFormat, va_list args)
+{
+    return RTStrFormatV(pfnOutput, pvArg, rtlogFormatStr, NULL, pszFormat, args);
+}
+RT_EXPORT_SYMBOL(RTLogFormatV);
+
+
+/**
+ * Callback to format VBox formatting extentions.
+ * See @ref pg_rt_str_format for a reference on the format types.
+ *
+ * @returns The number of bytes formatted.
+ * @param   pvArg           Formatter argument.
+ * @param   pfnOutput       Pointer to output function.
+ * @param   pvArgOutput     Argument for the output function.
+ * @param   ppszFormat      Pointer to the format string pointer. Advance this till the char
+ *                          after the format specifier.
+ * @param   pArgs           Pointer to the argument list. Use this to fetch the arguments.
+ * @param   cchWidth        Format Width. -1 if not specified.
+ * @param   cchPrecision    Format Precision. -1 if not specified.
+ * @param   fFlags          Flags (RTSTR_NTFS_*).
+ * @param   chArgSize       The argument size specifier, 'l' or 'L'.
+ */
+static DECLCALLBACK(size_t) rtlogFormatStr(void *pvArg, PFNRTSTROUTPUT pfnOutput, void *pvArgOutput,
+                                           const char **ppszFormat, va_list *pArgs, int cchWidth,
+                                           int cchPrecision, unsigned fFlags, char chArgSize)
+{
+    char ch = *(*ppszFormat)++;
+
+    AssertMsgFailed(("Invalid logger format type '%%%c%.10s'!\n", ch, *ppszFormat)); NOREF(ch);
+
+    NOREF(pvArg); NOREF(pfnOutput); NOREF(pvArgOutput); NOREF(pArgs); NOREF(cchWidth);
+    NOREF(cchPrecision); NOREF(fFlags); NOREF(chArgSize);
+    return 0;
+}
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/vboxguest/common/log/logrel.c
@@ -0,0 +1,185 @@
+/* $Id: logrel.cpp $ */
+/** @file
+ * Runtime VBox - Release Logger.
+ */
+
+/*
+ * Copyright (C) 2006-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+
+/*********************************************************************************************************************************
+*   Header Files                                                                                                                 *
+*********************************************************************************************************************************/
+#include <iprt/log.h>
+#include "internal/iprt.h"
+
+#ifndef IN_RC
+# include <iprt/alloc.h>
+# include <iprt/process.h>
+# include <iprt/semaphore.h>
+# include <iprt/thread.h>
+# include <iprt/mp.h>
+#endif
+#ifdef IN_RING3
+# include <iprt/file.h>
+# include <iprt/path.h>
+#endif
+#include <iprt/time.h>
+#include <iprt/asm.h>
+#include <iprt/assert.h>
+#include <iprt/err.h>
+#include <iprt/param.h>
+
+#include <iprt/stdarg.h>
+#include <iprt/string.h>
+#include <iprt/ctype.h>
+#ifdef IN_RING3
+# include <iprt/alloca.h>
+# include <stdio.h>
+#endif
+
+
+/*********************************************************************************************************************************
+*   Global Variables                                                                                                             *
+*********************************************************************************************************************************/
+#ifdef IN_RC
+/** Default release logger instance. */
+extern "C" DECLIMPORT(RTLOGGERRC)   g_RelLogger;
+#else /* !IN_RC */
+/** Default release logger instance. */
+static PRTLOGGER                    g_pRelLogger;
+#endif /* !IN_RC */
+
+
+RTDECL(PRTLOGGER)   RTLogRelGetDefaultInstance(void)
+{
+#ifdef IN_RC
+    return &g_RelLogger;
+#else /* !IN_RC */
+    return g_pRelLogger;
+#endif /* !IN_RC */
+}
+RT_EXPORT_SYMBOL(RTLogRelGetDefaultInstance);
+
+
+RTDECL(PRTLOGGER)   RTLogRelGetDefaultInstanceEx(uint32_t fFlagsAndGroup)
+{
+#ifdef IN_RC
+    PRTLOGGER pLogger = &g_RelLogger;
+#else /* !IN_RC */
+    PRTLOGGER pLogger = g_pRelLogger;
+#endif /* !IN_RC */
+    if (pLogger)
+    {
+        if (pLogger->fFlags & RTLOGFLAGS_DISABLED)
+            pLogger = NULL;
+        else
+        {
+            uint16_t const fFlags = RT_LO_U16(fFlagsAndGroup);
+            uint16_t const iGroup = RT_HI_U16(fFlagsAndGroup);
+            if (   iGroup != UINT16_MAX
+                 && (   (pLogger->afGroups[iGroup < pLogger->cGroups ? iGroup : 0] & (fFlags | RTLOGGRPFLAGS_ENABLED))
+                     != (fFlags | RTLOGGRPFLAGS_ENABLED)))
+            pLogger = NULL;
+        }
+    }
+    return pLogger;
+}
+RT_EXPORT_SYMBOL(RTLogRelGetDefaultInstanceEx);
+
+
+#ifndef IN_RC
+/**
+ * Sets the default logger instance.
+ *
+ * @returns iprt status code.
+ * @param   pLogger     The new default release logger instance.
+ */
+RTDECL(PRTLOGGER) RTLogRelSetDefaultInstance(PRTLOGGER pLogger)
+{
+    return ASMAtomicXchgPtrT(&g_pRelLogger, pLogger, PRTLOGGER);
+}
+RT_EXPORT_SYMBOL(RTLogRelSetDefaultInstance);
+#endif /* !IN_RC */
+
+
+/**
+ * Write to a logger instance, defaulting to the release one.
+ *
+ * This function will check whether the instance, group and flags makes up a
+ * logging kind which is currently enabled before writing anything to the log.
+ *
+ * @param   pLogger     Pointer to logger instance. If NULL the default release instance is attempted.
+ * @param   fFlags      The logging flags.
+ * @param   iGroup      The group.
+ *                      The value ~0U is reserved for compatibility with RTLogLogger[V] and is
+ *                      only for internal usage!
+ * @param   pszFormat   Format string.
+ * @param   args        Format arguments.
+ */
+RTDECL(void) RTLogRelLoggerV(PRTLOGGER pLogger, unsigned fFlags, unsigned iGroup, const char *pszFormat, va_list args)
+{
+    /*
+     * A NULL logger means default instance.
+     */
+    if (!pLogger)
+    {
+        pLogger = RTLogRelGetDefaultInstance();
+        if (!pLogger)
+            return;
+    }
+    RTLogLoggerExV(pLogger, fFlags, iGroup, pszFormat, args);
+}
+RT_EXPORT_SYMBOL(RTLogRelLoggerV);
+
+
+/**
+ * vprintf like function for writing to the default release log.
+ *
+ * @param   pszFormat   Printf like format string.
+ * @param   args        Optional arguments as specified in pszFormat.
+ *
+ * @remark The API doesn't support formatting of floating point numbers at the moment.
+ */
+RTDECL(void) RTLogRelPrintfV(const char *pszFormat, va_list args)
+{
+    RTLogRelLoggerV(NULL, 0, ~0U, pszFormat, args);
+}
+RT_EXPORT_SYMBOL(RTLogRelPrintfV);
+
+
+/**
+ * Changes the buffering setting of the default release logger.
+ *
+ * This can be used for optimizing longish logging sequences.
+ *
+ * @returns The old state.
+ * @param   fBuffered       The new state.
+ */
+RTDECL(bool) RTLogRelSetBuffering(bool fBuffered)
+{
+    PRTLOGGER pLogger = RTLogRelGetDefaultInstance();
+    if (pLogger)
+        return RTLogSetBuffering(pLogger, fBuffered);
+    return false;
+}
+RT_EXPORT_SYMBOL(RTLogRelSetBuffering);
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/vboxguest/common/log/logrelellipsis.c
@@ -0,0 +1,78 @@
+/* $Id: logrelellipsis.cpp $ */
+/** @file
+ * Runtime VBox - Logger, the release ellipsis variants.
+ */
+
+/*
+ * Copyright (C) 2006-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+
+/*********************************************************************************************************************************
+*   Header Files                                                                                                                 *
+*********************************************************************************************************************************/
+#include <iprt/log.h>
+#include "internal/iprt.h"
+
+#include <iprt/stdarg.h>
+
+
+/**
+ * Write to a logger instance, defaulting to the release one.
+ *
+ * This function will check whether the instance, group and flags makes up a
+ * logging kind which is currently enabled before writing anything to the log.
+ *
+ * @param   pLogger     Pointer to logger instance.
+ * @param   fFlags      The logging flags.
+ * @param   iGroup      The group.
+ *                      The value ~0U is reserved for compatibility with RTLogLogger[V] and is
+ *                      only for internal usage!
+ * @param   pszFormat   Format string.
+ * @param   ...         Format arguments.
+ * @remark  This is a worker function for LogRelIt.
+ */
+RTDECL(void) RTLogRelLogger(PRTLOGGER pLogger, unsigned fFlags, unsigned iGroup, const char *pszFormat, ...)
+{
+    va_list args;
+    va_start(args, pszFormat);
+    RTLogRelLoggerV(pLogger, fFlags, iGroup, pszFormat, args);
+    va_end(args);
+}
+RT_EXPORT_SYMBOL(RTLogRelLogger);
+
+
+/**
+ * printf like function for writing to the default release log.
+ *
+ * @param   pszFormat   Printf like format string.
+ * @param   ...         Optional arguments as specified in pszFormat.
+ *
+ * @remark The API doesn't support formatting of floating point numbers at the moment.
+ */
+RTDECL(void) RTLogRelPrintf(const char *pszFormat, ...)
+{
+    va_list args;
+    va_start(args, pszFormat);
+    RTLogRelPrintfV(pszFormat, args);
+    va_end(args);
+}
+RT_EXPORT_SYMBOL(RTLogRelPrintf);
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/vboxguest/common/math/gcc/divdi3.c
@@ -0,0 +1,70 @@
+/*	$NetBSD: divdi3.c,v 1.8 2005/12/11 12:24:37 christos Exp $	*/
+
+/*-
+ * Copyright (c) 1992, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * This software was developed by the Computer Systems Engineering group
+ * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
+ * contributed to Berkeley.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*#include <sys/cdefs.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+static char sccsid[] = "@(#)divdi3.c	8.1 (Berkeley) 6/4/93";
+#else
+__RCSID("$NetBSD: divdi3.c,v 1.8 2005/12/11 12:24:37 christos Exp $");
+#endif
+#endif*/ /* LIBC_SCCS and not lint */
+
+#include "quad.h"
+
+/*
+ * Divide two signed quads.
+ * ??? if -1/2 should produce -1 on this machine, this code is wrong
+ */
+quad_t
+__divdi3(a, b)
+	quad_t a, b;
+{
+	u_quad_t ua, ub, uq;
+	int neg = 0;
+
+	ua = a;
+	ub = b;
+
+	if (a < 0)
+		ua = -ua, neg ^= 1;
+	if (b < 0)
+		ub = -ub, neg ^= 1;
+
+	uq = __qdivrem(ua, ub, (u_quad_t *)0);
+	if (neg)
+		uq = - uq;
+	return uq;
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/vboxguest/common/math/gcc/moddi3.c
@@ -0,0 +1,70 @@
+/*	$NetBSD: moddi3.c,v 1.8 2005/12/11 12:24:37 christos Exp $	*/
+
+/*-
+ * Copyright (c) 1992, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * This software was developed by the Computer Systems Engineering group
+ * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
+ * contributed to Berkeley.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*#include <sys/cdefs.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+static char sccsid[] = "@(#)moddi3.c	8.1 (Berkeley) 6/4/93";
+#else
+__RCSID("$NetBSD: moddi3.c,v 1.8 2005/12/11 12:24:37 christos Exp $");
+#endif
+#endif*/ /* LIBC_SCCS and not lint */
+
+#include "quad.h"
+
+/*
+ * Return remainder after dividing two signed quads.
+ *
+ * XXX	we assume a % b < 0 iff a < 0, but this is actually machine-dependent.
+ */
+quad_t
+__moddi3(a, b)
+	quad_t a, b;
+{
+	u_quad_t ua, ub, ur;
+	int neg = 0;
+
+	ua = a;
+	ub = b;
+
+	if (a < 0)
+		ua = -ua, neg ^= 1;
+	if (b < 0)
+		ub = -ub;
+	(void)__qdivrem(ua, ub, &ur);
+	if (neg)
+		ur = -ur;
+	return (ur);
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/vboxguest/common/math/gcc/qdivrem.c
@@ -0,0 +1,285 @@
+/*	$NetBSD: qdivrem.c,v 1.12 2005/12/11 12:24:37 christos Exp $	*/
+
+/*-
+ * Copyright (c) 1992, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * This software was developed by the Computer Systems Engineering group
+ * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
+ * contributed to Berkeley.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*#include <sys/cdefs.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+static char sccsid[] = "@(#)qdivrem.c	8.1 (Berkeley) 6/4/93";
+#else
+__RCSID("$NetBSD: qdivrem.c,v 1.12 2005/12/11 12:24:37 christos Exp $");
+#endif
+#endif*/ /* LIBC_SCCS and not lint */
+
+/*
+ * Multiprecision divide.  This algorithm is from Knuth vol. 2 (2nd ed),
+ * section 4.3.1, pp. 257--259.
+ */
+
+#include "quad.h"
+
+#define	B	((int)1 << HALF_BITS)	/* digit base */
+
+/* Combine two `digits' to make a single two-digit number. */
+#define	COMBINE(a, b) (((u_int)(a) << HALF_BITS) | (b))
+
+/* select a type for digits in base B: use unsigned short if they fit */
+#if UINT_MAX == 0xffffffffU && USHRT_MAX >= 0xffff
+typedef unsigned short digit;
+#else
+typedef u_int digit;
+#endif
+
+static void shl __P((digit *p, int len, int sh));
+
+/*
+ * __qdivrem(u, v, rem) returns u/v and, optionally, sets *rem to u%v.
+ *
+ * We do this in base 2-sup-HALF_BITS, so that all intermediate products
+ * fit within u_int.  As a consequence, the maximum length dividend and
+ * divisor are 4 `digits' in this base (they are shorter if they have
+ * leading zeros).
+ */
+u_quad_t
+__qdivrem(uq, vq, arq)
+	u_quad_t uq, vq, *arq;
+{
+	union uu tmp;
+	digit *u, *v, *q;
+	digit v1, v2;
+	u_int qhat, rhat, t;
+	int m, n, d, j, i;
+	digit uspace[5], vspace[5], qspace[5];
+
+	/*
+	 * Take care of special cases: divide by zero, and u < v.
+	 */
+	if (vq == 0) {
+		/* divide by zero. */
+		static volatile const unsigned int zero = 0;
+
+		tmp.ul[H] = tmp.ul[L] = 1 / zero;
+		if (arq)
+			*arq = uq;
+		return (tmp.q);
+	}
+	if (uq < vq) {
+		if (arq)
+			*arq = uq;
+		return (0);
+	}
+	u = &uspace[0];
+	v = &vspace[0];
+	q = &qspace[0];
+
+	/*
+	 * Break dividend and divisor into digits in base B, then
+	 * count leading zeros to determine m and n.  When done, we
+	 * will have:
+	 *	u = (u[1]u[2]...u[m+n]) sub B
+	 *	v = (v[1]v[2]...v[n]) sub B
+	 *	v[1] != 0
+	 *	1 < n <= 4 (if n = 1, we use a different division algorithm)
+	 *	m >= 0 (otherwise u < v, which we already checked)
+	 *	m + n = 4
+	 * and thus
+	 *	m = 4 - n <= 2
+	 */
+	tmp.uq = uq;
+	u[0] = 0;
+	u[1] = (digit)HHALF(tmp.ul[H]);
+	u[2] = (digit)LHALF(tmp.ul[H]);
+	u[3] = (digit)HHALF(tmp.ul[L]);
+	u[4] = (digit)LHALF(tmp.ul[L]);
+	tmp.uq = vq;
+	v[1] = (digit)HHALF(tmp.ul[H]);
+	v[2] = (digit)LHALF(tmp.ul[H]);
+	v[3] = (digit)HHALF(tmp.ul[L]);
+	v[4] = (digit)LHALF(tmp.ul[L]);
+	for (n = 4; v[1] == 0; v++) {
+		if (--n == 1) {
+			u_int rbj;	/* r*B+u[j] (not root boy jim) */
+			digit q1, q2, q3, q4;
+
+			/*
+			 * Change of plan, per exercise 16.
+			 *	r = 0;
+			 *	for j = 1..4:
+			 *		q[j] = floor((r*B + u[j]) / v),
+			 *		r = (r*B + u[j]) % v;
+			 * We unroll this completely here.
+			 */
+			t = v[2];	/* nonzero, by definition */
+			q1 = (digit)(u[1] / t);
+			rbj = COMBINE(u[1] % t, u[2]);
+			q2 = (digit)(rbj / t);
+			rbj = COMBINE(rbj % t, u[3]);
+			q3 = (digit)(rbj / t);
+			rbj = COMBINE(rbj % t, u[4]);
+			q4 = (digit)(rbj / t);
+			if (arq)
+				*arq = rbj % t;
+			tmp.ul[H] = COMBINE(q1, q2);
+			tmp.ul[L] = COMBINE(q3, q4);
+			return (tmp.q);
+		}
+	}
+
+	/*
+	 * By adjusting q once we determine m, we can guarantee that
+	 * there is a complete four-digit quotient at &qspace[1] when
+	 * we finally stop.
+	 */
+	for (m = 4 - n; u[1] == 0; u++)
+		m--;
+	for (i = 4 - m; --i >= 0;)
+		q[i] = 0;
+	q += 4 - m;
+
+	/*
+	 * Here we run Program D, translated from MIX to C and acquiring
+	 * a few minor changes.
+	 *
+	 * D1: choose multiplier 1 << d to ensure v[1] >= B/2.
+	 */
+	d = 0;
+	for (t = v[1]; t < B / 2; t <<= 1)
+		d++;
+	if (d > 0) {
+		shl(&u[0], m + n, d);		/* u <<= d */
+		shl(&v[1], n - 1, d);		/* v <<= d */
+	}
+	/*
+	 * D2: j = 0.
+	 */
+	j = 0;
+	v1 = v[1];	/* for D3 -- note that v[1..n] are constant */
+	v2 = v[2];	/* for D3 */
+	do {
+		digit uj0, uj1, uj2;
+
+		/*
+		 * D3: Calculate qhat (\^q, in TeX notation).
+		 * Let qhat = min((u[j]*B + u[j+1])/v[1], B-1), and
+		 * let rhat = (u[j]*B + u[j+1]) mod v[1].
+		 * While rhat < B and v[2]*qhat > rhat*B+u[j+2],
+		 * decrement qhat and increase rhat correspondingly.
+		 * Note that if rhat >= B, v[2]*qhat < rhat*B.
+		 */
+		uj0 = u[j + 0];	/* for D3 only -- note that u[j+...] change */
+		uj1 = u[j + 1];	/* for D3 only */
+		uj2 = u[j + 2];	/* for D3 only */
+		if (uj0 == v1) {
+			qhat = B;
+			rhat = uj1;
+			goto qhat_too_big;
+		} else {
+			u_int nn = COMBINE(uj0, uj1);
+			qhat = nn / v1;
+			rhat = nn % v1;
+		}
+		while (v2 * qhat > COMBINE(rhat, uj2)) {
+	qhat_too_big:
+			qhat--;
+			if ((rhat += v1) >= B)
+				break;
+		}
+		/*
+		 * D4: Multiply and subtract.
+		 * The variable `t' holds any borrows across the loop.
+		 * We split this up so that we do not require v[0] = 0,
+		 * and to eliminate a final special case.
+		 */
+		for (t = 0, i = n; i > 0; i--) {
+			t = u[i + j] - v[i] * qhat - t;
+			u[i + j] = (digit)LHALF(t);
+			t = (B - HHALF(t)) & (B - 1);
+		}
+		t = u[j] - t;
+		u[j] = (digit)LHALF(t);
+		/*
+		 * D5: test remainder.
+		 * There is a borrow if and only if HHALF(t) is nonzero;
+		 * in that (rare) case, qhat was too large (by exactly 1).
+		 * Fix it by adding v[1..n] to u[j..j+n].
+		 */
+		if (HHALF(t)) {
+			qhat--;
+			for (t = 0, i = n; i > 0; i--) { /* D6: add back. */
+				t += u[i + j] + v[i];
+				u[i + j] = (digit)LHALF(t);
+				t = HHALF(t);
+			}
+			u[j] = (digit)LHALF(u[j] + t);
+		}
+		q[j] = (digit)qhat;
+	} while (++j <= m);		/* D7: loop on j. */
+
+	/*
+	 * If caller wants the remainder, we have to calculate it as
+	 * u[m..m+n] >> d (this is at most n digits and thus fits in
+	 * u[m+1..m+n], but we may need more source digits).
+	 */
+	if (arq) {
+		if (d) {
+			for (i = m + n; i > m; --i)
+				u[i] = (digit)(((u_int)u[i] >> d) |
+				    LHALF((u_int)u[i - 1] << (HALF_BITS - d)));
+			u[i] = 0;
+		}
+		tmp.ul[H] = COMBINE(uspace[1], uspace[2]);
+		tmp.ul[L] = COMBINE(uspace[3], uspace[4]);
+		*arq = tmp.q;
+	}
+
+	tmp.ul[H] = COMBINE(qspace[1], qspace[2]);
+	tmp.ul[L] = COMBINE(qspace[3], qspace[4]);
+	return (tmp.q);
+}
+
+/*
+ * Shift p[0]..p[len] left `sh' bits, ignoring any bits that
+ * `fall out' the left (there never will be any such anyway).
+ * We may assume len >= 0.  NOTE THAT THIS WRITES len+1 DIGITS.
+ */
+static void
+shl(digit *p, int len, int sh)
+{
+	int i;
+
+	for (i = 0; i < len; i++)
+		p[i] = (digit)(LHALF((u_int)p[i] << sh) |
+		    ((u_int)p[i + 1] >> (HALF_BITS - sh)));
+	p[i] = (digit)(LHALF((u_int)p[i] << sh));
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/vboxguest/common/math/gcc/quad.h
@@ -0,0 +1,165 @@
+/*	$NetBSD: quad.h,v 1.17 2005/12/11 12:24:37 christos Exp $	*/
+
+/*-
+ * Copyright (c) 1992, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * This software was developed by the Computer Systems Engineering group
+ * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
+ * contributed to Berkeley.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	@(#)quad.h	8.1 (Berkeley) 6/4/93
+ */
+
+/*
+ * Quad arithmetic.
+ *
+ * This library makes the following assumptions:
+ *
+ *  - The type long long (aka quad_t) exists.
+ *
+ *  - A quad variable is exactly twice as long as `int'.
+ *
+ *  - The machine's arithmetic is two's complement.
+ *
+ * This library can provide 128-bit arithmetic on a machine with 128-bit
+ * quads and 64-bit ints, for instance, or 96-bit arithmetic on machines
+ * with 48-bit ints.
+ */
+
+#if 0 /* iprt */
+#include <sys/types.h>
+#if !defined(_KERNEL) && !defined(_STANDALONE)
+#include <limits.h>
+#else
+#include <machine/limits.h>
+#endif
+#else /* iprt */
+# include <iprt/types.h>
+# include <iprt/nocrt/limits.h>
+# undef __P
+# define __P(a) a
+# undef __GNUC_PREREQ__
+# define __GNUC_PREREQ__(m1,m2) 1
+# if 1 /* ASSUMES: little endian */
+#  define _QUAD_HIGHWORD        1
+#  define _QUAD_LOWWORD         0
+# else
+#  define _QUAD_HIGHWORD        0
+#  define _QUAD_LOWWORD         1
+# endif
+# if !defined(RT_OS_LINUX) || !defined(__KERNEL__) /* (linux/types.h defines u_int) */
+   typedef unsigned int	u_int;
+# endif
+# if !defined(RT_OS_SOLARIS)
+   typedef int64_t quad_t;
+# else
+#  define quad_t int64_t
+# endif
+   typedef uint64_t u_quad_t;
+   typedef quad_t *qaddr_t;
+#endif /* iprt */
+
+/*
+ * Depending on the desired operation, we view a `long long' (aka quad_t) in
+ * one or more of the following formats.
+ */
+union uu {
+	quad_t	q;		/* as a (signed) quad */
+	u_quad_t uq;		/* as an unsigned quad */
+	int	sl[2];		/* as two signed ints */
+	u_int	ul[2];		/* as two unsigned ints */
+};
+
+/*
+ * Define high and low parts of a quad_t.
+ */
+#define	H		_QUAD_HIGHWORD
+#define	L		_QUAD_LOWWORD
+
+/*
+ * Total number of bits in a quad_t and in the pieces that make it up.
+ * These are used for shifting, and also below for halfword extraction
+ * and assembly.
+ */
+#define	QUAD_BITS	(sizeof(quad_t) * CHAR_BIT)
+#define	INT_BITS	(sizeof(int) * CHAR_BIT)
+#define	HALF_BITS	(sizeof(int) * CHAR_BIT / 2)
+
+/*
+ * Extract high and low shortwords from longword, and move low shortword of
+ * longword to upper half of long, i.e., produce the upper longword of
+ * ((quad_t)(x) << (number_of_bits_in_int/2)).  (`x' must actually be u_int.)
+ *
+ * These are used in the multiply code, to split a longword into upper
+ * and lower halves, and to reassemble a product as a quad_t, shifted left
+ * (sizeof(int)*CHAR_BIT/2).
+ */
+#define	HHALF(x)	((u_int)(x) >> HALF_BITS)
+#define	LHALF(x)	((u_int)(x) & (((int)1 << HALF_BITS) - 1))
+#define	LHUP(x)		((u_int)(x) << HALF_BITS)
+
+/*
+ * XXX
+ * Compensate for gcc 1 vs gcc 2.  Gcc 1 defines ?sh?di3's second argument
+ * as u_quad_t, while gcc 2 correctly uses int.  Unfortunately, we still use
+ * both compilers.
+ */
+#if __GNUC_PREREQ__(2, 0) || defined(lint)
+typedef unsigned int	qshift_t;
+#else
+typedef u_quad_t	qshift_t;
+#endif
+
+RT_C_DECLS_BEGIN
+quad_t __adddi3 __P((quad_t, quad_t));
+quad_t __anddi3 __P((quad_t, quad_t));
+quad_t __ashldi3 __P((quad_t, qshift_t));
+quad_t __ashrdi3 __P((quad_t, qshift_t));
+int __cmpdi2 __P((quad_t, quad_t ));
+quad_t __divdi3 __P((quad_t, quad_t));
+quad_t __fixdfdi __P((double));
+quad_t __fixsfdi __P((float));
+u_quad_t __fixunsdfdi __P((double));
+u_quad_t __fixunssfdi __P((float));
+double __floatdidf __P((quad_t));
+float __floatdisf __P((quad_t));
+double __floatunsdidf __P((u_quad_t));
+quad_t __iordi3 __P((quad_t, quad_t));
+quad_t __lshldi3 __P((quad_t, qshift_t));
+quad_t __lshrdi3 __P((quad_t, qshift_t));
+quad_t __moddi3 __P((quad_t, quad_t));
+quad_t __muldi3 __P((quad_t, quad_t));
+quad_t __negdi2 __P((quad_t));
+quad_t __one_cmpldi2 __P((quad_t));
+u_quad_t __qdivrem __P((u_quad_t, u_quad_t, u_quad_t *));
+quad_t __subdi3 __P((quad_t, quad_t));
+int __ucmpdi2 __P((u_quad_t, u_quad_t));
+u_quad_t __udivdi3 __P((u_quad_t, u_quad_t ));
+u_quad_t __umoddi3 __P((u_quad_t, u_quad_t ));
+quad_t __xordi3 __P((quad_t, quad_t));
+RT_C_DECLS_END
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/vboxguest/common/math/gcc/udivdi3.c
@@ -0,0 +1,56 @@
+/*	$NetBSD: udivdi3.c,v 1.8 2005/12/11 12:24:37 christos Exp $	*/
+
+/*-
+ * Copyright (c) 1992, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * This software was developed by the Computer Systems Engineering group
+ * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
+ * contributed to Berkeley.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*#include <sys/cdefs.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+static char sccsid[] = "@(#)udivdi3.c	8.1 (Berkeley) 6/4/93";
+#else
+__RCSID("$NetBSD: udivdi3.c,v 1.8 2005/12/11 12:24:37 christos Exp $");
+#endif
+#endif*/ /* LIBC_SCCS and not lint */
+
+#include "quad.h"
+
+/*
+ * Divide two unsigned quads.
+ */
+u_quad_t
+__udivdi3(a, b)
+	u_quad_t a, b;
+{
+
+	return (__qdivrem(a, b, (u_quad_t *)0));
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/vboxguest/common/math/gcc/umoddi3.c
@@ -0,0 +1,58 @@
+/*	$NetBSD: umoddi3.c,v 1.8 2005/12/11 12:24:37 christos Exp $	*/
+
+/*-
+ * Copyright (c) 1992, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * This software was developed by the Computer Systems Engineering group
+ * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
+ * contributed to Berkeley.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*#include <sys/cdefs.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+static char sccsid[] = "@(#)umoddi3.c	8.1 (Berkeley) 6/4/93";
+#else
+__RCSID("$NetBSD: umoddi3.c,v 1.8 2005/12/11 12:24:37 christos Exp $");
+#endif
+#endif*/ /* LIBC_SCCS and not lint */
+
+#include "quad.h"
+
+/*
+ * Return remainder after dividing two unsigned quads.
+ */
+u_quad_t
+__umoddi3(a, b)
+	u_quad_t a, b;
+{
+	u_quad_t r;
+
+	(void)__qdivrem(a, b, &r);
+	return (r);
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/vboxguest/common/misc/RTAssertMsg1Weak.c
@@ -0,0 +1,42 @@
+/* $Id: RTAssertMsg1Weak.cpp $ */
+/** @file
+ * IPRT - RTAssertMsg1Weak.
+ */
+
+/*
+ * Copyright (C) 2008-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+
+/*********************************************************************************************************************************
+*   Header Files                                                                                                                 *
+*********************************************************************************************************************************/
+#include <iprt/assert.h>
+#include "internal/iprt.h"
+
+#include <iprt/stdarg.h>
+
+
+RTDECL(void) RTAssertMsg1Weak(const char *pszExpr, unsigned uLine, const char *pszFile, const char *pszFunction)
+{
+    RTAssertMsg1(pszExpr, uLine, pszFile, pszFunction);
+}
+RT_EXPORT_SYMBOL(RTAssertMsg1Weak);
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/vboxguest/common/misc/RTAssertMsg2.c
@@ -0,0 +1,45 @@
+/* $Id: RTAssertMsg2.cpp $ */
+/** @file
+ * IPRT - RTAssertMsg2.
+ */
+
+/*
+ * Copyright (C) 2008-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+
+/*********************************************************************************************************************************
+*   Header Files                                                                                                                 *
+*********************************************************************************************************************************/
+#include <iprt/assert.h>
+#include "internal/iprt.h"
+
+#include <iprt/stdarg.h>
+
+
+RTDECL(void) RTAssertMsg2(const char *pszFormat, ...)
+{
+    va_list va;
+    va_start(va, pszFormat);
+    RTAssertMsg2V(pszFormat, va);
+    va_end(va);
+}
+RT_EXPORT_SYMBOL(RTAssertMsg2);
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/vboxguest/common/misc/RTAssertMsg2Add.c
@@ -0,0 +1,45 @@
+/* $Id: RTAssertMsg2Add.cpp $ */
+/** @file
+ * IPRT - RTAssertMsg2Add.
+ */
+
+/*
+ * Copyright (C) 2008-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+
+/*********************************************************************************************************************************
+*   Header Files                                                                                                                 *
+*********************************************************************************************************************************/
+#include <iprt/assert.h>
+#include "internal/iprt.h"
+
+#include <iprt/stdarg.h>
+
+
+RTDECL(void) RTAssertMsg2Add(const char *pszFormat, ...)
+{
+    va_list va;
+    va_start(va, pszFormat);
+    RTAssertMsg2AddV(pszFormat, va);
+    va_end(va);
+}
+RT_EXPORT_SYMBOL(RTAssertMsg2Add);
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/vboxguest/common/misc/RTAssertMsg2AddWeak.c
@@ -0,0 +1,45 @@
+/* $Id: RTAssertMsg2AddWeak.cpp $ */
+/** @file
+ * IPRT - RTAssertMsg2AddWeak.
+ */
+
+/*
+ * Copyright (C) 2008-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+
+/*********************************************************************************************************************************
+*   Header Files                                                                                                                 *
+*********************************************************************************************************************************/
+#include <iprt/assert.h>
+#include "internal/iprt.h"
+
+#include <iprt/stdarg.h>
+
+
+RTDECL(void) RTAssertMsg2AddWeak(const char *pszFormat, ...)
+{
+    va_list va;
+    va_start(va, pszFormat);
+    RTAssertMsg2AddWeakV(pszFormat, va);
+    va_end(va);
+}
+RT_EXPORT_SYMBOL(RTAssertMsg2AddWeak);
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/vboxguest/common/misc/RTAssertMsg2AddWeakV.c
@@ -0,0 +1,40 @@
+/* $Id: RTAssertMsg2AddWeakV.cpp $ */
+/** @file
+ * IPRT - RTAssertMsg2AddWeakV.
+ */
+
+/*
+ * Copyright (C) 2009-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+
+/*********************************************************************************************************************************
+*   Header Files                                                                                                                 *
+*********************************************************************************************************************************/
+#include <iprt/assert.h>
+#include "internal/iprt.h"
+
+
+RTDECL(void) RTAssertMsg2AddWeakV(const char *pszFormat, va_list va)
+{
+    RTAssertMsg2AddV(pszFormat, va);
+}
+RT_EXPORT_SYMBOL(RTAssertMsg2AddWeakV);
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/vboxguest/common/misc/RTAssertMsg2Weak.c
@@ -0,0 +1,45 @@
+/* $Id: RTAssertMsg2Weak.cpp $ */
+/** @file
+ * IPRT - RTAssertMsg2Weak.
+ */
+
+/*
+ * Copyright (C) 2008-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+
+/*********************************************************************************************************************************
+*   Header Files                                                                                                                 *
+*********************************************************************************************************************************/
+#include <iprt/assert.h>
+#include "internal/iprt.h"
+
+#include <iprt/stdarg.h>
+
+
+RTDECL(void) RTAssertMsg2Weak(const char *pszFormat, ...)
+{
+    va_list va;
+    va_start(va, pszFormat);
+    RTAssertMsg2WeakV(pszFormat, va);
+    va_end(va);
+}
+RT_EXPORT_SYMBOL(RTAssertMsg2Weak);
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/vboxguest/common/misc/RTAssertMsg2WeakV.c
@@ -0,0 +1,40 @@
+/* $Id: RTAssertMsg2WeakV.cpp $ */
+/** @file
+ * IPRT - RTAssertMsg2WeakV.
+ */
+
+/*
+ * Copyright (C) 2009-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+
+/*********************************************************************************************************************************
+*   Header Files                                                                                                                 *
+*********************************************************************************************************************************/
+#include <iprt/assert.h>
+#include "internal/iprt.h"
+
+
+RTDECL(void) RTAssertMsg2WeakV(const char *pszFormat, va_list va)
+{
+    RTAssertMsg2V(pszFormat, va);
+}
+RT_EXPORT_SYMBOL(RTAssertMsg2WeakV);
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/vboxguest/common/misc/assert.c
@@ -0,0 +1,307 @@
+/* $Id: assert.cpp $ */
+/** @file
+ * IPRT - Assertions, common code.
+ */
+
+/*
+ * Copyright (C) 2006-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+
+/*********************************************************************************************************************************
+*   Header Files                                                                                                                 *
+*********************************************************************************************************************************/
+#include <iprt/assert.h>
+#include "internal/iprt.h"
+
+#include <iprt/asm.h>
+#include <iprt/err.h>
+#include <iprt/log.h>
+#include <iprt/string.h>
+#include <iprt/stdarg.h>
+#ifdef IN_RING3
+# include <stdio.h>
+#endif
+#include "internal/assert.h"
+
+
+/*********************************************************************************************************************************
+*   Global Variables                                                                                                             *
+*********************************************************************************************************************************/
+/** The last assert message, 1st part. */
+RTDATADECL(char)                    g_szRTAssertMsg1[1024];
+RT_EXPORT_SYMBOL(g_szRTAssertMsg1);
+/** The last assert message, 2nd part. */
+RTDATADECL(char)                    g_szRTAssertMsg2[4096];
+RT_EXPORT_SYMBOL(g_szRTAssertMsg2);
+/** The length of the g_szRTAssertMsg2 content.
+ * @remarks Race.  */
+static uint32_t volatile            g_cchRTAssertMsg2;
+/** The last assert message, expression. */
+RTDATADECL(const char * volatile)   g_pszRTAssertExpr;
+RT_EXPORT_SYMBOL(g_pszRTAssertExpr);
+/** The last assert message, function name. */
+RTDATADECL(const char *  volatile)  g_pszRTAssertFunction;
+RT_EXPORT_SYMBOL(g_pszRTAssertFunction);
+/** The last assert message, file name. */
+RTDATADECL(const char * volatile)   g_pszRTAssertFile;
+RT_EXPORT_SYMBOL(g_pszRTAssertFile);
+/** The last assert message, line number. */
+RTDATADECL(uint32_t volatile)       g_u32RTAssertLine;
+RT_EXPORT_SYMBOL(g_u32RTAssertLine);
+
+
+/** Set if assertions are quiet. */
+static bool volatile                g_fQuiet = false;
+/** Set if assertions may panic. */
+static bool volatile                g_fMayPanic = true;
+
+
+RTDECL(bool) RTAssertSetQuiet(bool fQuiet)
+{
+    return ASMAtomicXchgBool(&g_fQuiet, fQuiet);
+}
+RT_EXPORT_SYMBOL(RTAssertSetQuiet);
+
+
+RTDECL(bool) RTAssertAreQuiet(void)
+{
+    return ASMAtomicUoReadBool(&g_fQuiet);
+}
+RT_EXPORT_SYMBOL(RTAssertAreQuiet);
+
+
+RTDECL(bool) RTAssertSetMayPanic(bool fMayPanic)
+{
+    return ASMAtomicXchgBool(&g_fMayPanic, fMayPanic);
+}
+RT_EXPORT_SYMBOL(RTAssertSetMayPanic);
+
+
+RTDECL(bool) RTAssertMayPanic(void)
+{
+    return ASMAtomicUoReadBool(&g_fMayPanic);
+}
+RT_EXPORT_SYMBOL(RTAssertMayPanic);
+
+
+RTDECL(void) RTAssertMsg1(const char *pszExpr, unsigned uLine, const char *pszFile, const char *pszFunction)
+{
+    /*
+     * Fill in the globals.
+     */
+    ASMAtomicUoWritePtr(&g_pszRTAssertExpr, pszExpr);
+    ASMAtomicUoWritePtr(&g_pszRTAssertFile, pszFile);
+    ASMAtomicUoWritePtr(&g_pszRTAssertFunction, pszFunction);
+    ASMAtomicUoWriteU32(&g_u32RTAssertLine, uLine);
+    RTStrPrintf(g_szRTAssertMsg1, sizeof(g_szRTAssertMsg1),
+                "\n!!Assertion Failed!!\n"
+                "Expression: %s\n"
+                "Location  : %s(%d) %s\n",
+                pszExpr, pszFile, uLine, pszFunction);
+
+    /*
+     * If not quiet, make noise.
+     */
+    if (!RTAssertAreQuiet())
+    {
+        RTERRVARS SavedErrVars;
+        RTErrVarsSave(&SavedErrVars);
+
+#ifdef IN_RING0
+# ifdef IN_GUEST_R0
+        RTLogBackdoorPrintf("\n!!Assertion Failed!!\n"
+                            "Expression: %s\n"
+                            "Location  : %s(%d) %s\n",
+                            pszExpr, pszFile, uLine, pszFunction);
+# endif
+        /** @todo fully integrate this with the logger... play safe a bit for now.  */
+        rtR0AssertNativeMsg1(pszExpr, uLine, pszFile, pszFunction);
+
+#else  /* !IN_RING0 */
+# if !defined(IN_RING3) && !defined(LOG_NO_COM)
+#  if 0 /* Enable this iff you have a COM port and really want this debug info. */
+        RTLogComPrintf("\n!!Assertion Failed!!\n"
+                       "Expression: %s\n"
+                       "Location  : %s(%d) %s\n",
+                       pszExpr, pszFile, uLine, pszFunction);
+#  endif
+# endif
+
+        PRTLOGGER pLog = RTLogRelGetDefaultInstance();
+        if (pLog)
+        {
+            RTLogRelPrintf("\n!!Assertion Failed!!\n"
+                           "Expression: %s\n"
+                           "Location  : %s(%d) %s\n",
+                           pszExpr, pszFile, uLine, pszFunction);
+# ifndef IN_RC /* flushing is done automatically in RC */
+            RTLogFlush(pLog);
+# endif
+        }
+
+# ifndef LOG_ENABLED
+        if (!pLog)
+# endif
+        {
+            pLog = RTLogDefaultInstance();
+            if (pLog)
+            {
+                RTLogPrintf("\n!!Assertion Failed!!\n"
+                            "Expression: %s\n"
+                            "Location  : %s(%d) %s\n",
+                            pszExpr, pszFile, uLine, pszFunction);
+# ifndef IN_RC /* flushing is done automatically in RC */
+                RTLogFlush(pLog);
+# endif
+            }
+        }
+
+# ifdef IN_RING3
+        /* print to stderr, helps user and gdb debugging. */
+        fprintf(stderr,
+                "\n!!Assertion Failed!!\n"
+                "Expression: %s\n"
+                "Location  : %s(%d) %s\n",
+                VALID_PTR(pszExpr) ? pszExpr : "<none>",
+                VALID_PTR(pszFile) ? pszFile : "<none>",
+                uLine,
+                VALID_PTR(pszFunction) ? pszFunction : "");
+        fflush(stderr);
+# endif
+#endif /* !IN_RING0 */
+
+        RTErrVarsRestore(&SavedErrVars);
+    }
+}
+RT_EXPORT_SYMBOL(RTAssertMsg1);
+
+
+/**
+ * Worker for RTAssertMsg2V and RTAssertMsg2AddV
+ *
+ * @param   fInitial            True if it's RTAssertMsg2V, otherwise false.
+ * @param   pszFormat           The message format string.
+ * @param   va                  The format arguments.
+ */
+static void rtAssertMsg2Worker(bool fInitial, const char *pszFormat, va_list va)
+{
+    va_list vaCopy;
+    size_t  cch;
+
+    /*
+     * The global first.
+     */
+    if (fInitial)
+    {
+        va_copy(vaCopy, va);
+        cch = RTStrPrintfV(g_szRTAssertMsg2, sizeof(g_szRTAssertMsg2), pszFormat, vaCopy);
+        ASMAtomicWriteU32(&g_cchRTAssertMsg2, (uint32_t)cch);
+        va_end(vaCopy);
+    }
+    else
+    {
+        cch = ASMAtomicReadU32(&g_cchRTAssertMsg2);
+        if (cch < sizeof(g_szRTAssertMsg2) - 4)
+        {
+            va_copy(vaCopy, va);
+            cch += RTStrPrintfV(&g_szRTAssertMsg2[cch], sizeof(g_szRTAssertMsg2) - cch, pszFormat, vaCopy);
+            ASMAtomicWriteU32(&g_cchRTAssertMsg2, (uint32_t)cch);
+            va_end(vaCopy);
+        }
+    }
+
+    /*
+     * If not quiet, make some noise.
+     */
+    if (!RTAssertAreQuiet())
+    {
+        RTERRVARS SavedErrVars;
+        RTErrVarsSave(&SavedErrVars);
+
+#ifdef IN_RING0
+# ifdef IN_GUEST_R0
+        va_copy(vaCopy, va);
+        RTLogBackdoorPrintfV(pszFormat, vaCopy);
+        va_end(vaCopy);
+# endif
+        /** @todo fully integrate this with the logger... play safe a bit for now.  */
+        rtR0AssertNativeMsg2V(fInitial, pszFormat, va);
+
+#else  /* !IN_RING0 */
+# if !defined(IN_RING3) && !defined(LOG_NO_COM)
+#  if 0 /* Enable this iff you have a COM port and really want this debug info. */
+        va_copy(vaCopy, va);
+        RTLogComPrintfV(pszFormat, vaCopy);
+        va_end(vaCopy);
+#  endif
+# endif
+
+        PRTLOGGER pLog = RTLogRelGetDefaultInstance();
+        if (pLog)
+        {
+            va_copy(vaCopy, va);
+            RTLogRelPrintfV(pszFormat, vaCopy);
+            va_end(vaCopy);
+# ifndef IN_RC /* flushing is done automatically in RC */
+            RTLogFlush(pLog);
+# endif
+        }
+
+        pLog = RTLogDefaultInstance();
+        if (pLog)
+        {
+            va_copy(vaCopy, va);
+            RTLogPrintfV(pszFormat, vaCopy);
+            va_end(vaCopy);
+# ifndef IN_RC /* flushing is done automatically in RC */
+            RTLogFlush(pLog);
+#endif
+        }
+
+# ifdef IN_RING3
+        /* print to stderr, helps user and gdb debugging. */
+        char szMsg[sizeof(g_szRTAssertMsg2)];
+        va_copy(vaCopy, va);
+        RTStrPrintfV(szMsg, sizeof(szMsg), pszFormat, vaCopy);
+        va_end(vaCopy);
+        fprintf(stderr, "%s", szMsg);
+        fflush(stderr);
+# endif
+#endif /* !IN_RING0 */
+
+        RTErrVarsRestore(&SavedErrVars);
+    }
+}
+
+
+RTDECL(void) RTAssertMsg2V(const char *pszFormat, va_list va)
+{
+    rtAssertMsg2Worker(true /*fInitial*/, pszFormat, va);
+}
+RT_EXPORT_SYMBOL(RTAssertMsg2V);
+
+
+RTDECL(void) RTAssertMsg2AddV(const char *pszFormat, va_list va)
+{
+    rtAssertMsg2Worker(false /*fInitial*/, pszFormat, va);
+}
+RT_EXPORT_SYMBOL(RTAssertMsg2AddV);
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/vboxguest/common/misc/thread.c
@@ -0,0 +1,1586 @@
+/* $Id: thread.cpp $ */
+/** @file
+ * IPRT - Threads, common routines.
+ */
+
+/*
+ * Copyright (C) 2006-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+
+/*********************************************************************************************************************************
+*   Header Files                                                                                                                 *
+*********************************************************************************************************************************/
+#define LOG_GROUP RTLOGGROUP_THREAD
+#include <iprt/thread.h>
+#include "internal/iprt.h"
+
+#include <iprt/log.h>
+#include <iprt/avl.h>
+#include <iprt/alloc.h>
+#include <iprt/assert.h>
+#include <iprt/lockvalidator.h>
+#include <iprt/semaphore.h>
+#ifdef IN_RING0
+# include <iprt/spinlock.h>
+#endif
+#include <iprt/asm.h>
+#include <iprt/err.h>
+#include <iprt/string.h>
+#include "internal/magics.h"
+#include "internal/thread.h"
+#include "internal/sched.h"
+#include "internal/process.h"
+#ifdef RT_WITH_ICONV_CACHE
+# include "internal/string.h"
+#endif
+
+
+/*********************************************************************************************************************************
+*   Defined Constants And Macros                                                                                                 *
+*********************************************************************************************************************************/
+#ifdef IN_RING0
+# define RT_THREAD_LOCK_RW()        RTSpinlockAcquire(g_ThreadSpinlock)
+# define RT_THREAD_UNLOCK_RW()      RTSpinlockRelease(g_ThreadSpinlock)
+# define RT_THREAD_LOCK_RD()        RTSpinlockAcquire(g_ThreadSpinlock)
+# define RT_THREAD_UNLOCK_RD()      RTSpinlockRelease(g_ThreadSpinlock)
+#else
+# define RT_THREAD_LOCK_RW()        rtThreadLockRW()
+# define RT_THREAD_UNLOCK_RW()      rtThreadUnLockRW()
+# define RT_THREAD_LOCK_RD()        rtThreadLockRD()
+# define RT_THREAD_UNLOCK_RD()      rtThreadUnLockRD()
+#endif
+
+
+/*********************************************************************************************************************************
+*   Global Variables                                                                                                             *
+*********************************************************************************************************************************/
+/** The AVL thread containing the threads. */
+static PAVLPVNODECORE       g_ThreadTree;
+/** The number of threads in the tree (for ring-0 termination kludge). */
+static uint32_t volatile    g_cThreadInTree;
+#ifdef IN_RING3
+/** The RW lock protecting the tree. */
+static RTSEMRW          g_ThreadRWSem = NIL_RTSEMRW;
+#else
+/** The spinlocks protecting the tree. */
+static RTSPINLOCK       g_ThreadSpinlock = NIL_RTSPINLOCK;
+#endif
+/** Indicates whether we've been initialized or not. */
+static bool             g_frtThreadInitialized;
+
+
+/*********************************************************************************************************************************
+*   Internal Functions                                                                                                           *
+*********************************************************************************************************************************/
+static void rtThreadDestroy(PRTTHREADINT pThread);
+#ifdef IN_RING3
+static int rtThreadAdopt(RTTHREADTYPE enmType, unsigned fFlags, uint32_t fIntFlags, const char *pszName);
+#endif
+static void rtThreadRemoveLocked(PRTTHREADINT pThread);
+static PRTTHREADINT rtThreadAlloc(RTTHREADTYPE enmType, unsigned fFlags, uint32_t fIntFlags, const char *pszName);
+
+
+/** @page pg_rt_thread  IPRT Thread Internals
+ *
+ * IPRT provides interface to whatever native threading that the host provides,
+ * preferably using a CRT level interface to better integrate with other libraries.
+ *
+ * Internally IPRT keeps track of threads by means of the RTTHREADINT structure.
+ * All the RTTHREADINT structures are kept in a AVL tree which is protected by a
+ * read/write lock for efficient access. A thread is inserted into the tree in
+ * three places in the code. The main thread is 'adopted' by IPRT on rtR3Init()
+ * by rtThreadAdopt(). When creating a new thread there the child and the parent
+ * race inserting the thread, this is rtThreadMain() and RTThreadCreate.
+ *
+ * RTTHREADINT objects are using reference counting as a mean of sticking around
+ * till no-one needs them any longer. Waitable threads is created with one extra
+ * reference so they won't go away until they are waited on. This introduces a
+ * major problem if we use the host thread identifier as key in the AVL tree - the
+ * host may reuse the thread identifier before the thread was waited on. So, on
+ * most platforms we are using the RTTHREADINT pointer as key and not the
+ * thread id. RTThreadSelf() then have to be implemented using a pointer stored
+ * in thread local storage (TLS).
+ *
+ * In Ring-0 we only try keep track of kernel threads created by RTThreadCreate
+ * at the moment. There we really only need the 'join' feature, but doing things
+ * the same way allow us to name threads and similar stuff.
+ */
+
+
+/**
+ * Initializes the thread database.
+ *
+ * @returns iprt status code.
+ */
+DECLHIDDEN(int) rtThreadInit(void)
+{
+#ifdef IN_RING3
+    int rc = VINF_ALREADY_INITIALIZED;
+    if (g_ThreadRWSem == NIL_RTSEMRW)
+    {
+        /*
+         * We assume the caller is the 1st thread, which we'll call 'main'.
+         * But first, we'll create the semaphore.
+         */
+        rc = RTSemRWCreateEx(&g_ThreadRWSem, RTSEMRW_FLAGS_NO_LOCK_VAL, NIL_RTLOCKVALCLASS, RTLOCKVAL_SUB_CLASS_NONE, NULL);
+        if (RT_SUCCESS(rc))
+        {
+            rc = rtThreadNativeInit();
+            if (RT_SUCCESS(rc))
+                rc = rtThreadAdopt(RTTHREADTYPE_DEFAULT, 0, RTTHREADINT_FLAGS_MAIN, "main");
+            if (RT_SUCCESS(rc))
+                rc = rtSchedNativeCalcDefaultPriority(RTTHREADTYPE_DEFAULT);
+            if (RT_SUCCESS(rc))
+            {
+                g_frtThreadInitialized = true;
+                return VINF_SUCCESS;
+            }
+
+            /* failed, clear out */
+            RTSemRWDestroy(g_ThreadRWSem);
+            g_ThreadRWSem = NIL_RTSEMRW;
+        }
+    }
+
+#elif defined(IN_RING0)
+    int rc;
+    /*
+     * Create the spinlock and to native init.
+     */
+    Assert(g_ThreadSpinlock == NIL_RTSPINLOCK);
+    rc = RTSpinlockCreate(&g_ThreadSpinlock, RTSPINLOCK_FLAGS_INTERRUPT_SAFE, "RTThread");
+    if (RT_SUCCESS(rc))
+    {
+        rc = rtThreadNativeInit();
+        if (RT_SUCCESS(rc))
+        {
+            g_frtThreadInitialized = true;
+            return VINF_SUCCESS;
+        }
+
+        /* failed, clear out */
+        RTSpinlockDestroy(g_ThreadSpinlock);
+        g_ThreadSpinlock = NIL_RTSPINLOCK;
+    }
+#else
+# error "!IN_RING0 && !IN_RING3"
+#endif
+    return rc;
+}
+
+
+#ifdef IN_RING3
+/**
+ * Called when IPRT was first initialized in unobtrusive mode and later changed
+ * to obtrustive.
+ *
+ * This is only applicable in ring-3.
+ */
+DECLHIDDEN(void) rtThreadReInitObtrusive(void)
+{
+    rtThreadNativeReInitObtrusive();
+}
+#endif
+
+
+/**
+ * Terminates the thread database.
+ */
+DECLHIDDEN(void) rtThreadTerm(void)
+{
+#ifdef IN_RING3
+    /* we don't cleanup here yet */
+
+#elif defined(IN_RING0)
+    /* just destroy the spinlock and assume the thread is fine... */
+    RTSpinlockDestroy(g_ThreadSpinlock);
+    g_ThreadSpinlock = NIL_RTSPINLOCK;
+    if (g_ThreadTree != NULL)
+        RTAssertMsg2Weak("WARNING: g_ThreadTree=%p\n", g_ThreadTree);
+#endif
+}
+
+
+#ifdef IN_RING3
+
+DECLINLINE(void) rtThreadLockRW(void)
+{
+    if (g_ThreadRWSem == NIL_RTSEMRW)
+        rtThreadInit();
+    int rc = RTSemRWRequestWrite(g_ThreadRWSem, RT_INDEFINITE_WAIT);
+    AssertReleaseRC(rc);
+}
+
+
+DECLINLINE(void) rtThreadLockRD(void)
+{
+    if (g_ThreadRWSem == NIL_RTSEMRW)
+        rtThreadInit();
+    int rc = RTSemRWRequestRead(g_ThreadRWSem, RT_INDEFINITE_WAIT);
+    AssertReleaseRC(rc);
+}
+
+
+DECLINLINE(void) rtThreadUnLockRW(void)
+{
+    int rc = RTSemRWReleaseWrite(g_ThreadRWSem);
+    AssertReleaseRC(rc);
+}
+
+
+DECLINLINE(void) rtThreadUnLockRD(void)
+{
+    int rc = RTSemRWReleaseRead(g_ThreadRWSem);
+    AssertReleaseRC(rc);
+}
+
+
+/**
+ * Adopts the calling thread.
+ * No locks are taken or released by this function.
+ */
+static int rtThreadAdopt(RTTHREADTYPE enmType, unsigned fFlags, uint32_t fIntFlags, const char *pszName)
+{
+    int rc;
+    PRTTHREADINT pThread;
+    Assert(!(fFlags & RTTHREADFLAGS_WAITABLE));
+    fFlags &= ~RTTHREADFLAGS_WAITABLE;
+
+    /*
+     * Allocate and insert the thread.
+     * (It is vital that rtThreadNativeAdopt updates the TLS before
+     * we try inserting the thread because of locking.)
+     */
+    rc = VERR_NO_MEMORY;
+    pThread = rtThreadAlloc(enmType, fFlags, RTTHREADINT_FLAGS_ALIEN | fIntFlags, pszName);
+    if (pThread)
+    {
+        RTNATIVETHREAD NativeThread = RTThreadNativeSelf();
+        rc = rtThreadNativeAdopt(pThread);
+        if (RT_SUCCESS(rc))
+        {
+            rtThreadInsert(pThread, NativeThread);
+            rtThreadSetState(pThread, RTTHREADSTATE_RUNNING);
+            rtThreadRelease(pThread);
+        }
+    }
+    return rc;
+}
+
+/**
+ * Adopts a non-IPRT thread.
+ *
+ * @returns IPRT status code.
+ * @param   enmType         The thread type.
+ * @param   fFlags          The thread flags. RTTHREADFLAGS_WAITABLE is not currently allowed.
+ * @param   pszName         The thread name. Optional.
+ * @param   pThread         Where to store the thread handle. Optional.
+ */
+RTDECL(int) RTThreadAdopt(RTTHREADTYPE enmType, unsigned fFlags, const char *pszName, PRTTHREAD pThread)
+{
+    int      rc;
+    RTTHREAD Thread;
+
+    AssertReturn(!(fFlags & RTTHREADFLAGS_WAITABLE), VERR_INVALID_PARAMETER);
+    AssertReturn(!pszName || VALID_PTR(pszName), VERR_INVALID_POINTER);
+    AssertReturn(!pThread || VALID_PTR(pThread), VERR_INVALID_POINTER);
+
+    rc = VINF_SUCCESS;
+    Thread = RTThreadSelf();
+    if (Thread == NIL_RTTHREAD)
+    {
+        /* generate a name if none was given. */
+        char szName[RTTHREAD_NAME_LEN];
+        if (!pszName || !*pszName)
+        {
+            static uint32_t s_i32AlienId = 0;
+            uint32_t i32Id = ASMAtomicIncU32(&s_i32AlienId);
+            RTStrPrintf(szName, sizeof(szName), "ALIEN-%RX32", i32Id);
+            pszName = szName;
+        }
+
+        /* try adopt it */
+        rc = rtThreadAdopt(enmType, fFlags, 0, pszName);
+        Thread = RTThreadSelf();
+        Log(("RTThreadAdopt: %RTthrd %RTnthrd '%s' enmType=%d fFlags=%#x rc=%Rrc\n",
+             Thread, RTThreadNativeSelf(), pszName, enmType, fFlags, rc));
+    }
+    else
+        Log(("RTThreadAdopt: %RTthrd %RTnthrd '%s' enmType=%d fFlags=%#x - already adopted!\n",
+             Thread, RTThreadNativeSelf(), pszName, enmType, fFlags));
+
+    if (pThread)
+        *pThread = Thread;
+    return rc;
+}
+RT_EXPORT_SYMBOL(RTThreadAdopt);
+
+
+/**
+ * Get the thread handle of the current thread, automatically adopting alien
+ * threads.
+ *
+ * @returns Thread handle.
+ */
+RTDECL(RTTHREAD) RTThreadSelfAutoAdopt(void)
+{
+    RTTHREAD hSelf = RTThreadSelf();
+    if (RT_UNLIKELY(hSelf == NIL_RTTHREAD))
+        RTThreadAdopt(RTTHREADTYPE_DEFAULT, 0, NULL, &hSelf);
+    return hSelf;
+}
+RT_EXPORT_SYMBOL(RTThreadSelfAutoAdopt);
+
+#endif /* IN_RING3 */
+
+/**
+ * Allocates a per thread data structure and initializes the basic fields.
+ *
+ * @returns Pointer to per thread data structure.
+ *          This is reference once.
+ * @returns NULL on failure.
+ * @param   enmType     The thread type.
+ * @param   fFlags      The thread flags.
+ * @param   fIntFlags   The internal thread flags.
+ * @param   pszName     Pointer to the thread name.
+ */
+PRTTHREADINT rtThreadAlloc(RTTHREADTYPE enmType, unsigned fFlags, uint32_t fIntFlags, const char *pszName)
+{
+    PRTTHREADINT pThread = (PRTTHREADINT)RTMemAllocZ(sizeof(RTTHREADINT));
+    if (pThread)
+    {
+        size_t cchName;
+        int rc;
+
+        pThread->Core.Key   = (void*)NIL_RTTHREAD;
+        pThread->u32Magic   = RTTHREADINT_MAGIC;
+        cchName = strlen(pszName);
+        if (cchName >= RTTHREAD_NAME_LEN)
+            cchName = RTTHREAD_NAME_LEN - 1;
+        memcpy(pThread->szName, pszName, cchName);
+        pThread->szName[cchName] = '\0';
+        pThread->cRefs           = 2 + !!(fFlags & RTTHREADFLAGS_WAITABLE); /* And extra reference if waitable. */
+        pThread->rc              = VERR_PROCESS_RUNNING; /** @todo get a better error code! */
+        pThread->enmType         = enmType;
+        pThread->fFlags          = fFlags;
+        pThread->fIntFlags       = fIntFlags;
+        pThread->enmState        = RTTHREADSTATE_INITIALIZING;
+        pThread->fReallySleeping = false;
+#ifdef IN_RING3
+        rtLockValidatorInitPerThread(&pThread->LockValidator);
+#endif
+#ifdef RT_WITH_ICONV_CACHE
+        rtStrIconvCacheInit(pThread);
+#endif
+        rc = RTSemEventMultiCreate(&pThread->EventUser);
+        if (RT_SUCCESS(rc))
+        {
+            rc = RTSemEventMultiCreate(&pThread->EventTerminated);
+            if (RT_SUCCESS(rc))
+                return pThread;
+            RTSemEventMultiDestroy(pThread->EventUser);
+        }
+        RTMemFree(pThread);
+    }
+    return NULL;
+}
+
+
+/**
+ * Insert the per thread data structure into the tree.
+ *
+ * This can be called from both the thread it self and the parent,
+ * thus it must handle insertion failures in a nice manner.
+ *
+ * @param   pThread         Pointer to thread structure allocated by rtThreadAlloc().
+ * @param   NativeThread    The native thread id.
+ */
+DECLHIDDEN(void) rtThreadInsert(PRTTHREADINT pThread, RTNATIVETHREAD NativeThread)
+{
+    Assert(pThread);
+    Assert(pThread->u32Magic == RTTHREADINT_MAGIC);
+
+    {
+        RT_THREAD_LOCK_RW();
+
+        /*
+         * Do not insert a terminated thread.
+         *
+         * This may happen if the thread finishes before the RTThreadCreate call
+         * gets this far. Since the OS may quickly reuse the native thread ID
+         * it should not be reinserted at this point.
+         */
+        if (rtThreadGetState(pThread) != RTTHREADSTATE_TERMINATED)
+        {
+            /*
+             * Before inserting we must check if there is a thread with this id
+             * in the tree already. We're racing parent and child on insert here
+             * so that the handle is valid in both ends when they return / start.
+             *
+             * If it's not ourself we find, it's a dead alien thread and we will
+             * unlink it from the tree. Alien threads will be released at this point.
+             */
+            PRTTHREADINT pThreadOther = (PRTTHREADINT)RTAvlPVGet(&g_ThreadTree, (void *)NativeThread);
+            if (pThreadOther != pThread)
+            {
+                bool fRc;
+                /* remove dead alien if any */
+                if (pThreadOther)
+                {
+                    AssertMsg(pThreadOther->fIntFlags & RTTHREADINT_FLAGS_ALIEN, ("%p:%s; %p:%s\n", pThread, pThread->szName, pThreadOther, pThreadOther->szName));
+                    ASMAtomicBitClear(&pThread->fIntFlags, RTTHREADINT_FLAG_IN_TREE_BIT);
+                    rtThreadRemoveLocked(pThreadOther);
+                    if (pThreadOther->fIntFlags & RTTHREADINT_FLAGS_ALIEN)
+                    rtThreadRelease(pThreadOther);
+                }
+
+                /* insert the thread */
+                ASMAtomicWritePtr(&pThread->Core.Key, (void *)NativeThread);
+                fRc = RTAvlPVInsert(&g_ThreadTree, &pThread->Core);
+                ASMAtomicOrU32(&pThread->fIntFlags, RTTHREADINT_FLAG_IN_TREE);
+                if (fRc)
+                    ASMAtomicIncU32(&g_cThreadInTree);
+
+                AssertReleaseMsg(fRc, ("Lock problem? %p (%RTnthrd) %s\n", pThread, NativeThread, pThread->szName));
+                NOREF(fRc);
+            }
+        }
+
+        RT_THREAD_UNLOCK_RW();
+    }
+}
+
+
+/**
+ * Removes the thread from the AVL tree, call owns the tree lock
+ * and has cleared the RTTHREADINT_FLAG_IN_TREE bit.
+ *
+ * @param   pThread     The thread to remove.
+ */
+static void rtThreadRemoveLocked(PRTTHREADINT pThread)
+{
+    PRTTHREADINT pThread2 = (PRTTHREADINT)RTAvlPVRemove(&g_ThreadTree, pThread->Core.Key);
+#if !defined(RT_OS_OS2) /** @todo this asserts for threads created by NSPR */
+    AssertMsg(pThread2 == pThread, ("%p(%s) != %p (%p/%s)\n", pThread2, pThread2  ? pThread2->szName : "<null>",
+                                    pThread, pThread->Core.Key, pThread->szName));
+#endif
+    if (pThread2)
+        ASMAtomicDecU32(&g_cThreadInTree);
+}
+
+
+/**
+ * Removes the thread from the AVL tree.
+ *
+ * @param   pThread     The thread to remove.
+ */
+static void rtThreadRemove(PRTTHREADINT pThread)
+{
+    RT_THREAD_LOCK_RW();
+    if (ASMAtomicBitTestAndClear(&pThread->fIntFlags, RTTHREADINT_FLAG_IN_TREE_BIT))
+        rtThreadRemoveLocked(pThread);
+    RT_THREAD_UNLOCK_RW();
+}
+
+
+/**
+ * Checks if a thread is alive or not.
+ *
+ * @returns true if the thread is alive (or we don't really know).
+ * @returns false if the thread has surely terminate.
+ */
+DECLINLINE(bool) rtThreadIsAlive(PRTTHREADINT pThread)
+{
+    return !(pThread->fIntFlags & RTTHREADINT_FLAGS_TERMINATED);
+}
+
+
+/**
+ * Gets a thread by it's native ID.
+ *
+ * @returns pointer to the thread structure.
+ * @returns NULL if not a thread IPRT knows.
+ * @param   NativeThread    The native thread id.
+ */
+DECLHIDDEN(PRTTHREADINT) rtThreadGetByNative(RTNATIVETHREAD NativeThread)
+{
+    PRTTHREADINT pThread;
+    /*
+     * Simple tree lookup.
+     */
+    RT_THREAD_LOCK_RD();
+    pThread = (PRTTHREADINT)RTAvlPVGet(&g_ThreadTree, (void *)NativeThread);
+    RT_THREAD_UNLOCK_RD();
+    return pThread;
+}
+
+
+/**
+ * Gets the per thread data structure for a thread handle.
+ *
+ * @returns Pointer to the per thread data structure for Thread.
+ *          The caller must release the thread using rtThreadRelease().
+ * @returns NULL if Thread was not found.
+ * @param   Thread      Thread id which structure is to be returned.
+ */
+DECLHIDDEN(PRTTHREADINT) rtThreadGet(RTTHREAD Thread)
+{
+    if (    Thread != NIL_RTTHREAD
+        &&  VALID_PTR(Thread))
+    {
+        PRTTHREADINT pThread = (PRTTHREADINT)Thread;
+        if (    pThread->u32Magic == RTTHREADINT_MAGIC
+            &&  pThread->cRefs > 0)
+        {
+            ASMAtomicIncU32(&pThread->cRefs);
+            return pThread;
+        }
+    }
+
+    AssertMsgFailed(("Thread=%RTthrd\n", Thread));
+    return NULL;
+}
+
+/**
+ * Release a per thread data structure.
+ *
+ * @returns New reference count.
+ * @param   pThread     The thread structure to release.
+ */
+DECLHIDDEN(uint32_t) rtThreadRelease(PRTTHREADINT pThread)
+{
+    uint32_t cRefs;
+
+    Assert(pThread);
+    if (pThread->cRefs >= 1)
+    {
+        cRefs = ASMAtomicDecU32(&pThread->cRefs);
+        if (!cRefs)
+            rtThreadDestroy(pThread);
+    }
+    else
+    {
+        cRefs = 0;
+        AssertFailed();
+    }
+    return cRefs;
+}
+
+
+/**
+ * Destroys the per thread data.
+ *
+ * @param   pThread     The thread to destroy.
+ */
+static void rtThreadDestroy(PRTTHREADINT pThread)
+{
+    RTSEMEVENTMULTI hEvt1, hEvt2;
+    /*
+     * Remove it from the tree and mark it as dead.
+     *
+     * Threads that has seen rtThreadTerminate and should already have been
+     * removed from the tree. There is probably no thread that  should
+     * require removing here. However, be careful making sure that cRefs
+     * isn't 0 if we do or we'll blow up because the strict locking code
+     * will be calling us back.
+     */
+    if (ASMBitTest(&pThread->fIntFlags, RTTHREADINT_FLAG_IN_TREE_BIT))
+    {
+        ASMAtomicIncU32(&pThread->cRefs);
+        rtThreadRemove(pThread);
+        ASMAtomicDecU32(&pThread->cRefs);
+    }
+
+    /*
+     * Invalidate the thread structure.
+     */
+#ifdef IN_RING3
+    rtLockValidatorSerializeDestructEnter();
+
+    rtLockValidatorDeletePerThread(&pThread->LockValidator);
+#endif
+#ifdef RT_WITH_ICONV_CACHE
+    rtStrIconvCacheDestroy(pThread);
+#endif
+    ASMAtomicXchgU32(&pThread->u32Magic, RTTHREADINT_MAGIC_DEAD);
+    ASMAtomicWritePtr(&pThread->Core.Key, (void *)NIL_RTTHREAD);
+    pThread->enmType         = RTTHREADTYPE_INVALID;
+    hEvt1    = pThread->EventUser;
+    pThread->EventUser       = NIL_RTSEMEVENTMULTI;
+    hEvt2    = pThread->EventTerminated;
+    pThread->EventTerminated = NIL_RTSEMEVENTMULTI;
+
+#ifdef IN_RING3
+    rtLockValidatorSerializeDestructLeave();
+#endif
+
+    /*
+     * Destroy semaphore resources and free the bugger.
+     */
+    RTSemEventMultiDestroy(hEvt1);
+    if (hEvt2 != NIL_RTSEMEVENTMULTI)
+        RTSemEventMultiDestroy(hEvt2);
+
+    rtThreadNativeDestroy(pThread);
+    RTMemFree(pThread);
+}
+
+
+/**
+ * Terminates the thread.
+ * Called by the thread wrapper function when the thread terminates.
+ *
+ * @param   pThread     The thread structure.
+ * @param   rc          The thread result code.
+ */
+DECLHIDDEN(void) rtThreadTerminate(PRTTHREADINT pThread, int rc)
+{
+    Assert(pThread->cRefs >= 1);
+
+#ifdef IPRT_WITH_GENERIC_TLS
+    /*
+     * Destroy TLS entries.
+     */
+    rtThreadTlsDestruction(pThread);
+#endif /* IPRT_WITH_GENERIC_TLS */
+
+    /*
+     * Set the rc, mark it terminated and signal anyone waiting.
+     */
+    pThread->rc = rc;
+    rtThreadSetState(pThread, RTTHREADSTATE_TERMINATED);
+    ASMAtomicOrU32(&pThread->fIntFlags, RTTHREADINT_FLAGS_TERMINATED);
+    if (pThread->EventTerminated != NIL_RTSEMEVENTMULTI)
+        RTSemEventMultiSignal(pThread->EventTerminated);
+
+    /*
+     * Remove the thread from the tree so that there will be no
+     * key clashes in the AVL tree and release our reference to ourself.
+     */
+    rtThreadRemove(pThread);
+    rtThreadRelease(pThread);
+}
+
+
+/**
+ * The common thread main function.
+ * This is called by rtThreadNativeMain().
+ *
+ * @returns The status code of the thread.
+ *          pThread is dereference by the thread before returning!
+ * @param   pThread         The thread structure.
+ * @param   NativeThread    The native thread id.
+ * @param   pszThreadName   The name of the thread (purely a dummy for backtrace).
+ */
+DECLCALLBACK(DECLHIDDEN(int)) rtThreadMain(PRTTHREADINT pThread, RTNATIVETHREAD NativeThread, const char *pszThreadName)
+{
+    int rc;
+    NOREF(pszThreadName);
+    rtThreadInsert(pThread, NativeThread);
+    Log(("rtThreadMain: Starting: pThread=%p NativeThread=%RTnthrd Name=%s pfnThread=%p pvUser=%p\n",
+         pThread, NativeThread, pThread->szName, pThread->pfnThread, pThread->pvUser));
+
+    /*
+     * Change the priority.
+     */
+    rc = rtThreadNativeSetPriority(pThread, pThread->enmType);
+#ifdef IN_RING3
+    AssertMsgRC(rc, ("Failed to set priority of thread %p (%RTnthrd / %s) to enmType=%d enmPriority=%d rc=%Rrc\n",
+                     pThread, NativeThread, pThread->szName, pThread->enmType, g_enmProcessPriority, rc));
+#else
+    AssertMsgRC(rc, ("Failed to set priority of thread %p (%RTnthrd / %s) to enmType=%d rc=%Rrc\n",
+                     pThread, NativeThread, pThread->szName, pThread->enmType, rc));
+#endif
+
+    /*
+     * Call thread function and terminate when it returns.
+     */
+    rtThreadSetState(pThread, RTTHREADSTATE_RUNNING);
+    rc = pThread->pfnThread(pThread, pThread->pvUser);
+
+    /*
+     * Paranoia checks for leftover resources.
+     */
+#ifdef RTSEMRW_STRICT
+    int32_t cWrite = ASMAtomicReadS32(&pThread->cWriteLocks);
+    Assert(!cWrite);
+    int32_t cRead = ASMAtomicReadS32(&pThread->cReadLocks);
+    Assert(!cRead);
+#endif
+
+    Log(("rtThreadMain: Terminating: rc=%d pThread=%p NativeThread=%RTnthrd Name=%s pfnThread=%p pvUser=%p\n",
+         rc, pThread, NativeThread, pThread->szName, pThread->pfnThread, pThread->pvUser));
+    rtThreadTerminate(pThread, rc);
+    return rc;
+}
+
+
+/**
+ * Create a new thread.
+ *
+ * @returns iprt status code.
+ * @param   pThread     Where to store the thread handle to the new thread. (optional)
+ * @param   pfnThread   The thread function.
+ * @param   pvUser      User argument.
+ * @param   cbStack     The size of the stack for the new thread.
+ *                      Use 0 for the default stack size.
+ * @param   enmType     The thread type. Used for deciding scheduling attributes
+ *                      of the thread.
+ * @param   fFlags      Flags of the RTTHREADFLAGS type (ORed together).
+ * @param   pszName     Thread name.
+ */
+RTDECL(int) RTThreadCreate(PRTTHREAD pThread, PFNRTTHREAD pfnThread, void *pvUser, size_t cbStack,
+                           RTTHREADTYPE enmType, unsigned fFlags, const char *pszName)
+{
+    int             rc;
+    PRTTHREADINT    pThreadInt;
+
+    LogFlow(("RTThreadCreate: pThread=%p pfnThread=%p pvUser=%p cbStack=%#x enmType=%d fFlags=%#x pszName=%p:{%s}\n",
+             pThread, pfnThread, pvUser, cbStack, enmType, fFlags, pszName, pszName));
+
+    /*
+     * Validate input.
+     */
+    if (!VALID_PTR(pThread) && pThread)
+    {
+        Assert(VALID_PTR(pThread));
+        return VERR_INVALID_PARAMETER;
+    }
+    if (!VALID_PTR(pfnThread))
+    {
+        Assert(VALID_PTR(pfnThread));
+        return VERR_INVALID_PARAMETER;
+    }
+    if (!pszName || !*pszName || strlen(pszName) >= RTTHREAD_NAME_LEN)
+    {
+        AssertMsgFailed(("pszName=%s (max len is %d because of logging)\n", pszName, RTTHREAD_NAME_LEN - 1));
+        return VERR_INVALID_PARAMETER;
+    }
+    if (fFlags & ~RTTHREADFLAGS_MASK)
+    {
+        AssertMsgFailed(("fFlags=%#x\n", fFlags));
+        return VERR_INVALID_PARAMETER;
+    }
+
+    /*
+     * Allocate thread argument.
+     */
+    pThreadInt = rtThreadAlloc(enmType, fFlags, 0, pszName);
+    if (pThreadInt)
+    {
+        RTNATIVETHREAD NativeThread;
+
+        pThreadInt->pfnThread = pfnThread;
+        pThreadInt->pvUser    = pvUser;
+        pThreadInt->cbStack   = cbStack;
+
+        rc = rtThreadNativeCreate(pThreadInt, &NativeThread);
+        if (RT_SUCCESS(rc))
+        {
+            rtThreadInsert(pThreadInt, NativeThread);
+            rtThreadRelease(pThreadInt);
+            Log(("RTThreadCreate: Created thread %p (%p) %s\n", pThreadInt, NativeThread, pszName));
+            if (pThread)
+                *pThread = pThreadInt;
+            return VINF_SUCCESS;
+        }
+
+        pThreadInt->cRefs = 1;
+        rtThreadRelease(pThreadInt);
+    }
+    else
+        rc = VERR_NO_TMP_MEMORY;
+    LogFlow(("RTThreadCreate: Failed to create thread, rc=%Rrc\n", rc));
+    AssertReleaseRC(rc);
+    return rc;
+}
+RT_EXPORT_SYMBOL(RTThreadCreate);
+
+
+/**
+ * Create a new thread.
+ *
+ * Same as RTThreadCreate except the name is given in the RTStrPrintfV form.
+ *
+ * @returns iprt status code.
+ * @param   pThread     See RTThreadCreate.
+ * @param   pfnThread   See RTThreadCreate.
+ * @param   pvUser      See RTThreadCreate.
+ * @param   cbStack     See RTThreadCreate.
+ * @param   enmType     See RTThreadCreate.
+ * @param   fFlags      See RTThreadCreate.
+ * @param   pszNameFmt  Thread name format.
+ * @param   va          Format arguments.
+ */
+RTDECL(int) RTThreadCreateV(PRTTHREAD pThread, PFNRTTHREAD pfnThread, void *pvUser, size_t cbStack,
+                            RTTHREADTYPE enmType, uint32_t fFlags, const char *pszNameFmt, va_list va)
+{
+    char szName[RTTHREAD_NAME_LEN * 2];
+    RTStrPrintfV(szName, sizeof(szName), pszNameFmt, va);
+    return RTThreadCreate(pThread, pfnThread, pvUser, cbStack, enmType, fFlags, szName);
+}
+RT_EXPORT_SYMBOL(RTThreadCreateV);
+
+
+/**
+ * Create a new thread.
+ *
+ * Same as RTThreadCreate except the name is given in the RTStrPrintf form.
+ *
+ * @returns iprt status code.
+ * @param   pThread     See RTThreadCreate.
+ * @param   pfnThread   See RTThreadCreate.
+ * @param   pvUser      See RTThreadCreate.
+ * @param   cbStack     See RTThreadCreate.
+ * @param   enmType     See RTThreadCreate.
+ * @param   fFlags      See RTThreadCreate.
+ * @param   pszNameFmt  Thread name format.
+ * @param   ...         Format arguments.
+ */
+RTDECL(int) RTThreadCreateF(PRTTHREAD pThread, PFNRTTHREAD pfnThread, void *pvUser, size_t cbStack,
+                            RTTHREADTYPE enmType, uint32_t fFlags, const char *pszNameFmt, ...)
+{
+    va_list va;
+    int rc;
+    va_start(va, pszNameFmt);
+    rc = RTThreadCreateV(pThread, pfnThread, pvUser, cbStack, enmType, fFlags, pszNameFmt, va);
+    va_end(va);
+    return rc;
+}
+RT_EXPORT_SYMBOL(RTThreadCreateF);
+
+
+/**
+ * Gets the native thread id of a IPRT thread.
+ *
+ * @returns The native thread id.
+ * @param   Thread      The IPRT thread.
+ */
+RTDECL(RTNATIVETHREAD) RTThreadGetNative(RTTHREAD Thread)
+{
+    PRTTHREADINT pThread = rtThreadGet(Thread);
+    if (pThread)
+    {
+        RTNATIVETHREAD NativeThread = (RTNATIVETHREAD)pThread->Core.Key;
+        rtThreadRelease(pThread);
+        return NativeThread;
+    }
+    return NIL_RTNATIVETHREAD;
+}
+RT_EXPORT_SYMBOL(RTThreadGetNative);
+
+
+/**
+ * Gets the IPRT thread of a native thread.
+ *
+ * @returns The IPRT thread handle
+ * @returns NIL_RTTHREAD if not a thread known to IPRT.
+ * @param   NativeThread        The native thread handle/id.
+ */
+RTDECL(RTTHREAD) RTThreadFromNative(RTNATIVETHREAD NativeThread)
+{
+    PRTTHREADINT pThread = rtThreadGetByNative(NativeThread);
+    if (pThread)
+        return pThread;
+    return NIL_RTTHREAD;
+}
+RT_EXPORT_SYMBOL(RTThreadFromNative);
+
+
+/**
+ * Gets the name of the current thread thread.
+ *
+ * @returns Pointer to readonly name string.
+ * @returns NULL on failure.
+ */
+RTDECL(const char *) RTThreadSelfName(void)
+{
+    RTTHREAD Thread = RTThreadSelf();
+    if (Thread != NIL_RTTHREAD)
+    {
+        PRTTHREADINT pThread = rtThreadGet(Thread);
+        if (pThread)
+        {
+            const char *szName = pThread->szName;
+            rtThreadRelease(pThread);
+            return szName;
+        }
+    }
+    return NULL;
+}
+RT_EXPORT_SYMBOL(RTThreadSelfName);
+
+
+/**
+ * Gets the name of a thread.
+ *
+ * @returns Pointer to readonly name string.
+ * @returns NULL on failure.
+ * @param   Thread      Thread handle of the thread to query the name of.
+ */
+RTDECL(const char *) RTThreadGetName(RTTHREAD Thread)
+{
+    PRTTHREADINT pThread;
+    if (Thread == NIL_RTTHREAD)
+        return NULL;
+    pThread = rtThreadGet(Thread);
+    if (pThread)
+    {
+        const char *szName = pThread->szName;
+        rtThreadRelease(pThread);
+        return szName;
+    }
+    return NULL;
+}
+RT_EXPORT_SYMBOL(RTThreadGetName);
+
+
+/**
+ * Sets the name of a thread.
+ *
+ * @returns iprt status code.
+ * @param   Thread      Thread handle of the thread to query the name of.
+ * @param   pszName     The thread name.
+ */
+RTDECL(int) RTThreadSetName(RTTHREAD Thread, const char *pszName)
+{
+    /*
+     * Validate input.
+     */
+    PRTTHREADINT pThread;
+    size_t cchName = strlen(pszName);
+    if (cchName >= RTTHREAD_NAME_LEN)
+    {
+        AssertMsgFailed(("pszName=%s is too long, max is %d\n", pszName, RTTHREAD_NAME_LEN - 1));
+        return VERR_INVALID_PARAMETER;
+    }
+    pThread = rtThreadGet(Thread);
+    if (!pThread)
+        return VERR_INVALID_HANDLE;
+
+    /*
+     * Update the name.
+     */
+    pThread->szName[cchName] = '\0';    /* paranoia */
+    memcpy(pThread->szName, pszName, cchName);
+    rtThreadRelease(pThread);
+    return VINF_SUCCESS;
+}
+RT_EXPORT_SYMBOL(RTThreadSetName);
+
+
+/**
+ * Checks if the specified thread is the main thread.
+ *
+ * @returns true if it is, false if it isn't.
+ *
+ * @param   hThread     The thread handle.
+ *
+ * @remarks This function may not return the correct value when rtR3Init was
+ *          called on a thread of the than the main one.  This could for
+ *          instance happen when the DLL/DYLIB/SO containing IPRT is dynamically
+ *          loaded at run time by a different thread.
+ */
+RTDECL(bool) RTThreadIsMain(RTTHREAD hThread)
+{
+    PRTTHREADINT pThread = rtThreadGet(hThread);
+    if (pThread)
+    {
+        bool fRc = !!(pThread->fIntFlags & RTTHREADINT_FLAGS_MAIN);
+        rtThreadRelease(pThread);
+        return fRc;
+    }
+    return false;
+}
+RT_EXPORT_SYMBOL(RTThreadIsMain);
+
+
+RTDECL(bool) RTThreadIsSelfAlive(void)
+{
+    if (g_frtThreadInitialized)
+    {
+        RTTHREAD hSelf = RTThreadSelf();
+        if (hSelf != NIL_RTTHREAD)
+        {
+            /*
+             * Inspect the thread state.  ASSUMES thread state order.
+             */
+            RTTHREADSTATE enmState = rtThreadGetState(hSelf);
+            if (   enmState >= RTTHREADSTATE_RUNNING
+                && enmState <= RTTHREADSTATE_END)
+                return true;
+        }
+    }
+    return false;
+}
+RT_EXPORT_SYMBOL(RTThreadIsSelfAlive);
+
+
+RTDECL(bool) RTThreadIsSelfKnown(void)
+{
+    if (g_frtThreadInitialized)
+    {
+        RTTHREAD hSelf = RTThreadSelf();
+        if (hSelf != NIL_RTTHREAD)
+            return true;
+    }
+    return false;
+}
+RT_EXPORT_SYMBOL(RTThreadIsSelfKnown);
+
+
+RTDECL(bool) RTThreadIsInitialized(void)
+{
+    return g_frtThreadInitialized;
+}
+RT_EXPORT_SYMBOL(RTThreadIsInitialized);
+
+
+/**
+ * Signal the user event.
+ *
+ * @returns     iprt status code.
+ */
+RTDECL(int) RTThreadUserSignal(RTTHREAD Thread)
+{
+    int             rc;
+    PRTTHREADINT    pThread = rtThreadGet(Thread);
+    if (pThread)
+    {
+        rc = RTSemEventMultiSignal(pThread->EventUser);
+        rtThreadRelease(pThread);
+    }
+    else
+        rc = VERR_INVALID_HANDLE;
+    return rc;
+}
+RT_EXPORT_SYMBOL(RTThreadUserSignal);
+
+
+/**
+ * Wait for the user event, resume on interruption.
+ *
+ * @returns     iprt status code.
+ * @param       Thread          The thread to wait for.
+ * @param       cMillies        The number of milliseconds to wait. Use RT_INDEFINITE_WAIT for
+ *                              an indefinite wait.
+ */
+RTDECL(int) RTThreadUserWait(RTTHREAD Thread, RTMSINTERVAL cMillies)
+{
+    int             rc;
+    PRTTHREADINT    pThread = rtThreadGet(Thread);
+    if (pThread)
+    {
+        rc = RTSemEventMultiWait(pThread->EventUser, cMillies);
+        rtThreadRelease(pThread);
+    }
+    else
+        rc = VERR_INVALID_HANDLE;
+    return rc;
+}
+RT_EXPORT_SYMBOL(RTThreadUserWait);
+
+
+/**
+ * Wait for the user event, return on interruption.
+ *
+ * @returns     iprt status code.
+ * @param       Thread          The thread to wait for.
+ * @param       cMillies        The number of milliseconds to wait. Use RT_INDEFINITE_WAIT for
+ *                              an indefinite wait.
+ */
+RTDECL(int) RTThreadUserWaitNoResume(RTTHREAD Thread, RTMSINTERVAL cMillies)
+{
+    int             rc;
+    PRTTHREADINT    pThread = rtThreadGet(Thread);
+    if (pThread)
+    {
+        rc = RTSemEventMultiWaitNoResume(pThread->EventUser, cMillies);
+        rtThreadRelease(pThread);
+    }
+    else
+        rc = VERR_INVALID_HANDLE;
+    return rc;
+}
+RT_EXPORT_SYMBOL(RTThreadUserWaitNoResume);
+
+
+/**
+ * Reset the user event.
+ *
+ * @returns     iprt status code.
+ * @param       Thread          The thread to reset.
+ */
+RTDECL(int) RTThreadUserReset(RTTHREAD Thread)
+{
+    int     rc;
+    PRTTHREADINT  pThread = rtThreadGet(Thread);
+    if (pThread)
+    {
+        rc = RTSemEventMultiReset(pThread->EventUser);
+        rtThreadRelease(pThread);
+    }
+    else
+        rc = VERR_INVALID_HANDLE;
+    return rc;
+}
+RT_EXPORT_SYMBOL(RTThreadUserReset);
+
+
+/**
+ * Wait for the thread to terminate.
+ *
+ * @returns     iprt status code.
+ * @param       Thread          The thread to wait for.
+ * @param       cMillies        The number of milliseconds to wait. Use RT_INDEFINITE_WAIT for
+ *                              an indefinite wait.
+ * @param       prc             Where to store the return code of the thread. Optional.
+ * @param       fAutoResume     Whether or not to resume the wait on VERR_INTERRUPTED.
+ */
+static int rtThreadWait(RTTHREAD Thread, RTMSINTERVAL cMillies, int *prc, bool fAutoResume)
+{
+    int rc = VERR_INVALID_HANDLE;
+    if (Thread != NIL_RTTHREAD)
+    {
+        PRTTHREADINT pThread = rtThreadGet(Thread);
+        if (pThread)
+        {
+            if (pThread->fFlags & RTTHREADFLAGS_WAITABLE)
+            {
+                if (fAutoResume)
+                    rc = RTSemEventMultiWait(pThread->EventTerminated, cMillies);
+                else
+                    rc = RTSemEventMultiWaitNoResume(pThread->EventTerminated, cMillies);
+                if (RT_SUCCESS(rc))
+                {
+                    if (prc)
+                        *prc = pThread->rc;
+
+                    /*
+                     * If the thread is marked as waitable, we'll do one additional
+                     * release in order to free up the thread structure (see how we
+                     * init cRef in rtThreadAlloc()).
+                     */
+                    if (ASMAtomicBitTestAndClear(&pThread->fFlags, RTTHREADFLAGS_WAITABLE_BIT))
+                    {
+                        rtThreadRelease(pThread);
+#ifdef IN_RING0
+                        /*
+                         * IPRT termination kludge. Call native code to make sure
+                         * the last thread is really out of IPRT to prevent it from
+                         * crashing after we destroyed the spinlock in rtThreadTerm.
+                         */
+                        if (   ASMAtomicReadU32(&g_cThreadInTree) == 1
+                            && ASMAtomicReadU32(&pThread->cRefs) > 1)
+                            rtThreadNativeWaitKludge(pThread);
+#endif
+                    }
+                }
+            }
+            else
+            {
+                rc = VERR_THREAD_NOT_WAITABLE;
+                AssertRC(rc);
+            }
+            rtThreadRelease(pThread);
+        }
+    }
+    return rc;
+}
+
+
+/**
+ * Wait for the thread to terminate, resume on interruption.
+ *
+ * @returns     iprt status code.
+ *              Will not return VERR_INTERRUPTED.
+ * @param       Thread          The thread to wait for.
+ * @param       cMillies        The number of milliseconds to wait. Use RT_INDEFINITE_WAIT for
+ *                              an indefinite wait.
+ * @param       prc             Where to store the return code of the thread. Optional.
+ */
+RTDECL(int) RTThreadWait(RTTHREAD Thread, RTMSINTERVAL cMillies, int *prc)
+{
+    int rc = rtThreadWait(Thread, cMillies, prc, true);
+    Assert(rc != VERR_INTERRUPTED);
+    return rc;
+}
+RT_EXPORT_SYMBOL(RTThreadWait);
+
+
+/**
+ * Wait for the thread to terminate, return on interruption.
+ *
+ * @returns     iprt status code.
+ * @param       Thread          The thread to wait for.
+ * @param       cMillies        The number of milliseconds to wait. Use RT_INDEFINITE_WAIT for
+ *                              an indefinite wait.
+ * @param       prc             Where to store the return code of the thread. Optional.
+ */
+RTDECL(int) RTThreadWaitNoResume(RTTHREAD Thread, RTMSINTERVAL cMillies, int *prc)
+{
+    return rtThreadWait(Thread, cMillies, prc, false);
+}
+RT_EXPORT_SYMBOL(RTThreadWaitNoResume);
+
+
+/**
+ * Changes the type of the specified thread.
+ *
+ * @returns iprt status code.
+ * @param   Thread      The thread which type should be changed.
+ * @param   enmType     The new thread type.
+ */
+RTDECL(int) RTThreadSetType(RTTHREAD Thread, RTTHREADTYPE enmType)
+{
+    /*
+     * Validate input.
+     */
+    int     rc;
+    if (    enmType > RTTHREADTYPE_INVALID
+        &&  enmType < RTTHREADTYPE_END)
+    {
+        PRTTHREADINT pThread = rtThreadGet(Thread);
+        if (pThread)
+        {
+            if (rtThreadIsAlive(pThread))
+            {
+                /*
+                 * Do the job.
+                 */
+                RT_THREAD_LOCK_RW();
+                rc = rtThreadNativeSetPriority(pThread, enmType);
+                if (RT_SUCCESS(rc))
+                    ASMAtomicXchgSize(&pThread->enmType, enmType);
+                RT_THREAD_UNLOCK_RW();
+                if (RT_FAILURE(rc))
+                    Log(("RTThreadSetType: failed on thread %p (%s), rc=%Rrc!!!\n", Thread, pThread->szName, rc));
+            }
+            else
+                rc = VERR_THREAD_IS_DEAD;
+            rtThreadRelease(pThread);
+        }
+        else
+            rc = VERR_INVALID_HANDLE;
+    }
+    else
+    {
+        AssertMsgFailed(("enmType=%d\n", enmType));
+        rc = VERR_INVALID_PARAMETER;
+    }
+    return rc;
+}
+RT_EXPORT_SYMBOL(RTThreadSetType);
+
+
+/**
+ * Gets the type of the specified thread.
+ *
+ * @returns The thread type.
+ * @returns RTTHREADTYPE_INVALID if the thread handle is invalid.
+ * @param   Thread      The thread in question.
+ */
+RTDECL(RTTHREADTYPE) RTThreadGetType(RTTHREAD Thread)
+{
+    RTTHREADTYPE enmType = RTTHREADTYPE_INVALID;
+    PRTTHREADINT pThread = rtThreadGet(Thread);
+    if (pThread)
+    {
+        enmType = pThread->enmType;
+        rtThreadRelease(pThread);
+    }
+    return enmType;
+}
+RT_EXPORT_SYMBOL(RTThreadGetType);
+
+#ifdef IN_RING3
+
+/**
+ * Recalculates scheduling attributes for the default process
+ * priority using the specified priority type for the calling thread.
+ *
+ * The scheduling attributes are targeted at threads and they are protected
+ * by the thread read-write semaphore, that's why RTProc is forwarding the
+ * operation to RTThread.
+ *
+ * @returns iprt status code.
+ * @remarks Will only work for strict builds.
+ */
+int rtThreadDoCalcDefaultPriority(RTTHREADTYPE enmType)
+{
+    RT_THREAD_LOCK_RW();
+    int rc = rtSchedNativeCalcDefaultPriority(enmType);
+    RT_THREAD_UNLOCK_RW();
+    return rc;
+}
+
+
+/**
+ * Thread enumerator - sets the priority of one thread.
+ *
+ * @returns 0 to continue.
+ * @returns !0 to stop. In our case a VERR_ code.
+ * @param   pNode   The thread node.
+ * @param   pvUser  The new priority.
+ */
+static DECLCALLBACK(int) rtThreadSetPriorityOne(PAVLPVNODECORE pNode, void *pvUser)
+{
+    PRTTHREADINT pThread = (PRTTHREADINT)pNode;
+    if (!rtThreadIsAlive(pThread))
+        return VINF_SUCCESS;
+    int rc = rtThreadNativeSetPriority(pThread, pThread->enmType);
+    if (RT_SUCCESS(rc)) /* hide any warnings */
+        return VINF_SUCCESS;
+    NOREF(pvUser);
+    return rc;
+}
+
+
+/**
+ * Attempts to alter the priority of the current process.
+ *
+ * The scheduling attributes are targeted at threads and they are protected
+ * by the thread read-write semaphore, that's why RTProc is forwarding the
+ * operation to RTThread. This operation also involves updating all thread
+ * which is much faster done from RTThread.
+ *
+ * @returns iprt status code.
+ * @param   enmPriority     The new priority.
+ */
+DECLHIDDEN(int) rtThreadDoSetProcPriority(RTPROCPRIORITY enmPriority)
+{
+    LogFlow(("rtThreadDoSetProcPriority: enmPriority=%d\n", enmPriority));
+
+    /*
+     * First validate that we're allowed by the OS to use all the
+     * scheduling attributes defined by the specified process priority.
+     */
+    RT_THREAD_LOCK_RW();
+    int rc = rtProcNativeSetPriority(enmPriority);
+    if (RT_SUCCESS(rc))
+    {
+        /*
+         * Update the priority of existing thread.
+         */
+        rc = RTAvlPVDoWithAll(&g_ThreadTree, true, rtThreadSetPriorityOne, NULL);
+        if (RT_SUCCESS(rc))
+            ASMAtomicXchgSize(&g_enmProcessPriority, enmPriority);
+        else
+        {
+            /*
+             * Failed, restore the priority.
+             */
+            rtProcNativeSetPriority(g_enmProcessPriority);
+            RTAvlPVDoWithAll(&g_ThreadTree, true, rtThreadSetPriorityOne, NULL);
+        }
+    }
+    RT_THREAD_UNLOCK_RW();
+    LogFlow(("rtThreadDoSetProcPriority: returns %Rrc\n", rc));
+    return rc;
+}
+
+
+/**
+ * Change the thread state to blocking.
+ *
+ * @param   hThread         The current thread.
+ * @param   enmState        The sleep state.
+ * @param   fReallySleeping Really going to sleep now.
+ */
+RTDECL(void) RTThreadBlocking(RTTHREAD hThread, RTTHREADSTATE enmState, bool fReallySleeping)
+{
+    Assert(RTTHREAD_IS_SLEEPING(enmState));
+    PRTTHREADINT pThread = hThread;
+    if (pThread != NIL_RTTHREAD)
+    {
+        Assert(pThread == RTThreadSelf());
+        if (rtThreadGetState(pThread) == RTTHREADSTATE_RUNNING)
+            rtThreadSetState(pThread, enmState);
+        ASMAtomicWriteBool(&pThread->fReallySleeping, fReallySleeping);
+    }
+}
+RT_EXPORT_SYMBOL(RTThreadBlocking);
+
+
+/**
+ * Unblocks a thread.
+ *
+ * This function is paired with rtThreadBlocking.
+ *
+ * @param   hThread     The current thread.
+ * @param   enmCurState The current state, used to check for nested blocking.
+ *                      The new state will be running.
+ */
+RTDECL(void) RTThreadUnblocked(RTTHREAD hThread, RTTHREADSTATE enmCurState)
+{
+    PRTTHREADINT pThread = hThread;
+    if (pThread != NIL_RTTHREAD)
+    {
+        Assert(pThread == RTThreadSelf());
+        ASMAtomicWriteBool(&pThread->fReallySleeping, false);
+
+        RTTHREADSTATE enmActualState = rtThreadGetState(pThread);
+        if (enmActualState == enmCurState)
+        {
+            rtThreadSetState(pThread, RTTHREADSTATE_RUNNING);
+            if (   pThread->LockValidator.pRec
+                && pThread->LockValidator.enmRecState == enmCurState)
+                ASMAtomicWriteNullPtr(&pThread->LockValidator.pRec);
+        }
+        /* This is a bit ugly... :-/ */
+        else if (   (   enmActualState == RTTHREADSTATE_TERMINATED
+                     || enmActualState == RTTHREADSTATE_INITIALIZING)
+                 && pThread->LockValidator.pRec)
+            ASMAtomicWriteNullPtr(&pThread->LockValidator.pRec);
+        Assert(   pThread->LockValidator.pRec == NULL
+               || RTTHREAD_IS_SLEEPING(enmActualState));
+    }
+}
+RT_EXPORT_SYMBOL(RTThreadUnblocked);
+
+
+/**
+ * Get the current thread state.
+ *
+ * @returns The thread state.
+ * @param   hThread         The thread.
+ */
+RTDECL(RTTHREADSTATE) RTThreadGetState(RTTHREAD hThread)
+{
+    RTTHREADSTATE   enmState = RTTHREADSTATE_INVALID;
+    PRTTHREADINT    pThread  = rtThreadGet(hThread);
+    if (pThread)
+    {
+        enmState = rtThreadGetState(pThread);
+        rtThreadRelease(pThread);
+    }
+    return enmState;
+}
+RT_EXPORT_SYMBOL(RTThreadGetState);
+
+
+RTDECL(RTTHREADSTATE) RTThreadGetReallySleeping(RTTHREAD hThread)
+{
+    RTTHREADSTATE   enmState = RTTHREADSTATE_INVALID;
+    PRTTHREADINT    pThread  = rtThreadGet(hThread);
+    if (pThread)
+    {
+        enmState = rtThreadGetState(pThread);
+        if (!ASMAtomicUoReadBool(&pThread->fReallySleeping))
+            enmState = RTTHREADSTATE_RUNNING;
+        rtThreadRelease(pThread);
+    }
+    return enmState;
+}
+RT_EXPORT_SYMBOL(RTThreadGetReallySleeping);
+
+
+/**
+ * Translate a thread state into a string.
+ *
+ * @returns Pointer to a read-only string containing the state name.
+ * @param   enmState            The state.
+ */
+RTDECL(const char *) RTThreadStateName(RTTHREADSTATE enmState)
+{
+    switch (enmState)
+    {
+        case RTTHREADSTATE_INVALID:         return "INVALID";
+        case RTTHREADSTATE_INITIALIZING:    return "INITIALIZING";
+        case RTTHREADSTATE_TERMINATED:      return "TERMINATED";
+        case RTTHREADSTATE_RUNNING:         return "RUNNING";
+        case RTTHREADSTATE_CRITSECT:        return "CRITSECT";
+        case RTTHREADSTATE_EVENT:           return "EVENT";
+        case RTTHREADSTATE_EVENT_MULTI:     return "EVENT_MULTI";
+        case RTTHREADSTATE_FAST_MUTEX:      return "FAST_MUTEX";
+        case RTTHREADSTATE_MUTEX:           return "MUTEX";
+        case RTTHREADSTATE_RW_READ:         return "RW_READ";
+        case RTTHREADSTATE_RW_WRITE:        return "RW_WRITE";
+        case RTTHREADSTATE_SLEEP:           return "SLEEP";
+        case RTTHREADSTATE_SPIN_MUTEX:      return "SPIN_MUTEX";
+        default:                            return "UnknownThreadState";
+    }
+}
+RT_EXPORT_SYMBOL(RTThreadStateName);
+
+#endif /* IN_RING3 */
+#ifdef IPRT_WITH_GENERIC_TLS
+
+/**
+ * Thread enumerator - clears a TLS entry.
+ *
+ * @returns 0.
+ * @param   pNode   The thread node.
+ * @param   pvUser  The TLS index.
+ */
+static DECLCALLBACK(int) rtThreadClearTlsEntryCallback(PAVLPVNODECORE pNode, void *pvUser)
+{
+    PRTTHREADINT pThread = (PRTTHREADINT)pNode;
+    RTTLS iTls = (RTTLS)(uintptr_t)pvUser;
+    ASMAtomicWriteNullPtr(&pThread->apvTlsEntries[iTls]);
+    return 0;
+}
+
+
+/**
+ * Helper for the generic TLS implementation that clears a given TLS
+ * entry on all threads.
+ *
+ * @param   iTls        The TLS entry. (valid)
+ */
+DECLHIDDEN(void) rtThreadClearTlsEntry(RTTLS iTls)
+{
+    RT_THREAD_LOCK_RD();
+    RTAvlPVDoWithAll(&g_ThreadTree, true /* fFromLeft*/, rtThreadClearTlsEntryCallback, (void *)(uintptr_t)iTls);
+    RT_THREAD_UNLOCK_RD();
+}
+
+#endif /* IPRT_WITH_GENERIC_TLS */
+
+
+#if defined(RT_OS_WINDOWS) && defined(IN_RING3)
+
+/**
+ * Thread enumeration callback for RTThreadNameThreads
+ */
+static DECLCALLBACK(int) rtThreadNameThreadCallback(PAVLPVNODECORE pNode, void *pvUser)
+{
+    PRTTHREADINT pThread = (PRTTHREADINT)pNode;
+    rtThreadNativeInformDebugger(pThread);
+    return 0;
+}
+
+/**
+ * A function that can be called from the windows debugger to get the names of
+ * all threads when attaching to a process.
+ *
+ * Usage: .call VBoxRT!RTThreadNameThreads()
+ *
+ * @returns 0
+ * @remarks Do not call from source code as it skips locks.
+ */
+extern "C" RTDECL(int) RTThreadNameThreads(void);
+RTDECL(int) RTThreadNameThreads(void)
+{
+    return RTAvlPVDoWithAll(&g_ThreadTree, true /* fFromLeft*/, rtThreadNameThreadCallback, NULL);
+}
+
+#endif
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/vboxguest/common/string/RTStrCopy.c
@@ -0,0 +1,52 @@
+/* $Id: RTStrCopy.cpp $ */
+/** @file
+ * IPRT - RTStrCopy.
+ */
+
+/*
+ * Copyright (C) 2010-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+
+/*********************************************************************************************************************************
+*   Header Files                                                                                                                 *
+*********************************************************************************************************************************/
+#include <iprt/string.h>
+#include "internal/iprt.h"
+
+
+RTDECL(int) RTStrCopy(char *pszDst, size_t cbDst, const char *pszSrc)
+{
+    size_t cchSrc = strlen(pszSrc);
+    if (RT_LIKELY(cchSrc < cbDst))
+    {
+        memcpy(pszDst, pszSrc, cchSrc + 1);
+        return VINF_SUCCESS;
+    }
+
+    if (cbDst != 0)
+    {
+        memcpy(pszDst, pszSrc, cbDst - 1);
+        pszDst[cbDst - 1] = '\0';
+    }
+    return VERR_BUFFER_OVERFLOW;
+}
+RT_EXPORT_SYMBOL(RTStrCopy);
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/vboxguest/common/string/RTStrCopyEx.c
@@ -0,0 +1,54 @@
+/* $Id: RTStrCopyEx.cpp $ */
+/** @file
+ * IPRT - RTStrCopyEx.
+ */
+
+/*
+ * Copyright (C) 2010-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+
+/*********************************************************************************************************************************
+*   Header Files                                                                                                                 *
+*********************************************************************************************************************************/
+#include <iprt/string.h>
+#include "internal/iprt.h"
+
+
+RTDECL(int) RTStrCopyEx(char *pszDst, size_t cbDst, const char *pszSrc, size_t cchMaxSrc)
+{
+    const char *pszSrcEol = RTStrEnd(pszSrc, cchMaxSrc);
+    size_t      cchSrc    = pszSrcEol ? (size_t)(pszSrcEol - pszSrc) : cchMaxSrc;
+    if (RT_LIKELY(cchSrc < cbDst))
+    {
+        memcpy(pszDst, pszSrc, cchSrc);
+        pszDst[cchSrc] = '\0';
+        return VINF_SUCCESS;
+    }
+
+    if (cbDst != 0)
+    {
+        memcpy(pszDst, pszSrc, cbDst - 1);
+        pszDst[cbDst - 1] = '\0';
+    }
+    return VERR_BUFFER_OVERFLOW;
+}
+RT_EXPORT_SYMBOL(RTStrCopyEx);
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/vboxguest/common/string/RTStrCopyP.c
@@ -0,0 +1,58 @@
+/* $Id: RTStrCopyP.cpp $ */
+/** @file
+ * IPRT - RTStrCopyP.
+ */
+
+/*
+ * Copyright (C) 2010-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+
+/*********************************************************************************************************************************
+*   Header Files                                                                                                                 *
+*********************************************************************************************************************************/
+#include <iprt/string.h>
+#include "internal/iprt.h"
+
+
+RTDECL(int) RTStrCopyP(char **ppszDst, size_t *pcbDst, const char *pszSrc)
+{
+    size_t const    cchSrc = strlen(pszSrc);
+    size_t const    cbDst  = *pcbDst;
+    char           *pszDst = *ppszDst;
+    if (RT_LIKELY(cchSrc < cbDst))
+    {
+        memcpy(pszDst, pszSrc, cchSrc + 1);
+        *ppszDst = pszDst += cchSrc;
+        *pcbDst -= cchSrc;
+        return VINF_SUCCESS;
+    }
+
+    if (cbDst != 0)
+    {
+        memcpy(*ppszDst, pszSrc, cbDst - 1);
+        *ppszDst = pszDst += cbDst - 1;
+        *pszDst  = '\0';
+        *pcbDst  = 1;
+    }
+    return VERR_BUFFER_OVERFLOW;
+}
+RT_EXPORT_SYMBOL(RTStrCopyP);
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/vboxguest/common/string/strformat.c
@@ -0,0 +1,858 @@
+/* $Id: strformat.cpp $ */
+/** @file
+ * IPRT - String Formatter.
+ */
+
+/*
+ * Copyright (C) 2006-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+
+/*********************************************************************************************************************************
+*   Defined Constants                                                                                                            *
+*********************************************************************************************************************************/
+#define ISDIGIT(c) ((c) >= '0' && (c) <= '9')
+/*#define MAX(a, b)  ((a) >= (b) ? (a) : (b))
+#define MIN(a, b)  ((a) < (b) ? (a) : (b)) */
+
+
+/*********************************************************************************************************************************
+*   Header Files                                                                                                                 *
+*********************************************************************************************************************************/
+#define LOG_GROUP RTLOGGROUP_STRING
+#include <iprt/string.h>
+#include "internal/iprt.h"
+
+#include <iprt/assert.h>
+#ifdef IN_RING3
+# include <iprt/alloc.h>
+# include <iprt/err.h>
+# include <iprt/uni.h>
+#endif
+#include <iprt/string.h>
+#include <iprt/stdarg.h>
+#include "internal/string.h"
+
+/* Wrappers for converting to iprt facilities. */
+#define SSToDS(ptr)     ptr
+#define kASSERT         Assert
+#define KENDIAN_LITTLE  1
+#define KENDIAN         KENDIAN_LITTLE
+#define KSIZE           size_t
+typedef struct
+{
+    uint32_t    ulLo;
+    uint32_t    ulHi;
+} KSIZE64;
+
+
+/*********************************************************************************************************************************
+*   Internal Functions                                                                                                           *
+*********************************************************************************************************************************/
+static unsigned _strnlen(const char *psz, unsigned cchMax);
+static unsigned _strnlenUtf16(PCRTUTF16 pwsz, unsigned cchMax);
+static int rtStrFormatNumber(char *psz, KSIZE64 ullValue, unsigned int uiBase, signed int cchWidth, signed int cchPrecision, unsigned int fFlags);
+
+
+/**
+ * Finds the length of a string up to cchMax.
+ * @returns   Length.
+ * @param     psz     Pointer to string.
+ * @param     cchMax  Max length.
+ */
+static unsigned _strnlen(const char *psz, unsigned cchMax)
+{
+    const char *pszC = psz;
+
+    while (cchMax-- > 0 &&  *psz != '\0')
+        psz++;
+
+    return (unsigned)(psz - pszC);
+}
+
+
+/**
+ * Finds the length of a string up to cchMax.
+ * @returns   Length.
+ * @param     pwsz    Pointer to string.
+ * @param     cchMax  Max length.
+ */
+static unsigned _strnlenUtf16(PCRTUTF16 pwsz, unsigned cchMax)
+{
+#ifdef IN_RING3
+    unsigned cwc = 0;
+    while (cchMax-- > 0)
+    {
+        RTUNICP cp;
+        int rc = RTUtf16GetCpEx(&pwsz, &cp);
+        AssertRC(rc);
+        if (RT_FAILURE(rc) || !cp)
+            break;
+        cwc++;
+    }
+    return cwc;
+#else   /* !IN_RING3 */
+    PCRTUTF16    pwszC = pwsz;
+
+    while (cchMax-- > 0 &&  *pwsz != '\0')
+        pwsz++;
+
+    return (unsigned)(pwsz - pwszC);
+#endif  /* !IN_RING3 */
+}
+
+
+/**
+ * Finds the length of a string up to cchMax.
+ * @returns   Length.
+ * @param     pusz    Pointer to string.
+ * @param     cchMax  Max length.
+ */
+static unsigned _strnlenUni(PCRTUNICP pusz, unsigned cchMax)
+{
+    PCRTUNICP   puszC = pusz;
+
+    while (cchMax-- > 0 && *pusz != '\0')
+        pusz++;
+
+    return (unsigned)(pusz - puszC);
+}
+
+
+/**
+ * Formats an integer number according to the parameters.
+ *
+ * @returns   Length of the formatted number.
+ * @param     psz            Pointer to output string buffer of sufficient size.
+ * @param     u64Value       Value to format.
+ * @param     uiBase         Number representation base.
+ * @param     cchWidth       Width.
+ * @param     cchPrecision   Precision.
+ * @param     fFlags         Flags (NTFS_*).
+ */
+RTDECL(int) RTStrFormatNumber(char *psz, uint64_t u64Value, unsigned int uiBase, signed int cchWidth, signed int cchPrecision,
+                              unsigned int fFlags)
+{
+    return rtStrFormatNumber(psz, *(KSIZE64 *)(void *)&u64Value, uiBase, cchWidth, cchPrecision, fFlags);
+}
+RT_EXPORT_SYMBOL(RTStrFormatNumber);
+
+
+
+/**
+ * Formats an integer number according to the parameters.
+ *
+ * @returns   Length of the number.
+ * @param     psz            Pointer to output string.
+ * @param     ullValue       Value. Using the high part is optional.
+ * @param     uiBase         Number representation base.
+ * @param     cchWidth       Width
+ * @param     cchPrecision   Precision.
+ * @param     fFlags         Flags (NTFS_*).
+ */
+static int rtStrFormatNumber(char *psz, KSIZE64 ullValue, unsigned int uiBase, signed int cchWidth, signed int cchPrecision,
+                             unsigned int fFlags)
+{
+    const char     *pachDigits = "0123456789abcdef";
+    char           *pszStart = psz;
+    int             cchMax;
+    int             cchValue;
+    unsigned long   ul;
+    int             i;
+    int             j;
+
+    /*
+     * Validate and adjust input...
+     */
+    Assert(uiBase >= 2 && uiBase <= 16);
+    if (fFlags & RTSTR_F_CAPITAL)
+        pachDigits = "0123456789ABCDEF";
+    if (fFlags & RTSTR_F_LEFT)
+        fFlags &= ~RTSTR_F_ZEROPAD;
+    if (    (fFlags & RTSTR_F_THOUSAND_SEP)
+        &&  (   uiBase != 10
+             || (fFlags & RTSTR_F_ZEROPAD))) /** @todo implement RTSTR_F_ZEROPAD + RTSTR_F_THOUSAND_SEP. */
+        fFlags &= ~RTSTR_F_THOUSAND_SEP;
+
+    /*
+     * Determine value length
+     */
+    cchValue = 0;
+    if (ullValue.ulHi || (fFlags & RTSTR_F_64BIT))
+    {
+        uint64_t    u64 = *(uint64_t *)(void *)&ullValue;
+        if ((fFlags & RTSTR_F_VALSIGNED) && (ullValue.ulHi & 0x80000000))
+            u64 = -(int64_t)u64;
+        do
+        {
+            cchValue++;
+            u64 /= uiBase;
+        } while (u64);
+    }
+    else
+    {
+        ul = (fFlags & RTSTR_F_VALSIGNED) && (ullValue.ulLo & 0x80000000) ? -(int32_t)ullValue.ulLo : ullValue.ulLo;
+        do
+        {
+            cchValue++;
+            ul /= uiBase;
+        } while (ul);
+    }
+    if (fFlags & RTSTR_F_THOUSAND_SEP)
+    {
+        if (cchValue <= 3)
+            fFlags &= ~RTSTR_F_THOUSAND_SEP;
+        else
+            cchValue += cchValue / 3 - (cchValue % 3 == 0);
+    }
+
+    /*
+     * Sign (+/-).
+     */
+    i = 0;
+    if (fFlags & RTSTR_F_VALSIGNED)
+    {
+        if ((ullValue.ulHi || (fFlags & RTSTR_F_64BIT) ? ullValue.ulHi : ullValue.ulLo) & 0x80000000)
+        {
+            ullValue.ulLo = -(int32_t)ullValue.ulLo;
+            if (ullValue.ulHi)
+                ullValue.ulHi = ~ullValue.ulHi;
+            psz[i++] = '-';
+        }
+        else if (fFlags & (RTSTR_F_PLUS | RTSTR_F_BLANK))
+            psz[i++] = (char)(fFlags & RTSTR_F_PLUS ? '+' : ' ');
+    }
+
+    /*
+     * Special (0/0x).
+     */
+    if ((fFlags & RTSTR_F_SPECIAL) && (uiBase % 8) == 0)
+    {
+        psz[i++] = '0';
+        if (uiBase == 16)
+            psz[i++] = (char)(fFlags & RTSTR_F_CAPITAL ? 'X' : 'x');
+    }
+
+    /*
+     * width - only if ZEROPAD
+     */
+    cchMax    = 64 - (cchValue + i + 1);   /* HACK! 64 bytes seems to be the usual buffer size... */
+    cchWidth -= i + cchValue;
+    if (fFlags & RTSTR_F_ZEROPAD)
+        while (--cchWidth >= 0 && i < cchMax)
+        {
+            AssertBreak(i < cchMax);
+            psz[i++] = '0';
+            cchPrecision--;
+        }
+    else if (!(fFlags & RTSTR_F_LEFT) && cchWidth > 0)
+    {
+        AssertStmt(cchWidth < cchMax, cchWidth = cchMax - 1);
+        for (j = i - 1; j >= 0; j--)
+            psz[cchWidth + j] = psz[j];
+        for (j = 0; j < cchWidth; j++)
+            psz[j] = ' ';
+        i += cchWidth;
+    }
+
+    /*
+     * precision
+     */
+    while (--cchPrecision >= cchValue)
+    {
+        AssertBreak(i < cchMax);
+        psz[i++] = '0';
+    }
+
+    psz += i;
+
+    /*
+     * write number - not good enough but it works
+     */
+    psz += cchValue;
+    i = -1;
+    if (ullValue.ulHi || (fFlags & RTSTR_F_64BIT))
+    {
+        uint64_t    u64 = *(uint64_t *)(void *)&ullValue;
+        if (fFlags & RTSTR_F_THOUSAND_SEP)
+        {
+            do
+            {
+                if ((-i - 1) % 4 == 3)
+                    psz[i--] = ' ';
+                psz[i--] = pachDigits[u64 % uiBase];
+                u64 /= uiBase;
+            } while (u64);
+        }
+        else
+        {
+            do
+            {
+                psz[i--] = pachDigits[u64 % uiBase];
+                u64 /= uiBase;
+            } while (u64);
+        }
+    }
+    else
+    {
+        ul = (fFlags & RTSTR_F_VALSIGNED) && (ullValue.ulLo & 0x80000000) ? -(int32_t)ullValue.ulLo : ullValue.ulLo;
+        if (fFlags & RTSTR_F_THOUSAND_SEP)
+        {
+            do
+            {
+                if ((-i - 1) % 4 == 3)
+                    psz[i--] = ' ';
+                psz[i--] = pachDigits[ul % uiBase];
+                ul /= uiBase;
+            } while (ul);
+        }
+        else
+        {
+            do
+            {
+                psz[i--] = pachDigits[ul % uiBase];
+                ul /= uiBase;
+            } while (ul);
+        }
+    }
+
+    /*
+     * width if RTSTR_F_LEFT
+     */
+    if (fFlags & RTSTR_F_LEFT)
+        while (--cchWidth >= 0)
+            *psz++ = ' ';
+
+    *psz = '\0';
+    return (unsigned)(psz - pszStart);
+}
+
+
+/**
+ * Partial implementation of a printf like formatter.
+ * It doesn't do everything correct, and there is no floating point support.
+ * However, it supports custom formats by the means of a format callback.
+ *
+ * @returns number of bytes formatted.
+ * @param   pfnOutput   Output worker.
+ *                      Called in two ways. Normally with a string an it's length.
+ *                      For termination, it's called with NULL for string, 0 for length.
+ * @param   pvArgOutput Argument to the output worker.
+ * @param   pfnFormat   Custom format worker.
+ * @param   pvArgFormat Argument to the format worker.
+ * @param   pszFormat   Format string.
+ * @param   InArgs      Argument list.
+ */
+RTDECL(size_t) RTStrFormatV(PFNRTSTROUTPUT pfnOutput, void *pvArgOutput, PFNSTRFORMAT pfnFormat, void *pvArgFormat,
+                            const char *pszFormat, va_list InArgs)
+{
+    va_list     args;
+    KSIZE       cch = 0;
+    const char *pszStartOutput = pszFormat;
+
+    va_copy(args, InArgs); /* make a copy so we can reference it (AMD64 / gcc). */
+
+    while (*pszFormat != '\0')
+    {
+        if (*pszFormat == '%')
+        {
+            /* output pending string. */
+            if (pszStartOutput != pszFormat)
+                cch += pfnOutput(pvArgOutput, pszStartOutput, pszFormat - pszStartOutput);
+
+            /* skip '%' */
+            pszFormat++;
+            if (*pszFormat == '%')    /* '%%'-> '%' */
+                pszStartOutput = pszFormat++;
+            else
+            {
+                unsigned int fFlags = 0;
+                int          cchWidth = -1;
+                int          cchPrecision = -1;
+                unsigned int uBase = 10;
+                char         chArgSize;
+
+                /* flags */
+                for (;;)
+                {
+                    switch (*pszFormat++)
+                    {
+                        case '#':   fFlags |= RTSTR_F_SPECIAL;      continue;
+                        case '-':   fFlags |= RTSTR_F_LEFT;         continue;
+                        case '+':   fFlags |= RTSTR_F_PLUS;         continue;
+                        case ' ':   fFlags |= RTSTR_F_BLANK;        continue;
+                        case '0':   fFlags |= RTSTR_F_ZEROPAD;      continue;
+                        case '\'':  fFlags |= RTSTR_F_THOUSAND_SEP; continue;
+                    }
+                    pszFormat--;
+                    break;
+                }
+
+                /* width */
+                if (ISDIGIT(*pszFormat))
+                {
+                    for (cchWidth = 0; ISDIGIT(*pszFormat); pszFormat++)
+                    {
+                        cchWidth *= 10;
+                        cchWidth += *pszFormat - '0';
+                    }
+                    fFlags |= RTSTR_F_WIDTH;
+                }
+                else if (*pszFormat == '*')
+                {
+                    pszFormat++;
+                    cchWidth = va_arg(args, int);
+                    if (cchWidth < 0)
+                    {
+                        cchWidth = -cchWidth;
+                        fFlags |= RTSTR_F_LEFT;
+                    }
+                    fFlags |= RTSTR_F_WIDTH;
+                }
+
+                /* precision */
+                if (*pszFormat == '.')
+                {
+                    pszFormat++;
+                    if (ISDIGIT(*pszFormat))
+                    {
+                        for (cchPrecision = 0; ISDIGIT(*pszFormat); pszFormat++)
+                        {
+                            cchPrecision *= 10;
+                            cchPrecision += *pszFormat - '0';
+                        }
+
+                    }
+                    else if (*pszFormat == '*')
+                    {
+                        pszFormat++;
+                        cchPrecision = va_arg(args, int);
+                    }
+                    if (cchPrecision < 0)
+                        cchPrecision = 0;
+                    fFlags |= RTSTR_F_PRECISION;
+                }
+
+                /*
+                 * Argument size.
+                 */
+                chArgSize = *pszFormat;
+                switch (chArgSize)
+                {
+                    default:
+                        chArgSize = 0;
+                        break;
+
+                    case 'z':
+                    case 'L':
+                    case 'j':
+                    case 't':
+                        pszFormat++;
+                        break;
+
+                    case 'l':
+                        pszFormat++;
+                        if (*pszFormat == 'l')
+                        {
+                            chArgSize = 'L';
+                            pszFormat++;
+                        }
+                        break;
+
+                    case 'h':
+                        pszFormat++;
+                        if (*pszFormat == 'h')
+                        {
+                            chArgSize = 'H';
+                            pszFormat++;
+                        }
+                        break;
+
+                    case 'I': /* Used by Win32/64 compilers. */
+                        if (   pszFormat[1] == '6'
+                            && pszFormat[2] == '4')
+                        {
+                            pszFormat += 3;
+                            chArgSize = 'L';
+                        }
+                        else if (   pszFormat[1] == '3'
+                                 && pszFormat[2] == '2')
+                        {
+                            pszFormat += 3;
+                            chArgSize = 0;
+                        }
+                        else
+                        {
+                            pszFormat += 1;
+                            chArgSize = 'j';
+                        }
+                        break;
+
+                    case 'q': /* Used on BSD platforms. */
+                        pszFormat++;
+                        chArgSize = 'L';
+                        break;
+                }
+
+                /*
+                 * The type.
+                 */
+                switch (*pszFormat++)
+                {
+                    /* char */
+                    case 'c':
+                    {
+                        char ch;
+
+                        if (!(fFlags & RTSTR_F_LEFT))
+                            while (--cchWidth > 0)
+                                cch += pfnOutput(pvArgOutput, " ", 1);
+
+                        ch = (char)va_arg(args, int);
+                        cch += pfnOutput(pvArgOutput, SSToDS(&ch), 1);
+
+                        while (--cchWidth > 0)
+                            cch += pfnOutput(pvArgOutput, " ", 1);
+                        break;
+                    }
+
+                    case 'S':   /* Legacy, conversion done by streams now. */
+                    case 's':
+                    {
+                        if (chArgSize == 'l')
+                        {
+                            /* utf-16 -> utf-8 */
+                            int         cchStr;
+                            PCRTUTF16   pwszStr = va_arg(args, PRTUTF16);
+
+                            if (!VALID_PTR(pwszStr))
+                            {
+                                static RTUTF16  s_wszNull[] = {'<', 'N', 'U', 'L', 'L', '>', '\0' };
+                                pwszStr = s_wszNull;
+                            }
+                            cchStr = _strnlenUtf16(pwszStr, (unsigned)cchPrecision);
+                            if (!(fFlags & RTSTR_F_LEFT))
+                                while (--cchWidth >= cchStr)
+                                    cch += pfnOutput(pvArgOutput, " ", 1);
+                            cchWidth -= cchStr;
+                            while (cchStr-- > 0)
+                            {
+/**@todo \#ifndef IN_RC*/
+#ifdef IN_RING3
+                                RTUNICP Cp;
+                                RTUtf16GetCpEx(&pwszStr, &Cp);
+                                char szUtf8[8]; /* Cp=0x7fffffff -> 6 bytes. */
+                                char *pszEnd = RTStrPutCp(szUtf8, Cp);
+                                cch += pfnOutput(pvArgOutput, szUtf8, pszEnd - szUtf8);
+#else
+                                char ch = (char)*pwszStr++;
+                                cch += pfnOutput(pvArgOutput, &ch, 1);
+#endif
+                            }
+                            while (--cchWidth >= 0)
+                                cch += pfnOutput(pvArgOutput, " ", 1);
+                        }
+                        else if (chArgSize == 'L')
+                        {
+                            /* unicp -> utf8 */
+                            int         cchStr;
+                            PCRTUNICP   puszStr = va_arg(args, PCRTUNICP);
+
+                            if (!VALID_PTR(puszStr))
+                            {
+                                static RTUNICP s_uszNull[] = {'<', 'N', 'U', 'L', 'L', '>', '\0' };
+                                puszStr = s_uszNull;
+                            }
+                            cchStr = _strnlenUni(puszStr, (unsigned)cchPrecision);
+                            if (!(fFlags & RTSTR_F_LEFT))
+                                while (--cchWidth >= cchStr)
+                                    cch += pfnOutput(pvArgOutput, " ", 1);
+
+                            cchWidth -= cchStr;
+                            while (cchStr-- > 0)
+                            {
+/**@todo \#ifndef IN_RC*/
+#ifdef IN_RING3
+                                char szUtf8[8]; /* Cp=0x7fffffff -> 6 bytes. */
+                                char *pszEnd = RTStrPutCp(szUtf8, *puszStr++);
+                                cch += pfnOutput(pvArgOutput, szUtf8, pszEnd - szUtf8);
+#else
+                                char ch = (char)*puszStr++;
+                                cch += pfnOutput(pvArgOutput, &ch, 1);
+#endif
+                            }
+                            while (--cchWidth >= 0)
+                                cch += pfnOutput(pvArgOutput, " ", 1);
+                        }
+                        else
+                        {
+                            int   cchStr;
+                            const char *pszStr = va_arg(args, char*);
+
+                            if (!VALID_PTR(pszStr))
+                                pszStr = "<NULL>";
+                            cchStr = _strnlen(pszStr, (unsigned)cchPrecision);
+                            if (!(fFlags & RTSTR_F_LEFT))
+                                while (--cchWidth >= cchStr)
+                                    cch += pfnOutput(pvArgOutput, " ", 1);
+
+                            cch += pfnOutput(pvArgOutput, pszStr, cchStr);
+
+                            while (--cchWidth >= cchStr)
+                                cch += pfnOutput(pvArgOutput, " ", 1);
+                        }
+                        break;
+                    }
+
+                    /*-----------------*/
+                    /* integer/pointer */
+                    /*-----------------*/
+                    case 'd':
+                    case 'i':
+                    case 'o':
+                    case 'p':
+                    case 'u':
+                    case 'x':
+                    case 'X':
+                    {
+                        char        achNum[64]; /* FIXME */
+                        int         cchNum;
+                        uint64_t    u64Value;
+
+                        switch (pszFormat[-1])
+                        {
+                            case 'd': /* signed decimal integer */
+                            case 'i':
+                                fFlags |= RTSTR_F_VALSIGNED;
+                                break;
+
+                            case 'o':
+                                uBase = 8;
+                                break;
+
+                            case 'p':
+                                fFlags |= RTSTR_F_ZEROPAD; /* Note not standard behaviour (but I like it this way!) */
+                                uBase = 16;
+                                if (cchWidth < 0)
+                                    cchWidth = sizeof(char *) * 2;
+                                break;
+
+                            case 'u':
+                                uBase = 10;
+                                break;
+
+                            case 'X':
+                                fFlags |= RTSTR_F_CAPITAL;
+                            case 'x':
+                                uBase = 16;
+                                break;
+                        }
+
+                        if (pszFormat[-1] == 'p')
+                            u64Value = va_arg(args, uintptr_t);
+                        else if (fFlags & RTSTR_F_VALSIGNED)
+                        {
+                            if (chArgSize == 'L')
+                            {
+                                u64Value = va_arg(args, int64_t);
+                                fFlags |= RTSTR_F_64BIT;
+                            }
+                            else if (chArgSize == 'l')
+                            {
+                                u64Value = va_arg(args, signed long);
+                                fFlags |= RTSTR_GET_BIT_FLAG(unsigned long);
+                            }
+                            else if (chArgSize == 'h')
+                            {
+                                u64Value = va_arg(args, /* signed short */ int);
+                                fFlags |= RTSTR_GET_BIT_FLAG(signed short);
+                            }
+                            else if (chArgSize == 'H')
+                            {
+                                u64Value = va_arg(args, /* int8_t */ int);
+                                fFlags |= RTSTR_GET_BIT_FLAG(int8_t);
+                            }
+                            else if (chArgSize == 'j')
+                            {
+                                u64Value = va_arg(args, /*intmax_t*/ int64_t);
+                                fFlags |= RTSTR_F_64BIT;
+                            }
+                            else if (chArgSize == 'z')
+                            {
+                                u64Value = va_arg(args, size_t);
+                                fFlags |= RTSTR_GET_BIT_FLAG(size_t);
+                            }
+                            else if (chArgSize == 't')
+                            {
+                                u64Value = va_arg(args, ptrdiff_t);
+                                fFlags |= RTSTR_GET_BIT_FLAG(ptrdiff_t);
+                            }
+                            else
+                            {
+                                u64Value = va_arg(args, signed int);
+                                fFlags |= RTSTR_GET_BIT_FLAG(signed int);
+                            }
+                        }
+                        else
+                        {
+                            if (chArgSize == 'L')
+                            {
+                                u64Value = va_arg(args, uint64_t);
+                                fFlags |= RTSTR_F_64BIT;
+                            }
+                            else if (chArgSize == 'l')
+                            {
+                                u64Value = va_arg(args, unsigned long);
+                                fFlags |= RTSTR_GET_BIT_FLAG(unsigned long);
+                            }
+                            else if (chArgSize == 'h')
+                            {
+                                u64Value = va_arg(args, /* unsigned short */ int);
+                                fFlags |= RTSTR_GET_BIT_FLAG(unsigned short);
+                            }
+                            else if (chArgSize == 'H')
+                            {
+                                u64Value = va_arg(args, /* uint8_t */ int);
+                                fFlags |= RTSTR_GET_BIT_FLAG(uint8_t);
+                            }
+                            else if (chArgSize == 'j')
+                            {
+                                u64Value = va_arg(args, /*uintmax_t*/ int64_t);
+                                fFlags |= RTSTR_F_64BIT;
+                            }
+                            else if (chArgSize == 'z')
+                            {
+                                u64Value = va_arg(args, size_t);
+                                fFlags |= RTSTR_GET_BIT_FLAG(size_t);
+                            }
+                            else if (chArgSize == 't')
+                            {
+                                u64Value = va_arg(args, ptrdiff_t);
+                                fFlags |= RTSTR_GET_BIT_FLAG(ptrdiff_t);
+                            }
+                            else
+                            {
+                                u64Value = va_arg(args, unsigned int);
+                                fFlags |= RTSTR_GET_BIT_FLAG(unsigned int);
+                            }
+                        }
+                        cchNum = RTStrFormatNumber((char *)SSToDS(&achNum), u64Value, uBase, cchWidth, cchPrecision, fFlags);
+                        cch += pfnOutput(pvArgOutput, (char *)SSToDS(&achNum), cchNum);
+                        break;
+                    }
+
+                    /*
+                     * Nested extensions.
+                     */
+                    case 'M': /* replace the format string (not stacked yet). */
+                    {
+                        pszStartOutput = pszFormat = va_arg(args, const char *);
+                        AssertPtr(pszStartOutput);
+                        break;
+                    }
+
+                    case 'N': /* real nesting. */
+                    {
+                        const char *pszFormatNested = va_arg(args, const char *);
+                        va_list    *pArgsNested     = va_arg(args, va_list *);
+                        va_list     ArgsNested;
+                        va_copy(ArgsNested, *pArgsNested);
+                        Assert(pszFormatNested);
+                        cch += RTStrFormatV(pfnOutput, pvArgOutput, pfnFormat, pvArgFormat, pszFormatNested, ArgsNested);
+                        va_end(ArgsNested);
+                        break;
+                    }
+
+                    /*
+                     * IPRT Extensions.
+                     */
+                    case 'R':
+                    {
+                        if (*pszFormat != '[')
+                        {
+                            pszFormat--;
+                            cch += rtstrFormatRt(pfnOutput, pvArgOutput, &pszFormat, &args, cchWidth, cchPrecision, fFlags, chArgSize);
+                        }
+                        else
+                        {
+                            pszFormat--;
+                            cch += rtstrFormatType(pfnOutput, pvArgOutput, &pszFormat, &args, cchWidth, cchPrecision, fFlags, chArgSize);
+                        }
+                        break;
+                    }
+
+                    /*
+                     * Custom format.
+                     */
+                    default:
+                    {
+                        if (pfnFormat)
+                        {
+                            pszFormat--;
+                            cch += pfnFormat(pvArgFormat, pfnOutput, pvArgOutput, &pszFormat, &args, cchWidth, cchPrecision, fFlags, chArgSize);
+                        }
+                        break;
+                    }
+                }
+                pszStartOutput = pszFormat;
+            }
+        }
+        else
+            pszFormat++;
+    }
+
+    /* output pending string. */
+    if (pszStartOutput != pszFormat)
+        cch += pfnOutput(pvArgOutput, pszStartOutput, pszFormat - pszStartOutput);
+
+    /* terminate the output */
+    pfnOutput(pvArgOutput, NULL, 0);
+
+    return cch;
+}
+RT_EXPORT_SYMBOL(RTStrFormatV);
+
+
+/**
+ * Partial implementation of a printf like formatter.
+ * It doesn't do everything correct, and there is no floating point support.
+ * However, it supports custom formats by the means of a format callback.
+ *
+ * @returns number of bytes formatted.
+ * @param   pfnOutput   Output worker.
+ *                      Called in two ways. Normally with a string an it's length.
+ *                      For termination, it's called with NULL for string, 0 for length.
+ * @param   pvArgOutput Argument to the output worker.
+ * @param   pfnFormat   Custom format worker.
+ * @param   pvArgFormat Argument to the format worker.
+ * @param   pszFormat   Format string.
+ * @param   ...         Argument list.
+ */
+RTDECL(size_t) RTStrFormat(PFNRTSTROUTPUT pfnOutput, void *pvArgOutput, PFNSTRFORMAT pfnFormat, void *pvArgFormat, const char *pszFormat, ...)
+{
+    size_t cch;
+    va_list args;
+    va_start(args, pszFormat);
+    cch = RTStrFormatV(pfnOutput, pvArgOutput, pfnFormat, pvArgFormat, pszFormat, args);
+    va_end(args);
+    return cch;
+}
+RT_EXPORT_SYMBOL(RTStrFormat);
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/vboxguest/common/string/strformatrt.c
@@ -0,0 +1,1238 @@
+/* $Id: strformatrt.cpp $ */
+/** @file
+ * IPRT - IPRT String Formatter Extensions.
+ */
+
+/*
+ * Copyright (C) 2006-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+
+/*********************************************************************************************************************************
+*   Header Files                                                                                                                 *
+*********************************************************************************************************************************/
+#define LOG_GROUP RTLOGGROUP_STRING
+#include <iprt/string.h>
+#ifndef RT_NO_EXPORT_SYMBOL
+# define RT_NO_EXPORT_SYMBOL /* don't slurp <linux/module.h> which then again
+                                slurps arch-specific headers defining symbols */
+#endif
+#include "internal/iprt.h"
+
+#include <iprt/log.h>
+#include <iprt/assert.h>
+#include <iprt/string.h>
+#include <iprt/stdarg.h>
+#ifdef IN_RING3
+# include <iprt/thread.h>
+# include <iprt/err.h>
+#endif
+#include <iprt/ctype.h>
+#include <iprt/time.h>
+#include <iprt/net.h>
+#include <iprt/path.h>
+#include <iprt/asm.h>
+#define STRFORMAT_WITH_X86
+#ifdef STRFORMAT_WITH_X86
+# include <iprt/x86.h>
+#endif
+#include "internal/string.h"
+
+
+/*********************************************************************************************************************************
+*   Global Variables                                                                                                             *
+*********************************************************************************************************************************/
+static char g_szHexDigits[17] = "0123456789abcdef";
+
+
+/**
+ * Helper that formats a 16-bit hex word in a IPv6 address.
+ *
+ * @returns Length in chars.
+ * @param   pszDst      The output buffer.  Written from the start.
+ * @param   uWord       The word to format as hex.
+ */
+static size_t rtstrFormatIPv6HexWord(char *pszDst, uint16_t uWord)
+{
+    size_t   off;
+    uint16_t cDigits;
+
+    if (uWord & UINT16_C(0xff00))
+        cDigits = uWord & UINT16_C(0xf000) ? 4 : 3;
+    else
+        cDigits = uWord & UINT16_C(0x00f0) ? 2 : 1;
+
+    off = 0;
+    switch (cDigits)
+    {
+        case 4: pszDst[off++] = g_szHexDigits[(uWord >> 12) & 0xf];
+        case 3: pszDst[off++] = g_szHexDigits[(uWord >>  8) & 0xf];
+        case 2: pszDst[off++] = g_szHexDigits[(uWord >>  4) & 0xf];
+        case 1: pszDst[off++] = g_szHexDigits[(uWord >>  0) & 0xf];
+            break;
+    }
+    pszDst[off] = '\0';
+    return off;
+}
+
+
+/**
+ * Helper function to format IPv6 address according to RFC 5952.
+ *
+ * @returns The number of bytes formatted.
+ * @param   pfnOutput       Pointer to output function.
+ * @param   pvArgOutput     Argument for the output function.
+ * @param   pIpv6Addr       IPv6 address
+ */
+static size_t rtstrFormatIPv6(PFNRTSTROUTPUT pfnOutput, void *pvArgOutput, PCRTNETADDRIPV6 pIpv6Addr)
+{
+    size_t cch; /* result */
+    bool   fEmbeddedIpv4;
+    size_t cwHexPart;
+    size_t cwLongestZeroRun;
+    size_t iLongestZeroStart;
+    size_t idx;
+    char   szHexWord[8];
+
+    Assert(pIpv6Addr != NULL);
+
+    /*
+     * Check for embedded IPv4 address.
+     *
+     * IPv4-compatible - ::11.22.33.44 (obsolete)
+     * IPv4-mapped     - ::ffff:11.22.33.44
+     * IPv4-translated - ::ffff:0:11.22.33.44 (RFC 2765)
+     */
+    fEmbeddedIpv4 = false;
+    cwHexPart = RT_ELEMENTS(pIpv6Addr->au16);
+    if (   pIpv6Addr->au64[0] == 0
+        && (   (   pIpv6Addr->au32[2] == 0
+                && pIpv6Addr->au32[3] != 0
+                && pIpv6Addr->au32[3] != RT_H2BE_U32_C(1) )
+            || pIpv6Addr->au32[2] == RT_H2BE_U32_C(0x0000ffff)
+            || pIpv6Addr->au32[2] == RT_H2BE_U32_C(0xffff0000) ) )
+    {
+        fEmbeddedIpv4 = true;
+        cwHexPart -= 2;
+    }
+
+    /*
+     * Find the longest sequences of two or more zero words.
+     */
+    cwLongestZeroRun  = 0;
+    iLongestZeroStart = 0;
+    for (idx = 0; idx < cwHexPart; idx++)
+        if (pIpv6Addr->au16[idx] == 0)
+        {
+            size_t iZeroStart = idx;
+            size_t cwZeroRun;
+            do
+                idx++;
+            while (idx < cwHexPart && pIpv6Addr->au16[idx] == 0);
+            cwZeroRun = idx - iZeroStart;
+            if (cwZeroRun > 1 && cwZeroRun > cwLongestZeroRun)
+            {
+                cwLongestZeroRun  = cwZeroRun;
+                iLongestZeroStart = iZeroStart;
+                if (cwZeroRun >= cwHexPart - idx)
+                    break;
+            }
+        }
+
+    /*
+     * Do the formatting.
+     */
+    cch = 0;
+    if (cwLongestZeroRun == 0)
+    {
+        for (idx = 0; idx < cwHexPart; ++idx)
+        {
+            if (idx > 0)
+                cch += pfnOutput(pvArgOutput, ":", 1);
+            cch += pfnOutput(pvArgOutput, szHexWord, rtstrFormatIPv6HexWord(szHexWord, RT_BE2H_U16(pIpv6Addr->au16[idx])));
+        }
+
+        if (fEmbeddedIpv4)
+            cch += pfnOutput(pvArgOutput, ":", 1);
+    }
+    else
+    {
+        const size_t iLongestZeroEnd = iLongestZeroStart + cwLongestZeroRun;
+
+        if (iLongestZeroStart == 0)
+            cch += pfnOutput(pvArgOutput, ":", 1);
+        else
+            for (idx = 0; idx < iLongestZeroStart; ++idx)
+            {
+                cch += pfnOutput(pvArgOutput, szHexWord, rtstrFormatIPv6HexWord(szHexWord, RT_BE2H_U16(pIpv6Addr->au16[idx])));
+                cch += pfnOutput(pvArgOutput, ":", 1);
+            }
+
+        if (iLongestZeroEnd == cwHexPart)
+            cch += pfnOutput(pvArgOutput, ":", 1);
+        else
+        {
+            for (idx = iLongestZeroEnd; idx < cwHexPart; ++idx)
+            {
+                cch += pfnOutput(pvArgOutput, ":", 1);
+                cch += pfnOutput(pvArgOutput, szHexWord, rtstrFormatIPv6HexWord(szHexWord, RT_BE2H_U16(pIpv6Addr->au16[idx])));
+            }
+
+            if (fEmbeddedIpv4)
+                cch += pfnOutput(pvArgOutput, ":", 1);
+        }
+    }
+
+    if (fEmbeddedIpv4)
+        cch += RTStrFormat(pfnOutput, pvArgOutput, NULL, 0,
+                           "%u.%u.%u.%u",
+                           pIpv6Addr->au8[12],
+                           pIpv6Addr->au8[13],
+                           pIpv6Addr->au8[14],
+                           pIpv6Addr->au8[15]);
+
+    return cch;
+}
+
+
+/**
+ * Callback to format iprt formatting extentions.
+ * See @ref pg_rt_str_format for a reference on the format types.
+ *
+ * @returns The number of bytes formatted.
+ * @param   pfnOutput       Pointer to output function.
+ * @param   pvArgOutput     Argument for the output function.
+ * @param   ppszFormat      Pointer to the format string pointer. Advance this till the char
+ *                          after the format specifier.
+ * @param   pArgs           Pointer to the argument list. Use this to fetch the arguments.
+ * @param   cchWidth        Format Width. -1 if not specified.
+ * @param   cchPrecision    Format Precision. -1 if not specified.
+ * @param   fFlags          Flags (RTSTR_NTFS_*).
+ * @param   chArgSize       The argument size specifier, 'l' or 'L'.
+ */
+DECLHIDDEN(size_t) rtstrFormatRt(PFNRTSTROUTPUT pfnOutput, void *pvArgOutput, const char **ppszFormat, va_list *pArgs,
+                                 int cchWidth, int cchPrecision, unsigned fFlags, char chArgSize)
+{
+    const char *pszFormatOrg = *ppszFormat;
+    char        ch = *(*ppszFormat)++;
+    size_t      cch;
+    char        szBuf[80];
+
+    if (ch == 'R')
+    {
+        ch = *(*ppszFormat)++;
+        switch (ch)
+        {
+            /*
+             * Groups 1 and 2.
+             */
+            case 'T':
+            case 'G':
+            case 'H':
+            case 'R':
+            case 'C':
+            case 'I':
+            case 'X':
+            case 'U':
+            {
+                /*
+                 * Interpret the type.
+                 */
+                typedef enum
+                {
+                    RTSF_INT,
+                    RTSF_INTW,
+                    RTSF_BOOL,
+                    RTSF_FP16,
+                    RTSF_FP32,
+                    RTSF_FP64,
+                    RTSF_IPV4,
+                    RTSF_IPV6,
+                    RTSF_MAC,
+                    RTSF_NETADDR,
+                    RTSF_UUID
+                } RTSF;
+                static const struct
+                {
+                    uint8_t     cch;        /**< the length of the string. */
+                    char        sz[10];     /**< the part following 'R'. */
+                    uint8_t     cb;         /**< the size of the type. */
+                    uint8_t     u8Base;     /**< the size of the type. */
+                    RTSF        enmFormat;  /**< The way to format it. */
+                    uint16_t    fFlags;     /**< additional RTSTR_F_* flags. */
+                }
+                /** Sorted array of types, looked up using binary search! */
+                s_aTypes[] =
+                {
+#define STRMEM(str) sizeof(str) - 1, str
+                    { STRMEM("Ci"),      sizeof(RTINT),          10, RTSF_INT,   RTSTR_F_VALSIGNED },
+                    { STRMEM("Cp"),      sizeof(RTCCPHYS),       16, RTSF_INTW,  0 },
+                    { STRMEM("Cr"),      sizeof(RTCCUINTREG),    16, RTSF_INTW,  0 },
+                    { STRMEM("Cu"),      sizeof(RTUINT),         10, RTSF_INT,   0 },
+                    { STRMEM("Cv"),      sizeof(void *),         16, RTSF_INTW,  0 },
+                    { STRMEM("Cx"),      sizeof(RTUINT),         16, RTSF_INT,   0 },
+                    { STRMEM("Gi"),      sizeof(RTGCINT),        10, RTSF_INT,   RTSTR_F_VALSIGNED },
+                    { STRMEM("Gp"),      sizeof(RTGCPHYS),       16, RTSF_INTW,  0 },
+                    { STRMEM("Gr"),      sizeof(RTGCUINTREG),    16, RTSF_INTW,  0 },
+                    { STRMEM("Gu"),      sizeof(RTGCUINT),       10, RTSF_INT,   0 },
+                    { STRMEM("Gv"),      sizeof(RTGCPTR),        16, RTSF_INTW,  0 },
+                    { STRMEM("Gx"),      sizeof(RTGCUINT),       16, RTSF_INT,   0 },
+                    { STRMEM("Hi"),      sizeof(RTHCINT),        10, RTSF_INT,   RTSTR_F_VALSIGNED },
+                    { STRMEM("Hp"),      sizeof(RTHCPHYS),       16, RTSF_INTW,  0 },
+                    { STRMEM("Hr"),      sizeof(RTHCUINTREG),    16, RTSF_INTW,  0 },
+                    { STRMEM("Hu"),      sizeof(RTHCUINT),       10, RTSF_INT,   0 },
+                    { STRMEM("Hv"),      sizeof(RTHCPTR),        16, RTSF_INTW,  0 },
+                    { STRMEM("Hx"),      sizeof(RTHCUINT),       16, RTSF_INT,   0 },
+                    { STRMEM("I16"),     sizeof(int16_t),        10, RTSF_INT,   RTSTR_F_VALSIGNED },
+                    { STRMEM("I32"),     sizeof(int32_t),        10, RTSF_INT,   RTSTR_F_VALSIGNED },
+                    { STRMEM("I64"),     sizeof(int64_t),        10, RTSF_INT,   RTSTR_F_VALSIGNED },
+                    { STRMEM("I8"),      sizeof(int8_t),         10, RTSF_INT,   RTSTR_F_VALSIGNED },
+                    { STRMEM("Rv"),      sizeof(RTRCPTR),        16, RTSF_INTW,  0 },
+                    { STRMEM("Tbool"),   sizeof(bool),           10, RTSF_BOOL,  0 },
+                    { STRMEM("Tfile"),   sizeof(RTFILE),         10, RTSF_INT,   0 },
+                    { STRMEM("Tfmode"),  sizeof(RTFMODE),        16, RTSF_INTW,  0 },
+                    { STRMEM("Tfoff"),   sizeof(RTFOFF),         10, RTSF_INT,   RTSTR_F_VALSIGNED },
+                    { STRMEM("Tfp16"),   sizeof(RTFAR16),        16, RTSF_FP16,  RTSTR_F_ZEROPAD },
+                    { STRMEM("Tfp32"),   sizeof(RTFAR32),        16, RTSF_FP32,  RTSTR_F_ZEROPAD },
+                    { STRMEM("Tfp64"),   sizeof(RTFAR64),        16, RTSF_FP64,  RTSTR_F_ZEROPAD },
+                    { STRMEM("Tgid"),    sizeof(RTGID),          10, RTSF_INT,   RTSTR_F_VALSIGNED },
+                    { STRMEM("Tino"),    sizeof(RTINODE),        16, RTSF_INTW,  0 },
+                    { STRMEM("Tint"),    sizeof(RTINT),          10, RTSF_INT,   RTSTR_F_VALSIGNED },
+                    { STRMEM("Tiop"),    sizeof(RTIOPORT),       16, RTSF_INTW,  0 },
+                    { STRMEM("Tldrm"),   sizeof(RTLDRMOD),       16, RTSF_INTW,  0 },
+                    { STRMEM("Tmac"),    sizeof(PCRTMAC),        16, RTSF_MAC,   0 },
+                    { STRMEM("Tnaddr"),  sizeof(PCRTNETADDR),    10, RTSF_NETADDR,0 },
+                    { STRMEM("Tnaipv4"), sizeof(RTNETADDRIPV4),  10, RTSF_IPV4,  0 },
+                    { STRMEM("Tnaipv6"), sizeof(PCRTNETADDRIPV6),16, RTSF_IPV6,  0 },
+                    { STRMEM("Tnthrd"),  sizeof(RTNATIVETHREAD), 16, RTSF_INTW,  0 },
+                    { STRMEM("Tproc"),   sizeof(RTPROCESS),      16, RTSF_INTW,  0 },
+                    { STRMEM("Tptr"),    sizeof(RTUINTPTR),      16, RTSF_INTW,  0 },
+                    { STRMEM("Treg"),    sizeof(RTCCUINTREG),    16, RTSF_INTW,  0 },
+                    { STRMEM("Tsel"),    sizeof(RTSEL),          16, RTSF_INTW,  0 },
+                    { STRMEM("Tsem"),    sizeof(RTSEMEVENT),     16, RTSF_INTW,  0 },
+                    { STRMEM("Tsock"),   sizeof(RTSOCKET),       10, RTSF_INT,   0 },
+                    { STRMEM("Tthrd"),   sizeof(RTTHREAD),       16, RTSF_INTW,  0 },
+                    { STRMEM("Tuid"),    sizeof(RTUID),          10, RTSF_INT,   RTSTR_F_VALSIGNED },
+                    { STRMEM("Tuint"),   sizeof(RTUINT),         10, RTSF_INT,   0 },
+                    { STRMEM("Tunicp"),  sizeof(RTUNICP),        16, RTSF_INTW,  RTSTR_F_ZEROPAD },
+                    { STRMEM("Tutf16"),  sizeof(RTUTF16),        16, RTSF_INTW,  RTSTR_F_ZEROPAD },
+                    { STRMEM("Tuuid"),   sizeof(PCRTUUID),       16, RTSF_UUID,  0 },
+                    { STRMEM("Txint"),   sizeof(RTUINT),         16, RTSF_INT,   0 },
+                    { STRMEM("U16"),     sizeof(uint16_t),       10, RTSF_INT,   0 },
+                    { STRMEM("U32"),     sizeof(uint32_t),       10, RTSF_INT,   0 },
+                    { STRMEM("U64"),     sizeof(uint64_t),       10, RTSF_INT,   0 },
+                    { STRMEM("U8"),      sizeof(uint8_t),        10, RTSF_INT,   0 },
+                    { STRMEM("X16"),     sizeof(uint16_t),       16, RTSF_INT,   0 },
+                    { STRMEM("X32"),     sizeof(uint32_t),       16, RTSF_INT,   0 },
+                    { STRMEM("X64"),     sizeof(uint64_t),       16, RTSF_INT,   0 },
+                    { STRMEM("X8"),      sizeof(uint8_t),        16, RTSF_INT,   0 },
+#undef STRMEM
+                };
+                static const char s_szNull[] = "<NULL>";
+
+                const char *pszType = *ppszFormat - 1;
+                int         iStart  = 0;
+                int         iEnd    = RT_ELEMENTS(s_aTypes) - 1;
+                int         i       = RT_ELEMENTS(s_aTypes) / 2;
+
+                union
+                {
+                    uint8_t             u8;
+                    uint16_t            u16;
+                    uint32_t            u32;
+                    uint64_t            u64;
+                    int8_t              i8;
+                    int16_t             i16;
+                    int32_t             i32;
+                    int64_t             i64;
+                    RTFAR16             fp16;
+                    RTFAR32             fp32;
+                    RTFAR64             fp64;
+                    bool                fBool;
+                    PCRTMAC             pMac;
+                    RTNETADDRIPV4       Ipv4Addr;
+                    PCRTNETADDRIPV6     pIpv6Addr;
+                    PCRTNETADDR         pNetAddr;
+                    PCRTUUID            pUuid;
+                } u;
+
+                AssertMsg(!chArgSize, ("Not argument size '%c' for RT types! '%.10s'\n", chArgSize, pszFormatOrg));
+
+                /*
+                 * Lookup the type - binary search.
+                 */
+                for (;;)
+                {
+                    int iDiff = strncmp(pszType, s_aTypes[i].sz, s_aTypes[i].cch);
+                    if (!iDiff)
+                        break;
+                    if (iEnd == iStart)
+                    {
+                        AssertMsgFailed(("Invalid format type '%.10s'!\n", pszFormatOrg));
+                        return 0;
+                    }
+                    if (iDiff < 0)
+                        iEnd = i - 1;
+                    else
+                        iStart = i + 1;
+                    if (iEnd < iStart)
+                    {
+                        AssertMsgFailed(("Invalid format type '%.10s'!\n", pszFormatOrg));
+                        return 0;
+                    }
+                    i = iStart + (iEnd - iStart) / 2;
+                }
+
+                /*
+                 * Advance the format string and merge flags.
+                 */
+                *ppszFormat += s_aTypes[i].cch - 1;
+                fFlags |= s_aTypes[i].fFlags;
+
+                /*
+                 * Fetch the argument.
+                 * It's important that a signed value gets sign-extended up to 64-bit.
+                 */
+                RT_ZERO(u);
+                if (fFlags & RTSTR_F_VALSIGNED)
+                {
+                    switch (s_aTypes[i].cb)
+                    {
+                        case sizeof(int8_t):
+                            u.i64 = va_arg(*pArgs, /*int8_t*/int);
+                            fFlags |= RTSTR_F_8BIT;
+                            break;
+                        case sizeof(int16_t):
+                            u.i64 = va_arg(*pArgs, /*int16_t*/int);
+                            fFlags |= RTSTR_F_16BIT;
+                            break;
+                        case sizeof(int32_t):
+                            u.i64 = va_arg(*pArgs, int32_t);
+                            fFlags |= RTSTR_F_32BIT;
+                            break;
+                        case sizeof(int64_t):
+                            u.i64 = va_arg(*pArgs, int64_t);
+                            fFlags |= RTSTR_F_64BIT;
+                            break;
+                        default:
+                            AssertMsgFailed(("Invalid format error, size %d'!\n", s_aTypes[i].cb));
+                            break;
+                    }
+                }
+                else
+                {
+                    switch (s_aTypes[i].cb)
+                    {
+                        case sizeof(uint8_t):
+                            u.u8 = va_arg(*pArgs, /*uint8_t*/unsigned);
+                            fFlags |= RTSTR_F_8BIT;
+                            break;
+                        case sizeof(uint16_t):
+                            u.u16 = va_arg(*pArgs, /*uint16_t*/unsigned);
+                            fFlags |= RTSTR_F_16BIT;
+                            break;
+                        case sizeof(uint32_t):
+                            u.u32 = va_arg(*pArgs, uint32_t);
+                            fFlags |= RTSTR_F_32BIT;
+                            break;
+                        case sizeof(uint64_t):
+                            u.u64 = va_arg(*pArgs, uint64_t);
+                            fFlags |= RTSTR_F_64BIT;
+                            break;
+                        case sizeof(RTFAR32):
+                            u.fp32 = va_arg(*pArgs, RTFAR32);
+                            break;
+                        case sizeof(RTFAR64):
+                            u.fp64 = va_arg(*pArgs, RTFAR64);
+                            break;
+                        default:
+                            AssertMsgFailed(("Invalid format error, size %d'!\n", s_aTypes[i].cb));
+                            break;
+                    }
+                }
+
+                /*
+                 * Format the output.
+                 */
+                switch (s_aTypes[i].enmFormat)
+                {
+                    case RTSF_INT:
+                    {
+                        cch = RTStrFormatNumber(szBuf, u.u64, s_aTypes[i].u8Base, cchWidth, cchPrecision, fFlags);
+                        break;
+                    }
+
+                    /* hex which defaults to max width. */
+                    case RTSF_INTW:
+                    {
+                        Assert(s_aTypes[i].u8Base == 16);
+                        if (cchWidth < 0)
+                        {
+                            cchWidth = s_aTypes[i].cb * 2 + (fFlags & RTSTR_F_SPECIAL ? 2 : 0);
+                            fFlags |= RTSTR_F_ZEROPAD;
+                        }
+                        cch = RTStrFormatNumber(szBuf, u.u64, s_aTypes[i].u8Base, cchWidth, cchPrecision, fFlags);
+                        break;
+                    }
+
+                    case RTSF_BOOL:
+                    {
+                        static const char s_szTrue[]  = "true ";
+                        static const char s_szFalse[] = "false";
+                        if (u.u64 == 1)
+                            return pfnOutput(pvArgOutput, s_szTrue,  sizeof(s_szTrue) - 1);
+                        if (u.u64 == 0)
+                            return pfnOutput(pvArgOutput, s_szFalse, sizeof(s_szFalse) - 1);
+                        /* invalid boolean value */
+                        return RTStrFormat(pfnOutput, pvArgOutput, NULL, 0, "!%lld!", u.u64);
+                    }
+
+                    case RTSF_FP16:
+                    {
+                        fFlags &= ~(RTSTR_F_VALSIGNED | RTSTR_F_BIT_MASK | RTSTR_F_WIDTH | RTSTR_F_PRECISION | RTSTR_F_THOUSAND_SEP);
+                        cch = RTStrFormatNumber(&szBuf[0], u.fp16.sel, 16, 4, -1, fFlags | RTSTR_F_16BIT);
+                        Assert(cch == 4);
+                        szBuf[4] = ':';
+                        cch = RTStrFormatNumber(&szBuf[5], u.fp16.off, 16, 4, -1, fFlags | RTSTR_F_16BIT);
+                        Assert(cch == 4);
+                        cch = 4 + 1 + 4;
+                        break;
+                    }
+                    case RTSF_FP32:
+                    {
+                        fFlags &= ~(RTSTR_F_VALSIGNED | RTSTR_F_BIT_MASK | RTSTR_F_WIDTH | RTSTR_F_PRECISION | RTSTR_F_THOUSAND_SEP);
+                        cch = RTStrFormatNumber(&szBuf[0], u.fp32.sel, 16, 4, -1, fFlags | RTSTR_F_16BIT);
+                        Assert(cch == 4);
+                        szBuf[4] = ':';
+                        cch = RTStrFormatNumber(&szBuf[5], u.fp32.off, 16, 8, -1, fFlags | RTSTR_F_32BIT);
+                        Assert(cch == 8);
+                        cch = 4 + 1 + 8;
+                        break;
+                    }
+                    case RTSF_FP64:
+                    {
+                        fFlags &= ~(RTSTR_F_VALSIGNED | RTSTR_F_BIT_MASK | RTSTR_F_WIDTH | RTSTR_F_PRECISION | RTSTR_F_THOUSAND_SEP);
+                        cch = RTStrFormatNumber(&szBuf[0], u.fp64.sel, 16, 4, -1, fFlags | RTSTR_F_16BIT);
+                        Assert(cch == 4);
+                        szBuf[4] = ':';
+                        cch = RTStrFormatNumber(&szBuf[5], u.fp64.off, 16, 16, -1, fFlags | RTSTR_F_64BIT);
+                        Assert(cch == 16);
+                        cch = 4 + 1 + 16;
+                        break;
+                    }
+
+                    case RTSF_IPV4:
+                        return RTStrFormat(pfnOutput, pvArgOutput, NULL, 0,
+                                           "%u.%u.%u.%u",
+                                           u.Ipv4Addr.au8[0],
+                                           u.Ipv4Addr.au8[1],
+                                           u.Ipv4Addr.au8[2],
+                                           u.Ipv4Addr.au8[3]);
+
+                    case RTSF_IPV6:
+                    {
+                        if (VALID_PTR(u.pIpv6Addr))
+                            return rtstrFormatIPv6(pfnOutput, pvArgOutput, u.pIpv6Addr);
+                        return pfnOutput(pvArgOutput, s_szNull, sizeof(s_szNull) - 1);
+                    }
+
+                    case RTSF_MAC:
+                    {
+                        if (VALID_PTR(u.pMac))
+                            return RTStrFormat(pfnOutput, pvArgOutput, NULL, 0,
+                                               "%02x:%02x:%02x:%02x:%02x:%02x",
+                                               u.pMac->au8[0],
+                                               u.pMac->au8[1],
+                                               u.pMac->au8[2],
+                                               u.pMac->au8[3],
+                                               u.pMac->au8[4],
+                                               u.pMac->au8[5]);
+                        return pfnOutput(pvArgOutput, s_szNull, sizeof(s_szNull) - 1);
+                    }
+
+                    case RTSF_NETADDR:
+                    {
+                        if (VALID_PTR(u.pNetAddr))
+                        {
+                            switch (u.pNetAddr->enmType)
+                            {
+                                case RTNETADDRTYPE_IPV4:
+                                    if (u.pNetAddr->uPort == RTNETADDR_PORT_NA)
+                                        return RTStrFormat(pfnOutput, pvArgOutput, NULL, 0,
+                                                           "%u.%u.%u.%u",
+                                                           u.pNetAddr->uAddr.IPv4.au8[0],
+                                                           u.pNetAddr->uAddr.IPv4.au8[1],
+                                                           u.pNetAddr->uAddr.IPv4.au8[2],
+                                                           u.pNetAddr->uAddr.IPv4.au8[3]);
+                                    return RTStrFormat(pfnOutput, pvArgOutput, NULL, 0,
+                                                       "%u.%u.%u.%u:%u",
+                                                       u.pNetAddr->uAddr.IPv4.au8[0],
+                                                       u.pNetAddr->uAddr.IPv4.au8[1],
+                                                       u.pNetAddr->uAddr.IPv4.au8[2],
+                                                       u.pNetAddr->uAddr.IPv4.au8[3],
+                                                       u.pNetAddr->uPort);
+
+                                case RTNETADDRTYPE_IPV6:
+                                    if (u.pNetAddr->uPort == RTNETADDR_PORT_NA)
+                                        return rtstrFormatIPv6(pfnOutput, pvArgOutput, &u.pNetAddr->uAddr.IPv6);
+
+                                    return RTStrFormat(pfnOutput, pvArgOutput, NULL, 0,
+                                                       "[%RTnaipv6]:%u",
+                                                       &u.pNetAddr->uAddr.IPv6,
+                                                       u.pNetAddr->uPort);
+
+                                case RTNETADDRTYPE_MAC:
+                                    return RTStrFormat(pfnOutput, pvArgOutput, NULL, 0,
+                                                       "%02x:%02x:%02x:%02x:%02x:%02x",
+                                                       u.pNetAddr->uAddr.Mac.au8[0],
+                                                       u.pNetAddr->uAddr.Mac.au8[1],
+                                                       u.pNetAddr->uAddr.Mac.au8[2],
+                                                       u.pNetAddr->uAddr.Mac.au8[3],
+                                                       u.pNetAddr->uAddr.Mac.au8[4],
+                                                       u.pNetAddr->uAddr.Mac.au8[5]);
+
+                                default:
+                                    return RTStrFormat(pfnOutput, pvArgOutput, NULL, 0,
+                                                       "unsupported-netaddr-type=%u", u.pNetAddr->enmType);
+
+                            }
+                        }
+                        return pfnOutput(pvArgOutput, s_szNull, sizeof(s_szNull) - 1);
+                    }
+
+                    case RTSF_UUID:
+                    {
+                        if (VALID_PTR(u.pUuid))
+                        {
+                            /* cannot call RTUuidToStr because of GC/R0. */
+                            return RTStrFormat(pfnOutput, pvArgOutput, NULL, 0,
+                                               "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
+                                               RT_H2LE_U32(u.pUuid->Gen.u32TimeLow),
+                                               RT_H2LE_U16(u.pUuid->Gen.u16TimeMid),
+                                               RT_H2LE_U16(u.pUuid->Gen.u16TimeHiAndVersion),
+                                               u.pUuid->Gen.u8ClockSeqHiAndReserved,
+                                               u.pUuid->Gen.u8ClockSeqLow,
+                                               u.pUuid->Gen.au8Node[0],
+                                               u.pUuid->Gen.au8Node[1],
+                                               u.pUuid->Gen.au8Node[2],
+                                               u.pUuid->Gen.au8Node[3],
+                                               u.pUuid->Gen.au8Node[4],
+                                               u.pUuid->Gen.au8Node[5]);
+                        }
+                        return pfnOutput(pvArgOutput, s_szNull, sizeof(s_szNull) - 1);
+                    }
+
+                    default:
+                        AssertMsgFailed(("Internal error %d\n", s_aTypes[i].enmFormat));
+                        return 0;
+                }
+
+                /*
+                 * Finally, output the formatted string and return.
+                 */
+                return pfnOutput(pvArgOutput, szBuf, cch);
+            }
+
+
+            /* Group 3 */
+
+            /*
+             * Base name printing.
+             */
+            case 'b':
+            {
+                switch (*(*ppszFormat)++)
+                {
+                    case 'n':
+                    {
+                        const char *pszLastSep;
+                        const char *psz = pszLastSep = va_arg(*pArgs, const char *);
+                        if (!VALID_PTR(psz))
+                            return pfnOutput(pvArgOutput, RT_STR_TUPLE("<null>"));
+
+                        while ((ch = *psz) != '\0')
+                        {
+                            if (RTPATH_IS_SEP(ch))
+                            {
+                                do
+                                    psz++;
+                                while ((ch = *psz) != '\0' && RTPATH_IS_SEP(ch));
+                                if (!ch)
+                                    break;
+                                pszLastSep = psz;
+                            }
+                            psz++;
+                        }
+
+                        return pfnOutput(pvArgOutput, pszLastSep, psz - pszLastSep);
+                    }
+
+                    default:
+                        AssertMsgFailed(("Invalid status code format type '%.10s'!\n", pszFormatOrg));
+                        break;
+                }
+                break;
+            }
+
+
+            /*
+             * Pretty function / method name printing.
+             */
+            case 'f':
+            {
+                switch (*(*ppszFormat)++)
+                {
+                    /*
+                     * Pretty function / method name printing.
+                     * This isn't 100% right (see classic signal prototype) and it assumes
+                     * standardized names, but it'll do for today.
+                     */
+                    case 'n':
+                    {
+                        const char *pszStart;
+                        const char *psz = pszStart = va_arg(*pArgs, const char *);
+                        if (!VALID_PTR(psz))
+                            return pfnOutput(pvArgOutput, RT_STR_TUPLE("<null>"));
+
+                        while ((ch = *psz) != '\0' && ch != '(')
+                        {
+                            if (RT_C_IS_BLANK(ch))
+                            {
+                                psz++;
+                                while ((ch = *psz) != '\0' && (RT_C_IS_BLANK(ch) || ch == '('))
+                                    psz++;
+                                if (ch)
+                                    pszStart = psz;
+                            }
+                            else if (ch == '(')
+                                break;
+                            else
+                                psz++;
+                        }
+
+                        return pfnOutput(pvArgOutput, pszStart, psz - pszStart);
+                    }
+
+                    default:
+                        AssertMsgFailed(("Invalid status code format type '%.10s'!\n", pszFormatOrg));
+                        break;
+                }
+                break;
+            }
+
+
+            /*
+             * hex dumping and COM/XPCOM.
+             */
+            case 'h':
+            {
+                switch (*(*ppszFormat)++)
+                {
+                    /*
+                     * Hex stuff.
+                     */
+                    case 'x':
+                    {
+                        uint8_t *pu8 = va_arg(*pArgs, uint8_t *);
+                        if (cchPrecision < 0)
+                            cchPrecision = 16;
+                        if (pu8)
+                        {
+                            switch (*(*ppszFormat)++)
+                            {
+                                /*
+                                 * Regular hex dump.
+                                 */
+                                case 'd':
+                                {
+                                    int off = 0;
+                                    cch = 0;
+
+                                    if (cchWidth <= 0)
+                                        cchWidth = 16;
+
+                                    while (off < cchPrecision)
+                                    {
+                                        int i;
+                                        cch += RTStrFormat(pfnOutput, pvArgOutput, NULL, 0, "%s%0*p %04x:", off ? "\n" : "", sizeof(pu8) * 2, (uintptr_t)pu8, off);
+                                        for (i = 0; i < cchWidth && off + i < cchPrecision ; i++)
+                                            cch += RTStrFormat(pfnOutput, pvArgOutput, NULL, 0,
+                                                               off + i < cchPrecision ? !(i & 7) && i ? "-%02x" : " %02x" : "   ", pu8[i]);
+                                        while (i++ < cchWidth)
+                                            cch += pfnOutput(pvArgOutput, "   ", 3);
+
+                                        cch += pfnOutput(pvArgOutput, " ", 1);
+
+                                        for (i = 0; i < cchWidth && off + i < cchPrecision; i++)
+                                        {
+                                            uint8_t u8 = pu8[i];
+                                            cch += pfnOutput(pvArgOutput, u8 < 127 && u8 >= 32 ? (const char *)&u8 : ".", 1);
+                                        }
+
+                                        /* next */
+                                        pu8 += cchWidth;
+                                        off += cchWidth;
+                                    }
+                                    return cch;
+                                }
+
+                                /*
+                                 * Hex string.
+                                 */
+                                case 's':
+                                {
+                                    if (cchPrecision-- > 0)
+                                    {
+                                        cch = RTStrFormat(pfnOutput, pvArgOutput, NULL, 0, "%02x", *pu8++);
+                                        for (; cchPrecision > 0; cchPrecision--, pu8++)
+                                            cch += RTStrFormat(pfnOutput, pvArgOutput, NULL, 0, " %02x", *pu8);
+                                        return cch;
+                                    }
+                                    break;
+                                }
+
+                                default:
+                                    AssertMsgFailed(("Invalid status code format type '%.10s'!\n", pszFormatOrg));
+                                    break;
+                            }
+                        }
+                        else
+                            return pfnOutput(pvArgOutput, RT_STR_TUPLE("<null>"));
+                        break;
+                    }
+
+
+#ifdef IN_RING3
+                    /*
+                     * XPCOM / COM status code: %Rhrc, %Rhrf, %Rhra
+                     * ASSUMES: If Windows Then COM else XPCOM.
+                     */
+                    case 'r':
+                    {
+                        uint32_t hrc = va_arg(*pArgs, uint32_t);
+                        PCRTCOMERRMSG pMsg = RTErrCOMGet(hrc);
+                        switch (*(*ppszFormat)++)
+                        {
+                            case 'c':
+                                return pfnOutput(pvArgOutput, pMsg->pszDefine, strlen(pMsg->pszDefine));
+                            case 'f':
+                                return pfnOutput(pvArgOutput, pMsg->pszMsgFull,strlen(pMsg->pszMsgFull));
+                            case 'a':
+                                return RTStrFormat(pfnOutput, pvArgOutput, NULL, 0, "%s (0x%08X) - %s", pMsg->pszDefine, hrc, pMsg->pszMsgFull);
+                            default:
+                                AssertMsgFailed(("Invalid status code format type '%.10s'!\n", pszFormatOrg));
+                                return 0;
+                        }
+                        break;
+                    }
+#endif /* IN_RING3 */
+
+                    default:
+                        AssertMsgFailed(("Invalid status code format type '%.10s'!\n", pszFormatOrg));
+                        return 0;
+
+                }
+                break;
+            }
+
+            /*
+             * iprt status code: %Rrc, %Rrs, %Rrf, %Rra.
+             */
+            case 'r':
+            {
+                int rc = va_arg(*pArgs, int);
+#ifdef IN_RING3                         /* we don't want this anywhere else yet. */
+                PCRTSTATUSMSG pMsg = RTErrGet(rc);
+                switch (*(*ppszFormat)++)
+                {
+                    case 'c':
+                        return pfnOutput(pvArgOutput, pMsg->pszDefine,    strlen(pMsg->pszDefine));
+                    case 's':
+                        return pfnOutput(pvArgOutput, pMsg->pszMsgShort,  strlen(pMsg->pszMsgShort));
+                    case 'f':
+                        return pfnOutput(pvArgOutput, pMsg->pszMsgFull,   strlen(pMsg->pszMsgFull));
+                    case 'a':
+                        return RTStrFormat(pfnOutput, pvArgOutput, NULL, 0, "%s (%d) - %s", pMsg->pszDefine, rc, pMsg->pszMsgFull);
+                    default:
+                        AssertMsgFailed(("Invalid status code format type '%.10s'!\n", pszFormatOrg));
+                        return 0;
+                }
+#else /* !IN_RING3 */
+                switch (*(*ppszFormat)++)
+                {
+                    case 'c':
+                    case 's':
+                    case 'f':
+                    case 'a':
+                        return RTStrFormat(pfnOutput, pvArgOutput, NULL, 0, "%d", rc);
+                    default:
+                        AssertMsgFailed(("Invalid status code format type '%.10s'!\n", pszFormatOrg));
+                        return 0;
+                }
+#endif /* !IN_RING3 */
+                break;
+            }
+
+#if defined(IN_RING3)
+            /*
+             * Windows status code: %Rwc, %Rwf, %Rwa
+             */
+            case 'w':
+            {
+                long rc = va_arg(*pArgs, long);
+# if defined(RT_OS_WINDOWS)
+                PCRTWINERRMSG pMsg = RTErrWinGet(rc);
+# endif
+                switch (*(*ppszFormat)++)
+                {
+# if defined(RT_OS_WINDOWS)
+                    case 'c':
+                        return pfnOutput(pvArgOutput, pMsg->pszDefine, strlen(pMsg->pszDefine));
+                    case 'f':
+                        return pfnOutput(pvArgOutput, pMsg->pszMsgFull,strlen(pMsg->pszMsgFull));
+                    case 'a':
+                        return RTStrFormat(pfnOutput, pvArgOutput, NULL, 0, "%s (0x%08X) - %s", pMsg->pszDefine, rc, pMsg->pszMsgFull);
+# else
+                    case 'c':
+                    case 'f':
+                    case 'a':
+                        return RTStrFormat(pfnOutput, pvArgOutput, NULL, 0, "0x%08X", rc);
+# endif
+                    default:
+                        AssertMsgFailed(("Invalid status code format type '%.10s'!\n", pszFormatOrg));
+                        return 0;
+                }
+                break;
+            }
+#endif /* IN_RING3 */
+
+            /*
+             * Group 4, structure dumpers.
+             */
+            case 'D':
+            {
+                /*
+                 * Interpret the type.
+                 */
+                typedef enum
+                {
+                    RTST_TIMESPEC
+                } RTST;
+/** Set if it's a pointer */
+#define RTST_FLAGS_POINTER  RT_BIT(0)
+                static const struct
+                {
+                    uint8_t     cch;        /**< the length of the string. */
+                    char        sz[16-2];   /**< the part following 'R'. */
+                    uint8_t     cb;         /**< the size of the argument. */
+                    uint8_t     fFlags;     /**< RTST_FLAGS_* */
+                    RTST        enmType;    /**< The structure type. */
+                }
+                /** Sorted array of types, looked up using binary search! */
+                s_aTypes[] =
+                {
+#define STRMEM(str) sizeof(str) - 1, str
+                    { STRMEM("Dtimespec"),   sizeof(PCRTTIMESPEC),  RTST_FLAGS_POINTER, RTST_TIMESPEC},
+#undef STRMEM
+                };
+                const char *pszType = *ppszFormat - 1;
+                int         iStart  = 0;
+                int         iEnd    = RT_ELEMENTS(s_aTypes) - 1;
+                int         i       = RT_ELEMENTS(s_aTypes) / 2;
+
+                union
+                {
+                    const void     *pv;
+                    uint64_t        u64;
+                    PCRTTIMESPEC    pTimeSpec;
+                } u;
+
+                AssertMsg(!chArgSize, ("Not argument size '%c' for RT types! '%.10s'\n", chArgSize, pszFormatOrg));
+
+                /*
+                 * Lookup the type - binary search.
+                 */
+                for (;;)
+                {
+                    int iDiff = strncmp(pszType, s_aTypes[i].sz, s_aTypes[i].cch);
+                    if (!iDiff)
+                        break;
+                    if (iEnd == iStart)
+                    {
+                        AssertMsgFailed(("Invalid format type '%.10s'!\n", pszFormatOrg));
+                        return 0;
+                    }
+                    if (iDiff < 0)
+                        iEnd = i - 1;
+                    else
+                        iStart = i + 1;
+                    if (iEnd < iStart)
+                    {
+                        AssertMsgFailed(("Invalid format type '%.10s'!\n", pszFormatOrg));
+                        return 0;
+                    }
+                    i = iStart + (iEnd - iStart) / 2;
+                }
+                *ppszFormat += s_aTypes[i].cch - 1;
+
+                /*
+                 * Fetch the argument.
+                 */
+                u.u64 = 0;
+                switch (s_aTypes[i].cb)
+                {
+                    case sizeof(const void *):
+                        u.pv = va_arg(*pArgs, const void *);
+                        break;
+                    default:
+                        AssertMsgFailed(("Invalid format error, size %d'!\n", s_aTypes[i].cb));
+                        break;
+                }
+
+                /*
+                 * If it's a pointer, we'll check if it's valid before going on.
+                 */
+                if ((s_aTypes[i].fFlags & RTST_FLAGS_POINTER) && !VALID_PTR(u.pv))
+                    return pfnOutput(pvArgOutput, RT_STR_TUPLE("<null>"));
+
+                /*
+                 * Format the output.
+                 */
+                switch (s_aTypes[i].enmType)
+                {
+                    case RTST_TIMESPEC:
+                        return RTStrFormat(pfnOutput, pvArgOutput, NULL, NULL, "%'lld ns", RTTimeSpecGetNano(u.pTimeSpec));
+
+                    default:
+                        AssertMsgFailed(("Invalid/unhandled enmType=%d\n", s_aTypes[i].enmType));
+                        break;
+                }
+                break;
+            }
+
+#ifdef IN_RING3
+            /*
+             * Group 5, XML / HTML escapers.
+             */
+            case 'M':
+            {
+                char chWhat = (*ppszFormat)[0];
+                bool fAttr  = chWhat == 'a';
+                char chType = (*ppszFormat)[1];
+                AssertMsgBreak(chWhat == 'a' || chWhat == 'e', ("Invalid IPRT format type '%.10s'!\n", pszFormatOrg));
+                *ppszFormat += 2;
+                switch (chType)
+                {
+                    case 's':
+                    {
+                        static const char   s_szElemEscape[] = "<>&\"'";
+                        static const char   s_szAttrEscape[] = "<>&\"\n\r"; /* more? */
+                        const char * const  pszEscape =  fAttr ?             s_szAttrEscape  :             s_szElemEscape;
+                        size_t       const  cchEscape = (fAttr ? RT_ELEMENTS(s_szAttrEscape) : RT_ELEMENTS(s_szElemEscape)) - 1;
+                        size_t      cchOutput = 0;
+                        const char *pszStr    = va_arg(*pArgs, char *);
+                        ssize_t     cchStr;
+                        ssize_t     offCur;
+                        ssize_t     offLast;
+
+                        if (!VALID_PTR(pszStr))
+                            pszStr = "<NULL>";
+                        cchStr = RTStrNLen(pszStr, (unsigned)cchPrecision);
+
+                        if (fAttr)
+                            cchOutput += pfnOutput(pvArgOutput, "\"", 1);
+                        if (!(fFlags & RTSTR_F_LEFT))
+                            while (--cchWidth >= cchStr)
+                                cchOutput += pfnOutput(pvArgOutput, " ", 1);
+
+                        offLast = offCur = 0;
+                        while (offCur < cchStr)
+                        {
+                            if (memchr(pszEscape, pszStr[offCur], cchEscape))
+                            {
+                                if (offLast < offCur)
+                                    cchOutput += pfnOutput(pvArgOutput, &pszStr[offLast], offCur - offLast);
+                                switch (pszStr[offCur])
+                                {
+                                    case '<':   cchOutput += pfnOutput(pvArgOutput, "&lt;", 4); break;
+                                    case '>':   cchOutput += pfnOutput(pvArgOutput, "&gt;", 4); break;
+                                    case '&':   cchOutput += pfnOutput(pvArgOutput, "&amp;", 5); break;
+                                    case '\'':  cchOutput += pfnOutput(pvArgOutput, "&apos;", 6); break;
+                                    case '"':   cchOutput += pfnOutput(pvArgOutput, "&quot;", 6); break;
+                                    case '\n':  cchOutput += pfnOutput(pvArgOutput, "&#xA;", 5); break;
+                                    case '\r':  cchOutput += pfnOutput(pvArgOutput, "&#xD;", 5); break;
+                                    default:
+                                        AssertFailed();
+                                }
+                                offLast = offCur + 1;
+                            }
+                            offCur++;
+                        }
+                        if (offLast < offCur)
+                            cchOutput += pfnOutput(pvArgOutput, &pszStr[offLast], offCur - offLast);
+
+                        while (--cchWidth >= cchStr)
+                            cchOutput += pfnOutput(pvArgOutput, " ", 1);
+                        if (fAttr)
+                            cchOutput += pfnOutput(pvArgOutput, "\"", 1);
+                        return cchOutput;
+                    }
+
+                    default:
+                        AssertMsgFailed(("Invalid IPRT format type '%.10s'!\n", pszFormatOrg));
+                }
+                break;
+            }
+#endif /* IN_RING3 */
+
+
+            /*
+             * Groups 6 - CPU Architecture Register Formatters.
+             *            "%RAarch[reg]"
+             */
+            case 'A':
+            {
+                char const * const  pszArch   = *ppszFormat;
+                const char         *pszReg    = pszArch;
+                size_t              cchOutput = 0;
+                int                 cPrinted  = 0;
+                size_t              cchReg;
+
+                /* Parse out the */
+                while ((ch = *pszReg++) && ch != '[')
+                {   /* nothing */   }
+                AssertMsgBreak(ch == '[', ("Malformed IPRT architecture register format type '%.10s'!\n", pszFormatOrg));
+
+                cchReg = 0;
+                while ((ch = pszReg[cchReg]) && ch != ']')
+                    cchReg++;
+                AssertMsgBreak(ch == ']', ("Malformed IPRT architecture register format type '%.10s'!\n", pszFormatOrg));
+
+                *ppszFormat = &pszReg[cchReg + 1];
+
+
+#define REG_EQUALS(a_szReg)  (sizeof(a_szReg) - 1 == cchReg && !strncmp(a_szReg, pszReg, sizeof(a_szReg) - 1))
+#define REG_OUT_BIT(a_uVal, a_fBitMask, a_szName) \
+    do { \
+        if ((a_uVal) & (a_fBitMask)) \
+        { \
+            if (!cPrinted++) \
+                cchOutput += pfnOutput(pvArgOutput, "{" a_szName, sizeof(a_szName)); \
+            else \
+                cchOutput += pfnOutput(pvArgOutput, "," a_szName, sizeof(a_szName)); \
+           (a_uVal) &= ~(a_fBitMask); \
+        } \
+    } while (0)
+#define REG_OUT_CLOSE(a_uVal) \
+    do { \
+        if ((a_uVal)) \
+        { \
+            cchOutput += pfnOutput(pvArgOutput, !cPrinted ? "{unkn=" : ",unkn=", 6); \
+            cch = RTStrFormatNumber(&szBuf[0], (a_uVal), 16, 1, -1, fFlags); \
+            cchOutput += pfnOutput(pvArgOutput, szBuf, cch); \
+            cPrinted++; \
+        } \
+        if (cPrinted) \
+            cchOutput += pfnOutput(pvArgOutput, "}", 1); \
+    } while (0)
+
+
+                if (0)
+                { /* dummy */ }
+#ifdef STRFORMAT_WITH_X86
+                /*
+                 * X86 & AMD64.
+                 */
+                else if (   pszReg - pszArch == 3 + 1
+                         && pszArch[0] == 'x'
+                         && pszArch[1] == '8'
+                         && pszArch[2] == '6')
+                {
+                    if (REG_EQUALS("cr0"))
+                    {
+                        uint64_t cr0 = va_arg(*pArgs, uint64_t);
+                        fFlags |= RTSTR_F_64BIT;
+                        cch = RTStrFormatNumber(&szBuf[0], cr0, 16, 8, -1, fFlags | RTSTR_F_ZEROPAD);
+                        cchOutput += pfnOutput(pvArgOutput, szBuf, cch);
+                        REG_OUT_BIT(cr0, X86_CR0_PE, "PE");
+                        REG_OUT_BIT(cr0, X86_CR0_MP, "MP");
+                        REG_OUT_BIT(cr0, X86_CR0_EM, "EM");
+                        REG_OUT_BIT(cr0, X86_CR0_TS, "DE");
+                        REG_OUT_BIT(cr0, X86_CR0_ET, "ET");
+                        REG_OUT_BIT(cr0, X86_CR0_NE, "NE");
+                        REG_OUT_BIT(cr0, X86_CR0_WP, "WP");
+                        REG_OUT_BIT(cr0, X86_CR0_AM, "AM");
+                        REG_OUT_BIT(cr0, X86_CR0_NW, "NW");
+                        REG_OUT_BIT(cr0, X86_CR0_CD, "CD");
+                        REG_OUT_BIT(cr0, X86_CR0_PG, "PG");
+                        REG_OUT_CLOSE(cr0);
+                    }
+                    else if (REG_EQUALS("cr4"))
+                    {
+                        uint64_t cr4 = va_arg(*pArgs, uint64_t);
+                        fFlags |= RTSTR_F_64BIT;
+                        cch = RTStrFormatNumber(&szBuf[0], cr4, 16, 8, -1, fFlags | RTSTR_F_ZEROPAD);
+                        cchOutput += pfnOutput(pvArgOutput, szBuf, cch);
+                        REG_OUT_BIT(cr4, X86_CR4_VME, "VME");
+                        REG_OUT_BIT(cr4, X86_CR4_PVI, "PVI");
+                        REG_OUT_BIT(cr4, X86_CR4_TSD, "TSD");
+                        REG_OUT_BIT(cr4, X86_CR4_DE,  "DE");
+                        REG_OUT_BIT(cr4, X86_CR4_PSE, "PSE");
+                        REG_OUT_BIT(cr4, X86_CR4_PAE, "PAE");
+                        REG_OUT_BIT(cr4, X86_CR4_MCE, "MCE");
+                        REG_OUT_BIT(cr4, X86_CR4_PGE, "PGE");
+                        REG_OUT_BIT(cr4, X86_CR4_PCE, "PCE");
+                        REG_OUT_BIT(cr4, X86_CR4_OSFXSR, "OSFXSR");
+                        REG_OUT_BIT(cr4, X86_CR4_OSXMMEEXCPT, "OSXMMEEXCPT");
+                        REG_OUT_BIT(cr4, X86_CR4_VMXE, "VMXE");
+                        REG_OUT_BIT(cr4, X86_CR4_SMXE, "SMXE");
+                        REG_OUT_BIT(cr4, X86_CR4_PCIDE, "PCIDE");
+                        REG_OUT_BIT(cr4, X86_CR4_OSXSAVE, "OSXSAVE");
+                        REG_OUT_BIT(cr4, X86_CR4_SMEP, "SMEP");
+                        REG_OUT_BIT(cr4, X86_CR4_SMAP, "SMAP");
+                        REG_OUT_CLOSE(cr4);
+                    }
+                    else
+                        AssertMsgFailed(("Unknown x86 register specified in '%.10s'!\n", pszFormatOrg));
+                }
+#endif
+                else
+                    AssertMsgFailed(("Unknown architecture specified in '%.10s'!\n", pszFormatOrg));
+#undef REG_OUT_BIT
+#undef REG_OUT_CLOSE
+#undef REG_EQUALS
+                return cchOutput;
+            }
+
+            /*
+             * Invalid/Unknown. Bitch about it.
+             */
+            default:
+                AssertMsgFailed(("Invalid IPRT format type '%.10s'!\n", pszFormatOrg));
+                break;
+        }
+    }
+    else
+        AssertMsgFailed(("Invalid IPRT format type '%.10s'!\n", pszFormatOrg));
+
+    NOREF(pszFormatOrg);
+    return 0;
+}
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/vboxguest/common/string/strformattype.c
@@ -0,0 +1,476 @@
+/* $Id: strformattype.cpp $ */
+/** @file
+ * IPRT - IPRT String Formatter Extensions, Dynamic Types.
+ */
+
+/*
+ * Copyright (C) 2008-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+
+/*********************************************************************************************************************************
+*   Global Variables                                                                                                             *
+*********************************************************************************************************************************/
+#define LOG_GROUP RTLOGGROUP_STRING
+#include <iprt/string.h>
+#include "internal/iprt.h"
+
+#include <iprt/assert.h>
+#include <iprt/stdarg.h>
+#include <iprt/asm.h>
+#include "internal/string.h"
+
+
+/*********************************************************************************************************************************
+*   Defined Constants And Macros                                                                                                 *
+*********************************************************************************************************************************/
+#ifdef RT_STRICT
+# define RTSTRFORMATTYPE_WITH_LOCKING
+#endif
+#ifdef RTSTRFORMATTYPE_WITH_LOCKING
+# define RTSTRFORMATTYPE_LOCK_OFFSET    0x7fff0000
+#endif
+
+
+/*********************************************************************************************************************************
+*   Structures and Typedefs                                                                                                      *
+*********************************************************************************************************************************/
+/**
+ * Description of a registered formatting type.
+ *
+ * In GC we'll be using offsets instead of pointers just to try avoid having to
+ * do the bothersome relocating. This of course assumes that all the relevant
+ * code stays within the same mapping.
+ */
+typedef struct RTSTRDYNFMT
+{
+    /** The length of the type. */
+    uint8_t             cchType;
+    /** The type name. */
+    char                szType[47];
+    /** The handler function.
+     * In GC the offset is relative to g_aTypes[0], so that &g_aTypes[0] + offHandler
+     * gives the actual address. */
+#ifdef IN_RC
+    int32_t             offHandler;
+#else
+    PFNRTSTRFORMATTYPE  pfnHandler;
+#endif
+    /** Callback argument. */
+    void * volatile     pvUser;
+#if ARCH_BITS == 32
+    /** Size alignment padding. */
+    char                abPadding[8];
+#endif
+} RTSTRDYNFMT;
+AssertCompileSizeAlignment(RTSTRDYNFMT, 32);
+typedef RTSTRDYNFMT *PRTSTRDYNFMT;
+typedef RTSTRDYNFMT const *PCRTSTRDYNFMT;
+
+
+/*********************************************************************************************************************************
+*   Global Variables                                                                                                             *
+*********************************************************************************************************************************/
+/** The registered types, sorted for binary lookup.
+ * We use a static array here because it avoids RTMemAlloc dependencies+leaks. */
+static RTSTRDYNFMT      g_aTypes[64];
+/** The number of registered types. */
+static uint32_t         g_cTypes = 0;
+#ifdef RTSTRFORMATTYPE_WITH_LOCKING
+/** This is just a thing we assert/spin on.
+ * Zero == unlocked, negative == write locked, positive == read locked.
+ *
+ * The user should do all the serialization and we'll smack his fingers in
+ * strict builds if he doesn't. */
+static int32_t volatile g_i32Spinlock = 0;
+#endif
+
+
+/**
+ * Locks the stuff for updating.
+ *
+ * Mostly for check that the caller is doing his job.
+ */
+DECLINLINE(void) rtstrFormatTypeWriteLock(void)
+{
+#if defined(RTSTRFORMATTYPE_WITH_LOCKING)
+    if (RT_UNLIKELY(!ASMAtomicCmpXchgS32(&g_i32Spinlock, -RTSTRFORMATTYPE_LOCK_OFFSET, 0)))
+    {
+        unsigned volatile i;
+
+        AssertFailed();
+        for (i = 0;; i++)
+            if (    !g_i32Spinlock
+                &&  ASMAtomicCmpXchgS32(&g_i32Spinlock, -RTSTRFORMATTYPE_LOCK_OFFSET, 0))
+                break;
+    }
+#endif
+}
+
+
+/**
+ * Undoing rtstrFormatTypeWriteLock.
+ */
+DECLINLINE(void) rtstrFormatTypeWriteUnlock(void)
+{
+#if defined(RTSTRFORMATTYPE_WITH_LOCKING)
+    Assert(g_i32Spinlock < 0);
+    ASMAtomicAddS32(&g_i32Spinlock, RTSTRFORMATTYPE_LOCK_OFFSET);
+#endif
+}
+
+
+/**
+ * Locks the stuff for reading.
+ *
+ * This is just cheap stuff to make sure the caller is doing the right thing.
+ */
+DECLINLINE(void) rtstrFormatTypeReadLock(void)
+{
+#if defined(RTSTRFORMATTYPE_WITH_LOCKING)
+    if (RT_UNLIKELY(ASMAtomicIncS32(&g_i32Spinlock) < 0))
+    {
+        unsigned volatile i;
+
+        AssertFailed();
+        for (i = 0;; i++)
+            if (ASMAtomicUoReadS32(&g_i32Spinlock) > 0)
+                break;
+    }
+#endif
+}
+
+
+/**
+ * Undoing rtstrFormatTypeReadLock.
+ */
+DECLINLINE(void) rtstrFormatTypeReadUnlock(void)
+{
+#if defined(RTSTRFORMATTYPE_WITH_LOCKING)
+    Assert(g_i32Spinlock > 0);
+    ASMAtomicDecS32(&g_i32Spinlock);
+#endif
+}
+
+
+/**
+ * Compares a type string with a type entry, the string doesn't need to be terminated.
+ *
+ * @returns Same as memcmp.
+ * @param   pszType     The type string, doesn't need to be terminated.
+ * @param   cchType     The number of chars in @a pszType to compare.
+ * @param   pType       The type entry to compare with.
+ */
+DECLINLINE(int) rtstrFormatTypeCompare(const char *pszType, size_t cchType, PCRTSTRDYNFMT pType)
+{
+    size_t cch = RT_MIN(cchType, pType->cchType);
+    int iDiff = memcmp(pszType, pType->szType, cch);
+    if (!iDiff)
+    {
+        if (cchType == pType->cchType)
+            return 0;
+        iDiff = cchType < pType->cchType ? -1 : 1;
+    }
+    return iDiff;
+}
+
+
+/**
+ * Looks up a type entry.
+ *
+ * @returns The type index, -1 on failure.
+ * @param   pszType     The type to look up. This doesn't have to be terminated.
+ * @param   cchType     The length of the type.
+ */
+DECLINLINE(int32_t) rtstrFormatTypeLookup(const char *pszType, size_t cchType)
+{
+    /*
+     * Lookup the type - binary search.
+     */
+    int32_t iStart = 0;
+    int32_t iEnd   = g_cTypes - 1;
+    int32_t i      = iEnd / 2;
+    for (;;)
+    {
+        int iDiff = rtstrFormatTypeCompare(pszType, cchType, &g_aTypes[i]);
+        if (!iDiff)
+            return i;
+        if (iEnd == iStart)
+            break;
+        if (iDiff < 0)
+            iEnd = i - 1;
+        else
+            iStart = i + 1;
+        if (iEnd < iStart)
+            break;
+        i = iStart + (iEnd - iStart) / 2;
+    }
+    return -1;
+}
+
+
+/**
+ * Register a format handler for a type.
+ *
+ * The format handler is used to handle '%R[type]' format types, where the argument
+ * in the vector is a pointer value (a bit restrictive, but keeps it simple).
+ *
+ * The caller must ensure that no other thread will be making use of any of
+ * the dynamic formatting type facilities simultaneously with this call.
+ *
+ * @returns IPRT status code.
+ * @retval  VINF_SUCCESS on success.
+ * @retval  VERR_ALREADY_EXISTS if the type has already been registered.
+ * @retval  VERR_TOO_MANY_OPEN_FILES if all the type slots has been allocated already.
+ *
+ * @param   pszType         The type name.
+ * @param   pfnHandler      The handler address. See FNRTSTRFORMATTYPE for details.
+ * @param   pvUser          The user argument to pass to the handler. See RTStrFormatTypeSetUser
+ *                          for how to update this later.
+ */
+RTDECL(int) RTStrFormatTypeRegister(const char *pszType, PFNRTSTRFORMATTYPE pfnHandler, void *pvUser)
+{
+    int rc;
+    size_t cchType;
+    uint32_t cTypes;
+
+    /*
+     * Validate input.
+     */
+    AssertPtr(pfnHandler);
+    AssertPtr(pszType);
+    cchType = strlen(pszType);
+    AssertReturn(cchType < RT_SIZEOFMEMB(RTSTRDYNFMT, szType), VERR_INVALID_PARAMETER);
+
+    /*
+     * Try add it.
+     */
+    rtstrFormatTypeWriteLock();
+
+    /* check that there are empty slots. */
+    cTypes = g_cTypes;
+    if (cTypes < RT_ELEMENTS(g_aTypes))
+    {
+        /* find where to insert it. */
+        uint32_t i = 0;
+        rc = VINF_SUCCESS;
+        while (i < cTypes)
+        {
+            int iDiff = rtstrFormatTypeCompare(pszType, cchType, &g_aTypes[i]);
+            if (!iDiff)
+            {
+                rc = VERR_ALREADY_EXISTS;
+                break;
+            }
+            if (iDiff < 0)
+                break;
+            i++;
+        }
+        if (RT_SUCCESS(rc))
+        {
+            /* make room. */
+            uint32_t cToMove = cTypes - i;
+            if (cToMove)
+                memmove(&g_aTypes[i + 1], &g_aTypes[i], cToMove * sizeof(g_aTypes[i]));
+
+            /* insert the new entry. */
+            memset(&g_aTypes[i], 0, sizeof(g_aTypes[i]));
+            memcpy(&g_aTypes[i].szType[0], pszType, cchType + 1);
+            g_aTypes[i].cchType = (uint8_t)cchType;
+            g_aTypes[i].pvUser = pvUser;
+#ifdef IN_RC
+            g_aTypes[i].offHandler = (intptr_t)pfnHandler - (intptr_t)&g_aTypes[0];
+#else
+            g_aTypes[i].pfnHandler = pfnHandler;
+#endif
+            ASMAtomicIncU32(&g_cTypes);
+            rc = VINF_SUCCESS;
+        }
+    }
+    else
+        rc = VERR_TOO_MANY_OPEN_FILES; /** @todo fix error code */
+
+    rtstrFormatTypeWriteUnlock();
+
+    return rc;
+}
+RT_EXPORT_SYMBOL(RTStrFormatTypeRegister);
+
+
+/**
+ * Deregisters a format type.
+ *
+ * The caller must ensure that no other thread will be making use of any of
+ * the dynamic formatting type facilities simultaneously with this call.
+ *
+ * @returns IPRT status code.
+ * @retval  VINF_SUCCESS on success.
+ * @retval  VERR_FILE_NOT_FOUND if not found.
+ *
+ * @param   pszType     The type to deregister.
+ */
+RTDECL(int) RTStrFormatTypeDeregister(const char *pszType)
+{
+    int32_t i;
+
+    /*
+     * Validate input.
+     */
+    AssertPtr(pszType);
+
+    /*
+     * Locate the entry and remove it.
+     */
+    rtstrFormatTypeWriteLock();
+    i = rtstrFormatTypeLookup(pszType, strlen(pszType));
+    if (i >= 0)
+    {
+        const uint32_t cTypes = g_cTypes;
+        int32_t cToMove = cTypes - i - 1;
+        if (cToMove > 0)
+            memmove(&g_aTypes[i], &g_aTypes[i + 1], cToMove * sizeof(g_aTypes[i]));
+        memset(&g_aTypes[cTypes - 1], 0, sizeof(g_aTypes[0]));
+        ASMAtomicDecU32(&g_cTypes);
+    }
+    rtstrFormatTypeWriteUnlock();
+
+    Assert(i >= 0);
+    return i >= 0
+         ? VINF_SUCCESS
+         : VERR_FILE_NOT_FOUND; /** @todo fix status code */
+}
+RT_EXPORT_SYMBOL(RTStrFormatTypeDeregister);
+
+
+/**
+ * Sets the user argument for a type.
+ *
+ * This can be used if a user argument needs relocating in GC.
+ *
+ * @returns IPRT status code.
+ * @retval  VINF_SUCCESS on success.
+ * @retval  VERR_FILE_NOT_FOUND if not found.
+ *
+ * @param   pszType     The type to update.
+ * @param   pvUser      The new user argument value.
+ */
+RTDECL(int) RTStrFormatTypeSetUser(const char *pszType, void *pvUser)
+{
+    int32_t i;
+
+    /*
+     * Validate input.
+     */
+    AssertPtr(pszType);
+
+    /*
+     * Locate the entry and update it.
+     */
+    rtstrFormatTypeReadLock();
+
+    i = rtstrFormatTypeLookup(pszType, strlen(pszType));
+    if (i >= 0)
+        ASMAtomicWritePtr(&g_aTypes[i].pvUser, pvUser);
+
+    rtstrFormatTypeReadUnlock();
+
+    Assert(i >= 0);
+    return i >= 0
+         ? VINF_SUCCESS
+         : VERR_FILE_NOT_FOUND; /** @todo fix status code */
+}
+RT_EXPORT_SYMBOL(RTStrFormatTypeSetUser);
+
+
+/**
+ * Formats a type using a registered callback handler.
+ *
+ * This will handle %R[type].
+ *
+ * @returns The number of bytes formatted.
+ * @param   pfnOutput       Pointer to output function.
+ * @param   pvArgOutput     Argument for the output function.
+ * @param   ppszFormat      Pointer to the format string pointer. Advance this till the char
+ *                          after the format specifier.
+ * @param   pArgs           Pointer to the argument list. Use this to fetch the arguments.
+ * @param   cchWidth        Format Width. -1 if not specified.
+ * @param   cchPrecision    Format Precision. -1 if not specified.
+ * @param   fFlags          Flags (RTSTR_NTFS_*).
+ * @param   chArgSize       The argument size specifier, 'l' or 'L'.
+ */
+DECLHIDDEN(size_t) rtstrFormatType(PFNRTSTROUTPUT pfnOutput, void *pvArgOutput, const char **ppszFormat,
+                                   va_list *pArgs, int cchWidth, int cchPrecision, unsigned fFlags, char chArgSize)
+{
+    size_t      cch;
+    int32_t     i;
+    char const *pszTypeEnd;
+    char const *pszType;
+    char        ch;
+    void       *pvValue = va_arg(*pArgs, void *);
+    NOREF(chArgSize);
+
+    /*
+     * Parse out the type.
+     */
+    pszType = *ppszFormat + 2;
+    *ppszFormat = pszType;
+    Assert(pszType[-1] == '[');
+    Assert(pszType[-2] == 'R');
+    pszTypeEnd = pszType;
+    while ((ch = *pszTypeEnd) != ']')
+    {
+        AssertReturn(ch != '\0', 0);
+        AssertReturn(ch != '%', 0);
+        AssertReturn(ch != '[', 0);
+        pszTypeEnd++;
+    }
+    *ppszFormat = pszTypeEnd + 1;
+
+    /*
+     * Locate the entry and call the handler.
+     */
+    rtstrFormatTypeReadLock();
+
+    i = rtstrFormatTypeLookup(pszType, pszTypeEnd - pszType);
+    if (RT_LIKELY(i >= 0))
+    {
+#ifdef IN_RC
+        PFNRTSTRFORMATTYPE pfnHandler = (PFNRTSTRFORMATTYPE)((intptr_t)&g_aTypes[0] + g_aTypes[i].offHandler);
+#else
+        PFNRTSTRFORMATTYPE pfnHandler = g_aTypes[i].pfnHandler;
+#endif
+        void *pvUser = ASMAtomicReadPtr(&g_aTypes[i].pvUser);
+
+        rtstrFormatTypeReadUnlock();
+
+        cch = pfnHandler(pfnOutput, pvArgOutput, g_aTypes[i].szType, pvValue, cchWidth, cchPrecision, fFlags, pvUser);
+    }
+    else
+    {
+        rtstrFormatTypeReadUnlock();
+
+        cch  = pfnOutput(pvArgOutput, RT_STR_TUPLE("<missing:%R["));
+        cch += pfnOutput(pvArgOutput, pszType, pszTypeEnd - pszType);
+        cch += pfnOutput(pvArgOutput, RT_STR_TUPLE("]>"));
+    }
+
+    return cch;
+}
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/vboxguest/common/string/strprintf.c
@@ -0,0 +1,129 @@
+/* $Id: strprintf.cpp $ */
+/** @file
+ * IPRT - String Formatters.
+ */
+
+/*
+ * Copyright (C) 2006-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+
+/*********************************************************************************************************************************
+*   Header Files                                                                                                                 *
+*********************************************************************************************************************************/
+#include <iprt/string.h>
+#include "internal/iprt.h"
+
+#include <iprt/assert.h>
+
+
+/*********************************************************************************************************************************
+*   Structures and Typedefs                                                                                                      *
+*********************************************************************************************************************************/
+/** strbufoutput() argument structure. */
+typedef struct STRBUFARG
+{
+    /** Pointer to current buffer position. */
+    char   *psz;
+    /** Number of bytes left in the buffer - not including the trailing zero. */
+    size_t  cch;
+} STRBUFARG;
+/** Pointer to a strbufoutput() argument structure. */
+typedef STRBUFARG *PSTRBUFARG;
+
+
+/*********************************************************************************************************************************
+*   Internal Functions                                                                                                           *
+*********************************************************************************************************************************/
+static DECLCALLBACK(size_t) strbufoutput(void *pvArg, const char *pachChars, size_t cbChars);
+
+
+/**
+ * Output callback.
+ *
+ * @returns number of bytes written.
+ * @param   pvArg       Pointer to a STRBUFARG structure.
+ * @param   pachChars   Pointer to an array of utf-8 characters.
+ * @param   cbChars     Number of bytes in the character array pointed to by pachChars.
+ */
+static DECLCALLBACK(size_t) strbufoutput(void *pvArg, const char *pachChars, size_t cbChars)
+{
+    PSTRBUFARG  pArg = (PSTRBUFARG)pvArg;
+
+    cbChars = RT_MIN(pArg->cch, cbChars);
+    if (cbChars)
+    {
+        memcpy(pArg->psz, pachChars, cbChars);
+        pArg->cch -= cbChars;
+        pArg->psz += cbChars;
+    }
+    *pArg->psz = '\0';
+
+    return cbChars;
+}
+
+
+RTDECL(size_t) RTStrPrintfExV(PFNSTRFORMAT pfnFormat, void *pvArg, char *pszBuffer, size_t cchBuffer, const char *pszFormat, va_list args)
+{
+    STRBUFARG Arg;
+
+    if (!cchBuffer)
+    {
+        AssertMsgFailed(("Excellent idea! Format a string with no space for the output!\n"));
+        return 0;
+    }
+
+    Arg.psz = pszBuffer;
+    Arg.cch = cchBuffer - 1;
+    return RTStrFormatV(strbufoutput, &Arg, pfnFormat, pvArg, pszFormat, args);
+}
+RT_EXPORT_SYMBOL(RTStrPrintfExV);
+
+
+RTDECL(size_t) RTStrPrintfV(char *pszBuffer, size_t cchBuffer, const char *pszFormat, va_list args)
+{
+    return RTStrPrintfExV(NULL, NULL, pszBuffer, cchBuffer, pszFormat, args);
+}
+RT_EXPORT_SYMBOL(RTStrPrintfV);
+
+
+RTDECL(size_t) RTStrPrintfEx(PFNSTRFORMAT pfnFormat, void *pvArg, char *pszBuffer, size_t cchBuffer, const char *pszFormat, ...)
+{
+    va_list args;
+    size_t cbRet;
+    va_start(args, pszFormat);
+    cbRet = RTStrPrintfExV(pfnFormat, pvArg, pszBuffer, cchBuffer, pszFormat, args);
+    va_end(args);
+    return cbRet;
+}
+RT_EXPORT_SYMBOL(RTStrPrintfEx);
+
+
+RTDECL(size_t) RTStrPrintf(char *pszBuffer, size_t cchBuffer, const char *pszFormat, ...)
+{
+    va_list args;
+    size_t cbRet;
+    va_start(args, pszFormat);
+    cbRet = RTStrPrintfV(pszBuffer, cchBuffer, pszFormat, args);
+    va_end(args);
+    return cbRet;
+}
+RT_EXPORT_SYMBOL(RTStrPrintf);
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/vboxguest/common/string/strtonum.c
@@ -0,0 +1,1013 @@
+/* $Id: strtonum.cpp $ */
+/** @file
+ * IPRT - String To Number Conversion.
+ */
+
+/*
+ * Copyright (C) 2006-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+
+/*********************************************************************************************************************************
+*   Header Files                                                                                                                 *
+*********************************************************************************************************************************/
+#include <iprt/string.h>
+#include "internal/iprt.h"
+
+#include <iprt/assert.h>
+#include <iprt/ctype.h> /* needed for RT_C_IS_DIGIT */
+#include <iprt/err.h>
+
+
+/*********************************************************************************************************************************
+*   Global Variables                                                                                                             *
+*********************************************************************************************************************************/
+/** 8-bit char -> digit. */
+static const unsigned char g_auchDigits[256] =
+{
+    255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+    255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9,255,255,255,255,255,255,
+    255, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,255,255,255,255,255,
+    255, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,255,255,255,255,255,
+    255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+    255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+    255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+    255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255
+};
+/** Approximated overflow shift checks. */
+static const char g_auchShift[36] =
+{
+  /*  0   1   2   3   4   5   6   7   8   9  10  11  12  13  14  15  16  17  18  19  20  21  22  23  24  25  26  27  28  29  30  31  32  33  34  35 */
+     64, 64, 63, 63, 62, 62, 62, 62, 61, 61, 61, 61, 61, 61, 61, 61, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 59, 59, 59, 59
+};
+
+/*
+#include <stdio.h>
+int main()
+{
+    int i;
+    printf("static const unsigned char g_auchDigits[256] =\n"
+           "{");
+    for (i = 0; i < 256; i++)
+    {
+        int ch = 255;
+        if (i >= '0' && i <= '9')
+            ch = i - '0';
+        else if (i >= 'a' && i <= 'z')
+            ch = i - 'a' + 10;
+        else if (i >= 'A' && i <= 'Z')
+            ch = i - 'A' + 10;
+        if (i == 0)
+            printf("\n    %3d", ch);
+        else if ((i % 32) == 0)
+            printf(",\n    %3d", ch);
+        else
+            printf(",%3d", ch);
+    }
+    printf("\n"
+           "};\n");
+    return 0;
+}
+*/
+
+
+/**
+ * Converts a string representation of a number to a 64-bit unsigned number.
+ *
+ * @returns iprt status code.
+ *          Warnings are used to indicate conversion problems.
+ * @retval  VWRN_NUMBER_TOO_BIG
+ * @retval  VWRN_NEGATIVE_UNSIGNED
+ * @retval  VWRN_TRAILING_CHARS
+ * @retval  VWRN_TRAILING_SPACES
+ * @retval  VINF_SUCCESS
+ * @retval  VERR_NO_DIGITS
+ *
+ * @param   pszValue    Pointer to the string value.
+ * @param   ppszNext    Where to store the pointer to the first char following the number. (Optional)
+ * @param   uBase       The base of the representation used.
+ *                      If the function will look for known prefixes before defaulting to 10.
+ * @param   pu64        Where to store the converted number. (optional)
+ */
+RTDECL(int) RTStrToUInt64Ex(const char *pszValue, char **ppszNext, unsigned uBase, uint64_t *pu64)
+{
+    const char   *psz = pszValue;
+    int           iShift;
+    int           rc;
+    uint64_t      u64;
+    unsigned char uch;
+
+    /*
+     * Positive/Negative stuff.
+     */
+    bool fPositive = true;
+    for (;; psz++)
+    {
+        if (*psz == '+')
+            fPositive = true;
+        else if (*psz == '-')
+            fPositive = !fPositive;
+        else
+            break;
+    }
+
+    /*
+     * Check for hex prefix.
+     */
+    if (!uBase)
+    {
+        if (    psz[0] == '0'
+            &&  (psz[1] == 'x' || psz[1] == 'X')
+            &&  g_auchDigits[(unsigned char)psz[2]] < 16)
+        {
+            uBase = 16;
+            psz += 2;
+        }
+        else if (   psz[0] == '0'
+                 && g_auchDigits[(unsigned char)psz[1]] < 8)
+        {
+            uBase = 8;
+            psz++;
+        }
+        else
+            uBase = 10;
+    }
+    else if (   uBase == 16
+             && psz[0] == '0'
+             && (psz[1] == 'x' || psz[1] == 'X')
+             && g_auchDigits[(unsigned char)psz[2]] < 16)
+        psz += 2;
+
+    /*
+     * Interpret the value.
+     * Note: We only support ascii digits at this time... :-)
+     */
+    iShift = g_auchShift[uBase];
+    pszValue = psz; /* (Prefix and sign doesn't count in the digit counting.) */
+    rc = VINF_SUCCESS;
+    u64 = 0;
+    while ((uch = (unsigned char)*psz) != 0)
+    {
+        unsigned char chDigit = g_auchDigits[uch];
+        uint64_t u64Prev;
+
+        if (chDigit >= uBase)
+            break;
+
+        u64Prev = u64;
+        u64 *= uBase;
+        u64 += chDigit;
+        if (u64Prev > u64 || (u64Prev >> iShift))
+            rc = VWRN_NUMBER_TOO_BIG;
+        psz++;
+    }
+
+    if (!fPositive)
+    {
+        if (rc == VINF_SUCCESS)
+            rc = VWRN_NEGATIVE_UNSIGNED;
+        u64 = -(int64_t)u64;
+    }
+
+    if (pu64)
+        *pu64 = u64;
+
+    if (psz == pszValue)
+        rc = VERR_NO_DIGITS;
+
+    if (ppszNext)
+        *ppszNext = (char *)psz;
+
+    /*
+     * Warn about trailing chars/spaces.
+     */
+    if (    rc == VINF_SUCCESS
+        &&  *psz)
+    {
+        while (*psz == ' ' || *psz == '\t')
+            psz++;
+        rc = *psz ? VWRN_TRAILING_CHARS : VWRN_TRAILING_SPACES;
+    }
+
+    return rc;
+}
+RT_EXPORT_SYMBOL(RTStrToUInt64Ex);
+
+
+/**
+ * Converts a string representation of a number to a 64-bit unsigned number,
+ * making sure the full string is converted.
+ *
+ * @returns iprt status code.
+ *          Warnings are used to indicate conversion problems.
+ * @retval  VWRN_NUMBER_TOO_BIG
+ * @retval  VWRN_NEGATIVE_UNSIGNED
+ * @retval  VINF_SUCCESS
+ * @retval  VERR_NO_DIGITS
+ * @retval  VERR_TRAILING_SPACES
+ * @retval  VERR_TRAILING_CHARS
+ *
+ * @param   pszValue    Pointer to the string value.
+ * @param   uBase       The base of the representation used.
+ *                      If the function will look for known prefixes before defaulting to 10.
+ * @param   pu64        Where to store the converted number. (optional)
+ */
+RTDECL(int) RTStrToUInt64Full(const char *pszValue, unsigned uBase, uint64_t *pu64)
+{
+    char *psz;
+    int rc = RTStrToUInt64Ex(pszValue, &psz, uBase, pu64);
+    if (RT_SUCCESS(rc) && *psz)
+    {
+        if (rc == VWRN_TRAILING_CHARS || rc == VWRN_TRAILING_SPACES)
+            rc = -rc;
+        else
+        {
+            while (*psz == ' ' || *psz == '\t')
+                psz++;
+            rc = *psz ? VERR_TRAILING_CHARS : VERR_TRAILING_SPACES;
+        }
+    }
+    return rc;
+}
+RT_EXPORT_SYMBOL(RTStrToUInt64Full);
+
+
+/**
+ * Converts a string representation of a number to a 64-bit unsigned number.
+ * The base is guessed.
+ *
+ * @returns 64-bit unsigned number on success.
+ * @returns 0 on failure.
+ * @param   pszValue    Pointer to the string value.
+ */
+RTDECL(uint64_t) RTStrToUInt64(const char *pszValue)
+{
+    uint64_t u64;
+    int rc = RTStrToUInt64Ex(pszValue, NULL, 0, &u64);
+    if (RT_SUCCESS(rc))
+        return u64;
+    return 0;
+}
+RT_EXPORT_SYMBOL(RTStrToUInt64);
+
+
+/**
+ * Converts a string representation of a number to a 32-bit unsigned number.
+ *
+ * @returns iprt status code.
+ *          Warnings are used to indicate conversion problems.
+ * @retval  VWRN_NUMBER_TOO_BIG
+ * @retval  VWRN_NEGATIVE_UNSIGNED
+ * @retval  VWRN_TRAILING_CHARS
+ * @retval  VWRN_TRAILING_SPACES
+ * @retval  VINF_SUCCESS
+ * @retval  VERR_NO_DIGITS
+ *
+ * @param   pszValue    Pointer to the string value.
+ * @param   ppszNext    Where to store the pointer to the first char following the number. (Optional)
+ * @param   uBase       The base of the representation used.
+ *                      If the function will look for known prefixes before defaulting to 10.
+ * @param   pu32        Where to store the converted number. (optional)
+ */
+RTDECL(int) RTStrToUInt32Ex(const char *pszValue, char **ppszNext, unsigned uBase, uint32_t *pu32)
+{
+    uint64_t u64;
+    int rc = RTStrToUInt64Ex(pszValue, ppszNext, uBase, &u64);
+    if (RT_SUCCESS(rc))
+    {
+        if (u64 & ~0xffffffffULL)
+            rc = VWRN_NUMBER_TOO_BIG;
+    }
+    if (pu32)
+        *pu32 = (uint32_t)u64;
+    return rc;
+}
+RT_EXPORT_SYMBOL(RTStrToUInt32Ex);
+
+
+/**
+ * Converts a string representation of a number to a 32-bit unsigned number,
+ * making sure the full string is converted.
+ *
+ * @returns iprt status code.
+ *          Warnings are used to indicate conversion problems.
+ * @retval  VWRN_NUMBER_TOO_BIG
+ * @retval  VWRN_NEGATIVE_UNSIGNED
+ * @retval  VINF_SUCCESS
+ * @retval  VERR_NO_DIGITS
+ * @retval  VERR_TRAILING_SPACES
+ * @retval  VERR_TRAILING_CHARS
+ *
+ * @param   pszValue    Pointer to the string value.
+ * @param   uBase       The base of the representation used.
+ *                      If the function will look for known prefixes before defaulting to 10.
+ * @param   pu32        Where to store the converted number. (optional)
+ */
+RTDECL(int) RTStrToUInt32Full(const char *pszValue, unsigned uBase, uint32_t *pu32)
+{
+    uint64_t u64;
+    int rc = RTStrToUInt64Full(pszValue, uBase, &u64);
+    if (RT_SUCCESS(rc))
+    {
+        if (u64 & ~0xffffffffULL)
+            rc = VWRN_NUMBER_TOO_BIG;
+    }
+    if (pu32)
+        *pu32 = (uint32_t)u64;
+    return rc;
+}
+RT_EXPORT_SYMBOL(RTStrToUInt32Full);
+
+
+/**
+ * Converts a string representation of a number to a 64-bit unsigned number.
+ * The base is guessed.
+ *
+ * @returns 32-bit unsigned number on success.
+ * @returns 0 on failure.
+ * @param   pszValue    Pointer to the string value.
+ */
+RTDECL(uint32_t) RTStrToUInt32(const char *pszValue)
+{
+    uint32_t u32;
+    int rc = RTStrToUInt32Ex(pszValue, NULL, 0, &u32);
+    if (RT_SUCCESS(rc))
+        return u32;
+    return 0;
+}
+RT_EXPORT_SYMBOL(RTStrToUInt32);
+
+
+/**
+ * Converts a string representation of a number to a 16-bit unsigned number.
+ *
+ * @returns iprt status code.
+ *          Warnings are used to indicate conversion problems.
+ * @retval  VWRN_NUMBER_TOO_BIG
+ * @retval  VWRN_NEGATIVE_UNSIGNED
+ * @retval  VWRN_TRAILING_CHARS
+ * @retval  VWRN_TRAILING_SPACES
+ * @retval  VINF_SUCCESS
+ * @retval  VERR_NO_DIGITS
+ *
+ * @param   pszValue    Pointer to the string value.
+ * @param   ppszNext    Where to store the pointer to the first char following the number. (Optional)
+ * @param   uBase       The base of the representation used.
+ *                      If the function will look for known prefixes before defaulting to 10.
+ * @param   pu16        Where to store the converted number. (optional)
+ */
+RTDECL(int) RTStrToUInt16Ex(const char *pszValue, char **ppszNext, unsigned uBase, uint16_t *pu16)
+{
+    uint64_t u64;
+    int rc = RTStrToUInt64Ex(pszValue, ppszNext, uBase, &u64);
+    if (RT_SUCCESS(rc))
+    {
+        if (u64 & ~0xffffULL)
+            rc = VWRN_NUMBER_TOO_BIG;
+    }
+    if (pu16)
+        *pu16 = (uint16_t)u64;
+    return rc;
+}
+RT_EXPORT_SYMBOL(RTStrToUInt16Ex);
+
+
+/**
+ * Converts a string representation of a number to a 16-bit unsigned number,
+ * making sure the full string is converted.
+ *
+ * @returns iprt status code.
+ *          Warnings are used to indicate conversion problems.
+ * @retval  VWRN_NUMBER_TOO_BIG
+ * @retval  VWRN_NEGATIVE_UNSIGNED
+ * @retval  VINF_SUCCESS
+ * @retval  VERR_NO_DIGITS
+ * @retval  VERR_TRAILING_SPACES
+ * @retval  VERR_TRAILING_CHARS
+ *
+ * @param   pszValue    Pointer to the string value.
+ * @param   uBase       The base of the representation used.
+ *                      If the function will look for known prefixes before defaulting to 10.
+ * @param   pu16        Where to store the converted number. (optional)
+ */
+RTDECL(int) RTStrToUInt16Full(const char *pszValue, unsigned uBase, uint16_t *pu16)
+{
+    uint64_t u64;
+    int rc = RTStrToUInt64Full(pszValue, uBase, &u64);
+    if (RT_SUCCESS(rc))
+    {
+        if (u64 & ~0xffffULL)
+            rc = VWRN_NUMBER_TOO_BIG;
+    }
+    if (pu16)
+        *pu16 = (uint16_t)u64;
+    return rc;
+}
+RT_EXPORT_SYMBOL(RTStrToUInt16Full);
+
+
+/**
+ * Converts a string representation of a number to a 16-bit unsigned number.
+ * The base is guessed.
+ *
+ * @returns 16-bit unsigned number on success.
+ * @returns 0 on failure.
+ * @param   pszValue    Pointer to the string value.
+ */
+RTDECL(uint16_t) RTStrToUInt16(const char *pszValue)
+{
+    uint16_t u16;
+    int rc = RTStrToUInt16Ex(pszValue, NULL, 0, &u16);
+    if (RT_SUCCESS(rc))
+        return u16;
+    return 0;
+}
+RT_EXPORT_SYMBOL(RTStrToUInt16);
+
+
+/**
+ * Converts a string representation of a number to a 8-bit unsigned number.
+ *
+ * @returns iprt status code.
+ *          Warnings are used to indicate conversion problems.
+ * @retval  VWRN_NUMBER_TOO_BIG
+ * @retval  VWRN_NEGATIVE_UNSIGNED
+ * @retval  VWRN_TRAILING_CHARS
+ * @retval  VWRN_TRAILING_SPACES
+ * @retval  VINF_SUCCESS
+ * @retval  VERR_NO_DIGITS
+ *
+ * @param   pszValue    Pointer to the string value.
+ * @param   ppszNext    Where to store the pointer to the first char following the number. (Optional)
+ * @param   uBase       The base of the representation used.
+ *                      If the function will look for known prefixes before defaulting to 10.
+ * @param   pu8         Where to store the converted number. (optional)
+ */
+RTDECL(int) RTStrToUInt8Ex(const char *pszValue, char **ppszNext, unsigned uBase, uint8_t *pu8)
+{
+    uint64_t u64;
+    int rc = RTStrToUInt64Ex(pszValue, ppszNext, uBase, &u64);
+    if (RT_SUCCESS(rc))
+    {
+        if (u64 & ~0xffULL)
+            rc = VWRN_NUMBER_TOO_BIG;
+    }
+    if (pu8)
+        *pu8 = (uint8_t)u64;
+    return rc;
+}
+RT_EXPORT_SYMBOL(RTStrToUInt8Ex);
+
+
+/**
+ * Converts a string representation of a number to a 8-bit unsigned number,
+ * making sure the full string is converted.
+ *
+ * @returns iprt status code.
+ *          Warnings are used to indicate conversion problems.
+ * @retval  VWRN_NUMBER_TOO_BIG
+ * @retval  VWRN_NEGATIVE_UNSIGNED
+ * @retval  VINF_SUCCESS
+ * @retval  VERR_NO_DIGITS
+ * @retval  VERR_TRAILING_SPACES
+ * @retval  VERR_TRAILING_CHARS
+ *
+ * @param   pszValue    Pointer to the string value.
+ * @param   uBase       The base of the representation used.
+ *                      If the function will look for known prefixes before defaulting to 10.
+ * @param   pu8         Where to store the converted number. (optional)
+ */
+RTDECL(int) RTStrToUInt8Full(const char *pszValue, unsigned uBase, uint8_t *pu8)
+{
+    uint64_t u64;
+    int rc = RTStrToUInt64Full(pszValue, uBase, &u64);
+    if (RT_SUCCESS(rc))
+    {
+        if (u64 & ~0xffULL)
+            rc = VWRN_NUMBER_TOO_BIG;
+    }
+    if (pu8)
+        *pu8 = (uint8_t)u64;
+    return rc;
+}
+RT_EXPORT_SYMBOL(RTStrToUInt8Full);
+
+
+/**
+ * Converts a string representation of a number to a 8-bit unsigned number.
+ * The base is guessed.
+ *
+ * @returns 8-bit unsigned number on success.
+ * @returns 0 on failure.
+ * @param   pszValue    Pointer to the string value.
+ */
+RTDECL(uint8_t) RTStrToUInt8(const char *pszValue)
+{
+    uint8_t u8;
+    int rc = RTStrToUInt8Ex(pszValue, NULL, 0, &u8);
+    if (RT_SUCCESS(rc))
+        return u8;
+    return 0;
+}
+RT_EXPORT_SYMBOL(RTStrToUInt8);
+
+
+
+
+
+
+
+/**
+ * Converts a string representation of a number to a 64-bit signed number.
+ *
+ * @returns iprt status code.
+ *          Warnings are used to indicate conversion problems.
+ * @retval  VWRN_NUMBER_TOO_BIG
+ * @retval  VWRN_TRAILING_CHARS
+ * @retval  VWRN_TRAILING_SPACES
+ * @retval  VINF_SUCCESS
+ * @retval  VERR_NO_DIGITS
+ *
+ * @param   pszValue    Pointer to the string value.
+ * @param   ppszNext    Where to store the pointer to the first char following the number. (Optional)
+ * @param   uBase       The base of the representation used.
+ *                      If the function will look for known prefixes before defaulting to 10.
+ * @param   pi64        Where to store the converted number. (optional)
+ */
+RTDECL(int) RTStrToInt64Ex(const char *pszValue, char **ppszNext, unsigned uBase, int64_t *pi64)
+{
+    const char   *psz = pszValue;
+    int           iShift;
+    int           rc;
+    int64_t       i64;
+    unsigned char uch;
+
+    /*
+     * Positive/Negative stuff.
+     */
+    bool fPositive = true;
+    for (;; psz++)
+    {
+        if (*psz == '+')
+            fPositive = true;
+        else if (*psz == '-')
+            fPositive = !fPositive;
+        else
+            break;
+    }
+
+    /*
+     * Check for hex prefix.
+     */
+    if (!uBase)
+    {
+        if (    *psz == '0'
+            &&  (psz[1] == 'x' || psz[1] == 'X')
+            &&  g_auchDigits[(unsigned char)psz[2]] < 16)
+        {
+            uBase = 16;
+            psz += 2;
+        }
+        else if (   *psz == '0'
+                 && g_auchDigits[(unsigned char)psz[1]] < 8)
+        {
+            uBase = 8;
+            psz++;
+        }
+        else
+            uBase = 10;
+    }
+    else if (   uBase == 16
+             && *psz == '0'
+             && (psz[1] == 'x' || psz[1] == 'X')
+             && g_auchDigits[(unsigned char)psz[2]] < 16)
+        psz += 2;
+
+    /*
+     * Interpret the value.
+     * Note: We only support ascii digits at this time... :-)
+     */
+    iShift = g_auchShift[uBase]; /** @todo test this, it's probably not 100% right yet. */
+    pszValue = psz; /* (Prefix and sign doesn't count in the digit counting.) */
+    rc = VINF_SUCCESS;
+    i64 = 0;
+    while ((uch = (unsigned char)*psz) != 0)
+    {
+        unsigned char chDigit = g_auchDigits[uch];
+        int64_t i64Prev;
+
+        if (chDigit >= uBase)
+            break;
+
+        i64Prev = i64;
+        i64 *= uBase;
+        i64 += chDigit;
+        if (i64Prev > i64 || (i64Prev >> iShift))
+            rc = VWRN_NUMBER_TOO_BIG;
+        psz++;
+    }
+
+    if (!fPositive)
+        i64 = -i64;
+
+    if (pi64)
+        *pi64 = i64;
+
+    if (psz == pszValue)
+        rc = VERR_NO_DIGITS;
+
+    if (ppszNext)
+        *ppszNext = (char *)psz;
+
+    /*
+     * Warn about trailing chars/spaces.
+     */
+    if (    rc == VINF_SUCCESS
+        &&  *psz)
+    {
+        while (*psz == ' ' || *psz == '\t')
+            psz++;
+        rc = *psz ? VWRN_TRAILING_CHARS : VWRN_TRAILING_SPACES;
+    }
+
+    return rc;
+}
+RT_EXPORT_SYMBOL(RTStrToInt64Ex);
+
+
+/**
+ * Converts a string representation of a number to a 64-bit signed number,
+ * making sure the full string is converted.
+ *
+ * @returns iprt status code.
+ *          Warnings are used to indicate conversion problems.
+ * @retval  VWRN_NUMBER_TOO_BIG
+ * @retval  VINF_SUCCESS
+ * @retval  VERR_TRAILING_CHARS
+ * @retval  VERR_TRAILING_SPACES
+ * @retval  VERR_NO_DIGITS
+ *
+ * @param   pszValue    Pointer to the string value.
+ * @param   uBase       The base of the representation used.
+ *                      If the function will look for known prefixes before defaulting to 10.
+ * @param   pi64        Where to store the converted number. (optional)
+ */
+RTDECL(int) RTStrToInt64Full(const char *pszValue, unsigned uBase, int64_t *pi64)
+{
+    char *psz;
+    int rc = RTStrToInt64Ex(pszValue, &psz, uBase, pi64);
+    if (RT_SUCCESS(rc) && *psz)
+    {
+        if (rc == VWRN_TRAILING_CHARS || rc == VWRN_TRAILING_SPACES)
+            rc = -rc;
+        else
+        {
+            while (*psz == ' ' || *psz == '\t')
+                psz++;
+            rc = *psz ? VERR_TRAILING_CHARS : VERR_TRAILING_SPACES;
+        }
+    }
+    return rc;
+}
+RT_EXPORT_SYMBOL(RTStrToInt64Full);
+
+
+/**
+ * Converts a string representation of a number to a 64-bit signed number.
+ * The base is guessed.
+ *
+ * @returns 64-bit signed number on success.
+ * @returns 0 on failure.
+ * @param   pszValue    Pointer to the string value.
+ */
+RTDECL(int64_t) RTStrToInt64(const char *pszValue)
+{
+    int64_t i64;
+    int rc = RTStrToInt64Ex(pszValue, NULL, 0, &i64);
+    if (RT_SUCCESS(rc))
+        return i64;
+    return 0;
+}
+RT_EXPORT_SYMBOL(RTStrToInt64);
+
+
+/**
+ * Converts a string representation of a number to a 32-bit signed number.
+ *
+ * @returns iprt status code.
+ *          Warnings are used to indicate conversion problems.
+ * @retval  VWRN_NUMBER_TOO_BIG
+ * @retval  VWRN_TRAILING_CHARS
+ * @retval  VWRN_TRAILING_SPACES
+ * @retval  VINF_SUCCESS
+ * @retval  VERR_NO_DIGITS
+ *
+ * @param   pszValue    Pointer to the string value.
+ * @param   ppszNext    Where to store the pointer to the first char following the number. (Optional)
+ * @param   uBase       The base of the representation used.
+ *                      If the function will look for known prefixes before defaulting to 10.
+ * @param   pi32        Where to store the converted number. (optional)
+ */
+RTDECL(int) RTStrToInt32Ex(const char *pszValue, char **ppszNext, unsigned uBase, int32_t *pi32)
+{
+    int64_t i64;
+    int rc = RTStrToInt64Ex(pszValue, ppszNext, uBase, &i64);
+    if (RT_SUCCESS(rc))
+    {
+        int32_t i32 = (int32_t)i64;
+        if (i64 != (int64_t)i32)
+            rc = VWRN_NUMBER_TOO_BIG;
+    }
+    if (pi32)
+        *pi32 = (int32_t)i64;
+    return rc;
+}
+RT_EXPORT_SYMBOL(RTStrToInt32Ex);
+
+
+/**
+ * Converts a string representation of a number to a 32-bit signed number,
+ * making sure the full string is converted.
+ *
+ * @returns iprt status code.
+ *          Warnings are used to indicate conversion problems.
+ * @retval  VWRN_NUMBER_TOO_BIG
+ * @retval  VINF_SUCCESS
+ * @retval  VERR_TRAILING_CHARS
+ * @retval  VERR_TRAILING_SPACES
+ * @retval  VERR_NO_DIGITS
+ *
+ * @param   pszValue    Pointer to the string value.
+ * @param   uBase       The base of the representation used.
+ *                      If the function will look for known prefixes before defaulting to 10.
+ * @param   pi32        Where to store the converted number. (optional)
+ */
+RTDECL(int) RTStrToInt32Full(const char *pszValue, unsigned uBase, int32_t *pi32)
+{
+    int64_t i64;
+    int rc = RTStrToInt64Full(pszValue, uBase, &i64);
+    if (RT_SUCCESS(rc))
+    {
+        int32_t i32 = (int32_t)i64;
+        if (i64 != (int64_t)i32)
+            rc = VWRN_NUMBER_TOO_BIG;
+    }
+    if (pi32)
+        *pi32 = (int32_t)i64;
+    return rc;
+}
+RT_EXPORT_SYMBOL(RTStrToInt32Full);
+
+
+/**
+ * Converts a string representation of a number to a 32-bit signed number.
+ * The base is guessed.
+ *
+ * @returns 32-bit signed number on success.
+ * @returns 0 on failure.
+ * @param   pszValue    Pointer to the string value.
+ */
+RTDECL(int32_t) RTStrToInt32(const char *pszValue)
+{
+    int32_t i32;
+    int rc = RTStrToInt32Ex(pszValue, NULL, 0, &i32);
+    if (RT_SUCCESS(rc))
+        return i32;
+    return 0;
+}
+RT_EXPORT_SYMBOL(RTStrToInt32);
+
+
+/**
+ * Converts a string representation of a number to a 16-bit signed number.
+ *
+ * @returns iprt status code.
+ *          Warnings are used to indicate conversion problems.
+ * @retval  VWRN_NUMBER_TOO_BIG
+ * @retval  VWRN_TRAILING_CHARS
+ * @retval  VWRN_TRAILING_SPACES
+ * @retval  VINF_SUCCESS
+ * @retval  VERR_NO_DIGITS
+ *
+ * @param   pszValue    Pointer to the string value.
+ * @param   ppszNext    Where to store the pointer to the first char following the number. (Optional)
+ * @param   uBase       The base of the representation used.
+ *                      If the function will look for known prefixes before defaulting to 10.
+ * @param   pi16        Where to store the converted number. (optional)
+ */
+RTDECL(int) RTStrToInt16Ex(const char *pszValue, char **ppszNext, unsigned uBase, int16_t *pi16)
+{
+    int64_t i64;
+    int rc = RTStrToInt64Ex(pszValue, ppszNext, uBase, &i64);
+    if (RT_SUCCESS(rc))
+    {
+        int16_t i16 = (int16_t)i64;
+        if (i64 != (int64_t)i16)
+            rc = VWRN_NUMBER_TOO_BIG;
+    }
+    if (pi16)
+        *pi16 = (int16_t)i64;
+    return rc;
+}
+RT_EXPORT_SYMBOL(RTStrToInt16Ex);
+
+
+/**
+ * Converts a string representation of a number to a 16-bit signed number,
+ * making sure the full string is converted.
+ *
+ * @returns iprt status code.
+ *          Warnings are used to indicate conversion problems.
+ * @retval  VWRN_NUMBER_TOO_BIG
+ * @retval  VINF_SUCCESS
+ * @retval  VERR_TRAILING_CHARS
+ * @retval  VERR_TRAILING_SPACES
+ * @retval  VERR_NO_DIGITS
+ *
+ * @param   pszValue    Pointer to the string value.
+ * @param   uBase       The base of the representation used.
+ *                      If the function will look for known prefixes before defaulting to 10.
+ * @param   pi16        Where to store the converted number. (optional)
+ */
+RTDECL(int) RTStrToInt16Full(const char *pszValue, unsigned uBase, int16_t *pi16)
+{
+    int64_t i64;
+    int rc = RTStrToInt64Full(pszValue, uBase, &i64);
+    if (RT_SUCCESS(rc))
+    {
+        int16_t i16 = (int16_t)i64;
+        if (i64 != (int64_t)i16)
+            rc = VWRN_NUMBER_TOO_BIG;
+    }
+    if (pi16)
+        *pi16 = (int16_t)i64;
+    return rc;
+}
+RT_EXPORT_SYMBOL(RTStrToInt16Full);
+
+
+/**
+ * Converts a string representation of a number to a 16-bit signed number.
+ * The base is guessed.
+ *
+ * @returns 16-bit signed number on success.
+ * @returns 0 on failure.
+ * @param   pszValue    Pointer to the string value.
+ */
+RTDECL(int16_t) RTStrToInt16(const char *pszValue)
+{
+    int16_t i16;
+    int rc = RTStrToInt16Ex(pszValue, NULL, 0, &i16);
+    if (RT_SUCCESS(rc))
+        return i16;
+    return 0;
+}
+RT_EXPORT_SYMBOL(RTStrToInt16);
+
+
+/**
+ * Converts a string representation of a number to a 8-bit signed number.
+ *
+ * @returns iprt status code.
+ *          Warnings are used to indicate conversion problems.
+ * @retval  VWRN_NUMBER_TOO_BIG
+ * @retval  VWRN_TRAILING_CHARS
+ * @retval  VWRN_TRAILING_SPACES
+ * @retval  VINF_SUCCESS
+ * @retval  VERR_NO_DIGITS
+ *
+ * @param   pszValue    Pointer to the string value.
+ * @param   ppszNext    Where to store the pointer to the first char following the number. (Optional)
+ * @param   uBase       The base of the representation used.
+ *                      If the function will look for known prefixes before defaulting to 10.
+ * @param   pi8        Where to store the converted number. (optional)
+ */
+RTDECL(int) RTStrToInt8Ex(const char *pszValue, char **ppszNext, unsigned uBase, int8_t *pi8)
+{
+    int64_t i64;
+    int rc = RTStrToInt64Ex(pszValue, ppszNext, uBase, &i64);
+    if (RT_SUCCESS(rc))
+    {
+        int8_t i8 = (int8_t)i64;
+        if (i64 != (int64_t)i8)
+            rc = VWRN_NUMBER_TOO_BIG;
+    }
+    if (pi8)
+        *pi8 = (int8_t)i64;
+    return rc;
+}
+RT_EXPORT_SYMBOL(RTStrToInt8Ex);
+
+
+/**
+ * Converts a string representation of a number to a 8-bit signed number,
+ * making sure the full string is converted.
+ *
+ * @returns iprt status code.
+ *          Warnings are used to indicate conversion problems.
+ * @retval  VWRN_NUMBER_TOO_BIG
+ * @retval  VINF_SUCCESS
+ * @retval  VERR_TRAILING_CHARS
+ * @retval  VERR_TRAILING_SPACES
+ * @retval  VERR_NO_DIGITS
+ *
+ * @param   pszValue    Pointer to the string value.
+ * @param   uBase       The base of the representation used.
+ *                      If the function will look for known prefixes before defaulting to 10.
+ * @param   pi8         Where to store the converted number. (optional)
+ */
+RTDECL(int) RTStrToInt8Full(const char *pszValue, unsigned uBase, int8_t *pi8)
+{
+    int64_t i64;
+    int rc = RTStrToInt64Full(pszValue, uBase, &i64);
+    if (RT_SUCCESS(rc))
+    {
+        int8_t i8 = (int8_t)i64;
+        if (i64 != (int64_t)i8)
+            rc = VWRN_NUMBER_TOO_BIG;
+    }
+    if (pi8)
+        *pi8 = (int8_t)i64;
+    return rc;
+}
+RT_EXPORT_SYMBOL(RTStrToInt8Full);
+
+
+/**
+ * Converts a string representation of a number to a 8-bit signed number.
+ * The base is guessed.
+ *
+ * @returns 8-bit signed number on success.
+ * @returns 0 on failure.
+ * @param   pszValue    Pointer to the string value.
+ */
+RTDECL(int8_t) RTStrToInt8(const char *pszValue)
+{
+    int8_t i8;
+    int rc = RTStrToInt8Ex(pszValue, NULL, 0, &i8);
+    if (RT_SUCCESS(rc))
+        return i8;
+    return 0;
+}
+RT_EXPORT_SYMBOL(RTStrToInt8);
+
+
+RTDECL(int) RTStrConvertHexBytes(char const *pszHex, void *pv, size_t cb, uint32_t fFlags)
+{
+    size_t      cbDst;
+    uint8_t    *pbDst;
+    const char *pszSrc;
+
+    AssertPtrReturn(pszHex, VERR_INVALID_POINTER);
+    AssertReturn(!fFlags, VERR_INVALID_PARAMETER);
+
+    cbDst  = cb;
+    pbDst  = (uint8_t *)pv;
+    pszSrc = pszHex;
+    for (;;)
+    {
+        /* Pick the next two digit from the string. */
+        char ch = *pszSrc++;
+        unsigned char uchDigit1 = g_auchDigits[(unsigned char)ch];
+        unsigned char uchDigit2;
+        if (uchDigit1 >= 16)
+        {
+            if (!ch)
+                return cbDst == 0 ? VINF_SUCCESS : VERR_BUFFER_UNDERFLOW;
+
+            while (ch == ' ' || ch == '\t')
+                ch = *pszSrc++;
+            return ch ? VWRN_TRAILING_CHARS : VWRN_TRAILING_SPACES;
+        }
+
+        ch = *pszSrc++;
+        uchDigit2 = g_auchDigits[(unsigned char)ch];
+        if (uchDigit2 >= 16)
+            return VERR_UNEVEN_INPUT;
+
+        /* Add the byte to the output buffer. */
+        if (!cbDst)
+            return VERR_BUFFER_OVERFLOW;
+        cbDst--;
+        *pbDst++ = (uchDigit1 << 4) | uchDigit2;
+    }
+}
+RT_EXPORT_SYMBOL(RTStrConvertHexBytes);
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/vboxguest/common/table/avl_Base.cpp.h
@@ -0,0 +1,460 @@
+/* $Id: avl_Base.cpp.h $ */
+/** @file
+ * kAVLBase - basic routines for all AVL trees.
+ */
+
+/*
+ * Copyright (C) 2001-2012 knut st. osmundsen (bird-src-spam@anduin.net)
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+#ifndef _kAVLBase_h_
+#define _kAVLBase_h_
+
+
+/** @page   pg_rt_kAVL kAVL Template configuration.
+ * @internal
+ *
+ *  This is a template made to implement multiple AVL trees. The differences
+ *  among the implementations are related to the key used.
+ *
+ *  \#define KAVL_FN
+ *  Use this to alter the names of the AVL functions.
+ *  Must be defined.
+ *
+ *  \#define KAVL_EQUAL_ALLOWED
+ *  Define this to tell us that equal keys are allowed.
+ *  Then Equal keys will be put in a list pointed to by pList in the KAVLNODECORE.
+ *  This is by default not defined.
+ *
+ *  \#define KAVL_CHECK_FOR_EQUAL_INSERT
+ *  Define this to enable insert check for equal nodes.
+ *  This is by default not defined.
+ *
+ *  \#define KAVL_MAX_STACK
+ *  Use this to specify the number of stack entries the stack will use when inserting
+ *  and removing nodes from the tree. I think the size should be about
+ *      log2(<max nodes>) + 3
+ *  Must be defined.
+ *
+ */
+
+/*******************************************************************************
+*   Defined Constants And Macros                                               *
+*******************************************************************************/
+#define AVL_HEIGHTOF(pNode) ((unsigned char)((pNode) != NULL ? pNode->uchHeight : 0))
+
+/** @def KAVL_GET_POINTER
+ * Reads a 'pointer' value.
+ *
+ * @returns The native pointer.
+ * @param   pp      Pointer to the pointer to read.
+ */
+
+/** @def KAVL_GET_POINTER_NULL
+ * Reads a 'pointer' value which can be KAVL_NULL.
+ *
+ * @returns The native pointer.
+ * @returns NULL pointer if KAVL_NULL.
+ * @param   pp      Pointer to the pointer to read.
+ */
+
+/** @def KAVL_SET_POINTER
+ * Writes a 'pointer' value.
+ * For offset-based schemes offset relative to pp is calculated and assigned to *pp.
+ *
+ * @returns stored pointer.
+ * @param   pp      Pointer to where to store the pointer.
+ * @param   p       Native pointer to assign to *pp.
+ */
+
+/** @def KAVL_SET_POINTER_NULL
+ * Writes a 'pointer' value which can be KAVL_NULL.
+ *
+ * For offset-based schemes offset relative to pp is calculated and assigned to *pp,
+ * if p is not KAVL_NULL of course.
+ *
+ * @returns stored pointer.
+ * @param   pp      Pointer to where to store the pointer.
+ * @param   pp2     Pointer to where to pointer to assign to pp. This can be KAVL_NULL
+ */
+
+#ifndef KAVL_GET_POINTER
+# ifdef KAVL_OFFSET
+#  define KAVL_GET_POINTER(pp)              ( (PKAVLNODECORE)((intptr_t)(pp) + *(pp)) )
+#  define KAVL_GET_POINTER_NULL(pp)         ( *(pp) != KAVL_NULL ? KAVL_GET_POINTER(pp) : NULL )
+#  define KAVL_SET_POINTER(pp, p)           ( (*(pp)) = ((intptr_t)(p) - (intptr_t)(pp)) )
+#  define KAVL_SET_POINTER_NULL(pp, pp2)    ( (*(pp)) = *(pp2) != KAVL_NULL ? (intptr_t)KAVL_GET_POINTER(pp2) - (intptr_t)(pp) : KAVL_NULL )
+# else
+#  define KAVL_GET_POINTER(pp)              ( *(pp) )
+#  define KAVL_GET_POINTER_NULL(pp)         ( *(pp) )
+#  define KAVL_SET_POINTER(pp, p)           ( (*(pp)) = (p) )
+#  define KAVL_SET_POINTER_NULL(pp, pp2)    ( (*(pp)) = *(pp2) )
+# endif
+#endif
+
+
+/** @def KAVL_NULL
+ * The NULL 'pointer' equivalent.
+ */
+#ifndef KAVL_NULL
+# ifdef KAVL_OFFSET
+#  define KAVL_NULL     0
+# else
+#  define KAVL_NULL     NULL
+# endif
+#endif
+
+#ifndef KAVL_RANGE
+# define KAVL_R_IS_INTERSECTING(key1B, key2B, key1E, key2E) KAVL_E(key1B, key2B)
+# define KAVL_R_IS_IDENTICAL(key1B, key2B, key1E, key2E)    KAVL_E(key1B, key2B)
+#endif
+
+/** @def KAVL_DECL
+ * Function declation macro in the RTDECL tradition.
+ * @param   a_Type      The function return type.  */
+#ifndef KAVL_DECL
+# define KAVL_DECL(a_Type)  RTDECL(a_Type)
+#endif
+
+
+/*******************************************************************************
+*   Structures and Typedefs                                                    *
+*******************************************************************************/
+/*
+ * A stack used to avoid recursive calls...
+ */
+typedef struct _kAvlStack
+{
+    unsigned        cEntries;
+    PPKAVLNODECORE  aEntries[KAVL_MAX_STACK];
+} KAVLSTACK, *PKAVLSTACK;
+
+typedef struct _kAvlStack2
+{
+    unsigned        cEntries;
+    PKAVLNODECORE   aEntries[KAVL_MAX_STACK];
+    char            achFlags[KAVL_MAX_STACK];
+} KAVLSTACK2, *PLAVLSTACK2;
+
+
+
+/**
+ * Rewinds a stack of pointers to pointers to nodes, rebalancing the tree.
+ * @param     pStack  Pointer to stack to rewind.
+ * @sketch    LOOP thru all stack entries
+ *            BEGIN
+ *                Get pointer to pointer to node (and pointer to node) from the stack.
+ *                IF 2 higher left subtree than in right subtree THEN
+ *                BEGIN
+ *                    IF higher (or equal) left-sub-subtree than right-sub-subtree THEN
+ *                                *                       n+2|n+3
+ *                              /   \                     /     \
+ *                            n+2    n       ==>         n+1   n+1|n+2
+ *                           /   \                             /     \
+ *                         n+1 n|n+1                          n|n+1  n
+ *
+ *                         Or with keys:
+ *
+ *                               4                           2
+ *                             /   \                       /   \
+ *                            2     5        ==>          1     4
+ *                           / \                               / \
+ *                          1   3                             3   5
+ *
+ *                    ELSE
+ *                                *                         n+2
+ *                              /   \                      /   \
+ *                            n+2    n                   n+1   n+1
+ *                           /   \           ==>        /  \   /  \
+ *                          n    n+1                    n  L   R   n
+ *                               / \
+ *                              L   R
+ *
+ *                         Or with keys:
+ *                               6                           4
+ *                             /   \                       /   \
+ *                            2     7        ==>          2     6
+ *                          /   \                       /  \  /  \
+ *                          1    4                      1  3  5  7
+ *                              / \
+ *                             3   5
+ *                END
+ *                ELSE IF 2 higher in right subtree than in left subtree THEN
+ *                BEGIN
+ *                    Same as above but left <==> right. (invert the picture)
+ *                ELSE
+ *                    IF correct height THEN break
+ *                    ELSE correct height.
+ *            END
+ */
+DECLINLINE(void) KAVL_FN(Rebalance)(PKAVLSTACK pStack)
+{
+    while (pStack->cEntries > 0)
+    {
+        /** @todo Perhaps some of these KAVL_SET_POINTER_NULL() cases could be optimized away.. */
+        PPKAVLNODECORE   ppNode = pStack->aEntries[--pStack->cEntries];
+        PKAVLNODECORE    pNode = KAVL_GET_POINTER(ppNode);
+        PKAVLNODECORE    pLeftNode = KAVL_GET_POINTER_NULL(&pNode->pLeft);
+        unsigned char    uchLeftHeight = AVL_HEIGHTOF(pLeftNode);
+        PKAVLNODECORE    pRightNode = KAVL_GET_POINTER_NULL(&pNode->pRight);
+        unsigned char    uchRightHeight = AVL_HEIGHTOF(pRightNode);
+
+        if (uchRightHeight + 1 < uchLeftHeight)
+        {
+            PKAVLNODECORE    pLeftLeftNode = KAVL_GET_POINTER_NULL(&pLeftNode->pLeft);
+            PKAVLNODECORE    pLeftRightNode = KAVL_GET_POINTER_NULL(&pLeftNode->pRight);
+            unsigned char    uchLeftRightHeight = AVL_HEIGHTOF(pLeftRightNode);
+
+            if (AVL_HEIGHTOF(pLeftLeftNode) >= uchLeftRightHeight)
+            {
+                KAVL_SET_POINTER_NULL(&pNode->pLeft, &pLeftNode->pRight);
+                KAVL_SET_POINTER(&pLeftNode->pRight, pNode);
+                pLeftNode->uchHeight = (unsigned char)(1 + (pNode->uchHeight = (unsigned char)(1 + uchLeftRightHeight)));
+                KAVL_SET_POINTER(ppNode, pLeftNode);
+            }
+            else
+            {
+                KAVL_SET_POINTER_NULL(&pLeftNode->pRight, &pLeftRightNode->pLeft);
+                KAVL_SET_POINTER_NULL(&pNode->pLeft, &pLeftRightNode->pRight);
+                KAVL_SET_POINTER(&pLeftRightNode->pLeft, pLeftNode);
+                KAVL_SET_POINTER(&pLeftRightNode->pRight, pNode);
+                pLeftNode->uchHeight = pNode->uchHeight = uchLeftRightHeight;
+                pLeftRightNode->uchHeight = uchLeftHeight;
+                KAVL_SET_POINTER(ppNode, pLeftRightNode);
+            }
+        }
+        else if (uchLeftHeight + 1 < uchRightHeight)
+        {
+            PKAVLNODECORE    pRightLeftNode = KAVL_GET_POINTER_NULL(&pRightNode->pLeft);
+            unsigned char    uchRightLeftHeight = AVL_HEIGHTOF(pRightLeftNode);
+            PKAVLNODECORE    pRightRightNode = KAVL_GET_POINTER_NULL(&pRightNode->pRight);
+
+            if (AVL_HEIGHTOF(pRightRightNode) >= uchRightLeftHeight)
+            {
+                KAVL_SET_POINTER_NULL(&pNode->pRight, &pRightNode->pLeft);
+                KAVL_SET_POINTER(&pRightNode->pLeft, pNode);
+                pRightNode->uchHeight = (unsigned char)(1 + (pNode->uchHeight = (unsigned char)(1 + uchRightLeftHeight)));
+                KAVL_SET_POINTER(ppNode, pRightNode);
+            }
+            else
+            {
+                KAVL_SET_POINTER_NULL(&pRightNode->pLeft, &pRightLeftNode->pRight);
+                KAVL_SET_POINTER_NULL(&pNode->pRight, &pRightLeftNode->pLeft);
+                KAVL_SET_POINTER(&pRightLeftNode->pRight, pRightNode);
+                KAVL_SET_POINTER(&pRightLeftNode->pLeft, pNode);
+                pRightNode->uchHeight = pNode->uchHeight = uchRightLeftHeight;
+                pRightLeftNode->uchHeight = uchRightHeight;
+                KAVL_SET_POINTER(ppNode, pRightLeftNode);
+            }
+        }
+        else
+        {
+            register unsigned char uchHeight = (unsigned char)(KMAX(uchLeftHeight, uchRightHeight) + 1);
+            if (uchHeight == pNode->uchHeight)
+                break;
+            pNode->uchHeight = uchHeight;
+        }
+    }
+
+}
+
+
+
+
+/**
+ * Inserts a node into the AVL-tree.
+ * @returns   TRUE if inserted.
+ *            FALSE if node exists in tree.
+ * @param     ppTree  Pointer to the AVL-tree root node pointer.
+ * @param     pNode   Pointer to the node which is to be added.
+ * @sketch    Find the location of the node (using binary tree algorithm.):
+ *            LOOP until KAVL_NULL leaf pointer
+ *            BEGIN
+ *                Add node pointer pointer to the AVL-stack.
+ *                IF new-node-key < node key THEN
+ *                    left
+ *                ELSE
+ *                    right
+ *            END
+ *            Fill in leaf node and insert it.
+ *            Rebalance the tree.
+ */
+KAVL_DECL(bool) KAVL_FN(Insert)(PPKAVLNODECORE ppTree, PKAVLNODECORE pNode)
+{
+    KAVLSTACK               AVLStack;
+    PPKAVLNODECORE          ppCurNode = ppTree;
+    register PKAVLNODECORE  pCurNode;
+    register KAVLKEY        Key = pNode->Key; NOREF(Key);
+#ifdef KAVL_RANGE
+    register KAVLKEY        KeyLast = pNode->KeyLast; NOREF(KeyLast);
+#endif
+
+    AVLStack.cEntries = 0;
+
+#ifdef KAVL_RANGE
+    if (Key > KeyLast)
+        return false;
+#endif
+
+    for (;;)
+    {
+        if (*ppCurNode != KAVL_NULL)
+            pCurNode = KAVL_GET_POINTER(ppCurNode);
+        else
+            break;
+
+        kASSERT(AVLStack.cEntries < KAVL_MAX_STACK);
+        AVLStack.aEntries[AVLStack.cEntries++] = ppCurNode;
+#ifdef KAVL_EQUAL_ALLOWED
+        if (KAVL_R_IS_IDENTICAL(pCurNode->Key, Key, pCurNode->KeyLast, KeyLast))
+        {
+            /*
+             * If equal then we'll use a list of equal nodes.
+             */
+            pNode->pLeft = pNode->pRight = KAVL_NULL;
+            pNode->uchHeight = 0;
+            KAVL_SET_POINTER_NULL(&pNode->pList, &pCurNode->pList);
+            KAVL_SET_POINTER(&pCurNode->pList, pNode);
+            return true;
+        }
+#endif
+#ifdef KAVL_CHECK_FOR_EQUAL_INSERT
+        if (KAVL_R_IS_INTERSECTING(pCurNode->Key, Key, pCurNode->KeyLast, KeyLast))
+            return false;
+#endif
+        if (KAVL_G(pCurNode->Key, Key))
+            ppCurNode = &pCurNode->pLeft;
+        else
+            ppCurNode = &pCurNode->pRight;
+    }
+
+    pNode->pLeft = pNode->pRight = KAVL_NULL;
+#ifdef KAVL_EQUAL_ALLOWED
+    pNode->pList = KAVL_NULL;
+#endif
+    pNode->uchHeight = 1;
+    KAVL_SET_POINTER(ppCurNode, pNode);
+
+    KAVL_FN(Rebalance)(SSToDS(&AVLStack));
+    return true;
+}
+
+
+/**
+ * Removes a node from the AVL-tree.
+ * @returns   Pointer to the node.
+ * @param     ppTree  Pointer to the AVL-tree root node pointer.
+ * @param     Key     Key value of the node which is to be removed.
+ * @sketch    Find the node which is to be removed:
+ *            LOOP until not found
+ *            BEGIN
+ *                Add node pointer pointer to the AVL-stack.
+ *                IF the keys matches THEN break!
+ *                IF remove key < node key THEN
+ *                    left
+ *                ELSE
+ *                    right
+ *            END
+ *            IF found THEN
+ *            BEGIN
+ *                IF left node not empty THEN
+ *                BEGIN
+ *                    Find the right most node in the left tree while adding the pointer to the pointer to it's parent to the stack:
+ *                    Start at left node.
+ *                    LOOP until right node is empty
+ *                    BEGIN
+ *                        Add to stack.
+ *                        go right.
+ *                    END
+ *                    Link out the found node.
+ *                    Replace the node which is to be removed with the found node.
+ *                    Correct the stack entry for the pointer to the left tree.
+ *                END
+ *                ELSE
+ *                BEGIN
+ *                    Move up right node.
+ *                    Remove last stack entry.
+ *                END
+ *                Balance tree using stack.
+ *            END
+ *            return pointer to the removed node (if found).
+ */
+KAVL_DECL(PKAVLNODECORE) KAVL_FN(Remove)(PPKAVLNODECORE ppTree, KAVLKEY Key)
+{
+    KAVLSTACK                AVLStack;
+    PPKAVLNODECORE           ppDeleteNode = ppTree;
+    register PKAVLNODECORE   pDeleteNode;
+
+    AVLStack.cEntries = 0;
+
+    for (;;)
+    {
+        if (*ppDeleteNode != KAVL_NULL)
+            pDeleteNode = KAVL_GET_POINTER(ppDeleteNode);
+        else
+            return NULL;
+
+        kASSERT(AVLStack.cEntries < KAVL_MAX_STACK);
+        AVLStack.aEntries[AVLStack.cEntries++] = ppDeleteNode;
+        if (KAVL_E(pDeleteNode->Key, Key))
+            break;
+
+        if (KAVL_G(pDeleteNode->Key, Key))
+            ppDeleteNode = &pDeleteNode->pLeft;
+        else
+            ppDeleteNode = &pDeleteNode->pRight;
+    }
+
+    if (pDeleteNode->pLeft != KAVL_NULL)
+    {
+        /* find the rightmost node in the left tree. */
+        const unsigned          iStackEntry = AVLStack.cEntries;
+        PPKAVLNODECORE          ppLeftLeast = &pDeleteNode->pLeft;
+        register PKAVLNODECORE  pLeftLeast = KAVL_GET_POINTER(ppLeftLeast);
+
+        while (pLeftLeast->pRight != KAVL_NULL)
+        {
+            kASSERT(AVLStack.cEntries < KAVL_MAX_STACK);
+            AVLStack.aEntries[AVLStack.cEntries++] = ppLeftLeast;
+            ppLeftLeast = &pLeftLeast->pRight;
+            pLeftLeast  = KAVL_GET_POINTER(ppLeftLeast);
+        }
+
+        /* link out pLeftLeast */
+        KAVL_SET_POINTER_NULL(ppLeftLeast, &pLeftLeast->pLeft);
+
+        /* link it in place of the delete node. */
+        KAVL_SET_POINTER_NULL(&pLeftLeast->pLeft, &pDeleteNode->pLeft);
+        KAVL_SET_POINTER_NULL(&pLeftLeast->pRight, &pDeleteNode->pRight);
+        pLeftLeast->uchHeight = pDeleteNode->uchHeight;
+        KAVL_SET_POINTER(ppDeleteNode, pLeftLeast);
+        AVLStack.aEntries[iStackEntry] = &pLeftLeast->pLeft;
+    }
+    else
+    {
+        KAVL_SET_POINTER_NULL(ppDeleteNode, &pDeleteNode->pRight);
+        AVLStack.cEntries--;
+    }
+
+    KAVL_FN(Rebalance)(SSToDS(&AVLStack));
+    return pDeleteNode;
+}
+
+#endif
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/vboxguest/common/table/avl_Destroy.cpp.h
@@ -0,0 +1,110 @@
+/* $Id: avl_Destroy.cpp.h $ */
+/** @file
+ * kAVLDestroy - Walk the tree calling a callback to destroy all the nodes.
+ */
+
+/*
+ * Copyright (C) 1999-2011 knut st. osmundsen (bird-src-spam@anduin.net)
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+#ifndef _kAVLDestroy_h_
+#define _kAVLDestroy_h_
+
+
+/**
+ * Destroys the specified tree, starting with the root node and working our way down.
+ *
+ * @returns 0 on success.
+ * @returns Return value from callback on failure. On failure, the tree will be in
+ *          an unbalanced condition and only further calls to the Destroy should be
+ *          made on it. Note that the node we fail on will be considered dead and
+ *          no action is taken to link it back into the tree.
+ * @param   ppTree          Pointer to the AVL-tree root node pointer.
+ * @param   pfnCallBack     Pointer to callback function.
+ * @param   pvUser          User parameter passed on to the callback function.
+ */
+KAVL_DECL(int) KAVL_FN(Destroy)(PPKAVLNODECORE ppTree, PKAVLCALLBACK pfnCallBack, void *pvUser)
+{
+    unsigned        cEntries;
+    PKAVLNODECORE   apEntries[KAVL_MAX_STACK];
+    int             rc;
+
+    if (*ppTree == KAVL_NULL)
+        return VINF_SUCCESS;
+
+    cEntries = 1;
+    apEntries[0] = KAVL_GET_POINTER(ppTree);
+    while (cEntries > 0)
+    {
+        /*
+         * Process the subtrees first.
+         */
+        PKAVLNODECORE pNode = apEntries[cEntries - 1];
+        if (pNode->pLeft != KAVL_NULL)
+            apEntries[cEntries++] = KAVL_GET_POINTER(&pNode->pLeft);
+        else if (pNode->pRight != KAVL_NULL)
+            apEntries[cEntries++] = KAVL_GET_POINTER(&pNode->pRight);
+        else
+        {
+#ifdef KAVL_EQUAL_ALLOWED
+            /*
+             * Process nodes with the same key.
+             */
+            while (pNode->pList != KAVL_NULL)
+            {
+                PKAVLNODECORE pEqual = KAVL_GET_POINTER(&pNode->pList);
+                KAVL_SET_POINTER(&pNode->pList, KAVL_GET_POINTER_NULL(&pEqual->pList));
+                pEqual->pList = KAVL_NULL;
+
+                rc = pfnCallBack(pEqual, pvUser);
+                if (rc != VINF_SUCCESS)
+                    return rc;
+            }
+#endif
+
+            /*
+             * Unlink the node.
+             */
+            if (--cEntries > 0)
+            {
+                PKAVLNODECORE pParent = apEntries[cEntries - 1];
+                if (KAVL_GET_POINTER(&pParent->pLeft) == pNode)
+                    pParent->pLeft = KAVL_NULL;
+                else
+                    pParent->pRight = KAVL_NULL;
+            }
+            else
+                *ppTree = KAVL_NULL;
+
+            kASSERT(pNode->pLeft == KAVL_NULL);
+            kASSERT(pNode->pRight == KAVL_NULL);
+            rc = pfnCallBack(pNode, pvUser);
+            if (rc != VINF_SUCCESS)
+                return rc;
+        }
+    } /* while */
+
+    kASSERT(*ppTree == KAVL_NULL);
+
+    return VINF_SUCCESS;
+}
+
+#endif
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/vboxguest/common/table/avl_DoWithAll.cpp.h
@@ -0,0 +1,142 @@
+/* $Id: avl_DoWithAll.cpp.h $ */
+/** @file
+ * kAVLDoWithAll - Do with all nodes routine for AVL trees.
+ */
+
+/*
+ * Copyright (C) 1999-2011 knut st. osmundsen (bird-src-spam@anduin.net)
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+#ifndef _kAVLDoWithAll_h_
+#define _kAVLDoWithAll_h_
+
+
+/**
+ * Iterates thru all nodes in the given tree.
+ * @returns   0 on success. Return from callback on failure.
+ * @param     ppTree   Pointer to the AVL-tree root node pointer.
+ * @param     fFromLeft    TRUE:  Left to right.
+ *                         FALSE: Right to left.
+ * @param     pfnCallBack  Pointer to callback function.
+ * @param     pvParam      Userparameter passed on to the callback function.
+ */
+KAVL_DECL(int) KAVL_FN(DoWithAll)(PPKAVLNODECORE ppTree, int fFromLeft, PKAVLCALLBACK pfnCallBack, void * pvParam)
+{
+    KAVLSTACK2      AVLStack;
+    PKAVLNODECORE   pNode;
+#ifdef KAVL_EQUAL_ALLOWED
+    PKAVLNODECORE   pEqual;
+#endif
+    int             rc;
+
+    if (*ppTree == KAVL_NULL)
+        return VINF_SUCCESS;
+
+    AVLStack.cEntries = 1;
+    AVLStack.achFlags[0] = 0;
+    AVLStack.aEntries[0] = KAVL_GET_POINTER(ppTree);
+
+    if (fFromLeft)
+    {   /* from left */
+        while (AVLStack.cEntries > 0)
+        {
+            pNode = AVLStack.aEntries[AVLStack.cEntries - 1];
+
+            /* left */
+            if (!AVLStack.achFlags[AVLStack.cEntries - 1]++)
+            {
+                if (pNode->pLeft != KAVL_NULL)
+                {
+                    AVLStack.achFlags[AVLStack.cEntries] = 0; /* 0 first, 1 last */
+                    AVLStack.aEntries[AVLStack.cEntries++] = KAVL_GET_POINTER(&pNode->pLeft);
+                    continue;
+                }
+            }
+
+            /* center */
+            rc = pfnCallBack(pNode, pvParam);
+            if (rc != VINF_SUCCESS)
+                return rc;
+#ifdef KAVL_EQUAL_ALLOWED
+            if (pNode->pList != KAVL_NULL)
+                for (pEqual = KAVL_GET_POINTER(&pNode->pList); pEqual; pEqual = KAVL_GET_POINTER_NULL(&pEqual->pList))
+                {
+                    rc = pfnCallBack(pEqual, pvParam);
+                    if (rc != VINF_SUCCESS)
+                        return rc;
+                }
+#endif
+
+            /* right */
+            AVLStack.cEntries--;
+            if (pNode->pRight != KAVL_NULL)
+            {
+                AVLStack.achFlags[AVLStack.cEntries] = 0;
+                AVLStack.aEntries[AVLStack.cEntries++] = KAVL_GET_POINTER(&pNode->pRight);
+            }
+        } /* while */
+    }
+    else
+    {   /* from right */
+        while (AVLStack.cEntries > 0)
+        {
+            pNode = AVLStack.aEntries[AVLStack.cEntries - 1];
+
+            /* right */
+            if (!AVLStack.achFlags[AVLStack.cEntries - 1]++)
+            {
+                if (pNode->pRight != KAVL_NULL)
+                {
+                    AVLStack.achFlags[AVLStack.cEntries] = 0;  /* 0 first, 1 last */
+                    AVLStack.aEntries[AVLStack.cEntries++] = KAVL_GET_POINTER(&pNode->pRight);
+                    continue;
+                }
+            }
+
+            /* center */
+            rc = pfnCallBack(pNode, pvParam);
+            if (rc != VINF_SUCCESS)
+                return rc;
+#ifdef KAVL_EQUAL_ALLOWED
+            if (pNode->pList != KAVL_NULL)
+                for (pEqual = KAVL_GET_POINTER(&pNode->pList); pEqual; pEqual = KAVL_GET_POINTER_NULL(&pEqual->pList))
+                {
+                    rc = pfnCallBack(pEqual, pvParam);
+                    if (rc != VINF_SUCCESS)
+                        return rc;
+                }
+#endif
+
+            /* left */
+            AVLStack.cEntries--;
+            if (pNode->pLeft != KAVL_NULL)
+            {
+                AVLStack.achFlags[AVLStack.cEntries] = 0;
+                AVLStack.aEntries[AVLStack.cEntries++] = KAVL_GET_POINTER(&pNode->pLeft);
+            }
+        } /* while */
+    }
+
+    return VINF_SUCCESS;
+}
+
+
+#endif
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/vboxguest/common/table/avl_Get.cpp.h
@@ -0,0 +1,67 @@
+/* $Id: avl_Get.cpp.h $ */
+/** @file
+ * kAVLGet - get routine for AVL trees.
+ */
+
+/*
+ * Copyright (C) 1999-2012 knut st. osmundsen (bird-src-spam@anduin.net)
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+#ifndef _kAVLGet_h_
+#define _kAVLGet_h_
+
+
+/**
+ * Gets a node from the tree (does not remove it!)
+ * @returns   Pointer to the node holding the given key.
+ * @param     ppTree  Pointer to the AVL-tree root node pointer.
+ * @param     Key     Key value of the node which is to be found.
+ * @author    knut st. osmundsen
+ */
+KAVL_DECL(PKAVLNODECORE) KAVL_FN(Get)(PPKAVLNODECORE ppTree, KAVLKEY Key)
+{
+    register PKAVLNODECORE  pNode = KAVL_GET_POINTER_NULL(ppTree);
+
+    if (pNode)
+    {
+        while (KAVL_NE(pNode->Key, Key))
+        {
+            if (KAVL_G(pNode->Key, Key))
+            {
+                if (pNode->pLeft != KAVL_NULL)
+                    pNode = KAVL_GET_POINTER(&pNode->pLeft);
+                else
+                    return NULL;
+            }
+            else
+            {
+                if (pNode->pRight != KAVL_NULL)
+                    pNode = KAVL_GET_POINTER(&pNode->pRight);
+                else
+                    return NULL;
+            }
+        }
+    }
+
+    return pNode;
+}
+
+
+#endif
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/vboxguest/common/table/avl_GetBestFit.cpp.h
@@ -0,0 +1,103 @@
+/* $Id: avl_GetBestFit.cpp.h $ */
+/** @file
+ * kAVLGetBestFit - Get Best Fit routine for AVL trees.
+ *                  Intended specially on heaps. The tree should allow duplicate keys.
+ *
+ */
+
+/*
+ * Copyright (C) 1999-2012 knut st. osmundsen (bird-src-spam@anduin.net)
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+#ifndef _kAVLGetBestFit_h_
+#define _kAVLGetBestFit_h_
+
+
+/**
+ * Finds the best fitting node in the tree for the given Key value.
+ * @returns   Pointer to the best fitting node found.
+ * @param     ppTree  Pointer to Pointer to the tree root node.
+ * @param     Key     The Key of which is to be found a best fitting match for..
+ * @param     fAbove  TRUE:  Returned node is have the closest key to Key from above.
+ *                    FALSE: Returned node is have the closest key to Key from below.
+ * @sketch    The best fitting node is always located in the searchpath above you.
+ *            >= (above): The node where you last turned left.
+ *            <= (below): the node where you last turned right.
+ */
+KAVL_DECL(PKAVLNODECORE) KAVL_FN(GetBestFit)(PPKAVLNODECORE ppTree, KAVLKEY Key, bool fAbove)
+{
+    register PKAVLNODECORE  pNode = KAVL_GET_POINTER_NULL(ppTree);
+    if (pNode)
+    {
+        PKAVLNODECORE           pNodeLast = NULL;
+        if (fAbove)
+        {   /* pNode->Key >= Key */
+            while (KAVL_NE(pNode->Key, Key))
+            {
+                if (KAVL_G(pNode->Key, Key))
+                {
+                    if (pNode->pLeft != KAVL_NULL)
+                    {
+                        pNodeLast = pNode;
+                        pNode = KAVL_GET_POINTER(&pNode->pLeft);
+                    }
+                    else
+                        return pNode;
+                }
+                else
+                {
+                    if (pNode->pRight != KAVL_NULL)
+                        pNode = KAVL_GET_POINTER(&pNode->pRight);
+                    else
+                        return pNodeLast;
+                }
+            }
+        }
+        else
+        {   /* pNode->Key <= Key */
+            while (KAVL_NE(pNode->Key, Key))
+            {
+                if (KAVL_G(pNode->Key, Key))
+                {
+                    if (pNode->pLeft != KAVL_NULL)
+                        pNode = KAVL_GET_POINTER(&pNode->pLeft);
+                    else
+                        return pNodeLast;
+                }
+                else
+                {
+                    if (pNode->pRight != KAVL_NULL)
+                    {
+                        pNodeLast = pNode;
+                        pNode = KAVL_GET_POINTER(&pNode->pRight);
+                    }
+                    else
+                        return pNode;
+                }
+            }
+        }
+    }
+
+    /* perfect match or nothing. */
+    return pNode;
+}
+
+
+#endif
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/vboxguest/common/table/avl_RemoveBestFit.cpp.h
@@ -0,0 +1,70 @@
+/* $Id: avl_RemoveBestFit.cpp.h $ */
+/** @file
+ * kAVLRemoveBestFit - Remove Best Fit routine for AVL trees.
+ *                     Intended specially on heaps. The tree should allow duplicate keys.
+ *
+ */
+
+/*
+ * Copyright (C) 1999-2011 knut st. osmundsen (bird-src-spam@anduin.net)
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+#ifndef _kAVLRemoveBestFit_h_
+#define _kAVLRemoveBestFit_h_
+
+
+/**
+ * Finds the best fitting node in the tree for the given Key value.
+ * And removes it.
+ * @returns   Pointer to the best fitting node found.
+ * @param     ppTree  Pointer to Pointer to the tree root node.
+ * @param     Key     The Key of which is to be found a best fitting match for..
+ * @param     fAbove  TRUE:  Returned node is have the closest key to Key from above.
+ *                    FALSE: Returned node is have the closest key to Key from below.
+ * @sketch    The best fitting node is always located in the searchpath above you.
+ *            >= (above): The node where you last turned left.
+ *            <= (below): the node where you last turned right.
+ * @remark    This implementation should be speeded up slightly!
+ */
+KAVL_DECL(PKAVLNODECORE) KAVL_FN(RemoveBestFit)(PPKAVLNODECORE ppTree, KAVLKEY Key, bool fAbove)
+{
+    /*
+     * If we find anything we'll have to remove the node and return it.
+     * But, if duplicate keys are allowed we'll have to check for multiple
+     * nodes first and return one of them before doing an expensive remove+insert.
+     */
+    PKAVLNODECORE   pNode = KAVL_FN(GetBestFit)(ppTree, Key, fAbove);
+    if (pNode != NULL)
+    {
+#ifdef KAVL_EQUAL_ALLOWED
+        if (pNode->pList != KAVL_NULL)
+        {
+            PKAVLNODECORE pRet = KAVL_GET_POINTER(&pNode->pList);
+            KAVL_SET_POINTER_NULL(&pNode->pList, &pRet->pList);
+            return pRet;
+        }
+#endif
+        pNode = KAVL_FN(Remove)(ppTree, pNode->Key);
+    }
+    return pNode;
+}
+
+
+#endif
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/vboxguest/common/table/avlpv.c
@@ -0,0 +1,78 @@
+/* $Id: avlpv.cpp $ */
+/** @file
+ * IPRT - AVL tree, void *, unique keys.
+ */
+
+/*
+ * Copyright (C) 2001-2010 knut st. osmundsen (bird-src-spam@anduin.net)
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+#ifndef NOFILEID
+static const char szFileId[] = "Id: kAVLPVInt.c,v 1.5 2003/02/13 02:02:35 bird Exp $";
+#endif
+
+
+/*********************************************************************************************************************************
+*   Defined Constants And Macros                                                                                                 *
+*********************************************************************************************************************************/
+/*
+ * AVL configuration.
+ */
+#define KAVL_FN(a)                  RTAvlPV##a
+#define KAVL_MAX_STACK              27  /* Up to 2^24 nodes. */
+#define KAVL_CHECK_FOR_EQUAL_INSERT 1   /* No duplicate keys! */
+#define KAVLNODECORE                AVLPVNODECORE
+#define PKAVLNODECORE               PAVLPVNODECORE
+#define PPKAVLNODECORE              PPAVLPVNODECORE
+#define KAVLKEY                     AVLPVKEY
+#define PKAVLKEY                    PAVLPVKEY
+#define KAVLENUMDATA                AVLPVENUMDATA
+#define PKAVLENUMDATA               PAVLPVENUMDATA
+#define PKAVLCALLBACK               PAVLPVCALLBACK
+
+
+/*
+ * AVL Compare macros
+ */
+#define KAVL_G(key1, key2)          ( (const char*)(key1) >  (const char*)(key2) )
+#define KAVL_E(key1, key2)          ( (const char*)(key1) == (const char*)(key2) )
+#define KAVL_NE(key1, key2)         ( (const char*)(key1) != (const char*)(key2) )
+
+
+/*********************************************************************************************************************************
+*   Header Files                                                                                                                 *
+*********************************************************************************************************************************/
+#include <iprt/avl.h>
+#include <iprt/assert.h>
+#include <iprt/err.h>
+
+/*
+ * Include the code.
+ */
+#define SSToDS(ptr) ptr
+#define KMAX RT_MAX
+#define kASSERT Assert
+#include "avl_Base.cpp.h"
+#include "avl_Get.cpp.h"
+#include "avl_GetBestFit.cpp.h"
+#include "avl_RemoveBestFit.cpp.h"
+#include "avl_DoWithAll.cpp.h"
+#include "avl_Destroy.cpp.h"
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/vboxguest/common/time/time.c
@@ -0,0 +1,907 @@
+/* $Id: time.cpp $ */
+/** @file
+ * IPRT - Time.
+ */
+
+/*
+ * Copyright (C) 2006-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+
+/*********************************************************************************************************************************
+*   Header Files                                                                                                                 *
+*********************************************************************************************************************************/
+#define LOG_GROUP RTLOGGROUP_TIME
+#include <iprt/time.h>
+#include "internal/iprt.h"
+
+#include <iprt/ctype.h>
+#include <iprt/string.h>
+#include <iprt/assert.h>
+#include "internal/time.h"
+
+
+/*********************************************************************************************************************************
+*   Defined Constants And Macros                                                                                                 *
+*********************************************************************************************************************************/
+/** The max year we possibly could implode. */
+#define RTTIME_MAX_YEAR         (292 + 1970)
+/** The min year we possibly could implode. */
+#define RTTIME_MIN_YEAR         (-293 + 1970)
+
+/** The max day supported by our time representation. (2262-04-11T23-47-16.854775807) */
+#define RTTIME_MAX_DAY          (365*292+71 + 101-1)
+/** The min day supported by our time representation. (1677-09-21T00-12-43.145224192) */
+#define RTTIME_MIN_DAY          (365*-293-70 + 264-1)
+
+/** The max nano second into the max day.             (2262-04-11T23-47-16.854775807) */
+#define RTTIME_MAX_DAY_NANO     ( INT64_C(1000000000) * (23*3600 + 47*60 + 16) + 854775807 )
+/** The min nano second into the min day.             (1677-09-21T00-12-43.145224192) */
+#define RTTIME_MIN_DAY_NANO     ( INT64_C(1000000000) * (00*3600 + 12*60 + 43) + 145224192 )
+
+
+/*********************************************************************************************************************************
+*   Global Variables                                                                                                             *
+*********************************************************************************************************************************/
+/**
+ * Days per month in a common year.
+ */
+static const uint8_t g_acDaysInMonths[12] =
+{
+  /*Jan Feb Mar Arp May Jun Jul Aug Sep Oct Nov Dec */
+    31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
+};
+
+/**
+ * Days per month in a leap year.
+ */
+static const uint8_t g_acDaysInMonthsLeap[12] =
+{
+  /*Jan Feb Mar Arp May Jun Jul Aug Sep Oct Nov Dec */
+    31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
+};
+
+/**
+ * The day of year for each month in a common year.
+ */
+static const uint16_t g_aiDayOfYear[12 + 1] =
+{
+    1,                                  /* Jan */
+    1+31,                               /* Feb */
+    1+31+28,                            /* Mar */
+    1+31+28+31,                         /* Apr */
+    1+31+28+31+30,                      /* May */
+    1+31+28+31+30+31,                   /* Jun */
+    1+31+28+31+30+31+30,                /* Jul */
+    1+31+28+31+30+31+30+31,             /* Aug */
+    1+31+28+31+30+31+30+31+31,          /* Sep */
+    1+31+28+31+30+31+30+31+31+30,       /* Oct */
+    1+31+28+31+30+31+30+31+31+30+31,    /* Nov */
+    1+31+28+31+30+31+30+31+31+30+31+30, /* Dec */
+    1+31+28+31+30+31+30+31+31+30+31+30+31
+};
+
+/**
+ * The day of year for each month in a leap year.
+ */
+static const uint16_t g_aiDayOfYearLeap[12 + 1] =
+{
+    1,                                  /* Jan */
+    1+31,                               /* Feb */
+    1+31+29,                            /* Mar */
+    1+31+29+31,                         /* Apr */
+    1+31+29+31+30,                      /* May */
+    1+31+29+31+30+31,                   /* Jun */
+    1+31+29+31+30+31+30,                /* Jul */
+    1+31+29+31+30+31+30+31,             /* Aug */
+    1+31+29+31+30+31+30+31+31,          /* Sep */
+    1+31+29+31+30+31+30+31+31+30,       /* Oct */
+    1+31+29+31+30+31+30+31+31+30+31,    /* Nov */
+    1+31+29+31+30+31+30+31+31+30+31+30, /* Dec */
+    1+31+29+31+30+31+30+31+31+30+31+30+31
+};
+
+/** The index of 1970 in g_aoffYear */
+#define OFF_YEAR_IDX_EPOCH  300
+/** The year of the first index. */
+#define OFF_YEAR_IDX_0_YEAR 1670
+
+/**
+ * The number of days the 1st of January a year is offseted from 1970-01-01.
+ */
+static const int32_t g_aoffYear[] =
+{
+/*1670:*/ 365*-300+-72, 365*-299+-72, 365*-298+-72, 365*-297+-71, 365*-296+-71, 365*-295+-71, 365*-294+-71, 365*-293+-70, 365*-292+-70, 365*-291+-70,
+/*1680:*/ 365*-290+-70, 365*-289+-69, 365*-288+-69, 365*-287+-69, 365*-286+-69, 365*-285+-68, 365*-284+-68, 365*-283+-68, 365*-282+-68, 365*-281+-67,
+/*1690:*/ 365*-280+-67, 365*-279+-67, 365*-278+-67, 365*-277+-66, 365*-276+-66, 365*-275+-66, 365*-274+-66, 365*-273+-65, 365*-272+-65, 365*-271+-65,
+/*1700:*/ 365*-270+-65, 365*-269+-65, 365*-268+-65, 365*-267+-65, 365*-266+-65, 365*-265+-64, 365*-264+-64, 365*-263+-64, 365*-262+-64, 365*-261+-63,
+/*1710:*/ 365*-260+-63, 365*-259+-63, 365*-258+-63, 365*-257+-62, 365*-256+-62, 365*-255+-62, 365*-254+-62, 365*-253+-61, 365*-252+-61, 365*-251+-61,
+/*1720:*/ 365*-250+-61, 365*-249+-60, 365*-248+-60, 365*-247+-60, 365*-246+-60, 365*-245+-59, 365*-244+-59, 365*-243+-59, 365*-242+-59, 365*-241+-58,
+/*1730:*/ 365*-240+-58, 365*-239+-58, 365*-238+-58, 365*-237+-57, 365*-236+-57, 365*-235+-57, 365*-234+-57, 365*-233+-56, 365*-232+-56, 365*-231+-56,
+/*1740:*/ 365*-230+-56, 365*-229+-55, 365*-228+-55, 365*-227+-55, 365*-226+-55, 365*-225+-54, 365*-224+-54, 365*-223+-54, 365*-222+-54, 365*-221+-53,
+/*1750:*/ 365*-220+-53, 365*-219+-53, 365*-218+-53, 365*-217+-52, 365*-216+-52, 365*-215+-52, 365*-214+-52, 365*-213+-51, 365*-212+-51, 365*-211+-51,
+/*1760:*/ 365*-210+-51, 365*-209+-50, 365*-208+-50, 365*-207+-50, 365*-206+-50, 365*-205+-49, 365*-204+-49, 365*-203+-49, 365*-202+-49, 365*-201+-48,
+/*1770:*/ 365*-200+-48, 365*-199+-48, 365*-198+-48, 365*-197+-47, 365*-196+-47, 365*-195+-47, 365*-194+-47, 365*-193+-46, 365*-192+-46, 365*-191+-46,
+/*1780:*/ 365*-190+-46, 365*-189+-45, 365*-188+-45, 365*-187+-45, 365*-186+-45, 365*-185+-44, 365*-184+-44, 365*-183+-44, 365*-182+-44, 365*-181+-43,
+/*1790:*/ 365*-180+-43, 365*-179+-43, 365*-178+-43, 365*-177+-42, 365*-176+-42, 365*-175+-42, 365*-174+-42, 365*-173+-41, 365*-172+-41, 365*-171+-41,
+/*1800:*/ 365*-170+-41, 365*-169+-41, 365*-168+-41, 365*-167+-41, 365*-166+-41, 365*-165+-40, 365*-164+-40, 365*-163+-40, 365*-162+-40, 365*-161+-39,
+/*1810:*/ 365*-160+-39, 365*-159+-39, 365*-158+-39, 365*-157+-38, 365*-156+-38, 365*-155+-38, 365*-154+-38, 365*-153+-37, 365*-152+-37, 365*-151+-37,
+/*1820:*/ 365*-150+-37, 365*-149+-36, 365*-148+-36, 365*-147+-36, 365*-146+-36, 365*-145+-35, 365*-144+-35, 365*-143+-35, 365*-142+-35, 365*-141+-34,
+/*1830:*/ 365*-140+-34, 365*-139+-34, 365*-138+-34, 365*-137+-33, 365*-136+-33, 365*-135+-33, 365*-134+-33, 365*-133+-32, 365*-132+-32, 365*-131+-32,
+/*1840:*/ 365*-130+-32, 365*-129+-31, 365*-128+-31, 365*-127+-31, 365*-126+-31, 365*-125+-30, 365*-124+-30, 365*-123+-30, 365*-122+-30, 365*-121+-29,
+/*1850:*/ 365*-120+-29, 365*-119+-29, 365*-118+-29, 365*-117+-28, 365*-116+-28, 365*-115+-28, 365*-114+-28, 365*-113+-27, 365*-112+-27, 365*-111+-27,
+/*1860:*/ 365*-110+-27, 365*-109+-26, 365*-108+-26, 365*-107+-26, 365*-106+-26, 365*-105+-25, 365*-104+-25, 365*-103+-25, 365*-102+-25, 365*-101+-24,
+/*1870:*/ 365*-100+-24, 365* -99+-24, 365* -98+-24, 365* -97+-23, 365* -96+-23, 365* -95+-23, 365* -94+-23, 365* -93+-22, 365* -92+-22, 365* -91+-22,
+/*1880:*/ 365* -90+-22, 365* -89+-21, 365* -88+-21, 365* -87+-21, 365* -86+-21, 365* -85+-20, 365* -84+-20, 365* -83+-20, 365* -82+-20, 365* -81+-19,
+/*1890:*/ 365* -80+-19, 365* -79+-19, 365* -78+-19, 365* -77+-18, 365* -76+-18, 365* -75+-18, 365* -74+-18, 365* -73+-17, 365* -72+-17, 365* -71+-17,
+/*1900:*/ 365* -70+-17, 365* -69+-17, 365* -68+-17, 365* -67+-17, 365* -66+-17, 365* -65+-16, 365* -64+-16, 365* -63+-16, 365* -62+-16, 365* -61+-15,
+/*1910:*/ 365* -60+-15, 365* -59+-15, 365* -58+-15, 365* -57+-14, 365* -56+-14, 365* -55+-14, 365* -54+-14, 365* -53+-13, 365* -52+-13, 365* -51+-13,
+/*1920:*/ 365* -50+-13, 365* -49+-12, 365* -48+-12, 365* -47+-12, 365* -46+-12, 365* -45+-11, 365* -44+-11, 365* -43+-11, 365* -42+-11, 365* -41+-10,
+/*1930:*/ 365* -40+-10, 365* -39+-10, 365* -38+-10, 365* -37+-9 , 365* -36+-9 , 365* -35+-9 , 365* -34+-9 , 365* -33+-8 , 365* -32+-8 , 365* -31+-8 ,
+/*1940:*/ 365* -30+-8 , 365* -29+-7 , 365* -28+-7 , 365* -27+-7 , 365* -26+-7 , 365* -25+-6 , 365* -24+-6 , 365* -23+-6 , 365* -22+-6 , 365* -21+-5 ,
+/*1950:*/ 365* -20+-5 , 365* -19+-5 , 365* -18+-5 , 365* -17+-4 , 365* -16+-4 , 365* -15+-4 , 365* -14+-4 , 365* -13+-3 , 365* -12+-3 , 365* -11+-3 ,
+/*1960:*/ 365* -10+-3 , 365*  -9+-2 , 365*  -8+-2 , 365*  -7+-2 , 365*  -6+-2 , 365*  -5+-1 , 365*  -4+-1 , 365*  -3+-1 , 365*  -2+-1 , 365*  -1+0  ,
+/*1970:*/ 365*   0+0  , 365*   1+0  , 365*   2+0  , 365*   3+1  , 365*   4+1  , 365*   5+1  , 365*   6+1  , 365*   7+2  , 365*   8+2  , 365*   9+2  ,
+/*1980:*/ 365*  10+2  , 365*  11+3  , 365*  12+3  , 365*  13+3  , 365*  14+3  , 365*  15+4  , 365*  16+4  , 365*  17+4  , 365*  18+4  , 365*  19+5  ,
+/*1990:*/ 365*  20+5  , 365*  21+5  , 365*  22+5  , 365*  23+6  , 365*  24+6  , 365*  25+6  , 365*  26+6  , 365*  27+7  , 365*  28+7  , 365*  29+7  ,
+/*2000:*/ 365*  30+7  , 365*  31+8  , 365*  32+8  , 365*  33+8  , 365*  34+8  , 365*  35+9  , 365*  36+9  , 365*  37+9  , 365*  38+9  , 365*  39+10 ,
+/*2010:*/ 365*  40+10 , 365*  41+10 , 365*  42+10 , 365*  43+11 , 365*  44+11 , 365*  45+11 , 365*  46+11 , 365*  47+12 , 365*  48+12 , 365*  49+12 ,
+/*2020:*/ 365*  50+12 , 365*  51+13 , 365*  52+13 , 365*  53+13 , 365*  54+13 , 365*  55+14 , 365*  56+14 , 365*  57+14 , 365*  58+14 , 365*  59+15 ,
+/*2030:*/ 365*  60+15 , 365*  61+15 , 365*  62+15 , 365*  63+16 , 365*  64+16 , 365*  65+16 , 365*  66+16 , 365*  67+17 , 365*  68+17 , 365*  69+17 ,
+/*2040:*/ 365*  70+17 , 365*  71+18 , 365*  72+18 , 365*  73+18 , 365*  74+18 , 365*  75+19 , 365*  76+19 , 365*  77+19 , 365*  78+19 , 365*  79+20 ,
+/*2050:*/ 365*  80+20 , 365*  81+20 , 365*  82+20 , 365*  83+21 , 365*  84+21 , 365*  85+21 , 365*  86+21 , 365*  87+22 , 365*  88+22 , 365*  89+22 ,
+/*2060:*/ 365*  90+22 , 365*  91+23 , 365*  92+23 , 365*  93+23 , 365*  94+23 , 365*  95+24 , 365*  96+24 , 365*  97+24 , 365*  98+24 , 365*  99+25 ,
+/*2070:*/ 365* 100+25 , 365* 101+25 , 365* 102+25 , 365* 103+26 , 365* 104+26 , 365* 105+26 , 365* 106+26 , 365* 107+27 , 365* 108+27 , 365* 109+27 ,
+/*2080:*/ 365* 110+27 , 365* 111+28 , 365* 112+28 , 365* 113+28 , 365* 114+28 , 365* 115+29 , 365* 116+29 , 365* 117+29 , 365* 118+29 , 365* 119+30 ,
+/*2090:*/ 365* 120+30 , 365* 121+30 , 365* 122+30 , 365* 123+31 , 365* 124+31 , 365* 125+31 , 365* 126+31 , 365* 127+32 , 365* 128+32 , 365* 129+32 ,
+/*2100:*/ 365* 130+32 , 365* 131+32 , 365* 132+32 , 365* 133+32 , 365* 134+32 , 365* 135+33 , 365* 136+33 , 365* 137+33 , 365* 138+33 , 365* 139+34 ,
+/*2110:*/ 365* 140+34 , 365* 141+34 , 365* 142+34 , 365* 143+35 , 365* 144+35 , 365* 145+35 , 365* 146+35 , 365* 147+36 , 365* 148+36 , 365* 149+36 ,
+/*2120:*/ 365* 150+36 , 365* 151+37 , 365* 152+37 , 365* 153+37 , 365* 154+37 , 365* 155+38 , 365* 156+38 , 365* 157+38 , 365* 158+38 , 365* 159+39 ,
+/*2130:*/ 365* 160+39 , 365* 161+39 , 365* 162+39 , 365* 163+40 , 365* 164+40 , 365* 165+40 , 365* 166+40 , 365* 167+41 , 365* 168+41 , 365* 169+41 ,
+/*2140:*/ 365* 170+41 , 365* 171+42 , 365* 172+42 , 365* 173+42 , 365* 174+42 , 365* 175+43 , 365* 176+43 , 365* 177+43 , 365* 178+43 , 365* 179+44 ,
+/*2150:*/ 365* 180+44 , 365* 181+44 , 365* 182+44 , 365* 183+45 , 365* 184+45 , 365* 185+45 , 365* 186+45 , 365* 187+46 , 365* 188+46 , 365* 189+46 ,
+/*2160:*/ 365* 190+46 , 365* 191+47 , 365* 192+47 , 365* 193+47 , 365* 194+47 , 365* 195+48 , 365* 196+48 , 365* 197+48 , 365* 198+48 , 365* 199+49 ,
+/*2170:*/ 365* 200+49 , 365* 201+49 , 365* 202+49 , 365* 203+50 , 365* 204+50 , 365* 205+50 , 365* 206+50 , 365* 207+51 , 365* 208+51 , 365* 209+51 ,
+/*2180:*/ 365* 210+51 , 365* 211+52 , 365* 212+52 , 365* 213+52 , 365* 214+52 , 365* 215+53 , 365* 216+53 , 365* 217+53 , 365* 218+53 , 365* 219+54 ,
+/*2190:*/ 365* 220+54 , 365* 221+54 , 365* 222+54 , 365* 223+55 , 365* 224+55 , 365* 225+55 , 365* 226+55 , 365* 227+56 , 365* 228+56 , 365* 229+56 ,
+/*2200:*/ 365* 230+56 , 365* 231+56 , 365* 232+56 , 365* 233+56 , 365* 234+56 , 365* 235+57 , 365* 236+57 , 365* 237+57 , 365* 238+57 , 365* 239+58 ,
+/*2210:*/ 365* 240+58 , 365* 241+58 , 365* 242+58 , 365* 243+59 , 365* 244+59 , 365* 245+59 , 365* 246+59 , 365* 247+60 , 365* 248+60 , 365* 249+60 ,
+/*2220:*/ 365* 250+60 , 365* 251+61 , 365* 252+61 , 365* 253+61 , 365* 254+61 , 365* 255+62 , 365* 256+62 , 365* 257+62 , 365* 258+62 , 365* 259+63 ,
+/*2230:*/ 365* 260+63 , 365* 261+63 , 365* 262+63 , 365* 263+64 , 365* 264+64 , 365* 265+64 , 365* 266+64 , 365* 267+65 , 365* 268+65 , 365* 269+65 ,
+/*2240:*/ 365* 270+65 , 365* 271+66 , 365* 272+66 , 365* 273+66 , 365* 274+66 , 365* 275+67 , 365* 276+67 , 365* 277+67 , 365* 278+67 , 365* 279+68 ,
+/*2250:*/ 365* 280+68 , 365* 281+68 , 365* 282+68 , 365* 283+69 , 365* 284+69 , 365* 285+69 , 365* 286+69 , 365* 287+70 , 365* 288+70 , 365* 289+70 ,
+/*2260:*/ 365* 290+70 , 365* 291+71 , 365* 292+71 , 365* 293+71 , 365* 294+71 , 365* 295+72 , 365* 296+72 , 365* 297+72 , 365* 298+72 , 365* 299+73
+};
+
+/* generator code:
+#include <stdio.h>
+bool isLeapYear(int iYear)
+{
+    return iYear % 4 == 0 && (iYear % 100 != 0 || iYear % 400 == 0);
+}
+void printYear(int iYear, int iLeap)
+{
+    if (!(iYear % 10))
+        printf("\n/" "*%d:*" "/", iYear + 1970);
+    printf(" 365*%4d+%-3d,", iYear, iLeap);
+}
+int main()
+{
+    int iYear = 0;
+    int iLeap = 0;
+    while (iYear > -300)
+        iLeap -= isLeapYear(1970 + --iYear);
+    while (iYear < 300)
+    {
+        printYear(iYear, iLeap);
+        iLeap += isLeapYear(1970 + iYear++);
+    }
+    printf("\n");
+    return 0;
+}
+*/
+
+
+/**
+ * Checks if a year is a leap year or not.
+ *
+ * @returns true if it's a leap year.
+ * @returns false if it's a common year.
+ * @param   i32Year     The year in question.
+ */
+DECLINLINE(bool) rtTimeIsLeapYear(int32_t i32Year)
+{
+    return i32Year % 4 == 0
+        && (    i32Year % 100 != 0
+            ||  i32Year % 400 == 0);
+}
+
+
+/**
+ * Checks if a year is a leap year or not.
+ *
+ * @returns true if it's a leap year.
+ * @returns false if it's a common year.
+ * @param   i32Year     The year in question.
+ */
+RTDECL(bool) RTTimeIsLeapYear(int32_t i32Year)
+{
+    return rtTimeIsLeapYear(i32Year);
+}
+RT_EXPORT_SYMBOL(RTTimeIsLeapYear);
+
+
+/**
+ * Explodes a time spec (UTC).
+ *
+ * @returns pTime.
+ * @param   pTime       Where to store the exploded time.
+ * @param   pTimeSpec   The time spec to exploded.
+ */
+RTDECL(PRTTIME) RTTimeExplode(PRTTIME pTime, PCRTTIMESPEC pTimeSpec)
+{
+    int64_t         i64Div;
+    int32_t         i32Div;
+    int32_t         i32Rem;
+    unsigned        iYear;
+    const uint16_t *paiDayOfYear;
+    int             iMonth;
+
+    AssertMsg(VALID_PTR(pTime), ("%p\n", pTime));
+    AssertMsg(VALID_PTR(pTimeSpec), ("%p\n", pTime));
+
+    /*
+     * The simple stuff first.
+     */
+    pTime->fFlags = RTTIME_FLAGS_TYPE_UTC;
+    i64Div = pTimeSpec->i64NanosecondsRelativeToUnixEpoch;
+    i32Rem = (int32_t)(i64Div % 1000000000);
+    i64Div /= 1000000000;
+    if (i32Rem < 0)
+    {
+        i32Rem += 1000000000;
+        i64Div--;
+    }
+    pTime->u32Nanosecond = i32Rem;
+
+    /* second */
+    i32Rem = (int32_t)(i64Div % 60);
+    i64Div /= 60;
+    if (i32Rem < 0)
+    {
+        i32Rem += 60;
+        i64Div--;
+    }
+    pTime->u8Second      = i32Rem;
+
+    /* minute */
+    i32Div = (int32_t)i64Div;   /* 60,000,000,000 > 33bit, so 31bit suffices. */
+    i32Rem = i32Div % 60;
+    i32Div /= 60;
+    if (i32Rem < 0)
+    {
+        i32Rem += 60;
+        i32Div--;
+    }
+    pTime->u8Minute      = i32Rem;
+
+    /* hour */
+    i32Rem = i32Div % 24;
+    i32Div /= 24;                       /* days relative to 1970-01-01 */
+    if (i32Rem < 0)
+    {
+        i32Rem += 24;
+        i32Div--;
+    }
+    pTime->u8Hour        = i32Rem;
+
+    /* weekday - 1970-01-01 was a Thursday (3) */
+    pTime->u8WeekDay     = ((int)(i32Div % 7) + 3 + 7) % 7;
+
+    /*
+     * We've now got a number of days relative to 1970-01-01.
+     * To get the correct year number we have to mess with leap years. Fortunately,
+     * the representation we've got only supports a few hundred years, so we can
+     * generate a table and perform a simple two way search from the modulus 365 derived.
+     */
+    iYear = OFF_YEAR_IDX_EPOCH + i32Div / 365;
+    while (g_aoffYear[iYear + 1] <= i32Div)
+        iYear++;
+    while (g_aoffYear[iYear] > i32Div)
+        iYear--;
+    pTime->i32Year       = iYear + OFF_YEAR_IDX_0_YEAR;
+    i32Div -= g_aoffYear[iYear];
+    pTime->u16YearDay    = i32Div + 1;
+
+    /*
+     * Figuring out the month is done in a manner similar to the year, only here we
+     * ensure that the index is matching or too small.
+     */
+    if (rtTimeIsLeapYear(pTime->i32Year))
+    {
+        pTime->fFlags   |= RTTIME_FLAGS_LEAP_YEAR;
+        paiDayOfYear = &g_aiDayOfYearLeap[0];
+    }
+    else
+    {
+        pTime->fFlags   |= RTTIME_FLAGS_COMMON_YEAR;
+        paiDayOfYear = &g_aiDayOfYear[0];
+    }
+    iMonth = i32Div / 32;
+    i32Div++;
+    while (paiDayOfYear[iMonth + 1] <= i32Div)
+        iMonth++;
+    pTime->u8Month       = iMonth + 1;
+    i32Div -= paiDayOfYear[iMonth];
+    pTime->u8MonthDay    = i32Div + 1;
+
+    /* This is for UTC timespecs, so, no offset. */
+    pTime->offUTC        = 0;
+
+    return pTime;
+}
+RT_EXPORT_SYMBOL(RTTimeExplode);
+
+
+/**
+ * Implodes exploded time to a time spec (UTC).
+ *
+ * @returns pTime on success.
+ * @returns NULL if the pTime data is invalid.
+ * @param   pTimeSpec   Where to store the imploded UTC time.
+ *                      If pTime specifies a time which outside the range, maximum or
+ *                      minimum values will be returned.
+ * @param   pTime       Pointer to the exploded time to implode.
+ *                      The fields u8Month, u8WeekDay and u8MonthDay are not used,
+ *                      and all the other fields are expected to be within their
+ *                      bounds. Use RTTimeNormalize() to calculate u16YearDay and
+ *                      normalize the ranges of the fields.
+ */
+RTDECL(PRTTIMESPEC) RTTimeImplode(PRTTIMESPEC pTimeSpec, PCRTTIME pTime)
+{
+    int32_t     i32Days;
+    uint32_t    u32Secs;
+    int64_t     i64Nanos;
+
+    /*
+     * Validate input.
+     */
+    AssertReturn(VALID_PTR(pTimeSpec), NULL);
+    AssertReturn(VALID_PTR(pTime), NULL);
+    AssertReturn(pTime->u32Nanosecond < 1000000000, NULL);
+    AssertReturn(pTime->u8Second < 60, NULL);
+    AssertReturn(pTime->u8Minute < 60, NULL);
+    AssertReturn(pTime->u8Hour < 24, NULL);
+    AssertReturn(pTime->u16YearDay >= 1, NULL);
+    AssertReturn(pTime->u16YearDay <= (rtTimeIsLeapYear(pTime->i32Year) ? 366 : 365), NULL);
+    AssertMsgReturn(pTime->i32Year <= RTTIME_MAX_YEAR && pTime->i32Year >= RTTIME_MIN_YEAR, ("%RI32\n", pTime->i32Year), NULL);
+
+    /*
+     * Do the conversion to nanoseconds.
+     */
+    i32Days  = g_aoffYear[pTime->i32Year - OFF_YEAR_IDX_0_YEAR]
+             + pTime->u16YearDay - 1;
+    AssertMsgReturn(i32Days <= RTTIME_MAX_DAY && i32Days >= RTTIME_MIN_DAY, ("%RI32\n", i32Days), NULL);
+
+    u32Secs  = pTime->u8Second
+             + pTime->u8Minute * 60
+             + pTime->u8Hour   * 3600;
+    i64Nanos = (uint64_t)pTime->u32Nanosecond
+             + u32Secs * UINT64_C(1000000000);
+    AssertMsgReturn(i32Days != RTTIME_MAX_DAY || i64Nanos <= RTTIME_MAX_DAY_NANO, ("%RI64\n", i64Nanos), NULL);
+    AssertMsgReturn(i32Days != RTTIME_MIN_DAY || i64Nanos >= RTTIME_MIN_DAY_NANO, ("%RI64\n", i64Nanos), NULL);
+
+    i64Nanos += i32Days * UINT64_C(86400000000000);
+
+    pTimeSpec->i64NanosecondsRelativeToUnixEpoch = i64Nanos;
+    return pTimeSpec;
+}
+RT_EXPORT_SYMBOL(RTTimeImplode);
+
+
+/**
+ * Internal worker for RTTimeNormalize and RTTimeLocalNormalize.
+ * It doesn't adjust the UCT offset but leaves that for RTTimeLocalNormalize.
+ */
+static PRTTIME rtTimeNormalizeInternal(PRTTIME pTime)
+{
+    unsigned    uSecond;
+    unsigned    uMinute;
+    unsigned    uHour;
+    bool        fLeapYear;
+
+    /*
+     * Fix the YearDay and Month/MonthDay.
+     */
+    fLeapYear = rtTimeIsLeapYear(pTime->i32Year);
+    if (!pTime->u16YearDay)
+    {
+        /*
+         * The Month+MonthDay must present, overflow adjust them and calc the year day.
+         */
+        AssertMsgReturn(    pTime->u8Month
+                        &&  pTime->u8MonthDay,
+                        ("date=%d-%d-%d\n", pTime->i32Year, pTime->u8Month, pTime->u8MonthDay),
+                        NULL);
+        while (pTime->u8Month > 12)
+        {
+            pTime->u8Month -= 12;
+            pTime->i32Year++;
+            fLeapYear = rtTimeIsLeapYear(pTime->i32Year);
+            pTime->fFlags &= ~(RTTIME_FLAGS_COMMON_YEAR | RTTIME_FLAGS_LEAP_YEAR);
+        }
+
+        for (;;)
+        {
+            unsigned cDaysInMonth = fLeapYear
+                                  ? g_acDaysInMonthsLeap[pTime->u8Month - 1]
+                                  : g_acDaysInMonths[pTime->u8Month - 1];
+            if (pTime->u8MonthDay <= cDaysInMonth)
+                break;
+            pTime->u8MonthDay -= cDaysInMonth;
+            if (pTime->u8Month != 12)
+                pTime->u8Month++;
+            else
+            {
+                pTime->u8Month = 1;
+                pTime->i32Year++;
+                fLeapYear = rtTimeIsLeapYear(pTime->i32Year);
+                pTime->fFlags &= ~(RTTIME_FLAGS_COMMON_YEAR | RTTIME_FLAGS_LEAP_YEAR);
+            }
+        }
+
+        pTime->u16YearDay  = pTime->u8MonthDay - 1
+                           + (fLeapYear
+                              ? g_aiDayOfYearLeap[pTime->u8Month - 1]
+                              : g_aiDayOfYear[pTime->u8Month - 1]);
+    }
+    else
+    {
+        /*
+         * Are both YearDay and Month/MonthDay valid?
+         * Check that they don't overflow and match, if not use YearDay (simpler).
+         */
+        bool fRecalc = true;
+        if (    pTime->u8Month
+            &&  pTime->u8MonthDay)
+        {
+            do
+            {
+                uint16_t u16YearDay;
+
+                /* If you change one, zero the other to make clear what you mean. */
+                AssertBreak(pTime->u8Month <= 12);
+                AssertBreak(pTime->u8MonthDay <= (fLeapYear
+                                                  ? g_acDaysInMonthsLeap[pTime->u8Month - 1]
+                                                  : g_acDaysInMonths[pTime->u8Month - 1]));
+                u16YearDay = pTime->u8MonthDay - 1
+                           + (fLeapYear
+                              ? g_aiDayOfYearLeap[pTime->u8Month - 1]
+                              : g_aiDayOfYear[pTime->u8Month - 1]);
+                AssertBreak(u16YearDay == pTime->u16YearDay);
+                fRecalc = false;
+            } while (0);
+        }
+        if (fRecalc)
+        {
+            const uint16_t *paiDayOfYear;
+
+            /* overflow adjust YearDay */
+            while (pTime->u16YearDay > (fLeapYear ? 366 : 365))
+            {
+                pTime->u16YearDay -= fLeapYear ? 366 : 365;
+                pTime->i32Year++;
+                fLeapYear = rtTimeIsLeapYear(pTime->i32Year);
+                pTime->fFlags &= ~(RTTIME_FLAGS_COMMON_YEAR | RTTIME_FLAGS_LEAP_YEAR);
+            }
+
+            /* calc Month and MonthDay */
+            paiDayOfYear = fLeapYear
+                         ? &g_aiDayOfYearLeap[0]
+                         : &g_aiDayOfYear[0];
+            pTime->u8Month = 1;
+            while (pTime->u16YearDay > paiDayOfYear[pTime->u8Month])
+                pTime->u8Month++;
+            Assert(pTime->u8Month >= 1 && pTime->u8Month <= 12);
+            pTime->u8MonthDay = pTime->u16YearDay - paiDayOfYear[pTime->u8Month - 1] + 1;
+        }
+    }
+
+    /*
+     * Fixup time overflows.
+     * Use unsigned int values internally to avoid overflows.
+     */
+    uSecond = pTime->u8Second;
+    uMinute = pTime->u8Minute;
+    uHour   = pTime->u8Hour;
+
+    while (pTime->u32Nanosecond >= 1000000000)
+    {
+        pTime->u32Nanosecond -= 1000000000;
+        uSecond++;
+    }
+
+    while (uSecond >= 60)
+    {
+        uSecond -= 60;
+        uMinute++;
+    }
+
+    while (uMinute >= 60)
+    {
+        uMinute -= 60;
+        uHour++;
+    }
+
+    while (uHour >= 24)
+    {
+        uHour -= 24;
+
+        /* This is really a RTTimeIncDay kind of thing... */
+        if (pTime->u16YearDay + 1 != (fLeapYear ? g_aiDayOfYearLeap[pTime->u8Month] : g_aiDayOfYear[pTime->u8Month]))
+        {
+            pTime->u16YearDay++;
+            pTime->u8MonthDay++;
+        }
+        else if (pTime->u8Month != 12)
+        {
+            pTime->u16YearDay++;
+            pTime->u8Month++;
+            pTime->u8MonthDay = 1;
+        }
+        else
+        {
+            pTime->i32Year++;
+            fLeapYear = rtTimeIsLeapYear(pTime->i32Year);
+            pTime->fFlags &= ~(RTTIME_FLAGS_COMMON_YEAR | RTTIME_FLAGS_LEAP_YEAR);
+            pTime->u16YearDay = 1;
+            pTime->u8Month = 1;
+            pTime->u8MonthDay = 1;
+        }
+    }
+
+    pTime->u8Second = uSecond;
+    pTime->u8Minute = uMinute;
+    pTime->u8Hour = uHour;
+
+    /*
+     * Correct the leap year flag.
+     * Assert if it's wrong, but ignore if unset.
+     */
+    if (fLeapYear)
+    {
+        Assert(!(pTime->fFlags & RTTIME_FLAGS_COMMON_YEAR));
+        pTime->fFlags &= ~RTTIME_FLAGS_COMMON_YEAR;
+        pTime->fFlags |= RTTIME_FLAGS_LEAP_YEAR;
+    }
+    else
+    {
+        Assert(!(pTime->fFlags & RTTIME_FLAGS_LEAP_YEAR));
+        pTime->fFlags &= ~RTTIME_FLAGS_LEAP_YEAR;
+        pTime->fFlags |= RTTIME_FLAGS_COMMON_YEAR;
+    }
+
+
+    /*
+     * Calc week day.
+     *
+     * 1970-01-01 was a Thursday (3), so find the number of days relative to
+     * that point. We use the table when possible and a slow+stupid+brute-force
+     * algorithm for points outside it. Feel free to optimize the latter by
+     * using some clever formula.
+     */
+    if (    pTime->i32Year >= OFF_YEAR_IDX_0_YEAR
+        &&  pTime->i32Year <  OFF_YEAR_IDX_0_YEAR + (int32_t)RT_ELEMENTS(g_aoffYear))
+    {
+        int32_t offDays = g_aoffYear[pTime->i32Year - OFF_YEAR_IDX_0_YEAR]
+                        + pTime->u16YearDay -1;
+        pTime->u8WeekDay = ((offDays % 7) + 3 + 7) % 7;
+    }
+    else
+    {
+        int32_t i32Year = pTime->i32Year;
+        if (i32Year >= 1970)
+        {
+            uint64_t offDays = pTime->u16YearDay - 1;
+            while (--i32Year >= 1970)
+                offDays += rtTimeIsLeapYear(i32Year) ? 366 : 365;
+            pTime->u8WeekDay = (uint8_t)((offDays + 3) % 7);
+        }
+        else
+        {
+            int64_t offDays = (fLeapYear ? -366 - 1 : -365 - 1) + pTime->u16YearDay;
+            while (++i32Year < 1970)
+                offDays -= rtTimeIsLeapYear(i32Year) ? 366 : 365;
+            pTime->u8WeekDay = ((int)(offDays % 7) + 3 + 7) % 7;
+        }
+    }
+    return pTime;
+}
+
+
+/**
+ * Normalizes the fields of a time structure.
+ *
+ * It is possible to calculate year-day from month/day and vice
+ * versa. If you adjust any of these, make sure to zero the
+ * other so you make it clear which of the fields to use. If
+ * it's ambiguous, the year-day field is used (and you get
+ * assertions in debug builds).
+ *
+ * All the time fields and the year-day or month/day fields will
+ * be adjusted for overflows. (Since all fields are unsigned, there
+ * is no underflows.) It is possible to exploit this for simple
+ * date math, though the recommended way of doing that to implode
+ * the time into a timespec and do the math on that.
+ *
+ * @returns pTime on success.
+ * @returns NULL if the data is invalid.
+ *
+ * @param   pTime       The time structure to normalize.
+ *
+ * @remarks This function doesn't work with local time, only with UTC time.
+ */
+RTDECL(PRTTIME) RTTimeNormalize(PRTTIME pTime)
+{
+    /*
+     * Validate that we've got the minimum of stuff handy.
+     */
+    AssertReturn(VALID_PTR(pTime), NULL);
+    AssertMsgReturn(!(pTime->fFlags & ~RTTIME_FLAGS_MASK), ("%#x\n", pTime->fFlags), NULL);
+    AssertMsgReturn((pTime->fFlags & RTTIME_FLAGS_TYPE_MASK) != RTTIME_FLAGS_TYPE_LOCAL, ("Use RTTimeLocalNormalize!\n"), NULL);
+    AssertMsgReturn(pTime->offUTC == 0, ("%d; Use RTTimeLocalNormalize!\n", pTime->offUTC), NULL);
+
+    pTime = rtTimeNormalizeInternal(pTime);
+    if (pTime)
+        pTime->fFlags |= RTTIME_FLAGS_TYPE_UTC;
+    return pTime;
+}
+RT_EXPORT_SYMBOL(RTTimeNormalize);
+
+
+/**
+ * Converts a time spec to a ISO date string.
+ *
+ * @returns psz on success.
+ * @returns NULL on buffer underflow.
+ * @param   pTime       The time. Caller should've normalized this.
+ * @param   psz         Where to store the string.
+ * @param   cb          The size of the buffer.
+ */
+RTDECL(char *) RTTimeToString(PCRTTIME pTime, char *psz, size_t cb)
+{
+    size_t cch;
+
+    /* (Default to UTC if not specified) */
+    if (    (pTime->fFlags & RTTIME_FLAGS_TYPE_MASK) == RTTIME_FLAGS_TYPE_LOCAL
+        &&  pTime->offUTC)
+    {
+        int32_t offUTCHour   = pTime->offUTC / 60;
+        int32_t offUTCMinute = pTime->offUTC % 60;
+        char    chSign;
+        Assert(pTime->offUTC <= 840 && pTime->offUTC >= -840);
+        if (pTime->offUTC >= 0)
+            chSign = '+';
+        else
+        {
+            chSign = '-';
+            offUTCMinute = -offUTCMinute;
+            offUTCHour = -offUTCHour;
+        }
+        cch = RTStrPrintf(psz, cb,
+                          "%RI32-%02u-%02uT%02u:%02u:%02u.%09RU32%c%02d%02d",
+                          pTime->i32Year, pTime->u8Month, pTime->u8MonthDay,
+                          pTime->u8Hour, pTime->u8Minute, pTime->u8Second, pTime->u32Nanosecond,
+                          chSign, offUTCHour, offUTCMinute);
+        if (    cch <= 15
+            ||  psz[cch - 5] != chSign)
+            return NULL;
+    }
+    else
+    {
+        cch = RTStrPrintf(psz, cb, "%RI32-%02u-%02uT%02u:%02u:%02u.%09RU32Z",
+                          pTime->i32Year, pTime->u8Month, pTime->u8MonthDay,
+                          pTime->u8Hour, pTime->u8Minute, pTime->u8Second, pTime->u32Nanosecond);
+        if (    cch <= 15
+            ||  psz[cch - 1] != 'Z')
+            return NULL;
+    }
+    return psz;
+}
+RT_EXPORT_SYMBOL(RTTimeToString);
+
+
+/**
+ * Converts a time spec to a ISO date string.
+ *
+ * @returns psz on success.
+ * @returns NULL on buffer underflow.
+ * @param   pTime       The time spec.
+ * @param   psz         Where to store the string.
+ * @param   cb          The size of the buffer.
+ */
+RTDECL(char *) RTTimeSpecToString(PCRTTIMESPEC pTime, char *psz, size_t cb)
+{
+    RTTIME Time;
+    return RTTimeToString(RTTimeExplode(&Time, pTime), psz, cb);
+}
+RT_EXPORT_SYMBOL(RTTimeSpecToString);
+
+
+
+/**
+ * Attempts to convert an ISO date string to a time structure.
+ *
+ * We're a little forgiving with zero padding, unspecified parts, and leading
+ * and trailing spaces.
+ *
+ * @retval  pTime on success,
+ * @retval  NULL on failure.
+ * @param   pTime       Where to store the time on success.
+ * @param   pszString   The ISO date string to convert.
+ */
+RTDECL(PRTTIME) RTTimeFromString(PRTTIME pTime, const char *pszString)
+{
+    /* Ignore leading spaces. */
+    while (RT_C_IS_SPACE(*pszString))
+        pszString++;
+
+    /*
+     * Init non date & time parts.
+     */
+    pTime->fFlags = RTTIME_FLAGS_TYPE_LOCAL;
+    pTime->offUTC = 0;
+
+    /*
+     * The day part.
+     */
+
+    /* Year */
+    int rc = RTStrToInt32Ex(pszString, (char **)&pszString, 10, &pTime->i32Year);
+    if (rc != VWRN_TRAILING_CHARS)
+        return NULL;
+
+    bool const fLeapYear = rtTimeIsLeapYear(pTime->i32Year);
+    if (fLeapYear)
+        pTime->fFlags |= RTTIME_FLAGS_LEAP_YEAR;
+
+    if (*pszString++ != '-')
+        return NULL;
+
+    /* Month of the year. */
+    rc = RTStrToUInt8Ex(pszString, (char **)&pszString, 10, &pTime->u8Month);
+    if (rc != VWRN_TRAILING_CHARS)
+        return NULL;
+    if (pTime->u8Month == 0 || pTime->u8Month > 12)
+        return NULL;
+    if (*pszString++ != '-')
+        return NULL;
+
+    /* Day of month.*/
+    rc = RTStrToUInt8Ex(pszString, (char **)&pszString, 10, &pTime->u8MonthDay);
+    if (rc != VWRN_TRAILING_CHARS && rc != VINF_SUCCESS)
+        return NULL;
+    unsigned const cDaysInMonth = fLeapYear
+                                ? g_acDaysInMonthsLeap[pTime->u8Month - 1]
+                                : g_acDaysInMonths[pTime->u8Month - 1];
+    if (pTime->u8MonthDay == 0 || pTime->u8MonthDay > cDaysInMonth)
+        return NULL;
+
+    /* Calculate year day. */
+    pTime->u16YearDay = pTime->u8MonthDay - 1
+                      + (fLeapYear
+                         ? g_aiDayOfYearLeap[pTime->u8Month - 1]
+                         : g_aiDayOfYear[pTime->u8Month - 1]);
+
+    /*
+     * The time part.
+     */
+    if (*pszString++ != 'T')
+        return NULL;
+
+    /* Hour. */
+    rc = RTStrToUInt8Ex(pszString, (char **)&pszString, 10, &pTime->u8Hour);
+    if (rc != VWRN_TRAILING_CHARS)
+        return NULL;
+    if (pTime->u8Hour > 23)
+        return NULL;
+    if (*pszString++ != ':')
+        return NULL;
+
+    /* Minute. */
+    rc = RTStrToUInt8Ex(pszString, (char **)&pszString, 10, &pTime->u8Minute);
+    if (rc != VWRN_TRAILING_CHARS)
+        return NULL;
+    if (pTime->u8Minute > 59)
+        return NULL;
+    if (*pszString++ != ':')
+        return NULL;
+
+    /* Second. */
+    rc = RTStrToUInt8Ex(pszString, (char **)&pszString, 10, &pTime->u8Minute);
+    if (rc != VINF_SUCCESS && rc != VWRN_TRAILING_CHARS && rc != VWRN_TRAILING_SPACES)
+        return NULL;
+    if (pTime->u8Second > 59)
+        return NULL;
+
+    /* Nanoseconds is optional and probably non-standard. */
+    if (*pszString == '.')
+    {
+        rc = RTStrToUInt32Ex(pszString + 1, (char **)&pszString, 10, &pTime->u32Nanosecond);
+        if (rc != VINF_SUCCESS && rc != VWRN_TRAILING_CHARS && rc != VWRN_TRAILING_SPACES)
+            return NULL;
+        if (pTime->u32Nanosecond >= 1000000000)
+            return NULL;
+    }
+    else
+        pTime->u32Nanosecond = 0;
+
+    /*
+     * Time zone.
+     */
+    if (*pszString == 'Z')
+    {
+        pszString++;
+        pTime->fFlags &= ~RTTIME_FLAGS_TYPE_MASK;
+        pTime->fFlags |= ~RTTIME_FLAGS_TYPE_UTC;
+        pTime->offUTC = 0;
+    }
+    else if (   *pszString == '+'
+             || *pszString == '-')
+    {
+        rc = RTStrToInt32Ex(pszString, (char **)&pszString, 10, &pTime->offUTC);
+        if (rc != VINF_SUCCESS && rc != VWRN_TRAILING_CHARS && rc != VWRN_TRAILING_SPACES)
+            return NULL;
+    }
+    /* else: No time zone given, local with offUTC = 0. */
+
+    /*
+     * The rest of the string should be blanks.
+     */
+    char ch;
+    while ((ch = *pszString++) != '\0')
+        if (!RT_C_IS_BLANK(ch))
+            return NULL;
+
+    return pTime;
+}
+RT_EXPORT_SYMBOL(RTTimeFromString);
+
+
+/**
+ * Attempts to convert an ISO date string to a time structure.
+ *
+ * We're a little forgiving with zero padding, unspecified parts, and leading
+ * and trailing spaces.
+ *
+ * @retval  pTime on success,
+ * @retval  NULL on failure.
+ * @param   pTime       The time spec.
+ * @param   pszString   The ISO date string to convert.
+ */
+RTDECL(PRTTIMESPEC) RTTimeSpecFromString(PRTTIMESPEC pTime, const char *pszString)
+{
+    RTTIME Time;
+    if (RTTimeFromString(&Time, pszString))
+        return RTTimeImplode(pTime, &Time);
+    return NULL;
+}
+RT_EXPORT_SYMBOL(RTTimeSpecFromString);
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/vboxguest/do_Module.symvers
@@ -0,0 +1,33 @@
+#!/bin/sh
+
+#
+# This script is used when building kernel modules from DKMS. I don't
+# know how to solve the problem of inter-module dependencies better.
+#
+# Copyright (C) 2008-2015 Oracle Corporation
+#
+# This file is part of VirtualBox Open Source Edition (OSE), as
+# available from http://www.virtualbox.org. This file is free software;
+# you can redistribute it and/or modify it under the terms of the GNU
+# General Public License (GPL) as published by the Free Software
+# Foundation, in version 2 as it comes in the "COPYING" file of the
+# VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+# hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+#
+
+SYMFILE="/tmp/$1-Module.symvers"
+case "$2" in
+  save)
+    if [ -f "$3" ]; then
+      cp "$3" "$SYMFILE"
+    fi
+    ;;
+  restore)
+    if [ -f "$SYMFILE" ]; then
+      cp "$SYMFILE" "$3"
+    fi
+    ;;
+  *)
+    echo "Usage: <modname> save|restore <location of Module.symvers>"
+    ;;
+esac
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/vboxguest/generic/RTAssertShouldPanic-generic.c
@@ -0,0 +1,44 @@
+/* $Id: RTAssertShouldPanic-generic.cpp $ */
+/** @file
+ * IPRT - Assertions, generic RTAssertShouldPanic.
+ */
+
+/*
+ * Copyright (C) 2006-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+
+/*********************************************************************************************************************************
+*   Header Files                                                                                                                 *
+*********************************************************************************************************************************/
+#include <iprt/assert.h>
+#include "internal/iprt.h"
+
+
+RTDECL(bool) RTAssertShouldPanic(void)
+{
+#if 0 /* Enable this to not panic on assertions. (Make sure this code is used!) */
+    return false;
+#else
+    return RTAssertMayPanic();
+#endif
+}
+RT_EXPORT_SYMBOL(RTAssertShouldPanic);
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/vboxguest/generic/RTLogWriteStdErr-stub-generic.c
@@ -0,0 +1,42 @@
+/* $Id: RTLogWriteStdErr-stub-generic.cpp $ */
+/** @file
+ * IPRT - Log To StdErr, Generic Dummy.
+ */
+
+/*
+ * Copyright (C) 2006-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+
+/*********************************************************************************************************************************
+*   Header Files                                                                                                                 *
+*********************************************************************************************************************************/
+#include <iprt/log.h>
+#include "internal/iprt.h"
+
+
+RTDECL(void) RTLogWriteStdErr(const char *pch, size_t cb)
+{
+    NOREF(pch);
+    NOREF(cb);
+    return;
+}
+RT_EXPORT_SYMBOL(RTLogWriteStdErr);
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/vboxguest/generic/RTLogWriteStdOut-stub-generic.c
@@ -0,0 +1,42 @@
+/* $Id: RTLogWriteStdOut-stub-generic.cpp $ */
+/** @file
+ * IPRT - Log To StdOut, Generic Dummy.
+ */
+
+/*
+ * Copyright (C) 2006-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+
+/*********************************************************************************************************************************
+*   Header Files                                                                                                                 *
+*********************************************************************************************************************************/
+#include <iprt/log.h>
+#include "internal/iprt.h"
+
+
+RTDECL(void) RTLogWriteStdOut(const char *pch, size_t cb)
+{
+    NOREF(pch);
+    NOREF(cb);
+    return;
+}
+RT_EXPORT_SYMBOL(RTLogWriteStdOut);
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/vboxguest/generic/RTMpGetCoreCount-generic.c
@@ -0,0 +1,40 @@
+/* $Id: RTMpGetCoreCount-generic.cpp $ */
+/** @file
+ * IPRT - Multiprocessor, Generic RTMpGetCoreCount.
+ */
+
+/*
+ * Copyright (C) 2013-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+
+/*********************************************************************************************************************************
+*   Header Files                                                                                                                 *
+*********************************************************************************************************************************/
+#include <iprt/mp.h>
+#include "internal/iprt.h"
+
+
+RTDECL(RTCPUID) RTMpGetCoreCount(void)
+{
+    return RTMpGetCount();
+}
+RT_EXPORT_SYMBOL(RTMpGetCoreCount);
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/vboxguest/generic/RTSemEventMultiWait-2-ex-generic.c
@@ -0,0 +1,53 @@
+/* $Id: RTSemEventMultiWait-2-ex-generic.cpp $ */
+/** @file
+ * IPRT - RTSemEventMultiWait, implementation based on RTSemEventMultiWaitEx.
+ */
+
+/*
+ * Copyright (C) 2010-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+
+/*********************************************************************************************************************************
+*   Header Files                                                                                                                 *
+*********************************************************************************************************************************/
+#define LOG_GROUP RTLOGGROUP_SEM
+#define RTSEMEVENTMULTI_WITHOUT_REMAPPING
+#include <iprt/semaphore.h>
+#include "internal/iprt.h"
+
+#include <iprt/err.h>
+#include <iprt/assert.h>
+
+
+RTDECL(int)  RTSemEventMultiWait(RTSEMEVENTMULTI hEventMultiSem, RTMSINTERVAL cMillies)
+{
+    int rc;
+    if (cMillies == RT_INDEFINITE_WAIT)
+        rc = RTSemEventMultiWaitEx(hEventMultiSem, RTSEMWAIT_FLAGS_RESUME | RTSEMWAIT_FLAGS_INDEFINITE, 0);
+    else
+        rc = RTSemEventMultiWaitEx(hEventMultiSem,
+                                   RTSEMWAIT_FLAGS_RESUME | RTSEMWAIT_FLAGS_RELATIVE | RTSEMWAIT_FLAGS_MILLISECS,
+                                   cMillies);
+    Assert(rc != VERR_INTERRUPTED);
+    return rc;
+}
+RT_EXPORT_SYMBOL(RTSemEventMultiWait);
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/vboxguest/generic/RTSemEventMultiWaitNoResume-2-ex-generic.c
@@ -0,0 +1,53 @@
+/* $Id: RTSemEventMultiWaitNoResume-2-ex-generic.cpp $ */
+/** @file
+ * IPRT - RTSemEventMultiWaitNoResume, generic implementation based
+ *        on RTSemEventMultiWaitEx.
+ */
+
+/*
+ * Copyright (C) 2010-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+
+/*********************************************************************************************************************************
+*   Header Files                                                                                                                 *
+*********************************************************************************************************************************/
+#define LOG_GROUP RTLOGGROUP_SEM
+#define RTSEMEVENTMULTI_WITHOUT_REMAPPING
+#include <iprt/semaphore.h>
+#include "internal/iprt.h"
+
+#include <iprt/err.h>
+#include <iprt/assert.h>
+
+
+RTDECL(int) RTSemEventMultiWaitNoResume(RTSEMEVENTMULTI hEventMultiSem, RTMSINTERVAL cMillies)
+{
+    int rc;
+    if (cMillies == RT_INDEFINITE_WAIT)
+        rc = RTSemEventMultiWaitEx(hEventMultiSem, RTSEMWAIT_FLAGS_NORESUME | RTSEMWAIT_FLAGS_INDEFINITE, 0);
+    else
+        rc = RTSemEventMultiWaitEx(hEventMultiSem,
+                                   RTSEMWAIT_FLAGS_NORESUME | RTSEMWAIT_FLAGS_RELATIVE | RTSEMWAIT_FLAGS_MILLISECS,
+                                   cMillies);
+    return rc;
+}
+RT_EXPORT_SYMBOL(RTSemEventMultiWaitNoResume);
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/vboxguest/generic/RTSemEventWait-2-ex-generic.c
@@ -0,0 +1,53 @@
+/* $Id: RTSemEventWait-2-ex-generic.cpp $ */
+/** @file
+ * IPRT - RTSemEventWait, implementation based on RTSemEventWaitEx.
+ */
+
+/*
+ * Copyright (C) 2010-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+
+/*********************************************************************************************************************************
+*   Header Files                                                                                                                 *
+*********************************************************************************************************************************/
+#define LOG_GROUP RTLOGGROUP_SEM
+#define RTSEMEVENT_WITHOUT_REMAPPING
+#include <iprt/semaphore.h>
+#include "internal/iprt.h"
+
+#include <iprt/err.h>
+#include <iprt/assert.h>
+
+
+RTDECL(int)  RTSemEventWait(RTSEMEVENT hEventSem, RTMSINTERVAL cMillies)
+{
+    int rc;
+    if (cMillies == RT_INDEFINITE_WAIT)
+        rc = RTSemEventWaitEx(hEventSem, RTSEMWAIT_FLAGS_RESUME | RTSEMWAIT_FLAGS_INDEFINITE, 0);
+    else
+        rc = RTSemEventWaitEx(hEventSem,
+                              RTSEMWAIT_FLAGS_RESUME | RTSEMWAIT_FLAGS_RELATIVE | RTSEMWAIT_FLAGS_MILLISECS,
+                              cMillies);
+    Assert(rc != VERR_INTERRUPTED);
+    return rc;
+}
+RT_EXPORT_SYMBOL(RTSemEventWait);
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/vboxguest/generic/RTSemEventWaitNoResume-2-ex-generic.c
@@ -0,0 +1,53 @@
+/* $Id: RTSemEventWaitNoResume-2-ex-generic.cpp $ */
+/** @file
+ * IPRT - RTSemEventWaitNoResume, generic implementation based
+ *        on RTSemEventWaitEx.
+ */
+
+/*
+ * Copyright (C) 2010-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+
+/*********************************************************************************************************************************
+*   Header Files                                                                                                                 *
+*********************************************************************************************************************************/
+#define LOG_GROUP RTLOGGROUP_SEM
+#define RTSEMEVENT_WITHOUT_REMAPPING
+#include <iprt/semaphore.h>
+#include "internal/iprt.h"
+
+#include <iprt/err.h>
+#include <iprt/assert.h>
+
+
+RTDECL(int) RTSemEventWaitNoResume(RTSEMEVENT hEventSem, RTMSINTERVAL cMillies)
+{
+    int rc;
+    if (cMillies == RT_INDEFINITE_WAIT)
+        rc = RTSemEventWaitEx(hEventSem, RTSEMWAIT_FLAGS_NORESUME | RTSEMWAIT_FLAGS_INDEFINITE, 0);
+    else
+        rc = RTSemEventWaitEx(hEventSem,
+                              RTSEMWAIT_FLAGS_NORESUME | RTSEMWAIT_FLAGS_RELATIVE | RTSEMWAIT_FLAGS_MILLISECS,
+                              cMillies);
+    return rc;
+}
+RT_EXPORT_SYMBOL(RTSemEventWaitNoResume);
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/vboxguest/generic/errvars-generic.c
@@ -0,0 +1,66 @@
+/* $Id: errvars-generic.cpp $ */
+/** @file
+ * IPRT - Save and Restore Error Variables, generic stub implementation.
+ */
+
+/*
+ * Copyright (C) 2011-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+
+/*********************************************************************************************************************************
+*   Header Files                                                                                                                 *
+*********************************************************************************************************************************/
+#include <iprt/err.h>
+#include "internal/iprt.h"
+
+#include <iprt/assert.h>
+#include "internal/magics.h"
+
+
+
+RTDECL(PRTERRVARS) RTErrVarsSave(PRTERRVARS pVars)
+{
+    pVars->ai32Vars[0] = RTERRVARS_MAGIC;
+    return pVars;
+}
+
+
+RTDECL(void) RTErrVarsRestore(PCRTERRVARS pVars)
+{
+    Assert(pVars->ai32Vars[0] == RTERRVARS_MAGIC);
+}
+
+
+RTDECL(bool) RTErrVarsAreEqual(PCRTERRVARS pVars1, PCRTERRVARS pVars2)
+{
+    Assert(pVars1->ai32Vars[0] == RTERRVARS_MAGIC);
+    Assert(pVars2->ai32Vars[0] == RTERRVARS_MAGIC);
+
+    return pVars1->ai32Vars[0] == pVars2->ai32Vars[0];
+}
+
+
+RTDECL(bool) RTErrVarsHaveChanged(PCRTERRVARS pVars)
+{
+    Assert(pVars->ai32Vars[0] == RTERRVARS_MAGIC);
+    return false;
+}
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/vboxguest/generic/mppresent-generic.c
@@ -0,0 +1,61 @@
+/* $Id: mppresent-generic.cpp $ */
+/** @file
+ * IPRT - Multiprocessor, Stubs for the RTMp*Present* API.
+ */
+
+/*
+ * Copyright (C) 2008-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+
+/*********************************************************************************************************************************
+*   Header Files                                                                                                                 *
+*********************************************************************************************************************************/
+#include <iprt/mp.h>
+#include "internal/iprt.h"
+
+
+RTDECL(PRTCPUSET) RTMpGetPresentSet(PRTCPUSET pSet)
+{
+    return RTMpGetSet(pSet);
+}
+RT_EXPORT_SYMBOL(RTMpGetPresentSet);
+
+
+RTDECL(RTCPUID) RTMpGetPresentCount(void)
+{
+    return RTMpGetCount();
+}
+RT_EXPORT_SYMBOL(RTMpGetPresentCount);
+
+
+RTDECL(RTCPUID) RTMpGetPresentCoreCount(void)
+{
+    return RTMpGetCoreCount();
+}
+RT_EXPORT_SYMBOL(RTMpGetPresentCoreCount);
+
+
+RTDECL(bool) RTMpIsCpuPresent(RTCPUID idCpu)
+{
+    return RTMpIsCpuPossible(idCpu);
+}
+RT_EXPORT_SYMBOL(RTMpIsCpuPresent);
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/vboxguest/product-generated.h
@@ -0,0 +1,10 @@
+#ifndef ___product_generated_h___
+#define ___product_generated_h___
+
+#define VBOX_VENDOR "Oracle Corporation"
+#define VBOX_VENDOR_SHORT "Oracle"
+#define VBOX_PRODUCT "Oracle VM VirtualBox"
+#define VBOX_BUILD_PUBLISHER "_Ubuntu"
+#define VBOX_C_YEAR "2016"
+
+#endif
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/vboxguest/revision-generated.h
@@ -0,0 +1 @@
+#define VBOX_SVN_REV 106667
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/vboxguest/version-generated.h
@@ -0,0 +1,13 @@
+#ifndef ___version_generated_h___
+#define ___version_generated_h___
+
+#define VBOX_VERSION_MAJOR 5
+#define VBOX_VERSION_MINOR 0
+#define VBOX_VERSION_BUILD 18
+#define VBOX_VERSION_STRING_RAW "5.0.18"
+#define VBOX_VERSION_STRING "5.0.18_Ubuntu"
+#define VBOX_API_VERSION_STRING "5_0"
+
+#define VBOX_PRIVATE_BUILD_DESC "Private build by root"
+
+#endif
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/vboxsf/GenericRequest.c
@@ -0,0 +1,170 @@
+/* $Id: GenericRequest.cpp $ */
+/** @file
+ * VBoxGuestLibR0 - Generic VMMDev request management.
+ */
+
+/*
+ * Copyright (C) 2006-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+#include "VBGLInternal.h"
+#include <iprt/asm.h>
+#include <iprt/asm-amd64-x86.h>
+#include <iprt/assert.h>
+#include <iprt/string.h>
+
+
+DECLVBGL(int) VbglGRVerify(const VMMDevRequestHeader *pReq, size_t cbReq)
+{
+    size_t cbReqExpected;
+
+    if (RT_UNLIKELY(!pReq || cbReq < sizeof(VMMDevRequestHeader)))
+    {
+        dprintf(("VbglGRVerify: Invalid parameter: pReq = %p, cbReq = %zu\n", pReq, cbReq));
+        return VERR_INVALID_PARAMETER;
+    }
+
+    if (RT_UNLIKELY(pReq->size > cbReq))
+    {
+        dprintf(("VbglGRVerify: request size %u > buffer size %zu\n", pReq->size, cbReq));
+        return VERR_INVALID_PARAMETER;
+    }
+
+    /* The request size must correspond to the request type. */
+    cbReqExpected = vmmdevGetRequestSize(pReq->requestType);
+    if (RT_UNLIKELY(cbReq < cbReqExpected))
+    {
+        dprintf(("VbglGRVerify: buffer size %zu < expected size %zu\n", cbReq, cbReqExpected));
+        return VERR_INVALID_PARAMETER;
+    }
+
+    if (cbReqExpected == cbReq)
+    {
+        /*
+         * This is most likely a fixed size request, and in this case the
+         * request size must be also equal to the expected size.
+         */
+        if (RT_UNLIKELY(pReq->size != cbReqExpected))
+        {
+            dprintf(("VbglGRVerify: request size %u != expected size %zu\n", pReq->size, cbReqExpected));
+            return VERR_INVALID_PARAMETER;
+        }
+
+        return VINF_SUCCESS;
+    }
+
+    /*
+     * This can be a variable size request. Check the request type and limit the size
+     * to VMMDEV_MAX_VMMDEVREQ_SIZE, which is max size supported by the host.
+     *
+     * Note: Keep this list sorted for easier human lookup!
+     */
+    if (   pReq->requestType == VMMDevReq_ChangeMemBalloon
+#ifdef VBOX_WITH_64_BITS_GUESTS
+        || pReq->requestType == VMMDevReq_HGCMCall32
+        || pReq->requestType == VMMDevReq_HGCMCall64
+#else
+        || pReq->requestType == VMMDevReq_HGCMCall
+#endif
+        || pReq->requestType == VMMDevReq_RegisterSharedModule
+        || pReq->requestType == VMMDevReq_ReportGuestUserState
+        || pReq->requestType == VMMDevReq_LogString
+        || pReq->requestType == VMMDevReq_SetPointerShape
+        || pReq->requestType == VMMDevReq_VideoSetVisibleRegion)
+    {
+        if (RT_UNLIKELY(cbReq > VMMDEV_MAX_VMMDEVREQ_SIZE))
+        {
+            dprintf(("VbglGRVerify: VMMDevReq_LogString: buffer size %zu too big\n", cbReq));
+            return VERR_BUFFER_OVERFLOW; /** @todo is this error code ok? */
+        }
+    }
+    else
+    {
+        dprintf(("VbglGRVerify: request size %u > buffer size %zu\n", pReq->size, cbReq));
+        return VERR_IO_BAD_LENGTH; /** @todo is this error code ok? */
+    }
+
+    return VINF_SUCCESS;
+}
+
+DECLVBGL(int) VbglGRAlloc(VMMDevRequestHeader **ppReq, size_t cbReq, VMMDevRequestType enmReqType)
+{
+    int rc = vbglR0Enter();
+    if (RT_SUCCESS(rc))
+    {
+        if (   ppReq
+            && cbReq >= sizeof(VMMDevRequestHeader)
+            && cbReq == (uint32_t)cbReq)
+        {
+            VMMDevRequestHeader *pReq = (VMMDevRequestHeader *)VbglPhysHeapAlloc((uint32_t)cbReq);
+            AssertMsgReturn(pReq, ("VbglGRAlloc: no memory (cbReq=%u)\n", cbReq), VERR_NO_MEMORY);
+            memset(pReq, 0xAA, cbReq);
+
+            pReq->size        = (uint32_t)cbReq;
+            pReq->version     = VMMDEV_REQUEST_HEADER_VERSION;
+            pReq->requestType = enmReqType;
+            pReq->rc          = VERR_GENERAL_FAILURE;
+            pReq->reserved1   = 0;
+            pReq->reserved2   = 0;
+
+            *ppReq = pReq;
+            rc = VINF_SUCCESS;
+        }
+        else
+        {
+            dprintf(("VbglGRAlloc: Invalid parameter: ppReq=%p cbReq=%u\n", ppReq, cbReq));
+            rc = VERR_INVALID_PARAMETER;
+        }
+    }
+    return rc;
+}
+
+DECLVBGL(int) VbglGRPerform(VMMDevRequestHeader *pReq)
+{
+    int rc = vbglR0Enter();
+    if (RT_SUCCESS(rc))
+    {
+        if (pReq)
+        {
+            RTCCPHYS PhysAddr = VbglPhysHeapGetPhysAddr(pReq);
+            if (   PhysAddr != 0
+                && PhysAddr < _4G) /* Port IO is 32 bit. */
+            {
+                ASMOutU32(g_vbgldata.portVMMDev + VMMDEV_PORT_OFF_REQUEST, (uint32_t)PhysAddr);
+                /* Make the compiler aware that the host has changed memory. */
+                ASMCompilerBarrier();
+                rc = pReq->rc;
+            }
+            else
+                rc = VERR_VBGL_INVALID_ADDR;
+        }
+        else
+            rc = VERR_INVALID_PARAMETER;
+    }
+    return rc;
+}
+
+DECLVBGL(void) VbglGRFree(VMMDevRequestHeader *pReq)
+{
+    int rc = vbglR0Enter();
+    if (RT_SUCCESS(rc))
+        VbglPhysHeapFree(pReq);
+}
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/vboxsf/HGCM.c
@@ -0,0 +1,195 @@
+/* $Id: HGCM.cpp $ */
+/** @file
+ * VBoxGuestLib - Host-Guest Communication Manager.
+ *
+ * These public functions can be only used by other drivers. They all
+ * do an IOCTL to VBoxGuest via IDC.
+ */
+
+/*
+ * Copyright (C) 2006-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+/* Entire file is ifdef'ed with !VBGL_VBOXGUEST */
+#ifndef VBGL_VBOXGUEST
+
+#include "VBGLInternal.h"
+
+#include <iprt/assert.h>
+#include <iprt/semaphore.h>
+#include <iprt/string.h>
+
+#define VBGL_HGCM_ASSERT_MSG AssertReleaseMsg
+
+/**
+ * Initializes the HGCM VBGL bits.
+ *
+ * @return VBox status code.
+ */
+int vbglR0HGCMInit(void)
+{
+    return RTSemFastMutexCreate(&g_vbgldata.mutexHGCMHandle);
+}
+
+/**
+ * Initializes the HGCM VBGL bits.
+ *
+ * @return VBox status code.
+ */
+int vbglR0HGCMTerminate(void)
+{
+    RTSemFastMutexDestroy(g_vbgldata.mutexHGCMHandle);
+    g_vbgldata.mutexHGCMHandle = NIL_RTSEMFASTMUTEX;
+
+    return VINF_SUCCESS;
+}
+
+DECLINLINE(int) vbglHandleHeapEnter(void)
+{
+    int rc = RTSemFastMutexRequest(g_vbgldata.mutexHGCMHandle);
+
+    VBGL_HGCM_ASSERT_MSG(RT_SUCCESS(rc), ("Failed to request handle heap mutex, rc = %Rrc\n", rc));
+
+    return rc;
+}
+
+DECLINLINE(void) vbglHandleHeapLeave(void)
+{
+    RTSemFastMutexRelease(g_vbgldata.mutexHGCMHandle);
+}
+
+struct VBGLHGCMHANDLEDATA *vbglHGCMHandleAlloc(void)
+{
+    struct VBGLHGCMHANDLEDATA *p = NULL;
+    int rc = vbglHandleHeapEnter();
+    if (RT_SUCCESS(rc))
+    {
+        uint32_t i;
+
+        /* Simple linear search in array. This will be called not so often, only connect/disconnect. */
+        /** @todo bitmap for faster search and other obvious optimizations. */
+        for (i = 0; i < RT_ELEMENTS(g_vbgldata.aHGCMHandleData); i++)
+        {
+            if (!g_vbgldata.aHGCMHandleData[i].fAllocated)
+            {
+                p = &g_vbgldata.aHGCMHandleData[i];
+                p->fAllocated = 1;
+                break;
+            }
+        }
+
+        vbglHandleHeapLeave();
+
+        VBGL_HGCM_ASSERT_MSG(p != NULL, ("Not enough HGCM handles.\n"));
+    }
+    return p;
+}
+
+void vbglHGCMHandleFree(struct VBGLHGCMHANDLEDATA *pHandle)
+{
+    if (pHandle)
+    {
+        int rc = vbglHandleHeapEnter();
+        if (RT_SUCCESS(rc))
+        {
+            VBGL_HGCM_ASSERT_MSG(pHandle->fAllocated, ("Freeing not allocated handle.\n"));
+
+            RT_ZERO(*pHandle);
+            vbglHandleHeapLeave();
+        }
+    }
+}
+
+DECLVBGL(int) VbglHGCMConnect(VBGLHGCMHANDLE *pHandle, VBoxGuestHGCMConnectInfo *pData)
+{
+    int rc;
+    if (pHandle && pData)
+    {
+        struct VBGLHGCMHANDLEDATA *pHandleData = vbglHGCMHandleAlloc();
+        if (pHandleData)
+        {
+            rc = vbglDriverOpen(&pHandleData->driver);
+            if (RT_SUCCESS(rc))
+            {
+                rc = vbglDriverIOCtl(&pHandleData->driver, VBOXGUEST_IOCTL_HGCM_CONNECT, pData, sizeof(*pData));
+                if (RT_SUCCESS(rc))
+                    rc = pData->result;
+                if (RT_SUCCESS(rc))
+                {
+                    *pHandle = pHandleData;
+                    return rc;
+                }
+
+                vbglDriverClose(&pHandleData->driver);
+            }
+
+            vbglHGCMHandleFree(pHandleData);
+        }
+        else
+            rc = VERR_NO_MEMORY;
+    }
+    else
+        rc = VERR_INVALID_PARAMETER;
+    return rc;
+}
+
+DECLVBGL(int) VbglHGCMDisconnect(VBGLHGCMHANDLE handle, VBoxGuestHGCMDisconnectInfo *pData)
+{
+    int rc = vbglDriverIOCtl(&handle->driver, VBOXGUEST_IOCTL_HGCM_DISCONNECT, pData, sizeof(*pData));
+
+    vbglDriverClose(&handle->driver);
+
+    vbglHGCMHandleFree(handle);
+
+    return rc;
+}
+
+DECLVBGL(int) VbglHGCMCall(VBGLHGCMHANDLE handle, VBoxGuestHGCMCallInfo *pData, uint32_t cbData)
+{
+    VBGL_HGCM_ASSERT_MSG(cbData >= sizeof(VBoxGuestHGCMCallInfo) + pData->cParms * sizeof(HGCMFunctionParameter),
+                         ("cbData = %d, cParms = %d (calculated size %d)\n", cbData, pData->cParms,
+                          sizeof(VBoxGuestHGCMCallInfo) + pData->cParms * sizeof(VBoxGuestHGCMCallInfo)));
+
+    return vbglDriverIOCtl(&handle->driver, VBOXGUEST_IOCTL_HGCM_CALL(cbData), pData, cbData);
+}
+
+DECLVBGL(int) VbglHGCMCallUserData (VBGLHGCMHANDLE handle, VBoxGuestHGCMCallInfo *pData, uint32_t cbData)
+{
+    VBGL_HGCM_ASSERT_MSG(cbData >= sizeof(VBoxGuestHGCMCallInfo) + pData->cParms * sizeof(HGCMFunctionParameter),
+                         ("cbData = %d, cParms = %d (calculated size %d)\n", cbData, pData->cParms,
+                          sizeof(VBoxGuestHGCMCallInfo) + pData->cParms * sizeof(VBoxGuestHGCMCallInfo)));
+
+    return vbglDriverIOCtl(&handle->driver, VBOXGUEST_IOCTL_HGCM_CALL_USERDATA(cbData), pData, cbData);
+}
+
+
+DECLVBGL(int) VbglHGCMCallTimed(VBGLHGCMHANDLE handle, VBoxGuestHGCMCallInfoTimed *pData, uint32_t cbData)
+{
+    uint32_t cbExpected = sizeof(VBoxGuestHGCMCallInfoTimed)
+                        + pData->info.cParms * sizeof(HGCMFunctionParameter);
+    VBGL_HGCM_ASSERT_MSG(cbData >= cbExpected,
+                         ("cbData = %d, cParms = %d (calculated size %d)\n", cbData, pData->info.cParms, cbExpected));
+    NOREF(cbExpected);
+
+    return vbglDriverIOCtl(&handle->driver, VBOXGUEST_IOCTL_HGCM_CALL_TIMED(cbData), pData, cbData);
+}
+
+#endif /* !VBGL_VBOXGUEST */
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/vboxsf/Init.c
@@ -0,0 +1,310 @@
+/* $Id: Init.cpp $ */
+/** @file
+ * VBoxGuestLibR0 - Library initialization.
+ */
+
+/*
+ * Copyright (C) 2006-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+
+/*********************************************************************************************************************************
+*   Header Files                                                                                                                 *
+*********************************************************************************************************************************/
+#define VBGL_DECL_DATA
+#include "VBGLInternal.h"
+
+#include <iprt/string.h>
+#include <iprt/assert.h>
+#include <iprt/semaphore.h>
+
+
+/*********************************************************************************************************************************
+*   Global Variables                                                                                                             *
+*********************************************************************************************************************************/
+/** The global VBGL instance data.  */
+VBGLDATA g_vbgldata;
+
+/**
+ * Used by vbglQueryDriverInfo and VbglInit to try get the host feature mask and
+ * version information (g_vbgldata::hostVersion).
+ *
+ * This was first implemented by the host in 3.1 and we quietly ignore failures
+ * for that reason.
+ */
+static void vbglR0QueryHostVersion (void)
+{
+    VMMDevReqHostVersion *pReq;
+
+    int rc = VbglGRAlloc ((VMMDevRequestHeader **) &pReq, sizeof (*pReq), VMMDevReq_GetHostVersion);
+
+    if (RT_SUCCESS (rc))
+    {
+        rc = VbglGRPerform (&pReq->header);
+
+        if (RT_SUCCESS (rc))
+        {
+            g_vbgldata.hostVersion = *pReq;
+            Log (("vbglR0QueryHostVersion: %u.%u.%ur%u %#x\n",
+                  pReq->major, pReq->minor, pReq->build, pReq->revision, pReq->features));
+        }
+
+        VbglGRFree (&pReq->header);
+    }
+}
+
+#ifndef VBGL_VBOXGUEST
+/**
+ * The guest library uses lazy initialization for VMMDev port and memory,
+ * because these values are provided by the VBoxGuest driver and it might
+ * be loaded later than other drivers.
+ *
+ * The VbglEnter checks the current library status, tries to retrieve these
+ * values and fails if they are unavailable.
+ *
+ */
+static void vbglQueryDriverInfo (void)
+{
+    int rc = VINF_SUCCESS;
+
+    rc = RTSemMutexRequest(g_vbgldata.mutexDriverInit, RT_INDEFINITE_WAIT);
+
+    if (RT_FAILURE(rc))
+        return;
+
+    if (g_vbgldata.status == VbglStatusReady)
+    {
+        RTSemMutexRelease(g_vbgldata.mutexDriverInit);
+        return;
+    }
+
+    rc = vbglDriverOpen(&g_vbgldata.driver);
+
+    if (RT_SUCCESS(rc))
+    {
+        /*
+         * Try query the port info.
+         */
+        VBoxGuestPortInfo port;
+
+        rc = vbglDriverIOCtl (&g_vbgldata.driver,
+                              VBOXGUEST_IOCTL_GETVMMDEVPORT, &port,
+                              sizeof (port));
+
+        if (RT_SUCCESS (rc))
+        {
+            dprintf (("port = 0x%04X, mem = %p\n", port.portAddress, port.pVMMDevMemory));
+
+            g_vbgldata.portVMMDev = (RTIOPORT)port.portAddress;
+            g_vbgldata.pVMMDevMemory = port.pVMMDevMemory;
+
+            g_vbgldata.status = VbglStatusReady;
+
+            vbglR0QueryHostVersion();
+        }
+    }
+    RTSemMutexRelease(g_vbgldata.mutexDriverInit);
+    dprintf (("vbglQueryDriverInfo rc = %d\n", rc));
+}
+#endif /* !VBGL_VBOXGUEST */
+
+/**
+ * Checks if VBGL has been initialized.
+ *
+ * The client library, this will lazily complete the initialization.
+ *
+ * @return VINF_SUCCESS or VERR_VBGL_NOT_INITIALIZED.
+ */
+int vbglR0Enter (void)
+{
+    int rc;
+
+#ifndef VBGL_VBOXGUEST
+    if (g_vbgldata.status == VbglStatusInitializing)
+    {
+        vbglQueryDriverInfo ();
+    }
+#endif
+
+    rc = g_vbgldata.status == VbglStatusReady? VINF_SUCCESS: VERR_VBGL_NOT_INITIALIZED;
+
+    // dprintf(("VbglEnter: rc = %d\n", rc));
+
+    return rc;
+}
+
+int vbglInitCommon (void)
+{
+    int rc = VINF_SUCCESS;
+
+    RT_ZERO(g_vbgldata);
+
+    g_vbgldata.status = VbglStatusInitializing;
+
+    rc = VbglPhysHeapInit ();
+
+    if (RT_SUCCESS(rc))
+    {
+        /* other subsystems, none yet */
+        ;
+    }
+    else
+    {
+        LogRel(("vbglInitCommon: VbglPhysHeapInit failed. rc=%Rrc\n", rc));
+        g_vbgldata.status = VbglStatusNotInitialized;
+    }
+
+    dprintf(("vbglInitCommon: rc = %d\n", rc));
+
+    return rc;
+}
+
+DECLVBGL(void) vbglTerminateCommon (void)
+{
+    VbglPhysHeapTerminate ();
+    g_vbgldata.status = VbglStatusNotInitialized;
+
+    return;
+}
+
+#ifdef VBGL_VBOXGUEST
+
+DECLVBGL(int) VbglInitPrimary(RTIOPORT portVMMDev, VMMDevMemory *pVMMDevMemory)
+{
+    int rc = VINF_SUCCESS;
+
+# ifdef RT_OS_WINDOWS /** @todo r=bird: this doesn't make sense. Is there something special going on on windows? */
+    dprintf(("vbglInit: starts g_vbgldata.status %d\n", g_vbgldata.status));
+
+    if (   g_vbgldata.status == VbglStatusInitializing
+        || g_vbgldata.status == VbglStatusReady)
+    {
+        /* Initialization is already in process. */
+        return rc;
+    }
+# else
+    dprintf(("vbglInit: starts\n"));
+# endif
+
+    rc = vbglInitCommon ();
+
+    if (RT_SUCCESS(rc))
+    {
+        g_vbgldata.portVMMDev = portVMMDev;
+        g_vbgldata.pVMMDevMemory = pVMMDevMemory;
+
+        g_vbgldata.status = VbglStatusReady;
+
+        vbglR0QueryHostVersion();
+    }
+    else
+    {
+        g_vbgldata.status = VbglStatusNotInitialized;
+    }
+
+    return rc;
+}
+
+DECLVBGL(void) VbglTerminate (void)
+{
+    vbglTerminateCommon ();
+
+    return;
+}
+
+
+#else /* !VBGL_VBOXGUEST */
+
+DECLVBGL(int) VbglInitClient(void)
+{
+    int rc = VINF_SUCCESS;
+
+    if (   g_vbgldata.status == VbglStatusInitializing
+        || g_vbgldata.status == VbglStatusReady)
+    {
+        /* Initialization is already in process. */
+        return rc;
+    }
+
+    rc = vbglInitCommon ();
+
+    if (RT_SUCCESS(rc))
+    {
+        rc = RTSemMutexCreate(&g_vbgldata.mutexDriverInit);
+        if (RT_SUCCESS(rc))
+        {
+            /* Try to obtain VMMDev port via IOCTL to VBoxGuest main driver. */
+            vbglQueryDriverInfo ();
+
+# ifdef VBOX_WITH_HGCM
+            rc = vbglR0HGCMInit ();
+# endif /* VBOX_WITH_HGCM */
+
+            if (RT_FAILURE(rc))
+            {
+                RTSemMutexDestroy(g_vbgldata.mutexDriverInit);
+                g_vbgldata.mutexDriverInit = NIL_RTSEMMUTEX;
+            }
+        }
+
+        if (RT_FAILURE(rc))
+        {
+            vbglTerminateCommon ();
+        }
+
+    }
+
+    return rc;
+}
+
+DECLVBGL(void) VbglTerminate (void)
+{
+# ifdef VBOX_WITH_HGCM
+    vbglR0HGCMTerminate ();
+# endif
+
+    /* driver open could fail, which does not prevent VbglInit from succeeding,
+     * close the driver only if it is opened */
+    if (vbglDriverIsOpened(&g_vbgldata.driver))
+        vbglDriverClose(&g_vbgldata.driver);
+    RTSemMutexDestroy(g_vbgldata.mutexDriverInit);
+    g_vbgldata.mutexDriverInit = NIL_RTSEMMUTEX;
+
+    /* note: do vbglTerminateCommon as a last step since it zeroez up the g_vbgldata
+     * conceptually, doing vbglTerminateCommon last is correct
+     * since this is the reverse order to how init is done */
+    vbglTerminateCommon ();
+
+    return;
+}
+
+int vbglGetDriver(VBGLDRIVER **ppDriver)
+{
+    if (g_vbgldata.status != VbglStatusReady)
+    {
+        vbglQueryDriverInfo();
+        if (g_vbgldata.status != VbglStatusReady)
+            return VERR_TRY_AGAIN;
+    }
+    *ppDriver = &g_vbgldata.driver;
+    return VINF_SUCCESS;
+}
+
+#endif /* !VBGL_VBOXGUEST */
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/vboxsf/Makefile
@@ -0,0 +1,92 @@
+KBUILD_EXTMOD=${srctree}/ubuntu/vbox
+#
+# VirtualBox Guest Additions Module Makefile.
+#
+# (For 2.6.x this file must be 'Makefile'!)
+#
+# Copyright (C) 2006-2011 Oracle Corporation
+#
+# This file is part of VirtualBox Open Source Edition (OSE), as
+# available from http://www.virtualbox.org. This file is free software;
+# you can redistribute it and/or modify it under the terms of the GNU
+# General Public License (GPL) as published by the Free Software
+# Foundation, in version 2 as it comes in the "COPYING" file of the
+# VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+# hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+#
+
+# Linux kbuild sets this to our source directory if we are called from there
+obj ?= $(CURDIR)
+include $(obj)/Makefile.include.header
+
+MOD_NAME = vboxsf
+MOD_OBJS   = \
+	vfsmod.o \
+	dirops.o \
+	lnkops.o \
+	regops.o \
+	utils.o \
+	GenericRequest.o \
+	SysHlp.o \
+	PhysHeap.o \
+	Init.o \
+	VMMDev.o \
+	HGCM.o \
+	VBoxGuestR0LibSharedFolders.o \
+	VbglR0CanUsePhysPageList.o
+ifeq ($(BUILD_TARGET_ARCH),x86)
+MOD_OBJS  += \
+	divdi3.o \
+	moddi3.o \
+	udivdi3.o \
+	umoddi3.o \
+	qdivrem.o
+endif
+
+MOD_INCL = \
+    $(addprefix -I$(KBUILD_EXTMOD),/ /include /r0drv/linux) \
+    $(addprefix -I$(KBUILD_EXTMOD)/vboxsf,/ /include /r0drv/linux)
+
+ifneq ($(wildcard $(KBUILD_EXTMOD)/vboxsf),)
+ MANGLING := $(KBUILD_EXTMOD)/vboxsf/include/VBox/VBoxGuestMangling.h
+else
+ MANGLING := $(KBUILD_EXTMOD)/include/VBox/VBoxGuestMangling.h
+endif
+
+MOD_DEFS   = -DRT_OS_LINUX -DIN_RING0 -DIN_RT_R0 \
+	    -DIN_SUP_R0 -DVBOX -DVBOX_WITH_HGCM -DIN_MODULE -DIN_GUEST_R0
+# our module does not export any symbol
+MOD_DEFS  += -DRT_NO_EXPORT_SYMBOL
+ifeq ($(BUILD_TARGET_ARCH),amd64)
+ MOD_DEFS += -DRT_ARCH_AMD64 -DVBOX_WITH_64_BITS_GUESTS
+else
+ MOD_DEFS += -DRT_ARCH_X86
+endif
+
+ifeq ($(KERN_VERSION), 24)
+ MOD_CFLAGS =
+else
+ MOD_CFLAGS = -Wno-declaration-after-statement -fshort-wchar -include $(MANGLING)
+
+# special hack for Fedora Core 6 2.6.18 (fc6), rhel5 2.6.18 (el5),
+# ClarkConnect 4.3 (cc4) and ClarkConnect 5 (v5)
+ ifeq ($(KERNELRELEASE),)
+  MOD_EXTRA += $(foreach inc,$(KERN_INCL),\
+              $(if $(wildcard $(inc)/linux/utsrelease.h),\
+                $(if $(shell grep '"2.6.18.*fc6.*"' $(inc)/linux/utsrelease.h; \
+			    grep '"2.6.18.*el5.*"' $(inc)/linux/utsrelease.h; \
+			    grep '"2.6.18.*v5.*"'  $(inc)/linux/utsrelease.h; \
+			    grep '"2.6.18.*cc4.*"' $(inc)/linux/utsrelease.h),\
+		-DKERNEL_FC6,),))
+ else
+  MOD_EXTRA += $(if $(shell echo "$(KERNELRELEASE)"|grep '2.6.18.*fc6.*';\
+			echo "$(KERNELRELEASE)"|grep '2.6.18.*el5.*';\
+			echo "$(KERNELRELEASE)"|grep '2.6.18.*v5.*';\
+			echo "$(KERNELRELEASE)"|grep '2.6.18.*cc4.*'),\
+		-DKERNEL_FC6,)
+ endif
+endif
+
+MOD_CLEAN = . linux r0drv r0drv/linux
+
+include $(obj)/Makefile.include.footer
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/vboxsf/Makefile.include.footer
@@ -0,0 +1,96 @@
+#
+# VirtualBox Guest Additions kernel module Makefile, common parts.
+#
+# See Makefile.include.header for details of how to use this.
+#
+# Copyright (C) 2006-2015 Oracle Corporation
+#
+# This file is part of VirtualBox Open Source Edition (OSE), as
+# available from http://www.virtualbox.org. This file is free software;
+# you can redistribute it and/or modify it under the terms of the GNU
+# General Public License (GPL) as published by the Free Software
+# Foundation, in version 2 as it comes in the "COPYING" file of the
+# VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+# hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+#
+
+# override is required by the Debian guys
+override MODULE = $(MOD_NAME)
+OBJS   = $(MOD_OBJS)
+
+ifneq ($(MAKECMDGOALS),clean)
+
+KBUILD_VERBOSE ?= 1
+
+#
+# Compiler options
+#
+ifndef INCL
+ INCL    := $(addprefix -I,$(KERN_INCL) $(EXTRA_INCL))
+ ifndef KBUILD_EXTMOD
+  KBUILD_EXTMOD := $(shell pwd)
+ endif
+ INCL    += $(MOD_INCL)
+ export INCL
+endif
+KFLAGS   := -D__KERNEL__ -DMODULE $(MOD_DEFS)
+ifeq ($(BUILD_TYPE),debug)
+ KFLAGS  += -DDEBUG -DDEBUG_$(subst $(subst _, ,_),_,$(USERNAME)) -DDEBUG_USERNAME=$(subst $(subst _, ,_),_,$(USERNAME))
+endif
+
+ifeq ($(KERN_VERSION), 24)
+#
+# 2.4
+#
+
+ifeq ($(BUILD_TARGET_ARCH),amd64)
+ KFLAGS  += -mcmodel=kernel
+endif
+
+CFLAGS := -O2 -DVBOX_LINUX_2_4 $(MOD_CFLAGS) $(INCL) $(KFLAGS) $(MOD_EXTRA) $(KDEBUG)
+MODULE_EXT := o
+
+# 2.4 Module linking
+$(MODULE).o: $(OBJS)
+	$(LD) -o $@ -r $(OBJS)
+
+.PHONY: $(MODULE)
+all: $(MODULE)
+$(MODULE): $(MODULE).o
+
+else
+#
+# 2.6 and later
+#
+
+MODULE_EXT := ko
+
+$(MODULE)-y  := $(OBJS)
+
+# build defs
+EXTRA_CFLAGS += $(MOD_CFLAGS) $(INCL) $(KFLAGS) $(MOD_EXTRA) $(KDEBUG)
+
+all: $(MODULE)
+
+obj-m += $(MODULE).o
+
+# OL/UEK: disable module signing for external modules -- we don't have any private key
+$(MODULE):
+	$(MAKE) KBUILD_VERBOSE=$(KBUILD_VERBOSE) CONFIG_MODULE_SIG= -C $(KERN_DIR) SUBDIRS=$(CURDIR) SRCROOT=$(CURDIR) modules
+
+modules_install:
+	$(MAKE) KBUILD_VERBOSE=$(KBUILD_VERBOSE) CONFIG_MODULE_SIG= -C $(KERN_DIR) SUBDIRS=$(CURDIR) SRCROOT=$(CURDIR) modules_install
+
+endif
+
+install: $(MODULE)
+	@mkdir -p $(MODULE_DIR); \
+	install -m 0644 -o root -g root $(MODULE).$(MODULE_EXT) $(MODULE_DIR); \
+	PATH="$(PATH):/bin:/sbin" depmod -a;
+
+endif # eq($(MAKECMDGOALS),clean)
+
+# important: Don't remove Module.symvers! DKMS does 'make clean' before building ...
+clean:
+	for f in $(MOD_CLEAN); do rm -f $$f/*.o $$f/.*.cmd $$f/.*.flags; done
+	rm -rf .$(MOD_NAME)* .tmp_ver* $(MOD_NAME).* Modules.symvers modules.order
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/vboxsf/Makefile.include.header
@@ -0,0 +1,173 @@
+#
+# VirtualBox Guest Additions kernel module Makefile, common parts.
+#
+# (For 2.6.x, the main file must be called 'Makefile'!)
+#
+# Copyright (C) 2006-2015 Oracle Corporation
+#
+# This file is part of VirtualBox Open Source Edition (OSE), as
+# available from http://www.virtualbox.org. This file is free software;
+# you can redistribute it and/or modify it under the terms of the GNU
+# General Public License (GPL) as published by the Free Software
+# Foundation, in version 2 as it comes in the "COPYING" file of the
+# VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+# hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+#
+
+#
+# These file should be included by the Makefiles for any kernel modules we
+# build as part of the Guest Additions.  The intended way of doing this is as
+# follows:
+#
+# # Linux kbuild sets this to our source directory if we are called from
+# # there
+# obj ?= $(CURDIR)
+# include $(obj)/Makefile.include.header
+# MOD_NAME = <name of the module to be built, without extension>
+# MOD_OBJS = <list of object files which should be included>
+# MOD_DEFS = <any additional defines which this module needs>
+# MOD_INCL = <any additional include paths which this module needs>
+# MOD_CFLAGS = <any additional CFLAGS which this module needs>
+# MOD_CLEAN = <list of directories that the clean target should look at>
+# include $(obj)/Makefile.include.footer
+#
+# The kmk kBuild define KBUILD_TARGET_ARCH is available.
+#
+
+
+#
+# First, figure out which architecture we're targeting and the build type.
+# (We have to support basic cross building (ARCH=i386|x86_64).)
+# While at it, warn about BUILD_* vars found to help with user problems.
+#
+ifeq ($(filter-out x86_64 amd64 AMD64,$(shell uname -m)),)
+ BUILD_TARGET_ARCH_DEF := amd64
+else
+ BUILD_TARGET_ARCH_DEF := x86
+endif
+ifneq ($(filter-out amd64 x86,$(BUILD_TARGET_ARCH)),)
+ $(warning Ignoring unknown BUILD_TARGET_ARCH value '$(BUILD_TARGET_ARCH)'.)
+ BUILD_TARGET_ARCH :=
+endif
+ifeq ($(BUILD_TARGET_ARCH),)
+ ifeq ($(ARCH),x86_64)
+  BUILD_TARGET_ARCH := amd64
+ else
+  ifeq ($(ARCH),i386)
+   ifeq ($(CONFIG_X86_32),y)
+     BUILD_TARGET_ARCH := x86
+   else
+     BUILD_TARGET_ARCH := amd64
+   endif
+  else
+    ifeq ($(ARCH),x86)
+      ifeq ($(CONFIG_X86_32),y)
+        BUILD_TARGET_ARCH := x86
+      else
+        BUILD_TARGET_ARCH := amd64
+      endif
+    else
+      BUILD_TARGET_ARCH := $(BUILD_TARGET_ARCH_DEF)
+    endif
+  endif
+ endif
+else
+ ifneq ($(BUILD_TARGET_ARCH),$(BUILD_TARGET_ARCH_DEF))
+  $(warning Using BUILD_TARGET_ARCH='$(BUILD_TARGET_ARCH)' from the $(origin BUILD_TARGET_ARCH).)
+ endif
+endif
+
+ifneq ($(filter-out release profile debug strict,$(BUILD_TYPE)),)
+ $(warning Ignoring unknown BUILD_TYPE value '$(BUILD_TYPE)'.)
+ BUILD_TYPE :=
+endif
+ifeq ($(BUILD_TYPE),)
+ BUILD_TYPE := release
+else
+ ifneq ($(BUILD_TYPE),release)
+  $(warning Using BUILD_TYPE='$(BUILD_TYPE)' from the $(origin BUILD_TYPE).)
+ endif
+endif
+ifeq ($(USERNAME),)
+ USERNAME := noname
+endif
+
+ifneq ($(MAKECMDGOALS),clean)
+
+ifeq ($(KERNELRELEASE),)
+
+ #
+ # building from this directory
+ #
+
+ # kernel base directory
+ ifndef KERN_DIR
+  KERN_DIR := /lib/modules/$(shell uname -r)/build
+  ifneq ($(shell if test -d $(KERN_DIR); then echo yes; fi),yes)
+   KERN_DIR := /usr/src/linux
+   ifneq ($(shell if test -d $(KERN_DIR); then echo yes; fi),yes)
+    $(error Error: unable to find the sources of your current Linux kernel. \
+	           Specify KERN_DIR=<directory> and run Make again)
+   endif
+   $(warning Warning: using /usr/src/linux as the source directory of your \
+                      Linux kernel. If this is not correct, specify \
+		      KERN_DIR=<directory> and run Make again.)
+  endif
+ else
+  ifneq ($(shell if test -d $(KERN_DIR); then echo yes; fi),yes)
+   $(error Error: KERN_DIR does not point to a directory)
+  endif
+ endif
+
+ # includes
+ ifndef KERN_INCL
+  KERN_INCL = $(KERN_DIR)/include
+ endif
+ ifneq ($(shell if test -d $(KERN_INCL); then echo yes; fi),yes)
+  $(error Error: unable to find the include directory for your current Linux \
+                 kernel. Specify KERN_INCL=<directory> and run Make again)
+ endif
+
+ # module install dir, only for current kernel
+ ifneq ($(filter install install_rpm,$(MAKECMDGOALS)),)
+  ifndef MODULE_DIR
+   MODULE_DIR_TST := /lib/modules/$(shell uname -r)
+   ifeq ($(shell if test -d $(MODULE_DIR_TST); then echo yes; fi),yes)
+    MODULE_DIR := $(MODULE_DIR_TST)/misc
+   else
+    $(error Unable to find the folder to install the module to)
+   endif
+  endif # MODULE_DIR unspecified
+ endif
+
+ # guess kernel version (24 or 26)
+ ifeq ($(shell if grep '"2\.4\.' $(KERN_INCL)/linux/version.h > /dev/null; then echo yes; fi),yes)
+  KERN_VERSION := 24
+ else
+  KERN_VERSION := 26
+ endif
+
+else # neq($(KERNELRELEASE),)
+
+ #
+ # building from kbuild (make -C <kernel_directory> M=`pwd`)
+ #
+
+ # guess kernel version (24 or 26)
+ ifeq ($(shell if echo "$(VERSION).$(PATCHLEVEL)." | grep '2\.4\.' > /dev/null; then echo yes; fi),yes)
+  KERN_VERSION := 24
+ else
+  KERN_VERSION := 26
+ endif
+
+endif # neq($(KERNELRELEASE),)
+
+# debug - show guesses.
+ifdef DEBUG
+$(warning dbg: KERN_DIR     = $(KERN_DIR))
+$(warning dbg: KERN_INCL    = $(KERN_INCL))
+$(warning dbg: MODULE_DIR   = $(MODULE_DIR))
+$(warning dbg: KERN_VERSION = $(KERN_VERSION))
+endif
+
+endif # eq($(MAKECMDGOALS),clean)
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/vboxsf/PhysHeap.c
@@ -0,0 +1,636 @@
+/* $Id: PhysHeap.cpp $ */
+/** @file
+ * VBoxGuestLibR0 - Physical memory heap.
+ */
+
+/*
+ * Copyright (C) 2006-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+#include "VBGLInternal.h"
+
+#include <iprt/assert.h>
+#include <iprt/semaphore.h>
+#include <iprt/alloc.h>
+
+/* Physical memory heap consists of double linked list
+ * of chunks. Memory blocks are allocated inside these chunks
+ * and are members of Allocated and Free double linked lists.
+ *
+ * When allocating a block, we search in Free linked
+ * list for a suitable free block. If there is no such block,
+ * a new chunk is allocated and the new block is taken from
+ * the new chunk as the only chunk-sized free block.
+ * Allocated block is excluded from the Free list and goes to
+ * Alloc list.
+ *
+ * When freeing block, we check the pointer and then
+ * exclude block from Alloc list and move it to free list.
+ *
+ * For each chunk we maintain the allocated blocks counter.
+ * if 2 (or more) entire chunks are free they are immediately
+ * deallocated, so we always have at most 1 free chunk.
+ *
+ * When freeing blocks, two subsequent free blocks are always
+ * merged together. Current implementation merges blocks only
+ * when there is a block after the just freed one.
+ *
+ */
+
+#define VBGL_PH_ASSERT      Assert
+#define VBGL_PH_ASSERTMsg   AssertMsg
+
+// #define DUMPHEAP
+
+#ifdef DUMPHEAP
+# define VBGL_PH_dprintf(a) RTAssertMsg2Weak a
+#else
+# define VBGL_PH_dprintf(a)
+#endif
+
+/* Heap block signature */
+#define VBGL_PH_BLOCKSIGNATURE (0xADDBBBBB)
+
+
+/* Heap chunk signature */
+#define VBGL_PH_CHUNKSIGNATURE (0xADDCCCCC)
+/* Heap chunk allocation unit */
+#define VBGL_PH_CHUNKSIZE (0x10000)
+
+/* Heap block bit flags */
+#define VBGL_PH_BF_ALLOCATED (0x1)
+
+struct _VBGLPHYSHEAPBLOCK
+{
+    uint32_t u32Signature;
+
+    /* Size of user data in the block. Does not include the block header. */
+    uint32_t cbDataSize;
+
+    uint32_t fu32Flags;
+
+    struct _VBGLPHYSHEAPBLOCK *pNext;
+    struct _VBGLPHYSHEAPBLOCK *pPrev;
+
+    struct _VBGLPHYSHEAPCHUNK *pChunk;
+};
+
+struct _VBGLPHYSHEAPCHUNK
+{
+    uint32_t u32Signature;
+
+    /* Size of the chunk. Includes the chunk header. */
+    uint32_t cbSize;
+
+    /* Physical address of the chunk */
+    uint32_t physAddr;
+
+    /* Number of allocated blocks in the chunk */
+    int32_t cAllocatedBlocks;
+
+    struct _VBGLPHYSHEAPCHUNK *pNext;
+    struct _VBGLPHYSHEAPCHUNK *pPrev;
+};
+
+
+#ifndef DUMPHEAP
+#define dumpheap(a)
+#else
+void dumpheap (char *point)
+{
+   VBGL_PH_dprintf(("VBGL_PH dump at '%s'\n", point));
+
+   VBGL_PH_dprintf(("Chunks:\n"));
+
+   VBGLPHYSHEAPCHUNK *pChunk = g_vbgldata.pChunkHead;
+
+   while (pChunk)
+   {
+       VBGL_PH_dprintf(("%p: pNext = %p, pPrev = %p, sign = %08X, size = %8d, allocated = %8d, phys = %08X\n",
+                        pChunk, pChunk->pNext, pChunk->pPrev, pChunk->u32Signature, pChunk->cbSize, pChunk->cAllocatedBlocks, pChunk->physAddr));
+
+       pChunk = pChunk->pNext;
+   }
+
+   VBGL_PH_dprintf(("Allocated blocks:\n"));
+
+   VBGLPHYSHEAPBLOCK *pBlock = g_vbgldata.pAllocBlocksHead;
+
+   while (pBlock)
+   {
+       VBGL_PH_dprintf(("%p: pNext = %p, pPrev = %p, sign = %08X, size = %8d, flags = %08X, pChunk = %p\n",
+                        pBlock, pBlock->pNext, pBlock->pPrev, pBlock->u32Signature, pBlock->cbDataSize, pBlock->fu32Flags, pBlock->pChunk));
+
+       pBlock = pBlock->pNext;
+   }
+
+   VBGL_PH_dprintf(("Free blocks:\n"));
+
+   pBlock = g_vbgldata.pFreeBlocksHead;
+
+   while (pBlock)
+   {
+       VBGL_PH_dprintf(("%p: pNext = %p, pPrev = %p, sign = %08X, size = %8d, flags = %08X, pChunk = %p\n",
+                        pBlock, pBlock->pNext, pBlock->pPrev, pBlock->u32Signature, pBlock->cbDataSize, pBlock->fu32Flags, pBlock->pChunk));
+
+       pBlock = pBlock->pNext;
+   }
+
+   VBGL_PH_dprintf(("VBGL_PH dump at '%s' done\n", point));
+}
+#endif
+
+
+DECLINLINE(void *) vbglPhysHeapBlock2Data (VBGLPHYSHEAPBLOCK *pBlock)
+{
+    return (void *)(pBlock? (char *)pBlock + sizeof (VBGLPHYSHEAPBLOCK): NULL);
+}
+
+DECLINLINE(VBGLPHYSHEAPBLOCK *) vbglPhysHeapData2Block (void *p)
+{
+    VBGLPHYSHEAPBLOCK *pBlock = (VBGLPHYSHEAPBLOCK *)(p? (char *)p - sizeof (VBGLPHYSHEAPBLOCK): NULL);
+
+    VBGL_PH_ASSERTMsg(pBlock == NULL || pBlock->u32Signature == VBGL_PH_BLOCKSIGNATURE,
+                     ("pBlock->u32Signature = %08X\n", pBlock->u32Signature));
+
+    return pBlock;
+}
+
+DECLINLINE(int) vbglPhysHeapEnter (void)
+{
+    int rc = RTSemFastMutexRequest(g_vbgldata.mutexHeap);
+
+    VBGL_PH_ASSERTMsg(RT_SUCCESS(rc),
+                     ("Failed to request heap mutex, rc = %Rrc\n", rc));
+
+    return rc;
+}
+
+DECLINLINE(void) vbglPhysHeapLeave (void)
+{
+    RTSemFastMutexRelease(g_vbgldata.mutexHeap);
+}
+
+
+static void vbglPhysHeapInitBlock (VBGLPHYSHEAPBLOCK *pBlock, VBGLPHYSHEAPCHUNK *pChunk, uint32_t cbDataSize)
+{
+    VBGL_PH_ASSERT(pBlock != NULL);
+    VBGL_PH_ASSERT(pChunk != NULL);
+
+    pBlock->u32Signature = VBGL_PH_BLOCKSIGNATURE;
+    pBlock->cbDataSize   = cbDataSize;
+    pBlock->fu32Flags    = 0;
+    pBlock->pNext        = NULL;
+    pBlock->pPrev        = NULL;
+    pBlock->pChunk       = pChunk;
+}
+
+
+static void vbglPhysHeapInsertBlock (VBGLPHYSHEAPBLOCK *pInsertAfter, VBGLPHYSHEAPBLOCK *pBlock)
+{
+    VBGL_PH_ASSERTMsg(pBlock->pNext == NULL,
+                     ("pBlock->pNext = %p\n", pBlock->pNext));
+    VBGL_PH_ASSERTMsg(pBlock->pPrev == NULL,
+                     ("pBlock->pPrev = %p\n", pBlock->pPrev));
+
+    if (pInsertAfter)
+    {
+        pBlock->pNext = pInsertAfter->pNext;
+        pBlock->pPrev = pInsertAfter;
+
+        if (pInsertAfter->pNext)
+        {
+            pInsertAfter->pNext->pPrev = pBlock;
+        }
+
+        pInsertAfter->pNext = pBlock;
+    }
+    else
+    {
+        /* inserting to head of list */
+        pBlock->pPrev = NULL;
+
+        if (pBlock->fu32Flags & VBGL_PH_BF_ALLOCATED)
+        {
+            pBlock->pNext = g_vbgldata.pAllocBlocksHead;
+
+            if (g_vbgldata.pAllocBlocksHead)
+            {
+                g_vbgldata.pAllocBlocksHead->pPrev = pBlock;
+            }
+
+            g_vbgldata.pAllocBlocksHead = pBlock;
+        }
+        else
+        {
+            pBlock->pNext = g_vbgldata.pFreeBlocksHead;
+
+            if (g_vbgldata.pFreeBlocksHead)
+            {
+                g_vbgldata.pFreeBlocksHead->pPrev = pBlock;
+            }
+
+            g_vbgldata.pFreeBlocksHead = pBlock;
+        }
+    }
+}
+
+static void vbglPhysHeapExcludeBlock (VBGLPHYSHEAPBLOCK *pBlock)
+{
+    if (pBlock->pNext)
+    {
+        pBlock->pNext->pPrev = pBlock->pPrev;
+    }
+    else
+    {
+        /* this is tail of list but we do not maintain tails of block lists.
+         * so do nothing.
+         */
+        ;
+    }
+
+    if (pBlock->pPrev)
+    {
+        pBlock->pPrev->pNext = pBlock->pNext;
+    }
+    else
+    {
+        /* this is head of list but we do not maintain tails of block lists. */
+        if (pBlock->fu32Flags & VBGL_PH_BF_ALLOCATED)
+        {
+            g_vbgldata.pAllocBlocksHead = pBlock->pNext;
+        }
+        else
+        {
+            g_vbgldata.pFreeBlocksHead = pBlock->pNext;
+        }
+    }
+
+    pBlock->pNext = NULL;
+    pBlock->pPrev = NULL;
+}
+
+static VBGLPHYSHEAPBLOCK *vbglPhysHeapChunkAlloc (uint32_t cbSize)
+{
+    RTCCPHYS physAddr;
+    VBGLPHYSHEAPCHUNK *pChunk;
+    VBGLPHYSHEAPBLOCK *pBlock;
+    VBGL_PH_dprintf(("Allocating new chunk of size %d\n", cbSize));
+
+    /* Compute chunk size to allocate */
+    if (cbSize < VBGL_PH_CHUNKSIZE)
+    {
+        /* Includes case of block size 0 during initialization */
+        cbSize = VBGL_PH_CHUNKSIZE;
+    }
+    else
+    {
+        /* Round up to next chunk size, which must be power of 2 */
+        cbSize = (cbSize + (VBGL_PH_CHUNKSIZE - 1)) & ~(VBGL_PH_CHUNKSIZE - 1);
+    }
+
+    physAddr = 0;
+    /* This function allocates physical contiguous memory (below 4GB) according to the IPRT docs.
+     * Address < 4G is required for the port IO.
+     */
+    pChunk = (VBGLPHYSHEAPCHUNK *)RTMemContAlloc (&physAddr, cbSize);
+
+    if (!pChunk)
+    {
+        LogRel(("vbglPhysHeapChunkAlloc: failed to alloc %u contiguous bytes.\n", cbSize));
+        return NULL;
+    }
+
+    AssertRelease(physAddr < _4G && physAddr + cbSize <= _4G);
+
+    pChunk->u32Signature     = VBGL_PH_CHUNKSIGNATURE;
+    pChunk->cbSize           = cbSize;
+    pChunk->physAddr         = (uint32_t)physAddr;
+    pChunk->cAllocatedBlocks = 0;
+    pChunk->pNext            = g_vbgldata.pChunkHead;
+    pChunk->pPrev            = NULL;
+
+    /* Initialize the free block, which now occupies entire chunk. */
+    pBlock = (VBGLPHYSHEAPBLOCK *)((char *)pChunk + sizeof (VBGLPHYSHEAPCHUNK));
+
+    vbglPhysHeapInitBlock (pBlock, pChunk, cbSize - sizeof (VBGLPHYSHEAPCHUNK) - sizeof (VBGLPHYSHEAPBLOCK));
+
+    vbglPhysHeapInsertBlock (NULL, pBlock);
+
+    g_vbgldata.pChunkHead = pChunk;
+
+    VBGL_PH_dprintf(("Allocated chunk %p, block = %p size=%x\n", pChunk, pBlock, cbSize));
+
+    return pBlock;
+}
+
+
+void vbglPhysHeapChunkDelete (VBGLPHYSHEAPCHUNK *pChunk)
+{
+    char *p;
+    VBGL_PH_ASSERT(pChunk != NULL);
+    VBGL_PH_ASSERTMsg(pChunk->u32Signature == VBGL_PH_CHUNKSIGNATURE,
+                     ("pChunk->u32Signature = %08X\n", pChunk->u32Signature));
+
+    VBGL_PH_dprintf(("Deleting chunk %p size %x\n", pChunk, pChunk->cbSize));
+
+    /* first scan the chunk and exclude all blocks from lists */
+
+    p = (char *)pChunk + sizeof (VBGLPHYSHEAPCHUNK);
+
+    while (p < (char *)pChunk + pChunk->cbSize)
+    {
+        VBGLPHYSHEAPBLOCK *pBlock = (VBGLPHYSHEAPBLOCK *)p;
+
+        p += pBlock->cbDataSize + sizeof (VBGLPHYSHEAPBLOCK);
+
+        vbglPhysHeapExcludeBlock (pBlock);
+    }
+
+    VBGL_PH_ASSERTMsg(p == (char *)pChunk + pChunk->cbSize,
+                      ("p = %p, (char *)pChunk + pChunk->cbSize = %p, pChunk->cbSize = %08X\n",
+                       p, (char *)pChunk + pChunk->cbSize, pChunk->cbSize));
+
+    /* Exclude chunk from the chunk list */
+    if (pChunk->pNext)
+    {
+        pChunk->pNext->pPrev = pChunk->pPrev;
+    }
+    else
+    {
+        /* we do not maintain tail */
+        ;
+    }
+
+    if (pChunk->pPrev)
+    {
+        pChunk->pPrev->pNext = pChunk->pNext;
+    }
+    else
+    {
+        /* the chunk was head */
+        g_vbgldata.pChunkHead = pChunk->pNext;
+    }
+
+    RTMemContFree (pChunk, pChunk->cbSize);
+}
+
+
+DECLVBGL(void *) VbglPhysHeapAlloc (uint32_t cbSize)
+{
+    VBGLPHYSHEAPBLOCK *pBlock, *iter;
+    int rc = vbglPhysHeapEnter ();
+
+    if (RT_FAILURE(rc))
+        return NULL;
+
+    dumpheap ("pre alloc");
+
+    pBlock = NULL;
+
+    /* If there are free blocks in the heap, look at them. */
+    iter = g_vbgldata.pFreeBlocksHead;
+
+    /* There will be not many blocks in the heap, so
+     * linear search would be fast enough.
+     */
+
+    while (iter)
+    {
+        if (iter->cbDataSize == cbSize)
+        {
+            /* exact match */
+            pBlock = iter;
+            break;
+        }
+
+        /* Looking for a free block with nearest size */
+        if (iter->cbDataSize > cbSize)
+        {
+            if (pBlock)
+            {
+                if (iter->cbDataSize < pBlock->cbDataSize)
+                {
+                    pBlock = iter;
+                }
+            }
+            else
+            {
+                pBlock = iter;
+            }
+        }
+
+        iter = iter->pNext;
+    }
+
+    if (!pBlock)
+    {
+        /* No free blocks, allocate a new chunk,
+         * the only free block of the chunk will
+         * be returned.
+         */
+        pBlock = vbglPhysHeapChunkAlloc (cbSize);
+    }
+
+    if (pBlock)
+    {
+        VBGL_PH_ASSERTMsg(pBlock->u32Signature == VBGL_PH_BLOCKSIGNATURE,
+                         ("pBlock = %p, pBlock->u32Signature = %08X\n", pBlock, pBlock->u32Signature));
+        VBGL_PH_ASSERTMsg((pBlock->fu32Flags & VBGL_PH_BF_ALLOCATED) == 0,
+                         ("pBlock = %p, pBlock->fu32Flags = %08X\n", pBlock, pBlock->fu32Flags));
+
+        /* We have a free block, either found or allocated. */
+
+        if (pBlock->cbDataSize > 2*(cbSize + sizeof (VBGLPHYSHEAPBLOCK)))
+        {
+            /* Data will occupy less than a half of the block,
+             * the block should be split.
+             */
+            iter = (VBGLPHYSHEAPBLOCK *)((char *)pBlock + sizeof (VBGLPHYSHEAPBLOCK) + cbSize);
+
+            /* Init the new 'iter' block, initialized blocks are always marked as free. */
+            vbglPhysHeapInitBlock (iter, pBlock->pChunk, pBlock->cbDataSize - cbSize - sizeof (VBGLPHYSHEAPBLOCK));
+
+            pBlock->cbDataSize = cbSize;
+
+            /* Insert the new 'iter' block after the 'pBlock' in the free list */
+            vbglPhysHeapInsertBlock (pBlock, iter);
+        }
+
+        /* Exclude pBlock from free list */
+        vbglPhysHeapExcludeBlock (pBlock);
+
+        /* Mark as allocated */
+        pBlock->fu32Flags |= VBGL_PH_BF_ALLOCATED;
+
+        /* Insert to allocated list */
+        vbglPhysHeapInsertBlock (NULL, pBlock);
+
+        /* Adjust the chunk allocated blocks counter */
+        pBlock->pChunk->cAllocatedBlocks++;
+    }
+
+    dumpheap ("post alloc");
+
+    vbglPhysHeapLeave ();
+    VBGL_PH_dprintf(("VbglPhysHeapAlloc %x size %x\n", vbglPhysHeapBlock2Data (pBlock), pBlock->cbDataSize));
+
+    return vbglPhysHeapBlock2Data (pBlock);
+}
+
+DECLVBGL(uint32_t) VbglPhysHeapGetPhysAddr (void *p)
+{
+    uint32_t physAddr = 0;
+    VBGLPHYSHEAPBLOCK *pBlock = vbglPhysHeapData2Block (p);
+
+    if (pBlock)
+    {
+        VBGL_PH_ASSERTMsg((pBlock->fu32Flags & VBGL_PH_BF_ALLOCATED) != 0,
+                         ("pBlock = %p, pBlock->fu32Flags = %08X\n", pBlock, pBlock->fu32Flags));
+
+        if (pBlock->fu32Flags & VBGL_PH_BF_ALLOCATED)
+            physAddr = pBlock->pChunk->physAddr + (uint32_t)((uintptr_t)p - (uintptr_t)pBlock->pChunk);
+    }
+
+    return physAddr;
+}
+
+DECLVBGL(void) VbglPhysHeapFree(void *p)
+{
+    VBGLPHYSHEAPBLOCK *pBlock;
+    VBGLPHYSHEAPBLOCK *pNeighbour;
+
+    int rc = vbglPhysHeapEnter ();
+    if (RT_FAILURE(rc))
+        return;
+
+    dumpheap ("pre free");
+
+    pBlock = vbglPhysHeapData2Block (p);
+
+    if (!pBlock)
+    {
+        vbglPhysHeapLeave ();
+        return;
+    }
+
+    VBGL_PH_ASSERTMsg((pBlock->fu32Flags & VBGL_PH_BF_ALLOCATED) != 0,
+                     ("pBlock = %p, pBlock->fu32Flags = %08X\n", pBlock, pBlock->fu32Flags));
+
+    /* Exclude from allocated list */
+    vbglPhysHeapExcludeBlock (pBlock);
+
+    dumpheap ("post exclude");
+
+    VBGL_PH_dprintf(("VbglPhysHeapFree %x size %x\n", p, pBlock->cbDataSize));
+
+    /* Mark as free */
+    pBlock->fu32Flags &= ~VBGL_PH_BF_ALLOCATED;
+
+    /* Insert to free list */
+    vbglPhysHeapInsertBlock (NULL, pBlock);
+
+    dumpheap ("post insert");
+
+    /* Adjust the chunk allocated blocks counter */
+    pBlock->pChunk->cAllocatedBlocks--;
+
+    VBGL_PH_ASSERT(pBlock->pChunk->cAllocatedBlocks >= 0);
+
+    /* Check if we can merge 2 free blocks. To simplify heap maintenance,
+     * we will look at block after the just freed one.
+     * This will not prevent us from detecting free memory chunks.
+     * Also in most cases blocks are deallocated in reverse allocation order
+     * and in that case the merging will work.
+     */
+
+    pNeighbour = (VBGLPHYSHEAPBLOCK *)((char *)p + pBlock->cbDataSize);
+
+    if ((char *)pNeighbour < (char *)pBlock->pChunk + pBlock->pChunk->cbSize
+        && (pNeighbour->fu32Flags & VBGL_PH_BF_ALLOCATED) == 0)
+    {
+        /* The next block is free as well. */
+
+        /* Adjust size of current memory block */
+        pBlock->cbDataSize += pNeighbour->cbDataSize + sizeof (VBGLPHYSHEAPBLOCK);
+
+        /* Exclude the next neighbour */
+        vbglPhysHeapExcludeBlock (pNeighbour);
+    }
+
+    dumpheap ("post merge");
+
+    /* now check if there are 2 or more free chunks */
+    if (pBlock->pChunk->cAllocatedBlocks == 0)
+    {
+        VBGLPHYSHEAPCHUNK *pChunk = g_vbgldata.pChunkHead;
+
+        uint32_t u32FreeChunks = 0;
+
+        while (pChunk)
+        {
+            if (pChunk->cAllocatedBlocks == 0)
+            {
+                u32FreeChunks++;
+            }
+
+            pChunk = pChunk->pNext;
+        }
+
+        if (u32FreeChunks > 1)
+        {
+            /* Delete current chunk, it will also exclude all free blocks
+             * remaining in the chunk from the free list, so the pBlock
+             * will also be invalid after this.
+             */
+            vbglPhysHeapChunkDelete (pBlock->pChunk);
+        }
+    }
+
+    dumpheap ("post free");
+
+    vbglPhysHeapLeave ();
+}
+
+DECLVBGL(int) VbglPhysHeapInit (void)
+{
+    int rc = VINF_SUCCESS;
+
+    /* Allocate the first chunk of the heap. */
+    VBGLPHYSHEAPBLOCK *pBlock = vbglPhysHeapChunkAlloc (0);
+
+    if (!pBlock)
+        rc = VERR_NO_MEMORY;
+
+    RTSemFastMutexCreate(&g_vbgldata.mutexHeap);
+
+    return rc;
+}
+
+DECLVBGL(void) VbglPhysHeapTerminate (void)
+{
+    while (g_vbgldata.pChunkHead)
+    {
+        vbglPhysHeapChunkDelete (g_vbgldata.pChunkHead);
+    }
+
+    RTSemFastMutexDestroy(g_vbgldata.mutexHeap);
+}
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/vboxsf/SysHlp.c
@@ -0,0 +1,343 @@
+/* $Id: SysHlp.cpp $ */
+/** @file
+ * VBoxGuestLibR0 - IDC with VBoxGuest and HGCM helpers.
+ */
+
+/*
+ * Copyright (C) 2006-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+#define LOG_GROUP LOG_GROUP_HGCM
+#include <VBox/log.h>
+
+#include <VBox/VBoxGuestLib.h>
+#include "SysHlp.h"
+
+#include <iprt/assert.h>
+
+#ifdef VBGL_VBOXGUEST
+
+#if !defined (RT_OS_WINDOWS)
+# include <iprt/memobj.h>
+# include <iprt/mem.h>
+#endif
+
+
+/**
+ * Internal worker for locking a range of linear addresses.
+ *
+ * @returns VBox status code.
+ * @param   ppvCtx          Where to store context data.
+ * @param   pv              The start of the range.
+ * @param   u32Size         The size of the range.
+ * @param   fWriteAccess    Lock for read-write (true) or readonly (false).
+ * @param   fFlags          HGCM call flags, VBGLR0_HGCM_F_XXX.
+ */
+int vbglLockLinear(void **ppvCtx, void *pv, uint32_t u32Size, bool fWriteAccess, uint32_t fFlags)
+{
+    int         rc      = VINF_SUCCESS;
+#ifndef RT_OS_WINDOWS
+    RTR0MEMOBJ  MemObj  = NIL_RTR0MEMOBJ;
+    uint32_t    fAccess = RTMEM_PROT_READ | (fWriteAccess ? RTMEM_PROT_WRITE : 0);
+#endif
+
+    /* Zero size buffers shouldn't be locked. */
+    if (u32Size == 0)
+    {
+        Assert(pv == NULL);
+#ifdef RT_OS_WINDOWS
+        *ppvCtx = NULL;
+#else
+        *ppvCtx = NIL_RTR0MEMOBJ;
+#endif
+        return VINF_SUCCESS;
+    }
+
+    /** @todo just use IPRT here. the extra allocation shouldn't matter much...
+     *        Then we can move all this up one level even. */
+#ifdef RT_OS_WINDOWS
+    PMDL pMdl = IoAllocateMdl(pv, u32Size, FALSE, FALSE, NULL);
+
+    if (pMdl == NULL)
+    {
+        rc = VERR_NOT_SUPPORTED;
+        AssertMsgFailed(("IoAllocateMdl %p %x failed!!\n", pv, u32Size));
+    }
+    else
+    {
+        __try {
+            /* Calls to MmProbeAndLockPages must be enclosed in a try/except block. */
+            MmProbeAndLockPages(pMdl,
+                                /** @todo (fFlags & VBGLR0_HGCMCALL_F_MODE_MASK) == VBGLR0_HGCMCALL_F_USER? UserMode: KernelMode */
+                                KernelMode,
+                                (fWriteAccess) ? IoModifyAccess : IoReadAccess);
+
+            *ppvCtx = pMdl;
+
+        } __except(EXCEPTION_EXECUTE_HANDLER) {
+
+            IoFreeMdl(pMdl);
+            /** @todo  */
+            rc = VERR_INVALID_PARAMETER;
+            AssertMsgFailed(("MmProbeAndLockPages %p %x failed!!\n", pv, u32Size));
+        }
+    }
+
+#else
+    /*
+     * Lock depending on context.
+     *
+     * Note: We will later use the memory object here to convert the HGCM
+     *       linear buffer parameter into a physical page list. This is why
+     *       we lock both kernel pages on all systems, even those where we
+     *       know they aren't pageable.
+     */
+    if ((fFlags & VBGLR0_HGCMCALL_F_MODE_MASK) == VBGLR0_HGCMCALL_F_USER)
+        rc = RTR0MemObjLockUser(&MemObj, (RTR3PTR)pv, u32Size, fAccess, NIL_RTR0PROCESS);
+    else
+        rc = RTR0MemObjLockKernel(&MemObj, pv, u32Size, fAccess);
+    if (RT_SUCCESS(rc))
+        *ppvCtx = MemObj;
+    else
+        *ppvCtx = NIL_RTR0MEMOBJ;
+
+#endif
+
+    return rc;
+}
+
+void vbglUnlockLinear(void *pvCtx, void *pv, uint32_t u32Size)
+{
+#ifdef RT_OS_WINDOWS
+    PMDL pMdl = (PMDL)pvCtx;
+
+    Assert(pMdl);
+    if (pMdl != NULL)
+    {
+        MmUnlockPages(pMdl);
+        IoFreeMdl(pMdl);
+    }
+
+#else
+    RTR0MEMOBJ MemObj = (RTR0MEMOBJ)pvCtx;
+    int rc = RTR0MemObjFree(MemObj, false);
+    AssertRC(rc);
+
+#endif
+
+    NOREF(pv);
+    NOREF(u32Size);
+}
+
+#else  /* !VBGL_VBOXGUEST */
+
+# ifdef RT_OS_OS2
+#  include <VBox/VBoxGuest.h> /* for VBOXGUESTOS2IDCCONNECT */
+RT_C_DECLS_BEGIN
+/*
+ * On OS/2 we'll do the connecting in the assembly code of the
+ * client driver, exporting a g_VBoxGuestIDC symbol containing
+ * the connection information obtained from the 16-bit IDC.
+ */
+extern VBOXGUESTOS2IDCCONNECT g_VBoxGuestIDC;
+RT_C_DECLS_END
+# endif
+
+# if !defined(RT_OS_OS2) \
+  && !defined(RT_OS_WINDOWS)
+RT_C_DECLS_BEGIN
+extern DECLVBGL(void *) VBoxGuestIDCOpen(uint32_t *pu32Version);
+extern DECLVBGL(void)   VBoxGuestIDCClose(void *pvOpaque);
+extern DECLVBGL(int)    VBoxGuestIDCCall(void *pvOpaque, unsigned int iCmd, void *pvData, size_t cbSize, size_t *pcbReturn);
+RT_C_DECLS_END
+# endif
+
+bool vbglDriverIsOpened(VBGLDRIVER *pDriver)
+{
+# ifdef RT_OS_WINDOWS
+    return pDriver->pFileObject != NULL;
+# elif defined (RT_OS_OS2)
+    return pDriver->u32Session != UINT32_MAX && pDriver->u32Session != 0;
+# else
+    return pDriver->pvOpaque != NULL;
+# endif
+}
+
+int vbglDriverOpen(VBGLDRIVER *pDriver)
+{
+# ifdef RT_OS_WINDOWS
+    UNICODE_STRING uszDeviceName;
+    RtlInitUnicodeString(&uszDeviceName, L"\\Device\\VBoxGuest");
+
+    PDEVICE_OBJECT pDeviceObject = NULL;
+    PFILE_OBJECT pFileObject = NULL;
+
+    NTSTATUS rc = IoGetDeviceObjectPointer(&uszDeviceName, FILE_ALL_ACCESS, &pFileObject, &pDeviceObject);
+    if (NT_SUCCESS(rc))
+    {
+        Log(("vbglDriverOpen VBoxGuest successful pDeviceObject=%x\n", pDeviceObject));
+        pDriver->pDeviceObject = pDeviceObject;
+        pDriver->pFileObject = pFileObject;
+        return VINF_SUCCESS;
+    }
+    /** @todo return RTErrConvertFromNtStatus(rc)! */
+    Log(("vbglDriverOpen VBoxGuest failed with ntstatus=%x\n", rc));
+    return rc;
+
+# elif defined (RT_OS_OS2)
+    /*
+     * Just check whether the connection was made or not.
+     */
+    if (   g_VBoxGuestIDC.u32Version == VMMDEV_VERSION
+        && RT_VALID_PTR(g_VBoxGuestIDC.u32Session)
+        && RT_VALID_PTR(g_VBoxGuestIDC.pfnServiceEP))
+    {
+        pDriver->u32Session = g_VBoxGuestIDC.u32Session;
+        return VINF_SUCCESS;
+    }
+    pDriver->u32Session = UINT32_MAX;
+    Log(("vbglDriverOpen: failed\n"));
+    return VERR_FILE_NOT_FOUND;
+
+# else
+    uint32_t u32VMMDevVersion;
+    pDriver->pvOpaque = VBoxGuestIDCOpen(&u32VMMDevVersion);
+    if (   pDriver->pvOpaque
+        && u32VMMDevVersion == VMMDEV_VERSION)
+        return VINF_SUCCESS;
+
+    Log(("vbglDriverOpen: failed\n"));
+    return VERR_FILE_NOT_FOUND;
+# endif
+}
+
+# ifdef RT_OS_WINDOWS
+static NTSTATUS vbglDriverIOCtlCompletion(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context)
+{
+    Log(("VBGL completion %x\n", Irp));
+
+    KEVENT *pEvent = (KEVENT *)Context;
+    KeSetEvent(pEvent, IO_NO_INCREMENT, FALSE);
+
+    return STATUS_MORE_PROCESSING_REQUIRED;
+}
+# endif
+
+int vbglDriverIOCtl(VBGLDRIVER *pDriver, uint32_t u32Function, void *pvData, uint32_t cbData)
+{
+    Log(("vbglDriverIOCtl: pDriver: %p, Func: %x, pvData: %p, cbData: %d\n", pDriver, u32Function, pvData, cbData));
+
+# ifdef RT_OS_WINDOWS
+    KEVENT Event;
+
+    KeInitializeEvent(&Event, NotificationEvent, FALSE);
+
+    /* Have to use the IoAllocateIRP method because this code is generic and
+     * must work in any thread context.
+     * The IoBuildDeviceIoControlRequest, which was used here, does not work
+     * when APCs are disabled, for example.
+     */
+    PIRP irp = IoAllocateIrp(pDriver->pDeviceObject->StackSize, FALSE);
+
+    Log(("vbglDriverIOCtl: irp %p, IRQL = %d\n", irp, KeGetCurrentIrql()));
+
+    if (irp == NULL)
+    {
+        Log(("vbglDriverIOCtl: IRP allocation failed!\n"));
+        return VERR_NO_MEMORY;
+    }
+
+    /*
+     * Setup the IRP_MJ_DEVICE_CONTROL IRP.
+     */
+
+    PIO_STACK_LOCATION nextStack = IoGetNextIrpStackLocation(irp);
+
+    nextStack->MajorFunction = IRP_MJ_DEVICE_CONTROL;
+    nextStack->MinorFunction = 0;
+    nextStack->DeviceObject = pDriver->pDeviceObject;
+    nextStack->Parameters.DeviceIoControl.OutputBufferLength = cbData;
+    nextStack->Parameters.DeviceIoControl.InputBufferLength = cbData;
+    nextStack->Parameters.DeviceIoControl.IoControlCode = u32Function;
+    nextStack->Parameters.DeviceIoControl.Type3InputBuffer = pvData;
+
+    irp->AssociatedIrp.SystemBuffer = pvData; /* Output buffer. */
+    irp->MdlAddress = NULL;
+
+    /* A completion routine is required to signal the Event. */
+    IoSetCompletionRoutine(irp, vbglDriverIOCtlCompletion, &Event, TRUE, TRUE, TRUE);
+
+    NTSTATUS rc = IoCallDriver(pDriver->pDeviceObject, irp);
+
+    if (NT_SUCCESS (rc))
+    {
+        /* Wait the event to be signalled by the completion routine. */
+        KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
+
+        rc = irp->IoStatus.Status;
+
+        Log(("vbglDriverIOCtl: wait completed IRQL = %d\n", KeGetCurrentIrql()));
+    }
+
+    IoFreeIrp(irp);
+
+    if (rc != STATUS_SUCCESS)
+        Log(("vbglDriverIOCtl: ntstatus=%x\n", rc));
+
+    if (NT_SUCCESS(rc))
+        return VINF_SUCCESS;
+    if (rc == STATUS_INVALID_PARAMETER)
+        return VERR_INVALID_PARAMETER;
+    if (rc == STATUS_INVALID_BUFFER_SIZE)
+        return VERR_OUT_OF_RANGE;
+    return VERR_VBGL_IOCTL_FAILED;
+
+# elif defined (RT_OS_OS2)
+    if (    pDriver->u32Session
+        &&  pDriver->u32Session == g_VBoxGuestIDC.u32Session)
+        return g_VBoxGuestIDC.pfnServiceEP(pDriver->u32Session, u32Function, pvData, cbData, NULL);
+
+    Log(("vbglDriverIOCtl: No connection\n"));
+    return VERR_WRONG_ORDER;
+
+# else
+    return VBoxGuestIDCCall(pDriver->pvOpaque, u32Function, pvData, cbData, NULL);
+# endif
+}
+
+void vbglDriverClose(VBGLDRIVER *pDriver)
+{
+# ifdef RT_OS_WINDOWS
+    Log(("vbglDriverClose pDeviceObject=%x\n", pDriver->pDeviceObject));
+    ObDereferenceObject(pDriver->pFileObject);
+    pDriver->pFileObject = NULL;
+    pDriver->pDeviceObject = NULL;
+
+# elif defined (RT_OS_OS2)
+    pDriver->u32Session = 0;
+
+# else
+    VBoxGuestIDCClose(pDriver->pvOpaque);
+    pDriver->pvOpaque = NULL;
+# endif
+}
+
+#endif /* !VBGL_VBOXGUEST */
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/vboxsf/SysHlp.h
@@ -0,0 +1,122 @@
+/* $Id: SysHlp.h $ */
+/** @file
+ * VBoxGuestLibR0 - System dependent helpers internal header.
+ */
+
+/*
+ * Copyright (C) 2006-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+#ifndef ___VBoxGuestLib_SysHlp_h
+#define ___VBoxGuestLib_SysHlp_h
+
+#include <iprt/types.h>
+
+#ifdef RT_OS_WINDOWS
+# undef PAGE_SIZE
+# undef PAGE_SHIFT
+# if (_MSC_VER >= 1400) && !defined(VBOX_WITH_PATCHED_DDK)
+#  include <iprt/asm.h>
+#  define _InterlockedExchange           _InterlockedExchange_StupidDDKVsCompilerCrap
+#  define _InterlockedExchangeAdd        _InterlockedExchangeAdd_StupidDDKVsCompilerCrap
+#  define _InterlockedCompareExchange    _InterlockedCompareExchange_StupidDDKVsCompilerCrap
+#  define _InterlockedAddLargeStatistic  _InterlockedAddLargeStatistic_StupidDDKVsCompilerCrap
+#  pragma warning(disable : 4163)
+RT_C_DECLS_BEGIN
+#  include <ntddk.h>
+RT_C_DECLS_END
+#  pragma warning(default : 4163)
+#  undef  _InterlockedExchange
+#  undef  _InterlockedExchangeAdd
+#  undef  _InterlockedCompareExchange
+#  undef  _InterlockedAddLargeStatistic
+# else
+RT_C_DECLS_BEGIN
+#  include <ntddk.h>
+RT_C_DECLS_END
+# endif
+/* XP DDK #defines ExFreePool to ExFreePoolWithTag. The latter does not exist on NT4, so...
+ * The same for ExAllocatePool.
+ */
+# undef ExAllocatePool
+# undef ExFreePool
+#endif
+
+typedef struct _VBGLDRIVER
+{
+#ifdef RT_OS_WINDOWS
+    PDEVICE_OBJECT pDeviceObject;
+    PFILE_OBJECT pFileObject;
+#elif defined (RT_OS_OS2)
+    uint32_t u32Session; /**< just for sanity checking. */
+#else /* PORTME */
+    void *pvOpaque;
+#endif
+} VBGLDRIVER;
+
+int  vbglLockLinear(void **ppvCtx, void *pv, uint32_t cb, bool fWriteAccess, uint32_t fFlags);
+void vbglUnlockLinear(void *pvCtx, void *pv, uint32_t cb);
+
+
+#ifndef VBGL_VBOXGUEST
+
+/**
+ * Open VBoxGuest driver.
+ *
+ * @param pDriver      Pointer to the driver structure.
+ *
+ * @return VBox status code
+ */
+int vbglDriverOpen(VBGLDRIVER *pDriver);
+
+/**
+ * Answers whether the VBoxGuest driver is opened
+ *
+ * @param pDriver      Pointer to the driver structure.
+ *
+ * @return true - if opened, false - otherwise
+ */
+bool vbglDriverIsOpened(VBGLDRIVER *pDriver);
+
+/**
+ * Call VBoxGuest driver.
+ *
+ * @param pDriver      Pointer to the driver structure.
+ * @param u32Function  Function code.
+ * @param pvData       Pointer to supplied in/out data buffer.
+ * @param cbData       Size of data buffer.
+ *
+ * @returns VBox status code
+ */
+int vbglDriverIOCtl(VBGLDRIVER *pDriver, uint32_t u32Function, void *pvData, uint32_t cbData);
+
+/**
+ * Close VBoxGuest driver.
+ *
+ * @param pDriver      Pointer to the driver structure.
+ *
+ * @returns VBox status code
+ */
+void vbglDriverClose(VBGLDRIVER *pDriver);
+
+#endif
+
+#endif
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/vboxsf/VBGLInternal.h
@@ -0,0 +1,173 @@
+/* $Id: VBGLInternal.h $ */
+/** @file
+ * VBoxGuestLibR0 - Internal header.
+ */
+
+/*
+ * Copyright (C) 2006-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+#ifndef ___VBoxGuestLib_VBGLInternal_h
+#define ___VBoxGuestLib_VBGLInternal_h
+
+#include <VBox/VMMDev.h>
+#include <VBox/VBoxGuest.h>
+#include <VBox/VBoxGuestLib.h>
+
+#include <VBox/log.h>
+
+
+#ifdef RT_OS_WINDOWS /** @todo dprintf() -> Log() */
+# if (defined(DEBUG) && !defined(NO_LOGGING)) || defined(LOG_ENABLED)
+#  define dprintf(a) RTLogBackdoorPrintf a
+# else
+#  define dprintf(a) do {} while (0)
+# endif
+#else
+# define dprintf(a) Log(a)
+#endif
+
+#include "SysHlp.h"
+
+#pragma pack(4) /** @todo r=bird: What do we need packing for here? None of these structures are shared between drivers AFAIK. */
+
+struct _VBGLPHYSHEAPBLOCK;
+typedef struct _VBGLPHYSHEAPBLOCK VBGLPHYSHEAPBLOCK;
+struct _VBGLPHYSHEAPCHUNK;
+typedef struct _VBGLPHYSHEAPCHUNK VBGLPHYSHEAPCHUNK;
+
+#ifndef VBGL_VBOXGUEST
+struct VBGLHGCMHANDLEDATA
+{
+    uint32_t fAllocated;
+    VBGLDRIVER driver;
+};
+#endif
+
+enum VbglLibStatus
+{
+    VbglStatusNotInitialized = 0,
+    VbglStatusInitializing,
+    VbglStatusReady
+};
+
+/**
+ * Global VBGL ring-0 data.
+ * Lives in VbglR0Init.cpp.
+ */
+typedef struct VBGLDATA
+{
+    enum VbglLibStatus status;
+
+    RTIOPORT portVMMDev;
+
+    VMMDevMemory *pVMMDevMemory;
+
+    /**
+     * Physical memory heap data.
+     * @{
+     */
+
+    VBGLPHYSHEAPBLOCK *pFreeBlocksHead;
+    VBGLPHYSHEAPBLOCK *pAllocBlocksHead;
+    VBGLPHYSHEAPCHUNK *pChunkHead;
+
+    RTSEMFASTMUTEX mutexHeap;
+    /** @} */
+
+    /**
+     * The host version data.
+     */
+    VMMDevReqHostVersion hostVersion;
+
+
+#ifndef VBGL_VBOXGUEST
+    /**
+     * Handle for the main driver instance.
+     * @{
+     */
+
+    RTSEMMUTEX mutexDriverInit;
+
+    VBGLDRIVER driver;
+
+    /** @} */
+
+    /**
+     * Fast heap for HGCM handles data.
+     * @{
+     */
+
+    RTSEMFASTMUTEX mutexHGCMHandle;
+
+    struct VBGLHGCMHANDLEDATA aHGCMHandleData[64];
+
+    /** @} */
+#endif
+} VBGLDATA;
+
+
+#pragma pack()
+
+#ifndef VBGL_DECL_DATA
+extern VBGLDATA g_vbgldata;
+#endif
+
+/**
+ * Internal macro for checking whether we can pass physical page lists to the
+ * host.
+ *
+ * ASSUMES that vbglR0Enter has been called already.
+ *
+ * @param   a_fLocked       For the windows shared folders workarounds.
+ *
+ * @remarks Disabled the PageList feature for locked memory on Windows,
+ *          because a new MDL is created by VBGL to get the page addresses
+ *          and the pages from the MDL are marked as dirty when they should not.
+ */
+#if defined(RT_OS_WINDOWS)
+# define VBGLR0_CAN_USE_PHYS_PAGE_LIST(a_fLocked) \
+    ( !(a_fLocked) && (g_vbgldata.hostVersion.features & VMMDEV_HVF_HGCM_PHYS_PAGE_LIST) )
+#else
+# define VBGLR0_CAN_USE_PHYS_PAGE_LIST(a_fLocked) \
+    ( !!(g_vbgldata.hostVersion.features & VMMDEV_HVF_HGCM_PHYS_PAGE_LIST) )
+#endif
+
+int vbglR0Enter (void);
+
+#ifdef VBOX_WITH_HGCM
+# ifndef VBGL_VBOXGUEST
+int                         vbglR0HGCMInit(void);
+int                         vbglR0HGCMTerminate(void);
+# endif
+struct VBGLHGCMHANDLEDATA  *vbglHGCMHandleAlloc(void);
+void                        vbglHGCMHandleFree(struct VBGLHGCMHANDLEDATA *pHandle);
+#endif /* VBOX_WITH_HGCM */
+
+#ifndef VBGL_VBOXGUEST
+/**
+ * Get a handle to the main VBoxGuest driver.
+ * @returns VERR_TRY_AGAIN if the main driver has not yet been loaded.
+ */
+int vbglGetDriver(VBGLDRIVER **ppDriver);
+#endif
+
+#endif /* !___VBoxGuestLib_VBGLInternal_h */
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/vboxsf/VBoxGuestLog.h
@@ -0,0 +1,59 @@
+/* $Id: VBoxGuestLog.h $ */
+/** @file
+ * VBoxGuestLibR0 - Guest Logging facility.
+ */
+
+/*
+ * Copyright (C) 2006-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+#ifndef __VBOXGUESTLOG__H
+#define __VBOXGUESTLOG__H
+
+#ifndef RT_OS_WINDOWS
+# error "Don't include this file."
+#else  /* RT_OS_WINDOWS */
+/* Save LOG_ENABLED state, because "VBox/rt/log.h"
+ * may undefine it for IN_RING0 code.
+ */
+# if (defined(DEBUG) && !defined(NO_LOGGING)) || defined(LOG_ENABLED)
+#  define __LOG_ENABLED_SAVED__
+# endif
+
+# if (defined(DEBUG) && !defined(NO_LOGGING)) || defined(LOG_ENABLED)
+#  ifdef VBOX_GUEST
+#   include <VBox/log.h>
+#   undef Log
+#   define Log(a)  RTLogBackdoorPrintf a
+#  else
+#   define Log(a)  DbgPrint a
+#  endif
+# else
+#  define Log(a)
+# endif
+
+# ifdef __LOG_ENABLED_SAVED__
+#  define LOG_ENABLED
+#  undef __LOG_ENABLED_SAVED__
+# endif
+
+#endif  /* RT_OS_WINDOWS */
+
+#endif /* !__VBOXGUESTLOG__H */
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/vboxsf/VBoxGuestR0LibSharedFolders.c
@@ -0,0 +1,746 @@
+/* $Id: VBoxGuestR0LibSharedFolders.c $ */
+/** @file
+ * VBoxGuestR0LibSharedFolders - Ring 0 Shared Folders calls.
+ */
+
+/*
+ * Copyright (C) 2006-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+/* Entire file is ifdef'ed with !VBGL_VBOXGUEST */
+#ifndef VBGL_VBOXGUEST
+
+
+/*********************************************************************************************************************************
+*   Header Files                                                                                                                 *
+*********************************************************************************************************************************/
+#define LOG_GROUP LOG_GROUP_SHARED_FOLDERS
+#include <VBox/VBoxGuestLibSharedFolders.h>
+#include <VBox/log.h>
+#include <iprt/time.h>
+#include <iprt/mem.h>
+#include <iprt/path.h>
+#include <iprt/string.h>
+
+
+/*********************************************************************************************************************************
+*   Defined Constants And Macros                                                                                                 *
+*********************************************************************************************************************************/
+#define SHFL_CPARMS_SET_UTF8 0
+#define SHFL_CPARMS_SET_SYMLINKS 0
+
+#define VBOX_INIT_CALL(a, b, c) \
+    LogFunc(("%s, idClient=%d\n", "SHFL_FN_" # b, (c)->idClient)); \
+    (a)->result      = VINF_SUCCESS; \
+    (a)->u32ClientID = (c)->idClient; \
+    (a)->u32Function = SHFL_FN_##b; \
+    (a)->cParms      = SHFL_CPARMS_##b
+
+
+
+DECLVBGL(int) VbglR0SfInit(void)
+{
+    return VbglInitClient();
+}
+
+DECLVBGL(void) VbglR0SfTerm(void)
+{
+    VbglTerminate();
+}
+
+DECLVBGL(int) VbglR0SfConnect(PVBGLSFCLIENT pClient)
+{
+    int rc;
+    VBoxGuestHGCMConnectInfo data;
+
+    pClient->handle = NULL;
+
+    RT_ZERO(data);
+    data.result   = VINF_SUCCESS;
+    data.Loc.type = VMMDevHGCMLoc_LocalHost_Existing;
+    strcpy (data.Loc.u.host.achName, "VBoxSharedFolders");
+
+    rc = VbglHGCMConnect(&pClient->handle, &data);
+/*    Log(("VBOXSF: VbglR0SfConnect: VbglHGCMConnect rc = %#x, result = %#x\n", rc, data.result)); */
+    if (RT_SUCCESS(rc))
+        rc = data.result;
+    if (RT_SUCCESS(rc))
+    {
+        pClient->idClient = data.u32ClientID;
+        LogFunc(("idClient=%d\n", pClient->idClient));
+    }
+    return rc;
+}
+
+DECLVBGL(void) VbglR0SfDisconnect(PVBGLSFCLIENT pClient)
+{
+    int rc;
+    VBoxGuestHGCMDisconnectInfo data;
+
+    LogFunc(("u32ClientID=%d\n", pClient->idClient));
+    if (pClient->handle == NULL)
+        return;                 /* not connected */
+
+    RT_ZERO(data);
+    data.result      = VINF_SUCCESS;
+    data.u32ClientID = pClient->idClient;
+
+    rc = VbglHGCMDisconnect(pClient->handle, &data);
+    NOREF(rc);
+/*    Log(("VBOXSF: VbglR0SfDisconnect: VbglHGCMDisconnect rc = %#x, result = %#x\n", rc, data.result)); */
+    return;
+}
+
+DECLVBGL(int) VbglR0SfQueryMappings(PVBGLSFCLIENT pClient, SHFLMAPPING paMappings[], uint32_t *pcMappings)
+{
+    int rc;
+    VBoxSFQueryMappings data;
+
+    VBOX_INIT_CALL(&data.callInfo, QUERY_MAPPINGS, pClient);
+
+    data.flags.type                      = VMMDevHGCMParmType_32bit;
+    data.flags.u.value32                 = SHFL_MF_UCS2;
+
+    data.numberOfMappings.type           = VMMDevHGCMParmType_32bit;
+    data.numberOfMappings.u.value32      = *pcMappings;
+
+    data.mappings.type                   = VMMDevHGCMParmType_LinAddr;
+    data.mappings.u.Pointer.size         = sizeof(SHFLMAPPING) * *pcMappings;
+    data.mappings.u.Pointer.u.linearAddr = (uintptr_t)&paMappings[0];
+
+/*    Log(("VBOXSF: in ifs difference %d\n", (char *)&data.flags.type - (char *)&data.callInfo.cParms)); */
+    rc = VbglHGCMCall(pClient->handle, &data.callInfo, sizeof(data));
+/*    Log(("VBOXSF: VbglR0SfQueryMappings: VbglHGCMCall rc = %#x, result = %#x\n", rc, data.callInfo.result)); */
+    if (RT_SUCCESS(rc))
+        rc = data.callInfo.result;
+    if (RT_SUCCESS(rc))
+        *pcMappings = data.numberOfMappings.u.value32;
+
+    return rc;
+}
+
+DECLVBGL(int) VbglR0SfQueryMapName(PVBGLSFCLIENT pClient, SHFLROOT root, SHFLSTRING *pString, uint32_t size)
+{
+    int rc;
+    VBoxSFQueryMapName data;
+
+    VBOX_INIT_CALL(&data.callInfo, QUERY_MAP_NAME, pClient);
+
+    data.root.type                   = VMMDevHGCMParmType_32bit;
+    data.root.u.value32              = root;
+
+    data.name.type                   = VMMDevHGCMParmType_LinAddr;
+    data.name.u.Pointer.size         = size;
+    data.name.u.Pointer.u.linearAddr = (uintptr_t)pString;
+
+    rc = VbglHGCMCall(pClient->handle, &data.callInfo, sizeof(data));
+/*    Log(("VBOXSF: VbglR0SfQueryMapName: VbglHGCMCall rc = %#x, result = %#x\n", rc, data.callInfo.result)); */
+    if (RT_SUCCESS(rc))
+        rc = data.callInfo.result;
+
+    return rc;
+}
+
+DECLVBGL(int) VbglR0SfMapFolder(PVBGLSFCLIENT pClient, PSHFLSTRING szFolderName, PVBGLSFMAP pMap)
+{
+    int rc;
+    VBoxSFMapFolder data;
+
+    VBOX_INIT_CALL(&data.callInfo, MAP_FOLDER, pClient);
+
+    data.path.type                    = VMMDevHGCMParmType_LinAddr;
+    data.path.u.Pointer.size          = ShflStringSizeOfBuffer(szFolderName);
+    data.path.u.Pointer.u.linearAddr  = (uintptr_t)szFolderName;
+
+    data.root.type                    = VMMDevHGCMParmType_32bit;
+    data.root.u.value32               = 0;
+
+    data.delimiter.type               = VMMDevHGCMParmType_32bit;
+    data.delimiter.u.value32          = RTPATH_DELIMITER;
+
+    data.fCaseSensitive.type          = VMMDevHGCMParmType_32bit;
+#if defined(RT_OS_WINDOWS) || defined(RT_OS_OS2)
+    data.fCaseSensitive.u.value32     = 0;
+#else
+    data.fCaseSensitive.u.value32     = 1;
+#endif
+
+    rc = VbglHGCMCall(pClient->handle, &data.callInfo, sizeof(data));
+/*    Log(("VBOXSF: VbglR0SfMapFolder: VbglHGCMCall rc = %#x, result = %#x\n", rc, data.callInfo.result)); */
+    if (RT_SUCCESS(rc))
+    {
+        pMap->root = data.root.u.value32;
+        rc         = data.callInfo.result;
+    }
+    else if (rc == VERR_NOT_IMPLEMENTED)
+    {
+        /* try the legacy interface too; temporary to assure backwards compatibility */
+        VBoxSFMapFolder_Old OldData;
+
+        VBOX_INIT_CALL(&OldData.callInfo, MAP_FOLDER_OLD, pClient);
+
+        OldData.path.type                    = VMMDevHGCMParmType_LinAddr;
+        OldData.path.u.Pointer.size          = ShflStringSizeOfBuffer (szFolderName);
+        OldData.path.u.Pointer.u.linearAddr  = (uintptr_t)szFolderName;
+
+        OldData.root.type                    = VMMDevHGCMParmType_32bit;
+        OldData.root.u.value32               = 0;
+
+        OldData.delimiter.type               = VMMDevHGCMParmType_32bit;
+        OldData.delimiter.u.value32          = RTPATH_DELIMITER;
+
+        rc = VbglHGCMCall(pClient->handle, &OldData.callInfo, sizeof(OldData));
+        if (RT_SUCCESS(rc))
+        {
+            pMap->root = OldData.root.u.value32;
+            rc         = OldData.callInfo.result;
+        }
+    }
+    return rc;
+}
+
+DECLVBGL(int) VbglR0SfUnmapFolder(PVBGLSFCLIENT pClient, PVBGLSFMAP pMap)
+{
+    int rc;
+    VBoxSFUnmapFolder data;
+
+    VBOX_INIT_CALL(&data.callInfo, UNMAP_FOLDER, pClient);
+
+    data.root.type                      = VMMDevHGCMParmType_32bit;
+    data.root.u.value32                 = pMap->root;
+
+    rc = VbglHGCMCall(pClient->handle, &data.callInfo, sizeof(data));
+/*    Log(("VBOXSF: VbglR0SfUnmapFolder: VbglHGCMCall rc = %#x, result = %#x\n", rc, data.callInfo.result)); */
+    if (RT_SUCCESS(rc))
+        rc = data.callInfo.result;
+    return rc;
+}
+
+DECLVBGL(int) VbglR0SfCreate(PVBGLSFCLIENT pClient, PVBGLSFMAP pMap, PSHFLSTRING pParsedPath, PSHFLCREATEPARMS pCreateParms)
+{
+    /** @todo copy buffers to physical or mapped memory. */
+    int rc;
+    VBoxSFCreate data;
+
+    VBOX_INIT_CALL(&data.callInfo, CREATE, pClient);
+
+    data.root.type                    = VMMDevHGCMParmType_32bit;
+    data.root.u.value32               = pMap->root;
+
+    data.path.type                    = VMMDevHGCMParmType_LinAddr;
+    data.path.u.Pointer.size          = ShflStringSizeOfBuffer (pParsedPath);
+    data.path.u.Pointer.u.linearAddr  = (uintptr_t)pParsedPath;
+
+    data.parms.type                   = VMMDevHGCMParmType_LinAddr;
+    data.parms.u.Pointer.size         = sizeof(SHFLCREATEPARMS);
+    data.parms.u.Pointer.u.linearAddr = (uintptr_t)pCreateParms;
+
+    rc = VbglHGCMCall(pClient->handle, &data.callInfo, sizeof(data));
+/*    Log(("VBOXSF: VbglR0SfCreate: VbglHGCMCall rc = %#x, result = %#x\n", rc, data.callInfo.result)); */
+    if (RT_SUCCESS(rc))
+        rc = data.callInfo.result;
+    return rc;
+}
+
+DECLVBGL(int) VbglR0SfClose(PVBGLSFCLIENT pClient, PVBGLSFMAP pMap, SHFLHANDLE Handle)
+{
+    int rc;
+    VBoxSFClose data;
+
+    VBOX_INIT_CALL(&data.callInfo, CLOSE, pClient);
+
+    data.root.type                      = VMMDevHGCMParmType_32bit;
+    data.root.u.value32                 = pMap->root;
+
+    data.handle.type                    = VMMDevHGCMParmType_64bit;
+    data.handle.u.value64               = Handle;
+
+    rc = VbglHGCMCall(pClient->handle, &data.callInfo, sizeof(data));
+/*    Log(("VBOXSF: VbglR0SfClose: VbglHGCMCall rc = %#x, result = %#x\n", rc, data.callInfo.result)); */
+    if (RT_SUCCESS(rc))
+        rc = data.callInfo.result;
+    return rc;
+}
+
+DECLVBGL(int) VbglR0SfRemove(PVBGLSFCLIENT pClient, PVBGLSFMAP pMap, PSHFLSTRING pParsedPath, uint32_t flags)
+{
+    int rc = VINF_SUCCESS;
+
+    VBoxSFRemove data;
+
+    VBOX_INIT_CALL(&data.callInfo, REMOVE, pClient);
+
+    data.root.type                      = VMMDevHGCMParmType_32bit;
+    data.root.u.value32                 = pMap->root;
+
+    data.path.type                      = VMMDevHGCMParmType_LinAddr_In;
+    data.path.u.Pointer.size            = ShflStringSizeOfBuffer(pParsedPath);
+    data.path.u.Pointer.u.linearAddr    = (uintptr_t)pParsedPath;
+
+    data.flags.type                     = VMMDevHGCMParmType_32bit;
+    data.flags.u.value32                = flags;
+
+    rc = VbglHGCMCall(pClient->handle, &data.callInfo, sizeof(data));
+/*    Log(("VBOXSF: VbglR0SfRemove: VbglHGCMCall rc = %#x, result = %#x\n", rc, data.callInfo.result)); */
+    if (RT_SUCCESS (rc))
+        rc = data.callInfo.result;
+    return rc;
+}
+
+DECLVBGL(int) VbglR0SfRename(PVBGLSFCLIENT pClient, PVBGLSFMAP pMap, PSHFLSTRING pSrcPath, PSHFLSTRING pDestPath, uint32_t flags)
+{
+    int rc;
+    VBoxSFRename data;
+
+    VBOX_INIT_CALL(&data.callInfo, RENAME, pClient);
+
+    data.root.type                      = VMMDevHGCMParmType_32bit;
+    data.root.u.value32                 = pMap->root;
+
+    data.src.type                       = VMMDevHGCMParmType_LinAddr_In;
+    data.src.u.Pointer.size             = ShflStringSizeOfBuffer(pSrcPath);
+    data.src.u.Pointer.u.linearAddr     = (uintptr_t)pSrcPath;
+
+    data.dest.type                      = VMMDevHGCMParmType_LinAddr_In;
+    data.dest.u.Pointer.size            = ShflStringSizeOfBuffer(pDestPath);
+    data.dest.u.Pointer.u.linearAddr    = (uintptr_t)pDestPath;
+
+    data.flags.type                     = VMMDevHGCMParmType_32bit;
+    data.flags.u.value32                = flags;
+
+    rc = VbglHGCMCall(pClient->handle, &data.callInfo, sizeof(data));
+/*    Log(("VBOXSF: VbglR0SfRename: VbglHGCMCall rc = %#x, result = %#x\n", rc, data.callInfo.result)); */
+    if (RT_SUCCESS (rc))
+        rc = data.callInfo.result;
+    return rc;
+}
+
+DECLVBGL(int) VbglR0SfRead(PVBGLSFCLIENT pClient, PVBGLSFMAP pMap, SHFLHANDLE hFile,
+                           uint64_t offset, uint32_t *pcbBuffer, uint8_t *pBuffer, bool fLocked)
+{
+    int rc;
+    VBoxSFRead data;
+
+    VBOX_INIT_CALL(&data.callInfo, READ, pClient);
+
+    data.root.type                      = VMMDevHGCMParmType_32bit;
+    data.root.u.value32                 = pMap->root;
+
+    data.handle.type                    = VMMDevHGCMParmType_64bit;
+    data.handle.u.value64               = hFile;
+    data.offset.type                    = VMMDevHGCMParmType_64bit;
+    data.offset.u.value64               = offset;
+    data.cb.type                        = VMMDevHGCMParmType_32bit;
+    data.cb.u.value32                   = *pcbBuffer;
+    data.buffer.type                    = (fLocked) ? VMMDevHGCMParmType_LinAddr_Locked_Out : VMMDevHGCMParmType_LinAddr_Out;
+    data.buffer.u.Pointer.size          = *pcbBuffer;
+    data.buffer.u.Pointer.u.linearAddr  = (uintptr_t)pBuffer;
+
+    rc = VbglHGCMCall(pClient->handle, &data.callInfo, sizeof(data));
+/*    Log(("VBOXSF: VbglR0SfRead: VbglHGCMCall rc = %#x, result = %#x\n", rc, data.callInfo.result)); */
+    if (RT_SUCCESS(rc))
+    {
+        rc = data.callInfo.result;
+        *pcbBuffer = data.cb.u.value32;
+    }
+    return rc;
+}
+
+DECLVBGL(int) VbglR0SfReadPageList(PVBGLSFCLIENT pClient, PVBGLSFMAP pMap, SHFLHANDLE hFile, uint64_t offset, uint32_t *pcbBuffer,
+                                   uint16_t offFirstPage, uint16_t cPages, RTGCPHYS64 *paPages)
+{
+    uint32_t            cbToRead  = *pcbBuffer;
+    uint32_t            cbData    = (uint32_t)(sizeof(VBoxSFRead) + RT_UOFFSETOF(HGCMPageListInfo, aPages[cPages]));
+    VBoxSFRead         *pData     = (VBoxSFRead *)RTMemTmpAlloc(cbData);
+    HGCMPageListInfo   *pPgLst    = (HGCMPageListInfo *)(pData + 1);
+    uint16_t            iPage;
+    int                 rc;
+
+    if (RT_UNLIKELY(!pData))
+        return VERR_NO_TMP_MEMORY;
+
+    VBOX_INIT_CALL(&pData->callInfo, READ, pClient);
+
+    pData->root.type                      = VMMDevHGCMParmType_32bit;
+    pData->root.u.value32                 = pMap->root;
+
+    pData->handle.type                    = VMMDevHGCMParmType_64bit;
+    pData->handle.u.value64               = hFile;
+    pData->offset.type                    = VMMDevHGCMParmType_64bit;
+    pData->offset.u.value64               = offset;
+    pData->cb.type                        = VMMDevHGCMParmType_32bit;
+    pData->cb.u.value32                   = cbToRead;
+    pData->buffer.type                    = VMMDevHGCMParmType_PageList;
+    pData->buffer.u.PageList.size         = cbToRead;
+    pData->buffer.u.PageList.offset       = sizeof(VBoxSFRead);
+
+    pPgLst->flags = VBOX_HGCM_F_PARM_DIRECTION_FROM_HOST;
+    pPgLst->offFirstPage = offFirstPage;
+    pPgLst->cPages = cPages;
+    for (iPage = 0; iPage < cPages; iPage++)
+        pPgLst->aPages[iPage] = paPages[iPage];
+
+    rc = VbglHGCMCall(pClient->handle, &pData->callInfo, cbData);
+/*    Log(("VBOXSF: VbglR0SfReadPageList: VbglHGCMCall rc = %#x, result = %#x\n", rc, data.callInfo.result)); */
+    if (RT_SUCCESS(rc))
+    {
+        rc = pData->callInfo.result;
+        *pcbBuffer = pData->cb.u.value32;
+    }
+
+    RTMemTmpFree(pData);
+    return rc;
+}
+
+DECLVBGL(int) VbglR0SfWrite(PVBGLSFCLIENT pClient, PVBGLSFMAP pMap, SHFLHANDLE hFile,
+                            uint64_t offset, uint32_t *pcbBuffer, uint8_t *pBuffer, bool fLocked)
+{
+    int rc;
+    VBoxSFWrite data;
+
+    VBOX_INIT_CALL(&data.callInfo, WRITE, pClient);
+
+    data.root.type                      = VMMDevHGCMParmType_32bit;
+    data.root.u.value32                 = pMap->root;
+
+    data.handle.type                    = VMMDevHGCMParmType_64bit;
+    data.handle.u.value64               = hFile;
+    data.offset.type                    = VMMDevHGCMParmType_64bit;
+    data.offset.u.value64               = offset;
+    data.cb.type                        = VMMDevHGCMParmType_32bit;
+    data.cb.u.value32                   = *pcbBuffer;
+    data.buffer.type                    = fLocked ? VMMDevHGCMParmType_LinAddr_Locked_In : VMMDevHGCMParmType_LinAddr_In;
+    data.buffer.u.Pointer.size          = *pcbBuffer;
+    data.buffer.u.Pointer.u.linearAddr  = (uintptr_t)pBuffer;
+
+    rc = VbglHGCMCall(pClient->handle, &data.callInfo, sizeof(data));
+/*    Log(("VBOXSF: VbglR0SfWrite: VbglHGCMCall rc = %#x, result = %#x\n", rc, data.callInfo.result)); */
+    if (RT_SUCCESS(rc))
+    {
+        rc = data.callInfo.result;
+        *pcbBuffer = data.cb.u.value32;
+    }
+    return rc;
+}
+
+DECLVBGL(int) VbglR0SfWritePhysCont(PVBGLSFCLIENT pClient, PVBGLSFMAP pMap, SHFLHANDLE hFile, uint64_t offset,
+                                    uint32_t *pcbBuffer, RTCCPHYS PhysBuffer)
+{
+    uint32_t            cbToWrite = *pcbBuffer;
+    uint32_t            cPages    = RT_ALIGN_32((PhysBuffer & PAGE_OFFSET_MASK) + cbToWrite, PAGE_SIZE) >> PAGE_SHIFT;
+    uint32_t            cbData    = (uint32_t)(sizeof(VBoxSFWrite) + RT_UOFFSETOF(HGCMPageListInfo, aPages[cPages]));
+    VBoxSFWrite        *pData     = (VBoxSFWrite *)RTMemTmpAlloc(cbData);
+    HGCMPageListInfo   *pPgLst    = (HGCMPageListInfo *)(pData + 1);
+    uint32_t            iPage;
+    int                 rc;
+
+    if (RT_UNLIKELY(!pData))
+        return VERR_NO_TMP_MEMORY;
+
+    VBOX_INIT_CALL(&pData->callInfo, WRITE, pClient);
+
+    pData->root.type                      = VMMDevHGCMParmType_32bit;
+    pData->root.u.value32                 = pMap->root;
+
+    pData->handle.type                    = VMMDevHGCMParmType_64bit;
+    pData->handle.u.value64               = hFile;
+    pData->offset.type                    = VMMDevHGCMParmType_64bit;
+    pData->offset.u.value64               = offset;
+    pData->cb.type                        = VMMDevHGCMParmType_32bit;
+    pData->cb.u.value32                   = cbToWrite;
+    pData->buffer.type                    = VMMDevHGCMParmType_PageList;
+    pData->buffer.u.PageList.size         = cbToWrite;
+    pData->buffer.u.PageList.offset       = sizeof(VBoxSFWrite);
+
+    pPgLst->flags = VBOX_HGCM_F_PARM_DIRECTION_TO_HOST;
+    pPgLst->offFirstPage = (uint16_t)(PhysBuffer & PAGE_OFFSET_MASK);
+    pPgLst->cPages = cPages;
+    PhysBuffer &= ~(RTCCPHYS)PAGE_OFFSET_MASK;
+    for (iPage = 0; iPage < cPages; iPage++, PhysBuffer += PAGE_SIZE)
+        pPgLst->aPages[iPage] = PhysBuffer;
+
+    rc = VbglHGCMCall(pClient->handle, &pData->callInfo, cbData);
+/*    Log(("VBOXSF: VbglR0SfWritePhysCont: VbglHGCMCall rc = %#x, result = %#x\n", rc, data.callInfo.result)); */
+    if (RT_SUCCESS(rc))
+    {
+        rc = pData->callInfo.result;
+        *pcbBuffer = pData->cb.u.value32;
+    }
+
+    RTMemTmpFree(pData);
+    return rc;
+
+}
+
+DECLVBGL(int) VbglR0SfWritePageList(PVBGLSFCLIENT pClient, PVBGLSFMAP pMap, SHFLHANDLE hFile, uint64_t offset, uint32_t *pcbBuffer,
+                                    uint16_t offFirstPage, uint16_t cPages, RTGCPHYS64 *paPages)
+{
+    uint32_t            cbToWrite = *pcbBuffer;
+    uint32_t            cbData    = (uint32_t)(sizeof(VBoxSFWrite) + RT_UOFFSETOF(HGCMPageListInfo, aPages[cPages]));
+    VBoxSFWrite        *pData     = (VBoxSFWrite *)RTMemTmpAlloc(cbData);
+    HGCMPageListInfo   *pPgLst    = (HGCMPageListInfo *)(pData + 1);
+    uint16_t            iPage;
+    int                 rc;
+
+    if (RT_UNLIKELY(!pData))
+        return VERR_NO_TMP_MEMORY;
+
+    VBOX_INIT_CALL(&pData->callInfo, WRITE, pClient);
+
+    pData->root.type                      = VMMDevHGCMParmType_32bit;
+    pData->root.u.value32                 = pMap->root;
+
+    pData->handle.type                    = VMMDevHGCMParmType_64bit;
+    pData->handle.u.value64               = hFile;
+    pData->offset.type                    = VMMDevHGCMParmType_64bit;
+    pData->offset.u.value64               = offset;
+    pData->cb.type                        = VMMDevHGCMParmType_32bit;
+    pData->cb.u.value32                   = cbToWrite;
+    pData->buffer.type                    = VMMDevHGCMParmType_PageList;
+    pData->buffer.u.PageList.size         = cbToWrite;
+    pData->buffer.u.PageList.offset       = sizeof(VBoxSFWrite);
+
+    pPgLst->flags = VBOX_HGCM_F_PARM_DIRECTION_TO_HOST;
+    pPgLst->offFirstPage = offFirstPage;
+    pPgLst->cPages = cPages;
+    for (iPage = 0; iPage < cPages; iPage++)
+        pPgLst->aPages[iPage] = paPages[iPage];
+
+    rc = VbglHGCMCall(pClient->handle, &pData->callInfo, cbData);
+/*    Log(("VBOXSF: VbglR0SfWritePageList: VbglHGCMCall rc = %#x, result = %#x\n", rc, data.callInfo.result)); */
+    if (RT_SUCCESS(rc))
+    {
+        rc = pData->callInfo.result;
+        *pcbBuffer = pData->cb.u.value32;
+    }
+
+    RTMemTmpFree(pData);
+    return rc;
+}
+
+DECLVBGL(int) VbglR0SfFlush(PVBGLSFCLIENT pClient, PVBGLSFMAP pMap, SHFLHANDLE hFile)
+{
+    int rc;
+    VBoxSFFlush data;
+
+    VBOX_INIT_CALL(&data.callInfo, FLUSH, pClient);
+
+    data.root.type                      = VMMDevHGCMParmType_32bit;
+    data.root.u.value32                 = pMap->root;
+
+    data.handle.type                    = VMMDevHGCMParmType_64bit;
+    data.handle.u.value64               = hFile;
+
+    rc = VbglHGCMCall(pClient->handle, &data.callInfo, sizeof(data));
+/*    Log(("VBOXSF: VbglR0SfFlush: VbglHGCMCall rc = %#x, result = %#x\n", rc, data.callInfo.result)); */
+    if (RT_SUCCESS(rc))
+        rc = data.callInfo.result;
+    return rc;
+}
+
+DECLVBGL(int) VbglR0SfDirInfo(
+    PVBGLSFCLIENT pClient,
+    PVBGLSFMAP pMap,
+    SHFLHANDLE hFile,
+    PSHFLSTRING ParsedPath,
+    uint32_t flags,
+    uint32_t index,
+    uint32_t *pcbBuffer,
+    PSHFLDIRINFO pBuffer,
+    uint32_t *pcFiles)
+{
+    int rc;
+    VBoxSFList data;
+
+    VBOX_INIT_CALL(&data.callInfo, LIST, pClient);
+
+    data.root.type                      = VMMDevHGCMParmType_32bit;
+    data.root.u.value32                 = pMap->root;
+
+    data.handle.type                    = VMMDevHGCMParmType_64bit;
+    data.handle.u.value64               = hFile;
+    data.flags.type                     = VMMDevHGCMParmType_32bit;
+    data.flags.u.value32                = flags;
+    data.cb.type                        = VMMDevHGCMParmType_32bit;
+    data.cb.u.value32                   = *pcbBuffer;
+    data.path.type                      = VMMDevHGCMParmType_LinAddr_In;
+    data.path.u.Pointer.size            = ParsedPath ? ShflStringSizeOfBuffer(ParsedPath) : 0;
+    data.path.u.Pointer.u.linearAddr    = (uintptr_t) ParsedPath;
+
+    data.buffer.type                    = VMMDevHGCMParmType_LinAddr_Out;
+    data.buffer.u.Pointer.size          = *pcbBuffer;
+    data.buffer.u.Pointer.u.linearAddr  = (uintptr_t)pBuffer;
+
+    data.resumePoint.type               = VMMDevHGCMParmType_32bit;
+    data.resumePoint.u.value32          = index;
+    data.cFiles.type                    = VMMDevHGCMParmType_32bit;
+    data.cFiles.u.value32               = 0; /* out parameters only */
+
+    rc = VbglHGCMCall(pClient->handle, &data.callInfo, sizeof(data));
+/*    Log(("VBOXSF: VbglR0SfDirInfo: rc = %#x, result = %#x\n", rc, data.callInfo.result)); */
+    if (RT_SUCCESS(rc))
+        rc = data.callInfo.result;
+    *pcbBuffer = data.cb.u.value32;
+    *pcFiles   = data.cFiles.u.value32;
+    return rc;
+}
+
+DECLVBGL(int) VbglR0SfFsInfo(PVBGLSFCLIENT pClient, PVBGLSFMAP pMap, SHFLHANDLE hFile,
+                             uint32_t flags, uint32_t *pcbBuffer, PSHFLDIRINFO pBuffer)
+{
+    int rc;
+    VBoxSFInformation data;
+
+    VBOX_INIT_CALL(&data.callInfo, INFORMATION, pClient);
+
+    data.root.type                      = VMMDevHGCMParmType_32bit;
+    data.root.u.value32                 = pMap->root;
+
+    data.handle.type                    = VMMDevHGCMParmType_64bit;
+    data.handle.u.value64               = hFile;
+    data.flags.type                     = VMMDevHGCMParmType_32bit;
+    data.flags.u.value32                = flags;
+    data.cb.type                        = VMMDevHGCMParmType_32bit;
+    data.cb.u.value32                   = *pcbBuffer;
+    data.info.type                      = VMMDevHGCMParmType_LinAddr;
+    data.info.u.Pointer.size            = *pcbBuffer;
+    data.info.u.Pointer.u.linearAddr    = (uintptr_t)pBuffer;
+
+    rc = VbglHGCMCall(pClient->handle, &data.callInfo, sizeof(data));
+/*    Log(("VBOXSF: VbglR0SfFsInfo: VbglHGCMCall rc = %#x, result = %#x\n", rc, data.callInfo.result)); */
+    if (RT_SUCCESS(rc))
+    {
+        rc = data.callInfo.result;
+        *pcbBuffer = data.cb.u.value32;
+    }
+    return rc;
+}
+
+DECLVBGL(int) VbglR0SfLock(PVBGLSFCLIENT pClient, PVBGLSFMAP pMap, SHFLHANDLE hFile,
+                           uint64_t offset, uint64_t cbSize, uint32_t fLock)
+{
+    int rc;
+    VBoxSFLock data;
+
+    VBOX_INIT_CALL(&data.callInfo, LOCK, pClient);
+
+    data.root.type                      = VMMDevHGCMParmType_32bit;
+    data.root.u.value32                 = pMap->root;
+
+    data.handle.type                    = VMMDevHGCMParmType_64bit;
+    data.handle.u.value64               = hFile;
+    data.offset.type                    = VMMDevHGCMParmType_64bit;
+    data.offset.u.value64               = offset;
+    data.length.type                    = VMMDevHGCMParmType_64bit;
+    data.length.u.value64               = cbSize;
+
+    data.flags.type                     = VMMDevHGCMParmType_32bit;
+    data.flags.u.value32                = fLock;
+
+    rc = VbglHGCMCall(pClient->handle, &data.callInfo, sizeof(data));
+/*    Log(("VBOXSF: VbglR0SfLock: VbglHGCMCall rc = %#x, result = %#x\n", rc, data.callInfo.result)); */
+    if (RT_SUCCESS (rc))
+        rc = data.callInfo.result;
+    return rc;
+}
+
+DECLVBGL(int) VbglR0SfSetUtf8(PVBGLSFCLIENT pClient)
+{
+    int rc;
+    VBoxGuestHGCMCallInfo callInfo;
+
+    VBOX_INIT_CALL(&callInfo, SET_UTF8, pClient);
+    rc = VbglHGCMCall(pClient->handle, &callInfo, sizeof(callInfo));
+/*    Log(("VBOXSF: VbglR0SfSetUtf8: VbglHGCMCall rc = %#x, result = %#x\n", rc, data.callInfo.result)); */
+    if (RT_SUCCESS(rc))
+        rc = callInfo.result;
+    return rc;
+}
+
+DECLVBGL(int) VbglR0SfReadLink(PVBGLSFCLIENT pClient, PVBGLSFMAP pMap, PSHFLSTRING pParsedPath, uint32_t cbBuffer, uint8_t *pBuffer)
+{
+    int rc;
+    VBoxSFReadLink data;
+
+    VBOX_INIT_CALL(&data.callInfo, READLINK, pClient);
+
+    data.root.type                      = VMMDevHGCMParmType_32bit;
+    data.root.u.value32                 = pMap->root;
+
+    data.path.type                      = VMMDevHGCMParmType_LinAddr_In;
+    data.path.u.Pointer.size            = ShflStringSizeOfBuffer (pParsedPath);
+    data.path.u.Pointer.u.linearAddr    = (uintptr_t)pParsedPath;
+
+    data.buffer.type                    = VMMDevHGCMParmType_LinAddr_Out;
+    data.buffer.u.Pointer.size          = cbBuffer;
+    data.buffer.u.Pointer.u.linearAddr  = (uintptr_t)pBuffer;
+
+    rc = VbglHGCMCall(pClient->handle, &data.callInfo, sizeof(data));
+/*    Log(("VBOXSF: VbglR0SfReadLink: VbglHGCMCall rc = %#x, result = %#x\n", rc, data.callInfo.result)); */
+    if (RT_SUCCESS (rc))
+        rc = data.callInfo.result;
+    return rc;
+}
+
+DECLVBGL(int) VbglR0SfSymlink(PVBGLSFCLIENT pClient, PVBGLSFMAP pMap, PSHFLSTRING pNewPath, PSHFLSTRING pOldPath,
+                              PSHFLFSOBJINFO pBuffer)
+{
+    int rc;
+    VBoxSFSymlink data;
+
+    VBOX_INIT_CALL(&data.callInfo, SYMLINK, pClient);
+
+    data.root.type                      = VMMDevHGCMParmType_32bit;
+    data.root.u.value32                 = pMap->root;
+
+    data.newPath.type                   = VMMDevHGCMParmType_LinAddr_In;
+    data.newPath.u.Pointer.size         = ShflStringSizeOfBuffer (pNewPath);
+    data.newPath.u.Pointer.u.linearAddr = (uintptr_t)pNewPath;
+
+    data.oldPath.type                   = VMMDevHGCMParmType_LinAddr_In;
+    data.oldPath.u.Pointer.size         = ShflStringSizeOfBuffer (pOldPath);
+    data.oldPath.u.Pointer.u.linearAddr = (uintptr_t)pOldPath;
+
+    data.info.type                      = VMMDevHGCMParmType_LinAddr_Out;
+    data.info.u.Pointer.size            = sizeof(SHFLFSOBJINFO);
+    data.info.u.Pointer.u.linearAddr    = (uintptr_t)pBuffer;
+
+    rc = VbglHGCMCall(pClient->handle, &data.callInfo, sizeof(data));
+/*    Log(("VBOXSF: VbglR0SfSymlink: VbglHGCMCall rc = %#x, result = %#x\n", rc, data.callInfo.result)); */
+    if (RT_SUCCESS (rc))
+        rc = data.callInfo.result;
+    return rc;
+}
+
+DECLVBGL(int) VbglR0SfSetSymlinks(PVBGLSFCLIENT pClient)
+{
+    int rc;
+    VBoxGuestHGCMCallInfo callInfo;
+
+    VBOX_INIT_CALL(&callInfo, SET_SYMLINKS, pClient);
+    rc = VbglHGCMCall(pClient->handle, &callInfo, sizeof(callInfo));
+/*    Log(("VBOXSF: VbglR0SfSetSymlinks: VbglHGCMCall rc = %#x, result = %#x\n", rc, data.callInfo.result)); */
+    if (RT_SUCCESS(rc))
+        rc = callInfo.result;
+    return rc;
+}
+
+
+#endif /* !VBGL_VBOXGUEST */
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/vboxsf/VMMDev.c
@@ -0,0 +1,43 @@
+/* $Id: VMMDev.cpp $ */
+/** @file
+ * VBoxGuestLibR0 - VMMDev device related functions.
+ */
+
+/*
+ * Copyright (C) 2006-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+#include "VBGLInternal.h"
+
+
+DECLVBGL(int) VbglQueryVMMDevMemory(VMMDevMemory **ppVMMDevMemory)
+{
+    int rc = vbglR0Enter();
+    if (RT_FAILURE(rc))
+        return rc;
+
+    /* If the memory was not found, return an error. */
+    if (!g_vbgldata.pVMMDevMemory)
+        return VERR_NOT_SUPPORTED;
+
+    *ppVMMDevMemory = g_vbgldata.pVMMDevMemory;
+    return rc;
+}
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/vboxsf/VbglR0CanUsePhysPageList.c
@@ -0,0 +1,44 @@
+/* $Id: VbglR0CanUsePhysPageList.cpp $ */
+/** @file
+ * VBoxGuestLibR0 - Physical memory heap.
+ */
+
+/*
+ * Copyright (C) 2006-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+#include "VBGLInternal.h"
+
+
+/**
+ * Checks whether the host supports physical page lists or not.
+ *
+ * @returns true if it does, false if it doesn't.
+ */
+DECLR0VBGL(bool) VbglR0CanUsePhysPageList(void)
+{
+    /* a_fLocked is false, because the actual capability of the host is requested.
+     * See VBGLR0_CAN_USE_PHYS_PAGE_LIST definition.
+     */
+    int rc = vbglR0Enter();
+    return RT_SUCCESS(rc)
+        && VBGLR0_CAN_USE_PHYS_PAGE_LIST(/*a_fLocked =*/ false);
+}
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/vboxsf/dirops.c
@@ -0,0 +1,890 @@
+/** @file
+ *
+ * vboxsf -- VirtualBox Guest Additions for Linux:
+ * Directory inode and file operations
+ */
+
+/*
+ * Copyright (C) 2006-2012 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+#include "vfsmod.h"
+
+/**
+ * Open a directory. Read the complete content into a buffer.
+ *
+ * @param inode     inode
+ * @param file      file
+ * @returns 0 on success, Linux error code otherwise
+ */
+static int sf_dir_open(struct inode *inode, struct file *file)
+{
+    int rc;
+    int err;
+    struct sf_glob_info *sf_g = GET_GLOB_INFO(inode->i_sb);
+    struct sf_dir_info *sf_d;
+    struct sf_inode_info *sf_i = GET_INODE_INFO(inode);
+    SHFLCREATEPARMS params;
+
+    TRACE();
+    BUG_ON(!sf_g);
+    BUG_ON(!sf_i);
+
+    if (file->private_data)
+    {
+        LogFunc(("sf_dir_open() called on already opened directory '%s'\n",
+                sf_i->path->String.utf8));
+        return 0;
+    }
+
+    sf_d = sf_dir_info_alloc();
+    if (!sf_d)
+    {
+        LogRelFunc(("could not allocate directory info for '%s'\n",
+                    sf_i->path->String.utf8));
+        return -ENOMEM;
+    }
+
+    RT_ZERO(params);
+    params.Handle = SHFL_HANDLE_NIL;
+    params.CreateFlags = 0
+                       | SHFL_CF_DIRECTORY
+                       | SHFL_CF_ACT_OPEN_IF_EXISTS
+                       | SHFL_CF_ACT_FAIL_IF_NEW
+                       | SHFL_CF_ACCESS_READ
+                       ;
+
+    LogFunc(("sf_dir_open(): calling VbglR0SfCreate, folder %s, flags %#x\n",
+             sf_i->path->String.utf8, params.CreateFlags));
+    rc = VbglR0SfCreate(&client_handle, &sf_g->map, sf_i->path, &params);
+    if (RT_SUCCESS(rc))
+    {
+        if (params.Result == SHFL_FILE_EXISTS)
+        {
+            err = sf_dir_read_all(sf_g, sf_i, sf_d, params.Handle);
+            if (!err)
+                file->private_data = sf_d;
+        }
+        else
+            err = -ENOENT;
+
+        rc = VbglR0SfClose(&client_handle, &sf_g->map, params.Handle);
+        if (RT_FAILURE(rc))
+            LogFunc(("sf_dir_open(): VbglR0SfClose(%s) after err=%d failed rc=%Rrc\n",
+                     sf_i->path->String.utf8, err, rc));
+    }
+    else
+        err = -EPERM;
+
+    if (err)
+        sf_dir_info_free(sf_d);
+
+    return err;
+}
+
+
+/**
+ * This is called when reference count of [file] goes to zero. Notify
+ * the host that it can free whatever is associated with this directory
+ * and deallocate our own internal buffers
+ *
+ * @param inode     inode
+ * @param file      file
+ * returns 0 on success, Linux error code otherwise
+ */
+static int sf_dir_release(struct inode *inode, struct file *file)
+{
+    TRACE();
+
+    if (file->private_data)
+        sf_dir_info_free(file->private_data);
+
+    return 0;
+}
+
+/**
+ * Translate RTFMODE into DT_xxx (in conjunction to rtDirType())
+ * @param fMode     file mode
+ * returns d_type
+ */
+static int sf_get_d_type(RTFMODE fMode)
+{
+    int d_type;
+    switch (fMode & RTFS_TYPE_MASK)
+    {
+        case RTFS_TYPE_FIFO:      d_type = DT_FIFO;    break;
+        case RTFS_TYPE_DEV_CHAR:  d_type = DT_CHR;     break;
+        case RTFS_TYPE_DIRECTORY: d_type = DT_DIR;     break;
+        case RTFS_TYPE_DEV_BLOCK: d_type = DT_BLK;     break;
+        case RTFS_TYPE_FILE:      d_type = DT_REG;     break;
+        case RTFS_TYPE_SYMLINK:   d_type = DT_LNK;     break;
+        case RTFS_TYPE_SOCKET:    d_type = DT_SOCK;    break;
+        case RTFS_TYPE_WHITEOUT:  d_type = DT_WHT;     break;
+        default:                  d_type = DT_UNKNOWN; break;
+    }
+    return d_type;
+}
+
+/**
+ * Extract element ([dir]->f_pos) from the directory [dir] into [d_name].
+ *
+ * @returns 0 for success, 1 for end reached, Linux error code otherwise.
+ */
+static int sf_getdent(struct file *dir, char d_name[NAME_MAX], int *d_type)
+{
+    loff_t cur;
+    struct sf_glob_info *sf_g;
+    struct sf_dir_info *sf_d;
+    struct sf_inode_info *sf_i;
+    struct inode *inode;
+    struct list_head *pos, *list;
+
+    TRACE();
+
+    inode = GET_F_DENTRY(dir)->d_inode;
+    sf_i = GET_INODE_INFO(inode);
+    sf_g = GET_GLOB_INFO(inode->i_sb);
+    sf_d = dir->private_data;
+
+    BUG_ON(!sf_g);
+    BUG_ON(!sf_d);
+    BUG_ON(!sf_i);
+
+    if (sf_i->force_reread)
+    {
+        int rc;
+        int err;
+        SHFLCREATEPARMS params;
+
+        RT_ZERO(params);
+        params.Handle = SHFL_HANDLE_NIL;
+        params.CreateFlags = 0
+                           | SHFL_CF_DIRECTORY
+                           | SHFL_CF_ACT_OPEN_IF_EXISTS
+                           | SHFL_CF_ACT_FAIL_IF_NEW
+                           | SHFL_CF_ACCESS_READ
+                           ;
+
+        LogFunc(("sf_getdent: calling VbglR0SfCreate, folder %s, flags %#x\n",
+                  sf_i->path->String.utf8, params.CreateFlags));
+        rc = VbglR0SfCreate(&client_handle, &sf_g->map, sf_i->path, &params);
+        if (RT_FAILURE(rc))
+        {
+            LogFunc(("VbglR0SfCreate(%s) failed rc=%Rrc\n",
+                        sf_i->path->String.utf8, rc));
+            return -EPERM;
+        }
+
+        if (params.Result != SHFL_FILE_EXISTS)
+        {
+            LogFunc(("directory %s does not exist\n", sf_i->path->String.utf8));
+            sf_dir_info_free(sf_d);
+            return -ENOENT;
+        }
+
+        sf_dir_info_empty(sf_d);
+        err = sf_dir_read_all(sf_g, sf_i, sf_d, params.Handle);
+        rc = VbglR0SfClose(&client_handle, &sf_g->map, params.Handle);
+        if (RT_FAILURE(rc))
+            LogFunc(("VbglR0SfClose(%s) failed rc=%Rrc\n", sf_i->path->String.utf8, rc));
+        if (err)
+            return err;
+
+        sf_i->force_reread = 0;
+    }
+
+    cur = 0;
+    list = &sf_d->info_list;
+    list_for_each(pos, list)
+    {
+        struct sf_dir_buf *b;
+        SHFLDIRINFO *info;
+        loff_t i;
+
+        b = list_entry(pos, struct sf_dir_buf, head);
+        if (dir->f_pos >= cur + b->cEntries)
+        {
+            cur += b->cEntries;
+            continue;
+        }
+
+        for (i = 0, info = b->buf; i < dir->f_pos - cur; ++i)
+        {
+            size_t size;
+
+            size = offsetof(SHFLDIRINFO, name.String) + info->name.u16Size;
+            info = (SHFLDIRINFO *) ((uintptr_t) info + size);
+        }
+
+        *d_type = sf_get_d_type(info->Info.Attr.fMode);
+
+        return sf_nlscpy(sf_g, d_name, NAME_MAX,
+                         info->name.String.utf8, info->name.u16Length);
+    }
+
+    return 1;
+}
+
+/**
+ * This is called when vfs wants to populate internal buffers with
+ * directory [dir]s contents. [opaque] is an argument to the
+ * [filldir]. [filldir] magically modifies it's argument - [opaque]
+ * and takes following additional arguments (which i in turn get from
+ * the host via sf_getdent):
+ *
+ * name : name of the entry (i must also supply it's length huh?)
+ * type : type of the entry (FILE | DIR | etc) (i ellect to use DT_UNKNOWN)
+ * pos : position/index of the entry
+ * ino : inode number of the entry (i fake those)
+ *
+ * [dir] contains:
+ * f_pos : cursor into the directory listing
+ * private_data : mean of communication with the host side
+ *
+ * Extract elements from the directory listing (incrementing f_pos
+ * along the way) and feed them to [filldir] until:
+ *
+ * a. there are no more entries (i.e. sf_getdent set done to 1)
+ * b. failure to compute fake inode number
+ * c. filldir returns an error (see comment on that)
+ */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0)
+static int sf_dir_iterate(struct file *dir, struct dir_context *ctx)
+#else
+static int sf_dir_read(struct file *dir, void *opaque, filldir_t filldir)
+#endif
+{
+    TRACE();
+    for (;;)
+    {
+        int err;
+        ino_t fake_ino;
+        loff_t sanity;
+        char d_name[NAME_MAX];
+        int d_type = DT_UNKNOWN;
+
+        err = sf_getdent(dir, d_name, &d_type);
+        switch (err)
+        {
+            case 1:
+                return 0;
+
+            case 0:
+                break;
+
+            case -1:
+            default:
+                /* skip erroneous entry and proceed */
+                LogFunc(("sf_getdent error %d\n", err));
+                dir->f_pos += 1;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0)
+                ctx->pos += 1;
+#endif
+                continue;
+        }
+
+        /* d_name now contains a valid entry name */
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0)
+        sanity = ctx->pos + 0xbeef;
+#else
+        sanity = dir->f_pos + 0xbeef;
+#endif
+        fake_ino = sanity;
+        if (sanity - fake_ino)
+        {
+            LogRelFunc(("can not compute ino\n"));
+            return -EINVAL;
+        }
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0)
+        if (!dir_emit(ctx, d_name, strlen(d_name), fake_ino, d_type))
+        {
+            LogFunc(("dir_emit failed\n"));
+            return 0;
+        }
+#else
+        err = filldir(opaque, d_name, strlen(d_name), dir->f_pos, fake_ino, d_type);
+        if (err)
+        {
+            LogFunc(("filldir returned error %d\n", err));
+            /* Rely on the fact that filldir returns error
+               only when it runs out of space in opaque */
+            return 0;
+        }
+#endif
+
+        dir->f_pos += 1;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0)
+        ctx->pos += 1;
+#endif
+    }
+
+    BUG();
+}
+
+struct file_operations sf_dir_fops =
+{
+    .open    = sf_dir_open,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0)
+    .iterate = sf_dir_iterate,
+#else
+    .readdir = sf_dir_read,
+#endif
+    .release = sf_dir_release,
+    .read    = generic_read_dir
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)
+  , .llseek  = generic_file_llseek
+#endif
+};
+
+
+/* iops */
+
+/**
+ * This is called when vfs failed to locate dentry in the cache. The
+ * job of this function is to allocate inode and link it to dentry.
+ * [dentry] contains the name to be looked in the [parent] directory.
+ * Failure to locate the name is not a "hard" error, in this case NULL
+ * inode is added to [dentry] and vfs should proceed trying to create
+ * the entry via other means. NULL(or "positive" pointer) ought to be
+ * returned in case of success and "negative" pointer on error
+ */
+static struct dentry *sf_lookup(struct inode *parent, struct dentry *dentry
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0)
+                                , unsigned int flags
+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)
+                                , struct nameidata *nd
+#endif
+                               )
+{
+    int err;
+    struct sf_inode_info *sf_i, *sf_new_i;
+    struct sf_glob_info *sf_g;
+    SHFLSTRING *path;
+    struct inode *inode;
+    ino_t ino;
+    SHFLFSOBJINFO fsinfo;
+
+    TRACE();
+    sf_g = GET_GLOB_INFO(parent->i_sb);
+    sf_i = GET_INODE_INFO(parent);
+
+    BUG_ON(!sf_g);
+    BUG_ON(!sf_i);
+
+    err = sf_path_from_dentry(__func__, sf_g, sf_i, dentry, &path);
+    if (err)
+        goto fail0;
+
+    err = sf_stat(__func__, sf_g, path, &fsinfo, 1);
+    if (err)
+    {
+        if (err == -ENOENT)
+        {
+            /* -ENOENT: add NULL inode to dentry so it later can be
+               created via call to create/mkdir/open */
+            kfree(path);
+            inode = NULL;
+        }
+        else
+            goto fail1;
+    }
+    else
+    {
+        sf_new_i = kmalloc(sizeof(*sf_new_i), GFP_KERNEL);
+        if (!sf_new_i)
+        {
+            LogRelFunc(("could not allocate memory for new inode info\n"));
+            err = -ENOMEM;
+            goto fail1;
+        }
+        sf_new_i->handle = SHFL_HANDLE_NIL;
+        sf_new_i->force_reread = 0;
+
+        ino = iunique(parent->i_sb, 1);
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 25)
+        inode = iget_locked(parent->i_sb, ino);
+#else
+        inode = iget(parent->i_sb, ino);
+#endif
+        if (!inode)
+        {
+            LogFunc(("iget failed\n"));
+            err = -ENOMEM;          /* XXX: ??? */
+            goto fail2;
+        }
+
+        SET_INODE_INFO(inode, sf_new_i);
+        sf_init_inode(sf_g, inode, &fsinfo);
+        sf_new_i->path = path;
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 25)
+        unlock_new_inode(inode);
+#endif
+    }
+
+    sf_i->force_restat = 0;
+    dentry->d_time = jiffies;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 38)
+    d_set_d_op(dentry, &sf_dentry_ops);
+#else
+    dentry->d_op = &sf_dentry_ops;
+#endif
+    d_add(dentry, inode);
+    return NULL;
+
+fail2:
+    kfree(sf_new_i);
+
+fail1:
+    kfree(path);
+
+fail0:
+    return ERR_PTR(err);
+}
+
+/**
+ * This should allocate memory for sf_inode_info, compute a unique inode
+ * number, get an inode from vfs, initialize inode info, instantiate
+ * dentry.
+ *
+ * @param parent        inode entry of the directory
+ * @param dentry        directory cache entry
+ * @param path          path name
+ * @param info          file information
+ * @param handle        handle
+ * @returns 0 on success, Linux error code otherwise
+ */
+static int sf_instantiate(struct inode *parent, struct dentry *dentry,
+                          SHFLSTRING *path, PSHFLFSOBJINFO info, SHFLHANDLE handle)
+{
+    int err;
+    ino_t ino;
+    struct inode *inode;
+    struct sf_inode_info *sf_new_i;
+    struct sf_glob_info *sf_g = GET_GLOB_INFO(parent->i_sb);
+
+    TRACE();
+    BUG_ON(!sf_g);
+
+    sf_new_i = kmalloc(sizeof(*sf_new_i), GFP_KERNEL);
+    if (!sf_new_i)
+    {
+        LogRelFunc(("could not allocate inode info.\n"));
+        err = -ENOMEM;
+        goto fail0;
+    }
+
+    ino = iunique(parent->i_sb, 1);
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 25)
+    inode = iget_locked(parent->i_sb, ino);
+#else
+    inode = iget(parent->i_sb, ino);
+#endif
+    if (!inode)
+    {
+        LogFunc(("iget failed\n"));
+        err = -ENOMEM;
+        goto fail1;
+    }
+
+    sf_init_inode(sf_g, inode, info);
+    sf_new_i->path = path;
+    SET_INODE_INFO(inode, sf_new_i);
+    sf_new_i->force_restat = 1;
+    sf_new_i->force_reread = 0;
+
+    d_instantiate(dentry, inode);
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 25)
+    unlock_new_inode(inode);
+#endif
+
+    /* Store this handle if we leave the handle open. */
+    sf_new_i->handle = handle;
+    return 0;
+
+fail1:
+    kfree(sf_new_i);
+
+fail0:
+    return err;
+
+}
+
+/**
+ * Create a new regular file / directory.
+ *
+ * @param parent        inode of the directory
+ * @param dentry        directory cache entry
+ * @param mode          file mode
+ * @param fDirectory    true if directory, false otherwise
+ * @returns 0 on success, Linux error code otherwise
+ */
+static int sf_create_aux(struct inode *parent, struct dentry *dentry,
+                         umode_t mode, int fDirectory)
+{
+    int rc, err;
+    SHFLCREATEPARMS params;
+    SHFLSTRING *path;
+    struct sf_inode_info *sf_i = GET_INODE_INFO(parent);
+    struct sf_glob_info *sf_g = GET_GLOB_INFO(parent->i_sb);
+
+    TRACE();
+    BUG_ON(!sf_i);
+    BUG_ON(!sf_g);
+
+    err = sf_path_from_dentry(__func__, sf_g, sf_i, dentry, &path);
+    if (err)
+        goto fail0;
+
+    RT_ZERO(params);
+    params.Handle = SHFL_HANDLE_NIL;
+    params.CreateFlags = 0
+                       | SHFL_CF_ACT_CREATE_IF_NEW
+                       | SHFL_CF_ACT_FAIL_IF_EXISTS
+                       | SHFL_CF_ACCESS_READWRITE
+                       | (fDirectory ? SHFL_CF_DIRECTORY : 0)
+                       ;
+    params.Info.Attr.fMode = 0
+                           | (fDirectory ? RTFS_TYPE_DIRECTORY : RTFS_TYPE_FILE)
+                           | (mode & S_IRWXUGO)
+                           ;
+    params.Info.Attr.enmAdditional = RTFSOBJATTRADD_NOTHING;
+
+    LogFunc(("sf_create_aux: calling VbglR0SfCreate, folder %s, flags %#x\n",
+              path->String.utf8, params.CreateFlags));
+    rc = VbglR0SfCreate(&client_handle, &sf_g->map, path, &params);
+    if (RT_FAILURE(rc))
+    {
+        if (rc == VERR_WRITE_PROTECT)
+        {
+            err = -EROFS;
+            goto fail1;
+        }
+        err = -EPROTO;
+        LogFunc(("(%d): VbglR0SfCreate(%s) failed rc=%Rrc\n",
+                    fDirectory, sf_i->path->String.utf8, rc));
+        goto fail1;
+    }
+
+    if (params.Result != SHFL_FILE_CREATED)
+    {
+        err = -EPERM;
+        LogFunc(("(%d): could not create file %s result=%d\n",
+                    fDirectory, sf_i->path->String.utf8, params.Result));
+        goto fail1;
+    }
+
+    err = sf_instantiate(parent, dentry, path, &params.Info,
+                         fDirectory ? SHFL_HANDLE_NIL : params.Handle);
+    if (err)
+    {
+        LogFunc(("(%d): could not instantiate dentry for %s err=%d\n",
+                    fDirectory, sf_i->path->String.utf8, err));
+        goto fail2;
+    }
+
+    /*
+     * Don't close this handle right now. We assume that the same file is
+     * opened with sf_reg_open() and later closed with sf_reg_close(). Save
+     * the handle in between. Does not apply to directories. True?
+     */
+    if (fDirectory)
+    {
+        rc = VbglR0SfClose(&client_handle, &sf_g->map, params.Handle);
+        if (RT_FAILURE(rc))
+            LogFunc(("(%d): VbglR0SfClose failed rc=%Rrc\n", fDirectory, rc));
+    }
+
+    sf_i->force_restat = 1;
+    return 0;
+
+fail2:
+    rc = VbglR0SfClose(&client_handle, &sf_g->map, params.Handle);
+    if (RT_FAILURE(rc))
+        LogFunc(("(%d): VbglR0SfClose failed rc=%Rrc\n", fDirectory, rc));
+
+fail1:
+    kfree(path);
+
+fail0:
+    return err;
+}
+
+/**
+ * Create a new regular file.
+ *
+ * @param parent        inode of the directory
+ * @param dentry        directory cache entry
+ * @param mode          file mode
+ * @param excl          Possible O_EXCL...
+ * @returns 0 on success, Linux error code otherwise
+ */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0) || defined(DOXYGEN_RUNNING)
+static int sf_create(struct inode *parent, struct dentry *dentry, umode_t mode, bool excl)
+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0)
+static int sf_create(struct inode *parent, struct dentry *dentry, umode_t mode, struct nameidata *nd)
+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)
+static int sf_create(struct inode *parent, struct dentry *dentry, int mode, struct nameidata *nd)
+#else
+static int sf_create(struct inode *parent, struct dentry *dentry, int mode)
+#endif
+{
+    TRACE();
+    return sf_create_aux(parent, dentry, mode, 0);
+}
+
+/**
+ * Create a new directory.
+ *
+ * @param parent        inode of the directory
+ * @param dentry        directory cache entry
+ * @param mode          file mode
+ * @returns 0 on success, Linux error code otherwise
+ */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0)
+static int sf_mkdir(struct inode *parent, struct dentry *dentry, umode_t mode)
+#else
+static int sf_mkdir(struct inode *parent, struct dentry *dentry, int mode)
+#endif
+{
+    TRACE();
+    return sf_create_aux(parent, dentry, mode, 1);
+}
+
+/**
+ * Remove a regular file / directory.
+ *
+ * @param parent        inode of the directory
+ * @param dentry        directory cache entry
+ * @param fDirectory    true if directory, false otherwise
+ * @returns 0 on success, Linux error code otherwise
+ */
+static int sf_unlink_aux(struct inode *parent, struct dentry *dentry, int fDirectory)
+{
+    int rc, err;
+    struct sf_glob_info *sf_g = GET_GLOB_INFO(parent->i_sb);
+    struct sf_inode_info *sf_i = GET_INODE_INFO(parent);
+    SHFLSTRING *path;
+    uint32_t fFlags;
+
+    TRACE();
+    BUG_ON(!sf_g);
+
+    err = sf_path_from_dentry(__func__, sf_g, sf_i, dentry, &path);
+    if (err)
+        goto fail0;
+
+    fFlags = fDirectory ? SHFL_REMOVE_DIR : SHFL_REMOVE_FILE;
+    if (   dentry
+        && dentry->d_inode
+        && ((dentry->d_inode->i_mode & S_IFLNK) == S_IFLNK))
+        fFlags |= SHFL_REMOVE_SYMLINK;
+    rc = VbglR0SfRemove(&client_handle, &sf_g->map, path, fFlags);
+    if (RT_FAILURE(rc))
+    {
+        LogFunc(("(%d): VbglR0SfRemove(%s) failed rc=%Rrc\n", fDirectory, path->String.utf8, rc));
+        err = -RTErrConvertToErrno(rc);
+        goto fail1;
+    }
+
+    /* directory access/change time changed */
+    sf_i->force_restat = 1;
+    /* directory content changed */
+    sf_i->force_reread = 1;
+
+    err = 0;
+
+fail1:
+    kfree(path);
+
+fail0:
+    return err;
+}
+
+/**
+ * Remove a regular file.
+ *
+ * @param parent        inode of the directory
+ * @param dentry        directory cache entry
+ * @returns 0 on success, Linux error code otherwise
+ */
+static int sf_unlink(struct inode *parent, struct dentry *dentry)
+{
+    TRACE();
+    return sf_unlink_aux(parent, dentry, 0);
+}
+
+/**
+ * Remove a directory.
+ *
+ * @param parent        inode of the directory
+ * @param dentry        directory cache entry
+ * @returns 0 on success, Linux error code otherwise
+ */
+static int sf_rmdir(struct inode *parent, struct dentry *dentry)
+{
+    TRACE();
+    return sf_unlink_aux(parent, dentry, 1);
+}
+
+/**
+ * Rename a regular file / directory.
+ *
+ * @param old_parent    inode of the old parent directory
+ * @param old_dentry    old directory cache entry
+ * @param new_parent    inode of the new parent directory
+ * @param new_dentry    new directory cache entry
+ * @returns 0 on success, Linux error code otherwise
+ */
+static int sf_rename(struct inode *old_parent, struct dentry *old_dentry,
+                     struct inode *new_parent, struct dentry *new_dentry)
+{
+    int err = 0, rc = VINF_SUCCESS;
+    struct sf_glob_info *sf_g = GET_GLOB_INFO(old_parent->i_sb);
+
+    TRACE();
+
+    if (sf_g != GET_GLOB_INFO(new_parent->i_sb))
+    {
+        LogFunc(("rename with different roots\n"));
+        err = -EINVAL;
+    }
+    else
+    {
+        struct sf_inode_info *sf_old_i = GET_INODE_INFO(old_parent);
+        struct sf_inode_info *sf_new_i = GET_INODE_INFO(new_parent);
+        /* As we save the relative path inside the inode structure, we need to change
+           this if the rename is successful. */
+        struct sf_inode_info *sf_file_i = GET_INODE_INFO(old_dentry->d_inode);
+        SHFLSTRING *old_path;
+        SHFLSTRING *new_path;
+
+        BUG_ON(!sf_old_i);
+        BUG_ON(!sf_new_i);
+        BUG_ON(!sf_file_i);
+
+        old_path = sf_file_i->path;
+        err = sf_path_from_dentry(__func__, sf_g, sf_new_i,
+                                  new_dentry, &new_path);
+        if (err)
+            LogFunc(("failed to create new path\n"));
+        else
+        {
+            int fDir = ((old_dentry->d_inode->i_mode & S_IFDIR) != 0);
+
+            rc = VbglR0SfRename(&client_handle, &sf_g->map, old_path,
+                                new_path, fDir ? 0 : SHFL_RENAME_FILE | SHFL_RENAME_REPLACE_IF_EXISTS);
+            if (RT_SUCCESS(rc))
+            {
+                kfree(old_path);
+                sf_new_i->force_restat = 1;
+                sf_old_i->force_restat = 1; /* XXX: needed? */
+                /* Set the new relative path in the inode. */
+                sf_file_i->path = new_path;
+            }
+            else
+            {
+                LogFunc(("VbglR0SfRename failed rc=%Rrc\n", rc));
+                err = -RTErrConvertToErrno(rc);
+                kfree(new_path);
+            }
+        }
+    }
+    return err;
+}
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)
+static int sf_symlink(struct inode *parent, struct dentry *dentry, const char *symname)
+{
+    int err;
+    int rc;
+    struct sf_inode_info *sf_i;
+    struct sf_glob_info *sf_g;
+    SHFLSTRING *path, *ssymname;
+    SHFLFSOBJINFO info;
+    int symname_len = strlen(symname) + 1;
+
+    TRACE();
+    sf_g = GET_GLOB_INFO(parent->i_sb);
+    sf_i = GET_INODE_INFO(parent);
+
+    BUG_ON(!sf_g);
+    BUG_ON(!sf_i);
+
+    err = sf_path_from_dentry(__func__, sf_g, sf_i, dentry, &path);
+    if (err)
+        goto fail0;
+
+    ssymname = kmalloc(offsetof(SHFLSTRING, String.utf8) + symname_len, GFP_KERNEL);
+    if (!ssymname)
+    {
+        LogRelFunc(("kmalloc failed, caller=sf_symlink\n"));
+        err = -ENOMEM;
+        goto fail1;
+    }
+
+    ssymname->u16Length = symname_len - 1;
+    ssymname->u16Size = symname_len;
+    memcpy(ssymname->String.utf8, symname, symname_len);
+
+    rc = VbglR0SfSymlink(&client_handle, &sf_g->map, path, ssymname, &info);
+    kfree(ssymname);
+
+    if (RT_FAILURE(rc))
+    {
+        if (rc == VERR_WRITE_PROTECT)
+        {
+            err = -EROFS;
+            goto fail1;
+        }
+        LogFunc(("VbglR0SfSymlink(%s) failed rc=%Rrc\n",
+                    sf_i->path->String.utf8, rc));
+        err = -EPROTO;
+        goto fail1;
+    }
+
+    err = sf_instantiate(parent, dentry, path, &info, SHFL_HANDLE_NIL);
+    if (err)
+    {
+        LogFunc(("could not instantiate dentry for %s err=%d\n",
+                 sf_i->path->String.utf8, err));
+        goto fail1;
+    }
+
+    sf_i->force_restat = 1;
+    return 0;
+
+fail1:
+    kfree(path);
+fail0:
+    return err;
+}
+#endif
+
+struct inode_operations sf_dir_iops =
+{
+    .lookup     = sf_lookup,
+    .create     = sf_create,
+    .mkdir      = sf_mkdir,
+    .rmdir      = sf_rmdir,
+    .unlink     = sf_unlink,
+    .rename     = sf_rename,
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0)
+    .revalidate = sf_inode_revalidate
+#else
+    .getattr    = sf_getattr,
+    .setattr    = sf_setattr,
+    .symlink    = sf_symlink
+#endif
+};
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/vboxsf/divdi3.c
@@ -0,0 +1,70 @@
+/*	$NetBSD: divdi3.c,v 1.8 2005/12/11 12:24:37 christos Exp $	*/
+
+/*-
+ * Copyright (c) 1992, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * This software was developed by the Computer Systems Engineering group
+ * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
+ * contributed to Berkeley.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*#include <sys/cdefs.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+static char sccsid[] = "@(#)divdi3.c	8.1 (Berkeley) 6/4/93";
+#else
+__RCSID("$NetBSD: divdi3.c,v 1.8 2005/12/11 12:24:37 christos Exp $");
+#endif
+#endif*/ /* LIBC_SCCS and not lint */
+
+#include "quad.h"
+
+/*
+ * Divide two signed quads.
+ * ??? if -1/2 should produce -1 on this machine, this code is wrong
+ */
+quad_t
+__divdi3(a, b)
+	quad_t a, b;
+{
+	u_quad_t ua, ub, uq;
+	int neg = 0;
+
+	ua = a;
+	ub = b;
+
+	if (a < 0)
+		ua = -ua, neg ^= 1;
+	if (b < 0)
+		ub = -ub, neg ^= 1;
+
+	uq = __qdivrem(ua, ub, (u_quad_t *)0);
+	if (neg)
+		uq = - uq;
+	return uq;
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/vboxsf/do_Module.symvers
@@ -0,0 +1,33 @@
+#!/bin/sh
+
+#
+# This script is used when building kernel modules from DKMS. I don't
+# know how to solve the problem of inter-module dependencies better.
+#
+# Copyright (C) 2008-2015 Oracle Corporation
+#
+# This file is part of VirtualBox Open Source Edition (OSE), as
+# available from http://www.virtualbox.org. This file is free software;
+# you can redistribute it and/or modify it under the terms of the GNU
+# General Public License (GPL) as published by the Free Software
+# Foundation, in version 2 as it comes in the "COPYING" file of the
+# VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+# hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+#
+
+SYMFILE="/tmp/$1-Module.symvers"
+case "$2" in
+  save)
+    if [ -f "$3" ]; then
+      cp "$3" "$SYMFILE"
+    fi
+    ;;
+  restore)
+    if [ -f "$SYMFILE" ]; then
+      cp "$SYMFILE" "$3"
+    fi
+    ;;
+  *)
+    echo "Usage: <modname> save|restore <location of Module.symvers>"
+    ;;
+esac
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/vboxsf/lnkops.c
@@ -0,0 +1,105 @@
+/** @file
+ *
+ * vboxsf -- VirtualBox Guest Additions for Linux:
+ * Operations for symbolic links.
+ */
+
+/*
+ * Copyright (C) 2010-2011 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+#include "vfsmod.h"
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)
+
+# if LINUX_VERSION_CODE < KERNEL_VERSION(4, 5, 0)
+#  if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0)
+static const char *sf_follow_link(struct dentry *dentry, void **cookie)
+#  else
+static void *sf_follow_link(struct dentry *dentry, struct nameidata *nd)
+#  endif
+{
+    struct inode *inode = dentry->d_inode;
+    struct sf_glob_info *sf_g = GET_GLOB_INFO(inode->i_sb);
+    struct sf_inode_info *sf_i = GET_INODE_INFO(inode);
+    int error = -ENOMEM;
+    char *path = (char*)get_zeroed_page(GFP_KERNEL);
+    int rc;
+
+    if (path)
+    {
+        error = 0;
+        rc = VbglR0SfReadLink(&client_handle, &sf_g->map, sf_i->path, PATH_MAX, path);
+        if (RT_FAILURE(rc))
+        {
+            LogFunc(("VbglR0SfReadLink failed, caller=%s, rc=%Rrc\n", __func__, rc));
+            free_page((unsigned long)path);
+            error = -EPROTO;
+        }
+    }
+#  if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0)
+    return error ? ERR_PTR(error) : (*cookie = path);
+#  else
+    nd_set_link(nd, error ? ERR_PTR(error) : path);
+    return NULL;
+#  endif
+}
+
+#  if LINUX_VERSION_CODE < KERNEL_VERSION(4, 2, 0)
+static void sf_put_link(struct dentry *dentry, struct nameidata *nd, void *cookie)
+{
+    char *page = nd_get_link(nd);
+    if (!IS_ERR(page))
+        free_page((unsigned long)page);
+}
+#  endif
+
+# else /* LINUX_VERSION_CODE >= KERNEL_VERSION(4, 5, 0) */
+static const char *sf_get_link(struct dentry *dentry, struct inode *inode,
+                               struct delayed_call *done)
+{
+    struct sf_glob_info *sf_g = GET_GLOB_INFO(inode->i_sb);
+    struct sf_inode_info *sf_i = GET_INODE_INFO(inode);
+    char *path;
+    int rc;
+
+    if (!dentry)
+        return ERR_PTR(-ECHILD);
+    path = kzalloc(PAGE_SIZE, GFP_KERNEL);
+    if (!path)
+        return ERR_PTR(-ENOMEM);
+    rc = VbglR0SfReadLink(&client_handle, &sf_g->map, sf_i->path, PATH_MAX, path);
+    if (RT_FAILURE(rc))
+    {
+        LogFunc(("VbglR0SfReadLink failed, caller=%s, rc=%Rrc\n", __func__, rc));
+        kfree(path);
+        return ERR_PTR(-EPROTO);
+    }
+    set_delayed_call(done, kfree_link, path);
+    return path;
+}
+# endif /* LINUX_VERSION_CODE < KERNEL_VERSION(4, 5, 0) */
+
+struct inode_operations sf_lnk_iops =
+{
+    .readlink       = generic_readlink,
+# if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 5, 0)
+    .get_link       = sf_get_link
+# elif LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0)
+    .follow_link    = sf_follow_link,
+    .put_link       = free_page_put_link,
+# else
+    .follow_link    = sf_follow_link,
+    .put_link       = sf_put_link
+# endif
+};
+
+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) */
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/vboxsf/moddi3.c
@@ -0,0 +1,70 @@
+/*	$NetBSD: moddi3.c,v 1.8 2005/12/11 12:24:37 christos Exp $	*/
+
+/*-
+ * Copyright (c) 1992, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * This software was developed by the Computer Systems Engineering group
+ * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
+ * contributed to Berkeley.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*#include <sys/cdefs.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+static char sccsid[] = "@(#)moddi3.c	8.1 (Berkeley) 6/4/93";
+#else
+__RCSID("$NetBSD: moddi3.c,v 1.8 2005/12/11 12:24:37 christos Exp $");
+#endif
+#endif*/ /* LIBC_SCCS and not lint */
+
+#include "quad.h"
+
+/*
+ * Return remainder after dividing two signed quads.
+ *
+ * XXX	we assume a % b < 0 iff a < 0, but this is actually machine-dependent.
+ */
+quad_t
+__moddi3(a, b)
+	quad_t a, b;
+{
+	u_quad_t ua, ub, ur;
+	int neg = 0;
+
+	ua = a;
+	ub = b;
+
+	if (a < 0)
+		ua = -ua, neg ^= 1;
+	if (b < 0)
+		ub = -ub;
+	(void)__qdivrem(ua, ub, &ur);
+	if (neg)
+		ur = -ur;
+	return (ur);
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/vboxsf/product-generated.h
@@ -0,0 +1,10 @@
+#ifndef ___product_generated_h___
+#define ___product_generated_h___
+
+#define VBOX_VENDOR "Oracle Corporation"
+#define VBOX_VENDOR_SHORT "Oracle"
+#define VBOX_PRODUCT "Oracle VM VirtualBox"
+#define VBOX_BUILD_PUBLISHER "_Ubuntu"
+#define VBOX_C_YEAR "2016"
+
+#endif
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/vboxsf/qdivrem.c
@@ -0,0 +1,285 @@
+/*	$NetBSD: qdivrem.c,v 1.12 2005/12/11 12:24:37 christos Exp $	*/
+
+/*-
+ * Copyright (c) 1992, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * This software was developed by the Computer Systems Engineering group
+ * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
+ * contributed to Berkeley.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*#include <sys/cdefs.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+static char sccsid[] = "@(#)qdivrem.c	8.1 (Berkeley) 6/4/93";
+#else
+__RCSID("$NetBSD: qdivrem.c,v 1.12 2005/12/11 12:24:37 christos Exp $");
+#endif
+#endif*/ /* LIBC_SCCS and not lint */
+
+/*
+ * Multiprecision divide.  This algorithm is from Knuth vol. 2 (2nd ed),
+ * section 4.3.1, pp. 257--259.
+ */
+
+#include "quad.h"
+
+#define	B	((int)1 << HALF_BITS)	/* digit base */
+
+/* Combine two `digits' to make a single two-digit number. */
+#define	COMBINE(a, b) (((u_int)(a) << HALF_BITS) | (b))
+
+/* select a type for digits in base B: use unsigned short if they fit */
+#if UINT_MAX == 0xffffffffU && USHRT_MAX >= 0xffff
+typedef unsigned short digit;
+#else
+typedef u_int digit;
+#endif
+
+static void shl __P((digit *p, int len, int sh));
+
+/*
+ * __qdivrem(u, v, rem) returns u/v and, optionally, sets *rem to u%v.
+ *
+ * We do this in base 2-sup-HALF_BITS, so that all intermediate products
+ * fit within u_int.  As a consequence, the maximum length dividend and
+ * divisor are 4 `digits' in this base (they are shorter if they have
+ * leading zeros).
+ */
+u_quad_t
+__qdivrem(uq, vq, arq)
+	u_quad_t uq, vq, *arq;
+{
+	union uu tmp;
+	digit *u, *v, *q;
+	digit v1, v2;
+	u_int qhat, rhat, t;
+	int m, n, d, j, i;
+	digit uspace[5], vspace[5], qspace[5];
+
+	/*
+	 * Take care of special cases: divide by zero, and u < v.
+	 */
+	if (vq == 0) {
+		/* divide by zero. */
+		static volatile const unsigned int zero = 0;
+
+		tmp.ul[H] = tmp.ul[L] = 1 / zero;
+		if (arq)
+			*arq = uq;
+		return (tmp.q);
+	}
+	if (uq < vq) {
+		if (arq)
+			*arq = uq;
+		return (0);
+	}
+	u = &uspace[0];
+	v = &vspace[0];
+	q = &qspace[0];
+
+	/*
+	 * Break dividend and divisor into digits in base B, then
+	 * count leading zeros to determine m and n.  When done, we
+	 * will have:
+	 *	u = (u[1]u[2]...u[m+n]) sub B
+	 *	v = (v[1]v[2]...v[n]) sub B
+	 *	v[1] != 0
+	 *	1 < n <= 4 (if n = 1, we use a different division algorithm)
+	 *	m >= 0 (otherwise u < v, which we already checked)
+	 *	m + n = 4
+	 * and thus
+	 *	m = 4 - n <= 2
+	 */
+	tmp.uq = uq;
+	u[0] = 0;
+	u[1] = (digit)HHALF(tmp.ul[H]);
+	u[2] = (digit)LHALF(tmp.ul[H]);
+	u[3] = (digit)HHALF(tmp.ul[L]);
+	u[4] = (digit)LHALF(tmp.ul[L]);
+	tmp.uq = vq;
+	v[1] = (digit)HHALF(tmp.ul[H]);
+	v[2] = (digit)LHALF(tmp.ul[H]);
+	v[3] = (digit)HHALF(tmp.ul[L]);
+	v[4] = (digit)LHALF(tmp.ul[L]);
+	for (n = 4; v[1] == 0; v++) {
+		if (--n == 1) {
+			u_int rbj;	/* r*B+u[j] (not root boy jim) */
+			digit q1, q2, q3, q4;
+
+			/*
+			 * Change of plan, per exercise 16.
+			 *	r = 0;
+			 *	for j = 1..4:
+			 *		q[j] = floor((r*B + u[j]) / v),
+			 *		r = (r*B + u[j]) % v;
+			 * We unroll this completely here.
+			 */
+			t = v[2];	/* nonzero, by definition */
+			q1 = (digit)(u[1] / t);
+			rbj = COMBINE(u[1] % t, u[2]);
+			q2 = (digit)(rbj / t);
+			rbj = COMBINE(rbj % t, u[3]);
+			q3 = (digit)(rbj / t);
+			rbj = COMBINE(rbj % t, u[4]);
+			q4 = (digit)(rbj / t);
+			if (arq)
+				*arq = rbj % t;
+			tmp.ul[H] = COMBINE(q1, q2);
+			tmp.ul[L] = COMBINE(q3, q4);
+			return (tmp.q);
+		}
+	}
+
+	/*
+	 * By adjusting q once we determine m, we can guarantee that
+	 * there is a complete four-digit quotient at &qspace[1] when
+	 * we finally stop.
+	 */
+	for (m = 4 - n; u[1] == 0; u++)
+		m--;
+	for (i = 4 - m; --i >= 0;)
+		q[i] = 0;
+	q += 4 - m;
+
+	/*
+	 * Here we run Program D, translated from MIX to C and acquiring
+	 * a few minor changes.
+	 *
+	 * D1: choose multiplier 1 << d to ensure v[1] >= B/2.
+	 */
+	d = 0;
+	for (t = v[1]; t < B / 2; t <<= 1)
+		d++;
+	if (d > 0) {
+		shl(&u[0], m + n, d);		/* u <<= d */
+		shl(&v[1], n - 1, d);		/* v <<= d */
+	}
+	/*
+	 * D2: j = 0.
+	 */
+	j = 0;
+	v1 = v[1];	/* for D3 -- note that v[1..n] are constant */
+	v2 = v[2];	/* for D3 */
+	do {
+		digit uj0, uj1, uj2;
+
+		/*
+		 * D3: Calculate qhat (\^q, in TeX notation).
+		 * Let qhat = min((u[j]*B + u[j+1])/v[1], B-1), and
+		 * let rhat = (u[j]*B + u[j+1]) mod v[1].
+		 * While rhat < B and v[2]*qhat > rhat*B+u[j+2],
+		 * decrement qhat and increase rhat correspondingly.
+		 * Note that if rhat >= B, v[2]*qhat < rhat*B.
+		 */
+		uj0 = u[j + 0];	/* for D3 only -- note that u[j+...] change */
+		uj1 = u[j + 1];	/* for D3 only */
+		uj2 = u[j + 2];	/* for D3 only */
+		if (uj0 == v1) {
+			qhat = B;
+			rhat = uj1;
+			goto qhat_too_big;
+		} else {
+			u_int nn = COMBINE(uj0, uj1);
+			qhat = nn / v1;
+			rhat = nn % v1;
+		}
+		while (v2 * qhat > COMBINE(rhat, uj2)) {
+	qhat_too_big:
+			qhat--;
+			if ((rhat += v1) >= B)
+				break;
+		}
+		/*
+		 * D4: Multiply and subtract.
+		 * The variable `t' holds any borrows across the loop.
+		 * We split this up so that we do not require v[0] = 0,
+		 * and to eliminate a final special case.
+		 */
+		for (t = 0, i = n; i > 0; i--) {
+			t = u[i + j] - v[i] * qhat - t;
+			u[i + j] = (digit)LHALF(t);
+			t = (B - HHALF(t)) & (B - 1);
+		}
+		t = u[j] - t;
+		u[j] = (digit)LHALF(t);
+		/*
+		 * D5: test remainder.
+		 * There is a borrow if and only if HHALF(t) is nonzero;
+		 * in that (rare) case, qhat was too large (by exactly 1).
+		 * Fix it by adding v[1..n] to u[j..j+n].
+		 */
+		if (HHALF(t)) {
+			qhat--;
+			for (t = 0, i = n; i > 0; i--) { /* D6: add back. */
+				t += u[i + j] + v[i];
+				u[i + j] = (digit)LHALF(t);
+				t = HHALF(t);
+			}
+			u[j] = (digit)LHALF(u[j] + t);
+		}
+		q[j] = (digit)qhat;
+	} while (++j <= m);		/* D7: loop on j. */
+
+	/*
+	 * If caller wants the remainder, we have to calculate it as
+	 * u[m..m+n] >> d (this is at most n digits and thus fits in
+	 * u[m+1..m+n], but we may need more source digits).
+	 */
+	if (arq) {
+		if (d) {
+			for (i = m + n; i > m; --i)
+				u[i] = (digit)(((u_int)u[i] >> d) |
+				    LHALF((u_int)u[i - 1] << (HALF_BITS - d)));
+			u[i] = 0;
+		}
+		tmp.ul[H] = COMBINE(uspace[1], uspace[2]);
+		tmp.ul[L] = COMBINE(uspace[3], uspace[4]);
+		*arq = tmp.q;
+	}
+
+	tmp.ul[H] = COMBINE(qspace[1], qspace[2]);
+	tmp.ul[L] = COMBINE(qspace[3], qspace[4]);
+	return (tmp.q);
+}
+
+/*
+ * Shift p[0]..p[len] left `sh' bits, ignoring any bits that
+ * `fall out' the left (there never will be any such anyway).
+ * We may assume len >= 0.  NOTE THAT THIS WRITES len+1 DIGITS.
+ */
+static void
+shl(digit *p, int len, int sh)
+{
+	int i;
+
+	for (i = 0; i < len; i++)
+		p[i] = (digit)(LHALF((u_int)p[i] << sh) |
+		    ((u_int)p[i + 1] >> (HALF_BITS - sh)));
+	p[i] = (digit)(LHALF((u_int)p[i] << sh));
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/vboxsf/quad.h
@@ -0,0 +1,165 @@
+/*	$NetBSD: quad.h,v 1.17 2005/12/11 12:24:37 christos Exp $	*/
+
+/*-
+ * Copyright (c) 1992, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * This software was developed by the Computer Systems Engineering group
+ * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
+ * contributed to Berkeley.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	@(#)quad.h	8.1 (Berkeley) 6/4/93
+ */
+
+/*
+ * Quad arithmetic.
+ *
+ * This library makes the following assumptions:
+ *
+ *  - The type long long (aka quad_t) exists.
+ *
+ *  - A quad variable is exactly twice as long as `int'.
+ *
+ *  - The machine's arithmetic is two's complement.
+ *
+ * This library can provide 128-bit arithmetic on a machine with 128-bit
+ * quads and 64-bit ints, for instance, or 96-bit arithmetic on machines
+ * with 48-bit ints.
+ */
+
+#if 0 /* iprt */
+#include <sys/types.h>
+#if !defined(_KERNEL) && !defined(_STANDALONE)
+#include <limits.h>
+#else
+#include <machine/limits.h>
+#endif
+#else /* iprt */
+# include <iprt/types.h>
+# include <iprt/nocrt/limits.h>
+# undef __P
+# define __P(a) a
+# undef __GNUC_PREREQ__
+# define __GNUC_PREREQ__(m1,m2) 1
+# if 1 /* ASSUMES: little endian */
+#  define _QUAD_HIGHWORD        1
+#  define _QUAD_LOWWORD         0
+# else
+#  define _QUAD_HIGHWORD        0
+#  define _QUAD_LOWWORD         1
+# endif
+# if !defined(RT_OS_LINUX) || !defined(__KERNEL__) /* (linux/types.h defines u_int) */
+   typedef unsigned int	u_int;
+# endif
+# if !defined(RT_OS_SOLARIS)
+   typedef int64_t quad_t;
+# else
+#  define quad_t int64_t
+# endif
+   typedef uint64_t u_quad_t;
+   typedef quad_t *qaddr_t;
+#endif /* iprt */
+
+/*
+ * Depending on the desired operation, we view a `long long' (aka quad_t) in
+ * one or more of the following formats.
+ */
+union uu {
+	quad_t	q;		/* as a (signed) quad */
+	u_quad_t uq;		/* as an unsigned quad */
+	int	sl[2];		/* as two signed ints */
+	u_int	ul[2];		/* as two unsigned ints */
+};
+
+/*
+ * Define high and low parts of a quad_t.
+ */
+#define	H		_QUAD_HIGHWORD
+#define	L		_QUAD_LOWWORD
+
+/*
+ * Total number of bits in a quad_t and in the pieces that make it up.
+ * These are used for shifting, and also below for halfword extraction
+ * and assembly.
+ */
+#define	QUAD_BITS	(sizeof(quad_t) * CHAR_BIT)
+#define	INT_BITS	(sizeof(int) * CHAR_BIT)
+#define	HALF_BITS	(sizeof(int) * CHAR_BIT / 2)
+
+/*
+ * Extract high and low shortwords from longword, and move low shortword of
+ * longword to upper half of long, i.e., produce the upper longword of
+ * ((quad_t)(x) << (number_of_bits_in_int/2)).  (`x' must actually be u_int.)
+ *
+ * These are used in the multiply code, to split a longword into upper
+ * and lower halves, and to reassemble a product as a quad_t, shifted left
+ * (sizeof(int)*CHAR_BIT/2).
+ */
+#define	HHALF(x)	((u_int)(x) >> HALF_BITS)
+#define	LHALF(x)	((u_int)(x) & (((int)1 << HALF_BITS) - 1))
+#define	LHUP(x)		((u_int)(x) << HALF_BITS)
+
+/*
+ * XXX
+ * Compensate for gcc 1 vs gcc 2.  Gcc 1 defines ?sh?di3's second argument
+ * as u_quad_t, while gcc 2 correctly uses int.  Unfortunately, we still use
+ * both compilers.
+ */
+#if __GNUC_PREREQ__(2, 0) || defined(lint)
+typedef unsigned int	qshift_t;
+#else
+typedef u_quad_t	qshift_t;
+#endif
+
+RT_C_DECLS_BEGIN
+quad_t __adddi3 __P((quad_t, quad_t));
+quad_t __anddi3 __P((quad_t, quad_t));
+quad_t __ashldi3 __P((quad_t, qshift_t));
+quad_t __ashrdi3 __P((quad_t, qshift_t));
+int __cmpdi2 __P((quad_t, quad_t ));
+quad_t __divdi3 __P((quad_t, quad_t));
+quad_t __fixdfdi __P((double));
+quad_t __fixsfdi __P((float));
+u_quad_t __fixunsdfdi __P((double));
+u_quad_t __fixunssfdi __P((float));
+double __floatdidf __P((quad_t));
+float __floatdisf __P((quad_t));
+double __floatunsdidf __P((u_quad_t));
+quad_t __iordi3 __P((quad_t, quad_t));
+quad_t __lshldi3 __P((quad_t, qshift_t));
+quad_t __lshrdi3 __P((quad_t, qshift_t));
+quad_t __moddi3 __P((quad_t, quad_t));
+quad_t __muldi3 __P((quad_t, quad_t));
+quad_t __negdi2 __P((quad_t));
+quad_t __one_cmpldi2 __P((quad_t));
+u_quad_t __qdivrem __P((u_quad_t, u_quad_t, u_quad_t *));
+quad_t __subdi3 __P((quad_t, quad_t));
+int __ucmpdi2 __P((u_quad_t, u_quad_t));
+u_quad_t __udivdi3 __P((u_quad_t, u_quad_t ));
+u_quad_t __umoddi3 __P((u_quad_t, u_quad_t ));
+quad_t __xordi3 __P((quad_t, quad_t));
+RT_C_DECLS_END
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/vboxsf/regops.c
@@ -0,0 +1,738 @@
+/* $Id: regops.c $ */
+/** @file
+ * vboxsf - VBox Linux Shared Folders, Regular file inode and file operations.
+ */
+
+/*
+ * Copyright (C) 2006-2012 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+/*
+ * Limitations: only COW memory mapping is supported
+ */
+
+#include "vfsmod.h"
+
+static void *alloc_bounce_buffer(size_t *tmp_sizep, PRTCCPHYS physp, size_t
+                                 xfer_size, const char *caller)
+{
+    size_t tmp_size;
+    void *tmp;
+
+    /* try for big first. */
+    tmp_size = RT_ALIGN_Z(xfer_size, PAGE_SIZE);
+    if (tmp_size > 16U*_1K)
+        tmp_size = 16U*_1K;
+    tmp = kmalloc(tmp_size, GFP_KERNEL);
+    if (!tmp)
+    {
+        /* fall back on a page sized buffer. */
+        tmp = kmalloc(PAGE_SIZE, GFP_KERNEL);
+        if (!tmp)
+        {
+            LogRel(("%s: could not allocate bounce buffer for xfer_size=%zu %s\n", caller, xfer_size));
+            return NULL;
+        }
+        tmp_size = PAGE_SIZE;
+    }
+
+    *tmp_sizep = tmp_size;
+    *physp = virt_to_phys(tmp);
+    return tmp;
+}
+
+static void free_bounce_buffer(void *tmp)
+{
+    kfree (tmp);
+}
+
+
+/* fops */
+static int sf_reg_read_aux(const char *caller, struct sf_glob_info *sf_g,
+                           struct sf_reg_info *sf_r, void *buf,
+                           uint32_t *nread, uint64_t pos)
+{
+    /** @todo bird: yes, kmap() and kmalloc() input only. Since the buffer is
+     *        contiguous in physical memory (kmalloc or single page), we should
+     *        use a physical address here to speed things up. */
+    int rc = VbglR0SfRead(&client_handle, &sf_g->map, sf_r->handle,
+                          pos, nread, buf, false /* already locked? */);
+    if (RT_FAILURE(rc))
+    {
+        LogFunc(("VbglR0SfRead failed. caller=%s, rc=%Rrc\n", caller, rc));
+        return -EPROTO;
+    }
+    return 0;
+}
+
+static int sf_reg_write_aux(const char *caller, struct sf_glob_info *sf_g,
+                            struct sf_reg_info *sf_r, void *buf,
+                            uint32_t *nwritten, uint64_t pos)
+{
+    /** @todo bird: yes, kmap() and kmalloc() input only. Since the buffer is
+     *        contiguous in physical memory (kmalloc or single page), we should
+     *        use a physical address here to speed things up. */
+    int rc = VbglR0SfWrite(&client_handle, &sf_g->map, sf_r->handle,
+                           pos, nwritten, buf, false /* already locked? */);
+    if (RT_FAILURE(rc))
+    {
+        LogFunc(("VbglR0SfWrite failed. caller=%s, rc=%Rrc\n",
+                    caller, rc));
+        return -EPROTO;
+    }
+    return 0;
+}
+
+/**
+ * Read from a regular file.
+ *
+ * @param file          the file
+ * @param buf           the buffer
+ * @param size          length of the buffer
+ * @param off           offset within the file
+ * @returns the number of read bytes on success, Linux error code otherwise
+ */
+static ssize_t sf_reg_read(struct file *file, char *buf, size_t size, loff_t *off)
+{
+    int err;
+    void *tmp;
+    RTCCPHYS tmp_phys;
+    size_t tmp_size;
+    size_t left = size;
+    ssize_t total_bytes_read = 0;
+    struct inode *inode = GET_F_DENTRY(file)->d_inode;
+    struct sf_glob_info *sf_g = GET_GLOB_INFO(inode->i_sb);
+    struct sf_reg_info *sf_r = file->private_data;
+    loff_t pos = *off;
+
+    TRACE();
+    if (!S_ISREG(inode->i_mode))
+    {
+        LogFunc(("read from non regular file %d\n", inode->i_mode));
+        return -EINVAL;
+    }
+
+    /** XXX Check read permission according to inode->i_mode! */
+
+    if (!size)
+        return 0;
+
+    tmp = alloc_bounce_buffer(&tmp_size, &tmp_phys, size, __PRETTY_FUNCTION__);
+    if (!tmp)
+        return -ENOMEM;
+
+    while (left)
+    {
+        uint32_t to_read, nread;
+
+        to_read = tmp_size;
+        if (to_read > left)
+            to_read = (uint32_t) left;
+
+        nread = to_read;
+
+        err = sf_reg_read_aux(__func__, sf_g, sf_r, tmp, &nread, pos);
+        if (err)
+            goto fail;
+
+        if (copy_to_user(buf, tmp, nread))
+        {
+            err = -EFAULT;
+            goto fail;
+        }
+
+        pos  += nread;
+        left -= nread;
+        buf  += nread;
+        total_bytes_read += nread;
+        if (nread != to_read)
+            break;
+    }
+
+    *off += total_bytes_read;
+    free_bounce_buffer(tmp);
+    return total_bytes_read;
+
+fail:
+    free_bounce_buffer(tmp);
+    return err;
+}
+
+/**
+ * Write to a regular file.
+ *
+ * @param file          the file
+ * @param buf           the buffer
+ * @param size          length of the buffer
+ * @param off           offset within the file
+ * @returns the number of written bytes on success, Linux error code otherwise
+ */
+static ssize_t sf_reg_write(struct file *file, const char *buf, size_t size, loff_t *off)
+{
+    int err;
+    void *tmp;
+    RTCCPHYS tmp_phys;
+    size_t tmp_size;
+    size_t left = size;
+    ssize_t total_bytes_written = 0;
+    struct inode *inode = GET_F_DENTRY(file)->d_inode;
+    struct sf_inode_info *sf_i = GET_INODE_INFO(inode);
+    struct sf_glob_info *sf_g = GET_GLOB_INFO(inode->i_sb);
+    struct sf_reg_info *sf_r = file->private_data;
+    loff_t pos;
+
+    TRACE();
+    BUG_ON(!sf_i);
+    BUG_ON(!sf_g);
+    BUG_ON(!sf_r);
+
+    if (!S_ISREG(inode->i_mode))
+    {
+        LogFunc(("write to non regular file %d\n",  inode->i_mode));
+        return -EINVAL;
+    }
+
+    pos = *off;
+    if (file->f_flags & O_APPEND)
+    {
+        pos = inode->i_size;
+        *off = pos;
+    }
+
+    /** XXX Check write permission according to inode->i_mode! */
+
+    if (!size)
+        return 0;
+
+    tmp = alloc_bounce_buffer(&tmp_size, &tmp_phys, size, __PRETTY_FUNCTION__);
+    if (!tmp)
+        return -ENOMEM;
+
+    while (left)
+    {
+        uint32_t to_write, nwritten;
+
+        to_write = tmp_size;
+        if (to_write > left)
+            to_write = (uint32_t) left;
+
+        nwritten = to_write;
+
+        if (copy_from_user(tmp, buf, to_write))
+        {
+            err = -EFAULT;
+            goto fail;
+        }
+
+#if 1
+        if (VbglR0CanUsePhysPageList())
+        {
+            err = VbglR0SfWritePhysCont(&client_handle, &sf_g->map, sf_r->handle,
+                                        pos, &nwritten, tmp_phys);
+            err = RT_FAILURE(err) ? -EPROTO : 0;
+        }
+        else
+#endif
+            err = sf_reg_write_aux(__func__, sf_g, sf_r, tmp, &nwritten, pos);
+        if (err)
+            goto fail;
+
+        pos  += nwritten;
+        left -= nwritten;
+        buf  += nwritten;
+        total_bytes_written += nwritten;
+        if (nwritten != to_write)
+            break;
+    }
+
+    *off += total_bytes_written;
+    if (*off > inode->i_size)
+        inode->i_size = *off;
+
+    sf_i->force_restat = 1;
+    free_bounce_buffer(tmp);
+    return total_bytes_written;
+
+fail:
+    free_bounce_buffer(tmp);
+    return err;
+}
+
+/**
+ * Open a regular file.
+ *
+ * @param inode         the inode
+ * @param file          the file
+ * @returns 0 on success, Linux error code otherwise
+ */
+static int sf_reg_open(struct inode *inode, struct file *file)
+{
+    int rc, rc_linux = 0;
+    struct sf_glob_info *sf_g = GET_GLOB_INFO(inode->i_sb);
+    struct sf_inode_info *sf_i = GET_INODE_INFO(inode);
+    struct sf_reg_info *sf_r;
+    SHFLCREATEPARMS params;
+
+    TRACE();
+    BUG_ON(!sf_g);
+    BUG_ON(!sf_i);
+
+    LogFunc(("open %s\n", sf_i->path->String.utf8));
+
+    sf_r = kmalloc(sizeof(*sf_r), GFP_KERNEL);
+    if (!sf_r)
+    {
+        LogRelFunc(("could not allocate reg info\n"));
+        return -ENOMEM;
+    }
+
+    /* Already open? */
+    if (sf_i->handle != SHFL_HANDLE_NIL)
+    {
+        /*
+         * This inode was created with sf_create_aux(). Check the CreateFlags:
+         * O_CREAT, O_TRUNC: inherent true (file was just created). Not sure
+         * about the access flags (SHFL_CF_ACCESS_*).
+         */
+        sf_i->force_restat = 1;
+        sf_r->handle = sf_i->handle;
+        sf_i->handle = SHFL_HANDLE_NIL;
+        sf_i->file = file;
+        file->private_data = sf_r;
+        return 0;
+    }
+
+    RT_ZERO(params);
+    params.Handle = SHFL_HANDLE_NIL;
+    /* We check the value of params.Handle afterwards to find out if
+     * the call succeeded or failed, as the API does not seem to cleanly
+     * distinguish error and informational messages.
+     *
+     * Furthermore, we must set params.Handle to SHFL_HANDLE_NIL to
+     * make the shared folders host service use our fMode parameter */
+
+    if (file->f_flags & O_CREAT)
+    {
+        LogFunc(("O_CREAT set\n"));
+        params.CreateFlags |= SHFL_CF_ACT_CREATE_IF_NEW;
+        /* We ignore O_EXCL, as the Linux kernel seems to call create
+           beforehand itself, so O_EXCL should always fail. */
+        if (file->f_flags & O_TRUNC)
+        {
+            LogFunc(("O_TRUNC set\n"));
+            params.CreateFlags |= (  SHFL_CF_ACT_OVERWRITE_IF_EXISTS
+                                   | SHFL_CF_ACCESS_WRITE);
+        }
+        else
+            params.CreateFlags |= SHFL_CF_ACT_OPEN_IF_EXISTS;
+    }
+    else
+    {
+        params.CreateFlags |= SHFL_CF_ACT_FAIL_IF_NEW;
+        if (file->f_flags & O_TRUNC)
+        {
+            LogFunc(("O_TRUNC set\n"));
+            params.CreateFlags |= (  SHFL_CF_ACT_OVERWRITE_IF_EXISTS
+                    | SHFL_CF_ACCESS_WRITE);
+        }
+    }
+
+    if (!(params.CreateFlags & SHFL_CF_ACCESS_READWRITE))
+    {
+        switch (file->f_flags & O_ACCMODE)
+        {
+            case O_RDONLY:
+                params.CreateFlags |= SHFL_CF_ACCESS_READ;
+                break;
+
+            case O_WRONLY:
+                params.CreateFlags |= SHFL_CF_ACCESS_WRITE;
+                break;
+
+            case O_RDWR:
+                params.CreateFlags |= SHFL_CF_ACCESS_READWRITE;
+                break;
+
+            default:
+                BUG ();
+        }
+    }
+
+    if (file->f_flags & O_APPEND)
+    {
+        LogFunc(("O_APPEND set\n"));
+        params.CreateFlags |= SHFL_CF_ACCESS_APPEND;
+    }
+
+    params.Info.Attr.fMode = inode->i_mode;
+    LogFunc(("sf_reg_open: calling VbglR0SfCreate, file %s, flags=%#x, %#x\n",
+              sf_i->path->String.utf8 , file->f_flags, params.CreateFlags));
+    rc = VbglR0SfCreate(&client_handle, &sf_g->map, sf_i->path, &params);
+    if (RT_FAILURE(rc))
+    {
+        LogFunc(("VbglR0SfCreate failed flags=%d,%#x rc=%Rrc\n",
+                  file->f_flags, params.CreateFlags, rc));
+        kfree(sf_r);
+        return -RTErrConvertToErrno(rc);
+    }
+
+    if (SHFL_HANDLE_NIL == params.Handle)
+    {
+        switch (params.Result)
+        {
+            case SHFL_PATH_NOT_FOUND:
+            case SHFL_FILE_NOT_FOUND:
+                rc_linux = -ENOENT;
+                break;
+            case SHFL_FILE_EXISTS:
+                rc_linux = -EEXIST;
+                break;
+            default:
+                break;
+        }
+    }
+
+    sf_i->force_restat = 1;
+    sf_r->handle = params.Handle;
+    sf_i->file = file;
+    file->private_data = sf_r;
+    return rc_linux;
+}
+
+/**
+ * Close a regular file.
+ *
+ * @param inode         the inode
+ * @param file          the file
+ * @returns 0 on success, Linux error code otherwise
+ */
+static int sf_reg_release(struct inode *inode, struct file *file)
+{
+    int rc;
+    struct sf_reg_info *sf_r;
+    struct sf_glob_info *sf_g;
+    struct sf_inode_info *sf_i = GET_INODE_INFO(inode);
+
+    TRACE();
+    sf_g = GET_GLOB_INFO(inode->i_sb);
+    sf_r = file->private_data;
+
+    BUG_ON(!sf_g);
+    BUG_ON(!sf_r);
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 25)
+    /* See the smbfs source (file.c). mmap in particular can cause data to be
+     * written to the file after it is closed, which we can't cope with.  We
+     * copy and paste the body of filemap_write_and_wait() here as it was not
+     * defined before 2.6.6 and not exported until quite a bit later. */
+    /* filemap_write_and_wait(inode->i_mapping); */
+    if (   inode->i_mapping->nrpages
+        && filemap_fdatawrite(inode->i_mapping) != -EIO)
+        filemap_fdatawait(inode->i_mapping);
+#endif
+    rc = VbglR0SfClose(&client_handle, &sf_g->map, sf_r->handle);
+    if (RT_FAILURE(rc))
+        LogFunc(("VbglR0SfClose failed rc=%Rrc\n", rc));
+
+    kfree(sf_r);
+    sf_i->file = NULL;
+    sf_i->handle = SHFL_HANDLE_NIL;
+    file->private_data = NULL;
+    return 0;
+}
+
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 25)
+static int sf_reg_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)
+static struct page *sf_reg_nopage(struct vm_area_struct *vma, unsigned long vaddr, int *type)
+# define SET_TYPE(t) *type = (t)
+#else /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0) */
+static struct page *sf_reg_nopage(struct vm_area_struct *vma, unsigned long vaddr, int unused)
+# define SET_TYPE(t)
+#endif
+{
+    struct page *page;
+    char *buf;
+    loff_t off;
+    uint32_t nread = PAGE_SIZE;
+    int err;
+    struct file *file = vma->vm_file;
+    struct inode *inode = GET_F_DENTRY(file)->d_inode;
+    struct sf_glob_info *sf_g = GET_GLOB_INFO(inode->i_sb);
+    struct sf_reg_info *sf_r = file->private_data;
+
+    TRACE();
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 25)
+    if (vmf->pgoff > vma->vm_end)
+        return VM_FAULT_SIGBUS;
+#else
+    if (vaddr > vma->vm_end)
+    {
+        SET_TYPE(VM_FAULT_SIGBUS);
+        return NOPAGE_SIGBUS;
+    }
+#endif
+
+    /* Don't use GFP_HIGHUSER as long as sf_reg_read_aux() calls VbglR0SfRead()
+     * which works on virtual addresses. On Linux cannot reliably determine the
+     * physical address for high memory, see rtR0MemObjNativeLockKernel(). */
+    page = alloc_page(GFP_USER);
+    if (!page) {
+        LogRelFunc(("failed to allocate page\n"));
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 25)
+        return VM_FAULT_OOM;
+#else
+        SET_TYPE(VM_FAULT_OOM);
+        return NOPAGE_OOM;
+#endif
+    }
+
+    buf = kmap(page);
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 25)
+    off = (vmf->pgoff << PAGE_SHIFT);
+#else
+    off = (vaddr - vma->vm_start) + (vma->vm_pgoff << PAGE_SHIFT);
+#endif
+    err = sf_reg_read_aux(__func__, sf_g, sf_r, buf, &nread, off);
+    if (err)
+    {
+        kunmap(page);
+        put_page(page);
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 25)
+        return VM_FAULT_SIGBUS;
+#else
+        SET_TYPE(VM_FAULT_SIGBUS);
+        return NOPAGE_SIGBUS;
+#endif
+    }
+
+    BUG_ON (nread > PAGE_SIZE);
+    if (!nread)
+    {
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 25)
+        clear_user_page(page_address(page), vmf->pgoff, page);
+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)
+        clear_user_page(page_address(page), vaddr, page);
+#else
+        clear_user_page(page_address(page), vaddr);
+#endif
+    }
+    else
+        memset(buf + nread, 0, PAGE_SIZE - nread);
+
+    flush_dcache_page(page);
+    kunmap(page);
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 25)
+    vmf->page = page;
+    return 0;
+#else
+    SET_TYPE(VM_FAULT_MAJOR);
+    return page;
+#endif
+}
+
+static struct vm_operations_struct sf_vma_ops =
+{
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 25)
+    .fault = sf_reg_fault
+#else
+     .nopage = sf_reg_nopage
+#endif
+};
+
+static int sf_reg_mmap(struct file *file, struct vm_area_struct *vma)
+{
+    TRACE();
+    if (vma->vm_flags & VM_SHARED)
+    {
+        LogFunc(("shared mmapping not available\n"));
+        return -EINVAL;
+    }
+
+    vma->vm_ops = &sf_vma_ops;
+    return 0;
+}
+
+struct file_operations sf_reg_fops =
+{
+    .read        = sf_reg_read,
+    .open        = sf_reg_open,
+    .write       = sf_reg_write,
+    .release     = sf_reg_release,
+    .mmap        = sf_reg_mmap,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)
+# if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 23)
+    .splice_read = generic_file_splice_read,
+# else
+    .sendfile    = generic_file_sendfile,
+# endif
+# if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0)
+    .read_iter   = generic_file_read_iter,
+    .write_iter  = generic_file_write_iter,
+# else
+    .aio_read    = generic_file_aio_read,
+    .aio_write   = generic_file_aio_write,
+# endif
+# if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35)
+    .fsync       = noop_fsync,
+# else
+    .fsync       = simple_sync_file,
+# endif
+    .llseek      = generic_file_llseek,
+#endif
+};
+
+
+struct inode_operations sf_reg_iops =
+{
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0)
+    .revalidate = sf_inode_revalidate
+#else
+    .getattr    = sf_getattr,
+    .setattr    = sf_setattr
+#endif
+};
+
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)
+static int sf_readpage(struct file *file, struct page *page)
+{
+    struct inode *inode = GET_F_DENTRY(file)->d_inode;
+    struct sf_glob_info *sf_g = GET_GLOB_INFO(inode->i_sb);
+    struct sf_reg_info *sf_r = file->private_data;
+    uint32_t nread = PAGE_SIZE;
+    char *buf;
+    loff_t off = ((loff_t)page->index) << PAGE_SHIFT;
+    int ret;
+
+    TRACE();
+
+    buf = kmap(page);
+    ret = sf_reg_read_aux(__func__, sf_g, sf_r, buf, &nread, off);
+    if (ret)
+    {
+        kunmap(page);
+        if (PageLocked(page))
+            unlock_page(page);
+        return ret;
+    }
+    BUG_ON(nread > PAGE_SIZE);
+    memset(&buf[nread], 0, PAGE_SIZE - nread);
+    flush_dcache_page(page);
+    kunmap(page);
+    SetPageUptodate(page);
+    unlock_page(page);
+    return 0;
+}
+
+static int
+sf_writepage(struct page *page, struct writeback_control *wbc)
+{
+    struct address_space *mapping = page->mapping;
+    struct inode *inode = mapping->host;
+    struct sf_glob_info *sf_g = GET_GLOB_INFO(inode->i_sb);
+    struct sf_inode_info *sf_i = GET_INODE_INFO(inode);
+    struct file *file = sf_i->file;
+    struct sf_reg_info *sf_r = file->private_data;
+    char *buf;
+    uint32_t nwritten = PAGE_SIZE;
+    int end_index = inode->i_size >> PAGE_SHIFT;
+    loff_t off = ((loff_t) page->index) << PAGE_SHIFT;
+    int err;
+
+    TRACE();
+
+    if (page->index >= end_index)
+        nwritten = inode->i_size & (PAGE_SIZE-1);
+
+    buf = kmap(page);
+
+    err = sf_reg_write_aux(__func__, sf_g, sf_r, buf, &nwritten, off);
+    if (err < 0)
+    {
+        ClearPageUptodate(page);
+        goto out;
+    }
+
+    if (off > inode->i_size)
+        inode->i_size = off;
+
+    if (PageError(page))
+        ClearPageError(page);
+    err = 0;
+
+out:
+    kunmap(page);
+
+    unlock_page(page);
+    return err;
+}
+
+# if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24)
+int sf_write_begin(struct file *file, struct address_space *mapping, loff_t pos,
+                   unsigned len, unsigned flags, struct page **pagep, void **fsdata)
+{
+    TRACE();
+
+    return simple_write_begin(file, mapping, pos, len, flags, pagep, fsdata);
+}
+
+int sf_write_end(struct file *file, struct address_space *mapping, loff_t pos,
+                 unsigned len, unsigned copied, struct page *page, void *fsdata)
+{
+    struct inode *inode = mapping->host;
+    struct sf_glob_info *sf_g = GET_GLOB_INFO(inode->i_sb);
+    struct sf_reg_info *sf_r = file->private_data;
+    void *buf;
+    unsigned from = pos & (PAGE_SIZE - 1);
+    uint32_t nwritten = len;
+    int err;
+
+    TRACE();
+
+    buf = kmap(page);
+    err = sf_reg_write_aux(__func__, sf_g, sf_r, buf+from, &nwritten, pos);
+    kunmap(page);
+
+    if (!PageUptodate(page) && err == PAGE_SIZE)
+        SetPageUptodate(page);
+
+    if (err >= 0) {
+        pos += nwritten;
+        if (pos > inode->i_size)
+            inode->i_size = pos;
+    }
+
+    unlock_page(page);
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 6, 0)
+    put_page(page);
+#else
+    page_cache_release(page);
+#endif
+
+    return nwritten;
+}
+
+# endif /* KERNEL_VERSION >= 2.6.24 */
+
+struct address_space_operations sf_reg_aops =
+{
+    .readpage      = sf_readpage,
+    .writepage     = sf_writepage,
+# if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24)
+    .write_begin   = sf_write_begin,
+    .write_end     = sf_write_end,
+# else
+    .prepare_write = simple_prepare_write,
+    .commit_write  = simple_commit_write,
+# endif
+};
+#endif
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/vboxsf/udivdi3.c
@@ -0,0 +1,56 @@
+/*	$NetBSD: udivdi3.c,v 1.8 2005/12/11 12:24:37 christos Exp $	*/
+
+/*-
+ * Copyright (c) 1992, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * This software was developed by the Computer Systems Engineering group
+ * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
+ * contributed to Berkeley.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*#include <sys/cdefs.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+static char sccsid[] = "@(#)udivdi3.c	8.1 (Berkeley) 6/4/93";
+#else
+__RCSID("$NetBSD: udivdi3.c,v 1.8 2005/12/11 12:24:37 christos Exp $");
+#endif
+#endif*/ /* LIBC_SCCS and not lint */
+
+#include "quad.h"
+
+/*
+ * Divide two unsigned quads.
+ */
+u_quad_t
+__udivdi3(a, b)
+	u_quad_t a, b;
+{
+
+	return (__qdivrem(a, b, (u_quad_t *)0));
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/vboxsf/umoddi3.c
@@ -0,0 +1,58 @@
+/*	$NetBSD: umoddi3.c,v 1.8 2005/12/11 12:24:37 christos Exp $	*/
+
+/*-
+ * Copyright (c) 1992, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * This software was developed by the Computer Systems Engineering group
+ * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
+ * contributed to Berkeley.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*#include <sys/cdefs.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+static char sccsid[] = "@(#)umoddi3.c	8.1 (Berkeley) 6/4/93";
+#else
+__RCSID("$NetBSD: umoddi3.c,v 1.8 2005/12/11 12:24:37 christos Exp $");
+#endif
+#endif*/ /* LIBC_SCCS and not lint */
+
+#include "quad.h"
+
+/*
+ * Return remainder after dividing two unsigned quads.
+ */
+u_quad_t
+__umoddi3(a, b)
+	u_quad_t a, b;
+{
+	u_quad_t r;
+
+	(void)__qdivrem(a, b, &r);
+	return (r);
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/vboxsf/utils.c
@@ -0,0 +1,900 @@
+/** @file
+ *
+ * vboxsf -- VirtualBox Guest Additions for Linux:
+ * Utility functions.
+ * Mainly conversion from/to VirtualBox/Linux data structures
+ */
+
+/*
+ * Copyright (C) 2006-2012 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+#include "vfsmod.h"
+#include <iprt/asm.h>
+#include <linux/nfs_fs.h>
+#include <linux/vfs.h>
+
+/* #define USE_VMALLOC */
+
+/*
+ * sf_reg_aops and sf_backing_dev_info are just quick implementations to make
+ * sendfile work. For more information have a look at
+ *
+ *   http://us1.samba.org/samba/ftp/cifs-cvs/ols2006-fs-tutorial-smf.odp
+ *
+ * and the sample implementation
+ *
+ *   http://pserver.samba.org/samba/ftp/cifs-cvs/samplefs.tar.gz
+ */
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0)
+static void sf_ftime_from_timespec(time_t *time, RTTIMESPEC *ts)
+{
+    int64_t t = RTTimeSpecGetNano(ts);
+
+    do_div(t, 1000000000);
+    *time = t;
+}
+
+static void sf_timespec_from_ftime(RTTIMESPEC *ts, time_t *time)
+{
+    int64_t t = 1000000000 * *time;
+    RTTimeSpecSetNano(ts, t);
+}
+#else /* >= 2.6.0 */
+static void sf_ftime_from_timespec(struct timespec *tv, RTTIMESPEC *ts)
+{
+    int64_t t = RTTimeSpecGetNano(ts);
+    int64_t nsec;
+
+    nsec = do_div(t, 1000000000);
+    tv->tv_sec = t;
+    tv->tv_nsec = nsec;
+}
+
+static void sf_timespec_from_ftime(RTTIMESPEC *ts, struct timespec *tv)
+{
+    int64_t t = (int64_t)tv->tv_nsec + (int64_t)tv->tv_sec * 1000000000;
+    RTTimeSpecSetNano(ts, t);
+}
+#endif /* >= 2.6.0 */
+
+/* set [inode] attributes based on [info], uid/gid based on [sf_g] */
+void sf_init_inode(struct sf_glob_info *sf_g, struct inode *inode,
+                   PSHFLFSOBJINFO info)
+{
+    PSHFLFSOBJATTR attr;
+    int mode;
+
+    TRACE();
+
+    attr = &info->Attr;
+
+#define mode_set(r) attr->fMode & (RTFS_UNIX_##r) ? (S_##r) : 0;
+    mode  = mode_set(ISUID);
+    mode |= mode_set(ISGID);
+
+    mode |= mode_set(IRUSR);
+    mode |= mode_set(IWUSR);
+    mode |= mode_set(IXUSR);
+
+    mode |= mode_set(IRGRP);
+    mode |= mode_set(IWGRP);
+    mode |= mode_set(IXGRP);
+
+    mode |= mode_set(IROTH);
+    mode |= mode_set(IWOTH);
+    mode |= mode_set(IXOTH);
+
+#undef mode_set
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)
+    inode->i_mapping->a_ops = &sf_reg_aops;
+# if LINUX_VERSION_CODE <= KERNEL_VERSION(3, 19, 0)
+    /* XXX Was this ever necessary? */
+    inode->i_mapping->backing_dev_info = &sf_g->bdi;
+# endif
+#endif
+
+    if (RTFS_IS_DIRECTORY(attr->fMode))
+    {
+        inode->i_mode  = sf_g->dmode != ~0 ? (sf_g->dmode & 0777) : mode;
+        inode->i_mode &= ~sf_g->dmask;
+        inode->i_mode |= S_IFDIR;
+        inode->i_op    = &sf_dir_iops;
+        inode->i_fop   = &sf_dir_fops;
+        /* XXX: this probably should be set to the number of entries
+           in the directory plus two (. ..) */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0)
+        set_nlink(inode, 1);
+#else
+        inode->i_nlink = 1;
+#endif
+    }
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)
+    else if (RTFS_IS_SYMLINK(attr->fMode))
+    {
+        inode->i_mode  = sf_g->fmode != ~0 ? (sf_g->fmode & 0777): mode;
+        inode->i_mode &= ~sf_g->fmask;
+        inode->i_mode |= S_IFLNK;
+        inode->i_op    = &sf_lnk_iops;
+# if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0)
+        set_nlink(inode, 1);
+# else
+        inode->i_nlink = 1;
+# endif
+    }
+#endif
+    else
+    {
+        inode->i_mode  = sf_g->fmode != ~0 ? (sf_g->fmode & 0777): mode;
+        inode->i_mode &= ~sf_g->fmask;
+        inode->i_mode |= S_IFREG;
+        inode->i_op    = &sf_reg_iops;
+        inode->i_fop   = &sf_reg_fops;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0)
+        set_nlink(inode, 1);
+#else
+        inode->i_nlink = 1;
+#endif
+    }
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)
+    inode->i_uid = make_kuid(current_user_ns(), sf_g->uid);
+    inode->i_gid = make_kgid(current_user_ns(), sf_g->gid);
+#else
+    inode->i_uid = sf_g->uid;
+    inode->i_gid = sf_g->gid;
+#endif
+
+    inode->i_size = info->cbObject;
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19) && !defined(KERNEL_FC6)
+    inode->i_blksize = 4096;
+#endif
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 11)
+    inode->i_blkbits = 12;
+#endif
+    /* i_blocks always in units of 512 bytes! */
+    inode->i_blocks = (info->cbAllocated + 511) / 512;
+
+    sf_ftime_from_timespec(&inode->i_atime, &info->AccessTime);
+    sf_ftime_from_timespec(&inode->i_ctime, &info->ChangeTime);
+    sf_ftime_from_timespec(&inode->i_mtime, &info->ModificationTime);
+}
+
+int sf_stat(const char *caller, struct sf_glob_info *sf_g,
+            SHFLSTRING *path, PSHFLFSOBJINFO result, int ok_to_fail)
+{
+    int rc;
+    SHFLCREATEPARMS params;
+    NOREF(caller);
+
+    TRACE();
+
+    RT_ZERO(params);
+    params.Handle = SHFL_HANDLE_NIL;
+    params.CreateFlags = SHFL_CF_LOOKUP | SHFL_CF_ACT_FAIL_IF_NEW;
+    LogFunc(("sf_stat: calling VbglR0SfCreate, file %s, flags %#x\n",
+             path->String.utf8, params.CreateFlags));
+    rc = VbglR0SfCreate(&client_handle, &sf_g->map, path, &params);
+    if (rc == VERR_INVALID_NAME)
+    {
+        /* this can happen for names like 'foo*' on a Windows host */
+        return -ENOENT;
+    }
+    if (RT_FAILURE(rc))
+    {
+        LogFunc(("VbglR0SfCreate(%s) failed.  caller=%s, rc=%Rrc\n",
+                    path->String.utf8, rc, caller));
+        return -EPROTO;
+    }
+    if (params.Result != SHFL_FILE_EXISTS)
+    {
+        if (!ok_to_fail)
+            LogFunc(("VbglR0SfCreate(%s) file does not exist.  caller=%s, result=%d\n",
+                        path->String.utf8, params.Result, caller));
+        return -ENOENT;
+    }
+
+    *result = params.Info;
+    return 0;
+}
+
+/* this is called directly as iop on 2.4, indirectly as dop
+   [sf_dentry_revalidate] on 2.4/2.6, indirectly as iop through
+   [sf_getattr] on 2.6. the job is to find out whether dentry/inode is
+   still valid. the test is failed if [dentry] does not have an inode
+   or [sf_stat] is unsuccessful, otherwise we return success and
+   update inode attributes */
+int sf_inode_revalidate(struct dentry *dentry)
+{
+    int err;
+    struct sf_glob_info *sf_g;
+    struct sf_inode_info *sf_i;
+    SHFLFSOBJINFO info;
+
+    TRACE();
+    if (!dentry || !dentry->d_inode)
+    {
+        LogFunc(("no dentry(%p) or inode(%p)\n", dentry, dentry->d_inode));
+        return -EINVAL;
+    }
+
+    sf_g = GET_GLOB_INFO(dentry->d_inode->i_sb);
+    sf_i = GET_INODE_INFO(dentry->d_inode);
+
+#if 0
+    printk("%s called by %p:%p\n",
+            sf_i->path->String.utf8,
+            __builtin_return_address (0),
+            __builtin_return_address (1));
+#endif
+
+    BUG_ON(!sf_g);
+    BUG_ON(!sf_i);
+
+    if (!sf_i->force_restat)
+    {
+        if (jiffies - dentry->d_time < sf_g->ttl)
+            return 0;
+    }
+
+    err = sf_stat(__func__, sf_g, sf_i->path, &info, 1);
+    if (err)
+        return err;
+
+    dentry->d_time = jiffies;
+    sf_init_inode(sf_g, dentry->d_inode, &info);
+    return 0;
+}
+
+/* this is called during name resolution/lookup to check if the
+   [dentry] in the cache is still valid. the job is handled by
+   [sf_inode_revalidate] */
+static int
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0)
+sf_dentry_revalidate(struct dentry *dentry, unsigned flags)
+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)
+sf_dentry_revalidate(struct dentry *dentry, struct nameidata *nd)
+#else
+sf_dentry_revalidate(struct dentry *dentry, int flags)
+#endif
+{
+    TRACE();
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0)
+    if (flags & LOOKUP_RCU)
+        return -ECHILD;
+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 38)
+    /* see Documentation/filesystems/vfs.txt */
+    if (nd && nd->flags & LOOKUP_RCU)
+        return -ECHILD;
+#endif
+
+    if (sf_inode_revalidate(dentry))
+        return 0;
+
+    return 1;
+}
+
+/* on 2.6 this is a proxy for [sf_inode_revalidate] which (as a side
+   effect) updates inode attributes for [dentry] (given that [dentry]
+   has inode at all) from these new attributes we derive [kstat] via
+   [generic_fillattr] */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)
+int sf_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *kstat)
+{
+    int err;
+
+    TRACE();
+    err = sf_inode_revalidate(dentry);
+    if (err)
+        return err;
+
+    generic_fillattr(dentry->d_inode, kstat);
+    return 0;
+}
+
+int sf_setattr(struct dentry *dentry, struct iattr *iattr)
+{
+    struct sf_glob_info *sf_g;
+    struct sf_inode_info *sf_i;
+    SHFLCREATEPARMS params;
+    SHFLFSOBJINFO info;
+    uint32_t cbBuffer;
+    int rc, err;
+
+    TRACE();
+
+    sf_g = GET_GLOB_INFO(dentry->d_inode->i_sb);
+    sf_i = GET_INODE_INFO(dentry->d_inode);
+    err  = 0;
+
+    RT_ZERO(params);
+    params.Handle = SHFL_HANDLE_NIL;
+    params.CreateFlags = SHFL_CF_ACT_OPEN_IF_EXISTS
+                       | SHFL_CF_ACT_FAIL_IF_NEW
+                       | SHFL_CF_ACCESS_ATTR_WRITE;
+
+    /* this is at least required for Posix hosts */
+    if (iattr->ia_valid & ATTR_SIZE)
+        params.CreateFlags |= SHFL_CF_ACCESS_WRITE;
+
+    rc = VbglR0SfCreate(&client_handle, &sf_g->map, sf_i->path, &params);
+    if (RT_FAILURE(rc))
+    {
+        LogFunc(("VbglR0SfCreate(%s) failed rc=%Rrc\n",
+                 sf_i->path->String.utf8, rc));
+        err = -RTErrConvertToErrno(rc);
+        goto fail2;
+    }
+    if (params.Result != SHFL_FILE_EXISTS)
+    {
+        LogFunc(("file %s does not exist\n", sf_i->path->String.utf8));
+        err = -ENOENT;
+        goto fail1;
+    }
+
+    /* Setting the file size and setting the other attributes has to be
+     * handled separately, see implementation of vbsfSetFSInfo() in
+     * vbsf.cpp */
+    if (iattr->ia_valid & (ATTR_MODE | ATTR_ATIME | ATTR_MTIME))
+    {
+#define mode_set(r) ((iattr->ia_mode & (S_##r)) ? RTFS_UNIX_##r : 0)
+
+        RT_ZERO(info);
+        if (iattr->ia_valid & ATTR_MODE)
+        {
+            info.Attr.fMode  = mode_set(ISUID);
+            info.Attr.fMode |= mode_set(ISGID);
+            info.Attr.fMode |= mode_set(IRUSR);
+            info.Attr.fMode |= mode_set(IWUSR);
+            info.Attr.fMode |= mode_set(IXUSR);
+            info.Attr.fMode |= mode_set(IRGRP);
+            info.Attr.fMode |= mode_set(IWGRP);
+            info.Attr.fMode |= mode_set(IXGRP);
+            info.Attr.fMode |= mode_set(IROTH);
+            info.Attr.fMode |= mode_set(IWOTH);
+            info.Attr.fMode |= mode_set(IXOTH);
+
+            if (iattr->ia_mode & S_IFDIR)
+                info.Attr.fMode |= RTFS_TYPE_DIRECTORY;
+            else
+                info.Attr.fMode |= RTFS_TYPE_FILE;
+        }
+
+        if (iattr->ia_valid & ATTR_ATIME)
+            sf_timespec_from_ftime(&info.AccessTime, &iattr->ia_atime);
+        if (iattr->ia_valid & ATTR_MTIME)
+            sf_timespec_from_ftime(&info.ModificationTime, &iattr->ia_mtime);
+        /* ignore ctime (inode change time) as it can't be set from userland anyway */
+
+        cbBuffer = sizeof(info);
+        rc = VbglR0SfFsInfo(&client_handle, &sf_g->map, params.Handle,
+                            SHFL_INFO_SET | SHFL_INFO_FILE, &cbBuffer,
+                            (PSHFLDIRINFO)&info);
+        if (RT_FAILURE(rc))
+        {
+            LogFunc(("VbglR0SfFsInfo(%s, FILE) failed rc=%Rrc\n",
+                        sf_i->path->String.utf8, rc));
+            err = -RTErrConvertToErrno(rc);
+            goto fail1;
+        }
+    }
+
+    if (iattr->ia_valid & ATTR_SIZE)
+    {
+        RT_ZERO(info);
+        info.cbObject = iattr->ia_size;
+        cbBuffer = sizeof(info);
+        rc = VbglR0SfFsInfo(&client_handle, &sf_g->map, params.Handle,
+                            SHFL_INFO_SET | SHFL_INFO_SIZE, &cbBuffer,
+                            (PSHFLDIRINFO)&info);
+        if (RT_FAILURE(rc))
+        {
+            LogFunc(("VbglR0SfFsInfo(%s, SIZE) failed rc=%Rrc\n",
+                        sf_i->path->String.utf8, rc));
+            err = -RTErrConvertToErrno(rc);
+            goto fail1;
+        }
+    }
+
+    rc = VbglR0SfClose(&client_handle, &sf_g->map, params.Handle);
+    if (RT_FAILURE(rc))
+        LogFunc(("VbglR0SfClose(%s) failed rc=%Rrc\n", sf_i->path->String.utf8, rc));
+
+    return sf_inode_revalidate(dentry);
+
+fail1:
+    rc = VbglR0SfClose(&client_handle, &sf_g->map, params.Handle);
+    if (RT_FAILURE(rc))
+        LogFunc(("VbglR0SfClose(%s) failed rc=%Rrc\n", sf_i->path->String.utf8, rc));
+
+fail2:
+    return err;
+}
+#endif /* >= 2.6.0 */
+
+static int sf_make_path(const char *caller, struct sf_inode_info *sf_i,
+                        const char *d_name, size_t d_len, SHFLSTRING **result)
+{
+    size_t path_len, shflstring_len;
+    SHFLSTRING *tmp;
+    uint16_t p_len;
+    uint8_t *p_name;
+    int fRoot = 0;
+
+    TRACE();
+    p_len = sf_i->path->u16Length;
+    p_name = sf_i->path->String.utf8;
+
+    if (p_len == 1 && *p_name == '/')
+    {
+        path_len = d_len + 1;
+        fRoot = 1;
+    }
+    else
+    {
+        /* lengths of constituents plus terminating zero plus slash  */
+        path_len = p_len + d_len + 2;
+        if (path_len > 0xffff)
+        {
+            LogFunc(("path too long.  caller=%s, path_len=%zu\n", caller, path_len));
+            return -ENAMETOOLONG;
+        }
+    }
+
+    shflstring_len = offsetof(SHFLSTRING, String.utf8) + path_len;
+    tmp = kmalloc(shflstring_len, GFP_KERNEL);
+    if (!tmp)
+    {
+        LogRelFunc(("kmalloc failed, caller=%s\n", caller));
+        return -ENOMEM;
+    }
+    tmp->u16Length = path_len - 1;
+    tmp->u16Size = path_len;
+
+    if (fRoot)
+        memcpy(&tmp->String.utf8[0], d_name, d_len + 1);
+    else
+    {
+        memcpy(&tmp->String.utf8[0], p_name, p_len);
+        tmp->String.utf8[p_len] = '/';
+        memcpy(&tmp->String.utf8[p_len + 1], d_name, d_len);
+        tmp->String.utf8[p_len + 1 + d_len] = '\0';
+    }
+
+    *result = tmp;
+    return 0;
+}
+
+/**
+ * [dentry] contains string encoded in coding system that corresponds
+ * to [sf_g]->nls, we must convert it to UTF8 here and pass down to
+ * [sf_make_path] which will allocate SHFLSTRING and fill it in
+ */
+int sf_path_from_dentry(const char *caller, struct sf_glob_info *sf_g,
+                        struct sf_inode_info *sf_i, struct dentry *dentry,
+                        SHFLSTRING **result)
+{
+    int err;
+    const char *d_name;
+    size_t d_len;
+    const char *name;
+    size_t len = 0;
+
+    TRACE();
+    d_name = dentry->d_name.name;
+    d_len = dentry->d_name.len;
+
+    if (sf_g->nls)
+    {
+        size_t in_len, i, out_bound_len;
+        const char *in;
+        char *out;
+
+        in = d_name;
+        in_len = d_len;
+
+        out_bound_len = PATH_MAX;
+        out = kmalloc(out_bound_len, GFP_KERNEL);
+        name = out;
+
+        for (i = 0; i < d_len; ++i)
+        {
+            /* We renamed the linux kernel wchar_t type to linux_wchar_t in
+               the-linux-kernel.h, as it conflicts with the C++ type of that name. */
+            linux_wchar_t uni;
+            int nb;
+
+            nb = sf_g->nls->char2uni(in, in_len, &uni);
+            if (nb < 0)
+            {
+                LogFunc(("nls->char2uni failed %x %d\n",
+                            *in, in_len));
+                err = -EINVAL;
+                goto fail1;
+            }
+            in_len -= nb;
+            in += nb;
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 31)
+            nb = utf32_to_utf8(uni, out, out_bound_len);
+#else
+            nb = utf8_wctomb(out, uni, out_bound_len);
+#endif
+            if (nb < 0)
+            {
+                LogFunc(("nls->uni2char failed %x %d\n",
+                            uni, out_bound_len));
+                err = -EINVAL;
+                goto fail1;
+            }
+            out_bound_len -= nb;
+            out += nb;
+            len += nb;
+        }
+        if (len >= PATH_MAX - 1)
+        {
+            err = -ENAMETOOLONG;
+            goto fail1;
+        }
+
+        LogFunc(("result(%d) = %.*s\n", len, len, name));
+        *out = 0;
+    }
+    else
+    {
+        name = d_name;
+        len = d_len;
+    }
+
+    err = sf_make_path(caller, sf_i, name, len, result);
+    if (name != d_name)
+        kfree(name);
+
+    return err;
+
+fail1:
+    kfree(name);
+    return err;
+}
+
+int sf_nlscpy(struct sf_glob_info *sf_g,
+              char *name, size_t name_bound_len,
+              const unsigned char *utf8_name, size_t utf8_len)
+{
+    if (sf_g->nls)
+    {
+        const char *in;
+        char *out;
+        size_t out_len;
+        size_t out_bound_len;
+        size_t in_bound_len;
+
+        in = utf8_name;
+        in_bound_len = utf8_len;
+
+        out = name;
+        out_len = 0;
+        out_bound_len = name_bound_len;
+
+        while (in_bound_len)
+        {
+            int nb;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 31)
+            unicode_t uni;
+
+            nb = utf8_to_utf32(in, in_bound_len, &uni);
+#else
+            linux_wchar_t uni;
+
+            nb = utf8_mbtowc(&uni, in, in_bound_len);
+#endif
+            if (nb < 0)
+            {
+                LogFunc(("utf8_mbtowc failed(%s) %x:%d\n",
+                            (const char *) utf8_name, *in, in_bound_len));
+                return -EINVAL;
+            }
+            in += nb;
+            in_bound_len -= nb;
+
+            nb = sf_g->nls->uni2char(uni, out, out_bound_len);
+            if (nb < 0)
+            {
+                LogFunc(("nls->uni2char failed(%s) %x:%d\n",
+                            utf8_name, uni, out_bound_len));
+                return nb;
+            }
+            out += nb;
+            out_bound_len -= nb;
+            out_len += nb;
+        }
+
+        *out = 0;
+    }
+    else
+    {
+        if (utf8_len + 1 > name_bound_len)
+            return -ENAMETOOLONG;
+
+        memcpy(name, utf8_name, utf8_len + 1);
+    }
+    return 0;
+}
+
+static struct sf_dir_buf *sf_dir_buf_alloc(void)
+{
+    struct sf_dir_buf *b;
+
+    TRACE();
+    b = kmalloc(sizeof(*b), GFP_KERNEL);
+    if (!b)
+    {
+        LogRelFunc(("could not alloc directory buffer\n"));
+        return NULL;
+    }
+
+#ifdef USE_VMALLOC
+    b->buf = vmalloc(DIR_BUFFER_SIZE);
+#else
+    b->buf = kmalloc(DIR_BUFFER_SIZE, GFP_KERNEL);
+#endif
+    if (!b->buf)
+    {
+        kfree(b);
+        LogRelFunc(("could not alloc directory buffer storage\n"));
+        return NULL;
+    }
+
+    INIT_LIST_HEAD(&b->head);
+    b->cEntries = 0;
+    b->cbUsed   = 0;
+    b->cbFree   = DIR_BUFFER_SIZE;
+    return b;
+}
+
+static void sf_dir_buf_free(struct sf_dir_buf *b)
+{
+    BUG_ON(!b || !b->buf);
+
+    TRACE();
+    list_del(&b->head);
+#ifdef USE_VMALLOC
+    vfree(b->buf);
+#else
+    kfree(b->buf);
+#endif
+    kfree(b);
+}
+
+/**
+ * Free the directory buffer.
+ */
+void sf_dir_info_free(struct sf_dir_info *p)
+{
+    struct list_head *list, *pos, *tmp;
+
+    TRACE();
+    list = &p->info_list;
+    list_for_each_safe(pos, tmp, list)
+    {
+        struct sf_dir_buf *b;
+
+        b = list_entry(pos, struct sf_dir_buf, head);
+        sf_dir_buf_free(b);
+    }
+    kfree(p);
+}
+
+/**
+ * Empty (but not free) the directory buffer.
+ */
+void sf_dir_info_empty(struct sf_dir_info *p)
+{
+    struct list_head *list, *pos, *tmp;
+    TRACE();
+    list = &p->info_list;
+    list_for_each_safe(pos, tmp, list)
+    {
+        struct sf_dir_buf *b;
+        b = list_entry(pos, struct sf_dir_buf, head);
+        b->cEntries = 0;
+        b->cbUsed   = 0;
+        b->cbFree = DIR_BUFFER_SIZE;
+    }
+}
+
+/**
+ * Create a new directory buffer descriptor.
+ */
+struct sf_dir_info *sf_dir_info_alloc(void)
+{
+    struct sf_dir_info *p;
+
+    TRACE();
+    p = kmalloc(sizeof(*p), GFP_KERNEL);
+    if (!p)
+    {
+        LogRelFunc(("could not alloc directory info\n"));
+        return NULL;
+    }
+
+    INIT_LIST_HEAD(&p->info_list);
+    return p;
+}
+
+/**
+ * Search for an empty directory content buffer.
+ */
+static struct sf_dir_buf *sf_get_empty_dir_buf(struct sf_dir_info *sf_d)
+{
+    struct list_head *list, *pos;
+
+    list = &sf_d->info_list;
+    list_for_each(pos, list)
+    {
+        struct sf_dir_buf *b;
+
+        b = list_entry(pos, struct sf_dir_buf, head);
+        if (!b)
+            return NULL;
+        else
+        {
+            if (b->cbUsed == 0)
+                return b;
+        }
+    }
+
+    return NULL;
+}
+
+int sf_dir_read_all(struct sf_glob_info *sf_g, struct sf_inode_info *sf_i,
+                    struct sf_dir_info *sf_d, SHFLHANDLE handle)
+{
+    int err;
+    SHFLSTRING *mask;
+    struct sf_dir_buf *b;
+
+    TRACE();
+    err = sf_make_path(__func__, sf_i, "*", 1, &mask);
+    if (err)
+        goto fail0;
+
+    for (;;)
+    {
+        int rc;
+        void *buf;
+        uint32_t cbSize;
+        uint32_t cEntries;
+
+        b = sf_get_empty_dir_buf(sf_d);
+        if (!b)
+        {
+            b = sf_dir_buf_alloc();
+            if (!b)
+            {
+                err = -ENOMEM;
+                LogRelFunc(("could not alloc directory buffer\n"));
+                goto fail1;
+            }
+            list_add(&b->head, &sf_d->info_list);
+        }
+
+        buf = b->buf;
+        cbSize = b->cbFree;
+
+        rc = VbglR0SfDirInfo(&client_handle, &sf_g->map, handle, mask,
+                             0, 0, &cbSize, buf, &cEntries);
+        switch (rc)
+        {
+            case VINF_SUCCESS:
+                /* fallthrough */
+            case VERR_NO_MORE_FILES:
+                break;
+            case VERR_NO_TRANSLATION:
+                LogFunc(("host could not translate entry\n"));
+                /* XXX */
+                break;
+            default:
+                err = -RTErrConvertToErrno(rc);
+                LogFunc(("VbglR0SfDirInfo failed rc=%Rrc\n", rc));
+                goto fail1;
+        }
+
+        b->cEntries += cEntries;
+        b->cbFree   -= cbSize;
+        b->cbUsed   += cbSize;
+
+        if (RT_FAILURE(rc))
+            break;
+    }
+    err = 0;
+
+fail1:
+    kfree(mask);
+
+fail0:
+    return err;
+}
+
+int sf_get_volume_info(struct super_block *sb, STRUCT_STATFS *stat)
+{
+    struct sf_glob_info *sf_g;
+    SHFLVOLINFO SHFLVolumeInfo;
+    uint32_t cbBuffer;
+    int rc;
+
+    sf_g = GET_GLOB_INFO(sb);
+    cbBuffer = sizeof(SHFLVolumeInfo);
+    rc = VbglR0SfFsInfo(&client_handle, &sf_g->map, 0, SHFL_INFO_GET | SHFL_INFO_VOLUME,
+                        &cbBuffer, (PSHFLDIRINFO)&SHFLVolumeInfo);
+    if (RT_FAILURE(rc))
+        return -RTErrConvertToErrno(rc);
+
+    stat->f_type        = NFS_SUPER_MAGIC; /* XXX vboxsf type? */
+    stat->f_bsize       = SHFLVolumeInfo.ulBytesPerAllocationUnit;
+    stat->f_blocks      = SHFLVolumeInfo.ullTotalAllocationBytes
+                        / SHFLVolumeInfo.ulBytesPerAllocationUnit;
+    stat->f_bfree       = SHFLVolumeInfo.ullAvailableAllocationBytes
+                        / SHFLVolumeInfo.ulBytesPerAllocationUnit;
+    stat->f_bavail      = SHFLVolumeInfo.ullAvailableAllocationBytes
+                        / SHFLVolumeInfo.ulBytesPerAllocationUnit;
+    stat->f_files       = 1000;
+    stat->f_ffree       = 1000; /* don't return 0 here since the guest may think
+                                 * that it is not possible to create any more files */
+    stat->f_fsid.val[0] = 0;
+    stat->f_fsid.val[1] = 0;
+    stat->f_namelen     = 255;
+    return 0;
+}
+
+struct dentry_operations sf_dentry_ops =
+{
+    .d_revalidate = sf_dentry_revalidate
+};
+
+int sf_init_backing_dev(struct sf_glob_info *sf_g)
+{
+    int rc = 0;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) && LINUX_VERSION_CODE <= KERNEL_VERSION(3, 19, 0)
+    /* Each new shared folder map gets a new uint64_t identifier,
+     * allocated in sequence.  We ASSUME the sequence will not wrap. */
+    static uint64_t s_u64Sequence = 0;
+    uint64_t u64CurrentSequence = ASMAtomicIncU64(&s_u64Sequence);
+
+    sf_g->bdi.ra_pages = 0; /* No readahead */
+# if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 12)
+    sf_g->bdi.capabilities  = BDI_CAP_MAP_DIRECT    /* MAP_SHARED */
+                            | BDI_CAP_MAP_COPY      /* MAP_PRIVATE */
+                            | BDI_CAP_READ_MAP      /* can be mapped for reading */
+                            | BDI_CAP_WRITE_MAP     /* can be mapped for writing */
+                            | BDI_CAP_EXEC_MAP;     /* can be mapped for execution */
+# endif /* >= 2.6.12 */
+# if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24)
+    rc = bdi_init(&sf_g->bdi);
+#  if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26)
+    if (!rc)
+        rc = bdi_register(&sf_g->bdi, NULL, "vboxsf-%llu",
+                          (unsigned long long)u64CurrentSequence);
+#  endif /* >= 2.6.26 */
+# endif /* >= 2.6.24 */
+#endif /* >= 2.6.0 && <= 3.19.0 */
+    return rc;
+}
+
+void sf_done_backing_dev(struct sf_glob_info *sf_g)
+{
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24) && LINUX_VERSION_CODE <= KERNEL_VERSION(3, 19, 0)
+    bdi_destroy(&sf_g->bdi); /* includes bdi_unregister() */
+#endif
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/vboxsf/vbsfmount.h
@@ -0,0 +1,78 @@
+/** @file
+ * vboxsf -- VirtualBox Guest Additions for Linux: mount(2) parameter structure.
+ */
+
+/*
+ * Copyright (C) 2006-2010 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+#ifndef VBFS_MOUNT_H
+#define VBFS_MOUNT_H
+
+#define MAX_HOST_NAME  256
+#define MAX_NLS_NAME    32
+
+/* Linux constraints the size of data mount argument to PAGE_SIZE - 1. */
+struct vbsf_mount_info_old
+{
+    char name[MAX_HOST_NAME];
+    char nls_name[MAX_NLS_NAME];
+    int  uid;
+    int  gid;
+    int  ttl;
+};
+
+#define VBSF_MOUNT_SIGNATURE_BYTE_0 '\377'
+#define VBSF_MOUNT_SIGNATURE_BYTE_1 '\376'
+#define VBSF_MOUNT_SIGNATURE_BYTE_2 '\375'
+
+struct vbsf_mount_info_new
+{
+    char nullchar;              /* name cannot be '\0' -- we use this field
+                                   to distinguish between the old structure
+                                   and the new structure */
+    char signature[3];          /* signature */
+    int  length;                /* length of the whole structure */
+    char name[MAX_HOST_NAME];   /* share name */
+    char nls_name[MAX_NLS_NAME];/* name of an I/O charset */
+    int  uid;                   /* user ID for all entries, default 0=root */
+    int  gid;                   /* group ID for all entries, default 0=root */
+    int  ttl;                   /* time to live */
+    int  dmode;                 /* mode for directories if != 0xffffffff */
+    int  fmode;                 /* mode for regular files if != 0xffffffff */
+    int  dmask;                 /* umask applied to directories */
+    int  fmask;                 /* umask applied to regular files */
+};
+
+struct vbsf_mount_opts
+{
+    int  uid;
+    int  gid;
+    int  ttl;
+    int  dmode;
+    int  fmode;
+    int  dmask;
+    int  fmask;
+    int  ronly;
+    int  sloppy;
+    int  noexec;
+    int  nodev;
+    int  nosuid;
+    int  remount;
+    char nls_name[MAX_NLS_NAME];
+    char *convertcp;
+};
+
+/** Completes the mount operation by adding the new mount point to mtab if required. */
+int vbsfmount_complete(const char *host_name, const char *mount_point,
+                       unsigned long flags, struct vbsf_mount_opts *opts);
+
+#endif /* vbsfmount.h */
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/vboxsf/version-generated.h
@@ -0,0 +1,13 @@
+#ifndef ___version_generated_h___
+#define ___version_generated_h___
+
+#define VBOX_VERSION_MAJOR 5
+#define VBOX_VERSION_MINOR 0
+#define VBOX_VERSION_BUILD 18
+#define VBOX_VERSION_STRING_RAW "5.0.18"
+#define VBOX_VERSION_STRING "5.0.18_Ubuntu"
+#define VBOX_API_VERSION_STRING "5_0"
+
+#define VBOX_PRIVATE_BUILD_DESC "Private build by root"
+
+#endif
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/vboxsf/vfsmod.c
@@ -0,0 +1,664 @@
+/** @file
+ *
+ * vboxsf -- VirtualBox Guest Additions for Linux:
+ * Virtual File System for VirtualBox Shared Folders
+ *
+ * Module initialization/finalization
+ * File system registration/deregistration
+ * Superblock reading
+ * Few utility functions
+ */
+
+/*
+ * Copyright (C) 2006-2012 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+/**
+ * @note Anyone wishing to make changes here might wish to take a look at
+ *  http://www.atnf.csiro.au/people/rgooch/linux/vfs.txt
+ * which seems to be the closest there is to official documentation on
+ * writing filesystem drivers for Linux.
+ */
+
+#include "vfsmod.h"
+
+MODULE_DESCRIPTION(VBOX_PRODUCT " VFS Module for Host File System Access");
+MODULE_AUTHOR(VBOX_VENDOR);
+MODULE_LICENSE("GPL");
+#ifdef MODULE_VERSION
+MODULE_VERSION(VBOX_VERSION_STRING " (interface " RT_XSTR(VMMDEV_VERSION) ")");
+#endif
+
+/* globals */
+VBGLSFCLIENT client_handle;
+
+/* forward declarations */
+static struct super_operations sf_super_ops;
+
+/* allocate global info, try to map host share */
+static int sf_glob_alloc(struct vbsf_mount_info_new *info, struct sf_glob_info **sf_gp)
+{
+    int err, rc;
+    SHFLSTRING *str_name;
+    size_t name_len, str_len;
+    struct sf_glob_info *sf_g;
+
+    TRACE();
+    sf_g = kmalloc(sizeof(*sf_g), GFP_KERNEL);
+    if (!sf_g)
+    {
+        err = -ENOMEM;
+        LogRelFunc(("could not allocate memory for global info\n"));
+        goto fail0;
+    }
+
+    RT_ZERO(*sf_g);
+
+    if (   info->nullchar     != '\0'
+        || info->signature[0] != VBSF_MOUNT_SIGNATURE_BYTE_0
+        || info->signature[1] != VBSF_MOUNT_SIGNATURE_BYTE_1
+        || info->signature[2] != VBSF_MOUNT_SIGNATURE_BYTE_2)
+    {
+        /* An old version of mount.vboxsf made the syscall. Translate the
+         * old parameters to the new structure. */
+        struct vbsf_mount_info_old *info_old = (struct vbsf_mount_info_old *)info;
+        static struct vbsf_mount_info_new info_compat;
+
+        info = &info_compat;
+        memset(info, 0, sizeof(*info));
+        memcpy(&info->name, &info_old->name, MAX_HOST_NAME);
+        memcpy(&info->nls_name, &info_old->nls_name, MAX_NLS_NAME);
+        info->length = offsetof(struct vbsf_mount_info_new, dmode);
+        info->uid    = info_old->uid;
+        info->gid    = info_old->gid;
+        info->ttl    = info_old->ttl;
+    }
+
+    info->name[sizeof(info->name) - 1] = 0;
+    info->nls_name[sizeof(info->nls_name) - 1] = 0;
+
+    name_len = strlen(info->name);
+    if (name_len > 0xfffe)
+    {
+        err = -ENAMETOOLONG;
+        LogFunc(("map name too big\n"));
+        goto fail1;
+    }
+
+    str_len = offsetof(SHFLSTRING, String.utf8) + name_len + 1;
+    str_name = kmalloc(str_len, GFP_KERNEL);
+    if (!str_name)
+    {
+        err = -ENOMEM;
+        LogRelFunc(("could not allocate memory for host name\n"));
+        goto fail1;
+    }
+
+    str_name->u16Length = name_len;
+    str_name->u16Size = name_len + 1;
+    memcpy(str_name->String.utf8, info->name, name_len + 1);
+
+#define _IS_UTF8(_str) \
+    (strcmp(_str, "utf8") == 0)
+#define _IS_EMPTY(_str) \
+    (strcmp(_str, "") == 0)
+
+    /* Check if NLS charset is valid and not points to UTF8 table */
+    if (info->nls_name[0])
+    {
+        if (_IS_UTF8(info->nls_name))
+            sf_g->nls = NULL;
+        else
+        {
+            sf_g->nls = load_nls(info->nls_name);
+            if (!sf_g->nls)
+            {
+                err = -EINVAL;
+                LogFunc(("failed to load nls %s\n", info->nls_name));
+                goto fail1;
+            }
+        }
+    }
+    else
+    {
+#ifdef CONFIG_NLS_DEFAULT
+        /* If no NLS charset specified, try to load the default
+         * one if it's not points to UTF8. */
+        if (!_IS_UTF8(CONFIG_NLS_DEFAULT) && !_IS_EMPTY(CONFIG_NLS_DEFAULT))
+            sf_g->nls = load_nls_default();
+        else
+            sf_g->nls = NULL;
+#else
+        sf_g->nls = NULL;
+#endif
+
+#undef _IS_UTF8
+#undef _IS_EMPTY
+    }
+
+    rc = VbglR0SfMapFolder(&client_handle, str_name, &sf_g->map);
+    kfree(str_name);
+
+    if (RT_FAILURE(rc))
+    {
+        err = -EPROTO;
+        LogFunc(("VbglR0SfMapFolder failed rc=%d\n", rc));
+        goto fail2;
+    }
+
+    sf_g->ttl = info->ttl;
+    sf_g->uid = info->uid;
+    sf_g->gid = info->gid;
+
+    if ((unsigned)info->length >= sizeof(struct vbsf_mount_info_new))
+    {
+        /* new fields */
+        sf_g->dmode = info->dmode;
+        sf_g->fmode = info->fmode;
+        sf_g->dmask = info->dmask;
+        sf_g->fmask = info->fmask;
+    }
+    else
+    {
+        sf_g->dmode = ~0;
+        sf_g->fmode = ~0;
+    }
+
+    *sf_gp = sf_g;
+    return 0;
+
+fail2:
+    if (sf_g->nls)
+        unload_nls(sf_g->nls);
+
+fail1:
+    kfree(sf_g);
+
+fail0:
+    return err;
+}
+
+/* unmap the share and free global info [sf_g] */
+static void
+sf_glob_free(struct sf_glob_info *sf_g)
+{
+    int rc;
+
+    TRACE();
+    rc = VbglR0SfUnmapFolder(&client_handle, &sf_g->map);
+    if (RT_FAILURE(rc))
+        LogFunc(("VbglR0SfUnmapFolder failed rc=%d\n", rc));
+
+    if (sf_g->nls)
+        unload_nls(sf_g->nls);
+
+    kfree(sf_g);
+}
+
+/**
+ * This is called (by sf_read_super_[24|26] when vfs mounts the fs and
+ * wants to read super_block.
+ *
+ * calls [sf_glob_alloc] to map the folder and allocate global
+ * information structure.
+ *
+ * initializes [sb], initializes root inode and dentry.
+ *
+ * should respect [flags]
+ */
+static int sf_read_super_aux(struct super_block *sb, void *data, int flags)
+{
+    int err;
+    struct dentry *droot;
+    struct inode *iroot;
+    struct sf_inode_info *sf_i;
+    struct sf_glob_info *sf_g;
+    SHFLFSOBJINFO fsinfo;
+    struct vbsf_mount_info_new *info;
+    bool fInodePut = true;
+
+    TRACE();
+    if (!data)
+    {
+        LogFunc(("no mount info specified\n"));
+        return -EINVAL;
+    }
+
+    info = data;
+
+    if (flags & MS_REMOUNT)
+    {
+        LogFunc(("remounting is not supported\n"));
+        return -ENOSYS;
+    }
+
+    err = sf_glob_alloc(info, &sf_g);
+    if (err)
+        goto fail0;
+
+    sf_i = kmalloc(sizeof (*sf_i), GFP_KERNEL);
+    if (!sf_i)
+    {
+        err = -ENOMEM;
+        LogRelFunc(("could not allocate memory for root inode info\n"));
+        goto fail1;
+    }
+
+    sf_i->handle = SHFL_HANDLE_NIL;
+    sf_i->path = kmalloc(sizeof(SHFLSTRING) + 1, GFP_KERNEL);
+    if (!sf_i->path)
+    {
+        err = -ENOMEM;
+        LogRelFunc(("could not allocate memory for root inode path\n"));
+        goto fail2;
+    }
+
+    sf_i->path->u16Length = 1;
+    sf_i->path->u16Size = 2;
+    sf_i->path->String.utf8[0] = '/';
+    sf_i->path->String.utf8[1] = 0;
+    sf_i->force_reread = 0;
+
+    err = sf_stat(__func__, sf_g, sf_i->path, &fsinfo, 0);
+    if (err)
+    {
+        LogFunc(("could not stat root of share\n"));
+        goto fail3;
+    }
+
+    sb->s_magic = 0xface;
+    sb->s_blocksize = 1024;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 3)
+    /* Required for seek/sendfile.
+     *
+     * Must by less than or equal to INT64_MAX despite the fact that the
+     * declaration of this variable is unsigned long long. See determination
+     * of 'loff_t max' in fs/read_write.c / do_sendfile(). I don't know the
+     * correct limit but MAX_LFS_FILESIZE (8TB-1 on 32-bit boxes) takes the
+     * page cache into account and is the suggested limit. */
+# if defined MAX_LFS_FILESIZE
+    sb->s_maxbytes = MAX_LFS_FILESIZE;
+# else
+    sb->s_maxbytes = 0x7fffffffffffffffULL;
+# endif
+#endif
+    sb->s_op = &sf_super_ops;
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 25)
+    iroot = iget_locked(sb, 0);
+#else
+    iroot = iget(sb, 0);
+#endif
+    if (!iroot)
+    {
+        err = -ENOMEM;  /* XXX */
+        LogFunc(("could not get root inode\n"));
+        goto fail3;
+    }
+
+    if (sf_init_backing_dev(sf_g))
+    {
+        err = -EINVAL;
+        LogFunc(("could not init bdi\n"));
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 25)
+        unlock_new_inode(iroot);
+#endif
+        goto fail4;
+    }
+
+    sf_init_inode(sf_g, iroot, &fsinfo);
+    SET_INODE_INFO(iroot, sf_i);
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 25)
+    unlock_new_inode(iroot);
+#endif
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0)
+    droot = d_make_root(iroot);
+#else
+    droot = d_alloc_root(iroot);
+#endif
+    if (!droot)
+    {
+        err = -ENOMEM;  /* XXX */
+        LogFunc(("d_alloc_root failed\n"));
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0)
+        fInodePut = false;
+#endif
+        goto fail5;
+    }
+
+    sb->s_root = droot;
+    SET_GLOB_INFO(sb, sf_g);
+    return 0;
+
+fail5:
+    sf_done_backing_dev(sf_g);
+
+fail4:
+    if (fInodePut)
+        iput(iroot);
+
+fail3:
+    kfree(sf_i->path);
+
+fail2:
+    kfree(sf_i);
+
+fail1:
+    sf_glob_free(sf_g);
+
+fail0:
+    return err;
+}
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0)
+static struct super_block *
+sf_read_super_24(struct super_block *sb, void *data, int flags)
+{
+    int err;
+
+    TRACE();
+    err = sf_read_super_aux(sb, data, flags);
+    if (err)
+        return NULL;
+
+    return sb;
+}
+#endif
+
+/* this is called when vfs is about to destroy the [inode]. all
+   resources associated with this [inode] must be cleared here */
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 36)
+static void sf_clear_inode(struct inode *inode)
+{
+    struct sf_inode_info *sf_i;
+
+    TRACE();
+    sf_i = GET_INODE_INFO(inode);
+    if (!sf_i)
+        return;
+
+    BUG_ON(!sf_i->path);
+    kfree(sf_i->path);
+    kfree(sf_i);
+    SET_INODE_INFO(inode, NULL);
+}
+#else
+static void sf_evict_inode(struct inode *inode)
+{
+    struct sf_inode_info *sf_i;
+
+    TRACE();
+    truncate_inode_pages(&inode->i_data, 0);
+# if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)
+    clear_inode(inode);
+# else
+    end_writeback(inode);
+# endif
+
+    sf_i = GET_INODE_INFO(inode);
+    if (!sf_i)
+        return;
+
+    BUG_ON(!sf_i->path);
+    kfree(sf_i->path);
+    kfree(sf_i);
+    SET_INODE_INFO(inode, NULL);
+}
+#endif
+
+/* this is called by vfs when it wants to populate [inode] with data.
+   the only thing that is known about inode at this point is its index
+   hence we can't do anything here, and let lookup/whatever with the
+   job to properly fill then [inode] */
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 25)
+static void sf_read_inode(struct inode *inode)
+{
+}
+#endif
+
+/* vfs is done with [sb] (umount called) call [sf_glob_free] to unmap
+   the folder and free [sf_g] */
+static void sf_put_super(struct super_block *sb)
+{
+    struct sf_glob_info *sf_g;
+
+    sf_g = GET_GLOB_INFO(sb);
+    BUG_ON(!sf_g);
+    sf_done_backing_dev(sf_g);
+    sf_glob_free(sf_g);
+}
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 18)
+static int sf_statfs(struct super_block *sb, STRUCT_STATFS *stat)
+{
+    return sf_get_volume_info(sb, stat);
+}
+#else
+static int sf_statfs(struct dentry *dentry, STRUCT_STATFS *stat)
+{
+    struct super_block *sb = dentry->d_inode->i_sb;
+    return sf_get_volume_info(sb, stat);
+}
+#endif
+
+static int sf_remount_fs(struct super_block *sb, int *flags, char *data)
+{
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 23)
+    struct sf_glob_info *sf_g;
+    struct sf_inode_info *sf_i;
+    struct inode *iroot;
+    SHFLFSOBJINFO fsinfo;
+    int err;
+
+    sf_g = GET_GLOB_INFO(sb);
+    BUG_ON(!sf_g);
+    if (data && data[0] != 0)
+    {
+        struct vbsf_mount_info_new *info =
+            (struct vbsf_mount_info_new *)data;
+        if (   info->signature[0] == VBSF_MOUNT_SIGNATURE_BYTE_0
+            && info->signature[1] == VBSF_MOUNT_SIGNATURE_BYTE_1
+            && info->signature[2] == VBSF_MOUNT_SIGNATURE_BYTE_2)
+        {
+            sf_g->uid = info->uid;
+            sf_g->gid = info->gid;
+            sf_g->ttl = info->ttl;
+            sf_g->dmode = info->dmode;
+            sf_g->fmode = info->fmode;
+            sf_g->dmask = info->dmask;
+            sf_g->fmask = info->fmask;
+        }
+    }
+
+    iroot = ilookup(sb, 0);
+    if (!iroot)
+        return -ENOSYS;
+
+    sf_i = GET_INODE_INFO(iroot);
+    err = sf_stat(__func__, sf_g, sf_i->path, &fsinfo, 0);
+    BUG_ON(err != 0);
+    sf_init_inode(sf_g, iroot, &fsinfo);
+    /*unlock_new_inode(iroot);*/
+    return 0;
+#else
+    return -ENOSYS;
+#endif
+}
+
+static struct super_operations sf_super_ops =
+{
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 36)
+    .clear_inode = sf_clear_inode,
+#else
+    .evict_inode = sf_evict_inode,
+#endif
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 25)
+    .read_inode  = sf_read_inode,
+#endif
+    .put_super   = sf_put_super,
+    .statfs      = sf_statfs,
+    .remount_fs  = sf_remount_fs
+};
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0)
+static DECLARE_FSTYPE(vboxsf_fs_type, "vboxsf", sf_read_super_24, 0);
+#else
+static int
+sf_read_super_26(struct super_block *sb, void *data, int flags)
+{
+    int err;
+
+    TRACE();
+    err = sf_read_super_aux(sb, data, flags);
+    if (err)
+        printk(KERN_DEBUG "sf_read_super_aux err=%d\n", err);
+
+    return err;
+}
+
+# if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 18)
+static struct super_block *sf_get_sb(struct file_system_type *fs_type, int flags,
+                                     const char *dev_name, void *data)
+{
+    TRACE();
+    return get_sb_nodev(fs_type, flags, data, sf_read_super_26);
+}
+# elif LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 39)
+static int sf_get_sb(struct file_system_type *fs_type, int flags,
+                     const char *dev_name, void *data, struct vfsmount *mnt)
+{
+    TRACE();
+    return get_sb_nodev(fs_type, flags, data, sf_read_super_26, mnt);
+}
+# else
+static struct dentry *sf_mount(struct file_system_type *fs_type, int flags,
+                               const char *dev_name, void *data)
+{
+    TRACE();
+    return mount_nodev(fs_type, flags, data, sf_read_super_26);
+}
+# endif
+
+static struct file_system_type vboxsf_fs_type =
+{
+    .owner   = THIS_MODULE,
+    .name    = "vboxsf",
+# if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 39)
+    .get_sb  = sf_get_sb,
+# else
+    .mount   = sf_mount,
+# endif
+    .kill_sb = kill_anon_super
+};
+#endif
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)
+static int follow_symlinks = 0;
+module_param(follow_symlinks, int, 0);
+MODULE_PARM_DESC(follow_symlinks, "Let host resolve symlinks rather than showing them");
+#endif
+
+/* Module initialization/finalization handlers */
+static int __init init(void)
+{
+    int rcVBox;
+    int rcRet = 0;
+    int err;
+
+    TRACE();
+
+    if (sizeof(struct vbsf_mount_info_new) > PAGE_SIZE)
+    {
+        printk(KERN_ERR
+                "Mount information structure is too large %lu\n"
+                "Must be less than or equal to %lu\n",
+                (unsigned long)sizeof (struct vbsf_mount_info_new),
+                (unsigned long)PAGE_SIZE);
+        return -EINVAL;
+    }
+
+    err = register_filesystem(&vboxsf_fs_type);
+    if (err)
+    {
+        LogFunc(("register_filesystem err=%d\n", err));
+        return err;
+    }
+
+    rcVBox = VbglR0SfInit();
+    if (RT_FAILURE(rcVBox))
+    {
+        LogRelFunc(("VbglR0SfInit failed, rc=%d\n", rcVBox));
+        rcRet = -EPROTO;
+        goto fail0;
+    }
+
+    rcVBox = VbglR0SfConnect(&client_handle);
+    if (RT_FAILURE(rcVBox))
+    {
+        LogRelFunc(("VbglR0SfConnect failed, rc=%d\n", rcVBox));
+        rcRet = -EPROTO;
+        goto fail1;
+    }
+
+    rcVBox = VbglR0SfSetUtf8(&client_handle);
+    if (RT_FAILURE(rcVBox))
+    {
+        LogRelFunc(("VbglR0SfSetUtf8 failed, rc=%d\n", rcVBox));
+        rcRet = -EPROTO;
+        goto fail2;
+    }
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)
+    if (!follow_symlinks)
+    {
+        rcVBox = VbglR0SfSetSymlinks(&client_handle);
+        if (RT_FAILURE(rcVBox))
+        {
+            printk(KERN_WARNING
+                     "vboxsf: Host unable to show symlinks, rc=%d\n",
+                     rcVBox);
+        }
+    }
+#endif
+
+    printk(KERN_DEBUG
+            "vboxsf: Successfully loaded version " VBOX_VERSION_STRING
+            " (interface " RT_XSTR(VMMDEV_VERSION) ")\n");
+
+    return 0;
+
+fail2:
+    VbglR0SfDisconnect(&client_handle);
+
+fail1:
+    VbglR0SfTerm();
+
+fail0:
+    unregister_filesystem(&vboxsf_fs_type);
+    return rcRet;
+}
+
+static void __exit fini(void)
+{
+    TRACE();
+
+    VbglR0SfDisconnect(&client_handle);
+    VbglR0SfTerm();
+    unregister_filesystem(&vboxsf_fs_type);
+}
+
+module_init(init);
+module_exit(fini);
+
+/* C++ hack */
+int __gxx_personality_v0 = 0xdeadbeef;
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/vboxsf/vfsmod.h
@@ -0,0 +1,165 @@
+/** @file
+ * vboxsf - VirtualBox Guest Additions for Linux.
+ */
+
+/*
+ * Copyright (C) 2006-2011 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+#ifndef VFSMOD_H
+#define VFSMOD_H
+
+#define LOG_GROUP LOG_GROUP_SHARED_FOLDERS
+#include "the-linux-kernel.h"
+#include "version-generated.h"
+#include "product-generated.h"
+#include <VBox/log.h>
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)
+# include <linux/backing-dev.h>
+#endif
+
+#include <VBox/VBoxGuestLibSharedFolders.h>
+#include "vbsfmount.h"
+
+#define DIR_BUFFER_SIZE (16*_1K)
+
+/* per-shared folder information */
+struct sf_glob_info
+{
+    VBGLSFMAP map;
+    struct nls_table *nls;
+    int ttl;
+    int uid;
+    int gid;
+    int dmode;
+    int fmode;
+    int dmask;
+    int fmask;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)
+    struct backing_dev_info bdi;
+#endif
+};
+
+/* per-inode information */
+struct sf_inode_info
+{
+    /* which file */
+    SHFLSTRING *path;
+    /* some information was changed, update data on next revalidate */
+    int force_restat;
+    /* directory content changed, update the whole directory on next sf_getdent */
+    int force_reread;
+    /* file structure, only valid between open() and release() */
+    struct file *file;
+    /* handle valid if a file was created with sf_create_aux until it will
+     * be opened with sf_reg_open() */
+    SHFLHANDLE handle;
+};
+
+struct sf_dir_info
+{
+    struct list_head info_list;
+};
+
+struct sf_dir_buf
+{
+    size_t cEntries;
+    size_t cbFree;
+    size_t cbUsed;
+    void   *buf;
+    struct list_head head;
+};
+
+struct sf_reg_info
+{
+    SHFLHANDLE handle;
+};
+
+/* globals */
+extern VBGLSFCLIENT client_handle;
+
+/* forward declarations */
+extern struct inode_operations         sf_dir_iops;
+extern struct inode_operations         sf_lnk_iops;
+extern struct inode_operations         sf_reg_iops;
+extern struct file_operations          sf_dir_fops;
+extern struct file_operations          sf_reg_fops;
+extern struct dentry_operations        sf_dentry_ops;
+extern struct address_space_operations sf_reg_aops;
+
+extern void sf_init_inode(struct sf_glob_info *sf_g, struct inode *inode,
+                          PSHFLFSOBJINFO info);
+extern int  sf_stat(const char *caller, struct sf_glob_info *sf_g,
+                    SHFLSTRING *path, PSHFLFSOBJINFO result, int ok_to_fail);
+extern int  sf_inode_revalidate(struct dentry *dentry);
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)
+extern int  sf_getattr(struct vfsmount *mnt, struct dentry *dentry,
+                       struct kstat *kstat);
+extern int  sf_setattr(struct dentry *dentry, struct iattr *iattr);
+#endif
+extern int  sf_path_from_dentry(const char *caller, struct sf_glob_info *sf_g,
+                                struct sf_inode_info *sf_i, struct dentry *dentry,
+                                SHFLSTRING **result);
+extern int  sf_nlscpy(struct sf_glob_info *sf_g,
+                      char *name, size_t name_bound_len,
+                      const unsigned char *utf8_name, size_t utf8_len);
+extern void sf_dir_info_free(struct sf_dir_info *p);
+extern void sf_dir_info_empty(struct sf_dir_info *p);
+extern struct sf_dir_info *sf_dir_info_alloc(void);
+extern int  sf_dir_read_all(struct sf_glob_info *sf_g, struct sf_inode_info *sf_i,
+                            struct sf_dir_info *sf_d, SHFLHANDLE handle);
+extern int  sf_init_backing_dev(struct sf_glob_info *sf_g);
+extern void sf_done_backing_dev(struct sf_glob_info *sf_g);
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0)
+# define STRUCT_STATFS  struct statfs
+#else
+# define STRUCT_STATFS  struct kstatfs
+#endif
+int sf_get_volume_info(struct super_block *sb,STRUCT_STATFS *stat);
+
+#ifdef __cplusplus
+# define CMC_API __attribute__ ((cdecl, regparm (0)))
+#else
+# define CMC_API __attribute__ ((regparm (0)))
+#endif
+
+#define TRACE() LogFunc(("tracepoint\n"))
+
+/* Following casts are here to prevent assignment of void * to
+   pointers of arbitrary type */
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0)
+# define GET_GLOB_INFO(sb)       ((struct sf_glob_info *) (sb)->u.generic_sbp)
+# define SET_GLOB_INFO(sb, sf_g) (sb)->u.generic_sbp = sf_g
+#else
+# define GET_GLOB_INFO(sb)       ((struct sf_glob_info *) (sb)->s_fs_info)
+# define SET_GLOB_INFO(sb, sf_g) (sb)->s_fs_info = sf_g
+#endif
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19) || defined(KERNEL_FC6)
+/* FC6 kernel 2.6.18, vanilla kernel 2.6.19+ */
+# define GET_INODE_INFO(i)       ((struct sf_inode_info *) (i)->i_private)
+# define SET_INODE_INFO(i, sf_i) (i)->i_private = sf_i
+#else
+/* vanilla kernel up to 2.6.18 */
+# define GET_INODE_INFO(i)       ((struct sf_inode_info *) (i)->u.generic_ip)
+# define SET_INODE_INFO(i, sf_i) (i)->u.generic_ip = sf_i
+#endif
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0)
+# define GET_F_DENTRY(f)        (f->f_path.dentry)
+#else
+# define GET_F_DENTRY(f)        (f->f_dentry)
+#endif
+
+#endif
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/vboxvideo/HGSMIBase.c
@@ -0,0 +1,694 @@
+/* $Id: HGSMIBase.cpp $ */
+/** @file
+ * VirtualBox Video driver, common code - HGSMI initialisation and helper
+ * functions.
+ */
+
+/*
+ * Copyright (C) 2006-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+#include <VBox/VBoxVideoGuest.h>
+#include <VBox/VBoxVideo.h>
+#include <VBox/VBoxGuest.h>
+#include <VBox/Hardware/VBoxVideoVBE.h>
+#include <VBox/VMMDev.h>
+
+#include <iprt/asm.h>
+#include <iprt/log.h>
+#include <iprt/string.h>
+
+/** Send completion notification to the host for the command located at offset
+ * @a offt into the host command buffer. */
+static void HGSMINotifyHostCmdComplete(PHGSMIHOSTCOMMANDCONTEXT pCtx, HGSMIOFFSET offt)
+{
+    VBoxVideoCmnPortWriteUlong(pCtx->port, offt);
+}
+
+
+/**
+ * Inform the host that a command has been handled.
+ *
+ * @param  pCtx   the context containing the heap to be used
+ * @param  pvMem  pointer into the heap as mapped in @a pCtx to the command to
+ *                be completed
+ */
+RTDECL(void) VBoxHGSMIHostCmdComplete(PHGSMIHOSTCOMMANDCONTEXT pCtx,
+                                      void *pvMem)
+{
+    HGSMIBUFFERHEADER *pHdr = HGSMIBufferHeaderFromData(pvMem);
+    HGSMIOFFSET offMem = HGSMIPointerToOffset(&pCtx->areaCtx, pHdr);
+    Assert(offMem != HGSMIOFFSET_VOID);
+    if(offMem != HGSMIOFFSET_VOID)
+    {
+        HGSMINotifyHostCmdComplete(pCtx, offMem);
+    }
+}
+
+
+/** Submit an incoming host command to the appropriate handler. */
+static void hgsmiHostCmdProcess(PHGSMIHOSTCOMMANDCONTEXT pCtx,
+                                HGSMIOFFSET offBuffer)
+{
+    int rc = HGSMIBufferProcess(&pCtx->areaCtx, &pCtx->channels, offBuffer);
+    Assert(!RT_FAILURE(rc));
+    if(RT_FAILURE(rc))
+    {
+        /* failure means the command was not submitted to the handler for some reason
+         * it's our responsibility to notify its completion in this case */
+        HGSMINotifyHostCmdComplete(pCtx, offBuffer);
+    }
+    /* if the cmd succeeded it's responsibility of the callback to complete it */
+}
+
+/** Get the next command from the host. */
+static HGSMIOFFSET hgsmiGetHostBuffer(PHGSMIHOSTCOMMANDCONTEXT pCtx)
+{
+    return VBoxVideoCmnPortReadUlong(pCtx->port);
+}
+
+
+/** Get and handle the next command from the host. */
+static void hgsmiHostCommandQueryProcess(PHGSMIHOSTCOMMANDCONTEXT pCtx)
+{
+    HGSMIOFFSET offset = hgsmiGetHostBuffer(pCtx);
+    AssertReturnVoid(offset != HGSMIOFFSET_VOID);
+    hgsmiHostCmdProcess(pCtx, offset);
+}
+
+
+/** Drain the host command queue. */
+RTDECL(void) VBoxHGSMIProcessHostQueue(PHGSMIHOSTCOMMANDCONTEXT pCtx)
+{
+    while (pCtx->pfHostFlags->u32HostFlags & HGSMIHOSTFLAGS_COMMANDS_PENDING)
+    {
+        if (!ASMAtomicCmpXchgBool(&pCtx->fHostCmdProcessing, true, false))
+            return;
+        hgsmiHostCommandQueryProcess(pCtx);
+        ASMAtomicWriteBool(&pCtx->fHostCmdProcessing, false);
+    }
+}
+
+
+/** Detect whether HGSMI is supported by the host. */
+RTDECL(bool) VBoxHGSMIIsSupported(void)
+{
+    uint16_t DispiId;
+
+    VBoxVideoCmnPortWriteUshort(VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_ID);
+    VBoxVideoCmnPortWriteUshort(VBE_DISPI_IOPORT_DATA, VBE_DISPI_ID_HGSMI);
+
+    DispiId = VBoxVideoCmnPortReadUshort(VBE_DISPI_IOPORT_DATA);
+
+    return (DispiId == VBE_DISPI_ID_HGSMI);
+}
+
+
+/**
+ * Allocate and initialise a command descriptor in the guest heap for a
+ * guest-to-host command.
+ *
+ * @returns  pointer to the descriptor's command data buffer
+ * @param  pCtx     the context containing the heap to be used
+ * @param  cbData   the size of the command data to go into the descriptor
+ * @param  u8Ch     the HGSMI channel to be used, set to the descriptor
+ * @param  u16Op    the HGSMI command to be sent, set to the descriptor
+ */
+RTDECL(void *) VBoxHGSMIBufferAlloc(PHGSMIGUESTCOMMANDCONTEXT pCtx,
+                                    HGSMISIZE cbData,
+                                    uint8_t u8Ch,
+                                    uint16_t u16Op)
+{
+#ifdef VBOX_WDDM_MINIPORT
+    return VBoxSHGSMIHeapAlloc (&pCtx->heapCtx, cbData, u8Ch, u16Op);
+#else
+    return HGSMIHeapAlloc (&pCtx->heapCtx, cbData, u8Ch, u16Op);
+#endif
+}
+
+
+/**
+ * Free a descriptor allocated by @a VBoxHGSMIBufferAlloc.
+ *
+ * @param  pCtx      the context containing the heap used
+ * @param  pvBuffer  the pointer returned by @a VBoxHGSMIBufferAlloc
+ */
+RTDECL(void) VBoxHGSMIBufferFree(PHGSMIGUESTCOMMANDCONTEXT pCtx,
+                                 void *pvBuffer)
+{
+#ifdef VBOX_WDDM_MINIPORT
+    VBoxSHGSMIHeapFree (&pCtx->heapCtx, pvBuffer);
+#else
+    HGSMIHeapFree (&pCtx->heapCtx, pvBuffer);
+#endif
+}
+
+
+/**
+ * Submit a command descriptor allocated by @a VBoxHGSMIBufferAlloc.
+ *
+ * @param  pCtx      the context containing the heap used
+ * @param  pvBuffer  the pointer returned by @a VBoxHGSMIBufferAlloc
+ */
+RTDECL(int) VBoxHGSMIBufferSubmit(PHGSMIGUESTCOMMANDCONTEXT pCtx,
+                                  void *pvBuffer)
+{
+    /* Initialize the buffer and get the offset for port IO. */
+    HGSMIOFFSET offBuffer = HGSMIHeapBufferOffset (HGSMIGUESTCMDHEAP_GET(&pCtx->heapCtx), pvBuffer);
+
+    Assert(offBuffer != HGSMIOFFSET_VOID);
+    if (offBuffer != HGSMIOFFSET_VOID)
+    {
+        /* Submit the buffer to the host. */
+        VBoxVideoCmnPortWriteUlong(pCtx->port, offBuffer);
+        /* Make the compiler aware that the host has changed memory. */
+        ASMCompilerBarrier();
+        return VINF_SUCCESS;
+    }
+
+    return VERR_INVALID_PARAMETER;
+}
+
+
+/** Inform the host of the location of the host flags in VRAM via an HGSMI
+ * command. */
+static int vboxHGSMIReportFlagsLocation(PHGSMIGUESTCOMMANDCONTEXT pCtx,
+                                        HGSMIOFFSET offLocation)
+{
+    HGSMIBUFFERLOCATION *p;
+    int rc = VINF_SUCCESS;
+
+    /* Allocate the IO buffer. */
+    p = (HGSMIBUFFERLOCATION *)VBoxHGSMIBufferAlloc(pCtx,
+                                              sizeof(HGSMIBUFFERLOCATION),
+                                              HGSMI_CH_HGSMI,
+                                              HGSMI_CC_HOST_FLAGS_LOCATION);
+    if (p)
+    {
+        /* Prepare data to be sent to the host. */
+        p->offLocation = offLocation;
+        p->cbLocation  = sizeof(HGSMIHOSTFLAGS);
+        rc = VBoxHGSMIBufferSubmit(pCtx, p);
+        /* Free the IO buffer. */
+        VBoxHGSMIBufferFree(pCtx, p);
+    }
+    else
+        rc = VERR_NO_MEMORY;
+    return rc;
+}
+
+
+/**
+ * Inform the host of the location of the host flags in VRAM via an HGSMI
+ * command.
+ * @returns  IPRT status value.
+ * @returns  VERR_NOT_IMPLEMENTED  if the host does not support the command.
+ * @returns  VERR_NO_MEMORY        if a heap allocation fails.
+ * @param    pCtx                  the context of the guest heap to use.
+ * @param    offLocation           the offset chosen for the flags withing guest
+ *                                 VRAM.
+ */
+RTDECL(int) VBoxHGSMIReportFlagsLocation(PHGSMIGUESTCOMMANDCONTEXT pCtx,
+                                         HGSMIOFFSET offLocation)
+{
+    return vboxHGSMIReportFlagsLocation(pCtx, offLocation);
+}
+
+
+/** Notify the host of HGSMI-related guest capabilities via an HGSMI command.
+ */
+static int vboxHGSMISendCapsInfo(PHGSMIGUESTCOMMANDCONTEXT pCtx,
+                                 uint32_t fCaps)
+{
+    VBVACAPS *pCaps;
+    int rc = VINF_SUCCESS;
+
+    /* Allocate the IO buffer. */
+    pCaps = (VBVACAPS *)VBoxHGSMIBufferAlloc(pCtx,
+                                       sizeof(VBVACAPS), HGSMI_CH_VBVA,
+                                       VBVA_INFO_CAPS);
+
+    if (pCaps)
+    {
+        /* Prepare data to be sent to the host. */
+        pCaps->rc    = VERR_NOT_IMPLEMENTED;
+        pCaps->fCaps = fCaps;
+        rc = VBoxHGSMIBufferSubmit(pCtx, pCaps);
+        if (RT_SUCCESS(rc))
+        {
+            AssertRC(pCaps->rc);
+            rc = pCaps->rc;
+        }
+        /* Free the IO buffer. */
+        VBoxHGSMIBufferFree(pCtx, pCaps);
+    }
+    else
+        rc = VERR_NO_MEMORY;
+    return rc;
+}
+
+
+/**
+ * Notify the host of HGSMI-related guest capabilities via an HGSMI command.
+ * @returns  IPRT status value.
+ * @returns  VERR_NOT_IMPLEMENTED  if the host does not support the command.
+ * @returns  VERR_NO_MEMORY        if a heap allocation fails.
+ * @param    pCtx                  the context of the guest heap to use.
+ * @param    fCaps                 the capabilities to report, see VBVACAPS.
+ */
+RTDECL(int) VBoxHGSMISendCapsInfo(PHGSMIGUESTCOMMANDCONTEXT pCtx,
+                                  uint32_t fCaps)
+{
+    return vboxHGSMISendCapsInfo(pCtx, fCaps);
+}
+
+
+/** Tell the host about the location of the area of VRAM set aside for the host
+ * heap. */
+static int vboxHGSMIReportHostArea(PHGSMIGUESTCOMMANDCONTEXT pCtx,
+                                   uint32_t u32AreaOffset, uint32_t u32AreaSize)
+{
+    VBVAINFOHEAP *p;
+    int rc = VINF_SUCCESS;
+
+    /* Allocate the IO buffer. */
+    p = (VBVAINFOHEAP *)VBoxHGSMIBufferAlloc(pCtx,
+                                       sizeof (VBVAINFOHEAP), HGSMI_CH_VBVA,
+                                       VBVA_INFO_HEAP);
+    if (p)
+    {
+        /* Prepare data to be sent to the host. */
+        p->u32HeapOffset = u32AreaOffset;
+        p->u32HeapSize   = u32AreaSize;
+        rc = VBoxHGSMIBufferSubmit(pCtx, p);
+        /* Free the IO buffer. */
+        VBoxHGSMIBufferFree(pCtx, p);
+    }
+    else
+        rc = VERR_NO_MEMORY;
+    return rc;
+}
+
+
+/**
+ * Get the information needed to map the basic communication structures in
+ * device memory into our address space.  All pointer parameters are optional.
+ *
+ * @param  cbVRAM               how much video RAM is allocated to the device
+ * @param  poffVRAMBaseMapping  where to save the offset from the start of the
+ *                              device VRAM of the whole area to map
+ * @param  pcbMapping           where to save the mapping size
+ * @param  poffGuestHeapMemory  where to save the offset into the mapped area
+ *                              of the guest heap backing memory
+ * @param  pcbGuestHeapMemory   where to save the size of the guest heap
+ *                              backing memory
+ * @param  poffHostFlags        where to save the offset into the mapped area
+ *                              of the host flags
+ */
+RTDECL(void) VBoxHGSMIGetBaseMappingInfo(uint32_t cbVRAM,
+                                         uint32_t *poffVRAMBaseMapping,
+                                         uint32_t *pcbMapping,
+                                         uint32_t *poffGuestHeapMemory,
+                                         uint32_t *pcbGuestHeapMemory,
+                                         uint32_t *poffHostFlags)
+{
+    AssertPtrNullReturnVoid(poffVRAMBaseMapping);
+    AssertPtrNullReturnVoid(pcbMapping);
+    AssertPtrNullReturnVoid(poffGuestHeapMemory);
+    AssertPtrNullReturnVoid(pcbGuestHeapMemory);
+    AssertPtrNullReturnVoid(poffHostFlags);
+    if (poffVRAMBaseMapping)
+        *poffVRAMBaseMapping = cbVRAM - VBVA_ADAPTER_INFORMATION_SIZE;
+    if (pcbMapping)
+        *pcbMapping = VBVA_ADAPTER_INFORMATION_SIZE;
+    if (poffGuestHeapMemory)
+        *poffGuestHeapMemory = 0;
+    if (pcbGuestHeapMemory)
+        *pcbGuestHeapMemory =   VBVA_ADAPTER_INFORMATION_SIZE
+                              - sizeof(HGSMIHOSTFLAGS);
+    if (poffHostFlags)
+        *poffHostFlags =   VBVA_ADAPTER_INFORMATION_SIZE
+                         - sizeof(HGSMIHOSTFLAGS);
+}
+
+
+/**
+ * Set up the HGSMI guest-to-host command context.
+ * @returns iprt status value
+ * @param  pCtx                    the context to set up
+ * @param  pvGuestHeapMemory       a pointer to the mapped backing memory for
+ *                                 the guest heap
+ * @param  cbGuestHeapMemory       the size of the backing memory area
+ * @param  offVRAMGuestHeapMemory  the offset of the memory pointed to by
+ *                                 @a pvGuestHeapMemory within the video RAM
+ */
+RTDECL(int) VBoxHGSMISetupGuestContext(PHGSMIGUESTCOMMANDCONTEXT pCtx,
+                                       void *pvGuestHeapMemory,
+                                       uint32_t cbGuestHeapMemory,
+                                       uint32_t offVRAMGuestHeapMemory,
+                                       const HGSMIENV *pEnv)
+{
+    /** @todo should we be using a fixed ISA port value here? */
+    pCtx->port = (RTIOPORT)VGA_PORT_HGSMI_GUEST;
+#ifdef VBOX_WDDM_MINIPORT
+    return VBoxSHGSMIInit(&pCtx->heapCtx, pvGuestHeapMemory,
+                          cbGuestHeapMemory, offVRAMGuestHeapMemory, pEnv);
+#else
+    return HGSMIHeapSetup(&pCtx->heapCtx, pvGuestHeapMemory,
+                          cbGuestHeapMemory, offVRAMGuestHeapMemory, pEnv);
+#endif
+}
+
+
+/**
+ * Get the information needed to map the area used by the host to send back
+ * requests.
+ *
+ * @param  pCtx                the context containing the heap to use
+ * @param  cbVRAM              how much video RAM is allocated to the device
+ * @param  offVRAMBaseMapping  the offset of the basic communication structures
+ *                             into the guest's VRAM
+ * @param  poffVRAMHostArea    where to store the offset into VRAM of the host
+ *                             heap area
+ * @param  pcbHostArea         where to store the size of the host heap area
+ */
+RTDECL(void) VBoxHGSMIGetHostAreaMapping(PHGSMIGUESTCOMMANDCONTEXT pCtx,
+                                         uint32_t cbVRAM,
+                                         uint32_t offVRAMBaseMapping,
+                                         uint32_t *poffVRAMHostArea,
+                                         uint32_t *pcbHostArea)
+{
+    uint32_t offVRAMHostArea = offVRAMBaseMapping, cbHostArea = 0;
+
+    AssertPtrReturnVoid(poffVRAMHostArea);
+    AssertPtrReturnVoid(pcbHostArea);
+    VBoxQueryConfHGSMI(pCtx, VBOX_VBVA_CONF32_HOST_HEAP_SIZE, &cbHostArea);
+    if (cbHostArea != 0)
+    {
+        uint32_t cbHostAreaMaxSize = cbVRAM / 4;
+        /** @todo what is the idea of this? */
+        if (cbHostAreaMaxSize >= VBVA_ADAPTER_INFORMATION_SIZE)
+        {
+            cbHostAreaMaxSize -= VBVA_ADAPTER_INFORMATION_SIZE;
+        }
+        if (cbHostArea > cbHostAreaMaxSize)
+        {
+            cbHostArea = cbHostAreaMaxSize;
+        }
+        /* Round up to 4096 bytes. */
+        cbHostArea = (cbHostArea + 0xFFF) & ~0xFFF;
+        offVRAMHostArea = offVRAMBaseMapping - cbHostArea;
+    }
+
+    *pcbHostArea = cbHostArea;
+    *poffVRAMHostArea = offVRAMHostArea;
+    LogFunc(("offVRAMHostArea = 0x%08X, cbHostArea = 0x%08X\n",
+             offVRAMHostArea, cbHostArea));
+}
+
+
+/**
+ * Initialise the host context structure.
+ *
+ * @param  pCtx               the context structure to initialise
+ * @param  pvBaseMapping      where the basic HGSMI structures are mapped at
+ * @param  offHostFlags       the offset of the host flags into the basic HGSMI
+ *                            structures
+ * @param  pvHostAreaMapping  where the area for the host heap is mapped at
+ * @param  offVRAMHostArea    offset of the host heap area into VRAM
+ * @param  cbHostArea         size in bytes of the host heap area
+ */
+RTDECL(void) VBoxHGSMISetupHostContext(PHGSMIHOSTCOMMANDCONTEXT pCtx,
+                                       void *pvBaseMapping,
+                                       uint32_t offHostFlags,
+                                       void *pvHostAreaMapping,
+                                       uint32_t offVRAMHostArea,
+                                       uint32_t cbHostArea)
+{
+    uint8_t *pu8HostFlags = ((uint8_t *)pvBaseMapping) + offHostFlags;
+    pCtx->pfHostFlags = (HGSMIHOSTFLAGS *)pu8HostFlags;
+    /** @todo should we really be using a fixed ISA port value here? */
+    pCtx->port        = (RTIOPORT)VGA_PORT_HGSMI_HOST;
+    HGSMIAreaInitialize(&pCtx->areaCtx, pvHostAreaMapping, cbHostArea,
+                         offVRAMHostArea);
+}
+
+
+/**
+ * Tell the host about the ways it can use to communicate back to us via an
+ * HGSMI command
+ *
+ * @returns  iprt status value
+ * @param  pCtx                  the context containing the heap to use
+ * @param  offVRAMFlagsLocation  where we wish the host to place its flags
+ *                               relative to the start of the VRAM
+ * @param  fCaps                 additions HGSMI capabilities the guest
+ *                               supports
+ * @param  offVRAMHostArea       offset into VRAM of the host heap area
+ * @param  cbHostArea            size in bytes of the host heap area
+ */
+RTDECL(int) VBoxHGSMISendHostCtxInfo(PHGSMIGUESTCOMMANDCONTEXT pCtx,
+                                     HGSMIOFFSET offVRAMFlagsLocation,
+                                     uint32_t fCaps,
+                                     uint32_t offVRAMHostArea,
+                                     uint32_t cbHostArea)
+{
+    Log(("VBoxVideo::vboxSetupAdapterInfo\n"));
+
+    /* setup the flags first to ensure they are initialized by the time the
+     * host heap is ready */
+    int rc = vboxHGSMIReportFlagsLocation(pCtx, offVRAMFlagsLocation);
+    AssertRC(rc);
+    if (RT_SUCCESS(rc) && fCaps)
+    {
+        /* Inform about caps */
+        rc = vboxHGSMISendCapsInfo(pCtx, fCaps);
+        AssertRC(rc);
+    }
+    if (RT_SUCCESS (rc))
+    {
+        /* Report the host heap location. */
+        rc = vboxHGSMIReportHostArea(pCtx, offVRAMHostArea, cbHostArea);
+        AssertRC(rc);
+    }
+    Log(("VBoxVideo::vboxSetupAdapterInfo finished rc = %d\n", rc));
+    return rc;
+}
+
+
+/** Sanity test on first call.  We do not worry about concurrency issues. */
+static int testQueryConf(PHGSMIGUESTCOMMANDCONTEXT pCtx)
+{
+    static bool cOnce = false;
+    uint32_t ulValue = 0;
+    int rc;
+
+    if (cOnce)
+        return VINF_SUCCESS;
+    cOnce = true;
+    rc = VBoxQueryConfHGSMI(pCtx, UINT32_MAX, &ulValue);
+    if (RT_SUCCESS(rc) && ulValue == UINT32_MAX)
+        return VINF_SUCCESS;
+    cOnce = false;
+    if (RT_FAILURE(rc))
+        return rc;
+    return VERR_INTERNAL_ERROR;
+}
+
+
+/**
+ * Query the host for an HGSMI configuration parameter via an HGSMI command.
+ * @returns iprt status value
+ * @param  pCtx      the context containing the heap used
+ * @param  u32Index  the index of the parameter to query,
+ *                   @see VBVACONF32::u32Index
+ * @param  u32DefValue defaut value
+ * @param  pulValue  where to store the value of the parameter on success
+ */
+RTDECL(int) VBoxQueryConfHGSMIDef(PHGSMIGUESTCOMMANDCONTEXT pCtx,
+                                  uint32_t u32Index, uint32_t u32DefValue, uint32_t *pulValue)
+{
+    int rc = VINF_SUCCESS;
+    VBVACONF32 *p;
+    LogFunc(("u32Index = %d\n", u32Index));
+
+    rc = testQueryConf(pCtx);
+    if (RT_FAILURE(rc))
+        return rc;
+    /* Allocate the IO buffer. */
+    p = (VBVACONF32 *)VBoxHGSMIBufferAlloc(pCtx,
+                                     sizeof(VBVACONF32), HGSMI_CH_VBVA,
+                                     VBVA_QUERY_CONF32);
+    if (p)
+    {
+        /* Prepare data to be sent to the host. */
+        p->u32Index = u32Index;
+        p->u32Value = u32DefValue;
+        rc = VBoxHGSMIBufferSubmit(pCtx, p);
+        if (RT_SUCCESS(rc))
+        {
+            *pulValue = p->u32Value;
+            LogFunc(("u32Value = %d\n", p->u32Value));
+        }
+        /* Free the IO buffer. */
+        VBoxHGSMIBufferFree(pCtx, p);
+    }
+    else
+        rc = VERR_NO_MEMORY;
+    LogFunc(("rc = %d\n", rc));
+    return rc;
+}
+
+RTDECL(int) VBoxQueryConfHGSMI(PHGSMIGUESTCOMMANDCONTEXT pCtx,
+                               uint32_t u32Index, uint32_t *pulValue)
+{
+    return VBoxQueryConfHGSMIDef(pCtx, u32Index, UINT32_MAX, pulValue);
+}
+
+/**
+ * Pass the host a new mouse pointer shape via an HGSMI command.
+ *
+ * @returns  success or failure
+ * @param  fFlags    cursor flags, @see VMMDevReqMousePointer::fFlags
+ * @param  cHotX     horizontal position of the hot spot
+ * @param  cHotY     vertical position of the hot spot
+ * @param  cWidth    width in pixels of the cursor
+ * @param  cHeight   height in pixels of the cursor
+ * @param  pPixels   pixel data, @see VMMDevReqMousePointer for the format
+ * @param  cbLength  size in bytes of the pixel data
+ */
+RTDECL(int)  VBoxHGSMIUpdatePointerShape(PHGSMIGUESTCOMMANDCONTEXT pCtx,
+                                         uint32_t fFlags,
+                                         uint32_t cHotX,
+                                         uint32_t cHotY,
+                                         uint32_t cWidth,
+                                         uint32_t cHeight,
+                                         uint8_t *pPixels,
+                                         uint32_t cbLength)
+{
+    VBVAMOUSEPOINTERSHAPE *p;
+    uint32_t cbData = 0;
+    int rc = VINF_SUCCESS;
+
+    if (fFlags & VBOX_MOUSE_POINTER_SHAPE)
+    {
+        /* Size of the pointer data: sizeof (AND mask) + sizeof (XOR_MASK) */
+        cbData = ((((cWidth + 7) / 8) * cHeight + 3) & ~3)
+                 + cWidth * 4 * cHeight;
+        /* If shape is supplied, then always create the pointer visible.
+         * See comments in 'vboxUpdatePointerShape'
+         */
+        fFlags |= VBOX_MOUSE_POINTER_VISIBLE;
+    }
+    LogFlowFunc(("cbData %d, %dx%d\n", cbData, cWidth, cHeight));
+    if (cbData > cbLength)
+    {
+        LogFunc(("calculated pointer data size is too big (%d bytes, limit %d)\n",
+                 cbData, cbLength));
+        return VERR_INVALID_PARAMETER;
+    }
+    /* Allocate the IO buffer. */
+    p = (VBVAMOUSEPOINTERSHAPE *)VBoxHGSMIBufferAlloc(pCtx,
+                                                  sizeof(VBVAMOUSEPOINTERSHAPE)
+                                                + cbData,
+                                                HGSMI_CH_VBVA,
+                                                VBVA_MOUSE_POINTER_SHAPE);
+    if (p)
+    {
+        /* Prepare data to be sent to the host. */
+        /* Will be updated by the host. */
+        p->i32Result = VINF_SUCCESS;
+        /* We have our custom flags in the field */
+        p->fu32Flags = fFlags;
+        p->u32HotX   = cHotX;
+        p->u32HotY   = cHotY;
+        p->u32Width  = cWidth;
+        p->u32Height = cHeight;
+        if (p->fu32Flags & VBOX_MOUSE_POINTER_SHAPE)
+            /* Copy the actual pointer data. */
+            memcpy (p->au8Data, pPixels, cbData);
+        rc = VBoxHGSMIBufferSubmit(pCtx, p);
+        if (RT_SUCCESS(rc))
+            rc = p->i32Result;
+        /* Free the IO buffer. */
+        VBoxHGSMIBufferFree(pCtx, p);
+    }
+    else
+        rc = VERR_NO_MEMORY;
+    LogFlowFunc(("rc %d\n", rc));
+    return rc;
+}
+
+
+/**
+ * Report the guest cursor position.  The host may wish to use this information
+ * to re-position its own cursor (though this is currently unlikely).  The
+ * current host cursor position is returned.
+ * @param  pCtx             The context containing the heap used.
+ * @param  fReportPosition  Are we reporting a position?
+ * @param  x                Guest cursor X position.
+ * @param  y                Guest cursor Y position.
+ * @param  pxHost           Host cursor X position is stored here.  Optional.
+ * @param  pyHost           Host cursor Y position is stored here.  Optional.
+ * @returns  iprt status code.
+ * @returns  VERR_NO_MEMORY      HGSMI heap allocation failed.
+ */
+RTDECL(int) VBoxHGSMICursorPosition(PHGSMIGUESTCOMMANDCONTEXT pCtx, bool fReportPosition, uint32_t x, uint32_t y,
+                                    uint32_t *pxHost, uint32_t *pyHost)
+{
+    int rc = VINF_SUCCESS;
+    VBVACURSORPOSITION *p;
+    Log(("%s: x=%u, y=%u\n", __PRETTY_FUNCTION__, (unsigned)x, (unsigned)y));
+
+    /* Allocate the IO buffer. */
+    p = (VBVACURSORPOSITION *)VBoxHGSMIBufferAlloc(pCtx, sizeof(VBVACURSORPOSITION), HGSMI_CH_VBVA, VBVA_CURSOR_POSITION);
+    if (p)
+    {
+        /* Prepare data to be sent to the host. */
+        p->fReportPosition = fReportPosition ? 1 : 0;
+        p->x = x;
+        p->y = y;
+        rc = VBoxHGSMIBufferSubmit(pCtx, p);
+        if (RT_SUCCESS(rc))
+        {
+            if (pxHost)
+                *pxHost = p->x;
+            if (pyHost)
+                *pyHost = p->y;
+            Log(("%s: return: x=%u, y=%u\n", __PRETTY_FUNCTION__, (unsigned)p->x, (unsigned)p->y));
+        }
+        /* Free the IO buffer. */
+        VBoxHGSMIBufferFree(pCtx, p);
+    }
+    else
+        rc = VERR_NO_MEMORY;
+    LogFunc(("rc = %d\n", rc));
+    return rc;
+}
+
+
+/** @todo Mouse pointer position to be read from VMMDev memory, address of the memory region
+ * can be queried from VMMDev via an IOCTL. This VMMDev memory region will contain
+ * host information which is needed by the guest.
+ *
+ * Reading will not cause a switch to the host.
+ *
+ * Have to take into account:
+ *  * synchronization: host must write to the memory only from EMT,
+ *    large structures must be read under flag, which tells the host
+ *    that the guest is currently reading the memory (OWNER flag?).
+ *  * guest writes: may be allocate a page for the host info and make
+ *    the page readonly for the guest.
+ *  * the information should be available only for additions drivers.
+ *  * VMMDev additions driver will inform the host which version of the info it expects,
+ *    host must support all versions.
+ *
+ */
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/vboxvideo/HGSMICommon.c
@@ -0,0 +1,433 @@
+/* $Id: HGSMICommon.cpp $ */
+/** @file
+ * VBox Host Guest Shared Memory Interface (HGSMI) - Functions common to both host and guest.
+ */
+
+/*
+ * Copyright (C) 2006-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+#define LOG_DISABLED /* Maybe we can enabled it all the time now? */
+#define LOG_GROUP LOG_GROUP_HGSMI
+#include <iprt/heap.h>
+#include <iprt/string.h>
+
+#include <VBox/HGSMI/HGSMI.h>
+#include <VBox/log.h>
+
+
+/* Channel flags. */
+#define HGSMI_CH_F_REGISTERED 0x01
+
+/* Assertions for situations which could happen and normally must be processed properly
+ * but must be investigated during development: guest misbehaving, etc.
+ */
+#ifdef HGSMI_STRICT
+#define HGSMI_STRICT_ASSERT_FAILED() AssertFailed()
+#define HGSMI_STRICT_ASSERT(expr) Assert(expr)
+#else
+#define HGSMI_STRICT_ASSERT_FAILED() do {} while (0)
+#define HGSMI_STRICT_ASSERT(expr) do {} while (0)
+#endif /* !HGSMI_STRICT */
+
+/* One-at-a-Time Hash from
+ * http://www.burtleburtle.net/bob/hash/doobs.html
+ *
+ * ub4 one_at_a_time(char *key, ub4 len)
+ * {
+ *   ub4   hash, i;
+ *   for (hash=0, i=0; i<len; ++i)
+ *   {
+ *     hash += key[i];
+ *     hash += (hash << 10);
+ *     hash ^= (hash >> 6);
+ *   }
+ *   hash += (hash << 3);
+ *   hash ^= (hash >> 11);
+ *   hash += (hash << 15);
+ *   return hash;
+ * }
+ */
+
+static uint32_t hgsmiHashBegin(void)
+{
+    return 0;
+}
+
+static uint32_t hgsmiHashProcess(uint32_t hash,
+                                 const void *pvData,
+                                 size_t cbData)
+{
+    const uint8_t *pu8Data = (const uint8_t *)pvData;
+
+    while (cbData--)
+    {
+        hash += *pu8Data++;
+        hash += (hash << 10);
+        hash ^= (hash >> 6);
+    }
+
+    return hash;
+}
+
+static uint32_t hgsmiHashEnd(uint32_t hash)
+{
+    hash += (hash << 3);
+    hash ^= (hash >> 11);
+    hash += (hash << 15);
+
+    return hash;
+}
+
+uint32_t HGSMIChecksum(HGSMIOFFSET offBuffer,
+                       const HGSMIBUFFERHEADER *pHeader,
+                       const HGSMIBUFFERTAIL *pTail)
+{
+    uint32_t u32Checksum = hgsmiHashBegin();
+
+    u32Checksum = hgsmiHashProcess(u32Checksum, &offBuffer, sizeof(offBuffer));
+    u32Checksum = hgsmiHashProcess(u32Checksum, pHeader, sizeof(HGSMIBUFFERHEADER));
+    u32Checksum = hgsmiHashProcess(u32Checksum, pTail, RT_OFFSETOF(HGSMIBUFFERTAIL, u32Checksum));
+
+    return hgsmiHashEnd(u32Checksum);
+}
+
+int HGSMIAreaInitialize(HGSMIAREA *pArea,
+                        void *pvBase,
+                        HGSMISIZE cbArea,
+                        HGSMIOFFSET offBase)
+{
+    uint8_t *pu8Base = (uint8_t *)pvBase;
+
+    if (  !pArea                                   /* Check that the area: */
+        || cbArea < HGSMIBufferMinimumSize()       /* large enough; */
+        || pu8Base + cbArea < pu8Base              /* no address space wrap; */
+        || offBase > UINT32_C(0xFFFFFFFF) - cbArea /* area within the 32 bit space: offBase + cbMem <= 0xFFFFFFFF. */
+       )
+    {
+        return VERR_INVALID_PARAMETER;
+    }
+
+    pArea->pu8Base = pu8Base;
+    pArea->offBase = offBase;
+    pArea->offLast = cbArea - HGSMIBufferMinimumSize() + offBase;
+    pArea->cbArea = cbArea;
+
+    return VINF_SUCCESS;
+}
+
+void HGSMIAreaClear(HGSMIAREA *pArea)
+{
+    if (pArea)
+    {
+        RT_ZERO(*pArea);
+    }
+}
+
+/* Initialize the memory buffer including its checksum.
+ * No changes alloed to the header and the tail after that.
+ */
+HGSMIOFFSET HGSMIBufferInitializeSingle(const HGSMIAREA *pArea,
+                                        HGSMIBUFFERHEADER *pHeader,
+                                        HGSMISIZE cbBuffer,
+                                        uint8_t u8Channel,
+                                        uint16_t u16ChannelInfo)
+{
+    if (   !pArea
+        || !pHeader
+        || cbBuffer < HGSMIBufferMinimumSize())
+    {
+        return HGSMIOFFSET_VOID;
+    }
+
+    /* Buffer must be within the area:
+     *   * header data size do not exceed the maximum data size;
+     *   * buffer address is greater than the area base address;
+     *   * buffer address is lower than the maximum allowed for the given data size.
+     */
+    HGSMISIZE cbMaximumDataSize = pArea->offLast - pArea->offBase;
+    uint32_t u32DataSize = cbBuffer - HGSMIBufferMinimumSize();
+
+    if (   u32DataSize > cbMaximumDataSize
+        || (uint8_t *)pHeader < pArea->pu8Base
+        || (uint8_t *)pHeader > pArea->pu8Base + cbMaximumDataSize - u32DataSize)
+    {
+        return HGSMIOFFSET_VOID;
+    }
+
+    HGSMIOFFSET offBuffer = HGSMIPointerToOffset(pArea, pHeader);
+
+    pHeader->u8Flags        = HGSMI_BUFFER_HEADER_F_SEQ_SINGLE;
+    pHeader->u32DataSize    = u32DataSize;
+    pHeader->u8Channel      = u8Channel;
+    pHeader->u16ChannelInfo = u16ChannelInfo;
+    RT_ZERO(pHeader->u.au8Union);
+
+    HGSMIBUFFERTAIL *pTail = HGSMIBufferTailFromPtr(pHeader, u32DataSize);
+    pTail->u32Reserved = 0;
+    pTail->u32Checksum = HGSMIChecksum(offBuffer, pHeader, pTail);
+
+    return offBuffer;
+}
+
+int HGSMIHeapSetup(HGSMIHEAP *pHeap,
+                   void *pvBase,
+                   HGSMISIZE cbArea,
+                   HGSMIOFFSET offBase,
+                   const HGSMIENV *pEnv)
+{
+    AssertPtrReturn(pHeap, VERR_INVALID_PARAMETER);
+    AssertPtrReturn(pvBase, VERR_INVALID_PARAMETER);
+
+    int rc = HGSMIAreaInitialize(&pHeap->area, pvBase, cbArea, offBase);
+    if (RT_SUCCESS(rc))
+    {
+        rc = HGSMIMAInit(&pHeap->ma, &pHeap->area, NULL, 0, 0, pEnv);
+        if (RT_FAILURE(rc))
+        {
+            HGSMIAreaClear(&pHeap->area);
+        }
+    }
+
+    return rc;
+}
+
+void HGSMIHeapDestroy(HGSMIHEAP *pHeap)
+{
+    if (pHeap)
+    {
+        HGSMIMAUninit(&pHeap->ma);
+        RT_ZERO(*pHeap);
+    }
+}
+
+void *HGSMIHeapAlloc(HGSMIHEAP *pHeap,
+                     HGSMISIZE cbData,
+                     uint8_t u8Channel,
+                     uint16_t u16ChannelInfo)
+{
+    HGSMISIZE cbAlloc = HGSMIBufferRequiredSize(cbData);
+    HGSMIBUFFERHEADER *pHeader = (HGSMIBUFFERHEADER *)HGSMIHeapBufferAlloc(pHeap, cbAlloc);
+    if (pHeader)
+    {
+        HGSMIOFFSET offBuffer = HGSMIBufferInitializeSingle(HGSMIHeapArea(pHeap), pHeader,
+                                                            cbAlloc, u8Channel, u16ChannelInfo);
+        if (offBuffer == HGSMIOFFSET_VOID)
+        {
+            HGSMIHeapBufferFree(pHeap, pHeader);
+            pHeader = NULL;
+        }
+    }
+
+    return pHeader? HGSMIBufferDataFromPtr(pHeader): NULL;
+}
+
+void HGSMIHeapFree(HGSMIHEAP *pHeap,
+                   void *pvData)
+{
+    if (pvData)
+    {
+        HGSMIBUFFERHEADER *pHeader = HGSMIBufferHeaderFromData(pvData);
+        HGSMIHeapBufferFree(pHeap, pHeader);
+    }
+}
+
+void *HGSMIHeapBufferAlloc(HGSMIHEAP *pHeap,
+                           HGSMISIZE cbBuffer)
+{
+    void *pvBuf = HGSMIMAAlloc(&pHeap->ma, cbBuffer);
+    return pvBuf;
+}
+
+void HGSMIHeapBufferFree(HGSMIHEAP *pHeap,
+                         void *pvBuf)
+{
+    HGSMIMAFree(&pHeap->ma, pvBuf);
+}
+
+typedef struct HGSMIBUFFERCONTEXT
+{
+    const HGSMIBUFFERHEADER *pHeader; /* The original buffer header. */
+    void *pvData;                     /* Payload data in the buffer./ */
+    uint32_t cbData;                  /* Size of data  */
+} HGSMIBUFFERCONTEXT;
+
+/** Verify that the given offBuffer points to a valid buffer, which is within the area.
+ *
+ * @returns VBox status and the buffer information in pBufferContext.
+ * @param pArea          Area which supposed to contain the buffer.
+ * @param offBuffer      The buffer location in the area.
+ * @param pBufferContext Where to write information about the buffer.
+ */
+static int hgsmiVerifyBuffer(const HGSMIAREA *pArea,
+                             HGSMIOFFSET offBuffer,
+                             HGSMIBUFFERCONTEXT *pBufferContext)
+{
+    LogFlowFunc(("buffer 0x%x, area %p %x [0x%x;0x%x]\n",
+                 offBuffer, pArea->pu8Base, pArea->cbArea, pArea->offBase, pArea->offLast));
+
+    int rc = VINF_SUCCESS;
+
+    if (   offBuffer < pArea->offBase
+        || offBuffer > pArea->offLast)
+    {
+        LogFunc(("offset 0x%x is outside the area [0x%x;0x%x]!!!\n",
+                 offBuffer, pArea->offBase, pArea->offLast));
+        rc = VERR_INVALID_PARAMETER;
+        HGSMI_STRICT_ASSERT_FAILED();
+    }
+    else
+    {
+        void *pvBuffer = HGSMIOffsetToPointer(pArea, offBuffer);
+        HGSMIBUFFERHEADER header = *HGSMIBufferHeaderFromPtr(pvBuffer);
+
+        /* Quick check of the data size, it should be less than the maximum
+         * data size for the buffer at this offset.
+         */
+        LogFlowFunc(("datasize check: header.u32DataSize = 0x%x pArea->offLast - offBuffer = 0x%x\n",
+                     header.u32DataSize, pArea->offLast - offBuffer));
+
+        if (header.u32DataSize <= pArea->offLast - offBuffer)
+        {
+            HGSMIBUFFERTAIL tail = *HGSMIBufferTailFromPtr(pvBuffer, header.u32DataSize);
+
+            /* At least both header and tail structures are in the area. Check the checksum. */
+            uint32_t u32Checksum = HGSMIChecksum(offBuffer, &header, &tail);
+            LogFlowFunc(("checksum check: u32Checksum = 0x%x pTail->u32Checksum = 0x%x\n",
+                         u32Checksum, tail.u32Checksum));
+            if (u32Checksum == tail.u32Checksum)
+            {
+                /* Success. */
+                pBufferContext->pHeader = HGSMIBufferHeaderFromPtr(pvBuffer);
+                pBufferContext->pvData = HGSMIBufferDataFromPtr(pvBuffer);
+                pBufferContext->cbData = header.u32DataSize;
+            }
+            else
+            {
+                LogFunc(("invalid checksum 0x%x, expected 0x%x!!!\n",
+                         u32Checksum, tail.u32Checksum));
+                rc = VERR_INVALID_STATE;
+                HGSMI_STRICT_ASSERT_FAILED();
+            }
+        }
+        else
+        {
+            LogFunc(("invalid data size 0x%x, maximum is 0x%x!!!\n",
+                     header.u32DataSize, pArea->offLast - offBuffer));
+            rc = VERR_TOO_MUCH_DATA;
+            HGSMI_STRICT_ASSERT_FAILED();
+        }
+    }
+
+    return rc;
+}
+
+/** Helper to convert HGSMI channel index to the channel structure pointer.
+ *
+ * @returns Pointer to the channel data.
+ * @param pChannelInfo The channel pool.
+ * @param u8Channel    The channel index.
+ */
+HGSMICHANNEL *HGSMIChannelFindById(HGSMICHANNELINFO *pChannelInfo,
+                                   uint8_t u8Channel)
+{
+    AssertCompile(RT_ELEMENTS(pChannelInfo->Channels) >= 0x100);
+    HGSMICHANNEL *pChannel = &pChannelInfo->Channels[u8Channel];
+
+    if (pChannel->u8Flags & HGSMI_CH_F_REGISTERED)
+    {
+        return pChannel;
+    }
+
+    return NULL;
+}
+
+/** Process a guest buffer.
+ *
+ * @returns VBox status code.
+ * @param pArea        Area which supposed to contain the buffer.
+ * @param pChannelInfo The channel pool.
+ * @param offBuffer    The buffer location in the area.
+ */
+int HGSMIBufferProcess(const HGSMIAREA *pArea,
+                       HGSMICHANNELINFO *pChannelInfo,
+                       HGSMIOFFSET offBuffer)
+{
+    LogFlowFunc(("pArea %p, offBuffer 0x%x\n", pArea, offBuffer));
+
+    AssertPtrReturn(pArea, VERR_INVALID_PARAMETER);
+    AssertPtrReturn(pChannelInfo, VERR_INVALID_PARAMETER);
+
+    /* Guest has prepared a command description at 'offBuffer'. */
+    HGSMIBUFFERCONTEXT bufferContext;
+    int rc = hgsmiVerifyBuffer(pArea, offBuffer, &bufferContext);
+    if (RT_SUCCESS(rc))
+    {
+        /* Pass the command to the appropriate handler registered with this instance.
+         * Start with the handler list head, which is the preallocated HGSMI setup channel.
+         */
+        const HGSMICHANNEL *pChannel = HGSMIChannelFindById(pChannelInfo, bufferContext.pHeader->u8Channel);
+        if (pChannel)
+        {
+            const HGSMICHANNELHANDLER *pHandler = &pChannel->handler;
+            if (pHandler->pfnHandler)
+            {
+                pHandler->pfnHandler(pHandler->pvHandler, bufferContext.pHeader->u16ChannelInfo,
+                                     bufferContext.pvData, bufferContext.cbData);
+            }
+            HGSMI_STRICT_ASSERT(RT_SUCCESS(hgsmiVerifyBuffer(pArea, offBuffer, &bufferContext)));
+        }
+        else
+        {
+            rc = VERR_INVALID_FUNCTION;
+            HGSMI_STRICT_ASSERT_FAILED();
+        }
+    }
+
+    return rc;
+}
+
+/** Register a new HGSMI channel by index.
+ *
+ * @returns VBox status code.
+ * @param pChannelInfo      The channel pool managed by the caller.
+ * @param u8Channel         Index of the channel.
+ * @param pszName           Name of the channel (optional, allocated by the caller).
+ * @param pfnChannelHandler The channel callback.
+ * @param pvChannelHandler  The callback pointer.
+ */
+int HGSMIChannelRegister(HGSMICHANNELINFO *pChannelInfo,
+                         uint8_t u8Channel,
+                         const char *pszName,
+                         PFNHGSMICHANNELHANDLER pfnChannelHandler,
+                         void *pvChannelHandler)
+{
+    /* Check whether the channel is already registered. */
+    HGSMICHANNEL *pChannel = HGSMIChannelFindById(pChannelInfo, u8Channel);
+    if (pChannel)
+    {
+        HGSMI_STRICT_ASSERT_FAILED();
+        return VERR_ALREADY_EXISTS;
+    }
+
+    /* Channel is not yet registered. */
+    pChannel = &pChannelInfo->Channels[u8Channel];
+
+    pChannel->u8Flags = HGSMI_CH_F_REGISTERED;
+    pChannel->u8Channel = u8Channel;
+
+    pChannel->handler.pfnHandler = pfnChannelHandler;
+    pChannel->handler.pvHandler = pvChannelHandler;
+
+    pChannel->pszName = pszName;
+
+    return VINF_SUCCESS;
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/vboxvideo/HGSMIMemAlloc.c
@@ -0,0 +1,661 @@
+/* $Id: HGSMIMemAlloc.cpp $ */
+/** @file
+ * VBox Host Guest Shared Memory Interface (HGSMI) - Memory allocator.
+ */
+
+/*
+ * Copyright (C) 2014 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+/*
+ * Memory allocator
+ * ----------------
+ *
+ * Area [0; AreaSize) contains only the data, control structures are separate.
+ * Block sizes are power of 2: 32B, ..., 1MB
+ * Area size can be anything and will be divided initially to largest possible free blocks.
+ *
+ * The entire area is described by a list of 32 bit block descriptors:
+ *  * bits 0..3  - order, which is log2 size of the block - 5: 2^(0+5) ... 2^(15+5) == 32B .. 1MB
+ *  * bit  4     - 1 for free blocks.
+ *  * bits 5..31 - block offset.
+ *
+ * 31 ... 5 | 4 | 3 ... 0
+ *  offset    F   order
+ *
+ * There is a sorted collection of all block descriptors
+ * (key is the block offset, bits 0...4 do not interfere with sorting).
+ * Also there are lists of free blocks for each size for fast allocation.
+ *
+ *
+ * Implementation
+ * --------------
+ *
+ * The blocks collection is a sorted linear list.
+ *
+ * Initially the entire area consists of one or more largest blocks followed by smaller blocks:
+ *  * 100B area - 64B block with descriptor: 0x00000011
+ *                32B block with descriptor: 0x00000030
+ *                4B unused
+ *  * 64K area  - one 64K block with descriptor: 0x0000001C
+ *  * 512K area - one 512K block with descriptor: 0x0000001F
+ *
+ * When allocating a new block:
+ *  * larger free blocks are splitted when there are no smaller free blocks;
+ *  * smaller free blocks are merged if they can build a requested larger block.
+ */
+#include <VBox/HGSMI/HGSMIMemAlloc.h>
+#include <VBox/HGSMI/HGSMI.h>
+
+#include <iprt/err.h>
+#include <iprt/string.h>
+
+
+DECLINLINE(HGSMIOFFSET) hgsmiMADescriptor(HGSMIOFFSET off, bool fFree, HGSMIOFFSET order)
+{
+    return (off & HGSMI_MA_DESC_OFFSET_MASK) |
+           (fFree? HGSMI_MA_DESC_FREE_MASK: 0) |
+           (order & HGSMI_MA_DESC_ORDER_MASK);
+}
+
+static void hgsmiMABlockFree(HGSMIMADATA *pMA, HGSMIMABLOCK *pBlock)
+{
+    pMA->env.pfnFree(pMA->env.pvEnv, pBlock);
+}
+
+static int hgsmiMABlockAlloc(HGSMIMADATA *pMA, HGSMIMABLOCK **ppBlock)
+{
+    int rc = VINF_SUCCESS;
+
+    HGSMIMABLOCK *pBlock = (HGSMIMABLOCK *)pMA->env.pfnAlloc(pMA->env.pvEnv, sizeof(HGSMIMABLOCK));
+    if (pBlock)
+    {
+        RT_ZERO(pBlock->nodeBlock);
+        *ppBlock = pBlock;
+    }
+    else
+    {
+        rc = VERR_NO_MEMORY;
+    }
+
+    return rc;
+}
+
+/* Divide entire area to free blocks. */
+static int hgsmiMAFormat(HGSMIMADATA *pMA)
+{
+    int rc = VINF_SUCCESS;
+
+    /* Initial value, it will be updated in the loop below. */
+    pMA->cbMaxBlock = HGSMI_MA_BLOCK_SIZE_MIN;
+    pMA->cBlocks = 0;
+
+    HGSMISIZE cbBlock = HGSMI_MA_BLOCK_SIZE_MAX;
+    HGSMISIZE cbRemaining = pMA->area.cbArea;
+    HGSMIOFFSET off = 0;
+
+    while (cbBlock >= HGSMI_MA_BLOCK_SIZE_MIN)
+    {
+        /* Build a list of free memory blocks with u32BlockSize. */
+        uint32_t cBlocks = cbRemaining / cbBlock;
+        if (cBlocks > 0)
+        {
+            if (pMA->cbMaxBlock < cbBlock)
+            {
+                pMA->cbMaxBlock = cbBlock;
+            }
+
+            HGSMIOFFSET order = HGSMIMASize2Order(cbBlock);
+
+            uint32_t i;
+            for (i = 0; i < cBlocks; ++i)
+            {
+                /* A new free block. */
+                HGSMIMABLOCK *pBlock;
+                rc = hgsmiMABlockAlloc(pMA, &pBlock);
+                if (RT_FAILURE(rc))
+                {
+                    break;
+                }
+
+                pBlock->descriptor = hgsmiMADescriptor(off, true, order);
+                RTListAppend(&pMA->listBlocks, &pBlock->nodeBlock);
+                ++pMA->cBlocks;
+
+                off += cbBlock;
+                cbRemaining -= cbBlock;
+            }
+        }
+
+        if (RT_FAILURE(rc))
+        {
+            break;
+        }
+
+        cbBlock /= 2;
+    }
+
+    return rc;
+}
+
+static int hgsmiMARebuildFreeLists(HGSMIMADATA *pMA)
+{
+    int rc = VINF_SUCCESS;
+
+    HGSMIMABLOCK *pIter;
+    RTListForEach(&pMA->listBlocks, pIter, HGSMIMABLOCK, nodeBlock)
+    {
+        if (HGSMI_MA_DESC_IS_FREE(pIter->descriptor))
+        {
+            HGSMIOFFSET order = HGSMI_MA_DESC_ORDER(pIter->descriptor);
+            RTListAppend(&pMA->aListFreeBlocks[order], &pIter->nodeFree);
+        }
+    }
+
+    return rc;
+}
+
+static int hgsmiMARestore(HGSMIMADATA *pMA, HGSMIOFFSET *paDescriptors, uint32_t cDescriptors, HGSMISIZE cbMaxBlock)
+{
+    int rc = VINF_SUCCESS;
+
+    pMA->cbMaxBlock = cbMaxBlock;
+    pMA->cBlocks = 0;
+
+    HGSMISIZE cbRemaining = pMA->area.cbArea;
+    HGSMIOFFSET off = 0;
+
+    uint32_t i;
+    for (i = 0; i < cDescriptors; ++i)
+    {
+        /* Verify the descriptor. */
+        HGSMISIZE cbBlock = HGSMIMAOrder2Size(HGSMI_MA_DESC_ORDER(paDescriptors[i]));
+        if (   off != HGSMI_MA_DESC_OFFSET(paDescriptors[i])
+            || cbBlock > cbRemaining
+            || cbBlock > pMA->cbMaxBlock)
+        {
+            rc = VERR_INVALID_PARAMETER;
+            break;
+        }
+
+        /* A new free block. */
+        HGSMIMABLOCK *pBlock;
+        rc = hgsmiMABlockAlloc(pMA, &pBlock);
+        if (RT_FAILURE(rc))
+        {
+            break;
+        }
+
+        pBlock->descriptor = paDescriptors[i];
+        RTListAppend(&pMA->listBlocks, &pBlock->nodeBlock);
+        ++pMA->cBlocks;
+
+        off += cbBlock;
+        cbRemaining -= cbBlock;
+    }
+
+    return rc;
+}
+
+static HGSMIMABLOCK *hgsmiMAGetFreeBlock(HGSMIMADATA *pMA, HGSMIOFFSET order)
+{
+    HGSMIMABLOCK *pBlock = NULL;
+
+    HGSMIOFFSET i;
+    for (i = order; i < RT_ELEMENTS(pMA->aListFreeBlocks); ++i)
+    {
+        pBlock = RTListGetFirst(&pMA->aListFreeBlocks[i], HGSMIMABLOCK, nodeFree);
+        if (pBlock)
+        {
+            break;
+        }
+    }
+
+    if (pBlock)
+    {
+        AssertReturn(HGSMI_MA_DESC_IS_FREE(pBlock->descriptor), NULL);
+
+        /* Where the block starts. */
+        HGSMIOFFSET off = HGSMI_MA_DESC_OFFSET(pBlock->descriptor);
+
+        /* 'i' is the order of the block. */
+        while (i != order)
+        {
+            /* A larger block was found and need to be split to 2 smaller blocks. */
+            HGSMIMABLOCK *pBlock2;
+            int rc = hgsmiMABlockAlloc(pMA, &pBlock2);
+            if (RT_FAILURE(rc))
+            {
+                pBlock = NULL;
+                break;
+            }
+
+            /* Create 2 blocks with descreased order. */
+            --i;
+
+            /* Remove from the free list. */
+            RTListNodeRemove(&pBlock->nodeFree);
+
+            pBlock->descriptor = hgsmiMADescriptor(off, true, i);
+            pBlock2->descriptor = hgsmiMADescriptor(off + HGSMIMAOrder2Size(i), true, i);
+
+            /* Update list of all blocks by inserting pBlock2 after pBlock. */
+            RTListNodeInsertAfter(&pBlock->nodeBlock, &pBlock2->nodeBlock);
+            ++pMA->cBlocks;
+
+            /* Update the free list. */
+            RTListAppend(&pMA->aListFreeBlocks[i], &pBlock->nodeFree);
+            RTListAppend(&pMA->aListFreeBlocks[i], &pBlock2->nodeFree);
+        }
+    }
+
+    return pBlock;
+}
+
+static void hgsmiMAReformatFreeBlocks(HGSMIMADATA *pMA, HGSMIOFFSET maxId,
+                                      HGSMIMABLOCK *pStart, HGSMIMABLOCK *pEnd, HGSMISIZE cbBlocks)
+{
+    int rc = VINF_SUCCESS;
+
+    /*
+     * Blocks starting from pStart until pEnd will be replaced with
+     * another set of blocks.
+     *
+     * The new set will include the block with the required order.
+     * Since the required order is larger than any existing block,
+     * it will replace at least two existing blocks.
+     * The new set will also have minimal possible number of blocks.
+     * Therefore the new set will have at least one block less.
+     * Blocks will be updated in place and remaining blocks will be
+     * deallocated.
+     */
+
+    HGSMISIZE u32BlockSize = HGSMIMAOrder2Size(maxId);
+    HGSMISIZE cbRemaining = cbBlocks;
+    HGSMIOFFSET off = HGSMI_MA_DESC_OFFSET(pStart->descriptor);
+    HGSMIMABLOCK *pBlock = pStart;
+
+    while (u32BlockSize >= HGSMI_MA_BLOCK_SIZE_MIN && cbRemaining)
+    {
+        /* Build a list of free memory blocks with u32BlockSize. */
+        uint32_t cBlocks = cbRemaining / u32BlockSize;
+        if (cBlocks > 0)
+        {
+            HGSMIOFFSET order = HGSMIMASize2Order(u32BlockSize);
+
+            uint32_t i;
+            for (i = 0; i < cBlocks; ++i)
+            {
+                if (pBlock == pEnd)
+                {
+                    /* Should never happen because the new set of blocks is supposed to be smaller. */
+                    AssertFailed();
+                    rc = VERR_OUT_OF_RESOURCES;
+                    break;
+                }
+
+                /* Remove from the free list. */
+                RTListNodeRemove(&pBlock->nodeFree);
+
+                pBlock->descriptor = hgsmiMADescriptor(off, true, order);
+
+                RTListAppend(&pMA->aListFreeBlocks[order], &pBlock->nodeFree);
+
+                off += u32BlockSize;
+                cbRemaining -= u32BlockSize;
+
+                pBlock = RTListGetNext(&pMA->listBlocks, pBlock, HGSMIMABLOCK, nodeBlock);
+            }
+        }
+
+        if (RT_FAILURE(rc))
+        {
+            break;
+        }
+
+        u32BlockSize /= 2;
+    }
+
+    Assert(cbRemaining == 0);
+
+    if (RT_SUCCESS(rc))
+    {
+        /* Remove remaining free blocks from pBlock until pEnd */
+        for (;;)
+        {
+            bool fEnd = (pBlock == pEnd);
+            HGSMIMABLOCK *pNext = RTListGetNext(&pMA->listBlocks, pBlock, HGSMIMABLOCK, nodeBlock);
+
+            RTListNodeRemove(&pBlock->nodeFree);
+            RTListNodeRemove(&pBlock->nodeBlock);
+            --pMA->cBlocks;
+
+            hgsmiMABlockFree(pMA, pBlock);
+
+            if (fEnd)
+            {
+                break;
+            }
+
+            pBlock = pNext;
+        }
+    }
+}
+
+static void hgsmiMAQueryFreeRange(HGSMIMADATA *pMA, HGSMIMABLOCK *pBlock, HGSMISIZE cbRequired,
+                                  HGSMIMABLOCK **ppStart, HGSMIMABLOCK **ppEnd, HGSMISIZE *pcbBlocks)
+{
+    Assert(HGSMI_MA_DESC_IS_FREE(pBlock->descriptor));
+
+    *pcbBlocks = HGSMIMAOrder2Size(HGSMI_MA_DESC_ORDER(pBlock->descriptor));
+    *ppStart = pBlock;
+    *ppEnd = pBlock;
+
+    HGSMIMABLOCK *p;
+    for (;;)
+    {
+        p = RTListGetNext(&pMA->listBlocks, *ppEnd, HGSMIMABLOCK, nodeBlock);
+        if (!p || !HGSMI_MA_DESC_IS_FREE(p->descriptor))
+        {
+            break;
+        }
+        *pcbBlocks += HGSMIMAOrder2Size(HGSMI_MA_DESC_ORDER(p->descriptor));
+        *ppEnd = p;
+
+        if (cbRequired && *pcbBlocks >= cbRequired)
+        {
+            return;
+        }
+    }
+    for (;;)
+    {
+        p = RTListGetPrev(&pMA->listBlocks, *ppStart, HGSMIMABLOCK, nodeBlock);
+        if (!p || !HGSMI_MA_DESC_IS_FREE(p->descriptor))
+        {
+            break;
+        }
+        *pcbBlocks += HGSMIMAOrder2Size(HGSMI_MA_DESC_ORDER(p->descriptor));
+        *ppStart = p;
+
+        if (cbRequired && *pcbBlocks >= cbRequired)
+        {
+            return;
+        }
+    }
+}
+
+static void hgsmiMAMergeFreeBlocks(HGSMIMADATA *pMA, HGSMIOFFSET order)
+{
+    /* Try to create a free block with the order from smaller free blocks. */
+    if (order == 0)
+    {
+        /* No smaller blocks. */
+        return;
+    }
+
+    HGSMISIZE cbRequired = HGSMIMAOrder2Size(order);
+
+    /* Scan all free lists of smaller blocks.
+     *
+     * Get the sequence of free blocks before and after each free block.
+     * If possible, re-split the sequence to get the required block and other free block(s).
+     * If not possible, try the next free block.
+     *
+     * Free blocks are scanned from i to 0 orders.
+     */
+    HGSMIOFFSET i = order - 1;
+    for (;;)
+    {
+        HGSMIMABLOCK *pIter;
+        RTListForEach(&pMA->aListFreeBlocks[i], pIter, HGSMIMABLOCK, nodeFree)
+        {
+            Assert(HGSMI_MA_DESC_ORDER(pIter->descriptor) == i);
+
+            HGSMISIZE cbBlocks;
+            HGSMIMABLOCK *pFreeStart;
+            HGSMIMABLOCK *pFreeEnd;
+            hgsmiMAQueryFreeRange(pMA, pIter, cbRequired, &pFreeStart, &pFreeEnd, &cbBlocks);
+
+            Assert((cbBlocks / HGSMI_MA_BLOCK_SIZE_MIN) * HGSMI_MA_BLOCK_SIZE_MIN == cbBlocks);
+
+            /* Verify whether cbBlocks is enough for the requested block. */
+            if (cbBlocks >= cbRequired)
+            {
+                /* Build new free blocks starting from the requested. */
+                hgsmiMAReformatFreeBlocks(pMA, order, pFreeStart, pFreeEnd, cbBlocks);
+                i = 0; /* Leave the loop. */
+                break;
+            }
+        }
+
+        if (i == 0)
+        {
+            break;
+        }
+
+        --i;
+    }
+}
+
+static HGSMIOFFSET hgsmiMAAlloc(HGSMIMADATA *pMA, HGSMISIZE cb)
+{
+    if (cb > pMA->cbMaxBlock)
+    {
+        return HGSMIOFFSET_VOID;
+    }
+
+    if (cb < HGSMI_MA_BLOCK_SIZE_MIN)
+    {
+        cb = HGSMI_MA_BLOCK_SIZE_MIN;
+    }
+
+    HGSMIOFFSET order = HGSMIPopCnt32(cb - 1) - HGSMI_MA_DESC_ORDER_BASE;
+
+    AssertReturn(HGSMIMAOrder2Size(order) >= cb, HGSMIOFFSET_VOID);
+    AssertReturn(order < RT_ELEMENTS(pMA->aListFreeBlocks), HGSMIOFFSET_VOID);
+
+    HGSMIMABLOCK *pBlock = hgsmiMAGetFreeBlock(pMA, order);
+    if (RT_UNLIKELY(pBlock == NULL))
+    {
+        /* No free block with large enough size. Merge smaller free blocks and try again. */
+        hgsmiMAMergeFreeBlocks(pMA, order);
+        pBlock = hgsmiMAGetFreeBlock(pMA, order);
+    }
+
+    if (RT_LIKELY(pBlock != NULL))
+    {
+        RTListNodeRemove(&pBlock->nodeFree);
+        pBlock->descriptor &= ~HGSMI_MA_DESC_FREE_MASK;
+        return HGSMI_MA_DESC_OFFSET(pBlock->descriptor);
+    }
+
+    return HGSMIOFFSET_VOID;
+}
+
+static void hgsmiMAFree(HGSMIMADATA *pMA, HGSMIOFFSET off)
+{
+    if (off == HGSMIOFFSET_VOID)
+    {
+        return;
+    }
+
+    /* Find the block corresponding to the offset. */
+    Assert((off / HGSMI_MA_BLOCK_SIZE_MIN) * HGSMI_MA_BLOCK_SIZE_MIN == off);
+
+    HGSMIMABLOCK *pBlock = HGSMIMASearchOffset(pMA, off);
+    if (pBlock)
+    {
+        if (HGSMI_MA_DESC_OFFSET(pBlock->descriptor) == off)
+        {
+            /* Found the right block, mark it as free. */
+            pBlock->descriptor |= HGSMI_MA_DESC_FREE_MASK;
+            RTListAppend(&pMA->aListFreeBlocks[HGSMI_MA_DESC_ORDER(pBlock->descriptor)], &pBlock->nodeFree);
+            return;
+        }
+    }
+
+    AssertFailed();
+}
+
+int HGSMIMAInit(HGSMIMADATA *pMA, const HGSMIAREA *pArea,
+                HGSMIOFFSET *paDescriptors, uint32_t cDescriptors, HGSMISIZE cbMaxBlock,
+                const HGSMIENV *pEnv)
+{
+    AssertReturn(pArea->cbArea < UINT32_C(0x80000000), VERR_INVALID_PARAMETER);
+    AssertReturn(pArea->cbArea >= HGSMI_MA_BLOCK_SIZE_MIN, VERR_INVALID_PARAMETER);
+
+    RT_ZERO(*pMA);
+
+    HGSMISIZE cb = (pArea->cbArea / HGSMI_MA_BLOCK_SIZE_MIN) * HGSMI_MA_BLOCK_SIZE_MIN;
+
+    int rc = HGSMIAreaInitialize(&pMA->area, pArea->pu8Base, cb, 0);
+    if (RT_SUCCESS(rc))
+    {
+        pMA->env = *pEnv;
+
+        uint32_t i;
+        for (i = 0; i < RT_ELEMENTS(pMA->aListFreeBlocks); ++i)
+        {
+            RTListInit(&pMA->aListFreeBlocks[i]);
+        }
+        RTListInit(&pMA->listBlocks);
+
+        if (cDescriptors)
+        {
+            rc = hgsmiMARestore(pMA, paDescriptors, cDescriptors, cbMaxBlock);
+        }
+        else
+        {
+            rc = hgsmiMAFormat(pMA);
+        }
+
+        if (RT_SUCCESS(rc))
+        {
+            rc = hgsmiMARebuildFreeLists(pMA);
+        }
+    }
+
+    return rc;
+}
+
+void HGSMIMAUninit(HGSMIMADATA *pMA)
+{
+    HGSMIMABLOCK *pIter;
+    HGSMIMABLOCK *pNext;
+
+    RTListForEachSafe(&pMA->listBlocks, pIter, pNext, HGSMIMABLOCK, nodeBlock)
+    {
+        RTListNodeRemove(&pIter->nodeBlock);
+        hgsmiMABlockFree(pMA, pIter);
+    }
+
+    RT_ZERO(*pMA);
+}
+
+HGSMIOFFSET HGSMIMAPointerToOffset(const HGSMIMADATA *pMA, const void *pv)
+{
+    if (HGSMIAreaContainsPointer(&pMA->area, pv))
+    {
+        return HGSMIPointerToOffset(&pMA->area, pv);
+    }
+
+    AssertFailed();
+    return HGSMIOFFSET_VOID;
+}
+
+void *HGSMIMAOffsetToPointer(const HGSMIMADATA *pMA, HGSMIOFFSET off)
+{
+    if (HGSMIAreaContainsOffset(&pMA->area, off))
+    {
+        return HGSMIOffsetToPointer(&pMA->area, off);
+    }
+
+    AssertFailed();
+    return NULL;
+}
+
+void *HGSMIMAAlloc(HGSMIMADATA *pMA, HGSMISIZE cb)
+{
+    HGSMIOFFSET off = hgsmiMAAlloc(pMA, cb);
+    return HGSMIMAOffsetToPointer(pMA, off);
+}
+
+void HGSMIMAFree(HGSMIMADATA *pMA, void *pv)
+{
+    HGSMIOFFSET off = HGSMIMAPointerToOffset(pMA, pv);
+    if (off != HGSMIOFFSET_VOID)
+    {
+        hgsmiMAFree(pMA, off);
+    }
+    else
+    {
+        AssertFailed();
+    }
+}
+
+HGSMIMABLOCK *HGSMIMASearchOffset(HGSMIMADATA *pMA, HGSMIOFFSET off)
+{
+    /* Binary search in the block list for the offset. */
+    HGSMIMABLOCK *pStart = RTListGetFirst(&pMA->listBlocks, HGSMIMABLOCK, nodeBlock);
+    HGSMIMABLOCK *pEnd = RTListGetLast(&pMA->listBlocks, HGSMIMABLOCK, nodeBlock);
+    HGSMIMABLOCK *pMiddle;
+
+    uint32_t iStart = 0;
+    uint32_t iEnd = pMA->cBlocks;
+    uint32_t iMiddle;
+
+    for (;;)
+    {
+        pMiddle = pStart;
+        iMiddle = iStart + (iEnd - iStart) / 2;
+        if (iMiddle == iStart)
+        {
+            break;
+        }
+
+        /* Find the block with the iMiddle index. Never go further than pEnd. */
+        uint32_t i;
+        for (i = iStart; i < iMiddle && pMiddle != pEnd; ++i)
+        {
+            pMiddle = RTListNodeGetNext(&pMiddle->nodeBlock, HGSMIMABLOCK, nodeBlock);
+        }
+
+        HGSMIOFFSET offMiddle = HGSMI_MA_DESC_OFFSET(pMiddle->descriptor);
+        if (offMiddle > off)
+        {
+            pEnd = pMiddle;
+            iEnd = iMiddle;
+        }
+        else
+        {
+            pStart = pMiddle;
+            iStart = iMiddle;
+        }
+    }
+
+    return pMiddle;
+}
+
+
+/*
+ * Helper.
+ */
+
+uint32_t HGSMIPopCnt32(uint32_t u32)
+{
+    uint32_t c = 0;
+    if (u32 > 0xFFFF) { c += 16;  u32 >>= 16; }
+    if (u32 > 0xFF)   { c += 8;   u32 >>= 8;  }
+    if (u32 > 0xF)    { c += 4;   u32 >>= 4;  }
+    if (u32 > 0x3)    { c += 2;   u32 >>= 2;  }
+    if (u32 > 0x1)    { c += 1;   u32 >>= 1;  }
+    return c + u32;
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/vboxvideo/Makefile
@@ -0,0 +1,58 @@
+KBUILD_EXTMOD=${srctree}/ubuntu/vbox
+# $Id: Makefile.module.kms $
+## @file
+# VirtualBox Guest Additions Module Makefile.
+#
+# (For 2.6.x this file must be 'Makefile'!)
+#
+
+#
+# Copyright (C) 2006-2010 Oracle Corporation
+#
+# This file is part of VirtualBox Open Source Edition (OSE), as
+# available from http://www.virtualbox.org. This file is free software;
+# you can redistribute it and/or modify it under the terms of the GNU
+# General Public License (GPL) as published by the Free Software
+# Foundation, in version 2 as it comes in the "COPYING" file of the
+# VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+# hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+#
+
+# Linux kbuild sets this to our source directory if we are called from there
+obj ?= $(CURDIR)
+include $(obj)/Makefile.include.header
+
+MOD_NAME   = vboxvideo
+
+ifeq ($(filter 1.% 2.% 3.0.% 3.1.% 3.2.% 3.3.% 3.4.% 3.5.% 3.6.% 3.7.% \
+3.8.% 3.9.% 3.10.%,$(KERNELRELEASE)),)
+MOD_OBJS   = HGSMIBase.o HGSMICommon.o HGSMIMemAlloc.o heapoffset.o \
+             Modesetting.o vbox_drv.o vbox_fb.o vbox_irq.o vbox_main.o \
+             vbox_mode.o vbox_ttm.o VBVABase.o
+else
+MOD_OBJS   = vbox_dummy.o
+endif
+
+ifneq ($(wildcard $(KBUILD_EXTMOD)/vboxvideo),)
+ MANGLING := $(KBUILD_EXTMOD)/vboxvideo/include/VBox/VBoxGuestMangling.h
+else
+ MANGLING := $(KBUILD_EXTMOD)/include/VBox/VBoxGuestMangling.h
+endif
+MOD_CFLAGS = -Wno-declaration-after-statement -fshort-wchar -include $(MANGLING)
+MOD_INCL   = $(addprefix -I$(KBUILD_EXTMOD),/ /include)
+# What on earth is this?
+MOD_INCL  += $(addprefix -I$(KBUILD_EXTMOD)/vboxvideo,/ /include)
+MOD_INCL  += -Iinclude/drm
+MOD_DEFS  := -DRT_OS_LINUX -DIN_RING0 -DIN_RT_R0 \
+	     -DIN_SUP_R0 -DVBOX -DVBOX_WITH_HGCM -DLOG_TO_BACKDOOR -DIN_MODULE \
+	     -DIN_GUEST_R0
+# our module does not export any symbol
+MOD_DEFS  += -DRT_NO_EXPORT_SYMBOL
+ifeq ($(BUILD_TARGET_ARCH),amd64)
+ MOD_DEFS += -DRT_ARCH_AMD64 -DVBOX_WITH_64_BITS_GUESTS
+else
+ MOD_DEFS += -DRT_ARCH_X86
+endif
+MOD_CLEAN  = . linux r0drv r0drv/linux
+
+include $(obj)/Makefile.include.footer
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/vboxvideo/Makefile.include.footer
@@ -0,0 +1,96 @@
+#
+# VirtualBox Guest Additions kernel module Makefile, common parts.
+#
+# See Makefile.include.header for details of how to use this.
+#
+# Copyright (C) 2006-2015 Oracle Corporation
+#
+# This file is part of VirtualBox Open Source Edition (OSE), as
+# available from http://www.virtualbox.org. This file is free software;
+# you can redistribute it and/or modify it under the terms of the GNU
+# General Public License (GPL) as published by the Free Software
+# Foundation, in version 2 as it comes in the "COPYING" file of the
+# VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+# hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+#
+
+# override is required by the Debian guys
+override MODULE = $(MOD_NAME)
+OBJS   = $(MOD_OBJS)
+
+ifneq ($(MAKECMDGOALS),clean)
+
+KBUILD_VERBOSE ?= 1
+
+#
+# Compiler options
+#
+ifndef INCL
+ INCL    := $(addprefix -I,$(KERN_INCL) $(EXTRA_INCL))
+ ifndef KBUILD_EXTMOD
+  KBUILD_EXTMOD := $(shell pwd)
+ endif
+ INCL    += $(MOD_INCL)
+ export INCL
+endif
+KFLAGS   := -D__KERNEL__ -DMODULE $(MOD_DEFS)
+ifeq ($(BUILD_TYPE),debug)
+ KFLAGS  += -DDEBUG -DDEBUG_$(subst $(subst _, ,_),_,$(USERNAME)) -DDEBUG_USERNAME=$(subst $(subst _, ,_),_,$(USERNAME))
+endif
+
+ifeq ($(KERN_VERSION), 24)
+#
+# 2.4
+#
+
+ifeq ($(BUILD_TARGET_ARCH),amd64)
+ KFLAGS  += -mcmodel=kernel
+endif
+
+CFLAGS := -O2 -DVBOX_LINUX_2_4 $(MOD_CFLAGS) $(INCL) $(KFLAGS) $(MOD_EXTRA) $(KDEBUG)
+MODULE_EXT := o
+
+# 2.4 Module linking
+$(MODULE).o: $(OBJS)
+	$(LD) -o $@ -r $(OBJS)
+
+.PHONY: $(MODULE)
+all: $(MODULE)
+$(MODULE): $(MODULE).o
+
+else
+#
+# 2.6 and later
+#
+
+MODULE_EXT := ko
+
+$(MODULE)-y  := $(OBJS)
+
+# build defs
+EXTRA_CFLAGS += $(MOD_CFLAGS) $(INCL) $(KFLAGS) $(MOD_EXTRA) $(KDEBUG)
+
+all: $(MODULE)
+
+obj-m += $(MODULE).o
+
+# OL/UEK: disable module signing for external modules -- we don't have any private key
+$(MODULE):
+	$(MAKE) KBUILD_VERBOSE=$(KBUILD_VERBOSE) CONFIG_MODULE_SIG= -C $(KERN_DIR) SUBDIRS=$(CURDIR) SRCROOT=$(CURDIR) modules
+
+modules_install:
+	$(MAKE) KBUILD_VERBOSE=$(KBUILD_VERBOSE) CONFIG_MODULE_SIG= -C $(KERN_DIR) SUBDIRS=$(CURDIR) SRCROOT=$(CURDIR) modules_install
+
+endif
+
+install: $(MODULE)
+	@mkdir -p $(MODULE_DIR); \
+	install -m 0644 -o root -g root $(MODULE).$(MODULE_EXT) $(MODULE_DIR); \
+	PATH="$(PATH):/bin:/sbin" depmod -a;
+
+endif # eq($(MAKECMDGOALS),clean)
+
+# important: Don't remove Module.symvers! DKMS does 'make clean' before building ...
+clean:
+	for f in $(MOD_CLEAN); do rm -f $$f/*.o $$f/.*.cmd $$f/.*.flags; done
+	rm -rf .$(MOD_NAME)* .tmp_ver* $(MOD_NAME).* Modules.symvers modules.order
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/vboxvideo/Makefile.include.header
@@ -0,0 +1,173 @@
+#
+# VirtualBox Guest Additions kernel module Makefile, common parts.
+#
+# (For 2.6.x, the main file must be called 'Makefile'!)
+#
+# Copyright (C) 2006-2015 Oracle Corporation
+#
+# This file is part of VirtualBox Open Source Edition (OSE), as
+# available from http://www.virtualbox.org. This file is free software;
+# you can redistribute it and/or modify it under the terms of the GNU
+# General Public License (GPL) as published by the Free Software
+# Foundation, in version 2 as it comes in the "COPYING" file of the
+# VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+# hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+#
+
+#
+# These file should be included by the Makefiles for any kernel modules we
+# build as part of the Guest Additions.  The intended way of doing this is as
+# follows:
+#
+# # Linux kbuild sets this to our source directory if we are called from
+# # there
+# obj ?= $(CURDIR)
+# include $(obj)/Makefile.include.header
+# MOD_NAME = <name of the module to be built, without extension>
+# MOD_OBJS = <list of object files which should be included>
+# MOD_DEFS = <any additional defines which this module needs>
+# MOD_INCL = <any additional include paths which this module needs>
+# MOD_CFLAGS = <any additional CFLAGS which this module needs>
+# MOD_CLEAN = <list of directories that the clean target should look at>
+# include $(obj)/Makefile.include.footer
+#
+# The kmk kBuild define KBUILD_TARGET_ARCH is available.
+#
+
+
+#
+# First, figure out which architecture we're targeting and the build type.
+# (We have to support basic cross building (ARCH=i386|x86_64).)
+# While at it, warn about BUILD_* vars found to help with user problems.
+#
+ifeq ($(filter-out x86_64 amd64 AMD64,$(shell uname -m)),)
+ BUILD_TARGET_ARCH_DEF := amd64
+else
+ BUILD_TARGET_ARCH_DEF := x86
+endif
+ifneq ($(filter-out amd64 x86,$(BUILD_TARGET_ARCH)),)
+ $(warning Ignoring unknown BUILD_TARGET_ARCH value '$(BUILD_TARGET_ARCH)'.)
+ BUILD_TARGET_ARCH :=
+endif
+ifeq ($(BUILD_TARGET_ARCH),)
+ ifeq ($(ARCH),x86_64)
+  BUILD_TARGET_ARCH := amd64
+ else
+  ifeq ($(ARCH),i386)
+   ifeq ($(CONFIG_X86_32),y)
+     BUILD_TARGET_ARCH := x86
+   else
+     BUILD_TARGET_ARCH := amd64
+   endif
+  else
+    ifeq ($(ARCH),x86)
+      ifeq ($(CONFIG_X86_32),y)
+        BUILD_TARGET_ARCH := x86
+      else
+        BUILD_TARGET_ARCH := amd64
+      endif
+    else
+      BUILD_TARGET_ARCH := $(BUILD_TARGET_ARCH_DEF)
+    endif
+  endif
+ endif
+else
+ ifneq ($(BUILD_TARGET_ARCH),$(BUILD_TARGET_ARCH_DEF))
+  $(warning Using BUILD_TARGET_ARCH='$(BUILD_TARGET_ARCH)' from the $(origin BUILD_TARGET_ARCH).)
+ endif
+endif
+
+ifneq ($(filter-out release profile debug strict,$(BUILD_TYPE)),)
+ $(warning Ignoring unknown BUILD_TYPE value '$(BUILD_TYPE)'.)
+ BUILD_TYPE :=
+endif
+ifeq ($(BUILD_TYPE),)
+ BUILD_TYPE := release
+else
+ ifneq ($(BUILD_TYPE),release)
+  $(warning Using BUILD_TYPE='$(BUILD_TYPE)' from the $(origin BUILD_TYPE).)
+ endif
+endif
+ifeq ($(USERNAME),)
+ USERNAME := noname
+endif
+
+ifneq ($(MAKECMDGOALS),clean)
+
+ifeq ($(KERNELRELEASE),)
+
+ #
+ # building from this directory
+ #
+
+ # kernel base directory
+ ifndef KERN_DIR
+  KERN_DIR := /lib/modules/$(shell uname -r)/build
+  ifneq ($(shell if test -d $(KERN_DIR); then echo yes; fi),yes)
+   KERN_DIR := /usr/src/linux
+   ifneq ($(shell if test -d $(KERN_DIR); then echo yes; fi),yes)
+    $(error Error: unable to find the sources of your current Linux kernel. \
+	           Specify KERN_DIR=<directory> and run Make again)
+   endif
+   $(warning Warning: using /usr/src/linux as the source directory of your \
+                      Linux kernel. If this is not correct, specify \
+		      KERN_DIR=<directory> and run Make again.)
+  endif
+ else
+  ifneq ($(shell if test -d $(KERN_DIR); then echo yes; fi),yes)
+   $(error Error: KERN_DIR does not point to a directory)
+  endif
+ endif
+
+ # includes
+ ifndef KERN_INCL
+  KERN_INCL = $(KERN_DIR)/include
+ endif
+ ifneq ($(shell if test -d $(KERN_INCL); then echo yes; fi),yes)
+  $(error Error: unable to find the include directory for your current Linux \
+                 kernel. Specify KERN_INCL=<directory> and run Make again)
+ endif
+
+ # module install dir, only for current kernel
+ ifneq ($(filter install install_rpm,$(MAKECMDGOALS)),)
+  ifndef MODULE_DIR
+   MODULE_DIR_TST := /lib/modules/$(shell uname -r)
+   ifeq ($(shell if test -d $(MODULE_DIR_TST); then echo yes; fi),yes)
+    MODULE_DIR := $(MODULE_DIR_TST)/misc
+   else
+    $(error Unable to find the folder to install the module to)
+   endif
+  endif # MODULE_DIR unspecified
+ endif
+
+ # guess kernel version (24 or 26)
+ ifeq ($(shell if grep '"2\.4\.' $(KERN_INCL)/linux/version.h > /dev/null; then echo yes; fi),yes)
+  KERN_VERSION := 24
+ else
+  KERN_VERSION := 26
+ endif
+
+else # neq($(KERNELRELEASE),)
+
+ #
+ # building from kbuild (make -C <kernel_directory> M=`pwd`)
+ #
+
+ # guess kernel version (24 or 26)
+ ifeq ($(shell if echo "$(VERSION).$(PATCHLEVEL)." | grep '2\.4\.' > /dev/null; then echo yes; fi),yes)
+  KERN_VERSION := 24
+ else
+  KERN_VERSION := 26
+ endif
+
+endif # neq($(KERNELRELEASE),)
+
+# debug - show guesses.
+ifdef DEBUG
+$(warning dbg: KERN_DIR     = $(KERN_DIR))
+$(warning dbg: KERN_INCL    = $(KERN_INCL))
+$(warning dbg: MODULE_DIR   = $(MODULE_DIR))
+$(warning dbg: KERN_VERSION = $(KERN_VERSION))
+endif
+
+endif # eq($(MAKECMDGOALS),clean)
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/vboxvideo/Modesetting.c
@@ -0,0 +1,380 @@
+/* $Id: Modesetting.cpp $ */
+/** @file
+ * VirtualBox Video driver, common code - HGSMI initialisation and helper
+ * functions.
+ */
+
+/*
+ * Copyright (C) 2006-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+#include <VBox/VBoxVideoGuest.h>
+#include <VBox/VBoxVideo.h>
+#include <VBox/VBoxGuest.h>
+#include <VBox/Hardware/VBoxVideoVBE.h>
+#include <VBox/VMMDev.h>
+
+#include <iprt/asm.h>
+#include <iprt/log.h>
+
+#ifndef VBOX_GUESTR3XF86MOD
+# include <iprt/string.h>
+#endif
+
+/**
+ * Gets the count of virtual monitors attached to the guest via an HGSMI
+ * command
+ *
+ * @returns the right count on success or 1 on failure.
+ * @param  pCtx  the context containing the heap to use
+ */
+RTDECL(uint32_t) VBoxHGSMIGetMonitorCount(PHGSMIGUESTCOMMANDCONTEXT pCtx)
+{
+    /* Query the configured number of displays. */
+    uint32_t cDisplays = 0;
+    VBoxQueryConfHGSMI(pCtx, VBOX_VBVA_CONF32_MONITOR_COUNT, &cDisplays);
+    LogFunc(("cDisplays = %d\n", cDisplays));
+    if (cDisplays == 0 || cDisplays > VBOX_VIDEO_MAX_SCREENS)
+        /* Host reported some bad value. Continue in the 1 screen mode. */
+        cDisplays = 1;
+    return cDisplays;
+}
+
+
+/**
+ * Returns the size of the video RAM in bytes.
+ *
+ * @returns the size
+ */
+RTDECL(uint32_t) VBoxVideoGetVRAMSize(void)
+{
+    /** @note A 32bit read on this port returns the VRAM size. */
+    return VBoxVideoCmnPortReadUlong(VBE_DISPI_IOPORT_DATA);
+}
+
+
+/**
+ * Check whether this hardware allows the display width to have non-multiple-
+ * of-eight values.
+ *
+ * @returns true if any width is allowed, false otherwise.
+ */
+RTDECL(bool) VBoxVideoAnyWidthAllowed(void)
+{
+    unsigned DispiId;
+    VBoxVideoCmnPortWriteUshort(VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_ID);
+    VBoxVideoCmnPortWriteUshort(VBE_DISPI_IOPORT_DATA, VBE_DISPI_ID_ANYX);
+    DispiId = VBoxVideoCmnPortReadUshort(VBE_DISPI_IOPORT_DATA);
+    return (DispiId == VBE_DISPI_ID_ANYX);
+}
+
+
+/**
+ * Tell the host about how VRAM is divided up between each screen via an HGSMI
+ * command.  It is acceptable to specifiy identical data for each screen if
+ * they share a single framebuffer.
+ *
+ * @returns iprt status code, either VERR_NO_MEMORY or the status returned by
+ *          @a pfnFill
+ * @todo  What was I thinking of with that callback function?  It
+ *        would be much simpler to just pass in a structure in normal
+ *        memory and copy it.
+ * @param  pCtx      the context containing the heap to use
+ * @param  u32Count  the number of screens we are activating
+ * @param  pfnFill   a callback which initialises the VBVAINFOVIEW structures
+ *                   for all screens
+ * @param  pvData    context data for @a pfnFill
+ */
+RTDECL(int) VBoxHGSMISendViewInfo(PHGSMIGUESTCOMMANDCONTEXT pCtx,
+                                  uint32_t u32Count,
+                                  PFNHGSMIFILLVIEWINFO pfnFill,
+                                  void *pvData)
+{
+    int rc;
+    /* Issue the screen info command. */
+    void *p = VBoxHGSMIBufferAlloc(pCtx, sizeof(VBVAINFOVIEW) * u32Count,
+                                   HGSMI_CH_VBVA, VBVA_INFO_VIEW);
+    if (p)
+    {
+        VBVAINFOVIEW *pInfo = (VBVAINFOVIEW *)p;
+        rc = pfnFill(pvData, pInfo, u32Count);
+        if (RT_SUCCESS(rc))
+            VBoxHGSMIBufferSubmit (pCtx, p);
+        VBoxHGSMIBufferFree(pCtx, p);
+    }
+    else
+        rc = VERR_NO_MEMORY;
+    return rc;
+}
+
+
+/**
+ * Set a video mode using port registers.  This must be done for the first
+ * screen before every HGSMI modeset and also works when HGSM is not enabled.
+ * @param  cWidth      the mode width
+ * @param  cHeight     the mode height
+ * @param  cVirtWidth  the mode pitch
+ * @param  cBPP        the colour depth of the mode
+ * @param  fFlags      flags for the mode.  These will be or-ed with the
+ *                     default _ENABLED flag, so unless you are restoring
+ *                     a saved mode or have special requirements you can pass
+ *                     zero here.
+ * @param  cx          the horizontal panning offset
+ * @param  cy          the vertical panning offset
+ */
+RTDECL(void) VBoxVideoSetModeRegisters(uint16_t cWidth, uint16_t cHeight,
+                                       uint16_t cVirtWidth, uint16_t cBPP,
+                                       uint16_t fFlags, uint16_t cx,
+                                       uint16_t cy)
+{
+    /* set the mode characteristics */
+    VBoxVideoCmnPortWriteUshort(VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_XRES);
+    VBoxVideoCmnPortWriteUshort(VBE_DISPI_IOPORT_DATA, cWidth);
+    VBoxVideoCmnPortWriteUshort(VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_YRES);
+    VBoxVideoCmnPortWriteUshort(VBE_DISPI_IOPORT_DATA, cHeight);
+    VBoxVideoCmnPortWriteUshort(VBE_DISPI_IOPORT_INDEX,
+                                VBE_DISPI_INDEX_VIRT_WIDTH);
+    VBoxVideoCmnPortWriteUshort(VBE_DISPI_IOPORT_DATA, cVirtWidth);
+    VBoxVideoCmnPortWriteUshort(VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_BPP);
+    VBoxVideoCmnPortWriteUshort(VBE_DISPI_IOPORT_DATA, cBPP);
+    /* enable the mode */
+    VBoxVideoCmnPortWriteUshort(VBE_DISPI_IOPORT_INDEX,
+                                VBE_DISPI_INDEX_ENABLE);
+    VBoxVideoCmnPortWriteUshort(VBE_DISPI_IOPORT_DATA,
+                                fFlags | VBE_DISPI_ENABLED);
+    /* Panning registers */
+    VBoxVideoCmnPortWriteUshort(VBE_DISPI_IOPORT_INDEX,
+                                VBE_DISPI_INDEX_X_OFFSET);
+    VBoxVideoCmnPortWriteUshort(VBE_DISPI_IOPORT_DATA, cx);
+    VBoxVideoCmnPortWriteUshort(VBE_DISPI_IOPORT_INDEX,
+                                VBE_DISPI_INDEX_Y_OFFSET);
+    VBoxVideoCmnPortWriteUshort(VBE_DISPI_IOPORT_DATA, cy);
+    /** @todo read from the port to see if the mode switch was successful */
+}
+
+
+/**
+ * Get the video mode for the first screen using the port registers.  All
+ * parameters are optional
+ * @returns  true if the VBE mode returned is active, false if we are in VGA
+ *           mode
+ * @note  If anyone else needs additional register values just extend the
+ *        function with additional parameters and fix any existing callers.
+ * @param  pcWidth      where to store the mode width
+ * @param  pcHeight     where to store the mode height
+ * @param  pcVirtWidth  where to store the mode pitch
+ * @param  pcBPP        where to store the colour depth of the mode
+ * @param  pfFlags      where to store the flags for the mode
+ */
+RTDECL(bool) VBoxVideoGetModeRegisters(uint16_t *pcWidth, uint16_t *pcHeight,
+                                       uint16_t *pcVirtWidth, uint16_t *pcBPP,
+                                       uint16_t *pfFlags)
+{
+    uint16_t fFlags;
+
+    VBoxVideoCmnPortWriteUshort(VBE_DISPI_IOPORT_INDEX,
+                                VBE_DISPI_INDEX_ENABLE);
+    fFlags = VBoxVideoCmnPortReadUshort(VBE_DISPI_IOPORT_DATA);
+    if (pcWidth)
+    {
+        VBoxVideoCmnPortWriteUshort(VBE_DISPI_IOPORT_INDEX,
+                                    VBE_DISPI_INDEX_XRES);
+        *pcWidth = VBoxVideoCmnPortReadUshort(VBE_DISPI_IOPORT_DATA);
+    }
+    if (pcHeight)
+    {
+        VBoxVideoCmnPortWriteUshort(VBE_DISPI_IOPORT_INDEX,
+                                    VBE_DISPI_INDEX_YRES);
+        *pcHeight = VBoxVideoCmnPortReadUshort(VBE_DISPI_IOPORT_DATA);
+    }
+    if (pcVirtWidth)
+    {
+        VBoxVideoCmnPortWriteUshort(VBE_DISPI_IOPORT_INDEX,
+                                    VBE_DISPI_INDEX_VIRT_WIDTH);
+        *pcVirtWidth = VBoxVideoCmnPortReadUshort(VBE_DISPI_IOPORT_DATA);
+    }
+    if (pcBPP)
+    {
+        VBoxVideoCmnPortWriteUshort(VBE_DISPI_IOPORT_INDEX,
+                                    VBE_DISPI_INDEX_BPP);
+        *pcBPP = VBoxVideoCmnPortReadUshort(VBE_DISPI_IOPORT_DATA);
+    }
+    if (pfFlags)
+        *pfFlags = fFlags;
+    return RT_BOOL(fFlags & VBE_DISPI_ENABLED);
+}
+
+
+/**
+ * Disable our extended graphics mode and go back to VGA mode.
+ */
+RTDECL(void) VBoxVideoDisableVBE(void)
+{
+    VBoxVideoCmnPortWriteUshort(VBE_DISPI_IOPORT_INDEX,
+                                VBE_DISPI_INDEX_ENABLE);
+    VBoxVideoCmnPortWriteUshort(VBE_DISPI_IOPORT_DATA, 0);
+}
+
+
+/**
+ * Set a video mode via an HGSMI request.  The views must have been
+ * initialised first using @a VBoxHGSMISendViewInfo and if the mode is being
+ * set on the first display then it must be set first using registers.
+ * @param  cDisplay  the screen number
+ * @param  cOriginX  the horizontal displacement relative to the first screen
+ * @param  cOriginY  the vertical displacement relative to the first screen
+ * @param  offStart  the offset of the visible area of the framebuffer
+ *                   relative to the framebuffer start
+ * @param  cbPitch   the offset in bytes between the starts of two adjecent
+ *                   scan lines in video RAM
+ * @param  cWidth    the mode width
+ * @param  cHeight   the mode height
+ * @param  cBPP      the colour depth of the mode
+ */
+RTDECL(void) VBoxHGSMIProcessDisplayInfo(PHGSMIGUESTCOMMANDCONTEXT pCtx,
+                                         uint32_t cDisplay,
+                                         int32_t  cOriginX,
+                                         int32_t  cOriginY,
+                                         uint32_t offStart,
+                                         uint32_t cbPitch,
+                                         uint32_t cWidth,
+                                         uint32_t cHeight,
+                                         uint16_t cBPP,
+                                         uint16_t fFlags)
+{
+    /* Issue the screen info command. */
+    void *p = VBoxHGSMIBufferAlloc(pCtx,
+                                   sizeof (VBVAINFOSCREEN),
+                                   HGSMI_CH_VBVA,
+                                   VBVA_INFO_SCREEN);
+    if (!p)
+    {
+        LogFunc(("HGSMIHeapAlloc failed\n"));
+    }
+    else
+    {
+        VBVAINFOSCREEN *pScreen = (VBVAINFOSCREEN *)p;
+
+        pScreen->u32ViewIndex    = cDisplay;
+        pScreen->i32OriginX      = cOriginX;
+        pScreen->i32OriginY      = cOriginY;
+        pScreen->u32StartOffset  = offStart;
+        pScreen->u32LineSize     = cbPitch;
+        pScreen->u32Width        = cWidth;
+        pScreen->u32Height       = cHeight;
+        pScreen->u16BitsPerPixel = cBPP;
+        pScreen->u16Flags        = fFlags;
+
+        VBoxHGSMIBufferSubmit(pCtx, p);
+
+        VBoxHGSMIBufferFree(pCtx, p);
+    }
+}
+
+
+/** Report the rectangle relative to which absolute pointer events should be
+ *  expressed.  This information remains valid until the next VBVA resize event
+ *  for any screen, at which time it is reset to the bounding rectangle of all
+ *  virtual screens.
+ * @param  pCtx      The context containing the heap to use.
+ * @param  cOriginX  Upper left X co-ordinate relative to the first screen.
+ * @param  cOriginY  Upper left Y co-ordinate relative to the first screen.
+ * @param  cWidth    Rectangle width.
+ * @param  cHeight   Rectangle height.
+ * @returns  iprt status code.
+ * @returns  VERR_NO_MEMORY      HGSMI heap allocation failed.
+ */
+RTDECL(int)      VBoxHGSMIUpdateInputMapping(PHGSMIGUESTCOMMANDCONTEXT pCtx, int32_t  cOriginX, int32_t  cOriginY,
+                                             uint32_t cWidth, uint32_t cHeight)
+{
+    int rc = VINF_SUCCESS;
+    VBVAREPORTINPUTMAPPING *p;
+    Log(("%s: cOriginX=%d, cOriginY=%d, cWidth=%u, cHeight=%u\n", __PRETTY_FUNCTION__, (int)cOriginX, (int)cOriginX,
+         (unsigned)cWidth, (unsigned)cHeight));
+
+    /* Allocate the IO buffer. */
+    p = (VBVAREPORTINPUTMAPPING *)VBoxHGSMIBufferAlloc(pCtx, sizeof(VBVAREPORTINPUTMAPPING), HGSMI_CH_VBVA,
+                                                       VBVA_REPORT_INPUT_MAPPING);
+    if (p)
+    {
+        /* Prepare data to be sent to the host. */
+        p->x  = cOriginX;
+        p->y  = cOriginY;
+        p->cx = cWidth;
+        p->cy = cHeight;
+        rc = VBoxHGSMIBufferSubmit(pCtx, p);
+        /* Free the IO buffer. */
+        VBoxHGSMIBufferFree(pCtx, p);
+    }
+    else
+        rc = VERR_NO_MEMORY;
+    LogFunc(("rc = %d\n", rc));
+    return rc;
+}
+
+
+/**
+ * Get most recent video mode hints.
+ * @param  pCtx      the context containing the heap to use
+ * @param  cScreens  the number of screens to query hints for, starting at 0.
+ * @param  pHints    array of VBVAMODEHINT structures for receiving the hints.
+ * @returns  iprt status code
+ * @returns  VERR_NO_MEMORY      HGSMI heap allocation failed.
+ * @returns  VERR_NOT_SUPPORTED  Host does not support this command.
+ */
+RTDECL(int) VBoxHGSMIGetModeHints(PHGSMIGUESTCOMMANDCONTEXT pCtx,
+                                  unsigned cScreens, VBVAMODEHINT *paHints)
+{
+    int rc;
+    AssertPtrReturn(paHints, VERR_INVALID_POINTER);
+    void *p = VBoxHGSMIBufferAlloc(pCtx,   sizeof(VBVAQUERYMODEHINTS)
+                                         + cScreens * sizeof(VBVAMODEHINT),
+                                   HGSMI_CH_VBVA, VBVA_QUERY_MODE_HINTS);
+    if (!p)
+    {
+        LogFunc(("HGSMIHeapAlloc failed\n"));
+        return VERR_NO_MEMORY;
+    }
+    else
+    {
+        VBVAQUERYMODEHINTS *pQuery   = (VBVAQUERYMODEHINTS *)p;
+
+        pQuery->cHintsQueried        = cScreens;
+        pQuery->cbHintStructureGuest = sizeof(VBVAMODEHINT);
+        pQuery->rc                   = VERR_NOT_SUPPORTED;
+
+        VBoxHGSMIBufferSubmit(pCtx, p);
+        rc = pQuery->rc;
+        if (RT_SUCCESS(rc))
+            memcpy(paHints, ((uint8_t *)p) + sizeof(VBVAQUERYMODEHINTS),
+                   cScreens * sizeof(VBVAMODEHINT));
+
+        VBoxHGSMIBufferFree(pCtx, p);
+    }
+    return rc;
+}
+
+
+/**
+ * Query the supported flags in VBVAINFOSCREEN::u16Flags.
+ *
+ * @returns The mask of VBVA_SCREEN_F_* flags or 0 if host does not support the request.
+ * @param  pCtx  the context containing the heap to use
+ */
+RTDECL(uint16_t) VBoxHGSMIGetScreenFlags(PHGSMIGUESTCOMMANDCONTEXT pCtx)
+{
+    uint32_t u32Flags = 0;
+    int rc = VBoxQueryConfHGSMIDef(pCtx, VBOX_VBVA_CONF32_SCREEN_FLAGS, 0, &u32Flags);
+    LogFunc(("u32Flags = 0x%x rc %Rrc\n", u32Flags, rc));
+    if (RT_FAILURE(rc))
+        u32Flags = 0;
+    return (uint16_t)u32Flags;
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/vboxvideo/VBVABase.c
@@ -0,0 +1,389 @@
+/* $Id: VBVABase.cpp $ */
+/** @file
+ * VirtualBox Video driver, common code - VBVA initialisation and helper
+ * functions.
+ */
+
+/*
+ * Copyright (C) 2006-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+#include <VBox/VBoxVideoGuest.h>
+#include <VBox/VBoxVideo.h>
+#include <VBox/err.h>
+#include <VBox/log.h>
+#include <iprt/assert.h>
+#include <iprt/string.h>
+
+/*
+ * There is a hardware ring buffer in the graphics device video RAM, formerly
+ * in the VBox VMMDev PCI memory space.
+ * All graphics commands go there serialized by VBoxVBVABufferBeginUpdate.
+ * and vboxHwBufferEndUpdate.
+ *
+ * off32Free is writing position. off32Data is reading position.
+ * off32Free == off32Data means buffer is empty.
+ * There must be always gap between off32Data and off32Free when data
+ * are in the buffer.
+ * Guest only changes off32Free, host changes off32Data.
+ */
+
+/* Forward declarations of internal functions. */
+static void vboxHwBufferFlush(PHGSMIGUESTCOMMANDCONTEXT pCtx);
+static void vboxHwBufferPlaceDataAt(PVBVABUFFERCONTEXT pCtx, const void *p,
+                                    uint32_t cb, uint32_t offset);
+static bool vboxHwBufferWrite(PVBVABUFFERCONTEXT pCtx,
+                              PHGSMIGUESTCOMMANDCONTEXT pHGSMICtx,
+                              const void *p, uint32_t cb);
+
+
+static bool vboxVBVAInformHost(PVBVABUFFERCONTEXT pCtx,
+                               PHGSMIGUESTCOMMANDCONTEXT pHGSMICtx,
+                               int32_t cScreen, bool bEnable)
+{
+    bool bRc = false;
+
+#if 0  /* All callers check this */
+    if (ppdev->bHGSMISupported)
+#endif
+    {
+        void *p = VBoxHGSMIBufferAlloc(pHGSMICtx,
+                                       sizeof (VBVAENABLE_EX),
+                                       HGSMI_CH_VBVA,
+                                       VBVA_ENABLE);
+        if (!p)
+        {
+            LogFunc(("HGSMIHeapAlloc failed\n"));
+        }
+        else
+        {
+            VBVAENABLE_EX *pEnable = (VBVAENABLE_EX *)p;
+
+            pEnable->Base.u32Flags  = bEnable? VBVA_F_ENABLE: VBVA_F_DISABLE;
+            pEnable->Base.u32Offset = pCtx->offVRAMBuffer;
+            pEnable->Base.i32Result = VERR_NOT_SUPPORTED;
+            if (cScreen >= 0)
+            {
+                pEnable->Base.u32Flags |= VBVA_F_EXTENDED | VBVA_F_ABSOFFSET;
+                pEnable->u32ScreenId    = cScreen;
+            }
+
+            VBoxHGSMIBufferSubmit(pHGSMICtx, p);
+
+            if (bEnable)
+            {
+                bRc = RT_SUCCESS(pEnable->Base.i32Result);
+            }
+            else
+            {
+                bRc = true;
+            }
+
+            VBoxHGSMIBufferFree(pHGSMICtx, p);
+        }
+    }
+
+    return bRc;
+}
+
+/*
+ * Public hardware buffer methods.
+ */
+RTDECL(bool) VBoxVBVAEnable(PVBVABUFFERCONTEXT pCtx,
+                            PHGSMIGUESTCOMMANDCONTEXT pHGSMICtx,
+                            VBVABUFFER *pVBVA, int32_t cScreen)
+{
+    bool bRc = false;
+
+    LogFlowFunc(("pVBVA %p\n", pVBVA));
+
+#if 0  /* All callers check this */
+    if (ppdev->bHGSMISupported)
+#endif
+    {
+        LogFunc(("pVBVA %p vbva off 0x%x\n", pVBVA, pCtx->offVRAMBuffer));
+
+        pVBVA->hostFlags.u32HostEvents      = 0;
+        pVBVA->hostFlags.u32SupportedOrders = 0;
+        pVBVA->off32Data          = 0;
+        pVBVA->off32Free          = 0;
+        memset(pVBVA->aRecords, 0, sizeof (pVBVA->aRecords));
+        pVBVA->indexRecordFirst   = 0;
+        pVBVA->indexRecordFree    = 0;
+        pVBVA->cbPartialWriteThreshold = 256;
+        pVBVA->cbData             = pCtx->cbBuffer - sizeof (VBVABUFFER) + sizeof (pVBVA->au8Data);
+
+        pCtx->fHwBufferOverflow = false;
+        pCtx->pRecord    = NULL;
+        pCtx->pVBVA      = pVBVA;
+
+        bRc = vboxVBVAInformHost(pCtx, pHGSMICtx, cScreen, true);
+    }
+
+    if (!bRc)
+    {
+        VBoxVBVADisable(pCtx, pHGSMICtx, cScreen);
+    }
+
+    return bRc;
+}
+
+RTDECL(void) VBoxVBVADisable(PVBVABUFFERCONTEXT pCtx,
+                             PHGSMIGUESTCOMMANDCONTEXT pHGSMICtx,
+                             int32_t cScreen)
+{
+    LogFlowFunc(("\n"));
+
+    pCtx->fHwBufferOverflow = false;
+    pCtx->pRecord           = NULL;
+    pCtx->pVBVA             = NULL;
+
+    vboxVBVAInformHost(pCtx, pHGSMICtx, cScreen, false);
+
+    return;
+}
+
+RTDECL(bool) VBoxVBVABufferBeginUpdate(PVBVABUFFERCONTEXT pCtx,
+                                       PHGSMIGUESTCOMMANDCONTEXT pHGSMICtx)
+{
+    bool bRc = false;
+
+    // LogFunc(("flags = 0x%08X\n", pCtx->pVBVA? pCtx->pVBVA->u32HostEvents: -1));
+
+    if (   pCtx->pVBVA
+        && (pCtx->pVBVA->hostFlags.u32HostEvents & VBVA_F_MODE_ENABLED))
+    {
+        uint32_t indexRecordNext;
+
+        Assert(!pCtx->fHwBufferOverflow);
+        Assert(pCtx->pRecord == NULL);
+
+        indexRecordNext = (pCtx->pVBVA->indexRecordFree + 1) % VBVA_MAX_RECORDS;
+
+        if (indexRecordNext == pCtx->pVBVA->indexRecordFirst)
+        {
+            /* All slots in the records queue are used. */
+            vboxHwBufferFlush (pHGSMICtx);
+        }
+
+        if (indexRecordNext == pCtx->pVBVA->indexRecordFirst)
+        {
+            /* Even after flush there is no place. Fail the request. */
+            LogFunc(("no space in the queue of records!!! first %d, last %d\n",
+                     pCtx->pVBVA->indexRecordFirst, pCtx->pVBVA->indexRecordFree));
+        }
+        else
+        {
+            /* Initialize the record. */
+            VBVARECORD *pRecord = &pCtx->pVBVA->aRecords[pCtx->pVBVA->indexRecordFree];
+
+            pRecord->cbRecord = VBVA_F_RECORD_PARTIAL;
+
+            pCtx->pVBVA->indexRecordFree = indexRecordNext;
+
+            // LogFunc(("indexRecordNext = %d\n", indexRecordNext));
+
+            /* Remember which record we are using. */
+            pCtx->pRecord = pRecord;
+
+            bRc = true;
+        }
+    }
+
+    return bRc;
+}
+
+RTDECL(void) VBoxVBVABufferEndUpdate(PVBVABUFFERCONTEXT pCtx)
+{
+    VBVARECORD *pRecord;
+
+    // LogFunc(("\n"));
+
+    Assert(pCtx->pVBVA);
+
+    pRecord = pCtx->pRecord;
+    Assert(pRecord && (pRecord->cbRecord & VBVA_F_RECORD_PARTIAL));
+
+    /* Mark the record completed. */
+    pRecord->cbRecord &= ~VBVA_F_RECORD_PARTIAL;
+
+    pCtx->fHwBufferOverflow = false;
+    pCtx->pRecord = NULL;
+
+    return;
+}
+
+/*
+ * Private operations.
+ */
+static uint32_t vboxHwBufferAvail (const VBVABUFFER *pVBVA)
+{
+    int32_t i32Diff = pVBVA->off32Data - pVBVA->off32Free;
+
+    return i32Diff > 0? i32Diff: pVBVA->cbData + i32Diff;
+}
+
+static void vboxHwBufferFlush(PHGSMIGUESTCOMMANDCONTEXT pCtx)
+{
+    /* Issue the flush command. */
+    void *p = VBoxHGSMIBufferAlloc(pCtx,
+                                   sizeof (VBVAFLUSH),
+                                   HGSMI_CH_VBVA,
+                                   VBVA_FLUSH);
+    if (!p)
+    {
+        LogFunc(("HGSMIHeapAlloc failed\n"));
+    }
+    else
+    {
+        VBVAFLUSH *pFlush = (VBVAFLUSH *)p;
+
+        pFlush->u32Reserved = 0;
+
+        VBoxHGSMIBufferSubmit(pCtx, p);
+
+        VBoxHGSMIBufferFree(pCtx, p);
+    }
+
+    return;
+}
+
+static void vboxHwBufferPlaceDataAt(PVBVABUFFERCONTEXT pCtx, const void *p,
+                                    uint32_t cb, uint32_t offset)
+{
+    VBVABUFFER *pVBVA = pCtx->pVBVA;
+    uint32_t u32BytesTillBoundary = pVBVA->cbData - offset;
+    uint8_t  *dst                 = &pVBVA->au8Data[offset];
+    int32_t i32Diff               = cb - u32BytesTillBoundary;
+
+    if (i32Diff <= 0)
+    {
+        /* Chunk will not cross buffer boundary. */
+        memcpy (dst, p, cb);
+    }
+    else
+    {
+        /* Chunk crosses buffer boundary. */
+        memcpy (dst, p, u32BytesTillBoundary);
+        memcpy (&pVBVA->au8Data[0], (uint8_t *)p + u32BytesTillBoundary, i32Diff);
+    }
+
+    return;
+}
+
+static bool vboxHwBufferWrite(PVBVABUFFERCONTEXT pCtx,
+                              PHGSMIGUESTCOMMANDCONTEXT pHGSMICtx,
+                              const void *p, uint32_t cb)
+{
+    VBVARECORD *pRecord;
+    uint32_t cbHwBufferAvail;
+
+    uint32_t cbWritten = 0;
+
+    VBVABUFFER *pVBVA = pCtx->pVBVA;
+    Assert(pVBVA);
+
+    if (!pVBVA || pCtx->fHwBufferOverflow)
+    {
+        return false;
+    }
+
+    Assert(pVBVA->indexRecordFirst != pVBVA->indexRecordFree);
+
+    pRecord = pCtx->pRecord;
+    Assert(pRecord && (pRecord->cbRecord & VBVA_F_RECORD_PARTIAL));
+
+    // LogFunc(("%d\n", cb));
+
+    cbHwBufferAvail = vboxHwBufferAvail (pVBVA);
+
+    while (cb > 0)
+    {
+        uint32_t cbChunk = cb;
+
+        // LogFunc(("pVBVA->off32Free %d, pRecord->cbRecord 0x%08X, cbHwBufferAvail %d, cb %d, cbWritten %d\n",
+        //             pVBVA->off32Free, pRecord->cbRecord, cbHwBufferAvail, cb, cbWritten));
+
+        if (cbChunk >= cbHwBufferAvail)
+        {
+            LogFunc(("1) avail %d, chunk %d\n", cbHwBufferAvail, cbChunk));
+
+            vboxHwBufferFlush (pHGSMICtx);
+
+            cbHwBufferAvail = vboxHwBufferAvail (pVBVA);
+
+            if (cbChunk >= cbHwBufferAvail)
+            {
+                LogFunc(("no place for %d bytes. Only %d bytes available after flush. Going to partial writes.\n",
+                            cb, cbHwBufferAvail));
+
+                if (cbHwBufferAvail <= pVBVA->cbPartialWriteThreshold)
+                {
+                    LogFunc(("Buffer overflow!!!\n"));
+                    pCtx->fHwBufferOverflow = true;
+                    Assert(false);
+                    return false;
+                }
+
+                cbChunk = cbHwBufferAvail - pVBVA->cbPartialWriteThreshold;
+            }
+        }
+
+        Assert(cbChunk <= cb);
+        Assert(cbChunk <= vboxHwBufferAvail (pVBVA));
+
+        vboxHwBufferPlaceDataAt (pCtx, (uint8_t *)p + cbWritten, cbChunk, pVBVA->off32Free);
+
+        pVBVA->off32Free   = (pVBVA->off32Free + cbChunk) % pVBVA->cbData;
+        pRecord->cbRecord += cbChunk;
+        cbHwBufferAvail -= cbChunk;
+
+        cb        -= cbChunk;
+        cbWritten += cbChunk;
+    }
+
+    return true;
+}
+
+/*
+ * Public writer to the hardware buffer.
+ */
+RTDECL(bool) VBoxVBVAWrite(PVBVABUFFERCONTEXT pCtx,
+                           PHGSMIGUESTCOMMANDCONTEXT pHGSMICtx,
+                           const void *pv, uint32_t cb)
+{
+    return vboxHwBufferWrite (pCtx, pHGSMICtx, pv, cb);
+}
+
+RTDECL(bool) VBoxVBVAOrderSupported(PVBVABUFFERCONTEXT pCtx, unsigned code)
+{
+    VBVABUFFER *pVBVA = pCtx->pVBVA;
+
+    if (!pVBVA)
+    {
+        return false;
+    }
+
+    if (pVBVA->hostFlags.u32SupportedOrders & (1 << code))
+    {
+        return true;
+    }
+
+    return false;
+}
+
+RTDECL(void) VBoxVBVASetupBufferContext(PVBVABUFFERCONTEXT pCtx,
+                                        uint32_t offVRAMBuffer,
+                                        uint32_t cbBuffer)
+{
+    pCtx->offVRAMBuffer = offVRAMBuffer;
+    pCtx->cbBuffer      = cbBuffer;
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/vboxvideo/do_Module.symvers
@@ -0,0 +1,33 @@
+#!/bin/sh
+
+#
+# This script is used when building kernel modules from DKMS. I don't
+# know how to solve the problem of inter-module dependencies better.
+#
+# Copyright (C) 2008-2015 Oracle Corporation
+#
+# This file is part of VirtualBox Open Source Edition (OSE), as
+# available from http://www.virtualbox.org. This file is free software;
+# you can redistribute it and/or modify it under the terms of the GNU
+# General Public License (GPL) as published by the Free Software
+# Foundation, in version 2 as it comes in the "COPYING" file of the
+# VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+# hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+#
+
+SYMFILE="/tmp/$1-Module.symvers"
+case "$2" in
+  save)
+    if [ -f "$3" ]; then
+      cp "$3" "$SYMFILE"
+    fi
+    ;;
+  restore)
+    if [ -f "$SYMFILE" ]; then
+      cp "$SYMFILE" "$3"
+    fi
+    ;;
+  *)
+    echo "Usage: <modname> save|restore <location of Module.symvers>"
+    ;;
+esac
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/vboxvideo/heapoffset.c
@@ -0,0 +1,928 @@
+/* $Id: heapoffset.cpp $ */
+/** @file
+ * IPRT - An Offset Based Heap.
+ */
+
+/*
+ * Copyright (C) 2006-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+
+/*********************************************************************************************************************************
+*   Header Files                                                                                                                 *
+*********************************************************************************************************************************/
+#define LOG_GROUP RTLOGGROUP_DEFAULT
+#include <iprt/heap.h>
+#include "internal/iprt.h"
+
+#include <iprt/assert.h>
+#include <iprt/asm.h>
+#include <iprt/err.h>
+#include <iprt/log.h>
+#include <iprt/param.h>
+#include <iprt/string.h>
+
+#include "internal/magics.h"
+
+
+/*********************************************************************************************************************************
+*   Structures and Typedefs                                                                                                      *
+*********************************************************************************************************************************/
+/** Pointer to the heap anchor block. */
+typedef struct RTHEAPOFFSETINTERNAL *PRTHEAPOFFSETINTERNAL;
+/** Pointer to a heap block. */
+typedef struct RTHEAPOFFSETBLOCK *PRTHEAPOFFSETBLOCK;
+/** Pointer to a free heap block. */
+typedef struct RTHEAPOFFSETFREE *PRTHEAPOFFSETFREE;
+
+/**
+ * Structure describing a block in an offset based heap.
+ *
+ * If this block is allocated, it is followed by the user data.
+ * If this block is free, see RTHEAPOFFSETFREE.
+ */
+typedef struct RTHEAPOFFSETBLOCK
+{
+    /** The next block in the global block list. */
+    uint32_t /*PRTHEAPOFFSETBLOCK*/     offNext;
+    /** The previous block in the global block list. */
+    uint32_t /*PRTHEAPOFFSETBLOCK*/     offPrev;
+    /** Offset into the heap of this block. Used to locate the anchor block. */
+    uint32_t /*PRTHEAPOFFSETINTERNAL*/  offSelf;
+    /** Flags + magic. */
+    uint32_t                            fFlags;
+} RTHEAPOFFSETBLOCK;
+AssertCompileSize(RTHEAPOFFSETBLOCK, 16);
+
+/** The block is free if this flag is set. When cleared it's allocated. */
+#define RTHEAPOFFSETBLOCK_FLAGS_FREE        (RT_BIT_32(0))
+/** The magic value. */
+#define RTHEAPOFFSETBLOCK_FLAGS_MAGIC       (UINT32_C(0xabcdef00))
+/** The mask that needs to be applied to RTHEAPOFFSETBLOCK::fFlags to obtain the magic value. */
+#define RTHEAPOFFSETBLOCK_FLAGS_MAGIC_MASK  (~RT_BIT_32(0))
+
+/**
+ * Checks if the specified block is valid or not.
+ * @returns boolean answer.
+ * @param   pBlock      Pointer to a RTHEAPOFFSETBLOCK structure.
+ */
+#define RTHEAPOFFSETBLOCK_IS_VALID(pBlock)  \
+    ( ((pBlock)->fFlags & RTHEAPOFFSETBLOCK_FLAGS_MAGIC_MASK) == RTHEAPOFFSETBLOCK_FLAGS_MAGIC )
+
+/**
+ * Checks if the specified block is valid and in use.
+ * @returns boolean answer.
+ * @param   pBlock      Pointer to a RTHEAPOFFSETBLOCK structure.
+ */
+#define RTHEAPOFFSETBLOCK_IS_VALID_USED(pBlock)  \
+    ( ((pBlock)->fFlags & (RTHEAPOFFSETBLOCK_FLAGS_MAGIC_MASK | RTHEAPOFFSETBLOCK_FLAGS_FREE)) \
+       == RTHEAPOFFSETBLOCK_FLAGS_MAGIC )
+
+/**
+ * Checks if the specified block is valid and free.
+ * @returns boolean answer.
+ * @param   pBlock      Pointer to a RTHEAPOFFSETBLOCK structure.
+ */
+#define RTHEAPOFFSETBLOCK_IS_VALID_FREE(pBlock)  \
+    ( ((pBlock)->fFlags & (RTHEAPOFFSETBLOCK_FLAGS_MAGIC_MASK | RTHEAPOFFSETBLOCK_FLAGS_FREE)) \
+       == (RTHEAPOFFSETBLOCK_FLAGS_MAGIC | RTHEAPOFFSETBLOCK_FLAGS_FREE) )
+
+/**
+ * Checks if the specified block is free or not.
+ * @returns boolean answer.
+ * @param   pBlock      Pointer to a valid RTHEAPOFFSETBLOCK structure.
+ */
+#define RTHEAPOFFSETBLOCK_IS_FREE(pBlock)   (!!((pBlock)->fFlags & RTHEAPOFFSETBLOCK_FLAGS_FREE))
+
+/**
+ * A free heap block.
+ * This is an extended version of RTHEAPOFFSETBLOCK that takes the unused
+ * user data to store free list pointers and a cached size value.
+ */
+typedef struct RTHEAPOFFSETFREE
+{
+    /** Core stuff. */
+    RTHEAPOFFSETBLOCK               Core;
+    /** Pointer to the next free block. */
+    uint32_t /*PRTHEAPOFFSETFREE*/  offNext;
+    /** Pointer to the previous free block. */
+    uint32_t /*PRTHEAPOFFSETFREE*/  offPrev;
+    /** The size of the block (excluding the RTHEAPOFFSETBLOCK part). */
+    uint32_t                        cb;
+    /** An alignment filler to make it a multiple of 16 bytes. */
+    uint32_t                        Alignment;
+} RTHEAPOFFSETFREE;
+AssertCompileSize(RTHEAPOFFSETFREE, 16+16);
+
+
+/**
+ * The heap anchor block.
+ * This structure is placed at the head of the memory block specified to RTHeapOffsetInit(),
+ * which means that the first RTHEAPOFFSETBLOCK appears immediately after this structure.
+ */
+typedef struct RTHEAPOFFSETINTERNAL
+{
+    /** The typical magic (RTHEAPOFFSET_MAGIC). */
+    uint32_t                        u32Magic;
+    /** The heap size. (This structure is included!) */
+    uint32_t                        cbHeap;
+    /** The amount of free memory in the heap. */
+    uint32_t                        cbFree;
+    /** Free head pointer. */
+    uint32_t /*PRTHEAPOFFSETFREE*/  offFreeHead;
+    /** Free tail pointer. */
+    uint32_t /*PRTHEAPOFFSETFREE*/  offFreeTail;
+    /** Make the size of this structure 32 bytes. */
+    uint32_t                        au32Alignment[3];
+} RTHEAPOFFSETINTERNAL;
+AssertCompileSize(RTHEAPOFFSETINTERNAL, 32);
+
+
+/** The minimum allocation size. */
+#define RTHEAPOFFSET_MIN_BLOCK  (sizeof(RTHEAPOFFSETBLOCK))
+AssertCompile(RTHEAPOFFSET_MIN_BLOCK >= sizeof(RTHEAPOFFSETBLOCK));
+AssertCompile(RTHEAPOFFSET_MIN_BLOCK >= sizeof(RTHEAPOFFSETFREE) - sizeof(RTHEAPOFFSETBLOCK));
+
+/** The minimum and default alignment.  */
+#define RTHEAPOFFSET_ALIGNMENT  (sizeof(RTHEAPOFFSETBLOCK))
+
+
+/*********************************************************************************************************************************
+*   Defined Constants And Macros                                                                                                 *
+*********************************************************************************************************************************/
+#ifdef RT_STRICT
+# define RTHEAPOFFSET_STRICT 1
+#endif
+
+/**
+ * Converts RTHEAPOFFSETBLOCK::offSelf into a heap anchor block pointer.
+ *
+ * @returns Pointer of given type.
+ * @param   pBlock          The block to find the heap anchor block for.
+ */
+#define RTHEAPOFF_GET_ANCHOR(pBlock)    ( (PRTHEAPOFFSETINTERNAL)((uint8_t *)(pBlock) - (pBlock)->offSelf ) )
+
+
+/**
+ * Converts an offset to a pointer.
+ *
+ * All offsets are relative to the heap to make life simple.
+ *
+ * @returns Pointer of given type.
+ * @param   pHeapInt        Pointer to the heap anchor block.
+ * @param   off             The offset to convert.
+ * @param   type            The desired type.
+ */
+#ifdef RTHEAPOFFSET_STRICT
+# define RTHEAPOFF_TO_PTR_N(pHeapInt, off, type)   ( (type)rtHeapOffCheckedOffToPtr(pHeapInt, off, true /*fNull*/) )
+#else
+# define RTHEAPOFF_TO_PTR_N(pHeapInt, off, type)   ( (type)((off) ? (uint8_t *)(pHeapInt) + (off) : NULL) )
+#endif
+
+/**
+ * Converts an offset to a pointer.
+ *
+ * All offsets are relative to the heap to make life simple.
+ *
+ * @returns Pointer of given type.
+ * @param   pHeapInt        Pointer to the heap anchor block.
+ * @param   off             The offset to convert.
+ * @param   type            The desired type.
+ */
+#ifdef RTHEAPOFFSET_STRICT
+# define RTHEAPOFF_TO_PTR(pHeapInt, off, type)   ( (type)rtHeapOffCheckedOffToPtr(pHeapInt, off, false /*fNull*/) )
+#else
+# define RTHEAPOFF_TO_PTR(pHeapInt, off, type)   ( (type)((uint8_t *)(pHeapInt) + (off)) )
+#endif
+
+/**
+ * Converts a pointer to an offset.
+ *
+ * All offsets are relative to the heap to make life simple.
+ *
+ * @returns Offset into the heap.
+ * @param   pHeapInt        Pointer to the heap anchor block.
+ * @param   ptr             The pointer to convert.
+ */
+#ifdef RTHEAPOFFSET_STRICT
+# define RTHEAPOFF_TO_OFF(pHeapInt, ptr)    rtHeapOffCheckedPtrToOff(pHeapInt, ptr)
+#else
+# define RTHEAPOFF_TO_OFF(pHeapInt, ptr)    ( (uint32_t)((ptr) ? (uintptr_t)(ptr) - (uintptr_t)(pHeapInt) : UINT32_C(0)) )
+#endif
+
+#define ASSERT_L(a, b)    AssertMsg((a) <  (b), ("a=%08x b=%08x\n", (a), (b)))
+#define ASSERT_LE(a, b)   AssertMsg((a) <= (b), ("a=%08x b=%08x\n", (a), (b)))
+#define ASSERT_G(a, b)    AssertMsg((a) >  (b), ("a=%08x b=%08x\n", (a), (b)))
+#define ASSERT_GE(a, b)   AssertMsg((a) >= (b), ("a=%08x b=%08x\n", (a), (b)))
+#define ASSERT_ALIGN(a)   AssertMsg(!((uintptr_t)(a) & (RTHEAPOFFSET_ALIGNMENT - 1)), ("a=%p\n", (uintptr_t)(a)))
+
+#define ASSERT_PREV(pHeapInt, pBlock)  \
+    do { ASSERT_ALIGN((pBlock)->offPrev); \
+         if ((pBlock)->offPrev) \
+         { \
+             ASSERT_L((pBlock)->offPrev, RTHEAPOFF_TO_OFF(pHeapInt, pBlock)); \
+             ASSERT_GE((pBlock)->offPrev, sizeof(RTHEAPOFFSETINTERNAL)); \
+         } \
+         else \
+             Assert((pBlock) == (PRTHEAPOFFSETBLOCK)((pHeapInt) + 1)); \
+    } while (0)
+
+#define ASSERT_NEXT(pHeap, pBlock) \
+    do { ASSERT_ALIGN((pBlock)->offNext); \
+         if ((pBlock)->offNext) \
+         { \
+             ASSERT_L((pBlock)->offNext, (pHeapInt)->cbHeap); \
+             ASSERT_G((pBlock)->offNext, RTHEAPOFF_TO_OFF(pHeapInt, pBlock)); \
+         } \
+    } while (0)
+
+#define ASSERT_BLOCK(pHeapInt, pBlock) \
+    do { AssertMsg(RTHEAPOFFSETBLOCK_IS_VALID(pBlock), ("%#x\n", (pBlock)->fFlags)); \
+         AssertMsg(RTHEAPOFF_GET_ANCHOR(pBlock) == (pHeapInt), ("%p != %p\n", RTHEAPOFF_GET_ANCHOR(pBlock), (pHeapInt))); \
+         ASSERT_GE(RTHEAPOFF_TO_OFF(pHeapInt, pBlock), sizeof(RTHEAPOFFSETINTERNAL)); \
+         ASSERT_L( RTHEAPOFF_TO_OFF(pHeapInt, pBlock), (pHeapInt)->cbHeap); \
+         ASSERT_NEXT(pHeapInt, pBlock); \
+         ASSERT_PREV(pHeapInt, pBlock); \
+    } while (0)
+
+#define ASSERT_BLOCK_USED(pHeapInt, pBlock) \
+    do { AssertMsg(RTHEAPOFFSETBLOCK_IS_VALID_USED((pBlock)), ("%#x\n", (pBlock)->fFlags)); \
+         AssertMsg(RTHEAPOFF_GET_ANCHOR(pBlock) == (pHeapInt), ("%p != %p\n", RTHEAPOFF_GET_ANCHOR(pBlock), (pHeapInt))); \
+         ASSERT_GE(RTHEAPOFF_TO_OFF(pHeapInt, pBlock), sizeof(RTHEAPOFFSETINTERNAL)); \
+         ASSERT_L( RTHEAPOFF_TO_OFF(pHeapInt, pBlock), (pHeapInt)->cbHeap); \
+         ASSERT_NEXT(pHeapInt, pBlock); \
+         ASSERT_PREV(pHeapInt, pBlock); \
+    } while (0)
+
+#define ASSERT_FREE_PREV(pHeapInt, pBlock) \
+    do { ASSERT_ALIGN((pBlock)->offPrev); \
+         if ((pBlock)->offPrev) \
+         { \
+             ASSERT_GE((pBlock)->offPrev, (pHeapInt)->offFreeHead); \
+             ASSERT_L((pBlock)->offPrev, RTHEAPOFF_TO_OFF(pHeapInt, pBlock)); \
+             ASSERT_LE((pBlock)->offPrev, (pBlock)->Core.offPrev); \
+         } \
+         else \
+             Assert((pBlock) == RTHEAPOFF_TO_PTR(pHeapInt, (pHeapInt)->offFreeHead, PRTHEAPOFFSETFREE) ); \
+    } while (0)
+
+#define ASSERT_FREE_NEXT(pHeapInt, pBlock) \
+    do { ASSERT_ALIGN((pBlock)->offNext); \
+         if ((pBlock)->offNext) \
+         { \
+             ASSERT_LE((pBlock)->offNext, (pHeapInt)->offFreeTail); \
+             ASSERT_G((pBlock)->offNext, RTHEAPOFF_TO_OFF(pHeapInt, pBlock)); \
+             ASSERT_GE((pBlock)->offNext, (pBlock)->Core.offNext); \
+         } \
+         else \
+             Assert((pBlock) == RTHEAPOFF_TO_PTR(pHeapInt, (pHeapInt)->offFreeTail, PRTHEAPOFFSETFREE)); \
+    } while (0)
+
+#ifdef RTHEAPOFFSET_STRICT
+# define ASSERT_FREE_CB(pHeapInt, pBlock) \
+    do { size_t cbCalc = ((pBlock)->Core.offNext ? (pBlock)->Core.offNext : (pHeapInt)->cbHeap) \
+                       - RTHEAPOFF_TO_OFF((pHeapInt), (pBlock)) - sizeof(RTHEAPOFFSETBLOCK); \
+         AssertMsg((pBlock)->cb == cbCalc, ("cb=%#zx cbCalc=%#zx\n", (pBlock)->cb, cbCalc)); \
+    } while (0)
+#else
+# define ASSERT_FREE_CB(pHeapInt, pBlock) do {} while (0)
+#endif
+
+/** Asserts that a free block is valid. */
+#define ASSERT_BLOCK_FREE(pHeapInt, pBlock) \
+    do { ASSERT_BLOCK(pHeapInt, &(pBlock)->Core); \
+         Assert(RTHEAPOFFSETBLOCK_IS_VALID_FREE(&(pBlock)->Core)); \
+         ASSERT_GE(RTHEAPOFF_TO_OFF(pHeapInt, pBlock), (pHeapInt)->offFreeHead); \
+         ASSERT_LE(RTHEAPOFF_TO_OFF(pHeapInt, pBlock), (pHeapInt)->offFreeTail); \
+         ASSERT_FREE_NEXT(pHeapInt, pBlock); \
+         ASSERT_FREE_PREV(pHeapInt, pBlock); \
+         ASSERT_FREE_CB(pHeapInt, pBlock); \
+    } while (0)
+
+/** Asserts that the heap anchor block is ok. */
+#define ASSERT_ANCHOR(pHeapInt) \
+    do { AssertPtr(pHeapInt);\
+         Assert((pHeapInt)->u32Magic == RTHEAPOFFSET_MAGIC); \
+    } while (0)
+
+
+/*********************************************************************************************************************************
+*   Internal Functions                                                                                                           *
+*********************************************************************************************************************************/
+#ifdef RTHEAPOFFSET_STRICT
+static void rtHeapOffsetAssertAll(PRTHEAPOFFSETINTERNAL pHeapInt);
+#endif
+static PRTHEAPOFFSETBLOCK rtHeapOffsetAllocBlock(PRTHEAPOFFSETINTERNAL pHeapInt, size_t cb, size_t uAlignment);
+static void rtHeapOffsetFreeBlock(PRTHEAPOFFSETINTERNAL pHeapInt, PRTHEAPOFFSETBLOCK pBlock);
+
+#ifdef RTHEAPOFFSET_STRICT
+
+/** Checked version of RTHEAPOFF_TO_PTR and RTHEAPOFF_TO_PTR_N. */
+DECLINLINE(void *) rtHeapOffCheckedOffToPtr(PRTHEAPOFFSETINTERNAL pHeapInt, uint32_t off, bool fNull)
+{
+    Assert(off || fNull);
+    if (!off)
+        return NULL;
+    AssertMsg(off < pHeapInt->cbHeap,   ("%#x %#x\n", off, pHeapInt->cbHeap));
+    AssertMsg(off >= sizeof(*pHeapInt), ("%#x %#x\n", off, sizeof(*pHeapInt)));
+    return (uint8_t *)pHeapInt + off;
+}
+
+/** Checked version of RTHEAPOFF_TO_OFF. */
+DECLINLINE(uint32_t) rtHeapOffCheckedPtrToOff(PRTHEAPOFFSETINTERNAL pHeapInt, void *pv)
+{
+    if (!pv)
+        return 0;
+    uintptr_t off = (uintptr_t)pv - (uintptr_t)pHeapInt;
+    AssertMsg(off < pHeapInt->cbHeap,   ("%#x %#x\n", off, pHeapInt->cbHeap));
+    AssertMsg(off >= sizeof(*pHeapInt), ("%#x %#x\n", off, sizeof(*pHeapInt)));
+    return (uint32_t)off;
+}
+
+#endif /* RTHEAPOFFSET_STRICT */
+
+
+
+RTDECL(int) RTHeapOffsetInit(PRTHEAPOFFSET phHeap, void *pvMemory, size_t cbMemory)
+{
+    PRTHEAPOFFSETINTERNAL pHeapInt;
+    PRTHEAPOFFSETFREE pFree;
+    unsigned i;
+
+    /*
+     * Validate input. The imposed minimum heap size is just a convenient value.
+     */
+    AssertReturn(cbMemory >= PAGE_SIZE, VERR_INVALID_PARAMETER);
+    AssertReturn(cbMemory < UINT32_MAX, VERR_INVALID_PARAMETER);
+    AssertPtrReturn(pvMemory, VERR_INVALID_POINTER);
+    AssertReturn((uintptr_t)pvMemory + (cbMemory - 1) > (uintptr_t)cbMemory, VERR_INVALID_PARAMETER);
+
+    /*
+     * Place the heap anchor block at the start of the heap memory,
+     * enforce 32 byte alignment of it. Also align the heap size correctly.
+     */
+    pHeapInt = (PRTHEAPOFFSETINTERNAL)pvMemory;
+    if ((uintptr_t)pvMemory & 31)
+    {
+        const uintptr_t off = 32 - ((uintptr_t)pvMemory & 31);
+        cbMemory -= off;
+        pHeapInt = (PRTHEAPOFFSETINTERNAL)((uintptr_t)pvMemory + off);
+    }
+    cbMemory &= ~(RTHEAPOFFSET_ALIGNMENT - 1);
+
+
+    /* Init the heap anchor block. */
+    pHeapInt->u32Magic = RTHEAPOFFSET_MAGIC;
+    pHeapInt->cbHeap = (uint32_t)cbMemory;
+    pHeapInt->cbFree = (uint32_t)cbMemory
+                     - sizeof(RTHEAPOFFSETBLOCK)
+                     - sizeof(RTHEAPOFFSETINTERNAL);
+    pHeapInt->offFreeTail = pHeapInt->offFreeHead = sizeof(*pHeapInt);
+    for (i = 0; i < RT_ELEMENTS(pHeapInt->au32Alignment); i++)
+        pHeapInt->au32Alignment[i] = UINT32_MAX;
+
+    /* Init the single free block. */
+    pFree = RTHEAPOFF_TO_PTR(pHeapInt, pHeapInt->offFreeHead, PRTHEAPOFFSETFREE);
+    pFree->Core.offNext = 0;
+    pFree->Core.offPrev = 0;
+    pFree->Core.offSelf = pHeapInt->offFreeHead;
+    pFree->Core.fFlags = RTHEAPOFFSETBLOCK_FLAGS_MAGIC | RTHEAPOFFSETBLOCK_FLAGS_FREE;
+    pFree->offNext = 0;
+    pFree->offPrev = 0;
+    pFree->cb = pHeapInt->cbFree;
+
+    *phHeap = pHeapInt;
+
+#ifdef RTHEAPOFFSET_STRICT
+    rtHeapOffsetAssertAll(pHeapInt);
+#endif
+    return VINF_SUCCESS;
+}
+RT_EXPORT_SYMBOL(RTHeapOffsetInit);
+
+
+RTDECL(void *) RTHeapOffsetAlloc(RTHEAPOFFSET hHeap, size_t cb, size_t cbAlignment)
+{
+    PRTHEAPOFFSETINTERNAL pHeapInt = hHeap;
+    PRTHEAPOFFSETBLOCK pBlock;
+
+    /*
+     * Validate and adjust the input.
+     */
+    AssertPtrReturn(pHeapInt, NULL);
+    if (cb < RTHEAPOFFSET_MIN_BLOCK)
+        cb = RTHEAPOFFSET_MIN_BLOCK;
+    else
+        cb = RT_ALIGN_Z(cb, RTHEAPOFFSET_ALIGNMENT);
+    if (!cbAlignment)
+        cbAlignment = RTHEAPOFFSET_ALIGNMENT;
+    else
+    {
+        Assert(!(cbAlignment & (cbAlignment - 1)));
+        Assert((cbAlignment & ~(cbAlignment - 1)) == cbAlignment);
+        if (cbAlignment < RTHEAPOFFSET_ALIGNMENT)
+            cbAlignment = RTHEAPOFFSET_ALIGNMENT;
+    }
+
+    /*
+     * Do the allocation.
+     */
+    pBlock = rtHeapOffsetAllocBlock(pHeapInt, cb, cbAlignment);
+    if (RT_LIKELY(pBlock))
+    {
+        void *pv = pBlock + 1;
+        return pv;
+    }
+    return NULL;
+}
+RT_EXPORT_SYMBOL(RTHeapOffsetAlloc);
+
+
+RTDECL(void *) RTHeapOffsetAllocZ(RTHEAPOFFSET hHeap, size_t cb, size_t cbAlignment)
+{
+    PRTHEAPOFFSETINTERNAL pHeapInt = hHeap;
+    PRTHEAPOFFSETBLOCK pBlock;
+
+    /*
+     * Validate and adjust the input.
+     */
+    AssertPtrReturn(pHeapInt, NULL);
+    if (cb < RTHEAPOFFSET_MIN_BLOCK)
+        cb = RTHEAPOFFSET_MIN_BLOCK;
+    else
+        cb = RT_ALIGN_Z(cb, RTHEAPOFFSET_ALIGNMENT);
+    if (!cbAlignment)
+        cbAlignment = RTHEAPOFFSET_ALIGNMENT;
+    else
+    {
+        Assert(!(cbAlignment & (cbAlignment - 1)));
+        Assert((cbAlignment & ~(cbAlignment - 1)) == cbAlignment);
+        if (cbAlignment < RTHEAPOFFSET_ALIGNMENT)
+            cbAlignment = RTHEAPOFFSET_ALIGNMENT;
+    }
+
+    /*
+     * Do the allocation.
+     */
+    pBlock = rtHeapOffsetAllocBlock(pHeapInt, cb, cbAlignment);
+    if (RT_LIKELY(pBlock))
+    {
+        void *pv = pBlock + 1;
+        memset(pv, 0, cb);
+        return pv;
+    }
+    return NULL;
+}
+RT_EXPORT_SYMBOL(RTHeapOffsetAllocZ);
+
+
+/**
+ * Allocates a block of memory from the specified heap.
+ *
+ * No parameter validation or adjustment is performed.
+ *
+ * @returns Pointer to the allocated block.
+ * @returns NULL on failure.
+ *
+ * @param   pHeapInt    The heap.
+ * @param   cb          Size of the memory block to allocate.
+ * @param   uAlignment  The alignment specifications for the allocated block.
+ */
+static PRTHEAPOFFSETBLOCK rtHeapOffsetAllocBlock(PRTHEAPOFFSETINTERNAL pHeapInt, size_t cb, size_t uAlignment)
+{
+    PRTHEAPOFFSETBLOCK  pRet = NULL;
+    PRTHEAPOFFSETFREE   pFree;
+
+    AssertReturn((pHeapInt)->u32Magic == RTHEAPOFFSET_MAGIC, NULL);
+#ifdef RTHEAPOFFSET_STRICT
+    rtHeapOffsetAssertAll(pHeapInt);
+#endif
+
+    /*
+     * Search for a fitting block from the lower end of the heap.
+     */
+    for (pFree = RTHEAPOFF_TO_PTR_N(pHeapInt, pHeapInt->offFreeHead, PRTHEAPOFFSETFREE);
+         pFree;
+         pFree = RTHEAPOFF_TO_PTR_N(pHeapInt, pFree->offNext, PRTHEAPOFFSETFREE))
+    {
+        uintptr_t offAlign;
+        ASSERT_BLOCK_FREE(pHeapInt, pFree);
+
+        /*
+         * Match for size and alignment.
+         */
+        if (pFree->cb < cb)
+            continue;
+        offAlign = (uintptr_t)(&pFree->Core + 1) & (uAlignment - 1);
+        if (offAlign)
+        {
+            PRTHEAPOFFSETFREE pPrev;
+
+            offAlign = (uintptr_t)(&pFree[1].Core + 1) & (uAlignment - 1);
+            offAlign = uAlignment - offAlign;
+            if (pFree->cb < cb + offAlign + sizeof(RTHEAPOFFSETFREE))
+                continue;
+
+            /*
+             * Split up the free block into two, so that the 2nd is aligned as
+             * per specification.
+             */
+            pPrev = pFree;
+            pFree = (PRTHEAPOFFSETFREE)((uintptr_t)(pFree + 1) + offAlign);
+            pFree->Core.offPrev = pPrev->Core.offSelf;
+            pFree->Core.offNext = pPrev->Core.offNext;
+            pFree->Core.offSelf = RTHEAPOFF_TO_OFF(pHeapInt, pFree);
+            pFree->Core.fFlags  = RTHEAPOFFSETBLOCK_FLAGS_MAGIC | RTHEAPOFFSETBLOCK_FLAGS_FREE;
+            pFree->offPrev      = pPrev->Core.offSelf;
+            pFree->offNext      = pPrev->offNext;
+            pFree->cb           = (pFree->Core.offNext ? pFree->Core.offNext : pHeapInt->cbHeap)
+                                - pFree->Core.offSelf - sizeof(RTHEAPOFFSETBLOCK);
+
+            pPrev->Core.offNext = pFree->Core.offSelf;
+            pPrev->offNext      = pFree->Core.offSelf;
+            pPrev->cb           = pFree->Core.offSelf - pPrev->Core.offSelf - sizeof(RTHEAPOFFSETBLOCK);
+
+            if (pFree->Core.offNext)
+                RTHEAPOFF_TO_PTR(pHeapInt, pFree->Core.offNext, PRTHEAPOFFSETBLOCK)->offPrev = pFree->Core.offSelf;
+            if (pFree->offNext)
+                RTHEAPOFF_TO_PTR(pHeapInt, pFree->Core.offNext, PRTHEAPOFFSETFREE)->offPrev = pFree->Core.offSelf;
+            else
+                pHeapInt->offFreeTail = pFree->Core.offSelf;
+
+            pHeapInt->cbFree -= sizeof(RTHEAPOFFSETBLOCK);
+            ASSERT_BLOCK_FREE(pHeapInt, pPrev);
+            ASSERT_BLOCK_FREE(pHeapInt, pFree);
+        }
+
+        /*
+         * Split off a new FREE block?
+         */
+        if (pFree->cb >= cb + RT_ALIGN_Z(sizeof(RTHEAPOFFSETFREE), RTHEAPOFFSET_ALIGNMENT))
+        {
+            /*
+             * Create a new FREE block at then end of this one.
+             */
+            PRTHEAPOFFSETFREE   pNew = (PRTHEAPOFFSETFREE)((uintptr_t)&pFree->Core + cb + sizeof(RTHEAPOFFSETBLOCK));
+
+            pNew->Core.offSelf = RTHEAPOFF_TO_OFF(pHeapInt, pNew);
+            pNew->Core.offNext = pFree->Core.offNext;
+            if (pFree->Core.offNext)
+                RTHEAPOFF_TO_PTR(pHeapInt, pFree->Core.offNext, PRTHEAPOFFSETBLOCK)->offPrev = pNew->Core.offSelf;
+            pNew->Core.offPrev = RTHEAPOFF_TO_OFF(pHeapInt, pFree);
+            pNew->Core.fFlags = RTHEAPOFFSETBLOCK_FLAGS_MAGIC | RTHEAPOFFSETBLOCK_FLAGS_FREE;
+
+            pNew->offNext = pFree->offNext;
+            if (pNew->offNext)
+                RTHEAPOFF_TO_PTR(pHeapInt, pNew->offNext, PRTHEAPOFFSETFREE)->offPrev = pNew->Core.offSelf;
+            else
+                pHeapInt->offFreeTail = pNew->Core.offSelf;
+            pNew->offPrev = pFree->offPrev;
+            if (pNew->offPrev)
+                RTHEAPOFF_TO_PTR(pHeapInt, pNew->offPrev, PRTHEAPOFFSETFREE)->offNext = pNew->Core.offSelf;
+            else
+                pHeapInt->offFreeHead = pNew->Core.offSelf;
+            pNew->cb    = (pNew->Core.offNext ? pNew->Core.offNext : pHeapInt->cbHeap) \
+                        - pNew->Core.offSelf - sizeof(RTHEAPOFFSETBLOCK);
+            ASSERT_BLOCK_FREE(pHeapInt, pNew);
+
+            /*
+             * Adjust and convert the old FREE node into a USED node.
+             */
+            pFree->Core.fFlags &= ~RTHEAPOFFSETBLOCK_FLAGS_FREE;
+            pFree->Core.offNext = pNew->Core.offSelf;
+            pHeapInt->cbFree -= pFree->cb;
+            pHeapInt->cbFree += pNew->cb;
+            pRet = &pFree->Core;
+            ASSERT_BLOCK_USED(pHeapInt, pRet);
+        }
+        else
+        {
+            /*
+             * Link it out of the free list.
+             */
+            if (pFree->offNext)
+                RTHEAPOFF_TO_PTR(pHeapInt, pFree->offNext, PRTHEAPOFFSETFREE)->offPrev = pFree->offPrev;
+            else
+                pHeapInt->offFreeTail = pFree->offPrev;
+            if (pFree->offPrev)
+                RTHEAPOFF_TO_PTR(pHeapInt, pFree->offPrev, PRTHEAPOFFSETFREE)->offNext = pFree->offNext;
+            else
+                pHeapInt->offFreeHead = pFree->offNext;
+
+            /*
+             * Convert it to a used block.
+             */
+            pHeapInt->cbFree -= pFree->cb;
+            pFree->Core.fFlags &= ~RTHEAPOFFSETBLOCK_FLAGS_FREE;
+            pRet = &pFree->Core;
+            ASSERT_BLOCK_USED(pHeapInt, pRet);
+        }
+        break;
+    }
+
+#ifdef RTHEAPOFFSET_STRICT
+    rtHeapOffsetAssertAll(pHeapInt);
+#endif
+    return pRet;
+}
+
+
+RTDECL(void) RTHeapOffsetFree(RTHEAPOFFSET hHeap, void *pv)
+{
+    PRTHEAPOFFSETINTERNAL pHeapInt;
+    PRTHEAPOFFSETBLOCK pBlock;
+
+    /*
+     * Validate input.
+     */
+    if (!pv)
+        return;
+    AssertPtr(pv);
+    Assert(RT_ALIGN_P(pv, RTHEAPOFFSET_ALIGNMENT) == pv);
+
+    /*
+     * Get the block and heap. If in strict mode, validate these.
+     */
+    pBlock = (PRTHEAPOFFSETBLOCK)pv - 1;
+    pHeapInt = RTHEAPOFF_GET_ANCHOR(pBlock);
+    ASSERT_BLOCK_USED(pHeapInt, pBlock);
+    ASSERT_ANCHOR(pHeapInt);
+    Assert(pHeapInt == (PRTHEAPOFFSETINTERNAL)hHeap || !hHeap);
+
+#ifdef RTHEAPOFFSET_FREE_POISON
+    /*
+     * Poison the block.
+     */
+    const size_t cbBlock = (pBlock->pNext ? (uintptr_t)pBlock->pNext : (uintptr_t)pHeapInt->pvEnd)
+                         - (uintptr_t)pBlock - sizeof(RTHEAPOFFSETBLOCK);
+    memset(pBlock + 1, RTHEAPOFFSET_FREE_POISON, cbBlock);
+#endif
+
+    /*
+     * Call worker which does the actual job.
+     */
+    rtHeapOffsetFreeBlock(pHeapInt, pBlock);
+}
+RT_EXPORT_SYMBOL(RTHeapOffsetFree);
+
+
+/**
+ * Free a memory block.
+ *
+ * @param   pHeapInt       The heap.
+ * @param   pBlock         The memory block to free.
+ */
+static void rtHeapOffsetFreeBlock(PRTHEAPOFFSETINTERNAL pHeapInt, PRTHEAPOFFSETBLOCK pBlock)
+{
+    PRTHEAPOFFSETFREE   pFree = (PRTHEAPOFFSETFREE)pBlock;
+    PRTHEAPOFFSETFREE   pLeft;
+    PRTHEAPOFFSETFREE   pRight;
+
+#ifdef RTHEAPOFFSET_STRICT
+    rtHeapOffsetAssertAll(pHeapInt);
+#endif
+
+    /*
+     * Look for the closest free list blocks by walking the blocks right
+     * of us (both lists are sorted by address).
+     */
+    pLeft = NULL;
+    pRight = NULL;
+    if (pHeapInt->offFreeTail)
+    {
+        pRight = RTHEAPOFF_TO_PTR_N(pHeapInt, pFree->Core.offNext, PRTHEAPOFFSETFREE);
+        while (pRight && !RTHEAPOFFSETBLOCK_IS_FREE(&pRight->Core))
+        {
+            ASSERT_BLOCK(pHeapInt, &pRight->Core);
+            pRight = RTHEAPOFF_TO_PTR_N(pHeapInt, pRight->Core.offNext, PRTHEAPOFFSETFREE);
+        }
+        if (!pRight)
+            pLeft = RTHEAPOFF_TO_PTR_N(pHeapInt, pHeapInt->offFreeTail, PRTHEAPOFFSETFREE);
+        else
+        {
+            ASSERT_BLOCK_FREE(pHeapInt, pRight);
+            pLeft = RTHEAPOFF_TO_PTR_N(pHeapInt, pRight->offPrev, PRTHEAPOFFSETFREE);
+        }
+        if (pLeft)
+            ASSERT_BLOCK_FREE(pHeapInt, pLeft);
+    }
+    AssertMsgReturnVoid(pLeft != pFree, ("Freed twice! pv=%p (pBlock=%p)\n", pBlock + 1, pBlock));
+    ASSERT_L(RTHEAPOFF_TO_OFF(pHeapInt, pLeft), RTHEAPOFF_TO_OFF(pHeapInt, pFree));
+    Assert(!pRight || (uintptr_t)pRight > (uintptr_t)pFree);
+    Assert(!pLeft || RTHEAPOFF_TO_PTR_N(pHeapInt, pLeft->offNext, PRTHEAPOFFSETFREE) == pRight);
+
+    /*
+     * Insert at the head of the free block list?
+     */
+    if (!pLeft)
+    {
+        Assert(pRight == RTHEAPOFF_TO_PTR_N(pHeapInt, pHeapInt->offFreeHead, PRTHEAPOFFSETFREE));
+        pFree->Core.fFlags |= RTHEAPOFFSETBLOCK_FLAGS_FREE;
+        pFree->offPrev = 0;
+        pFree->offNext = RTHEAPOFF_TO_OFF(pHeapInt, pRight);
+        if (pRight)
+            pRight->offPrev = RTHEAPOFF_TO_OFF(pHeapInt, pFree);
+        else
+            pHeapInt->offFreeTail = RTHEAPOFF_TO_OFF(pHeapInt, pFree);
+        pHeapInt->offFreeHead = RTHEAPOFF_TO_OFF(pHeapInt, pFree);
+    }
+    else
+    {
+        /*
+         * Can we merge with left hand free block?
+         */
+        if (pLeft->Core.offNext == RTHEAPOFF_TO_OFF(pHeapInt, pFree))
+        {
+            pLeft->Core.offNext = pFree->Core.offNext;
+            if (pFree->Core.offNext)
+                RTHEAPOFF_TO_PTR(pHeapInt, pFree->Core.offNext, PRTHEAPOFFSETBLOCK)->offPrev = RTHEAPOFF_TO_OFF(pHeapInt, pLeft);
+            pHeapInt->cbFree -= pLeft->cb;
+            pFree = pLeft;
+        }
+        /*
+         * No, just link it into the free list then.
+         */
+        else
+        {
+            pFree->Core.fFlags |= RTHEAPOFFSETBLOCK_FLAGS_FREE;
+            pFree->offNext = RTHEAPOFF_TO_OFF(pHeapInt, pRight);
+            pFree->offPrev = RTHEAPOFF_TO_OFF(pHeapInt, pLeft);
+            pLeft->offNext = RTHEAPOFF_TO_OFF(pHeapInt, pFree);
+            if (pRight)
+                pRight->offPrev = RTHEAPOFF_TO_OFF(pHeapInt, pFree);
+            else
+                pHeapInt->offFreeTail = RTHEAPOFF_TO_OFF(pHeapInt, pFree);
+        }
+    }
+
+    /*
+     * Can we merge with right hand free block?
+     */
+    if (    pRight
+        &&  pRight->Core.offPrev == RTHEAPOFF_TO_OFF(pHeapInt, pFree))
+    {
+        /* core */
+        pFree->Core.offNext = pRight->Core.offNext;
+        if (pRight->Core.offNext)
+            RTHEAPOFF_TO_PTR(pHeapInt, pRight->Core.offNext, PRTHEAPOFFSETBLOCK)->offPrev = RTHEAPOFF_TO_OFF(pHeapInt, pFree);
+
+        /* free */
+        pFree->offNext = pRight->offNext;
+        if (pRight->offNext)
+            RTHEAPOFF_TO_PTR(pHeapInt, pRight->offNext, PRTHEAPOFFSETFREE)->offPrev = RTHEAPOFF_TO_OFF(pHeapInt, pFree);
+        else
+            pHeapInt->offFreeTail = RTHEAPOFF_TO_OFF(pHeapInt, pFree);
+        pHeapInt->cbFree -= pRight->cb;
+    }
+
+    /*
+     * Calculate the size and update free stats.
+     */
+    pFree->cb = (pFree->Core.offNext ? pFree->Core.offNext : pHeapInt->cbHeap)
+              - RTHEAPOFF_TO_OFF(pHeapInt, pFree) - sizeof(RTHEAPOFFSETBLOCK);
+    pHeapInt->cbFree += pFree->cb;
+    ASSERT_BLOCK_FREE(pHeapInt, pFree);
+
+#ifdef RTHEAPOFFSET_STRICT
+    rtHeapOffsetAssertAll(pHeapInt);
+#endif
+}
+
+
+#ifdef RTHEAPOFFSET_STRICT
+/**
+ * Internal consistency check (relying on assertions).
+ * @param   pHeapInt
+ */
+static void rtHeapOffsetAssertAll(PRTHEAPOFFSETINTERNAL pHeapInt)
+{
+    PRTHEAPOFFSETFREE pPrev = NULL;
+    PRTHEAPOFFSETFREE pPrevFree = NULL;
+    PRTHEAPOFFSETFREE pBlock;
+    for (pBlock = (PRTHEAPOFFSETFREE)(pHeapInt + 1);
+         pBlock;
+         pBlock = RTHEAPOFF_TO_PTR_N(pHeapInt, pBlock->Core.offNext, PRTHEAPOFFSETFREE))
+    {
+        if (RTHEAPOFFSETBLOCK_IS_FREE(&pBlock->Core))
+        {
+            ASSERT_BLOCK_FREE(pHeapInt, pBlock);
+            Assert(pBlock->offPrev == RTHEAPOFF_TO_OFF(pHeapInt, pPrevFree));
+            Assert(pPrevFree || pHeapInt->offFreeHead == RTHEAPOFF_TO_OFF(pHeapInt, pBlock));
+            pPrevFree = pBlock;
+        }
+        else
+            ASSERT_BLOCK_USED(pHeapInt, &pBlock->Core);
+        Assert(!pPrev || RTHEAPOFF_TO_OFF(pHeapInt, pPrev) == pBlock->Core.offPrev);
+        pPrev = pBlock;
+    }
+    Assert(pHeapInt->offFreeTail == RTHEAPOFF_TO_OFF(pHeapInt, pPrevFree));
+}
+#endif
+
+
+RTDECL(size_t) RTHeapOffsetSize(RTHEAPOFFSET hHeap, void *pv)
+{
+    PRTHEAPOFFSETINTERNAL pHeapInt;
+    PRTHEAPOFFSETBLOCK pBlock;
+    size_t cbBlock;
+
+    /*
+     * Validate input.
+     */
+    if (!pv)
+        return 0;
+    AssertPtrReturn(pv, 0);
+    AssertReturn(RT_ALIGN_P(pv, RTHEAPOFFSET_ALIGNMENT) == pv, 0);
+
+    /*
+     * Get the block and heap. If in strict mode, validate these.
+     */
+    pBlock = (PRTHEAPOFFSETBLOCK)pv - 1;
+    pHeapInt = RTHEAPOFF_GET_ANCHOR(pBlock);
+    ASSERT_BLOCK_USED(pHeapInt, pBlock);
+    ASSERT_ANCHOR(pHeapInt);
+    Assert(pHeapInt == (PRTHEAPOFFSETINTERNAL)hHeap || !hHeap);
+
+    /*
+     * Calculate the block size.
+     */
+    cbBlock = (pBlock->offNext ? pBlock->offNext : pHeapInt->cbHeap)
+            - RTHEAPOFF_TO_OFF(pHeapInt, pBlock) - sizeof(RTHEAPOFFSETBLOCK);
+    return cbBlock;
+}
+RT_EXPORT_SYMBOL(RTHeapOffsetSize);
+
+
+RTDECL(size_t) RTHeapOffsetGetHeapSize(RTHEAPOFFSET hHeap)
+{
+    PRTHEAPOFFSETINTERNAL pHeapInt;
+
+    if (hHeap == NIL_RTHEAPOFFSET)
+        return 0;
+
+    pHeapInt = hHeap;
+    AssertPtrReturn(pHeapInt, 0);
+    ASSERT_ANCHOR(pHeapInt);
+    return pHeapInt->cbHeap;
+}
+RT_EXPORT_SYMBOL(RTHeapOffsetGetHeapSize);
+
+
+RTDECL(size_t) RTHeapOffsetGetFreeSize(RTHEAPOFFSET hHeap)
+{
+    PRTHEAPOFFSETINTERNAL pHeapInt;
+
+    if (hHeap == NIL_RTHEAPOFFSET)
+        return 0;
+
+    pHeapInt = hHeap;
+    AssertPtrReturn(pHeapInt, 0);
+    ASSERT_ANCHOR(pHeapInt);
+    return pHeapInt->cbFree;
+}
+RT_EXPORT_SYMBOL(RTHeapOffsetGetFreeSize);
+
+
+RTDECL(void) RTHeapOffsetDump(RTHEAPOFFSET hHeap, PFNRTHEAPOFFSETPRINTF pfnPrintf)
+{
+    PRTHEAPOFFSETINTERNAL pHeapInt = (PRTHEAPOFFSETINTERNAL)hHeap;
+    PRTHEAPOFFSETFREE pBlock;
+
+    pfnPrintf("**** Dumping Heap %p - cbHeap=%x cbFree=%x ****\n",
+              hHeap, pHeapInt->cbHeap, pHeapInt->cbFree);
+
+    for (pBlock = (PRTHEAPOFFSETFREE)(pHeapInt + 1);
+         pBlock;
+         pBlock = RTHEAPOFF_TO_PTR_N(pHeapInt, pBlock->Core.offNext, PRTHEAPOFFSETFREE))
+    {
+        size_t cb = (pBlock->offNext ? pBlock->Core.offNext : pHeapInt->cbHeap)
+                  - RTHEAPOFF_TO_OFF(pHeapInt, pBlock) - sizeof(RTHEAPOFFSETBLOCK);
+        if (RTHEAPOFFSETBLOCK_IS_FREE(&pBlock->Core))
+            pfnPrintf("%p  %06x FREE offNext=%06x offPrev=%06x fFlags=%#x cb=%#06x : cb=%#06x offNext=%06x offPrev=%06x\n",
+                      pBlock, pBlock->Core.offSelf, pBlock->Core.offNext, pBlock->Core.offPrev, pBlock->Core.fFlags, cb,
+                      pBlock->cb, pBlock->offNext, pBlock->offPrev);
+        else
+            pfnPrintf("%p  %06x USED offNext=%06x offPrev=%06x fFlags=%#x cb=%#06x\n",
+                      pBlock, pBlock->Core.offSelf, pBlock->Core.offNext, pBlock->Core.offPrev, pBlock->Core.fFlags, cb);
+    }
+    pfnPrintf("**** Done dumping Heap %p ****\n", hHeap);
+}
+RT_EXPORT_SYMBOL(RTHeapOffsetDump);
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/vboxvideo/product-generated.h
@@ -0,0 +1,10 @@
+#ifndef ___product_generated_h___
+#define ___product_generated_h___
+
+#define VBOX_VENDOR "Oracle Corporation"
+#define VBOX_VENDOR_SHORT "Oracle"
+#define VBOX_PRODUCT "Oracle VM VirtualBox"
+#define VBOX_BUILD_PUBLISHER "_Ubuntu"
+#define VBOX_C_YEAR "2016"
+
+#endif
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/vboxvideo/vbox_drv.c
@@ -0,0 +1,300 @@
+/*  $Id: vbox_drv.c $ */
+/** @file
+ * VirtualBox Additions Linux kernel video driver
+ */
+
+/*
+ * Copyright (C) 2013 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ * --------------------------------------------------------------------
+ *
+ * This code is based on
+ * ast_drv.c
+ * with the following copyright and permission notice:
+ *
+ * Copyright 2012 Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ */
+/*
+ * Authors: Dave Airlie <airlied@redhat.com>
+ */
+#include "vbox_drv.h"
+
+#include <VBox/VBoxGuest.h>
+
+#include <linux/module.h>
+#include <linux/console.h>
+#include <linux/vt_kern.h>
+
+#include <drm/drmP.h>
+#include <drm/drm_crtc_helper.h>
+#include "version-generated.h"
+
+int vbox_modeset = -1;
+
+MODULE_PARM_DESC(modeset, "Disable/Enable modesetting");
+module_param_named(modeset, vbox_modeset, int, 0400);
+
+static struct drm_driver driver;
+
+static DEFINE_PCI_DEVICE_TABLE(pciidlist) =
+{
+    {0x80ee, 0xbeef, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+    {0, 0, 0},
+};
+
+MODULE_DEVICE_TABLE(pci, pciidlist);
+
+static int vbox_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+{
+    return drm_get_pci_dev(pdev, ent, &driver);
+}
+
+
+static void vbox_pci_remove(struct pci_dev *pdev)
+{
+    struct drm_device *dev = pci_get_drvdata(pdev);
+
+    drm_put_dev(dev);
+}
+
+
+
+static int vbox_drm_freeze(struct drm_device *dev)
+{
+    drm_kms_helper_poll_disable(dev);
+
+    pci_save_state(dev->pdev);
+
+    console_lock();
+    vbox_fbdev_set_suspend(dev, 1);
+    console_unlock();
+    return 0;
+}
+
+static int vbox_drm_thaw(struct drm_device *dev)
+{
+    int error = 0;
+
+    drm_mode_config_reset(dev);
+    drm_helper_resume_force_mode(dev);
+
+    console_lock();
+    vbox_fbdev_set_suspend(dev, 0);
+    console_unlock();
+    return error;
+}
+
+static int vbox_drm_resume(struct drm_device *dev)
+{
+    int ret;
+
+    if (pci_enable_device(dev->pdev))
+        return -EIO;
+
+       ret = vbox_drm_thaw(dev);
+    if (ret)
+       return ret;
+
+    drm_kms_helper_poll_enable(dev);
+    return 0;
+}
+
+static int vbox_pm_suspend(struct device *dev)
+{
+    struct pci_dev *pdev = to_pci_dev(dev);
+    struct drm_device *ddev = pci_get_drvdata(pdev);
+    int error;
+
+    error = vbox_drm_freeze(ddev);
+    if (error)
+        return error;
+
+    pci_disable_device(pdev);
+    pci_set_power_state(pdev, PCI_D3hot);
+    return 0;
+}
+
+static int vbox_pm_resume(struct device *dev)
+{
+    struct pci_dev *pdev = to_pci_dev(dev);
+    struct drm_device *ddev = pci_get_drvdata(pdev);
+    return vbox_drm_resume(ddev);
+}
+
+static int vbox_pm_freeze(struct device *dev)
+{
+    struct pci_dev *pdev = to_pci_dev(dev);
+    struct drm_device *ddev = pci_get_drvdata(pdev);
+
+    if (!ddev || !ddev->dev_private)
+        return -ENODEV;
+    return vbox_drm_freeze(ddev);
+
+}
+
+static int vbox_pm_thaw(struct device *dev)
+{
+    struct pci_dev *pdev = to_pci_dev(dev);
+    struct drm_device *ddev = pci_get_drvdata(pdev);
+    return vbox_drm_thaw(ddev);
+}
+
+static int vbox_pm_poweroff(struct device *dev)
+{
+    struct pci_dev *pdev = to_pci_dev(dev);
+    struct drm_device *ddev = pci_get_drvdata(pdev);
+
+    return vbox_drm_freeze(ddev);
+}
+
+static const struct dev_pm_ops vbox_pm_ops = {
+    .suspend = vbox_pm_suspend,
+    .resume = vbox_pm_resume,
+    .freeze = vbox_pm_freeze,
+    .thaw = vbox_pm_thaw,
+    .poweroff = vbox_pm_poweroff,
+    .restore = vbox_pm_resume,
+};
+
+static struct pci_driver vbox_pci_driver =
+{
+    .name = DRIVER_NAME,
+    .id_table = pciidlist,
+    .probe = vbox_pci_probe,
+    .remove = vbox_pci_remove,
+    .driver.pm = &vbox_pm_ops,
+};
+
+static const struct file_operations vbox_fops =
+{
+    .owner = THIS_MODULE,
+    .open = drm_open,
+    .release = drm_release,
+    .unlocked_ioctl = drm_ioctl,
+    .mmap = vbox_mmap,
+    .poll = drm_poll,
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 12, 0)
+    .fasync = drm_fasync,
+#endif
+#ifdef CONFIG_COMPAT
+    .compat_ioctl = drm_compat_ioctl,
+#endif
+    .read = drm_read,
+};
+
+static int vbox_master_set(struct drm_device *dev,
+                           struct drm_file *file_priv,
+                           bool from_open)
+{
+    struct vbox_private *vbox = dev->dev_private;
+    vbox->initial_mode_queried = false;
+    vbox_disable_accel(vbox);
+    return 0;
+}
+
+static void vbox_master_drop(struct drm_device *dev,
+                             struct drm_file *file_priv,
+                             bool from_release)
+{
+    struct vbox_private *vbox = dev->dev_private;
+    vbox->initial_mode_queried = false;
+    vbox_disable_accel(vbox);
+}
+
+static struct drm_driver driver =
+{
+    .driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED,
+    .dev_priv_size = 0,
+
+    .load = vbox_driver_load,
+    .unload = vbox_driver_unload,
+    .lastclose = vbox_driver_lastclose,
+    .master_set = vbox_master_set,
+    .master_drop = vbox_master_drop,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0)
+    .set_busid = drm_pci_set_busid,
+#endif
+
+    .fops = &vbox_fops,
+    .irq_handler = vbox_irq_handler,
+    .name = DRIVER_NAME,
+    .desc = DRIVER_DESC,
+    .date = DRIVER_DATE,
+    .major = DRIVER_MAJOR,
+    .minor = DRIVER_MINOR,
+    .patchlevel = DRIVER_PATCHLEVEL,
+
+    .gem_free_object = vbox_gem_free_object,
+    .dumb_create = vbox_dumb_create,
+    .dumb_map_offset = vbox_dumb_mmap_offset,
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 12, 0)
+    .dumb_destroy = vbox_dumb_destroy,
+#else
+    .dumb_destroy = drm_gem_dumb_destroy,
+#endif
+
+};
+
+static int __init vbox_init(void)
+{
+    unsigned i;
+
+#ifdef CONFIG_VGA_CONSOLE
+    if (vgacon_text_force() && vbox_modeset == -1)
+        return -EINVAL;
+#endif
+
+    if (vbox_modeset == 0)
+        return -EINVAL;
+
+    /* Do not load if any of the virtual consoles is in graphics mode to be
+     * sure that we do not pick a fight with a user-mode driver or VESA. */
+    for (i = 0; i < MAX_NR_CONSOLES - 1; ++i)
+        if (vc_cons[i].d && vc_cons[i].d->vc_mode == KD_GRAPHICS)
+            return -EINVAL;
+
+    return drm_pci_init(&driver, &vbox_pci_driver);
+}
+static void __exit vbox_exit(void)
+{
+    drm_pci_exit(&driver, &vbox_pci_driver);
+}
+
+module_init(vbox_init);
+module_exit(vbox_exit);
+
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL and additional rights");
+#ifdef MODULE_VERSION
+MODULE_VERSION(VBOX_VERSION_STRING);
+#endif
+
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/vboxvideo/vbox_drv.h
@@ -0,0 +1,312 @@
+/* $Id: vbox_drv.h $ */
+/** @file
+ * VirtualBox Additions Linux kernel video driver
+ */
+
+/*
+ * Copyright (C) 2013 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ * --------------------------------------------------------------------
+ *
+ * This code is based on
+ * ast_drv.h
+ * with the following copyright and permission notice:
+ *
+ * Copyright 2012 Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ */
+/*
+ * Authors: Dave Airlie <airlied@redhat.com>
+ */
+#ifndef __VBOX_DRV_H__
+#define __VBOX_DRV_H__
+
+#define LOG_GROUP LOG_GROUP_DEV_VGA
+
+#include "the-linux-kernel.h"
+
+#include <VBox/VBoxVideoGuest.h>
+#include <VBox/log.h>
+
+#include <drm/drmP.h>
+#include <drm/drm_fb_helper.h>
+
+#include <drm/ttm/ttm_bo_api.h>
+#include <drm/ttm/ttm_bo_driver.h>
+#include <drm/ttm/ttm_placement.h>
+#include <drm/ttm/ttm_memory.h>
+#include <drm/ttm/ttm_module.h>
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0)
+# include <drm/drm_gem.h>
+#endif
+
+/* #include "vboxvideo.h" */
+
+#include "product-generated.h"
+
+#define DRIVER_AUTHOR       VBOX_VENDOR
+
+#define DRIVER_NAME         "vboxvideo"
+#define DRIVER_DESC         VBOX_PRODUCT " Graphics Card"
+#define DRIVER_DATE         "20130823"
+
+#define DRIVER_MAJOR        1
+#define DRIVER_MINOR        0
+#define DRIVER_PATCHLEVEL   0
+
+#define VBOX_MAX_CURSOR_WIDTH  64
+#define VBOX_MAX_CURSOR_HEIGHT 64
+#define CURSOR_PIXEL_COUNT VBOX_MAX_CURSOR_WIDTH * VBOX_MAX_CURSOR_HEIGHT
+#define CURSOR_DATA_SIZE CURSOR_PIXEL_COUNT * 4 + CURSOR_PIXEL_COUNT / 8
+
+struct vbox_fbdev;
+
+struct vbox_private {
+    struct drm_device *dev;
+
+    uint8_t __iomem *vram;
+    HGSMIGUESTCOMMANDCONTEXT submit_info;
+    struct VBVABUFFERCONTEXT *vbva_info;
+    bool any_pitch;
+    unsigned num_crtcs;
+    bool vga2_clone;
+    /** Amount of available VRAM, including space used for buffers. */
+    uint32_t full_vram_size;
+    /** Amount of available VRAM, not including space used for buffers. */
+    uint32_t vram_size;
+    /** Offset to the host flags in the VRAM. */
+    uint32_t host_flags_offset;
+    /** Array of structures for receiving mode hints. */
+    VBVAMODEHINT *last_mode_hints;
+
+    struct vbox_fbdev *fbdev;
+
+    int fb_mtrr;
+
+    struct {
+        struct drm_global_reference mem_global_ref;
+        struct ttm_bo_global_ref bo_global_ref;
+        struct ttm_bo_device bdev;
+        bool mm_initialised;
+    } ttm;
+
+    struct mutex hw_mutex;
+    bool isr_installed;
+    /** We decide whether or not user-space supports display hot-plug
+     * depending on whether they react to a hot-plug event after the initial
+     * mode query. */
+    bool initial_mode_queried;
+    struct work_struct hotplug_work;
+    uint32_t input_mapping_width;
+    uint32_t input_mapping_height;
+    uint32_t cursor_width;
+    uint32_t cursor_height;
+    uint32_t cursor_hot_x;
+    uint32_t cursor_hot_y;
+    size_t cursor_data_size;
+    uint8_t cursor_data[CURSOR_DATA_SIZE];
+};
+
+#undef CURSOR_PIXEL_COUNT
+#undef CURSOR_DATA_SIZE
+
+int vbox_driver_load(struct drm_device *dev, unsigned long flags);
+int vbox_driver_unload(struct drm_device *dev);
+void vbox_driver_lastclose(struct drm_device *dev);
+
+struct vbox_gem_object;
+
+#ifndef VGA_PORT_HGSMI_HOST
+# define VGA_PORT_HGSMI_HOST             0x3b0
+# define VGA_PORT_HGSMI_GUEST            0x3d0
+#endif
+
+struct vbox_connector {
+    struct drm_connector base;
+    char name[32];
+    struct vbox_crtc *vbox_crtc;
+    struct {
+        uint16_t width;
+        uint16_t height;
+        bool disconnected;
+    } mode_hint;
+};
+
+struct vbox_crtc {
+    struct drm_crtc base;
+    bool blanked;
+    bool disconnected;
+    unsigned crtc_id;
+    uint32_t fb_offset;
+    bool cursor_enabled;
+};
+
+struct vbox_encoder {
+    struct drm_encoder base;
+};
+
+struct vbox_framebuffer {
+    struct drm_framebuffer base;
+    struct drm_gem_object *obj;
+};
+
+struct vbox_fbdev {
+    struct drm_fb_helper helper;
+    struct vbox_framebuffer afb;
+    void *sysram;
+    int size;
+    struct ttm_bo_kmap_obj mapping;
+    int x1, y1, x2, y2; /* dirty rect */
+    spinlock_t dirty_lock;
+};
+
+#define to_vbox_crtc(x) container_of(x, struct vbox_crtc, base)
+#define to_vbox_connector(x) container_of(x, struct vbox_connector, base)
+#define to_vbox_encoder(x) container_of(x, struct vbox_encoder, base)
+#define to_vbox_framebuffer(x) container_of(x, struct vbox_framebuffer, base)
+
+extern int vbox_mode_init(struct drm_device *dev);
+extern void vbox_mode_fini(struct drm_device *dev);
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 3, 0)
+# define DRM_MODE_FB_CMD drm_mode_fb_cmd
+#else
+# define DRM_MODE_FB_CMD drm_mode_fb_cmd2
+#endif
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 15, 0)
+# define CRTC_FB(crtc) (crtc)->fb
+#else
+# define CRTC_FB(crtc) (crtc)->primary->fb
+#endif
+
+void vbox_enable_accel(struct vbox_private *vbox);
+void vbox_disable_accel(struct vbox_private *vbox);
+void vbox_enable_caps(struct vbox_private *vbox);
+
+void vbox_framebuffer_dirty_rectangles(struct drm_framebuffer *fb,
+                                       struct drm_clip_rect *rects,
+                                       unsigned num_rects);
+
+int vbox_framebuffer_init(struct drm_device *dev,
+             struct vbox_framebuffer *vbox_fb,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 5, 0)
+             const
+#endif
+             struct DRM_MODE_FB_CMD *mode_cmd,
+             struct drm_gem_object *obj);
+
+int vbox_fbdev_init(struct drm_device *dev);
+void vbox_fbdev_fini(struct drm_device *dev);
+void vbox_fbdev_set_suspend(struct drm_device *dev, int state);
+
+struct vbox_bo {
+    struct ttm_buffer_object bo;
+    struct ttm_placement placement;
+    struct ttm_bo_kmap_obj kmap;
+    struct drm_gem_object gem;
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 18, 0)
+    u32 placements[3];
+#else
+    struct ttm_place placements[3];
+#endif
+    int pin_count;
+};
+#define gem_to_vbox_bo(gobj) container_of((gobj), struct vbox_bo, gem)
+
+static inline struct vbox_bo *
+vbox_bo(struct ttm_buffer_object *bo)
+{
+    return container_of(bo, struct vbox_bo, bo);
+}
+
+
+#define to_vbox_obj(x) container_of(x, struct vbox_gem_object, base)
+
+extern int vbox_dumb_create(struct drm_file *file,
+               struct drm_device *dev,
+               struct drm_mode_create_dumb *args);
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 12, 0)
+extern int vbox_dumb_destroy(struct drm_file *file,
+                struct drm_device *dev,
+                uint32_t handle);
+#endif
+
+extern void vbox_gem_free_object(struct drm_gem_object *obj);
+extern int vbox_dumb_mmap_offset(struct drm_file *file,
+                struct drm_device *dev,
+                uint32_t handle,
+                uint64_t *offset);
+
+#define DRM_FILE_PAGE_OFFSET (0x100000000ULL >> PAGE_SHIFT)
+
+int vbox_mm_init(struct vbox_private *vbox);
+void vbox_mm_fini(struct vbox_private *vbox);
+
+int vbox_bo_create(struct drm_device *dev, int size, int align,
+          uint32_t flags, struct vbox_bo **pvboxbo);
+
+int vbox_gem_create(struct drm_device *dev,
+           u32 size, bool iskernel,
+           struct drm_gem_object **obj);
+
+int vbox_bo_pin(struct vbox_bo *bo, u32 pl_flag, u64 *gpu_addr);
+int vbox_bo_unpin(struct vbox_bo *bo);
+
+static inline int vbox_bo_reserve(struct vbox_bo *bo, bool no_wait)
+{
+    int ret;
+
+    ret = ttm_bo_reserve(&bo->bo, true, no_wait, false, 0);
+    if (ret)
+    {
+        if (ret != -ERESTARTSYS && ret != -EBUSY)
+            DRM_ERROR("reserve failed %p\n", bo);
+        return ret;
+    }
+    return 0;
+}
+
+static inline void vbox_bo_unreserve(struct vbox_bo *bo)
+{
+    ttm_bo_unreserve(&bo->bo);
+}
+
+void vbox_ttm_placement(struct vbox_bo *bo, int domain);
+int vbox_bo_push_sysram(struct vbox_bo *bo);
+int vbox_mmap(struct file *filp, struct vm_area_struct *vma);
+
+/* vbox_irq.c */
+int vbox_irq_init(struct vbox_private *vbox);
+void vbox_irq_fini(struct vbox_private *vbox);
+void vbox_report_hotplug(struct vbox_private *vbox);
+irqreturn_t vbox_irq_handler(int irq, void *arg);
+#endif
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/vboxvideo/vbox_dummy.c
@@ -0,0 +1,32 @@
+/*  $Id: vbox_dummy.c $ */
+/** @file
+ * VirtualBox Additions Linux kernel video driver, dummy driver for
+ * older kernels.
+ */
+
+/*
+ * Copyright (C) 2016 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+#include <linux/module.h>
+
+static int __init vbox_init(void)
+{
+    return -EINVAL;
+}
+static void __exit vbox_exit(void)
+{
+}
+
+module_init(vbox_init);
+module_exit(vbox_exit);
+
+MODULE_LICENSE("GPL");
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/vboxvideo/vbox_fb.c
@@ -0,0 +1,454 @@
+/* $Id: vbox_fb.c $ */
+/** @file
+ * VirtualBox Additions Linux kernel video driver
+ */
+
+/*
+ * Copyright (C) 2013 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ * --------------------------------------------------------------------
+ *
+ * This code is based on
+ * ast_fb.c
+ * with the following copyright and permission notice:
+ *
+ * Copyright 2012 Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ */
+/*
+ * Authors: Dave Airlie <airlied@redhat.com>
+ */
+/* Include from most specific to most general to be able to override things. */
+#include "vbox_drv.h"
+#include <VBox/VBoxVideo.h>
+#include <VBox/VMMDev.h>
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/tty.h>
+#include <linux/sysrq.h>
+#include <linux/delay.h>
+#include <linux/fb.h>
+#include <linux/init.h>
+
+
+#include <drm/drmP.h>
+#include <drm/drm_crtc.h>
+#include <drm/drm_fb_helper.h>
+#include <drm/drm_crtc_helper.h>
+#include "vbox_drv.h"
+
+/**
+ * Tell the host about dirty rectangles to update.
+ */
+static void vbox_dirty_update(struct vbox_fbdev *fbdev,
+                 int x, int y, int width, int height)
+{
+    struct drm_device *dev = fbdev->helper.dev;
+    int i;
+
+    struct drm_gem_object *obj;
+    struct vbox_bo *bo;
+    int src_offset, dst_offset;
+    int bpp = (fbdev->afb.base.bits_per_pixel + 7)/8;
+    int ret = -EBUSY;
+    bool unmap = false;
+    bool store_for_later = false;
+    int x2, y2;
+    unsigned long flags;
+    struct drm_clip_rect rect;
+
+    LogFunc(("vboxvideo: %d\n", __LINE__));
+    obj = fbdev->afb.obj;
+    bo = gem_to_vbox_bo(obj);
+
+    /*
+     * try and reserve the BO, if we fail with busy
+     * then the BO is being moved and we should
+     * store up the damage until later.
+     */
+    if (drm_can_sleep())
+        ret = vbox_bo_reserve(bo, true);
+    if (ret) {
+        if (ret != -EBUSY)
+            return;
+
+        store_for_later = true;
+    }
+
+    x2 = x + width - 1;
+    y2 = y + height - 1;
+    spin_lock_irqsave(&fbdev->dirty_lock, flags);
+
+    if (fbdev->y1 < y)
+        y = fbdev->y1;
+    if (fbdev->y2 > y2)
+        y2 = fbdev->y2;
+    if (fbdev->x1 < x)
+        x = fbdev->x1;
+    if (fbdev->x2 > x2)
+        x2 = fbdev->x2;
+
+    if (store_for_later) {
+        fbdev->x1 = x;
+        fbdev->x2 = x2;
+        fbdev->y1 = y;
+        fbdev->y2 = y2;
+        spin_unlock_irqrestore(&fbdev->dirty_lock, flags);
+        LogFunc(("vboxvideo: %d\n", __LINE__));
+        return;
+    }
+
+    fbdev->x1 = fbdev->y1 = INT_MAX;
+    fbdev->x2 = fbdev->y2 = 0;
+    spin_unlock_irqrestore(&fbdev->dirty_lock, flags);
+
+    if (!bo->kmap.virtual) {
+        ret = ttm_bo_kmap(&bo->bo, 0, bo->bo.num_pages, &bo->kmap);
+        if (ret) {
+            DRM_ERROR("failed to kmap fb updates\n");
+            vbox_bo_unreserve(bo);
+            return;
+        }
+        unmap = true;
+    }
+    for (i = y; i <= y2; i++) {
+        /* assume equal stride for now */
+        src_offset = dst_offset = i * fbdev->afb.base.pitches[0] + (x * bpp);
+        memcpy_toio(bo->kmap.virtual + src_offset, (char *)fbdev->sysram + src_offset, (x2 - x + 1) * bpp);
+    }
+    /* Not sure why the original code subtracted 1 here, but I will keep it that
+     * way to avoid unnecessary differences. */
+    rect.x1 = x;
+    rect.x2 = x2 + 1;
+    rect.y1 = y;
+    rect.y2 = y2 + 1;
+    vbox_framebuffer_dirty_rectangles(&fbdev->afb.base, &rect, 1);
+    LogFunc(("vboxvideo: %d, bo->kmap.virtual=%p, fbdev->sysram=%p, x=%d, y=%d, x2=%d, y2=%d, unmap=%RTbool\n",
+             __LINE__, bo->kmap.virtual, fbdev->sysram, (int)x, (int)y, (int)x2, (int)y2, unmap));
+    if (unmap)
+        ttm_bo_kunmap(&bo->kmap);
+
+    vbox_bo_unreserve(bo);
+}
+
+static void vbox_fillrect(struct fb_info *info,
+             const struct fb_fillrect *rect)
+{
+    struct vbox_fbdev *fbdev = info->par;
+    LogFunc(("vboxvideo: %d\n", __LINE__));
+    sys_fillrect(info, rect);
+    vbox_dirty_update(fbdev, rect->dx, rect->dy, rect->width,
+             rect->height);
+}
+
+static void vbox_copyarea(struct fb_info *info,
+             const struct fb_copyarea *area)
+{
+    struct vbox_fbdev *fbdev = info->par;
+    LogFunc(("vboxvideo: %d\n", __LINE__));
+    sys_copyarea(info, area);
+    vbox_dirty_update(fbdev, area->dx, area->dy, area->width,
+             area->height);
+}
+
+static void vbox_imageblit(struct fb_info *info,
+              const struct fb_image *image)
+{
+    struct vbox_fbdev *fbdev = info->par;
+    LogFunc(("vboxvideo: %d\n", __LINE__));
+    sys_imageblit(info, image);
+    vbox_dirty_update(fbdev, image->dx, image->dy, image->width,
+             image->height);
+}
+
+static struct fb_ops vboxfb_ops = {
+    .owner = THIS_MODULE,
+    .fb_check_var = drm_fb_helper_check_var,
+    .fb_set_par = drm_fb_helper_set_par,
+    .fb_fillrect = vbox_fillrect,
+    .fb_copyarea = vbox_copyarea,
+    .fb_imageblit = vbox_imageblit,
+    .fb_pan_display = drm_fb_helper_pan_display,
+    .fb_blank = drm_fb_helper_blank,
+    .fb_setcmap = drm_fb_helper_setcmap,
+    .fb_debug_enter = drm_fb_helper_debug_enter,
+    .fb_debug_leave = drm_fb_helper_debug_leave,
+};
+
+static int vboxfb_create_object(struct vbox_fbdev *fbdev,
+                   struct DRM_MODE_FB_CMD *mode_cmd,
+                   struct drm_gem_object **gobj_p)
+{
+    struct drm_device *dev = fbdev->helper.dev;
+    u32 bpp, depth;
+    u32 size;
+    struct drm_gem_object *gobj;
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 3, 0)
+    __u32 pitch = mode_cmd->pitch;
+#else
+    __u32 pitch = mode_cmd->pitches[0];
+#endif
+
+    int ret = 0;
+    LogFunc(("vboxvideo: %d\n", __LINE__));
+    drm_fb_get_bpp_depth(mode_cmd->pixel_format, &depth, &bpp);
+
+    size = pitch * mode_cmd->height;
+    ret = vbox_gem_create(dev, size, true, &gobj);
+    if (ret)
+        return ret;
+
+    *gobj_p = gobj;
+    LogFunc(("vboxvideo: %d\n", __LINE__));
+    return ret;
+}
+
+static int vboxfb_create(struct drm_fb_helper *helper,
+            struct drm_fb_helper_surface_size *sizes)
+{
+    struct vbox_fbdev *fbdev =
+            container_of(helper, struct vbox_fbdev, helper);
+    struct drm_device *dev = fbdev->helper.dev;
+    struct DRM_MODE_FB_CMD mode_cmd;
+    struct drm_framebuffer *fb;
+    struct fb_info *info;
+    __u32 pitch;
+    int size, ret;
+    struct device *device = &dev->pdev->dev;
+    void *sysram;
+    struct drm_gem_object *gobj = NULL;
+    struct vbox_bo *bo = NULL;
+    LogFunc(("vboxvideo: %d\n", __LINE__));
+    mode_cmd.width = sizes->surface_width;
+    mode_cmd.height = sizes->surface_height;
+    pitch = mode_cmd.width * ((sizes->surface_bpp + 7) / 8);
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 3, 0)
+    mode_cmd.bpp = sizes->surface_bpp;
+    mode_cmd.depth = sizes->surface_depth;
+    mode_cmd.pitch = pitch;
+#else
+    mode_cmd.pixel_format = drm_mode_legacy_fb_format(sizes->surface_bpp,
+                                                      sizes->surface_depth);
+    mode_cmd.pitches[0] = pitch;
+#endif
+
+    size = pitch * mode_cmd.height;
+
+    ret = vboxfb_create_object(fbdev, &mode_cmd, &gobj);
+    if (ret) {
+        DRM_ERROR("failed to create fbcon backing object %d\n", ret);
+        return ret;
+    }
+    bo = gem_to_vbox_bo(gobj);
+
+    sysram = vmalloc(size);
+    if (!sysram)
+        return -ENOMEM;
+
+    info = framebuffer_alloc(0, device);
+    if (!info) {
+        ret = -ENOMEM;
+        goto out;
+    }
+    info->par = fbdev;
+
+    ret = vbox_framebuffer_init(dev, &fbdev->afb, &mode_cmd, gobj);
+    if (ret)
+        goto out;
+
+    fbdev->sysram = sysram;
+    fbdev->size = size;
+
+    fb = &fbdev->afb.base;
+    fbdev->helper.fb = fb;
+    fbdev->helper.fbdev = info;
+
+    strcpy(info->fix.id, "vboxdrmfb");
+
+    /* The last flag forces a mode set on VT switches even if the kernel does
+     * not think it is needed. */
+    info->flags =   FBINFO_DEFAULT | FBINFO_CAN_FORCE_OUTPUT
+                  | FBINFO_MISC_ALWAYS_SETPAR;
+    info->fbops = &vboxfb_ops;
+
+    ret = fb_alloc_cmap(&info->cmap, 256, 0);
+    if (ret) {
+        ret = -ENOMEM;
+        goto out;
+    }
+
+    /* This seems to be done for safety checking that the framebuffer is not
+     * registered twice by different drivers. */
+    info->apertures = alloc_apertures(1);
+    if (!info->apertures) {
+        ret = -ENOMEM;
+        goto out;
+    }
+    info->apertures->ranges[0].base = pci_resource_start(dev->pdev, 0);
+    info->apertures->ranges[0].size = pci_resource_len(dev->pdev, 0);
+
+    drm_fb_helper_fill_fix(info, fb->pitches[0], fb->depth);
+    drm_fb_helper_fill_var(info, &fbdev->helper, sizes->fb_width, sizes->fb_height);
+
+    info->screen_base = sysram;
+    info->screen_size = size;
+
+    info->pixmap.flags = FB_PIXMAP_SYSTEM;
+
+    DRM_DEBUG_KMS("allocated %dx%d\n",
+              fb->width, fb->height);
+
+    LogFunc(("vboxvideo: %d\n", __LINE__));
+    return 0;
+out:
+    LogFunc(("vboxvideo: %d\n", __LINE__));
+    return ret;
+}
+
+static void vbox_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green,
+                   u16 blue, int regno)
+{
+
+}
+
+static void vbox_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green,
+                   u16 *blue, int regno)
+{
+    *red = regno;
+    *green = regno;
+    *blue = regno;
+}
+
+static struct drm_fb_helper_funcs vbox_fb_helper_funcs = {
+    .gamma_set = vbox_fb_gamma_set,
+    .gamma_get = vbox_fb_gamma_get,
+    .fb_probe = vboxfb_create,
+};
+
+static void vbox_fbdev_destroy(struct drm_device *dev,
+                  struct vbox_fbdev *fbdev)
+{
+    struct fb_info *info;
+    struct vbox_framebuffer *afb = &fbdev->afb;
+    LogFunc(("vboxvideo: %d\n", __LINE__));
+    if (fbdev->helper.fbdev) {
+        info = fbdev->helper.fbdev;
+        unregister_framebuffer(info);
+        if (info->cmap.len)
+            fb_dealloc_cmap(&info->cmap);
+        framebuffer_release(info);
+    }
+
+    if (afb->obj) {
+        drm_gem_object_unreference_unlocked(afb->obj);
+        afb->obj = NULL;
+    }
+    drm_fb_helper_fini(&fbdev->helper);
+
+    vfree(fbdev->sysram);
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0)
+    drm_framebuffer_unregister_private(&afb->base);
+#endif
+    drm_framebuffer_cleanup(&afb->base);
+    LogFunc(("vboxvideo: %d\n", __LINE__));
+}
+
+int vbox_fbdev_init(struct drm_device *dev)
+{
+    struct vbox_private *vbox = dev->dev_private;
+    struct vbox_fbdev *fbdev;
+    int ret;
+
+    LogFunc(("vboxvideo: %d\n", __LINE__));
+    fbdev = kzalloc(sizeof(struct vbox_fbdev), GFP_KERNEL);
+    if (!fbdev)
+        return -ENOMEM;
+
+    vbox->fbdev = fbdev;
+    spin_lock_init(&fbdev->dirty_lock);
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 17, 0)
+    fbdev->helper.funcs = &vbox_fb_helper_funcs;
+#else
+    drm_fb_helper_prepare(dev, &fbdev->helper, &vbox_fb_helper_funcs);
+#endif
+    ret = drm_fb_helper_init(dev, &fbdev->helper, vbox->num_crtcs, vbox->num_crtcs);
+    if (ret)
+        goto free;
+
+    ret = drm_fb_helper_single_add_all_connectors(&fbdev->helper);
+    if (ret)
+        goto fini;
+
+    /* disable all the possible outputs/crtcs before entering KMS mode */
+    drm_helper_disable_unused_functions(dev);
+
+    ret = drm_fb_helper_initial_config(&fbdev->helper, 32);
+    if (ret)
+        goto fini;
+
+    LogFunc(("vboxvideo: %d\n", __LINE__));
+    return 0;
+fini:
+    drm_fb_helper_fini(&fbdev->helper);
+free:
+    kfree(fbdev);
+    vbox->fbdev = NULL;
+    LogFunc(("vboxvideo: %d, ret=%d\n", __LINE__, ret));
+    return ret;
+}
+
+void vbox_fbdev_fini(struct drm_device *dev)
+{
+    struct vbox_private *vbox = dev->dev_private;
+
+    if (!vbox->fbdev)
+        return;
+
+    LogFunc(("vboxvideo: %d\n", __LINE__));
+    vbox_fbdev_destroy(dev, vbox->fbdev);
+    kfree(vbox->fbdev);
+    vbox->fbdev = NULL;
+}
+
+void vbox_fbdev_set_suspend(struct drm_device *dev, int state)
+{
+    struct vbox_private *vbox = dev->dev_private;
+
+    LogFunc(("vboxvideo: %d\n", __LINE__));
+    if (!vbox->fbdev)
+        return;
+
+    fb_set_suspend(vbox->fbdev->helper.fbdev, state);
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/vboxvideo/vbox_irq.c
@@ -0,0 +1,187 @@
+/* $Id: vbox_irq.c $ */
+/** @file
+ * VirtualBox Additions Linux kernel video driver
+ */
+
+/*
+ * Copyright (C) 2016 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ * --------------------------------------------------------------------
+ *
+ * This code is based on
+ * qxl_irq.c
+ * with the following copyright and permission notice:
+ *
+ * Copyright 2013 Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Dave Airlie
+ *          Alon Levy
+ */
+
+#include "vbox_drv.h"
+
+#include <VBox/VBoxVideo.h>
+
+#include <drm/drm_crtc_helper.h>
+
+static void vbox_clear_irq(void)
+{
+    outl((uint32_t)~0, VGA_PORT_HGSMI_HOST);
+}
+
+static uint32_t vbox_get_flags(struct vbox_private *vbox)
+{
+    return (uint32_t)readl(vbox->vram + vbox->host_flags_offset);
+}
+
+void vbox_report_hotplug(struct vbox_private *vbox)
+{
+    schedule_work(&vbox->hotplug_work);
+}
+
+irqreturn_t vbox_irq_handler(int irq, void *arg)
+{
+    struct drm_device *dev = (struct drm_device *) arg;
+    struct vbox_private *vbox = (struct vbox_private *)dev->dev_private;
+    uint32_t host_flags = vbox_get_flags(vbox);
+
+    if (!(host_flags & HGSMIHOSTFLAGS_IRQ))
+        return IRQ_NONE;
+
+    /* Due to a bug in the initial host implementation of hot-plug interrupts,
+     * the hot-plug and cursor capability flags were never cleared.  Fortunately
+     * we can tell when they would have been set by checking that the VSYNC flag
+     * is not set. */
+    if (   host_flags & (HGSMIHOSTFLAGS_HOTPLUG | HGSMIHOSTFLAGS_CURSOR_CAPABILITIES)
+        && !(host_flags & HGSMIHOSTFLAGS_VSYNC))
+        vbox_report_hotplug(vbox);
+    vbox_clear_irq();
+    return IRQ_HANDLED;
+}
+
+/**
+ * Query the host for 
+ */
+static void vbox_update_mode_hints(struct vbox_private *vbox)
+{
+    struct drm_device *dev = vbox->dev;
+    struct drm_connector *connector;
+    struct vbox_connector *vbox_connector;
+    struct VBVAMODEHINT *hints;
+    uint16_t flags;
+    bool disconnected;
+    unsigned crtc_id;
+    int rc;
+
+    rc = VBoxHGSMIGetModeHints(&vbox->submit_info, vbox->num_crtcs,
+                               vbox->last_mode_hints);
+    AssertMsgRCReturnVoid(rc, ("VBoxHGSMIGetModeHints failed, rc=%Rrc.\n", rc));
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0)
+    drm_modeset_lock_all(dev);
+#else
+    mutex_lock(&dev->mode_config.mutex);
+#endif
+    list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
+        vbox_connector = to_vbox_connector(connector);
+        hints = &vbox->last_mode_hints[vbox_connector->vbox_crtc->crtc_id];
+        if (hints->magic == VBVAMODEHINT_MAGIC) {
+            LogFunc(("vboxvideo: %d: crtc_id=%u, mode %hdx%hd(enabled:%d),%hdx%hd\n",
+                     __LINE__, (unsigned)vbox_connector->vbox_crtc->crtc_id,
+                     (short)hints->cx, (short)hints->cy, (int)hints->fEnabled,
+                     (short)hints->dx, (short)hints->dy));
+            disconnected = !(hints->fEnabled);
+            crtc_id = vbox_connector->vbox_crtc->crtc_id;
+            flags =   VBVA_SCREEN_F_ACTIVE
+                    | (disconnected ? VBVA_SCREEN_F_DISABLED : VBVA_SCREEN_F_BLANK);
+            vbox_connector->mode_hint.width = hints->cx & 0x8fff;
+            vbox_connector->mode_hint.height = hints->cy & 0x8fff;
+            vbox_connector->mode_hint.disconnected = disconnected;
+            if (vbox_connector->vbox_crtc->disconnected != disconnected) {
+                VBoxHGSMIProcessDisplayInfo(&vbox->submit_info, crtc_id,
+                                            0, 0, 0, hints->cx * 4, hints->cx,
+                                            hints->cy, 0, flags);
+                vbox_connector->vbox_crtc->disconnected = disconnected;
+            }
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0)
+            if ((hints->dx < 0xffff) && (hints->dy < 0xffff)) {
+                drm_object_property_set_value(&connector->base,
+                    dev->mode_config.suggested_x_property, hints->dx & 0x8fff);
+                drm_object_property_set_value(&connector->base,
+                    dev->mode_config.suggested_y_property, hints->dy & 0x8fff);
+            }
+#endif
+        }
+    }
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0)
+    drm_modeset_unlock_all(dev);
+#else
+    mutex_unlock(&dev->mode_config.mutex);
+#endif
+}
+
+static void vbox_hotplug_worker(struct work_struct *work)
+{
+    struct vbox_private *vbox = container_of(work, struct vbox_private,
+                                             hotplug_work);
+
+    LogFunc(("vboxvideo: %d: vbox=%p\n", __LINE__, vbox));
+    vbox_update_mode_hints(vbox);
+    drm_kms_helper_hotplug_event(vbox->dev);
+}
+
+int vbox_irq_init(struct vbox_private *vbox)
+{
+    int ret;
+
+    LogFunc(("vboxvideo: %d: vbox=%p\n", __LINE__, vbox));
+    vbox_update_mode_hints(vbox);
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0)
+    ret = drm_irq_install(vbox->dev, vbox->dev->pdev->irq);
+#else
+    ret = drm_irq_install(vbox->dev);
+#endif
+    if (unlikely(ret != 0)) {
+        vbox_irq_fini(vbox);
+        DRM_ERROR("Failed installing irq: %d\n", ret);
+        return 1;
+    }
+    INIT_WORK(&vbox->hotplug_work, vbox_hotplug_worker);
+    vbox->isr_installed = true;
+    LogFunc(("vboxvideo: %d: vbox=%p\n", __LINE__, vbox));
+    return 0;
+}
+
+void vbox_irq_fini(struct vbox_private *vbox)
+{
+    LogFunc(("vboxvideo: %d: vbox=%p\n", __LINE__, vbox));
+    if (vbox->isr_installed) {
+        drm_irq_uninstall(vbox->dev);
+        flush_work(&vbox->hotplug_work);
+        vbox->isr_installed = false;
+    }
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/vboxvideo/vbox_main.c
@@ -0,0 +1,566 @@
+/* $Id: vbox_main.c $ */
+/** @file
+ * VirtualBox Additions Linux kernel video driver
+ */
+
+/*
+ * Copyright (C) 2013 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ * --------------------------------------------------------------------
+ *
+ * This code is based on
+ * ast_main.c
+ * with the following copyright and permission notice:
+ *
+ * Copyright 2012 Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ */
+/*
+ * Authors: Dave Airlie <airlied@redhat.com>
+ */
+#include "vbox_drv.h"
+
+#include <VBox/VBoxVideoGuest.h>
+#include <VBox/VBoxVideo.h>
+
+#include <drm/drm_fb_helper.h>
+#include <drm/drm_crtc_helper.h>
+
+static void vbox_user_framebuffer_destroy(struct drm_framebuffer *fb)
+{
+    struct vbox_framebuffer *vbox_fb = to_vbox_framebuffer(fb);
+    if (vbox_fb->obj)
+        drm_gem_object_unreference_unlocked(vbox_fb->obj);
+
+    LogFunc(("vboxvideo: %d: vbox_fb=%p, vbox_fb->obj=%p\n", __LINE__,
+             vbox_fb, vbox_fb->obj));
+    drm_framebuffer_cleanup(fb);
+    kfree(fb);
+}
+
+void vbox_enable_accel(struct vbox_private *vbox)
+{
+    unsigned i;
+    struct VBVABUFFER *vbva;
+
+    AssertLogRelReturnVoid(vbox->vbva_info != NULL);
+    for (i = 0; i < vbox->num_crtcs; ++i) {
+        if (vbox->vbva_info[i].pVBVA == NULL) {
+            LogFunc(("vboxvideo: enabling VBVA.\n"));
+            vbva = (struct VBVABUFFER *) (  ((uint8_t *)vbox->vram)
+                                           + vbox->vram_size
+                                           + i * VBVA_MIN_BUFFER_SIZE);
+            if (!VBoxVBVAEnable(&vbox->vbva_info[i], &vbox->submit_info, vbva, i))
+                AssertReleaseMsgFailed(("VBoxVBVAEnable failed - heap allocation error, very old host or driver error.\n"));
+        }
+    }
+}
+
+void vbox_disable_accel(struct vbox_private *vbox)
+{
+    unsigned i;
+
+    for (i = 0; i < vbox->num_crtcs; ++i)
+        VBoxVBVADisable(&vbox->vbva_info[i], &vbox->submit_info, i);
+}
+
+void vbox_enable_caps(struct vbox_private *vbox)
+{
+    uint32_t caps =   VBVACAPS_DISABLE_CURSOR_INTEGRATION
+                     | VBVACAPS_IRQ
+                     | VBVACAPS_USE_VBVA_ONLY;
+    if (vbox->initial_mode_queried)
+        caps |= VBVACAPS_VIDEO_MODE_HINTS;
+    VBoxHGSMISendCapsInfo(&vbox->submit_info, caps);
+}
+
+/** Send information about dirty rectangles to VBVA.  If necessary we enable
+ * VBVA first, as this is normally disabled after a change of master in case
+ * the new master does not send dirty rectangle information (is this even
+ * allowed?) */
+void vbox_framebuffer_dirty_rectangles(struct drm_framebuffer *fb,
+                                       struct drm_clip_rect *rects,
+                                       unsigned num_rects)
+{
+    struct vbox_private *vbox = fb->dev->dev_private;
+    unsigned i;
+
+    LogFunc(("vboxvideo: %d: fb=%p, num_rects=%u, vbox=%p\n", __LINE__, fb,
+             num_rects, vbox));
+    vbox_enable_accel(vbox);
+    mutex_lock(&vbox->hw_mutex);
+    for (i = 0; i < num_rects; ++i)
+    {
+        struct drm_crtc *crtc;
+        list_for_each_entry(crtc, &fb->dev->mode_config.crtc_list, head)
+        {
+            unsigned crtc_id = to_vbox_crtc(crtc)->crtc_id;
+            VBVACMDHDR cmd_hdr;
+
+            if (   CRTC_FB(crtc) != fb
+                || rects[i].x1 >   crtc->x
+                                  + crtc->hwmode.hdisplay
+                || rects[i].y1 >   crtc->y
+                                  + crtc->hwmode.vdisplay
+                || rects[i].x2 < crtc->x
+                || rects[i].y2 < crtc->y)
+                continue;
+            cmd_hdr.x = (int16_t)rects[i].x1;
+            cmd_hdr.y = (int16_t)rects[i].y1;
+            cmd_hdr.w = (uint16_t)rects[i].x2 - rects[i].x1;
+            cmd_hdr.h = (uint16_t)rects[i].y2 - rects[i].y1;
+            if (VBoxVBVABufferBeginUpdate(&vbox->vbva_info[crtc_id],
+                                          &vbox->submit_info))
+            {
+                VBoxVBVAWrite(&vbox->vbva_info[crtc_id], &vbox->submit_info, &cmd_hdr,
+                              sizeof(cmd_hdr));
+                VBoxVBVABufferEndUpdate(&vbox->vbva_info[crtc_id]);
+            }
+        }
+    }
+    mutex_unlock(&vbox->hw_mutex);
+    LogFunc(("vboxvideo: %d\n", __LINE__));
+}
+
+static int vbox_user_framebuffer_dirty(struct drm_framebuffer *fb,
+                                       struct drm_file *file_priv,
+                                       unsigned flags, unsigned color,
+                                       struct drm_clip_rect *rects,
+                                       unsigned num_rects)
+{
+    LogFunc(("vboxvideo: %d, flags=%u\n", __LINE__, flags));
+    vbox_framebuffer_dirty_rectangles(fb, rects, num_rects);
+    return 0;
+}
+
+static const struct drm_framebuffer_funcs vbox_fb_funcs = {
+    .destroy = vbox_user_framebuffer_destroy,
+    .dirty = vbox_user_framebuffer_dirty,
+};
+
+
+int vbox_framebuffer_init(struct drm_device *dev,
+             struct vbox_framebuffer *vbox_fb,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 5, 0)
+             const
+#endif
+             struct DRM_MODE_FB_CMD *mode_cmd,
+             struct drm_gem_object *obj)
+{
+    int ret;
+
+    LogFunc(("vboxvideo: %d: dev=%p, vbox_fb=%p, obj=%p\n", __LINE__, dev,
+             vbox_fb, obj));
+    drm_helper_mode_fill_fb_struct(&vbox_fb->base, mode_cmd);
+    vbox_fb->obj = obj;
+    ret = drm_framebuffer_init(dev, &vbox_fb->base, &vbox_fb_funcs);
+    if (ret) {
+        DRM_ERROR("framebuffer init failed %d\n", ret);
+        LogFunc(("vboxvideo: %d\n", __LINE__));
+        return ret;
+    }
+    LogFunc(("vboxvideo: %d\n", __LINE__));
+    return 0;
+}
+
+static struct drm_framebuffer *
+vbox_user_framebuffer_create(struct drm_device *dev,
+           struct drm_file *filp,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 5, 0)
+           const
+#endif
+           struct drm_mode_fb_cmd2 *mode_cmd)
+{
+    struct drm_gem_object *obj;
+    struct vbox_framebuffer *vbox_fb;
+    int ret;
+
+    LogFunc(("vboxvideo: %d\n", __LINE__));
+    obj = drm_gem_object_lookup(dev, filp, mode_cmd->handles[0]);
+    if (obj == NULL)
+        return ERR_PTR(-ENOENT);
+
+    vbox_fb = kzalloc(sizeof(*vbox_fb), GFP_KERNEL);
+    if (!vbox_fb) {
+        drm_gem_object_unreference_unlocked(obj);
+        return ERR_PTR(-ENOMEM);
+    }
+
+    ret = vbox_framebuffer_init(dev, vbox_fb, mode_cmd, obj);
+    if (ret) {
+        drm_gem_object_unreference_unlocked(obj);
+        kfree(vbox_fb);
+        return ERR_PTR(ret);
+    }
+    LogFunc(("vboxvideo: %d\n", __LINE__));
+    return &vbox_fb->base;
+}
+
+static const struct drm_mode_config_funcs vbox_mode_funcs = {
+    .fb_create = vbox_user_framebuffer_create,
+};
+
+static void vbox_accel_fini(struct vbox_private *vbox)
+{
+    if (vbox->vbva_info)
+    {
+        vbox_disable_accel(vbox);
+        kfree(vbox->vbva_info);
+        vbox->vbva_info = NULL;
+    }
+}
+
+static int vbox_accel_init(struct vbox_private *vbox)
+{
+    unsigned i;
+    LogFunc(("vboxvideo: %d: vbox=%p, vbox->num_crtcs=%u, vbox->vbva_info=%p\n",
+             __LINE__, vbox, (unsigned)vbox->num_crtcs, vbox->vbva_info));
+    if (!vbox->vbva_info)
+    {
+        vbox->vbva_info = kzalloc(  sizeof(struct VBVABUFFERCONTEXT)
+                                  * vbox->num_crtcs,
+                                  GFP_KERNEL);
+        if (!vbox->vbva_info)
+            return -ENOMEM;
+    }
+    /* Take a command buffer for each screen from the end of usable VRAM. */
+    vbox->vram_size -= vbox->num_crtcs * VBVA_MIN_BUFFER_SIZE;
+    for (i = 0; i < vbox->num_crtcs; ++i)
+        VBoxVBVASetupBufferContext(&vbox->vbva_info[i],
+                                   vbox->vram_size + i * VBVA_MIN_BUFFER_SIZE,
+                                   VBVA_MIN_BUFFER_SIZE);
+    LogFunc(("vboxvideo: %d: vbox->vbva_info=%p, vbox->vram_size=%u\n",
+             __LINE__, vbox->vbva_info, (unsigned)vbox->vram_size));
+    return 0;
+}
+
+/** Allocation function for the HGSMI heap and data. */
+static DECLCALLBACK(void *) alloc_hgsmi_environ(void *environ, HGSMISIZE size)
+{
+    NOREF(environ);
+    return kmalloc(size, GFP_KERNEL);
+}
+
+
+/** Free function for the HGSMI heap and data. */
+static DECLCALLBACK(void) free_hgsmi_environ(void *environ, void *ptr)
+{
+    NOREF(environ);
+    kfree(ptr);
+}
+
+
+/** Pointers to the HGSMI heap and data manipulation functions. */
+static HGSMIENV hgsmi_environ =
+{
+    NULL,
+    alloc_hgsmi_environ,
+    free_hgsmi_environ
+};
+
+
+/** Do we support the 4.3 plus mode hint reporting interface? */
+static bool have_hgsmi_mode_hints(struct vbox_private *vbox)
+{
+    uint32_t have_hints, have_cursor;
+
+    return    RT_SUCCESS(VBoxQueryConfHGSMI(&vbox->submit_info, VBOX_VBVA_CONF32_MODE_HINT_REPORTING, &have_hints))
+           && RT_SUCCESS(VBoxQueryConfHGSMI(&vbox->submit_info, VBOX_VBVA_CONF32_GUEST_CURSOR_REPORTING, &have_cursor))
+           && have_hints == VINF_SUCCESS
+           && have_cursor == VINF_SUCCESS;
+}
+
+
+/** Set up our heaps and data exchange buffers in VRAM before handing the rest
+ *  to the memory manager. */
+static int vbox_hw_init(struct vbox_private *vbox)
+{
+    uint32_t base_offset, guest_heap_offset, guest_heap_size, host_flags_offset;
+    void *guest_heap;
+
+    vbox->full_vram_size = VBoxVideoGetVRAMSize();
+    vbox->any_pitch = VBoxVideoAnyWidthAllowed();
+    DRM_INFO("VRAM %08x\n", vbox->full_vram_size);
+    VBoxHGSMIGetBaseMappingInfo(vbox->full_vram_size, &base_offset, NULL,
+                                &guest_heap_offset, &guest_heap_size, &host_flags_offset);
+    guest_heap =   ((uint8_t *)vbox->vram) + base_offset + guest_heap_offset;
+    vbox->host_flags_offset = base_offset + host_flags_offset;
+    if (RT_FAILURE(VBoxHGSMISetupGuestContext(&vbox->submit_info, guest_heap,
+                                              guest_heap_size,
+                                              base_offset + guest_heap_offset,
+                                              &hgsmi_environ)))
+        return -ENOMEM;
+    /* Reduce available VRAM size to reflect the guest heap. */
+    vbox->vram_size = base_offset;
+    /* Linux drm represents monitors as a 32-bit array. */
+    vbox->num_crtcs = RT_MIN(VBoxHGSMIGetMonitorCount(&vbox->submit_info), 32);
+    if (!have_hgsmi_mode_hints(vbox))
+        return -ENOTSUPP;
+    vbox->last_mode_hints = kzalloc(sizeof(VBVAMODEHINT) * vbox->num_crtcs, GFP_KERNEL);
+    if (!vbox->last_mode_hints)
+        return -ENOMEM;
+    return vbox_accel_init(vbox);
+}
+
+static void vbox_hw_fini(struct vbox_private *vbox)
+{
+    vbox_accel_fini(vbox);
+    if (vbox->last_mode_hints)
+        kfree(vbox->last_mode_hints);
+    vbox->last_mode_hints = NULL;
+}
+
+int vbox_driver_load(struct drm_device *dev, unsigned long flags)
+{
+    struct vbox_private *vbox;
+    int ret = 0;
+
+    LogFunc(("vboxvideo: %d: dev=%p\n", __LINE__, dev));
+    if (!VBoxHGSMIIsSupported())
+        return -ENODEV;
+    vbox = kzalloc(sizeof(struct vbox_private), GFP_KERNEL);
+    if (!vbox)
+        return -ENOMEM;
+
+    dev->dev_private = vbox;
+    vbox->dev = dev;
+
+    mutex_init(&vbox->hw_mutex);
+    /* I hope this won't interfere with the memory manager. */
+    vbox->vram = pci_iomap(dev->pdev, 0, 0);
+    if (!vbox->vram) {
+        ret = -EIO;
+        goto out_free;
+    }
+
+    ret = vbox_hw_init(vbox);
+    if (ret)
+        goto out_free;
+
+    ret = vbox_mm_init(vbox);
+    if (ret)
+        goto out_free;
+
+    drm_mode_config_init(dev);
+
+    dev->mode_config.funcs = (void *)&vbox_mode_funcs;
+    dev->mode_config.min_width = 64;
+    dev->mode_config.min_height = 64;
+    dev->mode_config.preferred_depth = 24;
+    dev->mode_config.max_width = VBE_DISPI_MAX_XRES;
+    dev->mode_config.max_height = VBE_DISPI_MAX_YRES;
+
+    ret = vbox_mode_init(dev);
+    if (ret)
+        goto out_free;
+
+    ret = vbox_irq_init(vbox);
+    if (ret)
+        goto out_free;
+
+    ret = vbox_fbdev_init(dev);
+    if (ret)
+        goto out_free;
+    LogFunc(("vboxvideo: %d: vbox=%p, vbox->vram=%p, vbox->full_vram_size=%u\n",
+             __LINE__, vbox, vbox->vram, (unsigned)vbox->full_vram_size));
+    return 0;
+out_free:
+    vbox_driver_unload(dev);
+    LogFunc(("vboxvideo: %d: ret=%d\n", __LINE__, ret));
+    return ret;
+}
+
+int vbox_driver_unload(struct drm_device *dev)
+{
+    struct vbox_private *vbox = dev->dev_private;
+
+    LogFunc(("vboxvideo: %d\n", __LINE__));
+    vbox_fbdev_fini(dev);
+    vbox_irq_fini(vbox);
+    vbox_mode_fini(dev);
+    if (dev->mode_config.funcs)
+        drm_mode_config_cleanup(dev);
+
+    vbox_hw_fini(vbox);
+    vbox_mm_fini(vbox);
+    if (vbox->vram)
+        pci_iounmap(dev->pdev, vbox->vram);
+    kfree(vbox);
+    dev->dev_private = NULL;
+    LogFunc(("vboxvideo: %d\n", __LINE__));
+    return 0;
+}
+
+/** @note this is described in the DRM framework documentation.  AST does not
+ *        have it, but we get an oops on driver unload if it is not present. */
+void vbox_driver_lastclose(struct drm_device *dev)
+{
+    struct vbox_private *vbox = dev->dev_private;
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0)
+    if (vbox->fbdev)
+        drm_fb_helper_restore_fbdev_mode_unlocked(&vbox->fbdev->helper);
+#else
+    mutex_lock(&dev->mode_config.mutex);
+    if (vbox->fbdev)
+        drm_fb_helper_restore_fbdev_mode(&vbox->fbdev->helper);
+    mutex_unlock(&dev->mode_config.mutex);
+#endif
+}
+
+int vbox_gem_create(struct drm_device *dev,
+           u32 size, bool iskernel,
+           struct drm_gem_object **obj)
+{
+    struct vbox_bo *vboxbo;
+    int ret;
+
+    LogFunc(("vboxvideo: %d: dev=%p, size=%u, iskernel=%u\n", __LINE__,
+             dev, (unsigned)size, (unsigned)iskernel));
+    *obj = NULL;
+
+    size = roundup(size, PAGE_SIZE);
+    if (size == 0)
+        return -EINVAL;
+
+    ret = vbox_bo_create(dev, size, 0, 0, &vboxbo);
+    if (ret) {
+        if (ret != -ERESTARTSYS)
+            DRM_ERROR("failed to allocate GEM object\n");
+        return ret;
+    }
+    *obj = &vboxbo->gem;
+    LogFunc(("vboxvideo: %d: obj=%p\n", __LINE__, obj));
+    return 0;
+}
+
+int vbox_dumb_create(struct drm_file *file,
+            struct drm_device *dev,
+            struct drm_mode_create_dumb *args)
+{
+    int ret;
+    struct drm_gem_object *gobj;
+    u32 handle;
+
+    LogFunc(("vboxvideo: %d: args->width=%u, args->height=%u, args->bpp=%u\n",
+             __LINE__, (unsigned)args->width, (unsigned)args->height,
+             (unsigned)args->bpp));
+    args->pitch = args->width * ((args->bpp + 7) / 8);
+    args->size = args->pitch * args->height;
+
+    ret = vbox_gem_create(dev, args->size, false,
+                 &gobj);
+    if (ret)
+        return ret;
+
+    ret = drm_gem_handle_create(file, gobj, &handle);
+    drm_gem_object_unreference_unlocked(gobj);
+    if (ret)
+        return ret;
+
+    args->handle = handle;
+    LogFunc(("vboxvideo: %d: args->handle=%u\n", __LINE__,
+             (unsigned)args->handle));
+    return 0;
+}
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 12, 0)
+int vbox_dumb_destroy(struct drm_file *file,
+             struct drm_device *dev,
+             uint32_t handle)
+{
+    LogFunc(("vboxvideo: %d: dev=%p, handle=%u\n", __LINE__, dev,
+             (unsigned)handle));
+    return drm_gem_handle_delete(file, handle);
+}
+#endif
+
+static void vbox_bo_unref(struct vbox_bo **bo)
+{
+    struct ttm_buffer_object *tbo;
+
+    if ((*bo) == NULL)
+        return;
+
+    LogFunc(("vboxvideo: %d: bo=%p\n", __LINE__, bo));
+    tbo = &((*bo)->bo);
+    ttm_bo_unref(&tbo);
+    if (tbo == NULL)
+        *bo = NULL;
+
+}
+void vbox_gem_free_object(struct drm_gem_object *obj)
+{
+    struct vbox_bo *vbox_bo = gem_to_vbox_bo(obj);
+
+    LogFunc(("vboxvideo: %d: vbox_bo=%p\n", __LINE__, vbox_bo));
+    vbox_bo_unref(&vbox_bo);
+}
+
+
+static inline u64 vbox_bo_mmap_offset(struct vbox_bo *bo)
+{
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 12, 0)
+    return bo->bo.addr_space_offset;
+#else
+    return drm_vma_node_offset_addr(&bo->bo.vma_node);
+#endif
+}
+int
+vbox_dumb_mmap_offset(struct drm_file *file,
+             struct drm_device *dev,
+             uint32_t handle,
+             uint64_t *offset)
+{
+    struct drm_gem_object *obj;
+    int ret;
+    struct vbox_bo *bo;
+
+    LogFunc(("vboxvideo: %d: dev=%p, handle=%u\n", __LINE__,
+             dev, (unsigned)handle));
+    mutex_lock(&dev->struct_mutex);
+    obj = drm_gem_object_lookup(dev, file, handle);
+    if (obj == NULL) {
+        ret = -ENOENT;
+        goto out_unlock;
+    }
+
+    bo = gem_to_vbox_bo(obj);
+    *offset = vbox_bo_mmap_offset(bo);
+
+    drm_gem_object_unreference(obj);
+    ret = 0;
+    LogFunc(("vboxvideo: %d: bo=%p, *offset=%llu\n", __LINE__,
+             bo, (unsigned long long)*offset));
+out_unlock:
+    mutex_unlock(&dev->struct_mutex);
+    return ret;
+
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/vboxvideo/vbox_mode.c
@@ -0,0 +1,801 @@
+/* $Id: vbox_mode.c $ */
+/** @file
+ * VirtualBox Additions Linux kernel video driver
+ */
+
+/*
+ * Copyright (C) 2013 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ * --------------------------------------------------------------------
+ *
+ * This code is based on
+ * ast_mode.c
+ * with the following copyright and permission notice:
+ *
+ * Copyright 2012 Red Hat Inc.
+ * Parts based on xf86-video-ast
+ * Copyright (c) 2005 ASPEED Technology Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ */
+/*
+ * Authors: Dave Airlie <airlied@redhat.com>
+ */
+#include "vbox_drv.h"
+
+#include <VBox/VBoxVideo.h>
+
+#include <linux/export.h>
+#include <drm/drm_crtc_helper.h>
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0)
+# include <drm/drm_plane_helper.h>
+#endif
+
+static int vbox_cursor_set2(struct drm_crtc *crtc, struct drm_file *file_priv,
+                            uint32_t handle, uint32_t width, uint32_t height,
+                            int32_t hot_x, int32_t hot_y);
+static int vbox_cursor_move(struct drm_crtc *crtc, int x, int y);
+
+/** Set a graphics mode.  Poke any required values into registers, do an HGSMI
+ * mode set and tell the host we support advanced graphics functions.
+ */
+static void vbox_do_modeset(struct drm_crtc *crtc,
+                            const struct drm_display_mode *mode)
+{
+    struct vbox_crtc   *vbox_crtc = to_vbox_crtc(crtc);
+    struct vbox_private *vbox;
+    int width, height, bpp, pitch;
+    unsigned crtc_id;
+    uint16_t flags;
+
+    LogFunc(("vboxvideo: %d: vbox_crtc=%p, CRTC_FB(crtc)=%p\n", __LINE__,
+             vbox_crtc, CRTC_FB(crtc)));
+    vbox = crtc->dev->dev_private;
+    width = mode->hdisplay ? mode->hdisplay : 640;
+    height = mode->vdisplay ? mode->vdisplay : 480;
+    crtc_id = vbox_crtc->crtc_id;
+    bpp = crtc->enabled ? CRTC_FB(crtc)->bits_per_pixel : 32;
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 3, 0)
+    pitch = crtc->enabled ? CRTC_FB(crtc)->pitch : width * bpp / 8;
+#else
+    pitch = crtc->enabled ? CRTC_FB(crtc)->pitches[0] : width * bpp / 8;
+#endif
+    /* This is the old way of setting graphics modes.  It assumed one screen
+     * and a frame-buffer at the start of video RAM.  On older versions of
+     * VirtualBox, certain parts of the code still assume that the first
+     * screen is programmed this way, so try to fake it. */
+    if (   vbox_crtc->crtc_id == 0
+        && crtc->enabled
+        && vbox_crtc->fb_offset / pitch < 0xffff - crtc->y
+        && vbox_crtc->fb_offset % (bpp / 8) == 0)
+        VBoxVideoSetModeRegisters(width, height, pitch * 8 / bpp,
+                          CRTC_FB(crtc)->bits_per_pixel, 0,
+                          vbox_crtc->fb_offset % pitch / bpp * 8 + crtc->x,
+                          vbox_crtc->fb_offset / pitch + crtc->y);
+    flags = VBVA_SCREEN_F_ACTIVE;
+    flags |= (crtc->enabled && !vbox_crtc->blanked ? 0 : VBVA_SCREEN_F_BLANK);
+    flags |= (vbox_crtc->disconnected ? VBVA_SCREEN_F_DISABLED : 0);
+    VBoxHGSMIProcessDisplayInfo(&vbox->submit_info, vbox_crtc->crtc_id,
+                                crtc->x, crtc->y,
+                                crtc->x * bpp / 8 + crtc->y * pitch,
+                                pitch, width, height,
+                                vbox_crtc->blanked ? 0 : bpp, flags);
+    VBoxHGSMIReportFlagsLocation(&vbox->submit_info, vbox->host_flags_offset);
+    LogFunc(("vboxvideo: %d\n", __LINE__));
+}
+
+static int vbox_set_view(struct drm_crtc *crtc)
+{
+    struct vbox_crtc   *vbox_crtc = to_vbox_crtc(crtc);
+    struct vbox_private *vbox = crtc->dev->dev_private;
+    void *p;
+
+    LogFunc(("vboxvideo: %d: vbox_crtc=%p\n", __LINE__, vbox_crtc));
+    /* Tell the host about the view.  This design originally targeted the
+     * Windows XP driver architecture and assumed that each screen would have
+     * a dedicated frame buffer with the command buffer following it, the whole
+     * being a "view".  The host works out which screen a command buffer belongs
+     * to by checking whether it is in the first view, then whether it is in the
+     * second and so on.  The first match wins.  We cheat around this by making
+     * the first view be the managed memory plus the first command buffer, the
+     * second the same plus the second buffer and so on. */
+    p = VBoxHGSMIBufferAlloc(&vbox->submit_info, sizeof(VBVAINFOVIEW), HGSMI_CH_VBVA,
+                             VBVA_INFO_VIEW);
+    if (p)
+    {
+        VBVAINFOVIEW *pInfo = (VBVAINFOVIEW *)p;
+        pInfo->u32ViewIndex = vbox_crtc->crtc_id;
+        pInfo->u32ViewOffset = vbox_crtc->fb_offset;
+        pInfo->u32ViewSize =   vbox->vram_size - vbox_crtc->fb_offset
+                             + vbox_crtc->crtc_id * VBVA_MIN_BUFFER_SIZE;
+        pInfo->u32MaxScreenSize = vbox->vram_size - vbox_crtc->fb_offset;
+        VBoxHGSMIBufferSubmit(&vbox->submit_info, p);
+        VBoxHGSMIBufferFree(&vbox->submit_info, p);
+    }
+    else
+        return -ENOMEM;
+    LogFunc(("vboxvideo: %d: p=%p\n", __LINE__, p));
+    return 0;
+}
+
+static void vbox_crtc_load_lut(struct drm_crtc *crtc)
+{
+
+}
+
+static void vbox_crtc_dpms(struct drm_crtc *crtc, int mode)
+{
+    struct vbox_crtc *vbox_crtc = to_vbox_crtc(crtc);
+    struct vbox_private *vbox = crtc->dev->dev_private;
+
+    LogFunc(("vboxvideo: %d: vbox_crtc=%p, mode=%d\n", __LINE__, vbox_crtc,
+             mode));
+    switch (mode) {
+    case DRM_MODE_DPMS_ON:
+        vbox_crtc->blanked = false;
+        break;
+    case DRM_MODE_DPMS_STANDBY:
+    case DRM_MODE_DPMS_SUSPEND:
+    case DRM_MODE_DPMS_OFF:
+        vbox_crtc->blanked = true;
+        break;
+    }
+    mutex_lock(&vbox->hw_mutex);
+    vbox_do_modeset(crtc, &crtc->hwmode);
+    mutex_unlock(&vbox->hw_mutex);
+    LogFunc(("vboxvideo: %d\n", __LINE__));
+}
+
+static bool vbox_crtc_mode_fixup(struct drm_crtc *crtc,
+                const struct drm_display_mode *mode,
+                struct drm_display_mode *adjusted_mode)
+{
+    return true;
+}
+
+/* We move buffers which are not in active use out of VRAM to save memory. */
+static int vbox_crtc_do_set_base(struct drm_crtc *crtc,
+                struct drm_framebuffer *fb,
+                int x, int y, int atomic)
+{
+    struct vbox_private *vbox = crtc->dev->dev_private;
+    struct vbox_crtc *vbox_crtc = to_vbox_crtc(crtc);
+    struct drm_gem_object *obj;
+    struct vbox_framebuffer *vbox_fb;
+    struct vbox_bo *bo;
+    int ret;
+    u64 gpu_addr;
+
+    LogFunc(("vboxvideo: %d: fb=%p, vbox_crtc=%p\n", __LINE__, fb, vbox_crtc));
+    /* push the previous fb to system ram */
+    if (!atomic && fb) {
+        vbox_fb = to_vbox_framebuffer(fb);
+        obj = vbox_fb->obj;
+        bo = gem_to_vbox_bo(obj);
+        ret = vbox_bo_reserve(bo, false);
+        if (ret)
+            return ret;
+        vbox_bo_push_sysram(bo);
+        vbox_bo_unreserve(bo);
+    }
+
+    vbox_fb = to_vbox_framebuffer(CRTC_FB(crtc));
+    obj = vbox_fb->obj;
+    bo = gem_to_vbox_bo(obj);
+
+    ret = vbox_bo_reserve(bo, false);
+    if (ret)
+        return ret;
+
+    ret = vbox_bo_pin(bo, TTM_PL_FLAG_VRAM, &gpu_addr);
+    if (ret) {
+        vbox_bo_unreserve(bo);
+        return ret;
+    }
+
+    if (&vbox->fbdev->afb == vbox_fb) {
+        /* if pushing console in kmap it */
+        ret = ttm_bo_kmap(&bo->bo, 0, bo->bo.num_pages, &bo->kmap);
+        if (ret)
+            DRM_ERROR("failed to kmap fbcon\n");
+    }
+    vbox_bo_unreserve(bo);
+
+    /* vbox_set_start_address_crt1(crtc, (u32)gpu_addr); */
+    vbox_crtc->fb_offset = gpu_addr;
+    if (vbox_crtc->crtc_id == 0) {
+        vbox->input_mapping_width = CRTC_FB(crtc)->width;
+        vbox->input_mapping_height = CRTC_FB(crtc)->height;
+    }
+    LogFunc(("vboxvideo: %d: vbox_fb=%p, obj=%p, bo=%p, gpu_addr=%u\n",
+             __LINE__, vbox_fb, obj, bo, (unsigned)gpu_addr));
+    return 0;
+}
+
+static int vbox_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
+                 struct drm_framebuffer *old_fb)
+{
+    LogFunc(("vboxvideo: %d\n", __LINE__));
+    return vbox_crtc_do_set_base(crtc, old_fb, x, y, 0);
+}
+
+static int vbox_crtc_mode_set(struct drm_crtc *crtc,
+                 struct drm_display_mode *mode,
+                 struct drm_display_mode *adjusted_mode,
+                 int x, int y,
+                 struct drm_framebuffer *old_fb)
+{
+    struct vbox_private *vbox = crtc->dev->dev_private;
+    int rc = 0;
+
+    LogFunc(("vboxvideo: %d: vbox=%p\n", __LINE__, vbox));
+    vbox_crtc_mode_set_base(crtc, x, y, old_fb);
+    mutex_lock(&vbox->hw_mutex);
+    rc = vbox_set_view(crtc);
+    if (!rc)
+        vbox_do_modeset(crtc, mode);
+    /* Note that the input mapping is always relative to the first screen. */
+    VBoxHGSMIUpdateInputMapping(&vbox->submit_info, 0, 0,
+                                vbox->input_mapping_width,
+                                vbox->input_mapping_height);
+    mutex_unlock(&vbox->hw_mutex);
+    LogFunc(("vboxvideo: %d\n", __LINE__));
+    return rc;
+}
+
+static void vbox_crtc_disable(struct drm_crtc *crtc)
+{
+
+}
+
+static void vbox_crtc_prepare(struct drm_crtc *crtc)
+{
+
+}
+
+static void vbox_crtc_commit(struct drm_crtc *crtc)
+{
+
+}
+
+
+static const struct drm_crtc_helper_funcs vbox_crtc_helper_funcs = {
+    .dpms = vbox_crtc_dpms,
+    .mode_fixup = vbox_crtc_mode_fixup,
+    .mode_set = vbox_crtc_mode_set,
+    /* .mode_set_base = vbox_crtc_mode_set_base, */
+    .disable = vbox_crtc_disable,
+    .load_lut = vbox_crtc_load_lut,
+    .prepare = vbox_crtc_prepare,
+    .commit = vbox_crtc_commit,
+
+};
+
+static void vbox_crtc_reset(struct drm_crtc *crtc)
+{
+
+}
+
+
+static void vbox_crtc_destroy(struct drm_crtc *crtc)
+{
+    drm_crtc_cleanup(crtc);
+    kfree(crtc);
+}
+
+static const struct drm_crtc_funcs vbox_crtc_funcs = {
+    .cursor_move = vbox_cursor_move,
+    .cursor_set2 = vbox_cursor_set2,
+    .reset = vbox_crtc_reset,
+    .set_config = drm_crtc_helper_set_config,
+    /* .gamma_set = vbox_crtc_gamma_set, */
+    .destroy = vbox_crtc_destroy,
+};
+
+static struct vbox_crtc *vbox_crtc_init(struct drm_device *dev, unsigned i)
+{
+    struct vbox_crtc *vbox_crtc;
+
+    LogFunc(("vboxvideo: %d\n", __LINE__));
+    vbox_crtc = kzalloc(sizeof(struct vbox_crtc), GFP_KERNEL);
+    if (!vbox_crtc)
+        return NULL;
+    vbox_crtc->crtc_id = i;
+
+    drm_crtc_init(dev, &vbox_crtc->base, &vbox_crtc_funcs);
+    drm_mode_crtc_set_gamma_size(&vbox_crtc->base, 256);
+    drm_crtc_helper_add(&vbox_crtc->base, &vbox_crtc_helper_funcs);
+    LogFunc(("vboxvideo: %d: crtc=%p\n", __LINE__, vbox_crtc));
+
+    return vbox_crtc;
+}
+
+static void vbox_encoder_destroy(struct drm_encoder *encoder)
+{
+    LogFunc(("vboxvideo: %d: encoder=%p\n", __LINE__, encoder));
+    drm_encoder_cleanup(encoder);
+    kfree(encoder);
+}
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 13, 0)
+static struct drm_encoder *drm_encoder_find(struct drm_device *dev, uint32_t id)
+{
+     struct drm_mode_object *mo;
+     mo = drm_mode_object_find(dev, id, DRM_MODE_OBJECT_ENCODER);
+     return mo ? obj_to_encoder(mo) : NULL;
+}
+#endif
+
+static struct drm_encoder *vbox_best_single_encoder(struct drm_connector *connector)
+{
+    int enc_id = connector->encoder_ids[0];
+
+    LogFunc(("vboxvideo: %d: connector=%p\n", __LINE__, connector));
+    /* pick the encoder ids */
+    if (enc_id)
+        return drm_encoder_find(connector->dev, enc_id);
+    LogFunc(("vboxvideo: %d\n", __LINE__));
+    return NULL;
+}
+
+
+static const struct drm_encoder_funcs vbox_enc_funcs = {
+    .destroy = vbox_encoder_destroy,
+};
+
+static void vbox_encoder_dpms(struct drm_encoder *encoder, int mode)
+{
+
+}
+
+static bool vbox_mode_fixup(struct drm_encoder *encoder,
+               const struct drm_display_mode *mode,
+               struct drm_display_mode *adjusted_mode)
+{
+    return true;
+}
+
+static void vbox_encoder_mode_set(struct drm_encoder *encoder,
+                   struct drm_display_mode *mode,
+                   struct drm_display_mode *adjusted_mode)
+{
+}
+
+static void vbox_encoder_prepare(struct drm_encoder *encoder)
+{
+
+}
+
+static void vbox_encoder_commit(struct drm_encoder *encoder)
+{
+
+}
+
+
+static const struct drm_encoder_helper_funcs vbox_enc_helper_funcs = {
+    .dpms = vbox_encoder_dpms,
+    .mode_fixup = vbox_mode_fixup,
+    .prepare = vbox_encoder_prepare,
+    .commit = vbox_encoder_commit,
+    .mode_set = vbox_encoder_mode_set,
+};
+
+static struct drm_encoder *vbox_encoder_init(struct drm_device *dev, unsigned i)
+{
+    struct vbox_encoder *vbox_encoder;
+
+    LogFunc(("vboxvideo: %d: dev=%d\n", __LINE__));
+    vbox_encoder = kzalloc(sizeof(struct vbox_encoder), GFP_KERNEL);
+    if (!vbox_encoder)
+        return NULL;
+
+    drm_encoder_init(dev, &vbox_encoder->base, &vbox_enc_funcs,
+                     DRM_MODE_ENCODER_DAC
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 5, 0)
+                     , NULL
+#endif
+                     );
+    drm_encoder_helper_add(&vbox_encoder->base, &vbox_enc_helper_funcs);
+
+    vbox_encoder->base.possible_crtcs = 1 << i;
+    LogFunc(("vboxvideo: %d: vbox_encoder=%p\n", __LINE__, vbox_encoder));
+    return &vbox_encoder->base;
+}
+
+/** Generate EDID data with a mode-unique serial number for the virtual
+ *  monitor to try to persuade Unity that different modes correspond to
+ *  different monitors and it should not try to force the same resolution on
+ *  them. */
+static void vbox_set_edid(struct drm_connector *connector, int width,
+                          int height)
+{
+    enum { EDID_SIZE = 128 };
+    unsigned char edid[EDID_SIZE] = {
+        0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, /* header */
+        0x58, 0x58, /* manufacturer (VBX) */
+        0x00, 0x00, /* product code */
+        0x00, 0x00,0x00, 0x00, /* serial number goes here */
+        0x01, /* week of manufacture */
+        0x00, /* year of manufacture */
+        0x01, 0x03, /* EDID version */
+        0x80, /* capabilities - digital */
+        0x00, /* horiz. res in cm, zero for projectors */
+        0x00, /* vert. res in cm */
+        0x78, /* display gamma (120 == 2.2). */
+        0xEE, /* features (standby, suspend, off, RGB, standard colour space,
+               * preferred timing mode) */
+        0xEE, 0x91, 0xA3, 0x54, 0x4C, 0x99, 0x26, 0x0F, 0x50, 0x54,
+            /* chromaticity for standard colour space. */
+        0x00, 0x00, 0x00, /* no default timings */
+        0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+        0x01, 0x01, 0x01, 0x01, /* no standard timings */
+        0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x02, 0x02, 0x02, 0x02,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* descriptor block 1 goes here */
+        0x00, 0x00, 0x00, 0xFD, 0x00, /* descriptor block 2, monitor ranges */
+        0x00, 0xC8, 0x00, 0xC8, 0x64, 0x00, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20,
+        0x20, /* 0-200Hz vertical, 0-200KHz horizontal, 1000MHz pixel clock */
+        0x00, 0x00, 0x00, 0xFC, 0x00, /* descriptor block 3, monitor name */
+        'V', 'B', 'O', 'X', ' ', 'm', 'o', 'n', 'i', 't', 'o', 'r', '\n',
+        0x00, 0x00, 0x00, 0x10, 0x00, /* descriptor block 4: dummy data */
+        0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+        0x20,
+        0x00, /* number of extensions */
+        0x00 /* checksum goes here */
+    };
+    int clock = (width + 6) * (height + 6) * 60 / 10000;
+    unsigned i;
+    unsigned sum = 0;
+
+    edid[12] = width & 0xff;
+    edid[13] = width >> 8;
+    edid[14] = height & 0xff;
+    edid[15] = height >> 8;
+    edid[54] = clock & 0xff;
+    edid[55] = clock >> 8;
+    edid[56] = width & 0xff;
+    edid[58] = (width >> 4) & 0xf0;
+    edid[59] = height & 0xff;
+    edid[61] = (height >> 4) & 0xf0;
+    for (i = 0; i < EDID_SIZE - 1; ++i)
+        sum += edid[i];
+    edid[EDID_SIZE - 1] = (0x100 - (sum & 0xFF)) & 0xFF;
+    drm_mode_connector_update_edid_property(connector, (struct edid *)edid);
+}
+
+static int vbox_get_modes(struct drm_connector *connector)
+{
+    struct vbox_connector *vbox_connector = NULL;
+    struct drm_display_mode *mode = NULL;
+    struct vbox_private *vbox = NULL;
+    unsigned num_modes = 0;
+    int preferred_width, preferred_height;
+
+    LogFunc(("vboxvideo: %d: connector=%p\n", __LINE__, connector));
+    vbox_connector = to_vbox_connector(connector);
+    vbox = connector->dev->dev_private;
+    if (vbox_connector->vbox_crtc->crtc_id == 0)
+        vbox_enable_caps(vbox);
+    if (!vbox->initial_mode_queried) {
+        if (vbox_connector->vbox_crtc->crtc_id == 0) {
+            vbox->initial_mode_queried = true;
+            vbox_report_hotplug(vbox);
+        }
+        return drm_add_modes_noedid(connector, 800, 600);
+    }
+    num_modes = drm_add_modes_noedid(connector, 2560, 1600);
+    preferred_width = vbox_connector->mode_hint.width ? vbox_connector->mode_hint.width : 1024;
+    preferred_height = vbox_connector->mode_hint.height ? vbox_connector->mode_hint.height : 768;
+    mode = drm_cvt_mode(connector->dev, preferred_width, preferred_height, 60, false,
+                         false, false);
+    if (mode)
+    {
+        mode->type |= DRM_MODE_TYPE_PREFERRED;
+        drm_mode_probed_add(connector, mode);
+        ++num_modes;
+    }
+    vbox_set_edid(connector, preferred_width, preferred_height);
+    return num_modes;
+}
+
+static int vbox_mode_valid(struct drm_connector *connector,
+              struct drm_display_mode *mode)
+{
+    return MODE_OK;
+}
+
+static void vbox_connector_destroy(struct drm_connector *connector)
+{
+    struct vbox_connector *vbox_connector = NULL;
+
+    LogFunc(("vboxvideo: %d: connector=%p\n", __LINE__, connector));
+    vbox_connector = to_vbox_connector(connector);
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 17, 0)
+    drm_sysfs_connector_remove(connector);
+#else
+    drm_connector_unregister(connector);
+#endif
+    drm_connector_cleanup(connector);
+    kfree(connector);
+}
+
+static enum drm_connector_status
+vbox_connector_detect(struct drm_connector *connector, bool force)
+{
+    struct vbox_connector *vbox_connector = NULL;
+
+    (void) force;
+    LogFunc(("vboxvideo: %d: connector=%p\n", __LINE__, connector));
+    vbox_connector = to_vbox_connector(connector);
+    return vbox_connector->mode_hint.disconnected ?
+                connector_status_disconnected : connector_status_connected;
+}
+
+static int vbox_fill_modes(struct drm_connector *connector, uint32_t max_x, uint32_t max_y)
+{
+    struct vbox_connector *vbox_connector;
+    struct drm_device *dev;
+    struct drm_display_mode *mode, *iterator;
+
+    LogFunc(("vboxvideo: %d: connector=%p, max_x=%lu, max_y = %lu\n", __LINE__,
+             connector, (unsigned long)max_x, (unsigned long)max_y));
+    vbox_connector = to_vbox_connector(connector);
+    dev = vbox_connector->base.dev;
+    list_for_each_entry_safe(mode, iterator, &connector->modes, head)
+    {
+        list_del(&mode->head);
+        drm_mode_destroy(dev, mode);
+    }
+    return drm_helper_probe_single_connector_modes(connector, max_x, max_y);
+}
+
+static const struct drm_connector_helper_funcs vbox_connector_helper_funcs = {
+    .mode_valid = vbox_mode_valid,
+    .get_modes = vbox_get_modes,
+    .best_encoder = vbox_best_single_encoder,
+};
+
+static const struct drm_connector_funcs vbox_connector_funcs = {
+    .dpms = drm_helper_connector_dpms,
+    .detect = vbox_connector_detect,
+    .fill_modes = vbox_fill_modes,
+    .destroy = vbox_connector_destroy,
+};
+
+static int vbox_connector_init(struct drm_device *dev,
+                               struct vbox_crtc *vbox_crtc,
+                               struct drm_encoder *encoder)
+{
+    struct vbox_connector *vbox_connector;
+    struct drm_connector *connector;
+
+    LogFunc(("vboxvideo: %d: dev=%p, encoder=%p\n", __LINE__, dev,
+             encoder));
+    vbox_connector = kzalloc(sizeof(struct vbox_connector), GFP_KERNEL);
+    if (!vbox_connector)
+        return -ENOMEM;
+
+    connector = &vbox_connector->base;
+    vbox_connector->vbox_crtc = vbox_crtc;
+
+    drm_connector_init(dev, connector, &vbox_connector_funcs,
+                       DRM_MODE_CONNECTOR_VGA);
+    drm_connector_helper_add(connector, &vbox_connector_helper_funcs);
+
+    connector->interlace_allowed = 0;
+    connector->doublescan_allowed = 0;
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0)
+    drm_mode_create_suggested_offset_properties(dev);
+    drm_object_attach_property(&connector->base,
+                               dev->mode_config.suggested_x_property, 0);
+    drm_object_attach_property(&connector->base,
+                               dev->mode_config.suggested_y_property, 0);
+#endif
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 17, 0)
+    drm_sysfs_connector_add(connector);
+#else
+    drm_connector_register(connector);
+#endif
+
+    drm_mode_connector_attach_encoder(connector, encoder);
+
+    LogFunc(("vboxvideo: %d: connector=%p\n", __LINE__, connector));
+    return 0;
+}
+
+int vbox_mode_init(struct drm_device *dev)
+{
+    struct vbox_private *vbox = dev->dev_private;
+    struct drm_encoder *encoder;
+    struct vbox_crtc *vbox_crtc;
+    unsigned i;
+    /* vbox_cursor_init(dev); */
+    LogFunc(("vboxvideo: %d: dev=%p\n", __LINE__, dev));
+    for (i = 0; i < vbox->num_crtcs; ++i)
+    {
+        vbox_crtc = vbox_crtc_init(dev, i);
+        if (!vbox_crtc)
+            return -ENOMEM;
+        encoder = vbox_encoder_init(dev, i);
+        if (!encoder)
+            return -ENOMEM;
+        vbox_connector_init(dev, vbox_crtc, encoder);
+    }
+    return 0;
+}
+
+void vbox_mode_fini(struct drm_device *dev)
+{
+    /* vbox_cursor_fini(dev); */
+}
+
+
+/** Copy the ARGB image and generate the mask, which is needed in case the host
+ *  does not support ARGB cursors.  The mask is a 1BPP bitmap with the bit set
+ *  if the corresponding alpha value in the ARGB image is greater than 0xF0. */
+static void copy_cursor_image(u8 *src, u8 *dst, int width, int height,
+                              size_t mask_size)
+{
+    unsigned i, j;
+    size_t line_size = (width + 7) / 8;
+
+    memcpy(dst + mask_size, src, width * height * 4);
+    for (i = 0; i < height; ++i)
+        for (j = 0; j < width; ++j)
+            if (((uint32_t *)src)[i * width + j] > 0xf0000000)
+                dst[i * line_size + j / 8] |= (0x80 >> (j % 8));
+}
+
+static int vbox_cursor_set2(struct drm_crtc *crtc, struct drm_file *file_priv,
+                            uint32_t handle, uint32_t width, uint32_t height,
+                            int32_t hot_x, int32_t hot_y)
+{
+    struct vbox_private *vbox = crtc->dev->dev_private;
+    struct vbox_crtc *vbox_crtc = to_vbox_crtc(crtc);
+    struct drm_gem_object *obj;
+    struct vbox_bo *bo;
+    int ret, rc;
+    struct ttm_bo_kmap_obj uobj_map;
+    u8 *src;
+    u8 *dst = NULL;
+    u32 caps = 0;
+    size_t data_size, mask_size;
+    bool src_isiomem;
+
+    if (!handle) {
+        bool cursor_enabled = false;
+        struct drm_crtc *crtci;
+
+        /* Hide cursor. */
+        vbox_crtc->cursor_enabled = false;
+        list_for_each_entry(crtci, &vbox->dev->mode_config.crtc_list, head)
+            if (to_vbox_crtc(crtci)->cursor_enabled)
+                cursor_enabled = true;
+        if (!cursor_enabled)
+            VBoxHGSMIUpdatePointerShape(&vbox->submit_info, 0, 0, 0, 0, 0, NULL, 0);
+        return 0;
+    }
+    vbox_crtc->cursor_enabled = true;
+    if (   width > VBOX_MAX_CURSOR_WIDTH || height > VBOX_MAX_CURSOR_HEIGHT
+        || width == 0 || height == 0)
+        return -EINVAL;
+    rc = VBoxQueryConfHGSMI(&vbox->submit_info,
+                            VBOX_VBVA_CONF32_CURSOR_CAPABILITIES, &caps);
+    ret = -RTErrConvertToErrno(rc);
+    if (ret)
+        return ret;
+    if (   caps & VMMDEV_MOUSE_HOST_CANNOT_HWPOINTER
+        || !(caps & VMMDEV_MOUSE_HOST_WANTS_ABSOLUTE))
+        return -EINVAL;
+
+    obj = drm_gem_object_lookup(crtc->dev, file_priv, handle);
+    if (obj)
+    {
+        bo = gem_to_vbox_bo(obj);
+        ret = vbox_bo_reserve(bo, false);
+        if (!ret)
+        {
+            /* The mask must be calculated based on the alpha channel, one bit
+             * per ARGB word, and must be 32-bit padded. */
+            mask_size  = ((width + 7) / 8 * height + 3) & ~3;
+            data_size = width * height * 4 + mask_size;
+            vbox->cursor_hot_x = min((uint32_t)max(hot_x, 0), width);
+            vbox->cursor_hot_y = min((uint32_t)max(hot_y, 0), height);
+            vbox->cursor_width = width;
+            vbox->cursor_height = height;
+            vbox->cursor_data_size = data_size;
+            dst = vbox->cursor_data;
+            ret = ttm_bo_kmap(&bo->bo, 0, bo->bo.num_pages, &uobj_map);
+            if (!ret)
+            {
+                src = ttm_kmap_obj_virtual(&uobj_map, &src_isiomem);
+                if (!src_isiomem)
+                {
+                    uint32_t flags =   VBOX_MOUSE_POINTER_VISIBLE
+                                      | VBOX_MOUSE_POINTER_SHAPE
+                                      | VBOX_MOUSE_POINTER_ALPHA;
+                    copy_cursor_image(src, dst, width, height, mask_size);
+                    rc = VBoxHGSMIUpdatePointerShape(&vbox->submit_info, flags,
+                                                     vbox->cursor_hot_x,
+                                                     vbox->cursor_hot_y,
+                                                     width, height, dst,
+                                                     data_size);
+                    ret = -RTErrConvertToErrno(rc);
+                }
+                else
+                    DRM_ERROR("src cursor bo should be in main memory\n");
+                ttm_bo_kunmap(&uobj_map);
+            }
+            else
+                vbox->cursor_data_size = 0;
+            vbox_bo_unreserve(bo);
+        }
+        drm_gem_object_unreference_unlocked(obj);
+    }
+    else
+    {
+        DRM_ERROR("Cannot find cursor object %x for crtc\n", handle);
+        ret = -ENOENT;
+    }
+    return ret;
+}
+
+static int vbox_cursor_move(struct drm_crtc *crtc,
+               int x, int y)
+{
+    struct vbox_private *vbox = crtc->dev->dev_private;
+    uint32_t flags =   VBOX_MOUSE_POINTER_VISIBLE
+                      | VBOX_MOUSE_POINTER_SHAPE
+                      | VBOX_MOUSE_POINTER_ALPHA;
+    uint32_t host_x, host_y;
+    uint32_t hot_x = 0;
+    uint32_t hot_y = 0;
+    int rc;
+
+    /* We compare these to unsigned later and don't need to handle negative. */
+    if (x + crtc->x < 0 || y + crtc->y < 0 || vbox->cursor_data_size == 0)
+        return 0;
+    rc = VBoxHGSMICursorPosition(&vbox->submit_info, true, x + crtc->x,
+                                 y + crtc->y, &host_x, &host_y);
+    if (RT_FAILURE(rc))
+        return -RTErrConvertToErrno(rc);
+    if (x + crtc->x < host_x)
+        hot_x = min(host_x - x - crtc->x, vbox->cursor_width);
+    if (y + crtc->y < host_y)
+        hot_y = min(host_y - y - crtc->y, vbox->cursor_height);
+    if (hot_x == vbox->cursor_hot_x && hot_y == vbox->cursor_hot_y)
+        return 0;
+    vbox->cursor_hot_x = hot_x;
+    vbox->cursor_hot_y = hot_y;
+    rc = VBoxHGSMIUpdatePointerShape(&vbox->submit_info, flags, hot_x, hot_y,
+                                     vbox->cursor_width, vbox->cursor_height,
+                                     vbox->cursor_data,
+                                     vbox->cursor_data_size);
+    return -RTErrConvertToErrno(rc);
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/vboxvideo/vbox_ttm.c
@@ -0,0 +1,501 @@
+/* $Id: vbox_ttm.c $ */
+/** @file
+ * VirtualBox Additions Linux kernel video driver
+ */
+
+/*
+ * Copyright (C) 2013 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ * --------------------------------------------------------------------
+ *
+ * This code is based on
+ * ast_ttm.c
+ * with the following copyright and permission notice:
+ *
+ * Copyright 2012 Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ */
+/*
+ * Authors: Dave Airlie <airlied@redhat.com>
+ */
+#include "vbox_drv.h"
+#include <ttm/ttm_page_alloc.h>
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 18, 0)
+# define PLACEMENT_FLAGS(placement) (placement)
+#else
+# define PLACEMENT_FLAGS(placement) (placement).flags
+#endif
+
+static inline struct vbox_private *
+vbox_bdev(struct ttm_bo_device *bd)
+{
+    return container_of(bd, struct vbox_private, ttm.bdev);
+}
+
+static int
+vbox_ttm_mem_global_init(struct drm_global_reference *ref)
+{
+    return ttm_mem_global_init(ref->object);
+}
+
+static void
+vbox_ttm_mem_global_release(struct drm_global_reference *ref)
+{
+    ttm_mem_global_release(ref->object);
+}
+
+/**
+ * Adds the vbox memory manager object/structures to the global memory manager.
+ */
+static int vbox_ttm_global_init(struct vbox_private *vbox)
+{
+    struct drm_global_reference *global_ref;
+    int r;
+
+    global_ref = &vbox->ttm.mem_global_ref;
+    global_ref->global_type = DRM_GLOBAL_TTM_MEM;
+    global_ref->size = sizeof(struct ttm_mem_global);
+    global_ref->init = &vbox_ttm_mem_global_init;
+    global_ref->release = &vbox_ttm_mem_global_release;
+    r = drm_global_item_ref(global_ref);
+    if (r != 0) {
+        DRM_ERROR("Failed setting up TTM memory accounting "
+              "subsystem.\n");
+        return r;
+    }
+
+    vbox->ttm.bo_global_ref.mem_glob =
+        vbox->ttm.mem_global_ref.object;
+    global_ref = &vbox->ttm.bo_global_ref.ref;
+    global_ref->global_type = DRM_GLOBAL_TTM_BO;
+    global_ref->size = sizeof(struct ttm_bo_global);
+    global_ref->init = &ttm_bo_global_init;
+    global_ref->release = &ttm_bo_global_release;
+    r = drm_global_item_ref(global_ref);
+    if (r != 0) {
+        DRM_ERROR("Failed setting up TTM BO subsystem.\n");
+        drm_global_item_unref(&vbox->ttm.mem_global_ref);
+        return r;
+    }
+    return 0;
+}
+
+/**
+ * Removes the vbox memory manager object from the global memory manager.
+ */
+static void
+vbox_ttm_global_release(struct vbox_private *vbox)
+{
+    if (vbox->ttm.mem_global_ref.release == NULL)
+        return;
+
+    drm_global_item_unref(&vbox->ttm.bo_global_ref.ref);
+    drm_global_item_unref(&vbox->ttm.mem_global_ref);
+    vbox->ttm.mem_global_ref.release = NULL;
+}
+
+
+static void vbox_bo_ttm_destroy(struct ttm_buffer_object *tbo)
+{
+    struct vbox_bo *bo;
+
+    bo = container_of(tbo, struct vbox_bo, bo);
+
+    drm_gem_object_release(&bo->gem);
+    kfree(bo);
+}
+
+static bool vbox_ttm_bo_is_vbox_bo(struct ttm_buffer_object *bo)
+{
+    if (bo->destroy == &vbox_bo_ttm_destroy)
+        return true;
+    return false;
+}
+
+static int
+vbox_bo_init_mem_type(struct ttm_bo_device *bdev, uint32_t type,
+             struct ttm_mem_type_manager *man)
+{
+    switch (type) {
+    case TTM_PL_SYSTEM:
+        man->flags = TTM_MEMTYPE_FLAG_MAPPABLE;
+        man->available_caching = TTM_PL_MASK_CACHING;
+        man->default_caching = TTM_PL_FLAG_CACHED;
+        break;
+    case TTM_PL_VRAM:
+        man->func = &ttm_bo_manager_func;
+        man->flags = TTM_MEMTYPE_FLAG_FIXED |
+            TTM_MEMTYPE_FLAG_MAPPABLE;
+        man->available_caching = TTM_PL_FLAG_UNCACHED |
+            TTM_PL_FLAG_WC;
+        man->default_caching = TTM_PL_FLAG_WC;
+        break;
+    default:
+        DRM_ERROR("Unsupported memory type %u\n", (unsigned)type);
+        return -EINVAL;
+    }
+    return 0;
+}
+
+static void
+vbox_bo_evict_flags(struct ttm_buffer_object *bo, struct ttm_placement *pl)
+{
+    struct vbox_bo *vboxbo = vbox_bo(bo);
+
+    if (!vbox_ttm_bo_is_vbox_bo(bo))
+        return;
+
+    vbox_ttm_placement(vboxbo, TTM_PL_FLAG_SYSTEM);
+    *pl = vboxbo->placement;
+}
+
+static int vbox_bo_verify_access(struct ttm_buffer_object *bo, struct file *filp)
+{
+    return 0;
+}
+
+static int vbox_ttm_io_mem_reserve(struct ttm_bo_device *bdev,
+                  struct ttm_mem_reg *mem)
+{
+    struct ttm_mem_type_manager *man = &bdev->man[mem->mem_type];
+    struct vbox_private *vbox = vbox_bdev(bdev);
+
+    mem->bus.addr = NULL;
+    mem->bus.offset = 0;
+    mem->bus.size = mem->num_pages << PAGE_SHIFT;
+    mem->bus.base = 0;
+    mem->bus.is_iomem = false;
+    if (!(man->flags & TTM_MEMTYPE_FLAG_MAPPABLE))
+        return -EINVAL;
+    switch (mem->mem_type) {
+    case TTM_PL_SYSTEM:
+        /* system memory */
+        return 0;
+    case TTM_PL_VRAM:
+        mem->bus.offset = mem->start << PAGE_SHIFT;
+        mem->bus.base = pci_resource_start(vbox->dev->pdev, 0);
+        mem->bus.is_iomem = true;
+        break;
+    default:
+        return -EINVAL;
+        break;
+    }
+    return 0;
+}
+
+static void vbox_ttm_io_mem_free(struct ttm_bo_device *bdev, struct ttm_mem_reg *mem)
+{
+}
+
+static int vbox_bo_move(struct ttm_buffer_object *bo,
+               bool evict, bool interruptible,
+               bool no_wait_gpu,
+               struct ttm_mem_reg *new_mem)
+{
+    int r;
+    r = ttm_bo_move_memcpy(bo, evict, no_wait_gpu, new_mem);
+    return r;
+}
+
+
+static void vbox_ttm_backend_destroy(struct ttm_tt *tt)
+{
+    ttm_tt_fini(tt);
+    kfree(tt);
+}
+
+static struct ttm_backend_func vbox_tt_backend_func = {
+    .destroy = &vbox_ttm_backend_destroy,
+};
+
+
+static struct ttm_tt *vbox_ttm_tt_create(struct ttm_bo_device *bdev,
+                 unsigned long size, uint32_t page_flags,
+                 struct page *dummy_read_page)
+{
+    struct ttm_tt *tt;
+
+    tt = kzalloc(sizeof(struct ttm_tt), GFP_KERNEL);
+    if (tt == NULL)
+        return NULL;
+    tt->func = &vbox_tt_backend_func;
+    if (ttm_tt_init(tt, bdev, size, page_flags, dummy_read_page)) {
+        kfree(tt);
+        return NULL;
+    }
+    return tt;
+}
+
+static int vbox_ttm_tt_populate(struct ttm_tt *ttm)
+{
+    return ttm_pool_populate(ttm);
+}
+
+static void vbox_ttm_tt_unpopulate(struct ttm_tt *ttm)
+{
+    ttm_pool_unpopulate(ttm);
+}
+
+struct ttm_bo_driver vbox_bo_driver = {
+    .ttm_tt_create = vbox_ttm_tt_create,
+    .ttm_tt_populate = vbox_ttm_tt_populate,
+    .ttm_tt_unpopulate = vbox_ttm_tt_unpopulate,
+    .init_mem_type = vbox_bo_init_mem_type,
+    .evict_flags = vbox_bo_evict_flags,
+    .move = vbox_bo_move,
+    .verify_access = vbox_bo_verify_access,
+    .io_mem_reserve = &vbox_ttm_io_mem_reserve,
+    .io_mem_free = &vbox_ttm_io_mem_free,
+};
+
+int vbox_mm_init(struct vbox_private *vbox)
+{
+    int ret;
+    struct drm_device *dev = vbox->dev;
+    struct ttm_bo_device *bdev = &vbox->ttm.bdev;
+
+    ret = vbox_ttm_global_init(vbox);
+    if (ret)
+        return ret;
+
+    ret = ttm_bo_device_init(&vbox->ttm.bdev,
+                 vbox->ttm.bo_global_ref.ref.object,
+                 &vbox_bo_driver,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0)
+                 dev->anon_inode->i_mapping,
+#endif
+                 DRM_FILE_PAGE_OFFSET,
+                 true);
+    if (ret) {
+        DRM_ERROR("Error initialising bo driver; %d\n", ret);
+        return ret;
+    }
+
+    ret = ttm_bo_init_mm(bdev, TTM_PL_VRAM,
+                 vbox->vram_size >> PAGE_SHIFT);
+    if (ret) {
+        DRM_ERROR("Failed ttm VRAM init: %d\n", ret);
+        return ret;
+    }
+
+#ifdef DRM_MTRR_WC
+    vbox->fb_mtrr = drm_mtrr_add(pci_resource_start(dev->pdev, 0),
+                    pci_resource_len(dev->pdev, 0),
+                    DRM_MTRR_WC);
+#else
+    vbox->fb_mtrr = arch_phys_wc_add(pci_resource_start(dev->pdev, 0),
+                    pci_resource_len(dev->pdev, 0));
+#endif
+
+    vbox->ttm.mm_initialised = true;
+    return 0;
+}
+
+void vbox_mm_fini(struct vbox_private *vbox)
+{
+#ifdef DRM_MTRR_WC
+    struct drm_device *dev = vbox->dev;
+#endif
+    if (!vbox->ttm.mm_initialised)
+        return;
+    ttm_bo_device_release(&vbox->ttm.bdev);
+
+    vbox_ttm_global_release(vbox);
+
+#ifdef DRM_MTRR_WC
+    drm_mtrr_del(vbox->fb_mtrr,
+             pci_resource_start(dev->pdev, 0),
+             pci_resource_len(dev->pdev, 0), DRM_MTRR_WC);
+#else
+    arch_phys_wc_del(vbox->fb_mtrr);
+#endif
+}
+
+void vbox_ttm_placement(struct vbox_bo *bo, int domain)
+{
+    u32 c = 0;
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 18, 0)
+    bo->placement.fpfn = 0;
+    bo->placement.lpfn = 0;
+#else
+    unsigned i;
+#endif
+
+    bo->placement.placement = bo->placements;
+    bo->placement.busy_placement = bo->placements;
+    if (domain & TTM_PL_FLAG_VRAM)
+        PLACEMENT_FLAGS(bo->placements[c++]) = TTM_PL_FLAG_WC | TTM_PL_FLAG_UNCACHED | TTM_PL_FLAG_VRAM;
+    if (domain & TTM_PL_FLAG_SYSTEM)
+        PLACEMENT_FLAGS(bo->placements[c++]) = TTM_PL_MASK_CACHING | TTM_PL_FLAG_SYSTEM;
+    if (!c)
+        PLACEMENT_FLAGS(bo->placements[c++]) = TTM_PL_MASK_CACHING | TTM_PL_FLAG_SYSTEM;
+    bo->placement.num_placement = c;
+    bo->placement.num_busy_placement = c;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0)
+    for (i = 0; i < c; ++i) {
+        bo->placements[i].fpfn = 0;
+        bo->placements[i].lpfn = 0;
+    }
+#endif
+}
+
+int vbox_bo_create(struct drm_device *dev, int size, int align,
+          uint32_t flags, struct vbox_bo **pvboxbo)
+{
+    struct vbox_private *vbox = dev->dev_private;
+    struct vbox_bo *vboxbo;
+    size_t acc_size;
+    int ret;
+
+    vboxbo = kzalloc(sizeof(struct vbox_bo), GFP_KERNEL);
+    if (!vboxbo)
+        return -ENOMEM;
+
+    ret = drm_gem_object_init(dev, &vboxbo->gem, size);
+    if (ret) {
+        kfree(vboxbo);
+        return ret;
+    }
+
+    vboxbo->bo.bdev = &vbox->ttm.bdev;
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 15, 0)
+    vboxbo->bo.bdev->dev_mapping = dev->dev_mapping;
+#endif
+
+    vbox_ttm_placement(vboxbo, TTM_PL_FLAG_VRAM | TTM_PL_FLAG_SYSTEM);
+
+    acc_size = ttm_bo_dma_acc_size(&vbox->ttm.bdev, size,
+                       sizeof(struct vbox_bo));
+
+    ret = ttm_bo_init(&vbox->ttm.bdev, &vboxbo->bo, size,
+              ttm_bo_type_device, &vboxbo->placement,
+              align >> PAGE_SHIFT, false, NULL, acc_size,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0)
+              NULL,
+#endif
+              NULL, vbox_bo_ttm_destroy);
+    if (ret)
+        return ret;
+
+    *pvboxbo = vboxbo;
+    return 0;
+}
+
+static inline u64 vbox_bo_gpu_offset(struct vbox_bo *bo)
+{
+    return bo->bo.offset;
+}
+
+int vbox_bo_pin(struct vbox_bo *bo, u32 pl_flag, u64 *gpu_addr)
+{
+    int i, ret;
+
+    if (bo->pin_count) {
+        bo->pin_count++;
+        if (gpu_addr)
+            *gpu_addr = vbox_bo_gpu_offset(bo);
+        return 0;
+    }
+
+    vbox_ttm_placement(bo, pl_flag);
+    for (i = 0; i < bo->placement.num_placement; i++)
+        PLACEMENT_FLAGS(bo->placements[i]) |= TTM_PL_FLAG_NO_EVICT;
+    ret = ttm_bo_validate(&bo->bo, &bo->placement, false, false);
+    if (ret)
+        return ret;
+
+    bo->pin_count = 1;
+    if (gpu_addr)
+        *gpu_addr = vbox_bo_gpu_offset(bo);
+    return 0;
+}
+
+int vbox_bo_unpin(struct vbox_bo *bo)
+{
+    int i, ret;
+    if (!bo->pin_count) {
+        DRM_ERROR("unpin bad %p\n", bo);
+        return 0;
+    }
+    bo->pin_count--;
+    if (bo->pin_count)
+        return 0;
+
+    for (i = 0; i < bo->placement.num_placement ; i++)
+        PLACEMENT_FLAGS(bo->placements[i]) &= ~TTM_PL_FLAG_NO_EVICT;
+    ret = ttm_bo_validate(&bo->bo, &bo->placement, false, false);
+    if (ret)
+        return ret;
+
+    return 0;
+}
+
+/* Move a vbox-owned buffer object to system memory if no one else has it
+ * pinned.  The caller must have pinned it previously, and this call will
+ * release the caller's pin. */
+int vbox_bo_push_sysram(struct vbox_bo *bo)
+{
+    int i, ret;
+    if (!bo->pin_count) {
+        DRM_ERROR("unpin bad %p\n", bo);
+        return 0;
+    }
+    bo->pin_count--;
+    if (bo->pin_count)
+        return 0;
+
+    if (bo->kmap.virtual)
+        ttm_bo_kunmap(&bo->kmap);
+
+    vbox_ttm_placement(bo, TTM_PL_FLAG_SYSTEM);
+    for (i = 0; i < bo->placement.num_placement ; i++)
+        PLACEMENT_FLAGS(bo->placements[i]) |= TTM_PL_FLAG_NO_EVICT;
+
+    ret = ttm_bo_validate(&bo->bo, &bo->placement, false, false);
+    if (ret) {
+        DRM_ERROR("pushing to VRAM failed\n");
+        return ret;
+    }
+    return 0;
+}
+
+int vbox_mmap(struct file *filp, struct vm_area_struct *vma)
+{
+    struct drm_file *file_priv;
+    struct vbox_private *vbox;
+
+    if (unlikely(vma->vm_pgoff < DRM_FILE_PAGE_OFFSET))
+        return -EINVAL;
+
+    file_priv = filp->private_data;
+    vbox = file_priv->minor->dev->dev_private;
+    return ttm_bo_mmap(filp, vma, &vbox->ttm.bdev);
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/ubuntu/vbox/vboxvideo/version-generated.h
@@ -0,0 +1,13 @@
+#ifndef ___version_generated_h___
+#define ___version_generated_h___
+
+#define VBOX_VERSION_MAJOR 5
+#define VBOX_VERSION_MINOR 0
+#define VBOX_VERSION_BUILD 18
+#define VBOX_VERSION_STRING_RAW "5.0.18"
+#define VBOX_VERSION_STRING "5.0.18_Ubuntu"
+#define VBOX_API_VERSION_STRING "5_0"
+
+#define VBOX_PRIVATE_BUILD_DESC "Private build by root"
+
+#endif
--- /dev/null
+++ zfcpdump-kernel-4.4/update
@@ -0,0 +1,28 @@
+#!/bin/bash
+
+if [ "$#" -ne 1 ]; then
+	echo "Usage: $0 <linux-source-directory>" 1>&2
+	exit 1
+fi
+master_dir="$1"
+
+# Work out the master kernel version.
+if [ -f "$master_dir/debian/debian.env" ]; then
+	branch=`sed -ne 's/DEBIAN=//p' <"$master_dir/debian/debian.env"`
+	changelog="-l$branch/changelog"
+else
+	changelog=""
+fi
+master_version=`(cd "$master_dir" && LC_ALL=C dpkg-parsechangelog -S Version $changelog)`
+
+here=$(pwd)
+(
+	cd "$master_dir" || exit 1
+
+	git ls-files | grep -v '^debian' | cpio --unconditional -pd --preserve-modification-time "$here"
+)
+
+cp -p "$master_dir/debian/source/options" "debian/source"
+git add .
+
+git commit -s -m "UBUNTU: update to master $master_version"
--- zfcpdump-kernel-4.4.orig/virt/kvm/arm/arch_timer.c
+++ zfcpdump-kernel-4.4/virt/kvm/arm/arch_timer.c
@@ -86,6 +86,8 @@ static void kvm_timer_inject_irq_work(st
 	vcpu = container_of(work, struct kvm_vcpu, arch.timer_cpu.expired);
 	vcpu->arch.timer_cpu.armed = false;
 
+	WARN_ON(!kvm_timer_should_fire(vcpu));
+
 	/*
 	 * If the vcpu is blocked we want to wake it up so that it will see
 	 * the timer has expired when entering the guest.
@@ -93,10 +95,46 @@ static void kvm_timer_inject_irq_work(st
 	kvm_vcpu_kick(vcpu);
 }
 
+static u64 kvm_timer_compute_delta(struct kvm_vcpu *vcpu)
+{
+	cycle_t cval, now;
+
+	cval = vcpu->arch.timer_cpu.cntv_cval;
+	now = kvm_phys_timer_read() - vcpu->kvm->arch.timer.cntvoff;
+
+	if (now < cval) {
+		u64 ns;
+
+		ns = cyclecounter_cyc2ns(timecounter->cc,
+					 cval - now,
+					 timecounter->mask,
+					 &timecounter->frac);
+		return ns;
+	}
+
+	return 0;
+}
+
 static enum hrtimer_restart kvm_timer_expire(struct hrtimer *hrt)
 {
 	struct arch_timer_cpu *timer;
+	struct kvm_vcpu *vcpu;
+	u64 ns;
+
 	timer = container_of(hrt, struct arch_timer_cpu, timer);
+	vcpu = container_of(timer, struct kvm_vcpu, arch.timer_cpu);
+
+	/*
+	 * Check that the timer has really expired from the guest's
+	 * PoV (NTP on the host may have forced it to expire
+	 * early). If we should have slept longer, restart it.
+	 */
+	ns = kvm_timer_compute_delta(vcpu);
+	if (unlikely(ns)) {
+		hrtimer_forward_now(hrt, ns_to_ktime(ns));
+		return HRTIMER_RESTART;
+	}
+
 	queue_work(wqueue, &timer->expired);
 	return HRTIMER_NORESTART;
 }
@@ -143,7 +181,7 @@ static void kvm_timer_update_irq(struct
  * Check if there was a change in the timer state (should we raise or lower
  * the line level to the GIC).
  */
-static void kvm_timer_update_state(struct kvm_vcpu *vcpu)
+static int kvm_timer_update_state(struct kvm_vcpu *vcpu)
 {
 	struct arch_timer_cpu *timer = &vcpu->arch.timer_cpu;
 
@@ -154,10 +192,12 @@ static void kvm_timer_update_state(struc
 	 * until we call this function from kvm_timer_flush_hwstate.
 	 */
 	if (!vgic_initialized(vcpu->kvm))
-	    return;
+		return -ENODEV;
 
 	if (kvm_timer_should_fire(vcpu) != timer->irq.level)
 		kvm_timer_update_irq(vcpu, !timer->irq.level);
+
+	return 0;
 }
 
 /*
@@ -168,8 +208,6 @@ static void kvm_timer_update_state(struc
 void kvm_timer_schedule(struct kvm_vcpu *vcpu)
 {
 	struct arch_timer_cpu *timer = &vcpu->arch.timer_cpu;
-	u64 ns;
-	cycle_t cval, now;
 
 	BUG_ON(timer_is_armed(timer));
 
@@ -189,14 +227,7 @@ void kvm_timer_schedule(struct kvm_vcpu
 		return;
 
 	/*  The timer has not yet expired, schedule a background timer */
-	cval = timer->cntv_cval;
-	now = kvm_phys_timer_read() - vcpu->kvm->arch.timer.cntvoff;
-
-	ns = cyclecounter_cyc2ns(timecounter->cc,
-				 cval - now,
-				 timecounter->mask,
-				 &timecounter->frac);
-	timer_arm(timer, ns);
+	timer_arm(timer, kvm_timer_compute_delta(vcpu));
 }
 
 void kvm_timer_unschedule(struct kvm_vcpu *vcpu)
@@ -218,7 +249,8 @@ void kvm_timer_flush_hwstate(struct kvm_
 	bool phys_active;
 	int ret;
 
-	kvm_timer_update_state(vcpu);
+	if (kvm_timer_update_state(vcpu))
+		return;
 
 	/*
 	* If we enter the guest with the virtual input level to the VGIC
--- zfcpdump-kernel-4.4.orig/virt/kvm/arm/vgic.c
+++ zfcpdump-kernel-4.4/virt/kvm/arm/vgic.c
@@ -1875,8 +1875,8 @@ void kvm_vgic_vcpu_destroy(struct kvm_vc
 static int vgic_vcpu_init_maps(struct kvm_vcpu *vcpu, int nr_irqs)
 {
 	struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu;
-
-	int sz = (nr_irqs - VGIC_NR_PRIVATE_IRQS) / 8;
+	int nr_longs = BITS_TO_LONGS(nr_irqs - VGIC_NR_PRIVATE_IRQS);
+	int sz = nr_longs * sizeof(unsigned long);
 	vgic_cpu->pending_shared = kzalloc(sz, GFP_KERNEL);
 	vgic_cpu->active_shared = kzalloc(sz, GFP_KERNEL);
 	vgic_cpu->pend_act_shared = kzalloc(sz, GFP_KERNEL);
--- zfcpdump-kernel-4.4.orig/virt/kvm/async_pf.c
+++ zfcpdump-kernel-4.4/virt/kvm/async_pf.c
@@ -173,7 +173,7 @@ int kvm_setup_async_pf(struct kvm_vcpu *
 	 * do alloc nowait since if we are going to sleep anyway we
 	 * may as well sleep faulting in page
 	 */
-	work = kmem_cache_zalloc(async_pf_cache, GFP_NOWAIT);
+	work = kmem_cache_zalloc(async_pf_cache, GFP_NOWAIT | __GFP_NOWARN);
 	if (!work)
 		return 0;
 
--- zfcpdump-kernel-4.4.orig/virt/kvm/irqchip.c
+++ zfcpdump-kernel-4.4/virt/kvm/irqchip.c
@@ -40,7 +40,7 @@ int kvm_irq_map_gsi(struct kvm *kvm,
 
 	irq_rt = srcu_dereference_check(kvm->irq_routing, &kvm->irq_srcu,
 					lockdep_is_held(&kvm->irq_lock));
-	if (gsi < irq_rt->nr_rt_entries) {
+	if (irq_rt && gsi < irq_rt->nr_rt_entries) {
 		hlist_for_each_entry(e, &irq_rt->map[gsi], link) {
 			entries[n] = *e;
 			++n;
--- zfcpdump-kernel-4.4.orig/virt/kvm/kvm_main.c
+++ zfcpdump-kernel-4.4/virt/kvm/kvm_main.c
@@ -142,6 +142,7 @@ int vcpu_load(struct kvm_vcpu *vcpu)
 	put_cpu();
 	return 0;
 }
+EXPORT_SYMBOL_GPL(vcpu_load);
 
 void vcpu_put(struct kvm_vcpu *vcpu)
 {
@@ -151,6 +152,7 @@ void vcpu_put(struct kvm_vcpu *vcpu)
 	preempt_enable();
 	mutex_unlock(&vcpu->mutex);
 }
+EXPORT_SYMBOL_GPL(vcpu_put);
 
 static void ack_flush(void *_completed)
 {
@@ -547,6 +549,16 @@ static struct kvm *kvm_create_vm(unsigne
 	if (!kvm)
 		return ERR_PTR(-ENOMEM);
 
+	spin_lock_init(&kvm->mmu_lock);
+	atomic_inc(&current->mm->mm_count);
+	kvm->mm = current->mm;
+	kvm_eventfd_init(kvm);
+	mutex_init(&kvm->lock);
+	mutex_init(&kvm->irq_lock);
+	mutex_init(&kvm->slots_lock);
+	atomic_set(&kvm->users_count, 1);
+	INIT_LIST_HEAD(&kvm->devices);
+
 	r = kvm_arch_init_vm(kvm, type);
 	if (r)
 		goto out_err_no_disable;
@@ -579,16 +591,6 @@ static struct kvm *kvm_create_vm(unsigne
 			goto out_err;
 	}
 
-	spin_lock_init(&kvm->mmu_lock);
-	kvm->mm = current->mm;
-	atomic_inc(&kvm->mm->mm_count);
-	kvm_eventfd_init(kvm);
-	mutex_init(&kvm->lock);
-	mutex_init(&kvm->irq_lock);
-	mutex_init(&kvm->slots_lock);
-	atomic_set(&kvm->users_count, 1);
-	INIT_LIST_HEAD(&kvm->devices);
-
 	r = kvm_init_mmu_notifier(kvm);
 	if (r)
 		goto out_err;
@@ -613,6 +615,7 @@ out_err_no_disable:
 	for (i = 0; i < KVM_ADDRESS_SPACE_NUM; i++)
 		kvm_free_memslots(kvm, kvm->memslots[i]);
 	kvm_arch_free_vm(kvm);
+	mmdrop(current->mm);
 	return ERR_PTR(r);
 }
 
@@ -1961,6 +1964,9 @@ static void grow_halt_poll_ns(struct kvm
 	else
 		val *= halt_poll_ns_grow;
 
+	if (val > halt_poll_ns)
+		val = halt_poll_ns;
+
 	vcpu->halt_poll_ns = val;
 	trace_kvm_halt_poll_ns_grow(vcpu->vcpu_id, val, old);
 }
@@ -2857,7 +2863,7 @@ static long kvm_vm_ioctl(struct file *fi
 		if (copy_from_user(&routing, argp, sizeof(routing)))
 			goto out;
 		r = -EINVAL;
-		if (routing.nr >= KVM_MAX_IRQ_ROUTES)
+		if (routing.nr > KVM_MAX_IRQ_ROUTES)
 			goto out;
 		if (routing.flags)
 			goto out;
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/AUTHORS
@@ -0,0 +1,95 @@
+Brian Behlendorf is the principal developer of the ZFS on Linux port.
+He works full time as a computer scientist at Lawrence Livermore
+National Laboratory on the ZFS and Lustre filesystems.  However,
+this port would not have been possible without the help of many
+others who have contributed their time, effort, and insight.
+
+  Brian Behlendorf <behlendorf1@llnl.gov>
+
+First and foremost the hard working ZFS developers at Sun/Oracle.
+They are responsible for the bulk of the code in this project and
+without their efforts there never would have been a ZFS filesystem.
+
+  The ZFS Development Team at Sun/Oracle
+
+Next all the developers at KQ Infotech who implemented a prototype
+ZFS Posix Layer (ZPL).  Their implementation provided an excellent
+reference for adding the ZPL functionality.
+
+  Anand Mitra <mitra@kqinfotech.com>
+  Anurag Agarwal <anurag@kqinfotech.com>
+  Neependra Khare <neependra@kqinfotech.com>
+  Prasad Joshi <prasad@kqinfotech.com>
+  Rohan Puri <rohan@kqinfotech.com>
+  Sandip Divekar <sandipd@kqinfotech.com>
+  Shoaib <shoaib@kqinfotech.com>
+  Shrirang <shrirang@kqinfotech.com>
+
+Additionally the following individuals have all made contributions
+to the project and deserve to be acknowledged.
+
+  Albert Lee <trisk@nexenta.com>
+  Alejandro R. Sedeño <asedeno@mit.edu>
+  Alex Zhuravlev <bzzz@whamcloud.com>
+  Alexander Eremin <a.eremin@nexenta.com>
+  Alexander Stetsenko <ams@nexenta.com>
+  Alexey Shvetsov <alexxy@gentoo.org>
+  Andreas Dilger <adilger@whamcloud.com>
+  Andrew Reid <ColdCanuck@nailedtotheperch.com>
+  Andrew Stormont <andrew.stormont@nexenta.com>
+  Andrew Tselischev <andrewtselischev@gmail.com>
+  Andriy Gapon <avg@FreeBSD.org>
+  Aniruddha Shankar <k@191a.net>
+  Bill Pijewski <wdp@joyent.com>
+  Chris Dunlap <cdunlap@llnl.gov>
+  Chris Dunlop <chris@onthe.net.au>
+  Chris Siden <chris.siden@delphix.com>
+  Chris Wedgwood <cw@f00f.org>
+  Christian Kohlschütter <christian@kohlschutter.com>
+  Christopher Siden <chris.siden@delphix.com>
+  Craig Sanders <github@taz.net.au>
+  Cyril Plisko <cyril.plisko@mountall.com>
+  Dan McDonald <danmcd@nexenta.com>
+  Daniel Verite <daniel@verite.pro>
+  Darik Horn <dajhorn@vanadac.com>
+  Eric Schrock <Eric.Schrock@delphix.com>
+  Etienne Dechamps <etienne.dechamps@ovh.net>
+  Fajar A. Nugraha <github@fajar.net>
+  Frederik Wessels <wessels147@gmail.com>
+  Garrett D'Amore <garrett@nexenta.com>
+  George Wilson <george.wilson@delphix.com>
+  Gordon Ross <gwr@nexenta.com>
+  Gregor Kopka <mailfrom-github.com@kopka.net>
+  Gunnar Beutner <gunnar@beutner.name>
+  James H <james@kagisoft.co.uk>
+  Javen Wu <wu.javen@gmail.com>
+  Jeremy Gill <jgill@parallax-innovations.com>
+  Jorgen Lundman <lundman@lundman.net>
+  KORN Andras <korn@elan.rulez.org>
+  Kyle Fuller <inbox@kylefuller.co.uk>
+  Manuel Amador (Rudd-O) <rudd-o@rudd-o.com>
+  Martin Matuska <mm@FreeBSD.org>
+  Massimo Maggi <massimo@mmmm.it>
+  Matthew Ahrens <mahrens@delphix.com>
+  Michael Martin <mgmartin.mgm@gmail.com>
+  Mike Harsch <mike@harschsystems.com>
+  Ned Bass <bass6@llnl.gov>
+  Oleg Stepura <oleg@stepura.com>
+  P.SCH <p88@yahoo.com>
+  Pawel Jakub Dawidek <pawel@dawidek.net>
+  Prakash Surya <surya1@llnl.gov>
+  Prasad Joshi <pjoshi@stec-inc.com>
+  Ricardo M. Correia <Ricardo.M.Correia@Sun.COM>
+  Richard Laager <rlaager@wiktel.com>
+  Richard Lowe <richlowe@richlowe.net>
+  Richard Yao <ryao@cs.stonybrook.edu>
+  Rohan Puri <rohan.puri15@gmail.com>
+  Shampavman <sham.pavman@nexenta.com>
+  Simon Klinkert <klinkert@webgods.de>
+  Suman Chakravartula <suman@gogrid.com>
+  Tim Haley <Tim.Haley@Sun.COM>
+  Turbo Fredriksson <turbo@bayour.com>
+  Xin Li <delphij@FreeBSD.org>
+  Yuxuan Shui <yshuiv7@gmail.com>
+  Zachary Bedell <zac@thebedells.org>
+  nordaux <nordaux@gmail.com>
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/COPYRIGHT
@@ -0,0 +1,33 @@
+The majority of the code in the ZFS on Linux port comes from OpenSolaris
+which has been released under the terms of the CDDL open source license.
+This includes the core ZFS code, libavl, libnvpair, libefi, libunicode,
+and libutil.  The original OpenSolaris source can be downloaded from:
+
+http://dlc.sun.com/osol/on/downloads/b121/on-src.tar.bz2
+
+Files which do not originate from OpenSolaris are noted in the file header
+and attributed properly.  These exceptions include, but are not limited
+to, the vdev_disk.c and zvol.c implementation which are licensed under
+the CDDL.
+
+The zpios test code is originally derived from the Lustre pios test code
+which is licensed under the GPLv2.  As such the heavily modified zpios
+kernel test code also remains licensed under the GPLv2.
+
+The latest stable and development versions of this port can be downloaded
+from the official ZFS on Linux site located at:
+
+http://zfsonlinux.org/
+
+This ZFS on Linux port was produced at the Lawrence Livermore National
+Laboratory (LLNL) under Contract No. DE-AC52-07NA27344 (Contract 44)
+between the U.S. Department of Energy (DOE) and Lawrence Livermore
+National Security, LLC (LLNS) for the operation of LLNL.  It has been
+approved for release under LLNL-CODE-403049.
+
+Unless otherwise noted, all files in this distribution are released
+under the Common Development and Distribution License (CDDL).
+Exceptions are noted within the associated source files.  See the file
+OPENSOLARIS.LICENSE for more information.
+
+Refer to the git commit log for authoritative copyright attribution.
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/DISCLAIMER
@@ -0,0 +1,24 @@
+This work was produced at the Lawrence Livermore National Laboratory
+(LLNL) under Contract No. DE-AC52-07NA27344 (Contract 44) between
+the U.S. Department of Energy (DOE) and Lawrence Livermore National
+Security, LLC (LLNS) for the operation of LLNL.
+
+This work was prepared as an account of work sponsored by an agency of
+the United States Government.  Neither the United States Government nor
+Lawrence Livermore National Security, LLC nor any of their employees,
+makes any warranty, express or implied, or assumes any liability or
+responsibility for the accuracy, completeness, or usefulness of any
+information, apparatus, product, or process disclosed, or represents
+that its use would not infringe privately-owned rights.
+
+Reference herein to any specific commercial products, process, or
+services by trade name, trademark, manufacturer or otherwise does
+not necessarily constitute or imply its endorsement, recommendation,
+or favoring by the United States Government or Lawrence Livermore
+National Security, LLC.  The views and opinions of authors expressed
+herein do not necessarily state or reflect those of the United States
+Government or Lawrence Livermore National Security, LLC, and shall
+not be used for advertising or product endorsement purposes.
+
+The precise terms and conditions for copying, distribution, and
+modification are specified in the file OPENSOLARIS.LICENSE.
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/META
@@ -0,0 +1,8 @@
+Meta:         1
+Name:         zfs
+Branch:       1.0
+Version:      0.6.5.6
+Release:      0ubuntu10
+Release-Tags: relext
+License:      CDDL
+Author:       OpenZFS on Linux
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/Makefile.am
@@ -0,0 +1,70 @@
+ACLOCAL_AMFLAGS = -I config
+
+include config/rpm.am
+include config/deb.am
+include config/tgz.am
+
+SUBDIRS = include rpm
+if CONFIG_USER
+SUBDIRS += udev etc man scripts lib cmd contrib
+endif
+if CONFIG_KERNEL
+SUBDIRS += module
+
+extradir = @prefix@/src/zfs-$(VERSION)
+extra_HEADERS = zfs.release.in zfs_config.h.in
+
+kerneldir = @prefix@/src/zfs-$(VERSION)/$(LINUX_VERSION)
+nodist_kernel_HEADERS = zfs.release zfs_config.h module/$(LINUX_SYMBOLS)
+endif
+
+AUTOMAKE_OPTIONS = foreign
+EXTRA_DIST  = autogen.sh copy-builtin
+EXTRA_DIST += config/config.awk config/rpm.am config/deb.am config/tgz.am
+EXTRA_DIST += META DISCLAIMER COPYRIGHT README.markdown OPENSOLARIS.LICENSE
+
+distclean-local::
+	-$(RM) -R autom4te*.cache
+	-find . \( -name SCCS -o -name BitKeeper -o -name .svn -o -name CVS \
+		-o -name .pc -o -name .hg -o -name .git \) -prune -o \
+		\( -name '*.orig' -o -name '*.rej' -o -name '*~' \
+		-o -name '*.bak' -o -name '#*#' -o -name '.*.orig' \
+		-o -name '.*.rej' -o -name '.script-config' -o -size 0 \
+		-o -name '*%' -o -name '.*.cmd' -o -name 'core' \
+		-o -name 'Makefile' -o -name 'Module.symvers' \
+		-o -name '*.order' -o -name '*.markers' \) \
+		-type f -print | xargs $(RM)
+
+dist-hook:
+	sed -i 's/Release:[[:print:]]*/Release:      $(RELEASE)/' \
+		$(distdir)/META
+
+checkstyle: cstyle shellcheck
+
+cstyle:
+	@find ${top_srcdir} -name '*.[hc]' ! -name 'zfs_config.*' \
+		! -name '*.mod.c' -type f -exec scripts/cstyle.pl {} \+
+
+shellcheck:
+	@if type shellcheck > /dev/null 2>&1; then \
+		(find ${top_srcdir} -type f -name '*.sh.in' -o -type f \
+		 -name '*.sh'; find etc/init.d/zfs*.in -type f) | \
+		 grep -v 'zfs-script-config' | \
+		 while read file; do \
+			shellcheck --format gcc "$$file"; \
+		 done; \
+	 fi
+
+ctags:
+	$(RM) tags
+	find $(top_srcdir) -name .git -prune -o -name '*.[hc]' | xargs ctags
+
+etags:
+	$(RM) TAGS
+	find $(top_srcdir) -name .pc -prune -o -name '*.[hc]' | xargs etags -a
+
+tags: ctags etags
+
+pkg: @DEFAULT_PACKAGE@
+pkg-kmod: @DEFAULT_PACKAGE@-kmod
+pkg-utils: @DEFAULT_PACKAGE@-utils
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/Makefile.in
@@ -0,0 +1,1305 @@
+# Makefile.in generated by automake 1.15 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2014 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+###############################################################################
+# Copyright (C) 2007-2013 Lawrence Livermore National Security, LLC.
+# Copyright (C) 2007 The Regents of the University of California.
+# Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+###############################################################################
+# Build targets for RPM packages.
+###############################################################################
+
+VPATH = @srcdir@
+am__is_gnu_make = { \
+  if test -z '$(MAKELEVEL)'; then \
+    false; \
+  elif test -n '$(MAKE_HOST)'; then \
+    true; \
+  elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+    true; \
+  else \
+    false; \
+  fi; \
+}
+am__make_running_with_option = \
+  case $${target_option-} in \
+      ?) ;; \
+      *) echo "am__make_running_with_option: internal error: invalid" \
+              "target option '$${target_option-}' specified" >&2; \
+         exit 1;; \
+  esac; \
+  has_opt=no; \
+  sane_makeflags=$$MAKEFLAGS; \
+  if $(am__is_gnu_make); then \
+    sane_makeflags=$$MFLAGS; \
+  else \
+    case $$MAKEFLAGS in \
+      *\\[\ \	]*) \
+        bs=\\; \
+        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
+    esac; \
+  fi; \
+  skip_next=no; \
+  strip_trailopt () \
+  { \
+    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+  }; \
+  for flg in $$sane_makeflags; do \
+    test $$skip_next = yes && { skip_next=no; continue; }; \
+    case $$flg in \
+      *=*|--*) continue;; \
+        -*I) strip_trailopt 'I'; skip_next=yes;; \
+      -*I?*) strip_trailopt 'I';; \
+        -*O) strip_trailopt 'O'; skip_next=yes;; \
+      -*O?*) strip_trailopt 'O';; \
+        -*l) strip_trailopt 'l'; skip_next=yes;; \
+      -*l?*) strip_trailopt 'l';; \
+      -[dEDm]) skip_next=yes;; \
+      -[JT]) skip_next=yes;; \
+    esac; \
+    case $$flg in \
+      *$$target_option*) has_opt=yes; break;; \
+    esac; \
+  done; \
+  test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+target_triplet = @target@
+@CONFIG_USER_TRUE@am__append_1 = udev etc man scripts lib cmd contrib
+@CONFIG_KERNEL_TRUE@am__append_2 = module
+subdir = .
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/config/always-no-bool-compare.m4 \
+	$(top_srcdir)/config/always-no-unused-but-set-variable.m4 \
+	$(top_srcdir)/config/dkms.m4 \
+	$(top_srcdir)/config/kernel-acl.m4 \
+	$(top_srcdir)/config/kernel-automount.m4 \
+	$(top_srcdir)/config/kernel-bdev-block-device-operations.m4 \
+	$(top_srcdir)/config/kernel-bdev-logical-size.m4 \
+	$(top_srcdir)/config/kernel-bdev-physical-size.m4 \
+	$(top_srcdir)/config/kernel-bdi-setup-and-register.m4 \
+	$(top_srcdir)/config/kernel-bio-bvec-iter.m4 \
+	$(top_srcdir)/config/kernel-bio-end-io-t-args.m4 \
+	$(top_srcdir)/config/kernel-bio-failfast.m4 \
+	$(top_srcdir)/config/kernel-bio-rw-barrier.m4 \
+	$(top_srcdir)/config/kernel-bio-rw-discard.m4 \
+	$(top_srcdir)/config/kernel-blk-queue-flush.m4 \
+	$(top_srcdir)/config/kernel-blk-queue-max-hw-sectors.m4 \
+	$(top_srcdir)/config/kernel-blk-queue-max-segments.m4 \
+	$(top_srcdir)/config/kernel-blkdev-get-by-path.m4 \
+	$(top_srcdir)/config/kernel-blkdev-get.m4 \
+	$(top_srcdir)/config/kernel-block-device-operations-release-void.m4 \
+	$(top_srcdir)/config/kernel-check-disk-size-change.m4 \
+	$(top_srcdir)/config/kernel-clear-inode.m4 \
+	$(top_srcdir)/config/kernel-commit-metadata.m4 \
+	$(top_srcdir)/config/kernel-create-nameidata.m4 \
+	$(top_srcdir)/config/kernel-current_bio_tail.m4 \
+	$(top_srcdir)/config/kernel-d-make-root.m4 \
+	$(top_srcdir)/config/kernel-d-obtain-alias.m4 \
+	$(top_srcdir)/config/kernel-d-prune-aliases.m4 \
+	$(top_srcdir)/config/kernel-declare-event-class.m4 \
+	$(top_srcdir)/config/kernel-dentry-operations.m4 \
+	$(top_srcdir)/config/kernel-dirty-inode.m4 \
+	$(top_srcdir)/config/kernel-discard-granularity.m4 \
+	$(top_srcdir)/config/kernel-elevator-change.m4 \
+	$(top_srcdir)/config/kernel-encode-fh-inode.m4 \
+	$(top_srcdir)/config/kernel-evict-inode.m4 \
+	$(top_srcdir)/config/kernel-fallocate.m4 \
+	$(top_srcdir)/config/kernel-file-inode.m4 \
+	$(top_srcdir)/config/kernel-fmode-t.m4 \
+	$(top_srcdir)/config/kernel-follow-down-one.m4 \
+	$(top_srcdir)/config/kernel-fsync.m4 \
+	$(top_srcdir)/config/kernel-generic_io_acct.m4 \
+	$(top_srcdir)/config/kernel-get-disk-ro.m4 \
+	$(top_srcdir)/config/kernel-get-gendisk.m4 \
+	$(top_srcdir)/config/kernel-get-link.m4 \
+	$(top_srcdir)/config/kernel-insert-inode-locked.m4 \
+	$(top_srcdir)/config/kernel-invalidate-bdev-args.m4 \
+	$(top_srcdir)/config/kernel-is_owner_or_cap.m4 \
+	$(top_srcdir)/config/kernel-kmap-atomic-args.m4 \
+	$(top_srcdir)/config/kernel-kobj-name-len.m4 \
+	$(top_srcdir)/config/kernel-lookup-bdev.m4 \
+	$(top_srcdir)/config/kernel-lookup-nameidata.m4 \
+	$(top_srcdir)/config/kernel-lseek-execute.m4 \
+	$(top_srcdir)/config/kernel-mk-request-fn.m4 \
+	$(top_srcdir)/config/kernel-mkdir-umode-t.m4 \
+	$(top_srcdir)/config/kernel-mount-nodev.m4 \
+	$(top_srcdir)/config/kernel-open-bdev-exclusive.m4 \
+	$(top_srcdir)/config/kernel-put-link.m4 \
+	$(top_srcdir)/config/kernel-security-inode-init.m4 \
+	$(top_srcdir)/config/kernel-set-nlink.m4 \
+	$(top_srcdir)/config/kernel-sget-args.m4 \
+	$(top_srcdir)/config/kernel-show-options.m4 \
+	$(top_srcdir)/config/kernel-shrink.m4 \
+	$(top_srcdir)/config/kernel-truncate-range.m4 \
+	$(top_srcdir)/config/kernel-truncate-setsize.m4 \
+	$(top_srcdir)/config/kernel-vfs-iterate.m4 \
+	$(top_srcdir)/config/kernel-vfs-rw-iterate.m4 \
+	$(top_srcdir)/config/kernel-xattr-handler.m4 \
+	$(top_srcdir)/config/kernel.m4 $(top_srcdir)/config/libtool.m4 \
+	$(top_srcdir)/config/ltoptions.m4 \
+	$(top_srcdir)/config/ltsugar.m4 \
+	$(top_srcdir)/config/ltversion.m4 \
+	$(top_srcdir)/config/lt~obsolete.m4 \
+	$(top_srcdir)/config/mount-helper.m4 \
+	$(top_srcdir)/config/user-arch.m4 \
+	$(top_srcdir)/config/user-dracut.m4 \
+	$(top_srcdir)/config/user-frame-larger-than.m4 \
+	$(top_srcdir)/config/user-libblkid.m4 \
+	$(top_srcdir)/config/user-libuuid.m4 \
+	$(top_srcdir)/config/user-runstatedir.m4 \
+	$(top_srcdir)/config/user-systemd.m4 \
+	$(top_srcdir)/config/user-sysvinit.m4 \
+	$(top_srcdir)/config/user-udev.m4 \
+	$(top_srcdir)/config/user-zlib.m4 $(top_srcdir)/config/user.m4 \
+	$(top_srcdir)/config/zfs-build.m4 \
+	$(top_srcdir)/config/zfs-meta.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(top_srcdir)/configure \
+	$(am__configure_deps) $(am__extra_HEADERS_DIST) \
+	$(am__DIST_COMMON)
+am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
+ configure.lineno config.status.lineno
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = zfs_config.h
+CONFIG_CLEAN_FILES = module/Makefile module/avl/Makefile \
+	module/nvpair/Makefile module/unicode/Makefile \
+	module/zcommon/Makefile module/zfs/Makefile \
+	module/zpios/Makefile zfs-script-config.sh zfs.release
+CONFIG_CLEAN_VPATH_FILES =
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo "  GEN     " $@;
+am__v_GEN_1 = 
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 = 
+SOURCES =
+DIST_SOURCES =
+RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \
+	ctags-recursive dvi-recursive html-recursive info-recursive \
+	install-data-recursive install-dvi-recursive \
+	install-exec-recursive install-html-recursive \
+	install-info-recursive install-pdf-recursive \
+	install-ps-recursive install-recursive installcheck-recursive \
+	installdirs-recursive pdf-recursive ps-recursive \
+	tags-recursive uninstall-recursive
+am__can_run_installinfo = \
+  case $$AM_UPDATE_INFO_DIR in \
+    n|no|NO) false;; \
+    *) (install-info --version) >/dev/null 2>&1;; \
+  esac
+am__extra_HEADERS_DIST = zfs.release.in zfs_config.h.in
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+    $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+    *) f=$$p;; \
+  esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+  srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+  for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+  for p in $$list; do echo "$$p $$p"; done | \
+  sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+  $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+    if (++n[$$2] == $(am__install_max)) \
+      { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+    END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+  sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+  sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+  test -z "$$files" \
+    || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+    || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+         $(am__cd) "$$dir" && rm -f $$files; }; \
+  }
+am__installdirs = "$(DESTDIR)$(extradir)" "$(DESTDIR)$(kerneldir)"
+HEADERS = $(extra_HEADERS) $(nodist_kernel_HEADERS)
+RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive	\
+  distclean-recursive maintainer-clean-recursive
+am__recursive_targets = \
+  $(RECURSIVE_TARGETS) \
+  $(RECURSIVE_CLEAN_TARGETS) \
+  $(am__extra_recursive_targets)
+AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \
+	cscope distdir dist dist-all distcheck
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) \
+	$(LISP)zfs_config.h.in
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates.  Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+  BEGIN { nonempty = 0; } \
+  { items[$$0] = 1; nonempty = 1; } \
+  END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique.  This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+  list='$(am__tagged_files)'; \
+  unique=`for i in $$list; do \
+    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+  done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+CSCOPE = cscope
+DIST_SUBDIRS = include rpm udev etc man scripts lib cmd contrib module
+am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/config/deb.am \
+	$(srcdir)/config/rpm.am $(srcdir)/config/tgz.am \
+	$(srcdir)/zfs-script-config.sh.in $(srcdir)/zfs.release.in \
+	$(srcdir)/zfs_config.h.in $(top_srcdir)/config/compile \
+	$(top_srcdir)/config/config.guess \
+	$(top_srcdir)/config/config.sub \
+	$(top_srcdir)/config/install-sh $(top_srcdir)/config/ltmain.sh \
+	$(top_srcdir)/config/missing $(top_srcdir)/module/Makefile.in \
+	$(top_srcdir)/module/avl/Makefile.in \
+	$(top_srcdir)/module/nvpair/Makefile.in \
+	$(top_srcdir)/module/unicode/Makefile.in \
+	$(top_srcdir)/module/zcommon/Makefile.in \
+	$(top_srcdir)/module/zfs/Makefile.in \
+	$(top_srcdir)/module/zpios/Makefile.in AUTHORS config/compile \
+	config/config.guess config/config.sub config/install-sh \
+	config/ltmain.sh config/missing
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+distdir = $(PACKAGE)-$(VERSION)
+top_distdir = $(distdir)
+am__remove_distdir = \
+  if test -d "$(distdir)"; then \
+    find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \
+      && rm -rf "$(distdir)" \
+      || { sleep 5 && rm -rf "$(distdir)"; }; \
+  else :; fi
+am__post_remove_distdir = $(am__remove_distdir)
+am__relativize = \
+  dir0=`pwd`; \
+  sed_first='s,^\([^/]*\)/.*$$,\1,'; \
+  sed_rest='s,^[^/]*/*,,'; \
+  sed_last='s,^.*/\([^/]*\)$$,\1,'; \
+  sed_butlast='s,/*[^/]*$$,,'; \
+  while test -n "$$dir1"; do \
+    first=`echo "$$dir1" | sed -e "$$sed_first"`; \
+    if test "$$first" != "."; then \
+      if test "$$first" = ".."; then \
+        dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \
+        dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \
+      else \
+        first2=`echo "$$dir2" | sed -e "$$sed_first"`; \
+        if test "$$first2" = "$$first"; then \
+          dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \
+        else \
+          dir2="../$$dir2"; \
+        fi; \
+        dir0="$$dir0"/"$$first"; \
+      fi; \
+    fi; \
+    dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \
+  done; \
+  reldir="$$dir2"
+DIST_ARCHIVES = $(distdir).tar.gz
+GZIP_ENV = --best
+DIST_TARGETS = dist-gzip
+distuninstallcheck_listfiles = find . -type f -print
+am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \
+  | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$'
+distcleancheck_listfiles = find . -type f -print
+ACLOCAL = @ACLOCAL@
+ALIEN = @ALIEN@
+ALIEN_VERSION = @ALIEN_VERSION@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCAS = @CCAS@
+CCASDEPMODE = @CCASDEPMODE@
+CCASFLAGS = @CCASFLAGS@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEBUG_CFLAGS = @DEBUG_CFLAGS@
+DEBUG_DMU_TX = @DEBUG_DMU_TX@
+DEBUG_STACKFLAGS = @DEBUG_STACKFLAGS@
+DEBUG_ZFS = @DEBUG_ZFS@
+DEFAULT_INITCONF_DIR = @DEFAULT_INITCONF_DIR@
+DEFAULT_INIT_DIR = @DEFAULT_INIT_DIR@
+DEFAULT_INIT_SCRIPT = @DEFAULT_INIT_SCRIPT@
+DEFAULT_PACKAGE = @DEFAULT_PACKAGE@
+DEFINE_INITRAMFS = @DEFINE_INITRAMFS@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DPKG = @DPKG@
+DPKGBUILD = @DPKGBUILD@
+DPKGBUILD_VERSION = @DPKGBUILD_VERSION@
+DPKG_VERSION = @DPKG_VERSION@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+FRAME_LARGER_THAN = @FRAME_LARGER_THAN@
+GREP = @GREP@
+HAVE_ALIEN = @HAVE_ALIEN@
+HAVE_DPKG = @HAVE_DPKG@
+HAVE_DPKGBUILD = @HAVE_DPKGBUILD@
+HAVE_RPM = @HAVE_RPM@
+HAVE_RPMBUILD = @HAVE_RPMBUILD@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+KERNELCPPFLAGS = @KERNELCPPFLAGS@
+KERNELMAKE_PARAMS = @KERNELMAKE_PARAMS@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBBLKID = @LIBBLKID@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIBUUID = @LIBUUID@
+LINUX = @LINUX@
+LINUX_OBJ = @LINUX_OBJ@
+LINUX_SYMBOLS = @LINUX_SYMBOLS@
+LINUX_VERSION = @LINUX_VERSION@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NO_BOOL_COMPARE = @NO_BOOL_COMPARE@
+NO_UNUSED_BUT_SET_VARIABLE = @NO_UNUSED_BUT_SET_VARIABLE@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+RANLIB = @RANLIB@
+RELEASE = @RELEASE@
+RPM = @RPM@
+RPMBUILD = @RPMBUILD@
+RPMBUILD_VERSION = @RPMBUILD_VERSION@
+RPM_DEFINE_COMMON = @RPM_DEFINE_COMMON@
+RPM_DEFINE_DKMS = @RPM_DEFINE_DKMS@
+RPM_DEFINE_KMOD = @RPM_DEFINE_KMOD@
+RPM_DEFINE_UTIL = @RPM_DEFINE_UTIL@
+RPM_SPEC_DIR = @RPM_SPEC_DIR@
+RPM_VERSION = @RPM_VERSION@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SPL = @SPL@
+SPL_OBJ = @SPL_OBJ@
+SPL_SYMBOLS = @SPL_SYMBOLS@
+SPL_VERSION = @SPL_VERSION@
+SRPM_DEFINE_COMMON = @SRPM_DEFINE_COMMON@
+SRPM_DEFINE_DKMS = @SRPM_DEFINE_DKMS@
+SRPM_DEFINE_KMOD = @SRPM_DEFINE_KMOD@
+SRPM_DEFINE_UTIL = @SRPM_DEFINE_UTIL@
+STRIP = @STRIP@
+TARGET_ASM_DIR = @TARGET_ASM_DIR@
+VENDOR = @VENDOR@
+VERSION = @VERSION@
+ZFS_CONFIG = @ZFS_CONFIG@
+ZFS_INIT_SYSTEMD = @ZFS_INIT_SYSTEMD@
+ZFS_INIT_SYSV = @ZFS_INIT_SYSV@
+ZFS_META_ALIAS = @ZFS_META_ALIAS@
+ZFS_META_AUTHOR = @ZFS_META_AUTHOR@
+ZFS_META_DATA = @ZFS_META_DATA@
+ZFS_META_LICENSE = @ZFS_META_LICENSE@
+ZFS_META_LT_AGE = @ZFS_META_LT_AGE@
+ZFS_META_LT_CURRENT = @ZFS_META_LT_CURRENT@
+ZFS_META_LT_REVISION = @ZFS_META_LT_REVISION@
+ZFS_META_NAME = @ZFS_META_NAME@
+ZFS_META_RELEASE = @ZFS_META_RELEASE@
+ZFS_META_VERSION = @ZFS_META_VERSION@
+ZFS_MODULE_LOAD = @ZFS_MODULE_LOAD@
+ZLIB = @ZLIB@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dracutdir = @dracutdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+modulesloaddir = @modulesloaddir@
+mounthelperdir = @mounthelperdir@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+runstatedir = @runstatedir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+systemdpresetdir = @systemdpresetdir@
+systemdunitdir = @systemdunitdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+udevdir = @udevdir@
+udevruledir = @udevruledir@
+ACLOCAL_AMFLAGS = -I config
+SUBDIRS = include rpm $(am__append_1) $(am__append_2)
+@CONFIG_KERNEL_TRUE@extradir = @prefix@/src/zfs-$(VERSION)
+@CONFIG_KERNEL_TRUE@extra_HEADERS = zfs.release.in zfs_config.h.in
+@CONFIG_KERNEL_TRUE@kerneldir = @prefix@/src/zfs-$(VERSION)/$(LINUX_VERSION)
+@CONFIG_KERNEL_TRUE@nodist_kernel_HEADERS = zfs.release zfs_config.h module/$(LINUX_SYMBOLS)
+AUTOMAKE_OPTIONS = foreign
+EXTRA_DIST = autogen.sh copy-builtin config/config.awk config/rpm.am \
+	config/deb.am config/tgz.am META DISCLAIMER COPYRIGHT \
+	README.markdown OPENSOLARIS.LICENSE
+all: zfs_config.h
+	$(MAKE) $(AM_MAKEFLAGS) all-recursive
+
+.SUFFIXES:
+am--refresh: Makefile
+	@:
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(srcdir)/config/rpm.am $(srcdir)/config/deb.am $(srcdir)/config/tgz.am $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      echo ' cd $(srcdir) && $(AUTOMAKE) --foreign'; \
+	      $(am__cd) $(srcdir) && $(AUTOMAKE) --foreign \
+		&& exit 0; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --foreign Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    echo ' $(SHELL) ./config.status'; \
+	    $(SHELL) ./config.status;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \
+	esac;
+$(srcdir)/config/rpm.am $(srcdir)/config/deb.am $(srcdir)/config/tgz.am $(am__empty):
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	$(SHELL) ./config.status --recheck
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+	$(am__cd) $(srcdir) && $(AUTOCONF)
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+	$(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS)
+$(am__aclocal_m4_deps):
+
+zfs_config.h: stamp-h1
+	@test -f $@ || rm -f stamp-h1
+	@test -f $@ || $(MAKE) $(AM_MAKEFLAGS) stamp-h1
+
+stamp-h1: $(srcdir)/zfs_config.h.in $(top_builddir)/config.status
+	@rm -f stamp-h1
+	cd $(top_builddir) && $(SHELL) ./config.status zfs_config.h
+$(srcdir)/zfs_config.h.in: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) 
+	($(am__cd) $(top_srcdir) && $(AUTOHEADER))
+	rm -f stamp-h1
+	touch $@
+
+distclean-hdr:
+	-rm -f zfs_config.h stamp-h1
+module/Makefile: $(top_builddir)/config.status $(top_srcdir)/module/Makefile.in
+	cd $(top_builddir) && $(SHELL) ./config.status $@
+module/avl/Makefile: $(top_builddir)/config.status $(top_srcdir)/module/avl/Makefile.in
+	cd $(top_builddir) && $(SHELL) ./config.status $@
+module/nvpair/Makefile: $(top_builddir)/config.status $(top_srcdir)/module/nvpair/Makefile.in
+	cd $(top_builddir) && $(SHELL) ./config.status $@
+module/unicode/Makefile: $(top_builddir)/config.status $(top_srcdir)/module/unicode/Makefile.in
+	cd $(top_builddir) && $(SHELL) ./config.status $@
+module/zcommon/Makefile: $(top_builddir)/config.status $(top_srcdir)/module/zcommon/Makefile.in
+	cd $(top_builddir) && $(SHELL) ./config.status $@
+module/zfs/Makefile: $(top_builddir)/config.status $(top_srcdir)/module/zfs/Makefile.in
+	cd $(top_builddir) && $(SHELL) ./config.status $@
+module/zpios/Makefile: $(top_builddir)/config.status $(top_srcdir)/module/zpios/Makefile.in
+	cd $(top_builddir) && $(SHELL) ./config.status $@
+zfs-script-config.sh: $(top_builddir)/config.status $(srcdir)/zfs-script-config.sh.in
+	cd $(top_builddir) && $(SHELL) ./config.status $@
+zfs.release: $(top_builddir)/config.status $(srcdir)/zfs.release.in
+	cd $(top_builddir) && $(SHELL) ./config.status $@
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
+
+distclean-libtool:
+	-rm -f libtool config.lt
+install-extraHEADERS: $(extra_HEADERS)
+	@$(NORMAL_INSTALL)
+	@list='$(extra_HEADERS)'; test -n "$(extradir)" || list=; \
+	if test -n "$$list"; then \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(extradir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(extradir)" || exit 1; \
+	fi; \
+	for p in $$list; do \
+	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+	  echo "$$d$$p"; \
+	done | $(am__base_list) | \
+	while read files; do \
+	  echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(extradir)'"; \
+	  $(INSTALL_HEADER) $$files "$(DESTDIR)$(extradir)" || exit $$?; \
+	done
+
+uninstall-extraHEADERS:
+	@$(NORMAL_UNINSTALL)
+	@list='$(extra_HEADERS)'; test -n "$(extradir)" || list=; \
+	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+	dir='$(DESTDIR)$(extradir)'; $(am__uninstall_files_from_dir)
+install-nodist_kernelHEADERS: $(nodist_kernel_HEADERS)
+	@$(NORMAL_INSTALL)
+	@list='$(nodist_kernel_HEADERS)'; test -n "$(kerneldir)" || list=; \
+	if test -n "$$list"; then \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(kerneldir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(kerneldir)" || exit 1; \
+	fi; \
+	for p in $$list; do \
+	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+	  echo "$$d$$p"; \
+	done | $(am__base_list) | \
+	while read files; do \
+	  echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(kerneldir)'"; \
+	  $(INSTALL_HEADER) $$files "$(DESTDIR)$(kerneldir)" || exit $$?; \
+	done
+
+uninstall-nodist_kernelHEADERS:
+	@$(NORMAL_UNINSTALL)
+	@list='$(nodist_kernel_HEADERS)'; test -n "$(kerneldir)" || list=; \
+	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+	dir='$(DESTDIR)$(kerneldir)'; $(am__uninstall_files_from_dir)
+
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run 'make' without going through this Makefile.
+# To change the values of 'make' variables: instead of editing Makefiles,
+# (1) if the variable is set in 'config.status', edit 'config.status'
+#     (which will cause the Makefiles to be regenerated when you run 'make');
+# (2) otherwise, pass the desired values on the 'make' command line.
+$(am__recursive_targets):
+	@fail=; \
+	if $(am__make_keepgoing); then \
+	  failcom='fail=yes'; \
+	else \
+	  failcom='exit 1'; \
+	fi; \
+	dot_seen=no; \
+	target=`echo $@ | sed s/-recursive//`; \
+	case "$@" in \
+	  distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
+	  *) list='$(SUBDIRS)' ;; \
+	esac; \
+	for subdir in $$list; do \
+	  echo "Making $$target in $$subdir"; \
+	  if test "$$subdir" = "."; then \
+	    dot_seen=yes; \
+	    local_target="$$target-am"; \
+	  else \
+	    local_target="$$target"; \
+	  fi; \
+	  ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+	  || eval $$failcom; \
+	done; \
+	if test "$$dot_seen" = "no"; then \
+	  $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+	fi; test -z "$$fail"
+
+ID: $(am__tagged_files)
+	$(am__define_uniq_tagged_files); mkid -fID $$unique
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	set x; \
+	here=`pwd`; \
+	if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
+	  include_option=--etags-include; \
+	  empty_fix=.; \
+	else \
+	  include_option=--include; \
+	  empty_fix=; \
+	fi; \
+	list='$(SUBDIRS)'; for subdir in $$list; do \
+	  if test "$$subdir" = .; then :; else \
+	    test ! -f $$subdir/TAGS || \
+	      set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \
+	  fi; \
+	done; \
+	$(am__define_uniq_tagged_files); \
+	shift; \
+	if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+	  test -n "$$unique" || unique=$$empty_fix; \
+	  if test $$# -gt 0; then \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      "$$@" $$unique; \
+	  else \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      $$unique; \
+	  fi; \
+	fi
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	$(am__define_uniq_tagged_files); \
+	test -z "$(CTAGS_ARGS)$$unique" \
+	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+	     $$unique
+
+GTAGS:
+	here=`$(am__cd) $(top_builddir) && pwd` \
+	  && $(am__cd) $(top_srcdir) \
+	  && gtags -i $(GTAGS_ARGS) "$$here"
+cscope: cscope.files
+	test ! -s cscope.files \
+	  || $(CSCOPE) -b -q $(AM_CSCOPEFLAGS) $(CSCOPEFLAGS) -i cscope.files $(CSCOPE_ARGS)
+clean-cscope:
+	-rm -f cscope.files
+cscope.files: clean-cscope cscopelist
+cscopelist: cscopelist-recursive
+
+cscopelist-am: $(am__tagged_files)
+	list='$(am__tagged_files)'; \
+	case "$(srcdir)" in \
+	  [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+	  *) sdir=$(subdir)/$(srcdir) ;; \
+	esac; \
+	for i in $$list; do \
+	  if test -f "$$i"; then \
+	    echo "$(subdir)/$$i"; \
+	  else \
+	    echo "$$sdir/$$i"; \
+	  fi; \
+	done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+	-rm -f cscope.out cscope.in.out cscope.po.out cscope.files
+
+distdir: $(DISTFILES)
+	$(am__remove_distdir)
+	test -d "$(distdir)" || mkdir "$(distdir)"
+	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	list='$(DISTFILES)'; \
+	  dist_files=`for file in $$list; do echo $$file; done | \
+	  sed -e "s|^$$srcdirstrip/||;t" \
+	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+	case $$dist_files in \
+	  */*) $(MKDIR_P) `echo "$$dist_files" | \
+			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+			   sort -u` ;; \
+	esac; \
+	for file in $$dist_files; do \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  if test -d $$d/$$file; then \
+	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+	    if test -d "$(distdir)/$$file"; then \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+	  else \
+	    test -f "$(distdir)/$$file" \
+	    || cp -p $$d/$$file "$(distdir)/$$file" \
+	    || exit 1; \
+	  fi; \
+	done
+	@list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
+	  if test "$$subdir" = .; then :; else \
+	    $(am__make_dryrun) \
+	      || test -d "$(distdir)/$$subdir" \
+	      || $(MKDIR_P) "$(distdir)/$$subdir" \
+	      || exit 1; \
+	    dir1=$$subdir; dir2="$(distdir)/$$subdir"; \
+	    $(am__relativize); \
+	    new_distdir=$$reldir; \
+	    dir1=$$subdir; dir2="$(top_distdir)"; \
+	    $(am__relativize); \
+	    new_top_distdir=$$reldir; \
+	    echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \
+	    echo "     am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \
+	    ($(am__cd) $$subdir && \
+	      $(MAKE) $(AM_MAKEFLAGS) \
+	        top_distdir="$$new_top_distdir" \
+	        distdir="$$new_distdir" \
+		am__remove_distdir=: \
+		am__skip_length_check=: \
+		am__skip_mode_fix=: \
+	        distdir) \
+	      || exit 1; \
+	  fi; \
+	done
+	$(MAKE) $(AM_MAKEFLAGS) \
+	  top_distdir="$(top_distdir)" distdir="$(distdir)" \
+	  dist-hook
+	-test -n "$(am__skip_mode_fix)" \
+	|| find "$(distdir)" -type d ! -perm -755 \
+		-exec chmod u+rwx,go+rx {} \; -o \
+	  ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \
+	  ! -type d ! -perm -400 -exec chmod a+r {} \; -o \
+	  ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \
+	|| chmod -R a+r "$(distdir)"
+dist-gzip: distdir
+	tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
+	$(am__post_remove_distdir)
+
+dist-bzip2: distdir
+	tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2
+	$(am__post_remove_distdir)
+
+dist-lzip: distdir
+	tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz
+	$(am__post_remove_distdir)
+
+dist-xz: distdir
+	tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz
+	$(am__post_remove_distdir)
+
+dist-tarZ: distdir
+	@echo WARNING: "Support for distribution archives compressed with" \
+		       "legacy program 'compress' is deprecated." >&2
+	@echo WARNING: "It will be removed altogether in Automake 2.0" >&2
+	tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z
+	$(am__post_remove_distdir)
+
+dist-shar: distdir
+	@echo WARNING: "Support for shar distribution archives is" \
+	               "deprecated." >&2
+	@echo WARNING: "It will be removed altogether in Automake 2.0" >&2
+	shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz
+	$(am__post_remove_distdir)
+
+dist-zip: distdir
+	-rm -f $(distdir).zip
+	zip -rq $(distdir).zip $(distdir)
+	$(am__post_remove_distdir)
+
+dist dist-all:
+	$(MAKE) $(AM_MAKEFLAGS) $(DIST_TARGETS) am__post_remove_distdir='@:'
+	$(am__post_remove_distdir)
+
+# This target untars the dist file and tries a VPATH configuration.  Then
+# it guarantees that the distribution is self-contained by making another
+# tarfile.
+distcheck: dist
+	case '$(DIST_ARCHIVES)' in \
+	*.tar.gz*) \
+	  GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\
+	*.tar.bz2*) \
+	  bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\
+	*.tar.lz*) \
+	  lzip -dc $(distdir).tar.lz | $(am__untar) ;;\
+	*.tar.xz*) \
+	  xz -dc $(distdir).tar.xz | $(am__untar) ;;\
+	*.tar.Z*) \
+	  uncompress -c $(distdir).tar.Z | $(am__untar) ;;\
+	*.shar.gz*) \
+	  GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\
+	*.zip*) \
+	  unzip $(distdir).zip ;;\
+	esac
+	chmod -R a-w $(distdir)
+	chmod u+w $(distdir)
+	mkdir $(distdir)/_build $(distdir)/_build/sub $(distdir)/_inst
+	chmod a-w $(distdir)
+	test -d $(distdir)/_build || exit 0; \
+	dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \
+	  && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \
+	  && am__cwd=`pwd` \
+	  && $(am__cd) $(distdir)/_build/sub \
+	  && ../../configure \
+	    $(AM_DISTCHECK_CONFIGURE_FLAGS) \
+	    $(DISTCHECK_CONFIGURE_FLAGS) \
+	    --srcdir=../.. --prefix="$$dc_install_base" \
+	  && $(MAKE) $(AM_MAKEFLAGS) \
+	  && $(MAKE) $(AM_MAKEFLAGS) dvi \
+	  && $(MAKE) $(AM_MAKEFLAGS) check \
+	  && $(MAKE) $(AM_MAKEFLAGS) install \
+	  && $(MAKE) $(AM_MAKEFLAGS) installcheck \
+	  && $(MAKE) $(AM_MAKEFLAGS) uninstall \
+	  && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \
+	        distuninstallcheck \
+	  && chmod -R a-w "$$dc_install_base" \
+	  && ({ \
+	       (cd ../.. && umask 077 && mkdir "$$dc_destdir") \
+	       && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \
+	       && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \
+	       && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \
+	            distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \
+	      } || { rm -rf "$$dc_destdir"; exit 1; }) \
+	  && rm -rf "$$dc_destdir" \
+	  && $(MAKE) $(AM_MAKEFLAGS) dist \
+	  && rm -rf $(DIST_ARCHIVES) \
+	  && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \
+	  && cd "$$am__cwd" \
+	  || exit 1
+	$(am__post_remove_distdir)
+	@(echo "$(distdir) archives ready for distribution: "; \
+	  list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \
+	  sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x'
+distuninstallcheck:
+	@test -n '$(distuninstallcheck_dir)' || { \
+	  echo 'ERROR: trying to run $@ with an empty' \
+	       '$$(distuninstallcheck_dir)' >&2; \
+	  exit 1; \
+	}; \
+	$(am__cd) '$(distuninstallcheck_dir)' || { \
+	  echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \
+	  exit 1; \
+	}; \
+	test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \
+	   || { echo "ERROR: files left after uninstall:" ; \
+	        if test -n "$(DESTDIR)"; then \
+	          echo "  (check DESTDIR support)"; \
+	        fi ; \
+	        $(distuninstallcheck_listfiles) ; \
+	        exit 1; } >&2
+distcleancheck: distclean
+	@if test '$(srcdir)' = . ; then \
+	  echo "ERROR: distcleancheck can only run from a VPATH build" ; \
+	  exit 1 ; \
+	fi
+	@test `$(distcleancheck_listfiles) | wc -l` -eq 0 \
+	  || { echo "ERROR: files left in build directory after distclean:" ; \
+	       $(distcleancheck_listfiles) ; \
+	       exit 1; } >&2
+check-am: all-am
+check: check-recursive
+all-am: Makefile $(HEADERS) zfs_config.h
+installdirs: installdirs-recursive
+installdirs-am:
+	for dir in "$(DESTDIR)$(extradir)" "$(DESTDIR)$(kerneldir)"; do \
+	  test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+	done
+install: install-recursive
+install-exec: install-exec-recursive
+install-data: install-data-recursive
+uninstall: uninstall-recursive
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-recursive
+install-strip:
+	if test -z '$(STRIP)'; then \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	      install; \
+	else \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+	fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+clean: clean-recursive
+
+clean-am: clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-recursive
+	-rm -f $(am__CONFIG_DISTCLEAN_FILES)
+	-rm -f Makefile
+distclean-am: clean-am distclean-generic distclean-hdr \
+	distclean-libtool distclean-local distclean-tags
+
+dvi: dvi-recursive
+
+dvi-am:
+
+html: html-recursive
+
+html-am:
+
+info: info-recursive
+
+info-am:
+
+install-data-am: install-extraHEADERS install-nodist_kernelHEADERS
+
+install-dvi: install-dvi-recursive
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-recursive
+
+install-html-am:
+
+install-info: install-info-recursive
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-recursive
+
+install-pdf-am:
+
+install-ps: install-ps-recursive
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-recursive
+	-rm -f $(am__CONFIG_DISTCLEAN_FILES)
+	-rm -rf $(top_srcdir)/autom4te.cache
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-recursive
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-recursive
+
+pdf-am:
+
+ps: ps-recursive
+
+ps-am:
+
+uninstall-am: uninstall-extraHEADERS uninstall-nodist_kernelHEADERS
+
+.MAKE: $(am__recursive_targets) all install-am install-strip
+
+.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \
+	am--refresh check check-am clean clean-cscope clean-generic \
+	clean-libtool cscope cscopelist-am ctags ctags-am dist \
+	dist-all dist-bzip2 dist-gzip dist-hook dist-lzip dist-shar \
+	dist-tarZ dist-xz dist-zip distcheck distclean \
+	distclean-generic distclean-hdr distclean-libtool \
+	distclean-local distclean-tags distcleancheck distdir \
+	distuninstallcheck dvi dvi-am html html-am info info-am \
+	install install-am install-data install-data-am install-dvi \
+	install-dvi-am install-exec install-exec-am \
+	install-extraHEADERS install-html install-html-am install-info \
+	install-info-am install-man install-nodist_kernelHEADERS \
+	install-pdf install-pdf-am install-ps install-ps-am \
+	install-strip installcheck installcheck-am installdirs \
+	installdirs-am maintainer-clean maintainer-clean-generic \
+	mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \
+	ps ps-am tags tags-am uninstall uninstall-am \
+	uninstall-extraHEADERS uninstall-nodist_kernelHEADERS
+
+.PRECIOUS: Makefile
+
+
+srpm-kmod:
+	$(MAKE) $(AM_MAKEFLAGS) pkg="${PACKAGE}-kmod" \
+		def='${SRPM_DEFINE_COMMON} ${SRPM_DEFINE_KMOD}' srpm-common
+
+srpm-dkms:
+	$(MAKE) $(AM_MAKEFLAGS) pkg="${PACKAGE}-dkms" \
+		def='${SRPM_DEFINE_COMMON} ${SRPM_DEFINE_DKMS}' srpm-common
+
+srpm-utils:
+	$(MAKE) $(AM_MAKEFLAGS) pkg="${PACKAGE}" \
+		def='${SRPM_DEFINE_COMMON} ${SRPM_DEFINE_UTIL}' srpm-common
+
+srpm: srpm-kmod srpm-dkms srpm-utils
+srpms: srpm-kmod srpm-dkms srpm-utils
+
+rpm-kmod: srpm-kmod
+	$(MAKE) $(AM_MAKEFLAGS) pkg="${PACKAGE}-kmod" \
+		def='${RPM_DEFINE_COMMON} ${RPM_DEFINE_KMOD}' rpm-common
+
+rpm-dkms: srpm-dkms
+	$(MAKE) $(AM_MAKEFLAGS) pkg="${PACKAGE}-dkms" \
+		def='${RPM_DEFINE_COMMON} ${RPM_DEFINE_DKMS}' rpm-common
+
+rpm-utils: srpm-utils
+	$(MAKE) $(AM_MAKEFLAGS) pkg="${PACKAGE}" \
+		def='${RPM_DEFINE_COMMON} ${RPM_DEFINE_UTIL}' rpm-common
+
+rpm: rpm-kmod rpm-dkms rpm-utils
+rpms: rpm-kmod rpm-dkms rpm-utils
+
+rpm-local:
+	@(if test "${HAVE_RPMBUILD}" = "no"; then \
+		echo -e "\n" \
+	"*** Required util ${RPMBUILD} missing.  Please install the\n" \
+	"*** package for your distribution which provides ${RPMBUILD},\n" \
+	"*** re-run configure, and try again.\n"; \
+		exit 1; \
+	fi; \
+	mkdir -p $(rpmbuild)/TMP && \
+	mkdir -p $(rpmbuild)/BUILD && \
+	mkdir -p $(rpmbuild)/RPMS && \
+	mkdir -p $(rpmbuild)/SRPMS && \
+	mkdir -p $(rpmbuild)/SPECS && \
+	cp ${RPM_SPEC_DIR}/$(rpmspec) $(rpmbuild)/SPECS && \
+	mkdir -p $(rpmbuild)/SOURCES && \
+	cp $(top_srcdir)/scripts/kmodtool $(rpmbuild)/SOURCES && \
+	cp $(distdir).tar.gz $(rpmbuild)/SOURCES)
+
+srpm-common: dist
+	@(dist=`$(RPM) --eval %{?dist}`; \
+	rpmpkg=$(pkg)-$(VERSION)-$(RELEASE)$$dist*src.rpm; \
+	rpmspec=$(pkg).spec; \
+	rpmbuild=`mktemp -t -d $(PACKAGE)-build-$$USER-XXXXXXXX`; \
+	$(MAKE) $(AM_MAKEFLAGS) \
+		rpmbuild="$$rpmbuild" \
+		rpmspec="$$rpmspec" \
+		rpm-local || exit 1; \
+	LANG=C $(RPMBUILD) \
+		--define "_tmppath $$rpmbuild/TMP" \
+		--define "_topdir $$rpmbuild" \
+		$(def) -bs $$rpmbuild/SPECS/$$rpmspec || exit 1; \
+	cp $$rpmbuild/SRPMS/$$rpmpkg . || exit 1; \
+	rm -R $$rpmbuild)
+
+rpm-common: 
+	@(dist=`$(RPM) --eval %{?dist}`; \
+	rpmpkg=$(pkg)-$(VERSION)-$(RELEASE)$$dist*src.rpm; \
+	rpmspec=$(pkg).spec; \
+	rpmbuild=`mktemp -t -d $(PACKAGE)-build-$$USER-XXXXXXXX`; \
+	$(MAKE) $(AM_MAKEFLAGS) \
+		rpmbuild="$$rpmbuild" \
+		rpmspec="$$rpmspec" \
+		rpm-local || exit 1; \
+	LANG=C ${RPMBUILD} \
+		--define "_tmppath $$rpmbuild/TMP" \
+		--define "_topdir $$rpmbuild" \
+		$(def) --rebuild $$rpmpkg || exit 1; \
+	cp $$rpmbuild/RPMS/*/* . || exit 1; \
+	rm -R $$rpmbuild)
+deb-local:
+	@(if test "${HAVE_DPKGBUILD}" = "no"; then \
+		echo -e "\n" \
+	"*** Required util ${DPKGBUILD} missing.  Please install the\n" \
+        "*** package for your distribution which provides ${DPKGBUILD},\n" \
+	"*** re-run configure, and try again.\n"; \
+                exit 1; \
+	fi; \
+	if test "${HAVE_ALIEN}" = "no"; then \
+		echo -e "\n" \
+	"*** Required util ${ALIEN} missing.  Please install the\n" \
+        "*** package for your distribution which provides ${ALIEN},\n" \
+	"*** re-run configure, and try again.\n"; \
+                exit 1; \
+	fi)
+
+deb-kmod: deb-local rpm-kmod
+@CONFIG_KERNEL_TRUE@	name=${PACKAGE}; \
+@CONFIG_KERNEL_TRUE@	version=${VERSION}-${RELEASE}; \
+@CONFIG_KERNEL_TRUE@	arch=`$(RPM) -qp $${name}-kmod-$${version}.src.rpm --qf %{arch} | tail -1`; \
+@CONFIG_KERNEL_TRUE@	pkg1=kmod-$${name}*$${version}.$${arch}.rpm; \
+@CONFIG_KERNEL_TRUE@	fakeroot $(ALIEN) --bump=0 --scripts --to-deb $$pkg1; \
+@CONFIG_KERNEL_TRUE@	$(RM) $$pkg1
+
+deb-utils: deb-local rpm-utils
+@CONFIG_USER_TRUE@	name=${PACKAGE}; \
+@CONFIG_USER_TRUE@	version=${VERSION}-${RELEASE}; \
+@CONFIG_USER_TRUE@	arch=`$(RPM) -qp $${name}-$${version}.src.rpm --qf %{arch} | tail -1`; \
+@CONFIG_USER_TRUE@	pkg1=$${name}-$${version}.$${arch}.rpm; \
+@CONFIG_USER_TRUE@	pkg2=libnvpair1-$${version}.$${arch}.rpm; \
+@CONFIG_USER_TRUE@	pkg3=libuutil1-$${version}.$${arch}.rpm; \
+@CONFIG_USER_TRUE@	pkg4=libzfs2-$${version}.$${arch}.rpm; \
+@CONFIG_USER_TRUE@	pkg5=libzpool2-$${version}.$${arch}.rpm; \
+@CONFIG_USER_TRUE@	pkg6=libzfs2-devel-$${version}.$${arch}.rpm; \
+@CONFIG_USER_TRUE@	pkg7=$${name}-test-$${version}.$${arch}.rpm; \
+@CONFIG_USER_TRUE@	pkg8=$${name}-dracut-$${version}.$${arch}.rpm; \
+@CONFIG_USER_TRUE@	pkg9=$${name}-initramfs-$${version}.$${arch}.rpm; \
+@CONFIG_USER_TRUE@	fakeroot $(ALIEN) --bump=0 --scripts --to-deb \
+@CONFIG_USER_TRUE@	    $$pkg1 $$pkg2 $$pkg3 $$pkg4 $$pkg5 $$pkg6 $$pkg7 \
+@CONFIG_USER_TRUE@	    $$pkg8 $$pkg9;
+@CONFIG_USER_TRUE@	$(RM) $$pkg1 $$pkg2 $$pkg3 $$pkg4 $$pkg5 $$pkg6 $$pkg7 \
+@CONFIG_USER_TRUE@	    $$pkg8 $$pkg9;
+
+deb: deb-kmod deb-utils
+tgz-local:
+	@(if test "${HAVE_ALIEN}" = "no"; then \
+		echo -e "\n" \
+	"*** Required util ${ALIEN} missing.  Please install the\n" \
+        "*** package for your distribution which provides ${ALIEN},\n" \
+	"*** re-run configure, and try again.\n"; \
+                exit 1; \
+	fi)
+
+tgz-kmod: tgz-local rpm-kmod
+@CONFIG_KERNEL_TRUE@	name=${PACKAGE}; \
+@CONFIG_KERNEL_TRUE@	version=${VERSION}-${RELEASE}; \
+@CONFIG_KERNEL_TRUE@	arch=`$(RPM) -qp $${name}-kmod-$${version}.src.rpm --qf %{arch} | tail -1`; \
+@CONFIG_KERNEL_TRUE@	pkg1=kmod-$${name}*$${version}.$${arch}.rpm; \
+@CONFIG_KERNEL_TRUE@	fakeroot $(ALIEN) --scripts --to-tgz $$pkg1; \
+@CONFIG_KERNEL_TRUE@	$(RM) $$pkg1
+
+tgz-utils: tgz-local rpm-utils
+@CONFIG_USER_TRUE@	name=${PACKAGE}; \
+@CONFIG_USER_TRUE@	version=${VERSION}-${RELEASE}; \
+@CONFIG_USER_TRUE@	arch=`$(RPM) -qp $${name}-$${version}.src.rpm --qf %{arch} | tail -1`; \
+@CONFIG_USER_TRUE@	pkg1=$${name}-$${version}.$${arch}.rpm; \
+@CONFIG_USER_TRUE@	pkg2=$${name}-devel-$${version}.$${arch}.rpm; \
+@CONFIG_USER_TRUE@	pkg3=$${name}-test-$${version}.$${arch}.rpm; \
+@CONFIG_USER_TRUE@	fakeroot $(ALIEN) --scripts --to-tgz $$pkg1 $$pkg2 $$pkg3; \
+@CONFIG_USER_TRUE@	$(RM) $$pkg1 $$pkg2 $$pkg3
+
+tgz: tgz-kmod tgz-utils
+
+distclean-local::
+	-$(RM) -R autom4te*.cache
+	-find . \( -name SCCS -o -name BitKeeper -o -name .svn -o -name CVS \
+		-o -name .pc -o -name .hg -o -name .git \) -prune -o \
+		\( -name '*.orig' -o -name '*.rej' -o -name '*~' \
+		-o -name '*.bak' -o -name '#*#' -o -name '.*.orig' \
+		-o -name '.*.rej' -o -name '.script-config' -o -size 0 \
+		-o -name '*%' -o -name '.*.cmd' -o -name 'core' \
+		-o -name 'Makefile' -o -name 'Module.symvers' \
+		-o -name '*.order' -o -name '*.markers' \) \
+		-type f -print | xargs $(RM)
+
+dist-hook:
+	sed -i 's/Release:[[:print:]]*/Release:      $(RELEASE)/' \
+		$(distdir)/META
+
+checkstyle: cstyle shellcheck
+
+cstyle:
+	@find ${top_srcdir} -name '*.[hc]' ! -name 'zfs_config.*' \
+		! -name '*.mod.c' -type f -exec scripts/cstyle.pl {} \+
+
+shellcheck:
+	@if type shellcheck > /dev/null 2>&1; then \
+		(find ${top_srcdir} -type f -name '*.sh.in' -o -type f \
+		 -name '*.sh'; find etc/init.d/zfs*.in -type f) | \
+		 grep -v 'zfs-script-config' | \
+		 while read file; do \
+			shellcheck --format gcc "$$file"; \
+		 done; \
+	 fi
+
+ctags:
+	$(RM) tags
+	find $(top_srcdir) -name .git -prune -o -name '*.[hc]' | xargs ctags
+
+etags:
+	$(RM) TAGS
+	find $(top_srcdir) -name .pc -prune -o -name '*.[hc]' | xargs etags -a
+
+tags: ctags etags
+
+pkg: @DEFAULT_PACKAGE@
+pkg-kmod: @DEFAULT_PACKAGE@-kmod
+pkg-utils: @DEFAULT_PACKAGE@-utils
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/OPENSOLARIS.LICENSE
@@ -0,0 +1,384 @@
+Unless otherwise noted, all files in this distribution are released
+under the Common Development and Distribution License (CDDL).
+Exceptions are noted within the associated source files.
+
+--------------------------------------------------------------------
+
+
+COMMON DEVELOPMENT AND DISTRIBUTION LICENSE Version 1.0
+
+1. Definitions.
+
+    1.1. "Contributor" means each individual or entity that creates
+         or contributes to the creation of Modifications.
+
+    1.2. "Contributor Version" means the combination of the Original
+         Software, prior Modifications used by a Contributor (if any),
+         and the Modifications made by that particular Contributor.
+
+    1.3. "Covered Software" means (a) the Original Software, or (b)
+         Modifications, or (c) the combination of files containing
+         Original Software with files containing Modifications, in
+         each case including portions thereof.
+
+    1.4. "Executable" means the Covered Software in any form other
+         than Source Code.
+
+    1.5. "Initial Developer" means the individual or entity that first
+         makes Original Software available under this License.
+
+    1.6. "Larger Work" means a work which combines Covered Software or
+         portions thereof with code not governed by the terms of this
+         License.
+
+    1.7. "License" means this document.
+
+    1.8. "Licensable" means having the right to grant, to the maximum
+         extent possible, whether at the time of the initial grant or
+         subsequently acquired, any and all of the rights conveyed
+         herein.
+
+    1.9. "Modifications" means the Source Code and Executable form of
+         any of the following:
+
+        A. Any file that results from an addition to, deletion from or
+           modification of the contents of a file containing Original
+           Software or previous Modifications;
+
+        B. Any new file that contains any part of the Original
+           Software or previous Modifications; or
+
+        C. Any new file that is contributed or otherwise made
+           available under the terms of this License.
+
+    1.10. "Original Software" means the Source Code and Executable
+          form of computer software code that is originally released
+          under this License.
+
+    1.11. "Patent Claims" means any patent claim(s), now owned or
+          hereafter acquired, including without limitation, method,
+          process, and apparatus claims, in any patent Licensable by
+          grantor.
+
+    1.12. "Source Code" means (a) the common form of computer software
+          code in which modifications are made and (b) associated
+          documentation included in or with such code.
+
+    1.13. "You" (or "Your") means an individual or a legal entity
+          exercising rights under, and complying with all of the terms
+          of, this License.  For legal entities, "You" includes any
+          entity which controls, is controlled by, or is under common
+          control with You.  For purposes of this definition,
+          "control" means (a) the power, direct or indirect, to cause
+          the direction or management of such entity, whether by
+          contract or otherwise, or (b) ownership of more than fifty
+          percent (50%) of the outstanding shares or beneficial
+          ownership of such entity.
+
+2. License Grants.
+
+    2.1. The Initial Developer Grant.
+
+    Conditioned upon Your compliance with Section 3.1 below and
+    subject to third party intellectual property claims, the Initial
+    Developer hereby grants You a world-wide, royalty-free,
+    non-exclusive license:
+
+        (a) under intellectual property rights (other than patent or
+            trademark) Licensable by Initial Developer, to use,
+            reproduce, modify, display, perform, sublicense and
+            distribute the Original Software (or portions thereof),
+            with or without Modifications, and/or as part of a Larger
+            Work; and
+
+        (b) under Patent Claims infringed by the making, using or
+            selling of Original Software, to make, have made, use,
+            practice, sell, and offer for sale, and/or otherwise
+            dispose of the Original Software (or portions thereof).
+
+        (c) The licenses granted in Sections 2.1(a) and (b) are
+            effective on the date Initial Developer first distributes
+            or otherwise makes the Original Software available to a
+            third party under the terms of this License.
+
+        (d) Notwithstanding Section 2.1(b) above, no patent license is
+            granted: (1) for code that You delete from the Original
+            Software, or (2) for infringements caused by: (i) the
+            modification of the Original Software, or (ii) the
+            combination of the Original Software with other software
+            or devices.
+
+    2.2. Contributor Grant.
+
+    Conditioned upon Your compliance with Section 3.1 below and
+    subject to third party intellectual property claims, each
+    Contributor hereby grants You a world-wide, royalty-free,
+    non-exclusive license:
+
+        (a) under intellectual property rights (other than patent or
+            trademark) Licensable by Contributor to use, reproduce,
+            modify, display, perform, sublicense and distribute the
+            Modifications created by such Contributor (or portions
+            thereof), either on an unmodified basis, with other
+            Modifications, as Covered Software and/or as part of a
+            Larger Work; and
+
+        (b) under Patent Claims infringed by the making, using, or
+            selling of Modifications made by that Contributor either
+            alone and/or in combination with its Contributor Version
+            (or portions of such combination), to make, use, sell,
+            offer for sale, have made, and/or otherwise dispose of:
+            (1) Modifications made by that Contributor (or portions
+            thereof); and (2) the combination of Modifications made by
+            that Contributor with its Contributor Version (or portions
+            of such combination).
+
+        (c) The licenses granted in Sections 2.2(a) and 2.2(b) are
+            effective on the date Contributor first distributes or
+            otherwise makes the Modifications available to a third
+            party.
+
+        (d) Notwithstanding Section 2.2(b) above, no patent license is
+            granted: (1) for any code that Contributor has deleted
+            from the Contributor Version; (2) for infringements caused
+            by: (i) third party modifications of Contributor Version,
+            or (ii) the combination of Modifications made by that
+            Contributor with other software (except as part of the
+            Contributor Version) or other devices; or (3) under Patent
+            Claims infringed by Covered Software in the absence of
+            Modifications made by that Contributor.
+
+3. Distribution Obligations.
+
+    3.1. Availability of Source Code.
+
+    Any Covered Software that You distribute or otherwise make
+    available in Executable form must also be made available in Source
+    Code form and that Source Code form must be distributed only under
+    the terms of this License.  You must include a copy of this
+    License with every copy of the Source Code form of the Covered
+    Software You distribute or otherwise make available.  You must
+    inform recipients of any such Covered Software in Executable form
+    as to how they can obtain such Covered Software in Source Code
+    form in a reasonable manner on or through a medium customarily
+    used for software exchange.
+
+    3.2. Modifications.
+
+    The Modifications that You create or to which You contribute are
+    governed by the terms of this License.  You represent that You
+    believe Your Modifications are Your original creation(s) and/or
+    You have sufficient rights to grant the rights conveyed by this
+    License.
+
+    3.3. Required Notices.
+
+    You must include a notice in each of Your Modifications that
+    identifies You as the Contributor of the Modification.  You may
+    not remove or alter any copyright, patent or trademark notices
+    contained within the Covered Software, or any notices of licensing
+    or any descriptive text giving attribution to any Contributor or
+    the Initial Developer.
+
+    3.4. Application of Additional Terms.
+
+    You may not offer or impose any terms on any Covered Software in
+    Source Code form that alters or restricts the applicable version
+    of this License or the recipients' rights hereunder.  You may
+    choose to offer, and to charge a fee for, warranty, support,
+    indemnity or liability obligations to one or more recipients of
+    Covered Software.  However, you may do so only on Your own behalf,
+    and not on behalf of the Initial Developer or any Contributor.
+    You must make it absolutely clear that any such warranty, support,
+    indemnity or liability obligation is offered by You alone, and You
+    hereby agree to indemnify the Initial Developer and every
+    Contributor for any liability incurred by the Initial Developer or
+    such Contributor as a result of warranty, support, indemnity or
+    liability terms You offer.
+
+    3.5. Distribution of Executable Versions.
+
+    You may distribute the Executable form of the Covered Software
+    under the terms of this License or under the terms of a license of
+    Your choice, which may contain terms different from this License,
+    provided that You are in compliance with the terms of this License
+    and that the license for the Executable form does not attempt to
+    limit or alter the recipient's rights in the Source Code form from
+    the rights set forth in this License.  If You distribute the
+    Covered Software in Executable form under a different license, You
+    must make it absolutely clear that any terms which differ from
+    this License are offered by You alone, not by the Initial
+    Developer or Contributor.  You hereby agree to indemnify the
+    Initial Developer and every Contributor for any liability incurred
+    by the Initial Developer or such Contributor as a result of any
+    such terms You offer.
+
+    3.6. Larger Works.
+
+    You may create a Larger Work by combining Covered Software with
+    other code not governed by the terms of this License and
+    distribute the Larger Work as a single product.  In such a case,
+    You must make sure the requirements of this License are fulfilled
+    for the Covered Software.
+
+4. Versions of the License.
+
+    4.1. New Versions.
+
+    Sun Microsystems, Inc. is the initial license steward and may
+    publish revised and/or new versions of this License from time to
+    time.  Each version will be given a distinguishing version number.
+    Except as provided in Section 4.3, no one other than the license
+    steward has the right to modify this License.
+
+    4.2. Effect of New Versions.
+
+    You may always continue to use, distribute or otherwise make the
+    Covered Software available under the terms of the version of the
+    License under which You originally received the Covered Software.
+    If the Initial Developer includes a notice in the Original
+    Software prohibiting it from being distributed or otherwise made
+    available under any subsequent version of the License, You must
+    distribute and make the Covered Software available under the terms
+    of the version of the License under which You originally received
+    the Covered Software.  Otherwise, You may also choose to use,
+    distribute or otherwise make the Covered Software available under
+    the terms of any subsequent version of the License published by
+    the license steward.
+
+    4.3. Modified Versions.
+
+    When You are an Initial Developer and You want to create a new
+    license for Your Original Software, You may create and use a
+    modified version of this License if You: (a) rename the license
+    and remove any references to the name of the license steward
+    (except to note that the license differs from this License); and
+    (b) otherwise make it clear that the license contains terms which
+    differ from this License.
+
+5. DISCLAIMER OF WARRANTY.
+
+    COVERED SOFTWARE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS"
+    BASIS, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED,
+    INCLUDING, WITHOUT LIMITATION, WARRANTIES THAT THE COVERED
+    SOFTWARE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR
+    PURPOSE OR NON-INFRINGING.  THE ENTIRE RISK AS TO THE QUALITY AND
+    PERFORMANCE OF THE COVERED SOFTWARE IS WITH YOU.  SHOULD ANY
+    COVERED SOFTWARE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT THE
+    INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY
+    NECESSARY SERVICING, REPAIR OR CORRECTION.  THIS DISCLAIMER OF
+    WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE.  NO USE OF
+    ANY COVERED SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS
+    DISCLAIMER.
+
+6. TERMINATION.
+
+    6.1. This License and the rights granted hereunder will terminate
+    automatically if You fail to comply with terms herein and fail to
+    cure such breach within 30 days of becoming aware of the breach.
+    Provisions which, by their nature, must remain in effect beyond
+    the termination of this License shall survive.
+
+    6.2. If You assert a patent infringement claim (excluding
+    declaratory judgment actions) against Initial Developer or a
+    Contributor (the Initial Developer or Contributor against whom You
+    assert such claim is referred to as "Participant") alleging that
+    the Participant Software (meaning the Contributor Version where
+    the Participant is a Contributor or the Original Software where
+    the Participant is the Initial Developer) directly or indirectly
+    infringes any patent, then any and all rights granted directly or
+    indirectly to You by such Participant, the Initial Developer (if
+    the Initial Developer is not the Participant) and all Contributors
+    under Sections 2.1 and/or 2.2 of this License shall, upon 60 days
+    notice from Participant terminate prospectively and automatically
+    at the expiration of such 60 day notice period, unless if within
+    such 60 day period You withdraw Your claim with respect to the
+    Participant Software against such Participant either unilaterally
+    or pursuant to a written agreement with Participant.
+
+    6.3. In the event of termination under Sections 6.1 or 6.2 above,
+    all end user licenses that have been validly granted by You or any
+    distributor hereunder prior to termination (excluding licenses
+    granted to You by any distributor) shall survive termination.
+
+7. LIMITATION OF LIABILITY.
+
+    UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT
+    (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL YOU, THE
+    INITIAL DEVELOPER, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF
+    COVERED SOFTWARE, OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE
+    LIABLE TO ANY PERSON FOR ANY INDIRECT, SPECIAL, INCIDENTAL, OR
+    CONSEQUENTIAL DAMAGES OF ANY CHARACTER INCLUDING, WITHOUT
+    LIMITATION, DAMAGES FOR LOST PROFITS, LOSS OF GOODWILL, WORK
+    STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER
+    COMMERCIAL DAMAGES OR LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN
+    INFORMED OF THE POSSIBILITY OF SUCH DAMAGES.  THIS LIMITATION OF
+    LIABILITY SHALL NOT APPLY TO LIABILITY FOR DEATH OR PERSONAL
+    INJURY RESULTING FROM SUCH PARTY'S NEGLIGENCE TO THE EXTENT
+    APPLICABLE LAW PROHIBITS SUCH LIMITATION.  SOME JURISDICTIONS DO
+    NOT ALLOW THE EXCLUSION OR LIMITATION OF INCIDENTAL OR
+    CONSEQUENTIAL DAMAGES, SO THIS EXCLUSION AND LIMITATION MAY NOT
+    APPLY TO YOU.
+
+8. U.S. GOVERNMENT END USERS.
+
+    The Covered Software is a "commercial item," as that term is
+    defined in 48 C.F.R. 2.101 (Oct. 1995), consisting of "commercial
+    computer software" (as that term is defined at 48
+    C.F.R. 252.227-7014(a)(1)) and "commercial computer software
+    documentation" as such terms are used in 48 C.F.R. 12.212
+    (Sept. 1995).  Consistent with 48 C.F.R. 12.212 and 48
+    C.F.R. 227.7202-1 through 227.7202-4 (June 1995), all
+    U.S. Government End Users acquire Covered Software with only those
+    rights set forth herein.  This U.S. Government Rights clause is in
+    lieu of, and supersedes, any other FAR, DFAR, or other clause or
+    provision that addresses Government rights in computer software
+    under this License.
+
+9. MISCELLANEOUS.
+
+    This License represents the complete agreement concerning subject
+    matter hereof.  If any provision of this License is held to be
+    unenforceable, such provision shall be reformed only to the extent
+    necessary to make it enforceable.  This License shall be governed
+    by the law of the jurisdiction specified in a notice contained
+    within the Original Software (except to the extent applicable law,
+    if any, provides otherwise), excluding such jurisdiction's
+    conflict-of-law provisions.  Any litigation relating to this
+    License shall be subject to the jurisdiction of the courts located
+    in the jurisdiction and venue specified in a notice contained
+    within the Original Software, with the losing party responsible
+    for costs, including, without limitation, court costs and
+    reasonable attorneys' fees and expenses.  The application of the
+    United Nations Convention on Contracts for the International Sale
+    of Goods is expressly excluded.  Any law or regulation which
+    provides that the language of a contract shall be construed
+    against the drafter shall not apply to this License.  You agree
+    that You alone are responsible for compliance with the United
+    States export administration regulations (and the export control
+    laws and regulation of any other countries) when You use,
+    distribute or otherwise make available any Covered Software.
+
+10. RESPONSIBILITY FOR CLAIMS.
+
+    As between Initial Developer and the Contributors, each party is
+    responsible for claims and damages arising, directly or
+    indirectly, out of its utilization of rights under this License
+    and You agree to work with Initial Developer and Contributors to
+    distribute such responsibility on an equitable basis.  Nothing
+    herein is intended or shall be deemed to constitute any admission
+    of liability.
+
+--------------------------------------------------------------------
+
+NOTICE PURSUANT TO SECTION 9 OF THE COMMON DEVELOPMENT AND
+DISTRIBUTION LICENSE (CDDL)
+
+For Covered Software in this distribution, this License shall
+be governed by the laws of the State of California (excluding
+conflict-of-law provisions).
+
+Any litigation relating to this License shall be subject to the
+jurisdiction of the Federal Courts of the Northern District of
+California and the state courts of the State of California, with
+venue lying in Santa Clara County, California.
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/README.markdown
@@ -0,0 +1,10 @@
+Native ZFS for Linux!
+
+ZFS is an advanced file system and volume manager which was originally
+developed for Solaris and is now maintained by the Illumos community.
+
+ZFS on Linux, which is also known as ZoL, is currently feature complete.  It
+includes fully functional and stable SPA, DMU, ZVOL, and ZPL layers.
+
+Full documentation for installing ZoL on your favorite Linux distribution can
+be found at: <http://zfsonlinux.org>
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/aclocal.m4
@@ -0,0 +1,1295 @@
+# generated automatically by aclocal 1.15 -*- Autoconf -*-
+
+# Copyright (C) 1996-2014 Free Software Foundation, Inc.
+
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])])
+m4_ifndef([AC_AUTOCONF_VERSION],
+  [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
+m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.69],,
+[m4_warning([this file was generated for autoconf 2.69.
+You have another version of autoconf.  It may work, but is not guaranteed to.
+If you have problems, you may need to regenerate the build system entirely.
+To do so, use the procedure documented by the package, typically 'autoreconf'.])])
+
+# Copyright (C) 2002-2014 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_AUTOMAKE_VERSION(VERSION)
+# ----------------------------
+# Automake X.Y traces this macro to ensure aclocal.m4 has been
+# generated from the m4 files accompanying Automake X.Y.
+# (This private macro should not be called outside this file.)
+AC_DEFUN([AM_AUTOMAKE_VERSION],
+[am__api_version='1.15'
+dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to
+dnl require some minimum version.  Point them to the right macro.
+m4_if([$1], [1.15], [],
+      [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl
+])
+
+# _AM_AUTOCONF_VERSION(VERSION)
+# -----------------------------
+# aclocal traces this macro to find the Autoconf version.
+# This is a private macro too.  Using m4_define simplifies
+# the logic in aclocal, which can simply ignore this definition.
+m4_define([_AM_AUTOCONF_VERSION], [])
+
+# AM_SET_CURRENT_AUTOMAKE_VERSION
+# -------------------------------
+# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced.
+# This function is AC_REQUIREd by AM_INIT_AUTOMAKE.
+AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
+[AM_AUTOMAKE_VERSION([1.15])dnl
+m4_ifndef([AC_AUTOCONF_VERSION],
+  [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
+_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
+
+# Figure out how to run the assembler.                      -*- Autoconf -*-
+
+# Copyright (C) 2001-2014 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_PROG_AS
+# ----------
+AC_DEFUN([AM_PROG_AS],
+[# By default we simply use the C compiler to build assembly code.
+AC_REQUIRE([AC_PROG_CC])
+test "${CCAS+set}" = set || CCAS=$CC
+test "${CCASFLAGS+set}" = set || CCASFLAGS=$CFLAGS
+AC_ARG_VAR([CCAS],      [assembler compiler command (defaults to CC)])
+AC_ARG_VAR([CCASFLAGS], [assembler compiler flags (defaults to CFLAGS)])
+_AM_IF_OPTION([no-dependencies],, [_AM_DEPENDENCIES([CCAS])])dnl
+])
+
+# AM_AUX_DIR_EXPAND                                         -*- Autoconf -*-
+
+# Copyright (C) 2001-2014 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets
+# $ac_aux_dir to '$srcdir/foo'.  In other projects, it is set to
+# '$srcdir', '$srcdir/..', or '$srcdir/../..'.
+#
+# Of course, Automake must honor this variable whenever it calls a
+# tool from the auxiliary directory.  The problem is that $srcdir (and
+# therefore $ac_aux_dir as well) can be either absolute or relative,
+# depending on how configure is run.  This is pretty annoying, since
+# it makes $ac_aux_dir quite unusable in subdirectories: in the top
+# source directory, any form will work fine, but in subdirectories a
+# relative path needs to be adjusted first.
+#
+# $ac_aux_dir/missing
+#    fails when called from a subdirectory if $ac_aux_dir is relative
+# $top_srcdir/$ac_aux_dir/missing
+#    fails if $ac_aux_dir is absolute,
+#    fails when called from a subdirectory in a VPATH build with
+#          a relative $ac_aux_dir
+#
+# The reason of the latter failure is that $top_srcdir and $ac_aux_dir
+# are both prefixed by $srcdir.  In an in-source build this is usually
+# harmless because $srcdir is '.', but things will broke when you
+# start a VPATH build or use an absolute $srcdir.
+#
+# So we could use something similar to $top_srcdir/$ac_aux_dir/missing,
+# iff we strip the leading $srcdir from $ac_aux_dir.  That would be:
+#   am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"`
+# and then we would define $MISSING as
+#   MISSING="\${SHELL} $am_aux_dir/missing"
+# This will work as long as MISSING is not called from configure, because
+# unfortunately $(top_srcdir) has no meaning in configure.
+# However there are other variables, like CC, which are often used in
+# configure, and could therefore not use this "fixed" $ac_aux_dir.
+#
+# Another solution, used here, is to always expand $ac_aux_dir to an
+# absolute PATH.  The drawback is that using absolute paths prevent a
+# configured tree to be moved without reconfiguration.
+
+AC_DEFUN([AM_AUX_DIR_EXPAND],
+[AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl
+# Expand $ac_aux_dir to an absolute path.
+am_aux_dir=`cd "$ac_aux_dir" && pwd`
+])
+
+# AM_CONDITIONAL                                            -*- Autoconf -*-
+
+# Copyright (C) 1997-2014 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_CONDITIONAL(NAME, SHELL-CONDITION)
+# -------------------------------------
+# Define a conditional.
+AC_DEFUN([AM_CONDITIONAL],
+[AC_PREREQ([2.52])dnl
+ m4_if([$1], [TRUE],  [AC_FATAL([$0: invalid condition: $1])],
+       [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl
+AC_SUBST([$1_TRUE])dnl
+AC_SUBST([$1_FALSE])dnl
+_AM_SUBST_NOTMAKE([$1_TRUE])dnl
+_AM_SUBST_NOTMAKE([$1_FALSE])dnl
+m4_define([_AM_COND_VALUE_$1], [$2])dnl
+if $2; then
+  $1_TRUE=
+  $1_FALSE='#'
+else
+  $1_TRUE='#'
+  $1_FALSE=
+fi
+AC_CONFIG_COMMANDS_PRE(
+[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then
+  AC_MSG_ERROR([[conditional "$1" was never defined.
+Usually this means the macro was only invoked conditionally.]])
+fi])])
+
+# Copyright (C) 1999-2014 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+
+# There are a few dirty hacks below to avoid letting 'AC_PROG_CC' be
+# written in clear, in which case automake, when reading aclocal.m4,
+# will think it sees a *use*, and therefore will trigger all it's
+# C support machinery.  Also note that it means that autoscan, seeing
+# CC etc. in the Makefile, will ask for an AC_PROG_CC use...
+
+
+# _AM_DEPENDENCIES(NAME)
+# ----------------------
+# See how the compiler implements dependency checking.
+# NAME is "CC", "CXX", "OBJC", "OBJCXX", "UPC", or "GJC".
+# We try a few techniques and use that to set a single cache variable.
+#
+# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was
+# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular
+# dependency, and given that the user is not expected to run this macro,
+# just rely on AC_PROG_CC.
+AC_DEFUN([_AM_DEPENDENCIES],
+[AC_REQUIRE([AM_SET_DEPDIR])dnl
+AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl
+AC_REQUIRE([AM_MAKE_INCLUDE])dnl
+AC_REQUIRE([AM_DEP_TRACK])dnl
+
+m4_if([$1], [CC],   [depcc="$CC"   am_compiler_list=],
+      [$1], [CXX],  [depcc="$CXX"  am_compiler_list=],
+      [$1], [OBJC], [depcc="$OBJC" am_compiler_list='gcc3 gcc'],
+      [$1], [OBJCXX], [depcc="$OBJCXX" am_compiler_list='gcc3 gcc'],
+      [$1], [UPC],  [depcc="$UPC"  am_compiler_list=],
+      [$1], [GCJ],  [depcc="$GCJ"  am_compiler_list='gcc3 gcc'],
+                    [depcc="$$1"   am_compiler_list=])
+
+AC_CACHE_CHECK([dependency style of $depcc],
+               [am_cv_$1_dependencies_compiler_type],
+[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
+  # We make a subdir and do the tests there.  Otherwise we can end up
+  # making bogus files that we don't know about and never remove.  For
+  # instance it was reported that on HP-UX the gcc test will end up
+  # making a dummy file named 'D' -- because '-MD' means "put the output
+  # in D".
+  rm -rf conftest.dir
+  mkdir conftest.dir
+  # Copy depcomp to subdir because otherwise we won't find it if we're
+  # using a relative directory.
+  cp "$am_depcomp" conftest.dir
+  cd conftest.dir
+  # We will build objects and dependencies in a subdirectory because
+  # it helps to detect inapplicable dependency modes.  For instance
+  # both Tru64's cc and ICC support -MD to output dependencies as a
+  # side effect of compilation, but ICC will put the dependencies in
+  # the current directory while Tru64 will put them in the object
+  # directory.
+  mkdir sub
+
+  am_cv_$1_dependencies_compiler_type=none
+  if test "$am_compiler_list" = ""; then
+     am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp`
+  fi
+  am__universal=false
+  m4_case([$1], [CC],
+    [case " $depcc " in #(
+     *\ -arch\ *\ -arch\ *) am__universal=true ;;
+     esac],
+    [CXX],
+    [case " $depcc " in #(
+     *\ -arch\ *\ -arch\ *) am__universal=true ;;
+     esac])
+
+  for depmode in $am_compiler_list; do
+    # Setup a source with many dependencies, because some compilers
+    # like to wrap large dependency lists on column 80 (with \), and
+    # we should not choose a depcomp mode which is confused by this.
+    #
+    # We need to recreate these files for each test, as the compiler may
+    # overwrite some of them when testing with obscure command lines.
+    # This happens at least with the AIX C compiler.
+    : > sub/conftest.c
+    for i in 1 2 3 4 5 6; do
+      echo '#include "conftst'$i'.h"' >> sub/conftest.c
+      # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with
+      # Solaris 10 /bin/sh.
+      echo '/* dummy */' > sub/conftst$i.h
+    done
+    echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
+
+    # We check with '-c' and '-o' for the sake of the "dashmstdout"
+    # mode.  It turns out that the SunPro C++ compiler does not properly
+    # handle '-M -o', and we need to detect this.  Also, some Intel
+    # versions had trouble with output in subdirs.
+    am__obj=sub/conftest.${OBJEXT-o}
+    am__minus_obj="-o $am__obj"
+    case $depmode in
+    gcc)
+      # This depmode causes a compiler race in universal mode.
+      test "$am__universal" = false || continue
+      ;;
+    nosideeffect)
+      # After this tag, mechanisms are not by side-effect, so they'll
+      # only be used when explicitly requested.
+      if test "x$enable_dependency_tracking" = xyes; then
+	continue
+      else
+	break
+      fi
+      ;;
+    msvc7 | msvc7msys | msvisualcpp | msvcmsys)
+      # This compiler won't grok '-c -o', but also, the minuso test has
+      # not run yet.  These depmodes are late enough in the game, and
+      # so weak that their functioning should not be impacted.
+      am__obj=conftest.${OBJEXT-o}
+      am__minus_obj=
+      ;;
+    none) break ;;
+    esac
+    if depmode=$depmode \
+       source=sub/conftest.c object=$am__obj \
+       depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
+       $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \
+         >/dev/null 2>conftest.err &&
+       grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 &&
+       grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
+       grep $am__obj sub/conftest.Po > /dev/null 2>&1 &&
+       ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
+      # icc doesn't choke on unknown options, it will just issue warnings
+      # or remarks (even with -Werror).  So we grep stderr for any message
+      # that says an option was ignored or not supported.
+      # When given -MP, icc 7.0 and 7.1 complain thusly:
+      #   icc: Command line warning: ignoring option '-M'; no argument required
+      # The diagnosis changed in icc 8.0:
+      #   icc: Command line remark: option '-MP' not supported
+      if (grep 'ignoring option' conftest.err ||
+          grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
+        am_cv_$1_dependencies_compiler_type=$depmode
+        break
+      fi
+    fi
+  done
+
+  cd ..
+  rm -rf conftest.dir
+else
+  am_cv_$1_dependencies_compiler_type=none
+fi
+])
+AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type])
+AM_CONDITIONAL([am__fastdep$1], [
+  test "x$enable_dependency_tracking" != xno \
+  && test "$am_cv_$1_dependencies_compiler_type" = gcc3])
+])
+
+
+# AM_SET_DEPDIR
+# -------------
+# Choose a directory name for dependency files.
+# This macro is AC_REQUIREd in _AM_DEPENDENCIES.
+AC_DEFUN([AM_SET_DEPDIR],
+[AC_REQUIRE([AM_SET_LEADING_DOT])dnl
+AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl
+])
+
+
+# AM_DEP_TRACK
+# ------------
+AC_DEFUN([AM_DEP_TRACK],
+[AC_ARG_ENABLE([dependency-tracking], [dnl
+AS_HELP_STRING(
+  [--enable-dependency-tracking],
+  [do not reject slow dependency extractors])
+AS_HELP_STRING(
+  [--disable-dependency-tracking],
+  [speeds up one-time build])])
+if test "x$enable_dependency_tracking" != xno; then
+  am_depcomp="$ac_aux_dir/depcomp"
+  AMDEPBACKSLASH='\'
+  am__nodep='_no'
+fi
+AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno])
+AC_SUBST([AMDEPBACKSLASH])dnl
+_AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl
+AC_SUBST([am__nodep])dnl
+_AM_SUBST_NOTMAKE([am__nodep])dnl
+])
+
+# Generate code to set up dependency tracking.              -*- Autoconf -*-
+
+# Copyright (C) 1999-2014 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+
+# _AM_OUTPUT_DEPENDENCY_COMMANDS
+# ------------------------------
+AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
+[{
+  # Older Autoconf quotes --file arguments for eval, but not when files
+  # are listed without --file.  Let's play safe and only enable the eval
+  # if we detect the quoting.
+  case $CONFIG_FILES in
+  *\'*) eval set x "$CONFIG_FILES" ;;
+  *)   set x $CONFIG_FILES ;;
+  esac
+  shift
+  for mf
+  do
+    # Strip MF so we end up with the name of the file.
+    mf=`echo "$mf" | sed -e 's/:.*$//'`
+    # Check whether this is an Automake generated Makefile or not.
+    # We used to match only the files named 'Makefile.in', but
+    # some people rename them; so instead we look at the file content.
+    # Grep'ing the first line is not enough: some people post-process
+    # each Makefile.in and add a new line on top of each file to say so.
+    # Grep'ing the whole file is not good either: AIX grep has a line
+    # limit of 2048, but all sed's we know have understand at least 4000.
+    if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then
+      dirpart=`AS_DIRNAME("$mf")`
+    else
+      continue
+    fi
+    # Extract the definition of DEPDIR, am__include, and am__quote
+    # from the Makefile without running 'make'.
+    DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"`
+    test -z "$DEPDIR" && continue
+    am__include=`sed -n 's/^am__include = //p' < "$mf"`
+    test -z "$am__include" && continue
+    am__quote=`sed -n 's/^am__quote = //p' < "$mf"`
+    # Find all dependency output files, they are included files with
+    # $(DEPDIR) in their names.  We invoke sed twice because it is the
+    # simplest approach to changing $(DEPDIR) to its actual value in the
+    # expansion.
+    for file in `sed -n "
+      s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \
+	 sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do
+      # Make sure the directory exists.
+      test -f "$dirpart/$file" && continue
+      fdir=`AS_DIRNAME(["$file"])`
+      AS_MKDIR_P([$dirpart/$fdir])
+      # echo "creating $dirpart/$file"
+      echo '# dummy' > "$dirpart/$file"
+    done
+  done
+}
+])# _AM_OUTPUT_DEPENDENCY_COMMANDS
+
+
+# AM_OUTPUT_DEPENDENCY_COMMANDS
+# -----------------------------
+# This macro should only be invoked once -- use via AC_REQUIRE.
+#
+# This code is only required when automatic dependency tracking
+# is enabled.  FIXME.  This creates each '.P' file that we will
+# need in order to bootstrap the dependency handling code.
+AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],
+[AC_CONFIG_COMMANDS([depfiles],
+     [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS],
+     [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"])
+])
+
+# Do all the work for Automake.                             -*- Autoconf -*-
+
+# Copyright (C) 1996-2014 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This macro actually does too much.  Some checks are only needed if
+# your package does certain things.  But this isn't really a big deal.
+
+dnl Redefine AC_PROG_CC to automatically invoke _AM_PROG_CC_C_O.
+m4_define([AC_PROG_CC],
+m4_defn([AC_PROG_CC])
+[_AM_PROG_CC_C_O
+])
+
+# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE])
+# AM_INIT_AUTOMAKE([OPTIONS])
+# -----------------------------------------------
+# The call with PACKAGE and VERSION arguments is the old style
+# call (pre autoconf-2.50), which is being phased out.  PACKAGE
+# and VERSION should now be passed to AC_INIT and removed from
+# the call to AM_INIT_AUTOMAKE.
+# We support both call styles for the transition.  After
+# the next Automake release, Autoconf can make the AC_INIT
+# arguments mandatory, and then we can depend on a new Autoconf
+# release and drop the old call support.
+AC_DEFUN([AM_INIT_AUTOMAKE],
+[AC_PREREQ([2.65])dnl
+dnl Autoconf wants to disallow AM_ names.  We explicitly allow
+dnl the ones we care about.
+m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl
+AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl
+AC_REQUIRE([AC_PROG_INSTALL])dnl
+if test "`cd $srcdir && pwd`" != "`pwd`"; then
+  # Use -I$(srcdir) only when $(srcdir) != ., so that make's output
+  # is not polluted with repeated "-I."
+  AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl
+  # test to see if srcdir already configured
+  if test -f $srcdir/config.status; then
+    AC_MSG_ERROR([source directory already configured; run "make distclean" there first])
+  fi
+fi
+
+# test whether we have cygpath
+if test -z "$CYGPATH_W"; then
+  if (cygpath --version) >/dev/null 2>/dev/null; then
+    CYGPATH_W='cygpath -w'
+  else
+    CYGPATH_W=echo
+  fi
+fi
+AC_SUBST([CYGPATH_W])
+
+# Define the identity of the package.
+dnl Distinguish between old-style and new-style calls.
+m4_ifval([$2],
+[AC_DIAGNOSE([obsolete],
+             [$0: two- and three-arguments forms are deprecated.])
+m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl
+ AC_SUBST([PACKAGE], [$1])dnl
+ AC_SUBST([VERSION], [$2])],
+[_AM_SET_OPTIONS([$1])dnl
+dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT.
+m4_if(
+  m4_ifdef([AC_PACKAGE_NAME], [ok]):m4_ifdef([AC_PACKAGE_VERSION], [ok]),
+  [ok:ok],,
+  [m4_fatal([AC_INIT should be called with package and version arguments])])dnl
+ AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl
+ AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl
+
+_AM_IF_OPTION([no-define],,
+[AC_DEFINE_UNQUOTED([PACKAGE], ["$PACKAGE"], [Name of package])
+ AC_DEFINE_UNQUOTED([VERSION], ["$VERSION"], [Version number of package])])dnl
+
+# Some tools Automake needs.
+AC_REQUIRE([AM_SANITY_CHECK])dnl
+AC_REQUIRE([AC_ARG_PROGRAM])dnl
+AM_MISSING_PROG([ACLOCAL], [aclocal-${am__api_version}])
+AM_MISSING_PROG([AUTOCONF], [autoconf])
+AM_MISSING_PROG([AUTOMAKE], [automake-${am__api_version}])
+AM_MISSING_PROG([AUTOHEADER], [autoheader])
+AM_MISSING_PROG([MAKEINFO], [makeinfo])
+AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
+AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl
+AC_REQUIRE([AC_PROG_MKDIR_P])dnl
+# For better backward compatibility.  To be removed once Automake 1.9.x
+# dies out for good.  For more background, see:
+# <http://lists.gnu.org/archive/html/automake/2012-07/msg00001.html>
+# <http://lists.gnu.org/archive/html/automake/2012-07/msg00014.html>
+AC_SUBST([mkdir_p], ['$(MKDIR_P)'])
+# We need awk for the "check" target (and possibly the TAP driver).  The
+# system "awk" is bad on some platforms.
+AC_REQUIRE([AC_PROG_AWK])dnl
+AC_REQUIRE([AC_PROG_MAKE_SET])dnl
+AC_REQUIRE([AM_SET_LEADING_DOT])dnl
+_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])],
+	      [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])],
+			     [_AM_PROG_TAR([v7])])])
+_AM_IF_OPTION([no-dependencies],,
+[AC_PROVIDE_IFELSE([AC_PROG_CC],
+		  [_AM_DEPENDENCIES([CC])],
+		  [m4_define([AC_PROG_CC],
+			     m4_defn([AC_PROG_CC])[_AM_DEPENDENCIES([CC])])])dnl
+AC_PROVIDE_IFELSE([AC_PROG_CXX],
+		  [_AM_DEPENDENCIES([CXX])],
+		  [m4_define([AC_PROG_CXX],
+			     m4_defn([AC_PROG_CXX])[_AM_DEPENDENCIES([CXX])])])dnl
+AC_PROVIDE_IFELSE([AC_PROG_OBJC],
+		  [_AM_DEPENDENCIES([OBJC])],
+		  [m4_define([AC_PROG_OBJC],
+			     m4_defn([AC_PROG_OBJC])[_AM_DEPENDENCIES([OBJC])])])dnl
+AC_PROVIDE_IFELSE([AC_PROG_OBJCXX],
+		  [_AM_DEPENDENCIES([OBJCXX])],
+		  [m4_define([AC_PROG_OBJCXX],
+			     m4_defn([AC_PROG_OBJCXX])[_AM_DEPENDENCIES([OBJCXX])])])dnl
+])
+AC_REQUIRE([AM_SILENT_RULES])dnl
+dnl The testsuite driver may need to know about EXEEXT, so add the
+dnl 'am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen.  This
+dnl macro is hooked onto _AC_COMPILER_EXEEXT early, see below.
+AC_CONFIG_COMMANDS_PRE(dnl
+[m4_provide_if([_AM_COMPILER_EXEEXT],
+  [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl
+
+# POSIX will say in a future version that running "rm -f" with no argument
+# is OK; and we want to be able to make that assumption in our Makefile
+# recipes.  So use an aggressive probe to check that the usage we want is
+# actually supported "in the wild" to an acceptable degree.
+# See automake bug#10828.
+# To make any issue more visible, cause the running configure to be aborted
+# by default if the 'rm' program in use doesn't match our expectations; the
+# user can still override this though.
+if rm -f && rm -fr && rm -rf; then : OK; else
+  cat >&2 <<'END'
+Oops!
+
+Your 'rm' program seems unable to run without file operands specified
+on the command line, even when the '-f' option is present.  This is contrary
+to the behaviour of most rm programs out there, and not conforming with
+the upcoming POSIX standard: <http://austingroupbugs.net/view.php?id=542>
+
+Please tell bug-automake@gnu.org about your system, including the value
+of your $PATH and any error possibly output before this message.  This
+can help us improve future automake versions.
+
+END
+  if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then
+    echo 'Configuration will proceed anyway, since you have set the' >&2
+    echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2
+    echo >&2
+  else
+    cat >&2 <<'END'
+Aborting the configuration process, to ensure you take notice of the issue.
+
+You can download and install GNU coreutils to get an 'rm' implementation
+that behaves properly: <http://www.gnu.org/software/coreutils/>.
+
+If you want to complete the configuration process using your problematic
+'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM
+to "yes", and re-run configure.
+
+END
+    AC_MSG_ERROR([Your 'rm' program is bad, sorry.])
+  fi
+fi
+dnl The trailing newline in this macro's definition is deliberate, for
+dnl backward compatibility and to allow trailing 'dnl'-style comments
+dnl after the AM_INIT_AUTOMAKE invocation. See automake bug#16841.
+])
+
+dnl Hook into '_AC_COMPILER_EXEEXT' early to learn its expansion.  Do not
+dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further
+dnl mangled by Autoconf and run in a shell conditional statement.
+m4_define([_AC_COMPILER_EXEEXT],
+m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])])
+
+# When config.status generates a header, we must update the stamp-h file.
+# This file resides in the same directory as the config header
+# that is generated.  The stamp files are numbered to have different names.
+
+# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the
+# loop where config.status creates the headers, so we can generate
+# our stamp files there.
+AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK],
+[# Compute $1's index in $config_headers.
+_am_arg=$1
+_am_stamp_count=1
+for _am_header in $config_headers :; do
+  case $_am_header in
+    $_am_arg | $_am_arg:* )
+      break ;;
+    * )
+      _am_stamp_count=`expr $_am_stamp_count + 1` ;;
+  esac
+done
+echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count])
+
+# Copyright (C) 2001-2014 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_PROG_INSTALL_SH
+# ------------------
+# Define $install_sh.
+AC_DEFUN([AM_PROG_INSTALL_SH],
+[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+if test x"${install_sh+set}" != xset; then
+  case $am_aux_dir in
+  *\ * | *\	*)
+    install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;;
+  *)
+    install_sh="\${SHELL} $am_aux_dir/install-sh"
+  esac
+fi
+AC_SUBST([install_sh])])
+
+# Copyright (C) 2003-2014 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# Check whether the underlying file-system supports filenames
+# with a leading dot.  For instance MS-DOS doesn't.
+AC_DEFUN([AM_SET_LEADING_DOT],
+[rm -rf .tst 2>/dev/null
+mkdir .tst 2>/dev/null
+if test -d .tst; then
+  am__leading_dot=.
+else
+  am__leading_dot=_
+fi
+rmdir .tst 2>/dev/null
+AC_SUBST([am__leading_dot])])
+
+# Add --enable-maintainer-mode option to configure.         -*- Autoconf -*-
+# From Jim Meyering
+
+# Copyright (C) 1996-2014 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_MAINTAINER_MODE([DEFAULT-MODE])
+# ----------------------------------
+# Control maintainer-specific portions of Makefiles.
+# Default is to disable them, unless 'enable' is passed literally.
+# For symmetry, 'disable' may be passed as well.  Anyway, the user
+# can override the default with the --enable/--disable switch.
+AC_DEFUN([AM_MAINTAINER_MODE],
+[m4_case(m4_default([$1], [disable]),
+       [enable], [m4_define([am_maintainer_other], [disable])],
+       [disable], [m4_define([am_maintainer_other], [enable])],
+       [m4_define([am_maintainer_other], [enable])
+        m4_warn([syntax], [unexpected argument to AM@&t@_MAINTAINER_MODE: $1])])
+AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles])
+  dnl maintainer-mode's default is 'disable' unless 'enable' is passed
+  AC_ARG_ENABLE([maintainer-mode],
+    [AS_HELP_STRING([--]am_maintainer_other[-maintainer-mode],
+      am_maintainer_other[ make rules and dependencies not useful
+      (and sometimes confusing) to the casual installer])],
+    [USE_MAINTAINER_MODE=$enableval],
+    [USE_MAINTAINER_MODE=]m4_if(am_maintainer_other, [enable], [no], [yes]))
+  AC_MSG_RESULT([$USE_MAINTAINER_MODE])
+  AM_CONDITIONAL([MAINTAINER_MODE], [test $USE_MAINTAINER_MODE = yes])
+  MAINT=$MAINTAINER_MODE_TRUE
+  AC_SUBST([MAINT])dnl
+]
+)
+
+# Check to see how 'make' treats includes.	            -*- Autoconf -*-
+
+# Copyright (C) 2001-2014 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_MAKE_INCLUDE()
+# -----------------
+# Check to see how make treats includes.
+AC_DEFUN([AM_MAKE_INCLUDE],
+[am_make=${MAKE-make}
+cat > confinc << 'END'
+am__doit:
+	@echo this is the am__doit target
+.PHONY: am__doit
+END
+# If we don't find an include directive, just comment out the code.
+AC_MSG_CHECKING([for style of include used by $am_make])
+am__include="#"
+am__quote=
+_am_result=none
+# First try GNU make style include.
+echo "include confinc" > confmf
+# Ignore all kinds of additional output from 'make'.
+case `$am_make -s -f confmf 2> /dev/null` in #(
+*the\ am__doit\ target*)
+  am__include=include
+  am__quote=
+  _am_result=GNU
+  ;;
+esac
+# Now try BSD make style include.
+if test "$am__include" = "#"; then
+   echo '.include "confinc"' > confmf
+   case `$am_make -s -f confmf 2> /dev/null` in #(
+   *the\ am__doit\ target*)
+     am__include=.include
+     am__quote="\""
+     _am_result=BSD
+     ;;
+   esac
+fi
+AC_SUBST([am__include])
+AC_SUBST([am__quote])
+AC_MSG_RESULT([$_am_result])
+rm -f confinc confmf
+])
+
+# Fake the existence of programs that GNU maintainers use.  -*- Autoconf -*-
+
+# Copyright (C) 1997-2014 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_MISSING_PROG(NAME, PROGRAM)
+# ------------------------------
+AC_DEFUN([AM_MISSING_PROG],
+[AC_REQUIRE([AM_MISSING_HAS_RUN])
+$1=${$1-"${am_missing_run}$2"}
+AC_SUBST($1)])
+
+# AM_MISSING_HAS_RUN
+# ------------------
+# Define MISSING if not defined so far and test if it is modern enough.
+# If it is, set am_missing_run to use it, otherwise, to nothing.
+AC_DEFUN([AM_MISSING_HAS_RUN],
+[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+AC_REQUIRE_AUX_FILE([missing])dnl
+if test x"${MISSING+set}" != xset; then
+  case $am_aux_dir in
+  *\ * | *\	*)
+    MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;;
+  *)
+    MISSING="\${SHELL} $am_aux_dir/missing" ;;
+  esac
+fi
+# Use eval to expand $SHELL
+if eval "$MISSING --is-lightweight"; then
+  am_missing_run="$MISSING "
+else
+  am_missing_run=
+  AC_MSG_WARN(['missing' script is too old or missing])
+fi
+])
+
+# Helper functions for option handling.                     -*- Autoconf -*-
+
+# Copyright (C) 2001-2014 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# _AM_MANGLE_OPTION(NAME)
+# -----------------------
+AC_DEFUN([_AM_MANGLE_OPTION],
+[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])])
+
+# _AM_SET_OPTION(NAME)
+# --------------------
+# Set option NAME.  Presently that only means defining a flag for this option.
+AC_DEFUN([_AM_SET_OPTION],
+[m4_define(_AM_MANGLE_OPTION([$1]), [1])])
+
+# _AM_SET_OPTIONS(OPTIONS)
+# ------------------------
+# OPTIONS is a space-separated list of Automake options.
+AC_DEFUN([_AM_SET_OPTIONS],
+[m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])])
+
+# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET])
+# -------------------------------------------
+# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise.
+AC_DEFUN([_AM_IF_OPTION],
+[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])
+
+# Copyright (C) 1999-2014 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# _AM_PROG_CC_C_O
+# ---------------
+# Like AC_PROG_CC_C_O, but changed for automake.  We rewrite AC_PROG_CC
+# to automatically call this.
+AC_DEFUN([_AM_PROG_CC_C_O],
+[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+AC_REQUIRE_AUX_FILE([compile])dnl
+AC_LANG_PUSH([C])dnl
+AC_CACHE_CHECK(
+  [whether $CC understands -c and -o together],
+  [am_cv_prog_cc_c_o],
+  [AC_LANG_CONFTEST([AC_LANG_PROGRAM([])])
+  # Make sure it works both with $CC and with simple cc.
+  # Following AC_PROG_CC_C_O, we do the test twice because some
+  # compilers refuse to overwrite an existing .o file with -o,
+  # though they will create one.
+  am_cv_prog_cc_c_o=yes
+  for am_i in 1 2; do
+    if AM_RUN_LOG([$CC -c conftest.$ac_ext -o conftest2.$ac_objext]) \
+         && test -f conftest2.$ac_objext; then
+      : OK
+    else
+      am_cv_prog_cc_c_o=no
+      break
+    fi
+  done
+  rm -f core conftest*
+  unset am_i])
+if test "$am_cv_prog_cc_c_o" != yes; then
+   # Losing compiler, so override with the script.
+   # FIXME: It is wrong to rewrite CC.
+   # But if we don't then we get into trouble of one sort or another.
+   # A longer-term fix would be to have automake use am__CC in this case,
+   # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)"
+   CC="$am_aux_dir/compile $CC"
+fi
+AC_LANG_POP([C])])
+
+# For backward compatibility.
+AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])])
+
+# Copyright (C) 2001-2014 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_RUN_LOG(COMMAND)
+# -------------------
+# Run COMMAND, save the exit status in ac_status, and log it.
+# (This has been adapted from Autoconf's _AC_RUN_LOG macro.)
+AC_DEFUN([AM_RUN_LOG],
+[{ echo "$as_me:$LINENO: $1" >&AS_MESSAGE_LOG_FD
+   ($1) >&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD
+   ac_status=$?
+   echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD
+   (exit $ac_status); }])
+
+# Check to make sure that the build environment is sane.    -*- Autoconf -*-
+
+# Copyright (C) 1996-2014 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_SANITY_CHECK
+# ---------------
+AC_DEFUN([AM_SANITY_CHECK],
+[AC_MSG_CHECKING([whether build environment is sane])
+# Reject unsafe characters in $srcdir or the absolute working directory
+# name.  Accept space and tab only in the latter.
+am_lf='
+'
+case `pwd` in
+  *[[\\\"\#\$\&\'\`$am_lf]]*)
+    AC_MSG_ERROR([unsafe absolute working directory name]);;
+esac
+case $srcdir in
+  *[[\\\"\#\$\&\'\`$am_lf\ \	]]*)
+    AC_MSG_ERROR([unsafe srcdir value: '$srcdir']);;
+esac
+
+# Do 'set' in a subshell so we don't clobber the current shell's
+# arguments.  Must try -L first in case configure is actually a
+# symlink; some systems play weird games with the mod time of symlinks
+# (eg FreeBSD returns the mod time of the symlink's containing
+# directory).
+if (
+   am_has_slept=no
+   for am_try in 1 2; do
+     echo "timestamp, slept: $am_has_slept" > conftest.file
+     set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null`
+     if test "$[*]" = "X"; then
+	# -L didn't work.
+	set X `ls -t "$srcdir/configure" conftest.file`
+     fi
+     if test "$[*]" != "X $srcdir/configure conftest.file" \
+	&& test "$[*]" != "X conftest.file $srcdir/configure"; then
+
+	# If neither matched, then we have a broken ls.  This can happen
+	# if, for instance, CONFIG_SHELL is bash and it inherits a
+	# broken ls alias from the environment.  This has actually
+	# happened.  Such a system could not be considered "sane".
+	AC_MSG_ERROR([ls -t appears to fail.  Make sure there is not a broken
+  alias in your environment])
+     fi
+     if test "$[2]" = conftest.file || test $am_try -eq 2; then
+       break
+     fi
+     # Just in case.
+     sleep 1
+     am_has_slept=yes
+   done
+   test "$[2]" = conftest.file
+   )
+then
+   # Ok.
+   :
+else
+   AC_MSG_ERROR([newly created file is older than distributed files!
+Check your system clock])
+fi
+AC_MSG_RESULT([yes])
+# If we didn't sleep, we still need to ensure time stamps of config.status and
+# generated files are strictly newer.
+am_sleep_pid=
+if grep 'slept: no' conftest.file >/dev/null 2>&1; then
+  ( sleep 1 ) &
+  am_sleep_pid=$!
+fi
+AC_CONFIG_COMMANDS_PRE(
+  [AC_MSG_CHECKING([that generated files are newer than configure])
+   if test -n "$am_sleep_pid"; then
+     # Hide warnings about reused PIDs.
+     wait $am_sleep_pid 2>/dev/null
+   fi
+   AC_MSG_RESULT([done])])
+rm -f conftest.file
+])
+
+# Copyright (C) 2009-2014 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_SILENT_RULES([DEFAULT])
+# --------------------------
+# Enable less verbose build rules; with the default set to DEFAULT
+# ("yes" being less verbose, "no" or empty being verbose).
+AC_DEFUN([AM_SILENT_RULES],
+[AC_ARG_ENABLE([silent-rules], [dnl
+AS_HELP_STRING(
+  [--enable-silent-rules],
+  [less verbose build output (undo: "make V=1")])
+AS_HELP_STRING(
+  [--disable-silent-rules],
+  [verbose build output (undo: "make V=0")])dnl
+])
+case $enable_silent_rules in @%:@ (((
+  yes) AM_DEFAULT_VERBOSITY=0;;
+   no) AM_DEFAULT_VERBOSITY=1;;
+    *) AM_DEFAULT_VERBOSITY=m4_if([$1], [yes], [0], [1]);;
+esac
+dnl
+dnl A few 'make' implementations (e.g., NonStop OS and NextStep)
+dnl do not support nested variable expansions.
+dnl See automake bug#9928 and bug#10237.
+am_make=${MAKE-make}
+AC_CACHE_CHECK([whether $am_make supports nested variables],
+   [am_cv_make_support_nested_variables],
+   [if AS_ECHO([['TRUE=$(BAR$(V))
+BAR0=false
+BAR1=true
+V=1
+am__doit:
+	@$(TRUE)
+.PHONY: am__doit']]) | $am_make -f - >/dev/null 2>&1; then
+  am_cv_make_support_nested_variables=yes
+else
+  am_cv_make_support_nested_variables=no
+fi])
+if test $am_cv_make_support_nested_variables = yes; then
+  dnl Using '$V' instead of '$(V)' breaks IRIX make.
+  AM_V='$(V)'
+  AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)'
+else
+  AM_V=$AM_DEFAULT_VERBOSITY
+  AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY
+fi
+AC_SUBST([AM_V])dnl
+AM_SUBST_NOTMAKE([AM_V])dnl
+AC_SUBST([AM_DEFAULT_V])dnl
+AM_SUBST_NOTMAKE([AM_DEFAULT_V])dnl
+AC_SUBST([AM_DEFAULT_VERBOSITY])dnl
+AM_BACKSLASH='\'
+AC_SUBST([AM_BACKSLASH])dnl
+_AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl
+])
+
+# Copyright (C) 2001-2014 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_PROG_INSTALL_STRIP
+# ---------------------
+# One issue with vendor 'install' (even GNU) is that you can't
+# specify the program used to strip binaries.  This is especially
+# annoying in cross-compiling environments, where the build's strip
+# is unlikely to handle the host's binaries.
+# Fortunately install-sh will honor a STRIPPROG variable, so we
+# always use install-sh in "make install-strip", and initialize
+# STRIPPROG with the value of the STRIP variable (set by the user).
+AC_DEFUN([AM_PROG_INSTALL_STRIP],
+[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
+# Installed binaries are usually stripped using 'strip' when the user
+# run "make install-strip".  However 'strip' might not be the right
+# tool to use in cross-compilation environments, therefore Automake
+# will honor the 'STRIP' environment variable to overrule this program.
+dnl Don't test for $cross_compiling = yes, because it might be 'maybe'.
+if test "$cross_compiling" != no; then
+  AC_CHECK_TOOL([STRIP], [strip], :)
+fi
+INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
+AC_SUBST([INSTALL_STRIP_PROGRAM])])
+
+# Copyright (C) 2006-2014 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# _AM_SUBST_NOTMAKE(VARIABLE)
+# ---------------------------
+# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in.
+# This macro is traced by Automake.
+AC_DEFUN([_AM_SUBST_NOTMAKE])
+
+# AM_SUBST_NOTMAKE(VARIABLE)
+# --------------------------
+# Public sister of _AM_SUBST_NOTMAKE.
+AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)])
+
+# Check how to create a tarball.                            -*- Autoconf -*-
+
+# Copyright (C) 2004-2014 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# _AM_PROG_TAR(FORMAT)
+# --------------------
+# Check how to create a tarball in format FORMAT.
+# FORMAT should be one of 'v7', 'ustar', or 'pax'.
+#
+# Substitute a variable $(am__tar) that is a command
+# writing to stdout a FORMAT-tarball containing the directory
+# $tardir.
+#     tardir=directory && $(am__tar) > result.tar
+#
+# Substitute a variable $(am__untar) that extract such
+# a tarball read from stdin.
+#     $(am__untar) < result.tar
+#
+AC_DEFUN([_AM_PROG_TAR],
+[# Always define AMTAR for backward compatibility.  Yes, it's still used
+# in the wild :-(  We should find a proper way to deprecate it ...
+AC_SUBST([AMTAR], ['$${TAR-tar}'])
+
+# We'll loop over all known methods to create a tar archive until one works.
+_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none'
+
+m4_if([$1], [v7],
+  [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'],
+
+  [m4_case([$1],
+    [ustar],
+     [# The POSIX 1988 'ustar' format is defined with fixed-size fields.
+      # There is notably a 21 bits limit for the UID and the GID.  In fact,
+      # the 'pax' utility can hang on bigger UID/GID (see automake bug#8343
+      # and bug#13588).
+      am_max_uid=2097151 # 2^21 - 1
+      am_max_gid=$am_max_uid
+      # The $UID and $GID variables are not portable, so we need to resort
+      # to the POSIX-mandated id(1) utility.  Errors in the 'id' calls
+      # below are definitely unexpected, so allow the users to see them
+      # (that is, avoid stderr redirection).
+      am_uid=`id -u || echo unknown`
+      am_gid=`id -g || echo unknown`
+      AC_MSG_CHECKING([whether UID '$am_uid' is supported by ustar format])
+      if test $am_uid -le $am_max_uid; then
+         AC_MSG_RESULT([yes])
+      else
+         AC_MSG_RESULT([no])
+         _am_tools=none
+      fi
+      AC_MSG_CHECKING([whether GID '$am_gid' is supported by ustar format])
+      if test $am_gid -le $am_max_gid; then
+         AC_MSG_RESULT([yes])
+      else
+        AC_MSG_RESULT([no])
+        _am_tools=none
+      fi],
+
+  [pax],
+    [],
+
+  [m4_fatal([Unknown tar format])])
+
+  AC_MSG_CHECKING([how to create a $1 tar archive])
+
+  # Go ahead even if we have the value already cached.  We do so because we
+  # need to set the values for the 'am__tar' and 'am__untar' variables.
+  _am_tools=${am_cv_prog_tar_$1-$_am_tools}
+
+  for _am_tool in $_am_tools; do
+    case $_am_tool in
+    gnutar)
+      for _am_tar in tar gnutar gtar; do
+        AM_RUN_LOG([$_am_tar --version]) && break
+      done
+      am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"'
+      am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"'
+      am__untar="$_am_tar -xf -"
+      ;;
+    plaintar)
+      # Must skip GNU tar: if it does not support --format= it doesn't create
+      # ustar tarball either.
+      (tar --version) >/dev/null 2>&1 && continue
+      am__tar='tar chf - "$$tardir"'
+      am__tar_='tar chf - "$tardir"'
+      am__untar='tar xf -'
+      ;;
+    pax)
+      am__tar='pax -L -x $1 -w "$$tardir"'
+      am__tar_='pax -L -x $1 -w "$tardir"'
+      am__untar='pax -r'
+      ;;
+    cpio)
+      am__tar='find "$$tardir" -print | cpio -o -H $1 -L'
+      am__tar_='find "$tardir" -print | cpio -o -H $1 -L'
+      am__untar='cpio -i -H $1 -d'
+      ;;
+    none)
+      am__tar=false
+      am__tar_=false
+      am__untar=false
+      ;;
+    esac
+
+    # If the value was cached, stop now.  We just wanted to have am__tar
+    # and am__untar set.
+    test -n "${am_cv_prog_tar_$1}" && break
+
+    # tar/untar a dummy directory, and stop if the command works.
+    rm -rf conftest.dir
+    mkdir conftest.dir
+    echo GrepMe > conftest.dir/file
+    AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar])
+    rm -rf conftest.dir
+    if test -s conftest.tar; then
+      AM_RUN_LOG([$am__untar <conftest.tar])
+      AM_RUN_LOG([cat conftest.dir/file])
+      grep GrepMe conftest.dir/file >/dev/null 2>&1 && break
+    fi
+  done
+  rm -rf conftest.dir
+
+  AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool])
+  AC_MSG_RESULT([$am_cv_prog_tar_$1])])
+
+AC_SUBST([am__tar])
+AC_SUBST([am__untar])
+]) # _AM_PROG_TAR
+
+m4_include([config/always-no-bool-compare.m4])
+m4_include([config/always-no-unused-but-set-variable.m4])
+m4_include([config/dkms.m4])
+m4_include([config/kernel-acl.m4])
+m4_include([config/kernel-automount.m4])
+m4_include([config/kernel-bdev-block-device-operations.m4])
+m4_include([config/kernel-bdev-logical-size.m4])
+m4_include([config/kernel-bdev-physical-size.m4])
+m4_include([config/kernel-bdi-setup-and-register.m4])
+m4_include([config/kernel-bio-bvec-iter.m4])
+m4_include([config/kernel-bio-end-io-t-args.m4])
+m4_include([config/kernel-bio-failfast.m4])
+m4_include([config/kernel-bio-rw-barrier.m4])
+m4_include([config/kernel-bio-rw-discard.m4])
+m4_include([config/kernel-blk-queue-flush.m4])
+m4_include([config/kernel-blk-queue-max-hw-sectors.m4])
+m4_include([config/kernel-blk-queue-max-segments.m4])
+m4_include([config/kernel-blkdev-get-by-path.m4])
+m4_include([config/kernel-blkdev-get.m4])
+m4_include([config/kernel-block-device-operations-release-void.m4])
+m4_include([config/kernel-check-disk-size-change.m4])
+m4_include([config/kernel-clear-inode.m4])
+m4_include([config/kernel-commit-metadata.m4])
+m4_include([config/kernel-create-nameidata.m4])
+m4_include([config/kernel-current_bio_tail.m4])
+m4_include([config/kernel-d-make-root.m4])
+m4_include([config/kernel-d-obtain-alias.m4])
+m4_include([config/kernel-d-prune-aliases.m4])
+m4_include([config/kernel-declare-event-class.m4])
+m4_include([config/kernel-dentry-operations.m4])
+m4_include([config/kernel-dirty-inode.m4])
+m4_include([config/kernel-discard-granularity.m4])
+m4_include([config/kernel-elevator-change.m4])
+m4_include([config/kernel-encode-fh-inode.m4])
+m4_include([config/kernel-evict-inode.m4])
+m4_include([config/kernel-fallocate.m4])
+m4_include([config/kernel-file-inode.m4])
+m4_include([config/kernel-fmode-t.m4])
+m4_include([config/kernel-follow-down-one.m4])
+m4_include([config/kernel-fsync.m4])
+m4_include([config/kernel-generic_io_acct.m4])
+m4_include([config/kernel-get-disk-ro.m4])
+m4_include([config/kernel-get-gendisk.m4])
+m4_include([config/kernel-get-link.m4])
+m4_include([config/kernel-insert-inode-locked.m4])
+m4_include([config/kernel-invalidate-bdev-args.m4])
+m4_include([config/kernel-is_owner_or_cap.m4])
+m4_include([config/kernel-kmap-atomic-args.m4])
+m4_include([config/kernel-kobj-name-len.m4])
+m4_include([config/kernel-lookup-bdev.m4])
+m4_include([config/kernel-lookup-nameidata.m4])
+m4_include([config/kernel-lseek-execute.m4])
+m4_include([config/kernel-mk-request-fn.m4])
+m4_include([config/kernel-mkdir-umode-t.m4])
+m4_include([config/kernel-mount-nodev.m4])
+m4_include([config/kernel-open-bdev-exclusive.m4])
+m4_include([config/kernel-put-link.m4])
+m4_include([config/kernel-security-inode-init.m4])
+m4_include([config/kernel-set-nlink.m4])
+m4_include([config/kernel-sget-args.m4])
+m4_include([config/kernel-show-options.m4])
+m4_include([config/kernel-shrink.m4])
+m4_include([config/kernel-truncate-range.m4])
+m4_include([config/kernel-truncate-setsize.m4])
+m4_include([config/kernel-vfs-iterate.m4])
+m4_include([config/kernel-vfs-rw-iterate.m4])
+m4_include([config/kernel-xattr-handler.m4])
+m4_include([config/kernel.m4])
+m4_include([config/libtool.m4])
+m4_include([config/ltoptions.m4])
+m4_include([config/ltsugar.m4])
+m4_include([config/ltversion.m4])
+m4_include([config/lt~obsolete.m4])
+m4_include([config/mount-helper.m4])
+m4_include([config/user-arch.m4])
+m4_include([config/user-dracut.m4])
+m4_include([config/user-frame-larger-than.m4])
+m4_include([config/user-libblkid.m4])
+m4_include([config/user-libuuid.m4])
+m4_include([config/user-runstatedir.m4])
+m4_include([config/user-systemd.m4])
+m4_include([config/user-sysvinit.m4])
+m4_include([config/user-udev.m4])
+m4_include([config/user-zlib.m4])
+m4_include([config/user.m4])
+m4_include([config/zfs-build.m4])
+m4_include([config/zfs-meta.m4])
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/autogen.sh
@@ -0,0 +1,4 @@
+#!/bin/sh
+
+autoreconf -fiv
+rm -Rf autom4te.cache
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/cmd/Makefile.in
@@ -0,0 +1,2 @@
+%:
+	#
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/cmd/arc_summary/Makefile.in
@@ -0,0 +1,2 @@
+%:
+	#
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/cmd/arcstat/Makefile.in
@@ -0,0 +1,2 @@
+%:
+	#
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/cmd/dbufstat/Makefile.in
@@ -0,0 +1,2 @@
+%:
+	#
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/cmd/fsck_zfs/Makefile.in
@@ -0,0 +1,2 @@
+%:
+	#
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/cmd/mount_zfs/Makefile.in
@@ -0,0 +1,2 @@
+%:
+	#
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/cmd/vdev_id/Makefile.in
@@ -0,0 +1,2 @@
+%:
+	#
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/cmd/zdb/Makefile.in
@@ -0,0 +1,2 @@
+%:
+	#
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/cmd/zed/Makefile.in
@@ -0,0 +1,2 @@
+%:
+	#
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/cmd/zfs/Makefile.in
@@ -0,0 +1,2 @@
+%:
+	#
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/cmd/zhack/Makefile.in
@@ -0,0 +1,2 @@
+%:
+	#
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/cmd/zinject/Makefile.in
@@ -0,0 +1,2 @@
+%:
+	#
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/cmd/zpios/Makefile.in
@@ -0,0 +1,2 @@
+%:
+	#
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/cmd/zpool/Makefile.in
@@ -0,0 +1,2 @@
+%:
+	#
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/cmd/zstreamdump/Makefile.in
@@ -0,0 +1,2 @@
+%:
+	#
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/cmd/ztest/Makefile.in
@@ -0,0 +1,2 @@
+%:
+	#
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/cmd/zvol_id/Makefile.in
@@ -0,0 +1,2 @@
+%:
+	#
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/config/Rules.am
@@ -0,0 +1,14 @@
+DEFAULT_INCLUDES = -include ${top_builddir}/zfs_config.h
+
+AM_LIBTOOLFLAGS = --silent
+AM_CFLAGS  = ${DEBUG_CFLAGS} -Wall -Wstrict-prototypes
+AM_CFLAGS += ${NO_UNUSED_BUT_SET_VARIABLE}
+AM_CFLAGS += ${NO_BOOL_COMPARE}
+AM_CFLAGS += -fno-strict-aliasing
+AM_CPPFLAGS  = -D_GNU_SOURCE -D__EXTENSIONS__ -D_REENTRANT
+AM_CPPFLAGS += -D_POSIX_PTHREAD_SEMANTICS -D_FILE_OFFSET_BITS=64
+AM_CPPFLAGS += -D_LARGEFILE64_SOURCE -DTEXT_DOMAIN=\"zfs-linux-user\"
+AM_CPPFLAGS += -DLIBEXECDIR=\"$(libexecdir)\"
+AM_CPPFLAGS += -DRUNSTATEDIR=\"$(runstatedir)\"
+AM_CPPFLAGS += -DSBINDIR=\"$(sbindir)\"
+AM_CPPFLAGS += -DSYSCONFDIR=\"$(sysconfdir)\"
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/config/always-no-bool-compare.m4
@@ -0,0 +1,27 @@
+dnl #
+dnl # Check if gcc supports -Wno-bool-compare option.
+dnl #
+dnl # We actually invoke gcc with the -Wbool-compare option
+dnl # and infer the 'no-' version does or doesn't exist based upon
+dnl # the results.  This is required because when checking any of
+dnl # no- prefixed options gcc always returns success.
+dnl #
+AC_DEFUN([ZFS_AC_CONFIG_ALWAYS_NO_BOOL_COMPARE], [
+	AC_MSG_CHECKING([for -Wno-bool-compare support])
+
+	saved_flags="$CFLAGS"
+	CFLAGS="$CFLAGS -Wbool-compare"
+
+	AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], [])],
+	[
+		NO_BOOL_COMPARE=-Wno-bool-compare
+		AC_MSG_RESULT([yes])
+	],
+	[
+		NO_BOOL_COMPARE=
+		AC_MSG_RESULT([no])
+	])
+
+	CFLAGS="$saved_flags"
+	AC_SUBST([NO_BOOL_COMPARE])
+])
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/config/always-no-unused-but-set-variable.m4
@@ -0,0 +1,27 @@
+dnl #
+dnl # Check if gcc supports -Wno-unused-but-set-variable option.
+dnl #
+dnl # We actually invoke gcc with the -Wunused-but-set-variable option
+dnl # and infer the 'no-' version does or doesn't exist based upon
+dnl # the results.  This is required because when checking any of
+dnl # no- prefixed options gcc always returns success.
+dnl #
+AC_DEFUN([ZFS_AC_CONFIG_ALWAYS_NO_UNUSED_BUT_SET_VARIABLE], [
+	AC_MSG_CHECKING([for -Wno-unused-but-set-variable support])
+
+	saved_flags="$CFLAGS"
+	CFLAGS="$CFLAGS -Wunused-but-set-variable"
+
+	AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], [])],
+	[
+		NO_UNUSED_BUT_SET_VARIABLE=-Wno-unused-but-set-variable
+		AC_MSG_RESULT([yes])
+	],
+	[
+		NO_UNUSED_BUT_SET_VARIABLE=
+		AC_MSG_RESULT([no])
+	])
+
+	CFLAGS="$saved_flags"
+	AC_SUBST([NO_UNUSED_BUT_SET_VARIABLE])
+])
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/config/compile
@@ -0,0 +1,347 @@
+#! /bin/sh
+# Wrapper for compilers which do not understand '-c -o'.
+
+scriptversion=2012-10-14.11; # UTC
+
+# Copyright (C) 1999-2014 Free Software Foundation, Inc.
+# Written by Tom Tromey <tromey@cygnus.com>.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# This file is maintained in Automake, please report
+# bugs to <bug-automake@gnu.org> or send patches to
+# <automake-patches@gnu.org>.
+
+nl='
+'
+
+# We need space, tab and new line, in precisely that order.  Quoting is
+# there to prevent tools from complaining about whitespace usage.
+IFS=" ""	$nl"
+
+file_conv=
+
+# func_file_conv build_file lazy
+# Convert a $build file to $host form and store it in $file
+# Currently only supports Windows hosts. If the determined conversion
+# type is listed in (the comma separated) LAZY, no conversion will
+# take place.
+func_file_conv ()
+{
+  file=$1
+  case $file in
+    / | /[!/]*) # absolute file, and not a UNC file
+      if test -z "$file_conv"; then
+	# lazily determine how to convert abs files
+	case `uname -s` in
+	  MINGW*)
+	    file_conv=mingw
+	    ;;
+	  CYGWIN*)
+	    file_conv=cygwin
+	    ;;
+	  *)
+	    file_conv=wine
+	    ;;
+	esac
+      fi
+      case $file_conv/,$2, in
+	*,$file_conv,*)
+	  ;;
+	mingw/*)
+	  file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'`
+	  ;;
+	cygwin/*)
+	  file=`cygpath -m "$file" || echo "$file"`
+	  ;;
+	wine/*)
+	  file=`winepath -w "$file" || echo "$file"`
+	  ;;
+      esac
+      ;;
+  esac
+}
+
+# func_cl_dashL linkdir
+# Make cl look for libraries in LINKDIR
+func_cl_dashL ()
+{
+  func_file_conv "$1"
+  if test -z "$lib_path"; then
+    lib_path=$file
+  else
+    lib_path="$lib_path;$file"
+  fi
+  linker_opts="$linker_opts -LIBPATH:$file"
+}
+
+# func_cl_dashl library
+# Do a library search-path lookup for cl
+func_cl_dashl ()
+{
+  lib=$1
+  found=no
+  save_IFS=$IFS
+  IFS=';'
+  for dir in $lib_path $LIB
+  do
+    IFS=$save_IFS
+    if $shared && test -f "$dir/$lib.dll.lib"; then
+      found=yes
+      lib=$dir/$lib.dll.lib
+      break
+    fi
+    if test -f "$dir/$lib.lib"; then
+      found=yes
+      lib=$dir/$lib.lib
+      break
+    fi
+    if test -f "$dir/lib$lib.a"; then
+      found=yes
+      lib=$dir/lib$lib.a
+      break
+    fi
+  done
+  IFS=$save_IFS
+
+  if test "$found" != yes; then
+    lib=$lib.lib
+  fi
+}
+
+# func_cl_wrapper cl arg...
+# Adjust compile command to suit cl
+func_cl_wrapper ()
+{
+  # Assume a capable shell
+  lib_path=
+  shared=:
+  linker_opts=
+  for arg
+  do
+    if test -n "$eat"; then
+      eat=
+    else
+      case $1 in
+	-o)
+	  # configure might choose to run compile as 'compile cc -o foo foo.c'.
+	  eat=1
+	  case $2 in
+	    *.o | *.[oO][bB][jJ])
+	      func_file_conv "$2"
+	      set x "$@" -Fo"$file"
+	      shift
+	      ;;
+	    *)
+	      func_file_conv "$2"
+	      set x "$@" -Fe"$file"
+	      shift
+	      ;;
+	  esac
+	  ;;
+	-I)
+	  eat=1
+	  func_file_conv "$2" mingw
+	  set x "$@" -I"$file"
+	  shift
+	  ;;
+	-I*)
+	  func_file_conv "${1#-I}" mingw
+	  set x "$@" -I"$file"
+	  shift
+	  ;;
+	-l)
+	  eat=1
+	  func_cl_dashl "$2"
+	  set x "$@" "$lib"
+	  shift
+	  ;;
+	-l*)
+	  func_cl_dashl "${1#-l}"
+	  set x "$@" "$lib"
+	  shift
+	  ;;
+	-L)
+	  eat=1
+	  func_cl_dashL "$2"
+	  ;;
+	-L*)
+	  func_cl_dashL "${1#-L}"
+	  ;;
+	-static)
+	  shared=false
+	  ;;
+	-Wl,*)
+	  arg=${1#-Wl,}
+	  save_ifs="$IFS"; IFS=','
+	  for flag in $arg; do
+	    IFS="$save_ifs"
+	    linker_opts="$linker_opts $flag"
+	  done
+	  IFS="$save_ifs"
+	  ;;
+	-Xlinker)
+	  eat=1
+	  linker_opts="$linker_opts $2"
+	  ;;
+	-*)
+	  set x "$@" "$1"
+	  shift
+	  ;;
+	*.cc | *.CC | *.cxx | *.CXX | *.[cC]++)
+	  func_file_conv "$1"
+	  set x "$@" -Tp"$file"
+	  shift
+	  ;;
+	*.c | *.cpp | *.CPP | *.lib | *.LIB | *.Lib | *.OBJ | *.obj | *.[oO])
+	  func_file_conv "$1" mingw
+	  set x "$@" "$file"
+	  shift
+	  ;;
+	*)
+	  set x "$@" "$1"
+	  shift
+	  ;;
+      esac
+    fi
+    shift
+  done
+  if test -n "$linker_opts"; then
+    linker_opts="-link$linker_opts"
+  fi
+  exec "$@" $linker_opts
+  exit 1
+}
+
+eat=
+
+case $1 in
+  '')
+     echo "$0: No command.  Try '$0 --help' for more information." 1>&2
+     exit 1;
+     ;;
+  -h | --h*)
+    cat <<\EOF
+Usage: compile [--help] [--version] PROGRAM [ARGS]
+
+Wrapper for compilers which do not understand '-c -o'.
+Remove '-o dest.o' from ARGS, run PROGRAM with the remaining
+arguments, and rename the output as expected.
+
+If you are trying to build a whole package this is not the
+right script to run: please start by reading the file 'INSTALL'.
+
+Report bugs to <bug-automake@gnu.org>.
+EOF
+    exit $?
+    ;;
+  -v | --v*)
+    echo "compile $scriptversion"
+    exit $?
+    ;;
+  cl | *[/\\]cl | cl.exe | *[/\\]cl.exe )
+    func_cl_wrapper "$@"      # Doesn't return...
+    ;;
+esac
+
+ofile=
+cfile=
+
+for arg
+do
+  if test -n "$eat"; then
+    eat=
+  else
+    case $1 in
+      -o)
+	# configure might choose to run compile as 'compile cc -o foo foo.c'.
+	# So we strip '-o arg' only if arg is an object.
+	eat=1
+	case $2 in
+	  *.o | *.obj)
+	    ofile=$2
+	    ;;
+	  *)
+	    set x "$@" -o "$2"
+	    shift
+	    ;;
+	esac
+	;;
+      *.c)
+	cfile=$1
+	set x "$@" "$1"
+	shift
+	;;
+      *)
+	set x "$@" "$1"
+	shift
+	;;
+    esac
+  fi
+  shift
+done
+
+if test -z "$ofile" || test -z "$cfile"; then
+  # If no '-o' option was seen then we might have been invoked from a
+  # pattern rule where we don't need one.  That is ok -- this is a
+  # normal compilation that the losing compiler can handle.  If no
+  # '.c' file was seen then we are probably linking.  That is also
+  # ok.
+  exec "$@"
+fi
+
+# Name of file we expect compiler to create.
+cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'`
+
+# Create the lock directory.
+# Note: use '[/\\:.-]' here to ensure that we don't use the same name
+# that we are using for the .o file.  Also, base the name on the expected
+# object file name, since that is what matters with a parallel build.
+lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d
+while true; do
+  if mkdir "$lockdir" >/dev/null 2>&1; then
+    break
+  fi
+  sleep 1
+done
+# FIXME: race condition here if user kills between mkdir and trap.
+trap "rmdir '$lockdir'; exit 1" 1 2 15
+
+# Run the compile.
+"$@"
+ret=$?
+
+if test -f "$cofile"; then
+  test "$cofile" = "$ofile" || mv "$cofile" "$ofile"
+elif test -f "${cofile}bj"; then
+  test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile"
+fi
+
+rmdir "$lockdir"
+exit $ret
+
+# Local Variables:
+# mode: shell-script
+# sh-indentation: 2
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
+# End:
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/config/config.awk
@@ -0,0 +1,15 @@
+# Remove default preprocessor define's from config.h
+#   PACKAGE
+#   PACKAGE_BUGREPORT
+#   PACKAGE_NAME
+#   PACKAGE_STRING
+#   PACKAGE_TARNAME
+#   PACKAGE_VERSION
+#   STDC_HEADERS
+#   VERSION
+
+BEGIN { RS = "" ; FS = "\n" }     \
+	!/.#define PACKAGE./ &&   \
+	!/.#define VERSION./ &&   \
+	!/.#define STDC_HEADERS./ \
+	{ print $0"\n" }
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/config/config.guess
@@ -0,0 +1,1441 @@
+#! /bin/sh
+# Attempt to guess a canonical system name.
+#   Copyright 1992-2015 Free Software Foundation, Inc.
+
+timestamp='2015-08-20'
+
+# This file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, see <http://www.gnu.org/licenses/>.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that
+# program.  This Exception is an additional permission under section 7
+# of the GNU General Public License, version 3 ("GPLv3").
+#
+# Originally written by Per Bothner; maintained since 2000 by Ben Elliston.
+#
+# You can get the latest version of this script from:
+# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
+#
+# Please send patches to <config-patches@gnu.org>.
+
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION]
+
+Output the configuration name of the system \`$me' is run on.
+
+Operation modes:
+  -h, --help         print this help, then exit
+  -t, --time-stamp   print date of last modification, then exit
+  -v, --version      print version number, then exit
+
+Report bugs and patches to <config-patches@gnu.org>."
+
+version="\
+GNU config.guess ($timestamp)
+
+Originally written by Per Bothner.
+Copyright 1992-2015 Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions.  There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+  case $1 in
+    --time-stamp | --time* | -t )
+       echo "$timestamp" ; exit ;;
+    --version | -v )
+       echo "$version" ; exit ;;
+    --help | --h* | -h )
+       echo "$usage"; exit ;;
+    -- )     # Stop option processing
+       shift; break ;;
+    - )	# Use stdin as input.
+       break ;;
+    -* )
+       echo "$me: invalid option $1$help" >&2
+       exit 1 ;;
+    * )
+       break ;;
+  esac
+done
+
+if test $# != 0; then
+  echo "$me: too many arguments$help" >&2
+  exit 1
+fi
+
+trap 'exit 1' 1 2 15
+
+# CC_FOR_BUILD -- compiler used by this script. Note that the use of a
+# compiler to aid in system detection is discouraged as it requires
+# temporary files to be created and, as you can see below, it is a
+# headache to deal with in a portable fashion.
+
+# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still
+# use `HOST_CC' if defined, but it is deprecated.
+
+# Portable tmp directory creation inspired by the Autoconf team.
+
+set_cc_for_build='
+trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ;
+trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ;
+: ${TMPDIR=/tmp} ;
+ { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
+ { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } ||
+ { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } ||
+ { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ;
+dummy=$tmp/dummy ;
+tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ;
+case $CC_FOR_BUILD,$HOST_CC,$CC in
+ ,,)    echo "int x;" > $dummy.c ;
+	for c in cc gcc c89 c99 ; do
+	  if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then
+	     CC_FOR_BUILD="$c"; break ;
+	  fi ;
+	done ;
+	if test x"$CC_FOR_BUILD" = x ; then
+	  CC_FOR_BUILD=no_compiler_found ;
+	fi
+	;;
+ ,,*)   CC_FOR_BUILD=$CC ;;
+ ,*,*)  CC_FOR_BUILD=$HOST_CC ;;
+esac ; set_cc_for_build= ;'
+
+# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
+# (ghazi@noc.rutgers.edu 1994-08-24)
+if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
+	PATH=$PATH:/.attbin ; export PATH
+fi
+
+UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
+UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
+UNAME_SYSTEM=`(uname -s) 2>/dev/null`  || UNAME_SYSTEM=unknown
+UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
+
+case "${UNAME_SYSTEM}" in
+Linux|GNU|GNU/*)
+	# If the system lacks a compiler, then just pick glibc.
+	# We could probably try harder.
+	LIBC=gnu
+
+	eval $set_cc_for_build
+	cat <<-EOF > $dummy.c
+	#include <features.h>
+	#if defined(__UCLIBC__)
+	LIBC=uclibc
+	#elif defined(__dietlibc__)
+	LIBC=dietlibc
+	#else
+	LIBC=gnu
+	#endif
+	EOF
+	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC' | sed 's, ,,g'`
+	;;
+esac
+
+# Note: order is significant - the case branches are not exclusive.
+
+case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
+    *:NetBSD:*:*)
+	# NetBSD (nbsd) targets should (where applicable) match one or
+	# more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*,
+	# *-*-netbsdecoff* and *-*-netbsd*.  For targets that recently
+	# switched to ELF, *-*-netbsd* would select the old
+	# object file format.  This provides both forward
+	# compatibility and a consistent mechanism for selecting the
+	# object file format.
+	#
+	# Note: NetBSD doesn't particularly care about the vendor
+	# portion of the name.  We always set it to "unknown".
+	sysctl="sysctl -n hw.machine_arch"
+	UNAME_MACHINE_ARCH=`(uname -p 2>/dev/null || \
+	    /sbin/$sysctl 2>/dev/null || \
+	    /usr/sbin/$sysctl 2>/dev/null || \
+	    echo unknown)`
+	case "${UNAME_MACHINE_ARCH}" in
+	    armeb) machine=armeb-unknown ;;
+	    arm*) machine=arm-unknown ;;
+	    sh3el) machine=shl-unknown ;;
+	    sh3eb) machine=sh-unknown ;;
+	    sh5el) machine=sh5le-unknown ;;
+	    earmv*)
+		arch=`echo ${UNAME_MACHINE_ARCH} | sed -e 's,^e\(armv[0-9]\).*$,\1,'`
+		endian=`echo ${UNAME_MACHINE_ARCH} | sed -ne 's,^.*\(eb\)$,\1,p'`
+		machine=${arch}${endian}-unknown
+		;;
+	    *) machine=${UNAME_MACHINE_ARCH}-unknown ;;
+	esac
+	# The Operating System including object format, if it has switched
+	# to ELF recently, or will in the future.
+	case "${UNAME_MACHINE_ARCH}" in
+	    arm*|earm*|i386|m68k|ns32k|sh3*|sparc|vax)
+		eval $set_cc_for_build
+		if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
+			| grep -q __ELF__
+		then
+		    # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
+		    # Return netbsd for either.  FIX?
+		    os=netbsd
+		else
+		    os=netbsdelf
+		fi
+		;;
+	    *)
+		os=netbsd
+		;;
+	esac
+	# Determine ABI tags.
+	case "${UNAME_MACHINE_ARCH}" in
+	    earm*)
+		expr='s/^earmv[0-9]/-eabi/;s/eb$//'
+		abi=`echo ${UNAME_MACHINE_ARCH} | sed -e "$expr"`
+		;;
+	esac
+	# The OS release
+	# Debian GNU/NetBSD machines have a different userland, and
+	# thus, need a distinct triplet. However, they do not need
+	# kernel version information, so it can be replaced with a
+	# suitable tag, in the style of linux-gnu.
+	case "${UNAME_VERSION}" in
+	    Debian*)
+		release='-gnu'
+		;;
+	    *)
+		release=`echo ${UNAME_RELEASE} | sed -e 's/[-_].*//' | cut -d. -f1,2`
+		;;
+	esac
+	# Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
+	# contains redundant information, the shorter form:
+	# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
+	echo "${machine}-${os}${release}${abi}"
+	exit ;;
+    *:Bitrig:*:*)
+	UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'`
+	echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_RELEASE}
+	exit ;;
+    *:OpenBSD:*:*)
+	UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`
+	echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE}
+	exit ;;
+    *:ekkoBSD:*:*)
+	echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE}
+	exit ;;
+    *:SolidBSD:*:*)
+	echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE}
+	exit ;;
+    macppc:MirBSD:*:*)
+	echo powerpc-unknown-mirbsd${UNAME_RELEASE}
+	exit ;;
+    *:MirBSD:*:*)
+	echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE}
+	exit ;;
+    *:Sortix:*:*)
+	echo ${UNAME_MACHINE}-unknown-sortix
+	exit ;;
+    alpha:OSF1:*:*)
+	case $UNAME_RELEASE in
+	*4.0)
+		UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
+		;;
+	*5.*)
+		UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
+		;;
+	esac
+	# According to Compaq, /usr/sbin/psrinfo has been available on
+	# OSF/1 and Tru64 systems produced since 1995.  I hope that
+	# covers most systems running today.  This code pipes the CPU
+	# types through head -n 1, so we only detect the type of CPU 0.
+	ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^  The alpha \(.*\) processor.*$/\1/p' | head -n 1`
+	case "$ALPHA_CPU_TYPE" in
+	    "EV4 (21064)")
+		UNAME_MACHINE="alpha" ;;
+	    "EV4.5 (21064)")
+		UNAME_MACHINE="alpha" ;;
+	    "LCA4 (21066/21068)")
+		UNAME_MACHINE="alpha" ;;
+	    "EV5 (21164)")
+		UNAME_MACHINE="alphaev5" ;;
+	    "EV5.6 (21164A)")
+		UNAME_MACHINE="alphaev56" ;;
+	    "EV5.6 (21164PC)")
+		UNAME_MACHINE="alphapca56" ;;
+	    "EV5.7 (21164PC)")
+		UNAME_MACHINE="alphapca57" ;;
+	    "EV6 (21264)")
+		UNAME_MACHINE="alphaev6" ;;
+	    "EV6.7 (21264A)")
+		UNAME_MACHINE="alphaev67" ;;
+	    "EV6.8CB (21264C)")
+		UNAME_MACHINE="alphaev68" ;;
+	    "EV6.8AL (21264B)")
+		UNAME_MACHINE="alphaev68" ;;
+	    "EV6.8CX (21264D)")
+		UNAME_MACHINE="alphaev68" ;;
+	    "EV6.9A (21264/EV69A)")
+		UNAME_MACHINE="alphaev69" ;;
+	    "EV7 (21364)")
+		UNAME_MACHINE="alphaev7" ;;
+	    "EV7.9 (21364A)")
+		UNAME_MACHINE="alphaev79" ;;
+	esac
+	# A Pn.n version is a patched version.
+	# A Vn.n version is a released version.
+	# A Tn.n version is a released field test version.
+	# A Xn.n version is an unreleased experimental baselevel.
+	# 1.2 uses "1.2" for uname -r.
+	echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+	# Reset EXIT trap before exiting to avoid spurious non-zero exit code.
+	exitcode=$?
+	trap '' 0
+	exit $exitcode ;;
+    Alpha\ *:Windows_NT*:*)
+	# How do we know it's Interix rather than the generic POSIX subsystem?
+	# Should we change UNAME_MACHINE based on the output of uname instead
+	# of the specific Alpha model?
+	echo alpha-pc-interix
+	exit ;;
+    21064:Windows_NT:50:3)
+	echo alpha-dec-winnt3.5
+	exit ;;
+    Amiga*:UNIX_System_V:4.0:*)
+	echo m68k-unknown-sysv4
+	exit ;;
+    *:[Aa]miga[Oo][Ss]:*:*)
+	echo ${UNAME_MACHINE}-unknown-amigaos
+	exit ;;
+    *:[Mm]orph[Oo][Ss]:*:*)
+	echo ${UNAME_MACHINE}-unknown-morphos
+	exit ;;
+    *:OS/390:*:*)
+	echo i370-ibm-openedition
+	exit ;;
+    *:z/VM:*:*)
+	echo s390-ibm-zvmoe
+	exit ;;
+    *:OS400:*:*)
+	echo powerpc-ibm-os400
+	exit ;;
+    arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
+	echo arm-acorn-riscix${UNAME_RELEASE}
+	exit ;;
+    arm*:riscos:*:*|arm*:RISCOS:*:*)
+	echo arm-unknown-riscos
+	exit ;;
+    SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
+	echo hppa1.1-hitachi-hiuxmpp
+	exit ;;
+    Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
+	# akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
+	if test "`(/bin/universe) 2>/dev/null`" = att ; then
+		echo pyramid-pyramid-sysv3
+	else
+		echo pyramid-pyramid-bsd
+	fi
+	exit ;;
+    NILE*:*:*:dcosx)
+	echo pyramid-pyramid-svr4
+	exit ;;
+    DRS?6000:unix:4.0:6*)
+	echo sparc-icl-nx6
+	exit ;;
+    DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*)
+	case `/usr/bin/uname -p` in
+	    sparc) echo sparc-icl-nx7; exit ;;
+	esac ;;
+    s390x:SunOS:*:*)
+	echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit ;;
+    sun4H:SunOS:5.*:*)
+	echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit ;;
+    sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
+	echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit ;;
+    i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*)
+	echo i386-pc-auroraux${UNAME_RELEASE}
+	exit ;;
+    i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*)
+	eval $set_cc_for_build
+	SUN_ARCH="i386"
+	# If there is a compiler, see if it is configured for 64-bit objects.
+	# Note that the Sun cc does not turn __LP64__ into 1 like gcc does.
+	# This test works for both compilers.
+	if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
+	    if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \
+		(CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
+		grep IS_64BIT_ARCH >/dev/null
+	    then
+		SUN_ARCH="x86_64"
+	    fi
+	fi
+	echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit ;;
+    sun4*:SunOS:6*:*)
+	# According to config.sub, this is the proper way to canonicalize
+	# SunOS6.  Hard to guess exactly what SunOS6 will be like, but
+	# it's likely to be more like Solaris than SunOS4.
+	echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit ;;
+    sun4*:SunOS:*:*)
+	case "`/usr/bin/arch -k`" in
+	    Series*|S4*)
+		UNAME_RELEASE=`uname -v`
+		;;
+	esac
+	# Japanese Language versions have a version number like `4.1.3-JL'.
+	echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
+	exit ;;
+    sun3*:SunOS:*:*)
+	echo m68k-sun-sunos${UNAME_RELEASE}
+	exit ;;
+    sun*:*:4.2BSD:*)
+	UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
+	test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
+	case "`/bin/arch`" in
+	    sun3)
+		echo m68k-sun-sunos${UNAME_RELEASE}
+		;;
+	    sun4)
+		echo sparc-sun-sunos${UNAME_RELEASE}
+		;;
+	esac
+	exit ;;
+    aushp:SunOS:*:*)
+	echo sparc-auspex-sunos${UNAME_RELEASE}
+	exit ;;
+    # The situation for MiNT is a little confusing.  The machine name
+    # can be virtually everything (everything which is not
+    # "atarist" or "atariste" at least should have a processor
+    # > m68000).  The system name ranges from "MiNT" over "FreeMiNT"
+    # to the lowercase version "mint" (or "freemint").  Finally
+    # the system name "TOS" denotes a system which is actually not
+    # MiNT.  But MiNT is downward compatible to TOS, so this should
+    # be no problem.
+    atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
+	echo m68k-atari-mint${UNAME_RELEASE}
+	exit ;;
+    atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
+	echo m68k-atari-mint${UNAME_RELEASE}
+	exit ;;
+    *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
+	echo m68k-atari-mint${UNAME_RELEASE}
+	exit ;;
+    milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
+	echo m68k-milan-mint${UNAME_RELEASE}
+	exit ;;
+    hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
+	echo m68k-hades-mint${UNAME_RELEASE}
+	exit ;;
+    *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
+	echo m68k-unknown-mint${UNAME_RELEASE}
+	exit ;;
+    m68k:machten:*:*)
+	echo m68k-apple-machten${UNAME_RELEASE}
+	exit ;;
+    powerpc:machten:*:*)
+	echo powerpc-apple-machten${UNAME_RELEASE}
+	exit ;;
+    RISC*:Mach:*:*)
+	echo mips-dec-mach_bsd4.3
+	exit ;;
+    RISC*:ULTRIX:*:*)
+	echo mips-dec-ultrix${UNAME_RELEASE}
+	exit ;;
+    VAX*:ULTRIX*:*:*)
+	echo vax-dec-ultrix${UNAME_RELEASE}
+	exit ;;
+    2020:CLIX:*:* | 2430:CLIX:*:*)
+	echo clipper-intergraph-clix${UNAME_RELEASE}
+	exit ;;
+    mips:*:*:UMIPS | mips:*:*:RISCos)
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+#ifdef __cplusplus
+#include <stdio.h>  /* for printf() prototype */
+	int main (int argc, char *argv[]) {
+#else
+	int main (argc, argv) int argc; char *argv[]; {
+#endif
+	#if defined (host_mips) && defined (MIPSEB)
+	#if defined (SYSTYPE_SYSV)
+	  printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
+	#endif
+	#if defined (SYSTYPE_SVR4)
+	  printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
+	#endif
+	#if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
+	  printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
+	#endif
+	#endif
+	  exit (-1);
+	}
+EOF
+	$CC_FOR_BUILD -o $dummy $dummy.c &&
+	  dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` &&
+	  SYSTEM_NAME=`$dummy $dummyarg` &&
+	    { echo "$SYSTEM_NAME"; exit; }
+	echo mips-mips-riscos${UNAME_RELEASE}
+	exit ;;
+    Motorola:PowerMAX_OS:*:*)
+	echo powerpc-motorola-powermax
+	exit ;;
+    Motorola:*:4.3:PL8-*)
+	echo powerpc-harris-powermax
+	exit ;;
+    Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*)
+	echo powerpc-harris-powermax
+	exit ;;
+    Night_Hawk:Power_UNIX:*:*)
+	echo powerpc-harris-powerunix
+	exit ;;
+    m88k:CX/UX:7*:*)
+	echo m88k-harris-cxux7
+	exit ;;
+    m88k:*:4*:R4*)
+	echo m88k-motorola-sysv4
+	exit ;;
+    m88k:*:3*:R3*)
+	echo m88k-motorola-sysv3
+	exit ;;
+    AViiON:dgux:*:*)
+	# DG/UX returns AViiON for all architectures
+	UNAME_PROCESSOR=`/usr/bin/uname -p`
+	if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
+	then
+	    if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
+	       [ ${TARGET_BINARY_INTERFACE}x = x ]
+	    then
+		echo m88k-dg-dgux${UNAME_RELEASE}
+	    else
+		echo m88k-dg-dguxbcs${UNAME_RELEASE}
+	    fi
+	else
+	    echo i586-dg-dgux${UNAME_RELEASE}
+	fi
+	exit ;;
+    M88*:DolphinOS:*:*)	# DolphinOS (SVR3)
+	echo m88k-dolphin-sysv3
+	exit ;;
+    M88*:*:R3*:*)
+	# Delta 88k system running SVR3
+	echo m88k-motorola-sysv3
+	exit ;;
+    XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
+	echo m88k-tektronix-sysv3
+	exit ;;
+    Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
+	echo m68k-tektronix-bsd
+	exit ;;
+    *:IRIX*:*:*)
+	echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
+	exit ;;
+    ????????:AIX?:[12].1:2)   # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
+	echo romp-ibm-aix     # uname -m gives an 8 hex-code CPU id
+	exit ;;               # Note that: echo "'`uname -s`'" gives 'AIX '
+    i*86:AIX:*:*)
+	echo i386-ibm-aix
+	exit ;;
+    ia64:AIX:*:*)
+	if [ -x /usr/bin/oslevel ] ; then
+		IBM_REV=`/usr/bin/oslevel`
+	else
+		IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+	fi
+	echo ${UNAME_MACHINE}-ibm-aix${IBM_REV}
+	exit ;;
+    *:AIX:2:3)
+	if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
+		eval $set_cc_for_build
+		sed 's/^		//' << EOF >$dummy.c
+		#include <sys/systemcfg.h>
+
+		main()
+			{
+			if (!__power_pc())
+				exit(1);
+			puts("powerpc-ibm-aix3.2.5");
+			exit(0);
+			}
+EOF
+		if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy`
+		then
+			echo "$SYSTEM_NAME"
+		else
+			echo rs6000-ibm-aix3.2.5
+		fi
+	elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
+		echo rs6000-ibm-aix3.2.4
+	else
+		echo rs6000-ibm-aix3.2
+	fi
+	exit ;;
+    *:AIX:*:[4567])
+	IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
+	if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
+		IBM_ARCH=rs6000
+	else
+		IBM_ARCH=powerpc
+	fi
+	if [ -x /usr/bin/lslpp ] ; then
+		IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc |
+			   awk -F: '{ print $3 }' | sed s/[0-9]*$/0/`
+	else
+		IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+	fi
+	echo ${IBM_ARCH}-ibm-aix${IBM_REV}
+	exit ;;
+    *:AIX:*:*)
+	echo rs6000-ibm-aix
+	exit ;;
+    ibmrt:4.4BSD:*|romp-ibm:BSD:*)
+	echo romp-ibm-bsd4.4
+	exit ;;
+    ibmrt:*BSD:*|romp-ibm:BSD:*)            # covers RT/PC BSD and
+	echo romp-ibm-bsd${UNAME_RELEASE}   # 4.3 with uname added to
+	exit ;;                             # report: romp-ibm BSD 4.3
+    *:BOSX:*:*)
+	echo rs6000-bull-bosx
+	exit ;;
+    DPX/2?00:B.O.S.:*:*)
+	echo m68k-bull-sysv3
+	exit ;;
+    9000/[34]??:4.3bsd:1.*:*)
+	echo m68k-hp-bsd
+	exit ;;
+    hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
+	echo m68k-hp-bsd4.4
+	exit ;;
+    9000/[34678]??:HP-UX:*:*)
+	HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+	case "${UNAME_MACHINE}" in
+	    9000/31? )            HP_ARCH=m68000 ;;
+	    9000/[34]?? )         HP_ARCH=m68k ;;
+	    9000/[678][0-9][0-9])
+		if [ -x /usr/bin/getconf ]; then
+		    sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
+		    sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
+		    case "${sc_cpu_version}" in
+		      523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
+		      528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
+		      532)                      # CPU_PA_RISC2_0
+			case "${sc_kernel_bits}" in
+			  32) HP_ARCH="hppa2.0n" ;;
+			  64) HP_ARCH="hppa2.0w" ;;
+			  '') HP_ARCH="hppa2.0" ;;   # HP-UX 10.20
+			esac ;;
+		    esac
+		fi
+		if [ "${HP_ARCH}" = "" ]; then
+		    eval $set_cc_for_build
+		    sed 's/^		//' << EOF >$dummy.c
+
+		#define _HPUX_SOURCE
+		#include <stdlib.h>
+		#include <unistd.h>
+
+		int main ()
+		{
+		#if defined(_SC_KERNEL_BITS)
+		    long bits = sysconf(_SC_KERNEL_BITS);
+		#endif
+		    long cpu  = sysconf (_SC_CPU_VERSION);
+
+		    switch (cpu)
+			{
+			case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
+			case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
+			case CPU_PA_RISC2_0:
+		#if defined(_SC_KERNEL_BITS)
+			    switch (bits)
+				{
+				case 64: puts ("hppa2.0w"); break;
+				case 32: puts ("hppa2.0n"); break;
+				default: puts ("hppa2.0"); break;
+				} break;
+		#else  /* !defined(_SC_KERNEL_BITS) */
+			    puts ("hppa2.0"); break;
+		#endif
+			default: puts ("hppa1.0"); break;
+			}
+		    exit (0);
+		}
+EOF
+		    (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
+		    test -z "$HP_ARCH" && HP_ARCH=hppa
+		fi ;;
+	esac
+	if [ ${HP_ARCH} = "hppa2.0w" ]
+	then
+	    eval $set_cc_for_build
+
+	    # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating
+	    # 32-bit code.  hppa64-hp-hpux* has the same kernel and a compiler
+	    # generating 64-bit code.  GNU and HP use different nomenclature:
+	    #
+	    # $ CC_FOR_BUILD=cc ./config.guess
+	    # => hppa2.0w-hp-hpux11.23
+	    # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess
+	    # => hppa64-hp-hpux11.23
+
+	    if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) |
+		grep -q __LP64__
+	    then
+		HP_ARCH="hppa2.0w"
+	    else
+		HP_ARCH="hppa64"
+	    fi
+	fi
+	echo ${HP_ARCH}-hp-hpux${HPUX_REV}
+	exit ;;
+    ia64:HP-UX:*:*)
+	HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+	echo ia64-hp-hpux${HPUX_REV}
+	exit ;;
+    3050*:HI-UX:*:*)
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+	#include <unistd.h>
+	int
+	main ()
+	{
+	  long cpu = sysconf (_SC_CPU_VERSION);
+	  /* The order matters, because CPU_IS_HP_MC68K erroneously returns
+	     true for CPU_PA_RISC1_0.  CPU_IS_PA_RISC returns correct
+	     results, however.  */
+	  if (CPU_IS_PA_RISC (cpu))
+	    {
+	      switch (cpu)
+		{
+		  case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break;
+		  case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break;
+		  case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break;
+		  default: puts ("hppa-hitachi-hiuxwe2"); break;
+		}
+	    }
+	  else if (CPU_IS_HP_MC68K (cpu))
+	    puts ("m68k-hitachi-hiuxwe2");
+	  else puts ("unknown-hitachi-hiuxwe2");
+	  exit (0);
+	}
+EOF
+	$CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` &&
+		{ echo "$SYSTEM_NAME"; exit; }
+	echo unknown-hitachi-hiuxwe2
+	exit ;;
+    9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
+	echo hppa1.1-hp-bsd
+	exit ;;
+    9000/8??:4.3bsd:*:*)
+	echo hppa1.0-hp-bsd
+	exit ;;
+    *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)
+	echo hppa1.0-hp-mpeix
+	exit ;;
+    hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
+	echo hppa1.1-hp-osf
+	exit ;;
+    hp8??:OSF1:*:*)
+	echo hppa1.0-hp-osf
+	exit ;;
+    i*86:OSF1:*:*)
+	if [ -x /usr/sbin/sysversion ] ; then
+	    echo ${UNAME_MACHINE}-unknown-osf1mk
+	else
+	    echo ${UNAME_MACHINE}-unknown-osf1
+	fi
+	exit ;;
+    parisc*:Lites*:*:*)
+	echo hppa1.1-hp-lites
+	exit ;;
+    C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
+	echo c1-convex-bsd
+	exit ;;
+    C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
+	if getsysinfo -f scalar_acc
+	then echo c32-convex-bsd
+	else echo c2-convex-bsd
+	fi
+	exit ;;
+    C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
+	echo c34-convex-bsd
+	exit ;;
+    C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
+	echo c38-convex-bsd
+	exit ;;
+    C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
+	echo c4-convex-bsd
+	exit ;;
+    CRAY*Y-MP:*:*:*)
+	echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit ;;
+    CRAY*[A-Z]90:*:*:*)
+	echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
+	| sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
+	      -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \
+	      -e 's/\.[^.]*$/.X/'
+	exit ;;
+    CRAY*TS:*:*:*)
+	echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit ;;
+    CRAY*T3E:*:*:*)
+	echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit ;;
+    CRAY*SV1:*:*:*)
+	echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit ;;
+    *:UNICOS/mp:*:*)
+	echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit ;;
+    F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
+	FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+	FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+	FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
+	echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+	exit ;;
+    5000:UNIX_System_V:4.*:*)
+	FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+	FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
+	echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+	exit ;;
+    i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
+	echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
+	exit ;;
+    sparc*:BSD/OS:*:*)
+	echo sparc-unknown-bsdi${UNAME_RELEASE}
+	exit ;;
+    *:BSD/OS:*:*)
+	echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
+	exit ;;
+    *:FreeBSD:*:*)
+	UNAME_PROCESSOR=`/usr/bin/uname -p`
+	case ${UNAME_PROCESSOR} in
+	    amd64)
+		echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+	    *)
+		echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+	esac
+	exit ;;
+    i*:CYGWIN*:*)
+	echo ${UNAME_MACHINE}-pc-cygwin
+	exit ;;
+    *:MINGW64*:*)
+	echo ${UNAME_MACHINE}-pc-mingw64
+	exit ;;
+    *:MINGW*:*)
+	echo ${UNAME_MACHINE}-pc-mingw32
+	exit ;;
+    *:MSYS*:*)
+	echo ${UNAME_MACHINE}-pc-msys
+	exit ;;
+    i*:windows32*:*)
+	# uname -m includes "-pc" on this system.
+	echo ${UNAME_MACHINE}-mingw32
+	exit ;;
+    i*:PW*:*)
+	echo ${UNAME_MACHINE}-pc-pw32
+	exit ;;
+    *:Interix*:*)
+	case ${UNAME_MACHINE} in
+	    x86)
+		echo i586-pc-interix${UNAME_RELEASE}
+		exit ;;
+	    authenticamd | genuineintel | EM64T)
+		echo x86_64-unknown-interix${UNAME_RELEASE}
+		exit ;;
+	    IA64)
+		echo ia64-unknown-interix${UNAME_RELEASE}
+		exit ;;
+	esac ;;
+    [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
+	echo i${UNAME_MACHINE}-pc-mks
+	exit ;;
+    8664:Windows_NT:*)
+	echo x86_64-pc-mks
+	exit ;;
+    i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
+	# How do we know it's Interix rather than the generic POSIX subsystem?
+	# It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
+	# UNAME_MACHINE based on the output of uname instead of i386?
+	echo i586-pc-interix
+	exit ;;
+    i*:UWIN*:*)
+	echo ${UNAME_MACHINE}-pc-uwin
+	exit ;;
+    amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*)
+	echo x86_64-unknown-cygwin
+	exit ;;
+    p*:CYGWIN*:*)
+	echo powerpcle-unknown-cygwin
+	exit ;;
+    prep*:SunOS:5.*:*)
+	echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit ;;
+    *:GNU:*:*)
+	# the GNU system
+	echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-${LIBC}`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
+	exit ;;
+    *:GNU/*:*:*)
+	# other systems with GNU libc and userland
+	echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC}
+	exit ;;
+    i*86:Minix:*:*)
+	echo ${UNAME_MACHINE}-pc-minix
+	exit ;;
+    aarch64:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
+    aarch64_be:Linux:*:*)
+	UNAME_MACHINE=aarch64_be
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
+    alpha:Linux:*:*)
+	case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
+	  EV5)   UNAME_MACHINE=alphaev5 ;;
+	  EV56)  UNAME_MACHINE=alphaev56 ;;
+	  PCA56) UNAME_MACHINE=alphapca56 ;;
+	  PCA57) UNAME_MACHINE=alphapca56 ;;
+	  EV6)   UNAME_MACHINE=alphaev6 ;;
+	  EV67)  UNAME_MACHINE=alphaev67 ;;
+	  EV68*) UNAME_MACHINE=alphaev68 ;;
+	esac
+	objdump --private-headers /bin/sh | grep -q ld.so.1
+	if test "$?" = 0 ; then LIBC="gnulibc1" ; fi
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
+    arc:Linux:*:* | arceb:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
+    arm*:Linux:*:*)
+	eval $set_cc_for_build
+	if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
+	    | grep -q __ARM_EABI__
+	then
+	    echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	else
+	    if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \
+		| grep -q __ARM_PCS_VFP
+	    then
+		echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabi
+	    else
+		echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabihf
+	    fi
+	fi
+	exit ;;
+    avr32*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
+    cris:Linux:*:*)
+	echo ${UNAME_MACHINE}-axis-linux-${LIBC}
+	exit ;;
+    crisv32:Linux:*:*)
+	echo ${UNAME_MACHINE}-axis-linux-${LIBC}
+	exit ;;
+    e2k:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
+    frv:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
+    hexagon:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
+    i*86:Linux:*:*)
+	echo ${UNAME_MACHINE}-pc-linux-${LIBC}
+	exit ;;
+    ia64:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
+    m32r*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
+    m68*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
+    mips:Linux:*:* | mips64:Linux:*:*)
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+	#undef CPU
+	#undef ${UNAME_MACHINE}
+	#undef ${UNAME_MACHINE}el
+	#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
+	CPU=${UNAME_MACHINE}el
+	#else
+	#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
+	CPU=${UNAME_MACHINE}
+	#else
+	CPU=
+	#endif
+	#endif
+EOF
+	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'`
+	test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; }
+	;;
+    openrisc*:Linux:*:*)
+	echo or1k-unknown-linux-${LIBC}
+	exit ;;
+    or32:Linux:*:* | or1k*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
+    padre:Linux:*:*)
+	echo sparc-unknown-linux-${LIBC}
+	exit ;;
+    parisc64:Linux:*:* | hppa64:Linux:*:*)
+	echo hppa64-unknown-linux-${LIBC}
+	exit ;;
+    parisc:Linux:*:* | hppa:Linux:*:*)
+	# Look for CPU level
+	case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
+	  PA7*) echo hppa1.1-unknown-linux-${LIBC} ;;
+	  PA8*) echo hppa2.0-unknown-linux-${LIBC} ;;
+	  *)    echo hppa-unknown-linux-${LIBC} ;;
+	esac
+	exit ;;
+    ppc64:Linux:*:*)
+	echo powerpc64-unknown-linux-${LIBC}
+	exit ;;
+    ppc:Linux:*:*)
+	echo powerpc-unknown-linux-${LIBC}
+	exit ;;
+    ppc64le:Linux:*:*)
+	echo powerpc64le-unknown-linux-${LIBC}
+	exit ;;
+    ppcle:Linux:*:*)
+	echo powerpcle-unknown-linux-${LIBC}
+	exit ;;
+    s390:Linux:*:* | s390x:Linux:*:*)
+	echo ${UNAME_MACHINE}-ibm-linux-${LIBC}
+	exit ;;
+    sh64*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
+    sh*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
+    sparc:Linux:*:* | sparc64:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
+    tile*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
+    vax:Linux:*:*)
+	echo ${UNAME_MACHINE}-dec-linux-${LIBC}
+	exit ;;
+    x86_64:Linux:*:*)
+	echo ${UNAME_MACHINE}-pc-linux-${LIBC}
+	exit ;;
+    xtensa*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
+    i*86:DYNIX/ptx:4*:*)
+	# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
+	# earlier versions are messed up and put the nodename in both
+	# sysname and nodename.
+	echo i386-sequent-sysv4
+	exit ;;
+    i*86:UNIX_SV:4.2MP:2.*)
+	# Unixware is an offshoot of SVR4, but it has its own version
+	# number series starting with 2...
+	# I am not positive that other SVR4 systems won't match this,
+	# I just have to hope.  -- rms.
+	# Use sysv4.2uw... so that sysv4* matches it.
+	echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
+	exit ;;
+    i*86:OS/2:*:*)
+	# If we were able to find `uname', then EMX Unix compatibility
+	# is probably installed.
+	echo ${UNAME_MACHINE}-pc-os2-emx
+	exit ;;
+    i*86:XTS-300:*:STOP)
+	echo ${UNAME_MACHINE}-unknown-stop
+	exit ;;
+    i*86:atheos:*:*)
+	echo ${UNAME_MACHINE}-unknown-atheos
+	exit ;;
+    i*86:syllable:*:*)
+	echo ${UNAME_MACHINE}-pc-syllable
+	exit ;;
+    i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*)
+	echo i386-unknown-lynxos${UNAME_RELEASE}
+	exit ;;
+    i*86:*DOS:*:*)
+	echo ${UNAME_MACHINE}-pc-msdosdjgpp
+	exit ;;
+    i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*)
+	UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'`
+	if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
+		echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL}
+	else
+		echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL}
+	fi
+	exit ;;
+    i*86:*:5:[678]*)
+	# UnixWare 7.x, OpenUNIX and OpenServer 6.
+	case `/bin/uname -X | grep "^Machine"` in
+	    *486*)	     UNAME_MACHINE=i486 ;;
+	    *Pentium)	     UNAME_MACHINE=i586 ;;
+	    *Pent*|*Celeron) UNAME_MACHINE=i686 ;;
+	esac
+	echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}
+	exit ;;
+    i*86:*:3.2:*)
+	if test -f /usr/options/cb.name; then
+		UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
+		echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
+	elif /bin/uname -X 2>/dev/null >/dev/null ; then
+		UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')`
+		(/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486
+		(/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \
+			&& UNAME_MACHINE=i586
+		(/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \
+			&& UNAME_MACHINE=i686
+		(/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \
+			&& UNAME_MACHINE=i686
+		echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
+	else
+		echo ${UNAME_MACHINE}-pc-sysv32
+	fi
+	exit ;;
+    pc:*:*:*)
+	# Left here for compatibility:
+	# uname -m prints for DJGPP always 'pc', but it prints nothing about
+	# the processor, so we play safe by assuming i586.
+	# Note: whatever this is, it MUST be the same as what config.sub
+	# prints for the "djgpp" host, or else GDB configury will decide that
+	# this is a cross-build.
+	echo i586-pc-msdosdjgpp
+	exit ;;
+    Intel:Mach:3*:*)
+	echo i386-pc-mach3
+	exit ;;
+    paragon:*:*:*)
+	echo i860-intel-osf1
+	exit ;;
+    i860:*:4.*:*) # i860-SVR4
+	if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
+	  echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
+	else # Add other i860-SVR4 vendors below as they are discovered.
+	  echo i860-unknown-sysv${UNAME_RELEASE}  # Unknown i860-SVR4
+	fi
+	exit ;;
+    mini*:CTIX:SYS*5:*)
+	# "miniframe"
+	echo m68010-convergent-sysv
+	exit ;;
+    mc68k:UNIX:SYSTEM5:3.51m)
+	echo m68k-convergent-sysv
+	exit ;;
+    M680?0:D-NIX:5.3:*)
+	echo m68k-diab-dnix
+	exit ;;
+    M68*:*:R3V[5678]*:*)
+	test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;;
+    3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0)
+	OS_REL=''
+	test -r /etc/.relid \
+	&& OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+	/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+	  && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
+	/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+	  && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
+    3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
+	/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+	  && { echo i486-ncr-sysv4; exit; } ;;
+    NCR*:*:4.2:* | MPRAS*:*:4.2:*)
+	OS_REL='.3'
+	test -r /etc/.relid \
+	    && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+	/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+	    && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
+	/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+	    && { echo i586-ncr-sysv4.3${OS_REL}; exit; }
+	/bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \
+	    && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
+    m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
+	echo m68k-unknown-lynxos${UNAME_RELEASE}
+	exit ;;
+    mc68030:UNIX_System_V:4.*:*)
+	echo m68k-atari-sysv4
+	exit ;;
+    TSUNAMI:LynxOS:2.*:*)
+	echo sparc-unknown-lynxos${UNAME_RELEASE}
+	exit ;;
+    rs6000:LynxOS:2.*:*)
+	echo rs6000-unknown-lynxos${UNAME_RELEASE}
+	exit ;;
+    PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*)
+	echo powerpc-unknown-lynxos${UNAME_RELEASE}
+	exit ;;
+    SM[BE]S:UNIX_SV:*:*)
+	echo mips-dde-sysv${UNAME_RELEASE}
+	exit ;;
+    RM*:ReliantUNIX-*:*:*)
+	echo mips-sni-sysv4
+	exit ;;
+    RM*:SINIX-*:*:*)
+	echo mips-sni-sysv4
+	exit ;;
+    *:SINIX-*:*:*)
+	if uname -p 2>/dev/null >/dev/null ; then
+		UNAME_MACHINE=`(uname -p) 2>/dev/null`
+		echo ${UNAME_MACHINE}-sni-sysv4
+	else
+		echo ns32k-sni-sysv
+	fi
+	exit ;;
+    PENTIUM:*:4.0*:*)	# Unisys `ClearPath HMP IX 4000' SVR4/MP effort
+			# says <Richard.M.Bartel@ccMail.Census.GOV>
+	echo i586-unisys-sysv4
+	exit ;;
+    *:UNIX_System_V:4*:FTX*)
+	# From Gerald Hewes <hewes@openmarket.com>.
+	# How about differentiating between stratus architectures? -djm
+	echo hppa1.1-stratus-sysv4
+	exit ;;
+    *:*:*:FTX*)
+	# From seanf@swdc.stratus.com.
+	echo i860-stratus-sysv4
+	exit ;;
+    i*86:VOS:*:*)
+	# From Paul.Green@stratus.com.
+	echo ${UNAME_MACHINE}-stratus-vos
+	exit ;;
+    *:VOS:*:*)
+	# From Paul.Green@stratus.com.
+	echo hppa1.1-stratus-vos
+	exit ;;
+    mc68*:A/UX:*:*)
+	echo m68k-apple-aux${UNAME_RELEASE}
+	exit ;;
+    news*:NEWS-OS:6*:*)
+	echo mips-sony-newsos6
+	exit ;;
+    R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
+	if [ -d /usr/nec ]; then
+		echo mips-nec-sysv${UNAME_RELEASE}
+	else
+		echo mips-unknown-sysv${UNAME_RELEASE}
+	fi
+	exit ;;
+    BeBox:BeOS:*:*)	# BeOS running on hardware made by Be, PPC only.
+	echo powerpc-be-beos
+	exit ;;
+    BeMac:BeOS:*:*)	# BeOS running on Mac or Mac clone, PPC only.
+	echo powerpc-apple-beos
+	exit ;;
+    BePC:BeOS:*:*)	# BeOS running on Intel PC compatible.
+	echo i586-pc-beos
+	exit ;;
+    BePC:Haiku:*:*)	# Haiku running on Intel PC compatible.
+	echo i586-pc-haiku
+	exit ;;
+    x86_64:Haiku:*:*)
+	echo x86_64-unknown-haiku
+	exit ;;
+    SX-4:SUPER-UX:*:*)
+	echo sx4-nec-superux${UNAME_RELEASE}
+	exit ;;
+    SX-5:SUPER-UX:*:*)
+	echo sx5-nec-superux${UNAME_RELEASE}
+	exit ;;
+    SX-6:SUPER-UX:*:*)
+	echo sx6-nec-superux${UNAME_RELEASE}
+	exit ;;
+    SX-7:SUPER-UX:*:*)
+	echo sx7-nec-superux${UNAME_RELEASE}
+	exit ;;
+    SX-8:SUPER-UX:*:*)
+	echo sx8-nec-superux${UNAME_RELEASE}
+	exit ;;
+    SX-8R:SUPER-UX:*:*)
+	echo sx8r-nec-superux${UNAME_RELEASE}
+	exit ;;
+    Power*:Rhapsody:*:*)
+	echo powerpc-apple-rhapsody${UNAME_RELEASE}
+	exit ;;
+    *:Rhapsody:*:*)
+	echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
+	exit ;;
+    *:Darwin:*:*)
+	UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
+	eval $set_cc_for_build
+	if test "$UNAME_PROCESSOR" = unknown ; then
+	    UNAME_PROCESSOR=powerpc
+	fi
+	if test `echo "$UNAME_RELEASE" | sed -e 's/\..*//'` -le 10 ; then
+	    if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
+		if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
+		    (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
+		    grep IS_64BIT_ARCH >/dev/null
+		then
+		    case $UNAME_PROCESSOR in
+			i386) UNAME_PROCESSOR=x86_64 ;;
+			powerpc) UNAME_PROCESSOR=powerpc64 ;;
+		    esac
+		fi
+	    fi
+	elif test "$UNAME_PROCESSOR" = i386 ; then
+	    # Avoid executing cc on OS X 10.9, as it ships with a stub
+	    # that puts up a graphical alert prompting to install
+	    # developer tools.  Any system running Mac OS X 10.7 or
+	    # later (Darwin 11 and later) is required to have a 64-bit
+	    # processor. This is not true of the ARM version of Darwin
+	    # that Apple uses in portable devices.
+	    UNAME_PROCESSOR=x86_64
+	fi
+	echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
+	exit ;;
+    *:procnto*:*:* | *:QNX:[0123456789]*:*)
+	UNAME_PROCESSOR=`uname -p`
+	if test "$UNAME_PROCESSOR" = "x86"; then
+		UNAME_PROCESSOR=i386
+		UNAME_MACHINE=pc
+	fi
+	echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE}
+	exit ;;
+    *:QNX:*:4*)
+	echo i386-pc-qnx
+	exit ;;
+    NEO-?:NONSTOP_KERNEL:*:*)
+	echo neo-tandem-nsk${UNAME_RELEASE}
+	exit ;;
+    NSE-*:NONSTOP_KERNEL:*:*)
+	echo nse-tandem-nsk${UNAME_RELEASE}
+	exit ;;
+    NSR-?:NONSTOP_KERNEL:*:*)
+	echo nsr-tandem-nsk${UNAME_RELEASE}
+	exit ;;
+    *:NonStop-UX:*:*)
+	echo mips-compaq-nonstopux
+	exit ;;
+    BS2000:POSIX*:*:*)
+	echo bs2000-siemens-sysv
+	exit ;;
+    DS/*:UNIX_System_V:*:*)
+	echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE}
+	exit ;;
+    *:Plan9:*:*)
+	# "uname -m" is not consistent, so use $cputype instead. 386
+	# is converted to i386 for consistency with other x86
+	# operating systems.
+	if test "$cputype" = "386"; then
+	    UNAME_MACHINE=i386
+	else
+	    UNAME_MACHINE="$cputype"
+	fi
+	echo ${UNAME_MACHINE}-unknown-plan9
+	exit ;;
+    *:TOPS-10:*:*)
+	echo pdp10-unknown-tops10
+	exit ;;
+    *:TENEX:*:*)
+	echo pdp10-unknown-tenex
+	exit ;;
+    KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*)
+	echo pdp10-dec-tops20
+	exit ;;
+    XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*)
+	echo pdp10-xkl-tops20
+	exit ;;
+    *:TOPS-20:*:*)
+	echo pdp10-unknown-tops20
+	exit ;;
+    *:ITS:*:*)
+	echo pdp10-unknown-its
+	exit ;;
+    SEI:*:*:SEIUX)
+	echo mips-sei-seiux${UNAME_RELEASE}
+	exit ;;
+    *:DragonFly:*:*)
+	echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
+	exit ;;
+    *:*VMS:*:*)
+	UNAME_MACHINE=`(uname -p) 2>/dev/null`
+	case "${UNAME_MACHINE}" in
+	    A*) echo alpha-dec-vms ; exit ;;
+	    I*) echo ia64-dec-vms ; exit ;;
+	    V*) echo vax-dec-vms ; exit ;;
+	esac ;;
+    *:XENIX:*:SysV)
+	echo i386-pc-xenix
+	exit ;;
+    i*86:skyos:*:*)
+	echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//'
+	exit ;;
+    i*86:rdos:*:*)
+	echo ${UNAME_MACHINE}-pc-rdos
+	exit ;;
+    i*86:AROS:*:*)
+	echo ${UNAME_MACHINE}-pc-aros
+	exit ;;
+    x86_64:VMkernel:*:*)
+	echo ${UNAME_MACHINE}-unknown-esx
+	exit ;;
+esac
+
+cat >&2 <<EOF
+$0: unable to guess system type
+
+This script, last modified $timestamp, has failed to recognize
+the operating system you are using. It is advised that you
+download the most up to date version of the config scripts from
+
+  http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
+and
+  http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
+
+If the version you run ($0) is already up to date, please
+send the following data and any information you think might be
+pertinent to <config-patches@gnu.org> in order to provide the needed
+information to handle your system.
+
+config.guess timestamp = $timestamp
+
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null`
+/bin/uname -X     = `(/bin/uname -X) 2>/dev/null`
+
+hostinfo               = `(hostinfo) 2>/dev/null`
+/bin/universe          = `(/bin/universe) 2>/dev/null`
+/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null`
+/bin/arch              = `(/bin/arch) 2>/dev/null`
+/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null`
+
+UNAME_MACHINE = ${UNAME_MACHINE}
+UNAME_RELEASE = ${UNAME_RELEASE}
+UNAME_SYSTEM  = ${UNAME_SYSTEM}
+UNAME_VERSION = ${UNAME_VERSION}
+EOF
+
+exit 1
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/config/config.sub
@@ -0,0 +1,1813 @@
+#! /bin/sh
+# Configuration validation subroutine script.
+#   Copyright 1992-2015 Free Software Foundation, Inc.
+
+timestamp='2015-08-20'
+
+# This file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, see <http://www.gnu.org/licenses/>.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that
+# program.  This Exception is an additional permission under section 7
+# of the GNU General Public License, version 3 ("GPLv3").
+
+
+# Please send patches to <config-patches@gnu.org>.
+#
+# Configuration subroutine to validate and canonicalize a configuration type.
+# Supply the specified configuration type as an argument.
+# If it is invalid, we print an error message on stderr and exit with code 1.
+# Otherwise, we print the canonical config type on stdout and succeed.
+
+# You can get the latest version of this script from:
+# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
+
+# This file is supposed to be the same for all GNU packages
+# and recognize all the CPU types, system types and aliases
+# that are meaningful with *any* GNU software.
+# Each package is responsible for reporting which valid configurations
+# it does not support.  The user should be able to distinguish
+# a failure to support a valid configuration from a meaningless
+# configuration.
+
+# The goal of this file is to map all the various variations of a given
+# machine specification into a single specification in the form:
+#	CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
+# or in some cases, the newer four-part form:
+#	CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
+# It is wrong to echo any other type of specification.
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION] CPU-MFR-OPSYS
+       $0 [OPTION] ALIAS
+
+Canonicalize a configuration name.
+
+Operation modes:
+  -h, --help         print this help, then exit
+  -t, --time-stamp   print date of last modification, then exit
+  -v, --version      print version number, then exit
+
+Report bugs and patches to <config-patches@gnu.org>."
+
+version="\
+GNU config.sub ($timestamp)
+
+Copyright 1992-2015 Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions.  There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+  case $1 in
+    --time-stamp | --time* | -t )
+       echo "$timestamp" ; exit ;;
+    --version | -v )
+       echo "$version" ; exit ;;
+    --help | --h* | -h )
+       echo "$usage"; exit ;;
+    -- )     # Stop option processing
+       shift; break ;;
+    - )	# Use stdin as input.
+       break ;;
+    -* )
+       echo "$me: invalid option $1$help"
+       exit 1 ;;
+
+    *local*)
+       # First pass through any local machine types.
+       echo $1
+       exit ;;
+
+    * )
+       break ;;
+  esac
+done
+
+case $# in
+ 0) echo "$me: missing argument$help" >&2
+    exit 1;;
+ 1) ;;
+ *) echo "$me: too many arguments$help" >&2
+    exit 1;;
+esac
+
+# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
+# Here we must recognize all the valid KERNEL-OS combinations.
+maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
+case $maybe_os in
+  nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \
+  linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
+  knetbsd*-gnu* | netbsd*-gnu* | netbsd*-eabi* | \
+  kopensolaris*-gnu* | \
+  storm-chaos* | os2-emx* | rtmk-nova*)
+    os=-$maybe_os
+    basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
+    ;;
+  android-linux)
+    os=-linux-android
+    basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown
+    ;;
+  *)
+    basic_machine=`echo $1 | sed 's/-[^-]*$//'`
+    if [ $basic_machine != $1 ]
+    then os=`echo $1 | sed 's/.*-/-/'`
+    else os=; fi
+    ;;
+esac
+
+### Let's recognize common machines as not being operating systems so
+### that things like config.sub decstation-3100 work.  We also
+### recognize some manufacturers as not being operating systems, so we
+### can provide default operating systems below.
+case $os in
+	-sun*os*)
+		# Prevent following clause from handling this invalid input.
+		;;
+	-dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
+	-att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
+	-unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
+	-convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
+	-c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
+	-harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
+	-apple | -axis | -knuth | -cray | -microblaze*)
+		os=
+		basic_machine=$1
+		;;
+	-bluegene*)
+		os=-cnk
+		;;
+	-sim | -cisco | -oki | -wec | -winbond)
+		os=
+		basic_machine=$1
+		;;
+	-scout)
+		;;
+	-wrs)
+		os=-vxworks
+		basic_machine=$1
+		;;
+	-chorusos*)
+		os=-chorusos
+		basic_machine=$1
+		;;
+	-chorusrdb)
+		os=-chorusrdb
+		basic_machine=$1
+		;;
+	-hiux*)
+		os=-hiuxwe2
+		;;
+	-sco6)
+		os=-sco5v6
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco5)
+		os=-sco3.2v5
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco4)
+		os=-sco3.2v4
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco3.2.[4-9]*)
+		os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco3.2v[4-9]*)
+		# Don't forget version if it is 3.2v4 or newer.
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco5v6*)
+		# Don't forget version if it is 3.2v4 or newer.
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco*)
+		os=-sco3.2v2
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-udk*)
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-isc)
+		os=-isc2.2
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-clix*)
+		basic_machine=clipper-intergraph
+		;;
+	-isc*)
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-lynx*178)
+		os=-lynxos178
+		;;
+	-lynx*5)
+		os=-lynxos5
+		;;
+	-lynx*)
+		os=-lynxos
+		;;
+	-ptx*)
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
+		;;
+	-windowsnt*)
+		os=`echo $os | sed -e 's/windowsnt/winnt/'`
+		;;
+	-psos*)
+		os=-psos
+		;;
+	-mint | -mint[0-9]*)
+		basic_machine=m68k-atari
+		os=-mint
+		;;
+esac
+
+# Decode aliases for certain CPU-COMPANY combinations.
+case $basic_machine in
+	# Recognize the basic CPU types without company name.
+	# Some are omitted here because they have special meanings below.
+	1750a | 580 \
+	| a29k \
+	| aarch64 | aarch64_be \
+	| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
+	| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
+	| am33_2.0 \
+	| arc | arceb \
+	| arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \
+	| avr | avr32 \
+	| ba \
+	| be32 | be64 \
+	| bfin \
+	| c4x | c8051 | clipper \
+	| d10v | d30v | dlx | dsp16xx \
+	| e2k | epiphany \
+	| fido | fr30 | frv | ft32 \
+	| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
+	| hexagon \
+	| i370 | i860 | i960 | ia64 \
+	| ip2k | iq2000 \
+	| k1om \
+	| le32 | le64 \
+	| lm32 \
+	| m32c | m32r | m32rle | m68000 | m68k | m88k \
+	| maxq | mb | microblaze | microblazeel | mcore | mep | metag \
+	| mips | mipsbe | mipseb | mipsel | mipsle \
+	| mips16 \
+	| mips64 | mips64el \
+	| mips64octeon | mips64octeonel \
+	| mips64orion | mips64orionel \
+	| mips64r5900 | mips64r5900el \
+	| mips64vr | mips64vrel \
+	| mips64vr4100 | mips64vr4100el \
+	| mips64vr4300 | mips64vr4300el \
+	| mips64vr5000 | mips64vr5000el \
+	| mips64vr5900 | mips64vr5900el \
+	| mipsisa32 | mipsisa32el \
+	| mipsisa32r2 | mipsisa32r2el \
+	| mipsisa32r6 | mipsisa32r6el \
+	| mipsisa64 | mipsisa64el \
+	| mipsisa64r2 | mipsisa64r2el \
+	| mipsisa64r6 | mipsisa64r6el \
+	| mipsisa64sb1 | mipsisa64sb1el \
+	| mipsisa64sr71k | mipsisa64sr71kel \
+	| mipsr5900 | mipsr5900el \
+	| mipstx39 | mipstx39el \
+	| mn10200 | mn10300 \
+	| moxie \
+	| mt \
+	| msp430 \
+	| nds32 | nds32le | nds32be \
+	| nios | nios2 | nios2eb | nios2el \
+	| ns16k | ns32k \
+	| open8 | or1k | or1knd | or32 \
+	| pdp10 | pdp11 | pj | pjl \
+	| powerpc | powerpc64 | powerpc64le | powerpcle \
+	| pyramid \
+	| riscv32 | riscv64 \
+	| rl78 | rx \
+	| score \
+	| sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[234]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
+	| sh64 | sh64le \
+	| sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
+	| sparcv8 | sparcv9 | sparcv9b | sparcv9v \
+	| spu \
+	| tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \
+	| ubicom32 \
+	| v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \
+	| visium \
+	| we32k \
+	| x86 | xc16x | xstormy16 | xtensa \
+	| z8k | z80)
+		basic_machine=$basic_machine-unknown
+		;;
+	c54x)
+		basic_machine=tic54x-unknown
+		;;
+	c55x)
+		basic_machine=tic55x-unknown
+		;;
+	c6x)
+		basic_machine=tic6x-unknown
+		;;
+	leon|leon[3-9])
+		basic_machine=sparc-$basic_machine
+		;;
+	m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip)
+		basic_machine=$basic_machine-unknown
+		os=-none
+		;;
+	m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
+		;;
+	ms1)
+		basic_machine=mt-unknown
+		;;
+
+	strongarm | thumb | xscale)
+		basic_machine=arm-unknown
+		;;
+	xgate)
+		basic_machine=$basic_machine-unknown
+		os=-none
+		;;
+	xscaleeb)
+		basic_machine=armeb-unknown
+		;;
+
+	xscaleel)
+		basic_machine=armel-unknown
+		;;
+
+	# We use `pc' rather than `unknown'
+	# because (1) that's what they normally are, and
+	# (2) the word "unknown" tends to confuse beginning users.
+	i*86 | x86_64)
+	  basic_machine=$basic_machine-pc
+	  ;;
+	# Object if more than one company name word.
+	*-*-*)
+		echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+		exit 1
+		;;
+	# Recognize the basic CPU types with company name.
+	580-* \
+	| a29k-* \
+	| aarch64-* | aarch64_be-* \
+	| alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
+	| alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
+	| alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \
+	| arm-*  | armbe-* | armle-* | armeb-* | armv*-* \
+	| avr-* | avr32-* \
+	| ba-* \
+	| be32-* | be64-* \
+	| bfin-* | bs2000-* \
+	| c[123]* | c30-* | [cjt]90-* | c4x-* \
+	| c8051-* | clipper-* | craynv-* | cydra-* \
+	| d10v-* | d30v-* | dlx-* \
+	| e2k-* | elxsi-* \
+	| f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
+	| h8300-* | h8500-* \
+	| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
+	| hexagon-* \
+	| i*86-* | i860-* | i960-* | ia64-* \
+	| ip2k-* | iq2000-* \
+	| k1om-* \
+	| le32-* | le64-* \
+	| lm32-* \
+	| m32c-* | m32r-* | m32rle-* \
+	| m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
+	| m88110-* | m88k-* | maxq-* | mcore-* | metag-* \
+	| microblaze-* | microblazeel-* \
+	| mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
+	| mips16-* \
+	| mips64-* | mips64el-* \
+	| mips64octeon-* | mips64octeonel-* \
+	| mips64orion-* | mips64orionel-* \
+	| mips64r5900-* | mips64r5900el-* \
+	| mips64vr-* | mips64vrel-* \
+	| mips64vr4100-* | mips64vr4100el-* \
+	| mips64vr4300-* | mips64vr4300el-* \
+	| mips64vr5000-* | mips64vr5000el-* \
+	| mips64vr5900-* | mips64vr5900el-* \
+	| mipsisa32-* | mipsisa32el-* \
+	| mipsisa32r2-* | mipsisa32r2el-* \
+	| mipsisa32r6-* | mipsisa32r6el-* \
+	| mipsisa64-* | mipsisa64el-* \
+	| mipsisa64r2-* | mipsisa64r2el-* \
+	| mipsisa64r6-* | mipsisa64r6el-* \
+	| mipsisa64sb1-* | mipsisa64sb1el-* \
+	| mipsisa64sr71k-* | mipsisa64sr71kel-* \
+	| mipsr5900-* | mipsr5900el-* \
+	| mipstx39-* | mipstx39el-* \
+	| mmix-* \
+	| mt-* \
+	| msp430-* \
+	| nds32-* | nds32le-* | nds32be-* \
+	| nios-* | nios2-* | nios2eb-* | nios2el-* \
+	| none-* | np1-* | ns16k-* | ns32k-* \
+	| open8-* \
+	| or1k*-* \
+	| orion-* \
+	| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
+	| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \
+	| pyramid-* \
+	| riscv32-* | riscv64-* \
+	| rl78-* | romp-* | rs6000-* | rx-* \
+	| sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
+	| shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
+	| sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
+	| sparclite-* \
+	| sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx*-* \
+	| tahoe-* \
+	| tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
+	| tile*-* \
+	| tron-* \
+	| ubicom32-* \
+	| v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \
+	| vax-* \
+	| visium-* \
+	| we32k-* \
+	| x86-* | x86_64-* | xc16x-* | xps100-* \
+	| xstormy16-* | xtensa*-* \
+	| ymp-* \
+	| z8k-* | z80-*)
+		;;
+	# Recognize the basic CPU types without company name, with glob match.
+	xtensa*)
+		basic_machine=$basic_machine-unknown
+		;;
+	# Recognize the various machine names and aliases which stand
+	# for a CPU type and a company and sometimes even an OS.
+	386bsd)
+		basic_machine=i386-unknown
+		os=-bsd
+		;;
+	3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
+		basic_machine=m68000-att
+		;;
+	3b*)
+		basic_machine=we32k-att
+		;;
+	a29khif)
+		basic_machine=a29k-amd
+		os=-udi
+		;;
+	abacus)
+		basic_machine=abacus-unknown
+		;;
+	adobe68k)
+		basic_machine=m68010-adobe
+		os=-scout
+		;;
+	alliant | fx80)
+		basic_machine=fx80-alliant
+		;;
+	altos | altos3068)
+		basic_machine=m68k-altos
+		;;
+	am29k)
+		basic_machine=a29k-none
+		os=-bsd
+		;;
+	amd64)
+		basic_machine=x86_64-pc
+		;;
+	amd64-*)
+		basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	amdahl)
+		basic_machine=580-amdahl
+		os=-sysv
+		;;
+	amiga | amiga-*)
+		basic_machine=m68k-unknown
+		;;
+	amigaos | amigados)
+		basic_machine=m68k-unknown
+		os=-amigaos
+		;;
+	amigaunix | amix)
+		basic_machine=m68k-unknown
+		os=-sysv4
+		;;
+	apollo68)
+		basic_machine=m68k-apollo
+		os=-sysv
+		;;
+	apollo68bsd)
+		basic_machine=m68k-apollo
+		os=-bsd
+		;;
+	aros)
+		basic_machine=i386-pc
+		os=-aros
+		;;
+        asmjs)
+		basic_machine=asmjs-unknown
+		;;
+	aux)
+		basic_machine=m68k-apple
+		os=-aux
+		;;
+	balance)
+		basic_machine=ns32k-sequent
+		os=-dynix
+		;;
+	blackfin)
+		basic_machine=bfin-unknown
+		os=-linux
+		;;
+	blackfin-*)
+		basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'`
+		os=-linux
+		;;
+	bluegene*)
+		basic_machine=powerpc-ibm
+		os=-cnk
+		;;
+	c54x-*)
+		basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	c55x-*)
+		basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	c6x-*)
+		basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	c90)
+		basic_machine=c90-cray
+		os=-unicos
+		;;
+	cegcc)
+		basic_machine=arm-unknown
+		os=-cegcc
+		;;
+	convex-c1)
+		basic_machine=c1-convex
+		os=-bsd
+		;;
+	convex-c2)
+		basic_machine=c2-convex
+		os=-bsd
+		;;
+	convex-c32)
+		basic_machine=c32-convex
+		os=-bsd
+		;;
+	convex-c34)
+		basic_machine=c34-convex
+		os=-bsd
+		;;
+	convex-c38)
+		basic_machine=c38-convex
+		os=-bsd
+		;;
+	cray | j90)
+		basic_machine=j90-cray
+		os=-unicos
+		;;
+	craynv)
+		basic_machine=craynv-cray
+		os=-unicosmp
+		;;
+	cr16 | cr16-*)
+		basic_machine=cr16-unknown
+		os=-elf
+		;;
+	crds | unos)
+		basic_machine=m68k-crds
+		;;
+	crisv32 | crisv32-* | etraxfs*)
+		basic_machine=crisv32-axis
+		;;
+	cris | cris-* | etrax*)
+		basic_machine=cris-axis
+		;;
+	crx)
+		basic_machine=crx-unknown
+		os=-elf
+		;;
+	da30 | da30-*)
+		basic_machine=m68k-da30
+		;;
+	decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
+		basic_machine=mips-dec
+		;;
+	decsystem10* | dec10*)
+		basic_machine=pdp10-dec
+		os=-tops10
+		;;
+	decsystem20* | dec20*)
+		basic_machine=pdp10-dec
+		os=-tops20
+		;;
+	delta | 3300 | motorola-3300 | motorola-delta \
+	      | 3300-motorola | delta-motorola)
+		basic_machine=m68k-motorola
+		;;
+	delta88)
+		basic_machine=m88k-motorola
+		os=-sysv3
+		;;
+	dicos)
+		basic_machine=i686-pc
+		os=-dicos
+		;;
+	djgpp)
+		basic_machine=i586-pc
+		os=-msdosdjgpp
+		;;
+	dpx20 | dpx20-*)
+		basic_machine=rs6000-bull
+		os=-bosx
+		;;
+	dpx2* | dpx2*-bull)
+		basic_machine=m68k-bull
+		os=-sysv3
+		;;
+	ebmon29k)
+		basic_machine=a29k-amd
+		os=-ebmon
+		;;
+	elxsi)
+		basic_machine=elxsi-elxsi
+		os=-bsd
+		;;
+	encore | umax | mmax)
+		basic_machine=ns32k-encore
+		;;
+	es1800 | OSE68k | ose68k | ose | OSE)
+		basic_machine=m68k-ericsson
+		os=-ose
+		;;
+	fx2800)
+		basic_machine=i860-alliant
+		;;
+	genix)
+		basic_machine=ns32k-ns
+		;;
+	gmicro)
+		basic_machine=tron-gmicro
+		os=-sysv
+		;;
+	go32)
+		basic_machine=i386-pc
+		os=-go32
+		;;
+	h3050r* | hiux*)
+		basic_machine=hppa1.1-hitachi
+		os=-hiuxwe2
+		;;
+	h8300hms)
+		basic_machine=h8300-hitachi
+		os=-hms
+		;;
+	h8300xray)
+		basic_machine=h8300-hitachi
+		os=-xray
+		;;
+	h8500hms)
+		basic_machine=h8500-hitachi
+		os=-hms
+		;;
+	harris)
+		basic_machine=m88k-harris
+		os=-sysv3
+		;;
+	hp300-*)
+		basic_machine=m68k-hp
+		;;
+	hp300bsd)
+		basic_machine=m68k-hp
+		os=-bsd
+		;;
+	hp300hpux)
+		basic_machine=m68k-hp
+		os=-hpux
+		;;
+	hp3k9[0-9][0-9] | hp9[0-9][0-9])
+		basic_machine=hppa1.0-hp
+		;;
+	hp9k2[0-9][0-9] | hp9k31[0-9])
+		basic_machine=m68000-hp
+		;;
+	hp9k3[2-9][0-9])
+		basic_machine=m68k-hp
+		;;
+	hp9k6[0-9][0-9] | hp6[0-9][0-9])
+		basic_machine=hppa1.0-hp
+		;;
+	hp9k7[0-79][0-9] | hp7[0-79][0-9])
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k78[0-9] | hp78[0-9])
+		# FIXME: really hppa2.0-hp
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)
+		# FIXME: really hppa2.0-hp
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k8[0-9][13679] | hp8[0-9][13679])
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k8[0-9][0-9] | hp8[0-9][0-9])
+		basic_machine=hppa1.0-hp
+		;;
+	hppa-next)
+		os=-nextstep3
+		;;
+	hppaosf)
+		basic_machine=hppa1.1-hp
+		os=-osf
+		;;
+	hppro)
+		basic_machine=hppa1.1-hp
+		os=-proelf
+		;;
+	i370-ibm* | ibm*)
+		basic_machine=i370-ibm
+		;;
+	i*86v32)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-sysv32
+		;;
+	i*86v4*)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-sysv4
+		;;
+	i*86v)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-sysv
+		;;
+	i*86sol2)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-solaris2
+		;;
+	i386mach)
+		basic_machine=i386-mach
+		os=-mach
+		;;
+	i386-vsta | vsta)
+		basic_machine=i386-unknown
+		os=-vsta
+		;;
+	iris | iris4d)
+		basic_machine=mips-sgi
+		case $os in
+		    -irix*)
+			;;
+		    *)
+			os=-irix4
+			;;
+		esac
+		;;
+	isi68 | isi)
+		basic_machine=m68k-isi
+		os=-sysv
+		;;
+	leon-*|leon[3-9]-*)
+		basic_machine=sparc-`echo $basic_machine | sed 's/-.*//'`
+		;;
+	m68knommu)
+		basic_machine=m68k-unknown
+		os=-linux
+		;;
+	m68knommu-*)
+		basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'`
+		os=-linux
+		;;
+	m88k-omron*)
+		basic_machine=m88k-omron
+		;;
+	magnum | m3230)
+		basic_machine=mips-mips
+		os=-sysv
+		;;
+	merlin)
+		basic_machine=ns32k-utek
+		os=-sysv
+		;;
+	microblaze*)
+		basic_machine=microblaze-xilinx
+		;;
+	mingw64)
+		basic_machine=x86_64-pc
+		os=-mingw64
+		;;
+	mingw32)
+		basic_machine=i686-pc
+		os=-mingw32
+		;;
+	mingw32ce)
+		basic_machine=arm-unknown
+		os=-mingw32ce
+		;;
+	miniframe)
+		basic_machine=m68000-convergent
+		;;
+	*mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*)
+		basic_machine=m68k-atari
+		os=-mint
+		;;
+	mips3*-*)
+		basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
+		;;
+	mips3*)
+		basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
+		;;
+	monitor)
+		basic_machine=m68k-rom68k
+		os=-coff
+		;;
+	morphos)
+		basic_machine=powerpc-unknown
+		os=-morphos
+		;;
+	moxiebox)
+		basic_machine=moxie-unknown
+		os=-moxiebox
+		;;
+	msdos)
+		basic_machine=i386-pc
+		os=-msdos
+		;;
+	ms1-*)
+		basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`
+		;;
+	msys)
+		basic_machine=i686-pc
+		os=-msys
+		;;
+	mvs)
+		basic_machine=i370-ibm
+		os=-mvs
+		;;
+	nacl)
+		basic_machine=le32-unknown
+		os=-nacl
+		;;
+	ncr3000)
+		basic_machine=i486-ncr
+		os=-sysv4
+		;;
+	netbsd386)
+		basic_machine=i386-unknown
+		os=-netbsd
+		;;
+	netwinder)
+		basic_machine=armv4l-rebel
+		os=-linux
+		;;
+	news | news700 | news800 | news900)
+		basic_machine=m68k-sony
+		os=-newsos
+		;;
+	news1000)
+		basic_machine=m68030-sony
+		os=-newsos
+		;;
+	news-3600 | risc-news)
+		basic_machine=mips-sony
+		os=-newsos
+		;;
+	necv70)
+		basic_machine=v70-nec
+		os=-sysv
+		;;
+	next | m*-next )
+		basic_machine=m68k-next
+		case $os in
+		    -nextstep* )
+			;;
+		    -ns2*)
+		      os=-nextstep2
+			;;
+		    *)
+		      os=-nextstep3
+			;;
+		esac
+		;;
+	nh3000)
+		basic_machine=m68k-harris
+		os=-cxux
+		;;
+	nh[45]000)
+		basic_machine=m88k-harris
+		os=-cxux
+		;;
+	nindy960)
+		basic_machine=i960-intel
+		os=-nindy
+		;;
+	mon960)
+		basic_machine=i960-intel
+		os=-mon960
+		;;
+	nonstopux)
+		basic_machine=mips-compaq
+		os=-nonstopux
+		;;
+	np1)
+		basic_machine=np1-gould
+		;;
+	neo-tandem)
+		basic_machine=neo-tandem
+		;;
+	nse-tandem)
+		basic_machine=nse-tandem
+		;;
+	nsr-tandem)
+		basic_machine=nsr-tandem
+		;;
+	op50n-* | op60c-*)
+		basic_machine=hppa1.1-oki
+		os=-proelf
+		;;
+	openrisc | openrisc-*)
+		basic_machine=or32-unknown
+		;;
+	os400)
+		basic_machine=powerpc-ibm
+		os=-os400
+		;;
+	OSE68000 | ose68000)
+		basic_machine=m68000-ericsson
+		os=-ose
+		;;
+	os68k)
+		basic_machine=m68k-none
+		os=-os68k
+		;;
+	pa-hitachi)
+		basic_machine=hppa1.1-hitachi
+		os=-hiuxwe2
+		;;
+	paragon)
+		basic_machine=i860-intel
+		os=-osf
+		;;
+	parisc)
+		basic_machine=hppa-unknown
+		os=-linux
+		;;
+	parisc-*)
+		basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'`
+		os=-linux
+		;;
+	pbd)
+		basic_machine=sparc-tti
+		;;
+	pbb)
+		basic_machine=m68k-tti
+		;;
+	pc532 | pc532-*)
+		basic_machine=ns32k-pc532
+		;;
+	pc98)
+		basic_machine=i386-pc
+		;;
+	pc98-*)
+		basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentium | p5 | k5 | k6 | nexgen | viac3)
+		basic_machine=i586-pc
+		;;
+	pentiumpro | p6 | 6x86 | athlon | athlon_*)
+		basic_machine=i686-pc
+		;;
+	pentiumii | pentium2 | pentiumiii | pentium3)
+		basic_machine=i686-pc
+		;;
+	pentium4)
+		basic_machine=i786-pc
+		;;
+	pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
+		basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentiumpro-* | p6-* | 6x86-* | athlon-*)
+		basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
+		basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentium4-*)
+		basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pn)
+		basic_machine=pn-gould
+		;;
+	power)	basic_machine=power-ibm
+		;;
+	ppc | ppcbe)	basic_machine=powerpc-unknown
+		;;
+	ppc-* | ppcbe-*)
+		basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ppcle | powerpclittle | ppc-le | powerpc-little)
+		basic_machine=powerpcle-unknown
+		;;
+	ppcle-* | powerpclittle-*)
+		basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ppc64)	basic_machine=powerpc64-unknown
+		;;
+	ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ppc64le | powerpc64little | ppc64-le | powerpc64-little)
+		basic_machine=powerpc64le-unknown
+		;;
+	ppc64le-* | powerpc64little-*)
+		basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ps2)
+		basic_machine=i386-ibm
+		;;
+	pw32)
+		basic_machine=i586-unknown
+		os=-pw32
+		;;
+	rdos | rdos64)
+		basic_machine=x86_64-pc
+		os=-rdos
+		;;
+	rdos32)
+		basic_machine=i386-pc
+		os=-rdos
+		;;
+	rom68k)
+		basic_machine=m68k-rom68k
+		os=-coff
+		;;
+	rm[46]00)
+		basic_machine=mips-siemens
+		;;
+	rtpc | rtpc-*)
+		basic_machine=romp-ibm
+		;;
+	s390 | s390-*)
+		basic_machine=s390-ibm
+		;;
+	s390x | s390x-*)
+		basic_machine=s390x-ibm
+		;;
+	sa29200)
+		basic_machine=a29k-amd
+		os=-udi
+		;;
+	sb1)
+		basic_machine=mipsisa64sb1-unknown
+		;;
+	sb1el)
+		basic_machine=mipsisa64sb1el-unknown
+		;;
+	sde)
+		basic_machine=mipsisa32-sde
+		os=-elf
+		;;
+	sei)
+		basic_machine=mips-sei
+		os=-seiux
+		;;
+	sequent)
+		basic_machine=i386-sequent
+		;;
+	sh)
+		basic_machine=sh-hitachi
+		os=-hms
+		;;
+	sh5el)
+		basic_machine=sh5le-unknown
+		;;
+	sh64)
+		basic_machine=sh64-unknown
+		;;
+	sparclite-wrs | simso-wrs)
+		basic_machine=sparclite-wrs
+		os=-vxworks
+		;;
+	sps7)
+		basic_machine=m68k-bull
+		os=-sysv2
+		;;
+	spur)
+		basic_machine=spur-unknown
+		;;
+	st2000)
+		basic_machine=m68k-tandem
+		;;
+	stratus)
+		basic_machine=i860-stratus
+		os=-sysv4
+		;;
+	strongarm-* | thumb-*)
+		basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	sun2)
+		basic_machine=m68000-sun
+		;;
+	sun2os3)
+		basic_machine=m68000-sun
+		os=-sunos3
+		;;
+	sun2os4)
+		basic_machine=m68000-sun
+		os=-sunos4
+		;;
+	sun3os3)
+		basic_machine=m68k-sun
+		os=-sunos3
+		;;
+	sun3os4)
+		basic_machine=m68k-sun
+		os=-sunos4
+		;;
+	sun4os3)
+		basic_machine=sparc-sun
+		os=-sunos3
+		;;
+	sun4os4)
+		basic_machine=sparc-sun
+		os=-sunos4
+		;;
+	sun4sol2)
+		basic_machine=sparc-sun
+		os=-solaris2
+		;;
+	sun3 | sun3-*)
+		basic_machine=m68k-sun
+		;;
+	sun4)
+		basic_machine=sparc-sun
+		;;
+	sun386 | sun386i | roadrunner)
+		basic_machine=i386-sun
+		;;
+	sv1)
+		basic_machine=sv1-cray
+		os=-unicos
+		;;
+	symmetry)
+		basic_machine=i386-sequent
+		os=-dynix
+		;;
+	t3e)
+		basic_machine=alphaev5-cray
+		os=-unicos
+		;;
+	t90)
+		basic_machine=t90-cray
+		os=-unicos
+		;;
+	tile*)
+		basic_machine=$basic_machine-unknown
+		os=-linux-gnu
+		;;
+	tx39)
+		basic_machine=mipstx39-unknown
+		;;
+	tx39el)
+		basic_machine=mipstx39el-unknown
+		;;
+	toad1)
+		basic_machine=pdp10-xkl
+		os=-tops20
+		;;
+	tower | tower-32)
+		basic_machine=m68k-ncr
+		;;
+	tpf)
+		basic_machine=s390x-ibm
+		os=-tpf
+		;;
+	udi29k)
+		basic_machine=a29k-amd
+		os=-udi
+		;;
+	ultra3)
+		basic_machine=a29k-nyu
+		os=-sym1
+		;;
+	v810 | necv810)
+		basic_machine=v810-nec
+		os=-none
+		;;
+	vaxv)
+		basic_machine=vax-dec
+		os=-sysv
+		;;
+	vms)
+		basic_machine=vax-dec
+		os=-vms
+		;;
+	vpp*|vx|vx-*)
+		basic_machine=f301-fujitsu
+		;;
+	vxworks960)
+		basic_machine=i960-wrs
+		os=-vxworks
+		;;
+	vxworks68)
+		basic_machine=m68k-wrs
+		os=-vxworks
+		;;
+	vxworks29k)
+		basic_machine=a29k-wrs
+		os=-vxworks
+		;;
+	w65*)
+		basic_machine=w65-wdc
+		os=-none
+		;;
+	w89k-*)
+		basic_machine=hppa1.1-winbond
+		os=-proelf
+		;;
+	xbox)
+		basic_machine=i686-pc
+		os=-mingw32
+		;;
+	xps | xps100)
+		basic_machine=xps100-honeywell
+		;;
+	xscale-* | xscalee[bl]-*)
+		basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'`
+		;;
+	ymp)
+		basic_machine=ymp-cray
+		os=-unicos
+		;;
+	z8k-*-coff)
+		basic_machine=z8k-unknown
+		os=-sim
+		;;
+	z80-*-coff)
+		basic_machine=z80-unknown
+		os=-sim
+		;;
+	none)
+		basic_machine=none-none
+		os=-none
+		;;
+
+# Here we handle the default manufacturer of certain CPU types.  It is in
+# some cases the only manufacturer, in others, it is the most popular.
+	w89k)
+		basic_machine=hppa1.1-winbond
+		;;
+	op50n)
+		basic_machine=hppa1.1-oki
+		;;
+	op60c)
+		basic_machine=hppa1.1-oki
+		;;
+	romp)
+		basic_machine=romp-ibm
+		;;
+	mmix)
+		basic_machine=mmix-knuth
+		;;
+	rs6000)
+		basic_machine=rs6000-ibm
+		;;
+	vax)
+		basic_machine=vax-dec
+		;;
+	pdp10)
+		# there are many clones, so DEC is not a safe bet
+		basic_machine=pdp10-unknown
+		;;
+	pdp11)
+		basic_machine=pdp11-dec
+		;;
+	we32k)
+		basic_machine=we32k-att
+		;;
+	sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele)
+		basic_machine=sh-unknown
+		;;
+	sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v)
+		basic_machine=sparc-sun
+		;;
+	cydra)
+		basic_machine=cydra-cydrome
+		;;
+	orion)
+		basic_machine=orion-highlevel
+		;;
+	orion105)
+		basic_machine=clipper-highlevel
+		;;
+	mac | mpw | mac-mpw)
+		basic_machine=m68k-apple
+		;;
+	pmac | pmac-mpw)
+		basic_machine=powerpc-apple
+		;;
+	*-unknown)
+		# Make sure to match an already-canonicalized machine name.
+		;;
+	*)
+		echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+		exit 1
+		;;
+esac
+
+# Here we canonicalize certain aliases for manufacturers.
+case $basic_machine in
+	*-digital*)
+		basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
+		;;
+	*-commodore*)
+		basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
+		;;
+	*)
+		;;
+esac
+
+# Decode manufacturer-specific aliases for certain operating systems.
+
+if [ x"$os" != x"" ]
+then
+case $os in
+	# First match some system type aliases
+	# that might get confused with valid system types.
+	# -solaris* is a basic system type, with this one exception.
+	-auroraux)
+		os=-auroraux
+		;;
+	-solaris1 | -solaris1.*)
+		os=`echo $os | sed -e 's|solaris1|sunos4|'`
+		;;
+	-solaris)
+		os=-solaris2
+		;;
+	-svr4*)
+		os=-sysv4
+		;;
+	-unixware*)
+		os=-sysv4.2uw
+		;;
+	-gnu/linux*)
+		os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
+		;;
+	# First accept the basic system types.
+	# The portable systems comes first.
+	# Each alternative MUST END IN A *, to match a version number.
+	# -sysv* is not here because it comes later, after sysvr4.
+	-gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
+	      | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\
+	      | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \
+	      | -sym* | -kopensolaris* | -plan9* \
+	      | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
+	      | -aos* | -aros* | -cloudabi* | -sortix* \
+	      | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
+	      | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
+	      | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
+	      | -bitrig* | -openbsd* | -solidbsd* \
+	      | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
+	      | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
+	      | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
+	      | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
+	      | -chorusos* | -chorusrdb* | -cegcc* \
+	      | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
+	      | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \
+	      | -linux-newlib* | -linux-musl* | -linux-uclibc* \
+	      | -uxpv* | -beos* | -mpeix* | -udk* | -moxiebox* \
+	      | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
+	      | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
+	      | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
+	      | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
+	      | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
+	      | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
+	      | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* | -tirtos*)
+	# Remember, each alternative MUST END IN *, to match a version number.
+		;;
+	-qnx*)
+		case $basic_machine in
+		    x86-* | i*86-*)
+			;;
+		    *)
+			os=-nto$os
+			;;
+		esac
+		;;
+	-nto-qnx*)
+		;;
+	-nto*)
+		os=`echo $os | sed -e 's|nto|nto-qnx|'`
+		;;
+	-sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
+	      | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \
+	      | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
+		;;
+	-mac*)
+		os=`echo $os | sed -e 's|mac|macos|'`
+		;;
+	-linux-dietlibc)
+		os=-linux-dietlibc
+		;;
+	-linux*)
+		os=`echo $os | sed -e 's|linux|linux-gnu|'`
+		;;
+	-sunos5*)
+		os=`echo $os | sed -e 's|sunos5|solaris2|'`
+		;;
+	-sunos6*)
+		os=`echo $os | sed -e 's|sunos6|solaris3|'`
+		;;
+	-opened*)
+		os=-openedition
+		;;
+	-os400*)
+		os=-os400
+		;;
+	-wince*)
+		os=-wince
+		;;
+	-osfrose*)
+		os=-osfrose
+		;;
+	-osf*)
+		os=-osf
+		;;
+	-utek*)
+		os=-bsd
+		;;
+	-dynix*)
+		os=-bsd
+		;;
+	-acis*)
+		os=-aos
+		;;
+	-atheos*)
+		os=-atheos
+		;;
+	-syllable*)
+		os=-syllable
+		;;
+	-386bsd)
+		os=-bsd
+		;;
+	-ctix* | -uts*)
+		os=-sysv
+		;;
+	-nova*)
+		os=-rtmk-nova
+		;;
+	-ns2 )
+		os=-nextstep2
+		;;
+	-nsk*)
+		os=-nsk
+		;;
+	# Preserve the version number of sinix5.
+	-sinix5.*)
+		os=`echo $os | sed -e 's|sinix|sysv|'`
+		;;
+	-sinix*)
+		os=-sysv4
+		;;
+	-tpf*)
+		os=-tpf
+		;;
+	-triton*)
+		os=-sysv3
+		;;
+	-oss*)
+		os=-sysv3
+		;;
+	-svr4)
+		os=-sysv4
+		;;
+	-svr3)
+		os=-sysv3
+		;;
+	-sysvr4)
+		os=-sysv4
+		;;
+	# This must come after -sysvr4.
+	-sysv*)
+		;;
+	-ose*)
+		os=-ose
+		;;
+	-es1800*)
+		os=-ose
+		;;
+	-xenix)
+		os=-xenix
+		;;
+	-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+		os=-mint
+		;;
+	-aros*)
+		os=-aros
+		;;
+	-zvmoe)
+		os=-zvmoe
+		;;
+	-dicos*)
+		os=-dicos
+		;;
+	-nacl*)
+		;;
+	-none)
+		;;
+	*)
+		# Get rid of the `-' at the beginning of $os.
+		os=`echo $os | sed 's/[^-]*-//'`
+		echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
+		exit 1
+		;;
+esac
+else
+
+# Here we handle the default operating systems that come with various machines.
+# The value should be what the vendor currently ships out the door with their
+# machine or put another way, the most popular os provided with the machine.
+
+# Note that if you're going to try to match "-MANUFACTURER" here (say,
+# "-sun"), then you have to tell the case statement up towards the top
+# that MANUFACTURER isn't an operating system.  Otherwise, code above
+# will signal an error saying that MANUFACTURER isn't an operating
+# system, and we'll never get to this point.
+
+case $basic_machine in
+	score-*)
+		os=-elf
+		;;
+	spu-*)
+		os=-elf
+		;;
+	*-acorn)
+		os=-riscix1.2
+		;;
+	arm*-rebel)
+		os=-linux
+		;;
+	arm*-semi)
+		os=-aout
+		;;
+	c4x-* | tic4x-*)
+		os=-coff
+		;;
+	c8051-*)
+		os=-elf
+		;;
+	hexagon-*)
+		os=-elf
+		;;
+	tic54x-*)
+		os=-coff
+		;;
+	tic55x-*)
+		os=-coff
+		;;
+	tic6x-*)
+		os=-coff
+		;;
+	# This must come before the *-dec entry.
+	pdp10-*)
+		os=-tops20
+		;;
+	pdp11-*)
+		os=-none
+		;;
+	*-dec | vax-*)
+		os=-ultrix4.2
+		;;
+	m68*-apollo)
+		os=-domain
+		;;
+	i386-sun)
+		os=-sunos4.0.2
+		;;
+	m68000-sun)
+		os=-sunos3
+		;;
+	m68*-cisco)
+		os=-aout
+		;;
+	mep-*)
+		os=-elf
+		;;
+	mips*-cisco)
+		os=-elf
+		;;
+	mips*-*)
+		os=-elf
+		;;
+	or32-*)
+		os=-coff
+		;;
+	*-tti)	# must be before sparc entry or we get the wrong os.
+		os=-sysv3
+		;;
+	sparc-* | *-sun)
+		os=-sunos4.1.1
+		;;
+	*-be)
+		os=-beos
+		;;
+	*-haiku)
+		os=-haiku
+		;;
+	*-ibm)
+		os=-aix
+		;;
+	*-knuth)
+		os=-mmixware
+		;;
+	*-wec)
+		os=-proelf
+		;;
+	*-winbond)
+		os=-proelf
+		;;
+	*-oki)
+		os=-proelf
+		;;
+	*-hp)
+		os=-hpux
+		;;
+	*-hitachi)
+		os=-hiux
+		;;
+	i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
+		os=-sysv
+		;;
+	*-cbm)
+		os=-amigaos
+		;;
+	*-dg)
+		os=-dgux
+		;;
+	*-dolphin)
+		os=-sysv3
+		;;
+	m68k-ccur)
+		os=-rtu
+		;;
+	m88k-omron*)
+		os=-luna
+		;;
+	*-next )
+		os=-nextstep
+		;;
+	*-sequent)
+		os=-ptx
+		;;
+	*-crds)
+		os=-unos
+		;;
+	*-ns)
+		os=-genix
+		;;
+	i370-*)
+		os=-mvs
+		;;
+	*-next)
+		os=-nextstep3
+		;;
+	*-gould)
+		os=-sysv
+		;;
+	*-highlevel)
+		os=-bsd
+		;;
+	*-encore)
+		os=-bsd
+		;;
+	*-sgi)
+		os=-irix
+		;;
+	*-siemens)
+		os=-sysv4
+		;;
+	*-masscomp)
+		os=-rtu
+		;;
+	f30[01]-fujitsu | f700-fujitsu)
+		os=-uxpv
+		;;
+	*-rom68k)
+		os=-coff
+		;;
+	*-*bug)
+		os=-coff
+		;;
+	*-apple)
+		os=-macos
+		;;
+	*-atari*)
+		os=-mint
+		;;
+	*)
+		os=-none
+		;;
+esac
+fi
+
+# Here we handle the case where we know the os, and the CPU type, but not the
+# manufacturer.  We pick the logical manufacturer.
+vendor=unknown
+case $basic_machine in
+	*-unknown)
+		case $os in
+			-riscix*)
+				vendor=acorn
+				;;
+			-sunos*)
+				vendor=sun
+				;;
+			-cnk*|-aix*)
+				vendor=ibm
+				;;
+			-beos*)
+				vendor=be
+				;;
+			-hpux*)
+				vendor=hp
+				;;
+			-mpeix*)
+				vendor=hp
+				;;
+			-hiux*)
+				vendor=hitachi
+				;;
+			-unos*)
+				vendor=crds
+				;;
+			-dgux*)
+				vendor=dg
+				;;
+			-luna*)
+				vendor=omron
+				;;
+			-genix*)
+				vendor=ns
+				;;
+			-mvs* | -opened*)
+				vendor=ibm
+				;;
+			-os400*)
+				vendor=ibm
+				;;
+			-ptx*)
+				vendor=sequent
+				;;
+			-tpf*)
+				vendor=ibm
+				;;
+			-vxsim* | -vxworks* | -windiss*)
+				vendor=wrs
+				;;
+			-aux*)
+				vendor=apple
+				;;
+			-hms*)
+				vendor=hitachi
+				;;
+			-mpw* | -macos*)
+				vendor=apple
+				;;
+			-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+				vendor=atari
+				;;
+			-vos*)
+				vendor=stratus
+				;;
+		esac
+		basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
+		;;
+esac
+
+echo $basic_machine$os
+exit
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/config/deb.am
@@ -0,0 +1,48 @@
+deb-local:
+	@(if test "${HAVE_DPKGBUILD}" = "no"; then \
+		echo -e "\n" \
+	"*** Required util ${DPKGBUILD} missing.  Please install the\n" \
+        "*** package for your distribution which provides ${DPKGBUILD},\n" \
+	"*** re-run configure, and try again.\n"; \
+                exit 1; \
+	fi; \
+	if test "${HAVE_ALIEN}" = "no"; then \
+		echo -e "\n" \
+	"*** Required util ${ALIEN} missing.  Please install the\n" \
+        "*** package for your distribution which provides ${ALIEN},\n" \
+	"*** re-run configure, and try again.\n"; \
+                exit 1; \
+	fi)
+
+deb-kmod: deb-local rpm-kmod
+if CONFIG_KERNEL
+	name=${PACKAGE}; \
+	version=${VERSION}-${RELEASE}; \
+	arch=`$(RPM) -qp $${name}-kmod-$${version}.src.rpm --qf %{arch} | tail -1`; \
+	pkg1=kmod-$${name}*$${version}.$${arch}.rpm; \
+	fakeroot $(ALIEN) --bump=0 --scripts --to-deb $$pkg1; \
+	$(RM) $$pkg1
+endif
+
+deb-utils: deb-local rpm-utils
+if CONFIG_USER
+	name=${PACKAGE}; \
+	version=${VERSION}-${RELEASE}; \
+	arch=`$(RPM) -qp $${name}-$${version}.src.rpm --qf %{arch} | tail -1`; \
+	pkg1=$${name}-$${version}.$${arch}.rpm; \
+	pkg2=libnvpair1-$${version}.$${arch}.rpm; \
+	pkg3=libuutil1-$${version}.$${arch}.rpm; \
+	pkg4=libzfs2-$${version}.$${arch}.rpm; \
+	pkg5=libzpool2-$${version}.$${arch}.rpm; \
+	pkg6=libzfs2-devel-$${version}.$${arch}.rpm; \
+	pkg7=$${name}-test-$${version}.$${arch}.rpm; \
+	pkg8=$${name}-dracut-$${version}.$${arch}.rpm; \
+	pkg9=$${name}-initramfs-$${version}.$${arch}.rpm; \
+	fakeroot $(ALIEN) --bump=0 --scripts --to-deb \
+	    $$pkg1 $$pkg2 $$pkg3 $$pkg4 $$pkg5 $$pkg6 $$pkg7 \
+	    $$pkg8 $$pkg9;
+	$(RM) $$pkg1 $$pkg2 $$pkg3 $$pkg4 $$pkg5 $$pkg6 $$pkg7 \
+	    $$pkg8 $$pkg9;
+endif
+
+deb: deb-kmod deb-utils
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/config/depcomp
@@ -0,0 +1,791 @@
+#! /bin/sh
+# depcomp - compile a program generating dependencies as side-effects
+
+scriptversion=2013-05-30.07; # UTC
+
+# Copyright (C) 1999-2014 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Originally written by Alexandre Oliva <oliva@dcc.unicamp.br>.
+
+case $1 in
+  '')
+    echo "$0: No command.  Try '$0 --help' for more information." 1>&2
+    exit 1;
+    ;;
+  -h | --h*)
+    cat <<\EOF
+Usage: depcomp [--help] [--version] PROGRAM [ARGS]
+
+Run PROGRAMS ARGS to compile a file, generating dependencies
+as side-effects.
+
+Environment variables:
+  depmode     Dependency tracking mode.
+  source      Source file read by 'PROGRAMS ARGS'.
+  object      Object file output by 'PROGRAMS ARGS'.
+  DEPDIR      directory where to store dependencies.
+  depfile     Dependency file to output.
+  tmpdepfile  Temporary file to use when outputting dependencies.
+  libtool     Whether libtool is used (yes/no).
+
+Report bugs to <bug-automake@gnu.org>.
+EOF
+    exit $?
+    ;;
+  -v | --v*)
+    echo "depcomp $scriptversion"
+    exit $?
+    ;;
+esac
+
+# Get the directory component of the given path, and save it in the
+# global variables '$dir'.  Note that this directory component will
+# be either empty or ending with a '/' character.  This is deliberate.
+set_dir_from ()
+{
+  case $1 in
+    */*) dir=`echo "$1" | sed -e 's|/[^/]*$|/|'`;;
+      *) dir=;;
+  esac
+}
+
+# Get the suffix-stripped basename of the given path, and save it the
+# global variable '$base'.
+set_base_from ()
+{
+  base=`echo "$1" | sed -e 's|^.*/||' -e 's/\.[^.]*$//'`
+}
+
+# If no dependency file was actually created by the compiler invocation,
+# we still have to create a dummy depfile, to avoid errors with the
+# Makefile "include basename.Plo" scheme.
+make_dummy_depfile ()
+{
+  echo "#dummy" > "$depfile"
+}
+
+# Factor out some common post-processing of the generated depfile.
+# Requires the auxiliary global variable '$tmpdepfile' to be set.
+aix_post_process_depfile ()
+{
+  # If the compiler actually managed to produce a dependency file,
+  # post-process it.
+  if test -f "$tmpdepfile"; then
+    # Each line is of the form 'foo.o: dependency.h'.
+    # Do two passes, one to just change these to
+    #   $object: dependency.h
+    # and one to simply output
+    #   dependency.h:
+    # which is needed to avoid the deleted-header problem.
+    { sed -e "s,^.*\.[$lower]*:,$object:," < "$tmpdepfile"
+      sed -e "s,^.*\.[$lower]*:[$tab ]*,," -e 's,$,:,' < "$tmpdepfile"
+    } > "$depfile"
+    rm -f "$tmpdepfile"
+  else
+    make_dummy_depfile
+  fi
+}
+
+# A tabulation character.
+tab='	'
+# A newline character.
+nl='
+'
+# Character ranges might be problematic outside the C locale.
+# These definitions help.
+upper=ABCDEFGHIJKLMNOPQRSTUVWXYZ
+lower=abcdefghijklmnopqrstuvwxyz
+digits=0123456789
+alpha=${upper}${lower}
+
+if test -z "$depmode" || test -z "$source" || test -z "$object"; then
+  echo "depcomp: Variables source, object and depmode must be set" 1>&2
+  exit 1
+fi
+
+# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po.
+depfile=${depfile-`echo "$object" |
+  sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`}
+tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`}
+
+rm -f "$tmpdepfile"
+
+# Avoid interferences from the environment.
+gccflag= dashmflag=
+
+# Some modes work just like other modes, but use different flags.  We
+# parameterize here, but still list the modes in the big case below,
+# to make depend.m4 easier to write.  Note that we *cannot* use a case
+# here, because this file can only contain one case statement.
+if test "$depmode" = hp; then
+  # HP compiler uses -M and no extra arg.
+  gccflag=-M
+  depmode=gcc
+fi
+
+if test "$depmode" = dashXmstdout; then
+  # This is just like dashmstdout with a different argument.
+  dashmflag=-xM
+  depmode=dashmstdout
+fi
+
+cygpath_u="cygpath -u -f -"
+if test "$depmode" = msvcmsys; then
+  # This is just like msvisualcpp but w/o cygpath translation.
+  # Just convert the backslash-escaped backslashes to single forward
+  # slashes to satisfy depend.m4
+  cygpath_u='sed s,\\\\,/,g'
+  depmode=msvisualcpp
+fi
+
+if test "$depmode" = msvc7msys; then
+  # This is just like msvc7 but w/o cygpath translation.
+  # Just convert the backslash-escaped backslashes to single forward
+  # slashes to satisfy depend.m4
+  cygpath_u='sed s,\\\\,/,g'
+  depmode=msvc7
+fi
+
+if test "$depmode" = xlc; then
+  # IBM C/C++ Compilers xlc/xlC can output gcc-like dependency information.
+  gccflag=-qmakedep=gcc,-MF
+  depmode=gcc
+fi
+
+case "$depmode" in
+gcc3)
+## gcc 3 implements dependency tracking that does exactly what
+## we want.  Yay!  Note: for some reason libtool 1.4 doesn't like
+## it if -MD -MP comes after the -MF stuff.  Hmm.
+## Unfortunately, FreeBSD c89 acceptance of flags depends upon
+## the command line argument order; so add the flags where they
+## appear in depend2.am.  Note that the slowdown incurred here
+## affects only configure: in makefiles, %FASTDEP% shortcuts this.
+  for arg
+  do
+    case $arg in
+    -c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;;
+    *)  set fnord "$@" "$arg" ;;
+    esac
+    shift # fnord
+    shift # $arg
+  done
+  "$@"
+  stat=$?
+  if test $stat -ne 0; then
+    rm -f "$tmpdepfile"
+    exit $stat
+  fi
+  mv "$tmpdepfile" "$depfile"
+  ;;
+
+gcc)
+## Note that this doesn't just cater to obsosete pre-3.x GCC compilers.
+## but also to in-use compilers like IMB xlc/xlC and the HP C compiler.
+## (see the conditional assignment to $gccflag above).
+## There are various ways to get dependency output from gcc.  Here's
+## why we pick this rather obscure method:
+## - Don't want to use -MD because we'd like the dependencies to end
+##   up in a subdir.  Having to rename by hand is ugly.
+##   (We might end up doing this anyway to support other compilers.)
+## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like
+##   -MM, not -M (despite what the docs say).  Also, it might not be
+##   supported by the other compilers which use the 'gcc' depmode.
+## - Using -M directly means running the compiler twice (even worse
+##   than renaming).
+  if test -z "$gccflag"; then
+    gccflag=-MD,
+  fi
+  "$@" -Wp,"$gccflag$tmpdepfile"
+  stat=$?
+  if test $stat -ne 0; then
+    rm -f "$tmpdepfile"
+    exit $stat
+  fi
+  rm -f "$depfile"
+  echo "$object : \\" > "$depfile"
+  # The second -e expression handles DOS-style file names with drive
+  # letters.
+  sed -e 's/^[^:]*: / /' \
+      -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile"
+## This next piece of magic avoids the "deleted header file" problem.
+## The problem is that when a header file which appears in a .P file
+## is deleted, the dependency causes make to die (because there is
+## typically no way to rebuild the header).  We avoid this by adding
+## dummy dependencies for each header file.  Too bad gcc doesn't do
+## this for us directly.
+## Some versions of gcc put a space before the ':'.  On the theory
+## that the space means something, we add a space to the output as
+## well.  hp depmode also adds that space, but also prefixes the VPATH
+## to the object.  Take care to not repeat it in the output.
+## Some versions of the HPUX 10.20 sed can't process this invocation
+## correctly.  Breaking it into two sed invocations is a workaround.
+  tr ' ' "$nl" < "$tmpdepfile" \
+    | sed -e 's/^\\$//' -e '/^$/d' -e "s|.*$object$||" -e '/:$/d' \
+    | sed -e 's/$/ :/' >> "$depfile"
+  rm -f "$tmpdepfile"
+  ;;
+
+hp)
+  # This case exists only to let depend.m4 do its work.  It works by
+  # looking at the text of this script.  This case will never be run,
+  # since it is checked for above.
+  exit 1
+  ;;
+
+sgi)
+  if test "$libtool" = yes; then
+    "$@" "-Wp,-MDupdate,$tmpdepfile"
+  else
+    "$@" -MDupdate "$tmpdepfile"
+  fi
+  stat=$?
+  if test $stat -ne 0; then
+    rm -f "$tmpdepfile"
+    exit $stat
+  fi
+  rm -f "$depfile"
+
+  if test -f "$tmpdepfile"; then  # yes, the sourcefile depend on other files
+    echo "$object : \\" > "$depfile"
+    # Clip off the initial element (the dependent).  Don't try to be
+    # clever and replace this with sed code, as IRIX sed won't handle
+    # lines with more than a fixed number of characters (4096 in
+    # IRIX 6.2 sed, 8192 in IRIX 6.5).  We also remove comment lines;
+    # the IRIX cc adds comments like '#:fec' to the end of the
+    # dependency line.
+    tr ' ' "$nl" < "$tmpdepfile" \
+      | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' \
+      | tr "$nl" ' ' >> "$depfile"
+    echo >> "$depfile"
+    # The second pass generates a dummy entry for each header file.
+    tr ' ' "$nl" < "$tmpdepfile" \
+      | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \
+      >> "$depfile"
+  else
+    make_dummy_depfile
+  fi
+  rm -f "$tmpdepfile"
+  ;;
+
+xlc)
+  # This case exists only to let depend.m4 do its work.  It works by
+  # looking at the text of this script.  This case will never be run,
+  # since it is checked for above.
+  exit 1
+  ;;
+
+aix)
+  # The C for AIX Compiler uses -M and outputs the dependencies
+  # in a .u file.  In older versions, this file always lives in the
+  # current directory.  Also, the AIX compiler puts '$object:' at the
+  # start of each line; $object doesn't have directory information.
+  # Version 6 uses the directory in both cases.
+  set_dir_from "$object"
+  set_base_from "$object"
+  if test "$libtool" = yes; then
+    tmpdepfile1=$dir$base.u
+    tmpdepfile2=$base.u
+    tmpdepfile3=$dir.libs/$base.u
+    "$@" -Wc,-M
+  else
+    tmpdepfile1=$dir$base.u
+    tmpdepfile2=$dir$base.u
+    tmpdepfile3=$dir$base.u
+    "$@" -M
+  fi
+  stat=$?
+  if test $stat -ne 0; then
+    rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
+    exit $stat
+  fi
+
+  for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
+  do
+    test -f "$tmpdepfile" && break
+  done
+  aix_post_process_depfile
+  ;;
+
+tcc)
+  # tcc (Tiny C Compiler) understand '-MD -MF file' since version 0.9.26
+  # FIXME: That version still under development at the moment of writing.
+  #        Make that this statement remains true also for stable, released
+  #        versions.
+  # It will wrap lines (doesn't matter whether long or short) with a
+  # trailing '\', as in:
+  #
+  #   foo.o : \
+  #    foo.c \
+  #    foo.h \
+  #
+  # It will put a trailing '\' even on the last line, and will use leading
+  # spaces rather than leading tabs (at least since its commit 0394caf7
+  # "Emit spaces for -MD").
+  "$@" -MD -MF "$tmpdepfile"
+  stat=$?
+  if test $stat -ne 0; then
+    rm -f "$tmpdepfile"
+    exit $stat
+  fi
+  rm -f "$depfile"
+  # Each non-empty line is of the form 'foo.o : \' or ' dep.h \'.
+  # We have to change lines of the first kind to '$object: \'.
+  sed -e "s|.*:|$object :|" < "$tmpdepfile" > "$depfile"
+  # And for each line of the second kind, we have to emit a 'dep.h:'
+  # dummy dependency, to avoid the deleted-header problem.
+  sed -n -e 's|^  *\(.*\) *\\$|\1:|p' < "$tmpdepfile" >> "$depfile"
+  rm -f "$tmpdepfile"
+  ;;
+
+## The order of this option in the case statement is important, since the
+## shell code in configure will try each of these formats in the order
+## listed in this file.  A plain '-MD' option would be understood by many
+## compilers, so we must ensure this comes after the gcc and icc options.
+pgcc)
+  # Portland's C compiler understands '-MD'.
+  # Will always output deps to 'file.d' where file is the root name of the
+  # source file under compilation, even if file resides in a subdirectory.
+  # The object file name does not affect the name of the '.d' file.
+  # pgcc 10.2 will output
+  #    foo.o: sub/foo.c sub/foo.h
+  # and will wrap long lines using '\' :
+  #    foo.o: sub/foo.c ... \
+  #     sub/foo.h ... \
+  #     ...
+  set_dir_from "$object"
+  # Use the source, not the object, to determine the base name, since
+  # that's sadly what pgcc will do too.
+  set_base_from "$source"
+  tmpdepfile=$base.d
+
+  # For projects that build the same source file twice into different object
+  # files, the pgcc approach of using the *source* file root name can cause
+  # problems in parallel builds.  Use a locking strategy to avoid stomping on
+  # the same $tmpdepfile.
+  lockdir=$base.d-lock
+  trap "
+    echo '$0: caught signal, cleaning up...' >&2
+    rmdir '$lockdir'
+    exit 1
+  " 1 2 13 15
+  numtries=100
+  i=$numtries
+  while test $i -gt 0; do
+    # mkdir is a portable test-and-set.
+    if mkdir "$lockdir" 2>/dev/null; then
+      # This process acquired the lock.
+      "$@" -MD
+      stat=$?
+      # Release the lock.
+      rmdir "$lockdir"
+      break
+    else
+      # If the lock is being held by a different process, wait
+      # until the winning process is done or we timeout.
+      while test -d "$lockdir" && test $i -gt 0; do
+        sleep 1
+        i=`expr $i - 1`
+      done
+    fi
+    i=`expr $i - 1`
+  done
+  trap - 1 2 13 15
+  if test $i -le 0; then
+    echo "$0: failed to acquire lock after $numtries attempts" >&2
+    echo "$0: check lockdir '$lockdir'" >&2
+    exit 1
+  fi
+
+  if test $stat -ne 0; then
+    rm -f "$tmpdepfile"
+    exit $stat
+  fi
+  rm -f "$depfile"
+  # Each line is of the form `foo.o: dependent.h',
+  # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'.
+  # Do two passes, one to just change these to
+  # `$object: dependent.h' and one to simply `dependent.h:'.
+  sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile"
+  # Some versions of the HPUX 10.20 sed can't process this invocation
+  # correctly.  Breaking it into two sed invocations is a workaround.
+  sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" \
+    | sed -e 's/$/ :/' >> "$depfile"
+  rm -f "$tmpdepfile"
+  ;;
+
+hp2)
+  # The "hp" stanza above does not work with aCC (C++) and HP's ia64
+  # compilers, which have integrated preprocessors.  The correct option
+  # to use with these is +Maked; it writes dependencies to a file named
+  # 'foo.d', which lands next to the object file, wherever that
+  # happens to be.
+  # Much of this is similar to the tru64 case; see comments there.
+  set_dir_from  "$object"
+  set_base_from "$object"
+  if test "$libtool" = yes; then
+    tmpdepfile1=$dir$base.d
+    tmpdepfile2=$dir.libs/$base.d
+    "$@" -Wc,+Maked
+  else
+    tmpdepfile1=$dir$base.d
+    tmpdepfile2=$dir$base.d
+    "$@" +Maked
+  fi
+  stat=$?
+  if test $stat -ne 0; then
+     rm -f "$tmpdepfile1" "$tmpdepfile2"
+     exit $stat
+  fi
+
+  for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2"
+  do
+    test -f "$tmpdepfile" && break
+  done
+  if test -f "$tmpdepfile"; then
+    sed -e "s,^.*\.[$lower]*:,$object:," "$tmpdepfile" > "$depfile"
+    # Add 'dependent.h:' lines.
+    sed -ne '2,${
+               s/^ *//
+               s/ \\*$//
+               s/$/:/
+               p
+             }' "$tmpdepfile" >> "$depfile"
+  else
+    make_dummy_depfile
+  fi
+  rm -f "$tmpdepfile" "$tmpdepfile2"
+  ;;
+
+tru64)
+  # The Tru64 compiler uses -MD to generate dependencies as a side
+  # effect.  'cc -MD -o foo.o ...' puts the dependencies into 'foo.o.d'.
+  # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put
+  # dependencies in 'foo.d' instead, so we check for that too.
+  # Subdirectories are respected.
+  set_dir_from  "$object"
+  set_base_from "$object"
+
+  if test "$libtool" = yes; then
+    # Libtool generates 2 separate objects for the 2 libraries.  These
+    # two compilations output dependencies in $dir.libs/$base.o.d and
+    # in $dir$base.o.d.  We have to check for both files, because
+    # one of the two compilations can be disabled.  We should prefer
+    # $dir$base.o.d over $dir.libs/$base.o.d because the latter is
+    # automatically cleaned when .libs/ is deleted, while ignoring
+    # the former would cause a distcleancheck panic.
+    tmpdepfile1=$dir$base.o.d          # libtool 1.5
+    tmpdepfile2=$dir.libs/$base.o.d    # Likewise.
+    tmpdepfile3=$dir.libs/$base.d      # Compaq CCC V6.2-504
+    "$@" -Wc,-MD
+  else
+    tmpdepfile1=$dir$base.d
+    tmpdepfile2=$dir$base.d
+    tmpdepfile3=$dir$base.d
+    "$@" -MD
+  fi
+
+  stat=$?
+  if test $stat -ne 0; then
+    rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
+    exit $stat
+  fi
+
+  for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
+  do
+    test -f "$tmpdepfile" && break
+  done
+  # Same post-processing that is required for AIX mode.
+  aix_post_process_depfile
+  ;;
+
+msvc7)
+  if test "$libtool" = yes; then
+    showIncludes=-Wc,-showIncludes
+  else
+    showIncludes=-showIncludes
+  fi
+  "$@" $showIncludes > "$tmpdepfile"
+  stat=$?
+  grep -v '^Note: including file: ' "$tmpdepfile"
+  if test $stat -ne 0; then
+    rm -f "$tmpdepfile"
+    exit $stat
+  fi
+  rm -f "$depfile"
+  echo "$object : \\" > "$depfile"
+  # The first sed program below extracts the file names and escapes
+  # backslashes for cygpath.  The second sed program outputs the file
+  # name when reading, but also accumulates all include files in the
+  # hold buffer in order to output them again at the end.  This only
+  # works with sed implementations that can handle large buffers.
+  sed < "$tmpdepfile" -n '
+/^Note: including file:  *\(.*\)/ {
+  s//\1/
+  s/\\/\\\\/g
+  p
+}' | $cygpath_u | sort -u | sed -n '
+s/ /\\ /g
+s/\(.*\)/'"$tab"'\1 \\/p
+s/.\(.*\) \\/\1:/
+H
+$ {
+  s/.*/'"$tab"'/
+  G
+  p
+}' >> "$depfile"
+  echo >> "$depfile" # make sure the fragment doesn't end with a backslash
+  rm -f "$tmpdepfile"
+  ;;
+
+msvc7msys)
+  # This case exists only to let depend.m4 do its work.  It works by
+  # looking at the text of this script.  This case will never be run,
+  # since it is checked for above.
+  exit 1
+  ;;
+
+#nosideeffect)
+  # This comment above is used by automake to tell side-effect
+  # dependency tracking mechanisms from slower ones.
+
+dashmstdout)
+  # Important note: in order to support this mode, a compiler *must*
+  # always write the preprocessed file to stdout, regardless of -o.
+  "$@" || exit $?
+
+  # Remove the call to Libtool.
+  if test "$libtool" = yes; then
+    while test "X$1" != 'X--mode=compile'; do
+      shift
+    done
+    shift
+  fi
+
+  # Remove '-o $object'.
+  IFS=" "
+  for arg
+  do
+    case $arg in
+    -o)
+      shift
+      ;;
+    $object)
+      shift
+      ;;
+    *)
+      set fnord "$@" "$arg"
+      shift # fnord
+      shift # $arg
+      ;;
+    esac
+  done
+
+  test -z "$dashmflag" && dashmflag=-M
+  # Require at least two characters before searching for ':'
+  # in the target name.  This is to cope with DOS-style filenames:
+  # a dependency such as 'c:/foo/bar' could be seen as target 'c' otherwise.
+  "$@" $dashmflag |
+    sed "s|^[$tab ]*[^:$tab ][^:][^:]*:[$tab ]*|$object: |" > "$tmpdepfile"
+  rm -f "$depfile"
+  cat < "$tmpdepfile" > "$depfile"
+  # Some versions of the HPUX 10.20 sed can't process this sed invocation
+  # correctly.  Breaking it into two sed invocations is a workaround.
+  tr ' ' "$nl" < "$tmpdepfile" \
+    | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \
+    | sed -e 's/$/ :/' >> "$depfile"
+  rm -f "$tmpdepfile"
+  ;;
+
+dashXmstdout)
+  # This case only exists to satisfy depend.m4.  It is never actually
+  # run, as this mode is specially recognized in the preamble.
+  exit 1
+  ;;
+
+makedepend)
+  "$@" || exit $?
+  # Remove any Libtool call
+  if test "$libtool" = yes; then
+    while test "X$1" != 'X--mode=compile'; do
+      shift
+    done
+    shift
+  fi
+  # X makedepend
+  shift
+  cleared=no eat=no
+  for arg
+  do
+    case $cleared in
+    no)
+      set ""; shift
+      cleared=yes ;;
+    esac
+    if test $eat = yes; then
+      eat=no
+      continue
+    fi
+    case "$arg" in
+    -D*|-I*)
+      set fnord "$@" "$arg"; shift ;;
+    # Strip any option that makedepend may not understand.  Remove
+    # the object too, otherwise makedepend will parse it as a source file.
+    -arch)
+      eat=yes ;;
+    -*|$object)
+      ;;
+    *)
+      set fnord "$@" "$arg"; shift ;;
+    esac
+  done
+  obj_suffix=`echo "$object" | sed 's/^.*\././'`
+  touch "$tmpdepfile"
+  ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@"
+  rm -f "$depfile"
+  # makedepend may prepend the VPATH from the source file name to the object.
+  # No need to regex-escape $object, excess matching of '.' is harmless.
+  sed "s|^.*\($object *:\)|\1|" "$tmpdepfile" > "$depfile"
+  # Some versions of the HPUX 10.20 sed can't process the last invocation
+  # correctly.  Breaking it into two sed invocations is a workaround.
+  sed '1,2d' "$tmpdepfile" \
+    | tr ' ' "$nl" \
+    | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \
+    | sed -e 's/$/ :/' >> "$depfile"
+  rm -f "$tmpdepfile" "$tmpdepfile".bak
+  ;;
+
+cpp)
+  # Important note: in order to support this mode, a compiler *must*
+  # always write the preprocessed file to stdout.
+  "$@" || exit $?
+
+  # Remove the call to Libtool.
+  if test "$libtool" = yes; then
+    while test "X$1" != 'X--mode=compile'; do
+      shift
+    done
+    shift
+  fi
+
+  # Remove '-o $object'.
+  IFS=" "
+  for arg
+  do
+    case $arg in
+    -o)
+      shift
+      ;;
+    $object)
+      shift
+      ;;
+    *)
+      set fnord "$@" "$arg"
+      shift # fnord
+      shift # $arg
+      ;;
+    esac
+  done
+
+  "$@" -E \
+    | sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \
+             -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \
+    | sed '$ s: \\$::' > "$tmpdepfile"
+  rm -f "$depfile"
+  echo "$object : \\" > "$depfile"
+  cat < "$tmpdepfile" >> "$depfile"
+  sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile"
+  rm -f "$tmpdepfile"
+  ;;
+
+msvisualcpp)
+  # Important note: in order to support this mode, a compiler *must*
+  # always write the preprocessed file to stdout.
+  "$@" || exit $?
+
+  # Remove the call to Libtool.
+  if test "$libtool" = yes; then
+    while test "X$1" != 'X--mode=compile'; do
+      shift
+    done
+    shift
+  fi
+
+  IFS=" "
+  for arg
+  do
+    case "$arg" in
+    -o)
+      shift
+      ;;
+    $object)
+      shift
+      ;;
+    "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI")
+        set fnord "$@"
+        shift
+        shift
+        ;;
+    *)
+        set fnord "$@" "$arg"
+        shift
+        shift
+        ;;
+    esac
+  done
+  "$@" -E 2>/dev/null |
+  sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile"
+  rm -f "$depfile"
+  echo "$object : \\" > "$depfile"
+  sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::'"$tab"'\1 \\:p' >> "$depfile"
+  echo "$tab" >> "$depfile"
+  sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile"
+  rm -f "$tmpdepfile"
+  ;;
+
+msvcmsys)
+  # This case exists only to let depend.m4 do its work.  It works by
+  # looking at the text of this script.  This case will never be run,
+  # since it is checked for above.
+  exit 1
+  ;;
+
+none)
+  exec "$@"
+  ;;
+
+*)
+  echo "Unknown depmode $depmode" 1>&2
+  exit 1
+  ;;
+esac
+
+exit 0
+
+# Local Variables:
+# mode: shell-script
+# sh-indentation: 2
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
+# End:
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/config/dkms.m4
@@ -0,0 +1,14 @@
+dnl #
+dnl # Prevent manual building in DKMS source tree.
+dnl #
+AC_DEFUN([ZFS_AC_DKMS_INHIBIT], [
+	AC_MSG_CHECKING([for dkms.conf file])
+        AS_IF([test -e dkms.conf], [
+		AC_MSG_ERROR([
+	*** ZFS should not be manually built in the DKMS source tree.
+	*** Remove all ZFS packages before compiling the ZoL sources.
+	*** Running "make install" breaks ZFS packages.])
+        ], [
+		AC_MSG_RESULT([not found])
+        ])
+])
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/config/install-sh
@@ -0,0 +1,508 @@
+#!/bin/sh
+# install - install a program, script, or datafile
+
+scriptversion=2014-09-12.12; # UTC
+
+# This originates from X11R5 (mit/util/scripts/install.sh), which was
+# later released in X11R6 (xc/config/util/install.sh) with the
+# following copyright and license.
+#
+# Copyright (C) 1994 X Consortium
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to
+# deal in the Software without restriction, including without limitation the
+# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+# sell copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
+# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+# Except as contained in this notice, the name of the X Consortium shall not
+# be used in advertising or otherwise to promote the sale, use or other deal-
+# ings in this Software without prior written authorization from the X Consor-
+# tium.
+#
+#
+# FSF changes to this file are in the public domain.
+#
+# Calling this script install-sh is preferred over install.sh, to prevent
+# 'make' implicit rules from creating a file called install from it
+# when there is no Makefile.
+#
+# This script is compatible with the BSD install script, but was written
+# from scratch.
+
+tab='	'
+nl='
+'
+IFS=" $tab$nl"
+
+# Set DOITPROG to "echo" to test this script.
+
+doit=${DOITPROG-}
+doit_exec=${doit:-exec}
+
+# Put in absolute file names if you don't have them in your path;
+# or use environment vars.
+
+chgrpprog=${CHGRPPROG-chgrp}
+chmodprog=${CHMODPROG-chmod}
+chownprog=${CHOWNPROG-chown}
+cmpprog=${CMPPROG-cmp}
+cpprog=${CPPROG-cp}
+mkdirprog=${MKDIRPROG-mkdir}
+mvprog=${MVPROG-mv}
+rmprog=${RMPROG-rm}
+stripprog=${STRIPPROG-strip}
+
+posix_mkdir=
+
+# Desired mode of installed file.
+mode=0755
+
+chgrpcmd=
+chmodcmd=$chmodprog
+chowncmd=
+mvcmd=$mvprog
+rmcmd="$rmprog -f"
+stripcmd=
+
+src=
+dst=
+dir_arg=
+dst_arg=
+
+copy_on_change=false
+is_target_a_directory=possibly
+
+usage="\
+Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
+   or: $0 [OPTION]... SRCFILES... DIRECTORY
+   or: $0 [OPTION]... -t DIRECTORY SRCFILES...
+   or: $0 [OPTION]... -d DIRECTORIES...
+
+In the 1st form, copy SRCFILE to DSTFILE.
+In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
+In the 4th, create DIRECTORIES.
+
+Options:
+     --help     display this help and exit.
+     --version  display version info and exit.
+
+  -c            (ignored)
+  -C            install only if different (preserve the last data modification time)
+  -d            create directories instead of installing files.
+  -g GROUP      $chgrpprog installed files to GROUP.
+  -m MODE       $chmodprog installed files to MODE.
+  -o USER       $chownprog installed files to USER.
+  -s            $stripprog installed files.
+  -t DIRECTORY  install into DIRECTORY.
+  -T            report an error if DSTFILE is a directory.
+
+Environment variables override the default commands:
+  CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
+  RMPROG STRIPPROG
+"
+
+while test $# -ne 0; do
+  case $1 in
+    -c) ;;
+
+    -C) copy_on_change=true;;
+
+    -d) dir_arg=true;;
+
+    -g) chgrpcmd="$chgrpprog $2"
+        shift;;
+
+    --help) echo "$usage"; exit $?;;
+
+    -m) mode=$2
+        case $mode in
+          *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*)
+            echo "$0: invalid mode: $mode" >&2
+            exit 1;;
+        esac
+        shift;;
+
+    -o) chowncmd="$chownprog $2"
+        shift;;
+
+    -s) stripcmd=$stripprog;;
+
+    -t)
+        is_target_a_directory=always
+        dst_arg=$2
+        # Protect names problematic for 'test' and other utilities.
+        case $dst_arg in
+          -* | [=\(\)!]) dst_arg=./$dst_arg;;
+        esac
+        shift;;
+
+    -T) is_target_a_directory=never;;
+
+    --version) echo "$0 $scriptversion"; exit $?;;
+
+    --) shift
+        break;;
+
+    -*) echo "$0: invalid option: $1" >&2
+        exit 1;;
+
+    *)  break;;
+  esac
+  shift
+done
+
+# We allow the use of options -d and -T together, by making -d
+# take the precedence; this is for compatibility with GNU install.
+
+if test -n "$dir_arg"; then
+  if test -n "$dst_arg"; then
+    echo "$0: target directory not allowed when installing a directory." >&2
+    exit 1
+  fi
+fi
+
+if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
+  # When -d is used, all remaining arguments are directories to create.
+  # When -t is used, the destination is already specified.
+  # Otherwise, the last argument is the destination.  Remove it from $@.
+  for arg
+  do
+    if test -n "$dst_arg"; then
+      # $@ is not empty: it contains at least $arg.
+      set fnord "$@" "$dst_arg"
+      shift # fnord
+    fi
+    shift # arg
+    dst_arg=$arg
+    # Protect names problematic for 'test' and other utilities.
+    case $dst_arg in
+      -* | [=\(\)!]) dst_arg=./$dst_arg;;
+    esac
+  done
+fi
+
+if test $# -eq 0; then
+  if test -z "$dir_arg"; then
+    echo "$0: no input file specified." >&2
+    exit 1
+  fi
+  # It's OK to call 'install-sh -d' without argument.
+  # This can happen when creating conditional directories.
+  exit 0
+fi
+
+if test -z "$dir_arg"; then
+  if test $# -gt 1 || test "$is_target_a_directory" = always; then
+    if test ! -d "$dst_arg"; then
+      echo "$0: $dst_arg: Is not a directory." >&2
+      exit 1
+    fi
+  fi
+fi
+
+if test -z "$dir_arg"; then
+  do_exit='(exit $ret); exit $ret'
+  trap "ret=129; $do_exit" 1
+  trap "ret=130; $do_exit" 2
+  trap "ret=141; $do_exit" 13
+  trap "ret=143; $do_exit" 15
+
+  # Set umask so as not to create temps with too-generous modes.
+  # However, 'strip' requires both read and write access to temps.
+  case $mode in
+    # Optimize common cases.
+    *644) cp_umask=133;;
+    *755) cp_umask=22;;
+
+    *[0-7])
+      if test -z "$stripcmd"; then
+        u_plus_rw=
+      else
+        u_plus_rw='% 200'
+      fi
+      cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
+    *)
+      if test -z "$stripcmd"; then
+        u_plus_rw=
+      else
+        u_plus_rw=,u+rw
+      fi
+      cp_umask=$mode$u_plus_rw;;
+  esac
+fi
+
+for src
+do
+  # Protect names problematic for 'test' and other utilities.
+  case $src in
+    -* | [=\(\)!]) src=./$src;;
+  esac
+
+  if test -n "$dir_arg"; then
+    dst=$src
+    dstdir=$dst
+    test -d "$dstdir"
+    dstdir_status=$?
+  else
+
+    # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
+    # might cause directories to be created, which would be especially bad
+    # if $src (and thus $dsttmp) contains '*'.
+    if test ! -f "$src" && test ! -d "$src"; then
+      echo "$0: $src does not exist." >&2
+      exit 1
+    fi
+
+    if test -z "$dst_arg"; then
+      echo "$0: no destination specified." >&2
+      exit 1
+    fi
+    dst=$dst_arg
+
+    # If destination is a directory, append the input filename; won't work
+    # if double slashes aren't ignored.
+    if test -d "$dst"; then
+      if test "$is_target_a_directory" = never; then
+        echo "$0: $dst_arg: Is a directory" >&2
+        exit 1
+      fi
+      dstdir=$dst
+      dst=$dstdir/`basename "$src"`
+      dstdir_status=0
+    else
+      dstdir=`dirname "$dst"`
+      test -d "$dstdir"
+      dstdir_status=$?
+    fi
+  fi
+
+  obsolete_mkdir_used=false
+
+  if test $dstdir_status != 0; then
+    case $posix_mkdir in
+      '')
+        # Create intermediate dirs using mode 755 as modified by the umask.
+        # This is like FreeBSD 'install' as of 1997-10-28.
+        umask=`umask`
+        case $stripcmd.$umask in
+          # Optimize common cases.
+          *[2367][2367]) mkdir_umask=$umask;;
+          .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
+
+          *[0-7])
+            mkdir_umask=`expr $umask + 22 \
+              - $umask % 100 % 40 + $umask % 20 \
+              - $umask % 10 % 4 + $umask % 2
+            `;;
+          *) mkdir_umask=$umask,go-w;;
+        esac
+
+        # With -d, create the new directory with the user-specified mode.
+        # Otherwise, rely on $mkdir_umask.
+        if test -n "$dir_arg"; then
+          mkdir_mode=-m$mode
+        else
+          mkdir_mode=
+        fi
+
+        posix_mkdir=false
+        case $umask in
+          *[123567][0-7][0-7])
+            # POSIX mkdir -p sets u+wx bits regardless of umask, which
+            # is incompatible with FreeBSD 'install' when (umask & 300) != 0.
+            ;;
+          *)
+            # $RANDOM is not portable (e.g. dash);  use it when possible to
+            # lower collision chance
+            tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
+            trap 'ret=$?; rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null; exit $ret' 0
+
+            # As "mkdir -p" follows symlinks and we work in /tmp possibly;  so
+            # create the $tmpdir first (and fail if unsuccessful) to make sure
+            # that nobody tries to guess the $tmpdir name.
+            if (umask $mkdir_umask &&
+                $mkdirprog $mkdir_mode "$tmpdir" &&
+                exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1
+            then
+              if test -z "$dir_arg" || {
+                   # Check for POSIX incompatibilities with -m.
+                   # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
+                   # other-writable bit of parent directory when it shouldn't.
+                   # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
+                   test_tmpdir="$tmpdir/a"
+                   ls_ld_tmpdir=`ls -ld "$test_tmpdir"`
+                   case $ls_ld_tmpdir in
+                     d????-?r-*) different_mode=700;;
+                     d????-?--*) different_mode=755;;
+                     *) false;;
+                   esac &&
+                   $mkdirprog -m$different_mode -p -- "$test_tmpdir" && {
+                     ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"`
+                     test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
+                   }
+                 }
+              then posix_mkdir=:
+              fi
+              rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir"
+            else
+              # Remove any dirs left behind by ancient mkdir implementations.
+              rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null
+            fi
+            trap '' 0;;
+        esac;;
+    esac
+
+    if
+      $posix_mkdir && (
+        umask $mkdir_umask &&
+        $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
+      )
+    then :
+    else
+
+      # The umask is ridiculous, or mkdir does not conform to POSIX,
+      # or it failed possibly due to a race condition.  Create the
+      # directory the slow way, step by step, checking for races as we go.
+
+      case $dstdir in
+        /*) prefix='/';;
+        [-=\(\)!]*) prefix='./';;
+        *)  prefix='';;
+      esac
+
+      oIFS=$IFS
+      IFS=/
+      set -f
+      set fnord $dstdir
+      shift
+      set +f
+      IFS=$oIFS
+
+      prefixes=
+
+      for d
+      do
+        test X"$d" = X && continue
+
+        prefix=$prefix$d
+        if test -d "$prefix"; then
+          prefixes=
+        else
+          if $posix_mkdir; then
+            (umask=$mkdir_umask &&
+             $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
+            # Don't fail if two instances are running concurrently.
+            test -d "$prefix" || exit 1
+          else
+            case $prefix in
+              *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
+              *) qprefix=$prefix;;
+            esac
+            prefixes="$prefixes '$qprefix'"
+          fi
+        fi
+        prefix=$prefix/
+      done
+
+      if test -n "$prefixes"; then
+        # Don't fail if two instances are running concurrently.
+        (umask $mkdir_umask &&
+         eval "\$doit_exec \$mkdirprog $prefixes") ||
+          test -d "$dstdir" || exit 1
+        obsolete_mkdir_used=true
+      fi
+    fi
+  fi
+
+  if test -n "$dir_arg"; then
+    { test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
+    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
+    { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
+      test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
+  else
+
+    # Make a couple of temp file names in the proper directory.
+    dsttmp=$dstdir/_inst.$$_
+    rmtmp=$dstdir/_rm.$$_
+
+    # Trap to clean up those temp files at exit.
+    trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
+
+    # Copy the file name to the temp name.
+    (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
+
+    # and set any options; do chmod last to preserve setuid bits.
+    #
+    # If any of these fail, we abort the whole thing.  If we want to
+    # ignore errors from any of these, just make sure not to ignore
+    # errors from the above "$doit $cpprog $src $dsttmp" command.
+    #
+    { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
+    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
+    { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
+    { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
+
+    # If -C, don't bother to copy if it wouldn't change the file.
+    if $copy_on_change &&
+       old=`LC_ALL=C ls -dlL "$dst"     2>/dev/null` &&
+       new=`LC_ALL=C ls -dlL "$dsttmp"  2>/dev/null` &&
+       set -f &&
+       set X $old && old=:$2:$4:$5:$6 &&
+       set X $new && new=:$2:$4:$5:$6 &&
+       set +f &&
+       test "$old" = "$new" &&
+       $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
+    then
+      rm -f "$dsttmp"
+    else
+      # Rename the file to the real destination.
+      $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
+
+      # The rename failed, perhaps because mv can't rename something else
+      # to itself, or perhaps because mv is so ancient that it does not
+      # support -f.
+      {
+        # Now remove or move aside any old file at destination location.
+        # We try this two ways since rm can't unlink itself on some
+        # systems and the destination file might be busy for other
+        # reasons.  In this case, the final cleanup might fail but the new
+        # file should still install successfully.
+        {
+          test ! -f "$dst" ||
+          $doit $rmcmd -f "$dst" 2>/dev/null ||
+          { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
+            { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
+          } ||
+          { echo "$0: cannot unlink or rename $dst" >&2
+            (exit 1); exit 1
+          }
+        } &&
+
+        # Now rename the file to the real destination.
+        $doit $mvcmd "$dsttmp" "$dst"
+      }
+    fi || exit 1
+
+    trap '' 0
+  fi
+done
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
+# End:
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/config/kernel-acl.m4
@@ -0,0 +1,265 @@
+dnl #
+dnl # Check if posix_acl_release can be used from a ZFS_META_LICENSED
+dnl # module.  The is_owner_or_cap macro was replaced by
+dnl # inode_owner_or_capable
+dnl #
+AC_DEFUN([ZFS_AC_KERNEL_POSIX_ACL_RELEASE], [
+	AC_MSG_CHECKING([whether posix_acl_release() is available])
+	ZFS_LINUX_TRY_COMPILE([
+		#include <linux/cred.h>
+		#include <linux/fs.h>
+		#include <linux/posix_acl.h>
+	],[
+		struct posix_acl* tmp = posix_acl_alloc(1, 0);
+		posix_acl_release(tmp);
+	],[
+		AC_MSG_RESULT(yes)
+		AC_DEFINE(HAVE_POSIX_ACL_RELEASE, 1,
+		    [posix_acl_release() is available])
+	],[
+		AC_MSG_RESULT(no)
+	])
+
+	AC_MSG_CHECKING([whether posix_acl_release() is GPL-only])
+	ZFS_LINUX_TRY_COMPILE([
+		#include <linux/cred.h>
+		#include <linux/fs.h>
+		#include <linux/posix_acl.h>
+
+		MODULE_LICENSE("$ZFS_META_LICENSE");
+	],[
+		struct posix_acl* tmp = posix_acl_alloc(1, 0);
+		posix_acl_release(tmp);
+	],[
+		AC_MSG_RESULT(no)
+	],[
+		AC_MSG_RESULT(yes)
+		AC_DEFINE(HAVE_POSIX_ACL_RELEASE_GPL_ONLY, 1,
+		    [posix_acl_release() is GPL-only])
+	])
+])
+
+dnl #
+dnl # 3.1 API change,
+dnl # posix_acl_chmod_masq() is not exported anymore and posix_acl_chmod()
+dnl # was introduced to replace it.
+dnl #
+dnl # 3.14 API change,
+dnl # posix_acl_chmod() is changed to __posix_acl_chmod()
+dnl #
+AC_DEFUN([ZFS_AC_KERNEL_POSIX_ACL_CHMOD], [
+	AC_MSG_CHECKING([whether posix_acl_chmod exists])
+	ZFS_LINUX_TRY_COMPILE([
+		#include <linux/fs.h>
+		#include <linux/posix_acl.h>
+	],[
+		posix_acl_chmod(NULL, 0, 0)
+	],[
+		AC_MSG_RESULT(yes)
+		AC_DEFINE(HAVE_POSIX_ACL_CHMOD, 1, [posix_acl_chmod() exists])
+	],[
+		AC_MSG_RESULT(no)
+	])
+
+	AC_MSG_CHECKING([whether __posix_acl_chmod exists])
+	ZFS_LINUX_TRY_COMPILE([
+		#include <linux/fs.h>
+		#include <linux/posix_acl.h>
+	],[
+		__posix_acl_chmod(NULL, 0, 0)
+	],[
+		AC_MSG_RESULT(yes)
+		AC_DEFINE(HAVE___POSIX_ACL_CHMOD, 1, [__posix_acl_chmod() exists])
+	],[
+		AC_MSG_RESULT(no)
+	])
+])
+
+dnl #
+dnl # 2.6.30 API change,
+dnl # caching of ACL into the inode was added in this version.
+dnl #
+AC_DEFUN([ZFS_AC_KERNEL_POSIX_ACL_CACHING], [
+	AC_MSG_CHECKING([whether inode has i_acl and i_default_acl])
+	ZFS_LINUX_TRY_COMPILE([
+		#include <linux/fs.h>
+	],[
+		struct inode ino;
+		ino.i_acl = NULL;
+		ino.i_default_acl = NULL;
+	],[
+		AC_MSG_RESULT(yes)
+		AC_DEFINE(HAVE_POSIX_ACL_CACHING, 1,
+		    [inode contains i_acl and i_default_acl])
+	],[
+		AC_MSG_RESULT(no)
+	])
+])
+
+dnl #
+dnl # 3.1 API change,
+dnl # posix_acl_equiv_mode now wants an umode_t* instead of a mode_t*
+dnl #
+AC_DEFUN([ZFS_AC_KERNEL_POSIX_ACL_EQUIV_MODE_WANTS_UMODE_T], [
+	AC_MSG_CHECKING([whether posix_acl_equiv_mode() wants umode_t])
+	ZFS_LINUX_TRY_COMPILE([
+		#include <linux/fs.h>
+		#include <linux/posix_acl.h>
+	],[
+		umode_t tmp;
+		posix_acl_equiv_mode(NULL,&tmp);
+	],[
+		AC_MSG_RESULT(yes)
+		AC_DEFINE(HAVE_POSIX_ACL_EQUIV_MODE_UMODE_T, 1,
+		    [ posix_acl_equiv_mode wants umode_t*])
+	],[
+		AC_MSG_RESULT(no)
+	])
+])
+
+dnl #
+dnl # 2.6.27 API change,
+dnl # Check if inode_operations contains the function permission
+dnl # and expects the nameidata structure to have been removed.
+dnl #
+AC_DEFUN([ZFS_AC_KERNEL_INODE_OPERATIONS_PERMISSION], [
+	AC_MSG_CHECKING([whether iops->permission() exists])
+	ZFS_LINUX_TRY_COMPILE([
+		#include <linux/fs.h>
+
+		int permission_fn(struct inode *inode, int mask) { return 0; }
+
+		static const struct inode_operations
+		    iops __attribute__ ((unused)) = {
+			.permission = permission_fn,
+		};
+	],[
+	],[
+		AC_MSG_RESULT(yes)
+		AC_DEFINE(HAVE_PERMISSION, 1, [iops->permission() exists])
+	],[
+		AC_MSG_RESULT(no)
+	])
+])
+
+dnl #
+dnl # 2.6.26 API change,
+dnl # Check if inode_operations contains the function permission
+dnl # and expects the nameidata structure to be passed.
+dnl #
+AC_DEFUN([ZFS_AC_KERNEL_INODE_OPERATIONS_PERMISSION_WITH_NAMEIDATA], [
+	AC_MSG_CHECKING([whether iops->permission() wants nameidata])
+	ZFS_LINUX_TRY_COMPILE([
+		#include <linux/fs.h>
+
+		int permission_fn(struct inode *inode, int mask,
+		    struct nameidata *nd) { return 0; }
+
+		static const struct inode_operations
+		    iops __attribute__ ((unused)) = {
+			.permission = permission_fn,
+		};
+	],[
+	],[
+		AC_MSG_RESULT(yes)
+		AC_DEFINE(HAVE_PERMISSION, 1, [iops->permission() exists])
+		AC_DEFINE(HAVE_PERMISSION_WITH_NAMEIDATA, 1,
+		    [iops->permission() with nameidata exists])
+	],[
+		AC_MSG_RESULT(no)
+	])
+])
+
+dnl #
+dnl # 2.6.32 API change,
+dnl # Check if inode_operations contains the function check_acl
+dnl #
+AC_DEFUN([ZFS_AC_KERNEL_INODE_OPERATIONS_CHECK_ACL], [
+	AC_MSG_CHECKING([whether iops->check_acl() exists])
+	ZFS_LINUX_TRY_COMPILE([
+		#include <linux/fs.h>
+
+		int check_acl_fn(struct inode *inode, int mask) { return 0; }
+
+		static const struct inode_operations
+		    iops __attribute__ ((unused)) = {
+			.check_acl = check_acl_fn,
+		};
+	],[
+	],[
+		AC_MSG_RESULT(yes)
+		AC_DEFINE(HAVE_CHECK_ACL, 1, [iops->check_acl() exists])
+	],[
+		AC_MSG_RESULT(no)
+	])
+])
+
+dnl #
+dnl # 2.6.38 API change,
+dnl # The function check_acl gained a new parameter: flags
+dnl #
+AC_DEFUN([ZFS_AC_KERNEL_INODE_OPERATIONS_CHECK_ACL_WITH_FLAGS], [
+	AC_MSG_CHECKING([whether iops->check_acl() wants flags])
+	ZFS_LINUX_TRY_COMPILE([
+		#include <linux/fs.h>
+
+		int check_acl_fn(struct inode *inode, int mask,
+		    unsigned int flags) { return 0; }
+
+		static const struct inode_operations
+		    iops __attribute__ ((unused)) = {
+			.check_acl = check_acl_fn,
+		};
+	],[
+	],[
+		AC_MSG_RESULT(yes)
+		AC_DEFINE(HAVE_CHECK_ACL, 1, [iops->check_acl() exists])
+		AC_DEFINE(HAVE_CHECK_ACL_WITH_FLAGS, 1,
+		    [iops->check_acl() wants flags])
+	],[
+		AC_MSG_RESULT(no)
+	])
+])
+
+dnl #
+dnl # 3.1 API change,
+dnl # Check if inode_operations contains the function get_acl
+dnl #
+AC_DEFUN([ZFS_AC_KERNEL_INODE_OPERATIONS_GET_ACL], [
+	AC_MSG_CHECKING([whether iops->get_acl() exists])
+	ZFS_LINUX_TRY_COMPILE([
+		#include <linux/fs.h>
+
+		struct posix_acl *get_acl_fn(struct inode *inode, int type)
+		    { return NULL; }
+
+		static const struct inode_operations
+		    iops __attribute__ ((unused)) = {
+			.get_acl = get_acl_fn,
+		};
+	],[
+	],[
+		AC_MSG_RESULT(yes)
+		AC_DEFINE(HAVE_GET_ACL, 1, [iops->get_acl() exists])
+	],[
+		AC_MSG_RESULT(no)
+	])
+])
+
+dnl #
+dnl # 2.6.30 API change,
+dnl # current_umask exists only since this version.
+dnl #
+AC_DEFUN([ZFS_AC_KERNEL_CURRENT_UMASK], [
+	AC_MSG_CHECKING([whether current_umask exists])
+	ZFS_LINUX_TRY_COMPILE([
+		#include <linux/fs.h>
+	],[
+		current_umask();
+	],[
+		AC_MSG_RESULT(yes)
+		AC_DEFINE(HAVE_CURRENT_UMASK, 1, [current_umask() exists])
+	],[
+		AC_MSG_RESULT(no)
+	])
+])
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/config/kernel-automount.m4
@@ -0,0 +1,23 @@
+dnl #
+dnl # 2.6.37 API change
+dnl # The dops->d_automount() dentry operation was added as a clean
+dnl # solution to handling automounts.  Prior to this cifs/nfs clients
+dnl # which required automount support would abuse the follow_link()
+dnl # operation on directories for this purpose.
+dnl #
+AC_DEFUN([ZFS_AC_KERNEL_AUTOMOUNT], [
+	AC_MSG_CHECKING([whether dops->d_automount() exists])
+	ZFS_LINUX_TRY_COMPILE([
+		#include <linux/dcache.h>
+		struct vfsmount *d_automount(struct path *p) { return NULL; }
+		struct dentry_operations dops __attribute__ ((unused)) = {
+			.d_automount = d_automount,
+		};
+	],[
+	],[
+		AC_MSG_RESULT(yes)
+		AC_DEFINE(HAVE_AUTOMOUNT, 1, [dops->automount() exists])
+	],[
+		AC_MSG_RESULT(no)
+	])
+])
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/config/kernel-bdev-block-device-operations.m4
@@ -0,0 +1,34 @@
+dnl #
+dnl # 2.6.x API change
+dnl #
+AC_DEFUN([ZFS_AC_KERNEL_BDEV_BLOCK_DEVICE_OPERATIONS], [
+	AC_MSG_CHECKING([block device operation prototypes])
+	tmp_flags="$EXTRA_KCFLAGS"
+	EXTRA_KCFLAGS="${NO_UNUSED_BUT_SET_VARIABLE}"
+	ZFS_LINUX_TRY_COMPILE([
+		#include <linux/blkdev.h>
+
+		int blk_open(struct block_device *bdev, fmode_t mode)
+		    { return 0; }
+		int blk_ioctl(struct block_device *bdev, fmode_t mode,
+		    unsigned x, unsigned long y) { return 0; }
+		int blk_compat_ioctl(struct block_device * bdev, fmode_t mode,
+		    unsigned x, unsigned long y) { return 0; }
+
+		static const struct block_device_operations
+		    bops __attribute__ ((unused)) = {
+			.open		= blk_open,
+			.release	= NULL,
+			.ioctl		= blk_ioctl,
+			.compat_ioctl	= blk_compat_ioctl,
+		};
+	],[
+	],[
+		AC_MSG_RESULT(struct block_device)
+		AC_DEFINE(HAVE_BDEV_BLOCK_DEVICE_OPERATIONS, 1,
+		          [struct block_device_operations use bdevs])
+	],[
+		AC_MSG_RESULT(struct inode)
+	])
+	EXTRA_KCFLAGS="$tmp_flags"
+])
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/config/kernel-bdev-logical-size.m4
@@ -0,0 +1,25 @@
+dnl #
+dnl # 2.6.30 API change
+dnl # bdev_hardsect_size() replaced with bdev_logical_block_size().  While
+dnl # it has been true for a while that there was no strict 1:1 mapping
+dnl # between physical sector size and logical block size this change makes
+dnl # it explicit.
+dnl #
+AC_DEFUN([ZFS_AC_KERNEL_BDEV_LOGICAL_BLOCK_SIZE], [
+	AC_MSG_CHECKING([whether bdev_logical_block_size() is available])
+	tmp_flags="$EXTRA_KCFLAGS"
+	EXTRA_KCFLAGS="${NO_UNUSED_BUT_SET_VARIABLE}"
+	ZFS_LINUX_TRY_COMPILE([
+		#include <linux/blkdev.h>
+	],[
+		struct block_device *bdev = NULL;
+		bdev_logical_block_size(bdev);
+	],[
+		AC_MSG_RESULT(yes)
+		AC_DEFINE(HAVE_BDEV_LOGICAL_BLOCK_SIZE, 1,
+		          [bdev_logical_block_size() is available])
+	],[
+		AC_MSG_RESULT(no)
+	])
+	EXTRA_KCFLAGS="$tmp_flags"
+])
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/config/kernel-bdev-physical-size.m4
@@ -0,0 +1,39 @@
+dnl #
+dnl # 2.6.30 API change
+dnl #
+dnl # The bdev_physical_block_size() interface was added to provide a way
+dnl # to determine the smallest write which can be performed without a
+dnl # read-modify-write operation.  From the kernel documentation:
+dnl #
+dnl # What:          /sys/block/<disk>/queue/physical_block_size
+dnl # Date:          May 2009
+dnl # Contact:       Martin K. Petersen <martin.petersen@oracle.com>
+dnl # Description:
+dnl #                This is the smallest unit the storage device can write
+dnl #                without resorting to read-modify-write operation.  It is
+dnl #                usually the same as the logical block size but may be
+dnl #                bigger.  One example is SATA drives with 4KB sectors
+dnl #                that expose a 512-byte logical block size to the
+dnl #                operating system.
+dnl #
+dnl # Unfortunately, this interface isn't entirely reliable because
+dnl # drives are sometimes known to misreport this value.
+dnl #
+AC_DEFUN([ZFS_AC_KERNEL_BDEV_PHYSICAL_BLOCK_SIZE], [
+	AC_MSG_CHECKING([whether bdev_physical_block_size() is available])
+	tmp_flags="$EXTRA_KCFLAGS"
+	EXTRA_KCFLAGS="${NO_UNUSED_BUT_SET_VARIABLE}"
+	ZFS_LINUX_TRY_COMPILE([
+		#include <linux/blkdev.h>
+	],[
+		struct block_device *bdev = NULL;
+		bdev_physical_block_size(bdev);
+	],[
+		AC_MSG_RESULT(yes)
+		AC_DEFINE(HAVE_BDEV_PHYSICAL_BLOCK_SIZE, 1,
+		          [bdev_physical_block_size() is available])
+	],[
+		AC_MSG_RESULT(no)
+	])
+	EXTRA_KCFLAGS="$tmp_flags"
+])
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/config/kernel-bdi-setup-and-register.m4
@@ -0,0 +1,38 @@
+dnl #
+dnl # 2.6.32 - 2.6.33, bdi_setup_and_register() is not exported.
+dnl # 2.6.34 - 3.19, bdi_setup_and_register() takes 3 arguments.
+dnl # 4.0 - x.y, bdi_setup_and_register() takes 2 arguments.
+dnl #
+AC_DEFUN([ZFS_AC_KERNEL_BDI_SETUP_AND_REGISTER], [
+	AC_MSG_CHECKING([whether bdi_setup_and_register() wants 2 args])
+	ZFS_LINUX_TRY_COMPILE_SYMBOL([
+		#include <linux/backing-dev.h>
+		struct backing_dev_info bdi;
+	], [
+		char *name = "bdi";
+		int error __attribute__((unused)) =
+		    bdi_setup_and_register(&bdi, name);
+	], [bdi_setup_and_register], [mm/backing-dev.c], [
+		AC_MSG_RESULT(yes)
+		AC_DEFINE(HAVE_2ARGS_BDI_SETUP_AND_REGISTER, 1,
+		    [bdi_setup_and_register() wants 2 args])
+	], [
+		AC_MSG_RESULT(no)
+		AC_MSG_CHECKING([whether bdi_setup_and_register() wants 3 args])
+		ZFS_LINUX_TRY_COMPILE_SYMBOL([
+			#include <linux/backing-dev.h>
+			struct backing_dev_info bdi;
+		], [
+			char *name = "bdi";
+			unsigned int cap = BDI_CAP_MAP_COPY;
+			int error __attribute__((unused)) =
+			    bdi_setup_and_register(&bdi, name, cap);
+		], [bdi_setup_and_register], [mm/backing-dev.c], [
+			AC_MSG_RESULT(yes)
+			AC_DEFINE(HAVE_3ARGS_BDI_SETUP_AND_REGISTER, 1,
+			    [bdi_setup_and_register() wants 3 args])
+		], [
+			AC_MSG_RESULT(no)
+		])
+	])
+])
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/config/kernel-bio-bvec-iter.m4
@@ -0,0 +1,20 @@
+dnl #
+dnl # 3.14 API change,
+dnl # Immutable biovecs. A number of fields of struct bio are moved to
+dnl # struct bvec_iter.
+dnl #
+AC_DEFUN([ZFS_AC_KERNEL_BIO_BVEC_ITER], [
+	AC_MSG_CHECKING([whether bio has bi_iter])
+	ZFS_LINUX_TRY_COMPILE([
+		#include <linux/bio.h>
+	],[
+		struct bio bio;
+		bio.bi_iter.bi_sector = 0;
+	],[
+		AC_MSG_RESULT(yes)
+		AC_DEFINE(HAVE_BIO_BVEC_ITER, 1, [bio has bi_iter])
+	],[
+		AC_MSG_RESULT(no)
+	])
+])
+
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/config/kernel-bio-end-io-t-args.m4
@@ -0,0 +1,24 @@
+dnl #
+dnl # 4.3 API change
+dnl # Error argument dropped from bio_endio in favor of newly introduced
+dnl # bio->bi_error. This also replaces bio->bi_flags value BIO_UPTODATE.
+dnl # Introduced by torvalds/linux@4246a0b63bd8f56a1469b12eafeb875b1041a451
+dnl # ("block: add a bi_error field to struct bio").
+dnl #
+AC_DEFUN([ZFS_AC_KERNEL_BIO_END_IO_T_ARGS], [
+	AC_MSG_CHECKING([whether bio_end_io_t wants 1 arg])
+	ZFS_LINUX_TRY_COMPILE([
+		#include <linux/bio.h>
+
+		void wanted_end_io(struct bio *bio) { return; }
+
+		bio_end_io_t *end_io __attribute__ ((unused)) = wanted_end_io;
+	],[
+	],[
+		AC_MSG_RESULT(yes)
+		AC_DEFINE(HAVE_1ARG_BIO_END_IO_T, 1,
+			  [bio_end_io_t wants 1 arg])
+	],[
+		AC_MSG_RESULT(no)
+	])
+])
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/config/kernel-bio-failfast.m4
@@ -0,0 +1,39 @@
+dnl #
+dnl # Preferred interface for setting FAILFAST on a bio:
+dnl #   2.6.28-2.6.35: BIO_RW_FAILFAST_{DEV|TRANSPORT|DRIVER}
+dnl #       >= 2.6.36: REQ_FAILFAST_{DEV|TRANSPORT|DRIVER}
+dnl #
+
+AC_DEFUN([ZFS_AC_KERNEL_BIO_FAILFAST_DTD], [
+	AC_MSG_CHECKING([whether BIO_RW_FAILFAST_* are defined])
+	ZFS_LINUX_TRY_COMPILE([
+		#include <linux/bio.h>
+	],[
+		int flags __attribute__ ((unused));
+		flags = ((1 << BIO_RW_FAILFAST_DEV) |
+			 (1 << BIO_RW_FAILFAST_TRANSPORT) |
+			 (1 << BIO_RW_FAILFAST_DRIVER));
+	],[
+		AC_MSG_RESULT(yes)
+		AC_DEFINE(HAVE_BIO_RW_FAILFAST_DTD, 1,
+		          [BIO_RW_FAILFAST_* are defined])
+	],[
+		AC_MSG_RESULT(no)
+	])
+])
+
+AC_DEFUN([ZFS_AC_KERNEL_REQ_FAILFAST_MASK], [
+	AC_MSG_CHECKING([whether REQ_FAILFAST_MASK is defined])
+	ZFS_LINUX_TRY_COMPILE([
+		#include <linux/bio.h>
+	],[
+		int flags __attribute__ ((unused));
+		flags = REQ_FAILFAST_MASK;
+	],[
+		AC_MSG_RESULT(yes)
+		AC_DEFINE(HAVE_REQ_FAILFAST_MASK, 1,
+		          [REQ_FAILFAST_MASK is defined])
+	],[
+		AC_MSG_RESULT(no)
+	])
+])
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/config/kernel-bio-rw-barrier.m4
@@ -0,0 +1,25 @@
+dnl #
+dnl # Interface for issuing a discard bio:
+dnl # 2.6.28-2.6.35: BIO_RW_BARRIER
+dnl # 2.6.36-3.x:    REQ_BARRIER
+dnl #
+
+dnl # Since REQ_BARRIER is a preprocessor definition, there is no need for an
+dnl # autotools check for it. Also, REQ_BARRIER existed in the request layer
+dnl # until torvalds/linux@7b6d91daee5cac6402186ff224c3af39d79f4a0e unified the
+dnl # request layer and bio layer flags, so it would be wrong to assume that
+dnl # the APIs are mutually exclusive contrary to the typical case.
+AC_DEFUN([ZFS_AC_KERNEL_BIO_RW_BARRIER], [
+	AC_MSG_CHECKING([whether BIO_RW_BARRIER is defined])
+	ZFS_LINUX_TRY_COMPILE([
+		#include <linux/bio.h>
+	],[
+		int flags __attribute__ ((unused));
+		flags = BIO_RW_BARRIER;
+	],[
+		AC_MSG_RESULT(yes)
+		AC_DEFINE(HAVE_BIO_RW_BARRIER, 1, [BIO_RW_BARRIER is defined])
+	],[
+		AC_MSG_RESULT(no)
+	])
+])
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/config/kernel-bio-rw-discard.m4
@@ -0,0 +1,25 @@
+dnl #
+dnl # Interface for issuing a discard bio:
+dnl # 2.6.28-2.6.35: BIO_RW_DISCARD
+dnl # 2.6.36-3.x:    REQ_DISCARD
+dnl #
+
+dnl # Since REQ_DISCARD is a preprocessor definition, there is no need for an
+dnl # autotools check for it. Also, REQ_DISCARD existed in the request layer
+dnl # until torvalds/linux@7b6d91daee5cac6402186ff224c3af39d79f4a0e unified the
+dnl # request layer and bio layer flags, so it would be wrong to assume that
+dnl # the APIs are mutually exclusive contrary to the typical case.
+AC_DEFUN([ZFS_AC_KERNEL_BIO_RW_DISCARD], [
+	AC_MSG_CHECKING([whether BIO_RW_DISCARD is defined])
+	ZFS_LINUX_TRY_COMPILE([
+		#include <linux/bio.h>
+	],[
+		int flags __attribute__ ((unused));
+		flags = BIO_RW_DISCARD;
+	],[
+		AC_MSG_RESULT(yes)
+		AC_DEFINE(HAVE_BIO_RW_DISCARD, 1, [BIO_RW_DISCARD is defined])
+	],[
+		AC_MSG_RESULT(no)
+	])
+])
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/config/kernel-blk-queue-flush.m4
@@ -0,0 +1,46 @@
+dnl #
+dnl # 2.6.36 API change
+dnl # In 2.6.36 kernels the blk_queue_ordered() interface has been
+dnl # replaced by the simpler blk_queue_flush().  However, while the
+dnl # old interface was available to all the new one is GPL-only.
+dnl # Thus in addition to detecting if this function is available
+dnl # we determine if it is GPL-only.  If the GPL-only interface is
+dnl # there we implement our own compatibility function, otherwise
+dnl # we use the function.  The hope is that long term this function
+dnl # will be opened up.
+dnl #
+AC_DEFUN([ZFS_AC_KERNEL_BLK_QUEUE_FLUSH], [
+	AC_MSG_CHECKING([whether blk_queue_flush() is available])
+	tmp_flags="$EXTRA_KCFLAGS"
+	EXTRA_KCFLAGS="${NO_UNUSED_BUT_SET_VARIABLE}"
+	ZFS_LINUX_TRY_COMPILE([
+		#include <linux/blkdev.h>
+	],[
+		struct request_queue *q = NULL;
+		(void) blk_queue_flush(q, REQ_FLUSH);
+	],[
+		AC_MSG_RESULT(yes)
+		AC_DEFINE(HAVE_BLK_QUEUE_FLUSH, 1,
+		          [blk_queue_flush() is available])
+	],[
+		AC_MSG_RESULT(no)
+	])
+
+	AC_MSG_CHECKING([whether blk_queue_flush() is GPL-only])
+	ZFS_LINUX_TRY_COMPILE([
+		#include <linux/module.h>
+		#include <linux/blkdev.h>
+
+		MODULE_LICENSE("$ZFS_META_LICENSE");
+	],[
+		struct request_queue *q = NULL;
+		(void) blk_queue_flush(q, REQ_FLUSH);
+	],[
+		AC_MSG_RESULT(no)
+	],[
+		AC_MSG_RESULT(yes)
+		AC_DEFINE(HAVE_BLK_QUEUE_FLUSH_GPL_ONLY, 1,
+		          [blk_queue_flush() is GPL-only])
+	])
+	EXTRA_KCFLAGS="$tmp_flags"
+])
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/config/kernel-blk-queue-max-hw-sectors.m4
@@ -0,0 +1,22 @@
+dnl #
+dnl # 2.6.34 API change
+dnl # blk_queue_max_hw_sectors() replaces blk_queue_max_sectors().
+dnl #
+AC_DEFUN([ZFS_AC_KERNEL_BLK_QUEUE_MAX_HW_SECTORS], [
+	AC_MSG_CHECKING([whether blk_queue_max_hw_sectors() is available])
+	tmp_flags="$EXTRA_KCFLAGS"
+	EXTRA_KCFLAGS="${NO_UNUSED_BUT_SET_VARIABLE}"
+	ZFS_LINUX_TRY_COMPILE([
+		#include <linux/blkdev.h>
+	],[
+		struct request_queue *q = NULL;
+		(void) blk_queue_max_hw_sectors(q, BLK_SAFE_MAX_SECTORS);
+	],[
+		AC_MSG_RESULT(yes)
+		AC_DEFINE(HAVE_BLK_QUEUE_MAX_HW_SECTORS, 1,
+		          [blk_queue_max_hw_sectors() is available])
+	],[
+		AC_MSG_RESULT(no)
+	])
+	EXTRA_KCFLAGS="$tmp_flags"
+])
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/config/kernel-blk-queue-max-segments.m4
@@ -0,0 +1,23 @@
+dnl #
+dnl # 2.6.34 API change
+dnl # blk_queue_max_segments() consolidates blk_queue_max_hw_segments()
+dnl # and blk_queue_max_phys_segments().
+dnl #
+AC_DEFUN([ZFS_AC_KERNEL_BLK_QUEUE_MAX_SEGMENTS], [
+	AC_MSG_CHECKING([whether blk_queue_max_segments() is available])
+	tmp_flags="$EXTRA_KCFLAGS"
+	EXTRA_KCFLAGS="${NO_UNUSED_BUT_SET_VARIABLE}"
+	ZFS_LINUX_TRY_COMPILE([
+		#include <linux/blkdev.h>
+	],[
+		struct request_queue *q = NULL;
+		(void) blk_queue_max_segments(q, BLK_MAX_SEGMENTS);
+	],[
+		AC_MSG_RESULT(yes)
+		AC_DEFINE(HAVE_BLK_QUEUE_MAX_SEGMENTS, 1,
+		          [blk_queue_max_segments() is available])
+	],[
+		AC_MSG_RESULT(no)
+	])
+	EXTRA_KCFLAGS="$tmp_flags"
+])
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/config/kernel-blkdev-get-by-path.m4
@@ -0,0 +1,19 @@
+dnl #
+dnl # 2.6.38 API change
+dnl # open_bdev_exclusive() changed to blkdev_get_by_path()
+dnl # close_bdev_exclusive() changed to blkdev_put()
+dnl #
+AC_DEFUN([ZFS_AC_KERNEL_BLKDEV_GET_BY_PATH],
+	[AC_MSG_CHECKING([whether blkdev_get_by_path() is available])
+	ZFS_LINUX_TRY_COMPILE_SYMBOL([
+		#include <linux/fs.h>
+	], [
+		blkdev_get_by_path(NULL, 0, NULL);
+	], [blkdev_get_by_path], [fs/block_dev.c], [
+		AC_MSG_RESULT(yes)
+		AC_DEFINE(HAVE_BLKDEV_GET_BY_PATH, 1,
+		          [blkdev_get_by_path() is available])
+	], [
+		AC_MSG_RESULT(no)
+	])
+])
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/config/kernel-blkdev-get.m4
@@ -0,0 +1,19 @@
+dnl #
+dnl # 2.6.37 API change
+dnl # Added 3rd argument for the active holder, previously this was
+dnl # hardcoded to NULL.
+dnl #
+AC_DEFUN([ZFS_AC_KERNEL_3ARG_BLKDEV_GET], [
+	AC_MSG_CHECKING([whether blkdev_get() wants 3 args])
+	ZFS_LINUX_TRY_COMPILE([
+		#include <linux/fs.h>
+	],[
+		struct block_device *bdev = NULL;
+		(void) blkdev_get(bdev, 0, NULL);
+	],[
+		AC_MSG_RESULT(yes)
+		AC_DEFINE(HAVE_3ARG_BLKDEV_GET, 1, [blkdev_get() wants 3 args])
+	],[
+		AC_MSG_RESULT(no)
+	])
+])
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/config/kernel-block-device-operations-release-void.m4
@@ -0,0 +1,29 @@
+dnl #
+dnl # 3.10.x API change
+dnl #
+AC_DEFUN([ZFS_AC_KERNEL_BLOCK_DEVICE_OPERATIONS_RELEASE_VOID], [
+	AC_MSG_CHECKING([whether block_device_operations.release is void])
+	tmp_flags="$EXTRA_KCFLAGS"
+	EXTRA_KCFLAGS="${NO_UNUSED_BUT_SET_VARIABLE}"
+	ZFS_LINUX_TRY_COMPILE([
+		#include <linux/blkdev.h>
+
+		void blk_release(struct gendisk *g, fmode_t mode) { return; }
+
+		static const struct block_device_operations
+		    bops __attribute__ ((unused)) = {
+			.open		= NULL,
+			.release	= blk_release,
+			.ioctl		= NULL,
+			.compat_ioctl	= NULL,
+		};
+	],[
+	],[
+		AC_MSG_RESULT(void)
+		AC_DEFINE(HAVE_BLOCK_DEVICE_OPERATIONS_RELEASE_VOID, 1,
+		          [struct block_device_operations.release returns void])
+	],[
+		AC_MSG_RESULT(int)
+	])
+	EXTRA_KCFLAGS="$tmp_flags"
+])
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/config/kernel-check-disk-size-change.m4
@@ -0,0 +1,18 @@
+dnl #
+dnl # 2.6.28 API change
+dnl # Added check_disk_size_change() helper function.
+dnl #
+AC_DEFUN([ZFS_AC_KERNEL_CHECK_DISK_SIZE_CHANGE],
+	[AC_MSG_CHECKING([whether check_disk_size_change() is available])
+	ZFS_LINUX_TRY_COMPILE_SYMBOL([
+		#include <linux/fs.h>
+	], [
+		check_disk_size_change(NULL, NULL);
+	], [check_disk_size_change], [fs/block_dev.c], [
+		AC_MSG_RESULT(yes)
+		AC_DEFINE(HAVE_CHECK_DISK_SIZE_CHANGE, 1,
+		          [check_disk_size_change() is available])
+	], [
+		AC_MSG_RESULT(no)
+	])
+])
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/config/kernel-clear-inode.m4
@@ -0,0 +1,34 @@
+dnl #
+dnl # 3.5.0 API change
+dnl # torvalds/linux@dbd5768f87ff6fb0a4fe09c4d7b6c4a24de99430 and
+dnl # torvalds/linux@7994e6f7254354e03028a11f98a27bd67dace9f1 reworked
+dnl # where inode_sync_wait() is called.
+dnl #
+dnl # Prior to these changes it would occur in end_writeback() but due
+dnl # to various issues (described in the above commits) it has been
+dnl # moved to evict().   This changes the ordering is which sync occurs
+dnl # but otherwise doesn't impact the zpl implementation.
+dnl #
+dnl # The major impact here is the renaming of end_writeback() to
+dnl # clear_inode().  However, care must be taken when detecting this
+dnl # API change because as recently as 2.6.35 there was a clear_inode()
+dnl # function.  However, it was made obsolete by the evict_inode() API
+dnl # change at the same time.
+dnl #
+dnl # Therefore, to ensure we have the correct API we only allow the
+dnl # clear_inode() compatibility code to be defined iff the evict_inode()
+dnl # functionality is also detected.
+dnl #
+AC_DEFUN([ZFS_AC_KERNEL_CLEAR_INODE],
+	[AC_MSG_CHECKING([whether clear_inode() is available])
+	ZFS_LINUX_TRY_COMPILE_SYMBOL([
+		#include <linux/fs.h>
+	], [
+		clear_inode(NULL);
+	], [clear_inode], [fs/inode.c], [
+		AC_MSG_RESULT(yes)
+		AC_DEFINE(HAVE_CLEAR_INODE, 1, [clear_inode() is available])
+	], [
+		AC_MSG_RESULT(no)
+	])
+])
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/config/kernel-commit-metadata.m4
@@ -0,0 +1,23 @@
+dnl #
+dnl # 2.6.33 API change
+dnl # Added eops->commit_metadata() callback to allow the underlying
+dnl # filesystem to determine the most efficient way to commit the inode.
+dnl # Prior to this the nfs server would issue an explicit fsync().
+dnl #
+AC_DEFUN([ZFS_AC_KERNEL_COMMIT_METADATA], [
+	AC_MSG_CHECKING([whether eops->commit_metadata() exists])
+	ZFS_LINUX_TRY_COMPILE([
+		#include <linux/exportfs.h>
+		int commit_metadata(struct inode *inode) { return 0; }
+		static struct export_operations eops __attribute__ ((unused))={
+			.commit_metadata = commit_metadata,
+		};
+	],[
+	],[
+		AC_MSG_RESULT(yes)
+		AC_DEFINE(HAVE_COMMIT_METADATA, 1,
+		          [eops->commit_metadata() exists])
+	],[
+		AC_MSG_RESULT(no)
+	])
+])
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/config/kernel-create-nameidata.m4
@@ -0,0 +1,29 @@
+dnl #
+dnl # 3.6 API change
+dnl #
+AC_DEFUN([ZFS_AC_KERNEL_CREATE_NAMEIDATA], [
+	AC_MSG_CHECKING([whether iops->create() passes nameidata])
+	ZFS_LINUX_TRY_COMPILE([
+		#include <linux/fs.h>
+
+		#ifdef HAVE_MKDIR_UMODE_T
+		int inode_create(struct inode *inode ,struct dentry *dentry,
+		    umode_t umode, struct nameidata *nidata) { return 0; }
+		#else
+		int inode_create(struct inode *inode,struct dentry *dentry,
+		    int umode, struct nameidata * nidata) { return 0; }
+		#endif
+
+		static const struct inode_operations
+		    iops __attribute__ ((unused)) = {
+			.create		= inode_create,
+		};
+	],[
+	],[
+		AC_MSG_RESULT(yes)
+		AC_DEFINE(HAVE_CREATE_NAMEIDATA, 1,
+		          [iops->create() passes nameidata])
+	],[
+		AC_MSG_RESULT(no)
+	])
+])
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/config/kernel-current_bio_tail.m4
@@ -0,0 +1,33 @@
+dnl #
+dnl # 2.6.34 API change
+dnl # current->bio_tail and current->bio_list were struct bio pointers prior to
+dnl # Linux 2.6.34. They were refactored into a struct bio_list pointer called
+dnl # current->bio_list in Linux 2.6.34.
+dnl #
+AC_DEFUN([ZFS_AC_KERNEL_CURRENT_BIO_TAIL], [
+	AC_MSG_CHECKING([whether current->bio_tail exists])
+	ZFS_LINUX_TRY_COMPILE([
+		#include <linux/sched.h>
+	],[
+		current->bio_tail = (struct bio **) NULL;
+	],[
+		AC_MSG_RESULT(yes)
+		AC_DEFINE(HAVE_CURRENT_BIO_TAIL, 1,
+		    [current->bio_tail exists])
+	],[
+		AC_MSG_RESULT(no)
+		AC_MSG_CHECKING([whether current->bio_list exists])
+		ZFS_LINUX_TRY_COMPILE([
+			#include <linux/sched.h>
+		],[
+			current->bio_list = (struct bio_list *) NULL;
+		],[
+			AC_MSG_RESULT(yes)
+			AC_DEFINE(HAVE_CURRENT_BIO_LIST, 1,
+			    [current->bio_list exists])
+		],[
+			AC_MSG_ERROR(no - Please file a bug report at
+			    https://github.com/zfsonlinux/zfs/issues/new)
+		])
+	])
+])
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/config/kernel-d-make-root.m4
@@ -0,0 +1,17 @@
+dnl #
+dnl # 3.4.0 API change
+dnl # Added d_make_root() to replace previous d_alloc_root() function.
+dnl #
+AC_DEFUN([ZFS_AC_KERNEL_D_MAKE_ROOT],
+	[AC_MSG_CHECKING([whether d_make_root() is available])
+	ZFS_LINUX_TRY_COMPILE_SYMBOL([
+		#include <linux/dcache.h>
+	], [
+		d_make_root(NULL);
+	], [d_make_root], [fs/dcache.c], [
+		AC_MSG_RESULT(yes)
+		AC_DEFINE(HAVE_D_MAKE_ROOT, 1, [d_make_root() is available])
+	], [
+		AC_MSG_RESULT(no)
+	])
+])
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/config/kernel-d-obtain-alias.m4
@@ -0,0 +1,18 @@
+dnl #
+dnl # 2.6.28 API change
+dnl # Added d_obtain_alias() helper function.
+dnl #
+AC_DEFUN([ZFS_AC_KERNEL_D_OBTAIN_ALIAS],
+	[AC_MSG_CHECKING([whether d_obtain_alias() is available])
+	ZFS_LINUX_TRY_COMPILE_SYMBOL([
+		#include <linux/dcache.h>
+	], [
+		d_obtain_alias(NULL);
+	], [d_obtain_alias], [fs/dcache.c], [
+		AC_MSG_RESULT(yes)
+		AC_DEFINE(HAVE_D_OBTAIN_ALIAS, 1,
+		          [d_obtain_alias() is available])
+	], [
+		AC_MSG_RESULT(no)
+	])
+])
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/config/kernel-d-prune-aliases.m4
@@ -0,0 +1,19 @@
+dnl #
+dnl # 2.6.12 API change
+dnl # d_prune_aliases() helper function available.
+dnl #
+AC_DEFUN([ZFS_AC_KERNEL_D_PRUNE_ALIASES],
+	[AC_MSG_CHECKING([whether d_prune_aliases() is available])
+	ZFS_LINUX_TRY_COMPILE_SYMBOL([
+		#include <linux/dcache.h>
+	], [
+		struct inode *ip = NULL;
+		d_prune_aliases(ip);
+	], [d_prune_aliases], [fs/dcache.c], [
+		AC_MSG_RESULT(yes)
+		AC_DEFINE(HAVE_D_PRUNE_ALIASES, 1,
+		          [d_prune_aliases() is available])
+	], [
+		AC_MSG_RESULT(no)
+	])
+])
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/config/kernel-declare-event-class.m4
@@ -0,0 +1,59 @@
+dnl #
+dnl # Ensure the DECLARE_EVENT_CLASS macro is available to non-GPL modules.
+dnl #
+AC_DEFUN([ZFS_AC_KERNEL_DECLARE_EVENT_CLASS], [
+	tmp_flags="$EXTRA_KCFLAGS"
+	EXTRA_KCFLAGS="-I\$(src)"
+
+	AC_MSG_CHECKING([whether DECLARE_EVENT_CLASS() is available])
+	ZFS_LINUX_TRY_COMPILE_HEADER([
+		#include <linux/module.h>
+		MODULE_LICENSE(ZFS_META_LICENSE);
+
+		#define CREATE_TRACE_POINTS
+		#include "conftest.h"
+	],[
+		trace_zfs_autoconf_event_one(1UL);
+		trace_zfs_autoconf_event_two(2UL);
+	],[
+		AC_MSG_RESULT(yes)
+		AC_DEFINE(HAVE_DECLARE_EVENT_CLASS, 1,
+		          [DECLARE_EVENT_CLASS() is available])
+	],[
+		AC_MSG_RESULT(no)
+	],[
+		#if !defined(_CONFTEST_H) || defined(TRACE_HEADER_MULTI_READ)
+		#define _CONFTEST_H
+
+		#undef  TRACE_SYSTEM
+		#define TRACE_SYSTEM zfs
+		#include <linux/tracepoint.h>
+
+		DECLARE_EVENT_CLASS(zfs_autoconf_event_class,
+			TP_PROTO(unsigned long i),
+			TP_ARGS(i),
+			TP_STRUCT__entry(
+				__field(unsigned long, i)
+			),
+			TP_fast_assign(
+				__entry->i = i;
+			),
+			TP_printk("i = %lu", __entry->i)
+		);
+
+		#define DEFINE_AUTOCONF_EVENT(name) \
+		DEFINE_EVENT(zfs_autoconf_event_class, name, \
+			TP_PROTO(unsigned long i), \
+			TP_ARGS(i))
+		DEFINE_AUTOCONF_EVENT(zfs_autoconf_event_one);
+		DEFINE_AUTOCONF_EVENT(zfs_autoconf_event_two);
+
+		#endif /* _CONFTEST_H */
+
+		#undef  TRACE_INCLUDE_PATH
+		#define TRACE_INCLUDE_PATH .
+		#define TRACE_INCLUDE_FILE conftest
+		#include <trace/define_trace.h>
+	])
+	EXTRA_KCFLAGS="$tmp_flags"
+])
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/config/kernel-dentry-operations.m4
@@ -0,0 +1,87 @@
+dnl #
+dnl # 3.6 API change
+dnl #
+AC_DEFUN([ZFS_AC_KERNEL_D_REVALIDATE_NAMEIDATA], [
+	AC_MSG_CHECKING([whether dops->d_revalidate() takes struct nameidata])
+	ZFS_LINUX_TRY_COMPILE([
+		#include <linux/dcache.h>
+
+		int revalidate (struct dentry *dentry,
+		    struct nameidata *nidata) { return 0; }
+
+		static const struct dentry_operations
+		    dops __attribute__ ((unused)) = {
+			.d_revalidate	= revalidate,
+		};
+	],[
+	],[
+		AC_MSG_RESULT(yes)
+		AC_DEFINE(HAVE_D_REVALIDATE_NAMEIDATA, 1,
+		          [dops->d_revalidate() operation takes nameidata])
+	],[
+		AC_MSG_RESULT(no)
+	])
+])
+
+dnl #
+dnl # 2.6.30 API change
+dnl # The 'struct dentry_operations' was constified in the dentry structure.
+dnl #
+AC_DEFUN([ZFS_AC_KERNEL_CONST_DENTRY_OPERATIONS], [
+	AC_MSG_CHECKING([whether dentry uses const struct dentry_operations])
+	ZFS_LINUX_TRY_COMPILE([
+		#include <linux/dcache.h>
+
+		const struct dentry_operations test_d_op = {
+			.d_revalidate = NULL,
+		};
+	],[
+		struct dentry d __attribute__ ((unused));
+
+		d.d_op = &test_d_op;
+	],[
+		AC_MSG_RESULT(yes)
+		AC_DEFINE(HAVE_CONST_DENTRY_OPERATIONS, 1,
+		          [dentry uses const struct dentry_operations])
+	],[
+		AC_MSG_RESULT(no)
+	])
+])
+
+dnl #
+dnl # 2.6.38 API change
+dnl # Added d_set_d_op() helper function.
+dnl #
+AC_DEFUN([ZFS_AC_KERNEL_D_SET_D_OP],
+	[AC_MSG_CHECKING([whether d_set_d_op() is available])
+	ZFS_LINUX_TRY_COMPILE_SYMBOL([
+		#include <linux/dcache.h>
+	], [
+		d_set_d_op(NULL, NULL);
+	], [d_set_d_op], [fs/dcache.c], [
+		AC_MSG_RESULT(yes)
+		AC_DEFINE(HAVE_D_SET_D_OP, 1,
+		          [d_set_d_op() is available])
+	], [
+		AC_MSG_RESULT(no)
+	])
+])
+
+dnl #
+dnl # 2.6.38 API chage
+dnl # Added sb->s_d_op default dentry_operations member
+dnl #
+AC_DEFUN([ZFS_AC_KERNEL_S_D_OP],
+	[AC_MSG_CHECKING([whether super_block has s_d_op])
+	ZFS_LINUX_TRY_COMPILE([
+		#include <linux/fs.h>
+	],[
+		struct super_block sb __attribute__ ((unused));
+		sb.s_d_op = NULL;
+	], [
+		AC_MSG_RESULT(yes)
+		AC_DEFINE(HAVE_S_D_OP, 1, [struct super_block has s_d_op])
+	], [
+		AC_MSG_RESULT(no)
+	])
+])
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/config/kernel-dirty-inode.m4
@@ -0,0 +1,26 @@
+dnl #
+dnl # 3.0 API change
+dnl # The sops->dirty_inode() callbacks were updated to take a flags
+dnl # argument.  This allows the greater control over whether the
+dnl # filesystem needs to push out a transaction or not.
+dnl #
+AC_DEFUN([ZFS_AC_KERNEL_DIRTY_INODE_WITH_FLAGS], [
+	AC_MSG_CHECKING([whether sops->dirty_inode() wants flags])
+	ZFS_LINUX_TRY_COMPILE([
+		#include <linux/fs.h>
+
+		void dirty_inode(struct inode *a, int b) { return; }
+
+		static const struct super_operations
+		    sops __attribute__ ((unused)) = {
+			.dirty_inode = dirty_inode,
+		};
+	],[
+	],[
+		AC_MSG_RESULT([yes])
+		AC_DEFINE(HAVE_DIRTY_INODE_WITH_FLAGS, 1,
+			[sops->dirty_inode() wants flags])
+	],[
+		AC_MSG_RESULT([no])
+	])
+])
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/config/kernel-discard-granularity.m4
@@ -0,0 +1,20 @@
+dnl #
+dnl # 2.6.33 API change
+dnl # Discard granularity and alignment restrictions may now be set.
+dnl #
+AC_DEFUN([ZFS_AC_KERNEL_DISCARD_GRANULARITY], [
+	AC_MSG_CHECKING([whether ql->discard_granularity is available])
+	ZFS_LINUX_TRY_COMPILE([
+		#include <linux/blkdev.h>
+	],[
+		struct queue_limits ql __attribute__ ((unused));
+
+		ql.discard_granularity = 0;
+	],[
+		AC_MSG_RESULT(yes)
+		AC_DEFINE(HAVE_DISCARD_GRANULARITY, 1,
+		          [ql->discard_granularity is available])
+	],[
+		AC_MSG_RESULT(no)
+	])
+])
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/config/kernel-elevator-change.m4
@@ -0,0 +1,25 @@
+dnl #
+dnl # 2.6.36 API change
+dnl # Verify the elevator_change() symbol is available.
+dnl #
+AC_DEFUN([ZFS_AC_KERNEL_ELEVATOR_CHANGE], [
+	AC_MSG_CHECKING([whether elevator_change() is available])
+	tmp_flags="$EXTRA_KCFLAGS"
+	EXTRA_KCFLAGS="${NO_UNUSED_BUT_SET_VARIABLE}"
+	ZFS_LINUX_TRY_COMPILE([
+		#include <linux/blkdev.h>
+		#include <linux/elevator.h>
+	],[
+		int ret;
+		struct request_queue *q = NULL;
+		char *elevator = NULL;
+		ret = elevator_change(q, elevator);
+	],[
+		AC_MSG_RESULT(yes)
+		AC_DEFINE(HAVE_ELEVATOR_CHANGE, 1,
+			  [elevator_change() is available])
+	],[
+		AC_MSG_RESULT(no)
+	])
+	EXTRA_KCFLAGS="$tmp_flags"
+])
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/config/kernel-encode-fh-inode.m4
@@ -0,0 +1,24 @@
+dnl #
+dnl # 3.5.0 API change
+dnl # torvalds/linux@b0b0382bb4904965a9e9fca77ad87514dfda0d1c changed the
+dnl # ->encode_fh() callback to pass the child inode and its parents inode
+dnl # rather than a dentry and a boolean saying whether we want the parent.
+dnl #
+AC_DEFUN([ZFS_AC_KERNEL_ENCODE_FH_WITH_INODE], [
+	AC_MSG_CHECKING([whether eops->encode_fh() wants inode])
+	ZFS_LINUX_TRY_COMPILE([
+		#include <linux/exportfs.h>
+		int encode_fh(struct inode *inode, __u32 *fh, int *max_len,
+		              struct inode *parent) { return 0; }
+		static struct export_operations eops __attribute__ ((unused))={
+			.encode_fh = encode_fh,
+		};
+	],[
+	],[
+		AC_MSG_RESULT(yes)
+		AC_DEFINE(HAVE_ENCODE_FH_WITH_INODE, 1,
+		          [eops->encode_fh() wants child and parent inodes])
+	],[
+		AC_MSG_RESULT(no)
+	])
+])
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/config/kernel-evict-inode.m4
@@ -0,0 +1,21 @@
+dnl #
+dnl # 2.6.36 API change
+dnl # The sops->delete_inode() and sops->clear_inode() callbacks have
+dnl # replaced by a single sops->evict_inode() callback.
+dnl #
+AC_DEFUN([ZFS_AC_KERNEL_EVICT_INODE], [
+	AC_MSG_CHECKING([whether sops->evict_inode() exists])
+	ZFS_LINUX_TRY_COMPILE([
+		#include <linux/fs.h>
+		void evict_inode (struct inode * t) { return; }
+		static struct super_operations sops __attribute__ ((unused)) = {
+			.evict_inode = evict_inode,
+		};
+	],[
+	],[
+		AC_MSG_RESULT(yes)
+		AC_DEFINE(HAVE_EVICT_INODE, 1, [sops->evict_inode() exists])
+	],[
+		AC_MSG_RESULT(no)
+	])
+])
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/config/kernel-fallocate.m4
@@ -0,0 +1,56 @@
+dnl #
+dnl # Linux 2.6.38 - 3.x API
+dnl #
+AC_DEFUN([ZFS_AC_KERNEL_FILE_FALLOCATE], [
+	AC_MSG_CHECKING([whether fops->fallocate() exists])
+	ZFS_LINUX_TRY_COMPILE([
+		#include <linux/fs.h>
+
+		long test_fallocate(struct file *file, int mode,
+		    loff_t offset, loff_t len) { return 0; }
+
+		static const struct file_operations
+		    fops __attribute__ ((unused)) = {
+			.fallocate = test_fallocate,
+		};
+	],[
+	],[
+		AC_MSG_RESULT(yes)
+		AC_DEFINE(HAVE_FILE_FALLOCATE, 1, [fops->fallocate() exists])
+	],[
+		AC_MSG_RESULT(no)
+	])
+])
+
+dnl #
+dnl # Linux 2.6.x - 2.6.37 API
+dnl #
+AC_DEFUN([ZFS_AC_KERNEL_INODE_FALLOCATE], [
+	AC_MSG_CHECKING([whether iops->fallocate() exists])
+	ZFS_LINUX_TRY_COMPILE([
+		#include <linux/fs.h>
+
+		long test_fallocate(struct inode *inode, int mode,
+		    loff_t offset, loff_t len) { return 0; }
+
+		static const struct inode_operations
+		    fops __attribute__ ((unused)) = {
+			.fallocate = test_fallocate,
+		};
+	],[
+	],[
+		AC_MSG_RESULT(yes)
+		AC_DEFINE(HAVE_INODE_FALLOCATE, 1, [fops->fallocate() exists])
+	],[
+		AC_MSG_RESULT(no)
+	])
+])
+
+dnl #
+dnl # The fallocate callback was moved from the inode_operations
+dnl # structure to the file_operations structure.
+dnl #
+AC_DEFUN([ZFS_AC_KERNEL_FALLOCATE], [
+	ZFS_AC_KERNEL_FILE_FALLOCATE
+	ZFS_AC_KERNEL_INODE_FALLOCATE
+])
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/config/kernel-file-inode.m4
@@ -0,0 +1,19 @@
+dnl #
+dnl # 3.19 API change
+dnl # struct access f->f_dentry->d_inode was replaced by accessor function
+dnl # file_inode(f)
+dnl #
+AC_DEFUN([ZFS_AC_KERNEL_FILE_INODE], [
+	AC_MSG_CHECKING([whether file_inode() is available])
+	ZFS_LINUX_TRY_COMPILE([
+		#include <linux/fs.h>
+	],[
+		struct file *f = NULL;
+		file_inode(f);
+	],[
+		AC_MSG_RESULT(yes)
+		AC_DEFINE(HAVE_FILE_INODE, 1, [file_inode() is available])
+	],[
+		AC_MSG_RESULT(no)
+	])
+])
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/config/kernel-fmode-t.m4
@@ -0,0 +1,18 @@
+dnl #
+dnl # 2.6.28 API change,
+dnl # check if fmode_t typedef is defined
+dnl #
+AC_DEFUN([ZFS_AC_KERNEL_TYPE_FMODE_T],
+	[AC_MSG_CHECKING([whether kernel defines fmode_t])
+	ZFS_LINUX_TRY_COMPILE([
+		#include <linux/types.h>
+	],[
+		fmode_t *ptr __attribute__ ((unused));
+	],[
+		AC_MSG_RESULT([yes])
+		AC_DEFINE(HAVE_FMODE_T, 1,
+		          [kernel defines fmode_t])
+	],[
+		AC_MSG_RESULT([no])
+	])
+])
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/config/kernel-follow-down-one.m4
@@ -0,0 +1,20 @@
+dnl #
+dnl # 2.6.38 API change
+dnl # follow_down() renamed follow_down_one().  The original follow_down()
+dnl # symbol still exists but will traverse down all the layers.
+dnl #
+AC_DEFUN([ZFS_AC_KERNEL_FOLLOW_DOWN_ONE], [
+	AC_MSG_CHECKING([whether follow_down_one() is available])
+	ZFS_LINUX_TRY_COMPILE([
+		#include <linux/namei.h>
+	],[
+		struct path *p = NULL;
+		follow_down_one(p);
+	],[
+		AC_MSG_RESULT(yes)
+		AC_DEFINE(HAVE_FOLLOW_DOWN_ONE, 1,
+		    [follow_down_one() is available])
+	],[
+		AC_MSG_RESULT(no)
+	])
+])
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/config/kernel-fsync.m4
@@ -0,0 +1,74 @@
+dnl #
+dnl # Linux 2.6.x - 2.6.34 API
+dnl #
+AC_DEFUN([ZFS_AC_KERNEL_FSYNC_WITH_DENTRY], [
+	ZFS_LINUX_TRY_COMPILE([
+		#include <linux/fs.h>
+
+		int test_fsync(struct file *f, struct dentry *dentry, int x)
+		    { return 0; }
+
+		static const struct file_operations
+		    fops __attribute__ ((unused)) = {
+			.fsync = test_fsync,
+		};
+	],[
+	],[
+		AC_MSG_RESULT([dentry])
+		AC_DEFINE(HAVE_FSYNC_WITH_DENTRY, 1,
+			[fops->fsync() with dentry])
+	],[
+	])
+])
+
+dnl #
+dnl # Linux 2.6.35 - Linux 3.0 API
+dnl #
+AC_DEFUN([ZFS_AC_KERNEL_FSYNC_WITHOUT_DENTRY], [
+	ZFS_LINUX_TRY_COMPILE([
+		#include <linux/fs.h>
+
+		int test_fsync(struct file *f, int x) { return 0; }
+
+		static const struct file_operations
+		    fops __attribute__ ((unused)) = {
+			.fsync = test_fsync,
+		};
+	],[
+	],[
+		AC_MSG_RESULT([no dentry])
+		AC_DEFINE(HAVE_FSYNC_WITHOUT_DENTRY, 1,
+			[fops->fsync() without dentry])
+	],[
+	])
+])
+
+dnl #
+dnl # Linux 3.1 - 3.x API
+dnl #
+AC_DEFUN([ZFS_AC_KERNEL_FSYNC_RANGE], [
+	ZFS_LINUX_TRY_COMPILE([
+		#include <linux/fs.h>
+
+		int test_fsync(struct file *f, loff_t a, loff_t b, int c)
+		    { return 0; }
+
+		static const struct file_operations
+		    fops __attribute__ ((unused)) = {
+			.fsync = test_fsync,
+		};
+	],[
+	],[
+		AC_MSG_RESULT([range])
+		AC_DEFINE(HAVE_FSYNC_RANGE, 1,
+			[fops->fsync() with range])
+	],[
+	])
+])
+
+AC_DEFUN([ZFS_AC_KERNEL_FSYNC], [
+	AC_MSG_CHECKING([whether fops->fsync() wants])
+	ZFS_AC_KERNEL_FSYNC_WITH_DENTRY
+	ZFS_AC_KERNEL_FSYNC_WITHOUT_DENTRY
+	ZFS_AC_KERNEL_FSYNC_RANGE
+])
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/config/kernel-generic_io_acct.m4
@@ -0,0 +1,26 @@
+dnl #
+dnl # 3.19 API addition
+dnl #
+dnl # torvalds/linux@394ffa503bc40e32d7f54a9b817264e81ce131b4 allows us to
+dnl # increment iostat counters without generic_make_request().
+dnl #
+AC_DEFUN([ZFS_AC_KERNEL_GENERIC_IO_ACCT], [
+	AC_MSG_CHECKING([whether generic IO accounting symbols are avaliable])
+	ZFS_LINUX_TRY_COMPILE_SYMBOL([
+		#include <linux/bio.h>
+
+		void (*generic_start_io_acct_f)(int, unsigned long,
+		    struct hd_struct *) = &generic_start_io_acct;
+		void (*generic_end_io_acct_f)(int, struct hd_struct *,
+		    unsigned long) = &generic_end_io_acct;
+	], [
+		generic_start_io_acct(0, 0, NULL);
+		generic_end_io_acct(0, NULL, 0);
+	], [generic_start_io_acct], [block/bio.c], [
+		AC_MSG_RESULT(yes)
+		AC_DEFINE(HAVE_GENERIC_IO_ACCT, 1,
+		    [generic_start_io_acct()/generic_end_io_acct() avaliable])
+	], [
+		AC_MSG_RESULT(no)
+	])
+])
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/config/kernel-get-disk-ro.m4
@@ -0,0 +1,21 @@
+dnl #
+dnl # 2.6.x API change
+dnl #
+AC_DEFUN([ZFS_AC_KERNEL_GET_DISK_RO], [
+	AC_MSG_CHECKING([whether get_disk_ro() is available])
+	tmp_flags="$EXTRA_KCFLAGS"
+	EXTRA_KCFLAGS="${NO_UNUSED_BUT_SET_VARIABLE}"
+	ZFS_LINUX_TRY_COMPILE([
+		#include <linux/blkdev.h>
+	],[
+		struct gendisk *disk = NULL;
+		(void) get_disk_ro(disk);
+	],[
+		AC_MSG_RESULT(yes)
+		AC_DEFINE(HAVE_GET_DISK_RO, 1,
+		          [blk_disk_ro() is available])
+	],[
+		AC_MSG_RESULT(no)
+	])
+	EXTRA_KCFLAGS="$tmp_flags"
+])
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/config/kernel-get-gendisk.m4
@@ -0,0 +1,17 @@
+dnl #
+dnl # 2.6.34 API change
+dnl # Verify the get_gendisk() symbol is available.
+dnl #
+AC_DEFUN([ZFS_AC_KERNEL_GET_GENDISK],
+	[AC_MSG_CHECKING([whether get_gendisk() is available])
+	ZFS_LINUX_TRY_COMPILE_SYMBOL([
+		#include <linux/genhd.h>
+	], [
+		get_gendisk(0, NULL);
+	], [get_gendisk], [block/genhd.c], [
+		AC_MSG_RESULT(yes)
+		AC_DEFINE(HAVE_GET_GENDISK, 1, [get_gendisk() is available])
+	], [
+		AC_MSG_RESULT(no)
+	])
+])
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/config/kernel-get-link.m4
@@ -0,0 +1,100 @@
+dnl #
+dnl # Supported get_link() interfaces checked newest to oldest.
+dnl #
+AC_DEFUN([ZFS_AC_KERNEL_FOLLOW_LINK], [
+	dnl #
+	dnl # 4.2 API change
+	dnl # - This kernel retired the nameidata structure.
+	dnl #
+	AC_MSG_CHECKING([whether iops->follow_link() passes cookie])
+	ZFS_LINUX_TRY_COMPILE([
+		#include <linux/fs.h>
+		const char *follow_link(struct dentry *de,
+		    void **cookie) { return "symlink"; }
+		static struct inode_operations
+		    iops __attribute__ ((unused)) = {
+			.follow_link = follow_link,
+		};
+	],[
+	],[
+		AC_MSG_RESULT(yes)
+		AC_DEFINE(HAVE_FOLLOW_LINK_COOKIE, 1,
+		    [iops->follow_link() cookie])
+	],[
+		dnl #
+		dnl # 2.6.32 API
+		dnl #
+		AC_MSG_RESULT(no)
+		AC_MSG_CHECKING(
+		   [whether iops->follow_link() passes nameidata])
+		ZFS_LINUX_TRY_COMPILE([
+		#include <linux/fs.h>
+			void *follow_link(struct dentry *de, struct
+			    nameidata *nd) { return (void *)NULL; }
+			static struct inode_operations
+			    iops __attribute__ ((unused)) = {
+				.follow_link = follow_link,
+			};
+		],[
+		],[
+			AC_MSG_RESULT(yes)
+			AC_DEFINE(HAVE_FOLLOW_LINK_NAMEIDATA, 1,
+			          [iops->follow_link() nameidata])
+		],[
+                        AC_MSG_ERROR(no; please file a bug report)
+		])
+	])
+])
+
+AC_DEFUN([ZFS_AC_KERNEL_GET_LINK], [
+	dnl #
+	dnl # 4.5 API change
+	dnl # The get_link interface has added a delayed done call and
+	dnl # used it to retire the put_link() interface.
+	dnl #
+	AC_MSG_CHECKING([whether iops->get_link() passes delayed])
+	ZFS_LINUX_TRY_COMPILE([
+		#include <linux/fs.h>
+		const char *get_link(struct dentry *de, struct inode *ip,
+		    struct delayed_call *done) { return "symlink"; }
+		static struct inode_operations
+		     iops __attribute__ ((unused)) = {
+			.get_link = get_link,
+		};
+	],[
+	],[
+		AC_MSG_RESULT(yes)
+		AC_DEFINE(HAVE_GET_LINK_DELAYED, 1,
+		    [iops->get_link() delayed])
+	],[
+		dnl #
+		dnl # 4.5 API change
+		dnl # The follow_link() interface has been replaced by
+		dnl # get_link() which behaves the same as before except:
+		dnl # - An inode is passed as a separate argument
+		dnl # - When called in RCU mode a NULL dentry is passed.
+		dnl #
+		AC_MSG_RESULT(no)
+		AC_MSG_CHECKING([whether iops->get_link() passes cookie])
+		ZFS_LINUX_TRY_COMPILE([
+			#include <linux/fs.h>
+			const char *get_link(struct dentry *de, struct
+			    inode *ip, void **cookie) { return "symlink"; }
+			static struct inode_operations
+			     iops __attribute__ ((unused)) = {
+				.get_link = get_link,
+			};
+		],[
+		],[
+			AC_MSG_RESULT(yes)
+			AC_DEFINE(HAVE_GET_LINK_COOKIE, 1,
+			    [iops->get_link() cookie])
+		],[
+			dnl #
+			dnl # Check for the follow_link APIs.
+			dnl #
+			AC_MSG_RESULT(no)
+			ZFS_AC_KERNEL_FOLLOW_LINK
+		])
+	])
+])
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/config/kernel-insert-inode-locked.m4
@@ -0,0 +1,18 @@
+dnl #
+dnl # 2.6.28 API change
+dnl # Added insert_inode_locked() helper function.
+dnl #
+AC_DEFUN([ZFS_AC_KERNEL_INSERT_INODE_LOCKED],
+	[AC_MSG_CHECKING([whether insert_inode_locked() is available])
+	ZFS_LINUX_TRY_COMPILE_SYMBOL([
+		#include <linux/fs.h>
+	], [
+		insert_inode_locked(NULL);
+	], [insert_inode_locked], [fs/inode.c], [
+		AC_MSG_RESULT(yes)
+		AC_DEFINE(HAVE_INSERT_INODE_LOCKED, 1,
+		          [insert_inode_locked() is available])
+	], [
+		AC_MSG_RESULT(no)
+	])
+])
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/config/kernel-invalidate-bdev-args.m4
@@ -0,0 +1,19 @@
+dnl #
+dnl # 2.6.22 API change
+dnl # Unused destroy_dirty_buffers arg removed from prototype.
+dnl #
+AC_DEFUN([ZFS_AC_KERNEL_INVALIDATE_BDEV_ARGS], [
+	AC_MSG_CHECKING([whether invalidate_bdev() wants 1 arg])
+	ZFS_LINUX_TRY_COMPILE([
+		#include <linux/buffer_head.h>
+	],[
+		struct block_device *bdev = NULL;
+		invalidate_bdev(bdev);
+	],[
+		AC_MSG_RESULT(yes)
+		AC_DEFINE(HAVE_1ARG_INVALIDATE_BDEV, 1,
+		          [invalidate_bdev() wants 1 arg])
+	],[
+		AC_MSG_RESULT(no)
+	])
+])
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/config/kernel-is_owner_or_cap.m4
@@ -0,0 +1,36 @@
+dnl #
+dnl # 2.6.39 API change,
+dnl # The is_owner_or_cap() macro was renamed to inode_owner_or_capable(),
+dnl # This is used for permission checks in the xattr and file attribute call
+dnl # paths.
+dnl #
+AC_DEFUN([ZFS_AC_KERNEL_INODE_OWNER_OR_CAPABLE], [
+	AC_MSG_CHECKING([whether inode_owner_or_capable() exists])
+	ZFS_LINUX_TRY_COMPILE([
+		#include <linux/fs.h>
+	],[
+		struct inode *ip = NULL;
+		(void) inode_owner_or_capable(ip);
+	],[
+		AC_MSG_RESULT(yes)
+		AC_DEFINE(HAVE_INODE_OWNER_OR_CAPABLE, 1,
+		    [inode_owner_or_capable() exists])
+	],[
+		AC_MSG_RESULT(no)
+		AC_MSG_CHECKING([whether is_owner_or_cap() exists])
+		ZFS_LINUX_TRY_COMPILE([
+			#include <linux/fs.h>
+			#include <linux/sched.h>
+		],[
+			struct inode *ip = NULL;
+			(void) is_owner_or_cap(ip);
+		],[
+			AC_MSG_RESULT(yes)
+			AC_DEFINE(HAVE_IS_OWNER_OR_CAP, 1,
+			    [is_owner_or_cap() exists])
+		],[
+			AC_MSG_ERROR(no - Please file a bug report at
+			    https://github.com/zfsonlinux/zfs/issues/new)
+		])
+	])
+])
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/config/kernel-kmap-atomic-args.m4
@@ -0,0 +1,20 @@
+dnl #
+dnl # 2.6.37 API change
+dnl # kmap_atomic changed from assigning hard-coded named slot to using
+dnl # push/pop based dynamical allocation.
+dnl #
+AC_DEFUN([ZFS_AC_KERNEL_KMAP_ATOMIC_ARGS], [
+	AC_MSG_CHECKING([whether kmap_atomic wants 1 args])
+	ZFS_LINUX_TRY_COMPILE([
+		#include <linux/pagemap.h>
+	],[
+		struct page page;
+		kmap_atomic(&page);
+	],[
+		AC_MSG_RESULT(yes)
+		AC_DEFINE(HAVE_1ARG_KMAP_ATOMIC, 1,
+		          [kmap_atomic wants 1 args])
+	],[
+		AC_MSG_RESULT(no)
+	])
+])
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/config/kernel-kobj-name-len.m4
@@ -0,0 +1,21 @@
+dnl #
+dnl # 2.6.27 API change,
+dnl # kobject KOBJ_NAME_LEN static limit removed.  All users of this
+dnl # constant were removed prior to 2.6.27, but to be on the safe
+dnl # side this check ensures the constant is undefined.
+dnl #
+AC_DEFUN([ZFS_AC_KERNEL_KOBJ_NAME_LEN], [
+	AC_MSG_CHECKING([whether kernel defines KOBJ_NAME_LEN])
+	ZFS_LINUX_TRY_COMPILE([
+		#include <linux/kobject.h>
+	],[
+		int val __attribute__ ((unused));
+		val = KOBJ_NAME_LEN;
+	],[
+		AC_MSG_RESULT([yes])
+		AC_DEFINE(HAVE_KOBJ_NAME_LEN, 1,
+		          [kernel defines KOBJ_NAME_LEN])
+	],[
+		AC_MSG_RESULT([no])
+	])
+])
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/config/kernel-lookup-bdev.m4
@@ -0,0 +1,17 @@
+dnl #
+dnl # 2.6.27 API change
+dnl # lookup_bdev() was exported.
+dnl #
+AC_DEFUN([ZFS_AC_KERNEL_LOOKUP_BDEV],
+	[AC_MSG_CHECKING([whether lookup_bdev() is available])
+	ZFS_LINUX_TRY_COMPILE_SYMBOL([
+		#include <linux/fs.h>
+	], [
+		lookup_bdev(NULL);
+	], [lookup_bdev], [fs/block_dev.c], [
+		AC_MSG_RESULT(yes)
+		AC_DEFINE(HAVE_LOOKUP_BDEV, 1, [lookup_bdev() is available])
+	], [
+		AC_MSG_RESULT(no)
+	])
+])
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/config/kernel-lookup-nameidata.m4
@@ -0,0 +1,25 @@
+dnl #
+dnl # 3.6 API change
+dnl #
+AC_DEFUN([ZFS_AC_KERNEL_LOOKUP_NAMEIDATA], [
+	AC_MSG_CHECKING([whether iops->lookup() passes nameidata])
+	ZFS_LINUX_TRY_COMPILE([
+		#include <linux/fs.h>
+
+		struct dentry *inode_lookup(struct inode *inode,
+		    struct dentry *dentry, struct nameidata *nidata)
+		    { return NULL; }
+
+		static const struct inode_operations iops
+		    __attribute__ ((unused)) = {
+			.lookup	= inode_lookup,
+		};
+	],[
+	],[
+		AC_MSG_RESULT(yes)
+		AC_DEFINE(HAVE_LOOKUP_NAMEIDATA, 1,
+		          [iops->lookup() passes nameidata])
+	],[
+		AC_MSG_RESULT(no)
+	])
+])
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/config/kernel-lseek-execute.m4
@@ -0,0 +1,23 @@
+dnl #
+dnl # 3.11 API change
+dnl # lseek_execute helper exported
+dnl #
+AC_DEFUN([ZFS_AC_KERNEL_LSEEK_EXECUTE],
+	[AC_MSG_CHECKING([whether lseek_execute() is available])
+	ZFS_LINUX_TRY_COMPILE_SYMBOL([
+		#include <linux/fs.h>
+	], [
+		struct file *fp __attribute__ ((unused)) = NULL;
+		struct inode *ip __attribute__ ((unused)) = NULL;
+		loff_t offset __attribute__ ((unused)) = 0;
+		loff_t maxsize __attribute__ ((unused)) = 0;
+
+		lseek_execute(fp, ip, offset, maxsize);
+	], [lseek_exclusive], [fs/read_write.c], [
+		AC_MSG_RESULT(yes)
+		AC_DEFINE(HAVE_LSEEK_EXECUTE, 1,
+		          [lseek_execute() is available])
+	], [
+		AC_MSG_RESULT(no)
+	])
+])
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/config/kernel-mk-request-fn.m4
@@ -0,0 +1,65 @@
+dnl #
+dnl # Linux 3.2 API Change
+dnl # make_request_fn returns void instead of int.
+dnl #
+dnl # Linux 4.4 API Change
+dnl # make_request_fn returns blk_qc_t.
+dnl #
+AC_DEFUN([ZFS_AC_KERNEL_MAKE_REQUEST_FN], [
+	AC_MSG_CHECKING([whether make_request_fn() returns int])
+	ZFS_LINUX_TRY_COMPILE([
+		#include <linux/blkdev.h>
+
+		int make_request(struct request_queue *q, struct bio *bio)
+		{
+			return (0);
+		}
+	],[
+		blk_queue_make_request(NULL, &make_request);
+	],[
+		AC_MSG_RESULT(yes)
+		AC_DEFINE(MAKE_REQUEST_FN_RET, int,
+		    [make_request_fn() returns int])
+		AC_DEFINE(HAVE_MAKE_REQUEST_FN_RET_INT, 1,
+		    [Noting that make_request_fn() returns int])
+	],[
+		AC_MSG_RESULT(no)
+		AC_MSG_CHECKING([whether make_request_fn() returns void])
+		ZFS_LINUX_TRY_COMPILE([
+			#include <linux/blkdev.h>
+
+			void make_request(struct request_queue *q, struct bio *bio)
+			{
+				return;
+			}
+		],[
+			blk_queue_make_request(NULL, &make_request);
+		],[
+			AC_MSG_RESULT(yes)
+			AC_DEFINE(MAKE_REQUEST_FN_RET, void,
+			    [make_request_fn() returns void])
+		],[
+			AC_MSG_RESULT(no)
+			AC_MSG_CHECKING([whether make_request_fn() returns blk_qc_t])
+			ZFS_LINUX_TRY_COMPILE([
+				#include <linux/blkdev.h>
+
+				blk_qc_t make_request(struct request_queue *q, struct bio *bio)
+				{
+					return (BLK_QC_T_NONE);
+				}
+			],[
+				blk_queue_make_request(NULL, &make_request);
+			],[
+				AC_MSG_RESULT(yes)
+				AC_DEFINE(MAKE_REQUEST_FN_RET, blk_qc_t,
+				    [make_request_fn() returns blk_qc_t])
+				AC_DEFINE(HAVE_MAKE_REQUEST_FN_RET_QC, 1,
+				    [Noting that make_request_fn() returns blk_qc_t])
+			],[
+				AC_MSG_ERROR(no - Please file a bug report at
+				    https://github.com/zfsonlinux/zfs/issues/new)
+			])
+		])
+	])
+])
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/config/kernel-mkdir-umode-t.m4
@@ -0,0 +1,29 @@
+dnl #
+dnl # 3.3 API change
+dnl # The VFS .create, .mkdir and .mknod callbacks were updated to take a
+dnl # umode_t type rather than an int.  The expectation is that any backport
+dnl # would also change all three prototypes.  However, if it turns out that
+dnl # some distribution doesn't backport the whole thing this could be
+dnl # broken apart in to three seperate checks.
+dnl #
+AC_DEFUN([ZFS_AC_KERNEL_MKDIR_UMODE_T], [
+	AC_MSG_CHECKING([whether iops->create()/mkdir()/mknod() take umode_t])
+	ZFS_LINUX_TRY_COMPILE([
+		#include <linux/fs.h>
+
+		int mkdir(struct inode *inode, struct dentry *dentry,
+		    umode_t umode) { return 0; }
+
+		static const struct inode_operations
+		    iops __attribute__ ((unused)) = {
+			.mkdir = mkdir,
+		};
+	],[
+	],[
+		AC_MSG_RESULT(yes)
+		AC_DEFINE(HAVE_MKDIR_UMODE_T, 1,
+		    [iops->create()/mkdir()/mknod() take umode_t])
+	],[
+		AC_MSG_RESULT(no)
+	])
+])
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/config/kernel-mount-nodev.m4
@@ -0,0 +1,20 @@
+dnl #
+dnl # 2.6.39 API change
+dnl # The .get_sb callback has been replaced by a .mount callback
+dnl # in the file_system_type structure.  When using the new
+dnl # interface the caller must now use the mount_nodev() helper.
+dnl # This updated callback and helper no longer pass the vfsmount.
+dnl #
+AC_DEFUN([ZFS_AC_KERNEL_MOUNT_NODEV],
+	[AC_MSG_CHECKING([whether mount_nodev() is available])
+	ZFS_LINUX_TRY_COMPILE_SYMBOL([
+		#include <linux/fs.h>
+	], [
+		mount_nodev(NULL, 0, NULL, NULL);
+	], [mount_nodev], [fs/super.c], [
+		AC_MSG_RESULT(yes)
+		AC_DEFINE(HAVE_MOUNT_NODEV, 1, [mount_nodev() is available])
+	], [
+		AC_MSG_RESULT(no)
+	])
+])
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/config/kernel-open-bdev-exclusive.m4
@@ -0,0 +1,18 @@
+dnl #
+dnl # 2.6.28 API change
+dnl # open/close_bdev_excl() renamed to open/close_bdev_exclusive()
+dnl #
+AC_DEFUN([ZFS_AC_KERNEL_OPEN_BDEV_EXCLUSIVE],
+	[AC_MSG_CHECKING([whether open_bdev_exclusive() is available])
+	ZFS_LINUX_TRY_COMPILE_SYMBOL([
+		#include <linux/fs.h>
+	], [
+		open_bdev_exclusive(NULL, 0, NULL);
+	], [open_bdev_exclusive], [fs/block_dev.c], [
+		AC_MSG_RESULT(yes)
+		AC_DEFINE(HAVE_OPEN_BDEV_EXCLUSIVE, 1,
+		          [open_bdev_exclusive() is available])
+	], [
+		AC_MSG_RESULT(no)
+	])
+])
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/config/kernel-put-link.m4
@@ -0,0 +1,60 @@
+dnl #
+dnl # Supported symlink APIs
+dnl #
+AC_DEFUN([ZFS_AC_KERNEL_PUT_LINK], [
+	dnl #
+	dnl # 4.5 API change
+	dnl # get_link() uses delayed done, there is no put_link() interface.
+	dnl #
+	ZFS_LINUX_TRY_COMPILE([
+		#if !defined(HAVE_GET_LINK_DELAYED)
+		#error "Expecting get_link() delayed done"
+		#endif
+	],[
+	],[
+		AC_DEFINE(HAVE_PUT_LINK_DELAYED, 1, [iops->put_link() delayed])
+	],[
+		dnl #
+		dnl # 4.2 API change
+		dnl # This kernel retired the nameidata structure.
+		dnl #
+		AC_MSG_CHECKING([whether iops->put_link() passes cookie])
+		ZFS_LINUX_TRY_COMPILE([
+			#include <linux/fs.h>
+			void put_link(struct inode *ip, void *cookie)
+			    { return; }
+			static struct inode_operations
+			    iops __attribute__ ((unused)) = {
+				.put_link = put_link,
+			};
+		],[
+		],[
+			AC_MSG_RESULT(yes)
+			AC_DEFINE(HAVE_PUT_LINK_COOKIE, 1,
+			    [iops->put_link() cookie])
+		],[
+			dnl #
+			dnl # 2.6.32 API
+			dnl #
+			AC_MSG_RESULT(no)
+			AC_MSG_CHECKING(
+			    [whether iops->put_link() passes nameidata])
+			ZFS_LINUX_TRY_COMPILE([
+				#include <linux/fs.h>
+				void put_link(struct dentry *de, struct
+				    nameidata *nd, void *ptr) { return; }
+				static struct inode_operations
+				    iops __attribute__ ((unused)) = {
+					.put_link = put_link,
+				};
+			],[
+			],[
+				AC_MSG_RESULT(yes)
+				AC_DEFINE(HAVE_PUT_LINK_NAMEIDATA, 1,
+				    [iops->put_link() nameidata])
+			],[
+				AC_MSG_ERROR(no; please file a bug report)
+			])
+		])
+	])
+])
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/config/kernel-security-inode-init.m4
@@ -0,0 +1,55 @@
+dnl #
+dnl # 2.6.39 API change
+dnl # The security_inode_init_security() function now takes an additional
+dnl # qstr argument which must be passed in from the dentry if available.
+dnl # Passing a NULL is safe when no qstr is available the relevant
+dnl # security checks will just be skipped.
+dnl #
+AC_DEFUN([ZFS_AC_KERNEL_6ARGS_SECURITY_INODE_INIT_SECURITY], [
+	AC_MSG_CHECKING([whether security_inode_init_security wants 6 args])
+	ZFS_LINUX_TRY_COMPILE([
+		#include <linux/security.h>
+	],[
+		struct inode *ip __attribute__ ((unused)) = NULL;
+		struct inode *dip __attribute__ ((unused)) = NULL;
+		const struct qstr *str __attribute__ ((unused)) = NULL;
+		char *name __attribute__ ((unused)) = NULL;
+		void *value __attribute__ ((unused)) = NULL;
+		size_t len __attribute__ ((unused)) = 0;
+
+		security_inode_init_security(ip, dip, str, &name, &value, &len);
+	],[
+		AC_MSG_RESULT(yes)
+		AC_DEFINE(HAVE_6ARGS_SECURITY_INODE_INIT_SECURITY, 1,
+		          [security_inode_init_security wants 6 args])
+	],[
+		AC_MSG_RESULT(no)
+	])
+])
+
+dnl #
+dnl # 3.2 API change
+dnl # The security_inode_init_security() API has been changed to include
+dnl # a filesystem specific callback to write security extended attributes.
+dnl # This was done to support the initialization of multiple LSM xattrs
+dnl # and the EVM xattr.
+dnl #
+AC_DEFUN([ZFS_AC_KERNEL_CALLBACK_SECURITY_INODE_INIT_SECURITY], [
+	AC_MSG_CHECKING([whether security_inode_init_security wants callback])
+	ZFS_LINUX_TRY_COMPILE([
+		#include <linux/security.h>
+	],[
+		struct inode *ip __attribute__ ((unused)) = NULL;
+		struct inode *dip __attribute__ ((unused)) = NULL;
+		const struct qstr *str __attribute__ ((unused)) = NULL;
+		initxattrs func __attribute__ ((unused)) = NULL;
+
+		security_inode_init_security(ip, dip, str, func, NULL);
+	],[
+		AC_MSG_RESULT(yes)
+		AC_DEFINE(HAVE_CALLBACK_SECURITY_INODE_INIT_SECURITY, 1,
+		          [security_inode_init_security wants callback])
+	],[
+		AC_MSG_RESULT(no)
+	])
+])
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/config/kernel-set-nlink.m4
@@ -0,0 +1,20 @@
+dnl #
+dnl # Linux v3.2-rc1 API change
+dnl # SHA: bfe8684869601dacfcb2cd69ef8cfd9045f62170
+dnl #
+AC_DEFUN([ZFS_AC_KERNEL_SET_NLINK], [
+	AC_MSG_CHECKING([whether set_nlink() is available])
+	ZFS_LINUX_TRY_COMPILE([
+		#include <linux/fs.h>
+	],[
+		struct inode node;
+		unsigned int link = 0;
+		(void) set_nlink(&node, link);
+	],[
+		AC_MSG_RESULT(yes)
+		AC_DEFINE(HAVE_SET_NLINK, 1,
+		          [set_nlink() is available])
+	],[
+		AC_MSG_RESULT(no)
+	])
+])
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/config/kernel-sget-args.m4
@@ -0,0 +1,23 @@
+dnl #
+dnl # 3.6 API change,
+dnl # 'sget' now takes the mount flags as an argument.
+dnl #
+AC_DEFUN([ZFS_AC_KERNEL_5ARG_SGET],
+	[AC_MSG_CHECKING([whether sget() wants 5 args])
+	ZFS_LINUX_TRY_COMPILE([
+		#include <linux/fs.h>
+	],[
+		struct file_system_type *type = NULL;
+		int (*test)(struct super_block *,void *) = NULL;
+		int (*set)(struct super_block *,void *) = NULL;
+		int flags = 0;
+		void *data = NULL;
+		(void) sget(type, test, set, flags, data);
+	],[
+		AC_MSG_RESULT(yes)
+		AC_DEFINE(HAVE_5ARG_SGET, 1, [sget() wants 5 args])
+	],[
+		AC_MSG_RESULT(no)
+	])
+])
+
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/config/kernel-show-options.m4
@@ -0,0 +1,22 @@
+dnl #
+dnl # Linux 3.3 API
+dnl #
+AC_DEFUN([ZFS_AC_KERNEL_SHOW_OPTIONS], [
+	AC_MSG_CHECKING([whether sops->show_options() wants dentry])
+
+	ZFS_LINUX_TRY_COMPILE([
+		#include <linux/fs.h>
+
+		int show_options (struct seq_file * x, struct dentry * y) { return 0; };
+		static struct super_operations sops __attribute__ ((unused)) = {
+			.show_options = show_options,
+		};
+	],[
+	],[
+		AC_MSG_RESULT([yes])
+		AC_DEFINE(HAVE_SHOW_OPTIONS_WITH_DENTRY, 1,
+			[sops->show_options() with dentry])
+	],[
+		AC_MSG_RESULT([no])
+	])
+])
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/config/kernel-shrink.m4
@@ -0,0 +1,133 @@
+dnl #
+dnl # 3.1 API change
+dnl # The super_block structure now stores a per-filesystem shrinker.
+dnl # This interface is preferable because it can be used to specifically
+dnl # target only the zfs filesystem for pruning.
+dnl #
+AC_DEFUN([ZFS_AC_KERNEL_SHRINK], [
+	AC_MSG_CHECKING([whether super_block has s_shrink])
+	ZFS_LINUX_TRY_COMPILE([
+		#include <linux/fs.h>
+
+		int shrink(struct shrinker *s, struct shrink_control *sc)
+		    { return 0; }
+
+		static const struct super_block
+		    sb __attribute__ ((unused)) = {
+			.s_shrink.shrink = shrink,
+			.s_shrink.seeks = DEFAULT_SEEKS,
+			.s_shrink.batch = 0,
+		};
+	],[
+	],[
+		AC_MSG_RESULT(yes)
+		AC_DEFINE(HAVE_SHRINK, 1, [struct super_block has s_shrink])
+
+	],[
+		AC_MSG_RESULT(no)
+	])
+])
+
+dnl #
+dnl # 3.3 API change
+dnl # The super_block structure was changed to use an hlist_node instead
+dnl # of a list_head for the .s_instance linkage.
+dnl #
+dnl # This was done in part to resolve a race in the iterate_supers_type()
+dnl # function which was introduced in Linux 3.0 kernel.  The iterator
+dnl # was supposed to provide a safe way to call an arbitrary function on
+dnl # all super blocks of a specific type.  Unfortunately, because a
+dnl # list_head was used it was possible for iterate_supers_type() to
+dnl # get stuck spinning a super block which was just deactivated.
+dnl #
+dnl # This can occur because when the list head is removed from the
+dnl # fs_supers list it is reinitialized to point to itself.  If the
+dnl # iterate_supers_type() function happened to be processing the
+dnl # removed list_head it will get stuck spinning on that list_head.
+dnl #
+dnl # To resolve the issue for existing 3.0 - 3.2 kernels we detect when
+dnl # a list_head is used.  Then to prevent the spinning from occurring
+dnl # the .next pointer is set to the fs_supers list_head which ensures
+dnl # the iterate_supers_type() function will always terminate.
+dnl #
+AC_DEFUN([ZFS_AC_KERNEL_S_INSTANCES_LIST_HEAD], [
+	AC_MSG_CHECKING([whether super_block has s_instances list_head])
+	ZFS_LINUX_TRY_COMPILE([
+		#include <linux/fs.h>
+	],[
+		struct super_block sb __attribute__ ((unused));
+
+		INIT_LIST_HEAD(&sb.s_instances);
+	],[
+		AC_MSG_RESULT(yes)
+		AC_DEFINE(HAVE_S_INSTANCES_LIST_HEAD, 1,
+		    [struct super_block has s_instances list_head])
+	],[
+		AC_MSG_RESULT(no)
+	])
+])
+
+AC_DEFUN([ZFS_AC_KERNEL_NR_CACHED_OBJECTS], [
+	AC_MSG_CHECKING([whether sops->nr_cached_objects() exists])
+	ZFS_LINUX_TRY_COMPILE([
+		#include <linux/fs.h>
+
+		int nr_cached_objects(struct super_block *sb) { return 0; }
+
+		static const struct super_operations
+		    sops __attribute__ ((unused)) = {
+			.nr_cached_objects = nr_cached_objects,
+		};
+	],[
+	],[
+		AC_MSG_RESULT(yes)
+		AC_DEFINE(HAVE_NR_CACHED_OBJECTS, 1,
+			[sops->nr_cached_objects() exists])
+	],[
+		AC_MSG_RESULT(no)
+	])
+])
+
+AC_DEFUN([ZFS_AC_KERNEL_FREE_CACHED_OBJECTS], [
+	AC_MSG_CHECKING([whether sops->free_cached_objects() exists])
+	ZFS_LINUX_TRY_COMPILE([
+		#include <linux/fs.h>
+
+		void free_cached_objects(struct super_block *sb, int x)
+		    { return; }
+
+		static const struct super_operations
+		    sops __attribute__ ((unused)) = {
+			.free_cached_objects = free_cached_objects,
+		};
+	],[
+	],[
+		AC_MSG_RESULT(yes)
+		AC_DEFINE(HAVE_FREE_CACHED_OBJECTS, 1,
+			[sops->free_cached_objects() exists])
+	],[
+		AC_MSG_RESULT(no)
+	])
+])
+
+dnl #
+dnl # 3.12 API change
+dnl # The nid member was added to struct shrink_control to support
+dnl # NUMA-aware shrinkers.
+dnl #
+AC_DEFUN([ZFS_AC_KERNEL_SHRINK_CONTROL_HAS_NID], [
+	AC_MSG_CHECKING([whether shrink_control has nid])
+	ZFS_LINUX_TRY_COMPILE([
+		#include <linux/fs.h>
+	],[
+		struct shrink_control sc __attribute__ ((unused));
+		unsigned long scnidsize __attribute__ ((unused)) =
+		    sizeof(sc.nid);
+	],[
+		AC_MSG_RESULT(yes)
+		AC_DEFINE(SHRINK_CONTROL_HAS_NID, 1,
+		    [struct shrink_control has nid])
+	],[
+		AC_MSG_RESULT(no)
+	])
+])
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/config/kernel-truncate-range.m4
@@ -0,0 +1,24 @@
+dnl #
+dnl # 3.5.0 API change
+dnl # torvalds/linux@17cf28afea2a1112f240a3a2da8af883be024811 removed
+dnl # truncate_range(). The file hole punching functionality is now
+dnl # provided by fallocate()
+dnl #
+AC_DEFUN([ZFS_AC_KERNEL_TRUNCATE_RANGE], [
+	AC_MSG_CHECKING([whether iops->truncate_range() exists])
+	ZFS_LINUX_TRY_COMPILE([
+		#include <linux/fs.h>
+		void truncate_range(struct inode *inode, loff_t start,
+		                    loff_t end) { return; }
+		static struct inode_operations iops __attribute__ ((unused)) = {
+			.truncate_range	= truncate_range,
+		};
+	],[
+	],[
+		AC_MSG_RESULT(yes)
+		AC_DEFINE(HAVE_INODE_TRUNCATE_RANGE, 1,
+		          [iops->truncate_range() exists])
+	],[
+		AC_MSG_RESULT(no)
+	])
+])
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/config/kernel-truncate-setsize.m4
@@ -0,0 +1,18 @@
+dnl #
+dnl # 2.6.35 API change
+dnl # Added truncate_setsize() helper function.
+dnl #
+AC_DEFUN([ZFS_AC_KERNEL_TRUNCATE_SETSIZE],
+	[AC_MSG_CHECKING([whether truncate_setsize() is available])
+	ZFS_LINUX_TRY_COMPILE_SYMBOL([
+		#include <linux/mm.h>
+	], [
+		truncate_setsize(NULL, 0);
+	], [truncate_setsize], [mm/truncate.c], [
+		AC_MSG_RESULT(yes)
+		AC_DEFINE(HAVE_TRUNCATE_SETSIZE, 1,
+		          [truncate_setsize() is available])
+	], [
+		AC_MSG_RESULT(no)
+	])
+])
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/config/kernel-vfs-iterate.m4
@@ -0,0 +1,43 @@
+dnl #
+dnl # 3.11 API change
+dnl #
+AC_DEFUN([ZFS_AC_KERNEL_VFS_ITERATE], [
+	AC_MSG_CHECKING([whether fops->iterate() is available])
+	ZFS_LINUX_TRY_COMPILE([
+		#include <linux/fs.h>
+		int iterate(struct file *filp, struct dir_context * context)
+		    { return 0; }
+
+		static const struct file_operations fops
+		    __attribute__ ((unused)) = {
+			.iterate	 = iterate,
+		};
+	],[
+	],[
+		AC_MSG_RESULT(yes)
+		AC_DEFINE(HAVE_VFS_ITERATE, 1,
+		          [fops->iterate() is available])
+	],[
+		AC_MSG_RESULT(no)
+
+		AC_MSG_CHECKING([whether fops->readdir() is available])
+		ZFS_LINUX_TRY_COMPILE([
+			#include <linux/fs.h>
+			int readdir(struct file *filp, void *entry, filldir_t func)
+			    { return 0; }
+
+			static const struct file_operations fops
+			    __attribute__ ((unused)) = {
+				.readdir = readdir,
+			};
+		],[
+		],[
+			AC_MSG_RESULT(yes)
+			AC_DEFINE(HAVE_VFS_READDIR, 1,
+				  [fops->readdir() is available])
+		],[
+			AC_MSG_ERROR(no; file a bug report with ZFSOnLinux)
+		])
+
+	])
+])
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/config/kernel-vfs-rw-iterate.m4
@@ -0,0 +1,27 @@
+dnl #
+dnl # Linux 4.1.x API
+dnl #
+AC_DEFUN([ZFS_AC_KERNEL_VFS_RW_ITERATE],
+	[AC_MSG_CHECKING([whether fops->read/write_iter() are available])
+	ZFS_LINUX_TRY_COMPILE([
+		#include <linux/fs.h>
+
+		ssize_t test_read(struct kiocb *kiocb, struct iov_iter *to)
+		    { return 0; }
+		ssize_t test_write(struct kiocb *kiocb, struct iov_iter *from)
+		    { return 0; }
+
+		static const struct file_operations
+		    fops __attribute__ ((unused)) = {
+		    .read_iter = test_read,
+		    .write_iter = test_write,
+		};
+	],[
+	],[
+		AC_MSG_RESULT(yes)
+		AC_DEFINE(HAVE_VFS_RW_ITERATE, 1,
+			[fops->read/write_iter() are available])
+	],[
+		AC_MSG_RESULT(no)
+	])
+])
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/config/kernel-xattr-handler.m4
@@ -0,0 +1,317 @@
+dnl #
+dnl # 2.6.35 API change,
+dnl # The 'struct xattr_handler' was constified in the generic
+dnl # super_block structure.
+dnl #
+AC_DEFUN([ZFS_AC_KERNEL_CONST_XATTR_HANDLER], [
+	AC_MSG_CHECKING([whether super_block uses const struct xattr_handler])
+	ZFS_LINUX_TRY_COMPILE([
+		#include <linux/fs.h>
+		#include <linux/xattr.h>
+
+		const struct xattr_handler xattr_test_handler = {
+			.prefix	= "test",
+			.get	= NULL,
+			.set	= NULL,
+		};
+
+		const struct xattr_handler *xattr_handlers[] = {
+			&xattr_test_handler,
+		};
+
+		const struct super_block sb __attribute__ ((unused)) = {
+			.s_xattr = xattr_handlers,
+		};
+	],[
+	],[
+		AC_MSG_RESULT([yes])
+		AC_DEFINE(HAVE_CONST_XATTR_HANDLER, 1,
+		          [super_block uses const struct xattr_handler])
+	],[
+		AC_MSG_RESULT([no])
+	])
+])
+
+dnl #
+dnl # Supported xattr handler get() interfaces checked newest to oldest.
+dnl #
+AC_DEFUN([ZFS_AC_KERNEL_XATTR_HANDLER_GET], [
+	dnl #
+	dnl # 4.4 API change,
+	dnl # The xattr_handler->get() callback was changed to take a
+	dnl # attr_handler, and handler_flags argument was removed and
+	dnl # should be accessed by handler->flags.
+	dnl #
+	AC_MSG_CHECKING([whether xattr_handler->get() wants xattr_handler])
+	ZFS_LINUX_TRY_COMPILE([
+		#include <linux/xattr.h>
+
+		int get(const struct xattr_handler *handler,
+		    struct dentry *dentry, const char *name,
+		    void *buffer, size_t size) { return 0; }
+		static const struct xattr_handler
+		    xops __attribute__ ((unused)) = {
+			.get = get,
+		};
+	],[
+	],[
+		AC_MSG_RESULT(yes)
+		AC_DEFINE(HAVE_XATTR_GET_HANDLER, 1,
+		    [xattr_handler->get() wants xattr_handler])
+	],[
+		dnl #
+		dnl # 2.6.33 API change,
+		dnl # The xattr_handler->get() callback was changed to take
+		dnl # a dentry instead of an inode, and a handler_flags
+		dnl # argument was added.
+		dnl #
+		AC_MSG_RESULT(no)
+		AC_MSG_CHECKING([whether xattr_handler->get() wants dentry])
+		ZFS_LINUX_TRY_COMPILE([
+			#include <linux/xattr.h>
+
+			int get(struct dentry *dentry, const char *name,
+			    void *buffer, size_t size, int handler_flags)
+			    { return 0; }
+			static const struct xattr_handler
+			    xops __attribute__ ((unused)) = {
+				.get = get,
+			};
+		],[
+		],[
+			AC_MSG_RESULT(yes)
+			AC_DEFINE(HAVE_XATTR_GET_DENTRY, 1,
+			    [xattr_handler->get() wants dentry])
+		],[
+			dnl #
+			dnl # 2.6.32 API
+			dnl #
+			AC_MSG_RESULT(no)
+			AC_MSG_CHECKING(
+			    [whether xattr_handler->get() wants inode])
+			ZFS_LINUX_TRY_COMPILE([
+				#include <linux/xattr.h>
+
+				int get(struct inode *ip, const char *name,
+				    void *buffer, size_t size) { return 0; }
+				static const struct xattr_handler
+				    xops __attribute__ ((unused)) = {
+					.get = get,
+				};
+			],[
+			],[
+				AC_MSG_RESULT(yes)
+				AC_DEFINE(HAVE_XATTR_GET_INODE, 1,
+				    [xattr_handler->get() wants inode])
+			],[
+	                        AC_MSG_ERROR([no; please file a bug report])
+			])
+		])
+	])
+])
+
+dnl #
+dnl # Supported xattr handler set() interfaces checked newest to oldest.
+dnl #
+AC_DEFUN([ZFS_AC_KERNEL_XATTR_HANDLER_SET], [
+	dnl #
+	dnl # 4.4 API change,
+	dnl # The xattr_handler->set() callback was changed to take a
+	dnl # xattr_handler, and handler_flags argument was removed and
+	dnl # should be accessed by handler->flags.
+	dnl #
+	AC_MSG_CHECKING([whether xattr_handler->set() wants xattr_handler])
+	ZFS_LINUX_TRY_COMPILE([
+		#include <linux/xattr.h>
+
+		int set(const struct xattr_handler *handler,
+		    struct dentry *dentry, const char *name,
+		    const void *buffer, size_t size, int flags)
+		    { return 0; }
+		static const struct xattr_handler
+		    xops __attribute__ ((unused)) = {
+			.set = set,
+		};
+	],[
+	],[
+		AC_MSG_RESULT(yes)
+		AC_DEFINE(HAVE_XATTR_SET_HANDLER, 1,
+		    [xattr_handler->set() wants xattr_handler])
+	],[
+		dnl #
+		dnl # 2.6.33 API change,
+		dnl # The xattr_handler->set() callback was changed to take a
+		dnl # dentry instead of an inode, and a handler_flags
+		dnl # argument was added.
+		dnl #
+		AC_MSG_RESULT(no)
+		AC_MSG_CHECKING([whether xattr_handler->set() wants dentry])
+		ZFS_LINUX_TRY_COMPILE([
+			#include <linux/xattr.h>
+
+			int set(struct dentry *dentry, const char *name,
+			    const void *buffer, size_t size, int flags,
+			    int handler_flags) { return 0; }
+			static const struct xattr_handler
+			    xops __attribute__ ((unused)) = {
+				.set = set,
+			};
+		],[
+		],[
+			AC_MSG_RESULT(yes)
+			AC_DEFINE(HAVE_XATTR_SET_DENTRY, 1,
+			    [xattr_handler->set() wants dentry])
+		],[
+			dnl #
+			dnl # 2.6.32 API
+			dnl #
+			AC_MSG_RESULT(no)
+			AC_MSG_CHECKING(
+			    [whether xattr_handler->set() wants inode])
+			ZFS_LINUX_TRY_COMPILE([
+				#include <linux/xattr.h>
+
+				int set(struct inode *ip, const char *name,
+				    const void *buffer, size_t size, int flags)
+				    { return 0; }
+				static const struct xattr_handler
+				    xops __attribute__ ((unused)) = {
+					.set = set,
+				};
+			],[
+			],[
+				AC_MSG_RESULT(yes)
+				AC_DEFINE(HAVE_XATTR_SET_INODE, 1,
+				    [xattr_handler->set() wants inode])
+			],[
+	                        AC_MSG_ERROR([no; please file a bug report])
+			])
+		])
+	])
+])
+
+dnl #
+dnl # Supported xattr handler list() interfaces checked newest to oldest.
+dnl #
+AC_DEFUN([ZFS_AC_KERNEL_XATTR_HANDLER_LIST], [
+	dnl # 4.5 API change,
+	dnl # The xattr_handler->list() callback was changed to take only a
+	dnl # dentry and it only needs to return if it's accessable.
+	AC_MSG_CHECKING([whether xattr_handler->list() wants simple])
+	ZFS_LINUX_TRY_COMPILE([
+		#include <linux/xattr.h>
+
+		bool list(struct dentry *dentry) { return 0; }
+		static const struct xattr_handler
+		    xops __attribute__ ((unused)) = {
+			.list = list,
+		};
+	],[
+	],[
+		AC_MSG_RESULT(yes)
+		AC_DEFINE(HAVE_XATTR_LIST_SIMPLE, 1,
+		    [xattr_handler->list() wants simple])
+	],[
+		dnl #
+		dnl # 4.4 API change,
+		dnl # The xattr_handler->list() callback was changed to take a
+		dnl # xattr_handler, and handler_flags argument was removed
+		dnl # and should be accessed by handler->flags.
+		dnl #
+		AC_MSG_RESULT(no)
+		AC_MSG_CHECKING(
+		    [whether xattr_handler->list() wants xattr_handler])
+		ZFS_LINUX_TRY_COMPILE([
+			#include <linux/xattr.h>
+
+			size_t list(const struct xattr_handler *handler,
+			    struct dentry *dentry, char *list, size_t list_size,
+			    const char *name, size_t name_len) { return 0; }
+			static const struct xattr_handler
+			    xops __attribute__ ((unused)) = {
+				.list = list,
+			};
+		],[
+		],[
+			AC_MSG_RESULT(yes)
+			AC_DEFINE(HAVE_XATTR_LIST_HANDLER, 1,
+			    [xattr_handler->list() wants xattr_handler])
+		],[
+			dnl #
+			dnl # 2.6.33 API change,
+			dnl # The xattr_handler->list() callback was changed
+			dnl # to take a dentry instead of an inode, and a
+			dnl # handler_flags argument was added.
+			dnl #
+			AC_MSG_RESULT(no)
+			AC_MSG_CHECKING(
+			    [whether xattr_handler->list() wants dentry])
+			ZFS_LINUX_TRY_COMPILE([
+				#include <linux/xattr.h>
+
+				size_t list(struct dentry *dentry,
+				    char *list, size_t list_size,
+				    const char *name, size_t name_len,
+				    int handler_flags) { return 0; }
+				static const struct xattr_handler
+				    xops __attribute__ ((unused)) = {
+					.list = list,
+				};
+			],[
+			],[
+				AC_MSG_RESULT(yes)
+				AC_DEFINE(HAVE_XATTR_LIST_DENTRY, 1,
+				    [xattr_handler->list() wants dentry])
+			],[
+				dnl #
+				dnl # 2.6.32 API
+				dnl #
+				AC_MSG_RESULT(no)
+				AC_MSG_CHECKING(
+				    [whether xattr_handler->list() wants inode])
+				ZFS_LINUX_TRY_COMPILE([
+					#include <linux/xattr.h>
+
+					size_t list(struct inode *ip, char *lst,
+					    size_t list_size, const char *name,
+					    size_t name_len) { return 0; }
+					static const struct xattr_handler
+					    xops __attribute__ ((unused)) = {
+						.list = list,
+					};
+				],[
+				],[
+					AC_MSG_RESULT(yes)
+					AC_DEFINE(HAVE_XATTR_LIST_INODE, 1,
+					    [xattr_handler->list() wants inode])
+				],[
+		                        AC_MSG_ERROR(
+					    [no; please file a bug report])
+				])
+			])
+		])
+	])
+])
+
+dnl #
+dnl # 3.7 API change,
+dnl # The posix_acl_{from,to}_xattr functions gained a new
+dnl # parameter: user_ns
+dnl #
+AC_DEFUN([ZFS_AC_KERNEL_POSIX_ACL_FROM_XATTR_USERNS], [
+	AC_MSG_CHECKING([whether posix_acl_from_xattr() needs user_ns])
+	ZFS_LINUX_TRY_COMPILE([
+		#include <linux/cred.h>
+		#include <linux/fs.h>
+		#include <linux/posix_acl_xattr.h>
+	],[
+		posix_acl_from_xattr(&init_user_ns, NULL, 0);
+	],[
+		AC_MSG_RESULT(yes)
+		AC_DEFINE(HAVE_POSIX_ACL_FROM_XATTR_USERNS, 1,
+		    [posix_acl_from_xattr() needs user_ns])
+	],[
+		AC_MSG_RESULT(no)
+	])
+])
+
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/config/kernel.m4
@@ -0,0 +1,654 @@
+dnl #
+dnl # Default ZFS kernel configuration 
+dnl #
+AC_DEFUN([ZFS_AC_CONFIG_KERNEL], [
+	ZFS_AC_KERNEL
+	ZFS_AC_SPL
+	ZFS_AC_TEST_MODULE
+	ZFS_AC_KERNEL_CONFIG
+	ZFS_AC_KERNEL_DECLARE_EVENT_CLASS
+	ZFS_AC_KERNEL_CURRENT_BIO_TAIL
+	ZFS_AC_KERNEL_BDEV_BLOCK_DEVICE_OPERATIONS
+	ZFS_AC_KERNEL_BLOCK_DEVICE_OPERATIONS_RELEASE_VOID
+	ZFS_AC_KERNEL_TYPE_FMODE_T
+	ZFS_AC_KERNEL_KOBJ_NAME_LEN
+	ZFS_AC_KERNEL_3ARG_BLKDEV_GET
+	ZFS_AC_KERNEL_BLKDEV_GET_BY_PATH
+	ZFS_AC_KERNEL_OPEN_BDEV_EXCLUSIVE
+	ZFS_AC_KERNEL_LOOKUP_BDEV
+	ZFS_AC_KERNEL_INVALIDATE_BDEV_ARGS
+	ZFS_AC_KERNEL_BDEV_LOGICAL_BLOCK_SIZE
+	ZFS_AC_KERNEL_BDEV_PHYSICAL_BLOCK_SIZE
+	ZFS_AC_KERNEL_BIO_BVEC_ITER
+	ZFS_AC_KERNEL_BIO_FAILFAST_DTD
+	ZFS_AC_KERNEL_REQ_FAILFAST_MASK
+	ZFS_AC_KERNEL_BIO_END_IO_T_ARGS
+	ZFS_AC_KERNEL_BIO_RW_BARRIER
+	ZFS_AC_KERNEL_BIO_RW_DISCARD
+	ZFS_AC_KERNEL_BLK_QUEUE_FLUSH
+	ZFS_AC_KERNEL_BLK_QUEUE_MAX_HW_SECTORS
+	ZFS_AC_KERNEL_BLK_QUEUE_MAX_SEGMENTS
+	ZFS_AC_KERNEL_GET_DISK_RO
+	ZFS_AC_KERNEL_GET_GENDISK
+	ZFS_AC_KERNEL_DISCARD_GRANULARITY
+	ZFS_AC_KERNEL_CONST_XATTR_HANDLER
+	ZFS_AC_KERNEL_XATTR_HANDLER_GET
+	ZFS_AC_KERNEL_XATTR_HANDLER_SET
+	ZFS_AC_KERNEL_XATTR_HANDLER_LIST
+	ZFS_AC_KERNEL_INODE_OWNER_OR_CAPABLE
+	ZFS_AC_KERNEL_POSIX_ACL_FROM_XATTR_USERNS
+	ZFS_AC_KERNEL_POSIX_ACL_RELEASE
+	ZFS_AC_KERNEL_POSIX_ACL_CHMOD
+	ZFS_AC_KERNEL_POSIX_ACL_CACHING
+	ZFS_AC_KERNEL_POSIX_ACL_EQUIV_MODE_WANTS_UMODE_T
+	ZFS_AC_KERNEL_INODE_OPERATIONS_PERMISSION
+	ZFS_AC_KERNEL_INODE_OPERATIONS_PERMISSION_WITH_NAMEIDATA
+	ZFS_AC_KERNEL_INODE_OPERATIONS_CHECK_ACL
+	ZFS_AC_KERNEL_INODE_OPERATIONS_CHECK_ACL_WITH_FLAGS
+	ZFS_AC_KERNEL_INODE_OPERATIONS_GET_ACL
+	ZFS_AC_KERNEL_CURRENT_UMASK
+	ZFS_AC_KERNEL_SHOW_OPTIONS
+	ZFS_AC_KERNEL_FILE_INODE
+	ZFS_AC_KERNEL_FSYNC
+	ZFS_AC_KERNEL_EVICT_INODE
+	ZFS_AC_KERNEL_DIRTY_INODE_WITH_FLAGS
+	ZFS_AC_KERNEL_NR_CACHED_OBJECTS
+	ZFS_AC_KERNEL_FREE_CACHED_OBJECTS
+	ZFS_AC_KERNEL_FALLOCATE
+	ZFS_AC_KERNEL_MKDIR_UMODE_T
+	ZFS_AC_KERNEL_LOOKUP_NAMEIDATA
+	ZFS_AC_KERNEL_CREATE_NAMEIDATA
+	ZFS_AC_KERNEL_GET_LINK
+	ZFS_AC_KERNEL_PUT_LINK
+	ZFS_AC_KERNEL_TRUNCATE_RANGE
+	ZFS_AC_KERNEL_AUTOMOUNT
+	ZFS_AC_KERNEL_ENCODE_FH_WITH_INODE
+	ZFS_AC_KERNEL_COMMIT_METADATA
+	ZFS_AC_KERNEL_CLEAR_INODE
+	ZFS_AC_KERNEL_INSERT_INODE_LOCKED
+	ZFS_AC_KERNEL_D_MAKE_ROOT
+	ZFS_AC_KERNEL_D_OBTAIN_ALIAS
+	ZFS_AC_KERNEL_D_PRUNE_ALIASES
+	ZFS_AC_KERNEL_D_SET_D_OP
+	ZFS_AC_KERNEL_D_REVALIDATE_NAMEIDATA
+	ZFS_AC_KERNEL_CONST_DENTRY_OPERATIONS
+	ZFS_AC_KERNEL_CHECK_DISK_SIZE_CHANGE
+	ZFS_AC_KERNEL_TRUNCATE_SETSIZE
+	ZFS_AC_KERNEL_6ARGS_SECURITY_INODE_INIT_SECURITY
+	ZFS_AC_KERNEL_CALLBACK_SECURITY_INODE_INIT_SECURITY
+	ZFS_AC_KERNEL_MOUNT_NODEV
+	ZFS_AC_KERNEL_SHRINK
+	ZFS_AC_KERNEL_SHRINK_CONTROL_HAS_NID
+	ZFS_AC_KERNEL_S_INSTANCES_LIST_HEAD
+	ZFS_AC_KERNEL_S_D_OP
+	ZFS_AC_KERNEL_BDI_SETUP_AND_REGISTER
+	ZFS_AC_KERNEL_SET_NLINK
+	ZFS_AC_KERNEL_ELEVATOR_CHANGE
+	ZFS_AC_KERNEL_5ARG_SGET
+	ZFS_AC_KERNEL_LSEEK_EXECUTE
+	ZFS_AC_KERNEL_VFS_ITERATE
+	ZFS_AC_KERNEL_VFS_RW_ITERATE
+	ZFS_AC_KERNEL_KMAP_ATOMIC_ARGS
+	ZFS_AC_KERNEL_FOLLOW_DOWN_ONE
+	ZFS_AC_KERNEL_MAKE_REQUEST_FN
+	ZFS_AC_KERNEL_GENERIC_IO_ACCT
+
+	AS_IF([test "$LINUX_OBJ" != "$LINUX"], [
+		KERNELMAKE_PARAMS="$KERNELMAKE_PARAMS O=$LINUX_OBJ"
+	])
+	AC_SUBST(KERNELMAKE_PARAMS)
+
+
+	dnl # -Wall -fno-strict-aliasing -Wstrict-prototypes and other
+	dnl # compiler options are added by the kernel build system.
+	KERNELCPPFLAGS="$KERNELCPPFLAGS $NO_UNUSED_BUT_SET_VARIABLE"
+	KERNELCPPFLAGS="$KERNELCPPFLAGS $NO_BOOL_COMPARE"
+	KERNELCPPFLAGS="$KERNELCPPFLAGS -DHAVE_SPL -D_KERNEL"
+	KERNELCPPFLAGS="$KERNELCPPFLAGS -DTEXT_DOMAIN=\\\"zfs-linux-kernel\\\""
+
+	AC_SUBST(KERNELCPPFLAGS)
+])
+
+dnl #
+dnl # Detect name used for Module.symvers file in kernel
+dnl #
+AC_DEFUN([ZFS_AC_MODULE_SYMVERS], [
+	modpost=$LINUX/scripts/Makefile.modpost
+	AC_MSG_CHECKING([kernel file name for module symbols])
+	AS_IF([test "x$enable_linux_builtin" != xyes -a -f "$modpost"], [
+		AS_IF([grep -q Modules.symvers $modpost], [
+			LINUX_SYMBOLS=Modules.symvers
+		], [
+			LINUX_SYMBOLS=Module.symvers
+		])
+
+		AS_IF([test ! -f "$LINUX_OBJ/$LINUX_SYMBOLS"], [
+			AC_MSG_ERROR([
+	*** Please make sure the kernel devel package for your distribution
+	*** is installed.  If you are building with a custom kernel, make sure the
+	*** kernel is configured, built, and the '--with-linux=PATH' configure
+	*** option refers to the location of the kernel source.])
+		])
+	], [
+		LINUX_SYMBOLS=NONE
+	])
+	AC_MSG_RESULT($LINUX_SYMBOLS)
+	AC_SUBST(LINUX_SYMBOLS)
+])
+
+dnl #
+dnl # Detect the kernel to be built against
+dnl #
+AC_DEFUN([ZFS_AC_KERNEL], [
+	AC_ARG_WITH([linux],
+		AS_HELP_STRING([--with-linux=PATH],
+		[Path to kernel source]),
+		[kernelsrc="$withval"])
+
+	AC_ARG_WITH(linux-obj,
+		AS_HELP_STRING([--with-linux-obj=PATH],
+		[Path to kernel build objects]),
+		[kernelbuild="$withval"])
+
+	AC_MSG_CHECKING([kernel source directory])
+	AS_IF([test -z "$kernelsrc"], [
+		AS_IF([test -e "/lib/modules/$(uname -r)/source"], [
+			headersdir="/lib/modules/$(uname -r)/source"
+			sourcelink=$(readlink -f "$headersdir")
+		], [test -e "/lib/modules/$(uname -r)/build"], [
+			headersdir="/lib/modules/$(uname -r)/build"
+			sourcelink=$(readlink -f "$headersdir")
+		], [
+			sourcelink=$(ls -1d /usr/src/kernels/* \
+			             /usr/src/linux-* \
+			             2>/dev/null | grep -v obj | tail -1)
+		])
+
+		AS_IF([test -n "$sourcelink" && test -e ${sourcelink}], [
+			kernelsrc=`readlink -f ${sourcelink}`
+		], [
+			kernelsrc="[Not found]"
+		])
+	], [
+		AS_IF([test "$kernelsrc" = "NONE"], [
+			kernsrcver=NONE
+		])
+	])
+
+	AC_MSG_RESULT([$kernelsrc])
+	AS_IF([test ! -d "$kernelsrc"], [
+		AC_MSG_ERROR([
+	*** Please make sure the kernel devel package for your distribution
+	*** is installed and then try again.  If that fails, you can specify the
+	*** location of the kernel source with the '--with-linux=PATH' option.])
+	])
+
+	AC_MSG_CHECKING([kernel build directory])
+	AS_IF([test -z "$kernelbuild"], [
+		AS_IF([test -e "/lib/modules/$(uname -r)/build"], [
+			kernelbuild=`readlink -f /lib/modules/$(uname -r)/build`
+		], [test -d ${kernelsrc}-obj/${target_cpu}/${target_cpu}], [
+			kernelbuild=${kernelsrc}-obj/${target_cpu}/${target_cpu}
+		], [test -d ${kernelsrc}-obj/${target_cpu}/default], [
+			kernelbuild=${kernelsrc}-obj/${target_cpu}/default
+		], [test -d `dirname ${kernelsrc}`/build-${target_cpu}], [
+			kernelbuild=`dirname ${kernelsrc}`/build-${target_cpu}
+		], [
+			kernelbuild=${kernelsrc}
+		])
+	])
+	AC_MSG_RESULT([$kernelbuild])
+
+	AC_MSG_CHECKING([kernel source version])
+	utsrelease1=$kernelbuild/include/linux/version.h
+	utsrelease2=$kernelbuild/include/linux/utsrelease.h
+	utsrelease3=$kernelbuild/include/generated/utsrelease.h
+	AS_IF([test -r $utsrelease1 && fgrep -q UTS_RELEASE $utsrelease1], [
+		utsrelease=linux/version.h
+	], [test -r $utsrelease2 && fgrep -q UTS_RELEASE $utsrelease2], [
+		utsrelease=linux/utsrelease.h
+	], [test -r $utsrelease3 && fgrep -q UTS_RELEASE $utsrelease3], [
+		utsrelease=generated/utsrelease.h
+	])
+
+	AS_IF([test "$utsrelease"], [
+		kernsrcver=`(echo "#include <$utsrelease>";
+		             echo "kernsrcver=UTS_RELEASE") |
+		             cpp -I $kernelbuild/include |
+		             grep "^kernsrcver=" | cut -d \" -f 2`
+
+		AS_IF([test -z "$kernsrcver"], [
+			AC_MSG_RESULT([Not found])
+			AC_MSG_ERROR([*** Cannot determine kernel version.])
+		])
+	], [
+		AC_MSG_RESULT([Not found])
+		if test "x$enable_linux_builtin" != xyes; then
+			AC_MSG_ERROR([*** Cannot find UTS_RELEASE definition.])
+		else
+			AC_MSG_ERROR([
+	*** Cannot find UTS_RELEASE definition.
+	*** Please run 'make prepare' inside the kernel source tree.])
+		fi
+	])
+
+	AC_MSG_RESULT([$kernsrcver])
+
+	LINUX=${kernelsrc}
+	LINUX_OBJ=${kernelbuild}
+	LINUX_VERSION=${kernsrcver}
+
+	AC_SUBST(LINUX)
+	AC_SUBST(LINUX_OBJ)
+	AC_SUBST(LINUX_VERSION)
+
+	ZFS_AC_MODULE_SYMVERS
+])
+
+
+dnl #
+dnl # Detect the SPL module to be built against
+dnl #
+AC_DEFUN([ZFS_AC_SPL], [
+	AC_ARG_WITH([spl],
+		AS_HELP_STRING([--with-spl=PATH],
+		[Path to spl source]),
+		[splsrc="$withval"])
+
+	AC_ARG_WITH([spl-obj],
+		AS_HELP_STRING([--with-spl-obj=PATH],
+		[Path to spl build objects]),
+		[splbuild="$withval"])
+
+	AC_ARG_WITH([spl-timeout],
+		AS_HELP_STRING([--with-spl-timeout=SECS],
+		[Wait SECS for SPL header and symver file @<:@default=0@:>@]),
+		[timeout="$withval"], [timeout=0])
+
+	dnl #
+	dnl # The existence of spl.release.in is used to identify a valid
+	dnl # source directory.  In order of preference:
+	dnl #
+	splsrc0="/var/lib/dkms/spl/${VERSION}/build"
+	splsrc1="/usr/local/src/spl-${VERSION}/${LINUX_VERSION}"
+	splsrc2="/usr/local/src/spl-${VERSION}"
+	splsrc3="/usr/src/spl-${VERSION}/${LINUX_VERSION}"
+	splsrc4="/usr/src/spl-${VERSION}"
+	splsrc5="../spl/"
+	splsrc6="$LINUX"
+
+	AC_MSG_CHECKING([spl source directory])
+	AS_IF([test -z "${splsrc}"], [
+		AS_IF([ test -e "${splsrc0}/spl.release.in"], [
+			splsrc=${splsrc0}
+		], [ test -e "${splsrc1}/spl.release.in"], [
+			splsrc=${splsrc1}
+		], [ test -e "${splsrc2}/spl.release.in"], [
+			splsrc=${splsrc2}
+		], [ test -e "${splsrc3}/spl.release.in"], [
+			splsrc=$(readlink -f "${splsrc3}")
+		], [ test -e "${splsrc4}/spl.release.in" ], [
+			splsrc=${splsrc4}
+		], [ test -e "${splsrc5}/spl.release.in"], [
+			splsrc=$(readlink -f "${splsrc5}")
+		], [ test -e "${splsrc6}/spl.release.in" ], [
+			splsrc=${splsrc6}
+		], [
+			splsrc="[Not found]"
+		])
+	], [
+		AS_IF([test "$splsrc" = "NONE"], [
+			splbuild=NONE
+			splsrcver=NONE
+		])
+	])
+
+	AC_MSG_RESULT([$splsrc])
+	AS_IF([ test ! -e "$splsrc/spl.release.in"], [
+		AC_MSG_ERROR([
+	*** Please make sure the kmod spl devel package for your distribution
+	*** is installed then try again.  If that fails you can specify the
+	*** location of the spl source with the '--with-spl=PATH' option.])
+	])
+
+	dnl #
+	dnl # The existence of the spl_config.h is used to identify a valid
+	dnl # spl object directory.  In many cases the object and source
+	dnl # directory are the same, however the objects may also reside
+	dnl # is a subdirectory named after the kernel version.
+	dnl #
+	dnl # This file is supposed to be available after DKMS finishes
+	dnl # building the SPL kernel module for the target kernel.  The
+	dnl # '--with-spl-timeout' option can be passed to pause here,
+	dnl # waiting for the file to appear from a concurrently building
+	dnl # SPL package.
+	dnl #
+	AC_MSG_CHECKING([spl build directory])
+	while true; do
+		AS_IF([test -z "$splbuild"], [
+			AS_IF([ test -e "${splsrc}/${LINUX_VERSION}/spl_config.h" ], [
+				splbuild="${splsrc}/${LINUX_VERSION}"
+			], [ test -e "${splsrc}/spl_config.h" ], [
+				splbuild="${splsrc}"
+			], [ find -L "${splsrc}" -name spl_config.h 2> /dev/null | grep -wq spl_config.h ], [
+				splbuild=$(find -L "${splsrc}" -name spl_config.h | sed 's,/spl_config.h,,')
+			], [
+				splbuild="[Not found]"
+			])
+		])
+		AS_IF([test -e "$splbuild/spl_config.h" -o $timeout -le 0], [
+			break;
+		], [
+			sleep 1
+			timeout=$((timeout-1))
+		])
+	done
+
+	AC_MSG_RESULT([$splbuild])
+	AS_IF([ ! test -e "$splbuild/spl_config.h"], [
+		AC_MSG_ERROR([
+	*** Please make sure the kmod spl devel <kernel> package for your
+	*** distribution is installed then try again.  If that fails you
+	*** can specify the location of the spl objects with the
+	*** '--with-spl-obj=PATH' option.])
+	])
+
+	AC_MSG_CHECKING([spl source version])
+	AS_IF([test -r $splbuild/spl_config.h &&
+		fgrep -q SPL_META_VERSION $splbuild/spl_config.h], [
+
+		splsrcver=`(echo "#include <spl_config.h>";
+		            echo "splsrcver=SPL_META_VERSION-SPL_META_RELEASE") |
+		            cpp -I $splbuild |
+		            grep "^splsrcver=" | tr -d \" | cut -d= -f2`
+	])
+
+	AS_IF([test -z "$splsrcver"], [
+		AC_MSG_RESULT([Not found])
+		AC_MSG_ERROR([
+	*** Cannot determine the version of the spl source.
+	*** Please prepare the spl source before running this script])
+	])
+
+	AC_MSG_RESULT([$splsrcver])
+
+	SPL=${splsrc}
+	SPL_OBJ=${splbuild}
+	SPL_VERSION=${splsrcver}
+
+	AC_SUBST(SPL)
+	AC_SUBST(SPL_OBJ)
+	AC_SUBST(SPL_VERSION)
+
+	dnl #
+	dnl # Detect the name used for the SPL Module.symvers file.  If one
+	dnl # does not exist this is likely because the SPL has been configured
+	dnl # but not built.  The '--with-spl-timeout' option can be passed
+	dnl # to pause here, waiting for the file to appear from a concurrently
+	dnl # building SPL package.  If the file does not appear in time, a good
+	dnl # guess is made as to what this file will be named based on what it
+	dnl # is named in the kernel build products.  This file will first be
+	dnl # used at link time so if the guess is wrong the build will fail
+	dnl # then.  This unfortunately means the ZFS package does not contain a
+	dnl # reliable mechanism to detect symbols exported by the SPL at
+	dnl # configure time.
+	dnl #
+	AC_MSG_CHECKING([spl file name for module symbols])
+	SPL_SYMBOLS=NONE
+
+	while true; do
+		AS_IF([test -r $SPL_OBJ/Module.symvers], [
+			SPL_SYMBOLS=Module.symvers
+		], [test -r $SPL_OBJ/Modules.symvers], [
+			SPL_SYMBOLS=Modules.symvers
+		], [test -r $SPL_OBJ/module/Module.symvers], [
+			SPL_SYMBOLS=Module.symvers
+		], [test -r $SPL_OBJ/module/Modules.symvers], [
+			SPL_SYMBOLS=Modules.symvers
+		])
+
+		AS_IF([test $SPL_SYMBOLS != NONE -o $timeout -le 0], [
+			break;
+		], [
+			sleep 1
+			timeout=$((timeout-1))
+		])
+	done
+
+	AS_IF([test "$SPL_SYMBOLS" = NONE], [
+		SPL_SYMBOLS=$LINUX_SYMBOLS
+	])
+
+	AC_MSG_RESULT([$SPL_SYMBOLS])
+	AC_SUBST(SPL_SYMBOLS)
+])
+
+dnl #
+dnl # Basic toolchain sanity check.
+dnl #
+AC_DEFUN([ZFS_AC_TEST_MODULE], [
+	AC_MSG_CHECKING([whether modules can be built])
+	ZFS_LINUX_TRY_COMPILE([],[],[
+		AC_MSG_RESULT([yes])
+	],[
+		AC_MSG_RESULT([no])
+		if test "x$enable_linux_builtin" != xyes; then
+			AC_MSG_ERROR([*** Unable to build an empty module.])
+		else
+			AC_MSG_ERROR([
+	*** Unable to build an empty module.
+	*** Please run 'make scripts' inside the kernel source tree.])
+		fi
+	])
+])
+
+dnl #
+dnl # Certain kernel build options are not supported.  These must be
+dnl # detected at configure time and cause a build failure.  Otherwise
+dnl # modules may be successfully built that behave incorrectly.
+dnl #
+AC_DEFUN([ZFS_AC_KERNEL_CONFIG], [
+	AS_IF([test "x$cross_compiling" != xyes], [
+		AC_RUN_IFELSE([
+			AC_LANG_PROGRAM([
+				#include "$LINUX/include/linux/license.h"
+			], [
+				return !license_is_gpl_compatible("$ZFS_META_LICENSE");
+			])
+		], [
+			AC_DEFINE([ZFS_IS_GPL_COMPATIBLE], [1],
+			    [Define to 1 if GPL-only symbols can be used])
+		], [
+		])
+	])
+
+	ZFS_AC_KERNEL_CONFIG_DEBUG_LOCK_ALLOC
+])
+
+dnl #
+dnl # Check CONFIG_DEBUG_LOCK_ALLOC
+dnl #
+dnl # This is typically only set for debug kernels because it comes with
+dnl # a performance penalty.  However, when it is set it maps the non-GPL
+dnl # symbol mutex_lock() to the GPL-only mutex_lock_nested() symbol.
+dnl # This will cause a failure at link time which we'd rather know about
+dnl # at compile time.
+dnl #
+dnl # Since we plan to pursue making mutex_lock_nested() a non-GPL symbol
+dnl # with the upstream community we add a check to detect this case.
+dnl #
+AC_DEFUN([ZFS_AC_KERNEL_CONFIG_DEBUG_LOCK_ALLOC], [
+
+	ZFS_LINUX_CONFIG([DEBUG_LOCK_ALLOC], [
+		AC_MSG_CHECKING([whether mutex_lock() is GPL-only])
+		tmp_flags="$EXTRA_KCFLAGS"
+		ZFS_LINUX_TRY_COMPILE([
+			#include <linux/module.h>
+			#include <linux/mutex.h>
+
+			MODULE_LICENSE("$ZFS_META_LICENSE");
+		],[
+			struct mutex lock;
+
+			mutex_init(&lock);
+			mutex_lock(&lock);
+			mutex_unlock(&lock);
+		],[
+			AC_MSG_RESULT(no)
+		],[
+			AC_MSG_RESULT(yes)
+			AC_MSG_ERROR([
+	*** Kernel built with CONFIG_DEBUG_LOCK_ALLOC which is incompatible
+	*** with the CDDL license and will prevent the module linking stage
+	*** from succeeding.  You must rebuild your kernel without this
+	*** option enabled.])
+		])
+		EXTRA_KCFLAGS="$tmp_flags"
+	], [])
+])
+
+dnl #
+dnl # ZFS_LINUX_CONFTEST_H
+dnl #
+AC_DEFUN([ZFS_LINUX_CONFTEST_H], [
+cat - <<_ACEOF >conftest.h
+$1
+_ACEOF
+])
+
+dnl #
+dnl # ZFS_LINUX_CONFTEST_C
+dnl #
+AC_DEFUN([ZFS_LINUX_CONFTEST_C], [
+cat confdefs.h - <<_ACEOF >conftest.c
+$1
+_ACEOF
+])
+
+dnl #
+dnl # ZFS_LANG_PROGRAM(C)([PROLOGUE], [BODY])
+dnl #
+m4_define([ZFS_LANG_PROGRAM], [
+$1
+int
+main (void)
+{
+dnl Do *not* indent the following line: there may be CPP directives.
+dnl Don't move the `;' right after for the same reason.
+$2
+  ;
+  return 0;
+}
+])
+
+dnl #
+dnl # ZFS_LINUX_COMPILE_IFELSE / like AC_COMPILE_IFELSE
+dnl #
+AC_DEFUN([ZFS_LINUX_COMPILE_IFELSE], [
+	m4_ifvaln([$1], [ZFS_LINUX_CONFTEST_C([$1])])
+	m4_ifvaln([$6], [ZFS_LINUX_CONFTEST_H([$6])], [ZFS_LINUX_CONFTEST_H([])])
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	AS_IF(
+		[AC_TRY_COMMAND(cp conftest.c conftest.h build && make [$2] -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag) >/dev/null && AC_TRY_COMMAND([$3])],
+		[$4],
+		[_AC_MSG_LOG_CONFTEST m4_ifvaln([$5],[$5])]
+	)
+	rm -Rf build
+])
+
+dnl #
+dnl # ZFS_LINUX_TRY_COMPILE like AC_TRY_COMPILE
+dnl #
+AC_DEFUN([ZFS_LINUX_TRY_COMPILE],
+	[ZFS_LINUX_COMPILE_IFELSE(
+	[AC_LANG_SOURCE([ZFS_LANG_PROGRAM([[$1]], [[$2]])])],
+	[modules],
+	[test -s build/conftest.o],
+	[$3], [$4])
+])
+
+dnl #
+dnl # ZFS_LINUX_CONFIG
+dnl #
+AC_DEFUN([ZFS_LINUX_CONFIG],
+	[AC_MSG_CHECKING([whether Linux was built with CONFIG_$1])
+	ZFS_LINUX_TRY_COMPILE([
+		#include <linux/module.h>
+	],[
+		#ifndef CONFIG_$1
+		#error CONFIG_$1 not #defined
+		#endif
+	],[
+		AC_MSG_RESULT([yes])
+		$2
+	],[
+		AC_MSG_RESULT([no])
+		$3
+	])
+])
+
+dnl #
+dnl # ZFS_CHECK_SYMBOL_EXPORT
+dnl # check symbol exported or not
+dnl #
+AC_DEFUN([ZFS_CHECK_SYMBOL_EXPORT], [
+	grep -q -E '[[[:space:]]]$1[[[:space:]]]' \
+		$LINUX_OBJ/$LINUX_SYMBOLS 2>/dev/null
+	rc=$?
+	if test $rc -ne 0; then
+		export=0
+		for file in $2; do
+			grep -q -E "EXPORT_SYMBOL.*($1)" \
+				"$LINUX/$file" 2>/dev/null
+			rc=$?
+			if test $rc -eq 0; then
+				export=1
+				break;
+			fi
+		done
+		if test $export -eq 0; then :
+			$4
+		else :
+			$3
+		fi
+	else :
+		$3
+	fi
+])
+
+dnl #
+dnl # ZFS_LINUX_TRY_COMPILE_SYMBOL
+dnl # like ZFS_LINUX_TRY_COMPILE, except ZFS_CHECK_SYMBOL_EXPORT
+dnl # is called if not compiling for builtin
+dnl #
+AC_DEFUN([ZFS_LINUX_TRY_COMPILE_SYMBOL], [
+	ZFS_LINUX_TRY_COMPILE([$1], [$2], [rc=0], [rc=1])
+	if test $rc -ne 0; then :
+		$6
+	else
+		if test "x$enable_linux_builtin" != xyes; then
+			ZFS_CHECK_SYMBOL_EXPORT([$3], [$4], [rc=0], [rc=1])
+		fi
+		if test $rc -ne 0; then :
+			$6
+		else :
+			$5
+		fi
+	fi
+])
+
+dnl #
+dnl # ZFS_LINUX_TRY_COMPILE_HEADER
+dnl # like ZFS_LINUX_TRY_COMPILE, except the contents conftest.h are
+dnl # provided via the fifth parameter
+dnl #
+AC_DEFUN([ZFS_LINUX_TRY_COMPILE_HEADER],
+	[ZFS_LINUX_COMPILE_IFELSE(
+	[AC_LANG_SOURCE([ZFS_LANG_PROGRAM([[$1]], [[$2]])])],
+	[modules],
+	[test -s build/conftest.o],
+	[$3], [$4], [$5])
+])
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/config/libtool.m4
@@ -0,0 +1,8388 @@
+# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*-
+#
+#   Copyright (C) 1996-2001, 2003-2015 Free Software Foundation, Inc.
+#   Written by Gordon Matzigkeit, 1996
+#
+# This file is free software; the Free Software Foundation gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+
+m4_define([_LT_COPYING], [dnl
+# Copyright (C) 2014 Free Software Foundation, Inc.
+# This is free software; see the source for copying conditions.  There is NO
+# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+# GNU Libtool is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of of the License, or
+# (at your option) any later version.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program or library that is built
+# using GNU Libtool, you may include this file under the  same
+# distribution terms that you use for the rest of that program.
+#
+# GNU Libtool is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+])
+
+# serial 58 LT_INIT
+
+
+# LT_PREREQ(VERSION)
+# ------------------
+# Complain and exit if this libtool version is less that VERSION.
+m4_defun([LT_PREREQ],
+[m4_if(m4_version_compare(m4_defn([LT_PACKAGE_VERSION]), [$1]), -1,
+       [m4_default([$3],
+		   [m4_fatal([Libtool version $1 or higher is required],
+		             63)])],
+       [$2])])
+
+
+# _LT_CHECK_BUILDDIR
+# ------------------
+# Complain if the absolute build directory name contains unusual characters
+m4_defun([_LT_CHECK_BUILDDIR],
+[case `pwd` in
+  *\ * | *\	*)
+    AC_MSG_WARN([Libtool does not cope well with whitespace in `pwd`]) ;;
+esac
+])
+
+
+# LT_INIT([OPTIONS])
+# ------------------
+AC_DEFUN([LT_INIT],
+[AC_PREREQ([2.62])dnl We use AC_PATH_PROGS_FEATURE_CHECK
+AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl
+AC_BEFORE([$0], [LT_LANG])dnl
+AC_BEFORE([$0], [LT_OUTPUT])dnl
+AC_BEFORE([$0], [LTDL_INIT])dnl
+m4_require([_LT_CHECK_BUILDDIR])dnl
+
+dnl Autoconf doesn't catch unexpanded LT_ macros by default:
+m4_pattern_forbid([^_?LT_[A-Z_]+$])dnl
+m4_pattern_allow([^(_LT_EOF|LT_DLGLOBAL|LT_DLLAZY_OR_NOW|LT_MULTI_MODULE)$])dnl
+dnl aclocal doesn't pull ltoptions.m4, ltsugar.m4, or ltversion.m4
+dnl unless we require an AC_DEFUNed macro:
+AC_REQUIRE([LTOPTIONS_VERSION])dnl
+AC_REQUIRE([LTSUGAR_VERSION])dnl
+AC_REQUIRE([LTVERSION_VERSION])dnl
+AC_REQUIRE([LTOBSOLETE_VERSION])dnl
+m4_require([_LT_PROG_LTMAIN])dnl
+
+_LT_SHELL_INIT([SHELL=${CONFIG_SHELL-/bin/sh}])
+
+dnl Parse OPTIONS
+_LT_SET_OPTIONS([$0], [$1])
+
+# This can be used to rebuild libtool when needed
+LIBTOOL_DEPS=$ltmain
+
+# Always use our own libtool.
+LIBTOOL='$(SHELL) $(top_builddir)/libtool'
+AC_SUBST(LIBTOOL)dnl
+
+_LT_SETUP
+
+# Only expand once:
+m4_define([LT_INIT])
+])# LT_INIT
+
+# Old names:
+AU_ALIAS([AC_PROG_LIBTOOL], [LT_INIT])
+AU_ALIAS([AM_PROG_LIBTOOL], [LT_INIT])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_PROG_LIBTOOL], [])
+dnl AC_DEFUN([AM_PROG_LIBTOOL], [])
+
+
+# _LT_PREPARE_CC_BASENAME
+# -----------------------
+m4_defun([_LT_PREPARE_CC_BASENAME], [
+# Calculate cc_basename.  Skip known compiler wrappers and cross-prefix.
+func_cc_basename ()
+{
+    for cc_temp in @S|@*""; do
+      case $cc_temp in
+        compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;;
+        distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;;
+        \-*) ;;
+        *) break;;
+      esac
+    done
+    func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"`
+}
+])# _LT_PREPARE_CC_BASENAME
+
+
+# _LT_CC_BASENAME(CC)
+# -------------------
+# It would be clearer to call AC_REQUIREs from _LT_PREPARE_CC_BASENAME,
+# but that macro is also expanded into generated libtool script, which
+# arranges for $SED and $ECHO to be set by different means.
+m4_defun([_LT_CC_BASENAME],
+[m4_require([_LT_PREPARE_CC_BASENAME])dnl
+AC_REQUIRE([_LT_DECL_SED])dnl
+AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl
+func_cc_basename $1
+cc_basename=$func_cc_basename_result
+])
+
+
+# _LT_FILEUTILS_DEFAULTS
+# ----------------------
+# It is okay to use these file commands and assume they have been set
+# sensibly after 'm4_require([_LT_FILEUTILS_DEFAULTS])'.
+m4_defun([_LT_FILEUTILS_DEFAULTS],
+[: ${CP="cp -f"}
+: ${MV="mv -f"}
+: ${RM="rm -f"}
+])# _LT_FILEUTILS_DEFAULTS
+
+
+# _LT_SETUP
+# ---------
+m4_defun([_LT_SETUP],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+AC_REQUIRE([_LT_PREPARE_SED_QUOTE_VARS])dnl
+AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl
+
+_LT_DECL([], [PATH_SEPARATOR], [1], [The PATH separator for the build system])dnl
+dnl
+_LT_DECL([], [host_alias], [0], [The host system])dnl
+_LT_DECL([], [host], [0])dnl
+_LT_DECL([], [host_os], [0])dnl
+dnl
+_LT_DECL([], [build_alias], [0], [The build system])dnl
+_LT_DECL([], [build], [0])dnl
+_LT_DECL([], [build_os], [0])dnl
+dnl
+AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([LT_PATH_LD])dnl
+AC_REQUIRE([LT_PATH_NM])dnl
+dnl
+AC_REQUIRE([AC_PROG_LN_S])dnl
+test -z "$LN_S" && LN_S="ln -s"
+_LT_DECL([], [LN_S], [1], [Whether we need soft or hard links])dnl
+dnl
+AC_REQUIRE([LT_CMD_MAX_LEN])dnl
+_LT_DECL([objext], [ac_objext], [0], [Object file suffix (normally "o")])dnl
+_LT_DECL([], [exeext], [0], [Executable file suffix (normally "")])dnl
+dnl
+m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_CHECK_SHELL_FEATURES])dnl
+m4_require([_LT_PATH_CONVERSION_FUNCTIONS])dnl
+m4_require([_LT_CMD_RELOAD])dnl
+m4_require([_LT_CHECK_MAGIC_METHOD])dnl
+m4_require([_LT_CHECK_SHAREDLIB_FROM_LINKLIB])dnl
+m4_require([_LT_CMD_OLD_ARCHIVE])dnl
+m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl
+m4_require([_LT_WITH_SYSROOT])dnl
+m4_require([_LT_CMD_TRUNCATE])dnl
+
+_LT_CONFIG_LIBTOOL_INIT([
+# See if we are running on zsh, and set the options that allow our
+# commands through without removal of \ escapes INIT.
+if test -n "\${ZSH_VERSION+set}"; then
+   setopt NO_GLOB_SUBST
+fi
+])
+if test -n "${ZSH_VERSION+set}"; then
+   setopt NO_GLOB_SUBST
+fi
+
+_LT_CHECK_OBJDIR
+
+m4_require([_LT_TAG_COMPILER])dnl
+
+case $host_os in
+aix3*)
+  # AIX sometimes has problems with the GCC collect2 program.  For some
+  # reason, if we set the COLLECT_NAMES environment variable, the problems
+  # vanish in a puff of smoke.
+  if test set != "${COLLECT_NAMES+set}"; then
+    COLLECT_NAMES=
+    export COLLECT_NAMES
+  fi
+  ;;
+esac
+
+# Global variables:
+ofile=libtool
+can_build_shared=yes
+
+# All known linkers require a '.a' archive for static linking (except MSVC,
+# which needs '.lib').
+libext=a
+
+with_gnu_ld=$lt_cv_prog_gnu_ld
+
+old_CC=$CC
+old_CFLAGS=$CFLAGS
+
+# Set sane defaults for various variables
+test -z "$CC" && CC=cc
+test -z "$LTCC" && LTCC=$CC
+test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS
+test -z "$LD" && LD=ld
+test -z "$ac_objext" && ac_objext=o
+
+_LT_CC_BASENAME([$compiler])
+
+# Only perform the check for file, if the check method requires it
+test -z "$MAGIC_CMD" && MAGIC_CMD=file
+case $deplibs_check_method in
+file_magic*)
+  if test "$file_magic_cmd" = '$MAGIC_CMD'; then
+    _LT_PATH_MAGIC
+  fi
+  ;;
+esac
+
+# Use C for the default configuration in the libtool script
+LT_SUPPORTED_TAG([CC])
+_LT_LANG_C_CONFIG
+_LT_LANG_DEFAULT_CONFIG
+_LT_CONFIG_COMMANDS
+])# _LT_SETUP
+
+
+# _LT_PREPARE_SED_QUOTE_VARS
+# --------------------------
+# Define a few sed substitution that help us do robust quoting.
+m4_defun([_LT_PREPARE_SED_QUOTE_VARS],
+[# Backslashify metacharacters that are still active within
+# double-quoted strings.
+sed_quote_subst='s/\([["`$\\]]\)/\\\1/g'
+
+# Same as above, but do not quote variable references.
+double_quote_subst='s/\([["`\\]]\)/\\\1/g'
+
+# Sed substitution to delay expansion of an escaped shell variable in a
+# double_quote_subst'ed string.
+delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g'
+
+# Sed substitution to delay expansion of an escaped single quote.
+delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g'
+
+# Sed substitution to avoid accidental globbing in evaled expressions
+no_glob_subst='s/\*/\\\*/g'
+])
+
+# _LT_PROG_LTMAIN
+# ---------------
+# Note that this code is called both from 'configure', and 'config.status'
+# now that we use AC_CONFIG_COMMANDS to generate libtool.  Notably,
+# 'config.status' has no value for ac_aux_dir unless we are using Automake,
+# so we pass a copy along to make sure it has a sensible value anyway.
+m4_defun([_LT_PROG_LTMAIN],
+[m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([ltmain.sh])])dnl
+_LT_CONFIG_LIBTOOL_INIT([ac_aux_dir='$ac_aux_dir'])
+ltmain=$ac_aux_dir/ltmain.sh
+])# _LT_PROG_LTMAIN
+
+
+## ------------------------------------- ##
+## Accumulate code for creating libtool. ##
+## ------------------------------------- ##
+
+# So that we can recreate a full libtool script including additional
+# tags, we accumulate the chunks of code to send to AC_CONFIG_COMMANDS
+# in macros and then make a single call at the end using the 'libtool'
+# label.
+
+
+# _LT_CONFIG_LIBTOOL_INIT([INIT-COMMANDS])
+# ----------------------------------------
+# Register INIT-COMMANDS to be passed to AC_CONFIG_COMMANDS later.
+m4_define([_LT_CONFIG_LIBTOOL_INIT],
+[m4_ifval([$1],
+          [m4_append([_LT_OUTPUT_LIBTOOL_INIT],
+                     [$1
+])])])
+
+# Initialize.
+m4_define([_LT_OUTPUT_LIBTOOL_INIT])
+
+
+# _LT_CONFIG_LIBTOOL([COMMANDS])
+# ------------------------------
+# Register COMMANDS to be passed to AC_CONFIG_COMMANDS later.
+m4_define([_LT_CONFIG_LIBTOOL],
+[m4_ifval([$1],
+          [m4_append([_LT_OUTPUT_LIBTOOL_COMMANDS],
+                     [$1
+])])])
+
+# Initialize.
+m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS])
+
+
+# _LT_CONFIG_SAVE_COMMANDS([COMMANDS], [INIT_COMMANDS])
+# -----------------------------------------------------
+m4_defun([_LT_CONFIG_SAVE_COMMANDS],
+[_LT_CONFIG_LIBTOOL([$1])
+_LT_CONFIG_LIBTOOL_INIT([$2])
+])
+
+
+# _LT_FORMAT_COMMENT([COMMENT])
+# -----------------------------
+# Add leading comment marks to the start of each line, and a trailing
+# full-stop to the whole comment if one is not present already.
+m4_define([_LT_FORMAT_COMMENT],
+[m4_ifval([$1], [
+m4_bpatsubst([m4_bpatsubst([$1], [^ *], [# ])],
+              [['`$\]], [\\\&])]m4_bmatch([$1], [[!?.]$], [], [.])
+)])
+
+
+
+## ------------------------ ##
+## FIXME: Eliminate VARNAME ##
+## ------------------------ ##
+
+
+# _LT_DECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION], [IS-TAGGED?])
+# -------------------------------------------------------------------
+# CONFIGNAME is the name given to the value in the libtool script.
+# VARNAME is the (base) name used in the configure script.
+# VALUE may be 0, 1 or 2 for a computed quote escaped value based on
+# VARNAME.  Any other value will be used directly.
+m4_define([_LT_DECL],
+[lt_if_append_uniq([lt_decl_varnames], [$2], [, ],
+    [lt_dict_add_subkey([lt_decl_dict], [$2], [libtool_name],
+	[m4_ifval([$1], [$1], [$2])])
+    lt_dict_add_subkey([lt_decl_dict], [$2], [value], [$3])
+    m4_ifval([$4],
+	[lt_dict_add_subkey([lt_decl_dict], [$2], [description], [$4])])
+    lt_dict_add_subkey([lt_decl_dict], [$2],
+	[tagged?], [m4_ifval([$5], [yes], [no])])])
+])
+
+
+# _LT_TAGDECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION])
+# --------------------------------------------------------
+m4_define([_LT_TAGDECL], [_LT_DECL([$1], [$2], [$3], [$4], [yes])])
+
+
+# lt_decl_tag_varnames([SEPARATOR], [VARNAME1...])
+# ------------------------------------------------
+m4_define([lt_decl_tag_varnames],
+[_lt_decl_filter([tagged?], [yes], $@)])
+
+
+# _lt_decl_filter(SUBKEY, VALUE, [SEPARATOR], [VARNAME1..])
+# ---------------------------------------------------------
+m4_define([_lt_decl_filter],
+[m4_case([$#],
+  [0], [m4_fatal([$0: too few arguments: $#])],
+  [1], [m4_fatal([$0: too few arguments: $#: $1])],
+  [2], [lt_dict_filter([lt_decl_dict], [$1], [$2], [], lt_decl_varnames)],
+  [3], [lt_dict_filter([lt_decl_dict], [$1], [$2], [$3], lt_decl_varnames)],
+  [lt_dict_filter([lt_decl_dict], $@)])[]dnl
+])
+
+
+# lt_decl_quote_varnames([SEPARATOR], [VARNAME1...])
+# --------------------------------------------------
+m4_define([lt_decl_quote_varnames],
+[_lt_decl_filter([value], [1], $@)])
+
+
+# lt_decl_dquote_varnames([SEPARATOR], [VARNAME1...])
+# ---------------------------------------------------
+m4_define([lt_decl_dquote_varnames],
+[_lt_decl_filter([value], [2], $@)])
+
+
+# lt_decl_varnames_tagged([SEPARATOR], [VARNAME1...])
+# ---------------------------------------------------
+m4_define([lt_decl_varnames_tagged],
+[m4_assert([$# <= 2])dnl
+_$0(m4_quote(m4_default([$1], [[, ]])),
+    m4_ifval([$2], [[$2]], [m4_dquote(lt_decl_tag_varnames)]),
+    m4_split(m4_normalize(m4_quote(_LT_TAGS)), [ ]))])
+m4_define([_lt_decl_varnames_tagged],
+[m4_ifval([$3], [lt_combine([$1], [$2], [_], $3)])])
+
+
+# lt_decl_all_varnames([SEPARATOR], [VARNAME1...])
+# ------------------------------------------------
+m4_define([lt_decl_all_varnames],
+[_$0(m4_quote(m4_default([$1], [[, ]])),
+     m4_if([$2], [],
+	   m4_quote(lt_decl_varnames),
+	m4_quote(m4_shift($@))))[]dnl
+])
+m4_define([_lt_decl_all_varnames],
+[lt_join($@, lt_decl_varnames_tagged([$1],
+			lt_decl_tag_varnames([[, ]], m4_shift($@))))dnl
+])
+
+
+# _LT_CONFIG_STATUS_DECLARE([VARNAME])
+# ------------------------------------
+# Quote a variable value, and forward it to 'config.status' so that its
+# declaration there will have the same value as in 'configure'.  VARNAME
+# must have a single quote delimited value for this to work.
+m4_define([_LT_CONFIG_STATUS_DECLARE],
+[$1='`$ECHO "$][$1" | $SED "$delay_single_quote_subst"`'])
+
+
+# _LT_CONFIG_STATUS_DECLARATIONS
+# ------------------------------
+# We delimit libtool config variables with single quotes, so when
+# we write them to config.status, we have to be sure to quote all
+# embedded single quotes properly.  In configure, this macro expands
+# each variable declared with _LT_DECL (and _LT_TAGDECL) into:
+#
+#    <var>='`$ECHO "$<var>" | $SED "$delay_single_quote_subst"`'
+m4_defun([_LT_CONFIG_STATUS_DECLARATIONS],
+[m4_foreach([_lt_var], m4_quote(lt_decl_all_varnames),
+    [m4_n([_LT_CONFIG_STATUS_DECLARE(_lt_var)])])])
+
+
+# _LT_LIBTOOL_TAGS
+# ----------------
+# Output comment and list of tags supported by the script
+m4_defun([_LT_LIBTOOL_TAGS],
+[_LT_FORMAT_COMMENT([The names of the tagged configurations supported by this script])dnl
+available_tags='_LT_TAGS'dnl
+])
+
+
+# _LT_LIBTOOL_DECLARE(VARNAME, [TAG])
+# -----------------------------------
+# Extract the dictionary values for VARNAME (optionally with TAG) and
+# expand to a commented shell variable setting:
+#
+#    # Some comment about what VAR is for.
+#    visible_name=$lt_internal_name
+m4_define([_LT_LIBTOOL_DECLARE],
+[_LT_FORMAT_COMMENT(m4_quote(lt_dict_fetch([lt_decl_dict], [$1],
+					   [description])))[]dnl
+m4_pushdef([_libtool_name],
+    m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [libtool_name])))[]dnl
+m4_case(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [value])),
+    [0], [_libtool_name=[$]$1],
+    [1], [_libtool_name=$lt_[]$1],
+    [2], [_libtool_name=$lt_[]$1],
+    [_libtool_name=lt_dict_fetch([lt_decl_dict], [$1], [value])])[]dnl
+m4_ifval([$2], [_$2])[]m4_popdef([_libtool_name])[]dnl
+])
+
+
+# _LT_LIBTOOL_CONFIG_VARS
+# -----------------------
+# Produce commented declarations of non-tagged libtool config variables
+# suitable for insertion in the LIBTOOL CONFIG section of the 'libtool'
+# script.  Tagged libtool config variables (even for the LIBTOOL CONFIG
+# section) are produced by _LT_LIBTOOL_TAG_VARS.
+m4_defun([_LT_LIBTOOL_CONFIG_VARS],
+[m4_foreach([_lt_var],
+    m4_quote(_lt_decl_filter([tagged?], [no], [], lt_decl_varnames)),
+    [m4_n([_LT_LIBTOOL_DECLARE(_lt_var)])])])
+
+
+# _LT_LIBTOOL_TAG_VARS(TAG)
+# -------------------------
+m4_define([_LT_LIBTOOL_TAG_VARS],
+[m4_foreach([_lt_var], m4_quote(lt_decl_tag_varnames),
+    [m4_n([_LT_LIBTOOL_DECLARE(_lt_var, [$1])])])])
+
+
+# _LT_TAGVAR(VARNAME, [TAGNAME])
+# ------------------------------
+m4_define([_LT_TAGVAR], [m4_ifval([$2], [$1_$2], [$1])])
+
+
+# _LT_CONFIG_COMMANDS
+# -------------------
+# Send accumulated output to $CONFIG_STATUS.  Thanks to the lists of
+# variables for single and double quote escaping we saved from calls
+# to _LT_DECL, we can put quote escaped variables declarations
+# into 'config.status', and then the shell code to quote escape them in
+# for loops in 'config.status'.  Finally, any additional code accumulated
+# from calls to _LT_CONFIG_LIBTOOL_INIT is expanded.
+m4_defun([_LT_CONFIG_COMMANDS],
+[AC_PROVIDE_IFELSE([LT_OUTPUT],
+	dnl If the libtool generation code has been placed in $CONFIG_LT,
+	dnl instead of duplicating it all over again into config.status,
+	dnl then we will have config.status run $CONFIG_LT later, so it
+	dnl needs to know what name is stored there:
+        [AC_CONFIG_COMMANDS([libtool],
+            [$SHELL $CONFIG_LT || AS_EXIT(1)], [CONFIG_LT='$CONFIG_LT'])],
+    dnl If the libtool generation code is destined for config.status,
+    dnl expand the accumulated commands and init code now:
+    [AC_CONFIG_COMMANDS([libtool],
+        [_LT_OUTPUT_LIBTOOL_COMMANDS], [_LT_OUTPUT_LIBTOOL_COMMANDS_INIT])])
+])#_LT_CONFIG_COMMANDS
+
+
+# Initialize.
+m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS_INIT],
+[
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+sed_quote_subst='$sed_quote_subst'
+double_quote_subst='$double_quote_subst'
+delay_variable_subst='$delay_variable_subst'
+_LT_CONFIG_STATUS_DECLARATIONS
+LTCC='$LTCC'
+LTCFLAGS='$LTCFLAGS'
+compiler='$compiler_DEFAULT'
+
+# A function that is used when there is no print builtin or printf.
+func_fallback_echo ()
+{
+  eval 'cat <<_LTECHO_EOF
+\$[]1
+_LTECHO_EOF'
+}
+
+# Quote evaled strings.
+for var in lt_decl_all_varnames([[ \
+]], lt_decl_quote_varnames); do
+    case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in
+    *[[\\\\\\\`\\"\\\$]]*)
+      eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes
+      ;;
+    *)
+      eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
+      ;;
+    esac
+done
+
+# Double-quote double-evaled strings.
+for var in lt_decl_all_varnames([[ \
+]], lt_decl_dquote_varnames); do
+    case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in
+    *[[\\\\\\\`\\"\\\$]]*)
+      eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes
+      ;;
+    *)
+      eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
+      ;;
+    esac
+done
+
+_LT_OUTPUT_LIBTOOL_INIT
+])
+
+# _LT_GENERATED_FILE_INIT(FILE, [COMMENT])
+# ------------------------------------
+# Generate a child script FILE with all initialization necessary to
+# reuse the environment learned by the parent script, and make the
+# file executable.  If COMMENT is supplied, it is inserted after the
+# '#!' sequence but before initialization text begins.  After this
+# macro, additional text can be appended to FILE to form the body of
+# the child script.  The macro ends with non-zero status if the
+# file could not be fully written (such as if the disk is full).
+m4_ifdef([AS_INIT_GENERATED],
+[m4_defun([_LT_GENERATED_FILE_INIT],[AS_INIT_GENERATED($@)])],
+[m4_defun([_LT_GENERATED_FILE_INIT],
+[m4_require([AS_PREPARE])]dnl
+[m4_pushdef([AS_MESSAGE_LOG_FD])]dnl
+[lt_write_fail=0
+cat >$1 <<_ASEOF || lt_write_fail=1
+#! $SHELL
+# Generated by $as_me.
+$2
+SHELL=\${CONFIG_SHELL-$SHELL}
+export SHELL
+_ASEOF
+cat >>$1 <<\_ASEOF || lt_write_fail=1
+AS_SHELL_SANITIZE
+_AS_PREPARE
+exec AS_MESSAGE_FD>&1
+_ASEOF
+test 0 = "$lt_write_fail" && chmod +x $1[]dnl
+m4_popdef([AS_MESSAGE_LOG_FD])])])# _LT_GENERATED_FILE_INIT
+
+# LT_OUTPUT
+# ---------
+# This macro allows early generation of the libtool script (before
+# AC_OUTPUT is called), incase it is used in configure for compilation
+# tests.
+AC_DEFUN([LT_OUTPUT],
+[: ${CONFIG_LT=./config.lt}
+AC_MSG_NOTICE([creating $CONFIG_LT])
+_LT_GENERATED_FILE_INIT(["$CONFIG_LT"],
+[# Run this file to recreate a libtool stub with the current configuration.])
+
+cat >>"$CONFIG_LT" <<\_LTEOF
+lt_cl_silent=false
+exec AS_MESSAGE_LOG_FD>>config.log
+{
+  echo
+  AS_BOX([Running $as_me.])
+} >&AS_MESSAGE_LOG_FD
+
+lt_cl_help="\
+'$as_me' creates a local libtool stub from the current configuration,
+for use in further configure time tests before the real libtool is
+generated.
+
+Usage: $[0] [[OPTIONS]]
+
+  -h, --help      print this help, then exit
+  -V, --version   print version number, then exit
+  -q, --quiet     do not print progress messages
+  -d, --debug     don't remove temporary files
+
+Report bugs to <bug-libtool@gnu.org>."
+
+lt_cl_version="\
+m4_ifset([AC_PACKAGE_NAME], [AC_PACKAGE_NAME ])config.lt[]dnl
+m4_ifset([AC_PACKAGE_VERSION], [ AC_PACKAGE_VERSION])
+configured by $[0], generated by m4_PACKAGE_STRING.
+
+Copyright (C) 2011 Free Software Foundation, Inc.
+This config.lt script is free software; the Free Software Foundation
+gives unlimited permision to copy, distribute and modify it."
+
+while test 0 != $[#]
+do
+  case $[1] in
+    --version | --v* | -V )
+      echo "$lt_cl_version"; exit 0 ;;
+    --help | --h* | -h )
+      echo "$lt_cl_help"; exit 0 ;;
+    --debug | --d* | -d )
+      debug=: ;;
+    --quiet | --q* | --silent | --s* | -q )
+      lt_cl_silent=: ;;
+
+    -*) AC_MSG_ERROR([unrecognized option: $[1]
+Try '$[0] --help' for more information.]) ;;
+
+    *) AC_MSG_ERROR([unrecognized argument: $[1]
+Try '$[0] --help' for more information.]) ;;
+  esac
+  shift
+done
+
+if $lt_cl_silent; then
+  exec AS_MESSAGE_FD>/dev/null
+fi
+_LTEOF
+
+cat >>"$CONFIG_LT" <<_LTEOF
+_LT_OUTPUT_LIBTOOL_COMMANDS_INIT
+_LTEOF
+
+cat >>"$CONFIG_LT" <<\_LTEOF
+AC_MSG_NOTICE([creating $ofile])
+_LT_OUTPUT_LIBTOOL_COMMANDS
+AS_EXIT(0)
+_LTEOF
+chmod +x "$CONFIG_LT"
+
+# configure is writing to config.log, but config.lt does its own redirection,
+# appending to config.log, which fails on DOS, as config.log is still kept
+# open by configure.  Here we exec the FD to /dev/null, effectively closing
+# config.log, so it can be properly (re)opened and appended to by config.lt.
+lt_cl_success=:
+test yes = "$silent" &&
+  lt_config_lt_args="$lt_config_lt_args --quiet"
+exec AS_MESSAGE_LOG_FD>/dev/null
+$SHELL "$CONFIG_LT" $lt_config_lt_args || lt_cl_success=false
+exec AS_MESSAGE_LOG_FD>>config.log
+$lt_cl_success || AS_EXIT(1)
+])# LT_OUTPUT
+
+
+# _LT_CONFIG(TAG)
+# ---------------
+# If TAG is the built-in tag, create an initial libtool script with a
+# default configuration from the untagged config vars.  Otherwise add code
+# to config.status for appending the configuration named by TAG from the
+# matching tagged config vars.
+m4_defun([_LT_CONFIG],
+[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+_LT_CONFIG_SAVE_COMMANDS([
+  m4_define([_LT_TAG], m4_if([$1], [], [C], [$1]))dnl
+  m4_if(_LT_TAG, [C], [
+    # See if we are running on zsh, and set the options that allow our
+    # commands through without removal of \ escapes.
+    if test -n "${ZSH_VERSION+set}"; then
+      setopt NO_GLOB_SUBST
+    fi
+
+    cfgfile=${ofile}T
+    trap "$RM \"$cfgfile\"; exit 1" 1 2 15
+    $RM "$cfgfile"
+
+    cat <<_LT_EOF >> "$cfgfile"
+#! $SHELL
+# Generated automatically by $as_me ($PACKAGE) $VERSION
+# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+# NOTE: Changes made to this file will be lost: look at ltmain.sh.
+
+# Provide generalized library-building support services.
+# Written by Gordon Matzigkeit, 1996
+
+_LT_COPYING
+_LT_LIBTOOL_TAGS
+
+# Configured defaults for sys_lib_dlsearch_path munging.
+: \${LT_SYS_LIBRARY_PATH="$configure_time_lt_sys_library_path"}
+
+# ### BEGIN LIBTOOL CONFIG
+_LT_LIBTOOL_CONFIG_VARS
+_LT_LIBTOOL_TAG_VARS
+# ### END LIBTOOL CONFIG
+
+_LT_EOF
+
+    cat <<'_LT_EOF' >> "$cfgfile"
+
+# ### BEGIN FUNCTIONS SHARED WITH CONFIGURE
+
+_LT_PREPARE_MUNGE_PATH_LIST
+_LT_PREPARE_CC_BASENAME
+
+# ### END FUNCTIONS SHARED WITH CONFIGURE
+
+_LT_EOF
+
+  case $host_os in
+  aix3*)
+    cat <<\_LT_EOF >> "$cfgfile"
+# AIX sometimes has problems with the GCC collect2 program.  For some
+# reason, if we set the COLLECT_NAMES environment variable, the problems
+# vanish in a puff of smoke.
+if test set != "${COLLECT_NAMES+set}"; then
+  COLLECT_NAMES=
+  export COLLECT_NAMES
+fi
+_LT_EOF
+    ;;
+  esac
+
+  _LT_PROG_LTMAIN
+
+  # We use sed instead of cat because bash on DJGPP gets confused if
+  # if finds mixed CR/LF and LF-only lines.  Since sed operates in
+  # text mode, it properly converts lines to CR/LF.  This bash problem
+  # is reportedly fixed, but why not run on old versions too?
+  sed '$q' "$ltmain" >> "$cfgfile" \
+     || (rm -f "$cfgfile"; exit 1)
+
+   mv -f "$cfgfile" "$ofile" ||
+    (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile")
+  chmod +x "$ofile"
+],
+[cat <<_LT_EOF >> "$ofile"
+
+dnl Unfortunately we have to use $1 here, since _LT_TAG is not expanded
+dnl in a comment (ie after a #).
+# ### BEGIN LIBTOOL TAG CONFIG: $1
+_LT_LIBTOOL_TAG_VARS(_LT_TAG)
+# ### END LIBTOOL TAG CONFIG: $1
+_LT_EOF
+])dnl /m4_if
+],
+[m4_if([$1], [], [
+    PACKAGE='$PACKAGE'
+    VERSION='$VERSION'
+    RM='$RM'
+    ofile='$ofile'], [])
+])dnl /_LT_CONFIG_SAVE_COMMANDS
+])# _LT_CONFIG
+
+
+# LT_SUPPORTED_TAG(TAG)
+# ---------------------
+# Trace this macro to discover what tags are supported by the libtool
+# --tag option, using:
+#    autoconf --trace 'LT_SUPPORTED_TAG:$1'
+AC_DEFUN([LT_SUPPORTED_TAG], [])
+
+
+# C support is built-in for now
+m4_define([_LT_LANG_C_enabled], [])
+m4_define([_LT_TAGS], [])
+
+
+# LT_LANG(LANG)
+# -------------
+# Enable libtool support for the given language if not already enabled.
+AC_DEFUN([LT_LANG],
+[AC_BEFORE([$0], [LT_OUTPUT])dnl
+m4_case([$1],
+  [C],			[_LT_LANG(C)],
+  [C++],		[_LT_LANG(CXX)],
+  [Go],			[_LT_LANG(GO)],
+  [Java],		[_LT_LANG(GCJ)],
+  [Fortran 77],		[_LT_LANG(F77)],
+  [Fortran],		[_LT_LANG(FC)],
+  [Windows Resource],	[_LT_LANG(RC)],
+  [m4_ifdef([_LT_LANG_]$1[_CONFIG],
+    [_LT_LANG($1)],
+    [m4_fatal([$0: unsupported language: "$1"])])])dnl
+])# LT_LANG
+
+
+# _LT_LANG(LANGNAME)
+# ------------------
+m4_defun([_LT_LANG],
+[m4_ifdef([_LT_LANG_]$1[_enabled], [],
+  [LT_SUPPORTED_TAG([$1])dnl
+  m4_append([_LT_TAGS], [$1 ])dnl
+  m4_define([_LT_LANG_]$1[_enabled], [])dnl
+  _LT_LANG_$1_CONFIG($1)])dnl
+])# _LT_LANG
+
+
+m4_ifndef([AC_PROG_GO], [
+############################################################
+# NOTE: This macro has been submitted for inclusion into   #
+#  GNU Autoconf as AC_PROG_GO.  When it is available in    #
+#  a released version of Autoconf we should remove this    #
+#  macro and use it instead.                               #
+############################################################
+m4_defun([AC_PROG_GO],
+[AC_LANG_PUSH(Go)dnl
+AC_ARG_VAR([GOC],     [Go compiler command])dnl
+AC_ARG_VAR([GOFLAGS], [Go compiler flags])dnl
+_AC_ARG_VAR_LDFLAGS()dnl
+AC_CHECK_TOOL(GOC, gccgo)
+if test -z "$GOC"; then
+  if test -n "$ac_tool_prefix"; then
+    AC_CHECK_PROG(GOC, [${ac_tool_prefix}gccgo], [${ac_tool_prefix}gccgo])
+  fi
+fi
+if test -z "$GOC"; then
+  AC_CHECK_PROG(GOC, gccgo, gccgo, false)
+fi
+])#m4_defun
+])#m4_ifndef
+
+
+# _LT_LANG_DEFAULT_CONFIG
+# -----------------------
+m4_defun([_LT_LANG_DEFAULT_CONFIG],
+[AC_PROVIDE_IFELSE([AC_PROG_CXX],
+  [LT_LANG(CXX)],
+  [m4_define([AC_PROG_CXX], defn([AC_PROG_CXX])[LT_LANG(CXX)])])
+
+AC_PROVIDE_IFELSE([AC_PROG_F77],
+  [LT_LANG(F77)],
+  [m4_define([AC_PROG_F77], defn([AC_PROG_F77])[LT_LANG(F77)])])
+
+AC_PROVIDE_IFELSE([AC_PROG_FC],
+  [LT_LANG(FC)],
+  [m4_define([AC_PROG_FC], defn([AC_PROG_FC])[LT_LANG(FC)])])
+
+dnl The call to [A][M_PROG_GCJ] is quoted like that to stop aclocal
+dnl pulling things in needlessly.
+AC_PROVIDE_IFELSE([AC_PROG_GCJ],
+  [LT_LANG(GCJ)],
+  [AC_PROVIDE_IFELSE([A][M_PROG_GCJ],
+    [LT_LANG(GCJ)],
+    [AC_PROVIDE_IFELSE([LT_PROG_GCJ],
+      [LT_LANG(GCJ)],
+      [m4_ifdef([AC_PROG_GCJ],
+	[m4_define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[LT_LANG(GCJ)])])
+       m4_ifdef([A][M_PROG_GCJ],
+	[m4_define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[LT_LANG(GCJ)])])
+       m4_ifdef([LT_PROG_GCJ],
+	[m4_define([LT_PROG_GCJ], defn([LT_PROG_GCJ])[LT_LANG(GCJ)])])])])])
+
+AC_PROVIDE_IFELSE([AC_PROG_GO],
+  [LT_LANG(GO)],
+  [m4_define([AC_PROG_GO], defn([AC_PROG_GO])[LT_LANG(GO)])])
+
+AC_PROVIDE_IFELSE([LT_PROG_RC],
+  [LT_LANG(RC)],
+  [m4_define([LT_PROG_RC], defn([LT_PROG_RC])[LT_LANG(RC)])])
+])# _LT_LANG_DEFAULT_CONFIG
+
+# Obsolete macros:
+AU_DEFUN([AC_LIBTOOL_CXX], [LT_LANG(C++)])
+AU_DEFUN([AC_LIBTOOL_F77], [LT_LANG(Fortran 77)])
+AU_DEFUN([AC_LIBTOOL_FC], [LT_LANG(Fortran)])
+AU_DEFUN([AC_LIBTOOL_GCJ], [LT_LANG(Java)])
+AU_DEFUN([AC_LIBTOOL_RC], [LT_LANG(Windows Resource)])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_CXX], [])
+dnl AC_DEFUN([AC_LIBTOOL_F77], [])
+dnl AC_DEFUN([AC_LIBTOOL_FC], [])
+dnl AC_DEFUN([AC_LIBTOOL_GCJ], [])
+dnl AC_DEFUN([AC_LIBTOOL_RC], [])
+
+
+# _LT_TAG_COMPILER
+# ----------------
+m4_defun([_LT_TAG_COMPILER],
+[AC_REQUIRE([AC_PROG_CC])dnl
+
+_LT_DECL([LTCC], [CC], [1], [A C compiler])dnl
+_LT_DECL([LTCFLAGS], [CFLAGS], [1], [LTCC compiler flags])dnl
+_LT_TAGDECL([CC], [compiler], [1], [A language specific compiler])dnl
+_LT_TAGDECL([with_gcc], [GCC], [0], [Is the compiler the GNU compiler?])dnl
+
+# If no C compiler was specified, use CC.
+LTCC=${LTCC-"$CC"}
+
+# If no C compiler flags were specified, use CFLAGS.
+LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
+
+# Allow CC to be a program name with arguments.
+compiler=$CC
+])# _LT_TAG_COMPILER
+
+
+# _LT_COMPILER_BOILERPLATE
+# ------------------------
+# Check for compiler boilerplate output or warnings with
+# the simple compiler test code.
+m4_defun([_LT_COMPILER_BOILERPLATE],
+[m4_require([_LT_DECL_SED])dnl
+ac_outfile=conftest.$ac_objext
+echo "$lt_simple_compile_test_code" >conftest.$ac_ext
+eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_compiler_boilerplate=`cat conftest.err`
+$RM conftest*
+])# _LT_COMPILER_BOILERPLATE
+
+
+# _LT_LINKER_BOILERPLATE
+# ----------------------
+# Check for linker boilerplate output or warnings with
+# the simple link test code.
+m4_defun([_LT_LINKER_BOILERPLATE],
+[m4_require([_LT_DECL_SED])dnl
+ac_outfile=conftest.$ac_objext
+echo "$lt_simple_link_test_code" >conftest.$ac_ext
+eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_linker_boilerplate=`cat conftest.err`
+$RM -r conftest*
+])# _LT_LINKER_BOILERPLATE
+
+# _LT_REQUIRED_DARWIN_CHECKS
+# -------------------------
+m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[
+  case $host_os in
+    rhapsody* | darwin*)
+    AC_CHECK_TOOL([DSYMUTIL], [dsymutil], [:])
+    AC_CHECK_TOOL([NMEDIT], [nmedit], [:])
+    AC_CHECK_TOOL([LIPO], [lipo], [:])
+    AC_CHECK_TOOL([OTOOL], [otool], [:])
+    AC_CHECK_TOOL([OTOOL64], [otool64], [:])
+    _LT_DECL([], [DSYMUTIL], [1],
+      [Tool to manipulate archived DWARF debug symbol files on Mac OS X])
+    _LT_DECL([], [NMEDIT], [1],
+      [Tool to change global to local symbols on Mac OS X])
+    _LT_DECL([], [LIPO], [1],
+      [Tool to manipulate fat objects and archives on Mac OS X])
+    _LT_DECL([], [OTOOL], [1],
+      [ldd/readelf like tool for Mach-O binaries on Mac OS X])
+    _LT_DECL([], [OTOOL64], [1],
+      [ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4])
+
+    AC_CACHE_CHECK([for -single_module linker flag],[lt_cv_apple_cc_single_mod],
+      [lt_cv_apple_cc_single_mod=no
+      if test -z "$LT_MULTI_MODULE"; then
+	# By default we will add the -single_module flag. You can override
+	# by either setting the environment variable LT_MULTI_MODULE
+	# non-empty at configure time, or by adding -multi_module to the
+	# link flags.
+	rm -rf libconftest.dylib*
+	echo "int foo(void){return 1;}" > conftest.c
+	echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \
+-dynamiclib -Wl,-single_module conftest.c" >&AS_MESSAGE_LOG_FD
+	$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \
+	  -dynamiclib -Wl,-single_module conftest.c 2>conftest.err
+        _lt_result=$?
+	# If there is a non-empty error log, and "single_module"
+	# appears in it, assume the flag caused a linker warning
+        if test -s conftest.err && $GREP single_module conftest.err; then
+	  cat conftest.err >&AS_MESSAGE_LOG_FD
+	# Otherwise, if the output was created with a 0 exit code from
+	# the compiler, it worked.
+	elif test -f libconftest.dylib && test 0 = "$_lt_result"; then
+	  lt_cv_apple_cc_single_mod=yes
+	else
+	  cat conftest.err >&AS_MESSAGE_LOG_FD
+	fi
+	rm -rf libconftest.dylib*
+	rm -f conftest.*
+      fi])
+
+    AC_CACHE_CHECK([for -exported_symbols_list linker flag],
+      [lt_cv_ld_exported_symbols_list],
+      [lt_cv_ld_exported_symbols_list=no
+      save_LDFLAGS=$LDFLAGS
+      echo "_main" > conftest.sym
+      LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym"
+      AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])],
+	[lt_cv_ld_exported_symbols_list=yes],
+	[lt_cv_ld_exported_symbols_list=no])
+	LDFLAGS=$save_LDFLAGS
+    ])
+
+    AC_CACHE_CHECK([for -force_load linker flag],[lt_cv_ld_force_load],
+      [lt_cv_ld_force_load=no
+      cat > conftest.c << _LT_EOF
+int forced_loaded() { return 2;}
+_LT_EOF
+      echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&AS_MESSAGE_LOG_FD
+      $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&AS_MESSAGE_LOG_FD
+      echo "$AR cru libconftest.a conftest.o" >&AS_MESSAGE_LOG_FD
+      $AR cru libconftest.a conftest.o 2>&AS_MESSAGE_LOG_FD
+      echo "$RANLIB libconftest.a" >&AS_MESSAGE_LOG_FD
+      $RANLIB libconftest.a 2>&AS_MESSAGE_LOG_FD
+      cat > conftest.c << _LT_EOF
+int main() { return 0;}
+_LT_EOF
+      echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&AS_MESSAGE_LOG_FD
+      $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err
+      _lt_result=$?
+      if test -s conftest.err && $GREP force_load conftest.err; then
+	cat conftest.err >&AS_MESSAGE_LOG_FD
+      elif test -f conftest && test 0 = "$_lt_result" && $GREP forced_load conftest >/dev/null 2>&1; then
+	lt_cv_ld_force_load=yes
+      else
+	cat conftest.err >&AS_MESSAGE_LOG_FD
+      fi
+        rm -f conftest.err libconftest.a conftest conftest.c
+        rm -rf conftest.dSYM
+    ])
+    case $host_os in
+    rhapsody* | darwin1.[[012]])
+      _lt_dar_allow_undefined='$wl-undefined ${wl}suppress' ;;
+    darwin1.*)
+      _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;;
+    darwin*) # darwin 5.x on
+      # if running on 10.5 or later, the deployment target defaults
+      # to the OS version, if on x86, and 10.4, the deployment
+      # target defaults to 10.4. Don't you love it?
+      case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in
+	10.0,*86*-darwin8*|10.0,*-darwin[[91]]*)
+	  _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;;
+	10.[[012]][[,.]]*)
+	  _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;;
+	10.*)
+	  _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;;
+      esac
+    ;;
+  esac
+    if test yes = "$lt_cv_apple_cc_single_mod"; then
+      _lt_dar_single_mod='$single_module'
+    fi
+    if test yes = "$lt_cv_ld_exported_symbols_list"; then
+      _lt_dar_export_syms=' $wl-exported_symbols_list,$output_objdir/$libname-symbols.expsym'
+    else
+      _lt_dar_export_syms='~$NMEDIT -s $output_objdir/$libname-symbols.expsym $lib'
+    fi
+    if test : != "$DSYMUTIL" && test no = "$lt_cv_ld_force_load"; then
+      _lt_dsymutil='~$DSYMUTIL $lib || :'
+    else
+      _lt_dsymutil=
+    fi
+    ;;
+  esac
+])
+
+
+# _LT_DARWIN_LINKER_FEATURES([TAG])
+# ---------------------------------
+# Checks for linker and compiler features on darwin
+m4_defun([_LT_DARWIN_LINKER_FEATURES],
+[
+  m4_require([_LT_REQUIRED_DARWIN_CHECKS])
+  _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+  _LT_TAGVAR(hardcode_direct, $1)=no
+  _LT_TAGVAR(hardcode_automatic, $1)=yes
+  _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
+  if test yes = "$lt_cv_ld_force_load"; then
+    _LT_TAGVAR(whole_archive_flag_spec, $1)='`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience $wl-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`'
+    m4_case([$1], [F77], [_LT_TAGVAR(compiler_needs_object, $1)=yes],
+                  [FC],  [_LT_TAGVAR(compiler_needs_object, $1)=yes])
+  else
+    _LT_TAGVAR(whole_archive_flag_spec, $1)=''
+  fi
+  _LT_TAGVAR(link_all_deplibs, $1)=yes
+  _LT_TAGVAR(allow_undefined_flag, $1)=$_lt_dar_allow_undefined
+  case $cc_basename in
+     ifort*|nagfor*) _lt_dar_can_shared=yes ;;
+     *) _lt_dar_can_shared=$GCC ;;
+  esac
+  if test yes = "$_lt_dar_can_shared"; then
+    output_verbose_link_cmd=func_echo_all
+    _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil"
+    _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil"
+    _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil"
+    _LT_TAGVAR(module_expsym_cmds, $1)="sed -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil"
+    m4_if([$1], [CXX],
+[   if test yes != "$lt_cv_apple_cc_single_mod"; then
+      _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dsymutil"
+      _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dar_export_syms$_lt_dsymutil"
+    fi
+],[])
+  else
+  _LT_TAGVAR(ld_shlibs, $1)=no
+  fi
+])
+
+# _LT_SYS_MODULE_PATH_AIX([TAGNAME])
+# ----------------------------------
+# Links a minimal program and checks the executable
+# for the system default hardcoded library path. In most cases,
+# this is /usr/lib:/lib, but when the MPI compilers are used
+# the location of the communication and MPI libs are included too.
+# If we don't find anything, use the default library path according
+# to the aix ld manual.
+# Store the results from the different compilers for each TAGNAME.
+# Allow to override them for all tags through lt_cv_aix_libpath.
+m4_defun([_LT_SYS_MODULE_PATH_AIX],
+[m4_require([_LT_DECL_SED])dnl
+if test set = "${lt_cv_aix_libpath+set}"; then
+  aix_libpath=$lt_cv_aix_libpath
+else
+  AC_CACHE_VAL([_LT_TAGVAR([lt_cv_aix_libpath_], [$1])],
+  [AC_LINK_IFELSE([AC_LANG_PROGRAM],[
+  lt_aix_libpath_sed='[
+      /Import File Strings/,/^$/ {
+	  /^0/ {
+	      s/^0  *\([^ ]*\) *$/\1/
+	      p
+	  }
+      }]'
+  _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+  # Check for a 64-bit object if we didn't find anything.
+  if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then
+    _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+  fi],[])
+  if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then
+    _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=/usr/lib:/lib
+  fi
+  ])
+  aix_libpath=$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])
+fi
+])# _LT_SYS_MODULE_PATH_AIX
+
+
+# _LT_SHELL_INIT(ARG)
+# -------------------
+m4_define([_LT_SHELL_INIT],
+[m4_divert_text([M4SH-INIT], [$1
+])])# _LT_SHELL_INIT
+
+
+
+# _LT_PROG_ECHO_BACKSLASH
+# -----------------------
+# Find how we can fake an echo command that does not interpret backslash.
+# In particular, with Autoconf 2.60 or later we add some code to the start
+# of the generated configure script that will find a shell with a builtin
+# printf (that we can use as an echo command).
+m4_defun([_LT_PROG_ECHO_BACKSLASH],
+[ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO
+ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO
+
+AC_MSG_CHECKING([how to print strings])
+# Test print first, because it will be a builtin if present.
+if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \
+   test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then
+  ECHO='print -r --'
+elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then
+  ECHO='printf %s\n'
+else
+  # Use this function as a fallback that always works.
+  func_fallback_echo ()
+  {
+    eval 'cat <<_LTECHO_EOF
+$[]1
+_LTECHO_EOF'
+  }
+  ECHO='func_fallback_echo'
+fi
+
+# func_echo_all arg...
+# Invoke $ECHO with all args, space-separated.
+func_echo_all ()
+{
+    $ECHO "$*"
+}
+
+case $ECHO in
+  printf*) AC_MSG_RESULT([printf]) ;;
+  print*) AC_MSG_RESULT([print -r]) ;;
+  *) AC_MSG_RESULT([cat]) ;;
+esac
+
+m4_ifdef([_AS_DETECT_SUGGESTED],
+[_AS_DETECT_SUGGESTED([
+  test -n "${ZSH_VERSION+set}${BASH_VERSION+set}" || (
+    ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+    ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO
+    ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO
+    PATH=/empty FPATH=/empty; export PATH FPATH
+    test "X`printf %s $ECHO`" = "X$ECHO" \
+      || test "X`print -r -- $ECHO`" = "X$ECHO" )])])
+
+_LT_DECL([], [SHELL], [1], [Shell to use when invoking shell scripts])
+_LT_DECL([], [ECHO], [1], [An echo program that protects backslashes])
+])# _LT_PROG_ECHO_BACKSLASH
+
+
+# _LT_WITH_SYSROOT
+# ----------------
+AC_DEFUN([_LT_WITH_SYSROOT],
+[AC_MSG_CHECKING([for sysroot])
+AC_ARG_WITH([sysroot],
+[AS_HELP_STRING([--with-sysroot@<:@=DIR@:>@],
+  [Search for dependent libraries within DIR (or the compiler's sysroot
+   if not specified).])],
+[], [with_sysroot=no])
+
+dnl lt_sysroot will always be passed unquoted.  We quote it here
+dnl in case the user passed a directory name.
+lt_sysroot=
+case $with_sysroot in #(
+ yes)
+   if test yes = "$GCC"; then
+     lt_sysroot=`$CC --print-sysroot 2>/dev/null`
+   fi
+   ;; #(
+ /*)
+   lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"`
+   ;; #(
+ no|'')
+   ;; #(
+ *)
+   AC_MSG_RESULT([$with_sysroot])
+   AC_MSG_ERROR([The sysroot must be an absolute path.])
+   ;;
+esac
+
+ AC_MSG_RESULT([${lt_sysroot:-no}])
+_LT_DECL([], [lt_sysroot], [0], [The root where to search for ]dnl
+[dependent libraries, and where our libraries should be installed.])])
+
+# _LT_ENABLE_LOCK
+# ---------------
+m4_defun([_LT_ENABLE_LOCK],
+[AC_ARG_ENABLE([libtool-lock],
+  [AS_HELP_STRING([--disable-libtool-lock],
+    [avoid locking (might break parallel builds)])])
+test no = "$enable_libtool_lock" || enable_libtool_lock=yes
+
+# Some flags need to be propagated to the compiler or linker for good
+# libtool support.
+case $host in
+ia64-*-hpux*)
+  # Find out what ABI is being produced by ac_compile, and set mode
+  # options accordingly.
+  echo 'int i;' > conftest.$ac_ext
+  if AC_TRY_EVAL(ac_compile); then
+    case `/usr/bin/file conftest.$ac_objext` in
+      *ELF-32*)
+	HPUX_IA64_MODE=32
+	;;
+      *ELF-64*)
+	HPUX_IA64_MODE=64
+	;;
+    esac
+  fi
+  rm -rf conftest*
+  ;;
+*-*-irix6*)
+  # Find out what ABI is being produced by ac_compile, and set linker
+  # options accordingly.
+  echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext
+  if AC_TRY_EVAL(ac_compile); then
+    if test yes = "$lt_cv_prog_gnu_ld"; then
+      case `/usr/bin/file conftest.$ac_objext` in
+	*32-bit*)
+	  LD="${LD-ld} -melf32bsmip"
+	  ;;
+	*N32*)
+	  LD="${LD-ld} -melf32bmipn32"
+	  ;;
+	*64-bit*)
+	  LD="${LD-ld} -melf64bmip"
+	;;
+      esac
+    else
+      case `/usr/bin/file conftest.$ac_objext` in
+	*32-bit*)
+	  LD="${LD-ld} -32"
+	  ;;
+	*N32*)
+	  LD="${LD-ld} -n32"
+	  ;;
+	*64-bit*)
+	  LD="${LD-ld} -64"
+	  ;;
+      esac
+    fi
+  fi
+  rm -rf conftest*
+  ;;
+
+mips64*-*linux*)
+  # Find out what ABI is being produced by ac_compile, and set linker
+  # options accordingly.
+  echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext
+  if AC_TRY_EVAL(ac_compile); then
+    emul=elf
+    case `/usr/bin/file conftest.$ac_objext` in
+      *32-bit*)
+	emul="${emul}32"
+	;;
+      *64-bit*)
+	emul="${emul}64"
+	;;
+    esac
+    case `/usr/bin/file conftest.$ac_objext` in
+      *MSB*)
+	emul="${emul}btsmip"
+	;;
+      *LSB*)
+	emul="${emul}ltsmip"
+	;;
+    esac
+    case `/usr/bin/file conftest.$ac_objext` in
+      *N32*)
+	emul="${emul}n32"
+	;;
+    esac
+    LD="${LD-ld} -m $emul"
+  fi
+  rm -rf conftest*
+  ;;
+
+x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \
+s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
+  # Find out what ABI is being produced by ac_compile, and set linker
+  # options accordingly.  Note that the listed cases only cover the
+  # situations where additional linker options are needed (such as when
+  # doing 32-bit compilation for a host where ld defaults to 64-bit, or
+  # vice versa); the common cases where no linker options are needed do
+  # not appear in the list.
+  echo 'int i;' > conftest.$ac_ext
+  if AC_TRY_EVAL(ac_compile); then
+    case `/usr/bin/file conftest.o` in
+      *32-bit*)
+	case $host in
+	  x86_64-*kfreebsd*-gnu)
+	    LD="${LD-ld} -m elf_i386_fbsd"
+	    ;;
+	  x86_64-*linux*)
+	    case `/usr/bin/file conftest.o` in
+	      *x86-64*)
+		LD="${LD-ld} -m elf32_x86_64"
+		;;
+	      *)
+		LD="${LD-ld} -m elf_i386"
+		;;
+	    esac
+	    ;;
+	  powerpc64le-*linux*)
+	    LD="${LD-ld} -m elf32lppclinux"
+	    ;;
+	  powerpc64-*linux*)
+	    LD="${LD-ld} -m elf32ppclinux"
+	    ;;
+	  s390x-*linux*)
+	    LD="${LD-ld} -m elf_s390"
+	    ;;
+	  sparc64-*linux*)
+	    LD="${LD-ld} -m elf32_sparc"
+	    ;;
+	esac
+	;;
+      *64-bit*)
+	case $host in
+	  x86_64-*kfreebsd*-gnu)
+	    LD="${LD-ld} -m elf_x86_64_fbsd"
+	    ;;
+	  x86_64-*linux*)
+	    LD="${LD-ld} -m elf_x86_64"
+	    ;;
+	  powerpcle-*linux*)
+	    LD="${LD-ld} -m elf64lppc"
+	    ;;
+	  powerpc-*linux*)
+	    LD="${LD-ld} -m elf64ppc"
+	    ;;
+	  s390*-*linux*|s390*-*tpf*)
+	    LD="${LD-ld} -m elf64_s390"
+	    ;;
+	  sparc*-*linux*)
+	    LD="${LD-ld} -m elf64_sparc"
+	    ;;
+	esac
+	;;
+    esac
+  fi
+  rm -rf conftest*
+  ;;
+
+*-*-sco3.2v5*)
+  # On SCO OpenServer 5, we need -belf to get full-featured binaries.
+  SAVE_CFLAGS=$CFLAGS
+  CFLAGS="$CFLAGS -belf"
+  AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf,
+    [AC_LANG_PUSH(C)
+     AC_LINK_IFELSE([AC_LANG_PROGRAM([[]],[[]])],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no])
+     AC_LANG_POP])
+  if test yes != "$lt_cv_cc_needs_belf"; then
+    # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf
+    CFLAGS=$SAVE_CFLAGS
+  fi
+  ;;
+*-*solaris*)
+  # Find out what ABI is being produced by ac_compile, and set linker
+  # options accordingly.
+  echo 'int i;' > conftest.$ac_ext
+  if AC_TRY_EVAL(ac_compile); then
+    case `/usr/bin/file conftest.o` in
+    *64-bit*)
+      case $lt_cv_prog_gnu_ld in
+      yes*)
+        case $host in
+        i?86-*-solaris*|x86_64-*-solaris*)
+          LD="${LD-ld} -m elf_x86_64"
+          ;;
+        sparc*-*-solaris*)
+          LD="${LD-ld} -m elf64_sparc"
+          ;;
+        esac
+        # GNU ld 2.21 introduced _sol2 emulations.  Use them if available.
+        if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then
+          LD=${LD-ld}_sol2
+        fi
+        ;;
+      *)
+	if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then
+	  LD="${LD-ld} -64"
+	fi
+	;;
+      esac
+      ;;
+    esac
+  fi
+  rm -rf conftest*
+  ;;
+esac
+
+need_locks=$enable_libtool_lock
+])# _LT_ENABLE_LOCK
+
+
+# _LT_PROG_AR
+# -----------
+m4_defun([_LT_PROG_AR],
+[AC_CHECK_TOOLS(AR, [ar], false)
+: ${AR=ar}
+: ${AR_FLAGS=cru}
+_LT_DECL([], [AR], [1], [The archiver])
+_LT_DECL([], [AR_FLAGS], [1], [Flags to create an archive])
+
+AC_CACHE_CHECK([for archiver @FILE support], [lt_cv_ar_at_file],
+  [lt_cv_ar_at_file=no
+   AC_COMPILE_IFELSE([AC_LANG_PROGRAM],
+     [echo conftest.$ac_objext > conftest.lst
+      lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&AS_MESSAGE_LOG_FD'
+      AC_TRY_EVAL([lt_ar_try])
+      if test 0 -eq "$ac_status"; then
+	# Ensure the archiver fails upon bogus file names.
+	rm -f conftest.$ac_objext libconftest.a
+	AC_TRY_EVAL([lt_ar_try])
+	if test 0 -ne "$ac_status"; then
+          lt_cv_ar_at_file=@
+        fi
+      fi
+      rm -f conftest.* libconftest.a
+     ])
+  ])
+
+if test no = "$lt_cv_ar_at_file"; then
+  archiver_list_spec=
+else
+  archiver_list_spec=$lt_cv_ar_at_file
+fi
+_LT_DECL([], [archiver_list_spec], [1],
+  [How to feed a file listing to the archiver])
+])# _LT_PROG_AR
+
+
+# _LT_CMD_OLD_ARCHIVE
+# -------------------
+m4_defun([_LT_CMD_OLD_ARCHIVE],
+[_LT_PROG_AR
+
+AC_CHECK_TOOL(STRIP, strip, :)
+test -z "$STRIP" && STRIP=:
+_LT_DECL([], [STRIP], [1], [A symbol stripping program])
+
+AC_CHECK_TOOL(RANLIB, ranlib, :)
+test -z "$RANLIB" && RANLIB=:
+_LT_DECL([], [RANLIB], [1],
+    [Commands used to install an old-style archive])
+
+# Determine commands to create old-style static archives.
+old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs'
+old_postinstall_cmds='chmod 644 $oldlib'
+old_postuninstall_cmds=
+
+if test -n "$RANLIB"; then
+  case $host_os in
+  bitrig* | openbsd*)
+    old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib"
+    ;;
+  *)
+    old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib"
+    ;;
+  esac
+  old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib"
+fi
+
+case $host_os in
+  darwin*)
+    lock_old_archive_extraction=yes ;;
+  *)
+    lock_old_archive_extraction=no ;;
+esac
+_LT_DECL([], [old_postinstall_cmds], [2])
+_LT_DECL([], [old_postuninstall_cmds], [2])
+_LT_TAGDECL([], [old_archive_cmds], [2],
+    [Commands used to build an old-style archive])
+_LT_DECL([], [lock_old_archive_extraction], [0],
+    [Whether to use a lock for old archive extraction])
+])# _LT_CMD_OLD_ARCHIVE
+
+
+# _LT_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS,
+#		[OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE])
+# ----------------------------------------------------------------
+# Check whether the given compiler option works
+AC_DEFUN([_LT_COMPILER_OPTION],
+[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_DECL_SED])dnl
+AC_CACHE_CHECK([$1], [$2],
+  [$2=no
+   m4_if([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4])
+   echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+   lt_compiler_flag="$3"  ## exclude from sc_useless_quotes_in_assignment
+   # Insert the option either (1) after the last *FLAGS variable, or
+   # (2) before a word containing "conftest.", or (3) at the end.
+   # Note that $ac_compile itself does not contain backslashes and begins
+   # with a dollar sign (not a hyphen), so the echo should work correctly.
+   # The option is referenced via a variable to avoid confusing sed.
+   lt_compile=`echo "$ac_compile" | $SED \
+   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+   -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \
+   -e 's:$: $lt_compiler_flag:'`
+   (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD)
+   (eval "$lt_compile" 2>conftest.err)
+   ac_status=$?
+   cat conftest.err >&AS_MESSAGE_LOG_FD
+   echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD
+   if (exit $ac_status) && test -s "$ac_outfile"; then
+     # The compiler can only warn and ignore the option if not recognized
+     # So say no if there are warnings other than the usual output.
+     $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp
+     $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+     if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
+       $2=yes
+     fi
+   fi
+   $RM conftest*
+])
+
+if test yes = "[$]$2"; then
+    m4_if([$5], , :, [$5])
+else
+    m4_if([$6], , :, [$6])
+fi
+])# _LT_COMPILER_OPTION
+
+# Old name:
+AU_ALIAS([AC_LIBTOOL_COMPILER_OPTION], [_LT_COMPILER_OPTION])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION], [])
+
+
+# _LT_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS,
+#                  [ACTION-SUCCESS], [ACTION-FAILURE])
+# ----------------------------------------------------
+# Check whether the given linker option works
+AC_DEFUN([_LT_LINKER_OPTION],
+[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_DECL_SED])dnl
+AC_CACHE_CHECK([$1], [$2],
+  [$2=no
+   save_LDFLAGS=$LDFLAGS
+   LDFLAGS="$LDFLAGS $3"
+   echo "$lt_simple_link_test_code" > conftest.$ac_ext
+   if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
+     # The linker can only warn and ignore the option if not recognized
+     # So say no if there are warnings
+     if test -s conftest.err; then
+       # Append any errors to the config.log.
+       cat conftest.err 1>&AS_MESSAGE_LOG_FD
+       $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp
+       $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+       if diff conftest.exp conftest.er2 >/dev/null; then
+         $2=yes
+       fi
+     else
+       $2=yes
+     fi
+   fi
+   $RM -r conftest*
+   LDFLAGS=$save_LDFLAGS
+])
+
+if test yes = "[$]$2"; then
+    m4_if([$4], , :, [$4])
+else
+    m4_if([$5], , :, [$5])
+fi
+])# _LT_LINKER_OPTION
+
+# Old name:
+AU_ALIAS([AC_LIBTOOL_LINKER_OPTION], [_LT_LINKER_OPTION])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_LINKER_OPTION], [])
+
+
+# LT_CMD_MAX_LEN
+#---------------
+AC_DEFUN([LT_CMD_MAX_LEN],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+# find the maximum length of command line arguments
+AC_MSG_CHECKING([the maximum length of command line arguments])
+AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl
+  i=0
+  teststring=ABCD
+
+  case $build_os in
+  msdosdjgpp*)
+    # On DJGPP, this test can blow up pretty badly due to problems in libc
+    # (any single argument exceeding 2000 bytes causes a buffer overrun
+    # during glob expansion).  Even if it were fixed, the result of this
+    # check would be larger than it should be.
+    lt_cv_sys_max_cmd_len=12288;    # 12K is about right
+    ;;
+
+  gnu*)
+    # Under GNU Hurd, this test is not required because there is
+    # no limit to the length of command line arguments.
+    # Libtool will interpret -1 as no limit whatsoever
+    lt_cv_sys_max_cmd_len=-1;
+    ;;
+
+  cygwin* | mingw* | cegcc*)
+    # On Win9x/ME, this test blows up -- it succeeds, but takes
+    # about 5 minutes as the teststring grows exponentially.
+    # Worse, since 9x/ME are not pre-emptively multitasking,
+    # you end up with a "frozen" computer, even though with patience
+    # the test eventually succeeds (with a max line length of 256k).
+    # Instead, let's just punt: use the minimum linelength reported by
+    # all of the supported platforms: 8192 (on NT/2K/XP).
+    lt_cv_sys_max_cmd_len=8192;
+    ;;
+
+  mint*)
+    # On MiNT this can take a long time and run out of memory.
+    lt_cv_sys_max_cmd_len=8192;
+    ;;
+
+  amigaos*)
+    # On AmigaOS with pdksh, this test takes hours, literally.
+    # So we just punt and use a minimum line length of 8192.
+    lt_cv_sys_max_cmd_len=8192;
+    ;;
+
+  bitrig* | darwin* | dragonfly* | freebsd* | netbsd* | openbsd*)
+    # This has been around since 386BSD, at least.  Likely further.
+    if test -x /sbin/sysctl; then
+      lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax`
+    elif test -x /usr/sbin/sysctl; then
+      lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax`
+    else
+      lt_cv_sys_max_cmd_len=65536	# usable default for all BSDs
+    fi
+    # And add a safety zone
+    lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
+    lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
+    ;;
+
+  interix*)
+    # We know the value 262144 and hardcode it with a safety zone (like BSD)
+    lt_cv_sys_max_cmd_len=196608
+    ;;
+
+  os2*)
+    # The test takes a long time on OS/2.
+    lt_cv_sys_max_cmd_len=8192
+    ;;
+
+  osf*)
+    # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure
+    # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not
+    # nice to cause kernel panics so lets avoid the loop below.
+    # First set a reasonable default.
+    lt_cv_sys_max_cmd_len=16384
+    #
+    if test -x /sbin/sysconfig; then
+      case `/sbin/sysconfig -q proc exec_disable_arg_limit` in
+        *1*) lt_cv_sys_max_cmd_len=-1 ;;
+      esac
+    fi
+    ;;
+  sco3.2v5*)
+    lt_cv_sys_max_cmd_len=102400
+    ;;
+  sysv5* | sco5v6* | sysv4.2uw2*)
+    kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null`
+    if test -n "$kargmax"; then
+      lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[[	 ]]//'`
+    else
+      lt_cv_sys_max_cmd_len=32768
+    fi
+    ;;
+  *)
+    lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null`
+    if test -n "$lt_cv_sys_max_cmd_len" && \
+       test undefined != "$lt_cv_sys_max_cmd_len"; then
+      lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
+      lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
+    else
+      # Make teststring a little bigger before we do anything with it.
+      # a 1K string should be a reasonable start.
+      for i in 1 2 3 4 5 6 7 8; do
+        teststring=$teststring$teststring
+      done
+      SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}}
+      # If test is not a shell built-in, we'll probably end up computing a
+      # maximum length that is only half of the actual maximum length, but
+      # we can't tell.
+      while { test X`env echo "$teststring$teststring" 2>/dev/null` \
+	         = "X$teststring$teststring"; } >/dev/null 2>&1 &&
+	      test 17 != "$i" # 1/2 MB should be enough
+      do
+        i=`expr $i + 1`
+        teststring=$teststring$teststring
+      done
+      # Only check the string length outside the loop.
+      lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1`
+      teststring=
+      # Add a significant safety factor because C++ compilers can tack on
+      # massive amounts of additional arguments before passing them to the
+      # linker.  It appears as though 1/2 is a usable value.
+      lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2`
+    fi
+    ;;
+  esac
+])
+if test -n "$lt_cv_sys_max_cmd_len"; then
+  AC_MSG_RESULT($lt_cv_sys_max_cmd_len)
+else
+  AC_MSG_RESULT(none)
+fi
+max_cmd_len=$lt_cv_sys_max_cmd_len
+_LT_DECL([], [max_cmd_len], [0],
+    [What is the maximum length of a command?])
+])# LT_CMD_MAX_LEN
+
+# Old name:
+AU_ALIAS([AC_LIBTOOL_SYS_MAX_CMD_LEN], [LT_CMD_MAX_LEN])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN], [])
+
+
+# _LT_HEADER_DLFCN
+# ----------------
+m4_defun([_LT_HEADER_DLFCN],
+[AC_CHECK_HEADERS([dlfcn.h], [], [], [AC_INCLUDES_DEFAULT])dnl
+])# _LT_HEADER_DLFCN
+
+
+# _LT_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE,
+#                      ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING)
+# ----------------------------------------------------------------
+m4_defun([_LT_TRY_DLOPEN_SELF],
+[m4_require([_LT_HEADER_DLFCN])dnl
+if test yes = "$cross_compiling"; then :
+  [$4]
+else
+  lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+  lt_status=$lt_dlunknown
+  cat > conftest.$ac_ext <<_LT_EOF
+[#line $LINENO "configure"
+#include "confdefs.h"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+#  define LT_DLGLOBAL		RTLD_GLOBAL
+#else
+#  ifdef DL_GLOBAL
+#    define LT_DLGLOBAL		DL_GLOBAL
+#  else
+#    define LT_DLGLOBAL		0
+#  endif
+#endif
+
+/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
+   find out it does not work in some platform. */
+#ifndef LT_DLLAZY_OR_NOW
+#  ifdef RTLD_LAZY
+#    define LT_DLLAZY_OR_NOW		RTLD_LAZY
+#  else
+#    ifdef DL_LAZY
+#      define LT_DLLAZY_OR_NOW		DL_LAZY
+#    else
+#      ifdef RTLD_NOW
+#        define LT_DLLAZY_OR_NOW	RTLD_NOW
+#      else
+#        ifdef DL_NOW
+#          define LT_DLLAZY_OR_NOW	DL_NOW
+#        else
+#          define LT_DLLAZY_OR_NOW	0
+#        endif
+#      endif
+#    endif
+#  endif
+#endif
+
+/* When -fvisibility=hidden is used, assume the code has been annotated
+   correspondingly for the symbols needed.  */
+#if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))
+int fnord () __attribute__((visibility("default")));
+#endif
+
+int fnord () { return 42; }
+int main ()
+{
+  void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
+  int status = $lt_dlunknown;
+
+  if (self)
+    {
+      if (dlsym (self,"fnord"))       status = $lt_dlno_uscore;
+      else
+        {
+	  if (dlsym( self,"_fnord"))  status = $lt_dlneed_uscore;
+          else puts (dlerror ());
+	}
+      /* dlclose (self); */
+    }
+  else
+    puts (dlerror ());
+
+  return status;
+}]
+_LT_EOF
+  if AC_TRY_EVAL(ac_link) && test -s "conftest$ac_exeext" 2>/dev/null; then
+    (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null
+    lt_status=$?
+    case x$lt_status in
+      x$lt_dlno_uscore) $1 ;;
+      x$lt_dlneed_uscore) $2 ;;
+      x$lt_dlunknown|x*) $3 ;;
+    esac
+  else :
+    # compilation failed
+    $3
+  fi
+fi
+rm -fr conftest*
+])# _LT_TRY_DLOPEN_SELF
+
+
+# LT_SYS_DLOPEN_SELF
+# ------------------
+AC_DEFUN([LT_SYS_DLOPEN_SELF],
+[m4_require([_LT_HEADER_DLFCN])dnl
+if test yes != "$enable_dlopen"; then
+  enable_dlopen=unknown
+  enable_dlopen_self=unknown
+  enable_dlopen_self_static=unknown
+else
+  lt_cv_dlopen=no
+  lt_cv_dlopen_libs=
+
+  case $host_os in
+  beos*)
+    lt_cv_dlopen=load_add_on
+    lt_cv_dlopen_libs=
+    lt_cv_dlopen_self=yes
+    ;;
+
+  mingw* | pw32* | cegcc*)
+    lt_cv_dlopen=LoadLibrary
+    lt_cv_dlopen_libs=
+    ;;
+
+  cygwin*)
+    lt_cv_dlopen=dlopen
+    lt_cv_dlopen_libs=
+    ;;
+
+  darwin*)
+    # if libdl is installed we need to link against it
+    AC_CHECK_LIB([dl], [dlopen],
+		[lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl],[
+    lt_cv_dlopen=dyld
+    lt_cv_dlopen_libs=
+    lt_cv_dlopen_self=yes
+    ])
+    ;;
+
+  tpf*)
+    # Don't try to run any link tests for TPF.  We know it's impossible
+    # because TPF is a cross-compiler, and we know how we open DSOs.
+    lt_cv_dlopen=dlopen
+    lt_cv_dlopen_libs=
+    lt_cv_dlopen_self=no
+    ;;
+
+  *)
+    AC_CHECK_FUNC([shl_load],
+	  [lt_cv_dlopen=shl_load],
+      [AC_CHECK_LIB([dld], [shl_load],
+	    [lt_cv_dlopen=shl_load lt_cv_dlopen_libs=-ldld],
+	[AC_CHECK_FUNC([dlopen],
+	      [lt_cv_dlopen=dlopen],
+	  [AC_CHECK_LIB([dl], [dlopen],
+		[lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl],
+	    [AC_CHECK_LIB([svld], [dlopen],
+		  [lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-lsvld],
+	      [AC_CHECK_LIB([dld], [dld_link],
+		    [lt_cv_dlopen=dld_link lt_cv_dlopen_libs=-ldld])
+	      ])
+	    ])
+	  ])
+	])
+      ])
+    ;;
+  esac
+
+  if test no = "$lt_cv_dlopen"; then
+    enable_dlopen=no
+  else
+    enable_dlopen=yes
+  fi
+
+  case $lt_cv_dlopen in
+  dlopen)
+    save_CPPFLAGS=$CPPFLAGS
+    test yes = "$ac_cv_header_dlfcn_h" && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H"
+
+    save_LDFLAGS=$LDFLAGS
+    wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\"
+
+    save_LIBS=$LIBS
+    LIBS="$lt_cv_dlopen_libs $LIBS"
+
+    AC_CACHE_CHECK([whether a program can dlopen itself],
+	  lt_cv_dlopen_self, [dnl
+	  _LT_TRY_DLOPEN_SELF(
+	    lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes,
+	    lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross)
+    ])
+
+    if test yes = "$lt_cv_dlopen_self"; then
+      wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\"
+      AC_CACHE_CHECK([whether a statically linked program can dlopen itself],
+	  lt_cv_dlopen_self_static, [dnl
+	  _LT_TRY_DLOPEN_SELF(
+	    lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes,
+	    lt_cv_dlopen_self_static=no,  lt_cv_dlopen_self_static=cross)
+      ])
+    fi
+
+    CPPFLAGS=$save_CPPFLAGS
+    LDFLAGS=$save_LDFLAGS
+    LIBS=$save_LIBS
+    ;;
+  esac
+
+  case $lt_cv_dlopen_self in
+  yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;;
+  *) enable_dlopen_self=unknown ;;
+  esac
+
+  case $lt_cv_dlopen_self_static in
+  yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;;
+  *) enable_dlopen_self_static=unknown ;;
+  esac
+fi
+_LT_DECL([dlopen_support], [enable_dlopen], [0],
+	 [Whether dlopen is supported])
+_LT_DECL([dlopen_self], [enable_dlopen_self], [0],
+	 [Whether dlopen of programs is supported])
+_LT_DECL([dlopen_self_static], [enable_dlopen_self_static], [0],
+	 [Whether dlopen of statically linked programs is supported])
+])# LT_SYS_DLOPEN_SELF
+
+# Old name:
+AU_ALIAS([AC_LIBTOOL_DLOPEN_SELF], [LT_SYS_DLOPEN_SELF])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], [])
+
+
+# _LT_COMPILER_C_O([TAGNAME])
+# ---------------------------
+# Check to see if options -c and -o are simultaneously supported by compiler.
+# This macro does not hard code the compiler like AC_PROG_CC_C_O.
+m4_defun([_LT_COMPILER_C_O],
+[m4_require([_LT_DECL_SED])dnl
+m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_TAG_COMPILER])dnl
+AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext],
+  [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)],
+  [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no
+   $RM -r conftest 2>/dev/null
+   mkdir conftest
+   cd conftest
+   mkdir out
+   echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+   lt_compiler_flag="-o out/conftest2.$ac_objext"
+   # Insert the option either (1) after the last *FLAGS variable, or
+   # (2) before a word containing "conftest.", or (3) at the end.
+   # Note that $ac_compile itself does not contain backslashes and begins
+   # with a dollar sign (not a hyphen), so the echo should work correctly.
+   lt_compile=`echo "$ac_compile" | $SED \
+   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+   -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \
+   -e 's:$: $lt_compiler_flag:'`
+   (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD)
+   (eval "$lt_compile" 2>out/conftest.err)
+   ac_status=$?
+   cat out/conftest.err >&AS_MESSAGE_LOG_FD
+   echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD
+   if (exit $ac_status) && test -s out/conftest2.$ac_objext
+   then
+     # The compiler can only warn and ignore the option if not recognized
+     # So say no if there are warnings
+     $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp
+     $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
+     if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
+       _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes
+     fi
+   fi
+   chmod u+w . 2>&AS_MESSAGE_LOG_FD
+   $RM conftest*
+   # SGI C++ compiler will create directory out/ii_files/ for
+   # template instantiation
+   test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files
+   $RM out/* && rmdir out
+   cd ..
+   $RM -r conftest
+   $RM conftest*
+])
+_LT_TAGDECL([compiler_c_o], [lt_cv_prog_compiler_c_o], [1],
+	[Does compiler simultaneously support -c and -o options?])
+])# _LT_COMPILER_C_O
+
+
+# _LT_COMPILER_FILE_LOCKS([TAGNAME])
+# ----------------------------------
+# Check to see if we can do hard links to lock some files if needed
+m4_defun([_LT_COMPILER_FILE_LOCKS],
+[m4_require([_LT_ENABLE_LOCK])dnl
+m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+_LT_COMPILER_C_O([$1])
+
+hard_links=nottested
+if test no = "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" && test no != "$need_locks"; then
+  # do not overwrite the value of need_locks provided by the user
+  AC_MSG_CHECKING([if we can lock with hard links])
+  hard_links=yes
+  $RM conftest*
+  ln conftest.a conftest.b 2>/dev/null && hard_links=no
+  touch conftest.a
+  ln conftest.a conftest.b 2>&5 || hard_links=no
+  ln conftest.a conftest.b 2>/dev/null && hard_links=no
+  AC_MSG_RESULT([$hard_links])
+  if test no = "$hard_links"; then
+    AC_MSG_WARN(['$CC' does not support '-c -o', so 'make -j' may be unsafe])
+    need_locks=warn
+  fi
+else
+  need_locks=no
+fi
+_LT_DECL([], [need_locks], [1], [Must we lock files when doing compilation?])
+])# _LT_COMPILER_FILE_LOCKS
+
+
+# _LT_CHECK_OBJDIR
+# ----------------
+m4_defun([_LT_CHECK_OBJDIR],
+[AC_CACHE_CHECK([for objdir], [lt_cv_objdir],
+[rm -f .libs 2>/dev/null
+mkdir .libs 2>/dev/null
+if test -d .libs; then
+  lt_cv_objdir=.libs
+else
+  # MS-DOS does not allow filenames that begin with a dot.
+  lt_cv_objdir=_libs
+fi
+rmdir .libs 2>/dev/null])
+objdir=$lt_cv_objdir
+_LT_DECL([], [objdir], [0],
+         [The name of the directory that contains temporary libtool files])dnl
+m4_pattern_allow([LT_OBJDIR])dnl
+AC_DEFINE_UNQUOTED([LT_OBJDIR], "$lt_cv_objdir/",
+  [Define to the sub-directory where libtool stores uninstalled libraries.])
+])# _LT_CHECK_OBJDIR
+
+
+# _LT_LINKER_HARDCODE_LIBPATH([TAGNAME])
+# --------------------------------------
+# Check hardcoding attributes.
+m4_defun([_LT_LINKER_HARDCODE_LIBPATH],
+[AC_MSG_CHECKING([how to hardcode library paths into programs])
+_LT_TAGVAR(hardcode_action, $1)=
+if test -n "$_LT_TAGVAR(hardcode_libdir_flag_spec, $1)" ||
+   test -n "$_LT_TAGVAR(runpath_var, $1)" ||
+   test yes = "$_LT_TAGVAR(hardcode_automatic, $1)"; then
+
+  # We can hardcode non-existent directories.
+  if test no != "$_LT_TAGVAR(hardcode_direct, $1)" &&
+     # If the only mechanism to avoid hardcoding is shlibpath_var, we
+     # have to relink, otherwise we might link with an installed library
+     # when we should be linking with a yet-to-be-installed one
+     ## test no != "$_LT_TAGVAR(hardcode_shlibpath_var, $1)" &&
+     test no != "$_LT_TAGVAR(hardcode_minus_L, $1)"; then
+    # Linking always hardcodes the temporary library directory.
+    _LT_TAGVAR(hardcode_action, $1)=relink
+  else
+    # We can link without hardcoding, and we can hardcode nonexisting dirs.
+    _LT_TAGVAR(hardcode_action, $1)=immediate
+  fi
+else
+  # We cannot hardcode anything, or else we can only hardcode existing
+  # directories.
+  _LT_TAGVAR(hardcode_action, $1)=unsupported
+fi
+AC_MSG_RESULT([$_LT_TAGVAR(hardcode_action, $1)])
+
+if test relink = "$_LT_TAGVAR(hardcode_action, $1)" ||
+   test yes = "$_LT_TAGVAR(inherit_rpath, $1)"; then
+  # Fast installation is not supported
+  enable_fast_install=no
+elif test yes = "$shlibpath_overrides_runpath" ||
+     test no = "$enable_shared"; then
+  # Fast installation is not necessary
+  enable_fast_install=needless
+fi
+_LT_TAGDECL([], [hardcode_action], [0],
+    [How to hardcode a shared library path into an executable])
+])# _LT_LINKER_HARDCODE_LIBPATH
+
+
+# _LT_CMD_STRIPLIB
+# ----------------
+m4_defun([_LT_CMD_STRIPLIB],
+[m4_require([_LT_DECL_EGREP])
+striplib=
+old_striplib=
+AC_MSG_CHECKING([whether stripping libraries is possible])
+if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then
+  test -z "$old_striplib" && old_striplib="$STRIP --strip-debug"
+  test -z "$striplib" && striplib="$STRIP --strip-unneeded"
+  AC_MSG_RESULT([yes])
+else
+# FIXME - insert some real tests, host_os isn't really good enough
+  case $host_os in
+  darwin*)
+    if test -n "$STRIP"; then
+      striplib="$STRIP -x"
+      old_striplib="$STRIP -S"
+      AC_MSG_RESULT([yes])
+    else
+      AC_MSG_RESULT([no])
+    fi
+    ;;
+  *)
+    AC_MSG_RESULT([no])
+    ;;
+  esac
+fi
+_LT_DECL([], [old_striplib], [1], [Commands to strip libraries])
+_LT_DECL([], [striplib], [1])
+])# _LT_CMD_STRIPLIB
+
+
+# _LT_PREPARE_MUNGE_PATH_LIST
+# ---------------------------
+# Make sure func_munge_path_list() is defined correctly.
+m4_defun([_LT_PREPARE_MUNGE_PATH_LIST],
+[[# func_munge_path_list VARIABLE PATH
+# -----------------------------------
+# VARIABLE is name of variable containing _space_ separated list of
+# directories to be munged by the contents of PATH, which is string
+# having a format:
+# "DIR[:DIR]:"
+#       string "DIR[ DIR]" will be prepended to VARIABLE
+# ":DIR[:DIR]"
+#       string "DIR[ DIR]" will be appended to VARIABLE
+# "DIRP[:DIRP]::[DIRA:]DIRA"
+#       string "DIRP[ DIRP]" will be prepended to VARIABLE and string
+#       "DIRA[ DIRA]" will be appended to VARIABLE
+# "DIR[:DIR]"
+#       VARIABLE will be replaced by "DIR[ DIR]"
+func_munge_path_list ()
+{
+    case x@S|@2 in
+    x)
+        ;;
+    *:)
+        eval @S|@1=\"`$ECHO @S|@2 | $SED 's/:/ /g'` \@S|@@S|@1\"
+        ;;
+    x:*)
+        eval @S|@1=\"\@S|@@S|@1 `$ECHO @S|@2 | $SED 's/:/ /g'`\"
+        ;;
+    *::*)
+        eval @S|@1=\"\@S|@@S|@1\ `$ECHO @S|@2 | $SED -e 's/.*:://' -e 's/:/ /g'`\"
+        eval @S|@1=\"`$ECHO @S|@2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \@S|@@S|@1\"
+        ;;
+    *)
+        eval @S|@1=\"`$ECHO @S|@2 | $SED 's/:/ /g'`\"
+        ;;
+    esac
+}
+]])# _LT_PREPARE_PATH_LIST
+
+
+# _LT_SYS_DYNAMIC_LINKER([TAG])
+# -----------------------------
+# PORTME Fill in your ld.so characteristics
+m4_defun([_LT_SYS_DYNAMIC_LINKER],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+m4_require([_LT_DECL_EGREP])dnl
+m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_DECL_OBJDUMP])dnl
+m4_require([_LT_DECL_SED])dnl
+m4_require([_LT_CHECK_SHELL_FEATURES])dnl
+m4_require([_LT_PREPARE_MUNGE_PATH_LIST])dnl
+AC_MSG_CHECKING([dynamic linker characteristics])
+m4_if([$1],
+	[], [
+if test yes = "$GCC"; then
+  case $host_os in
+    darwin*) lt_awk_arg='/^libraries:/,/LR/' ;;
+    *) lt_awk_arg='/^libraries:/' ;;
+  esac
+  case $host_os in
+    mingw* | cegcc*) lt_sed_strip_eq='s|=\([[A-Za-z]]:\)|\1|g' ;;
+    *) lt_sed_strip_eq='s|=/|/|g' ;;
+  esac
+  lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq`
+  case $lt_search_path_spec in
+  *\;*)
+    # if the path contains ";" then we assume it to be the separator
+    # otherwise default to the standard path separator (i.e. ":") - it is
+    # assumed that no part of a normal pathname contains ";" but that should
+    # okay in the real world where ";" in dirpaths is itself problematic.
+    lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'`
+    ;;
+  *)
+    lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"`
+    ;;
+  esac
+  # Ok, now we have the path, separated by spaces, we can step through it
+  # and add multilib dir if necessary...
+  lt_tmp_lt_search_path_spec=
+  lt_multi_os_dir=/`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null`
+  # ...but if some path component already ends with the multilib dir we assume
+  # that all is fine and trust -print-search-dirs as is (GCC 4.2? or newer).
+  case "$lt_multi_os_dir; $lt_search_path_spec " in
+  "/; "* | "/.; "* | "/./; "* | *"$lt_multi_os_dir "* | *"$lt_multi_os_dir/ "*)
+    lt_multi_os_dir=
+    ;;
+  esac
+  for lt_sys_path in $lt_search_path_spec; do
+    if test -d "$lt_sys_path$lt_multi_os_dir"; then
+      lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path$lt_multi_os_dir"
+    elif test -n "$lt_multi_os_dir"; then
+      test -d "$lt_sys_path" && \
+	lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path"
+    fi
+  done
+  lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk '
+BEGIN {RS = " "; FS = "/|\n";} {
+  lt_foo = "";
+  lt_count = 0;
+  for (lt_i = NF; lt_i > 0; lt_i--) {
+    if ($lt_i != "" && $lt_i != ".") {
+      if ($lt_i == "..") {
+        lt_count++;
+      } else {
+        if (lt_count == 0) {
+          lt_foo = "/" $lt_i lt_foo;
+        } else {
+          lt_count--;
+        }
+      }
+    }
+  }
+  if (lt_foo != "") { lt_freq[[lt_foo]]++; }
+  if (lt_freq[[lt_foo]] == 1) { print lt_foo; }
+}'`
+  # AWK program above erroneously prepends '/' to C:/dos/paths
+  # for these hosts.
+  case $host_os in
+    mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\
+      $SED 's|/\([[A-Za-z]]:\)|\1|g'` ;;
+  esac
+  sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP`
+else
+  sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
+fi])
+library_names_spec=
+libname_spec='lib$name'
+soname_spec=
+shrext_cmds=.so
+postinstall_cmds=
+postuninstall_cmds=
+finish_cmds=
+finish_eval=
+shlibpath_var=
+shlibpath_overrides_runpath=unknown
+version_type=none
+dynamic_linker="$host_os ld.so"
+sys_lib_dlsearch_path_spec="/lib /usr/lib"
+need_lib_prefix=unknown
+hardcode_into_libs=no
+
+# when you set need_version to no, make sure it does not cause -set_version
+# flags to be left without arguments
+need_version=unknown
+
+AC_ARG_VAR([LT_SYS_LIBRARY_PATH],
+[User-defined run-time library search path.])
+
+case $host_os in
+aix3*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  library_names_spec='$libname$release$shared_ext$versuffix $libname.a'
+  shlibpath_var=LIBPATH
+
+  # AIX 3 has no versioning support, so we append a major version to the name.
+  soname_spec='$libname$release$shared_ext$major'
+  ;;
+
+aix[[4-9]]*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  need_lib_prefix=no
+  need_version=no
+  hardcode_into_libs=yes
+  if test ia64 = "$host_cpu"; then
+    # AIX 5 supports IA64
+    library_names_spec='$libname$release$shared_ext$major $libname$release$shared_ext$versuffix $libname$shared_ext'
+    shlibpath_var=LD_LIBRARY_PATH
+  else
+    # With GCC up to 2.95.x, collect2 would create an import file
+    # for dependence libraries.  The import file would start with
+    # the line '#! .'.  This would cause the generated library to
+    # depend on '.', always an invalid library.  This was fixed in
+    # development snapshots of GCC prior to 3.0.
+    case $host_os in
+      aix4 | aix4.[[01]] | aix4.[[01]].*)
+      if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)'
+	   echo ' yes '
+	   echo '#endif'; } | $CC -E - | $GREP yes > /dev/null; then
+	:
+      else
+	can_build_shared=no
+      fi
+      ;;
+    esac
+    # Using Import Files as archive members, it is possible to support
+    # filename-based versioning of shared library archives on AIX. While
+    # this would work for both with and without runtime linking, it will
+    # prevent static linking of such archives. So we do filename-based
+    # shared library versioning with .so extension only, which is used
+    # when both runtime linking and shared linking is enabled.
+    # Unfortunately, runtime linking may impact performance, so we do
+    # not want this to be the default eventually. Also, we use the
+    # versioned .so libs for executables only if there is the -brtl
+    # linker flag in LDFLAGS as well, or --with-aix-soname=svr4 only.
+    # To allow for filename-based versioning support, we need to create
+    # libNAME.so.V as an archive file, containing:
+    # *) an Import File, referring to the versioned filename of the
+    #    archive as well as the shared archive member, telling the
+    #    bitwidth (32 or 64) of that shared object, and providing the
+    #    list of exported symbols of that shared object, eventually
+    #    decorated with the 'weak' keyword
+    # *) the shared object with the F_LOADONLY flag set, to really avoid
+    #    it being seen by the linker.
+    # At run time we better use the real file rather than another symlink,
+    # but for link time we create the symlink libNAME.so -> libNAME.so.V
+
+    case $with_aix_soname,$aix_use_runtimelinking in
+    # AIX (on Power*) has no versioning support, so currently we cannot hardcode correct
+    # soname into executable. Probably we can add versioning support to
+    # collect2, so additional links can be useful in future.
+    aix,yes) # traditional libtool
+      dynamic_linker='AIX unversionable lib.so'
+      # If using run time linking (on AIX 4.2 or later) use lib<name>.so
+      # instead of lib<name>.a to let people know that these are not
+      # typical AIX shared libraries.
+      library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+      ;;
+    aix,no) # traditional AIX only
+      dynamic_linker='AIX lib.a[(]lib.so.V[)]'
+      # We preserve .a as extension for shared libraries through AIX4.2
+      # and later when we are not doing run time linking.
+      library_names_spec='$libname$release.a $libname.a'
+      soname_spec='$libname$release$shared_ext$major'
+      ;;
+    svr4,*) # full svr4 only
+      dynamic_linker="AIX lib.so.V[(]$shared_archive_member_spec.o[)]"
+      library_names_spec='$libname$release$shared_ext$major $libname$shared_ext'
+      # We do not specify a path in Import Files, so LIBPATH fires.
+      shlibpath_overrides_runpath=yes
+      ;;
+    *,yes) # both, prefer svr4
+      dynamic_linker="AIX lib.so.V[(]$shared_archive_member_spec.o[)], lib.a[(]lib.so.V[)]"
+      library_names_spec='$libname$release$shared_ext$major $libname$shared_ext'
+      # unpreferred sharedlib libNAME.a needs extra handling
+      postinstall_cmds='test -n "$linkname" || linkname="$realname"~func_stripname "" ".so" "$linkname"~$install_shared_prog "$dir/$func_stripname_result.$libext" "$destdir/$func_stripname_result.$libext"~test -z "$tstripme" || test -z "$striplib" || $striplib "$destdir/$func_stripname_result.$libext"'
+      postuninstall_cmds='for n in $library_names $old_library; do :; done~func_stripname "" ".so" "$n"~test "$func_stripname_result" = "$n" || func_append rmfiles " $odir/$func_stripname_result.$libext"'
+      # We do not specify a path in Import Files, so LIBPATH fires.
+      shlibpath_overrides_runpath=yes
+      ;;
+    *,no) # both, prefer aix
+      dynamic_linker="AIX lib.a[(]lib.so.V[)], lib.so.V[(]$shared_archive_member_spec.o[)]"
+      library_names_spec='$libname$release.a $libname.a'
+      soname_spec='$libname$release$shared_ext$major'
+      # unpreferred sharedlib libNAME.so.V and symlink libNAME.so need extra handling
+      postinstall_cmds='test -z "$dlname" || $install_shared_prog $dir/$dlname $destdir/$dlname~test -z "$tstripme" || test -z "$striplib" || $striplib $destdir/$dlname~test -n "$linkname" || linkname=$realname~func_stripname "" ".a" "$linkname"~(cd "$destdir" && $LN_S -f $dlname $func_stripname_result.so)'
+      postuninstall_cmds='test -z "$dlname" || func_append rmfiles " $odir/$dlname"~for n in $old_library $library_names; do :; done~func_stripname "" ".a" "$n"~func_append rmfiles " $odir/$func_stripname_result.so"'
+      ;;
+    esac
+    shlibpath_var=LIBPATH
+  fi
+  ;;
+
+amigaos*)
+  case $host_cpu in
+  powerpc)
+    # Since July 2007 AmigaOS4 officially supports .so libraries.
+    # When compiling the executable, add -use-dynld -Lsobjs: to the compileline.
+    library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+    ;;
+  m68k)
+    library_names_spec='$libname.ixlibrary $libname.a'
+    # Create ${libname}_ixlibrary.a entries in /sys/libs.
+    finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
+    ;;
+  esac
+  ;;
+
+beos*)
+  library_names_spec='$libname$shared_ext'
+  dynamic_linker="$host_os ld.so"
+  shlibpath_var=LIBRARY_PATH
+  ;;
+
+bsdi[[45]]*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  need_version=no
+  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+  soname_spec='$libname$release$shared_ext$major'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
+  sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib"
+  # the default ld.so.conf also contains /usr/contrib/lib and
+  # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow
+  # libtool to hard-code these into programs
+  ;;
+
+cygwin* | mingw* | pw32* | cegcc*)
+  version_type=windows
+  shrext_cmds=.dll
+  need_version=no
+  need_lib_prefix=no
+
+  case $GCC,$cc_basename in
+  yes,*)
+    # gcc
+    library_names_spec='$libname.dll.a'
+    # DLL is installed to $(libdir)/../bin by postinstall_cmds
+    postinstall_cmds='base_file=`basename \$file`~
+      dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~
+      dldir=$destdir/`dirname \$dlpath`~
+      test -d \$dldir || mkdir -p \$dldir~
+      $install_prog $dir/$dlname \$dldir/$dlname~
+      chmod a+x \$dldir/$dlname~
+      if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then
+        eval '\''$striplib \$dldir/$dlname'\'' || exit \$?;
+      fi'
+    postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+      dlpath=$dir/\$dldll~
+       $RM \$dlpath'
+    shlibpath_overrides_runpath=yes
+
+    case $host_os in
+    cygwin*)
+      # Cygwin DLLs use 'cyg' prefix rather than 'lib'
+      soname_spec='`echo $libname | sed -e 's/^lib/cyg/'``echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext'
+m4_if([$1], [],[
+      sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"])
+      ;;
+    mingw* | cegcc*)
+      # MinGW DLLs use traditional 'lib' prefix
+      soname_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext'
+      ;;
+    pw32*)
+      # pw32 DLLs use 'pw' prefix rather than 'lib'
+      library_names_spec='`echo $libname | sed -e 's/^lib/pw/'``echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext'
+      ;;
+    esac
+    dynamic_linker='Win32 ld.exe'
+    ;;
+
+  *,cl*)
+    # Native MSVC
+    libname_spec='$name'
+    soname_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext'
+    library_names_spec='$libname.dll.lib'
+
+    case $build_os in
+    mingw*)
+      sys_lib_search_path_spec=
+      lt_save_ifs=$IFS
+      IFS=';'
+      for lt_path in $LIB
+      do
+        IFS=$lt_save_ifs
+        # Let DOS variable expansion print the short 8.3 style file name.
+        lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"`
+        sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path"
+      done
+      IFS=$lt_save_ifs
+      # Convert to MSYS style.
+      sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([[a-zA-Z]]\\):| /\\1|g' -e 's|^ ||'`
+      ;;
+    cygwin*)
+      # Convert to unix form, then to dos form, then back to unix form
+      # but this time dos style (no spaces!) so that the unix form looks
+      # like /cygdrive/c/PROGRA~1:/cygdr...
+      sys_lib_search_path_spec=`cygpath --path --unix "$LIB"`
+      sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null`
+      sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
+      ;;
+    *)
+      sys_lib_search_path_spec=$LIB
+      if $ECHO "$sys_lib_search_path_spec" | [$GREP ';[c-zC-Z]:/' >/dev/null]; then
+        # It is most probably a Windows format PATH.
+        sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
+      else
+        sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
+      fi
+      # FIXME: find the short name or the path components, as spaces are
+      # common. (e.g. "Program Files" -> "PROGRA~1")
+      ;;
+    esac
+
+    # DLL is installed to $(libdir)/../bin by postinstall_cmds
+    postinstall_cmds='base_file=`basename \$file`~
+      dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~
+      dldir=$destdir/`dirname \$dlpath`~
+      test -d \$dldir || mkdir -p \$dldir~
+      $install_prog $dir/$dlname \$dldir/$dlname'
+    postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+      dlpath=$dir/\$dldll~
+       $RM \$dlpath'
+    shlibpath_overrides_runpath=yes
+    dynamic_linker='Win32 link.exe'
+    ;;
+
+  *)
+    # Assume MSVC wrapper
+    library_names_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext $libname.lib'
+    dynamic_linker='Win32 ld.exe'
+    ;;
+  esac
+  # FIXME: first we should search . and the directory the executable is in
+  shlibpath_var=PATH
+  ;;
+
+darwin* | rhapsody*)
+  dynamic_linker="$host_os dyld"
+  version_type=darwin
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='$libname$release$major$shared_ext $libname$shared_ext'
+  soname_spec='$libname$release$major$shared_ext'
+  shlibpath_overrides_runpath=yes
+  shlibpath_var=DYLD_LIBRARY_PATH
+  shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`'
+m4_if([$1], [],[
+  sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"])
+  sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib'
+  ;;
+
+dgux*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+  soname_spec='$libname$release$shared_ext$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+freebsd* | dragonfly*)
+  # DragonFly does not have aout.  When/if they implement a new
+  # versioning mechanism, adjust this.
+  if test -x /usr/bin/objformat; then
+    objformat=`/usr/bin/objformat`
+  else
+    case $host_os in
+    freebsd[[23]].*) objformat=aout ;;
+    *) objformat=elf ;;
+    esac
+  fi
+  version_type=freebsd-$objformat
+  case $version_type in
+    freebsd-elf*)
+      library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+      soname_spec='$libname$release$shared_ext$major'
+      need_version=no
+      need_lib_prefix=no
+      ;;
+    freebsd-*)
+      library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'
+      need_version=yes
+      ;;
+  esac
+  shlibpath_var=LD_LIBRARY_PATH
+  case $host_os in
+  freebsd2.*)
+    shlibpath_overrides_runpath=yes
+    ;;
+  freebsd3.[[01]]* | freebsdelf3.[[01]]*)
+    shlibpath_overrides_runpath=yes
+    hardcode_into_libs=yes
+    ;;
+  freebsd3.[[2-9]]* | freebsdelf3.[[2-9]]* | \
+  freebsd4.[[0-5]] | freebsdelf4.[[0-5]] | freebsd4.1.1 | freebsdelf4.1.1)
+    shlibpath_overrides_runpath=no
+    hardcode_into_libs=yes
+    ;;
+  *) # from 4.6 on, and DragonFly
+    shlibpath_overrides_runpath=yes
+    hardcode_into_libs=yes
+    ;;
+  esac
+  ;;
+
+haiku*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  need_lib_prefix=no
+  need_version=no
+  dynamic_linker="$host_os runtime_loader"
+  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+  soname_spec='$libname$release$shared_ext$major'
+  shlibpath_var=LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib'
+  hardcode_into_libs=yes
+  ;;
+
+hpux9* | hpux10* | hpux11*)
+  # Give a soname corresponding to the major version so that dld.sl refuses to
+  # link against other versions.
+  version_type=sunos
+  need_lib_prefix=no
+  need_version=no
+  case $host_cpu in
+  ia64*)
+    shrext_cmds='.so'
+    hardcode_into_libs=yes
+    dynamic_linker="$host_os dld.so"
+    shlibpath_var=LD_LIBRARY_PATH
+    shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+    library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+    soname_spec='$libname$release$shared_ext$major'
+    if test 32 = "$HPUX_IA64_MODE"; then
+      sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib"
+      sys_lib_dlsearch_path_spec=/usr/lib/hpux32
+    else
+      sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64"
+      sys_lib_dlsearch_path_spec=/usr/lib/hpux64
+    fi
+    ;;
+  hppa*64*)
+    shrext_cmds='.sl'
+    hardcode_into_libs=yes
+    dynamic_linker="$host_os dld.sl"
+    shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH
+    shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+    library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+    soname_spec='$libname$release$shared_ext$major'
+    sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64"
+    sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+    ;;
+  *)
+    shrext_cmds='.sl'
+    dynamic_linker="$host_os dld.sl"
+    shlibpath_var=SHLIB_PATH
+    shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
+    library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+    soname_spec='$libname$release$shared_ext$major'
+    ;;
+  esac
+  # HP-UX runs *really* slowly unless shared libraries are mode 555, ...
+  postinstall_cmds='chmod 555 $lib'
+  # or fails outright, so override atomically:
+  install_override_mode=555
+  ;;
+
+interix[[3-9]]*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+  soname_spec='$libname$release$shared_ext$major'
+  dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  ;;
+
+irix5* | irix6* | nonstopux*)
+  case $host_os in
+    nonstopux*) version_type=nonstopux ;;
+    *)
+	if test yes = "$lt_cv_prog_gnu_ld"; then
+		version_type=linux # correct to gnu/linux during the next big refactor
+	else
+		version_type=irix
+	fi ;;
+  esac
+  need_lib_prefix=no
+  need_version=no
+  soname_spec='$libname$release$shared_ext$major'
+  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$release$shared_ext $libname$shared_ext'
+  case $host_os in
+  irix5* | nonstopux*)
+    libsuff= shlibsuff=
+    ;;
+  *)
+    case $LD in # libtool.m4 will add one of these switches to LD
+    *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ")
+      libsuff= shlibsuff= libmagic=32-bit;;
+    *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ")
+      libsuff=32 shlibsuff=N32 libmagic=N32;;
+    *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ")
+      libsuff=64 shlibsuff=64 libmagic=64-bit;;
+    *) libsuff= shlibsuff= libmagic=never-match;;
+    esac
+    ;;
+  esac
+  shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
+  shlibpath_overrides_runpath=no
+  sys_lib_search_path_spec="/usr/lib$libsuff /lib$libsuff /usr/local/lib$libsuff"
+  sys_lib_dlsearch_path_spec="/usr/lib$libsuff /lib$libsuff"
+  hardcode_into_libs=yes
+  ;;
+
+# No shared lib support for Linux oldld, aout, or coff.
+linux*oldld* | linux*aout* | linux*coff*)
+  dynamic_linker=no
+  ;;
+
+linux*android*)
+  version_type=none # Android doesn't support versioned libraries.
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='$libname$release$shared_ext'
+  soname_spec='$libname$release$shared_ext'
+  finish_cmds=
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+
+  # This implies no fast_install, which is unacceptable.
+  # Some rework will be needed to allow for fast_install
+  # before this can be enabled.
+  hardcode_into_libs=yes
+
+  dynamic_linker='Android linker'
+  # Don't embed -rpath directories since the linker doesn't support them.
+  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+  ;;
+
+# This must be glibc/ELF.
+linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+  soname_spec='$libname$release$shared_ext$major'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+
+  # Some binutils ld are patched to set DT_RUNPATH
+  AC_CACHE_VAL([lt_cv_shlibpath_overrides_runpath],
+    [lt_cv_shlibpath_overrides_runpath=no
+    save_LDFLAGS=$LDFLAGS
+    save_libdir=$libdir
+    eval "libdir=/foo; wl=\"$_LT_TAGVAR(lt_prog_compiler_wl, $1)\"; \
+	 LDFLAGS=\"\$LDFLAGS $_LT_TAGVAR(hardcode_libdir_flag_spec, $1)\""
+    AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])],
+      [AS_IF([ ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null],
+	 [lt_cv_shlibpath_overrides_runpath=yes])])
+    LDFLAGS=$save_LDFLAGS
+    libdir=$save_libdir
+    ])
+  shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath
+
+  # This implies no fast_install, which is unacceptable.
+  # Some rework will be needed to allow for fast_install
+  # before this can be enabled.
+  hardcode_into_libs=yes
+
+  # Ideally, we could use ldconfig to report *all* directores which are
+  # searched for libraries, however this is still not possible.  Aside from not
+  # being certain /sbin/ldconfig is available, command
+  # 'ldconfig -N -X -v | grep ^/' on 64bit Fedora does not report /usr/lib64,
+  # even though it is searched at run-time.  Try to do the best guess by
+  # appending ld.so.conf contents (and includes) to the search path.
+  if test -f /etc/ld.so.conf; then
+    lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[	 ]*hwcap[	 ]/d;s/[:,	]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '`
+    sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra"
+  fi
+
+  # We used to test for /lib/ld.so.1 and disable shared libraries on
+  # powerpc, because MkLinux only supported shared libraries with the
+  # GNU dynamic linker.  Since this was broken with cross compilers,
+  # most powerpc-linux boxes support dynamic linking these days and
+  # people can always --disable-shared, the test was removed, and we
+  # assume the GNU/Linux dynamic linker is in use.
+  dynamic_linker='GNU/Linux ld.so'
+  ;;
+
+netbsdelf*-gnu)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  dynamic_linker='NetBSD ld.elf_so'
+  ;;
+
+netbsd*)
+  version_type=sunos
+  need_lib_prefix=no
+  need_version=no
+  if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+    library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'
+    finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+    dynamic_linker='NetBSD (a.out) ld.so'
+  else
+    library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+    soname_spec='$libname$release$shared_ext$major'
+    dynamic_linker='NetBSD ld.elf_so'
+  fi
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  hardcode_into_libs=yes
+  ;;
+
+newsos6)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  ;;
+
+*nto* | *qnx*)
+  version_type=qnx
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+  soname_spec='$libname$release$shared_ext$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  dynamic_linker='ldqnx.so'
+  ;;
+
+openbsd* | bitrig*)
+  version_type=sunos
+  sys_lib_dlsearch_path_spec=/usr/lib
+  need_lib_prefix=no
+  if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then
+    need_version=no
+  else
+    need_version=yes
+  fi
+  library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  ;;
+
+os2*)
+  libname_spec='$name'
+  version_type=windows
+  shrext_cmds=.dll
+  need_version=no
+  need_lib_prefix=no
+  # OS/2 can only load a DLL with a base name of 8 characters or less.
+  soname_spec='`test -n "$os2dllname" && libname="$os2dllname";
+    v=$($ECHO $release$versuffix | tr -d .-);
+    n=$($ECHO $libname | cut -b -$((8 - ${#v})) | tr . _);
+    $ECHO $n$v`$shared_ext'
+  library_names_spec='${libname}_dll.$libext'
+  dynamic_linker='OS/2 ld.exe'
+  shlibpath_var=BEGINLIBPATH
+  sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
+  sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+  postinstall_cmds='base_file=`basename \$file`~
+    dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; $ECHO \$dlname'\''`~
+    dldir=$destdir/`dirname \$dlpath`~
+    test -d \$dldir || mkdir -p \$dldir~
+    $install_prog $dir/$dlname \$dldir/$dlname~
+    chmod a+x \$dldir/$dlname~
+    if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then
+      eval '\''$striplib \$dldir/$dlname'\'' || exit \$?;
+    fi'
+  postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; $ECHO \$dlname'\''`~
+    dlpath=$dir/\$dldll~
+    $RM \$dlpath'
+  ;;
+
+osf3* | osf4* | osf5*)
+  version_type=osf
+  need_lib_prefix=no
+  need_version=no
+  soname_spec='$libname$release$shared_ext$major'
+  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+  shlibpath_var=LD_LIBRARY_PATH
+  sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
+  sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+  ;;
+
+rdos*)
+  dynamic_linker=no
+  ;;
+
+solaris*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+  soname_spec='$libname$release$shared_ext$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  hardcode_into_libs=yes
+  # ldd complains unless libraries are executable
+  postinstall_cmds='chmod +x $lib'
+  ;;
+
+sunos4*)
+  version_type=sunos
+  library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'
+  finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  if test yes = "$with_gnu_ld"; then
+    need_lib_prefix=no
+  fi
+  need_version=yes
+  ;;
+
+sysv4 | sysv4.3*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+  soname_spec='$libname$release$shared_ext$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  case $host_vendor in
+    sni)
+      shlibpath_overrides_runpath=no
+      need_lib_prefix=no
+      runpath_var=LD_RUN_PATH
+      ;;
+    siemens)
+      need_lib_prefix=no
+      ;;
+    motorola)
+      need_lib_prefix=no
+      need_version=no
+      shlibpath_overrides_runpath=no
+      sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib'
+      ;;
+  esac
+  ;;
+
+sysv4*MP*)
+  if test -d /usr/nec; then
+    version_type=linux # correct to gnu/linux during the next big refactor
+    library_names_spec='$libname$shared_ext.$versuffix $libname$shared_ext.$major $libname$shared_ext'
+    soname_spec='$libname$shared_ext.$major'
+    shlibpath_var=LD_LIBRARY_PATH
+  fi
+  ;;
+
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+  version_type=sco
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext $libname$shared_ext'
+  soname_spec='$libname$release$shared_ext$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  hardcode_into_libs=yes
+  if test yes = "$with_gnu_ld"; then
+    sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib'
+  else
+    sys_lib_search_path_spec='/usr/ccs/lib /usr/lib'
+    case $host_os in
+      sco3.2v5*)
+        sys_lib_search_path_spec="$sys_lib_search_path_spec /lib"
+	;;
+    esac
+  fi
+  sys_lib_dlsearch_path_spec='/usr/lib'
+  ;;
+
+tpf*)
+  # TPF is a cross-target only.  Preferred cross-host = GNU/Linux.
+  version_type=linux # correct to gnu/linux during the next big refactor
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  ;;
+
+uts4*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+  soname_spec='$libname$release$shared_ext$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+*)
+  dynamic_linker=no
+  ;;
+esac
+AC_MSG_RESULT([$dynamic_linker])
+test no = "$dynamic_linker" && can_build_shared=no
+
+variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
+if test yes = "$GCC"; then
+  variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
+fi
+
+if test set = "${lt_cv_sys_lib_search_path_spec+set}"; then
+  sys_lib_search_path_spec=$lt_cv_sys_lib_search_path_spec
+fi
+
+if test set = "${lt_cv_sys_lib_dlsearch_path_spec+set}"; then
+  sys_lib_dlsearch_path_spec=$lt_cv_sys_lib_dlsearch_path_spec
+fi
+
+# remember unaugmented sys_lib_dlsearch_path content for libtool script decls...
+configure_time_dlsearch_path=$sys_lib_dlsearch_path_spec
+
+# ... but it needs LT_SYS_LIBRARY_PATH munging for other configure-time code
+func_munge_path_list sys_lib_dlsearch_path_spec "$LT_SYS_LIBRARY_PATH"
+
+# to be used as default LT_SYS_LIBRARY_PATH value in generated libtool
+configure_time_lt_sys_library_path=$LT_SYS_LIBRARY_PATH
+
+_LT_DECL([], [variables_saved_for_relink], [1],
+    [Variables whose values should be saved in libtool wrapper scripts and
+    restored at link time])
+_LT_DECL([], [need_lib_prefix], [0],
+    [Do we need the "lib" prefix for modules?])
+_LT_DECL([], [need_version], [0], [Do we need a version for libraries?])
+_LT_DECL([], [version_type], [0], [Library versioning type])
+_LT_DECL([], [runpath_var], [0],  [Shared library runtime path variable])
+_LT_DECL([], [shlibpath_var], [0],[Shared library path variable])
+_LT_DECL([], [shlibpath_overrides_runpath], [0],
+    [Is shlibpath searched before the hard-coded library search path?])
+_LT_DECL([], [libname_spec], [1], [Format of library name prefix])
+_LT_DECL([], [library_names_spec], [1],
+    [[List of archive names.  First name is the real one, the rest are links.
+    The last name is the one that the linker finds with -lNAME]])
+_LT_DECL([], [soname_spec], [1],
+    [[The coded name of the library, if different from the real name]])
+_LT_DECL([], [install_override_mode], [1],
+    [Permission mode override for installation of shared libraries])
+_LT_DECL([], [postinstall_cmds], [2],
+    [Command to use after installation of a shared archive])
+_LT_DECL([], [postuninstall_cmds], [2],
+    [Command to use after uninstallation of a shared archive])
+_LT_DECL([], [finish_cmds], [2],
+    [Commands used to finish a libtool library installation in a directory])
+_LT_DECL([], [finish_eval], [1],
+    [[As "finish_cmds", except a single script fragment to be evaled but
+    not shown]])
+_LT_DECL([], [hardcode_into_libs], [0],
+    [Whether we should hardcode library paths into libraries])
+_LT_DECL([], [sys_lib_search_path_spec], [2],
+    [Compile-time system search path for libraries])
+_LT_DECL([sys_lib_dlsearch_path_spec], [configure_time_dlsearch_path], [2],
+    [Detected run-time system search path for libraries])
+_LT_DECL([], [configure_time_lt_sys_library_path], [2],
+    [Explicit LT_SYS_LIBRARY_PATH set during ./configure time])
+])# _LT_SYS_DYNAMIC_LINKER
+
+
+# _LT_PATH_TOOL_PREFIX(TOOL)
+# --------------------------
+# find a file program that can recognize shared library
+AC_DEFUN([_LT_PATH_TOOL_PREFIX],
+[m4_require([_LT_DECL_EGREP])dnl
+AC_MSG_CHECKING([for $1])
+AC_CACHE_VAL(lt_cv_path_MAGIC_CMD,
+[case $MAGIC_CMD in
+[[\\/*] |  ?:[\\/]*])
+  lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path.
+  ;;
+*)
+  lt_save_MAGIC_CMD=$MAGIC_CMD
+  lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR
+dnl $ac_dummy forces splitting on constant user-supplied paths.
+dnl POSIX.2 word splitting is done only on the output of word expansions,
+dnl not every word.  This closes a longstanding sh security hole.
+  ac_dummy="m4_if([$2], , $PATH, [$2])"
+  for ac_dir in $ac_dummy; do
+    IFS=$lt_save_ifs
+    test -z "$ac_dir" && ac_dir=.
+    if test -f "$ac_dir/$1"; then
+      lt_cv_path_MAGIC_CMD=$ac_dir/"$1"
+      if test -n "$file_magic_test_file"; then
+	case $deplibs_check_method in
+	"file_magic "*)
+	  file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"`
+	  MAGIC_CMD=$lt_cv_path_MAGIC_CMD
+	  if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
+	    $EGREP "$file_magic_regex" > /dev/null; then
+	    :
+	  else
+	    cat <<_LT_EOF 1>&2
+
+*** Warning: the command libtool uses to detect shared libraries,
+*** $file_magic_cmd, produces output that libtool cannot recognize.
+*** The result is that libtool may fail to recognize shared libraries
+*** as such.  This will affect the creation of libtool libraries that
+*** depend on shared libraries, but programs linked with such libtool
+*** libraries will work regardless of this problem.  Nevertheless, you
+*** may want to report the problem to your system manager and/or to
+*** bug-libtool@gnu.org
+
+_LT_EOF
+	  fi ;;
+	esac
+      fi
+      break
+    fi
+  done
+  IFS=$lt_save_ifs
+  MAGIC_CMD=$lt_save_MAGIC_CMD
+  ;;
+esac])
+MAGIC_CMD=$lt_cv_path_MAGIC_CMD
+if test -n "$MAGIC_CMD"; then
+  AC_MSG_RESULT($MAGIC_CMD)
+else
+  AC_MSG_RESULT(no)
+fi
+_LT_DECL([], [MAGIC_CMD], [0],
+	 [Used to examine libraries when file_magic_cmd begins with "file"])dnl
+])# _LT_PATH_TOOL_PREFIX
+
+# Old name:
+AU_ALIAS([AC_PATH_TOOL_PREFIX], [_LT_PATH_TOOL_PREFIX])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_PATH_TOOL_PREFIX], [])
+
+
+# _LT_PATH_MAGIC
+# --------------
+# find a file program that can recognize a shared library
+m4_defun([_LT_PATH_MAGIC],
+[_LT_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH)
+if test -z "$lt_cv_path_MAGIC_CMD"; then
+  if test -n "$ac_tool_prefix"; then
+    _LT_PATH_TOOL_PREFIX(file, /usr/bin$PATH_SEPARATOR$PATH)
+  else
+    MAGIC_CMD=:
+  fi
+fi
+])# _LT_PATH_MAGIC
+
+
+# LT_PATH_LD
+# ----------
+# find the pathname to the GNU or non-GNU linker
+AC_DEFUN([LT_PATH_LD],
+[AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+m4_require([_LT_DECL_SED])dnl
+m4_require([_LT_DECL_EGREP])dnl
+m4_require([_LT_PROG_ECHO_BACKSLASH])dnl
+
+AC_ARG_WITH([gnu-ld],
+    [AS_HELP_STRING([--with-gnu-ld],
+	[assume the C compiler uses GNU ld @<:@default=no@:>@])],
+    [test no = "$withval" || with_gnu_ld=yes],
+    [with_gnu_ld=no])dnl
+
+ac_prog=ld
+if test yes = "$GCC"; then
+  # Check if gcc -print-prog-name=ld gives a path.
+  AC_MSG_CHECKING([for ld used by $CC])
+  case $host in
+  *-*-mingw*)
+    # gcc leaves a trailing carriage return, which upsets mingw
+    ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
+  *)
+    ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
+  esac
+  case $ac_prog in
+    # Accept absolute paths.
+    [[\\/]]* | ?:[[\\/]]*)
+      re_direlt='/[[^/]][[^/]]*/\.\./'
+      # Canonicalize the pathname of ld
+      ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'`
+      while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do
+	ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"`
+      done
+      test -z "$LD" && LD=$ac_prog
+      ;;
+  "")
+    # If it fails, then pretend we aren't using GCC.
+    ac_prog=ld
+    ;;
+  *)
+    # If it is relative, then search for the first ld in PATH.
+    with_gnu_ld=unknown
+    ;;
+  esac
+elif test yes = "$with_gnu_ld"; then
+  AC_MSG_CHECKING([for GNU ld])
+else
+  AC_MSG_CHECKING([for non-GNU ld])
+fi
+AC_CACHE_VAL(lt_cv_path_LD,
+[if test -z "$LD"; then
+  lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR
+  for ac_dir in $PATH; do
+    IFS=$lt_save_ifs
+    test -z "$ac_dir" && ac_dir=.
+    if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+      lt_cv_path_LD=$ac_dir/$ac_prog
+      # Check to see if the program is GNU ld.  I'd rather use --version,
+      # but apparently some variants of GNU ld only accept -v.
+      # Break only if it was the GNU/non-GNU ld that we prefer.
+      case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in
+      *GNU* | *'with BFD'*)
+	test no != "$with_gnu_ld" && break
+	;;
+      *)
+	test yes != "$with_gnu_ld" && break
+	;;
+      esac
+    fi
+  done
+  IFS=$lt_save_ifs
+else
+  lt_cv_path_LD=$LD # Let the user override the test with a path.
+fi])
+LD=$lt_cv_path_LD
+if test -n "$LD"; then
+  AC_MSG_RESULT($LD)
+else
+  AC_MSG_RESULT(no)
+fi
+test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH])
+_LT_PATH_LD_GNU
+AC_SUBST([LD])
+
+_LT_TAGDECL([], [LD], [1], [The linker used to build libraries])
+])# LT_PATH_LD
+
+# Old names:
+AU_ALIAS([AM_PROG_LD], [LT_PATH_LD])
+AU_ALIAS([AC_PROG_LD], [LT_PATH_LD])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AM_PROG_LD], [])
+dnl AC_DEFUN([AC_PROG_LD], [])
+
+
+# _LT_PATH_LD_GNU
+#- --------------
+m4_defun([_LT_PATH_LD_GNU],
+[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], lt_cv_prog_gnu_ld,
+[# I'd rather use --version here, but apparently some GNU lds only accept -v.
+case `$LD -v 2>&1 </dev/null` in
+*GNU* | *'with BFD'*)
+  lt_cv_prog_gnu_ld=yes
+  ;;
+*)
+  lt_cv_prog_gnu_ld=no
+  ;;
+esac])
+with_gnu_ld=$lt_cv_prog_gnu_ld
+])# _LT_PATH_LD_GNU
+
+
+# _LT_CMD_RELOAD
+# --------------
+# find reload flag for linker
+#   -- PORTME Some linkers may need a different reload flag.
+m4_defun([_LT_CMD_RELOAD],
+[AC_CACHE_CHECK([for $LD option to reload object files],
+  lt_cv_ld_reload_flag,
+  [lt_cv_ld_reload_flag='-r'])
+reload_flag=$lt_cv_ld_reload_flag
+case $reload_flag in
+"" | " "*) ;;
+*) reload_flag=" $reload_flag" ;;
+esac
+reload_cmds='$LD$reload_flag -o $output$reload_objs'
+case $host_os in
+  cygwin* | mingw* | pw32* | cegcc*)
+    if test yes != "$GCC"; then
+      reload_cmds=false
+    fi
+    ;;
+  darwin*)
+    if test yes = "$GCC"; then
+      reload_cmds='$LTCC $LTCFLAGS -nostdlib $wl-r -o $output$reload_objs'
+    else
+      reload_cmds='$LD$reload_flag -o $output$reload_objs'
+    fi
+    ;;
+esac
+_LT_TAGDECL([], [reload_flag], [1], [How to create reloadable object files])dnl
+_LT_TAGDECL([], [reload_cmds], [2])dnl
+])# _LT_CMD_RELOAD
+
+
+# _LT_PATH_DD
+# -----------
+# find a working dd
+m4_defun([_LT_PATH_DD],
+[AC_CACHE_CHECK([for a working dd], [ac_cv_path_lt_DD],
+[printf 0123456789abcdef0123456789abcdef >conftest.i
+cat conftest.i conftest.i >conftest2.i
+: ${lt_DD:=$DD}
+AC_PATH_PROGS_FEATURE_CHECK([lt_DD], [dd],
+[if "$ac_path_lt_DD" bs=32 count=1 <conftest2.i >conftest.out 2>/dev/null; then
+  cmp -s conftest.i conftest.out \
+  && ac_cv_path_lt_DD="$ac_path_lt_DD" ac_path_lt_DD_found=:
+fi])
+rm -f conftest.i conftest2.i conftest.out])
+])# _LT_PATH_DD
+
+
+# _LT_CMD_TRUNCATE
+# ----------------
+# find command to truncate a binary pipe
+m4_defun([_LT_CMD_TRUNCATE],
+[m4_require([_LT_PATH_DD])
+AC_CACHE_CHECK([how to truncate binary pipes], [lt_cv_truncate_bin],
+[printf 0123456789abcdef0123456789abcdef >conftest.i
+cat conftest.i conftest.i >conftest2.i
+lt_cv_truncate_bin=
+if "$ac_cv_path_lt_DD" bs=32 count=1 <conftest2.i >conftest.out 2>/dev/null; then
+  cmp -s conftest.i conftest.out \
+  && lt_cv_truncate_bin="$ac_cv_path_lt_DD bs=4096 count=1"
+fi
+rm -f conftest.i conftest2.i conftest.out
+test -z "$lt_cv_truncate_bin" && lt_cv_truncate_bin="$SED -e 4q"])
+_LT_DECL([lt_truncate_bin], [lt_cv_truncate_bin], [1],
+  [Command to truncate a binary pipe])
+])# _LT_CMD_TRUNCATE
+
+
+# _LT_CHECK_MAGIC_METHOD
+# ----------------------
+# how to check for library dependencies
+#  -- PORTME fill in with the dynamic library characteristics
+m4_defun([_LT_CHECK_MAGIC_METHOD],
+[m4_require([_LT_DECL_EGREP])
+m4_require([_LT_DECL_OBJDUMP])
+AC_CACHE_CHECK([how to recognize dependent libraries],
+lt_cv_deplibs_check_method,
+[lt_cv_file_magic_cmd='$MAGIC_CMD'
+lt_cv_file_magic_test_file=
+lt_cv_deplibs_check_method='unknown'
+# Need to set the preceding variable on all platforms that support
+# interlibrary dependencies.
+# 'none' -- dependencies not supported.
+# 'unknown' -- same as none, but documents that we really don't know.
+# 'pass_all' -- all dependencies passed with no checks.
+# 'test_compile' -- check by making test program.
+# 'file_magic [[regex]]' -- check by looking for files in library path
+# that responds to the $file_magic_cmd with a given extended regex.
+# If you have 'file' or equivalent on your system and you're not sure
+# whether 'pass_all' will *always* work, you probably want this one.
+
+case $host_os in
+aix[[4-9]]*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+beos*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+bsdi[[45]]*)
+  lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib)'
+  lt_cv_file_magic_cmd='/usr/bin/file -L'
+  lt_cv_file_magic_test_file=/shlib/libc.so
+  ;;
+
+cygwin*)
+  # func_win32_libid is a shell function defined in ltmain.sh
+  lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
+  lt_cv_file_magic_cmd='func_win32_libid'
+  ;;
+
+mingw* | pw32*)
+  # Base MSYS/MinGW do not provide the 'file' command needed by
+  # func_win32_libid shell function, so use a weaker test based on 'objdump',
+  # unless we find 'file', for example because we are cross-compiling.
+  if ( file / ) >/dev/null 2>&1; then
+    lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
+    lt_cv_file_magic_cmd='func_win32_libid'
+  else
+    # Keep this pattern in sync with the one in func_win32_libid.
+    lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)'
+    lt_cv_file_magic_cmd='$OBJDUMP -f'
+  fi
+  ;;
+
+cegcc*)
+  # use the weaker test based on 'objdump'. See mingw*.
+  lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?'
+  lt_cv_file_magic_cmd='$OBJDUMP -f'
+  ;;
+
+darwin* | rhapsody*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+freebsd* | dragonfly*)
+  if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
+    case $host_cpu in
+    i*86 )
+      # Not sure whether the presence of OpenBSD here was a mistake.
+      # Let's accept both of them until this is cleared up.
+      lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[[3-9]]86 (compact )?demand paged shared library'
+      lt_cv_file_magic_cmd=/usr/bin/file
+      lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*`
+      ;;
+    esac
+  else
+    lt_cv_deplibs_check_method=pass_all
+  fi
+  ;;
+
+haiku*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+hpux10.20* | hpux11*)
+  lt_cv_file_magic_cmd=/usr/bin/file
+  case $host_cpu in
+  ia64*)
+    lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64'
+    lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so
+    ;;
+  hppa*64*)
+    [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]']
+    lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl
+    ;;
+  *)
+    lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]]\.[[0-9]]) shared library'
+    lt_cv_file_magic_test_file=/usr/lib/libc.sl
+    ;;
+  esac
+  ;;
+
+interix[[3-9]]*)
+  # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here
+  lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|\.a)$'
+  ;;
+
+irix5* | irix6* | nonstopux*)
+  case $LD in
+  *-32|*"-32 ") libmagic=32-bit;;
+  *-n32|*"-n32 ") libmagic=N32;;
+  *-64|*"-64 ") libmagic=64-bit;;
+  *) libmagic=never-match;;
+  esac
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+# This must be glibc/ELF.
+linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+netbsd* | netbsdelf*-gnu)
+  if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
+    lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$'
+  else
+    lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|_pic\.a)$'
+  fi
+  ;;
+
+newos6*)
+  lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)'
+  lt_cv_file_magic_cmd=/usr/bin/file
+  lt_cv_file_magic_test_file=/usr/lib/libnls.so
+  ;;
+
+*nto* | *qnx*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+openbsd* | bitrig*)
+  if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then
+    lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|\.so|_pic\.a)$'
+  else
+    lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$'
+  fi
+  ;;
+
+osf3* | osf4* | osf5*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+rdos*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+solaris*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+sysv4 | sysv4.3*)
+  case $host_vendor in
+  motorola)
+    lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]'
+    lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*`
+    ;;
+  ncr)
+    lt_cv_deplibs_check_method=pass_all
+    ;;
+  sequent)
+    lt_cv_file_magic_cmd='/bin/file'
+    lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )'
+    ;;
+  sni)
+    lt_cv_file_magic_cmd='/bin/file'
+    lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib"
+    lt_cv_file_magic_test_file=/lib/libc.so
+    ;;
+  siemens)
+    lt_cv_deplibs_check_method=pass_all
+    ;;
+  pc)
+    lt_cv_deplibs_check_method=pass_all
+    ;;
+  esac
+  ;;
+
+tpf*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+os2*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+esac
+])
+
+file_magic_glob=
+want_nocaseglob=no
+if test "$build" = "$host"; then
+  case $host_os in
+  mingw* | pw32*)
+    if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then
+      want_nocaseglob=yes
+    else
+      file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[[\1]]\/[[\1]]\/g;/g"`
+    fi
+    ;;
+  esac
+fi
+
+file_magic_cmd=$lt_cv_file_magic_cmd
+deplibs_check_method=$lt_cv_deplibs_check_method
+test -z "$deplibs_check_method" && deplibs_check_method=unknown
+
+_LT_DECL([], [deplibs_check_method], [1],
+    [Method to check whether dependent libraries are shared objects])
+_LT_DECL([], [file_magic_cmd], [1],
+    [Command to use when deplibs_check_method = "file_magic"])
+_LT_DECL([], [file_magic_glob], [1],
+    [How to find potential files when deplibs_check_method = "file_magic"])
+_LT_DECL([], [want_nocaseglob], [1],
+    [Find potential files using nocaseglob when deplibs_check_method = "file_magic"])
+])# _LT_CHECK_MAGIC_METHOD
+
+
+# LT_PATH_NM
+# ----------
+# find the pathname to a BSD- or MS-compatible name lister
+AC_DEFUN([LT_PATH_NM],
+[AC_REQUIRE([AC_PROG_CC])dnl
+AC_CACHE_CHECK([for BSD- or MS-compatible name lister (nm)], lt_cv_path_NM,
+[if test -n "$NM"; then
+  # Let the user override the test.
+  lt_cv_path_NM=$NM
+else
+  lt_nm_to_check=${ac_tool_prefix}nm
+  if test -n "$ac_tool_prefix" && test "$build" = "$host"; then
+    lt_nm_to_check="$lt_nm_to_check nm"
+  fi
+  for lt_tmp_nm in $lt_nm_to_check; do
+    lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR
+    for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do
+      IFS=$lt_save_ifs
+      test -z "$ac_dir" && ac_dir=.
+      tmp_nm=$ac_dir/$lt_tmp_nm
+      if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext"; then
+	# Check to see if the nm accepts a BSD-compat flag.
+	# Adding the 'sed 1q' prevents false positives on HP-UX, which says:
+	#   nm: unknown option "B" ignored
+	# Tru64's nm complains that /dev/null is an invalid object file
+	# MSYS converts /dev/null to NUL, MinGW nm treats NUL as empty
+	case $build_os in
+	mingw*) lt_bad_file=conftest.nm/nofile ;;
+	*) lt_bad_file=/dev/null ;;
+	esac
+	case `"$tmp_nm" -B $lt_bad_file 2>&1 | sed '1q'` in
+	*$lt_bad_file* | *'Invalid file or object type'*)
+	  lt_cv_path_NM="$tmp_nm -B"
+	  break 2
+	  ;;
+	*)
+	  case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in
+	  */dev/null*)
+	    lt_cv_path_NM="$tmp_nm -p"
+	    break 2
+	    ;;
+	  *)
+	    lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but
+	    continue # so that we can try to find one that supports BSD flags
+	    ;;
+	  esac
+	  ;;
+	esac
+      fi
+    done
+    IFS=$lt_save_ifs
+  done
+  : ${lt_cv_path_NM=no}
+fi])
+if test no != "$lt_cv_path_NM"; then
+  NM=$lt_cv_path_NM
+else
+  # Didn't find any BSD compatible name lister, look for dumpbin.
+  if test -n "$DUMPBIN"; then :
+    # Let the user override the test.
+  else
+    AC_CHECK_TOOLS(DUMPBIN, [dumpbin "link -dump"], :)
+    case `$DUMPBIN -symbols -headers /dev/null 2>&1 | sed '1q'` in
+    *COFF*)
+      DUMPBIN="$DUMPBIN -symbols -headers"
+      ;;
+    *)
+      DUMPBIN=:
+      ;;
+    esac
+  fi
+  AC_SUBST([DUMPBIN])
+  if test : != "$DUMPBIN"; then
+    NM=$DUMPBIN
+  fi
+fi
+test -z "$NM" && NM=nm
+AC_SUBST([NM])
+_LT_DECL([], [NM], [1], [A BSD- or MS-compatible name lister])dnl
+
+AC_CACHE_CHECK([the name lister ($NM) interface], [lt_cv_nm_interface],
+  [lt_cv_nm_interface="BSD nm"
+  echo "int some_variable = 0;" > conftest.$ac_ext
+  (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&AS_MESSAGE_LOG_FD)
+  (eval "$ac_compile" 2>conftest.err)
+  cat conftest.err >&AS_MESSAGE_LOG_FD
+  (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&AS_MESSAGE_LOG_FD)
+  (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out)
+  cat conftest.err >&AS_MESSAGE_LOG_FD
+  (eval echo "\"\$as_me:$LINENO: output\"" >&AS_MESSAGE_LOG_FD)
+  cat conftest.out >&AS_MESSAGE_LOG_FD
+  if $GREP 'External.*some_variable' conftest.out > /dev/null; then
+    lt_cv_nm_interface="MS dumpbin"
+  fi
+  rm -f conftest*])
+])# LT_PATH_NM
+
+# Old names:
+AU_ALIAS([AM_PROG_NM], [LT_PATH_NM])
+AU_ALIAS([AC_PROG_NM], [LT_PATH_NM])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AM_PROG_NM], [])
+dnl AC_DEFUN([AC_PROG_NM], [])
+
+# _LT_CHECK_SHAREDLIB_FROM_LINKLIB
+# --------------------------------
+# how to determine the name of the shared library
+# associated with a specific link library.
+#  -- PORTME fill in with the dynamic library characteristics
+m4_defun([_LT_CHECK_SHAREDLIB_FROM_LINKLIB],
+[m4_require([_LT_DECL_EGREP])
+m4_require([_LT_DECL_OBJDUMP])
+m4_require([_LT_DECL_DLLTOOL])
+AC_CACHE_CHECK([how to associate runtime and link libraries],
+lt_cv_sharedlib_from_linklib_cmd,
+[lt_cv_sharedlib_from_linklib_cmd='unknown'
+
+case $host_os in
+cygwin* | mingw* | pw32* | cegcc*)
+  # two different shell functions defined in ltmain.sh;
+  # decide which one to use based on capabilities of $DLLTOOL
+  case `$DLLTOOL --help 2>&1` in
+  *--identify-strict*)
+    lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib
+    ;;
+  *)
+    lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback
+    ;;
+  esac
+  ;;
+*)
+  # fallback: assume linklib IS sharedlib
+  lt_cv_sharedlib_from_linklib_cmd=$ECHO
+  ;;
+esac
+])
+sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd
+test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO
+
+_LT_DECL([], [sharedlib_from_linklib_cmd], [1],
+    [Command to associate shared and link libraries])
+])# _LT_CHECK_SHAREDLIB_FROM_LINKLIB
+
+
+# _LT_PATH_MANIFEST_TOOL
+# ----------------------
+# locate the manifest tool
+m4_defun([_LT_PATH_MANIFEST_TOOL],
+[AC_CHECK_TOOL(MANIFEST_TOOL, mt, :)
+test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt
+AC_CACHE_CHECK([if $MANIFEST_TOOL is a manifest tool], [lt_cv_path_mainfest_tool],
+  [lt_cv_path_mainfest_tool=no
+  echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&AS_MESSAGE_LOG_FD
+  $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out
+  cat conftest.err >&AS_MESSAGE_LOG_FD
+  if $GREP 'Manifest Tool' conftest.out > /dev/null; then
+    lt_cv_path_mainfest_tool=yes
+  fi
+  rm -f conftest*])
+if test yes != "$lt_cv_path_mainfest_tool"; then
+  MANIFEST_TOOL=:
+fi
+_LT_DECL([], [MANIFEST_TOOL], [1], [Manifest tool])dnl
+])# _LT_PATH_MANIFEST_TOOL
+
+
+# _LT_DLL_DEF_P([FILE])
+# ---------------------
+# True iff FILE is a Windows DLL '.def' file.
+# Keep in sync with func_dll_def_p in the libtool script
+AC_DEFUN([_LT_DLL_DEF_P],
+[dnl
+  test DEF = "`$SED -n dnl
+    -e '\''s/^[[	 ]]*//'\'' dnl Strip leading whitespace
+    -e '\''/^\(;.*\)*$/d'\'' dnl      Delete empty lines and comments
+    -e '\''s/^\(EXPORTS\|LIBRARY\)\([[	 ]].*\)*$/DEF/p'\'' dnl
+    -e q dnl                          Only consider the first "real" line
+    $1`" dnl
+])# _LT_DLL_DEF_P
+
+
+# LT_LIB_M
+# --------
+# check for math library
+AC_DEFUN([LT_LIB_M],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+LIBM=
+case $host in
+*-*-beos* | *-*-cegcc* | *-*-cygwin* | *-*-haiku* | *-*-pw32* | *-*-darwin*)
+  # These system don't have libm, or don't need it
+  ;;
+*-ncr-sysv4.3*)
+  AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM=-lmw)
+  AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm")
+  ;;
+*)
+  AC_CHECK_LIB(m, cos, LIBM=-lm)
+  ;;
+esac
+AC_SUBST([LIBM])
+])# LT_LIB_M
+
+# Old name:
+AU_ALIAS([AC_CHECK_LIBM], [LT_LIB_M])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_CHECK_LIBM], [])
+
+
+# _LT_COMPILER_NO_RTTI([TAGNAME])
+# -------------------------------
+m4_defun([_LT_COMPILER_NO_RTTI],
+[m4_require([_LT_TAG_COMPILER])dnl
+
+_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=
+
+if test yes = "$GCC"; then
+  case $cc_basename in
+  nvcc*)
+    _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -Xcompiler -fno-builtin' ;;
+  *)
+    _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' ;;
+  esac
+
+  _LT_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions],
+    lt_cv_prog_compiler_rtti_exceptions,
+    [-fno-rtti -fno-exceptions], [],
+    [_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)="$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) -fno-rtti -fno-exceptions"])
+fi
+_LT_TAGDECL([no_builtin_flag], [lt_prog_compiler_no_builtin_flag], [1],
+	[Compiler flag to turn off builtin functions])
+])# _LT_COMPILER_NO_RTTI
+
+
+# _LT_CMD_GLOBAL_SYMBOLS
+# ----------------------
+m4_defun([_LT_CMD_GLOBAL_SYMBOLS],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([AC_PROG_AWK])dnl
+AC_REQUIRE([LT_PATH_NM])dnl
+AC_REQUIRE([LT_PATH_LD])dnl
+m4_require([_LT_DECL_SED])dnl
+m4_require([_LT_DECL_EGREP])dnl
+m4_require([_LT_TAG_COMPILER])dnl
+
+# Check for command to grab the raw symbol name followed by C symbol from nm.
+AC_MSG_CHECKING([command to parse $NM output from $compiler object])
+AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe],
+[
+# These are sane defaults that work on at least a few old systems.
+# [They come from Ultrix.  What could be older than Ultrix?!! ;)]
+
+# Character class describing NM global symbol codes.
+symcode='[[BCDEGRST]]'
+
+# Regexp to match symbols that can be accessed directly from C.
+sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)'
+
+# Define system-specific variables.
+case $host_os in
+aix*)
+  symcode='[[BCDT]]'
+  ;;
+cygwin* | mingw* | pw32* | cegcc*)
+  symcode='[[ABCDGISTW]]'
+  ;;
+hpux*)
+  if test ia64 = "$host_cpu"; then
+    symcode='[[ABCDEGRST]]'
+  fi
+  ;;
+irix* | nonstopux*)
+  symcode='[[BCDEGRST]]'
+  ;;
+osf*)
+  symcode='[[BCDEGQRST]]'
+  ;;
+solaris*)
+  symcode='[[BDRT]]'
+  ;;
+sco3.2v5*)
+  symcode='[[DT]]'
+  ;;
+sysv4.2uw2*)
+  symcode='[[DT]]'
+  ;;
+sysv5* | sco5v6* | unixware* | OpenUNIX*)
+  symcode='[[ABDT]]'
+  ;;
+sysv4)
+  symcode='[[DFNSTU]]'
+  ;;
+esac
+
+# If we're using GNU nm, then use its standard symbol codes.
+case `$NM -V 2>&1` in
+*GNU* | *'with BFD'*)
+  symcode='[[ABCDGIRSTW]]' ;;
+esac
+
+if test "$lt_cv_nm_interface" = "MS dumpbin"; then
+  # Gets list of data symbols to import.
+  lt_cv_sys_global_symbol_to_import="sed -n -e 's/^I .* \(.*\)$/\1/p'"
+  # Adjust the below global symbol transforms to fixup imported variables.
+  lt_cdecl_hook=" -e 's/^I .* \(.*\)$/extern __declspec(dllimport) char \1;/p'"
+  lt_c_name_hook=" -e 's/^I .* \(.*\)$/  {\"\1\", (void *) 0},/p'"
+  lt_c_name_lib_hook="\
+  -e 's/^I .* \(lib.*\)$/  {\"\1\", (void *) 0},/p'\
+  -e 's/^I .* \(.*\)$/  {\"lib\1\", (void *) 0},/p'"
+else
+  # Disable hooks by default.
+  lt_cv_sys_global_symbol_to_import=
+  lt_cdecl_hook=
+  lt_c_name_hook=
+  lt_c_name_lib_hook=
+fi
+
+# Transform an extracted symbol line into a proper C declaration.
+# Some systems (esp. on ia64) link data and code symbols differently,
+# so use this general approach.
+lt_cv_sys_global_symbol_to_cdecl="sed -n"\
+$lt_cdecl_hook\
+" -e 's/^T .* \(.*\)$/extern int \1();/p'"\
+" -e 's/^$symcode$symcode* .* \(.*\)$/extern char \1;/p'"
+
+# Transform an extracted symbol line into symbol name and symbol address
+lt_cv_sys_global_symbol_to_c_name_address="sed -n"\
+$lt_c_name_hook\
+" -e 's/^: \(.*\) .*$/  {\"\1\", (void *) 0},/p'"\
+" -e 's/^$symcode$symcode* .* \(.*\)$/  {\"\1\", (void *) \&\1},/p'"
+
+# Transform an extracted symbol line into symbol name with lib prefix and
+# symbol address.
+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n"\
+$lt_c_name_lib_hook\
+" -e 's/^: \(.*\) .*$/  {\"\1\", (void *) 0},/p'"\
+" -e 's/^$symcode$symcode* .* \(lib.*\)$/  {\"\1\", (void *) \&\1},/p'"\
+" -e 's/^$symcode$symcode* .* \(.*\)$/  {\"lib\1\", (void *) \&\1},/p'"
+
+# Handle CRLF in mingw tool chain
+opt_cr=
+case $build_os in
+mingw*)
+  opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp
+  ;;
+esac
+
+# Try without a prefix underscore, then with it.
+for ac_symprfx in "" "_"; do
+
+  # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol.
+  symxfrm="\\1 $ac_symprfx\\2 \\2"
+
+  # Write the raw and C identifiers.
+  if test "$lt_cv_nm_interface" = "MS dumpbin"; then
+    # Fake it for dumpbin and say T for any non-static function,
+    # D for any global variable and I for any imported variable.
+    # Also find C++ and __fastcall symbols from MSVC++,
+    # which start with @ or ?.
+    lt_cv_sys_global_symbol_pipe="$AWK ['"\
+"     {last_section=section; section=\$ 3};"\
+"     /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\
+"     /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\
+"     /^ *Symbol name *: /{split(\$ 0,sn,\":\"); si=substr(sn[2],2)};"\
+"     /^ *Type *: code/{print \"T\",si,substr(si,length(prfx))};"\
+"     /^ *Type *: data/{print \"I\",si,substr(si,length(prfx))};"\
+"     \$ 0!~/External *\|/{next};"\
+"     / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\
+"     {if(hide[section]) next};"\
+"     {f=\"D\"}; \$ 0~/\(\).*\|/{f=\"T\"};"\
+"     {split(\$ 0,a,/\||\r/); split(a[2],s)};"\
+"     s[1]~/^[@?]/{print f,s[1],s[1]; next};"\
+"     s[1]~prfx {split(s[1],t,\"@\"); print f,t[1],substr(t[1],length(prfx))}"\
+"     ' prfx=^$ac_symprfx]"
+  else
+    lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[	 ]]\($symcode$symcode*\)[[	 ]][[	 ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'"
+  fi
+  lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'"
+
+  # Check to see that the pipe works correctly.
+  pipe_works=no
+
+  rm -f conftest*
+  cat > conftest.$ac_ext <<_LT_EOF
+#ifdef __cplusplus
+extern "C" {
+#endif
+char nm_test_var;
+void nm_test_func(void);
+void nm_test_func(void){}
+#ifdef __cplusplus
+}
+#endif
+int main(){nm_test_var='a';nm_test_func();return(0);}
+_LT_EOF
+
+  if AC_TRY_EVAL(ac_compile); then
+    # Now try to grab the symbols.
+    nlist=conftest.nm
+    if AC_TRY_EVAL(NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) && test -s "$nlist"; then
+      # Try sorting and uniquifying the output.
+      if sort "$nlist" | uniq > "$nlist"T; then
+	mv -f "$nlist"T "$nlist"
+      else
+	rm -f "$nlist"T
+      fi
+
+      # Make sure that we snagged all the symbols we need.
+      if $GREP ' nm_test_var$' "$nlist" >/dev/null; then
+	if $GREP ' nm_test_func$' "$nlist" >/dev/null; then
+	  cat <<_LT_EOF > conftest.$ac_ext
+/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests.  */
+#if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE
+/* DATA imports from DLLs on WIN32 can't be const, because runtime
+   relocations are performed -- see ld's documentation on pseudo-relocs.  */
+# define LT@&t@_DLSYM_CONST
+#elif defined __osf__
+/* This system does not cope well with relocations in const data.  */
+# define LT@&t@_DLSYM_CONST
+#else
+# define LT@&t@_DLSYM_CONST const
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+_LT_EOF
+	  # Now generate the symbol file.
+	  eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext'
+
+	  cat <<_LT_EOF >> conftest.$ac_ext
+
+/* The mapping between symbol names and symbols.  */
+LT@&t@_DLSYM_CONST struct {
+  const char *name;
+  void       *address;
+}
+lt__PROGRAM__LTX_preloaded_symbols[[]] =
+{
+  { "@PROGRAM@", (void *) 0 },
+_LT_EOF
+	  $SED "s/^$symcode$symcode* .* \(.*\)$/  {\"\1\", (void *) \&\1},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext
+	  cat <<\_LT_EOF >> conftest.$ac_ext
+  {0, (void *) 0}
+};
+
+/* This works around a problem in FreeBSD linker */
+#ifdef FREEBSD_WORKAROUND
+static const void *lt_preloaded_setup() {
+  return lt__PROGRAM__LTX_preloaded_symbols;
+}
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+_LT_EOF
+	  # Now try linking the two files.
+	  mv conftest.$ac_objext conftstm.$ac_objext
+	  lt_globsym_save_LIBS=$LIBS
+	  lt_globsym_save_CFLAGS=$CFLAGS
+	  LIBS=conftstm.$ac_objext
+	  CFLAGS="$CFLAGS$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)"
+	  if AC_TRY_EVAL(ac_link) && test -s conftest$ac_exeext; then
+	    pipe_works=yes
+	  fi
+	  LIBS=$lt_globsym_save_LIBS
+	  CFLAGS=$lt_globsym_save_CFLAGS
+	else
+	  echo "cannot find nm_test_func in $nlist" >&AS_MESSAGE_LOG_FD
+	fi
+      else
+	echo "cannot find nm_test_var in $nlist" >&AS_MESSAGE_LOG_FD
+      fi
+    else
+      echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD
+    fi
+  else
+    echo "$progname: failed program was:" >&AS_MESSAGE_LOG_FD
+    cat conftest.$ac_ext >&5
+  fi
+  rm -rf conftest* conftst*
+
+  # Do not use the global_symbol_pipe unless it works.
+  if test yes = "$pipe_works"; then
+    break
+  else
+    lt_cv_sys_global_symbol_pipe=
+  fi
+done
+])
+if test -z "$lt_cv_sys_global_symbol_pipe"; then
+  lt_cv_sys_global_symbol_to_cdecl=
+fi
+if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then
+  AC_MSG_RESULT(failed)
+else
+  AC_MSG_RESULT(ok)
+fi
+
+# Response file support.
+if test "$lt_cv_nm_interface" = "MS dumpbin"; then
+  nm_file_list_spec='@'
+elif $NM --help 2>/dev/null | grep '[[@]]FILE' >/dev/null; then
+  nm_file_list_spec='@'
+fi
+
+_LT_DECL([global_symbol_pipe], [lt_cv_sys_global_symbol_pipe], [1],
+    [Take the output of nm and produce a listing of raw symbols and C names])
+_LT_DECL([global_symbol_to_cdecl], [lt_cv_sys_global_symbol_to_cdecl], [1],
+    [Transform the output of nm in a proper C declaration])
+_LT_DECL([global_symbol_to_import], [lt_cv_sys_global_symbol_to_import], [1],
+    [Transform the output of nm into a list of symbols to manually relocate])
+_LT_DECL([global_symbol_to_c_name_address],
+    [lt_cv_sys_global_symbol_to_c_name_address], [1],
+    [Transform the output of nm in a C name address pair])
+_LT_DECL([global_symbol_to_c_name_address_lib_prefix],
+    [lt_cv_sys_global_symbol_to_c_name_address_lib_prefix], [1],
+    [Transform the output of nm in a C name address pair when lib prefix is needed])
+_LT_DECL([nm_interface], [lt_cv_nm_interface], [1],
+    [The name lister interface])
+_LT_DECL([], [nm_file_list_spec], [1],
+    [Specify filename containing input files for $NM])
+]) # _LT_CMD_GLOBAL_SYMBOLS
+
+
+# _LT_COMPILER_PIC([TAGNAME])
+# ---------------------------
+m4_defun([_LT_COMPILER_PIC],
+[m4_require([_LT_TAG_COMPILER])dnl
+_LT_TAGVAR(lt_prog_compiler_wl, $1)=
+_LT_TAGVAR(lt_prog_compiler_pic, $1)=
+_LT_TAGVAR(lt_prog_compiler_static, $1)=
+
+m4_if([$1], [CXX], [
+  # C++ specific cases for pic, static, wl, etc.
+  if test yes = "$GXX"; then
+    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+    _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+
+    case $host_os in
+    aix*)
+      # All AIX code is PIC.
+      if test ia64 = "$host_cpu"; then
+	# AIX 5 now supports IA64 processor
+	_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      fi
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+      ;;
+
+    amigaos*)
+      case $host_cpu in
+      powerpc)
+            # see comment about AmigaOS4 .so support
+            _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+        ;;
+      m68k)
+            # FIXME: we need at least 68020 code to build shared libraries, but
+            # adding the '-m68020' flag to GCC prevents building anything better,
+            # like '-m68040'.
+            _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4'
+        ;;
+      esac
+      ;;
+
+    beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
+      # PIC is the default for these OSes.
+      ;;
+    mingw* | cygwin* | os2* | pw32* | cegcc*)
+      # This hack is so that the source file can tell whether it is being
+      # built for inclusion in a dll (and should export symbols for example).
+      # Although the cygwin gcc ignores -fPIC, still need this for old-style
+      # (--disable-auto-import) libraries
+      m4_if([$1], [GCJ], [],
+	[_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])
+      case $host_os in
+      os2*)
+	_LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static'
+	;;
+      esac
+      ;;
+    darwin* | rhapsody*)
+      # PIC is the default on this platform
+      # Common symbols not allowed in MH_DYLIB files
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common'
+      ;;
+    *djgpp*)
+      # DJGPP does not support shared libraries at all
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)=
+      ;;
+    haiku*)
+      # PIC is the default for Haiku.
+      # The "-static" flag exists, but is broken.
+      _LT_TAGVAR(lt_prog_compiler_static, $1)=
+      ;;
+    interix[[3-9]]*)
+      # Interix 3.x gcc -fpic/-fPIC options generate broken code.
+      # Instead, we relocate shared libraries at runtime.
+      ;;
+    sysv4*MP*)
+      if test -d /usr/nec; then
+	_LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic
+      fi
+      ;;
+    hpux*)
+      # PIC is the default for 64-bit PA HP-UX, but not for 32-bit
+      # PA HP-UX.  On IA64 HP-UX, PIC is the default but the pic flag
+      # sets the default TLS model and affects inlining.
+      case $host_cpu in
+      hppa*64*)
+	;;
+      *)
+	_LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+	;;
+      esac
+      ;;
+    *qnx* | *nto*)
+      # QNX uses GNU C++, but need to define -shared option too, otherwise
+      # it will coredump.
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared'
+      ;;
+    *)
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+      ;;
+    esac
+  else
+    case $host_os in
+      aix[[4-9]]*)
+	# All AIX code is PIC.
+	if test ia64 = "$host_cpu"; then
+	  # AIX 5 now supports IA64 processor
+	  _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+	else
+	  _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp'
+	fi
+	;;
+      chorus*)
+	case $cc_basename in
+	cxch68*)
+	  # Green Hills C++ Compiler
+	  # _LT_TAGVAR(lt_prog_compiler_static, $1)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a"
+	  ;;
+	esac
+	;;
+      mingw* | cygwin* | os2* | pw32* | cegcc*)
+	# This hack is so that the source file can tell whether it is being
+	# built for inclusion in a dll (and should export symbols for example).
+	m4_if([$1], [GCJ], [],
+	  [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])
+	;;
+      dgux*)
+	case $cc_basename in
+	  ec++*)
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+	    ;;
+	  ghcx*)
+	    # Green Hills C++ Compiler
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      freebsd* | dragonfly*)
+	# FreeBSD uses GNU C++
+	;;
+      hpux9* | hpux10* | hpux11*)
+	case $cc_basename in
+	  CC*)
+	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive'
+	    if test ia64 != "$host_cpu"; then
+	      _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z'
+	    fi
+	    ;;
+	  aCC*)
+	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive'
+	    case $host_cpu in
+	    hppa*64*|ia64*)
+	      # +Z the default
+	      ;;
+	    *)
+	      _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z'
+	      ;;
+	    esac
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      interix*)
+	# This is c89, which is MS Visual C++ (no shared libs)
+	# Anyone wants to do a port?
+	;;
+      irix5* | irix6* | nonstopux*)
+	case $cc_basename in
+	  CC*)
+	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+	    # CC pic flag -KPIC is the default.
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
+	case $cc_basename in
+	  KCC*)
+	    # KAI C++ Compiler
+	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,'
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+	    ;;
+	  ecpc* )
+	    # old Intel C++ for x86_64, which still supported -KPIC.
+	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+	    ;;
+	  icpc* )
+	    # Intel C++, used to be incompatible with GCC.
+	    # ICC 10 doesn't accept -KPIC any more.
+	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+	    ;;
+	  pgCC* | pgcpp*)
+	    # Portland Group C++ compiler
+	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic'
+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+	    ;;
+	  cxx*)
+	    # Compaq C++
+	    # Make sure the PIC flag is empty.  It appears that all Alpha
+	    # Linux and Compaq Tru64 Unix objects are PIC.
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)=
+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+	    ;;
+	  xlc* | xlC* | bgxl[[cC]]* | mpixl[[cC]]*)
+	    # IBM XL 8.0, 9.0 on PPC and BlueGene
+	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic'
+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink'
+	    ;;
+	  *)
+	    case `$CC -V 2>&1 | sed 5q` in
+	    *Sun\ C*)
+	      # Sun C++ 5.9
+	      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+	      _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+	      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '
+	      ;;
+	    esac
+	    ;;
+	esac
+	;;
+      lynxos*)
+	;;
+      m88k*)
+	;;
+      mvs*)
+	case $cc_basename in
+	  cxx*)
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      netbsd* | netbsdelf*-gnu)
+	;;
+      *qnx* | *nto*)
+        # QNX uses GNU C++, but need to define -shared option too, otherwise
+        # it will coredump.
+        _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared'
+        ;;
+      osf3* | osf4* | osf5*)
+	case $cc_basename in
+	  KCC*)
+	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,'
+	    ;;
+	  RCC*)
+	    # Rational C++ 2.4.1
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+	    ;;
+	  cxx*)
+	    # Digital/Compaq C++
+	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	    # Make sure the PIC flag is empty.  It appears that all Alpha
+	    # Linux and Compaq Tru64 Unix objects are PIC.
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)=
+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      psos*)
+	;;
+      solaris*)
+	case $cc_basename in
+	  CC* | sunCC*)
+	    # Sun C++ 4.2, 5.x and Centerline C++
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '
+	    ;;
+	  gcx*)
+	    # Green Hills C++ Compiler
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      sunos4*)
+	case $cc_basename in
+	  CC*)
+	    # Sun C++ 4.x
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+	    ;;
+	  lcc*)
+	    # Lucid
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
+	case $cc_basename in
+	  CC*)
+	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+	    ;;
+	esac
+	;;
+      tandem*)
+	case $cc_basename in
+	  NCC*)
+	    # NonStop-UX NCC 3.20
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      vxworks*)
+	;;
+      *)
+	_LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
+	;;
+    esac
+  fi
+],
+[
+  if test yes = "$GCC"; then
+    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+    _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+
+    case $host_os in
+      aix*)
+      # All AIX code is PIC.
+      if test ia64 = "$host_cpu"; then
+	# AIX 5 now supports IA64 processor
+	_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      fi
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+      ;;
+
+    amigaos*)
+      case $host_cpu in
+      powerpc)
+            # see comment about AmigaOS4 .so support
+            _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+        ;;
+      m68k)
+            # FIXME: we need at least 68020 code to build shared libraries, but
+            # adding the '-m68020' flag to GCC prevents building anything better,
+            # like '-m68040'.
+            _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4'
+        ;;
+      esac
+      ;;
+
+    beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
+      # PIC is the default for these OSes.
+      ;;
+
+    mingw* | cygwin* | pw32* | os2* | cegcc*)
+      # This hack is so that the source file can tell whether it is being
+      # built for inclusion in a dll (and should export symbols for example).
+      # Although the cygwin gcc ignores -fPIC, still need this for old-style
+      # (--disable-auto-import) libraries
+      m4_if([$1], [GCJ], [],
+	[_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])
+      case $host_os in
+      os2*)
+	_LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static'
+	;;
+      esac
+      ;;
+
+    darwin* | rhapsody*)
+      # PIC is the default on this platform
+      # Common symbols not allowed in MH_DYLIB files
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common'
+      ;;
+
+    haiku*)
+      # PIC is the default for Haiku.
+      # The "-static" flag exists, but is broken.
+      _LT_TAGVAR(lt_prog_compiler_static, $1)=
+      ;;
+
+    hpux*)
+      # PIC is the default for 64-bit PA HP-UX, but not for 32-bit
+      # PA HP-UX.  On IA64 HP-UX, PIC is the default but the pic flag
+      # sets the default TLS model and affects inlining.
+      case $host_cpu in
+      hppa*64*)
+	# +Z the default
+	;;
+      *)
+	_LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+	;;
+      esac
+      ;;
+
+    interix[[3-9]]*)
+      # Interix 3.x gcc -fpic/-fPIC options generate broken code.
+      # Instead, we relocate shared libraries at runtime.
+      ;;
+
+    msdosdjgpp*)
+      # Just because we use GCC doesn't mean we suddenly get shared libraries
+      # on systems that don't support them.
+      _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
+      enable_shared=no
+      ;;
+
+    *nto* | *qnx*)
+      # QNX uses GNU C++, but need to define -shared option too, otherwise
+      # it will coredump.
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared'
+      ;;
+
+    sysv4*MP*)
+      if test -d /usr/nec; then
+	_LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic
+      fi
+      ;;
+
+    *)
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+      ;;
+    esac
+
+    case $cc_basename in
+    nvcc*) # Cuda Compiler Driver 2.2
+      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Xlinker '
+      if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then
+        _LT_TAGVAR(lt_prog_compiler_pic, $1)="-Xcompiler $_LT_TAGVAR(lt_prog_compiler_pic, $1)"
+      fi
+      ;;
+    esac
+  else
+    # PORTME Check for flag to pass linker flags through the system compiler.
+    case $host_os in
+    aix*)
+      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+      if test ia64 = "$host_cpu"; then
+	# AIX 5 now supports IA64 processor
+	_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      else
+	_LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp'
+      fi
+      ;;
+
+    darwin* | rhapsody*)
+      # PIC is the default on this platform
+      # Common symbols not allowed in MH_DYLIB files
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common'
+      case $cc_basename in
+      nagfor*)
+        # NAG Fortran compiler
+        _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,'
+        _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC'
+        _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+        ;;
+      esac
+      ;;
+
+    mingw* | cygwin* | pw32* | os2* | cegcc*)
+      # This hack is so that the source file can tell whether it is being
+      # built for inclusion in a dll (and should export symbols for example).
+      m4_if([$1], [GCJ], [],
+	[_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])
+      case $host_os in
+      os2*)
+	_LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static'
+	;;
+      esac
+      ;;
+
+    hpux9* | hpux10* | hpux11*)
+      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+      # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
+      # not for PA HP-UX.
+      case $host_cpu in
+      hppa*64*|ia64*)
+	# +Z the default
+	;;
+      *)
+	_LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z'
+	;;
+      esac
+      # Is there a better lt_prog_compiler_static that works with the bundled CC?
+      _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive'
+      ;;
+
+    irix5* | irix6* | nonstopux*)
+      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+      # PIC (with -KPIC) is the default.
+      _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+      ;;
+
+    linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
+      case $cc_basename in
+      # old Intel for x86_64, which still supported -KPIC.
+      ecc*)
+	_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	_LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+	_LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+        ;;
+      # icc used to be incompatible with GCC.
+      # ICC 10 doesn't accept -KPIC any more.
+      icc* | ifort*)
+	_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	_LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+	_LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+        ;;
+      # Lahey Fortran 8.1.
+      lf95*)
+	_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	_LT_TAGVAR(lt_prog_compiler_pic, $1)='--shared'
+	_LT_TAGVAR(lt_prog_compiler_static, $1)='--static'
+	;;
+      nagfor*)
+	# NAG Fortran compiler
+	_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,'
+	_LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC'
+	_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+	;;
+      tcc*)
+	# Fabrice Bellard et al's Tiny C Compiler
+	_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	_LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+	_LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+	;;
+      pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*)
+        # Portland Group compilers (*not* the Pentium gcc compiler,
+	# which looks to be a dead project)
+	_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	_LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic'
+	_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+        ;;
+      ccc*)
+        _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+        # All Alpha code is PIC.
+        _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+        ;;
+      xl* | bgxl* | bgf* | mpixl*)
+	# IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene
+	_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	_LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic'
+	_LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink'
+	;;
+      *)
+	case `$CC -V 2>&1 | sed 5q` in
+	*Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [[1-7]].* | *Sun*Fortran*\ 8.[[0-3]]*)
+	  # Sun Fortran 8.3 passes all unrecognized flags to the linker
+	  _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+	  _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+	  _LT_TAGVAR(lt_prog_compiler_wl, $1)=''
+	  ;;
+	*Sun\ F* | *Sun*Fortran*)
+	  _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+	  _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+	  _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '
+	  ;;
+	*Sun\ C*)
+	  # Sun C 5.9
+	  _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+	  _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+	  _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	  ;;
+        *Intel*\ [[CF]]*Compiler*)
+	  _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	  _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+	  _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+	  ;;
+	*Portland\ Group*)
+	  _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	  _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic'
+	  _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+	  ;;
+	esac
+	;;
+      esac
+      ;;
+
+    newsos6)
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+      _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      ;;
+
+    *nto* | *qnx*)
+      # QNX uses GNU C++, but need to define -shared option too, otherwise
+      # it will coredump.
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared'
+      ;;
+
+    osf3* | osf4* | osf5*)
+      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+      # All OSF/1 code is PIC.
+      _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+      ;;
+
+    rdos*)
+      _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+      ;;
+
+    solaris*)
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+      _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      case $cc_basename in
+      f77* | f90* | f95* | sunf77* | sunf90* | sunf95*)
+	_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ';;
+      *)
+	_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,';;
+      esac
+      ;;
+
+    sunos4*)
+      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC'
+      _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      ;;
+
+    sysv4 | sysv4.2uw2* | sysv4.3*)
+      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+      _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      ;;
+
+    sysv4*MP*)
+      if test -d /usr/nec; then
+	_LT_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic'
+	_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      fi
+      ;;
+
+    sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
+      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+      _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      ;;
+
+    unicos*)
+      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+      _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
+      ;;
+
+    uts4*)
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+      _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      ;;
+
+    *)
+      _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
+      ;;
+    esac
+  fi
+])
+case $host_os in
+  # For platforms that do not support PIC, -DPIC is meaningless:
+  *djgpp*)
+    _LT_TAGVAR(lt_prog_compiler_pic, $1)=
+    ;;
+  *)
+    _LT_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])"
+    ;;
+esac
+
+AC_CACHE_CHECK([for $compiler option to produce PIC],
+  [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)],
+  [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_prog_compiler_pic, $1)])
+_LT_TAGVAR(lt_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)
+
+#
+# Check to make sure the PIC flag actually works.
+#
+if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then
+  _LT_COMPILER_OPTION([if $compiler PIC flag $_LT_TAGVAR(lt_prog_compiler_pic, $1) works],
+    [_LT_TAGVAR(lt_cv_prog_compiler_pic_works, $1)],
+    [$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])], [],
+    [case $_LT_TAGVAR(lt_prog_compiler_pic, $1) in
+     "" | " "*) ;;
+     *) _LT_TAGVAR(lt_prog_compiler_pic, $1)=" $_LT_TAGVAR(lt_prog_compiler_pic, $1)" ;;
+     esac],
+    [_LT_TAGVAR(lt_prog_compiler_pic, $1)=
+     _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no])
+fi
+_LT_TAGDECL([pic_flag], [lt_prog_compiler_pic], [1],
+	[Additional compiler flags for building library objects])
+
+_LT_TAGDECL([wl], [lt_prog_compiler_wl], [1],
+	[How to pass a linker flag through the compiler])
+#
+# Check to make sure the static flag actually works.
+#
+wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) eval lt_tmp_static_flag=\"$_LT_TAGVAR(lt_prog_compiler_static, $1)\"
+_LT_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works],
+  _LT_TAGVAR(lt_cv_prog_compiler_static_works, $1),
+  $lt_tmp_static_flag,
+  [],
+  [_LT_TAGVAR(lt_prog_compiler_static, $1)=])
+_LT_TAGDECL([link_static_flag], [lt_prog_compiler_static], [1],
+	[Compiler flag to prevent dynamic linking])
+])# _LT_COMPILER_PIC
+
+
+# _LT_LINKER_SHLIBS([TAGNAME])
+# ----------------------------
+# See if the linker supports building shared libraries.
+m4_defun([_LT_LINKER_SHLIBS],
+[AC_REQUIRE([LT_PATH_LD])dnl
+AC_REQUIRE([LT_PATH_NM])dnl
+m4_require([_LT_PATH_MANIFEST_TOOL])dnl
+m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_DECL_EGREP])dnl
+m4_require([_LT_DECL_SED])dnl
+m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl
+m4_require([_LT_TAG_COMPILER])dnl
+AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries])
+m4_if([$1], [CXX], [
+  _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+  _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*']
+  case $host_os in
+  aix[[4-9]]*)
+    # If we're using GNU nm, then we don't want the "-C" option.
+    # -C means demangle to GNU nm, but means don't demangle to AIX nm.
+    # Without the "-l" option, or with the "-B" option, AIX nm treats
+    # weak defined symbols like other global defined symbols, whereas
+    # GNU nm marks them as "W".
+    # While the 'weak' keyword is ignored in the Export File, we need
+    # it in the Import File for the 'aix-soname' feature, so we have
+    # to replace the "-B" option with "-P" for AIX nm.
+    if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
+      _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols'
+    else
+      _LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols'
+    fi
+    ;;
+  pw32*)
+    _LT_TAGVAR(export_symbols_cmds, $1)=$ltdll_cmds
+    ;;
+  cygwin* | mingw* | cegcc*)
+    case $cc_basename in
+    cl*)
+      _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*'
+      ;;
+    *)
+      _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols'
+      _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname']
+      ;;
+    esac
+    ;;
+  linux* | k*bsd*-gnu | gnu*)
+    _LT_TAGVAR(link_all_deplibs, $1)=no
+    ;;
+  *)
+    _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+    ;;
+  esac
+], [
+  runpath_var=
+  _LT_TAGVAR(allow_undefined_flag, $1)=
+  _LT_TAGVAR(always_export_symbols, $1)=no
+  _LT_TAGVAR(archive_cmds, $1)=
+  _LT_TAGVAR(archive_expsym_cmds, $1)=
+  _LT_TAGVAR(compiler_needs_object, $1)=no
+  _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no
+  _LT_TAGVAR(export_dynamic_flag_spec, $1)=
+  _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+  _LT_TAGVAR(hardcode_automatic, $1)=no
+  _LT_TAGVAR(hardcode_direct, $1)=no
+  _LT_TAGVAR(hardcode_direct_absolute, $1)=no
+  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+  _LT_TAGVAR(hardcode_libdir_separator, $1)=
+  _LT_TAGVAR(hardcode_minus_L, $1)=no
+  _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
+  _LT_TAGVAR(inherit_rpath, $1)=no
+  _LT_TAGVAR(link_all_deplibs, $1)=unknown
+  _LT_TAGVAR(module_cmds, $1)=
+  _LT_TAGVAR(module_expsym_cmds, $1)=
+  _LT_TAGVAR(old_archive_from_new_cmds, $1)=
+  _LT_TAGVAR(old_archive_from_expsyms_cmds, $1)=
+  _LT_TAGVAR(thread_safe_flag_spec, $1)=
+  _LT_TAGVAR(whole_archive_flag_spec, $1)=
+  # include_expsyms should be a list of space-separated symbols to be *always*
+  # included in the symbol list
+  _LT_TAGVAR(include_expsyms, $1)=
+  # exclude_expsyms can be an extended regexp of symbols to exclude
+  # it will be wrapped by ' (' and ')$', so one must not match beginning or
+  # end of line.  Example: 'a|bc|.*d.*' will exclude the symbols 'a' and 'bc',
+  # as well as any symbol that contains 'd'.
+  _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*']
+  # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out
+  # platforms (ab)use it in PIC code, but their linkers get confused if
+  # the symbol is explicitly referenced.  Since portable code cannot
+  # rely on this symbol name, it's probably fine to never include it in
+  # preloaded symbol tables.
+  # Exclude shared library initialization/finalization symbols.
+dnl Note also adjust exclude_expsyms for C++ above.
+  extract_expsyms_cmds=
+
+  case $host_os in
+  cygwin* | mingw* | pw32* | cegcc*)
+    # FIXME: the MSVC++ port hasn't been tested in a loooong time
+    # When not using gcc, we currently assume that we are using
+    # Microsoft Visual C++.
+    if test yes != "$GCC"; then
+      with_gnu_ld=no
+    fi
+    ;;
+  interix*)
+    # we just hope/assume this is gcc and not c89 (= MSVC++)
+    with_gnu_ld=yes
+    ;;
+  openbsd* | bitrig*)
+    with_gnu_ld=no
+    ;;
+  linux* | k*bsd*-gnu | gnu*)
+    _LT_TAGVAR(link_all_deplibs, $1)=no
+    ;;
+  esac
+
+  _LT_TAGVAR(ld_shlibs, $1)=yes
+
+  # On some targets, GNU ld is compatible enough with the native linker
+  # that we're better off using the native interface for both.
+  lt_use_gnu_ld_interface=no
+  if test yes = "$with_gnu_ld"; then
+    case $host_os in
+      aix*)
+	# The AIX port of GNU ld has always aspired to compatibility
+	# with the native linker.  However, as the warning in the GNU ld
+	# block says, versions before 2.19.5* couldn't really create working
+	# shared libraries, regardless of the interface used.
+	case `$LD -v 2>&1` in
+	  *\ \(GNU\ Binutils\)\ 2.19.5*) ;;
+	  *\ \(GNU\ Binutils\)\ 2.[[2-9]]*) ;;
+	  *\ \(GNU\ Binutils\)\ [[3-9]]*) ;;
+	  *)
+	    lt_use_gnu_ld_interface=yes
+	    ;;
+	esac
+	;;
+      *)
+	lt_use_gnu_ld_interface=yes
+	;;
+    esac
+  fi
+
+  if test yes = "$lt_use_gnu_ld_interface"; then
+    # If archive_cmds runs LD, not CC, wlarc should be empty
+    wlarc='$wl'
+
+    # Set some defaults for GNU ld with shared library support. These
+    # are reset later if shared libraries are not supported. Putting them
+    # here allows them to be overridden if necessary.
+    runpath_var=LD_RUN_PATH
+    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+    _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic'
+    # ancient GNU ld didn't support --whole-archive et. al.
+    if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then
+      _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive'
+    else
+      _LT_TAGVAR(whole_archive_flag_spec, $1)=
+    fi
+    supports_anon_versioning=no
+    case `$LD -v | $SED -e 's/([^)]\+)\s\+//' 2>&1` in
+      *GNU\ gold*) supports_anon_versioning=yes ;;
+      *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11
+      *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ...
+      *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ...
+      *\ 2.11.*) ;; # other 2.11 versions
+      *) supports_anon_versioning=yes ;;
+    esac
+
+    # See if GNU ld supports shared libraries.
+    case $host_os in
+    aix[[3-9]]*)
+      # On AIX/PPC, the GNU linker is very broken
+      if test ia64 != "$host_cpu"; then
+	_LT_TAGVAR(ld_shlibs, $1)=no
+	cat <<_LT_EOF 1>&2
+
+*** Warning: the GNU linker, at least up to release 2.19, is reported
+*** to be unable to reliably create shared libraries on AIX.
+*** Therefore, libtool is disabling shared libraries support.  If you
+*** really care for shared libraries, you may want to install binutils
+*** 2.20 or above, or modify your PATH so that a non-GNU linker is found.
+*** You will then need to restart the configuration process.
+
+_LT_EOF
+      fi
+      ;;
+
+    amigaos*)
+      case $host_cpu in
+      powerpc)
+            # see comment about AmigaOS4 .so support
+            _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+            _LT_TAGVAR(archive_expsym_cmds, $1)=''
+        ;;
+      m68k)
+            _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+            _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+            _LT_TAGVAR(hardcode_minus_L, $1)=yes
+        ;;
+      esac
+      ;;
+
+    beos*)
+      if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+	_LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+	# Joseph Beckenbach <jrb3@best.com> says some releases of gcc
+	# support --undefined.  This deserves some investigation.  FIXME
+	_LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+      else
+	_LT_TAGVAR(ld_shlibs, $1)=no
+      fi
+      ;;
+
+    cygwin* | mingw* | pw32* | cegcc*)
+      # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless,
+      # as there is no search path for DLLs.
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+      _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-all-symbols'
+      _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+      _LT_TAGVAR(always_export_symbols, $1)=no
+      _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+      _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols'
+      _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname']
+
+      if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
+        _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+	# If the export-symbols file already is a .def file, use it as
+	# is; otherwise, prepend EXPORTS...
+	_LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then
+          cp $export_symbols $output_objdir/$soname.def;
+        else
+          echo EXPORTS > $output_objdir/$soname.def;
+          cat $export_symbols >> $output_objdir/$soname.def;
+        fi~
+        $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+      else
+	_LT_TAGVAR(ld_shlibs, $1)=no
+      fi
+      ;;
+
+    haiku*)
+      _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+      _LT_TAGVAR(link_all_deplibs, $1)=yes
+      ;;
+
+    os2*)
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+      _LT_TAGVAR(hardcode_minus_L, $1)=yes
+      _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+      shrext_cmds=.dll
+      _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
+	$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
+	$ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
+	$ECHO EXPORTS >> $output_objdir/$libname.def~
+	emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~
+	$CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
+	emximp -o $lib $output_objdir/$libname.def'
+      _LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
+	$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
+	$ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
+	$ECHO EXPORTS >> $output_objdir/$libname.def~
+	prefix_cmds="$SED"~
+	if test EXPORTS = "`$SED 1q $export_symbols`"; then
+	  prefix_cmds="$prefix_cmds -e 1d";
+	fi~
+	prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~
+	cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~
+	$CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
+	emximp -o $lib $output_objdir/$libname.def'
+      _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def'
+      _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+      ;;
+
+    interix[[3-9]]*)
+      _LT_TAGVAR(hardcode_direct, $1)=no
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir'
+      _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
+      # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
+      # Instead, shared libraries are loaded at an image base (0x10000000 by
+      # default) and relocated if they conflict, which is a slow very memory
+      # consuming and fragmenting process.  To avoid this, we pick a random,
+      # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
+      # time.  Moving up from 0x10000000 also allows more sbrk(2) space.
+      _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+      _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+      ;;
+
+    gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu)
+      tmp_diet=no
+      if test linux-dietlibc = "$host_os"; then
+	case $cc_basename in
+	  diet\ *) tmp_diet=yes;;	# linux-dietlibc with static linking (!diet-dyn)
+	esac
+      fi
+      if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \
+	 && test no = "$tmp_diet"
+      then
+	tmp_addflag=' $pic_flag'
+	tmp_sharedflag='-shared'
+	case $cc_basename,$host_cpu in
+        pgcc*)				# Portland Group C compiler
+	  _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+	  tmp_addflag=' $pic_flag'
+	  ;;
+	pgf77* | pgf90* | pgf95* | pgfortran*)
+					# Portland Group f77 and f90 compilers
+	  _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+	  tmp_addflag=' $pic_flag -Mnomain' ;;
+	ecc*,ia64* | icc*,ia64*)	# Intel C compiler on ia64
+	  tmp_addflag=' -i_dynamic' ;;
+	efc*,ia64* | ifort*,ia64*)	# Intel Fortran compiler on ia64
+	  tmp_addflag=' -i_dynamic -nofor_main' ;;
+	ifc* | ifort*)			# Intel Fortran compiler
+	  tmp_addflag=' -nofor_main' ;;
+	lf95*)				# Lahey Fortran 8.1
+	  _LT_TAGVAR(whole_archive_flag_spec, $1)=
+	  tmp_sharedflag='--shared' ;;
+        nagfor*)                        # NAGFOR 5.3
+          tmp_sharedflag='-Wl,-shared' ;;
+	xl[[cC]]* | bgxl[[cC]]* | mpixl[[cC]]*) # IBM XL C 8.0 on PPC (deal with xlf below)
+	  tmp_sharedflag='-qmkshrobj'
+	  tmp_addflag= ;;
+	nvcc*)	# Cuda Compiler Driver 2.2
+	  _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+	  _LT_TAGVAR(compiler_needs_object, $1)=yes
+	  ;;
+	esac
+	case `$CC -V 2>&1 | sed 5q` in
+	*Sun\ C*)			# Sun C 5.9
+	  _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+	  _LT_TAGVAR(compiler_needs_object, $1)=yes
+	  tmp_sharedflag='-G' ;;
+	*Sun\ F*)			# Sun Fortran 8.3
+	  tmp_sharedflag='-G' ;;
+	esac
+	_LT_TAGVAR(archive_cmds, $1)='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+
+        if test yes = "$supports_anon_versioning"; then
+          _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~
+            cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+            echo "local: *; };" >> $output_objdir/$libname.ver~
+            $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib'
+        fi
+
+	case $cc_basename in
+	tcc*)
+	  _LT_TAGVAR(export_dynamic_flag_spec, $1)='-rdynamic'
+	  ;;
+	xlf* | bgf* | bgxlf* | mpixlf*)
+	  # IBM XL Fortran 10.1 on PPC cannot create shared libs itself
+	  _LT_TAGVAR(whole_archive_flag_spec, $1)='--whole-archive$convenience --no-whole-archive'
+	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+	  _LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib'
+	  if test yes = "$supports_anon_versioning"; then
+	    _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~
+              cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+              echo "local: *; };" >> $output_objdir/$libname.ver~
+              $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib'
+	  fi
+	  ;;
+	esac
+      else
+        _LT_TAGVAR(ld_shlibs, $1)=no
+      fi
+      ;;
+
+    netbsd* | netbsdelf*-gnu)
+      if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+	_LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
+	wlarc=
+      else
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+      fi
+      ;;
+
+    solaris*)
+      if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then
+	_LT_TAGVAR(ld_shlibs, $1)=no
+	cat <<_LT_EOF 1>&2
+
+*** Warning: The releases 2.8.* of the GNU linker cannot reliably
+*** create shared libraries on Solaris systems.  Therefore, libtool
+*** is disabling shared libraries support.  We urge you to upgrade GNU
+*** binutils to release 2.9.1 or newer.  Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+_LT_EOF
+      elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+      else
+	_LT_TAGVAR(ld_shlibs, $1)=no
+      fi
+      ;;
+
+    sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*)
+      case `$LD -v 2>&1` in
+        *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.1[[0-5]].*)
+	_LT_TAGVAR(ld_shlibs, $1)=no
+	cat <<_LT_EOF 1>&2
+
+*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 cannot
+*** reliably create shared libraries on SCO systems.  Therefore, libtool
+*** is disabling shared libraries support.  We urge you to upgrade GNU
+*** binutils to release 2.16.91.0.3 or newer.  Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+_LT_EOF
+	;;
+	*)
+	  # For security reasons, it is highly recommended that you always
+	  # use absolute paths for naming shared libraries, and exclude the
+	  # DT_RUNPATH tag from executables and libraries.  But doing so
+	  # requires that you compile everything twice, which is a pain.
+	  if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+	    _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+	    _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+	  else
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	  fi
+	;;
+      esac
+      ;;
+
+    sunos4*)
+      _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+      wlarc=
+      _LT_TAGVAR(hardcode_direct, $1)=yes
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    *)
+      if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+      else
+	_LT_TAGVAR(ld_shlibs, $1)=no
+      fi
+      ;;
+    esac
+
+    if test no = "$_LT_TAGVAR(ld_shlibs, $1)"; then
+      runpath_var=
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+      _LT_TAGVAR(export_dynamic_flag_spec, $1)=
+      _LT_TAGVAR(whole_archive_flag_spec, $1)=
+    fi
+  else
+    # PORTME fill in a description of your system's linker (not GNU ld)
+    case $host_os in
+    aix3*)
+      _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+      _LT_TAGVAR(always_export_symbols, $1)=yes
+      _LT_TAGVAR(archive_expsym_cmds, $1)='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname'
+      # Note: this linker hardcodes the directories in LIBPATH if there
+      # are no directories specified by -L.
+      _LT_TAGVAR(hardcode_minus_L, $1)=yes
+      if test yes = "$GCC" && test -z "$lt_prog_compiler_static"; then
+	# Neither direct hardcoding nor static linking is supported with a
+	# broken collect2.
+	_LT_TAGVAR(hardcode_direct, $1)=unsupported
+      fi
+      ;;
+
+    aix[[4-9]]*)
+      if test ia64 = "$host_cpu"; then
+	# On IA64, the linker does run time linking by default, so we don't
+	# have to do anything special.
+	aix_use_runtimelinking=no
+	exp_sym_flag='-Bexport'
+	no_entry_flag=
+      else
+	# If we're using GNU nm, then we don't want the "-C" option.
+	# -C means demangle to GNU nm, but means don't demangle to AIX nm.
+	# Without the "-l" option, or with the "-B" option, AIX nm treats
+	# weak defined symbols like other global defined symbols, whereas
+	# GNU nm marks them as "W".
+	# While the 'weak' keyword is ignored in the Export File, we need
+	# it in the Import File for the 'aix-soname' feature, so we have
+	# to replace the "-B" option with "-P" for AIX nm.
+	if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
+	  _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols'
+	else
+	  _LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols'
+	fi
+	aix_use_runtimelinking=no
+
+	# Test if we are trying to use run time linking or normal
+	# AIX style linking. If -brtl is somewhere in LDFLAGS, we
+	# have runtime linking enabled, and use it for executables.
+	# For shared libraries, we enable/disable runtime linking
+	# depending on the kind of the shared library created -
+	# when "with_aix_soname,aix_use_runtimelinking" is:
+	# "aix,no"   lib.a(lib.so.V) shared, rtl:no,  for executables
+	# "aix,yes"  lib.so          shared, rtl:yes, for executables
+	#            lib.a           static archive
+	# "both,no"  lib.so.V(shr.o) shared, rtl:yes
+	#            lib.a(lib.so.V) shared, rtl:no,  for executables
+	# "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables
+	#            lib.a(lib.so.V) shared, rtl:no
+	# "svr4,*"   lib.so.V(shr.o) shared, rtl:yes, for executables
+	#            lib.a           static archive
+	case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*)
+	  for ld_flag in $LDFLAGS; do
+	  if (test x-brtl = "x$ld_flag" || test x-Wl,-brtl = "x$ld_flag"); then
+	    aix_use_runtimelinking=yes
+	    break
+	  fi
+	  done
+	  if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then
+	    # With aix-soname=svr4, we create the lib.so.V shared archives only,
+	    # so we don't have lib.a shared libs to link our executables.
+	    # We have to force runtime linking in this case.
+	    aix_use_runtimelinking=yes
+	    LDFLAGS="$LDFLAGS -Wl,-brtl"
+	  fi
+	  ;;
+	esac
+
+	exp_sym_flag='-bexport'
+	no_entry_flag='-bnoentry'
+      fi
+
+      # When large executables or shared objects are built, AIX ld can
+      # have problems creating the table of contents.  If linking a library
+      # or program results in "error TOC overflow" add -mminimal-toc to
+      # CXXFLAGS/CFLAGS for g++/gcc.  In the cases where that is not
+      # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
+
+      _LT_TAGVAR(archive_cmds, $1)=''
+      _LT_TAGVAR(hardcode_direct, $1)=yes
+      _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+      _LT_TAGVAR(hardcode_libdir_separator, $1)=':'
+      _LT_TAGVAR(link_all_deplibs, $1)=yes
+      _LT_TAGVAR(file_list_spec, $1)='$wl-f,'
+      case $with_aix_soname,$aix_use_runtimelinking in
+      aix,*) ;; # traditional, no import file
+      svr4,* | *,yes) # use import file
+	# The Import File defines what to hardcode.
+	_LT_TAGVAR(hardcode_direct, $1)=no
+	_LT_TAGVAR(hardcode_direct_absolute, $1)=no
+	;;
+      esac
+
+      if test yes = "$GCC"; then
+	case $host_os in aix4.[[012]]|aix4.[[012]].*)
+	# We only want to do this on AIX 4.2 and lower, the check
+	# below for broken collect2 doesn't work under 4.3+
+	  collect2name=`$CC -print-prog-name=collect2`
+	  if test -f "$collect2name" &&
+	   strings "$collect2name" | $GREP resolve_lib_name >/dev/null
+	  then
+	  # We have reworked collect2
+	  :
+	  else
+	  # We have old collect2
+	  _LT_TAGVAR(hardcode_direct, $1)=unsupported
+	  # It fails to find uninstalled libraries when the uninstalled
+	  # path is not listed in the libpath.  Setting hardcode_minus_L
+	  # to unsupported forces relinking
+	  _LT_TAGVAR(hardcode_minus_L, $1)=yes
+	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+	  _LT_TAGVAR(hardcode_libdir_separator, $1)=
+	  fi
+	  ;;
+	esac
+	shared_flag='-shared'
+	if test yes = "$aix_use_runtimelinking"; then
+	  shared_flag="$shared_flag "'$wl-G'
+	fi
+	# Need to ensure runtime linking is disabled for the traditional
+	# shared library, or the linker may eventually find shared libraries
+	# /with/ Import File - we do not want to mix them.
+	shared_flag_aix='-shared'
+	shared_flag_svr4='-shared $wl-G'
+      else
+	# not using gcc
+	if test ia64 = "$host_cpu"; then
+	# VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
+	# chokes on -Wl,-G. The following line is correct:
+	  shared_flag='-G'
+	else
+	  if test yes = "$aix_use_runtimelinking"; then
+	    shared_flag='$wl-G'
+	  else
+	    shared_flag='$wl-bM:SRE'
+	  fi
+	  shared_flag_aix='$wl-bM:SRE'
+	  shared_flag_svr4='$wl-G'
+	fi
+      fi
+
+      _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-bexpall'
+      # It seems that -bexpall does not export symbols beginning with
+      # underscore (_), so it is better to generate a list of symbols to export.
+      _LT_TAGVAR(always_export_symbols, $1)=yes
+      if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then
+	# Warning - without using the other runtime loading flags (-brtl),
+	# -berok will link without error, but may produce a broken library.
+	_LT_TAGVAR(allow_undefined_flag, $1)='-berok'
+        # Determine the default libpath from the value encoded in an
+        # empty executable.
+        _LT_SYS_MODULE_PATH_AIX([$1])
+        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath"
+        _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag
+      else
+	if test ia64 = "$host_cpu"; then
+	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $libdir:/usr/lib:/lib'
+	  _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs"
+	  _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols"
+	else
+	 # Determine the default libpath from the value encoded in an
+	 # empty executable.
+	 _LT_SYS_MODULE_PATH_AIX([$1])
+	 _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath"
+	  # Warning - without using the other run time loading flags,
+	  # -berok will link without error, but may produce a broken library.
+	  _LT_TAGVAR(no_undefined_flag, $1)=' $wl-bernotok'
+	  _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-berok'
+	  if test yes = "$with_gnu_ld"; then
+	    # We only use this code for GNU lds that support --whole-archive.
+	    _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive'
+	  else
+	    # Exported symbols can be pulled into shared objects from archives
+	    _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience'
+	  fi
+	  _LT_TAGVAR(archive_cmds_need_lc, $1)=yes
+	  _LT_TAGVAR(archive_expsym_cmds, $1)='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d'
+	  # -brtl affects multiple linker settings, -berok does not and is overridden later
+	  compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([[, ]]\\)%-berok\\1%g"`'
+	  if test svr4 != "$with_aix_soname"; then
+	    # This is similar to how AIX traditionally builds its shared libraries.
+	    _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname'
+	  fi
+	  if test aix != "$with_aix_soname"; then
+	    _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp'
+	  else
+	    # used by -dlpreopen to get the symbols
+	    _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$MV  $output_objdir/$realname.d/$soname $output_objdir'
+	  fi
+	  _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$RM -r $output_objdir/$realname.d'
+	fi
+      fi
+      ;;
+
+    amigaos*)
+      case $host_cpu in
+      powerpc)
+            # see comment about AmigaOS4 .so support
+            _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+            _LT_TAGVAR(archive_expsym_cmds, $1)=''
+        ;;
+      m68k)
+            _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+            _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+            _LT_TAGVAR(hardcode_minus_L, $1)=yes
+        ;;
+      esac
+      ;;
+
+    bsdi[[45]]*)
+      _LT_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic
+      ;;
+
+    cygwin* | mingw* | pw32* | cegcc*)
+      # When not using gcc, we currently assume that we are using
+      # Microsoft Visual C++.
+      # hardcode_libdir_flag_spec is actually meaningless, as there is
+      # no search path for DLLs.
+      case $cc_basename in
+      cl*)
+	# Native MSVC
+	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' '
+	_LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+	_LT_TAGVAR(always_export_symbols, $1)=yes
+	_LT_TAGVAR(file_list_spec, $1)='@'
+	# Tell ltmain to make .lib files, not .a files.
+	libext=lib
+	# Tell ltmain to make .dll files, not .so files.
+	shrext_cmds=.dll
+	# FIXME: Setting linknames here is a bad hack.
+	_LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames='
+	_LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then
+            cp "$export_symbols" "$output_objdir/$soname.def";
+            echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp";
+          else
+            $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp;
+          fi~
+          $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
+          linknames='
+	# The linker will not automatically build a static lib if we build a DLL.
+	# _LT_TAGVAR(old_archive_from_new_cmds, $1)='true'
+	_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+	_LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*'
+	_LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1,DATA/'\'' | $SED -e '\''/^[[AITW]][[ ]]/s/.*[[ ]]//'\'' | sort | uniq > $export_symbols'
+	# Don't use ranlib
+	_LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib'
+	_LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~
+          lt_tool_outputfile="@TOOL_OUTPUT@"~
+          case $lt_outputfile in
+            *.exe|*.EXE) ;;
+            *)
+              lt_outputfile=$lt_outputfile.exe
+              lt_tool_outputfile=$lt_tool_outputfile.exe
+              ;;
+          esac~
+          if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then
+            $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1;
+            $RM "$lt_outputfile.manifest";
+          fi'
+	;;
+      *)
+	# Assume MSVC wrapper
+	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' '
+	_LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+	# Tell ltmain to make .lib files, not .a files.
+	libext=lib
+	# Tell ltmain to make .dll files, not .so files.
+	shrext_cmds=.dll
+	# FIXME: Setting linknames here is a bad hack.
+	_LT_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames='
+	# The linker will automatically build a .lib file if we build a DLL.
+	_LT_TAGVAR(old_archive_from_new_cmds, $1)='true'
+	# FIXME: Should let the user specify the lib program.
+	_LT_TAGVAR(old_archive_cmds, $1)='lib -OUT:$oldlib$oldobjs$old_deplibs'
+	_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+	;;
+      esac
+      ;;
+
+    darwin* | rhapsody*)
+      _LT_DARWIN_LINKER_FEATURES($1)
+      ;;
+
+    dgux*)
+      _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor
+    # support.  Future versions do this automatically, but an explicit c++rt0.o
+    # does not break anything, and helps significantly (at the cost of a little
+    # extra space).
+    freebsd2.2*)
+      _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o'
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+      _LT_TAGVAR(hardcode_direct, $1)=yes
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    # Unfortunately, older versions of FreeBSD 2 do not have this feature.
+    freebsd2.*)
+      _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+      _LT_TAGVAR(hardcode_direct, $1)=yes
+      _LT_TAGVAR(hardcode_minus_L, $1)=yes
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    # FreeBSD 3 and greater uses gcc -shared to do shared libraries.
+    freebsd* | dragonfly*)
+      _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+      _LT_TAGVAR(hardcode_direct, $1)=yes
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    hpux9*)
+      if test yes = "$GCC"; then
+	_LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib'
+      else
+	_LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib'
+      fi
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir'
+      _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+      _LT_TAGVAR(hardcode_direct, $1)=yes
+
+      # hardcode_minus_L: Not really in the search PATH,
+      # but as the default location of the library.
+      _LT_TAGVAR(hardcode_minus_L, $1)=yes
+      _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
+      ;;
+
+    hpux10*)
+      if test yes,no = "$GCC,$with_gnu_ld"; then
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+      else
+	_LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
+      fi
+      if test no = "$with_gnu_ld"; then
+	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir'
+	_LT_TAGVAR(hardcode_libdir_separator, $1)=:
+	_LT_TAGVAR(hardcode_direct, $1)=yes
+	_LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+	_LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
+	# hardcode_minus_L: Not really in the search PATH,
+	# but as the default location of the library.
+	_LT_TAGVAR(hardcode_minus_L, $1)=yes
+      fi
+      ;;
+
+    hpux11*)
+      if test yes,no = "$GCC,$with_gnu_ld"; then
+	case $host_cpu in
+	hppa*64*)
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	ia64*)
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	*)
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	esac
+      else
+	case $host_cpu in
+	hppa*64*)
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	ia64*)
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	*)
+	m4_if($1, [], [
+	  # Older versions of the 11.00 compiler do not understand -b yet
+	  # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does)
+	  _LT_LINKER_OPTION([if $CC understands -b],
+	    _LT_TAGVAR(lt_cv_prog_compiler__b, $1), [-b],
+	    [_LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags'],
+	    [_LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'])],
+	  [_LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags'])
+	  ;;
+	esac
+      fi
+      if test no = "$with_gnu_ld"; then
+	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir'
+	_LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+	case $host_cpu in
+	hppa*64*|ia64*)
+	  _LT_TAGVAR(hardcode_direct, $1)=no
+	  _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+	  ;;
+	*)
+	  _LT_TAGVAR(hardcode_direct, $1)=yes
+	  _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+	  _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
+
+	  # hardcode_minus_L: Not really in the search PATH,
+	  # but as the default location of the library.
+	  _LT_TAGVAR(hardcode_minus_L, $1)=yes
+	  ;;
+	esac
+      fi
+      ;;
+
+    irix5* | irix6* | nonstopux*)
+      if test yes = "$GCC"; then
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
+	# Try to use the -exported_symbol ld option, if it does not
+	# work, assume that -exports_file does not work either and
+	# implicitly export all symbols.
+	# This should be the same for all languages, so no per-tag cache variable.
+	AC_CACHE_CHECK([whether the $host_os linker accepts -exported_symbol],
+	  [lt_cv_irix_exported_symbol],
+	  [save_LDFLAGS=$LDFLAGS
+	   LDFLAGS="$LDFLAGS -shared $wl-exported_symbol ${wl}foo $wl-update_registry $wl/dev/null"
+	   AC_LINK_IFELSE(
+	     [AC_LANG_SOURCE(
+	        [AC_LANG_CASE([C], [[int foo (void) { return 0; }]],
+			      [C++], [[int foo (void) { return 0; }]],
+			      [Fortran 77], [[
+      subroutine foo
+      end]],
+			      [Fortran], [[
+      subroutine foo
+      end]])])],
+	      [lt_cv_irix_exported_symbol=yes],
+	      [lt_cv_irix_exported_symbol=no])
+           LDFLAGS=$save_LDFLAGS])
+	if test yes = "$lt_cv_irix_exported_symbol"; then
+          _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations $wl-exports_file $wl$export_symbols -o $lib'
+	fi
+	_LT_TAGVAR(link_all_deplibs, $1)=no
+      else
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -exports_file $export_symbols -o $lib'
+      fi
+      _LT_TAGVAR(archive_cmds_need_lc, $1)='no'
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+      _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+      _LT_TAGVAR(inherit_rpath, $1)=yes
+      _LT_TAGVAR(link_all_deplibs, $1)=yes
+      ;;
+
+    linux*)
+      case $cc_basename in
+      tcc*)
+	# Fabrice Bellard et al's Tiny C Compiler
+	_LT_TAGVAR(ld_shlibs, $1)=yes
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+	;;
+      esac
+      ;;
+
+    netbsd* | netbsdelf*-gnu)
+      if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+	_LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'  # a.out
+      else
+	_LT_TAGVAR(archive_cmds, $1)='$LD -shared -o $lib $libobjs $deplibs $linker_flags'      # ELF
+      fi
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+      _LT_TAGVAR(hardcode_direct, $1)=yes
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    newsos6)
+      _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      _LT_TAGVAR(hardcode_direct, $1)=yes
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+      _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    *nto* | *qnx*)
+      ;;
+
+    openbsd* | bitrig*)
+      if test -f /usr/libexec/ld.so; then
+	_LT_TAGVAR(hardcode_direct, $1)=yes
+	_LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+	_LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+	if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+	  _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags $wl-retain-symbols-file,$export_symbols'
+	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir'
+	  _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
+	else
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir'
+	fi
+      else
+	_LT_TAGVAR(ld_shlibs, $1)=no
+      fi
+      ;;
+
+    os2*)
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+      _LT_TAGVAR(hardcode_minus_L, $1)=yes
+      _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+      shrext_cmds=.dll
+      _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
+	$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
+	$ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
+	$ECHO EXPORTS >> $output_objdir/$libname.def~
+	emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~
+	$CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
+	emximp -o $lib $output_objdir/$libname.def'
+      _LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
+	$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
+	$ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
+	$ECHO EXPORTS >> $output_objdir/$libname.def~
+	prefix_cmds="$SED"~
+	if test EXPORTS = "`$SED 1q $export_symbols`"; then
+	  prefix_cmds="$prefix_cmds -e 1d";
+	fi~
+	prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~
+	cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~
+	$CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
+	emximp -o $lib $output_objdir/$libname.def'
+      _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def'
+      _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+      ;;
+
+    osf3*)
+      if test yes = "$GCC"; then
+	_LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*'
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
+      else
+	_LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
+      fi
+      _LT_TAGVAR(archive_cmds_need_lc, $1)='no'
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+      _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+      ;;
+
+    osf4* | osf5*)	# as osf3* with the addition of -msym flag
+      if test yes = "$GCC"; then
+	_LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*'
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $pic_flag $libobjs $deplibs $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
+	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+      else
+	_LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~
+          $CC -shared$allow_undefined_flag $wl-input $wl$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~$RM $lib.exp'
+
+	# Both c and cxx compiler support -rpath directly
+	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'
+      fi
+      _LT_TAGVAR(archive_cmds_need_lc, $1)='no'
+      _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+      ;;
+
+    solaris*)
+      _LT_TAGVAR(no_undefined_flag, $1)=' -z defs'
+      if test yes = "$GCC"; then
+	wlarc='$wl'
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl-z ${wl}text $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+          $CC -shared $pic_flag $wl-z ${wl}text $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+      else
+	case `$CC -V 2>&1` in
+	*"Compilers 5.0"*)
+	  wlarc=''
+	  _LT_TAGVAR(archive_cmds, $1)='$LD -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $linker_flags'
+	  _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+            $LD -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp'
+	  ;;
+	*)
+	  wlarc='$wl'
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $compiler_flags'
+	  _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+            $CC -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+	  ;;
+	esac
+      fi
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      case $host_os in
+      solaris2.[[0-5]] | solaris2.[[0-5]].*) ;;
+      *)
+	# The compiler driver will combine and reorder linker options,
+	# but understands '-z linker_flag'.  GCC discards it without '$wl',
+	# but is careful enough not to reorder.
+	# Supported since Solaris 2.6 (maybe 2.5.1?)
+	if test yes = "$GCC"; then
+	  _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract'
+	else
+	  _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract'
+	fi
+	;;
+      esac
+      _LT_TAGVAR(link_all_deplibs, $1)=yes
+      ;;
+
+    sunos4*)
+      if test sequent = "$host_vendor"; then
+	# Use $CC to link under sequent, because it throws in some extra .o
+	# files that make .init and .fini sections work.
+	_LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h $soname -o $lib $libobjs $deplibs $compiler_flags'
+      else
+	_LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags'
+      fi
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+      _LT_TAGVAR(hardcode_direct, $1)=yes
+      _LT_TAGVAR(hardcode_minus_L, $1)=yes
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    sysv4)
+      case $host_vendor in
+	sni)
+	  _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+	  _LT_TAGVAR(hardcode_direct, $1)=yes # is this really true???
+	;;
+	siemens)
+	  ## LD is ld it makes a PLAMLIB
+	  ## CC just makes a GrossModule.
+	  _LT_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags'
+	  _LT_TAGVAR(reload_cmds, $1)='$CC -r -o $output$reload_objs'
+	  _LT_TAGVAR(hardcode_direct, $1)=no
+        ;;
+	motorola)
+	  _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+	  _LT_TAGVAR(hardcode_direct, $1)=no #Motorola manual says yes, but my tests say they lie
+	;;
+      esac
+      runpath_var='LD_RUN_PATH'
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    sysv4.3*)
+      _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      _LT_TAGVAR(export_dynamic_flag_spec, $1)='-Bexport'
+      ;;
+
+    sysv4*MP*)
+      if test -d /usr/nec; then
+	_LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+	_LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+	runpath_var=LD_RUN_PATH
+	hardcode_runpath_var=yes
+	_LT_TAGVAR(ld_shlibs, $1)=yes
+      fi
+      ;;
+
+    sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*)
+      _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text'
+      _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      runpath_var='LD_RUN_PATH'
+
+      if test yes = "$GCC"; then
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+      else
+	_LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+      fi
+      ;;
+
+    sysv5* | sco3.2v5* | sco5v6*)
+      # Note: We CANNOT use -z defs as we might desire, because we do not
+      # link with -lc, and that would cause any symbols used from libc to
+      # always be unresolved, which means just about no library would
+      # ever link correctly.  If we're not using GNU ld we use -z text
+      # though, which does catch some bad symbols but isn't as heavy-handed
+      # as -z defs.
+      _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text'
+      _LT_TAGVAR(allow_undefined_flag, $1)='$wl-z,nodefs'
+      _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R,$libdir'
+      _LT_TAGVAR(hardcode_libdir_separator, $1)=':'
+      _LT_TAGVAR(link_all_deplibs, $1)=yes
+      _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Bexport'
+      runpath_var='LD_RUN_PATH'
+
+      if test yes = "$GCC"; then
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+      else
+	_LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+      fi
+      ;;
+
+    uts4*)
+      _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    *)
+      _LT_TAGVAR(ld_shlibs, $1)=no
+      ;;
+    esac
+
+    if test sni = "$host_vendor"; then
+      case $host in
+      sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+	_LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Blargedynsym'
+	;;
+      esac
+    fi
+  fi
+])
+AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)])
+test no = "$_LT_TAGVAR(ld_shlibs, $1)" && can_build_shared=no
+
+_LT_TAGVAR(with_gnu_ld, $1)=$with_gnu_ld
+
+_LT_DECL([], [libext], [0], [Old archive suffix (normally "a")])dnl
+_LT_DECL([], [shrext_cmds], [1], [Shared library suffix (normally ".so")])dnl
+_LT_DECL([], [extract_expsyms_cmds], [2],
+    [The commands to extract the exported symbol list from a shared archive])
+
+#
+# Do we need to explicitly link libc?
+#
+case "x$_LT_TAGVAR(archive_cmds_need_lc, $1)" in
+x|xyes)
+  # Assume -lc should be added
+  _LT_TAGVAR(archive_cmds_need_lc, $1)=yes
+
+  if test yes,yes = "$GCC,$enable_shared"; then
+    case $_LT_TAGVAR(archive_cmds, $1) in
+    *'~'*)
+      # FIXME: we may have to deal with multi-command sequences.
+      ;;
+    '$CC '*)
+      # Test whether the compiler implicitly links with -lc since on some
+      # systems, -lgcc has to come before -lc. If gcc already passes -lc
+      # to ld, don't add -lc before -lgcc.
+      AC_CACHE_CHECK([whether -lc should be explicitly linked in],
+	[lt_cv_]_LT_TAGVAR(archive_cmds_need_lc, $1),
+	[$RM conftest*
+	echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+	if AC_TRY_EVAL(ac_compile) 2>conftest.err; then
+	  soname=conftest
+	  lib=conftest
+	  libobjs=conftest.$ac_objext
+	  deplibs=
+	  wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1)
+	  pic_flag=$_LT_TAGVAR(lt_prog_compiler_pic, $1)
+	  compiler_flags=-v
+	  linker_flags=-v
+	  verstring=
+	  output_objdir=.
+	  libname=conftest
+	  lt_save_allow_undefined_flag=$_LT_TAGVAR(allow_undefined_flag, $1)
+	  _LT_TAGVAR(allow_undefined_flag, $1)=
+	  if AC_TRY_EVAL(_LT_TAGVAR(archive_cmds, $1) 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1)
+	  then
+	    lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+	  else
+	    lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=yes
+	  fi
+	  _LT_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag
+	else
+	  cat conftest.err 1>&5
+	fi
+	$RM conftest*
+	])
+      _LT_TAGVAR(archive_cmds_need_lc, $1)=$lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)
+      ;;
+    esac
+  fi
+  ;;
+esac
+
+_LT_TAGDECL([build_libtool_need_lc], [archive_cmds_need_lc], [0],
+    [Whether or not to add -lc for building shared libraries])
+_LT_TAGDECL([allow_libtool_libs_with_static_runtimes],
+    [enable_shared_with_static_runtimes], [0],
+    [Whether or not to disallow shared libs when runtime libs are static])
+_LT_TAGDECL([], [export_dynamic_flag_spec], [1],
+    [Compiler flag to allow reflexive dlopens])
+_LT_TAGDECL([], [whole_archive_flag_spec], [1],
+    [Compiler flag to generate shared objects directly from archives])
+_LT_TAGDECL([], [compiler_needs_object], [1],
+    [Whether the compiler copes with passing no objects directly])
+_LT_TAGDECL([], [old_archive_from_new_cmds], [2],
+    [Create an old-style archive from a shared archive])
+_LT_TAGDECL([], [old_archive_from_expsyms_cmds], [2],
+    [Create a temporary old-style archive to link instead of a shared archive])
+_LT_TAGDECL([], [archive_cmds], [2], [Commands used to build a shared archive])
+_LT_TAGDECL([], [archive_expsym_cmds], [2])
+_LT_TAGDECL([], [module_cmds], [2],
+    [Commands used to build a loadable module if different from building
+    a shared archive.])
+_LT_TAGDECL([], [module_expsym_cmds], [2])
+_LT_TAGDECL([], [with_gnu_ld], [1],
+    [Whether we are building with GNU ld or not])
+_LT_TAGDECL([], [allow_undefined_flag], [1],
+    [Flag that allows shared libraries with undefined symbols to be built])
+_LT_TAGDECL([], [no_undefined_flag], [1],
+    [Flag that enforces no undefined symbols])
+_LT_TAGDECL([], [hardcode_libdir_flag_spec], [1],
+    [Flag to hardcode $libdir into a binary during linking.
+    This must work even if $libdir does not exist])
+_LT_TAGDECL([], [hardcode_libdir_separator], [1],
+    [Whether we need a single "-rpath" flag with a separated argument])
+_LT_TAGDECL([], [hardcode_direct], [0],
+    [Set to "yes" if using DIR/libNAME$shared_ext during linking hardcodes
+    DIR into the resulting binary])
+_LT_TAGDECL([], [hardcode_direct_absolute], [0],
+    [Set to "yes" if using DIR/libNAME$shared_ext during linking hardcodes
+    DIR into the resulting binary and the resulting library dependency is
+    "absolute", i.e impossible to change by setting $shlibpath_var if the
+    library is relocated])
+_LT_TAGDECL([], [hardcode_minus_L], [0],
+    [Set to "yes" if using the -LDIR flag during linking hardcodes DIR
+    into the resulting binary])
+_LT_TAGDECL([], [hardcode_shlibpath_var], [0],
+    [Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR
+    into the resulting binary])
+_LT_TAGDECL([], [hardcode_automatic], [0],
+    [Set to "yes" if building a shared library automatically hardcodes DIR
+    into the library and all subsequent libraries and executables linked
+    against it])
+_LT_TAGDECL([], [inherit_rpath], [0],
+    [Set to yes if linker adds runtime paths of dependent libraries
+    to runtime path list])
+_LT_TAGDECL([], [link_all_deplibs], [0],
+    [Whether libtool must link a program against all its dependency libraries])
+_LT_TAGDECL([], [always_export_symbols], [0],
+    [Set to "yes" if exported symbols are required])
+_LT_TAGDECL([], [export_symbols_cmds], [2],
+    [The commands to list exported symbols])
+_LT_TAGDECL([], [exclude_expsyms], [1],
+    [Symbols that should not be listed in the preloaded symbols])
+_LT_TAGDECL([], [include_expsyms], [1],
+    [Symbols that must always be exported])
+_LT_TAGDECL([], [prelink_cmds], [2],
+    [Commands necessary for linking programs (against libraries) with templates])
+_LT_TAGDECL([], [postlink_cmds], [2],
+    [Commands necessary for finishing linking programs])
+_LT_TAGDECL([], [file_list_spec], [1],
+    [Specify filename containing input files])
+dnl FIXME: Not yet implemented
+dnl _LT_TAGDECL([], [thread_safe_flag_spec], [1],
+dnl    [Compiler flag to generate thread safe objects])
+])# _LT_LINKER_SHLIBS
+
+
+# _LT_LANG_C_CONFIG([TAG])
+# ------------------------
+# Ensure that the configuration variables for a C compiler are suitably
+# defined.  These variables are subsequently used by _LT_CONFIG to write
+# the compiler configuration to 'libtool'.
+m4_defun([_LT_LANG_C_CONFIG],
+[m4_require([_LT_DECL_EGREP])dnl
+lt_save_CC=$CC
+AC_LANG_PUSH(C)
+
+# Source file extension for C test sources.
+ac_ext=c
+
+# Object file extension for compiled C test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="int some_variable = 0;"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code='int main(){return(0);}'
+
+_LT_TAG_COMPILER
+# Save the default compiler, since it gets overwritten when the other
+# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP.
+compiler_DEFAULT=$CC
+
+# save warnings/boilerplate of simple test code
+_LT_COMPILER_BOILERPLATE
+_LT_LINKER_BOILERPLATE
+
+## CAVEAT EMPTOR:
+## There is no encapsulation within the following macros, do not change
+## the running order or otherwise move them around unless you know exactly
+## what you are doing...
+if test -n "$compiler"; then
+  _LT_COMPILER_NO_RTTI($1)
+  _LT_COMPILER_PIC($1)
+  _LT_COMPILER_C_O($1)
+  _LT_COMPILER_FILE_LOCKS($1)
+  _LT_LINKER_SHLIBS($1)
+  _LT_SYS_DYNAMIC_LINKER($1)
+  _LT_LINKER_HARDCODE_LIBPATH($1)
+  LT_SYS_DLOPEN_SELF
+  _LT_CMD_STRIPLIB
+
+  # Report what library types will actually be built
+  AC_MSG_CHECKING([if libtool supports shared libraries])
+  AC_MSG_RESULT([$can_build_shared])
+
+  AC_MSG_CHECKING([whether to build shared libraries])
+  test no = "$can_build_shared" && enable_shared=no
+
+  # On AIX, shared libraries and static libraries use the same namespace, and
+  # are all built from PIC.
+  case $host_os in
+  aix3*)
+    test yes = "$enable_shared" && enable_static=no
+    if test -n "$RANLIB"; then
+      archive_cmds="$archive_cmds~\$RANLIB \$lib"
+      postinstall_cmds='$RANLIB $lib'
+    fi
+    ;;
+
+  aix[[4-9]]*)
+    if test ia64 != "$host_cpu"; then
+      case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in
+      yes,aix,yes) ;;			# shared object as lib.so file only
+      yes,svr4,*) ;;			# shared object as lib.so archive member only
+      yes,*) enable_static=no ;;	# shared object in lib.a archive as well
+      esac
+    fi
+    ;;
+  esac
+  AC_MSG_RESULT([$enable_shared])
+
+  AC_MSG_CHECKING([whether to build static libraries])
+  # Make sure either enable_shared or enable_static is yes.
+  test yes = "$enable_shared" || enable_static=yes
+  AC_MSG_RESULT([$enable_static])
+
+  _LT_CONFIG($1)
+fi
+AC_LANG_POP
+CC=$lt_save_CC
+])# _LT_LANG_C_CONFIG
+
+
+# _LT_LANG_CXX_CONFIG([TAG])
+# --------------------------
+# Ensure that the configuration variables for a C++ compiler are suitably
+# defined.  These variables are subsequently used by _LT_CONFIG to write
+# the compiler configuration to 'libtool'.
+m4_defun([_LT_LANG_CXX_CONFIG],
+[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_DECL_EGREP])dnl
+m4_require([_LT_PATH_MANIFEST_TOOL])dnl
+if test -n "$CXX" && ( test no != "$CXX" &&
+    ( (test g++ = "$CXX" && `g++ -v >/dev/null 2>&1` ) ||
+    (test g++ != "$CXX"))); then
+  AC_PROG_CXXCPP
+else
+  _lt_caught_CXX_error=yes
+fi
+
+AC_LANG_PUSH(C++)
+_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+_LT_TAGVAR(allow_undefined_flag, $1)=
+_LT_TAGVAR(always_export_symbols, $1)=no
+_LT_TAGVAR(archive_expsym_cmds, $1)=
+_LT_TAGVAR(compiler_needs_object, $1)=no
+_LT_TAGVAR(export_dynamic_flag_spec, $1)=
+_LT_TAGVAR(hardcode_direct, $1)=no
+_LT_TAGVAR(hardcode_direct_absolute, $1)=no
+_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+_LT_TAGVAR(hardcode_libdir_separator, $1)=
+_LT_TAGVAR(hardcode_minus_L, $1)=no
+_LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
+_LT_TAGVAR(hardcode_automatic, $1)=no
+_LT_TAGVAR(inherit_rpath, $1)=no
+_LT_TAGVAR(module_cmds, $1)=
+_LT_TAGVAR(module_expsym_cmds, $1)=
+_LT_TAGVAR(link_all_deplibs, $1)=unknown
+_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+_LT_TAGVAR(reload_flag, $1)=$reload_flag
+_LT_TAGVAR(reload_cmds, $1)=$reload_cmds
+_LT_TAGVAR(no_undefined_flag, $1)=
+_LT_TAGVAR(whole_archive_flag_spec, $1)=
+_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no
+
+# Source file extension for C++ test sources.
+ac_ext=cpp
+
+# Object file extension for compiled C++ test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# No sense in running all these tests if we already determined that
+# the CXX compiler isn't working.  Some variables (like enable_shared)
+# are currently assumed to apply to all compilers on this platform,
+# and will be corrupted by setting them based on a non-working compiler.
+if test yes != "$_lt_caught_CXX_error"; then
+  # Code to be used in simple compile tests
+  lt_simple_compile_test_code="int some_variable = 0;"
+
+  # Code to be used in simple link tests
+  lt_simple_link_test_code='int main(int, char *[[]]) { return(0); }'
+
+  # ltmain only uses $CC for tagged configurations so make sure $CC is set.
+  _LT_TAG_COMPILER
+
+  # save warnings/boilerplate of simple test code
+  _LT_COMPILER_BOILERPLATE
+  _LT_LINKER_BOILERPLATE
+
+  # Allow CC to be a program name with arguments.
+  lt_save_CC=$CC
+  lt_save_CFLAGS=$CFLAGS
+  lt_save_LD=$LD
+  lt_save_GCC=$GCC
+  GCC=$GXX
+  lt_save_with_gnu_ld=$with_gnu_ld
+  lt_save_path_LD=$lt_cv_path_LD
+  if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then
+    lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx
+  else
+    $as_unset lt_cv_prog_gnu_ld
+  fi
+  if test -n "${lt_cv_path_LDCXX+set}"; then
+    lt_cv_path_LD=$lt_cv_path_LDCXX
+  else
+    $as_unset lt_cv_path_LD
+  fi
+  test -z "${LDCXX+set}" || LD=$LDCXX
+  CC=${CXX-"c++"}
+  CFLAGS=$CXXFLAGS
+  compiler=$CC
+  _LT_TAGVAR(compiler, $1)=$CC
+  _LT_CC_BASENAME([$compiler])
+
+  if test -n "$compiler"; then
+    # We don't want -fno-exception when compiling C++ code, so set the
+    # no_builtin_flag separately
+    if test yes = "$GXX"; then
+      _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin'
+    else
+      _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=
+    fi
+
+    if test yes = "$GXX"; then
+      # Set up default GNU C++ configuration
+
+      LT_PATH_LD
+
+      # Check if GNU C++ uses GNU ld as the underlying linker, since the
+      # archiving commands below assume that GNU ld is being used.
+      if test yes = "$with_gnu_ld"; then
+        _LT_TAGVAR(archive_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib'
+        _LT_TAGVAR(archive_expsym_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+
+        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+        _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic'
+
+        # If archive_cmds runs LD, not CC, wlarc should be empty
+        # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to
+        #     investigate it a little bit more. (MM)
+        wlarc='$wl'
+
+        # ancient GNU ld didn't support --whole-archive et. al.
+        if eval "`$CC -print-prog-name=ld` --help 2>&1" |
+	  $GREP 'no-whole-archive' > /dev/null; then
+          _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive'
+        else
+          _LT_TAGVAR(whole_archive_flag_spec, $1)=
+        fi
+      else
+        with_gnu_ld=no
+        wlarc=
+
+        # A generic and very simple default shared library creation
+        # command for GNU C++ for the case where it uses the native
+        # linker, instead of GNU ld.  If possible, this setting should
+        # overridden to take advantage of the native linker features on
+        # the platform it is being used on.
+        _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib'
+      fi
+
+      # Commands to make compiler produce verbose output that lists
+      # what "hidden" libraries, object files and flags are used when
+      # linking a shared library.
+      output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+
+    else
+      GXX=no
+      with_gnu_ld=no
+      wlarc=
+    fi
+
+    # PORTME: fill in a description of your system's C++ link characteristics
+    AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries])
+    _LT_TAGVAR(ld_shlibs, $1)=yes
+    case $host_os in
+      aix3*)
+        # FIXME: insert proper C++ library support
+        _LT_TAGVAR(ld_shlibs, $1)=no
+        ;;
+      aix[[4-9]]*)
+        if test ia64 = "$host_cpu"; then
+          # On IA64, the linker does run time linking by default, so we don't
+          # have to do anything special.
+          aix_use_runtimelinking=no
+          exp_sym_flag='-Bexport'
+          no_entry_flag=
+        else
+          aix_use_runtimelinking=no
+
+          # Test if we are trying to use run time linking or normal
+          # AIX style linking. If -brtl is somewhere in LDFLAGS, we
+          # have runtime linking enabled, and use it for executables.
+          # For shared libraries, we enable/disable runtime linking
+          # depending on the kind of the shared library created -
+          # when "with_aix_soname,aix_use_runtimelinking" is:
+          # "aix,no"   lib.a(lib.so.V) shared, rtl:no,  for executables
+          # "aix,yes"  lib.so          shared, rtl:yes, for executables
+          #            lib.a           static archive
+          # "both,no"  lib.so.V(shr.o) shared, rtl:yes
+          #            lib.a(lib.so.V) shared, rtl:no,  for executables
+          # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables
+          #            lib.a(lib.so.V) shared, rtl:no
+          # "svr4,*"   lib.so.V(shr.o) shared, rtl:yes, for executables
+          #            lib.a           static archive
+          case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*)
+	    for ld_flag in $LDFLAGS; do
+	      case $ld_flag in
+	      *-brtl*)
+	        aix_use_runtimelinking=yes
+	        break
+	        ;;
+	      esac
+	    done
+	    if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then
+	      # With aix-soname=svr4, we create the lib.so.V shared archives only,
+	      # so we don't have lib.a shared libs to link our executables.
+	      # We have to force runtime linking in this case.
+	      aix_use_runtimelinking=yes
+	      LDFLAGS="$LDFLAGS -Wl,-brtl"
+	    fi
+	    ;;
+          esac
+
+          exp_sym_flag='-bexport'
+          no_entry_flag='-bnoentry'
+        fi
+
+        # When large executables or shared objects are built, AIX ld can
+        # have problems creating the table of contents.  If linking a library
+        # or program results in "error TOC overflow" add -mminimal-toc to
+        # CXXFLAGS/CFLAGS for g++/gcc.  In the cases where that is not
+        # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
+
+        _LT_TAGVAR(archive_cmds, $1)=''
+        _LT_TAGVAR(hardcode_direct, $1)=yes
+        _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+        _LT_TAGVAR(hardcode_libdir_separator, $1)=':'
+        _LT_TAGVAR(link_all_deplibs, $1)=yes
+        _LT_TAGVAR(file_list_spec, $1)='$wl-f,'
+        case $with_aix_soname,$aix_use_runtimelinking in
+        aix,*) ;;	# no import file
+        svr4,* | *,yes) # use import file
+          # The Import File defines what to hardcode.
+          _LT_TAGVAR(hardcode_direct, $1)=no
+          _LT_TAGVAR(hardcode_direct_absolute, $1)=no
+          ;;
+        esac
+
+        if test yes = "$GXX"; then
+          case $host_os in aix4.[[012]]|aix4.[[012]].*)
+          # We only want to do this on AIX 4.2 and lower, the check
+          # below for broken collect2 doesn't work under 4.3+
+	  collect2name=`$CC -print-prog-name=collect2`
+	  if test -f "$collect2name" &&
+	     strings "$collect2name" | $GREP resolve_lib_name >/dev/null
+	  then
+	    # We have reworked collect2
+	    :
+	  else
+	    # We have old collect2
+	    _LT_TAGVAR(hardcode_direct, $1)=unsupported
+	    # It fails to find uninstalled libraries when the uninstalled
+	    # path is not listed in the libpath.  Setting hardcode_minus_L
+	    # to unsupported forces relinking
+	    _LT_TAGVAR(hardcode_minus_L, $1)=yes
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+	    _LT_TAGVAR(hardcode_libdir_separator, $1)=
+	  fi
+          esac
+          shared_flag='-shared'
+	  if test yes = "$aix_use_runtimelinking"; then
+	    shared_flag=$shared_flag' $wl-G'
+	  fi
+	  # Need to ensure runtime linking is disabled for the traditional
+	  # shared library, or the linker may eventually find shared libraries
+	  # /with/ Import File - we do not want to mix them.
+	  shared_flag_aix='-shared'
+	  shared_flag_svr4='-shared $wl-G'
+        else
+          # not using gcc
+          if test ia64 = "$host_cpu"; then
+	  # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
+	  # chokes on -Wl,-G. The following line is correct:
+	  shared_flag='-G'
+          else
+	    if test yes = "$aix_use_runtimelinking"; then
+	      shared_flag='$wl-G'
+	    else
+	      shared_flag='$wl-bM:SRE'
+	    fi
+	    shared_flag_aix='$wl-bM:SRE'
+	    shared_flag_svr4='$wl-G'
+          fi
+        fi
+
+        _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-bexpall'
+        # It seems that -bexpall does not export symbols beginning with
+        # underscore (_), so it is better to generate a list of symbols to
+	# export.
+        _LT_TAGVAR(always_export_symbols, $1)=yes
+	if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then
+          # Warning - without using the other runtime loading flags (-brtl),
+          # -berok will link without error, but may produce a broken library.
+          # The "-G" linker flag allows undefined symbols.
+          _LT_TAGVAR(no_undefined_flag, $1)='-bernotok'
+          # Determine the default libpath from the value encoded in an empty
+          # executable.
+          _LT_SYS_MODULE_PATH_AIX([$1])
+          _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath"
+
+          _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag
+        else
+          if test ia64 = "$host_cpu"; then
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $libdir:/usr/lib:/lib'
+	    _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs"
+	    _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols"
+          else
+	    # Determine the default libpath from the value encoded in an
+	    # empty executable.
+	    _LT_SYS_MODULE_PATH_AIX([$1])
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath"
+	    # Warning - without using the other run time loading flags,
+	    # -berok will link without error, but may produce a broken library.
+	    _LT_TAGVAR(no_undefined_flag, $1)=' $wl-bernotok'
+	    _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-berok'
+	    if test yes = "$with_gnu_ld"; then
+	      # We only use this code for GNU lds that support --whole-archive.
+	      _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive'
+	    else
+	      # Exported symbols can be pulled into shared objects from archives
+	      _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience'
+	    fi
+	    _LT_TAGVAR(archive_cmds_need_lc, $1)=yes
+	    _LT_TAGVAR(archive_expsym_cmds, $1)='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d'
+	    # -brtl affects multiple linker settings, -berok does not and is overridden later
+	    compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([[, ]]\\)%-berok\\1%g"`'
+	    if test svr4 != "$with_aix_soname"; then
+	      # This is similar to how AIX traditionally builds its shared
+	      # libraries. Need -bnortl late, we may have -brtl in LDFLAGS.
+	      _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname'
+	    fi
+	    if test aix != "$with_aix_soname"; then
+	      _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp'
+	    else
+	      # used by -dlpreopen to get the symbols
+	      _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$MV  $output_objdir/$realname.d/$soname $output_objdir'
+	    fi
+	    _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$RM -r $output_objdir/$realname.d'
+          fi
+        fi
+        ;;
+
+      beos*)
+	if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+	  _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+	  # Joseph Beckenbach <jrb3@best.com> says some releases of gcc
+	  # support --undefined.  This deserves some investigation.  FIXME
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+	else
+	  _LT_TAGVAR(ld_shlibs, $1)=no
+	fi
+	;;
+
+      chorus*)
+        case $cc_basename in
+          *)
+	  # FIXME: insert proper C++ library support
+	  _LT_TAGVAR(ld_shlibs, $1)=no
+	  ;;
+        esac
+        ;;
+
+      cygwin* | mingw* | pw32* | cegcc*)
+	case $GXX,$cc_basename in
+	,cl* | no,cl*)
+	  # Native MSVC
+	  # hardcode_libdir_flag_spec is actually meaningless, as there is
+	  # no search path for DLLs.
+	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' '
+	  _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+	  _LT_TAGVAR(always_export_symbols, $1)=yes
+	  _LT_TAGVAR(file_list_spec, $1)='@'
+	  # Tell ltmain to make .lib files, not .a files.
+	  libext=lib
+	  # Tell ltmain to make .dll files, not .so files.
+	  shrext_cmds=.dll
+	  # FIXME: Setting linknames here is a bad hack.
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames='
+	  _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then
+              cp "$export_symbols" "$output_objdir/$soname.def";
+              echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp";
+            else
+              $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp;
+            fi~
+            $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
+            linknames='
+	  # The linker will not automatically build a static lib if we build a DLL.
+	  # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true'
+	  _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+	  # Don't use ranlib
+	  _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib'
+	  _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~
+            lt_tool_outputfile="@TOOL_OUTPUT@"~
+            case $lt_outputfile in
+              *.exe|*.EXE) ;;
+              *)
+                lt_outputfile=$lt_outputfile.exe
+                lt_tool_outputfile=$lt_tool_outputfile.exe
+                ;;
+            esac~
+            func_to_tool_file "$lt_outputfile"~
+            if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then
+              $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1;
+              $RM "$lt_outputfile.manifest";
+            fi'
+	  ;;
+	*)
+	  # g++
+	  # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless,
+	  # as there is no search path for DLLs.
+	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+	  _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-all-symbols'
+	  _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+	  _LT_TAGVAR(always_export_symbols, $1)=no
+	  _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+
+	  if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
+	    _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+	    # If the export-symbols file already is a .def file, use it as
+	    # is; otherwise, prepend EXPORTS...
+	    _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then
+              cp $export_symbols $output_objdir/$soname.def;
+            else
+              echo EXPORTS > $output_objdir/$soname.def;
+              cat $export_symbols >> $output_objdir/$soname.def;
+            fi~
+            $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+	  else
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	  fi
+	  ;;
+	esac
+	;;
+      darwin* | rhapsody*)
+        _LT_DARWIN_LINKER_FEATURES($1)
+	;;
+
+      os2*)
+	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+	_LT_TAGVAR(hardcode_minus_L, $1)=yes
+	_LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+	shrext_cmds=.dll
+	_LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
+	  $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
+	  $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
+	  $ECHO EXPORTS >> $output_objdir/$libname.def~
+	  emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~
+	  $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
+	  emximp -o $lib $output_objdir/$libname.def'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
+	  $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
+	  $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
+	  $ECHO EXPORTS >> $output_objdir/$libname.def~
+	  prefix_cmds="$SED"~
+	  if test EXPORTS = "`$SED 1q $export_symbols`"; then
+	    prefix_cmds="$prefix_cmds -e 1d";
+	  fi~
+	  prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~
+	  cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~
+	  $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
+	  emximp -o $lib $output_objdir/$libname.def'
+	_LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def'
+	_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+	;;
+
+      dgux*)
+        case $cc_basename in
+          ec++*)
+	    # FIXME: insert proper C++ library support
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	    ;;
+          ghcx*)
+	    # Green Hills C++ Compiler
+	    # FIXME: insert proper C++ library support
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	    ;;
+          *)
+	    # FIXME: insert proper C++ library support
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	    ;;
+        esac
+        ;;
+
+      freebsd2.*)
+        # C++ shared libraries reported to be fairly broken before
+	# switch to ELF
+        _LT_TAGVAR(ld_shlibs, $1)=no
+        ;;
+
+      freebsd-elf*)
+        _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+        ;;
+
+      freebsd* | dragonfly*)
+        # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF
+        # conventions
+        _LT_TAGVAR(ld_shlibs, $1)=yes
+        ;;
+
+      haiku*)
+        _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+        _LT_TAGVAR(link_all_deplibs, $1)=yes
+        ;;
+
+      hpux9*)
+        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir'
+        _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+        _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
+        _LT_TAGVAR(hardcode_direct, $1)=yes
+        _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH,
+				             # but as the default
+				             # location of the library.
+
+        case $cc_basename in
+          CC*)
+            # FIXME: insert proper C++ library support
+            _LT_TAGVAR(ld_shlibs, $1)=no
+            ;;
+          aCC*)
+            _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -b $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib'
+            # Commands to make compiler produce verbose output that lists
+            # what "hidden" libraries, object files and flags are used when
+            # linking a shared library.
+            #
+            # There doesn't appear to be a way to prevent this compiler from
+            # explicitly linking system object files so we need to strip them
+            # from the output so that they don't get included in the library
+            # dependencies.
+            output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+            ;;
+          *)
+            if test yes = "$GXX"; then
+              _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib'
+            else
+              # FIXME: insert proper C++ library support
+              _LT_TAGVAR(ld_shlibs, $1)=no
+            fi
+            ;;
+        esac
+        ;;
+
+      hpux10*|hpux11*)
+        if test no = "$with_gnu_ld"; then
+	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir'
+	  _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+          case $host_cpu in
+            hppa*64*|ia64*)
+              ;;
+            *)
+	      _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
+              ;;
+          esac
+        fi
+        case $host_cpu in
+          hppa*64*|ia64*)
+            _LT_TAGVAR(hardcode_direct, $1)=no
+            _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+            ;;
+          *)
+            _LT_TAGVAR(hardcode_direct, $1)=yes
+            _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+            _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH,
+					         # but as the default
+					         # location of the library.
+            ;;
+        esac
+
+        case $cc_basename in
+          CC*)
+	    # FIXME: insert proper C++ library support
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	    ;;
+          aCC*)
+	    case $host_cpu in
+	      hppa*64*)
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	        ;;
+	      ia64*)
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	        ;;
+	      *)
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	        ;;
+	    esac
+	    # Commands to make compiler produce verbose output that lists
+	    # what "hidden" libraries, object files and flags are used when
+	    # linking a shared library.
+	    #
+	    # There doesn't appear to be a way to prevent this compiler from
+	    # explicitly linking system object files so we need to strip them
+	    # from the output so that they don't get included in the library
+	    # dependencies.
+	    output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+	    ;;
+          *)
+	    if test yes = "$GXX"; then
+	      if test no = "$with_gnu_ld"; then
+	        case $host_cpu in
+	          hppa*64*)
+	            _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	            ;;
+	          ia64*)
+	            _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	            ;;
+	          *)
+	            _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	            ;;
+	        esac
+	      fi
+	    else
+	      # FIXME: insert proper C++ library support
+	      _LT_TAGVAR(ld_shlibs, $1)=no
+	    fi
+	    ;;
+        esac
+        ;;
+
+      interix[[3-9]]*)
+	_LT_TAGVAR(hardcode_direct, $1)=no
+	_LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir'
+	_LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
+	# Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
+	# Instead, shared libraries are loaded at an image base (0x10000000 by
+	# default) and relocated if they conflict, which is a slow very memory
+	# consuming and fragmenting process.  To avoid this, we pick a random,
+	# 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
+	# time.  Moving up from 0x10000000 also allows more sbrk(2) space.
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+	;;
+      irix5* | irix6*)
+        case $cc_basename in
+          CC*)
+	    # SGI C++
+	    _LT_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
+
+	    # Archives containing C++ object files must be created using
+	    # "CC -ar", where "CC" is the IRIX C++ compiler.  This is
+	    # necessary to make sure instantiated templates are included
+	    # in the archive.
+	    _LT_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs'
+	    ;;
+          *)
+	    if test yes = "$GXX"; then
+	      if test no = "$with_gnu_ld"; then
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
+	      else
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` -o $lib'
+	      fi
+	    fi
+	    _LT_TAGVAR(link_all_deplibs, $1)=yes
+	    ;;
+        esac
+        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+        _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+        _LT_TAGVAR(inherit_rpath, $1)=yes
+        ;;
+
+      linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
+        case $cc_basename in
+          KCC*)
+	    # Kuck and Associates, Inc. (KAI) C++ Compiler
+
+	    # KCC will only create a shared library if the output file
+	    # ends with ".so" (or ".sl" for HP-UX), so rename the library
+	    # to its proper name (with version) after linking.
+	    _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
+	    _LT_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib $wl-retain-symbols-file,$export_symbols; mv \$templib $lib'
+	    # Commands to make compiler produce verbose output that lists
+	    # what "hidden" libraries, object files and flags are used when
+	    # linking a shared library.
+	    #
+	    # There doesn't appear to be a way to prevent this compiler from
+	    # explicitly linking system object files so we need to strip them
+	    # from the output so that they don't get included in the library
+	    # dependencies.
+	    output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir'
+	    _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic'
+
+	    # Archives containing C++ object files must be created using
+	    # "CC -Bstatic", where "CC" is the KAI C++ compiler.
+	    _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs'
+	    ;;
+	  icpc* | ecpc* )
+	    # Intel C++
+	    with_gnu_ld=yes
+	    # version 8.0 and above of icpc choke on multiply defined symbols
+	    # if we add $predep_objects and $postdep_objects, however 7.1 and
+	    # earlier do not add the objects themselves.
+	    case `$CC -V 2>&1` in
+	      *"Version 7."*)
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib'
+		_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+		;;
+	      *)  # Version 8.0 or newer
+	        tmp_idyn=
+	        case $host_cpu in
+		  ia64*) tmp_idyn=' -i_dynamic';;
+		esac
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+		_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+		;;
+	    esac
+	    _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir'
+	    _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic'
+	    _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive'
+	    ;;
+          pgCC* | pgcpp*)
+            # Portland Group C++ compiler
+	    case `$CC -V` in
+	    *pgCC\ [[1-5]].* | *pgcpp\ [[1-5]].*)
+	      _LT_TAGVAR(prelink_cmds, $1)='tpldir=Template.dir~
+               rm -rf $tpldir~
+               $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~
+               compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"'
+	      _LT_TAGVAR(old_archive_cmds, $1)='tpldir=Template.dir~
+                rm -rf $tpldir~
+                $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~
+                $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~
+                $RANLIB $oldlib'
+	      _LT_TAGVAR(archive_cmds, $1)='tpldir=Template.dir~
+                rm -rf $tpldir~
+                $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~
+                $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib'
+	      _LT_TAGVAR(archive_expsym_cmds, $1)='tpldir=Template.dir~
+                rm -rf $tpldir~
+                $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~
+                $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+	      ;;
+	    *) # Version 6 and above use weak symbols
+	      _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib'
+	      _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+	      ;;
+	    esac
+
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl--rpath $wl$libdir'
+	    _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic'
+	    _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+            ;;
+	  cxx*)
+	    # Compaq C++
+	    _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib'
+	    _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname  -o $lib $wl-retain-symbols-file $wl$export_symbols'
+
+	    runpath_var=LD_RUN_PATH
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'
+	    _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+	    # Commands to make compiler produce verbose output that lists
+	    # what "hidden" libraries, object files and flags are used when
+	    # linking a shared library.
+	    #
+	    # There doesn't appear to be a way to prevent this compiler from
+	    # explicitly linking system object files so we need to strip them
+	    # from the output so that they don't get included in the library
+	    # dependencies.
+	    output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed'
+	    ;;
+	  xl* | mpixl* | bgxl*)
+	    # IBM XL 8.0 on PPC, with GNU ld
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+	    _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic'
+	    _LT_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+	    if test yes = "$supports_anon_versioning"; then
+	      _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~
+                cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+                echo "local: *; };" >> $output_objdir/$libname.ver~
+                $CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib'
+	    fi
+	    ;;
+	  *)
+	    case `$CC -V 2>&1 | sed 5q` in
+	    *Sun\ C*)
+	      # Sun C++ 5.9
+	      _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs'
+	      _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	      _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file $wl$export_symbols'
+	      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+	      _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+	      _LT_TAGVAR(compiler_needs_object, $1)=yes
+
+	      # Not sure whether something based on
+	      # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1
+	      # would be better.
+	      output_verbose_link_cmd='func_echo_all'
+
+	      # Archives containing C++ object files must be created using
+	      # "CC -xar", where "CC" is the Sun C++ compiler.  This is
+	      # necessary to make sure instantiated templates are included
+	      # in the archive.
+	      _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs'
+	      ;;
+	    esac
+	    ;;
+	esac
+	;;
+
+      lynxos*)
+        # FIXME: insert proper C++ library support
+	_LT_TAGVAR(ld_shlibs, $1)=no
+	;;
+
+      m88k*)
+        # FIXME: insert proper C++ library support
+        _LT_TAGVAR(ld_shlibs, $1)=no
+	;;
+
+      mvs*)
+        case $cc_basename in
+          cxx*)
+	    # FIXME: insert proper C++ library support
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	    ;;
+	  *)
+	    # FIXME: insert proper C++ library support
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	    ;;
+	esac
+	;;
+
+      netbsd*)
+        if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+	  _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable  -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags'
+	  wlarc=
+	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+	  _LT_TAGVAR(hardcode_direct, $1)=yes
+	  _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+	fi
+	# Workaround some broken pre-1.5 toolchains
+	output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"'
+	;;
+
+      *nto* | *qnx*)
+        _LT_TAGVAR(ld_shlibs, $1)=yes
+	;;
+
+      openbsd* | bitrig*)
+	if test -f /usr/libexec/ld.so; then
+	  _LT_TAGVAR(hardcode_direct, $1)=yes
+	  _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+	  _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib'
+	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir'
+	  if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`"; then
+	    _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file,$export_symbols -o $lib'
+	    _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
+	    _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive'
+	  fi
+	  output_verbose_link_cmd=func_echo_all
+	else
+	  _LT_TAGVAR(ld_shlibs, $1)=no
+	fi
+	;;
+
+      osf3* | osf4* | osf5*)
+        case $cc_basename in
+          KCC*)
+	    # Kuck and Associates, Inc. (KAI) C++ Compiler
+
+	    # KCC will only create a shared library if the output file
+	    # ends with ".so" (or ".sl" for HP-UX), so rename the library
+	    # to its proper name (with version) after linking.
+	    _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
+
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir'
+	    _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+	    # Archives containing C++ object files must be created using
+	    # the KAI C++ compiler.
+	    case $host in
+	      osf3*) _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;;
+	      *) _LT_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs' ;;
+	    esac
+	    ;;
+          RCC*)
+	    # Rational C++ 2.4.1
+	    # FIXME: insert proper C++ library support
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	    ;;
+          cxx*)
+	    case $host in
+	      osf3*)
+	        _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*'
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $soname `test -n "$verstring" && func_echo_all "$wl-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
+	        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+		;;
+	      *)
+	        _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
+	        _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~
+                  echo "-hidden">> $lib.exp~
+                  $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname $wl-input $wl$lib.exp  `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~
+                  $RM $lib.exp'
+	        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'
+		;;
+	    esac
+
+	    _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+	    # Commands to make compiler produce verbose output that lists
+	    # what "hidden" libraries, object files and flags are used when
+	    # linking a shared library.
+	    #
+	    # There doesn't appear to be a way to prevent this compiler from
+	    # explicitly linking system object files so we need to strip them
+	    # from the output so that they don't get included in the library
+	    # dependencies.
+	    output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+	    ;;
+	  *)
+	    if test yes,no = "$GXX,$with_gnu_ld"; then
+	      _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*'
+	      case $host in
+	        osf3*)
+	          _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
+		  ;;
+	        *)
+	          _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
+		  ;;
+	      esac
+
+	      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+	      _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+	      # Commands to make compiler produce verbose output that lists
+	      # what "hidden" libraries, object files and flags are used when
+	      # linking a shared library.
+	      output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+
+	    else
+	      # FIXME: insert proper C++ library support
+	      _LT_TAGVAR(ld_shlibs, $1)=no
+	    fi
+	    ;;
+        esac
+        ;;
+
+      psos*)
+        # FIXME: insert proper C++ library support
+        _LT_TAGVAR(ld_shlibs, $1)=no
+        ;;
+
+      sunos4*)
+        case $cc_basename in
+          CC*)
+	    # Sun C++ 4.x
+	    # FIXME: insert proper C++ library support
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	    ;;
+          lcc*)
+	    # Lucid
+	    # FIXME: insert proper C++ library support
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	    ;;
+          *)
+	    # FIXME: insert proper C++ library support
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	    ;;
+        esac
+        ;;
+
+      solaris*)
+        case $cc_basename in
+          CC* | sunCC*)
+	    # Sun C++ 4.2, 5.x and Centerline C++
+            _LT_TAGVAR(archive_cmds_need_lc,$1)=yes
+	    _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs'
+	    _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	    _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+              $CC -G$allow_undefined_flag $wl-M $wl$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+	    _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+	    case $host_os in
+	      solaris2.[[0-5]] | solaris2.[[0-5]].*) ;;
+	      *)
+		# The compiler driver will combine and reorder linker options,
+		# but understands '-z linker_flag'.
+	        # Supported since Solaris 2.6 (maybe 2.5.1?)
+		_LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract'
+	        ;;
+	    esac
+	    _LT_TAGVAR(link_all_deplibs, $1)=yes
+
+	    output_verbose_link_cmd='func_echo_all'
+
+	    # Archives containing C++ object files must be created using
+	    # "CC -xar", where "CC" is the Sun C++ compiler.  This is
+	    # necessary to make sure instantiated templates are included
+	    # in the archive.
+	    _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs'
+	    ;;
+          gcx*)
+	    # Green Hills C++ Compiler
+	    _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib'
+
+	    # The C++ compiler must be used to create the archive.
+	    _LT_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs'
+	    ;;
+          *)
+	    # GNU C++ compiler with Solaris linker
+	    if test yes,no = "$GXX,$with_gnu_ld"; then
+	      _LT_TAGVAR(no_undefined_flag, $1)=' $wl-z ${wl}defs'
+	      if $CC --version | $GREP -v '^2\.7' > /dev/null; then
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib'
+	        _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+                  $CC -shared $pic_flag -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+
+	        # Commands to make compiler produce verbose output that lists
+	        # what "hidden" libraries, object files and flags are used when
+	        # linking a shared library.
+	        output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+	      else
+	        # g++ 2.7 appears to require '-G' NOT '-shared' on this
+	        # platform.
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib'
+	        _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+                  $CC -G -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+
+	        # Commands to make compiler produce verbose output that lists
+	        # what "hidden" libraries, object files and flags are used when
+	        # linking a shared library.
+	        output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+	      fi
+
+	      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $wl$libdir'
+	      case $host_os in
+		solaris2.[[0-5]] | solaris2.[[0-5]].*) ;;
+		*)
+		  _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract'
+		  ;;
+	      esac
+	    fi
+	    ;;
+        esac
+        ;;
+
+    sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*)
+      _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text'
+      _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      runpath_var='LD_RUN_PATH'
+
+      case $cc_basename in
+        CC*)
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	*)
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+      esac
+      ;;
+
+      sysv5* | sco3.2v5* | sco5v6*)
+	# Note: We CANNOT use -z defs as we might desire, because we do not
+	# link with -lc, and that would cause any symbols used from libc to
+	# always be unresolved, which means just about no library would
+	# ever link correctly.  If we're not using GNU ld we use -z text
+	# though, which does catch some bad symbols but isn't as heavy-handed
+	# as -z defs.
+	_LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text'
+	_LT_TAGVAR(allow_undefined_flag, $1)='$wl-z,nodefs'
+	_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+	_LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R,$libdir'
+	_LT_TAGVAR(hardcode_libdir_separator, $1)=':'
+	_LT_TAGVAR(link_all_deplibs, $1)=yes
+	_LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Bexport'
+	runpath_var='LD_RUN_PATH'
+
+	case $cc_basename in
+          CC*)
+	    _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	    _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	    _LT_TAGVAR(old_archive_cmds, $1)='$CC -Tprelink_objects $oldobjs~
+              '"$_LT_TAGVAR(old_archive_cmds, $1)"
+	    _LT_TAGVAR(reload_cmds, $1)='$CC -Tprelink_objects $reload_objs~
+              '"$_LT_TAGVAR(reload_cmds, $1)"
+	    ;;
+	  *)
+	    _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	    _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	    ;;
+	esac
+      ;;
+
+      tandem*)
+        case $cc_basename in
+          NCC*)
+	    # NonStop-UX NCC 3.20
+	    # FIXME: insert proper C++ library support
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	    ;;
+          *)
+	    # FIXME: insert proper C++ library support
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	    ;;
+        esac
+        ;;
+
+      vxworks*)
+        # FIXME: insert proper C++ library support
+        _LT_TAGVAR(ld_shlibs, $1)=no
+        ;;
+
+      *)
+        # FIXME: insert proper C++ library support
+        _LT_TAGVAR(ld_shlibs, $1)=no
+        ;;
+    esac
+
+    AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)])
+    test no = "$_LT_TAGVAR(ld_shlibs, $1)" && can_build_shared=no
+
+    _LT_TAGVAR(GCC, $1)=$GXX
+    _LT_TAGVAR(LD, $1)=$LD
+
+    ## CAVEAT EMPTOR:
+    ## There is no encapsulation within the following macros, do not change
+    ## the running order or otherwise move them around unless you know exactly
+    ## what you are doing...
+    _LT_SYS_HIDDEN_LIBDEPS($1)
+    _LT_COMPILER_PIC($1)
+    _LT_COMPILER_C_O($1)
+    _LT_COMPILER_FILE_LOCKS($1)
+    _LT_LINKER_SHLIBS($1)
+    _LT_SYS_DYNAMIC_LINKER($1)
+    _LT_LINKER_HARDCODE_LIBPATH($1)
+
+    _LT_CONFIG($1)
+  fi # test -n "$compiler"
+
+  CC=$lt_save_CC
+  CFLAGS=$lt_save_CFLAGS
+  LDCXX=$LD
+  LD=$lt_save_LD
+  GCC=$lt_save_GCC
+  with_gnu_ld=$lt_save_with_gnu_ld
+  lt_cv_path_LDCXX=$lt_cv_path_LD
+  lt_cv_path_LD=$lt_save_path_LD
+  lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld
+  lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld
+fi # test yes != "$_lt_caught_CXX_error"
+
+AC_LANG_POP
+])# _LT_LANG_CXX_CONFIG
+
+
+# _LT_FUNC_STRIPNAME_CNF
+# ----------------------
+# func_stripname_cnf prefix suffix name
+# strip PREFIX and SUFFIX off of NAME.
+# PREFIX and SUFFIX must not contain globbing or regex special
+# characters, hashes, percent signs, but SUFFIX may contain a leading
+# dot (in which case that matches only a dot).
+#
+# This function is identical to the (non-XSI) version of func_stripname,
+# except this one can be used by m4 code that may be executed by configure,
+# rather than the libtool script.
+m4_defun([_LT_FUNC_STRIPNAME_CNF],[dnl
+AC_REQUIRE([_LT_DECL_SED])
+AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])
+func_stripname_cnf ()
+{
+  case @S|@2 in
+  .*) func_stripname_result=`$ECHO "@S|@3" | $SED "s%^@S|@1%%; s%\\\\@S|@2\$%%"`;;
+  *)  func_stripname_result=`$ECHO "@S|@3" | $SED "s%^@S|@1%%; s%@S|@2\$%%"`;;
+  esac
+} # func_stripname_cnf
+])# _LT_FUNC_STRIPNAME_CNF
+
+
+# _LT_SYS_HIDDEN_LIBDEPS([TAGNAME])
+# ---------------------------------
+# Figure out "hidden" library dependencies from verbose
+# compiler output when linking a shared library.
+# Parse the compiler output and extract the necessary
+# objects, libraries and library flags.
+m4_defun([_LT_SYS_HIDDEN_LIBDEPS],
+[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+AC_REQUIRE([_LT_FUNC_STRIPNAME_CNF])dnl
+# Dependencies to place before and after the object being linked:
+_LT_TAGVAR(predep_objects, $1)=
+_LT_TAGVAR(postdep_objects, $1)=
+_LT_TAGVAR(predeps, $1)=
+_LT_TAGVAR(postdeps, $1)=
+_LT_TAGVAR(compiler_lib_search_path, $1)=
+
+dnl we can't use the lt_simple_compile_test_code here,
+dnl because it contains code intended for an executable,
+dnl not a library.  It's possible we should let each
+dnl tag define a new lt_????_link_test_code variable,
+dnl but it's only used here...
+m4_if([$1], [], [cat > conftest.$ac_ext <<_LT_EOF
+int a;
+void foo (void) { a = 0; }
+_LT_EOF
+], [$1], [CXX], [cat > conftest.$ac_ext <<_LT_EOF
+class Foo
+{
+public:
+  Foo (void) { a = 0; }
+private:
+  int a;
+};
+_LT_EOF
+], [$1], [F77], [cat > conftest.$ac_ext <<_LT_EOF
+      subroutine foo
+      implicit none
+      integer*4 a
+      a=0
+      return
+      end
+_LT_EOF
+], [$1], [FC], [cat > conftest.$ac_ext <<_LT_EOF
+      subroutine foo
+      implicit none
+      integer a
+      a=0
+      return
+      end
+_LT_EOF
+], [$1], [GCJ], [cat > conftest.$ac_ext <<_LT_EOF
+public class foo {
+  private int a;
+  public void bar (void) {
+    a = 0;
+  }
+};
+_LT_EOF
+], [$1], [GO], [cat > conftest.$ac_ext <<_LT_EOF
+package foo
+func foo() {
+}
+_LT_EOF
+])
+
+_lt_libdeps_save_CFLAGS=$CFLAGS
+case "$CC $CFLAGS " in #(
+*\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;;
+*\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;;
+*\ -fuse-linker-plugin*\ *) CFLAGS="$CFLAGS -fno-use-linker-plugin" ;;
+esac
+
+dnl Parse the compiler output and extract the necessary
+dnl objects, libraries and library flags.
+if AC_TRY_EVAL(ac_compile); then
+  # Parse the compiler output and extract the necessary
+  # objects, libraries and library flags.
+
+  # Sentinel used to keep track of whether or not we are before
+  # the conftest object file.
+  pre_test_object_deps_done=no
+
+  for p in `eval "$output_verbose_link_cmd"`; do
+    case $prev$p in
+
+    -L* | -R* | -l*)
+       # Some compilers place space between "-{L,R}" and the path.
+       # Remove the space.
+       if test x-L = "$p" ||
+          test x-R = "$p"; then
+	 prev=$p
+	 continue
+       fi
+
+       # Expand the sysroot to ease extracting the directories later.
+       if test -z "$prev"; then
+         case $p in
+         -L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;;
+         -R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;;
+         -l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;;
+         esac
+       fi
+       case $p in
+       =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;;
+       esac
+       if test no = "$pre_test_object_deps_done"; then
+	 case $prev in
+	 -L | -R)
+	   # Internal compiler library paths should come after those
+	   # provided the user.  The postdeps already come after the
+	   # user supplied libs so there is no need to process them.
+	   if test -z "$_LT_TAGVAR(compiler_lib_search_path, $1)"; then
+	     _LT_TAGVAR(compiler_lib_search_path, $1)=$prev$p
+	   else
+	     _LT_TAGVAR(compiler_lib_search_path, $1)="${_LT_TAGVAR(compiler_lib_search_path, $1)} $prev$p"
+	   fi
+	   ;;
+	 # The "-l" case would never come before the object being
+	 # linked, so don't bother handling this case.
+	 esac
+       else
+	 if test -z "$_LT_TAGVAR(postdeps, $1)"; then
+	   _LT_TAGVAR(postdeps, $1)=$prev$p
+	 else
+	   _LT_TAGVAR(postdeps, $1)="${_LT_TAGVAR(postdeps, $1)} $prev$p"
+	 fi
+       fi
+       prev=
+       ;;
+
+    *.lto.$objext) ;; # Ignore GCC LTO objects
+    *.$objext)
+       # This assumes that the test object file only shows up
+       # once in the compiler output.
+       if test "$p" = "conftest.$objext"; then
+	 pre_test_object_deps_done=yes
+	 continue
+       fi
+
+       if test no = "$pre_test_object_deps_done"; then
+	 if test -z "$_LT_TAGVAR(predep_objects, $1)"; then
+	   _LT_TAGVAR(predep_objects, $1)=$p
+	 else
+	   _LT_TAGVAR(predep_objects, $1)="$_LT_TAGVAR(predep_objects, $1) $p"
+	 fi
+       else
+	 if test -z "$_LT_TAGVAR(postdep_objects, $1)"; then
+	   _LT_TAGVAR(postdep_objects, $1)=$p
+	 else
+	   _LT_TAGVAR(postdep_objects, $1)="$_LT_TAGVAR(postdep_objects, $1) $p"
+	 fi
+       fi
+       ;;
+
+    *) ;; # Ignore the rest.
+
+    esac
+  done
+
+  # Clean up.
+  rm -f a.out a.exe
+else
+  echo "libtool.m4: error: problem compiling $1 test program"
+fi
+
+$RM -f confest.$objext
+CFLAGS=$_lt_libdeps_save_CFLAGS
+
+# PORTME: override above test on systems where it is broken
+m4_if([$1], [CXX],
+[case $host_os in
+interix[[3-9]]*)
+  # Interix 3.5 installs completely hosed .la files for C++, so rather than
+  # hack all around it, let's just trust "g++" to DTRT.
+  _LT_TAGVAR(predep_objects,$1)=
+  _LT_TAGVAR(postdep_objects,$1)=
+  _LT_TAGVAR(postdeps,$1)=
+  ;;
+esac
+])
+
+case " $_LT_TAGVAR(postdeps, $1) " in
+*" -lc "*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;;
+esac
+ _LT_TAGVAR(compiler_lib_search_dirs, $1)=
+if test -n "${_LT_TAGVAR(compiler_lib_search_path, $1)}"; then
+ _LT_TAGVAR(compiler_lib_search_dirs, $1)=`echo " ${_LT_TAGVAR(compiler_lib_search_path, $1)}" | $SED -e 's! -L! !g' -e 's!^ !!'`
+fi
+_LT_TAGDECL([], [compiler_lib_search_dirs], [1],
+    [The directories searched by this compiler when creating a shared library])
+_LT_TAGDECL([], [predep_objects], [1],
+    [Dependencies to place before and after the objects being linked to
+    create a shared library])
+_LT_TAGDECL([], [postdep_objects], [1])
+_LT_TAGDECL([], [predeps], [1])
+_LT_TAGDECL([], [postdeps], [1])
+_LT_TAGDECL([], [compiler_lib_search_path], [1],
+    [The library search path used internally by the compiler when linking
+    a shared library])
+])# _LT_SYS_HIDDEN_LIBDEPS
+
+
+# _LT_LANG_F77_CONFIG([TAG])
+# --------------------------
+# Ensure that the configuration variables for a Fortran 77 compiler are
+# suitably defined.  These variables are subsequently used by _LT_CONFIG
+# to write the compiler configuration to 'libtool'.
+m4_defun([_LT_LANG_F77_CONFIG],
+[AC_LANG_PUSH(Fortran 77)
+if test -z "$F77" || test no = "$F77"; then
+  _lt_disable_F77=yes
+fi
+
+_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+_LT_TAGVAR(allow_undefined_flag, $1)=
+_LT_TAGVAR(always_export_symbols, $1)=no
+_LT_TAGVAR(archive_expsym_cmds, $1)=
+_LT_TAGVAR(export_dynamic_flag_spec, $1)=
+_LT_TAGVAR(hardcode_direct, $1)=no
+_LT_TAGVAR(hardcode_direct_absolute, $1)=no
+_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+_LT_TAGVAR(hardcode_libdir_separator, $1)=
+_LT_TAGVAR(hardcode_minus_L, $1)=no
+_LT_TAGVAR(hardcode_automatic, $1)=no
+_LT_TAGVAR(inherit_rpath, $1)=no
+_LT_TAGVAR(module_cmds, $1)=
+_LT_TAGVAR(module_expsym_cmds, $1)=
+_LT_TAGVAR(link_all_deplibs, $1)=unknown
+_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+_LT_TAGVAR(reload_flag, $1)=$reload_flag
+_LT_TAGVAR(reload_cmds, $1)=$reload_cmds
+_LT_TAGVAR(no_undefined_flag, $1)=
+_LT_TAGVAR(whole_archive_flag_spec, $1)=
+_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no
+
+# Source file extension for f77 test sources.
+ac_ext=f
+
+# Object file extension for compiled f77 test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# No sense in running all these tests if we already determined that
+# the F77 compiler isn't working.  Some variables (like enable_shared)
+# are currently assumed to apply to all compilers on this platform,
+# and will be corrupted by setting them based on a non-working compiler.
+if test yes != "$_lt_disable_F77"; then
+  # Code to be used in simple compile tests
+  lt_simple_compile_test_code="\
+      subroutine t
+      return
+      end
+"
+
+  # Code to be used in simple link tests
+  lt_simple_link_test_code="\
+      program t
+      end
+"
+
+  # ltmain only uses $CC for tagged configurations so make sure $CC is set.
+  _LT_TAG_COMPILER
+
+  # save warnings/boilerplate of simple test code
+  _LT_COMPILER_BOILERPLATE
+  _LT_LINKER_BOILERPLATE
+
+  # Allow CC to be a program name with arguments.
+  lt_save_CC=$CC
+  lt_save_GCC=$GCC
+  lt_save_CFLAGS=$CFLAGS
+  CC=${F77-"f77"}
+  CFLAGS=$FFLAGS
+  compiler=$CC
+  _LT_TAGVAR(compiler, $1)=$CC
+  _LT_CC_BASENAME([$compiler])
+  GCC=$G77
+  if test -n "$compiler"; then
+    AC_MSG_CHECKING([if libtool supports shared libraries])
+    AC_MSG_RESULT([$can_build_shared])
+
+    AC_MSG_CHECKING([whether to build shared libraries])
+    test no = "$can_build_shared" && enable_shared=no
+
+    # On AIX, shared libraries and static libraries use the same namespace, and
+    # are all built from PIC.
+    case $host_os in
+      aix3*)
+        test yes = "$enable_shared" && enable_static=no
+        if test -n "$RANLIB"; then
+          archive_cmds="$archive_cmds~\$RANLIB \$lib"
+          postinstall_cmds='$RANLIB $lib'
+        fi
+        ;;
+      aix[[4-9]]*)
+	if test ia64 != "$host_cpu"; then
+	  case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in
+	  yes,aix,yes) ;;		# shared object as lib.so file only
+	  yes,svr4,*) ;;		# shared object as lib.so archive member only
+	  yes,*) enable_static=no ;;	# shared object in lib.a archive as well
+	  esac
+	fi
+        ;;
+    esac
+    AC_MSG_RESULT([$enable_shared])
+
+    AC_MSG_CHECKING([whether to build static libraries])
+    # Make sure either enable_shared or enable_static is yes.
+    test yes = "$enable_shared" || enable_static=yes
+    AC_MSG_RESULT([$enable_static])
+
+    _LT_TAGVAR(GCC, $1)=$G77
+    _LT_TAGVAR(LD, $1)=$LD
+
+    ## CAVEAT EMPTOR:
+    ## There is no encapsulation within the following macros, do not change
+    ## the running order or otherwise move them around unless you know exactly
+    ## what you are doing...
+    _LT_COMPILER_PIC($1)
+    _LT_COMPILER_C_O($1)
+    _LT_COMPILER_FILE_LOCKS($1)
+    _LT_LINKER_SHLIBS($1)
+    _LT_SYS_DYNAMIC_LINKER($1)
+    _LT_LINKER_HARDCODE_LIBPATH($1)
+
+    _LT_CONFIG($1)
+  fi # test -n "$compiler"
+
+  GCC=$lt_save_GCC
+  CC=$lt_save_CC
+  CFLAGS=$lt_save_CFLAGS
+fi # test yes != "$_lt_disable_F77"
+
+AC_LANG_POP
+])# _LT_LANG_F77_CONFIG
+
+
+# _LT_LANG_FC_CONFIG([TAG])
+# -------------------------
+# Ensure that the configuration variables for a Fortran compiler are
+# suitably defined.  These variables are subsequently used by _LT_CONFIG
+# to write the compiler configuration to 'libtool'.
+m4_defun([_LT_LANG_FC_CONFIG],
+[AC_LANG_PUSH(Fortran)
+
+if test -z "$FC" || test no = "$FC"; then
+  _lt_disable_FC=yes
+fi
+
+_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+_LT_TAGVAR(allow_undefined_flag, $1)=
+_LT_TAGVAR(always_export_symbols, $1)=no
+_LT_TAGVAR(archive_expsym_cmds, $1)=
+_LT_TAGVAR(export_dynamic_flag_spec, $1)=
+_LT_TAGVAR(hardcode_direct, $1)=no
+_LT_TAGVAR(hardcode_direct_absolute, $1)=no
+_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+_LT_TAGVAR(hardcode_libdir_separator, $1)=
+_LT_TAGVAR(hardcode_minus_L, $1)=no
+_LT_TAGVAR(hardcode_automatic, $1)=no
+_LT_TAGVAR(inherit_rpath, $1)=no
+_LT_TAGVAR(module_cmds, $1)=
+_LT_TAGVAR(module_expsym_cmds, $1)=
+_LT_TAGVAR(link_all_deplibs, $1)=unknown
+_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+_LT_TAGVAR(reload_flag, $1)=$reload_flag
+_LT_TAGVAR(reload_cmds, $1)=$reload_cmds
+_LT_TAGVAR(no_undefined_flag, $1)=
+_LT_TAGVAR(whole_archive_flag_spec, $1)=
+_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no
+
+# Source file extension for fc test sources.
+ac_ext=${ac_fc_srcext-f}
+
+# Object file extension for compiled fc test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# No sense in running all these tests if we already determined that
+# the FC compiler isn't working.  Some variables (like enable_shared)
+# are currently assumed to apply to all compilers on this platform,
+# and will be corrupted by setting them based on a non-working compiler.
+if test yes != "$_lt_disable_FC"; then
+  # Code to be used in simple compile tests
+  lt_simple_compile_test_code="\
+      subroutine t
+      return
+      end
+"
+
+  # Code to be used in simple link tests
+  lt_simple_link_test_code="\
+      program t
+      end
+"
+
+  # ltmain only uses $CC for tagged configurations so make sure $CC is set.
+  _LT_TAG_COMPILER
+
+  # save warnings/boilerplate of simple test code
+  _LT_COMPILER_BOILERPLATE
+  _LT_LINKER_BOILERPLATE
+
+  # Allow CC to be a program name with arguments.
+  lt_save_CC=$CC
+  lt_save_GCC=$GCC
+  lt_save_CFLAGS=$CFLAGS
+  CC=${FC-"f95"}
+  CFLAGS=$FCFLAGS
+  compiler=$CC
+  GCC=$ac_cv_fc_compiler_gnu
+
+  _LT_TAGVAR(compiler, $1)=$CC
+  _LT_CC_BASENAME([$compiler])
+
+  if test -n "$compiler"; then
+    AC_MSG_CHECKING([if libtool supports shared libraries])
+    AC_MSG_RESULT([$can_build_shared])
+
+    AC_MSG_CHECKING([whether to build shared libraries])
+    test no = "$can_build_shared" && enable_shared=no
+
+    # On AIX, shared libraries and static libraries use the same namespace, and
+    # are all built from PIC.
+    case $host_os in
+      aix3*)
+        test yes = "$enable_shared" && enable_static=no
+        if test -n "$RANLIB"; then
+          archive_cmds="$archive_cmds~\$RANLIB \$lib"
+          postinstall_cmds='$RANLIB $lib'
+        fi
+        ;;
+      aix[[4-9]]*)
+	if test ia64 != "$host_cpu"; then
+	  case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in
+	  yes,aix,yes) ;;		# shared object as lib.so file only
+	  yes,svr4,*) ;;		# shared object as lib.so archive member only
+	  yes,*) enable_static=no ;;	# shared object in lib.a archive as well
+	  esac
+	fi
+        ;;
+    esac
+    AC_MSG_RESULT([$enable_shared])
+
+    AC_MSG_CHECKING([whether to build static libraries])
+    # Make sure either enable_shared or enable_static is yes.
+    test yes = "$enable_shared" || enable_static=yes
+    AC_MSG_RESULT([$enable_static])
+
+    _LT_TAGVAR(GCC, $1)=$ac_cv_fc_compiler_gnu
+    _LT_TAGVAR(LD, $1)=$LD
+
+    ## CAVEAT EMPTOR:
+    ## There is no encapsulation within the following macros, do not change
+    ## the running order or otherwise move them around unless you know exactly
+    ## what you are doing...
+    _LT_SYS_HIDDEN_LIBDEPS($1)
+    _LT_COMPILER_PIC($1)
+    _LT_COMPILER_C_O($1)
+    _LT_COMPILER_FILE_LOCKS($1)
+    _LT_LINKER_SHLIBS($1)
+    _LT_SYS_DYNAMIC_LINKER($1)
+    _LT_LINKER_HARDCODE_LIBPATH($1)
+
+    _LT_CONFIG($1)
+  fi # test -n "$compiler"
+
+  GCC=$lt_save_GCC
+  CC=$lt_save_CC
+  CFLAGS=$lt_save_CFLAGS
+fi # test yes != "$_lt_disable_FC"
+
+AC_LANG_POP
+])# _LT_LANG_FC_CONFIG
+
+
+# _LT_LANG_GCJ_CONFIG([TAG])
+# --------------------------
+# Ensure that the configuration variables for the GNU Java Compiler compiler
+# are suitably defined.  These variables are subsequently used by _LT_CONFIG
+# to write the compiler configuration to 'libtool'.
+m4_defun([_LT_LANG_GCJ_CONFIG],
+[AC_REQUIRE([LT_PROG_GCJ])dnl
+AC_LANG_SAVE
+
+# Source file extension for Java test sources.
+ac_ext=java
+
+# Object file extension for compiled Java test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="class foo {}"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code='public class conftest { public static void main(String[[]] argv) {}; }'
+
+# ltmain only uses $CC for tagged configurations so make sure $CC is set.
+_LT_TAG_COMPILER
+
+# save warnings/boilerplate of simple test code
+_LT_COMPILER_BOILERPLATE
+_LT_LINKER_BOILERPLATE
+
+# Allow CC to be a program name with arguments.
+lt_save_CC=$CC
+lt_save_CFLAGS=$CFLAGS
+lt_save_GCC=$GCC
+GCC=yes
+CC=${GCJ-"gcj"}
+CFLAGS=$GCJFLAGS
+compiler=$CC
+_LT_TAGVAR(compiler, $1)=$CC
+_LT_TAGVAR(LD, $1)=$LD
+_LT_CC_BASENAME([$compiler])
+
+# GCJ did not exist at the time GCC didn't implicitly link libc in.
+_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+
+_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+_LT_TAGVAR(reload_flag, $1)=$reload_flag
+_LT_TAGVAR(reload_cmds, $1)=$reload_cmds
+
+## CAVEAT EMPTOR:
+## There is no encapsulation within the following macros, do not change
+## the running order or otherwise move them around unless you know exactly
+## what you are doing...
+if test -n "$compiler"; then
+  _LT_COMPILER_NO_RTTI($1)
+  _LT_COMPILER_PIC($1)
+  _LT_COMPILER_C_O($1)
+  _LT_COMPILER_FILE_LOCKS($1)
+  _LT_LINKER_SHLIBS($1)
+  _LT_LINKER_HARDCODE_LIBPATH($1)
+
+  _LT_CONFIG($1)
+fi
+
+AC_LANG_RESTORE
+
+GCC=$lt_save_GCC
+CC=$lt_save_CC
+CFLAGS=$lt_save_CFLAGS
+])# _LT_LANG_GCJ_CONFIG
+
+
+# _LT_LANG_GO_CONFIG([TAG])
+# --------------------------
+# Ensure that the configuration variables for the GNU Go compiler
+# are suitably defined.  These variables are subsequently used by _LT_CONFIG
+# to write the compiler configuration to 'libtool'.
+m4_defun([_LT_LANG_GO_CONFIG],
+[AC_REQUIRE([LT_PROG_GO])dnl
+AC_LANG_SAVE
+
+# Source file extension for Go test sources.
+ac_ext=go
+
+# Object file extension for compiled Go test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="package main; func main() { }"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code='package main; func main() { }'
+
+# ltmain only uses $CC for tagged configurations so make sure $CC is set.
+_LT_TAG_COMPILER
+
+# save warnings/boilerplate of simple test code
+_LT_COMPILER_BOILERPLATE
+_LT_LINKER_BOILERPLATE
+
+# Allow CC to be a program name with arguments.
+lt_save_CC=$CC
+lt_save_CFLAGS=$CFLAGS
+lt_save_GCC=$GCC
+GCC=yes
+CC=${GOC-"gccgo"}
+CFLAGS=$GOFLAGS
+compiler=$CC
+_LT_TAGVAR(compiler, $1)=$CC
+_LT_TAGVAR(LD, $1)=$LD
+_LT_CC_BASENAME([$compiler])
+
+# Go did not exist at the time GCC didn't implicitly link libc in.
+_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+
+_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+_LT_TAGVAR(reload_flag, $1)=$reload_flag
+_LT_TAGVAR(reload_cmds, $1)=$reload_cmds
+
+## CAVEAT EMPTOR:
+## There is no encapsulation within the following macros, do not change
+## the running order or otherwise move them around unless you know exactly
+## what you are doing...
+if test -n "$compiler"; then
+  _LT_COMPILER_NO_RTTI($1)
+  _LT_COMPILER_PIC($1)
+  _LT_COMPILER_C_O($1)
+  _LT_COMPILER_FILE_LOCKS($1)
+  _LT_LINKER_SHLIBS($1)
+  _LT_LINKER_HARDCODE_LIBPATH($1)
+
+  _LT_CONFIG($1)
+fi
+
+AC_LANG_RESTORE
+
+GCC=$lt_save_GCC
+CC=$lt_save_CC
+CFLAGS=$lt_save_CFLAGS
+])# _LT_LANG_GO_CONFIG
+
+
+# _LT_LANG_RC_CONFIG([TAG])
+# -------------------------
+# Ensure that the configuration variables for the Windows resource compiler
+# are suitably defined.  These variables are subsequently used by _LT_CONFIG
+# to write the compiler configuration to 'libtool'.
+m4_defun([_LT_LANG_RC_CONFIG],
+[AC_REQUIRE([LT_PROG_RC])dnl
+AC_LANG_SAVE
+
+# Source file extension for RC test sources.
+ac_ext=rc
+
+# Object file extension for compiled RC test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }'
+
+# Code to be used in simple link tests
+lt_simple_link_test_code=$lt_simple_compile_test_code
+
+# ltmain only uses $CC for tagged configurations so make sure $CC is set.
+_LT_TAG_COMPILER
+
+# save warnings/boilerplate of simple test code
+_LT_COMPILER_BOILERPLATE
+_LT_LINKER_BOILERPLATE
+
+# Allow CC to be a program name with arguments.
+lt_save_CC=$CC
+lt_save_CFLAGS=$CFLAGS
+lt_save_GCC=$GCC
+GCC=
+CC=${RC-"windres"}
+CFLAGS=
+compiler=$CC
+_LT_TAGVAR(compiler, $1)=$CC
+_LT_CC_BASENAME([$compiler])
+_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes
+
+if test -n "$compiler"; then
+  :
+  _LT_CONFIG($1)
+fi
+
+GCC=$lt_save_GCC
+AC_LANG_RESTORE
+CC=$lt_save_CC
+CFLAGS=$lt_save_CFLAGS
+])# _LT_LANG_RC_CONFIG
+
+
+# LT_PROG_GCJ
+# -----------
+AC_DEFUN([LT_PROG_GCJ],
+[m4_ifdef([AC_PROG_GCJ], [AC_PROG_GCJ],
+  [m4_ifdef([A][M_PROG_GCJ], [A][M_PROG_GCJ],
+    [AC_CHECK_TOOL(GCJ, gcj,)
+      test set = "${GCJFLAGS+set}" || GCJFLAGS="-g -O2"
+      AC_SUBST(GCJFLAGS)])])[]dnl
+])
+
+# Old name:
+AU_ALIAS([LT_AC_PROG_GCJ], [LT_PROG_GCJ])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([LT_AC_PROG_GCJ], [])
+
+
+# LT_PROG_GO
+# ----------
+AC_DEFUN([LT_PROG_GO],
+[AC_CHECK_TOOL(GOC, gccgo,)
+])
+
+
+# LT_PROG_RC
+# ----------
+AC_DEFUN([LT_PROG_RC],
+[AC_CHECK_TOOL(RC, windres,)
+])
+
+# Old name:
+AU_ALIAS([LT_AC_PROG_RC], [LT_PROG_RC])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([LT_AC_PROG_RC], [])
+
+
+# _LT_DECL_EGREP
+# --------------
+# If we don't have a new enough Autoconf to choose the best grep
+# available, choose the one first in the user's PATH.
+m4_defun([_LT_DECL_EGREP],
+[AC_REQUIRE([AC_PROG_EGREP])dnl
+AC_REQUIRE([AC_PROG_FGREP])dnl
+test -z "$GREP" && GREP=grep
+_LT_DECL([], [GREP], [1], [A grep program that handles long lines])
+_LT_DECL([], [EGREP], [1], [An ERE matcher])
+_LT_DECL([], [FGREP], [1], [A literal string matcher])
+dnl Non-bleeding-edge autoconf doesn't subst GREP, so do it here too
+AC_SUBST([GREP])
+])
+
+
+# _LT_DECL_OBJDUMP
+# --------------
+# If we don't have a new enough Autoconf to choose the best objdump
+# available, choose the one first in the user's PATH.
+m4_defun([_LT_DECL_OBJDUMP],
+[AC_CHECK_TOOL(OBJDUMP, objdump, false)
+test -z "$OBJDUMP" && OBJDUMP=objdump
+_LT_DECL([], [OBJDUMP], [1], [An object symbol dumper])
+AC_SUBST([OBJDUMP])
+])
+
+# _LT_DECL_DLLTOOL
+# ----------------
+# Ensure DLLTOOL variable is set.
+m4_defun([_LT_DECL_DLLTOOL],
+[AC_CHECK_TOOL(DLLTOOL, dlltool, false)
+test -z "$DLLTOOL" && DLLTOOL=dlltool
+_LT_DECL([], [DLLTOOL], [1], [DLL creation program])
+AC_SUBST([DLLTOOL])
+])
+
+# _LT_DECL_SED
+# ------------
+# Check for a fully-functional sed program, that truncates
+# as few characters as possible.  Prefer GNU sed if found.
+m4_defun([_LT_DECL_SED],
+[AC_PROG_SED
+test -z "$SED" && SED=sed
+Xsed="$SED -e 1s/^X//"
+_LT_DECL([], [SED], [1], [A sed program that does not truncate output])
+_LT_DECL([], [Xsed], ["\$SED -e 1s/^X//"],
+    [Sed that helps us avoid accidentally triggering echo(1) options like -n])
+])# _LT_DECL_SED
+
+m4_ifndef([AC_PROG_SED], [
+############################################################
+# NOTE: This macro has been submitted for inclusion into   #
+#  GNU Autoconf as AC_PROG_SED.  When it is available in   #
+#  a released version of Autoconf we should remove this    #
+#  macro and use it instead.                               #
+############################################################
+
+m4_defun([AC_PROG_SED],
+[AC_MSG_CHECKING([for a sed that does not truncate output])
+AC_CACHE_VAL(lt_cv_path_SED,
+[# Loop through the user's path and test for sed and gsed.
+# Then use that list of sed's as ones to test for truncation.
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for lt_ac_prog in sed gsed; do
+    for ac_exec_ext in '' $ac_executable_extensions; do
+      if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then
+        lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext"
+      fi
+    done
+  done
+done
+IFS=$as_save_IFS
+lt_ac_max=0
+lt_ac_count=0
+# Add /usr/xpg4/bin/sed as it is typically found on Solaris
+# along with /bin/sed that truncates output.
+for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do
+  test ! -f "$lt_ac_sed" && continue
+  cat /dev/null > conftest.in
+  lt_ac_count=0
+  echo $ECHO_N "0123456789$ECHO_C" >conftest.in
+  # Check for GNU sed and select it if it is found.
+  if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then
+    lt_cv_path_SED=$lt_ac_sed
+    break
+  fi
+  while true; do
+    cat conftest.in conftest.in >conftest.tmp
+    mv conftest.tmp conftest.in
+    cp conftest.in conftest.nl
+    echo >>conftest.nl
+    $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break
+    cmp -s conftest.out conftest.nl || break
+    # 10000 chars as input seems more than enough
+    test 10 -lt "$lt_ac_count" && break
+    lt_ac_count=`expr $lt_ac_count + 1`
+    if test "$lt_ac_count" -gt "$lt_ac_max"; then
+      lt_ac_max=$lt_ac_count
+      lt_cv_path_SED=$lt_ac_sed
+    fi
+  done
+done
+])
+SED=$lt_cv_path_SED
+AC_SUBST([SED])
+AC_MSG_RESULT([$SED])
+])#AC_PROG_SED
+])#m4_ifndef
+
+# Old name:
+AU_ALIAS([LT_AC_PROG_SED], [AC_PROG_SED])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([LT_AC_PROG_SED], [])
+
+
+# _LT_CHECK_SHELL_FEATURES
+# ------------------------
+# Find out whether the shell is Bourne or XSI compatible,
+# or has some other useful features.
+m4_defun([_LT_CHECK_SHELL_FEATURES],
+[if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+  lt_unset=unset
+else
+  lt_unset=false
+fi
+_LT_DECL([], [lt_unset], [0], [whether the shell understands "unset"])dnl
+
+# test EBCDIC or ASCII
+case `echo X|tr X '\101'` in
+ A) # ASCII based system
+    # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr
+  lt_SP2NL='tr \040 \012'
+  lt_NL2SP='tr \015\012 \040\040'
+  ;;
+ *) # EBCDIC based system
+  lt_SP2NL='tr \100 \n'
+  lt_NL2SP='tr \r\n \100\100'
+  ;;
+esac
+_LT_DECL([SP2NL], [lt_SP2NL], [1], [turn spaces into newlines])dnl
+_LT_DECL([NL2SP], [lt_NL2SP], [1], [turn newlines into spaces])dnl
+])# _LT_CHECK_SHELL_FEATURES
+
+
+# _LT_PATH_CONVERSION_FUNCTIONS
+# -----------------------------
+# Determine what file name conversion functions should be used by
+# func_to_host_file (and, implicitly, by func_to_host_path).  These are needed
+# for certain cross-compile configurations and native mingw.
+m4_defun([_LT_PATH_CONVERSION_FUNCTIONS],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+AC_MSG_CHECKING([how to convert $build file names to $host format])
+AC_CACHE_VAL(lt_cv_to_host_file_cmd,
+[case $host in
+  *-*-mingw* )
+    case $build in
+      *-*-mingw* ) # actually msys
+        lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32
+        ;;
+      *-*-cygwin* )
+        lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32
+        ;;
+      * ) # otherwise, assume *nix
+        lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32
+        ;;
+    esac
+    ;;
+  *-*-cygwin* )
+    case $build in
+      *-*-mingw* ) # actually msys
+        lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin
+        ;;
+      *-*-cygwin* )
+        lt_cv_to_host_file_cmd=func_convert_file_noop
+        ;;
+      * ) # otherwise, assume *nix
+        lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin
+        ;;
+    esac
+    ;;
+  * ) # unhandled hosts (and "normal" native builds)
+    lt_cv_to_host_file_cmd=func_convert_file_noop
+    ;;
+esac
+])
+to_host_file_cmd=$lt_cv_to_host_file_cmd
+AC_MSG_RESULT([$lt_cv_to_host_file_cmd])
+_LT_DECL([to_host_file_cmd], [lt_cv_to_host_file_cmd],
+         [0], [convert $build file names to $host format])dnl
+
+AC_MSG_CHECKING([how to convert $build file names to toolchain format])
+AC_CACHE_VAL(lt_cv_to_tool_file_cmd,
+[#assume ordinary cross tools, or native build.
+lt_cv_to_tool_file_cmd=func_convert_file_noop
+case $host in
+  *-*-mingw* )
+    case $build in
+      *-*-mingw* ) # actually msys
+        lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32
+        ;;
+    esac
+    ;;
+esac
+])
+to_tool_file_cmd=$lt_cv_to_tool_file_cmd
+AC_MSG_RESULT([$lt_cv_to_tool_file_cmd])
+_LT_DECL([to_tool_file_cmd], [lt_cv_to_tool_file_cmd],
+         [0], [convert $build files to toolchain format])dnl
+])# _LT_PATH_CONVERSION_FUNCTIONS
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/config/ltmain.sh
@@ -0,0 +1,11156 @@
+#! /bin/sh
+## DO NOT EDIT - This file generated from ./build-aux/ltmain.in
+##               by inline-source v2014-01-03.01
+
+# libtool (GNU libtool) 2.4.6
+# Provide generalized library-building support services.
+# Written by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
+
+# Copyright (C) 1996-2015 Free Software Foundation, Inc.
+# This is free software; see the source for copying conditions.  There is NO
+# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+# GNU Libtool is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# As a special exception to the GNU General Public License,
+# if you distribute this file as part of a program or library that
+# is built using GNU Libtool, you may include this file under the
+# same distribution terms that you use for the rest of that program.
+#
+# GNU Libtool is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+
+PROGRAM=libtool
+PACKAGE=libtool
+VERSION="2.4.6 Debian-2.4.6-0.1"
+package_revision=2.4.6
+
+
+## ------ ##
+## Usage. ##
+## ------ ##
+
+# Run './libtool --help' for help with using this script from the
+# command line.
+
+
+## ------------------------------- ##
+## User overridable command paths. ##
+## ------------------------------- ##
+
+# After configure completes, it has a better idea of some of the
+# shell tools we need than the defaults used by the functions shared
+# with bootstrap, so set those here where they can still be over-
+# ridden by the user, but otherwise take precedence.
+
+: ${AUTOCONF="autoconf"}
+: ${AUTOMAKE="automake"}
+
+
+## -------------------------- ##
+## Source external libraries. ##
+## -------------------------- ##
+
+# Much of our low-level functionality needs to be sourced from external
+# libraries, which are installed to $pkgauxdir.
+
+# Set a version string for this script.
+scriptversion=2015-01-20.17; # UTC
+
+# General shell script boiler plate, and helper functions.
+# Written by Gary V. Vaughan, 2004
+
+# Copyright (C) 2004-2015 Free Software Foundation, Inc.
+# This is free software; see the source for copying conditions.  There is NO
+# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+
+# As a special exception to the GNU General Public License, if you distribute
+# this file as part of a program or library that is built using GNU Libtool,
+# you may include this file under the same distribution terms that you use
+# for the rest of that program.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNES FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+# Please report bugs or propose patches to gary@gnu.org.
+
+
+## ------ ##
+## Usage. ##
+## ------ ##
+
+# Evaluate this file near the top of your script to gain access to
+# the functions and variables defined here:
+#
+#   . `echo "$0" | ${SED-sed} 's|[^/]*$||'`/build-aux/funclib.sh
+#
+# If you need to override any of the default environment variable
+# settings, do that before evaluating this file.
+
+
+## -------------------- ##
+## Shell normalisation. ##
+## -------------------- ##
+
+# Some shells need a little help to be as Bourne compatible as possible.
+# Before doing anything else, make sure all that help has been provided!
+
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
+  emulate sh
+  NULLCMD=:
+  # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+  setopt NO_GLOB_SUBST
+else
+  case `(set -o) 2>/dev/null` in *posix*) set -o posix ;; esac
+fi
+
+# NLS nuisances: We save the old values in case they are required later.
+_G_user_locale=
+_G_safe_locale=
+for _G_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES
+do
+  eval "if test set = \"\${$_G_var+set}\"; then
+          save_$_G_var=\$$_G_var
+          $_G_var=C
+	  export $_G_var
+	  _G_user_locale=\"$_G_var=\\\$save_\$_G_var; \$_G_user_locale\"
+	  _G_safe_locale=\"$_G_var=C; \$_G_safe_locale\"
+	fi"
+done
+
+# CDPATH.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+# Make sure IFS has a sensible default
+sp=' '
+nl='
+'
+IFS="$sp	$nl"
+
+# There are apparently some retarded systems that use ';' as a PATH separator!
+if test "${PATH_SEPARATOR+set}" != set; then
+  PATH_SEPARATOR=:
+  (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+    (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+      PATH_SEPARATOR=';'
+  }
+fi
+
+
+
+## ------------------------- ##
+## Locate command utilities. ##
+## ------------------------- ##
+
+
+# func_executable_p FILE
+# ----------------------
+# Check that FILE is an executable regular file.
+func_executable_p ()
+{
+    test -f "$1" && test -x "$1"
+}
+
+
+# func_path_progs PROGS_LIST CHECK_FUNC [PATH]
+# --------------------------------------------
+# Search for either a program that responds to --version with output
+# containing "GNU", or else returned by CHECK_FUNC otherwise, by
+# trying all the directories in PATH with each of the elements of
+# PROGS_LIST.
+#
+# CHECK_FUNC should accept the path to a candidate program, and
+# set $func_check_prog_result if it truncates its output less than
+# $_G_path_prog_max characters.
+func_path_progs ()
+{
+    _G_progs_list=$1
+    _G_check_func=$2
+    _G_PATH=${3-"$PATH"}
+
+    _G_path_prog_max=0
+    _G_path_prog_found=false
+    _G_save_IFS=$IFS; IFS=${PATH_SEPARATOR-:}
+    for _G_dir in $_G_PATH; do
+      IFS=$_G_save_IFS
+      test -z "$_G_dir" && _G_dir=.
+      for _G_prog_name in $_G_progs_list; do
+        for _exeext in '' .EXE; do
+          _G_path_prog=$_G_dir/$_G_prog_name$_exeext
+          func_executable_p "$_G_path_prog" || continue
+          case `"$_G_path_prog" --version 2>&1` in
+            *GNU*) func_path_progs_result=$_G_path_prog _G_path_prog_found=: ;;
+            *)     $_G_check_func $_G_path_prog
+		   func_path_progs_result=$func_check_prog_result
+		   ;;
+          esac
+          $_G_path_prog_found && break 3
+        done
+      done
+    done
+    IFS=$_G_save_IFS
+    test -z "$func_path_progs_result" && {
+      echo "no acceptable sed could be found in \$PATH" >&2
+      exit 1
+    }
+}
+
+
+# We want to be able to use the functions in this file before configure
+# has figured out where the best binaries are kept, which means we have
+# to search for them ourselves - except when the results are already set
+# where we skip the searches.
+
+# Unless the user overrides by setting SED, search the path for either GNU
+# sed, or the sed that truncates its output the least.
+test -z "$SED" && {
+  _G_sed_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/
+  for _G_i in 1 2 3 4 5 6 7; do
+    _G_sed_script=$_G_sed_script$nl$_G_sed_script
+  done
+  echo "$_G_sed_script" 2>/dev/null | sed 99q >conftest.sed
+  _G_sed_script=
+
+  func_check_prog_sed ()
+  {
+    _G_path_prog=$1
+
+    _G_count=0
+    printf 0123456789 >conftest.in
+    while :
+    do
+      cat conftest.in conftest.in >conftest.tmp
+      mv conftest.tmp conftest.in
+      cp conftest.in conftest.nl
+      echo '' >> conftest.nl
+      "$_G_path_prog" -f conftest.sed <conftest.nl >conftest.out 2>/dev/null || break
+      diff conftest.out conftest.nl >/dev/null 2>&1 || break
+      _G_count=`expr $_G_count + 1`
+      if test "$_G_count" -gt "$_G_path_prog_max"; then
+        # Best one so far, save it but keep looking for a better one
+        func_check_prog_result=$_G_path_prog
+        _G_path_prog_max=$_G_count
+      fi
+      # 10*(2^10) chars as input seems more than enough
+      test 10 -lt "$_G_count" && break
+    done
+    rm -f conftest.in conftest.tmp conftest.nl conftest.out
+  }
+
+  func_path_progs "sed gsed" func_check_prog_sed $PATH:/usr/xpg4/bin
+  rm -f conftest.sed
+  SED=$func_path_progs_result
+}
+
+
+# Unless the user overrides by setting GREP, search the path for either GNU
+# grep, or the grep that truncates its output the least.
+test -z "$GREP" && {
+  func_check_prog_grep ()
+  {
+    _G_path_prog=$1
+
+    _G_count=0
+    _G_path_prog_max=0
+    printf 0123456789 >conftest.in
+    while :
+    do
+      cat conftest.in conftest.in >conftest.tmp
+      mv conftest.tmp conftest.in
+      cp conftest.in conftest.nl
+      echo 'GREP' >> conftest.nl
+      "$_G_path_prog" -e 'GREP$' -e '-(cannot match)-' <conftest.nl >conftest.out 2>/dev/null || break
+      diff conftest.out conftest.nl >/dev/null 2>&1 || break
+      _G_count=`expr $_G_count + 1`
+      if test "$_G_count" -gt "$_G_path_prog_max"; then
+        # Best one so far, save it but keep looking for a better one
+        func_check_prog_result=$_G_path_prog
+        _G_path_prog_max=$_G_count
+      fi
+      # 10*(2^10) chars as input seems more than enough
+      test 10 -lt "$_G_count" && break
+    done
+    rm -f conftest.in conftest.tmp conftest.nl conftest.out
+  }
+
+  func_path_progs "grep ggrep" func_check_prog_grep $PATH:/usr/xpg4/bin
+  GREP=$func_path_progs_result
+}
+
+
+## ------------------------------- ##
+## User overridable command paths. ##
+## ------------------------------- ##
+
+# All uppercase variable names are used for environment variables.  These
+# variables can be overridden by the user before calling a script that
+# uses them if a suitable command of that name is not already available
+# in the command search PATH.
+
+: ${CP="cp -f"}
+: ${ECHO="printf %s\n"}
+: ${EGREP="$GREP -E"}
+: ${FGREP="$GREP -F"}
+: ${LN_S="ln -s"}
+: ${MAKE="make"}
+: ${MKDIR="mkdir"}
+: ${MV="mv -f"}
+: ${RM="rm -f"}
+: ${SHELL="${CONFIG_SHELL-/bin/sh}"}
+
+
+## -------------------- ##
+## Useful sed snippets. ##
+## -------------------- ##
+
+sed_dirname='s|/[^/]*$||'
+sed_basename='s|^.*/||'
+
+# Sed substitution that helps us do robust quoting.  It backslashifies
+# metacharacters that are still active within double-quoted strings.
+sed_quote_subst='s|\([`"$\\]\)|\\\1|g'
+
+# Same as above, but do not quote variable references.
+sed_double_quote_subst='s/\(["`\\]\)/\\\1/g'
+
+# Sed substitution that turns a string into a regex matching for the
+# string literally.
+sed_make_literal_regex='s|[].[^$\\*\/]|\\&|g'
+
+# Sed substitution that converts a w32 file name or path
+# that contains forward slashes, into one that contains
+# (escaped) backslashes.  A very naive implementation.
+sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g'
+
+# Re-'\' parameter expansions in output of sed_double_quote_subst that
+# were '\'-ed in input to the same.  If an odd number of '\' preceded a
+# '$' in input to sed_double_quote_subst, that '$' was protected from
+# expansion.  Since each input '\' is now two '\'s, look for any number
+# of runs of four '\'s followed by two '\'s and then a '$'.  '\' that '$'.
+_G_bs='\\'
+_G_bs2='\\\\'
+_G_bs4='\\\\\\\\'
+_G_dollar='\$'
+sed_double_backslash="\
+  s/$_G_bs4/&\\
+/g
+  s/^$_G_bs2$_G_dollar/$_G_bs&/
+  s/\\([^$_G_bs]\\)$_G_bs2$_G_dollar/\\1$_G_bs2$_G_bs$_G_dollar/g
+  s/\n//g"
+
+
+## ----------------- ##
+## Global variables. ##
+## ----------------- ##
+
+# Except for the global variables explicitly listed below, the following
+# functions in the '^func_' namespace, and the '^require_' namespace
+# variables initialised in the 'Resource management' section, sourcing
+# this file will not pollute your global namespace with anything
+# else. There's no portable way to scope variables in Bourne shell
+# though, so actually running these functions will sometimes place
+# results into a variable named after the function, and often use
+# temporary variables in the '^_G_' namespace. If you are careful to
+# avoid using those namespaces casually in your sourcing script, things
+# should continue to work as you expect. And, of course, you can freely
+# overwrite any of the functions or variables defined here before
+# calling anything to customize them.
+
+EXIT_SUCCESS=0
+EXIT_FAILURE=1
+EXIT_MISMATCH=63  # $? = 63 is used to indicate version mismatch to missing.
+EXIT_SKIP=77	  # $? = 77 is used to indicate a skipped test to automake.
+
+# Allow overriding, eg assuming that you follow the convention of
+# putting '$debug_cmd' at the start of all your functions, you can get
+# bash to show function call trace with:
+#
+#    debug_cmd='eval echo "${FUNCNAME[0]} $*" >&2' bash your-script-name
+debug_cmd=${debug_cmd-":"}
+exit_cmd=:
+
+# By convention, finish your script with:
+#
+#    exit $exit_status
+#
+# so that you can set exit_status to non-zero if you want to indicate
+# something went wrong during execution without actually bailing out at
+# the point of failure.
+exit_status=$EXIT_SUCCESS
+
+# Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh
+# is ksh but when the shell is invoked as "sh" and the current value of
+# the _XPG environment variable is not equal to 1 (one), the special
+# positional parameter $0, within a function call, is the name of the
+# function.
+progpath=$0
+
+# The name of this program.
+progname=`$ECHO "$progpath" |$SED "$sed_basename"`
+
+# Make sure we have an absolute progpath for reexecution:
+case $progpath in
+  [\\/]*|[A-Za-z]:\\*) ;;
+  *[\\/]*)
+     progdir=`$ECHO "$progpath" |$SED "$sed_dirname"`
+     progdir=`cd "$progdir" && pwd`
+     progpath=$progdir/$progname
+     ;;
+  *)
+     _G_IFS=$IFS
+     IFS=${PATH_SEPARATOR-:}
+     for progdir in $PATH; do
+       IFS=$_G_IFS
+       test -x "$progdir/$progname" && break
+     done
+     IFS=$_G_IFS
+     test -n "$progdir" || progdir=`pwd`
+     progpath=$progdir/$progname
+     ;;
+esac
+
+
+## ----------------- ##
+## Standard options. ##
+## ----------------- ##
+
+# The following options affect the operation of the functions defined
+# below, and should be set appropriately depending on run-time para-
+# meters passed on the command line.
+
+opt_dry_run=false
+opt_quiet=false
+opt_verbose=false
+
+# Categories 'all' and 'none' are always available.  Append any others
+# you will pass as the first argument to func_warning from your own
+# code.
+warning_categories=
+
+# By default, display warnings according to 'opt_warning_types'.  Set
+# 'warning_func'  to ':' to elide all warnings, or func_fatal_error to
+# treat the next displayed warning as a fatal error.
+warning_func=func_warn_and_continue
+
+# Set to 'all' to display all warnings, 'none' to suppress all
+# warnings, or a space delimited list of some subset of
+# 'warning_categories' to display only the listed warnings.
+opt_warning_types=all
+
+
+## -------------------- ##
+## Resource management. ##
+## -------------------- ##
+
+# This section contains definitions for functions that each ensure a
+# particular resource (a file, or a non-empty configuration variable for
+# example) is available, and if appropriate to extract default values
+# from pertinent package files. Call them using their associated
+# 'require_*' variable to ensure that they are executed, at most, once.
+#
+# It's entirely deliberate that calling these functions can set
+# variables that don't obey the namespace limitations obeyed by the rest
+# of this file, in order that that they be as useful as possible to
+# callers.
+
+
+# require_term_colors
+# -------------------
+# Allow display of bold text on terminals that support it.
+require_term_colors=func_require_term_colors
+func_require_term_colors ()
+{
+    $debug_cmd
+
+    test -t 1 && {
+      # COLORTERM and USE_ANSI_COLORS environment variables take
+      # precedence, because most terminfo databases neglect to describe
+      # whether color sequences are supported.
+      test -n "${COLORTERM+set}" && : ${USE_ANSI_COLORS="1"}
+
+      if test 1 = "$USE_ANSI_COLORS"; then
+        # Standard ANSI escape sequences
+        tc_reset='[0m'
+        tc_bold='[1m';   tc_standout='[7m'
+        tc_red='[31m';   tc_green='[32m'
+        tc_blue='[34m';  tc_cyan='[36m'
+      else
+        # Otherwise trust the terminfo database after all.
+        test -n "`tput sgr0 2>/dev/null`" && {
+          tc_reset=`tput sgr0`
+          test -n "`tput bold 2>/dev/null`" && tc_bold=`tput bold`
+          tc_standout=$tc_bold
+          test -n "`tput smso 2>/dev/null`" && tc_standout=`tput smso`
+          test -n "`tput setaf 1 2>/dev/null`" && tc_red=`tput setaf 1`
+          test -n "`tput setaf 2 2>/dev/null`" && tc_green=`tput setaf 2`
+          test -n "`tput setaf 4 2>/dev/null`" && tc_blue=`tput setaf 4`
+          test -n "`tput setaf 5 2>/dev/null`" && tc_cyan=`tput setaf 5`
+        }
+      fi
+    }
+
+    require_term_colors=:
+}
+
+
+## ----------------- ##
+## Function library. ##
+## ----------------- ##
+
+# This section contains a variety of useful functions to call in your
+# scripts. Take note of the portable wrappers for features provided by
+# some modern shells, which will fall back to slower equivalents on
+# less featureful shells.
+
+
+# func_append VAR VALUE
+# ---------------------
+# Append VALUE onto the existing contents of VAR.
+
+  # We should try to minimise forks, especially on Windows where they are
+  # unreasonably slow, so skip the feature probes when bash or zsh are
+  # being used:
+  if test set = "${BASH_VERSION+set}${ZSH_VERSION+set}"; then
+    : ${_G_HAVE_ARITH_OP="yes"}
+    : ${_G_HAVE_XSI_OPS="yes"}
+    # The += operator was introduced in bash 3.1
+    case $BASH_VERSION in
+      [12].* | 3.0 | 3.0*) ;;
+      *)
+        : ${_G_HAVE_PLUSEQ_OP="yes"}
+        ;;
+    esac
+  fi
+
+  # _G_HAVE_PLUSEQ_OP
+  # Can be empty, in which case the shell is probed, "yes" if += is
+  # useable or anything else if it does not work.
+  test -z "$_G_HAVE_PLUSEQ_OP" \
+    && (eval 'x=a; x+=" b"; test "a b" = "$x"') 2>/dev/null \
+    && _G_HAVE_PLUSEQ_OP=yes
+
+if test yes = "$_G_HAVE_PLUSEQ_OP"
+then
+  # This is an XSI compatible shell, allowing a faster implementation...
+  eval 'func_append ()
+  {
+    $debug_cmd
+
+    eval "$1+=\$2"
+  }'
+else
+  # ...otherwise fall back to using expr, which is often a shell builtin.
+  func_append ()
+  {
+    $debug_cmd
+
+    eval "$1=\$$1\$2"
+  }
+fi
+
+
+# func_append_quoted VAR VALUE
+# ----------------------------
+# Quote VALUE and append to the end of shell variable VAR, separated
+# by a space.
+if test yes = "$_G_HAVE_PLUSEQ_OP"; then
+  eval 'func_append_quoted ()
+  {
+    $debug_cmd
+
+    func_quote_for_eval "$2"
+    eval "$1+=\\ \$func_quote_for_eval_result"
+  }'
+else
+  func_append_quoted ()
+  {
+    $debug_cmd
+
+    func_quote_for_eval "$2"
+    eval "$1=\$$1\\ \$func_quote_for_eval_result"
+  }
+fi
+
+
+# func_append_uniq VAR VALUE
+# --------------------------
+# Append unique VALUE onto the existing contents of VAR, assuming
+# entries are delimited by the first character of VALUE.  For example:
+#
+#   func_append_uniq options " --another-option option-argument"
+#
+# will only append to $options if " --another-option option-argument "
+# is not already present somewhere in $options already (note spaces at
+# each end implied by leading space in second argument).
+func_append_uniq ()
+{
+    $debug_cmd
+
+    eval _G_current_value='`$ECHO $'$1'`'
+    _G_delim=`expr "$2" : '\(.\)'`
+
+    case $_G_delim$_G_current_value$_G_delim in
+      *"$2$_G_delim"*) ;;
+      *) func_append "$@" ;;
+    esac
+}
+
+
+# func_arith TERM...
+# ------------------
+# Set func_arith_result to the result of evaluating TERMs.
+  test -z "$_G_HAVE_ARITH_OP" \
+    && (eval 'test 2 = $(( 1 + 1 ))') 2>/dev/null \
+    && _G_HAVE_ARITH_OP=yes
+
+if test yes = "$_G_HAVE_ARITH_OP"; then
+  eval 'func_arith ()
+  {
+    $debug_cmd
+
+    func_arith_result=$(( $* ))
+  }'
+else
+  func_arith ()
+  {
+    $debug_cmd
+
+    func_arith_result=`expr "$@"`
+  }
+fi
+
+
+# func_basename FILE
+# ------------------
+# Set func_basename_result to FILE with everything up to and including
+# the last / stripped.
+if test yes = "$_G_HAVE_XSI_OPS"; then
+  # If this shell supports suffix pattern removal, then use it to avoid
+  # forking. Hide the definitions single quotes in case the shell chokes
+  # on unsupported syntax...
+  _b='func_basename_result=${1##*/}'
+  _d='case $1 in
+        */*) func_dirname_result=${1%/*}$2 ;;
+        *  ) func_dirname_result=$3        ;;
+      esac'
+
+else
+  # ...otherwise fall back to using sed.
+  _b='func_basename_result=`$ECHO "$1" |$SED "$sed_basename"`'
+  _d='func_dirname_result=`$ECHO "$1"  |$SED "$sed_dirname"`
+      if test "X$func_dirname_result" = "X$1"; then
+        func_dirname_result=$3
+      else
+        func_append func_dirname_result "$2"
+      fi'
+fi
+
+eval 'func_basename ()
+{
+    $debug_cmd
+
+    '"$_b"'
+}'
+
+
+# func_dirname FILE APPEND NONDIR_REPLACEMENT
+# -------------------------------------------
+# Compute the dirname of FILE.  If nonempty, add APPEND to the result,
+# otherwise set result to NONDIR_REPLACEMENT.
+eval 'func_dirname ()
+{
+    $debug_cmd
+
+    '"$_d"'
+}'
+
+
+# func_dirname_and_basename FILE APPEND NONDIR_REPLACEMENT
+# --------------------------------------------------------
+# Perform func_basename and func_dirname in a single function
+# call:
+#   dirname:  Compute the dirname of FILE.  If nonempty,
+#             add APPEND to the result, otherwise set result
+#             to NONDIR_REPLACEMENT.
+#             value returned in "$func_dirname_result"
+#   basename: Compute filename of FILE.
+#             value retuned in "$func_basename_result"
+# For efficiency, we do not delegate to the functions above but instead
+# duplicate the functionality here.
+eval 'func_dirname_and_basename ()
+{
+    $debug_cmd
+
+    '"$_b"'
+    '"$_d"'
+}'
+
+
+# func_echo ARG...
+# ----------------
+# Echo program name prefixed message.
+func_echo ()
+{
+    $debug_cmd
+
+    _G_message=$*
+
+    func_echo_IFS=$IFS
+    IFS=$nl
+    for _G_line in $_G_message; do
+      IFS=$func_echo_IFS
+      $ECHO "$progname: $_G_line"
+    done
+    IFS=$func_echo_IFS
+}
+
+
+# func_echo_all ARG...
+# --------------------
+# Invoke $ECHO with all args, space-separated.
+func_echo_all ()
+{
+    $ECHO "$*"
+}
+
+
+# func_echo_infix_1 INFIX ARG...
+# ------------------------------
+# Echo program name, followed by INFIX on the first line, with any
+# additional lines not showing INFIX.
+func_echo_infix_1 ()
+{
+    $debug_cmd
+
+    $require_term_colors
+
+    _G_infix=$1; shift
+    _G_indent=$_G_infix
+    _G_prefix="$progname: $_G_infix: "
+    _G_message=$*
+
+    # Strip color escape sequences before counting printable length
+    for _G_tc in "$tc_reset" "$tc_bold" "$tc_standout" "$tc_red" "$tc_green" "$tc_blue" "$tc_cyan"
+    do
+      test -n "$_G_tc" && {
+        _G_esc_tc=`$ECHO "$_G_tc" | $SED "$sed_make_literal_regex"`
+        _G_indent=`$ECHO "$_G_indent" | $SED "s|$_G_esc_tc||g"`
+      }
+    done
+    _G_indent="$progname: "`echo "$_G_indent" | $SED 's|.| |g'`"  " ## exclude from sc_prohibit_nested_quotes
+
+    func_echo_infix_1_IFS=$IFS
+    IFS=$nl
+    for _G_line in $_G_message; do
+      IFS=$func_echo_infix_1_IFS
+      $ECHO "$_G_prefix$tc_bold$_G_line$tc_reset" >&2
+      _G_prefix=$_G_indent
+    done
+    IFS=$func_echo_infix_1_IFS
+}
+
+
+# func_error ARG...
+# -----------------
+# Echo program name prefixed message to standard error.
+func_error ()
+{
+    $debug_cmd
+
+    $require_term_colors
+
+    func_echo_infix_1 "  $tc_standout${tc_red}error$tc_reset" "$*" >&2
+}
+
+
+# func_fatal_error ARG...
+# -----------------------
+# Echo program name prefixed message to standard error, and exit.
+func_fatal_error ()
+{
+    $debug_cmd
+
+    func_error "$*"
+    exit $EXIT_FAILURE
+}
+
+
+# func_grep EXPRESSION FILENAME
+# -----------------------------
+# Check whether EXPRESSION matches any line of FILENAME, without output.
+func_grep ()
+{
+    $debug_cmd
+
+    $GREP "$1" "$2" >/dev/null 2>&1
+}
+
+
+# func_len STRING
+# ---------------
+# Set func_len_result to the length of STRING. STRING may not
+# start with a hyphen.
+  test -z "$_G_HAVE_XSI_OPS" \
+    && (eval 'x=a/b/c;
+      test 5aa/bb/cc = "${#x}${x%%/*}${x%/*}${x#*/}${x##*/}"') 2>/dev/null \
+    && _G_HAVE_XSI_OPS=yes
+
+if test yes = "$_G_HAVE_XSI_OPS"; then
+  eval 'func_len ()
+  {
+    $debug_cmd
+
+    func_len_result=${#1}
+  }'
+else
+  func_len ()
+  {
+    $debug_cmd
+
+    func_len_result=`expr "$1" : ".*" 2>/dev/null || echo $max_cmd_len`
+  }
+fi
+
+
+# func_mkdir_p DIRECTORY-PATH
+# ---------------------------
+# Make sure the entire path to DIRECTORY-PATH is available.
+func_mkdir_p ()
+{
+    $debug_cmd
+
+    _G_directory_path=$1
+    _G_dir_list=
+
+    if test -n "$_G_directory_path" && test : != "$opt_dry_run"; then
+
+      # Protect directory names starting with '-'
+      case $_G_directory_path in
+        -*) _G_directory_path=./$_G_directory_path ;;
+      esac
+
+      # While some portion of DIR does not yet exist...
+      while test ! -d "$_G_directory_path"; do
+        # ...make a list in topmost first order.  Use a colon delimited
+	# list incase some portion of path contains whitespace.
+        _G_dir_list=$_G_directory_path:$_G_dir_list
+
+        # If the last portion added has no slash in it, the list is done
+        case $_G_directory_path in */*) ;; *) break ;; esac
+
+        # ...otherwise throw away the child directory and loop
+        _G_directory_path=`$ECHO "$_G_directory_path" | $SED -e "$sed_dirname"`
+      done
+      _G_dir_list=`$ECHO "$_G_dir_list" | $SED 's|:*$||'`
+
+      func_mkdir_p_IFS=$IFS; IFS=:
+      for _G_dir in $_G_dir_list; do
+	IFS=$func_mkdir_p_IFS
+        # mkdir can fail with a 'File exist' error if two processes
+        # try to create one of the directories concurrently.  Don't
+        # stop in that case!
+        $MKDIR "$_G_dir" 2>/dev/null || :
+      done
+      IFS=$func_mkdir_p_IFS
+
+      # Bail out if we (or some other process) failed to create a directory.
+      test -d "$_G_directory_path" || \
+        func_fatal_error "Failed to create '$1'"
+    fi
+}
+
+
+# func_mktempdir [BASENAME]
+# -------------------------
+# Make a temporary directory that won't clash with other running
+# libtool processes, and avoids race conditions if possible.  If
+# given, BASENAME is the basename for that directory.
+func_mktempdir ()
+{
+    $debug_cmd
+
+    _G_template=${TMPDIR-/tmp}/${1-$progname}
+
+    if test : = "$opt_dry_run"; then
+      # Return a directory name, but don't create it in dry-run mode
+      _G_tmpdir=$_G_template-$$
+    else
+
+      # If mktemp works, use that first and foremost
+      _G_tmpdir=`mktemp -d "$_G_template-XXXXXXXX" 2>/dev/null`
+
+      if test ! -d "$_G_tmpdir"; then
+        # Failing that, at least try and use $RANDOM to avoid a race
+        _G_tmpdir=$_G_template-${RANDOM-0}$$
+
+        func_mktempdir_umask=`umask`
+        umask 0077
+        $MKDIR "$_G_tmpdir"
+        umask $func_mktempdir_umask
+      fi
+
+      # If we're not in dry-run mode, bomb out on failure
+      test -d "$_G_tmpdir" || \
+        func_fatal_error "cannot create temporary directory '$_G_tmpdir'"
+    fi
+
+    $ECHO "$_G_tmpdir"
+}
+
+
+# func_normal_abspath PATH
+# ------------------------
+# Remove doubled-up and trailing slashes, "." path components,
+# and cancel out any ".." path components in PATH after making
+# it an absolute path.
+func_normal_abspath ()
+{
+    $debug_cmd
+
+    # These SED scripts presuppose an absolute path with a trailing slash.
+    _G_pathcar='s|^/\([^/]*\).*$|\1|'
+    _G_pathcdr='s|^/[^/]*||'
+    _G_removedotparts=':dotsl
+		s|/\./|/|g
+		t dotsl
+		s|/\.$|/|'
+    _G_collapseslashes='s|/\{1,\}|/|g'
+    _G_finalslash='s|/*$|/|'
+
+    # Start from root dir and reassemble the path.
+    func_normal_abspath_result=
+    func_normal_abspath_tpath=$1
+    func_normal_abspath_altnamespace=
+    case $func_normal_abspath_tpath in
+      "")
+        # Empty path, that just means $cwd.
+        func_stripname '' '/' "`pwd`"
+        func_normal_abspath_result=$func_stripname_result
+        return
+        ;;
+      # The next three entries are used to spot a run of precisely
+      # two leading slashes without using negated character classes;
+      # we take advantage of case's first-match behaviour.
+      ///*)
+        # Unusual form of absolute path, do nothing.
+        ;;
+      //*)
+        # Not necessarily an ordinary path; POSIX reserves leading '//'
+        # and for example Cygwin uses it to access remote file shares
+        # over CIFS/SMB, so we conserve a leading double slash if found.
+        func_normal_abspath_altnamespace=/
+        ;;
+      /*)
+        # Absolute path, do nothing.
+        ;;
+      *)
+        # Relative path, prepend $cwd.
+        func_normal_abspath_tpath=`pwd`/$func_normal_abspath_tpath
+        ;;
+    esac
+
+    # Cancel out all the simple stuff to save iterations.  We also want
+    # the path to end with a slash for ease of parsing, so make sure
+    # there is one (and only one) here.
+    func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \
+          -e "$_G_removedotparts" -e "$_G_collapseslashes" -e "$_G_finalslash"`
+    while :; do
+      # Processed it all yet?
+      if test / = "$func_normal_abspath_tpath"; then
+        # If we ascended to the root using ".." the result may be empty now.
+        if test -z "$func_normal_abspath_result"; then
+          func_normal_abspath_result=/
+        fi
+        break
+      fi
+      func_normal_abspath_tcomponent=`$ECHO "$func_normal_abspath_tpath" | $SED \
+          -e "$_G_pathcar"`
+      func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \
+          -e "$_G_pathcdr"`
+      # Figure out what to do with it
+      case $func_normal_abspath_tcomponent in
+        "")
+          # Trailing empty path component, ignore it.
+          ;;
+        ..)
+          # Parent dir; strip last assembled component from result.
+          func_dirname "$func_normal_abspath_result"
+          func_normal_abspath_result=$func_dirname_result
+          ;;
+        *)
+          # Actual path component, append it.
+          func_append func_normal_abspath_result "/$func_normal_abspath_tcomponent"
+          ;;
+      esac
+    done
+    # Restore leading double-slash if one was found on entry.
+    func_normal_abspath_result=$func_normal_abspath_altnamespace$func_normal_abspath_result
+}
+
+
+# func_notquiet ARG...
+# --------------------
+# Echo program name prefixed message only when not in quiet mode.
+func_notquiet ()
+{
+    $debug_cmd
+
+    $opt_quiet || func_echo ${1+"$@"}
+
+    # A bug in bash halts the script if the last line of a function
+    # fails when set -e is in force, so we need another command to
+    # work around that:
+    :
+}
+
+
+# func_relative_path SRCDIR DSTDIR
+# --------------------------------
+# Set func_relative_path_result to the relative path from SRCDIR to DSTDIR.
+func_relative_path ()
+{
+    $debug_cmd
+
+    func_relative_path_result=
+    func_normal_abspath "$1"
+    func_relative_path_tlibdir=$func_normal_abspath_result
+    func_normal_abspath "$2"
+    func_relative_path_tbindir=$func_normal_abspath_result
+
+    # Ascend the tree starting from libdir
+    while :; do
+      # check if we have found a prefix of bindir
+      case $func_relative_path_tbindir in
+        $func_relative_path_tlibdir)
+          # found an exact match
+          func_relative_path_tcancelled=
+          break
+          ;;
+        $func_relative_path_tlibdir*)
+          # found a matching prefix
+          func_stripname "$func_relative_path_tlibdir" '' "$func_relative_path_tbindir"
+          func_relative_path_tcancelled=$func_stripname_result
+          if test -z "$func_relative_path_result"; then
+            func_relative_path_result=.
+          fi
+          break
+          ;;
+        *)
+          func_dirname $func_relative_path_tlibdir
+          func_relative_path_tlibdir=$func_dirname_result
+          if test -z "$func_relative_path_tlibdir"; then
+            # Have to descend all the way to the root!
+            func_relative_path_result=../$func_relative_path_result
+            func_relative_path_tcancelled=$func_relative_path_tbindir
+            break
+          fi
+          func_relative_path_result=../$func_relative_path_result
+          ;;
+      esac
+    done
+
+    # Now calculate path; take care to avoid doubling-up slashes.
+    func_stripname '' '/' "$func_relative_path_result"
+    func_relative_path_result=$func_stripname_result
+    func_stripname '/' '/' "$func_relative_path_tcancelled"
+    if test -n "$func_stripname_result"; then
+      func_append func_relative_path_result "/$func_stripname_result"
+    fi
+
+    # Normalisation. If bindir is libdir, return '.' else relative path.
+    if test -n "$func_relative_path_result"; then
+      func_stripname './' '' "$func_relative_path_result"
+      func_relative_path_result=$func_stripname_result
+    fi
+
+    test -n "$func_relative_path_result" || func_relative_path_result=.
+
+    :
+}
+
+
+# func_quote_for_eval ARG...
+# --------------------------
+# Aesthetically quote ARGs to be evaled later.
+# This function returns two values:
+#   i) func_quote_for_eval_result
+#      double-quoted, suitable for a subsequent eval
+#  ii) func_quote_for_eval_unquoted_result
+#      has all characters that are still active within double
+#      quotes backslashified.
+func_quote_for_eval ()
+{
+    $debug_cmd
+
+    func_quote_for_eval_unquoted_result=
+    func_quote_for_eval_result=
+    while test 0 -lt $#; do
+      case $1 in
+        *[\\\`\"\$]*)
+	  _G_unquoted_arg=`printf '%s\n' "$1" |$SED "$sed_quote_subst"` ;;
+        *)
+          _G_unquoted_arg=$1 ;;
+      esac
+      if test -n "$func_quote_for_eval_unquoted_result"; then
+	func_append func_quote_for_eval_unquoted_result " $_G_unquoted_arg"
+      else
+        func_append func_quote_for_eval_unquoted_result "$_G_unquoted_arg"
+      fi
+
+      case $_G_unquoted_arg in
+        # Double-quote args containing shell metacharacters to delay
+        # word splitting, command substitution and variable expansion
+        # for a subsequent eval.
+        # Many Bourne shells cannot handle close brackets correctly
+        # in scan sets, so we specify it separately.
+        *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
+          _G_quoted_arg=\"$_G_unquoted_arg\"
+          ;;
+        *)
+          _G_quoted_arg=$_G_unquoted_arg
+	  ;;
+      esac
+
+      if test -n "$func_quote_for_eval_result"; then
+	func_append func_quote_for_eval_result " $_G_quoted_arg"
+      else
+        func_append func_quote_for_eval_result "$_G_quoted_arg"
+      fi
+      shift
+    done
+}
+
+
+# func_quote_for_expand ARG
+# -------------------------
+# Aesthetically quote ARG to be evaled later; same as above,
+# but do not quote variable references.
+func_quote_for_expand ()
+{
+    $debug_cmd
+
+    case $1 in
+      *[\\\`\"]*)
+	_G_arg=`$ECHO "$1" | $SED \
+	    -e "$sed_double_quote_subst" -e "$sed_double_backslash"` ;;
+      *)
+        _G_arg=$1 ;;
+    esac
+
+    case $_G_arg in
+      # Double-quote args containing shell metacharacters to delay
+      # word splitting and command substitution for a subsequent eval.
+      # Many Bourne shells cannot handle close brackets correctly
+      # in scan sets, so we specify it separately.
+      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
+        _G_arg=\"$_G_arg\"
+        ;;
+    esac
+
+    func_quote_for_expand_result=$_G_arg
+}
+
+
+# func_stripname PREFIX SUFFIX NAME
+# ---------------------------------
+# strip PREFIX and SUFFIX from NAME, and store in func_stripname_result.
+# PREFIX and SUFFIX must not contain globbing or regex special
+# characters, hashes, percent signs, but SUFFIX may contain a leading
+# dot (in which case that matches only a dot).
+if test yes = "$_G_HAVE_XSI_OPS"; then
+  eval 'func_stripname ()
+  {
+    $debug_cmd
+
+    # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are
+    # positional parameters, so assign one to ordinary variable first.
+    func_stripname_result=$3
+    func_stripname_result=${func_stripname_result#"$1"}
+    func_stripname_result=${func_stripname_result%"$2"}
+  }'
+else
+  func_stripname ()
+  {
+    $debug_cmd
+
+    case $2 in
+      .*) func_stripname_result=`$ECHO "$3" | $SED -e "s%^$1%%" -e "s%\\\\$2\$%%"`;;
+      *)  func_stripname_result=`$ECHO "$3" | $SED -e "s%^$1%%" -e "s%$2\$%%"`;;
+    esac
+  }
+fi
+
+
+# func_show_eval CMD [FAIL_EXP]
+# -----------------------------
+# Unless opt_quiet is true, then output CMD.  Then, if opt_dryrun is
+# not true, evaluate CMD.  If the evaluation of CMD fails, and FAIL_EXP
+# is given, then evaluate it.
+func_show_eval ()
+{
+    $debug_cmd
+
+    _G_cmd=$1
+    _G_fail_exp=${2-':'}
+
+    func_quote_for_expand "$_G_cmd"
+    eval "func_notquiet $func_quote_for_expand_result"
+
+    $opt_dry_run || {
+      eval "$_G_cmd"
+      _G_status=$?
+      if test 0 -ne "$_G_status"; then
+	eval "(exit $_G_status); $_G_fail_exp"
+      fi
+    }
+}
+
+
+# func_show_eval_locale CMD [FAIL_EXP]
+# ------------------------------------
+# Unless opt_quiet is true, then output CMD.  Then, if opt_dryrun is
+# not true, evaluate CMD.  If the evaluation of CMD fails, and FAIL_EXP
+# is given, then evaluate it.  Use the saved locale for evaluation.
+func_show_eval_locale ()
+{
+    $debug_cmd
+
+    _G_cmd=$1
+    _G_fail_exp=${2-':'}
+
+    $opt_quiet || {
+      func_quote_for_expand "$_G_cmd"
+      eval "func_echo $func_quote_for_expand_result"
+    }
+
+    $opt_dry_run || {
+      eval "$_G_user_locale
+	    $_G_cmd"
+      _G_status=$?
+      eval "$_G_safe_locale"
+      if test 0 -ne "$_G_status"; then
+	eval "(exit $_G_status); $_G_fail_exp"
+      fi
+    }
+}
+
+
+# func_tr_sh
+# ----------
+# Turn $1 into a string suitable for a shell variable name.
+# Result is stored in $func_tr_sh_result.  All characters
+# not in the set a-zA-Z0-9_ are replaced with '_'. Further,
+# if $1 begins with a digit, a '_' is prepended as well.
+func_tr_sh ()
+{
+    $debug_cmd
+
+    case $1 in
+    [0-9]* | *[!a-zA-Z0-9_]*)
+      func_tr_sh_result=`$ECHO "$1" | $SED -e 's/^\([0-9]\)/_\1/' -e 's/[^a-zA-Z0-9_]/_/g'`
+      ;;
+    * )
+      func_tr_sh_result=$1
+      ;;
+    esac
+}
+
+
+# func_verbose ARG...
+# -------------------
+# Echo program name prefixed message in verbose mode only.
+func_verbose ()
+{
+    $debug_cmd
+
+    $opt_verbose && func_echo "$*"
+
+    :
+}
+
+
+# func_warn_and_continue ARG...
+# -----------------------------
+# Echo program name prefixed warning message to standard error.
+func_warn_and_continue ()
+{
+    $debug_cmd
+
+    $require_term_colors
+
+    func_echo_infix_1 "${tc_red}warning$tc_reset" "$*" >&2
+}
+
+
+# func_warning CATEGORY ARG...
+# ----------------------------
+# Echo program name prefixed warning message to standard error. Warning
+# messages can be filtered according to CATEGORY, where this function
+# elides messages where CATEGORY is not listed in the global variable
+# 'opt_warning_types'.
+func_warning ()
+{
+    $debug_cmd
+
+    # CATEGORY must be in the warning_categories list!
+    case " $warning_categories " in
+      *" $1 "*) ;;
+      *) func_internal_error "invalid warning category '$1'" ;;
+    esac
+
+    _G_category=$1
+    shift
+
+    case " $opt_warning_types " in
+      *" $_G_category "*) $warning_func ${1+"$@"} ;;
+    esac
+}
+
+
+# func_sort_ver VER1 VER2
+# -----------------------
+# 'sort -V' is not generally available.
+# Note this deviates from the version comparison in automake
+# in that it treats 1.5 < 1.5.0, and treats 1.4.4a < 1.4-p3a
+# but this should suffice as we won't be specifying old
+# version formats or redundant trailing .0 in bootstrap.conf.
+# If we did want full compatibility then we should probably
+# use m4_version_compare from autoconf.
+func_sort_ver ()
+{
+    $debug_cmd
+
+    printf '%s\n%s\n' "$1" "$2" \
+      | sort -t. -k 1,1n -k 2,2n -k 3,3n -k 4,4n -k 5,5n -k 6,6n -k 7,7n -k 8,8n -k 9,9n
+}
+
+# func_lt_ver PREV CURR
+# ---------------------
+# Return true if PREV and CURR are in the correct order according to
+# func_sort_ver, otherwise false.  Use it like this:
+#
+#  func_lt_ver "$prev_ver" "$proposed_ver" || func_fatal_error "..."
+func_lt_ver ()
+{
+    $debug_cmd
+
+    test "x$1" = x`func_sort_ver "$1" "$2" | $SED 1q`
+}
+
+
+# Local variables:
+# mode: shell-script
+# sh-indentation: 2
+# eval: (add-hook 'before-save-hook 'time-stamp)
+# time-stamp-pattern: "10/scriptversion=%:y-%02m-%02d.%02H; # UTC"
+# time-stamp-time-zone: "UTC"
+# End:
+#! /bin/sh
+
+# Set a version string for this script.
+scriptversion=2014-01-07.03; # UTC
+
+# A portable, pluggable option parser for Bourne shell.
+# Written by Gary V. Vaughan, 2010
+
+# Copyright (C) 2010-2015 Free Software Foundation, Inc.
+# This is free software; see the source for copying conditions.  There is NO
+# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# Please report bugs or propose patches to gary@gnu.org.
+
+
+## ------ ##
+## Usage. ##
+## ------ ##
+
+# This file is a library for parsing options in your shell scripts along
+# with assorted other useful supporting features that you can make use
+# of too.
+#
+# For the simplest scripts you might need only:
+#
+#   #!/bin/sh
+#   . relative/path/to/funclib.sh
+#   . relative/path/to/options-parser
+#   scriptversion=1.0
+#   func_options ${1+"$@"}
+#   eval set dummy "$func_options_result"; shift
+#   ...rest of your script...
+#
+# In order for the '--version' option to work, you will need to have a
+# suitably formatted comment like the one at the top of this file
+# starting with '# Written by ' and ending with '# warranty; '.
+#
+# For '-h' and '--help' to work, you will also need a one line
+# description of your script's purpose in a comment directly above the
+# '# Written by ' line, like the one at the top of this file.
+#
+# The default options also support '--debug', which will turn on shell
+# execution tracing (see the comment above debug_cmd below for another
+# use), and '--verbose' and the func_verbose function to allow your script
+# to display verbose messages only when your user has specified
+# '--verbose'.
+#
+# After sourcing this file, you can plug processing for additional
+# options by amending the variables from the 'Configuration' section
+# below, and following the instructions in the 'Option parsing'
+# section further down.
+
+## -------------- ##
+## Configuration. ##
+## -------------- ##
+
+# You should override these variables in your script after sourcing this
+# file so that they reflect the customisations you have added to the
+# option parser.
+
+# The usage line for option parsing errors and the start of '-h' and
+# '--help' output messages. You can embed shell variables for delayed
+# expansion at the time the message is displayed, but you will need to
+# quote other shell meta-characters carefully to prevent them being
+# expanded when the contents are evaled.
+usage='$progpath [OPTION]...'
+
+# Short help message in response to '-h' and '--help'.  Add to this or
+# override it after sourcing this library to reflect the full set of
+# options your script accepts.
+usage_message="\
+       --debug        enable verbose shell tracing
+   -W, --warnings=CATEGORY
+                      report the warnings falling in CATEGORY [all]
+   -v, --verbose      verbosely report processing
+       --version      print version information and exit
+   -h, --help         print short or long help message and exit
+"
+
+# Additional text appended to 'usage_message' in response to '--help'.
+long_help_message="
+Warning categories include:
+       'all'          show all warnings
+       'none'         turn off all the warnings
+       'error'        warnings are treated as fatal errors"
+
+# Help message printed before fatal option parsing errors.
+fatal_help="Try '\$progname --help' for more information."
+
+
+
+## ------------------------- ##
+## Hook function management. ##
+## ------------------------- ##
+
+# This section contains functions for adding, removing, and running hooks
+# to the main code.  A hook is just a named list of of function, that can
+# be run in order later on.
+
+# func_hookable FUNC_NAME
+# -----------------------
+# Declare that FUNC_NAME will run hooks added with
+# 'func_add_hook FUNC_NAME ...'.
+func_hookable ()
+{
+    $debug_cmd
+
+    func_append hookable_fns " $1"
+}
+
+
+# func_add_hook FUNC_NAME HOOK_FUNC
+# ---------------------------------
+# Request that FUNC_NAME call HOOK_FUNC before it returns.  FUNC_NAME must
+# first have been declared "hookable" by a call to 'func_hookable'.
+func_add_hook ()
+{
+    $debug_cmd
+
+    case " $hookable_fns " in
+      *" $1 "*) ;;
+      *) func_fatal_error "'$1' does not accept hook functions." ;;
+    esac
+
+    eval func_append ${1}_hooks '" $2"'
+}
+
+
+# func_remove_hook FUNC_NAME HOOK_FUNC
+# ------------------------------------
+# Remove HOOK_FUNC from the list of functions called by FUNC_NAME.
+func_remove_hook ()
+{
+    $debug_cmd
+
+    eval ${1}_hooks='`$ECHO "\$'$1'_hooks" |$SED "s| '$2'||"`'
+}
+
+
+# func_run_hooks FUNC_NAME [ARG]...
+# ---------------------------------
+# Run all hook functions registered to FUNC_NAME.
+# It is assumed that the list of hook functions contains nothing more
+# than a whitespace-delimited list of legal shell function names, and
+# no effort is wasted trying to catch shell meta-characters or preserve
+# whitespace.
+func_run_hooks ()
+{
+    $debug_cmd
+
+    case " $hookable_fns " in
+      *" $1 "*) ;;
+      *) func_fatal_error "'$1' does not support hook funcions.n" ;;
+    esac
+
+    eval _G_hook_fns=\$$1_hooks; shift
+
+    for _G_hook in $_G_hook_fns; do
+      eval $_G_hook '"$@"'
+
+      # store returned options list back into positional
+      # parameters for next 'cmd' execution.
+      eval _G_hook_result=\$${_G_hook}_result
+      eval set dummy "$_G_hook_result"; shift
+    done
+
+    func_quote_for_eval ${1+"$@"}
+    func_run_hooks_result=$func_quote_for_eval_result
+}
+
+
+
+## --------------- ##
+## Option parsing. ##
+## --------------- ##
+
+# In order to add your own option parsing hooks, you must accept the
+# full positional parameter list in your hook function, remove any
+# options that you action, and then pass back the remaining unprocessed
+# options in '<hooked_function_name>_result', escaped suitably for
+# 'eval'.  Like this:
+#
+#    my_options_prep ()
+#    {
+#        $debug_cmd
+#
+#        # Extend the existing usage message.
+#        usage_message=$usage_message'
+#      -s, --silent       don'\''t print informational messages
+#    '
+#
+#        func_quote_for_eval ${1+"$@"}
+#        my_options_prep_result=$func_quote_for_eval_result
+#    }
+#    func_add_hook func_options_prep my_options_prep
+#
+#
+#    my_silent_option ()
+#    {
+#        $debug_cmd
+#
+#        # Note that for efficiency, we parse as many options as we can
+#        # recognise in a loop before passing the remainder back to the
+#        # caller on the first unrecognised argument we encounter.
+#        while test $# -gt 0; do
+#          opt=$1; shift
+#          case $opt in
+#            --silent|-s) opt_silent=: ;;
+#            # Separate non-argument short options:
+#            -s*)         func_split_short_opt "$_G_opt"
+#                         set dummy "$func_split_short_opt_name" \
+#                             "-$func_split_short_opt_arg" ${1+"$@"}
+#                         shift
+#                         ;;
+#            *)            set dummy "$_G_opt" "$*"; shift; break ;;
+#          esac
+#        done
+#
+#        func_quote_for_eval ${1+"$@"}
+#        my_silent_option_result=$func_quote_for_eval_result
+#    }
+#    func_add_hook func_parse_options my_silent_option
+#
+#
+#    my_option_validation ()
+#    {
+#        $debug_cmd
+#
+#        $opt_silent && $opt_verbose && func_fatal_help "\
+#    '--silent' and '--verbose' options are mutually exclusive."
+#
+#        func_quote_for_eval ${1+"$@"}
+#        my_option_validation_result=$func_quote_for_eval_result
+#    }
+#    func_add_hook func_validate_options my_option_validation
+#
+# You'll alse need to manually amend $usage_message to reflect the extra
+# options you parse.  It's preferable to append if you can, so that
+# multiple option parsing hooks can be added safely.
+
+
+# func_options [ARG]...
+# ---------------------
+# All the functions called inside func_options are hookable. See the
+# individual implementations for details.
+func_hookable func_options
+func_options ()
+{
+    $debug_cmd
+
+    func_options_prep ${1+"$@"}
+    eval func_parse_options \
+        ${func_options_prep_result+"$func_options_prep_result"}
+    eval func_validate_options \
+        ${func_parse_options_result+"$func_parse_options_result"}
+
+    eval func_run_hooks func_options \
+        ${func_validate_options_result+"$func_validate_options_result"}
+
+    # save modified positional parameters for caller
+    func_options_result=$func_run_hooks_result
+}
+
+
+# func_options_prep [ARG]...
+# --------------------------
+# All initialisations required before starting the option parse loop.
+# Note that when calling hook functions, we pass through the list of
+# positional parameters.  If a hook function modifies that list, and
+# needs to propogate that back to rest of this script, then the complete
+# modified list must be put in 'func_run_hooks_result' before
+# returning.
+func_hookable func_options_prep
+func_options_prep ()
+{
+    $debug_cmd
+
+    # Option defaults:
+    opt_verbose=false
+    opt_warning_types=
+
+    func_run_hooks func_options_prep ${1+"$@"}
+
+    # save modified positional parameters for caller
+    func_options_prep_result=$func_run_hooks_result
+}
+
+
+# func_parse_options [ARG]...
+# ---------------------------
+# The main option parsing loop.
+func_hookable func_parse_options
+func_parse_options ()
+{
+    $debug_cmd
+
+    func_parse_options_result=
+
+    # this just eases exit handling
+    while test $# -gt 0; do
+      # Defer to hook functions for initial option parsing, so they
+      # get priority in the event of reusing an option name.
+      func_run_hooks func_parse_options ${1+"$@"}
+
+      # Adjust func_parse_options positional parameters to match
+      eval set dummy "$func_run_hooks_result"; shift
+
+      # Break out of the loop if we already parsed every option.
+      test $# -gt 0 || break
+
+      _G_opt=$1
+      shift
+      case $_G_opt in
+        --debug|-x)   debug_cmd='set -x'
+                      func_echo "enabling shell trace mode"
+                      $debug_cmd
+                      ;;
+
+        --no-warnings|--no-warning|--no-warn)
+                      set dummy --warnings none ${1+"$@"}
+                      shift
+		      ;;
+
+        --warnings|--warning|-W)
+                      test $# = 0 && func_missing_arg $_G_opt && break
+                      case " $warning_categories $1" in
+                        *" $1 "*)
+                          # trailing space prevents matching last $1 above
+                          func_append_uniq opt_warning_types " $1"
+                          ;;
+                        *all)
+                          opt_warning_types=$warning_categories
+                          ;;
+                        *none)
+                          opt_warning_types=none
+                          warning_func=:
+                          ;;
+                        *error)
+                          opt_warning_types=$warning_categories
+                          warning_func=func_fatal_error
+                          ;;
+                        *)
+                          func_fatal_error \
+                             "unsupported warning category: '$1'"
+                          ;;
+                      esac
+                      shift
+                      ;;
+
+        --verbose|-v) opt_verbose=: ;;
+        --version)    func_version ;;
+        -\?|-h)       func_usage ;;
+        --help)       func_help ;;
+
+	# Separate optargs to long options (plugins may need this):
+	--*=*)        func_split_equals "$_G_opt"
+	              set dummy "$func_split_equals_lhs" \
+                          "$func_split_equals_rhs" ${1+"$@"}
+                      shift
+                      ;;
+
+       # Separate optargs to short options:
+        -W*)
+                      func_split_short_opt "$_G_opt"
+                      set dummy "$func_split_short_opt_name" \
+                          "$func_split_short_opt_arg" ${1+"$@"}
+                      shift
+                      ;;
+
+        # Separate non-argument short options:
+        -\?*|-h*|-v*|-x*)
+                      func_split_short_opt "$_G_opt"
+                      set dummy "$func_split_short_opt_name" \
+                          "-$func_split_short_opt_arg" ${1+"$@"}
+                      shift
+                      ;;
+
+        --)           break ;;
+        -*)           func_fatal_help "unrecognised option: '$_G_opt'" ;;
+        *)            set dummy "$_G_opt" ${1+"$@"}; shift; break ;;
+      esac
+    done
+
+    # save modified positional parameters for caller
+    func_quote_for_eval ${1+"$@"}
+    func_parse_options_result=$func_quote_for_eval_result
+}
+
+
+# func_validate_options [ARG]...
+# ------------------------------
+# Perform any sanity checks on option settings and/or unconsumed
+# arguments.
+func_hookable func_validate_options
+func_validate_options ()
+{
+    $debug_cmd
+
+    # Display all warnings if -W was not given.
+    test -n "$opt_warning_types" || opt_warning_types=" $warning_categories"
+
+    func_run_hooks func_validate_options ${1+"$@"}
+
+    # Bail if the options were screwed!
+    $exit_cmd $EXIT_FAILURE
+
+    # save modified positional parameters for caller
+    func_validate_options_result=$func_run_hooks_result
+}
+
+
+
+## ----------------- ##
+## Helper functions. ##
+## ----------------- ##
+
+# This section contains the helper functions used by the rest of the
+# hookable option parser framework in ascii-betical order.
+
+
+# func_fatal_help ARG...
+# ----------------------
+# Echo program name prefixed message to standard error, followed by
+# a help hint, and exit.
+func_fatal_help ()
+{
+    $debug_cmd
+
+    eval \$ECHO \""Usage: $usage"\"
+    eval \$ECHO \""$fatal_help"\"
+    func_error ${1+"$@"}
+    exit $EXIT_FAILURE
+}
+
+
+# func_help
+# ---------
+# Echo long help message to standard output and exit.
+func_help ()
+{
+    $debug_cmd
+
+    func_usage_message
+    $ECHO "$long_help_message"
+    exit 0
+}
+
+
+# func_missing_arg ARGNAME
+# ------------------------
+# Echo program name prefixed message to standard error and set global
+# exit_cmd.
+func_missing_arg ()
+{
+    $debug_cmd
+
+    func_error "Missing argument for '$1'."
+    exit_cmd=exit
+}
+
+
+# func_split_equals STRING
+# ------------------------
+# Set func_split_equals_lhs and func_split_equals_rhs shell variables after
+# splitting STRING at the '=' sign.
+test -z "$_G_HAVE_XSI_OPS" \
+    && (eval 'x=a/b/c;
+      test 5aa/bb/cc = "${#x}${x%%/*}${x%/*}${x#*/}${x##*/}"') 2>/dev/null \
+    && _G_HAVE_XSI_OPS=yes
+
+if test yes = "$_G_HAVE_XSI_OPS"
+then
+  # This is an XSI compatible shell, allowing a faster implementation...
+  eval 'func_split_equals ()
+  {
+      $debug_cmd
+
+      func_split_equals_lhs=${1%%=*}
+      func_split_equals_rhs=${1#*=}
+      test "x$func_split_equals_lhs" = "x$1" \
+        && func_split_equals_rhs=
+  }'
+else
+  # ...otherwise fall back to using expr, which is often a shell builtin.
+  func_split_equals ()
+  {
+      $debug_cmd
+
+      func_split_equals_lhs=`expr "x$1" : 'x\([^=]*\)'`
+      func_split_equals_rhs=
+      test "x$func_split_equals_lhs" = "x$1" \
+        || func_split_equals_rhs=`expr "x$1" : 'x[^=]*=\(.*\)$'`
+  }
+fi #func_split_equals
+
+
+# func_split_short_opt SHORTOPT
+# -----------------------------
+# Set func_split_short_opt_name and func_split_short_opt_arg shell
+# variables after splitting SHORTOPT after the 2nd character.
+if test yes = "$_G_HAVE_XSI_OPS"
+then
+  # This is an XSI compatible shell, allowing a faster implementation...
+  eval 'func_split_short_opt ()
+  {
+      $debug_cmd
+
+      func_split_short_opt_arg=${1#??}
+      func_split_short_opt_name=${1%"$func_split_short_opt_arg"}
+  }'
+else
+  # ...otherwise fall back to using expr, which is often a shell builtin.
+  func_split_short_opt ()
+  {
+      $debug_cmd
+
+      func_split_short_opt_name=`expr "x$1" : 'x-\(.\)'`
+      func_split_short_opt_arg=`expr "x$1" : 'x-.\(.*\)$'`
+  }
+fi #func_split_short_opt
+
+
+# func_usage
+# ----------
+# Echo short help message to standard output and exit.
+func_usage ()
+{
+    $debug_cmd
+
+    func_usage_message
+    $ECHO "Run '$progname --help |${PAGER-more}' for full usage"
+    exit 0
+}
+
+
+# func_usage_message
+# ------------------
+# Echo short help message to standard output.
+func_usage_message ()
+{
+    $debug_cmd
+
+    eval \$ECHO \""Usage: $usage"\"
+    echo
+    $SED -n 's|^# ||
+        /^Written by/{
+          x;p;x
+        }
+	h
+	/^Written by/q' < "$progpath"
+    echo
+    eval \$ECHO \""$usage_message"\"
+}
+
+
+# func_version
+# ------------
+# Echo version message to standard output and exit.
+func_version ()
+{
+    $debug_cmd
+
+    printf '%s\n' "$progname $scriptversion"
+    $SED -n '
+        /(C)/!b go
+        :more
+        /\./!{
+          N
+          s|\n# | |
+          b more
+        }
+        :go
+        /^# Written by /,/# warranty; / {
+          s|^# ||
+          s|^# *$||
+          s|\((C)\)[ 0-9,-]*[ ,-]\([1-9][0-9]* \)|\1 \2|
+          p
+        }
+        /^# Written by / {
+          s|^# ||
+          p
+        }
+        /^warranty; /q' < "$progpath"
+
+    exit $?
+}
+
+
+# Local variables:
+# mode: shell-script
+# sh-indentation: 2
+# eval: (add-hook 'before-save-hook 'time-stamp)
+# time-stamp-pattern: "10/scriptversion=%:y-%02m-%02d.%02H; # UTC"
+# time-stamp-time-zone: "UTC"
+# End:
+
+# Set a version string.
+scriptversion='(GNU libtool) 2.4.6'
+
+
+# func_echo ARG...
+# ----------------
+# Libtool also displays the current mode in messages, so override
+# funclib.sh func_echo with this custom definition.
+func_echo ()
+{
+    $debug_cmd
+
+    _G_message=$*
+
+    func_echo_IFS=$IFS
+    IFS=$nl
+    for _G_line in $_G_message; do
+      IFS=$func_echo_IFS
+      $ECHO "$progname${opt_mode+: $opt_mode}: $_G_line"
+    done
+    IFS=$func_echo_IFS
+}
+
+
+# func_warning ARG...
+# -------------------
+# Libtool warnings are not categorized, so override funclib.sh
+# func_warning with this simpler definition.
+func_warning ()
+{
+    $debug_cmd
+
+    $warning_func ${1+"$@"}
+}
+
+
+## ---------------- ##
+## Options parsing. ##
+## ---------------- ##
+
+# Hook in the functions to make sure our own options are parsed during
+# the option parsing loop.
+
+usage='$progpath [OPTION]... [MODE-ARG]...'
+
+# Short help message in response to '-h'.
+usage_message="Options:
+       --config             show all configuration variables
+       --debug              enable verbose shell tracing
+   -n, --dry-run            display commands without modifying any files
+       --features           display basic configuration information and exit
+       --mode=MODE          use operation mode MODE
+       --no-warnings        equivalent to '-Wnone'
+       --preserve-dup-deps  don't remove duplicate dependency libraries
+       --quiet, --silent    don't print informational messages
+       --tag=TAG            use configuration variables from tag TAG
+   -v, --verbose            print more informational messages than default
+       --version            print version information
+   -W, --warnings=CATEGORY  report the warnings falling in CATEGORY [all]
+   -h, --help, --help-all   print short, long, or detailed help message
+"
+
+# Additional text appended to 'usage_message' in response to '--help'.
+func_help ()
+{
+    $debug_cmd
+
+    func_usage_message
+    $ECHO "$long_help_message
+
+MODE must be one of the following:
+
+       clean           remove files from the build directory
+       compile         compile a source file into a libtool object
+       execute         automatically set library path, then run a program
+       finish          complete the installation of libtool libraries
+       install         install libraries or executables
+       link            create a library or an executable
+       uninstall       remove libraries from an installed directory
+
+MODE-ARGS vary depending on the MODE.  When passed as first option,
+'--mode=MODE' may be abbreviated as 'MODE' or a unique abbreviation of that.
+Try '$progname --help --mode=MODE' for a more detailed description of MODE.
+
+When reporting a bug, please describe a test case to reproduce it and
+include the following information:
+
+       host-triplet:   $host
+       shell:          $SHELL
+       compiler:       $LTCC
+       compiler flags: $LTCFLAGS
+       linker:         $LD (gnu? $with_gnu_ld)
+       version:        $progname (GNU libtool) 2.4.6
+       automake:       `($AUTOMAKE --version) 2>/dev/null |$SED 1q`
+       autoconf:       `($AUTOCONF --version) 2>/dev/null |$SED 1q`
+
+Report bugs to <bug-libtool@gnu.org>.
+GNU libtool home page: <http://www.gnu.org/s/libtool/>.
+General help using GNU software: <http://www.gnu.org/gethelp/>."
+    exit 0
+}
+
+
+# func_lo2o OBJECT-NAME
+# ---------------------
+# Transform OBJECT-NAME from a '.lo' suffix to the platform specific
+# object suffix.
+
+lo2o=s/\\.lo\$/.$objext/
+o2lo=s/\\.$objext\$/.lo/
+
+if test yes = "$_G_HAVE_XSI_OPS"; then
+  eval 'func_lo2o ()
+  {
+    case $1 in
+      *.lo) func_lo2o_result=${1%.lo}.$objext ;;
+      *   ) func_lo2o_result=$1               ;;
+    esac
+  }'
+
+  # func_xform LIBOBJ-OR-SOURCE
+  # ---------------------------
+  # Transform LIBOBJ-OR-SOURCE from a '.o' or '.c' (or otherwise)
+  # suffix to a '.lo' libtool-object suffix.
+  eval 'func_xform ()
+  {
+    func_xform_result=${1%.*}.lo
+  }'
+else
+  # ...otherwise fall back to using sed.
+  func_lo2o ()
+  {
+    func_lo2o_result=`$ECHO "$1" | $SED "$lo2o"`
+  }
+
+  func_xform ()
+  {
+    func_xform_result=`$ECHO "$1" | $SED 's|\.[^.]*$|.lo|'`
+  }
+fi
+
+
+# func_fatal_configuration ARG...
+# -------------------------------
+# Echo program name prefixed message to standard error, followed by
+# a configuration failure hint, and exit.
+func_fatal_configuration ()
+{
+    func__fatal_error ${1+"$@"} \
+      "See the $PACKAGE documentation for more information." \
+      "Fatal configuration error."
+}
+
+
+# func_config
+# -----------
+# Display the configuration for all the tags in this script.
+func_config ()
+{
+    re_begincf='^# ### BEGIN LIBTOOL'
+    re_endcf='^# ### END LIBTOOL'
+
+    # Default configuration.
+    $SED "1,/$re_begincf CONFIG/d;/$re_endcf CONFIG/,\$d" < "$progpath"
+
+    # Now print the configurations for the tags.
+    for tagname in $taglist; do
+      $SED -n "/$re_begincf TAG CONFIG: $tagname\$/,/$re_endcf TAG CONFIG: $tagname\$/p" < "$progpath"
+    done
+
+    exit $?
+}
+
+
+# func_features
+# -------------
+# Display the features supported by this script.
+func_features ()
+{
+    echo "host: $host"
+    if test yes = "$build_libtool_libs"; then
+      echo "enable shared libraries"
+    else
+      echo "disable shared libraries"
+    fi
+    if test yes = "$build_old_libs"; then
+      echo "enable static libraries"
+    else
+      echo "disable static libraries"
+    fi
+
+    exit $?
+}
+
+
+# func_enable_tag TAGNAME
+# -----------------------
+# Verify that TAGNAME is valid, and either flag an error and exit, or
+# enable the TAGNAME tag.  We also add TAGNAME to the global $taglist
+# variable here.
+func_enable_tag ()
+{
+    # Global variable:
+    tagname=$1
+
+    re_begincf="^# ### BEGIN LIBTOOL TAG CONFIG: $tagname\$"
+    re_endcf="^# ### END LIBTOOL TAG CONFIG: $tagname\$"
+    sed_extractcf=/$re_begincf/,/$re_endcf/p
+
+    # Validate tagname.
+    case $tagname in
+      *[!-_A-Za-z0-9,/]*)
+        func_fatal_error "invalid tag name: $tagname"
+        ;;
+    esac
+
+    # Don't test for the "default" C tag, as we know it's
+    # there but not specially marked.
+    case $tagname in
+        CC) ;;
+    *)
+        if $GREP "$re_begincf" "$progpath" >/dev/null 2>&1; then
+	  taglist="$taglist $tagname"
+
+	  # Evaluate the configuration.  Be careful to quote the path
+	  # and the sed script, to avoid splitting on whitespace, but
+	  # also don't use non-portable quotes within backquotes within
+	  # quotes we have to do it in 2 steps:
+	  extractedcf=`$SED -n -e "$sed_extractcf" < "$progpath"`
+	  eval "$extractedcf"
+        else
+	  func_error "ignoring unknown tag $tagname"
+        fi
+        ;;
+    esac
+}
+
+
+# func_check_version_match
+# ------------------------
+# Ensure that we are using m4 macros, and libtool script from the same
+# release of libtool.
+func_check_version_match ()
+{
+    if test "$package_revision" != "$macro_revision"; then
+      if test "$VERSION" != "$macro_version"; then
+        if test -z "$macro_version"; then
+          cat >&2 <<_LT_EOF
+$progname: Version mismatch error.  This is $PACKAGE $VERSION, but the
+$progname: definition of this LT_INIT comes from an older release.
+$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION
+$progname: and run autoconf again.
+_LT_EOF
+        else
+          cat >&2 <<_LT_EOF
+$progname: Version mismatch error.  This is $PACKAGE $VERSION, but the
+$progname: definition of this LT_INIT comes from $PACKAGE $macro_version.
+$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION
+$progname: and run autoconf again.
+_LT_EOF
+        fi
+      else
+        cat >&2 <<_LT_EOF
+$progname: Version mismatch error.  This is $PACKAGE $VERSION, revision $package_revision,
+$progname: but the definition of this LT_INIT comes from revision $macro_revision.
+$progname: You should recreate aclocal.m4 with macros from revision $package_revision
+$progname: of $PACKAGE $VERSION and run autoconf again.
+_LT_EOF
+      fi
+
+      exit $EXIT_MISMATCH
+    fi
+}
+
+
+# libtool_options_prep [ARG]...
+# -----------------------------
+# Preparation for options parsed by libtool.
+libtool_options_prep ()
+{
+    $debug_mode
+
+    # Option defaults:
+    opt_config=false
+    opt_dlopen=
+    opt_dry_run=false
+    opt_help=false
+    opt_mode=
+    opt_preserve_dup_deps=false
+    opt_quiet=false
+
+    nonopt=
+    preserve_args=
+
+    # Shorthand for --mode=foo, only valid as the first argument
+    case $1 in
+    clean|clea|cle|cl)
+      shift; set dummy --mode clean ${1+"$@"}; shift
+      ;;
+    compile|compil|compi|comp|com|co|c)
+      shift; set dummy --mode compile ${1+"$@"}; shift
+      ;;
+    execute|execut|execu|exec|exe|ex|e)
+      shift; set dummy --mode execute ${1+"$@"}; shift
+      ;;
+    finish|finis|fini|fin|fi|f)
+      shift; set dummy --mode finish ${1+"$@"}; shift
+      ;;
+    install|instal|insta|inst|ins|in|i)
+      shift; set dummy --mode install ${1+"$@"}; shift
+      ;;
+    link|lin|li|l)
+      shift; set dummy --mode link ${1+"$@"}; shift
+      ;;
+    uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u)
+      shift; set dummy --mode uninstall ${1+"$@"}; shift
+      ;;
+    esac
+
+    # Pass back the list of options.
+    func_quote_for_eval ${1+"$@"}
+    libtool_options_prep_result=$func_quote_for_eval_result
+}
+func_add_hook func_options_prep libtool_options_prep
+
+
+# libtool_parse_options [ARG]...
+# ---------------------------------
+# Provide handling for libtool specific options.
+libtool_parse_options ()
+{
+    $debug_cmd
+
+    # Perform our own loop to consume as many options as possible in
+    # each iteration.
+    while test $# -gt 0; do
+      _G_opt=$1
+      shift
+      case $_G_opt in
+        --dry-run|--dryrun|-n)
+                        opt_dry_run=:
+                        ;;
+
+        --config)       func_config ;;
+
+        --dlopen|-dlopen)
+                        opt_dlopen="${opt_dlopen+$opt_dlopen
+}$1"
+                        shift
+                        ;;
+
+        --preserve-dup-deps)
+                        opt_preserve_dup_deps=: ;;
+
+        --features)     func_features ;;
+
+        --finish)       set dummy --mode finish ${1+"$@"}; shift ;;
+
+        --help)         opt_help=: ;;
+
+        --help-all)     opt_help=': help-all' ;;
+
+        --mode)         test $# = 0 && func_missing_arg $_G_opt && break
+                        opt_mode=$1
+                        case $1 in
+                          # Valid mode arguments:
+                          clean|compile|execute|finish|install|link|relink|uninstall) ;;
+
+                          # Catch anything else as an error
+                          *) func_error "invalid argument for $_G_opt"
+                             exit_cmd=exit
+                             break
+                             ;;
+                        esac
+                        shift
+                        ;;
+
+        --no-silent|--no-quiet)
+                        opt_quiet=false
+                        func_append preserve_args " $_G_opt"
+                        ;;
+
+        --no-warnings|--no-warning|--no-warn)
+                        opt_warning=false
+                        func_append preserve_args " $_G_opt"
+                        ;;
+
+        --no-verbose)
+                        opt_verbose=false
+                        func_append preserve_args " $_G_opt"
+                        ;;
+
+        --silent|--quiet)
+                        opt_quiet=:
+                        opt_verbose=false
+                        func_append preserve_args " $_G_opt"
+                        ;;
+
+        --tag)          test $# = 0 && func_missing_arg $_G_opt && break
+                        opt_tag=$1
+                        func_append preserve_args " $_G_opt $1"
+                        func_enable_tag "$1"
+                        shift
+                        ;;
+
+        --verbose|-v)   opt_quiet=false
+                        opt_verbose=:
+                        func_append preserve_args " $_G_opt"
+                        ;;
+
+	# An option not handled by this hook function:
+        *)		set dummy "$_G_opt" ${1+"$@"};	shift; break  ;;
+      esac
+    done
+
+
+    # save modified positional parameters for caller
+    func_quote_for_eval ${1+"$@"}
+    libtool_parse_options_result=$func_quote_for_eval_result
+}
+func_add_hook func_parse_options libtool_parse_options
+
+
+
+# libtool_validate_options [ARG]...
+# ---------------------------------
+# Perform any sanity checks on option settings and/or unconsumed
+# arguments.
+libtool_validate_options ()
+{
+    # save first non-option argument
+    if test 0 -lt $#; then
+      nonopt=$1
+      shift
+    fi
+
+    # preserve --debug
+    test : = "$debug_cmd" || func_append preserve_args " --debug"
+
+    case $host in
+      # Solaris2 added to fix http://debbugs.gnu.org/cgi/bugreport.cgi?bug=16452
+      # see also: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59788
+      *cygwin* | *mingw* | *pw32* | *cegcc* | *solaris2* | *os2*)
+        # don't eliminate duplications in $postdeps and $predeps
+        opt_duplicate_compiler_generated_deps=:
+        ;;
+      *)
+        opt_duplicate_compiler_generated_deps=$opt_preserve_dup_deps
+        ;;
+    esac
+
+    $opt_help || {
+      # Sanity checks first:
+      func_check_version_match
+
+      test yes != "$build_libtool_libs" \
+        && test yes != "$build_old_libs" \
+        && func_fatal_configuration "not configured to build any kind of library"
+
+      # Darwin sucks
+      eval std_shrext=\"$shrext_cmds\"
+
+      # Only execute mode is allowed to have -dlopen flags.
+      if test -n "$opt_dlopen" && test execute != "$opt_mode"; then
+        func_error "unrecognized option '-dlopen'"
+        $ECHO "$help" 1>&2
+        exit $EXIT_FAILURE
+      fi
+
+      # Change the help message to a mode-specific one.
+      generic_help=$help
+      help="Try '$progname --help --mode=$opt_mode' for more information."
+    }
+
+    # Pass back the unparsed argument list
+    func_quote_for_eval ${1+"$@"}
+    libtool_validate_options_result=$func_quote_for_eval_result
+}
+func_add_hook func_validate_options libtool_validate_options
+
+
+# Process options as early as possible so that --help and --version
+# can return quickly.
+func_options ${1+"$@"}
+eval set dummy "$func_options_result"; shift
+
+
+
+## ----------- ##
+##    Main.    ##
+## ----------- ##
+
+magic='%%%MAGIC variable%%%'
+magic_exe='%%%MAGIC EXE variable%%%'
+
+# Global variables.
+extracted_archives=
+extracted_serial=0
+
+# If this variable is set in any of the actions, the command in it
+# will be execed at the end.  This prevents here-documents from being
+# left over by shells.
+exec_cmd=
+
+
+# A function that is used when there is no print builtin or printf.
+func_fallback_echo ()
+{
+  eval 'cat <<_LTECHO_EOF
+$1
+_LTECHO_EOF'
+}
+
+# func_generated_by_libtool
+# True iff stdin has been generated by Libtool. This function is only
+# a basic sanity check; it will hardly flush out determined imposters.
+func_generated_by_libtool_p ()
+{
+  $GREP "^# Generated by .*$PACKAGE" > /dev/null 2>&1
+}
+
+# func_lalib_p file
+# True iff FILE is a libtool '.la' library or '.lo' object file.
+# This function is only a basic sanity check; it will hardly flush out
+# determined imposters.
+func_lalib_p ()
+{
+    test -f "$1" &&
+      $SED -e 4q "$1" 2>/dev/null | func_generated_by_libtool_p
+}
+
+# func_lalib_unsafe_p file
+# True iff FILE is a libtool '.la' library or '.lo' object file.
+# This function implements the same check as func_lalib_p without
+# resorting to external programs.  To this end, it redirects stdin and
+# closes it afterwards, without saving the original file descriptor.
+# As a safety measure, use it only where a negative result would be
+# fatal anyway.  Works if 'file' does not exist.
+func_lalib_unsafe_p ()
+{
+    lalib_p=no
+    if test -f "$1" && test -r "$1" && exec 5<&0 <"$1"; then
+	for lalib_p_l in 1 2 3 4
+	do
+	    read lalib_p_line
+	    case $lalib_p_line in
+		\#\ Generated\ by\ *$PACKAGE* ) lalib_p=yes; break;;
+	    esac
+	done
+	exec 0<&5 5<&-
+    fi
+    test yes = "$lalib_p"
+}
+
+# func_ltwrapper_script_p file
+# True iff FILE is a libtool wrapper script
+# This function is only a basic sanity check; it will hardly flush out
+# determined imposters.
+func_ltwrapper_script_p ()
+{
+    test -f "$1" &&
+      $lt_truncate_bin < "$1" 2>/dev/null | func_generated_by_libtool_p
+}
+
+# func_ltwrapper_executable_p file
+# True iff FILE is a libtool wrapper executable
+# This function is only a basic sanity check; it will hardly flush out
+# determined imposters.
+func_ltwrapper_executable_p ()
+{
+    func_ltwrapper_exec_suffix=
+    case $1 in
+    *.exe) ;;
+    *) func_ltwrapper_exec_suffix=.exe ;;
+    esac
+    $GREP "$magic_exe" "$1$func_ltwrapper_exec_suffix" >/dev/null 2>&1
+}
+
+# func_ltwrapper_scriptname file
+# Assumes file is an ltwrapper_executable
+# uses $file to determine the appropriate filename for a
+# temporary ltwrapper_script.
+func_ltwrapper_scriptname ()
+{
+    func_dirname_and_basename "$1" "" "."
+    func_stripname '' '.exe' "$func_basename_result"
+    func_ltwrapper_scriptname_result=$func_dirname_result/$objdir/${func_stripname_result}_ltshwrapper
+}
+
+# func_ltwrapper_p file
+# True iff FILE is a libtool wrapper script or wrapper executable
+# This function is only a basic sanity check; it will hardly flush out
+# determined imposters.
+func_ltwrapper_p ()
+{
+    func_ltwrapper_script_p "$1" || func_ltwrapper_executable_p "$1"
+}
+
+
+# func_execute_cmds commands fail_cmd
+# Execute tilde-delimited COMMANDS.
+# If FAIL_CMD is given, eval that upon failure.
+# FAIL_CMD may read-access the current command in variable CMD!
+func_execute_cmds ()
+{
+    $debug_cmd
+
+    save_ifs=$IFS; IFS='~'
+    for cmd in $1; do
+      IFS=$sp$nl
+      eval cmd=\"$cmd\"
+      IFS=$save_ifs
+      func_show_eval "$cmd" "${2-:}"
+    done
+    IFS=$save_ifs
+}
+
+
+# func_source file
+# Source FILE, adding directory component if necessary.
+# Note that it is not necessary on cygwin/mingw to append a dot to
+# FILE even if both FILE and FILE.exe exist: automatic-append-.exe
+# behavior happens only for exec(3), not for open(2)!  Also, sourcing
+# 'FILE.' does not work on cygwin managed mounts.
+func_source ()
+{
+    $debug_cmd
+
+    case $1 in
+    */* | *\\*)	. "$1" ;;
+    *)		. "./$1" ;;
+    esac
+}
+
+
+# func_resolve_sysroot PATH
+# Replace a leading = in PATH with a sysroot.  Store the result into
+# func_resolve_sysroot_result
+func_resolve_sysroot ()
+{
+  func_resolve_sysroot_result=$1
+  case $func_resolve_sysroot_result in
+  =*)
+    func_stripname '=' '' "$func_resolve_sysroot_result"
+    func_resolve_sysroot_result=$lt_sysroot$func_stripname_result
+    ;;
+  esac
+}
+
+# func_replace_sysroot PATH
+# If PATH begins with the sysroot, replace it with = and
+# store the result into func_replace_sysroot_result.
+func_replace_sysroot ()
+{
+  case $lt_sysroot:$1 in
+  ?*:"$lt_sysroot"*)
+    func_stripname "$lt_sysroot" '' "$1"
+    func_replace_sysroot_result='='$func_stripname_result
+    ;;
+  *)
+    # Including no sysroot.
+    func_replace_sysroot_result=$1
+    ;;
+  esac
+}
+
+# func_infer_tag arg
+# Infer tagged configuration to use if any are available and
+# if one wasn't chosen via the "--tag" command line option.
+# Only attempt this if the compiler in the base compile
+# command doesn't match the default compiler.
+# arg is usually of the form 'gcc ...'
+func_infer_tag ()
+{
+    $debug_cmd
+
+    if test -n "$available_tags" && test -z "$tagname"; then
+      CC_quoted=
+      for arg in $CC; do
+	func_append_quoted CC_quoted "$arg"
+      done
+      CC_expanded=`func_echo_all $CC`
+      CC_quoted_expanded=`func_echo_all $CC_quoted`
+      case $@ in
+      # Blanks in the command may have been stripped by the calling shell,
+      # but not from the CC environment variable when configure was run.
+      " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \
+      " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) ;;
+      # Blanks at the start of $base_compile will cause this to fail
+      # if we don't check for them as well.
+      *)
+	for z in $available_tags; do
+	  if $GREP "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then
+	    # Evaluate the configuration.
+	    eval "`$SED -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`"
+	    CC_quoted=
+	    for arg in $CC; do
+	      # Double-quote args containing other shell metacharacters.
+	      func_append_quoted CC_quoted "$arg"
+	    done
+	    CC_expanded=`func_echo_all $CC`
+	    CC_quoted_expanded=`func_echo_all $CC_quoted`
+	    case "$@ " in
+	    " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \
+	    " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*)
+	      # The compiler in the base compile command matches
+	      # the one in the tagged configuration.
+	      # Assume this is the tagged configuration we want.
+	      tagname=$z
+	      break
+	      ;;
+	    esac
+	  fi
+	done
+	# If $tagname still isn't set, then no tagged configuration
+	# was found and let the user know that the "--tag" command
+	# line option must be used.
+	if test -z "$tagname"; then
+	  func_echo "unable to infer tagged configuration"
+	  func_fatal_error "specify a tag with '--tag'"
+#	else
+#	  func_verbose "using $tagname tagged configuration"
+	fi
+	;;
+      esac
+    fi
+}
+
+
+
+# func_write_libtool_object output_name pic_name nonpic_name
+# Create a libtool object file (analogous to a ".la" file),
+# but don't create it if we're doing a dry run.
+func_write_libtool_object ()
+{
+    write_libobj=$1
+    if test yes = "$build_libtool_libs"; then
+      write_lobj=\'$2\'
+    else
+      write_lobj=none
+    fi
+
+    if test yes = "$build_old_libs"; then
+      write_oldobj=\'$3\'
+    else
+      write_oldobj=none
+    fi
+
+    $opt_dry_run || {
+      cat >${write_libobj}T <<EOF
+# $write_libobj - a libtool object file
+# Generated by $PROGRAM (GNU $PACKAGE) $VERSION
+#
+# Please DO NOT delete this file!
+# It is necessary for linking the library.
+
+# Name of the PIC object.
+pic_object=$write_lobj
+
+# Name of the non-PIC object
+non_pic_object=$write_oldobj
+
+EOF
+      $MV "${write_libobj}T" "$write_libobj"
+    }
+}
+
+
+##################################################
+# FILE NAME AND PATH CONVERSION HELPER FUNCTIONS #
+##################################################
+
+# func_convert_core_file_wine_to_w32 ARG
+# Helper function used by file name conversion functions when $build is *nix,
+# and $host is mingw, cygwin, or some other w32 environment. Relies on a
+# correctly configured wine environment available, with the winepath program
+# in $build's $PATH.
+#
+# ARG is the $build file name to be converted to w32 format.
+# Result is available in $func_convert_core_file_wine_to_w32_result, and will
+# be empty on error (or when ARG is empty)
+func_convert_core_file_wine_to_w32 ()
+{
+  $debug_cmd
+
+  func_convert_core_file_wine_to_w32_result=$1
+  if test -n "$1"; then
+    # Unfortunately, winepath does not exit with a non-zero error code, so we
+    # are forced to check the contents of stdout. On the other hand, if the
+    # command is not found, the shell will set an exit code of 127 and print
+    # *an error message* to stdout. So we must check for both error code of
+    # zero AND non-empty stdout, which explains the odd construction:
+    func_convert_core_file_wine_to_w32_tmp=`winepath -w "$1" 2>/dev/null`
+    if test "$?" -eq 0 && test -n "$func_convert_core_file_wine_to_w32_tmp"; then
+      func_convert_core_file_wine_to_w32_result=`$ECHO "$func_convert_core_file_wine_to_w32_tmp" |
+        $SED -e "$sed_naive_backslashify"`
+    else
+      func_convert_core_file_wine_to_w32_result=
+    fi
+  fi
+}
+# end: func_convert_core_file_wine_to_w32
+
+
+# func_convert_core_path_wine_to_w32 ARG
+# Helper function used by path conversion functions when $build is *nix, and
+# $host is mingw, cygwin, or some other w32 environment. Relies on a correctly
+# configured wine environment available, with the winepath program in $build's
+# $PATH. Assumes ARG has no leading or trailing path separator characters.
+#
+# ARG is path to be converted from $build format to win32.
+# Result is available in $func_convert_core_path_wine_to_w32_result.
+# Unconvertible file (directory) names in ARG are skipped; if no directory names
+# are convertible, then the result may be empty.
+func_convert_core_path_wine_to_w32 ()
+{
+  $debug_cmd
+
+  # unfortunately, winepath doesn't convert paths, only file names
+  func_convert_core_path_wine_to_w32_result=
+  if test -n "$1"; then
+    oldIFS=$IFS
+    IFS=:
+    for func_convert_core_path_wine_to_w32_f in $1; do
+      IFS=$oldIFS
+      func_convert_core_file_wine_to_w32 "$func_convert_core_path_wine_to_w32_f"
+      if test -n "$func_convert_core_file_wine_to_w32_result"; then
+        if test -z "$func_convert_core_path_wine_to_w32_result"; then
+          func_convert_core_path_wine_to_w32_result=$func_convert_core_file_wine_to_w32_result
+        else
+          func_append func_convert_core_path_wine_to_w32_result ";$func_convert_core_file_wine_to_w32_result"
+        fi
+      fi
+    done
+    IFS=$oldIFS
+  fi
+}
+# end: func_convert_core_path_wine_to_w32
+
+
+# func_cygpath ARGS...
+# Wrapper around calling the cygpath program via LT_CYGPATH. This is used when
+# when (1) $build is *nix and Cygwin is hosted via a wine environment; or (2)
+# $build is MSYS and $host is Cygwin, or (3) $build is Cygwin. In case (1) or
+# (2), returns the Cygwin file name or path in func_cygpath_result (input
+# file name or path is assumed to be in w32 format, as previously converted
+# from $build's *nix or MSYS format). In case (3), returns the w32 file name
+# or path in func_cygpath_result (input file name or path is assumed to be in
+# Cygwin format). Returns an empty string on error.
+#
+# ARGS are passed to cygpath, with the last one being the file name or path to
+# be converted.
+#
+# Specify the absolute *nix (or w32) name to cygpath in the LT_CYGPATH
+# environment variable; do not put it in $PATH.
+func_cygpath ()
+{
+  $debug_cmd
+
+  if test -n "$LT_CYGPATH" && test -f "$LT_CYGPATH"; then
+    func_cygpath_result=`$LT_CYGPATH "$@" 2>/dev/null`
+    if test "$?" -ne 0; then
+      # on failure, ensure result is empty
+      func_cygpath_result=
+    fi
+  else
+    func_cygpath_result=
+    func_error "LT_CYGPATH is empty or specifies non-existent file: '$LT_CYGPATH'"
+  fi
+}
+#end: func_cygpath
+
+
+# func_convert_core_msys_to_w32 ARG
+# Convert file name or path ARG from MSYS format to w32 format.  Return
+# result in func_convert_core_msys_to_w32_result.
+func_convert_core_msys_to_w32 ()
+{
+  $debug_cmd
+
+  # awkward: cmd appends spaces to result
+  func_convert_core_msys_to_w32_result=`( cmd //c echo "$1" ) 2>/dev/null |
+    $SED -e 's/[ ]*$//' -e "$sed_naive_backslashify"`
+}
+#end: func_convert_core_msys_to_w32
+
+
+# func_convert_file_check ARG1 ARG2
+# Verify that ARG1 (a file name in $build format) was converted to $host
+# format in ARG2. Otherwise, emit an error message, but continue (resetting
+# func_to_host_file_result to ARG1).
+func_convert_file_check ()
+{
+  $debug_cmd
+
+  if test -z "$2" && test -n "$1"; then
+    func_error "Could not determine host file name corresponding to"
+    func_error "  '$1'"
+    func_error "Continuing, but uninstalled executables may not work."
+    # Fallback:
+    func_to_host_file_result=$1
+  fi
+}
+# end func_convert_file_check
+
+
+# func_convert_path_check FROM_PATHSEP TO_PATHSEP FROM_PATH TO_PATH
+# Verify that FROM_PATH (a path in $build format) was converted to $host
+# format in TO_PATH. Otherwise, emit an error message, but continue, resetting
+# func_to_host_file_result to a simplistic fallback value (see below).
+func_convert_path_check ()
+{
+  $debug_cmd
+
+  if test -z "$4" && test -n "$3"; then
+    func_error "Could not determine the host path corresponding to"
+    func_error "  '$3'"
+    func_error "Continuing, but uninstalled executables may not work."
+    # Fallback.  This is a deliberately simplistic "conversion" and
+    # should not be "improved".  See libtool.info.
+    if test "x$1" != "x$2"; then
+      lt_replace_pathsep_chars="s|$1|$2|g"
+      func_to_host_path_result=`echo "$3" |
+        $SED -e "$lt_replace_pathsep_chars"`
+    else
+      func_to_host_path_result=$3
+    fi
+  fi
+}
+# end func_convert_path_check
+
+
+# func_convert_path_front_back_pathsep FRONTPAT BACKPAT REPL ORIG
+# Modifies func_to_host_path_result by prepending REPL if ORIG matches FRONTPAT
+# and appending REPL if ORIG matches BACKPAT.
+func_convert_path_front_back_pathsep ()
+{
+  $debug_cmd
+
+  case $4 in
+  $1 ) func_to_host_path_result=$3$func_to_host_path_result
+    ;;
+  esac
+  case $4 in
+  $2 ) func_append func_to_host_path_result "$3"
+    ;;
+  esac
+}
+# end func_convert_path_front_back_pathsep
+
+
+##################################################
+# $build to $host FILE NAME CONVERSION FUNCTIONS #
+##################################################
+# invoked via '$to_host_file_cmd ARG'
+#
+# In each case, ARG is the path to be converted from $build to $host format.
+# Result will be available in $func_to_host_file_result.
+
+
+# func_to_host_file ARG
+# Converts the file name ARG from $build format to $host format. Return result
+# in func_to_host_file_result.
+func_to_host_file ()
+{
+  $debug_cmd
+
+  $to_host_file_cmd "$1"
+}
+# end func_to_host_file
+
+
+# func_to_tool_file ARG LAZY
+# converts the file name ARG from $build format to toolchain format. Return
+# result in func_to_tool_file_result.  If the conversion in use is listed
+# in (the comma separated) LAZY, no conversion takes place.
+func_to_tool_file ()
+{
+  $debug_cmd
+
+  case ,$2, in
+    *,"$to_tool_file_cmd",*)
+      func_to_tool_file_result=$1
+      ;;
+    *)
+      $to_tool_file_cmd "$1"
+      func_to_tool_file_result=$func_to_host_file_result
+      ;;
+  esac
+}
+# end func_to_tool_file
+
+
+# func_convert_file_noop ARG
+# Copy ARG to func_to_host_file_result.
+func_convert_file_noop ()
+{
+  func_to_host_file_result=$1
+}
+# end func_convert_file_noop
+
+
+# func_convert_file_msys_to_w32 ARG
+# Convert file name ARG from (mingw) MSYS to (mingw) w32 format; automatic
+# conversion to w32 is not available inside the cwrapper.  Returns result in
+# func_to_host_file_result.
+func_convert_file_msys_to_w32 ()
+{
+  $debug_cmd
+
+  func_to_host_file_result=$1
+  if test -n "$1"; then
+    func_convert_core_msys_to_w32 "$1"
+    func_to_host_file_result=$func_convert_core_msys_to_w32_result
+  fi
+  func_convert_file_check "$1" "$func_to_host_file_result"
+}
+# end func_convert_file_msys_to_w32
+
+
+# func_convert_file_cygwin_to_w32 ARG
+# Convert file name ARG from Cygwin to w32 format.  Returns result in
+# func_to_host_file_result.
+func_convert_file_cygwin_to_w32 ()
+{
+  $debug_cmd
+
+  func_to_host_file_result=$1
+  if test -n "$1"; then
+    # because $build is cygwin, we call "the" cygpath in $PATH; no need to use
+    # LT_CYGPATH in this case.
+    func_to_host_file_result=`cygpath -m "$1"`
+  fi
+  func_convert_file_check "$1" "$func_to_host_file_result"
+}
+# end func_convert_file_cygwin_to_w32
+
+
+# func_convert_file_nix_to_w32 ARG
+# Convert file name ARG from *nix to w32 format.  Requires a wine environment
+# and a working winepath. Returns result in func_to_host_file_result.
+func_convert_file_nix_to_w32 ()
+{
+  $debug_cmd
+
+  func_to_host_file_result=$1
+  if test -n "$1"; then
+    func_convert_core_file_wine_to_w32 "$1"
+    func_to_host_file_result=$func_convert_core_file_wine_to_w32_result
+  fi
+  func_convert_file_check "$1" "$func_to_host_file_result"
+}
+# end func_convert_file_nix_to_w32
+
+
+# func_convert_file_msys_to_cygwin ARG
+# Convert file name ARG from MSYS to Cygwin format.  Requires LT_CYGPATH set.
+# Returns result in func_to_host_file_result.
+func_convert_file_msys_to_cygwin ()
+{
+  $debug_cmd
+
+  func_to_host_file_result=$1
+  if test -n "$1"; then
+    func_convert_core_msys_to_w32 "$1"
+    func_cygpath -u "$func_convert_core_msys_to_w32_result"
+    func_to_host_file_result=$func_cygpath_result
+  fi
+  func_convert_file_check "$1" "$func_to_host_file_result"
+}
+# end func_convert_file_msys_to_cygwin
+
+
+# func_convert_file_nix_to_cygwin ARG
+# Convert file name ARG from *nix to Cygwin format.  Requires Cygwin installed
+# in a wine environment, working winepath, and LT_CYGPATH set.  Returns result
+# in func_to_host_file_result.
+func_convert_file_nix_to_cygwin ()
+{
+  $debug_cmd
+
+  func_to_host_file_result=$1
+  if test -n "$1"; then
+    # convert from *nix to w32, then use cygpath to convert from w32 to cygwin.
+    func_convert_core_file_wine_to_w32 "$1"
+    func_cygpath -u "$func_convert_core_file_wine_to_w32_result"
+    func_to_host_file_result=$func_cygpath_result
+  fi
+  func_convert_file_check "$1" "$func_to_host_file_result"
+}
+# end func_convert_file_nix_to_cygwin
+
+
+#############################################
+# $build to $host PATH CONVERSION FUNCTIONS #
+#############################################
+# invoked via '$to_host_path_cmd ARG'
+#
+# In each case, ARG is the path to be converted from $build to $host format.
+# The result will be available in $func_to_host_path_result.
+#
+# Path separators are also converted from $build format to $host format.  If
+# ARG begins or ends with a path separator character, it is preserved (but
+# converted to $host format) on output.
+#
+# All path conversion functions are named using the following convention:
+#   file name conversion function    : func_convert_file_X_to_Y ()
+#   path conversion function         : func_convert_path_X_to_Y ()
+# where, for any given $build/$host combination the 'X_to_Y' value is the
+# same.  If conversion functions are added for new $build/$host combinations,
+# the two new functions must follow this pattern, or func_init_to_host_path_cmd
+# will break.
+
+
+# func_init_to_host_path_cmd
+# Ensures that function "pointer" variable $to_host_path_cmd is set to the
+# appropriate value, based on the value of $to_host_file_cmd.
+to_host_path_cmd=
+func_init_to_host_path_cmd ()
+{
+  $debug_cmd
+
+  if test -z "$to_host_path_cmd"; then
+    func_stripname 'func_convert_file_' '' "$to_host_file_cmd"
+    to_host_path_cmd=func_convert_path_$func_stripname_result
+  fi
+}
+
+
+# func_to_host_path ARG
+# Converts the path ARG from $build format to $host format. Return result
+# in func_to_host_path_result.
+func_to_host_path ()
+{
+  $debug_cmd
+
+  func_init_to_host_path_cmd
+  $to_host_path_cmd "$1"
+}
+# end func_to_host_path
+
+
+# func_convert_path_noop ARG
+# Copy ARG to func_to_host_path_result.
+func_convert_path_noop ()
+{
+  func_to_host_path_result=$1
+}
+# end func_convert_path_noop
+
+
+# func_convert_path_msys_to_w32 ARG
+# Convert path ARG from (mingw) MSYS to (mingw) w32 format; automatic
+# conversion to w32 is not available inside the cwrapper.  Returns result in
+# func_to_host_path_result.
+func_convert_path_msys_to_w32 ()
+{
+  $debug_cmd
+
+  func_to_host_path_result=$1
+  if test -n "$1"; then
+    # Remove leading and trailing path separator characters from ARG.  MSYS
+    # behavior is inconsistent here; cygpath turns them into '.;' and ';.';
+    # and winepath ignores them completely.
+    func_stripname : : "$1"
+    func_to_host_path_tmp1=$func_stripname_result
+    func_convert_core_msys_to_w32 "$func_to_host_path_tmp1"
+    func_to_host_path_result=$func_convert_core_msys_to_w32_result
+    func_convert_path_check : ";" \
+      "$func_to_host_path_tmp1" "$func_to_host_path_result"
+    func_convert_path_front_back_pathsep ":*" "*:" ";" "$1"
+  fi
+}
+# end func_convert_path_msys_to_w32
+
+
+# func_convert_path_cygwin_to_w32 ARG
+# Convert path ARG from Cygwin to w32 format.  Returns result in
+# func_to_host_file_result.
+func_convert_path_cygwin_to_w32 ()
+{
+  $debug_cmd
+
+  func_to_host_path_result=$1
+  if test -n "$1"; then
+    # See func_convert_path_msys_to_w32:
+    func_stripname : : "$1"
+    func_to_host_path_tmp1=$func_stripname_result
+    func_to_host_path_result=`cygpath -m -p "$func_to_host_path_tmp1"`
+    func_convert_path_check : ";" \
+      "$func_to_host_path_tmp1" "$func_to_host_path_result"
+    func_convert_path_front_back_pathsep ":*" "*:" ";" "$1"
+  fi
+}
+# end func_convert_path_cygwin_to_w32
+
+
+# func_convert_path_nix_to_w32 ARG
+# Convert path ARG from *nix to w32 format.  Requires a wine environment and
+# a working winepath.  Returns result in func_to_host_file_result.
+func_convert_path_nix_to_w32 ()
+{
+  $debug_cmd
+
+  func_to_host_path_result=$1
+  if test -n "$1"; then
+    # See func_convert_path_msys_to_w32:
+    func_stripname : : "$1"
+    func_to_host_path_tmp1=$func_stripname_result
+    func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1"
+    func_to_host_path_result=$func_convert_core_path_wine_to_w32_result
+    func_convert_path_check : ";" \
+      "$func_to_host_path_tmp1" "$func_to_host_path_result"
+    func_convert_path_front_back_pathsep ":*" "*:" ";" "$1"
+  fi
+}
+# end func_convert_path_nix_to_w32
+
+
+# func_convert_path_msys_to_cygwin ARG
+# Convert path ARG from MSYS to Cygwin format.  Requires LT_CYGPATH set.
+# Returns result in func_to_host_file_result.
+func_convert_path_msys_to_cygwin ()
+{
+  $debug_cmd
+
+  func_to_host_path_result=$1
+  if test -n "$1"; then
+    # See func_convert_path_msys_to_w32:
+    func_stripname : : "$1"
+    func_to_host_path_tmp1=$func_stripname_result
+    func_convert_core_msys_to_w32 "$func_to_host_path_tmp1"
+    func_cygpath -u -p "$func_convert_core_msys_to_w32_result"
+    func_to_host_path_result=$func_cygpath_result
+    func_convert_path_check : : \
+      "$func_to_host_path_tmp1" "$func_to_host_path_result"
+    func_convert_path_front_back_pathsep ":*" "*:" : "$1"
+  fi
+}
+# end func_convert_path_msys_to_cygwin
+
+
+# func_convert_path_nix_to_cygwin ARG
+# Convert path ARG from *nix to Cygwin format.  Requires Cygwin installed in a
+# a wine environment, working winepath, and LT_CYGPATH set.  Returns result in
+# func_to_host_file_result.
+func_convert_path_nix_to_cygwin ()
+{
+  $debug_cmd
+
+  func_to_host_path_result=$1
+  if test -n "$1"; then
+    # Remove leading and trailing path separator characters from
+    # ARG. msys behavior is inconsistent here, cygpath turns them
+    # into '.;' and ';.', and winepath ignores them completely.
+    func_stripname : : "$1"
+    func_to_host_path_tmp1=$func_stripname_result
+    func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1"
+    func_cygpath -u -p "$func_convert_core_path_wine_to_w32_result"
+    func_to_host_path_result=$func_cygpath_result
+    func_convert_path_check : : \
+      "$func_to_host_path_tmp1" "$func_to_host_path_result"
+    func_convert_path_front_back_pathsep ":*" "*:" : "$1"
+  fi
+}
+# end func_convert_path_nix_to_cygwin
+
+
+# func_dll_def_p FILE
+# True iff FILE is a Windows DLL '.def' file.
+# Keep in sync with _LT_DLL_DEF_P in libtool.m4
+func_dll_def_p ()
+{
+  $debug_cmd
+
+  func_dll_def_p_tmp=`$SED -n \
+    -e 's/^[	 ]*//' \
+    -e '/^\(;.*\)*$/d' \
+    -e 's/^\(EXPORTS\|LIBRARY\)\([	 ].*\)*$/DEF/p' \
+    -e q \
+    "$1"`
+  test DEF = "$func_dll_def_p_tmp"
+}
+
+
+# func_mode_compile arg...
+func_mode_compile ()
+{
+    $debug_cmd
+
+    # Get the compilation command and the source file.
+    base_compile=
+    srcfile=$nonopt  #  always keep a non-empty value in "srcfile"
+    suppress_opt=yes
+    suppress_output=
+    arg_mode=normal
+    libobj=
+    later=
+    pie_flag=
+
+    for arg
+    do
+      case $arg_mode in
+      arg  )
+	# do not "continue".  Instead, add this to base_compile
+	lastarg=$arg
+	arg_mode=normal
+	;;
+
+      target )
+	libobj=$arg
+	arg_mode=normal
+	continue
+	;;
+
+      normal )
+	# Accept any command-line options.
+	case $arg in
+	-o)
+	  test -n "$libobj" && \
+	    func_fatal_error "you cannot specify '-o' more than once"
+	  arg_mode=target
+	  continue
+	  ;;
+
+	-pie | -fpie | -fPIE)
+          func_append pie_flag " $arg"
+	  continue
+	  ;;
+
+	-shared | -static | -prefer-pic | -prefer-non-pic)
+	  func_append later " $arg"
+	  continue
+	  ;;
+
+	-no-suppress)
+	  suppress_opt=no
+	  continue
+	  ;;
+
+	-Xcompiler)
+	  arg_mode=arg  #  the next one goes into the "base_compile" arg list
+	  continue      #  The current "srcfile" will either be retained or
+	  ;;            #  replaced later.  I would guess that would be a bug.
+
+	-Wc,*)
+	  func_stripname '-Wc,' '' "$arg"
+	  args=$func_stripname_result
+	  lastarg=
+	  save_ifs=$IFS; IFS=,
+	  for arg in $args; do
+	    IFS=$save_ifs
+	    func_append_quoted lastarg "$arg"
+	  done
+	  IFS=$save_ifs
+	  func_stripname ' ' '' "$lastarg"
+	  lastarg=$func_stripname_result
+
+	  # Add the arguments to base_compile.
+	  func_append base_compile " $lastarg"
+	  continue
+	  ;;
+
+	*)
+	  # Accept the current argument as the source file.
+	  # The previous "srcfile" becomes the current argument.
+	  #
+	  lastarg=$srcfile
+	  srcfile=$arg
+	  ;;
+	esac  #  case $arg
+	;;
+      esac    #  case $arg_mode
+
+      # Aesthetically quote the previous argument.
+      func_append_quoted base_compile "$lastarg"
+    done # for arg
+
+    case $arg_mode in
+    arg)
+      func_fatal_error "you must specify an argument for -Xcompile"
+      ;;
+    target)
+      func_fatal_error "you must specify a target with '-o'"
+      ;;
+    *)
+      # Get the name of the library object.
+      test -z "$libobj" && {
+	func_basename "$srcfile"
+	libobj=$func_basename_result
+      }
+      ;;
+    esac
+
+    # Recognize several different file suffixes.
+    # If the user specifies -o file.o, it is replaced with file.lo
+    case $libobj in
+    *.[cCFSifmso] | \
+    *.ada | *.adb | *.ads | *.asm | \
+    *.c++ | *.cc | *.ii | *.class | *.cpp | *.cxx | \
+    *.[fF][09]? | *.for | *.java | *.go | *.obj | *.sx | *.cu | *.cup)
+      func_xform "$libobj"
+      libobj=$func_xform_result
+      ;;
+    esac
+
+    case $libobj in
+    *.lo) func_lo2o "$libobj"; obj=$func_lo2o_result ;;
+    *)
+      func_fatal_error "cannot determine name of library object from '$libobj'"
+      ;;
+    esac
+
+    func_infer_tag $base_compile
+
+    for arg in $later; do
+      case $arg in
+      -shared)
+	test yes = "$build_libtool_libs" \
+	  || func_fatal_configuration "cannot build a shared library"
+	build_old_libs=no
+	continue
+	;;
+
+      -static)
+	build_libtool_libs=no
+	build_old_libs=yes
+	continue
+	;;
+
+      -prefer-pic)
+	pic_mode=yes
+	continue
+	;;
+
+      -prefer-non-pic)
+	pic_mode=no
+	continue
+	;;
+      esac
+    done
+
+    func_quote_for_eval "$libobj"
+    test "X$libobj" != "X$func_quote_for_eval_result" \
+      && $ECHO "X$libobj" | $GREP '[]~#^*{};<>?"'"'"'	 &()|`$[]' \
+      && func_warning "libobj name '$libobj' may not contain shell special characters."
+    func_dirname_and_basename "$obj" "/" ""
+    objname=$func_basename_result
+    xdir=$func_dirname_result
+    lobj=$xdir$objdir/$objname
+
+    test -z "$base_compile" && \
+      func_fatal_help "you must specify a compilation command"
+
+    # Delete any leftover library objects.
+    if test yes = "$build_old_libs"; then
+      removelist="$obj $lobj $libobj ${libobj}T"
+    else
+      removelist="$lobj $libobj ${libobj}T"
+    fi
+
+    # On Cygwin there's no "real" PIC flag so we must build both object types
+    case $host_os in
+    cygwin* | mingw* | pw32* | os2* | cegcc*)
+      pic_mode=default
+      ;;
+    esac
+    if test no = "$pic_mode" && test pass_all != "$deplibs_check_method"; then
+      # non-PIC code in shared libraries is not supported
+      pic_mode=default
+    fi
+
+    # Calculate the filename of the output object if compiler does
+    # not support -o with -c
+    if test no = "$compiler_c_o"; then
+      output_obj=`$ECHO "$srcfile" | $SED 's%^.*/%%; s%\.[^.]*$%%'`.$objext
+      lockfile=$output_obj.lock
+    else
+      output_obj=
+      need_locks=no
+      lockfile=
+    fi
+
+    # Lock this critical section if it is needed
+    # We use this script file to make the link, it avoids creating a new file
+    if test yes = "$need_locks"; then
+      until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do
+	func_echo "Waiting for $lockfile to be removed"
+	sleep 2
+      done
+    elif test warn = "$need_locks"; then
+      if test -f "$lockfile"; then
+	$ECHO "\
+*** ERROR, $lockfile exists and contains:
+`cat $lockfile 2>/dev/null`
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support '-c' and '-o' together.  If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+	$opt_dry_run || $RM $removelist
+	exit $EXIT_FAILURE
+      fi
+      func_append removelist " $output_obj"
+      $ECHO "$srcfile" > "$lockfile"
+    fi
+
+    $opt_dry_run || $RM $removelist
+    func_append removelist " $lockfile"
+    trap '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' 1 2 15
+
+    func_to_tool_file "$srcfile" func_convert_file_msys_to_w32
+    srcfile=$func_to_tool_file_result
+    func_quote_for_eval "$srcfile"
+    qsrcfile=$func_quote_for_eval_result
+
+    # Only build a PIC object if we are building libtool libraries.
+    if test yes = "$build_libtool_libs"; then
+      # Without this assignment, base_compile gets emptied.
+      fbsd_hideous_sh_bug=$base_compile
+
+      if test no != "$pic_mode"; then
+	command="$base_compile $qsrcfile $pic_flag"
+      else
+	# Don't build PIC code
+	command="$base_compile $qsrcfile"
+      fi
+
+      func_mkdir_p "$xdir$objdir"
+
+      if test -z "$output_obj"; then
+	# Place PIC objects in $objdir
+	func_append command " -o $lobj"
+      fi
+
+      func_show_eval_locale "$command"	\
+          'test -n "$output_obj" && $RM $removelist; exit $EXIT_FAILURE'
+
+      if test warn = "$need_locks" &&
+	 test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then
+	$ECHO "\
+*** ERROR, $lockfile contains:
+`cat $lockfile 2>/dev/null`
+
+but it should contain:
+$srcfile
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support '-c' and '-o' together.  If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+	$opt_dry_run || $RM $removelist
+	exit $EXIT_FAILURE
+      fi
+
+      # Just move the object if needed, then go on to compile the next one
+      if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then
+	func_show_eval '$MV "$output_obj" "$lobj"' \
+	  'error=$?; $opt_dry_run || $RM $removelist; exit $error'
+      fi
+
+      # Allow error messages only from the first compilation.
+      if test yes = "$suppress_opt"; then
+	suppress_output=' >/dev/null 2>&1'
+      fi
+    fi
+
+    # Only build a position-dependent object if we build old libraries.
+    if test yes = "$build_old_libs"; then
+      if test yes != "$pic_mode"; then
+	# Don't build PIC code
+	command="$base_compile $qsrcfile$pie_flag"
+      else
+	command="$base_compile $qsrcfile $pic_flag"
+      fi
+      if test yes = "$compiler_c_o"; then
+	func_append command " -o $obj"
+      fi
+
+      # Suppress compiler output if we already did a PIC compilation.
+      func_append command "$suppress_output"
+      func_show_eval_locale "$command" \
+        '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE'
+
+      if test warn = "$need_locks" &&
+	 test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then
+	$ECHO "\
+*** ERROR, $lockfile contains:
+`cat $lockfile 2>/dev/null`
+
+but it should contain:
+$srcfile
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support '-c' and '-o' together.  If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+	$opt_dry_run || $RM $removelist
+	exit $EXIT_FAILURE
+      fi
+
+      # Just move the object if needed
+      if test -n "$output_obj" && test "X$output_obj" != "X$obj"; then
+	func_show_eval '$MV "$output_obj" "$obj"' \
+	  'error=$?; $opt_dry_run || $RM $removelist; exit $error'
+      fi
+    fi
+
+    $opt_dry_run || {
+      func_write_libtool_object "$libobj" "$objdir/$objname" "$objname"
+
+      # Unlock the critical section if it was locked
+      if test no != "$need_locks"; then
+	removelist=$lockfile
+        $RM "$lockfile"
+      fi
+    }
+
+    exit $EXIT_SUCCESS
+}
+
+$opt_help || {
+  test compile = "$opt_mode" && func_mode_compile ${1+"$@"}
+}
+
+func_mode_help ()
+{
+    # We need to display help for each of the modes.
+    case $opt_mode in
+      "")
+        # Generic help is extracted from the usage comments
+        # at the start of this file.
+        func_help
+        ;;
+
+      clean)
+        $ECHO \
+"Usage: $progname [OPTION]... --mode=clean RM [RM-OPTION]... FILE...
+
+Remove files from the build directory.
+
+RM is the name of the program to use to delete files associated with each FILE
+(typically '/bin/rm').  RM-OPTIONS are options (such as '-f') to be passed
+to RM.
+
+If FILE is a libtool library, object or program, all the files associated
+with it are deleted. Otherwise, only FILE itself is deleted using RM."
+        ;;
+
+      compile)
+      $ECHO \
+"Usage: $progname [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE
+
+Compile a source file into a libtool library object.
+
+This mode accepts the following additional options:
+
+  -o OUTPUT-FILE    set the output file name to OUTPUT-FILE
+  -no-suppress      do not suppress compiler output for multiple passes
+  -prefer-pic       try to build PIC objects only
+  -prefer-non-pic   try to build non-PIC objects only
+  -shared           do not build a '.o' file suitable for static linking
+  -static           only build a '.o' file suitable for static linking
+  -Wc,FLAG          pass FLAG directly to the compiler
+
+COMPILE-COMMAND is a command to be used in creating a 'standard' object file
+from the given SOURCEFILE.
+
+The output file name is determined by removing the directory component from
+SOURCEFILE, then substituting the C source code suffix '.c' with the
+library object suffix, '.lo'."
+        ;;
+
+      execute)
+        $ECHO \
+"Usage: $progname [OPTION]... --mode=execute COMMAND [ARGS]...
+
+Automatically set library path, then run a program.
+
+This mode accepts the following additional options:
+
+  -dlopen FILE      add the directory containing FILE to the library path
+
+This mode sets the library path environment variable according to '-dlopen'
+flags.
+
+If any of the ARGS are libtool executable wrappers, then they are translated
+into their corresponding uninstalled binary, and any of their required library
+directories are added to the library path.
+
+Then, COMMAND is executed, with ARGS as arguments."
+        ;;
+
+      finish)
+        $ECHO \
+"Usage: $progname [OPTION]... --mode=finish [LIBDIR]...
+
+Complete the installation of libtool libraries.
+
+Each LIBDIR is a directory that contains libtool libraries.
+
+The commands that this mode executes may require superuser privileges.  Use
+the '--dry-run' option if you just want to see what would be executed."
+        ;;
+
+      install)
+        $ECHO \
+"Usage: $progname [OPTION]... --mode=install INSTALL-COMMAND...
+
+Install executables or libraries.
+
+INSTALL-COMMAND is the installation command.  The first component should be
+either the 'install' or 'cp' program.
+
+The following components of INSTALL-COMMAND are treated specially:
+
+  -inst-prefix-dir PREFIX-DIR  Use PREFIX-DIR as a staging area for installation
+
+The rest of the components are interpreted as arguments to that command (only
+BSD-compatible install options are recognized)."
+        ;;
+
+      link)
+        $ECHO \
+"Usage: $progname [OPTION]... --mode=link LINK-COMMAND...
+
+Link object files or libraries together to form another library, or to
+create an executable program.
+
+LINK-COMMAND is a command using the C compiler that you would use to create
+a program from several object files.
+
+The following components of LINK-COMMAND are treated specially:
+
+  -all-static       do not do any dynamic linking at all
+  -avoid-version    do not add a version suffix if possible
+  -bindir BINDIR    specify path to binaries directory (for systems where
+                    libraries must be found in the PATH setting at runtime)
+  -dlopen FILE      '-dlpreopen' FILE if it cannot be dlopened at runtime
+  -dlpreopen FILE   link in FILE and add its symbols to lt_preloaded_symbols
+  -export-dynamic   allow symbols from OUTPUT-FILE to be resolved with dlsym(3)
+  -export-symbols SYMFILE
+                    try to export only the symbols listed in SYMFILE
+  -export-symbols-regex REGEX
+                    try to export only the symbols matching REGEX
+  -LLIBDIR          search LIBDIR for required installed libraries
+  -lNAME            OUTPUT-FILE requires the installed library libNAME
+  -module           build a library that can dlopened
+  -no-fast-install  disable the fast-install mode
+  -no-install       link a not-installable executable
+  -no-undefined     declare that a library does not refer to external symbols
+  -o OUTPUT-FILE    create OUTPUT-FILE from the specified objects
+  -objectlist FILE  use a list of object files found in FILE to specify objects
+  -os2dllname NAME  force a short DLL name on OS/2 (no effect on other OSes)
+  -precious-files-regex REGEX
+                    don't remove output files matching REGEX
+  -release RELEASE  specify package release information
+  -rpath LIBDIR     the created library will eventually be installed in LIBDIR
+  -R[ ]LIBDIR       add LIBDIR to the runtime path of programs and libraries
+  -shared           only do dynamic linking of libtool libraries
+  -shrext SUFFIX    override the standard shared library file extension
+  -static           do not do any dynamic linking of uninstalled libtool libraries
+  -static-libtool-libs
+                    do not do any dynamic linking of libtool libraries
+  -version-info CURRENT[:REVISION[:AGE]]
+                    specify library version info [each variable defaults to 0]
+  -weak LIBNAME     declare that the target provides the LIBNAME interface
+  -Wc,FLAG
+  -Xcompiler FLAG   pass linker-specific FLAG directly to the compiler
+  -Wl,FLAG
+  -Xlinker FLAG     pass linker-specific FLAG directly to the linker
+  -XCClinker FLAG   pass link-specific FLAG to the compiler driver (CC)
+
+All other options (arguments beginning with '-') are ignored.
+
+Every other argument is treated as a filename.  Files ending in '.la' are
+treated as uninstalled libtool libraries, other files are standard or library
+object files.
+
+If the OUTPUT-FILE ends in '.la', then a libtool library is created,
+only library objects ('.lo' files) may be specified, and '-rpath' is
+required, except when creating a convenience library.
+
+If OUTPUT-FILE ends in '.a' or '.lib', then a standard library is created
+using 'ar' and 'ranlib', or on Windows using 'lib'.
+
+If OUTPUT-FILE ends in '.lo' or '.$objext', then a reloadable object file
+is created, otherwise an executable program is created."
+        ;;
+
+      uninstall)
+        $ECHO \
+"Usage: $progname [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE...
+
+Remove libraries from an installation directory.
+
+RM is the name of the program to use to delete files associated with each FILE
+(typically '/bin/rm').  RM-OPTIONS are options (such as '-f') to be passed
+to RM.
+
+If FILE is a libtool library, all the files associated with it are deleted.
+Otherwise, only FILE itself is deleted using RM."
+        ;;
+
+      *)
+        func_fatal_help "invalid operation mode '$opt_mode'"
+        ;;
+    esac
+
+    echo
+    $ECHO "Try '$progname --help' for more information about other modes."
+}
+
+# Now that we've collected a possible --mode arg, show help if necessary
+if $opt_help; then
+  if test : = "$opt_help"; then
+    func_mode_help
+  else
+    {
+      func_help noexit
+      for opt_mode in compile link execute install finish uninstall clean; do
+	func_mode_help
+      done
+    } | $SED -n '1p; 2,$s/^Usage:/  or: /p'
+    {
+      func_help noexit
+      for opt_mode in compile link execute install finish uninstall clean; do
+	echo
+	func_mode_help
+      done
+    } |
+    $SED '1d
+      /^When reporting/,/^Report/{
+	H
+	d
+      }
+      $x
+      /information about other modes/d
+      /more detailed .*MODE/d
+      s/^Usage:.*--mode=\([^ ]*\) .*/Description of \1 mode:/'
+  fi
+  exit $?
+fi
+
+
+# func_mode_execute arg...
+func_mode_execute ()
+{
+    $debug_cmd
+
+    # The first argument is the command name.
+    cmd=$nonopt
+    test -z "$cmd" && \
+      func_fatal_help "you must specify a COMMAND"
+
+    # Handle -dlopen flags immediately.
+    for file in $opt_dlopen; do
+      test -f "$file" \
+	|| func_fatal_help "'$file' is not a file"
+
+      dir=
+      case $file in
+      *.la)
+	func_resolve_sysroot "$file"
+	file=$func_resolve_sysroot_result
+
+	# Check to see that this really is a libtool archive.
+	func_lalib_unsafe_p "$file" \
+	  || func_fatal_help "'$lib' is not a valid libtool archive"
+
+	# Read the libtool library.
+	dlname=
+	library_names=
+	func_source "$file"
+
+	# Skip this library if it cannot be dlopened.
+	if test -z "$dlname"; then
+	  # Warn if it was a shared library.
+	  test -n "$library_names" && \
+	    func_warning "'$file' was not linked with '-export-dynamic'"
+	  continue
+	fi
+
+	func_dirname "$file" "" "."
+	dir=$func_dirname_result
+
+	if test -f "$dir/$objdir/$dlname"; then
+	  func_append dir "/$objdir"
+	else
+	  if test ! -f "$dir/$dlname"; then
+	    func_fatal_error "cannot find '$dlname' in '$dir' or '$dir/$objdir'"
+	  fi
+	fi
+	;;
+
+      *.lo)
+	# Just add the directory containing the .lo file.
+	func_dirname "$file" "" "."
+	dir=$func_dirname_result
+	;;
+
+      *)
+	func_warning "'-dlopen' is ignored for non-libtool libraries and objects"
+	continue
+	;;
+      esac
+
+      # Get the absolute pathname.
+      absdir=`cd "$dir" && pwd`
+      test -n "$absdir" && dir=$absdir
+
+      # Now add the directory to shlibpath_var.
+      if eval "test -z \"\$$shlibpath_var\""; then
+	eval "$shlibpath_var=\"\$dir\""
+      else
+	eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\""
+      fi
+    done
+
+    # This variable tells wrapper scripts just to set shlibpath_var
+    # rather than running their programs.
+    libtool_execute_magic=$magic
+
+    # Check if any of the arguments is a wrapper script.
+    args=
+    for file
+    do
+      case $file in
+      -* | *.la | *.lo ) ;;
+      *)
+	# Do a test to see if this is really a libtool program.
+	if func_ltwrapper_script_p "$file"; then
+	  func_source "$file"
+	  # Transform arg to wrapped name.
+	  file=$progdir/$program
+	elif func_ltwrapper_executable_p "$file"; then
+	  func_ltwrapper_scriptname "$file"
+	  func_source "$func_ltwrapper_scriptname_result"
+	  # Transform arg to wrapped name.
+	  file=$progdir/$program
+	fi
+	;;
+      esac
+      # Quote arguments (to preserve shell metacharacters).
+      func_append_quoted args "$file"
+    done
+
+    if $opt_dry_run; then
+      # Display what would be done.
+      if test -n "$shlibpath_var"; then
+	eval "\$ECHO \"\$shlibpath_var=\$$shlibpath_var\""
+	echo "export $shlibpath_var"
+      fi
+      $ECHO "$cmd$args"
+      exit $EXIT_SUCCESS
+    else
+      if test -n "$shlibpath_var"; then
+	# Export the shlibpath_var.
+	eval "export $shlibpath_var"
+      fi
+
+      # Restore saved environment variables
+      for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES
+      do
+	eval "if test \"\${save_$lt_var+set}\" = set; then
+                $lt_var=\$save_$lt_var; export $lt_var
+	      else
+		$lt_unset $lt_var
+	      fi"
+      done
+
+      # Now prepare to actually exec the command.
+      exec_cmd=\$cmd$args
+    fi
+}
+
+test execute = "$opt_mode" && func_mode_execute ${1+"$@"}
+
+
+# func_mode_finish arg...
+func_mode_finish ()
+{
+    $debug_cmd
+
+    libs=
+    libdirs=
+    admincmds=
+
+    for opt in "$nonopt" ${1+"$@"}
+    do
+      if test -d "$opt"; then
+	func_append libdirs " $opt"
+
+      elif test -f "$opt"; then
+	if func_lalib_unsafe_p "$opt"; then
+	  func_append libs " $opt"
+	else
+	  func_warning "'$opt' is not a valid libtool archive"
+	fi
+
+      else
+	func_fatal_error "invalid argument '$opt'"
+      fi
+    done
+
+    if test -n "$libs"; then
+      if test -n "$lt_sysroot"; then
+        sysroot_regex=`$ECHO "$lt_sysroot" | $SED "$sed_make_literal_regex"`
+        sysroot_cmd="s/\([ ']\)$sysroot_regex/\1/g;"
+      else
+        sysroot_cmd=
+      fi
+
+      # Remove sysroot references
+      if $opt_dry_run; then
+        for lib in $libs; do
+          echo "removing references to $lt_sysroot and '=' prefixes from $lib"
+        done
+      else
+        tmpdir=`func_mktempdir`
+        for lib in $libs; do
+	  $SED -e "$sysroot_cmd s/\([ ']-[LR]\)=/\1/g; s/\([ ']\)=/\1/g" $lib \
+	    > $tmpdir/tmp-la
+	  mv -f $tmpdir/tmp-la $lib
+	done
+        ${RM}r "$tmpdir"
+      fi
+    fi
+
+    if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then
+      for libdir in $libdirs; do
+	if test -n "$finish_cmds"; then
+	  # Do each command in the finish commands.
+	  func_execute_cmds "$finish_cmds" 'admincmds="$admincmds
+'"$cmd"'"'
+	fi
+	if test -n "$finish_eval"; then
+	  # Do the single finish_eval.
+	  eval cmds=\"$finish_eval\"
+	  $opt_dry_run || eval "$cmds" || func_append admincmds "
+       $cmds"
+	fi
+      done
+    fi
+
+    # Exit here if they wanted silent mode.
+    $opt_quiet && exit $EXIT_SUCCESS
+
+    if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then
+      echo "----------------------------------------------------------------------"
+      echo "Libraries have been installed in:"
+      for libdir in $libdirs; do
+	$ECHO "   $libdir"
+      done
+      echo
+      echo "If you ever happen to want to link against installed libraries"
+      echo "in a given directory, LIBDIR, you must either use libtool, and"
+      echo "specify the full pathname of the library, or use the '-LLIBDIR'"
+      echo "flag during linking and do at least one of the following:"
+      if test -n "$shlibpath_var"; then
+	echo "   - add LIBDIR to the '$shlibpath_var' environment variable"
+	echo "     during execution"
+      fi
+      if test -n "$runpath_var"; then
+	echo "   - add LIBDIR to the '$runpath_var' environment variable"
+	echo "     during linking"
+      fi
+      if test -n "$hardcode_libdir_flag_spec"; then
+	libdir=LIBDIR
+	eval flag=\"$hardcode_libdir_flag_spec\"
+
+	$ECHO "   - use the '$flag' linker flag"
+      fi
+      if test -n "$admincmds"; then
+	$ECHO "   - have your system administrator run these commands:$admincmds"
+      fi
+      if test -f /etc/ld.so.conf; then
+	echo "   - have your system administrator add LIBDIR to '/etc/ld.so.conf'"
+      fi
+      echo
+
+      echo "See any operating system documentation about shared libraries for"
+      case $host in
+	solaris2.[6789]|solaris2.1[0-9])
+	  echo "more information, such as the ld(1), crle(1) and ld.so(8) manual"
+	  echo "pages."
+	  ;;
+	*)
+	  echo "more information, such as the ld(1) and ld.so(8) manual pages."
+	  ;;
+      esac
+      echo "----------------------------------------------------------------------"
+    fi
+    exit $EXIT_SUCCESS
+}
+
+test finish = "$opt_mode" && func_mode_finish ${1+"$@"}
+
+
+# func_mode_install arg...
+func_mode_install ()
+{
+    $debug_cmd
+
+    # There may be an optional sh(1) argument at the beginning of
+    # install_prog (especially on Windows NT).
+    if test "$SHELL" = "$nonopt" || test /bin/sh = "$nonopt" ||
+       # Allow the use of GNU shtool's install command.
+       case $nonopt in *shtool*) :;; *) false;; esac
+    then
+      # Aesthetically quote it.
+      func_quote_for_eval "$nonopt"
+      install_prog="$func_quote_for_eval_result "
+      arg=$1
+      shift
+    else
+      install_prog=
+      arg=$nonopt
+    fi
+
+    # The real first argument should be the name of the installation program.
+    # Aesthetically quote it.
+    func_quote_for_eval "$arg"
+    func_append install_prog "$func_quote_for_eval_result"
+    install_shared_prog=$install_prog
+    case " $install_prog " in
+      *[\\\ /]cp\ *) install_cp=: ;;
+      *) install_cp=false ;;
+    esac
+
+    # We need to accept at least all the BSD install flags.
+    dest=
+    files=
+    opts=
+    prev=
+    install_type=
+    isdir=false
+    stripme=
+    no_mode=:
+    for arg
+    do
+      arg2=
+      if test -n "$dest"; then
+	func_append files " $dest"
+	dest=$arg
+	continue
+      fi
+
+      case $arg in
+      -d) isdir=: ;;
+      -f)
+	if $install_cp; then :; else
+	  prev=$arg
+	fi
+	;;
+      -g | -m | -o)
+	prev=$arg
+	;;
+      -s)
+	stripme=" -s"
+	continue
+	;;
+      -*)
+	;;
+      *)
+	# If the previous option needed an argument, then skip it.
+	if test -n "$prev"; then
+	  if test X-m = "X$prev" && test -n "$install_override_mode"; then
+	    arg2=$install_override_mode
+	    no_mode=false
+	  fi
+	  prev=
+	else
+	  dest=$arg
+	  continue
+	fi
+	;;
+      esac
+
+      # Aesthetically quote the argument.
+      func_quote_for_eval "$arg"
+      func_append install_prog " $func_quote_for_eval_result"
+      if test -n "$arg2"; then
+	func_quote_for_eval "$arg2"
+      fi
+      func_append install_shared_prog " $func_quote_for_eval_result"
+    done
+
+    test -z "$install_prog" && \
+      func_fatal_help "you must specify an install program"
+
+    test -n "$prev" && \
+      func_fatal_help "the '$prev' option requires an argument"
+
+    if test -n "$install_override_mode" && $no_mode; then
+      if $install_cp; then :; else
+	func_quote_for_eval "$install_override_mode"
+	func_append install_shared_prog " -m $func_quote_for_eval_result"
+      fi
+    fi
+
+    if test -z "$files"; then
+      if test -z "$dest"; then
+	func_fatal_help "no file or destination specified"
+      else
+	func_fatal_help "you must specify a destination"
+      fi
+    fi
+
+    # Strip any trailing slash from the destination.
+    func_stripname '' '/' "$dest"
+    dest=$func_stripname_result
+
+    # Check to see that the destination is a directory.
+    test -d "$dest" && isdir=:
+    if $isdir; then
+      destdir=$dest
+      destname=
+    else
+      func_dirname_and_basename "$dest" "" "."
+      destdir=$func_dirname_result
+      destname=$func_basename_result
+
+      # Not a directory, so check to see that there is only one file specified.
+      set dummy $files; shift
+      test "$#" -gt 1 && \
+	func_fatal_help "'$dest' is not a directory"
+    fi
+    case $destdir in
+    [\\/]* | [A-Za-z]:[\\/]*) ;;
+    *)
+      for file in $files; do
+	case $file in
+	*.lo) ;;
+	*)
+	  func_fatal_help "'$destdir' must be an absolute directory name"
+	  ;;
+	esac
+      done
+      ;;
+    esac
+
+    # This variable tells wrapper scripts just to set variables rather
+    # than running their programs.
+    libtool_install_magic=$magic
+
+    staticlibs=
+    future_libdirs=
+    current_libdirs=
+    for file in $files; do
+
+      # Do each installation.
+      case $file in
+      *.$libext)
+	# Do the static libraries later.
+	func_append staticlibs " $file"
+	;;
+
+      *.la)
+	func_resolve_sysroot "$file"
+	file=$func_resolve_sysroot_result
+
+	# Check to see that this really is a libtool archive.
+	func_lalib_unsafe_p "$file" \
+	  || func_fatal_help "'$file' is not a valid libtool archive"
+
+	library_names=
+	old_library=
+	relink_command=
+	func_source "$file"
+
+	# Add the libdir to current_libdirs if it is the destination.
+	if test "X$destdir" = "X$libdir"; then
+	  case "$current_libdirs " in
+	  *" $libdir "*) ;;
+	  *) func_append current_libdirs " $libdir" ;;
+	  esac
+	else
+	  # Note the libdir as a future libdir.
+	  case "$future_libdirs " in
+	  *" $libdir "*) ;;
+	  *) func_append future_libdirs " $libdir" ;;
+	  esac
+	fi
+
+	func_dirname "$file" "/" ""
+	dir=$func_dirname_result
+	func_append dir "$objdir"
+
+	if test -n "$relink_command"; then
+	  # Determine the prefix the user has applied to our future dir.
+	  inst_prefix_dir=`$ECHO "$destdir" | $SED -e "s%$libdir\$%%"`
+
+	  # Don't allow the user to place us outside of our expected
+	  # location b/c this prevents finding dependent libraries that
+	  # are installed to the same prefix.
+	  # At present, this check doesn't affect windows .dll's that
+	  # are installed into $libdir/../bin (currently, that works fine)
+	  # but it's something to keep an eye on.
+	  test "$inst_prefix_dir" = "$destdir" && \
+	    func_fatal_error "error: cannot install '$file' to a directory not ending in $libdir"
+
+	  if test -n "$inst_prefix_dir"; then
+	    # Stick the inst_prefix_dir data into the link command.
+	    relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%"`
+	  else
+	    relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%%"`
+	  fi
+
+	  func_warning "relinking '$file'"
+	  func_show_eval "$relink_command" \
+	    'func_fatal_error "error: relink '\''$file'\'' with the above command before installing it"'
+	fi
+
+	# See the names of the shared library.
+	set dummy $library_names; shift
+	if test -n "$1"; then
+	  realname=$1
+	  shift
+
+	  srcname=$realname
+	  test -n "$relink_command" && srcname=${realname}T
+
+	  # Install the shared library and build the symlinks.
+	  func_show_eval "$install_shared_prog $dir/$srcname $destdir/$realname" \
+	      'exit $?'
+	  tstripme=$stripme
+	  case $host_os in
+	  cygwin* | mingw* | pw32* | cegcc*)
+	    case $realname in
+	    *.dll.a)
+	      tstripme=
+	      ;;
+	    esac
+	    ;;
+	  os2*)
+	    case $realname in
+	    *_dll.a)
+	      tstripme=
+	      ;;
+	    esac
+	    ;;
+	  esac
+	  if test -n "$tstripme" && test -n "$striplib"; then
+	    func_show_eval "$striplib $destdir/$realname" 'exit $?'
+	  fi
+
+	  if test "$#" -gt 0; then
+	    # Delete the old symlinks, and create new ones.
+	    # Try 'ln -sf' first, because the 'ln' binary might depend on
+	    # the symlink we replace!  Solaris /bin/ln does not understand -f,
+	    # so we also need to try rm && ln -s.
+	    for linkname
+	    do
+	      test "$linkname" != "$realname" \
+		&& func_show_eval "(cd $destdir && { $LN_S -f $realname $linkname || { $RM $linkname && $LN_S $realname $linkname; }; })"
+	    done
+	  fi
+
+	  # Do each command in the postinstall commands.
+	  lib=$destdir/$realname
+	  func_execute_cmds "$postinstall_cmds" 'exit $?'
+	fi
+
+	# Install the pseudo-library for information purposes.
+	func_basename "$file"
+	name=$func_basename_result
+	instname=$dir/${name}i
+	func_show_eval "$install_prog $instname $destdir/$name" 'exit $?'
+
+	# Maybe install the static library, too.
+	test -n "$old_library" && func_append staticlibs " $dir/$old_library"
+	;;
+
+      *.lo)
+	# Install (i.e. copy) a libtool object.
+
+	# Figure out destination file name, if it wasn't already specified.
+	if test -n "$destname"; then
+	  destfile=$destdir/$destname
+	else
+	  func_basename "$file"
+	  destfile=$func_basename_result
+	  destfile=$destdir/$destfile
+	fi
+
+	# Deduce the name of the destination old-style object file.
+	case $destfile in
+	*.lo)
+	  func_lo2o "$destfile"
+	  staticdest=$func_lo2o_result
+	  ;;
+	*.$objext)
+	  staticdest=$destfile
+	  destfile=
+	  ;;
+	*)
+	  func_fatal_help "cannot copy a libtool object to '$destfile'"
+	  ;;
+	esac
+
+	# Install the libtool object if requested.
+	test -n "$destfile" && \
+	  func_show_eval "$install_prog $file $destfile" 'exit $?'
+
+	# Install the old object if enabled.
+	if test yes = "$build_old_libs"; then
+	  # Deduce the name of the old-style object file.
+	  func_lo2o "$file"
+	  staticobj=$func_lo2o_result
+	  func_show_eval "$install_prog \$staticobj \$staticdest" 'exit $?'
+	fi
+	exit $EXIT_SUCCESS
+	;;
+
+      *)
+	# Figure out destination file name, if it wasn't already specified.
+	if test -n "$destname"; then
+	  destfile=$destdir/$destname
+	else
+	  func_basename "$file"
+	  destfile=$func_basename_result
+	  destfile=$destdir/$destfile
+	fi
+
+	# If the file is missing, and there is a .exe on the end, strip it
+	# because it is most likely a libtool script we actually want to
+	# install
+	stripped_ext=
+	case $file in
+	  *.exe)
+	    if test ! -f "$file"; then
+	      func_stripname '' '.exe' "$file"
+	      file=$func_stripname_result
+	      stripped_ext=.exe
+	    fi
+	    ;;
+	esac
+
+	# Do a test to see if this is really a libtool program.
+	case $host in
+	*cygwin* | *mingw*)
+	    if func_ltwrapper_executable_p "$file"; then
+	      func_ltwrapper_scriptname "$file"
+	      wrapper=$func_ltwrapper_scriptname_result
+	    else
+	      func_stripname '' '.exe' "$file"
+	      wrapper=$func_stripname_result
+	    fi
+	    ;;
+	*)
+	    wrapper=$file
+	    ;;
+	esac
+	if func_ltwrapper_script_p "$wrapper"; then
+	  notinst_deplibs=
+	  relink_command=
+
+	  func_source "$wrapper"
+
+	  # Check the variables that should have been set.
+	  test -z "$generated_by_libtool_version" && \
+	    func_fatal_error "invalid libtool wrapper script '$wrapper'"
+
+	  finalize=:
+	  for lib in $notinst_deplibs; do
+	    # Check to see that each library is installed.
+	    libdir=
+	    if test -f "$lib"; then
+	      func_source "$lib"
+	    fi
+	    libfile=$libdir/`$ECHO "$lib" | $SED 's%^.*/%%g'`
+	    if test -n "$libdir" && test ! -f "$libfile"; then
+	      func_warning "'$lib' has not been installed in '$libdir'"
+	      finalize=false
+	    fi
+	  done
+
+	  relink_command=
+	  func_source "$wrapper"
+
+	  outputname=
+	  if test no = "$fast_install" && test -n "$relink_command"; then
+	    $opt_dry_run || {
+	      if $finalize; then
+	        tmpdir=`func_mktempdir`
+		func_basename "$file$stripped_ext"
+		file=$func_basename_result
+	        outputname=$tmpdir/$file
+	        # Replace the output file specification.
+	        relink_command=`$ECHO "$relink_command" | $SED 's%@OUTPUT@%'"$outputname"'%g'`
+
+	        $opt_quiet || {
+	          func_quote_for_expand "$relink_command"
+		  eval "func_echo $func_quote_for_expand_result"
+	        }
+	        if eval "$relink_command"; then :
+	          else
+		  func_error "error: relink '$file' with the above command before installing it"
+		  $opt_dry_run || ${RM}r "$tmpdir"
+		  continue
+	        fi
+	        file=$outputname
+	      else
+	        func_warning "cannot relink '$file'"
+	      fi
+	    }
+	  else
+	    # Install the binary that we compiled earlier.
+	    file=`$ECHO "$file$stripped_ext" | $SED "s%\([^/]*\)$%$objdir/\1%"`
+	  fi
+	fi
+
+	# remove .exe since cygwin /usr/bin/install will append another
+	# one anyway
+	case $install_prog,$host in
+	*/usr/bin/install*,*cygwin*)
+	  case $file:$destfile in
+	  *.exe:*.exe)
+	    # this is ok
+	    ;;
+	  *.exe:*)
+	    destfile=$destfile.exe
+	    ;;
+	  *:*.exe)
+	    func_stripname '' '.exe' "$destfile"
+	    destfile=$func_stripname_result
+	    ;;
+	  esac
+	  ;;
+	esac
+	func_show_eval "$install_prog\$stripme \$file \$destfile" 'exit $?'
+	$opt_dry_run || if test -n "$outputname"; then
+	  ${RM}r "$tmpdir"
+	fi
+	;;
+      esac
+    done
+
+    for file in $staticlibs; do
+      func_basename "$file"
+      name=$func_basename_result
+
+      # Set up the ranlib parameters.
+      oldlib=$destdir/$name
+      func_to_tool_file "$oldlib" func_convert_file_msys_to_w32
+      tool_oldlib=$func_to_tool_file_result
+
+      func_show_eval "$install_prog \$file \$oldlib" 'exit $?'
+
+      if test -n "$stripme" && test -n "$old_striplib"; then
+	func_show_eval "$old_striplib $tool_oldlib" 'exit $?'
+      fi
+
+      # Do each command in the postinstall commands.
+      func_execute_cmds "$old_postinstall_cmds" 'exit $?'
+    done
+
+    test -n "$future_libdirs" && \
+      func_warning "remember to run '$progname --finish$future_libdirs'"
+
+    if test -n "$current_libdirs"; then
+      # Maybe just do a dry run.
+      $opt_dry_run && current_libdirs=" -n$current_libdirs"
+      exec_cmd='$SHELL "$progpath" $preserve_args --finish$current_libdirs'
+    else
+      exit $EXIT_SUCCESS
+    fi
+}
+
+test install = "$opt_mode" && func_mode_install ${1+"$@"}
+
+
+# func_generate_dlsyms outputname originator pic_p
+# Extract symbols from dlprefiles and create ${outputname}S.o with
+# a dlpreopen symbol table.
+func_generate_dlsyms ()
+{
+    $debug_cmd
+
+    my_outputname=$1
+    my_originator=$2
+    my_pic_p=${3-false}
+    my_prefix=`$ECHO "$my_originator" | $SED 's%[^a-zA-Z0-9]%_%g'`
+    my_dlsyms=
+
+    if test -n "$dlfiles$dlprefiles" || test no != "$dlself"; then
+      if test -n "$NM" && test -n "$global_symbol_pipe"; then
+	my_dlsyms=${my_outputname}S.c
+      else
+	func_error "not configured to extract global symbols from dlpreopened files"
+      fi
+    fi
+
+    if test -n "$my_dlsyms"; then
+      case $my_dlsyms in
+      "") ;;
+      *.c)
+	# Discover the nlist of each of the dlfiles.
+	nlist=$output_objdir/$my_outputname.nm
+
+	func_show_eval "$RM $nlist ${nlist}S ${nlist}T"
+
+	# Parse the name list into a source file.
+	func_verbose "creating $output_objdir/$my_dlsyms"
+
+	$opt_dry_run || $ECHO > "$output_objdir/$my_dlsyms" "\
+/* $my_dlsyms - symbol resolution table for '$my_outputname' dlsym emulation. */
+/* Generated by $PROGRAM (GNU $PACKAGE) $VERSION */
+
+#ifdef __cplusplus
+extern \"C\" {
+#endif
+
+#if defined __GNUC__ && (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 4)) || (__GNUC__ > 4))
+#pragma GCC diagnostic ignored \"-Wstrict-prototypes\"
+#endif
+
+/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests.  */
+#if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE
+/* DATA imports from DLLs on WIN32 can't be const, because runtime
+   relocations are performed -- see ld's documentation on pseudo-relocs.  */
+# define LT_DLSYM_CONST
+#elif defined __osf__
+/* This system does not cope well with relocations in const data.  */
+# define LT_DLSYM_CONST
+#else
+# define LT_DLSYM_CONST const
+#endif
+
+#define STREQ(s1, s2) (strcmp ((s1), (s2)) == 0)
+
+/* External symbol declarations for the compiler. */\
+"
+
+	if test yes = "$dlself"; then
+	  func_verbose "generating symbol list for '$output'"
+
+	  $opt_dry_run || echo ': @PROGRAM@ ' > "$nlist"
+
+	  # Add our own program objects to the symbol list.
+	  progfiles=`$ECHO "$objs$old_deplibs" | $SP2NL | $SED "$lo2o" | $NL2SP`
+	  for progfile in $progfiles; do
+	    func_to_tool_file "$progfile" func_convert_file_msys_to_w32
+	    func_verbose "extracting global C symbols from '$func_to_tool_file_result'"
+	    $opt_dry_run || eval "$NM $func_to_tool_file_result | $global_symbol_pipe >> '$nlist'"
+	  done
+
+	  if test -n "$exclude_expsyms"; then
+	    $opt_dry_run || {
+	      eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T'
+	      eval '$MV "$nlist"T "$nlist"'
+	    }
+	  fi
+
+	  if test -n "$export_symbols_regex"; then
+	    $opt_dry_run || {
+	      eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T'
+	      eval '$MV "$nlist"T "$nlist"'
+	    }
+	  fi
+
+	  # Prepare the list of exported symbols
+	  if test -z "$export_symbols"; then
+	    export_symbols=$output_objdir/$outputname.exp
+	    $opt_dry_run || {
+	      $RM $export_symbols
+	      eval "$SED -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"'
+	      case $host in
+	      *cygwin* | *mingw* | *cegcc* )
+                eval "echo EXPORTS "'> "$output_objdir/$outputname.def"'
+                eval 'cat "$export_symbols" >> "$output_objdir/$outputname.def"'
+	        ;;
+	      esac
+	    }
+	  else
+	    $opt_dry_run || {
+	      eval "$SED -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"'
+	      eval '$GREP -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T'
+	      eval '$MV "$nlist"T "$nlist"'
+	      case $host in
+	        *cygwin* | *mingw* | *cegcc* )
+	          eval "echo EXPORTS "'> "$output_objdir/$outputname.def"'
+	          eval 'cat "$nlist" >> "$output_objdir/$outputname.def"'
+	          ;;
+	      esac
+	    }
+	  fi
+	fi
+
+	for dlprefile in $dlprefiles; do
+	  func_verbose "extracting global C symbols from '$dlprefile'"
+	  func_basename "$dlprefile"
+	  name=$func_basename_result
+          case $host in
+	    *cygwin* | *mingw* | *cegcc* )
+	      # if an import library, we need to obtain dlname
+	      if func_win32_import_lib_p "$dlprefile"; then
+	        func_tr_sh "$dlprefile"
+	        eval "curr_lafile=\$libfile_$func_tr_sh_result"
+	        dlprefile_dlbasename=
+	        if test -n "$curr_lafile" && func_lalib_p "$curr_lafile"; then
+	          # Use subshell, to avoid clobbering current variable values
+	          dlprefile_dlname=`source "$curr_lafile" && echo "$dlname"`
+	          if test -n "$dlprefile_dlname"; then
+	            func_basename "$dlprefile_dlname"
+	            dlprefile_dlbasename=$func_basename_result
+	          else
+	            # no lafile. user explicitly requested -dlpreopen <import library>.
+	            $sharedlib_from_linklib_cmd "$dlprefile"
+	            dlprefile_dlbasename=$sharedlib_from_linklib_result
+	          fi
+	        fi
+	        $opt_dry_run || {
+	          if test -n "$dlprefile_dlbasename"; then
+	            eval '$ECHO ": $dlprefile_dlbasename" >> "$nlist"'
+	          else
+	            func_warning "Could not compute DLL name from $name"
+	            eval '$ECHO ": $name " >> "$nlist"'
+	          fi
+	          func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32
+	          eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe |
+	            $SED -e '/I __imp/d' -e 's/I __nm_/D /;s/_nm__//' >> '$nlist'"
+	        }
+	      else # not an import lib
+	        $opt_dry_run || {
+	          eval '$ECHO ": $name " >> "$nlist"'
+	          func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32
+	          eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'"
+	        }
+	      fi
+	    ;;
+	    *)
+	      $opt_dry_run || {
+	        eval '$ECHO ": $name " >> "$nlist"'
+	        func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32
+	        eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'"
+	      }
+	    ;;
+          esac
+	done
+
+	$opt_dry_run || {
+	  # Make sure we have at least an empty file.
+	  test -f "$nlist" || : > "$nlist"
+
+	  if test -n "$exclude_expsyms"; then
+	    $EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T
+	    $MV "$nlist"T "$nlist"
+	  fi
+
+	  # Try sorting and uniquifying the output.
+	  if $GREP -v "^: " < "$nlist" |
+	      if sort -k 3 </dev/null >/dev/null 2>&1; then
+		sort -k 3
+	      else
+		sort +2
+	      fi |
+	      uniq > "$nlist"S; then
+	    :
+	  else
+	    $GREP -v "^: " < "$nlist" > "$nlist"S
+	  fi
+
+	  if test -f "$nlist"S; then
+	    eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$my_dlsyms"'
+	  else
+	    echo '/* NONE */' >> "$output_objdir/$my_dlsyms"
+	  fi
+
+	  func_show_eval '$RM "${nlist}I"'
+	  if test -n "$global_symbol_to_import"; then
+	    eval "$global_symbol_to_import"' < "$nlist"S > "$nlist"I'
+	  fi
+
+	  echo >> "$output_objdir/$my_dlsyms" "\
+
+/* The mapping between symbol names and symbols.  */
+typedef struct {
+  const char *name;
+  void *address;
+} lt_dlsymlist;
+extern LT_DLSYM_CONST lt_dlsymlist
+lt_${my_prefix}_LTX_preloaded_symbols[];\
+"
+
+	  if test -s "$nlist"I; then
+	    echo >> "$output_objdir/$my_dlsyms" "\
+static void lt_syminit(void)
+{
+  LT_DLSYM_CONST lt_dlsymlist *symbol = lt_${my_prefix}_LTX_preloaded_symbols;
+  for (; symbol->name; ++symbol)
+    {"
+	    $SED 's/.*/      if (STREQ (symbol->name, \"&\")) symbol->address = (void *) \&&;/' < "$nlist"I >> "$output_objdir/$my_dlsyms"
+	    echo >> "$output_objdir/$my_dlsyms" "\
+    }
+}"
+	  fi
+	  echo >> "$output_objdir/$my_dlsyms" "\
+LT_DLSYM_CONST lt_dlsymlist
+lt_${my_prefix}_LTX_preloaded_symbols[] =
+{ {\"$my_originator\", (void *) 0},"
+
+	  if test -s "$nlist"I; then
+	    echo >> "$output_objdir/$my_dlsyms" "\
+  {\"@INIT@\", (void *) &lt_syminit},"
+	  fi
+
+	  case $need_lib_prefix in
+	  no)
+	    eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$my_dlsyms"
+	    ;;
+	  *)
+	    eval "$global_symbol_to_c_name_address_lib_prefix" < "$nlist" >> "$output_objdir/$my_dlsyms"
+	    ;;
+	  esac
+	  echo >> "$output_objdir/$my_dlsyms" "\
+  {0, (void *) 0}
+};
+
+/* This works around a problem in FreeBSD linker */
+#ifdef FREEBSD_WORKAROUND
+static const void *lt_preloaded_setup() {
+  return lt_${my_prefix}_LTX_preloaded_symbols;
+}
+#endif
+
+#ifdef __cplusplus
+}
+#endif\
+"
+	} # !$opt_dry_run
+
+	pic_flag_for_symtable=
+	case "$compile_command " in
+	*" -static "*) ;;
+	*)
+	  case $host in
+	  # compiling the symbol table file with pic_flag works around
+	  # a FreeBSD bug that causes programs to crash when -lm is
+	  # linked before any other PIC object.  But we must not use
+	  # pic_flag when linking with -static.  The problem exists in
+	  # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1.
+	  *-*-freebsd2.*|*-*-freebsd3.0*|*-*-freebsdelf3.0*)
+	    pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND" ;;
+	  *-*-hpux*)
+	    pic_flag_for_symtable=" $pic_flag"  ;;
+	  *)
+	    $my_pic_p && pic_flag_for_symtable=" $pic_flag"
+	    ;;
+	  esac
+	  ;;
+	esac
+	symtab_cflags=
+	for arg in $LTCFLAGS; do
+	  case $arg in
+	  -pie | -fpie | -fPIE) ;;
+	  *) func_append symtab_cflags " $arg" ;;
+	  esac
+	done
+
+	# Now compile the dynamic symbol file.
+	func_show_eval '(cd $output_objdir && $LTCC$symtab_cflags -c$no_builtin_flag$pic_flag_for_symtable "$my_dlsyms")' 'exit $?'
+
+	# Clean up the generated files.
+	func_show_eval '$RM "$output_objdir/$my_dlsyms" "$nlist" "${nlist}S" "${nlist}T" "${nlist}I"'
+
+	# Transform the symbol file into the correct name.
+	symfileobj=$output_objdir/${my_outputname}S.$objext
+	case $host in
+	*cygwin* | *mingw* | *cegcc* )
+	  if test -f "$output_objdir/$my_outputname.def"; then
+	    compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"`
+	    finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"`
+	  else
+	    compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"`
+	    finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"`
+	  fi
+	  ;;
+	*)
+	  compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"`
+	  finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"`
+	  ;;
+	esac
+	;;
+      *)
+	func_fatal_error "unknown suffix for '$my_dlsyms'"
+	;;
+      esac
+    else
+      # We keep going just in case the user didn't refer to
+      # lt_preloaded_symbols.  The linker will fail if global_symbol_pipe
+      # really was required.
+
+      # Nullify the symbol file.
+      compile_command=`$ECHO "$compile_command" | $SED "s% @SYMFILE@%%"`
+      finalize_command=`$ECHO "$finalize_command" | $SED "s% @SYMFILE@%%"`
+    fi
+}
+
+# func_cygming_gnu_implib_p ARG
+# This predicate returns with zero status (TRUE) if
+# ARG is a GNU/binutils-style import library. Returns
+# with nonzero status (FALSE) otherwise.
+func_cygming_gnu_implib_p ()
+{
+  $debug_cmd
+
+  func_to_tool_file "$1" func_convert_file_msys_to_w32
+  func_cygming_gnu_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $EGREP ' (_head_[A-Za-z0-9_]+_[ad]l*|[A-Za-z0-9_]+_[ad]l*_iname)$'`
+  test -n "$func_cygming_gnu_implib_tmp"
+}
+
+# func_cygming_ms_implib_p ARG
+# This predicate returns with zero status (TRUE) if
+# ARG is an MS-style import library. Returns
+# with nonzero status (FALSE) otherwise.
+func_cygming_ms_implib_p ()
+{
+  $debug_cmd
+
+  func_to_tool_file "$1" func_convert_file_msys_to_w32
+  func_cygming_ms_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $GREP '_NULL_IMPORT_DESCRIPTOR'`
+  test -n "$func_cygming_ms_implib_tmp"
+}
+
+# func_win32_libid arg
+# return the library type of file 'arg'
+#
+# Need a lot of goo to handle *both* DLLs and import libs
+# Has to be a shell function in order to 'eat' the argument
+# that is supplied when $file_magic_command is called.
+# Despite the name, also deal with 64 bit binaries.
+func_win32_libid ()
+{
+  $debug_cmd
+
+  win32_libid_type=unknown
+  win32_fileres=`file -L $1 2>/dev/null`
+  case $win32_fileres in
+  *ar\ archive\ import\ library*) # definitely import
+    win32_libid_type="x86 archive import"
+    ;;
+  *ar\ archive*) # could be an import, or static
+    # Keep the egrep pattern in sync with the one in _LT_CHECK_MAGIC_METHOD.
+    if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null |
+       $EGREP 'file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' >/dev/null; then
+      case $nm_interface in
+      "MS dumpbin")
+	if func_cygming_ms_implib_p "$1" ||
+	   func_cygming_gnu_implib_p "$1"
+	then
+	  win32_nmres=import
+	else
+	  win32_nmres=
+	fi
+	;;
+      *)
+	func_to_tool_file "$1" func_convert_file_msys_to_w32
+	win32_nmres=`eval $NM -f posix -A \"$func_to_tool_file_result\" |
+	  $SED -n -e '
+	    1,100{
+		/ I /{
+		    s|.*|import|
+		    p
+		    q
+		}
+	    }'`
+	;;
+      esac
+      case $win32_nmres in
+      import*)  win32_libid_type="x86 archive import";;
+      *)        win32_libid_type="x86 archive static";;
+      esac
+    fi
+    ;;
+  *DLL*)
+    win32_libid_type="x86 DLL"
+    ;;
+  *executable*) # but shell scripts are "executable" too...
+    case $win32_fileres in
+    *MS\ Windows\ PE\ Intel*)
+      win32_libid_type="x86 DLL"
+      ;;
+    esac
+    ;;
+  esac
+  $ECHO "$win32_libid_type"
+}
+
+# func_cygming_dll_for_implib ARG
+#
+# Platform-specific function to extract the
+# name of the DLL associated with the specified
+# import library ARG.
+# Invoked by eval'ing the libtool variable
+#    $sharedlib_from_linklib_cmd
+# Result is available in the variable
+#    $sharedlib_from_linklib_result
+func_cygming_dll_for_implib ()
+{
+  $debug_cmd
+
+  sharedlib_from_linklib_result=`$DLLTOOL --identify-strict --identify "$1"`
+}
+
+# func_cygming_dll_for_implib_fallback_core SECTION_NAME LIBNAMEs
+#
+# The is the core of a fallback implementation of a
+# platform-specific function to extract the name of the
+# DLL associated with the specified import library LIBNAME.
+#
+# SECTION_NAME is either .idata$6 or .idata$7, depending
+# on the platform and compiler that created the implib.
+#
+# Echos the name of the DLL associated with the
+# specified import library.
+func_cygming_dll_for_implib_fallback_core ()
+{
+  $debug_cmd
+
+  match_literal=`$ECHO "$1" | $SED "$sed_make_literal_regex"`
+  $OBJDUMP -s --section "$1" "$2" 2>/dev/null |
+    $SED '/^Contents of section '"$match_literal"':/{
+      # Place marker at beginning of archive member dllname section
+      s/.*/====MARK====/
+      p
+      d
+    }
+    # These lines can sometimes be longer than 43 characters, but
+    # are always uninteresting
+    /:[	 ]*file format pe[i]\{,1\}-/d
+    /^In archive [^:]*:/d
+    # Ensure marker is printed
+    /^====MARK====/p
+    # Remove all lines with less than 43 characters
+    /^.\{43\}/!d
+    # From remaining lines, remove first 43 characters
+    s/^.\{43\}//' |
+    $SED -n '
+      # Join marker and all lines until next marker into a single line
+      /^====MARK====/ b para
+      H
+      $ b para
+      b
+      :para
+      x
+      s/\n//g
+      # Remove the marker
+      s/^====MARK====//
+      # Remove trailing dots and whitespace
+      s/[\. \t]*$//
+      # Print
+      /./p' |
+    # we now have a list, one entry per line, of the stringified
+    # contents of the appropriate section of all members of the
+    # archive that possess that section. Heuristic: eliminate
+    # all those that have a first or second character that is
+    # a '.' (that is, objdump's representation of an unprintable
+    # character.) This should work for all archives with less than
+    # 0x302f exports -- but will fail for DLLs whose name actually
+    # begins with a literal '.' or a single character followed by
+    # a '.'.
+    #
+    # Of those that remain, print the first one.
+    $SED -e '/^\./d;/^.\./d;q'
+}
+
+# func_cygming_dll_for_implib_fallback ARG
+# Platform-specific function to extract the
+# name of the DLL associated with the specified
+# import library ARG.
+#
+# This fallback implementation is for use when $DLLTOOL
+# does not support the --identify-strict option.
+# Invoked by eval'ing the libtool variable
+#    $sharedlib_from_linklib_cmd
+# Result is available in the variable
+#    $sharedlib_from_linklib_result
+func_cygming_dll_for_implib_fallback ()
+{
+  $debug_cmd
+
+  if func_cygming_gnu_implib_p "$1"; then
+    # binutils import library
+    sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$7' "$1"`
+  elif func_cygming_ms_implib_p "$1"; then
+    # ms-generated import library
+    sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$6' "$1"`
+  else
+    # unknown
+    sharedlib_from_linklib_result=
+  fi
+}
+
+
+# func_extract_an_archive dir oldlib
+func_extract_an_archive ()
+{
+    $debug_cmd
+
+    f_ex_an_ar_dir=$1; shift
+    f_ex_an_ar_oldlib=$1
+    if test yes = "$lock_old_archive_extraction"; then
+      lockfile=$f_ex_an_ar_oldlib.lock
+      until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do
+	func_echo "Waiting for $lockfile to be removed"
+	sleep 2
+      done
+    fi
+    func_show_eval "(cd \$f_ex_an_ar_dir && $AR x \"\$f_ex_an_ar_oldlib\")" \
+		   'stat=$?; rm -f "$lockfile"; exit $stat'
+    if test yes = "$lock_old_archive_extraction"; then
+      $opt_dry_run || rm -f "$lockfile"
+    fi
+    if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then
+     :
+    else
+      func_fatal_error "object name conflicts in archive: $f_ex_an_ar_dir/$f_ex_an_ar_oldlib"
+    fi
+}
+
+
+# func_extract_archives gentop oldlib ...
+func_extract_archives ()
+{
+    $debug_cmd
+
+    my_gentop=$1; shift
+    my_oldlibs=${1+"$@"}
+    my_oldobjs=
+    my_xlib=
+    my_xabs=
+    my_xdir=
+
+    for my_xlib in $my_oldlibs; do
+      # Extract the objects.
+      case $my_xlib in
+	[\\/]* | [A-Za-z]:[\\/]*) my_xabs=$my_xlib ;;
+	*) my_xabs=`pwd`"/$my_xlib" ;;
+      esac
+      func_basename "$my_xlib"
+      my_xlib=$func_basename_result
+      my_xlib_u=$my_xlib
+      while :; do
+        case " $extracted_archives " in
+	*" $my_xlib_u "*)
+	  func_arith $extracted_serial + 1
+	  extracted_serial=$func_arith_result
+	  my_xlib_u=lt$extracted_serial-$my_xlib ;;
+	*) break ;;
+	esac
+      done
+      extracted_archives="$extracted_archives $my_xlib_u"
+      my_xdir=$my_gentop/$my_xlib_u
+
+      func_mkdir_p "$my_xdir"
+
+      case $host in
+      *-darwin*)
+	func_verbose "Extracting $my_xabs"
+	# Do not bother doing anything if just a dry run
+	$opt_dry_run || {
+	  darwin_orig_dir=`pwd`
+	  cd $my_xdir || exit $?
+	  darwin_archive=$my_xabs
+	  darwin_curdir=`pwd`
+	  func_basename "$darwin_archive"
+	  darwin_base_archive=$func_basename_result
+	  darwin_arches=`$LIPO -info "$darwin_archive" 2>/dev/null | $GREP Architectures 2>/dev/null || true`
+	  if test -n "$darwin_arches"; then
+	    darwin_arches=`$ECHO "$darwin_arches" | $SED -e 's/.*are://'`
+	    darwin_arch=
+	    func_verbose "$darwin_base_archive has multiple architectures $darwin_arches"
+	    for darwin_arch in  $darwin_arches; do
+	      func_mkdir_p "unfat-$$/$darwin_base_archive-$darwin_arch"
+	      $LIPO -thin $darwin_arch -output "unfat-$$/$darwin_base_archive-$darwin_arch/$darwin_base_archive" "$darwin_archive"
+	      cd "unfat-$$/$darwin_base_archive-$darwin_arch"
+	      func_extract_an_archive "`pwd`" "$darwin_base_archive"
+	      cd "$darwin_curdir"
+	      $RM "unfat-$$/$darwin_base_archive-$darwin_arch/$darwin_base_archive"
+	    done # $darwin_arches
+            ## Okay now we've a bunch of thin objects, gotta fatten them up :)
+	    darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print | $SED -e "$sed_basename" | sort -u`
+	    darwin_file=
+	    darwin_files=
+	    for darwin_file in $darwin_filelist; do
+	      darwin_files=`find unfat-$$ -name $darwin_file -print | sort | $NL2SP`
+	      $LIPO -create -output "$darwin_file" $darwin_files
+	    done # $darwin_filelist
+	    $RM -rf unfat-$$
+	    cd "$darwin_orig_dir"
+	  else
+	    cd $darwin_orig_dir
+	    func_extract_an_archive "$my_xdir" "$my_xabs"
+	  fi # $darwin_arches
+	} # !$opt_dry_run
+	;;
+      *)
+        func_extract_an_archive "$my_xdir" "$my_xabs"
+	;;
+      esac
+      my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | sort | $NL2SP`
+    done
+
+    func_extract_archives_result=$my_oldobjs
+}
+
+
+# func_emit_wrapper [arg=no]
+#
+# Emit a libtool wrapper script on stdout.
+# Don't directly open a file because we may want to
+# incorporate the script contents within a cygwin/mingw
+# wrapper executable.  Must ONLY be called from within
+# func_mode_link because it depends on a number of variables
+# set therein.
+#
+# ARG is the value that the WRAPPER_SCRIPT_BELONGS_IN_OBJDIR
+# variable will take.  If 'yes', then the emitted script
+# will assume that the directory where it is stored is
+# the $objdir directory.  This is a cygwin/mingw-specific
+# behavior.
+func_emit_wrapper ()
+{
+	func_emit_wrapper_arg1=${1-no}
+
+	$ECHO "\
+#! $SHELL
+
+# $output - temporary wrapper script for $objdir/$outputname
+# Generated by $PROGRAM (GNU $PACKAGE) $VERSION
+#
+# The $output program cannot be directly executed until all the libtool
+# libraries that it depends on are installed.
+#
+# This wrapper script should never be moved out of the build directory.
+# If it is, it will not operate correctly.
+
+# Sed substitution that helps us do robust quoting.  It backslashifies
+# metacharacters that are still active within double-quoted strings.
+sed_quote_subst='$sed_quote_subst'
+
+# Be Bourne compatible
+if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then
+  emulate sh
+  NULLCMD=:
+  # Zsh 3.x and 4.x performs word splitting on \${1+\"\$@\"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '\${1+\"\$@\"}'='\"\$@\"'
+  setopt NO_GLOB_SUBST
+else
+  case \`(set -o) 2>/dev/null\` in *posix*) set -o posix;; esac
+fi
+BIN_SH=xpg4; export BIN_SH # for Tru64
+DUALCASE=1; export DUALCASE # for MKS sh
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+relink_command=\"$relink_command\"
+
+# This environment variable determines our operation mode.
+if test \"\$libtool_install_magic\" = \"$magic\"; then
+  # install mode needs the following variables:
+  generated_by_libtool_version='$macro_version'
+  notinst_deplibs='$notinst_deplibs'
+else
+  # When we are sourced in execute mode, \$file and \$ECHO are already set.
+  if test \"\$libtool_execute_magic\" != \"$magic\"; then
+    file=\"\$0\""
+
+    qECHO=`$ECHO "$ECHO" | $SED "$sed_quote_subst"`
+    $ECHO "\
+
+# A function that is used when there is no print builtin or printf.
+func_fallback_echo ()
+{
+  eval 'cat <<_LTECHO_EOF
+\$1
+_LTECHO_EOF'
+}
+    ECHO=\"$qECHO\"
+  fi
+
+# Very basic option parsing. These options are (a) specific to
+# the libtool wrapper, (b) are identical between the wrapper
+# /script/ and the wrapper /executable/ that is used only on
+# windows platforms, and (c) all begin with the string "--lt-"
+# (application programs are unlikely to have options that match
+# this pattern).
+#
+# There are only two supported options: --lt-debug and
+# --lt-dump-script. There is, deliberately, no --lt-help.
+#
+# The first argument to this parsing function should be the
+# script's $0 value, followed by "$@".
+lt_option_debug=
+func_parse_lt_options ()
+{
+  lt_script_arg0=\$0
+  shift
+  for lt_opt
+  do
+    case \"\$lt_opt\" in
+    --lt-debug) lt_option_debug=1 ;;
+    --lt-dump-script)
+        lt_dump_D=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%/[^/]*$%%'\`
+        test \"X\$lt_dump_D\" = \"X\$lt_script_arg0\" && lt_dump_D=.
+        lt_dump_F=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%^.*/%%'\`
+        cat \"\$lt_dump_D/\$lt_dump_F\"
+        exit 0
+      ;;
+    --lt-*)
+        \$ECHO \"Unrecognized --lt- option: '\$lt_opt'\" 1>&2
+        exit 1
+      ;;
+    esac
+  done
+
+  # Print the debug banner immediately:
+  if test -n \"\$lt_option_debug\"; then
+    echo \"$outputname:$output:\$LINENO: libtool wrapper (GNU $PACKAGE) $VERSION\" 1>&2
+  fi
+}
+
+# Used when --lt-debug. Prints its arguments to stdout
+# (redirection is the responsibility of the caller)
+func_lt_dump_args ()
+{
+  lt_dump_args_N=1;
+  for lt_arg
+  do
+    \$ECHO \"$outputname:$output:\$LINENO: newargv[\$lt_dump_args_N]: \$lt_arg\"
+    lt_dump_args_N=\`expr \$lt_dump_args_N + 1\`
+  done
+}
+
+# Core function for launching the target application
+func_exec_program_core ()
+{
+"
+  case $host in
+  # Backslashes separate directories on plain windows
+  *-*-mingw | *-*-os2* | *-cegcc*)
+    $ECHO "\
+      if test -n \"\$lt_option_debug\"; then
+        \$ECHO \"$outputname:$output:\$LINENO: newargv[0]: \$progdir\\\\\$program\" 1>&2
+        func_lt_dump_args \${1+\"\$@\"} 1>&2
+      fi
+      exec \"\$progdir\\\\\$program\" \${1+\"\$@\"}
+"
+    ;;
+
+  *)
+    $ECHO "\
+      if test -n \"\$lt_option_debug\"; then
+        \$ECHO \"$outputname:$output:\$LINENO: newargv[0]: \$progdir/\$program\" 1>&2
+        func_lt_dump_args \${1+\"\$@\"} 1>&2
+      fi
+      exec \"\$progdir/\$program\" \${1+\"\$@\"}
+"
+    ;;
+  esac
+  $ECHO "\
+      \$ECHO \"\$0: cannot exec \$program \$*\" 1>&2
+      exit 1
+}
+
+# A function to encapsulate launching the target application
+# Strips options in the --lt-* namespace from \$@ and
+# launches target application with the remaining arguments.
+func_exec_program ()
+{
+  case \" \$* \" in
+  *\\ --lt-*)
+    for lt_wr_arg
+    do
+      case \$lt_wr_arg in
+      --lt-*) ;;
+      *) set x \"\$@\" \"\$lt_wr_arg\"; shift;;
+      esac
+      shift
+    done ;;
+  esac
+  func_exec_program_core \${1+\"\$@\"}
+}
+
+  # Parse options
+  func_parse_lt_options \"\$0\" \${1+\"\$@\"}
+
+  # Find the directory that this script lives in.
+  thisdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*$%%'\`
+  test \"x\$thisdir\" = \"x\$file\" && thisdir=.
+
+  # Follow symbolic links until we get to the real thisdir.
+  file=\`ls -ld \"\$file\" | $SED -n 's/.*-> //p'\`
+  while test -n \"\$file\"; do
+    destdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*\$%%'\`
+
+    # If there was a directory component, then change thisdir.
+    if test \"x\$destdir\" != \"x\$file\"; then
+      case \"\$destdir\" in
+      [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;;
+      *) thisdir=\"\$thisdir/\$destdir\" ;;
+      esac
+    fi
+
+    file=\`\$ECHO \"\$file\" | $SED 's%^.*/%%'\`
+    file=\`ls -ld \"\$thisdir/\$file\" | $SED -n 's/.*-> //p'\`
+  done
+
+  # Usually 'no', except on cygwin/mingw when embedded into
+  # the cwrapper.
+  WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=$func_emit_wrapper_arg1
+  if test \"\$WRAPPER_SCRIPT_BELONGS_IN_OBJDIR\" = \"yes\"; then
+    # special case for '.'
+    if test \"\$thisdir\" = \".\"; then
+      thisdir=\`pwd\`
+    fi
+    # remove .libs from thisdir
+    case \"\$thisdir\" in
+    *[\\\\/]$objdir ) thisdir=\`\$ECHO \"\$thisdir\" | $SED 's%[\\\\/][^\\\\/]*$%%'\` ;;
+    $objdir )   thisdir=. ;;
+    esac
+  fi
+
+  # Try to get the absolute directory name.
+  absdir=\`cd \"\$thisdir\" && pwd\`
+  test -n \"\$absdir\" && thisdir=\"\$absdir\"
+"
+
+	if test yes = "$fast_install"; then
+	  $ECHO "\
+  program=lt-'$outputname'$exeext
+  progdir=\"\$thisdir/$objdir\"
+
+  if test ! -f \"\$progdir/\$program\" ||
+     { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | $SED 1q\`; \\
+       test \"X\$file\" != \"X\$progdir/\$program\"; }; then
+
+    file=\"\$\$-\$program\"
+
+    if test ! -d \"\$progdir\"; then
+      $MKDIR \"\$progdir\"
+    else
+      $RM \"\$progdir/\$file\"
+    fi"
+
+	  $ECHO "\
+
+    # relink executable if necessary
+    if test -n \"\$relink_command\"; then
+      if relink_command_output=\`eval \$relink_command 2>&1\`; then :
+      else
+	\$ECHO \"\$relink_command_output\" >&2
+	$RM \"\$progdir/\$file\"
+	exit 1
+      fi
+    fi
+
+    $MV \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null ||
+    { $RM \"\$progdir/\$program\";
+      $MV \"\$progdir/\$file\" \"\$progdir/\$program\"; }
+    $RM \"\$progdir/\$file\"
+  fi"
+	else
+	  $ECHO "\
+  program='$outputname'
+  progdir=\"\$thisdir/$objdir\"
+"
+	fi
+
+	$ECHO "\
+
+  if test -f \"\$progdir/\$program\"; then"
+
+	# fixup the dll searchpath if we need to.
+	#
+	# Fix the DLL searchpath if we need to.  Do this before prepending
+	# to shlibpath, because on Windows, both are PATH and uninstalled
+	# libraries must come first.
+	if test -n "$dllsearchpath"; then
+	  $ECHO "\
+    # Add the dll search path components to the executable PATH
+    PATH=$dllsearchpath:\$PATH
+"
+	fi
+
+	# Export our shlibpath_var if we have one.
+	if test yes = "$shlibpath_overrides_runpath" && test -n "$shlibpath_var" && test -n "$temp_rpath"; then
+	  $ECHO "\
+    # Add our own library path to $shlibpath_var
+    $shlibpath_var=\"$temp_rpath\$$shlibpath_var\"
+
+    # Some systems cannot cope with colon-terminated $shlibpath_var
+    # The second colon is a workaround for a bug in BeOS R4 sed
+    $shlibpath_var=\`\$ECHO \"\$$shlibpath_var\" | $SED 's/::*\$//'\`
+
+    export $shlibpath_var
+"
+	fi
+
+	$ECHO "\
+    if test \"\$libtool_execute_magic\" != \"$magic\"; then
+      # Run the actual program with our arguments.
+      func_exec_program \${1+\"\$@\"}
+    fi
+  else
+    # The program doesn't exist.
+    \$ECHO \"\$0: error: '\$progdir/\$program' does not exist\" 1>&2
+    \$ECHO \"This script is just a wrapper for \$program.\" 1>&2
+    \$ECHO \"See the $PACKAGE documentation for more information.\" 1>&2
+    exit 1
+  fi
+fi\
+"
+}
+
+
+# func_emit_cwrapperexe_src
+# emit the source code for a wrapper executable on stdout
+# Must ONLY be called from within func_mode_link because
+# it depends on a number of variable set therein.
+func_emit_cwrapperexe_src ()
+{
+	cat <<EOF
+
+/* $cwrappersource - temporary wrapper executable for $objdir/$outputname
+   Generated by $PROGRAM (GNU $PACKAGE) $VERSION
+
+   The $output program cannot be directly executed until all the libtool
+   libraries that it depends on are installed.
+
+   This wrapper executable should never be moved out of the build directory.
+   If it is, it will not operate correctly.
+*/
+EOF
+	    cat <<"EOF"
+#ifdef _MSC_VER
+# define _CRT_SECURE_NO_DEPRECATE 1
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef _MSC_VER
+# include <direct.h>
+# include <process.h>
+# include <io.h>
+#else
+# include <unistd.h>
+# include <stdint.h>
+# ifdef __CYGWIN__
+#  include <io.h>
+# endif
+#endif
+#include <malloc.h>
+#include <stdarg.h>
+#include <assert.h>
+#include <string.h>
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+
+#define STREQ(s1, s2) (strcmp ((s1), (s2)) == 0)
+
+/* declarations of non-ANSI functions */
+#if defined __MINGW32__
+# ifdef __STRICT_ANSI__
+int _putenv (const char *);
+# endif
+#elif defined __CYGWIN__
+# ifdef __STRICT_ANSI__
+char *realpath (const char *, char *);
+int putenv (char *);
+int setenv (const char *, const char *, int);
+# endif
+/* #elif defined other_platform || defined ... */
+#endif
+
+/* portability defines, excluding path handling macros */
+#if defined _MSC_VER
+# define setmode _setmode
+# define stat    _stat
+# define chmod   _chmod
+# define getcwd  _getcwd
+# define putenv  _putenv
+# define S_IXUSR _S_IEXEC
+#elif defined __MINGW32__
+# define setmode _setmode
+# define stat    _stat
+# define chmod   _chmod
+# define getcwd  _getcwd
+# define putenv  _putenv
+#elif defined __CYGWIN__
+# define HAVE_SETENV
+# define FOPEN_WB "wb"
+/* #elif defined other platforms ... */
+#endif
+
+#if defined PATH_MAX
+# define LT_PATHMAX PATH_MAX
+#elif defined MAXPATHLEN
+# define LT_PATHMAX MAXPATHLEN
+#else
+# define LT_PATHMAX 1024
+#endif
+
+#ifndef S_IXOTH
+# define S_IXOTH 0
+#endif
+#ifndef S_IXGRP
+# define S_IXGRP 0
+#endif
+
+/* path handling portability macros */
+#ifndef DIR_SEPARATOR
+# define DIR_SEPARATOR '/'
+# define PATH_SEPARATOR ':'
+#endif
+
+#if defined _WIN32 || defined __MSDOS__ || defined __DJGPP__ || \
+  defined __OS2__
+# define HAVE_DOS_BASED_FILE_SYSTEM
+# define FOPEN_WB "wb"
+# ifndef DIR_SEPARATOR_2
+#  define DIR_SEPARATOR_2 '\\'
+# endif
+# ifndef PATH_SEPARATOR_2
+#  define PATH_SEPARATOR_2 ';'
+# endif
+#endif
+
+#ifndef DIR_SEPARATOR_2
+# define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR)
+#else /* DIR_SEPARATOR_2 */
+# define IS_DIR_SEPARATOR(ch) \
+	(((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2))
+#endif /* DIR_SEPARATOR_2 */
+
+#ifndef PATH_SEPARATOR_2
+# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR)
+#else /* PATH_SEPARATOR_2 */
+# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR_2)
+#endif /* PATH_SEPARATOR_2 */
+
+#ifndef FOPEN_WB
+# define FOPEN_WB "w"
+#endif
+#ifndef _O_BINARY
+# define _O_BINARY 0
+#endif
+
+#define XMALLOC(type, num)      ((type *) xmalloc ((num) * sizeof(type)))
+#define XFREE(stale) do { \
+  if (stale) { free (stale); stale = 0; } \
+} while (0)
+
+#if defined LT_DEBUGWRAPPER
+static int lt_debug = 1;
+#else
+static int lt_debug = 0;
+#endif
+
+const char *program_name = "libtool-wrapper"; /* in case xstrdup fails */
+
+void *xmalloc (size_t num);
+char *xstrdup (const char *string);
+const char *base_name (const char *name);
+char *find_executable (const char *wrapper);
+char *chase_symlinks (const char *pathspec);
+int make_executable (const char *path);
+int check_executable (const char *path);
+char *strendzap (char *str, const char *pat);
+void lt_debugprintf (const char *file, int line, const char *fmt, ...);
+void lt_fatal (const char *file, int line, const char *message, ...);
+static const char *nonnull (const char *s);
+static const char *nonempty (const char *s);
+void lt_setenv (const char *name, const char *value);
+char *lt_extend_str (const char *orig_value, const char *add, int to_end);
+void lt_update_exe_path (const char *name, const char *value);
+void lt_update_lib_path (const char *name, const char *value);
+char **prepare_spawn (char **argv);
+void lt_dump_script (FILE *f);
+EOF
+
+	    cat <<EOF
+#if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 5)
+# define externally_visible volatile
+#else
+# define externally_visible __attribute__((externally_visible)) volatile
+#endif
+externally_visible const char * MAGIC_EXE = "$magic_exe";
+const char * LIB_PATH_VARNAME = "$shlibpath_var";
+EOF
+
+	    if test yes = "$shlibpath_overrides_runpath" && test -n "$shlibpath_var" && test -n "$temp_rpath"; then
+              func_to_host_path "$temp_rpath"
+	      cat <<EOF
+const char * LIB_PATH_VALUE   = "$func_to_host_path_result";
+EOF
+	    else
+	      cat <<"EOF"
+const char * LIB_PATH_VALUE   = "";
+EOF
+	    fi
+
+	    if test -n "$dllsearchpath"; then
+              func_to_host_path "$dllsearchpath:"
+	      cat <<EOF
+const char * EXE_PATH_VARNAME = "PATH";
+const char * EXE_PATH_VALUE   = "$func_to_host_path_result";
+EOF
+	    else
+	      cat <<"EOF"
+const char * EXE_PATH_VARNAME = "";
+const char * EXE_PATH_VALUE   = "";
+EOF
+	    fi
+
+	    if test yes = "$fast_install"; then
+	      cat <<EOF
+const char * TARGET_PROGRAM_NAME = "lt-$outputname"; /* hopefully, no .exe */
+EOF
+	    else
+	      cat <<EOF
+const char * TARGET_PROGRAM_NAME = "$outputname"; /* hopefully, no .exe */
+EOF
+	    fi
+
+
+	    cat <<"EOF"
+
+#define LTWRAPPER_OPTION_PREFIX         "--lt-"
+
+static const char *ltwrapper_option_prefix = LTWRAPPER_OPTION_PREFIX;
+static const char *dumpscript_opt       = LTWRAPPER_OPTION_PREFIX "dump-script";
+static const char *debug_opt            = LTWRAPPER_OPTION_PREFIX "debug";
+
+int
+main (int argc, char *argv[])
+{
+  char **newargz;
+  int  newargc;
+  char *tmp_pathspec;
+  char *actual_cwrapper_path;
+  char *actual_cwrapper_name;
+  char *target_name;
+  char *lt_argv_zero;
+  int rval = 127;
+
+  int i;
+
+  program_name = (char *) xstrdup (base_name (argv[0]));
+  newargz = XMALLOC (char *, (size_t) argc + 1);
+
+  /* very simple arg parsing; don't want to rely on getopt
+   * also, copy all non cwrapper options to newargz, except
+   * argz[0], which is handled differently
+   */
+  newargc=0;
+  for (i = 1; i < argc; i++)
+    {
+      if (STREQ (argv[i], dumpscript_opt))
+	{
+EOF
+	    case $host in
+	      *mingw* | *cygwin* )
+		# make stdout use "unix" line endings
+		echo "          setmode(1,_O_BINARY);"
+		;;
+	      esac
+
+	    cat <<"EOF"
+	  lt_dump_script (stdout);
+	  return 0;
+	}
+      if (STREQ (argv[i], debug_opt))
+	{
+          lt_debug = 1;
+          continue;
+	}
+      if (STREQ (argv[i], ltwrapper_option_prefix))
+        {
+          /* however, if there is an option in the LTWRAPPER_OPTION_PREFIX
+             namespace, but it is not one of the ones we know about and
+             have already dealt with, above (inluding dump-script), then
+             report an error. Otherwise, targets might begin to believe
+             they are allowed to use options in the LTWRAPPER_OPTION_PREFIX
+             namespace. The first time any user complains about this, we'll
+             need to make LTWRAPPER_OPTION_PREFIX a configure-time option
+             or a configure.ac-settable value.
+           */
+          lt_fatal (__FILE__, __LINE__,
+		    "unrecognized %s option: '%s'",
+                    ltwrapper_option_prefix, argv[i]);
+        }
+      /* otherwise ... */
+      newargz[++newargc] = xstrdup (argv[i]);
+    }
+  newargz[++newargc] = NULL;
+
+EOF
+	    cat <<EOF
+  /* The GNU banner must be the first non-error debug message */
+  lt_debugprintf (__FILE__, __LINE__, "libtool wrapper (GNU $PACKAGE) $VERSION\n");
+EOF
+	    cat <<"EOF"
+  lt_debugprintf (__FILE__, __LINE__, "(main) argv[0]: %s\n", argv[0]);
+  lt_debugprintf (__FILE__, __LINE__, "(main) program_name: %s\n", program_name);
+
+  tmp_pathspec = find_executable (argv[0]);
+  if (tmp_pathspec == NULL)
+    lt_fatal (__FILE__, __LINE__, "couldn't find %s", argv[0]);
+  lt_debugprintf (__FILE__, __LINE__,
+                  "(main) found exe (before symlink chase) at: %s\n",
+		  tmp_pathspec);
+
+  actual_cwrapper_path = chase_symlinks (tmp_pathspec);
+  lt_debugprintf (__FILE__, __LINE__,
+                  "(main) found exe (after symlink chase) at: %s\n",
+		  actual_cwrapper_path);
+  XFREE (tmp_pathspec);
+
+  actual_cwrapper_name = xstrdup (base_name (actual_cwrapper_path));
+  strendzap (actual_cwrapper_path, actual_cwrapper_name);
+
+  /* wrapper name transforms */
+  strendzap (actual_cwrapper_name, ".exe");
+  tmp_pathspec = lt_extend_str (actual_cwrapper_name, ".exe", 1);
+  XFREE (actual_cwrapper_name);
+  actual_cwrapper_name = tmp_pathspec;
+  tmp_pathspec = 0;
+
+  /* target_name transforms -- use actual target program name; might have lt- prefix */
+  target_name = xstrdup (base_name (TARGET_PROGRAM_NAME));
+  strendzap (target_name, ".exe");
+  tmp_pathspec = lt_extend_str (target_name, ".exe", 1);
+  XFREE (target_name);
+  target_name = tmp_pathspec;
+  tmp_pathspec = 0;
+
+  lt_debugprintf (__FILE__, __LINE__,
+		  "(main) libtool target name: %s\n",
+		  target_name);
+EOF
+
+	    cat <<EOF
+  newargz[0] =
+    XMALLOC (char, (strlen (actual_cwrapper_path) +
+		    strlen ("$objdir") + 1 + strlen (actual_cwrapper_name) + 1));
+  strcpy (newargz[0], actual_cwrapper_path);
+  strcat (newargz[0], "$objdir");
+  strcat (newargz[0], "/");
+EOF
+
+	    cat <<"EOF"
+  /* stop here, and copy so we don't have to do this twice */
+  tmp_pathspec = xstrdup (newargz[0]);
+
+  /* do NOT want the lt- prefix here, so use actual_cwrapper_name */
+  strcat (newargz[0], actual_cwrapper_name);
+
+  /* DO want the lt- prefix here if it exists, so use target_name */
+  lt_argv_zero = lt_extend_str (tmp_pathspec, target_name, 1);
+  XFREE (tmp_pathspec);
+  tmp_pathspec = NULL;
+EOF
+
+	    case $host_os in
+	      mingw*)
+	    cat <<"EOF"
+  {
+    char* p;
+    while ((p = strchr (newargz[0], '\\')) != NULL)
+      {
+	*p = '/';
+      }
+    while ((p = strchr (lt_argv_zero, '\\')) != NULL)
+      {
+	*p = '/';
+      }
+  }
+EOF
+	    ;;
+	    esac
+
+	    cat <<"EOF"
+  XFREE (target_name);
+  XFREE (actual_cwrapper_path);
+  XFREE (actual_cwrapper_name);
+
+  lt_setenv ("BIN_SH", "xpg4"); /* for Tru64 */
+  lt_setenv ("DUALCASE", "1");  /* for MSK sh */
+  /* Update the DLL searchpath.  EXE_PATH_VALUE ($dllsearchpath) must
+     be prepended before (that is, appear after) LIB_PATH_VALUE ($temp_rpath)
+     because on Windows, both *_VARNAMEs are PATH but uninstalled
+     libraries must come first. */
+  lt_update_exe_path (EXE_PATH_VARNAME, EXE_PATH_VALUE);
+  lt_update_lib_path (LIB_PATH_VARNAME, LIB_PATH_VALUE);
+
+  lt_debugprintf (__FILE__, __LINE__, "(main) lt_argv_zero: %s\n",
+		  nonnull (lt_argv_zero));
+  for (i = 0; i < newargc; i++)
+    {
+      lt_debugprintf (__FILE__, __LINE__, "(main) newargz[%d]: %s\n",
+		      i, nonnull (newargz[i]));
+    }
+
+EOF
+
+	    case $host_os in
+	      mingw*)
+		cat <<"EOF"
+  /* execv doesn't actually work on mingw as expected on unix */
+  newargz = prepare_spawn (newargz);
+  rval = (int) _spawnv (_P_WAIT, lt_argv_zero, (const char * const *) newargz);
+  if (rval == -1)
+    {
+      /* failed to start process */
+      lt_debugprintf (__FILE__, __LINE__,
+		      "(main) failed to launch target \"%s\": %s\n",
+		      lt_argv_zero, nonnull (strerror (errno)));
+      return 127;
+    }
+  return rval;
+EOF
+		;;
+	      *)
+		cat <<"EOF"
+  execv (lt_argv_zero, newargz);
+  return rval; /* =127, but avoids unused variable warning */
+EOF
+		;;
+	    esac
+
+	    cat <<"EOF"
+}
+
+void *
+xmalloc (size_t num)
+{
+  void *p = (void *) malloc (num);
+  if (!p)
+    lt_fatal (__FILE__, __LINE__, "memory exhausted");
+
+  return p;
+}
+
+char *
+xstrdup (const char *string)
+{
+  return string ? strcpy ((char *) xmalloc (strlen (string) + 1),
+			  string) : NULL;
+}
+
+const char *
+base_name (const char *name)
+{
+  const char *base;
+
+#if defined HAVE_DOS_BASED_FILE_SYSTEM
+  /* Skip over the disk name in MSDOS pathnames. */
+  if (isalpha ((unsigned char) name[0]) && name[1] == ':')
+    name += 2;
+#endif
+
+  for (base = name; *name; name++)
+    if (IS_DIR_SEPARATOR (*name))
+      base = name + 1;
+  return base;
+}
+
+int
+check_executable (const char *path)
+{
+  struct stat st;
+
+  lt_debugprintf (__FILE__, __LINE__, "(check_executable): %s\n",
+                  nonempty (path));
+  if ((!path) || (!*path))
+    return 0;
+
+  if ((stat (path, &st) >= 0)
+      && (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH)))
+    return 1;
+  else
+    return 0;
+}
+
+int
+make_executable (const char *path)
+{
+  int rval = 0;
+  struct stat st;
+
+  lt_debugprintf (__FILE__, __LINE__, "(make_executable): %s\n",
+                  nonempty (path));
+  if ((!path) || (!*path))
+    return 0;
+
+  if (stat (path, &st) >= 0)
+    {
+      rval = chmod (path, st.st_mode | S_IXOTH | S_IXGRP | S_IXUSR);
+    }
+  return rval;
+}
+
+/* Searches for the full path of the wrapper.  Returns
+   newly allocated full path name if found, NULL otherwise
+   Does not chase symlinks, even on platforms that support them.
+*/
+char *
+find_executable (const char *wrapper)
+{
+  int has_slash = 0;
+  const char *p;
+  const char *p_next;
+  /* static buffer for getcwd */
+  char tmp[LT_PATHMAX + 1];
+  size_t tmp_len;
+  char *concat_name;
+
+  lt_debugprintf (__FILE__, __LINE__, "(find_executable): %s\n",
+                  nonempty (wrapper));
+
+  if ((wrapper == NULL) || (*wrapper == '\0'))
+    return NULL;
+
+  /* Absolute path? */
+#if defined HAVE_DOS_BASED_FILE_SYSTEM
+  if (isalpha ((unsigned char) wrapper[0]) && wrapper[1] == ':')
+    {
+      concat_name = xstrdup (wrapper);
+      if (check_executable (concat_name))
+	return concat_name;
+      XFREE (concat_name);
+    }
+  else
+    {
+#endif
+      if (IS_DIR_SEPARATOR (wrapper[0]))
+	{
+	  concat_name = xstrdup (wrapper);
+	  if (check_executable (concat_name))
+	    return concat_name;
+	  XFREE (concat_name);
+	}
+#if defined HAVE_DOS_BASED_FILE_SYSTEM
+    }
+#endif
+
+  for (p = wrapper; *p; p++)
+    if (*p == '/')
+      {
+	has_slash = 1;
+	break;
+      }
+  if (!has_slash)
+    {
+      /* no slashes; search PATH */
+      const char *path = getenv ("PATH");
+      if (path != NULL)
+	{
+	  for (p = path; *p; p = p_next)
+	    {
+	      const char *q;
+	      size_t p_len;
+	      for (q = p; *q; q++)
+		if (IS_PATH_SEPARATOR (*q))
+		  break;
+	      p_len = (size_t) (q - p);
+	      p_next = (*q == '\0' ? q : q + 1);
+	      if (p_len == 0)
+		{
+		  /* empty path: current directory */
+		  if (getcwd (tmp, LT_PATHMAX) == NULL)
+		    lt_fatal (__FILE__, __LINE__, "getcwd failed: %s",
+                              nonnull (strerror (errno)));
+		  tmp_len = strlen (tmp);
+		  concat_name =
+		    XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1);
+		  memcpy (concat_name, tmp, tmp_len);
+		  concat_name[tmp_len] = '/';
+		  strcpy (concat_name + tmp_len + 1, wrapper);
+		}
+	      else
+		{
+		  concat_name =
+		    XMALLOC (char, p_len + 1 + strlen (wrapper) + 1);
+		  memcpy (concat_name, p, p_len);
+		  concat_name[p_len] = '/';
+		  strcpy (concat_name + p_len + 1, wrapper);
+		}
+	      if (check_executable (concat_name))
+		return concat_name;
+	      XFREE (concat_name);
+	    }
+	}
+      /* not found in PATH; assume curdir */
+    }
+  /* Relative path | not found in path: prepend cwd */
+  if (getcwd (tmp, LT_PATHMAX) == NULL)
+    lt_fatal (__FILE__, __LINE__, "getcwd failed: %s",
+              nonnull (strerror (errno)));
+  tmp_len = strlen (tmp);
+  concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1);
+  memcpy (concat_name, tmp, tmp_len);
+  concat_name[tmp_len] = '/';
+  strcpy (concat_name + tmp_len + 1, wrapper);
+
+  if (check_executable (concat_name))
+    return concat_name;
+  XFREE (concat_name);
+  return NULL;
+}
+
+char *
+chase_symlinks (const char *pathspec)
+{
+#ifndef S_ISLNK
+  return xstrdup (pathspec);
+#else
+  char buf[LT_PATHMAX];
+  struct stat s;
+  char *tmp_pathspec = xstrdup (pathspec);
+  char *p;
+  int has_symlinks = 0;
+  while (strlen (tmp_pathspec) && !has_symlinks)
+    {
+      lt_debugprintf (__FILE__, __LINE__,
+		      "checking path component for symlinks: %s\n",
+		      tmp_pathspec);
+      if (lstat (tmp_pathspec, &s) == 0)
+	{
+	  if (S_ISLNK (s.st_mode) != 0)
+	    {
+	      has_symlinks = 1;
+	      break;
+	    }
+
+	  /* search backwards for last DIR_SEPARATOR */
+	  p = tmp_pathspec + strlen (tmp_pathspec) - 1;
+	  while ((p > tmp_pathspec) && (!IS_DIR_SEPARATOR (*p)))
+	    p--;
+	  if ((p == tmp_pathspec) && (!IS_DIR_SEPARATOR (*p)))
+	    {
+	      /* no more DIR_SEPARATORS left */
+	      break;
+	    }
+	  *p = '\0';
+	}
+      else
+	{
+	  lt_fatal (__FILE__, __LINE__,
+		    "error accessing file \"%s\": %s",
+		    tmp_pathspec, nonnull (strerror (errno)));
+	}
+    }
+  XFREE (tmp_pathspec);
+
+  if (!has_symlinks)
+    {
+      return xstrdup (pathspec);
+    }
+
+  tmp_pathspec = realpath (pathspec, buf);
+  if (tmp_pathspec == 0)
+    {
+      lt_fatal (__FILE__, __LINE__,
+		"could not follow symlinks for %s", pathspec);
+    }
+  return xstrdup (tmp_pathspec);
+#endif
+}
+
+char *
+strendzap (char *str, const char *pat)
+{
+  size_t len, patlen;
+
+  assert (str != NULL);
+  assert (pat != NULL);
+
+  len = strlen (str);
+  patlen = strlen (pat);
+
+  if (patlen <= len)
+    {
+      str += len - patlen;
+      if (STREQ (str, pat))
+	*str = '\0';
+    }
+  return str;
+}
+
+void
+lt_debugprintf (const char *file, int line, const char *fmt, ...)
+{
+  va_list args;
+  if (lt_debug)
+    {
+      (void) fprintf (stderr, "%s:%s:%d: ", program_name, file, line);
+      va_start (args, fmt);
+      (void) vfprintf (stderr, fmt, args);
+      va_end (args);
+    }
+}
+
+static void
+lt_error_core (int exit_status, const char *file,
+	       int line, const char *mode,
+	       const char *message, va_list ap)
+{
+  fprintf (stderr, "%s:%s:%d: %s: ", program_name, file, line, mode);
+  vfprintf (stderr, message, ap);
+  fprintf (stderr, ".\n");
+
+  if (exit_status >= 0)
+    exit (exit_status);
+}
+
+void
+lt_fatal (const char *file, int line, const char *message, ...)
+{
+  va_list ap;
+  va_start (ap, message);
+  lt_error_core (EXIT_FAILURE, file, line, "FATAL", message, ap);
+  va_end (ap);
+}
+
+static const char *
+nonnull (const char *s)
+{
+  return s ? s : "(null)";
+}
+
+static const char *
+nonempty (const char *s)
+{
+  return (s && !*s) ? "(empty)" : nonnull (s);
+}
+
+void
+lt_setenv (const char *name, const char *value)
+{
+  lt_debugprintf (__FILE__, __LINE__,
+		  "(lt_setenv) setting '%s' to '%s'\n",
+                  nonnull (name), nonnull (value));
+  {
+#ifdef HAVE_SETENV
+    /* always make a copy, for consistency with !HAVE_SETENV */
+    char *str = xstrdup (value);
+    setenv (name, str, 1);
+#else
+    size_t len = strlen (name) + 1 + strlen (value) + 1;
+    char *str = XMALLOC (char, len);
+    sprintf (str, "%s=%s", name, value);
+    if (putenv (str) != EXIT_SUCCESS)
+      {
+        XFREE (str);
+      }
+#endif
+  }
+}
+
+char *
+lt_extend_str (const char *orig_value, const char *add, int to_end)
+{
+  char *new_value;
+  if (orig_value && *orig_value)
+    {
+      size_t orig_value_len = strlen (orig_value);
+      size_t add_len = strlen (add);
+      new_value = XMALLOC (char, add_len + orig_value_len + 1);
+      if (to_end)
+        {
+          strcpy (new_value, orig_value);
+          strcpy (new_value + orig_value_len, add);
+        }
+      else
+        {
+          strcpy (new_value, add);
+          strcpy (new_value + add_len, orig_value);
+        }
+    }
+  else
+    {
+      new_value = xstrdup (add);
+    }
+  return new_value;
+}
+
+void
+lt_update_exe_path (const char *name, const char *value)
+{
+  lt_debugprintf (__FILE__, __LINE__,
+		  "(lt_update_exe_path) modifying '%s' by prepending '%s'\n",
+                  nonnull (name), nonnull (value));
+
+  if (name && *name && value && *value)
+    {
+      char *new_value = lt_extend_str (getenv (name), value, 0);
+      /* some systems can't cope with a ':'-terminated path #' */
+      size_t len = strlen (new_value);
+      while ((len > 0) && IS_PATH_SEPARATOR (new_value[len-1]))
+        {
+          new_value[--len] = '\0';
+        }
+      lt_setenv (name, new_value);
+      XFREE (new_value);
+    }
+}
+
+void
+lt_update_lib_path (const char *name, const char *value)
+{
+  lt_debugprintf (__FILE__, __LINE__,
+		  "(lt_update_lib_path) modifying '%s' by prepending '%s'\n",
+                  nonnull (name), nonnull (value));
+
+  if (name && *name && value && *value)
+    {
+      char *new_value = lt_extend_str (getenv (name), value, 0);
+      lt_setenv (name, new_value);
+      XFREE (new_value);
+    }
+}
+
+EOF
+	    case $host_os in
+	      mingw*)
+		cat <<"EOF"
+
+/* Prepares an argument vector before calling spawn().
+   Note that spawn() does not by itself call the command interpreter
+     (getenv ("COMSPEC") != NULL ? getenv ("COMSPEC") :
+      ({ OSVERSIONINFO v; v.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+         GetVersionEx(&v);
+         v.dwPlatformId == VER_PLATFORM_WIN32_NT;
+      }) ? "cmd.exe" : "command.com").
+   Instead it simply concatenates the arguments, separated by ' ', and calls
+   CreateProcess().  We must quote the arguments since Win32 CreateProcess()
+   interprets characters like ' ', '\t', '\\', '"' (but not '<' and '>') in a
+   special way:
+   - Space and tab are interpreted as delimiters. They are not treated as
+     delimiters if they are surrounded by double quotes: "...".
+   - Unescaped double quotes are removed from the input. Their only effect is
+     that within double quotes, space and tab are treated like normal
+     characters.
+   - Backslashes not followed by double quotes are not special.
+   - But 2*n+1 backslashes followed by a double quote become
+     n backslashes followed by a double quote (n >= 0):
+       \" -> "
+       \\\" -> \"
+       \\\\\" -> \\"
+ */
+#define SHELL_SPECIAL_CHARS "\"\\ \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037"
+#define SHELL_SPACE_CHARS " \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037"
+char **
+prepare_spawn (char **argv)
+{
+  size_t argc;
+  char **new_argv;
+  size_t i;
+
+  /* Count number of arguments.  */
+  for (argc = 0; argv[argc] != NULL; argc++)
+    ;
+
+  /* Allocate new argument vector.  */
+  new_argv = XMALLOC (char *, argc + 1);
+
+  /* Put quoted arguments into the new argument vector.  */
+  for (i = 0; i < argc; i++)
+    {
+      const char *string = argv[i];
+
+      if (string[0] == '\0')
+	new_argv[i] = xstrdup ("\"\"");
+      else if (strpbrk (string, SHELL_SPECIAL_CHARS) != NULL)
+	{
+	  int quote_around = (strpbrk (string, SHELL_SPACE_CHARS) != NULL);
+	  size_t length;
+	  unsigned int backslashes;
+	  const char *s;
+	  char *quoted_string;
+	  char *p;
+
+	  length = 0;
+	  backslashes = 0;
+	  if (quote_around)
+	    length++;
+	  for (s = string; *s != '\0'; s++)
+	    {
+	      char c = *s;
+	      if (c == '"')
+		length += backslashes + 1;
+	      length++;
+	      if (c == '\\')
+		backslashes++;
+	      else
+		backslashes = 0;
+	    }
+	  if (quote_around)
+	    length += backslashes + 1;
+
+	  quoted_string = XMALLOC (char, length + 1);
+
+	  p = quoted_string;
+	  backslashes = 0;
+	  if (quote_around)
+	    *p++ = '"';
+	  for (s = string; *s != '\0'; s++)
+	    {
+	      char c = *s;
+	      if (c == '"')
+		{
+		  unsigned int j;
+		  for (j = backslashes + 1; j > 0; j--)
+		    *p++ = '\\';
+		}
+	      *p++ = c;
+	      if (c == '\\')
+		backslashes++;
+	      else
+		backslashes = 0;
+	    }
+	  if (quote_around)
+	    {
+	      unsigned int j;
+	      for (j = backslashes; j > 0; j--)
+		*p++ = '\\';
+	      *p++ = '"';
+	    }
+	  *p = '\0';
+
+	  new_argv[i] = quoted_string;
+	}
+      else
+	new_argv[i] = (char *) string;
+    }
+  new_argv[argc] = NULL;
+
+  return new_argv;
+}
+EOF
+		;;
+	    esac
+
+            cat <<"EOF"
+void lt_dump_script (FILE* f)
+{
+EOF
+	    func_emit_wrapper yes |
+	      $SED -n -e '
+s/^\(.\{79\}\)\(..*\)/\1\
+\2/
+h
+s/\([\\"]\)/\\\1/g
+s/$/\\n/
+s/\([^\n]*\).*/  fputs ("\1", f);/p
+g
+D'
+            cat <<"EOF"
+}
+EOF
+}
+# end: func_emit_cwrapperexe_src
+
+# func_win32_import_lib_p ARG
+# True if ARG is an import lib, as indicated by $file_magic_cmd
+func_win32_import_lib_p ()
+{
+    $debug_cmd
+
+    case `eval $file_magic_cmd \"\$1\" 2>/dev/null | $SED -e 10q` in
+    *import*) : ;;
+    *) false ;;
+    esac
+}
+
+# func_suncc_cstd_abi
+# !!ONLY CALL THIS FOR SUN CC AFTER $compile_command IS FULLY EXPANDED!!
+# Several compiler flags select an ABI that is incompatible with the
+# Cstd library. Avoid specifying it if any are in CXXFLAGS.
+func_suncc_cstd_abi ()
+{
+    $debug_cmd
+
+    case " $compile_command " in
+    *" -compat=g "*|*\ -std=c++[0-9][0-9]\ *|*" -library=stdcxx4 "*|*" -library=stlport4 "*)
+      suncc_use_cstd_abi=no
+      ;;
+    *)
+      suncc_use_cstd_abi=yes
+      ;;
+    esac
+}
+
+# func_mode_link arg...
+func_mode_link ()
+{
+    $debug_cmd
+
+    case $host in
+    *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*)
+      # It is impossible to link a dll without this setting, and
+      # we shouldn't force the makefile maintainer to figure out
+      # what system we are compiling for in order to pass an extra
+      # flag for every libtool invocation.
+      # allow_undefined=no
+
+      # FIXME: Unfortunately, there are problems with the above when trying
+      # to make a dll that has undefined symbols, in which case not
+      # even a static library is built.  For now, we need to specify
+      # -no-undefined on the libtool link line when we can be certain
+      # that all symbols are satisfied, otherwise we get a static library.
+      allow_undefined=yes
+      ;;
+    *)
+      allow_undefined=yes
+      ;;
+    esac
+    libtool_args=$nonopt
+    base_compile="$nonopt $@"
+    compile_command=$nonopt
+    finalize_command=$nonopt
+
+    compile_rpath=
+    finalize_rpath=
+    compile_shlibpath=
+    finalize_shlibpath=
+    convenience=
+    old_convenience=
+    deplibs=
+    old_deplibs=
+    compiler_flags=
+    linker_flags=
+    dllsearchpath=
+    lib_search_path=`pwd`
+    inst_prefix_dir=
+    new_inherited_linker_flags=
+
+    avoid_version=no
+    bindir=
+    dlfiles=
+    dlprefiles=
+    dlself=no
+    export_dynamic=no
+    export_symbols=
+    export_symbols_regex=
+    generated=
+    libobjs=
+    ltlibs=
+    module=no
+    no_install=no
+    objs=
+    os2dllname=
+    non_pic_objects=
+    precious_files_regex=
+    prefer_static_libs=no
+    preload=false
+    prev=
+    prevarg=
+    release=
+    rpath=
+    xrpath=
+    perm_rpath=
+    temp_rpath=
+    thread_safe=no
+    vinfo=
+    vinfo_number=no
+    weak_libs=
+    single_module=$wl-single_module
+    func_infer_tag $base_compile
+
+    # We need to know -static, to get the right output filenames.
+    for arg
+    do
+      case $arg in
+      -shared)
+	test yes != "$build_libtool_libs" \
+	  && func_fatal_configuration "cannot build a shared library"
+	build_old_libs=no
+	break
+	;;
+      -all-static | -static | -static-libtool-libs)
+	case $arg in
+	-all-static)
+	  if test yes = "$build_libtool_libs" && test -z "$link_static_flag"; then
+	    func_warning "complete static linking is impossible in this configuration"
+	  fi
+	  if test -n "$link_static_flag"; then
+	    dlopen_self=$dlopen_self_static
+	  fi
+	  prefer_static_libs=yes
+	  ;;
+	-static)
+	  if test -z "$pic_flag" && test -n "$link_static_flag"; then
+	    dlopen_self=$dlopen_self_static
+	  fi
+	  prefer_static_libs=built
+	  ;;
+	-static-libtool-libs)
+	  if test -z "$pic_flag" && test -n "$link_static_flag"; then
+	    dlopen_self=$dlopen_self_static
+	  fi
+	  prefer_static_libs=yes
+	  ;;
+	esac
+	build_libtool_libs=no
+	build_old_libs=yes
+	break
+	;;
+      esac
+    done
+
+    # See if our shared archives depend on static archives.
+    test -n "$old_archive_from_new_cmds" && build_old_libs=yes
+
+    # Go through the arguments, transforming them on the way.
+    while test "$#" -gt 0; do
+      arg=$1
+      shift
+      func_quote_for_eval "$arg"
+      qarg=$func_quote_for_eval_unquoted_result
+      func_append libtool_args " $func_quote_for_eval_result"
+
+      # If the previous option needs an argument, assign it.
+      if test -n "$prev"; then
+	case $prev in
+	output)
+	  func_append compile_command " @OUTPUT@"
+	  func_append finalize_command " @OUTPUT@"
+	  ;;
+	esac
+
+	case $prev in
+	bindir)
+	  bindir=$arg
+	  prev=
+	  continue
+	  ;;
+	dlfiles|dlprefiles)
+	  $preload || {
+	    # Add the symbol object into the linking commands.
+	    func_append compile_command " @SYMFILE@"
+	    func_append finalize_command " @SYMFILE@"
+	    preload=:
+	  }
+	  case $arg in
+	  *.la | *.lo) ;;  # We handle these cases below.
+	  force)
+	    if test no = "$dlself"; then
+	      dlself=needless
+	      export_dynamic=yes
+	    fi
+	    prev=
+	    continue
+	    ;;
+	  self)
+	    if test dlprefiles = "$prev"; then
+	      dlself=yes
+	    elif test dlfiles = "$prev" && test yes != "$dlopen_self"; then
+	      dlself=yes
+	    else
+	      dlself=needless
+	      export_dynamic=yes
+	    fi
+	    prev=
+	    continue
+	    ;;
+	  *)
+	    if test dlfiles = "$prev"; then
+	      func_append dlfiles " $arg"
+	    else
+	      func_append dlprefiles " $arg"
+	    fi
+	    prev=
+	    continue
+	    ;;
+	  esac
+	  ;;
+	expsyms)
+	  export_symbols=$arg
+	  test -f "$arg" \
+	    || func_fatal_error "symbol file '$arg' does not exist"
+	  prev=
+	  continue
+	  ;;
+	expsyms_regex)
+	  export_symbols_regex=$arg
+	  prev=
+	  continue
+	  ;;
+	framework)
+	  case $host in
+	    *-*-darwin*)
+	      case "$deplibs " in
+		*" $qarg.ltframework "*) ;;
+		*) func_append deplibs " $qarg.ltframework" # this is fixed later
+		   ;;
+	      esac
+	      ;;
+	  esac
+	  prev=
+	  continue
+	  ;;
+	inst_prefix)
+	  inst_prefix_dir=$arg
+	  prev=
+	  continue
+	  ;;
+	mllvm)
+	  # Clang does not use LLVM to link, so we can simply discard any
+	  # '-mllvm $arg' options when doing the link step.
+	  prev=
+	  continue
+	  ;;
+	objectlist)
+	  if test -f "$arg"; then
+	    save_arg=$arg
+	    moreargs=
+	    for fil in `cat "$save_arg"`
+	    do
+#	      func_append moreargs " $fil"
+	      arg=$fil
+	      # A libtool-controlled object.
+
+	      # Check to see that this really is a libtool object.
+	      if func_lalib_unsafe_p "$arg"; then
+		pic_object=
+		non_pic_object=
+
+		# Read the .lo file
+		func_source "$arg"
+
+		if test -z "$pic_object" ||
+		   test -z "$non_pic_object" ||
+		   test none = "$pic_object" &&
+		   test none = "$non_pic_object"; then
+		  func_fatal_error "cannot find name of object for '$arg'"
+		fi
+
+		# Extract subdirectory from the argument.
+		func_dirname "$arg" "/" ""
+		xdir=$func_dirname_result
+
+		if test none != "$pic_object"; then
+		  # Prepend the subdirectory the object is found in.
+		  pic_object=$xdir$pic_object
+
+		  if test dlfiles = "$prev"; then
+		    if test yes = "$build_libtool_libs" && test yes = "$dlopen_support"; then
+		      func_append dlfiles " $pic_object"
+		      prev=
+		      continue
+		    else
+		      # If libtool objects are unsupported, then we need to preload.
+		      prev=dlprefiles
+		    fi
+		  fi
+
+		  # CHECK ME:  I think I busted this.  -Ossama
+		  if test dlprefiles = "$prev"; then
+		    # Preload the old-style object.
+		    func_append dlprefiles " $pic_object"
+		    prev=
+		  fi
+
+		  # A PIC object.
+		  func_append libobjs " $pic_object"
+		  arg=$pic_object
+		fi
+
+		# Non-PIC object.
+		if test none != "$non_pic_object"; then
+		  # Prepend the subdirectory the object is found in.
+		  non_pic_object=$xdir$non_pic_object
+
+		  # A standard non-PIC object
+		  func_append non_pic_objects " $non_pic_object"
+		  if test -z "$pic_object" || test none = "$pic_object"; then
+		    arg=$non_pic_object
+		  fi
+		else
+		  # If the PIC object exists, use it instead.
+		  # $xdir was prepended to $pic_object above.
+		  non_pic_object=$pic_object
+		  func_append non_pic_objects " $non_pic_object"
+		fi
+	      else
+		# Only an error if not doing a dry-run.
+		if $opt_dry_run; then
+		  # Extract subdirectory from the argument.
+		  func_dirname "$arg" "/" ""
+		  xdir=$func_dirname_result
+
+		  func_lo2o "$arg"
+		  pic_object=$xdir$objdir/$func_lo2o_result
+		  non_pic_object=$xdir$func_lo2o_result
+		  func_append libobjs " $pic_object"
+		  func_append non_pic_objects " $non_pic_object"
+	        else
+		  func_fatal_error "'$arg' is not a valid libtool object"
+		fi
+	      fi
+	    done
+	  else
+	    func_fatal_error "link input file '$arg' does not exist"
+	  fi
+	  arg=$save_arg
+	  prev=
+	  continue
+	  ;;
+	os2dllname)
+	  os2dllname=$arg
+	  prev=
+	  continue
+	  ;;
+	precious_regex)
+	  precious_files_regex=$arg
+	  prev=
+	  continue
+	  ;;
+	release)
+	  release=-$arg
+	  prev=
+	  continue
+	  ;;
+	rpath | xrpath)
+	  # We need an absolute path.
+	  case $arg in
+	  [\\/]* | [A-Za-z]:[\\/]*) ;;
+	  *)
+	    func_fatal_error "only absolute run-paths are allowed"
+	    ;;
+	  esac
+	  if test rpath = "$prev"; then
+	    case "$rpath " in
+	    *" $arg "*) ;;
+	    *) func_append rpath " $arg" ;;
+	    esac
+	  else
+	    case "$xrpath " in
+	    *" $arg "*) ;;
+	    *) func_append xrpath " $arg" ;;
+	    esac
+	  fi
+	  prev=
+	  continue
+	  ;;
+	shrext)
+	  shrext_cmds=$arg
+	  prev=
+	  continue
+	  ;;
+	weak)
+	  func_append weak_libs " $arg"
+	  prev=
+	  continue
+	  ;;
+	xcclinker)
+	  func_append linker_flags " $qarg"
+	  func_append compiler_flags " $qarg"
+	  prev=
+	  func_append compile_command " $qarg"
+	  func_append finalize_command " $qarg"
+	  continue
+	  ;;
+	xcompiler)
+	  func_append compiler_flags " $qarg"
+	  prev=
+	  func_append compile_command " $qarg"
+	  func_append finalize_command " $qarg"
+	  continue
+	  ;;
+	xlinker)
+	  func_append linker_flags " $qarg"
+	  func_append compiler_flags " $wl$qarg"
+	  prev=
+	  func_append compile_command " $wl$qarg"
+	  func_append finalize_command " $wl$qarg"
+	  continue
+	  ;;
+	*)
+	  eval "$prev=\"\$arg\""
+	  prev=
+	  continue
+	  ;;
+	esac
+      fi # test -n "$prev"
+
+      prevarg=$arg
+
+      case $arg in
+      -all-static)
+	if test -n "$link_static_flag"; then
+	  # See comment for -static flag below, for more details.
+	  func_append compile_command " $link_static_flag"
+	  func_append finalize_command " $link_static_flag"
+	fi
+	continue
+	;;
+
+      -allow-undefined)
+	# FIXME: remove this flag sometime in the future.
+	func_fatal_error "'-allow-undefined' must not be used because it is the default"
+	;;
+
+      -avoid-version)
+	avoid_version=yes
+	continue
+	;;
+
+      -bindir)
+	prev=bindir
+	continue
+	;;
+
+      -dlopen)
+	prev=dlfiles
+	continue
+	;;
+
+      -dlpreopen)
+	prev=dlprefiles
+	continue
+	;;
+
+      -export-dynamic)
+	export_dynamic=yes
+	continue
+	;;
+
+      -export-symbols | -export-symbols-regex)
+	if test -n "$export_symbols" || test -n "$export_symbols_regex"; then
+	  func_fatal_error "more than one -exported-symbols argument is not allowed"
+	fi
+	if test X-export-symbols = "X$arg"; then
+	  prev=expsyms
+	else
+	  prev=expsyms_regex
+	fi
+	continue
+	;;
+
+      -framework)
+	prev=framework
+	continue
+	;;
+
+      -inst-prefix-dir)
+	prev=inst_prefix
+	continue
+	;;
+
+      # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:*
+      # so, if we see these flags be careful not to treat them like -L
+      -L[A-Z][A-Z]*:*)
+	case $with_gcc/$host in
+	no/*-*-irix* | /*-*-irix*)
+	  func_append compile_command " $arg"
+	  func_append finalize_command " $arg"
+	  ;;
+	esac
+	continue
+	;;
+
+      -L*)
+	func_stripname "-L" '' "$arg"
+	if test -z "$func_stripname_result"; then
+	  if test "$#" -gt 0; then
+	    func_fatal_error "require no space between '-L' and '$1'"
+	  else
+	    func_fatal_error "need path for '-L' option"
+	  fi
+	fi
+	func_resolve_sysroot "$func_stripname_result"
+	dir=$func_resolve_sysroot_result
+	# We need an absolute path.
+	case $dir in
+	[\\/]* | [A-Za-z]:[\\/]*) ;;
+	*)
+	  absdir=`cd "$dir" && pwd`
+	  test -z "$absdir" && \
+	    func_fatal_error "cannot determine absolute directory name of '$dir'"
+	  dir=$absdir
+	  ;;
+	esac
+	case "$deplibs " in
+	*" -L$dir "* | *" $arg "*)
+	  # Will only happen for absolute or sysroot arguments
+	  ;;
+	*)
+	  # Preserve sysroot, but never include relative directories
+	  case $dir in
+	    [\\/]* | [A-Za-z]:[\\/]* | =*) func_append deplibs " $arg" ;;
+	    *) func_append deplibs " -L$dir" ;;
+	  esac
+	  func_append lib_search_path " $dir"
+	  ;;
+	esac
+	case $host in
+	*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*)
+	  testbindir=`$ECHO "$dir" | $SED 's*/lib$*/bin*'`
+	  case :$dllsearchpath: in
+	  *":$dir:"*) ;;
+	  ::) dllsearchpath=$dir;;
+	  *) func_append dllsearchpath ":$dir";;
+	  esac
+	  case :$dllsearchpath: in
+	  *":$testbindir:"*) ;;
+	  ::) dllsearchpath=$testbindir;;
+	  *) func_append dllsearchpath ":$testbindir";;
+	  esac
+	  ;;
+	esac
+	continue
+	;;
+
+      -l*)
+	if test X-lc = "X$arg" || test X-lm = "X$arg"; then
+	  case $host in
+	  *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos* | *-cegcc* | *-*-haiku*)
+	    # These systems don't actually have a C or math library (as such)
+	    continue
+	    ;;
+	  *-*-os2*)
+	    # These systems don't actually have a C library (as such)
+	    test X-lc = "X$arg" && continue
+	    ;;
+	  *-*-openbsd* | *-*-freebsd* | *-*-dragonfly* | *-*-bitrig*)
+	    # Do not include libc due to us having libc/libc_r.
+	    test X-lc = "X$arg" && continue
+	    ;;
+	  *-*-rhapsody* | *-*-darwin1.[012])
+	    # Rhapsody C and math libraries are in the System framework
+	    func_append deplibs " System.ltframework"
+	    continue
+	    ;;
+	  *-*-sco3.2v5* | *-*-sco5v6*)
+	    # Causes problems with __ctype
+	    test X-lc = "X$arg" && continue
+	    ;;
+	  *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*)
+	    # Compiler inserts libc in the correct place for threads to work
+	    test X-lc = "X$arg" && continue
+	    ;;
+	  esac
+	elif test X-lc_r = "X$arg"; then
+	 case $host in
+	 *-*-openbsd* | *-*-freebsd* | *-*-dragonfly* | *-*-bitrig*)
+	   # Do not include libc_r directly, use -pthread flag.
+	   continue
+	   ;;
+	 esac
+	fi
+	func_append deplibs " $arg"
+	continue
+	;;
+
+      -mllvm)
+	prev=mllvm
+	continue
+	;;
+
+      -module)
+	module=yes
+	continue
+	;;
+
+      # Tru64 UNIX uses -model [arg] to determine the layout of C++
+      # classes, name mangling, and exception handling.
+      # Darwin uses the -arch flag to determine output architecture.
+      -model|-arch|-isysroot|--sysroot)
+	func_append compiler_flags " $arg"
+	func_append compile_command " $arg"
+	func_append finalize_command " $arg"
+	prev=xcompiler
+	continue
+	;;
+
+      -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \
+      |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*)
+	func_append compiler_flags " $arg"
+	func_append compile_command " $arg"
+	func_append finalize_command " $arg"
+	case "$new_inherited_linker_flags " in
+	    *" $arg "*) ;;
+	    * ) func_append new_inherited_linker_flags " $arg" ;;
+	esac
+	continue
+	;;
+
+      -multi_module)
+	single_module=$wl-multi_module
+	continue
+	;;
+
+      -no-fast-install)
+	fast_install=no
+	continue
+	;;
+
+      -no-install)
+	case $host in
+	*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-darwin* | *-cegcc*)
+	  # The PATH hackery in wrapper scripts is required on Windows
+	  # and Darwin in order for the loader to find any dlls it needs.
+	  func_warning "'-no-install' is ignored for $host"
+	  func_warning "assuming '-no-fast-install' instead"
+	  fast_install=no
+	  ;;
+	*) no_install=yes ;;
+	esac
+	continue
+	;;
+
+      -no-undefined)
+	allow_undefined=no
+	continue
+	;;
+
+      -objectlist)
+	prev=objectlist
+	continue
+	;;
+
+      -os2dllname)
+	prev=os2dllname
+	continue
+	;;
+
+      -o) prev=output ;;
+
+      -precious-files-regex)
+	prev=precious_regex
+	continue
+	;;
+
+      -release)
+	prev=release
+	continue
+	;;
+
+      -rpath)
+	prev=rpath
+	continue
+	;;
+
+      -R)
+	prev=xrpath
+	continue
+	;;
+
+      -R*)
+	func_stripname '-R' '' "$arg"
+	dir=$func_stripname_result
+	# We need an absolute path.
+	case $dir in
+	[\\/]* | [A-Za-z]:[\\/]*) ;;
+	=*)
+	  func_stripname '=' '' "$dir"
+	  dir=$lt_sysroot$func_stripname_result
+	  ;;
+	*)
+	  func_fatal_error "only absolute run-paths are allowed"
+	  ;;
+	esac
+	case "$xrpath " in
+	*" $dir "*) ;;
+	*) func_append xrpath " $dir" ;;
+	esac
+	continue
+	;;
+
+      -shared)
+	# The effects of -shared are defined in a previous loop.
+	continue
+	;;
+
+      -shrext)
+	prev=shrext
+	continue
+	;;
+
+      -static | -static-libtool-libs)
+	# The effects of -static are defined in a previous loop.
+	# We used to do the same as -all-static on platforms that
+	# didn't have a PIC flag, but the assumption that the effects
+	# would be equivalent was wrong.  It would break on at least
+	# Digital Unix and AIX.
+	continue
+	;;
+
+      -thread-safe)
+	thread_safe=yes
+	continue
+	;;
+
+      -version-info)
+	prev=vinfo
+	continue
+	;;
+
+      -version-number)
+	prev=vinfo
+	vinfo_number=yes
+	continue
+	;;
+
+      -weak)
+        prev=weak
+	continue
+	;;
+
+      -Wc,*)
+	func_stripname '-Wc,' '' "$arg"
+	args=$func_stripname_result
+	arg=
+	save_ifs=$IFS; IFS=,
+	for flag in $args; do
+	  IFS=$save_ifs
+          func_quote_for_eval "$flag"
+	  func_append arg " $func_quote_for_eval_result"
+	  func_append compiler_flags " $func_quote_for_eval_result"
+	done
+	IFS=$save_ifs
+	func_stripname ' ' '' "$arg"
+	arg=$func_stripname_result
+	;;
+
+      -Wl,*)
+	func_stripname '-Wl,' '' "$arg"
+	args=$func_stripname_result
+	arg=
+	save_ifs=$IFS; IFS=,
+	for flag in $args; do
+	  IFS=$save_ifs
+          func_quote_for_eval "$flag"
+	  func_append arg " $wl$func_quote_for_eval_result"
+	  func_append compiler_flags " $wl$func_quote_for_eval_result"
+	  func_append linker_flags " $func_quote_for_eval_result"
+	done
+	IFS=$save_ifs
+	func_stripname ' ' '' "$arg"
+	arg=$func_stripname_result
+	;;
+
+      -Xcompiler)
+	prev=xcompiler
+	continue
+	;;
+
+      -Xlinker)
+	prev=xlinker
+	continue
+	;;
+
+      -XCClinker)
+	prev=xcclinker
+	continue
+	;;
+
+      # -msg_* for osf cc
+      -msg_*)
+	func_quote_for_eval "$arg"
+	arg=$func_quote_for_eval_result
+	;;
+
+      # Flags to be passed through unchanged, with rationale:
+      # -64, -mips[0-9]      enable 64-bit mode for the SGI compiler
+      # -r[0-9][0-9]*        specify processor for the SGI compiler
+      # -xarch=*, -xtarget=* enable 64-bit mode for the Sun compiler
+      # +DA*, +DD*           enable 64-bit mode for the HP compiler
+      # -q*                  compiler args for the IBM compiler
+      # -m*, -t[45]*, -txscale* architecture-specific flags for GCC
+      # -F/path              path to uninstalled frameworks, gcc on darwin
+      # -p, -pg, --coverage, -fprofile-*  profiling flags for GCC
+      # -fstack-protector*   stack protector flags for GCC
+      # @file                GCC response files
+      # -tp=*                Portland pgcc target processor selection
+      # --sysroot=*          for sysroot support
+      # -O*, -g*, -flto*, -fwhopr*, -fuse-linker-plugin GCC link-time optimization
+      # -specs=*             GCC specs files
+      # -stdlib=*            select c++ std lib with clang
+      # -fsanitize=*         Clang/GCC memory and address sanitizer
+      -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \
+      -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*|-tp=*|--sysroot=*| \
+      -O*|-g*|-flto*|-fwhopr*|-fuse-linker-plugin|-fstack-protector*|-stdlib=*| \
+      -specs=*|-fsanitize=*)
+        func_quote_for_eval "$arg"
+	arg=$func_quote_for_eval_result
+        func_append compile_command " $arg"
+        func_append finalize_command " $arg"
+        func_append compiler_flags " $arg"
+        continue
+        ;;
+
+      -Z*)
+        if test os2 = "`expr $host : '.*\(os2\)'`"; then
+          # OS/2 uses -Zxxx to specify OS/2-specific options
+	  compiler_flags="$compiler_flags $arg"
+	  func_append compile_command " $arg"
+	  func_append finalize_command " $arg"
+	  case $arg in
+	  -Zlinker | -Zstack)
+	    prev=xcompiler
+	    ;;
+	  esac
+	  continue
+        else
+	  # Otherwise treat like 'Some other compiler flag' below
+	  func_quote_for_eval "$arg"
+	  arg=$func_quote_for_eval_result
+        fi
+	;;
+
+      # Some other compiler flag.
+      -* | +*)
+        func_quote_for_eval "$arg"
+	arg=$func_quote_for_eval_result
+	;;
+
+      *.$objext)
+	# A standard object.
+	func_append objs " $arg"
+	;;
+
+      *.lo)
+	# A libtool-controlled object.
+
+	# Check to see that this really is a libtool object.
+	if func_lalib_unsafe_p "$arg"; then
+	  pic_object=
+	  non_pic_object=
+
+	  # Read the .lo file
+	  func_source "$arg"
+
+	  if test -z "$pic_object" ||
+	     test -z "$non_pic_object" ||
+	     test none = "$pic_object" &&
+	     test none = "$non_pic_object"; then
+	    func_fatal_error "cannot find name of object for '$arg'"
+	  fi
+
+	  # Extract subdirectory from the argument.
+	  func_dirname "$arg" "/" ""
+	  xdir=$func_dirname_result
+
+	  test none = "$pic_object" || {
+	    # Prepend the subdirectory the object is found in.
+	    pic_object=$xdir$pic_object
+
+	    if test dlfiles = "$prev"; then
+	      if test yes = "$build_libtool_libs" && test yes = "$dlopen_support"; then
+		func_append dlfiles " $pic_object"
+		prev=
+		continue
+	      else
+		# If libtool objects are unsupported, then we need to preload.
+		prev=dlprefiles
+	      fi
+	    fi
+
+	    # CHECK ME:  I think I busted this.  -Ossama
+	    if test dlprefiles = "$prev"; then
+	      # Preload the old-style object.
+	      func_append dlprefiles " $pic_object"
+	      prev=
+	    fi
+
+	    # A PIC object.
+	    func_append libobjs " $pic_object"
+	    arg=$pic_object
+	  }
+
+	  # Non-PIC object.
+	  if test none != "$non_pic_object"; then
+	    # Prepend the subdirectory the object is found in.
+	    non_pic_object=$xdir$non_pic_object
+
+	    # A standard non-PIC object
+	    func_append non_pic_objects " $non_pic_object"
+	    if test -z "$pic_object" || test none = "$pic_object"; then
+	      arg=$non_pic_object
+	    fi
+	  else
+	    # If the PIC object exists, use it instead.
+	    # $xdir was prepended to $pic_object above.
+	    non_pic_object=$pic_object
+	    func_append non_pic_objects " $non_pic_object"
+	  fi
+	else
+	  # Only an error if not doing a dry-run.
+	  if $opt_dry_run; then
+	    # Extract subdirectory from the argument.
+	    func_dirname "$arg" "/" ""
+	    xdir=$func_dirname_result
+
+	    func_lo2o "$arg"
+	    pic_object=$xdir$objdir/$func_lo2o_result
+	    non_pic_object=$xdir$func_lo2o_result
+	    func_append libobjs " $pic_object"
+	    func_append non_pic_objects " $non_pic_object"
+	  else
+	    func_fatal_error "'$arg' is not a valid libtool object"
+	  fi
+	fi
+	;;
+
+      *.$libext)
+	# An archive.
+	func_append deplibs " $arg"
+	func_append old_deplibs " $arg"
+	continue
+	;;
+
+      *.la)
+	# A libtool-controlled library.
+
+	func_resolve_sysroot "$arg"
+	if test dlfiles = "$prev"; then
+	  # This library was specified with -dlopen.
+	  func_append dlfiles " $func_resolve_sysroot_result"
+	  prev=
+	elif test dlprefiles = "$prev"; then
+	  # The library was specified with -dlpreopen.
+	  func_append dlprefiles " $func_resolve_sysroot_result"
+	  prev=
+	else
+	  func_append deplibs " $func_resolve_sysroot_result"
+	fi
+	continue
+	;;
+
+      # Some other compiler argument.
+      *)
+	# Unknown arguments in both finalize_command and compile_command need
+	# to be aesthetically quoted because they are evaled later.
+	func_quote_for_eval "$arg"
+	arg=$func_quote_for_eval_result
+	;;
+      esac # arg
+
+      # Now actually substitute the argument into the commands.
+      if test -n "$arg"; then
+	func_append compile_command " $arg"
+	func_append finalize_command " $arg"
+      fi
+    done # argument parsing loop
+
+    test -n "$prev" && \
+      func_fatal_help "the '$prevarg' option requires an argument"
+
+    if test yes = "$export_dynamic" && test -n "$export_dynamic_flag_spec"; then
+      eval arg=\"$export_dynamic_flag_spec\"
+      func_append compile_command " $arg"
+      func_append finalize_command " $arg"
+    fi
+
+    oldlibs=
+    # calculate the name of the file, without its directory
+    func_basename "$output"
+    outputname=$func_basename_result
+    libobjs_save=$libobjs
+
+    if test -n "$shlibpath_var"; then
+      # get the directories listed in $shlibpath_var
+      eval shlib_search_path=\`\$ECHO \"\$$shlibpath_var\" \| \$SED \'s/:/ /g\'\`
+    else
+      shlib_search_path=
+    fi
+    eval sys_lib_search_path=\"$sys_lib_search_path_spec\"
+    eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\"
+
+    # Definition is injected by LT_CONFIG during libtool generation.
+    func_munge_path_list sys_lib_dlsearch_path "$LT_SYS_LIBRARY_PATH"
+
+    func_dirname "$output" "/" ""
+    output_objdir=$func_dirname_result$objdir
+    func_to_tool_file "$output_objdir/"
+    tool_output_objdir=$func_to_tool_file_result
+    # Create the object directory.
+    func_mkdir_p "$output_objdir"
+
+    # Determine the type of output
+    case $output in
+    "")
+      func_fatal_help "you must specify an output file"
+      ;;
+    *.$libext) linkmode=oldlib ;;
+    *.lo | *.$objext) linkmode=obj ;;
+    *.la) linkmode=lib ;;
+    *) linkmode=prog ;; # Anything else should be a program.
+    esac
+
+    specialdeplibs=
+
+    libs=
+    # Find all interdependent deplibs by searching for libraries
+    # that are linked more than once (e.g. -la -lb -la)
+    for deplib in $deplibs; do
+      if $opt_preserve_dup_deps; then
+	case "$libs " in
+	*" $deplib "*) func_append specialdeplibs " $deplib" ;;
+	esac
+      fi
+      func_append libs " $deplib"
+    done
+
+    if test lib = "$linkmode"; then
+      libs="$predeps $libs $compiler_lib_search_path $postdeps"
+
+      # Compute libraries that are listed more than once in $predeps
+      # $postdeps and mark them as special (i.e., whose duplicates are
+      # not to be eliminated).
+      pre_post_deps=
+      if $opt_duplicate_compiler_generated_deps; then
+	for pre_post_dep in $predeps $postdeps; do
+	  case "$pre_post_deps " in
+	  *" $pre_post_dep "*) func_append specialdeplibs " $pre_post_deps" ;;
+	  esac
+	  func_append pre_post_deps " $pre_post_dep"
+	done
+      fi
+      pre_post_deps=
+    fi
+
+    deplibs=
+    newdependency_libs=
+    newlib_search_path=
+    need_relink=no # whether we're linking any uninstalled libtool libraries
+    notinst_deplibs= # not-installed libtool libraries
+    notinst_path= # paths that contain not-installed libtool libraries
+
+    case $linkmode in
+    lib)
+	passes="conv dlpreopen link"
+	for file in $dlfiles $dlprefiles; do
+	  case $file in
+	  *.la) ;;
+	  *)
+	    func_fatal_help "libraries can '-dlopen' only libtool libraries: $file"
+	    ;;
+	  esac
+	done
+	;;
+    prog)
+	compile_deplibs=
+	finalize_deplibs=
+	alldeplibs=false
+	newdlfiles=
+	newdlprefiles=
+	passes="conv scan dlopen dlpreopen link"
+	;;
+    *)  passes="conv"
+	;;
+    esac
+
+    for pass in $passes; do
+      # The preopen pass in lib mode reverses $deplibs; put it back here
+      # so that -L comes before libs that need it for instance...
+      if test lib,link = "$linkmode,$pass"; then
+	## FIXME: Find the place where the list is rebuilt in the wrong
+	##        order, and fix it there properly
+        tmp_deplibs=
+	for deplib in $deplibs; do
+	  tmp_deplibs="$deplib $tmp_deplibs"
+	done
+	deplibs=$tmp_deplibs
+      fi
+
+      if test lib,link = "$linkmode,$pass" ||
+	 test prog,scan = "$linkmode,$pass"; then
+	libs=$deplibs
+	deplibs=
+      fi
+      if test prog = "$linkmode"; then
+	case $pass in
+	dlopen) libs=$dlfiles ;;
+	dlpreopen) libs=$dlprefiles ;;
+	link)
+	  libs="$deplibs %DEPLIBS%"
+	  test "X$link_all_deplibs" != Xno && libs="$libs $dependency_libs"
+	  ;;
+	esac
+      fi
+      if test lib,dlpreopen = "$linkmode,$pass"; then
+	# Collect and forward deplibs of preopened libtool libs
+	for lib in $dlprefiles; do
+	  # Ignore non-libtool-libs
+	  dependency_libs=
+	  func_resolve_sysroot "$lib"
+	  case $lib in
+	  *.la)	func_source "$func_resolve_sysroot_result" ;;
+	  esac
+
+	  # Collect preopened libtool deplibs, except any this library
+	  # has declared as weak libs
+	  for deplib in $dependency_libs; do
+	    func_basename "$deplib"
+            deplib_base=$func_basename_result
+	    case " $weak_libs " in
+	    *" $deplib_base "*) ;;
+	    *) func_append deplibs " $deplib" ;;
+	    esac
+	  done
+	done
+	libs=$dlprefiles
+      fi
+      if test dlopen = "$pass"; then
+	# Collect dlpreopened libraries
+	save_deplibs=$deplibs
+	deplibs=
+      fi
+
+      for deplib in $libs; do
+	lib=
+	found=false
+	case $deplib in
+	-mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \
+        |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*)
+	  if test prog,link = "$linkmode,$pass"; then
+	    compile_deplibs="$deplib $compile_deplibs"
+	    finalize_deplibs="$deplib $finalize_deplibs"
+	  else
+	    func_append compiler_flags " $deplib"
+	    if test lib = "$linkmode"; then
+		case "$new_inherited_linker_flags " in
+		    *" $deplib "*) ;;
+		    * ) func_append new_inherited_linker_flags " $deplib" ;;
+		esac
+	    fi
+	  fi
+	  continue
+	  ;;
+	-l*)
+	  if test lib != "$linkmode" && test prog != "$linkmode"; then
+	    func_warning "'-l' is ignored for archives/objects"
+	    continue
+	  fi
+	  func_stripname '-l' '' "$deplib"
+	  name=$func_stripname_result
+	  if test lib = "$linkmode"; then
+	    searchdirs="$newlib_search_path $lib_search_path $compiler_lib_search_dirs $sys_lib_search_path $shlib_search_path"
+	  else
+	    searchdirs="$newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path"
+	  fi
+	  for searchdir in $searchdirs; do
+	    for search_ext in .la $std_shrext .so .a; do
+	      # Search the libtool library
+	      lib=$searchdir/lib$name$search_ext
+	      if test -f "$lib"; then
+		if test .la = "$search_ext"; then
+		  found=:
+		else
+		  found=false
+		fi
+		break 2
+	      fi
+	    done
+	  done
+	  if $found; then
+	    # deplib is a libtool library
+	    # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib,
+	    # We need to do some special things here, and not later.
+	    if test yes = "$allow_libtool_libs_with_static_runtimes"; then
+	      case " $predeps $postdeps " in
+	      *" $deplib "*)
+		if func_lalib_p "$lib"; then
+		  library_names=
+		  old_library=
+		  func_source "$lib"
+		  for l in $old_library $library_names; do
+		    ll=$l
+		  done
+		  if test "X$ll" = "X$old_library"; then # only static version available
+		    found=false
+		    func_dirname "$lib" "" "."
+		    ladir=$func_dirname_result
+		    lib=$ladir/$old_library
+		    if test prog,link = "$linkmode,$pass"; then
+		      compile_deplibs="$deplib $compile_deplibs"
+		      finalize_deplibs="$deplib $finalize_deplibs"
+		    else
+		      deplibs="$deplib $deplibs"
+		      test lib = "$linkmode" && newdependency_libs="$deplib $newdependency_libs"
+		    fi
+		    continue
+		  fi
+		fi
+		;;
+	      *) ;;
+	      esac
+	    fi
+	  else
+	    # deplib doesn't seem to be a libtool library
+	    if test prog,link = "$linkmode,$pass"; then
+	      compile_deplibs="$deplib $compile_deplibs"
+	      finalize_deplibs="$deplib $finalize_deplibs"
+	    else
+	      deplibs="$deplib $deplibs"
+	      test lib = "$linkmode" && newdependency_libs="$deplib $newdependency_libs"
+	    fi
+	    continue
+	  fi
+	  ;; # -l
+	*.ltframework)
+	  if test prog,link = "$linkmode,$pass"; then
+	    compile_deplibs="$deplib $compile_deplibs"
+	    finalize_deplibs="$deplib $finalize_deplibs"
+	  else
+	    deplibs="$deplib $deplibs"
+	    if test lib = "$linkmode"; then
+		case "$new_inherited_linker_flags " in
+		    *" $deplib "*) ;;
+		    * ) func_append new_inherited_linker_flags " $deplib" ;;
+		esac
+	    fi
+	  fi
+	  continue
+	  ;;
+	-L*)
+	  case $linkmode in
+	  lib)
+	    deplibs="$deplib $deplibs"
+	    test conv = "$pass" && continue
+	    newdependency_libs="$deplib $newdependency_libs"
+	    func_stripname '-L' '' "$deplib"
+	    func_resolve_sysroot "$func_stripname_result"
+	    func_append newlib_search_path " $func_resolve_sysroot_result"
+	    ;;
+	  prog)
+	    if test conv = "$pass"; then
+	      deplibs="$deplib $deplibs"
+	      continue
+	    fi
+	    if test scan = "$pass"; then
+	      deplibs="$deplib $deplibs"
+	    else
+	      compile_deplibs="$deplib $compile_deplibs"
+	      finalize_deplibs="$deplib $finalize_deplibs"
+	    fi
+	    func_stripname '-L' '' "$deplib"
+	    func_resolve_sysroot "$func_stripname_result"
+	    func_append newlib_search_path " $func_resolve_sysroot_result"
+	    ;;
+	  *)
+	    func_warning "'-L' is ignored for archives/objects"
+	    ;;
+	  esac # linkmode
+	  continue
+	  ;; # -L
+	-R*)
+	  if test link = "$pass"; then
+	    func_stripname '-R' '' "$deplib"
+	    func_resolve_sysroot "$func_stripname_result"
+	    dir=$func_resolve_sysroot_result
+	    # Make sure the xrpath contains only unique directories.
+	    case "$xrpath " in
+	    *" $dir "*) ;;
+	    *) func_append xrpath " $dir" ;;
+	    esac
+	  fi
+	  deplibs="$deplib $deplibs"
+	  continue
+	  ;;
+	*.la)
+	  func_resolve_sysroot "$deplib"
+	  lib=$func_resolve_sysroot_result
+	  ;;
+	*.$libext)
+	  if test conv = "$pass"; then
+	    deplibs="$deplib $deplibs"
+	    continue
+	  fi
+	  case $linkmode in
+	  lib)
+	    # Linking convenience modules into shared libraries is allowed,
+	    # but linking other static libraries is non-portable.
+	    case " $dlpreconveniencelibs " in
+	    *" $deplib "*) ;;
+	    *)
+	      valid_a_lib=false
+	      case $deplibs_check_method in
+		match_pattern*)
+		  set dummy $deplibs_check_method; shift
+		  match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"`
+		  if eval "\$ECHO \"$deplib\"" 2>/dev/null | $SED 10q \
+		    | $EGREP "$match_pattern_regex" > /dev/null; then
+		    valid_a_lib=:
+		  fi
+		;;
+		pass_all)
+		  valid_a_lib=:
+		;;
+	      esac
+	      if $valid_a_lib; then
+		echo
+		$ECHO "*** Warning: Linking the shared library $output against the"
+		$ECHO "*** static library $deplib is not portable!"
+		deplibs="$deplib $deplibs"
+	      else
+		echo
+		$ECHO "*** Warning: Trying to link with static lib archive $deplib."
+		echo "*** I have the capability to make that library automatically link in when"
+		echo "*** you link to this library.  But I can only do this if you have a"
+		echo "*** shared version of the library, which you do not appear to have"
+		echo "*** because the file extensions .$libext of this argument makes me believe"
+		echo "*** that it is just a static archive that I should not use here."
+	      fi
+	      ;;
+	    esac
+	    continue
+	    ;;
+	  prog)
+	    if test link != "$pass"; then
+	      deplibs="$deplib $deplibs"
+	    else
+	      compile_deplibs="$deplib $compile_deplibs"
+	      finalize_deplibs="$deplib $finalize_deplibs"
+	    fi
+	    continue
+	    ;;
+	  esac # linkmode
+	  ;; # *.$libext
+	*.lo | *.$objext)
+	  if test conv = "$pass"; then
+	    deplibs="$deplib $deplibs"
+	  elif test prog = "$linkmode"; then
+	    if test dlpreopen = "$pass" || test yes != "$dlopen_support" || test no = "$build_libtool_libs"; then
+	      # If there is no dlopen support or we're linking statically,
+	      # we need to preload.
+	      func_append newdlprefiles " $deplib"
+	      compile_deplibs="$deplib $compile_deplibs"
+	      finalize_deplibs="$deplib $finalize_deplibs"
+	    else
+	      func_append newdlfiles " $deplib"
+	    fi
+	  fi
+	  continue
+	  ;;
+	%DEPLIBS%)
+	  alldeplibs=:
+	  continue
+	  ;;
+	esac # case $deplib
+
+	$found || test -f "$lib" \
+	  || func_fatal_error "cannot find the library '$lib' or unhandled argument '$deplib'"
+
+	# Check to see that this really is a libtool archive.
+	func_lalib_unsafe_p "$lib" \
+	  || func_fatal_error "'$lib' is not a valid libtool archive"
+
+	func_dirname "$lib" "" "."
+	ladir=$func_dirname_result
+
+	dlname=
+	dlopen=
+	dlpreopen=
+	libdir=
+	library_names=
+	old_library=
+	inherited_linker_flags=
+	# If the library was installed with an old release of libtool,
+	# it will not redefine variables installed, or shouldnotlink
+	installed=yes
+	shouldnotlink=no
+	avoidtemprpath=
+
+
+	# Read the .la file
+	func_source "$lib"
+
+	# Convert "-framework foo" to "foo.ltframework"
+	if test -n "$inherited_linker_flags"; then
+	  tmp_inherited_linker_flags=`$ECHO "$inherited_linker_flags" | $SED 's/-framework \([^ $]*\)/\1.ltframework/g'`
+	  for tmp_inherited_linker_flag in $tmp_inherited_linker_flags; do
+	    case " $new_inherited_linker_flags " in
+	      *" $tmp_inherited_linker_flag "*) ;;
+	      *) func_append new_inherited_linker_flags " $tmp_inherited_linker_flag";;
+	    esac
+	  done
+	fi
+	dependency_libs=`$ECHO " $dependency_libs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+	if test lib,link = "$linkmode,$pass" ||
+	   test prog,scan = "$linkmode,$pass" ||
+	   { test prog != "$linkmode" && test lib != "$linkmode"; }; then
+	  test -n "$dlopen" && func_append dlfiles " $dlopen"
+	  test -n "$dlpreopen" && func_append dlprefiles " $dlpreopen"
+	fi
+
+	if test conv = "$pass"; then
+	  # Only check for convenience libraries
+	  deplibs="$lib $deplibs"
+	  if test -z "$libdir"; then
+	    if test -z "$old_library"; then
+	      func_fatal_error "cannot find name of link library for '$lib'"
+	    fi
+	    # It is a libtool convenience library, so add in its objects.
+	    func_append convenience " $ladir/$objdir/$old_library"
+	    func_append old_convenience " $ladir/$objdir/$old_library"
+	    tmp_libs=
+	    for deplib in $dependency_libs; do
+	      deplibs="$deplib $deplibs"
+	      if $opt_preserve_dup_deps; then
+		case "$tmp_libs " in
+		*" $deplib "*) func_append specialdeplibs " $deplib" ;;
+		esac
+	      fi
+	      func_append tmp_libs " $deplib"
+	    done
+	  elif test prog != "$linkmode" && test lib != "$linkmode"; then
+	    func_fatal_error "'$lib' is not a convenience library"
+	  fi
+	  continue
+	fi # $pass = conv
+
+
+	# Get the name of the library we link against.
+	linklib=
+	if test -n "$old_library" &&
+	   { test yes = "$prefer_static_libs" ||
+	     test built,no = "$prefer_static_libs,$installed"; }; then
+	  linklib=$old_library
+	else
+	  for l in $old_library $library_names; do
+	    linklib=$l
+	  done
+	fi
+	if test -z "$linklib"; then
+	  func_fatal_error "cannot find name of link library for '$lib'"
+	fi
+
+	# This library was specified with -dlopen.
+	if test dlopen = "$pass"; then
+	  test -z "$libdir" \
+	    && func_fatal_error "cannot -dlopen a convenience library: '$lib'"
+	  if test -z "$dlname" ||
+	     test yes != "$dlopen_support" ||
+	     test no = "$build_libtool_libs"
+	  then
+	    # If there is no dlname, no dlopen support or we're linking
+	    # statically, we need to preload.  We also need to preload any
+	    # dependent libraries so libltdl's deplib preloader doesn't
+	    # bomb out in the load deplibs phase.
+	    func_append dlprefiles " $lib $dependency_libs"
+	  else
+	    func_append newdlfiles " $lib"
+	  fi
+	  continue
+	fi # $pass = dlopen
+
+	# We need an absolute path.
+	case $ladir in
+	[\\/]* | [A-Za-z]:[\\/]*) abs_ladir=$ladir ;;
+	*)
+	  abs_ladir=`cd "$ladir" && pwd`
+	  if test -z "$abs_ladir"; then
+	    func_warning "cannot determine absolute directory name of '$ladir'"
+	    func_warning "passing it literally to the linker, although it might fail"
+	    abs_ladir=$ladir
+	  fi
+	  ;;
+	esac
+	func_basename "$lib"
+	laname=$func_basename_result
+
+	# Find the relevant object directory and library name.
+	if test yes = "$installed"; then
+	  if test ! -f "$lt_sysroot$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then
+	    func_warning "library '$lib' was moved."
+	    dir=$ladir
+	    absdir=$abs_ladir
+	    libdir=$abs_ladir
+	  else
+	    dir=$lt_sysroot$libdir
+	    absdir=$lt_sysroot$libdir
+	  fi
+	  test yes = "$hardcode_automatic" && avoidtemprpath=yes
+	else
+	  if test ! -f "$ladir/$objdir/$linklib" && test -f "$abs_ladir/$linklib"; then
+	    dir=$ladir
+	    absdir=$abs_ladir
+	    # Remove this search path later
+	    func_append notinst_path " $abs_ladir"
+	  else
+	    dir=$ladir/$objdir
+	    absdir=$abs_ladir/$objdir
+	    # Remove this search path later
+	    func_append notinst_path " $abs_ladir"
+	  fi
+	fi # $installed = yes
+	func_stripname 'lib' '.la' "$laname"
+	name=$func_stripname_result
+
+	# This library was specified with -dlpreopen.
+	if test dlpreopen = "$pass"; then
+	  if test -z "$libdir" && test prog = "$linkmode"; then
+	    func_fatal_error "only libraries may -dlpreopen a convenience library: '$lib'"
+	  fi
+	  case $host in
+	    # special handling for platforms with PE-DLLs.
+	    *cygwin* | *mingw* | *cegcc* )
+	      # Linker will automatically link against shared library if both
+	      # static and shared are present.  Therefore, ensure we extract
+	      # symbols from the import library if a shared library is present
+	      # (otherwise, the dlopen module name will be incorrect).  We do
+	      # this by putting the import library name into $newdlprefiles.
+	      # We recover the dlopen module name by 'saving' the la file
+	      # name in a special purpose variable, and (later) extracting the
+	      # dlname from the la file.
+	      if test -n "$dlname"; then
+	        func_tr_sh "$dir/$linklib"
+	        eval "libfile_$func_tr_sh_result=\$abs_ladir/\$laname"
+	        func_append newdlprefiles " $dir/$linklib"
+	      else
+	        func_append newdlprefiles " $dir/$old_library"
+	        # Keep a list of preopened convenience libraries to check
+	        # that they are being used correctly in the link pass.
+	        test -z "$libdir" && \
+	          func_append dlpreconveniencelibs " $dir/$old_library"
+	      fi
+	    ;;
+	    * )
+	      # Prefer using a static library (so that no silly _DYNAMIC symbols
+	      # are required to link).
+	      if test -n "$old_library"; then
+	        func_append newdlprefiles " $dir/$old_library"
+	        # Keep a list of preopened convenience libraries to check
+	        # that they are being used correctly in the link pass.
+	        test -z "$libdir" && \
+	          func_append dlpreconveniencelibs " $dir/$old_library"
+	      # Otherwise, use the dlname, so that lt_dlopen finds it.
+	      elif test -n "$dlname"; then
+	        func_append newdlprefiles " $dir/$dlname"
+	      else
+	        func_append newdlprefiles " $dir/$linklib"
+	      fi
+	    ;;
+	  esac
+	fi # $pass = dlpreopen
+
+	if test -z "$libdir"; then
+	  # Link the convenience library
+	  if test lib = "$linkmode"; then
+	    deplibs="$dir/$old_library $deplibs"
+	  elif test prog,link = "$linkmode,$pass"; then
+	    compile_deplibs="$dir/$old_library $compile_deplibs"
+	    finalize_deplibs="$dir/$old_library $finalize_deplibs"
+	  else
+	    deplibs="$lib $deplibs" # used for prog,scan pass
+	  fi
+	  continue
+	fi
+
+
+	if test prog = "$linkmode" && test link != "$pass"; then
+	  func_append newlib_search_path " $ladir"
+	  deplibs="$lib $deplibs"
+
+	  linkalldeplibs=false
+	  if test no != "$link_all_deplibs" || test -z "$library_names" ||
+	     test no = "$build_libtool_libs"; then
+	    linkalldeplibs=:
+	  fi
+
+	  tmp_libs=
+	  for deplib in $dependency_libs; do
+	    case $deplib in
+	    -L*) func_stripname '-L' '' "$deplib"
+	         func_resolve_sysroot "$func_stripname_result"
+	         func_append newlib_search_path " $func_resolve_sysroot_result"
+		 ;;
+	    esac
+	    # Need to link against all dependency_libs?
+	    if $linkalldeplibs; then
+	      deplibs="$deplib $deplibs"
+	    else
+	      # Need to hardcode shared library paths
+	      # or/and link against static libraries
+	      newdependency_libs="$deplib $newdependency_libs"
+	    fi
+	    if $opt_preserve_dup_deps; then
+	      case "$tmp_libs " in
+	      *" $deplib "*) func_append specialdeplibs " $deplib" ;;
+	      esac
+	    fi
+	    func_append tmp_libs " $deplib"
+	  done # for deplib
+	  continue
+	fi # $linkmode = prog...
+
+	if test prog,link = "$linkmode,$pass"; then
+	  if test -n "$library_names" &&
+	     { { test no = "$prefer_static_libs" ||
+	         test built,yes = "$prefer_static_libs,$installed"; } ||
+	       test -z "$old_library"; }; then
+	    # We need to hardcode the library path
+	    if test -n "$shlibpath_var" && test -z "$avoidtemprpath"; then
+	      # Make sure the rpath contains only unique directories.
+	      case $temp_rpath: in
+	      *"$absdir:"*) ;;
+	      *) func_append temp_rpath "$absdir:" ;;
+	      esac
+	    fi
+
+	    # Hardcode the library path.
+	    # Skip directories that are in the system default run-time
+	    # search path.
+	    case " $sys_lib_dlsearch_path " in
+	    *" $absdir "*) ;;
+	    *)
+	      case "$compile_rpath " in
+	      *" $absdir "*) ;;
+	      *) func_append compile_rpath " $absdir" ;;
+	      esac
+	      ;;
+	    esac
+	    case " $sys_lib_dlsearch_path " in
+	    *" $libdir "*) ;;
+	    *)
+	      case "$finalize_rpath " in
+	      *" $libdir "*) ;;
+	      *) func_append finalize_rpath " $libdir" ;;
+	      esac
+	      ;;
+	    esac
+	  fi # $linkmode,$pass = prog,link...
+
+	  if $alldeplibs &&
+	     { test pass_all = "$deplibs_check_method" ||
+	       { test yes = "$build_libtool_libs" &&
+		 test -n "$library_names"; }; }; then
+	    # We only need to search for static libraries
+	    continue
+	  fi
+	fi
+
+	link_static=no # Whether the deplib will be linked statically
+	use_static_libs=$prefer_static_libs
+	if test built = "$use_static_libs" && test yes = "$installed"; then
+	  use_static_libs=no
+	fi
+	if test -n "$library_names" &&
+	   { test no = "$use_static_libs" || test -z "$old_library"; }; then
+	  case $host in
+	  *cygwin* | *mingw* | *cegcc* | *os2*)
+	      # No point in relinking DLLs because paths are not encoded
+	      func_append notinst_deplibs " $lib"
+	      need_relink=no
+	    ;;
+	  *)
+	    if test no = "$installed"; then
+	      func_append notinst_deplibs " $lib"
+	      need_relink=yes
+	    fi
+	    ;;
+	  esac
+	  # This is a shared library
+
+	  # Warn about portability, can't link against -module's on some
+	  # systems (darwin).  Don't bleat about dlopened modules though!
+	  dlopenmodule=
+	  for dlpremoduletest in $dlprefiles; do
+	    if test "X$dlpremoduletest" = "X$lib"; then
+	      dlopenmodule=$dlpremoduletest
+	      break
+	    fi
+	  done
+	  if test -z "$dlopenmodule" && test yes = "$shouldnotlink" && test link = "$pass"; then
+	    echo
+	    if test prog = "$linkmode"; then
+	      $ECHO "*** Warning: Linking the executable $output against the loadable module"
+	    else
+	      $ECHO "*** Warning: Linking the shared library $output against the loadable module"
+	    fi
+	    $ECHO "*** $linklib is not portable!"
+	  fi
+	  if test lib = "$linkmode" &&
+	     test yes = "$hardcode_into_libs"; then
+	    # Hardcode the library path.
+	    # Skip directories that are in the system default run-time
+	    # search path.
+	    case " $sys_lib_dlsearch_path " in
+	    *" $absdir "*) ;;
+	    *)
+	      case "$compile_rpath " in
+	      *" $absdir "*) ;;
+	      *) func_append compile_rpath " $absdir" ;;
+	      esac
+	      ;;
+	    esac
+	    case " $sys_lib_dlsearch_path " in
+	    *" $libdir "*) ;;
+	    *)
+	      case "$finalize_rpath " in
+	      *" $libdir "*) ;;
+	      *) func_append finalize_rpath " $libdir" ;;
+	      esac
+	      ;;
+	    esac
+	  fi
+
+	  if test -n "$old_archive_from_expsyms_cmds"; then
+	    # figure out the soname
+	    set dummy $library_names
+	    shift
+	    realname=$1
+	    shift
+	    libname=`eval "\\$ECHO \"$libname_spec\""`
+	    # use dlname if we got it. it's perfectly good, no?
+	    if test -n "$dlname"; then
+	      soname=$dlname
+	    elif test -n "$soname_spec"; then
+	      # bleh windows
+	      case $host in
+	      *cygwin* | mingw* | *cegcc* | *os2*)
+	        func_arith $current - $age
+		major=$func_arith_result
+		versuffix=-$major
+		;;
+	      esac
+	      eval soname=\"$soname_spec\"
+	    else
+	      soname=$realname
+	    fi
+
+	    # Make a new name for the extract_expsyms_cmds to use
+	    soroot=$soname
+	    func_basename "$soroot"
+	    soname=$func_basename_result
+	    func_stripname 'lib' '.dll' "$soname"
+	    newlib=libimp-$func_stripname_result.a
+
+	    # If the library has no export list, then create one now
+	    if test -f "$output_objdir/$soname-def"; then :
+	    else
+	      func_verbose "extracting exported symbol list from '$soname'"
+	      func_execute_cmds "$extract_expsyms_cmds" 'exit $?'
+	    fi
+
+	    # Create $newlib
+	    if test -f "$output_objdir/$newlib"; then :; else
+	      func_verbose "generating import library for '$soname'"
+	      func_execute_cmds "$old_archive_from_expsyms_cmds" 'exit $?'
+	    fi
+	    # make sure the library variables are pointing to the new library
+	    dir=$output_objdir
+	    linklib=$newlib
+	  fi # test -n "$old_archive_from_expsyms_cmds"
+
+	  if test prog = "$linkmode" || test relink != "$opt_mode"; then
+	    add_shlibpath=
+	    add_dir=
+	    add=
+	    lib_linked=yes
+	    case $hardcode_action in
+	    immediate | unsupported)
+	      if test no = "$hardcode_direct"; then
+		add=$dir/$linklib
+		case $host in
+		  *-*-sco3.2v5.0.[024]*) add_dir=-L$dir ;;
+		  *-*-sysv4*uw2*) add_dir=-L$dir ;;
+		  *-*-sysv5OpenUNIX* | *-*-sysv5UnixWare7.[01].[10]* | \
+		    *-*-unixware7*) add_dir=-L$dir ;;
+		  *-*-darwin* )
+		    # if the lib is a (non-dlopened) module then we cannot
+		    # link against it, someone is ignoring the earlier warnings
+		    if /usr/bin/file -L $add 2> /dev/null |
+			 $GREP ": [^:]* bundle" >/dev/null; then
+		      if test "X$dlopenmodule" != "X$lib"; then
+			$ECHO "*** Warning: lib $linklib is a module, not a shared library"
+			if test -z "$old_library"; then
+			  echo
+			  echo "*** And there doesn't seem to be a static archive available"
+			  echo "*** The link will probably fail, sorry"
+			else
+			  add=$dir/$old_library
+			fi
+		      elif test -n "$old_library"; then
+			add=$dir/$old_library
+		      fi
+		    fi
+		esac
+	      elif test no = "$hardcode_minus_L"; then
+		case $host in
+		*-*-sunos*) add_shlibpath=$dir ;;
+		esac
+		add_dir=-L$dir
+		add=-l$name
+	      elif test no = "$hardcode_shlibpath_var"; then
+		add_shlibpath=$dir
+		add=-l$name
+	      else
+		lib_linked=no
+	      fi
+	      ;;
+	    relink)
+	      if test yes = "$hardcode_direct" &&
+	         test no = "$hardcode_direct_absolute"; then
+		add=$dir/$linklib
+	      elif test yes = "$hardcode_minus_L"; then
+		add_dir=-L$absdir
+		# Try looking first in the location we're being installed to.
+		if test -n "$inst_prefix_dir"; then
+		  case $libdir in
+		    [\\/]*)
+		      func_append add_dir " -L$inst_prefix_dir$libdir"
+		      ;;
+		  esac
+		fi
+		add=-l$name
+	      elif test yes = "$hardcode_shlibpath_var"; then
+		add_shlibpath=$dir
+		add=-l$name
+	      else
+		lib_linked=no
+	      fi
+	      ;;
+	    *) lib_linked=no ;;
+	    esac
+
+	    if test yes != "$lib_linked"; then
+	      func_fatal_configuration "unsupported hardcode properties"
+	    fi
+
+	    if test -n "$add_shlibpath"; then
+	      case :$compile_shlibpath: in
+	      *":$add_shlibpath:"*) ;;
+	      *) func_append compile_shlibpath "$add_shlibpath:" ;;
+	      esac
+	    fi
+	    if test prog = "$linkmode"; then
+	      test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs"
+	      test -n "$add" && compile_deplibs="$add $compile_deplibs"
+	    else
+	      test -n "$add_dir" && deplibs="$add_dir $deplibs"
+	      test -n "$add" && deplibs="$add $deplibs"
+	      if test yes != "$hardcode_direct" &&
+		 test yes != "$hardcode_minus_L" &&
+		 test yes = "$hardcode_shlibpath_var"; then
+		case :$finalize_shlibpath: in
+		*":$libdir:"*) ;;
+		*) func_append finalize_shlibpath "$libdir:" ;;
+		esac
+	      fi
+	    fi
+	  fi
+
+	  if test prog = "$linkmode" || test relink = "$opt_mode"; then
+	    add_shlibpath=
+	    add_dir=
+	    add=
+	    # Finalize command for both is simple: just hardcode it.
+	    if test yes = "$hardcode_direct" &&
+	       test no = "$hardcode_direct_absolute"; then
+	      add=$libdir/$linklib
+	    elif test yes = "$hardcode_minus_L"; then
+	      add_dir=-L$libdir
+	      add=-l$name
+	    elif test yes = "$hardcode_shlibpath_var"; then
+	      case :$finalize_shlibpath: in
+	      *":$libdir:"*) ;;
+	      *) func_append finalize_shlibpath "$libdir:" ;;
+	      esac
+	      add=-l$name
+	    elif test yes = "$hardcode_automatic"; then
+	      if test -n "$inst_prefix_dir" &&
+		 test -f "$inst_prefix_dir$libdir/$linklib"; then
+		add=$inst_prefix_dir$libdir/$linklib
+	      else
+		add=$libdir/$linklib
+	      fi
+	    else
+	      # We cannot seem to hardcode it, guess we'll fake it.
+	      add_dir=-L$libdir
+	      # Try looking first in the location we're being installed to.
+	      if test -n "$inst_prefix_dir"; then
+		case $libdir in
+		  [\\/]*)
+		    func_append add_dir " -L$inst_prefix_dir$libdir"
+		    ;;
+		esac
+	      fi
+	      add=-l$name
+	    fi
+
+	    if test prog = "$linkmode"; then
+	      test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs"
+	      test -n "$add" && finalize_deplibs="$add $finalize_deplibs"
+	    else
+	      test -n "$add_dir" && deplibs="$add_dir $deplibs"
+	      test -n "$add" && deplibs="$add $deplibs"
+	    fi
+	  fi
+	elif test prog = "$linkmode"; then
+	  # Here we assume that one of hardcode_direct or hardcode_minus_L
+	  # is not unsupported.  This is valid on all known static and
+	  # shared platforms.
+	  if test unsupported != "$hardcode_direct"; then
+	    test -n "$old_library" && linklib=$old_library
+	    compile_deplibs="$dir/$linklib $compile_deplibs"
+	    finalize_deplibs="$dir/$linklib $finalize_deplibs"
+	  else
+	    compile_deplibs="-l$name -L$dir $compile_deplibs"
+	    finalize_deplibs="-l$name -L$dir $finalize_deplibs"
+	  fi
+	elif test yes = "$build_libtool_libs"; then
+	  # Not a shared library
+	  if test pass_all != "$deplibs_check_method"; then
+	    # We're trying link a shared library against a static one
+	    # but the system doesn't support it.
+
+	    # Just print a warning and add the library to dependency_libs so
+	    # that the program can be linked against the static library.
+	    echo
+	    $ECHO "*** Warning: This system cannot link to static lib archive $lib."
+	    echo "*** I have the capability to make that library automatically link in when"
+	    echo "*** you link to this library.  But I can only do this if you have a"
+	    echo "*** shared version of the library, which you do not appear to have."
+	    if test yes = "$module"; then
+	      echo "*** But as you try to build a module library, libtool will still create "
+	      echo "*** a static module, that should work as long as the dlopening application"
+	      echo "*** is linked with the -dlopen flag to resolve symbols at runtime."
+	      if test -z "$global_symbol_pipe"; then
+		echo
+		echo "*** However, this would only work if libtool was able to extract symbol"
+		echo "*** lists from a program, using 'nm' or equivalent, but libtool could"
+		echo "*** not find such a program.  So, this module is probably useless."
+		echo "*** 'nm' from GNU binutils and a full rebuild may help."
+	      fi
+	      if test no = "$build_old_libs"; then
+		build_libtool_libs=module
+		build_old_libs=yes
+	      else
+		build_libtool_libs=no
+	      fi
+	    fi
+	  else
+	    deplibs="$dir/$old_library $deplibs"
+	    link_static=yes
+	  fi
+	fi # link shared/static library?
+
+	if test lib = "$linkmode"; then
+	  if test -n "$dependency_libs" &&
+	     { test yes != "$hardcode_into_libs" ||
+	       test yes = "$build_old_libs" ||
+	       test yes = "$link_static"; }; then
+	    # Extract -R from dependency_libs
+	    temp_deplibs=
+	    for libdir in $dependency_libs; do
+	      case $libdir in
+	      -R*) func_stripname '-R' '' "$libdir"
+	           temp_xrpath=$func_stripname_result
+		   case " $xrpath " in
+		   *" $temp_xrpath "*) ;;
+		   *) func_append xrpath " $temp_xrpath";;
+		   esac;;
+	      *) func_append temp_deplibs " $libdir";;
+	      esac
+	    done
+	    dependency_libs=$temp_deplibs
+	  fi
+
+	  func_append newlib_search_path " $absdir"
+	  # Link against this library
+	  test no = "$link_static" && newdependency_libs="$abs_ladir/$laname $newdependency_libs"
+	  # ... and its dependency_libs
+	  tmp_libs=
+	  for deplib in $dependency_libs; do
+	    newdependency_libs="$deplib $newdependency_libs"
+	    case $deplib in
+              -L*) func_stripname '-L' '' "$deplib"
+                   func_resolve_sysroot "$func_stripname_result";;
+              *) func_resolve_sysroot "$deplib" ;;
+            esac
+	    if $opt_preserve_dup_deps; then
+	      case "$tmp_libs " in
+	      *" $func_resolve_sysroot_result "*)
+                func_append specialdeplibs " $func_resolve_sysroot_result" ;;
+	      esac
+	    fi
+	    func_append tmp_libs " $func_resolve_sysroot_result"
+	  done
+
+	  if test no != "$link_all_deplibs"; then
+	    # Add the search paths of all dependency libraries
+	    for deplib in $dependency_libs; do
+	      path=
+	      case $deplib in
+	      -L*) path=$deplib ;;
+	      *.la)
+	        func_resolve_sysroot "$deplib"
+	        deplib=$func_resolve_sysroot_result
+	        func_dirname "$deplib" "" "."
+		dir=$func_dirname_result
+		# We need an absolute path.
+		case $dir in
+		[\\/]* | [A-Za-z]:[\\/]*) absdir=$dir ;;
+		*)
+		  absdir=`cd "$dir" && pwd`
+		  if test -z "$absdir"; then
+		    func_warning "cannot determine absolute directory name of '$dir'"
+		    absdir=$dir
+		  fi
+		  ;;
+		esac
+		if $GREP "^installed=no" $deplib > /dev/null; then
+		case $host in
+		*-*-darwin*)
+		  depdepl=
+		  eval deplibrary_names=`$SED -n -e 's/^library_names=\(.*\)$/\1/p' $deplib`
+		  if test -n "$deplibrary_names"; then
+		    for tmp in $deplibrary_names; do
+		      depdepl=$tmp
+		    done
+		    if test -f "$absdir/$objdir/$depdepl"; then
+		      depdepl=$absdir/$objdir/$depdepl
+		      darwin_install_name=`$OTOOL -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'`
+                      if test -z "$darwin_install_name"; then
+                          darwin_install_name=`$OTOOL64 -L $depdepl  | awk '{if (NR == 2) {print $1;exit}}'`
+                      fi
+		      func_append compiler_flags " $wl-dylib_file $wl$darwin_install_name:$depdepl"
+		      func_append linker_flags " -dylib_file $darwin_install_name:$depdepl"
+		      path=
+		    fi
+		  fi
+		  ;;
+		*)
+		  path=-L$absdir/$objdir
+		  ;;
+		esac
+		else
+		  eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $deplib`
+		  test -z "$libdir" && \
+		    func_fatal_error "'$deplib' is not a valid libtool archive"
+		  test "$absdir" != "$libdir" && \
+		    func_warning "'$deplib' seems to be moved"
+
+		  path=-L$absdir
+		fi
+		;;
+	      esac
+	      case " $deplibs " in
+	      *" $path "*) ;;
+	      *) deplibs="$path $deplibs" ;;
+	      esac
+	    done
+	  fi # link_all_deplibs != no
+	fi # linkmode = lib
+      done # for deplib in $libs
+      if test link = "$pass"; then
+	if test prog = "$linkmode"; then
+	  compile_deplibs="$new_inherited_linker_flags $compile_deplibs"
+	  finalize_deplibs="$new_inherited_linker_flags $finalize_deplibs"
+	else
+	  compiler_flags="$compiler_flags "`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+	fi
+      fi
+      dependency_libs=$newdependency_libs
+      if test dlpreopen = "$pass"; then
+	# Link the dlpreopened libraries before other libraries
+	for deplib in $save_deplibs; do
+	  deplibs="$deplib $deplibs"
+	done
+      fi
+      if test dlopen != "$pass"; then
+	test conv = "$pass" || {
+	  # Make sure lib_search_path contains only unique directories.
+	  lib_search_path=
+	  for dir in $newlib_search_path; do
+	    case "$lib_search_path " in
+	    *" $dir "*) ;;
+	    *) func_append lib_search_path " $dir" ;;
+	    esac
+	  done
+	  newlib_search_path=
+	}
+
+	if test prog,link = "$linkmode,$pass"; then
+	  vars="compile_deplibs finalize_deplibs"
+	else
+	  vars=deplibs
+	fi
+	for var in $vars dependency_libs; do
+	  # Add libraries to $var in reverse order
+	  eval tmp_libs=\"\$$var\"
+	  new_libs=
+	  for deplib in $tmp_libs; do
+	    # FIXME: Pedantically, this is the right thing to do, so
+	    #        that some nasty dependency loop isn't accidentally
+	    #        broken:
+	    #new_libs="$deplib $new_libs"
+	    # Pragmatically, this seems to cause very few problems in
+	    # practice:
+	    case $deplib in
+	    -L*) new_libs="$deplib $new_libs" ;;
+	    -R*) ;;
+	    *)
+	      # And here is the reason: when a library appears more
+	      # than once as an explicit dependence of a library, or
+	      # is implicitly linked in more than once by the
+	      # compiler, it is considered special, and multiple
+	      # occurrences thereof are not removed.  Compare this
+	      # with having the same library being listed as a
+	      # dependency of multiple other libraries: in this case,
+	      # we know (pedantically, we assume) the library does not
+	      # need to be listed more than once, so we keep only the
+	      # last copy.  This is not always right, but it is rare
+	      # enough that we require users that really mean to play
+	      # such unportable linking tricks to link the library
+	      # using -Wl,-lname, so that libtool does not consider it
+	      # for duplicate removal.
+	      case " $specialdeplibs " in
+	      *" $deplib "*) new_libs="$deplib $new_libs" ;;
+	      *)
+		case " $new_libs " in
+		*" $deplib "*) ;;
+		*) new_libs="$deplib $new_libs" ;;
+		esac
+		;;
+	      esac
+	      ;;
+	    esac
+	  done
+	  tmp_libs=
+	  for deplib in $new_libs; do
+	    case $deplib in
+	    -L*)
+	      case " $tmp_libs " in
+	      *" $deplib "*) ;;
+	      *) func_append tmp_libs " $deplib" ;;
+	      esac
+	      ;;
+	    *) func_append tmp_libs " $deplib" ;;
+	    esac
+	  done
+	  eval $var=\"$tmp_libs\"
+	done # for var
+      fi
+
+      # Add Sun CC postdeps if required:
+      test CXX = "$tagname" && {
+        case $host_os in
+        linux*)
+          case `$CC -V 2>&1 | sed 5q` in
+          *Sun\ C*) # Sun C++ 5.9
+            func_suncc_cstd_abi
+
+            if test no != "$suncc_use_cstd_abi"; then
+              func_append postdeps ' -library=Cstd -library=Crun'
+            fi
+            ;;
+          esac
+          ;;
+
+        solaris*)
+          func_cc_basename "$CC"
+          case $func_cc_basename_result in
+          CC* | sunCC*)
+            func_suncc_cstd_abi
+
+            if test no != "$suncc_use_cstd_abi"; then
+              func_append postdeps ' -library=Cstd -library=Crun'
+            fi
+            ;;
+          esac
+          ;;
+        esac
+      }
+
+      # Last step: remove runtime libs from dependency_libs
+      # (they stay in deplibs)
+      tmp_libs=
+      for i in $dependency_libs; do
+	case " $predeps $postdeps $compiler_lib_search_path " in
+	*" $i "*)
+	  i=
+	  ;;
+	esac
+	if test -n "$i"; then
+	  func_append tmp_libs " $i"
+	fi
+      done
+      dependency_libs=$tmp_libs
+    done # for pass
+    if test prog = "$linkmode"; then
+      dlfiles=$newdlfiles
+    fi
+    if test prog = "$linkmode" || test lib = "$linkmode"; then
+      dlprefiles=$newdlprefiles
+    fi
+
+    case $linkmode in
+    oldlib)
+      if test -n "$dlfiles$dlprefiles" || test no != "$dlself"; then
+	func_warning "'-dlopen' is ignored for archives"
+      fi
+
+      case " $deplibs" in
+      *\ -l* | *\ -L*)
+	func_warning "'-l' and '-L' are ignored for archives" ;;
+      esac
+
+      test -n "$rpath" && \
+	func_warning "'-rpath' is ignored for archives"
+
+      test -n "$xrpath" && \
+	func_warning "'-R' is ignored for archives"
+
+      test -n "$vinfo" && \
+	func_warning "'-version-info/-version-number' is ignored for archives"
+
+      test -n "$release" && \
+	func_warning "'-release' is ignored for archives"
+
+      test -n "$export_symbols$export_symbols_regex" && \
+	func_warning "'-export-symbols' is ignored for archives"
+
+      # Now set the variables for building old libraries.
+      build_libtool_libs=no
+      oldlibs=$output
+      func_append objs "$old_deplibs"
+      ;;
+
+    lib)
+      # Make sure we only generate libraries of the form 'libNAME.la'.
+      case $outputname in
+      lib*)
+	func_stripname 'lib' '.la' "$outputname"
+	name=$func_stripname_result
+	eval shared_ext=\"$shrext_cmds\"
+	eval libname=\"$libname_spec\"
+	;;
+      *)
+	test no = "$module" \
+	  && func_fatal_help "libtool library '$output' must begin with 'lib'"
+
+	if test no != "$need_lib_prefix"; then
+	  # Add the "lib" prefix for modules if required
+	  func_stripname '' '.la' "$outputname"
+	  name=$func_stripname_result
+	  eval shared_ext=\"$shrext_cmds\"
+	  eval libname=\"$libname_spec\"
+	else
+	  func_stripname '' '.la' "$outputname"
+	  libname=$func_stripname_result
+	fi
+	;;
+      esac
+
+      if test -n "$objs"; then
+	if test pass_all != "$deplibs_check_method"; then
+	  func_fatal_error "cannot build libtool library '$output' from non-libtool objects on this host:$objs"
+	else
+	  echo
+	  $ECHO "*** Warning: Linking the shared library $output against the non-libtool"
+	  $ECHO "*** objects $objs is not portable!"
+	  func_append libobjs " $objs"
+	fi
+      fi
+
+      test no = "$dlself" \
+	|| func_warning "'-dlopen self' is ignored for libtool libraries"
+
+      set dummy $rpath
+      shift
+      test 1 -lt "$#" \
+	&& func_warning "ignoring multiple '-rpath's for a libtool library"
+
+      install_libdir=$1
+
+      oldlibs=
+      if test -z "$rpath"; then
+	if test yes = "$build_libtool_libs"; then
+	  # Building a libtool convenience library.
+	  # Some compilers have problems with a '.al' extension so
+	  # convenience libraries should have the same extension an
+	  # archive normally would.
+	  oldlibs="$output_objdir/$libname.$libext $oldlibs"
+	  build_libtool_libs=convenience
+	  build_old_libs=yes
+	fi
+
+	test -n "$vinfo" && \
+	  func_warning "'-version-info/-version-number' is ignored for convenience libraries"
+
+	test -n "$release" && \
+	  func_warning "'-release' is ignored for convenience libraries"
+      else
+
+	# Parse the version information argument.
+	save_ifs=$IFS; IFS=:
+	set dummy $vinfo 0 0 0
+	shift
+	IFS=$save_ifs
+
+	test -n "$7" && \
+	  func_fatal_help "too many parameters to '-version-info'"
+
+	# convert absolute version numbers to libtool ages
+	# this retains compatibility with .la files and attempts
+	# to make the code below a bit more comprehensible
+
+	case $vinfo_number in
+	yes)
+	  number_major=$1
+	  number_minor=$2
+	  number_revision=$3
+	  #
+	  # There are really only two kinds -- those that
+	  # use the current revision as the major version
+	  # and those that subtract age and use age as
+	  # a minor version.  But, then there is irix
+	  # that has an extra 1 added just for fun
+	  #
+	  case $version_type in
+	  # correct linux to gnu/linux during the next big refactor
+	  darwin|freebsd-elf|linux|osf|windows|none)
+	    func_arith $number_major + $number_minor
+	    current=$func_arith_result
+	    age=$number_minor
+	    revision=$number_revision
+	    ;;
+	  freebsd-aout|qnx|sunos)
+	    current=$number_major
+	    revision=$number_minor
+	    age=0
+	    ;;
+	  irix|nonstopux)
+	    func_arith $number_major + $number_minor
+	    current=$func_arith_result
+	    age=$number_minor
+	    revision=$number_minor
+	    lt_irix_increment=no
+	    ;;
+	  *)
+	    func_fatal_configuration "$modename: unknown library version type '$version_type'"
+	    ;;
+	  esac
+	  ;;
+	no)
+	  current=$1
+	  revision=$2
+	  age=$3
+	  ;;
+	esac
+
+	# Check that each of the things are valid numbers.
+	case $current in
+	0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;;
+	*)
+	  func_error "CURRENT '$current' must be a nonnegative integer"
+	  func_fatal_error "'$vinfo' is not valid version information"
+	  ;;
+	esac
+
+	case $revision in
+	0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;;
+	*)
+	  func_error "REVISION '$revision' must be a nonnegative integer"
+	  func_fatal_error "'$vinfo' is not valid version information"
+	  ;;
+	esac
+
+	case $age in
+	0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;;
+	*)
+	  func_error "AGE '$age' must be a nonnegative integer"
+	  func_fatal_error "'$vinfo' is not valid version information"
+	  ;;
+	esac
+
+	if test "$age" -gt "$current"; then
+	  func_error "AGE '$age' is greater than the current interface number '$current'"
+	  func_fatal_error "'$vinfo' is not valid version information"
+	fi
+
+	# Calculate the version variables.
+	major=
+	versuffix=
+	verstring=
+	case $version_type in
+	none) ;;
+
+	darwin)
+	  # Like Linux, but with the current version available in
+	  # verstring for coding it into the library header
+	  func_arith $current - $age
+	  major=.$func_arith_result
+	  versuffix=$major.$age.$revision
+	  # Darwin ld doesn't like 0 for these options...
+	  func_arith $current + 1
+	  minor_current=$func_arith_result
+	  xlcverstring="$wl-compatibility_version $wl$minor_current $wl-current_version $wl$minor_current.$revision"
+	  verstring="-compatibility_version $minor_current -current_version $minor_current.$revision"
+          # On Darwin other compilers
+          case $CC in
+              nagfor*)
+                  verstring="$wl-compatibility_version $wl$minor_current $wl-current_version $wl$minor_current.$revision"
+                  ;;
+              *)
+                  verstring="-compatibility_version $minor_current -current_version $minor_current.$revision"
+                  ;;
+          esac
+	  ;;
+
+	freebsd-aout)
+	  major=.$current
+	  versuffix=.$current.$revision
+	  ;;
+
+	freebsd-elf)
+	  func_arith $current - $age
+	  major=.$func_arith_result
+	  versuffix=$major.$age.$revision
+	  ;;
+
+	irix | nonstopux)
+	  if test no = "$lt_irix_increment"; then
+	    func_arith $current - $age
+	  else
+	    func_arith $current - $age + 1
+	  fi
+	  major=$func_arith_result
+
+	  case $version_type in
+	    nonstopux) verstring_prefix=nonstopux ;;
+	    *)         verstring_prefix=sgi ;;
+	  esac
+	  verstring=$verstring_prefix$major.$revision
+
+	  # Add in all the interfaces that we are compatible with.
+	  loop=$revision
+	  while test 0 -ne "$loop"; do
+	    func_arith $revision - $loop
+	    iface=$func_arith_result
+	    func_arith $loop - 1
+	    loop=$func_arith_result
+	    verstring=$verstring_prefix$major.$iface:$verstring
+	  done
+
+	  # Before this point, $major must not contain '.'.
+	  major=.$major
+	  versuffix=$major.$revision
+	  ;;
+
+	linux) # correct to gnu/linux during the next big refactor
+	  func_arith $current - $age
+	  major=.$func_arith_result
+	  versuffix=$major.$age.$revision
+	  ;;
+
+	osf)
+	  func_arith $current - $age
+	  major=.$func_arith_result
+	  versuffix=.$current.$age.$revision
+	  verstring=$current.$age.$revision
+
+	  # Add in all the interfaces that we are compatible with.
+	  loop=$age
+	  while test 0 -ne "$loop"; do
+	    func_arith $current - $loop
+	    iface=$func_arith_result
+	    func_arith $loop - 1
+	    loop=$func_arith_result
+	    verstring=$verstring:$iface.0
+	  done
+
+	  # Make executables depend on our current version.
+	  func_append verstring ":$current.0"
+	  ;;
+
+	qnx)
+	  major=.$current
+	  versuffix=.$current
+	  ;;
+
+	sco)
+	  major=.$current
+	  versuffix=.$current
+	  ;;
+
+	sunos)
+	  major=.$current
+	  versuffix=.$current.$revision
+	  ;;
+
+	windows)
+	  # Use '-' rather than '.', since we only want one
+	  # extension on DOS 8.3 file systems.
+	  func_arith $current - $age
+	  major=$func_arith_result
+	  versuffix=-$major
+	  ;;
+
+	*)
+	  func_fatal_configuration "unknown library version type '$version_type'"
+	  ;;
+	esac
+
+	# Clear the version info if we defaulted, and they specified a release.
+	if test -z "$vinfo" && test -n "$release"; then
+	  major=
+	  case $version_type in
+	  darwin)
+	    # we can't check for "0.0" in archive_cmds due to quoting
+	    # problems, so we reset it completely
+	    verstring=
+	    ;;
+	  *)
+	    verstring=0.0
+	    ;;
+	  esac
+	  if test no = "$need_version"; then
+	    versuffix=
+	  else
+	    versuffix=.0.0
+	  fi
+	fi
+
+	# Remove version info from name if versioning should be avoided
+	if test yes,no = "$avoid_version,$need_version"; then
+	  major=
+	  versuffix=
+	  verstring=
+	fi
+
+	# Check to see if the archive will have undefined symbols.
+	if test yes = "$allow_undefined"; then
+	  if test unsupported = "$allow_undefined_flag"; then
+	    if test yes = "$build_old_libs"; then
+	      func_warning "undefined symbols not allowed in $host shared libraries; building static only"
+	      build_libtool_libs=no
+	    else
+	      func_fatal_error "can't build $host shared library unless -no-undefined is specified"
+	    fi
+	  fi
+	else
+	  # Don't allow undefined symbols.
+	  allow_undefined_flag=$no_undefined_flag
+	fi
+
+      fi
+
+      func_generate_dlsyms "$libname" "$libname" :
+      func_append libobjs " $symfileobj"
+      test " " = "$libobjs" && libobjs=
+
+      if test relink != "$opt_mode"; then
+	# Remove our outputs, but don't remove object files since they
+	# may have been created when compiling PIC objects.
+	removelist=
+	tempremovelist=`$ECHO "$output_objdir/*"`
+	for p in $tempremovelist; do
+	  case $p in
+	    *.$objext | *.gcno)
+	       ;;
+	    $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/$libname$release.*)
+	       if test -n "$precious_files_regex"; then
+		 if $ECHO "$p" | $EGREP -e "$precious_files_regex" >/dev/null 2>&1
+		 then
+		   continue
+		 fi
+	       fi
+	       func_append removelist " $p"
+	       ;;
+	    *) ;;
+	  esac
+	done
+	test -n "$removelist" && \
+	  func_show_eval "${RM}r \$removelist"
+      fi
+
+      # Now set the variables for building old libraries.
+      if test yes = "$build_old_libs" && test convenience != "$build_libtool_libs"; then
+	func_append oldlibs " $output_objdir/$libname.$libext"
+
+	# Transform .lo files to .o files.
+	oldobjs="$objs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.$libext$/d; $lo2o" | $NL2SP`
+      fi
+
+      # Eliminate all temporary directories.
+      #for path in $notinst_path; do
+      #	lib_search_path=`$ECHO "$lib_search_path " | $SED "s% $path % %g"`
+      #	deplibs=`$ECHO "$deplibs " | $SED "s% -L$path % %g"`
+      #	dependency_libs=`$ECHO "$dependency_libs " | $SED "s% -L$path % %g"`
+      #done
+
+      if test -n "$xrpath"; then
+	# If the user specified any rpath flags, then add them.
+	temp_xrpath=
+	for libdir in $xrpath; do
+	  func_replace_sysroot "$libdir"
+	  func_append temp_xrpath " -R$func_replace_sysroot_result"
+	  case "$finalize_rpath " in
+	  *" $libdir "*) ;;
+	  *) func_append finalize_rpath " $libdir" ;;
+	  esac
+	done
+	if test yes != "$hardcode_into_libs" || test yes = "$build_old_libs"; then
+	  dependency_libs="$temp_xrpath $dependency_libs"
+	fi
+      fi
+
+      # Make sure dlfiles contains only unique files that won't be dlpreopened
+      old_dlfiles=$dlfiles
+      dlfiles=
+      for lib in $old_dlfiles; do
+	case " $dlprefiles $dlfiles " in
+	*" $lib "*) ;;
+	*) func_append dlfiles " $lib" ;;
+	esac
+      done
+
+      # Make sure dlprefiles contains only unique files
+      old_dlprefiles=$dlprefiles
+      dlprefiles=
+      for lib in $old_dlprefiles; do
+	case "$dlprefiles " in
+	*" $lib "*) ;;
+	*) func_append dlprefiles " $lib" ;;
+	esac
+      done
+
+      if test yes = "$build_libtool_libs"; then
+	if test -n "$rpath"; then
+	  case $host in
+	  *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos* | *-cegcc* | *-*-haiku*)
+	    # these systems don't actually have a c library (as such)!
+	    ;;
+	  *-*-rhapsody* | *-*-darwin1.[012])
+	    # Rhapsody C library is in the System framework
+	    func_append deplibs " System.ltframework"
+	    ;;
+	  *-*-netbsd*)
+	    # Don't link with libc until the a.out ld.so is fixed.
+	    ;;
+	  *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*)
+	    # Do not include libc due to us having libc/libc_r.
+	    ;;
+	  *-*-sco3.2v5* | *-*-sco5v6*)
+	    # Causes problems with __ctype
+	    ;;
+	  *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*)
+	    # Compiler inserts libc in the correct place for threads to work
+	    ;;
+	  *)
+	    # Add libc to deplibs on all other systems if necessary.
+	    if test yes = "$build_libtool_need_lc"; then
+	      func_append deplibs " -lc"
+	    fi
+	    ;;
+	  esac
+	fi
+
+	# Transform deplibs into only deplibs that can be linked in shared.
+	name_save=$name
+	libname_save=$libname
+	release_save=$release
+	versuffix_save=$versuffix
+	major_save=$major
+	# I'm not sure if I'm treating the release correctly.  I think
+	# release should show up in the -l (ie -lgmp5) so we don't want to
+	# add it in twice.  Is that correct?
+	release=
+	versuffix=
+	major=
+	newdeplibs=
+	droppeddeps=no
+	case $deplibs_check_method in
+	pass_all)
+	  # Don't check for shared/static.  Everything works.
+	  # This might be a little naive.  We might want to check
+	  # whether the library exists or not.  But this is on
+	  # osf3 & osf4 and I'm not really sure... Just
+	  # implementing what was already the behavior.
+	  newdeplibs=$deplibs
+	  ;;
+	test_compile)
+	  # This code stresses the "libraries are programs" paradigm to its
+	  # limits. Maybe even breaks it.  We compile a program, linking it
+	  # against the deplibs as a proxy for the library.  Then we can check
+	  # whether they linked in statically or dynamically with ldd.
+	  $opt_dry_run || $RM conftest.c
+	  cat > conftest.c <<EOF
+	  int main() { return 0; }
+EOF
+	  $opt_dry_run || $RM conftest
+	  if $LTCC $LTCFLAGS -o conftest conftest.c $deplibs; then
+	    ldd_output=`ldd conftest`
+	    for i in $deplibs; do
+	      case $i in
+	      -l*)
+		func_stripname -l '' "$i"
+		name=$func_stripname_result
+		if test yes = "$allow_libtool_libs_with_static_runtimes"; then
+		  case " $predeps $postdeps " in
+		  *" $i "*)
+		    func_append newdeplibs " $i"
+		    i=
+		    ;;
+		  esac
+		fi
+		if test -n "$i"; then
+		  libname=`eval "\\$ECHO \"$libname_spec\""`
+		  deplib_matches=`eval "\\$ECHO \"$library_names_spec\""`
+		  set dummy $deplib_matches; shift
+		  deplib_match=$1
+		  if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0; then
+		    func_append newdeplibs " $i"
+		  else
+		    droppeddeps=yes
+		    echo
+		    $ECHO "*** Warning: dynamic linker does not accept needed library $i."
+		    echo "*** I have the capability to make that library automatically link in when"
+		    echo "*** you link to this library.  But I can only do this if you have a"
+		    echo "*** shared version of the library, which I believe you do not have"
+		    echo "*** because a test_compile did reveal that the linker did not use it for"
+		    echo "*** its dynamic dependency list that programs get resolved with at runtime."
+		  fi
+		fi
+		;;
+	      *)
+		func_append newdeplibs " $i"
+		;;
+	      esac
+	    done
+	  else
+	    # Error occurred in the first compile.  Let's try to salvage
+	    # the situation: Compile a separate program for each library.
+	    for i in $deplibs; do
+	      case $i in
+	      -l*)
+		func_stripname -l '' "$i"
+		name=$func_stripname_result
+		$opt_dry_run || $RM conftest
+		if $LTCC $LTCFLAGS -o conftest conftest.c $i; then
+		  ldd_output=`ldd conftest`
+		  if test yes = "$allow_libtool_libs_with_static_runtimes"; then
+		    case " $predeps $postdeps " in
+		    *" $i "*)
+		      func_append newdeplibs " $i"
+		      i=
+		      ;;
+		    esac
+		  fi
+		  if test -n "$i"; then
+		    libname=`eval "\\$ECHO \"$libname_spec\""`
+		    deplib_matches=`eval "\\$ECHO \"$library_names_spec\""`
+		    set dummy $deplib_matches; shift
+		    deplib_match=$1
+		    if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0; then
+		      func_append newdeplibs " $i"
+		    else
+		      droppeddeps=yes
+		      echo
+		      $ECHO "*** Warning: dynamic linker does not accept needed library $i."
+		      echo "*** I have the capability to make that library automatically link in when"
+		      echo "*** you link to this library.  But I can only do this if you have a"
+		      echo "*** shared version of the library, which you do not appear to have"
+		      echo "*** because a test_compile did reveal that the linker did not use this one"
+		      echo "*** as a dynamic dependency that programs can get resolved with at runtime."
+		    fi
+		  fi
+		else
+		  droppeddeps=yes
+		  echo
+		  $ECHO "*** Warning!  Library $i is needed by this library but I was not able to"
+		  echo "*** make it link in!  You will probably need to install it or some"
+		  echo "*** library that it depends on before this library will be fully"
+		  echo "*** functional.  Installing it before continuing would be even better."
+		fi
+		;;
+	      *)
+		func_append newdeplibs " $i"
+		;;
+	      esac
+	    done
+	  fi
+	  ;;
+	file_magic*)
+	  set dummy $deplibs_check_method; shift
+	  file_magic_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"`
+	  for a_deplib in $deplibs; do
+	    case $a_deplib in
+	    -l*)
+	      func_stripname -l '' "$a_deplib"
+	      name=$func_stripname_result
+	      if test yes = "$allow_libtool_libs_with_static_runtimes"; then
+		case " $predeps $postdeps " in
+		*" $a_deplib "*)
+		  func_append newdeplibs " $a_deplib"
+		  a_deplib=
+		  ;;
+		esac
+	      fi
+	      if test -n "$a_deplib"; then
+		libname=`eval "\\$ECHO \"$libname_spec\""`
+		if test -n "$file_magic_glob"; then
+		  libnameglob=`func_echo_all "$libname" | $SED -e $file_magic_glob`
+		else
+		  libnameglob=$libname
+		fi
+		test yes = "$want_nocaseglob" && nocaseglob=`shopt -p nocaseglob`
+		for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do
+		  if test yes = "$want_nocaseglob"; then
+		    shopt -s nocaseglob
+		    potential_libs=`ls $i/$libnameglob[.-]* 2>/dev/null`
+		    $nocaseglob
+		  else
+		    potential_libs=`ls $i/$libnameglob[.-]* 2>/dev/null`
+		  fi
+		  for potent_lib in $potential_libs; do
+		      # Follow soft links.
+		      if ls -lLd "$potent_lib" 2>/dev/null |
+			 $GREP " -> " >/dev/null; then
+			continue
+		      fi
+		      # The statement above tries to avoid entering an
+		      # endless loop below, in case of cyclic links.
+		      # We might still enter an endless loop, since a link
+		      # loop can be closed while we follow links,
+		      # but so what?
+		      potlib=$potent_lib
+		      while test -h "$potlib" 2>/dev/null; do
+			potliblink=`ls -ld $potlib | $SED 's/.* -> //'`
+			case $potliblink in
+			[\\/]* | [A-Za-z]:[\\/]*) potlib=$potliblink;;
+			*) potlib=`$ECHO "$potlib" | $SED 's|[^/]*$||'`"$potliblink";;
+			esac
+		      done
+		      if eval $file_magic_cmd \"\$potlib\" 2>/dev/null |
+			 $SED -e 10q |
+			 $EGREP "$file_magic_regex" > /dev/null; then
+			func_append newdeplibs " $a_deplib"
+			a_deplib=
+			break 2
+		      fi
+		  done
+		done
+	      fi
+	      if test -n "$a_deplib"; then
+		droppeddeps=yes
+		echo
+		$ECHO "*** Warning: linker path does not have real file for library $a_deplib."
+		echo "*** I have the capability to make that library automatically link in when"
+		echo "*** you link to this library.  But I can only do this if you have a"
+		echo "*** shared version of the library, which you do not appear to have"
+		echo "*** because I did check the linker path looking for a file starting"
+		if test -z "$potlib"; then
+		  $ECHO "*** with $libname but no candidates were found. (...for file magic test)"
+		else
+		  $ECHO "*** with $libname and none of the candidates passed a file format test"
+		  $ECHO "*** using a file magic. Last file checked: $potlib"
+		fi
+	      fi
+	      ;;
+	    *)
+	      # Add a -L argument.
+	      func_append newdeplibs " $a_deplib"
+	      ;;
+	    esac
+	  done # Gone through all deplibs.
+	  ;;
+	match_pattern*)
+	  set dummy $deplibs_check_method; shift
+	  match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"`
+	  for a_deplib in $deplibs; do
+	    case $a_deplib in
+	    -l*)
+	      func_stripname -l '' "$a_deplib"
+	      name=$func_stripname_result
+	      if test yes = "$allow_libtool_libs_with_static_runtimes"; then
+		case " $predeps $postdeps " in
+		*" $a_deplib "*)
+		  func_append newdeplibs " $a_deplib"
+		  a_deplib=
+		  ;;
+		esac
+	      fi
+	      if test -n "$a_deplib"; then
+		libname=`eval "\\$ECHO \"$libname_spec\""`
+		for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do
+		  potential_libs=`ls $i/$libname[.-]* 2>/dev/null`
+		  for potent_lib in $potential_libs; do
+		    potlib=$potent_lib # see symlink-check above in file_magic test
+		    if eval "\$ECHO \"$potent_lib\"" 2>/dev/null | $SED 10q | \
+		       $EGREP "$match_pattern_regex" > /dev/null; then
+		      func_append newdeplibs " $a_deplib"
+		      a_deplib=
+		      break 2
+		    fi
+		  done
+		done
+	      fi
+	      if test -n "$a_deplib"; then
+		droppeddeps=yes
+		echo
+		$ECHO "*** Warning: linker path does not have real file for library $a_deplib."
+		echo "*** I have the capability to make that library automatically link in when"
+		echo "*** you link to this library.  But I can only do this if you have a"
+		echo "*** shared version of the library, which you do not appear to have"
+		echo "*** because I did check the linker path looking for a file starting"
+		if test -z "$potlib"; then
+		  $ECHO "*** with $libname but no candidates were found. (...for regex pattern test)"
+		else
+		  $ECHO "*** with $libname and none of the candidates passed a file format test"
+		  $ECHO "*** using a regex pattern. Last file checked: $potlib"
+		fi
+	      fi
+	      ;;
+	    *)
+	      # Add a -L argument.
+	      func_append newdeplibs " $a_deplib"
+	      ;;
+	    esac
+	  done # Gone through all deplibs.
+	  ;;
+	none | unknown | *)
+	  newdeplibs=
+	  tmp_deplibs=`$ECHO " $deplibs" | $SED 's/ -lc$//; s/ -[LR][^ ]*//g'`
+	  if test yes = "$allow_libtool_libs_with_static_runtimes"; then
+	    for i in $predeps $postdeps; do
+	      # can't use Xsed below, because $i might contain '/'
+	      tmp_deplibs=`$ECHO " $tmp_deplibs" | $SED "s|$i||"`
+	    done
+	  fi
+	  case $tmp_deplibs in
+	  *[!\	\ ]*)
+	    echo
+	    if test none = "$deplibs_check_method"; then
+	      echo "*** Warning: inter-library dependencies are not supported in this platform."
+	    else
+	      echo "*** Warning: inter-library dependencies are not known to be supported."
+	    fi
+	    echo "*** All declared inter-library dependencies are being dropped."
+	    droppeddeps=yes
+	    ;;
+	  esac
+	  ;;
+	esac
+	versuffix=$versuffix_save
+	major=$major_save
+	release=$release_save
+	libname=$libname_save
+	name=$name_save
+
+	case $host in
+	*-*-rhapsody* | *-*-darwin1.[012])
+	  # On Rhapsody replace the C library with the System framework
+	  newdeplibs=`$ECHO " $newdeplibs" | $SED 's/ -lc / System.ltframework /'`
+	  ;;
+	esac
+
+	if test yes = "$droppeddeps"; then
+	  if test yes = "$module"; then
+	    echo
+	    echo "*** Warning: libtool could not satisfy all declared inter-library"
+	    $ECHO "*** dependencies of module $libname.  Therefore, libtool will create"
+	    echo "*** a static module, that should work as long as the dlopening"
+	    echo "*** application is linked with the -dlopen flag."
+	    if test -z "$global_symbol_pipe"; then
+	      echo
+	      echo "*** However, this would only work if libtool was able to extract symbol"
+	      echo "*** lists from a program, using 'nm' or equivalent, but libtool could"
+	      echo "*** not find such a program.  So, this module is probably useless."
+	      echo "*** 'nm' from GNU binutils and a full rebuild may help."
+	    fi
+	    if test no = "$build_old_libs"; then
+	      oldlibs=$output_objdir/$libname.$libext
+	      build_libtool_libs=module
+	      build_old_libs=yes
+	    else
+	      build_libtool_libs=no
+	    fi
+	  else
+	    echo "*** The inter-library dependencies that have been dropped here will be"
+	    echo "*** automatically added whenever a program is linked with this library"
+	    echo "*** or is declared to -dlopen it."
+
+	    if test no = "$allow_undefined"; then
+	      echo
+	      echo "*** Since this library must not contain undefined symbols,"
+	      echo "*** because either the platform does not support them or"
+	      echo "*** it was explicitly requested with -no-undefined,"
+	      echo "*** libtool will only create a static version of it."
+	      if test no = "$build_old_libs"; then
+		oldlibs=$output_objdir/$libname.$libext
+		build_libtool_libs=module
+		build_old_libs=yes
+	      else
+		build_libtool_libs=no
+	      fi
+	    fi
+	  fi
+	fi
+	# Done checking deplibs!
+	deplibs=$newdeplibs
+      fi
+      # Time to change all our "foo.ltframework" stuff back to "-framework foo"
+      case $host in
+	*-*-darwin*)
+	  newdeplibs=`$ECHO " $newdeplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+	  new_inherited_linker_flags=`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+	  deplibs=`$ECHO " $deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+	  ;;
+      esac
+
+      # move library search paths that coincide with paths to not yet
+      # installed libraries to the beginning of the library search list
+      new_libs=
+      for path in $notinst_path; do
+	case " $new_libs " in
+	*" -L$path/$objdir "*) ;;
+	*)
+	  case " $deplibs " in
+	  *" -L$path/$objdir "*)
+	    func_append new_libs " -L$path/$objdir" ;;
+	  esac
+	  ;;
+	esac
+      done
+      for deplib in $deplibs; do
+	case $deplib in
+	-L*)
+	  case " $new_libs " in
+	  *" $deplib "*) ;;
+	  *) func_append new_libs " $deplib" ;;
+	  esac
+	  ;;
+	*) func_append new_libs " $deplib" ;;
+	esac
+      done
+      deplibs=$new_libs
+
+      # All the library-specific variables (install_libdir is set above).
+      library_names=
+      old_library=
+      dlname=
+
+      # Test again, we may have decided not to build it any more
+      if test yes = "$build_libtool_libs"; then
+	# Remove $wl instances when linking with ld.
+	# FIXME: should test the right _cmds variable.
+	case $archive_cmds in
+	  *\$LD\ *) wl= ;;
+        esac
+	if test yes = "$hardcode_into_libs"; then
+	  # Hardcode the library paths
+	  hardcode_libdirs=
+	  dep_rpath=
+	  rpath=$finalize_rpath
+	  test relink = "$opt_mode" || rpath=$compile_rpath$rpath
+	  for libdir in $rpath; do
+	    if test -n "$hardcode_libdir_flag_spec"; then
+	      if test -n "$hardcode_libdir_separator"; then
+		func_replace_sysroot "$libdir"
+		libdir=$func_replace_sysroot_result
+		if test -z "$hardcode_libdirs"; then
+		  hardcode_libdirs=$libdir
+		else
+		  # Just accumulate the unique libdirs.
+		  case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
+		  *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+		    ;;
+		  *)
+		    func_append hardcode_libdirs "$hardcode_libdir_separator$libdir"
+		    ;;
+		  esac
+		fi
+	      else
+		eval flag=\"$hardcode_libdir_flag_spec\"
+		func_append dep_rpath " $flag"
+	      fi
+	    elif test -n "$runpath_var"; then
+	      case "$perm_rpath " in
+	      *" $libdir "*) ;;
+	      *) func_append perm_rpath " $libdir" ;;
+	      esac
+	    fi
+	  done
+	  # Substitute the hardcoded libdirs into the rpath.
+	  if test -n "$hardcode_libdir_separator" &&
+	     test -n "$hardcode_libdirs"; then
+	    libdir=$hardcode_libdirs
+	    eval "dep_rpath=\"$hardcode_libdir_flag_spec\""
+	  fi
+	  if test -n "$runpath_var" && test -n "$perm_rpath"; then
+	    # We should set the runpath_var.
+	    rpath=
+	    for dir in $perm_rpath; do
+	      func_append rpath "$dir:"
+	    done
+	    eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var"
+	  fi
+	  test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs"
+	fi
+
+	shlibpath=$finalize_shlibpath
+	test relink = "$opt_mode" || shlibpath=$compile_shlibpath$shlibpath
+	if test -n "$shlibpath"; then
+	  eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var"
+	fi
+
+	# Get the real and link names of the library.
+	eval shared_ext=\"$shrext_cmds\"
+	eval library_names=\"$library_names_spec\"
+	set dummy $library_names
+	shift
+	realname=$1
+	shift
+
+	if test -n "$soname_spec"; then
+	  eval soname=\"$soname_spec\"
+	else
+	  soname=$realname
+	fi
+	if test -z "$dlname"; then
+	  dlname=$soname
+	fi
+
+	lib=$output_objdir/$realname
+	linknames=
+	for link
+	do
+	  func_append linknames " $link"
+	done
+
+	# Use standard objects if they are pic
+	test -z "$pic_flag" && libobjs=`$ECHO "$libobjs" | $SP2NL | $SED "$lo2o" | $NL2SP`
+	test "X$libobjs" = "X " && libobjs=
+
+	delfiles=
+	if test -n "$export_symbols" && test -n "$include_expsyms"; then
+	  $opt_dry_run || cp "$export_symbols" "$output_objdir/$libname.uexp"
+	  export_symbols=$output_objdir/$libname.uexp
+	  func_append delfiles " $export_symbols"
+	fi
+
+	orig_export_symbols=
+	case $host_os in
+	cygwin* | mingw* | cegcc*)
+	  if test -n "$export_symbols" && test -z "$export_symbols_regex"; then
+	    # exporting using user supplied symfile
+	    func_dll_def_p "$export_symbols" || {
+	      # and it's NOT already a .def file. Must figure out
+	      # which of the given symbols are data symbols and tag
+	      # them as such. So, trigger use of export_symbols_cmds.
+	      # export_symbols gets reassigned inside the "prepare
+	      # the list of exported symbols" if statement, so the
+	      # include_expsyms logic still works.
+	      orig_export_symbols=$export_symbols
+	      export_symbols=
+	      always_export_symbols=yes
+	    }
+	  fi
+	  ;;
+	esac
+
+	# Prepare the list of exported symbols
+	if test -z "$export_symbols"; then
+	  if test yes = "$always_export_symbols" || test -n "$export_symbols_regex"; then
+	    func_verbose "generating symbol list for '$libname.la'"
+	    export_symbols=$output_objdir/$libname.exp
+	    $opt_dry_run || $RM $export_symbols
+	    cmds=$export_symbols_cmds
+	    save_ifs=$IFS; IFS='~'
+	    for cmd1 in $cmds; do
+	      IFS=$save_ifs
+	      # Take the normal branch if the nm_file_list_spec branch
+	      # doesn't work or if tool conversion is not needed.
+	      case $nm_file_list_spec~$to_tool_file_cmd in
+		*~func_convert_file_noop | *~func_convert_file_msys_to_w32 | ~*)
+		  try_normal_branch=yes
+		  eval cmd=\"$cmd1\"
+		  func_len " $cmd"
+		  len=$func_len_result
+		  ;;
+		*)
+		  try_normal_branch=no
+		  ;;
+	      esac
+	      if test yes = "$try_normal_branch" \
+		 && { test "$len" -lt "$max_cmd_len" \
+		      || test "$max_cmd_len" -le -1; }
+	      then
+		func_show_eval "$cmd" 'exit $?'
+		skipped_export=false
+	      elif test -n "$nm_file_list_spec"; then
+		func_basename "$output"
+		output_la=$func_basename_result
+		save_libobjs=$libobjs
+		save_output=$output
+		output=$output_objdir/$output_la.nm
+		func_to_tool_file "$output"
+		libobjs=$nm_file_list_spec$func_to_tool_file_result
+		func_append delfiles " $output"
+		func_verbose "creating $NM input file list: $output"
+		for obj in $save_libobjs; do
+		  func_to_tool_file "$obj"
+		  $ECHO "$func_to_tool_file_result"
+		done > "$output"
+		eval cmd=\"$cmd1\"
+		func_show_eval "$cmd" 'exit $?'
+		output=$save_output
+		libobjs=$save_libobjs
+		skipped_export=false
+	      else
+		# The command line is too long to execute in one step.
+		func_verbose "using reloadable object file for export list..."
+		skipped_export=:
+		# Break out early, otherwise skipped_export may be
+		# set to false by a later but shorter cmd.
+		break
+	      fi
+	    done
+	    IFS=$save_ifs
+	    if test -n "$export_symbols_regex" && test : != "$skipped_export"; then
+	      func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"'
+	      func_show_eval '$MV "${export_symbols}T" "$export_symbols"'
+	    fi
+	  fi
+	fi
+
+	if test -n "$export_symbols" && test -n "$include_expsyms"; then
+	  tmp_export_symbols=$export_symbols
+	  test -n "$orig_export_symbols" && tmp_export_symbols=$orig_export_symbols
+	  $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"'
+	fi
+
+	if test : != "$skipped_export" && test -n "$orig_export_symbols"; then
+	  # The given exports_symbols file has to be filtered, so filter it.
+	  func_verbose "filter symbol list for '$libname.la' to tag DATA exports"
+	  # FIXME: $output_objdir/$libname.filter potentially contains lots of
+	  # 's' commands, which not all seds can handle. GNU sed should be fine
+	  # though. Also, the filter scales superlinearly with the number of
+	  # global variables. join(1) would be nice here, but unfortunately
+	  # isn't a blessed tool.
+	  $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter
+	  func_append delfiles " $export_symbols $output_objdir/$libname.filter"
+	  export_symbols=$output_objdir/$libname.def
+	  $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols
+	fi
+
+	tmp_deplibs=
+	for test_deplib in $deplibs; do
+	  case " $convenience " in
+	  *" $test_deplib "*) ;;
+	  *)
+	    func_append tmp_deplibs " $test_deplib"
+	    ;;
+	  esac
+	done
+	deplibs=$tmp_deplibs
+
+	if test -n "$convenience"; then
+	  if test -n "$whole_archive_flag_spec" &&
+	    test yes = "$compiler_needs_object" &&
+	    test -z "$libobjs"; then
+	    # extract the archives, so we have objects to list.
+	    # TODO: could optimize this to just extract one archive.
+	    whole_archive_flag_spec=
+	  fi
+	  if test -n "$whole_archive_flag_spec"; then
+	    save_libobjs=$libobjs
+	    eval libobjs=\"\$libobjs $whole_archive_flag_spec\"
+	    test "X$libobjs" = "X " && libobjs=
+	  else
+	    gentop=$output_objdir/${outputname}x
+	    func_append generated " $gentop"
+
+	    func_extract_archives $gentop $convenience
+	    func_append libobjs " $func_extract_archives_result"
+	    test "X$libobjs" = "X " && libobjs=
+	  fi
+	fi
+
+	if test yes = "$thread_safe" && test -n "$thread_safe_flag_spec"; then
+	  eval flag=\"$thread_safe_flag_spec\"
+	  func_append linker_flags " $flag"
+	fi
+
+	# Make a backup of the uninstalled library when relinking
+	if test relink = "$opt_mode"; then
+	  $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}U && $MV $realname ${realname}U)' || exit $?
+	fi
+
+	# Do each of the archive commands.
+	if test yes = "$module" && test -n "$module_cmds"; then
+	  if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then
+	    eval test_cmds=\"$module_expsym_cmds\"
+	    cmds=$module_expsym_cmds
+	  else
+	    eval test_cmds=\"$module_cmds\"
+	    cmds=$module_cmds
+	  fi
+	else
+	  if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then
+	    eval test_cmds=\"$archive_expsym_cmds\"
+	    cmds=$archive_expsym_cmds
+	  else
+	    eval test_cmds=\"$archive_cmds\"
+	    cmds=$archive_cmds
+	  fi
+	fi
+
+	if test : != "$skipped_export" &&
+	   func_len " $test_cmds" &&
+	   len=$func_len_result &&
+	   test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then
+	  :
+	else
+	  # The command line is too long to link in one step, link piecewise
+	  # or, if using GNU ld and skipped_export is not :, use a linker
+	  # script.
+
+	  # Save the value of $output and $libobjs because we want to
+	  # use them later.  If we have whole_archive_flag_spec, we
+	  # want to use save_libobjs as it was before
+	  # whole_archive_flag_spec was expanded, because we can't
+	  # assume the linker understands whole_archive_flag_spec.
+	  # This may have to be revisited, in case too many
+	  # convenience libraries get linked in and end up exceeding
+	  # the spec.
+	  if test -z "$convenience" || test -z "$whole_archive_flag_spec"; then
+	    save_libobjs=$libobjs
+	  fi
+	  save_output=$output
+	  func_basename "$output"
+	  output_la=$func_basename_result
+
+	  # Clear the reloadable object creation command queue and
+	  # initialize k to one.
+	  test_cmds=
+	  concat_cmds=
+	  objlist=
+	  last_robj=
+	  k=1
+
+	  if test -n "$save_libobjs" && test : != "$skipped_export" && test yes = "$with_gnu_ld"; then
+	    output=$output_objdir/$output_la.lnkscript
+	    func_verbose "creating GNU ld script: $output"
+	    echo 'INPUT (' > $output
+	    for obj in $save_libobjs
+	    do
+	      func_to_tool_file "$obj"
+	      $ECHO "$func_to_tool_file_result" >> $output
+	    done
+	    echo ')' >> $output
+	    func_append delfiles " $output"
+	    func_to_tool_file "$output"
+	    output=$func_to_tool_file_result
+	  elif test -n "$save_libobjs" && test : != "$skipped_export" && test -n "$file_list_spec"; then
+	    output=$output_objdir/$output_la.lnk
+	    func_verbose "creating linker input file list: $output"
+	    : > $output
+	    set x $save_libobjs
+	    shift
+	    firstobj=
+	    if test yes = "$compiler_needs_object"; then
+	      firstobj="$1 "
+	      shift
+	    fi
+	    for obj
+	    do
+	      func_to_tool_file "$obj"
+	      $ECHO "$func_to_tool_file_result" >> $output
+	    done
+	    func_append delfiles " $output"
+	    func_to_tool_file "$output"
+	    output=$firstobj\"$file_list_spec$func_to_tool_file_result\"
+	  else
+	    if test -n "$save_libobjs"; then
+	      func_verbose "creating reloadable object files..."
+	      output=$output_objdir/$output_la-$k.$objext
+	      eval test_cmds=\"$reload_cmds\"
+	      func_len " $test_cmds"
+	      len0=$func_len_result
+	      len=$len0
+
+	      # Loop over the list of objects to be linked.
+	      for obj in $save_libobjs
+	      do
+		func_len " $obj"
+		func_arith $len + $func_len_result
+		len=$func_arith_result
+		if test -z "$objlist" ||
+		   test "$len" -lt "$max_cmd_len"; then
+		  func_append objlist " $obj"
+		else
+		  # The command $test_cmds is almost too long, add a
+		  # command to the queue.
+		  if test 1 -eq "$k"; then
+		    # The first file doesn't have a previous command to add.
+		    reload_objs=$objlist
+		    eval concat_cmds=\"$reload_cmds\"
+		  else
+		    # All subsequent reloadable object files will link in
+		    # the last one created.
+		    reload_objs="$objlist $last_robj"
+		    eval concat_cmds=\"\$concat_cmds~$reload_cmds~\$RM $last_robj\"
+		  fi
+		  last_robj=$output_objdir/$output_la-$k.$objext
+		  func_arith $k + 1
+		  k=$func_arith_result
+		  output=$output_objdir/$output_la-$k.$objext
+		  objlist=" $obj"
+		  func_len " $last_robj"
+		  func_arith $len0 + $func_len_result
+		  len=$func_arith_result
+		fi
+	      done
+	      # Handle the remaining objects by creating one last
+	      # reloadable object file.  All subsequent reloadable object
+	      # files will link in the last one created.
+	      test -z "$concat_cmds" || concat_cmds=$concat_cmds~
+	      reload_objs="$objlist $last_robj"
+	      eval concat_cmds=\"\$concat_cmds$reload_cmds\"
+	      if test -n "$last_robj"; then
+	        eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\"
+	      fi
+	      func_append delfiles " $output"
+
+	    else
+	      output=
+	    fi
+
+	    ${skipped_export-false} && {
+	      func_verbose "generating symbol list for '$libname.la'"
+	      export_symbols=$output_objdir/$libname.exp
+	      $opt_dry_run || $RM $export_symbols
+	      libobjs=$output
+	      # Append the command to create the export file.
+	      test -z "$concat_cmds" || concat_cmds=$concat_cmds~
+	      eval concat_cmds=\"\$concat_cmds$export_symbols_cmds\"
+	      if test -n "$last_robj"; then
+		eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\"
+	      fi
+	    }
+
+	    test -n "$save_libobjs" &&
+	      func_verbose "creating a temporary reloadable object file: $output"
+
+	    # Loop through the commands generated above and execute them.
+	    save_ifs=$IFS; IFS='~'
+	    for cmd in $concat_cmds; do
+	      IFS=$save_ifs
+	      $opt_quiet || {
+		  func_quote_for_expand "$cmd"
+		  eval "func_echo $func_quote_for_expand_result"
+	      }
+	      $opt_dry_run || eval "$cmd" || {
+		lt_exit=$?
+
+		# Restore the uninstalled library and exit
+		if test relink = "$opt_mode"; then
+		  ( cd "$output_objdir" && \
+		    $RM "${realname}T" && \
+		    $MV "${realname}U" "$realname" )
+		fi
+
+		exit $lt_exit
+	      }
+	    done
+	    IFS=$save_ifs
+
+	    if test -n "$export_symbols_regex" && ${skipped_export-false}; then
+	      func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"'
+	      func_show_eval '$MV "${export_symbols}T" "$export_symbols"'
+	    fi
+	  fi
+
+          ${skipped_export-false} && {
+	    if test -n "$export_symbols" && test -n "$include_expsyms"; then
+	      tmp_export_symbols=$export_symbols
+	      test -n "$orig_export_symbols" && tmp_export_symbols=$orig_export_symbols
+	      $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"'
+	    fi
+
+	    if test -n "$orig_export_symbols"; then
+	      # The given exports_symbols file has to be filtered, so filter it.
+	      func_verbose "filter symbol list for '$libname.la' to tag DATA exports"
+	      # FIXME: $output_objdir/$libname.filter potentially contains lots of
+	      # 's' commands, which not all seds can handle. GNU sed should be fine
+	      # though. Also, the filter scales superlinearly with the number of
+	      # global variables. join(1) would be nice here, but unfortunately
+	      # isn't a blessed tool.
+	      $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter
+	      func_append delfiles " $export_symbols $output_objdir/$libname.filter"
+	      export_symbols=$output_objdir/$libname.def
+	      $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols
+	    fi
+	  }
+
+	  libobjs=$output
+	  # Restore the value of output.
+	  output=$save_output
+
+	  if test -n "$convenience" && test -n "$whole_archive_flag_spec"; then
+	    eval libobjs=\"\$libobjs $whole_archive_flag_spec\"
+	    test "X$libobjs" = "X " && libobjs=
+	  fi
+	  # Expand the library linking commands again to reset the
+	  # value of $libobjs for piecewise linking.
+
+	  # Do each of the archive commands.
+	  if test yes = "$module" && test -n "$module_cmds"; then
+	    if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then
+	      cmds=$module_expsym_cmds
+	    else
+	      cmds=$module_cmds
+	    fi
+	  else
+	    if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then
+	      cmds=$archive_expsym_cmds
+	    else
+	      cmds=$archive_cmds
+	    fi
+	  fi
+	fi
+
+	if test -n "$delfiles"; then
+	  # Append the command to remove temporary files to $cmds.
+	  eval cmds=\"\$cmds~\$RM $delfiles\"
+	fi
+
+	# Add any objects from preloaded convenience libraries
+	if test -n "$dlprefiles"; then
+	  gentop=$output_objdir/${outputname}x
+	  func_append generated " $gentop"
+
+	  func_extract_archives $gentop $dlprefiles
+	  func_append libobjs " $func_extract_archives_result"
+	  test "X$libobjs" = "X " && libobjs=
+	fi
+
+	save_ifs=$IFS; IFS='~'
+	for cmd in $cmds; do
+	  IFS=$sp$nl
+	  eval cmd=\"$cmd\"
+	  IFS=$save_ifs
+	  $opt_quiet || {
+	    func_quote_for_expand "$cmd"
+	    eval "func_echo $func_quote_for_expand_result"
+	  }
+	  $opt_dry_run || eval "$cmd" || {
+	    lt_exit=$?
+
+	    # Restore the uninstalled library and exit
+	    if test relink = "$opt_mode"; then
+	      ( cd "$output_objdir" && \
+	        $RM "${realname}T" && \
+		$MV "${realname}U" "$realname" )
+	    fi
+
+	    exit $lt_exit
+	  }
+	done
+	IFS=$save_ifs
+
+	# Restore the uninstalled library and exit
+	if test relink = "$opt_mode"; then
+	  $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}T && $MV $realname ${realname}T && $MV ${realname}U $realname)' || exit $?
+
+	  if test -n "$convenience"; then
+	    if test -z "$whole_archive_flag_spec"; then
+	      func_show_eval '${RM}r "$gentop"'
+	    fi
+	  fi
+
+	  exit $EXIT_SUCCESS
+	fi
+
+	# Create links to the real library.
+	for linkname in $linknames; do
+	  if test "$realname" != "$linkname"; then
+	    func_show_eval '(cd "$output_objdir" && $RM "$linkname" && $LN_S "$realname" "$linkname")' 'exit $?'
+	  fi
+	done
+
+	# If -module or -export-dynamic was specified, set the dlname.
+	if test yes = "$module" || test yes = "$export_dynamic"; then
+	  # On all known operating systems, these are identical.
+	  dlname=$soname
+	fi
+      fi
+      ;;
+
+    obj)
+      if test -n "$dlfiles$dlprefiles" || test no != "$dlself"; then
+	func_warning "'-dlopen' is ignored for objects"
+      fi
+
+      case " $deplibs" in
+      *\ -l* | *\ -L*)
+	func_warning "'-l' and '-L' are ignored for objects" ;;
+      esac
+
+      test -n "$rpath" && \
+	func_warning "'-rpath' is ignored for objects"
+
+      test -n "$xrpath" && \
+	func_warning "'-R' is ignored for objects"
+
+      test -n "$vinfo" && \
+	func_warning "'-version-info' is ignored for objects"
+
+      test -n "$release" && \
+	func_warning "'-release' is ignored for objects"
+
+      case $output in
+      *.lo)
+	test -n "$objs$old_deplibs" && \
+	  func_fatal_error "cannot build library object '$output' from non-libtool objects"
+
+	libobj=$output
+	func_lo2o "$libobj"
+	obj=$func_lo2o_result
+	;;
+      *)
+	libobj=
+	obj=$output
+	;;
+      esac
+
+      # Delete the old objects.
+      $opt_dry_run || $RM $obj $libobj
+
+      # Objects from convenience libraries.  This assumes
+      # single-version convenience libraries.  Whenever we create
+      # different ones for PIC/non-PIC, this we'll have to duplicate
+      # the extraction.
+      reload_conv_objs=
+      gentop=
+      # if reload_cmds runs $LD directly, get rid of -Wl from
+      # whole_archive_flag_spec and hope we can get by with turning comma
+      # into space.
+      case $reload_cmds in
+        *\$LD[\ \$]*) wl= ;;
+      esac
+      if test -n "$convenience"; then
+	if test -n "$whole_archive_flag_spec"; then
+	  eval tmp_whole_archive_flags=\"$whole_archive_flag_spec\"
+	  test -n "$wl" || tmp_whole_archive_flags=`$ECHO "$tmp_whole_archive_flags" | $SED 's|,| |g'`
+	  reload_conv_objs=$reload_objs\ $tmp_whole_archive_flags
+	else
+	  gentop=$output_objdir/${obj}x
+	  func_append generated " $gentop"
+
+	  func_extract_archives $gentop $convenience
+	  reload_conv_objs="$reload_objs $func_extract_archives_result"
+	fi
+      fi
+
+      # If we're not building shared, we need to use non_pic_objs
+      test yes = "$build_libtool_libs" || libobjs=$non_pic_objects
+
+      # Create the old-style object.
+      reload_objs=$objs$old_deplibs' '`$ECHO "$libobjs" | $SP2NL | $SED "/\.$libext$/d; /\.lib$/d; $lo2o" | $NL2SP`' '$reload_conv_objs
+
+      output=$obj
+      func_execute_cmds "$reload_cmds" 'exit $?'
+
+      # Exit if we aren't doing a library object file.
+      if test -z "$libobj"; then
+	if test -n "$gentop"; then
+	  func_show_eval '${RM}r "$gentop"'
+	fi
+
+	exit $EXIT_SUCCESS
+      fi
+
+      test yes = "$build_libtool_libs" || {
+	if test -n "$gentop"; then
+	  func_show_eval '${RM}r "$gentop"'
+	fi
+
+	# Create an invalid libtool object if no PIC, so that we don't
+	# accidentally link it into a program.
+	# $show "echo timestamp > $libobj"
+	# $opt_dry_run || eval "echo timestamp > $libobj" || exit $?
+	exit $EXIT_SUCCESS
+      }
+
+      if test -n "$pic_flag" || test default != "$pic_mode"; then
+	# Only do commands if we really have different PIC objects.
+	reload_objs="$libobjs $reload_conv_objs"
+	output=$libobj
+	func_execute_cmds "$reload_cmds" 'exit $?'
+      fi
+
+      if test -n "$gentop"; then
+	func_show_eval '${RM}r "$gentop"'
+      fi
+
+      exit $EXIT_SUCCESS
+      ;;
+
+    prog)
+      case $host in
+	*cygwin*) func_stripname '' '.exe' "$output"
+	          output=$func_stripname_result.exe;;
+      esac
+      test -n "$vinfo" && \
+	func_warning "'-version-info' is ignored for programs"
+
+      test -n "$release" && \
+	func_warning "'-release' is ignored for programs"
+
+      $preload \
+	&& test unknown,unknown,unknown = "$dlopen_support,$dlopen_self,$dlopen_self_static" \
+	&& func_warning "'LT_INIT([dlopen])' not used. Assuming no dlopen support."
+
+      case $host in
+      *-*-rhapsody* | *-*-darwin1.[012])
+	# On Rhapsody replace the C library is the System framework
+	compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's/ -lc / System.ltframework /'`
+	finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's/ -lc / System.ltframework /'`
+	;;
+      esac
+
+      case $host in
+      *-*-darwin*)
+	# Don't allow lazy linking, it breaks C++ global constructors
+	# But is supposedly fixed on 10.4 or later (yay!).
+	if test CXX = "$tagname"; then
+	  case ${MACOSX_DEPLOYMENT_TARGET-10.0} in
+	    10.[0123])
+	      func_append compile_command " $wl-bind_at_load"
+	      func_append finalize_command " $wl-bind_at_load"
+	    ;;
+	  esac
+	fi
+	# Time to change all our "foo.ltframework" stuff back to "-framework foo"
+	compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+	finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+	;;
+      esac
+
+
+      # move library search paths that coincide with paths to not yet
+      # installed libraries to the beginning of the library search list
+      new_libs=
+      for path in $notinst_path; do
+	case " $new_libs " in
+	*" -L$path/$objdir "*) ;;
+	*)
+	  case " $compile_deplibs " in
+	  *" -L$path/$objdir "*)
+	    func_append new_libs " -L$path/$objdir" ;;
+	  esac
+	  ;;
+	esac
+      done
+      for deplib in $compile_deplibs; do
+	case $deplib in
+	-L*)
+	  case " $new_libs " in
+	  *" $deplib "*) ;;
+	  *) func_append new_libs " $deplib" ;;
+	  esac
+	  ;;
+	*) func_append new_libs " $deplib" ;;
+	esac
+      done
+      compile_deplibs=$new_libs
+
+
+      func_append compile_command " $compile_deplibs"
+      func_append finalize_command " $finalize_deplibs"
+
+      if test -n "$rpath$xrpath"; then
+	# If the user specified any rpath flags, then add them.
+	for libdir in $rpath $xrpath; do
+	  # This is the magic to use -rpath.
+	  case "$finalize_rpath " in
+	  *" $libdir "*) ;;
+	  *) func_append finalize_rpath " $libdir" ;;
+	  esac
+	done
+      fi
+
+      # Now hardcode the library paths
+      rpath=
+      hardcode_libdirs=
+      for libdir in $compile_rpath $finalize_rpath; do
+	if test -n "$hardcode_libdir_flag_spec"; then
+	  if test -n "$hardcode_libdir_separator"; then
+	    if test -z "$hardcode_libdirs"; then
+	      hardcode_libdirs=$libdir
+	    else
+	      # Just accumulate the unique libdirs.
+	      case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
+	      *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+		;;
+	      *)
+		func_append hardcode_libdirs "$hardcode_libdir_separator$libdir"
+		;;
+	      esac
+	    fi
+	  else
+	    eval flag=\"$hardcode_libdir_flag_spec\"
+	    func_append rpath " $flag"
+	  fi
+	elif test -n "$runpath_var"; then
+	  case "$perm_rpath " in
+	  *" $libdir "*) ;;
+	  *) func_append perm_rpath " $libdir" ;;
+	  esac
+	fi
+	case $host in
+	*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*)
+	  testbindir=`$ECHO "$libdir" | $SED -e 's*/lib$*/bin*'`
+	  case :$dllsearchpath: in
+	  *":$libdir:"*) ;;
+	  ::) dllsearchpath=$libdir;;
+	  *) func_append dllsearchpath ":$libdir";;
+	  esac
+	  case :$dllsearchpath: in
+	  *":$testbindir:"*) ;;
+	  ::) dllsearchpath=$testbindir;;
+	  *) func_append dllsearchpath ":$testbindir";;
+	  esac
+	  ;;
+	esac
+      done
+      # Substitute the hardcoded libdirs into the rpath.
+      if test -n "$hardcode_libdir_separator" &&
+	 test -n "$hardcode_libdirs"; then
+	libdir=$hardcode_libdirs
+	eval rpath=\" $hardcode_libdir_flag_spec\"
+      fi
+      compile_rpath=$rpath
+
+      rpath=
+      hardcode_libdirs=
+      for libdir in $finalize_rpath; do
+	if test -n "$hardcode_libdir_flag_spec"; then
+	  if test -n "$hardcode_libdir_separator"; then
+	    if test -z "$hardcode_libdirs"; then
+	      hardcode_libdirs=$libdir
+	    else
+	      # Just accumulate the unique libdirs.
+	      case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
+	      *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+		;;
+	      *)
+		func_append hardcode_libdirs "$hardcode_libdir_separator$libdir"
+		;;
+	      esac
+	    fi
+	  else
+	    eval flag=\"$hardcode_libdir_flag_spec\"
+	    func_append rpath " $flag"
+	  fi
+	elif test -n "$runpath_var"; then
+	  case "$finalize_perm_rpath " in
+	  *" $libdir "*) ;;
+	  *) func_append finalize_perm_rpath " $libdir" ;;
+	  esac
+	fi
+      done
+      # Substitute the hardcoded libdirs into the rpath.
+      if test -n "$hardcode_libdir_separator" &&
+	 test -n "$hardcode_libdirs"; then
+	libdir=$hardcode_libdirs
+	eval rpath=\" $hardcode_libdir_flag_spec\"
+      fi
+      finalize_rpath=$rpath
+
+      if test -n "$libobjs" && test yes = "$build_old_libs"; then
+	# Transform all the library objects into standard objects.
+	compile_command=`$ECHO "$compile_command" | $SP2NL | $SED "$lo2o" | $NL2SP`
+	finalize_command=`$ECHO "$finalize_command" | $SP2NL | $SED "$lo2o" | $NL2SP`
+      fi
+
+      func_generate_dlsyms "$outputname" "@PROGRAM@" false
+
+      # template prelinking step
+      if test -n "$prelink_cmds"; then
+	func_execute_cmds "$prelink_cmds" 'exit $?'
+      fi
+
+      wrappers_required=:
+      case $host in
+      *cegcc* | *mingw32ce*)
+        # Disable wrappers for cegcc and mingw32ce hosts, we are cross compiling anyway.
+        wrappers_required=false
+        ;;
+      *cygwin* | *mingw* )
+        test yes = "$build_libtool_libs" || wrappers_required=false
+        ;;
+      *)
+        if test no = "$need_relink" || test yes != "$build_libtool_libs"; then
+          wrappers_required=false
+        fi
+        ;;
+      esac
+      $wrappers_required || {
+	# Replace the output file specification.
+	compile_command=`$ECHO "$compile_command" | $SED 's%@OUTPUT@%'"$output"'%g'`
+	link_command=$compile_command$compile_rpath
+
+	# We have no uninstalled library dependencies, so finalize right now.
+	exit_status=0
+	func_show_eval "$link_command" 'exit_status=$?'
+
+	if test -n "$postlink_cmds"; then
+	  func_to_tool_file "$output"
+	  postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'`
+	  func_execute_cmds "$postlink_cmds" 'exit $?'
+	fi
+
+	# Delete the generated files.
+	if test -f "$output_objdir/${outputname}S.$objext"; then
+	  func_show_eval '$RM "$output_objdir/${outputname}S.$objext"'
+	fi
+
+	exit $exit_status
+      }
+
+      if test -n "$compile_shlibpath$finalize_shlibpath"; then
+	compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command"
+      fi
+      if test -n "$finalize_shlibpath"; then
+	finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command"
+      fi
+
+      compile_var=
+      finalize_var=
+      if test -n "$runpath_var"; then
+	if test -n "$perm_rpath"; then
+	  # We should set the runpath_var.
+	  rpath=
+	  for dir in $perm_rpath; do
+	    func_append rpath "$dir:"
+	  done
+	  compile_var="$runpath_var=\"$rpath\$$runpath_var\" "
+	fi
+	if test -n "$finalize_perm_rpath"; then
+	  # We should set the runpath_var.
+	  rpath=
+	  for dir in $finalize_perm_rpath; do
+	    func_append rpath "$dir:"
+	  done
+	  finalize_var="$runpath_var=\"$rpath\$$runpath_var\" "
+	fi
+      fi
+
+      if test yes = "$no_install"; then
+	# We don't need to create a wrapper script.
+	link_command=$compile_var$compile_command$compile_rpath
+	# Replace the output file specification.
+	link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output"'%g'`
+	# Delete the old output file.
+	$opt_dry_run || $RM $output
+	# Link the executable and exit
+	func_show_eval "$link_command" 'exit $?'
+
+	if test -n "$postlink_cmds"; then
+	  func_to_tool_file "$output"
+	  postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'`
+	  func_execute_cmds "$postlink_cmds" 'exit $?'
+	fi
+
+	exit $EXIT_SUCCESS
+      fi
+
+      case $hardcode_action,$fast_install in
+        relink,*)
+	  # Fast installation is not supported
+	  link_command=$compile_var$compile_command$compile_rpath
+	  relink_command=$finalize_var$finalize_command$finalize_rpath
+
+	  func_warning "this platform does not like uninstalled shared libraries"
+	  func_warning "'$output' will be relinked during installation"
+	  ;;
+        *,yes)
+	  link_command=$finalize_var$compile_command$finalize_rpath
+	  relink_command=`$ECHO "$compile_var$compile_command$compile_rpath" | $SED 's%@OUTPUT@%\$progdir/\$file%g'`
+          ;;
+	*,no)
+	  link_command=$compile_var$compile_command$compile_rpath
+	  relink_command=$finalize_var$finalize_command$finalize_rpath
+          ;;
+	*,needless)
+	  link_command=$finalize_var$compile_command$finalize_rpath
+	  relink_command=
+          ;;
+      esac
+
+      # Replace the output file specification.
+      link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'`
+
+      # Delete the old output files.
+      $opt_dry_run || $RM $output $output_objdir/$outputname $output_objdir/lt-$outputname
+
+      func_show_eval "$link_command" 'exit $?'
+
+      if test -n "$postlink_cmds"; then
+	func_to_tool_file "$output_objdir/$outputname"
+	postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'`
+	func_execute_cmds "$postlink_cmds" 'exit $?'
+      fi
+
+      # Now create the wrapper script.
+      func_verbose "creating $output"
+
+      # Quote the relink command for shipping.
+      if test -n "$relink_command"; then
+	# Preserve any variables that may affect compiler behavior
+	for var in $variables_saved_for_relink; do
+	  if eval test -z \"\${$var+set}\"; then
+	    relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command"
+	  elif eval var_value=\$$var; test -z "$var_value"; then
+	    relink_command="$var=; export $var; $relink_command"
+	  else
+	    func_quote_for_eval "$var_value"
+	    relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command"
+	  fi
+	done
+	relink_command="(cd `pwd`; $relink_command)"
+	relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"`
+      fi
+
+      # Only actually do things if not in dry run mode.
+      $opt_dry_run || {
+	# win32 will think the script is a binary if it has
+	# a .exe suffix, so we strip it off here.
+	case $output in
+	  *.exe) func_stripname '' '.exe' "$output"
+	         output=$func_stripname_result ;;
+	esac
+	# test for cygwin because mv fails w/o .exe extensions
+	case $host in
+	  *cygwin*)
+	    exeext=.exe
+	    func_stripname '' '.exe' "$outputname"
+	    outputname=$func_stripname_result ;;
+	  *) exeext= ;;
+	esac
+	case $host in
+	  *cygwin* | *mingw* )
+	    func_dirname_and_basename "$output" "" "."
+	    output_name=$func_basename_result
+	    output_path=$func_dirname_result
+	    cwrappersource=$output_path/$objdir/lt-$output_name.c
+	    cwrapper=$output_path/$output_name.exe
+	    $RM $cwrappersource $cwrapper
+	    trap "$RM $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15
+
+	    func_emit_cwrapperexe_src > $cwrappersource
+
+	    # The wrapper executable is built using the $host compiler,
+	    # because it contains $host paths and files. If cross-
+	    # compiling, it, like the target executable, must be
+	    # executed on the $host or under an emulation environment.
+	    $opt_dry_run || {
+	      $LTCC $LTCFLAGS -o $cwrapper $cwrappersource
+	      $STRIP $cwrapper
+	    }
+
+	    # Now, create the wrapper script for func_source use:
+	    func_ltwrapper_scriptname $cwrapper
+	    $RM $func_ltwrapper_scriptname_result
+	    trap "$RM $func_ltwrapper_scriptname_result; exit $EXIT_FAILURE" 1 2 15
+	    $opt_dry_run || {
+	      # note: this script will not be executed, so do not chmod.
+	      if test "x$build" = "x$host"; then
+		$cwrapper --lt-dump-script > $func_ltwrapper_scriptname_result
+	      else
+		func_emit_wrapper no > $func_ltwrapper_scriptname_result
+	      fi
+	    }
+	  ;;
+	  * )
+	    $RM $output
+	    trap "$RM $output; exit $EXIT_FAILURE" 1 2 15
+
+	    func_emit_wrapper no > $output
+	    chmod +x $output
+	  ;;
+	esac
+      }
+      exit $EXIT_SUCCESS
+      ;;
+    esac
+
+    # See if we need to build an old-fashioned archive.
+    for oldlib in $oldlibs; do
+
+      case $build_libtool_libs in
+        convenience)
+	  oldobjs="$libobjs_save $symfileobj"
+	  addlibs=$convenience
+	  build_libtool_libs=no
+	  ;;
+	module)
+	  oldobjs=$libobjs_save
+	  addlibs=$old_convenience
+	  build_libtool_libs=no
+          ;;
+	*)
+	  oldobjs="$old_deplibs $non_pic_objects"
+	  $preload && test -f "$symfileobj" \
+	    && func_append oldobjs " $symfileobj"
+	  addlibs=$old_convenience
+	  ;;
+      esac
+
+      if test -n "$addlibs"; then
+	gentop=$output_objdir/${outputname}x
+	func_append generated " $gentop"
+
+	func_extract_archives $gentop $addlibs
+	func_append oldobjs " $func_extract_archives_result"
+      fi
+
+      # Do each command in the archive commands.
+      if test -n "$old_archive_from_new_cmds" && test yes = "$build_libtool_libs"; then
+	cmds=$old_archive_from_new_cmds
+      else
+
+	# Add any objects from preloaded convenience libraries
+	if test -n "$dlprefiles"; then
+	  gentop=$output_objdir/${outputname}x
+	  func_append generated " $gentop"
+
+	  func_extract_archives $gentop $dlprefiles
+	  func_append oldobjs " $func_extract_archives_result"
+	fi
+
+	# POSIX demands no paths to be encoded in archives.  We have
+	# to avoid creating archives with duplicate basenames if we
+	# might have to extract them afterwards, e.g., when creating a
+	# static archive out of a convenience library, or when linking
+	# the entirety of a libtool archive into another (currently
+	# not supported by libtool).
+	if (for obj in $oldobjs
+	    do
+	      func_basename "$obj"
+	      $ECHO "$func_basename_result"
+	    done | sort | sort -uc >/dev/null 2>&1); then
+	  :
+	else
+	  echo "copying selected object files to avoid basename conflicts..."
+	  gentop=$output_objdir/${outputname}x
+	  func_append generated " $gentop"
+	  func_mkdir_p "$gentop"
+	  save_oldobjs=$oldobjs
+	  oldobjs=
+	  counter=1
+	  for obj in $save_oldobjs
+	  do
+	    func_basename "$obj"
+	    objbase=$func_basename_result
+	    case " $oldobjs " in
+	    " ") oldobjs=$obj ;;
+	    *[\ /]"$objbase "*)
+	      while :; do
+		# Make sure we don't pick an alternate name that also
+		# overlaps.
+		newobj=lt$counter-$objbase
+		func_arith $counter + 1
+		counter=$func_arith_result
+		case " $oldobjs " in
+		*[\ /]"$newobj "*) ;;
+		*) if test ! -f "$gentop/$newobj"; then break; fi ;;
+		esac
+	      done
+	      func_show_eval "ln $obj $gentop/$newobj || cp $obj $gentop/$newobj"
+	      func_append oldobjs " $gentop/$newobj"
+	      ;;
+	    *) func_append oldobjs " $obj" ;;
+	    esac
+	  done
+	fi
+	func_to_tool_file "$oldlib" func_convert_file_msys_to_w32
+	tool_oldlib=$func_to_tool_file_result
+	eval cmds=\"$old_archive_cmds\"
+
+	func_len " $cmds"
+	len=$func_len_result
+	if test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then
+	  cmds=$old_archive_cmds
+	elif test -n "$archiver_list_spec"; then
+	  func_verbose "using command file archive linking..."
+	  for obj in $oldobjs
+	  do
+	    func_to_tool_file "$obj"
+	    $ECHO "$func_to_tool_file_result"
+	  done > $output_objdir/$libname.libcmd
+	  func_to_tool_file "$output_objdir/$libname.libcmd"
+	  oldobjs=" $archiver_list_spec$func_to_tool_file_result"
+	  cmds=$old_archive_cmds
+	else
+	  # the command line is too long to link in one step, link in parts
+	  func_verbose "using piecewise archive linking..."
+	  save_RANLIB=$RANLIB
+	  RANLIB=:
+	  objlist=
+	  concat_cmds=
+	  save_oldobjs=$oldobjs
+	  oldobjs=
+	  # Is there a better way of finding the last object in the list?
+	  for obj in $save_oldobjs
+	  do
+	    last_oldobj=$obj
+	  done
+	  eval test_cmds=\"$old_archive_cmds\"
+	  func_len " $test_cmds"
+	  len0=$func_len_result
+	  len=$len0
+	  for obj in $save_oldobjs
+	  do
+	    func_len " $obj"
+	    func_arith $len + $func_len_result
+	    len=$func_arith_result
+	    func_append objlist " $obj"
+	    if test "$len" -lt "$max_cmd_len"; then
+	      :
+	    else
+	      # the above command should be used before it gets too long
+	      oldobjs=$objlist
+	      if test "$obj" = "$last_oldobj"; then
+		RANLIB=$save_RANLIB
+	      fi
+	      test -z "$concat_cmds" || concat_cmds=$concat_cmds~
+	      eval concat_cmds=\"\$concat_cmds$old_archive_cmds\"
+	      objlist=
+	      len=$len0
+	    fi
+	  done
+	  RANLIB=$save_RANLIB
+	  oldobjs=$objlist
+	  if test -z "$oldobjs"; then
+	    eval cmds=\"\$concat_cmds\"
+	  else
+	    eval cmds=\"\$concat_cmds~\$old_archive_cmds\"
+	  fi
+	fi
+      fi
+      func_execute_cmds "$cmds" 'exit $?'
+    done
+
+    test -n "$generated" && \
+      func_show_eval "${RM}r$generated"
+
+    # Now create the libtool archive.
+    case $output in
+    *.la)
+      old_library=
+      test yes = "$build_old_libs" && old_library=$libname.$libext
+      func_verbose "creating $output"
+
+      # Preserve any variables that may affect compiler behavior
+      for var in $variables_saved_for_relink; do
+	if eval test -z \"\${$var+set}\"; then
+	  relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command"
+	elif eval var_value=\$$var; test -z "$var_value"; then
+	  relink_command="$var=; export $var; $relink_command"
+	else
+	  func_quote_for_eval "$var_value"
+	  relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command"
+	fi
+      done
+      # Quote the link command for shipping.
+      relink_command="(cd `pwd`; $SHELL \"$progpath\" $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)"
+      relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"`
+      if test yes = "$hardcode_automatic"; then
+	relink_command=
+      fi
+
+      # Only create the output if not a dry run.
+      $opt_dry_run || {
+	for installed in no yes; do
+	  if test yes = "$installed"; then
+	    if test -z "$install_libdir"; then
+	      break
+	    fi
+	    output=$output_objdir/${outputname}i
+	    # Replace all uninstalled libtool libraries with the installed ones
+	    newdependency_libs=
+	    for deplib in $dependency_libs; do
+	      case $deplib in
+	      *.la)
+		func_basename "$deplib"
+		name=$func_basename_result
+		func_resolve_sysroot "$deplib"
+		eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $func_resolve_sysroot_result`
+		test -z "$libdir" && \
+		  func_fatal_error "'$deplib' is not a valid libtool archive"
+		func_append newdependency_libs " ${lt_sysroot:+=}$libdir/$name"
+		;;
+	      -L*)
+		func_stripname -L '' "$deplib"
+		func_replace_sysroot "$func_stripname_result"
+		func_append newdependency_libs " -L$func_replace_sysroot_result"
+		;;
+	      -R*)
+		func_stripname -R '' "$deplib"
+		func_replace_sysroot "$func_stripname_result"
+		func_append newdependency_libs " -R$func_replace_sysroot_result"
+		;;
+	      *) func_append newdependency_libs " $deplib" ;;
+	      esac
+	    done
+	    dependency_libs=$newdependency_libs
+	    newdlfiles=
+
+	    for lib in $dlfiles; do
+	      case $lib in
+	      *.la)
+	        func_basename "$lib"
+		name=$func_basename_result
+		eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $lib`
+		test -z "$libdir" && \
+		  func_fatal_error "'$lib' is not a valid libtool archive"
+		func_append newdlfiles " ${lt_sysroot:+=}$libdir/$name"
+		;;
+	      *) func_append newdlfiles " $lib" ;;
+	      esac
+	    done
+	    dlfiles=$newdlfiles
+	    newdlprefiles=
+	    for lib in $dlprefiles; do
+	      case $lib in
+	      *.la)
+		# Only pass preopened files to the pseudo-archive (for
+		# eventual linking with the app. that links it) if we
+		# didn't already link the preopened objects directly into
+		# the library:
+		func_basename "$lib"
+		name=$func_basename_result
+		eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $lib`
+		test -z "$libdir" && \
+		  func_fatal_error "'$lib' is not a valid libtool archive"
+		func_append newdlprefiles " ${lt_sysroot:+=}$libdir/$name"
+		;;
+	      esac
+	    done
+	    dlprefiles=$newdlprefiles
+	  else
+	    newdlfiles=
+	    for lib in $dlfiles; do
+	      case $lib in
+		[\\/]* | [A-Za-z]:[\\/]*) abs=$lib ;;
+		*) abs=`pwd`"/$lib" ;;
+	      esac
+	      func_append newdlfiles " $abs"
+	    done
+	    dlfiles=$newdlfiles
+	    newdlprefiles=
+	    for lib in $dlprefiles; do
+	      case $lib in
+		[\\/]* | [A-Za-z]:[\\/]*) abs=$lib ;;
+		*) abs=`pwd`"/$lib" ;;
+	      esac
+	      func_append newdlprefiles " $abs"
+	    done
+	    dlprefiles=$newdlprefiles
+	  fi
+	  $RM $output
+	  # place dlname in correct position for cygwin
+	  # In fact, it would be nice if we could use this code for all target
+	  # systems that can't hard-code library paths into their executables
+	  # and that have no shared library path variable independent of PATH,
+	  # but it turns out we can't easily determine that from inspecting
+	  # libtool variables, so we have to hard-code the OSs to which it
+	  # applies here; at the moment, that means platforms that use the PE
+	  # object format with DLL files.  See the long comment at the top of
+	  # tests/bindir.at for full details.
+	  tdlname=$dlname
+	  case $host,$output,$installed,$module,$dlname in
+	    *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll | *cegcc*,*lai,yes,no,*.dll)
+	      # If a -bindir argument was supplied, place the dll there.
+	      if test -n "$bindir"; then
+		func_relative_path "$install_libdir" "$bindir"
+		tdlname=$func_relative_path_result/$dlname
+	      else
+		# Otherwise fall back on heuristic.
+		tdlname=../bin/$dlname
+	      fi
+	      ;;
+	  esac
+	  $ECHO > $output "\
+# $outputname - a libtool library file
+# Generated by $PROGRAM (GNU $PACKAGE) $VERSION
+#
+# Please DO NOT delete this file!
+# It is necessary for linking the library.
+
+# The name that we can dlopen(3).
+dlname='$tdlname'
+
+# Names of this library.
+library_names='$library_names'
+
+# The name of the static archive.
+old_library='$old_library'
+
+# Linker flags that cannot go in dependency_libs.
+inherited_linker_flags='$new_inherited_linker_flags'
+
+# Libraries that this one depends upon.
+dependency_libs='$dependency_libs'
+
+# Names of additional weak libraries provided by this library
+weak_library_names='$weak_libs'
+
+# Version information for $libname.
+current=$current
+age=$age
+revision=$revision
+
+# Is this an already installed library?
+installed=$installed
+
+# Should we warn about portability when linking against -modules?
+shouldnotlink=$module
+
+# Files to dlopen/dlpreopen
+dlopen='$dlfiles'
+dlpreopen='$dlprefiles'
+
+# Directory that this library needs to be installed in:
+libdir='$install_libdir'"
+	  if test no,yes = "$installed,$need_relink"; then
+	    $ECHO >> $output "\
+relink_command=\"$relink_command\""
+	  fi
+	done
+      }
+
+      # Do a symbolic link so that the libtool archive can be found in
+      # LD_LIBRARY_PATH before the program is installed.
+      func_show_eval '( cd "$output_objdir" && $RM "$outputname" && $LN_S "../$outputname" "$outputname" )' 'exit $?'
+      ;;
+    esac
+    exit $EXIT_SUCCESS
+}
+
+if test link = "$opt_mode" || test relink = "$opt_mode"; then
+  func_mode_link ${1+"$@"}
+fi
+
+
+# func_mode_uninstall arg...
+func_mode_uninstall ()
+{
+    $debug_cmd
+
+    RM=$nonopt
+    files=
+    rmforce=false
+    exit_status=0
+
+    # This variable tells wrapper scripts just to set variables rather
+    # than running their programs.
+    libtool_install_magic=$magic
+
+    for arg
+    do
+      case $arg in
+      -f) func_append RM " $arg"; rmforce=: ;;
+      -*) func_append RM " $arg" ;;
+      *) func_append files " $arg" ;;
+      esac
+    done
+
+    test -z "$RM" && \
+      func_fatal_help "you must specify an RM program"
+
+    rmdirs=
+
+    for file in $files; do
+      func_dirname "$file" "" "."
+      dir=$func_dirname_result
+      if test . = "$dir"; then
+	odir=$objdir
+      else
+	odir=$dir/$objdir
+      fi
+      func_basename "$file"
+      name=$func_basename_result
+      test uninstall = "$opt_mode" && odir=$dir
+
+      # Remember odir for removal later, being careful to avoid duplicates
+      if test clean = "$opt_mode"; then
+	case " $rmdirs " in
+	  *" $odir "*) ;;
+	  *) func_append rmdirs " $odir" ;;
+	esac
+      fi
+
+      # Don't error if the file doesn't exist and rm -f was used.
+      if { test -L "$file"; } >/dev/null 2>&1 ||
+	 { test -h "$file"; } >/dev/null 2>&1 ||
+	 test -f "$file"; then
+	:
+      elif test -d "$file"; then
+	exit_status=1
+	continue
+      elif $rmforce; then
+	continue
+      fi
+
+      rmfiles=$file
+
+      case $name in
+      *.la)
+	# Possibly a libtool archive, so verify it.
+	if func_lalib_p "$file"; then
+	  func_source $dir/$name
+
+	  # Delete the libtool libraries and symlinks.
+	  for n in $library_names; do
+	    func_append rmfiles " $odir/$n"
+	  done
+	  test -n "$old_library" && func_append rmfiles " $odir/$old_library"
+
+	  case $opt_mode in
+	  clean)
+	    case " $library_names " in
+	    *" $dlname "*) ;;
+	    *) test -n "$dlname" && func_append rmfiles " $odir/$dlname" ;;
+	    esac
+	    test -n "$libdir" && func_append rmfiles " $odir/$name $odir/${name}i"
+	    ;;
+	  uninstall)
+	    if test -n "$library_names"; then
+	      # Do each command in the postuninstall commands.
+	      func_execute_cmds "$postuninstall_cmds" '$rmforce || exit_status=1'
+	    fi
+
+	    if test -n "$old_library"; then
+	      # Do each command in the old_postuninstall commands.
+	      func_execute_cmds "$old_postuninstall_cmds" '$rmforce || exit_status=1'
+	    fi
+	    # FIXME: should reinstall the best remaining shared library.
+	    ;;
+	  esac
+	fi
+	;;
+
+      *.lo)
+	# Possibly a libtool object, so verify it.
+	if func_lalib_p "$file"; then
+
+	  # Read the .lo file
+	  func_source $dir/$name
+
+	  # Add PIC object to the list of files to remove.
+	  if test -n "$pic_object" && test none != "$pic_object"; then
+	    func_append rmfiles " $dir/$pic_object"
+	  fi
+
+	  # Add non-PIC object to the list of files to remove.
+	  if test -n "$non_pic_object" && test none != "$non_pic_object"; then
+	    func_append rmfiles " $dir/$non_pic_object"
+	  fi
+	fi
+	;;
+
+      *)
+	if test clean = "$opt_mode"; then
+	  noexename=$name
+	  case $file in
+	  *.exe)
+	    func_stripname '' '.exe' "$file"
+	    file=$func_stripname_result
+	    func_stripname '' '.exe' "$name"
+	    noexename=$func_stripname_result
+	    # $file with .exe has already been added to rmfiles,
+	    # add $file without .exe
+	    func_append rmfiles " $file"
+	    ;;
+	  esac
+	  # Do a test to see if this is a libtool program.
+	  if func_ltwrapper_p "$file"; then
+	    if func_ltwrapper_executable_p "$file"; then
+	      func_ltwrapper_scriptname "$file"
+	      relink_command=
+	      func_source $func_ltwrapper_scriptname_result
+	      func_append rmfiles " $func_ltwrapper_scriptname_result"
+	    else
+	      relink_command=
+	      func_source $dir/$noexename
+	    fi
+
+	    # note $name still contains .exe if it was in $file originally
+	    # as does the version of $file that was added into $rmfiles
+	    func_append rmfiles " $odir/$name $odir/${name}S.$objext"
+	    if test yes = "$fast_install" && test -n "$relink_command"; then
+	      func_append rmfiles " $odir/lt-$name"
+	    fi
+	    if test "X$noexename" != "X$name"; then
+	      func_append rmfiles " $odir/lt-$noexename.c"
+	    fi
+	  fi
+	fi
+	;;
+      esac
+      func_show_eval "$RM $rmfiles" 'exit_status=1'
+    done
+
+    # Try to remove the $objdir's in the directories where we deleted files
+    for dir in $rmdirs; do
+      if test -d "$dir"; then
+	func_show_eval "rmdir $dir >/dev/null 2>&1"
+      fi
+    done
+
+    exit $exit_status
+}
+
+if test uninstall = "$opt_mode" || test clean = "$opt_mode"; then
+  func_mode_uninstall ${1+"$@"}
+fi
+
+test -z "$opt_mode" && {
+  help=$generic_help
+  func_fatal_help "you must specify a MODE"
+}
+
+test -z "$exec_cmd" && \
+  func_fatal_help "invalid operation mode '$opt_mode'"
+
+if test -n "$exec_cmd"; then
+  eval exec "$exec_cmd"
+  exit $EXIT_FAILURE
+fi
+
+exit $exit_status
+
+
+# The TAGs below are defined such that we never get into a situation
+# where we disable both kinds of libraries.  Given conflicting
+# choices, we go for a static library, that is the most portable,
+# since we can't tell whether shared libraries were disabled because
+# the user asked for that or because the platform doesn't support
+# them.  This is particularly important on AIX, because we don't
+# support having both static and shared libraries enabled at the same
+# time on that platform, so we default to a shared-only configuration.
+# If a disable-shared tag is given, we'll fallback to a static-only
+# configuration.  But we'll never go from static-only to shared-only.
+
+# ### BEGIN LIBTOOL TAG CONFIG: disable-shared
+build_libtool_libs=no
+build_old_libs=yes
+# ### END LIBTOOL TAG CONFIG: disable-shared
+
+# ### BEGIN LIBTOOL TAG CONFIG: disable-static
+build_old_libs=`case $build_libtool_libs in yes) echo no;; *) echo yes;; esac`
+# ### END LIBTOOL TAG CONFIG: disable-static
+
+# Local Variables:
+# mode:shell-script
+# sh-indentation:2
+# End:
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/config/ltoptions.m4
@@ -0,0 +1,437 @@
+# Helper functions for option handling.                    -*- Autoconf -*-
+#
+#   Copyright (C) 2004-2005, 2007-2009, 2011-2015 Free Software
+#   Foundation, Inc.
+#   Written by Gary V. Vaughan, 2004
+#
+# This file is free software; the Free Software Foundation gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+
+# serial 8 ltoptions.m4
+
+# This is to help aclocal find these macros, as it can't see m4_define.
+AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])])
+
+
+# _LT_MANGLE_OPTION(MACRO-NAME, OPTION-NAME)
+# ------------------------------------------
+m4_define([_LT_MANGLE_OPTION],
+[[_LT_OPTION_]m4_bpatsubst($1__$2, [[^a-zA-Z0-9_]], [_])])
+
+
+# _LT_SET_OPTION(MACRO-NAME, OPTION-NAME)
+# ---------------------------------------
+# Set option OPTION-NAME for macro MACRO-NAME, and if there is a
+# matching handler defined, dispatch to it.  Other OPTION-NAMEs are
+# saved as a flag.
+m4_define([_LT_SET_OPTION],
+[m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl
+m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]),
+        _LT_MANGLE_DEFUN([$1], [$2]),
+    [m4_warning([Unknown $1 option '$2'])])[]dnl
+])
+
+
+# _LT_IF_OPTION(MACRO-NAME, OPTION-NAME, IF-SET, [IF-NOT-SET])
+# ------------------------------------------------------------
+# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise.
+m4_define([_LT_IF_OPTION],
+[m4_ifdef(_LT_MANGLE_OPTION([$1], [$2]), [$3], [$4])])
+
+
+# _LT_UNLESS_OPTIONS(MACRO-NAME, OPTION-LIST, IF-NOT-SET)
+# -------------------------------------------------------
+# Execute IF-NOT-SET unless all options in OPTION-LIST for MACRO-NAME
+# are set.
+m4_define([_LT_UNLESS_OPTIONS],
+[m4_foreach([_LT_Option], m4_split(m4_normalize([$2])),
+	    [m4_ifdef(_LT_MANGLE_OPTION([$1], _LT_Option),
+		      [m4_define([$0_found])])])[]dnl
+m4_ifdef([$0_found], [m4_undefine([$0_found])], [$3
+])[]dnl
+])
+
+
+# _LT_SET_OPTIONS(MACRO-NAME, OPTION-LIST)
+# ----------------------------------------
+# OPTION-LIST is a space-separated list of Libtool options associated
+# with MACRO-NAME.  If any OPTION has a matching handler declared with
+# LT_OPTION_DEFINE, dispatch to that macro; otherwise complain about
+# the unknown option and exit.
+m4_defun([_LT_SET_OPTIONS],
+[# Set options
+m4_foreach([_LT_Option], m4_split(m4_normalize([$2])),
+    [_LT_SET_OPTION([$1], _LT_Option)])
+
+m4_if([$1],[LT_INIT],[
+  dnl
+  dnl Simply set some default values (i.e off) if boolean options were not
+  dnl specified:
+  _LT_UNLESS_OPTIONS([LT_INIT], [dlopen], [enable_dlopen=no
+  ])
+  _LT_UNLESS_OPTIONS([LT_INIT], [win32-dll], [enable_win32_dll=no
+  ])
+  dnl
+  dnl If no reference was made to various pairs of opposing options, then
+  dnl we run the default mode handler for the pair.  For example, if neither
+  dnl 'shared' nor 'disable-shared' was passed, we enable building of shared
+  dnl archives by default:
+  _LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED])
+  _LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC])
+  _LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC])
+  _LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install],
+		   [_LT_ENABLE_FAST_INSTALL])
+  _LT_UNLESS_OPTIONS([LT_INIT], [aix-soname=aix aix-soname=both aix-soname=svr4],
+		   [_LT_WITH_AIX_SONAME([aix])])
+  ])
+])# _LT_SET_OPTIONS
+
+
+## --------------------------------- ##
+## Macros to handle LT_INIT options. ##
+## --------------------------------- ##
+
+# _LT_MANGLE_DEFUN(MACRO-NAME, OPTION-NAME)
+# -----------------------------------------
+m4_define([_LT_MANGLE_DEFUN],
+[[_LT_OPTION_DEFUN_]m4_bpatsubst(m4_toupper([$1__$2]), [[^A-Z0-9_]], [_])])
+
+
+# LT_OPTION_DEFINE(MACRO-NAME, OPTION-NAME, CODE)
+# -----------------------------------------------
+m4_define([LT_OPTION_DEFINE],
+[m4_define(_LT_MANGLE_DEFUN([$1], [$2]), [$3])[]dnl
+])# LT_OPTION_DEFINE
+
+
+# dlopen
+# ------
+LT_OPTION_DEFINE([LT_INIT], [dlopen], [enable_dlopen=yes
+])
+
+AU_DEFUN([AC_LIBTOOL_DLOPEN],
+[_LT_SET_OPTION([LT_INIT], [dlopen])
+AC_DIAGNOSE([obsolete],
+[$0: Remove this warning and the call to _LT_SET_OPTION when you
+put the 'dlopen' option into LT_INIT's first parameter.])
+])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_DLOPEN], [])
+
+
+# win32-dll
+# ---------
+# Declare package support for building win32 dll's.
+LT_OPTION_DEFINE([LT_INIT], [win32-dll],
+[enable_win32_dll=yes
+
+case $host in
+*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*)
+  AC_CHECK_TOOL(AS, as, false)
+  AC_CHECK_TOOL(DLLTOOL, dlltool, false)
+  AC_CHECK_TOOL(OBJDUMP, objdump, false)
+  ;;
+esac
+
+test -z "$AS" && AS=as
+_LT_DECL([], [AS],      [1], [Assembler program])dnl
+
+test -z "$DLLTOOL" && DLLTOOL=dlltool
+_LT_DECL([], [DLLTOOL], [1], [DLL creation program])dnl
+
+test -z "$OBJDUMP" && OBJDUMP=objdump
+_LT_DECL([], [OBJDUMP], [1], [Object dumper program])dnl
+])# win32-dll
+
+AU_DEFUN([AC_LIBTOOL_WIN32_DLL],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+_LT_SET_OPTION([LT_INIT], [win32-dll])
+AC_DIAGNOSE([obsolete],
+[$0: Remove this warning and the call to _LT_SET_OPTION when you
+put the 'win32-dll' option into LT_INIT's first parameter.])
+])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], [])
+
+
+# _LT_ENABLE_SHARED([DEFAULT])
+# ----------------------------
+# implement the --enable-shared flag, and supports the 'shared' and
+# 'disable-shared' LT_INIT options.
+# DEFAULT is either 'yes' or 'no'.  If omitted, it defaults to 'yes'.
+m4_define([_LT_ENABLE_SHARED],
+[m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl
+AC_ARG_ENABLE([shared],
+    [AS_HELP_STRING([--enable-shared@<:@=PKGS@:>@],
+	[build shared libraries @<:@default=]_LT_ENABLE_SHARED_DEFAULT[@:>@])],
+    [p=${PACKAGE-default}
+    case $enableval in
+    yes) enable_shared=yes ;;
+    no) enable_shared=no ;;
+    *)
+      enable_shared=no
+      # Look at the argument we got.  We use all the common list separators.
+      lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
+      for pkg in $enableval; do
+	IFS=$lt_save_ifs
+	if test "X$pkg" = "X$p"; then
+	  enable_shared=yes
+	fi
+      done
+      IFS=$lt_save_ifs
+      ;;
+    esac],
+    [enable_shared=]_LT_ENABLE_SHARED_DEFAULT)
+
+    _LT_DECL([build_libtool_libs], [enable_shared], [0],
+	[Whether or not to build shared libraries])
+])# _LT_ENABLE_SHARED
+
+LT_OPTION_DEFINE([LT_INIT], [shared], [_LT_ENABLE_SHARED([yes])])
+LT_OPTION_DEFINE([LT_INIT], [disable-shared], [_LT_ENABLE_SHARED([no])])
+
+# Old names:
+AC_DEFUN([AC_ENABLE_SHARED],
+[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[shared])
+])
+
+AC_DEFUN([AC_DISABLE_SHARED],
+[_LT_SET_OPTION([LT_INIT], [disable-shared])
+])
+
+AU_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)])
+AU_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AM_ENABLE_SHARED], [])
+dnl AC_DEFUN([AM_DISABLE_SHARED], [])
+
+
+
+# _LT_ENABLE_STATIC([DEFAULT])
+# ----------------------------
+# implement the --enable-static flag, and support the 'static' and
+# 'disable-static' LT_INIT options.
+# DEFAULT is either 'yes' or 'no'.  If omitted, it defaults to 'yes'.
+m4_define([_LT_ENABLE_STATIC],
+[m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl
+AC_ARG_ENABLE([static],
+    [AS_HELP_STRING([--enable-static@<:@=PKGS@:>@],
+	[build static libraries @<:@default=]_LT_ENABLE_STATIC_DEFAULT[@:>@])],
+    [p=${PACKAGE-default}
+    case $enableval in
+    yes) enable_static=yes ;;
+    no) enable_static=no ;;
+    *)
+     enable_static=no
+      # Look at the argument we got.  We use all the common list separators.
+      lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
+      for pkg in $enableval; do
+	IFS=$lt_save_ifs
+	if test "X$pkg" = "X$p"; then
+	  enable_static=yes
+	fi
+      done
+      IFS=$lt_save_ifs
+      ;;
+    esac],
+    [enable_static=]_LT_ENABLE_STATIC_DEFAULT)
+
+    _LT_DECL([build_old_libs], [enable_static], [0],
+	[Whether or not to build static libraries])
+])# _LT_ENABLE_STATIC
+
+LT_OPTION_DEFINE([LT_INIT], [static], [_LT_ENABLE_STATIC([yes])])
+LT_OPTION_DEFINE([LT_INIT], [disable-static], [_LT_ENABLE_STATIC([no])])
+
+# Old names:
+AC_DEFUN([AC_ENABLE_STATIC],
+[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[static])
+])
+
+AC_DEFUN([AC_DISABLE_STATIC],
+[_LT_SET_OPTION([LT_INIT], [disable-static])
+])
+
+AU_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)])
+AU_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AM_ENABLE_STATIC], [])
+dnl AC_DEFUN([AM_DISABLE_STATIC], [])
+
+
+
+# _LT_ENABLE_FAST_INSTALL([DEFAULT])
+# ----------------------------------
+# implement the --enable-fast-install flag, and support the 'fast-install'
+# and 'disable-fast-install' LT_INIT options.
+# DEFAULT is either 'yes' or 'no'.  If omitted, it defaults to 'yes'.
+m4_define([_LT_ENABLE_FAST_INSTALL],
+[m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl
+AC_ARG_ENABLE([fast-install],
+    [AS_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@],
+    [optimize for fast installation @<:@default=]_LT_ENABLE_FAST_INSTALL_DEFAULT[@:>@])],
+    [p=${PACKAGE-default}
+    case $enableval in
+    yes) enable_fast_install=yes ;;
+    no) enable_fast_install=no ;;
+    *)
+      enable_fast_install=no
+      # Look at the argument we got.  We use all the common list separators.
+      lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
+      for pkg in $enableval; do
+	IFS=$lt_save_ifs
+	if test "X$pkg" = "X$p"; then
+	  enable_fast_install=yes
+	fi
+      done
+      IFS=$lt_save_ifs
+      ;;
+    esac],
+    [enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT)
+
+_LT_DECL([fast_install], [enable_fast_install], [0],
+	 [Whether or not to optimize for fast installation])dnl
+])# _LT_ENABLE_FAST_INSTALL
+
+LT_OPTION_DEFINE([LT_INIT], [fast-install], [_LT_ENABLE_FAST_INSTALL([yes])])
+LT_OPTION_DEFINE([LT_INIT], [disable-fast-install], [_LT_ENABLE_FAST_INSTALL([no])])
+
+# Old names:
+AU_DEFUN([AC_ENABLE_FAST_INSTALL],
+[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install])
+AC_DIAGNOSE([obsolete],
+[$0: Remove this warning and the call to _LT_SET_OPTION when you put
+the 'fast-install' option into LT_INIT's first parameter.])
+])
+
+AU_DEFUN([AC_DISABLE_FAST_INSTALL],
+[_LT_SET_OPTION([LT_INIT], [disable-fast-install])
+AC_DIAGNOSE([obsolete],
+[$0: Remove this warning and the call to _LT_SET_OPTION when you put
+the 'disable-fast-install' option into LT_INIT's first parameter.])
+])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], [])
+dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], [])
+
+
+# _LT_WITH_AIX_SONAME([DEFAULT])
+# ----------------------------------
+# implement the --with-aix-soname flag, and support the `aix-soname=aix'
+# and `aix-soname=both' and `aix-soname=svr4' LT_INIT options. DEFAULT
+# is either `aix', `both' or `svr4'.  If omitted, it defaults to `aix'.
+m4_define([_LT_WITH_AIX_SONAME],
+[m4_define([_LT_WITH_AIX_SONAME_DEFAULT], [m4_if($1, svr4, svr4, m4_if($1, both, both, aix))])dnl
+shared_archive_member_spec=
+case $host,$enable_shared in
+power*-*-aix[[5-9]]*,yes)
+  AC_MSG_CHECKING([which variant of shared library versioning to provide])
+  AC_ARG_WITH([aix-soname],
+    [AS_HELP_STRING([--with-aix-soname=aix|svr4|both],
+      [shared library versioning (aka "SONAME") variant to provide on AIX, @<:@default=]_LT_WITH_AIX_SONAME_DEFAULT[@:>@.])],
+    [case $withval in
+    aix|svr4|both)
+      ;;
+    *)
+      AC_MSG_ERROR([Unknown argument to --with-aix-soname])
+      ;;
+    esac
+    lt_cv_with_aix_soname=$with_aix_soname],
+    [AC_CACHE_VAL([lt_cv_with_aix_soname],
+      [lt_cv_with_aix_soname=]_LT_WITH_AIX_SONAME_DEFAULT)
+    with_aix_soname=$lt_cv_with_aix_soname])
+  AC_MSG_RESULT([$with_aix_soname])
+  if test aix != "$with_aix_soname"; then
+    # For the AIX way of multilib, we name the shared archive member
+    # based on the bitwidth used, traditionally 'shr.o' or 'shr_64.o',
+    # and 'shr.imp' or 'shr_64.imp', respectively, for the Import File.
+    # Even when GNU compilers ignore OBJECT_MODE but need '-maix64' flag,
+    # the AIX toolchain works better with OBJECT_MODE set (default 32).
+    if test 64 = "${OBJECT_MODE-32}"; then
+      shared_archive_member_spec=shr_64
+    else
+      shared_archive_member_spec=shr
+    fi
+  fi
+  ;;
+*)
+  with_aix_soname=aix
+  ;;
+esac
+
+_LT_DECL([], [shared_archive_member_spec], [0],
+    [Shared archive member basename, for filename based shared library versioning on AIX])dnl
+])# _LT_WITH_AIX_SONAME
+
+LT_OPTION_DEFINE([LT_INIT], [aix-soname=aix], [_LT_WITH_AIX_SONAME([aix])])
+LT_OPTION_DEFINE([LT_INIT], [aix-soname=both], [_LT_WITH_AIX_SONAME([both])])
+LT_OPTION_DEFINE([LT_INIT], [aix-soname=svr4], [_LT_WITH_AIX_SONAME([svr4])])
+
+
+# _LT_WITH_PIC([MODE])
+# --------------------
+# implement the --with-pic flag, and support the 'pic-only' and 'no-pic'
+# LT_INIT options.
+# MODE is either 'yes' or 'no'.  If omitted, it defaults to 'both'.
+m4_define([_LT_WITH_PIC],
+[AC_ARG_WITH([pic],
+    [AS_HELP_STRING([--with-pic@<:@=PKGS@:>@],
+	[try to use only PIC/non-PIC objects @<:@default=use both@:>@])],
+    [lt_p=${PACKAGE-default}
+    case $withval in
+    yes|no) pic_mode=$withval ;;
+    *)
+      pic_mode=default
+      # Look at the argument we got.  We use all the common list separators.
+      lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
+      for lt_pkg in $withval; do
+	IFS=$lt_save_ifs
+	if test "X$lt_pkg" = "X$lt_p"; then
+	  pic_mode=yes
+	fi
+      done
+      IFS=$lt_save_ifs
+      ;;
+    esac],
+    [pic_mode=m4_default([$1], [default])])
+
+_LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl
+])# _LT_WITH_PIC
+
+LT_OPTION_DEFINE([LT_INIT], [pic-only], [_LT_WITH_PIC([yes])])
+LT_OPTION_DEFINE([LT_INIT], [no-pic], [_LT_WITH_PIC([no])])
+
+# Old name:
+AU_DEFUN([AC_LIBTOOL_PICMODE],
+[_LT_SET_OPTION([LT_INIT], [pic-only])
+AC_DIAGNOSE([obsolete],
+[$0: Remove this warning and the call to _LT_SET_OPTION when you
+put the 'pic-only' option into LT_INIT's first parameter.])
+])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_PICMODE], [])
+
+## ----------------- ##
+## LTDL_INIT Options ##
+## ----------------- ##
+
+m4_define([_LTDL_MODE], [])
+LT_OPTION_DEFINE([LTDL_INIT], [nonrecursive],
+		 [m4_define([_LTDL_MODE], [nonrecursive])])
+LT_OPTION_DEFINE([LTDL_INIT], [recursive],
+		 [m4_define([_LTDL_MODE], [recursive])])
+LT_OPTION_DEFINE([LTDL_INIT], [subproject],
+		 [m4_define([_LTDL_MODE], [subproject])])
+
+m4_define([_LTDL_TYPE], [])
+LT_OPTION_DEFINE([LTDL_INIT], [installable],
+		 [m4_define([_LTDL_TYPE], [installable])])
+LT_OPTION_DEFINE([LTDL_INIT], [convenience],
+		 [m4_define([_LTDL_TYPE], [convenience])])
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/config/ltsugar.m4
@@ -0,0 +1,124 @@
+# ltsugar.m4 -- libtool m4 base layer.                         -*-Autoconf-*-
+#
+# Copyright (C) 2004-2005, 2007-2008, 2011-2015 Free Software
+# Foundation, Inc.
+# Written by Gary V. Vaughan, 2004
+#
+# This file is free software; the Free Software Foundation gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+
+# serial 6 ltsugar.m4
+
+# This is to help aclocal find these macros, as it can't see m4_define.
+AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])])
+
+
+# lt_join(SEP, ARG1, [ARG2...])
+# -----------------------------
+# Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their
+# associated separator.
+# Needed until we can rely on m4_join from Autoconf 2.62, since all earlier
+# versions in m4sugar had bugs.
+m4_define([lt_join],
+[m4_if([$#], [1], [],
+       [$#], [2], [[$2]],
+       [m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])])
+m4_define([_lt_join],
+[m4_if([$#$2], [2], [],
+       [m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])])
+
+
+# lt_car(LIST)
+# lt_cdr(LIST)
+# ------------
+# Manipulate m4 lists.
+# These macros are necessary as long as will still need to support
+# Autoconf-2.59, which quotes differently.
+m4_define([lt_car], [[$1]])
+m4_define([lt_cdr],
+[m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])],
+       [$#], 1, [],
+       [m4_dquote(m4_shift($@))])])
+m4_define([lt_unquote], $1)
+
+
+# lt_append(MACRO-NAME, STRING, [SEPARATOR])
+# ------------------------------------------
+# Redefine MACRO-NAME to hold its former content plus 'SEPARATOR''STRING'.
+# Note that neither SEPARATOR nor STRING are expanded; they are appended
+# to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked).
+# No SEPARATOR is output if MACRO-NAME was previously undefined (different
+# than defined and empty).
+#
+# This macro is needed until we can rely on Autoconf 2.62, since earlier
+# versions of m4sugar mistakenly expanded SEPARATOR but not STRING.
+m4_define([lt_append],
+[m4_define([$1],
+	   m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])])
+
+
+
+# lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...])
+# ----------------------------------------------------------
+# Produce a SEP delimited list of all paired combinations of elements of
+# PREFIX-LIST with SUFFIX1 through SUFFIXn.  Each element of the list
+# has the form PREFIXmINFIXSUFFIXn.
+# Needed until we can rely on m4_combine added in Autoconf 2.62.
+m4_define([lt_combine],
+[m4_if(m4_eval([$# > 3]), [1],
+       [m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl
+[[m4_foreach([_Lt_prefix], [$2],
+	     [m4_foreach([_Lt_suffix],
+		]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[,
+	[_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])])
+
+
+# lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ])
+# -----------------------------------------------------------------------
+# Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited
+# by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ.
+m4_define([lt_if_append_uniq],
+[m4_ifdef([$1],
+	  [m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1],
+		 [lt_append([$1], [$2], [$3])$4],
+		 [$5])],
+	  [lt_append([$1], [$2], [$3])$4])])
+
+
+# lt_dict_add(DICT, KEY, VALUE)
+# -----------------------------
+m4_define([lt_dict_add],
+[m4_define([$1($2)], [$3])])
+
+
+# lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE)
+# --------------------------------------------
+m4_define([lt_dict_add_subkey],
+[m4_define([$1($2:$3)], [$4])])
+
+
+# lt_dict_fetch(DICT, KEY, [SUBKEY])
+# ----------------------------------
+m4_define([lt_dict_fetch],
+[m4_ifval([$3],
+	m4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]),
+    m4_ifdef([$1($2)], [m4_defn([$1($2)])]))])
+
+
+# lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE])
+# -----------------------------------------------------------------
+m4_define([lt_if_dict_fetch],
+[m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4],
+	[$5],
+    [$6])])
+
+
+# lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...])
+# --------------------------------------------------------------
+m4_define([lt_dict_filter],
+[m4_if([$5], [], [],
+  [lt_join(m4_quote(m4_default([$4], [[, ]])),
+           lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]),
+		      [lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl
+])
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/config/ltversion.m4
@@ -0,0 +1,23 @@
+# ltversion.m4 -- version numbers			-*- Autoconf -*-
+#
+#   Copyright (C) 2004, 2011-2015 Free Software Foundation, Inc.
+#   Written by Scott James Remnant, 2004
+#
+# This file is free software; the Free Software Foundation gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+
+# @configure_input@
+
+# serial 4179 ltversion.m4
+# This file is part of GNU Libtool
+
+m4_define([LT_PACKAGE_VERSION], [2.4.6])
+m4_define([LT_PACKAGE_REVISION], [2.4.6])
+
+AC_DEFUN([LTVERSION_VERSION],
+[macro_version='2.4.6'
+macro_revision='2.4.6'
+_LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?])
+_LT_DECL(, macro_revision, 0)
+])
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/config/lt~obsolete.m4
@@ -0,0 +1,99 @@
+# lt~obsolete.m4 -- aclocal satisfying obsolete definitions.    -*-Autoconf-*-
+#
+#   Copyright (C) 2004-2005, 2007, 2009, 2011-2015 Free Software
+#   Foundation, Inc.
+#   Written by Scott James Remnant, 2004.
+#
+# This file is free software; the Free Software Foundation gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+
+# serial 5 lt~obsolete.m4
+
+# These exist entirely to fool aclocal when bootstrapping libtool.
+#
+# In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN),
+# which have later been changed to m4_define as they aren't part of the
+# exported API, or moved to Autoconf or Automake where they belong.
+#
+# The trouble is, aclocal is a bit thick.  It'll see the old AC_DEFUN
+# in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us
+# using a macro with the same name in our local m4/libtool.m4 it'll
+# pull the old libtool.m4 in (it doesn't see our shiny new m4_define
+# and doesn't know about Autoconf macros at all.)
+#
+# So we provide this file, which has a silly filename so it's always
+# included after everything else.  This provides aclocal with the
+# AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything
+# because those macros already exist, or will be overwritten later.
+# We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6.
+#
+# Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here.
+# Yes, that means every name once taken will need to remain here until
+# we give up compatibility with versions before 1.7, at which point
+# we need to keep only those names which we still refer to.
+
+# This is to help aclocal find these macros, as it can't see m4_define.
+AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])])
+
+m4_ifndef([AC_LIBTOOL_LINKER_OPTION],	[AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])])
+m4_ifndef([AC_PROG_EGREP],		[AC_DEFUN([AC_PROG_EGREP])])
+m4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH],	[AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])])
+m4_ifndef([_LT_AC_SHELL_INIT],		[AC_DEFUN([_LT_AC_SHELL_INIT])])
+m4_ifndef([_LT_AC_SYS_LIBPATH_AIX],	[AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])])
+m4_ifndef([_LT_PROG_LTMAIN],		[AC_DEFUN([_LT_PROG_LTMAIN])])
+m4_ifndef([_LT_AC_TAGVAR],		[AC_DEFUN([_LT_AC_TAGVAR])])
+m4_ifndef([AC_LTDL_ENABLE_INSTALL],	[AC_DEFUN([AC_LTDL_ENABLE_INSTALL])])
+m4_ifndef([AC_LTDL_PREOPEN],		[AC_DEFUN([AC_LTDL_PREOPEN])])
+m4_ifndef([_LT_AC_SYS_COMPILER],	[AC_DEFUN([_LT_AC_SYS_COMPILER])])
+m4_ifndef([_LT_AC_LOCK],		[AC_DEFUN([_LT_AC_LOCK])])
+m4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE],	[AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])])
+m4_ifndef([_LT_AC_TRY_DLOPEN_SELF],	[AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])])
+m4_ifndef([AC_LIBTOOL_PROG_CC_C_O],	[AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])])
+m4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])])
+m4_ifndef([AC_LIBTOOL_OBJDIR],		[AC_DEFUN([AC_LIBTOOL_OBJDIR])])
+m4_ifndef([AC_LTDL_OBJDIR],		[AC_DEFUN([AC_LTDL_OBJDIR])])
+m4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])])
+m4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP],	[AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])])
+m4_ifndef([AC_PATH_MAGIC],		[AC_DEFUN([AC_PATH_MAGIC])])
+m4_ifndef([AC_PROG_LD_GNU],		[AC_DEFUN([AC_PROG_LD_GNU])])
+m4_ifndef([AC_PROG_LD_RELOAD_FLAG],	[AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])])
+m4_ifndef([AC_DEPLIBS_CHECK_METHOD],	[AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])])
+m4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])])
+m4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])])
+m4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])])
+m4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS],	[AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])])
+m4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP],	[AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])])
+m4_ifndef([LT_AC_PROG_EGREP],		[AC_DEFUN([LT_AC_PROG_EGREP])])
+m4_ifndef([LT_AC_PROG_SED],		[AC_DEFUN([LT_AC_PROG_SED])])
+m4_ifndef([_LT_CC_BASENAME],		[AC_DEFUN([_LT_CC_BASENAME])])
+m4_ifndef([_LT_COMPILER_BOILERPLATE],	[AC_DEFUN([_LT_COMPILER_BOILERPLATE])])
+m4_ifndef([_LT_LINKER_BOILERPLATE],	[AC_DEFUN([_LT_LINKER_BOILERPLATE])])
+m4_ifndef([_AC_PROG_LIBTOOL],		[AC_DEFUN([_AC_PROG_LIBTOOL])])
+m4_ifndef([AC_LIBTOOL_SETUP],		[AC_DEFUN([AC_LIBTOOL_SETUP])])
+m4_ifndef([_LT_AC_CHECK_DLFCN],		[AC_DEFUN([_LT_AC_CHECK_DLFCN])])
+m4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER],	[AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])])
+m4_ifndef([_LT_AC_TAGCONFIG],		[AC_DEFUN([_LT_AC_TAGCONFIG])])
+m4_ifndef([AC_DISABLE_FAST_INSTALL],	[AC_DEFUN([AC_DISABLE_FAST_INSTALL])])
+m4_ifndef([_LT_AC_LANG_CXX],		[AC_DEFUN([_LT_AC_LANG_CXX])])
+m4_ifndef([_LT_AC_LANG_F77],		[AC_DEFUN([_LT_AC_LANG_F77])])
+m4_ifndef([_LT_AC_LANG_GCJ],		[AC_DEFUN([_LT_AC_LANG_GCJ])])
+m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG],	[AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])])
+m4_ifndef([_LT_AC_LANG_C_CONFIG],	[AC_DEFUN([_LT_AC_LANG_C_CONFIG])])
+m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG],	[AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])])
+m4_ifndef([_LT_AC_LANG_CXX_CONFIG],	[AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])])
+m4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG],	[AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])])
+m4_ifndef([_LT_AC_LANG_F77_CONFIG],	[AC_DEFUN([_LT_AC_LANG_F77_CONFIG])])
+m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG],	[AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])])
+m4_ifndef([_LT_AC_LANG_GCJ_CONFIG],	[AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])])
+m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG],	[AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])])
+m4_ifndef([_LT_AC_LANG_RC_CONFIG],	[AC_DEFUN([_LT_AC_LANG_RC_CONFIG])])
+m4_ifndef([AC_LIBTOOL_CONFIG],		[AC_DEFUN([AC_LIBTOOL_CONFIG])])
+m4_ifndef([_LT_AC_FILE_LTDLL_C],	[AC_DEFUN([_LT_AC_FILE_LTDLL_C])])
+m4_ifndef([_LT_REQUIRED_DARWIN_CHECKS],	[AC_DEFUN([_LT_REQUIRED_DARWIN_CHECKS])])
+m4_ifndef([_LT_AC_PROG_CXXCPP],		[AC_DEFUN([_LT_AC_PROG_CXXCPP])])
+m4_ifndef([_LT_PREPARE_SED_QUOTE_VARS],	[AC_DEFUN([_LT_PREPARE_SED_QUOTE_VARS])])
+m4_ifndef([_LT_PROG_ECHO_BACKSLASH],	[AC_DEFUN([_LT_PROG_ECHO_BACKSLASH])])
+m4_ifndef([_LT_PROG_F77],		[AC_DEFUN([_LT_PROG_F77])])
+m4_ifndef([_LT_PROG_FC],		[AC_DEFUN([_LT_PROG_FC])])
+m4_ifndef([_LT_PROG_CXX],		[AC_DEFUN([_LT_PROG_CXX])])
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/config/missing
@@ -0,0 +1,215 @@
+#! /bin/sh
+# Common wrapper for a few potentially missing GNU programs.
+
+scriptversion=2013-10-28.13; # UTC
+
+# Copyright (C) 1996-2014 Free Software Foundation, Inc.
+# Originally written by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+if test $# -eq 0; then
+  echo 1>&2 "Try '$0 --help' for more information"
+  exit 1
+fi
+
+case $1 in
+
+  --is-lightweight)
+    # Used by our autoconf macros to check whether the available missing
+    # script is modern enough.
+    exit 0
+    ;;
+
+  --run)
+    # Back-compat with the calling convention used by older automake.
+    shift
+    ;;
+
+  -h|--h|--he|--hel|--help)
+    echo "\
+$0 [OPTION]... PROGRAM [ARGUMENT]...
+
+Run 'PROGRAM [ARGUMENT]...', returning a proper advice when this fails due
+to PROGRAM being missing or too old.
+
+Options:
+  -h, --help      display this help and exit
+  -v, --version   output version information and exit
+
+Supported PROGRAM values:
+  aclocal   autoconf  autoheader   autom4te  automake  makeinfo
+  bison     yacc      flex         lex       help2man
+
+Version suffixes to PROGRAM as well as the prefixes 'gnu-', 'gnu', and
+'g' are ignored when checking the name.
+
+Send bug reports to <bug-automake@gnu.org>."
+    exit $?
+    ;;
+
+  -v|--v|--ve|--ver|--vers|--versi|--versio|--version)
+    echo "missing $scriptversion (GNU Automake)"
+    exit $?
+    ;;
+
+  -*)
+    echo 1>&2 "$0: unknown '$1' option"
+    echo 1>&2 "Try '$0 --help' for more information"
+    exit 1
+    ;;
+
+esac
+
+# Run the given program, remember its exit status.
+"$@"; st=$?
+
+# If it succeeded, we are done.
+test $st -eq 0 && exit 0
+
+# Also exit now if we it failed (or wasn't found), and '--version' was
+# passed; such an option is passed most likely to detect whether the
+# program is present and works.
+case $2 in --version|--help) exit $st;; esac
+
+# Exit code 63 means version mismatch.  This often happens when the user
+# tries to use an ancient version of a tool on a file that requires a
+# minimum version.
+if test $st -eq 63; then
+  msg="probably too old"
+elif test $st -eq 127; then
+  # Program was missing.
+  msg="missing on your system"
+else
+  # Program was found and executed, but failed.  Give up.
+  exit $st
+fi
+
+perl_URL=http://www.perl.org/
+flex_URL=http://flex.sourceforge.net/
+gnu_software_URL=http://www.gnu.org/software
+
+program_details ()
+{
+  case $1 in
+    aclocal|automake)
+      echo "The '$1' program is part of the GNU Automake package:"
+      echo "<$gnu_software_URL/automake>"
+      echo "It also requires GNU Autoconf, GNU m4 and Perl in order to run:"
+      echo "<$gnu_software_URL/autoconf>"
+      echo "<$gnu_software_URL/m4/>"
+      echo "<$perl_URL>"
+      ;;
+    autoconf|autom4te|autoheader)
+      echo "The '$1' program is part of the GNU Autoconf package:"
+      echo "<$gnu_software_URL/autoconf/>"
+      echo "It also requires GNU m4 and Perl in order to run:"
+      echo "<$gnu_software_URL/m4/>"
+      echo "<$perl_URL>"
+      ;;
+  esac
+}
+
+give_advice ()
+{
+  # Normalize program name to check for.
+  normalized_program=`echo "$1" | sed '
+    s/^gnu-//; t
+    s/^gnu//; t
+    s/^g//; t'`
+
+  printf '%s\n' "'$1' is $msg."
+
+  configure_deps="'configure.ac' or m4 files included by 'configure.ac'"
+  case $normalized_program in
+    autoconf*)
+      echo "You should only need it if you modified 'configure.ac',"
+      echo "or m4 files included by it."
+      program_details 'autoconf'
+      ;;
+    autoheader*)
+      echo "You should only need it if you modified 'acconfig.h' or"
+      echo "$configure_deps."
+      program_details 'autoheader'
+      ;;
+    automake*)
+      echo "You should only need it if you modified 'Makefile.am' or"
+      echo "$configure_deps."
+      program_details 'automake'
+      ;;
+    aclocal*)
+      echo "You should only need it if you modified 'acinclude.m4' or"
+      echo "$configure_deps."
+      program_details 'aclocal'
+      ;;
+   autom4te*)
+      echo "You might have modified some maintainer files that require"
+      echo "the 'autom4te' program to be rebuilt."
+      program_details 'autom4te'
+      ;;
+    bison*|yacc*)
+      echo "You should only need it if you modified a '.y' file."
+      echo "You may want to install the GNU Bison package:"
+      echo "<$gnu_software_URL/bison/>"
+      ;;
+    lex*|flex*)
+      echo "You should only need it if you modified a '.l' file."
+      echo "You may want to install the Fast Lexical Analyzer package:"
+      echo "<$flex_URL>"
+      ;;
+    help2man*)
+      echo "You should only need it if you modified a dependency" \
+           "of a man page."
+      echo "You may want to install the GNU Help2man package:"
+      echo "<$gnu_software_URL/help2man/>"
+    ;;
+    makeinfo*)
+      echo "You should only need it if you modified a '.texi' file, or"
+      echo "any other file indirectly affecting the aspect of the manual."
+      echo "You might want to install the Texinfo package:"
+      echo "<$gnu_software_URL/texinfo/>"
+      echo "The spurious makeinfo call might also be the consequence of"
+      echo "using a buggy 'make' (AIX, DU, IRIX), in which case you might"
+      echo "want to install GNU make:"
+      echo "<$gnu_software_URL/make/>"
+      ;;
+    *)
+      echo "You might have modified some files without having the proper"
+      echo "tools for further handling them.  Check the 'README' file, it"
+      echo "often tells you about the needed prerequisites for installing"
+      echo "this package.  You may also peek at any GNU archive site, in"
+      echo "case some other package contains this missing '$1' program."
+      ;;
+  esac
+}
+
+give_advice "$1" | sed -e '1s/^/WARNING: /' \
+                       -e '2,$s/^/         /' >&2
+
+# Propagate the correct exit status (expected to be 127 for a program
+# not found, 63 for a program that failed due to version mismatch).
+exit $st
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
+# End:
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/config/mount-helper.m4
@@ -0,0 +1,8 @@
+AC_DEFUN([ZFS_AC_CONFIG_USER_MOUNT_HELPER], [
+	AC_ARG_WITH(mounthelperdir,
+		AC_HELP_STRING([--with-mounthelperdir=DIR],
+		[install mount.zfs in dir [[/sbin]]]),
+		mounthelperdir=$withval,mounthelperdir=/sbin)
+
+	AC_SUBST(mounthelperdir)
+])
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/config/rpm.am
@@ -0,0 +1,87 @@
+###############################################################################
+# Copyright (C) 2007-2013 Lawrence Livermore National Security, LLC.
+# Copyright (C) 2007 The Regents of the University of California.
+# Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+###############################################################################
+# Build targets for RPM packages.
+###############################################################################
+
+srpm-kmod:
+	$(MAKE) $(AM_MAKEFLAGS) pkg="${PACKAGE}-kmod" \
+		def='${SRPM_DEFINE_COMMON} ${SRPM_DEFINE_KMOD}' srpm-common
+
+srpm-dkms:
+	$(MAKE) $(AM_MAKEFLAGS) pkg="${PACKAGE}-dkms" \
+		def='${SRPM_DEFINE_COMMON} ${SRPM_DEFINE_DKMS}' srpm-common
+
+srpm-utils:
+	$(MAKE) $(AM_MAKEFLAGS) pkg="${PACKAGE}" \
+		def='${SRPM_DEFINE_COMMON} ${SRPM_DEFINE_UTIL}' srpm-common
+
+srpm: srpm-kmod srpm-dkms srpm-utils
+srpms: srpm-kmod srpm-dkms srpm-utils
+
+rpm-kmod: srpm-kmod
+	$(MAKE) $(AM_MAKEFLAGS) pkg="${PACKAGE}-kmod" \
+		def='${RPM_DEFINE_COMMON} ${RPM_DEFINE_KMOD}' rpm-common
+
+rpm-dkms: srpm-dkms
+	$(MAKE) $(AM_MAKEFLAGS) pkg="${PACKAGE}-dkms" \
+		def='${RPM_DEFINE_COMMON} ${RPM_DEFINE_DKMS}' rpm-common
+
+rpm-utils: srpm-utils
+	$(MAKE) $(AM_MAKEFLAGS) pkg="${PACKAGE}" \
+		def='${RPM_DEFINE_COMMON} ${RPM_DEFINE_UTIL}' rpm-common
+
+rpm: rpm-kmod rpm-dkms rpm-utils
+rpms: rpm-kmod rpm-dkms rpm-utils
+
+rpm-local:
+	@(if test "${HAVE_RPMBUILD}" = "no"; then \
+		echo -e "\n" \
+	"*** Required util ${RPMBUILD} missing.  Please install the\n" \
+	"*** package for your distribution which provides ${RPMBUILD},\n" \
+	"*** re-run configure, and try again.\n"; \
+		exit 1; \
+	fi; \
+	mkdir -p $(rpmbuild)/TMP && \
+	mkdir -p $(rpmbuild)/BUILD && \
+	mkdir -p $(rpmbuild)/RPMS && \
+	mkdir -p $(rpmbuild)/SRPMS && \
+	mkdir -p $(rpmbuild)/SPECS && \
+	cp ${RPM_SPEC_DIR}/$(rpmspec) $(rpmbuild)/SPECS && \
+	mkdir -p $(rpmbuild)/SOURCES && \
+	cp $(top_srcdir)/scripts/kmodtool $(rpmbuild)/SOURCES && \
+	cp $(distdir).tar.gz $(rpmbuild)/SOURCES)
+
+srpm-common: dist
+	@(dist=`$(RPM) --eval %{?dist}`; \
+	rpmpkg=$(pkg)-$(VERSION)-$(RELEASE)$$dist*src.rpm; \
+	rpmspec=$(pkg).spec; \
+	rpmbuild=`mktemp -t -d $(PACKAGE)-build-$$USER-XXXXXXXX`; \
+	$(MAKE) $(AM_MAKEFLAGS) \
+		rpmbuild="$$rpmbuild" \
+		rpmspec="$$rpmspec" \
+		rpm-local || exit 1; \
+	LANG=C $(RPMBUILD) \
+		--define "_tmppath $$rpmbuild/TMP" \
+		--define "_topdir $$rpmbuild" \
+		$(def) -bs $$rpmbuild/SPECS/$$rpmspec || exit 1; \
+	cp $$rpmbuild/SRPMS/$$rpmpkg . || exit 1; \
+	rm -R $$rpmbuild)
+
+rpm-common: 
+	@(dist=`$(RPM) --eval %{?dist}`; \
+	rpmpkg=$(pkg)-$(VERSION)-$(RELEASE)$$dist*src.rpm; \
+	rpmspec=$(pkg).spec; \
+	rpmbuild=`mktemp -t -d $(PACKAGE)-build-$$USER-XXXXXXXX`; \
+	$(MAKE) $(AM_MAKEFLAGS) \
+		rpmbuild="$$rpmbuild" \
+		rpmspec="$$rpmspec" \
+		rpm-local || exit 1; \
+	LANG=C ${RPMBUILD} \
+		--define "_tmppath $$rpmbuild/TMP" \
+		--define "_topdir $$rpmbuild" \
+		$(def) --rebuild $$rpmpkg || exit 1; \
+	cp $$rpmbuild/RPMS/*/* . || exit 1; \
+	rm -R $$rpmbuild)
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/config/tgz.am
@@ -0,0 +1,32 @@
+tgz-local:
+	@(if test "${HAVE_ALIEN}" = "no"; then \
+		echo -e "\n" \
+	"*** Required util ${ALIEN} missing.  Please install the\n" \
+        "*** package for your distribution which provides ${ALIEN},\n" \
+	"*** re-run configure, and try again.\n"; \
+                exit 1; \
+	fi)
+
+tgz-kmod: tgz-local rpm-kmod
+if CONFIG_KERNEL
+	name=${PACKAGE}; \
+	version=${VERSION}-${RELEASE}; \
+	arch=`$(RPM) -qp $${name}-kmod-$${version}.src.rpm --qf %{arch} | tail -1`; \
+	pkg1=kmod-$${name}*$${version}.$${arch}.rpm; \
+	fakeroot $(ALIEN) --scripts --to-tgz $$pkg1; \
+	$(RM) $$pkg1
+endif
+
+tgz-utils: tgz-local rpm-utils
+if CONFIG_USER
+	name=${PACKAGE}; \
+	version=${VERSION}-${RELEASE}; \
+	arch=`$(RPM) -qp $${name}-$${version}.src.rpm --qf %{arch} | tail -1`; \
+	pkg1=$${name}-$${version}.$${arch}.rpm; \
+	pkg2=$${name}-devel-$${version}.$${arch}.rpm; \
+	pkg3=$${name}-test-$${version}.$${arch}.rpm; \
+	fakeroot $(ALIEN) --scripts --to-tgz $$pkg1 $$pkg2 $$pkg3; \
+	$(RM) $$pkg1 $$pkg2 $$pkg3
+endif
+
+tgz: tgz-kmod tgz-utils
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/config/user-arch.m4
@@ -0,0 +1,19 @@
+dnl #
+dnl # Set the target arch for libspl atomic implementation
+dnl #
+AC_DEFUN([ZFS_AC_CONFIG_USER_ARCH], [
+	AC_MSG_CHECKING(for target asm dir)
+	TARGET_ARCH=`echo ${target_cpu} | sed -e s/i.86/i386/`
+
+	case $TARGET_ARCH in
+	i386|x86_64)
+		TARGET_ASM_DIR=asm-${TARGET_ARCH}
+		;;
+	*)
+		TARGET_ASM_DIR=asm-generic
+		;;
+	esac
+
+	AC_SUBST([TARGET_ASM_DIR])
+	AC_MSG_RESULT([$TARGET_ASM_DIR])
+])
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/config/user-dracut.m4
@@ -0,0 +1,22 @@
+AC_DEFUN([ZFS_AC_CONFIG_USER_DRACUT], [
+	AC_MSG_CHECKING(for dracut directory)
+	AC_ARG_WITH([dracutdir],
+		AC_HELP_STRING([--with-dracutdir=DIR],
+		[install dracut helpers @<:@default=check@:>@]),
+		[dracutdir=$withval],
+		[dracutdir=check])
+
+	AS_IF([test "x$dracutdir" = xcheck], [
+		path1=/usr/share/dracut
+		path2=/usr/lib/dracut
+		default=$path2
+
+		AS_IF([test -d "$path1"], [dracutdir="$path1"], [
+			AS_IF([test -d "$path2"], [dracutdir="$path2"],
+				[dracutdir="$default"])
+		])
+	])
+
+	AC_SUBST(dracutdir)
+	AC_MSG_RESULT([$dracutdir])
+])
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/config/user-frame-larger-than.m4
@@ -0,0 +1,22 @@
+dnl #
+dnl # Check if gcc supports -Wframe-larger-than=<size> option.
+dnl #
+AC_DEFUN([ZFS_AC_CONFIG_USER_FRAME_LARGER_THAN], [
+	AC_MSG_CHECKING([for -Wframe-larger-than=<size> support])
+
+	saved_flags="$CFLAGS"
+	CFLAGS="$CFLAGS -Wframe-larger-than=1024"
+
+	AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], [])],
+	[
+		FRAME_LARGER_THAN=-Wframe-larger-than=1024
+		AC_MSG_RESULT([yes])
+	],
+	[
+		FRAME_LARGER_THAN=
+		AC_MSG_RESULT([no])
+	])
+
+	CFLAGS="$saved_flags"
+        AC_SUBST([FRAME_LARGER_THAN])
+])
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/config/user-libblkid.m4
@@ -0,0 +1,113 @@
+dnl #
+dnl # Check for ZFS support in libblkid.  This test needs to check
+dnl # more than if the library exists because we expect there are
+dnl # at least 3 flavors of the library out in the wild:
+dnl #
+dnl #   1) blkid which has no ZFS support
+dnl #   2) blkid with ZFS support and a flawed method of probing
+dnl #   3) blkid with ZFS support and a working method of probing
+dnl #
+dnl # To handle this the check first validates that there is a version
+dnl # of the library installed.  If there is it creates a simulated
+dnl # ZFS filesystem and then links a small test app which attempts
+dnl # to detect the simualated filesystem type.  If it correctly
+dnl # identifies the filesystem as ZFS we can safely assume case 3).
+dnl # Otherwise we disable blkid support and resort to manual probing.
+dnl #
+AC_DEFUN([ZFS_AC_CONFIG_USER_LIBBLKID], [
+	AC_ARG_WITH([blkid],
+		[AS_HELP_STRING([--with-blkid],
+		[support blkid caching @<:@default=check@:>@])],
+		[],
+		[with_blkid=check])
+
+	LIBBLKID=
+	AS_IF([test "x$with_blkid" = xyes],
+	[
+		AC_SUBST([LIBBLKID], ["-lblkid"])
+		AC_DEFINE([HAVE_LIBBLKID], 1,
+			[Define if you have libblkid])
+	])
+
+	AS_IF([test "x$with_blkid" = xcheck],
+	[
+		AC_CHECK_LIB([blkid], [blkid_get_cache],
+		[
+			AC_MSG_CHECKING([for blkid zfs support])
+
+			ZFS_DEV=`mktemp`
+			truncate -s 64M $ZFS_DEV
+			echo -en "\x0c\xb1\xba\0\0\0\0\0" | \
+				dd of=$ZFS_DEV bs=1k count=8 \
+				seek=128 conv=notrunc &>/dev/null \
+				>/dev/null 2>/dev/null
+			echo -en "\x0c\xb1\xba\0\0\0\0\0" | \
+				dd of=$ZFS_DEV bs=1k count=8 \
+				seek=132 conv=notrunc &>/dev/null \
+				>/dev/null 2>/dev/null
+			echo -en "\x0c\xb1\xba\0\0\0\0\0" | \
+				dd of=$ZFS_DEV bs=1k count=8 \
+				seek=136 conv=notrunc &>/dev/null \
+				>/dev/null 2>/dev/null
+			echo -en "\x0c\xb1\xba\0\0\0\0\0" | \
+				dd of=$ZFS_DEV bs=1k count=8 \
+				seek=140 conv=notrunc &>/dev/null \
+				>/dev/null 2>/dev/null
+
+			saved_LIBS="$LIBS"
+			LIBS="-lblkid"
+
+			AC_RUN_IFELSE([AC_LANG_PROGRAM(
+			[
+				#include <stdio.h>
+				#include <stdlib.h>
+				#include <blkid/blkid.h>
+			],
+			[
+				blkid_cache cache;
+				char *value;
+
+			        if (blkid_get_cache(&cache, NULL) < 0)
+					return 1;
+
+				value = blkid_get_tag_value(cache, "TYPE",
+				                            "$ZFS_DEV");
+				if (!value) {
+					blkid_put_cache(cache);
+					return 2;
+				}
+
+				if (strcmp(value, "zfs_member")) {
+					free(value);
+					blkid_put_cache(cache);
+					return 0;
+				}
+
+				free(value);
+				blkid_put_cache(cache);
+			])],
+			[
+				rm -f $ZFS_DEV
+				AC_MSG_RESULT([yes])
+				AC_SUBST([LIBBLKID], ["-lblkid"])
+				AC_DEFINE([HAVE_LIBBLKID], 1,
+					[Define if you have libblkid])
+			],
+			[
+				rm -f $ZFS_DEV
+				AC_MSG_RESULT([no])
+				AS_IF([test "x$with_blkid" != xcheck],
+					[AC_MSG_FAILURE(
+					[--with-blkid given but unavailable])])
+			])
+
+			LIBS="$saved_LIBS"
+		],
+		[
+			AS_IF([test "x$with_blkid" != xcheck],
+				[AC_MSG_FAILURE(
+				[--with-blkid given but unavailable])])
+		]
+		[])
+	])
+])
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/config/user-libuuid.m4
@@ -0,0 +1,18 @@
+dnl #
+dnl # Check for libuuid
+dnl #
+AC_DEFUN([ZFS_AC_CONFIG_USER_LIBUUID], [
+	LIBUUID=
+
+	AC_CHECK_HEADER([uuid/uuid.h], [], [AC_MSG_FAILURE([
+	*** uuid/uuid.h missing, libuuid-devel package required])])
+
+	AC_CHECK_LIB([uuid], [uuid_generate], [], [AC_MSG_FAILURE([
+	*** uuid_generate() missing, libuuid-devel package required])])
+
+	AC_CHECK_LIB([uuid], [uuid_is_null], [], [AC_MSG_FAILURE([
+	*** uuid_is_null() missing, libuuid-devel package required])])
+
+	AC_SUBST([LIBUUID], ["-luuid"])
+	AC_DEFINE([HAVE_LIBUUID], 1, [Define if you have libuuid])
+])
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/config/user-runstatedir.m4
@@ -0,0 +1,6 @@
+dnl For backwards compatibility; runstatedir added in autoconf 2.70.
+AC_DEFUN([ZFS_AC_CONFIG_USER_RUNSTATEDIR], [
+	if test "x$runstatedir" = x; then
+		AC_SUBST([runstatedir], ['${localstatedir}/run'])
+	fi
+])
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/config/user-systemd.m4
@@ -0,0 +1,35 @@
+AC_DEFUN([ZFS_AC_CONFIG_USER_SYSTEMD], [
+	AC_ARG_ENABLE(systemd,
+		AC_HELP_STRING([--enable-systemd],
+		[install systemd unit/preset files [[default: yes]]]),
+		[],enable_systemd=yes)
+
+	AC_ARG_WITH(systemdunitdir,
+		AC_HELP_STRING([--with-systemdunitdir=DIR],
+		[install systemd unit files in dir [[/usr/lib/systemd/system]]]),
+		systemdunitdir=$withval,systemdunitdir=/usr/lib/systemd/system)
+
+	AC_ARG_WITH(systemdpresetdir,
+		AC_HELP_STRING([--with-systemdpresetdir=DIR],
+		[install systemd preset files in dir [[/usr/lib/systemd/system-preset]]]),
+		systemdpresetdir=$withval,systemdpresetdir=/usr/lib/systemd/system-preset)
+
+	AC_ARG_WITH(systemdmodulesloaddir,
+		AC_HELP_STRING([--with-systemdmodulesloaddir=DIR],
+		[install systemd module load files into dir [[/usr/lib/modules-load.d]]]),
+		systemdmoduleloaddir=$withval,systemdmodulesloaddir=/usr/lib/modules-load.d)
+
+
+	AS_IF([test "x$enable_systemd" = xyes],
+		[
+		ZFS_INIT_SYSTEMD=systemd
+		ZFS_MODULE_LOAD=modules-load.d
+		modulesloaddir=$systemdmodulesloaddir
+		])
+
+	AC_SUBST(ZFS_INIT_SYSTEMD)
+	AC_SUBST(ZFS_MODULE_LOAD)
+	AC_SUBST(systemdunitdir)
+	AC_SUBST(systemdpresetdir)
+	AC_SUBST(modulesloaddir)
+])
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/config/user-sysvinit.m4
@@ -0,0 +1,11 @@
+AC_DEFUN([ZFS_AC_CONFIG_USER_SYSVINIT], [
+	AC_ARG_ENABLE(sysvinit,
+		AC_HELP_STRING([--enable-sysvinit],
+		[install SysV init scripts [default: yes]]),
+		[],enable_sysvinit=yes)
+
+	AS_IF([test "x$enable_sysvinit" = xyes],
+		[ZFS_INIT_SYSV=init.d])
+
+	AC_SUBST(ZFS_INIT_SYSV)
+])
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/config/user-udev.m4
@@ -0,0 +1,29 @@
+AC_DEFUN([ZFS_AC_CONFIG_USER_UDEV], [
+	AC_MSG_CHECKING(for udev directories)
+	AC_ARG_WITH(udevdir,
+		AC_HELP_STRING([--with-udevdir=DIR],
+		[install udev helpers @<:@default=check@:>@]),
+		[udevdir=$withval],
+		[udevdir=check])
+
+	AS_IF([test "x$udevdir" = xcheck], [
+		path1=/lib/udev
+		path2=/usr/lib/udev
+		default=$path2
+
+		AS_IF([test -d "$path1"], [udevdir="$path1"], [
+			AS_IF([test -d "$path2"], [udevdir="$path2"],
+				[udevdir="$default"])
+		])
+	])
+
+	AC_ARG_WITH(udevruledir,
+		AC_HELP_STRING([--with-udevruledir=DIR],
+		[install udev rules [[UDEVDIR/rules.d]]]),
+		[udevruledir=$withval],
+		[udevruledir="${udevdir}/rules.d"])
+
+	AC_SUBST(udevdir)
+	AC_SUBST(udevruledir)
+	AC_MSG_RESULT([$udevdir;$udevruledir])
+])
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/config/user-zlib.m4
@@ -0,0 +1,21 @@
+dnl #
+dnl # Check for zlib
+dnl #
+AC_DEFUN([ZFS_AC_CONFIG_USER_ZLIB], [
+	ZLIB=
+
+	AC_CHECK_HEADER([zlib.h], [], [AC_MSG_FAILURE([
+	*** zlib.h missing, zlib-devel package required])])
+
+	AC_CHECK_LIB([z], [compress2], [], [AC_MSG_FAILURE([
+	*** compress2() missing, zlib-devel package required])])
+
+	AC_CHECK_LIB([z], [uncompress], [], [AC_MSG_FAILURE([
+	*** uncompress() missing, zlib-devel package required])])
+
+	AC_CHECK_LIB([z], [crc32], [], [AC_MSG_FAILURE([
+	*** crc32() missing, zlib-devel package required])])
+
+	AC_SUBST([ZLIB], ["-lz"])
+	AC_DEFINE([HAVE_ZLIB], 1, [Define if you have zlib])
+])
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/config/user.m4
@@ -0,0 +1,20 @@
+dnl #
+dnl # Default ZFS user configuration
+dnl #
+AC_DEFUN([ZFS_AC_CONFIG_USER], [
+	ZFS_AC_DKMS_INHIBIT
+	ZFS_AC_CONFIG_USER_MOUNT_HELPER
+	ZFS_AC_CONFIG_USER_UDEV
+	ZFS_AC_CONFIG_USER_SYSTEMD
+	ZFS_AC_CONFIG_USER_SYSVINIT
+	ZFS_AC_CONFIG_USER_DRACUT
+	ZFS_AC_CONFIG_USER_ARCH
+	ZFS_AC_CONFIG_USER_ZLIB
+	ZFS_AC_CONFIG_USER_LIBUUID
+	ZFS_AC_CONFIG_USER_LIBBLKID
+	ZFS_AC_CONFIG_USER_FRAME_LARGER_THAN
+	ZFS_AC_CONFIG_USER_RUNSTATEDIR
+dnl #
+dnl #	Checks for library functions
+	AC_CHECK_FUNCS([mlockall])
+])
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/config/zfs-build.m4
@@ -0,0 +1,347 @@
+AC_DEFUN([ZFS_AC_LICENSE], [
+	AC_MSG_CHECKING([zfs author])
+	AC_MSG_RESULT([$ZFS_META_AUTHOR])
+
+	AC_MSG_CHECKING([zfs license])
+	AC_MSG_RESULT([$ZFS_META_LICENSE])
+])
+
+AC_DEFUN([ZFS_AC_DEBUG], [
+	AC_MSG_CHECKING([whether debugging is enabled])
+	AC_ARG_ENABLE([debug],
+		[AS_HELP_STRING([--enable-debug],
+		[Enable generic debug support @<:@default=no@:>@])],
+		[],
+		[enable_debug=no])
+
+	AS_IF([test "x$enable_debug" = xyes],
+	[
+		KERNELCPPFLAGS="${KERNELCPPFLAGS} -DDEBUG -Werror"
+		HOSTCFLAGS="${HOSTCFLAGS} -DDEBUG -Werror"
+		DEBUG_CFLAGS="-DDEBUG -Werror"
+		DEBUG_STACKFLAGS="-fstack-check"
+		DEBUG_ZFS="_with_debug"
+		AC_DEFINE(ZFS_DEBUG, 1, [zfs debugging enabled])
+	],
+	[
+		KERNELCPPFLAGS="${KERNELCPPFLAGS} -DNDEBUG "
+		HOSTCFLAGS="${HOSTCFLAGS} -DNDEBUG "
+		DEBUG_CFLAGS="-DNDEBUG"
+		DEBUG_STACKFLAGS=""
+		DEBUG_ZFS="_without_debug"
+	])
+
+	AC_SUBST(DEBUG_CFLAGS)
+	AC_SUBST(DEBUG_STACKFLAGS)
+	AC_SUBST(DEBUG_ZFS)
+	AC_MSG_RESULT([$enable_debug])
+])
+
+AC_DEFUN([ZFS_AC_DEBUG_DMU_TX], [
+	AC_ARG_ENABLE([debug-dmu-tx],
+		[AS_HELP_STRING([--enable-debug-dmu-tx],
+		[Enable dmu tx validation @<:@default=no@:>@])],
+		[],
+		[enable_debug_dmu_tx=no])
+
+	AS_IF([test "x$enable_debug_dmu_tx" = xyes],
+	[
+		KERNELCPPFLAGS="${KERNELCPPFLAGS} -DDEBUG_DMU_TX"
+		DEBUG_DMU_TX="_with_debug_dmu_tx"
+		AC_DEFINE([DEBUG_DMU_TX], [1],
+		[Define to 1 to enabled dmu tx validation])
+	],
+	[
+		DEBUG_DMU_TX="_without_debug_dmu_tx"
+	])
+
+	AC_SUBST(DEBUG_DMU_TX)
+	AC_MSG_CHECKING([whether dmu tx validation is enabled])
+	AC_MSG_RESULT([$enable_debug_dmu_tx])
+])
+
+AC_DEFUN([ZFS_AC_CONFIG_ALWAYS], [
+	ZFS_AC_CONFIG_ALWAYS_NO_UNUSED_BUT_SET_VARIABLE
+	ZFS_AC_CONFIG_ALWAYS_NO_BOOL_COMPARE
+])
+
+AC_DEFUN([ZFS_AC_CONFIG], [
+	TARGET_ASM_DIR=asm-generic
+	AC_SUBST(TARGET_ASM_DIR)
+
+	ZFS_CONFIG=all
+	AC_ARG_WITH([config],
+		AS_HELP_STRING([--with-config=CONFIG],
+		[Config file 'kernel|user|all|srpm']),
+		[ZFS_CONFIG="$withval"])
+	AC_ARG_ENABLE([linux-builtin],
+		[AC_HELP_STRING([--enable-linux-builtin],
+		[Configure for builtin in-tree kernel modules @<:@default=no@:>@])],
+		[],
+		[enable_linux_builtin=no])
+
+	AC_MSG_CHECKING([zfs config])
+	AC_MSG_RESULT([$ZFS_CONFIG]);
+	AC_SUBST(ZFS_CONFIG)
+
+	ZFS_AC_CONFIG_ALWAYS
+
+	case "$ZFS_CONFIG" in
+		user)	ZFS_AC_CONFIG_USER   ;;
+		kernel) ZFS_AC_CONFIG_KERNEL ;;
+		all)    ZFS_AC_CONFIG_KERNEL
+			ZFS_AC_CONFIG_USER   ;;
+		srpm)                        ;;
+		*)
+		AC_MSG_RESULT([Error!])
+		AC_MSG_ERROR([Bad value "$ZFS_CONFIG" for --with-config,
+		              user kernel|user|all|srpm]) ;;
+	esac
+
+	AM_CONDITIONAL([CONFIG_USER],
+		       [test "$ZFS_CONFIG" = user -o "$ZFS_CONFIG" = all])
+	AM_CONDITIONAL([CONFIG_KERNEL],
+		       [test "$ZFS_CONFIG" = kernel -o "$ZFS_CONFIG" = all] &&
+		       [test "x$enable_linux_builtin" != xyes ])
+])
+
+dnl #
+dnl # Check for rpm+rpmbuild to build RPM packages.  If these tools
+dnl # are missing it is non-fatal but you will not be able to build
+dnl # RPM packages and will be warned if you try too.
+dnl #
+dnl # By default the generic spec file will be used because it requires
+dnl # minimal dependencies.  Distribution specific spec files can be
+dnl # placed under the 'rpm/<distribution>' directory and enabled using
+dnl # the --with-spec=<distribution> configure option.
+dnl #
+AC_DEFUN([ZFS_AC_RPM], [
+	RPM=rpm
+	RPMBUILD=rpmbuild
+
+	AC_MSG_CHECKING([whether $RPM is available])
+	AS_IF([tmp=$($RPM --version 2>/dev/null)], [
+		RPM_VERSION=$(echo $tmp | $AWK '/RPM/ { print $[3] }')
+		HAVE_RPM=yes
+		AC_MSG_RESULT([$HAVE_RPM ($RPM_VERSION)])
+	],[
+		HAVE_RPM=no
+		AC_MSG_RESULT([$HAVE_RPM])
+	])
+
+	AC_MSG_CHECKING([whether $RPMBUILD is available])
+	AS_IF([tmp=$($RPMBUILD --version 2>/dev/null)], [
+		RPMBUILD_VERSION=$(echo $tmp | $AWK '/RPM/ { print $[3] }')
+		HAVE_RPMBUILD=yes
+		AC_MSG_RESULT([$HAVE_RPMBUILD ($RPMBUILD_VERSION)])
+	],[
+		HAVE_RPMBUILD=no
+		AC_MSG_RESULT([$HAVE_RPMBUILD])
+	])
+
+	RPM_DEFINE_COMMON='--define "$(DEBUG_ZFS) 1" --define "$(DEBUG_DMU_TX) 1"'
+	RPM_DEFINE_UTIL='--define "_dracutdir $(dracutdir)" --define "_udevdir $(udevdir)" --define "_udevruledir $(udevruledir)" --define "_initconfdir $(DEFAULT_INITCONF_DIR)" $(DEFINE_INITRAMFS)'
+	RPM_DEFINE_KMOD='--define "kernels $(LINUX_VERSION)" --define "require_spldir $(SPL)" --define "require_splobj $(SPL_OBJ)" --define "ksrc $(LINUX)" --define "kobj $(LINUX_OBJ)"'
+	RPM_DEFINE_DKMS=
+
+	SRPM_DEFINE_COMMON='--define "build_src_rpm 1"'
+	SRPM_DEFINE_UTIL=
+	SRPM_DEFINE_KMOD=
+	SRPM_DEFINE_DKMS=
+
+	RPM_SPEC_DIR="rpm/generic"
+	AC_ARG_WITH([spec],
+		AS_HELP_STRING([--with-spec=SPEC],
+		[Spec files 'generic|redhat']),
+		[RPM_SPEC_DIR="rpm/$withval"])
+
+	AC_MSG_CHECKING([whether spec files are available])
+	AC_MSG_RESULT([yes ($RPM_SPEC_DIR/*.spec.in)])
+
+	AC_SUBST(HAVE_RPM)
+	AC_SUBST(RPM)
+	AC_SUBST(RPM_VERSION)
+
+	AC_SUBST(HAVE_RPMBUILD)
+	AC_SUBST(RPMBUILD)
+	AC_SUBST(RPMBUILD_VERSION)
+
+	AC_SUBST(RPM_SPEC_DIR)
+	AC_SUBST(RPM_DEFINE_UTIL)
+	AC_SUBST(RPM_DEFINE_KMOD)
+	AC_SUBST(RPM_DEFINE_DKMS)
+	AC_SUBST(RPM_DEFINE_COMMON)
+	AC_SUBST(SRPM_DEFINE_UTIL)
+	AC_SUBST(SRPM_DEFINE_KMOD)
+	AC_SUBST(SRPM_DEFINE_DKMS)
+	AC_SUBST(SRPM_DEFINE_COMMON)
+])
+
+dnl #
+dnl # Check for dpkg+dpkg-buildpackage to build DEB packages.  If these
+dnl # tools are missing it is non-fatal but you will not be able to build
+dnl # DEB packages and will be warned if you try too.
+dnl #
+AC_DEFUN([ZFS_AC_DPKG], [
+	DPKG=dpkg
+	DPKGBUILD=dpkg-buildpackage
+
+	AC_MSG_CHECKING([whether $DPKG is available])
+	AS_IF([tmp=$($DPKG --version 2>/dev/null)], [
+		DPKG_VERSION=$(echo $tmp | $AWK '/Debian/ { print $[7] }')
+		HAVE_DPKG=yes
+		AC_MSG_RESULT([$HAVE_DPKG ($DPKG_VERSION)])
+	],[
+		HAVE_DPKG=no
+		AC_MSG_RESULT([$HAVE_DPKG])
+	])
+
+	AC_MSG_CHECKING([whether $DPKGBUILD is available])
+	AS_IF([tmp=$($DPKGBUILD --version 2>/dev/null)], [
+		DPKGBUILD_VERSION=$(echo $tmp | \
+		    $AWK '/Debian/ { print $[4] }' | cut -f-4 -d'.')
+		HAVE_DPKGBUILD=yes
+		AC_MSG_RESULT([$HAVE_DPKGBUILD ($DPKGBUILD_VERSION)])
+	],[
+		HAVE_DPKGBUILD=no
+		AC_MSG_RESULT([$HAVE_DPKGBUILD])
+	])
+
+	AC_SUBST(HAVE_DPKG)
+	AC_SUBST(DPKG)
+	AC_SUBST(DPKG_VERSION)
+
+	AC_SUBST(HAVE_DPKGBUILD)
+	AC_SUBST(DPKGBUILD)
+	AC_SUBST(DPKGBUILD_VERSION)
+])
+
+dnl #
+dnl # Until native packaging for various different packing systems
+dnl # can be added the least we can do is attempt to use alien to
+dnl # convert the RPM packages to the needed package type.  This is
+dnl # a hack but so far it has worked reasonable well.
+dnl #
+AC_DEFUN([ZFS_AC_ALIEN], [
+	ALIEN=alien
+
+	AC_MSG_CHECKING([whether $ALIEN is available])
+	AS_IF([tmp=$($ALIEN --version 2>/dev/null)], [
+		ALIEN_VERSION=$(echo $tmp | $AWK '{ print $[3] }')
+		HAVE_ALIEN=yes
+		AC_MSG_RESULT([$HAVE_ALIEN ($ALIEN_VERSION)])
+	],[
+		HAVE_ALIEN=no
+		AC_MSG_RESULT([$HAVE_ALIEN])
+	])
+
+	AC_SUBST(HAVE_ALIEN)
+	AC_SUBST(ALIEN)
+	AC_SUBST(ALIEN_VERSION)
+])
+
+dnl #
+dnl # Using the VENDOR tag from config.guess set the default
+dnl # package type for 'make pkg': (rpm | deb | tgz)
+dnl #
+AC_DEFUN([ZFS_AC_DEFAULT_PACKAGE], [
+	AC_MSG_CHECKING([linux distribution])
+	if test -f /etc/toss-release ; then
+		VENDOR=toss ;
+	elif test -f /etc/fedora-release ; then
+		VENDOR=fedora ;
+	elif test -f /etc/redhat-release ; then
+		VENDOR=redhat ;
+	elif test -f /etc/gentoo-release ; then
+		VENDOR=gentoo ;
+	elif test -f /etc/arch-release ; then
+		VENDOR=arch ;
+	elif test -f /etc/SuSE-release ; then
+		VENDOR=sles ;
+	elif test -f /etc/slackware-version ; then
+		VENDOR=slackware ;
+	elif test -f /etc/lunar.release ; then
+		VENDOR=lunar ;
+	elif test -f /etc/lsb-release ; then
+		VENDOR=ubuntu ;
+	elif test -f /etc/debian_version ; then
+		VENDOR=debian ;
+	else
+		VENDOR= ;
+	fi
+	AC_MSG_RESULT([$VENDOR])
+	AC_SUBST(VENDOR)
+
+	AC_MSG_CHECKING([default package type])
+	case "$VENDOR" in
+		toss)       DEFAULT_PACKAGE=rpm  ;;
+		redhat)     DEFAULT_PACKAGE=rpm  ;;
+		fedora)     DEFAULT_PACKAGE=rpm  ;;
+		gentoo)     DEFAULT_PACKAGE=tgz  ;;
+		arch)       DEFAULT_PACKAGE=tgz  ;;
+		sles)       DEFAULT_PACKAGE=rpm  ;;
+		slackware)  DEFAULT_PACKAGE=tgz  ;;
+		lunar)      DEFAULT_PACKAGE=tgz  ;;
+		ubuntu)     DEFAULT_PACKAGE=deb  ;;
+		debian)     DEFAULT_PACKAGE=deb  ;;
+		*)          DEFAULT_PACKAGE=rpm  ;;
+	esac
+	AC_MSG_RESULT([$DEFAULT_PACKAGE])
+	AC_SUBST(DEFAULT_PACKAGE)
+
+	DEFAULT_INIT_DIR=$sysconfdir/init.d
+	AC_MSG_CHECKING([default init directory])
+	AC_MSG_RESULT([$DEFAULT_INIT_DIR])
+	AC_SUBST(DEFAULT_INIT_DIR)
+
+	AC_MSG_CHECKING([default init script type])
+	case "$VENDOR" in
+		toss)       DEFAULT_INIT_SCRIPT=redhat ;;
+		redhat)     DEFAULT_INIT_SCRIPT=redhat ;;
+		fedora)     DEFAULT_INIT_SCRIPT=fedora ;;
+		gentoo)     DEFAULT_INIT_SCRIPT=gentoo ;;
+		arch)       DEFAULT_INIT_SCRIPT=lsb    ;;
+		sles)       DEFAULT_INIT_SCRIPT=lsb    ;;
+		slackware)  DEFAULT_INIT_SCRIPT=lsb    ;;
+		lunar)      DEFAULT_INIT_SCRIPT=lunar  ;;
+		ubuntu)     DEFAULT_INIT_SCRIPT=lsb    ;;
+		debian)     DEFAULT_INIT_SCRIPT=lsb    ;;
+		*)          DEFAULT_INIT_SCRIPT=lsb    ;;
+	esac
+	AC_MSG_RESULT([$DEFAULT_INIT_SCRIPT])
+	AC_SUBST(DEFAULT_INIT_SCRIPT)
+
+	AC_MSG_CHECKING([default init config direectory])
+	case "$VENDOR" in
+		gentoo)     DEFAULT_INITCONF_DIR=/etc/conf.d    ;;
+		toss)       DEFAULT_INITCONF_DIR=/etc/sysconfig ;;
+		redhat)     DEFAULT_INITCONF_DIR=/etc/sysconfig ;;
+		fedora)     DEFAULT_INITCONF_DIR=/etc/sysconfig ;;
+		sles)       DEFAULT_INITCONF_DIR=/etc/sysconfig ;;
+		ubuntu)     DEFAULT_INITCONF_DIR=/etc/default   ;;
+		debian)     DEFAULT_INITCONF_DIR=/etc/default   ;;
+		*)          DEFAULT_INITCONF_DIR=/etc/default   ;;
+	esac
+	AC_MSG_RESULT([$DEFAULT_INITCONF_DIR])
+	AC_SUBST(DEFAULT_INITCONF_DIR)
+
+	AC_MSG_CHECKING([whether initramfs-tools is available])
+	if test -d /usr/share/initramfs-tools ; then
+		DEFINE_INITRAMFS='--define "_initramfs 1"'
+		AC_MSG_RESULT([yes])
+	else
+		DEFINE_INITRAMFS=''
+		AC_MSG_RESULT([no])
+	fi
+	AC_SUBST(DEFINE_INITRAMFS)
+])
+
+dnl #
+dnl # Default ZFS package configuration
+dnl #
+AC_DEFUN([ZFS_AC_PACKAGE], [
+	ZFS_AC_DEFAULT_PACKAGE
+	ZFS_AC_RPM
+	ZFS_AC_DPKG
+	ZFS_AC_ALIEN
+])
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/config/zfs-meta.m4
@@ -0,0 +1,197 @@
+dnl #
+dnl # DESCRIPTION:
+dnl # Read meta data from the META file or the debian/changelog file if it
+dnl # exists.  When building from a git repository the ZFS_META_RELEASE field
+dnl # will be overwritten if there is an annotated tag matching the form
+dnl # ZFS_META_NAME-ZFS_META_VERSION-*.  This allows for working builds to be
+dnl # uniquely identified using the git commit hash.
+dnl #
+dnl #    The META file format is as follows:
+dnl #      ^[ ]*KEY:[ \t]+VALUE$
+dnl #
+dnl #    In other words:
+dnl #    - KEY is separated from VALUE by a colon and one or more spaces/tabs.
+dnl #    - KEY and VALUE are case sensitive.
+dnl #    - Leading spaces are ignored.
+dnl #    - First match wins for duplicate keys.
+dnl #
+dnl #    A line can be commented out by preceding it with a '#' (or technically
+dnl #    any non-space character since that will prevent the regex from
+dnl #    matching).
+dnl #
+dnl # WARNING:
+dnl #   Placing a colon followed by a space or tab (ie, ":[ \t]+") within the
+dnl #   VALUE will prematurely terminate the string since that sequence is
+dnl #   used as the awk field separator.
+dnl #
+dnl # KEYS:
+dnl #   The following META keys are recognized:
+dnl #     Name, Version, Release, Date, Author, LT_Current, LT_Revision, LT_Age
+dnl #
+dnl # Written by Chris Dunlap <cdunlap@llnl.gov>.
+dnl # Modified by Brian Behlendorf <behlendorf1@llnl.gov>.
+dnl #
+AC_DEFUN([ZFS_AC_META], [
+
+	AH_BOTTOM([
+#undef PACKAGE
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+#undef STDC_HEADERS
+#undef VERSION])
+
+	AC_PROG_AWK
+	AC_MSG_CHECKING([metadata])
+
+	META="$srcdir/META"
+	_zfs_ac_meta_type="none"
+	if test -f "$META"; then
+		_zfs_ac_meta_type="META file"
+		_dpkg_parsechangelog=$(dpkg-parsechangelog 2>/dev/null)
+
+		ZFS_META_NAME=_ZFS_AC_META_GETVAL([(Name|Project|Package)]);
+		if test -n "$ZFS_META_NAME"; then
+			AC_DEFINE_UNQUOTED([ZFS_META_NAME], ["$ZFS_META_NAME"],
+				[Define the project name.]
+			)
+			AC_SUBST([ZFS_META_NAME])
+		fi
+
+		ZFS_META_VERSION=_ZFS_AC_META_GETVAL([Version]);
+		if test -n "$ZFS_META_VERSION"; then
+			AC_DEFINE_UNQUOTED([ZFS_META_VERSION], ["$ZFS_META_VERSION"],
+				[Define the project version.]
+			)
+			AC_SUBST([ZFS_META_VERSION])
+		fi
+
+		if test -n "${_dpkg_parsechangelog}"; then
+			_dpkg_version=$(echo "${_dpkg_parsechangelog}" \
+				| $AWK '$[]1 == "Version:" { print $[]2; }' \
+				| cut -d- -f1)
+			if test "${_dpkg_version}" != "$ZFS_META_VERSION"; then
+				AC_MSG_ERROR([
+	*** Version $ZFS_META_VERSION in the META file is different than
+	*** version $_dpkg_version in the debian/changelog file. DKMS and DEB
+	*** packaging require that these files have the same version.
+				])
+			fi
+		fi
+
+		ZFS_META_RELEASE=_ZFS_AC_META_GETVAL([Release]);
+
+		if test -n "${_dpkg_parsechangelog}"; then
+			_dpkg_release=$(echo "${_dpkg_parsechangelog}" \
+				| $AWK '$[]1 == "Version:" { print $[]2; }' \
+				| cut -d- -f2-)
+			if test -n "${_dpkg_release}"; then
+				ZFS_META_RELEASE=${_dpkg_release}
+				_zfs_ac_meta_type="dpkg-parsechangelog"
+			fi
+		elif test ! -f ".nogitrelease" && git rev-parse --git-dir > /dev/null 2>&1; then
+			_match="${ZFS_META_NAME}-${ZFS_META_VERSION}"
+			_alias=$(git describe --match=${_match} 2>/dev/null)
+			_release=$(echo ${_alias}|cut -f3- -d'-'|sed 's/-/_/g')
+			if test -n "${_release}"; then
+				ZFS_META_RELEASE=${_release}
+				_zfs_ac_meta_type="git describe"
+			fi
+		fi
+
+		if test -n "$ZFS_META_RELEASE"; then
+			AC_DEFINE_UNQUOTED([ZFS_META_RELEASE], ["$ZFS_META_RELEASE"],
+				[Define the project release.]
+			)
+			AC_SUBST([ZFS_META_RELEASE])
+
+			RELEASE="$ZFS_META_RELEASE"
+			AC_SUBST([RELEASE])
+		fi
+
+		ZFS_META_LICENSE=_ZFS_AC_META_GETVAL([License]);
+		if test -n "$ZFS_META_LICENSE"; then
+			AC_DEFINE_UNQUOTED([ZFS_META_LICENSE], ["$ZFS_META_LICENSE"],
+				[Define the project license.]
+			)
+			AC_SUBST([ZFS_META_LICENSE])
+		fi
+
+		if test -n "$ZFS_META_NAME" -a -n "$ZFS_META_VERSION"; then
+				ZFS_META_ALIAS="$ZFS_META_NAME-$ZFS_META_VERSION"
+				test -n "$ZFS_META_RELEASE" && 
+				        ZFS_META_ALIAS="$ZFS_META_ALIAS-$ZFS_META_RELEASE"
+				AC_DEFINE_UNQUOTED([ZFS_META_ALIAS],
+					["$ZFS_META_ALIAS"],
+					[Define the project alias string.] 
+				)
+				AC_SUBST([ZFS_META_ALIAS])
+		fi
+
+		ZFS_META_DATA=_ZFS_AC_META_GETVAL([Date]);
+		if test -n "$ZFS_META_DATA"; then
+			AC_DEFINE_UNQUOTED([ZFS_META_DATA], ["$ZFS_META_DATA"],
+				[Define the project release date.] 
+			)
+			AC_SUBST([ZFS_META_DATA])
+		fi
+
+		ZFS_META_AUTHOR=_ZFS_AC_META_GETVAL([Author]);
+		if test -n "$ZFS_META_AUTHOR"; then
+			AC_DEFINE_UNQUOTED([ZFS_META_AUTHOR], ["$ZFS_META_AUTHOR"],
+				[Define the project author.]
+			)
+			AC_SUBST([ZFS_META_AUTHOR])
+		fi
+
+		m4_pattern_allow([^LT_(CURRENT|REVISION|AGE)$])
+		ZFS_META_LT_CURRENT=_ZFS_AC_META_GETVAL([LT_Current]);
+		ZFS_META_LT_REVISION=_ZFS_AC_META_GETVAL([LT_Revision]);
+		ZFS_META_LT_AGE=_ZFS_AC_META_GETVAL([LT_Age]);
+		if test -n "$ZFS_META_LT_CURRENT" \
+				 -o -n "$ZFS_META_LT_REVISION" \
+				 -o -n "$ZFS_META_LT_AGE"; then
+			test -n "$ZFS_META_LT_CURRENT" || ZFS_META_LT_CURRENT="0"
+			test -n "$ZFS_META_LT_REVISION" || ZFS_META_LT_REVISION="0"
+			test -n "$ZFS_META_LT_AGE" || ZFS_META_LT_AGE="0"
+			AC_DEFINE_UNQUOTED([ZFS_META_LT_CURRENT],
+				["$ZFS_META_LT_CURRENT"],
+				[Define the libtool library 'current'
+				 version information.]
+			)
+			AC_DEFINE_UNQUOTED([ZFS_META_LT_REVISION],
+				["$ZFS_META_LT_REVISION"],
+				[Define the libtool library 'revision'
+				 version information.]
+			)
+			AC_DEFINE_UNQUOTED([ZFS_META_LT_AGE], ["$ZFS_META_LT_AGE"],
+				[Define the libtool library 'age' 
+				 version information.]
+			)
+			AC_SUBST([ZFS_META_LT_CURRENT])
+			AC_SUBST([ZFS_META_LT_REVISION])
+			AC_SUBST([ZFS_META_LT_AGE])
+		fi
+	fi
+
+	AC_MSG_RESULT([$_zfs_ac_meta_type])
+	]
+)
+
+dnl # _ZFS_AC_META_GETVAL (KEY_NAME_OR_REGEX)
+dnl #
+dnl # Returns the META VALUE associated with the given KEY_NAME_OR_REGEX expr.
+dnl #
+dnl # Despite their resemblance to line noise,
+dnl #   the "@<:@" and "@:>@" constructs are quadrigraphs for "[" and "]".
+dnl #   <www.gnu.org/software/autoconf/manual/autoconf.html#Quadrigraphs>
+dnl #
+dnl # The "$[]1" and "$[]2" constructs prevent M4 parameter expansion
+dnl #   so a literal $1 and $2 will be passed to the resulting awk script,
+dnl #   whereas the "$1" will undergo M4 parameter expansion for the META key.
+dnl #
+AC_DEFUN([_ZFS_AC_META_GETVAL],
+	[`$AWK -F ':@<:@ \t@:>@+' '$[]1 ~ /^ *$1$/ { print $[]2; exit }' $META`]dnl
+)
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/configure
@@ -0,0 +1,34870 @@
+#! /bin/sh
+# Guess values for system-dependent variables and create Makefiles.
+# Generated by GNU Autoconf 2.69 for zfs 0.6.5.6.
+#
+#
+# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
+#
+#
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+## -------------------- ##
+## M4sh Initialization. ##
+## -------------------- ##
+
+# Be more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
+  emulate sh
+  NULLCMD=:
+  # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+  setopt NO_GLOB_SUBST
+else
+  case `(set -o) 2>/dev/null` in #(
+  *posix*) :
+    set -o posix ;; #(
+  *) :
+     ;;
+esac
+fi
+
+
+as_nl='
+'
+export as_nl
+# Printing a long string crashes Solaris 7 /usr/bin/printf.
+as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
+# Prefer a ksh shell builtin over an external printf program on Solaris,
+# but without wasting forks for bash or zsh.
+if test -z "$BASH_VERSION$ZSH_VERSION" \
+    && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
+  as_echo='print -r --'
+  as_echo_n='print -rn --'
+elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
+  as_echo='printf %s\n'
+  as_echo_n='printf %s'
+else
+  if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
+    as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
+    as_echo_n='/usr/ucb/echo -n'
+  else
+    as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
+    as_echo_n_body='eval
+      arg=$1;
+      case $arg in #(
+      *"$as_nl"*)
+	expr "X$arg" : "X\\(.*\\)$as_nl";
+	arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
+      esac;
+      expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
+    '
+    export as_echo_n_body
+    as_echo_n='sh -c $as_echo_n_body as_echo'
+  fi
+  export as_echo_body
+  as_echo='sh -c $as_echo_body as_echo'
+fi
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  PATH_SEPARATOR=:
+  (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+    (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+      PATH_SEPARATOR=';'
+  }
+fi
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.  Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+IFS=" ""	$as_nl"
+
+# Find who we are.  Look in the path if we contain no directory separator.
+as_myself=
+case $0 in #((
+  *[\\/]* ) as_myself=$0 ;;
+  *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+  done
+IFS=$as_save_IFS
+
+     ;;
+esac
+# We did not find ourselves, most probably we were run as `sh COMMAND'
+# in which case we are not to be found in the path.
+if test "x$as_myself" = x; then
+  as_myself=$0
+fi
+if test ! -f "$as_myself"; then
+  $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+  exit 1
+fi
+
+# Unset variables that we do not need and which cause bugs (e.g. in
+# pre-3.0 UWIN ksh).  But do not cause bugs in bash 2.01; the "|| exit 1"
+# suppresses any "Segmentation fault" message there.  '((' could
+# trigger a bug in pdksh 5.2.14.
+for as_var in BASH_ENV ENV MAIL MAILPATH
+do eval test x\${$as_var+set} = xset \
+  && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
+done
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# CDPATH.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+# Use a proper internal environment variable to ensure we don't fall
+  # into an infinite loop, continuously re-executing ourselves.
+  if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then
+    _as_can_reexec=no; export _as_can_reexec;
+    # We cannot yet assume a decent shell, so we have to provide a
+# neutralization value for shells without unset; and this also
+# works around shells that cannot unset nonexistent variables.
+# Preserve -v and -x to the replacement shell.
+BASH_ENV=/dev/null
+ENV=/dev/null
+(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+case $- in # ((((
+  *v*x* | *x*v* ) as_opts=-vx ;;
+  *v* ) as_opts=-v ;;
+  *x* ) as_opts=-x ;;
+  * ) as_opts= ;;
+esac
+exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
+# Admittedly, this is quite paranoid, since all the known shells bail
+# out after a failed `exec'.
+$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
+as_fn_exit 255
+  fi
+  # We don't want this to propagate to other subprocesses.
+          { _as_can_reexec=; unset _as_can_reexec;}
+if test "x$CONFIG_SHELL" = x; then
+  as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then :
+  emulate sh
+  NULLCMD=:
+  # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '\${1+\"\$@\"}'='\"\$@\"'
+  setopt NO_GLOB_SUBST
+else
+  case \`(set -o) 2>/dev/null\` in #(
+  *posix*) :
+    set -o posix ;; #(
+  *) :
+     ;;
+esac
+fi
+"
+  as_required="as_fn_return () { (exit \$1); }
+as_fn_success () { as_fn_return 0; }
+as_fn_failure () { as_fn_return 1; }
+as_fn_ret_success () { return 0; }
+as_fn_ret_failure () { return 1; }
+
+exitcode=0
+as_fn_success || { exitcode=1; echo as_fn_success failed.; }
+as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; }
+as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; }
+as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; }
+if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then :
+
+else
+  exitcode=1; echo positional parameters were not saved.
+fi
+test x\$exitcode = x0 || exit 1
+test -x / || exit 1"
+  as_suggested="  as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO
+  as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO
+  eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" &&
+  test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1
+
+  test -n \"\${ZSH_VERSION+set}\${BASH_VERSION+set}\" || (
+    ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+    ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO
+    ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO
+    PATH=/empty FPATH=/empty; export PATH FPATH
+    test \"X\`printf %s \$ECHO\`\" = \"X\$ECHO\" \\
+      || test \"X\`print -r -- \$ECHO\`\" = \"X\$ECHO\" ) || exit 1
+test \$(( 1 + 1 )) = 2 || exit 1"
+  if (eval "$as_required") 2>/dev/null; then :
+  as_have_required=yes
+else
+  as_have_required=no
+fi
+  if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then :
+
+else
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+as_found=false
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  as_found=:
+  case $as_dir in #(
+	 /*)
+	   for as_base in sh bash ksh sh5; do
+	     # Try only shells that exist, to save several forks.
+	     as_shell=$as_dir/$as_base
+	     if { test -f "$as_shell" || test -f "$as_shell.exe"; } &&
+		    { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then :
+  CONFIG_SHELL=$as_shell as_have_required=yes
+		   if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then :
+  break 2
+fi
+fi
+	   done;;
+       esac
+  as_found=false
+done
+$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } &&
+	      { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then :
+  CONFIG_SHELL=$SHELL as_have_required=yes
+fi; }
+IFS=$as_save_IFS
+
+
+      if test "x$CONFIG_SHELL" != x; then :
+  export CONFIG_SHELL
+             # We cannot yet assume a decent shell, so we have to provide a
+# neutralization value for shells without unset; and this also
+# works around shells that cannot unset nonexistent variables.
+# Preserve -v and -x to the replacement shell.
+BASH_ENV=/dev/null
+ENV=/dev/null
+(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+case $- in # ((((
+  *v*x* | *x*v* ) as_opts=-vx ;;
+  *v* ) as_opts=-v ;;
+  *x* ) as_opts=-x ;;
+  * ) as_opts= ;;
+esac
+exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
+# Admittedly, this is quite paranoid, since all the known shells bail
+# out after a failed `exec'.
+$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
+exit 255
+fi
+
+    if test x$as_have_required = xno; then :
+  $as_echo "$0: This script requires a shell more modern than all"
+  $as_echo "$0: the shells that I found on your system."
+  if test x${ZSH_VERSION+set} = xset ; then
+    $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should"
+    $as_echo "$0: be upgraded to zsh 4.3.4 or later."
+  else
+    $as_echo "$0: Please tell bug-autoconf@gnu.org about your system,
+$0: including any error possibly output before this
+$0: message. Then install a modern shell, or manually run
+$0: the script under such a shell if you do have one."
+  fi
+  exit 1
+fi
+fi
+fi
+SHELL=${CONFIG_SHELL-/bin/sh}
+export SHELL
+# Unset more variables known to interfere with behavior of common tools.
+CLICOLOR_FORCE= GREP_OPTIONS=
+unset CLICOLOR_FORCE GREP_OPTIONS
+
+## --------------------- ##
+## M4sh Shell Functions. ##
+## --------------------- ##
+# as_fn_unset VAR
+# ---------------
+# Portably unset VAR.
+as_fn_unset ()
+{
+  { eval $1=; unset $1;}
+}
+as_unset=as_fn_unset
+
+# as_fn_set_status STATUS
+# -----------------------
+# Set $? to STATUS, without forking.
+as_fn_set_status ()
+{
+  return $1
+} # as_fn_set_status
+
+# as_fn_exit STATUS
+# -----------------
+# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
+as_fn_exit ()
+{
+  set +e
+  as_fn_set_status $1
+  exit $1
+} # as_fn_exit
+
+# as_fn_mkdir_p
+# -------------
+# Create "$as_dir" as a directory, including parents if necessary.
+as_fn_mkdir_p ()
+{
+
+  case $as_dir in #(
+  -*) as_dir=./$as_dir;;
+  esac
+  test -d "$as_dir" || eval $as_mkdir_p || {
+    as_dirs=
+    while :; do
+      case $as_dir in #(
+      *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+      *) as_qdir=$as_dir;;
+      esac
+      as_dirs="'$as_qdir' $as_dirs"
+      as_dir=`$as_dirname -- "$as_dir" ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$as_dir" : 'X\(//\)[^/]' \| \
+	 X"$as_dir" : 'X\(//\)$' \| \
+	 X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_dir" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+      test -d "$as_dir" && break
+    done
+    test -z "$as_dirs" || eval "mkdir $as_dirs"
+  } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"
+
+
+} # as_fn_mkdir_p
+
+# as_fn_executable_p FILE
+# -----------------------
+# Test if FILE is an executable regular file.
+as_fn_executable_p ()
+{
+  test -f "$1" && test -x "$1"
+} # as_fn_executable_p
+# as_fn_append VAR VALUE
+# ----------------------
+# Append the text in VALUE to the end of the definition contained in VAR. Take
+# advantage of any shell optimizations that allow amortized linear growth over
+# repeated appends, instead of the typical quadratic growth present in naive
+# implementations.
+if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
+  eval 'as_fn_append ()
+  {
+    eval $1+=\$2
+  }'
+else
+  as_fn_append ()
+  {
+    eval $1=\$$1\$2
+  }
+fi # as_fn_append
+
+# as_fn_arith ARG...
+# ------------------
+# Perform arithmetic evaluation on the ARGs, and store the result in the
+# global $as_val. Take advantage of shells that can avoid forks. The arguments
+# must be portable across $(()) and expr.
+if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
+  eval 'as_fn_arith ()
+  {
+    as_val=$(( $* ))
+  }'
+else
+  as_fn_arith ()
+  {
+    as_val=`expr "$@" || test $? -eq 1`
+  }
+fi # as_fn_arith
+
+
+# as_fn_error STATUS ERROR [LINENO LOG_FD]
+# ----------------------------------------
+# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
+# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
+# script with STATUS, using 1 if that was 0.
+as_fn_error ()
+{
+  as_status=$1; test $as_status -eq 0 && as_status=1
+  if test "$4"; then
+    as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+    $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
+  fi
+  $as_echo "$as_me: error: $2" >&2
+  as_fn_exit $as_status
+} # as_fn_error
+
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+   test "X`expr 00001 : '.*\(...\)'`" = X001; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
+  as_basename=basename
+else
+  as_basename=false
+fi
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+  as_dirname=dirname
+else
+  as_dirname=false
+fi
+
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+	 X"$0" : 'X\(//\)$' \| \
+	 X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X/"$0" |
+    sed '/^.*\/\([^/][^/]*\)\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\/\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\/\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+
+  as_lineno_1=$LINENO as_lineno_1a=$LINENO
+  as_lineno_2=$LINENO as_lineno_2a=$LINENO
+  eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" &&
+  test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || {
+  # Blame Lee E. McMahon (1931-1989) for sed's syntax.  :-)
+  sed -n '
+    p
+    /[$]LINENO/=
+  ' <$as_myself |
+    sed '
+      s/[$]LINENO.*/&-/
+      t lineno
+      b
+      :lineno
+      N
+      :loop
+      s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
+      t loop
+      s/-\n.*//
+    ' >$as_me.lineno &&
+  chmod +x "$as_me.lineno" ||
+    { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; }
+
+  # If we had to re-execute with $CONFIG_SHELL, we're ensured to have
+  # already done that, so ensure we don't try to do so again and fall
+  # in an infinite loop.  This has already happened in practice.
+  _as_can_reexec=no; export _as_can_reexec
+  # Don't try to exec as it changes $[0], causing all sort of problems
+  # (the dirname of $[0] is not the place where we might find the
+  # original and so on.  Autoconf is especially sensitive to this).
+  . "./$as_me.lineno"
+  # Exit status is that of the last command.
+  exit
+}
+
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in #(((((
+-n*)
+  case `echo 'xy\c'` in
+  *c*) ECHO_T='	';;	# ECHO_T is single tab character.
+  xy)  ECHO_C='\c';;
+  *)   echo `echo ksh88 bug on AIX 6.1` > /dev/null
+       ECHO_T='	';;
+  esac;;
+*)
+  ECHO_N='-n';;
+esac
+
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+  rm -f conf$$.dir/conf$$.file
+else
+  rm -f conf$$.dir
+  mkdir conf$$.dir 2>/dev/null
+fi
+if (echo >conf$$.file) 2>/dev/null; then
+  if ln -s conf$$.file conf$$ 2>/dev/null; then
+    as_ln_s='ln -s'
+    # ... but there are two gotchas:
+    # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+    # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+    # In both cases, we have to default to `cp -pR'.
+    ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+      as_ln_s='cp -pR'
+  elif ln conf$$.file conf$$ 2>/dev/null; then
+    as_ln_s=ln
+  else
+    as_ln_s='cp -pR'
+  fi
+else
+  as_ln_s='cp -pR'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+if mkdir -p . 2>/dev/null; then
+  as_mkdir_p='mkdir -p "$as_dir"'
+else
+  test -d ./-p && rmdir ./-p
+  as_mkdir_p=false
+fi
+
+as_test_x='test -x'
+as_executable_p=as_fn_executable_p
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+SHELL=${CONFIG_SHELL-/bin/sh}
+
+
+test -n "$DJDIR" || exec 7<&0 </dev/null
+exec 6>&1
+
+# Name of the host.
+# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status,
+# so uname gets run too.
+ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
+
+#
+# Initializations.
+#
+ac_default_prefix=/usr/local
+ac_clean_files=
+ac_config_libobj_dir=.
+LIBOBJS=
+cross_compiling=no
+subdirs=
+MFLAGS=
+MAKEFLAGS=
+
+# Identity of this package.
+PACKAGE_NAME='zfs'
+PACKAGE_TARNAME='zfs'
+PACKAGE_VERSION='0.6.5.6'
+PACKAGE_STRING='zfs 0.6.5.6'
+PACKAGE_BUGREPORT=''
+PACKAGE_URL=''
+
+# Factoring default headers for most tests.
+ac_includes_default="\
+#include <stdio.h>
+#ifdef HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# ifdef HAVE_STDLIB_H
+#  include <stdlib.h>
+# endif
+#endif
+#ifdef HAVE_STRING_H
+# if !defined STDC_HEADERS && defined HAVE_MEMORY_H
+#  include <memory.h>
+# endif
+# include <string.h>
+#endif
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif
+#ifdef HAVE_INTTYPES_H
+# include <inttypes.h>
+#endif
+#ifdef HAVE_STDINT_H
+# include <stdint.h>
+#endif
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif"
+
+ac_subst_vars='am__EXEEXT_FALSE
+am__EXEEXT_TRUE
+LTLIBOBJS
+LIBOBJS
+DEBUG_DMU_TX
+DEBUG_ZFS
+DEBUG_STACKFLAGS
+DEBUG_CFLAGS
+CONFIG_KERNEL_FALSE
+CONFIG_KERNEL_TRUE
+CONFIG_USER_FALSE
+CONFIG_USER_TRUE
+KERNELCPPFLAGS
+KERNELMAKE_PARAMS
+SPL_SYMBOLS
+SPL_VERSION
+SPL_OBJ
+SPL
+LINUX_SYMBOLS
+LINUX_VERSION
+LINUX_OBJ
+LINUX
+FRAME_LARGER_THAN
+LIBBLKID
+LIBUUID
+ZLIB
+dracutdir
+ZFS_INIT_SYSV
+modulesloaddir
+systemdpresetdir
+systemdunitdir
+ZFS_MODULE_LOAD
+ZFS_INIT_SYSTEMD
+udevruledir
+udevdir
+mounthelperdir
+NO_BOOL_COMPARE
+NO_UNUSED_BUT_SET_VARIABLE
+ZFS_CONFIG
+TARGET_ASM_DIR
+ALIEN_VERSION
+ALIEN
+HAVE_ALIEN
+DPKGBUILD_VERSION
+DPKGBUILD
+HAVE_DPKGBUILD
+DPKG_VERSION
+DPKG
+HAVE_DPKG
+SRPM_DEFINE_COMMON
+SRPM_DEFINE_DKMS
+SRPM_DEFINE_KMOD
+SRPM_DEFINE_UTIL
+RPM_DEFINE_COMMON
+RPM_DEFINE_DKMS
+RPM_DEFINE_KMOD
+RPM_DEFINE_UTIL
+RPM_SPEC_DIR
+RPMBUILD_VERSION
+RPMBUILD
+HAVE_RPMBUILD
+RPM_VERSION
+RPM
+HAVE_RPM
+DEFINE_INITRAMFS
+DEFAULT_INITCONF_DIR
+DEFAULT_INIT_SCRIPT
+DEFAULT_INIT_DIR
+DEFAULT_PACKAGE
+VENDOR
+am__fastdepCCAS_FALSE
+am__fastdepCCAS_TRUE
+CCASDEPMODE
+CCASFLAGS
+CCAS
+CPP
+LT_SYS_LIBRARY_PATH
+OTOOL64
+OTOOL
+LIPO
+NMEDIT
+DSYMUTIL
+MANIFEST_TOOL
+RANLIB
+ac_ct_AR
+AR
+DLLTOOL
+OBJDUMP
+LN_S
+NM
+ac_ct_DUMPBIN
+DUMPBIN
+LD
+FGREP
+EGREP
+GREP
+SED
+LIBTOOL
+am__fastdepCC_FALSE
+am__fastdepCC_TRUE
+CCDEPMODE
+am__nodep
+AMDEPBACKSLASH
+AMDEP_FALSE
+AMDEP_TRUE
+am__quote
+am__include
+DEPDIR
+OBJEXT
+EXEEXT
+ac_ct_CC
+CPPFLAGS
+LDFLAGS
+CFLAGS
+CC
+am__untar
+am__tar
+AMTAR
+am__leading_dot
+SET_MAKE
+mkdir_p
+MKDIR_P
+INSTALL_STRIP_PROGRAM
+STRIP
+install_sh
+MAKEINFO
+AUTOHEADER
+AUTOMAKE
+AUTOCONF
+ACLOCAL
+VERSION
+PACKAGE
+CYGPATH_W
+am__isrc
+INSTALL_DATA
+INSTALL_SCRIPT
+INSTALL_PROGRAM
+AM_BACKSLASH
+AM_DEFAULT_VERBOSITY
+AM_DEFAULT_V
+AM_V
+MAINT
+MAINTAINER_MODE_FALSE
+MAINTAINER_MODE_TRUE
+target_os
+target_vendor
+target_cpu
+target
+host_os
+host_vendor
+host_cpu
+host
+build_os
+build_vendor
+build_cpu
+build
+ZFS_META_LT_AGE
+ZFS_META_LT_REVISION
+ZFS_META_LT_CURRENT
+ZFS_META_AUTHOR
+ZFS_META_DATA
+ZFS_META_ALIAS
+ZFS_META_LICENSE
+RELEASE
+ZFS_META_RELEASE
+ZFS_META_VERSION
+ZFS_META_NAME
+AWK
+target_alias
+host_alias
+build_alias
+LIBS
+ECHO_T
+ECHO_N
+ECHO_C
+DEFS
+mandir
+localedir
+libdir
+psdir
+pdfdir
+dvidir
+htmldir
+infodir
+docdir
+oldincludedir
+includedir
+runstatedir
+localstatedir
+sharedstatedir
+sysconfdir
+datadir
+datarootdir
+libexecdir
+sbindir
+bindir
+program_transform_name
+prefix
+exec_prefix
+PACKAGE_URL
+PACKAGE_BUGREPORT
+PACKAGE_STRING
+PACKAGE_VERSION
+PACKAGE_TARNAME
+PACKAGE_NAME
+PATH_SEPARATOR
+SHELL'
+ac_subst_files=''
+ac_user_opts='
+enable_option_checking
+enable_maintainer_mode
+enable_silent_rules
+enable_dependency_tracking
+enable_shared
+enable_static
+with_pic
+enable_fast_install
+with_aix_soname
+with_gnu_ld
+with_sysroot
+enable_libtool_lock
+with_spec
+with_config
+enable_linux_builtin
+with_mounthelperdir
+with_udevdir
+with_udevruledir
+enable_systemd
+with_systemdunitdir
+with_systemdpresetdir
+with_systemdmodulesloaddir
+enable_sysvinit
+with_dracutdir
+with_blkid
+with_linux
+with_linux_obj
+with_spl
+with_spl_obj
+with_spl_timeout
+enable_debug
+enable_debug_dmu_tx
+'
+      ac_precious_vars='build_alias
+host_alias
+target_alias
+CC
+CFLAGS
+LDFLAGS
+LIBS
+CPPFLAGS
+LT_SYS_LIBRARY_PATH
+CPP
+CCAS
+CCASFLAGS'
+
+
+# Initialize some variables set by options.
+ac_init_help=
+ac_init_version=false
+ac_unrecognized_opts=
+ac_unrecognized_sep=
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+cache_file=/dev/null
+exec_prefix=NONE
+no_create=
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+verbose=
+x_includes=NONE
+x_libraries=NONE
+
+# Installation directory options.
+# These are left unexpanded so users can "make install exec_prefix=/foo"
+# and all the variables that are supposed to be based on exec_prefix
+# by default will actually change.
+# Use braces instead of parens because sh, perl, etc. also accept them.
+# (The list follows the same order as the GNU Coding Standards.)
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datarootdir='${prefix}/share'
+datadir='${datarootdir}'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+runstatedir='${localstatedir}/run'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
+infodir='${datarootdir}/info'
+htmldir='${docdir}'
+dvidir='${docdir}'
+pdfdir='${docdir}'
+psdir='${docdir}'
+libdir='${exec_prefix}/lib'
+localedir='${datarootdir}/locale'
+mandir='${datarootdir}/man'
+
+ac_prev=
+ac_dashdash=
+for ac_option
+do
+  # If the previous option needs an argument, assign it.
+  if test -n "$ac_prev"; then
+    eval $ac_prev=\$ac_option
+    ac_prev=
+    continue
+  fi
+
+  case $ac_option in
+  *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;;
+  *=)   ac_optarg= ;;
+  *)    ac_optarg=yes ;;
+  esac
+
+  # Accept the important Cygnus configure options, so we can diagnose typos.
+
+  case $ac_dashdash$ac_option in
+  --)
+    ac_dashdash=yes ;;
+
+  -bindir | --bindir | --bindi | --bind | --bin | --bi)
+    ac_prev=bindir ;;
+  -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+    bindir=$ac_optarg ;;
+
+  -build | --build | --buil | --bui | --bu)
+    ac_prev=build_alias ;;
+  -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+    build_alias=$ac_optarg ;;
+
+  -cache-file | --cache-file | --cache-fil | --cache-fi \
+  | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+    ac_prev=cache_file ;;
+  -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+  | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+    cache_file=$ac_optarg ;;
+
+  --config-cache | -C)
+    cache_file=config.cache ;;
+
+  -datadir | --datadir | --datadi | --datad)
+    ac_prev=datadir ;;
+  -datadir=* | --datadir=* | --datadi=* | --datad=*)
+    datadir=$ac_optarg ;;
+
+  -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \
+  | --dataroo | --dataro | --datar)
+    ac_prev=datarootdir ;;
+  -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \
+  | --dataroot=* | --dataroo=* | --dataro=* | --datar=*)
+    datarootdir=$ac_optarg ;;
+
+  -disable-* | --disable-*)
+    ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+      as_fn_error $? "invalid feature name: $ac_useropt"
+    ac_useropt_orig=$ac_useropt
+    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+    case $ac_user_opts in
+      *"
+"enable_$ac_useropt"
+"*) ;;
+      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig"
+	 ac_unrecognized_sep=', ';;
+    esac
+    eval enable_$ac_useropt=no ;;
+
+  -docdir | --docdir | --docdi | --doc | --do)
+    ac_prev=docdir ;;
+  -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*)
+    docdir=$ac_optarg ;;
+
+  -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv)
+    ac_prev=dvidir ;;
+  -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*)
+    dvidir=$ac_optarg ;;
+
+  -enable-* | --enable-*)
+    ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+      as_fn_error $? "invalid feature name: $ac_useropt"
+    ac_useropt_orig=$ac_useropt
+    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+    case $ac_user_opts in
+      *"
+"enable_$ac_useropt"
+"*) ;;
+      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig"
+	 ac_unrecognized_sep=', ';;
+    esac
+    eval enable_$ac_useropt=\$ac_optarg ;;
+
+  -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+  | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+  | --exec | --exe | --ex)
+    ac_prev=exec_prefix ;;
+  -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+  | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+  | --exec=* | --exe=* | --ex=*)
+    exec_prefix=$ac_optarg ;;
+
+  -gas | --gas | --ga | --g)
+    # Obsolete; use --with-gas.
+    with_gas=yes ;;
+
+  -help | --help | --hel | --he | -h)
+    ac_init_help=long ;;
+  -help=r* | --help=r* | --hel=r* | --he=r* | -hr*)
+    ac_init_help=recursive ;;
+  -help=s* | --help=s* | --hel=s* | --he=s* | -hs*)
+    ac_init_help=short ;;
+
+  -host | --host | --hos | --ho)
+    ac_prev=host_alias ;;
+  -host=* | --host=* | --hos=* | --ho=*)
+    host_alias=$ac_optarg ;;
+
+  -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht)
+    ac_prev=htmldir ;;
+  -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \
+  | --ht=*)
+    htmldir=$ac_optarg ;;
+
+  -includedir | --includedir | --includedi | --included | --include \
+  | --includ | --inclu | --incl | --inc)
+    ac_prev=includedir ;;
+  -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+  | --includ=* | --inclu=* | --incl=* | --inc=*)
+    includedir=$ac_optarg ;;
+
+  -infodir | --infodir | --infodi | --infod | --info | --inf)
+    ac_prev=infodir ;;
+  -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+    infodir=$ac_optarg ;;
+
+  -libdir | --libdir | --libdi | --libd)
+    ac_prev=libdir ;;
+  -libdir=* | --libdir=* | --libdi=* | --libd=*)
+    libdir=$ac_optarg ;;
+
+  -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+  | --libexe | --libex | --libe)
+    ac_prev=libexecdir ;;
+  -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+  | --libexe=* | --libex=* | --libe=*)
+    libexecdir=$ac_optarg ;;
+
+  -localedir | --localedir | --localedi | --localed | --locale)
+    ac_prev=localedir ;;
+  -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*)
+    localedir=$ac_optarg ;;
+
+  -localstatedir | --localstatedir | --localstatedi | --localstated \
+  | --localstate | --localstat | --localsta | --localst | --locals)
+    ac_prev=localstatedir ;;
+  -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+  | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*)
+    localstatedir=$ac_optarg ;;
+
+  -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+    ac_prev=mandir ;;
+  -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+    mandir=$ac_optarg ;;
+
+  -nfp | --nfp | --nf)
+    # Obsolete; use --without-fp.
+    with_fp=no ;;
+
+  -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+  | --no-cr | --no-c | -n)
+    no_create=yes ;;
+
+  -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+  | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+    no_recursion=yes ;;
+
+  -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+  | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+  | --oldin | --oldi | --old | --ol | --o)
+    ac_prev=oldincludedir ;;
+  -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+  | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+  | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+    oldincludedir=$ac_optarg ;;
+
+  -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+    ac_prev=prefix ;;
+  -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+    prefix=$ac_optarg ;;
+
+  -program-prefix | --program-prefix | --program-prefi | --program-pref \
+  | --program-pre | --program-pr | --program-p)
+    ac_prev=program_prefix ;;
+  -program-prefix=* | --program-prefix=* | --program-prefi=* \
+  | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+    program_prefix=$ac_optarg ;;
+
+  -program-suffix | --program-suffix | --program-suffi | --program-suff \
+  | --program-suf | --program-su | --program-s)
+    ac_prev=program_suffix ;;
+  -program-suffix=* | --program-suffix=* | --program-suffi=* \
+  | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+    program_suffix=$ac_optarg ;;
+
+  -program-transform-name | --program-transform-name \
+  | --program-transform-nam | --program-transform-na \
+  | --program-transform-n | --program-transform- \
+  | --program-transform | --program-transfor \
+  | --program-transfo | --program-transf \
+  | --program-trans | --program-tran \
+  | --progr-tra | --program-tr | --program-t)
+    ac_prev=program_transform_name ;;
+  -program-transform-name=* | --program-transform-name=* \
+  | --program-transform-nam=* | --program-transform-na=* \
+  | --program-transform-n=* | --program-transform-=* \
+  | --program-transform=* | --program-transfor=* \
+  | --program-transfo=* | --program-transf=* \
+  | --program-trans=* | --program-tran=* \
+  | --progr-tra=* | --program-tr=* | --program-t=*)
+    program_transform_name=$ac_optarg ;;
+
+  -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd)
+    ac_prev=pdfdir ;;
+  -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*)
+    pdfdir=$ac_optarg ;;
+
+  -psdir | --psdir | --psdi | --psd | --ps)
+    ac_prev=psdir ;;
+  -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*)
+    psdir=$ac_optarg ;;
+
+  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+  | -silent | --silent | --silen | --sile | --sil)
+    silent=yes ;;
+
+  -runstatedir | --runstatedir | --runstatedi | --runstated \
+  | --runstate | --runstat | --runsta | --runst | --runs \
+  | --run | --ru | --r)
+    ac_prev=runstatedir ;;
+  -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \
+  | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \
+  | --run=* | --ru=* | --r=*)
+    runstatedir=$ac_optarg ;;
+
+  -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+    ac_prev=sbindir ;;
+  -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+  | --sbi=* | --sb=*)
+    sbindir=$ac_optarg ;;
+
+  -sharedstatedir | --sharedstatedir | --sharedstatedi \
+  | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+  | --sharedst | --shareds | --shared | --share | --shar \
+  | --sha | --sh)
+    ac_prev=sharedstatedir ;;
+  -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+  | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+  | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+  | --sha=* | --sh=*)
+    sharedstatedir=$ac_optarg ;;
+
+  -site | --site | --sit)
+    ac_prev=site ;;
+  -site=* | --site=* | --sit=*)
+    site=$ac_optarg ;;
+
+  -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+    ac_prev=srcdir ;;
+  -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+    srcdir=$ac_optarg ;;
+
+  -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+  | --syscon | --sysco | --sysc | --sys | --sy)
+    ac_prev=sysconfdir ;;
+  -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+  | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+    sysconfdir=$ac_optarg ;;
+
+  -target | --target | --targe | --targ | --tar | --ta | --t)
+    ac_prev=target_alias ;;
+  -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+    target_alias=$ac_optarg ;;
+
+  -v | -verbose | --verbose | --verbos | --verbo | --verb)
+    verbose=yes ;;
+
+  -version | --version | --versio | --versi | --vers | -V)
+    ac_init_version=: ;;
+
+  -with-* | --with-*)
+    ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+      as_fn_error $? "invalid package name: $ac_useropt"
+    ac_useropt_orig=$ac_useropt
+    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+    case $ac_user_opts in
+      *"
+"with_$ac_useropt"
+"*) ;;
+      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig"
+	 ac_unrecognized_sep=', ';;
+    esac
+    eval with_$ac_useropt=\$ac_optarg ;;
+
+  -without-* | --without-*)
+    ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+      as_fn_error $? "invalid package name: $ac_useropt"
+    ac_useropt_orig=$ac_useropt
+    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+    case $ac_user_opts in
+      *"
+"with_$ac_useropt"
+"*) ;;
+      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig"
+	 ac_unrecognized_sep=', ';;
+    esac
+    eval with_$ac_useropt=no ;;
+
+  --x)
+    # Obsolete; use --with-x.
+    with_x=yes ;;
+
+  -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+  | --x-incl | --x-inc | --x-in | --x-i)
+    ac_prev=x_includes ;;
+  -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+  | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+    x_includes=$ac_optarg ;;
+
+  -x-libraries | --x-libraries | --x-librarie | --x-librari \
+  | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+    ac_prev=x_libraries ;;
+  -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+  | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+    x_libraries=$ac_optarg ;;
+
+  -*) as_fn_error $? "unrecognized option: \`$ac_option'
+Try \`$0 --help' for more information"
+    ;;
+
+  *=*)
+    ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
+    # Reject names that are not valid shell variable names.
+    case $ac_envvar in #(
+      '' | [0-9]* | *[!_$as_cr_alnum]* )
+      as_fn_error $? "invalid variable name: \`$ac_envvar'" ;;
+    esac
+    eval $ac_envvar=\$ac_optarg
+    export $ac_envvar ;;
+
+  *)
+    # FIXME: should be removed in autoconf 3.0.
+    $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2
+    expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
+      $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2
+    : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}"
+    ;;
+
+  esac
+done
+
+if test -n "$ac_prev"; then
+  ac_option=--`echo $ac_prev | sed 's/_/-/g'`
+  as_fn_error $? "missing argument to $ac_option"
+fi
+
+if test -n "$ac_unrecognized_opts"; then
+  case $enable_option_checking in
+    no) ;;
+    fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;;
+    *)     $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;;
+  esac
+fi
+
+# Check all directory arguments for consistency.
+for ac_var in	exec_prefix prefix bindir sbindir libexecdir datarootdir \
+		datadir sysconfdir sharedstatedir localstatedir includedir \
+		oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
+		libdir localedir mandir runstatedir
+do
+  eval ac_val=\$$ac_var
+  # Remove trailing slashes.
+  case $ac_val in
+    */ )
+      ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'`
+      eval $ac_var=\$ac_val;;
+  esac
+  # Be sure to have absolute directory names.
+  case $ac_val in
+    [\\/$]* | ?:[\\/]* )  continue;;
+    NONE | '' ) case $ac_var in *prefix ) continue;; esac;;
+  esac
+  as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val"
+done
+
+# There might be people who depend on the old broken behavior: `$host'
+# used to hold the argument of --host etc.
+# FIXME: To remove some day.
+build=$build_alias
+host=$host_alias
+target=$target_alias
+
+# FIXME: To remove some day.
+if test "x$host_alias" != x; then
+  if test "x$build_alias" = x; then
+    cross_compiling=maybe
+  elif test "x$build_alias" != "x$host_alias"; then
+    cross_compiling=yes
+  fi
+fi
+
+ac_tool_prefix=
+test -n "$host_alias" && ac_tool_prefix=$host_alias-
+
+test "$silent" = yes && exec 6>/dev/null
+
+
+ac_pwd=`pwd` && test -n "$ac_pwd" &&
+ac_ls_di=`ls -di .` &&
+ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` ||
+  as_fn_error $? "working directory cannot be determined"
+test "X$ac_ls_di" = "X$ac_pwd_ls_di" ||
+  as_fn_error $? "pwd does not report name of working directory"
+
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+  ac_srcdir_defaulted=yes
+  # Try the directory containing this script, then the parent directory.
+  ac_confdir=`$as_dirname -- "$as_myself" ||
+$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$as_myself" : 'X\(//\)[^/]' \| \
+	 X"$as_myself" : 'X\(//\)$' \| \
+	 X"$as_myself" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_myself" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+  srcdir=$ac_confdir
+  if test ! -r "$srcdir/$ac_unique_file"; then
+    srcdir=..
+  fi
+else
+  ac_srcdir_defaulted=no
+fi
+if test ! -r "$srcdir/$ac_unique_file"; then
+  test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .."
+  as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir"
+fi
+ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work"
+ac_abs_confdir=`(
+	cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg"
+	pwd)`
+# When building in place, set srcdir=.
+if test "$ac_abs_confdir" = "$ac_pwd"; then
+  srcdir=.
+fi
+# Remove unnecessary trailing slashes from srcdir.
+# Double slashes in file names in object file debugging info
+# mess up M-x gdb in Emacs.
+case $srcdir in
+*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;;
+esac
+for ac_var in $ac_precious_vars; do
+  eval ac_env_${ac_var}_set=\${${ac_var}+set}
+  eval ac_env_${ac_var}_value=\$${ac_var}
+  eval ac_cv_env_${ac_var}_set=\${${ac_var}+set}
+  eval ac_cv_env_${ac_var}_value=\$${ac_var}
+done
+
+#
+# Report the --help message.
+#
+if test "$ac_init_help" = "long"; then
+  # Omit some internal or obsolete options to make the list less imposing.
+  # This message is too long to be a string in the A/UX 3.1 sh.
+  cat <<_ACEOF
+\`configure' configures zfs 0.6.5.6 to adapt to many kinds of systems.
+
+Usage: $0 [OPTION]... [VAR=VALUE]...
+
+To assign environment variables (e.g., CC, CFLAGS...), specify them as
+VAR=VALUE.  See below for descriptions of some of the useful variables.
+
+Defaults for the options are specified in brackets.
+
+Configuration:
+  -h, --help              display this help and exit
+      --help=short        display options specific to this package
+      --help=recursive    display the short help of all the included packages
+  -V, --version           display version information and exit
+  -q, --quiet, --silent   do not print \`checking ...' messages
+      --cache-file=FILE   cache test results in FILE [disabled]
+  -C, --config-cache      alias for \`--cache-file=config.cache'
+  -n, --no-create         do not create output files
+      --srcdir=DIR        find the sources in DIR [configure dir or \`..']
+
+Installation directories:
+  --prefix=PREFIX         install architecture-independent files in PREFIX
+                          [$ac_default_prefix]
+  --exec-prefix=EPREFIX   install architecture-dependent files in EPREFIX
+                          [PREFIX]
+
+By default, \`make install' will install all the files in
+\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc.  You can specify
+an installation prefix other than \`$ac_default_prefix' using \`--prefix',
+for instance \`--prefix=\$HOME'.
+
+For better control, use the options below.
+
+Fine tuning of the installation directories:
+  --bindir=DIR            user executables [EPREFIX/bin]
+  --sbindir=DIR           system admin executables [EPREFIX/sbin]
+  --libexecdir=DIR        program executables [EPREFIX/libexec]
+  --sysconfdir=DIR        read-only single-machine data [PREFIX/etc]
+  --sharedstatedir=DIR    modifiable architecture-independent data [PREFIX/com]
+  --localstatedir=DIR     modifiable single-machine data [PREFIX/var]
+  --runstatedir=DIR       modifiable per-process data [LOCALSTATEDIR/run]
+  --libdir=DIR            object code libraries [EPREFIX/lib]
+  --includedir=DIR        C header files [PREFIX/include]
+  --oldincludedir=DIR     C header files for non-gcc [/usr/include]
+  --datarootdir=DIR       read-only arch.-independent data root [PREFIX/share]
+  --datadir=DIR           read-only architecture-independent data [DATAROOTDIR]
+  --infodir=DIR           info documentation [DATAROOTDIR/info]
+  --localedir=DIR         locale-dependent data [DATAROOTDIR/locale]
+  --mandir=DIR            man documentation [DATAROOTDIR/man]
+  --docdir=DIR            documentation root [DATAROOTDIR/doc/zfs]
+  --htmldir=DIR           html documentation [DOCDIR]
+  --dvidir=DIR            dvi documentation [DOCDIR]
+  --pdfdir=DIR            pdf documentation [DOCDIR]
+  --psdir=DIR             ps documentation [DOCDIR]
+_ACEOF
+
+  cat <<\_ACEOF
+
+Program names:
+  --program-prefix=PREFIX            prepend PREFIX to installed program names
+  --program-suffix=SUFFIX            append SUFFIX to installed program names
+  --program-transform-name=PROGRAM   run sed PROGRAM on installed program names
+
+System types:
+  --build=BUILD     configure for building on BUILD [guessed]
+  --host=HOST       cross-compile to build programs to run on HOST [BUILD]
+  --target=TARGET   configure for building compilers for TARGET [HOST]
+_ACEOF
+fi
+
+if test -n "$ac_init_help"; then
+  case $ac_init_help in
+     short | recursive ) echo "Configuration of zfs 0.6.5.6:";;
+   esac
+  cat <<\_ACEOF
+
+Optional Features:
+  --disable-option-checking  ignore unrecognized --enable/--with options
+  --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
+  --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
+  --enable-maintainer-mode
+                          enable make rules and dependencies not useful (and
+                          sometimes confusing) to the casual installer
+  --enable-silent-rules   less verbose build output (undo: "make V=1")
+  --disable-silent-rules  verbose build output (undo: "make V=0")
+  --enable-dependency-tracking
+                          do not reject slow dependency extractors
+  --disable-dependency-tracking
+                          speeds up one-time build
+  --enable-shared[=PKGS]  build shared libraries [default=yes]
+  --enable-static[=PKGS]  build static libraries [default=yes]
+  --enable-fast-install[=PKGS]
+                          optimize for fast installation [default=yes]
+  --disable-libtool-lock  avoid locking (might break parallel builds)
+  --enable-linux-builtin  Configure for builtin in-tree kernel modules
+                          [default=no]
+  --enable-systemd        install systemd unit/preset files [[default: yes]]
+  --enable-sysvinit       install SysV init scripts [default: yes]
+  --enable-debug          Enable generic debug support [default=no]
+  --enable-debug-dmu-tx   Enable dmu tx validation [default=no]
+
+Optional Packages:
+  --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
+  --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
+  --with-pic[=PKGS]       try to use only PIC/non-PIC objects [default=use
+                          both]
+  --with-aix-soname=aix|svr4|both
+                          shared library versioning (aka "SONAME") variant to
+                          provide on AIX, [default=aix].
+  --with-gnu-ld           assume the C compiler uses GNU ld [default=no]
+  --with-sysroot[=DIR]    Search for dependent libraries within DIR (or the
+                          compiler's sysroot if not specified).
+  --with-spec=SPEC        Spec files 'generic|redhat'
+  --with-config=CONFIG    Config file 'kernel|user|all|srpm'
+  --with-mounthelperdir=DIR
+                          install mount.zfs in dir [[/sbin]]
+  --with-udevdir=DIR      install udev helpers [default=check]
+  --with-udevruledir=DIR  install udev rules [[UDEVDIR/rules.d]]
+  --with-systemdunitdir=DIR
+                          install systemd unit files in dir
+                          [[/usr/lib/systemd/system]]
+  --with-systemdpresetdir=DIR
+                          install systemd preset files in dir
+                          [[/usr/lib/systemd/system-preset]]
+  --with-systemdmodulesloaddir=DIR
+                          install systemd module load files into dir
+                          [[/usr/lib/modules-load.d]]
+  --with-dracutdir=DIR    install dracut helpers [default=check]
+  --with-blkid            support blkid caching [default=check]
+  --with-linux=PATH       Path to kernel source
+  --with-linux-obj=PATH   Path to kernel build objects
+  --with-spl=PATH         Path to spl source
+  --with-spl-obj=PATH     Path to spl build objects
+  --with-spl-timeout=SECS Wait SECS for SPL header and symver file [default=0]
+
+Some influential environment variables:
+  CC          C compiler command
+  CFLAGS      C compiler flags
+  LDFLAGS     linker flags, e.g. -L<lib dir> if you have libraries in a
+              nonstandard directory <lib dir>
+  LIBS        libraries to pass to the linker, e.g. -l<library>
+  CPPFLAGS    (Objective) C/C++ preprocessor flags, e.g. -I<include dir> if
+              you have headers in a nonstandard directory <include dir>
+  LT_SYS_LIBRARY_PATH
+              User-defined run-time library search path.
+  CPP         C preprocessor
+  CCAS        assembler compiler command (defaults to CC)
+  CCASFLAGS   assembler compiler flags (defaults to CFLAGS)
+
+Use these variables to override the choices made by `configure' or to help
+it to find libraries and programs with nonstandard names/locations.
+
+Report bugs to the package provider.
+_ACEOF
+ac_status=$?
+fi
+
+if test "$ac_init_help" = "recursive"; then
+  # If there are subdirs, report their specific --help.
+  for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
+    test -d "$ac_dir" ||
+      { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } ||
+      continue
+    ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+  ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
+  # A ".." for each directory in $ac_dir_suffix.
+  ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+  case $ac_top_builddir_sub in
+  "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+  *)  ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+  esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+  .)  # We are building in place.
+    ac_srcdir=.
+    ac_top_srcdir=$ac_top_builddir_sub
+    ac_abs_top_srcdir=$ac_pwd ;;
+  [\\/]* | ?:[\\/]* )  # Absolute name.
+    ac_srcdir=$srcdir$ac_dir_suffix;
+    ac_top_srcdir=$srcdir
+    ac_abs_top_srcdir=$srcdir ;;
+  *) # Relative name.
+    ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_build_prefix$srcdir
+    ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+    cd "$ac_dir" || { ac_status=$?; continue; }
+    # Check for guested configure.
+    if test -f "$ac_srcdir/configure.gnu"; then
+      echo &&
+      $SHELL "$ac_srcdir/configure.gnu" --help=recursive
+    elif test -f "$ac_srcdir/configure"; then
+      echo &&
+      $SHELL "$ac_srcdir/configure" --help=recursive
+    else
+      $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
+    fi || ac_status=$?
+    cd "$ac_pwd" || { ac_status=$?; break; }
+  done
+fi
+
+test -n "$ac_init_help" && exit $ac_status
+if $ac_init_version; then
+  cat <<\_ACEOF
+zfs configure 0.6.5.6
+generated by GNU Autoconf 2.69
+
+Copyright (C) 2012 Free Software Foundation, Inc.
+This configure script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it.
+_ACEOF
+  exit
+fi
+
+## ------------------------ ##
+## Autoconf initialization. ##
+## ------------------------ ##
+
+# ac_fn_c_try_compile LINENO
+# --------------------------
+# Try to compile conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_compile ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  rm -f conftest.$ac_objext
+  if { { ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_compile") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    grep -v '^ *+' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+    mv -f conftest.er1 conftest.err
+  fi
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then :
+  ac_retval=0
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_retval=1
+fi
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_compile
+
+# ac_fn_c_try_link LINENO
+# -----------------------
+# Try to link conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_link ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  rm -f conftest.$ac_objext conftest$ac_exeext
+  if { { ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_link") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    grep -v '^ *+' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+    mv -f conftest.er1 conftest.err
+  fi
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest$ac_exeext && {
+	 test "$cross_compiling" = yes ||
+	 test -x conftest$ac_exeext
+       }; then :
+  ac_retval=0
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_retval=1
+fi
+  # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information
+  # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would
+  # interfere with the next link command; also delete a directory that is
+  # left behind by Apple's compiler.  We do this before executing the actions.
+  rm -rf conftest.dSYM conftest_ipa8_conftest.oo
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_link
+
+# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES
+# -------------------------------------------------------
+# Tests whether HEADER exists and can be compiled using the include files in
+# INCLUDES, setting the cache variable VAR accordingly.
+ac_fn_c_check_header_compile ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+#include <$2>
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  eval "$3=yes"
+else
+  eval "$3=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_header_compile
+
+# ac_fn_c_try_cpp LINENO
+# ----------------------
+# Try to preprocess conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_cpp ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  if { { ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    grep -v '^ *+' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+    mv -f conftest.er1 conftest.err
+  fi
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } > conftest.i && {
+	 test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       }; then :
+  ac_retval=0
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+    ac_retval=1
+fi
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_cpp
+
+# ac_fn_c_try_run LINENO
+# ----------------------
+# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes
+# that executables *can* be run.
+ac_fn_c_try_run ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  if { { ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_link") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && { ac_try='./conftest$ac_exeext'
+  { { case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+  ac_retval=0
+else
+  $as_echo "$as_me: program exited with status $ac_status" >&5
+       $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+       ac_retval=$ac_status
+fi
+  rm -rf conftest.dSYM conftest_ipa8_conftest.oo
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_run
+
+# ac_fn_c_check_func LINENO FUNC VAR
+# ----------------------------------
+# Tests whether FUNC exists, setting the cache variable VAR accordingly
+ac_fn_c_check_func ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+/* Define $2 to an innocuous variant, in case <limits.h> declares $2.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define $2 innocuous_$2
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $2 (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $2
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char $2 ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined __stub_$2 || defined __stub___$2
+choke me
+#endif
+
+int
+main ()
+{
+return $2 ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  eval "$3=yes"
+else
+  eval "$3=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_func
+
+# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES
+# -------------------------------------------------------
+# Tests whether HEADER exists, giving a warning if it cannot be compiled using
+# the include files in INCLUDES and setting the cache variable VAR
+# accordingly.
+ac_fn_c_check_header_mongrel ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  if eval \${$3+:} false; then :
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+  $as_echo_n "(cached) " >&6
+fi
+eval ac_res=\$$3
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+else
+  # Is the header compilable?
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5
+$as_echo_n "checking $2 usability... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+#include <$2>
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_header_compiler=yes
+else
+  ac_header_compiler=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5
+$as_echo "$ac_header_compiler" >&6; }
+
+# Is the header present?
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5
+$as_echo_n "checking $2 presence... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <$2>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+  ac_header_preproc=yes
+else
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5
+$as_echo "$ac_header_preproc" >&6; }
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #((
+  yes:no: )
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5
+$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
+$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
+    ;;
+  no:yes:* )
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5
+$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;}
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2:     check for missing prerequisite headers?" >&5
+$as_echo "$as_me: WARNING: $2:     check for missing prerequisite headers?" >&2;}
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5
+$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;}
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2:     section \"Present But Cannot Be Compiled\"" >&5
+$as_echo "$as_me: WARNING: $2:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
+$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
+    ;;
+esac
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  eval "$3=\$ac_header_compiler"
+fi
+eval ac_res=\$$3
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+fi
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_header_mongrel
+cat >config.log <<_ACEOF
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+
+It was created by zfs $as_me 0.6.5.6, which was
+generated by GNU Autoconf 2.69.  Invocation command line was
+
+  $ $0 $@
+
+_ACEOF
+exec 5>>config.log
+{
+cat <<_ASUNAME
+## --------- ##
+## Platform. ##
+## --------- ##
+
+hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`
+/bin/uname -X     = `(/bin/uname -X) 2>/dev/null     || echo unknown`
+
+/bin/arch              = `(/bin/arch) 2>/dev/null              || echo unknown`
+/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null       || echo unknown`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
+/usr/bin/hostinfo      = `(/usr/bin/hostinfo) 2>/dev/null      || echo unknown`
+/bin/machine           = `(/bin/machine) 2>/dev/null           || echo unknown`
+/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null       || echo unknown`
+/bin/universe          = `(/bin/universe) 2>/dev/null          || echo unknown`
+
+_ASUNAME
+
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    $as_echo "PATH: $as_dir"
+  done
+IFS=$as_save_IFS
+
+} >&5
+
+cat >&5 <<_ACEOF
+
+
+## ----------- ##
+## Core tests. ##
+## ----------- ##
+
+_ACEOF
+
+
+# Keep a trace of the command line.
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Strip out --silent because we don't want to record it for future runs.
+# Also quote any args containing shell meta-characters.
+# Make two passes to allow for proper duplicate-argument suppression.
+ac_configure_args=
+ac_configure_args0=
+ac_configure_args1=
+ac_must_keep_next=false
+for ac_pass in 1 2
+do
+  for ac_arg
+  do
+    case $ac_arg in
+    -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;
+    -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+    | -silent | --silent | --silen | --sile | --sil)
+      continue ;;
+    *\'*)
+      ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+    esac
+    case $ac_pass in
+    1) as_fn_append ac_configure_args0 " '$ac_arg'" ;;
+    2)
+      as_fn_append ac_configure_args1 " '$ac_arg'"
+      if test $ac_must_keep_next = true; then
+	ac_must_keep_next=false # Got value, back to normal.
+      else
+	case $ac_arg in
+	  *=* | --config-cache | -C | -disable-* | --disable-* \
+	  | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
+	  | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
+	  | -with-* | --with-* | -without-* | --without-* | --x)
+	    case "$ac_configure_args0 " in
+	      "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
+	    esac
+	    ;;
+	  -* ) ac_must_keep_next=true ;;
+	esac
+      fi
+      as_fn_append ac_configure_args " '$ac_arg'"
+      ;;
+    esac
+  done
+done
+{ ac_configure_args0=; unset ac_configure_args0;}
+{ ac_configure_args1=; unset ac_configure_args1;}
+
+# When interrupted or exit'd, cleanup temporary files, and complete
+# config.log.  We remove comments because anyway the quotes in there
+# would cause problems or look ugly.
+# WARNING: Use '\'' to represent an apostrophe within the trap.
+# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug.
+trap 'exit_status=$?
+  # Save into config.log some information that might help in debugging.
+  {
+    echo
+
+    $as_echo "## ---------------- ##
+## Cache variables. ##
+## ---------------- ##"
+    echo
+    # The following way of writing the cache mishandles newlines in values,
+(
+  for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do
+    eval ac_val=\$$ac_var
+    case $ac_val in #(
+    *${as_nl}*)
+      case $ac_var in #(
+      *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
+$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
+      esac
+      case $ac_var in #(
+      _ | IFS | as_nl) ;; #(
+      BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
+      *) { eval $ac_var=; unset $ac_var;} ;;
+      esac ;;
+    esac
+  done
+  (set) 2>&1 |
+    case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #(
+    *${as_nl}ac_space=\ *)
+      sed -n \
+	"s/'\''/'\''\\\\'\'''\''/g;
+	  s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p"
+      ;; #(
+    *)
+      sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
+      ;;
+    esac |
+    sort
+)
+    echo
+
+    $as_echo "## ----------------- ##
+## Output variables. ##
+## ----------------- ##"
+    echo
+    for ac_var in $ac_subst_vars
+    do
+      eval ac_val=\$$ac_var
+      case $ac_val in
+      *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+      esac
+      $as_echo "$ac_var='\''$ac_val'\''"
+    done | sort
+    echo
+
+    if test -n "$ac_subst_files"; then
+      $as_echo "## ------------------- ##
+## File substitutions. ##
+## ------------------- ##"
+      echo
+      for ac_var in $ac_subst_files
+      do
+	eval ac_val=\$$ac_var
+	case $ac_val in
+	*\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+	esac
+	$as_echo "$ac_var='\''$ac_val'\''"
+      done | sort
+      echo
+    fi
+
+    if test -s confdefs.h; then
+      $as_echo "## ----------- ##
+## confdefs.h. ##
+## ----------- ##"
+      echo
+      cat confdefs.h
+      echo
+    fi
+    test "$ac_signal" != 0 &&
+      $as_echo "$as_me: caught signal $ac_signal"
+    $as_echo "$as_me: exit $exit_status"
+  } >&5
+  rm -f core *.core core.conftest.* &&
+    rm -f -r conftest* confdefs* conf$$* $ac_clean_files &&
+    exit $exit_status
+' 0
+for ac_signal in 1 2 13 15; do
+  trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal
+done
+ac_signal=0
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -f -r conftest* confdefs.h
+
+$as_echo "/* confdefs.h */" > confdefs.h
+
+# Predefined preprocessor variables.
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_NAME "$PACKAGE_NAME"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_TARNAME "$PACKAGE_TARNAME"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_VERSION "$PACKAGE_VERSION"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_STRING "$PACKAGE_STRING"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_URL "$PACKAGE_URL"
+_ACEOF
+
+
+# Let the site file select an alternate cache file if it wants to.
+# Prefer an explicitly selected file to automatically selected ones.
+ac_site_file1=NONE
+ac_site_file2=NONE
+if test -n "$CONFIG_SITE"; then
+  # We do not want a PATH search for config.site.
+  case $CONFIG_SITE in #((
+    -*)  ac_site_file1=./$CONFIG_SITE;;
+    */*) ac_site_file1=$CONFIG_SITE;;
+    *)   ac_site_file1=./$CONFIG_SITE;;
+  esac
+elif test "x$prefix" != xNONE; then
+  ac_site_file1=$prefix/share/config.site
+  ac_site_file2=$prefix/etc/config.site
+else
+  ac_site_file1=$ac_default_prefix/share/config.site
+  ac_site_file2=$ac_default_prefix/etc/config.site
+fi
+for ac_site_file in "$ac_site_file1" "$ac_site_file2"
+do
+  test "x$ac_site_file" = xNONE && continue
+  if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5
+$as_echo "$as_me: loading site script $ac_site_file" >&6;}
+    sed 's/^/| /' "$ac_site_file" >&5
+    . "$ac_site_file" \
+      || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "failed to load site script $ac_site_file
+See \`config.log' for more details" "$LINENO" 5; }
+  fi
+done
+
+if test -r "$cache_file"; then
+  # Some versions of bash will fail to source /dev/null (special files
+  # actually), so we avoid doing that.  DJGPP emulates it as a regular file.
+  if test /dev/null != "$cache_file" && test -f "$cache_file"; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5
+$as_echo "$as_me: loading cache $cache_file" >&6;}
+    case $cache_file in
+      [\\/]* | ?:[\\/]* ) . "$cache_file";;
+      *)                      . "./$cache_file";;
+    esac
+  fi
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5
+$as_echo "$as_me: creating cache $cache_file" >&6;}
+  >$cache_file
+fi
+
+# Check that the precious variables saved in the cache have kept the same
+# value.
+ac_cache_corrupted=false
+for ac_var in $ac_precious_vars; do
+  eval ac_old_set=\$ac_cv_env_${ac_var}_set
+  eval ac_new_set=\$ac_env_${ac_var}_set
+  eval ac_old_val=\$ac_cv_env_${ac_var}_value
+  eval ac_new_val=\$ac_env_${ac_var}_value
+  case $ac_old_set,$ac_new_set in
+    set,)
+      { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
+$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
+      ac_cache_corrupted=: ;;
+    ,set)
+      { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5
+$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
+      ac_cache_corrupted=: ;;
+    ,);;
+    *)
+      if test "x$ac_old_val" != "x$ac_new_val"; then
+	# differences in whitespace do not lead to failure.
+	ac_old_val_w=`echo x $ac_old_val`
+	ac_new_val_w=`echo x $ac_new_val`
+	if test "$ac_old_val_w" != "$ac_new_val_w"; then
+	  { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5
+$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
+	  ac_cache_corrupted=:
+	else
+	  { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5
+$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;}
+	  eval $ac_var=\$ac_old_val
+	fi
+	{ $as_echo "$as_me:${as_lineno-$LINENO}:   former value:  \`$ac_old_val'" >&5
+$as_echo "$as_me:   former value:  \`$ac_old_val'" >&2;}
+	{ $as_echo "$as_me:${as_lineno-$LINENO}:   current value: \`$ac_new_val'" >&5
+$as_echo "$as_me:   current value: \`$ac_new_val'" >&2;}
+      fi;;
+  esac
+  # Pass precious variables to config.status.
+  if test "$ac_new_set" = set; then
+    case $ac_new_val in
+    *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
+    *) ac_arg=$ac_var=$ac_new_val ;;
+    esac
+    case " $ac_configure_args " in
+      *" '$ac_arg' "*) ;; # Avoid dups.  Use of quotes ensures accuracy.
+      *) as_fn_append ac_configure_args " '$ac_arg'" ;;
+    esac
+  fi
+done
+if $ac_cache_corrupted; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+  { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5
+$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;}
+  as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5
+fi
+## -------------------- ##
+## Main body of script. ##
+## -------------------- ##
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+
+
+	for ac_prog in gawk mawk nawk awk
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_AWK+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$AWK"; then
+  ac_cv_prog_AWK="$AWK" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_AWK="$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+AWK=$ac_cv_prog_AWK
+if test -n "$AWK"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5
+$as_echo "$AWK" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  test -n "$AWK" && break
+done
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking metadata" >&5
+$as_echo_n "checking metadata... " >&6; }
+
+	META="$srcdir/META"
+	_zfs_ac_meta_type="none"
+	if test -f "$META"; then
+		_zfs_ac_meta_type="META file"
+		_dpkg_parsechangelog=$(dpkg-parsechangelog 2>/dev/null)
+
+		ZFS_META_NAME=`$AWK -F ':[ \t]+' '$1 ~ /^ *(Name|Project|Package)$/ { print $2; exit }' $META`;
+		if test -n "$ZFS_META_NAME"; then
+
+cat >>confdefs.h <<_ACEOF
+#define ZFS_META_NAME "$ZFS_META_NAME"
+_ACEOF
+
+
+		fi
+
+		ZFS_META_VERSION=`$AWK -F ':[ \t]+' '$1 ~ /^ *Version$/ { print $2; exit }' $META`;
+		if test -n "$ZFS_META_VERSION"; then
+
+cat >>confdefs.h <<_ACEOF
+#define ZFS_META_VERSION "$ZFS_META_VERSION"
+_ACEOF
+
+
+		fi
+
+		if test -n "${_dpkg_parsechangelog}"; then
+			_dpkg_version=$(echo "${_dpkg_parsechangelog}" \
+				| $AWK '$1 == "Version:" { print $2; }' \
+				| cut -d- -f1)
+			if test "${_dpkg_version}" != "$ZFS_META_VERSION"; then
+				as_fn_error $? "
+	*** Version $ZFS_META_VERSION in the META file is different than
+	*** version $_dpkg_version in the debian/changelog file. DKMS and DEB
+	*** packaging require that these files have the same version.
+				" "$LINENO" 5
+			fi
+		fi
+
+		ZFS_META_RELEASE=`$AWK -F ':[ \t]+' '$1 ~ /^ *Release$/ { print $2; exit }' $META`;
+
+		if test -n "${_dpkg_parsechangelog}"; then
+			_dpkg_release=$(echo "${_dpkg_parsechangelog}" \
+				| $AWK '$1 == "Version:" { print $2; }' \
+				| cut -d- -f2-)
+			if test -n "${_dpkg_release}"; then
+				ZFS_META_RELEASE=${_dpkg_release}
+				_zfs_ac_meta_type="dpkg-parsechangelog"
+			fi
+		elif test ! -f ".nogitrelease" && git rev-parse --git-dir > /dev/null 2>&1; then
+			_match="${ZFS_META_NAME}-${ZFS_META_VERSION}"
+			_alias=$(git describe --match=${_match} 2>/dev/null)
+			_release=$(echo ${_alias}|cut -f3- -d'-'|sed 's/-/_/g')
+			if test -n "${_release}"; then
+				ZFS_META_RELEASE=${_release}
+				_zfs_ac_meta_type="git describe"
+			fi
+		fi
+
+		if test -n "$ZFS_META_RELEASE"; then
+
+cat >>confdefs.h <<_ACEOF
+#define ZFS_META_RELEASE "$ZFS_META_RELEASE"
+_ACEOF
+
+
+
+			RELEASE="$ZFS_META_RELEASE"
+
+		fi
+
+		ZFS_META_LICENSE=`$AWK -F ':[ \t]+' '$1 ~ /^ *License$/ { print $2; exit }' $META`;
+		if test -n "$ZFS_META_LICENSE"; then
+
+cat >>confdefs.h <<_ACEOF
+#define ZFS_META_LICENSE "$ZFS_META_LICENSE"
+_ACEOF
+
+
+		fi
+
+		if test -n "$ZFS_META_NAME" -a -n "$ZFS_META_VERSION"; then
+				ZFS_META_ALIAS="$ZFS_META_NAME-$ZFS_META_VERSION"
+				test -n "$ZFS_META_RELEASE" &&
+				        ZFS_META_ALIAS="$ZFS_META_ALIAS-$ZFS_META_RELEASE"
+
+cat >>confdefs.h <<_ACEOF
+#define ZFS_META_ALIAS "$ZFS_META_ALIAS"
+_ACEOF
+
+
+		fi
+
+		ZFS_META_DATA=`$AWK -F ':[ \t]+' '$1 ~ /^ *Date$/ { print $2; exit }' $META`;
+		if test -n "$ZFS_META_DATA"; then
+
+cat >>confdefs.h <<_ACEOF
+#define ZFS_META_DATA "$ZFS_META_DATA"
+_ACEOF
+
+
+		fi
+
+		ZFS_META_AUTHOR=`$AWK -F ':[ \t]+' '$1 ~ /^ *Author$/ { print $2; exit }' $META`;
+		if test -n "$ZFS_META_AUTHOR"; then
+
+cat >>confdefs.h <<_ACEOF
+#define ZFS_META_AUTHOR "$ZFS_META_AUTHOR"
+_ACEOF
+
+
+		fi
+
+
+		ZFS_META_LT_CURRENT=`$AWK -F ':[ \t]+' '$1 ~ /^ *LT_Current$/ { print $2; exit }' $META`;
+		ZFS_META_LT_REVISION=`$AWK -F ':[ \t]+' '$1 ~ /^ *LT_Revision$/ { print $2; exit }' $META`;
+		ZFS_META_LT_AGE=`$AWK -F ':[ \t]+' '$1 ~ /^ *LT_Age$/ { print $2; exit }' $META`;
+		if test -n "$ZFS_META_LT_CURRENT" \
+				 -o -n "$ZFS_META_LT_REVISION" \
+				 -o -n "$ZFS_META_LT_AGE"; then
+			test -n "$ZFS_META_LT_CURRENT" || ZFS_META_LT_CURRENT="0"
+			test -n "$ZFS_META_LT_REVISION" || ZFS_META_LT_REVISION="0"
+			test -n "$ZFS_META_LT_AGE" || ZFS_META_LT_AGE="0"
+
+cat >>confdefs.h <<_ACEOF
+#define ZFS_META_LT_CURRENT "$ZFS_META_LT_CURRENT"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define ZFS_META_LT_REVISION "$ZFS_META_LT_REVISION"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define ZFS_META_LT_AGE "$ZFS_META_LT_AGE"
+_ACEOF
+
+
+
+
+		fi
+	fi
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $_zfs_ac_meta_type" >&5
+$as_echo "$_zfs_ac_meta_type" >&6; }
+
+
+ac_aux_dir=
+for ac_dir in config "$srcdir"/config; do
+  if test -f "$ac_dir/install-sh"; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install-sh -c"
+    break
+  elif test -f "$ac_dir/install.sh"; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install.sh -c"
+    break
+  elif test -f "$ac_dir/shtool"; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/shtool install -c"
+    break
+  fi
+done
+if test -z "$ac_aux_dir"; then
+  as_fn_error $? "cannot find install-sh, install.sh, or shtool in config \"$srcdir\"/config" "$LINENO" 5
+fi
+
+# These three variables are undocumented and unsupported,
+# and are intended to be withdrawn in a future Autoconf release.
+# They can cause serious problems if a builder's source tree is in a directory
+# whose full name contains unusual characters.
+ac_config_guess="$SHELL $ac_aux_dir/config.guess"  # Please don't use this var.
+ac_config_sub="$SHELL $ac_aux_dir/config.sub"  # Please don't use this var.
+ac_configure="$SHELL $ac_aux_dir/configure"  # Please don't use this var.
+
+
+
+# Make sure we can run config.sub.
+$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 ||
+  as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5
+$as_echo_n "checking build system type... " >&6; }
+if ${ac_cv_build+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_build_alias=$build_alias
+test "x$ac_build_alias" = x &&
+  ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"`
+test "x$ac_build_alias" = x &&
+  as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5
+ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` ||
+  as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5
+$as_echo "$ac_cv_build" >&6; }
+case $ac_cv_build in
+*-*-*) ;;
+*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;;
+esac
+build=$ac_cv_build
+ac_save_IFS=$IFS; IFS='-'
+set x $ac_cv_build
+shift
+build_cpu=$1
+build_vendor=$2
+shift; shift
+# Remember, the first character of IFS is used to create $*,
+# except with old shells:
+build_os=$*
+IFS=$ac_save_IFS
+case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5
+$as_echo_n "checking host system type... " >&6; }
+if ${ac_cv_host+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test "x$host_alias" = x; then
+  ac_cv_host=$ac_cv_build
+else
+  ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` ||
+    as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5
+$as_echo "$ac_cv_host" >&6; }
+case $ac_cv_host in
+*-*-*) ;;
+*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;;
+esac
+host=$ac_cv_host
+ac_save_IFS=$IFS; IFS='-'
+set x $ac_cv_host
+shift
+host_cpu=$1
+host_vendor=$2
+shift; shift
+# Remember, the first character of IFS is used to create $*,
+# except with old shells:
+host_os=$*
+IFS=$ac_save_IFS
+case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking target system type" >&5
+$as_echo_n "checking target system type... " >&6; }
+if ${ac_cv_target+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test "x$target_alias" = x; then
+  ac_cv_target=$ac_cv_host
+else
+  ac_cv_target=`$SHELL "$ac_aux_dir/config.sub" $target_alias` ||
+    as_fn_error $? "$SHELL $ac_aux_dir/config.sub $target_alias failed" "$LINENO" 5
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_target" >&5
+$as_echo "$ac_cv_target" >&6; }
+case $ac_cv_target in
+*-*-*) ;;
+*) as_fn_error $? "invalid value of canonical target" "$LINENO" 5;;
+esac
+target=$ac_cv_target
+ac_save_IFS=$IFS; IFS='-'
+set x $ac_cv_target
+shift
+target_cpu=$1
+target_vendor=$2
+shift; shift
+# Remember, the first character of IFS is used to create $*,
+# except with old shells:
+target_os=$*
+IFS=$ac_save_IFS
+case $target_os in *\ *) target_os=`echo "$target_os" | sed 's/ /-/g'`;; esac
+
+
+# The aliases save the names the user supplied, while $host etc.
+# will get canonicalized.
+test -n "$target_alias" &&
+  test "$program_prefix$program_suffix$program_transform_name" = \
+    NONENONEs,x,x, &&
+  program_prefix=${target_alias}-
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable maintainer-specific portions of Makefiles" >&5
+$as_echo_n "checking whether to enable maintainer-specific portions of Makefiles... " >&6; }
+    # Check whether --enable-maintainer-mode was given.
+if test "${enable_maintainer_mode+set}" = set; then :
+  enableval=$enable_maintainer_mode; USE_MAINTAINER_MODE=$enableval
+else
+  USE_MAINTAINER_MODE=no
+fi
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $USE_MAINTAINER_MODE" >&5
+$as_echo "$USE_MAINTAINER_MODE" >&6; }
+   if test $USE_MAINTAINER_MODE = yes; then
+  MAINTAINER_MODE_TRUE=
+  MAINTAINER_MODE_FALSE='#'
+else
+  MAINTAINER_MODE_TRUE='#'
+  MAINTAINER_MODE_FALSE=
+fi
+
+  MAINT=$MAINTAINER_MODE_TRUE
+
+
+# Check whether --enable-silent-rules was given.
+if test "${enable_silent_rules+set}" = set; then :
+  enableval=$enable_silent_rules;
+fi
+
+case $enable_silent_rules in # (((
+  yes) AM_DEFAULT_VERBOSITY=0;;
+   no) AM_DEFAULT_VERBOSITY=1;;
+    *) AM_DEFAULT_VERBOSITY=0;;
+esac
+am_make=${MAKE-make}
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5
+$as_echo_n "checking whether $am_make supports nested variables... " >&6; }
+if ${am_cv_make_support_nested_variables+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if $as_echo 'TRUE=$(BAR$(V))
+BAR0=false
+BAR1=true
+V=1
+am__doit:
+	@$(TRUE)
+.PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then
+  am_cv_make_support_nested_variables=yes
+else
+  am_cv_make_support_nested_variables=no
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5
+$as_echo "$am_cv_make_support_nested_variables" >&6; }
+if test $am_cv_make_support_nested_variables = yes; then
+    AM_V='$(V)'
+  AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)'
+else
+  AM_V=$AM_DEFAULT_VERBOSITY
+  AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY
+fi
+AM_BACKSLASH='\'
+
+am__api_version='1.15'
+
+# Find a good install program.  We prefer a C program (faster),
+# so one script is as good as another.  But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AmigaOS /C/install, which installs bootblocks on floppy discs
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# OS/2's system install, which has a completely different semantic
+# ./install, which can be erroneously created by make from ./install.sh.
+# Reject install programs that cannot install multiple files.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5
+$as_echo_n "checking for a BSD-compatible install... " >&6; }
+if test -z "$INSTALL"; then
+if ${ac_cv_path_install+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    # Account for people who put trailing slashes in PATH elements.
+case $as_dir/ in #((
+  ./ | .// | /[cC]/* | \
+  /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \
+  ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \
+  /usr/ucb/* ) ;;
+  *)
+    # OSF1 and SCO ODT 3.0 have their own names for install.
+    # Don't use installbsd from OSF since it installs stuff as root
+    # by default.
+    for ac_prog in ginstall scoinst install; do
+      for ac_exec_ext in '' $ac_executable_extensions; do
+	if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then
+	  if test $ac_prog = install &&
+	    grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+	    # AIX install.  It has an incompatible calling convention.
+	    :
+	  elif test $ac_prog = install &&
+	    grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+	    # program-specific install script used by HP pwplus--don't use.
+	    :
+	  else
+	    rm -rf conftest.one conftest.two conftest.dir
+	    echo one > conftest.one
+	    echo two > conftest.two
+	    mkdir conftest.dir
+	    if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" &&
+	      test -s conftest.one && test -s conftest.two &&
+	      test -s conftest.dir/conftest.one &&
+	      test -s conftest.dir/conftest.two
+	    then
+	      ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c"
+	      break 3
+	    fi
+	  fi
+	fi
+      done
+    done
+    ;;
+esac
+
+  done
+IFS=$as_save_IFS
+
+rm -rf conftest.one conftest.two conftest.dir
+
+fi
+  if test "${ac_cv_path_install+set}" = set; then
+    INSTALL=$ac_cv_path_install
+  else
+    # As a last resort, use the slow shell script.  Don't cache a
+    # value for INSTALL within a source directory, because that will
+    # break other packages using the cache if that directory is
+    # removed, or if the value is a relative name.
+    INSTALL=$ac_install_sh
+  fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5
+$as_echo "$INSTALL" >&6; }
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5
+$as_echo_n "checking whether build environment is sane... " >&6; }
+# Reject unsafe characters in $srcdir or the absolute working directory
+# name.  Accept space and tab only in the latter.
+am_lf='
+'
+case `pwd` in
+  *[\\\"\#\$\&\'\`$am_lf]*)
+    as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;;
+esac
+case $srcdir in
+  *[\\\"\#\$\&\'\`$am_lf\ \	]*)
+    as_fn_error $? "unsafe srcdir value: '$srcdir'" "$LINENO" 5;;
+esac
+
+# Do 'set' in a subshell so we don't clobber the current shell's
+# arguments.  Must try -L first in case configure is actually a
+# symlink; some systems play weird games with the mod time of symlinks
+# (eg FreeBSD returns the mod time of the symlink's containing
+# directory).
+if (
+   am_has_slept=no
+   for am_try in 1 2; do
+     echo "timestamp, slept: $am_has_slept" > conftest.file
+     set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null`
+     if test "$*" = "X"; then
+	# -L didn't work.
+	set X `ls -t "$srcdir/configure" conftest.file`
+     fi
+     if test "$*" != "X $srcdir/configure conftest.file" \
+	&& test "$*" != "X conftest.file $srcdir/configure"; then
+
+	# If neither matched, then we have a broken ls.  This can happen
+	# if, for instance, CONFIG_SHELL is bash and it inherits a
+	# broken ls alias from the environment.  This has actually
+	# happened.  Such a system could not be considered "sane".
+	as_fn_error $? "ls -t appears to fail.  Make sure there is not a broken
+  alias in your environment" "$LINENO" 5
+     fi
+     if test "$2" = conftest.file || test $am_try -eq 2; then
+       break
+     fi
+     # Just in case.
+     sleep 1
+     am_has_slept=yes
+   done
+   test "$2" = conftest.file
+   )
+then
+   # Ok.
+   :
+else
+   as_fn_error $? "newly created file is older than distributed files!
+Check your system clock" "$LINENO" 5
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+# If we didn't sleep, we still need to ensure time stamps of config.status and
+# generated files are strictly newer.
+am_sleep_pid=
+if grep 'slept: no' conftest.file >/dev/null 2>&1; then
+  ( sleep 1 ) &
+  am_sleep_pid=$!
+fi
+
+rm -f conftest.file
+
+test "$program_prefix" != NONE &&
+  program_transform_name="s&^&$program_prefix&;$program_transform_name"
+# Use a double $ so make ignores it.
+test "$program_suffix" != NONE &&
+  program_transform_name="s&\$&$program_suffix&;$program_transform_name"
+# Double any \ or $.
+# By default was `s,x,x', remove it if useless.
+ac_script='s/[\\$]/&&/g;s/;s,x,x,$//'
+program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"`
+
+# Expand $ac_aux_dir to an absolute path.
+am_aux_dir=`cd "$ac_aux_dir" && pwd`
+
+if test x"${MISSING+set}" != xset; then
+  case $am_aux_dir in
+  *\ * | *\	*)
+    MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;;
+  *)
+    MISSING="\${SHELL} $am_aux_dir/missing" ;;
+  esac
+fi
+# Use eval to expand $SHELL
+if eval "$MISSING --is-lightweight"; then
+  am_missing_run="$MISSING "
+else
+  am_missing_run=
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 'missing' script is too old or missing" >&5
+$as_echo "$as_me: WARNING: 'missing' script is too old or missing" >&2;}
+fi
+
+if test x"${install_sh+set}" != xset; then
+  case $am_aux_dir in
+  *\ * | *\	*)
+    install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;;
+  *)
+    install_sh="\${SHELL} $am_aux_dir/install-sh"
+  esac
+fi
+
+# Installed binaries are usually stripped using 'strip' when the user
+# run "make install-strip".  However 'strip' might not be the right
+# tool to use in cross-compilation environments, therefore Automake
+# will honor the 'STRIP' environment variable to overrule this program.
+if test "$cross_compiling" != no; then
+  if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args.
+set dummy ${ac_tool_prefix}strip; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_STRIP+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$STRIP"; then
+  ac_cv_prog_STRIP="$STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_STRIP="${ac_tool_prefix}strip"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+STRIP=$ac_cv_prog_STRIP
+if test -n "$STRIP"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5
+$as_echo "$STRIP" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_STRIP"; then
+  ac_ct_STRIP=$STRIP
+  # Extract the first word of "strip", so it can be a program name with args.
+set dummy strip; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_STRIP+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_STRIP"; then
+  ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_STRIP="strip"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP
+if test -n "$ac_ct_STRIP"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5
+$as_echo "$ac_ct_STRIP" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_STRIP" = x; then
+    STRIP=":"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    STRIP=$ac_ct_STRIP
+  fi
+else
+  STRIP="$ac_cv_prog_STRIP"
+fi
+
+fi
+INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5
+$as_echo_n "checking for a thread-safe mkdir -p... " >&6; }
+if test -z "$MKDIR_P"; then
+  if ${ac_cv_path_mkdir+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_prog in mkdir gmkdir; do
+	 for ac_exec_ext in '' $ac_executable_extensions; do
+	   as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext" || continue
+	   case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #(
+	     'mkdir (GNU coreutils) '* | \
+	     'mkdir (coreutils) '* | \
+	     'mkdir (fileutils) '4.1*)
+	       ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext
+	       break 3;;
+	   esac
+	 done
+       done
+  done
+IFS=$as_save_IFS
+
+fi
+
+  test -d ./--version && rmdir ./--version
+  if test "${ac_cv_path_mkdir+set}" = set; then
+    MKDIR_P="$ac_cv_path_mkdir -p"
+  else
+    # As a last resort, use the slow shell script.  Don't cache a
+    # value for MKDIR_P within a source directory, because that will
+    # break other packages using the cache if that directory is
+    # removed, or if the value is a relative name.
+    MKDIR_P="$ac_install_sh -d"
+  fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5
+$as_echo "$MKDIR_P" >&6; }
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5
+$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; }
+set x ${MAKE-make}
+ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'`
+if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat >conftest.make <<\_ACEOF
+SHELL = /bin/sh
+all:
+	@echo '@@@%%%=$(MAKE)=@@@%%%'
+_ACEOF
+# GNU make sometimes prints "make[1]: Entering ...", which would confuse us.
+case `${MAKE-make} -f conftest.make 2>/dev/null` in
+  *@@@%%%=?*=@@@%%%*)
+    eval ac_cv_prog_make_${ac_make}_set=yes;;
+  *)
+    eval ac_cv_prog_make_${ac_make}_set=no;;
+esac
+rm -f conftest.make
+fi
+if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+  SET_MAKE=
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+  SET_MAKE="MAKE=${MAKE-make}"
+fi
+
+rm -rf .tst 2>/dev/null
+mkdir .tst 2>/dev/null
+if test -d .tst; then
+  am__leading_dot=.
+else
+  am__leading_dot=_
+fi
+rmdir .tst 2>/dev/null
+
+if test "`cd $srcdir && pwd`" != "`pwd`"; then
+  # Use -I$(srcdir) only when $(srcdir) != ., so that make's output
+  # is not polluted with repeated "-I."
+  am__isrc=' -I$(srcdir)'
+  # test to see if srcdir already configured
+  if test -f $srcdir/config.status; then
+    as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5
+  fi
+fi
+
+# test whether we have cygpath
+if test -z "$CYGPATH_W"; then
+  if (cygpath --version) >/dev/null 2>/dev/null; then
+    CYGPATH_W='cygpath -w'
+  else
+    CYGPATH_W=echo
+  fi
+fi
+
+
+# Define the identity of the package.
+ PACKAGE='zfs'
+ VERSION='0.6.5.6'
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE "$PACKAGE"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define VERSION "$VERSION"
+_ACEOF
+
+# Some tools Automake needs.
+
+ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"}
+
+
+AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"}
+
+
+AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"}
+
+
+AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"}
+
+
+MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"}
+
+# For better backward compatibility.  To be removed once Automake 1.9.x
+# dies out for good.  For more background, see:
+# <http://lists.gnu.org/archive/html/automake/2012-07/msg00001.html>
+# <http://lists.gnu.org/archive/html/automake/2012-07/msg00014.html>
+mkdir_p='$(MKDIR_P)'
+
+# We need awk for the "check" target (and possibly the TAP driver).  The
+# system "awk" is bad on some platforms.
+# Always define AMTAR for backward compatibility.  Yes, it's still used
+# in the wild :-(  We should find a proper way to deprecate it ...
+AMTAR='$${TAR-tar}'
+
+
+# We'll loop over all known methods to create a tar archive until one works.
+_am_tools='gnutar  pax cpio none'
+
+am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'
+
+
+
+
+
+
+# POSIX will say in a future version that running "rm -f" with no argument
+# is OK; and we want to be able to make that assumption in our Makefile
+# recipes.  So use an aggressive probe to check that the usage we want is
+# actually supported "in the wild" to an acceptable degree.
+# See automake bug#10828.
+# To make any issue more visible, cause the running configure to be aborted
+# by default if the 'rm' program in use doesn't match our expectations; the
+# user can still override this though.
+if rm -f && rm -fr && rm -rf; then : OK; else
+  cat >&2 <<'END'
+Oops!
+
+Your 'rm' program seems unable to run without file operands specified
+on the command line, even when the '-f' option is present.  This is contrary
+to the behaviour of most rm programs out there, and not conforming with
+the upcoming POSIX standard: <http://austingroupbugs.net/view.php?id=542>
+
+Please tell bug-automake@gnu.org about your system, including the value
+of your $PATH and any error possibly output before this message.  This
+can help us improve future automake versions.
+
+END
+  if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then
+    echo 'Configuration will proceed anyway, since you have set the' >&2
+    echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2
+    echo >&2
+  else
+    cat >&2 <<'END'
+Aborting the configuration process, to ensure you take notice of the issue.
+
+You can download and install GNU coreutils to get an 'rm' implementation
+that behaves properly: <http://www.gnu.org/software/coreutils/>.
+
+If you want to complete the configuration process using your problematic
+'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM
+to "yes", and re-run configure.
+
+END
+    as_fn_error $? "Your 'rm' program is bad, sorry." "$LINENO" 5
+  fi
+fi
+
+ac_config_headers="$ac_config_headers zfs_config.h"
+
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}gcc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="${ac_tool_prefix}gcc"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+  ac_ct_CC=$CC
+  # Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_CC+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CC="gcc"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_CC" = x; then
+    CC=""
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    CC=$ac_ct_CC
+  fi
+else
+  CC="$ac_cv_prog_CC"
+fi
+
+if test -z "$CC"; then
+          if test -n "$ac_tool_prefix"; then
+    # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}cc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="${ac_tool_prefix}cc"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  fi
+fi
+if test -z "$CC"; then
+  # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+  ac_prog_rejected=no
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
+       ac_prog_rejected=yes
+       continue
+     fi
+    ac_cv_prog_CC="cc"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+if test $ac_prog_rejected = yes; then
+  # We found a bogon in the path, so make sure we never use it.
+  set dummy $ac_cv_prog_CC
+  shift
+  if test $# != 0; then
+    # We chose a different compiler from the bogus one.
+    # However, it has the same basename, so the bogon will be chosen
+    # first if we set CC to just the basename; use the full file name.
+    shift
+    ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
+  fi
+fi
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$CC"; then
+  if test -n "$ac_tool_prefix"; then
+  for ac_prog in cl.exe
+  do
+    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+    test -n "$CC" && break
+  done
+fi
+if test -z "$CC"; then
+  ac_ct_CC=$CC
+  for ac_prog in cl.exe
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_CC+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CC="$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  test -n "$ac_ct_CC" && break
+done
+
+  if test "x$ac_ct_CC" = x; then
+    CC=""
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    CC=$ac_ct_CC
+  fi
+fi
+
+fi
+
+
+test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "no acceptable C compiler found in \$PATH
+See \`config.log' for more details" "$LINENO" 5; }
+
+# Provide some information about the compiler.
+$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5
+set X $ac_compile
+ac_compiler=$2
+for ac_option in --version -v -V -qversion; do
+  { { ac_try="$ac_compiler $ac_option >&5"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_compiler $ac_option >&5") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    sed '10a\
+... rest of stderr output deleted ...
+         10q' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+  fi
+  rm -f conftest.er1 conftest.err
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+done
+
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out"
+# Try to create an executable without -o first, disregard a.out.
+# It will help us diagnose broken compilers, and finding out an intuition
+# of exeext.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5
+$as_echo_n "checking whether the C compiler works... " >&6; }
+ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
+
+# The possible output files:
+ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*"
+
+ac_rmfiles=
+for ac_file in $ac_files
+do
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
+    * ) ac_rmfiles="$ac_rmfiles $ac_file";;
+  esac
+done
+rm -f $ac_rmfiles
+
+if { { ac_try="$ac_link_default"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_link_default") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then :
+  # Autoconf-2.13 could set the ac_cv_exeext variable to `no'.
+# So ignore a value of `no', otherwise this would lead to `EXEEXT = no'
+# in a Makefile.  We should not override ac_cv_exeext if it was cached,
+# so that the user can short-circuit this test for compilers unknown to
+# Autoconf.
+for ac_file in $ac_files ''
+do
+  test -f "$ac_file" || continue
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj )
+	;;
+    [ab].out )
+	# We found the default executable, but exeext='' is most
+	# certainly right.
+	break;;
+    *.* )
+	if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no;
+	then :; else
+	   ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+	fi
+	# We set ac_cv_exeext here because the later test for it is not
+	# safe: cross compilers may not add the suffix if given an `-o'
+	# argument, so we may need to know it at that point already.
+	# Even if this section looks crufty: it has the advantage of
+	# actually working.
+	break;;
+    * )
+	break;;
+  esac
+done
+test "$ac_cv_exeext" = no && ac_cv_exeext=
+
+else
+  ac_file=''
+fi
+if test -z "$ac_file"; then :
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+$as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "C compiler cannot create executables
+See \`config.log' for more details" "$LINENO" 5; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5
+$as_echo_n "checking for C compiler default output file name... " >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5
+$as_echo "$ac_file" >&6; }
+ac_exeext=$ac_cv_exeext
+
+rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out
+ac_clean_files=$ac_clean_files_save
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5
+$as_echo_n "checking for suffix of executables... " >&6; }
+if { { ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_link") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then :
+  # If both `conftest.exe' and `conftest' are `present' (well, observable)
+# catch `conftest.exe'.  For instance with Cygwin, `ls conftest' will
+# work properly (i.e., refer to `conftest.exe'), while it won't with
+# `rm'.
+for ac_file in conftest.exe conftest conftest.*; do
+  test -f "$ac_file" || continue
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
+    *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+	  break;;
+    * ) break;;
+  esac
+done
+else
+  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+rm -f conftest conftest$ac_cv_exeext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5
+$as_echo "$ac_cv_exeext" >&6; }
+
+rm -f conftest.$ac_ext
+EXEEXT=$ac_cv_exeext
+ac_exeext=$EXEEXT
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdio.h>
+int
+main ()
+{
+FILE *f = fopen ("conftest.out", "w");
+ return ferror (f) || fclose (f) != 0;
+
+  ;
+  return 0;
+}
+_ACEOF
+ac_clean_files="$ac_clean_files conftest.out"
+# Check that the compiler produces executables we can run.  If not, either
+# the compiler is broken, or we cross compile.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5
+$as_echo_n "checking whether we are cross compiling... " >&6; }
+if test "$cross_compiling" != yes; then
+  { { ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_link") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+  if { ac_try='./conftest$ac_cv_exeext'
+  { { case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then
+    cross_compiling=no
+  else
+    if test "$cross_compiling" = maybe; then
+	cross_compiling=yes
+    else
+	{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details" "$LINENO" 5; }
+    fi
+  fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5
+$as_echo "$cross_compiling" >&6; }
+
+rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out
+ac_clean_files=$ac_clean_files_save
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5
+$as_echo_n "checking for suffix of object files... " >&6; }
+if ${ac_cv_objext+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.o conftest.obj
+if { { ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_compile") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then :
+  for ac_file in conftest.o conftest.obj conftest.*; do
+  test -f "$ac_file" || continue;
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;;
+    *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
+       break;;
+  esac
+done
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot compute suffix of object files: cannot compile
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+rm -f conftest.$ac_cv_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5
+$as_echo "$ac_cv_objext" >&6; }
+OBJEXT=$ac_cv_objext
+ac_objext=$OBJEXT
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5
+$as_echo_n "checking whether we are using the GNU C compiler... " >&6; }
+if ${ac_cv_c_compiler_gnu+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+#ifndef __GNUC__
+       choke me
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_compiler_gnu=yes
+else
+  ac_compiler_gnu=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_c_compiler_gnu=$ac_compiler_gnu
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5
+$as_echo "$ac_cv_c_compiler_gnu" >&6; }
+if test $ac_compiler_gnu = yes; then
+  GCC=yes
+else
+  GCC=
+fi
+ac_test_CFLAGS=${CFLAGS+set}
+ac_save_CFLAGS=$CFLAGS
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5
+$as_echo_n "checking whether $CC accepts -g... " >&6; }
+if ${ac_cv_prog_cc_g+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_save_c_werror_flag=$ac_c_werror_flag
+   ac_c_werror_flag=yes
+   ac_cv_prog_cc_g=no
+   CFLAGS="-g"
+   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_prog_cc_g=yes
+else
+  CFLAGS=""
+      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+else
+  ac_c_werror_flag=$ac_save_c_werror_flag
+	 CFLAGS="-g"
+	 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_prog_cc_g=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+   ac_c_werror_flag=$ac_save_c_werror_flag
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5
+$as_echo "$ac_cv_prog_cc_g" >&6; }
+if test "$ac_test_CFLAGS" = set; then
+  CFLAGS=$ac_save_CFLAGS
+elif test $ac_cv_prog_cc_g = yes; then
+  if test "$GCC" = yes; then
+    CFLAGS="-g -O2"
+  else
+    CFLAGS="-g"
+  fi
+else
+  if test "$GCC" = yes; then
+    CFLAGS="-O2"
+  else
+    CFLAGS=
+  fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5
+$as_echo_n "checking for $CC option to accept ISO C89... " >&6; }
+if ${ac_cv_prog_cc_c89+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_cv_prog_cc_c89=no
+ac_save_CC=$CC
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdarg.h>
+#include <stdio.h>
+struct stat;
+/* Most of the following tests are stolen from RCS 5.7's src/conf.sh.  */
+struct buf { int x; };
+FILE * (*rcsopen) (struct buf *, struct stat *, int);
+static char *e (p, i)
+     char **p;
+     int i;
+{
+  return p[i];
+}
+static char *f (char * (*g) (char **, int), char **p, ...)
+{
+  char *s;
+  va_list v;
+  va_start (v,p);
+  s = g (p, va_arg (v,int));
+  va_end (v);
+  return s;
+}
+
+/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default.  It has
+   function prototypes and stuff, but not '\xHH' hex character constants.
+   These don't provoke an error unfortunately, instead are silently treated
+   as 'x'.  The following induces an error, until -std is added to get
+   proper ANSI mode.  Curiously '\x00'!='x' always comes out true, for an
+   array size at least.  It's necessary to write '\x00'==0 to get something
+   that's true only with -std.  */
+int osf4_cc_array ['\x00' == 0 ? 1 : -1];
+
+/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters
+   inside strings and character constants.  */
+#define FOO(x) 'x'
+int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1];
+
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
+int argc;
+char **argv;
+int
+main ()
+{
+return f (e, argv, 0) != argv[0]  ||  f (e, argv, 1) != argv[1];
+  ;
+  return 0;
+}
+_ACEOF
+for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \
+	-Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+  CC="$ac_save_CC $ac_arg"
+  if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_prog_cc_c89=$ac_arg
+fi
+rm -f core conftest.err conftest.$ac_objext
+  test "x$ac_cv_prog_cc_c89" != "xno" && break
+done
+rm -f conftest.$ac_ext
+CC=$ac_save_CC
+
+fi
+# AC_CACHE_VAL
+case "x$ac_cv_prog_cc_c89" in
+  x)
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
+$as_echo "none needed" >&6; } ;;
+  xno)
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
+$as_echo "unsupported" >&6; } ;;
+  *)
+    CC="$CC $ac_cv_prog_cc_c89"
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5
+$as_echo "$ac_cv_prog_cc_c89" >&6; } ;;
+esac
+if test "x$ac_cv_prog_cc_c89" != xno; then :
+
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5
+$as_echo_n "checking whether $CC understands -c and -o together... " >&6; }
+if ${am_cv_prog_cc_c_o+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+  # Make sure it works both with $CC and with simple cc.
+  # Following AC_PROG_CC_C_O, we do the test twice because some
+  # compilers refuse to overwrite an existing .o file with -o,
+  # though they will create one.
+  am_cv_prog_cc_c_o=yes
+  for am_i in 1 2; do
+    if { echo "$as_me:$LINENO: $CC -c conftest.$ac_ext -o conftest2.$ac_objext" >&5
+   ($CC -c conftest.$ac_ext -o conftest2.$ac_objext) >&5 2>&5
+   ac_status=$?
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
+   (exit $ac_status); } \
+         && test -f conftest2.$ac_objext; then
+      : OK
+    else
+      am_cv_prog_cc_c_o=no
+      break
+    fi
+  done
+  rm -f core conftest*
+  unset am_i
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5
+$as_echo "$am_cv_prog_cc_c_o" >&6; }
+if test "$am_cv_prog_cc_c_o" != yes; then
+   # Losing compiler, so override with the script.
+   # FIXME: It is wrong to rewrite CC.
+   # But if we don't then we get into trouble of one sort or another.
+   # A longer-term fix would be to have automake use am__CC in this case,
+   # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)"
+   CC="$am_aux_dir/compile $CC"
+fi
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+DEPDIR="${am__leading_dot}deps"
+
+ac_config_commands="$ac_config_commands depfiles"
+
+
+am_make=${MAKE-make}
+cat > confinc << 'END'
+am__doit:
+	@echo this is the am__doit target
+.PHONY: am__doit
+END
+# If we don't find an include directive, just comment out the code.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5
+$as_echo_n "checking for style of include used by $am_make... " >&6; }
+am__include="#"
+am__quote=
+_am_result=none
+# First try GNU make style include.
+echo "include confinc" > confmf
+# Ignore all kinds of additional output from 'make'.
+case `$am_make -s -f confmf 2> /dev/null` in #(
+*the\ am__doit\ target*)
+  am__include=include
+  am__quote=
+  _am_result=GNU
+  ;;
+esac
+# Now try BSD make style include.
+if test "$am__include" = "#"; then
+   echo '.include "confinc"' > confmf
+   case `$am_make -s -f confmf 2> /dev/null` in #(
+   *the\ am__doit\ target*)
+     am__include=.include
+     am__quote="\""
+     _am_result=BSD
+     ;;
+   esac
+fi
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5
+$as_echo "$_am_result" >&6; }
+rm -f confinc confmf
+
+# Check whether --enable-dependency-tracking was given.
+if test "${enable_dependency_tracking+set}" = set; then :
+  enableval=$enable_dependency_tracking;
+fi
+
+if test "x$enable_dependency_tracking" != xno; then
+  am_depcomp="$ac_aux_dir/depcomp"
+  AMDEPBACKSLASH='\'
+  am__nodep='_no'
+fi
+ if test "x$enable_dependency_tracking" != xno; then
+  AMDEP_TRUE=
+  AMDEP_FALSE='#'
+else
+  AMDEP_TRUE='#'
+  AMDEP_FALSE=
+fi
+
+
+
+depcc="$CC"   am_compiler_list=
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5
+$as_echo_n "checking dependency style of $depcc... " >&6; }
+if ${am_cv_CC_dependencies_compiler_type+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
+  # We make a subdir and do the tests there.  Otherwise we can end up
+  # making bogus files that we don't know about and never remove.  For
+  # instance it was reported that on HP-UX the gcc test will end up
+  # making a dummy file named 'D' -- because '-MD' means "put the output
+  # in D".
+  rm -rf conftest.dir
+  mkdir conftest.dir
+  # Copy depcomp to subdir because otherwise we won't find it if we're
+  # using a relative directory.
+  cp "$am_depcomp" conftest.dir
+  cd conftest.dir
+  # We will build objects and dependencies in a subdirectory because
+  # it helps to detect inapplicable dependency modes.  For instance
+  # both Tru64's cc and ICC support -MD to output dependencies as a
+  # side effect of compilation, but ICC will put the dependencies in
+  # the current directory while Tru64 will put them in the object
+  # directory.
+  mkdir sub
+
+  am_cv_CC_dependencies_compiler_type=none
+  if test "$am_compiler_list" = ""; then
+     am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp`
+  fi
+  am__universal=false
+  case " $depcc " in #(
+     *\ -arch\ *\ -arch\ *) am__universal=true ;;
+     esac
+
+  for depmode in $am_compiler_list; do
+    # Setup a source with many dependencies, because some compilers
+    # like to wrap large dependency lists on column 80 (with \), and
+    # we should not choose a depcomp mode which is confused by this.
+    #
+    # We need to recreate these files for each test, as the compiler may
+    # overwrite some of them when testing with obscure command lines.
+    # This happens at least with the AIX C compiler.
+    : > sub/conftest.c
+    for i in 1 2 3 4 5 6; do
+      echo '#include "conftst'$i'.h"' >> sub/conftest.c
+      # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with
+      # Solaris 10 /bin/sh.
+      echo '/* dummy */' > sub/conftst$i.h
+    done
+    echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
+
+    # We check with '-c' and '-o' for the sake of the "dashmstdout"
+    # mode.  It turns out that the SunPro C++ compiler does not properly
+    # handle '-M -o', and we need to detect this.  Also, some Intel
+    # versions had trouble with output in subdirs.
+    am__obj=sub/conftest.${OBJEXT-o}
+    am__minus_obj="-o $am__obj"
+    case $depmode in
+    gcc)
+      # This depmode causes a compiler race in universal mode.
+      test "$am__universal" = false || continue
+      ;;
+    nosideeffect)
+      # After this tag, mechanisms are not by side-effect, so they'll
+      # only be used when explicitly requested.
+      if test "x$enable_dependency_tracking" = xyes; then
+	continue
+      else
+	break
+      fi
+      ;;
+    msvc7 | msvc7msys | msvisualcpp | msvcmsys)
+      # This compiler won't grok '-c -o', but also, the minuso test has
+      # not run yet.  These depmodes are late enough in the game, and
+      # so weak that their functioning should not be impacted.
+      am__obj=conftest.${OBJEXT-o}
+      am__minus_obj=
+      ;;
+    none) break ;;
+    esac
+    if depmode=$depmode \
+       source=sub/conftest.c object=$am__obj \
+       depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
+       $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \
+         >/dev/null 2>conftest.err &&
+       grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 &&
+       grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
+       grep $am__obj sub/conftest.Po > /dev/null 2>&1 &&
+       ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
+      # icc doesn't choke on unknown options, it will just issue warnings
+      # or remarks (even with -Werror).  So we grep stderr for any message
+      # that says an option was ignored or not supported.
+      # When given -MP, icc 7.0 and 7.1 complain thusly:
+      #   icc: Command line warning: ignoring option '-M'; no argument required
+      # The diagnosis changed in icc 8.0:
+      #   icc: Command line remark: option '-MP' not supported
+      if (grep 'ignoring option' conftest.err ||
+          grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
+        am_cv_CC_dependencies_compiler_type=$depmode
+        break
+      fi
+    fi
+  done
+
+  cd ..
+  rm -rf conftest.dir
+else
+  am_cv_CC_dependencies_compiler_type=none
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5
+$as_echo "$am_cv_CC_dependencies_compiler_type" >&6; }
+CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type
+
+ if
+  test "x$enable_dependency_tracking" != xno \
+  && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then
+  am__fastdepCC_TRUE=
+  am__fastdepCC_FALSE='#'
+else
+  am__fastdepCC_TRUE='#'
+  am__fastdepCC_FALSE=
+fi
+
+
+case `pwd` in
+  *\ * | *\	*)
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&5
+$as_echo "$as_me: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&2;} ;;
+esac
+
+
+
+macro_version='2.4.6'
+macro_revision='2.4.6'
+
+
+
+
+
+
+
+
+
+
+
+
+
+ltmain=$ac_aux_dir/ltmain.sh
+
+# Backslashify metacharacters that are still active within
+# double-quoted strings.
+sed_quote_subst='s/\(["`$\\]\)/\\\1/g'
+
+# Same as above, but do not quote variable references.
+double_quote_subst='s/\(["`\\]\)/\\\1/g'
+
+# Sed substitution to delay expansion of an escaped shell variable in a
+# double_quote_subst'ed string.
+delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g'
+
+# Sed substitution to delay expansion of an escaped single quote.
+delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g'
+
+# Sed substitution to avoid accidental globbing in evaled expressions
+no_glob_subst='s/\*/\\\*/g'
+
+ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO
+ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to print strings" >&5
+$as_echo_n "checking how to print strings... " >&6; }
+# Test print first, because it will be a builtin if present.
+if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \
+   test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then
+  ECHO='print -r --'
+elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then
+  ECHO='printf %s\n'
+else
+  # Use this function as a fallback that always works.
+  func_fallback_echo ()
+  {
+    eval 'cat <<_LTECHO_EOF
+$1
+_LTECHO_EOF'
+  }
+  ECHO='func_fallback_echo'
+fi
+
+# func_echo_all arg...
+# Invoke $ECHO with all args, space-separated.
+func_echo_all ()
+{
+    $ECHO ""
+}
+
+case $ECHO in
+  printf*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: printf" >&5
+$as_echo "printf" >&6; } ;;
+  print*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: print -r" >&5
+$as_echo "print -r" >&6; } ;;
+  *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: cat" >&5
+$as_echo "cat" >&6; } ;;
+esac
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5
+$as_echo_n "checking for a sed that does not truncate output... " >&6; }
+if ${ac_cv_path_SED+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+            ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/
+     for ac_i in 1 2 3 4 5 6 7; do
+       ac_script="$ac_script$as_nl$ac_script"
+     done
+     echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed
+     { ac_script=; unset ac_script;}
+     if test -z "$SED"; then
+  ac_path_SED_found=false
+  # Loop through the user's path and test for each of PROGNAME-LIST
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_prog in sed gsed; do
+    for ac_exec_ext in '' $ac_executable_extensions; do
+      ac_path_SED="$as_dir/$ac_prog$ac_exec_ext"
+      as_fn_executable_p "$ac_path_SED" || continue
+# Check for GNU ac_path_SED and select it if it is found.
+  # Check for GNU $ac_path_SED
+case `"$ac_path_SED" --version 2>&1` in
+*GNU*)
+  ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;;
+*)
+  ac_count=0
+  $as_echo_n 0123456789 >"conftest.in"
+  while :
+  do
+    cat "conftest.in" "conftest.in" >"conftest.tmp"
+    mv "conftest.tmp" "conftest.in"
+    cp "conftest.in" "conftest.nl"
+    $as_echo '' >> "conftest.nl"
+    "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break
+    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+    as_fn_arith $ac_count + 1 && ac_count=$as_val
+    if test $ac_count -gt ${ac_path_SED_max-0}; then
+      # Best one so far, save it but keep looking for a better one
+      ac_cv_path_SED="$ac_path_SED"
+      ac_path_SED_max=$ac_count
+    fi
+    # 10*(2^10) chars as input seems more than enough
+    test $ac_count -gt 10 && break
+  done
+  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+      $ac_path_SED_found && break 3
+    done
+  done
+  done
+IFS=$as_save_IFS
+  if test -z "$ac_cv_path_SED"; then
+    as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5
+  fi
+else
+  ac_cv_path_SED=$SED
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5
+$as_echo "$ac_cv_path_SED" >&6; }
+ SED="$ac_cv_path_SED"
+  rm -f conftest.sed
+
+test -z "$SED" && SED=sed
+Xsed="$SED -e 1s/^X//"
+
+
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5
+$as_echo_n "checking for grep that handles long lines and -e... " >&6; }
+if ${ac_cv_path_GREP+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -z "$GREP"; then
+  ac_path_GREP_found=false
+  # Loop through the user's path and test for each of PROGNAME-LIST
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_prog in grep ggrep; do
+    for ac_exec_ext in '' $ac_executable_extensions; do
+      ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext"
+      as_fn_executable_p "$ac_path_GREP" || continue
+# Check for GNU ac_path_GREP and select it if it is found.
+  # Check for GNU $ac_path_GREP
+case `"$ac_path_GREP" --version 2>&1` in
+*GNU*)
+  ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;;
+*)
+  ac_count=0
+  $as_echo_n 0123456789 >"conftest.in"
+  while :
+  do
+    cat "conftest.in" "conftest.in" >"conftest.tmp"
+    mv "conftest.tmp" "conftest.in"
+    cp "conftest.in" "conftest.nl"
+    $as_echo 'GREP' >> "conftest.nl"
+    "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+    as_fn_arith $ac_count + 1 && ac_count=$as_val
+    if test $ac_count -gt ${ac_path_GREP_max-0}; then
+      # Best one so far, save it but keep looking for a better one
+      ac_cv_path_GREP="$ac_path_GREP"
+      ac_path_GREP_max=$ac_count
+    fi
+    # 10*(2^10) chars as input seems more than enough
+    test $ac_count -gt 10 && break
+  done
+  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+      $ac_path_GREP_found && break 3
+    done
+  done
+  done
+IFS=$as_save_IFS
+  if test -z "$ac_cv_path_GREP"; then
+    as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+  fi
+else
+  ac_cv_path_GREP=$GREP
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5
+$as_echo "$ac_cv_path_GREP" >&6; }
+ GREP="$ac_cv_path_GREP"
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5
+$as_echo_n "checking for egrep... " >&6; }
+if ${ac_cv_path_EGREP+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if echo a | $GREP -E '(a|b)' >/dev/null 2>&1
+   then ac_cv_path_EGREP="$GREP -E"
+   else
+     if test -z "$EGREP"; then
+  ac_path_EGREP_found=false
+  # Loop through the user's path and test for each of PROGNAME-LIST
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_prog in egrep; do
+    for ac_exec_ext in '' $ac_executable_extensions; do
+      ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext"
+      as_fn_executable_p "$ac_path_EGREP" || continue
+# Check for GNU ac_path_EGREP and select it if it is found.
+  # Check for GNU $ac_path_EGREP
+case `"$ac_path_EGREP" --version 2>&1` in
+*GNU*)
+  ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;;
+*)
+  ac_count=0
+  $as_echo_n 0123456789 >"conftest.in"
+  while :
+  do
+    cat "conftest.in" "conftest.in" >"conftest.tmp"
+    mv "conftest.tmp" "conftest.in"
+    cp "conftest.in" "conftest.nl"
+    $as_echo 'EGREP' >> "conftest.nl"
+    "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+    as_fn_arith $ac_count + 1 && ac_count=$as_val
+    if test $ac_count -gt ${ac_path_EGREP_max-0}; then
+      # Best one so far, save it but keep looking for a better one
+      ac_cv_path_EGREP="$ac_path_EGREP"
+      ac_path_EGREP_max=$ac_count
+    fi
+    # 10*(2^10) chars as input seems more than enough
+    test $ac_count -gt 10 && break
+  done
+  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+      $ac_path_EGREP_found && break 3
+    done
+  done
+  done
+IFS=$as_save_IFS
+  if test -z "$ac_cv_path_EGREP"; then
+    as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+  fi
+else
+  ac_cv_path_EGREP=$EGREP
+fi
+
+   fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5
+$as_echo "$ac_cv_path_EGREP" >&6; }
+ EGREP="$ac_cv_path_EGREP"
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5
+$as_echo_n "checking for fgrep... " >&6; }
+if ${ac_cv_path_FGREP+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if echo 'ab*c' | $GREP -F 'ab*c' >/dev/null 2>&1
+   then ac_cv_path_FGREP="$GREP -F"
+   else
+     if test -z "$FGREP"; then
+  ac_path_FGREP_found=false
+  # Loop through the user's path and test for each of PROGNAME-LIST
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_prog in fgrep; do
+    for ac_exec_ext in '' $ac_executable_extensions; do
+      ac_path_FGREP="$as_dir/$ac_prog$ac_exec_ext"
+      as_fn_executable_p "$ac_path_FGREP" || continue
+# Check for GNU ac_path_FGREP and select it if it is found.
+  # Check for GNU $ac_path_FGREP
+case `"$ac_path_FGREP" --version 2>&1` in
+*GNU*)
+  ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_found=:;;
+*)
+  ac_count=0
+  $as_echo_n 0123456789 >"conftest.in"
+  while :
+  do
+    cat "conftest.in" "conftest.in" >"conftest.tmp"
+    mv "conftest.tmp" "conftest.in"
+    cp "conftest.in" "conftest.nl"
+    $as_echo 'FGREP' >> "conftest.nl"
+    "$ac_path_FGREP" FGREP < "conftest.nl" >"conftest.out" 2>/dev/null || break
+    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+    as_fn_arith $ac_count + 1 && ac_count=$as_val
+    if test $ac_count -gt ${ac_path_FGREP_max-0}; then
+      # Best one so far, save it but keep looking for a better one
+      ac_cv_path_FGREP="$ac_path_FGREP"
+      ac_path_FGREP_max=$ac_count
+    fi
+    # 10*(2^10) chars as input seems more than enough
+    test $ac_count -gt 10 && break
+  done
+  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+      $ac_path_FGREP_found && break 3
+    done
+  done
+  done
+IFS=$as_save_IFS
+  if test -z "$ac_cv_path_FGREP"; then
+    as_fn_error $? "no acceptable fgrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+  fi
+else
+  ac_cv_path_FGREP=$FGREP
+fi
+
+   fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_FGREP" >&5
+$as_echo "$ac_cv_path_FGREP" >&6; }
+ FGREP="$ac_cv_path_FGREP"
+
+
+test -z "$GREP" && GREP=grep
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# Check whether --with-gnu-ld was given.
+if test "${with_gnu_ld+set}" = set; then :
+  withval=$with_gnu_ld; test no = "$withval" || with_gnu_ld=yes
+else
+  with_gnu_ld=no
+fi
+
+ac_prog=ld
+if test yes = "$GCC"; then
+  # Check if gcc -print-prog-name=ld gives a path.
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5
+$as_echo_n "checking for ld used by $CC... " >&6; }
+  case $host in
+  *-*-mingw*)
+    # gcc leaves a trailing carriage return, which upsets mingw
+    ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
+  *)
+    ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
+  esac
+  case $ac_prog in
+    # Accept absolute paths.
+    [\\/]* | ?:[\\/]*)
+      re_direlt='/[^/][^/]*/\.\./'
+      # Canonicalize the pathname of ld
+      ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'`
+      while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do
+	ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"`
+      done
+      test -z "$LD" && LD=$ac_prog
+      ;;
+  "")
+    # If it fails, then pretend we aren't using GCC.
+    ac_prog=ld
+    ;;
+  *)
+    # If it is relative, then search for the first ld in PATH.
+    with_gnu_ld=unknown
+    ;;
+  esac
+elif test yes = "$with_gnu_ld"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5
+$as_echo_n "checking for GNU ld... " >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5
+$as_echo_n "checking for non-GNU ld... " >&6; }
+fi
+if ${lt_cv_path_LD+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -z "$LD"; then
+  lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR
+  for ac_dir in $PATH; do
+    IFS=$lt_save_ifs
+    test -z "$ac_dir" && ac_dir=.
+    if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+      lt_cv_path_LD=$ac_dir/$ac_prog
+      # Check to see if the program is GNU ld.  I'd rather use --version,
+      # but apparently some variants of GNU ld only accept -v.
+      # Break only if it was the GNU/non-GNU ld that we prefer.
+      case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in
+      *GNU* | *'with BFD'*)
+	test no != "$with_gnu_ld" && break
+	;;
+      *)
+	test yes != "$with_gnu_ld" && break
+	;;
+      esac
+    fi
+  done
+  IFS=$lt_save_ifs
+else
+  lt_cv_path_LD=$LD # Let the user override the test with a path.
+fi
+fi
+
+LD=$lt_cv_path_LD
+if test -n "$LD"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LD" >&5
+$as_echo "$LD" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5
+$as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; }
+if ${lt_cv_prog_gnu_ld+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  # I'd rather use --version here, but apparently some GNU lds only accept -v.
+case `$LD -v 2>&1 </dev/null` in
+*GNU* | *'with BFD'*)
+  lt_cv_prog_gnu_ld=yes
+  ;;
+*)
+  lt_cv_prog_gnu_ld=no
+  ;;
+esac
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_gnu_ld" >&5
+$as_echo "$lt_cv_prog_gnu_ld" >&6; }
+with_gnu_ld=$lt_cv_prog_gnu_ld
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for BSD- or MS-compatible name lister (nm)" >&5
+$as_echo_n "checking for BSD- or MS-compatible name lister (nm)... " >&6; }
+if ${lt_cv_path_NM+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$NM"; then
+  # Let the user override the test.
+  lt_cv_path_NM=$NM
+else
+  lt_nm_to_check=${ac_tool_prefix}nm
+  if test -n "$ac_tool_prefix" && test "$build" = "$host"; then
+    lt_nm_to_check="$lt_nm_to_check nm"
+  fi
+  for lt_tmp_nm in $lt_nm_to_check; do
+    lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR
+    for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do
+      IFS=$lt_save_ifs
+      test -z "$ac_dir" && ac_dir=.
+      tmp_nm=$ac_dir/$lt_tmp_nm
+      if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext"; then
+	# Check to see if the nm accepts a BSD-compat flag.
+	# Adding the 'sed 1q' prevents false positives on HP-UX, which says:
+	#   nm: unknown option "B" ignored
+	# Tru64's nm complains that /dev/null is an invalid object file
+	# MSYS converts /dev/null to NUL, MinGW nm treats NUL as empty
+	case $build_os in
+	mingw*) lt_bad_file=conftest.nm/nofile ;;
+	*) lt_bad_file=/dev/null ;;
+	esac
+	case `"$tmp_nm" -B $lt_bad_file 2>&1 | sed '1q'` in
+	*$lt_bad_file* | *'Invalid file or object type'*)
+	  lt_cv_path_NM="$tmp_nm -B"
+	  break 2
+	  ;;
+	*)
+	  case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in
+	  */dev/null*)
+	    lt_cv_path_NM="$tmp_nm -p"
+	    break 2
+	    ;;
+	  *)
+	    lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but
+	    continue # so that we can try to find one that supports BSD flags
+	    ;;
+	  esac
+	  ;;
+	esac
+      fi
+    done
+    IFS=$lt_save_ifs
+  done
+  : ${lt_cv_path_NM=no}
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_NM" >&5
+$as_echo "$lt_cv_path_NM" >&6; }
+if test no != "$lt_cv_path_NM"; then
+  NM=$lt_cv_path_NM
+else
+  # Didn't find any BSD compatible name lister, look for dumpbin.
+  if test -n "$DUMPBIN"; then :
+    # Let the user override the test.
+  else
+    if test -n "$ac_tool_prefix"; then
+  for ac_prog in dumpbin "link -dump"
+  do
+    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_DUMPBIN+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$DUMPBIN"; then
+  ac_cv_prog_DUMPBIN="$DUMPBIN" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_DUMPBIN="$ac_tool_prefix$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+DUMPBIN=$ac_cv_prog_DUMPBIN
+if test -n "$DUMPBIN"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DUMPBIN" >&5
+$as_echo "$DUMPBIN" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+    test -n "$DUMPBIN" && break
+  done
+fi
+if test -z "$DUMPBIN"; then
+  ac_ct_DUMPBIN=$DUMPBIN
+  for ac_prog in dumpbin "link -dump"
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_DUMPBIN+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_DUMPBIN"; then
+  ac_cv_prog_ac_ct_DUMPBIN="$ac_ct_DUMPBIN" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_DUMPBIN="$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_DUMPBIN=$ac_cv_prog_ac_ct_DUMPBIN
+if test -n "$ac_ct_DUMPBIN"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DUMPBIN" >&5
+$as_echo "$ac_ct_DUMPBIN" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  test -n "$ac_ct_DUMPBIN" && break
+done
+
+  if test "x$ac_ct_DUMPBIN" = x; then
+    DUMPBIN=":"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    DUMPBIN=$ac_ct_DUMPBIN
+  fi
+fi
+
+    case `$DUMPBIN -symbols -headers /dev/null 2>&1 | sed '1q'` in
+    *COFF*)
+      DUMPBIN="$DUMPBIN -symbols -headers"
+      ;;
+    *)
+      DUMPBIN=:
+      ;;
+    esac
+  fi
+
+  if test : != "$DUMPBIN"; then
+    NM=$DUMPBIN
+  fi
+fi
+test -z "$NM" && NM=nm
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the name lister ($NM) interface" >&5
+$as_echo_n "checking the name lister ($NM) interface... " >&6; }
+if ${lt_cv_nm_interface+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_nm_interface="BSD nm"
+  echo "int some_variable = 0;" > conftest.$ac_ext
+  (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&5)
+  (eval "$ac_compile" 2>conftest.err)
+  cat conftest.err >&5
+  (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
+  (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out)
+  cat conftest.err >&5
+  (eval echo "\"\$as_me:$LINENO: output\"" >&5)
+  cat conftest.out >&5
+  if $GREP 'External.*some_variable' conftest.out > /dev/null; then
+    lt_cv_nm_interface="MS dumpbin"
+  fi
+  rm -f conftest*
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_nm_interface" >&5
+$as_echo "$lt_cv_nm_interface" >&6; }
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5
+$as_echo_n "checking whether ln -s works... " >&6; }
+LN_S=$as_ln_s
+if test "$LN_S" = "ln -s"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5
+$as_echo "no, using $LN_S" >&6; }
+fi
+
+# find the maximum length of command line arguments
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the maximum length of command line arguments" >&5
+$as_echo_n "checking the maximum length of command line arguments... " >&6; }
+if ${lt_cv_sys_max_cmd_len+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+    i=0
+  teststring=ABCD
+
+  case $build_os in
+  msdosdjgpp*)
+    # On DJGPP, this test can blow up pretty badly due to problems in libc
+    # (any single argument exceeding 2000 bytes causes a buffer overrun
+    # during glob expansion).  Even if it were fixed, the result of this
+    # check would be larger than it should be.
+    lt_cv_sys_max_cmd_len=12288;    # 12K is about right
+    ;;
+
+  gnu*)
+    # Under GNU Hurd, this test is not required because there is
+    # no limit to the length of command line arguments.
+    # Libtool will interpret -1 as no limit whatsoever
+    lt_cv_sys_max_cmd_len=-1;
+    ;;
+
+  cygwin* | mingw* | cegcc*)
+    # On Win9x/ME, this test blows up -- it succeeds, but takes
+    # about 5 minutes as the teststring grows exponentially.
+    # Worse, since 9x/ME are not pre-emptively multitasking,
+    # you end up with a "frozen" computer, even though with patience
+    # the test eventually succeeds (with a max line length of 256k).
+    # Instead, let's just punt: use the minimum linelength reported by
+    # all of the supported platforms: 8192 (on NT/2K/XP).
+    lt_cv_sys_max_cmd_len=8192;
+    ;;
+
+  mint*)
+    # On MiNT this can take a long time and run out of memory.
+    lt_cv_sys_max_cmd_len=8192;
+    ;;
+
+  amigaos*)
+    # On AmigaOS with pdksh, this test takes hours, literally.
+    # So we just punt and use a minimum line length of 8192.
+    lt_cv_sys_max_cmd_len=8192;
+    ;;
+
+  bitrig* | darwin* | dragonfly* | freebsd* | netbsd* | openbsd*)
+    # This has been around since 386BSD, at least.  Likely further.
+    if test -x /sbin/sysctl; then
+      lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax`
+    elif test -x /usr/sbin/sysctl; then
+      lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax`
+    else
+      lt_cv_sys_max_cmd_len=65536	# usable default for all BSDs
+    fi
+    # And add a safety zone
+    lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
+    lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
+    ;;
+
+  interix*)
+    # We know the value 262144 and hardcode it with a safety zone (like BSD)
+    lt_cv_sys_max_cmd_len=196608
+    ;;
+
+  os2*)
+    # The test takes a long time on OS/2.
+    lt_cv_sys_max_cmd_len=8192
+    ;;
+
+  osf*)
+    # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure
+    # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not
+    # nice to cause kernel panics so lets avoid the loop below.
+    # First set a reasonable default.
+    lt_cv_sys_max_cmd_len=16384
+    #
+    if test -x /sbin/sysconfig; then
+      case `/sbin/sysconfig -q proc exec_disable_arg_limit` in
+        *1*) lt_cv_sys_max_cmd_len=-1 ;;
+      esac
+    fi
+    ;;
+  sco3.2v5*)
+    lt_cv_sys_max_cmd_len=102400
+    ;;
+  sysv5* | sco5v6* | sysv4.2uw2*)
+    kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null`
+    if test -n "$kargmax"; then
+      lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[	 ]//'`
+    else
+      lt_cv_sys_max_cmd_len=32768
+    fi
+    ;;
+  *)
+    lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null`
+    if test -n "$lt_cv_sys_max_cmd_len" && \
+       test undefined != "$lt_cv_sys_max_cmd_len"; then
+      lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
+      lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
+    else
+      # Make teststring a little bigger before we do anything with it.
+      # a 1K string should be a reasonable start.
+      for i in 1 2 3 4 5 6 7 8; do
+        teststring=$teststring$teststring
+      done
+      SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}}
+      # If test is not a shell built-in, we'll probably end up computing a
+      # maximum length that is only half of the actual maximum length, but
+      # we can't tell.
+      while { test X`env echo "$teststring$teststring" 2>/dev/null` \
+	         = "X$teststring$teststring"; } >/dev/null 2>&1 &&
+	      test 17 != "$i" # 1/2 MB should be enough
+      do
+        i=`expr $i + 1`
+        teststring=$teststring$teststring
+      done
+      # Only check the string length outside the loop.
+      lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1`
+      teststring=
+      # Add a significant safety factor because C++ compilers can tack on
+      # massive amounts of additional arguments before passing them to the
+      # linker.  It appears as though 1/2 is a usable value.
+      lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2`
+    fi
+    ;;
+  esac
+
+fi
+
+if test -n "$lt_cv_sys_max_cmd_len"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sys_max_cmd_len" >&5
+$as_echo "$lt_cv_sys_max_cmd_len" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: none" >&5
+$as_echo "none" >&6; }
+fi
+max_cmd_len=$lt_cv_sys_max_cmd_len
+
+
+
+
+
+
+: ${CP="cp -f"}
+: ${MV="mv -f"}
+: ${RM="rm -f"}
+
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+  lt_unset=unset
+else
+  lt_unset=false
+fi
+
+
+
+
+
+# test EBCDIC or ASCII
+case `echo X|tr X '\101'` in
+ A) # ASCII based system
+    # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr
+  lt_SP2NL='tr \040 \012'
+  lt_NL2SP='tr \015\012 \040\040'
+  ;;
+ *) # EBCDIC based system
+  lt_SP2NL='tr \100 \n'
+  lt_NL2SP='tr \r\n \100\100'
+  ;;
+esac
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to $host format" >&5
+$as_echo_n "checking how to convert $build file names to $host format... " >&6; }
+if ${lt_cv_to_host_file_cmd+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $host in
+  *-*-mingw* )
+    case $build in
+      *-*-mingw* ) # actually msys
+        lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32
+        ;;
+      *-*-cygwin* )
+        lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32
+        ;;
+      * ) # otherwise, assume *nix
+        lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32
+        ;;
+    esac
+    ;;
+  *-*-cygwin* )
+    case $build in
+      *-*-mingw* ) # actually msys
+        lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin
+        ;;
+      *-*-cygwin* )
+        lt_cv_to_host_file_cmd=func_convert_file_noop
+        ;;
+      * ) # otherwise, assume *nix
+        lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin
+        ;;
+    esac
+    ;;
+  * ) # unhandled hosts (and "normal" native builds)
+    lt_cv_to_host_file_cmd=func_convert_file_noop
+    ;;
+esac
+
+fi
+
+to_host_file_cmd=$lt_cv_to_host_file_cmd
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_host_file_cmd" >&5
+$as_echo "$lt_cv_to_host_file_cmd" >&6; }
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to toolchain format" >&5
+$as_echo_n "checking how to convert $build file names to toolchain format... " >&6; }
+if ${lt_cv_to_tool_file_cmd+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  #assume ordinary cross tools, or native build.
+lt_cv_to_tool_file_cmd=func_convert_file_noop
+case $host in
+  *-*-mingw* )
+    case $build in
+      *-*-mingw* ) # actually msys
+        lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32
+        ;;
+    esac
+    ;;
+esac
+
+fi
+
+to_tool_file_cmd=$lt_cv_to_tool_file_cmd
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_tool_file_cmd" >&5
+$as_echo "$lt_cv_to_tool_file_cmd" >&6; }
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $LD option to reload object files" >&5
+$as_echo_n "checking for $LD option to reload object files... " >&6; }
+if ${lt_cv_ld_reload_flag+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_ld_reload_flag='-r'
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_reload_flag" >&5
+$as_echo "$lt_cv_ld_reload_flag" >&6; }
+reload_flag=$lt_cv_ld_reload_flag
+case $reload_flag in
+"" | " "*) ;;
+*) reload_flag=" $reload_flag" ;;
+esac
+reload_cmds='$LD$reload_flag -o $output$reload_objs'
+case $host_os in
+  cygwin* | mingw* | pw32* | cegcc*)
+    if test yes != "$GCC"; then
+      reload_cmds=false
+    fi
+    ;;
+  darwin*)
+    if test yes = "$GCC"; then
+      reload_cmds='$LTCC $LTCFLAGS -nostdlib $wl-r -o $output$reload_objs'
+    else
+      reload_cmds='$LD$reload_flag -o $output$reload_objs'
+    fi
+    ;;
+esac
+
+
+
+
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args.
+set dummy ${ac_tool_prefix}objdump; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_OBJDUMP+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$OBJDUMP"; then
+  ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+OBJDUMP=$ac_cv_prog_OBJDUMP
+if test -n "$OBJDUMP"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5
+$as_echo "$OBJDUMP" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_OBJDUMP"; then
+  ac_ct_OBJDUMP=$OBJDUMP
+  # Extract the first word of "objdump", so it can be a program name with args.
+set dummy objdump; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_OBJDUMP+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_OBJDUMP"; then
+  ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_OBJDUMP="objdump"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP
+if test -n "$ac_ct_OBJDUMP"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5
+$as_echo "$ac_ct_OBJDUMP" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_OBJDUMP" = x; then
+    OBJDUMP="false"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    OBJDUMP=$ac_ct_OBJDUMP
+  fi
+else
+  OBJDUMP="$ac_cv_prog_OBJDUMP"
+fi
+
+test -z "$OBJDUMP" && OBJDUMP=objdump
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to recognize dependent libraries" >&5
+$as_echo_n "checking how to recognize dependent libraries... " >&6; }
+if ${lt_cv_deplibs_check_method+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_file_magic_cmd='$MAGIC_CMD'
+lt_cv_file_magic_test_file=
+lt_cv_deplibs_check_method='unknown'
+# Need to set the preceding variable on all platforms that support
+# interlibrary dependencies.
+# 'none' -- dependencies not supported.
+# 'unknown' -- same as none, but documents that we really don't know.
+# 'pass_all' -- all dependencies passed with no checks.
+# 'test_compile' -- check by making test program.
+# 'file_magic [[regex]]' -- check by looking for files in library path
+# that responds to the $file_magic_cmd with a given extended regex.
+# If you have 'file' or equivalent on your system and you're not sure
+# whether 'pass_all' will *always* work, you probably want this one.
+
+case $host_os in
+aix[4-9]*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+beos*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+bsdi[45]*)
+  lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)'
+  lt_cv_file_magic_cmd='/usr/bin/file -L'
+  lt_cv_file_magic_test_file=/shlib/libc.so
+  ;;
+
+cygwin*)
+  # func_win32_libid is a shell function defined in ltmain.sh
+  lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
+  lt_cv_file_magic_cmd='func_win32_libid'
+  ;;
+
+mingw* | pw32*)
+  # Base MSYS/MinGW do not provide the 'file' command needed by
+  # func_win32_libid shell function, so use a weaker test based on 'objdump',
+  # unless we find 'file', for example because we are cross-compiling.
+  if ( file / ) >/dev/null 2>&1; then
+    lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
+    lt_cv_file_magic_cmd='func_win32_libid'
+  else
+    # Keep this pattern in sync with the one in func_win32_libid.
+    lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)'
+    lt_cv_file_magic_cmd='$OBJDUMP -f'
+  fi
+  ;;
+
+cegcc*)
+  # use the weaker test based on 'objdump'. See mingw*.
+  lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?'
+  lt_cv_file_magic_cmd='$OBJDUMP -f'
+  ;;
+
+darwin* | rhapsody*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+freebsd* | dragonfly*)
+  if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
+    case $host_cpu in
+    i*86 )
+      # Not sure whether the presence of OpenBSD here was a mistake.
+      # Let's accept both of them until this is cleared up.
+      lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[3-9]86 (compact )?demand paged shared library'
+      lt_cv_file_magic_cmd=/usr/bin/file
+      lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*`
+      ;;
+    esac
+  else
+    lt_cv_deplibs_check_method=pass_all
+  fi
+  ;;
+
+haiku*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+hpux10.20* | hpux11*)
+  lt_cv_file_magic_cmd=/usr/bin/file
+  case $host_cpu in
+  ia64*)
+    lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64'
+    lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so
+    ;;
+  hppa*64*)
+    lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]'
+    lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl
+    ;;
+  *)
+    lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9]\.[0-9]) shared library'
+    lt_cv_file_magic_test_file=/usr/lib/libc.sl
+    ;;
+  esac
+  ;;
+
+interix[3-9]*)
+  # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here
+  lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|\.a)$'
+  ;;
+
+irix5* | irix6* | nonstopux*)
+  case $LD in
+  *-32|*"-32 ") libmagic=32-bit;;
+  *-n32|*"-n32 ") libmagic=N32;;
+  *-64|*"-64 ") libmagic=64-bit;;
+  *) libmagic=never-match;;
+  esac
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+# This must be glibc/ELF.
+linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+netbsd* | netbsdelf*-gnu)
+  if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
+    lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$'
+  else
+    lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|_pic\.a)$'
+  fi
+  ;;
+
+newos6*)
+  lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)'
+  lt_cv_file_magic_cmd=/usr/bin/file
+  lt_cv_file_magic_test_file=/usr/lib/libnls.so
+  ;;
+
+*nto* | *qnx*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+openbsd* | bitrig*)
+  if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then
+    lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$'
+  else
+    lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$'
+  fi
+  ;;
+
+osf3* | osf4* | osf5*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+rdos*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+solaris*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+sysv4 | sysv4.3*)
+  case $host_vendor in
+  motorola)
+    lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]'
+    lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*`
+    ;;
+  ncr)
+    lt_cv_deplibs_check_method=pass_all
+    ;;
+  sequent)
+    lt_cv_file_magic_cmd='/bin/file'
+    lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )'
+    ;;
+  sni)
+    lt_cv_file_magic_cmd='/bin/file'
+    lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib"
+    lt_cv_file_magic_test_file=/lib/libc.so
+    ;;
+  siemens)
+    lt_cv_deplibs_check_method=pass_all
+    ;;
+  pc)
+    lt_cv_deplibs_check_method=pass_all
+    ;;
+  esac
+  ;;
+
+tpf*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+os2*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+esac
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_deplibs_check_method" >&5
+$as_echo "$lt_cv_deplibs_check_method" >&6; }
+
+file_magic_glob=
+want_nocaseglob=no
+if test "$build" = "$host"; then
+  case $host_os in
+  mingw* | pw32*)
+    if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then
+      want_nocaseglob=yes
+    else
+      file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[\1]\/[\1]\/g;/g"`
+    fi
+    ;;
+  esac
+fi
+
+file_magic_cmd=$lt_cv_file_magic_cmd
+deplibs_check_method=$lt_cv_deplibs_check_method
+test -z "$deplibs_check_method" && deplibs_check_method=unknown
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args.
+set dummy ${ac_tool_prefix}dlltool; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_DLLTOOL+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$DLLTOOL"; then
+  ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+DLLTOOL=$ac_cv_prog_DLLTOOL
+if test -n "$DLLTOOL"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DLLTOOL" >&5
+$as_echo "$DLLTOOL" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_DLLTOOL"; then
+  ac_ct_DLLTOOL=$DLLTOOL
+  # Extract the first word of "dlltool", so it can be a program name with args.
+set dummy dlltool; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_DLLTOOL+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_DLLTOOL"; then
+  ac_cv_prog_ac_ct_DLLTOOL="$ac_ct_DLLTOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_DLLTOOL="dlltool"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_DLLTOOL=$ac_cv_prog_ac_ct_DLLTOOL
+if test -n "$ac_ct_DLLTOOL"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DLLTOOL" >&5
+$as_echo "$ac_ct_DLLTOOL" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_DLLTOOL" = x; then
+    DLLTOOL="false"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    DLLTOOL=$ac_ct_DLLTOOL
+  fi
+else
+  DLLTOOL="$ac_cv_prog_DLLTOOL"
+fi
+
+test -z "$DLLTOOL" && DLLTOOL=dlltool
+
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to associate runtime and link libraries" >&5
+$as_echo_n "checking how to associate runtime and link libraries... " >&6; }
+if ${lt_cv_sharedlib_from_linklib_cmd+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_sharedlib_from_linklib_cmd='unknown'
+
+case $host_os in
+cygwin* | mingw* | pw32* | cegcc*)
+  # two different shell functions defined in ltmain.sh;
+  # decide which one to use based on capabilities of $DLLTOOL
+  case `$DLLTOOL --help 2>&1` in
+  *--identify-strict*)
+    lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib
+    ;;
+  *)
+    lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback
+    ;;
+  esac
+  ;;
+*)
+  # fallback: assume linklib IS sharedlib
+  lt_cv_sharedlib_from_linklib_cmd=$ECHO
+  ;;
+esac
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sharedlib_from_linklib_cmd" >&5
+$as_echo "$lt_cv_sharedlib_from_linklib_cmd" >&6; }
+sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd
+test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO
+
+
+
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+  for ac_prog in ar
+  do
+    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_AR+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$AR"; then
+  ac_cv_prog_AR="$AR" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_AR="$ac_tool_prefix$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+AR=$ac_cv_prog_AR
+if test -n "$AR"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5
+$as_echo "$AR" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+    test -n "$AR" && break
+  done
+fi
+if test -z "$AR"; then
+  ac_ct_AR=$AR
+  for ac_prog in ar
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_AR+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_AR"; then
+  ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_AR="$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_AR=$ac_cv_prog_ac_ct_AR
+if test -n "$ac_ct_AR"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5
+$as_echo "$ac_ct_AR" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  test -n "$ac_ct_AR" && break
+done
+
+  if test "x$ac_ct_AR" = x; then
+    AR="false"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    AR=$ac_ct_AR
+  fi
+fi
+
+: ${AR=ar}
+: ${AR_FLAGS=cru}
+
+
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for archiver @FILE support" >&5
+$as_echo_n "checking for archiver @FILE support... " >&6; }
+if ${lt_cv_ar_at_file+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_ar_at_file=no
+   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  echo conftest.$ac_objext > conftest.lst
+      lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&5'
+      { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5
+  (eval $lt_ar_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      if test 0 -eq "$ac_status"; then
+	# Ensure the archiver fails upon bogus file names.
+	rm -f conftest.$ac_objext libconftest.a
+	{ { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5
+  (eval $lt_ar_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+	if test 0 -ne "$ac_status"; then
+          lt_cv_ar_at_file=@
+        fi
+      fi
+      rm -f conftest.* libconftest.a
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ar_at_file" >&5
+$as_echo "$lt_cv_ar_at_file" >&6; }
+
+if test no = "$lt_cv_ar_at_file"; then
+  archiver_list_spec=
+else
+  archiver_list_spec=$lt_cv_ar_at_file
+fi
+
+
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args.
+set dummy ${ac_tool_prefix}strip; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_STRIP+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$STRIP"; then
+  ac_cv_prog_STRIP="$STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_STRIP="${ac_tool_prefix}strip"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+STRIP=$ac_cv_prog_STRIP
+if test -n "$STRIP"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5
+$as_echo "$STRIP" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_STRIP"; then
+  ac_ct_STRIP=$STRIP
+  # Extract the first word of "strip", so it can be a program name with args.
+set dummy strip; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_STRIP+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_STRIP"; then
+  ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_STRIP="strip"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP
+if test -n "$ac_ct_STRIP"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5
+$as_echo "$ac_ct_STRIP" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_STRIP" = x; then
+    STRIP=":"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    STRIP=$ac_ct_STRIP
+  fi
+else
+  STRIP="$ac_cv_prog_STRIP"
+fi
+
+test -z "$STRIP" && STRIP=:
+
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
+set dummy ${ac_tool_prefix}ranlib; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_RANLIB+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$RANLIB"; then
+  ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+RANLIB=$ac_cv_prog_RANLIB
+if test -n "$RANLIB"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5
+$as_echo "$RANLIB" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_RANLIB"; then
+  ac_ct_RANLIB=$RANLIB
+  # Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_RANLIB+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_RANLIB"; then
+  ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_RANLIB="ranlib"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB
+if test -n "$ac_ct_RANLIB"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5
+$as_echo "$ac_ct_RANLIB" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_RANLIB" = x; then
+    RANLIB=":"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    RANLIB=$ac_ct_RANLIB
+  fi
+else
+  RANLIB="$ac_cv_prog_RANLIB"
+fi
+
+test -z "$RANLIB" && RANLIB=:
+
+
+
+
+
+
+# Determine commands to create old-style static archives.
+old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs'
+old_postinstall_cmds='chmod 644 $oldlib'
+old_postuninstall_cmds=
+
+if test -n "$RANLIB"; then
+  case $host_os in
+  bitrig* | openbsd*)
+    old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib"
+    ;;
+  *)
+    old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib"
+    ;;
+  esac
+  old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib"
+fi
+
+case $host_os in
+  darwin*)
+    lock_old_archive_extraction=yes ;;
+  *)
+    lock_old_archive_extraction=no ;;
+esac
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# If no C compiler was specified, use CC.
+LTCC=${LTCC-"$CC"}
+
+# If no C compiler flags were specified, use CFLAGS.
+LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
+
+# Allow CC to be a program name with arguments.
+compiler=$CC
+
+
+# Check for command to grab the raw symbol name followed by C symbol from nm.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking command to parse $NM output from $compiler object" >&5
+$as_echo_n "checking command to parse $NM output from $compiler object... " >&6; }
+if ${lt_cv_sys_global_symbol_pipe+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+# These are sane defaults that work on at least a few old systems.
+# [They come from Ultrix.  What could be older than Ultrix?!! ;)]
+
+# Character class describing NM global symbol codes.
+symcode='[BCDEGRST]'
+
+# Regexp to match symbols that can be accessed directly from C.
+sympat='\([_A-Za-z][_A-Za-z0-9]*\)'
+
+# Define system-specific variables.
+case $host_os in
+aix*)
+  symcode='[BCDT]'
+  ;;
+cygwin* | mingw* | pw32* | cegcc*)
+  symcode='[ABCDGISTW]'
+  ;;
+hpux*)
+  if test ia64 = "$host_cpu"; then
+    symcode='[ABCDEGRST]'
+  fi
+  ;;
+irix* | nonstopux*)
+  symcode='[BCDEGRST]'
+  ;;
+osf*)
+  symcode='[BCDEGQRST]'
+  ;;
+solaris*)
+  symcode='[BDRT]'
+  ;;
+sco3.2v5*)
+  symcode='[DT]'
+  ;;
+sysv4.2uw2*)
+  symcode='[DT]'
+  ;;
+sysv5* | sco5v6* | unixware* | OpenUNIX*)
+  symcode='[ABDT]'
+  ;;
+sysv4)
+  symcode='[DFNSTU]'
+  ;;
+esac
+
+# If we're using GNU nm, then use its standard symbol codes.
+case `$NM -V 2>&1` in
+*GNU* | *'with BFD'*)
+  symcode='[ABCDGIRSTW]' ;;
+esac
+
+if test "$lt_cv_nm_interface" = "MS dumpbin"; then
+  # Gets list of data symbols to import.
+  lt_cv_sys_global_symbol_to_import="sed -n -e 's/^I .* \(.*\)$/\1/p'"
+  # Adjust the below global symbol transforms to fixup imported variables.
+  lt_cdecl_hook=" -e 's/^I .* \(.*\)$/extern __declspec(dllimport) char \1;/p'"
+  lt_c_name_hook=" -e 's/^I .* \(.*\)$/  {\"\1\", (void *) 0},/p'"
+  lt_c_name_lib_hook="\
+  -e 's/^I .* \(lib.*\)$/  {\"\1\", (void *) 0},/p'\
+  -e 's/^I .* \(.*\)$/  {\"lib\1\", (void *) 0},/p'"
+else
+  # Disable hooks by default.
+  lt_cv_sys_global_symbol_to_import=
+  lt_cdecl_hook=
+  lt_c_name_hook=
+  lt_c_name_lib_hook=
+fi
+
+# Transform an extracted symbol line into a proper C declaration.
+# Some systems (esp. on ia64) link data and code symbols differently,
+# so use this general approach.
+lt_cv_sys_global_symbol_to_cdecl="sed -n"\
+$lt_cdecl_hook\
+" -e 's/^T .* \(.*\)$/extern int \1();/p'"\
+" -e 's/^$symcode$symcode* .* \(.*\)$/extern char \1;/p'"
+
+# Transform an extracted symbol line into symbol name and symbol address
+lt_cv_sys_global_symbol_to_c_name_address="sed -n"\
+$lt_c_name_hook\
+" -e 's/^: \(.*\) .*$/  {\"\1\", (void *) 0},/p'"\
+" -e 's/^$symcode$symcode* .* \(.*\)$/  {\"\1\", (void *) \&\1},/p'"
+
+# Transform an extracted symbol line into symbol name with lib prefix and
+# symbol address.
+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n"\
+$lt_c_name_lib_hook\
+" -e 's/^: \(.*\) .*$/  {\"\1\", (void *) 0},/p'"\
+" -e 's/^$symcode$symcode* .* \(lib.*\)$/  {\"\1\", (void *) \&\1},/p'"\
+" -e 's/^$symcode$symcode* .* \(.*\)$/  {\"lib\1\", (void *) \&\1},/p'"
+
+# Handle CRLF in mingw tool chain
+opt_cr=
+case $build_os in
+mingw*)
+  opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp
+  ;;
+esac
+
+# Try without a prefix underscore, then with it.
+for ac_symprfx in "" "_"; do
+
+  # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol.
+  symxfrm="\\1 $ac_symprfx\\2 \\2"
+
+  # Write the raw and C identifiers.
+  if test "$lt_cv_nm_interface" = "MS dumpbin"; then
+    # Fake it for dumpbin and say T for any non-static function,
+    # D for any global variable and I for any imported variable.
+    # Also find C++ and __fastcall symbols from MSVC++,
+    # which start with @ or ?.
+    lt_cv_sys_global_symbol_pipe="$AWK '"\
+"     {last_section=section; section=\$ 3};"\
+"     /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\
+"     /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\
+"     /^ *Symbol name *: /{split(\$ 0,sn,\":\"); si=substr(sn[2],2)};"\
+"     /^ *Type *: code/{print \"T\",si,substr(si,length(prfx))};"\
+"     /^ *Type *: data/{print \"I\",si,substr(si,length(prfx))};"\
+"     \$ 0!~/External *\|/{next};"\
+"     / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\
+"     {if(hide[section]) next};"\
+"     {f=\"D\"}; \$ 0~/\(\).*\|/{f=\"T\"};"\
+"     {split(\$ 0,a,/\||\r/); split(a[2],s)};"\
+"     s[1]~/^[@?]/{print f,s[1],s[1]; next};"\
+"     s[1]~prfx {split(s[1],t,\"@\"); print f,t[1],substr(t[1],length(prfx))}"\
+"     ' prfx=^$ac_symprfx"
+  else
+    lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[	 ]\($symcode$symcode*\)[	 ][	 ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'"
+  fi
+  lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'"
+
+  # Check to see that the pipe works correctly.
+  pipe_works=no
+
+  rm -f conftest*
+  cat > conftest.$ac_ext <<_LT_EOF
+#ifdef __cplusplus
+extern "C" {
+#endif
+char nm_test_var;
+void nm_test_func(void);
+void nm_test_func(void){}
+#ifdef __cplusplus
+}
+#endif
+int main(){nm_test_var='a';nm_test_func();return(0);}
+_LT_EOF
+
+  if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+    # Now try to grab the symbols.
+    nlist=conftest.nm
+    if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist\""; } >&5
+  (eval $NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && test -s "$nlist"; then
+      # Try sorting and uniquifying the output.
+      if sort "$nlist" | uniq > "$nlist"T; then
+	mv -f "$nlist"T "$nlist"
+      else
+	rm -f "$nlist"T
+      fi
+
+      # Make sure that we snagged all the symbols we need.
+      if $GREP ' nm_test_var$' "$nlist" >/dev/null; then
+	if $GREP ' nm_test_func$' "$nlist" >/dev/null; then
+	  cat <<_LT_EOF > conftest.$ac_ext
+/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests.  */
+#if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE
+/* DATA imports from DLLs on WIN32 can't be const, because runtime
+   relocations are performed -- see ld's documentation on pseudo-relocs.  */
+# define LT_DLSYM_CONST
+#elif defined __osf__
+/* This system does not cope well with relocations in const data.  */
+# define LT_DLSYM_CONST
+#else
+# define LT_DLSYM_CONST const
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+_LT_EOF
+	  # Now generate the symbol file.
+	  eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext'
+
+	  cat <<_LT_EOF >> conftest.$ac_ext
+
+/* The mapping between symbol names and symbols.  */
+LT_DLSYM_CONST struct {
+  const char *name;
+  void       *address;
+}
+lt__PROGRAM__LTX_preloaded_symbols[] =
+{
+  { "@PROGRAM@", (void *) 0 },
+_LT_EOF
+	  $SED "s/^$symcode$symcode* .* \(.*\)$/  {\"\1\", (void *) \&\1},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext
+	  cat <<\_LT_EOF >> conftest.$ac_ext
+  {0, (void *) 0}
+};
+
+/* This works around a problem in FreeBSD linker */
+#ifdef FREEBSD_WORKAROUND
+static const void *lt_preloaded_setup() {
+  return lt__PROGRAM__LTX_preloaded_symbols;
+}
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+_LT_EOF
+	  # Now try linking the two files.
+	  mv conftest.$ac_objext conftstm.$ac_objext
+	  lt_globsym_save_LIBS=$LIBS
+	  lt_globsym_save_CFLAGS=$CFLAGS
+	  LIBS=conftstm.$ac_objext
+	  CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag"
+	  if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && test -s conftest$ac_exeext; then
+	    pipe_works=yes
+	  fi
+	  LIBS=$lt_globsym_save_LIBS
+	  CFLAGS=$lt_globsym_save_CFLAGS
+	else
+	  echo "cannot find nm_test_func in $nlist" >&5
+	fi
+      else
+	echo "cannot find nm_test_var in $nlist" >&5
+      fi
+    else
+      echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5
+    fi
+  else
+    echo "$progname: failed program was:" >&5
+    cat conftest.$ac_ext >&5
+  fi
+  rm -rf conftest* conftst*
+
+  # Do not use the global_symbol_pipe unless it works.
+  if test yes = "$pipe_works"; then
+    break
+  else
+    lt_cv_sys_global_symbol_pipe=
+  fi
+done
+
+fi
+
+if test -z "$lt_cv_sys_global_symbol_pipe"; then
+  lt_cv_sys_global_symbol_to_cdecl=
+fi
+if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: failed" >&5
+$as_echo "failed" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5
+$as_echo "ok" >&6; }
+fi
+
+# Response file support.
+if test "$lt_cv_nm_interface" = "MS dumpbin"; then
+  nm_file_list_spec='@'
+elif $NM --help 2>/dev/null | grep '[@]FILE' >/dev/null; then
+  nm_file_list_spec='@'
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sysroot" >&5
+$as_echo_n "checking for sysroot... " >&6; }
+
+# Check whether --with-sysroot was given.
+if test "${with_sysroot+set}" = set; then :
+  withval=$with_sysroot;
+else
+  with_sysroot=no
+fi
+
+
+lt_sysroot=
+case $with_sysroot in #(
+ yes)
+   if test yes = "$GCC"; then
+     lt_sysroot=`$CC --print-sysroot 2>/dev/null`
+   fi
+   ;; #(
+ /*)
+   lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"`
+   ;; #(
+ no|'')
+   ;; #(
+ *)
+   { $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_sysroot" >&5
+$as_echo "$with_sysroot" >&6; }
+   as_fn_error $? "The sysroot must be an absolute path." "$LINENO" 5
+   ;;
+esac
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${lt_sysroot:-no}" >&5
+$as_echo "${lt_sysroot:-no}" >&6; }
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a working dd" >&5
+$as_echo_n "checking for a working dd... " >&6; }
+if ${ac_cv_path_lt_DD+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  printf 0123456789abcdef0123456789abcdef >conftest.i
+cat conftest.i conftest.i >conftest2.i
+: ${lt_DD:=$DD}
+if test -z "$lt_DD"; then
+  ac_path_lt_DD_found=false
+  # Loop through the user's path and test for each of PROGNAME-LIST
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_prog in dd; do
+    for ac_exec_ext in '' $ac_executable_extensions; do
+      ac_path_lt_DD="$as_dir/$ac_prog$ac_exec_ext"
+      as_fn_executable_p "$ac_path_lt_DD" || continue
+if "$ac_path_lt_DD" bs=32 count=1 <conftest2.i >conftest.out 2>/dev/null; then
+  cmp -s conftest.i conftest.out \
+  && ac_cv_path_lt_DD="$ac_path_lt_DD" ac_path_lt_DD_found=:
+fi
+      $ac_path_lt_DD_found && break 3
+    done
+  done
+  done
+IFS=$as_save_IFS
+  if test -z "$ac_cv_path_lt_DD"; then
+    :
+  fi
+else
+  ac_cv_path_lt_DD=$lt_DD
+fi
+
+rm -f conftest.i conftest2.i conftest.out
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_lt_DD" >&5
+$as_echo "$ac_cv_path_lt_DD" >&6; }
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to truncate binary pipes" >&5
+$as_echo_n "checking how to truncate binary pipes... " >&6; }
+if ${lt_cv_truncate_bin+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  printf 0123456789abcdef0123456789abcdef >conftest.i
+cat conftest.i conftest.i >conftest2.i
+lt_cv_truncate_bin=
+if "$ac_cv_path_lt_DD" bs=32 count=1 <conftest2.i >conftest.out 2>/dev/null; then
+  cmp -s conftest.i conftest.out \
+  && lt_cv_truncate_bin="$ac_cv_path_lt_DD bs=4096 count=1"
+fi
+rm -f conftest.i conftest2.i conftest.out
+test -z "$lt_cv_truncate_bin" && lt_cv_truncate_bin="$SED -e 4q"
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_truncate_bin" >&5
+$as_echo "$lt_cv_truncate_bin" >&6; }
+
+
+
+
+
+
+
+# Calculate cc_basename.  Skip known compiler wrappers and cross-prefix.
+func_cc_basename ()
+{
+    for cc_temp in $*""; do
+      case $cc_temp in
+        compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
+        distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
+        \-*) ;;
+        *) break;;
+      esac
+    done
+    func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"`
+}
+
+# Check whether --enable-libtool-lock was given.
+if test "${enable_libtool_lock+set}" = set; then :
+  enableval=$enable_libtool_lock;
+fi
+
+test no = "$enable_libtool_lock" || enable_libtool_lock=yes
+
+# Some flags need to be propagated to the compiler or linker for good
+# libtool support.
+case $host in
+ia64-*-hpux*)
+  # Find out what ABI is being produced by ac_compile, and set mode
+  # options accordingly.
+  echo 'int i;' > conftest.$ac_ext
+  if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+    case `/usr/bin/file conftest.$ac_objext` in
+      *ELF-32*)
+	HPUX_IA64_MODE=32
+	;;
+      *ELF-64*)
+	HPUX_IA64_MODE=64
+	;;
+    esac
+  fi
+  rm -rf conftest*
+  ;;
+*-*-irix6*)
+  # Find out what ABI is being produced by ac_compile, and set linker
+  # options accordingly.
+  echo '#line '$LINENO' "configure"' > conftest.$ac_ext
+  if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+    if test yes = "$lt_cv_prog_gnu_ld"; then
+      case `/usr/bin/file conftest.$ac_objext` in
+	*32-bit*)
+	  LD="${LD-ld} -melf32bsmip"
+	  ;;
+	*N32*)
+	  LD="${LD-ld} -melf32bmipn32"
+	  ;;
+	*64-bit*)
+	  LD="${LD-ld} -melf64bmip"
+	;;
+      esac
+    else
+      case `/usr/bin/file conftest.$ac_objext` in
+	*32-bit*)
+	  LD="${LD-ld} -32"
+	  ;;
+	*N32*)
+	  LD="${LD-ld} -n32"
+	  ;;
+	*64-bit*)
+	  LD="${LD-ld} -64"
+	  ;;
+      esac
+    fi
+  fi
+  rm -rf conftest*
+  ;;
+
+mips64*-*linux*)
+  # Find out what ABI is being produced by ac_compile, and set linker
+  # options accordingly.
+  echo '#line '$LINENO' "configure"' > conftest.$ac_ext
+  if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+    emul=elf
+    case `/usr/bin/file conftest.$ac_objext` in
+      *32-bit*)
+	emul="${emul}32"
+	;;
+      *64-bit*)
+	emul="${emul}64"
+	;;
+    esac
+    case `/usr/bin/file conftest.$ac_objext` in
+      *MSB*)
+	emul="${emul}btsmip"
+	;;
+      *LSB*)
+	emul="${emul}ltsmip"
+	;;
+    esac
+    case `/usr/bin/file conftest.$ac_objext` in
+      *N32*)
+	emul="${emul}n32"
+	;;
+    esac
+    LD="${LD-ld} -m $emul"
+  fi
+  rm -rf conftest*
+  ;;
+
+x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \
+s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
+  # Find out what ABI is being produced by ac_compile, and set linker
+  # options accordingly.  Note that the listed cases only cover the
+  # situations where additional linker options are needed (such as when
+  # doing 32-bit compilation for a host where ld defaults to 64-bit, or
+  # vice versa); the common cases where no linker options are needed do
+  # not appear in the list.
+  echo 'int i;' > conftest.$ac_ext
+  if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+    case `/usr/bin/file conftest.o` in
+      *32-bit*)
+	case $host in
+	  x86_64-*kfreebsd*-gnu)
+	    LD="${LD-ld} -m elf_i386_fbsd"
+	    ;;
+	  x86_64-*linux*)
+	    case `/usr/bin/file conftest.o` in
+	      *x86-64*)
+		LD="${LD-ld} -m elf32_x86_64"
+		;;
+	      *)
+		LD="${LD-ld} -m elf_i386"
+		;;
+	    esac
+	    ;;
+	  powerpc64le-*linux*)
+	    LD="${LD-ld} -m elf32lppclinux"
+	    ;;
+	  powerpc64-*linux*)
+	    LD="${LD-ld} -m elf32ppclinux"
+	    ;;
+	  s390x-*linux*)
+	    LD="${LD-ld} -m elf_s390"
+	    ;;
+	  sparc64-*linux*)
+	    LD="${LD-ld} -m elf32_sparc"
+	    ;;
+	esac
+	;;
+      *64-bit*)
+	case $host in
+	  x86_64-*kfreebsd*-gnu)
+	    LD="${LD-ld} -m elf_x86_64_fbsd"
+	    ;;
+	  x86_64-*linux*)
+	    LD="${LD-ld} -m elf_x86_64"
+	    ;;
+	  powerpcle-*linux*)
+	    LD="${LD-ld} -m elf64lppc"
+	    ;;
+	  powerpc-*linux*)
+	    LD="${LD-ld} -m elf64ppc"
+	    ;;
+	  s390*-*linux*|s390*-*tpf*)
+	    LD="${LD-ld} -m elf64_s390"
+	    ;;
+	  sparc*-*linux*)
+	    LD="${LD-ld} -m elf64_sparc"
+	    ;;
+	esac
+	;;
+    esac
+  fi
+  rm -rf conftest*
+  ;;
+
+*-*-sco3.2v5*)
+  # On SCO OpenServer 5, we need -belf to get full-featured binaries.
+  SAVE_CFLAGS=$CFLAGS
+  CFLAGS="$CFLAGS -belf"
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler needs -belf" >&5
+$as_echo_n "checking whether the C compiler needs -belf... " >&6; }
+if ${lt_cv_cc_needs_belf+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+     cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  lt_cv_cc_needs_belf=yes
+else
+  lt_cv_cc_needs_belf=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+     ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_cc_needs_belf" >&5
+$as_echo "$lt_cv_cc_needs_belf" >&6; }
+  if test yes != "$lt_cv_cc_needs_belf"; then
+    # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf
+    CFLAGS=$SAVE_CFLAGS
+  fi
+  ;;
+*-*solaris*)
+  # Find out what ABI is being produced by ac_compile, and set linker
+  # options accordingly.
+  echo 'int i;' > conftest.$ac_ext
+  if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+    case `/usr/bin/file conftest.o` in
+    *64-bit*)
+      case $lt_cv_prog_gnu_ld in
+      yes*)
+        case $host in
+        i?86-*-solaris*|x86_64-*-solaris*)
+          LD="${LD-ld} -m elf_x86_64"
+          ;;
+        sparc*-*-solaris*)
+          LD="${LD-ld} -m elf64_sparc"
+          ;;
+        esac
+        # GNU ld 2.21 introduced _sol2 emulations.  Use them if available.
+        if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then
+          LD=${LD-ld}_sol2
+        fi
+        ;;
+      *)
+	if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then
+	  LD="${LD-ld} -64"
+	fi
+	;;
+      esac
+      ;;
+    esac
+  fi
+  rm -rf conftest*
+  ;;
+esac
+
+need_locks=$enable_libtool_lock
+
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}mt", so it can be a program name with args.
+set dummy ${ac_tool_prefix}mt; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_MANIFEST_TOOL+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$MANIFEST_TOOL"; then
+  ac_cv_prog_MANIFEST_TOOL="$MANIFEST_TOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_MANIFEST_TOOL="${ac_tool_prefix}mt"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+MANIFEST_TOOL=$ac_cv_prog_MANIFEST_TOOL
+if test -n "$MANIFEST_TOOL"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MANIFEST_TOOL" >&5
+$as_echo "$MANIFEST_TOOL" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_MANIFEST_TOOL"; then
+  ac_ct_MANIFEST_TOOL=$MANIFEST_TOOL
+  # Extract the first word of "mt", so it can be a program name with args.
+set dummy mt; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_MANIFEST_TOOL+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_MANIFEST_TOOL"; then
+  ac_cv_prog_ac_ct_MANIFEST_TOOL="$ac_ct_MANIFEST_TOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_MANIFEST_TOOL="mt"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_MANIFEST_TOOL=$ac_cv_prog_ac_ct_MANIFEST_TOOL
+if test -n "$ac_ct_MANIFEST_TOOL"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_MANIFEST_TOOL" >&5
+$as_echo "$ac_ct_MANIFEST_TOOL" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_MANIFEST_TOOL" = x; then
+    MANIFEST_TOOL=":"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    MANIFEST_TOOL=$ac_ct_MANIFEST_TOOL
+  fi
+else
+  MANIFEST_TOOL="$ac_cv_prog_MANIFEST_TOOL"
+fi
+
+test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $MANIFEST_TOOL is a manifest tool" >&5
+$as_echo_n "checking if $MANIFEST_TOOL is a manifest tool... " >&6; }
+if ${lt_cv_path_mainfest_tool+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_path_mainfest_tool=no
+  echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&5
+  $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out
+  cat conftest.err >&5
+  if $GREP 'Manifest Tool' conftest.out > /dev/null; then
+    lt_cv_path_mainfest_tool=yes
+  fi
+  rm -f conftest*
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_mainfest_tool" >&5
+$as_echo "$lt_cv_path_mainfest_tool" >&6; }
+if test yes != "$lt_cv_path_mainfest_tool"; then
+  MANIFEST_TOOL=:
+fi
+
+
+
+
+
+
+  case $host_os in
+    rhapsody* | darwin*)
+    if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}dsymutil", so it can be a program name with args.
+set dummy ${ac_tool_prefix}dsymutil; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_DSYMUTIL+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$DSYMUTIL"; then
+  ac_cv_prog_DSYMUTIL="$DSYMUTIL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_DSYMUTIL="${ac_tool_prefix}dsymutil"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+DSYMUTIL=$ac_cv_prog_DSYMUTIL
+if test -n "$DSYMUTIL"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DSYMUTIL" >&5
+$as_echo "$DSYMUTIL" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_DSYMUTIL"; then
+  ac_ct_DSYMUTIL=$DSYMUTIL
+  # Extract the first word of "dsymutil", so it can be a program name with args.
+set dummy dsymutil; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_DSYMUTIL+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_DSYMUTIL"; then
+  ac_cv_prog_ac_ct_DSYMUTIL="$ac_ct_DSYMUTIL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_DSYMUTIL="dsymutil"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_DSYMUTIL=$ac_cv_prog_ac_ct_DSYMUTIL
+if test -n "$ac_ct_DSYMUTIL"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DSYMUTIL" >&5
+$as_echo "$ac_ct_DSYMUTIL" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_DSYMUTIL" = x; then
+    DSYMUTIL=":"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    DSYMUTIL=$ac_ct_DSYMUTIL
+  fi
+else
+  DSYMUTIL="$ac_cv_prog_DSYMUTIL"
+fi
+
+    if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}nmedit", so it can be a program name with args.
+set dummy ${ac_tool_prefix}nmedit; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_NMEDIT+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$NMEDIT"; then
+  ac_cv_prog_NMEDIT="$NMEDIT" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_NMEDIT="${ac_tool_prefix}nmedit"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+NMEDIT=$ac_cv_prog_NMEDIT
+if test -n "$NMEDIT"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NMEDIT" >&5
+$as_echo "$NMEDIT" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_NMEDIT"; then
+  ac_ct_NMEDIT=$NMEDIT
+  # Extract the first word of "nmedit", so it can be a program name with args.
+set dummy nmedit; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_NMEDIT+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_NMEDIT"; then
+  ac_cv_prog_ac_ct_NMEDIT="$ac_ct_NMEDIT" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_NMEDIT="nmedit"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_NMEDIT=$ac_cv_prog_ac_ct_NMEDIT
+if test -n "$ac_ct_NMEDIT"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_NMEDIT" >&5
+$as_echo "$ac_ct_NMEDIT" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_NMEDIT" = x; then
+    NMEDIT=":"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    NMEDIT=$ac_ct_NMEDIT
+  fi
+else
+  NMEDIT="$ac_cv_prog_NMEDIT"
+fi
+
+    if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}lipo", so it can be a program name with args.
+set dummy ${ac_tool_prefix}lipo; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_LIPO+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$LIPO"; then
+  ac_cv_prog_LIPO="$LIPO" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_LIPO="${ac_tool_prefix}lipo"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+LIPO=$ac_cv_prog_LIPO
+if test -n "$LIPO"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIPO" >&5
+$as_echo "$LIPO" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_LIPO"; then
+  ac_ct_LIPO=$LIPO
+  # Extract the first word of "lipo", so it can be a program name with args.
+set dummy lipo; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_LIPO+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_LIPO"; then
+  ac_cv_prog_ac_ct_LIPO="$ac_ct_LIPO" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_LIPO="lipo"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_LIPO=$ac_cv_prog_ac_ct_LIPO
+if test -n "$ac_ct_LIPO"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_LIPO" >&5
+$as_echo "$ac_ct_LIPO" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_LIPO" = x; then
+    LIPO=":"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    LIPO=$ac_ct_LIPO
+  fi
+else
+  LIPO="$ac_cv_prog_LIPO"
+fi
+
+    if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}otool", so it can be a program name with args.
+set dummy ${ac_tool_prefix}otool; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_OTOOL+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$OTOOL"; then
+  ac_cv_prog_OTOOL="$OTOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_OTOOL="${ac_tool_prefix}otool"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+OTOOL=$ac_cv_prog_OTOOL
+if test -n "$OTOOL"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL" >&5
+$as_echo "$OTOOL" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_OTOOL"; then
+  ac_ct_OTOOL=$OTOOL
+  # Extract the first word of "otool", so it can be a program name with args.
+set dummy otool; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_OTOOL+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_OTOOL"; then
+  ac_cv_prog_ac_ct_OTOOL="$ac_ct_OTOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_OTOOL="otool"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_OTOOL=$ac_cv_prog_ac_ct_OTOOL
+if test -n "$ac_ct_OTOOL"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL" >&5
+$as_echo "$ac_ct_OTOOL" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_OTOOL" = x; then
+    OTOOL=":"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    OTOOL=$ac_ct_OTOOL
+  fi
+else
+  OTOOL="$ac_cv_prog_OTOOL"
+fi
+
+    if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}otool64", so it can be a program name with args.
+set dummy ${ac_tool_prefix}otool64; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_OTOOL64+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$OTOOL64"; then
+  ac_cv_prog_OTOOL64="$OTOOL64" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_OTOOL64="${ac_tool_prefix}otool64"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+OTOOL64=$ac_cv_prog_OTOOL64
+if test -n "$OTOOL64"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL64" >&5
+$as_echo "$OTOOL64" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_OTOOL64"; then
+  ac_ct_OTOOL64=$OTOOL64
+  # Extract the first word of "otool64", so it can be a program name with args.
+set dummy otool64; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_OTOOL64+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_OTOOL64"; then
+  ac_cv_prog_ac_ct_OTOOL64="$ac_ct_OTOOL64" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_OTOOL64="otool64"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_OTOOL64=$ac_cv_prog_ac_ct_OTOOL64
+if test -n "$ac_ct_OTOOL64"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL64" >&5
+$as_echo "$ac_ct_OTOOL64" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_OTOOL64" = x; then
+    OTOOL64=":"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    OTOOL64=$ac_ct_OTOOL64
+  fi
+else
+  OTOOL64="$ac_cv_prog_OTOOL64"
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -single_module linker flag" >&5
+$as_echo_n "checking for -single_module linker flag... " >&6; }
+if ${lt_cv_apple_cc_single_mod+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_apple_cc_single_mod=no
+      if test -z "$LT_MULTI_MODULE"; then
+	# By default we will add the -single_module flag. You can override
+	# by either setting the environment variable LT_MULTI_MODULE
+	# non-empty at configure time, or by adding -multi_module to the
+	# link flags.
+	rm -rf libconftest.dylib*
+	echo "int foo(void){return 1;}" > conftest.c
+	echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \
+-dynamiclib -Wl,-single_module conftest.c" >&5
+	$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \
+	  -dynamiclib -Wl,-single_module conftest.c 2>conftest.err
+        _lt_result=$?
+	# If there is a non-empty error log, and "single_module"
+	# appears in it, assume the flag caused a linker warning
+        if test -s conftest.err && $GREP single_module conftest.err; then
+	  cat conftest.err >&5
+	# Otherwise, if the output was created with a 0 exit code from
+	# the compiler, it worked.
+	elif test -f libconftest.dylib && test 0 = "$_lt_result"; then
+	  lt_cv_apple_cc_single_mod=yes
+	else
+	  cat conftest.err >&5
+	fi
+	rm -rf libconftest.dylib*
+	rm -f conftest.*
+      fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_apple_cc_single_mod" >&5
+$as_echo "$lt_cv_apple_cc_single_mod" >&6; }
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -exported_symbols_list linker flag" >&5
+$as_echo_n "checking for -exported_symbols_list linker flag... " >&6; }
+if ${lt_cv_ld_exported_symbols_list+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_ld_exported_symbols_list=no
+      save_LDFLAGS=$LDFLAGS
+      echo "_main" > conftest.sym
+      LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym"
+      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  lt_cv_ld_exported_symbols_list=yes
+else
+  lt_cv_ld_exported_symbols_list=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+	LDFLAGS=$save_LDFLAGS
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list" >&5
+$as_echo "$lt_cv_ld_exported_symbols_list" >&6; }
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -force_load linker flag" >&5
+$as_echo_n "checking for -force_load linker flag... " >&6; }
+if ${lt_cv_ld_force_load+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_ld_force_load=no
+      cat > conftest.c << _LT_EOF
+int forced_loaded() { return 2;}
+_LT_EOF
+      echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&5
+      $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&5
+      echo "$AR cru libconftest.a conftest.o" >&5
+      $AR cru libconftest.a conftest.o 2>&5
+      echo "$RANLIB libconftest.a" >&5
+      $RANLIB libconftest.a 2>&5
+      cat > conftest.c << _LT_EOF
+int main() { return 0;}
+_LT_EOF
+      echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&5
+      $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err
+      _lt_result=$?
+      if test -s conftest.err && $GREP force_load conftest.err; then
+	cat conftest.err >&5
+      elif test -f conftest && test 0 = "$_lt_result" && $GREP forced_load conftest >/dev/null 2>&1; then
+	lt_cv_ld_force_load=yes
+      else
+	cat conftest.err >&5
+      fi
+        rm -f conftest.err libconftest.a conftest conftest.c
+        rm -rf conftest.dSYM
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_force_load" >&5
+$as_echo "$lt_cv_ld_force_load" >&6; }
+    case $host_os in
+    rhapsody* | darwin1.[012])
+      _lt_dar_allow_undefined='$wl-undefined ${wl}suppress' ;;
+    darwin1.*)
+      _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;;
+    darwin*) # darwin 5.x on
+      # if running on 10.5 or later, the deployment target defaults
+      # to the OS version, if on x86, and 10.4, the deployment
+      # target defaults to 10.4. Don't you love it?
+      case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in
+	10.0,*86*-darwin8*|10.0,*-darwin[91]*)
+	  _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;;
+	10.[012][,.]*)
+	  _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;;
+	10.*)
+	  _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;;
+      esac
+    ;;
+  esac
+    if test yes = "$lt_cv_apple_cc_single_mod"; then
+      _lt_dar_single_mod='$single_module'
+    fi
+    if test yes = "$lt_cv_ld_exported_symbols_list"; then
+      _lt_dar_export_syms=' $wl-exported_symbols_list,$output_objdir/$libname-symbols.expsym'
+    else
+      _lt_dar_export_syms='~$NMEDIT -s $output_objdir/$libname-symbols.expsym $lib'
+    fi
+    if test : != "$DSYMUTIL" && test no = "$lt_cv_ld_force_load"; then
+      _lt_dsymutil='~$DSYMUTIL $lib || :'
+    else
+      _lt_dsymutil=
+    fi
+    ;;
+  esac
+
+# func_munge_path_list VARIABLE PATH
+# -----------------------------------
+# VARIABLE is name of variable containing _space_ separated list of
+# directories to be munged by the contents of PATH, which is string
+# having a format:
+# "DIR[:DIR]:"
+#       string "DIR[ DIR]" will be prepended to VARIABLE
+# ":DIR[:DIR]"
+#       string "DIR[ DIR]" will be appended to VARIABLE
+# "DIRP[:DIRP]::[DIRA:]DIRA"
+#       string "DIRP[ DIRP]" will be prepended to VARIABLE and string
+#       "DIRA[ DIRA]" will be appended to VARIABLE
+# "DIR[:DIR]"
+#       VARIABLE will be replaced by "DIR[ DIR]"
+func_munge_path_list ()
+{
+    case x$2 in
+    x)
+        ;;
+    *:)
+        eval $1=\"`$ECHO $2 | $SED 's/:/ /g'` \$$1\"
+        ;;
+    x:*)
+        eval $1=\"\$$1 `$ECHO $2 | $SED 's/:/ /g'`\"
+        ;;
+    *::*)
+        eval $1=\"\$$1\ `$ECHO $2 | $SED -e 's/.*:://' -e 's/:/ /g'`\"
+        eval $1=\"`$ECHO $2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \$$1\"
+        ;;
+    *)
+        eval $1=\"`$ECHO $2 | $SED 's/:/ /g'`\"
+        ;;
+    esac
+}
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5
+$as_echo_n "checking how to run the C preprocessor... " >&6; }
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+  CPP=
+fi
+if test -z "$CPP"; then
+  if ${ac_cv_prog_CPP+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+      # Double quotes because CPP needs to be expanded
+    for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
+    do
+      ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+  # Use a header file that comes with gcc, so configuring glibc
+  # with a fresh cross-compiler works.
+  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+  # <limits.h> exists even on freestanding compilers.
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp. "Syntax error" is here to catch this case.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+		     Syntax error
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+
+else
+  # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+  # OK, works on sane cases.  Now check whether nonexistent headers
+  # can be detected and how.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+  # Broken: success on invalid input.
+continue
+else
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+  break
+fi
+
+    done
+    ac_cv_prog_CPP=$CPP
+
+fi
+  CPP=$ac_cv_prog_CPP
+else
+  ac_cv_prog_CPP=$CPP
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5
+$as_echo "$CPP" >&6; }
+ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+  # Use a header file that comes with gcc, so configuring glibc
+  # with a fresh cross-compiler works.
+  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+  # <limits.h> exists even on freestanding compilers.
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp. "Syntax error" is here to catch this case.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+		     Syntax error
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+
+else
+  # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+  # OK, works on sane cases.  Now check whether nonexistent headers
+  # can be detected and how.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+  # Broken: success on invalid input.
+continue
+else
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+
+else
+  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5
+$as_echo_n "checking for ANSI C header files... " >&6; }
+if ${ac_cv_header_stdc+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_header_stdc=yes
+else
+  ac_cv_header_stdc=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+if test $ac_cv_header_stdc = yes; then
+  # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "memchr" >/dev/null 2>&1; then :
+
+else
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "free" >/dev/null 2>&1; then :
+
+else
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+  if test "$cross_compiling" = yes; then :
+  :
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <ctype.h>
+#include <stdlib.h>
+#if ((' ' & 0x0FF) == 0x020)
+# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#else
+# define ISLOWER(c) \
+		   (('a' <= (c) && (c) <= 'i') \
+		     || ('j' <= (c) && (c) <= 'r') \
+		     || ('s' <= (c) && (c) <= 'z'))
+# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
+#endif
+
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int
+main ()
+{
+  int i;
+  for (i = 0; i < 256; i++)
+    if (XOR (islower (i), ISLOWER (i))
+	|| toupper (i) != TOUPPER (i))
+      return 2;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+
+else
+  ac_cv_header_stdc=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5
+$as_echo "$ac_cv_header_stdc" >&6; }
+if test $ac_cv_header_stdc = yes; then
+
+$as_echo "#define STDC_HEADERS 1" >>confdefs.h
+
+fi
+
+# On IRIX 5.3, sys/types and inttypes.h are conflicting.
+for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
+		  inttypes.h stdint.h unistd.h
+do :
+  as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default
+"
+if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+for ac_header in dlfcn.h
+do :
+  ac_fn_c_check_header_compile "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default
+"
+if test "x$ac_cv_header_dlfcn_h" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_DLFCN_H 1
+_ACEOF
+
+fi
+
+done
+
+
+
+
+
+# Set options
+
+
+
+        enable_dlopen=no
+
+
+  enable_win32_dll=no
+
+
+            # Check whether --enable-shared was given.
+if test "${enable_shared+set}" = set; then :
+  enableval=$enable_shared; p=${PACKAGE-default}
+    case $enableval in
+    yes) enable_shared=yes ;;
+    no) enable_shared=no ;;
+    *)
+      enable_shared=no
+      # Look at the argument we got.  We use all the common list separators.
+      lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
+      for pkg in $enableval; do
+	IFS=$lt_save_ifs
+	if test "X$pkg" = "X$p"; then
+	  enable_shared=yes
+	fi
+      done
+      IFS=$lt_save_ifs
+      ;;
+    esac
+else
+  enable_shared=yes
+fi
+
+
+
+
+
+
+
+
+
+  # Check whether --enable-static was given.
+if test "${enable_static+set}" = set; then :
+  enableval=$enable_static; p=${PACKAGE-default}
+    case $enableval in
+    yes) enable_static=yes ;;
+    no) enable_static=no ;;
+    *)
+     enable_static=no
+      # Look at the argument we got.  We use all the common list separators.
+      lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
+      for pkg in $enableval; do
+	IFS=$lt_save_ifs
+	if test "X$pkg" = "X$p"; then
+	  enable_static=yes
+	fi
+      done
+      IFS=$lt_save_ifs
+      ;;
+    esac
+else
+  enable_static=yes
+fi
+
+
+
+
+
+
+
+
+
+
+# Check whether --with-pic was given.
+if test "${with_pic+set}" = set; then :
+  withval=$with_pic; lt_p=${PACKAGE-default}
+    case $withval in
+    yes|no) pic_mode=$withval ;;
+    *)
+      pic_mode=default
+      # Look at the argument we got.  We use all the common list separators.
+      lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
+      for lt_pkg in $withval; do
+	IFS=$lt_save_ifs
+	if test "X$lt_pkg" = "X$lt_p"; then
+	  pic_mode=yes
+	fi
+      done
+      IFS=$lt_save_ifs
+      ;;
+    esac
+else
+  pic_mode=default
+fi
+
+
+
+
+
+
+
+
+  # Check whether --enable-fast-install was given.
+if test "${enable_fast_install+set}" = set; then :
+  enableval=$enable_fast_install; p=${PACKAGE-default}
+    case $enableval in
+    yes) enable_fast_install=yes ;;
+    no) enable_fast_install=no ;;
+    *)
+      enable_fast_install=no
+      # Look at the argument we got.  We use all the common list separators.
+      lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
+      for pkg in $enableval; do
+	IFS=$lt_save_ifs
+	if test "X$pkg" = "X$p"; then
+	  enable_fast_install=yes
+	fi
+      done
+      IFS=$lt_save_ifs
+      ;;
+    esac
+else
+  enable_fast_install=yes
+fi
+
+
+
+
+
+
+
+
+  shared_archive_member_spec=
+case $host,$enable_shared in
+power*-*-aix[5-9]*,yes)
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking which variant of shared library versioning to provide" >&5
+$as_echo_n "checking which variant of shared library versioning to provide... " >&6; }
+
+# Check whether --with-aix-soname was given.
+if test "${with_aix_soname+set}" = set; then :
+  withval=$with_aix_soname; case $withval in
+    aix|svr4|both)
+      ;;
+    *)
+      as_fn_error $? "Unknown argument to --with-aix-soname" "$LINENO" 5
+      ;;
+    esac
+    lt_cv_with_aix_soname=$with_aix_soname
+else
+  if ${lt_cv_with_aix_soname+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_with_aix_soname=aix
+fi
+
+    with_aix_soname=$lt_cv_with_aix_soname
+fi
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_aix_soname" >&5
+$as_echo "$with_aix_soname" >&6; }
+  if test aix != "$with_aix_soname"; then
+    # For the AIX way of multilib, we name the shared archive member
+    # based on the bitwidth used, traditionally 'shr.o' or 'shr_64.o',
+    # and 'shr.imp' or 'shr_64.imp', respectively, for the Import File.
+    # Even when GNU compilers ignore OBJECT_MODE but need '-maix64' flag,
+    # the AIX toolchain works better with OBJECT_MODE set (default 32).
+    if test 64 = "${OBJECT_MODE-32}"; then
+      shared_archive_member_spec=shr_64
+    else
+      shared_archive_member_spec=shr
+    fi
+  fi
+  ;;
+*)
+  with_aix_soname=aix
+  ;;
+esac
+
+
+
+
+
+
+
+
+
+
+# This can be used to rebuild libtool when needed
+LIBTOOL_DEPS=$ltmain
+
+# Always use our own libtool.
+LIBTOOL='$(SHELL) $(top_builddir)/libtool'
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+test -z "$LN_S" && LN_S="ln -s"
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+if test -n "${ZSH_VERSION+set}"; then
+   setopt NO_GLOB_SUBST
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for objdir" >&5
+$as_echo_n "checking for objdir... " >&6; }
+if ${lt_cv_objdir+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  rm -f .libs 2>/dev/null
+mkdir .libs 2>/dev/null
+if test -d .libs; then
+  lt_cv_objdir=.libs
+else
+  # MS-DOS does not allow filenames that begin with a dot.
+  lt_cv_objdir=_libs
+fi
+rmdir .libs 2>/dev/null
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_objdir" >&5
+$as_echo "$lt_cv_objdir" >&6; }
+objdir=$lt_cv_objdir
+
+
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define LT_OBJDIR "$lt_cv_objdir/"
+_ACEOF
+
+
+
+
+case $host_os in
+aix3*)
+  # AIX sometimes has problems with the GCC collect2 program.  For some
+  # reason, if we set the COLLECT_NAMES environment variable, the problems
+  # vanish in a puff of smoke.
+  if test set != "${COLLECT_NAMES+set}"; then
+    COLLECT_NAMES=
+    export COLLECT_NAMES
+  fi
+  ;;
+esac
+
+# Global variables:
+ofile=libtool
+can_build_shared=yes
+
+# All known linkers require a '.a' archive for static linking (except MSVC,
+# which needs '.lib').
+libext=a
+
+with_gnu_ld=$lt_cv_prog_gnu_ld
+
+old_CC=$CC
+old_CFLAGS=$CFLAGS
+
+# Set sane defaults for various variables
+test -z "$CC" && CC=cc
+test -z "$LTCC" && LTCC=$CC
+test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS
+test -z "$LD" && LD=ld
+test -z "$ac_objext" && ac_objext=o
+
+func_cc_basename $compiler
+cc_basename=$func_cc_basename_result
+
+
+# Only perform the check for file, if the check method requires it
+test -z "$MAGIC_CMD" && MAGIC_CMD=file
+case $deplibs_check_method in
+file_magic*)
+  if test "$file_magic_cmd" = '$MAGIC_CMD'; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${ac_tool_prefix}file" >&5
+$as_echo_n "checking for ${ac_tool_prefix}file... " >&6; }
+if ${lt_cv_path_MAGIC_CMD+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $MAGIC_CMD in
+[\\/*] |  ?:[\\/]*)
+  lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path.
+  ;;
+*)
+  lt_save_MAGIC_CMD=$MAGIC_CMD
+  lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR
+  ac_dummy="/usr/bin$PATH_SEPARATOR$PATH"
+  for ac_dir in $ac_dummy; do
+    IFS=$lt_save_ifs
+    test -z "$ac_dir" && ac_dir=.
+    if test -f "$ac_dir/${ac_tool_prefix}file"; then
+      lt_cv_path_MAGIC_CMD=$ac_dir/"${ac_tool_prefix}file"
+      if test -n "$file_magic_test_file"; then
+	case $deplibs_check_method in
+	"file_magic "*)
+	  file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"`
+	  MAGIC_CMD=$lt_cv_path_MAGIC_CMD
+	  if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
+	    $EGREP "$file_magic_regex" > /dev/null; then
+	    :
+	  else
+	    cat <<_LT_EOF 1>&2
+
+*** Warning: the command libtool uses to detect shared libraries,
+*** $file_magic_cmd, produces output that libtool cannot recognize.
+*** The result is that libtool may fail to recognize shared libraries
+*** as such.  This will affect the creation of libtool libraries that
+*** depend on shared libraries, but programs linked with such libtool
+*** libraries will work regardless of this problem.  Nevertheless, you
+*** may want to report the problem to your system manager and/or to
+*** bug-libtool@gnu.org
+
+_LT_EOF
+	  fi ;;
+	esac
+      fi
+      break
+    fi
+  done
+  IFS=$lt_save_ifs
+  MAGIC_CMD=$lt_save_MAGIC_CMD
+  ;;
+esac
+fi
+
+MAGIC_CMD=$lt_cv_path_MAGIC_CMD
+if test -n "$MAGIC_CMD"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5
+$as_echo "$MAGIC_CMD" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+
+
+
+if test -z "$lt_cv_path_MAGIC_CMD"; then
+  if test -n "$ac_tool_prefix"; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for file" >&5
+$as_echo_n "checking for file... " >&6; }
+if ${lt_cv_path_MAGIC_CMD+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $MAGIC_CMD in
+[\\/*] |  ?:[\\/]*)
+  lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path.
+  ;;
+*)
+  lt_save_MAGIC_CMD=$MAGIC_CMD
+  lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR
+  ac_dummy="/usr/bin$PATH_SEPARATOR$PATH"
+  for ac_dir in $ac_dummy; do
+    IFS=$lt_save_ifs
+    test -z "$ac_dir" && ac_dir=.
+    if test -f "$ac_dir/file"; then
+      lt_cv_path_MAGIC_CMD=$ac_dir/"file"
+      if test -n "$file_magic_test_file"; then
+	case $deplibs_check_method in
+	"file_magic "*)
+	  file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"`
+	  MAGIC_CMD=$lt_cv_path_MAGIC_CMD
+	  if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
+	    $EGREP "$file_magic_regex" > /dev/null; then
+	    :
+	  else
+	    cat <<_LT_EOF 1>&2
+
+*** Warning: the command libtool uses to detect shared libraries,
+*** $file_magic_cmd, produces output that libtool cannot recognize.
+*** The result is that libtool may fail to recognize shared libraries
+*** as such.  This will affect the creation of libtool libraries that
+*** depend on shared libraries, but programs linked with such libtool
+*** libraries will work regardless of this problem.  Nevertheless, you
+*** may want to report the problem to your system manager and/or to
+*** bug-libtool@gnu.org
+
+_LT_EOF
+	  fi ;;
+	esac
+      fi
+      break
+    fi
+  done
+  IFS=$lt_save_ifs
+  MAGIC_CMD=$lt_save_MAGIC_CMD
+  ;;
+esac
+fi
+
+MAGIC_CMD=$lt_cv_path_MAGIC_CMD
+if test -n "$MAGIC_CMD"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5
+$as_echo "$MAGIC_CMD" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  else
+    MAGIC_CMD=:
+  fi
+fi
+
+  fi
+  ;;
+esac
+
+# Use C for the default configuration in the libtool script
+
+lt_save_CC=$CC
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+# Source file extension for C test sources.
+ac_ext=c
+
+# Object file extension for compiled C test sources.
+objext=o
+objext=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="int some_variable = 0;"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code='int main(){return(0);}'
+
+
+
+
+
+
+
+# If no C compiler was specified, use CC.
+LTCC=${LTCC-"$CC"}
+
+# If no C compiler flags were specified, use CFLAGS.
+LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
+
+# Allow CC to be a program name with arguments.
+compiler=$CC
+
+# Save the default compiler, since it gets overwritten when the other
+# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP.
+compiler_DEFAULT=$CC
+
+# save warnings/boilerplate of simple test code
+ac_outfile=conftest.$ac_objext
+echo "$lt_simple_compile_test_code" >conftest.$ac_ext
+eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_compiler_boilerplate=`cat conftest.err`
+$RM conftest*
+
+ac_outfile=conftest.$ac_objext
+echo "$lt_simple_link_test_code" >conftest.$ac_ext
+eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_linker_boilerplate=`cat conftest.err`
+$RM -r conftest*
+
+
+## CAVEAT EMPTOR:
+## There is no encapsulation within the following macros, do not change
+## the running order or otherwise move them around unless you know exactly
+## what you are doing...
+if test -n "$compiler"; then
+
+lt_prog_compiler_no_builtin_flag=
+
+if test yes = "$GCC"; then
+  case $cc_basename in
+  nvcc*)
+    lt_prog_compiler_no_builtin_flag=' -Xcompiler -fno-builtin' ;;
+  *)
+    lt_prog_compiler_no_builtin_flag=' -fno-builtin' ;;
+  esac
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -fno-rtti -fno-exceptions" >&5
+$as_echo_n "checking if $compiler supports -fno-rtti -fno-exceptions... " >&6; }
+if ${lt_cv_prog_compiler_rtti_exceptions+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_prog_compiler_rtti_exceptions=no
+   ac_outfile=conftest.$ac_objext
+   echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+   lt_compiler_flag="-fno-rtti -fno-exceptions"  ## exclude from sc_useless_quotes_in_assignment
+   # Insert the option either (1) after the last *FLAGS variable, or
+   # (2) before a word containing "conftest.", or (3) at the end.
+   # Note that $ac_compile itself does not contain backslashes and begins
+   # with a dollar sign (not a hyphen), so the echo should work correctly.
+   # The option is referenced via a variable to avoid confusing sed.
+   lt_compile=`echo "$ac_compile" | $SED \
+   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+   -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+   -e 's:$: $lt_compiler_flag:'`
+   (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>conftest.err)
+   ac_status=$?
+   cat conftest.err >&5
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
+   if (exit $ac_status) && test -s "$ac_outfile"; then
+     # The compiler can only warn and ignore the option if not recognized
+     # So say no if there are warnings other than the usual output.
+     $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp
+     $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+     if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
+       lt_cv_prog_compiler_rtti_exceptions=yes
+     fi
+   fi
+   $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_rtti_exceptions" >&5
+$as_echo "$lt_cv_prog_compiler_rtti_exceptions" >&6; }
+
+if test yes = "$lt_cv_prog_compiler_rtti_exceptions"; then
+    lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions"
+else
+    :
+fi
+
+fi
+
+
+
+
+
+
+  lt_prog_compiler_wl=
+lt_prog_compiler_pic=
+lt_prog_compiler_static=
+
+
+  if test yes = "$GCC"; then
+    lt_prog_compiler_wl='-Wl,'
+    lt_prog_compiler_static='-static'
+
+    case $host_os in
+      aix*)
+      # All AIX code is PIC.
+      if test ia64 = "$host_cpu"; then
+	# AIX 5 now supports IA64 processor
+	lt_prog_compiler_static='-Bstatic'
+      fi
+      lt_prog_compiler_pic='-fPIC'
+      ;;
+
+    amigaos*)
+      case $host_cpu in
+      powerpc)
+            # see comment about AmigaOS4 .so support
+            lt_prog_compiler_pic='-fPIC'
+        ;;
+      m68k)
+            # FIXME: we need at least 68020 code to build shared libraries, but
+            # adding the '-m68020' flag to GCC prevents building anything better,
+            # like '-m68040'.
+            lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4'
+        ;;
+      esac
+      ;;
+
+    beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
+      # PIC is the default for these OSes.
+      ;;
+
+    mingw* | cygwin* | pw32* | os2* | cegcc*)
+      # This hack is so that the source file can tell whether it is being
+      # built for inclusion in a dll (and should export symbols for example).
+      # Although the cygwin gcc ignores -fPIC, still need this for old-style
+      # (--disable-auto-import) libraries
+      lt_prog_compiler_pic='-DDLL_EXPORT'
+      case $host_os in
+      os2*)
+	lt_prog_compiler_static='$wl-static'
+	;;
+      esac
+      ;;
+
+    darwin* | rhapsody*)
+      # PIC is the default on this platform
+      # Common symbols not allowed in MH_DYLIB files
+      lt_prog_compiler_pic='-fno-common'
+      ;;
+
+    haiku*)
+      # PIC is the default for Haiku.
+      # The "-static" flag exists, but is broken.
+      lt_prog_compiler_static=
+      ;;
+
+    hpux*)
+      # PIC is the default for 64-bit PA HP-UX, but not for 32-bit
+      # PA HP-UX.  On IA64 HP-UX, PIC is the default but the pic flag
+      # sets the default TLS model and affects inlining.
+      case $host_cpu in
+      hppa*64*)
+	# +Z the default
+	;;
+      *)
+	lt_prog_compiler_pic='-fPIC'
+	;;
+      esac
+      ;;
+
+    interix[3-9]*)
+      # Interix 3.x gcc -fpic/-fPIC options generate broken code.
+      # Instead, we relocate shared libraries at runtime.
+      ;;
+
+    msdosdjgpp*)
+      # Just because we use GCC doesn't mean we suddenly get shared libraries
+      # on systems that don't support them.
+      lt_prog_compiler_can_build_shared=no
+      enable_shared=no
+      ;;
+
+    *nto* | *qnx*)
+      # QNX uses GNU C++, but need to define -shared option too, otherwise
+      # it will coredump.
+      lt_prog_compiler_pic='-fPIC -shared'
+      ;;
+
+    sysv4*MP*)
+      if test -d /usr/nec; then
+	lt_prog_compiler_pic=-Kconform_pic
+      fi
+      ;;
+
+    *)
+      lt_prog_compiler_pic='-fPIC'
+      ;;
+    esac
+
+    case $cc_basename in
+    nvcc*) # Cuda Compiler Driver 2.2
+      lt_prog_compiler_wl='-Xlinker '
+      if test -n "$lt_prog_compiler_pic"; then
+        lt_prog_compiler_pic="-Xcompiler $lt_prog_compiler_pic"
+      fi
+      ;;
+    esac
+  else
+    # PORTME Check for flag to pass linker flags through the system compiler.
+    case $host_os in
+    aix*)
+      lt_prog_compiler_wl='-Wl,'
+      if test ia64 = "$host_cpu"; then
+	# AIX 5 now supports IA64 processor
+	lt_prog_compiler_static='-Bstatic'
+      else
+	lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp'
+      fi
+      ;;
+
+    darwin* | rhapsody*)
+      # PIC is the default on this platform
+      # Common symbols not allowed in MH_DYLIB files
+      lt_prog_compiler_pic='-fno-common'
+      case $cc_basename in
+      nagfor*)
+        # NAG Fortran compiler
+        lt_prog_compiler_wl='-Wl,-Wl,,'
+        lt_prog_compiler_pic='-PIC'
+        lt_prog_compiler_static='-Bstatic'
+        ;;
+      esac
+      ;;
+
+    mingw* | cygwin* | pw32* | os2* | cegcc*)
+      # This hack is so that the source file can tell whether it is being
+      # built for inclusion in a dll (and should export symbols for example).
+      lt_prog_compiler_pic='-DDLL_EXPORT'
+      case $host_os in
+      os2*)
+	lt_prog_compiler_static='$wl-static'
+	;;
+      esac
+      ;;
+
+    hpux9* | hpux10* | hpux11*)
+      lt_prog_compiler_wl='-Wl,'
+      # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
+      # not for PA HP-UX.
+      case $host_cpu in
+      hppa*64*|ia64*)
+	# +Z the default
+	;;
+      *)
+	lt_prog_compiler_pic='+Z'
+	;;
+      esac
+      # Is there a better lt_prog_compiler_static that works with the bundled CC?
+      lt_prog_compiler_static='$wl-a ${wl}archive'
+      ;;
+
+    irix5* | irix6* | nonstopux*)
+      lt_prog_compiler_wl='-Wl,'
+      # PIC (with -KPIC) is the default.
+      lt_prog_compiler_static='-non_shared'
+      ;;
+
+    linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
+      case $cc_basename in
+      # old Intel for x86_64, which still supported -KPIC.
+      ecc*)
+	lt_prog_compiler_wl='-Wl,'
+	lt_prog_compiler_pic='-KPIC'
+	lt_prog_compiler_static='-static'
+        ;;
+      # icc used to be incompatible with GCC.
+      # ICC 10 doesn't accept -KPIC any more.
+      icc* | ifort*)
+	lt_prog_compiler_wl='-Wl,'
+	lt_prog_compiler_pic='-fPIC'
+	lt_prog_compiler_static='-static'
+        ;;
+      # Lahey Fortran 8.1.
+      lf95*)
+	lt_prog_compiler_wl='-Wl,'
+	lt_prog_compiler_pic='--shared'
+	lt_prog_compiler_static='--static'
+	;;
+      nagfor*)
+	# NAG Fortran compiler
+	lt_prog_compiler_wl='-Wl,-Wl,,'
+	lt_prog_compiler_pic='-PIC'
+	lt_prog_compiler_static='-Bstatic'
+	;;
+      tcc*)
+	# Fabrice Bellard et al's Tiny C Compiler
+	lt_prog_compiler_wl='-Wl,'
+	lt_prog_compiler_pic='-fPIC'
+	lt_prog_compiler_static='-static'
+	;;
+      pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*)
+        # Portland Group compilers (*not* the Pentium gcc compiler,
+	# which looks to be a dead project)
+	lt_prog_compiler_wl='-Wl,'
+	lt_prog_compiler_pic='-fpic'
+	lt_prog_compiler_static='-Bstatic'
+        ;;
+      ccc*)
+        lt_prog_compiler_wl='-Wl,'
+        # All Alpha code is PIC.
+        lt_prog_compiler_static='-non_shared'
+        ;;
+      xl* | bgxl* | bgf* | mpixl*)
+	# IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene
+	lt_prog_compiler_wl='-Wl,'
+	lt_prog_compiler_pic='-qpic'
+	lt_prog_compiler_static='-qstaticlink'
+	;;
+      *)
+	case `$CC -V 2>&1 | sed 5q` in
+	*Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [1-7].* | *Sun*Fortran*\ 8.[0-3]*)
+	  # Sun Fortran 8.3 passes all unrecognized flags to the linker
+	  lt_prog_compiler_pic='-KPIC'
+	  lt_prog_compiler_static='-Bstatic'
+	  lt_prog_compiler_wl=''
+	  ;;
+	*Sun\ F* | *Sun*Fortran*)
+	  lt_prog_compiler_pic='-KPIC'
+	  lt_prog_compiler_static='-Bstatic'
+	  lt_prog_compiler_wl='-Qoption ld '
+	  ;;
+	*Sun\ C*)
+	  # Sun C 5.9
+	  lt_prog_compiler_pic='-KPIC'
+	  lt_prog_compiler_static='-Bstatic'
+	  lt_prog_compiler_wl='-Wl,'
+	  ;;
+        *Intel*\ [CF]*Compiler*)
+	  lt_prog_compiler_wl='-Wl,'
+	  lt_prog_compiler_pic='-fPIC'
+	  lt_prog_compiler_static='-static'
+	  ;;
+	*Portland\ Group*)
+	  lt_prog_compiler_wl='-Wl,'
+	  lt_prog_compiler_pic='-fpic'
+	  lt_prog_compiler_static='-Bstatic'
+	  ;;
+	esac
+	;;
+      esac
+      ;;
+
+    newsos6)
+      lt_prog_compiler_pic='-KPIC'
+      lt_prog_compiler_static='-Bstatic'
+      ;;
+
+    *nto* | *qnx*)
+      # QNX uses GNU C++, but need to define -shared option too, otherwise
+      # it will coredump.
+      lt_prog_compiler_pic='-fPIC -shared'
+      ;;
+
+    osf3* | osf4* | osf5*)
+      lt_prog_compiler_wl='-Wl,'
+      # All OSF/1 code is PIC.
+      lt_prog_compiler_static='-non_shared'
+      ;;
+
+    rdos*)
+      lt_prog_compiler_static='-non_shared'
+      ;;
+
+    solaris*)
+      lt_prog_compiler_pic='-KPIC'
+      lt_prog_compiler_static='-Bstatic'
+      case $cc_basename in
+      f77* | f90* | f95* | sunf77* | sunf90* | sunf95*)
+	lt_prog_compiler_wl='-Qoption ld ';;
+      *)
+	lt_prog_compiler_wl='-Wl,';;
+      esac
+      ;;
+
+    sunos4*)
+      lt_prog_compiler_wl='-Qoption ld '
+      lt_prog_compiler_pic='-PIC'
+      lt_prog_compiler_static='-Bstatic'
+      ;;
+
+    sysv4 | sysv4.2uw2* | sysv4.3*)
+      lt_prog_compiler_wl='-Wl,'
+      lt_prog_compiler_pic='-KPIC'
+      lt_prog_compiler_static='-Bstatic'
+      ;;
+
+    sysv4*MP*)
+      if test -d /usr/nec; then
+	lt_prog_compiler_pic='-Kconform_pic'
+	lt_prog_compiler_static='-Bstatic'
+      fi
+      ;;
+
+    sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
+      lt_prog_compiler_wl='-Wl,'
+      lt_prog_compiler_pic='-KPIC'
+      lt_prog_compiler_static='-Bstatic'
+      ;;
+
+    unicos*)
+      lt_prog_compiler_wl='-Wl,'
+      lt_prog_compiler_can_build_shared=no
+      ;;
+
+    uts4*)
+      lt_prog_compiler_pic='-pic'
+      lt_prog_compiler_static='-Bstatic'
+      ;;
+
+    *)
+      lt_prog_compiler_can_build_shared=no
+      ;;
+    esac
+  fi
+
+case $host_os in
+  # For platforms that do not support PIC, -DPIC is meaningless:
+  *djgpp*)
+    lt_prog_compiler_pic=
+    ;;
+  *)
+    lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC"
+    ;;
+esac
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5
+$as_echo_n "checking for $compiler option to produce PIC... " >&6; }
+if ${lt_cv_prog_compiler_pic+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_prog_compiler_pic=$lt_prog_compiler_pic
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic" >&5
+$as_echo "$lt_cv_prog_compiler_pic" >&6; }
+lt_prog_compiler_pic=$lt_cv_prog_compiler_pic
+
+#
+# Check to make sure the PIC flag actually works.
+#
+if test -n "$lt_prog_compiler_pic"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5
+$as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic works... " >&6; }
+if ${lt_cv_prog_compiler_pic_works+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_prog_compiler_pic_works=no
+   ac_outfile=conftest.$ac_objext
+   echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+   lt_compiler_flag="$lt_prog_compiler_pic -DPIC"  ## exclude from sc_useless_quotes_in_assignment
+   # Insert the option either (1) after the last *FLAGS variable, or
+   # (2) before a word containing "conftest.", or (3) at the end.
+   # Note that $ac_compile itself does not contain backslashes and begins
+   # with a dollar sign (not a hyphen), so the echo should work correctly.
+   # The option is referenced via a variable to avoid confusing sed.
+   lt_compile=`echo "$ac_compile" | $SED \
+   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+   -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+   -e 's:$: $lt_compiler_flag:'`
+   (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>conftest.err)
+   ac_status=$?
+   cat conftest.err >&5
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
+   if (exit $ac_status) && test -s "$ac_outfile"; then
+     # The compiler can only warn and ignore the option if not recognized
+     # So say no if there are warnings other than the usual output.
+     $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp
+     $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+     if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
+       lt_cv_prog_compiler_pic_works=yes
+     fi
+   fi
+   $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works" >&5
+$as_echo "$lt_cv_prog_compiler_pic_works" >&6; }
+
+if test yes = "$lt_cv_prog_compiler_pic_works"; then
+    case $lt_prog_compiler_pic in
+     "" | " "*) ;;
+     *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;;
+     esac
+else
+    lt_prog_compiler_pic=
+     lt_prog_compiler_can_build_shared=no
+fi
+
+fi
+
+
+
+
+
+
+
+
+
+
+
+#
+# Check to make sure the static flag actually works.
+#
+wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\"
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5
+$as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; }
+if ${lt_cv_prog_compiler_static_works+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_prog_compiler_static_works=no
+   save_LDFLAGS=$LDFLAGS
+   LDFLAGS="$LDFLAGS $lt_tmp_static_flag"
+   echo "$lt_simple_link_test_code" > conftest.$ac_ext
+   if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
+     # The linker can only warn and ignore the option if not recognized
+     # So say no if there are warnings
+     if test -s conftest.err; then
+       # Append any errors to the config.log.
+       cat conftest.err 1>&5
+       $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp
+       $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+       if diff conftest.exp conftest.er2 >/dev/null; then
+         lt_cv_prog_compiler_static_works=yes
+       fi
+     else
+       lt_cv_prog_compiler_static_works=yes
+     fi
+   fi
+   $RM -r conftest*
+   LDFLAGS=$save_LDFLAGS
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works" >&5
+$as_echo "$lt_cv_prog_compiler_static_works" >&6; }
+
+if test yes = "$lt_cv_prog_compiler_static_works"; then
+    :
+else
+    lt_prog_compiler_static=
+fi
+
+
+
+
+
+
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5
+$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; }
+if ${lt_cv_prog_compiler_c_o+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_prog_compiler_c_o=no
+   $RM -r conftest 2>/dev/null
+   mkdir conftest
+   cd conftest
+   mkdir out
+   echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+   lt_compiler_flag="-o out/conftest2.$ac_objext"
+   # Insert the option either (1) after the last *FLAGS variable, or
+   # (2) before a word containing "conftest.", or (3) at the end.
+   # Note that $ac_compile itself does not contain backslashes and begins
+   # with a dollar sign (not a hyphen), so the echo should work correctly.
+   lt_compile=`echo "$ac_compile" | $SED \
+   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+   -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+   -e 's:$: $lt_compiler_flag:'`
+   (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>out/conftest.err)
+   ac_status=$?
+   cat out/conftest.err >&5
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
+   if (exit $ac_status) && test -s out/conftest2.$ac_objext
+   then
+     # The compiler can only warn and ignore the option if not recognized
+     # So say no if there are warnings
+     $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp
+     $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
+     if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
+       lt_cv_prog_compiler_c_o=yes
+     fi
+   fi
+   chmod u+w . 2>&5
+   $RM conftest*
+   # SGI C++ compiler will create directory out/ii_files/ for
+   # template instantiation
+   test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files
+   $RM out/* && rmdir out
+   cd ..
+   $RM -r conftest
+   $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5
+$as_echo "$lt_cv_prog_compiler_c_o" >&6; }
+
+
+
+
+
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5
+$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; }
+if ${lt_cv_prog_compiler_c_o+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_prog_compiler_c_o=no
+   $RM -r conftest 2>/dev/null
+   mkdir conftest
+   cd conftest
+   mkdir out
+   echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+   lt_compiler_flag="-o out/conftest2.$ac_objext"
+   # Insert the option either (1) after the last *FLAGS variable, or
+   # (2) before a word containing "conftest.", or (3) at the end.
+   # Note that $ac_compile itself does not contain backslashes and begins
+   # with a dollar sign (not a hyphen), so the echo should work correctly.
+   lt_compile=`echo "$ac_compile" | $SED \
+   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+   -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+   -e 's:$: $lt_compiler_flag:'`
+   (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>out/conftest.err)
+   ac_status=$?
+   cat out/conftest.err >&5
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
+   if (exit $ac_status) && test -s out/conftest2.$ac_objext
+   then
+     # The compiler can only warn and ignore the option if not recognized
+     # So say no if there are warnings
+     $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp
+     $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
+     if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
+       lt_cv_prog_compiler_c_o=yes
+     fi
+   fi
+   chmod u+w . 2>&5
+   $RM conftest*
+   # SGI C++ compiler will create directory out/ii_files/ for
+   # template instantiation
+   test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files
+   $RM out/* && rmdir out
+   cd ..
+   $RM -r conftest
+   $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5
+$as_echo "$lt_cv_prog_compiler_c_o" >&6; }
+
+
+
+
+hard_links=nottested
+if test no = "$lt_cv_prog_compiler_c_o" && test no != "$need_locks"; then
+  # do not overwrite the value of need_locks provided by the user
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5
+$as_echo_n "checking if we can lock with hard links... " >&6; }
+  hard_links=yes
+  $RM conftest*
+  ln conftest.a conftest.b 2>/dev/null && hard_links=no
+  touch conftest.a
+  ln conftest.a conftest.b 2>&5 || hard_links=no
+  ln conftest.a conftest.b 2>/dev/null && hard_links=no
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5
+$as_echo "$hard_links" >&6; }
+  if test no = "$hard_links"; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&5
+$as_echo "$as_me: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&2;}
+    need_locks=warn
+  fi
+else
+  need_locks=no
+fi
+
+
+
+
+
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5
+$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; }
+
+  runpath_var=
+  allow_undefined_flag=
+  always_export_symbols=no
+  archive_cmds=
+  archive_expsym_cmds=
+  compiler_needs_object=no
+  enable_shared_with_static_runtimes=no
+  export_dynamic_flag_spec=
+  export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+  hardcode_automatic=no
+  hardcode_direct=no
+  hardcode_direct_absolute=no
+  hardcode_libdir_flag_spec=
+  hardcode_libdir_separator=
+  hardcode_minus_L=no
+  hardcode_shlibpath_var=unsupported
+  inherit_rpath=no
+  link_all_deplibs=unknown
+  module_cmds=
+  module_expsym_cmds=
+  old_archive_from_new_cmds=
+  old_archive_from_expsyms_cmds=
+  thread_safe_flag_spec=
+  whole_archive_flag_spec=
+  # include_expsyms should be a list of space-separated symbols to be *always*
+  # included in the symbol list
+  include_expsyms=
+  # exclude_expsyms can be an extended regexp of symbols to exclude
+  # it will be wrapped by ' (' and ')$', so one must not match beginning or
+  # end of line.  Example: 'a|bc|.*d.*' will exclude the symbols 'a' and 'bc',
+  # as well as any symbol that contains 'd'.
+  exclude_expsyms='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'
+  # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out
+  # platforms (ab)use it in PIC code, but their linkers get confused if
+  # the symbol is explicitly referenced.  Since portable code cannot
+  # rely on this symbol name, it's probably fine to never include it in
+  # preloaded symbol tables.
+  # Exclude shared library initialization/finalization symbols.
+  extract_expsyms_cmds=
+
+  case $host_os in
+  cygwin* | mingw* | pw32* | cegcc*)
+    # FIXME: the MSVC++ port hasn't been tested in a loooong time
+    # When not using gcc, we currently assume that we are using
+    # Microsoft Visual C++.
+    if test yes != "$GCC"; then
+      with_gnu_ld=no
+    fi
+    ;;
+  interix*)
+    # we just hope/assume this is gcc and not c89 (= MSVC++)
+    with_gnu_ld=yes
+    ;;
+  openbsd* | bitrig*)
+    with_gnu_ld=no
+    ;;
+  linux* | k*bsd*-gnu | gnu*)
+    link_all_deplibs=no
+    ;;
+  esac
+
+  ld_shlibs=yes
+
+  # On some targets, GNU ld is compatible enough with the native linker
+  # that we're better off using the native interface for both.
+  lt_use_gnu_ld_interface=no
+  if test yes = "$with_gnu_ld"; then
+    case $host_os in
+      aix*)
+	# The AIX port of GNU ld has always aspired to compatibility
+	# with the native linker.  However, as the warning in the GNU ld
+	# block says, versions before 2.19.5* couldn't really create working
+	# shared libraries, regardless of the interface used.
+	case `$LD -v 2>&1` in
+	  *\ \(GNU\ Binutils\)\ 2.19.5*) ;;
+	  *\ \(GNU\ Binutils\)\ 2.[2-9]*) ;;
+	  *\ \(GNU\ Binutils\)\ [3-9]*) ;;
+	  *)
+	    lt_use_gnu_ld_interface=yes
+	    ;;
+	esac
+	;;
+      *)
+	lt_use_gnu_ld_interface=yes
+	;;
+    esac
+  fi
+
+  if test yes = "$lt_use_gnu_ld_interface"; then
+    # If archive_cmds runs LD, not CC, wlarc should be empty
+    wlarc='$wl'
+
+    # Set some defaults for GNU ld with shared library support. These
+    # are reset later if shared libraries are not supported. Putting them
+    # here allows them to be overridden if necessary.
+    runpath_var=LD_RUN_PATH
+    hardcode_libdir_flag_spec='$wl-rpath $wl$libdir'
+    export_dynamic_flag_spec='$wl--export-dynamic'
+    # ancient GNU ld didn't support --whole-archive et. al.
+    if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then
+      whole_archive_flag_spec=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive'
+    else
+      whole_archive_flag_spec=
+    fi
+    supports_anon_versioning=no
+    case `$LD -v | $SED -e 's/(^)\+)\s\+//' 2>&1` in
+      *GNU\ gold*) supports_anon_versioning=yes ;;
+      *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11
+      *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ...
+      *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ...
+      *\ 2.11.*) ;; # other 2.11 versions
+      *) supports_anon_versioning=yes ;;
+    esac
+
+    # See if GNU ld supports shared libraries.
+    case $host_os in
+    aix[3-9]*)
+      # On AIX/PPC, the GNU linker is very broken
+      if test ia64 != "$host_cpu"; then
+	ld_shlibs=no
+	cat <<_LT_EOF 1>&2
+
+*** Warning: the GNU linker, at least up to release 2.19, is reported
+*** to be unable to reliably create shared libraries on AIX.
+*** Therefore, libtool is disabling shared libraries support.  If you
+*** really care for shared libraries, you may want to install binutils
+*** 2.20 or above, or modify your PATH so that a non-GNU linker is found.
+*** You will then need to restart the configuration process.
+
+_LT_EOF
+      fi
+      ;;
+
+    amigaos*)
+      case $host_cpu in
+      powerpc)
+            # see comment about AmigaOS4 .so support
+            archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+            archive_expsym_cmds=''
+        ;;
+      m68k)
+            archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+            hardcode_libdir_flag_spec='-L$libdir'
+            hardcode_minus_L=yes
+        ;;
+      esac
+      ;;
+
+    beos*)
+      if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+	allow_undefined_flag=unsupported
+	# Joseph Beckenbach <jrb3@best.com> says some releases of gcc
+	# support --undefined.  This deserves some investigation.  FIXME
+	archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+      else
+	ld_shlibs=no
+      fi
+      ;;
+
+    cygwin* | mingw* | pw32* | cegcc*)
+      # _LT_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless,
+      # as there is no search path for DLLs.
+      hardcode_libdir_flag_spec='-L$libdir'
+      export_dynamic_flag_spec='$wl--export-all-symbols'
+      allow_undefined_flag=unsupported
+      always_export_symbols=no
+      enable_shared_with_static_runtimes=yes
+      export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols'
+      exclude_expsyms='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'
+
+      if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
+        archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+	# If the export-symbols file already is a .def file, use it as
+	# is; otherwise, prepend EXPORTS...
+	archive_expsym_cmds='if   test DEF = "`$SED -n     -e '\''s/^[	 ]*//'\''     -e '\''/^\(;.*\)*$/d'\''     -e '\''s/^\(EXPORTS\|LIBRARY\)\([	 ].*\)*$/DEF/p'\''     -e q     $export_symbols`" ; then
+          cp $export_symbols $output_objdir/$soname.def;
+        else
+          echo EXPORTS > $output_objdir/$soname.def;
+          cat $export_symbols >> $output_objdir/$soname.def;
+        fi~
+        $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+      else
+	ld_shlibs=no
+      fi
+      ;;
+
+    haiku*)
+      archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+      link_all_deplibs=yes
+      ;;
+
+    os2*)
+      hardcode_libdir_flag_spec='-L$libdir'
+      hardcode_minus_L=yes
+      allow_undefined_flag=unsupported
+      shrext_cmds=.dll
+      archive_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
+	$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
+	$ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
+	$ECHO EXPORTS >> $output_objdir/$libname.def~
+	emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~
+	$CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
+	emximp -o $lib $output_objdir/$libname.def'
+      archive_expsym_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
+	$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
+	$ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
+	$ECHO EXPORTS >> $output_objdir/$libname.def~
+	prefix_cmds="$SED"~
+	if test EXPORTS = "`$SED 1q $export_symbols`"; then
+	  prefix_cmds="$prefix_cmds -e 1d";
+	fi~
+	prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~
+	cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~
+	$CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
+	emximp -o $lib $output_objdir/$libname.def'
+      old_archive_From_new_cmds='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def'
+      enable_shared_with_static_runtimes=yes
+      ;;
+
+    interix[3-9]*)
+      hardcode_direct=no
+      hardcode_shlibpath_var=no
+      hardcode_libdir_flag_spec='$wl-rpath,$libdir'
+      export_dynamic_flag_spec='$wl-E'
+      # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
+      # Instead, shared libraries are loaded at an image base (0x10000000 by
+      # default) and relocated if they conflict, which is a slow very memory
+      # consuming and fragmenting process.  To avoid this, we pick a random,
+      # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
+      # time.  Moving up from 0x10000000 also allows more sbrk(2) space.
+      archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+      archive_expsym_cmds='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+      ;;
+
+    gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu)
+      tmp_diet=no
+      if test linux-dietlibc = "$host_os"; then
+	case $cc_basename in
+	  diet\ *) tmp_diet=yes;;	# linux-dietlibc with static linking (!diet-dyn)
+	esac
+      fi
+      if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \
+	 && test no = "$tmp_diet"
+      then
+	tmp_addflag=' $pic_flag'
+	tmp_sharedflag='-shared'
+	case $cc_basename,$host_cpu in
+        pgcc*)				# Portland Group C compiler
+	  whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+	  tmp_addflag=' $pic_flag'
+	  ;;
+	pgf77* | pgf90* | pgf95* | pgfortran*)
+					# Portland Group f77 and f90 compilers
+	  whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+	  tmp_addflag=' $pic_flag -Mnomain' ;;
+	ecc*,ia64* | icc*,ia64*)	# Intel C compiler on ia64
+	  tmp_addflag=' -i_dynamic' ;;
+	efc*,ia64* | ifort*,ia64*)	# Intel Fortran compiler on ia64
+	  tmp_addflag=' -i_dynamic -nofor_main' ;;
+	ifc* | ifort*)			# Intel Fortran compiler
+	  tmp_addflag=' -nofor_main' ;;
+	lf95*)				# Lahey Fortran 8.1
+	  whole_archive_flag_spec=
+	  tmp_sharedflag='--shared' ;;
+        nagfor*)                        # NAGFOR 5.3
+          tmp_sharedflag='-Wl,-shared' ;;
+	xl[cC]* | bgxl[cC]* | mpixl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below)
+	  tmp_sharedflag='-qmkshrobj'
+	  tmp_addflag= ;;
+	nvcc*)	# Cuda Compiler Driver 2.2
+	  whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+	  compiler_needs_object=yes
+	  ;;
+	esac
+	case `$CC -V 2>&1 | sed 5q` in
+	*Sun\ C*)			# Sun C 5.9
+	  whole_archive_flag_spec='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+	  compiler_needs_object=yes
+	  tmp_sharedflag='-G' ;;
+	*Sun\ F*)			# Sun Fortran 8.3
+	  tmp_sharedflag='-G' ;;
+	esac
+	archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+
+        if test yes = "$supports_anon_versioning"; then
+          archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~
+            cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+            echo "local: *; };" >> $output_objdir/$libname.ver~
+            $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib'
+        fi
+
+	case $cc_basename in
+	tcc*)
+	  export_dynamic_flag_spec='-rdynamic'
+	  ;;
+	xlf* | bgf* | bgxlf* | mpixlf*)
+	  # IBM XL Fortran 10.1 on PPC cannot create shared libs itself
+	  whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive'
+	  hardcode_libdir_flag_spec='$wl-rpath $wl$libdir'
+	  archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib'
+	  if test yes = "$supports_anon_versioning"; then
+	    archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~
+              cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+              echo "local: *; };" >> $output_objdir/$libname.ver~
+              $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib'
+	  fi
+	  ;;
+	esac
+      else
+        ld_shlibs=no
+      fi
+      ;;
+
+    netbsd* | netbsdelf*-gnu)
+      if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+	archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
+	wlarc=
+      else
+	archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+	archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+      fi
+      ;;
+
+    solaris*)
+      if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then
+	ld_shlibs=no
+	cat <<_LT_EOF 1>&2
+
+*** Warning: The releases 2.8.* of the GNU linker cannot reliably
+*** create shared libraries on Solaris systems.  Therefore, libtool
+*** is disabling shared libraries support.  We urge you to upgrade GNU
+*** binutils to release 2.9.1 or newer.  Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+_LT_EOF
+      elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+	archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+	archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+      else
+	ld_shlibs=no
+      fi
+      ;;
+
+    sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*)
+      case `$LD -v 2>&1` in
+        *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*)
+	ld_shlibs=no
+	cat <<_LT_EOF 1>&2
+
+*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 cannot
+*** reliably create shared libraries on SCO systems.  Therefore, libtool
+*** is disabling shared libraries support.  We urge you to upgrade GNU
+*** binutils to release 2.16.91.0.3 or newer.  Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+_LT_EOF
+	;;
+	*)
+	  # For security reasons, it is highly recommended that you always
+	  # use absolute paths for naming shared libraries, and exclude the
+	  # DT_RUNPATH tag from executables and libraries.  But doing so
+	  # requires that you compile everything twice, which is a pain.
+	  if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+	    hardcode_libdir_flag_spec='$wl-rpath $wl$libdir'
+	    archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+	    archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+	  else
+	    ld_shlibs=no
+	  fi
+	;;
+      esac
+      ;;
+
+    sunos4*)
+      archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+      wlarc=
+      hardcode_direct=yes
+      hardcode_shlibpath_var=no
+      ;;
+
+    *)
+      if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+	archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+	archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+      else
+	ld_shlibs=no
+      fi
+      ;;
+    esac
+
+    if test no = "$ld_shlibs"; then
+      runpath_var=
+      hardcode_libdir_flag_spec=
+      export_dynamic_flag_spec=
+      whole_archive_flag_spec=
+    fi
+  else
+    # PORTME fill in a description of your system's linker (not GNU ld)
+    case $host_os in
+    aix3*)
+      allow_undefined_flag=unsupported
+      always_export_symbols=yes
+      archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname'
+      # Note: this linker hardcodes the directories in LIBPATH if there
+      # are no directories specified by -L.
+      hardcode_minus_L=yes
+      if test yes = "$GCC" && test -z "$lt_prog_compiler_static"; then
+	# Neither direct hardcoding nor static linking is supported with a
+	# broken collect2.
+	hardcode_direct=unsupported
+      fi
+      ;;
+
+    aix[4-9]*)
+      if test ia64 = "$host_cpu"; then
+	# On IA64, the linker does run time linking by default, so we don't
+	# have to do anything special.
+	aix_use_runtimelinking=no
+	exp_sym_flag='-Bexport'
+	no_entry_flag=
+      else
+	# If we're using GNU nm, then we don't want the "-C" option.
+	# -C means demangle to GNU nm, but means don't demangle to AIX nm.
+	# Without the "-l" option, or with the "-B" option, AIX nm treats
+	# weak defined symbols like other global defined symbols, whereas
+	# GNU nm marks them as "W".
+	# While the 'weak' keyword is ignored in the Export File, we need
+	# it in the Import File for the 'aix-soname' feature, so we have
+	# to replace the "-B" option with "-P" for AIX nm.
+	if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
+	  export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols'
+	else
+	  export_symbols_cmds='`func_echo_all $NM | $SED -e '\''s/B\([^B]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && (substr(\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols'
+	fi
+	aix_use_runtimelinking=no
+
+	# Test if we are trying to use run time linking or normal
+	# AIX style linking. If -brtl is somewhere in LDFLAGS, we
+	# have runtime linking enabled, and use it for executables.
+	# For shared libraries, we enable/disable runtime linking
+	# depending on the kind of the shared library created -
+	# when "with_aix_soname,aix_use_runtimelinking" is:
+	# "aix,no"   lib.a(lib.so.V) shared, rtl:no,  for executables
+	# "aix,yes"  lib.so          shared, rtl:yes, for executables
+	#            lib.a           static archive
+	# "both,no"  lib.so.V(shr.o) shared, rtl:yes
+	#            lib.a(lib.so.V) shared, rtl:no,  for executables
+	# "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables
+	#            lib.a(lib.so.V) shared, rtl:no
+	# "svr4,*"   lib.so.V(shr.o) shared, rtl:yes, for executables
+	#            lib.a           static archive
+	case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*)
+	  for ld_flag in $LDFLAGS; do
+	  if (test x-brtl = "x$ld_flag" || test x-Wl,-brtl = "x$ld_flag"); then
+	    aix_use_runtimelinking=yes
+	    break
+	  fi
+	  done
+	  if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then
+	    # With aix-soname=svr4, we create the lib.so.V shared archives only,
+	    # so we don't have lib.a shared libs to link our executables.
+	    # We have to force runtime linking in this case.
+	    aix_use_runtimelinking=yes
+	    LDFLAGS="$LDFLAGS -Wl,-brtl"
+	  fi
+	  ;;
+	esac
+
+	exp_sym_flag='-bexport'
+	no_entry_flag='-bnoentry'
+      fi
+
+      # When large executables or shared objects are built, AIX ld can
+      # have problems creating the table of contents.  If linking a library
+      # or program results in "error TOC overflow" add -mminimal-toc to
+      # CXXFLAGS/CFLAGS for g++/gcc.  In the cases where that is not
+      # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
+
+      archive_cmds=''
+      hardcode_direct=yes
+      hardcode_direct_absolute=yes
+      hardcode_libdir_separator=':'
+      link_all_deplibs=yes
+      file_list_spec='$wl-f,'
+      case $with_aix_soname,$aix_use_runtimelinking in
+      aix,*) ;; # traditional, no import file
+      svr4,* | *,yes) # use import file
+	# The Import File defines what to hardcode.
+	hardcode_direct=no
+	hardcode_direct_absolute=no
+	;;
+      esac
+
+      if test yes = "$GCC"; then
+	case $host_os in aix4.[012]|aix4.[012].*)
+	# We only want to do this on AIX 4.2 and lower, the check
+	# below for broken collect2 doesn't work under 4.3+
+	  collect2name=`$CC -print-prog-name=collect2`
+	  if test -f "$collect2name" &&
+	   strings "$collect2name" | $GREP resolve_lib_name >/dev/null
+	  then
+	  # We have reworked collect2
+	  :
+	  else
+	  # We have old collect2
+	  hardcode_direct=unsupported
+	  # It fails to find uninstalled libraries when the uninstalled
+	  # path is not listed in the libpath.  Setting hardcode_minus_L
+	  # to unsupported forces relinking
+	  hardcode_minus_L=yes
+	  hardcode_libdir_flag_spec='-L$libdir'
+	  hardcode_libdir_separator=
+	  fi
+	  ;;
+	esac
+	shared_flag='-shared'
+	if test yes = "$aix_use_runtimelinking"; then
+	  shared_flag="$shared_flag "'$wl-G'
+	fi
+	# Need to ensure runtime linking is disabled for the traditional
+	# shared library, or the linker may eventually find shared libraries
+	# /with/ Import File - we do not want to mix them.
+	shared_flag_aix='-shared'
+	shared_flag_svr4='-shared $wl-G'
+      else
+	# not using gcc
+	if test ia64 = "$host_cpu"; then
+	# VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
+	# chokes on -Wl,-G. The following line is correct:
+	  shared_flag='-G'
+	else
+	  if test yes = "$aix_use_runtimelinking"; then
+	    shared_flag='$wl-G'
+	  else
+	    shared_flag='$wl-bM:SRE'
+	  fi
+	  shared_flag_aix='$wl-bM:SRE'
+	  shared_flag_svr4='$wl-G'
+	fi
+      fi
+
+      export_dynamic_flag_spec='$wl-bexpall'
+      # It seems that -bexpall does not export symbols beginning with
+      # underscore (_), so it is better to generate a list of symbols to export.
+      always_export_symbols=yes
+      if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then
+	# Warning - without using the other runtime loading flags (-brtl),
+	# -berok will link without error, but may produce a broken library.
+	allow_undefined_flag='-berok'
+        # Determine the default libpath from the value encoded in an
+        # empty executable.
+        if test set = "${lt_cv_aix_libpath+set}"; then
+  aix_libpath=$lt_cv_aix_libpath
+else
+  if ${lt_cv_aix_libpath_+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+
+  lt_aix_libpath_sed='
+      /Import File Strings/,/^$/ {
+	  /^0/ {
+	      s/^0  *\([^ ]*\) *$/\1/
+	      p
+	  }
+      }'
+  lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+  # Check for a 64-bit object if we didn't find anything.
+  if test -z "$lt_cv_aix_libpath_"; then
+    lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+  fi
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+  if test -z "$lt_cv_aix_libpath_"; then
+    lt_cv_aix_libpath_=/usr/lib:/lib
+  fi
+
+fi
+
+  aix_libpath=$lt_cv_aix_libpath_
+fi
+
+        hardcode_libdir_flag_spec='$wl-blibpath:$libdir:'"$aix_libpath"
+        archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag
+      else
+	if test ia64 = "$host_cpu"; then
+	  hardcode_libdir_flag_spec='$wl-R $libdir:/usr/lib:/lib'
+	  allow_undefined_flag="-z nodefs"
+	  archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols"
+	else
+	 # Determine the default libpath from the value encoded in an
+	 # empty executable.
+	 if test set = "${lt_cv_aix_libpath+set}"; then
+  aix_libpath=$lt_cv_aix_libpath
+else
+  if ${lt_cv_aix_libpath_+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+
+  lt_aix_libpath_sed='
+      /Import File Strings/,/^$/ {
+	  /^0/ {
+	      s/^0  *\([^ ]*\) *$/\1/
+	      p
+	  }
+      }'
+  lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+  # Check for a 64-bit object if we didn't find anything.
+  if test -z "$lt_cv_aix_libpath_"; then
+    lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+  fi
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+  if test -z "$lt_cv_aix_libpath_"; then
+    lt_cv_aix_libpath_=/usr/lib:/lib
+  fi
+
+fi
+
+  aix_libpath=$lt_cv_aix_libpath_
+fi
+
+	 hardcode_libdir_flag_spec='$wl-blibpath:$libdir:'"$aix_libpath"
+	  # Warning - without using the other run time loading flags,
+	  # -berok will link without error, but may produce a broken library.
+	  no_undefined_flag=' $wl-bernotok'
+	  allow_undefined_flag=' $wl-berok'
+	  if test yes = "$with_gnu_ld"; then
+	    # We only use this code for GNU lds that support --whole-archive.
+	    whole_archive_flag_spec='$wl--whole-archive$convenience $wl--no-whole-archive'
+	  else
+	    # Exported symbols can be pulled into shared objects from archives
+	    whole_archive_flag_spec='$convenience'
+	  fi
+	  archive_cmds_need_lc=yes
+	  archive_expsym_cmds='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d'
+	  # -brtl affects multiple linker settings, -berok does not and is overridden later
+	  compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([, ]\\)%-berok\\1%g"`'
+	  if test svr4 != "$with_aix_soname"; then
+	    # This is similar to how AIX traditionally builds its shared libraries.
+	    archive_expsym_cmds="$archive_expsym_cmds"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname'
+	  fi
+	  if test aix != "$with_aix_soname"; then
+	    archive_expsym_cmds="$archive_expsym_cmds"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp'
+	  else
+	    # used by -dlpreopen to get the symbols
+	    archive_expsym_cmds="$archive_expsym_cmds"'~$MV  $output_objdir/$realname.d/$soname $output_objdir'
+	  fi
+	  archive_expsym_cmds="$archive_expsym_cmds"'~$RM -r $output_objdir/$realname.d'
+	fi
+      fi
+      ;;
+
+    amigaos*)
+      case $host_cpu in
+      powerpc)
+            # see comment about AmigaOS4 .so support
+            archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+            archive_expsym_cmds=''
+        ;;
+      m68k)
+            archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+            hardcode_libdir_flag_spec='-L$libdir'
+            hardcode_minus_L=yes
+        ;;
+      esac
+      ;;
+
+    bsdi[45]*)
+      export_dynamic_flag_spec=-rdynamic
+      ;;
+
+    cygwin* | mingw* | pw32* | cegcc*)
+      # When not using gcc, we currently assume that we are using
+      # Microsoft Visual C++.
+      # hardcode_libdir_flag_spec is actually meaningless, as there is
+      # no search path for DLLs.
+      case $cc_basename in
+      cl*)
+	# Native MSVC
+	hardcode_libdir_flag_spec=' '
+	allow_undefined_flag=unsupported
+	always_export_symbols=yes
+	file_list_spec='@'
+	# Tell ltmain to make .lib files, not .a files.
+	libext=lib
+	# Tell ltmain to make .dll files, not .so files.
+	shrext_cmds=.dll
+	# FIXME: Setting linknames here is a bad hack.
+	archive_cmds='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames='
+	archive_expsym_cmds='if   test DEF = "`$SED -n     -e '\''s/^[	 ]*//'\''     -e '\''/^\(;.*\)*$/d'\''     -e '\''s/^\(EXPORTS\|LIBRARY\)\([	 ].*\)*$/DEF/p'\''     -e q     $export_symbols`" ; then
+            cp "$export_symbols" "$output_objdir/$soname.def";
+            echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp";
+          else
+            $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp;
+          fi~
+          $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
+          linknames='
+	# The linker will not automatically build a static lib if we build a DLL.
+	# _LT_TAGVAR(old_archive_from_new_cmds, )='true'
+	enable_shared_with_static_runtimes=yes
+	exclude_expsyms='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*'
+	export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1,DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols'
+	# Don't use ranlib
+	old_postinstall_cmds='chmod 644 $oldlib'
+	postlink_cmds='lt_outputfile="@OUTPUT@"~
+          lt_tool_outputfile="@TOOL_OUTPUT@"~
+          case $lt_outputfile in
+            *.exe|*.EXE) ;;
+            *)
+              lt_outputfile=$lt_outputfile.exe
+              lt_tool_outputfile=$lt_tool_outputfile.exe
+              ;;
+          esac~
+          if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then
+            $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1;
+            $RM "$lt_outputfile.manifest";
+          fi'
+	;;
+      *)
+	# Assume MSVC wrapper
+	hardcode_libdir_flag_spec=' '
+	allow_undefined_flag=unsupported
+	# Tell ltmain to make .lib files, not .a files.
+	libext=lib
+	# Tell ltmain to make .dll files, not .so files.
+	shrext_cmds=.dll
+	# FIXME: Setting linknames here is a bad hack.
+	archive_cmds='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames='
+	# The linker will automatically build a .lib file if we build a DLL.
+	old_archive_from_new_cmds='true'
+	# FIXME: Should let the user specify the lib program.
+	old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs'
+	enable_shared_with_static_runtimes=yes
+	;;
+      esac
+      ;;
+
+    darwin* | rhapsody*)
+
+
+  archive_cmds_need_lc=no
+  hardcode_direct=no
+  hardcode_automatic=yes
+  hardcode_shlibpath_var=unsupported
+  if test yes = "$lt_cv_ld_force_load"; then
+    whole_archive_flag_spec='`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience $wl-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`'
+
+  else
+    whole_archive_flag_spec=''
+  fi
+  link_all_deplibs=yes
+  allow_undefined_flag=$_lt_dar_allow_undefined
+  case $cc_basename in
+     ifort*|nagfor*) _lt_dar_can_shared=yes ;;
+     *) _lt_dar_can_shared=$GCC ;;
+  esac
+  if test yes = "$_lt_dar_can_shared"; then
+    output_verbose_link_cmd=func_echo_all
+    archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil"
+    module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil"
+    archive_expsym_cmds="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil"
+    module_expsym_cmds="sed -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil"
+
+  else
+  ld_shlibs=no
+  fi
+
+      ;;
+
+    dgux*)
+      archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_libdir_flag_spec='-L$libdir'
+      hardcode_shlibpath_var=no
+      ;;
+
+    # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor
+    # support.  Future versions do this automatically, but an explicit c++rt0.o
+    # does not break anything, and helps significantly (at the cost of a little
+    # extra space).
+    freebsd2.2*)
+      archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o'
+      hardcode_libdir_flag_spec='-R$libdir'
+      hardcode_direct=yes
+      hardcode_shlibpath_var=no
+      ;;
+
+    # Unfortunately, older versions of FreeBSD 2 do not have this feature.
+    freebsd2.*)
+      archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_direct=yes
+      hardcode_minus_L=yes
+      hardcode_shlibpath_var=no
+      ;;
+
+    # FreeBSD 3 and greater uses gcc -shared to do shared libraries.
+    freebsd* | dragonfly*)
+      archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+      hardcode_libdir_flag_spec='-R$libdir'
+      hardcode_direct=yes
+      hardcode_shlibpath_var=no
+      ;;
+
+    hpux9*)
+      if test yes = "$GCC"; then
+	archive_cmds='$RM $output_objdir/$soname~$CC -shared $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib'
+      else
+	archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib'
+      fi
+      hardcode_libdir_flag_spec='$wl+b $wl$libdir'
+      hardcode_libdir_separator=:
+      hardcode_direct=yes
+
+      # hardcode_minus_L: Not really in the search PATH,
+      # but as the default location of the library.
+      hardcode_minus_L=yes
+      export_dynamic_flag_spec='$wl-E'
+      ;;
+
+    hpux10*)
+      if test yes,no = "$GCC,$with_gnu_ld"; then
+	archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+      else
+	archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
+      fi
+      if test no = "$with_gnu_ld"; then
+	hardcode_libdir_flag_spec='$wl+b $wl$libdir'
+	hardcode_libdir_separator=:
+	hardcode_direct=yes
+	hardcode_direct_absolute=yes
+	export_dynamic_flag_spec='$wl-E'
+	# hardcode_minus_L: Not really in the search PATH,
+	# but as the default location of the library.
+	hardcode_minus_L=yes
+      fi
+      ;;
+
+    hpux11*)
+      if test yes,no = "$GCC,$with_gnu_ld"; then
+	case $host_cpu in
+	hppa*64*)
+	  archive_cmds='$CC -shared $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	ia64*)
+	  archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	*)
+	  archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	esac
+      else
+	case $host_cpu in
+	hppa*64*)
+	  archive_cmds='$CC -b $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	ia64*)
+	  archive_cmds='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	*)
+
+	  # Older versions of the 11.00 compiler do not understand -b yet
+	  # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does)
+	  { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC understands -b" >&5
+$as_echo_n "checking if $CC understands -b... " >&6; }
+if ${lt_cv_prog_compiler__b+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_prog_compiler__b=no
+   save_LDFLAGS=$LDFLAGS
+   LDFLAGS="$LDFLAGS -b"
+   echo "$lt_simple_link_test_code" > conftest.$ac_ext
+   if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
+     # The linker can only warn and ignore the option if not recognized
+     # So say no if there are warnings
+     if test -s conftest.err; then
+       # Append any errors to the config.log.
+       cat conftest.err 1>&5
+       $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp
+       $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+       if diff conftest.exp conftest.er2 >/dev/null; then
+         lt_cv_prog_compiler__b=yes
+       fi
+     else
+       lt_cv_prog_compiler__b=yes
+     fi
+   fi
+   $RM -r conftest*
+   LDFLAGS=$save_LDFLAGS
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler__b" >&5
+$as_echo "$lt_cv_prog_compiler__b" >&6; }
+
+if test yes = "$lt_cv_prog_compiler__b"; then
+    archive_cmds='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+else
+    archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
+fi
+
+	  ;;
+	esac
+      fi
+      if test no = "$with_gnu_ld"; then
+	hardcode_libdir_flag_spec='$wl+b $wl$libdir'
+	hardcode_libdir_separator=:
+
+	case $host_cpu in
+	hppa*64*|ia64*)
+	  hardcode_direct=no
+	  hardcode_shlibpath_var=no
+	  ;;
+	*)
+	  hardcode_direct=yes
+	  hardcode_direct_absolute=yes
+	  export_dynamic_flag_spec='$wl-E'
+
+	  # hardcode_minus_L: Not really in the search PATH,
+	  # but as the default location of the library.
+	  hardcode_minus_L=yes
+	  ;;
+	esac
+      fi
+      ;;
+
+    irix5* | irix6* | nonstopux*)
+      if test yes = "$GCC"; then
+	archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
+	# Try to use the -exported_symbol ld option, if it does not
+	# work, assume that -exports_file does not work either and
+	# implicitly export all symbols.
+	# This should be the same for all languages, so no per-tag cache variable.
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $host_os linker accepts -exported_symbol" >&5
+$as_echo_n "checking whether the $host_os linker accepts -exported_symbol... " >&6; }
+if ${lt_cv_irix_exported_symbol+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  save_LDFLAGS=$LDFLAGS
+	   LDFLAGS="$LDFLAGS -shared $wl-exported_symbol ${wl}foo $wl-update_registry $wl/dev/null"
+	   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+int foo (void) { return 0; }
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  lt_cv_irix_exported_symbol=yes
+else
+  lt_cv_irix_exported_symbol=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+           LDFLAGS=$save_LDFLAGS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_irix_exported_symbol" >&5
+$as_echo "$lt_cv_irix_exported_symbol" >&6; }
+	if test yes = "$lt_cv_irix_exported_symbol"; then
+          archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations $wl-exports_file $wl$export_symbols -o $lib'
+	fi
+	link_all_deplibs=no
+      else
+	archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
+	archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -exports_file $export_symbols -o $lib'
+      fi
+      archive_cmds_need_lc='no'
+      hardcode_libdir_flag_spec='$wl-rpath $wl$libdir'
+      hardcode_libdir_separator=:
+      inherit_rpath=yes
+      link_all_deplibs=yes
+      ;;
+
+    linux*)
+      case $cc_basename in
+      tcc*)
+	# Fabrice Bellard et al's Tiny C Compiler
+	ld_shlibs=yes
+	archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+	;;
+      esac
+      ;;
+
+    netbsd* | netbsdelf*-gnu)
+      if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+	archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'  # a.out
+      else
+	archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags'      # ELF
+      fi
+      hardcode_libdir_flag_spec='-R$libdir'
+      hardcode_direct=yes
+      hardcode_shlibpath_var=no
+      ;;
+
+    newsos6)
+      archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_direct=yes
+      hardcode_libdir_flag_spec='$wl-rpath $wl$libdir'
+      hardcode_libdir_separator=:
+      hardcode_shlibpath_var=no
+      ;;
+
+    *nto* | *qnx*)
+      ;;
+
+    openbsd* | bitrig*)
+      if test -f /usr/libexec/ld.so; then
+	hardcode_direct=yes
+	hardcode_shlibpath_var=no
+	hardcode_direct_absolute=yes
+	if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then
+	  archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+	  archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags $wl-retain-symbols-file,$export_symbols'
+	  hardcode_libdir_flag_spec='$wl-rpath,$libdir'
+	  export_dynamic_flag_spec='$wl-E'
+	else
+	  archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+	  hardcode_libdir_flag_spec='$wl-rpath,$libdir'
+	fi
+      else
+	ld_shlibs=no
+      fi
+      ;;
+
+    os2*)
+      hardcode_libdir_flag_spec='-L$libdir'
+      hardcode_minus_L=yes
+      allow_undefined_flag=unsupported
+      shrext_cmds=.dll
+      archive_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
+	$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
+	$ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
+	$ECHO EXPORTS >> $output_objdir/$libname.def~
+	emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~
+	$CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
+	emximp -o $lib $output_objdir/$libname.def'
+      archive_expsym_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
+	$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
+	$ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
+	$ECHO EXPORTS >> $output_objdir/$libname.def~
+	prefix_cmds="$SED"~
+	if test EXPORTS = "`$SED 1q $export_symbols`"; then
+	  prefix_cmds="$prefix_cmds -e 1d";
+	fi~
+	prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~
+	cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~
+	$CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
+	emximp -o $lib $output_objdir/$libname.def'
+      old_archive_From_new_cmds='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def'
+      enable_shared_with_static_runtimes=yes
+      ;;
+
+    osf3*)
+      if test yes = "$GCC"; then
+	allow_undefined_flag=' $wl-expect_unresolved $wl\*'
+	archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
+      else
+	allow_undefined_flag=' -expect_unresolved \*'
+	archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
+      fi
+      archive_cmds_need_lc='no'
+      hardcode_libdir_flag_spec='$wl-rpath $wl$libdir'
+      hardcode_libdir_separator=:
+      ;;
+
+    osf4* | osf5*)	# as osf3* with the addition of -msym flag
+      if test yes = "$GCC"; then
+	allow_undefined_flag=' $wl-expect_unresolved $wl\*'
+	archive_cmds='$CC -shared$allow_undefined_flag $pic_flag $libobjs $deplibs $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
+	hardcode_libdir_flag_spec='$wl-rpath $wl$libdir'
+      else
+	allow_undefined_flag=' -expect_unresolved \*'
+	archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
+	archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~
+          $CC -shared$allow_undefined_flag $wl-input $wl$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~$RM $lib.exp'
+
+	# Both c and cxx compiler support -rpath directly
+	hardcode_libdir_flag_spec='-rpath $libdir'
+      fi
+      archive_cmds_need_lc='no'
+      hardcode_libdir_separator=:
+      ;;
+
+    solaris*)
+      no_undefined_flag=' -z defs'
+      if test yes = "$GCC"; then
+	wlarc='$wl'
+	archive_cmds='$CC -shared $pic_flag $wl-z ${wl}text $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags'
+	archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+          $CC -shared $pic_flag $wl-z ${wl}text $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+      else
+	case `$CC -V 2>&1` in
+	*"Compilers 5.0"*)
+	  wlarc=''
+	  archive_cmds='$LD -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $linker_flags'
+	  archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+            $LD -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp'
+	  ;;
+	*)
+	  wlarc='$wl'
+	  archive_cmds='$CC -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $compiler_flags'
+	  archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+            $CC -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+	  ;;
+	esac
+      fi
+      hardcode_libdir_flag_spec='-R$libdir'
+      hardcode_shlibpath_var=no
+      case $host_os in
+      solaris2.[0-5] | solaris2.[0-5].*) ;;
+      *)
+	# The compiler driver will combine and reorder linker options,
+	# but understands '-z linker_flag'.  GCC discards it without '$wl',
+	# but is careful enough not to reorder.
+	# Supported since Solaris 2.6 (maybe 2.5.1?)
+	if test yes = "$GCC"; then
+	  whole_archive_flag_spec='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract'
+	else
+	  whole_archive_flag_spec='-z allextract$convenience -z defaultextract'
+	fi
+	;;
+      esac
+      link_all_deplibs=yes
+      ;;
+
+    sunos4*)
+      if test sequent = "$host_vendor"; then
+	# Use $CC to link under sequent, because it throws in some extra .o
+	# files that make .init and .fini sections work.
+	archive_cmds='$CC -G $wl-h $soname -o $lib $libobjs $deplibs $compiler_flags'
+      else
+	archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags'
+      fi
+      hardcode_libdir_flag_spec='-L$libdir'
+      hardcode_direct=yes
+      hardcode_minus_L=yes
+      hardcode_shlibpath_var=no
+      ;;
+
+    sysv4)
+      case $host_vendor in
+	sni)
+	  archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+	  hardcode_direct=yes # is this really true???
+	;;
+	siemens)
+	  ## LD is ld it makes a PLAMLIB
+	  ## CC just makes a GrossModule.
+	  archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags'
+	  reload_cmds='$CC -r -o $output$reload_objs'
+	  hardcode_direct=no
+        ;;
+	motorola)
+	  archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+	  hardcode_direct=no #Motorola manual says yes, but my tests say they lie
+	;;
+      esac
+      runpath_var='LD_RUN_PATH'
+      hardcode_shlibpath_var=no
+      ;;
+
+    sysv4.3*)
+      archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_shlibpath_var=no
+      export_dynamic_flag_spec='-Bexport'
+      ;;
+
+    sysv4*MP*)
+      if test -d /usr/nec; then
+	archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+	hardcode_shlibpath_var=no
+	runpath_var=LD_RUN_PATH
+	hardcode_runpath_var=yes
+	ld_shlibs=yes
+      fi
+      ;;
+
+    sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*)
+      no_undefined_flag='$wl-z,text'
+      archive_cmds_need_lc=no
+      hardcode_shlibpath_var=no
+      runpath_var='LD_RUN_PATH'
+
+      if test yes = "$GCC"; then
+	archive_cmds='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	archive_expsym_cmds='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+      else
+	archive_cmds='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	archive_expsym_cmds='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+      fi
+      ;;
+
+    sysv5* | sco3.2v5* | sco5v6*)
+      # Note: We CANNOT use -z defs as we might desire, because we do not
+      # link with -lc, and that would cause any symbols used from libc to
+      # always be unresolved, which means just about no library would
+      # ever link correctly.  If we're not using GNU ld we use -z text
+      # though, which does catch some bad symbols but isn't as heavy-handed
+      # as -z defs.
+      no_undefined_flag='$wl-z,text'
+      allow_undefined_flag='$wl-z,nodefs'
+      archive_cmds_need_lc=no
+      hardcode_shlibpath_var=no
+      hardcode_libdir_flag_spec='$wl-R,$libdir'
+      hardcode_libdir_separator=':'
+      link_all_deplibs=yes
+      export_dynamic_flag_spec='$wl-Bexport'
+      runpath_var='LD_RUN_PATH'
+
+      if test yes = "$GCC"; then
+	archive_cmds='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	archive_expsym_cmds='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+      else
+	archive_cmds='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	archive_expsym_cmds='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+      fi
+      ;;
+
+    uts4*)
+      archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_libdir_flag_spec='-L$libdir'
+      hardcode_shlibpath_var=no
+      ;;
+
+    *)
+      ld_shlibs=no
+      ;;
+    esac
+
+    if test sni = "$host_vendor"; then
+      case $host in
+      sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+	export_dynamic_flag_spec='$wl-Blargedynsym'
+	;;
+      esac
+    fi
+  fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs" >&5
+$as_echo "$ld_shlibs" >&6; }
+test no = "$ld_shlibs" && can_build_shared=no
+
+with_gnu_ld=$with_gnu_ld
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+#
+# Do we need to explicitly link libc?
+#
+case "x$archive_cmds_need_lc" in
+x|xyes)
+  # Assume -lc should be added
+  archive_cmds_need_lc=yes
+
+  if test yes,yes = "$GCC,$enable_shared"; then
+    case $archive_cmds in
+    *'~'*)
+      # FIXME: we may have to deal with multi-command sequences.
+      ;;
+    '$CC '*)
+      # Test whether the compiler implicitly links with -lc since on some
+      # systems, -lgcc has to come before -lc. If gcc already passes -lc
+      # to ld, don't add -lc before -lgcc.
+      { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5
+$as_echo_n "checking whether -lc should be explicitly linked in... " >&6; }
+if ${lt_cv_archive_cmds_need_lc+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  $RM conftest*
+	echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+	if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } 2>conftest.err; then
+	  soname=conftest
+	  lib=conftest
+	  libobjs=conftest.$ac_objext
+	  deplibs=
+	  wl=$lt_prog_compiler_wl
+	  pic_flag=$lt_prog_compiler_pic
+	  compiler_flags=-v
+	  linker_flags=-v
+	  verstring=
+	  output_objdir=.
+	  libname=conftest
+	  lt_save_allow_undefined_flag=$allow_undefined_flag
+	  allow_undefined_flag=
+	  if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5
+  (eval $archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+	  then
+	    lt_cv_archive_cmds_need_lc=no
+	  else
+	    lt_cv_archive_cmds_need_lc=yes
+	  fi
+	  allow_undefined_flag=$lt_save_allow_undefined_flag
+	else
+	  cat conftest.err 1>&5
+	fi
+	$RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc" >&5
+$as_echo "$lt_cv_archive_cmds_need_lc" >&6; }
+      archive_cmds_need_lc=$lt_cv_archive_cmds_need_lc
+      ;;
+    esac
+  fi
+  ;;
+esac
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5
+$as_echo_n "checking dynamic linker characteristics... " >&6; }
+
+if test yes = "$GCC"; then
+  case $host_os in
+    darwin*) lt_awk_arg='/^libraries:/,/LR/' ;;
+    *) lt_awk_arg='/^libraries:/' ;;
+  esac
+  case $host_os in
+    mingw* | cegcc*) lt_sed_strip_eq='s|=\([A-Za-z]:\)|\1|g' ;;
+    *) lt_sed_strip_eq='s|=/|/|g' ;;
+  esac
+  lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq`
+  case $lt_search_path_spec in
+  *\;*)
+    # if the path contains ";" then we assume it to be the separator
+    # otherwise default to the standard path separator (i.e. ":") - it is
+    # assumed that no part of a normal pathname contains ";" but that should
+    # okay in the real world where ";" in dirpaths is itself problematic.
+    lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'`
+    ;;
+  *)
+    lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"`
+    ;;
+  esac
+  # Ok, now we have the path, separated by spaces, we can step through it
+  # and add multilib dir if necessary...
+  lt_tmp_lt_search_path_spec=
+  lt_multi_os_dir=/`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null`
+  # ...but if some path component already ends with the multilib dir we assume
+  # that all is fine and trust -print-search-dirs as is (GCC 4.2? or newer).
+  case "$lt_multi_os_dir; $lt_search_path_spec " in
+  "/; "* | "/.; "* | "/./; "* | *"$lt_multi_os_dir "* | *"$lt_multi_os_dir/ "*)
+    lt_multi_os_dir=
+    ;;
+  esac
+  for lt_sys_path in $lt_search_path_spec; do
+    if test -d "$lt_sys_path$lt_multi_os_dir"; then
+      lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path$lt_multi_os_dir"
+    elif test -n "$lt_multi_os_dir"; then
+      test -d "$lt_sys_path" && \
+	lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path"
+    fi
+  done
+  lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk '
+BEGIN {RS = " "; FS = "/|\n";} {
+  lt_foo = "";
+  lt_count = 0;
+  for (lt_i = NF; lt_i > 0; lt_i--) {
+    if ($lt_i != "" && $lt_i != ".") {
+      if ($lt_i == "..") {
+        lt_count++;
+      } else {
+        if (lt_count == 0) {
+          lt_foo = "/" $lt_i lt_foo;
+        } else {
+          lt_count--;
+        }
+      }
+    }
+  }
+  if (lt_foo != "") { lt_freq[lt_foo]++; }
+  if (lt_freq[lt_foo] == 1) { print lt_foo; }
+}'`
+  # AWK program above erroneously prepends '/' to C:/dos/paths
+  # for these hosts.
+  case $host_os in
+    mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\
+      $SED 's|/\([A-Za-z]:\)|\1|g'` ;;
+  esac
+  sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP`
+else
+  sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
+fi
+library_names_spec=
+libname_spec='lib$name'
+soname_spec=
+shrext_cmds=.so
+postinstall_cmds=
+postuninstall_cmds=
+finish_cmds=
+finish_eval=
+shlibpath_var=
+shlibpath_overrides_runpath=unknown
+version_type=none
+dynamic_linker="$host_os ld.so"
+sys_lib_dlsearch_path_spec="/lib /usr/lib"
+need_lib_prefix=unknown
+hardcode_into_libs=no
+
+# when you set need_version to no, make sure it does not cause -set_version
+# flags to be left without arguments
+need_version=unknown
+
+
+
+case $host_os in
+aix3*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  library_names_spec='$libname$release$shared_ext$versuffix $libname.a'
+  shlibpath_var=LIBPATH
+
+  # AIX 3 has no versioning support, so we append a major version to the name.
+  soname_spec='$libname$release$shared_ext$major'
+  ;;
+
+aix[4-9]*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  need_lib_prefix=no
+  need_version=no
+  hardcode_into_libs=yes
+  if test ia64 = "$host_cpu"; then
+    # AIX 5 supports IA64
+    library_names_spec='$libname$release$shared_ext$major $libname$release$shared_ext$versuffix $libname$shared_ext'
+    shlibpath_var=LD_LIBRARY_PATH
+  else
+    # With GCC up to 2.95.x, collect2 would create an import file
+    # for dependence libraries.  The import file would start with
+    # the line '#! .'.  This would cause the generated library to
+    # depend on '.', always an invalid library.  This was fixed in
+    # development snapshots of GCC prior to 3.0.
+    case $host_os in
+      aix4 | aix4.[01] | aix4.[01].*)
+      if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)'
+	   echo ' yes '
+	   echo '#endif'; } | $CC -E - | $GREP yes > /dev/null; then
+	:
+      else
+	can_build_shared=no
+      fi
+      ;;
+    esac
+    # Using Import Files as archive members, it is possible to support
+    # filename-based versioning of shared library archives on AIX. While
+    # this would work for both with and without runtime linking, it will
+    # prevent static linking of such archives. So we do filename-based
+    # shared library versioning with .so extension only, which is used
+    # when both runtime linking and shared linking is enabled.
+    # Unfortunately, runtime linking may impact performance, so we do
+    # not want this to be the default eventually. Also, we use the
+    # versioned .so libs for executables only if there is the -brtl
+    # linker flag in LDFLAGS as well, or --with-aix-soname=svr4 only.
+    # To allow for filename-based versioning support, we need to create
+    # libNAME.so.V as an archive file, containing:
+    # *) an Import File, referring to the versioned filename of the
+    #    archive as well as the shared archive member, telling the
+    #    bitwidth (32 or 64) of that shared object, and providing the
+    #    list of exported symbols of that shared object, eventually
+    #    decorated with the 'weak' keyword
+    # *) the shared object with the F_LOADONLY flag set, to really avoid
+    #    it being seen by the linker.
+    # At run time we better use the real file rather than another symlink,
+    # but for link time we create the symlink libNAME.so -> libNAME.so.V
+
+    case $with_aix_soname,$aix_use_runtimelinking in
+    # AIX (on Power*) has no versioning support, so currently we cannot hardcode correct
+    # soname into executable. Probably we can add versioning support to
+    # collect2, so additional links can be useful in future.
+    aix,yes) # traditional libtool
+      dynamic_linker='AIX unversionable lib.so'
+      # If using run time linking (on AIX 4.2 or later) use lib<name>.so
+      # instead of lib<name>.a to let people know that these are not
+      # typical AIX shared libraries.
+      library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+      ;;
+    aix,no) # traditional AIX only
+      dynamic_linker='AIX lib.a(lib.so.V)'
+      # We preserve .a as extension for shared libraries through AIX4.2
+      # and later when we are not doing run time linking.
+      library_names_spec='$libname$release.a $libname.a'
+      soname_spec='$libname$release$shared_ext$major'
+      ;;
+    svr4,*) # full svr4 only
+      dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o)"
+      library_names_spec='$libname$release$shared_ext$major $libname$shared_ext'
+      # We do not specify a path in Import Files, so LIBPATH fires.
+      shlibpath_overrides_runpath=yes
+      ;;
+    *,yes) # both, prefer svr4
+      dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o), lib.a(lib.so.V)"
+      library_names_spec='$libname$release$shared_ext$major $libname$shared_ext'
+      # unpreferred sharedlib libNAME.a needs extra handling
+      postinstall_cmds='test -n "$linkname" || linkname="$realname"~func_stripname "" ".so" "$linkname"~$install_shared_prog "$dir/$func_stripname_result.$libext" "$destdir/$func_stripname_result.$libext"~test -z "$tstripme" || test -z "$striplib" || $striplib "$destdir/$func_stripname_result.$libext"'
+      postuninstall_cmds='for n in $library_names $old_library; do :; done~func_stripname "" ".so" "$n"~test "$func_stripname_result" = "$n" || func_append rmfiles " $odir/$func_stripname_result.$libext"'
+      # We do not specify a path in Import Files, so LIBPATH fires.
+      shlibpath_overrides_runpath=yes
+      ;;
+    *,no) # both, prefer aix
+      dynamic_linker="AIX lib.a(lib.so.V), lib.so.V($shared_archive_member_spec.o)"
+      library_names_spec='$libname$release.a $libname.a'
+      soname_spec='$libname$release$shared_ext$major'
+      # unpreferred sharedlib libNAME.so.V and symlink libNAME.so need extra handling
+      postinstall_cmds='test -z "$dlname" || $install_shared_prog $dir/$dlname $destdir/$dlname~test -z "$tstripme" || test -z "$striplib" || $striplib $destdir/$dlname~test -n "$linkname" || linkname=$realname~func_stripname "" ".a" "$linkname"~(cd "$destdir" && $LN_S -f $dlname $func_stripname_result.so)'
+      postuninstall_cmds='test -z "$dlname" || func_append rmfiles " $odir/$dlname"~for n in $old_library $library_names; do :; done~func_stripname "" ".a" "$n"~func_append rmfiles " $odir/$func_stripname_result.so"'
+      ;;
+    esac
+    shlibpath_var=LIBPATH
+  fi
+  ;;
+
+amigaos*)
+  case $host_cpu in
+  powerpc)
+    # Since July 2007 AmigaOS4 officially supports .so libraries.
+    # When compiling the executable, add -use-dynld -Lsobjs: to the compileline.
+    library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+    ;;
+  m68k)
+    library_names_spec='$libname.ixlibrary $libname.a'
+    # Create ${libname}_ixlibrary.a entries in /sys/libs.
+    finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
+    ;;
+  esac
+  ;;
+
+beos*)
+  library_names_spec='$libname$shared_ext'
+  dynamic_linker="$host_os ld.so"
+  shlibpath_var=LIBRARY_PATH
+  ;;
+
+bsdi[45]*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  need_version=no
+  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+  soname_spec='$libname$release$shared_ext$major'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
+  sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib"
+  # the default ld.so.conf also contains /usr/contrib/lib and
+  # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow
+  # libtool to hard-code these into programs
+  ;;
+
+cygwin* | mingw* | pw32* | cegcc*)
+  version_type=windows
+  shrext_cmds=.dll
+  need_version=no
+  need_lib_prefix=no
+
+  case $GCC,$cc_basename in
+  yes,*)
+    # gcc
+    library_names_spec='$libname.dll.a'
+    # DLL is installed to $(libdir)/../bin by postinstall_cmds
+    postinstall_cmds='base_file=`basename \$file`~
+      dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~
+      dldir=$destdir/`dirname \$dlpath`~
+      test -d \$dldir || mkdir -p \$dldir~
+      $install_prog $dir/$dlname \$dldir/$dlname~
+      chmod a+x \$dldir/$dlname~
+      if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then
+        eval '\''$striplib \$dldir/$dlname'\'' || exit \$?;
+      fi'
+    postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+      dlpath=$dir/\$dldll~
+       $RM \$dlpath'
+    shlibpath_overrides_runpath=yes
+
+    case $host_os in
+    cygwin*)
+      # Cygwin DLLs use 'cyg' prefix rather than 'lib'
+      soname_spec='`echo $libname | sed -e 's/^lib/cyg/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext'
+
+      sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"
+      ;;
+    mingw* | cegcc*)
+      # MinGW DLLs use traditional 'lib' prefix
+      soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext'
+      ;;
+    pw32*)
+      # pw32 DLLs use 'pw' prefix rather than 'lib'
+      library_names_spec='`echo $libname | sed -e 's/^lib/pw/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext'
+      ;;
+    esac
+    dynamic_linker='Win32 ld.exe'
+    ;;
+
+  *,cl*)
+    # Native MSVC
+    libname_spec='$name'
+    soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext'
+    library_names_spec='$libname.dll.lib'
+
+    case $build_os in
+    mingw*)
+      sys_lib_search_path_spec=
+      lt_save_ifs=$IFS
+      IFS=';'
+      for lt_path in $LIB
+      do
+        IFS=$lt_save_ifs
+        # Let DOS variable expansion print the short 8.3 style file name.
+        lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"`
+        sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path"
+      done
+      IFS=$lt_save_ifs
+      # Convert to MSYS style.
+      sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'`
+      ;;
+    cygwin*)
+      # Convert to unix form, then to dos form, then back to unix form
+      # but this time dos style (no spaces!) so that the unix form looks
+      # like /cygdrive/c/PROGRA~1:/cygdr...
+      sys_lib_search_path_spec=`cygpath --path --unix "$LIB"`
+      sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null`
+      sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
+      ;;
+    *)
+      sys_lib_search_path_spec=$LIB
+      if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then
+        # It is most probably a Windows format PATH.
+        sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
+      else
+        sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
+      fi
+      # FIXME: find the short name or the path components, as spaces are
+      # common. (e.g. "Program Files" -> "PROGRA~1")
+      ;;
+    esac
+
+    # DLL is installed to $(libdir)/../bin by postinstall_cmds
+    postinstall_cmds='base_file=`basename \$file`~
+      dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~
+      dldir=$destdir/`dirname \$dlpath`~
+      test -d \$dldir || mkdir -p \$dldir~
+      $install_prog $dir/$dlname \$dldir/$dlname'
+    postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+      dlpath=$dir/\$dldll~
+       $RM \$dlpath'
+    shlibpath_overrides_runpath=yes
+    dynamic_linker='Win32 link.exe'
+    ;;
+
+  *)
+    # Assume MSVC wrapper
+    library_names_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext $libname.lib'
+    dynamic_linker='Win32 ld.exe'
+    ;;
+  esac
+  # FIXME: first we should search . and the directory the executable is in
+  shlibpath_var=PATH
+  ;;
+
+darwin* | rhapsody*)
+  dynamic_linker="$host_os dyld"
+  version_type=darwin
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='$libname$release$major$shared_ext $libname$shared_ext'
+  soname_spec='$libname$release$major$shared_ext'
+  shlibpath_overrides_runpath=yes
+  shlibpath_var=DYLD_LIBRARY_PATH
+  shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`'
+
+  sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"
+  sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib'
+  ;;
+
+dgux*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+  soname_spec='$libname$release$shared_ext$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+freebsd* | dragonfly*)
+  # DragonFly does not have aout.  When/if they implement a new
+  # versioning mechanism, adjust this.
+  if test -x /usr/bin/objformat; then
+    objformat=`/usr/bin/objformat`
+  else
+    case $host_os in
+    freebsd[23].*) objformat=aout ;;
+    *) objformat=elf ;;
+    esac
+  fi
+  version_type=freebsd-$objformat
+  case $version_type in
+    freebsd-elf*)
+      library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+      soname_spec='$libname$release$shared_ext$major'
+      need_version=no
+      need_lib_prefix=no
+      ;;
+    freebsd-*)
+      library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'
+      need_version=yes
+      ;;
+  esac
+  shlibpath_var=LD_LIBRARY_PATH
+  case $host_os in
+  freebsd2.*)
+    shlibpath_overrides_runpath=yes
+    ;;
+  freebsd3.[01]* | freebsdelf3.[01]*)
+    shlibpath_overrides_runpath=yes
+    hardcode_into_libs=yes
+    ;;
+  freebsd3.[2-9]* | freebsdelf3.[2-9]* | \
+  freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1)
+    shlibpath_overrides_runpath=no
+    hardcode_into_libs=yes
+    ;;
+  *) # from 4.6 on, and DragonFly
+    shlibpath_overrides_runpath=yes
+    hardcode_into_libs=yes
+    ;;
+  esac
+  ;;
+
+haiku*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  need_lib_prefix=no
+  need_version=no
+  dynamic_linker="$host_os runtime_loader"
+  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+  soname_spec='$libname$release$shared_ext$major'
+  shlibpath_var=LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib'
+  hardcode_into_libs=yes
+  ;;
+
+hpux9* | hpux10* | hpux11*)
+  # Give a soname corresponding to the major version so that dld.sl refuses to
+  # link against other versions.
+  version_type=sunos
+  need_lib_prefix=no
+  need_version=no
+  case $host_cpu in
+  ia64*)
+    shrext_cmds='.so'
+    hardcode_into_libs=yes
+    dynamic_linker="$host_os dld.so"
+    shlibpath_var=LD_LIBRARY_PATH
+    shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+    library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+    soname_spec='$libname$release$shared_ext$major'
+    if test 32 = "$HPUX_IA64_MODE"; then
+      sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib"
+      sys_lib_dlsearch_path_spec=/usr/lib/hpux32
+    else
+      sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64"
+      sys_lib_dlsearch_path_spec=/usr/lib/hpux64
+    fi
+    ;;
+  hppa*64*)
+    shrext_cmds='.sl'
+    hardcode_into_libs=yes
+    dynamic_linker="$host_os dld.sl"
+    shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH
+    shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+    library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+    soname_spec='$libname$release$shared_ext$major'
+    sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64"
+    sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+    ;;
+  *)
+    shrext_cmds='.sl'
+    dynamic_linker="$host_os dld.sl"
+    shlibpath_var=SHLIB_PATH
+    shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
+    library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+    soname_spec='$libname$release$shared_ext$major'
+    ;;
+  esac
+  # HP-UX runs *really* slowly unless shared libraries are mode 555, ...
+  postinstall_cmds='chmod 555 $lib'
+  # or fails outright, so override atomically:
+  install_override_mode=555
+  ;;
+
+interix[3-9]*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+  soname_spec='$libname$release$shared_ext$major'
+  dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  ;;
+
+irix5* | irix6* | nonstopux*)
+  case $host_os in
+    nonstopux*) version_type=nonstopux ;;
+    *)
+	if test yes = "$lt_cv_prog_gnu_ld"; then
+		version_type=linux # correct to gnu/linux during the next big refactor
+	else
+		version_type=irix
+	fi ;;
+  esac
+  need_lib_prefix=no
+  need_version=no
+  soname_spec='$libname$release$shared_ext$major'
+  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$release$shared_ext $libname$shared_ext'
+  case $host_os in
+  irix5* | nonstopux*)
+    libsuff= shlibsuff=
+    ;;
+  *)
+    case $LD in # libtool.m4 will add one of these switches to LD
+    *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ")
+      libsuff= shlibsuff= libmagic=32-bit;;
+    *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ")
+      libsuff=32 shlibsuff=N32 libmagic=N32;;
+    *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ")
+      libsuff=64 shlibsuff=64 libmagic=64-bit;;
+    *) libsuff= shlibsuff= libmagic=never-match;;
+    esac
+    ;;
+  esac
+  shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
+  shlibpath_overrides_runpath=no
+  sys_lib_search_path_spec="/usr/lib$libsuff /lib$libsuff /usr/local/lib$libsuff"
+  sys_lib_dlsearch_path_spec="/usr/lib$libsuff /lib$libsuff"
+  hardcode_into_libs=yes
+  ;;
+
+# No shared lib support for Linux oldld, aout, or coff.
+linux*oldld* | linux*aout* | linux*coff*)
+  dynamic_linker=no
+  ;;
+
+linux*android*)
+  version_type=none # Android doesn't support versioned libraries.
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='$libname$release$shared_ext'
+  soname_spec='$libname$release$shared_ext'
+  finish_cmds=
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+
+  # This implies no fast_install, which is unacceptable.
+  # Some rework will be needed to allow for fast_install
+  # before this can be enabled.
+  hardcode_into_libs=yes
+
+  dynamic_linker='Android linker'
+  # Don't embed -rpath directories since the linker doesn't support them.
+  hardcode_libdir_flag_spec='-L$libdir'
+  ;;
+
+# This must be glibc/ELF.
+linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+  soname_spec='$libname$release$shared_ext$major'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+
+  # Some binutils ld are patched to set DT_RUNPATH
+  if ${lt_cv_shlibpath_overrides_runpath+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_shlibpath_overrides_runpath=no
+    save_LDFLAGS=$LDFLAGS
+    save_libdir=$libdir
+    eval "libdir=/foo; wl=\"$lt_prog_compiler_wl\"; \
+	 LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec\""
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  if  ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then :
+  lt_cv_shlibpath_overrides_runpath=yes
+fi
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+    LDFLAGS=$save_LDFLAGS
+    libdir=$save_libdir
+
+fi
+
+  shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath
+
+  # This implies no fast_install, which is unacceptable.
+  # Some rework will be needed to allow for fast_install
+  # before this can be enabled.
+  hardcode_into_libs=yes
+
+  # Ideally, we could use ldconfig to report *all* directores which are
+  # searched for libraries, however this is still not possible.  Aside from not
+  # being certain /sbin/ldconfig is available, command
+  # 'ldconfig -N -X -v | grep ^/' on 64bit Fedora does not report /usr/lib64,
+  # even though it is searched at run-time.  Try to do the best guess by
+  # appending ld.so.conf contents (and includes) to the search path.
+  if test -f /etc/ld.so.conf; then
+    lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[	 ]*hwcap[	 ]/d;s/[:,	]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '`
+    sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra"
+  fi
+
+  # We used to test for /lib/ld.so.1 and disable shared libraries on
+  # powerpc, because MkLinux only supported shared libraries with the
+  # GNU dynamic linker.  Since this was broken with cross compilers,
+  # most powerpc-linux boxes support dynamic linking these days and
+  # people can always --disable-shared, the test was removed, and we
+  # assume the GNU/Linux dynamic linker is in use.
+  dynamic_linker='GNU/Linux ld.so'
+  ;;
+
+netbsdelf*-gnu)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  dynamic_linker='NetBSD ld.elf_so'
+  ;;
+
+netbsd*)
+  version_type=sunos
+  need_lib_prefix=no
+  need_version=no
+  if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+    library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'
+    finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+    dynamic_linker='NetBSD (a.out) ld.so'
+  else
+    library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+    soname_spec='$libname$release$shared_ext$major'
+    dynamic_linker='NetBSD ld.elf_so'
+  fi
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  hardcode_into_libs=yes
+  ;;
+
+newsos6)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  ;;
+
+*nto* | *qnx*)
+  version_type=qnx
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+  soname_spec='$libname$release$shared_ext$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  dynamic_linker='ldqnx.so'
+  ;;
+
+openbsd* | bitrig*)
+  version_type=sunos
+  sys_lib_dlsearch_path_spec=/usr/lib
+  need_lib_prefix=no
+  if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then
+    need_version=no
+  else
+    need_version=yes
+  fi
+  library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  ;;
+
+os2*)
+  libname_spec='$name'
+  version_type=windows
+  shrext_cmds=.dll
+  need_version=no
+  need_lib_prefix=no
+  # OS/2 can only load a DLL with a base name of 8 characters or less.
+  soname_spec='`test -n "$os2dllname" && libname="$os2dllname";
+    v=$($ECHO $release$versuffix | tr -d .-);
+    n=$($ECHO $libname | cut -b -$((8 - ${#v})) | tr . _);
+    $ECHO $n$v`$shared_ext'
+  library_names_spec='${libname}_dll.$libext'
+  dynamic_linker='OS/2 ld.exe'
+  shlibpath_var=BEGINLIBPATH
+  sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
+  sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+  postinstall_cmds='base_file=`basename \$file`~
+    dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; $ECHO \$dlname'\''`~
+    dldir=$destdir/`dirname \$dlpath`~
+    test -d \$dldir || mkdir -p \$dldir~
+    $install_prog $dir/$dlname \$dldir/$dlname~
+    chmod a+x \$dldir/$dlname~
+    if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then
+      eval '\''$striplib \$dldir/$dlname'\'' || exit \$?;
+    fi'
+  postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; $ECHO \$dlname'\''`~
+    dlpath=$dir/\$dldll~
+    $RM \$dlpath'
+  ;;
+
+osf3* | osf4* | osf5*)
+  version_type=osf
+  need_lib_prefix=no
+  need_version=no
+  soname_spec='$libname$release$shared_ext$major'
+  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+  shlibpath_var=LD_LIBRARY_PATH
+  sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
+  sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+  ;;
+
+rdos*)
+  dynamic_linker=no
+  ;;
+
+solaris*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+  soname_spec='$libname$release$shared_ext$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  hardcode_into_libs=yes
+  # ldd complains unless libraries are executable
+  postinstall_cmds='chmod +x $lib'
+  ;;
+
+sunos4*)
+  version_type=sunos
+  library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'
+  finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  if test yes = "$with_gnu_ld"; then
+    need_lib_prefix=no
+  fi
+  need_version=yes
+  ;;
+
+sysv4 | sysv4.3*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+  soname_spec='$libname$release$shared_ext$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  case $host_vendor in
+    sni)
+      shlibpath_overrides_runpath=no
+      need_lib_prefix=no
+      runpath_var=LD_RUN_PATH
+      ;;
+    siemens)
+      need_lib_prefix=no
+      ;;
+    motorola)
+      need_lib_prefix=no
+      need_version=no
+      shlibpath_overrides_runpath=no
+      sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib'
+      ;;
+  esac
+  ;;
+
+sysv4*MP*)
+  if test -d /usr/nec; then
+    version_type=linux # correct to gnu/linux during the next big refactor
+    library_names_spec='$libname$shared_ext.$versuffix $libname$shared_ext.$major $libname$shared_ext'
+    soname_spec='$libname$shared_ext.$major'
+    shlibpath_var=LD_LIBRARY_PATH
+  fi
+  ;;
+
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+  version_type=sco
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext $libname$shared_ext'
+  soname_spec='$libname$release$shared_ext$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  hardcode_into_libs=yes
+  if test yes = "$with_gnu_ld"; then
+    sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib'
+  else
+    sys_lib_search_path_spec='/usr/ccs/lib /usr/lib'
+    case $host_os in
+      sco3.2v5*)
+        sys_lib_search_path_spec="$sys_lib_search_path_spec /lib"
+	;;
+    esac
+  fi
+  sys_lib_dlsearch_path_spec='/usr/lib'
+  ;;
+
+tpf*)
+  # TPF is a cross-target only.  Preferred cross-host = GNU/Linux.
+  version_type=linux # correct to gnu/linux during the next big refactor
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  ;;
+
+uts4*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+  soname_spec='$libname$release$shared_ext$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+*)
+  dynamic_linker=no
+  ;;
+esac
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5
+$as_echo "$dynamic_linker" >&6; }
+test no = "$dynamic_linker" && can_build_shared=no
+
+variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
+if test yes = "$GCC"; then
+  variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
+fi
+
+if test set = "${lt_cv_sys_lib_search_path_spec+set}"; then
+  sys_lib_search_path_spec=$lt_cv_sys_lib_search_path_spec
+fi
+
+if test set = "${lt_cv_sys_lib_dlsearch_path_spec+set}"; then
+  sys_lib_dlsearch_path_spec=$lt_cv_sys_lib_dlsearch_path_spec
+fi
+
+# remember unaugmented sys_lib_dlsearch_path content for libtool script decls...
+configure_time_dlsearch_path=$sys_lib_dlsearch_path_spec
+
+# ... but it needs LT_SYS_LIBRARY_PATH munging for other configure-time code
+func_munge_path_list sys_lib_dlsearch_path_spec "$LT_SYS_LIBRARY_PATH"
+
+# to be used as default LT_SYS_LIBRARY_PATH value in generated libtool
+configure_time_lt_sys_library_path=$LT_SYS_LIBRARY_PATH
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5
+$as_echo_n "checking how to hardcode library paths into programs... " >&6; }
+hardcode_action=
+if test -n "$hardcode_libdir_flag_spec" ||
+   test -n "$runpath_var" ||
+   test yes = "$hardcode_automatic"; then
+
+  # We can hardcode non-existent directories.
+  if test no != "$hardcode_direct" &&
+     # If the only mechanism to avoid hardcoding is shlibpath_var, we
+     # have to relink, otherwise we might link with an installed library
+     # when we should be linking with a yet-to-be-installed one
+     ## test no != "$_LT_TAGVAR(hardcode_shlibpath_var, )" &&
+     test no != "$hardcode_minus_L"; then
+    # Linking always hardcodes the temporary library directory.
+    hardcode_action=relink
+  else
+    # We can link without hardcoding, and we can hardcode nonexisting dirs.
+    hardcode_action=immediate
+  fi
+else
+  # We cannot hardcode anything, or else we can only hardcode existing
+  # directories.
+  hardcode_action=unsupported
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action" >&5
+$as_echo "$hardcode_action" >&6; }
+
+if test relink = "$hardcode_action" ||
+   test yes = "$inherit_rpath"; then
+  # Fast installation is not supported
+  enable_fast_install=no
+elif test yes = "$shlibpath_overrides_runpath" ||
+     test no = "$enable_shared"; then
+  # Fast installation is not necessary
+  enable_fast_install=needless
+fi
+
+
+
+
+
+
+  if test yes != "$enable_dlopen"; then
+  enable_dlopen=unknown
+  enable_dlopen_self=unknown
+  enable_dlopen_self_static=unknown
+else
+  lt_cv_dlopen=no
+  lt_cv_dlopen_libs=
+
+  case $host_os in
+  beos*)
+    lt_cv_dlopen=load_add_on
+    lt_cv_dlopen_libs=
+    lt_cv_dlopen_self=yes
+    ;;
+
+  mingw* | pw32* | cegcc*)
+    lt_cv_dlopen=LoadLibrary
+    lt_cv_dlopen_libs=
+    ;;
+
+  cygwin*)
+    lt_cv_dlopen=dlopen
+    lt_cv_dlopen_libs=
+    ;;
+
+  darwin*)
+    # if libdl is installed we need to link against it
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5
+$as_echo_n "checking for dlopen in -ldl... " >&6; }
+if ${ac_cv_lib_dl_dlopen+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldl  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dlopen ();
+int
+main ()
+{
+return dlopen ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_dl_dlopen=yes
+else
+  ac_cv_lib_dl_dlopen=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5
+$as_echo "$ac_cv_lib_dl_dlopen" >&6; }
+if test "x$ac_cv_lib_dl_dlopen" = xyes; then :
+  lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl
+else
+
+    lt_cv_dlopen=dyld
+    lt_cv_dlopen_libs=
+    lt_cv_dlopen_self=yes
+
+fi
+
+    ;;
+
+  tpf*)
+    # Don't try to run any link tests for TPF.  We know it's impossible
+    # because TPF is a cross-compiler, and we know how we open DSOs.
+    lt_cv_dlopen=dlopen
+    lt_cv_dlopen_libs=
+    lt_cv_dlopen_self=no
+    ;;
+
+  *)
+    ac_fn_c_check_func "$LINENO" "shl_load" "ac_cv_func_shl_load"
+if test "x$ac_cv_func_shl_load" = xyes; then :
+  lt_cv_dlopen=shl_load
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5
+$as_echo_n "checking for shl_load in -ldld... " >&6; }
+if ${ac_cv_lib_dld_shl_load+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldld  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char shl_load ();
+int
+main ()
+{
+return shl_load ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_dld_shl_load=yes
+else
+  ac_cv_lib_dld_shl_load=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5
+$as_echo "$ac_cv_lib_dld_shl_load" >&6; }
+if test "x$ac_cv_lib_dld_shl_load" = xyes; then :
+  lt_cv_dlopen=shl_load lt_cv_dlopen_libs=-ldld
+else
+  ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen"
+if test "x$ac_cv_func_dlopen" = xyes; then :
+  lt_cv_dlopen=dlopen
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5
+$as_echo_n "checking for dlopen in -ldl... " >&6; }
+if ${ac_cv_lib_dl_dlopen+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldl  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dlopen ();
+int
+main ()
+{
+return dlopen ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_dl_dlopen=yes
+else
+  ac_cv_lib_dl_dlopen=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5
+$as_echo "$ac_cv_lib_dl_dlopen" >&6; }
+if test "x$ac_cv_lib_dl_dlopen" = xyes; then :
+  lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -lsvld" >&5
+$as_echo_n "checking for dlopen in -lsvld... " >&6; }
+if ${ac_cv_lib_svld_dlopen+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lsvld  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dlopen ();
+int
+main ()
+{
+return dlopen ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_svld_dlopen=yes
+else
+  ac_cv_lib_svld_dlopen=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_svld_dlopen" >&5
+$as_echo "$ac_cv_lib_svld_dlopen" >&6; }
+if test "x$ac_cv_lib_svld_dlopen" = xyes; then :
+  lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-lsvld
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dld_link in -ldld" >&5
+$as_echo_n "checking for dld_link in -ldld... " >&6; }
+if ${ac_cv_lib_dld_dld_link+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldld  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dld_link ();
+int
+main ()
+{
+return dld_link ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_dld_dld_link=yes
+else
+  ac_cv_lib_dld_dld_link=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_dld_link" >&5
+$as_echo "$ac_cv_lib_dld_dld_link" >&6; }
+if test "x$ac_cv_lib_dld_dld_link" = xyes; then :
+  lt_cv_dlopen=dld_link lt_cv_dlopen_libs=-ldld
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+    ;;
+  esac
+
+  if test no = "$lt_cv_dlopen"; then
+    enable_dlopen=no
+  else
+    enable_dlopen=yes
+  fi
+
+  case $lt_cv_dlopen in
+  dlopen)
+    save_CPPFLAGS=$CPPFLAGS
+    test yes = "$ac_cv_header_dlfcn_h" && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H"
+
+    save_LDFLAGS=$LDFLAGS
+    wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\"
+
+    save_LIBS=$LIBS
+    LIBS="$lt_cv_dlopen_libs $LIBS"
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a program can dlopen itself" >&5
+$as_echo_n "checking whether a program can dlopen itself... " >&6; }
+if ${lt_cv_dlopen_self+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  	  if test yes = "$cross_compiling"; then :
+  lt_cv_dlopen_self=cross
+else
+  lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+  lt_status=$lt_dlunknown
+  cat > conftest.$ac_ext <<_LT_EOF
+#line $LINENO "configure"
+#include "confdefs.h"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+#  define LT_DLGLOBAL		RTLD_GLOBAL
+#else
+#  ifdef DL_GLOBAL
+#    define LT_DLGLOBAL		DL_GLOBAL
+#  else
+#    define LT_DLGLOBAL		0
+#  endif
+#endif
+
+/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
+   find out it does not work in some platform. */
+#ifndef LT_DLLAZY_OR_NOW
+#  ifdef RTLD_LAZY
+#    define LT_DLLAZY_OR_NOW		RTLD_LAZY
+#  else
+#    ifdef DL_LAZY
+#      define LT_DLLAZY_OR_NOW		DL_LAZY
+#    else
+#      ifdef RTLD_NOW
+#        define LT_DLLAZY_OR_NOW	RTLD_NOW
+#      else
+#        ifdef DL_NOW
+#          define LT_DLLAZY_OR_NOW	DL_NOW
+#        else
+#          define LT_DLLAZY_OR_NOW	0
+#        endif
+#      endif
+#    endif
+#  endif
+#endif
+
+/* When -fvisibility=hidden is used, assume the code has been annotated
+   correspondingly for the symbols needed.  */
+#if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))
+int fnord () __attribute__((visibility("default")));
+#endif
+
+int fnord () { return 42; }
+int main ()
+{
+  void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
+  int status = $lt_dlunknown;
+
+  if (self)
+    {
+      if (dlsym (self,"fnord"))       status = $lt_dlno_uscore;
+      else
+        {
+	  if (dlsym( self,"_fnord"))  status = $lt_dlneed_uscore;
+          else puts (dlerror ());
+	}
+      /* dlclose (self); */
+    }
+  else
+    puts (dlerror ());
+
+  return status;
+}
+_LT_EOF
+  if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && test -s "conftest$ac_exeext" 2>/dev/null; then
+    (./conftest; exit; ) >&5 2>/dev/null
+    lt_status=$?
+    case x$lt_status in
+      x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;;
+      x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;;
+      x$lt_dlunknown|x*) lt_cv_dlopen_self=no ;;
+    esac
+  else :
+    # compilation failed
+    lt_cv_dlopen_self=no
+  fi
+fi
+rm -fr conftest*
+
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self" >&5
+$as_echo "$lt_cv_dlopen_self" >&6; }
+
+    if test yes = "$lt_cv_dlopen_self"; then
+      wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\"
+      { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a statically linked program can dlopen itself" >&5
+$as_echo_n "checking whether a statically linked program can dlopen itself... " >&6; }
+if ${lt_cv_dlopen_self_static+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  	  if test yes = "$cross_compiling"; then :
+  lt_cv_dlopen_self_static=cross
+else
+  lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+  lt_status=$lt_dlunknown
+  cat > conftest.$ac_ext <<_LT_EOF
+#line $LINENO "configure"
+#include "confdefs.h"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+#  define LT_DLGLOBAL		RTLD_GLOBAL
+#else
+#  ifdef DL_GLOBAL
+#    define LT_DLGLOBAL		DL_GLOBAL
+#  else
+#    define LT_DLGLOBAL		0
+#  endif
+#endif
+
+/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
+   find out it does not work in some platform. */
+#ifndef LT_DLLAZY_OR_NOW
+#  ifdef RTLD_LAZY
+#    define LT_DLLAZY_OR_NOW		RTLD_LAZY
+#  else
+#    ifdef DL_LAZY
+#      define LT_DLLAZY_OR_NOW		DL_LAZY
+#    else
+#      ifdef RTLD_NOW
+#        define LT_DLLAZY_OR_NOW	RTLD_NOW
+#      else
+#        ifdef DL_NOW
+#          define LT_DLLAZY_OR_NOW	DL_NOW
+#        else
+#          define LT_DLLAZY_OR_NOW	0
+#        endif
+#      endif
+#    endif
+#  endif
+#endif
+
+/* When -fvisibility=hidden is used, assume the code has been annotated
+   correspondingly for the symbols needed.  */
+#if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))
+int fnord () __attribute__((visibility("default")));
+#endif
+
+int fnord () { return 42; }
+int main ()
+{
+  void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
+  int status = $lt_dlunknown;
+
+  if (self)
+    {
+      if (dlsym (self,"fnord"))       status = $lt_dlno_uscore;
+      else
+        {
+	  if (dlsym( self,"_fnord"))  status = $lt_dlneed_uscore;
+          else puts (dlerror ());
+	}
+      /* dlclose (self); */
+    }
+  else
+    puts (dlerror ());
+
+  return status;
+}
+_LT_EOF
+  if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && test -s "conftest$ac_exeext" 2>/dev/null; then
+    (./conftest; exit; ) >&5 2>/dev/null
+    lt_status=$?
+    case x$lt_status in
+      x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;;
+      x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;;
+      x$lt_dlunknown|x*) lt_cv_dlopen_self_static=no ;;
+    esac
+  else :
+    # compilation failed
+    lt_cv_dlopen_self_static=no
+  fi
+fi
+rm -fr conftest*
+
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self_static" >&5
+$as_echo "$lt_cv_dlopen_self_static" >&6; }
+    fi
+
+    CPPFLAGS=$save_CPPFLAGS
+    LDFLAGS=$save_LDFLAGS
+    LIBS=$save_LIBS
+    ;;
+  esac
+
+  case $lt_cv_dlopen_self in
+  yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;;
+  *) enable_dlopen_self=unknown ;;
+  esac
+
+  case $lt_cv_dlopen_self_static in
+  yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;;
+  *) enable_dlopen_self_static=unknown ;;
+  esac
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+striplib=
+old_striplib=
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stripping libraries is possible" >&5
+$as_echo_n "checking whether stripping libraries is possible... " >&6; }
+if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then
+  test -z "$old_striplib" && old_striplib="$STRIP --strip-debug"
+  test -z "$striplib" && striplib="$STRIP --strip-unneeded"
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+else
+# FIXME - insert some real tests, host_os isn't really good enough
+  case $host_os in
+  darwin*)
+    if test -n "$STRIP"; then
+      striplib="$STRIP -x"
+      old_striplib="$STRIP -S"
+      { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+    else
+      { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+    fi
+    ;;
+  *)
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+    ;;
+  esac
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+  # Report what library types will actually be built
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking if libtool supports shared libraries" >&5
+$as_echo_n "checking if libtool supports shared libraries... " >&6; }
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $can_build_shared" >&5
+$as_echo "$can_build_shared" >&6; }
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build shared libraries" >&5
+$as_echo_n "checking whether to build shared libraries... " >&6; }
+  test no = "$can_build_shared" && enable_shared=no
+
+  # On AIX, shared libraries and static libraries use the same namespace, and
+  # are all built from PIC.
+  case $host_os in
+  aix3*)
+    test yes = "$enable_shared" && enable_static=no
+    if test -n "$RANLIB"; then
+      archive_cmds="$archive_cmds~\$RANLIB \$lib"
+      postinstall_cmds='$RANLIB $lib'
+    fi
+    ;;
+
+  aix[4-9]*)
+    if test ia64 != "$host_cpu"; then
+      case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in
+      yes,aix,yes) ;;			# shared object as lib.so file only
+      yes,svr4,*) ;;			# shared object as lib.so archive member only
+      yes,*) enable_static=no ;;	# shared object in lib.a archive as well
+      esac
+    fi
+    ;;
+  esac
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_shared" >&5
+$as_echo "$enable_shared" >&6; }
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build static libraries" >&5
+$as_echo_n "checking whether to build static libraries... " >&6; }
+  # Make sure either enable_shared or enable_static is yes.
+  test yes = "$enable_shared" || enable_static=yes
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_static" >&5
+$as_echo "$enable_static" >&6; }
+
+
+
+
+fi
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+CC=$lt_save_CC
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+        ac_config_commands="$ac_config_commands libtool"
+
+
+
+
+# Only expand once:
+
+
+# By default we simply use the C compiler to build assembly code.
+
+test "${CCAS+set}" = set || CCAS=$CC
+test "${CCASFLAGS+set}" = set || CCASFLAGS=$CFLAGS
+
+
+
+depcc="$CCAS"   am_compiler_list=
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5
+$as_echo_n "checking dependency style of $depcc... " >&6; }
+if ${am_cv_CCAS_dependencies_compiler_type+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
+  # We make a subdir and do the tests there.  Otherwise we can end up
+  # making bogus files that we don't know about and never remove.  For
+  # instance it was reported that on HP-UX the gcc test will end up
+  # making a dummy file named 'D' -- because '-MD' means "put the output
+  # in D".
+  rm -rf conftest.dir
+  mkdir conftest.dir
+  # Copy depcomp to subdir because otherwise we won't find it if we're
+  # using a relative directory.
+  cp "$am_depcomp" conftest.dir
+  cd conftest.dir
+  # We will build objects and dependencies in a subdirectory because
+  # it helps to detect inapplicable dependency modes.  For instance
+  # both Tru64's cc and ICC support -MD to output dependencies as a
+  # side effect of compilation, but ICC will put the dependencies in
+  # the current directory while Tru64 will put them in the object
+  # directory.
+  mkdir sub
+
+  am_cv_CCAS_dependencies_compiler_type=none
+  if test "$am_compiler_list" = ""; then
+     am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp`
+  fi
+  am__universal=false
+
+
+  for depmode in $am_compiler_list; do
+    # Setup a source with many dependencies, because some compilers
+    # like to wrap large dependency lists on column 80 (with \), and
+    # we should not choose a depcomp mode which is confused by this.
+    #
+    # We need to recreate these files for each test, as the compiler may
+    # overwrite some of them when testing with obscure command lines.
+    # This happens at least with the AIX C compiler.
+    : > sub/conftest.c
+    for i in 1 2 3 4 5 6; do
+      echo '#include "conftst'$i'.h"' >> sub/conftest.c
+      # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with
+      # Solaris 10 /bin/sh.
+      echo '/* dummy */' > sub/conftst$i.h
+    done
+    echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
+
+    # We check with '-c' and '-o' for the sake of the "dashmstdout"
+    # mode.  It turns out that the SunPro C++ compiler does not properly
+    # handle '-M -o', and we need to detect this.  Also, some Intel
+    # versions had trouble with output in subdirs.
+    am__obj=sub/conftest.${OBJEXT-o}
+    am__minus_obj="-o $am__obj"
+    case $depmode in
+    gcc)
+      # This depmode causes a compiler race in universal mode.
+      test "$am__universal" = false || continue
+      ;;
+    nosideeffect)
+      # After this tag, mechanisms are not by side-effect, so they'll
+      # only be used when explicitly requested.
+      if test "x$enable_dependency_tracking" = xyes; then
+	continue
+      else
+	break
+      fi
+      ;;
+    msvc7 | msvc7msys | msvisualcpp | msvcmsys)
+      # This compiler won't grok '-c -o', but also, the minuso test has
+      # not run yet.  These depmodes are late enough in the game, and
+      # so weak that their functioning should not be impacted.
+      am__obj=conftest.${OBJEXT-o}
+      am__minus_obj=
+      ;;
+    none) break ;;
+    esac
+    if depmode=$depmode \
+       source=sub/conftest.c object=$am__obj \
+       depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
+       $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \
+         >/dev/null 2>conftest.err &&
+       grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 &&
+       grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
+       grep $am__obj sub/conftest.Po > /dev/null 2>&1 &&
+       ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
+      # icc doesn't choke on unknown options, it will just issue warnings
+      # or remarks (even with -Werror).  So we grep stderr for any message
+      # that says an option was ignored or not supported.
+      # When given -MP, icc 7.0 and 7.1 complain thusly:
+      #   icc: Command line warning: ignoring option '-M'; no argument required
+      # The diagnosis changed in icc 8.0:
+      #   icc: Command line remark: option '-MP' not supported
+      if (grep 'ignoring option' conftest.err ||
+          grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
+        am_cv_CCAS_dependencies_compiler_type=$depmode
+        break
+      fi
+    fi
+  done
+
+  cd ..
+  rm -rf conftest.dir
+else
+  am_cv_CCAS_dependencies_compiler_type=none
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CCAS_dependencies_compiler_type" >&5
+$as_echo "$am_cv_CCAS_dependencies_compiler_type" >&6; }
+CCASDEPMODE=depmode=$am_cv_CCAS_dependencies_compiler_type
+
+ if
+  test "x$enable_dependency_tracking" != xno \
+  && test "$am_cv_CCAS_dependencies_compiler_type" = gcc3; then
+  am__fastdepCCAS_TRUE=
+  am__fastdepCCAS_FALSE='#'
+else
+  am__fastdepCCAS_TRUE='#'
+  am__fastdepCCAS_FALSE=
+fi
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking zfs author" >&5
+$as_echo_n "checking zfs author... " >&6; }
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ZFS_META_AUTHOR" >&5
+$as_echo "$ZFS_META_AUTHOR" >&6; }
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking zfs license" >&5
+$as_echo_n "checking zfs license... " >&6; }
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ZFS_META_LICENSE" >&5
+$as_echo "$ZFS_META_LICENSE" >&6; }
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking linux distribution" >&5
+$as_echo_n "checking linux distribution... " >&6; }
+	if test -f /etc/toss-release ; then
+		VENDOR=toss ;
+	elif test -f /etc/fedora-release ; then
+		VENDOR=fedora ;
+	elif test -f /etc/redhat-release ; then
+		VENDOR=redhat ;
+	elif test -f /etc/gentoo-release ; then
+		VENDOR=gentoo ;
+	elif test -f /etc/arch-release ; then
+		VENDOR=arch ;
+	elif test -f /etc/SuSE-release ; then
+		VENDOR=sles ;
+	elif test -f /etc/slackware-version ; then
+		VENDOR=slackware ;
+	elif test -f /etc/lunar.release ; then
+		VENDOR=lunar ;
+	elif test -f /etc/lsb-release ; then
+		VENDOR=ubuntu ;
+	elif test -f /etc/debian_version ; then
+		VENDOR=debian ;
+	else
+		VENDOR= ;
+	fi
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $VENDOR" >&5
+$as_echo "$VENDOR" >&6; }
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking default package type" >&5
+$as_echo_n "checking default package type... " >&6; }
+	case "$VENDOR" in
+		toss)       DEFAULT_PACKAGE=rpm  ;;
+		redhat)     DEFAULT_PACKAGE=rpm  ;;
+		fedora)     DEFAULT_PACKAGE=rpm  ;;
+		gentoo)     DEFAULT_PACKAGE=tgz  ;;
+		arch)       DEFAULT_PACKAGE=tgz  ;;
+		sles)       DEFAULT_PACKAGE=rpm  ;;
+		slackware)  DEFAULT_PACKAGE=tgz  ;;
+		lunar)      DEFAULT_PACKAGE=tgz  ;;
+		ubuntu)     DEFAULT_PACKAGE=deb  ;;
+		debian)     DEFAULT_PACKAGE=deb  ;;
+		*)          DEFAULT_PACKAGE=rpm  ;;
+	esac
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $DEFAULT_PACKAGE" >&5
+$as_echo "$DEFAULT_PACKAGE" >&6; }
+
+
+	DEFAULT_INIT_DIR=$sysconfdir/init.d
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking default init directory" >&5
+$as_echo_n "checking default init directory... " >&6; }
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $DEFAULT_INIT_DIR" >&5
+$as_echo "$DEFAULT_INIT_DIR" >&6; }
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking default init script type" >&5
+$as_echo_n "checking default init script type... " >&6; }
+	case "$VENDOR" in
+		toss)       DEFAULT_INIT_SCRIPT=redhat ;;
+		redhat)     DEFAULT_INIT_SCRIPT=redhat ;;
+		fedora)     DEFAULT_INIT_SCRIPT=fedora ;;
+		gentoo)     DEFAULT_INIT_SCRIPT=gentoo ;;
+		arch)       DEFAULT_INIT_SCRIPT=lsb    ;;
+		sles)       DEFAULT_INIT_SCRIPT=lsb    ;;
+		slackware)  DEFAULT_INIT_SCRIPT=lsb    ;;
+		lunar)      DEFAULT_INIT_SCRIPT=lunar  ;;
+		ubuntu)     DEFAULT_INIT_SCRIPT=lsb    ;;
+		debian)     DEFAULT_INIT_SCRIPT=lsb    ;;
+		*)          DEFAULT_INIT_SCRIPT=lsb    ;;
+	esac
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $DEFAULT_INIT_SCRIPT" >&5
+$as_echo "$DEFAULT_INIT_SCRIPT" >&6; }
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking default init config direectory" >&5
+$as_echo_n "checking default init config direectory... " >&6; }
+	case "$VENDOR" in
+		gentoo)     DEFAULT_INITCONF_DIR=/etc/conf.d    ;;
+		toss)       DEFAULT_INITCONF_DIR=/etc/sysconfig ;;
+		redhat)     DEFAULT_INITCONF_DIR=/etc/sysconfig ;;
+		fedora)     DEFAULT_INITCONF_DIR=/etc/sysconfig ;;
+		sles)       DEFAULT_INITCONF_DIR=/etc/sysconfig ;;
+		ubuntu)     DEFAULT_INITCONF_DIR=/etc/default   ;;
+		debian)     DEFAULT_INITCONF_DIR=/etc/default   ;;
+		*)          DEFAULT_INITCONF_DIR=/etc/default   ;;
+	esac
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $DEFAULT_INITCONF_DIR" >&5
+$as_echo "$DEFAULT_INITCONF_DIR" >&6; }
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether initramfs-tools is available" >&5
+$as_echo_n "checking whether initramfs-tools is available... " >&6; }
+	if test -d /usr/share/initramfs-tools ; then
+		DEFINE_INITRAMFS='--define "_initramfs 1"'
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+	else
+		DEFINE_INITRAMFS=''
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+	fi
+
+
+
+	RPM=rpm
+	RPMBUILD=rpmbuild
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $RPM is available" >&5
+$as_echo_n "checking whether $RPM is available... " >&6; }
+	if tmp=$($RPM --version 2>/dev/null); then :
+
+		RPM_VERSION=$(echo $tmp | $AWK '/RPM/ { print $3 }')
+		HAVE_RPM=yes
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $HAVE_RPM ($RPM_VERSION)" >&5
+$as_echo "$HAVE_RPM ($RPM_VERSION)" >&6; }
+
+else
+
+		HAVE_RPM=no
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $HAVE_RPM" >&5
+$as_echo "$HAVE_RPM" >&6; }
+
+fi
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $RPMBUILD is available" >&5
+$as_echo_n "checking whether $RPMBUILD is available... " >&6; }
+	if tmp=$($RPMBUILD --version 2>/dev/null); then :
+
+		RPMBUILD_VERSION=$(echo $tmp | $AWK '/RPM/ { print $3 }')
+		HAVE_RPMBUILD=yes
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $HAVE_RPMBUILD ($RPMBUILD_VERSION)" >&5
+$as_echo "$HAVE_RPMBUILD ($RPMBUILD_VERSION)" >&6; }
+
+else
+
+		HAVE_RPMBUILD=no
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $HAVE_RPMBUILD" >&5
+$as_echo "$HAVE_RPMBUILD" >&6; }
+
+fi
+
+	RPM_DEFINE_COMMON='--define "$(DEBUG_ZFS) 1" --define "$(DEBUG_DMU_TX) 1"'
+	RPM_DEFINE_UTIL='--define "_dracutdir $(dracutdir)" --define "_udevdir $(udevdir)" --define "_udevruledir $(udevruledir)" --define "_initconfdir $(DEFAULT_INITCONF_DIR)" $(DEFINE_INITRAMFS)'
+	RPM_DEFINE_KMOD='--define "kernels $(LINUX_VERSION)" --define "require_spldir $(SPL)" --define "require_splobj $(SPL_OBJ)" --define "ksrc $(LINUX)" --define "kobj $(LINUX_OBJ)"'
+	RPM_DEFINE_DKMS=
+
+	SRPM_DEFINE_COMMON='--define "build_src_rpm 1"'
+	SRPM_DEFINE_UTIL=
+	SRPM_DEFINE_KMOD=
+	SRPM_DEFINE_DKMS=
+
+	RPM_SPEC_DIR="rpm/generic"
+
+# Check whether --with-spec was given.
+if test "${with_spec+set}" = set; then :
+  withval=$with_spec; RPM_SPEC_DIR="rpm/$withval"
+fi
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether spec files are available" >&5
+$as_echo_n "checking whether spec files are available... " >&6; }
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes ($RPM_SPEC_DIR/*.spec.in)" >&5
+$as_echo "yes ($RPM_SPEC_DIR/*.spec.in)" >&6; }
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+	DPKG=dpkg
+	DPKGBUILD=dpkg-buildpackage
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $DPKG is available" >&5
+$as_echo_n "checking whether $DPKG is available... " >&6; }
+	if tmp=$($DPKG --version 2>/dev/null); then :
+
+		DPKG_VERSION=$(echo $tmp | $AWK '/Debian/ { print $7 }')
+		HAVE_DPKG=yes
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $HAVE_DPKG ($DPKG_VERSION)" >&5
+$as_echo "$HAVE_DPKG ($DPKG_VERSION)" >&6; }
+
+else
+
+		HAVE_DPKG=no
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $HAVE_DPKG" >&5
+$as_echo "$HAVE_DPKG" >&6; }
+
+fi
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $DPKGBUILD is available" >&5
+$as_echo_n "checking whether $DPKGBUILD is available... " >&6; }
+	if tmp=$($DPKGBUILD --version 2>/dev/null); then :
+
+		DPKGBUILD_VERSION=$(echo $tmp | \
+		    $AWK '/Debian/ { print $4 }' | cut -f-4 -d'.')
+		HAVE_DPKGBUILD=yes
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $HAVE_DPKGBUILD ($DPKGBUILD_VERSION)" >&5
+$as_echo "$HAVE_DPKGBUILD ($DPKGBUILD_VERSION)" >&6; }
+
+else
+
+		HAVE_DPKGBUILD=no
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $HAVE_DPKGBUILD" >&5
+$as_echo "$HAVE_DPKGBUILD" >&6; }
+
+fi
+
+
+
+
+
+
+
+
+
+
+	ALIEN=alien
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $ALIEN is available" >&5
+$as_echo_n "checking whether $ALIEN is available... " >&6; }
+	if tmp=$($ALIEN --version 2>/dev/null); then :
+
+		ALIEN_VERSION=$(echo $tmp | $AWK '{ print $3 }')
+		HAVE_ALIEN=yes
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $HAVE_ALIEN ($ALIEN_VERSION)" >&5
+$as_echo "$HAVE_ALIEN ($ALIEN_VERSION)" >&6; }
+
+else
+
+		HAVE_ALIEN=no
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $HAVE_ALIEN" >&5
+$as_echo "$HAVE_ALIEN" >&6; }
+
+fi
+
+
+
+
+
+
+
+	TARGET_ASM_DIR=asm-generic
+
+
+	ZFS_CONFIG=all
+
+# Check whether --with-config was given.
+if test "${with_config+set}" = set; then :
+  withval=$with_config; ZFS_CONFIG="$withval"
+fi
+
+	# Check whether --enable-linux-builtin was given.
+if test "${enable_linux_builtin+set}" = set; then :
+  enableval=$enable_linux_builtin;
+else
+  enable_linux_builtin=no
+fi
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking zfs config" >&5
+$as_echo_n "checking zfs config... " >&6; }
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ZFS_CONFIG" >&5
+$as_echo "$ZFS_CONFIG" >&6; };
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for -Wno-unused-but-set-variable support" >&5
+$as_echo_n "checking for -Wno-unused-but-set-variable support... " >&6; }
+
+	saved_flags="$CFLAGS"
+	CFLAGS="$CFLAGS -Wunused-but-set-variable"
+
+	cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+		NO_UNUSED_BUT_SET_VARIABLE=-Wno-unused-but-set-variable
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+else
+
+		NO_UNUSED_BUT_SET_VARIABLE=
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+	CFLAGS="$saved_flags"
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for -Wno-bool-compare support" >&5
+$as_echo_n "checking for -Wno-bool-compare support... " >&6; }
+
+	saved_flags="$CFLAGS"
+	CFLAGS="$CFLAGS -Wbool-compare"
+
+	cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+		NO_BOOL_COMPARE=-Wno-bool-compare
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+else
+
+		NO_BOOL_COMPARE=
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+	CFLAGS="$saved_flags"
+
+
+
+
+	case "$ZFS_CONFIG" in
+		user)
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for dkms.conf file" >&5
+$as_echo_n "checking for dkms.conf file... " >&6; }
+        if test -e dkms.conf; then :
+
+		as_fn_error $? "
+	*** ZFS should not be manually built in the DKMS source tree.
+	*** Remove all ZFS packages before compiling the ZoL sources.
+	*** Running \"make install\" breaks ZFS packages." "$LINENO" 5
+
+else
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: not found" >&5
+$as_echo "not found" >&6; }
+
+fi
+
+
+
+# Check whether --with-mounthelperdir was given.
+if test "${with_mounthelperdir+set}" = set; then :
+  withval=$with_mounthelperdir; mounthelperdir=$withval
+else
+  mounthelperdir=/sbin
+fi
+
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for udev directories" >&5
+$as_echo_n "checking for udev directories... " >&6; }
+
+# Check whether --with-udevdir was given.
+if test "${with_udevdir+set}" = set; then :
+  withval=$with_udevdir; udevdir=$withval
+else
+  udevdir=check
+fi
+
+
+	if test "x$udevdir" = xcheck; then :
+
+		path1=/lib/udev
+		path2=/usr/lib/udev
+		default=$path2
+
+		if test -d "$path1"; then :
+  udevdir="$path1"
+else
+
+			if test -d "$path2"; then :
+  udevdir="$path2"
+else
+  udevdir="$default"
+fi
+
+fi
+
+fi
+
+
+# Check whether --with-udevruledir was given.
+if test "${with_udevruledir+set}" = set; then :
+  withval=$with_udevruledir; udevruledir=$withval
+else
+  udevruledir="${udevdir}/rules.d"
+fi
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $udevdir;$udevruledir" >&5
+$as_echo "$udevdir;$udevruledir" >&6; }
+
+
+	# Check whether --enable-systemd was given.
+if test "${enable_systemd+set}" = set; then :
+  enableval=$enable_systemd;
+else
+  enable_systemd=yes
+fi
+
+
+
+# Check whether --with-systemdunitdir was given.
+if test "${with_systemdunitdir+set}" = set; then :
+  withval=$with_systemdunitdir; systemdunitdir=$withval
+else
+  systemdunitdir=/usr/lib/systemd/system
+fi
+
+
+
+# Check whether --with-systemdpresetdir was given.
+if test "${with_systemdpresetdir+set}" = set; then :
+  withval=$with_systemdpresetdir; systemdpresetdir=$withval
+else
+  systemdpresetdir=/usr/lib/systemd/system-preset
+fi
+
+
+
+# Check whether --with-systemdmodulesloaddir was given.
+if test "${with_systemdmodulesloaddir+set}" = set; then :
+  withval=$with_systemdmodulesloaddir; systemdmoduleloaddir=$withval
+else
+  systemdmodulesloaddir=/usr/lib/modules-load.d
+fi
+
+
+
+	if test "x$enable_systemd" = xyes; then :
+
+		ZFS_INIT_SYSTEMD=systemd
+		ZFS_MODULE_LOAD=modules-load.d
+		modulesloaddir=$systemdmodulesloaddir
+
+fi
+
+
+
+
+
+
+
+
+	# Check whether --enable-sysvinit was given.
+if test "${enable_sysvinit+set}" = set; then :
+  enableval=$enable_sysvinit;
+else
+  enable_sysvinit=yes
+fi
+
+
+	if test "x$enable_sysvinit" = xyes; then :
+  ZFS_INIT_SYSV=init.d
+fi
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for dracut directory" >&5
+$as_echo_n "checking for dracut directory... " >&6; }
+
+# Check whether --with-dracutdir was given.
+if test "${with_dracutdir+set}" = set; then :
+  withval=$with_dracutdir; dracutdir=$withval
+else
+  dracutdir=check
+fi
+
+
+	if test "x$dracutdir" = xcheck; then :
+
+		path1=/usr/share/dracut
+		path2=/usr/lib/dracut
+		default=$path2
+
+		if test -d "$path1"; then :
+  dracutdir="$path1"
+else
+
+			if test -d "$path2"; then :
+  dracutdir="$path2"
+else
+  dracutdir="$default"
+fi
+
+fi
+
+fi
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $dracutdir" >&5
+$as_echo "$dracutdir" >&6; }
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for target asm dir" >&5
+$as_echo_n "checking for target asm dir... " >&6; }
+	TARGET_ARCH=`echo ${target_cpu} | sed -e s/i.86/i386/`
+
+	case $TARGET_ARCH in
+	i386|x86_64)
+		TARGET_ASM_DIR=asm-${TARGET_ARCH}
+		;;
+	*)
+		TARGET_ASM_DIR=asm-generic
+		;;
+	esac
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $TARGET_ASM_DIR" >&5
+$as_echo "$TARGET_ASM_DIR" >&6; }
+
+
+	ZLIB=
+
+	ac_fn_c_check_header_mongrel "$LINENO" "zlib.h" "ac_cv_header_zlib_h" "$ac_includes_default"
+if test "x$ac_cv_header_zlib_h" = xyes; then :
+
+else
+  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "
+	*** zlib.h missing, zlib-devel package required
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for compress2 in -lz" >&5
+$as_echo_n "checking for compress2 in -lz... " >&6; }
+if ${ac_cv_lib_z_compress2+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lz  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char compress2 ();
+int
+main ()
+{
+return compress2 ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_z_compress2=yes
+else
+  ac_cv_lib_z_compress2=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_z_compress2" >&5
+$as_echo "$ac_cv_lib_z_compress2" >&6; }
+if test "x$ac_cv_lib_z_compress2" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBZ 1
+_ACEOF
+
+  LIBS="-lz $LIBS"
+
+else
+  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "
+	*** compress2() missing, zlib-devel package required
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for uncompress in -lz" >&5
+$as_echo_n "checking for uncompress in -lz... " >&6; }
+if ${ac_cv_lib_z_uncompress+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lz  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char uncompress ();
+int
+main ()
+{
+return uncompress ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_z_uncompress=yes
+else
+  ac_cv_lib_z_uncompress=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_z_uncompress" >&5
+$as_echo "$ac_cv_lib_z_uncompress" >&6; }
+if test "x$ac_cv_lib_z_uncompress" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBZ 1
+_ACEOF
+
+  LIBS="-lz $LIBS"
+
+else
+  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "
+	*** uncompress() missing, zlib-devel package required
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for crc32 in -lz" >&5
+$as_echo_n "checking for crc32 in -lz... " >&6; }
+if ${ac_cv_lib_z_crc32+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lz  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char crc32 ();
+int
+main ()
+{
+return crc32 ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_z_crc32=yes
+else
+  ac_cv_lib_z_crc32=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_z_crc32" >&5
+$as_echo "$ac_cv_lib_z_crc32" >&6; }
+if test "x$ac_cv_lib_z_crc32" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBZ 1
+_ACEOF
+
+  LIBS="-lz $LIBS"
+
+else
+  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "
+	*** crc32() missing, zlib-devel package required
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+
+
+	ZLIB="-lz"
+
+
+$as_echo "#define HAVE_ZLIB 1" >>confdefs.h
+
+
+
+	LIBUUID=
+
+	ac_fn_c_check_header_mongrel "$LINENO" "uuid/uuid.h" "ac_cv_header_uuid_uuid_h" "$ac_includes_default"
+if test "x$ac_cv_header_uuid_uuid_h" = xyes; then :
+
+else
+  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "
+	*** uuid/uuid.h missing, libuuid-devel package required
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for uuid_generate in -luuid" >&5
+$as_echo_n "checking for uuid_generate in -luuid... " >&6; }
+if ${ac_cv_lib_uuid_uuid_generate+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-luuid  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char uuid_generate ();
+int
+main ()
+{
+return uuid_generate ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_uuid_uuid_generate=yes
+else
+  ac_cv_lib_uuid_uuid_generate=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_uuid_uuid_generate" >&5
+$as_echo "$ac_cv_lib_uuid_uuid_generate" >&6; }
+if test "x$ac_cv_lib_uuid_uuid_generate" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBUUID 1
+_ACEOF
+
+  LIBS="-luuid $LIBS"
+
+else
+  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "
+	*** uuid_generate() missing, libuuid-devel package required
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for uuid_is_null in -luuid" >&5
+$as_echo_n "checking for uuid_is_null in -luuid... " >&6; }
+if ${ac_cv_lib_uuid_uuid_is_null+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-luuid  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char uuid_is_null ();
+int
+main ()
+{
+return uuid_is_null ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_uuid_uuid_is_null=yes
+else
+  ac_cv_lib_uuid_uuid_is_null=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_uuid_uuid_is_null" >&5
+$as_echo "$ac_cv_lib_uuid_uuid_is_null" >&6; }
+if test "x$ac_cv_lib_uuid_uuid_is_null" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBUUID 1
+_ACEOF
+
+  LIBS="-luuid $LIBS"
+
+else
+  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "
+	*** uuid_is_null() missing, libuuid-devel package required
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+
+
+	LIBUUID="-luuid"
+
+
+$as_echo "#define HAVE_LIBUUID 1" >>confdefs.h
+
+
+
+
+# Check whether --with-blkid was given.
+if test "${with_blkid+set}" = set; then :
+  withval=$with_blkid;
+else
+  with_blkid=check
+fi
+
+
+	LIBBLKID=
+	if test "x$with_blkid" = xyes; then :
+
+		LIBBLKID="-lblkid"
+
+
+$as_echo "#define HAVE_LIBBLKID 1" >>confdefs.h
+
+
+fi
+
+	if test "x$with_blkid" = xcheck; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for blkid_get_cache in -lblkid" >&5
+$as_echo_n "checking for blkid_get_cache in -lblkid... " >&6; }
+if ${ac_cv_lib_blkid_blkid_get_cache+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lblkid  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char blkid_get_cache ();
+int
+main ()
+{
+return blkid_get_cache ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_blkid_blkid_get_cache=yes
+else
+  ac_cv_lib_blkid_blkid_get_cache=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_blkid_blkid_get_cache" >&5
+$as_echo "$ac_cv_lib_blkid_blkid_get_cache" >&6; }
+if test "x$ac_cv_lib_blkid_blkid_get_cache" = xyes; then :
+
+			{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for blkid zfs support" >&5
+$as_echo_n "checking for blkid zfs support... " >&6; }
+
+			ZFS_DEV=`mktemp`
+			truncate -s 64M $ZFS_DEV
+			echo -en "\x0c\xb1\xba\0\0\0\0\0" | \
+				dd of=$ZFS_DEV bs=1k count=8 \
+				seek=128 conv=notrunc &>/dev/null \
+				>/dev/null 2>/dev/null
+			echo -en "\x0c\xb1\xba\0\0\0\0\0" | \
+				dd of=$ZFS_DEV bs=1k count=8 \
+				seek=132 conv=notrunc &>/dev/null \
+				>/dev/null 2>/dev/null
+			echo -en "\x0c\xb1\xba\0\0\0\0\0" | \
+				dd of=$ZFS_DEV bs=1k count=8 \
+				seek=136 conv=notrunc &>/dev/null \
+				>/dev/null 2>/dev/null
+			echo -en "\x0c\xb1\xba\0\0\0\0\0" | \
+				dd of=$ZFS_DEV bs=1k count=8 \
+				seek=140 conv=notrunc &>/dev/null \
+				>/dev/null 2>/dev/null
+
+			saved_LIBS="$LIBS"
+			LIBS="-lblkid"
+
+			if test "$cross_compiling" = yes; then :
+  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot run test program while cross compiling
+See \`config.log' for more details" "$LINENO" 5; }
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+				#include <stdio.h>
+				#include <stdlib.h>
+				#include <blkid/blkid.h>
+
+int
+main ()
+{
+
+				blkid_cache cache;
+				char *value;
+
+			        if (blkid_get_cache(&cache, NULL) < 0)
+					return 1;
+
+				value = blkid_get_tag_value(cache, "TYPE",
+				                            "$ZFS_DEV");
+				if (!value) {
+					blkid_put_cache(cache);
+					return 2;
+				}
+
+				if (strcmp(value, "zfs_member")) {
+					free(value);
+					blkid_put_cache(cache);
+					return 0;
+				}
+
+				free(value);
+				blkid_put_cache(cache);
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+
+				rm -f $ZFS_DEV
+				{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+				LIBBLKID="-lblkid"
+
+
+$as_echo "#define HAVE_LIBBLKID 1" >>confdefs.h
+
+
+else
+
+				rm -f $ZFS_DEV
+				{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+				if test "x$with_blkid" != xcheck; then :
+  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "--with-blkid given but unavailable
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+
+			LIBS="$saved_LIBS"
+
+else
+
+			if test "x$with_blkid" != xcheck; then :
+  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "--with-blkid given but unavailable
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+
+
+fi
+
+
+fi
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for -Wframe-larger-than=<size> support" >&5
+$as_echo_n "checking for -Wframe-larger-than=<size> support... " >&6; }
+
+	saved_flags="$CFLAGS"
+	CFLAGS="$CFLAGS -Wframe-larger-than=1024"
+
+	cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+		FRAME_LARGER_THAN=-Wframe-larger-than=1024
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+else
+
+		FRAME_LARGER_THAN=
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+	CFLAGS="$saved_flags"
+
+
+
+	if test "x$runstatedir" = x; then
+		runstatedir='${localstatedir}/run'
+
+	fi
+
+	for ac_func in mlockall
+do :
+  ac_fn_c_check_func "$LINENO" "mlockall" "ac_cv_func_mlockall"
+if test "x$ac_cv_func_mlockall" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_MLOCKALL 1
+_ACEOF
+
+fi
+done
+
+   ;;
+		kernel)
+
+
+# Check whether --with-linux was given.
+if test "${with_linux+set}" = set; then :
+  withval=$with_linux; kernelsrc="$withval"
+fi
+
+
+
+# Check whether --with-linux-obj was given.
+if test "${with_linux_obj+set}" = set; then :
+  withval=$with_linux_obj; kernelbuild="$withval"
+fi
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking kernel source directory" >&5
+$as_echo_n "checking kernel source directory... " >&6; }
+	if test -z "$kernelsrc"; then :
+
+		if test -e "/lib/modules/$(uname -r)/source"; then :
+
+			headersdir="/lib/modules/$(uname -r)/source"
+			sourcelink=$(readlink -f "$headersdir")
+
+elif test -e "/lib/modules/$(uname -r)/build"; then :
+
+			headersdir="/lib/modules/$(uname -r)/build"
+			sourcelink=$(readlink -f "$headersdir")
+
+else
+
+			sourcelink=$(ls -1d /usr/src/kernels/* \
+			             /usr/src/linux-* \
+			             2>/dev/null | grep -v obj | tail -1)
+
+fi
+
+		if test -n "$sourcelink" && test -e ${sourcelink}; then :
+
+			kernelsrc=`readlink -f ${sourcelink}`
+
+else
+
+			kernelsrc="Not found"
+
+fi
+
+else
+
+		if test "$kernelsrc" = "NONE"; then :
+
+			kernsrcver=NONE
+
+fi
+
+fi
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $kernelsrc" >&5
+$as_echo "$kernelsrc" >&6; }
+	if test ! -d "$kernelsrc"; then :
+
+		as_fn_error $? "
+	*** Please make sure the kernel devel package for your distribution
+	*** is installed and then try again.  If that fails, you can specify the
+	*** location of the kernel source with the '--with-linux=PATH' option." "$LINENO" 5
+
+fi
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking kernel build directory" >&5
+$as_echo_n "checking kernel build directory... " >&6; }
+	if test -z "$kernelbuild"; then :
+
+		if test -e "/lib/modules/$(uname -r)/build"; then :
+
+			kernelbuild=`readlink -f /lib/modules/$(uname -r)/build`
+
+elif test -d ${kernelsrc}-obj/${target_cpu}/${target_cpu}; then :
+
+			kernelbuild=${kernelsrc}-obj/${target_cpu}/${target_cpu}
+
+elif test -d ${kernelsrc}-obj/${target_cpu}/default; then :
+
+			kernelbuild=${kernelsrc}-obj/${target_cpu}/default
+
+elif test -d `dirname ${kernelsrc}`/build-${target_cpu}; then :
+
+			kernelbuild=`dirname ${kernelsrc}`/build-${target_cpu}
+
+else
+
+			kernelbuild=${kernelsrc}
+
+fi
+
+fi
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $kernelbuild" >&5
+$as_echo "$kernelbuild" >&6; }
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking kernel source version" >&5
+$as_echo_n "checking kernel source version... " >&6; }
+	utsrelease1=$kernelbuild/include/linux/version.h
+	utsrelease2=$kernelbuild/include/linux/utsrelease.h
+	utsrelease3=$kernelbuild/include/generated/utsrelease.h
+	if test -r $utsrelease1 && fgrep -q UTS_RELEASE $utsrelease1; then :
+
+		utsrelease=linux/version.h
+
+elif test -r $utsrelease2 && fgrep -q UTS_RELEASE $utsrelease2; then :
+
+		utsrelease=linux/utsrelease.h
+
+elif test -r $utsrelease3 && fgrep -q UTS_RELEASE $utsrelease3; then :
+
+		utsrelease=generated/utsrelease.h
+
+fi
+
+	if test "$utsrelease"; then :
+
+		kernsrcver=`(echo "#include <$utsrelease>";
+		             echo "kernsrcver=UTS_RELEASE") |
+		             cpp -I $kernelbuild/include |
+		             grep "^kernsrcver=" | cut -d \" -f 2`
+
+		if test -z "$kernsrcver"; then :
+
+			{ $as_echo "$as_me:${as_lineno-$LINENO}: result: Not found" >&5
+$as_echo "Not found" >&6; }
+			as_fn_error $? "*** Cannot determine kernel version." "$LINENO" 5
+
+fi
+
+else
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: Not found" >&5
+$as_echo "Not found" >&6; }
+		if test "x$enable_linux_builtin" != xyes; then
+			as_fn_error $? "*** Cannot find UTS_RELEASE definition." "$LINENO" 5
+		else
+			as_fn_error $? "
+	*** Cannot find UTS_RELEASE definition.
+	*** Please run 'make prepare' inside the kernel source tree." "$LINENO" 5
+		fi
+
+fi
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $kernsrcver" >&5
+$as_echo "$kernsrcver" >&6; }
+
+	LINUX=${kernelsrc}
+	LINUX_OBJ=${kernelbuild}
+	LINUX_VERSION=${kernsrcver}
+
+
+
+
+
+
+	modpost=$LINUX/scripts/Makefile.modpost
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking kernel file name for module symbols" >&5
+$as_echo_n "checking kernel file name for module symbols... " >&6; }
+	if test "x$enable_linux_builtin" != xyes -a -f "$modpost"; then :
+
+		if grep -q Modules.symvers $modpost; then :
+
+			LINUX_SYMBOLS=Modules.symvers
+
+else
+
+			LINUX_SYMBOLS=Module.symvers
+
+fi
+
+		if test ! -f "$LINUX_OBJ/$LINUX_SYMBOLS"; then :
+
+			as_fn_error $? "
+	*** Please make sure the kernel devel package for your distribution
+	*** is installed.  If you are building with a custom kernel, make sure the
+	*** kernel is configured, built, and the '--with-linux=PATH' configure
+	*** option refers to the location of the kernel source." "$LINENO" 5
+
+fi
+
+else
+
+		LINUX_SYMBOLS=NONE
+
+fi
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $LINUX_SYMBOLS" >&5
+$as_echo "$LINUX_SYMBOLS" >&6; }
+
+
+
+
+
+# Check whether --with-spl was given.
+if test "${with_spl+set}" = set; then :
+  withval=$with_spl; splsrc="$withval"
+fi
+
+
+
+# Check whether --with-spl-obj was given.
+if test "${with_spl_obj+set}" = set; then :
+  withval=$with_spl_obj; splbuild="$withval"
+fi
+
+
+
+# Check whether --with-spl-timeout was given.
+if test "${with_spl_timeout+set}" = set; then :
+  withval=$with_spl_timeout; timeout="$withval"
+else
+  timeout=0
+fi
+
+
+					splsrc0="/var/lib/dkms/spl/${VERSION}/build"
+	splsrc1="/usr/local/src/spl-${VERSION}/${LINUX_VERSION}"
+	splsrc2="/usr/local/src/spl-${VERSION}"
+	splsrc3="/usr/src/spl-${VERSION}/${LINUX_VERSION}"
+	splsrc4="/usr/src/spl-${VERSION}"
+	splsrc5="../spl/"
+	splsrc6="$LINUX"
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking spl source directory" >&5
+$as_echo_n "checking spl source directory... " >&6; }
+	if test -z "${splsrc}"; then :
+
+		if  test -e "${splsrc0}/spl.release.in"; then :
+
+			splsrc=${splsrc0}
+
+elif  test -e "${splsrc1}/spl.release.in"; then :
+
+			splsrc=${splsrc1}
+
+elif  test -e "${splsrc2}/spl.release.in"; then :
+
+			splsrc=${splsrc2}
+
+elif  test -e "${splsrc3}/spl.release.in"; then :
+
+			splsrc=$(readlink -f "${splsrc3}")
+
+elif  test -e "${splsrc4}/spl.release.in" ; then :
+
+			splsrc=${splsrc4}
+
+elif  test -e "${splsrc5}/spl.release.in"; then :
+
+			splsrc=$(readlink -f "${splsrc5}")
+
+elif  test -e "${splsrc6}/spl.release.in" ; then :
+
+			splsrc=${splsrc6}
+
+else
+
+			splsrc="Not found"
+
+fi
+
+else
+
+		if test "$splsrc" = "NONE"; then :
+
+			splbuild=NONE
+			splsrcver=NONE
+
+fi
+
+fi
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $splsrc" >&5
+$as_echo "$splsrc" >&6; }
+	if  test ! -e "$splsrc/spl.release.in"; then :
+
+		as_fn_error $? "
+	*** Please make sure the kmod spl devel package for your distribution
+	*** is installed then try again.  If that fails you can specify the
+	*** location of the spl source with the '--with-spl=PATH' option." "$LINENO" 5
+
+fi
+
+													{ $as_echo "$as_me:${as_lineno-$LINENO}: checking spl build directory" >&5
+$as_echo_n "checking spl build directory... " >&6; }
+	while true; do
+		if test -z "$splbuild"; then :
+
+			if  test -e "${splsrc}/${LINUX_VERSION}/spl_config.h" ; then :
+
+				splbuild="${splsrc}/${LINUX_VERSION}"
+
+elif  test -e "${splsrc}/spl_config.h" ; then :
+
+				splbuild="${splsrc}"
+
+elif  find -L "${splsrc}" -name spl_config.h 2> /dev/null | grep -wq spl_config.h ; then :
+
+				splbuild=$(find -L "${splsrc}" -name spl_config.h | sed 's,/spl_config.h,,')
+
+else
+
+				splbuild="Not found"
+
+fi
+
+fi
+		if test -e "$splbuild/spl_config.h" -o $timeout -le 0; then :
+
+			break;
+
+else
+
+			sleep 1
+			timeout=$((timeout-1))
+
+fi
+	done
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $splbuild" >&5
+$as_echo "$splbuild" >&6; }
+	if  ! test -e "$splbuild/spl_config.h"; then :
+
+		as_fn_error $? "
+	*** Please make sure the kmod spl devel <kernel> package for your
+	*** distribution is installed then try again.  If that fails you
+	*** can specify the location of the spl objects with the
+	*** '--with-spl-obj=PATH' option." "$LINENO" 5
+
+fi
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking spl source version" >&5
+$as_echo_n "checking spl source version... " >&6; }
+	if test -r $splbuild/spl_config.h &&
+		fgrep -q SPL_META_VERSION $splbuild/spl_config.h; then :
+
+
+		splsrcver=`(echo "#include <spl_config.h>";
+		            echo "splsrcver=SPL_META_VERSION-SPL_META_RELEASE") |
+		            cpp -I $splbuild |
+		            grep "^splsrcver=" | tr -d \" | cut -d= -f2`
+
+fi
+
+	if test -z "$splsrcver"; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: Not found" >&5
+$as_echo "Not found" >&6; }
+		as_fn_error $? "
+	*** Cannot determine the version of the spl source.
+	*** Please prepare the spl source before running this script" "$LINENO" 5
+
+fi
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $splsrcver" >&5
+$as_echo "$splsrcver" >&6; }
+
+	SPL=${splsrc}
+	SPL_OBJ=${splbuild}
+	SPL_VERSION=${splsrcver}
+
+
+
+
+
+														{ $as_echo "$as_me:${as_lineno-$LINENO}: checking spl file name for module symbols" >&5
+$as_echo_n "checking spl file name for module symbols... " >&6; }
+	SPL_SYMBOLS=NONE
+
+	while true; do
+		if test -r $SPL_OBJ/Module.symvers; then :
+
+			SPL_SYMBOLS=Module.symvers
+
+elif test -r $SPL_OBJ/Modules.symvers; then :
+
+			SPL_SYMBOLS=Modules.symvers
+
+elif test -r $SPL_OBJ/module/Module.symvers; then :
+
+			SPL_SYMBOLS=Module.symvers
+
+elif test -r $SPL_OBJ/module/Modules.symvers; then :
+
+			SPL_SYMBOLS=Modules.symvers
+
+fi
+
+		if test $SPL_SYMBOLS != NONE -o $timeout -le 0; then :
+
+			break;
+
+else
+
+			sleep 1
+			timeout=$((timeout-1))
+
+fi
+	done
+
+	if test "$SPL_SYMBOLS" = NONE; then :
+
+		SPL_SYMBOLS=$LINUX_SYMBOLS
+
+fi
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $SPL_SYMBOLS" >&5
+$as_echo "$SPL_SYMBOLS" >&6; }
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether modules can be built" >&5
+$as_echo_n "checking whether modules can be built... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+int
+main (void)
+{
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+		if test "x$enable_linux_builtin" != xyes; then
+			as_fn_error $? "*** Unable to build an empty module." "$LINENO" 5
+		else
+			as_fn_error $? "
+	*** Unable to build an empty module.
+	*** Please run 'make scripts' inside the kernel source tree." "$LINENO" 5
+		fi
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+	if test "x$cross_compiling" != xyes; then :
+
+		if test "$cross_compiling" = yes; then :
+  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot run test program while cross compiling
+See \`config.log' for more details" "$LINENO" 5; }
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+
+				#include "$LINUX/include/linux/license.h"
+
+int
+main ()
+{
+
+				return !license_is_gpl_compatible("$ZFS_META_LICENSE");
+
+  ;
+  return 0;
+}
+
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+
+
+$as_echo "#define ZFS_IS_GPL_COMPATIBLE 1" >>confdefs.h
+
+
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+
+fi
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether Linux was built with CONFIG_DEBUG_LOCK_ALLOC" >&5
+$as_echo_n "checking whether Linux was built with CONFIG_DEBUG_LOCK_ALLOC... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/module.h>
+
+int
+main (void)
+{
+
+		#ifndef CONFIG_DEBUG_LOCK_ALLOC
+		#error CONFIG_DEBUG_LOCK_ALLOC not #defined
+		#endif
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether mutex_lock() is GPL-only" >&5
+$as_echo_n "checking whether mutex_lock() is GPL-only... " >&6; }
+		tmp_flags="$EXTRA_KCFLAGS"
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+			#include <linux/module.h>
+			#include <linux/mutex.h>
+
+			MODULE_LICENSE("$ZFS_META_LICENSE");
+
+int
+main (void)
+{
+
+			struct mutex lock;
+
+			mutex_init(&lock);
+			mutex_lock(&lock);
+			mutex_unlock(&lock);
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+			{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+			{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+			as_fn_error $? "
+	*** Kernel built with CONFIG_DEBUG_LOCK_ALLOC which is incompatible
+	*** with the CDDL license and will prevent the module linking stage
+	*** from succeeding.  You must rebuild your kernel without this
+	*** option enabled." "$LINENO" 5
+
+
+
+fi
+	rm -Rf build
+
+
+		EXTRA_KCFLAGS="$tmp_flags"
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+
+
+	tmp_flags="$EXTRA_KCFLAGS"
+	EXTRA_KCFLAGS="-I\$(src)"
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether DECLARE_EVENT_CLASS() is available" >&5
+$as_echo_n "checking whether DECLARE_EVENT_CLASS() is available... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/module.h>
+		MODULE_LICENSE(ZFS_META_LICENSE);
+
+		#define CREATE_TRACE_POINTS
+		#include "conftest.h"
+
+int
+main (void)
+{
+
+		trace_zfs_autoconf_event_one(1UL);
+		trace_zfs_autoconf_event_two(2UL);
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+		#if !defined(_CONFTEST_H) || defined(TRACE_HEADER_MULTI_READ)
+		#define _CONFTEST_H
+
+		#undef  TRACE_SYSTEM
+		#define TRACE_SYSTEM zfs
+		#include <linux/tracepoint.h>
+
+		DECLARE_EVENT_CLASS(zfs_autoconf_event_class,
+			TP_PROTO(unsigned long i),
+			TP_ARGS(i),
+			TP_STRUCT__entry(
+				__field(unsigned long, i)
+			),
+			TP_fast_assign(
+				__entry->i = i;
+			),
+			TP_printk("i = %lu", __entry->i)
+		);
+
+		#define DEFINE_AUTOCONF_EVENT(name) \
+		DEFINE_EVENT(zfs_autoconf_event_class, name, \
+			TP_PROTO(unsigned long i), \
+			TP_ARGS(i))
+		DEFINE_AUTOCONF_EVENT(zfs_autoconf_event_one);
+		DEFINE_AUTOCONF_EVENT(zfs_autoconf_event_two);
+
+		#endif /* _CONFTEST_H */
+
+		#undef  TRACE_INCLUDE_PATH
+		#define TRACE_INCLUDE_PATH .
+		#define TRACE_INCLUDE_FILE conftest
+		#include <trace/define_trace.h>
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_DECLARE_EVENT_CLASS 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+	EXTRA_KCFLAGS="$tmp_flags"
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether current->bio_tail exists" >&5
+$as_echo_n "checking whether current->bio_tail exists... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/sched.h>
+
+int
+main (void)
+{
+
+		current->bio_tail = (struct bio **) NULL;
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_CURRENT_BIO_TAIL 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether current->bio_list exists" >&5
+$as_echo_n "checking whether current->bio_list exists... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+			#include <linux/sched.h>
+
+int
+main (void)
+{
+
+			current->bio_list = (struct bio_list *) NULL;
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+			{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_CURRENT_BIO_LIST 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+			as_fn_error $? "no - Please file a bug report at
+			    https://github.com/zfsonlinux/zfs/issues/new" "$LINENO" 5
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking block device operation prototypes" >&5
+$as_echo_n "checking block device operation prototypes... " >&6; }
+	tmp_flags="$EXTRA_KCFLAGS"
+	EXTRA_KCFLAGS="${NO_UNUSED_BUT_SET_VARIABLE}"
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/blkdev.h>
+
+		int blk_open(struct block_device *bdev, fmode_t mode)
+		    { return 0; }
+		int blk_ioctl(struct block_device *bdev, fmode_t mode,
+		    unsigned x, unsigned long y) { return 0; }
+		int blk_compat_ioctl(struct block_device * bdev, fmode_t mode,
+		    unsigned x, unsigned long y) { return 0; }
+
+		static const struct block_device_operations
+		    bops __attribute__ ((unused)) = {
+			.open		= blk_open,
+			.release	= NULL,
+			.ioctl		= blk_ioctl,
+			.compat_ioctl	= blk_compat_ioctl,
+		};
+
+int
+main (void)
+{
+
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: struct block_device" >&5
+$as_echo "struct block_device" >&6; }
+
+$as_echo "#define HAVE_BDEV_BLOCK_DEVICE_OPERATIONS 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: struct inode" >&5
+$as_echo "struct inode" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+	EXTRA_KCFLAGS="$tmp_flags"
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether block_device_operations.release is void" >&5
+$as_echo_n "checking whether block_device_operations.release is void... " >&6; }
+	tmp_flags="$EXTRA_KCFLAGS"
+	EXTRA_KCFLAGS="${NO_UNUSED_BUT_SET_VARIABLE}"
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/blkdev.h>
+
+		void blk_release(struct gendisk *g, fmode_t mode) { return; }
+
+		static const struct block_device_operations
+		    bops __attribute__ ((unused)) = {
+			.open		= NULL,
+			.release	= blk_release,
+			.ioctl		= NULL,
+			.compat_ioctl	= NULL,
+		};
+
+int
+main (void)
+{
+
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: void" >&5
+$as_echo "void" >&6; }
+
+$as_echo "#define HAVE_BLOCK_DEVICE_OPERATIONS_RELEASE_VOID 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: int" >&5
+$as_echo "int" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+	EXTRA_KCFLAGS="$tmp_flags"
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether kernel defines fmode_t" >&5
+$as_echo_n "checking whether kernel defines fmode_t... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/types.h>
+
+int
+main (void)
+{
+
+		fmode_t *ptr __attribute__ ((unused));
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_FMODE_T 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether kernel defines KOBJ_NAME_LEN" >&5
+$as_echo_n "checking whether kernel defines KOBJ_NAME_LEN... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/kobject.h>
+
+int
+main (void)
+{
+
+		int val __attribute__ ((unused));
+		val = KOBJ_NAME_LEN;
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_KOBJ_NAME_LEN 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether blkdev_get() wants 3 args" >&5
+$as_echo_n "checking whether blkdev_get() wants 3 args... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/fs.h>
+
+int
+main (void)
+{
+
+		struct block_device *bdev = NULL;
+		(void) blkdev_get(bdev, 0, NULL);
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_3ARG_BLKDEV_GET 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether blkdev_get_by_path() is available" >&5
+$as_echo_n "checking whether blkdev_get_by_path() is available... " >&6; }
+
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/fs.h>
+
+int
+main (void)
+{
+
+		blkdev_get_by_path(NULL, 0, NULL);
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+  rc=0
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+ rc=1
+
+
+fi
+	rm -Rf build
+
+
+	if test $rc -ne 0; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+	else
+		if test "x$enable_linux_builtin" != xyes; then
+
+	grep -q -E '[[:space:]]blkdev_get_by_path[[:space:]]' \
+		$LINUX_OBJ/$LINUX_SYMBOLS 2>/dev/null
+	rc=$?
+	if test $rc -ne 0; then
+		export=0
+		for file in fs/block_dev.c; do
+			grep -q -E "EXPORT_SYMBOL.*(blkdev_get_by_path)" \
+				"$LINUX/$file" 2>/dev/null
+			rc=$?
+			if test $rc -eq 0; then
+				export=1
+				break;
+			fi
+		done
+		if test $export -eq 0; then :
+			rc=1
+		else :
+			rc=0
+		fi
+	else :
+		rc=0
+	fi
+
+		fi
+		if test $rc -ne 0; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+		else :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_BLKDEV_GET_BY_PATH 1" >>confdefs.h
+
+
+		fi
+	fi
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether open_bdev_exclusive() is available" >&5
+$as_echo_n "checking whether open_bdev_exclusive() is available... " >&6; }
+
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/fs.h>
+
+int
+main (void)
+{
+
+		open_bdev_exclusive(NULL, 0, NULL);
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+  rc=0
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+ rc=1
+
+
+fi
+	rm -Rf build
+
+
+	if test $rc -ne 0; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+	else
+		if test "x$enable_linux_builtin" != xyes; then
+
+	grep -q -E '[[:space:]]open_bdev_exclusive[[:space:]]' \
+		$LINUX_OBJ/$LINUX_SYMBOLS 2>/dev/null
+	rc=$?
+	if test $rc -ne 0; then
+		export=0
+		for file in fs/block_dev.c; do
+			grep -q -E "EXPORT_SYMBOL.*(open_bdev_exclusive)" \
+				"$LINUX/$file" 2>/dev/null
+			rc=$?
+			if test $rc -eq 0; then
+				export=1
+				break;
+			fi
+		done
+		if test $export -eq 0; then :
+			rc=1
+		else :
+			rc=0
+		fi
+	else :
+		rc=0
+	fi
+
+		fi
+		if test $rc -ne 0; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+		else :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_OPEN_BDEV_EXCLUSIVE 1" >>confdefs.h
+
+
+		fi
+	fi
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether lookup_bdev() is available" >&5
+$as_echo_n "checking whether lookup_bdev() is available... " >&6; }
+
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/fs.h>
+
+int
+main (void)
+{
+
+		lookup_bdev(NULL);
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+  rc=0
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+ rc=1
+
+
+fi
+	rm -Rf build
+
+
+	if test $rc -ne 0; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+	else
+		if test "x$enable_linux_builtin" != xyes; then
+
+	grep -q -E '[[:space:]]lookup_bdev[[:space:]]' \
+		$LINUX_OBJ/$LINUX_SYMBOLS 2>/dev/null
+	rc=$?
+	if test $rc -ne 0; then
+		export=0
+		for file in fs/block_dev.c; do
+			grep -q -E "EXPORT_SYMBOL.*(lookup_bdev)" \
+				"$LINUX/$file" 2>/dev/null
+			rc=$?
+			if test $rc -eq 0; then
+				export=1
+				break;
+			fi
+		done
+		if test $export -eq 0; then :
+			rc=1
+		else :
+			rc=0
+		fi
+	else :
+		rc=0
+	fi
+
+		fi
+		if test $rc -ne 0; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+		else :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_LOOKUP_BDEV 1" >>confdefs.h
+
+
+		fi
+	fi
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether invalidate_bdev() wants 1 arg" >&5
+$as_echo_n "checking whether invalidate_bdev() wants 1 arg... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/buffer_head.h>
+
+int
+main (void)
+{
+
+		struct block_device *bdev = NULL;
+		invalidate_bdev(bdev);
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_1ARG_INVALIDATE_BDEV 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether bdev_logical_block_size() is available" >&5
+$as_echo_n "checking whether bdev_logical_block_size() is available... " >&6; }
+	tmp_flags="$EXTRA_KCFLAGS"
+	EXTRA_KCFLAGS="${NO_UNUSED_BUT_SET_VARIABLE}"
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/blkdev.h>
+
+int
+main (void)
+{
+
+		struct block_device *bdev = NULL;
+		bdev_logical_block_size(bdev);
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_BDEV_LOGICAL_BLOCK_SIZE 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+	EXTRA_KCFLAGS="$tmp_flags"
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether bdev_physical_block_size() is available" >&5
+$as_echo_n "checking whether bdev_physical_block_size() is available... " >&6; }
+	tmp_flags="$EXTRA_KCFLAGS"
+	EXTRA_KCFLAGS="${NO_UNUSED_BUT_SET_VARIABLE}"
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/blkdev.h>
+
+int
+main (void)
+{
+
+		struct block_device *bdev = NULL;
+		bdev_physical_block_size(bdev);
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_BDEV_PHYSICAL_BLOCK_SIZE 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+	EXTRA_KCFLAGS="$tmp_flags"
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether bio has bi_iter" >&5
+$as_echo_n "checking whether bio has bi_iter... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/bio.h>
+
+int
+main (void)
+{
+
+		struct bio bio;
+		bio.bi_iter.bi_sector = 0;
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_BIO_BVEC_ITER 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether BIO_RW_FAILFAST_* are defined" >&5
+$as_echo_n "checking whether BIO_RW_FAILFAST_* are defined... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/bio.h>
+
+int
+main (void)
+{
+
+		int flags __attribute__ ((unused));
+		flags = ((1 << BIO_RW_FAILFAST_DEV) |
+			 (1 << BIO_RW_FAILFAST_TRANSPORT) |
+			 (1 << BIO_RW_FAILFAST_DRIVER));
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_BIO_RW_FAILFAST_DTD 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether REQ_FAILFAST_MASK is defined" >&5
+$as_echo_n "checking whether REQ_FAILFAST_MASK is defined... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/bio.h>
+
+int
+main (void)
+{
+
+		int flags __attribute__ ((unused));
+		flags = REQ_FAILFAST_MASK;
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_REQ_FAILFAST_MASK 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether bio_end_io_t wants 1 arg" >&5
+$as_echo_n "checking whether bio_end_io_t wants 1 arg... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/bio.h>
+
+		void wanted_end_io(struct bio *bio) { return; }
+
+		bio_end_io_t *end_io __attribute__ ((unused)) = wanted_end_io;
+
+int
+main (void)
+{
+
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_1ARG_BIO_END_IO_T 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether BIO_RW_BARRIER is defined" >&5
+$as_echo_n "checking whether BIO_RW_BARRIER is defined... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/bio.h>
+
+int
+main (void)
+{
+
+		int flags __attribute__ ((unused));
+		flags = BIO_RW_BARRIER;
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_BIO_RW_BARRIER 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether BIO_RW_DISCARD is defined" >&5
+$as_echo_n "checking whether BIO_RW_DISCARD is defined... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/bio.h>
+
+int
+main (void)
+{
+
+		int flags __attribute__ ((unused));
+		flags = BIO_RW_DISCARD;
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_BIO_RW_DISCARD 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether blk_queue_flush() is available" >&5
+$as_echo_n "checking whether blk_queue_flush() is available... " >&6; }
+	tmp_flags="$EXTRA_KCFLAGS"
+	EXTRA_KCFLAGS="${NO_UNUSED_BUT_SET_VARIABLE}"
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/blkdev.h>
+
+int
+main (void)
+{
+
+		struct request_queue *q = NULL;
+		(void) blk_queue_flush(q, REQ_FLUSH);
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_BLK_QUEUE_FLUSH 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether blk_queue_flush() is GPL-only" >&5
+$as_echo_n "checking whether blk_queue_flush() is GPL-only... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/module.h>
+		#include <linux/blkdev.h>
+
+		MODULE_LICENSE("$ZFS_META_LICENSE");
+
+int
+main (void)
+{
+
+		struct request_queue *q = NULL;
+		(void) blk_queue_flush(q, REQ_FLUSH);
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_BLK_QUEUE_FLUSH_GPL_ONLY 1" >>confdefs.h
+
+
+
+
+fi
+	rm -Rf build
+
+
+	EXTRA_KCFLAGS="$tmp_flags"
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether blk_queue_max_hw_sectors() is available" >&5
+$as_echo_n "checking whether blk_queue_max_hw_sectors() is available... " >&6; }
+	tmp_flags="$EXTRA_KCFLAGS"
+	EXTRA_KCFLAGS="${NO_UNUSED_BUT_SET_VARIABLE}"
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/blkdev.h>
+
+int
+main (void)
+{
+
+		struct request_queue *q = NULL;
+		(void) blk_queue_max_hw_sectors(q, BLK_SAFE_MAX_SECTORS);
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_BLK_QUEUE_MAX_HW_SECTORS 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+	EXTRA_KCFLAGS="$tmp_flags"
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether blk_queue_max_segments() is available" >&5
+$as_echo_n "checking whether blk_queue_max_segments() is available... " >&6; }
+	tmp_flags="$EXTRA_KCFLAGS"
+	EXTRA_KCFLAGS="${NO_UNUSED_BUT_SET_VARIABLE}"
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/blkdev.h>
+
+int
+main (void)
+{
+
+		struct request_queue *q = NULL;
+		(void) blk_queue_max_segments(q, BLK_MAX_SEGMENTS);
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_BLK_QUEUE_MAX_SEGMENTS 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+	EXTRA_KCFLAGS="$tmp_flags"
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether get_disk_ro() is available" >&5
+$as_echo_n "checking whether get_disk_ro() is available... " >&6; }
+	tmp_flags="$EXTRA_KCFLAGS"
+	EXTRA_KCFLAGS="${NO_UNUSED_BUT_SET_VARIABLE}"
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/blkdev.h>
+
+int
+main (void)
+{
+
+		struct gendisk *disk = NULL;
+		(void) get_disk_ro(disk);
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_GET_DISK_RO 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+	EXTRA_KCFLAGS="$tmp_flags"
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether get_gendisk() is available" >&5
+$as_echo_n "checking whether get_gendisk() is available... " >&6; }
+
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/genhd.h>
+
+int
+main (void)
+{
+
+		get_gendisk(0, NULL);
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+  rc=0
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+ rc=1
+
+
+fi
+	rm -Rf build
+
+
+	if test $rc -ne 0; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+	else
+		if test "x$enable_linux_builtin" != xyes; then
+
+	grep -q -E '[[:space:]]get_gendisk[[:space:]]' \
+		$LINUX_OBJ/$LINUX_SYMBOLS 2>/dev/null
+	rc=$?
+	if test $rc -ne 0; then
+		export=0
+		for file in block/genhd.c; do
+			grep -q -E "EXPORT_SYMBOL.*(get_gendisk)" \
+				"$LINUX/$file" 2>/dev/null
+			rc=$?
+			if test $rc -eq 0; then
+				export=1
+				break;
+			fi
+		done
+		if test $export -eq 0; then :
+			rc=1
+		else :
+			rc=0
+		fi
+	else :
+		rc=0
+	fi
+
+		fi
+		if test $rc -ne 0; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+		else :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_GET_GENDISK 1" >>confdefs.h
+
+
+		fi
+	fi
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ql->discard_granularity is available" >&5
+$as_echo_n "checking whether ql->discard_granularity is available... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/blkdev.h>
+
+int
+main (void)
+{
+
+		struct queue_limits ql __attribute__ ((unused));
+
+		ql.discard_granularity = 0;
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_DISCARD_GRANULARITY 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether super_block uses const struct xattr_handler" >&5
+$as_echo_n "checking whether super_block uses const struct xattr_handler... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/fs.h>
+		#include <linux/xattr.h>
+
+		const struct xattr_handler xattr_test_handler = {
+			.prefix	= "test",
+			.get	= NULL,
+			.set	= NULL,
+		};
+
+		const struct xattr_handler *xattr_handlers[] = {
+			&xattr_test_handler,
+		};
+
+		const struct super_block sb __attribute__ ((unused)) = {
+			.s_xattr = xattr_handlers,
+		};
+
+int
+main (void)
+{
+
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_CONST_XATTR_HANDLER 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+							{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether xattr_handler->get() wants xattr_handler" >&5
+$as_echo_n "checking whether xattr_handler->get() wants xattr_handler... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/xattr.h>
+
+		int get(const struct xattr_handler *handler,
+		    struct dentry *dentry, const char *name,
+		    void *buffer, size_t size) { return 0; }
+		static const struct xattr_handler
+		    xops __attribute__ ((unused)) = {
+			.get = get,
+		};
+
+int
+main (void)
+{
+
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_XATTR_GET_HANDLER 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+														{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether xattr_handler->get() wants dentry" >&5
+$as_echo_n "checking whether xattr_handler->get() wants dentry... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+			#include <linux/xattr.h>
+
+			int get(struct dentry *dentry, const char *name,
+			    void *buffer, size_t size, int handler_flags)
+			    { return 0; }
+			static const struct xattr_handler
+			    xops __attribute__ ((unused)) = {
+				.get = get,
+			};
+
+int
+main (void)
+{
+
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+			{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_XATTR_GET_DENTRY 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+												{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+			{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether xattr_handler->get() wants inode" >&5
+$as_echo_n "checking whether xattr_handler->get() wants inode... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+				#include <linux/xattr.h>
+
+				int get(struct inode *ip, const char *name,
+				    void *buffer, size_t size) { return 0; }
+				static const struct xattr_handler
+				    xops __attribute__ ((unused)) = {
+					.get = get,
+				};
+
+int
+main (void)
+{
+
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+				{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_XATTR_GET_INODE 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	                        as_fn_error $? "no; please file a bug report" "$LINENO" 5
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+							{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether xattr_handler->set() wants xattr_handler" >&5
+$as_echo_n "checking whether xattr_handler->set() wants xattr_handler... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/xattr.h>
+
+		int set(const struct xattr_handler *handler,
+		    struct dentry *dentry, const char *name,
+		    const void *buffer, size_t size, int flags)
+		    { return 0; }
+		static const struct xattr_handler
+		    xops __attribute__ ((unused)) = {
+			.set = set,
+		};
+
+int
+main (void)
+{
+
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_XATTR_SET_HANDLER 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+														{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether xattr_handler->set() wants dentry" >&5
+$as_echo_n "checking whether xattr_handler->set() wants dentry... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+			#include <linux/xattr.h>
+
+			int set(struct dentry *dentry, const char *name,
+			    const void *buffer, size_t size, int flags,
+			    int handler_flags) { return 0; }
+			static const struct xattr_handler
+			    xops __attribute__ ((unused)) = {
+				.set = set,
+			};
+
+int
+main (void)
+{
+
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+			{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_XATTR_SET_DENTRY 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+												{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+			{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether xattr_handler->set() wants inode" >&5
+$as_echo_n "checking whether xattr_handler->set() wants inode... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+				#include <linux/xattr.h>
+
+				int set(struct inode *ip, const char *name,
+				    const void *buffer, size_t size, int flags)
+				    { return 0; }
+				static const struct xattr_handler
+				    xops __attribute__ ((unused)) = {
+					.set = set,
+				};
+
+int
+main (void)
+{
+
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+				{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_XATTR_SET_INODE 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	                        as_fn_error $? "no; please file a bug report" "$LINENO" 5
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+				{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether xattr_handler->list() wants simple" >&5
+$as_echo_n "checking whether xattr_handler->list() wants simple... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/xattr.h>
+
+		bool list(struct dentry *dentry) { return 0; }
+		static const struct xattr_handler
+		    xops __attribute__ ((unused)) = {
+			.list = list,
+		};
+
+int
+main (void)
+{
+
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_XATTR_LIST_SIMPLE 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+														{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether xattr_handler->list() wants xattr_handler" >&5
+$as_echo_n "checking whether xattr_handler->list() wants xattr_handler... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+			#include <linux/xattr.h>
+
+			size_t list(const struct xattr_handler *handler,
+			    struct dentry *dentry, char *list, size_t list_size,
+			    const char *name, size_t name_len) { return 0; }
+			static const struct xattr_handler
+			    xops __attribute__ ((unused)) = {
+				.list = list,
+			};
+
+int
+main (void)
+{
+
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+			{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_XATTR_LIST_HANDLER 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+																					{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+			{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether xattr_handler->list() wants dentry" >&5
+$as_echo_n "checking whether xattr_handler->list() wants dentry... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+				#include <linux/xattr.h>
+
+				size_t list(struct dentry *dentry,
+				    char *list, size_t list_size,
+				    const char *name, size_t name_len,
+				    int handler_flags) { return 0; }
+				static const struct xattr_handler
+				    xops __attribute__ ((unused)) = {
+					.list = list,
+				};
+
+int
+main (void)
+{
+
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+				{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_XATTR_LIST_DENTRY 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+																{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+				{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether xattr_handler->list() wants inode" >&5
+$as_echo_n "checking whether xattr_handler->list() wants inode... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+					#include <linux/xattr.h>
+
+					size_t list(struct inode *ip, char *lst,
+					    size_t list_size, const char *name,
+					    size_t name_len) { return 0; }
+					static const struct xattr_handler
+					    xops __attribute__ ((unused)) = {
+						.list = list,
+					};
+
+int
+main (void)
+{
+
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+					{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_XATTR_LIST_INODE 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		                        as_fn_error $? "no; please file a bug report" "$LINENO" 5
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether inode_owner_or_capable() exists" >&5
+$as_echo_n "checking whether inode_owner_or_capable() exists... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/fs.h>
+
+int
+main (void)
+{
+
+		struct inode *ip = NULL;
+		(void) inode_owner_or_capable(ip);
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_INODE_OWNER_OR_CAPABLE 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether is_owner_or_cap() exists" >&5
+$as_echo_n "checking whether is_owner_or_cap() exists... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+			#include <linux/fs.h>
+			#include <linux/sched.h>
+
+int
+main (void)
+{
+
+			struct inode *ip = NULL;
+			(void) is_owner_or_cap(ip);
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+			{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_IS_OWNER_OR_CAP 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+			as_fn_error $? "no - Please file a bug report at
+			    https://github.com/zfsonlinux/zfs/issues/new" "$LINENO" 5
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether posix_acl_from_xattr() needs user_ns" >&5
+$as_echo_n "checking whether posix_acl_from_xattr() needs user_ns... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/cred.h>
+		#include <linux/fs.h>
+		#include <linux/posix_acl_xattr.h>
+
+int
+main (void)
+{
+
+		posix_acl_from_xattr(&init_user_ns, NULL, 0);
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_POSIX_ACL_FROM_XATTR_USERNS 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether posix_acl_release() is available" >&5
+$as_echo_n "checking whether posix_acl_release() is available... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/cred.h>
+		#include <linux/fs.h>
+		#include <linux/posix_acl.h>
+
+int
+main (void)
+{
+
+		struct posix_acl* tmp = posix_acl_alloc(1, 0);
+		posix_acl_release(tmp);
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_POSIX_ACL_RELEASE 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether posix_acl_release() is GPL-only" >&5
+$as_echo_n "checking whether posix_acl_release() is GPL-only... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/cred.h>
+		#include <linux/fs.h>
+		#include <linux/posix_acl.h>
+
+		MODULE_LICENSE("$ZFS_META_LICENSE");
+
+int
+main (void)
+{
+
+		struct posix_acl* tmp = posix_acl_alloc(1, 0);
+		posix_acl_release(tmp);
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_POSIX_ACL_RELEASE_GPL_ONLY 1" >>confdefs.h
+
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether posix_acl_chmod exists" >&5
+$as_echo_n "checking whether posix_acl_chmod exists... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/fs.h>
+		#include <linux/posix_acl.h>
+
+int
+main (void)
+{
+
+		posix_acl_chmod(NULL, 0, 0)
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_POSIX_ACL_CHMOD 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether __posix_acl_chmod exists" >&5
+$as_echo_n "checking whether __posix_acl_chmod exists... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/fs.h>
+		#include <linux/posix_acl.h>
+
+int
+main (void)
+{
+
+		__posix_acl_chmod(NULL, 0, 0)
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE___POSIX_ACL_CHMOD 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether inode has i_acl and i_default_acl" >&5
+$as_echo_n "checking whether inode has i_acl and i_default_acl... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/fs.h>
+
+int
+main (void)
+{
+
+		struct inode ino;
+		ino.i_acl = NULL;
+		ino.i_default_acl = NULL;
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_POSIX_ACL_CACHING 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether posix_acl_equiv_mode() wants umode_t" >&5
+$as_echo_n "checking whether posix_acl_equiv_mode() wants umode_t... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/fs.h>
+		#include <linux/posix_acl.h>
+
+int
+main (void)
+{
+
+		umode_t tmp;
+		posix_acl_equiv_mode(NULL,&tmp);
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_POSIX_ACL_EQUIV_MODE_UMODE_T 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether iops->permission() exists" >&5
+$as_echo_n "checking whether iops->permission() exists... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/fs.h>
+
+		int permission_fn(struct inode *inode, int mask) { return 0; }
+
+		static const struct inode_operations
+		    iops __attribute__ ((unused)) = {
+			.permission = permission_fn,
+		};
+
+int
+main (void)
+{
+
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_PERMISSION 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether iops->permission() wants nameidata" >&5
+$as_echo_n "checking whether iops->permission() wants nameidata... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/fs.h>
+
+		int permission_fn(struct inode *inode, int mask,
+		    struct nameidata *nd) { return 0; }
+
+		static const struct inode_operations
+		    iops __attribute__ ((unused)) = {
+			.permission = permission_fn,
+		};
+
+int
+main (void)
+{
+
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_PERMISSION 1" >>confdefs.h
+
+
+$as_echo "#define HAVE_PERMISSION_WITH_NAMEIDATA 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether iops->check_acl() exists" >&5
+$as_echo_n "checking whether iops->check_acl() exists... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/fs.h>
+
+		int check_acl_fn(struct inode *inode, int mask) { return 0; }
+
+		static const struct inode_operations
+		    iops __attribute__ ((unused)) = {
+			.check_acl = check_acl_fn,
+		};
+
+int
+main (void)
+{
+
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_CHECK_ACL 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether iops->check_acl() wants flags" >&5
+$as_echo_n "checking whether iops->check_acl() wants flags... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/fs.h>
+
+		int check_acl_fn(struct inode *inode, int mask,
+		    unsigned int flags) { return 0; }
+
+		static const struct inode_operations
+		    iops __attribute__ ((unused)) = {
+			.check_acl = check_acl_fn,
+		};
+
+int
+main (void)
+{
+
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_CHECK_ACL 1" >>confdefs.h
+
+
+$as_echo "#define HAVE_CHECK_ACL_WITH_FLAGS 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether iops->get_acl() exists" >&5
+$as_echo_n "checking whether iops->get_acl() exists... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/fs.h>
+
+		struct posix_acl *get_acl_fn(struct inode *inode, int type)
+		    { return NULL; }
+
+		static const struct inode_operations
+		    iops __attribute__ ((unused)) = {
+			.get_acl = get_acl_fn,
+		};
+
+int
+main (void)
+{
+
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_GET_ACL 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether current_umask exists" >&5
+$as_echo_n "checking whether current_umask exists... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/fs.h>
+
+int
+main (void)
+{
+
+		current_umask();
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_CURRENT_UMASK 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether sops->show_options() wants dentry" >&5
+$as_echo_n "checking whether sops->show_options() wants dentry... " >&6; }
+
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/fs.h>
+
+		int show_options (struct seq_file * x, struct dentry * y) { return 0; };
+		static struct super_operations sops __attribute__ ((unused)) = {
+			.show_options = show_options,
+		};
+
+int
+main (void)
+{
+
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_SHOW_OPTIONS_WITH_DENTRY 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether file_inode() is available" >&5
+$as_echo_n "checking whether file_inode() is available... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/fs.h>
+
+int
+main (void)
+{
+
+		struct file *f = NULL;
+		file_inode(f);
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_FILE_INODE 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether fops->fsync() wants" >&5
+$as_echo_n "checking whether fops->fsync() wants... " >&6; }
+
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/fs.h>
+
+		int test_fsync(struct file *f, struct dentry *dentry, int x)
+		    { return 0; }
+
+		static const struct file_operations
+		    fops __attribute__ ((unused)) = {
+			.fsync = test_fsync,
+		};
+
+int
+main (void)
+{
+
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: dentry" >&5
+$as_echo "dentry" >&6; }
+
+$as_echo "#define HAVE_FSYNC_WITH_DENTRY 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/fs.h>
+
+		int test_fsync(struct file *f, int x) { return 0; }
+
+		static const struct file_operations
+		    fops __attribute__ ((unused)) = {
+			.fsync = test_fsync,
+		};
+
+int
+main (void)
+{
+
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no dentry" >&5
+$as_echo "no dentry" >&6; }
+
+$as_echo "#define HAVE_FSYNC_WITHOUT_DENTRY 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/fs.h>
+
+		int test_fsync(struct file *f, loff_t a, loff_t b, int c)
+		    { return 0; }
+
+		static const struct file_operations
+		    fops __attribute__ ((unused)) = {
+			.fsync = test_fsync,
+		};
+
+int
+main (void)
+{
+
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: range" >&5
+$as_echo "range" >&6; }
+
+$as_echo "#define HAVE_FSYNC_RANGE 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether sops->evict_inode() exists" >&5
+$as_echo_n "checking whether sops->evict_inode() exists... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/fs.h>
+		void evict_inode (struct inode * t) { return; }
+		static struct super_operations sops __attribute__ ((unused)) = {
+			.evict_inode = evict_inode,
+		};
+
+int
+main (void)
+{
+
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_EVICT_INODE 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether sops->dirty_inode() wants flags" >&5
+$as_echo_n "checking whether sops->dirty_inode() wants flags... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/fs.h>
+
+		void dirty_inode(struct inode *a, int b) { return; }
+
+		static const struct super_operations
+		    sops __attribute__ ((unused)) = {
+			.dirty_inode = dirty_inode,
+		};
+
+int
+main (void)
+{
+
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_DIRTY_INODE_WITH_FLAGS 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether sops->nr_cached_objects() exists" >&5
+$as_echo_n "checking whether sops->nr_cached_objects() exists... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/fs.h>
+
+		int nr_cached_objects(struct super_block *sb) { return 0; }
+
+		static const struct super_operations
+		    sops __attribute__ ((unused)) = {
+			.nr_cached_objects = nr_cached_objects,
+		};
+
+int
+main (void)
+{
+
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_NR_CACHED_OBJECTS 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether sops->free_cached_objects() exists" >&5
+$as_echo_n "checking whether sops->free_cached_objects() exists... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/fs.h>
+
+		void free_cached_objects(struct super_block *sb, int x)
+		    { return; }
+
+		static const struct super_operations
+		    sops __attribute__ ((unused)) = {
+			.free_cached_objects = free_cached_objects,
+		};
+
+int
+main (void)
+{
+
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_FREE_CACHED_OBJECTS 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether fops->fallocate() exists" >&5
+$as_echo_n "checking whether fops->fallocate() exists... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/fs.h>
+
+		long test_fallocate(struct file *file, int mode,
+		    loff_t offset, loff_t len) { return 0; }
+
+		static const struct file_operations
+		    fops __attribute__ ((unused)) = {
+			.fallocate = test_fallocate,
+		};
+
+int
+main (void)
+{
+
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_FILE_FALLOCATE 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether iops->fallocate() exists" >&5
+$as_echo_n "checking whether iops->fallocate() exists... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/fs.h>
+
+		long test_fallocate(struct inode *inode, int mode,
+		    loff_t offset, loff_t len) { return 0; }
+
+		static const struct inode_operations
+		    fops __attribute__ ((unused)) = {
+			.fallocate = test_fallocate,
+		};
+
+int
+main (void)
+{
+
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_INODE_FALLOCATE 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether iops->create()/mkdir()/mknod() take umode_t" >&5
+$as_echo_n "checking whether iops->create()/mkdir()/mknod() take umode_t... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/fs.h>
+
+		int mkdir(struct inode *inode, struct dentry *dentry,
+		    umode_t umode) { return 0; }
+
+		static const struct inode_operations
+		    iops __attribute__ ((unused)) = {
+			.mkdir = mkdir,
+		};
+
+int
+main (void)
+{
+
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_MKDIR_UMODE_T 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether iops->lookup() passes nameidata" >&5
+$as_echo_n "checking whether iops->lookup() passes nameidata... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/fs.h>
+
+		struct dentry *inode_lookup(struct inode *inode,
+		    struct dentry *dentry, struct nameidata *nidata)
+		    { return NULL; }
+
+		static const struct inode_operations iops
+		    __attribute__ ((unused)) = {
+			.lookup	= inode_lookup,
+		};
+
+int
+main (void)
+{
+
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_LOOKUP_NAMEIDATA 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether iops->create() passes nameidata" >&5
+$as_echo_n "checking whether iops->create() passes nameidata... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/fs.h>
+
+		#ifdef HAVE_MKDIR_UMODE_T
+		int inode_create(struct inode *inode ,struct dentry *dentry,
+		    umode_t umode, struct nameidata *nidata) { return 0; }
+		#else
+		int inode_create(struct inode *inode,struct dentry *dentry,
+		    int umode, struct nameidata * nidata) { return 0; }
+		#endif
+
+		static const struct inode_operations
+		    iops __attribute__ ((unused)) = {
+			.create		= inode_create,
+		};
+
+int
+main (void)
+{
+
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_CREATE_NAMEIDATA 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+						{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether iops->get_link() passes delayed" >&5
+$as_echo_n "checking whether iops->get_link() passes delayed... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/fs.h>
+		const char *get_link(struct dentry *de, struct inode *ip,
+		    struct delayed_call *done) { return "symlink"; }
+		static struct inode_operations
+		     iops __attribute__ ((unused)) = {
+			.get_link = get_link,
+		};
+
+int
+main (void)
+{
+
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_GET_LINK_DELAYED 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+																{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether iops->get_link() passes cookie" >&5
+$as_echo_n "checking whether iops->get_link() passes cookie... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+			#include <linux/fs.h>
+			const char *get_link(struct dentry *de, struct
+			    inode *ip, void **cookie) { return "symlink"; }
+			static struct inode_operations
+			     iops __attribute__ ((unused)) = {
+				.get_link = get_link,
+			};
+
+int
+main (void)
+{
+
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+			{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_GET_LINK_COOKIE 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+												{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+					{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether iops->follow_link() passes cookie" >&5
+$as_echo_n "checking whether iops->follow_link() passes cookie... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/fs.h>
+		const char *follow_link(struct dentry *de,
+		    void **cookie) { return "symlink"; }
+		static struct inode_operations
+		    iops __attribute__ ((unused)) = {
+			.follow_link = follow_link,
+		};
+
+int
+main (void)
+{
+
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_FOLLOW_LINK_COOKIE 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+								{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether iops->follow_link() passes nameidata" >&5
+$as_echo_n "checking whether iops->follow_link() passes nameidata... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/fs.h>
+			void *follow_link(struct dentry *de, struct
+			    nameidata *nd) { return (void *)NULL; }
+			static struct inode_operations
+			    iops __attribute__ ((unused)) = {
+				.follow_link = follow_link,
+			};
+
+int
+main (void)
+{
+
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+			{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_FOLLOW_LINK_NAMEIDATA 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+                        as_fn_error $? "no; please file a bug report" "$LINENO" 5
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#if !defined(HAVE_GET_LINK_DELAYED)
+		#error "Expecting get_link() delayed done"
+		#endif
+
+int
+main (void)
+{
+
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+
+$as_echo "#define HAVE_PUT_LINK_DELAYED 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+										{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether iops->put_link() passes cookie" >&5
+$as_echo_n "checking whether iops->put_link() passes cookie... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+			#include <linux/fs.h>
+			void put_link(struct inode *ip, void *cookie)
+			    { return; }
+			static struct inode_operations
+			    iops __attribute__ ((unused)) = {
+				.put_link = put_link,
+			};
+
+int
+main (void)
+{
+
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+			{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_PUT_LINK_COOKIE 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+												{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+			{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether iops->put_link() passes nameidata" >&5
+$as_echo_n "checking whether iops->put_link() passes nameidata... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+				#include <linux/fs.h>
+				void put_link(struct dentry *de, struct
+				    nameidata *nd, void *ptr) { return; }
+				static struct inode_operations
+				    iops __attribute__ ((unused)) = {
+					.put_link = put_link,
+				};
+
+int
+main (void)
+{
+
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+				{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_PUT_LINK_NAMEIDATA 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+				as_fn_error $? "no; please file a bug report" "$LINENO" 5
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether iops->truncate_range() exists" >&5
+$as_echo_n "checking whether iops->truncate_range() exists... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/fs.h>
+		void truncate_range(struct inode *inode, loff_t start,
+		                    loff_t end) { return; }
+		static struct inode_operations iops __attribute__ ((unused)) = {
+			.truncate_range	= truncate_range,
+		};
+
+int
+main (void)
+{
+
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_INODE_TRUNCATE_RANGE 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether dops->d_automount() exists" >&5
+$as_echo_n "checking whether dops->d_automount() exists... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/dcache.h>
+		struct vfsmount *d_automount(struct path *p) { return NULL; }
+		struct dentry_operations dops __attribute__ ((unused)) = {
+			.d_automount = d_automount,
+		};
+
+int
+main (void)
+{
+
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_AUTOMOUNT 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether eops->encode_fh() wants inode" >&5
+$as_echo_n "checking whether eops->encode_fh() wants inode... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/exportfs.h>
+		int encode_fh(struct inode *inode, __u32 *fh, int *max_len,
+		              struct inode *parent) { return 0; }
+		static struct export_operations eops __attribute__ ((unused))={
+			.encode_fh = encode_fh,
+		};
+
+int
+main (void)
+{
+
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_ENCODE_FH_WITH_INODE 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether eops->commit_metadata() exists" >&5
+$as_echo_n "checking whether eops->commit_metadata() exists... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/exportfs.h>
+		int commit_metadata(struct inode *inode) { return 0; }
+		static struct export_operations eops __attribute__ ((unused))={
+			.commit_metadata = commit_metadata,
+		};
+
+int
+main (void)
+{
+
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_COMMIT_METADATA 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether clear_inode() is available" >&5
+$as_echo_n "checking whether clear_inode() is available... " >&6; }
+
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/fs.h>
+
+int
+main (void)
+{
+
+		clear_inode(NULL);
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+  rc=0
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+ rc=1
+
+
+fi
+	rm -Rf build
+
+
+	if test $rc -ne 0; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+	else
+		if test "x$enable_linux_builtin" != xyes; then
+
+	grep -q -E '[[:space:]]clear_inode[[:space:]]' \
+		$LINUX_OBJ/$LINUX_SYMBOLS 2>/dev/null
+	rc=$?
+	if test $rc -ne 0; then
+		export=0
+		for file in fs/inode.c; do
+			grep -q -E "EXPORT_SYMBOL.*(clear_inode)" \
+				"$LINUX/$file" 2>/dev/null
+			rc=$?
+			if test $rc -eq 0; then
+				export=1
+				break;
+			fi
+		done
+		if test $export -eq 0; then :
+			rc=1
+		else :
+			rc=0
+		fi
+	else :
+		rc=0
+	fi
+
+		fi
+		if test $rc -ne 0; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+		else :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_CLEAR_INODE 1" >>confdefs.h
+
+
+		fi
+	fi
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether insert_inode_locked() is available" >&5
+$as_echo_n "checking whether insert_inode_locked() is available... " >&6; }
+
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/fs.h>
+
+int
+main (void)
+{
+
+		insert_inode_locked(NULL);
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+  rc=0
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+ rc=1
+
+
+fi
+	rm -Rf build
+
+
+	if test $rc -ne 0; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+	else
+		if test "x$enable_linux_builtin" != xyes; then
+
+	grep -q -E '[[:space:]]insert_inode_locked[[:space:]]' \
+		$LINUX_OBJ/$LINUX_SYMBOLS 2>/dev/null
+	rc=$?
+	if test $rc -ne 0; then
+		export=0
+		for file in fs/inode.c; do
+			grep -q -E "EXPORT_SYMBOL.*(insert_inode_locked)" \
+				"$LINUX/$file" 2>/dev/null
+			rc=$?
+			if test $rc -eq 0; then
+				export=1
+				break;
+			fi
+		done
+		if test $export -eq 0; then :
+			rc=1
+		else :
+			rc=0
+		fi
+	else :
+		rc=0
+	fi
+
+		fi
+		if test $rc -ne 0; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+		else :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_INSERT_INODE_LOCKED 1" >>confdefs.h
+
+
+		fi
+	fi
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether d_make_root() is available" >&5
+$as_echo_n "checking whether d_make_root() is available... " >&6; }
+
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/dcache.h>
+
+int
+main (void)
+{
+
+		d_make_root(NULL);
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+  rc=0
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+ rc=1
+
+
+fi
+	rm -Rf build
+
+
+	if test $rc -ne 0; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+	else
+		if test "x$enable_linux_builtin" != xyes; then
+
+	grep -q -E '[[:space:]]d_make_root[[:space:]]' \
+		$LINUX_OBJ/$LINUX_SYMBOLS 2>/dev/null
+	rc=$?
+	if test $rc -ne 0; then
+		export=0
+		for file in fs/dcache.c; do
+			grep -q -E "EXPORT_SYMBOL.*(d_make_root)" \
+				"$LINUX/$file" 2>/dev/null
+			rc=$?
+			if test $rc -eq 0; then
+				export=1
+				break;
+			fi
+		done
+		if test $export -eq 0; then :
+			rc=1
+		else :
+			rc=0
+		fi
+	else :
+		rc=0
+	fi
+
+		fi
+		if test $rc -ne 0; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+		else :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_D_MAKE_ROOT 1" >>confdefs.h
+
+
+		fi
+	fi
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether d_obtain_alias() is available" >&5
+$as_echo_n "checking whether d_obtain_alias() is available... " >&6; }
+
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/dcache.h>
+
+int
+main (void)
+{
+
+		d_obtain_alias(NULL);
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+  rc=0
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+ rc=1
+
+
+fi
+	rm -Rf build
+
+
+	if test $rc -ne 0; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+	else
+		if test "x$enable_linux_builtin" != xyes; then
+
+	grep -q -E '[[:space:]]d_obtain_alias[[:space:]]' \
+		$LINUX_OBJ/$LINUX_SYMBOLS 2>/dev/null
+	rc=$?
+	if test $rc -ne 0; then
+		export=0
+		for file in fs/dcache.c; do
+			grep -q -E "EXPORT_SYMBOL.*(d_obtain_alias)" \
+				"$LINUX/$file" 2>/dev/null
+			rc=$?
+			if test $rc -eq 0; then
+				export=1
+				break;
+			fi
+		done
+		if test $export -eq 0; then :
+			rc=1
+		else :
+			rc=0
+		fi
+	else :
+		rc=0
+	fi
+
+		fi
+		if test $rc -ne 0; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+		else :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_D_OBTAIN_ALIAS 1" >>confdefs.h
+
+
+		fi
+	fi
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether d_prune_aliases() is available" >&5
+$as_echo_n "checking whether d_prune_aliases() is available... " >&6; }
+
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/dcache.h>
+
+int
+main (void)
+{
+
+		struct inode *ip = NULL;
+		d_prune_aliases(ip);
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+  rc=0
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+ rc=1
+
+
+fi
+	rm -Rf build
+
+
+	if test $rc -ne 0; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+	else
+		if test "x$enable_linux_builtin" != xyes; then
+
+	grep -q -E '[[:space:]]d_prune_aliases[[:space:]]' \
+		$LINUX_OBJ/$LINUX_SYMBOLS 2>/dev/null
+	rc=$?
+	if test $rc -ne 0; then
+		export=0
+		for file in fs/dcache.c; do
+			grep -q -E "EXPORT_SYMBOL.*(d_prune_aliases)" \
+				"$LINUX/$file" 2>/dev/null
+			rc=$?
+			if test $rc -eq 0; then
+				export=1
+				break;
+			fi
+		done
+		if test $export -eq 0; then :
+			rc=1
+		else :
+			rc=0
+		fi
+	else :
+		rc=0
+	fi
+
+		fi
+		if test $rc -ne 0; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+		else :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_D_PRUNE_ALIASES 1" >>confdefs.h
+
+
+		fi
+	fi
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether d_set_d_op() is available" >&5
+$as_echo_n "checking whether d_set_d_op() is available... " >&6; }
+
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/dcache.h>
+
+int
+main (void)
+{
+
+		d_set_d_op(NULL, NULL);
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+  rc=0
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+ rc=1
+
+
+fi
+	rm -Rf build
+
+
+	if test $rc -ne 0; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+	else
+		if test "x$enable_linux_builtin" != xyes; then
+
+	grep -q -E '[[:space:]]d_set_d_op[[:space:]]' \
+		$LINUX_OBJ/$LINUX_SYMBOLS 2>/dev/null
+	rc=$?
+	if test $rc -ne 0; then
+		export=0
+		for file in fs/dcache.c; do
+			grep -q -E "EXPORT_SYMBOL.*(d_set_d_op)" \
+				"$LINUX/$file" 2>/dev/null
+			rc=$?
+			if test $rc -eq 0; then
+				export=1
+				break;
+			fi
+		done
+		if test $export -eq 0; then :
+			rc=1
+		else :
+			rc=0
+		fi
+	else :
+		rc=0
+	fi
+
+		fi
+		if test $rc -ne 0; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+		else :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_D_SET_D_OP 1" >>confdefs.h
+
+
+		fi
+	fi
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether dops->d_revalidate() takes struct nameidata" >&5
+$as_echo_n "checking whether dops->d_revalidate() takes struct nameidata... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/dcache.h>
+
+		int revalidate (struct dentry *dentry,
+		    struct nameidata *nidata) { return 0; }
+
+		static const struct dentry_operations
+		    dops __attribute__ ((unused)) = {
+			.d_revalidate	= revalidate,
+		};
+
+int
+main (void)
+{
+
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_D_REVALIDATE_NAMEIDATA 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether dentry uses const struct dentry_operations" >&5
+$as_echo_n "checking whether dentry uses const struct dentry_operations... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/dcache.h>
+
+		const struct dentry_operations test_d_op = {
+			.d_revalidate = NULL,
+		};
+
+int
+main (void)
+{
+
+		struct dentry d __attribute__ ((unused));
+
+		d.d_op = &test_d_op;
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_CONST_DENTRY_OPERATIONS 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether check_disk_size_change() is available" >&5
+$as_echo_n "checking whether check_disk_size_change() is available... " >&6; }
+
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/fs.h>
+
+int
+main (void)
+{
+
+		check_disk_size_change(NULL, NULL);
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+  rc=0
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+ rc=1
+
+
+fi
+	rm -Rf build
+
+
+	if test $rc -ne 0; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+	else
+		if test "x$enable_linux_builtin" != xyes; then
+
+	grep -q -E '[[:space:]]check_disk_size_change[[:space:]]' \
+		$LINUX_OBJ/$LINUX_SYMBOLS 2>/dev/null
+	rc=$?
+	if test $rc -ne 0; then
+		export=0
+		for file in fs/block_dev.c; do
+			grep -q -E "EXPORT_SYMBOL.*(check_disk_size_change)" \
+				"$LINUX/$file" 2>/dev/null
+			rc=$?
+			if test $rc -eq 0; then
+				export=1
+				break;
+			fi
+		done
+		if test $export -eq 0; then :
+			rc=1
+		else :
+			rc=0
+		fi
+	else :
+		rc=0
+	fi
+
+		fi
+		if test $rc -ne 0; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+		else :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_CHECK_DISK_SIZE_CHANGE 1" >>confdefs.h
+
+
+		fi
+	fi
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether truncate_setsize() is available" >&5
+$as_echo_n "checking whether truncate_setsize() is available... " >&6; }
+
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/mm.h>
+
+int
+main (void)
+{
+
+		truncate_setsize(NULL, 0);
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+  rc=0
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+ rc=1
+
+
+fi
+	rm -Rf build
+
+
+	if test $rc -ne 0; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+	else
+		if test "x$enable_linux_builtin" != xyes; then
+
+	grep -q -E '[[:space:]]truncate_setsize[[:space:]]' \
+		$LINUX_OBJ/$LINUX_SYMBOLS 2>/dev/null
+	rc=$?
+	if test $rc -ne 0; then
+		export=0
+		for file in mm/truncate.c; do
+			grep -q -E "EXPORT_SYMBOL.*(truncate_setsize)" \
+				"$LINUX/$file" 2>/dev/null
+			rc=$?
+			if test $rc -eq 0; then
+				export=1
+				break;
+			fi
+		done
+		if test $export -eq 0; then :
+			rc=1
+		else :
+			rc=0
+		fi
+	else :
+		rc=0
+	fi
+
+		fi
+		if test $rc -ne 0; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+		else :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_TRUNCATE_SETSIZE 1" >>confdefs.h
+
+
+		fi
+	fi
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether security_inode_init_security wants 6 args" >&5
+$as_echo_n "checking whether security_inode_init_security wants 6 args... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/security.h>
+
+int
+main (void)
+{
+
+		struct inode *ip __attribute__ ((unused)) = NULL;
+		struct inode *dip __attribute__ ((unused)) = NULL;
+		const struct qstr *str __attribute__ ((unused)) = NULL;
+		char *name __attribute__ ((unused)) = NULL;
+		void *value __attribute__ ((unused)) = NULL;
+		size_t len __attribute__ ((unused)) = 0;
+
+		security_inode_init_security(ip, dip, str, &name, &value, &len);
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_6ARGS_SECURITY_INODE_INIT_SECURITY 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether security_inode_init_security wants callback" >&5
+$as_echo_n "checking whether security_inode_init_security wants callback... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/security.h>
+
+int
+main (void)
+{
+
+		struct inode *ip __attribute__ ((unused)) = NULL;
+		struct inode *dip __attribute__ ((unused)) = NULL;
+		const struct qstr *str __attribute__ ((unused)) = NULL;
+		initxattrs func __attribute__ ((unused)) = NULL;
+
+		security_inode_init_security(ip, dip, str, func, NULL);
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_CALLBACK_SECURITY_INODE_INIT_SECURITY 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether mount_nodev() is available" >&5
+$as_echo_n "checking whether mount_nodev() is available... " >&6; }
+
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/fs.h>
+
+int
+main (void)
+{
+
+		mount_nodev(NULL, 0, NULL, NULL);
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+  rc=0
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+ rc=1
+
+
+fi
+	rm -Rf build
+
+
+	if test $rc -ne 0; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+	else
+		if test "x$enable_linux_builtin" != xyes; then
+
+	grep -q -E '[[:space:]]mount_nodev[[:space:]]' \
+		$LINUX_OBJ/$LINUX_SYMBOLS 2>/dev/null
+	rc=$?
+	if test $rc -ne 0; then
+		export=0
+		for file in fs/super.c; do
+			grep -q -E "EXPORT_SYMBOL.*(mount_nodev)" \
+				"$LINUX/$file" 2>/dev/null
+			rc=$?
+			if test $rc -eq 0; then
+				export=1
+				break;
+			fi
+		done
+		if test $export -eq 0; then :
+			rc=1
+		else :
+			rc=0
+		fi
+	else :
+		rc=0
+	fi
+
+		fi
+		if test $rc -ne 0; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+		else :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_MOUNT_NODEV 1" >>confdefs.h
+
+
+		fi
+	fi
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether super_block has s_shrink" >&5
+$as_echo_n "checking whether super_block has s_shrink... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/fs.h>
+
+		int shrink(struct shrinker *s, struct shrink_control *sc)
+		    { return 0; }
+
+		static const struct super_block
+		    sb __attribute__ ((unused)) = {
+			.s_shrink.shrink = shrink,
+			.s_shrink.seeks = DEFAULT_SEEKS,
+			.s_shrink.batch = 0,
+		};
+
+int
+main (void)
+{
+
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_SHRINK 1" >>confdefs.h
+
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether shrink_control has nid" >&5
+$as_echo_n "checking whether shrink_control has nid... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/fs.h>
+
+int
+main (void)
+{
+
+		struct shrink_control sc __attribute__ ((unused));
+		unsigned long scnidsize __attribute__ ((unused)) =
+		    sizeof(sc.nid);
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define SHRINK_CONTROL_HAS_NID 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether super_block has s_instances list_head" >&5
+$as_echo_n "checking whether super_block has s_instances list_head... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/fs.h>
+
+int
+main (void)
+{
+
+		struct super_block sb __attribute__ ((unused));
+
+		INIT_LIST_HEAD(&sb.s_instances);
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_S_INSTANCES_LIST_HEAD 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether super_block has s_d_op" >&5
+$as_echo_n "checking whether super_block has s_d_op... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/fs.h>
+
+int
+main (void)
+{
+
+		struct super_block sb __attribute__ ((unused));
+		sb.s_d_op = NULL;
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_S_D_OP 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether bdi_setup_and_register() wants 2 args" >&5
+$as_echo_n "checking whether bdi_setup_and_register() wants 2 args... " >&6; }
+
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/backing-dev.h>
+		struct backing_dev_info bdi;
+
+int
+main (void)
+{
+
+		char *name = "bdi";
+		int error __attribute__((unused)) =
+		    bdi_setup_and_register(&bdi, name);
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+  rc=0
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+ rc=1
+
+
+fi
+	rm -Rf build
+
+
+	if test $rc -ne 0; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether bdi_setup_and_register() wants 3 args" >&5
+$as_echo_n "checking whether bdi_setup_and_register() wants 3 args... " >&6; }
+
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+			#include <linux/backing-dev.h>
+			struct backing_dev_info bdi;
+
+int
+main (void)
+{
+
+			char *name = "bdi";
+			unsigned int cap = BDI_CAP_MAP_COPY;
+			int error __attribute__((unused)) =
+			    bdi_setup_and_register(&bdi, name, cap);
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+  rc=0
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+ rc=1
+
+
+fi
+	rm -Rf build
+
+
+	if test $rc -ne 0; then :
+
+			{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+	else
+		if test "x$enable_linux_builtin" != xyes; then
+
+	grep -q -E '[[:space:]]bdi_setup_and_register[[:space:]]' \
+		$LINUX_OBJ/$LINUX_SYMBOLS 2>/dev/null
+	rc=$?
+	if test $rc -ne 0; then
+		export=0
+		for file in mm/backing-dev.c; do
+			grep -q -E "EXPORT_SYMBOL.*(bdi_setup_and_register)" \
+				"$LINUX/$file" 2>/dev/null
+			rc=$?
+			if test $rc -eq 0; then
+				export=1
+				break;
+			fi
+		done
+		if test $export -eq 0; then :
+			rc=1
+		else :
+			rc=0
+		fi
+	else :
+		rc=0
+	fi
+
+		fi
+		if test $rc -ne 0; then :
+
+			{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+		else :
+
+			{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_3ARGS_BDI_SETUP_AND_REGISTER 1" >>confdefs.h
+
+
+		fi
+	fi
+
+
+	else
+		if test "x$enable_linux_builtin" != xyes; then
+
+	grep -q -E '[[:space:]]bdi_setup_and_register[[:space:]]' \
+		$LINUX_OBJ/$LINUX_SYMBOLS 2>/dev/null
+	rc=$?
+	if test $rc -ne 0; then
+		export=0
+		for file in mm/backing-dev.c; do
+			grep -q -E "EXPORT_SYMBOL.*(bdi_setup_and_register)" \
+				"$LINUX/$file" 2>/dev/null
+			rc=$?
+			if test $rc -eq 0; then
+				export=1
+				break;
+			fi
+		done
+		if test $export -eq 0; then :
+			rc=1
+		else :
+			rc=0
+		fi
+	else :
+		rc=0
+	fi
+
+		fi
+		if test $rc -ne 0; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether bdi_setup_and_register() wants 3 args" >&5
+$as_echo_n "checking whether bdi_setup_and_register() wants 3 args... " >&6; }
+
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+			#include <linux/backing-dev.h>
+			struct backing_dev_info bdi;
+
+int
+main (void)
+{
+
+			char *name = "bdi";
+			unsigned int cap = BDI_CAP_MAP_COPY;
+			int error __attribute__((unused)) =
+			    bdi_setup_and_register(&bdi, name, cap);
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+  rc=0
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+ rc=1
+
+
+fi
+	rm -Rf build
+
+
+	if test $rc -ne 0; then :
+
+			{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+	else
+		if test "x$enable_linux_builtin" != xyes; then
+
+	grep -q -E '[[:space:]]bdi_setup_and_register[[:space:]]' \
+		$LINUX_OBJ/$LINUX_SYMBOLS 2>/dev/null
+	rc=$?
+	if test $rc -ne 0; then
+		export=0
+		for file in mm/backing-dev.c; do
+			grep -q -E "EXPORT_SYMBOL.*(bdi_setup_and_register)" \
+				"$LINUX/$file" 2>/dev/null
+			rc=$?
+			if test $rc -eq 0; then
+				export=1
+				break;
+			fi
+		done
+		if test $export -eq 0; then :
+			rc=1
+		else :
+			rc=0
+		fi
+	else :
+		rc=0
+	fi
+
+		fi
+		if test $rc -ne 0; then :
+
+			{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+		else :
+
+			{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_3ARGS_BDI_SETUP_AND_REGISTER 1" >>confdefs.h
+
+
+		fi
+	fi
+
+
+		else :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_2ARGS_BDI_SETUP_AND_REGISTER 1" >>confdefs.h
+
+
+		fi
+	fi
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether set_nlink() is available" >&5
+$as_echo_n "checking whether set_nlink() is available... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/fs.h>
+
+int
+main (void)
+{
+
+		struct inode node;
+		unsigned int link = 0;
+		(void) set_nlink(&node, link);
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_SET_NLINK 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether elevator_change() is available" >&5
+$as_echo_n "checking whether elevator_change() is available... " >&6; }
+	tmp_flags="$EXTRA_KCFLAGS"
+	EXTRA_KCFLAGS="${NO_UNUSED_BUT_SET_VARIABLE}"
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/blkdev.h>
+		#include <linux/elevator.h>
+
+int
+main (void)
+{
+
+		int ret;
+		struct request_queue *q = NULL;
+		char *elevator = NULL;
+		ret = elevator_change(q, elevator);
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_ELEVATOR_CHANGE 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+	EXTRA_KCFLAGS="$tmp_flags"
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether sget() wants 5 args" >&5
+$as_echo_n "checking whether sget() wants 5 args... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/fs.h>
+
+int
+main (void)
+{
+
+		struct file_system_type *type = NULL;
+		int (*test)(struct super_block *,void *) = NULL;
+		int (*set)(struct super_block *,void *) = NULL;
+		int flags = 0;
+		void *data = NULL;
+		(void) sget(type, test, set, flags, data);
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_5ARG_SGET 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether lseek_execute() is available" >&5
+$as_echo_n "checking whether lseek_execute() is available... " >&6; }
+
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/fs.h>
+
+int
+main (void)
+{
+
+		struct file *fp __attribute__ ((unused)) = NULL;
+		struct inode *ip __attribute__ ((unused)) = NULL;
+		loff_t offset __attribute__ ((unused)) = 0;
+		loff_t maxsize __attribute__ ((unused)) = 0;
+
+		lseek_execute(fp, ip, offset, maxsize);
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+  rc=0
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+ rc=1
+
+
+fi
+	rm -Rf build
+
+
+	if test $rc -ne 0; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+	else
+		if test "x$enable_linux_builtin" != xyes; then
+
+	grep -q -E '[[:space:]]lseek_exclusive[[:space:]]' \
+		$LINUX_OBJ/$LINUX_SYMBOLS 2>/dev/null
+	rc=$?
+	if test $rc -ne 0; then
+		export=0
+		for file in fs/read_write.c; do
+			grep -q -E "EXPORT_SYMBOL.*(lseek_exclusive)" \
+				"$LINUX/$file" 2>/dev/null
+			rc=$?
+			if test $rc -eq 0; then
+				export=1
+				break;
+			fi
+		done
+		if test $export -eq 0; then :
+			rc=1
+		else :
+			rc=0
+		fi
+	else :
+		rc=0
+	fi
+
+		fi
+		if test $rc -ne 0; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+		else :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_LSEEK_EXECUTE 1" >>confdefs.h
+
+
+		fi
+	fi
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether fops->iterate() is available" >&5
+$as_echo_n "checking whether fops->iterate() is available... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/fs.h>
+		int iterate(struct file *filp, struct dir_context * context)
+		    { return 0; }
+
+		static const struct file_operations fops
+		    __attribute__ ((unused)) = {
+			.iterate	 = iterate,
+		};
+
+int
+main (void)
+{
+
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_VFS_ITERATE 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether fops->readdir() is available" >&5
+$as_echo_n "checking whether fops->readdir() is available... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+			#include <linux/fs.h>
+			int readdir(struct file *filp, void *entry, filldir_t func)
+			    { return 0; }
+
+			static const struct file_operations fops
+			    __attribute__ ((unused)) = {
+				.readdir = readdir,
+			};
+
+int
+main (void)
+{
+
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+			{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_VFS_READDIR 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+			as_fn_error $? "no; file a bug report with ZFSOnLinux" "$LINENO" 5
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+
+
+fi
+	rm -Rf build
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether fops->read/write_iter() are available" >&5
+$as_echo_n "checking whether fops->read/write_iter() are available... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/fs.h>
+
+		ssize_t test_read(struct kiocb *kiocb, struct iov_iter *to)
+		    { return 0; }
+		ssize_t test_write(struct kiocb *kiocb, struct iov_iter *from)
+		    { return 0; }
+
+		static const struct file_operations
+		    fops __attribute__ ((unused)) = {
+		    .read_iter = test_read,
+		    .write_iter = test_write,
+		};
+
+int
+main (void)
+{
+
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_VFS_RW_ITERATE 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether kmap_atomic wants 1 args" >&5
+$as_echo_n "checking whether kmap_atomic wants 1 args... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/pagemap.h>
+
+int
+main (void)
+{
+
+		struct page page;
+		kmap_atomic(&page);
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_1ARG_KMAP_ATOMIC 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether follow_down_one() is available" >&5
+$as_echo_n "checking whether follow_down_one() is available... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/namei.h>
+
+int
+main (void)
+{
+
+		struct path *p = NULL;
+		follow_down_one(p);
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_FOLLOW_DOWN_ONE 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether make_request_fn() returns int" >&5
+$as_echo_n "checking whether make_request_fn() returns int... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/blkdev.h>
+
+		int make_request(struct request_queue *q, struct bio *bio)
+		{
+			return (0);
+		}
+
+int
+main (void)
+{
+
+		blk_queue_make_request(NULL, &make_request);
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define MAKE_REQUEST_FN_RET int" >>confdefs.h
+
+
+$as_echo "#define HAVE_MAKE_REQUEST_FN_RET_INT 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether make_request_fn() returns void" >&5
+$as_echo_n "checking whether make_request_fn() returns void... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+			#include <linux/blkdev.h>
+
+			void make_request(struct request_queue *q, struct bio *bio)
+			{
+				return;
+			}
+
+int
+main (void)
+{
+
+			blk_queue_make_request(NULL, &make_request);
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+			{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define MAKE_REQUEST_FN_RET void" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+			{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+			{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether make_request_fn() returns blk_qc_t" >&5
+$as_echo_n "checking whether make_request_fn() returns blk_qc_t... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+				#include <linux/blkdev.h>
+
+				blk_qc_t make_request(struct request_queue *q, struct bio *bio)
+				{
+					return (BLK_QC_T_NONE);
+				}
+
+int
+main (void)
+{
+
+				blk_queue_make_request(NULL, &make_request);
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+				{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define MAKE_REQUEST_FN_RET blk_qc_t" >>confdefs.h
+
+
+$as_echo "#define HAVE_MAKE_REQUEST_FN_RET_QC 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+				as_fn_error $? "no - Please file a bug report at
+				    https://github.com/zfsonlinux/zfs/issues/new" "$LINENO" 5
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether generic IO accounting symbols are avaliable" >&5
+$as_echo_n "checking whether generic IO accounting symbols are avaliable... " >&6; }
+
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/bio.h>
+
+		void (*generic_start_io_acct_f)(int, unsigned long,
+		    struct hd_struct *) = &generic_start_io_acct;
+		void (*generic_end_io_acct_f)(int, struct hd_struct *,
+		    unsigned long) = &generic_end_io_acct;
+
+int
+main (void)
+{
+
+		generic_start_io_acct(0, 0, NULL);
+		generic_end_io_acct(0, NULL, 0);
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+  rc=0
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+ rc=1
+
+
+fi
+	rm -Rf build
+
+
+	if test $rc -ne 0; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+	else
+		if test "x$enable_linux_builtin" != xyes; then
+
+	grep -q -E '[[:space:]]generic_start_io_acct[[:space:]]' \
+		$LINUX_OBJ/$LINUX_SYMBOLS 2>/dev/null
+	rc=$?
+	if test $rc -ne 0; then
+		export=0
+		for file in block/bio.c; do
+			grep -q -E "EXPORT_SYMBOL.*(generic_start_io_acct)" \
+				"$LINUX/$file" 2>/dev/null
+			rc=$?
+			if test $rc -eq 0; then
+				export=1
+				break;
+			fi
+		done
+		if test $export -eq 0; then :
+			rc=1
+		else :
+			rc=0
+		fi
+	else :
+		rc=0
+	fi
+
+		fi
+		if test $rc -ne 0; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+		else :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_GENERIC_IO_ACCT 1" >>confdefs.h
+
+
+		fi
+	fi
+
+
+
+	if test "$LINUX_OBJ" != "$LINUX"; then :
+
+		KERNELMAKE_PARAMS="$KERNELMAKE_PARAMS O=$LINUX_OBJ"
+
+fi
+
+
+
+			KERNELCPPFLAGS="$KERNELCPPFLAGS $NO_UNUSED_BUT_SET_VARIABLE"
+	KERNELCPPFLAGS="$KERNELCPPFLAGS $NO_BOOL_COMPARE"
+	KERNELCPPFLAGS="$KERNELCPPFLAGS -DHAVE_SPL -D_KERNEL"
+	KERNELCPPFLAGS="$KERNELCPPFLAGS -DTEXT_DOMAIN=\\\"zfs-linux-kernel\\\""
+
+
+ ;;
+		all)
+
+
+# Check whether --with-linux was given.
+if test "${with_linux+set}" = set; then :
+  withval=$with_linux; kernelsrc="$withval"
+fi
+
+
+
+# Check whether --with-linux-obj was given.
+if test "${with_linux_obj+set}" = set; then :
+  withval=$with_linux_obj; kernelbuild="$withval"
+fi
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking kernel source directory" >&5
+$as_echo_n "checking kernel source directory... " >&6; }
+	if test -z "$kernelsrc"; then :
+
+		if test -e "/lib/modules/$(uname -r)/source"; then :
+
+			headersdir="/lib/modules/$(uname -r)/source"
+			sourcelink=$(readlink -f "$headersdir")
+
+elif test -e "/lib/modules/$(uname -r)/build"; then :
+
+			headersdir="/lib/modules/$(uname -r)/build"
+			sourcelink=$(readlink -f "$headersdir")
+
+else
+
+			sourcelink=$(ls -1d /usr/src/kernels/* \
+			             /usr/src/linux-* \
+			             2>/dev/null | grep -v obj | tail -1)
+
+fi
+
+		if test -n "$sourcelink" && test -e ${sourcelink}; then :
+
+			kernelsrc=`readlink -f ${sourcelink}`
+
+else
+
+			kernelsrc="Not found"
+
+fi
+
+else
+
+		if test "$kernelsrc" = "NONE"; then :
+
+			kernsrcver=NONE
+
+fi
+
+fi
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $kernelsrc" >&5
+$as_echo "$kernelsrc" >&6; }
+	if test ! -d "$kernelsrc"; then :
+
+		as_fn_error $? "
+	*** Please make sure the kernel devel package for your distribution
+	*** is installed and then try again.  If that fails, you can specify the
+	*** location of the kernel source with the '--with-linux=PATH' option." "$LINENO" 5
+
+fi
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking kernel build directory" >&5
+$as_echo_n "checking kernel build directory... " >&6; }
+	if test -z "$kernelbuild"; then :
+
+		if test -e "/lib/modules/$(uname -r)/build"; then :
+
+			kernelbuild=`readlink -f /lib/modules/$(uname -r)/build`
+
+elif test -d ${kernelsrc}-obj/${target_cpu}/${target_cpu}; then :
+
+			kernelbuild=${kernelsrc}-obj/${target_cpu}/${target_cpu}
+
+elif test -d ${kernelsrc}-obj/${target_cpu}/default; then :
+
+			kernelbuild=${kernelsrc}-obj/${target_cpu}/default
+
+elif test -d `dirname ${kernelsrc}`/build-${target_cpu}; then :
+
+			kernelbuild=`dirname ${kernelsrc}`/build-${target_cpu}
+
+else
+
+			kernelbuild=${kernelsrc}
+
+fi
+
+fi
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $kernelbuild" >&5
+$as_echo "$kernelbuild" >&6; }
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking kernel source version" >&5
+$as_echo_n "checking kernel source version... " >&6; }
+	utsrelease1=$kernelbuild/include/linux/version.h
+	utsrelease2=$kernelbuild/include/linux/utsrelease.h
+	utsrelease3=$kernelbuild/include/generated/utsrelease.h
+	if test -r $utsrelease1 && fgrep -q UTS_RELEASE $utsrelease1; then :
+
+		utsrelease=linux/version.h
+
+elif test -r $utsrelease2 && fgrep -q UTS_RELEASE $utsrelease2; then :
+
+		utsrelease=linux/utsrelease.h
+
+elif test -r $utsrelease3 && fgrep -q UTS_RELEASE $utsrelease3; then :
+
+		utsrelease=generated/utsrelease.h
+
+fi
+
+	if test "$utsrelease"; then :
+
+		kernsrcver=`(echo "#include <$utsrelease>";
+		             echo "kernsrcver=UTS_RELEASE") |
+		             cpp -I $kernelbuild/include |
+		             grep "^kernsrcver=" | cut -d \" -f 2`
+
+		if test -z "$kernsrcver"; then :
+
+			{ $as_echo "$as_me:${as_lineno-$LINENO}: result: Not found" >&5
+$as_echo "Not found" >&6; }
+			as_fn_error $? "*** Cannot determine kernel version." "$LINENO" 5
+
+fi
+
+else
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: Not found" >&5
+$as_echo "Not found" >&6; }
+		if test "x$enable_linux_builtin" != xyes; then
+			as_fn_error $? "*** Cannot find UTS_RELEASE definition." "$LINENO" 5
+		else
+			as_fn_error $? "
+	*** Cannot find UTS_RELEASE definition.
+	*** Please run 'make prepare' inside the kernel source tree." "$LINENO" 5
+		fi
+
+fi
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $kernsrcver" >&5
+$as_echo "$kernsrcver" >&6; }
+
+	LINUX=${kernelsrc}
+	LINUX_OBJ=${kernelbuild}
+	LINUX_VERSION=${kernsrcver}
+
+
+
+
+
+
+	modpost=$LINUX/scripts/Makefile.modpost
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking kernel file name for module symbols" >&5
+$as_echo_n "checking kernel file name for module symbols... " >&6; }
+	if test "x$enable_linux_builtin" != xyes -a -f "$modpost"; then :
+
+		if grep -q Modules.symvers $modpost; then :
+
+			LINUX_SYMBOLS=Modules.symvers
+
+else
+
+			LINUX_SYMBOLS=Module.symvers
+
+fi
+
+		if test ! -f "$LINUX_OBJ/$LINUX_SYMBOLS"; then :
+
+			as_fn_error $? "
+	*** Please make sure the kernel devel package for your distribution
+	*** is installed.  If you are building with a custom kernel, make sure the
+	*** kernel is configured, built, and the '--with-linux=PATH' configure
+	*** option refers to the location of the kernel source." "$LINENO" 5
+
+fi
+
+else
+
+		LINUX_SYMBOLS=NONE
+
+fi
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $LINUX_SYMBOLS" >&5
+$as_echo "$LINUX_SYMBOLS" >&6; }
+
+
+
+
+
+# Check whether --with-spl was given.
+if test "${with_spl+set}" = set; then :
+  withval=$with_spl; splsrc="$withval"
+fi
+
+
+
+# Check whether --with-spl-obj was given.
+if test "${with_spl_obj+set}" = set; then :
+  withval=$with_spl_obj; splbuild="$withval"
+fi
+
+
+
+# Check whether --with-spl-timeout was given.
+if test "${with_spl_timeout+set}" = set; then :
+  withval=$with_spl_timeout; timeout="$withval"
+else
+  timeout=0
+fi
+
+
+					splsrc0="/var/lib/dkms/spl/${VERSION}/build"
+	splsrc1="/usr/local/src/spl-${VERSION}/${LINUX_VERSION}"
+	splsrc2="/usr/local/src/spl-${VERSION}"
+	splsrc3="/usr/src/spl-${VERSION}/${LINUX_VERSION}"
+	splsrc4="/usr/src/spl-${VERSION}"
+	splsrc5="../spl/"
+	splsrc6="$LINUX"
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking spl source directory" >&5
+$as_echo_n "checking spl source directory... " >&6; }
+	if test -z "${splsrc}"; then :
+
+		if  test -e "${splsrc0}/spl.release.in"; then :
+
+			splsrc=${splsrc0}
+
+elif  test -e "${splsrc1}/spl.release.in"; then :
+
+			splsrc=${splsrc1}
+
+elif  test -e "${splsrc2}/spl.release.in"; then :
+
+			splsrc=${splsrc2}
+
+elif  test -e "${splsrc3}/spl.release.in"; then :
+
+			splsrc=$(readlink -f "${splsrc3}")
+
+elif  test -e "${splsrc4}/spl.release.in" ; then :
+
+			splsrc=${splsrc4}
+
+elif  test -e "${splsrc5}/spl.release.in"; then :
+
+			splsrc=$(readlink -f "${splsrc5}")
+
+elif  test -e "${splsrc6}/spl.release.in" ; then :
+
+			splsrc=${splsrc6}
+
+else
+
+			splsrc="Not found"
+
+fi
+
+else
+
+		if test "$splsrc" = "NONE"; then :
+
+			splbuild=NONE
+			splsrcver=NONE
+
+fi
+
+fi
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $splsrc" >&5
+$as_echo "$splsrc" >&6; }
+	if  test ! -e "$splsrc/spl.release.in"; then :
+
+		as_fn_error $? "
+	*** Please make sure the kmod spl devel package for your distribution
+	*** is installed then try again.  If that fails you can specify the
+	*** location of the spl source with the '--with-spl=PATH' option." "$LINENO" 5
+
+fi
+
+													{ $as_echo "$as_me:${as_lineno-$LINENO}: checking spl build directory" >&5
+$as_echo_n "checking spl build directory... " >&6; }
+	while true; do
+		if test -z "$splbuild"; then :
+
+			if  test -e "${splsrc}/${LINUX_VERSION}/spl_config.h" ; then :
+
+				splbuild="${splsrc}/${LINUX_VERSION}"
+
+elif  test -e "${splsrc}/spl_config.h" ; then :
+
+				splbuild="${splsrc}"
+
+elif  find -L "${splsrc}" -name spl_config.h 2> /dev/null | grep -wq spl_config.h ; then :
+
+				splbuild=$(find -L "${splsrc}" -name spl_config.h | sed 's,/spl_config.h,,')
+
+else
+
+				splbuild="Not found"
+
+fi
+
+fi
+		if test -e "$splbuild/spl_config.h" -o $timeout -le 0; then :
+
+			break;
+
+else
+
+			sleep 1
+			timeout=$((timeout-1))
+
+fi
+	done
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $splbuild" >&5
+$as_echo "$splbuild" >&6; }
+	if  ! test -e "$splbuild/spl_config.h"; then :
+
+		as_fn_error $? "
+	*** Please make sure the kmod spl devel <kernel> package for your
+	*** distribution is installed then try again.  If that fails you
+	*** can specify the location of the spl objects with the
+	*** '--with-spl-obj=PATH' option." "$LINENO" 5
+
+fi
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking spl source version" >&5
+$as_echo_n "checking spl source version... " >&6; }
+	if test -r $splbuild/spl_config.h &&
+		fgrep -q SPL_META_VERSION $splbuild/spl_config.h; then :
+
+
+		splsrcver=`(echo "#include <spl_config.h>";
+		            echo "splsrcver=SPL_META_VERSION-SPL_META_RELEASE") |
+		            cpp -I $splbuild |
+		            grep "^splsrcver=" | tr -d \" | cut -d= -f2`
+
+fi
+
+	if test -z "$splsrcver"; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: Not found" >&5
+$as_echo "Not found" >&6; }
+		as_fn_error $? "
+	*** Cannot determine the version of the spl source.
+	*** Please prepare the spl source before running this script" "$LINENO" 5
+
+fi
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $splsrcver" >&5
+$as_echo "$splsrcver" >&6; }
+
+	SPL=${splsrc}
+	SPL_OBJ=${splbuild}
+	SPL_VERSION=${splsrcver}
+
+
+
+
+
+														{ $as_echo "$as_me:${as_lineno-$LINENO}: checking spl file name for module symbols" >&5
+$as_echo_n "checking spl file name for module symbols... " >&6; }
+	SPL_SYMBOLS=NONE
+
+	while true; do
+		if test -r $SPL_OBJ/Module.symvers; then :
+
+			SPL_SYMBOLS=Module.symvers
+
+elif test -r $SPL_OBJ/Modules.symvers; then :
+
+			SPL_SYMBOLS=Modules.symvers
+
+elif test -r $SPL_OBJ/module/Module.symvers; then :
+
+			SPL_SYMBOLS=Module.symvers
+
+elif test -r $SPL_OBJ/module/Modules.symvers; then :
+
+			SPL_SYMBOLS=Modules.symvers
+
+fi
+
+		if test $SPL_SYMBOLS != NONE -o $timeout -le 0; then :
+
+			break;
+
+else
+
+			sleep 1
+			timeout=$((timeout-1))
+
+fi
+	done
+
+	if test "$SPL_SYMBOLS" = NONE; then :
+
+		SPL_SYMBOLS=$LINUX_SYMBOLS
+
+fi
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $SPL_SYMBOLS" >&5
+$as_echo "$SPL_SYMBOLS" >&6; }
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether modules can be built" >&5
+$as_echo_n "checking whether modules can be built... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+int
+main (void)
+{
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+		if test "x$enable_linux_builtin" != xyes; then
+			as_fn_error $? "*** Unable to build an empty module." "$LINENO" 5
+		else
+			as_fn_error $? "
+	*** Unable to build an empty module.
+	*** Please run 'make scripts' inside the kernel source tree." "$LINENO" 5
+		fi
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+	if test "x$cross_compiling" != xyes; then :
+
+		if test "$cross_compiling" = yes; then :
+  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot run test program while cross compiling
+See \`config.log' for more details" "$LINENO" 5; }
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+
+				#include "$LINUX/include/linux/license.h"
+
+int
+main ()
+{
+
+				return !license_is_gpl_compatible("$ZFS_META_LICENSE");
+
+  ;
+  return 0;
+}
+
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+
+
+$as_echo "#define ZFS_IS_GPL_COMPATIBLE 1" >>confdefs.h
+
+
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+
+fi
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether Linux was built with CONFIG_DEBUG_LOCK_ALLOC" >&5
+$as_echo_n "checking whether Linux was built with CONFIG_DEBUG_LOCK_ALLOC... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/module.h>
+
+int
+main (void)
+{
+
+		#ifndef CONFIG_DEBUG_LOCK_ALLOC
+		#error CONFIG_DEBUG_LOCK_ALLOC not #defined
+		#endif
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether mutex_lock() is GPL-only" >&5
+$as_echo_n "checking whether mutex_lock() is GPL-only... " >&6; }
+		tmp_flags="$EXTRA_KCFLAGS"
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+			#include <linux/module.h>
+			#include <linux/mutex.h>
+
+			MODULE_LICENSE("$ZFS_META_LICENSE");
+
+int
+main (void)
+{
+
+			struct mutex lock;
+
+			mutex_init(&lock);
+			mutex_lock(&lock);
+			mutex_unlock(&lock);
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+			{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+			{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+			as_fn_error $? "
+	*** Kernel built with CONFIG_DEBUG_LOCK_ALLOC which is incompatible
+	*** with the CDDL license and will prevent the module linking stage
+	*** from succeeding.  You must rebuild your kernel without this
+	*** option enabled." "$LINENO" 5
+
+
+
+fi
+	rm -Rf build
+
+
+		EXTRA_KCFLAGS="$tmp_flags"
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+
+
+	tmp_flags="$EXTRA_KCFLAGS"
+	EXTRA_KCFLAGS="-I\$(src)"
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether DECLARE_EVENT_CLASS() is available" >&5
+$as_echo_n "checking whether DECLARE_EVENT_CLASS() is available... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/module.h>
+		MODULE_LICENSE(ZFS_META_LICENSE);
+
+		#define CREATE_TRACE_POINTS
+		#include "conftest.h"
+
+int
+main (void)
+{
+
+		trace_zfs_autoconf_event_one(1UL);
+		trace_zfs_autoconf_event_two(2UL);
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+		#if !defined(_CONFTEST_H) || defined(TRACE_HEADER_MULTI_READ)
+		#define _CONFTEST_H
+
+		#undef  TRACE_SYSTEM
+		#define TRACE_SYSTEM zfs
+		#include <linux/tracepoint.h>
+
+		DECLARE_EVENT_CLASS(zfs_autoconf_event_class,
+			TP_PROTO(unsigned long i),
+			TP_ARGS(i),
+			TP_STRUCT__entry(
+				__field(unsigned long, i)
+			),
+			TP_fast_assign(
+				__entry->i = i;
+			),
+			TP_printk("i = %lu", __entry->i)
+		);
+
+		#define DEFINE_AUTOCONF_EVENT(name) \
+		DEFINE_EVENT(zfs_autoconf_event_class, name, \
+			TP_PROTO(unsigned long i), \
+			TP_ARGS(i))
+		DEFINE_AUTOCONF_EVENT(zfs_autoconf_event_one);
+		DEFINE_AUTOCONF_EVENT(zfs_autoconf_event_two);
+
+		#endif /* _CONFTEST_H */
+
+		#undef  TRACE_INCLUDE_PATH
+		#define TRACE_INCLUDE_PATH .
+		#define TRACE_INCLUDE_FILE conftest
+		#include <trace/define_trace.h>
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_DECLARE_EVENT_CLASS 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+	EXTRA_KCFLAGS="$tmp_flags"
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether current->bio_tail exists" >&5
+$as_echo_n "checking whether current->bio_tail exists... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/sched.h>
+
+int
+main (void)
+{
+
+		current->bio_tail = (struct bio **) NULL;
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_CURRENT_BIO_TAIL 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether current->bio_list exists" >&5
+$as_echo_n "checking whether current->bio_list exists... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+			#include <linux/sched.h>
+
+int
+main (void)
+{
+
+			current->bio_list = (struct bio_list *) NULL;
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+			{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_CURRENT_BIO_LIST 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+			as_fn_error $? "no - Please file a bug report at
+			    https://github.com/zfsonlinux/zfs/issues/new" "$LINENO" 5
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking block device operation prototypes" >&5
+$as_echo_n "checking block device operation prototypes... " >&6; }
+	tmp_flags="$EXTRA_KCFLAGS"
+	EXTRA_KCFLAGS="${NO_UNUSED_BUT_SET_VARIABLE}"
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/blkdev.h>
+
+		int blk_open(struct block_device *bdev, fmode_t mode)
+		    { return 0; }
+		int blk_ioctl(struct block_device *bdev, fmode_t mode,
+		    unsigned x, unsigned long y) { return 0; }
+		int blk_compat_ioctl(struct block_device * bdev, fmode_t mode,
+		    unsigned x, unsigned long y) { return 0; }
+
+		static const struct block_device_operations
+		    bops __attribute__ ((unused)) = {
+			.open		= blk_open,
+			.release	= NULL,
+			.ioctl		= blk_ioctl,
+			.compat_ioctl	= blk_compat_ioctl,
+		};
+
+int
+main (void)
+{
+
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: struct block_device" >&5
+$as_echo "struct block_device" >&6; }
+
+$as_echo "#define HAVE_BDEV_BLOCK_DEVICE_OPERATIONS 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: struct inode" >&5
+$as_echo "struct inode" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+	EXTRA_KCFLAGS="$tmp_flags"
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether block_device_operations.release is void" >&5
+$as_echo_n "checking whether block_device_operations.release is void... " >&6; }
+	tmp_flags="$EXTRA_KCFLAGS"
+	EXTRA_KCFLAGS="${NO_UNUSED_BUT_SET_VARIABLE}"
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/blkdev.h>
+
+		void blk_release(struct gendisk *g, fmode_t mode) { return; }
+
+		static const struct block_device_operations
+		    bops __attribute__ ((unused)) = {
+			.open		= NULL,
+			.release	= blk_release,
+			.ioctl		= NULL,
+			.compat_ioctl	= NULL,
+		};
+
+int
+main (void)
+{
+
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: void" >&5
+$as_echo "void" >&6; }
+
+$as_echo "#define HAVE_BLOCK_DEVICE_OPERATIONS_RELEASE_VOID 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: int" >&5
+$as_echo "int" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+	EXTRA_KCFLAGS="$tmp_flags"
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether kernel defines fmode_t" >&5
+$as_echo_n "checking whether kernel defines fmode_t... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/types.h>
+
+int
+main (void)
+{
+
+		fmode_t *ptr __attribute__ ((unused));
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_FMODE_T 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether kernel defines KOBJ_NAME_LEN" >&5
+$as_echo_n "checking whether kernel defines KOBJ_NAME_LEN... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/kobject.h>
+
+int
+main (void)
+{
+
+		int val __attribute__ ((unused));
+		val = KOBJ_NAME_LEN;
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_KOBJ_NAME_LEN 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether blkdev_get() wants 3 args" >&5
+$as_echo_n "checking whether blkdev_get() wants 3 args... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/fs.h>
+
+int
+main (void)
+{
+
+		struct block_device *bdev = NULL;
+		(void) blkdev_get(bdev, 0, NULL);
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_3ARG_BLKDEV_GET 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether blkdev_get_by_path() is available" >&5
+$as_echo_n "checking whether blkdev_get_by_path() is available... " >&6; }
+
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/fs.h>
+
+int
+main (void)
+{
+
+		blkdev_get_by_path(NULL, 0, NULL);
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+  rc=0
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+ rc=1
+
+
+fi
+	rm -Rf build
+
+
+	if test $rc -ne 0; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+	else
+		if test "x$enable_linux_builtin" != xyes; then
+
+	grep -q -E '[[:space:]]blkdev_get_by_path[[:space:]]' \
+		$LINUX_OBJ/$LINUX_SYMBOLS 2>/dev/null
+	rc=$?
+	if test $rc -ne 0; then
+		export=0
+		for file in fs/block_dev.c; do
+			grep -q -E "EXPORT_SYMBOL.*(blkdev_get_by_path)" \
+				"$LINUX/$file" 2>/dev/null
+			rc=$?
+			if test $rc -eq 0; then
+				export=1
+				break;
+			fi
+		done
+		if test $export -eq 0; then :
+			rc=1
+		else :
+			rc=0
+		fi
+	else :
+		rc=0
+	fi
+
+		fi
+		if test $rc -ne 0; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+		else :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_BLKDEV_GET_BY_PATH 1" >>confdefs.h
+
+
+		fi
+	fi
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether open_bdev_exclusive() is available" >&5
+$as_echo_n "checking whether open_bdev_exclusive() is available... " >&6; }
+
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/fs.h>
+
+int
+main (void)
+{
+
+		open_bdev_exclusive(NULL, 0, NULL);
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+  rc=0
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+ rc=1
+
+
+fi
+	rm -Rf build
+
+
+	if test $rc -ne 0; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+	else
+		if test "x$enable_linux_builtin" != xyes; then
+
+	grep -q -E '[[:space:]]open_bdev_exclusive[[:space:]]' \
+		$LINUX_OBJ/$LINUX_SYMBOLS 2>/dev/null
+	rc=$?
+	if test $rc -ne 0; then
+		export=0
+		for file in fs/block_dev.c; do
+			grep -q -E "EXPORT_SYMBOL.*(open_bdev_exclusive)" \
+				"$LINUX/$file" 2>/dev/null
+			rc=$?
+			if test $rc -eq 0; then
+				export=1
+				break;
+			fi
+		done
+		if test $export -eq 0; then :
+			rc=1
+		else :
+			rc=0
+		fi
+	else :
+		rc=0
+	fi
+
+		fi
+		if test $rc -ne 0; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+		else :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_OPEN_BDEV_EXCLUSIVE 1" >>confdefs.h
+
+
+		fi
+	fi
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether lookup_bdev() is available" >&5
+$as_echo_n "checking whether lookup_bdev() is available... " >&6; }
+
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/fs.h>
+
+int
+main (void)
+{
+
+		lookup_bdev(NULL);
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+  rc=0
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+ rc=1
+
+
+fi
+	rm -Rf build
+
+
+	if test $rc -ne 0; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+	else
+		if test "x$enable_linux_builtin" != xyes; then
+
+	grep -q -E '[[:space:]]lookup_bdev[[:space:]]' \
+		$LINUX_OBJ/$LINUX_SYMBOLS 2>/dev/null
+	rc=$?
+	if test $rc -ne 0; then
+		export=0
+		for file in fs/block_dev.c; do
+			grep -q -E "EXPORT_SYMBOL.*(lookup_bdev)" \
+				"$LINUX/$file" 2>/dev/null
+			rc=$?
+			if test $rc -eq 0; then
+				export=1
+				break;
+			fi
+		done
+		if test $export -eq 0; then :
+			rc=1
+		else :
+			rc=0
+		fi
+	else :
+		rc=0
+	fi
+
+		fi
+		if test $rc -ne 0; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+		else :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_LOOKUP_BDEV 1" >>confdefs.h
+
+
+		fi
+	fi
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether invalidate_bdev() wants 1 arg" >&5
+$as_echo_n "checking whether invalidate_bdev() wants 1 arg... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/buffer_head.h>
+
+int
+main (void)
+{
+
+		struct block_device *bdev = NULL;
+		invalidate_bdev(bdev);
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_1ARG_INVALIDATE_BDEV 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether bdev_logical_block_size() is available" >&5
+$as_echo_n "checking whether bdev_logical_block_size() is available... " >&6; }
+	tmp_flags="$EXTRA_KCFLAGS"
+	EXTRA_KCFLAGS="${NO_UNUSED_BUT_SET_VARIABLE}"
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/blkdev.h>
+
+int
+main (void)
+{
+
+		struct block_device *bdev = NULL;
+		bdev_logical_block_size(bdev);
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_BDEV_LOGICAL_BLOCK_SIZE 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+	EXTRA_KCFLAGS="$tmp_flags"
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether bdev_physical_block_size() is available" >&5
+$as_echo_n "checking whether bdev_physical_block_size() is available... " >&6; }
+	tmp_flags="$EXTRA_KCFLAGS"
+	EXTRA_KCFLAGS="${NO_UNUSED_BUT_SET_VARIABLE}"
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/blkdev.h>
+
+int
+main (void)
+{
+
+		struct block_device *bdev = NULL;
+		bdev_physical_block_size(bdev);
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_BDEV_PHYSICAL_BLOCK_SIZE 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+	EXTRA_KCFLAGS="$tmp_flags"
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether bio has bi_iter" >&5
+$as_echo_n "checking whether bio has bi_iter... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/bio.h>
+
+int
+main (void)
+{
+
+		struct bio bio;
+		bio.bi_iter.bi_sector = 0;
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_BIO_BVEC_ITER 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether BIO_RW_FAILFAST_* are defined" >&5
+$as_echo_n "checking whether BIO_RW_FAILFAST_* are defined... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/bio.h>
+
+int
+main (void)
+{
+
+		int flags __attribute__ ((unused));
+		flags = ((1 << BIO_RW_FAILFAST_DEV) |
+			 (1 << BIO_RW_FAILFAST_TRANSPORT) |
+			 (1 << BIO_RW_FAILFAST_DRIVER));
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_BIO_RW_FAILFAST_DTD 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether REQ_FAILFAST_MASK is defined" >&5
+$as_echo_n "checking whether REQ_FAILFAST_MASK is defined... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/bio.h>
+
+int
+main (void)
+{
+
+		int flags __attribute__ ((unused));
+		flags = REQ_FAILFAST_MASK;
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_REQ_FAILFAST_MASK 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether bio_end_io_t wants 1 arg" >&5
+$as_echo_n "checking whether bio_end_io_t wants 1 arg... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/bio.h>
+
+		void wanted_end_io(struct bio *bio) { return; }
+
+		bio_end_io_t *end_io __attribute__ ((unused)) = wanted_end_io;
+
+int
+main (void)
+{
+
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_1ARG_BIO_END_IO_T 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether BIO_RW_BARRIER is defined" >&5
+$as_echo_n "checking whether BIO_RW_BARRIER is defined... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/bio.h>
+
+int
+main (void)
+{
+
+		int flags __attribute__ ((unused));
+		flags = BIO_RW_BARRIER;
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_BIO_RW_BARRIER 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether BIO_RW_DISCARD is defined" >&5
+$as_echo_n "checking whether BIO_RW_DISCARD is defined... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/bio.h>
+
+int
+main (void)
+{
+
+		int flags __attribute__ ((unused));
+		flags = BIO_RW_DISCARD;
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_BIO_RW_DISCARD 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether blk_queue_flush() is available" >&5
+$as_echo_n "checking whether blk_queue_flush() is available... " >&6; }
+	tmp_flags="$EXTRA_KCFLAGS"
+	EXTRA_KCFLAGS="${NO_UNUSED_BUT_SET_VARIABLE}"
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/blkdev.h>
+
+int
+main (void)
+{
+
+		struct request_queue *q = NULL;
+		(void) blk_queue_flush(q, REQ_FLUSH);
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_BLK_QUEUE_FLUSH 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether blk_queue_flush() is GPL-only" >&5
+$as_echo_n "checking whether blk_queue_flush() is GPL-only... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/module.h>
+		#include <linux/blkdev.h>
+
+		MODULE_LICENSE("$ZFS_META_LICENSE");
+
+int
+main (void)
+{
+
+		struct request_queue *q = NULL;
+		(void) blk_queue_flush(q, REQ_FLUSH);
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_BLK_QUEUE_FLUSH_GPL_ONLY 1" >>confdefs.h
+
+
+
+
+fi
+	rm -Rf build
+
+
+	EXTRA_KCFLAGS="$tmp_flags"
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether blk_queue_max_hw_sectors() is available" >&5
+$as_echo_n "checking whether blk_queue_max_hw_sectors() is available... " >&6; }
+	tmp_flags="$EXTRA_KCFLAGS"
+	EXTRA_KCFLAGS="${NO_UNUSED_BUT_SET_VARIABLE}"
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/blkdev.h>
+
+int
+main (void)
+{
+
+		struct request_queue *q = NULL;
+		(void) blk_queue_max_hw_sectors(q, BLK_SAFE_MAX_SECTORS);
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_BLK_QUEUE_MAX_HW_SECTORS 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+	EXTRA_KCFLAGS="$tmp_flags"
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether blk_queue_max_segments() is available" >&5
+$as_echo_n "checking whether blk_queue_max_segments() is available... " >&6; }
+	tmp_flags="$EXTRA_KCFLAGS"
+	EXTRA_KCFLAGS="${NO_UNUSED_BUT_SET_VARIABLE}"
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/blkdev.h>
+
+int
+main (void)
+{
+
+		struct request_queue *q = NULL;
+		(void) blk_queue_max_segments(q, BLK_MAX_SEGMENTS);
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_BLK_QUEUE_MAX_SEGMENTS 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+	EXTRA_KCFLAGS="$tmp_flags"
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether get_disk_ro() is available" >&5
+$as_echo_n "checking whether get_disk_ro() is available... " >&6; }
+	tmp_flags="$EXTRA_KCFLAGS"
+	EXTRA_KCFLAGS="${NO_UNUSED_BUT_SET_VARIABLE}"
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/blkdev.h>
+
+int
+main (void)
+{
+
+		struct gendisk *disk = NULL;
+		(void) get_disk_ro(disk);
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_GET_DISK_RO 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+	EXTRA_KCFLAGS="$tmp_flags"
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether get_gendisk() is available" >&5
+$as_echo_n "checking whether get_gendisk() is available... " >&6; }
+
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/genhd.h>
+
+int
+main (void)
+{
+
+		get_gendisk(0, NULL);
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+  rc=0
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+ rc=1
+
+
+fi
+	rm -Rf build
+
+
+	if test $rc -ne 0; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+	else
+		if test "x$enable_linux_builtin" != xyes; then
+
+	grep -q -E '[[:space:]]get_gendisk[[:space:]]' \
+		$LINUX_OBJ/$LINUX_SYMBOLS 2>/dev/null
+	rc=$?
+	if test $rc -ne 0; then
+		export=0
+		for file in block/genhd.c; do
+			grep -q -E "EXPORT_SYMBOL.*(get_gendisk)" \
+				"$LINUX/$file" 2>/dev/null
+			rc=$?
+			if test $rc -eq 0; then
+				export=1
+				break;
+			fi
+		done
+		if test $export -eq 0; then :
+			rc=1
+		else :
+			rc=0
+		fi
+	else :
+		rc=0
+	fi
+
+		fi
+		if test $rc -ne 0; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+		else :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_GET_GENDISK 1" >>confdefs.h
+
+
+		fi
+	fi
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ql->discard_granularity is available" >&5
+$as_echo_n "checking whether ql->discard_granularity is available... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/blkdev.h>
+
+int
+main (void)
+{
+
+		struct queue_limits ql __attribute__ ((unused));
+
+		ql.discard_granularity = 0;
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_DISCARD_GRANULARITY 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether super_block uses const struct xattr_handler" >&5
+$as_echo_n "checking whether super_block uses const struct xattr_handler... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/fs.h>
+		#include <linux/xattr.h>
+
+		const struct xattr_handler xattr_test_handler = {
+			.prefix	= "test",
+			.get	= NULL,
+			.set	= NULL,
+		};
+
+		const struct xattr_handler *xattr_handlers[] = {
+			&xattr_test_handler,
+		};
+
+		const struct super_block sb __attribute__ ((unused)) = {
+			.s_xattr = xattr_handlers,
+		};
+
+int
+main (void)
+{
+
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_CONST_XATTR_HANDLER 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+							{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether xattr_handler->get() wants xattr_handler" >&5
+$as_echo_n "checking whether xattr_handler->get() wants xattr_handler... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/xattr.h>
+
+		int get(const struct xattr_handler *handler,
+		    struct dentry *dentry, const char *name,
+		    void *buffer, size_t size) { return 0; }
+		static const struct xattr_handler
+		    xops __attribute__ ((unused)) = {
+			.get = get,
+		};
+
+int
+main (void)
+{
+
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_XATTR_GET_HANDLER 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+														{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether xattr_handler->get() wants dentry" >&5
+$as_echo_n "checking whether xattr_handler->get() wants dentry... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+			#include <linux/xattr.h>
+
+			int get(struct dentry *dentry, const char *name,
+			    void *buffer, size_t size, int handler_flags)
+			    { return 0; }
+			static const struct xattr_handler
+			    xops __attribute__ ((unused)) = {
+				.get = get,
+			};
+
+int
+main (void)
+{
+
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+			{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_XATTR_GET_DENTRY 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+												{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+			{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether xattr_handler->get() wants inode" >&5
+$as_echo_n "checking whether xattr_handler->get() wants inode... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+				#include <linux/xattr.h>
+
+				int get(struct inode *ip, const char *name,
+				    void *buffer, size_t size) { return 0; }
+				static const struct xattr_handler
+				    xops __attribute__ ((unused)) = {
+					.get = get,
+				};
+
+int
+main (void)
+{
+
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+				{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_XATTR_GET_INODE 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	                        as_fn_error $? "no; please file a bug report" "$LINENO" 5
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+							{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether xattr_handler->set() wants xattr_handler" >&5
+$as_echo_n "checking whether xattr_handler->set() wants xattr_handler... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/xattr.h>
+
+		int set(const struct xattr_handler *handler,
+		    struct dentry *dentry, const char *name,
+		    const void *buffer, size_t size, int flags)
+		    { return 0; }
+		static const struct xattr_handler
+		    xops __attribute__ ((unused)) = {
+			.set = set,
+		};
+
+int
+main (void)
+{
+
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_XATTR_SET_HANDLER 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+														{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether xattr_handler->set() wants dentry" >&5
+$as_echo_n "checking whether xattr_handler->set() wants dentry... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+			#include <linux/xattr.h>
+
+			int set(struct dentry *dentry, const char *name,
+			    const void *buffer, size_t size, int flags,
+			    int handler_flags) { return 0; }
+			static const struct xattr_handler
+			    xops __attribute__ ((unused)) = {
+				.set = set,
+			};
+
+int
+main (void)
+{
+
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+			{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_XATTR_SET_DENTRY 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+												{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+			{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether xattr_handler->set() wants inode" >&5
+$as_echo_n "checking whether xattr_handler->set() wants inode... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+				#include <linux/xattr.h>
+
+				int set(struct inode *ip, const char *name,
+				    const void *buffer, size_t size, int flags)
+				    { return 0; }
+				static const struct xattr_handler
+				    xops __attribute__ ((unused)) = {
+					.set = set,
+				};
+
+int
+main (void)
+{
+
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+				{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_XATTR_SET_INODE 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	                        as_fn_error $? "no; please file a bug report" "$LINENO" 5
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+				{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether xattr_handler->list() wants simple" >&5
+$as_echo_n "checking whether xattr_handler->list() wants simple... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/xattr.h>
+
+		bool list(struct dentry *dentry) { return 0; }
+		static const struct xattr_handler
+		    xops __attribute__ ((unused)) = {
+			.list = list,
+		};
+
+int
+main (void)
+{
+
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_XATTR_LIST_SIMPLE 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+														{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether xattr_handler->list() wants xattr_handler" >&5
+$as_echo_n "checking whether xattr_handler->list() wants xattr_handler... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+			#include <linux/xattr.h>
+
+			size_t list(const struct xattr_handler *handler,
+			    struct dentry *dentry, char *list, size_t list_size,
+			    const char *name, size_t name_len) { return 0; }
+			static const struct xattr_handler
+			    xops __attribute__ ((unused)) = {
+				.list = list,
+			};
+
+int
+main (void)
+{
+
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+			{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_XATTR_LIST_HANDLER 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+																					{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+			{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether xattr_handler->list() wants dentry" >&5
+$as_echo_n "checking whether xattr_handler->list() wants dentry... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+				#include <linux/xattr.h>
+
+				size_t list(struct dentry *dentry,
+				    char *list, size_t list_size,
+				    const char *name, size_t name_len,
+				    int handler_flags) { return 0; }
+				static const struct xattr_handler
+				    xops __attribute__ ((unused)) = {
+					.list = list,
+				};
+
+int
+main (void)
+{
+
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+				{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_XATTR_LIST_DENTRY 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+																{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+				{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether xattr_handler->list() wants inode" >&5
+$as_echo_n "checking whether xattr_handler->list() wants inode... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+					#include <linux/xattr.h>
+
+					size_t list(struct inode *ip, char *lst,
+					    size_t list_size, const char *name,
+					    size_t name_len) { return 0; }
+					static const struct xattr_handler
+					    xops __attribute__ ((unused)) = {
+						.list = list,
+					};
+
+int
+main (void)
+{
+
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+					{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_XATTR_LIST_INODE 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		                        as_fn_error $? "no; please file a bug report" "$LINENO" 5
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether inode_owner_or_capable() exists" >&5
+$as_echo_n "checking whether inode_owner_or_capable() exists... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/fs.h>
+
+int
+main (void)
+{
+
+		struct inode *ip = NULL;
+		(void) inode_owner_or_capable(ip);
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_INODE_OWNER_OR_CAPABLE 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether is_owner_or_cap() exists" >&5
+$as_echo_n "checking whether is_owner_or_cap() exists... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+			#include <linux/fs.h>
+			#include <linux/sched.h>
+
+int
+main (void)
+{
+
+			struct inode *ip = NULL;
+			(void) is_owner_or_cap(ip);
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+			{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_IS_OWNER_OR_CAP 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+			as_fn_error $? "no - Please file a bug report at
+			    https://github.com/zfsonlinux/zfs/issues/new" "$LINENO" 5
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether posix_acl_from_xattr() needs user_ns" >&5
+$as_echo_n "checking whether posix_acl_from_xattr() needs user_ns... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/cred.h>
+		#include <linux/fs.h>
+		#include <linux/posix_acl_xattr.h>
+
+int
+main (void)
+{
+
+		posix_acl_from_xattr(&init_user_ns, NULL, 0);
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_POSIX_ACL_FROM_XATTR_USERNS 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether posix_acl_release() is available" >&5
+$as_echo_n "checking whether posix_acl_release() is available... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/cred.h>
+		#include <linux/fs.h>
+		#include <linux/posix_acl.h>
+
+int
+main (void)
+{
+
+		struct posix_acl* tmp = posix_acl_alloc(1, 0);
+		posix_acl_release(tmp);
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_POSIX_ACL_RELEASE 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether posix_acl_release() is GPL-only" >&5
+$as_echo_n "checking whether posix_acl_release() is GPL-only... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/cred.h>
+		#include <linux/fs.h>
+		#include <linux/posix_acl.h>
+
+		MODULE_LICENSE("$ZFS_META_LICENSE");
+
+int
+main (void)
+{
+
+		struct posix_acl* tmp = posix_acl_alloc(1, 0);
+		posix_acl_release(tmp);
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_POSIX_ACL_RELEASE_GPL_ONLY 1" >>confdefs.h
+
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether posix_acl_chmod exists" >&5
+$as_echo_n "checking whether posix_acl_chmod exists... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/fs.h>
+		#include <linux/posix_acl.h>
+
+int
+main (void)
+{
+
+		posix_acl_chmod(NULL, 0, 0)
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_POSIX_ACL_CHMOD 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether __posix_acl_chmod exists" >&5
+$as_echo_n "checking whether __posix_acl_chmod exists... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/fs.h>
+		#include <linux/posix_acl.h>
+
+int
+main (void)
+{
+
+		__posix_acl_chmod(NULL, 0, 0)
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE___POSIX_ACL_CHMOD 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether inode has i_acl and i_default_acl" >&5
+$as_echo_n "checking whether inode has i_acl and i_default_acl... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/fs.h>
+
+int
+main (void)
+{
+
+		struct inode ino;
+		ino.i_acl = NULL;
+		ino.i_default_acl = NULL;
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_POSIX_ACL_CACHING 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether posix_acl_equiv_mode() wants umode_t" >&5
+$as_echo_n "checking whether posix_acl_equiv_mode() wants umode_t... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/fs.h>
+		#include <linux/posix_acl.h>
+
+int
+main (void)
+{
+
+		umode_t tmp;
+		posix_acl_equiv_mode(NULL,&tmp);
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_POSIX_ACL_EQUIV_MODE_UMODE_T 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether iops->permission() exists" >&5
+$as_echo_n "checking whether iops->permission() exists... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/fs.h>
+
+		int permission_fn(struct inode *inode, int mask) { return 0; }
+
+		static const struct inode_operations
+		    iops __attribute__ ((unused)) = {
+			.permission = permission_fn,
+		};
+
+int
+main (void)
+{
+
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_PERMISSION 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether iops->permission() wants nameidata" >&5
+$as_echo_n "checking whether iops->permission() wants nameidata... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/fs.h>
+
+		int permission_fn(struct inode *inode, int mask,
+		    struct nameidata *nd) { return 0; }
+
+		static const struct inode_operations
+		    iops __attribute__ ((unused)) = {
+			.permission = permission_fn,
+		};
+
+int
+main (void)
+{
+
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_PERMISSION 1" >>confdefs.h
+
+
+$as_echo "#define HAVE_PERMISSION_WITH_NAMEIDATA 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether iops->check_acl() exists" >&5
+$as_echo_n "checking whether iops->check_acl() exists... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/fs.h>
+
+		int check_acl_fn(struct inode *inode, int mask) { return 0; }
+
+		static const struct inode_operations
+		    iops __attribute__ ((unused)) = {
+			.check_acl = check_acl_fn,
+		};
+
+int
+main (void)
+{
+
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_CHECK_ACL 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether iops->check_acl() wants flags" >&5
+$as_echo_n "checking whether iops->check_acl() wants flags... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/fs.h>
+
+		int check_acl_fn(struct inode *inode, int mask,
+		    unsigned int flags) { return 0; }
+
+		static const struct inode_operations
+		    iops __attribute__ ((unused)) = {
+			.check_acl = check_acl_fn,
+		};
+
+int
+main (void)
+{
+
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_CHECK_ACL 1" >>confdefs.h
+
+
+$as_echo "#define HAVE_CHECK_ACL_WITH_FLAGS 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether iops->get_acl() exists" >&5
+$as_echo_n "checking whether iops->get_acl() exists... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/fs.h>
+
+		struct posix_acl *get_acl_fn(struct inode *inode, int type)
+		    { return NULL; }
+
+		static const struct inode_operations
+		    iops __attribute__ ((unused)) = {
+			.get_acl = get_acl_fn,
+		};
+
+int
+main (void)
+{
+
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_GET_ACL 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether current_umask exists" >&5
+$as_echo_n "checking whether current_umask exists... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/fs.h>
+
+int
+main (void)
+{
+
+		current_umask();
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_CURRENT_UMASK 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether sops->show_options() wants dentry" >&5
+$as_echo_n "checking whether sops->show_options() wants dentry... " >&6; }
+
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/fs.h>
+
+		int show_options (struct seq_file * x, struct dentry * y) { return 0; };
+		static struct super_operations sops __attribute__ ((unused)) = {
+			.show_options = show_options,
+		};
+
+int
+main (void)
+{
+
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_SHOW_OPTIONS_WITH_DENTRY 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether file_inode() is available" >&5
+$as_echo_n "checking whether file_inode() is available... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/fs.h>
+
+int
+main (void)
+{
+
+		struct file *f = NULL;
+		file_inode(f);
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_FILE_INODE 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether fops->fsync() wants" >&5
+$as_echo_n "checking whether fops->fsync() wants... " >&6; }
+
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/fs.h>
+
+		int test_fsync(struct file *f, struct dentry *dentry, int x)
+		    { return 0; }
+
+		static const struct file_operations
+		    fops __attribute__ ((unused)) = {
+			.fsync = test_fsync,
+		};
+
+int
+main (void)
+{
+
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: dentry" >&5
+$as_echo "dentry" >&6; }
+
+$as_echo "#define HAVE_FSYNC_WITH_DENTRY 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/fs.h>
+
+		int test_fsync(struct file *f, int x) { return 0; }
+
+		static const struct file_operations
+		    fops __attribute__ ((unused)) = {
+			.fsync = test_fsync,
+		};
+
+int
+main (void)
+{
+
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no dentry" >&5
+$as_echo "no dentry" >&6; }
+
+$as_echo "#define HAVE_FSYNC_WITHOUT_DENTRY 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/fs.h>
+
+		int test_fsync(struct file *f, loff_t a, loff_t b, int c)
+		    { return 0; }
+
+		static const struct file_operations
+		    fops __attribute__ ((unused)) = {
+			.fsync = test_fsync,
+		};
+
+int
+main (void)
+{
+
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: range" >&5
+$as_echo "range" >&6; }
+
+$as_echo "#define HAVE_FSYNC_RANGE 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether sops->evict_inode() exists" >&5
+$as_echo_n "checking whether sops->evict_inode() exists... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/fs.h>
+		void evict_inode (struct inode * t) { return; }
+		static struct super_operations sops __attribute__ ((unused)) = {
+			.evict_inode = evict_inode,
+		};
+
+int
+main (void)
+{
+
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_EVICT_INODE 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether sops->dirty_inode() wants flags" >&5
+$as_echo_n "checking whether sops->dirty_inode() wants flags... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/fs.h>
+
+		void dirty_inode(struct inode *a, int b) { return; }
+
+		static const struct super_operations
+		    sops __attribute__ ((unused)) = {
+			.dirty_inode = dirty_inode,
+		};
+
+int
+main (void)
+{
+
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_DIRTY_INODE_WITH_FLAGS 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether sops->nr_cached_objects() exists" >&5
+$as_echo_n "checking whether sops->nr_cached_objects() exists... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/fs.h>
+
+		int nr_cached_objects(struct super_block *sb) { return 0; }
+
+		static const struct super_operations
+		    sops __attribute__ ((unused)) = {
+			.nr_cached_objects = nr_cached_objects,
+		};
+
+int
+main (void)
+{
+
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_NR_CACHED_OBJECTS 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether sops->free_cached_objects() exists" >&5
+$as_echo_n "checking whether sops->free_cached_objects() exists... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/fs.h>
+
+		void free_cached_objects(struct super_block *sb, int x)
+		    { return; }
+
+		static const struct super_operations
+		    sops __attribute__ ((unused)) = {
+			.free_cached_objects = free_cached_objects,
+		};
+
+int
+main (void)
+{
+
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_FREE_CACHED_OBJECTS 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether fops->fallocate() exists" >&5
+$as_echo_n "checking whether fops->fallocate() exists... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/fs.h>
+
+		long test_fallocate(struct file *file, int mode,
+		    loff_t offset, loff_t len) { return 0; }
+
+		static const struct file_operations
+		    fops __attribute__ ((unused)) = {
+			.fallocate = test_fallocate,
+		};
+
+int
+main (void)
+{
+
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_FILE_FALLOCATE 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether iops->fallocate() exists" >&5
+$as_echo_n "checking whether iops->fallocate() exists... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/fs.h>
+
+		long test_fallocate(struct inode *inode, int mode,
+		    loff_t offset, loff_t len) { return 0; }
+
+		static const struct inode_operations
+		    fops __attribute__ ((unused)) = {
+			.fallocate = test_fallocate,
+		};
+
+int
+main (void)
+{
+
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_INODE_FALLOCATE 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether iops->create()/mkdir()/mknod() take umode_t" >&5
+$as_echo_n "checking whether iops->create()/mkdir()/mknod() take umode_t... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/fs.h>
+
+		int mkdir(struct inode *inode, struct dentry *dentry,
+		    umode_t umode) { return 0; }
+
+		static const struct inode_operations
+		    iops __attribute__ ((unused)) = {
+			.mkdir = mkdir,
+		};
+
+int
+main (void)
+{
+
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_MKDIR_UMODE_T 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether iops->lookup() passes nameidata" >&5
+$as_echo_n "checking whether iops->lookup() passes nameidata... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/fs.h>
+
+		struct dentry *inode_lookup(struct inode *inode,
+		    struct dentry *dentry, struct nameidata *nidata)
+		    { return NULL; }
+
+		static const struct inode_operations iops
+		    __attribute__ ((unused)) = {
+			.lookup	= inode_lookup,
+		};
+
+int
+main (void)
+{
+
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_LOOKUP_NAMEIDATA 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether iops->create() passes nameidata" >&5
+$as_echo_n "checking whether iops->create() passes nameidata... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/fs.h>
+
+		#ifdef HAVE_MKDIR_UMODE_T
+		int inode_create(struct inode *inode ,struct dentry *dentry,
+		    umode_t umode, struct nameidata *nidata) { return 0; }
+		#else
+		int inode_create(struct inode *inode,struct dentry *dentry,
+		    int umode, struct nameidata * nidata) { return 0; }
+		#endif
+
+		static const struct inode_operations
+		    iops __attribute__ ((unused)) = {
+			.create		= inode_create,
+		};
+
+int
+main (void)
+{
+
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_CREATE_NAMEIDATA 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+						{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether iops->get_link() passes delayed" >&5
+$as_echo_n "checking whether iops->get_link() passes delayed... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/fs.h>
+		const char *get_link(struct dentry *de, struct inode *ip,
+		    struct delayed_call *done) { return "symlink"; }
+		static struct inode_operations
+		     iops __attribute__ ((unused)) = {
+			.get_link = get_link,
+		};
+
+int
+main (void)
+{
+
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_GET_LINK_DELAYED 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+																{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether iops->get_link() passes cookie" >&5
+$as_echo_n "checking whether iops->get_link() passes cookie... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+			#include <linux/fs.h>
+			const char *get_link(struct dentry *de, struct
+			    inode *ip, void **cookie) { return "symlink"; }
+			static struct inode_operations
+			     iops __attribute__ ((unused)) = {
+				.get_link = get_link,
+			};
+
+int
+main (void)
+{
+
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+			{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_GET_LINK_COOKIE 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+												{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+					{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether iops->follow_link() passes cookie" >&5
+$as_echo_n "checking whether iops->follow_link() passes cookie... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/fs.h>
+		const char *follow_link(struct dentry *de,
+		    void **cookie) { return "symlink"; }
+		static struct inode_operations
+		    iops __attribute__ ((unused)) = {
+			.follow_link = follow_link,
+		};
+
+int
+main (void)
+{
+
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_FOLLOW_LINK_COOKIE 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+								{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether iops->follow_link() passes nameidata" >&5
+$as_echo_n "checking whether iops->follow_link() passes nameidata... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/fs.h>
+			void *follow_link(struct dentry *de, struct
+			    nameidata *nd) { return (void *)NULL; }
+			static struct inode_operations
+			    iops __attribute__ ((unused)) = {
+				.follow_link = follow_link,
+			};
+
+int
+main (void)
+{
+
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+			{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_FOLLOW_LINK_NAMEIDATA 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+                        as_fn_error $? "no; please file a bug report" "$LINENO" 5
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#if !defined(HAVE_GET_LINK_DELAYED)
+		#error "Expecting get_link() delayed done"
+		#endif
+
+int
+main (void)
+{
+
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+
+$as_echo "#define HAVE_PUT_LINK_DELAYED 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+										{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether iops->put_link() passes cookie" >&5
+$as_echo_n "checking whether iops->put_link() passes cookie... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+			#include <linux/fs.h>
+			void put_link(struct inode *ip, void *cookie)
+			    { return; }
+			static struct inode_operations
+			    iops __attribute__ ((unused)) = {
+				.put_link = put_link,
+			};
+
+int
+main (void)
+{
+
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+			{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_PUT_LINK_COOKIE 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+												{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+			{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether iops->put_link() passes nameidata" >&5
+$as_echo_n "checking whether iops->put_link() passes nameidata... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+				#include <linux/fs.h>
+				void put_link(struct dentry *de, struct
+				    nameidata *nd, void *ptr) { return; }
+				static struct inode_operations
+				    iops __attribute__ ((unused)) = {
+					.put_link = put_link,
+				};
+
+int
+main (void)
+{
+
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+				{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_PUT_LINK_NAMEIDATA 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+				as_fn_error $? "no; please file a bug report" "$LINENO" 5
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether iops->truncate_range() exists" >&5
+$as_echo_n "checking whether iops->truncate_range() exists... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/fs.h>
+		void truncate_range(struct inode *inode, loff_t start,
+		                    loff_t end) { return; }
+		static struct inode_operations iops __attribute__ ((unused)) = {
+			.truncate_range	= truncate_range,
+		};
+
+int
+main (void)
+{
+
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_INODE_TRUNCATE_RANGE 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether dops->d_automount() exists" >&5
+$as_echo_n "checking whether dops->d_automount() exists... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/dcache.h>
+		struct vfsmount *d_automount(struct path *p) { return NULL; }
+		struct dentry_operations dops __attribute__ ((unused)) = {
+			.d_automount = d_automount,
+		};
+
+int
+main (void)
+{
+
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_AUTOMOUNT 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether eops->encode_fh() wants inode" >&5
+$as_echo_n "checking whether eops->encode_fh() wants inode... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/exportfs.h>
+		int encode_fh(struct inode *inode, __u32 *fh, int *max_len,
+		              struct inode *parent) { return 0; }
+		static struct export_operations eops __attribute__ ((unused))={
+			.encode_fh = encode_fh,
+		};
+
+int
+main (void)
+{
+
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_ENCODE_FH_WITH_INODE 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether eops->commit_metadata() exists" >&5
+$as_echo_n "checking whether eops->commit_metadata() exists... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/exportfs.h>
+		int commit_metadata(struct inode *inode) { return 0; }
+		static struct export_operations eops __attribute__ ((unused))={
+			.commit_metadata = commit_metadata,
+		};
+
+int
+main (void)
+{
+
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_COMMIT_METADATA 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether clear_inode() is available" >&5
+$as_echo_n "checking whether clear_inode() is available... " >&6; }
+
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/fs.h>
+
+int
+main (void)
+{
+
+		clear_inode(NULL);
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+  rc=0
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+ rc=1
+
+
+fi
+	rm -Rf build
+
+
+	if test $rc -ne 0; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+	else
+		if test "x$enable_linux_builtin" != xyes; then
+
+	grep -q -E '[[:space:]]clear_inode[[:space:]]' \
+		$LINUX_OBJ/$LINUX_SYMBOLS 2>/dev/null
+	rc=$?
+	if test $rc -ne 0; then
+		export=0
+		for file in fs/inode.c; do
+			grep -q -E "EXPORT_SYMBOL.*(clear_inode)" \
+				"$LINUX/$file" 2>/dev/null
+			rc=$?
+			if test $rc -eq 0; then
+				export=1
+				break;
+			fi
+		done
+		if test $export -eq 0; then :
+			rc=1
+		else :
+			rc=0
+		fi
+	else :
+		rc=0
+	fi
+
+		fi
+		if test $rc -ne 0; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+		else :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_CLEAR_INODE 1" >>confdefs.h
+
+
+		fi
+	fi
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether insert_inode_locked() is available" >&5
+$as_echo_n "checking whether insert_inode_locked() is available... " >&6; }
+
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/fs.h>
+
+int
+main (void)
+{
+
+		insert_inode_locked(NULL);
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+  rc=0
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+ rc=1
+
+
+fi
+	rm -Rf build
+
+
+	if test $rc -ne 0; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+	else
+		if test "x$enable_linux_builtin" != xyes; then
+
+	grep -q -E '[[:space:]]insert_inode_locked[[:space:]]' \
+		$LINUX_OBJ/$LINUX_SYMBOLS 2>/dev/null
+	rc=$?
+	if test $rc -ne 0; then
+		export=0
+		for file in fs/inode.c; do
+			grep -q -E "EXPORT_SYMBOL.*(insert_inode_locked)" \
+				"$LINUX/$file" 2>/dev/null
+			rc=$?
+			if test $rc -eq 0; then
+				export=1
+				break;
+			fi
+		done
+		if test $export -eq 0; then :
+			rc=1
+		else :
+			rc=0
+		fi
+	else :
+		rc=0
+	fi
+
+		fi
+		if test $rc -ne 0; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+		else :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_INSERT_INODE_LOCKED 1" >>confdefs.h
+
+
+		fi
+	fi
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether d_make_root() is available" >&5
+$as_echo_n "checking whether d_make_root() is available... " >&6; }
+
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/dcache.h>
+
+int
+main (void)
+{
+
+		d_make_root(NULL);
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+  rc=0
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+ rc=1
+
+
+fi
+	rm -Rf build
+
+
+	if test $rc -ne 0; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+	else
+		if test "x$enable_linux_builtin" != xyes; then
+
+	grep -q -E '[[:space:]]d_make_root[[:space:]]' \
+		$LINUX_OBJ/$LINUX_SYMBOLS 2>/dev/null
+	rc=$?
+	if test $rc -ne 0; then
+		export=0
+		for file in fs/dcache.c; do
+			grep -q -E "EXPORT_SYMBOL.*(d_make_root)" \
+				"$LINUX/$file" 2>/dev/null
+			rc=$?
+			if test $rc -eq 0; then
+				export=1
+				break;
+			fi
+		done
+		if test $export -eq 0; then :
+			rc=1
+		else :
+			rc=0
+		fi
+	else :
+		rc=0
+	fi
+
+		fi
+		if test $rc -ne 0; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+		else :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_D_MAKE_ROOT 1" >>confdefs.h
+
+
+		fi
+	fi
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether d_obtain_alias() is available" >&5
+$as_echo_n "checking whether d_obtain_alias() is available... " >&6; }
+
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/dcache.h>
+
+int
+main (void)
+{
+
+		d_obtain_alias(NULL);
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+  rc=0
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+ rc=1
+
+
+fi
+	rm -Rf build
+
+
+	if test $rc -ne 0; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+	else
+		if test "x$enable_linux_builtin" != xyes; then
+
+	grep -q -E '[[:space:]]d_obtain_alias[[:space:]]' \
+		$LINUX_OBJ/$LINUX_SYMBOLS 2>/dev/null
+	rc=$?
+	if test $rc -ne 0; then
+		export=0
+		for file in fs/dcache.c; do
+			grep -q -E "EXPORT_SYMBOL.*(d_obtain_alias)" \
+				"$LINUX/$file" 2>/dev/null
+			rc=$?
+			if test $rc -eq 0; then
+				export=1
+				break;
+			fi
+		done
+		if test $export -eq 0; then :
+			rc=1
+		else :
+			rc=0
+		fi
+	else :
+		rc=0
+	fi
+
+		fi
+		if test $rc -ne 0; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+		else :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_D_OBTAIN_ALIAS 1" >>confdefs.h
+
+
+		fi
+	fi
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether d_prune_aliases() is available" >&5
+$as_echo_n "checking whether d_prune_aliases() is available... " >&6; }
+
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/dcache.h>
+
+int
+main (void)
+{
+
+		struct inode *ip = NULL;
+		d_prune_aliases(ip);
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+  rc=0
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+ rc=1
+
+
+fi
+	rm -Rf build
+
+
+	if test $rc -ne 0; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+	else
+		if test "x$enable_linux_builtin" != xyes; then
+
+	grep -q -E '[[:space:]]d_prune_aliases[[:space:]]' \
+		$LINUX_OBJ/$LINUX_SYMBOLS 2>/dev/null
+	rc=$?
+	if test $rc -ne 0; then
+		export=0
+		for file in fs/dcache.c; do
+			grep -q -E "EXPORT_SYMBOL.*(d_prune_aliases)" \
+				"$LINUX/$file" 2>/dev/null
+			rc=$?
+			if test $rc -eq 0; then
+				export=1
+				break;
+			fi
+		done
+		if test $export -eq 0; then :
+			rc=1
+		else :
+			rc=0
+		fi
+	else :
+		rc=0
+	fi
+
+		fi
+		if test $rc -ne 0; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+		else :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_D_PRUNE_ALIASES 1" >>confdefs.h
+
+
+		fi
+	fi
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether d_set_d_op() is available" >&5
+$as_echo_n "checking whether d_set_d_op() is available... " >&6; }
+
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/dcache.h>
+
+int
+main (void)
+{
+
+		d_set_d_op(NULL, NULL);
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+  rc=0
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+ rc=1
+
+
+fi
+	rm -Rf build
+
+
+	if test $rc -ne 0; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+	else
+		if test "x$enable_linux_builtin" != xyes; then
+
+	grep -q -E '[[:space:]]d_set_d_op[[:space:]]' \
+		$LINUX_OBJ/$LINUX_SYMBOLS 2>/dev/null
+	rc=$?
+	if test $rc -ne 0; then
+		export=0
+		for file in fs/dcache.c; do
+			grep -q -E "EXPORT_SYMBOL.*(d_set_d_op)" \
+				"$LINUX/$file" 2>/dev/null
+			rc=$?
+			if test $rc -eq 0; then
+				export=1
+				break;
+			fi
+		done
+		if test $export -eq 0; then :
+			rc=1
+		else :
+			rc=0
+		fi
+	else :
+		rc=0
+	fi
+
+		fi
+		if test $rc -ne 0; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+		else :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_D_SET_D_OP 1" >>confdefs.h
+
+
+		fi
+	fi
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether dops->d_revalidate() takes struct nameidata" >&5
+$as_echo_n "checking whether dops->d_revalidate() takes struct nameidata... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/dcache.h>
+
+		int revalidate (struct dentry *dentry,
+		    struct nameidata *nidata) { return 0; }
+
+		static const struct dentry_operations
+		    dops __attribute__ ((unused)) = {
+			.d_revalidate	= revalidate,
+		};
+
+int
+main (void)
+{
+
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_D_REVALIDATE_NAMEIDATA 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether dentry uses const struct dentry_operations" >&5
+$as_echo_n "checking whether dentry uses const struct dentry_operations... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/dcache.h>
+
+		const struct dentry_operations test_d_op = {
+			.d_revalidate = NULL,
+		};
+
+int
+main (void)
+{
+
+		struct dentry d __attribute__ ((unused));
+
+		d.d_op = &test_d_op;
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_CONST_DENTRY_OPERATIONS 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether check_disk_size_change() is available" >&5
+$as_echo_n "checking whether check_disk_size_change() is available... " >&6; }
+
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/fs.h>
+
+int
+main (void)
+{
+
+		check_disk_size_change(NULL, NULL);
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+  rc=0
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+ rc=1
+
+
+fi
+	rm -Rf build
+
+
+	if test $rc -ne 0; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+	else
+		if test "x$enable_linux_builtin" != xyes; then
+
+	grep -q -E '[[:space:]]check_disk_size_change[[:space:]]' \
+		$LINUX_OBJ/$LINUX_SYMBOLS 2>/dev/null
+	rc=$?
+	if test $rc -ne 0; then
+		export=0
+		for file in fs/block_dev.c; do
+			grep -q -E "EXPORT_SYMBOL.*(check_disk_size_change)" \
+				"$LINUX/$file" 2>/dev/null
+			rc=$?
+			if test $rc -eq 0; then
+				export=1
+				break;
+			fi
+		done
+		if test $export -eq 0; then :
+			rc=1
+		else :
+			rc=0
+		fi
+	else :
+		rc=0
+	fi
+
+		fi
+		if test $rc -ne 0; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+		else :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_CHECK_DISK_SIZE_CHANGE 1" >>confdefs.h
+
+
+		fi
+	fi
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether truncate_setsize() is available" >&5
+$as_echo_n "checking whether truncate_setsize() is available... " >&6; }
+
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/mm.h>
+
+int
+main (void)
+{
+
+		truncate_setsize(NULL, 0);
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+  rc=0
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+ rc=1
+
+
+fi
+	rm -Rf build
+
+
+	if test $rc -ne 0; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+	else
+		if test "x$enable_linux_builtin" != xyes; then
+
+	grep -q -E '[[:space:]]truncate_setsize[[:space:]]' \
+		$LINUX_OBJ/$LINUX_SYMBOLS 2>/dev/null
+	rc=$?
+	if test $rc -ne 0; then
+		export=0
+		for file in mm/truncate.c; do
+			grep -q -E "EXPORT_SYMBOL.*(truncate_setsize)" \
+				"$LINUX/$file" 2>/dev/null
+			rc=$?
+			if test $rc -eq 0; then
+				export=1
+				break;
+			fi
+		done
+		if test $export -eq 0; then :
+			rc=1
+		else :
+			rc=0
+		fi
+	else :
+		rc=0
+	fi
+
+		fi
+		if test $rc -ne 0; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+		else :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_TRUNCATE_SETSIZE 1" >>confdefs.h
+
+
+		fi
+	fi
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether security_inode_init_security wants 6 args" >&5
+$as_echo_n "checking whether security_inode_init_security wants 6 args... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/security.h>
+
+int
+main (void)
+{
+
+		struct inode *ip __attribute__ ((unused)) = NULL;
+		struct inode *dip __attribute__ ((unused)) = NULL;
+		const struct qstr *str __attribute__ ((unused)) = NULL;
+		char *name __attribute__ ((unused)) = NULL;
+		void *value __attribute__ ((unused)) = NULL;
+		size_t len __attribute__ ((unused)) = 0;
+
+		security_inode_init_security(ip, dip, str, &name, &value, &len);
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_6ARGS_SECURITY_INODE_INIT_SECURITY 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether security_inode_init_security wants callback" >&5
+$as_echo_n "checking whether security_inode_init_security wants callback... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/security.h>
+
+int
+main (void)
+{
+
+		struct inode *ip __attribute__ ((unused)) = NULL;
+		struct inode *dip __attribute__ ((unused)) = NULL;
+		const struct qstr *str __attribute__ ((unused)) = NULL;
+		initxattrs func __attribute__ ((unused)) = NULL;
+
+		security_inode_init_security(ip, dip, str, func, NULL);
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_CALLBACK_SECURITY_INODE_INIT_SECURITY 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether mount_nodev() is available" >&5
+$as_echo_n "checking whether mount_nodev() is available... " >&6; }
+
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/fs.h>
+
+int
+main (void)
+{
+
+		mount_nodev(NULL, 0, NULL, NULL);
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+  rc=0
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+ rc=1
+
+
+fi
+	rm -Rf build
+
+
+	if test $rc -ne 0; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+	else
+		if test "x$enable_linux_builtin" != xyes; then
+
+	grep -q -E '[[:space:]]mount_nodev[[:space:]]' \
+		$LINUX_OBJ/$LINUX_SYMBOLS 2>/dev/null
+	rc=$?
+	if test $rc -ne 0; then
+		export=0
+		for file in fs/super.c; do
+			grep -q -E "EXPORT_SYMBOL.*(mount_nodev)" \
+				"$LINUX/$file" 2>/dev/null
+			rc=$?
+			if test $rc -eq 0; then
+				export=1
+				break;
+			fi
+		done
+		if test $export -eq 0; then :
+			rc=1
+		else :
+			rc=0
+		fi
+	else :
+		rc=0
+	fi
+
+		fi
+		if test $rc -ne 0; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+		else :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_MOUNT_NODEV 1" >>confdefs.h
+
+
+		fi
+	fi
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether super_block has s_shrink" >&5
+$as_echo_n "checking whether super_block has s_shrink... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/fs.h>
+
+		int shrink(struct shrinker *s, struct shrink_control *sc)
+		    { return 0; }
+
+		static const struct super_block
+		    sb __attribute__ ((unused)) = {
+			.s_shrink.shrink = shrink,
+			.s_shrink.seeks = DEFAULT_SEEKS,
+			.s_shrink.batch = 0,
+		};
+
+int
+main (void)
+{
+
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_SHRINK 1" >>confdefs.h
+
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether shrink_control has nid" >&5
+$as_echo_n "checking whether shrink_control has nid... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/fs.h>
+
+int
+main (void)
+{
+
+		struct shrink_control sc __attribute__ ((unused));
+		unsigned long scnidsize __attribute__ ((unused)) =
+		    sizeof(sc.nid);
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define SHRINK_CONTROL_HAS_NID 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether super_block has s_instances list_head" >&5
+$as_echo_n "checking whether super_block has s_instances list_head... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/fs.h>
+
+int
+main (void)
+{
+
+		struct super_block sb __attribute__ ((unused));
+
+		INIT_LIST_HEAD(&sb.s_instances);
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_S_INSTANCES_LIST_HEAD 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether super_block has s_d_op" >&5
+$as_echo_n "checking whether super_block has s_d_op... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/fs.h>
+
+int
+main (void)
+{
+
+		struct super_block sb __attribute__ ((unused));
+		sb.s_d_op = NULL;
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_S_D_OP 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether bdi_setup_and_register() wants 2 args" >&5
+$as_echo_n "checking whether bdi_setup_and_register() wants 2 args... " >&6; }
+
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/backing-dev.h>
+		struct backing_dev_info bdi;
+
+int
+main (void)
+{
+
+		char *name = "bdi";
+		int error __attribute__((unused)) =
+		    bdi_setup_and_register(&bdi, name);
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+  rc=0
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+ rc=1
+
+
+fi
+	rm -Rf build
+
+
+	if test $rc -ne 0; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether bdi_setup_and_register() wants 3 args" >&5
+$as_echo_n "checking whether bdi_setup_and_register() wants 3 args... " >&6; }
+
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+			#include <linux/backing-dev.h>
+			struct backing_dev_info bdi;
+
+int
+main (void)
+{
+
+			char *name = "bdi";
+			unsigned int cap = BDI_CAP_MAP_COPY;
+			int error __attribute__((unused)) =
+			    bdi_setup_and_register(&bdi, name, cap);
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+  rc=0
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+ rc=1
+
+
+fi
+	rm -Rf build
+
+
+	if test $rc -ne 0; then :
+
+			{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+	else
+		if test "x$enable_linux_builtin" != xyes; then
+
+	grep -q -E '[[:space:]]bdi_setup_and_register[[:space:]]' \
+		$LINUX_OBJ/$LINUX_SYMBOLS 2>/dev/null
+	rc=$?
+	if test $rc -ne 0; then
+		export=0
+		for file in mm/backing-dev.c; do
+			grep -q -E "EXPORT_SYMBOL.*(bdi_setup_and_register)" \
+				"$LINUX/$file" 2>/dev/null
+			rc=$?
+			if test $rc -eq 0; then
+				export=1
+				break;
+			fi
+		done
+		if test $export -eq 0; then :
+			rc=1
+		else :
+			rc=0
+		fi
+	else :
+		rc=0
+	fi
+
+		fi
+		if test $rc -ne 0; then :
+
+			{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+		else :
+
+			{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_3ARGS_BDI_SETUP_AND_REGISTER 1" >>confdefs.h
+
+
+		fi
+	fi
+
+
+	else
+		if test "x$enable_linux_builtin" != xyes; then
+
+	grep -q -E '[[:space:]]bdi_setup_and_register[[:space:]]' \
+		$LINUX_OBJ/$LINUX_SYMBOLS 2>/dev/null
+	rc=$?
+	if test $rc -ne 0; then
+		export=0
+		for file in mm/backing-dev.c; do
+			grep -q -E "EXPORT_SYMBOL.*(bdi_setup_and_register)" \
+				"$LINUX/$file" 2>/dev/null
+			rc=$?
+			if test $rc -eq 0; then
+				export=1
+				break;
+			fi
+		done
+		if test $export -eq 0; then :
+			rc=1
+		else :
+			rc=0
+		fi
+	else :
+		rc=0
+	fi
+
+		fi
+		if test $rc -ne 0; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether bdi_setup_and_register() wants 3 args" >&5
+$as_echo_n "checking whether bdi_setup_and_register() wants 3 args... " >&6; }
+
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+			#include <linux/backing-dev.h>
+			struct backing_dev_info bdi;
+
+int
+main (void)
+{
+
+			char *name = "bdi";
+			unsigned int cap = BDI_CAP_MAP_COPY;
+			int error __attribute__((unused)) =
+			    bdi_setup_and_register(&bdi, name, cap);
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+  rc=0
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+ rc=1
+
+
+fi
+	rm -Rf build
+
+
+	if test $rc -ne 0; then :
+
+			{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+	else
+		if test "x$enable_linux_builtin" != xyes; then
+
+	grep -q -E '[[:space:]]bdi_setup_and_register[[:space:]]' \
+		$LINUX_OBJ/$LINUX_SYMBOLS 2>/dev/null
+	rc=$?
+	if test $rc -ne 0; then
+		export=0
+		for file in mm/backing-dev.c; do
+			grep -q -E "EXPORT_SYMBOL.*(bdi_setup_and_register)" \
+				"$LINUX/$file" 2>/dev/null
+			rc=$?
+			if test $rc -eq 0; then
+				export=1
+				break;
+			fi
+		done
+		if test $export -eq 0; then :
+			rc=1
+		else :
+			rc=0
+		fi
+	else :
+		rc=0
+	fi
+
+		fi
+		if test $rc -ne 0; then :
+
+			{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+		else :
+
+			{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_3ARGS_BDI_SETUP_AND_REGISTER 1" >>confdefs.h
+
+
+		fi
+	fi
+
+
+		else :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_2ARGS_BDI_SETUP_AND_REGISTER 1" >>confdefs.h
+
+
+		fi
+	fi
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether set_nlink() is available" >&5
+$as_echo_n "checking whether set_nlink() is available... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/fs.h>
+
+int
+main (void)
+{
+
+		struct inode node;
+		unsigned int link = 0;
+		(void) set_nlink(&node, link);
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_SET_NLINK 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether elevator_change() is available" >&5
+$as_echo_n "checking whether elevator_change() is available... " >&6; }
+	tmp_flags="$EXTRA_KCFLAGS"
+	EXTRA_KCFLAGS="${NO_UNUSED_BUT_SET_VARIABLE}"
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/blkdev.h>
+		#include <linux/elevator.h>
+
+int
+main (void)
+{
+
+		int ret;
+		struct request_queue *q = NULL;
+		char *elevator = NULL;
+		ret = elevator_change(q, elevator);
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_ELEVATOR_CHANGE 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+	EXTRA_KCFLAGS="$tmp_flags"
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether sget() wants 5 args" >&5
+$as_echo_n "checking whether sget() wants 5 args... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/fs.h>
+
+int
+main (void)
+{
+
+		struct file_system_type *type = NULL;
+		int (*test)(struct super_block *,void *) = NULL;
+		int (*set)(struct super_block *,void *) = NULL;
+		int flags = 0;
+		void *data = NULL;
+		(void) sget(type, test, set, flags, data);
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_5ARG_SGET 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether lseek_execute() is available" >&5
+$as_echo_n "checking whether lseek_execute() is available... " >&6; }
+
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/fs.h>
+
+int
+main (void)
+{
+
+		struct file *fp __attribute__ ((unused)) = NULL;
+		struct inode *ip __attribute__ ((unused)) = NULL;
+		loff_t offset __attribute__ ((unused)) = 0;
+		loff_t maxsize __attribute__ ((unused)) = 0;
+
+		lseek_execute(fp, ip, offset, maxsize);
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+  rc=0
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+ rc=1
+
+
+fi
+	rm -Rf build
+
+
+	if test $rc -ne 0; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+	else
+		if test "x$enable_linux_builtin" != xyes; then
+
+	grep -q -E '[[:space:]]lseek_exclusive[[:space:]]' \
+		$LINUX_OBJ/$LINUX_SYMBOLS 2>/dev/null
+	rc=$?
+	if test $rc -ne 0; then
+		export=0
+		for file in fs/read_write.c; do
+			grep -q -E "EXPORT_SYMBOL.*(lseek_exclusive)" \
+				"$LINUX/$file" 2>/dev/null
+			rc=$?
+			if test $rc -eq 0; then
+				export=1
+				break;
+			fi
+		done
+		if test $export -eq 0; then :
+			rc=1
+		else :
+			rc=0
+		fi
+	else :
+		rc=0
+	fi
+
+		fi
+		if test $rc -ne 0; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+		else :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_LSEEK_EXECUTE 1" >>confdefs.h
+
+
+		fi
+	fi
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether fops->iterate() is available" >&5
+$as_echo_n "checking whether fops->iterate() is available... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/fs.h>
+		int iterate(struct file *filp, struct dir_context * context)
+		    { return 0; }
+
+		static const struct file_operations fops
+		    __attribute__ ((unused)) = {
+			.iterate	 = iterate,
+		};
+
+int
+main (void)
+{
+
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_VFS_ITERATE 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether fops->readdir() is available" >&5
+$as_echo_n "checking whether fops->readdir() is available... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+			#include <linux/fs.h>
+			int readdir(struct file *filp, void *entry, filldir_t func)
+			    { return 0; }
+
+			static const struct file_operations fops
+			    __attribute__ ((unused)) = {
+				.readdir = readdir,
+			};
+
+int
+main (void)
+{
+
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+			{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_VFS_READDIR 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+			as_fn_error $? "no; file a bug report with ZFSOnLinux" "$LINENO" 5
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+
+
+fi
+	rm -Rf build
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether fops->read/write_iter() are available" >&5
+$as_echo_n "checking whether fops->read/write_iter() are available... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/fs.h>
+
+		ssize_t test_read(struct kiocb *kiocb, struct iov_iter *to)
+		    { return 0; }
+		ssize_t test_write(struct kiocb *kiocb, struct iov_iter *from)
+		    { return 0; }
+
+		static const struct file_operations
+		    fops __attribute__ ((unused)) = {
+		    .read_iter = test_read,
+		    .write_iter = test_write,
+		};
+
+int
+main (void)
+{
+
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_VFS_RW_ITERATE 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether kmap_atomic wants 1 args" >&5
+$as_echo_n "checking whether kmap_atomic wants 1 args... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/pagemap.h>
+
+int
+main (void)
+{
+
+		struct page page;
+		kmap_atomic(&page);
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_1ARG_KMAP_ATOMIC 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether follow_down_one() is available" >&5
+$as_echo_n "checking whether follow_down_one() is available... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/namei.h>
+
+int
+main (void)
+{
+
+		struct path *p = NULL;
+		follow_down_one(p);
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_FOLLOW_DOWN_ONE 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether make_request_fn() returns int" >&5
+$as_echo_n "checking whether make_request_fn() returns int... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/blkdev.h>
+
+		int make_request(struct request_queue *q, struct bio *bio)
+		{
+			return (0);
+		}
+
+int
+main (void)
+{
+
+		blk_queue_make_request(NULL, &make_request);
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define MAKE_REQUEST_FN_RET int" >>confdefs.h
+
+
+$as_echo "#define HAVE_MAKE_REQUEST_FN_RET_INT 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether make_request_fn() returns void" >&5
+$as_echo_n "checking whether make_request_fn() returns void... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+			#include <linux/blkdev.h>
+
+			void make_request(struct request_queue *q, struct bio *bio)
+			{
+				return;
+			}
+
+int
+main (void)
+{
+
+			blk_queue_make_request(NULL, &make_request);
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+			{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define MAKE_REQUEST_FN_RET void" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+			{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+			{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether make_request_fn() returns blk_qc_t" >&5
+$as_echo_n "checking whether make_request_fn() returns blk_qc_t... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+				#include <linux/blkdev.h>
+
+				blk_qc_t make_request(struct request_queue *q, struct bio *bio)
+				{
+					return (BLK_QC_T_NONE);
+				}
+
+int
+main (void)
+{
+
+				blk_queue_make_request(NULL, &make_request);
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+				{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define MAKE_REQUEST_FN_RET blk_qc_t" >>confdefs.h
+
+
+$as_echo "#define HAVE_MAKE_REQUEST_FN_RET_QC 1" >>confdefs.h
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+				as_fn_error $? "no - Please file a bug report at
+				    https://github.com/zfsonlinux/zfs/issues/new" "$LINENO" 5
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+
+fi
+	rm -Rf build
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether generic IO accounting symbols are avaliable" >&5
+$as_echo_n "checking whether generic IO accounting symbols are avaliable... " >&6; }
+
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+		#include <linux/bio.h>
+
+		void (*generic_start_io_acct_f)(int, unsigned long,
+		    struct hd_struct *) = &generic_start_io_acct;
+		void (*generic_end_io_acct_f)(int, struct hd_struct *,
+		    unsigned long) = &generic_end_io_acct;
+
+int
+main (void)
+{
+
+		generic_start_io_acct(0, 0, NULL);
+		generic_end_io_acct(0, NULL, 0);
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+	rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+	echo "obj-m := conftest.o" >build/Makefile
+	modpost_flag=''
+	test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+	if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+  rc=0
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+ rc=1
+
+
+fi
+	rm -Rf build
+
+
+	if test $rc -ne 0; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+	else
+		if test "x$enable_linux_builtin" != xyes; then
+
+	grep -q -E '[[:space:]]generic_start_io_acct[[:space:]]' \
+		$LINUX_OBJ/$LINUX_SYMBOLS 2>/dev/null
+	rc=$?
+	if test $rc -ne 0; then
+		export=0
+		for file in block/bio.c; do
+			grep -q -E "EXPORT_SYMBOL.*(generic_start_io_acct)" \
+				"$LINUX/$file" 2>/dev/null
+			rc=$?
+			if test $rc -eq 0; then
+				export=1
+				break;
+			fi
+		done
+		if test $export -eq 0; then :
+			rc=1
+		else :
+			rc=0
+		fi
+	else :
+		rc=0
+	fi
+
+		fi
+		if test $rc -ne 0; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+		else :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_GENERIC_IO_ACCT 1" >>confdefs.h
+
+
+		fi
+	fi
+
+
+
+	if test "$LINUX_OBJ" != "$LINUX"; then :
+
+		KERNELMAKE_PARAMS="$KERNELMAKE_PARAMS O=$LINUX_OBJ"
+
+fi
+
+
+
+			KERNELCPPFLAGS="$KERNELCPPFLAGS $NO_UNUSED_BUT_SET_VARIABLE"
+	KERNELCPPFLAGS="$KERNELCPPFLAGS $NO_BOOL_COMPARE"
+	KERNELCPPFLAGS="$KERNELCPPFLAGS -DHAVE_SPL -D_KERNEL"
+	KERNELCPPFLAGS="$KERNELCPPFLAGS -DTEXT_DOMAIN=\\\"zfs-linux-kernel\\\""
+
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for dkms.conf file" >&5
+$as_echo_n "checking for dkms.conf file... " >&6; }
+        if test -e dkms.conf; then :
+
+		as_fn_error $? "
+	*** ZFS should not be manually built in the DKMS source tree.
+	*** Remove all ZFS packages before compiling the ZoL sources.
+	*** Running \"make install\" breaks ZFS packages." "$LINENO" 5
+
+else
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: not found" >&5
+$as_echo "not found" >&6; }
+
+fi
+
+
+
+# Check whether --with-mounthelperdir was given.
+if test "${with_mounthelperdir+set}" = set; then :
+  withval=$with_mounthelperdir; mounthelperdir=$withval
+else
+  mounthelperdir=/sbin
+fi
+
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for udev directories" >&5
+$as_echo_n "checking for udev directories... " >&6; }
+
+# Check whether --with-udevdir was given.
+if test "${with_udevdir+set}" = set; then :
+  withval=$with_udevdir; udevdir=$withval
+else
+  udevdir=check
+fi
+
+
+	if test "x$udevdir" = xcheck; then :
+
+		path1=/lib/udev
+		path2=/usr/lib/udev
+		default=$path2
+
+		if test -d "$path1"; then :
+  udevdir="$path1"
+else
+
+			if test -d "$path2"; then :
+  udevdir="$path2"
+else
+  udevdir="$default"
+fi
+
+fi
+
+fi
+
+
+# Check whether --with-udevruledir was given.
+if test "${with_udevruledir+set}" = set; then :
+  withval=$with_udevruledir; udevruledir=$withval
+else
+  udevruledir="${udevdir}/rules.d"
+fi
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $udevdir;$udevruledir" >&5
+$as_echo "$udevdir;$udevruledir" >&6; }
+
+
+	# Check whether --enable-systemd was given.
+if test "${enable_systemd+set}" = set; then :
+  enableval=$enable_systemd;
+else
+  enable_systemd=yes
+fi
+
+
+
+# Check whether --with-systemdunitdir was given.
+if test "${with_systemdunitdir+set}" = set; then :
+  withval=$with_systemdunitdir; systemdunitdir=$withval
+else
+  systemdunitdir=/usr/lib/systemd/system
+fi
+
+
+
+# Check whether --with-systemdpresetdir was given.
+if test "${with_systemdpresetdir+set}" = set; then :
+  withval=$with_systemdpresetdir; systemdpresetdir=$withval
+else
+  systemdpresetdir=/usr/lib/systemd/system-preset
+fi
+
+
+
+# Check whether --with-systemdmodulesloaddir was given.
+if test "${with_systemdmodulesloaddir+set}" = set; then :
+  withval=$with_systemdmodulesloaddir; systemdmoduleloaddir=$withval
+else
+  systemdmodulesloaddir=/usr/lib/modules-load.d
+fi
+
+
+
+	if test "x$enable_systemd" = xyes; then :
+
+		ZFS_INIT_SYSTEMD=systemd
+		ZFS_MODULE_LOAD=modules-load.d
+		modulesloaddir=$systemdmodulesloaddir
+
+fi
+
+
+
+
+
+
+
+
+	# Check whether --enable-sysvinit was given.
+if test "${enable_sysvinit+set}" = set; then :
+  enableval=$enable_sysvinit;
+else
+  enable_sysvinit=yes
+fi
+
+
+	if test "x$enable_sysvinit" = xyes; then :
+  ZFS_INIT_SYSV=init.d
+fi
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for dracut directory" >&5
+$as_echo_n "checking for dracut directory... " >&6; }
+
+# Check whether --with-dracutdir was given.
+if test "${with_dracutdir+set}" = set; then :
+  withval=$with_dracutdir; dracutdir=$withval
+else
+  dracutdir=check
+fi
+
+
+	if test "x$dracutdir" = xcheck; then :
+
+		path1=/usr/share/dracut
+		path2=/usr/lib/dracut
+		default=$path2
+
+		if test -d "$path1"; then :
+  dracutdir="$path1"
+else
+
+			if test -d "$path2"; then :
+  dracutdir="$path2"
+else
+  dracutdir="$default"
+fi
+
+fi
+
+fi
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $dracutdir" >&5
+$as_echo "$dracutdir" >&6; }
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for target asm dir" >&5
+$as_echo_n "checking for target asm dir... " >&6; }
+	TARGET_ARCH=`echo ${target_cpu} | sed -e s/i.86/i386/`
+
+	case $TARGET_ARCH in
+	i386|x86_64)
+		TARGET_ASM_DIR=asm-${TARGET_ARCH}
+		;;
+	*)
+		TARGET_ASM_DIR=asm-generic
+		;;
+	esac
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $TARGET_ASM_DIR" >&5
+$as_echo "$TARGET_ASM_DIR" >&6; }
+
+
+	ZLIB=
+
+	ac_fn_c_check_header_mongrel "$LINENO" "zlib.h" "ac_cv_header_zlib_h" "$ac_includes_default"
+if test "x$ac_cv_header_zlib_h" = xyes; then :
+
+else
+  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "
+	*** zlib.h missing, zlib-devel package required
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for compress2 in -lz" >&5
+$as_echo_n "checking for compress2 in -lz... " >&6; }
+if ${ac_cv_lib_z_compress2+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lz  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char compress2 ();
+int
+main ()
+{
+return compress2 ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_z_compress2=yes
+else
+  ac_cv_lib_z_compress2=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_z_compress2" >&5
+$as_echo "$ac_cv_lib_z_compress2" >&6; }
+if test "x$ac_cv_lib_z_compress2" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBZ 1
+_ACEOF
+
+  LIBS="-lz $LIBS"
+
+else
+  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "
+	*** compress2() missing, zlib-devel package required
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for uncompress in -lz" >&5
+$as_echo_n "checking for uncompress in -lz... " >&6; }
+if ${ac_cv_lib_z_uncompress+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lz  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char uncompress ();
+int
+main ()
+{
+return uncompress ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_z_uncompress=yes
+else
+  ac_cv_lib_z_uncompress=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_z_uncompress" >&5
+$as_echo "$ac_cv_lib_z_uncompress" >&6; }
+if test "x$ac_cv_lib_z_uncompress" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBZ 1
+_ACEOF
+
+  LIBS="-lz $LIBS"
+
+else
+  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "
+	*** uncompress() missing, zlib-devel package required
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for crc32 in -lz" >&5
+$as_echo_n "checking for crc32 in -lz... " >&6; }
+if ${ac_cv_lib_z_crc32+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lz  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char crc32 ();
+int
+main ()
+{
+return crc32 ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_z_crc32=yes
+else
+  ac_cv_lib_z_crc32=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_z_crc32" >&5
+$as_echo "$ac_cv_lib_z_crc32" >&6; }
+if test "x$ac_cv_lib_z_crc32" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBZ 1
+_ACEOF
+
+  LIBS="-lz $LIBS"
+
+else
+  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "
+	*** crc32() missing, zlib-devel package required
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+
+
+	ZLIB="-lz"
+
+
+$as_echo "#define HAVE_ZLIB 1" >>confdefs.h
+
+
+
+	LIBUUID=
+
+	ac_fn_c_check_header_mongrel "$LINENO" "uuid/uuid.h" "ac_cv_header_uuid_uuid_h" "$ac_includes_default"
+if test "x$ac_cv_header_uuid_uuid_h" = xyes; then :
+
+else
+  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "
+	*** uuid/uuid.h missing, libuuid-devel package required
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for uuid_generate in -luuid" >&5
+$as_echo_n "checking for uuid_generate in -luuid... " >&6; }
+if ${ac_cv_lib_uuid_uuid_generate+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-luuid  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char uuid_generate ();
+int
+main ()
+{
+return uuid_generate ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_uuid_uuid_generate=yes
+else
+  ac_cv_lib_uuid_uuid_generate=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_uuid_uuid_generate" >&5
+$as_echo "$ac_cv_lib_uuid_uuid_generate" >&6; }
+if test "x$ac_cv_lib_uuid_uuid_generate" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBUUID 1
+_ACEOF
+
+  LIBS="-luuid $LIBS"
+
+else
+  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "
+	*** uuid_generate() missing, libuuid-devel package required
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for uuid_is_null in -luuid" >&5
+$as_echo_n "checking for uuid_is_null in -luuid... " >&6; }
+if ${ac_cv_lib_uuid_uuid_is_null+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-luuid  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char uuid_is_null ();
+int
+main ()
+{
+return uuid_is_null ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_uuid_uuid_is_null=yes
+else
+  ac_cv_lib_uuid_uuid_is_null=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_uuid_uuid_is_null" >&5
+$as_echo "$ac_cv_lib_uuid_uuid_is_null" >&6; }
+if test "x$ac_cv_lib_uuid_uuid_is_null" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBUUID 1
+_ACEOF
+
+  LIBS="-luuid $LIBS"
+
+else
+  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "
+	*** uuid_is_null() missing, libuuid-devel package required
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+
+
+	LIBUUID="-luuid"
+
+
+$as_echo "#define HAVE_LIBUUID 1" >>confdefs.h
+
+
+
+
+# Check whether --with-blkid was given.
+if test "${with_blkid+set}" = set; then :
+  withval=$with_blkid;
+else
+  with_blkid=check
+fi
+
+
+	LIBBLKID=
+	if test "x$with_blkid" = xyes; then :
+
+		LIBBLKID="-lblkid"
+
+
+$as_echo "#define HAVE_LIBBLKID 1" >>confdefs.h
+
+
+fi
+
+	if test "x$with_blkid" = xcheck; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for blkid_get_cache in -lblkid" >&5
+$as_echo_n "checking for blkid_get_cache in -lblkid... " >&6; }
+if ${ac_cv_lib_blkid_blkid_get_cache+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lblkid  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char blkid_get_cache ();
+int
+main ()
+{
+return blkid_get_cache ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_blkid_blkid_get_cache=yes
+else
+  ac_cv_lib_blkid_blkid_get_cache=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_blkid_blkid_get_cache" >&5
+$as_echo "$ac_cv_lib_blkid_blkid_get_cache" >&6; }
+if test "x$ac_cv_lib_blkid_blkid_get_cache" = xyes; then :
+
+			{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for blkid zfs support" >&5
+$as_echo_n "checking for blkid zfs support... " >&6; }
+
+			ZFS_DEV=`mktemp`
+			truncate -s 64M $ZFS_DEV
+			echo -en "\x0c\xb1\xba\0\0\0\0\0" | \
+				dd of=$ZFS_DEV bs=1k count=8 \
+				seek=128 conv=notrunc &>/dev/null \
+				>/dev/null 2>/dev/null
+			echo -en "\x0c\xb1\xba\0\0\0\0\0" | \
+				dd of=$ZFS_DEV bs=1k count=8 \
+				seek=132 conv=notrunc &>/dev/null \
+				>/dev/null 2>/dev/null
+			echo -en "\x0c\xb1\xba\0\0\0\0\0" | \
+				dd of=$ZFS_DEV bs=1k count=8 \
+				seek=136 conv=notrunc &>/dev/null \
+				>/dev/null 2>/dev/null
+			echo -en "\x0c\xb1\xba\0\0\0\0\0" | \
+				dd of=$ZFS_DEV bs=1k count=8 \
+				seek=140 conv=notrunc &>/dev/null \
+				>/dev/null 2>/dev/null
+
+			saved_LIBS="$LIBS"
+			LIBS="-lblkid"
+
+			if test "$cross_compiling" = yes; then :
+  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot run test program while cross compiling
+See \`config.log' for more details" "$LINENO" 5; }
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+				#include <stdio.h>
+				#include <stdlib.h>
+				#include <blkid/blkid.h>
+
+int
+main ()
+{
+
+				blkid_cache cache;
+				char *value;
+
+			        if (blkid_get_cache(&cache, NULL) < 0)
+					return 1;
+
+				value = blkid_get_tag_value(cache, "TYPE",
+				                            "$ZFS_DEV");
+				if (!value) {
+					blkid_put_cache(cache);
+					return 2;
+				}
+
+				if (strcmp(value, "zfs_member")) {
+					free(value);
+					blkid_put_cache(cache);
+					return 0;
+				}
+
+				free(value);
+				blkid_put_cache(cache);
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+
+				rm -f $ZFS_DEV
+				{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+				LIBBLKID="-lblkid"
+
+
+$as_echo "#define HAVE_LIBBLKID 1" >>confdefs.h
+
+
+else
+
+				rm -f $ZFS_DEV
+				{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+				if test "x$with_blkid" != xcheck; then :
+  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "--with-blkid given but unavailable
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+
+			LIBS="$saved_LIBS"
+
+else
+
+			if test "x$with_blkid" != xcheck; then :
+  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "--with-blkid given but unavailable
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+
+
+fi
+
+
+fi
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for -Wframe-larger-than=<size> support" >&5
+$as_echo_n "checking for -Wframe-larger-than=<size> support... " >&6; }
+
+	saved_flags="$CFLAGS"
+	CFLAGS="$CFLAGS -Wframe-larger-than=1024"
+
+	cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+		FRAME_LARGER_THAN=-Wframe-larger-than=1024
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+else
+
+		FRAME_LARGER_THAN=
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+	CFLAGS="$saved_flags"
+
+
+
+	if test "x$runstatedir" = x; then
+		runstatedir='${localstatedir}/run'
+
+	fi
+
+	for ac_func in mlockall
+do :
+  ac_fn_c_check_func "$LINENO" "mlockall" "ac_cv_func_mlockall"
+if test "x$ac_cv_func_mlockall" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_MLOCKALL 1
+_ACEOF
+
+fi
+done
+
+   ;;
+		srpm)                        ;;
+		*)
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: Error!" >&5
+$as_echo "Error!" >&6; }
+		as_fn_error $? "Bad value \"$ZFS_CONFIG\" for --with-config,
+		              user kernel|user|all|srpm" "$LINENO" 5 ;;
+	esac
+
+	 if test "$ZFS_CONFIG" = user -o "$ZFS_CONFIG" = all; then
+  CONFIG_USER_TRUE=
+  CONFIG_USER_FALSE='#'
+else
+  CONFIG_USER_TRUE='#'
+  CONFIG_USER_FALSE=
+fi
+
+	 if test "$ZFS_CONFIG" = kernel -o "$ZFS_CONFIG" = all &&
+		       test "x$enable_linux_builtin" != xyes ; then
+  CONFIG_KERNEL_TRUE=
+  CONFIG_KERNEL_FALSE='#'
+else
+  CONFIG_KERNEL_TRUE='#'
+  CONFIG_KERNEL_FALSE=
+fi
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether debugging is enabled" >&5
+$as_echo_n "checking whether debugging is enabled... " >&6; }
+	# Check whether --enable-debug was given.
+if test "${enable_debug+set}" = set; then :
+  enableval=$enable_debug;
+else
+  enable_debug=no
+fi
+
+
+	if test "x$enable_debug" = xyes; then :
+
+		KERNELCPPFLAGS="${KERNELCPPFLAGS} -DDEBUG -Werror"
+		HOSTCFLAGS="${HOSTCFLAGS} -DDEBUG -Werror"
+		DEBUG_CFLAGS="-DDEBUG -Werror"
+		DEBUG_STACKFLAGS="-fstack-check"
+		DEBUG_ZFS="_with_debug"
+
+$as_echo "#define ZFS_DEBUG 1" >>confdefs.h
+
+
+else
+
+		KERNELCPPFLAGS="${KERNELCPPFLAGS} -DNDEBUG "
+		HOSTCFLAGS="${HOSTCFLAGS} -DNDEBUG "
+		DEBUG_CFLAGS="-DNDEBUG"
+		DEBUG_STACKFLAGS=""
+		DEBUG_ZFS="_without_debug"
+
+fi
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_debug" >&5
+$as_echo "$enable_debug" >&6; }
+
+
+	# Check whether --enable-debug-dmu-tx was given.
+if test "${enable_debug_dmu_tx+set}" = set; then :
+  enableval=$enable_debug_dmu_tx;
+else
+  enable_debug_dmu_tx=no
+fi
+
+
+	if test "x$enable_debug_dmu_tx" = xyes; then :
+
+		KERNELCPPFLAGS="${KERNELCPPFLAGS} -DDEBUG_DMU_TX"
+		DEBUG_DMU_TX="_with_debug_dmu_tx"
+
+$as_echo "#define DEBUG_DMU_TX 1" >>confdefs.h
+
+
+else
+
+		DEBUG_DMU_TX="_without_debug_dmu_tx"
+
+fi
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether dmu tx validation is enabled" >&5
+$as_echo_n "checking whether dmu tx validation is enabled... " >&6; }
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_debug_dmu_tx" >&5
+$as_echo "$enable_debug_dmu_tx" >&6; }
+
+
+ac_config_files="$ac_config_files Makefile udev/Makefile udev/rules.d/Makefile etc/Makefile etc/init.d/Makefile etc/zfs/Makefile etc/systemd/Makefile etc/systemd/system/Makefile etc/modules-load.d/Makefile man/Makefile man/man1/Makefile man/man5/Makefile man/man8/Makefile lib/Makefile lib/libspl/Makefile lib/libspl/asm-generic/Makefile lib/libspl/asm-i386/Makefile lib/libspl/asm-x86_64/Makefile lib/libspl/include/Makefile lib/libspl/include/ia32/Makefile lib/libspl/include/ia32/sys/Makefile lib/libspl/include/rpc/Makefile lib/libspl/include/sys/Makefile lib/libspl/include/sys/sysevent/Makefile lib/libspl/include/sys/dktp/Makefile lib/libspl/include/util/Makefile lib/libavl/Makefile lib/libefi/Makefile lib/libnvpair/Makefile lib/libunicode/Makefile lib/libuutil/Makefile lib/libzpool/Makefile lib/libzfs/libzfs.pc lib/libzfs/libzfs_core.pc lib/libzfs/Makefile lib/libzfs_core/Makefile lib/libshare/Makefile cmd/Makefile cmd/zdb/Makefile cmd/zhack/Makefile cmd/zfs/Makefile cmd/zinject/Makefile cmd/zpool/Makefile cmd/zstreamdump/Makefile cmd/ztest/Makefile cmd/zpios/Makefile cmd/mount_zfs/Makefile cmd/fsck_zfs/Makefile cmd/zvol_id/Makefile cmd/vdev_id/Makefile cmd/arcstat/Makefile cmd/dbufstat/Makefile cmd/arc_summary/Makefile cmd/zed/Makefile contrib/Makefile contrib/bash_completion.d/Makefile contrib/dracut/Makefile contrib/dracut/90zfs/Makefile contrib/initramfs/Makefile module/Makefile module/avl/Makefile module/nvpair/Makefile module/unicode/Makefile module/zcommon/Makefile module/zfs/Makefile module/zpios/Makefile include/Makefile include/linux/Makefile include/sys/Makefile include/sys/fs/Makefile include/sys/fm/Makefile include/sys/fm/fs/Makefile scripts/Makefile scripts/zpios-profile/Makefile scripts/zpios-test/Makefile scripts/zpool-config/Makefile scripts/common.sh rpm/Makefile rpm/redhat/Makefile rpm/redhat/zfs.spec rpm/redhat/zfs-kmod.spec rpm/redhat/zfs-dkms.spec rpm/generic/Makefile rpm/generic/zfs.spec rpm/generic/zfs-kmod.spec rpm/generic/zfs-dkms.spec zfs-script-config.sh zfs.release"
+
+
+cat >confcache <<\_ACEOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs, see configure's option --config-cache.
+# It is not useful on other systems.  If it contains results you don't
+# want to keep, you may remove or edit it.
+#
+# config.status only pays attention to the cache file if you give it
+# the --recheck option to rerun configure.
+#
+# `ac_cv_env_foo' variables (set or unset) will be overridden when
+# loading this file, other *unset* `ac_cv_foo' will be assigned the
+# following values.
+
+_ACEOF
+
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, we kill variables containing newlines.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(
+  for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do
+    eval ac_val=\$$ac_var
+    case $ac_val in #(
+    *${as_nl}*)
+      case $ac_var in #(
+      *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
+$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
+      esac
+      case $ac_var in #(
+      _ | IFS | as_nl) ;; #(
+      BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
+      *) { eval $ac_var=; unset $ac_var;} ;;
+      esac ;;
+    esac
+  done
+
+  (set) 2>&1 |
+    case $as_nl`(ac_space=' '; set) 2>&1` in #(
+    *${as_nl}ac_space=\ *)
+      # `set' does not quote correctly, so add quotes: double-quote
+      # substitution turns \\\\ into \\, and sed turns \\ into \.
+      sed -n \
+	"s/'/'\\\\''/g;
+	  s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
+      ;; #(
+    *)
+      # `set' quotes correctly as required by POSIX, so do not add quotes.
+      sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
+      ;;
+    esac |
+    sort
+) |
+  sed '
+     /^ac_cv_env_/b end
+     t clear
+     :clear
+     s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
+     t end
+     s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
+     :end' >>confcache
+if diff "$cache_file" confcache >/dev/null 2>&1; then :; else
+  if test -w "$cache_file"; then
+    if test "x$cache_file" != "x/dev/null"; then
+      { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5
+$as_echo "$as_me: updating cache $cache_file" >&6;}
+      if test ! -f "$cache_file" || test -h "$cache_file"; then
+	cat confcache >"$cache_file"
+      else
+        case $cache_file in #(
+        */* | ?:*)
+	  mv -f confcache "$cache_file"$$ &&
+	  mv -f "$cache_file"$$ "$cache_file" ;; #(
+        *)
+	  mv -f confcache "$cache_file" ;;
+	esac
+      fi
+    fi
+  else
+    { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5
+$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;}
+  fi
+fi
+rm -f confcache
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+DEFS=-DHAVE_CONFIG_H
+
+ac_libobjs=
+ac_ltlibobjs=
+U=
+for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
+  # 1. Remove the extension, and $U if already installed.
+  ac_script='s/\$U\././;s/\.o$//;s/\.obj$//'
+  ac_i=`$as_echo "$ac_i" | sed "$ac_script"`
+  # 2. Prepend LIBOBJDIR.  When used with automake>=1.10 LIBOBJDIR
+  #    will be set to the directory where LIBOBJS objects are built.
+  as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext"
+  as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo'
+done
+LIBOBJS=$ac_libobjs
+
+LTLIBOBJS=$ac_ltlibobjs
+
+
+if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then
+  as_fn_error $? "conditional \"MAINTAINER_MODE\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking that generated files are newer than configure" >&5
+$as_echo_n "checking that generated files are newer than configure... " >&6; }
+   if test -n "$am_sleep_pid"; then
+     # Hide warnings about reused PIDs.
+     wait $am_sleep_pid 2>/dev/null
+   fi
+   { $as_echo "$as_me:${as_lineno-$LINENO}: result: done" >&5
+$as_echo "done" >&6; }
+ if test -n "$EXEEXT"; then
+  am__EXEEXT_TRUE=
+  am__EXEEXT_FALSE='#'
+else
+  am__EXEEXT_TRUE='#'
+  am__EXEEXT_FALSE=
+fi
+
+if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then
+  as_fn_error $? "conditional \"AMDEP\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then
+  as_fn_error $? "conditional \"am__fastdepCC\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${am__fastdepCCAS_TRUE}" && test -z "${am__fastdepCCAS_FALSE}"; then
+  as_fn_error $? "conditional \"am__fastdepCCAS\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${CONFIG_USER_TRUE}" && test -z "${CONFIG_USER_FALSE}"; then
+  as_fn_error $? "conditional \"CONFIG_USER\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${CONFIG_KERNEL_TRUE}" && test -z "${CONFIG_KERNEL_FALSE}"; then
+  as_fn_error $? "conditional \"CONFIG_KERNEL\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+
+: "${CONFIG_STATUS=./config.status}"
+ac_write_fail=0
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files $CONFIG_STATUS"
+{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5
+$as_echo "$as_me: creating $CONFIG_STATUS" >&6;}
+as_write_fail=0
+cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1
+#! $SHELL
+# Generated by $as_me.
+# Run this file to recreate the current configuration.
+# Compiler output produced by configure, useful for debugging
+# configure, is in config.log if it exists.
+
+debug=false
+ac_cs_recheck=false
+ac_cs_silent=false
+
+SHELL=\${CONFIG_SHELL-$SHELL}
+export SHELL
+_ASEOF
+cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1
+## -------------------- ##
+## M4sh Initialization. ##
+## -------------------- ##
+
+# Be more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
+  emulate sh
+  NULLCMD=:
+  # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+  setopt NO_GLOB_SUBST
+else
+  case `(set -o) 2>/dev/null` in #(
+  *posix*) :
+    set -o posix ;; #(
+  *) :
+     ;;
+esac
+fi
+
+
+as_nl='
+'
+export as_nl
+# Printing a long string crashes Solaris 7 /usr/bin/printf.
+as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
+# Prefer a ksh shell builtin over an external printf program on Solaris,
+# but without wasting forks for bash or zsh.
+if test -z "$BASH_VERSION$ZSH_VERSION" \
+    && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
+  as_echo='print -r --'
+  as_echo_n='print -rn --'
+elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
+  as_echo='printf %s\n'
+  as_echo_n='printf %s'
+else
+  if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
+    as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
+    as_echo_n='/usr/ucb/echo -n'
+  else
+    as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
+    as_echo_n_body='eval
+      arg=$1;
+      case $arg in #(
+      *"$as_nl"*)
+	expr "X$arg" : "X\\(.*\\)$as_nl";
+	arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
+      esac;
+      expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
+    '
+    export as_echo_n_body
+    as_echo_n='sh -c $as_echo_n_body as_echo'
+  fi
+  export as_echo_body
+  as_echo='sh -c $as_echo_body as_echo'
+fi
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  PATH_SEPARATOR=:
+  (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+    (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+      PATH_SEPARATOR=';'
+  }
+fi
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.  Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+IFS=" ""	$as_nl"
+
+# Find who we are.  Look in the path if we contain no directory separator.
+as_myself=
+case $0 in #((
+  *[\\/]* ) as_myself=$0 ;;
+  *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+  done
+IFS=$as_save_IFS
+
+     ;;
+esac
+# We did not find ourselves, most probably we were run as `sh COMMAND'
+# in which case we are not to be found in the path.
+if test "x$as_myself" = x; then
+  as_myself=$0
+fi
+if test ! -f "$as_myself"; then
+  $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+  exit 1
+fi
+
+# Unset variables that we do not need and which cause bugs (e.g. in
+# pre-3.0 UWIN ksh).  But do not cause bugs in bash 2.01; the "|| exit 1"
+# suppresses any "Segmentation fault" message there.  '((' could
+# trigger a bug in pdksh 5.2.14.
+for as_var in BASH_ENV ENV MAIL MAILPATH
+do eval test x\${$as_var+set} = xset \
+  && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
+done
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# CDPATH.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+
+# as_fn_error STATUS ERROR [LINENO LOG_FD]
+# ----------------------------------------
+# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
+# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
+# script with STATUS, using 1 if that was 0.
+as_fn_error ()
+{
+  as_status=$1; test $as_status -eq 0 && as_status=1
+  if test "$4"; then
+    as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+    $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
+  fi
+  $as_echo "$as_me: error: $2" >&2
+  as_fn_exit $as_status
+} # as_fn_error
+
+
+# as_fn_set_status STATUS
+# -----------------------
+# Set $? to STATUS, without forking.
+as_fn_set_status ()
+{
+  return $1
+} # as_fn_set_status
+
+# as_fn_exit STATUS
+# -----------------
+# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
+as_fn_exit ()
+{
+  set +e
+  as_fn_set_status $1
+  exit $1
+} # as_fn_exit
+
+# as_fn_unset VAR
+# ---------------
+# Portably unset VAR.
+as_fn_unset ()
+{
+  { eval $1=; unset $1;}
+}
+as_unset=as_fn_unset
+# as_fn_append VAR VALUE
+# ----------------------
+# Append the text in VALUE to the end of the definition contained in VAR. Take
+# advantage of any shell optimizations that allow amortized linear growth over
+# repeated appends, instead of the typical quadratic growth present in naive
+# implementations.
+if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
+  eval 'as_fn_append ()
+  {
+    eval $1+=\$2
+  }'
+else
+  as_fn_append ()
+  {
+    eval $1=\$$1\$2
+  }
+fi # as_fn_append
+
+# as_fn_arith ARG...
+# ------------------
+# Perform arithmetic evaluation on the ARGs, and store the result in the
+# global $as_val. Take advantage of shells that can avoid forks. The arguments
+# must be portable across $(()) and expr.
+if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
+  eval 'as_fn_arith ()
+  {
+    as_val=$(( $* ))
+  }'
+else
+  as_fn_arith ()
+  {
+    as_val=`expr "$@" || test $? -eq 1`
+  }
+fi # as_fn_arith
+
+
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+   test "X`expr 00001 : '.*\(...\)'`" = X001; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
+  as_basename=basename
+else
+  as_basename=false
+fi
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+  as_dirname=dirname
+else
+  as_dirname=false
+fi
+
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+	 X"$0" : 'X\(//\)$' \| \
+	 X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X/"$0" |
+    sed '/^.*\/\([^/][^/]*\)\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\/\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\/\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in #(((((
+-n*)
+  case `echo 'xy\c'` in
+  *c*) ECHO_T='	';;	# ECHO_T is single tab character.
+  xy)  ECHO_C='\c';;
+  *)   echo `echo ksh88 bug on AIX 6.1` > /dev/null
+       ECHO_T='	';;
+  esac;;
+*)
+  ECHO_N='-n';;
+esac
+
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+  rm -f conf$$.dir/conf$$.file
+else
+  rm -f conf$$.dir
+  mkdir conf$$.dir 2>/dev/null
+fi
+if (echo >conf$$.file) 2>/dev/null; then
+  if ln -s conf$$.file conf$$ 2>/dev/null; then
+    as_ln_s='ln -s'
+    # ... but there are two gotchas:
+    # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+    # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+    # In both cases, we have to default to `cp -pR'.
+    ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+      as_ln_s='cp -pR'
+  elif ln conf$$.file conf$$ 2>/dev/null; then
+    as_ln_s=ln
+  else
+    as_ln_s='cp -pR'
+  fi
+else
+  as_ln_s='cp -pR'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+
+# as_fn_mkdir_p
+# -------------
+# Create "$as_dir" as a directory, including parents if necessary.
+as_fn_mkdir_p ()
+{
+
+  case $as_dir in #(
+  -*) as_dir=./$as_dir;;
+  esac
+  test -d "$as_dir" || eval $as_mkdir_p || {
+    as_dirs=
+    while :; do
+      case $as_dir in #(
+      *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+      *) as_qdir=$as_dir;;
+      esac
+      as_dirs="'$as_qdir' $as_dirs"
+      as_dir=`$as_dirname -- "$as_dir" ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$as_dir" : 'X\(//\)[^/]' \| \
+	 X"$as_dir" : 'X\(//\)$' \| \
+	 X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_dir" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+      test -d "$as_dir" && break
+    done
+    test -z "$as_dirs" || eval "mkdir $as_dirs"
+  } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"
+
+
+} # as_fn_mkdir_p
+if mkdir -p . 2>/dev/null; then
+  as_mkdir_p='mkdir -p "$as_dir"'
+else
+  test -d ./-p && rmdir ./-p
+  as_mkdir_p=false
+fi
+
+
+# as_fn_executable_p FILE
+# -----------------------
+# Test if FILE is an executable regular file.
+as_fn_executable_p ()
+{
+  test -f "$1" && test -x "$1"
+} # as_fn_executable_p
+as_test_x='test -x'
+as_executable_p=as_fn_executable_p
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+exec 6>&1
+## ----------------------------------- ##
+## Main body of $CONFIG_STATUS script. ##
+## ----------------------------------- ##
+_ASEOF
+test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# Save the log message, to keep $0 and so on meaningful, and to
+# report actual input values of CONFIG_FILES etc. instead of their
+# values after options handling.
+ac_log="
+This file was extended by zfs $as_me 0.6.5.6, which was
+generated by GNU Autoconf 2.69.  Invocation command line was
+
+  CONFIG_FILES    = $CONFIG_FILES
+  CONFIG_HEADERS  = $CONFIG_HEADERS
+  CONFIG_LINKS    = $CONFIG_LINKS
+  CONFIG_COMMANDS = $CONFIG_COMMANDS
+  $ $0 $@
+
+on `(hostname || uname -n) 2>/dev/null | sed 1q`
+"
+
+_ACEOF
+
+case $ac_config_files in *"
+"*) set x $ac_config_files; shift; ac_config_files=$*;;
+esac
+
+case $ac_config_headers in *"
+"*) set x $ac_config_headers; shift; ac_config_headers=$*;;
+esac
+
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+# Files that config.status was made for.
+config_files="$ac_config_files"
+config_headers="$ac_config_headers"
+config_commands="$ac_config_commands"
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+ac_cs_usage="\
+\`$as_me' instantiates files and other configuration actions
+from templates according to the current configuration.  Unless the files
+and actions are specified as TAGs, all are instantiated by default.
+
+Usage: $0 [OPTION]... [TAG]...
+
+  -h, --help       print this help, then exit
+  -V, --version    print version number and configuration settings, then exit
+      --config     print configuration, then exit
+  -q, --quiet, --silent
+                   do not print progress messages
+  -d, --debug      don't remove temporary files
+      --recheck    update $as_me by reconfiguring in the same conditions
+      --file=FILE[:TEMPLATE]
+                   instantiate the configuration file FILE
+      --header=FILE[:TEMPLATE]
+                   instantiate the configuration header FILE
+
+Configuration files:
+$config_files
+
+Configuration headers:
+$config_headers
+
+Configuration commands:
+$config_commands
+
+Report bugs to the package provider."
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
+ac_cs_version="\\
+zfs config.status 0.6.5.6
+configured by $0, generated by GNU Autoconf 2.69,
+  with options \\"\$ac_cs_config\\"
+
+Copyright (C) 2012 Free Software Foundation, Inc.
+This config.status script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it."
+
+ac_pwd='$ac_pwd'
+srcdir='$srcdir'
+INSTALL='$INSTALL'
+MKDIR_P='$MKDIR_P'
+AWK='$AWK'
+test -n "\$AWK" || AWK=awk
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# The default lists apply if the user does not specify any file.
+ac_need_defaults=:
+while test $# != 0
+do
+  case $1 in
+  --*=?*)
+    ac_option=`expr "X$1" : 'X\([^=]*\)='`
+    ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'`
+    ac_shift=:
+    ;;
+  --*=)
+    ac_option=`expr "X$1" : 'X\([^=]*\)='`
+    ac_optarg=
+    ac_shift=:
+    ;;
+  *)
+    ac_option=$1
+    ac_optarg=$2
+    ac_shift=shift
+    ;;
+  esac
+
+  case $ac_option in
+  # Handling of the options.
+  -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+    ac_cs_recheck=: ;;
+  --version | --versio | --versi | --vers | --ver | --ve | --v | -V )
+    $as_echo "$ac_cs_version"; exit ;;
+  --config | --confi | --conf | --con | --co | --c )
+    $as_echo "$ac_cs_config"; exit ;;
+  --debug | --debu | --deb | --de | --d | -d )
+    debug=: ;;
+  --file | --fil | --fi | --f )
+    $ac_shift
+    case $ac_optarg in
+    *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
+    '') as_fn_error $? "missing file argument" ;;
+    esac
+    as_fn_append CONFIG_FILES " '$ac_optarg'"
+    ac_need_defaults=false;;
+  --header | --heade | --head | --hea )
+    $ac_shift
+    case $ac_optarg in
+    *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
+    esac
+    as_fn_append CONFIG_HEADERS " '$ac_optarg'"
+    ac_need_defaults=false;;
+  --he | --h)
+    # Conflict between --help and --header
+    as_fn_error $? "ambiguous option: \`$1'
+Try \`$0 --help' for more information.";;
+  --help | --hel | -h )
+    $as_echo "$ac_cs_usage"; exit ;;
+  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+  | -silent | --silent | --silen | --sile | --sil | --si | --s)
+    ac_cs_silent=: ;;
+
+  # This is an error.
+  -*) as_fn_error $? "unrecognized option: \`$1'
+Try \`$0 --help' for more information." ;;
+
+  *) as_fn_append ac_config_targets " $1"
+     ac_need_defaults=false ;;
+
+  esac
+  shift
+done
+
+ac_configure_extra_args=
+
+if $ac_cs_silent; then
+  exec 6>/dev/null
+  ac_configure_extra_args="$ac_configure_extra_args --silent"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+if \$ac_cs_recheck; then
+  set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
+  shift
+  \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6
+  CONFIG_SHELL='$SHELL'
+  export CONFIG_SHELL
+  exec "\$@"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+exec 5>>config.log
+{
+  echo
+  sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
+## Running $as_me. ##
+_ASBOX
+  $as_echo "$ac_log"
+} >&5
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+#
+# INIT-COMMANDS
+#
+AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"
+
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+sed_quote_subst='$sed_quote_subst'
+double_quote_subst='$double_quote_subst'
+delay_variable_subst='$delay_variable_subst'
+macro_version='`$ECHO "$macro_version" | $SED "$delay_single_quote_subst"`'
+macro_revision='`$ECHO "$macro_revision" | $SED "$delay_single_quote_subst"`'
+enable_shared='`$ECHO "$enable_shared" | $SED "$delay_single_quote_subst"`'
+enable_static='`$ECHO "$enable_static" | $SED "$delay_single_quote_subst"`'
+pic_mode='`$ECHO "$pic_mode" | $SED "$delay_single_quote_subst"`'
+enable_fast_install='`$ECHO "$enable_fast_install" | $SED "$delay_single_quote_subst"`'
+shared_archive_member_spec='`$ECHO "$shared_archive_member_spec" | $SED "$delay_single_quote_subst"`'
+SHELL='`$ECHO "$SHELL" | $SED "$delay_single_quote_subst"`'
+ECHO='`$ECHO "$ECHO" | $SED "$delay_single_quote_subst"`'
+PATH_SEPARATOR='`$ECHO "$PATH_SEPARATOR" | $SED "$delay_single_quote_subst"`'
+host_alias='`$ECHO "$host_alias" | $SED "$delay_single_quote_subst"`'
+host='`$ECHO "$host" | $SED "$delay_single_quote_subst"`'
+host_os='`$ECHO "$host_os" | $SED "$delay_single_quote_subst"`'
+build_alias='`$ECHO "$build_alias" | $SED "$delay_single_quote_subst"`'
+build='`$ECHO "$build" | $SED "$delay_single_quote_subst"`'
+build_os='`$ECHO "$build_os" | $SED "$delay_single_quote_subst"`'
+SED='`$ECHO "$SED" | $SED "$delay_single_quote_subst"`'
+Xsed='`$ECHO "$Xsed" | $SED "$delay_single_quote_subst"`'
+GREP='`$ECHO "$GREP" | $SED "$delay_single_quote_subst"`'
+EGREP='`$ECHO "$EGREP" | $SED "$delay_single_quote_subst"`'
+FGREP='`$ECHO "$FGREP" | $SED "$delay_single_quote_subst"`'
+LD='`$ECHO "$LD" | $SED "$delay_single_quote_subst"`'
+NM='`$ECHO "$NM" | $SED "$delay_single_quote_subst"`'
+LN_S='`$ECHO "$LN_S" | $SED "$delay_single_quote_subst"`'
+max_cmd_len='`$ECHO "$max_cmd_len" | $SED "$delay_single_quote_subst"`'
+ac_objext='`$ECHO "$ac_objext" | $SED "$delay_single_quote_subst"`'
+exeext='`$ECHO "$exeext" | $SED "$delay_single_quote_subst"`'
+lt_unset='`$ECHO "$lt_unset" | $SED "$delay_single_quote_subst"`'
+lt_SP2NL='`$ECHO "$lt_SP2NL" | $SED "$delay_single_quote_subst"`'
+lt_NL2SP='`$ECHO "$lt_NL2SP" | $SED "$delay_single_quote_subst"`'
+lt_cv_to_host_file_cmd='`$ECHO "$lt_cv_to_host_file_cmd" | $SED "$delay_single_quote_subst"`'
+lt_cv_to_tool_file_cmd='`$ECHO "$lt_cv_to_tool_file_cmd" | $SED "$delay_single_quote_subst"`'
+reload_flag='`$ECHO "$reload_flag" | $SED "$delay_single_quote_subst"`'
+reload_cmds='`$ECHO "$reload_cmds" | $SED "$delay_single_quote_subst"`'
+OBJDUMP='`$ECHO "$OBJDUMP" | $SED "$delay_single_quote_subst"`'
+deplibs_check_method='`$ECHO "$deplibs_check_method" | $SED "$delay_single_quote_subst"`'
+file_magic_cmd='`$ECHO "$file_magic_cmd" | $SED "$delay_single_quote_subst"`'
+file_magic_glob='`$ECHO "$file_magic_glob" | $SED "$delay_single_quote_subst"`'
+want_nocaseglob='`$ECHO "$want_nocaseglob" | $SED "$delay_single_quote_subst"`'
+DLLTOOL='`$ECHO "$DLLTOOL" | $SED "$delay_single_quote_subst"`'
+sharedlib_from_linklib_cmd='`$ECHO "$sharedlib_from_linklib_cmd" | $SED "$delay_single_quote_subst"`'
+AR='`$ECHO "$AR" | $SED "$delay_single_quote_subst"`'
+AR_FLAGS='`$ECHO "$AR_FLAGS" | $SED "$delay_single_quote_subst"`'
+archiver_list_spec='`$ECHO "$archiver_list_spec" | $SED "$delay_single_quote_subst"`'
+STRIP='`$ECHO "$STRIP" | $SED "$delay_single_quote_subst"`'
+RANLIB='`$ECHO "$RANLIB" | $SED "$delay_single_quote_subst"`'
+old_postinstall_cmds='`$ECHO "$old_postinstall_cmds" | $SED "$delay_single_quote_subst"`'
+old_postuninstall_cmds='`$ECHO "$old_postuninstall_cmds" | $SED "$delay_single_quote_subst"`'
+old_archive_cmds='`$ECHO "$old_archive_cmds" | $SED "$delay_single_quote_subst"`'
+lock_old_archive_extraction='`$ECHO "$lock_old_archive_extraction" | $SED "$delay_single_quote_subst"`'
+CC='`$ECHO "$CC" | $SED "$delay_single_quote_subst"`'
+CFLAGS='`$ECHO "$CFLAGS" | $SED "$delay_single_quote_subst"`'
+compiler='`$ECHO "$compiler" | $SED "$delay_single_quote_subst"`'
+GCC='`$ECHO "$GCC" | $SED "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_pipe='`$ECHO "$lt_cv_sys_global_symbol_pipe" | $SED "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_to_cdecl='`$ECHO "$lt_cv_sys_global_symbol_to_cdecl" | $SED "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_to_import='`$ECHO "$lt_cv_sys_global_symbol_to_import" | $SED "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address" | $SED "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $SED "$delay_single_quote_subst"`'
+lt_cv_nm_interface='`$ECHO "$lt_cv_nm_interface" | $SED "$delay_single_quote_subst"`'
+nm_file_list_spec='`$ECHO "$nm_file_list_spec" | $SED "$delay_single_quote_subst"`'
+lt_sysroot='`$ECHO "$lt_sysroot" | $SED "$delay_single_quote_subst"`'
+lt_cv_truncate_bin='`$ECHO "$lt_cv_truncate_bin" | $SED "$delay_single_quote_subst"`'
+objdir='`$ECHO "$objdir" | $SED "$delay_single_quote_subst"`'
+MAGIC_CMD='`$ECHO "$MAGIC_CMD" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_no_builtin_flag='`$ECHO "$lt_prog_compiler_no_builtin_flag" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_pic='`$ECHO "$lt_prog_compiler_pic" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_wl='`$ECHO "$lt_prog_compiler_wl" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_static='`$ECHO "$lt_prog_compiler_static" | $SED "$delay_single_quote_subst"`'
+lt_cv_prog_compiler_c_o='`$ECHO "$lt_cv_prog_compiler_c_o" | $SED "$delay_single_quote_subst"`'
+need_locks='`$ECHO "$need_locks" | $SED "$delay_single_quote_subst"`'
+MANIFEST_TOOL='`$ECHO "$MANIFEST_TOOL" | $SED "$delay_single_quote_subst"`'
+DSYMUTIL='`$ECHO "$DSYMUTIL" | $SED "$delay_single_quote_subst"`'
+NMEDIT='`$ECHO "$NMEDIT" | $SED "$delay_single_quote_subst"`'
+LIPO='`$ECHO "$LIPO" | $SED "$delay_single_quote_subst"`'
+OTOOL='`$ECHO "$OTOOL" | $SED "$delay_single_quote_subst"`'
+OTOOL64='`$ECHO "$OTOOL64" | $SED "$delay_single_quote_subst"`'
+libext='`$ECHO "$libext" | $SED "$delay_single_quote_subst"`'
+shrext_cmds='`$ECHO "$shrext_cmds" | $SED "$delay_single_quote_subst"`'
+extract_expsyms_cmds='`$ECHO "$extract_expsyms_cmds" | $SED "$delay_single_quote_subst"`'
+archive_cmds_need_lc='`$ECHO "$archive_cmds_need_lc" | $SED "$delay_single_quote_subst"`'
+enable_shared_with_static_runtimes='`$ECHO "$enable_shared_with_static_runtimes" | $SED "$delay_single_quote_subst"`'
+export_dynamic_flag_spec='`$ECHO "$export_dynamic_flag_spec" | $SED "$delay_single_quote_subst"`'
+whole_archive_flag_spec='`$ECHO "$whole_archive_flag_spec" | $SED "$delay_single_quote_subst"`'
+compiler_needs_object='`$ECHO "$compiler_needs_object" | $SED "$delay_single_quote_subst"`'
+old_archive_from_new_cmds='`$ECHO "$old_archive_from_new_cmds" | $SED "$delay_single_quote_subst"`'
+old_archive_from_expsyms_cmds='`$ECHO "$old_archive_from_expsyms_cmds" | $SED "$delay_single_quote_subst"`'
+archive_cmds='`$ECHO "$archive_cmds" | $SED "$delay_single_quote_subst"`'
+archive_expsym_cmds='`$ECHO "$archive_expsym_cmds" | $SED "$delay_single_quote_subst"`'
+module_cmds='`$ECHO "$module_cmds" | $SED "$delay_single_quote_subst"`'
+module_expsym_cmds='`$ECHO "$module_expsym_cmds" | $SED "$delay_single_quote_subst"`'
+with_gnu_ld='`$ECHO "$with_gnu_ld" | $SED "$delay_single_quote_subst"`'
+allow_undefined_flag='`$ECHO "$allow_undefined_flag" | $SED "$delay_single_quote_subst"`'
+no_undefined_flag='`$ECHO "$no_undefined_flag" | $SED "$delay_single_quote_subst"`'
+hardcode_libdir_flag_spec='`$ECHO "$hardcode_libdir_flag_spec" | $SED "$delay_single_quote_subst"`'
+hardcode_libdir_separator='`$ECHO "$hardcode_libdir_separator" | $SED "$delay_single_quote_subst"`'
+hardcode_direct='`$ECHO "$hardcode_direct" | $SED "$delay_single_quote_subst"`'
+hardcode_direct_absolute='`$ECHO "$hardcode_direct_absolute" | $SED "$delay_single_quote_subst"`'
+hardcode_minus_L='`$ECHO "$hardcode_minus_L" | $SED "$delay_single_quote_subst"`'
+hardcode_shlibpath_var='`$ECHO "$hardcode_shlibpath_var" | $SED "$delay_single_quote_subst"`'
+hardcode_automatic='`$ECHO "$hardcode_automatic" | $SED "$delay_single_quote_subst"`'
+inherit_rpath='`$ECHO "$inherit_rpath" | $SED "$delay_single_quote_subst"`'
+link_all_deplibs='`$ECHO "$link_all_deplibs" | $SED "$delay_single_quote_subst"`'
+always_export_symbols='`$ECHO "$always_export_symbols" | $SED "$delay_single_quote_subst"`'
+export_symbols_cmds='`$ECHO "$export_symbols_cmds" | $SED "$delay_single_quote_subst"`'
+exclude_expsyms='`$ECHO "$exclude_expsyms" | $SED "$delay_single_quote_subst"`'
+include_expsyms='`$ECHO "$include_expsyms" | $SED "$delay_single_quote_subst"`'
+prelink_cmds='`$ECHO "$prelink_cmds" | $SED "$delay_single_quote_subst"`'
+postlink_cmds='`$ECHO "$postlink_cmds" | $SED "$delay_single_quote_subst"`'
+file_list_spec='`$ECHO "$file_list_spec" | $SED "$delay_single_quote_subst"`'
+variables_saved_for_relink='`$ECHO "$variables_saved_for_relink" | $SED "$delay_single_quote_subst"`'
+need_lib_prefix='`$ECHO "$need_lib_prefix" | $SED "$delay_single_quote_subst"`'
+need_version='`$ECHO "$need_version" | $SED "$delay_single_quote_subst"`'
+version_type='`$ECHO "$version_type" | $SED "$delay_single_quote_subst"`'
+runpath_var='`$ECHO "$runpath_var" | $SED "$delay_single_quote_subst"`'
+shlibpath_var='`$ECHO "$shlibpath_var" | $SED "$delay_single_quote_subst"`'
+shlibpath_overrides_runpath='`$ECHO "$shlibpath_overrides_runpath" | $SED "$delay_single_quote_subst"`'
+libname_spec='`$ECHO "$libname_spec" | $SED "$delay_single_quote_subst"`'
+library_names_spec='`$ECHO "$library_names_spec" | $SED "$delay_single_quote_subst"`'
+soname_spec='`$ECHO "$soname_spec" | $SED "$delay_single_quote_subst"`'
+install_override_mode='`$ECHO "$install_override_mode" | $SED "$delay_single_quote_subst"`'
+postinstall_cmds='`$ECHO "$postinstall_cmds" | $SED "$delay_single_quote_subst"`'
+postuninstall_cmds='`$ECHO "$postuninstall_cmds" | $SED "$delay_single_quote_subst"`'
+finish_cmds='`$ECHO "$finish_cmds" | $SED "$delay_single_quote_subst"`'
+finish_eval='`$ECHO "$finish_eval" | $SED "$delay_single_quote_subst"`'
+hardcode_into_libs='`$ECHO "$hardcode_into_libs" | $SED "$delay_single_quote_subst"`'
+sys_lib_search_path_spec='`$ECHO "$sys_lib_search_path_spec" | $SED "$delay_single_quote_subst"`'
+configure_time_dlsearch_path='`$ECHO "$configure_time_dlsearch_path" | $SED "$delay_single_quote_subst"`'
+configure_time_lt_sys_library_path='`$ECHO "$configure_time_lt_sys_library_path" | $SED "$delay_single_quote_subst"`'
+hardcode_action='`$ECHO "$hardcode_action" | $SED "$delay_single_quote_subst"`'
+enable_dlopen='`$ECHO "$enable_dlopen" | $SED "$delay_single_quote_subst"`'
+enable_dlopen_self='`$ECHO "$enable_dlopen_self" | $SED "$delay_single_quote_subst"`'
+enable_dlopen_self_static='`$ECHO "$enable_dlopen_self_static" | $SED "$delay_single_quote_subst"`'
+old_striplib='`$ECHO "$old_striplib" | $SED "$delay_single_quote_subst"`'
+striplib='`$ECHO "$striplib" | $SED "$delay_single_quote_subst"`'
+
+LTCC='$LTCC'
+LTCFLAGS='$LTCFLAGS'
+compiler='$compiler_DEFAULT'
+
+# A function that is used when there is no print builtin or printf.
+func_fallback_echo ()
+{
+  eval 'cat <<_LTECHO_EOF
+\$1
+_LTECHO_EOF'
+}
+
+# Quote evaled strings.
+for var in SHELL \
+ECHO \
+PATH_SEPARATOR \
+SED \
+GREP \
+EGREP \
+FGREP \
+LD \
+NM \
+LN_S \
+lt_SP2NL \
+lt_NL2SP \
+reload_flag \
+OBJDUMP \
+deplibs_check_method \
+file_magic_cmd \
+file_magic_glob \
+want_nocaseglob \
+DLLTOOL \
+sharedlib_from_linklib_cmd \
+AR \
+AR_FLAGS \
+archiver_list_spec \
+STRIP \
+RANLIB \
+CC \
+CFLAGS \
+compiler \
+lt_cv_sys_global_symbol_pipe \
+lt_cv_sys_global_symbol_to_cdecl \
+lt_cv_sys_global_symbol_to_import \
+lt_cv_sys_global_symbol_to_c_name_address \
+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix \
+lt_cv_nm_interface \
+nm_file_list_spec \
+lt_cv_truncate_bin \
+lt_prog_compiler_no_builtin_flag \
+lt_prog_compiler_pic \
+lt_prog_compiler_wl \
+lt_prog_compiler_static \
+lt_cv_prog_compiler_c_o \
+need_locks \
+MANIFEST_TOOL \
+DSYMUTIL \
+NMEDIT \
+LIPO \
+OTOOL \
+OTOOL64 \
+shrext_cmds \
+export_dynamic_flag_spec \
+whole_archive_flag_spec \
+compiler_needs_object \
+with_gnu_ld \
+allow_undefined_flag \
+no_undefined_flag \
+hardcode_libdir_flag_spec \
+hardcode_libdir_separator \
+exclude_expsyms \
+include_expsyms \
+file_list_spec \
+variables_saved_for_relink \
+libname_spec \
+library_names_spec \
+soname_spec \
+install_override_mode \
+finish_eval \
+old_striplib \
+striplib; do
+    case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in
+    *[\\\\\\\`\\"\\\$]*)
+      eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes
+      ;;
+    *)
+      eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
+      ;;
+    esac
+done
+
+# Double-quote double-evaled strings.
+for var in reload_cmds \
+old_postinstall_cmds \
+old_postuninstall_cmds \
+old_archive_cmds \
+extract_expsyms_cmds \
+old_archive_from_new_cmds \
+old_archive_from_expsyms_cmds \
+archive_cmds \
+archive_expsym_cmds \
+module_cmds \
+module_expsym_cmds \
+export_symbols_cmds \
+prelink_cmds \
+postlink_cmds \
+postinstall_cmds \
+postuninstall_cmds \
+finish_cmds \
+sys_lib_search_path_spec \
+configure_time_dlsearch_path \
+configure_time_lt_sys_library_path; do
+    case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in
+    *[\\\\\\\`\\"\\\$]*)
+      eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes
+      ;;
+    *)
+      eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
+      ;;
+    esac
+done
+
+ac_aux_dir='$ac_aux_dir'
+
+# See if we are running on zsh, and set the options that allow our
+# commands through without removal of \ escapes INIT.
+if test -n "\${ZSH_VERSION+set}"; then
+   setopt NO_GLOB_SUBST
+fi
+
+
+    PACKAGE='$PACKAGE'
+    VERSION='$VERSION'
+    RM='$RM'
+    ofile='$ofile'
+
+
+
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+
+# Handling of arguments.
+for ac_config_target in $ac_config_targets
+do
+  case $ac_config_target in
+    "zfs_config.h") CONFIG_HEADERS="$CONFIG_HEADERS zfs_config.h" ;;
+    "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;;
+    "libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;;
+    "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
+    "udev/Makefile") CONFIG_FILES="$CONFIG_FILES udev/Makefile" ;;
+    "udev/rules.d/Makefile") CONFIG_FILES="$CONFIG_FILES udev/rules.d/Makefile" ;;
+    "etc/Makefile") CONFIG_FILES="$CONFIG_FILES etc/Makefile" ;;
+    "etc/init.d/Makefile") CONFIG_FILES="$CONFIG_FILES etc/init.d/Makefile" ;;
+    "etc/zfs/Makefile") CONFIG_FILES="$CONFIG_FILES etc/zfs/Makefile" ;;
+    "etc/systemd/Makefile") CONFIG_FILES="$CONFIG_FILES etc/systemd/Makefile" ;;
+    "etc/systemd/system/Makefile") CONFIG_FILES="$CONFIG_FILES etc/systemd/system/Makefile" ;;
+    "etc/modules-load.d/Makefile") CONFIG_FILES="$CONFIG_FILES etc/modules-load.d/Makefile" ;;
+    "man/Makefile") CONFIG_FILES="$CONFIG_FILES man/Makefile" ;;
+    "man/man1/Makefile") CONFIG_FILES="$CONFIG_FILES man/man1/Makefile" ;;
+    "man/man5/Makefile") CONFIG_FILES="$CONFIG_FILES man/man5/Makefile" ;;
+    "man/man8/Makefile") CONFIG_FILES="$CONFIG_FILES man/man8/Makefile" ;;
+    "lib/Makefile") CONFIG_FILES="$CONFIG_FILES lib/Makefile" ;;
+    "lib/libspl/Makefile") CONFIG_FILES="$CONFIG_FILES lib/libspl/Makefile" ;;
+    "lib/libspl/asm-generic/Makefile") CONFIG_FILES="$CONFIG_FILES lib/libspl/asm-generic/Makefile" ;;
+    "lib/libspl/asm-i386/Makefile") CONFIG_FILES="$CONFIG_FILES lib/libspl/asm-i386/Makefile" ;;
+    "lib/libspl/asm-x86_64/Makefile") CONFIG_FILES="$CONFIG_FILES lib/libspl/asm-x86_64/Makefile" ;;
+    "lib/libspl/include/Makefile") CONFIG_FILES="$CONFIG_FILES lib/libspl/include/Makefile" ;;
+    "lib/libspl/include/ia32/Makefile") CONFIG_FILES="$CONFIG_FILES lib/libspl/include/ia32/Makefile" ;;
+    "lib/libspl/include/ia32/sys/Makefile") CONFIG_FILES="$CONFIG_FILES lib/libspl/include/ia32/sys/Makefile" ;;
+    "lib/libspl/include/rpc/Makefile") CONFIG_FILES="$CONFIG_FILES lib/libspl/include/rpc/Makefile" ;;
+    "lib/libspl/include/sys/Makefile") CONFIG_FILES="$CONFIG_FILES lib/libspl/include/sys/Makefile" ;;
+    "lib/libspl/include/sys/sysevent/Makefile") CONFIG_FILES="$CONFIG_FILES lib/libspl/include/sys/sysevent/Makefile" ;;
+    "lib/libspl/include/sys/dktp/Makefile") CONFIG_FILES="$CONFIG_FILES lib/libspl/include/sys/dktp/Makefile" ;;
+    "lib/libspl/include/util/Makefile") CONFIG_FILES="$CONFIG_FILES lib/libspl/include/util/Makefile" ;;
+    "lib/libavl/Makefile") CONFIG_FILES="$CONFIG_FILES lib/libavl/Makefile" ;;
+    "lib/libefi/Makefile") CONFIG_FILES="$CONFIG_FILES lib/libefi/Makefile" ;;
+    "lib/libnvpair/Makefile") CONFIG_FILES="$CONFIG_FILES lib/libnvpair/Makefile" ;;
+    "lib/libunicode/Makefile") CONFIG_FILES="$CONFIG_FILES lib/libunicode/Makefile" ;;
+    "lib/libuutil/Makefile") CONFIG_FILES="$CONFIG_FILES lib/libuutil/Makefile" ;;
+    "lib/libzpool/Makefile") CONFIG_FILES="$CONFIG_FILES lib/libzpool/Makefile" ;;
+    "lib/libzfs/libzfs.pc") CONFIG_FILES="$CONFIG_FILES lib/libzfs/libzfs.pc" ;;
+    "lib/libzfs/libzfs_core.pc") CONFIG_FILES="$CONFIG_FILES lib/libzfs/libzfs_core.pc" ;;
+    "lib/libzfs/Makefile") CONFIG_FILES="$CONFIG_FILES lib/libzfs/Makefile" ;;
+    "lib/libzfs_core/Makefile") CONFIG_FILES="$CONFIG_FILES lib/libzfs_core/Makefile" ;;
+    "lib/libshare/Makefile") CONFIG_FILES="$CONFIG_FILES lib/libshare/Makefile" ;;
+    "cmd/Makefile") CONFIG_FILES="$CONFIG_FILES cmd/Makefile" ;;
+    "cmd/zdb/Makefile") CONFIG_FILES="$CONFIG_FILES cmd/zdb/Makefile" ;;
+    "cmd/zhack/Makefile") CONFIG_FILES="$CONFIG_FILES cmd/zhack/Makefile" ;;
+    "cmd/zfs/Makefile") CONFIG_FILES="$CONFIG_FILES cmd/zfs/Makefile" ;;
+    "cmd/zinject/Makefile") CONFIG_FILES="$CONFIG_FILES cmd/zinject/Makefile" ;;
+    "cmd/zpool/Makefile") CONFIG_FILES="$CONFIG_FILES cmd/zpool/Makefile" ;;
+    "cmd/zstreamdump/Makefile") CONFIG_FILES="$CONFIG_FILES cmd/zstreamdump/Makefile" ;;
+    "cmd/ztest/Makefile") CONFIG_FILES="$CONFIG_FILES cmd/ztest/Makefile" ;;
+    "cmd/zpios/Makefile") CONFIG_FILES="$CONFIG_FILES cmd/zpios/Makefile" ;;
+    "cmd/mount_zfs/Makefile") CONFIG_FILES="$CONFIG_FILES cmd/mount_zfs/Makefile" ;;
+    "cmd/fsck_zfs/Makefile") CONFIG_FILES="$CONFIG_FILES cmd/fsck_zfs/Makefile" ;;
+    "cmd/zvol_id/Makefile") CONFIG_FILES="$CONFIG_FILES cmd/zvol_id/Makefile" ;;
+    "cmd/vdev_id/Makefile") CONFIG_FILES="$CONFIG_FILES cmd/vdev_id/Makefile" ;;
+    "cmd/arcstat/Makefile") CONFIG_FILES="$CONFIG_FILES cmd/arcstat/Makefile" ;;
+    "cmd/dbufstat/Makefile") CONFIG_FILES="$CONFIG_FILES cmd/dbufstat/Makefile" ;;
+    "cmd/arc_summary/Makefile") CONFIG_FILES="$CONFIG_FILES cmd/arc_summary/Makefile" ;;
+    "cmd/zed/Makefile") CONFIG_FILES="$CONFIG_FILES cmd/zed/Makefile" ;;
+    "contrib/Makefile") CONFIG_FILES="$CONFIG_FILES contrib/Makefile" ;;
+    "contrib/bash_completion.d/Makefile") CONFIG_FILES="$CONFIG_FILES contrib/bash_completion.d/Makefile" ;;
+    "contrib/dracut/Makefile") CONFIG_FILES="$CONFIG_FILES contrib/dracut/Makefile" ;;
+    "contrib/dracut/90zfs/Makefile") CONFIG_FILES="$CONFIG_FILES contrib/dracut/90zfs/Makefile" ;;
+    "contrib/initramfs/Makefile") CONFIG_FILES="$CONFIG_FILES contrib/initramfs/Makefile" ;;
+    "module/Makefile") CONFIG_FILES="$CONFIG_FILES module/Makefile" ;;
+    "module/avl/Makefile") CONFIG_FILES="$CONFIG_FILES module/avl/Makefile" ;;
+    "module/nvpair/Makefile") CONFIG_FILES="$CONFIG_FILES module/nvpair/Makefile" ;;
+    "module/unicode/Makefile") CONFIG_FILES="$CONFIG_FILES module/unicode/Makefile" ;;
+    "module/zcommon/Makefile") CONFIG_FILES="$CONFIG_FILES module/zcommon/Makefile" ;;
+    "module/zfs/Makefile") CONFIG_FILES="$CONFIG_FILES module/zfs/Makefile" ;;
+    "module/zpios/Makefile") CONFIG_FILES="$CONFIG_FILES module/zpios/Makefile" ;;
+    "include/Makefile") CONFIG_FILES="$CONFIG_FILES include/Makefile" ;;
+    "include/linux/Makefile") CONFIG_FILES="$CONFIG_FILES include/linux/Makefile" ;;
+    "include/sys/Makefile") CONFIG_FILES="$CONFIG_FILES include/sys/Makefile" ;;
+    "include/sys/fs/Makefile") CONFIG_FILES="$CONFIG_FILES include/sys/fs/Makefile" ;;
+    "include/sys/fm/Makefile") CONFIG_FILES="$CONFIG_FILES include/sys/fm/Makefile" ;;
+    "include/sys/fm/fs/Makefile") CONFIG_FILES="$CONFIG_FILES include/sys/fm/fs/Makefile" ;;
+    "scripts/Makefile") CONFIG_FILES="$CONFIG_FILES scripts/Makefile" ;;
+    "scripts/zpios-profile/Makefile") CONFIG_FILES="$CONFIG_FILES scripts/zpios-profile/Makefile" ;;
+    "scripts/zpios-test/Makefile") CONFIG_FILES="$CONFIG_FILES scripts/zpios-test/Makefile" ;;
+    "scripts/zpool-config/Makefile") CONFIG_FILES="$CONFIG_FILES scripts/zpool-config/Makefile" ;;
+    "scripts/common.sh") CONFIG_FILES="$CONFIG_FILES scripts/common.sh" ;;
+    "rpm/Makefile") CONFIG_FILES="$CONFIG_FILES rpm/Makefile" ;;
+    "rpm/redhat/Makefile") CONFIG_FILES="$CONFIG_FILES rpm/redhat/Makefile" ;;
+    "rpm/redhat/zfs.spec") CONFIG_FILES="$CONFIG_FILES rpm/redhat/zfs.spec" ;;
+    "rpm/redhat/zfs-kmod.spec") CONFIG_FILES="$CONFIG_FILES rpm/redhat/zfs-kmod.spec" ;;
+    "rpm/redhat/zfs-dkms.spec") CONFIG_FILES="$CONFIG_FILES rpm/redhat/zfs-dkms.spec" ;;
+    "rpm/generic/Makefile") CONFIG_FILES="$CONFIG_FILES rpm/generic/Makefile" ;;
+    "rpm/generic/zfs.spec") CONFIG_FILES="$CONFIG_FILES rpm/generic/zfs.spec" ;;
+    "rpm/generic/zfs-kmod.spec") CONFIG_FILES="$CONFIG_FILES rpm/generic/zfs-kmod.spec" ;;
+    "rpm/generic/zfs-dkms.spec") CONFIG_FILES="$CONFIG_FILES rpm/generic/zfs-dkms.spec" ;;
+    "zfs-script-config.sh") CONFIG_FILES="$CONFIG_FILES zfs-script-config.sh" ;;
+    "zfs.release") CONFIG_FILES="$CONFIG_FILES zfs.release" ;;
+
+  *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
+  esac
+done
+
+
+# If the user did not use the arguments to specify the items to instantiate,
+# then the envvar interface is used.  Set only those that are not.
+# We use the long form for the default assignment because of an extremely
+# bizarre bug on SunOS 4.1.3.
+if $ac_need_defaults; then
+  test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
+  test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers
+  test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands
+fi
+
+# Have a temporary directory for convenience.  Make it in the build tree
+# simply because there is no reason against having it here, and in addition,
+# creating and moving files from /tmp can sometimes cause problems.
+# Hook for its removal unless debugging.
+# Note that there is a small window in which the directory will not be cleaned:
+# after its creation but before its name has been assigned to `$tmp'.
+$debug ||
+{
+  tmp= ac_tmp=
+  trap 'exit_status=$?
+  : "${ac_tmp:=$tmp}"
+  { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status
+' 0
+  trap 'as_fn_exit 1' 1 2 13 15
+}
+# Create a (secure) tmp directory for tmp files.
+
+{
+  tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` &&
+  test -d "$tmp"
+}  ||
+{
+  tmp=./conf$$-$RANDOM
+  (umask 077 && mkdir "$tmp")
+} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5
+ac_tmp=$tmp
+
+# Set up the scripts for CONFIG_FILES section.
+# No need to generate them if there are no CONFIG_FILES.
+# This happens for instance with `./config.status config.h'.
+if test -n "$CONFIG_FILES"; then
+
+
+ac_cr=`echo X | tr X '\015'`
+# On cygwin, bash can eat \r inside `` if the user requested igncr.
+# But we know of no other shell where ac_cr would be empty at this
+# point, so we can use a bashism as a fallback.
+if test "x$ac_cr" = x; then
+  eval ac_cr=\$\'\\r\'
+fi
+ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' </dev/null 2>/dev/null`
+if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then
+  ac_cs_awk_cr='\\r'
+else
+  ac_cs_awk_cr=$ac_cr
+fi
+
+echo 'BEGIN {' >"$ac_tmp/subs1.awk" &&
+_ACEOF
+
+
+{
+  echo "cat >conf$$subs.awk <<_ACEOF" &&
+  echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' &&
+  echo "_ACEOF"
+} >conf$$subs.sh ||
+  as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
+ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'`
+ac_delim='%!_!# '
+for ac_last_try in false false false false false :; do
+  . ./conf$$subs.sh ||
+    as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
+
+  ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X`
+  if test $ac_delim_n = $ac_delim_num; then
+    break
+  elif $ac_last_try; then
+    as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
+  else
+    ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
+  fi
+done
+rm -f conf$$subs.sh
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK &&
+_ACEOF
+sed -n '
+h
+s/^/S["/; s/!.*/"]=/
+p
+g
+s/^[^!]*!//
+:repl
+t repl
+s/'"$ac_delim"'$//
+t delim
+:nl
+h
+s/\(.\{148\}\)..*/\1/
+t more1
+s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/
+p
+n
+b repl
+:more1
+s/["\\]/\\&/g; s/^/"/; s/$/"\\/
+p
+g
+s/.\{148\}//
+t nl
+:delim
+h
+s/\(.\{148\}\)..*/\1/
+t more2
+s/["\\]/\\&/g; s/^/"/; s/$/"/
+p
+b
+:more2
+s/["\\]/\\&/g; s/^/"/; s/$/"\\/
+p
+g
+s/.\{148\}//
+t delim
+' <conf$$subs.awk | sed '
+/^[^""]/{
+  N
+  s/\n//
+}
+' >>$CONFIG_STATUS || ac_write_fail=1
+rm -f conf$$subs.awk
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+_ACAWK
+cat >>"\$ac_tmp/subs1.awk" <<_ACAWK &&
+  for (key in S) S_is_set[key] = 1
+  FS = ""
+
+}
+{
+  line = $ 0
+  nfields = split(line, field, "@")
+  substed = 0
+  len = length(field[1])
+  for (i = 2; i < nfields; i++) {
+    key = field[i]
+    keylen = length(key)
+    if (S_is_set[key]) {
+      value = S[key]
+      line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3)
+      len += length(value) + length(field[++i])
+      substed = 1
+    } else
+      len += 1 + keylen
+  }
+
+  print line
+}
+
+_ACAWK
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then
+  sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g"
+else
+  cat
+fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \
+  || as_fn_error $? "could not setup config files machinery" "$LINENO" 5
+_ACEOF
+
+# VPATH may cause trouble with some makes, so we remove sole $(srcdir),
+# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and
+# trailing colons and then remove the whole line if VPATH becomes empty
+# (actually we leave an empty line to preserve line numbers).
+if test "x$srcdir" = x.; then
+  ac_vpsub='/^[	 ]*VPATH[	 ]*=[	 ]*/{
+h
+s///
+s/^/:/
+s/[	 ]*$/:/
+s/:\$(srcdir):/:/g
+s/:\${srcdir}:/:/g
+s/:@srcdir@:/:/g
+s/^:*//
+s/:*$//
+x
+s/\(=[	 ]*\).*/\1/
+G
+s/\n//
+s/^[^=]*=[	 ]*$//
+}'
+fi
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+fi # test -n "$CONFIG_FILES"
+
+# Set up the scripts for CONFIG_HEADERS section.
+# No need to generate them if there are no CONFIG_HEADERS.
+# This happens for instance with `./config.status Makefile'.
+if test -n "$CONFIG_HEADERS"; then
+cat >"$ac_tmp/defines.awk" <<\_ACAWK ||
+BEGIN {
+_ACEOF
+
+# Transform confdefs.h into an awk script `defines.awk', embedded as
+# here-document in config.status, that substitutes the proper values into
+# config.h.in to produce config.h.
+
+# Create a delimiter string that does not exist in confdefs.h, to ease
+# handling of long lines.
+ac_delim='%!_!# '
+for ac_last_try in false false :; do
+  ac_tt=`sed -n "/$ac_delim/p" confdefs.h`
+  if test -z "$ac_tt"; then
+    break
+  elif $ac_last_try; then
+    as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5
+  else
+    ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
+  fi
+done
+
+# For the awk script, D is an array of macro values keyed by name,
+# likewise P contains macro parameters if any.  Preserve backslash
+# newline sequences.
+
+ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]*
+sed -n '
+s/.\{148\}/&'"$ac_delim"'/g
+t rset
+:rset
+s/^[	 ]*#[	 ]*define[	 ][	 ]*/ /
+t def
+d
+:def
+s/\\$//
+t bsnl
+s/["\\]/\\&/g
+s/^ \('"$ac_word_re"'\)\(([^()]*)\)[	 ]*\(.*\)/P["\1"]="\2"\
+D["\1"]=" \3"/p
+s/^ \('"$ac_word_re"'\)[	 ]*\(.*\)/D["\1"]=" \2"/p
+d
+:bsnl
+s/["\\]/\\&/g
+s/^ \('"$ac_word_re"'\)\(([^()]*)\)[	 ]*\(.*\)/P["\1"]="\2"\
+D["\1"]=" \3\\\\\\n"\\/p
+t cont
+s/^ \('"$ac_word_re"'\)[	 ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p
+t cont
+d
+:cont
+n
+s/.\{148\}/&'"$ac_delim"'/g
+t clear
+:clear
+s/\\$//
+t bsnlc
+s/["\\]/\\&/g; s/^/"/; s/$/"/p
+d
+:bsnlc
+s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p
+b cont
+' <confdefs.h | sed '
+s/'"$ac_delim"'/"\\\
+"/g' >>$CONFIG_STATUS || ac_write_fail=1
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+  for (key in D) D_is_set[key] = 1
+  FS = ""
+}
+/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ {
+  line = \$ 0
+  split(line, arg, " ")
+  if (arg[1] == "#") {
+    defundef = arg[2]
+    mac1 = arg[3]
+  } else {
+    defundef = substr(arg[1], 2)
+    mac1 = arg[2]
+  }
+  split(mac1, mac2, "(") #)
+  macro = mac2[1]
+  prefix = substr(line, 1, index(line, defundef) - 1)
+  if (D_is_set[macro]) {
+    # Preserve the white space surrounding the "#".
+    print prefix "define", macro P[macro] D[macro]
+    next
+  } else {
+    # Replace #undef with comments.  This is necessary, for example,
+    # in the case of _POSIX_SOURCE, which is predefined and required
+    # on some systems where configure will not decide to define it.
+    if (defundef == "undef") {
+      print "/*", prefix defundef, macro, "*/"
+      next
+    }
+  }
+}
+{ print }
+_ACAWK
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+  as_fn_error $? "could not setup config headers machinery" "$LINENO" 5
+fi # test -n "$CONFIG_HEADERS"
+
+
+eval set X "  :F $CONFIG_FILES  :H $CONFIG_HEADERS    :C $CONFIG_COMMANDS"
+shift
+for ac_tag
+do
+  case $ac_tag in
+  :[FHLC]) ac_mode=$ac_tag; continue;;
+  esac
+  case $ac_mode$ac_tag in
+  :[FHL]*:*);;
+  :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;;
+  :[FH]-) ac_tag=-:-;;
+  :[FH]*) ac_tag=$ac_tag:$ac_tag.in;;
+  esac
+  ac_save_IFS=$IFS
+  IFS=:
+  set x $ac_tag
+  IFS=$ac_save_IFS
+  shift
+  ac_file=$1
+  shift
+
+  case $ac_mode in
+  :L) ac_source=$1;;
+  :[FH])
+    ac_file_inputs=
+    for ac_f
+    do
+      case $ac_f in
+      -) ac_f="$ac_tmp/stdin";;
+      *) # Look for the file first in the build tree, then in the source tree
+	 # (if the path is not absolute).  The absolute path cannot be DOS-style,
+	 # because $ac_f cannot contain `:'.
+	 test -f "$ac_f" ||
+	   case $ac_f in
+	   [\\/$]*) false;;
+	   *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";;
+	   esac ||
+	   as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;;
+      esac
+      case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac
+      as_fn_append ac_file_inputs " '$ac_f'"
+    done
+
+    # Let's still pretend it is `configure' which instantiates (i.e., don't
+    # use $as_me), people would be surprised to read:
+    #    /* config.h.  Generated by config.status.  */
+    configure_input='Generated from '`
+	  $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g'
+	`' by configure.'
+    if test x"$ac_file" != x-; then
+      configure_input="$ac_file.  $configure_input"
+      { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5
+$as_echo "$as_me: creating $ac_file" >&6;}
+    fi
+    # Neutralize special characters interpreted by sed in replacement strings.
+    case $configure_input in #(
+    *\&* | *\|* | *\\* )
+       ac_sed_conf_input=`$as_echo "$configure_input" |
+       sed 's/[\\\\&|]/\\\\&/g'`;; #(
+    *) ac_sed_conf_input=$configure_input;;
+    esac
+
+    case $ac_tag in
+    *:-:* | *:-) cat >"$ac_tmp/stdin" \
+      || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;;
+    esac
+    ;;
+  esac
+
+  ac_dir=`$as_dirname -- "$ac_file" ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$ac_file" : 'X\(//\)[^/]' \| \
+	 X"$ac_file" : 'X\(//\)$' \| \
+	 X"$ac_file" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$ac_file" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+  as_dir="$ac_dir"; as_fn_mkdir_p
+  ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+  ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
+  # A ".." for each directory in $ac_dir_suffix.
+  ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+  case $ac_top_builddir_sub in
+  "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+  *)  ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+  esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+  .)  # We are building in place.
+    ac_srcdir=.
+    ac_top_srcdir=$ac_top_builddir_sub
+    ac_abs_top_srcdir=$ac_pwd ;;
+  [\\/]* | ?:[\\/]* )  # Absolute name.
+    ac_srcdir=$srcdir$ac_dir_suffix;
+    ac_top_srcdir=$srcdir
+    ac_abs_top_srcdir=$srcdir ;;
+  *) # Relative name.
+    ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_build_prefix$srcdir
+    ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+
+  case $ac_mode in
+  :F)
+  #
+  # CONFIG_FILE
+  #
+
+  case $INSTALL in
+  [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;;
+  *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;;
+  esac
+  ac_MKDIR_P=$MKDIR_P
+  case $MKDIR_P in
+  [\\/$]* | ?:[\\/]* ) ;;
+  */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;;
+  esac
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# If the template does not know about datarootdir, expand it.
+# FIXME: This hack should be removed a few years after 2.60.
+ac_datarootdir_hack=; ac_datarootdir_seen=
+ac_sed_dataroot='
+/datarootdir/ {
+  p
+  q
+}
+/@datadir@/p
+/@docdir@/p
+/@infodir@/p
+/@localedir@/p
+/@mandir@/p'
+case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in
+*datarootdir*) ac_datarootdir_seen=yes;;
+*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*)
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5
+$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;}
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+  ac_datarootdir_hack='
+  s&@datadir@&$datadir&g
+  s&@docdir@&$docdir&g
+  s&@infodir@&$infodir&g
+  s&@localedir@&$localedir&g
+  s&@mandir@&$mandir&g
+  s&\\\${datarootdir}&$datarootdir&g' ;;
+esac
+_ACEOF
+
+# Neutralize VPATH when `$srcdir' = `.'.
+# Shell code in configure.ac might set extrasub.
+# FIXME: do we really want to maintain this feature?
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ac_sed_extra="$ac_vpsub
+$extrasub
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+:t
+/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
+s|@configure_input@|$ac_sed_conf_input|;t t
+s&@top_builddir@&$ac_top_builddir_sub&;t t
+s&@top_build_prefix@&$ac_top_build_prefix&;t t
+s&@srcdir@&$ac_srcdir&;t t
+s&@abs_srcdir@&$ac_abs_srcdir&;t t
+s&@top_srcdir@&$ac_top_srcdir&;t t
+s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t
+s&@builddir@&$ac_builddir&;t t
+s&@abs_builddir@&$ac_abs_builddir&;t t
+s&@abs_top_builddir@&$ac_abs_top_builddir&;t t
+s&@INSTALL@&$ac_INSTALL&;t t
+s&@MKDIR_P@&$ac_MKDIR_P&;t t
+$ac_datarootdir_hack
+"
+eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \
+  >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+
+test -z "$ac_datarootdir_hack$ac_datarootdir_seen" &&
+  { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } &&
+  { ac_out=`sed -n '/^[	 ]*datarootdir[	 ]*:*=/p' \
+      "$ac_tmp/out"`; test -z "$ac_out"; } &&
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined.  Please make sure it is defined" >&5
+$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined.  Please make sure it is defined" >&2;}
+
+  rm -f "$ac_tmp/stdin"
+  case $ac_file in
+  -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";;
+  *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";;
+  esac \
+  || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+ ;;
+  :H)
+  #
+  # CONFIG_HEADER
+  #
+  if test x"$ac_file" != x-; then
+    {
+      $as_echo "/* $configure_input  */" \
+      && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs"
+    } >"$ac_tmp/config.h" \
+      || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+    if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then
+      { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5
+$as_echo "$as_me: $ac_file is unchanged" >&6;}
+    else
+      rm -f "$ac_file"
+      mv "$ac_tmp/config.h" "$ac_file" \
+	|| as_fn_error $? "could not create $ac_file" "$LINENO" 5
+    fi
+  else
+    $as_echo "/* $configure_input  */" \
+      && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \
+      || as_fn_error $? "could not create -" "$LINENO" 5
+  fi
+# Compute "$ac_file"'s index in $config_headers.
+_am_arg="$ac_file"
+_am_stamp_count=1
+for _am_header in $config_headers :; do
+  case $_am_header in
+    $_am_arg | $_am_arg:* )
+      break ;;
+    * )
+      _am_stamp_count=`expr $_am_stamp_count + 1` ;;
+  esac
+done
+echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" ||
+$as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$_am_arg" : 'X\(//\)[^/]' \| \
+	 X"$_am_arg" : 'X\(//\)$' \| \
+	 X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$_am_arg" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`/stamp-h$_am_stamp_count
+ ;;
+
+  :C)  { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5
+$as_echo "$as_me: executing $ac_file commands" >&6;}
+ ;;
+  esac
+
+
+  case $ac_file$ac_mode in
+    "zfs_config.h":H)
+	(mv zfs_config.h zfs_config.h.tmp &&
+	awk -f ${ac_srcdir}/config/config.awk zfs_config.h.tmp >zfs_config.h &&
+	rm zfs_config.h.tmp) || exit 1 ;;
+    "depfiles":C) test x"$AMDEP_TRUE" != x"" || {
+  # Older Autoconf quotes --file arguments for eval, but not when files
+  # are listed without --file.  Let's play safe and only enable the eval
+  # if we detect the quoting.
+  case $CONFIG_FILES in
+  *\'*) eval set x "$CONFIG_FILES" ;;
+  *)   set x $CONFIG_FILES ;;
+  esac
+  shift
+  for mf
+  do
+    # Strip MF so we end up with the name of the file.
+    mf=`echo "$mf" | sed -e 's/:.*$//'`
+    # Check whether this is an Automake generated Makefile or not.
+    # We used to match only the files named 'Makefile.in', but
+    # some people rename them; so instead we look at the file content.
+    # Grep'ing the first line is not enough: some people post-process
+    # each Makefile.in and add a new line on top of each file to say so.
+    # Grep'ing the whole file is not good either: AIX grep has a line
+    # limit of 2048, but all sed's we know have understand at least 4000.
+    if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then
+      dirpart=`$as_dirname -- "$mf" ||
+$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$mf" : 'X\(//\)[^/]' \| \
+	 X"$mf" : 'X\(//\)$' \| \
+	 X"$mf" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$mf" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+    else
+      continue
+    fi
+    # Extract the definition of DEPDIR, am__include, and am__quote
+    # from the Makefile without running 'make'.
+    DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"`
+    test -z "$DEPDIR" && continue
+    am__include=`sed -n 's/^am__include = //p' < "$mf"`
+    test -z "$am__include" && continue
+    am__quote=`sed -n 's/^am__quote = //p' < "$mf"`
+    # Find all dependency output files, they are included files with
+    # $(DEPDIR) in their names.  We invoke sed twice because it is the
+    # simplest approach to changing $(DEPDIR) to its actual value in the
+    # expansion.
+    for file in `sed -n "
+      s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \
+	 sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do
+      # Make sure the directory exists.
+      test -f "$dirpart/$file" && continue
+      fdir=`$as_dirname -- "$file" ||
+$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$file" : 'X\(//\)[^/]' \| \
+	 X"$file" : 'X\(//\)$' \| \
+	 X"$file" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$file" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+      as_dir=$dirpart/$fdir; as_fn_mkdir_p
+      # echo "creating $dirpart/$file"
+      echo '# dummy' > "$dirpart/$file"
+    done
+  done
+}
+ ;;
+    "libtool":C)
+
+    # See if we are running on zsh, and set the options that allow our
+    # commands through without removal of \ escapes.
+    if test -n "${ZSH_VERSION+set}"; then
+      setopt NO_GLOB_SUBST
+    fi
+
+    cfgfile=${ofile}T
+    trap "$RM \"$cfgfile\"; exit 1" 1 2 15
+    $RM "$cfgfile"
+
+    cat <<_LT_EOF >> "$cfgfile"
+#! $SHELL
+# Generated automatically by $as_me ($PACKAGE) $VERSION
+# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+# NOTE: Changes made to this file will be lost: look at ltmain.sh.
+
+# Provide generalized library-building support services.
+# Written by Gordon Matzigkeit, 1996
+
+# Copyright (C) 2014 Free Software Foundation, Inc.
+# This is free software; see the source for copying conditions.  There is NO
+# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+# GNU Libtool is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of of the License, or
+# (at your option) any later version.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program or library that is built
+# using GNU Libtool, you may include this file under the  same
+# distribution terms that you use for the rest of that program.
+#
+# GNU Libtool is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+
+# The names of the tagged configurations supported by this script.
+available_tags=''
+
+# Configured defaults for sys_lib_dlsearch_path munging.
+: \${LT_SYS_LIBRARY_PATH="$configure_time_lt_sys_library_path"}
+
+# ### BEGIN LIBTOOL CONFIG
+
+# Which release of libtool.m4 was used?
+macro_version=$macro_version
+macro_revision=$macro_revision
+
+# Whether or not to build shared libraries.
+build_libtool_libs=$enable_shared
+
+# Whether or not to build static libraries.
+build_old_libs=$enable_static
+
+# What type of objects to build.
+pic_mode=$pic_mode
+
+# Whether or not to optimize for fast installation.
+fast_install=$enable_fast_install
+
+# Shared archive member basename,for filename based shared library versioning on AIX.
+shared_archive_member_spec=$shared_archive_member_spec
+
+# Shell to use when invoking shell scripts.
+SHELL=$lt_SHELL
+
+# An echo program that protects backslashes.
+ECHO=$lt_ECHO
+
+# The PATH separator for the build system.
+PATH_SEPARATOR=$lt_PATH_SEPARATOR
+
+# The host system.
+host_alias=$host_alias
+host=$host
+host_os=$host_os
+
+# The build system.
+build_alias=$build_alias
+build=$build
+build_os=$build_os
+
+# A sed program that does not truncate output.
+SED=$lt_SED
+
+# Sed that helps us avoid accidentally triggering echo(1) options like -n.
+Xsed="\$SED -e 1s/^X//"
+
+# A grep program that handles long lines.
+GREP=$lt_GREP
+
+# An ERE matcher.
+EGREP=$lt_EGREP
+
+# A literal string matcher.
+FGREP=$lt_FGREP
+
+# A BSD- or MS-compatible name lister.
+NM=$lt_NM
+
+# Whether we need soft or hard links.
+LN_S=$lt_LN_S
+
+# What is the maximum length of a command?
+max_cmd_len=$max_cmd_len
+
+# Object file suffix (normally "o").
+objext=$ac_objext
+
+# Executable file suffix (normally "").
+exeext=$exeext
+
+# whether the shell understands "unset".
+lt_unset=$lt_unset
+
+# turn spaces into newlines.
+SP2NL=$lt_lt_SP2NL
+
+# turn newlines into spaces.
+NL2SP=$lt_lt_NL2SP
+
+# convert \$build file names to \$host format.
+to_host_file_cmd=$lt_cv_to_host_file_cmd
+
+# convert \$build files to toolchain format.
+to_tool_file_cmd=$lt_cv_to_tool_file_cmd
+
+# An object symbol dumper.
+OBJDUMP=$lt_OBJDUMP
+
+# Method to check whether dependent libraries are shared objects.
+deplibs_check_method=$lt_deplibs_check_method
+
+# Command to use when deplibs_check_method = "file_magic".
+file_magic_cmd=$lt_file_magic_cmd
+
+# How to find potential files when deplibs_check_method = "file_magic".
+file_magic_glob=$lt_file_magic_glob
+
+# Find potential files using nocaseglob when deplibs_check_method = "file_magic".
+want_nocaseglob=$lt_want_nocaseglob
+
+# DLL creation program.
+DLLTOOL=$lt_DLLTOOL
+
+# Command to associate shared and link libraries.
+sharedlib_from_linklib_cmd=$lt_sharedlib_from_linklib_cmd
+
+# The archiver.
+AR=$lt_AR
+
+# Flags to create an archive.
+AR_FLAGS=$lt_AR_FLAGS
+
+# How to feed a file listing to the archiver.
+archiver_list_spec=$lt_archiver_list_spec
+
+# A symbol stripping program.
+STRIP=$lt_STRIP
+
+# Commands used to install an old-style archive.
+RANLIB=$lt_RANLIB
+old_postinstall_cmds=$lt_old_postinstall_cmds
+old_postuninstall_cmds=$lt_old_postuninstall_cmds
+
+# Whether to use a lock for old archive extraction.
+lock_old_archive_extraction=$lock_old_archive_extraction
+
+# A C compiler.
+LTCC=$lt_CC
+
+# LTCC compiler flags.
+LTCFLAGS=$lt_CFLAGS
+
+# Take the output of nm and produce a listing of raw symbols and C names.
+global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe
+
+# Transform the output of nm in a proper C declaration.
+global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl
+
+# Transform the output of nm into a list of symbols to manually relocate.
+global_symbol_to_import=$lt_lt_cv_sys_global_symbol_to_import
+
+# Transform the output of nm in a C name address pair.
+global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address
+
+# Transform the output of nm in a C name address pair when lib prefix is needed.
+global_symbol_to_c_name_address_lib_prefix=$lt_lt_cv_sys_global_symbol_to_c_name_address_lib_prefix
+
+# The name lister interface.
+nm_interface=$lt_lt_cv_nm_interface
+
+# Specify filename containing input files for \$NM.
+nm_file_list_spec=$lt_nm_file_list_spec
+
+# The root where to search for dependent libraries,and where our libraries should be installed.
+lt_sysroot=$lt_sysroot
+
+# Command to truncate a binary pipe.
+lt_truncate_bin=$lt_lt_cv_truncate_bin
+
+# The name of the directory that contains temporary libtool files.
+objdir=$objdir
+
+# Used to examine libraries when file_magic_cmd begins with "file".
+MAGIC_CMD=$MAGIC_CMD
+
+# Must we lock files when doing compilation?
+need_locks=$lt_need_locks
+
+# Manifest tool.
+MANIFEST_TOOL=$lt_MANIFEST_TOOL
+
+# Tool to manipulate archived DWARF debug symbol files on Mac OS X.
+DSYMUTIL=$lt_DSYMUTIL
+
+# Tool to change global to local symbols on Mac OS X.
+NMEDIT=$lt_NMEDIT
+
+# Tool to manipulate fat objects and archives on Mac OS X.
+LIPO=$lt_LIPO
+
+# ldd/readelf like tool for Mach-O binaries on Mac OS X.
+OTOOL=$lt_OTOOL
+
+# ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4.
+OTOOL64=$lt_OTOOL64
+
+# Old archive suffix (normally "a").
+libext=$libext
+
+# Shared library suffix (normally ".so").
+shrext_cmds=$lt_shrext_cmds
+
+# The commands to extract the exported symbol list from a shared archive.
+extract_expsyms_cmds=$lt_extract_expsyms_cmds
+
+# Variables whose values should be saved in libtool wrapper scripts and
+# restored at link time.
+variables_saved_for_relink=$lt_variables_saved_for_relink
+
+# Do we need the "lib" prefix for modules?
+need_lib_prefix=$need_lib_prefix
+
+# Do we need a version for libraries?
+need_version=$need_version
+
+# Library versioning type.
+version_type=$version_type
+
+# Shared library runtime path variable.
+runpath_var=$runpath_var
+
+# Shared library path variable.
+shlibpath_var=$shlibpath_var
+
+# Is shlibpath searched before the hard-coded library search path?
+shlibpath_overrides_runpath=$shlibpath_overrides_runpath
+
+# Format of library name prefix.
+libname_spec=$lt_libname_spec
+
+# List of archive names.  First name is the real one, the rest are links.
+# The last name is the one that the linker finds with -lNAME
+library_names_spec=$lt_library_names_spec
+
+# The coded name of the library, if different from the real name.
+soname_spec=$lt_soname_spec
+
+# Permission mode override for installation of shared libraries.
+install_override_mode=$lt_install_override_mode
+
+# Command to use after installation of a shared archive.
+postinstall_cmds=$lt_postinstall_cmds
+
+# Command to use after uninstallation of a shared archive.
+postuninstall_cmds=$lt_postuninstall_cmds
+
+# Commands used to finish a libtool library installation in a directory.
+finish_cmds=$lt_finish_cmds
+
+# As "finish_cmds", except a single script fragment to be evaled but
+# not shown.
+finish_eval=$lt_finish_eval
+
+# Whether we should hardcode library paths into libraries.
+hardcode_into_libs=$hardcode_into_libs
+
+# Compile-time system search path for libraries.
+sys_lib_search_path_spec=$lt_sys_lib_search_path_spec
+
+# Detected run-time system search path for libraries.
+sys_lib_dlsearch_path_spec=$lt_configure_time_dlsearch_path
+
+# Explicit LT_SYS_LIBRARY_PATH set during ./configure time.
+configure_time_lt_sys_library_path=$lt_configure_time_lt_sys_library_path
+
+# Whether dlopen is supported.
+dlopen_support=$enable_dlopen
+
+# Whether dlopen of programs is supported.
+dlopen_self=$enable_dlopen_self
+
+# Whether dlopen of statically linked programs is supported.
+dlopen_self_static=$enable_dlopen_self_static
+
+# Commands to strip libraries.
+old_striplib=$lt_old_striplib
+striplib=$lt_striplib
+
+
+# The linker used to build libraries.
+LD=$lt_LD
+
+# How to create reloadable object files.
+reload_flag=$lt_reload_flag
+reload_cmds=$lt_reload_cmds
+
+# Commands used to build an old-style archive.
+old_archive_cmds=$lt_old_archive_cmds
+
+# A language specific compiler.
+CC=$lt_compiler
+
+# Is the compiler the GNU compiler?
+with_gcc=$GCC
+
+# Compiler flag to turn off builtin functions.
+no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag
+
+# Additional compiler flags for building library objects.
+pic_flag=$lt_lt_prog_compiler_pic
+
+# How to pass a linker flag through the compiler.
+wl=$lt_lt_prog_compiler_wl
+
+# Compiler flag to prevent dynamic linking.
+link_static_flag=$lt_lt_prog_compiler_static
+
+# Does compiler simultaneously support -c and -o options?
+compiler_c_o=$lt_lt_cv_prog_compiler_c_o
+
+# Whether or not to add -lc for building shared libraries.
+build_libtool_need_lc=$archive_cmds_need_lc
+
+# Whether or not to disallow shared libs when runtime libs are static.
+allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes
+
+# Compiler flag to allow reflexive dlopens.
+export_dynamic_flag_spec=$lt_export_dynamic_flag_spec
+
+# Compiler flag to generate shared objects directly from archives.
+whole_archive_flag_spec=$lt_whole_archive_flag_spec
+
+# Whether the compiler copes with passing no objects directly.
+compiler_needs_object=$lt_compiler_needs_object
+
+# Create an old-style archive from a shared archive.
+old_archive_from_new_cmds=$lt_old_archive_from_new_cmds
+
+# Create a temporary old-style archive to link instead of a shared archive.
+old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds
+
+# Commands used to build a shared archive.
+archive_cmds=$lt_archive_cmds
+archive_expsym_cmds=$lt_archive_expsym_cmds
+
+# Commands used to build a loadable module if different from building
+# a shared archive.
+module_cmds=$lt_module_cmds
+module_expsym_cmds=$lt_module_expsym_cmds
+
+# Whether we are building with GNU ld or not.
+with_gnu_ld=$lt_with_gnu_ld
+
+# Flag that allows shared libraries with undefined symbols to be built.
+allow_undefined_flag=$lt_allow_undefined_flag
+
+# Flag that enforces no undefined symbols.
+no_undefined_flag=$lt_no_undefined_flag
+
+# Flag to hardcode \$libdir into a binary during linking.
+# This must work even if \$libdir does not exist
+hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec
+
+# Whether we need a single "-rpath" flag with a separated argument.
+hardcode_libdir_separator=$lt_hardcode_libdir_separator
+
+# Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes
+# DIR into the resulting binary.
+hardcode_direct=$hardcode_direct
+
+# Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes
+# DIR into the resulting binary and the resulting library dependency is
+# "absolute",i.e impossible to change by setting \$shlibpath_var if the
+# library is relocated.
+hardcode_direct_absolute=$hardcode_direct_absolute
+
+# Set to "yes" if using the -LDIR flag during linking hardcodes DIR
+# into the resulting binary.
+hardcode_minus_L=$hardcode_minus_L
+
+# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR
+# into the resulting binary.
+hardcode_shlibpath_var=$hardcode_shlibpath_var
+
+# Set to "yes" if building a shared library automatically hardcodes DIR
+# into the library and all subsequent libraries and executables linked
+# against it.
+hardcode_automatic=$hardcode_automatic
+
+# Set to yes if linker adds runtime paths of dependent libraries
+# to runtime path list.
+inherit_rpath=$inherit_rpath
+
+# Whether libtool must link a program against all its dependency libraries.
+link_all_deplibs=$link_all_deplibs
+
+# Set to "yes" if exported symbols are required.
+always_export_symbols=$always_export_symbols
+
+# The commands to list exported symbols.
+export_symbols_cmds=$lt_export_symbols_cmds
+
+# Symbols that should not be listed in the preloaded symbols.
+exclude_expsyms=$lt_exclude_expsyms
+
+# Symbols that must always be exported.
+include_expsyms=$lt_include_expsyms
+
+# Commands necessary for linking programs (against libraries) with templates.
+prelink_cmds=$lt_prelink_cmds
+
+# Commands necessary for finishing linking programs.
+postlink_cmds=$lt_postlink_cmds
+
+# Specify filename containing input files.
+file_list_spec=$lt_file_list_spec
+
+# How to hardcode a shared library path into an executable.
+hardcode_action=$hardcode_action
+
+# ### END LIBTOOL CONFIG
+
+_LT_EOF
+
+    cat <<'_LT_EOF' >> "$cfgfile"
+
+# ### BEGIN FUNCTIONS SHARED WITH CONFIGURE
+
+# func_munge_path_list VARIABLE PATH
+# -----------------------------------
+# VARIABLE is name of variable containing _space_ separated list of
+# directories to be munged by the contents of PATH, which is string
+# having a format:
+# "DIR[:DIR]:"
+#       string "DIR[ DIR]" will be prepended to VARIABLE
+# ":DIR[:DIR]"
+#       string "DIR[ DIR]" will be appended to VARIABLE
+# "DIRP[:DIRP]::[DIRA:]DIRA"
+#       string "DIRP[ DIRP]" will be prepended to VARIABLE and string
+#       "DIRA[ DIRA]" will be appended to VARIABLE
+# "DIR[:DIR]"
+#       VARIABLE will be replaced by "DIR[ DIR]"
+func_munge_path_list ()
+{
+    case x$2 in
+    x)
+        ;;
+    *:)
+        eval $1=\"`$ECHO $2 | $SED 's/:/ /g'` \$$1\"
+        ;;
+    x:*)
+        eval $1=\"\$$1 `$ECHO $2 | $SED 's/:/ /g'`\"
+        ;;
+    *::*)
+        eval $1=\"\$$1\ `$ECHO $2 | $SED -e 's/.*:://' -e 's/:/ /g'`\"
+        eval $1=\"`$ECHO $2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \$$1\"
+        ;;
+    *)
+        eval $1=\"`$ECHO $2 | $SED 's/:/ /g'`\"
+        ;;
+    esac
+}
+
+
+# Calculate cc_basename.  Skip known compiler wrappers and cross-prefix.
+func_cc_basename ()
+{
+    for cc_temp in $*""; do
+      case $cc_temp in
+        compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
+        distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
+        \-*) ;;
+        *) break;;
+      esac
+    done
+    func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"`
+}
+
+
+# ### END FUNCTIONS SHARED WITH CONFIGURE
+
+_LT_EOF
+
+  case $host_os in
+  aix3*)
+    cat <<\_LT_EOF >> "$cfgfile"
+# AIX sometimes has problems with the GCC collect2 program.  For some
+# reason, if we set the COLLECT_NAMES environment variable, the problems
+# vanish in a puff of smoke.
+if test set != "${COLLECT_NAMES+set}"; then
+  COLLECT_NAMES=
+  export COLLECT_NAMES
+fi
+_LT_EOF
+    ;;
+  esac
+
+
+ltmain=$ac_aux_dir/ltmain.sh
+
+
+  # We use sed instead of cat because bash on DJGPP gets confused if
+  # if finds mixed CR/LF and LF-only lines.  Since sed operates in
+  # text mode, it properly converts lines to CR/LF.  This bash problem
+  # is reportedly fixed, but why not run on old versions too?
+  sed '$q' "$ltmain" >> "$cfgfile" \
+     || (rm -f "$cfgfile"; exit 1)
+
+   mv -f "$cfgfile" "$ofile" ||
+    (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile")
+  chmod +x "$ofile"
+
+ ;;
+
+  esac
+done # for ac_tag
+
+
+as_fn_exit 0
+_ACEOF
+ac_clean_files=$ac_clean_files_save
+
+test $ac_write_fail = 0 ||
+  as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5
+
+
+# configure is writing to config.log, and then calls config.status.
+# config.status does its own redirection, appending to config.log.
+# Unfortunately, on DOS this fails, as config.log is still kept open
+# by configure, so config.status won't be able to write to it; its
+# output is simply discarded.  So we exec the FD to /dev/null,
+# effectively closing config.log, so it can be properly (re)opened and
+# appended to by config.status.  When coming back to configure, we
+# need to make the FD available again.
+if test "$no_create" != yes; then
+  ac_cs_success=:
+  ac_config_status_args=
+  test "$silent" = yes &&
+    ac_config_status_args="$ac_config_status_args --quiet"
+  exec 5>/dev/null
+  $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
+  exec 5>>config.log
+  # Use ||, not &&, to avoid exiting from the if with $? = 1, which
+  # would make configure fail if this is the last instruction.
+  $ac_cs_success || as_fn_exit 1
+fi
+if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5
+$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;}
+fi
+
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/configure.ac
@@ -0,0 +1,150 @@
+/*
+ * This file is part of the ZFS Linux port.
+ *
+ * Copyright (c) 2009 Lawrence Livermore National Security, LLC.
+ * Produced at Lawrence Livermore National Laboratory
+ * Written by:
+ *         Brian Behlendorf <behlendorf1@llnl.gov>,
+ *         Herb Wartens <wartens2@llnl.gov>,
+ *         Jim Garlick <garlick@llnl.gov>
+ * LLNL-CODE-403049
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License").  You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+AC_INIT(m4_esyscmd(grep Name META | cut -d ':' -f 2 | tr -d ' \n'),
+	m4_esyscmd(grep Version META | cut -d ':' -f 2 | tr -d ' \n'))
+AC_LANG(C)
+ZFS_AC_META
+AC_CONFIG_AUX_DIR([config])
+AC_CONFIG_MACRO_DIR([config])
+AC_CANONICAL_SYSTEM
+AM_MAINTAINER_MODE
+m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
+AM_INIT_AUTOMAKE
+AC_CONFIG_HEADERS([zfs_config.h], [
+	(mv zfs_config.h zfs_config.h.tmp &&
+	awk -f ${ac_srcdir}/config/config.awk zfs_config.h.tmp >zfs_config.h &&
+	rm zfs_config.h.tmp) || exit 1])
+
+AC_PROG_INSTALL
+AC_PROG_CC
+AC_PROG_LIBTOOL
+AM_PROG_AS
+
+ZFS_AC_LICENSE
+ZFS_AC_PACKAGE
+ZFS_AC_CONFIG
+ZFS_AC_DEBUG
+ZFS_AC_DEBUG_DMU_TX
+
+AC_CONFIG_FILES([ 
+	Makefile
+	udev/Makefile
+	udev/rules.d/Makefile
+	etc/Makefile
+	etc/init.d/Makefile
+	etc/zfs/Makefile
+	etc/systemd/Makefile
+	etc/systemd/system/Makefile
+	etc/modules-load.d/Makefile
+	man/Makefile
+	man/man1/Makefile
+	man/man5/Makefile
+	man/man8/Makefile
+	lib/Makefile
+	lib/libspl/Makefile
+	lib/libspl/asm-generic/Makefile
+	lib/libspl/asm-i386/Makefile
+	lib/libspl/asm-x86_64/Makefile
+	lib/libspl/include/Makefile
+	lib/libspl/include/ia32/Makefile
+	lib/libspl/include/ia32/sys/Makefile
+	lib/libspl/include/rpc/Makefile
+	lib/libspl/include/sys/Makefile
+	lib/libspl/include/sys/sysevent/Makefile
+	lib/libspl/include/sys/dktp/Makefile
+	lib/libspl/include/util/Makefile
+	lib/libavl/Makefile
+	lib/libefi/Makefile
+	lib/libnvpair/Makefile
+	lib/libunicode/Makefile
+	lib/libuutil/Makefile
+	lib/libzpool/Makefile
+	lib/libzfs/libzfs.pc
+	lib/libzfs/libzfs_core.pc
+	lib/libzfs/Makefile
+	lib/libzfs_core/Makefile
+	lib/libshare/Makefile
+	cmd/Makefile
+	cmd/zdb/Makefile
+	cmd/zhack/Makefile
+	cmd/zfs/Makefile
+	cmd/zinject/Makefile
+	cmd/zpool/Makefile
+	cmd/zstreamdump/Makefile
+	cmd/ztest/Makefile
+	cmd/zpios/Makefile
+	cmd/mount_zfs/Makefile
+	cmd/fsck_zfs/Makefile
+	cmd/zvol_id/Makefile
+	cmd/vdev_id/Makefile
+	cmd/arcstat/Makefile
+	cmd/dbufstat/Makefile
+	cmd/arc_summary/Makefile
+	cmd/zed/Makefile
+	contrib/Makefile
+	contrib/bash_completion.d/Makefile
+	contrib/dracut/Makefile
+	contrib/dracut/90zfs/Makefile
+	contrib/initramfs/Makefile
+	module/Makefile
+	module/avl/Makefile
+	module/nvpair/Makefile
+	module/unicode/Makefile
+	module/zcommon/Makefile
+	module/zfs/Makefile
+	module/zpios/Makefile
+	include/Makefile
+	include/linux/Makefile
+	include/sys/Makefile
+	include/sys/fs/Makefile
+	include/sys/fm/Makefile
+	include/sys/fm/fs/Makefile
+	scripts/Makefile
+	scripts/zpios-profile/Makefile
+	scripts/zpios-test/Makefile
+	scripts/zpool-config/Makefile
+	scripts/common.sh
+	rpm/Makefile
+	rpm/redhat/Makefile
+	rpm/redhat/zfs.spec
+	rpm/redhat/zfs-kmod.spec
+	rpm/redhat/zfs-dkms.spec
+	rpm/generic/Makefile
+	rpm/generic/zfs.spec
+	rpm/generic/zfs-kmod.spec
+	rpm/generic/zfs-dkms.spec
+	zfs-script-config.sh
+	zfs.release
+])
+
+AC_OUTPUT
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/contrib/Makefile.am
@@ -0,0 +1,2 @@
+SUBDIRS = bash_completion.d dracut initramfs
+DIST_SUBDIRS = bash_completion.d dracut initramfs
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/contrib/Makefile.in
@@ -0,0 +1,779 @@
+# Makefile.in generated by automake 1.15 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2014 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+VPATH = @srcdir@
+am__is_gnu_make = { \
+  if test -z '$(MAKELEVEL)'; then \
+    false; \
+  elif test -n '$(MAKE_HOST)'; then \
+    true; \
+  elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+    true; \
+  else \
+    false; \
+  fi; \
+}
+am__make_running_with_option = \
+  case $${target_option-} in \
+      ?) ;; \
+      *) echo "am__make_running_with_option: internal error: invalid" \
+              "target option '$${target_option-}' specified" >&2; \
+         exit 1;; \
+  esac; \
+  has_opt=no; \
+  sane_makeflags=$$MAKEFLAGS; \
+  if $(am__is_gnu_make); then \
+    sane_makeflags=$$MFLAGS; \
+  else \
+    case $$MAKEFLAGS in \
+      *\\[\ \	]*) \
+        bs=\\; \
+        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
+    esac; \
+  fi; \
+  skip_next=no; \
+  strip_trailopt () \
+  { \
+    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+  }; \
+  for flg in $$sane_makeflags; do \
+    test $$skip_next = yes && { skip_next=no; continue; }; \
+    case $$flg in \
+      *=*|--*) continue;; \
+        -*I) strip_trailopt 'I'; skip_next=yes;; \
+      -*I?*) strip_trailopt 'I';; \
+        -*O) strip_trailopt 'O'; skip_next=yes;; \
+      -*O?*) strip_trailopt 'O';; \
+        -*l) strip_trailopt 'l'; skip_next=yes;; \
+      -*l?*) strip_trailopt 'l';; \
+      -[dEDm]) skip_next=yes;; \
+      -[JT]) skip_next=yes;; \
+    esac; \
+    case $$flg in \
+      *$$target_option*) has_opt=yes; break;; \
+    esac; \
+  done; \
+  test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+target_triplet = @target@
+subdir = contrib
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/config/always-no-bool-compare.m4 \
+	$(top_srcdir)/config/always-no-unused-but-set-variable.m4 \
+	$(top_srcdir)/config/dkms.m4 \
+	$(top_srcdir)/config/kernel-acl.m4 \
+	$(top_srcdir)/config/kernel-automount.m4 \
+	$(top_srcdir)/config/kernel-bdev-block-device-operations.m4 \
+	$(top_srcdir)/config/kernel-bdev-logical-size.m4 \
+	$(top_srcdir)/config/kernel-bdev-physical-size.m4 \
+	$(top_srcdir)/config/kernel-bdi-setup-and-register.m4 \
+	$(top_srcdir)/config/kernel-bio-bvec-iter.m4 \
+	$(top_srcdir)/config/kernel-bio-end-io-t-args.m4 \
+	$(top_srcdir)/config/kernel-bio-failfast.m4 \
+	$(top_srcdir)/config/kernel-bio-rw-barrier.m4 \
+	$(top_srcdir)/config/kernel-bio-rw-discard.m4 \
+	$(top_srcdir)/config/kernel-blk-queue-flush.m4 \
+	$(top_srcdir)/config/kernel-blk-queue-max-hw-sectors.m4 \
+	$(top_srcdir)/config/kernel-blk-queue-max-segments.m4 \
+	$(top_srcdir)/config/kernel-blkdev-get-by-path.m4 \
+	$(top_srcdir)/config/kernel-blkdev-get.m4 \
+	$(top_srcdir)/config/kernel-block-device-operations-release-void.m4 \
+	$(top_srcdir)/config/kernel-check-disk-size-change.m4 \
+	$(top_srcdir)/config/kernel-clear-inode.m4 \
+	$(top_srcdir)/config/kernel-commit-metadata.m4 \
+	$(top_srcdir)/config/kernel-create-nameidata.m4 \
+	$(top_srcdir)/config/kernel-current_bio_tail.m4 \
+	$(top_srcdir)/config/kernel-d-make-root.m4 \
+	$(top_srcdir)/config/kernel-d-obtain-alias.m4 \
+	$(top_srcdir)/config/kernel-d-prune-aliases.m4 \
+	$(top_srcdir)/config/kernel-declare-event-class.m4 \
+	$(top_srcdir)/config/kernel-dentry-operations.m4 \
+	$(top_srcdir)/config/kernel-dirty-inode.m4 \
+	$(top_srcdir)/config/kernel-discard-granularity.m4 \
+	$(top_srcdir)/config/kernel-elevator-change.m4 \
+	$(top_srcdir)/config/kernel-encode-fh-inode.m4 \
+	$(top_srcdir)/config/kernel-evict-inode.m4 \
+	$(top_srcdir)/config/kernel-fallocate.m4 \
+	$(top_srcdir)/config/kernel-file-inode.m4 \
+	$(top_srcdir)/config/kernel-fmode-t.m4 \
+	$(top_srcdir)/config/kernel-follow-down-one.m4 \
+	$(top_srcdir)/config/kernel-fsync.m4 \
+	$(top_srcdir)/config/kernel-generic_io_acct.m4 \
+	$(top_srcdir)/config/kernel-get-disk-ro.m4 \
+	$(top_srcdir)/config/kernel-get-gendisk.m4 \
+	$(top_srcdir)/config/kernel-get-link.m4 \
+	$(top_srcdir)/config/kernel-insert-inode-locked.m4 \
+	$(top_srcdir)/config/kernel-invalidate-bdev-args.m4 \
+	$(top_srcdir)/config/kernel-is_owner_or_cap.m4 \
+	$(top_srcdir)/config/kernel-kmap-atomic-args.m4 \
+	$(top_srcdir)/config/kernel-kobj-name-len.m4 \
+	$(top_srcdir)/config/kernel-lookup-bdev.m4 \
+	$(top_srcdir)/config/kernel-lookup-nameidata.m4 \
+	$(top_srcdir)/config/kernel-lseek-execute.m4 \
+	$(top_srcdir)/config/kernel-mk-request-fn.m4 \
+	$(top_srcdir)/config/kernel-mkdir-umode-t.m4 \
+	$(top_srcdir)/config/kernel-mount-nodev.m4 \
+	$(top_srcdir)/config/kernel-open-bdev-exclusive.m4 \
+	$(top_srcdir)/config/kernel-put-link.m4 \
+	$(top_srcdir)/config/kernel-security-inode-init.m4 \
+	$(top_srcdir)/config/kernel-set-nlink.m4 \
+	$(top_srcdir)/config/kernel-sget-args.m4 \
+	$(top_srcdir)/config/kernel-show-options.m4 \
+	$(top_srcdir)/config/kernel-shrink.m4 \
+	$(top_srcdir)/config/kernel-truncate-range.m4 \
+	$(top_srcdir)/config/kernel-truncate-setsize.m4 \
+	$(top_srcdir)/config/kernel-vfs-iterate.m4 \
+	$(top_srcdir)/config/kernel-vfs-rw-iterate.m4 \
+	$(top_srcdir)/config/kernel-xattr-handler.m4 \
+	$(top_srcdir)/config/kernel.m4 $(top_srcdir)/config/libtool.m4 \
+	$(top_srcdir)/config/ltoptions.m4 \
+	$(top_srcdir)/config/ltsugar.m4 \
+	$(top_srcdir)/config/ltversion.m4 \
+	$(top_srcdir)/config/lt~obsolete.m4 \
+	$(top_srcdir)/config/mount-helper.m4 \
+	$(top_srcdir)/config/user-arch.m4 \
+	$(top_srcdir)/config/user-dracut.m4 \
+	$(top_srcdir)/config/user-frame-larger-than.m4 \
+	$(top_srcdir)/config/user-libblkid.m4 \
+	$(top_srcdir)/config/user-libuuid.m4 \
+	$(top_srcdir)/config/user-runstatedir.m4 \
+	$(top_srcdir)/config/user-systemd.m4 \
+	$(top_srcdir)/config/user-sysvinit.m4 \
+	$(top_srcdir)/config/user-udev.m4 \
+	$(top_srcdir)/config/user-zlib.m4 $(top_srcdir)/config/user.m4 \
+	$(top_srcdir)/config/zfs-build.m4 \
+	$(top_srcdir)/config/zfs-meta.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/zfs_config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo "  GEN     " $@;
+am__v_GEN_1 = 
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 = 
+SOURCES =
+DIST_SOURCES =
+RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \
+	ctags-recursive dvi-recursive html-recursive info-recursive \
+	install-data-recursive install-dvi-recursive \
+	install-exec-recursive install-html-recursive \
+	install-info-recursive install-pdf-recursive \
+	install-ps-recursive install-recursive installcheck-recursive \
+	installdirs-recursive pdf-recursive ps-recursive \
+	tags-recursive uninstall-recursive
+am__can_run_installinfo = \
+  case $$AM_UPDATE_INFO_DIR in \
+    n|no|NO) false;; \
+    *) (install-info --version) >/dev/null 2>&1;; \
+  esac
+RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive	\
+  distclean-recursive maintainer-clean-recursive
+am__recursive_targets = \
+  $(RECURSIVE_TARGETS) \
+  $(RECURSIVE_CLEAN_TARGETS) \
+  $(am__extra_recursive_targets)
+AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \
+	distdir
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates.  Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+  BEGIN { nonempty = 0; } \
+  { items[$$0] = 1; nonempty = 1; } \
+  END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique.  This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+  list='$(am__tagged_files)'; \
+  unique=`for i in $$list; do \
+    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+  done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+am__DIST_COMMON = $(srcdir)/Makefile.in
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+am__relativize = \
+  dir0=`pwd`; \
+  sed_first='s,^\([^/]*\)/.*$$,\1,'; \
+  sed_rest='s,^[^/]*/*,,'; \
+  sed_last='s,^.*/\([^/]*\)$$,\1,'; \
+  sed_butlast='s,/*[^/]*$$,,'; \
+  while test -n "$$dir1"; do \
+    first=`echo "$$dir1" | sed -e "$$sed_first"`; \
+    if test "$$first" != "."; then \
+      if test "$$first" = ".."; then \
+        dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \
+        dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \
+      else \
+        first2=`echo "$$dir2" | sed -e "$$sed_first"`; \
+        if test "$$first2" = "$$first"; then \
+          dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \
+        else \
+          dir2="../$$dir2"; \
+        fi; \
+        dir0="$$dir0"/"$$first"; \
+      fi; \
+    fi; \
+    dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \
+  done; \
+  reldir="$$dir2"
+ACLOCAL = @ACLOCAL@
+ALIEN = @ALIEN@
+ALIEN_VERSION = @ALIEN_VERSION@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCAS = @CCAS@
+CCASDEPMODE = @CCASDEPMODE@
+CCASFLAGS = @CCASFLAGS@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEBUG_CFLAGS = @DEBUG_CFLAGS@
+DEBUG_DMU_TX = @DEBUG_DMU_TX@
+DEBUG_STACKFLAGS = @DEBUG_STACKFLAGS@
+DEBUG_ZFS = @DEBUG_ZFS@
+DEFAULT_INITCONF_DIR = @DEFAULT_INITCONF_DIR@
+DEFAULT_INIT_DIR = @DEFAULT_INIT_DIR@
+DEFAULT_INIT_SCRIPT = @DEFAULT_INIT_SCRIPT@
+DEFAULT_PACKAGE = @DEFAULT_PACKAGE@
+DEFINE_INITRAMFS = @DEFINE_INITRAMFS@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DPKG = @DPKG@
+DPKGBUILD = @DPKGBUILD@
+DPKGBUILD_VERSION = @DPKGBUILD_VERSION@
+DPKG_VERSION = @DPKG_VERSION@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+FRAME_LARGER_THAN = @FRAME_LARGER_THAN@
+GREP = @GREP@
+HAVE_ALIEN = @HAVE_ALIEN@
+HAVE_DPKG = @HAVE_DPKG@
+HAVE_DPKGBUILD = @HAVE_DPKGBUILD@
+HAVE_RPM = @HAVE_RPM@
+HAVE_RPMBUILD = @HAVE_RPMBUILD@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+KERNELCPPFLAGS = @KERNELCPPFLAGS@
+KERNELMAKE_PARAMS = @KERNELMAKE_PARAMS@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBBLKID = @LIBBLKID@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIBUUID = @LIBUUID@
+LINUX = @LINUX@
+LINUX_OBJ = @LINUX_OBJ@
+LINUX_SYMBOLS = @LINUX_SYMBOLS@
+LINUX_VERSION = @LINUX_VERSION@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NO_BOOL_COMPARE = @NO_BOOL_COMPARE@
+NO_UNUSED_BUT_SET_VARIABLE = @NO_UNUSED_BUT_SET_VARIABLE@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+RANLIB = @RANLIB@
+RELEASE = @RELEASE@
+RPM = @RPM@
+RPMBUILD = @RPMBUILD@
+RPMBUILD_VERSION = @RPMBUILD_VERSION@
+RPM_DEFINE_COMMON = @RPM_DEFINE_COMMON@
+RPM_DEFINE_DKMS = @RPM_DEFINE_DKMS@
+RPM_DEFINE_KMOD = @RPM_DEFINE_KMOD@
+RPM_DEFINE_UTIL = @RPM_DEFINE_UTIL@
+RPM_SPEC_DIR = @RPM_SPEC_DIR@
+RPM_VERSION = @RPM_VERSION@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SPL = @SPL@
+SPL_OBJ = @SPL_OBJ@
+SPL_SYMBOLS = @SPL_SYMBOLS@
+SPL_VERSION = @SPL_VERSION@
+SRPM_DEFINE_COMMON = @SRPM_DEFINE_COMMON@
+SRPM_DEFINE_DKMS = @SRPM_DEFINE_DKMS@
+SRPM_DEFINE_KMOD = @SRPM_DEFINE_KMOD@
+SRPM_DEFINE_UTIL = @SRPM_DEFINE_UTIL@
+STRIP = @STRIP@
+TARGET_ASM_DIR = @TARGET_ASM_DIR@
+VENDOR = @VENDOR@
+VERSION = @VERSION@
+ZFS_CONFIG = @ZFS_CONFIG@
+ZFS_INIT_SYSTEMD = @ZFS_INIT_SYSTEMD@
+ZFS_INIT_SYSV = @ZFS_INIT_SYSV@
+ZFS_META_ALIAS = @ZFS_META_ALIAS@
+ZFS_META_AUTHOR = @ZFS_META_AUTHOR@
+ZFS_META_DATA = @ZFS_META_DATA@
+ZFS_META_LICENSE = @ZFS_META_LICENSE@
+ZFS_META_LT_AGE = @ZFS_META_LT_AGE@
+ZFS_META_LT_CURRENT = @ZFS_META_LT_CURRENT@
+ZFS_META_LT_REVISION = @ZFS_META_LT_REVISION@
+ZFS_META_NAME = @ZFS_META_NAME@
+ZFS_META_RELEASE = @ZFS_META_RELEASE@
+ZFS_META_VERSION = @ZFS_META_VERSION@
+ZFS_MODULE_LOAD = @ZFS_MODULE_LOAD@
+ZLIB = @ZLIB@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dracutdir = @dracutdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+modulesloaddir = @modulesloaddir@
+mounthelperdir = @mounthelperdir@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+runstatedir = @runstatedir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+systemdpresetdir = @systemdpresetdir@
+systemdunitdir = @systemdunitdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+udevdir = @udevdir@
+udevruledir = @udevruledir@
+SUBDIRS = bash_completion.d dracut initramfs
+DIST_SUBDIRS = bash_completion.d dracut initramfs
+all: all-recursive
+
+.SUFFIXES:
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+	        && { if test -f $@; then exit 0; else break; fi; }; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu contrib/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --gnu contrib/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+	esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
+
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run 'make' without going through this Makefile.
+# To change the values of 'make' variables: instead of editing Makefiles,
+# (1) if the variable is set in 'config.status', edit 'config.status'
+#     (which will cause the Makefiles to be regenerated when you run 'make');
+# (2) otherwise, pass the desired values on the 'make' command line.
+$(am__recursive_targets):
+	@fail=; \
+	if $(am__make_keepgoing); then \
+	  failcom='fail=yes'; \
+	else \
+	  failcom='exit 1'; \
+	fi; \
+	dot_seen=no; \
+	target=`echo $@ | sed s/-recursive//`; \
+	case "$@" in \
+	  distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
+	  *) list='$(SUBDIRS)' ;; \
+	esac; \
+	for subdir in $$list; do \
+	  echo "Making $$target in $$subdir"; \
+	  if test "$$subdir" = "."; then \
+	    dot_seen=yes; \
+	    local_target="$$target-am"; \
+	  else \
+	    local_target="$$target"; \
+	  fi; \
+	  ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+	  || eval $$failcom; \
+	done; \
+	if test "$$dot_seen" = "no"; then \
+	  $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+	fi; test -z "$$fail"
+
+ID: $(am__tagged_files)
+	$(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-recursive
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	set x; \
+	here=`pwd`; \
+	if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
+	  include_option=--etags-include; \
+	  empty_fix=.; \
+	else \
+	  include_option=--include; \
+	  empty_fix=; \
+	fi; \
+	list='$(SUBDIRS)'; for subdir in $$list; do \
+	  if test "$$subdir" = .; then :; else \
+	    test ! -f $$subdir/TAGS || \
+	      set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \
+	  fi; \
+	done; \
+	$(am__define_uniq_tagged_files); \
+	shift; \
+	if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+	  test -n "$$unique" || unique=$$empty_fix; \
+	  if test $$# -gt 0; then \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      "$$@" $$unique; \
+	  else \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      $$unique; \
+	  fi; \
+	fi
+ctags: ctags-recursive
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	$(am__define_uniq_tagged_files); \
+	test -z "$(CTAGS_ARGS)$$unique" \
+	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+	     $$unique
+
+GTAGS:
+	here=`$(am__cd) $(top_builddir) && pwd` \
+	  && $(am__cd) $(top_srcdir) \
+	  && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-recursive
+
+cscopelist-am: $(am__tagged_files)
+	list='$(am__tagged_files)'; \
+	case "$(srcdir)" in \
+	  [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+	  *) sdir=$(subdir)/$(srcdir) ;; \
+	esac; \
+	for i in $$list; do \
+	  if test -f "$$i"; then \
+	    echo "$(subdir)/$$i"; \
+	  else \
+	    echo "$$sdir/$$i"; \
+	  fi; \
+	done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	list='$(DISTFILES)'; \
+	  dist_files=`for file in $$list; do echo $$file; done | \
+	  sed -e "s|^$$srcdirstrip/||;t" \
+	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+	case $$dist_files in \
+	  */*) $(MKDIR_P) `echo "$$dist_files" | \
+			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+			   sort -u` ;; \
+	esac; \
+	for file in $$dist_files; do \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  if test -d $$d/$$file; then \
+	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+	    if test -d "$(distdir)/$$file"; then \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+	  else \
+	    test -f "$(distdir)/$$file" \
+	    || cp -p $$d/$$file "$(distdir)/$$file" \
+	    || exit 1; \
+	  fi; \
+	done
+	@list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
+	  if test "$$subdir" = .; then :; else \
+	    $(am__make_dryrun) \
+	      || test -d "$(distdir)/$$subdir" \
+	      || $(MKDIR_P) "$(distdir)/$$subdir" \
+	      || exit 1; \
+	    dir1=$$subdir; dir2="$(distdir)/$$subdir"; \
+	    $(am__relativize); \
+	    new_distdir=$$reldir; \
+	    dir1=$$subdir; dir2="$(top_distdir)"; \
+	    $(am__relativize); \
+	    new_top_distdir=$$reldir; \
+	    echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \
+	    echo "     am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \
+	    ($(am__cd) $$subdir && \
+	      $(MAKE) $(AM_MAKEFLAGS) \
+	        top_distdir="$$new_top_distdir" \
+	        distdir="$$new_distdir" \
+		am__remove_distdir=: \
+		am__skip_length_check=: \
+		am__skip_mode_fix=: \
+	        distdir) \
+	      || exit 1; \
+	  fi; \
+	done
+check-am: all-am
+check: check-recursive
+all-am: Makefile
+installdirs: installdirs-recursive
+installdirs-am:
+install: install-recursive
+install-exec: install-exec-recursive
+install-data: install-data-recursive
+uninstall: uninstall-recursive
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-recursive
+install-strip:
+	if test -z '$(STRIP)'; then \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	      install; \
+	else \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+	fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+clean: clean-recursive
+
+clean-am: clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-recursive
+	-rm -f Makefile
+distclean-am: clean-am distclean-generic distclean-tags
+
+dvi: dvi-recursive
+
+dvi-am:
+
+html: html-recursive
+
+html-am:
+
+info: info-recursive
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-recursive
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-recursive
+
+install-html-am:
+
+install-info: install-info-recursive
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-recursive
+
+install-pdf-am:
+
+install-ps: install-ps-recursive
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-recursive
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-recursive
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-recursive
+
+pdf-am:
+
+ps: ps-recursive
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: $(am__recursive_targets) install-am install-strip
+
+.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \
+	check-am clean clean-generic clean-libtool cscopelist-am ctags \
+	ctags-am distclean distclean-generic distclean-libtool \
+	distclean-tags distdir dvi dvi-am html html-am info info-am \
+	install install-am install-data install-data-am install-dvi \
+	install-dvi-am install-exec install-exec-am install-html \
+	install-html-am install-info install-info-am install-man \
+	install-pdf install-pdf-am install-ps install-ps-am \
+	install-strip installcheck installcheck-am installdirs \
+	installdirs-am maintainer-clean maintainer-clean-generic \
+	mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \
+	ps ps-am tags tags-am uninstall uninstall-am
+
+.PRECIOUS: Makefile
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/contrib/bash_completion.d/Makefile.am
@@ -0,0 +1,5 @@
+bashcompletiondir = $(sysconfdir)/bash_completion.d
+
+noinst_DATA = zfs
+
+EXTRA_DIST = $(noinst_DATA)
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/contrib/bash_completion.d/Makefile.in
@@ -0,0 +1,603 @@
+# Makefile.in generated by automake 1.15 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2014 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+VPATH = @srcdir@
+am__is_gnu_make = { \
+  if test -z '$(MAKELEVEL)'; then \
+    false; \
+  elif test -n '$(MAKE_HOST)'; then \
+    true; \
+  elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+    true; \
+  else \
+    false; \
+  fi; \
+}
+am__make_running_with_option = \
+  case $${target_option-} in \
+      ?) ;; \
+      *) echo "am__make_running_with_option: internal error: invalid" \
+              "target option '$${target_option-}' specified" >&2; \
+         exit 1;; \
+  esac; \
+  has_opt=no; \
+  sane_makeflags=$$MAKEFLAGS; \
+  if $(am__is_gnu_make); then \
+    sane_makeflags=$$MFLAGS; \
+  else \
+    case $$MAKEFLAGS in \
+      *\\[\ \	]*) \
+        bs=\\; \
+        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
+    esac; \
+  fi; \
+  skip_next=no; \
+  strip_trailopt () \
+  { \
+    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+  }; \
+  for flg in $$sane_makeflags; do \
+    test $$skip_next = yes && { skip_next=no; continue; }; \
+    case $$flg in \
+      *=*|--*) continue;; \
+        -*I) strip_trailopt 'I'; skip_next=yes;; \
+      -*I?*) strip_trailopt 'I';; \
+        -*O) strip_trailopt 'O'; skip_next=yes;; \
+      -*O?*) strip_trailopt 'O';; \
+        -*l) strip_trailopt 'l'; skip_next=yes;; \
+      -*l?*) strip_trailopt 'l';; \
+      -[dEDm]) skip_next=yes;; \
+      -[JT]) skip_next=yes;; \
+    esac; \
+    case $$flg in \
+      *$$target_option*) has_opt=yes; break;; \
+    esac; \
+  done; \
+  test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+target_triplet = @target@
+subdir = contrib/bash_completion.d
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/config/always-no-bool-compare.m4 \
+	$(top_srcdir)/config/always-no-unused-but-set-variable.m4 \
+	$(top_srcdir)/config/dkms.m4 \
+	$(top_srcdir)/config/kernel-acl.m4 \
+	$(top_srcdir)/config/kernel-automount.m4 \
+	$(top_srcdir)/config/kernel-bdev-block-device-operations.m4 \
+	$(top_srcdir)/config/kernel-bdev-logical-size.m4 \
+	$(top_srcdir)/config/kernel-bdev-physical-size.m4 \
+	$(top_srcdir)/config/kernel-bdi-setup-and-register.m4 \
+	$(top_srcdir)/config/kernel-bio-bvec-iter.m4 \
+	$(top_srcdir)/config/kernel-bio-end-io-t-args.m4 \
+	$(top_srcdir)/config/kernel-bio-failfast.m4 \
+	$(top_srcdir)/config/kernel-bio-rw-barrier.m4 \
+	$(top_srcdir)/config/kernel-bio-rw-discard.m4 \
+	$(top_srcdir)/config/kernel-blk-queue-flush.m4 \
+	$(top_srcdir)/config/kernel-blk-queue-max-hw-sectors.m4 \
+	$(top_srcdir)/config/kernel-blk-queue-max-segments.m4 \
+	$(top_srcdir)/config/kernel-blkdev-get-by-path.m4 \
+	$(top_srcdir)/config/kernel-blkdev-get.m4 \
+	$(top_srcdir)/config/kernel-block-device-operations-release-void.m4 \
+	$(top_srcdir)/config/kernel-check-disk-size-change.m4 \
+	$(top_srcdir)/config/kernel-clear-inode.m4 \
+	$(top_srcdir)/config/kernel-commit-metadata.m4 \
+	$(top_srcdir)/config/kernel-create-nameidata.m4 \
+	$(top_srcdir)/config/kernel-current_bio_tail.m4 \
+	$(top_srcdir)/config/kernel-d-make-root.m4 \
+	$(top_srcdir)/config/kernel-d-obtain-alias.m4 \
+	$(top_srcdir)/config/kernel-d-prune-aliases.m4 \
+	$(top_srcdir)/config/kernel-declare-event-class.m4 \
+	$(top_srcdir)/config/kernel-dentry-operations.m4 \
+	$(top_srcdir)/config/kernel-dirty-inode.m4 \
+	$(top_srcdir)/config/kernel-discard-granularity.m4 \
+	$(top_srcdir)/config/kernel-elevator-change.m4 \
+	$(top_srcdir)/config/kernel-encode-fh-inode.m4 \
+	$(top_srcdir)/config/kernel-evict-inode.m4 \
+	$(top_srcdir)/config/kernel-fallocate.m4 \
+	$(top_srcdir)/config/kernel-file-inode.m4 \
+	$(top_srcdir)/config/kernel-fmode-t.m4 \
+	$(top_srcdir)/config/kernel-follow-down-one.m4 \
+	$(top_srcdir)/config/kernel-fsync.m4 \
+	$(top_srcdir)/config/kernel-generic_io_acct.m4 \
+	$(top_srcdir)/config/kernel-get-disk-ro.m4 \
+	$(top_srcdir)/config/kernel-get-gendisk.m4 \
+	$(top_srcdir)/config/kernel-get-link.m4 \
+	$(top_srcdir)/config/kernel-insert-inode-locked.m4 \
+	$(top_srcdir)/config/kernel-invalidate-bdev-args.m4 \
+	$(top_srcdir)/config/kernel-is_owner_or_cap.m4 \
+	$(top_srcdir)/config/kernel-kmap-atomic-args.m4 \
+	$(top_srcdir)/config/kernel-kobj-name-len.m4 \
+	$(top_srcdir)/config/kernel-lookup-bdev.m4 \
+	$(top_srcdir)/config/kernel-lookup-nameidata.m4 \
+	$(top_srcdir)/config/kernel-lseek-execute.m4 \
+	$(top_srcdir)/config/kernel-mk-request-fn.m4 \
+	$(top_srcdir)/config/kernel-mkdir-umode-t.m4 \
+	$(top_srcdir)/config/kernel-mount-nodev.m4 \
+	$(top_srcdir)/config/kernel-open-bdev-exclusive.m4 \
+	$(top_srcdir)/config/kernel-put-link.m4 \
+	$(top_srcdir)/config/kernel-security-inode-init.m4 \
+	$(top_srcdir)/config/kernel-set-nlink.m4 \
+	$(top_srcdir)/config/kernel-sget-args.m4 \
+	$(top_srcdir)/config/kernel-show-options.m4 \
+	$(top_srcdir)/config/kernel-shrink.m4 \
+	$(top_srcdir)/config/kernel-truncate-range.m4 \
+	$(top_srcdir)/config/kernel-truncate-setsize.m4 \
+	$(top_srcdir)/config/kernel-vfs-iterate.m4 \
+	$(top_srcdir)/config/kernel-vfs-rw-iterate.m4 \
+	$(top_srcdir)/config/kernel-xattr-handler.m4 \
+	$(top_srcdir)/config/kernel.m4 $(top_srcdir)/config/libtool.m4 \
+	$(top_srcdir)/config/ltoptions.m4 \
+	$(top_srcdir)/config/ltsugar.m4 \
+	$(top_srcdir)/config/ltversion.m4 \
+	$(top_srcdir)/config/lt~obsolete.m4 \
+	$(top_srcdir)/config/mount-helper.m4 \
+	$(top_srcdir)/config/user-arch.m4 \
+	$(top_srcdir)/config/user-dracut.m4 \
+	$(top_srcdir)/config/user-frame-larger-than.m4 \
+	$(top_srcdir)/config/user-libblkid.m4 \
+	$(top_srcdir)/config/user-libuuid.m4 \
+	$(top_srcdir)/config/user-runstatedir.m4 \
+	$(top_srcdir)/config/user-systemd.m4 \
+	$(top_srcdir)/config/user-sysvinit.m4 \
+	$(top_srcdir)/config/user-udev.m4 \
+	$(top_srcdir)/config/user-zlib.m4 $(top_srcdir)/config/user.m4 \
+	$(top_srcdir)/config/zfs-build.m4 \
+	$(top_srcdir)/config/zfs-meta.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/zfs_config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo "  GEN     " $@;
+am__v_GEN_1 = 
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 = 
+SOURCES =
+DIST_SOURCES =
+am__can_run_installinfo = \
+  case $$AM_UPDATE_INFO_DIR in \
+    n|no|NO) false;; \
+    *) (install-info --version) >/dev/null 2>&1;; \
+  esac
+DATA = $(noinst_DATA)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+am__DIST_COMMON = $(srcdir)/Makefile.in
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ALIEN = @ALIEN@
+ALIEN_VERSION = @ALIEN_VERSION@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCAS = @CCAS@
+CCASDEPMODE = @CCASDEPMODE@
+CCASFLAGS = @CCASFLAGS@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEBUG_CFLAGS = @DEBUG_CFLAGS@
+DEBUG_DMU_TX = @DEBUG_DMU_TX@
+DEBUG_STACKFLAGS = @DEBUG_STACKFLAGS@
+DEBUG_ZFS = @DEBUG_ZFS@
+DEFAULT_INITCONF_DIR = @DEFAULT_INITCONF_DIR@
+DEFAULT_INIT_DIR = @DEFAULT_INIT_DIR@
+DEFAULT_INIT_SCRIPT = @DEFAULT_INIT_SCRIPT@
+DEFAULT_PACKAGE = @DEFAULT_PACKAGE@
+DEFINE_INITRAMFS = @DEFINE_INITRAMFS@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DPKG = @DPKG@
+DPKGBUILD = @DPKGBUILD@
+DPKGBUILD_VERSION = @DPKGBUILD_VERSION@
+DPKG_VERSION = @DPKG_VERSION@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+FRAME_LARGER_THAN = @FRAME_LARGER_THAN@
+GREP = @GREP@
+HAVE_ALIEN = @HAVE_ALIEN@
+HAVE_DPKG = @HAVE_DPKG@
+HAVE_DPKGBUILD = @HAVE_DPKGBUILD@
+HAVE_RPM = @HAVE_RPM@
+HAVE_RPMBUILD = @HAVE_RPMBUILD@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+KERNELCPPFLAGS = @KERNELCPPFLAGS@
+KERNELMAKE_PARAMS = @KERNELMAKE_PARAMS@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBBLKID = @LIBBLKID@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIBUUID = @LIBUUID@
+LINUX = @LINUX@
+LINUX_OBJ = @LINUX_OBJ@
+LINUX_SYMBOLS = @LINUX_SYMBOLS@
+LINUX_VERSION = @LINUX_VERSION@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NO_BOOL_COMPARE = @NO_BOOL_COMPARE@
+NO_UNUSED_BUT_SET_VARIABLE = @NO_UNUSED_BUT_SET_VARIABLE@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+RANLIB = @RANLIB@
+RELEASE = @RELEASE@
+RPM = @RPM@
+RPMBUILD = @RPMBUILD@
+RPMBUILD_VERSION = @RPMBUILD_VERSION@
+RPM_DEFINE_COMMON = @RPM_DEFINE_COMMON@
+RPM_DEFINE_DKMS = @RPM_DEFINE_DKMS@
+RPM_DEFINE_KMOD = @RPM_DEFINE_KMOD@
+RPM_DEFINE_UTIL = @RPM_DEFINE_UTIL@
+RPM_SPEC_DIR = @RPM_SPEC_DIR@
+RPM_VERSION = @RPM_VERSION@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SPL = @SPL@
+SPL_OBJ = @SPL_OBJ@
+SPL_SYMBOLS = @SPL_SYMBOLS@
+SPL_VERSION = @SPL_VERSION@
+SRPM_DEFINE_COMMON = @SRPM_DEFINE_COMMON@
+SRPM_DEFINE_DKMS = @SRPM_DEFINE_DKMS@
+SRPM_DEFINE_KMOD = @SRPM_DEFINE_KMOD@
+SRPM_DEFINE_UTIL = @SRPM_DEFINE_UTIL@
+STRIP = @STRIP@
+TARGET_ASM_DIR = @TARGET_ASM_DIR@
+VENDOR = @VENDOR@
+VERSION = @VERSION@
+ZFS_CONFIG = @ZFS_CONFIG@
+ZFS_INIT_SYSTEMD = @ZFS_INIT_SYSTEMD@
+ZFS_INIT_SYSV = @ZFS_INIT_SYSV@
+ZFS_META_ALIAS = @ZFS_META_ALIAS@
+ZFS_META_AUTHOR = @ZFS_META_AUTHOR@
+ZFS_META_DATA = @ZFS_META_DATA@
+ZFS_META_LICENSE = @ZFS_META_LICENSE@
+ZFS_META_LT_AGE = @ZFS_META_LT_AGE@
+ZFS_META_LT_CURRENT = @ZFS_META_LT_CURRENT@
+ZFS_META_LT_REVISION = @ZFS_META_LT_REVISION@
+ZFS_META_NAME = @ZFS_META_NAME@
+ZFS_META_RELEASE = @ZFS_META_RELEASE@
+ZFS_META_VERSION = @ZFS_META_VERSION@
+ZFS_MODULE_LOAD = @ZFS_MODULE_LOAD@
+ZLIB = @ZLIB@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dracutdir = @dracutdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+modulesloaddir = @modulesloaddir@
+mounthelperdir = @mounthelperdir@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+runstatedir = @runstatedir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+systemdpresetdir = @systemdpresetdir@
+systemdunitdir = @systemdunitdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+udevdir = @udevdir@
+udevruledir = @udevruledir@
+bashcompletiondir = $(sysconfdir)/bash_completion.d
+noinst_DATA = zfs
+EXTRA_DIST = $(noinst_DATA)
+all: all-am
+
+.SUFFIXES:
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+	        && { if test -f $@; then exit 0; else break; fi; }; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu contrib/bash_completion.d/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --gnu contrib/bash_completion.d/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+	esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
+tags TAGS:
+
+ctags CTAGS:
+
+cscope cscopelist:
+
+
+distdir: $(DISTFILES)
+	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	list='$(DISTFILES)'; \
+	  dist_files=`for file in $$list; do echo $$file; done | \
+	  sed -e "s|^$$srcdirstrip/||;t" \
+	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+	case $$dist_files in \
+	  */*) $(MKDIR_P) `echo "$$dist_files" | \
+			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+			   sort -u` ;; \
+	esac; \
+	for file in $$dist_files; do \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  if test -d $$d/$$file; then \
+	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+	    if test -d "$(distdir)/$$file"; then \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+	  else \
+	    test -f "$(distdir)/$$file" \
+	    || cp -p $$d/$$file "$(distdir)/$$file" \
+	    || exit 1; \
+	  fi; \
+	done
+check-am: all-am
+check: check-am
+all-am: Makefile $(DATA)
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+	if test -z '$(STRIP)'; then \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	      install; \
+	else \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+	fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-am
+	-rm -f Makefile
+distclean-am: clean-am distclean-generic
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: install-am install-strip
+
+.PHONY: all all-am check check-am clean clean-generic clean-libtool \
+	cscopelist-am ctags-am distclean distclean-generic \
+	distclean-libtool distdir dvi dvi-am html html-am info info-am \
+	install install-am install-data install-data-am install-dvi \
+	install-dvi-am install-exec install-exec-am install-html \
+	install-html-am install-info install-info-am install-man \
+	install-pdf install-pdf-am install-ps install-ps-am \
+	install-strip installcheck installcheck-am installdirs \
+	maintainer-clean maintainer-clean-generic mostlyclean \
+	mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+	tags-am uninstall uninstall-am
+
+.PRECIOUS: Makefile
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/contrib/bash_completion.d/zfs
@@ -0,0 +1,391 @@
+# Copyright (c) 2013, Aneurin Price <aneurin.price@gmail.com>
+
+# Permission is hereby granted, free of charge, to any person
+# obtaining a copy of this software and associated documentation
+# files (the "Software"), to deal in the Software without
+# restriction, including without limitation the rights to use,
+# copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the
+# Software is furnished to do so, subject to the following
+# conditions:
+
+# The above copyright notice and this permission notice shall be
+# included in all copies or substantial portions of the Software.
+
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+# OTHER DEALINGS IN THE SOFTWARE.
+
+if [[ -w /dev/zfs ]]; then
+    __ZFS_CMD="zfs"
+    __ZPOOL_CMD="zpool"
+else
+    __ZFS_CMD="sudo zfs"
+    __ZPOOL_CMD="sudo zpool"
+fi
+
+__zfs_get_commands()
+{
+    $__ZFS_CMD 2>&1 | awk '/^\t[a-z]/ {print $1}' | cut -f1 -d '|' | uniq
+}
+
+__zfs_get_properties()
+{
+    $__ZFS_CMD get 2>&1 | awk '$2 == "YES" || $2 == "NO" {print $1}'; echo all name space
+}
+
+__zfs_get_editable_properties()
+{
+    $__ZFS_CMD get 2>&1 | awk '$2 == "YES" {print $1"="}'
+}
+
+__zfs_get_inheritable_properties()
+{
+    $__ZFS_CMD get 2>&1 | awk '$3 == "YES" {print $1}'
+}
+
+__zfs_list_datasets()
+{
+    $__ZFS_CMD list -H -o name -t filesystem,volume
+}
+
+__zfs_list_filesystems()
+{
+    $__ZFS_CMD list -H -o name -t filesystem
+}
+
+__zfs_match_snapshot()
+{
+    local base_dataset=${cur%@*}
+    if [[ $base_dataset != $cur ]]
+    then
+        $__ZFS_CMD list -H -o name -t snapshot -d 1 $base_dataset
+    else
+        $__ZFS_CMD list -H -o name -t filesystem,volume | awk '{print $1"@"}'
+    fi
+}
+
+__zfs_match_explicit_snapshot()
+{
+    local base_dataset=${cur%@*}
+    if [[ $base_dataset != $cur ]]
+    then
+        $__ZFS_CMD list -H -o name -t snapshot -d 1 $base_dataset
+    fi
+}
+
+__zfs_match_multiple_snapshots()
+{
+    local existing_opts=$(expr "$cur" : '\(.*\)[%,]')
+    if [[ $existing_opts ]]
+    then
+        local base_dataset=${cur%@*}
+        if [[ $base_dataset != $cur ]]
+        then
+            local cur=${cur##*,}
+            if [[ $cur =~ ^%|%.*% ]]
+            then
+                # correct range syntax is start%end
+                return 1
+            fi
+            local range_start=$(expr "$cur" : '\(.*%\)')
+            $__ZFS_CMD list -H -o name -t snapshot -d 1 $base_dataset | sed 's$.*@$'$range_start'$g'
+        fi
+    else
+        __zfs_match_explicit_snapshot; __zfs_list_datasets
+    fi
+}
+
+__zfs_list_volumes()
+{
+    $__ZFS_CMD list -H -o name -t volume
+}
+
+__zfs_argument_chosen()
+{
+    local word property
+    for word in $(seq $((COMP_CWORD-1)) -1 2)
+    do
+        local prev="${COMP_WORDS[$word]}"
+        if [[ ${COMP_WORDS[$word-1]} != -[tos] ]]
+        then
+            if [[ "$prev" == [^,]*,* ]] || [[ "$prev" == *[@:]* ]]
+            then
+                return 0
+            fi
+            for property in $@
+            do
+                if [[ $prev == "$property" ]]
+                then
+                    return 0
+                fi
+            done
+        fi
+    done
+    return 1
+}
+
+__zfs_complete_ordered_arguments()
+{
+    local list1=$1
+    local list2=$2
+    local cur=$3
+    local extra=$4
+    if __zfs_argument_chosen $list1
+    then
+        COMPREPLY=($(compgen -W "$list2 $extra" -- "$cur"))
+    else
+        COMPREPLY=($(compgen -W "$list1 $extra" -- "$cur"))
+    fi
+}
+
+__zfs_complete_multiple_options()
+{
+    local options=$1
+    local cur=$2
+
+    COMPREPLY=($(compgen -W "$options" -- "${cur##*,}"))
+    local existing_opts=$(expr "$cur" : '\(.*,\)')
+    if [[ $existing_opts ]] 
+    then
+        COMPREPLY=( "${COMPREPLY[@]/#/${existing_opts}}" )
+    fi
+}
+
+__zfs_complete_switch()
+{
+    local options=$1
+    if [[ ${cur:0:1} == - ]]
+    then
+        COMPREPLY=($(compgen -W "-{$options}" -- "$cur"))
+        return 0
+    else
+        return 1
+    fi
+}
+
+__zfs_complete()
+{
+    local cur prev cmd cmds
+    COMPREPLY=()
+    # Don't split on colon
+    _get_comp_words_by_ref -n : -c cur -p prev -w COMP_WORDS -i COMP_CWORD
+    cmd="${COMP_WORDS[1]}"
+
+    if [[ ${prev##*/} == zfs ]]
+    then
+        cmds=$(__zfs_get_commands)
+        COMPREPLY=($(compgen -W "$cmds -?" -- "$cur"))
+        return 0
+    fi
+
+    case "${cmd}" in
+        clone)
+            case "${prev}" in
+                -o)
+                    COMPREPLY=($(compgen -W "$(__zfs_get_editable_properties)" -- "$cur"))
+                    ;;
+                *)
+                    if ! __zfs_complete_switch "o,p"
+                    then
+                        if __zfs_argument_chosen
+                        then
+                            COMPREPLY=($(compgen -W "$(__zfs_list_datasets)" -- "$cur"))
+                        else
+                            COMPREPLY=($(compgen -W "$(__zfs_match_snapshot)" -- "$cur"))
+                        fi
+                    fi
+                    ;;
+            esac
+            ;;
+        get)
+            case "${prev}" in
+                -d)
+                    COMPREPLY=($(compgen -W "" -- "$cur"))
+                    ;;
+                -t)
+                    __zfs_complete_multiple_options "filesystem volume snapshot all" "$cur"
+                    ;;
+                -s)
+                    __zfs_complete_multiple_options "local default inherited temporary none" "$cur"
+                    ;;
+                -o)
+                    __zfs_complete_multiple_options "name property value source received all" "$cur"
+                    ;;
+                *)
+                    if ! __zfs_complete_switch "H,r,p,d,o,t,s"
+                    then
+                        if __zfs_argument_chosen $(__zfs_get_properties)
+                        then
+                            COMPREPLY=($(compgen -W "$(__zfs_match_explicit_snapshot) $(__zfs_list_datasets)" -- "$cur"))
+                        else
+                            __zfs_complete_multiple_options "$(__zfs_get_properties)" "$cur"
+                        fi
+                    fi
+                    ;;
+            esac
+            ;;
+        inherit)
+            if ! __zfs_complete_switch "r"
+            then
+                __zfs_complete_ordered_arguments "$(__zfs_get_inheritable_properties)" "$(__zfs_match_explicit_snapshot) $(__zfs_list_datasets)" $cur
+            fi
+            ;;
+        list)
+            case "${prev}" in
+                -d)
+                    COMPREPLY=($(compgen -W "" -- "$cur"))
+                    ;;
+                -t)
+                    __zfs_complete_multiple_options "filesystem volume snapshot all" "$cur"
+                    ;;
+                -o)
+                    __zfs_complete_multiple_options "$(__zfs_get_properties)" "$cur"
+                    ;;
+                -s|-S)
+                    COMPREPLY=($(compgen -W "$(__zfs_get_properties)" -- "$cur"))
+                    ;;
+                *)
+                    if ! __zfs_complete_switch "H,r,d,o,t,s,S"
+                    then
+                        COMPREPLY=($(compgen -W "$(__zfs_match_explicit_snapshot) $(__zfs_list_datasets)" -- "$cur"))
+                    fi
+                    ;;
+            esac
+            ;;
+        promote)
+            COMPREPLY=($(compgen -W "$(__zfs_list_filesystems)" -- "$cur"))
+            ;;
+        rollback)
+            if ! __zfs_complete_switch "r,R,f"
+            then
+                COMPREPLY=($(compgen -W "$(__zfs_match_snapshot)" -- "$cur"))
+            fi
+            ;;
+        send)
+            if ! __zfs_complete_switch "d,n,P,p,R,v,i,I"
+            then
+                COMPREPLY=($(compgen -W "$(__zfs_match_snapshot)" -- "$cur"))
+            fi
+            ;;
+        snapshot)
+            case "${prev}" in
+                -o)
+                    COMPREPLY=($(compgen -W "$(__zfs_get_editable_properties)" -- "$cur"))
+                    ;;
+                *)
+                    if ! __zfs_complete_switch "o,r"
+                    then
+                        COMPREPLY=($(compgen -W "$(__zfs_list_datasets | awk '{print $1"@"}')" -- "$cur"))
+                    fi
+                    ;;
+            esac
+            ;;
+        set)
+            __zfs_complete_ordered_arguments "$(__zfs_get_editable_properties)" "$(__zfs_match_explicit_snapshot) $(__zfs_list_datasets)" $cur
+            ;;
+        upgrade)
+            case "${prev}" in
+                -a|-V|-v)
+                    COMPREPLY=($(compgen -W "" -- "$cur"))
+                    ;;
+                *)
+                    if ! __zfs_complete_switch "a,V,v,r"
+                    then
+                        COMPREPLY=($(compgen -W "$(__zfs_list_filesystems)" -- "$cur"))
+                    fi
+                    ;;
+            esac
+            ;;
+        destroy)
+            if ! __zfs_complete_switch "d,f,n,p,R,r,v"
+            then
+                __zfs_complete_multiple_options "$(__zfs_match_multiple_snapshots)" $cur
+            fi
+            ;;
+        *)
+            COMPREPLY=($(compgen -W "$(__zfs_match_explicit_snapshot) $(__zfs_list_datasets)" -- "$cur"))
+            ;;
+    esac
+    __ltrim_colon_completions "$cur"
+    return 0
+}
+
+__zpool_get_commands()
+{
+    $__ZPOOL_CMD 2>&1 | awk '/^\t[a-z]/ {print $1}' | uniq
+}
+
+__zpool_get_properties()
+{
+    $__ZPOOL_CMD get 2>&1 | awk '$2 == "YES" || $2 == "NO" {print $1}'; echo all
+}
+
+__zpool_get_editable_properties()
+{
+    $__ZPOOL_CMD get 2>&1 | awk '$2 == "YES" {print $1"="}'
+}
+
+__zpool_list_pools()
+{
+    $__ZPOOL_CMD list -H -o name
+}
+
+__zpool_complete()
+{
+    local cur prev cmd cmds
+    COMPREPLY=()
+    cur="${COMP_WORDS[COMP_CWORD]}"
+    prev="${COMP_WORDS[COMP_CWORD-1]}"
+    cmd="${COMP_WORDS[1]}"
+
+    if [[ ${prev##*/} == zpool ]]
+    then
+        cmds=$(__zpool_get_commands)
+        COMPREPLY=($(compgen -W "$cmds" -- "$cur"))
+        return 0
+    fi
+
+    case "${cmd}" in
+        get)
+            __zfs_complete_ordered_arguments "$(__zpool_get_properties)" "$(__zpool_list_pools)" $cur
+            return 0
+            ;;
+        import)
+            if [[ $prev == -d ]]
+            then
+                _filedir -d
+            else
+                COMPREPLY=($(compgen -W "$(__zpool_list_pools) -d" -- "$cur"))
+            fi
+            return 0
+            ;;
+        set)
+            __zfs_complete_ordered_arguments "$(__zpool_get_editable_properties)" "$(__zpool_list_pools)" $cur
+            return 0
+            ;;
+        add|attach|clear|create|detach|offline|online|remove|replace)
+            local pools="$(__zpool_list_pools)"
+            if __zfs_argument_chosen $pools
+            then
+                _filedir
+            else
+                COMPREPLY=($(compgen -W "$pools" -- "$cur"))
+            fi
+            return 0
+            ;;
+        *)
+            COMPREPLY=($(compgen -W "$(__zpool_list_pools)" -- "$cur"))
+            return 0
+            ;;
+    esac
+
+}
+
+complete -F __zfs_complete zfs
+complete -F __zpool_complete zpool
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/contrib/dracut/90zfs/Makefile.am
@@ -0,0 +1,25 @@
+pkgdracutdir = $(dracutdir)/modules.d/90zfs
+pkgdracut_SCRIPTS = \
+	export-zfs.sh \
+	module-setup.sh \
+	mount-zfs.sh \
+	parse-zfs.sh \
+	zfs-lib.sh
+
+EXTRA_DIST = \
+	$(top_srcdir)/contrib/dracut/90zfs/export-zfs.sh.in \
+	$(top_srcdir)/contrib/dracut/90zfs/module-setup.sh.in \
+	$(top_srcdir)/contrib/dracut/90zfs/mount-zfs.sh.in \
+	$(top_srcdir)/contrib/dracut/90zfs/parse-zfs.sh.in \
+	$(top_srcdir)/contrib/dracut/90zfs/zfs-lib.sh.in
+
+$(pkgdracut_SCRIPTS):
+	-$(SED) -e 's,@bindir\@,$(bindir),g' \
+		-e 's,@sbindir\@,$(sbindir),g' \
+		-e 's,@udevdir\@,$(udevdir),g' \
+		-e 's,@udevruledir\@,$(udevruledir),g' \
+		-e 's,@sysconfdir\@,$(sysconfdir),g' \
+		"$(top_srcdir)/contrib/dracut/90zfs/$@.in" >'$@'
+
+distclean-local::
+	-$(RM) $(pkgdracut_SCRIPTS)
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/contrib/dracut/90zfs/Makefile.in
@@ -0,0 +1,693 @@
+# Makefile.in generated by automake 1.15 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2014 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+VPATH = @srcdir@
+am__is_gnu_make = { \
+  if test -z '$(MAKELEVEL)'; then \
+    false; \
+  elif test -n '$(MAKE_HOST)'; then \
+    true; \
+  elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+    true; \
+  else \
+    false; \
+  fi; \
+}
+am__make_running_with_option = \
+  case $${target_option-} in \
+      ?) ;; \
+      *) echo "am__make_running_with_option: internal error: invalid" \
+              "target option '$${target_option-}' specified" >&2; \
+         exit 1;; \
+  esac; \
+  has_opt=no; \
+  sane_makeflags=$$MAKEFLAGS; \
+  if $(am__is_gnu_make); then \
+    sane_makeflags=$$MFLAGS; \
+  else \
+    case $$MAKEFLAGS in \
+      *\\[\ \	]*) \
+        bs=\\; \
+        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
+    esac; \
+  fi; \
+  skip_next=no; \
+  strip_trailopt () \
+  { \
+    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+  }; \
+  for flg in $$sane_makeflags; do \
+    test $$skip_next = yes && { skip_next=no; continue; }; \
+    case $$flg in \
+      *=*|--*) continue;; \
+        -*I) strip_trailopt 'I'; skip_next=yes;; \
+      -*I?*) strip_trailopt 'I';; \
+        -*O) strip_trailopt 'O'; skip_next=yes;; \
+      -*O?*) strip_trailopt 'O';; \
+        -*l) strip_trailopt 'l'; skip_next=yes;; \
+      -*l?*) strip_trailopt 'l';; \
+      -[dEDm]) skip_next=yes;; \
+      -[JT]) skip_next=yes;; \
+    esac; \
+    case $$flg in \
+      *$$target_option*) has_opt=yes; break;; \
+    esac; \
+  done; \
+  test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+target_triplet = @target@
+subdir = contrib/dracut/90zfs
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/config/always-no-bool-compare.m4 \
+	$(top_srcdir)/config/always-no-unused-but-set-variable.m4 \
+	$(top_srcdir)/config/dkms.m4 \
+	$(top_srcdir)/config/kernel-acl.m4 \
+	$(top_srcdir)/config/kernel-automount.m4 \
+	$(top_srcdir)/config/kernel-bdev-block-device-operations.m4 \
+	$(top_srcdir)/config/kernel-bdev-logical-size.m4 \
+	$(top_srcdir)/config/kernel-bdev-physical-size.m4 \
+	$(top_srcdir)/config/kernel-bdi-setup-and-register.m4 \
+	$(top_srcdir)/config/kernel-bio-bvec-iter.m4 \
+	$(top_srcdir)/config/kernel-bio-end-io-t-args.m4 \
+	$(top_srcdir)/config/kernel-bio-failfast.m4 \
+	$(top_srcdir)/config/kernel-bio-rw-barrier.m4 \
+	$(top_srcdir)/config/kernel-bio-rw-discard.m4 \
+	$(top_srcdir)/config/kernel-blk-queue-flush.m4 \
+	$(top_srcdir)/config/kernel-blk-queue-max-hw-sectors.m4 \
+	$(top_srcdir)/config/kernel-blk-queue-max-segments.m4 \
+	$(top_srcdir)/config/kernel-blkdev-get-by-path.m4 \
+	$(top_srcdir)/config/kernel-blkdev-get.m4 \
+	$(top_srcdir)/config/kernel-block-device-operations-release-void.m4 \
+	$(top_srcdir)/config/kernel-check-disk-size-change.m4 \
+	$(top_srcdir)/config/kernel-clear-inode.m4 \
+	$(top_srcdir)/config/kernel-commit-metadata.m4 \
+	$(top_srcdir)/config/kernel-create-nameidata.m4 \
+	$(top_srcdir)/config/kernel-current_bio_tail.m4 \
+	$(top_srcdir)/config/kernel-d-make-root.m4 \
+	$(top_srcdir)/config/kernel-d-obtain-alias.m4 \
+	$(top_srcdir)/config/kernel-d-prune-aliases.m4 \
+	$(top_srcdir)/config/kernel-declare-event-class.m4 \
+	$(top_srcdir)/config/kernel-dentry-operations.m4 \
+	$(top_srcdir)/config/kernel-dirty-inode.m4 \
+	$(top_srcdir)/config/kernel-discard-granularity.m4 \
+	$(top_srcdir)/config/kernel-elevator-change.m4 \
+	$(top_srcdir)/config/kernel-encode-fh-inode.m4 \
+	$(top_srcdir)/config/kernel-evict-inode.m4 \
+	$(top_srcdir)/config/kernel-fallocate.m4 \
+	$(top_srcdir)/config/kernel-file-inode.m4 \
+	$(top_srcdir)/config/kernel-fmode-t.m4 \
+	$(top_srcdir)/config/kernel-follow-down-one.m4 \
+	$(top_srcdir)/config/kernel-fsync.m4 \
+	$(top_srcdir)/config/kernel-generic_io_acct.m4 \
+	$(top_srcdir)/config/kernel-get-disk-ro.m4 \
+	$(top_srcdir)/config/kernel-get-gendisk.m4 \
+	$(top_srcdir)/config/kernel-get-link.m4 \
+	$(top_srcdir)/config/kernel-insert-inode-locked.m4 \
+	$(top_srcdir)/config/kernel-invalidate-bdev-args.m4 \
+	$(top_srcdir)/config/kernel-is_owner_or_cap.m4 \
+	$(top_srcdir)/config/kernel-kmap-atomic-args.m4 \
+	$(top_srcdir)/config/kernel-kobj-name-len.m4 \
+	$(top_srcdir)/config/kernel-lookup-bdev.m4 \
+	$(top_srcdir)/config/kernel-lookup-nameidata.m4 \
+	$(top_srcdir)/config/kernel-lseek-execute.m4 \
+	$(top_srcdir)/config/kernel-mk-request-fn.m4 \
+	$(top_srcdir)/config/kernel-mkdir-umode-t.m4 \
+	$(top_srcdir)/config/kernel-mount-nodev.m4 \
+	$(top_srcdir)/config/kernel-open-bdev-exclusive.m4 \
+	$(top_srcdir)/config/kernel-put-link.m4 \
+	$(top_srcdir)/config/kernel-security-inode-init.m4 \
+	$(top_srcdir)/config/kernel-set-nlink.m4 \
+	$(top_srcdir)/config/kernel-sget-args.m4 \
+	$(top_srcdir)/config/kernel-show-options.m4 \
+	$(top_srcdir)/config/kernel-shrink.m4 \
+	$(top_srcdir)/config/kernel-truncate-range.m4 \
+	$(top_srcdir)/config/kernel-truncate-setsize.m4 \
+	$(top_srcdir)/config/kernel-vfs-iterate.m4 \
+	$(top_srcdir)/config/kernel-vfs-rw-iterate.m4 \
+	$(top_srcdir)/config/kernel-xattr-handler.m4 \
+	$(top_srcdir)/config/kernel.m4 $(top_srcdir)/config/libtool.m4 \
+	$(top_srcdir)/config/ltoptions.m4 \
+	$(top_srcdir)/config/ltsugar.m4 \
+	$(top_srcdir)/config/ltversion.m4 \
+	$(top_srcdir)/config/lt~obsolete.m4 \
+	$(top_srcdir)/config/mount-helper.m4 \
+	$(top_srcdir)/config/user-arch.m4 \
+	$(top_srcdir)/config/user-dracut.m4 \
+	$(top_srcdir)/config/user-frame-larger-than.m4 \
+	$(top_srcdir)/config/user-libblkid.m4 \
+	$(top_srcdir)/config/user-libuuid.m4 \
+	$(top_srcdir)/config/user-runstatedir.m4 \
+	$(top_srcdir)/config/user-systemd.m4 \
+	$(top_srcdir)/config/user-sysvinit.m4 \
+	$(top_srcdir)/config/user-udev.m4 \
+	$(top_srcdir)/config/user-zlib.m4 $(top_srcdir)/config/user.m4 \
+	$(top_srcdir)/config/zfs-build.m4 \
+	$(top_srcdir)/config/zfs-meta.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/zfs_config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+    $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+    *) f=$$p;; \
+  esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+  srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+  for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+  for p in $$list; do echo "$$p $$p"; done | \
+  sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+  $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+    if (++n[$$2] == $(am__install_max)) \
+      { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+    END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+  sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+  sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+  test -z "$$files" \
+    || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+    || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+         $(am__cd) "$$dir" && rm -f $$files; }; \
+  }
+am__installdirs = "$(DESTDIR)$(pkgdracutdir)"
+SCRIPTS = $(pkgdracut_SCRIPTS)
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo "  GEN     " $@;
+am__v_GEN_1 = 
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 = 
+SOURCES =
+DIST_SOURCES =
+am__can_run_installinfo = \
+  case $$AM_UPDATE_INFO_DIR in \
+    n|no|NO) false;; \
+    *) (install-info --version) >/dev/null 2>&1;; \
+  esac
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+am__DIST_COMMON = $(srcdir)/Makefile.in
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ALIEN = @ALIEN@
+ALIEN_VERSION = @ALIEN_VERSION@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCAS = @CCAS@
+CCASDEPMODE = @CCASDEPMODE@
+CCASFLAGS = @CCASFLAGS@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEBUG_CFLAGS = @DEBUG_CFLAGS@
+DEBUG_DMU_TX = @DEBUG_DMU_TX@
+DEBUG_STACKFLAGS = @DEBUG_STACKFLAGS@
+DEBUG_ZFS = @DEBUG_ZFS@
+DEFAULT_INITCONF_DIR = @DEFAULT_INITCONF_DIR@
+DEFAULT_INIT_DIR = @DEFAULT_INIT_DIR@
+DEFAULT_INIT_SCRIPT = @DEFAULT_INIT_SCRIPT@
+DEFAULT_PACKAGE = @DEFAULT_PACKAGE@
+DEFINE_INITRAMFS = @DEFINE_INITRAMFS@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DPKG = @DPKG@
+DPKGBUILD = @DPKGBUILD@
+DPKGBUILD_VERSION = @DPKGBUILD_VERSION@
+DPKG_VERSION = @DPKG_VERSION@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+FRAME_LARGER_THAN = @FRAME_LARGER_THAN@
+GREP = @GREP@
+HAVE_ALIEN = @HAVE_ALIEN@
+HAVE_DPKG = @HAVE_DPKG@
+HAVE_DPKGBUILD = @HAVE_DPKGBUILD@
+HAVE_RPM = @HAVE_RPM@
+HAVE_RPMBUILD = @HAVE_RPMBUILD@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+KERNELCPPFLAGS = @KERNELCPPFLAGS@
+KERNELMAKE_PARAMS = @KERNELMAKE_PARAMS@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBBLKID = @LIBBLKID@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIBUUID = @LIBUUID@
+LINUX = @LINUX@
+LINUX_OBJ = @LINUX_OBJ@
+LINUX_SYMBOLS = @LINUX_SYMBOLS@
+LINUX_VERSION = @LINUX_VERSION@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NO_BOOL_COMPARE = @NO_BOOL_COMPARE@
+NO_UNUSED_BUT_SET_VARIABLE = @NO_UNUSED_BUT_SET_VARIABLE@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+RANLIB = @RANLIB@
+RELEASE = @RELEASE@
+RPM = @RPM@
+RPMBUILD = @RPMBUILD@
+RPMBUILD_VERSION = @RPMBUILD_VERSION@
+RPM_DEFINE_COMMON = @RPM_DEFINE_COMMON@
+RPM_DEFINE_DKMS = @RPM_DEFINE_DKMS@
+RPM_DEFINE_KMOD = @RPM_DEFINE_KMOD@
+RPM_DEFINE_UTIL = @RPM_DEFINE_UTIL@
+RPM_SPEC_DIR = @RPM_SPEC_DIR@
+RPM_VERSION = @RPM_VERSION@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SPL = @SPL@
+SPL_OBJ = @SPL_OBJ@
+SPL_SYMBOLS = @SPL_SYMBOLS@
+SPL_VERSION = @SPL_VERSION@
+SRPM_DEFINE_COMMON = @SRPM_DEFINE_COMMON@
+SRPM_DEFINE_DKMS = @SRPM_DEFINE_DKMS@
+SRPM_DEFINE_KMOD = @SRPM_DEFINE_KMOD@
+SRPM_DEFINE_UTIL = @SRPM_DEFINE_UTIL@
+STRIP = @STRIP@
+TARGET_ASM_DIR = @TARGET_ASM_DIR@
+VENDOR = @VENDOR@
+VERSION = @VERSION@
+ZFS_CONFIG = @ZFS_CONFIG@
+ZFS_INIT_SYSTEMD = @ZFS_INIT_SYSTEMD@
+ZFS_INIT_SYSV = @ZFS_INIT_SYSV@
+ZFS_META_ALIAS = @ZFS_META_ALIAS@
+ZFS_META_AUTHOR = @ZFS_META_AUTHOR@
+ZFS_META_DATA = @ZFS_META_DATA@
+ZFS_META_LICENSE = @ZFS_META_LICENSE@
+ZFS_META_LT_AGE = @ZFS_META_LT_AGE@
+ZFS_META_LT_CURRENT = @ZFS_META_LT_CURRENT@
+ZFS_META_LT_REVISION = @ZFS_META_LT_REVISION@
+ZFS_META_NAME = @ZFS_META_NAME@
+ZFS_META_RELEASE = @ZFS_META_RELEASE@
+ZFS_META_VERSION = @ZFS_META_VERSION@
+ZFS_MODULE_LOAD = @ZFS_MODULE_LOAD@
+ZLIB = @ZLIB@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dracutdir = @dracutdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+modulesloaddir = @modulesloaddir@
+mounthelperdir = @mounthelperdir@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+runstatedir = @runstatedir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+systemdpresetdir = @systemdpresetdir@
+systemdunitdir = @systemdunitdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+udevdir = @udevdir@
+udevruledir = @udevruledir@
+pkgdracutdir = $(dracutdir)/modules.d/90zfs
+pkgdracut_SCRIPTS = \
+	export-zfs.sh \
+	module-setup.sh \
+	mount-zfs.sh \
+	parse-zfs.sh \
+	zfs-lib.sh
+
+EXTRA_DIST = \
+	$(top_srcdir)/contrib/dracut/90zfs/export-zfs.sh.in \
+	$(top_srcdir)/contrib/dracut/90zfs/module-setup.sh.in \
+	$(top_srcdir)/contrib/dracut/90zfs/mount-zfs.sh.in \
+	$(top_srcdir)/contrib/dracut/90zfs/parse-zfs.sh.in \
+	$(top_srcdir)/contrib/dracut/90zfs/zfs-lib.sh.in
+
+all: all-am
+
+.SUFFIXES:
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+	        && { if test -f $@; then exit 0; else break; fi; }; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu contrib/dracut/90zfs/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --gnu contrib/dracut/90zfs/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+	esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+install-pkgdracutSCRIPTS: $(pkgdracut_SCRIPTS)
+	@$(NORMAL_INSTALL)
+	@list='$(pkgdracut_SCRIPTS)'; test -n "$(pkgdracutdir)" || list=; \
+	if test -n "$$list"; then \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(pkgdracutdir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(pkgdracutdir)" || exit 1; \
+	fi; \
+	for p in $$list; do \
+	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+	  if test -f "$$d$$p"; then echo "$$d$$p"; echo "$$p"; else :; fi; \
+	done | \
+	sed -e 'p;s,.*/,,;n' \
+	    -e 'h;s|.*|.|' \
+	    -e 'p;x;s,.*/,,;$(transform)' | sed 'N;N;N;s,\n, ,g' | \
+	$(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1; } \
+	  { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
+	    if ($$2 == $$4) { files[d] = files[d] " " $$1; \
+	      if (++n[d] == $(am__install_max)) { \
+		print "f", d, files[d]; n[d] = 0; files[d] = "" } } \
+	    else { print "f", d "/" $$4, $$1 } } \
+	  END { for (d in files) print "f", d, files[d] }' | \
+	while read type dir files; do \
+	     if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
+	     test -z "$$files" || { \
+	       echo " $(INSTALL_SCRIPT) $$files '$(DESTDIR)$(pkgdracutdir)$$dir'"; \
+	       $(INSTALL_SCRIPT) $$files "$(DESTDIR)$(pkgdracutdir)$$dir" || exit $$?; \
+	     } \
+	; done
+
+uninstall-pkgdracutSCRIPTS:
+	@$(NORMAL_UNINSTALL)
+	@list='$(pkgdracut_SCRIPTS)'; test -n "$(pkgdracutdir)" || exit 0; \
+	files=`for p in $$list; do echo "$$p"; done | \
+	       sed -e 's,.*/,,;$(transform)'`; \
+	dir='$(DESTDIR)$(pkgdracutdir)'; $(am__uninstall_files_from_dir)
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
+tags TAGS:
+
+ctags CTAGS:
+
+cscope cscopelist:
+
+
+distdir: $(DISTFILES)
+	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	list='$(DISTFILES)'; \
+	  dist_files=`for file in $$list; do echo $$file; done | \
+	  sed -e "s|^$$srcdirstrip/||;t" \
+	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+	case $$dist_files in \
+	  */*) $(MKDIR_P) `echo "$$dist_files" | \
+			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+			   sort -u` ;; \
+	esac; \
+	for file in $$dist_files; do \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  if test -d $$d/$$file; then \
+	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+	    if test -d "$(distdir)/$$file"; then \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+	  else \
+	    test -f "$(distdir)/$$file" \
+	    || cp -p $$d/$$file "$(distdir)/$$file" \
+	    || exit 1; \
+	  fi; \
+	done
+check-am: all-am
+check: check-am
+all-am: Makefile $(SCRIPTS)
+installdirs:
+	for dir in "$(DESTDIR)$(pkgdracutdir)"; do \
+	  test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+	done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+	if test -z '$(STRIP)'; then \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	      install; \
+	else \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+	fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-am
+	-rm -f Makefile
+distclean-am: clean-am distclean-generic distclean-local
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-pkgdracutSCRIPTS
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-pkgdracutSCRIPTS
+
+.MAKE: install-am install-strip
+
+.PHONY: all all-am check check-am clean clean-generic clean-libtool \
+	cscopelist-am ctags-am distclean distclean-generic \
+	distclean-libtool distclean-local distdir dvi dvi-am html \
+	html-am info info-am install install-am install-data \
+	install-data-am install-dvi install-dvi-am install-exec \
+	install-exec-am install-html install-html-am install-info \
+	install-info-am install-man install-pdf install-pdf-am \
+	install-pkgdracutSCRIPTS install-ps install-ps-am \
+	install-strip installcheck installcheck-am installdirs \
+	maintainer-clean maintainer-clean-generic mostlyclean \
+	mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+	tags-am uninstall uninstall-am uninstall-pkgdracutSCRIPTS
+
+.PRECIOUS: Makefile
+
+
+$(pkgdracut_SCRIPTS):
+	-$(SED) -e 's,@bindir\@,$(bindir),g' \
+		-e 's,@sbindir\@,$(sbindir),g' \
+		-e 's,@udevdir\@,$(udevdir),g' \
+		-e 's,@udevruledir\@,$(udevruledir),g' \
+		-e 's,@sysconfdir\@,$(sysconfdir),g' \
+		"$(top_srcdir)/contrib/dracut/90zfs/$@.in" >'$@'
+
+distclean-local::
+	-$(RM) $(pkgdracut_SCRIPTS)
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/contrib/dracut/90zfs/export-zfs.sh.in
@@ -0,0 +1,29 @@
+#!/bin/sh
+
+. /lib/dracut-zfs-lib.sh
+
+_do_zpool_export() {
+	local ret=0
+	local final="${1}"
+	local opts=""
+
+	if [ "x${final}" != "x" ]; then
+		opts="-f"
+	fi
+
+	info "Exporting ZFS storage pools."
+	export_all ${opts} || ret=$?
+
+	if [ "x${final}" != "x" ]; then
+		info "zpool list"
+		zpool list 2>&1 | vinfo
+	fi
+
+	return ${ret}
+}
+
+if command -v zpool >/dev/null; then
+	_do_zpool_export "${1}"
+else
+	:
+fi
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/contrib/dracut/90zfs/module-setup.sh.in
@@ -0,0 +1,61 @@
+#!/bin/sh
+
+check() {
+	# We depend on udev-rules being loaded
+	[ "${1}" = "-d" ] && return 0
+
+	# Verify the zfs tool chain
+	which zpool >/dev/null 2>&1 || return 1
+	which zfs >/dev/null 2>&1 || return 1
+
+	return 0
+}
+
+depends() {
+	echo udev-rules
+	return 0
+}
+
+installkernel() {
+	instmods zfs
+	instmods zcommon
+	instmods znvpair
+	instmods zavl
+	instmods zunicode
+	instmods spl
+	instmods zlib_deflate
+	instmods zlib_inflate
+}
+
+install() {
+	inst_rules @udevruledir@/90-zfs.rules
+	inst_rules @udevruledir@/69-vdev.rules
+	inst_rules @udevruledir@/60-zvol.rules
+	dracut_install @sbindir@/zfs
+	dracut_install @sbindir@/zpool
+	dracut_install @udevdir@/vdev_id
+	dracut_install @udevdir@/zvol_id
+	dracut_install mount.zfs
+	dracut_install hostid
+	dracut_install awk
+	dracut_install head
+	inst_hook cmdline 95 "${moddir}/parse-zfs.sh"
+	inst_hook mount 98 "${moddir}/mount-zfs.sh"
+	inst_hook shutdown 30 "${moddir}/export-zfs.sh"
+
+	inst_simple "${moddir}/zfs-lib.sh" "/lib/dracut-zfs-lib.sh"
+	if [ -e @sysconfdir@/zfs/zpool.cache ]; then
+		inst @sysconfdir@/zfs/zpool.cache
+	fi
+
+	if [ -e @sysconfdir@/zfs/vdev_id.conf ]; then
+		inst @sysconfdir@/zfs/vdev_id.conf
+	fi
+
+	# Synchronize initramfs and system hostid
+	AA=`hostid | cut -b 1,2`
+	BB=`hostid | cut -b 3,4`
+	CC=`hostid | cut -b 5,6`
+	DD=`hostid | cut -b 7,8`
+	printf "\x${DD}\x${CC}\x${BB}\x${AA}" > "${initdir}/etc/hostid"
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/contrib/dracut/90zfs/mount-zfs.sh.in
@@ -0,0 +1,44 @@
+#!/bin/sh
+
+. /lib/dracut-zfs-lib.sh
+
+ZFS_DATASET=""
+ZFS_POOL=""
+
+case "${root}" in
+	zfs:*) ;;
+	*) return ;;
+esac
+
+# Delay until all required block devices are present.
+udevadm settle
+
+if [ "${root}" = "zfs:AUTO" ] ; then
+	ZFS_DATASET="$(find_bootfs)"
+	if [ $? -ne 0 ] ; then
+		zpool import -N -a ${ZPOOL_IMPORT_OPTS}
+		ZFS_DATASET="$(find_bootfs)"
+		if [ $? -ne 0 ] ; then
+			warn "ZFS: No bootfs attribute found in importable pools."
+			export_all || export_all "-f"
+
+			rootok=0
+			return 1
+		fi
+	fi
+	info "ZFS: Using ${ZFS_DATASET} as root."
+fi
+
+ZFS_DATASET="${ZFS_DATASET:-${root#zfs:}}"
+ZFS_POOL="${ZFS_DATASET%%/*}"
+
+if import_pool "${ZFS_POOL}" ; then
+	info "ZFS: Mounting dataset ${ZFS_DATASET}..."
+	if mount_dataset "${ZFS_DATASET}" ; then
+		ROOTFS_MOUNTED=yes
+		return 0
+	fi
+fi
+
+rootok=0
+need_shutdown
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/contrib/dracut/90zfs/parse-zfs.sh.in
@@ -0,0 +1,59 @@
+#!/bin/sh
+
+. /lib/dracut-lib.sh
+
+# Let the command line override our host id.
+spl_hostid=`getarg spl_hostid=`
+if [ -n "${spl_hostid}" ] ; then
+	info "ZFS: Using hostid from command line: ${spl_hostid}"
+	AA=`echo ${spl_hostid} | cut -b 1,2`
+	BB=`echo ${spl_hostid} | cut -b 3,4`
+	CC=`echo ${spl_hostid} | cut -b 5,6`
+	DD=`echo ${spl_hostid} | cut -b 7,8`
+	printf "\x${DD}\x${CC}\x${BB}\x${AA}" >/etc/hostid
+elif [ -f "/etc/hostid" ] ; then
+	info "ZFS: Using hostid from /etc/hostid: `hostid`"
+else
+	warn "ZFS: No hostid found on kernel command line or /etc/hostid."
+	warn "ZFS: Pools may not import correctly."
+fi
+
+wait_for_zfs=0
+case "${root}" in
+	""|zfs|zfs:)
+		# We'll take root unset, root=zfs, or root=zfs:
+		# No root set, so we want to read the bootfs attribute.  We
+		# can't do that until udev settles so we'll set dummy values
+		# and hope for the best later on.
+		root="zfs:AUTO"
+		rootok=1
+		wait_for_zfs=1
+
+		info "ZFS: Enabling autodetection of bootfs after udev settles."
+		;;
+
+	ZFS\=*|zfs:*|zfs:FILESYSTEM\=*|FILESYSTEM\=*)
+		# root is explicit ZFS root.  Parse it now.  We can handle
+		# a root=... param in any of the following formats:
+		# root=ZFS=rpool/ROOT
+		# root=zfs:rpool/ROOT
+		# root=zfs:FILESYSTEM=rpool/ROOT
+		# root=FILESYSTEM=rpool/ROOT
+
+		# Strip down to just the pool/fs
+		root="${root#zfs:}"
+		root="${root#FILESYSTEM=}"
+		root="zfs:${root#ZFS=}"
+		rootok=1
+		wait_for_zfs=1
+
+		info "ZFS: Set ${root} as bootfs."
+		;;
+esac
+
+# Make sure Dracut is happy that we have a root and will wait for ZFS
+# modules to settle before mounting.
+if [ ${wait_for_zfs} -eq 1 ]; then
+	ln -s /dev/null /dev/root 2>/dev/null
+	echo '[ -e /dev/zfs ]' > "${hookdir}/initqueue/finished/zfs.sh"
+fi
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/contrib/dracut/90zfs/zfs-lib.sh.in
@@ -0,0 +1,87 @@
+#!/bin/sh
+
+command -v getarg >/dev/null || . /lib/dracut-lib.sh
+
+OLDIFS="${IFS}"
+NEWLINE="
+"
+
+ZPOOL_IMPORT_OPTS=""
+if getargbool 0 zfs_force -y zfs.force -y zfsforce ; then
+	warn "ZFS: Will force-import pools if necessary."
+	ZPOOL_IMPORT_OPTS="${ZPOOL_IMPORT_OPTS} -f"
+fi
+
+# find_bootfs
+#   returns the first dataset with the bootfs attribute.
+find_bootfs() {
+	IFS="${NEWLINE}"
+	for dataset in $(zpool list -H -o bootfs); do
+		case "${dataset}" in
+			"" | "-")
+				continue
+				;;
+			"no pools available")
+				IFS="${OLDIFS}"
+				return 1
+				;;
+			*)
+				IFS="${OLDIFS}"
+				echo "${dataset}"
+				return 0
+				;;
+		esac
+	done
+
+	IFS="${OLDIFS}"
+	return 1
+}
+
+# import_pool POOL
+#   imports the given zfs pool if it isn't imported already.
+import_pool() {
+	local pool="${1}"
+
+	if ! zpool list -H "${pool}" 2>&1 > /dev/null ; then
+		info "ZFS: Importing pool ${pool}..."
+		if ! zpool import -N ${ZPOOL_IMPORT_OPTS} "${pool}" ; then
+			warn "ZFS: Unable to import pool ${pool}"
+			return 1
+		fi
+	fi
+
+	return 0
+}
+
+# mount_dataset DATASET
+#   mounts the given zfs dataset.
+mount_dataset() {
+	local dataset="${1}"
+	local mountpoint="$(zfs get -H -o value mountpoint "${dataset}")"
+
+	# We need zfsutil for non-legacy mounts and not for legacy mounts.
+	if [ "${mountpoint}" = "legacy" ] ; then
+		mount -t zfs "${dataset}" "${NEWROOT}"
+	else
+		mount -o zfsutil -t zfs "${dataset}" "${NEWROOT}"
+	fi
+
+	return $?
+}
+
+# export_all OPTS
+#   exports all imported zfs pools.
+export_all() {
+	local opts="${1}"
+	local ret=0
+
+	IFS="${NEWLINE}"
+	for pool in `zpool list -H -o name` ; do
+		if zpool list -H "${pool}" 2>&1 > /dev/null ; then
+			zpool export "${pool}" ${opts} || ret=$?
+		fi
+	done
+	IFS="${OLDIFS}"
+
+	return ${ret}
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/contrib/dracut/Makefile.am
@@ -0,0 +1,3 @@
+SUBDIRS = 90zfs
+
+EXTRA_DIST = README.dracut.markdown
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/contrib/dracut/Makefile.in
@@ -0,0 +1,780 @@
+# Makefile.in generated by automake 1.15 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2014 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+VPATH = @srcdir@
+am__is_gnu_make = { \
+  if test -z '$(MAKELEVEL)'; then \
+    false; \
+  elif test -n '$(MAKE_HOST)'; then \
+    true; \
+  elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+    true; \
+  else \
+    false; \
+  fi; \
+}
+am__make_running_with_option = \
+  case $${target_option-} in \
+      ?) ;; \
+      *) echo "am__make_running_with_option: internal error: invalid" \
+              "target option '$${target_option-}' specified" >&2; \
+         exit 1;; \
+  esac; \
+  has_opt=no; \
+  sane_makeflags=$$MAKEFLAGS; \
+  if $(am__is_gnu_make); then \
+    sane_makeflags=$$MFLAGS; \
+  else \
+    case $$MAKEFLAGS in \
+      *\\[\ \	]*) \
+        bs=\\; \
+        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
+    esac; \
+  fi; \
+  skip_next=no; \
+  strip_trailopt () \
+  { \
+    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+  }; \
+  for flg in $$sane_makeflags; do \
+    test $$skip_next = yes && { skip_next=no; continue; }; \
+    case $$flg in \
+      *=*|--*) continue;; \
+        -*I) strip_trailopt 'I'; skip_next=yes;; \
+      -*I?*) strip_trailopt 'I';; \
+        -*O) strip_trailopt 'O'; skip_next=yes;; \
+      -*O?*) strip_trailopt 'O';; \
+        -*l) strip_trailopt 'l'; skip_next=yes;; \
+      -*l?*) strip_trailopt 'l';; \
+      -[dEDm]) skip_next=yes;; \
+      -[JT]) skip_next=yes;; \
+    esac; \
+    case $$flg in \
+      *$$target_option*) has_opt=yes; break;; \
+    esac; \
+  done; \
+  test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+target_triplet = @target@
+subdir = contrib/dracut
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/config/always-no-bool-compare.m4 \
+	$(top_srcdir)/config/always-no-unused-but-set-variable.m4 \
+	$(top_srcdir)/config/dkms.m4 \
+	$(top_srcdir)/config/kernel-acl.m4 \
+	$(top_srcdir)/config/kernel-automount.m4 \
+	$(top_srcdir)/config/kernel-bdev-block-device-operations.m4 \
+	$(top_srcdir)/config/kernel-bdev-logical-size.m4 \
+	$(top_srcdir)/config/kernel-bdev-physical-size.m4 \
+	$(top_srcdir)/config/kernel-bdi-setup-and-register.m4 \
+	$(top_srcdir)/config/kernel-bio-bvec-iter.m4 \
+	$(top_srcdir)/config/kernel-bio-end-io-t-args.m4 \
+	$(top_srcdir)/config/kernel-bio-failfast.m4 \
+	$(top_srcdir)/config/kernel-bio-rw-barrier.m4 \
+	$(top_srcdir)/config/kernel-bio-rw-discard.m4 \
+	$(top_srcdir)/config/kernel-blk-queue-flush.m4 \
+	$(top_srcdir)/config/kernel-blk-queue-max-hw-sectors.m4 \
+	$(top_srcdir)/config/kernel-blk-queue-max-segments.m4 \
+	$(top_srcdir)/config/kernel-blkdev-get-by-path.m4 \
+	$(top_srcdir)/config/kernel-blkdev-get.m4 \
+	$(top_srcdir)/config/kernel-block-device-operations-release-void.m4 \
+	$(top_srcdir)/config/kernel-check-disk-size-change.m4 \
+	$(top_srcdir)/config/kernel-clear-inode.m4 \
+	$(top_srcdir)/config/kernel-commit-metadata.m4 \
+	$(top_srcdir)/config/kernel-create-nameidata.m4 \
+	$(top_srcdir)/config/kernel-current_bio_tail.m4 \
+	$(top_srcdir)/config/kernel-d-make-root.m4 \
+	$(top_srcdir)/config/kernel-d-obtain-alias.m4 \
+	$(top_srcdir)/config/kernel-d-prune-aliases.m4 \
+	$(top_srcdir)/config/kernel-declare-event-class.m4 \
+	$(top_srcdir)/config/kernel-dentry-operations.m4 \
+	$(top_srcdir)/config/kernel-dirty-inode.m4 \
+	$(top_srcdir)/config/kernel-discard-granularity.m4 \
+	$(top_srcdir)/config/kernel-elevator-change.m4 \
+	$(top_srcdir)/config/kernel-encode-fh-inode.m4 \
+	$(top_srcdir)/config/kernel-evict-inode.m4 \
+	$(top_srcdir)/config/kernel-fallocate.m4 \
+	$(top_srcdir)/config/kernel-file-inode.m4 \
+	$(top_srcdir)/config/kernel-fmode-t.m4 \
+	$(top_srcdir)/config/kernel-follow-down-one.m4 \
+	$(top_srcdir)/config/kernel-fsync.m4 \
+	$(top_srcdir)/config/kernel-generic_io_acct.m4 \
+	$(top_srcdir)/config/kernel-get-disk-ro.m4 \
+	$(top_srcdir)/config/kernel-get-gendisk.m4 \
+	$(top_srcdir)/config/kernel-get-link.m4 \
+	$(top_srcdir)/config/kernel-insert-inode-locked.m4 \
+	$(top_srcdir)/config/kernel-invalidate-bdev-args.m4 \
+	$(top_srcdir)/config/kernel-is_owner_or_cap.m4 \
+	$(top_srcdir)/config/kernel-kmap-atomic-args.m4 \
+	$(top_srcdir)/config/kernel-kobj-name-len.m4 \
+	$(top_srcdir)/config/kernel-lookup-bdev.m4 \
+	$(top_srcdir)/config/kernel-lookup-nameidata.m4 \
+	$(top_srcdir)/config/kernel-lseek-execute.m4 \
+	$(top_srcdir)/config/kernel-mk-request-fn.m4 \
+	$(top_srcdir)/config/kernel-mkdir-umode-t.m4 \
+	$(top_srcdir)/config/kernel-mount-nodev.m4 \
+	$(top_srcdir)/config/kernel-open-bdev-exclusive.m4 \
+	$(top_srcdir)/config/kernel-put-link.m4 \
+	$(top_srcdir)/config/kernel-security-inode-init.m4 \
+	$(top_srcdir)/config/kernel-set-nlink.m4 \
+	$(top_srcdir)/config/kernel-sget-args.m4 \
+	$(top_srcdir)/config/kernel-show-options.m4 \
+	$(top_srcdir)/config/kernel-shrink.m4 \
+	$(top_srcdir)/config/kernel-truncate-range.m4 \
+	$(top_srcdir)/config/kernel-truncate-setsize.m4 \
+	$(top_srcdir)/config/kernel-vfs-iterate.m4 \
+	$(top_srcdir)/config/kernel-vfs-rw-iterate.m4 \
+	$(top_srcdir)/config/kernel-xattr-handler.m4 \
+	$(top_srcdir)/config/kernel.m4 $(top_srcdir)/config/libtool.m4 \
+	$(top_srcdir)/config/ltoptions.m4 \
+	$(top_srcdir)/config/ltsugar.m4 \
+	$(top_srcdir)/config/ltversion.m4 \
+	$(top_srcdir)/config/lt~obsolete.m4 \
+	$(top_srcdir)/config/mount-helper.m4 \
+	$(top_srcdir)/config/user-arch.m4 \
+	$(top_srcdir)/config/user-dracut.m4 \
+	$(top_srcdir)/config/user-frame-larger-than.m4 \
+	$(top_srcdir)/config/user-libblkid.m4 \
+	$(top_srcdir)/config/user-libuuid.m4 \
+	$(top_srcdir)/config/user-runstatedir.m4 \
+	$(top_srcdir)/config/user-systemd.m4 \
+	$(top_srcdir)/config/user-sysvinit.m4 \
+	$(top_srcdir)/config/user-udev.m4 \
+	$(top_srcdir)/config/user-zlib.m4 $(top_srcdir)/config/user.m4 \
+	$(top_srcdir)/config/zfs-build.m4 \
+	$(top_srcdir)/config/zfs-meta.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/zfs_config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo "  GEN     " $@;
+am__v_GEN_1 = 
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 = 
+SOURCES =
+DIST_SOURCES =
+RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \
+	ctags-recursive dvi-recursive html-recursive info-recursive \
+	install-data-recursive install-dvi-recursive \
+	install-exec-recursive install-html-recursive \
+	install-info-recursive install-pdf-recursive \
+	install-ps-recursive install-recursive installcheck-recursive \
+	installdirs-recursive pdf-recursive ps-recursive \
+	tags-recursive uninstall-recursive
+am__can_run_installinfo = \
+  case $$AM_UPDATE_INFO_DIR in \
+    n|no|NO) false;; \
+    *) (install-info --version) >/dev/null 2>&1;; \
+  esac
+RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive	\
+  distclean-recursive maintainer-clean-recursive
+am__recursive_targets = \
+  $(RECURSIVE_TARGETS) \
+  $(RECURSIVE_CLEAN_TARGETS) \
+  $(am__extra_recursive_targets)
+AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \
+	distdir
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates.  Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+  BEGIN { nonempty = 0; } \
+  { items[$$0] = 1; nonempty = 1; } \
+  END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique.  This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+  list='$(am__tagged_files)'; \
+  unique=`for i in $$list; do \
+    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+  done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+DIST_SUBDIRS = $(SUBDIRS)
+am__DIST_COMMON = $(srcdir)/Makefile.in
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+am__relativize = \
+  dir0=`pwd`; \
+  sed_first='s,^\([^/]*\)/.*$$,\1,'; \
+  sed_rest='s,^[^/]*/*,,'; \
+  sed_last='s,^.*/\([^/]*\)$$,\1,'; \
+  sed_butlast='s,/*[^/]*$$,,'; \
+  while test -n "$$dir1"; do \
+    first=`echo "$$dir1" | sed -e "$$sed_first"`; \
+    if test "$$first" != "."; then \
+      if test "$$first" = ".."; then \
+        dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \
+        dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \
+      else \
+        first2=`echo "$$dir2" | sed -e "$$sed_first"`; \
+        if test "$$first2" = "$$first"; then \
+          dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \
+        else \
+          dir2="../$$dir2"; \
+        fi; \
+        dir0="$$dir0"/"$$first"; \
+      fi; \
+    fi; \
+    dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \
+  done; \
+  reldir="$$dir2"
+ACLOCAL = @ACLOCAL@
+ALIEN = @ALIEN@
+ALIEN_VERSION = @ALIEN_VERSION@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCAS = @CCAS@
+CCASDEPMODE = @CCASDEPMODE@
+CCASFLAGS = @CCASFLAGS@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEBUG_CFLAGS = @DEBUG_CFLAGS@
+DEBUG_DMU_TX = @DEBUG_DMU_TX@
+DEBUG_STACKFLAGS = @DEBUG_STACKFLAGS@
+DEBUG_ZFS = @DEBUG_ZFS@
+DEFAULT_INITCONF_DIR = @DEFAULT_INITCONF_DIR@
+DEFAULT_INIT_DIR = @DEFAULT_INIT_DIR@
+DEFAULT_INIT_SCRIPT = @DEFAULT_INIT_SCRIPT@
+DEFAULT_PACKAGE = @DEFAULT_PACKAGE@
+DEFINE_INITRAMFS = @DEFINE_INITRAMFS@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DPKG = @DPKG@
+DPKGBUILD = @DPKGBUILD@
+DPKGBUILD_VERSION = @DPKGBUILD_VERSION@
+DPKG_VERSION = @DPKG_VERSION@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+FRAME_LARGER_THAN = @FRAME_LARGER_THAN@
+GREP = @GREP@
+HAVE_ALIEN = @HAVE_ALIEN@
+HAVE_DPKG = @HAVE_DPKG@
+HAVE_DPKGBUILD = @HAVE_DPKGBUILD@
+HAVE_RPM = @HAVE_RPM@
+HAVE_RPMBUILD = @HAVE_RPMBUILD@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+KERNELCPPFLAGS = @KERNELCPPFLAGS@
+KERNELMAKE_PARAMS = @KERNELMAKE_PARAMS@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBBLKID = @LIBBLKID@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIBUUID = @LIBUUID@
+LINUX = @LINUX@
+LINUX_OBJ = @LINUX_OBJ@
+LINUX_SYMBOLS = @LINUX_SYMBOLS@
+LINUX_VERSION = @LINUX_VERSION@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NO_BOOL_COMPARE = @NO_BOOL_COMPARE@
+NO_UNUSED_BUT_SET_VARIABLE = @NO_UNUSED_BUT_SET_VARIABLE@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+RANLIB = @RANLIB@
+RELEASE = @RELEASE@
+RPM = @RPM@
+RPMBUILD = @RPMBUILD@
+RPMBUILD_VERSION = @RPMBUILD_VERSION@
+RPM_DEFINE_COMMON = @RPM_DEFINE_COMMON@
+RPM_DEFINE_DKMS = @RPM_DEFINE_DKMS@
+RPM_DEFINE_KMOD = @RPM_DEFINE_KMOD@
+RPM_DEFINE_UTIL = @RPM_DEFINE_UTIL@
+RPM_SPEC_DIR = @RPM_SPEC_DIR@
+RPM_VERSION = @RPM_VERSION@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SPL = @SPL@
+SPL_OBJ = @SPL_OBJ@
+SPL_SYMBOLS = @SPL_SYMBOLS@
+SPL_VERSION = @SPL_VERSION@
+SRPM_DEFINE_COMMON = @SRPM_DEFINE_COMMON@
+SRPM_DEFINE_DKMS = @SRPM_DEFINE_DKMS@
+SRPM_DEFINE_KMOD = @SRPM_DEFINE_KMOD@
+SRPM_DEFINE_UTIL = @SRPM_DEFINE_UTIL@
+STRIP = @STRIP@
+TARGET_ASM_DIR = @TARGET_ASM_DIR@
+VENDOR = @VENDOR@
+VERSION = @VERSION@
+ZFS_CONFIG = @ZFS_CONFIG@
+ZFS_INIT_SYSTEMD = @ZFS_INIT_SYSTEMD@
+ZFS_INIT_SYSV = @ZFS_INIT_SYSV@
+ZFS_META_ALIAS = @ZFS_META_ALIAS@
+ZFS_META_AUTHOR = @ZFS_META_AUTHOR@
+ZFS_META_DATA = @ZFS_META_DATA@
+ZFS_META_LICENSE = @ZFS_META_LICENSE@
+ZFS_META_LT_AGE = @ZFS_META_LT_AGE@
+ZFS_META_LT_CURRENT = @ZFS_META_LT_CURRENT@
+ZFS_META_LT_REVISION = @ZFS_META_LT_REVISION@
+ZFS_META_NAME = @ZFS_META_NAME@
+ZFS_META_RELEASE = @ZFS_META_RELEASE@
+ZFS_META_VERSION = @ZFS_META_VERSION@
+ZFS_MODULE_LOAD = @ZFS_MODULE_LOAD@
+ZLIB = @ZLIB@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dracutdir = @dracutdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+modulesloaddir = @modulesloaddir@
+mounthelperdir = @mounthelperdir@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+runstatedir = @runstatedir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+systemdpresetdir = @systemdpresetdir@
+systemdunitdir = @systemdunitdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+udevdir = @udevdir@
+udevruledir = @udevruledir@
+SUBDIRS = 90zfs
+EXTRA_DIST = README.dracut.markdown
+all: all-recursive
+
+.SUFFIXES:
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+	        && { if test -f $@; then exit 0; else break; fi; }; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu contrib/dracut/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --gnu contrib/dracut/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+	esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
+
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run 'make' without going through this Makefile.
+# To change the values of 'make' variables: instead of editing Makefiles,
+# (1) if the variable is set in 'config.status', edit 'config.status'
+#     (which will cause the Makefiles to be regenerated when you run 'make');
+# (2) otherwise, pass the desired values on the 'make' command line.
+$(am__recursive_targets):
+	@fail=; \
+	if $(am__make_keepgoing); then \
+	  failcom='fail=yes'; \
+	else \
+	  failcom='exit 1'; \
+	fi; \
+	dot_seen=no; \
+	target=`echo $@ | sed s/-recursive//`; \
+	case "$@" in \
+	  distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
+	  *) list='$(SUBDIRS)' ;; \
+	esac; \
+	for subdir in $$list; do \
+	  echo "Making $$target in $$subdir"; \
+	  if test "$$subdir" = "."; then \
+	    dot_seen=yes; \
+	    local_target="$$target-am"; \
+	  else \
+	    local_target="$$target"; \
+	  fi; \
+	  ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+	  || eval $$failcom; \
+	done; \
+	if test "$$dot_seen" = "no"; then \
+	  $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+	fi; test -z "$$fail"
+
+ID: $(am__tagged_files)
+	$(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-recursive
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	set x; \
+	here=`pwd`; \
+	if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
+	  include_option=--etags-include; \
+	  empty_fix=.; \
+	else \
+	  include_option=--include; \
+	  empty_fix=; \
+	fi; \
+	list='$(SUBDIRS)'; for subdir in $$list; do \
+	  if test "$$subdir" = .; then :; else \
+	    test ! -f $$subdir/TAGS || \
+	      set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \
+	  fi; \
+	done; \
+	$(am__define_uniq_tagged_files); \
+	shift; \
+	if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+	  test -n "$$unique" || unique=$$empty_fix; \
+	  if test $$# -gt 0; then \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      "$$@" $$unique; \
+	  else \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      $$unique; \
+	  fi; \
+	fi
+ctags: ctags-recursive
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	$(am__define_uniq_tagged_files); \
+	test -z "$(CTAGS_ARGS)$$unique" \
+	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+	     $$unique
+
+GTAGS:
+	here=`$(am__cd) $(top_builddir) && pwd` \
+	  && $(am__cd) $(top_srcdir) \
+	  && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-recursive
+
+cscopelist-am: $(am__tagged_files)
+	list='$(am__tagged_files)'; \
+	case "$(srcdir)" in \
+	  [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+	  *) sdir=$(subdir)/$(srcdir) ;; \
+	esac; \
+	for i in $$list; do \
+	  if test -f "$$i"; then \
+	    echo "$(subdir)/$$i"; \
+	  else \
+	    echo "$$sdir/$$i"; \
+	  fi; \
+	done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	list='$(DISTFILES)'; \
+	  dist_files=`for file in $$list; do echo $$file; done | \
+	  sed -e "s|^$$srcdirstrip/||;t" \
+	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+	case $$dist_files in \
+	  */*) $(MKDIR_P) `echo "$$dist_files" | \
+			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+			   sort -u` ;; \
+	esac; \
+	for file in $$dist_files; do \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  if test -d $$d/$$file; then \
+	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+	    if test -d "$(distdir)/$$file"; then \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+	  else \
+	    test -f "$(distdir)/$$file" \
+	    || cp -p $$d/$$file "$(distdir)/$$file" \
+	    || exit 1; \
+	  fi; \
+	done
+	@list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
+	  if test "$$subdir" = .; then :; else \
+	    $(am__make_dryrun) \
+	      || test -d "$(distdir)/$$subdir" \
+	      || $(MKDIR_P) "$(distdir)/$$subdir" \
+	      || exit 1; \
+	    dir1=$$subdir; dir2="$(distdir)/$$subdir"; \
+	    $(am__relativize); \
+	    new_distdir=$$reldir; \
+	    dir1=$$subdir; dir2="$(top_distdir)"; \
+	    $(am__relativize); \
+	    new_top_distdir=$$reldir; \
+	    echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \
+	    echo "     am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \
+	    ($(am__cd) $$subdir && \
+	      $(MAKE) $(AM_MAKEFLAGS) \
+	        top_distdir="$$new_top_distdir" \
+	        distdir="$$new_distdir" \
+		am__remove_distdir=: \
+		am__skip_length_check=: \
+		am__skip_mode_fix=: \
+	        distdir) \
+	      || exit 1; \
+	  fi; \
+	done
+check-am: all-am
+check: check-recursive
+all-am: Makefile
+installdirs: installdirs-recursive
+installdirs-am:
+install: install-recursive
+install-exec: install-exec-recursive
+install-data: install-data-recursive
+uninstall: uninstall-recursive
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-recursive
+install-strip:
+	if test -z '$(STRIP)'; then \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	      install; \
+	else \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+	fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+clean: clean-recursive
+
+clean-am: clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-recursive
+	-rm -f Makefile
+distclean-am: clean-am distclean-generic distclean-tags
+
+dvi: dvi-recursive
+
+dvi-am:
+
+html: html-recursive
+
+html-am:
+
+info: info-recursive
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-recursive
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-recursive
+
+install-html-am:
+
+install-info: install-info-recursive
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-recursive
+
+install-pdf-am:
+
+install-ps: install-ps-recursive
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-recursive
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-recursive
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-recursive
+
+pdf-am:
+
+ps: ps-recursive
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: $(am__recursive_targets) install-am install-strip
+
+.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \
+	check-am clean clean-generic clean-libtool cscopelist-am ctags \
+	ctags-am distclean distclean-generic distclean-libtool \
+	distclean-tags distdir dvi dvi-am html html-am info info-am \
+	install install-am install-data install-data-am install-dvi \
+	install-dvi-am install-exec install-exec-am install-html \
+	install-html-am install-info install-info-am install-man \
+	install-pdf install-pdf-am install-ps install-ps-am \
+	install-strip installcheck installcheck-am installdirs \
+	installdirs-am maintainer-clean maintainer-clean-generic \
+	mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \
+	ps ps-am tags tags-am uninstall uninstall-am
+
+.PRECIOUS: Makefile
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/contrib/dracut/README.dracut.markdown
@@ -0,0 +1,207 @@
+How to setup a zfs root filesystem using dracut
+-----------------------------------------------
+
+1) Install the zfs-dracut package.  This package adds a zfs dracut module
+to the /usr/share/dracut/modules.d/ directory which allows dracut to
+create an initramfs which is zfs aware.
+
+2) Set the bootfs property for the bootable dataset in the pool.  Then set
+the dataset mountpoint property to '/'.
+
+    $ zpool set bootfs=pool/dataset pool
+    $ zfs set mountpoint=/ pool/dataset
+
+It is also possible to set the bootfs property for an entire pool, just in
+case you are not using a dedicated dataset for '/'.
+
+    $ zpool set bootfs=pool pool
+    $ zfs set mountpoint=/ pool
+
+Alternately, legacy mountpoints can be used by setting the 'root=' option
+on the kernel line of your grub.conf/menu.lst configuration file.  Then
+set the dataset mountpoint property to 'legacy'.
+
+    $ grub.conf/menu.lst: kernel ... root=ZFS=pool/dataset
+    $ zfs set mountpoint=legacy pool/dataset
+
+3) To set zfs module options put them in /etc/modprobe.d/zfs.conf file.
+The complete list of zfs module options is available by running the
+_modinfo zfs_ command.  Commonly set options include: zfs_arc_min,
+zfs_arc_max, zfs_prefetch_disable, and zfs_vdev_max_pending.
+
+4) Finally, create your new initramfs by running dracut.
+
+    $ dracut --force /path/to/initramfs kernel_version
+
+Kernel Command Line
+-------------------
+
+The initramfs' behavior is influenced by the following kernel command line
+parameters passed in from the boot loader:
+
+* `root=...`: If not set, importable pools are searched for a bootfs
+attribute.  If an explicitly set root is desired, you may use
+`root=ZFS:pool/dataset`
+
+* `zfs_force=0`: If set to 1, the initramfs will run `zpool import -f` when
+attempting to import pools if the required pool isn't automatically imported
+by the zfs module.  This can save you a trip to a bootcd if hostid has
+changed, but is dangerous and can lead to zpool corruption, particularly in
+cases where storage is on a shared fabric such as iSCSI where multiple hosts
+can access storage devices concurrently.  _Please understand the implications
+of force-importing a pool before enabling this option!_
+
+* `spl_hostid`: By default, the hostid used by the SPL module is read from
+/etc/hostid inside the initramfs.  This file is placed there from the host
+system when the initramfs is built which effectively ties the ramdisk to the
+host which builds it.  If a different hostid is desired, one may be set in
+this attribute and will override any file present in the ramdisk.  The
+format should be hex exactly as found in the `/etc/hostid` file, IE
+`spl_hostid=0x00bab10c`.
+
+Note that changing the hostid between boots will most likely lead to an
+un-importable pool since the last importing hostid won't match.  In order
+to recover from this, you may use the `zfs_force` option or boot from a
+different filesystem and `zpool import -f` then `zpool export` the pool
+before rebooting with the new hostid.
+
+How it Works
+============
+
+The Dracut module consists of the following files (less Makefile's):
+
+* `module-setup.sh`: Script run by the initramfs builder to create the
+ramdisk.  Contains instructions on which files are required by the modules
+and z* programs.  Also triggers inclusion of `/etc/hostid` and the zpool
+cache.  This file is not included in the initramfs.
+
+* `90-zfs.rules`: udev rules which trigger loading of the ZFS modules at boot.
+
+* `zfs-lib.sh`: Utility functions used by the other files.
+
+* `parse-zfs.sh`: Run early in the initramfs boot process to parse kernel
+command line and determine if ZFS is the active root filesystem.
+
+* `mount-zfs.sh`: Run later in initramfs boot process after udev has settled
+to mount the root dataset.
+
+* `export-zfs.sh`: Run on shutdown after dracut has restored the initramfs
+and pivoted to it, allowing for a clean unmount and export of the ZFS root.
+
+`zfs-lib.sh`
+------------
+
+This file provides a few handy functions for working with ZFS. Those
+functions are used by the `mount-zfs.sh` and `export-zfs.sh` files.
+However, they could be used by any other file as well, as long as the file
+sources `/lib/dracut-zfs-lib.sh`.
+
+`module-setup.sh`
+-----------------
+
+This file is run by the Dracut script within the live system, not at boot
+time.  It's not included in the final initramfs.  Functions in this script
+describe which files are needed by ZFS at boot time.
+
+Currently all the various z* and spl modules are included, a dependency is
+asserted on udev-rules, and the various zfs, zpool, etc. helpers are included.
+Dracut provides library functions which automatically gather the shared libs
+necessary to run each of these binaries, so statically built binaries are
+not required.
+
+The zpool and zvol udev rules files are copied from where they are
+installed by the ZFS build.  __PACKAGERS TAKE NOTE__: If you move
+`/etc/udev/rules/60-z*.rules`, you'll need to update this file to match.
+
+Currently this file also includes `/etc/hostid` and `/etc/zfs/zpool.cache`
+which means the generated ramdisk is specific to the host system which built
+it.  If a generic initramfs is required, it may be preferable to omit these
+files and specify the `spl_hostid` from the boot loader instead.
+
+`parse-zfs.sh`
+--------------
+
+Run during the cmdline phase of the initramfs boot process, this script
+performs some basic sanity checks on kernel command line parameters to
+determine if booting from ZFS is likely to be what is desired.  Dracut
+requires this script to adjust the `root` variable if required and to set
+`rootok=1` if a mountable root filesystem is available.  Unfortunately this
+script must run before udev is settled and kernel modules are known to be
+loaded, so accessing the zpool and zfs commands is unsafe.
+
+If the root=ZFS... parameter is set on the command line, then it's at least
+certain that ZFS is what is desired, though this script is unable to
+determine if ZFS is in fact available.  This script will alter the `root`
+parameter to replace several historical forms of specifying the pool and
+dataset name with the canonical form of `zfs:pool/dataset`.
+
+If no root= parameter is set, the best this script can do is guess that
+ZFS is desired.  At present, no other known filesystems will work with no
+root= parameter, though this might possibly interfere with using the
+compiled-in default root in the kernel image.  It's considered unlikely
+that would ever be the case when an initramfs is in use, so this script
+sets `root=zfs:AUTO` and hopes for the best.
+
+Once the root=... (or lack thereof) parameter is parsed, a dummy symlink
+is created from `/dev/root` -> `/dev/null` to satisfy parts of the Dracut
+process which check for presence of a single root device node.
+
+Finally, an initqueue/finished hook is registered which causes the initqueue
+phase of Dracut to wait for `/dev/zfs` to become available before attempting
+to mount anything.
+
+`mount-zfs.sh`
+--------------
+
+This script is run after udev has settled and all tasks in the initqueue
+have succeeded.  This ensures that `/dev/zfs` is available and that the
+various ZFS modules are successfully loaded.  As it is now safe to call
+zpool and friends, we can proceed to find the bootfs attribute if necessary.
+
+If the root parameter was explicitly set on the command line, no parsing is
+necessary.  The list of imported pools is checked to see if the desired pool
+is already imported.  If it's not, and attempt is made to import the pool
+explicitly, though no force is attempted.  Finally the specified dataset
+is mounted on `$NEWROOT`, first using the `-o zfsutil` option to handle
+non-legacy mounts, then if that fails, without zfsutil to handle legacy
+mount points.
+
+If no root parameter was specified, this script attempts to find a pool with
+its bootfs attribute set.  First, already-imported pools are scanned and if
+an appropriate pool is found, no additional pools are imported.  If no pool
+with bootfs is found, any additional pools in the system are imported with
+`zpool import -N -a`, and the scan for bootfs is tried again.  If no bootfs
+is found with all pools imported, all pools are re-exported, and boot fails.
+Assuming a bootfs is found, an attempt is made to mount it to `$NEWROOT`,
+first with, then without the zfsutil option as above.
+
+Ordinarily pools are imported _without_ the force option which may cause
+boot to fail if the hostid has changed or a pool has been physically moved
+between servers.  The `zfs_force` kernel parameter is provided which when
+set to `1` causes `zpool import` to be run with the `-f` flag.  Forcing pool
+import can lead to serious data corruption and loss of pools, so this option
+should be used with extreme caution.  Note that even with this flag set, if
+the required zpool was auto-imported by the kernel module, no additional
+`zpool import` commands are run, so nothing is forced.
+
+`export-zfs.sh`
+---------------
+
+Normally the zpool containing the root dataset cannot be exported on
+shutdown as it is still in use by the init process. To work around this,
+Dracut is able to restore the initramfs on shutdown and pivot to it.
+All remaining process are then running from a ramdisk, allowing for a
+clean unmount and export of the ZFS root. The theory of operation is
+described in detail in the [Dracut manual](https://www.kernel.org/pub/linux/utils/boot/dracut/dracut.html#_dracut_on_shutdown).
+
+This script will try to export all remaining zpools after Dracut has
+pivoted to the initramfs. If an initial regular export is not successful,
+Dracut will call this script once more with the `final` option,
+in which case a forceful export is attempted.
+
+Other Dracut modules include similar shutdown scripts and Dracut
+invokes these scripts round-robin until they succeed. In particular,
+the `90dm` module installs a script which tries to close and remove
+all device mapper targets. Thus, if there are ZVOLs containing
+dm-crypt volumes or if the zpool itself is backed by a dm-crypt
+volume, the shutdown scripts will try to untangle this.
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/contrib/initramfs/Makefile.am
@@ -0,0 +1,21 @@
+initrddir = $(datarootdir)/initramfs-tools
+
+initrd_SCRIPTS = conf-hooks.d/zfs hooks/zfs scripts/zfs
+
+EXTRA_DIST = \
+	$(top_srcdir)/contrib/initramfs/conf-hooks.d/zfs \
+	$(top_srcdir)/contrib/initramfs/hooks/zfs \
+	$(top_srcdir)/contrib/initramfs/scripts/zfs \
+	$(top_srcdir)/contrib/initramfs/README.initramfs.markdown
+
+install-initrdSCRIPTS: $(EXTRA_DIST)
+	for d in conf-hooks.d hooks scripts; do \
+	  $(MKDIR_P) $(DESTDIR)$(initrddir)/$$d; \
+	  cp $(top_srcdir)/contrib/initramfs/$$d/zfs \
+	    $(DESTDIR)$(initrddir)/$$d/; \
+	done
+	if [ -f etc/init.d/zfs ]; then \
+	  $(MKDIR_P) $(DESTDIR)$(DEFAULT_INITCONF_DIR); \
+	  cp $(top_srcdir)/etc/init.d/zfs \
+	    $(DESTDIR)$(DEFAULT_INITCONF_DIR)/; \
+	fi
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/contrib/initramfs/Makefile.in
@@ -0,0 +1,659 @@
+# Makefile.in generated by automake 1.15 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2014 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+VPATH = @srcdir@
+am__is_gnu_make = { \
+  if test -z '$(MAKELEVEL)'; then \
+    false; \
+  elif test -n '$(MAKE_HOST)'; then \
+    true; \
+  elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+    true; \
+  else \
+    false; \
+  fi; \
+}
+am__make_running_with_option = \
+  case $${target_option-} in \
+      ?) ;; \
+      *) echo "am__make_running_with_option: internal error: invalid" \
+              "target option '$${target_option-}' specified" >&2; \
+         exit 1;; \
+  esac; \
+  has_opt=no; \
+  sane_makeflags=$$MAKEFLAGS; \
+  if $(am__is_gnu_make); then \
+    sane_makeflags=$$MFLAGS; \
+  else \
+    case $$MAKEFLAGS in \
+      *\\[\ \	]*) \
+        bs=\\; \
+        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
+    esac; \
+  fi; \
+  skip_next=no; \
+  strip_trailopt () \
+  { \
+    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+  }; \
+  for flg in $$sane_makeflags; do \
+    test $$skip_next = yes && { skip_next=no; continue; }; \
+    case $$flg in \
+      *=*|--*) continue;; \
+        -*I) strip_trailopt 'I'; skip_next=yes;; \
+      -*I?*) strip_trailopt 'I';; \
+        -*O) strip_trailopt 'O'; skip_next=yes;; \
+      -*O?*) strip_trailopt 'O';; \
+        -*l) strip_trailopt 'l'; skip_next=yes;; \
+      -*l?*) strip_trailopt 'l';; \
+      -[dEDm]) skip_next=yes;; \
+      -[JT]) skip_next=yes;; \
+    esac; \
+    case $$flg in \
+      *$$target_option*) has_opt=yes; break;; \
+    esac; \
+  done; \
+  test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+target_triplet = @target@
+subdir = contrib/initramfs
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/config/always-no-bool-compare.m4 \
+	$(top_srcdir)/config/always-no-unused-but-set-variable.m4 \
+	$(top_srcdir)/config/dkms.m4 \
+	$(top_srcdir)/config/kernel-acl.m4 \
+	$(top_srcdir)/config/kernel-automount.m4 \
+	$(top_srcdir)/config/kernel-bdev-block-device-operations.m4 \
+	$(top_srcdir)/config/kernel-bdev-logical-size.m4 \
+	$(top_srcdir)/config/kernel-bdev-physical-size.m4 \
+	$(top_srcdir)/config/kernel-bdi-setup-and-register.m4 \
+	$(top_srcdir)/config/kernel-bio-bvec-iter.m4 \
+	$(top_srcdir)/config/kernel-bio-end-io-t-args.m4 \
+	$(top_srcdir)/config/kernel-bio-failfast.m4 \
+	$(top_srcdir)/config/kernel-bio-rw-barrier.m4 \
+	$(top_srcdir)/config/kernel-bio-rw-discard.m4 \
+	$(top_srcdir)/config/kernel-blk-queue-flush.m4 \
+	$(top_srcdir)/config/kernel-blk-queue-max-hw-sectors.m4 \
+	$(top_srcdir)/config/kernel-blk-queue-max-segments.m4 \
+	$(top_srcdir)/config/kernel-blkdev-get-by-path.m4 \
+	$(top_srcdir)/config/kernel-blkdev-get.m4 \
+	$(top_srcdir)/config/kernel-block-device-operations-release-void.m4 \
+	$(top_srcdir)/config/kernel-check-disk-size-change.m4 \
+	$(top_srcdir)/config/kernel-clear-inode.m4 \
+	$(top_srcdir)/config/kernel-commit-metadata.m4 \
+	$(top_srcdir)/config/kernel-create-nameidata.m4 \
+	$(top_srcdir)/config/kernel-current_bio_tail.m4 \
+	$(top_srcdir)/config/kernel-d-make-root.m4 \
+	$(top_srcdir)/config/kernel-d-obtain-alias.m4 \
+	$(top_srcdir)/config/kernel-d-prune-aliases.m4 \
+	$(top_srcdir)/config/kernel-declare-event-class.m4 \
+	$(top_srcdir)/config/kernel-dentry-operations.m4 \
+	$(top_srcdir)/config/kernel-dirty-inode.m4 \
+	$(top_srcdir)/config/kernel-discard-granularity.m4 \
+	$(top_srcdir)/config/kernel-elevator-change.m4 \
+	$(top_srcdir)/config/kernel-encode-fh-inode.m4 \
+	$(top_srcdir)/config/kernel-evict-inode.m4 \
+	$(top_srcdir)/config/kernel-fallocate.m4 \
+	$(top_srcdir)/config/kernel-file-inode.m4 \
+	$(top_srcdir)/config/kernel-fmode-t.m4 \
+	$(top_srcdir)/config/kernel-follow-down-one.m4 \
+	$(top_srcdir)/config/kernel-fsync.m4 \
+	$(top_srcdir)/config/kernel-generic_io_acct.m4 \
+	$(top_srcdir)/config/kernel-get-disk-ro.m4 \
+	$(top_srcdir)/config/kernel-get-gendisk.m4 \
+	$(top_srcdir)/config/kernel-get-link.m4 \
+	$(top_srcdir)/config/kernel-insert-inode-locked.m4 \
+	$(top_srcdir)/config/kernel-invalidate-bdev-args.m4 \
+	$(top_srcdir)/config/kernel-is_owner_or_cap.m4 \
+	$(top_srcdir)/config/kernel-kmap-atomic-args.m4 \
+	$(top_srcdir)/config/kernel-kobj-name-len.m4 \
+	$(top_srcdir)/config/kernel-lookup-bdev.m4 \
+	$(top_srcdir)/config/kernel-lookup-nameidata.m4 \
+	$(top_srcdir)/config/kernel-lseek-execute.m4 \
+	$(top_srcdir)/config/kernel-mk-request-fn.m4 \
+	$(top_srcdir)/config/kernel-mkdir-umode-t.m4 \
+	$(top_srcdir)/config/kernel-mount-nodev.m4 \
+	$(top_srcdir)/config/kernel-open-bdev-exclusive.m4 \
+	$(top_srcdir)/config/kernel-put-link.m4 \
+	$(top_srcdir)/config/kernel-security-inode-init.m4 \
+	$(top_srcdir)/config/kernel-set-nlink.m4 \
+	$(top_srcdir)/config/kernel-sget-args.m4 \
+	$(top_srcdir)/config/kernel-show-options.m4 \
+	$(top_srcdir)/config/kernel-shrink.m4 \
+	$(top_srcdir)/config/kernel-truncate-range.m4 \
+	$(top_srcdir)/config/kernel-truncate-setsize.m4 \
+	$(top_srcdir)/config/kernel-vfs-iterate.m4 \
+	$(top_srcdir)/config/kernel-vfs-rw-iterate.m4 \
+	$(top_srcdir)/config/kernel-xattr-handler.m4 \
+	$(top_srcdir)/config/kernel.m4 $(top_srcdir)/config/libtool.m4 \
+	$(top_srcdir)/config/ltoptions.m4 \
+	$(top_srcdir)/config/ltsugar.m4 \
+	$(top_srcdir)/config/ltversion.m4 \
+	$(top_srcdir)/config/lt~obsolete.m4 \
+	$(top_srcdir)/config/mount-helper.m4 \
+	$(top_srcdir)/config/user-arch.m4 \
+	$(top_srcdir)/config/user-dracut.m4 \
+	$(top_srcdir)/config/user-frame-larger-than.m4 \
+	$(top_srcdir)/config/user-libblkid.m4 \
+	$(top_srcdir)/config/user-libuuid.m4 \
+	$(top_srcdir)/config/user-runstatedir.m4 \
+	$(top_srcdir)/config/user-systemd.m4 \
+	$(top_srcdir)/config/user-sysvinit.m4 \
+	$(top_srcdir)/config/user-udev.m4 \
+	$(top_srcdir)/config/user-zlib.m4 $(top_srcdir)/config/user.m4 \
+	$(top_srcdir)/config/zfs-build.m4 \
+	$(top_srcdir)/config/zfs-meta.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/zfs_config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+    $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+    *) f=$$p;; \
+  esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+  srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+  for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+  for p in $$list; do echo "$$p $$p"; done | \
+  sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+  $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+    if (++n[$$2] == $(am__install_max)) \
+      { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+    END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+  sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+  sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+  test -z "$$files" \
+    || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+    || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+         $(am__cd) "$$dir" && rm -f $$files; }; \
+  }
+am__installdirs = "$(DESTDIR)$(initrddir)"
+SCRIPTS = $(initrd_SCRIPTS)
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo "  GEN     " $@;
+am__v_GEN_1 = 
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 = 
+SOURCES =
+DIST_SOURCES =
+am__can_run_installinfo = \
+  case $$AM_UPDATE_INFO_DIR in \
+    n|no|NO) false;; \
+    *) (install-info --version) >/dev/null 2>&1;; \
+  esac
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+am__DIST_COMMON = $(srcdir)/Makefile.in
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ALIEN = @ALIEN@
+ALIEN_VERSION = @ALIEN_VERSION@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCAS = @CCAS@
+CCASDEPMODE = @CCASDEPMODE@
+CCASFLAGS = @CCASFLAGS@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEBUG_CFLAGS = @DEBUG_CFLAGS@
+DEBUG_DMU_TX = @DEBUG_DMU_TX@
+DEBUG_STACKFLAGS = @DEBUG_STACKFLAGS@
+DEBUG_ZFS = @DEBUG_ZFS@
+DEFAULT_INITCONF_DIR = @DEFAULT_INITCONF_DIR@
+DEFAULT_INIT_DIR = @DEFAULT_INIT_DIR@
+DEFAULT_INIT_SCRIPT = @DEFAULT_INIT_SCRIPT@
+DEFAULT_PACKAGE = @DEFAULT_PACKAGE@
+DEFINE_INITRAMFS = @DEFINE_INITRAMFS@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DPKG = @DPKG@
+DPKGBUILD = @DPKGBUILD@
+DPKGBUILD_VERSION = @DPKGBUILD_VERSION@
+DPKG_VERSION = @DPKG_VERSION@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+FRAME_LARGER_THAN = @FRAME_LARGER_THAN@
+GREP = @GREP@
+HAVE_ALIEN = @HAVE_ALIEN@
+HAVE_DPKG = @HAVE_DPKG@
+HAVE_DPKGBUILD = @HAVE_DPKGBUILD@
+HAVE_RPM = @HAVE_RPM@
+HAVE_RPMBUILD = @HAVE_RPMBUILD@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+KERNELCPPFLAGS = @KERNELCPPFLAGS@
+KERNELMAKE_PARAMS = @KERNELMAKE_PARAMS@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBBLKID = @LIBBLKID@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIBUUID = @LIBUUID@
+LINUX = @LINUX@
+LINUX_OBJ = @LINUX_OBJ@
+LINUX_SYMBOLS = @LINUX_SYMBOLS@
+LINUX_VERSION = @LINUX_VERSION@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NO_BOOL_COMPARE = @NO_BOOL_COMPARE@
+NO_UNUSED_BUT_SET_VARIABLE = @NO_UNUSED_BUT_SET_VARIABLE@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+RANLIB = @RANLIB@
+RELEASE = @RELEASE@
+RPM = @RPM@
+RPMBUILD = @RPMBUILD@
+RPMBUILD_VERSION = @RPMBUILD_VERSION@
+RPM_DEFINE_COMMON = @RPM_DEFINE_COMMON@
+RPM_DEFINE_DKMS = @RPM_DEFINE_DKMS@
+RPM_DEFINE_KMOD = @RPM_DEFINE_KMOD@
+RPM_DEFINE_UTIL = @RPM_DEFINE_UTIL@
+RPM_SPEC_DIR = @RPM_SPEC_DIR@
+RPM_VERSION = @RPM_VERSION@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SPL = @SPL@
+SPL_OBJ = @SPL_OBJ@
+SPL_SYMBOLS = @SPL_SYMBOLS@
+SPL_VERSION = @SPL_VERSION@
+SRPM_DEFINE_COMMON = @SRPM_DEFINE_COMMON@
+SRPM_DEFINE_DKMS = @SRPM_DEFINE_DKMS@
+SRPM_DEFINE_KMOD = @SRPM_DEFINE_KMOD@
+SRPM_DEFINE_UTIL = @SRPM_DEFINE_UTIL@
+STRIP = @STRIP@
+TARGET_ASM_DIR = @TARGET_ASM_DIR@
+VENDOR = @VENDOR@
+VERSION = @VERSION@
+ZFS_CONFIG = @ZFS_CONFIG@
+ZFS_INIT_SYSTEMD = @ZFS_INIT_SYSTEMD@
+ZFS_INIT_SYSV = @ZFS_INIT_SYSV@
+ZFS_META_ALIAS = @ZFS_META_ALIAS@
+ZFS_META_AUTHOR = @ZFS_META_AUTHOR@
+ZFS_META_DATA = @ZFS_META_DATA@
+ZFS_META_LICENSE = @ZFS_META_LICENSE@
+ZFS_META_LT_AGE = @ZFS_META_LT_AGE@
+ZFS_META_LT_CURRENT = @ZFS_META_LT_CURRENT@
+ZFS_META_LT_REVISION = @ZFS_META_LT_REVISION@
+ZFS_META_NAME = @ZFS_META_NAME@
+ZFS_META_RELEASE = @ZFS_META_RELEASE@
+ZFS_META_VERSION = @ZFS_META_VERSION@
+ZFS_MODULE_LOAD = @ZFS_MODULE_LOAD@
+ZLIB = @ZLIB@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dracutdir = @dracutdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+modulesloaddir = @modulesloaddir@
+mounthelperdir = @mounthelperdir@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+runstatedir = @runstatedir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+systemdpresetdir = @systemdpresetdir@
+systemdunitdir = @systemdunitdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+udevdir = @udevdir@
+udevruledir = @udevruledir@
+initrddir = $(datarootdir)/initramfs-tools
+initrd_SCRIPTS = conf-hooks.d/zfs hooks/zfs scripts/zfs
+EXTRA_DIST = \
+	$(top_srcdir)/contrib/initramfs/conf-hooks.d/zfs \
+	$(top_srcdir)/contrib/initramfs/hooks/zfs \
+	$(top_srcdir)/contrib/initramfs/scripts/zfs \
+	$(top_srcdir)/contrib/initramfs/README.initramfs.markdown
+
+all: all-am
+
+.SUFFIXES:
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+	        && { if test -f $@; then exit 0; else break; fi; }; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu contrib/initramfs/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --gnu contrib/initramfs/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+	esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+uninstall-initrdSCRIPTS:
+	@$(NORMAL_UNINSTALL)
+	@list='$(initrd_SCRIPTS)'; test -n "$(initrddir)" || exit 0; \
+	files=`for p in $$list; do echo "$$p"; done | \
+	       sed -e 's,.*/,,;$(transform)'`; \
+	dir='$(DESTDIR)$(initrddir)'; $(am__uninstall_files_from_dir)
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
+tags TAGS:
+
+ctags CTAGS:
+
+cscope cscopelist:
+
+
+distdir: $(DISTFILES)
+	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	list='$(DISTFILES)'; \
+	  dist_files=`for file in $$list; do echo $$file; done | \
+	  sed -e "s|^$$srcdirstrip/||;t" \
+	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+	case $$dist_files in \
+	  */*) $(MKDIR_P) `echo "$$dist_files" | \
+			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+			   sort -u` ;; \
+	esac; \
+	for file in $$dist_files; do \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  if test -d $$d/$$file; then \
+	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+	    if test -d "$(distdir)/$$file"; then \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+	  else \
+	    test -f "$(distdir)/$$file" \
+	    || cp -p $$d/$$file "$(distdir)/$$file" \
+	    || exit 1; \
+	  fi; \
+	done
+check-am: all-am
+check: check-am
+all-am: Makefile $(SCRIPTS)
+installdirs:
+	for dir in "$(DESTDIR)$(initrddir)"; do \
+	  test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+	done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+	if test -z '$(STRIP)'; then \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	      install; \
+	else \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+	fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-am
+	-rm -f Makefile
+distclean-am: clean-am distclean-generic
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-initrdSCRIPTS
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-initrdSCRIPTS
+
+.MAKE: install-am install-strip
+
+.PHONY: all all-am check check-am clean clean-generic clean-libtool \
+	cscopelist-am ctags-am distclean distclean-generic \
+	distclean-libtool distdir dvi dvi-am html html-am info info-am \
+	install install-am install-data install-data-am install-dvi \
+	install-dvi-am install-exec install-exec-am install-html \
+	install-html-am install-info install-info-am \
+	install-initrdSCRIPTS install-man install-pdf install-pdf-am \
+	install-ps install-ps-am install-strip installcheck \
+	installcheck-am installdirs maintainer-clean \
+	maintainer-clean-generic mostlyclean mostlyclean-generic \
+	mostlyclean-libtool pdf pdf-am ps ps-am tags-am uninstall \
+	uninstall-am uninstall-initrdSCRIPTS
+
+.PRECIOUS: Makefile
+
+
+install-initrdSCRIPTS: $(EXTRA_DIST)
+	for d in conf-hooks.d hooks scripts; do \
+	  $(MKDIR_P) $(DESTDIR)$(initrddir)/$$d; \
+	  cp $(top_srcdir)/contrib/initramfs/$$d/zfs \
+	    $(DESTDIR)$(initrddir)/$$d/; \
+	done
+	if [ -f etc/init.d/zfs ]; then \
+	  $(MKDIR_P) $(DESTDIR)$(DEFAULT_INITCONF_DIR); \
+	  cp $(top_srcdir)/etc/init.d/zfs \
+	    $(DESTDIR)$(DEFAULT_INITCONF_DIR)/; \
+	fi
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/contrib/initramfs/README.initramfs.markdown
@@ -0,0 +1,94 @@
+DESCRIPTION
+  These scripts is intended to be used with initramfs-tools, which is a similar
+  software product to "dracut" (which is more used in RedHat based distributions,
+  and is mainly used by Debian GNU/Linux and derivates to create a initramfs so
+  that the system can be booted of a ZFS filesystem. If you have no need or
+  interest for this, then it can safely be ignored.
+
+  These script were written with the primary intention of being portable and
+  usable on as many systems as possible.
+
+  This is, in practice, usually not possible. But the intention is there.
+  And it is a good one.
+
+  They have been tested successfully on:
+
+    * Debian GNU/Linux Wheezy
+    * Debian GNU/Linux Jessie
+
+  It uses some functionality common with the SYSV init scripts, primarily
+  the "/etc/zfs/zfs-functions" script.
+
+FUNCTIONALITY
+  * Supports booting of a ZFS snapshot.
+    Do this by cloning the snapshot into a dataset. If this, the resulting
+    dataset, already exists, destroy it. Then mount it as the root filesystem.
+    * If snapshot does not exist, use base dataset (the part before '@')
+      as boot filesystem instead.
+    * Clone with 'mountpoint=none' and 'canmount=noauto' - we mount manually
+      and explicitly.
+    * Allow rollback of snapshots instead of clone it and boot from the clone.
+    * If no snapshot is specified on the 'root=' kernel command line, but
+      there is an '@', then get a list of snapshots below that filesystem
+      and ask the user which to use.
+
+  * Support all currently used kernel command line arguments
+    * Core options:
+      All the different distributions have their own standard on what to specify
+      on the kernel command line to boot of a ZFS filesystem.
+
+      Supports the following kernel command line argument combinations
+      (in this order - first match win):
+      * rpool=<pool>			(tries to finds bootfs automatically)
+      * bootfs=<pool>/<dataset>		(uses this for rpool - first part)
+      * rpool=<pool> bootfs=<pool>/<dataset>
+      * -B zfs-bootfs=<pool>/<fs>	(uses this for rpool - first part)
+      * rpool=rpool			(default if none of the above is used)
+      * root=<pool>/<dataset>		(uses this for rpool - first part)
+      * root=ZFS=<pool>/<dataset>	(uses this for rpool - first part, without 'ZFS=')
+      * root=zfs:AUTO			(tries to detect both pool and rootfs
+      * root=zfs:<pool>/<dataset>	(uses this for rpool - first part, without 'zfs:')
+
+      Option <dataset> could also be <snapshot>
+    * Extra (control) options:
+      * zfsdebug=(on,yes,1)   Show extra debugging information
+      * zfsforce=(on,yes,1)   Force import the pool
+      * rollback=(on,yes,1)   Rollback (instead of clone) the snapshot
+
+  * 'Smarter' way to import pools. Don't just try cache file or /dev.
+    * Try to use /dev/disk/by-vdev (if /etc/zfs/vdev_id.conf exists),
+    * Try /dev/mapper (to be able to use LUKS backed pools as well as
+      multi-path devices).
+    * /dev/disk/by-id and any other /dev/disk/by-* directory that may exist.
+    * Use /dev as a last ditch attempt.
+    * Fallback to using the cache file if that exist if nothing else worked.
+    * Only try to import pool if it haven't already been imported
+      * This will negate the need to force import a pool that have not been
+        exported cleanly.
+      * Support exclusion of pools to import by setting ZFS_POOL_EXCEPTIONS
+         in /etc/default/zfs.
+
+    Controlling in which order devices is searched for is controlled by
+    ZPOOL_IMPORT_PATH variable set in /etc/defaults/zfs.
+
+  * Support additional configuration variable ZFS_INITRD_ADDITIONAL_DATASETS
+    to mount additional filesystems not located under your root dataset.
+
+    For example, if the root fs is specified as 'rpool/ROOT/rootfs', it will
+    automatically and without specific configuration mount any filesystems
+    below this on the mount point specified in the 'mountpoint' property.
+    Such as 'rpool/root/rootfs/var', 'rpool/root/rootfs/usr' etc)
+
+    However, if one prefer to have separate filesystems, not located below
+    the root fs (such as 'rpool/var', 'rpool/ROOT/opt' etc), special
+    configuration needs to be done. This is what the variable, set in
+    /etc/defaults/zfs file, needs to be configured. The 'mountpoint'
+    property needs to be correct for this to work though.
+
+  * Allows mounting a rootfs with mountpoint=legacy set.
+
+  * Include /etc/modprobe.d/{zfs,spl}.conf in the initrd if it/they exist.
+
+  * Include the udev rule to use by-vdev for pool imports.
+
+  * Include the /etc/default/zfs file to the initrd.
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/contrib/initramfs/conf-hooks.d/zfs
@@ -0,0 +1,2 @@
+# Force the inclusion of Busybox in the initramfs.
+BUSYBOX=y
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/contrib/initramfs/hooks/zfs
@@ -0,0 +1,103 @@
+#!/bin/sh
+#
+# Add ZoL filesystem capabilities to an initrd, usually for a native ZFS root.
+#
+
+# This hook installs udev rules for ZoL.
+PREREQ="zdev"
+
+# These prerequisites are provided by the zfsutils package. The zdb utility is
+# not strictly required, but it can be useful at the initramfs recovery prompt.
+COPY_EXEC_LIST="/sbin/zdb /sbin/zpool /sbin/zfs /sbin/mount.zfs"
+COPY_EXEC_LIST="$COPY_EXEC_LIST /usr/bin/dirname /lib/udev/vdev_id"
+COPY_FILE_LIST="/etc/hostid /etc/zfs/zpool.cache /etc/default/zfs"
+COPY_FILE_LIST="$COPY_FILE_LIST /etc/zfs/zfs-functions /etc/zfs/vdev_id.conf"
+COPY_FILE_LIST="$COPY_FILE_LIST /lib/udev/rules.d/69-vdev.rules"
+
+# These prerequisites are provided by the base system.
+COPY_EXEC_LIST="$COPY_EXEC_LIST /bin/hostname /sbin/blkid"
+
+# Explicitly specify all kernel modules because automatic dependency resolution
+# is unreliable on many systems.
+BASE_MODULES="zlib_deflate spl zavl zcommon znvpair zunicode zfs"
+CRPT_MODULES="sun-ccm sun-gcm sun-ctr"
+MANUAL_ADD_MODULES_LIST="$BASE_MODULES"
+
+# Generic result code.
+RC=0
+
+case $1 in
+prereqs)
+	echo "$PREREQ"
+	exit 0
+	;;
+esac
+
+for ii in $COPY_EXEC_LIST
+do
+	if [ ! -x "$ii" ]
+	then
+		echo "Error: $ii is not executable."
+		RC=2
+	fi
+done
+
+if [ "$RC" -ne 0 ]
+then
+	exit "$RC"
+fi
+
+. /usr/share/initramfs-tools/hook-functions
+
+mkdir -p "$DESTDIR/etc/"
+
+# ZDB uses pthreads for some functions, but the library dependency is not
+# automatically detected. The `find` utility and extended `cp` options are
+# used here because libgcc_s.so could be in a subdirectory of /lib for
+# multi-arch installations.
+cp --target-directory="$DESTDIR" --parents $(find /lib -type f -name libgcc_s.so.1)
+
+for ii in $COPY_EXEC_LIST
+do
+	copy_exec "$ii"
+done
+
+for ii in $COPY_FILE_LIST
+do
+	dir=$(dirname "$ii")
+	[ -d "$dir" ] && mkdir -p "$DESTDIR/$dir"
+	[ -f "$ii" ] && cp -p "$ii" "$DESTDIR/$ii"
+done
+
+for ii in $MANUAL_ADD_MODULES_LIST
+do
+	manual_add_modules "$ii"
+done
+
+if [ -f "/etc/hostname" ]
+then
+	cp -p "/etc/hostname" "$DESTDIR/etc/"
+else
+	hostname >"$DESTDIR/etc/hostname"
+fi
+
+for ii in zfs zfs.conf spl spl.conf
+do  
+	if [ -f "/etc/modprobe.d/$ii" ]; then
+		if [ ! -d "$DESTDIR/etc/modprobe.d" ]; then
+			mkdir -p $DESTDIR/etc/modprobe.d
+		fi
+		cp -p "/etc/modprobe.d/$ii" $DESTDIR/etc/modprobe.d/
+	fi
+done
+
+# With pull request #1476 (not yet merged) comes a verbose warning
+# if /usr/bin/net doesn't exist or isn't executable. Just create
+# a dummy...
+[ ! -d "$DESTDIR/usr/bin" ] && mkdir -p "$DESTDIR/usr/bin"
+if [ ! -x "$DESTDIR/usr/bin/net" ]; then
+    touch "$DESTDIR/usr/bin/net"
+    chmod +x "$DESTDIR/usr/bin/net"
+fi
+
+exit 0
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/contrib/initramfs/scripts/zfs
@@ -0,0 +1,971 @@
+# ZFS boot stub for initramfs-tools.
+#
+# In the initramfs environment, the /init script sources this stub to
+# override the default functions in the /scripts/local script.
+#
+# Enable this by passing boot=zfs on the kernel command line.
+#
+
+# Source the common init script
+. /etc/zfs/zfs-functions
+
+# Paths to what we need - in the initrd, these paths are hardcoded,
+# so override the defines in zfs-functions.
+ZFS="/sbin/zfs"
+ZPOOL="/sbin/zpool"
+ZPOOL_CACHE="/etc/zfs/zpool.cache"
+export ZFS ZPOOL ZPOOL_CACHE
+
+# This runs any scripts that should run before we start importing
+# pools and mounting any filesystems.
+pre_mountroot()
+{
+	if type run_scripts > /dev/null 2>&1 && \
+	    [ -f "/scripts/local-top" -o -d "/scripts/local-top" ]
+	then
+		[ "$quiet" != "y" ] && \
+		    zfs_log_begin_msg "Running /scripts/local-top"
+		run_scripts /scripts/local-top
+		[ "$quiet" != "y" ] && zfs_log_end_msg
+	fi
+
+	if type run_scripts > /dev/null 2>&1 && \
+	    [ -f "/scripts/local-premount" -o -d "/scripts/local-premount" ]
+	then
+		[ "$quiet" != "y" ] && \
+		    zfs_log_begin_msg "Running /scripts/local-premount"
+		run_scripts /scripts/local-premount
+		[ "$quiet" != "y" ] && zfs_log_end_msg
+	fi
+}
+
+# If plymouth is availible, hide the splash image.
+disable_plymouth()
+{
+	if [ -x /bin/plymouth ] && /bin/plymouth --ping
+	then
+		/bin/plymouth hide-splash >/dev/null 2>&1
+	fi
+}
+
+# Get a ZFS filesystem property value.
+get_fs_value()
+{
+	local fs="$1"
+	local value=$2
+
+	"${ZFS}" get -H -ovalue $value "$fs" 2> /dev/null
+}
+
+# Find the 'bootfs' property on pool $1.
+# If the property does not contain '/', then ignore this
+# pool by exporting it again.
+find_rootfs()
+{
+	local pool="$1"
+
+	# If 'POOL_IMPORTED' isn't set, no pool imported and therefor
+	# we won't be able to find a root fs.
+	[ -z "${POOL_IMPORTED}" ] && return 1
+
+	# If it's already specified, just keep it mounted and exit
+	# User (kernel command line) must be correct.
+	[ -n "${ZFS_BOOTFS}" ] && return 0
+
+	# Not set, try to find it in the 'bootfs' property of the pool.
+	# NOTE: zpool does not support 'get -H -ovalue bootfs'...
+	ZFS_BOOTFS=$("${ZPOOL}" list -H -obootfs "$pool")
+
+	# Make sure it's not '-' and that it starts with /.
+	if [ "${ZFS_BOOTFS}" != "-" ] && \
+		$(get_fs_value "${ZFS_BOOTFS}" mountpoint | grep -q '^/$')
+	then
+		# Keep it mounted
+		POOL_IMPORTED=1
+		return 0
+	fi
+
+	# Not boot fs here, export it and later try again..
+	"${ZPOOL}" export "$pool"
+	POOL_IMPORTED=""
+
+	return 1
+}
+
+# Support function to get a list of all pools, separated with ';'
+find_pools()
+{
+	local CMD="$*"
+	local pools pool
+
+	pools=$($CMD 2> /dev/null | \
+		grep -E "pool:|^[a-zA-Z0-9]" | \
+		sed 's@.*: @@' | \
+		while read pool; do \
+		    echo -n "$pool;"
+		done)
+
+	echo "${pools%%;}" # Return without the last ';'.
+}
+
+# Get a list of all availible pools
+get_pools()
+{
+	local available_pools npools
+
+	if [ -n "${ZFS_POOL_IMPORT}" ]; then
+		echo "$ZFS_POOL_IMPORT"
+		return 0
+	fi
+
+	# Get the base list of availible pools.
+	available_pools=$(find_pools "$ZPOOL" import)
+
+	# Just in case - seen it happen (that a pool isn't visable/found
+	# with a simple "zpool import" but only when using the "-d"
+	# option or setting ZPOOL_IMPORT_PATH).
+	if [ -d "/dev/disk/by-id" ]
+	then
+		npools=$(find_pools "$ZPOOL" import -d /dev/disk/by-id)
+		if [ -n "$npools" ]
+		then
+			# Because we have found extra pool(s) here, which wasn't
+			# found 'normaly', we need to force USE_DISK_BY_ID to
+			# make sure we're able to actually import it/them later.
+			USE_DISK_BY_ID='yes'
+
+			if [ -n "$available_pools" ]
+			then
+				# Filter out duplicates (pools found with the simple
+				# "zpool import" but which is also found with the
+				# "zpool import -d ...").
+				npools=$(echo "$npools" | sed "s,$available_pools,,")
+
+				# Add the list to the existing list of
+				# available pools
+				available_pools="$available_pools;$npools"
+			else
+				available_pools="$npools"
+			fi
+		fi
+	fi
+
+        # Filter out any exceptions...
+	if [ -n "$ZFS_POOL_EXCEPTIONS" ]
+	then
+		local found=""
+		local apools=""
+		local pool exception
+		OLD_IFS="$IFS" ; IFS=";"
+
+		for pool in $available_pools
+		do
+			for exception in $ZFS_POOL_EXCEPTIONS
+			do
+				[ "$pool" = "$exception" ] && continue 2
+				found="$pool"
+			done
+
+			if [ -n "$found" ]
+			then
+				if [ -n "$apools" ]
+				then
+					apools="$apools;$pool"
+				else
+					apools="$pool"
+				fi
+			fi
+		done
+
+		IFS="$OLD_IFS"
+		available_pools="$apools"
+	fi
+
+	# Return list of availible pools.
+	echo "$available_pools"
+}
+
+# Import given pool $1
+import_pool()
+{
+	local pool="$1"
+	local dirs dir
+
+	# Verify that the pool isn't already imported
+	# Make as sure as we can to not require '-f' to import.
+	"${ZPOOL}" status "$pool" > /dev/null 2>&1 && return 0
+
+	# For backwards compability, make sure that ZPOOL_IMPORT_PATH is set
+	# to something we can use later with the real import(s). We want to
+	# make sure we find all by* dirs, BUT by-vdev should be first (if it
+	# exists).
+	if [ -n "$USE_DISK_BY_ID" -a -z "$ZPOOL_IMPORT_PATH" ]
+	then
+		dirs="$(for dir in $(echo /dev/disk/by-*)
+		do
+			# Ignore by-vdev here - we want it first!
+			echo "$dir" | grep -q /by-vdev && continue
+			[ ! -d "$dir" ] && continue
+
+			echo -n "$dir:"
+		done | sed 's,:$,,g')"
+
+		if [ -d "/dev/disk/by-vdev" ]
+		then
+			# Add by-vdev at the beginning.
+			ZPOOL_IMPORT_PATH="/dev/disk/by-vdev:"
+		fi
+
+		# ... and /dev at the very end, just for good measure.
+		ZPOOL_IMPORT_PATH="$ZPOOL_IMPORT_PATH$dirs:/dev"
+	fi
+
+	# Needs to be exported for "zpool" to catch it.
+	[ -n "$ZPOOL_IMPORT_PATH" ] && export ZPOOL_IMPORT_PATH
+
+
+	[ "$quiet" != "y" ] && zfs_log_begin_msg \
+		"Importing pool '${pool}' using defaults"
+
+	ZFS_CMD="${ZPOOL} import -N ${ZPOOL_FORCE} ${ZPOOL_IMPORT_OPTS}"
+	ZFS_STDERR="$($ZFS_CMD "$pool" 2>&1)"
+	ZFS_ERROR="$?"
+	if [ "${ZFS_ERROR}" != 0 ]
+	then
+		[ "$quiet" != "y" ] && zfs_log_failure_msg "${ZFS_ERROR}"
+
+		if [ -f "${ZPOOL_CACHE}" ]
+		then
+			[ "$quiet" != "y" ] && zfs_log_begin_msg \
+				"Importing pool '${pool}' using cachefile."
+
+			ZFS_CMD="${ZPOOL} import -c ${ZPOOL_CACHE} -N ${ZPOOL_FORCE} ${ZPOOL_IMPORT_OPTS}"
+			ZFS_STDERR="$($ZFS_CMD "$pool" 2>&1)"
+			ZFS_ERROR="$?"
+		fi
+
+		if [ "${ZFS_ERROR}" != 0 ]
+		then
+			[ "$quiet" != "y" ] && zfs_log_failure_msg "${ZFS_ERROR}"
+
+			disable_plymouth
+			echo ""
+			echo "Command: ${ZFS_CMD} '$pool'"
+			echo "Message: $ZFS_STDERR"
+			echo "Error: $ZFS_ERROR"
+			echo ""
+			echo "Failed to import pool '$pool'."
+			echo "Manually import the pool and exit."
+			/bin/sh
+		fi
+	fi
+
+	[ "$quiet" != "y" ] && zfs_log_end_msg
+
+	POOL_IMPORTED=1
+	return 0
+}
+
+# Load ZFS modules
+# Loading a module in a initrd require a slightly different approach,
+# with more logging etc.
+load_module_initrd()
+{
+	if [ "$ZFS_INITRD_PRE_MOUNTROOT_SLEEP" > 0 ]
+	then
+		if [ "$quiet" != "y" ]; then
+			zfs_log_begin_msg "Sleeping for" \
+				"$ZFS_INITRD_PRE_MOUNTROOT_SLEEP seconds..."
+		fi
+		sleep "$ZFS_INITRD_PRE_MOUNTROOT_SLEEP"
+		[ "$quiet" != "y" ] && zfs_log_end_msg
+	fi
+
+	# Wait for all of the /dev/{hd,sd}[a-z] device nodes to appear.
+	if type wait_for_udev > /dev/null 2>&1 ; then
+		wait_for_udev 10
+	elif type wait_for_dev > /dev/null 2>&1 ; then
+		wait_for_dev
+	fi
+
+	# zpool import refuse to import without a valid mtab
+	[ ! -f /proc/mounts ] && mount proc /proc
+	[ ! -f /etc/mtab ] && cat /proc/mounts > /etc/mtab
+
+	# Load the module
+	load_module "zfs" || return 1
+
+	if [ "$ZFS_INITRD_POST_MODPROBE_SLEEP" > 0 ]
+	then
+		if [ "$quiet" != "y" ]; then
+			zfs_log_begin_msg "Sleeping for" \
+				"$ZFS_INITRD_POST_MODPROBE_SLEEP seconds..."
+		fi
+		sleep "$ZFS_INITRD_POST_MODPROBE_SLEEP"
+		[ "$quiet" != "y" ] && zfs_log_end_msg
+	fi
+
+	return 0
+}
+
+# Mount a given filesystem
+mount_fs()
+{
+	local fs="$1"
+	local mountpoint
+
+	# Check that the filesystem exists
+	"${ZFS}" list -oname -tfilesystem -H "${fs}" > /dev/null 2>&1
+	[ "$?" -ne 0 ] && return 1
+
+	# Need the _original_ datasets mountpoint!
+	mountpoint=$(get_fs_value "$fs" mountpoint)
+	if [ "$mountpoint" = "legacy" -o "$mountpoint" = "none" ]; then
+		# Can't use the mountpoint property. Might be one of our
+		# clones. Check the 'org.zol:mountpoint' property set in
+		# clone_snap() if that's usable.
+		mountpoint=$(get_fs_value "$fs" org.zol:mountpoint)
+		if [ "$mountpoint" = "legacy" -o \
+		    "$mountpoint" = "none" -o \
+		    "$mountpoint" = "-" ]
+		then
+			if [ "$fs" != "${ZFS_BOOTFS}" ]; then
+				# We don't have a proper mountpoint, this
+				# isn't the root fs. So extract the root fs
+				# value from the filesystem, and we should
+				# (hopefully!) have a mountpoint we can use.
+				mountpoint="${fs##$ZFS_BOOTFS}"
+			else
+				# Last hail-mary: Hope 'rootmnt' is set!
+				mountpoint=""
+			fi
+		fi
+
+		if [ "$mountpoint" = "legacy" ]; then
+			ZFS_CMD="mount -t zfs"
+		else
+			# If it's not a legacy filesystem, it can only be a
+			# native one...
+			ZFS_CMD="mount -o zfsutil -t zfs"
+		fi
+	else
+		ZFS_CMD="mount -o zfsutil -t zfs"
+	fi
+
+	# Possibly decrypt a filesystem using native encryption.
+	decrypt_fs "$fs"
+
+	[ "$quiet" != "y" ] && \
+	    zfs_log_begin_msg "Mounting '${fs}' on '${rootmnt}/${mountpoint}'"
+	[ -n "${ZFS_DEBUG}" ] && \
+	    zfs_log_begin_msg "CMD: '$ZFS_CMD ${fs} ${rootmnt}/${mountpoint}'"
+
+	ZFS_STDERR=$(${ZFS_CMD} "${fs}" "${rootmnt}/${mountpoint}" 2>&1)
+	ZFS_ERROR=$?
+	if [ "${ZFS_ERROR}" != 0 ]
+	then
+		[ "$quiet" != "y" ] && zfs_log_failure_msg "${ZFS_ERROR}"
+
+		disable_plymouth
+		echo ""
+		echo "Command: ${ZFS_CMD} ${fs} ${rootmnt}/${mountpoint}"
+		echo "Message: $ZFS_STDERR"
+		echo "Error: $ZFS_ERROR"
+		echo ""
+		echo "Failed to mount ${fs} on ${rootmnt}/${mountpoint}."
+		echo "Manually mount the filesystem and exit."
+		/bin/sh
+	else
+		[ "$quiet" != "y" ] && zfs_log_end_msg
+	fi
+
+	return 0
+}
+
+# Unlock a ZFS native crypted filesystem.
+decrypt_fs()
+{
+	local fs="$1"
+
+	# If the 'zfs key' command isn't availible, exit right here.
+	"${ZFS}" 2>&1 | grep -q 'key -l ' || return 0
+
+	# Check if filesystem is encrypted. If not, exit right here.
+	[ "$(get_fs_value "$fs" encryption)" != "off" ] || return 0
+
+	[ "$quiet" != "y" ] && \
+	    zfs_log_begin_msg "Loading crypto wrapper key for $fs"
+
+	# Just make sure that ALL crypto modules module is loaded.
+	# Simplest just to load all...
+	for mod in sun-ccm sun-gcm sun-ctr
+	do
+		[ "$quiet" != "y" ] && zfs_log_progress_msg "${mod} "
+
+		ZFS_CMD="load_module $mod"
+		ZFS_STDERR="$(${ZFS_CMD} 2>&1)"
+		ZFS_ERROR="$?"
+
+		if [ "${ZFS_ERROR}" != 0 ]
+		then
+			[ "$quiet" != "y" ] && zfs_log_failure_msg "${ZFS_ERROR}"
+
+			disable_plymouth
+			echo ""
+			echo "Command: $ZFS_CMD"
+			echo "Message: $ZFS_STDERR"
+			echo "Error: $ZFS_ERROR"
+			echo ""
+			echo "Failed to load $mod module."
+			echo "Please verify that it is availible on the initrd image"
+			echo "(without it it won't be possible to unlock the filesystem)"
+			echo "and rerun:  $ZFS_CMD"
+			/bin/sh
+		else
+			[ "$quiet" != "y" ] && zfs_log_end_msg
+		fi
+	done
+
+	# If the key isn't availible, then this will fail!
+	ZFS_CMD="${ZFS} key -l -r $fs"
+	ZFS_STDERR="$(${ZFS_CMD} 2>&1)"
+	ZFS_ERROR="$?"
+
+	if [ "${ZFS_ERROR}" != 0 ]
+	then
+		[ "$quiet" != "y" ] && zfs_log_failure_msg "${ZFS_ERROR}"
+
+		disable_plymouth
+		echo ""
+		echo "Command: $ZFS_CMD"
+		echo "Message: $ZFS_STDERR"
+		echo "Error: $ZFS_ERROR"
+		echo ""
+		echo "Failed to load zfs encryption wrapper key (s)."
+		echo "Please verify dataset property 'keysource' for datasets"
+		echo "and rerun:  $ZFS_CMD"
+		/bin/sh
+	else
+		[ "$quiet" != "y" ] && zfs_log_end_msg
+	fi
+
+	return 0
+}
+
+# Destroy a given filesystem.
+destroy_fs()
+{
+	local fs="$1"
+
+	[ "$quiet" != "y" ] && \
+	    zfs_log_begin_msg "Destroying '$fs'"
+
+	ZFS_CMD="${ZFS} destroy $fs"
+	ZFS_STDERR="$(${ZFS_CMD} 2>&1)"
+	ZFS_ERROR="$?"
+	if [ "${ZFS_ERROR}" != 0 ]
+	then
+		[ "$quiet" != "y" ] && zfs_log_failure_msg "${ZFS_ERROR}"
+
+		disable_plymouth
+		echo ""
+		echo "Command: $ZFS_CMD"
+		echo "Message: $ZFS_STDERR"
+		echo "Error: $ZFS_ERROR"
+		echo ""
+		echo "Failed to destroy '$fs'. Please make sure that '$fs' is not availible."
+		echo "Hint: Try:  zfs destroy -Rfn $fs"
+		echo "If this dryrun looks good, then remove the 'n' from '-Rfn' and try again."
+		/bin/sh
+	else
+		[ "$quiet" != "y" ] && zfs_log_end_msg
+	fi
+
+	return 0
+}
+
+# Clone snapshot $1 to destination filesystem $2
+# Set 'canmount=noauto' and 'mountpoint=none' so that we get to keep
+# manual controll over it's mounting (i.e., make sure it's not automatically
+# mounted with a 'zfs mount -a' in the init/systemd scripts).
+clone_snap()
+{
+	local snap="$1"
+	local destfs="$2"
+	local mountpoint="$3"
+
+	[ "$quiet" != "y" ] && zfs_log_begin_msg "Cloning '$snap' to '$destfs'"
+
+	# Clone the snapshot into a dataset we can boot from
+	# + We don't want this filesystem to be automatically mounted, we
+	#   want controll over this here and nowhere else.
+	# + We don't need any mountpoint set for the same reason.
+	# We use the 'org.zol:mountpoint' property to remember the mountpoint.
+	ZFS_CMD="${ZFS} clone -o canmount=noauto -o mountpoint=none"
+	ZFS_CMD="${ZFS_CMD} -o org.zol:mountpoint=${mountpoint}"
+	ZFS_CMD="${ZFS_CMD} $snap $destfs"
+	ZFS_STDERR="$(${ZFS_CMD} 2>&1)"
+	ZFS_ERROR="$?"
+	if [ "${ZFS_ERROR}" != 0 ]
+	then
+		[ "$quiet" != "y" ] && zfs_log_failure_msg "${ZFS_ERROR}"
+
+		disable_plymouth
+		echo ""
+		echo "Command: $ZFS_CMD"
+		echo "Message: $ZFS_STDERR"
+		echo "Error: $ZFS_ERROR"
+		echo ""
+		echo "Failed to clone snapshot."
+		echo "Make sure that the any problems are corrected and then make sure"
+		echo "that the dataset '$destfs' exists and is bootable."
+		/bin/sh
+	else
+		[ "$quiet" != "y" ] && zfs_log_end_msg
+	fi
+
+	return 0
+}
+
+# Rollback a given snapshot.
+rollback_snap()
+{
+	local snap="$1"
+
+	[ "$quiet" != "y" ] && zfs_log_begin_msg "Rollback $snap"
+
+	ZFS_CMD="${ZFS} rollback -Rf $snap"
+	ZFS_STDERR="$(${ZFS_CMD} 2>&1)"
+	ZFS_ERROR="$?"
+	if [ "${ZFS_ERROR}" != 0 ]
+	then
+		[ "$quiet" != "y" ] && zfs_log_failure_msg "${ZFS_ERROR}"
+
+		disable_plymouth
+		echo ""
+		echo "Command: $ZFS_CMD"
+		echo "Message: $ZFS_STDERR"
+		echo "Error: $ZFS_ERROR"
+		echo ""
+		echo "Failed to rollback snapshot."
+		/bin/sh
+	else
+		[ "$quiet" != "y" ] && zfs_log_end_msg
+	fi
+
+	return 0
+}
+
+# Get a list of snapshots, give them as a numbered list
+# to the user to choose from.
+ask_user_snap()
+{
+	local fs="$1"
+	local i=1
+	local SNAP snapnr snap debug
+
+	# We need to temporarily disable debugging. Set 'debug' so we
+	# remember to enabled it again.
+	if [ -n "${ZFS_DEBUG}" ]; then
+		unset ZFS_DEBUG
+		set +x
+		debug=1
+	fi
+
+	# Because we need the resulting snapshot, which is sent on
+	# stdout to the caller, we use stderr for our questions.
+	echo "What snapshot do you want to boot from?" > /dev/stderr
+	while read snap; do
+	    echo "  $i: ${snap}" > /dev/stderr
+	    eval `echo SNAP_$i=$snap`
+	    i=$((i + 1))
+	done <<EOT
+$("${ZFS}" list -H -oname -tsnapshot "${fs}")
+EOT
+
+	echo -n "  Snap nr [0-$((i-1))]? " > /dev/stderr
+	read snapnr
+
+	# Reenable debugging.
+	if [ -n "${debug}" ]; then
+		ZFS_DEBUG=1
+		set -x
+	fi
+
+	echo "$(eval echo "$"SNAP_$snapnr)"
+}
+
+setup_snapshot_booting()
+{
+	local snap="$1"
+	local s destfs subfs mountpoint retval=0 filesystems fs
+
+	# Make sure that the snapshot specified actually exist.
+	if [ ! $(get_fs_value "${snap}" type) ]
+	then
+		# Snapshot does not exist (...@<null> ?)
+		# ask the user for a snapshot to use.
+		snap="$(ask_user_snap "${snap%%@*}")"
+	fi
+
+	# Separate the full snapshot ('$snap') into it's filesystem and
+	# snapshot names. Would have been nice with a split() function..
+	rootfs="${snap%%@*}"
+	snapname="${snap##*@}"	
+	ZFS_BOOTFS="${rootfs}_${snapname}"
+
+	if ! grep -qiE '(^|[^\\](\\\\)* )(rollback)=(on|yes|1)( |$)' /proc/cmdline
+	then
+		# If the destination dataset for the clone
+		# already exists, destroy it. Recursivly
+		if [ $(get_fs_value "${rootfs}_${snapname}" type) ]; then
+			filesystems=$("${ZFS}" list -oname -tfilesystem -H \
+			    -r -Sname "${ZFS_BOOTFS}")
+			for fs in $filesystems; do
+				destroy_fs "${fs}"
+			done
+		fi
+	fi
+
+	# Get all snapshots, recursivly (might need to clone /usr, /var etc
+	# as well).
+	for s in $("${ZFS}" list -H -oname -tsnapshot -r "${rootfs}" | \
+	    grep "${snapname}")
+	do
+		if grep -qiE '(^|[^\\](\\\\)* )(rollback)=(on|yes|1)( |$)' /proc/cmdline
+		then
+			# Rollback snapshot
+			rollback_snap "$s" || retval=$((retval + 1))
+		else
+			# Setup a destination filesystem name.
+			# Ex: Called with 'rpool/ROOT/debian@snap2'
+			#       rpool/ROOT/debian@snap2		=> rpool/ROOT/debian_snap2
+			#       rpool/ROOT/debian/boot@snap2	=> rpool/ROOT/debian_snap2/boot
+			#       rpool/ROOT/debian/usr@snap2	=> rpool/ROOT/debian_snap2/usr
+			#       rpool/ROOT/debian/var@snap2	=> rpool/ROOT/debian_snap2/var
+			subfs="${s##$rootfs}"
+			subfs="${subfs%%@$snapname}"
+
+			destfs="${rootfs}_${snapname}" # base fs.
+			[ -n "$subfs" ] && destfs="${destfs}$subfs" # + sub fs.
+
+			# Get the mountpoint of the filesystem, to be used
+			# with clone_snap(). If legacy or none, then use
+			# the sub fs value.
+			mountpoint=$(get_fs_value "${s%%@*}" mountpoint)
+			if [ "$mountpoint" = "legacy" -o \
+			    "$mountpoint" = "none" ]
+			then
+				if [ -n "${subfs}" ]; then
+					mountpoint="${subfs}"
+				else
+					mountpoint="/"
+				fi
+			fi
+
+			# Clone the snapshot into its own
+			# filesystem
+			clone_snap "$s" "${destfs}" "${mountpoint}" || \
+			    retval=$((retval + 1))
+		fi
+	done
+
+	# If we haven't return yet, we have a problem...
+	return "${retval}"
+}
+
+# ================================================================
+
+# This is the main function.
+mountroot()
+{
+	local snaporig snapsub destfs pool POOLS
+
+	# ----------------------------------------------------------------
+	# I N I T I A L   S E T U P
+
+	# ------------
+	# Run the pre-mount scripts from /scripts/local-top.
+	pre_mountroot
+
+	# ------------
+	# Source the default setup variables.
+	[ -r '/etc/default/zfs' ] && . /etc/default/zfs
+
+	# ------------
+	# Support debug option
+	if grep -qiE '(^|[^\\](\\\\)* )(zfs_debug|zfs\.debug|zfsdebug)=(on|yes|1)( |$)' /proc/cmdline
+	then
+		ZFS_DEBUG=1
+		mkdir /var/log
+		#exec 2> /var/log/boot.debug
+		set -x
+	fi
+
+	# ------------
+	# Load ZFS module etc.
+	if ! load_module_initrd; then
+		disable_plymouth
+		echo ""
+		echo "Failed to load ZFS modules."
+		echo "Manually load the modules and exit."
+		/bin/sh
+	fi
+
+	# ------------
+	# Look for the cache file (if any).
+	[ ! -f ${ZPOOL_CACHE} ] && unset ZPOOL_CACHE
+
+	# ------------
+	# Compatibility: 'ROOT' is for Debian GNU/Linux (etc),
+	#		 'root' is for Redhat/Fedora (etc),
+	#		 'REAL_ROOT' is for Gentoo
+	if [ -z "$ROOT" ]
+	then
+		[ -n "$root" ] && ROOT=${root}
+
+		[ -n "$REAL_ROOT" ] && ROOT=${REAL_ROOT}
+	fi
+
+	# ------------
+	# Where to mount the root fs in the initrd - set outside this script
+	# Compatibility: 'rootmnt' is for Debian GNU/Linux (etc),
+	#		 'NEWROOT' is for RedHat/Fedora (etc),
+	#		 'NEW_ROOT' is for Gentoo
+	if [ -z "$rootmnt" ]
+	then
+		[ -n "$NEWROOT" ] && rootmnt=${NEWROOT}
+
+		[ -n "$NEW_ROOT" ] && rootmnt=${NEW_ROOT}
+	fi
+
+	# ------------
+	# No longer set in the defaults file, but it could have been set in
+	# get_pools() in some circumstances. If it's something, but not 'yes',
+	# it's no good to us.
+	[ -n "$USE_DISK_BY_ID" -a "$USE_DISK_BY_ID" != 'yes' ] && \
+	    unset USE_DISK_BY_ID
+
+	# ----------------------------------------------------------------
+	# P A R S E   C O M M A N D   L I N E   O P T I O N S
+
+	# This part is the really ugly part - there's so many options and permutations
+	# 'out there', and if we should make this the 'primary' source for ZFS initrd
+	# scripting, we need/should support them all.
+	#
+	# Supports the following kernel command line argument combinations
+	# (in this order - first match win):
+	#
+	#	rpool=<pool>			(tries to finds bootfs automatically)
+	#	bootfs=<pool>/<dataset>		(uses this for rpool - first part)
+	#	rpool=<pool> bootfs=<pool>/<dataset>
+	#	-B zfs-bootfs=<pool>/<fs>	(uses this for rpool - first part)
+	#	rpool=rpool			(default if none of the above is used)
+	#	root=<pool>/<dataset>		(uses this for rpool - first part)
+	#	root=ZFS=<pool>/<dataset>	(uses this for rpool - first part, without 'ZFS=')
+	#	root=zfs:AUTO			(tries to detect both pool and rootfs
+	#	root=zfs:<pool>/<dataset>	(uses this for rpool - first part, without 'zfs:')
+	#
+	# Option <dataset> could also be <snapshot>
+
+	# ------------
+	# Support force option
+	# In addition, setting one of zfs_force, zfs.force or zfsforce to
+	# 'yes', 'on' or '1' will make sure we force import the pool.
+	# This should (almost) never be needed, but it's here for
+	# completeness.
+	ZPOOL_FORCE=""
+	if grep -qiE '(^|[^\\](\\\\)* )(zfs_force|zfs\.force|zfsforce)=(on|yes|1)( |$)' /proc/cmdline
+	then
+		ZPOOL_FORCE="-f"
+	fi
+
+	# ------------
+	# Look for 'rpool' and 'bootfs' parameter
+	[ -n "$rpool" ] && ZFS_RPOOL="${rpool#rpool=}"
+	[ -n "$bootfs" ] && ZFS_BOOTFS="${bootfs#bootfs=}"
+
+	# ------------
+	# If we have 'ROOT' (see above), but not 'ZFS_BOOTFS', then use
+	# 'ROOT'
+	[ -n "$ROOT" -a -z "${ZFS_BOOTFS}" ] && ZFS_BOOTFS="$ROOT"
+
+	# ------------
+	# Check for the `-B zfs-bootfs=%s/%u,...` kind of parameter.
+	# NOTE: Only use the pool name and dataset. The rest is not
+	#       supported by ZoL (whatever it's for).
+	if [ -z "$ZFS_RPOOL" ]
+	then
+		# The ${zfs-bootfs} variable is set at the kernel commmand
+		# line, usually by GRUB, but it cannot be referenced here
+		# directly because bourne variable names cannot contain a
+		# hyphen.
+		#
+		# Reassign the variable by dumping the environment and
+		# stripping the zfs-bootfs= prefix.  Let the shell handle
+		# quoting through the eval command.
+		eval ZFS_RPOOL=$(set | sed -n -e 's,^zfs-bootfs=,,p')
+	fi
+
+	# ------------
+	# No root fs or pool specified - do auto detect.
+	if [ -z "$ZFS_RPOOL" -a -z "${ZFS_BOOTFS}" ]
+	then
+		# Do auto detect. Do this by 'cheating' - set 'root=zfs:AUTO'
+		# which will be caught later
+		ROOT=zfs:AUTO
+	fi
+
+	# ----------------------------------------------------------------
+	# F I N D   A N D   I M P O R T   C O R R E C T   P O O L
+
+	# ------------
+	if [ "$ROOT" = "zfs:AUTO" ]
+	then
+		# Try to detect both pool and root fs.
+
+		[ "$quiet" != "y" ] && \
+		    zfs_log_begin_msg "Attempting to import additional pools."
+
+		# Get a list of pools available for import
+		if [ -n "$ZFS_RPOOL" ]
+		then
+			# We've specified a pool - check only that
+			POOLS=$ZFS_RPOOL
+		else
+			POOLS=$(get_pools)
+		fi
+
+		OLD_IFS="$IFS" ; IFS=";"
+		for pool in $POOLS
+		do
+			[ -z "$pool" ] && continue
+
+			import_pool "$pool"
+			find_rootfs "$pool"
+		done
+		IFS="$OLD_IFS"
+
+		[ "$quiet" != "y" ] && zfs_log_end_msg $ZFS_ERROR
+	else
+		# No auto - use value from the command line option.
+
+		# Strip 'zfs:' and 'ZFS='.
+		ZFS_BOOTFS="${ROOT#*[:=]}"
+
+		# Stip everything after the first slash.
+		ZFS_RPOOL="${ZFS_BOOTFS%%/*}"
+	fi
+
+	# Import the pool (if not already done so in the AUTO check above).
+	if [ -n "$ZFS_RPOOL" -a -z "${POOL_IMPORTED}" ]
+	then
+		[ "$quiet" != "y" ] && \
+		    zfs_log_begin_msg "Importing ZFS root pool '$ZFS_RPOOL'"
+
+		import_pool "${ZFS_RPOOL}"
+		find_rootfs "${ZFS_RPOOL}"
+
+		[ "$quiet" != "y" ] && zfs_log_end_msg
+	fi
+
+	if [ -z "${POOL_IMPORTED}" ]
+	then
+		# No pool imported, this is serious!
+		disable_plymouth
+		echo ""
+		echo "Command: $ZFS_CMD"
+		echo "Message: $ZFS_STDERR"
+		echo "Error: $ZFS_ERROR"
+		echo ""
+		echo "No pool imported. Manually import the root pool"
+		echo "at the command prompt and then exit."
+		echo "Hint: Try:  zpool import -R ${rootmnt} -N ${ZFS_RPOOL}"
+		/bin/sh
+	fi
+
+	# ----------------------------------------------------------------
+	# P R E P A R E   R O O T   F I L E S Y S T E M
+
+	if [ -n "${ZFS_BOOTFS}" ]
+	then
+		# Booting from a snapshot?
+		# Will overwrite the ZFS_BOOTFS variable like so:
+		#   rpool/ROOT/debian@snap2 => rpool/ROOT/debian_snap2
+		echo "${ZFS_BOOTFS}" | grep -q '@' && \
+		    setup_snapshot_booting "${ZFS_BOOTFS}"
+	fi
+
+	if [ -z "${ZFS_BOOTFS}" ]
+	then
+		# Still nothing! Let the user sort this out.
+		disable_plymouth
+		echo ""
+		echo "Error: Unknown root filesystem - no 'bootfs' pool property and"
+		echo "       not specified on the kernel command line."
+		echo ""
+		echo "Manually mount the root filesystem on $rootmnt and then exit."
+		echo "Hint: Try:  mount -o zfsutil -t zfs ${ZFS_RPOOL-rpool}/ROOT/system $rootmnt"
+		/bin/sh
+	fi
+
+	# ----------------------------------------------------------------
+	# M O U N T   F I L E S Y S T E M S
+
+	# * Ideally, the root filesystem would be mounted like this:
+	#
+	#     zpool import -R "$rootmnt" -N "$ZFS_RPOOL"
+	#     zfs mount -o mountpoint=/ "${ZFS_BOOTFS}"
+	#
+	#   but the MOUNTPOINT prefix is preserved on descendent filesystem
+	#   after the pivot into the regular root, which later breaks things
+	#   like `zfs mount -a` and the /etc/mtab refresh.
+	#
+	# * Mount additional filesystems required
+	#   Such as /usr, /var, /usr/local etc.
+	#   NOTE: Mounted in the order specified in the
+	#         ZFS_INITRD_ADDITIONAL_DATASETS variable so take care!
+
+	# Go through the complete list (recursivly) of all filesystems below
+	# the real root dataset
+	filesystems=$("${ZFS}" list -oname -tfilesystem -H -r "${ZFS_BOOTFS}")
+	for fs in $filesystems $ZFS_INITRD_ADDITIONAL_DATASETS
+	do
+		mount_fs "$fs"
+	done
+
+	# ------------
+	# Debugging information
+	if [ -n "${ZFS_DEBUG}" ]
+	then
+		#exec 2>&1-
+
+		echo "DEBUG: imported pools:"
+		"${ZPOOL}" list -H
+		echo
+
+		echo "DEBUG: mounted ZFS filesystems:"
+		mount | grep zfs
+		echo
+
+		echo "=> waiting for ENTER before continuing because of 'zfsdebug=1'. "
+		echo -n "   'c' for shell, 'r' for reboot, 'ENTER' to continue. "
+		read b
+
+		[ "$b" = "c" ] && /bin/sh
+		[ "$b" = "r" ] && reboot -f
+
+		set +x
+	fi
+
+	# ------------
+	# Run local bottom script
+	if type run_scripts > /dev/null 2>&1 && \
+	    [ -f "/scripts/local-bottom" -o -d "/scripts/local-bottom" ]
+	then
+		[ "$quiet" != "y" ] && \
+		    zfs_log_begin_msg "Running /scripts/local-bottom"
+		run_scripts /scripts/local-bottom
+		[ "$quiet" != "y" ] && zfs_log_end_msg
+	fi
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/copy-builtin
@@ -0,0 +1,126 @@
+#!/bin/bash
+
+set -e
+
+usage()
+{
+	echo "usage: $0 <kernel source tree>" >&2
+	exit 1
+}
+
+[ "$#" -eq 1 ] || usage
+KERNEL_DIR="$(readlink --canonicalize-existing "$1")"
+
+MODULES=()
+for MODULE_DIR in module/*
+do
+	[ -d "$MODULE_DIR" ] || continue
+	MODULES+=("${MODULE_DIR##*/}")
+done
+
+if ! [ -e 'zfs_config.h' ]
+then
+	echo >&2
+	echo "    $0: you did not run configure, or you're not in the ZFS source directory." >&2
+	echo "    $0: run configure with --with-linux=$KERNEL_DIR and --enable-linux-builtin." >&2
+	echo >&2
+	exit 1
+fi
+
+make clean || true
+
+rm -rf "$KERNEL_DIR/include/zfs" "$KERNEL_DIR/fs/zfs"
+cp --recursive include "$KERNEL_DIR/include/zfs"
+cp --recursive module "$KERNEL_DIR/fs/zfs"
+cp zfs_config.h "$KERNEL_DIR/"
+
+adjust_obj_paths()
+{
+	local FILE="$1"
+	local LINE OBJPATH
+
+	while IFS='' read -r LINE
+	do
+		OBJPATH="${LINE#\$(MODULE)-objs += }"
+		if [ "$OBJPATH" = "$LINE" ]
+		then
+			echo "$LINE"
+		else
+			echo "\$(MODULE)-objs += ${OBJPATH##*/}"
+		fi
+	done < "$FILE" > "$FILE.new"
+	mv "$FILE.new" "$FILE"
+}
+
+for MODULE in "${MODULES[@]}"
+do
+	adjust_obj_paths "$KERNEL_DIR/fs/zfs/$MODULE/Makefile"
+	sed -i.bak '/obj =/d' "$KERNEL_DIR/fs/zfs/$MODULE/Makefile"
+	sed -i.bak '/src =/d' "$KERNEL_DIR/fs/zfs/$MODULE/Makefile"
+done
+
+cat > "$KERNEL_DIR/fs/zfs/Kconfig" <<"EOF"
+config ZFS
+	tristate "ZFS filesystem support"
+	depends on SPL
+	depends on EFI_PARTITION
+	select ZLIB_INFLATE
+	select ZLIB_DEFLATE
+	help
+	  This is the ZFS filesystem from the ZFS On Linux project.
+
+	  See http://zfsonlinux.org/
+
+	  To compile this file system support as a module, choose M here.
+
+	  If unsure, say N.
+EOF
+
+{
+	cat <<-"EOF"
+	ZFS_MODULE_CFLAGS  = -I$(srctree)/include/zfs -I$(srctree)/include/spl 
+	ZFS_MODULE_CFLAGS += -include $(srctree)/spl_config.h -include $(srctree)/zfs_config.h
+	export ZFS_MODULE_CFLAGS
+
+	obj-$(CONFIG_ZFS) :=
+	EOF
+
+	for MODULE in "${MODULES[@]}"
+	do
+		echo 'obj-$(CONFIG_ZFS) += ' "$MODULE/"
+	done
+} > "$KERNEL_DIR/fs/zfs/Kbuild"
+
+add_after()
+{
+	local FILE="$1"
+	local MARKER="$2"
+	local NEW="$3"
+	local LINE
+
+	while IFS='' read -r LINE
+	do
+		echo "$LINE"
+
+		if [ -n "$MARKER" -a "$LINE" = "$MARKER" ]
+		then
+			echo "$NEW"
+			MARKER=''
+			if IFS='' read -r LINE
+			then
+				[ "$LINE" != "$NEW" ] && echo "$LINE"
+			fi
+		fi
+	done < "$FILE" > "$FILE.new"
+
+	mv "$FILE.new" "$FILE"
+}
+
+add_after "$KERNEL_DIR/fs/Kconfig" 'if BLOCK' 'source "fs/zfs/Kconfig"'
+add_after "$KERNEL_DIR/fs/Makefile" 'endif' 'obj-$(CONFIG_ZFS) += zfs/'
+
+echo >&2
+echo "    $0: done." >&2
+echo "    $0: now you can build the kernel with ZFS support." >&2
+echo "    $0: make sure you enable ZFS support (CONFIG_ZFS) before building." >&2
+echo >&2
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/cp
@@ -0,0 +1,2 @@
+#!/bin/sh
+cp "$@"
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/dkms.conf
@@ -0,0 +1,88 @@
+BUILD_DEPENDS[0]="spl"
+AUTOINSTALL="yes"
+PACKAGE_NAME="zfs"
+PACKAGE_VERSION="0.6.5.6"
+PRE_BUILD="configure
+  --prefix=/usr
+  --with-config=kernel
+  --with-linux=$(
+    case `lsb_release -is` in
+      (Debian)
+        if [[ -e ${kernel_source_dir/%build/source} ]]
+        then
+          echo ${kernel_source_dir/%build/source}
+        else
+          # A kpkg exception for Proxmox 2.0
+          echo ${kernel_source_dir}
+        fi
+      ;;
+      (*)
+        echo ${kernel_source_dir}
+      ;;
+    esac
+  )
+  --with-linux-obj=${kernel_source_dir}
+  --with-spl=${source_tree}/spl-${PACKAGE_VERSION}
+  --with-spl-obj=${dkms_tree}/spl/${PACKAGE_VERSION}/${kernelver}/${arch}
+  $(
+    [[ -r /etc/default/zfs ]] \
+    && source /etc/default/zfs \
+    && shopt -q -s extglob \
+    && \
+    {
+      if [[ ${ZFS_DKMS_ENABLE_DEBUG,,} == @(y|yes) ]]
+      then
+        echo --enable-debug
+      fi
+      if [[ ${ZFS_DKMS_ENABLE_DEBUG_DMU_TX,,} == @(y|yes) ]]
+      then
+        echo --enable-debug-dmu-tx
+      fi
+    }
+  )
+"
+POST_BUILD="cp
+  ${dkms_tree}/${PACKAGE_NAME}/${PACKAGE_VERSION}/build/zfs_config.h
+  ${dkms_tree}/${PACKAGE_NAME}/${PACKAGE_VERSION}/build/module/Module.symvers
+  ${dkms_tree}/${PACKAGE_NAME}/${PACKAGE_VERSION}/${kernelver}/${arch}/
+"
+REMAKE_INITRD="$(
+  if [ -e /usr/share/initramfs-tools/hooks/zfs \
+       -o -e /usr/share/dracut/modules.d/90zfs ]
+  then
+    echo -n yes
+  else
+    echo -n no
+  fi
+)"
+MAKE[0]="make"
+STRIP[0]="$(
+  [[ -r /etc/default/zfs ]] \
+  && source /etc/default/zfs \
+  && shopt -q -s extglob \
+  && [[ ${ZFS_DKMS_DISABLE_STRIP,,} == @(y|yes) ]] \
+  && echo -n no
+)"
+STRIP[1]="${STRIP[0]}"
+STRIP[2]="${STRIP[0]}"
+STRIP[3]="${STRIP[0]}"
+STRIP[4]="${STRIP[0]}"
+STRIP[5]="${STRIP[0]}"
+BUILT_MODULE_NAME[0]="zavl"
+BUILT_MODULE_LOCATION[0]="module/avl/"
+DEST_MODULE_LOCATION[0]="/extra/zfs/zavl"
+BUILT_MODULE_NAME[1]="zcommon"
+BUILT_MODULE_LOCATION[1]="module/zcommon/"
+DEST_MODULE_LOCATION[1]="/extra/zfs/zcommon"
+BUILT_MODULE_NAME[2]="znvpair"
+BUILT_MODULE_LOCATION[2]="module/nvpair/"
+DEST_MODULE_LOCATION[2]="/extra/zfs/znvpair"
+BUILT_MODULE_NAME[3]="zpios"
+BUILT_MODULE_LOCATION[3]="module/zpios/"
+DEST_MODULE_LOCATION[3]="/extra/zfs/zpios"
+BUILT_MODULE_NAME[4]="zunicode"
+BUILT_MODULE_LOCATION[4]="module/unicode/"
+DEST_MODULE_LOCATION[4]="/extra/zfs/zunicode"
+BUILT_MODULE_NAME[5]="zfs"
+BUILT_MODULE_LOCATION[5]="module/zfs/"
+DEST_MODULE_LOCATION[5]="/extra/zfs/zfs"
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/etc/Makefile.in
@@ -0,0 +1,2 @@
+%:
+	#
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/etc/init.d/Makefile.in
@@ -0,0 +1,2 @@
+%:
+	#
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/etc/init.d/zfs-functions.in
@@ -0,0 +1,2 @@
+%:
+	#
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/etc/init.d/zfs-import.in
@@ -0,0 +1,2 @@
+%:
+	#
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/etc/init.d/zfs-mount.in
@@ -0,0 +1,2 @@
+%:
+	#
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/etc/init.d/zfs-share.in
@@ -0,0 +1,2 @@
+%:
+	#
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/etc/init.d/zfs-zed.in
@@ -0,0 +1,2 @@
+%:
+	#
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/etc/init.d/zfs.in
@@ -0,0 +1,2 @@
+%:
+	#
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/etc/modules-load.d/Makefile.in
@@ -0,0 +1,2 @@
+%:
+	#
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/etc/modules-load.d/zfs.conf.in
@@ -0,0 +1,2 @@
+%:
+	#
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/etc/systemd/Makefile.in
@@ -0,0 +1,2 @@
+%:
+	#
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/etc/systemd/system/50-zfs.preset.in
@@ -0,0 +1,2 @@
+%:
+	#
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/etc/systemd/system/Makefile.in
@@ -0,0 +1,2 @@
+%:
+	#
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/etc/systemd/system/zed.service.in
@@ -0,0 +1,2 @@
+%:
+	#
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/etc/systemd/system/zfs-import-cache.service.in
@@ -0,0 +1,2 @@
+%:
+	#
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/etc/systemd/system/zfs-import-scan.service.in
@@ -0,0 +1,2 @@
+%:
+	#
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/etc/systemd/system/zfs-mount.service.in
@@ -0,0 +1,2 @@
+%:
+	#
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/etc/systemd/system/zfs-share.service.in
@@ -0,0 +1,2 @@
+%:
+	#
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/etc/systemd/system/zfs.target.in
@@ -0,0 +1,2 @@
+%:
+	#
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/etc/zfs/Makefile.in
@@ -0,0 +1,2 @@
+%:
+	#
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/include/Makefile.am
@@ -0,0 +1,34 @@
+SUBDIRS = linux sys
+
+COMMON_H = \
+	$(top_srcdir)/include/zfeature_common.h \
+	$(top_srcdir)/include/zfs_comutil.h \
+	$(top_srcdir)/include/zfs_deleg.h \
+	$(top_srcdir)/include/zfs_fletcher.h \
+	$(top_srcdir)/include/zfs_namecheck.h \
+	$(top_srcdir)/include/zfs_prop.h \
+	$(top_srcdir)/include/zpios-ctl.h
+
+KERNEL_H = \
+	$(top_srcdir)/include/zpios-internal.h
+
+USER_H = \
+	$(top_srcdir)/include/libnvpair.h \
+	$(top_srcdir)/include/libuutil_common.h \
+	$(top_srcdir)/include/libuutil.h \
+	$(top_srcdir)/include/libuutil_impl.h \
+	$(top_srcdir)/include/libzfs.h \
+	$(top_srcdir)/include/libzfs_core.h \
+	$(top_srcdir)/include/libzfs_impl.h
+
+EXTRA_DIST = $(COMMON_H) $(KERNEL_H) $(USER_H)
+
+if CONFIG_USER
+libzfsdir = $(includedir)/libzfs
+libzfs_HEADERS = $(COMMON_H) $(USER_H)
+endif
+
+if CONFIG_KERNEL
+kerneldir = @prefix@/src/zfs-$(VERSION)/include
+kernel_HEADERS = $(COMMON_H) $(KERNEL_H)
+endif
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/include/Makefile.in
@@ -0,0 +1,905 @@
+# Makefile.in generated by automake 1.15 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2014 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+VPATH = @srcdir@
+am__is_gnu_make = { \
+  if test -z '$(MAKELEVEL)'; then \
+    false; \
+  elif test -n '$(MAKE_HOST)'; then \
+    true; \
+  elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+    true; \
+  else \
+    false; \
+  fi; \
+}
+am__make_running_with_option = \
+  case $${target_option-} in \
+      ?) ;; \
+      *) echo "am__make_running_with_option: internal error: invalid" \
+              "target option '$${target_option-}' specified" >&2; \
+         exit 1;; \
+  esac; \
+  has_opt=no; \
+  sane_makeflags=$$MAKEFLAGS; \
+  if $(am__is_gnu_make); then \
+    sane_makeflags=$$MFLAGS; \
+  else \
+    case $$MAKEFLAGS in \
+      *\\[\ \	]*) \
+        bs=\\; \
+        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
+    esac; \
+  fi; \
+  skip_next=no; \
+  strip_trailopt () \
+  { \
+    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+  }; \
+  for flg in $$sane_makeflags; do \
+    test $$skip_next = yes && { skip_next=no; continue; }; \
+    case $$flg in \
+      *=*|--*) continue;; \
+        -*I) strip_trailopt 'I'; skip_next=yes;; \
+      -*I?*) strip_trailopt 'I';; \
+        -*O) strip_trailopt 'O'; skip_next=yes;; \
+      -*O?*) strip_trailopt 'O';; \
+        -*l) strip_trailopt 'l'; skip_next=yes;; \
+      -*l?*) strip_trailopt 'l';; \
+      -[dEDm]) skip_next=yes;; \
+      -[JT]) skip_next=yes;; \
+    esac; \
+    case $$flg in \
+      *$$target_option*) has_opt=yes; break;; \
+    esac; \
+  done; \
+  test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+target_triplet = @target@
+subdir = include
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/config/always-no-bool-compare.m4 \
+	$(top_srcdir)/config/always-no-unused-but-set-variable.m4 \
+	$(top_srcdir)/config/dkms.m4 \
+	$(top_srcdir)/config/kernel-acl.m4 \
+	$(top_srcdir)/config/kernel-automount.m4 \
+	$(top_srcdir)/config/kernel-bdev-block-device-operations.m4 \
+	$(top_srcdir)/config/kernel-bdev-logical-size.m4 \
+	$(top_srcdir)/config/kernel-bdev-physical-size.m4 \
+	$(top_srcdir)/config/kernel-bdi-setup-and-register.m4 \
+	$(top_srcdir)/config/kernel-bio-bvec-iter.m4 \
+	$(top_srcdir)/config/kernel-bio-end-io-t-args.m4 \
+	$(top_srcdir)/config/kernel-bio-failfast.m4 \
+	$(top_srcdir)/config/kernel-bio-rw-barrier.m4 \
+	$(top_srcdir)/config/kernel-bio-rw-discard.m4 \
+	$(top_srcdir)/config/kernel-blk-queue-flush.m4 \
+	$(top_srcdir)/config/kernel-blk-queue-max-hw-sectors.m4 \
+	$(top_srcdir)/config/kernel-blk-queue-max-segments.m4 \
+	$(top_srcdir)/config/kernel-blkdev-get-by-path.m4 \
+	$(top_srcdir)/config/kernel-blkdev-get.m4 \
+	$(top_srcdir)/config/kernel-block-device-operations-release-void.m4 \
+	$(top_srcdir)/config/kernel-check-disk-size-change.m4 \
+	$(top_srcdir)/config/kernel-clear-inode.m4 \
+	$(top_srcdir)/config/kernel-commit-metadata.m4 \
+	$(top_srcdir)/config/kernel-create-nameidata.m4 \
+	$(top_srcdir)/config/kernel-current_bio_tail.m4 \
+	$(top_srcdir)/config/kernel-d-make-root.m4 \
+	$(top_srcdir)/config/kernel-d-obtain-alias.m4 \
+	$(top_srcdir)/config/kernel-d-prune-aliases.m4 \
+	$(top_srcdir)/config/kernel-declare-event-class.m4 \
+	$(top_srcdir)/config/kernel-dentry-operations.m4 \
+	$(top_srcdir)/config/kernel-dirty-inode.m4 \
+	$(top_srcdir)/config/kernel-discard-granularity.m4 \
+	$(top_srcdir)/config/kernel-elevator-change.m4 \
+	$(top_srcdir)/config/kernel-encode-fh-inode.m4 \
+	$(top_srcdir)/config/kernel-evict-inode.m4 \
+	$(top_srcdir)/config/kernel-fallocate.m4 \
+	$(top_srcdir)/config/kernel-file-inode.m4 \
+	$(top_srcdir)/config/kernel-fmode-t.m4 \
+	$(top_srcdir)/config/kernel-follow-down-one.m4 \
+	$(top_srcdir)/config/kernel-fsync.m4 \
+	$(top_srcdir)/config/kernel-generic_io_acct.m4 \
+	$(top_srcdir)/config/kernel-get-disk-ro.m4 \
+	$(top_srcdir)/config/kernel-get-gendisk.m4 \
+	$(top_srcdir)/config/kernel-get-link.m4 \
+	$(top_srcdir)/config/kernel-insert-inode-locked.m4 \
+	$(top_srcdir)/config/kernel-invalidate-bdev-args.m4 \
+	$(top_srcdir)/config/kernel-is_owner_or_cap.m4 \
+	$(top_srcdir)/config/kernel-kmap-atomic-args.m4 \
+	$(top_srcdir)/config/kernel-kobj-name-len.m4 \
+	$(top_srcdir)/config/kernel-lookup-bdev.m4 \
+	$(top_srcdir)/config/kernel-lookup-nameidata.m4 \
+	$(top_srcdir)/config/kernel-lseek-execute.m4 \
+	$(top_srcdir)/config/kernel-mk-request-fn.m4 \
+	$(top_srcdir)/config/kernel-mkdir-umode-t.m4 \
+	$(top_srcdir)/config/kernel-mount-nodev.m4 \
+	$(top_srcdir)/config/kernel-open-bdev-exclusive.m4 \
+	$(top_srcdir)/config/kernel-put-link.m4 \
+	$(top_srcdir)/config/kernel-security-inode-init.m4 \
+	$(top_srcdir)/config/kernel-set-nlink.m4 \
+	$(top_srcdir)/config/kernel-sget-args.m4 \
+	$(top_srcdir)/config/kernel-show-options.m4 \
+	$(top_srcdir)/config/kernel-shrink.m4 \
+	$(top_srcdir)/config/kernel-truncate-range.m4 \
+	$(top_srcdir)/config/kernel-truncate-setsize.m4 \
+	$(top_srcdir)/config/kernel-vfs-iterate.m4 \
+	$(top_srcdir)/config/kernel-vfs-rw-iterate.m4 \
+	$(top_srcdir)/config/kernel-xattr-handler.m4 \
+	$(top_srcdir)/config/kernel.m4 $(top_srcdir)/config/libtool.m4 \
+	$(top_srcdir)/config/ltoptions.m4 \
+	$(top_srcdir)/config/ltsugar.m4 \
+	$(top_srcdir)/config/ltversion.m4 \
+	$(top_srcdir)/config/lt~obsolete.m4 \
+	$(top_srcdir)/config/mount-helper.m4 \
+	$(top_srcdir)/config/user-arch.m4 \
+	$(top_srcdir)/config/user-dracut.m4 \
+	$(top_srcdir)/config/user-frame-larger-than.m4 \
+	$(top_srcdir)/config/user-libblkid.m4 \
+	$(top_srcdir)/config/user-libuuid.m4 \
+	$(top_srcdir)/config/user-runstatedir.m4 \
+	$(top_srcdir)/config/user-systemd.m4 \
+	$(top_srcdir)/config/user-sysvinit.m4 \
+	$(top_srcdir)/config/user-udev.m4 \
+	$(top_srcdir)/config/user-zlib.m4 $(top_srcdir)/config/user.m4 \
+	$(top_srcdir)/config/zfs-build.m4 \
+	$(top_srcdir)/config/zfs-meta.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(am__kernel_HEADERS_DIST) \
+	$(am__libzfs_HEADERS_DIST) $(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/zfs_config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo "  GEN     " $@;
+am__v_GEN_1 = 
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 = 
+SOURCES =
+DIST_SOURCES =
+RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \
+	ctags-recursive dvi-recursive html-recursive info-recursive \
+	install-data-recursive install-dvi-recursive \
+	install-exec-recursive install-html-recursive \
+	install-info-recursive install-pdf-recursive \
+	install-ps-recursive install-recursive installcheck-recursive \
+	installdirs-recursive pdf-recursive ps-recursive \
+	tags-recursive uninstall-recursive
+am__can_run_installinfo = \
+  case $$AM_UPDATE_INFO_DIR in \
+    n|no|NO) false;; \
+    *) (install-info --version) >/dev/null 2>&1;; \
+  esac
+am__kernel_HEADERS_DIST = $(top_srcdir)/include/zfeature_common.h \
+	$(top_srcdir)/include/zfs_comutil.h \
+	$(top_srcdir)/include/zfs_deleg.h \
+	$(top_srcdir)/include/zfs_fletcher.h \
+	$(top_srcdir)/include/zfs_namecheck.h \
+	$(top_srcdir)/include/zfs_prop.h \
+	$(top_srcdir)/include/zpios-ctl.h \
+	$(top_srcdir)/include/zpios-internal.h
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+    $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+    *) f=$$p;; \
+  esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+  srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+  for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+  for p in $$list; do echo "$$p $$p"; done | \
+  sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+  $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+    if (++n[$$2] == $(am__install_max)) \
+      { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+    END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+  sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+  sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+  test -z "$$files" \
+    || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+    || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+         $(am__cd) "$$dir" && rm -f $$files; }; \
+  }
+am__installdirs = "$(DESTDIR)$(kerneldir)" "$(DESTDIR)$(libzfsdir)"
+am__libzfs_HEADERS_DIST = $(top_srcdir)/include/zfeature_common.h \
+	$(top_srcdir)/include/zfs_comutil.h \
+	$(top_srcdir)/include/zfs_deleg.h \
+	$(top_srcdir)/include/zfs_fletcher.h \
+	$(top_srcdir)/include/zfs_namecheck.h \
+	$(top_srcdir)/include/zfs_prop.h \
+	$(top_srcdir)/include/zpios-ctl.h \
+	$(top_srcdir)/include/libnvpair.h \
+	$(top_srcdir)/include/libuutil_common.h \
+	$(top_srcdir)/include/libuutil.h \
+	$(top_srcdir)/include/libuutil_impl.h \
+	$(top_srcdir)/include/libzfs.h \
+	$(top_srcdir)/include/libzfs_core.h \
+	$(top_srcdir)/include/libzfs_impl.h
+HEADERS = $(kernel_HEADERS) $(libzfs_HEADERS)
+RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive	\
+  distclean-recursive maintainer-clean-recursive
+am__recursive_targets = \
+  $(RECURSIVE_TARGETS) \
+  $(RECURSIVE_CLEAN_TARGETS) \
+  $(am__extra_recursive_targets)
+AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \
+	distdir
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates.  Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+  BEGIN { nonempty = 0; } \
+  { items[$$0] = 1; nonempty = 1; } \
+  END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique.  This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+  list='$(am__tagged_files)'; \
+  unique=`for i in $$list; do \
+    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+  done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+DIST_SUBDIRS = $(SUBDIRS)
+am__DIST_COMMON = $(srcdir)/Makefile.in
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+am__relativize = \
+  dir0=`pwd`; \
+  sed_first='s,^\([^/]*\)/.*$$,\1,'; \
+  sed_rest='s,^[^/]*/*,,'; \
+  sed_last='s,^.*/\([^/]*\)$$,\1,'; \
+  sed_butlast='s,/*[^/]*$$,,'; \
+  while test -n "$$dir1"; do \
+    first=`echo "$$dir1" | sed -e "$$sed_first"`; \
+    if test "$$first" != "."; then \
+      if test "$$first" = ".."; then \
+        dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \
+        dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \
+      else \
+        first2=`echo "$$dir2" | sed -e "$$sed_first"`; \
+        if test "$$first2" = "$$first"; then \
+          dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \
+        else \
+          dir2="../$$dir2"; \
+        fi; \
+        dir0="$$dir0"/"$$first"; \
+      fi; \
+    fi; \
+    dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \
+  done; \
+  reldir="$$dir2"
+ACLOCAL = @ACLOCAL@
+ALIEN = @ALIEN@
+ALIEN_VERSION = @ALIEN_VERSION@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCAS = @CCAS@
+CCASDEPMODE = @CCASDEPMODE@
+CCASFLAGS = @CCASFLAGS@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEBUG_CFLAGS = @DEBUG_CFLAGS@
+DEBUG_DMU_TX = @DEBUG_DMU_TX@
+DEBUG_STACKFLAGS = @DEBUG_STACKFLAGS@
+DEBUG_ZFS = @DEBUG_ZFS@
+DEFAULT_INITCONF_DIR = @DEFAULT_INITCONF_DIR@
+DEFAULT_INIT_DIR = @DEFAULT_INIT_DIR@
+DEFAULT_INIT_SCRIPT = @DEFAULT_INIT_SCRIPT@
+DEFAULT_PACKAGE = @DEFAULT_PACKAGE@
+DEFINE_INITRAMFS = @DEFINE_INITRAMFS@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DPKG = @DPKG@
+DPKGBUILD = @DPKGBUILD@
+DPKGBUILD_VERSION = @DPKGBUILD_VERSION@
+DPKG_VERSION = @DPKG_VERSION@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+FRAME_LARGER_THAN = @FRAME_LARGER_THAN@
+GREP = @GREP@
+HAVE_ALIEN = @HAVE_ALIEN@
+HAVE_DPKG = @HAVE_DPKG@
+HAVE_DPKGBUILD = @HAVE_DPKGBUILD@
+HAVE_RPM = @HAVE_RPM@
+HAVE_RPMBUILD = @HAVE_RPMBUILD@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+KERNELCPPFLAGS = @KERNELCPPFLAGS@
+KERNELMAKE_PARAMS = @KERNELMAKE_PARAMS@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBBLKID = @LIBBLKID@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIBUUID = @LIBUUID@
+LINUX = @LINUX@
+LINUX_OBJ = @LINUX_OBJ@
+LINUX_SYMBOLS = @LINUX_SYMBOLS@
+LINUX_VERSION = @LINUX_VERSION@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NO_BOOL_COMPARE = @NO_BOOL_COMPARE@
+NO_UNUSED_BUT_SET_VARIABLE = @NO_UNUSED_BUT_SET_VARIABLE@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+RANLIB = @RANLIB@
+RELEASE = @RELEASE@
+RPM = @RPM@
+RPMBUILD = @RPMBUILD@
+RPMBUILD_VERSION = @RPMBUILD_VERSION@
+RPM_DEFINE_COMMON = @RPM_DEFINE_COMMON@
+RPM_DEFINE_DKMS = @RPM_DEFINE_DKMS@
+RPM_DEFINE_KMOD = @RPM_DEFINE_KMOD@
+RPM_DEFINE_UTIL = @RPM_DEFINE_UTIL@
+RPM_SPEC_DIR = @RPM_SPEC_DIR@
+RPM_VERSION = @RPM_VERSION@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SPL = @SPL@
+SPL_OBJ = @SPL_OBJ@
+SPL_SYMBOLS = @SPL_SYMBOLS@
+SPL_VERSION = @SPL_VERSION@
+SRPM_DEFINE_COMMON = @SRPM_DEFINE_COMMON@
+SRPM_DEFINE_DKMS = @SRPM_DEFINE_DKMS@
+SRPM_DEFINE_KMOD = @SRPM_DEFINE_KMOD@
+SRPM_DEFINE_UTIL = @SRPM_DEFINE_UTIL@
+STRIP = @STRIP@
+TARGET_ASM_DIR = @TARGET_ASM_DIR@
+VENDOR = @VENDOR@
+VERSION = @VERSION@
+ZFS_CONFIG = @ZFS_CONFIG@
+ZFS_INIT_SYSTEMD = @ZFS_INIT_SYSTEMD@
+ZFS_INIT_SYSV = @ZFS_INIT_SYSV@
+ZFS_META_ALIAS = @ZFS_META_ALIAS@
+ZFS_META_AUTHOR = @ZFS_META_AUTHOR@
+ZFS_META_DATA = @ZFS_META_DATA@
+ZFS_META_LICENSE = @ZFS_META_LICENSE@
+ZFS_META_LT_AGE = @ZFS_META_LT_AGE@
+ZFS_META_LT_CURRENT = @ZFS_META_LT_CURRENT@
+ZFS_META_LT_REVISION = @ZFS_META_LT_REVISION@
+ZFS_META_NAME = @ZFS_META_NAME@
+ZFS_META_RELEASE = @ZFS_META_RELEASE@
+ZFS_META_VERSION = @ZFS_META_VERSION@
+ZFS_MODULE_LOAD = @ZFS_MODULE_LOAD@
+ZLIB = @ZLIB@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dracutdir = @dracutdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+modulesloaddir = @modulesloaddir@
+mounthelperdir = @mounthelperdir@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+runstatedir = @runstatedir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+systemdpresetdir = @systemdpresetdir@
+systemdunitdir = @systemdunitdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+udevdir = @udevdir@
+udevruledir = @udevruledir@
+SUBDIRS = linux sys
+COMMON_H = \
+	$(top_srcdir)/include/zfeature_common.h \
+	$(top_srcdir)/include/zfs_comutil.h \
+	$(top_srcdir)/include/zfs_deleg.h \
+	$(top_srcdir)/include/zfs_fletcher.h \
+	$(top_srcdir)/include/zfs_namecheck.h \
+	$(top_srcdir)/include/zfs_prop.h \
+	$(top_srcdir)/include/zpios-ctl.h
+
+KERNEL_H = \
+	$(top_srcdir)/include/zpios-internal.h
+
+USER_H = \
+	$(top_srcdir)/include/libnvpair.h \
+	$(top_srcdir)/include/libuutil_common.h \
+	$(top_srcdir)/include/libuutil.h \
+	$(top_srcdir)/include/libuutil_impl.h \
+	$(top_srcdir)/include/libzfs.h \
+	$(top_srcdir)/include/libzfs_core.h \
+	$(top_srcdir)/include/libzfs_impl.h
+
+EXTRA_DIST = $(COMMON_H) $(KERNEL_H) $(USER_H)
+@CONFIG_USER_TRUE@libzfsdir = $(includedir)/libzfs
+@CONFIG_USER_TRUE@libzfs_HEADERS = $(COMMON_H) $(USER_H)
+@CONFIG_KERNEL_TRUE@kerneldir = @prefix@/src/zfs-$(VERSION)/include
+@CONFIG_KERNEL_TRUE@kernel_HEADERS = $(COMMON_H) $(KERNEL_H)
+all: all-recursive
+
+.SUFFIXES:
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+	        && { if test -f $@; then exit 0; else break; fi; }; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu include/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --gnu include/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+	esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
+install-kernelHEADERS: $(kernel_HEADERS)
+	@$(NORMAL_INSTALL)
+	@list='$(kernel_HEADERS)'; test -n "$(kerneldir)" || list=; \
+	if test -n "$$list"; then \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(kerneldir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(kerneldir)" || exit 1; \
+	fi; \
+	for p in $$list; do \
+	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+	  echo "$$d$$p"; \
+	done | $(am__base_list) | \
+	while read files; do \
+	  echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(kerneldir)'"; \
+	  $(INSTALL_HEADER) $$files "$(DESTDIR)$(kerneldir)" || exit $$?; \
+	done
+
+uninstall-kernelHEADERS:
+	@$(NORMAL_UNINSTALL)
+	@list='$(kernel_HEADERS)'; test -n "$(kerneldir)" || list=; \
+	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+	dir='$(DESTDIR)$(kerneldir)'; $(am__uninstall_files_from_dir)
+install-libzfsHEADERS: $(libzfs_HEADERS)
+	@$(NORMAL_INSTALL)
+	@list='$(libzfs_HEADERS)'; test -n "$(libzfsdir)" || list=; \
+	if test -n "$$list"; then \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(libzfsdir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(libzfsdir)" || exit 1; \
+	fi; \
+	for p in $$list; do \
+	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+	  echo "$$d$$p"; \
+	done | $(am__base_list) | \
+	while read files; do \
+	  echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(libzfsdir)'"; \
+	  $(INSTALL_HEADER) $$files "$(DESTDIR)$(libzfsdir)" || exit $$?; \
+	done
+
+uninstall-libzfsHEADERS:
+	@$(NORMAL_UNINSTALL)
+	@list='$(libzfs_HEADERS)'; test -n "$(libzfsdir)" || list=; \
+	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+	dir='$(DESTDIR)$(libzfsdir)'; $(am__uninstall_files_from_dir)
+
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run 'make' without going through this Makefile.
+# To change the values of 'make' variables: instead of editing Makefiles,
+# (1) if the variable is set in 'config.status', edit 'config.status'
+#     (which will cause the Makefiles to be regenerated when you run 'make');
+# (2) otherwise, pass the desired values on the 'make' command line.
+$(am__recursive_targets):
+	@fail=; \
+	if $(am__make_keepgoing); then \
+	  failcom='fail=yes'; \
+	else \
+	  failcom='exit 1'; \
+	fi; \
+	dot_seen=no; \
+	target=`echo $@ | sed s/-recursive//`; \
+	case "$@" in \
+	  distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
+	  *) list='$(SUBDIRS)' ;; \
+	esac; \
+	for subdir in $$list; do \
+	  echo "Making $$target in $$subdir"; \
+	  if test "$$subdir" = "."; then \
+	    dot_seen=yes; \
+	    local_target="$$target-am"; \
+	  else \
+	    local_target="$$target"; \
+	  fi; \
+	  ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+	  || eval $$failcom; \
+	done; \
+	if test "$$dot_seen" = "no"; then \
+	  $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+	fi; test -z "$$fail"
+
+ID: $(am__tagged_files)
+	$(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-recursive
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	set x; \
+	here=`pwd`; \
+	if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
+	  include_option=--etags-include; \
+	  empty_fix=.; \
+	else \
+	  include_option=--include; \
+	  empty_fix=; \
+	fi; \
+	list='$(SUBDIRS)'; for subdir in $$list; do \
+	  if test "$$subdir" = .; then :; else \
+	    test ! -f $$subdir/TAGS || \
+	      set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \
+	  fi; \
+	done; \
+	$(am__define_uniq_tagged_files); \
+	shift; \
+	if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+	  test -n "$$unique" || unique=$$empty_fix; \
+	  if test $$# -gt 0; then \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      "$$@" $$unique; \
+	  else \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      $$unique; \
+	  fi; \
+	fi
+ctags: ctags-recursive
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	$(am__define_uniq_tagged_files); \
+	test -z "$(CTAGS_ARGS)$$unique" \
+	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+	     $$unique
+
+GTAGS:
+	here=`$(am__cd) $(top_builddir) && pwd` \
+	  && $(am__cd) $(top_srcdir) \
+	  && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-recursive
+
+cscopelist-am: $(am__tagged_files)
+	list='$(am__tagged_files)'; \
+	case "$(srcdir)" in \
+	  [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+	  *) sdir=$(subdir)/$(srcdir) ;; \
+	esac; \
+	for i in $$list; do \
+	  if test -f "$$i"; then \
+	    echo "$(subdir)/$$i"; \
+	  else \
+	    echo "$$sdir/$$i"; \
+	  fi; \
+	done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	list='$(DISTFILES)'; \
+	  dist_files=`for file in $$list; do echo $$file; done | \
+	  sed -e "s|^$$srcdirstrip/||;t" \
+	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+	case $$dist_files in \
+	  */*) $(MKDIR_P) `echo "$$dist_files" | \
+			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+			   sort -u` ;; \
+	esac; \
+	for file in $$dist_files; do \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  if test -d $$d/$$file; then \
+	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+	    if test -d "$(distdir)/$$file"; then \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+	  else \
+	    test -f "$(distdir)/$$file" \
+	    || cp -p $$d/$$file "$(distdir)/$$file" \
+	    || exit 1; \
+	  fi; \
+	done
+	@list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
+	  if test "$$subdir" = .; then :; else \
+	    $(am__make_dryrun) \
+	      || test -d "$(distdir)/$$subdir" \
+	      || $(MKDIR_P) "$(distdir)/$$subdir" \
+	      || exit 1; \
+	    dir1=$$subdir; dir2="$(distdir)/$$subdir"; \
+	    $(am__relativize); \
+	    new_distdir=$$reldir; \
+	    dir1=$$subdir; dir2="$(top_distdir)"; \
+	    $(am__relativize); \
+	    new_top_distdir=$$reldir; \
+	    echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \
+	    echo "     am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \
+	    ($(am__cd) $$subdir && \
+	      $(MAKE) $(AM_MAKEFLAGS) \
+	        top_distdir="$$new_top_distdir" \
+	        distdir="$$new_distdir" \
+		am__remove_distdir=: \
+		am__skip_length_check=: \
+		am__skip_mode_fix=: \
+	        distdir) \
+	      || exit 1; \
+	  fi; \
+	done
+check-am: all-am
+check: check-recursive
+all-am: Makefile $(HEADERS)
+installdirs: installdirs-recursive
+installdirs-am:
+	for dir in "$(DESTDIR)$(kerneldir)" "$(DESTDIR)$(libzfsdir)"; do \
+	  test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+	done
+install: install-recursive
+install-exec: install-exec-recursive
+install-data: install-data-recursive
+uninstall: uninstall-recursive
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-recursive
+install-strip:
+	if test -z '$(STRIP)'; then \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	      install; \
+	else \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+	fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+clean: clean-recursive
+
+clean-am: clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-recursive
+	-rm -f Makefile
+distclean-am: clean-am distclean-generic distclean-tags
+
+dvi: dvi-recursive
+
+dvi-am:
+
+html: html-recursive
+
+html-am:
+
+info: info-recursive
+
+info-am:
+
+install-data-am: install-kernelHEADERS install-libzfsHEADERS
+
+install-dvi: install-dvi-recursive
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-recursive
+
+install-html-am:
+
+install-info: install-info-recursive
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-recursive
+
+install-pdf-am:
+
+install-ps: install-ps-recursive
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-recursive
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-recursive
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-recursive
+
+pdf-am:
+
+ps: ps-recursive
+
+ps-am:
+
+uninstall-am: uninstall-kernelHEADERS uninstall-libzfsHEADERS
+
+.MAKE: $(am__recursive_targets) install-am install-strip
+
+.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \
+	check-am clean clean-generic clean-libtool cscopelist-am ctags \
+	ctags-am distclean distclean-generic distclean-libtool \
+	distclean-tags distdir dvi dvi-am html html-am info info-am \
+	install install-am install-data install-data-am install-dvi \
+	install-dvi-am install-exec install-exec-am install-html \
+	install-html-am install-info install-info-am \
+	install-kernelHEADERS install-libzfsHEADERS install-man \
+	install-pdf install-pdf-am install-ps install-ps-am \
+	install-strip installcheck installcheck-am installdirs \
+	installdirs-am maintainer-clean maintainer-clean-generic \
+	mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \
+	ps ps-am tags tags-am uninstall uninstall-am \
+	uninstall-kernelHEADERS uninstall-libzfsHEADERS
+
+.PRECIOUS: Makefile
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/include/libnvpair.h
@@ -0,0 +1,194 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+ */
+
+#ifndef	_LIBNVPAIR_H
+#define	_LIBNVPAIR_H
+
+#include <sys/nvpair.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <regex.h>
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+/*
+ * All interfaces described in this file are private to Solaris, and
+ * are subject to change at any time and without notice.  The public
+ * nvlist/nvpair interfaces, as documented in manpage sections 3NVPAIR,
+ * are all imported from <sys/nvpair.h> included above.
+ */
+
+extern int nvpair_value_match(nvpair_t *, int, char *, char **);
+extern int nvpair_value_match_regex(nvpair_t *, int, char *, regex_t *,
+    char **);
+
+extern void nvlist_print(FILE *, nvlist_t *);
+extern void dump_nvlist(nvlist_t *, int);
+
+/*
+ * Private nvlist printing interface that allows the caller some control
+ * over output rendering (as opposed to nvlist_print and dump_nvlist).
+ *
+ * Obtain an opaque nvlist_prtctl_t cookie using nvlist_prtctl_alloc
+ * (NULL on failure);  on return the cookie is set up for default formatting
+ * and rendering.  Quote the cookie in subsequent customisation functions and
+ * then pass the cookie to nvlist_prt to render the nvlist.  Finally,
+ * use nvlist_prtctl_free to release the cookie.
+ *
+ * For all nvlist_lookup_xxx and nvlist_lookup_xxx_array functions
+ * we have a corresponding brace of functions that appoint replacement
+ * rendering functions:
+ *
+ *	extern void nvlist_prtctl_xxx(nvlist_prtctl_t,
+ *	    void (*)(nvlist_prtctl_t ctl, void *private, const char *name,
+ *	    xxxtype value))
+ *
+ *	and
+ *
+ *	extern void nvlist_prtctl_xxx_array(nvlist_prtctl_t,
+ *	    void (*)(nvlist_prtctl_t ctl, void *private, const char *name,
+ *	    xxxtype value, uint_t count))
+ *
+ * where xxxtype is the C datatype corresponding to xxx, eg int8_t for "int8"
+ * and char * for "string".  The function that is appointed to render the
+ * specified datatype receives as arguments the cookie, the nvlist
+ * member name, the value of that member (or a pointer for array function),
+ * and (for array rendering functions) a count of the number of elements.
+ */
+
+typedef struct nvlist_prtctl *nvlist_prtctl_t;	/* opaque */
+
+enum nvlist_indent_mode {
+	NVLIST_INDENT_ABS,	/* Absolute indentation */
+	NVLIST_INDENT_TABBED	/* Indent with tabstops */
+};
+
+extern nvlist_prtctl_t nvlist_prtctl_alloc(void);
+extern void nvlist_prtctl_free(nvlist_prtctl_t);
+extern void nvlist_prt(nvlist_t *, nvlist_prtctl_t);
+
+/* Output stream */
+extern void nvlist_prtctl_setdest(nvlist_prtctl_t, FILE *);
+extern FILE *nvlist_prtctl_getdest(nvlist_prtctl_t);
+
+/* Indentation mode, start indent, indent increment; default tabbed/0/1 */
+extern void nvlist_prtctl_setindent(nvlist_prtctl_t, enum nvlist_indent_mode,
+    int, int);
+extern void nvlist_prtctl_doindent(nvlist_prtctl_t, int);
+
+enum nvlist_prtctl_fmt {
+	NVLIST_FMT_MEMBER_NAME,		/* name fmt; default "%s = " */
+	NVLIST_FMT_MEMBER_POSTAMBLE,	/* after nvlist member; default "\n" */
+	NVLIST_FMT_BTWN_ARRAY		/* between array members; default " " */
+};
+
+extern void nvlist_prtctl_setfmt(nvlist_prtctl_t, enum nvlist_prtctl_fmt,
+    const char *);
+extern void nvlist_prtctl_dofmt(nvlist_prtctl_t, enum nvlist_prtctl_fmt, ...);
+
+/*
+ * Function prototypes for interfaces that appoint a new rendering function
+ * for single-valued nvlist members.
+ *
+ * A replacement function receives arguments as follows:
+ *
+ *	nvlist_prtctl_t	Print control structure; do not change preferences
+ *			for this object from a print callback function.
+ *
+ *	void *		The function-private cookie argument registered
+ *			when the replacement function was appointed.
+ *
+ *	nvlist_t *	The full nvlist that is being processed.  The
+ *			rendering function is called to render a single
+ *			member (name and value passed as below) but it may
+ *			want to reference or incorporate other aspects of
+ *			the full nvlist.
+ *
+ *	const char *	Member name to render
+ *
+ *	valtype		Value of the member to render
+ *
+ * The function must return non-zero if it has rendered output for this
+ * member, or 0 if it wants to default to standard rendering for this
+ * one member.
+ */
+
+#define	NVLIST_PRINTCTL_SVDECL(funcname, valtype) \
+    extern void funcname(nvlist_prtctl_t, \
+    int (*)(nvlist_prtctl_t, void *, nvlist_t *, const char *, valtype), \
+    void *)
+
+NVLIST_PRINTCTL_SVDECL(nvlist_prtctlop_boolean, int);
+NVLIST_PRINTCTL_SVDECL(nvlist_prtctlop_boolean_value, boolean_t);
+NVLIST_PRINTCTL_SVDECL(nvlist_prtctlop_byte, uchar_t);
+NVLIST_PRINTCTL_SVDECL(nvlist_prtctlop_int8, int8_t);
+NVLIST_PRINTCTL_SVDECL(nvlist_prtctlop_uint8, uint8_t);
+NVLIST_PRINTCTL_SVDECL(nvlist_prtctlop_int16, int16_t);
+NVLIST_PRINTCTL_SVDECL(nvlist_prtctlop_uint16, uint16_t);
+NVLIST_PRINTCTL_SVDECL(nvlist_prtctlop_int32, int32_t);
+NVLIST_PRINTCTL_SVDECL(nvlist_prtctlop_uint32, uint32_t);
+NVLIST_PRINTCTL_SVDECL(nvlist_prtctlop_int64, int64_t);
+NVLIST_PRINTCTL_SVDECL(nvlist_prtctlop_uint64, uint64_t);
+NVLIST_PRINTCTL_SVDECL(nvlist_prtctlop_double, double);
+NVLIST_PRINTCTL_SVDECL(nvlist_prtctlop_string, char *);
+NVLIST_PRINTCTL_SVDECL(nvlist_prtctlop_hrtime, hrtime_t);
+NVLIST_PRINTCTL_SVDECL(nvlist_prtctlop_nvlist, nvlist_t *);
+
+#undef	NVLIST_PRINTCTL_SVDECL	/* was just for "clarity" above */
+
+/*
+ * Function prototypes for interfaces that appoint a new rendering function
+ * for array-valued nvlist members.
+ *
+ * One additional argument is taken: uint_t for the number of array elements
+ *
+ * Return values as above.
+ */
+#define	NVLIST_PRINTCTL_AVDECL(funcname, vtype) \
+    extern void funcname(nvlist_prtctl_t, \
+    int (*)(nvlist_prtctl_t, void *, nvlist_t *, const char *, vtype, uint_t), \
+    void *)
+
+NVLIST_PRINTCTL_AVDECL(nvlist_prtctlop_boolean_array, boolean_t *);
+NVLIST_PRINTCTL_AVDECL(nvlist_prtctlop_byte_array, uchar_t *);
+NVLIST_PRINTCTL_AVDECL(nvlist_prtctlop_int8_array, int8_t *);
+NVLIST_PRINTCTL_AVDECL(nvlist_prtctlop_uint8_array, uint8_t *);
+NVLIST_PRINTCTL_AVDECL(nvlist_prtctlop_int16_array, int16_t *);
+NVLIST_PRINTCTL_AVDECL(nvlist_prtctlop_uint16_array, uint16_t *);
+NVLIST_PRINTCTL_AVDECL(nvlist_prtctlop_int32_array, int32_t *);
+NVLIST_PRINTCTL_AVDECL(nvlist_prtctlop_uint32_array, uint32_t *);
+NVLIST_PRINTCTL_AVDECL(nvlist_prtctlop_int64_array, int64_t *);
+NVLIST_PRINTCTL_AVDECL(nvlist_prtctlop_uint64_array, uint64_t *);
+NVLIST_PRINTCTL_AVDECL(nvlist_prtctlop_string_array, char **);
+NVLIST_PRINTCTL_AVDECL(nvlist_prtctlop_nvlist_array, nvlist_t **);
+
+#undef	NVLIST_PRINTCTL_AVDECL	/* was just for "clarity" above */
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* _LIBNVPAIR_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/include/libuutil.h
@@ -0,0 +1,390 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
+ */
+
+#ifndef	_LIBUUTIL_H
+#define	_LIBUUTIL_H
+
+#include <sys/types.h>
+#include <stdarg.h>
+#include <stdio.h>
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+/*
+ * Standard flags codes.
+ */
+#define	UU_DEFAULT		0
+
+/*
+ * Standard error codes.
+ */
+#define	UU_ERROR_NONE		0	/* no error */
+#define	UU_ERROR_INVALID_ARGUMENT 1	/* invalid argument */
+#define	UU_ERROR_UNKNOWN_FLAG	2	/* passed flag invalid */
+#define	UU_ERROR_NO_MEMORY	3	/* out of memory */
+#define	UU_ERROR_CALLBACK_FAILED 4	/* callback-initiated error */
+#define	UU_ERROR_NOT_SUPPORTED	5	/* operation not supported */
+#define	UU_ERROR_EMPTY		6	/* no value provided */
+#define	UU_ERROR_UNDERFLOW	7	/* value is too small */
+#define	UU_ERROR_OVERFLOW	8	/* value is too value */
+#define	UU_ERROR_INVALID_CHAR	9	/* value contains unexpected char */
+#define	UU_ERROR_INVALID_DIGIT	10	/* value contains digit not in base */
+
+#define	UU_ERROR_SYSTEM		99	/* underlying system error */
+#define	UU_ERROR_UNKNOWN	100	/* error status not known */
+
+/*
+ * Standard program exit codes.
+ */
+#define	UU_EXIT_OK	(*(uu_exit_ok()))
+#define	UU_EXIT_FATAL	(*(uu_exit_fatal()))
+#define	UU_EXIT_USAGE	(*(uu_exit_usage()))
+
+/*
+ * Exit status profiles.
+ */
+#define	UU_PROFILE_DEFAULT	0
+#define	UU_PROFILE_LAUNCHER	1
+
+/*
+ * Error reporting functions.
+ */
+uint32_t uu_error(void);
+const char *uu_strerror(uint32_t);
+
+/*
+ * Program notification functions.
+ */
+extern void uu_alt_exit(int);
+extern const char *uu_setpname(char *);
+extern const char *uu_getpname(void);
+/*PRINTFLIKE1*/
+extern void uu_warn(const char *, ...);
+extern void uu_vwarn(const char *, va_list);
+/*PRINTFLIKE1*/
+extern void uu_die(const char *, ...) __NORETURN;
+extern void uu_vdie(const char *, va_list) __NORETURN;
+/*PRINTFLIKE2*/
+extern void uu_xdie(int, const char *, ...) __NORETURN;
+extern void uu_vxdie(int, const char *, va_list) __NORETURN;
+
+/*
+ * Exit status functions (not to be used directly)
+ */
+extern int *uu_exit_ok(void);
+extern int *uu_exit_fatal(void);
+extern int *uu_exit_usage(void);
+
+/*
+ * string->number conversions
+ */
+extern int uu_strtoint(const char *, void *, size_t, int, int64_t, int64_t);
+extern int uu_strtouint(const char *, void *, size_t, int, uint64_t, uint64_t);
+
+/*
+ * Debug print facility functions.
+ */
+typedef struct uu_dprintf uu_dprintf_t;
+
+typedef enum {
+	UU_DPRINTF_SILENT,
+	UU_DPRINTF_FATAL,
+	UU_DPRINTF_WARNING,
+	UU_DPRINTF_NOTICE,
+	UU_DPRINTF_INFO,
+	UU_DPRINTF_DEBUG
+} uu_dprintf_severity_t;
+
+extern uu_dprintf_t *uu_dprintf_create(const char *, uu_dprintf_severity_t,
+    uint_t);
+/*PRINTFLIKE3*/
+extern void uu_dprintf(uu_dprintf_t *, uu_dprintf_severity_t,
+    const char *, ...);
+extern void uu_dprintf_destroy(uu_dprintf_t *);
+extern const char *uu_dprintf_getname(uu_dprintf_t *);
+
+/*
+ * Identifier test flags and function.
+ */
+#define	UU_NAME_DOMAIN		0x1	/* allow SUNW, or com.sun, prefix */
+#define	UU_NAME_PATH		0x2	/* allow '/'-delimited paths */
+
+int uu_check_name(const char *, uint_t);
+
+/*
+ * File creation functions.
+ */
+extern int uu_open_tmp(const char *dir, uint_t uflags);
+
+/*
+ * Convenience functions.
+ */
+#define	UU_NELEM(a)	(sizeof (a) / sizeof ((a)[0]))
+
+/*PRINTFLIKE1*/
+extern char *uu_msprintf(const char *format, ...);
+extern void *uu_zalloc(size_t);
+extern char *uu_strdup(const char *);
+extern void uu_free(void *);
+
+extern boolean_t uu_strcaseeq(const char *a, const char *b);
+extern boolean_t uu_streq(const char *a, const char *b);
+extern char *uu_strndup(const char *s, size_t n);
+extern boolean_t uu_strbw(const char *a, const char *b);
+extern void *uu_memdup(const void *buf, size_t sz);
+extern void uu_dump(FILE *out, const char *prefix, const void *buf, size_t len);
+
+/*
+ * Comparison function type definition.
+ *   Developers should be careful in their use of the _private argument. If you
+ *   break interface guarantees, you get undefined behavior.
+ */
+typedef int uu_compare_fn_t(const void *__left, const void *__right,
+    void *__private);
+
+/*
+ * Walk variant flags.
+ *   A data structure need not provide support for all variants and
+ *   combinations.  Refer to the appropriate documentation.
+ */
+#define	UU_WALK_ROBUST		0x00000001	/* walk can survive removes */
+#define	UU_WALK_REVERSE		0x00000002	/* reverse walk order */
+
+#define	UU_WALK_PREORDER	0x00000010	/* walk tree in pre-order */
+#define	UU_WALK_POSTORDER	0x00000020	/* walk tree in post-order */
+
+/*
+ * Walk callback function return codes.
+ */
+#define	UU_WALK_ERROR		-1
+#define	UU_WALK_NEXT		0
+#define	UU_WALK_DONE		1
+
+/*
+ * Walk callback function type definition.
+ */
+typedef int uu_walk_fn_t(void *_elem, void *_private);
+
+/*
+ * lists: opaque structures
+ */
+typedef struct uu_list_pool uu_list_pool_t;
+typedef struct uu_list uu_list_t;
+
+typedef struct uu_list_node {
+	uintptr_t uln_opaque[2];
+} uu_list_node_t;
+
+typedef struct uu_list_walk uu_list_walk_t;
+
+typedef uintptr_t uu_list_index_t;
+
+/*
+ * lists: interface
+ *
+ * basic usage:
+ *	typedef struct foo {
+ *		...
+ *		uu_list_node_t foo_node;
+ *		...
+ *	} foo_t;
+ *
+ *	static int
+ *	foo_compare(void *l_arg, void *r_arg, void *private)
+ *	{
+ *		foo_t *l = l_arg;
+ *		foo_t *r = r_arg;
+ *
+ *		if (... l greater than r ...)
+ *			return (1);
+ *		if (... l less than r ...)
+ *			return (-1);
+ *		return (0);
+ *	}
+ *
+ *	...
+ *		// at initialization time
+ *		foo_pool = uu_list_pool_create("foo_pool",
+ *		    sizeof (foo_t), offsetof(foo_t, foo_node), foo_compare,
+ *		    debugging? 0 : UU_AVL_POOL_DEBUG);
+ *	...
+ */
+uu_list_pool_t *uu_list_pool_create(const char *, size_t, size_t,
+    uu_compare_fn_t *, uint32_t);
+#define	UU_LIST_POOL_DEBUG	0x00000001
+
+void uu_list_pool_destroy(uu_list_pool_t *);
+
+/*
+ * usage:
+ *
+ *	foo_t *a;
+ *	a = malloc(sizeof(*a));
+ *	uu_list_node_init(a, &a->foo_list, pool);
+ *	...
+ *	uu_list_node_fini(a, &a->foo_list, pool);
+ *	free(a);
+ */
+void uu_list_node_init(void *, uu_list_node_t *, uu_list_pool_t *);
+void uu_list_node_fini(void *, uu_list_node_t *, uu_list_pool_t *);
+
+uu_list_t *uu_list_create(uu_list_pool_t *, void *_parent, uint32_t);
+#define	UU_LIST_DEBUG	0x00000001
+#define	UU_LIST_SORTED	0x00000002	/* list is sorted */
+
+void uu_list_destroy(uu_list_t *);	/* list must be empty */
+
+size_t uu_list_numnodes(uu_list_t *);
+
+void *uu_list_first(uu_list_t *);
+void *uu_list_last(uu_list_t *);
+
+void *uu_list_next(uu_list_t *, void *);
+void *uu_list_prev(uu_list_t *, void *);
+
+int uu_list_walk(uu_list_t *, uu_walk_fn_t *, void *, uint32_t);
+
+uu_list_walk_t *uu_list_walk_start(uu_list_t *, uint32_t);
+void *uu_list_walk_next(uu_list_walk_t *);
+void uu_list_walk_end(uu_list_walk_t *);
+
+void *uu_list_find(uu_list_t *, void *, void *, uu_list_index_t *);
+void uu_list_insert(uu_list_t *, void *, uu_list_index_t);
+
+void *uu_list_nearest_next(uu_list_t *, uu_list_index_t);
+void *uu_list_nearest_prev(uu_list_t *, uu_list_index_t);
+
+void *uu_list_teardown(uu_list_t *, void **);
+
+void uu_list_remove(uu_list_t *, void *);
+
+/*
+ * lists: interfaces for non-sorted lists only
+ */
+int uu_list_insert_before(uu_list_t *, void *_target, void *_elem);
+int uu_list_insert_after(uu_list_t *, void *_target, void *_elem);
+
+/*
+ * avl trees: opaque structures
+ */
+typedef struct uu_avl_pool uu_avl_pool_t;
+typedef struct uu_avl uu_avl_t;
+
+typedef struct uu_avl_node {
+#ifdef _LP64
+	uintptr_t uan_opaque[3];
+#else
+	uintptr_t uan_opaque[4];
+#endif
+} uu_avl_node_t;
+
+typedef struct uu_avl_walk uu_avl_walk_t;
+
+typedef uintptr_t uu_avl_index_t;
+
+/*
+ * avl trees: interface
+ *
+ * basic usage:
+ *	typedef struct foo {
+ *		...
+ *		uu_avl_node_t foo_node;
+ *		...
+ *	} foo_t;
+ *
+ *	static int
+ *	foo_compare(void *l_arg, void *r_arg, void *private)
+ *	{
+ *		foo_t *l = l_arg;
+ *		foo_t *r = r_arg;
+ *
+ *		if (... l greater than r ...)
+ *			return (1);
+ *		if (... l less than r ...)
+ *			return (-1);
+ *		return (0);
+ *	}
+ *
+ *	...
+ *		// at initialization time
+ *		foo_pool = uu_avl_pool_create("foo_pool",
+ *		    sizeof (foo_t), offsetof(foo_t, foo_node), foo_compare,
+ *		    debugging? 0 : UU_AVL_POOL_DEBUG);
+ *	...
+ */
+uu_avl_pool_t *uu_avl_pool_create(const char *, size_t, size_t,
+    uu_compare_fn_t *, uint32_t);
+#define	UU_AVL_POOL_DEBUG	0x00000001
+
+void uu_avl_pool_destroy(uu_avl_pool_t *);
+
+/*
+ * usage:
+ *
+ *	foo_t *a;
+ *	a = malloc(sizeof(*a));
+ *	uu_avl_node_init(a, &a->foo_avl, pool);
+ *	...
+ *	uu_avl_node_fini(a, &a->foo_avl, pool);
+ *	free(a);
+ */
+void uu_avl_node_init(void *, uu_avl_node_t *, uu_avl_pool_t *);
+void uu_avl_node_fini(void *, uu_avl_node_t *, uu_avl_pool_t *);
+
+uu_avl_t *uu_avl_create(uu_avl_pool_t *, void *_parent, uint32_t);
+#define	UU_AVL_DEBUG	0x00000001
+
+void uu_avl_destroy(uu_avl_t *);	/* list must be empty */
+
+size_t uu_avl_numnodes(uu_avl_t *);
+
+void *uu_avl_first(uu_avl_t *);
+void *uu_avl_last(uu_avl_t *);
+
+void *uu_avl_next(uu_avl_t *, void *);
+void *uu_avl_prev(uu_avl_t *, void *);
+
+int uu_avl_walk(uu_avl_t *, uu_walk_fn_t *, void *, uint32_t);
+
+uu_avl_walk_t *uu_avl_walk_start(uu_avl_t *, uint32_t);
+void *uu_avl_walk_next(uu_avl_walk_t *);
+void uu_avl_walk_end(uu_avl_walk_t *);
+
+void *uu_avl_find(uu_avl_t *, void *, void *, uu_avl_index_t *);
+void uu_avl_insert(uu_avl_t *, void *, uu_avl_index_t);
+
+void *uu_avl_nearest_next(uu_avl_t *, uu_avl_index_t);
+void *uu_avl_nearest_prev(uu_avl_t *, uu_avl_index_t);
+
+void *uu_avl_teardown(uu_avl_t *, void **);
+
+void uu_avl_remove(uu_avl_t *, void *);
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* _LIBUUTIL_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/include/libuutil_common.h
@@ -0,0 +1,35 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef	_LIBUUTIL_COMMON_H
+#define	_LIBUUTIL_COMMON_H
+
+
+
+#include <libuutil.h>
+#include <libuutil_impl.h>
+
+#endif	/* _LIBUUTIL_COMMON_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/include/libuutil_impl.h
@@ -0,0 +1,181 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License").  You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef	_LIBUUTIL_IMPL_H
+#define	_LIBUUTIL_IMPL_H
+
+
+
+#include <libuutil.h>
+#include <pthread.h>
+
+#include <sys/avl_impl.h>
+#include <sys/byteorder.h>
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+void uu_set_error(uint_t);
+
+
+/*PRINTFLIKE1*/
+void uu_panic(const char *format, ...);
+
+
+struct uu_dprintf {
+	char	*uud_name;
+	uu_dprintf_severity_t uud_severity;
+	uint_t	uud_flags;
+};
+
+/*
+ * For debugging purposes, libuutil keeps around linked lists of all uu_lists
+ * and uu_avls, along with pointers to their parents.  These can cause false
+ * negatives when looking for memory leaks, so we encode the pointers by
+ * storing them with swapped endianness;  this is not perfect, but it's about
+ * the best we can do without wasting a lot of space.
+ */
+#ifdef _LP64
+#define	UU_PTR_ENCODE(ptr)		BSWAP_64((uintptr_t)(void *)(ptr))
+#else
+#define	UU_PTR_ENCODE(ptr)		BSWAP_32((uintptr_t)(void *)(ptr))
+#endif
+
+#define	UU_PTR_DECODE(ptr)		((void *)UU_PTR_ENCODE(ptr))
+
+/*
+ * uu_list structures
+ */
+typedef struct uu_list_node_impl {
+	struct uu_list_node_impl *uln_next;
+	struct uu_list_node_impl *uln_prev;
+} uu_list_node_impl_t;
+
+struct uu_list_walk {
+	uu_list_walk_t	*ulw_next;
+	uu_list_walk_t	*ulw_prev;
+
+	uu_list_t	*ulw_list;
+	int8_t		ulw_dir;
+	uint8_t		ulw_robust;
+	uu_list_node_impl_t *ulw_next_result;
+};
+
+struct uu_list {
+	uintptr_t	ul_next_enc;
+	uintptr_t	ul_prev_enc;
+
+	uu_list_pool_t	*ul_pool;
+	uintptr_t	ul_parent_enc;	/* encoded parent pointer */
+	size_t		ul_offset;
+	size_t		ul_numnodes;
+	uint8_t		ul_debug;
+	uint8_t		ul_sorted;
+	uint8_t		ul_index;	/* mark for uu_list_index_ts */
+
+	uu_list_node_impl_t ul_null_node;
+	uu_list_walk_t	ul_null_walk;	/* for robust walkers */
+};
+
+#define	UU_LIST_PTR(ptr)		((uu_list_t *)UU_PTR_DECODE(ptr))
+
+#define	UU_LIST_POOL_MAXNAME	64
+
+struct uu_list_pool {
+	uu_list_pool_t	*ulp_next;
+	uu_list_pool_t	*ulp_prev;
+
+	char		ulp_name[UU_LIST_POOL_MAXNAME];
+	size_t		ulp_nodeoffset;
+	size_t		ulp_objsize;
+	uu_compare_fn_t	*ulp_cmp;
+	uint8_t		ulp_debug;
+	uint8_t		ulp_last_index;
+	pthread_mutex_t	ulp_lock;		/* protects null_list */
+	uu_list_t	ulp_null_list;
+};
+
+/*
+ * uu_avl structures
+ */
+typedef struct avl_node		uu_avl_node_impl_t;
+
+struct uu_avl_walk {
+	uu_avl_walk_t	*uaw_next;
+	uu_avl_walk_t	*uaw_prev;
+
+	uu_avl_t	*uaw_avl;
+	void		*uaw_next_result;
+	int8_t		uaw_dir;
+	uint8_t		uaw_robust;
+};
+
+struct uu_avl {
+	uintptr_t	ua_next_enc;
+	uintptr_t	ua_prev_enc;
+
+	uu_avl_pool_t	*ua_pool;
+	uintptr_t	ua_parent_enc;
+	uint8_t		ua_debug;
+	uint8_t		ua_index;	/* mark for uu_avl_index_ts */
+
+	struct avl_tree	ua_tree;
+	uu_avl_walk_t	ua_null_walk;
+};
+
+#define	UU_AVL_PTR(x)		((uu_avl_t *)UU_PTR_DECODE(x))
+
+#define	UU_AVL_POOL_MAXNAME	64
+
+struct uu_avl_pool {
+	uu_avl_pool_t	*uap_next;
+	uu_avl_pool_t	*uap_prev;
+
+	char		uap_name[UU_AVL_POOL_MAXNAME];
+	size_t		uap_nodeoffset;
+	size_t		uap_objsize;
+	uu_compare_fn_t	*uap_cmp;
+	uint8_t		uap_debug;
+	uint8_t		uap_last_index;
+	pthread_mutex_t	uap_lock;		/* protects null_avl */
+	uu_avl_t	uap_null_avl;
+};
+
+/*
+ * atfork() handlers
+ */
+void uu_avl_lockup(void);
+void uu_avl_release(void);
+
+void uu_list_lockup(void);
+void uu_list_release(void);
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* _LIBUUTIL_IMPL_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/include/libzfs.h
@@ -0,0 +1,805 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013 by Delphix. All rights reserved.
+ * Copyright (c) 2012, Joyent, Inc. All rights reserved.
+ * Copyright (c) 2013 Steven Hartland. All rights reserved.
+ * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
+ */
+
+#ifndef	_LIBZFS_H
+#define	_LIBZFS_H
+
+#include <assert.h>
+#include <libnvpair.h>
+#include <sys/mnttab.h>
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/varargs.h>
+#include <sys/fs/zfs.h>
+#include <sys/avl.h>
+#include <ucred.h>
+#include <libzfs_core.h>
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+/*
+ * Miscellaneous ZFS constants
+ */
+#define	ZFS_MAXNAMELEN		MAXNAMELEN
+#define	ZPOOL_MAXNAMELEN	MAXNAMELEN
+#define	ZFS_MAXPROPLEN		MAXPATHLEN
+#define	ZPOOL_MAXPROPLEN	MAXPATHLEN
+
+/*
+ * Default device paths
+ */
+#define	DISK_ROOT		"/dev"
+#define	UDISK_ROOT		"/dev/disk"
+
+/*
+ * Default wait time for a device name to be created.
+ */
+#define	DISK_LABEL_WAIT		(30 * 1000)  /* 30 seconds */
+
+#define	DEFAULT_IMPORT_PATH_SIZE	7
+extern char *zpool_default_import_path[DEFAULT_IMPORT_PATH_SIZE];
+
+/*
+ * libzfs errors
+ */
+typedef enum zfs_error {
+	EZFS_SUCCESS = 0,	/* no error -- success */
+	EZFS_NOMEM = 2000,	/* out of memory */
+	EZFS_BADPROP,		/* invalid property value */
+	EZFS_PROPREADONLY,	/* cannot set readonly property */
+	EZFS_PROPTYPE,		/* property does not apply to dataset type */
+	EZFS_PROPNONINHERIT,	/* property is not inheritable */
+	EZFS_PROPSPACE,		/* bad quota or reservation */
+	EZFS_BADTYPE,		/* dataset is not of appropriate type */
+	EZFS_BUSY,		/* pool or dataset is busy */
+	EZFS_EXISTS,		/* pool or dataset already exists */
+	EZFS_NOENT,		/* no such pool or dataset */
+	EZFS_BADSTREAM,		/* bad backup stream */
+	EZFS_DSREADONLY,	/* dataset is readonly */
+	EZFS_VOLTOOBIG,		/* volume is too large for 32-bit system */
+	EZFS_INVALIDNAME,	/* invalid dataset name */
+	EZFS_BADRESTORE,	/* unable to restore to destination */
+	EZFS_BADBACKUP,		/* backup failed */
+	EZFS_BADTARGET,		/* bad attach/detach/replace target */
+	EZFS_NODEVICE,		/* no such device in pool */
+	EZFS_BADDEV,		/* invalid device to add */
+	EZFS_NOREPLICAS,	/* no valid replicas */
+	EZFS_RESILVERING,	/* currently resilvering */
+	EZFS_BADVERSION,	/* unsupported version */
+	EZFS_POOLUNAVAIL,	/* pool is currently unavailable */
+	EZFS_DEVOVERFLOW,	/* too many devices in one vdev */
+	EZFS_BADPATH,		/* must be an absolute path */
+	EZFS_CROSSTARGET,	/* rename or clone across pool or dataset */
+	EZFS_ZONED,		/* used improperly in local zone */
+	EZFS_MOUNTFAILED,	/* failed to mount dataset */
+	EZFS_UMOUNTFAILED,	/* failed to unmount dataset */
+	EZFS_UNSHARENFSFAILED,	/* unshare(1M) failed */
+	EZFS_SHARENFSFAILED,	/* share(1M) failed */
+	EZFS_PERM,		/* permission denied */
+	EZFS_NOSPC,		/* out of space */
+	EZFS_FAULT,		/* bad address */
+	EZFS_IO,		/* I/O error */
+	EZFS_INTR,		/* signal received */
+	EZFS_ISSPARE,		/* device is a hot spare */
+	EZFS_INVALCONFIG,	/* invalid vdev configuration */
+	EZFS_RECURSIVE,		/* recursive dependency */
+	EZFS_NOHISTORY,		/* no history object */
+	EZFS_POOLPROPS,		/* couldn't retrieve pool props */
+	EZFS_POOL_NOTSUP,	/* ops not supported for this type of pool */
+	EZFS_POOL_INVALARG,	/* invalid argument for this pool operation */
+	EZFS_NAMETOOLONG,	/* dataset name is too long */
+	EZFS_OPENFAILED,	/* open of device failed */
+	EZFS_NOCAP,		/* couldn't get capacity */
+	EZFS_LABELFAILED,	/* write of label failed */
+	EZFS_BADWHO,		/* invalid permission who */
+	EZFS_BADPERM,		/* invalid permission */
+	EZFS_BADPERMSET,	/* invalid permission set name */
+	EZFS_NODELEGATION,	/* delegated administration is disabled */
+	EZFS_UNSHARESMBFAILED,	/* failed to unshare over smb */
+	EZFS_SHARESMBFAILED,	/* failed to share over smb */
+	EZFS_BADCACHE,		/* bad cache file */
+	EZFS_ISL2CACHE,		/* device is for the level 2 ARC */
+	EZFS_VDEVNOTSUP,	/* unsupported vdev type */
+	EZFS_NOTSUP,		/* ops not supported on this dataset */
+	EZFS_ACTIVE_SPARE,	/* pool has active shared spare devices */
+	EZFS_UNPLAYED_LOGS,	/* log device has unplayed logs */
+	EZFS_REFTAG_RELE,	/* snapshot release: tag not found */
+	EZFS_REFTAG_HOLD,	/* snapshot hold: tag already exists */
+	EZFS_TAGTOOLONG,	/* snapshot hold/rele: tag too long */
+	EZFS_PIPEFAILED,	/* pipe create failed */
+	EZFS_THREADCREATEFAILED, /* thread create failed */
+	EZFS_POSTSPLIT_ONLINE,	/* onlining a disk after splitting it */
+	EZFS_SCRUBBING,		/* currently scrubbing */
+	EZFS_NO_SCRUB,		/* no active scrub */
+	EZFS_DIFF,		/* general failure of zfs diff */
+	EZFS_DIFFDATA,		/* bad zfs diff data */
+	EZFS_POOLREADONLY,	/* pool is in read-only mode */
+	EZFS_UNKNOWN
+} zfs_error_t;
+
+/*
+ * The following data structures are all part
+ * of the zfs_allow_t data structure which is
+ * used for printing 'allow' permissions.
+ * It is a linked list of zfs_allow_t's which
+ * then contain avl tree's for user/group/sets/...
+ * and each one of the entries in those trees have
+ * avl tree's for the permissions they belong to and
+ * whether they are local,descendent or local+descendent
+ * permissions.  The AVL trees are used primarily for
+ * sorting purposes, but also so that we can quickly find
+ * a given user and or permission.
+ */
+typedef struct zfs_perm_node {
+	avl_node_t z_node;
+	char z_pname[MAXPATHLEN];
+} zfs_perm_node_t;
+
+typedef struct zfs_allow_node {
+	avl_node_t z_node;
+	char z_key[MAXPATHLEN];		/* name, such as joe */
+	avl_tree_t z_localdescend;	/* local+descendent perms */
+	avl_tree_t z_local;		/* local permissions */
+	avl_tree_t z_descend;		/* descendent permissions */
+} zfs_allow_node_t;
+
+typedef struct zfs_allow {
+	struct zfs_allow *z_next;
+	char z_setpoint[MAXPATHLEN];
+	avl_tree_t z_sets;
+	avl_tree_t z_crperms;
+	avl_tree_t z_user;
+	avl_tree_t z_group;
+	avl_tree_t z_everyone;
+} zfs_allow_t;
+
+/*
+ * Basic handle types
+ */
+typedef struct zfs_handle zfs_handle_t;
+typedef struct zpool_handle zpool_handle_t;
+typedef struct libzfs_handle libzfs_handle_t;
+
+/*
+ * Library initialization
+ */
+extern libzfs_handle_t *libzfs_init(void);
+extern void libzfs_fini(libzfs_handle_t *);
+
+extern libzfs_handle_t *zpool_get_handle(zpool_handle_t *);
+extern libzfs_handle_t *zfs_get_handle(zfs_handle_t *);
+
+extern void libzfs_print_on_error(libzfs_handle_t *, boolean_t);
+
+extern void zfs_save_arguments(int argc, char **, char *, int);
+extern int zpool_log_history(libzfs_handle_t *, const char *);
+
+extern int libzfs_errno(libzfs_handle_t *);
+extern const char *libzfs_error_init(int);
+extern const char *libzfs_error_action(libzfs_handle_t *);
+extern const char *libzfs_error_description(libzfs_handle_t *);
+extern int zfs_standard_error(libzfs_handle_t *, int, const char *);
+extern void libzfs_mnttab_init(libzfs_handle_t *);
+extern void libzfs_mnttab_fini(libzfs_handle_t *);
+extern void libzfs_mnttab_cache(libzfs_handle_t *, boolean_t);
+extern int libzfs_mnttab_find(libzfs_handle_t *, const char *,
+    struct mnttab *);
+extern void libzfs_mnttab_add(libzfs_handle_t *, const char *,
+    const char *, const char *);
+extern void libzfs_mnttab_remove(libzfs_handle_t *, const char *);
+
+/*
+ * Basic handle functions
+ */
+extern zpool_handle_t *zpool_open(libzfs_handle_t *, const char *);
+extern zpool_handle_t *zpool_open_canfail(libzfs_handle_t *, const char *);
+extern void zpool_close(zpool_handle_t *);
+extern const char *zpool_get_name(zpool_handle_t *);
+extern int zpool_get_state(zpool_handle_t *);
+extern char *zpool_state_to_name(vdev_state_t, vdev_aux_t);
+extern const char *zpool_pool_state_to_name(pool_state_t);
+extern void zpool_free_handles(libzfs_handle_t *);
+
+/*
+ * Iterate over all active pools in the system.
+ */
+typedef int (*zpool_iter_f)(zpool_handle_t *, void *);
+extern int zpool_iter(libzfs_handle_t *, zpool_iter_f, void *);
+
+/*
+ * Functions to create and destroy pools
+ */
+extern int zpool_create(libzfs_handle_t *, const char *, nvlist_t *,
+    nvlist_t *, nvlist_t *);
+extern int zpool_destroy(zpool_handle_t *, const char *);
+extern int zpool_add(zpool_handle_t *, nvlist_t *);
+
+typedef struct splitflags {
+	/* do not split, but return the config that would be split off */
+	int dryrun : 1;
+
+	/* after splitting, import the pool */
+	int import : 1;
+	int name_flags;
+} splitflags_t;
+
+/*
+ * Functions to manipulate pool and vdev state
+ */
+extern int zpool_scan(zpool_handle_t *, pool_scan_func_t);
+extern int zpool_clear(zpool_handle_t *, const char *, nvlist_t *);
+extern int zpool_reguid(zpool_handle_t *);
+extern int zpool_reopen(zpool_handle_t *);
+
+extern int zpool_vdev_online(zpool_handle_t *, const char *, int,
+    vdev_state_t *);
+extern int zpool_vdev_offline(zpool_handle_t *, const char *, boolean_t);
+extern int zpool_vdev_attach(zpool_handle_t *, const char *,
+    const char *, nvlist_t *, int);
+extern int zpool_vdev_detach(zpool_handle_t *, const char *);
+extern int zpool_vdev_remove(zpool_handle_t *, const char *);
+extern int zpool_vdev_split(zpool_handle_t *, char *, nvlist_t **, nvlist_t *,
+    splitflags_t);
+
+extern int zpool_vdev_fault(zpool_handle_t *, uint64_t, vdev_aux_t);
+extern int zpool_vdev_degrade(zpool_handle_t *, uint64_t, vdev_aux_t);
+extern int zpool_vdev_clear(zpool_handle_t *, uint64_t);
+
+extern nvlist_t *zpool_find_vdev(zpool_handle_t *, const char *, boolean_t *,
+    boolean_t *, boolean_t *);
+extern nvlist_t *zpool_find_vdev_by_physpath(zpool_handle_t *, const char *,
+    boolean_t *, boolean_t *, boolean_t *);
+extern int zpool_label_disk_wait(char *, int);
+extern int zpool_label_disk(libzfs_handle_t *, zpool_handle_t *, char *);
+
+/*
+ * Functions to manage pool properties
+ */
+extern int zpool_set_prop(zpool_handle_t *, const char *, const char *);
+extern int zpool_get_prop(zpool_handle_t *, zpool_prop_t, char *,
+    size_t proplen, zprop_source_t *);
+extern int zpool_get_prop_literal(zpool_handle_t *, zpool_prop_t, char *,
+    size_t proplen, zprop_source_t *, boolean_t literal);
+extern uint64_t zpool_get_prop_int(zpool_handle_t *, zpool_prop_t,
+    zprop_source_t *);
+
+extern const char *zpool_prop_to_name(zpool_prop_t);
+extern const char *zpool_prop_values(zpool_prop_t);
+
+/*
+ * Pool health statistics.
+ */
+typedef enum {
+	/*
+	 * The following correspond to faults as defined in the (fault.fs.zfs.*)
+	 * event namespace.  Each is associated with a corresponding message ID.
+	 */
+	ZPOOL_STATUS_CORRUPT_CACHE,	/* corrupt /kernel/drv/zpool.cache */
+	ZPOOL_STATUS_MISSING_DEV_R,	/* missing device with replicas */
+	ZPOOL_STATUS_MISSING_DEV_NR,	/* missing device with no replicas */
+	ZPOOL_STATUS_CORRUPT_LABEL_R,	/* bad device label with replicas */
+	ZPOOL_STATUS_CORRUPT_LABEL_NR,	/* bad device label with no replicas */
+	ZPOOL_STATUS_BAD_GUID_SUM,	/* sum of device guids didn't match */
+	ZPOOL_STATUS_CORRUPT_POOL,	/* pool metadata is corrupted */
+	ZPOOL_STATUS_CORRUPT_DATA,	/* data errors in user (meta)data */
+	ZPOOL_STATUS_FAILING_DEV,	/* device experiencing errors */
+	ZPOOL_STATUS_VERSION_NEWER,	/* newer on-disk version */
+	ZPOOL_STATUS_HOSTID_MISMATCH,	/* last accessed by another system */
+	ZPOOL_STATUS_IO_FAILURE_WAIT,	/* failed I/O, failmode 'wait' */
+	ZPOOL_STATUS_IO_FAILURE_CONTINUE, /* failed I/O, failmode 'continue' */
+	ZPOOL_STATUS_BAD_LOG,		/* cannot read log chain(s) */
+	ZPOOL_STATUS_ERRATA,		/* informational errata available */
+
+	/*
+	 * If the pool has unsupported features but can still be opened in
+	 * read-only mode, its status is ZPOOL_STATUS_UNSUP_FEAT_WRITE. If the
+	 * pool has unsupported features but cannot be opened at all, its
+	 * status is ZPOOL_STATUS_UNSUP_FEAT_READ.
+	 */
+	ZPOOL_STATUS_UNSUP_FEAT_READ,	/* unsupported features for read */
+	ZPOOL_STATUS_UNSUP_FEAT_WRITE,	/* unsupported features for write */
+
+	/*
+	 * These faults have no corresponding message ID.  At the time we are
+	 * checking the status, the original reason for the FMA fault (I/O or
+	 * checksum errors) has been lost.
+	 */
+	ZPOOL_STATUS_FAULTED_DEV_R,	/* faulted device with replicas */
+	ZPOOL_STATUS_FAULTED_DEV_NR,	/* faulted device with no replicas */
+
+	/*
+	 * The following are not faults per se, but still an error possibly
+	 * requiring administrative attention.  There is no corresponding
+	 * message ID.
+	 */
+	ZPOOL_STATUS_VERSION_OLDER,	/* older legacy on-disk version */
+	ZPOOL_STATUS_FEAT_DISABLED,	/* supported features are disabled */
+	ZPOOL_STATUS_RESILVERING,	/* device being resilvered */
+	ZPOOL_STATUS_OFFLINE_DEV,	/* device online */
+	ZPOOL_STATUS_REMOVED_DEV,	/* removed device */
+
+	/*
+	 * Finally, the following indicates a healthy pool.
+	 */
+	ZPOOL_STATUS_OK
+} zpool_status_t;
+
+extern unsigned long get_system_hostid(void);
+extern zpool_status_t zpool_get_status(zpool_handle_t *, char **,
+    zpool_errata_t *);
+extern zpool_status_t zpool_import_status(nvlist_t *, char **,
+    zpool_errata_t *);
+extern void zpool_dump_ddt(const ddt_stat_t *dds, const ddt_histogram_t *ddh);
+
+/*
+ * Statistics and configuration functions.
+ */
+extern nvlist_t *zpool_get_config(zpool_handle_t *, nvlist_t **);
+extern nvlist_t *zpool_get_features(zpool_handle_t *);
+extern int zpool_refresh_stats(zpool_handle_t *, boolean_t *);
+extern int zpool_get_errlog(zpool_handle_t *, nvlist_t **);
+
+/*
+ * Import and export functions
+ */
+extern int zpool_export(zpool_handle_t *, boolean_t, const char *);
+extern int zpool_export_force(zpool_handle_t *, const char *);
+extern int zpool_import(libzfs_handle_t *, nvlist_t *, const char *,
+    char *altroot);
+extern int zpool_import_props(libzfs_handle_t *, nvlist_t *, const char *,
+    nvlist_t *, int);
+extern void zpool_print_unsup_feat(nvlist_t *config);
+
+/*
+ * Search for pools to import
+ */
+
+typedef struct importargs {
+	char **path;		/* a list of paths to search		*/
+	int paths;		/* number of paths to search		*/
+	char *poolname;		/* name of a pool to find		*/
+	uint64_t guid;		/* guid of a pool to find		*/
+	char *cachefile;	/* cachefile to use for import		*/
+	int can_be_active : 1;	/* can the pool be active?		*/
+	int unique : 1;		/* does 'poolname' already exist?	*/
+	int exists : 1;		/* set on return if pool already exists	*/
+} importargs_t;
+
+extern nvlist_t *zpool_search_import(libzfs_handle_t *, importargs_t *);
+
+/* legacy pool search routines */
+extern nvlist_t *zpool_find_import(libzfs_handle_t *, int, char **);
+extern nvlist_t *zpool_find_import_cached(libzfs_handle_t *, const char *,
+    char *, uint64_t);
+
+/*
+ * Miscellaneous pool functions
+ */
+struct zfs_cmd;
+
+extern const char *zfs_history_event_names[];
+
+typedef enum {
+	VDEV_NAME_PATH		= 1 << 0,
+	VDEV_NAME_GUID		= 1 << 1,
+	VDEV_NAME_FOLLOW_LINKS	= 1 << 2,
+	VDEV_NAME_TYPE_ID	= 1 << 3,
+} vdev_name_t;
+
+extern char *zpool_vdev_name(libzfs_handle_t *, zpool_handle_t *, nvlist_t *,
+    int name_flags);
+extern int zpool_upgrade(zpool_handle_t *, uint64_t);
+extern int zpool_get_history(zpool_handle_t *, nvlist_t **);
+extern int zpool_history_unpack(char *, uint64_t, uint64_t *,
+    nvlist_t ***, uint_t *);
+extern int zpool_events_next(libzfs_handle_t *, nvlist_t **, int *, unsigned,
+    int);
+extern int zpool_events_clear(libzfs_handle_t *, int *);
+extern int zpool_events_seek(libzfs_handle_t *, uint64_t, int);
+extern void zpool_obj_to_path(zpool_handle_t *, uint64_t, uint64_t, char *,
+    size_t len);
+extern int zfs_ioctl(libzfs_handle_t *, int, struct zfs_cmd *);
+extern int zpool_get_physpath(zpool_handle_t *, char *, size_t);
+extern void zpool_explain_recover(libzfs_handle_t *, const char *, int,
+    nvlist_t *);
+
+/*
+ * Basic handle manipulations.  These functions do not create or destroy the
+ * underlying datasets, only the references to them.
+ */
+extern zfs_handle_t *zfs_open(libzfs_handle_t *, const char *, int);
+extern zfs_handle_t *zfs_handle_dup(zfs_handle_t *);
+extern void zfs_close(zfs_handle_t *);
+extern zfs_type_t zfs_get_type(const zfs_handle_t *);
+extern const char *zfs_get_name(const zfs_handle_t *);
+extern zpool_handle_t *zfs_get_pool_handle(const zfs_handle_t *);
+
+/*
+ * Property management functions.  Some functions are shared with the kernel,
+ * and are found in sys/fs/zfs.h.
+ */
+
+/*
+ * zfs dataset property management
+ */
+extern const char *zfs_prop_default_string(zfs_prop_t);
+extern uint64_t zfs_prop_default_numeric(zfs_prop_t);
+extern const char *zfs_prop_column_name(zfs_prop_t);
+extern boolean_t zfs_prop_align_right(zfs_prop_t);
+
+extern nvlist_t *zfs_valid_proplist(libzfs_handle_t *, zfs_type_t,
+    nvlist_t *, uint64_t, zfs_handle_t *, const char *);
+
+extern const char *zfs_prop_to_name(zfs_prop_t);
+extern int zfs_prop_set(zfs_handle_t *, const char *, const char *);
+extern int zfs_prop_get(zfs_handle_t *, zfs_prop_t, char *, size_t,
+    zprop_source_t *, char *, size_t, boolean_t);
+extern int zfs_prop_get_recvd(zfs_handle_t *, const char *, char *, size_t,
+    boolean_t);
+extern int zfs_prop_get_numeric(zfs_handle_t *, zfs_prop_t, uint64_t *,
+    zprop_source_t *, char *, size_t);
+extern int zfs_prop_get_userquota_int(zfs_handle_t *zhp, const char *propname,
+    uint64_t *propvalue);
+extern int zfs_prop_get_userquota(zfs_handle_t *zhp, const char *propname,
+    char *propbuf, int proplen, boolean_t literal);
+extern int zfs_prop_get_written_int(zfs_handle_t *zhp, const char *propname,
+    uint64_t *propvalue);
+extern int zfs_prop_get_written(zfs_handle_t *zhp, const char *propname,
+    char *propbuf, int proplen, boolean_t literal);
+extern int zfs_prop_get_feature(zfs_handle_t *zhp, const char *propname,
+    char *buf, size_t len);
+extern uint64_t getprop_uint64(zfs_handle_t *, zfs_prop_t, char **);
+extern uint64_t zfs_prop_get_int(zfs_handle_t *, zfs_prop_t);
+extern int zfs_prop_inherit(zfs_handle_t *, const char *, boolean_t);
+extern const char *zfs_prop_values(zfs_prop_t);
+extern int zfs_prop_is_string(zfs_prop_t prop);
+extern nvlist_t *zfs_get_user_props(zfs_handle_t *);
+extern nvlist_t *zfs_get_recvd_props(zfs_handle_t *);
+extern nvlist_t *zfs_get_clones_nvl(zfs_handle_t *);
+
+typedef struct zprop_list {
+	int		pl_prop;
+	char		*pl_user_prop;
+	struct zprop_list *pl_next;
+	boolean_t	pl_all;
+	size_t		pl_width;
+	size_t		pl_recvd_width;
+	boolean_t	pl_fixed;
+} zprop_list_t;
+
+extern int zfs_expand_proplist(zfs_handle_t *, zprop_list_t **, boolean_t,
+    boolean_t);
+extern void zfs_prune_proplist(zfs_handle_t *, uint8_t *);
+
+#define	ZFS_MOUNTPOINT_NONE	"none"
+#define	ZFS_MOUNTPOINT_LEGACY	"legacy"
+
+#define	ZFS_FEATURE_DISABLED	"disabled"
+#define	ZFS_FEATURE_ENABLED	"enabled"
+#define	ZFS_FEATURE_ACTIVE	"active"
+
+#define	ZFS_UNSUPPORTED_INACTIVE	"inactive"
+#define	ZFS_UNSUPPORTED_READONLY	"readonly"
+
+/*
+ * zpool property management
+ */
+extern int zpool_expand_proplist(zpool_handle_t *, zprop_list_t **);
+extern int zpool_prop_get_feature(zpool_handle_t *, const char *, char *,
+    size_t);
+extern const char *zpool_prop_default_string(zpool_prop_t);
+extern uint64_t zpool_prop_default_numeric(zpool_prop_t);
+extern const char *zpool_prop_column_name(zpool_prop_t);
+extern boolean_t zpool_prop_align_right(zpool_prop_t);
+
+/*
+ * Functions shared by zfs and zpool property management.
+ */
+extern int zprop_iter(zprop_func func, void *cb, boolean_t show_all,
+    boolean_t ordered, zfs_type_t type);
+extern int zprop_get_list(libzfs_handle_t *, char *, zprop_list_t **,
+    zfs_type_t);
+extern void zprop_free_list(zprop_list_t *);
+
+#define	ZFS_GET_NCOLS	5
+
+typedef enum {
+	GET_COL_NONE,
+	GET_COL_NAME,
+	GET_COL_PROPERTY,
+	GET_COL_VALUE,
+	GET_COL_RECVD,
+	GET_COL_SOURCE
+} zfs_get_column_t;
+
+/*
+ * Functions for printing zfs or zpool properties
+ */
+typedef struct zprop_get_cbdata {
+	int cb_sources;
+	zfs_get_column_t cb_columns[ZFS_GET_NCOLS];
+	int cb_colwidths[ZFS_GET_NCOLS + 1];
+	boolean_t cb_scripted;
+	boolean_t cb_literal;
+	boolean_t cb_first;
+	zprop_list_t *cb_proplist;
+	zfs_type_t cb_type;
+} zprop_get_cbdata_t;
+
+void zprop_print_one_property(const char *, zprop_get_cbdata_t *,
+    const char *, const char *, zprop_source_t, const char *,
+    const char *);
+
+/*
+ * Iterator functions.
+ */
+typedef int (*zfs_iter_f)(zfs_handle_t *, void *);
+extern int zfs_iter_root(libzfs_handle_t *, zfs_iter_f, void *);
+extern int zfs_iter_children(zfs_handle_t *, zfs_iter_f, void *);
+extern int zfs_iter_dependents(zfs_handle_t *, boolean_t, zfs_iter_f, void *);
+extern int zfs_iter_filesystems(zfs_handle_t *, zfs_iter_f, void *);
+extern int zfs_iter_snapshots(zfs_handle_t *, boolean_t, zfs_iter_f, void *);
+extern int zfs_iter_snapshots_sorted(zfs_handle_t *, zfs_iter_f, void *);
+extern int zfs_iter_snapspec(zfs_handle_t *, const char *, zfs_iter_f, void *);
+extern int zfs_iter_bookmarks(zfs_handle_t *, zfs_iter_f, void *);
+
+typedef struct get_all_cb {
+	zfs_handle_t	**cb_handles;
+	size_t		cb_alloc;
+	size_t		cb_used;
+	boolean_t	cb_verbose;
+	int		(*cb_getone)(zfs_handle_t *, void *);
+} get_all_cb_t;
+
+void libzfs_add_handle(get_all_cb_t *, zfs_handle_t *);
+int libzfs_dataset_cmp(const void *, const void *);
+
+/*
+ * Functions to create and destroy datasets.
+ */
+extern int zfs_create(libzfs_handle_t *, const char *, zfs_type_t,
+    nvlist_t *);
+extern int zfs_create_ancestors(libzfs_handle_t *, const char *);
+extern int zfs_destroy(zfs_handle_t *, boolean_t);
+extern int zfs_destroy_snaps(zfs_handle_t *, char *, boolean_t);
+extern int zfs_destroy_snaps_nvl(libzfs_handle_t *, nvlist_t *, boolean_t);
+extern int zfs_clone(zfs_handle_t *, const char *, nvlist_t *);
+extern int zfs_snapshot(libzfs_handle_t *, const char *, boolean_t, nvlist_t *);
+extern int zfs_snapshot_nvl(libzfs_handle_t *hdl, nvlist_t *snaps,
+    nvlist_t *props);
+extern int zfs_rollback(zfs_handle_t *, zfs_handle_t *, boolean_t);
+extern int zfs_rename(zfs_handle_t *, const char *, boolean_t, boolean_t);
+
+typedef struct sendflags {
+	/* print informational messages (ie, -v was specified) */
+	boolean_t verbose;
+
+	/* recursive send  (ie, -R) */
+	boolean_t replicate;
+
+	/* for incrementals, do all intermediate snapshots */
+	boolean_t doall;
+
+	/* if dataset is a clone, do incremental from its origin */
+	boolean_t fromorigin;
+
+	/* do deduplication */
+	boolean_t dedup;
+
+	/* send properties (ie, -p) */
+	boolean_t props;
+
+	/* do not send (no-op, ie. -n) */
+	boolean_t dryrun;
+
+	/* parsable verbose output (ie. -P) */
+	boolean_t parsable;
+
+	/* show progress (ie. -v) */
+	boolean_t progress;
+
+	/* large blocks (>128K) are permitted */
+	boolean_t largeblock;
+
+	/* WRITE_EMBEDDED records of type DATA are permitted */
+	boolean_t embed_data;
+} sendflags_t;
+
+typedef boolean_t (snapfilter_cb_t)(zfs_handle_t *, void *);
+
+extern int zfs_send(zfs_handle_t *, const char *, const char *,
+    sendflags_t *, int, snapfilter_cb_t, void *, nvlist_t **);
+extern int zfs_send_one(zfs_handle_t *, const char *, int, enum lzc_send_flags);
+
+extern int zfs_promote(zfs_handle_t *);
+extern int zfs_hold(zfs_handle_t *, const char *, const char *,
+    boolean_t, int);
+extern int zfs_hold_nvl(zfs_handle_t *, int, nvlist_t *);
+extern int zfs_release(zfs_handle_t *, const char *, const char *, boolean_t);
+extern int zfs_get_holds(zfs_handle_t *, nvlist_t **);
+extern uint64_t zvol_volsize_to_reservation(uint64_t, nvlist_t *);
+
+typedef int (*zfs_userspace_cb_t)(void *arg, const char *domain,
+    uid_t rid, uint64_t space);
+
+extern int zfs_userspace(zfs_handle_t *, zfs_userquota_prop_t,
+    zfs_userspace_cb_t, void *);
+
+extern int zfs_get_fsacl(zfs_handle_t *, nvlist_t **);
+extern int zfs_set_fsacl(zfs_handle_t *, boolean_t, nvlist_t *);
+
+typedef struct recvflags {
+	/* print informational messages (ie, -v was specified) */
+	boolean_t verbose;
+
+	/* the destination is a prefix, not the exact fs (ie, -d) */
+	boolean_t isprefix;
+
+	/*
+	 * Only the tail of the sent snapshot path is appended to the
+	 * destination to determine the received snapshot name (ie, -e).
+	 */
+	boolean_t istail;
+
+	/* do not actually do the recv, just check if it would work (ie, -n) */
+	boolean_t dryrun;
+
+	/* rollback/destroy filesystems as necessary (eg, -F) */
+	boolean_t force;
+
+	/* set "canmount=off" on all modified filesystems */
+	boolean_t canmountoff;
+
+	/* byteswap flag is used internally; callers need not specify */
+	boolean_t byteswap;
+
+	/* do not mount file systems as they are extracted (private) */
+	boolean_t nomount;
+} recvflags_t;
+
+extern int zfs_receive(libzfs_handle_t *, const char *, recvflags_t *,
+    int, avl_tree_t *);
+
+typedef enum diff_flags {
+	ZFS_DIFF_PARSEABLE = 0x1,
+	ZFS_DIFF_TIMESTAMP = 0x2,
+	ZFS_DIFF_CLASSIFY = 0x4
+} diff_flags_t;
+
+extern int zfs_show_diffs(zfs_handle_t *, int, const char *, const char *,
+    int);
+
+/*
+ * Miscellaneous functions.
+ */
+extern const char *zfs_type_to_name(zfs_type_t);
+extern void zfs_refresh_properties(zfs_handle_t *);
+extern int zfs_name_valid(const char *, zfs_type_t);
+extern zfs_handle_t *zfs_path_to_zhandle(libzfs_handle_t *, char *, zfs_type_t);
+extern boolean_t zfs_dataset_exists(libzfs_handle_t *, const char *,
+    zfs_type_t);
+extern int zfs_spa_version(zfs_handle_t *, int *);
+extern boolean_t zfs_bookmark_exists(const char *path);
+extern int zfs_append_partition(char *path, size_t max_len);
+extern int zfs_resolve_shortname(const char *name, char *path, size_t pathlen);
+extern int zfs_strcmp_pathname(char *name, char *cmp_name, int wholedisk);
+
+/*
+ * Mount support functions.
+ */
+extern boolean_t is_mounted(libzfs_handle_t *, const char *special, char **);
+extern boolean_t zfs_is_mounted(zfs_handle_t *, char **);
+extern int zfs_mount(zfs_handle_t *, const char *, int);
+extern int zfs_unmount(zfs_handle_t *, const char *, int);
+extern int zfs_unmountall(zfs_handle_t *, int);
+
+/*
+ * Share support functions.
+ */
+extern boolean_t zfs_is_shared(zfs_handle_t *);
+extern int zfs_share(zfs_handle_t *);
+extern int zfs_unshare(zfs_handle_t *);
+
+/*
+ * Protocol-specific share support functions.
+ */
+extern boolean_t zfs_is_shared_nfs(zfs_handle_t *, char **);
+extern boolean_t zfs_is_shared_smb(zfs_handle_t *, char **);
+extern int zfs_share_nfs(zfs_handle_t *);
+extern int zfs_share_smb(zfs_handle_t *);
+extern int zfs_shareall(zfs_handle_t *);
+extern int zfs_unshare_nfs(zfs_handle_t *, const char *);
+extern int zfs_unshare_smb(zfs_handle_t *, const char *);
+extern int zfs_unshareall_nfs(zfs_handle_t *);
+extern int zfs_unshareall_smb(zfs_handle_t *);
+extern int zfs_unshareall_bypath(zfs_handle_t *, const char *);
+extern int zfs_unshareall(zfs_handle_t *);
+extern int zfs_deleg_share_nfs(libzfs_handle_t *, char *, char *, char *,
+    void *, void *, int, zfs_share_op_t);
+
+/*
+ * Utility function to convert a number to a human-readable form.
+ */
+extern void zfs_nicenum(uint64_t, char *, size_t);
+extern int zfs_nicestrtonum(libzfs_handle_t *, const char *, uint64_t *);
+
+/*
+ * Utility functions to run an external process.
+ */
+#define	STDOUT_VERBOSE	0x01
+#define	STDERR_VERBOSE	0x02
+
+int libzfs_run_process(const char *, char **, int flags);
+
+/*
+ * Given a device or file, determine if it is part of a pool.
+ */
+extern int zpool_in_use(libzfs_handle_t *, int, pool_state_t *, char **,
+    boolean_t *);
+
+/*
+ * Label manipulation.
+ */
+extern int zpool_read_label(int, nvlist_t **, int *);
+extern int zpool_clear_label(int);
+
+/*
+ * Management interfaces for SMB ACL files
+ */
+
+int zfs_smb_acl_add(libzfs_handle_t *, char *, char *, char *);
+int zfs_smb_acl_remove(libzfs_handle_t *, char *, char *, char *);
+int zfs_smb_acl_purge(libzfs_handle_t *, char *, char *);
+int zfs_smb_acl_rename(libzfs_handle_t *, char *, char *, char *, char *);
+
+/*
+ * Enable and disable datasets within a pool by mounting/unmounting and
+ * sharing/unsharing them.
+ */
+extern int zpool_enable_datasets(zpool_handle_t *, const char *, int);
+extern int zpool_disable_datasets(zpool_handle_t *, boolean_t);
+
+/*
+ * Mappings between vdev and FRU.
+ */
+extern void libzfs_fru_refresh(libzfs_handle_t *);
+extern const char *libzfs_fru_lookup(libzfs_handle_t *, const char *);
+extern const char *libzfs_fru_devpath(libzfs_handle_t *, const char *);
+extern boolean_t libzfs_fru_compare(libzfs_handle_t *, const char *,
+    const char *);
+extern boolean_t libzfs_fru_notself(libzfs_handle_t *, const char *);
+extern int zpool_fru_set(zpool_handle_t *, uint64_t, const char *);
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* _LIBZFS_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/include/libzfs_core.h
@@ -0,0 +1,72 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2013 by Delphix. All rights reserved.
+ */
+
+#ifndef	_LIBZFS_CORE_H
+#define	_LIBZFS_CORE_H
+
+#include <libnvpair.h>
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/fs/zfs.h>
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+int libzfs_core_init(void);
+void libzfs_core_fini(void);
+
+int lzc_snapshot(nvlist_t *, nvlist_t *, nvlist_t **);
+int lzc_create(const char *, dmu_objset_type_t, nvlist_t *);
+int lzc_clone(const char *, const char *, nvlist_t *);
+int lzc_destroy_snaps(nvlist_t *, boolean_t, nvlist_t **);
+int lzc_bookmark(nvlist_t *, nvlist_t **);
+int lzc_get_bookmarks(const char *, nvlist_t *, nvlist_t **);
+int lzc_destroy_bookmarks(nvlist_t *, nvlist_t **);
+
+int lzc_snaprange_space(const char *, const char *, uint64_t *);
+
+int lzc_hold(nvlist_t *, int, nvlist_t **);
+int lzc_release(nvlist_t *, nvlist_t **);
+int lzc_get_holds(const char *, nvlist_t **);
+
+enum lzc_send_flags {
+	LZC_SEND_FLAG_EMBED_DATA = 1 << 0,
+	LZC_SEND_FLAG_LARGE_BLOCK = 1 << 1
+};
+
+int lzc_send(const char *, const char *, int, enum lzc_send_flags);
+int lzc_receive(const char *, nvlist_t *, const char *, boolean_t, int);
+int lzc_send_space(const char *, const char *, uint64_t *);
+
+boolean_t lzc_exists(const char *);
+
+int lzc_rollback(const char *, char *, int);
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* _LIBZFS_CORE_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/include/libzfs_impl.h
@@ -0,0 +1,222 @@
+/*
+ * CDDL HEADER SART
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013 by Delphix. All rights reserved.
+ */
+
+#ifndef	_LIBZFS_IMPL_H
+#define	_LIBZFS_IMPL_H
+
+#include <sys/dmu.h>
+#include <sys/fs/zfs.h>
+#include <sys/zfs_ioctl.h>
+#include <sys/spa.h>
+#include <sys/nvpair.h>
+
+#include <libuutil.h>
+#include <libzfs.h>
+#include <libshare.h>
+#include <libzfs_core.h>
+
+#if defined(HAVE_LIBTOPO)
+#include <fm/libtopo.h>
+#endif /* HAVE_LIBTOPO */
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+#ifdef	VERIFY
+#undef	VERIFY
+#endif
+#define	VERIFY	verify
+
+typedef struct libzfs_fru {
+	char *zf_device;
+	char *zf_fru;
+	struct libzfs_fru *zf_chain;
+	struct libzfs_fru *zf_next;
+} libzfs_fru_t;
+
+struct libzfs_handle {
+	int libzfs_error;
+	int libzfs_fd;
+	FILE *libzfs_mnttab;
+	FILE *libzfs_sharetab;
+	zpool_handle_t *libzfs_pool_handles;
+	uu_avl_pool_t *libzfs_ns_avlpool;
+	uu_avl_t *libzfs_ns_avl;
+	uint64_t libzfs_ns_gen;
+	int libzfs_desc_active;
+	char libzfs_action[1024];
+	char libzfs_desc[1024];
+	int libzfs_printerr;
+	int libzfs_storeerr; /* stuff error messages into buffer */
+	void *libzfs_sharehdl; /* libshare handle */
+	uint_t libzfs_shareflags;
+	boolean_t libzfs_mnttab_enable;
+	avl_tree_t libzfs_mnttab_cache;
+	int libzfs_pool_iter;
+#if defined(HAVE_LIBTOPO)
+	topo_hdl_t *libzfs_topo_hdl;
+	libzfs_fru_t **libzfs_fru_hash;
+	libzfs_fru_t *libzfs_fru_list;
+#endif /* HAVE_LIBTOPO */
+	char libzfs_chassis_id[256];
+};
+
+#define	ZFSSHARE_MISS	0x01	/* Didn't find entry in cache */
+
+struct zfs_handle {
+	libzfs_handle_t *zfs_hdl;
+	zpool_handle_t *zpool_hdl;
+	char zfs_name[ZFS_MAXNAMELEN];
+	zfs_type_t zfs_type; /* type including snapshot */
+	zfs_type_t zfs_head_type; /* type excluding snapshot */
+	dmu_objset_stats_t zfs_dmustats;
+	nvlist_t *zfs_props;
+	nvlist_t *zfs_user_props;
+	nvlist_t *zfs_recvd_props;
+	boolean_t zfs_mntcheck;
+	char *zfs_mntopts;
+	uint8_t *zfs_props_table;
+};
+
+/*
+ * This is different from checking zfs_type, because it will also catch
+ * snapshots of volumes.
+ */
+#define	ZFS_IS_VOLUME(zhp) ((zhp)->zfs_head_type == ZFS_TYPE_VOLUME)
+
+struct zpool_handle {
+	libzfs_handle_t *zpool_hdl;
+	zpool_handle_t *zpool_next;
+	char zpool_name[ZPOOL_MAXNAMELEN];
+	int zpool_state;
+	size_t zpool_config_size;
+	nvlist_t *zpool_config;
+	nvlist_t *zpool_old_config;
+	nvlist_t *zpool_props;
+	diskaddr_t zpool_start_block;
+};
+
+typedef enum {
+	PROTO_NFS = 0,
+	PROTO_SMB = 1,
+	PROTO_END = 2
+} zfs_share_proto_t;
+
+/*
+ * The following can be used as a bitmask and any new values
+ * added must preserve that capability.
+ */
+typedef enum {
+	SHARED_NOT_SHARED = 0x0,
+	SHARED_NFS = 0x2,
+	SHARED_SMB = 0x4
+} zfs_share_type_t;
+
+int zfs_error(libzfs_handle_t *, int, const char *);
+int zfs_error_fmt(libzfs_handle_t *, int, const char *, ...);
+void zfs_error_aux(libzfs_handle_t *, const char *, ...);
+void *zfs_alloc(libzfs_handle_t *, size_t);
+void *zfs_realloc(libzfs_handle_t *, void *, size_t, size_t);
+char *zfs_asprintf(libzfs_handle_t *, const char *, ...);
+char *zfs_strdup(libzfs_handle_t *, const char *);
+int no_memory(libzfs_handle_t *);
+
+int zfs_standard_error(libzfs_handle_t *, int, const char *);
+int zfs_standard_error_fmt(libzfs_handle_t *, int, const char *, ...);
+int zpool_standard_error(libzfs_handle_t *, int, const char *);
+int zpool_standard_error_fmt(libzfs_handle_t *, int, const char *, ...);
+
+int get_dependents(libzfs_handle_t *, boolean_t, const char *, char ***,
+    size_t *);
+zfs_handle_t *make_dataset_handle_zc(libzfs_handle_t *, zfs_cmd_t *);
+zfs_handle_t *make_dataset_simple_handle_zc(zfs_handle_t *, zfs_cmd_t *);
+
+int zprop_parse_value(libzfs_handle_t *, nvpair_t *, int, zfs_type_t,
+    nvlist_t *, char **, uint64_t *, const char *);
+int zprop_expand_list(libzfs_handle_t *hdl, zprop_list_t **plp,
+    zfs_type_t type);
+
+/*
+ * Use this changelist_gather() flag to force attempting mounts
+ * on each change node regardless of whether or not it is currently
+ * mounted.
+ */
+#define	CL_GATHER_MOUNT_ALWAYS	1
+
+typedef struct prop_changelist prop_changelist_t;
+
+int zcmd_alloc_dst_nvlist(libzfs_handle_t *, zfs_cmd_t *, size_t);
+int zcmd_write_src_nvlist(libzfs_handle_t *, zfs_cmd_t *, nvlist_t *);
+int zcmd_write_conf_nvlist(libzfs_handle_t *, zfs_cmd_t *, nvlist_t *);
+int zcmd_expand_dst_nvlist(libzfs_handle_t *, zfs_cmd_t *);
+int zcmd_read_dst_nvlist(libzfs_handle_t *, zfs_cmd_t *, nvlist_t **);
+void zcmd_free_nvlists(zfs_cmd_t *);
+
+int changelist_prefix(prop_changelist_t *);
+int changelist_postfix(prop_changelist_t *);
+void changelist_rename(prop_changelist_t *, const char *, const char *);
+void changelist_remove(prop_changelist_t *, const char *);
+void changelist_free(prop_changelist_t *);
+prop_changelist_t *changelist_gather(zfs_handle_t *, zfs_prop_t, int, int);
+int changelist_unshare(prop_changelist_t *, zfs_share_proto_t *);
+int changelist_haszonedchild(prop_changelist_t *);
+
+void remove_mountpoint(zfs_handle_t *);
+int create_parents(libzfs_handle_t *, char *, int);
+boolean_t isa_child_of(const char *dataset, const char *parent);
+
+zfs_handle_t *make_dataset_handle(libzfs_handle_t *, const char *);
+zfs_handle_t *make_bookmark_handle(zfs_handle_t *, const char *,
+    nvlist_t *props);
+
+int zpool_open_silent(libzfs_handle_t *, const char *, zpool_handle_t **);
+
+boolean_t zpool_name_valid(libzfs_handle_t *, boolean_t, const char *);
+
+int zfs_validate_name(libzfs_handle_t *hdl, const char *path, int type,
+    boolean_t modifying);
+
+void namespace_clear(libzfs_handle_t *);
+
+/*
+ * libshare (sharemgr) interfaces used internally.
+ */
+
+extern int zfs_init_libshare(libzfs_handle_t *, int);
+extern void zfs_uninit_libshare(libzfs_handle_t *);
+extern int zfs_parse_options(char *, zfs_share_proto_t);
+
+extern int zfs_unshare_proto(zfs_handle_t *,
+    const char *, zfs_share_proto_t *);
+
+extern void libzfs_fru_clear(libzfs_handle_t *, boolean_t);
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* _LIBZFS_IMPL_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/include/linux/Makefile.am
@@ -0,0 +1,23 @@
+COMMON_H =
+
+KERNEL_H = \
+	$(top_srcdir)/include/linux/dcache_compat.h \
+	$(top_srcdir)/include/linux/xattr_compat.h \
+	$(top_srcdir)/include/linux/vfs_compat.h \
+	$(top_srcdir)/include/linux/blkdev_compat.h \
+	$(top_srcdir)/include/linux/utsname_compat.h \
+	$(top_srcdir)/include/linux/kmap_compat.h
+
+USER_H =
+
+EXTRA_DIST = $(COMMON_H) $(KERNEL_H) $(USER_H)
+
+if CONFIG_USER
+libzfsdir = $(includedir)/libzfs/linux
+libzfs_HEADERS = $(COMMON_H) $(USER_H)
+endif
+
+if CONFIG_KERNEL
+kerneldir = @prefix@/src/zfs-$(VERSION)/include/linux
+kernel_HEADERS = $(COMMON_H) $(KERNEL_H)
+endif
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/include/linux/Makefile.in
@@ -0,0 +1,761 @@
+# Makefile.in generated by automake 1.15 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2014 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+VPATH = @srcdir@
+am__is_gnu_make = { \
+  if test -z '$(MAKELEVEL)'; then \
+    false; \
+  elif test -n '$(MAKE_HOST)'; then \
+    true; \
+  elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+    true; \
+  else \
+    false; \
+  fi; \
+}
+am__make_running_with_option = \
+  case $${target_option-} in \
+      ?) ;; \
+      *) echo "am__make_running_with_option: internal error: invalid" \
+              "target option '$${target_option-}' specified" >&2; \
+         exit 1;; \
+  esac; \
+  has_opt=no; \
+  sane_makeflags=$$MAKEFLAGS; \
+  if $(am__is_gnu_make); then \
+    sane_makeflags=$$MFLAGS; \
+  else \
+    case $$MAKEFLAGS in \
+      *\\[\ \	]*) \
+        bs=\\; \
+        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
+    esac; \
+  fi; \
+  skip_next=no; \
+  strip_trailopt () \
+  { \
+    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+  }; \
+  for flg in $$sane_makeflags; do \
+    test $$skip_next = yes && { skip_next=no; continue; }; \
+    case $$flg in \
+      *=*|--*) continue;; \
+        -*I) strip_trailopt 'I'; skip_next=yes;; \
+      -*I?*) strip_trailopt 'I';; \
+        -*O) strip_trailopt 'O'; skip_next=yes;; \
+      -*O?*) strip_trailopt 'O';; \
+        -*l) strip_trailopt 'l'; skip_next=yes;; \
+      -*l?*) strip_trailopt 'l';; \
+      -[dEDm]) skip_next=yes;; \
+      -[JT]) skip_next=yes;; \
+    esac; \
+    case $$flg in \
+      *$$target_option*) has_opt=yes; break;; \
+    esac; \
+  done; \
+  test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+target_triplet = @target@
+subdir = include/linux
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/config/always-no-bool-compare.m4 \
+	$(top_srcdir)/config/always-no-unused-but-set-variable.m4 \
+	$(top_srcdir)/config/dkms.m4 \
+	$(top_srcdir)/config/kernel-acl.m4 \
+	$(top_srcdir)/config/kernel-automount.m4 \
+	$(top_srcdir)/config/kernel-bdev-block-device-operations.m4 \
+	$(top_srcdir)/config/kernel-bdev-logical-size.m4 \
+	$(top_srcdir)/config/kernel-bdev-physical-size.m4 \
+	$(top_srcdir)/config/kernel-bdi-setup-and-register.m4 \
+	$(top_srcdir)/config/kernel-bio-bvec-iter.m4 \
+	$(top_srcdir)/config/kernel-bio-end-io-t-args.m4 \
+	$(top_srcdir)/config/kernel-bio-failfast.m4 \
+	$(top_srcdir)/config/kernel-bio-rw-barrier.m4 \
+	$(top_srcdir)/config/kernel-bio-rw-discard.m4 \
+	$(top_srcdir)/config/kernel-blk-queue-flush.m4 \
+	$(top_srcdir)/config/kernel-blk-queue-max-hw-sectors.m4 \
+	$(top_srcdir)/config/kernel-blk-queue-max-segments.m4 \
+	$(top_srcdir)/config/kernel-blkdev-get-by-path.m4 \
+	$(top_srcdir)/config/kernel-blkdev-get.m4 \
+	$(top_srcdir)/config/kernel-block-device-operations-release-void.m4 \
+	$(top_srcdir)/config/kernel-check-disk-size-change.m4 \
+	$(top_srcdir)/config/kernel-clear-inode.m4 \
+	$(top_srcdir)/config/kernel-commit-metadata.m4 \
+	$(top_srcdir)/config/kernel-create-nameidata.m4 \
+	$(top_srcdir)/config/kernel-current_bio_tail.m4 \
+	$(top_srcdir)/config/kernel-d-make-root.m4 \
+	$(top_srcdir)/config/kernel-d-obtain-alias.m4 \
+	$(top_srcdir)/config/kernel-d-prune-aliases.m4 \
+	$(top_srcdir)/config/kernel-declare-event-class.m4 \
+	$(top_srcdir)/config/kernel-dentry-operations.m4 \
+	$(top_srcdir)/config/kernel-dirty-inode.m4 \
+	$(top_srcdir)/config/kernel-discard-granularity.m4 \
+	$(top_srcdir)/config/kernel-elevator-change.m4 \
+	$(top_srcdir)/config/kernel-encode-fh-inode.m4 \
+	$(top_srcdir)/config/kernel-evict-inode.m4 \
+	$(top_srcdir)/config/kernel-fallocate.m4 \
+	$(top_srcdir)/config/kernel-file-inode.m4 \
+	$(top_srcdir)/config/kernel-fmode-t.m4 \
+	$(top_srcdir)/config/kernel-follow-down-one.m4 \
+	$(top_srcdir)/config/kernel-fsync.m4 \
+	$(top_srcdir)/config/kernel-generic_io_acct.m4 \
+	$(top_srcdir)/config/kernel-get-disk-ro.m4 \
+	$(top_srcdir)/config/kernel-get-gendisk.m4 \
+	$(top_srcdir)/config/kernel-get-link.m4 \
+	$(top_srcdir)/config/kernel-insert-inode-locked.m4 \
+	$(top_srcdir)/config/kernel-invalidate-bdev-args.m4 \
+	$(top_srcdir)/config/kernel-is_owner_or_cap.m4 \
+	$(top_srcdir)/config/kernel-kmap-atomic-args.m4 \
+	$(top_srcdir)/config/kernel-kobj-name-len.m4 \
+	$(top_srcdir)/config/kernel-lookup-bdev.m4 \
+	$(top_srcdir)/config/kernel-lookup-nameidata.m4 \
+	$(top_srcdir)/config/kernel-lseek-execute.m4 \
+	$(top_srcdir)/config/kernel-mk-request-fn.m4 \
+	$(top_srcdir)/config/kernel-mkdir-umode-t.m4 \
+	$(top_srcdir)/config/kernel-mount-nodev.m4 \
+	$(top_srcdir)/config/kernel-open-bdev-exclusive.m4 \
+	$(top_srcdir)/config/kernel-put-link.m4 \
+	$(top_srcdir)/config/kernel-security-inode-init.m4 \
+	$(top_srcdir)/config/kernel-set-nlink.m4 \
+	$(top_srcdir)/config/kernel-sget-args.m4 \
+	$(top_srcdir)/config/kernel-show-options.m4 \
+	$(top_srcdir)/config/kernel-shrink.m4 \
+	$(top_srcdir)/config/kernel-truncate-range.m4 \
+	$(top_srcdir)/config/kernel-truncate-setsize.m4 \
+	$(top_srcdir)/config/kernel-vfs-iterate.m4 \
+	$(top_srcdir)/config/kernel-vfs-rw-iterate.m4 \
+	$(top_srcdir)/config/kernel-xattr-handler.m4 \
+	$(top_srcdir)/config/kernel.m4 $(top_srcdir)/config/libtool.m4 \
+	$(top_srcdir)/config/ltoptions.m4 \
+	$(top_srcdir)/config/ltsugar.m4 \
+	$(top_srcdir)/config/ltversion.m4 \
+	$(top_srcdir)/config/lt~obsolete.m4 \
+	$(top_srcdir)/config/mount-helper.m4 \
+	$(top_srcdir)/config/user-arch.m4 \
+	$(top_srcdir)/config/user-dracut.m4 \
+	$(top_srcdir)/config/user-frame-larger-than.m4 \
+	$(top_srcdir)/config/user-libblkid.m4 \
+	$(top_srcdir)/config/user-libuuid.m4 \
+	$(top_srcdir)/config/user-runstatedir.m4 \
+	$(top_srcdir)/config/user-systemd.m4 \
+	$(top_srcdir)/config/user-sysvinit.m4 \
+	$(top_srcdir)/config/user-udev.m4 \
+	$(top_srcdir)/config/user-zlib.m4 $(top_srcdir)/config/user.m4 \
+	$(top_srcdir)/config/zfs-build.m4 \
+	$(top_srcdir)/config/zfs-meta.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(am__kernel_HEADERS_DIST) \
+	$(libzfs_HEADERS) $(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/zfs_config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo "  GEN     " $@;
+am__v_GEN_1 = 
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 = 
+SOURCES =
+DIST_SOURCES =
+am__can_run_installinfo = \
+  case $$AM_UPDATE_INFO_DIR in \
+    n|no|NO) false;; \
+    *) (install-info --version) >/dev/null 2>&1;; \
+  esac
+am__kernel_HEADERS_DIST = $(top_srcdir)/include/linux/dcache_compat.h \
+	$(top_srcdir)/include/linux/xattr_compat.h \
+	$(top_srcdir)/include/linux/vfs_compat.h \
+	$(top_srcdir)/include/linux/blkdev_compat.h \
+	$(top_srcdir)/include/linux/utsname_compat.h \
+	$(top_srcdir)/include/linux/kmap_compat.h
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+    $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+    *) f=$$p;; \
+  esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+  srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+  for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+  for p in $$list; do echo "$$p $$p"; done | \
+  sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+  $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+    if (++n[$$2] == $(am__install_max)) \
+      { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+    END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+  sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+  sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+  test -z "$$files" \
+    || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+    || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+         $(am__cd) "$$dir" && rm -f $$files; }; \
+  }
+am__installdirs = "$(DESTDIR)$(kerneldir)" "$(DESTDIR)$(libzfsdir)"
+HEADERS = $(kernel_HEADERS) $(libzfs_HEADERS)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates.  Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+  BEGIN { nonempty = 0; } \
+  { items[$$0] = 1; nonempty = 1; } \
+  END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique.  This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+  list='$(am__tagged_files)'; \
+  unique=`for i in $$list; do \
+    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+  done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+am__DIST_COMMON = $(srcdir)/Makefile.in
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ALIEN = @ALIEN@
+ALIEN_VERSION = @ALIEN_VERSION@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCAS = @CCAS@
+CCASDEPMODE = @CCASDEPMODE@
+CCASFLAGS = @CCASFLAGS@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEBUG_CFLAGS = @DEBUG_CFLAGS@
+DEBUG_DMU_TX = @DEBUG_DMU_TX@
+DEBUG_STACKFLAGS = @DEBUG_STACKFLAGS@
+DEBUG_ZFS = @DEBUG_ZFS@
+DEFAULT_INITCONF_DIR = @DEFAULT_INITCONF_DIR@
+DEFAULT_INIT_DIR = @DEFAULT_INIT_DIR@
+DEFAULT_INIT_SCRIPT = @DEFAULT_INIT_SCRIPT@
+DEFAULT_PACKAGE = @DEFAULT_PACKAGE@
+DEFINE_INITRAMFS = @DEFINE_INITRAMFS@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DPKG = @DPKG@
+DPKGBUILD = @DPKGBUILD@
+DPKGBUILD_VERSION = @DPKGBUILD_VERSION@
+DPKG_VERSION = @DPKG_VERSION@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+FRAME_LARGER_THAN = @FRAME_LARGER_THAN@
+GREP = @GREP@
+HAVE_ALIEN = @HAVE_ALIEN@
+HAVE_DPKG = @HAVE_DPKG@
+HAVE_DPKGBUILD = @HAVE_DPKGBUILD@
+HAVE_RPM = @HAVE_RPM@
+HAVE_RPMBUILD = @HAVE_RPMBUILD@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+KERNELCPPFLAGS = @KERNELCPPFLAGS@
+KERNELMAKE_PARAMS = @KERNELMAKE_PARAMS@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBBLKID = @LIBBLKID@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIBUUID = @LIBUUID@
+LINUX = @LINUX@
+LINUX_OBJ = @LINUX_OBJ@
+LINUX_SYMBOLS = @LINUX_SYMBOLS@
+LINUX_VERSION = @LINUX_VERSION@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NO_BOOL_COMPARE = @NO_BOOL_COMPARE@
+NO_UNUSED_BUT_SET_VARIABLE = @NO_UNUSED_BUT_SET_VARIABLE@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+RANLIB = @RANLIB@
+RELEASE = @RELEASE@
+RPM = @RPM@
+RPMBUILD = @RPMBUILD@
+RPMBUILD_VERSION = @RPMBUILD_VERSION@
+RPM_DEFINE_COMMON = @RPM_DEFINE_COMMON@
+RPM_DEFINE_DKMS = @RPM_DEFINE_DKMS@
+RPM_DEFINE_KMOD = @RPM_DEFINE_KMOD@
+RPM_DEFINE_UTIL = @RPM_DEFINE_UTIL@
+RPM_SPEC_DIR = @RPM_SPEC_DIR@
+RPM_VERSION = @RPM_VERSION@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SPL = @SPL@
+SPL_OBJ = @SPL_OBJ@
+SPL_SYMBOLS = @SPL_SYMBOLS@
+SPL_VERSION = @SPL_VERSION@
+SRPM_DEFINE_COMMON = @SRPM_DEFINE_COMMON@
+SRPM_DEFINE_DKMS = @SRPM_DEFINE_DKMS@
+SRPM_DEFINE_KMOD = @SRPM_DEFINE_KMOD@
+SRPM_DEFINE_UTIL = @SRPM_DEFINE_UTIL@
+STRIP = @STRIP@
+TARGET_ASM_DIR = @TARGET_ASM_DIR@
+VENDOR = @VENDOR@
+VERSION = @VERSION@
+ZFS_CONFIG = @ZFS_CONFIG@
+ZFS_INIT_SYSTEMD = @ZFS_INIT_SYSTEMD@
+ZFS_INIT_SYSV = @ZFS_INIT_SYSV@
+ZFS_META_ALIAS = @ZFS_META_ALIAS@
+ZFS_META_AUTHOR = @ZFS_META_AUTHOR@
+ZFS_META_DATA = @ZFS_META_DATA@
+ZFS_META_LICENSE = @ZFS_META_LICENSE@
+ZFS_META_LT_AGE = @ZFS_META_LT_AGE@
+ZFS_META_LT_CURRENT = @ZFS_META_LT_CURRENT@
+ZFS_META_LT_REVISION = @ZFS_META_LT_REVISION@
+ZFS_META_NAME = @ZFS_META_NAME@
+ZFS_META_RELEASE = @ZFS_META_RELEASE@
+ZFS_META_VERSION = @ZFS_META_VERSION@
+ZFS_MODULE_LOAD = @ZFS_MODULE_LOAD@
+ZLIB = @ZLIB@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dracutdir = @dracutdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+modulesloaddir = @modulesloaddir@
+mounthelperdir = @mounthelperdir@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+runstatedir = @runstatedir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+systemdpresetdir = @systemdpresetdir@
+systemdunitdir = @systemdunitdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+udevdir = @udevdir@
+udevruledir = @udevruledir@
+COMMON_H = 
+KERNEL_H = \
+	$(top_srcdir)/include/linux/dcache_compat.h \
+	$(top_srcdir)/include/linux/xattr_compat.h \
+	$(top_srcdir)/include/linux/vfs_compat.h \
+	$(top_srcdir)/include/linux/blkdev_compat.h \
+	$(top_srcdir)/include/linux/utsname_compat.h \
+	$(top_srcdir)/include/linux/kmap_compat.h
+
+USER_H = 
+EXTRA_DIST = $(COMMON_H) $(KERNEL_H) $(USER_H)
+@CONFIG_USER_TRUE@libzfsdir = $(includedir)/libzfs/linux
+@CONFIG_USER_TRUE@libzfs_HEADERS = $(COMMON_H) $(USER_H)
+@CONFIG_KERNEL_TRUE@kerneldir = @prefix@/src/zfs-$(VERSION)/include/linux
+@CONFIG_KERNEL_TRUE@kernel_HEADERS = $(COMMON_H) $(KERNEL_H)
+all: all-am
+
+.SUFFIXES:
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+	        && { if test -f $@; then exit 0; else break; fi; }; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu include/linux/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --gnu include/linux/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+	esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
+install-kernelHEADERS: $(kernel_HEADERS)
+	@$(NORMAL_INSTALL)
+	@list='$(kernel_HEADERS)'; test -n "$(kerneldir)" || list=; \
+	if test -n "$$list"; then \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(kerneldir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(kerneldir)" || exit 1; \
+	fi; \
+	for p in $$list; do \
+	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+	  echo "$$d$$p"; \
+	done | $(am__base_list) | \
+	while read files; do \
+	  echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(kerneldir)'"; \
+	  $(INSTALL_HEADER) $$files "$(DESTDIR)$(kerneldir)" || exit $$?; \
+	done
+
+uninstall-kernelHEADERS:
+	@$(NORMAL_UNINSTALL)
+	@list='$(kernel_HEADERS)'; test -n "$(kerneldir)" || list=; \
+	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+	dir='$(DESTDIR)$(kerneldir)'; $(am__uninstall_files_from_dir)
+install-libzfsHEADERS: $(libzfs_HEADERS)
+	@$(NORMAL_INSTALL)
+	@list='$(libzfs_HEADERS)'; test -n "$(libzfsdir)" || list=; \
+	if test -n "$$list"; then \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(libzfsdir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(libzfsdir)" || exit 1; \
+	fi; \
+	for p in $$list; do \
+	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+	  echo "$$d$$p"; \
+	done | $(am__base_list) | \
+	while read files; do \
+	  echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(libzfsdir)'"; \
+	  $(INSTALL_HEADER) $$files "$(DESTDIR)$(libzfsdir)" || exit $$?; \
+	done
+
+uninstall-libzfsHEADERS:
+	@$(NORMAL_UNINSTALL)
+	@list='$(libzfs_HEADERS)'; test -n "$(libzfsdir)" || list=; \
+	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+	dir='$(DESTDIR)$(libzfsdir)'; $(am__uninstall_files_from_dir)
+
+ID: $(am__tagged_files)
+	$(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	set x; \
+	here=`pwd`; \
+	$(am__define_uniq_tagged_files); \
+	shift; \
+	if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+	  test -n "$$unique" || unique=$$empty_fix; \
+	  if test $$# -gt 0; then \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      "$$@" $$unique; \
+	  else \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      $$unique; \
+	  fi; \
+	fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	$(am__define_uniq_tagged_files); \
+	test -z "$(CTAGS_ARGS)$$unique" \
+	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+	     $$unique
+
+GTAGS:
+	here=`$(am__cd) $(top_builddir) && pwd` \
+	  && $(am__cd) $(top_srcdir) \
+	  && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+	list='$(am__tagged_files)'; \
+	case "$(srcdir)" in \
+	  [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+	  *) sdir=$(subdir)/$(srcdir) ;; \
+	esac; \
+	for i in $$list; do \
+	  if test -f "$$i"; then \
+	    echo "$(subdir)/$$i"; \
+	  else \
+	    echo "$$sdir/$$i"; \
+	  fi; \
+	done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	list='$(DISTFILES)'; \
+	  dist_files=`for file in $$list; do echo $$file; done | \
+	  sed -e "s|^$$srcdirstrip/||;t" \
+	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+	case $$dist_files in \
+	  */*) $(MKDIR_P) `echo "$$dist_files" | \
+			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+			   sort -u` ;; \
+	esac; \
+	for file in $$dist_files; do \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  if test -d $$d/$$file; then \
+	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+	    if test -d "$(distdir)/$$file"; then \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+	  else \
+	    test -f "$(distdir)/$$file" \
+	    || cp -p $$d/$$file "$(distdir)/$$file" \
+	    || exit 1; \
+	  fi; \
+	done
+check-am: all-am
+check: check-am
+all-am: Makefile $(HEADERS)
+installdirs:
+	for dir in "$(DESTDIR)$(kerneldir)" "$(DESTDIR)$(libzfsdir)"; do \
+	  test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+	done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+	if test -z '$(STRIP)'; then \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	      install; \
+	else \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+	fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-am
+	-rm -f Makefile
+distclean-am: clean-am distclean-generic distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-kernelHEADERS install-libzfsHEADERS
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-kernelHEADERS uninstall-libzfsHEADERS
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \
+	clean-libtool cscopelist-am ctags ctags-am distclean \
+	distclean-generic distclean-libtool distclean-tags distdir dvi \
+	dvi-am html html-am info info-am install install-am \
+	install-data install-data-am install-dvi install-dvi-am \
+	install-exec install-exec-am install-html install-html-am \
+	install-info install-info-am install-kernelHEADERS \
+	install-libzfsHEADERS install-man install-pdf install-pdf-am \
+	install-ps install-ps-am install-strip installcheck \
+	installcheck-am installdirs maintainer-clean \
+	maintainer-clean-generic mostlyclean mostlyclean-generic \
+	mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \
+	uninstall-am uninstall-kernelHEADERS uninstall-libzfsHEADERS
+
+.PRECIOUS: Makefile
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/include/linux/blkdev_compat.h
@@ -0,0 +1,348 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (C) 2011 Lawrence Livermore National Security, LLC.
+ * Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ * Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ * LLNL-CODE-403049.
+ */
+
+#ifndef _ZFS_BLKDEV_H
+#define	_ZFS_BLKDEV_H
+
+#include <linux/blkdev.h>
+#include <linux/elevator.h>
+
+#ifndef HAVE_FMODE_T
+typedef unsigned __bitwise__ fmode_t;
+#endif /* HAVE_FMODE_T */
+
+/*
+ * 2.6.36 API change,
+ * The blk_queue_flush() interface has replaced blk_queue_ordered()
+ * interface.  However, while the old interface was available to all the
+ * new one is GPL-only.   Thus if the GPL-only version is detected we
+ * implement our own trivial helper compatibility funcion.   The hope is
+ * that long term this function will be opened up.
+ */
+#if defined(HAVE_BLK_QUEUE_FLUSH) && defined(HAVE_BLK_QUEUE_FLUSH_GPL_ONLY)
+#define	blk_queue_flush __blk_queue_flush
+static inline void
+__blk_queue_flush(struct request_queue *q, unsigned int flags)
+{
+	q->flush_flags = flags & (REQ_FLUSH | REQ_FUA);
+}
+#endif /* HAVE_BLK_QUEUE_FLUSH && HAVE_BLK_QUEUE_FLUSH_GPL_ONLY */
+/*
+ * Most of the blk_* macros were removed in 2.6.36.  Ostensibly this was
+ * done to improve readability and allow easier grepping.  However, from
+ * a portability stand point the macros are helpful.  Therefore the needed
+ * macros are redefined here if they are missing from the kernel.
+ */
+#ifndef blk_fs_request
+#define	blk_fs_request(rq)	((rq)->cmd_type == REQ_TYPE_FS)
+#endif
+
+/*
+ * 2.6.27 API change,
+ * The blk_queue_stackable() queue flag was added in 2.6.27 to handle dm
+ * stacking drivers.  Prior to this request stacking drivers were detected
+ * by checking (q->request_fn == NULL), for earlier kernels we revert to
+ * this legacy behavior.
+ */
+#ifndef blk_queue_stackable
+#define	blk_queue_stackable(q)	((q)->request_fn == NULL)
+#endif
+
+/*
+ * 2.6.34 API change,
+ * The blk_queue_max_hw_sectors() function replaces blk_queue_max_sectors().
+ */
+#ifndef HAVE_BLK_QUEUE_MAX_HW_SECTORS
+#define	blk_queue_max_hw_sectors __blk_queue_max_hw_sectors
+static inline void
+__blk_queue_max_hw_sectors(struct request_queue *q, unsigned int max_hw_sectors)
+{
+	blk_queue_max_sectors(q, max_hw_sectors);
+}
+#endif
+
+/*
+ * 2.6.34 API change,
+ * The blk_queue_max_segments() function consolidates
+ * blk_queue_max_hw_segments() and blk_queue_max_phys_segments().
+ */
+#ifndef HAVE_BLK_QUEUE_MAX_SEGMENTS
+#define	blk_queue_max_segments __blk_queue_max_segments
+static inline void
+__blk_queue_max_segments(struct request_queue *q, unsigned short max_segments)
+{
+	blk_queue_max_phys_segments(q, max_segments);
+	blk_queue_max_hw_segments(q, max_segments);
+}
+#endif
+
+#ifndef HAVE_GET_DISK_RO
+static inline int
+get_disk_ro(struct gendisk *disk)
+{
+	int policy = 0;
+
+	if (disk->part[0])
+		policy = disk->part[0]->policy;
+
+	return (policy);
+}
+#endif /* HAVE_GET_DISK_RO */
+
+#ifdef HAVE_BIO_BVEC_ITER
+#define	BIO_BI_SECTOR(bio)	(bio)->bi_iter.bi_sector
+#define	BIO_BI_SIZE(bio)	(bio)->bi_iter.bi_size
+#define	BIO_BI_IDX(bio)		(bio)->bi_iter.bi_idx
+#define	bio_for_each_segment4(bv, bvp, b, i)	\
+	bio_for_each_segment((bv), (b), (i))
+typedef struct bvec_iter bvec_iterator_t;
+#else
+#define	BIO_BI_SECTOR(bio)	(bio)->bi_sector
+#define	BIO_BI_SIZE(bio)	(bio)->bi_size
+#define	BIO_BI_IDX(bio)		(bio)->bi_idx
+#define	bio_for_each_segment4(bv, bvp, b, i)	\
+	bio_for_each_segment((bvp), (b), (i))
+typedef int bvec_iterator_t;
+#endif
+
+/*
+ * Portable helper for correctly setting the FAILFAST flags.  The
+ * correct usage has changed 3 times from 2.6.12 to 2.6.38.
+ */
+static inline void
+bio_set_flags_failfast(struct block_device *bdev, int *flags)
+{
+#ifdef CONFIG_BUG
+	/*
+	 * Disable FAILFAST for loopback devices because of the
+	 * following incorrect BUG_ON() in loop_make_request().
+	 * This support is also disabled for md devices because the
+	 * test suite layers md devices on top of loopback devices.
+	 * This may be removed when the loopback driver is fixed.
+	 *
+	 *   BUG_ON(!lo || (rw != READ && rw != WRITE));
+	 */
+	if ((MAJOR(bdev->bd_dev) == LOOP_MAJOR) ||
+	    (MAJOR(bdev->bd_dev) == MD_MAJOR))
+		return;
+
+#ifdef BLOCK_EXT_MAJOR
+	if (MAJOR(bdev->bd_dev) == BLOCK_EXT_MAJOR)
+		return;
+#endif /* BLOCK_EXT_MAJOR */
+#endif /* CONFIG_BUG */
+
+#if defined(HAVE_BIO_RW_FAILFAST_DTD)
+	/* BIO_RW_FAILFAST_* preferred interface from 2.6.28 - 2.6.35 */
+	*flags |= (
+	    (1 << BIO_RW_FAILFAST_DEV) |
+	    (1 << BIO_RW_FAILFAST_TRANSPORT) |
+	    (1 << BIO_RW_FAILFAST_DRIVER));
+#elif defined(HAVE_REQ_FAILFAST_MASK)
+	/*
+	 * REQ_FAILFAST_* preferred interface from 2.6.36 - 2.6.xx,
+	 * the BIO_* and REQ_* flags were unified under REQ_* flags.
+	 */
+	*flags |= REQ_FAILFAST_MASK;
+#else
+#error "Undefined block IO FAILFAST interface."
+#endif
+}
+
+/*
+ * Maximum disk label length, it may be undefined for some kernels.
+ */
+#ifndef DISK_NAME_LEN
+#define	DISK_NAME_LEN	32
+#endif /* DISK_NAME_LEN */
+
+/*
+ * 4.3 API change
+ * The bio_endio() prototype changed slightly.  These are helper
+ * macro's to ensure the prototype and invocation are handled.
+ */
+#ifdef HAVE_1ARG_BIO_END_IO_T
+#define	BIO_END_IO_PROTO(fn, x, z)	static void fn(struct bio *x)
+#define	BIO_END_IO(bio, error)		bio->bi_error = error; bio_endio(bio);
+#else
+#define	BIO_END_IO_PROTO(fn, x, z)	static void fn(struct bio *x, int z)
+#define	BIO_END_IO(bio, error)		bio_endio(bio, error);
+#endif /* HAVE_1ARG_BIO_END_IO_T */
+
+/*
+ * 2.6.38 - 2.6.x API,
+ *   blkdev_get_by_path()
+ *   blkdev_put()
+ *
+ * 2.6.28 - 2.6.37 API,
+ *   open_bdev_exclusive()
+ *   close_bdev_exclusive()
+ *
+ * 2.6.12 - 2.6.27 API,
+ *   open_bdev_excl()
+ *   close_bdev_excl()
+ *
+ * Used to exclusively open a block device from within the kernel.
+ */
+#if defined(HAVE_BLKDEV_GET_BY_PATH)
+#define	vdev_bdev_open(path, md, hld)	blkdev_get_by_path(path, \
+					    (md) | FMODE_EXCL, hld)
+#define	vdev_bdev_close(bdev, md)	blkdev_put(bdev, (md) | FMODE_EXCL)
+#elif defined(HAVE_OPEN_BDEV_EXCLUSIVE)
+#define	vdev_bdev_open(path, md, hld)	open_bdev_exclusive(path, md, hld)
+#define	vdev_bdev_close(bdev, md)	close_bdev_exclusive(bdev, md)
+#else
+#define	vdev_bdev_open(path, md, hld)	open_bdev_excl(path, md, hld)
+#define	vdev_bdev_close(bdev, md)	close_bdev_excl(bdev)
+#endif /* HAVE_BLKDEV_GET_BY_PATH | HAVE_OPEN_BDEV_EXCLUSIVE */
+
+/*
+ * 2.6.22 API change
+ * The function invalidate_bdev() lost it's second argument because
+ * it was unused.
+ */
+#ifdef HAVE_1ARG_INVALIDATE_BDEV
+#define	vdev_bdev_invalidate(bdev)	invalidate_bdev(bdev)
+#else
+#define	vdev_bdev_invalidate(bdev)	invalidate_bdev(bdev, 1)
+#endif /* HAVE_1ARG_INVALIDATE_BDEV */
+
+/*
+ * 2.6.27 API change
+ * The function was exported for use, prior to this it existed by the
+ * symbol was not exported.
+ */
+#ifndef HAVE_LOOKUP_BDEV
+#define	lookup_bdev(path)		ERR_PTR(-ENOTSUP)
+#endif
+
+/*
+ * 2.6.30 API change
+ * To ensure good performance preferentially use the physical block size
+ * for proper alignment.  The physical size is supposed to be the internal
+ * sector size used by the device.  This is often 4096 byte for AF devices,
+ * while a smaller 512 byte logical size is supported for compatibility.
+ *
+ * Unfortunately, many drives still misreport their physical sector size.
+ * For devices which are known to lie you may need to manually set this
+ * at pool creation time with 'zpool create -o ashift=12 ...'.
+ *
+ * When the physical block size interface isn't available, we fall back to
+ * the logical block size interface and then the older hard sector size.
+ */
+#ifdef HAVE_BDEV_PHYSICAL_BLOCK_SIZE
+#define	vdev_bdev_block_size(bdev)	bdev_physical_block_size(bdev)
+#else
+#ifdef HAVE_BDEV_LOGICAL_BLOCK_SIZE
+#define	vdev_bdev_block_size(bdev)	bdev_logical_block_size(bdev)
+#else
+#define	vdev_bdev_block_size(bdev)	bdev_hardsect_size(bdev)
+#endif /* HAVE_BDEV_LOGICAL_BLOCK_SIZE */
+#endif /* HAVE_BDEV_PHYSICAL_BLOCK_SIZE */
+
+/*
+ * 2.6.37 API change
+ * The WRITE_FLUSH, WRITE_FUA, and WRITE_FLUSH_FUA flags have been
+ * introduced as a replacement for WRITE_BARRIER.  This was done to
+ * allow richer semantics to be expressed to the block layer.  It is
+ * the block layers responsibility to choose the correct way to
+ * implement these semantics.
+ *
+ * The existence of these flags implies that REQ_FLUSH an REQ_FUA are
+ * defined.  Thus we can safely define VDEV_REQ_FLUSH and VDEV_REQ_FUA
+ * compatibility macros.
+ */
+#ifdef WRITE_FLUSH_FUA
+#define	VDEV_WRITE_FLUSH_FUA		WRITE_FLUSH_FUA
+#define	VDEV_REQ_FLUSH			REQ_FLUSH
+#define	VDEV_REQ_FUA			REQ_FUA
+#else
+#define	VDEV_WRITE_FLUSH_FUA		WRITE_BARRIER
+#ifdef HAVE_BIO_RW_BARRIER
+#define	VDEV_REQ_FLUSH			(1 << BIO_RW_BARRIER)
+#define	VDEV_REQ_FUA			(1 << BIO_RW_BARRIER)
+#else
+#define	VDEV_REQ_FLUSH			REQ_HARDBARRIER
+#define	VDEV_REQ_FUA			REQ_FUA
+#endif
+#endif
+
+/*
+ * 2.6.32 API change
+ * Use the normal I/O patch for discards.
+ */
+#ifdef QUEUE_FLAG_DISCARD
+#ifdef HAVE_BIO_RW_DISCARD
+#define	VDEV_REQ_DISCARD		(1 << BIO_RW_DISCARD)
+#else
+#define	VDEV_REQ_DISCARD		REQ_DISCARD
+#endif
+#else
+#error	"Allowing the build will cause discard requests to become writes "
+	"potentially triggering the DMU_MAX_ACCESS assertion. Please file a "
+	"an issue report at: https://github.com/zfsonlinux/zfs/issues/new"
+#endif
+
+/*
+ * 2.6.33 API change
+ * Discard granularity and alignment restrictions may now be set.  For
+ * older kernels which do not support this it is safe to skip it.
+ */
+#ifdef HAVE_DISCARD_GRANULARITY
+static inline void
+blk_queue_discard_granularity(struct request_queue *q, unsigned int dg)
+{
+	q->limits.discard_granularity = dg;
+}
+#else
+#define	blk_queue_discard_granularity(x, dg)	((void)0)
+#endif /* HAVE_DISCARD_GRANULARITY */
+
+/*
+ * Default Linux IO Scheduler,
+ * Setting the scheduler to noop will allow the Linux IO scheduler to
+ * still perform front and back merging, while leaving the request
+ * ordering and prioritization to the ZFS IO scheduler.
+ */
+#define	VDEV_SCHEDULER			"noop"
+
+/*
+ * A common holder for vdev_bdev_open() is used to relax the exclusive open
+ * semantics slightly.  Internal vdev disk callers may pass VDEV_HOLDER to
+ * allow them to open the device multiple times.  Other kernel callers and
+ * user space processes which don't pass this value will get EBUSY.  This is
+ * currently required for the correct operation of hot spares.
+ */
+#define	VDEV_HOLDER			((void *)0x2401de7)
+
+#ifndef HAVE_GENERIC_IO_ACCT
+#define	generic_start_io_acct(rw, slen, part)		((void)0)
+#define	generic_end_io_acct(rw, part, start_jiffies)	((void)0)
+#endif
+
+#endif /* _ZFS_BLKDEV_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/include/linux/dcache_compat.h
@@ -0,0 +1,83 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (C) 2011 Lawrence Livermore National Security, LLC.
+ */
+
+#ifndef _ZFS_DCACHE_H
+#define	_ZFS_DCACHE_H
+
+#include <linux/dcache.h>
+
+#define	dname(dentry)	((char *)((dentry)->d_name.name))
+#define	dlen(dentry)	((int)((dentry)->d_name.len))
+
+#ifndef HAVE_D_MAKE_ROOT
+#define	d_make_root(inode)	d_alloc_root(inode)
+#endif /* HAVE_D_MAKE_ROOT */
+
+/*
+ * 2.6.30 API change,
+ * The const keyword was added to the 'struct dentry_operations' in
+ * the dentry structure.  To handle this we define an appropriate
+ * dentry_operations_t typedef which can be used.
+ */
+#ifdef HAVE_CONST_DENTRY_OPERATIONS
+typedef const struct dentry_operations	dentry_operations_t;
+#else
+typedef struct dentry_operations	dentry_operations_t;
+#endif
+
+/*
+ * 2.6.38 API change,
+ * Added d_set_d_op() helper function which sets some flags in
+ * dentry->d_flags based on which operations are defined.
+ */
+#ifndef HAVE_D_SET_D_OP
+static inline void
+d_set_d_op(struct dentry *dentry, dentry_operations_t *op)
+{
+	dentry->d_op = op;
+}
+#endif /* HAVE_D_SET_D_OP */
+
+/*
+ * 2.6.38 API addition,
+ * Added d_clear_d_op() helper function which clears some flags and the
+ * registered dentry->d_op table.  This is required because d_set_d_op()
+ * issues a warning when the dentry operations table is already set.
+ * For the .zfs control directory to work properly we must be able to
+ * override the default operations table and register custom .d_automount
+ * and .d_revalidate callbacks.
+ */
+static inline void
+d_clear_d_op(struct dentry *dentry)
+{
+#ifdef HAVE_D_SET_D_OP
+	dentry->d_op = NULL;
+	dentry->d_flags &= ~(
+	    DCACHE_OP_HASH | DCACHE_OP_COMPARE |
+	    DCACHE_OP_REVALIDATE | DCACHE_OP_DELETE);
+#endif /* HAVE_D_SET_D_OP */
+}
+
+#endif /* _ZFS_DCACHE_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/include/linux/kmap_compat.h
@@ -0,0 +1,40 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2015 by Chunwei Chen. All rights reserved.
+ */
+
+#ifndef _ZFS_KMAP_H
+#define	_ZFS_KMAP_H
+
+#include <linux/highmem.h>
+
+#ifdef HAVE_1ARG_KMAP_ATOMIC
+/* 2.6.37 API change */
+#define	zfs_kmap_atomic(page, km_type)		kmap_atomic(page)
+#define	zfs_kunmap_atomic(addr, km_type)	kunmap_atomic(addr)
+#else
+#define	zfs_kmap_atomic(page, km_type)		kmap_atomic(page, km_type)
+#define	zfs_kunmap_atomic(addr, km_type)	kunmap_atomic(addr, km_type)
+#endif
+
+#endif	/* _ZFS_KMAP_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/include/linux/utsname_compat.h
@@ -0,0 +1,29 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+#ifndef	_ZFS_UTSNAME_H
+#define	_ZFS_UTSNAME_H
+
+#include <linux/utsname.h>
+
+typedef struct new_utsname	utsname_t;
+
+#endif	/* _ZFS_UTSNAME_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/include/linux/vfs_compat.h
@@ -0,0 +1,366 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (C) 2011 Lawrence Livermore National Security, LLC.
+ * Copyright (C) 2015 Jörg Thalheim.
+ */
+
+#ifndef _ZFS_VFS_H
+#define	_ZFS_VFS_H
+
+#include <sys/taskq.h>
+#include <linux/backing-dev.h>
+
+/*
+ * 2.6.28 API change,
+ * Added insert_inode_locked() helper function, prior to this most callers
+ * used insert_inode_hash().  The older method doesn't check for collisions
+ * in the inode_hashtable but it still acceptible for use.
+ */
+#ifndef HAVE_INSERT_INODE_LOCKED
+static inline int
+insert_inode_locked(struct inode *ip)
+{
+	insert_inode_hash(ip);
+	return (0);
+}
+#endif /* HAVE_INSERT_INODE_LOCKED */
+
+/*
+ * 2.6.35 API change,
+ * Add truncate_setsize() if it is not exported by the Linux kernel.
+ *
+ * Truncate the inode and pages associated with the inode. The pages are
+ * unmapped and removed from cache.
+ */
+#ifndef HAVE_TRUNCATE_SETSIZE
+static inline void
+truncate_setsize(struct inode *ip, loff_t new)
+{
+	struct address_space *mapping = ip->i_mapping;
+
+	i_size_write(ip, new);
+
+	unmap_mapping_range(mapping, new + PAGE_SIZE - 1, 0, 1);
+	truncate_inode_pages(mapping, new);
+	unmap_mapping_range(mapping, new + PAGE_SIZE - 1, 0, 1);
+}
+#endif /* HAVE_TRUNCATE_SETSIZE */
+
+/*
+ * 2.6.32 - 2.6.33, bdi_setup_and_register() is not available.
+ * 2.6.34 - 3.19, bdi_setup_and_register() takes 3 arguments.
+ * 4.0 - x.y, bdi_setup_and_register() takes 2 arguments.
+ */
+#if defined(HAVE_2ARGS_BDI_SETUP_AND_REGISTER)
+static inline int
+zpl_bdi_setup_and_register(struct backing_dev_info *bdi, char *name)
+{
+	return (bdi_setup_and_register(bdi, name));
+}
+#elif defined(HAVE_3ARGS_BDI_SETUP_AND_REGISTER)
+static inline int
+zpl_bdi_setup_and_register(struct backing_dev_info *bdi, char *name)
+{
+	return (bdi_setup_and_register(bdi, name, BDI_CAP_MAP_COPY));
+}
+#else
+extern atomic_long_t zfs_bdi_seq;
+
+static inline int
+zpl_bdi_setup_and_register(struct backing_dev_info *bdi, char *name)
+{
+	char tmp[32];
+	int error;
+
+	bdi->name = name;
+	bdi->capabilities = BDI_CAP_MAP_COPY;
+
+	error = bdi_init(bdi);
+	if (error)
+		return (error);
+
+	sprintf(tmp, "%.28s%s", name, "-%d");
+	error = bdi_register(bdi, NULL, tmp,
+	    atomic_long_inc_return(&zfs_bdi_seq));
+	if (error) {
+		bdi_destroy(bdi);
+		return (error);
+	}
+
+	return (error);
+}
+#endif
+
+/*
+ * 2.6.38 API change,
+ * LOOKUP_RCU flag introduced to distinguish rcu-walk from ref-walk cases.
+ */
+#ifndef LOOKUP_RCU
+#define	LOOKUP_RCU	0x0
+#endif /* LOOKUP_RCU */
+
+/*
+ * 3.2-rc1 API change,
+ * Add set_nlink() if it is not exported by the Linux kernel.
+ *
+ * i_nlink is read-only in Linux 3.2, but it can be set directly in
+ * earlier kernels.
+ */
+#ifndef HAVE_SET_NLINK
+static inline void
+set_nlink(struct inode *inode, unsigned int nlink)
+{
+	inode->i_nlink = nlink;
+}
+#endif /* HAVE_SET_NLINK */
+
+/*
+ * 3.3 API change,
+ * The VFS .create, .mkdir and .mknod callbacks were updated to take a
+ * umode_t type rather than an int.  To cleanly handle both definitions
+ * the zpl_umode_t type is introduced and set accordingly.
+ */
+#ifdef HAVE_MKDIR_UMODE_T
+typedef	umode_t		zpl_umode_t;
+#else
+typedef	int		zpl_umode_t;
+#endif
+
+/*
+ * 3.5 API change,
+ * The clear_inode() function replaces end_writeback() and introduces an
+ * ordering change regarding when the inode_sync_wait() occurs.  See the
+ * configure check in config/kernel-clear-inode.m4 for full details.
+ */
+#if defined(HAVE_EVICT_INODE) && !defined(HAVE_CLEAR_INODE)
+#define	clear_inode(ip)		end_writeback(ip)
+#endif /* HAVE_EVICT_INODE && !HAVE_CLEAR_INODE */
+
+/*
+ * 3.6 API change,
+ * The sget() helper function now takes the mount flags as an argument.
+ */
+#ifdef HAVE_5ARG_SGET
+#define	zpl_sget(type, cmp, set, fl, mtd)	sget(type, cmp, set, fl, mtd)
+#else
+#define	zpl_sget(type, cmp, set, fl, mtd)	sget(type, cmp, set, mtd)
+#endif /* HAVE_5ARG_SGET */
+
+#if defined(SEEK_HOLE) && defined(SEEK_DATA) && !defined(HAVE_LSEEK_EXECUTE)
+static inline loff_t
+lseek_execute(
+	struct file *filp,
+	struct inode *inode,
+	loff_t offset,
+	loff_t maxsize)
+{
+	if (offset < 0 && !(filp->f_mode & FMODE_UNSIGNED_OFFSET))
+		return (-EINVAL);
+
+	if (offset > maxsize)
+		return (-EINVAL);
+
+	if (offset != filp->f_pos) {
+		spin_lock(&filp->f_lock);
+		filp->f_pos = offset;
+		filp->f_version = 0;
+		spin_unlock(&filp->f_lock);
+	}
+
+	return (offset);
+}
+#endif /* SEEK_HOLE && SEEK_DATA && !HAVE_LSEEK_EXECUTE */
+
+#if defined(CONFIG_FS_POSIX_ACL)
+/*
+ * These functions safely approximates the behavior of posix_acl_release()
+ * which cannot be used because it calls the GPL-only symbol kfree_rcu().
+ * The in-kernel version, which can access the RCU, frees the ACLs after
+ * the grace period expires.  Because we're unsure how long that grace
+ * period may be this implementation conservatively delays for 60 seconds.
+ * This is several orders of magnitude larger than expected grace period.
+ * At 60 seconds the kernel will also begin issuing RCU stall warnings.
+ */
+#include <linux/posix_acl.h>
+#ifndef HAVE_POSIX_ACL_CACHING
+#define	ACL_NOT_CACHED ((void *)(-1))
+#endif /* HAVE_POSIX_ACL_CACHING */
+
+#if defined(HAVE_POSIX_ACL_RELEASE) && !defined(HAVE_POSIX_ACL_RELEASE_GPL_ONLY)
+
+#define	zpl_posix_acl_release(arg)		posix_acl_release(arg)
+#define	zpl_set_cached_acl(ip, ty, n)		set_cached_acl(ip, ty, n)
+#define	zpl_forget_cached_acl(ip, ty)		forget_cached_acl(ip, ty)
+
+#else
+
+static inline void
+zpl_posix_acl_free(void *arg) {
+	kfree(arg);
+}
+
+static inline void
+zpl_posix_acl_release(struct posix_acl *acl)
+{
+	if ((acl == NULL) || (acl == ACL_NOT_CACHED))
+		return;
+
+	if (atomic_dec_and_test(&acl->a_refcount)) {
+		taskq_dispatch_delay(system_taskq, zpl_posix_acl_free, acl,
+		    TQ_SLEEP, ddi_get_lbolt() + 60*HZ);
+	}
+}
+
+static inline void
+zpl_set_cached_acl(struct inode *ip, int type, struct posix_acl *newer) {
+#ifdef HAVE_POSIX_ACL_CACHING
+	struct posix_acl *older = NULL;
+
+	spin_lock(&ip->i_lock);
+
+	if ((newer != ACL_NOT_CACHED) && (newer != NULL))
+		posix_acl_dup(newer);
+
+	switch (type) {
+	case ACL_TYPE_ACCESS:
+		older = ip->i_acl;
+		rcu_assign_pointer(ip->i_acl, newer);
+		break;
+	case ACL_TYPE_DEFAULT:
+		older = ip->i_default_acl;
+		rcu_assign_pointer(ip->i_default_acl, newer);
+		break;
+	}
+
+	spin_unlock(&ip->i_lock);
+
+	zpl_posix_acl_release(older);
+#endif /* HAVE_POSIX_ACL_CACHING */
+}
+
+static inline void
+zpl_forget_cached_acl(struct inode *ip, int type) {
+	zpl_set_cached_acl(ip, type, (struct posix_acl *)ACL_NOT_CACHED);
+}
+#endif /* HAVE_POSIX_ACL_RELEASE */
+
+#ifndef HAVE___POSIX_ACL_CHMOD
+#ifdef HAVE_POSIX_ACL_CHMOD
+#define	__posix_acl_chmod(acl, gfp, mode)	posix_acl_chmod(acl, gfp, mode)
+#define	__posix_acl_create(acl, gfp, mode)	posix_acl_create(acl, gfp, mode)
+#else
+static inline int
+__posix_acl_chmod(struct posix_acl **acl, int flags, umode_t umode) {
+	struct posix_acl *oldacl = *acl;
+	mode_t mode = umode;
+	int error;
+
+	*acl = posix_acl_clone(*acl, flags);
+	zpl_posix_acl_release(oldacl);
+
+	if (!(*acl))
+		return (-ENOMEM);
+
+	error = posix_acl_chmod_masq(*acl, mode);
+	if (error) {
+		zpl_posix_acl_release(*acl);
+		*acl = NULL;
+	}
+
+	return (error);
+}
+
+static inline int
+__posix_acl_create(struct posix_acl **acl, int flags, umode_t *umodep) {
+	struct posix_acl *oldacl = *acl;
+	mode_t mode = *umodep;
+	int error;
+
+	*acl = posix_acl_clone(*acl, flags);
+	zpl_posix_acl_release(oldacl);
+
+	if (!(*acl))
+		return (-ENOMEM);
+
+	error = posix_acl_create_masq(*acl, &mode);
+	*umodep = mode;
+
+	if (error < 0) {
+		zpl_posix_acl_release(*acl);
+		*acl = NULL;
+	}
+
+	return (error);
+}
+#endif /* HAVE_POSIX_ACL_CHMOD */
+#endif /* HAVE___POSIX_ACL_CHMOD */
+
+#ifdef HAVE_POSIX_ACL_EQUIV_MODE_UMODE_T
+typedef umode_t zpl_equivmode_t;
+#else
+typedef mode_t zpl_equivmode_t;
+#endif /* HAVE_POSIX_ACL_EQUIV_MODE_UMODE_T */
+#endif /* CONFIG_FS_POSIX_ACL */
+
+#ifndef HAVE_CURRENT_UMASK
+static inline int
+current_umask(void)
+{
+	return (current->fs->umask);
+}
+#endif /* HAVE_CURRENT_UMASK */
+
+/*
+ * 2.6.38 API change,
+ * The is_owner_or_cap() function was renamed to inode_owner_or_capable().
+ */
+#ifdef HAVE_INODE_OWNER_OR_CAPABLE
+#define	zpl_inode_owner_or_capable(ip)		inode_owner_or_capable(ip)
+#else
+#define	zpl_inode_owner_or_capable(ip)		is_owner_or_cap(ip)
+#endif /* HAVE_INODE_OWNER_OR_CAPABLE */
+
+/*
+ * 3.19 API change
+ * struct access f->f_dentry->d_inode was replaced by accessor function
+ * file_inode(f)
+ */
+#ifndef HAVE_FILE_INODE
+static inline struct inode *file_inode(const struct file *f)
+{
+	return (f->f_dentry->d_inode);
+}
+#endif /* HAVE_FILE_INODE */
+
+/*
+ * 2.6.38 API change
+ */
+#ifdef HAVE_FOLLOW_DOWN_ONE
+#define	zpl_follow_down_one(path)		follow_down_one(path)
+#define	zpl_follow_up(path)			follow_up(path)
+#else
+#define	zpl_follow_down_one(path)		follow_down(path)
+#define	zpl_follow_up(path)			follow_up(path)
+#endif
+
+#endif /* _ZFS_VFS_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/include/linux/xattr_compat.h
@@ -0,0 +1,224 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (C) 2011 Lawrence Livermore National Security, LLC.
+ */
+
+#ifndef _ZFS_XATTR_H
+#define	_ZFS_XATTR_H
+
+#include <linux/posix_acl_xattr.h>
+
+/*
+ * 2.6.35 API change,
+ * The const keyword was added to the 'struct xattr_handler' in the
+ * generic Linux super_block structure.  To handle this we define an
+ * appropriate xattr_handler_t typedef which can be used.  This was
+ * the preferred solution because it keeps the code clean and readable.
+ */
+#ifdef HAVE_CONST_XATTR_HANDLER
+typedef const struct xattr_handler	xattr_handler_t;
+#else
+typedef struct xattr_handler		xattr_handler_t;
+#endif
+
+/*
+ * 3.7 API change,
+ * Preferred XATTR_NAME_* definitions introduced, these are mapped to
+ * the previous definitions for older kernels.
+ */
+#ifndef XATTR_NAME_POSIX_ACL_DEFAULT
+#define	XATTR_NAME_POSIX_ACL_DEFAULT	POSIX_ACL_XATTR_DEFAULT
+#endif
+
+#ifndef XATTR_NAME_POSIX_ACL_ACCESS
+#define	XATTR_NAME_POSIX_ACL_ACCESS	POSIX_ACL_XATTR_ACCESS
+#endif
+
+/*
+ * 4.5 API change,
+ */
+#if defined(HAVE_XATTR_LIST_SIMPLE)
+#define	ZPL_XATTR_LIST_WRAPPER(fn)					\
+static bool								\
+fn(struct dentry *dentry)						\
+{									\
+	return (!!__ ## fn(dentry->d_inode, NULL, 0, NULL, 0));		\
+}
+/*
+ * 4.4 API change,
+ */
+#elif defined(HAVE_XATTR_LIST_DENTRY)
+#define	ZPL_XATTR_LIST_WRAPPER(fn)					\
+static size_t								\
+fn(struct dentry *dentry, char *list, size_t list_size,			\
+    const char *name, size_t name_len, int type)			\
+{									\
+	return (__ ## fn(dentry->d_inode,				\
+	    list, list_size, name, name_len));				\
+}
+/*
+ * 2.6.33 API change,
+ */
+#elif defined(HAVE_XATTR_LIST_HANDLER)
+#define	ZPL_XATTR_LIST_WRAPPER(fn)					\
+static size_t								\
+fn(const struct xattr_handler *handler, struct dentry *dentry,		\
+    char *list, size_t list_size, const char *name, size_t name_len)	\
+{									\
+	return (__ ## fn(dentry->d_inode,				\
+	    list, list_size, name, name_len));				\
+}
+/*
+ * 2.6.32 API
+ */
+#elif defined(HAVE_XATTR_LIST_INODE)
+#define	ZPL_XATTR_LIST_WRAPPER(fn)					\
+static size_t								\
+fn(struct inode *ip, char *list, size_t list_size,			\
+    const char *name, size_t name_len)					\
+{									\
+	return (__ ## fn(ip, list, list_size, name, name_len));		\
+}
+#endif
+
+/*
+ * 4.4 API change,
+ * The xattr_handler->get() callback was changed to take a xattr_handler,
+ * and handler_flags argument was removed and should be accessed by
+ * handler->flags.
+ */
+#if defined(HAVE_XATTR_GET_HANDLER)
+#define	ZPL_XATTR_GET_WRAPPER(fn)					\
+static int								\
+fn(const struct xattr_handler *handler, struct dentry *dentry,		\
+    const char *name, void *buffer, size_t size)			\
+{									\
+	return (__ ## fn(dentry->d_inode, name, buffer, size));		\
+}
+/*
+ * 2.6.33 API change,
+ * The xattr_handler->get() callback was changed to take a dentry
+ * instead of an inode, and a handler_flags argument was added.
+ */
+#elif defined(HAVE_XATTR_GET_DENTRY)
+#define	ZPL_XATTR_GET_WRAPPER(fn)					\
+static int								\
+fn(struct dentry *dentry, const char *name, void *buffer, size_t size,	\
+    int unused_handler_flags)						\
+{									\
+	return (__ ## fn(dentry->d_inode, name, buffer, size));		\
+}
+/*
+ * 2.6.32 API
+ */
+#elif defined(HAVE_XATTR_GET_INODE)
+#define	ZPL_XATTR_GET_WRAPPER(fn)					\
+static int								\
+fn(struct inode *ip, const char *name, void *buffer, size_t size)	\
+{									\
+	return (__ ## fn(ip, name, buffer, size));			\
+}
+#endif
+
+/*
+ * 4.4 API change,
+ * The xattr_handler->set() callback was changed to take a xattr_handler,
+ * and handler_flags argument was removed and should be accessed by
+ * handler->flags.
+ */
+#if defined(HAVE_XATTR_SET_HANDLER)
+#define	ZPL_XATTR_SET_WRAPPER(fn)					\
+static int								\
+fn(const struct xattr_handler *handler, struct dentry *dentry,		\
+    const char *name, const void *buffer, size_t size, int flags)	\
+{									\
+	return (__ ## fn(dentry->d_inode, name, buffer, size, flags));	\
+}
+/*
+ * 2.6.33 API change,
+ * The xattr_handler->set() callback was changed to take a dentry
+ * instead of an inode, and a handler_flags argument was added.
+ */
+#elif defined(HAVE_XATTR_SET_DENTRY)
+#define	ZPL_XATTR_SET_WRAPPER(fn)					\
+static int								\
+fn(struct dentry *dentry, const char *name, const void *buffer,		\
+    size_t size, int flags, int unused_handler_flags)			\
+{									\
+	return (__ ## fn(dentry->d_inode, name, buffer, size, flags));	\
+}
+/*
+ * 2.6.32 API
+ */
+#elif defined(HAVE_XATTR_SET_INODE)
+#define	ZPL_XATTR_SET_WRAPPER(fn)					\
+static int								\
+fn(struct inode *ip, const char *name, const void *buffer,		\
+    size_t size, int flags)						\
+{									\
+	return (__ ## fn(ip, name, buffer, size, flags));		\
+}
+#endif
+
+#ifdef HAVE_6ARGS_SECURITY_INODE_INIT_SECURITY
+#define	zpl_security_inode_init_security(ip, dip, qstr, nm, val, len)	\
+	security_inode_init_security(ip, dip, qstr, nm, val, len)
+#else
+#define	zpl_security_inode_init_security(ip, dip, qstr, nm, val, len)	\
+	security_inode_init_security(ip, dip, nm, val, len)
+#endif /* HAVE_6ARGS_SECURITY_INODE_INIT_SECURITY */
+
+/*
+ * Linux 3.7 API change. posix_acl_{from,to}_xattr gained the user_ns
+ * parameter.  All callers are expected to pass the &init_user_ns which
+ * is available through the init credential (kcred).
+ */
+#ifdef HAVE_POSIX_ACL_FROM_XATTR_USERNS
+static inline struct posix_acl *
+zpl_acl_from_xattr(const void *value, int size)
+{
+	return (posix_acl_from_xattr(kcred->user_ns, value, size));
+}
+
+static inline int
+zpl_acl_to_xattr(struct posix_acl *acl, void *value, int size)
+{
+	return (posix_acl_to_xattr(kcred->user_ns, acl, value, size));
+}
+
+#else
+
+static inline struct posix_acl *
+zpl_acl_from_xattr(const void *value, int size)
+{
+	return (posix_acl_from_xattr(value, size));
+}
+
+static inline int
+zpl_acl_to_xattr(struct posix_acl *acl, void *value, int size)
+{
+	return (posix_acl_to_xattr(acl, value, size));
+}
+#endif /* HAVE_POSIX_ACL_FROM_XATTR_USERNS */
+
+#endif /* _ZFS_XATTR_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/include/sys/Makefile.am
@@ -0,0 +1,119 @@
+SUBDIRS = fm fs
+
+COMMON_H = \
+	$(top_srcdir)/include/sys/arc.h \
+	$(top_srcdir)/include/sys/arc_impl.h \
+	$(top_srcdir)/include/sys/avl.h \
+	$(top_srcdir)/include/sys/avl_impl.h \
+	$(top_srcdir)/include/sys/blkptr.h \
+	$(top_srcdir)/include/sys/bplist.h \
+	$(top_srcdir)/include/sys/bpobj.h \
+	$(top_srcdir)/include/sys/bptree.h \
+	$(top_srcdir)/include/sys/dbuf.h \
+	$(top_srcdir)/include/sys/ddt.h \
+	$(top_srcdir)/include/sys/dmu.h \
+	$(top_srcdir)/include/sys/dmu_impl.h \
+	$(top_srcdir)/include/sys/dmu_objset.h \
+	$(top_srcdir)/include/sys/dmu_send.h \
+	$(top_srcdir)/include/sys/dmu_traverse.h \
+	$(top_srcdir)/include/sys/dmu_tx.h \
+	$(top_srcdir)/include/sys/dmu_zfetch.h \
+	$(top_srcdir)/include/sys/dnode.h \
+	$(top_srcdir)/include/sys/dsl_bookmark.h \
+	$(top_srcdir)/include/sys/dsl_dataset.h \
+	$(top_srcdir)/include/sys/dsl_deadlist.h \
+	$(top_srcdir)/include/sys/dsl_deleg.h \
+	$(top_srcdir)/include/sys/dsl_destroy.h \
+	$(top_srcdir)/include/sys/dsl_dir.h \
+	$(top_srcdir)/include/sys/dsl_pool.h \
+	$(top_srcdir)/include/sys/dsl_prop.h \
+	$(top_srcdir)/include/sys/dsl_scan.h \
+	$(top_srcdir)/include/sys/dsl_synctask.h \
+	$(top_srcdir)/include/sys/dsl_userhold.h \
+	$(top_srcdir)/include/sys/efi_partition.h \
+	$(top_srcdir)/include/sys/metaslab.h \
+	$(top_srcdir)/include/sys/metaslab_impl.h \
+	$(top_srcdir)/include/sys/mntent.h \
+	$(top_srcdir)/include/sys/multilist.h \
+	$(top_srcdir)/include/sys/nvpair.h \
+	$(top_srcdir)/include/sys/nvpair_impl.h \
+	$(top_srcdir)/include/sys/range_tree.h \
+	$(top_srcdir)/include/sys/refcount.h \
+	$(top_srcdir)/include/sys/rrwlock.h \
+	$(top_srcdir)/include/sys/sa.h \
+	$(top_srcdir)/include/sys/sa_impl.h \
+	$(top_srcdir)/include/sys/sdt.h \
+	$(top_srcdir)/include/sys/spa_boot.h \
+	$(top_srcdir)/include/sys/space_map.h \
+	$(top_srcdir)/include/sys/space_reftree.h \
+	$(top_srcdir)/include/sys/spa.h \
+	$(top_srcdir)/include/sys/spa_impl.h \
+	$(top_srcdir)/include/sys/trace.h \
+	$(top_srcdir)/include/sys/trace_acl.h \
+	$(top_srcdir)/include/sys/trace_arc.h \
+	$(top_srcdir)/include/sys/trace_dbgmsg.h \
+	$(top_srcdir)/include/sys/trace_dbuf.h \
+	$(top_srcdir)/include/sys/trace_dmu.h \
+	$(top_srcdir)/include/sys/trace_dnode.h \
+	$(top_srcdir)/include/sys/trace_multilist.h \
+	$(top_srcdir)/include/sys/trace_txg.h \
+	$(top_srcdir)/include/sys/trace_zil.h \
+	$(top_srcdir)/include/sys/trace_zrlock.h \
+	$(top_srcdir)/include/sys/txg.h \
+	$(top_srcdir)/include/sys/txg_impl.h \
+	$(top_srcdir)/include/sys/u8_textprep_data.h \
+	$(top_srcdir)/include/sys/u8_textprep.h \
+	$(top_srcdir)/include/sys/uberblock.h \
+	$(top_srcdir)/include/sys/uberblock_impl.h \
+	$(top_srcdir)/include/sys/uio_impl.h \
+	$(top_srcdir)/include/sys/unique.h \
+	$(top_srcdir)/include/sys/uuid.h \
+	$(top_srcdir)/include/sys/vdev_disk.h \
+	$(top_srcdir)/include/sys/vdev_file.h \
+	$(top_srcdir)/include/sys/vdev.h \
+	$(top_srcdir)/include/sys/vdev_impl.h \
+	$(top_srcdir)/include/sys/xvattr.h \
+	$(top_srcdir)/include/sys/zap.h \
+	$(top_srcdir)/include/sys/zap_impl.h \
+	$(top_srcdir)/include/sys/zap_leaf.h \
+	$(top_srcdir)/include/sys/zfeature.h \
+	$(top_srcdir)/include/sys/zfs_acl.h \
+	$(top_srcdir)/include/sys/zfs_context.h \
+	$(top_srcdir)/include/sys/zfs_ctldir.h \
+	$(top_srcdir)/include/sys/zfs_debug.h \
+	$(top_srcdir)/include/sys/zfs_delay.h \
+	$(top_srcdir)/include/sys/zfs_dir.h \
+	$(top_srcdir)/include/sys/zfs_fuid.h \
+	$(top_srcdir)/include/sys/zfs_rlock.h \
+	$(top_srcdir)/include/sys/zfs_sa.h \
+	$(top_srcdir)/include/sys/zfs_stat.h \
+	$(top_srcdir)/include/sys/zfs_vfsops.h \
+	$(top_srcdir)/include/sys/zfs_vnops.h \
+	$(top_srcdir)/include/sys/zfs_znode.h \
+	$(top_srcdir)/include/sys/zil.h \
+	$(top_srcdir)/include/sys/zil_impl.h \
+	$(top_srcdir)/include/sys/zio_checksum.h \
+	$(top_srcdir)/include/sys/zio_compress.h \
+	$(top_srcdir)/include/sys/zio.h \
+	$(top_srcdir)/include/sys/zio_impl.h \
+	$(top_srcdir)/include/sys/zrlock.h
+
+KERNEL_H = \
+	$(top_srcdir)/include/sys/zfs_ioctl.h \
+	$(top_srcdir)/include/sys/zfs_onexit.h \
+	${top_srcdir}/include/sys/zpl.h \
+	$(top_srcdir)/include/sys/zvol.h
+
+USER_H =
+
+EXTRA_DIST = $(COMMON_H) $(KERNEL_H) $(USER_H)
+
+if CONFIG_USER
+libzfsdir = $(includedir)/libzfs/sys
+libzfs_HEADERS = $(COMMON_H) $(USER_H)
+endif
+
+if CONFIG_KERNEL
+kerneldir = @prefix@/src/zfs-$(VERSION)/include/sys
+kernel_HEADERS = $(COMMON_H) $(KERNEL_H)
+endif
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/include/sys/Makefile.in
@@ -0,0 +1,1163 @@
+# Makefile.in generated by automake 1.15 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2014 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+VPATH = @srcdir@
+am__is_gnu_make = { \
+  if test -z '$(MAKELEVEL)'; then \
+    false; \
+  elif test -n '$(MAKE_HOST)'; then \
+    true; \
+  elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+    true; \
+  else \
+    false; \
+  fi; \
+}
+am__make_running_with_option = \
+  case $${target_option-} in \
+      ?) ;; \
+      *) echo "am__make_running_with_option: internal error: invalid" \
+              "target option '$${target_option-}' specified" >&2; \
+         exit 1;; \
+  esac; \
+  has_opt=no; \
+  sane_makeflags=$$MAKEFLAGS; \
+  if $(am__is_gnu_make); then \
+    sane_makeflags=$$MFLAGS; \
+  else \
+    case $$MAKEFLAGS in \
+      *\\[\ \	]*) \
+        bs=\\; \
+        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
+    esac; \
+  fi; \
+  skip_next=no; \
+  strip_trailopt () \
+  { \
+    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+  }; \
+  for flg in $$sane_makeflags; do \
+    test $$skip_next = yes && { skip_next=no; continue; }; \
+    case $$flg in \
+      *=*|--*) continue;; \
+        -*I) strip_trailopt 'I'; skip_next=yes;; \
+      -*I?*) strip_trailopt 'I';; \
+        -*O) strip_trailopt 'O'; skip_next=yes;; \
+      -*O?*) strip_trailopt 'O';; \
+        -*l) strip_trailopt 'l'; skip_next=yes;; \
+      -*l?*) strip_trailopt 'l';; \
+      -[dEDm]) skip_next=yes;; \
+      -[JT]) skip_next=yes;; \
+    esac; \
+    case $$flg in \
+      *$$target_option*) has_opt=yes; break;; \
+    esac; \
+  done; \
+  test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+target_triplet = @target@
+subdir = include/sys
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/config/always-no-bool-compare.m4 \
+	$(top_srcdir)/config/always-no-unused-but-set-variable.m4 \
+	$(top_srcdir)/config/dkms.m4 \
+	$(top_srcdir)/config/kernel-acl.m4 \
+	$(top_srcdir)/config/kernel-automount.m4 \
+	$(top_srcdir)/config/kernel-bdev-block-device-operations.m4 \
+	$(top_srcdir)/config/kernel-bdev-logical-size.m4 \
+	$(top_srcdir)/config/kernel-bdev-physical-size.m4 \
+	$(top_srcdir)/config/kernel-bdi-setup-and-register.m4 \
+	$(top_srcdir)/config/kernel-bio-bvec-iter.m4 \
+	$(top_srcdir)/config/kernel-bio-end-io-t-args.m4 \
+	$(top_srcdir)/config/kernel-bio-failfast.m4 \
+	$(top_srcdir)/config/kernel-bio-rw-barrier.m4 \
+	$(top_srcdir)/config/kernel-bio-rw-discard.m4 \
+	$(top_srcdir)/config/kernel-blk-queue-flush.m4 \
+	$(top_srcdir)/config/kernel-blk-queue-max-hw-sectors.m4 \
+	$(top_srcdir)/config/kernel-blk-queue-max-segments.m4 \
+	$(top_srcdir)/config/kernel-blkdev-get-by-path.m4 \
+	$(top_srcdir)/config/kernel-blkdev-get.m4 \
+	$(top_srcdir)/config/kernel-block-device-operations-release-void.m4 \
+	$(top_srcdir)/config/kernel-check-disk-size-change.m4 \
+	$(top_srcdir)/config/kernel-clear-inode.m4 \
+	$(top_srcdir)/config/kernel-commit-metadata.m4 \
+	$(top_srcdir)/config/kernel-create-nameidata.m4 \
+	$(top_srcdir)/config/kernel-current_bio_tail.m4 \
+	$(top_srcdir)/config/kernel-d-make-root.m4 \
+	$(top_srcdir)/config/kernel-d-obtain-alias.m4 \
+	$(top_srcdir)/config/kernel-d-prune-aliases.m4 \
+	$(top_srcdir)/config/kernel-declare-event-class.m4 \
+	$(top_srcdir)/config/kernel-dentry-operations.m4 \
+	$(top_srcdir)/config/kernel-dirty-inode.m4 \
+	$(top_srcdir)/config/kernel-discard-granularity.m4 \
+	$(top_srcdir)/config/kernel-elevator-change.m4 \
+	$(top_srcdir)/config/kernel-encode-fh-inode.m4 \
+	$(top_srcdir)/config/kernel-evict-inode.m4 \
+	$(top_srcdir)/config/kernel-fallocate.m4 \
+	$(top_srcdir)/config/kernel-file-inode.m4 \
+	$(top_srcdir)/config/kernel-fmode-t.m4 \
+	$(top_srcdir)/config/kernel-follow-down-one.m4 \
+	$(top_srcdir)/config/kernel-fsync.m4 \
+	$(top_srcdir)/config/kernel-generic_io_acct.m4 \
+	$(top_srcdir)/config/kernel-get-disk-ro.m4 \
+	$(top_srcdir)/config/kernel-get-gendisk.m4 \
+	$(top_srcdir)/config/kernel-get-link.m4 \
+	$(top_srcdir)/config/kernel-insert-inode-locked.m4 \
+	$(top_srcdir)/config/kernel-invalidate-bdev-args.m4 \
+	$(top_srcdir)/config/kernel-is_owner_or_cap.m4 \
+	$(top_srcdir)/config/kernel-kmap-atomic-args.m4 \
+	$(top_srcdir)/config/kernel-kobj-name-len.m4 \
+	$(top_srcdir)/config/kernel-lookup-bdev.m4 \
+	$(top_srcdir)/config/kernel-lookup-nameidata.m4 \
+	$(top_srcdir)/config/kernel-lseek-execute.m4 \
+	$(top_srcdir)/config/kernel-mk-request-fn.m4 \
+	$(top_srcdir)/config/kernel-mkdir-umode-t.m4 \
+	$(top_srcdir)/config/kernel-mount-nodev.m4 \
+	$(top_srcdir)/config/kernel-open-bdev-exclusive.m4 \
+	$(top_srcdir)/config/kernel-put-link.m4 \
+	$(top_srcdir)/config/kernel-security-inode-init.m4 \
+	$(top_srcdir)/config/kernel-set-nlink.m4 \
+	$(top_srcdir)/config/kernel-sget-args.m4 \
+	$(top_srcdir)/config/kernel-show-options.m4 \
+	$(top_srcdir)/config/kernel-shrink.m4 \
+	$(top_srcdir)/config/kernel-truncate-range.m4 \
+	$(top_srcdir)/config/kernel-truncate-setsize.m4 \
+	$(top_srcdir)/config/kernel-vfs-iterate.m4 \
+	$(top_srcdir)/config/kernel-vfs-rw-iterate.m4 \
+	$(top_srcdir)/config/kernel-xattr-handler.m4 \
+	$(top_srcdir)/config/kernel.m4 $(top_srcdir)/config/libtool.m4 \
+	$(top_srcdir)/config/ltoptions.m4 \
+	$(top_srcdir)/config/ltsugar.m4 \
+	$(top_srcdir)/config/ltversion.m4 \
+	$(top_srcdir)/config/lt~obsolete.m4 \
+	$(top_srcdir)/config/mount-helper.m4 \
+	$(top_srcdir)/config/user-arch.m4 \
+	$(top_srcdir)/config/user-dracut.m4 \
+	$(top_srcdir)/config/user-frame-larger-than.m4 \
+	$(top_srcdir)/config/user-libblkid.m4 \
+	$(top_srcdir)/config/user-libuuid.m4 \
+	$(top_srcdir)/config/user-runstatedir.m4 \
+	$(top_srcdir)/config/user-systemd.m4 \
+	$(top_srcdir)/config/user-sysvinit.m4 \
+	$(top_srcdir)/config/user-udev.m4 \
+	$(top_srcdir)/config/user-zlib.m4 $(top_srcdir)/config/user.m4 \
+	$(top_srcdir)/config/zfs-build.m4 \
+	$(top_srcdir)/config/zfs-meta.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(am__kernel_HEADERS_DIST) \
+	$(am__libzfs_HEADERS_DIST) $(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/zfs_config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo "  GEN     " $@;
+am__v_GEN_1 = 
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 = 
+SOURCES =
+DIST_SOURCES =
+RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \
+	ctags-recursive dvi-recursive html-recursive info-recursive \
+	install-data-recursive install-dvi-recursive \
+	install-exec-recursive install-html-recursive \
+	install-info-recursive install-pdf-recursive \
+	install-ps-recursive install-recursive installcheck-recursive \
+	installdirs-recursive pdf-recursive ps-recursive \
+	tags-recursive uninstall-recursive
+am__can_run_installinfo = \
+  case $$AM_UPDATE_INFO_DIR in \
+    n|no|NO) false;; \
+    *) (install-info --version) >/dev/null 2>&1;; \
+  esac
+am__kernel_HEADERS_DIST = $(top_srcdir)/include/sys/arc.h \
+	$(top_srcdir)/include/sys/arc_impl.h \
+	$(top_srcdir)/include/sys/avl.h \
+	$(top_srcdir)/include/sys/avl_impl.h \
+	$(top_srcdir)/include/sys/blkptr.h \
+	$(top_srcdir)/include/sys/bplist.h \
+	$(top_srcdir)/include/sys/bpobj.h \
+	$(top_srcdir)/include/sys/bptree.h \
+	$(top_srcdir)/include/sys/dbuf.h \
+	$(top_srcdir)/include/sys/ddt.h \
+	$(top_srcdir)/include/sys/dmu.h \
+	$(top_srcdir)/include/sys/dmu_impl.h \
+	$(top_srcdir)/include/sys/dmu_objset.h \
+	$(top_srcdir)/include/sys/dmu_send.h \
+	$(top_srcdir)/include/sys/dmu_traverse.h \
+	$(top_srcdir)/include/sys/dmu_tx.h \
+	$(top_srcdir)/include/sys/dmu_zfetch.h \
+	$(top_srcdir)/include/sys/dnode.h \
+	$(top_srcdir)/include/sys/dsl_bookmark.h \
+	$(top_srcdir)/include/sys/dsl_dataset.h \
+	$(top_srcdir)/include/sys/dsl_deadlist.h \
+	$(top_srcdir)/include/sys/dsl_deleg.h \
+	$(top_srcdir)/include/sys/dsl_destroy.h \
+	$(top_srcdir)/include/sys/dsl_dir.h \
+	$(top_srcdir)/include/sys/dsl_pool.h \
+	$(top_srcdir)/include/sys/dsl_prop.h \
+	$(top_srcdir)/include/sys/dsl_scan.h \
+	$(top_srcdir)/include/sys/dsl_synctask.h \
+	$(top_srcdir)/include/sys/dsl_userhold.h \
+	$(top_srcdir)/include/sys/efi_partition.h \
+	$(top_srcdir)/include/sys/metaslab.h \
+	$(top_srcdir)/include/sys/metaslab_impl.h \
+	$(top_srcdir)/include/sys/mntent.h \
+	$(top_srcdir)/include/sys/multilist.h \
+	$(top_srcdir)/include/sys/nvpair.h \
+	$(top_srcdir)/include/sys/nvpair_impl.h \
+	$(top_srcdir)/include/sys/range_tree.h \
+	$(top_srcdir)/include/sys/refcount.h \
+	$(top_srcdir)/include/sys/rrwlock.h \
+	$(top_srcdir)/include/sys/sa.h \
+	$(top_srcdir)/include/sys/sa_impl.h \
+	$(top_srcdir)/include/sys/sdt.h \
+	$(top_srcdir)/include/sys/spa_boot.h \
+	$(top_srcdir)/include/sys/space_map.h \
+	$(top_srcdir)/include/sys/space_reftree.h \
+	$(top_srcdir)/include/sys/spa.h \
+	$(top_srcdir)/include/sys/spa_impl.h \
+	$(top_srcdir)/include/sys/trace.h \
+	$(top_srcdir)/include/sys/trace_acl.h \
+	$(top_srcdir)/include/sys/trace_arc.h \
+	$(top_srcdir)/include/sys/trace_dbgmsg.h \
+	$(top_srcdir)/include/sys/trace_dbuf.h \
+	$(top_srcdir)/include/sys/trace_dmu.h \
+	$(top_srcdir)/include/sys/trace_dnode.h \
+	$(top_srcdir)/include/sys/trace_multilist.h \
+	$(top_srcdir)/include/sys/trace_txg.h \
+	$(top_srcdir)/include/sys/trace_zil.h \
+	$(top_srcdir)/include/sys/trace_zrlock.h \
+	$(top_srcdir)/include/sys/txg.h \
+	$(top_srcdir)/include/sys/txg_impl.h \
+	$(top_srcdir)/include/sys/u8_textprep_data.h \
+	$(top_srcdir)/include/sys/u8_textprep.h \
+	$(top_srcdir)/include/sys/uberblock.h \
+	$(top_srcdir)/include/sys/uberblock_impl.h \
+	$(top_srcdir)/include/sys/uio_impl.h \
+	$(top_srcdir)/include/sys/unique.h \
+	$(top_srcdir)/include/sys/uuid.h \
+	$(top_srcdir)/include/sys/vdev_disk.h \
+	$(top_srcdir)/include/sys/vdev_file.h \
+	$(top_srcdir)/include/sys/vdev.h \
+	$(top_srcdir)/include/sys/vdev_impl.h \
+	$(top_srcdir)/include/sys/xvattr.h \
+	$(top_srcdir)/include/sys/zap.h \
+	$(top_srcdir)/include/sys/zap_impl.h \
+	$(top_srcdir)/include/sys/zap_leaf.h \
+	$(top_srcdir)/include/sys/zfeature.h \
+	$(top_srcdir)/include/sys/zfs_acl.h \
+	$(top_srcdir)/include/sys/zfs_context.h \
+	$(top_srcdir)/include/sys/zfs_ctldir.h \
+	$(top_srcdir)/include/sys/zfs_debug.h \
+	$(top_srcdir)/include/sys/zfs_delay.h \
+	$(top_srcdir)/include/sys/zfs_dir.h \
+	$(top_srcdir)/include/sys/zfs_fuid.h \
+	$(top_srcdir)/include/sys/zfs_rlock.h \
+	$(top_srcdir)/include/sys/zfs_sa.h \
+	$(top_srcdir)/include/sys/zfs_stat.h \
+	$(top_srcdir)/include/sys/zfs_vfsops.h \
+	$(top_srcdir)/include/sys/zfs_vnops.h \
+	$(top_srcdir)/include/sys/zfs_znode.h \
+	$(top_srcdir)/include/sys/zil.h \
+	$(top_srcdir)/include/sys/zil_impl.h \
+	$(top_srcdir)/include/sys/zio_checksum.h \
+	$(top_srcdir)/include/sys/zio_compress.h \
+	$(top_srcdir)/include/sys/zio.h \
+	$(top_srcdir)/include/sys/zio_impl.h \
+	$(top_srcdir)/include/sys/zrlock.h \
+	$(top_srcdir)/include/sys/zfs_ioctl.h \
+	$(top_srcdir)/include/sys/zfs_onexit.h \
+	${top_srcdir}/include/sys/zpl.h \
+	$(top_srcdir)/include/sys/zvol.h
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+    $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+    *) f=$$p;; \
+  esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+  srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+  for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+  for p in $$list; do echo "$$p $$p"; done | \
+  sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+  $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+    if (++n[$$2] == $(am__install_max)) \
+      { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+    END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+  sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+  sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+  test -z "$$files" \
+    || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+    || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+         $(am__cd) "$$dir" && rm -f $$files; }; \
+  }
+am__installdirs = "$(DESTDIR)$(kerneldir)" "$(DESTDIR)$(libzfsdir)"
+am__libzfs_HEADERS_DIST = $(top_srcdir)/include/sys/arc.h \
+	$(top_srcdir)/include/sys/arc_impl.h \
+	$(top_srcdir)/include/sys/avl.h \
+	$(top_srcdir)/include/sys/avl_impl.h \
+	$(top_srcdir)/include/sys/blkptr.h \
+	$(top_srcdir)/include/sys/bplist.h \
+	$(top_srcdir)/include/sys/bpobj.h \
+	$(top_srcdir)/include/sys/bptree.h \
+	$(top_srcdir)/include/sys/dbuf.h \
+	$(top_srcdir)/include/sys/ddt.h \
+	$(top_srcdir)/include/sys/dmu.h \
+	$(top_srcdir)/include/sys/dmu_impl.h \
+	$(top_srcdir)/include/sys/dmu_objset.h \
+	$(top_srcdir)/include/sys/dmu_send.h \
+	$(top_srcdir)/include/sys/dmu_traverse.h \
+	$(top_srcdir)/include/sys/dmu_tx.h \
+	$(top_srcdir)/include/sys/dmu_zfetch.h \
+	$(top_srcdir)/include/sys/dnode.h \
+	$(top_srcdir)/include/sys/dsl_bookmark.h \
+	$(top_srcdir)/include/sys/dsl_dataset.h \
+	$(top_srcdir)/include/sys/dsl_deadlist.h \
+	$(top_srcdir)/include/sys/dsl_deleg.h \
+	$(top_srcdir)/include/sys/dsl_destroy.h \
+	$(top_srcdir)/include/sys/dsl_dir.h \
+	$(top_srcdir)/include/sys/dsl_pool.h \
+	$(top_srcdir)/include/sys/dsl_prop.h \
+	$(top_srcdir)/include/sys/dsl_scan.h \
+	$(top_srcdir)/include/sys/dsl_synctask.h \
+	$(top_srcdir)/include/sys/dsl_userhold.h \
+	$(top_srcdir)/include/sys/efi_partition.h \
+	$(top_srcdir)/include/sys/metaslab.h \
+	$(top_srcdir)/include/sys/metaslab_impl.h \
+	$(top_srcdir)/include/sys/mntent.h \
+	$(top_srcdir)/include/sys/multilist.h \
+	$(top_srcdir)/include/sys/nvpair.h \
+	$(top_srcdir)/include/sys/nvpair_impl.h \
+	$(top_srcdir)/include/sys/range_tree.h \
+	$(top_srcdir)/include/sys/refcount.h \
+	$(top_srcdir)/include/sys/rrwlock.h \
+	$(top_srcdir)/include/sys/sa.h \
+	$(top_srcdir)/include/sys/sa_impl.h \
+	$(top_srcdir)/include/sys/sdt.h \
+	$(top_srcdir)/include/sys/spa_boot.h \
+	$(top_srcdir)/include/sys/space_map.h \
+	$(top_srcdir)/include/sys/space_reftree.h \
+	$(top_srcdir)/include/sys/spa.h \
+	$(top_srcdir)/include/sys/spa_impl.h \
+	$(top_srcdir)/include/sys/trace.h \
+	$(top_srcdir)/include/sys/trace_acl.h \
+	$(top_srcdir)/include/sys/trace_arc.h \
+	$(top_srcdir)/include/sys/trace_dbgmsg.h \
+	$(top_srcdir)/include/sys/trace_dbuf.h \
+	$(top_srcdir)/include/sys/trace_dmu.h \
+	$(top_srcdir)/include/sys/trace_dnode.h \
+	$(top_srcdir)/include/sys/trace_multilist.h \
+	$(top_srcdir)/include/sys/trace_txg.h \
+	$(top_srcdir)/include/sys/trace_zil.h \
+	$(top_srcdir)/include/sys/trace_zrlock.h \
+	$(top_srcdir)/include/sys/txg.h \
+	$(top_srcdir)/include/sys/txg_impl.h \
+	$(top_srcdir)/include/sys/u8_textprep_data.h \
+	$(top_srcdir)/include/sys/u8_textprep.h \
+	$(top_srcdir)/include/sys/uberblock.h \
+	$(top_srcdir)/include/sys/uberblock_impl.h \
+	$(top_srcdir)/include/sys/uio_impl.h \
+	$(top_srcdir)/include/sys/unique.h \
+	$(top_srcdir)/include/sys/uuid.h \
+	$(top_srcdir)/include/sys/vdev_disk.h \
+	$(top_srcdir)/include/sys/vdev_file.h \
+	$(top_srcdir)/include/sys/vdev.h \
+	$(top_srcdir)/include/sys/vdev_impl.h \
+	$(top_srcdir)/include/sys/xvattr.h \
+	$(top_srcdir)/include/sys/zap.h \
+	$(top_srcdir)/include/sys/zap_impl.h \
+	$(top_srcdir)/include/sys/zap_leaf.h \
+	$(top_srcdir)/include/sys/zfeature.h \
+	$(top_srcdir)/include/sys/zfs_acl.h \
+	$(top_srcdir)/include/sys/zfs_context.h \
+	$(top_srcdir)/include/sys/zfs_ctldir.h \
+	$(top_srcdir)/include/sys/zfs_debug.h \
+	$(top_srcdir)/include/sys/zfs_delay.h \
+	$(top_srcdir)/include/sys/zfs_dir.h \
+	$(top_srcdir)/include/sys/zfs_fuid.h \
+	$(top_srcdir)/include/sys/zfs_rlock.h \
+	$(top_srcdir)/include/sys/zfs_sa.h \
+	$(top_srcdir)/include/sys/zfs_stat.h \
+	$(top_srcdir)/include/sys/zfs_vfsops.h \
+	$(top_srcdir)/include/sys/zfs_vnops.h \
+	$(top_srcdir)/include/sys/zfs_znode.h \
+	$(top_srcdir)/include/sys/zil.h \
+	$(top_srcdir)/include/sys/zil_impl.h \
+	$(top_srcdir)/include/sys/zio_checksum.h \
+	$(top_srcdir)/include/sys/zio_compress.h \
+	$(top_srcdir)/include/sys/zio.h \
+	$(top_srcdir)/include/sys/zio_impl.h \
+	$(top_srcdir)/include/sys/zrlock.h
+HEADERS = $(kernel_HEADERS) $(libzfs_HEADERS)
+RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive	\
+  distclean-recursive maintainer-clean-recursive
+am__recursive_targets = \
+  $(RECURSIVE_TARGETS) \
+  $(RECURSIVE_CLEAN_TARGETS) \
+  $(am__extra_recursive_targets)
+AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \
+	distdir
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates.  Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+  BEGIN { nonempty = 0; } \
+  { items[$$0] = 1; nonempty = 1; } \
+  END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique.  This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+  list='$(am__tagged_files)'; \
+  unique=`for i in $$list; do \
+    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+  done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+DIST_SUBDIRS = $(SUBDIRS)
+am__DIST_COMMON = $(srcdir)/Makefile.in
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+am__relativize = \
+  dir0=`pwd`; \
+  sed_first='s,^\([^/]*\)/.*$$,\1,'; \
+  sed_rest='s,^[^/]*/*,,'; \
+  sed_last='s,^.*/\([^/]*\)$$,\1,'; \
+  sed_butlast='s,/*[^/]*$$,,'; \
+  while test -n "$$dir1"; do \
+    first=`echo "$$dir1" | sed -e "$$sed_first"`; \
+    if test "$$first" != "."; then \
+      if test "$$first" = ".."; then \
+        dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \
+        dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \
+      else \
+        first2=`echo "$$dir2" | sed -e "$$sed_first"`; \
+        if test "$$first2" = "$$first"; then \
+          dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \
+        else \
+          dir2="../$$dir2"; \
+        fi; \
+        dir0="$$dir0"/"$$first"; \
+      fi; \
+    fi; \
+    dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \
+  done; \
+  reldir="$$dir2"
+ACLOCAL = @ACLOCAL@
+ALIEN = @ALIEN@
+ALIEN_VERSION = @ALIEN_VERSION@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCAS = @CCAS@
+CCASDEPMODE = @CCASDEPMODE@
+CCASFLAGS = @CCASFLAGS@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEBUG_CFLAGS = @DEBUG_CFLAGS@
+DEBUG_DMU_TX = @DEBUG_DMU_TX@
+DEBUG_STACKFLAGS = @DEBUG_STACKFLAGS@
+DEBUG_ZFS = @DEBUG_ZFS@
+DEFAULT_INITCONF_DIR = @DEFAULT_INITCONF_DIR@
+DEFAULT_INIT_DIR = @DEFAULT_INIT_DIR@
+DEFAULT_INIT_SCRIPT = @DEFAULT_INIT_SCRIPT@
+DEFAULT_PACKAGE = @DEFAULT_PACKAGE@
+DEFINE_INITRAMFS = @DEFINE_INITRAMFS@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DPKG = @DPKG@
+DPKGBUILD = @DPKGBUILD@
+DPKGBUILD_VERSION = @DPKGBUILD_VERSION@
+DPKG_VERSION = @DPKG_VERSION@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+FRAME_LARGER_THAN = @FRAME_LARGER_THAN@
+GREP = @GREP@
+HAVE_ALIEN = @HAVE_ALIEN@
+HAVE_DPKG = @HAVE_DPKG@
+HAVE_DPKGBUILD = @HAVE_DPKGBUILD@
+HAVE_RPM = @HAVE_RPM@
+HAVE_RPMBUILD = @HAVE_RPMBUILD@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+KERNELCPPFLAGS = @KERNELCPPFLAGS@
+KERNELMAKE_PARAMS = @KERNELMAKE_PARAMS@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBBLKID = @LIBBLKID@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIBUUID = @LIBUUID@
+LINUX = @LINUX@
+LINUX_OBJ = @LINUX_OBJ@
+LINUX_SYMBOLS = @LINUX_SYMBOLS@
+LINUX_VERSION = @LINUX_VERSION@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NO_BOOL_COMPARE = @NO_BOOL_COMPARE@
+NO_UNUSED_BUT_SET_VARIABLE = @NO_UNUSED_BUT_SET_VARIABLE@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+RANLIB = @RANLIB@
+RELEASE = @RELEASE@
+RPM = @RPM@
+RPMBUILD = @RPMBUILD@
+RPMBUILD_VERSION = @RPMBUILD_VERSION@
+RPM_DEFINE_COMMON = @RPM_DEFINE_COMMON@
+RPM_DEFINE_DKMS = @RPM_DEFINE_DKMS@
+RPM_DEFINE_KMOD = @RPM_DEFINE_KMOD@
+RPM_DEFINE_UTIL = @RPM_DEFINE_UTIL@
+RPM_SPEC_DIR = @RPM_SPEC_DIR@
+RPM_VERSION = @RPM_VERSION@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SPL = @SPL@
+SPL_OBJ = @SPL_OBJ@
+SPL_SYMBOLS = @SPL_SYMBOLS@
+SPL_VERSION = @SPL_VERSION@
+SRPM_DEFINE_COMMON = @SRPM_DEFINE_COMMON@
+SRPM_DEFINE_DKMS = @SRPM_DEFINE_DKMS@
+SRPM_DEFINE_KMOD = @SRPM_DEFINE_KMOD@
+SRPM_DEFINE_UTIL = @SRPM_DEFINE_UTIL@
+STRIP = @STRIP@
+TARGET_ASM_DIR = @TARGET_ASM_DIR@
+VENDOR = @VENDOR@
+VERSION = @VERSION@
+ZFS_CONFIG = @ZFS_CONFIG@
+ZFS_INIT_SYSTEMD = @ZFS_INIT_SYSTEMD@
+ZFS_INIT_SYSV = @ZFS_INIT_SYSV@
+ZFS_META_ALIAS = @ZFS_META_ALIAS@
+ZFS_META_AUTHOR = @ZFS_META_AUTHOR@
+ZFS_META_DATA = @ZFS_META_DATA@
+ZFS_META_LICENSE = @ZFS_META_LICENSE@
+ZFS_META_LT_AGE = @ZFS_META_LT_AGE@
+ZFS_META_LT_CURRENT = @ZFS_META_LT_CURRENT@
+ZFS_META_LT_REVISION = @ZFS_META_LT_REVISION@
+ZFS_META_NAME = @ZFS_META_NAME@
+ZFS_META_RELEASE = @ZFS_META_RELEASE@
+ZFS_META_VERSION = @ZFS_META_VERSION@
+ZFS_MODULE_LOAD = @ZFS_MODULE_LOAD@
+ZLIB = @ZLIB@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dracutdir = @dracutdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+modulesloaddir = @modulesloaddir@
+mounthelperdir = @mounthelperdir@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+runstatedir = @runstatedir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+systemdpresetdir = @systemdpresetdir@
+systemdunitdir = @systemdunitdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+udevdir = @udevdir@
+udevruledir = @udevruledir@
+SUBDIRS = fm fs
+COMMON_H = \
+	$(top_srcdir)/include/sys/arc.h \
+	$(top_srcdir)/include/sys/arc_impl.h \
+	$(top_srcdir)/include/sys/avl.h \
+	$(top_srcdir)/include/sys/avl_impl.h \
+	$(top_srcdir)/include/sys/blkptr.h \
+	$(top_srcdir)/include/sys/bplist.h \
+	$(top_srcdir)/include/sys/bpobj.h \
+	$(top_srcdir)/include/sys/bptree.h \
+	$(top_srcdir)/include/sys/dbuf.h \
+	$(top_srcdir)/include/sys/ddt.h \
+	$(top_srcdir)/include/sys/dmu.h \
+	$(top_srcdir)/include/sys/dmu_impl.h \
+	$(top_srcdir)/include/sys/dmu_objset.h \
+	$(top_srcdir)/include/sys/dmu_send.h \
+	$(top_srcdir)/include/sys/dmu_traverse.h \
+	$(top_srcdir)/include/sys/dmu_tx.h \
+	$(top_srcdir)/include/sys/dmu_zfetch.h \
+	$(top_srcdir)/include/sys/dnode.h \
+	$(top_srcdir)/include/sys/dsl_bookmark.h \
+	$(top_srcdir)/include/sys/dsl_dataset.h \
+	$(top_srcdir)/include/sys/dsl_deadlist.h \
+	$(top_srcdir)/include/sys/dsl_deleg.h \
+	$(top_srcdir)/include/sys/dsl_destroy.h \
+	$(top_srcdir)/include/sys/dsl_dir.h \
+	$(top_srcdir)/include/sys/dsl_pool.h \
+	$(top_srcdir)/include/sys/dsl_prop.h \
+	$(top_srcdir)/include/sys/dsl_scan.h \
+	$(top_srcdir)/include/sys/dsl_synctask.h \
+	$(top_srcdir)/include/sys/dsl_userhold.h \
+	$(top_srcdir)/include/sys/efi_partition.h \
+	$(top_srcdir)/include/sys/metaslab.h \
+	$(top_srcdir)/include/sys/metaslab_impl.h \
+	$(top_srcdir)/include/sys/mntent.h \
+	$(top_srcdir)/include/sys/multilist.h \
+	$(top_srcdir)/include/sys/nvpair.h \
+	$(top_srcdir)/include/sys/nvpair_impl.h \
+	$(top_srcdir)/include/sys/range_tree.h \
+	$(top_srcdir)/include/sys/refcount.h \
+	$(top_srcdir)/include/sys/rrwlock.h \
+	$(top_srcdir)/include/sys/sa.h \
+	$(top_srcdir)/include/sys/sa_impl.h \
+	$(top_srcdir)/include/sys/sdt.h \
+	$(top_srcdir)/include/sys/spa_boot.h \
+	$(top_srcdir)/include/sys/space_map.h \
+	$(top_srcdir)/include/sys/space_reftree.h \
+	$(top_srcdir)/include/sys/spa.h \
+	$(top_srcdir)/include/sys/spa_impl.h \
+	$(top_srcdir)/include/sys/trace.h \
+	$(top_srcdir)/include/sys/trace_acl.h \
+	$(top_srcdir)/include/sys/trace_arc.h \
+	$(top_srcdir)/include/sys/trace_dbgmsg.h \
+	$(top_srcdir)/include/sys/trace_dbuf.h \
+	$(top_srcdir)/include/sys/trace_dmu.h \
+	$(top_srcdir)/include/sys/trace_dnode.h \
+	$(top_srcdir)/include/sys/trace_multilist.h \
+	$(top_srcdir)/include/sys/trace_txg.h \
+	$(top_srcdir)/include/sys/trace_zil.h \
+	$(top_srcdir)/include/sys/trace_zrlock.h \
+	$(top_srcdir)/include/sys/txg.h \
+	$(top_srcdir)/include/sys/txg_impl.h \
+	$(top_srcdir)/include/sys/u8_textprep_data.h \
+	$(top_srcdir)/include/sys/u8_textprep.h \
+	$(top_srcdir)/include/sys/uberblock.h \
+	$(top_srcdir)/include/sys/uberblock_impl.h \
+	$(top_srcdir)/include/sys/uio_impl.h \
+	$(top_srcdir)/include/sys/unique.h \
+	$(top_srcdir)/include/sys/uuid.h \
+	$(top_srcdir)/include/sys/vdev_disk.h \
+	$(top_srcdir)/include/sys/vdev_file.h \
+	$(top_srcdir)/include/sys/vdev.h \
+	$(top_srcdir)/include/sys/vdev_impl.h \
+	$(top_srcdir)/include/sys/xvattr.h \
+	$(top_srcdir)/include/sys/zap.h \
+	$(top_srcdir)/include/sys/zap_impl.h \
+	$(top_srcdir)/include/sys/zap_leaf.h \
+	$(top_srcdir)/include/sys/zfeature.h \
+	$(top_srcdir)/include/sys/zfs_acl.h \
+	$(top_srcdir)/include/sys/zfs_context.h \
+	$(top_srcdir)/include/sys/zfs_ctldir.h \
+	$(top_srcdir)/include/sys/zfs_debug.h \
+	$(top_srcdir)/include/sys/zfs_delay.h \
+	$(top_srcdir)/include/sys/zfs_dir.h \
+	$(top_srcdir)/include/sys/zfs_fuid.h \
+	$(top_srcdir)/include/sys/zfs_rlock.h \
+	$(top_srcdir)/include/sys/zfs_sa.h \
+	$(top_srcdir)/include/sys/zfs_stat.h \
+	$(top_srcdir)/include/sys/zfs_vfsops.h \
+	$(top_srcdir)/include/sys/zfs_vnops.h \
+	$(top_srcdir)/include/sys/zfs_znode.h \
+	$(top_srcdir)/include/sys/zil.h \
+	$(top_srcdir)/include/sys/zil_impl.h \
+	$(top_srcdir)/include/sys/zio_checksum.h \
+	$(top_srcdir)/include/sys/zio_compress.h \
+	$(top_srcdir)/include/sys/zio.h \
+	$(top_srcdir)/include/sys/zio_impl.h \
+	$(top_srcdir)/include/sys/zrlock.h
+
+KERNEL_H = \
+	$(top_srcdir)/include/sys/zfs_ioctl.h \
+	$(top_srcdir)/include/sys/zfs_onexit.h \
+	${top_srcdir}/include/sys/zpl.h \
+	$(top_srcdir)/include/sys/zvol.h
+
+USER_H = 
+EXTRA_DIST = $(COMMON_H) $(KERNEL_H) $(USER_H)
+@CONFIG_USER_TRUE@libzfsdir = $(includedir)/libzfs/sys
+@CONFIG_USER_TRUE@libzfs_HEADERS = $(COMMON_H) $(USER_H)
+@CONFIG_KERNEL_TRUE@kerneldir = @prefix@/src/zfs-$(VERSION)/include/sys
+@CONFIG_KERNEL_TRUE@kernel_HEADERS = $(COMMON_H) $(KERNEL_H)
+all: all-recursive
+
+.SUFFIXES:
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+	        && { if test -f $@; then exit 0; else break; fi; }; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu include/sys/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --gnu include/sys/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+	esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
+install-kernelHEADERS: $(kernel_HEADERS)
+	@$(NORMAL_INSTALL)
+	@list='$(kernel_HEADERS)'; test -n "$(kerneldir)" || list=; \
+	if test -n "$$list"; then \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(kerneldir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(kerneldir)" || exit 1; \
+	fi; \
+	for p in $$list; do \
+	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+	  echo "$$d$$p"; \
+	done | $(am__base_list) | \
+	while read files; do \
+	  echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(kerneldir)'"; \
+	  $(INSTALL_HEADER) $$files "$(DESTDIR)$(kerneldir)" || exit $$?; \
+	done
+
+uninstall-kernelHEADERS:
+	@$(NORMAL_UNINSTALL)
+	@list='$(kernel_HEADERS)'; test -n "$(kerneldir)" || list=; \
+	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+	dir='$(DESTDIR)$(kerneldir)'; $(am__uninstall_files_from_dir)
+install-libzfsHEADERS: $(libzfs_HEADERS)
+	@$(NORMAL_INSTALL)
+	@list='$(libzfs_HEADERS)'; test -n "$(libzfsdir)" || list=; \
+	if test -n "$$list"; then \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(libzfsdir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(libzfsdir)" || exit 1; \
+	fi; \
+	for p in $$list; do \
+	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+	  echo "$$d$$p"; \
+	done | $(am__base_list) | \
+	while read files; do \
+	  echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(libzfsdir)'"; \
+	  $(INSTALL_HEADER) $$files "$(DESTDIR)$(libzfsdir)" || exit $$?; \
+	done
+
+uninstall-libzfsHEADERS:
+	@$(NORMAL_UNINSTALL)
+	@list='$(libzfs_HEADERS)'; test -n "$(libzfsdir)" || list=; \
+	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+	dir='$(DESTDIR)$(libzfsdir)'; $(am__uninstall_files_from_dir)
+
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run 'make' without going through this Makefile.
+# To change the values of 'make' variables: instead of editing Makefiles,
+# (1) if the variable is set in 'config.status', edit 'config.status'
+#     (which will cause the Makefiles to be regenerated when you run 'make');
+# (2) otherwise, pass the desired values on the 'make' command line.
+$(am__recursive_targets):
+	@fail=; \
+	if $(am__make_keepgoing); then \
+	  failcom='fail=yes'; \
+	else \
+	  failcom='exit 1'; \
+	fi; \
+	dot_seen=no; \
+	target=`echo $@ | sed s/-recursive//`; \
+	case "$@" in \
+	  distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
+	  *) list='$(SUBDIRS)' ;; \
+	esac; \
+	for subdir in $$list; do \
+	  echo "Making $$target in $$subdir"; \
+	  if test "$$subdir" = "."; then \
+	    dot_seen=yes; \
+	    local_target="$$target-am"; \
+	  else \
+	    local_target="$$target"; \
+	  fi; \
+	  ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+	  || eval $$failcom; \
+	done; \
+	if test "$$dot_seen" = "no"; then \
+	  $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+	fi; test -z "$$fail"
+
+ID: $(am__tagged_files)
+	$(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-recursive
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	set x; \
+	here=`pwd`; \
+	if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
+	  include_option=--etags-include; \
+	  empty_fix=.; \
+	else \
+	  include_option=--include; \
+	  empty_fix=; \
+	fi; \
+	list='$(SUBDIRS)'; for subdir in $$list; do \
+	  if test "$$subdir" = .; then :; else \
+	    test ! -f $$subdir/TAGS || \
+	      set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \
+	  fi; \
+	done; \
+	$(am__define_uniq_tagged_files); \
+	shift; \
+	if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+	  test -n "$$unique" || unique=$$empty_fix; \
+	  if test $$# -gt 0; then \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      "$$@" $$unique; \
+	  else \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      $$unique; \
+	  fi; \
+	fi
+ctags: ctags-recursive
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	$(am__define_uniq_tagged_files); \
+	test -z "$(CTAGS_ARGS)$$unique" \
+	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+	     $$unique
+
+GTAGS:
+	here=`$(am__cd) $(top_builddir) && pwd` \
+	  && $(am__cd) $(top_srcdir) \
+	  && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-recursive
+
+cscopelist-am: $(am__tagged_files)
+	list='$(am__tagged_files)'; \
+	case "$(srcdir)" in \
+	  [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+	  *) sdir=$(subdir)/$(srcdir) ;; \
+	esac; \
+	for i in $$list; do \
+	  if test -f "$$i"; then \
+	    echo "$(subdir)/$$i"; \
+	  else \
+	    echo "$$sdir/$$i"; \
+	  fi; \
+	done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	list='$(DISTFILES)'; \
+	  dist_files=`for file in $$list; do echo $$file; done | \
+	  sed -e "s|^$$srcdirstrip/||;t" \
+	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+	case $$dist_files in \
+	  */*) $(MKDIR_P) `echo "$$dist_files" | \
+			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+			   sort -u` ;; \
+	esac; \
+	for file in $$dist_files; do \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  if test -d $$d/$$file; then \
+	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+	    if test -d "$(distdir)/$$file"; then \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+	  else \
+	    test -f "$(distdir)/$$file" \
+	    || cp -p $$d/$$file "$(distdir)/$$file" \
+	    || exit 1; \
+	  fi; \
+	done
+	@list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
+	  if test "$$subdir" = .; then :; else \
+	    $(am__make_dryrun) \
+	      || test -d "$(distdir)/$$subdir" \
+	      || $(MKDIR_P) "$(distdir)/$$subdir" \
+	      || exit 1; \
+	    dir1=$$subdir; dir2="$(distdir)/$$subdir"; \
+	    $(am__relativize); \
+	    new_distdir=$$reldir; \
+	    dir1=$$subdir; dir2="$(top_distdir)"; \
+	    $(am__relativize); \
+	    new_top_distdir=$$reldir; \
+	    echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \
+	    echo "     am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \
+	    ($(am__cd) $$subdir && \
+	      $(MAKE) $(AM_MAKEFLAGS) \
+	        top_distdir="$$new_top_distdir" \
+	        distdir="$$new_distdir" \
+		am__remove_distdir=: \
+		am__skip_length_check=: \
+		am__skip_mode_fix=: \
+	        distdir) \
+	      || exit 1; \
+	  fi; \
+	done
+check-am: all-am
+check: check-recursive
+all-am: Makefile $(HEADERS)
+installdirs: installdirs-recursive
+installdirs-am:
+	for dir in "$(DESTDIR)$(kerneldir)" "$(DESTDIR)$(libzfsdir)"; do \
+	  test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+	done
+install: install-recursive
+install-exec: install-exec-recursive
+install-data: install-data-recursive
+uninstall: uninstall-recursive
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-recursive
+install-strip:
+	if test -z '$(STRIP)'; then \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	      install; \
+	else \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+	fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+clean: clean-recursive
+
+clean-am: clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-recursive
+	-rm -f Makefile
+distclean-am: clean-am distclean-generic distclean-tags
+
+dvi: dvi-recursive
+
+dvi-am:
+
+html: html-recursive
+
+html-am:
+
+info: info-recursive
+
+info-am:
+
+install-data-am: install-kernelHEADERS install-libzfsHEADERS
+
+install-dvi: install-dvi-recursive
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-recursive
+
+install-html-am:
+
+install-info: install-info-recursive
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-recursive
+
+install-pdf-am:
+
+install-ps: install-ps-recursive
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-recursive
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-recursive
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-recursive
+
+pdf-am:
+
+ps: ps-recursive
+
+ps-am:
+
+uninstall-am: uninstall-kernelHEADERS uninstall-libzfsHEADERS
+
+.MAKE: $(am__recursive_targets) install-am install-strip
+
+.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \
+	check-am clean clean-generic clean-libtool cscopelist-am ctags \
+	ctags-am distclean distclean-generic distclean-libtool \
+	distclean-tags distdir dvi dvi-am html html-am info info-am \
+	install install-am install-data install-data-am install-dvi \
+	install-dvi-am install-exec install-exec-am install-html \
+	install-html-am install-info install-info-am \
+	install-kernelHEADERS install-libzfsHEADERS install-man \
+	install-pdf install-pdf-am install-ps install-ps-am \
+	install-strip installcheck installcheck-am installdirs \
+	installdirs-am maintainer-clean maintainer-clean-generic \
+	mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \
+	ps ps-am tags tags-am uninstall uninstall-am \
+	uninstall-kernelHEADERS uninstall-libzfsHEADERS
+
+.PRECIOUS: Makefile
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/include/sys/arc.h
@@ -0,0 +1,230 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2014 by Delphix. All rights reserved.
+ * Copyright (c) 2013 by Saso Kiselkov. All rights reserved.
+ */
+
+#ifndef	_SYS_ARC_H
+#define	_SYS_ARC_H
+
+#include <sys/zfs_context.h>
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+#include <sys/zio.h>
+#include <sys/dmu.h>
+#include <sys/spa.h>
+#include <sys/refcount.h>
+
+/*
+ * Used by arc_flush() to inform arc_evict_state() that it should evict
+ * all available buffers from the arc state being passed in.
+ */
+#define	ARC_EVICT_ALL	-1ULL
+
+typedef struct arc_buf_hdr arc_buf_hdr_t;
+typedef struct arc_buf arc_buf_t;
+typedef struct arc_prune arc_prune_t;
+typedef void arc_done_func_t(zio_t *zio, arc_buf_t *buf, void *private);
+typedef void arc_prune_func_t(int64_t bytes, void *private);
+typedef int arc_evict_func_t(void *private);
+
+/* Shared module parameters */
+extern int zfs_arc_average_blocksize;
+
+/* generic arc_done_func_t's which you can use */
+arc_done_func_t arc_bcopy_func;
+arc_done_func_t arc_getbuf_func;
+
+/* generic arc_prune_func_t wrapper for callbacks */
+struct arc_prune {
+	arc_prune_func_t	*p_pfunc;
+	void			*p_private;
+	uint64_t		p_adjust;
+	list_node_t		p_node;
+	refcount_t		p_refcnt;
+};
+
+typedef enum arc_strategy {
+	ARC_STRATEGY_META_ONLY		= 0, /* Evict only meta data buffers */
+	ARC_STRATEGY_META_BALANCED	= 1, /* Evict data buffers if needed */
+} arc_strategy_t;
+
+typedef enum arc_flags
+{
+	/*
+	 * Public flags that can be passed into the ARC by external consumers.
+	 */
+	ARC_FLAG_NONE			= 1 << 0,	/* No flags set */
+	ARC_FLAG_WAIT			= 1 << 1,	/* perform sync I/O */
+	ARC_FLAG_NOWAIT			= 1 << 2,	/* perform async I/O */
+	ARC_FLAG_PREFETCH		= 1 << 3,	/* I/O is a prefetch */
+	ARC_FLAG_CACHED			= 1 << 4,	/* I/O was in cache */
+	ARC_FLAG_L2CACHE		= 1 << 5,	/* cache in L2ARC */
+	ARC_FLAG_L2COMPRESS		= 1 << 6,	/* compress in L2ARC */
+
+	/*
+	 * Private ARC flags.  These flags are private ARC only flags that
+	 * will show up in b_flags in the arc_hdr_buf_t. These flags should
+	 * only be set by ARC code.
+	 */
+	ARC_FLAG_IN_HASH_TABLE		= 1 << 7,	/* buffer is hashed */
+	ARC_FLAG_IO_IN_PROGRESS		= 1 << 8,	/* I/O in progress */
+	ARC_FLAG_IO_ERROR		= 1 << 9,	/* I/O failed for buf */
+	ARC_FLAG_FREED_IN_READ		= 1 << 10,	/* freed during read */
+	ARC_FLAG_BUF_AVAILABLE		= 1 << 11,	/* block not in use */
+	ARC_FLAG_INDIRECT		= 1 << 12,	/* indirect block */
+	ARC_FLAG_L2_WRITING		= 1 << 13,	/* write in progress */
+	ARC_FLAG_L2_EVICTED		= 1 << 14,	/* evicted during I/O */
+	ARC_FLAG_L2_WRITE_HEAD		= 1 << 15,	/* head of write list */
+	/* indicates that the buffer contains metadata (otherwise, data) */
+	ARC_FLAG_BUFC_METADATA		= 1 << 16,
+
+	/* Flags specifying whether optional hdr struct fields are defined */
+	ARC_FLAG_HAS_L1HDR		= 1 << 17,
+	ARC_FLAG_HAS_L2HDR		= 1 << 18,
+} arc_flags_t;
+
+struct arc_buf {
+	arc_buf_hdr_t		*b_hdr;
+	arc_buf_t		*b_next;
+	kmutex_t		b_evict_lock;
+	void			*b_data;
+	arc_evict_func_t	*b_efunc;
+	void			*b_private;
+};
+
+typedef enum arc_buf_contents {
+	ARC_BUFC_DATA,				/* buffer contains data */
+	ARC_BUFC_METADATA,			/* buffer contains metadata */
+	ARC_BUFC_NUMTYPES
+} arc_buf_contents_t;
+
+/*
+ * The following breakdows of arc_size exist for kstat only.
+ */
+typedef enum arc_space_type {
+	ARC_SPACE_DATA,
+	ARC_SPACE_META,
+	ARC_SPACE_HDRS,
+	ARC_SPACE_L2HDRS,
+	ARC_SPACE_OTHER,
+	ARC_SPACE_NUMTYPES
+} arc_space_type_t;
+
+typedef enum arc_state_type {
+	ARC_STATE_ANON,
+	ARC_STATE_MRU,
+	ARC_STATE_MRU_GHOST,
+	ARC_STATE_MFU,
+	ARC_STATE_MFU_GHOST,
+	ARC_STATE_L2C_ONLY,
+	ARC_STATE_NUMTYPES
+} arc_state_type_t;
+
+typedef struct arc_buf_info {
+	arc_state_type_t	abi_state_type;
+	arc_buf_contents_t	abi_state_contents;
+	uint32_t		abi_flags;
+	uint32_t		abi_datacnt;
+	uint64_t		abi_size;
+	uint64_t		abi_spa;
+	uint64_t		abi_access;
+	uint32_t		abi_mru_hits;
+	uint32_t		abi_mru_ghost_hits;
+	uint32_t		abi_mfu_hits;
+	uint32_t		abi_mfu_ghost_hits;
+	uint32_t		abi_l2arc_hits;
+	uint32_t		abi_holds;
+	uint64_t		abi_l2arc_dattr;
+	uint64_t		abi_l2arc_asize;
+	enum zio_compress	abi_l2arc_compress;
+} arc_buf_info_t;
+
+void arc_space_consume(uint64_t space, arc_space_type_t type);
+void arc_space_return(uint64_t space, arc_space_type_t type);
+arc_buf_t *arc_buf_alloc(spa_t *spa, uint64_t size, void *tag,
+    arc_buf_contents_t type);
+arc_buf_t *arc_loan_buf(spa_t *spa, uint64_t size);
+void arc_return_buf(arc_buf_t *buf, void *tag);
+void arc_loan_inuse_buf(arc_buf_t *buf, void *tag);
+void arc_buf_add_ref(arc_buf_t *buf, void *tag);
+boolean_t arc_buf_remove_ref(arc_buf_t *buf, void *tag);
+void arc_buf_info(arc_buf_t *buf, arc_buf_info_t *abi, int state_index);
+uint64_t arc_buf_size(arc_buf_t *buf);
+void arc_release(arc_buf_t *buf, void *tag);
+int arc_released(arc_buf_t *buf);
+void arc_buf_sigsegv(int sig, siginfo_t *si, void *unused);
+void arc_buf_freeze(arc_buf_t *buf);
+void arc_buf_thaw(arc_buf_t *buf);
+boolean_t arc_buf_eviction_needed(arc_buf_t *buf);
+#ifdef ZFS_DEBUG
+int arc_referenced(arc_buf_t *buf);
+#endif
+
+int arc_read(zio_t *pio, spa_t *spa, const blkptr_t *bp,
+    arc_done_func_t *done, void *private, zio_priority_t priority, int flags,
+    arc_flags_t *arc_flags, const zbookmark_phys_t *zb);
+zio_t *arc_write(zio_t *pio, spa_t *spa, uint64_t txg,
+    blkptr_t *bp, arc_buf_t *buf, boolean_t l2arc, boolean_t l2arc_compress,
+    const zio_prop_t *zp, arc_done_func_t *ready, arc_done_func_t *physdone,
+    arc_done_func_t *done, void *private, zio_priority_t priority,
+    int zio_flags, const zbookmark_phys_t *zb);
+
+arc_prune_t *arc_add_prune_callback(arc_prune_func_t *func, void *private);
+void arc_remove_prune_callback(arc_prune_t *p);
+void arc_freed(spa_t *spa, const blkptr_t *bp);
+
+void arc_set_callback(arc_buf_t *buf, arc_evict_func_t *func, void *private);
+boolean_t arc_clear_callback(arc_buf_t *buf);
+
+void arc_flush(spa_t *spa, boolean_t retry);
+void arc_tempreserve_clear(uint64_t reserve);
+int arc_tempreserve_space(uint64_t reserve, uint64_t txg);
+
+void arc_init(void);
+void arc_fini(void);
+
+/*
+ * Level 2 ARC
+ */
+
+void l2arc_add_vdev(spa_t *spa, vdev_t *vd);
+void l2arc_remove_vdev(vdev_t *vd);
+boolean_t l2arc_vdev_present(vdev_t *vd);
+void l2arc_init(void);
+void l2arc_fini(void);
+void l2arc_start(void);
+void l2arc_stop(void);
+
+#ifndef _KERNEL
+extern boolean_t arc_watch;
+#endif
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif /* _SYS_ARC_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/include/sys/arc_impl.h
@@ -0,0 +1,228 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013 by Delphix. All rights reserved.
+ * Copyright (c) 2013 by Saso Kiselkov. All rights reserved.
+ * Copyright 2013 Nexenta Systems, Inc.  All rights reserved.
+ */
+
+#ifndef _SYS_ARC_IMPL_H
+#define	_SYS_ARC_IMPL_H
+
+#include <sys/arc.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Note that buffers can be in one of 6 states:
+ *	ARC_anon	- anonymous (discussed below)
+ *	ARC_mru		- recently used, currently cached
+ *	ARC_mru_ghost	- recentely used, no longer in cache
+ *	ARC_mfu		- frequently used, currently cached
+ *	ARC_mfu_ghost	- frequently used, no longer in cache
+ *	ARC_l2c_only	- exists in L2ARC but not other states
+ * When there are no active references to the buffer, they are
+ * are linked onto a list in one of these arc states.  These are
+ * the only buffers that can be evicted or deleted.  Within each
+ * state there are multiple lists, one for meta-data and one for
+ * non-meta-data.  Meta-data (indirect blocks, blocks of dnodes,
+ * etc.) is tracked separately so that it can be managed more
+ * explicitly: favored over data, limited explicitly.
+ *
+ * Anonymous buffers are buffers that are not associated with
+ * a DVA.  These are buffers that hold dirty block copies
+ * before they are written to stable storage.  By definition,
+ * they are "ref'd" and are considered part of arc_mru
+ * that cannot be freed.  Generally, they will aquire a DVA
+ * as they are written and migrate onto the arc_mru list.
+ *
+ * The ARC_l2c_only state is for buffers that are in the second
+ * level ARC but no longer in any of the ARC_m* lists.  The second
+ * level ARC itself may also contain buffers that are in any of
+ * the ARC_m* states - meaning that a buffer can exist in two
+ * places.  The reason for the ARC_l2c_only state is to keep the
+ * buffer header in the hash table, so that reads that hit the
+ * second level ARC benefit from these fast lookups.
+ */
+
+typedef struct arc_state {
+	/*
+	 * list of evictable buffers
+	 */
+	multilist_t arcs_list[ARC_BUFC_NUMTYPES];
+	/*
+	 * total amount of evictable data in this state
+	 */
+	uint64_t arcs_lsize[ARC_BUFC_NUMTYPES];
+	/*
+	 * total amount of data in this state; this includes: evictable,
+	 * non-evictable, ARC_BUFC_DATA, and ARC_BUFC_METADATA.
+	 */
+	refcount_t arcs_size;
+	/*
+	 * supports the "dbufs" kstat
+	 */
+	arc_state_type_t arcs_state;
+} arc_state_t;
+
+typedef struct arc_callback arc_callback_t;
+
+struct arc_callback {
+	void			*acb_private;
+	arc_done_func_t		*acb_done;
+	arc_buf_t		*acb_buf;
+	zio_t			*acb_zio_dummy;
+	arc_callback_t		*acb_next;
+};
+
+typedef struct arc_write_callback arc_write_callback_t;
+
+struct arc_write_callback {
+	void		*awcb_private;
+	arc_done_func_t	*awcb_ready;
+	arc_done_func_t	*awcb_physdone;
+	arc_done_func_t	*awcb_done;
+	arc_buf_t	*awcb_buf;
+};
+
+/*
+ * ARC buffers are separated into multiple structs as a memory saving measure:
+ *   - Common fields struct, always defined, and embedded within it:
+ *       - L2-only fields, always allocated but undefined when not in L2ARC
+ *       - L1-only fields, only allocated when in L1ARC
+ *
+ *           Buffer in L1                     Buffer only in L2
+ *    +------------------------+          +------------------------+
+ *    | arc_buf_hdr_t          |          | arc_buf_hdr_t          |
+ *    |                        |          |                        |
+ *    |                        |          |                        |
+ *    |                        |          |                        |
+ *    +------------------------+          +------------------------+
+ *    | l2arc_buf_hdr_t        |          | l2arc_buf_hdr_t        |
+ *    | (undefined if L1-only) |          |                        |
+ *    +------------------------+          +------------------------+
+ *    | l1arc_buf_hdr_t        |
+ *    |                        |
+ *    |                        |
+ *    |                        |
+ *    |                        |
+ *    +------------------------+
+ *
+ * Because it's possible for the L2ARC to become extremely large, we can wind
+ * up eating a lot of memory in L2ARC buffer headers, so the size of a header
+ * is minimized by only allocating the fields necessary for an L1-cached buffer
+ * when a header is actually in the L1 cache. The sub-headers (l1arc_buf_hdr and
+ * l2arc_buf_hdr) are embedded rather than allocated separately to save a couple
+ * words in pointers. arc_hdr_realloc() is used to switch a header between
+ * these two allocation states.
+ */
+typedef struct l1arc_buf_hdr {
+	kmutex_t		b_freeze_lock;
+
+	arc_buf_t		*b_buf;
+	uint32_t		b_datacnt;
+	/* for waiting on writes to complete */
+	kcondvar_t		b_cv;
+
+
+	/* protected by arc state mutex */
+	arc_state_t		*b_state;
+	multilist_node_t	b_arc_node;
+
+	/* updated atomically */
+	clock_t			b_arc_access;
+	uint32_t		b_mru_hits;
+	uint32_t		b_mru_ghost_hits;
+	uint32_t		b_mfu_hits;
+	uint32_t		b_mfu_ghost_hits;
+	uint32_t		b_l2_hits;
+
+	/* self protecting */
+	refcount_t		b_refcnt;
+
+	arc_callback_t		*b_acb;
+	/* temporary buffer holder for in-flight compressed data */
+	void			*b_tmp_cdata;
+} l1arc_buf_hdr_t;
+
+typedef struct l2arc_dev {
+	vdev_t			*l2ad_vdev;	/* vdev */
+	spa_t			*l2ad_spa;	/* spa */
+	uint64_t		l2ad_hand;	/* next write location */
+	uint64_t		l2ad_start;	/* first addr on device */
+	uint64_t		l2ad_end;	/* last addr on device */
+	boolean_t		l2ad_first;	/* first sweep through */
+	boolean_t		l2ad_writing;	/* currently writing */
+	kmutex_t		l2ad_mtx;	/* lock for buffer list */
+	list_t			l2ad_buflist;	/* buffer list */
+	list_node_t		l2ad_node;	/* device list node */
+	refcount_t		l2ad_alloc;	/* allocated bytes */
+} l2arc_dev_t;
+
+typedef struct l2arc_buf_hdr {
+	/* protected by arc_buf_hdr mutex */
+	l2arc_dev_t		*b_dev;		/* L2ARC device */
+	uint64_t		b_daddr;	/* disk address, offset byte */
+	/* real alloc'd buffer size depending on b_compress applied */
+	uint32_t		b_hits;
+	int32_t			b_asize;
+	uint8_t			b_compress;
+
+	list_node_t		b_l2node;
+} l2arc_buf_hdr_t;
+
+typedef struct l2arc_write_callback {
+	l2arc_dev_t	*l2wcb_dev;		/* device info */
+	arc_buf_hdr_t	*l2wcb_head;		/* head of write buflist */
+} l2arc_write_callback_t;
+
+struct arc_buf_hdr {
+	/* protected by hash lock */
+	dva_t			b_dva;
+	uint64_t		b_birth;
+	/*
+	 * Even though this checksum is only set/verified when a buffer is in
+	 * the L1 cache, it needs to be in the set of common fields because it
+	 * must be preserved from the time before a buffer is written out to
+	 * L2ARC until after it is read back in.
+	 */
+	zio_cksum_t		*b_freeze_cksum;
+
+	arc_buf_hdr_t		*b_hash_next;
+	arc_flags_t		b_flags;
+
+	/* immutable */
+	int32_t			b_size;
+	uint64_t		b_spa;
+
+	/* L2ARC fields. Undefined when not in L2ARC. */
+	l2arc_buf_hdr_t		b_l2hdr;
+	/* L1ARC fields. Undefined when in l2arc_only state */
+	l1arc_buf_hdr_t		b_l1hdr;
+};
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _SYS_ARC_IMPL_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/include/sys/avl.h
@@ -0,0 +1,318 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/*
+ * Copyright (c) 2014 by Delphix. All rights reserved.
+ */
+
+#ifndef	_AVL_H
+#define	_AVL_H
+
+/*
+ * This is a private header file.  Applications should not directly include
+ * this file.
+ */
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+#include <sys/types.h>
+#include <sys/avl_impl.h>
+
+/*
+ * This is a generic implementation of AVL trees for use in the Solaris kernel.
+ * The interfaces provide an efficient way of implementing an ordered set of
+ * data structures.
+ *
+ * AVL trees provide an alternative to using an ordered linked list. Using AVL
+ * trees will usually be faster, however they requires more storage. An ordered
+ * linked list in general requires 2 pointers in each data structure. The
+ * AVL tree implementation uses 3 pointers. The following chart gives the
+ * approximate performance of operations with the different approaches:
+ *
+ *	Operation	 Link List	AVL tree
+ *	---------	 --------	--------
+ *	lookup		   O(n)		O(log(n))
+ *
+ *	insert 1 node	 constant	constant
+ *
+ *	delete 1 node	 constant	between constant and O(log(n))
+ *
+ *	delete all nodes   O(n)		O(n)
+ *
+ *	visit the next
+ *	or prev node	 constant	between constant and O(log(n))
+ *
+ *
+ * The data structure nodes are anchored at an "avl_tree_t" (the equivalent
+ * of a list header) and the individual nodes will have a field of
+ * type "avl_node_t" (corresponding to list pointers).
+ *
+ * The type "avl_index_t" is used to indicate a position in the list for
+ * certain calls.
+ *
+ * The usage scenario is generally:
+ *
+ * 1. Create the list/tree with: avl_create()
+ *
+ * followed by any mixture of:
+ *
+ * 2a. Insert nodes with: avl_add(), or avl_find() and avl_insert()
+ *
+ * 2b. Visited elements with:
+ *	 avl_first() - returns the lowest valued node
+ *	 avl_last() - returns the highest valued node
+ *	 AVL_NEXT() - given a node go to next higher one
+ *	 AVL_PREV() - given a node go to previous lower one
+ *
+ * 2c.  Find the node with the closest value either less than or greater
+ *	than a given value with avl_nearest().
+ *
+ * 2d. Remove individual nodes from the list/tree with avl_remove().
+ *
+ * and finally when the list is being destroyed
+ *
+ * 3. Use avl_destroy_nodes() to quickly process/free up any remaining nodes.
+ *    Note that once you use avl_destroy_nodes(), you can no longer
+ *    use any routine except avl_destroy_nodes() and avl_destoy().
+ *
+ * 4. Use avl_destroy() to destroy the AVL tree itself.
+ *
+ * Any locking for multiple thread access is up to the user to provide, just
+ * as is needed for any linked list implementation.
+ */
+
+
+/*
+ * Type used for the root of the AVL tree.
+ */
+typedef struct avl_tree avl_tree_t;
+
+/*
+ * The data nodes in the AVL tree must have a field of this type.
+ */
+typedef struct avl_node avl_node_t;
+
+/*
+ * An opaque type used to locate a position in the tree where a node
+ * would be inserted.
+ */
+typedef uintptr_t avl_index_t;
+
+
+/*
+ * Direction constants used for avl_nearest().
+ */
+#define	AVL_BEFORE	(0)
+#define	AVL_AFTER	(1)
+
+
+/*
+ * Prototypes
+ *
+ * Where not otherwise mentioned, "void *" arguments are a pointer to the
+ * user data structure which must contain a field of type avl_node_t.
+ *
+ * Also assume the user data structures looks like:
+ *	stuct my_type {
+ *		...
+ *		avl_node_t	my_link;
+ *		...
+ *	};
+ */
+
+/*
+ * Initialize an AVL tree. Arguments are:
+ *
+ * tree   - the tree to be initialized
+ * compar - function to compare two nodes, it must return exactly: -1, 0, or +1
+ *          -1 for <, 0 for ==, and +1 for >
+ * size   - the value of sizeof(struct my_type)
+ * offset - the value of OFFSETOF(struct my_type, my_link)
+ */
+extern void avl_create(avl_tree_t *tree,
+	int (*compar) (const void *, const void *), size_t size, size_t offset);
+
+
+/*
+ * Find a node with a matching value in the tree. Returns the matching node
+ * found. If not found, it returns NULL and then if "where" is not NULL it sets
+ * "where" for use with avl_insert() or avl_nearest().
+ *
+ * node   - node that has the value being looked for
+ * where  - position for use with avl_nearest() or avl_insert(), may be NULL
+ */
+extern void *avl_find(avl_tree_t *tree, const void *node, avl_index_t *where);
+
+/*
+ * Insert a node into the tree.
+ *
+ * node   - the node to insert
+ * where  - position as returned from avl_find()
+ */
+extern void avl_insert(avl_tree_t *tree, void *node, avl_index_t where);
+
+/*
+ * Insert "new_data" in "tree" in the given "direction" either after
+ * or before the data "here".
+ *
+ * This might be useful for avl clients caching recently accessed
+ * data to avoid doing avl_find() again for insertion.
+ *
+ * new_data	- new data to insert
+ * here		- existing node in "tree"
+ * direction	- either AVL_AFTER or AVL_BEFORE the data "here".
+ */
+extern void avl_insert_here(avl_tree_t *tree, void *new_data, void *here,
+    int direction);
+
+
+/*
+ * Return the first or last valued node in the tree. Will return NULL
+ * if the tree is empty.
+ *
+ */
+extern void *avl_first(avl_tree_t *tree);
+extern void *avl_last(avl_tree_t *tree);
+
+
+/*
+ * Return the next or previous valued node in the tree.
+ * AVL_NEXT() will return NULL if at the last node.
+ * AVL_PREV() will return NULL if at the first node.
+ *
+ * node   - the node from which the next or previous node is found
+ */
+#define	AVL_NEXT(tree, node)	avl_walk(tree, node, AVL_AFTER)
+#define	AVL_PREV(tree, node)	avl_walk(tree, node, AVL_BEFORE)
+
+
+/*
+ * Find the node with the nearest value either greater or less than
+ * the value from a previous avl_find(). Returns the node or NULL if
+ * there isn't a matching one.
+ *
+ * where     - position as returned from avl_find()
+ * direction - either AVL_BEFORE or AVL_AFTER
+ *
+ * EXAMPLE get the greatest node that is less than a given value:
+ *
+ *	avl_tree_t *tree;
+ *	struct my_data look_for_value = {....};
+ *	struct my_data *node;
+ *	struct my_data *less;
+ *	avl_index_t where;
+ *
+ *	node = avl_find(tree, &look_for_value, &where);
+ *	if (node != NULL)
+ *		less = AVL_PREV(tree, node);
+ *	else
+ *		less = avl_nearest(tree, where, AVL_BEFORE);
+ */
+extern void *avl_nearest(avl_tree_t *tree, avl_index_t where, int direction);
+
+
+/*
+ * Add a single node to the tree.
+ * The node must not be in the tree, and it must not
+ * compare equal to any other node already in the tree.
+ *
+ * node   - the node to add
+ */
+extern void avl_add(avl_tree_t *tree, void *node);
+
+
+/*
+ * Remove a single node from the tree.  The node must be in the tree.
+ *
+ * node   - the node to remove
+ */
+extern void avl_remove(avl_tree_t *tree, void *node);
+
+/*
+ * Reinsert a node only if its order has changed relative to its nearest
+ * neighbors. To optimize performance avl_update_lt() checks only the previous
+ * node and avl_update_gt() checks only the next node. Use avl_update_lt() and
+ * avl_update_gt() only if you know the direction in which the order of the
+ * node may change.
+ */
+extern boolean_t avl_update(avl_tree_t *, void *);
+extern boolean_t avl_update_lt(avl_tree_t *, void *);
+extern boolean_t avl_update_gt(avl_tree_t *, void *);
+
+/*
+ * Swaps the contents of the two trees.
+ */
+extern void avl_swap(avl_tree_t *tree1, avl_tree_t *tree2);
+
+/*
+ * Return the number of nodes in the tree
+ */
+extern ulong_t avl_numnodes(avl_tree_t *tree);
+
+/*
+ * Return B_TRUE if there are zero nodes in the tree, B_FALSE otherwise.
+ */
+extern boolean_t avl_is_empty(avl_tree_t *tree);
+
+/*
+ * Used to destroy any remaining nodes in a tree. The cookie argument should
+ * be initialized to NULL before the first call. Returns a node that has been
+ * removed from the tree and may be free()'d. Returns NULL when the tree is
+ * empty.
+ *
+ * Once you call avl_destroy_nodes(), you can only continuing calling it and
+ * finally avl_destroy(). No other AVL routines will be valid.
+ *
+ * cookie - a "void *" used to save state between calls to avl_destroy_nodes()
+ *
+ * EXAMPLE:
+ *	avl_tree_t *tree;
+ *	struct my_data *node;
+ *	void *cookie;
+ *
+ *	cookie = NULL;
+ *	while ((node = avl_destroy_nodes(tree, &cookie)) != NULL)
+ *		free(node);
+ *	avl_destroy(tree);
+ */
+extern void *avl_destroy_nodes(avl_tree_t *tree, void **cookie);
+
+
+/*
+ * Final destroy of an AVL tree. Arguments are:
+ *
+ * tree   - the empty tree to destroy
+ */
+extern void avl_destroy(avl_tree_t *tree);
+
+
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* _AVL_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/include/sys/avl_impl.h
@@ -0,0 +1,164 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License").  You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef	_AVL_IMPL_H
+#define	_AVL_IMPL_H
+
+
+
+/*
+ * This is a private header file.  Applications should not directly include
+ * this file.
+ */
+
+#include <sys/types.h>
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+
+/*
+ * generic AVL tree implementation for kernel use
+ *
+ * There are 5 pieces of information stored for each node in an AVL tree
+ *
+ * 	pointer to less than child
+ * 	pointer to greater than child
+ * 	a pointer to the parent of this node
+ *	an indication  [0/1]  of which child I am of my parent
+ * 	a "balance" (-1, 0, +1)  indicating which child tree is taller
+ *
+ * Since they only need 3 bits, the last two fields are packed into the
+ * bottom bits of the parent pointer on 64 bit machines to save on space.
+ */
+
+#ifndef _LP64
+
+struct avl_node {
+	struct avl_node *avl_child[2];	/* left/right children */
+	struct avl_node *avl_parent;	/* this node's parent */
+	unsigned short avl_child_index;	/* my index in parent's avl_child[] */
+	short avl_balance;		/* balance value: -1, 0, +1 */
+};
+
+#define	AVL_XPARENT(n)		((n)->avl_parent)
+#define	AVL_SETPARENT(n, p)	((n)->avl_parent = (p))
+
+#define	AVL_XCHILD(n)		((n)->avl_child_index)
+#define	AVL_SETCHILD(n, c)	((n)->avl_child_index = (unsigned short)(c))
+
+#define	AVL_XBALANCE(n)		((n)->avl_balance)
+#define	AVL_SETBALANCE(n, b)	((n)->avl_balance = (short)(b))
+
+#else /* _LP64 */
+
+/*
+ * for 64 bit machines, avl_pcb contains parent pointer, balance and child_index
+ * values packed in the following manner:
+ *
+ * |63                                  3|        2        |1          0 |
+ * |-------------------------------------|-----------------|-------------|
+ * |      avl_parent hi order bits       | avl_child_index | avl_balance |
+ * |                                     |                 |     + 1     |
+ * |-------------------------------------|-----------------|-------------|
+ *
+ */
+struct avl_node {
+	struct avl_node *avl_child[2];	/* left/right children nodes */
+	uintptr_t avl_pcb;		/* parent, child_index, balance */
+};
+
+/*
+ * macros to extract/set fields in avl_pcb
+ *
+ * pointer to the parent of the current node is the high order bits
+ */
+#define	AVL_XPARENT(n)		((struct avl_node *)((n)->avl_pcb & ~7))
+#define	AVL_SETPARENT(n, p)						\
+	((n)->avl_pcb = (((n)->avl_pcb & 7) | (uintptr_t)(p)))
+
+/*
+ * index of this node in its parent's avl_child[]: bit #2
+ */
+#define	AVL_XCHILD(n)		(((n)->avl_pcb >> 2) & 1)
+#define	AVL_SETCHILD(n, c)						\
+	((n)->avl_pcb = (uintptr_t)(((n)->avl_pcb & ~4) | ((c) << 2)))
+
+/*
+ * balance indication for a node, lowest 2 bits. A valid balance is
+ * -1, 0, or +1, and is encoded by adding 1 to the value to get the
+ * unsigned values of 0, 1, 2.
+ */
+#define	AVL_XBALANCE(n)		((int)(((n)->avl_pcb & 3) - 1))
+#define	AVL_SETBALANCE(n, b)						\
+	((n)->avl_pcb = (uintptr_t)((((n)->avl_pcb & ~3) | ((b) + 1))))
+
+#endif /* _LP64 */
+
+
+
+/*
+ * switch between a node and data pointer for a given tree
+ * the value of "o" is tree->avl_offset
+ */
+#define	AVL_NODE2DATA(n, o)	((void *)((uintptr_t)(n) - (o)))
+#define	AVL_DATA2NODE(d, o)	((struct avl_node *)((uintptr_t)(d) + (o)))
+
+
+
+/*
+ * macros used to create/access an avl_index_t
+ */
+#define	AVL_INDEX2NODE(x)	((avl_node_t *)((x) & ~1))
+#define	AVL_INDEX2CHILD(x)	((x) & 1)
+#define	AVL_MKINDEX(n, c)	((avl_index_t)(n) | (c))
+
+
+/*
+ * The tree structure. The fields avl_root, avl_compar, and avl_offset come
+ * first since they are needed for avl_find().  We want them to fit into
+ * a single 64 byte cache line to make avl_find() as fast as possible.
+ */
+struct avl_tree {
+	struct avl_node *avl_root;	/* root node in tree */
+	int (*avl_compar)(const void *, const void *);
+	size_t avl_offset;		/* offsetof(type, avl_link_t field) */
+	ulong_t avl_numnodes;		/* number of nodes in the tree */
+	size_t avl_size;		/* sizeof user type struct */
+};
+
+
+/*
+ * This will only by used via AVL_NEXT() or AVL_PREV()
+ */
+extern void *avl_walk(struct avl_tree *, void *, int);
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* _AVL_IMPL_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/include/sys/blkptr.h
@@ -0,0 +1,38 @@
+/*
+ * CDDL HEADER START
+ *
+ * This file and its contents are supplied under the terms of the
+ * Common Development and Distribution License ("CDDL"), version 1.0.
+ * You may only use this file in accordance with the terms of version
+ * 1.0 of the CDDL.
+ *
+ * A full copy of the text of the CDDL should have accompanied this
+ * source.  A copy of the CDDL is also available via the Internet at
+ * http://www.illumos.org/license/CDDL.
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2013 by Delphix. All rights reserved.
+ */
+
+#ifndef _SYS_BLKPTR_H
+#define	_SYS_BLKPTR_H
+
+#include <sys/spa.h>
+#include <sys/zio.h>
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+void encode_embedded_bp_compressed(blkptr_t *, void *,
+    enum zio_compress, int, int);
+void decode_embedded_bp_compressed(const blkptr_t *, void *);
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* _SYS_BLKPTR_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/include/sys/bplist.h
@@ -0,0 +1,57 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ */
+
+#ifndef	_SYS_BPLIST_H
+#define	_SYS_BPLIST_H
+
+#include <sys/zfs_context.h>
+#include <sys/spa.h>
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+typedef struct bplist_entry {
+	blkptr_t	bpe_blk;
+	list_node_t	bpe_node;
+} bplist_entry_t;
+
+typedef struct bplist {
+	kmutex_t	bpl_lock;
+	list_t		bpl_list;
+} bplist_t;
+
+typedef int bplist_itor_t(void *arg, const blkptr_t *bp, dmu_tx_t *tx);
+
+void bplist_create(bplist_t *bpl);
+void bplist_destroy(bplist_t *bpl);
+void bplist_append(bplist_t *bpl, const blkptr_t *bp);
+void bplist_iterate(bplist_t *bpl, bplist_itor_t *func,
+    void *arg, dmu_tx_t *tx);
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif /* _SYS_BPLIST_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/include/sys/bpobj.h
@@ -0,0 +1,93 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2014 by Delphix. All rights reserved.
+ */
+
+#ifndef	_SYS_BPOBJ_H
+#define	_SYS_BPOBJ_H
+
+#include <sys/dmu.h>
+#include <sys/spa.h>
+#include <sys/txg.h>
+#include <sys/zio.h>
+#include <sys/zfs_context.h>
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+typedef struct bpobj_phys {
+	/*
+	 * This is the bonus buffer for the dead lists.  The object's
+	 * contents is an array of bpo_entries blkptr_t's, representing
+	 * a total of bpo_bytes physical space.
+	 */
+	uint64_t	bpo_num_blkptrs;
+	uint64_t	bpo_bytes;
+	uint64_t	bpo_comp;
+	uint64_t	bpo_uncomp;
+	uint64_t	bpo_subobjs;
+	uint64_t	bpo_num_subobjs;
+} bpobj_phys_t;
+
+#define	BPOBJ_SIZE_V0	(2 * sizeof (uint64_t))
+#define	BPOBJ_SIZE_V1	(4 * sizeof (uint64_t))
+
+typedef struct bpobj {
+	kmutex_t	bpo_lock;
+	objset_t	*bpo_os;
+	uint64_t	bpo_object;
+	int		bpo_epb;
+	uint8_t		bpo_havecomp;
+	uint8_t		bpo_havesubobj;
+	bpobj_phys_t	*bpo_phys;
+	dmu_buf_t	*bpo_dbuf;
+	dmu_buf_t	*bpo_cached_dbuf;
+} bpobj_t;
+
+typedef int bpobj_itor_t(void *arg, const blkptr_t *bp, dmu_tx_t *tx);
+
+uint64_t bpobj_alloc(objset_t *mos, int blocksize, dmu_tx_t *tx);
+uint64_t bpobj_alloc_empty(objset_t *os, int blocksize, dmu_tx_t *tx);
+void bpobj_free(objset_t *os, uint64_t obj, dmu_tx_t *tx);
+void bpobj_decr_empty(objset_t *os, dmu_tx_t *tx);
+
+int bpobj_open(bpobj_t *bpo, objset_t *mos, uint64_t object);
+void bpobj_close(bpobj_t *bpo);
+
+int bpobj_iterate(bpobj_t *bpo, bpobj_itor_t func, void *arg, dmu_tx_t *tx);
+int bpobj_iterate_nofree(bpobj_t *bpo, bpobj_itor_t func, void *, dmu_tx_t *);
+
+void bpobj_enqueue_subobj(bpobj_t *bpo, uint64_t subobj, dmu_tx_t *tx);
+void bpobj_enqueue(bpobj_t *bpo, const blkptr_t *bp, dmu_tx_t *tx);
+
+int bpobj_space(bpobj_t *bpo,
+    uint64_t *usedp, uint64_t *compp, uint64_t *uncompp);
+int bpobj_space_range(bpobj_t *bpo, uint64_t mintxg, uint64_t maxtxg,
+    uint64_t *usedp, uint64_t *compp, uint64_t *uncompp);
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif /* _SYS_BPOBJ_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/include/sys/bptree.h
@@ -0,0 +1,65 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2012, 2014 by Delphix. All rights reserved.
+ */
+
+#ifndef	_SYS_BPTREE_H
+#define	_SYS_BPTREE_H
+
+#include <sys/spa.h>
+#include <sys/zio.h>
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+typedef struct bptree_phys {
+	uint64_t bt_begin;
+	uint64_t bt_end;
+	uint64_t bt_bytes;
+	uint64_t bt_comp;
+	uint64_t bt_uncomp;
+} bptree_phys_t;
+
+typedef struct bptree_entry_phys {
+	blkptr_t be_bp;
+	uint64_t be_birth_txg; /* only delete blocks born after this txg */
+	zbookmark_phys_t be_zb; /* holds traversal resume point if needed */
+} bptree_entry_phys_t;
+
+typedef int bptree_itor_t(void *arg, const blkptr_t *bp, dmu_tx_t *tx);
+
+uint64_t bptree_alloc(objset_t *os, dmu_tx_t *tx);
+int bptree_free(objset_t *os, uint64_t obj, dmu_tx_t *tx);
+boolean_t bptree_is_empty(objset_t *os, uint64_t obj);
+
+void bptree_add(objset_t *os, uint64_t obj, blkptr_t *bp, uint64_t birth_txg,
+    uint64_t bytes, uint64_t comp, uint64_t uncomp, dmu_tx_t *tx);
+
+int bptree_iterate(objset_t *os, uint64_t obj, boolean_t free,
+    bptree_itor_t func, void *arg, dmu_tx_t *tx);
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* _SYS_BPTREE_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/include/sys/dbuf.h
@@ -0,0 +1,392 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2015 by Delphix. All rights reserved.
+ * Copyright (c) 2013 by Saso Kiselkov. All rights reserved.
+ * Copyright (c) 2014 Spectra Logic Corporation, All rights reserved.
+ */
+
+#ifndef	_SYS_DBUF_H
+#define	_SYS_DBUF_H
+
+#include <sys/dmu.h>
+#include <sys/spa.h>
+#include <sys/txg.h>
+#include <sys/zio.h>
+#include <sys/arc.h>
+#include <sys/zfs_context.h>
+#include <sys/refcount.h>
+#include <sys/zrlock.h>
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+#define	IN_DMU_SYNC 2
+
+/*
+ * define flags for dbuf_read
+ */
+
+#define	DB_RF_MUST_SUCCEED	(1 << 0)
+#define	DB_RF_CANFAIL		(1 << 1)
+#define	DB_RF_HAVESTRUCT	(1 << 2)
+#define	DB_RF_NOPREFETCH	(1 << 3)
+#define	DB_RF_NEVERWAIT		(1 << 4)
+#define	DB_RF_CACHED		(1 << 5)
+
+/*
+ * The simplified state transition diagram for dbufs looks like:
+ *
+ *		+----> READ ----+
+ *		|		|
+ *		|		V
+ *  (alloc)-->UNCACHED	     CACHED-->EVICTING-->(free)
+ *		|		^	 ^
+ *		|		|	 |
+ *		+----> FILL ----+	 |
+ *		|			 |
+ *		|			 |
+ *		+--------> NOFILL -------+
+ *
+ * DB_SEARCH is an invalid state for a dbuf. It is used by dbuf_free_range
+ * to find all dbufs in a range of a dnode and must be less than any other
+ * dbuf_states_t (see comment on dn_dbufs in dnode.h).
+ */
+typedef enum dbuf_states {
+	DB_SEARCH = -1,
+	DB_UNCACHED,
+	DB_FILL,
+	DB_NOFILL,
+	DB_READ,
+	DB_CACHED,
+	DB_EVICTING
+} dbuf_states_t;
+
+struct dnode;
+struct dmu_tx;
+
+/*
+ * level = 0 means the user data
+ * level = 1 means the single indirect block
+ * etc.
+ */
+
+struct dmu_buf_impl;
+
+typedef enum override_states {
+	DR_NOT_OVERRIDDEN,
+	DR_IN_DMU_SYNC,
+	DR_OVERRIDDEN
+} override_states_t;
+
+typedef struct dbuf_dirty_record {
+	/* link on our parents dirty list */
+	list_node_t dr_dirty_node;
+
+	/* transaction group this data will sync in */
+	uint64_t dr_txg;
+
+	/* zio of outstanding write IO */
+	zio_t *dr_zio;
+
+	/* pointer back to our dbuf */
+	struct dmu_buf_impl *dr_dbuf;
+
+	/* pointer to next dirty record */
+	struct dbuf_dirty_record *dr_next;
+
+	/* pointer to parent dirty record */
+	struct dbuf_dirty_record *dr_parent;
+
+	/* How much space was changed to dsl_pool_dirty_space() for this? */
+	unsigned int dr_accounted;
+
+	union dirty_types {
+		struct dirty_indirect {
+
+			/* protect access to list */
+			kmutex_t dr_mtx;
+
+			/* Our list of dirty children */
+			list_t dr_children;
+		} di;
+		struct dirty_leaf {
+
+			/*
+			 * dr_data is set when we dirty the buffer
+			 * so that we can retain the pointer even if it
+			 * gets COW'd in a subsequent transaction group.
+			 */
+			arc_buf_t *dr_data;
+			blkptr_t dr_overridden_by;
+			override_states_t dr_override_state;
+			uint8_t dr_copies;
+			boolean_t dr_nopwrite;
+		} dl;
+	} dt;
+} dbuf_dirty_record_t;
+
+typedef struct dmu_buf_impl {
+	/*
+	 * The following members are immutable, with the exception of
+	 * db.db_data, which is protected by db_mtx.
+	 */
+
+	/* the publicly visible structure */
+	dmu_buf_t db;
+
+	/* the objset we belong to */
+	struct objset *db_objset;
+
+	/*
+	 * handle to safely access the dnode we belong to (NULL when evicted)
+	 */
+	struct dnode_handle *db_dnode_handle;
+
+	/*
+	 * our parent buffer; if the dnode points to us directly,
+	 * db_parent == db_dnode_handle->dnh_dnode->dn_dbuf
+	 * only accessed by sync thread ???
+	 * (NULL when evicted)
+	 * May change from NULL to non-NULL under the protection of db_mtx
+	 * (see dbuf_check_blkptr())
+	 */
+	struct dmu_buf_impl *db_parent;
+
+	/*
+	 * link for hash table of all dmu_buf_impl_t's
+	 */
+	struct dmu_buf_impl *db_hash_next;
+
+	/* our block number */
+	uint64_t db_blkid;
+
+	/*
+	 * Pointer to the blkptr_t which points to us. May be NULL if we
+	 * don't have one yet. (NULL when evicted)
+	 */
+	blkptr_t *db_blkptr;
+
+	/*
+	 * Our indirection level.  Data buffers have db_level==0.
+	 * Indirect buffers which point to data buffers have
+	 * db_level==1. etc.  Buffers which contain dnodes have
+	 * db_level==0, since the dnodes are stored in a file.
+	 */
+	uint8_t db_level;
+
+	/* db_mtx protects the members below */
+	kmutex_t db_mtx;
+
+	/*
+	 * Current state of the buffer
+	 */
+	dbuf_states_t db_state;
+
+	/*
+	 * Refcount accessed by dmu_buf_{hold,rele}.
+	 * If nonzero, the buffer can't be destroyed.
+	 * Protected by db_mtx.
+	 */
+	refcount_t db_holds;
+
+	/* buffer holding our data */
+	arc_buf_t *db_buf;
+
+	kcondvar_t db_changed;
+	dbuf_dirty_record_t *db_data_pending;
+
+	/* pointer to most recent dirty record for this buffer */
+	dbuf_dirty_record_t *db_last_dirty;
+
+	/*
+	 * Our link on the owner dnodes's dn_dbufs list.
+	 * Protected by its dn_dbufs_mtx.
+	 */
+	avl_node_t db_link;
+
+	/* Data which is unique to data (leaf) blocks: */
+
+	/* User callback information. */
+	dmu_buf_user_t *db_user;
+
+	/*
+	 * Evict user data as soon as the dirty and reference
+	 * counts are equal.
+	 */
+	uint8_t db_user_immediate_evict;
+
+	/*
+	 * This block was freed while a read or write was
+	 * active.
+	 */
+	uint8_t db_freed_in_flight;
+
+	/*
+	 * dnode_evict_dbufs() or dnode_evict_bonus() tried to
+	 * evict this dbuf, but couldn't due to outstanding
+	 * references.  Evict once the refcount drops to 0.
+	 */
+	uint8_t db_pending_evict;
+
+	uint8_t db_dirtycnt;
+} dmu_buf_impl_t;
+
+/* Note: the dbuf hash table is exposed only for the mdb module */
+#define	DBUF_MUTEXES 8192
+#define	DBUF_HASH_MUTEX(h, idx) (&(h)->hash_mutexes[(idx) & (DBUF_MUTEXES-1)])
+typedef struct dbuf_hash_table {
+	uint64_t hash_table_mask;
+	dmu_buf_impl_t **hash_table;
+	kmutex_t hash_mutexes[DBUF_MUTEXES];
+} dbuf_hash_table_t;
+
+
+uint64_t dbuf_whichblock(struct dnode *di, uint64_t offset);
+
+void dbuf_create_bonus(struct dnode *dn);
+int dbuf_spill_set_blksz(dmu_buf_t *db, uint64_t blksz, dmu_tx_t *tx);
+
+void dbuf_rm_spill(struct dnode *dn, dmu_tx_t *tx);
+
+dmu_buf_impl_t *dbuf_hold(struct dnode *dn, uint64_t blkid, void *tag);
+dmu_buf_impl_t *dbuf_hold_level(struct dnode *dn, int level, uint64_t blkid,
+    void *tag);
+int dbuf_hold_impl(struct dnode *dn, uint8_t level, uint64_t blkid, int create,
+    void *tag, dmu_buf_impl_t **dbp);
+
+void dbuf_prefetch(struct dnode *dn, uint64_t blkid, zio_priority_t prio);
+
+void dbuf_add_ref(dmu_buf_impl_t *db, void *tag);
+boolean_t dbuf_try_add_ref(dmu_buf_t *db, objset_t *os, uint64_t obj,
+    uint64_t blkid, void *tag);
+uint64_t dbuf_refcount(dmu_buf_impl_t *db);
+
+void dbuf_rele(dmu_buf_impl_t *db, void *tag);
+void dbuf_rele_and_unlock(dmu_buf_impl_t *db, void *tag);
+
+dmu_buf_impl_t *dbuf_find(struct objset *os, uint64_t object, uint8_t level,
+    uint64_t blkid);
+
+int dbuf_read(dmu_buf_impl_t *db, zio_t *zio, uint32_t flags);
+void dmu_buf_will_not_fill(dmu_buf_t *db, dmu_tx_t *tx);
+void dmu_buf_will_fill(dmu_buf_t *db, dmu_tx_t *tx);
+void dmu_buf_fill_done(dmu_buf_t *db, dmu_tx_t *tx);
+void dbuf_assign_arcbuf(dmu_buf_impl_t *db, arc_buf_t *buf, dmu_tx_t *tx);
+dbuf_dirty_record_t *dbuf_dirty(dmu_buf_impl_t *db, dmu_tx_t *tx);
+arc_buf_t *dbuf_loan_arcbuf(dmu_buf_impl_t *db);
+void dmu_buf_write_embedded(dmu_buf_t *dbuf, void *data,
+    bp_embedded_type_t etype, enum zio_compress comp,
+    int uncompressed_size, int compressed_size, int byteorder, dmu_tx_t *tx);
+
+void dbuf_clear(dmu_buf_impl_t *db);
+void dbuf_evict(dmu_buf_impl_t *db);
+
+void dbuf_unoverride(dbuf_dirty_record_t *dr);
+void dbuf_sync_list(list_t *list, int level, dmu_tx_t *tx);
+void dbuf_release_bp(dmu_buf_impl_t *db);
+
+void dbuf_free_range(struct dnode *dn, uint64_t start, uint64_t end,
+    struct dmu_tx *);
+
+void dbuf_new_size(dmu_buf_impl_t *db, int size, dmu_tx_t *tx);
+
+void dbuf_stats_init(dbuf_hash_table_t *hash);
+void dbuf_stats_destroy(void);
+
+#define	DB_DNODE(_db)		((_db)->db_dnode_handle->dnh_dnode)
+#define	DB_DNODE_LOCK(_db)	((_db)->db_dnode_handle->dnh_zrlock)
+#define	DB_DNODE_ENTER(_db)	(zrl_add(&DB_DNODE_LOCK(_db)))
+#define	DB_DNODE_EXIT(_db)	(zrl_remove(&DB_DNODE_LOCK(_db)))
+#define	DB_DNODE_HELD(_db)	(!zrl_is_zero(&DB_DNODE_LOCK(_db)))
+
+void dbuf_init(void);
+void dbuf_fini(void);
+
+boolean_t dbuf_is_metadata(dmu_buf_impl_t *db);
+
+#define	DBUF_GET_BUFC_TYPE(_db)	\
+	(dbuf_is_metadata(_db) ? ARC_BUFC_METADATA : ARC_BUFC_DATA)
+
+#define	DBUF_IS_CACHEABLE(_db)						\
+	((_db)->db_objset->os_primary_cache == ZFS_CACHE_ALL ||		\
+	(dbuf_is_metadata(_db) &&					\
+	((_db)->db_objset->os_primary_cache == ZFS_CACHE_METADATA)))
+
+#define	DBUF_IS_L2CACHEABLE(_db)					\
+	((_db)->db_objset->os_secondary_cache == ZFS_CACHE_ALL ||	\
+	(dbuf_is_metadata(_db) &&					\
+	((_db)->db_objset->os_secondary_cache == ZFS_CACHE_METADATA)))
+
+#define	DBUF_IS_L2COMPRESSIBLE(_db)					\
+	((_db)->db_objset->os_compress != ZIO_COMPRESS_OFF ||		\
+	(dbuf_is_metadata(_db) && zfs_mdcomp_disable == B_FALSE))
+
+#ifdef ZFS_DEBUG
+
+/*
+ * There should be a ## between the string literal and fmt, to make it
+ * clear that we're joining two strings together, but gcc does not
+ * support that preprocessor token.
+ */
+#define	dprintf_dbuf(dbuf, fmt, ...) do { \
+	if (zfs_flags & ZFS_DEBUG_DPRINTF) { \
+	char __db_buf[32]; \
+	uint64_t __db_obj = (dbuf)->db.db_object; \
+	if (__db_obj == DMU_META_DNODE_OBJECT) \
+		(void) strcpy(__db_buf, "mdn"); \
+	else \
+		(void) snprintf(__db_buf, sizeof (__db_buf), "%lld", \
+		    (u_longlong_t)__db_obj); \
+	dprintf_ds((dbuf)->db_objset->os_dsl_dataset, \
+	    "obj=%s lvl=%u blkid=%lld " fmt, \
+	    __db_buf, (dbuf)->db_level, \
+	    (u_longlong_t)(dbuf)->db_blkid, __VA_ARGS__); \
+	} \
+_NOTE(CONSTCOND) } while (0)
+
+#define	dprintf_dbuf_bp(db, bp, fmt, ...) do {			\
+	if (zfs_flags & ZFS_DEBUG_DPRINTF) {			\
+	char *__blkbuf = kmem_alloc(BP_SPRINTF_LEN, KM_SLEEP);	\
+	snprintf_blkptr(__blkbuf, BP_SPRINTF_LEN, bp);		\
+	dprintf_dbuf(db, fmt " %s\n", __VA_ARGS__, __blkbuf);	\
+	kmem_free(__blkbuf, BP_SPRINTF_LEN);			\
+	}							\
+_NOTE(CONSTCOND) } while (0)
+
+#define	DBUF_VERIFY(db)	dbuf_verify(db)
+
+#else
+
+#define	dprintf_dbuf(db, fmt, ...)
+#define	dprintf_dbuf_bp(db, bp, fmt, ...)
+#define	DBUF_VERIFY(db)
+
+#endif
+
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif /* _SYS_DBUF_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/include/sys/ddt.h
@@ -0,0 +1,247 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
+ */
+
+#ifndef _SYS_DDT_H
+#define	_SYS_DDT_H
+
+#include <sys/sysmacros.h>
+#include <sys/types.h>
+#include <sys/fs/zfs.h>
+#include <sys/zio.h>
+#include <sys/dmu.h>
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+/*
+ * On-disk DDT formats, in the desired search order (newest version first).
+ */
+enum ddt_type {
+	DDT_TYPE_ZAP = 0,
+	DDT_TYPES
+};
+
+/*
+ * DDT classes, in the desired search order (highest replication level first).
+ */
+enum ddt_class {
+	DDT_CLASS_DITTO = 0,
+	DDT_CLASS_DUPLICATE,
+	DDT_CLASS_UNIQUE,
+	DDT_CLASSES
+};
+
+#define	DDT_TYPE_CURRENT		0
+
+#define	DDT_COMPRESS_BYTEORDER_MASK	0x80
+#define	DDT_COMPRESS_FUNCTION_MASK	0x7f
+
+/*
+ * On-disk ddt entry:  key (name) and physical storage (value).
+ */
+typedef struct ddt_key {
+	zio_cksum_t	ddk_cksum;	/* 256-bit block checksum */
+	/*
+	 * Encoded with logical & physical size, and compression, as follows:
+	 *   +-------+-------+-------+-------+-------+-------+-------+-------+
+	 *   |   0   |   0   |   0   | comp  |     PSIZE     |     LSIZE     |
+	 *   +-------+-------+-------+-------+-------+-------+-------+-------+
+	 */
+	uint64_t	ddk_prop;
+} ddt_key_t;
+
+#define	DDK_GET_LSIZE(ddk)	\
+	BF64_GET_SB((ddk)->ddk_prop, 0, 16, SPA_MINBLOCKSHIFT, 1)
+#define	DDK_SET_LSIZE(ddk, x)	\
+	BF64_SET_SB((ddk)->ddk_prop, 0, 16, SPA_MINBLOCKSHIFT, 1, x)
+
+#define	DDK_GET_PSIZE(ddk)	\
+	BF64_GET_SB((ddk)->ddk_prop, 16, 16, SPA_MINBLOCKSHIFT, 1)
+#define	DDK_SET_PSIZE(ddk, x)	\
+	BF64_SET_SB((ddk)->ddk_prop, 16, 16, SPA_MINBLOCKSHIFT, 1, x)
+
+#define	DDK_GET_COMPRESS(ddk)		BF64_GET((ddk)->ddk_prop, 32, 8)
+#define	DDK_SET_COMPRESS(ddk, x)	BF64_SET((ddk)->ddk_prop, 32, 8, x)
+
+#define	DDT_KEY_WORDS	(sizeof (ddt_key_t) / sizeof (uint64_t))
+
+typedef struct ddt_phys {
+	dva_t		ddp_dva[SPA_DVAS_PER_BP];
+	uint64_t	ddp_refcnt;
+	uint64_t	ddp_phys_birth;
+} ddt_phys_t;
+
+enum ddt_phys_type {
+	DDT_PHYS_DITTO = 0,
+	DDT_PHYS_SINGLE = 1,
+	DDT_PHYS_DOUBLE = 2,
+	DDT_PHYS_TRIPLE = 3,
+	DDT_PHYS_TYPES
+};
+
+/*
+ * In-core ddt entry
+ */
+struct ddt_entry {
+	ddt_key_t	dde_key;
+	ddt_phys_t	dde_phys[DDT_PHYS_TYPES];
+	zio_t		*dde_lead_zio[DDT_PHYS_TYPES];
+	void		*dde_repair_data;
+	enum ddt_type	dde_type;
+	enum ddt_class	dde_class;
+	uint8_t		dde_loading;
+	uint8_t		dde_loaded;
+	kcondvar_t	dde_cv;
+	avl_node_t	dde_node;
+};
+
+/*
+ * In-core ddt
+ */
+struct ddt {
+	kmutex_t	ddt_lock;
+	avl_tree_t	ddt_tree;
+	avl_tree_t	ddt_repair_tree;
+	enum zio_checksum ddt_checksum;
+	spa_t		*ddt_spa;
+	objset_t	*ddt_os;
+	uint64_t	ddt_stat_object;
+	uint64_t	ddt_object[DDT_TYPES][DDT_CLASSES];
+	ddt_histogram_t	ddt_histogram[DDT_TYPES][DDT_CLASSES];
+	ddt_histogram_t	ddt_histogram_cache[DDT_TYPES][DDT_CLASSES];
+	ddt_object_t	ddt_object_stats[DDT_TYPES][DDT_CLASSES];
+	avl_node_t	ddt_node;
+};
+
+/*
+ * In-core and on-disk bookmark for DDT walks
+ */
+typedef struct ddt_bookmark {
+	uint64_t	ddb_class;
+	uint64_t	ddb_type;
+	uint64_t	ddb_checksum;
+	uint64_t	ddb_cursor;
+} ddt_bookmark_t;
+
+/*
+ * Ops vector to access a specific DDT object type.
+ */
+typedef struct ddt_ops {
+	char ddt_op_name[32];
+	int (*ddt_op_create)(objset_t *os, uint64_t *object, dmu_tx_t *tx,
+	    boolean_t prehash);
+	int (*ddt_op_destroy)(objset_t *os, uint64_t object, dmu_tx_t *tx);
+	int (*ddt_op_lookup)(objset_t *os, uint64_t object, ddt_entry_t *dde);
+	void (*ddt_op_prefetch)(objset_t *os, uint64_t object,
+	    ddt_entry_t *dde);
+	int (*ddt_op_update)(objset_t *os, uint64_t object, ddt_entry_t *dde,
+	    dmu_tx_t *tx);
+	int (*ddt_op_remove)(objset_t *os, uint64_t object, ddt_entry_t *dde,
+	    dmu_tx_t *tx);
+	int (*ddt_op_walk)(objset_t *os, uint64_t object, ddt_entry_t *dde,
+	    uint64_t *walk);
+	int (*ddt_op_count)(objset_t *os, uint64_t object, uint64_t *count);
+} ddt_ops_t;
+
+#define	DDT_NAMELEN	80
+
+extern void ddt_object_name(ddt_t *ddt, enum ddt_type type,
+    enum ddt_class class, char *name);
+extern int ddt_object_walk(ddt_t *ddt, enum ddt_type type,
+    enum ddt_class class, uint64_t *walk, ddt_entry_t *dde);
+extern int ddt_object_count(ddt_t *ddt, enum ddt_type type,
+    enum ddt_class class, uint64_t *count);
+extern int ddt_object_info(ddt_t *ddt, enum ddt_type type,
+    enum ddt_class class, dmu_object_info_t *);
+extern boolean_t ddt_object_exists(ddt_t *ddt, enum ddt_type type,
+    enum ddt_class class);
+
+extern void ddt_bp_fill(const ddt_phys_t *ddp, blkptr_t *bp,
+    uint64_t txg);
+extern void ddt_bp_create(enum zio_checksum checksum, const ddt_key_t *ddk,
+    const ddt_phys_t *ddp, blkptr_t *bp);
+
+extern void ddt_key_fill(ddt_key_t *ddk, const blkptr_t *bp);
+
+extern void ddt_phys_fill(ddt_phys_t *ddp, const blkptr_t *bp);
+extern void ddt_phys_clear(ddt_phys_t *ddp);
+extern void ddt_phys_addref(ddt_phys_t *ddp);
+extern void ddt_phys_decref(ddt_phys_t *ddp);
+extern void ddt_phys_free(ddt_t *ddt, ddt_key_t *ddk, ddt_phys_t *ddp,
+    uint64_t txg);
+extern ddt_phys_t *ddt_phys_select(const ddt_entry_t *dde, const blkptr_t *bp);
+extern uint64_t ddt_phys_total_refcnt(const ddt_entry_t *dde);
+
+extern void ddt_stat_add(ddt_stat_t *dst, const ddt_stat_t *src, uint64_t neg);
+
+extern void ddt_histogram_add(ddt_histogram_t *dst, const ddt_histogram_t *src);
+extern void ddt_histogram_stat(ddt_stat_t *dds, const ddt_histogram_t *ddh);
+extern boolean_t ddt_histogram_empty(const ddt_histogram_t *ddh);
+extern void ddt_get_dedup_object_stats(spa_t *spa, ddt_object_t *ddo);
+extern void ddt_get_dedup_histogram(spa_t *spa, ddt_histogram_t *ddh);
+extern void ddt_get_dedup_stats(spa_t *spa, ddt_stat_t *dds_total);
+
+extern uint64_t ddt_get_dedup_dspace(spa_t *spa);
+extern uint64_t ddt_get_pool_dedup_ratio(spa_t *spa);
+
+extern int ddt_ditto_copies_needed(ddt_t *ddt, ddt_entry_t *dde,
+    ddt_phys_t *ddp_willref);
+extern int ddt_ditto_copies_present(ddt_entry_t *dde);
+
+extern size_t ddt_compress(void *src, uchar_t *dst, size_t s_len, size_t d_len);
+extern void ddt_decompress(uchar_t *src, void *dst, size_t s_len, size_t d_len);
+
+extern ddt_t *ddt_select(spa_t *spa, const blkptr_t *bp);
+extern void ddt_enter(ddt_t *ddt);
+extern void ddt_exit(ddt_t *ddt);
+extern void ddt_init(void);
+extern void ddt_fini(void);
+extern ddt_entry_t *ddt_lookup(ddt_t *ddt, const blkptr_t *bp, boolean_t add);
+extern void ddt_prefetch(spa_t *spa, const blkptr_t *bp);
+extern void ddt_remove(ddt_t *ddt, ddt_entry_t *dde);
+
+extern boolean_t ddt_class_contains(spa_t *spa, enum ddt_class max_class,
+    const blkptr_t *bp);
+
+extern ddt_entry_t *ddt_repair_start(ddt_t *ddt, const blkptr_t *bp);
+extern void ddt_repair_done(ddt_t *ddt, ddt_entry_t *dde);
+
+extern int ddt_entry_compare(const void *x1, const void *x2);
+
+extern void ddt_create(spa_t *spa);
+extern int ddt_load(spa_t *spa);
+extern void ddt_unload(spa_t *spa);
+extern void ddt_sync(spa_t *spa, uint64_t txg);
+extern int ddt_walk(spa_t *spa, ddt_bookmark_t *ddb, ddt_entry_t *dde);
+extern int ddt_object_update(ddt_t *ddt, enum ddt_type type,
+    enum ddt_class class, ddt_entry_t *dde, dmu_tx_t *tx);
+
+extern const ddt_ops_t ddt_zap_ops;
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* _SYS_DDT_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/include/sys/dmu.h
@@ -0,0 +1,934 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2014 by Delphix. All rights reserved.
+ * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
+ * Copyright (c) 2012, Joyent, Inc. All rights reserved.
+ * Copyright 2014 HybridCluster. All rights reserved.
+ * Copyright (c) 2014 Spectra Logic Corporation, All rights reserved.
+ */
+
+/* Portions Copyright 2010 Robert Milkowski */
+
+#ifndef	_SYS_DMU_H
+#define	_SYS_DMU_H
+
+/*
+ * This file describes the interface that the DMU provides for its
+ * consumers.
+ *
+ * The DMU also interacts with the SPA.  That interface is described in
+ * dmu_spa.h.
+ */
+
+#include <sys/zfs_context.h>
+#include <sys/inttypes.h>
+#include <sys/cred.h>
+#include <sys/fs/zfs.h>
+#include <sys/uio.h>
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+struct page;
+struct vnode;
+struct spa;
+struct zilog;
+struct zio;
+struct blkptr;
+struct zap_cursor;
+struct dsl_dataset;
+struct dsl_pool;
+struct dnode;
+struct drr_begin;
+struct drr_end;
+struct zbookmark_phys;
+struct spa;
+struct nvlist;
+struct arc_buf;
+struct zio_prop;
+struct sa_handle;
+
+typedef struct objset objset_t;
+typedef struct dmu_tx dmu_tx_t;
+typedef struct dsl_dir dsl_dir_t;
+
+typedef enum dmu_object_byteswap {
+	DMU_BSWAP_UINT8,
+	DMU_BSWAP_UINT16,
+	DMU_BSWAP_UINT32,
+	DMU_BSWAP_UINT64,
+	DMU_BSWAP_ZAP,
+	DMU_BSWAP_DNODE,
+	DMU_BSWAP_OBJSET,
+	DMU_BSWAP_ZNODE,
+	DMU_BSWAP_OLDACL,
+	DMU_BSWAP_ACL,
+	/*
+	 * Allocating a new byteswap type number makes the on-disk format
+	 * incompatible with any other format that uses the same number.
+	 *
+	 * Data can usually be structured to work with one of the
+	 * DMU_BSWAP_UINT* or DMU_BSWAP_ZAP types.
+	 */
+	DMU_BSWAP_NUMFUNCS
+} dmu_object_byteswap_t;
+
+#define	DMU_OT_NEWTYPE 0x80
+#define	DMU_OT_METADATA 0x40
+#define	DMU_OT_BYTESWAP_MASK 0x3f
+
+/*
+ * Defines a uint8_t object type. Object types specify if the data
+ * in the object is metadata (boolean) and how to byteswap the data
+ * (dmu_object_byteswap_t).
+ */
+#define	DMU_OT(byteswap, metadata) \
+	(DMU_OT_NEWTYPE | \
+	((metadata) ? DMU_OT_METADATA : 0) | \
+	((byteswap) & DMU_OT_BYTESWAP_MASK))
+
+#define	DMU_OT_IS_VALID(ot) (((ot) & DMU_OT_NEWTYPE) ? \
+	((ot) & DMU_OT_BYTESWAP_MASK) < DMU_BSWAP_NUMFUNCS : \
+	(ot) < DMU_OT_NUMTYPES)
+
+#define	DMU_OT_IS_METADATA(ot) (((ot) & DMU_OT_NEWTYPE) ? \
+	((ot) & DMU_OT_METADATA) : \
+	dmu_ot[(int)(ot)].ot_metadata)
+
+/*
+ * These object types use bp_fill != 1 for their L0 bp's. Therefore they can't
+ * have their data embedded (i.e. use a BP_IS_EMBEDDED() bp), because bp_fill
+ * is repurposed for embedded BPs.
+ */
+#define	DMU_OT_HAS_FILL(ot) \
+	((ot) == DMU_OT_DNODE || (ot) == DMU_OT_OBJSET)
+
+#define	DMU_OT_BYTESWAP(ot) (((ot) & DMU_OT_NEWTYPE) ? \
+	((ot) & DMU_OT_BYTESWAP_MASK) : \
+	dmu_ot[(int)(ot)].ot_byteswap)
+
+typedef enum dmu_object_type {
+	DMU_OT_NONE,
+	/* general: */
+	DMU_OT_OBJECT_DIRECTORY,	/* ZAP */
+	DMU_OT_OBJECT_ARRAY,		/* UINT64 */
+	DMU_OT_PACKED_NVLIST,		/* UINT8 (XDR by nvlist_pack/unpack) */
+	DMU_OT_PACKED_NVLIST_SIZE,	/* UINT64 */
+	DMU_OT_BPOBJ,			/* UINT64 */
+	DMU_OT_BPOBJ_HDR,		/* UINT64 */
+	/* spa: */
+	DMU_OT_SPACE_MAP_HEADER,	/* UINT64 */
+	DMU_OT_SPACE_MAP,		/* UINT64 */
+	/* zil: */
+	DMU_OT_INTENT_LOG,		/* UINT64 */
+	/* dmu: */
+	DMU_OT_DNODE,			/* DNODE */
+	DMU_OT_OBJSET,			/* OBJSET */
+	/* dsl: */
+	DMU_OT_DSL_DIR,			/* UINT64 */
+	DMU_OT_DSL_DIR_CHILD_MAP,	/* ZAP */
+	DMU_OT_DSL_DS_SNAP_MAP,		/* ZAP */
+	DMU_OT_DSL_PROPS,		/* ZAP */
+	DMU_OT_DSL_DATASET,		/* UINT64 */
+	/* zpl: */
+	DMU_OT_ZNODE,			/* ZNODE */
+	DMU_OT_OLDACL,			/* Old ACL */
+	DMU_OT_PLAIN_FILE_CONTENTS,	/* UINT8 */
+	DMU_OT_DIRECTORY_CONTENTS,	/* ZAP */
+	DMU_OT_MASTER_NODE,		/* ZAP */
+	DMU_OT_UNLINKED_SET,		/* ZAP */
+	/* zvol: */
+	DMU_OT_ZVOL,			/* UINT8 */
+	DMU_OT_ZVOL_PROP,		/* ZAP */
+	/* other; for testing only! */
+	DMU_OT_PLAIN_OTHER,		/* UINT8 */
+	DMU_OT_UINT64_OTHER,		/* UINT64 */
+	DMU_OT_ZAP_OTHER,		/* ZAP */
+	/* new object types: */
+	DMU_OT_ERROR_LOG,		/* ZAP */
+	DMU_OT_SPA_HISTORY,		/* UINT8 */
+	DMU_OT_SPA_HISTORY_OFFSETS,	/* spa_his_phys_t */
+	DMU_OT_POOL_PROPS,		/* ZAP */
+	DMU_OT_DSL_PERMS,		/* ZAP */
+	DMU_OT_ACL,			/* ACL */
+	DMU_OT_SYSACL,			/* SYSACL */
+	DMU_OT_FUID,			/* FUID table (Packed NVLIST UINT8) */
+	DMU_OT_FUID_SIZE,		/* FUID table size UINT64 */
+	DMU_OT_NEXT_CLONES,		/* ZAP */
+	DMU_OT_SCAN_QUEUE,		/* ZAP */
+	DMU_OT_USERGROUP_USED,		/* ZAP */
+	DMU_OT_USERGROUP_QUOTA,		/* ZAP */
+	DMU_OT_USERREFS,		/* ZAP */
+	DMU_OT_DDT_ZAP,			/* ZAP */
+	DMU_OT_DDT_STATS,		/* ZAP */
+	DMU_OT_SA,			/* System attr */
+	DMU_OT_SA_MASTER_NODE,		/* ZAP */
+	DMU_OT_SA_ATTR_REGISTRATION,	/* ZAP */
+	DMU_OT_SA_ATTR_LAYOUTS,		/* ZAP */
+	DMU_OT_SCAN_XLATE,		/* ZAP */
+	DMU_OT_DEDUP,			/* fake dedup BP from ddt_bp_create() */
+	DMU_OT_DEADLIST,		/* ZAP */
+	DMU_OT_DEADLIST_HDR,		/* UINT64 */
+	DMU_OT_DSL_CLONES,		/* ZAP */
+	DMU_OT_BPOBJ_SUBOBJ,		/* UINT64 */
+	/*
+	 * Do not allocate new object types here. Doing so makes the on-disk
+	 * format incompatible with any other format that uses the same object
+	 * type number.
+	 *
+	 * When creating an object which does not have one of the above types
+	 * use the DMU_OTN_* type with the correct byteswap and metadata
+	 * values.
+	 *
+	 * The DMU_OTN_* types do not have entries in the dmu_ot table,
+	 * use the DMU_OT_IS_METDATA() and DMU_OT_BYTESWAP() macros instead
+	 * of indexing into dmu_ot directly (this works for both DMU_OT_* types
+	 * and DMU_OTN_* types).
+	 */
+	DMU_OT_NUMTYPES,
+
+	/*
+	 * Names for valid types declared with DMU_OT().
+	 */
+	DMU_OTN_UINT8_DATA = DMU_OT(DMU_BSWAP_UINT8, B_FALSE),
+	DMU_OTN_UINT8_METADATA = DMU_OT(DMU_BSWAP_UINT8, B_TRUE),
+	DMU_OTN_UINT16_DATA = DMU_OT(DMU_BSWAP_UINT16, B_FALSE),
+	DMU_OTN_UINT16_METADATA = DMU_OT(DMU_BSWAP_UINT16, B_TRUE),
+	DMU_OTN_UINT32_DATA = DMU_OT(DMU_BSWAP_UINT32, B_FALSE),
+	DMU_OTN_UINT32_METADATA = DMU_OT(DMU_BSWAP_UINT32, B_TRUE),
+	DMU_OTN_UINT64_DATA = DMU_OT(DMU_BSWAP_UINT64, B_FALSE),
+	DMU_OTN_UINT64_METADATA = DMU_OT(DMU_BSWAP_UINT64, B_TRUE),
+	DMU_OTN_ZAP_DATA = DMU_OT(DMU_BSWAP_ZAP, B_FALSE),
+	DMU_OTN_ZAP_METADATA = DMU_OT(DMU_BSWAP_ZAP, B_TRUE),
+} dmu_object_type_t;
+
+typedef enum txg_how {
+	TXG_WAIT = 1,
+	TXG_NOWAIT,
+	TXG_WAITED,
+} txg_how_t;
+
+void byteswap_uint64_array(void *buf, size_t size);
+void byteswap_uint32_array(void *buf, size_t size);
+void byteswap_uint16_array(void *buf, size_t size);
+void byteswap_uint8_array(void *buf, size_t size);
+void zap_byteswap(void *buf, size_t size);
+void zfs_oldacl_byteswap(void *buf, size_t size);
+void zfs_acl_byteswap(void *buf, size_t size);
+void zfs_znode_byteswap(void *buf, size_t size);
+
+#define	DS_FIND_SNAPSHOTS	(1<<0)
+#define	DS_FIND_CHILDREN	(1<<1)
+#define	DS_FIND_SERIALIZE	(1<<2)
+
+/*
+ * The maximum number of bytes that can be accessed as part of one
+ * operation, including metadata.
+ */
+#define	DMU_MAX_ACCESS (64 * 1024 * 1024) /* 64MB */
+#define	DMU_MAX_DELETEBLKCNT (20480) /* ~5MB of indirect blocks */
+
+#define	DMU_USERUSED_OBJECT	(-1ULL)
+#define	DMU_GROUPUSED_OBJECT	(-2ULL)
+
+/*
+ * artificial blkids for bonus buffer and spill blocks
+ */
+#define	DMU_BONUS_BLKID		(-1ULL)
+#define	DMU_SPILL_BLKID		(-2ULL)
+/*
+ * Public routines to create, destroy, open, and close objsets.
+ */
+int dmu_objset_hold(const char *name, void *tag, objset_t **osp);
+int dmu_objset_own(const char *name, dmu_objset_type_t type,
+    boolean_t readonly, void *tag, objset_t **osp);
+void dmu_objset_rele(objset_t *os, void *tag);
+void dmu_objset_disown(objset_t *os, void *tag);
+int dmu_objset_open_ds(struct dsl_dataset *ds, objset_t **osp);
+
+void dmu_objset_evict_dbufs(objset_t *os);
+int dmu_objset_create(const char *name, dmu_objset_type_t type, uint64_t flags,
+    void (*func)(objset_t *os, void *arg, cred_t *cr, dmu_tx_t *tx), void *arg);
+int dmu_objset_clone(const char *name, const char *origin);
+int dsl_destroy_snapshots_nvl(struct nvlist *snaps, boolean_t defer,
+    struct nvlist *errlist);
+int dmu_objset_snapshot_one(const char *fsname, const char *snapname);
+int dmu_objset_snapshot_tmp(const char *, const char *, int);
+int dmu_objset_find(char *name, int func(const char *, void *), void *arg,
+    int flags);
+void dmu_objset_byteswap(void *buf, size_t size);
+int dsl_dataset_rename_snapshot(const char *fsname,
+    const char *oldsnapname, const char *newsnapname, boolean_t recursive);
+
+typedef struct dmu_buf {
+	uint64_t db_object;		/* object that this buffer is part of */
+	uint64_t db_offset;		/* byte offset in this object */
+	uint64_t db_size;		/* size of buffer in bytes */
+	void *db_data;			/* data in buffer */
+} dmu_buf_t;
+
+/*
+ * The names of zap entries in the DIRECTORY_OBJECT of the MOS.
+ */
+#define	DMU_POOL_DIRECTORY_OBJECT	1
+#define	DMU_POOL_CONFIG			"config"
+#define	DMU_POOL_FEATURES_FOR_WRITE	"features_for_write"
+#define	DMU_POOL_FEATURES_FOR_READ	"features_for_read"
+#define	DMU_POOL_FEATURE_DESCRIPTIONS	"feature_descriptions"
+#define	DMU_POOL_FEATURE_ENABLED_TXG	"feature_enabled_txg"
+#define	DMU_POOL_ROOT_DATASET		"root_dataset"
+#define	DMU_POOL_SYNC_BPOBJ		"sync_bplist"
+#define	DMU_POOL_ERRLOG_SCRUB		"errlog_scrub"
+#define	DMU_POOL_ERRLOG_LAST		"errlog_last"
+#define	DMU_POOL_SPARES			"spares"
+#define	DMU_POOL_DEFLATE		"deflate"
+#define	DMU_POOL_HISTORY		"history"
+#define	DMU_POOL_PROPS			"pool_props"
+#define	DMU_POOL_L2CACHE		"l2cache"
+#define	DMU_POOL_TMP_USERREFS		"tmp_userrefs"
+#define	DMU_POOL_DDT			"DDT-%s-%s-%s"
+#define	DMU_POOL_DDT_STATS		"DDT-statistics"
+#define	DMU_POOL_CREATION_VERSION	"creation_version"
+#define	DMU_POOL_SCAN			"scan"
+#define	DMU_POOL_FREE_BPOBJ		"free_bpobj"
+#define	DMU_POOL_BPTREE_OBJ		"bptree_obj"
+#define	DMU_POOL_EMPTY_BPOBJ		"empty_bpobj"
+
+/*
+ * Allocate an object from this objset.  The range of object numbers
+ * available is (0, DN_MAX_OBJECT).  Object 0 is the meta-dnode.
+ *
+ * The transaction must be assigned to a txg.  The newly allocated
+ * object will be "held" in the transaction (ie. you can modify the
+ * newly allocated object in this transaction).
+ *
+ * dmu_object_alloc() chooses an object and returns it in *objectp.
+ *
+ * dmu_object_claim() allocates a specific object number.  If that
+ * number is already allocated, it fails and returns EEXIST.
+ *
+ * Return 0 on success, or ENOSPC or EEXIST as specified above.
+ */
+uint64_t dmu_object_alloc(objset_t *os, dmu_object_type_t ot,
+    int blocksize, dmu_object_type_t bonus_type, int bonus_len, dmu_tx_t *tx);
+int dmu_object_claim(objset_t *os, uint64_t object, dmu_object_type_t ot,
+    int blocksize, dmu_object_type_t bonus_type, int bonus_len, dmu_tx_t *tx);
+int dmu_object_reclaim(objset_t *os, uint64_t object, dmu_object_type_t ot,
+    int blocksize, dmu_object_type_t bonustype, int bonuslen, dmu_tx_t *txp);
+
+/*
+ * Free an object from this objset.
+ *
+ * The object's data will be freed as well (ie. you don't need to call
+ * dmu_free(object, 0, -1, tx)).
+ *
+ * The object need not be held in the transaction.
+ *
+ * If there are any holds on this object's buffers (via dmu_buf_hold()),
+ * or tx holds on the object (via dmu_tx_hold_object()), you can not
+ * free it; it fails and returns EBUSY.
+ *
+ * If the object is not allocated, it fails and returns ENOENT.
+ *
+ * Return 0 on success, or EBUSY or ENOENT as specified above.
+ */
+int dmu_object_free(objset_t *os, uint64_t object, dmu_tx_t *tx);
+
+/*
+ * Find the next allocated or free object.
+ *
+ * The objectp parameter is in-out.  It will be updated to be the next
+ * object which is allocated.  Ignore objects which have not been
+ * modified since txg.
+ *
+ * XXX Can only be called on a objset with no dirty data.
+ *
+ * Returns 0 on success, or ENOENT if there are no more objects.
+ */
+int dmu_object_next(objset_t *os, uint64_t *objectp,
+    boolean_t hole, uint64_t txg);
+
+/*
+ * Set the data blocksize for an object.
+ *
+ * The object cannot have any blocks allcated beyond the first.  If
+ * the first block is allocated already, the new size must be greater
+ * than the current block size.  If these conditions are not met,
+ * ENOTSUP will be returned.
+ *
+ * Returns 0 on success, or EBUSY if there are any holds on the object
+ * contents, or ENOTSUP as described above.
+ */
+int dmu_object_set_blocksize(objset_t *os, uint64_t object, uint64_t size,
+    int ibs, dmu_tx_t *tx);
+
+/*
+ * Set the checksum property on a dnode.  The new checksum algorithm will
+ * apply to all newly written blocks; existing blocks will not be affected.
+ */
+void dmu_object_set_checksum(objset_t *os, uint64_t object, uint8_t checksum,
+    dmu_tx_t *tx);
+
+/*
+ * Set the compress property on a dnode.  The new compression algorithm will
+ * apply to all newly written blocks; existing blocks will not be affected.
+ */
+void dmu_object_set_compress(objset_t *os, uint64_t object, uint8_t compress,
+    dmu_tx_t *tx);
+
+void
+dmu_write_embedded(objset_t *os, uint64_t object, uint64_t offset,
+    void *data, uint8_t etype, uint8_t comp, int uncompressed_size,
+    int compressed_size, int byteorder, dmu_tx_t *tx);
+
+/*
+ * Decide how to write a block: checksum, compression, number of copies, etc.
+ */
+#define	WP_NOFILL	0x1
+#define	WP_DMU_SYNC	0x2
+#define	WP_SPILL	0x4
+
+void dmu_write_policy(objset_t *os, struct dnode *dn, int level, int wp,
+    struct zio_prop *zp);
+/*
+ * The bonus data is accessed more or less like a regular buffer.
+ * You must dmu_bonus_hold() to get the buffer, which will give you a
+ * dmu_buf_t with db_offset==-1ULL, and db_size = the size of the bonus
+ * data.  As with any normal buffer, you must call dmu_buf_read() to
+ * read db_data, dmu_buf_will_dirty() before modifying it, and the
+ * object must be held in an assigned transaction before calling
+ * dmu_buf_will_dirty.  You may use dmu_buf_set_user() on the bonus
+ * buffer as well.  You must release what you hold with dmu_buf_rele().
+ *
+ * Returns ENOENT, EIO, or 0.
+ */
+int dmu_bonus_hold(objset_t *os, uint64_t object, void *tag, dmu_buf_t **);
+int dmu_bonus_max(void);
+int dmu_set_bonus(dmu_buf_t *, int, dmu_tx_t *);
+int dmu_set_bonustype(dmu_buf_t *, dmu_object_type_t, dmu_tx_t *);
+dmu_object_type_t dmu_get_bonustype(dmu_buf_t *);
+int dmu_rm_spill(objset_t *, uint64_t, dmu_tx_t *);
+
+/*
+ * Special spill buffer support used by "SA" framework
+ */
+
+int dmu_spill_hold_by_bonus(dmu_buf_t *bonus, void *tag, dmu_buf_t **dbp);
+int dmu_spill_hold_by_dnode(struct dnode *dn, uint32_t flags,
+    void *tag, dmu_buf_t **dbp);
+int dmu_spill_hold_existing(dmu_buf_t *bonus, void *tag, dmu_buf_t **dbp);
+
+/*
+ * Obtain the DMU buffer from the specified object which contains the
+ * specified offset.  dmu_buf_hold() puts a "hold" on the buffer, so
+ * that it will remain in memory.  You must release the hold with
+ * dmu_buf_rele().  You must not access the dmu_buf_t after releasing
+ * what you hold.  You must have a hold on any dmu_buf_t* you pass to the DMU.
+ *
+ * You must call dmu_buf_read, dmu_buf_will_dirty, or dmu_buf_will_fill
+ * on the returned buffer before reading or writing the buffer's
+ * db_data.  The comments for those routines describe what particular
+ * operations are valid after calling them.
+ *
+ * The object number must be a valid, allocated object number.
+ */
+int dmu_buf_hold(objset_t *os, uint64_t object, uint64_t offset,
+    void *tag, dmu_buf_t **, int flags);
+
+/*
+ * Add a reference to a dmu buffer that has already been held via
+ * dmu_buf_hold() in the current context.
+ */
+void dmu_buf_add_ref(dmu_buf_t *db, void* tag);
+
+/*
+ * Attempt to add a reference to a dmu buffer that is in an unknown state,
+ * using a pointer that may have been invalidated by eviction processing.
+ * The request will succeed if the passed in dbuf still represents the
+ * same os/object/blkid, is ineligible for eviction, and has at least
+ * one hold by a user other than the syncer.
+ */
+boolean_t dmu_buf_try_add_ref(dmu_buf_t *, objset_t *os, uint64_t object,
+    uint64_t blkid, void *tag);
+
+void dmu_buf_rele(dmu_buf_t *db, void *tag);
+uint64_t dmu_buf_refcount(dmu_buf_t *db);
+
+/*
+ * dmu_buf_hold_array holds the DMU buffers which contain all bytes in a
+ * range of an object.  A pointer to an array of dmu_buf_t*'s is
+ * returned (in *dbpp).
+ *
+ * dmu_buf_rele_array releases the hold on an array of dmu_buf_t*'s, and
+ * frees the array.  The hold on the array of buffers MUST be released
+ * with dmu_buf_rele_array.  You can NOT release the hold on each buffer
+ * individually with dmu_buf_rele.
+ */
+int dmu_buf_hold_array_by_bonus(dmu_buf_t *db, uint64_t offset,
+    uint64_t length, int read, void *tag, int *numbufsp, dmu_buf_t ***dbpp);
+void dmu_buf_rele_array(dmu_buf_t **, int numbufs, void *tag);
+
+typedef void dmu_buf_evict_func_t(void *user_ptr);
+
+/*
+ * A DMU buffer user object may be associated with a dbuf for the
+ * duration of its lifetime.  This allows the user of a dbuf (client)
+ * to attach private data to a dbuf (e.g. in-core only data such as a
+ * dnode_children_t, zap_t, or zap_leaf_t) and be optionally notified
+ * when that dbuf has been evicted.  Clients typically respond to the
+ * eviction notification by freeing their private data, thus ensuring
+ * the same lifetime for both dbuf and private data.
+ *
+ * The mapping from a dmu_buf_user_t to any client private data is the
+ * client's responsibility.  All current consumers of the API with private
+ * data embed a dmu_buf_user_t as the first member of the structure for
+ * their private data.  This allows conversions between the two types
+ * with a simple cast.  Since the DMU buf user API never needs access
+ * to the private data, other strategies can be employed if necessary
+ * or convenient for the client (e.g. using container_of() to do the
+ * conversion for private data that cannot have the dmu_buf_user_t as
+ * its first member).
+ *
+ * Eviction callbacks are executed without the dbuf mutex held or any
+ * other type of mechanism to guarantee that the dbuf is still available.
+ * For this reason, users must assume the dbuf has already been freed
+ * and not reference the dbuf from the callback context.
+ *
+ * Users requesting "immediate eviction" are notified as soon as the dbuf
+ * is only referenced by dirty records (dirties == holds).  Otherwise the
+ * notification occurs after eviction processing for the dbuf begins.
+ */
+typedef struct dmu_buf_user {
+	/*
+	 * Asynchronous user eviction callback state.
+	 */
+	taskq_ent_t	dbu_tqent;
+
+	/* This instance's eviction function pointer. */
+	dmu_buf_evict_func_t *dbu_evict_func;
+#ifdef ZFS_DEBUG
+	/*
+	 * Pointer to user's dbuf pointer.  NULL for clients that do
+	 * not associate a dbuf with their user data.
+	 *
+	 * The dbuf pointer is cleared upon eviction so as to catch
+	 * use-after-evict bugs in clients.
+	 */
+	dmu_buf_t **dbu_clear_on_evict_dbufp;
+#endif
+} dmu_buf_user_t;
+
+/*
+ * Initialize the given dmu_buf_user_t instance with the eviction function
+ * evict_func, to be called when the user is evicted.
+ *
+ * NOTE: This function should only be called once on a given dmu_buf_user_t.
+ *       To allow enforcement of this, dbu must already be zeroed on entry.
+ */
+#ifdef __lint
+/* Very ugly, but it beats issuing suppression directives in many Makefiles. */
+extern void
+dmu_buf_init_user(dmu_buf_user_t *dbu, dmu_buf_evict_func_t *evict_func,
+    dmu_buf_t **clear_on_evict_dbufp);
+#else /* __lint */
+static inline void
+dmu_buf_init_user(dmu_buf_user_t *dbu, dmu_buf_evict_func_t *evict_func,
+    dmu_buf_t **clear_on_evict_dbufp)
+{
+	ASSERT(dbu->dbu_evict_func == NULL);
+	ASSERT(evict_func != NULL);
+	dbu->dbu_evict_func = evict_func;
+	taskq_init_ent(&dbu->dbu_tqent);
+#ifdef ZFS_DEBUG
+	dbu->dbu_clear_on_evict_dbufp = clear_on_evict_dbufp;
+#endif
+}
+#endif /* __lint */
+
+/*
+ * Attach user data to a dbuf and mark it for normal (when the dbuf's
+ * data is cleared or its reference count goes to zero) eviction processing.
+ *
+ * Returns NULL on success, or the existing user if another user currently
+ * owns the buffer.
+ */
+void *dmu_buf_set_user(dmu_buf_t *db, dmu_buf_user_t *user);
+
+/*
+ * Attach user data to a dbuf and mark it for immediate (its dirty and
+ * reference counts are equal) eviction processing.
+ *
+ * Returns NULL on success, or the existing user if another user currently
+ * owns the buffer.
+ */
+void *dmu_buf_set_user_ie(dmu_buf_t *db, dmu_buf_user_t *user);
+
+/*
+ * Replace the current user of a dbuf.
+ *
+ * If given the current user of a dbuf, replaces the dbuf's user with
+ * "new_user" and returns the user data pointer that was replaced.
+ * Otherwise returns the current, and unmodified, dbuf user pointer.
+ */
+void *dmu_buf_replace_user(dmu_buf_t *db,
+    dmu_buf_user_t *old_user, dmu_buf_user_t *new_user);
+
+/*
+ * Remove the specified user data for a DMU buffer.
+ *
+ * Returns the user that was removed on success, or the current user if
+ * another user currently owns the buffer.
+ */
+void *dmu_buf_remove_user(dmu_buf_t *db, dmu_buf_user_t *user);
+
+/*
+ * Returns the user data (dmu_buf_user_t *) associated with this dbuf.
+ */
+void *dmu_buf_get_user(dmu_buf_t *db);
+
+/* Block until any in-progress dmu buf user evictions complete. */
+void dmu_buf_user_evict_wait(void);
+
+/*
+ * Returns the blkptr associated with this dbuf, or NULL if not set.
+ */
+struct blkptr *dmu_buf_get_blkptr(dmu_buf_t *db);
+
+/*
+ * Indicate that you are going to modify the buffer's data (db_data).
+ *
+ * The transaction (tx) must be assigned to a txg (ie. you've called
+ * dmu_tx_assign()).  The buffer's object must be held in the tx
+ * (ie. you've called dmu_tx_hold_object(tx, db->db_object)).
+ */
+void dmu_buf_will_dirty(dmu_buf_t *db, dmu_tx_t *tx);
+
+/*
+ * Tells if the given dbuf is freeable.
+ */
+boolean_t dmu_buf_freeable(dmu_buf_t *);
+
+/*
+ * You must create a transaction, then hold the objects which you will
+ * (or might) modify as part of this transaction.  Then you must assign
+ * the transaction to a transaction group.  Once the transaction has
+ * been assigned, you can modify buffers which belong to held objects as
+ * part of this transaction.  You can't modify buffers before the
+ * transaction has been assigned; you can't modify buffers which don't
+ * belong to objects which this transaction holds; you can't hold
+ * objects once the transaction has been assigned.  You may hold an
+ * object which you are going to free (with dmu_object_free()), but you
+ * don't have to.
+ *
+ * You can abort the transaction before it has been assigned.
+ *
+ * Note that you may hold buffers (with dmu_buf_hold) at any time,
+ * regardless of transaction state.
+ */
+
+#define	DMU_NEW_OBJECT	(-1ULL)
+#define	DMU_OBJECT_END	(-1ULL)
+
+dmu_tx_t *dmu_tx_create(objset_t *os);
+void dmu_tx_hold_write(dmu_tx_t *tx, uint64_t object, uint64_t off, int len);
+void dmu_tx_hold_free(dmu_tx_t *tx, uint64_t object, uint64_t off,
+    uint64_t len);
+void dmu_tx_hold_zap(dmu_tx_t *tx, uint64_t object, int add, const char *name);
+void dmu_tx_hold_bonus(dmu_tx_t *tx, uint64_t object);
+void dmu_tx_hold_spill(dmu_tx_t *tx, uint64_t object);
+void dmu_tx_hold_sa(dmu_tx_t *tx, struct sa_handle *hdl, boolean_t may_grow);
+void dmu_tx_hold_sa_create(dmu_tx_t *tx, int total_size);
+void dmu_tx_abort(dmu_tx_t *tx);
+int dmu_tx_assign(dmu_tx_t *tx, enum txg_how txg_how);
+void dmu_tx_wait(dmu_tx_t *tx);
+void dmu_tx_commit(dmu_tx_t *tx);
+
+/*
+ * To register a commit callback, dmu_tx_callback_register() must be called.
+ *
+ * dcb_data is a pointer to caller private data that is passed on as a
+ * callback parameter. The caller is responsible for properly allocating and
+ * freeing it.
+ *
+ * When registering a callback, the transaction must be already created, but
+ * it cannot be committed or aborted. It can be assigned to a txg or not.
+ *
+ * The callback will be called after the transaction has been safely written
+ * to stable storage and will also be called if the dmu_tx is aborted.
+ * If there is any error which prevents the transaction from being committed to
+ * disk, the callback will be called with a value of error != 0.
+ */
+typedef void dmu_tx_callback_func_t(void *dcb_data, int error);
+
+void dmu_tx_callback_register(dmu_tx_t *tx, dmu_tx_callback_func_t *dcb_func,
+    void *dcb_data);
+
+/*
+ * Free up the data blocks for a defined range of a file.  If size is
+ * -1, the range from offset to end-of-file is freed.
+ */
+int dmu_free_range(objset_t *os, uint64_t object, uint64_t offset,
+	uint64_t size, dmu_tx_t *tx);
+int dmu_free_long_range(objset_t *os, uint64_t object, uint64_t offset,
+	uint64_t size);
+int dmu_free_long_object(objset_t *os, uint64_t object);
+
+/*
+ * Convenience functions.
+ *
+ * Canfail routines will return 0 on success, or an errno if there is a
+ * nonrecoverable I/O error.
+ */
+#define	DMU_READ_PREFETCH	0 /* prefetch */
+#define	DMU_READ_NO_PREFETCH	1 /* don't prefetch */
+int dmu_read(objset_t *os, uint64_t object, uint64_t offset, uint64_t size,
+	void *buf, uint32_t flags);
+void dmu_write(objset_t *os, uint64_t object, uint64_t offset, uint64_t size,
+	const void *buf, dmu_tx_t *tx);
+void dmu_prealloc(objset_t *os, uint64_t object, uint64_t offset, uint64_t size,
+	dmu_tx_t *tx);
+#ifdef _KERNEL
+#include <linux/blkdev_compat.h>
+int dmu_read_bio(objset_t *os, uint64_t object, struct bio *bio);
+int dmu_write_bio(objset_t *os, uint64_t object, struct bio *bio,
+	dmu_tx_t *tx);
+int dmu_read_uio(objset_t *os, uint64_t object, struct uio *uio, uint64_t size);
+int dmu_read_uio_dbuf(dmu_buf_t *zdb, struct uio *uio, uint64_t size);
+int dmu_write_uio(objset_t *os, uint64_t object, struct uio *uio, uint64_t size,
+	dmu_tx_t *tx);
+int dmu_write_uio_dbuf(dmu_buf_t *zdb, struct uio *uio, uint64_t size,
+	dmu_tx_t *tx);
+#endif
+struct arc_buf *dmu_request_arcbuf(dmu_buf_t *handle, int size);
+void dmu_return_arcbuf(struct arc_buf *buf);
+void dmu_assign_arcbuf(dmu_buf_t *handle, uint64_t offset, struct arc_buf *buf,
+    dmu_tx_t *tx);
+int dmu_xuio_init(struct xuio *uio, int niov);
+void dmu_xuio_fini(struct xuio *uio);
+int dmu_xuio_add(struct xuio *uio, struct arc_buf *abuf, offset_t off,
+    size_t n);
+int dmu_xuio_cnt(struct xuio *uio);
+struct arc_buf *dmu_xuio_arcbuf(struct xuio *uio, int i);
+void dmu_xuio_clear(struct xuio *uio, int i);
+void xuio_stat_wbuf_copied(void);
+void xuio_stat_wbuf_nocopy(void);
+
+extern int zfs_prefetch_disable;
+extern int zfs_max_recordsize;
+
+/*
+ * Asynchronously try to read in the data.
+ */
+void dmu_prefetch(objset_t *os, uint64_t object, uint64_t offset,
+    uint64_t len);
+
+typedef struct dmu_object_info {
+	/* All sizes are in bytes unless otherwise indicated. */
+	uint32_t doi_data_block_size;
+	uint32_t doi_metadata_block_size;
+	dmu_object_type_t doi_type;
+	dmu_object_type_t doi_bonus_type;
+	uint64_t doi_bonus_size;
+	uint8_t doi_indirection;		/* 2 = dnode->indirect->data */
+	uint8_t doi_checksum;
+	uint8_t doi_compress;
+	uint8_t doi_nblkptr;
+	uint8_t doi_pad[4];
+	uint64_t doi_physical_blocks_512;	/* data + metadata, 512b blks */
+	uint64_t doi_max_offset;
+	uint64_t doi_fill_count;		/* number of non-empty blocks */
+} dmu_object_info_t;
+
+typedef void (*const arc_byteswap_func_t)(void *buf, size_t size);
+
+typedef struct dmu_object_type_info {
+	dmu_object_byteswap_t	ot_byteswap;
+	boolean_t		ot_metadata;
+	char			*ot_name;
+} dmu_object_type_info_t;
+
+typedef const struct dmu_object_byteswap_info {
+	arc_byteswap_func_t	 ob_func;
+	char			*ob_name;
+} dmu_object_byteswap_info_t;
+
+extern const dmu_object_type_info_t dmu_ot[DMU_OT_NUMTYPES];
+extern const dmu_object_byteswap_info_t dmu_ot_byteswap[DMU_BSWAP_NUMFUNCS];
+
+/*
+ * Get information on a DMU object.
+ *
+ * Return 0 on success or ENOENT if object is not allocated.
+ *
+ * If doi is NULL, just indicates whether the object exists.
+ */
+int dmu_object_info(objset_t *os, uint64_t object, dmu_object_info_t *doi);
+void __dmu_object_info_from_dnode(struct dnode *dn, dmu_object_info_t *doi);
+/* Like dmu_object_info, but faster if you have a held dnode in hand. */
+void dmu_object_info_from_dnode(struct dnode *dn, dmu_object_info_t *doi);
+/* Like dmu_object_info, but faster if you have a held dbuf in hand. */
+void dmu_object_info_from_db(dmu_buf_t *db, dmu_object_info_t *doi);
+/*
+ * Like dmu_object_info_from_db, but faster still when you only care about
+ * the size.  This is specifically optimized for zfs_getattr().
+ */
+void dmu_object_size_from_db(dmu_buf_t *db, uint32_t *blksize,
+    u_longlong_t *nblk512);
+
+typedef struct dmu_objset_stats {
+	uint64_t dds_num_clones; /* number of clones of this */
+	uint64_t dds_creation_txg;
+	uint64_t dds_guid;
+	dmu_objset_type_t dds_type;
+	uint8_t dds_is_snapshot;
+	uint8_t dds_inconsistent;
+	char dds_origin[MAXNAMELEN];
+} dmu_objset_stats_t;
+
+/*
+ * Get stats on a dataset.
+ */
+void dmu_objset_fast_stat(objset_t *os, dmu_objset_stats_t *stat);
+
+/*
+ * Add entries to the nvlist for all the objset's properties.  See
+ * zfs_prop_table[] and zfs(1m) for details on the properties.
+ */
+void dmu_objset_stats(objset_t *os, struct nvlist *nv);
+
+/*
+ * Get the space usage statistics for statvfs().
+ *
+ * refdbytes is the amount of space "referenced" by this objset.
+ * availbytes is the amount of space available to this objset, taking
+ * into account quotas & reservations, assuming that no other objsets
+ * use the space first.  These values correspond to the 'referenced' and
+ * 'available' properties, described in the zfs(1m) manpage.
+ *
+ * usedobjs and availobjs are the number of objects currently allocated,
+ * and available.
+ */
+void dmu_objset_space(objset_t *os, uint64_t *refdbytesp, uint64_t *availbytesp,
+    uint64_t *usedobjsp, uint64_t *availobjsp);
+
+/*
+ * The fsid_guid is a 56-bit ID that can change to avoid collisions.
+ * (Contrast with the ds_guid which is a 64-bit ID that will never
+ * change, so there is a small probability that it will collide.)
+ */
+uint64_t dmu_objset_fsid_guid(objset_t *os);
+
+/*
+ * Get the [cm]time for an objset's snapshot dir
+ */
+timestruc_t dmu_objset_snap_cmtime(objset_t *os);
+
+int dmu_objset_is_snapshot(objset_t *os);
+
+extern struct spa *dmu_objset_spa(objset_t *os);
+extern struct zilog *dmu_objset_zil(objset_t *os);
+extern struct dsl_pool *dmu_objset_pool(objset_t *os);
+extern struct dsl_dataset *dmu_objset_ds(objset_t *os);
+extern void dmu_objset_name(objset_t *os, char *buf);
+extern dmu_objset_type_t dmu_objset_type(objset_t *os);
+extern uint64_t dmu_objset_id(objset_t *os);
+extern zfs_sync_type_t dmu_objset_syncprop(objset_t *os);
+extern zfs_logbias_op_t dmu_objset_logbias(objset_t *os);
+extern int dmu_snapshot_list_next(objset_t *os, int namelen, char *name,
+    uint64_t *id, uint64_t *offp, boolean_t *case_conflict);
+extern int dmu_snapshot_lookup(objset_t *os, const char *name, uint64_t *val);
+extern int dmu_snapshot_realname(objset_t *os, char *name, char *real,
+    int maxlen, boolean_t *conflict);
+extern int dmu_dir_list_next(objset_t *os, int namelen, char *name,
+    uint64_t *idp, uint64_t *offp);
+
+typedef int objset_used_cb_t(dmu_object_type_t bonustype,
+    void *bonus, uint64_t *userp, uint64_t *groupp);
+extern void dmu_objset_register_type(dmu_objset_type_t ost,
+    objset_used_cb_t *cb);
+extern void dmu_objset_set_user(objset_t *os, void *user_ptr);
+extern void *dmu_objset_get_user(objset_t *os);
+
+/*
+ * Return the txg number for the given assigned transaction.
+ */
+uint64_t dmu_tx_get_txg(dmu_tx_t *tx);
+
+/*
+ * Synchronous write.
+ * If a parent zio is provided this function initiates a write on the
+ * provided buffer as a child of the parent zio.
+ * In the absence of a parent zio, the write is completed synchronously.
+ * At write completion, blk is filled with the bp of the written block.
+ * Note that while the data covered by this function will be on stable
+ * storage when the write completes this new data does not become a
+ * permanent part of the file until the associated transaction commits.
+ */
+
+/*
+ * {zfs,zvol,ztest}_get_done() args
+ */
+typedef struct zgd {
+	struct zilog	*zgd_zilog;
+	struct blkptr	*zgd_bp;
+	dmu_buf_t	*zgd_db;
+	struct rl	*zgd_rl;
+	void		*zgd_private;
+} zgd_t;
+
+typedef void dmu_sync_cb_t(zgd_t *arg, int error);
+int dmu_sync(struct zio *zio, uint64_t txg, dmu_sync_cb_t *done, zgd_t *zgd);
+
+/*
+ * Find the next hole or data block in file starting at *off
+ * Return found offset in *off. Return ESRCH for end of file.
+ */
+int dmu_offset_next(objset_t *os, uint64_t object, boolean_t hole,
+    uint64_t *off);
+
+/*
+ * Initial setup and final teardown.
+ */
+extern void dmu_init(void);
+extern void dmu_fini(void);
+
+typedef void (*dmu_traverse_cb_t)(objset_t *os, void *arg, struct blkptr *bp,
+    uint64_t object, uint64_t offset, int len);
+void dmu_traverse_objset(objset_t *os, uint64_t txg_start,
+    dmu_traverse_cb_t cb, void *arg);
+
+int dmu_diff(const char *tosnap_name, const char *fromsnap_name,
+    struct vnode *vp, offset_t *offp);
+
+/* CRC64 table */
+#define	ZFS_CRC64_POLY	0xC96C5795D7870F42ULL	/* ECMA-182, reflected form */
+extern uint64_t zfs_crc64_table[256];
+
+extern int zfs_mdcomp_disable;
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* _SYS_DMU_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/include/sys/dmu_impl.h
@@ -0,0 +1,286 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * Copyright (c) 2012, Joyent, Inc. All rights reserved.
+ * Copyright (c) 2013 by Delphix. All rights reserved.
+ */
+
+#ifndef _SYS_DMU_IMPL_H
+#define	_SYS_DMU_IMPL_H
+
+#include <sys/txg_impl.h>
+#include <sys/zio.h>
+#include <sys/dnode.h>
+#include <sys/zfs_context.h>
+#include <sys/zfs_ioctl.h>
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+/*
+ * This is the locking strategy for the DMU.  Numbers in parenthesis are
+ * cases that use that lock order, referenced below:
+ *
+ * ARC is self-contained
+ * bplist is self-contained
+ * refcount is self-contained
+ * txg is self-contained (hopefully!)
+ * zst_lock
+ * zf_rwlock
+ *
+ * XXX try to improve evicting path?
+ *
+ * dp_config_rwlock > os_obj_lock > dn_struct_rwlock >
+ * 	dn_dbufs_mtx > hash_mutexes > db_mtx > dd_lock > leafs
+ *
+ * dp_config_rwlock
+ *    must be held before: everything
+ *    protects dd namespace changes
+ *    protects property changes globally
+ *    held from:
+ *    	dsl_dir_open/r:
+ *    	dsl_dir_create_sync/w:
+ *    	dsl_dir_sync_destroy/w:
+ *    	dsl_dir_rename_sync/w:
+ *    	dsl_prop_changed_notify/r:
+ *
+ * os_obj_lock
+ *   must be held before:
+ *   	everything except dp_config_rwlock
+ *   protects os_obj_next
+ *   held from:
+ *   	dmu_object_alloc: dn_dbufs_mtx, db_mtx, hash_mutexes, dn_struct_rwlock
+ *
+ * dn_struct_rwlock
+ *   must be held before:
+ *   	everything except dp_config_rwlock and os_obj_lock
+ *   protects structure of dnode (eg. nlevels)
+ *   	db_blkptr can change when syncing out change to nlevels
+ *   	dn_maxblkid
+ *   	dn_nlevels
+ *   	dn_*blksz*
+ *   	phys nlevels, maxblkid, physical blkptr_t's (?)
+ *   held from:
+ *   	callers of dbuf_read_impl, dbuf_hold[_impl], dbuf_prefetch
+ *   	dmu_object_info_from_dnode: dn_dirty_mtx (dn_datablksz)
+ *   	dmu_tx_count_free:
+ *   	dbuf_read_impl: db_mtx, dmu_zfetch()
+ *   	dmu_zfetch: zf_rwlock/r, zst_lock, dbuf_prefetch()
+ *   	dbuf_new_size: db_mtx
+ *   	dbuf_dirty: db_mtx
+ *	dbuf_findbp: (callers, phys? - the real need)
+ *	dbuf_create: dn_dbufs_mtx, hash_mutexes, db_mtx (phys?)
+ *	dbuf_prefetch: dn_dirty_mtx, hash_mutexes, db_mtx, dn_dbufs_mtx
+ *	dbuf_hold_impl: hash_mutexes, db_mtx, dn_dbufs_mtx, dbuf_findbp()
+ *	dnode_sync/w (increase_indirection): db_mtx (phys)
+ *	dnode_set_blksz/w: dn_dbufs_mtx (dn_*blksz*)
+ *	dnode_new_blkid/w: (dn_maxblkid)
+ *	dnode_free_range/w: dn_dirty_mtx (dn_maxblkid)
+ *	dnode_next_offset: (phys)
+ *
+ * dn_dbufs_mtx
+ *    must be held before:
+ *    	db_mtx, hash_mutexes
+ *    protects:
+ *    	dn_dbufs
+ *    	dn_evicted
+ *    held from:
+ *    	dmu_evict_user: db_mtx (dn_dbufs)
+ *    	dbuf_free_range: db_mtx (dn_dbufs)
+ *    	dbuf_remove_ref: db_mtx, callees:
+ *    		dbuf_hash_remove: hash_mutexes, db_mtx
+ *    	dbuf_create: hash_mutexes, db_mtx (dn_dbufs)
+ *    	dnode_set_blksz: (dn_dbufs)
+ *
+ * hash_mutexes (global)
+ *   must be held before:
+ *   	db_mtx
+ *   protects dbuf_hash_table (global) and db_hash_next
+ *   held from:
+ *   	dbuf_find: db_mtx
+ *   	dbuf_hash_insert: db_mtx
+ *   	dbuf_hash_remove: db_mtx
+ *
+ * db_mtx (meta-leaf)
+ *   must be held before:
+ *   	dn_mtx, dn_dirty_mtx, dd_lock (leaf mutexes)
+ *   protects:
+ *   	db_state
+ * 	db_holds
+ * 	db_buf
+ * 	db_changed
+ * 	db_data_pending
+ * 	db_dirtied
+ * 	db_link
+ * 	db_dirty_node (??)
+ * 	db_dirtycnt
+ * 	db_d.*
+ * 	db.*
+ *   held from:
+ * 	dbuf_dirty: dn_mtx, dn_dirty_mtx
+ * 	dbuf_dirty->dsl_dir_willuse_space: dd_lock
+ * 	dbuf_dirty->dbuf_new_block->dsl_dataset_block_freeable: dd_lock
+ * 	dbuf_undirty: dn_dirty_mtx (db_d)
+ * 	dbuf_write_done: dn_dirty_mtx (db_state)
+ * 	dbuf_*
+ * 	dmu_buf_update_user: none (db_d)
+ * 	dmu_evict_user: none (db_d) (maybe can eliminate)
+ *   	dbuf_find: none (db_holds)
+ *   	dbuf_hash_insert: none (db_holds)
+ *   	dmu_buf_read_array_impl: none (db_state, db_changed)
+ *   	dmu_sync: none (db_dirty_node, db_d)
+ *   	dnode_reallocate: none (db)
+ *
+ * dn_mtx (leaf)
+ *   protects:
+ *   	dn_dirty_dbufs
+ *   	dn_ranges
+ *   	phys accounting
+ * 	dn_allocated_txg
+ * 	dn_free_txg
+ * 	dn_assigned_txg
+ * 	dd_assigned_tx
+ * 	dn_notxholds
+ * 	dn_dirtyctx
+ * 	dn_dirtyctx_firstset
+ * 	(dn_phys copy fields?)
+ * 	(dn_phys contents?)
+ *   held from:
+ *   	dnode_*
+ *   	dbuf_dirty: none
+ *   	dbuf_sync: none (phys accounting)
+ *   	dbuf_undirty: none (dn_ranges, dn_dirty_dbufs)
+ *   	dbuf_write_done: none (phys accounting)
+ *   	dmu_object_info_from_dnode: none (accounting)
+ *   	dmu_tx_commit: none
+ *   	dmu_tx_hold_object_impl: none
+ *   	dmu_tx_try_assign: dn_notxholds(cv)
+ *   	dmu_tx_unassign: none
+ *
+ * dd_lock
+ *    must be held before:
+ *      ds_lock
+ *      ancestors' dd_lock
+ *    protects:
+ *    	dd_prop_cbs
+ *    	dd_sync_*
+ *    	dd_used_bytes
+ *    	dd_tempreserved
+ *    	dd_space_towrite
+ *    	dd_myname
+ *    	dd_phys accounting?
+ *    held from:
+ *    	dsl_dir_*
+ *    	dsl_prop_changed_notify: none (dd_prop_cbs)
+ *    	dsl_prop_register: none (dd_prop_cbs)
+ *    	dsl_prop_unregister: none (dd_prop_cbs)
+ *    	dsl_dataset_block_freeable: none (dd_sync_*)
+ *
+ * os_lock (leaf)
+ *   protects:
+ *   	os_dirty_dnodes
+ *   	os_free_dnodes
+ *   	os_dnodes
+ *   	os_downgraded_dbufs
+ *   	dn_dirtyblksz
+ *   	dn_dirty_link
+ *   held from:
+ *   	dnode_create: none (os_dnodes)
+ *   	dnode_destroy: none (os_dnodes)
+ *   	dnode_setdirty: none (dn_dirtyblksz, os_*_dnodes)
+ *   	dnode_free: none (dn_dirtyblksz, os_*_dnodes)
+ *
+ * ds_lock
+ *    protects:
+ *    	ds_objset
+ *    	ds_open_refcount
+ *    	ds_snapname
+ *    	ds_phys accounting
+ *	ds_phys userrefs zapobj
+ *	ds_reserved
+ *    held from:
+ *    	dsl_dataset_*
+ *
+ * dr_mtx (leaf)
+ *    protects:
+ *	dr_children
+ *    held from:
+ *	dbuf_dirty
+ *	dbuf_undirty
+ *	dbuf_sync_indirect
+ *	dnode_new_blkid
+ */
+
+struct objset;
+struct dmu_pool;
+
+typedef struct dmu_xuio {
+	int next;
+	int cnt;
+	struct arc_buf **bufs;
+	iovec_t *iovp;
+} dmu_xuio_t;
+
+/*
+ * The list of data whose inclusion in a send stream can be pending from
+ * one call to backup_cb to another.  Multiple calls to dump_free() and
+ * dump_freeobjects() can be aggregated into a single DRR_FREE or
+ * DRR_FREEOBJECTS replay record.
+ */
+typedef enum {
+	PENDING_NONE,
+	PENDING_FREE,
+	PENDING_FREEOBJECTS
+} dmu_pendop_t;
+
+typedef struct dmu_sendarg {
+	list_node_t dsa_link;
+	dmu_replay_record_t *dsa_drr;
+	vnode_t *dsa_vp;
+	int dsa_outfd;
+	proc_t *dsa_proc;
+	offset_t *dsa_off;
+	objset_t *dsa_os;
+	zio_cksum_t dsa_zc;
+	uint64_t dsa_toguid;
+	int dsa_err;
+	dmu_pendop_t dsa_pending_op;
+	boolean_t dsa_incremental;
+	uint64_t dsa_featureflags;
+	uint64_t dsa_last_data_object;
+	uint64_t dsa_last_data_offset;
+} dmu_sendarg_t;
+
+void dmu_object_zapify(objset_t *, uint64_t, dmu_object_type_t, dmu_tx_t *);
+void dmu_object_free_zapified(objset_t *, uint64_t, dmu_tx_t *);
+int dmu_buf_hold_noread(objset_t *, uint64_t, uint64_t,
+    void *, dmu_buf_t **);
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* _SYS_DMU_IMPL_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/include/sys/dmu_objset.h
@@ -0,0 +1,186 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013 by Saso Kiselkov. All rights reserved.
+ * Copyright (c) 2012, 2014 by Delphix. All rights reserved.
+ * Copyright (c) 2014 Spectra Logic Corporation, All rights reserved.
+ */
+
+/* Portions Copyright 2010 Robert Milkowski */
+
+#ifndef	_SYS_DMU_OBJSET_H
+#define	_SYS_DMU_OBJSET_H
+
+#include <sys/spa.h>
+#include <sys/arc.h>
+#include <sys/txg.h>
+#include <sys/zfs_context.h>
+#include <sys/dnode.h>
+#include <sys/zio.h>
+#include <sys/zil.h>
+#include <sys/sa.h>
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+extern krwlock_t os_lock;
+
+struct dsl_pool;
+struct dsl_dataset;
+struct dmu_tx;
+
+#define	OBJSET_PHYS_SIZE 2048
+#define	OBJSET_OLD_PHYS_SIZE 1024
+
+#define	OBJSET_BUF_HAS_USERUSED(buf) \
+	(arc_buf_size(buf) > OBJSET_OLD_PHYS_SIZE)
+
+#define	OBJSET_FLAG_USERACCOUNTING_COMPLETE	(1ULL<<0)
+
+typedef struct objset_phys {
+	dnode_phys_t os_meta_dnode;
+	zil_header_t os_zil_header;
+	uint64_t os_type;
+	uint64_t os_flags;
+	char os_pad[OBJSET_PHYS_SIZE - sizeof (dnode_phys_t)*3 -
+	    sizeof (zil_header_t) - sizeof (uint64_t)*2];
+	dnode_phys_t os_userused_dnode;
+	dnode_phys_t os_groupused_dnode;
+} objset_phys_t;
+
+struct objset {
+	/* Immutable: */
+	struct dsl_dataset *os_dsl_dataset;
+	spa_t *os_spa;
+	arc_buf_t *os_phys_buf;
+	objset_phys_t *os_phys;
+	/*
+	 * The following "special" dnodes have no parent, are exempt
+	 * from dnode_move(), and are not recorded in os_dnodes, but they
+	 * root their descendents in this objset using handles anyway, so
+	 * that all access to dnodes from dbufs consistently uses handles.
+	 */
+	dnode_handle_t os_meta_dnode;
+	dnode_handle_t os_userused_dnode;
+	dnode_handle_t os_groupused_dnode;
+	zilog_t *os_zil;
+
+	list_node_t os_evicting_node;
+
+	/* can change, under dsl_dir's locks: */
+	enum zio_checksum os_checksum;
+	enum zio_compress os_compress;
+	uint8_t os_copies;
+	enum zio_checksum os_dedup_checksum;
+	boolean_t os_dedup_verify;
+	zfs_logbias_op_t os_logbias;
+	zfs_cache_type_t os_primary_cache;
+	zfs_cache_type_t os_secondary_cache;
+	zfs_sync_type_t os_sync;
+	zfs_redundant_metadata_type_t os_redundant_metadata;
+	int os_recordsize;
+
+	/* no lock needed: */
+	struct dmu_tx *os_synctx; /* XXX sketchy */
+	blkptr_t *os_rootbp;
+	zil_header_t os_zil_header;
+	list_t os_synced_dnodes;
+	uint64_t os_flags;
+
+	/* Protected by os_obj_lock */
+	kmutex_t os_obj_lock;
+	uint64_t os_obj_next;
+
+	/* Protected by os_lock */
+	kmutex_t os_lock;
+	list_t os_dirty_dnodes[TXG_SIZE];
+	list_t os_free_dnodes[TXG_SIZE];
+	list_t os_dnodes;
+	list_t os_downgraded_dbufs;
+
+	/* stuff we store for the user */
+	kmutex_t os_user_ptr_lock;
+	void *os_user_ptr;
+	sa_os_t *os_sa;
+};
+
+#define	DMU_META_OBJSET		0
+#define	DMU_META_DNODE_OBJECT	0
+#define	DMU_OBJECT_IS_SPECIAL(obj) ((int64_t)(obj) <= 0)
+#define	DMU_META_DNODE(os)	((os)->os_meta_dnode.dnh_dnode)
+#define	DMU_USERUSED_DNODE(os)	((os)->os_userused_dnode.dnh_dnode)
+#define	DMU_GROUPUSED_DNODE(os)	((os)->os_groupused_dnode.dnh_dnode)
+
+#define	DMU_OS_IS_L2CACHEABLE(os)				\
+	((os)->os_secondary_cache == ZFS_CACHE_ALL ||		\
+	(os)->os_secondary_cache == ZFS_CACHE_METADATA)
+
+#define	DMU_OS_IS_L2COMPRESSIBLE(os)	(zfs_mdcomp_disable == B_FALSE)
+
+/* called from zpl */
+int dmu_objset_hold(const char *name, void *tag, objset_t **osp);
+int dmu_objset_own(const char *name, dmu_objset_type_t type,
+    boolean_t readonly, void *tag, objset_t **osp);
+int dmu_objset_own_obj(struct dsl_pool *dp, uint64_t obj,
+    dmu_objset_type_t type, boolean_t readonly, void *tag, objset_t **osp);
+void dmu_objset_refresh_ownership(objset_t *os, void *tag);
+void dmu_objset_rele(objset_t *os, void *tag);
+void dmu_objset_disown(objset_t *os, void *tag);
+int dmu_objset_from_ds(struct dsl_dataset *ds, objset_t **osp);
+
+void dmu_objset_stats(objset_t *os, nvlist_t *nv);
+void dmu_objset_fast_stat(objset_t *os, dmu_objset_stats_t *stat);
+void dmu_objset_space(objset_t *os, uint64_t *refdbytesp, uint64_t *availbytesp,
+    uint64_t *usedobjsp, uint64_t *availobjsp);
+uint64_t dmu_objset_fsid_guid(objset_t *os);
+int dmu_objset_find_dp(struct dsl_pool *dp, uint64_t ddobj,
+    int func(struct dsl_pool *, struct dsl_dataset *, void *),
+    void *arg, int flags);
+void dmu_objset_evict_dbufs(objset_t *os);
+timestruc_t dmu_objset_snap_cmtime(objset_t *os);
+
+/* called from dsl */
+void dmu_objset_sync(objset_t *os, zio_t *zio, dmu_tx_t *tx);
+boolean_t dmu_objset_is_dirty(objset_t *os, uint64_t txg);
+objset_t *dmu_objset_create_impl(spa_t *spa, struct dsl_dataset *ds,
+    blkptr_t *bp, dmu_objset_type_t type, dmu_tx_t *tx);
+int dmu_objset_open_impl(spa_t *spa, struct dsl_dataset *ds, blkptr_t *bp,
+    objset_t **osp);
+void dmu_objset_evict(objset_t *os);
+void dmu_objset_do_userquota_updates(objset_t *os, dmu_tx_t *tx);
+void dmu_objset_userquota_get_ids(dnode_t *dn, boolean_t before, dmu_tx_t *tx);
+boolean_t dmu_objset_userused_enabled(objset_t *os);
+int dmu_objset_userspace_upgrade(objset_t *os);
+boolean_t dmu_objset_userspace_present(objset_t *os);
+int dmu_fsname(const char *snapname, char *buf);
+
+void dmu_objset_evict_done(objset_t *os);
+
+void dmu_objset_init(void);
+void dmu_objset_fini(void);
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif /* _SYS_DMU_OBJSET_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/include/sys/dmu_send.h
@@ -0,0 +1,73 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2014 by Delphix. All rights reserved.
+ * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
+ * Copyright (c) 2013, Joyent, Inc. All rights reserved.
+ */
+
+#ifndef _DMU_SEND_H
+#define	_DMU_SEND_H
+
+#include <sys/inttypes.h>
+#include <sys/spa.h>
+
+struct vnode;
+struct dsl_dataset;
+struct drr_begin;
+struct avl_tree;
+
+int dmu_send(const char *tosnap, const char *fromsnap,
+    boolean_t embedok, boolean_t large_block_ok,
+    int outfd, struct vnode *vp, offset_t *off);
+int dmu_send_estimate(struct dsl_dataset *ds, struct dsl_dataset *fromds,
+    uint64_t *sizep);
+int dmu_send_estimate_from_txg(struct dsl_dataset *ds, uint64_t fromtxg,
+    uint64_t *sizep);
+int dmu_send_obj(const char *pool, uint64_t tosnap, uint64_t fromsnap,
+    boolean_t embedok, boolean_t large_block_ok,
+    int outfd, struct vnode *vp, offset_t *off);
+
+typedef struct dmu_recv_cookie {
+	struct dsl_dataset *drc_ds;
+	struct drr_begin *drc_drrb;
+	const char *drc_tofs;
+	const char *drc_tosnap;
+	boolean_t drc_newfs;
+	boolean_t drc_byteswap;
+	boolean_t drc_force;
+	struct avl_tree *drc_guid_to_ds_map;
+	zio_cksum_t drc_cksum;
+	uint64_t drc_newsnapobj;
+	void *drc_owner;
+	cred_t *drc_cred;
+} dmu_recv_cookie_t;
+
+int dmu_recv_begin(char *tofs, char *tosnap, struct drr_begin *drrb,
+    boolean_t force, char *origin, dmu_recv_cookie_t *drc);
+int dmu_recv_stream(dmu_recv_cookie_t *drc, struct vnode *vp, offset_t *voffp,
+    int cleanup_fd, uint64_t *action_handlep);
+int dmu_recv_end(dmu_recv_cookie_t *drc, void *owner);
+boolean_t dmu_objset_is_receiving(objset_t *os);
+
+#endif /* _DMU_SEND_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/include/sys/dmu_traverse.h
@@ -0,0 +1,67 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2014 by Delphix. All rights reserved.
+ */
+
+#ifndef	_SYS_DMU_TRAVERSE_H
+#define	_SYS_DMU_TRAVERSE_H
+
+#include <sys/zfs_context.h>
+#include <sys/spa.h>
+#include <sys/zio.h>
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+struct dnode_phys;
+struct dsl_dataset;
+struct zilog;
+struct arc_buf;
+
+typedef int (blkptr_cb_t)(spa_t *spa, zilog_t *zilog, const blkptr_t *bp,
+    const zbookmark_phys_t *zb, const struct dnode_phys *dnp, void *arg);
+
+#define	TRAVERSE_PRE			(1<<0)
+#define	TRAVERSE_POST			(1<<1)
+#define	TRAVERSE_PREFETCH_METADATA	(1<<2)
+#define	TRAVERSE_PREFETCH_DATA		(1<<3)
+#define	TRAVERSE_PREFETCH (TRAVERSE_PREFETCH_METADATA | TRAVERSE_PREFETCH_DATA)
+#define	TRAVERSE_HARD			(1<<4)
+
+/* Special traverse error return value to indicate skipping of children */
+#define	TRAVERSE_VISIT_NO_CHILDREN	-1
+
+int traverse_dataset(struct dsl_dataset *ds,
+    uint64_t txg_start, int flags, blkptr_cb_t func, void *arg);
+int traverse_dataset_destroyed(spa_t *spa, blkptr_t *blkptr,
+    uint64_t txg_start, zbookmark_phys_t *resume, int flags,
+    blkptr_cb_t func, void *arg);
+int traverse_pool(spa_t *spa,
+    uint64_t txg_start, int flags, blkptr_cb_t func, void *arg);
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif /* _SYS_DMU_TRAVERSE_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/include/sys/dmu_tx.h
@@ -0,0 +1,193 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * Copyright (c) 2013 by Delphix. All rights reserved.
+ */
+
+#ifndef	_SYS_DMU_TX_H
+#define	_SYS_DMU_TX_H
+
+#include <sys/inttypes.h>
+#include <sys/dmu.h>
+#include <sys/txg.h>
+#include <sys/refcount.h>
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+struct dmu_buf_impl;
+struct dmu_tx_hold;
+struct dnode_link;
+struct dsl_pool;
+struct dnode;
+struct dsl_dir;
+
+struct dmu_tx {
+	/*
+	 * No synchronization is needed because a tx can only be handled
+	 * by one thread.
+	 */
+	list_t tx_holds; /* list of dmu_tx_hold_t */
+	objset_t *tx_objset;
+	struct dsl_dir *tx_dir;
+	struct dsl_pool *tx_pool;
+	uint64_t tx_txg;
+	uint64_t tx_lastsnap_txg;
+	uint64_t tx_lasttried_txg;
+	txg_handle_t tx_txgh;
+	void *tx_tempreserve_cookie;
+	struct dmu_tx_hold *tx_needassign_txh;
+
+	/* list of dmu_tx_callback_t on this dmu_tx */
+	list_t tx_callbacks;
+
+	/* placeholder for syncing context, doesn't need specific holds */
+	boolean_t tx_anyobj;
+
+	/* has this transaction already been delayed? */
+	boolean_t tx_waited;
+
+	/* time this transaction was created */
+	hrtime_t tx_start;
+
+	/* need to wait for sufficient dirty space */
+	boolean_t tx_wait_dirty;
+
+	int tx_err;
+#ifdef DEBUG_DMU_TX
+	uint64_t tx_space_towrite;
+	uint64_t tx_space_tofree;
+	uint64_t tx_space_tooverwrite;
+	uint64_t tx_space_tounref;
+	refcount_t tx_space_written;
+	refcount_t tx_space_freed;
+#endif
+};
+
+enum dmu_tx_hold_type {
+	THT_NEWOBJECT,
+	THT_WRITE,
+	THT_BONUS,
+	THT_FREE,
+	THT_ZAP,
+	THT_SPACE,
+	THT_SPILL,
+	THT_NUMTYPES
+};
+
+typedef struct dmu_tx_hold {
+	dmu_tx_t *txh_tx;
+	list_node_t txh_node;
+	struct dnode *txh_dnode;
+	uint64_t txh_space_towrite;
+	uint64_t txh_space_tofree;
+	uint64_t txh_space_tooverwrite;
+	uint64_t txh_space_tounref;
+	uint64_t txh_memory_tohold;
+	uint64_t txh_fudge;
+#ifdef DEBUG_DMU_TX
+	enum dmu_tx_hold_type txh_type;
+	uint64_t txh_arg1;
+	uint64_t txh_arg2;
+#endif
+} dmu_tx_hold_t;
+
+typedef struct dmu_tx_callback {
+	list_node_t		dcb_node;    /* linked to tx_callbacks list */
+	dmu_tx_callback_func_t	*dcb_func;   /* caller function pointer */
+	void			*dcb_data;   /* caller private data */
+} dmu_tx_callback_t;
+
+/*
+ * Used for dmu tx kstat.
+ */
+typedef struct dmu_tx_stats {
+	kstat_named_t dmu_tx_assigned;
+	kstat_named_t dmu_tx_delay;
+	kstat_named_t dmu_tx_error;
+	kstat_named_t dmu_tx_suspended;
+	kstat_named_t dmu_tx_group;
+	kstat_named_t dmu_tx_memory_reserve;
+	kstat_named_t dmu_tx_memory_reclaim;
+	kstat_named_t dmu_tx_dirty_throttle;
+	kstat_named_t dmu_tx_dirty_delay;
+	kstat_named_t dmu_tx_dirty_over_max;
+	kstat_named_t dmu_tx_quota;
+} dmu_tx_stats_t;
+
+extern dmu_tx_stats_t dmu_tx_stats;
+
+#define	DMU_TX_STAT_INCR(stat, val) \
+    atomic_add_64(&dmu_tx_stats.stat.value.ui64, (val));
+#define	DMU_TX_STAT_BUMP(stat) \
+    DMU_TX_STAT_INCR(stat, 1);
+
+/*
+ * These routines are defined in dmu.h, and are called by the user.
+ */
+dmu_tx_t *dmu_tx_create(objset_t *dd);
+int dmu_tx_assign(dmu_tx_t *tx, txg_how_t txg_how);
+void dmu_tx_commit(dmu_tx_t *tx);
+void dmu_tx_abort(dmu_tx_t *tx);
+uint64_t dmu_tx_get_txg(dmu_tx_t *tx);
+struct dsl_pool *dmu_tx_pool(dmu_tx_t *tx);
+void dmu_tx_wait(dmu_tx_t *tx);
+
+void dmu_tx_callback_register(dmu_tx_t *tx, dmu_tx_callback_func_t *dcb_func,
+    void *dcb_data);
+void dmu_tx_do_callbacks(list_t *cb_list, int error);
+
+/*
+ * These routines are defined in dmu_spa.h, and are called by the SPA.
+ */
+extern dmu_tx_t *dmu_tx_create_assigned(struct dsl_pool *dp, uint64_t txg);
+
+/*
+ * These routines are only called by the DMU.
+ */
+dmu_tx_t *dmu_tx_create_dd(dsl_dir_t *dd);
+int dmu_tx_is_syncing(dmu_tx_t *tx);
+int dmu_tx_private_ok(dmu_tx_t *tx);
+void dmu_tx_add_new_object(dmu_tx_t *tx, objset_t *os, uint64_t object);
+void dmu_tx_willuse_space(dmu_tx_t *tx, int64_t delta);
+void dmu_tx_dirty_buf(dmu_tx_t *tx, struct dmu_buf_impl *db);
+int dmu_tx_holds(dmu_tx_t *tx, uint64_t object);
+void dmu_tx_hold_space(dmu_tx_t *tx, uint64_t space);
+
+#ifdef DEBUG_DMU_TX
+#define	DMU_TX_DIRTY_BUF(tx, db)	dmu_tx_dirty_buf(tx, db)
+#else
+#define	DMU_TX_DIRTY_BUF(tx, db)
+#endif
+
+void dmu_tx_init(void);
+void dmu_tx_fini(void);
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* _SYS_DMU_TX_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/include/sys/dmu_zfetch.h
@@ -0,0 +1,76 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef	_DFETCH_H
+#define	_DFETCH_H
+
+#include <sys/zfs_context.h>
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+extern unsigned long	zfetch_array_rd_sz;
+
+struct dnode;				/* so we can reference dnode */
+
+typedef enum zfetch_dirn {
+	ZFETCH_FORWARD = 1,		/* prefetch increasing block numbers */
+	ZFETCH_BACKWARD	= -1		/* prefetch decreasing block numbers */
+} zfetch_dirn_t;
+
+typedef struct zstream {
+	uint64_t	zst_offset;	/* offset of starting block in range */
+	uint64_t	zst_len;	/* length of range, in blocks */
+	zfetch_dirn_t	zst_direction;	/* direction of prefetch */
+	uint64_t	zst_stride;	/* length of stride, in blocks */
+	uint64_t	zst_ph_offset;	/* prefetch offset, in blocks */
+	uint64_t	zst_cap;	/* prefetch limit (cap), in blocks */
+	kmutex_t	zst_lock;	/* protects stream */
+	clock_t		zst_last;	/* lbolt of last prefetch */
+	list_node_t	zst_node;	/* next zstream here */
+} zstream_t;
+
+typedef struct zfetch {
+	krwlock_t	zf_rwlock;	/* protects zfetch structure */
+	list_t		zf_stream;	/* AVL tree of zstream_t's */
+	struct dnode	*zf_dnode;	/* dnode that owns this zfetch */
+	uint32_t	zf_stream_cnt;	/* # of active streams */
+	uint64_t	zf_alloc_fail;	/* # of failed attempts to alloc strm */
+} zfetch_t;
+
+void		zfetch_init(void);
+void		zfetch_fini(void);
+
+void		dmu_zfetch_init(zfetch_t *, struct dnode *);
+void		dmu_zfetch_rele(zfetch_t *);
+void		dmu_zfetch(zfetch_t *, uint64_t, uint64_t, int);
+
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* _DFETCH_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/include/sys/dnode.h
@@ -0,0 +1,366 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2014 by Delphix. All rights reserved.
+ * Copyright (c) 2014 Spectra Logic Corporation, All rights reserved.
+ */
+
+#ifndef	_SYS_DNODE_H
+#define	_SYS_DNODE_H
+
+#include <sys/zfs_context.h>
+#include <sys/avl.h>
+#include <sys/spa.h>
+#include <sys/txg.h>
+#include <sys/zio.h>
+#include <sys/refcount.h>
+#include <sys/dmu_zfetch.h>
+#include <sys/zrlock.h>
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+/*
+ * dnode_hold() flags.
+ */
+#define	DNODE_MUST_BE_ALLOCATED	1
+#define	DNODE_MUST_BE_FREE	2
+
+/*
+ * dnode_next_offset() flags.
+ */
+#define	DNODE_FIND_HOLE		1
+#define	DNODE_FIND_BACKWARDS	2
+#define	DNODE_FIND_HAVELOCK	4
+
+/*
+ * Fixed constants.
+ */
+#define	DNODE_SHIFT		9	/* 512 bytes */
+#define	DN_MIN_INDBLKSHIFT	10	/* 1k */
+#define	DN_MAX_INDBLKSHIFT	14	/* 16k */
+#define	DNODE_BLOCK_SHIFT	14	/* 16k */
+#define	DNODE_CORE_SIZE		64	/* 64 bytes for dnode sans blkptrs */
+#define	DN_MAX_OBJECT_SHIFT	48	/* 256 trillion (zfs_fid_t limit) */
+#define	DN_MAX_OFFSET_SHIFT	64	/* 2^64 bytes in a dnode */
+
+/*
+ * dnode id flags
+ *
+ * Note: a file will never ever have its
+ * ids moved from bonus->spill
+ * and only in a crypto environment would it be on spill
+ */
+#define	DN_ID_CHKED_BONUS	0x1
+#define	DN_ID_CHKED_SPILL	0x2
+#define	DN_ID_OLD_EXIST		0x4
+#define	DN_ID_NEW_EXIST		0x8
+
+/*
+ * Derived constants.
+ */
+#define	DNODE_SIZE	(1 << DNODE_SHIFT)
+#define	DN_MAX_NBLKPTR	((DNODE_SIZE - DNODE_CORE_SIZE) >> SPA_BLKPTRSHIFT)
+#define	DN_MAX_BONUSLEN	(DNODE_SIZE - DNODE_CORE_SIZE - (1 << SPA_BLKPTRSHIFT))
+#define	DN_MAX_OBJECT	(1ULL << DN_MAX_OBJECT_SHIFT)
+#define	DN_ZERO_BONUSLEN	(DN_MAX_BONUSLEN + 1)
+#define	DN_KILL_SPILLBLK (1)
+
+#define	DNODES_PER_BLOCK_SHIFT	(DNODE_BLOCK_SHIFT - DNODE_SHIFT)
+#define	DNODES_PER_BLOCK	(1ULL << DNODES_PER_BLOCK_SHIFT)
+#define	DNODES_PER_LEVEL_SHIFT	(DN_MAX_INDBLKSHIFT - SPA_BLKPTRSHIFT)
+#define	DNODES_PER_LEVEL	(1ULL << DNODES_PER_LEVEL_SHIFT)
+
+/* The +2 here is a cheesy way to round up */
+#define	DN_MAX_LEVELS	(2 + ((DN_MAX_OFFSET_SHIFT - SPA_MINBLOCKSHIFT) / \
+	(DN_MIN_INDBLKSHIFT - SPA_BLKPTRSHIFT)))
+
+#define	DN_BONUS(dnp)	((void*)((dnp)->dn_bonus + \
+	(((dnp)->dn_nblkptr - 1) * sizeof (blkptr_t))))
+
+#define	DN_USED_BYTES(dnp) (((dnp)->dn_flags & DNODE_FLAG_USED_BYTES) ? \
+	(dnp)->dn_used : (dnp)->dn_used << SPA_MINBLOCKSHIFT)
+
+#define	EPB(blkshift, typeshift)	(1 << (blkshift - typeshift))
+
+struct dmu_buf_impl;
+struct objset;
+struct zio;
+
+enum dnode_dirtycontext {
+	DN_UNDIRTIED,
+	DN_DIRTY_OPEN,
+	DN_DIRTY_SYNC
+};
+
+/* Is dn_used in bytes?  if not, it's in multiples of SPA_MINBLOCKSIZE */
+#define	DNODE_FLAG_USED_BYTES		(1<<0)
+#define	DNODE_FLAG_USERUSED_ACCOUNTED	(1<<1)
+
+/* Does dnode have a SA spill blkptr in bonus? */
+#define	DNODE_FLAG_SPILL_BLKPTR	(1<<2)
+
+typedef struct dnode_phys {
+	uint8_t dn_type;		/* dmu_object_type_t */
+	uint8_t dn_indblkshift;		/* ln2(indirect block size) */
+	uint8_t dn_nlevels;		/* 1=dn_blkptr->data blocks */
+	uint8_t dn_nblkptr;		/* length of dn_blkptr */
+	uint8_t dn_bonustype;		/* type of data in bonus buffer */
+	uint8_t	dn_checksum;		/* ZIO_CHECKSUM type */
+	uint8_t	dn_compress;		/* ZIO_COMPRESS type */
+	uint8_t dn_flags;		/* DNODE_FLAG_* */
+	uint16_t dn_datablkszsec;	/* data block size in 512b sectors */
+	uint16_t dn_bonuslen;		/* length of dn_bonus */
+	uint8_t dn_pad2[4];
+
+	/* accounting is protected by dn_dirty_mtx */
+	uint64_t dn_maxblkid;		/* largest allocated block ID */
+	uint64_t dn_used;		/* bytes (or sectors) of disk space */
+
+	uint64_t dn_pad3[4];
+
+	/*
+	 * The tail region is 448 bytes, and there are three ways to
+	 * look at it.
+	 *
+	 * 0       64      128     192     256     320     384     448 (offset)
+	 * +---------------+---------------+---------------+-------+
+	 * | dn_blkptr[0]  | dn_blkptr[1]  | dn_blkptr[2]  | /     |
+	 * +---------------+---------------+---------------+-------+
+	 * | dn_blkptr[0]  | dn_bonus[0..319]                      |
+	 * +---------------+-----------------------+---------------+
+	 * | dn_blkptr[0]  | /                     | dn_spill      |
+	 * +---------------+-----------------------+---------------+
+	 */
+	union {
+		blkptr_t dn_blkptr[1+DN_MAX_BONUSLEN/sizeof (blkptr_t)];
+		struct {
+			blkptr_t __dn_ignore1;
+			uint8_t dn_bonus[DN_MAX_BONUSLEN];
+		};
+		struct {
+			blkptr_t __dn_ignore2;
+			uint8_t __dn_ignore3[DN_MAX_BONUSLEN-sizeof (blkptr_t)];
+			blkptr_t dn_spill;
+		};
+	};
+} dnode_phys_t;
+
+typedef struct dnode {
+	/*
+	 * Protects the structure of the dnode, including the number of levels
+	 * of indirection (dn_nlevels), dn_maxblkid, and dn_next_*
+	 */
+	krwlock_t dn_struct_rwlock;
+
+	/* Our link on dn_objset->os_dnodes list; protected by os_lock.  */
+	list_node_t dn_link;
+
+	/* immutable: */
+	struct objset *dn_objset;
+	uint64_t dn_object;
+	struct dmu_buf_impl *dn_dbuf;
+	struct dnode_handle *dn_handle;
+	dnode_phys_t *dn_phys; /* pointer into dn->dn_dbuf->db.db_data */
+
+	/*
+	 * Copies of stuff in dn_phys.  They're valid in the open
+	 * context (eg. even before the dnode is first synced).
+	 * Where necessary, these are protected by dn_struct_rwlock.
+	 */
+	dmu_object_type_t dn_type;	/* object type */
+	uint16_t dn_bonuslen;		/* bonus length */
+	uint8_t dn_bonustype;		/* bonus type */
+	uint8_t dn_nblkptr;		/* number of blkptrs (immutable) */
+	uint8_t dn_checksum;		/* ZIO_CHECKSUM type */
+	uint8_t dn_compress;		/* ZIO_COMPRESS type */
+	uint8_t dn_nlevels;
+	uint8_t dn_indblkshift;
+	uint8_t dn_datablkshift;	/* zero if blksz not power of 2! */
+	uint8_t dn_moved;		/* Has this dnode been moved? */
+	uint16_t dn_datablkszsec;	/* in 512b sectors */
+	uint32_t dn_datablksz;		/* in bytes */
+	uint64_t dn_maxblkid;
+	uint8_t dn_next_type[TXG_SIZE];
+	uint8_t dn_next_nblkptr[TXG_SIZE];
+	uint8_t dn_next_nlevels[TXG_SIZE];
+	uint8_t dn_next_indblkshift[TXG_SIZE];
+	uint8_t dn_next_bonustype[TXG_SIZE];
+	uint8_t dn_rm_spillblk[TXG_SIZE];	/* for removing spill blk */
+	uint16_t dn_next_bonuslen[TXG_SIZE];
+	uint32_t dn_next_blksz[TXG_SIZE];	/* next block size in bytes */
+
+	/* protected by dn_dbufs_mtx; declared here to fill 32-bit hole */
+	uint32_t dn_dbufs_count;	/* count of dn_dbufs */
+	/* There are no level-0 blocks of this blkid or higher in dn_dbufs */
+	uint64_t dn_unlisted_l0_blkid;
+
+	/* protected by os_lock: */
+	list_node_t dn_dirty_link[TXG_SIZE];	/* next on dataset's dirty */
+
+	/* protected by dn_mtx: */
+	kmutex_t dn_mtx;
+	list_t dn_dirty_records[TXG_SIZE];
+	struct range_tree *dn_free_ranges[TXG_SIZE];
+	uint64_t dn_allocated_txg;
+	uint64_t dn_free_txg;
+	uint64_t dn_assigned_txg;
+	kcondvar_t dn_notxholds;
+	enum dnode_dirtycontext dn_dirtyctx;
+	uint8_t *dn_dirtyctx_firstset;		/* dbg: contents meaningless */
+
+	/* protected by own devices */
+	refcount_t dn_tx_holds;
+	refcount_t dn_holds;
+
+	kmutex_t dn_dbufs_mtx;
+	/*
+	 * Descendent dbufs, ordered by dbuf_compare. Note that dn_dbufs
+	 * can contain multiple dbufs of the same (level, blkid) when a
+	 * dbuf is marked DB_EVICTING without being removed from
+	 * dn_dbufs. To maintain the avl invariant that there cannot be
+	 * duplicate entries, we order the dbufs by an arbitrary value -
+	 * their address in memory. This means that dn_dbufs cannot be used to
+	 * directly look up a dbuf. Instead, callers must use avl_walk, have
+	 * a reference to the dbuf, or look up a non-existant node with
+	 * db_state = DB_SEARCH (see dbuf_free_range for an example).
+	 */
+	avl_tree_t dn_dbufs;
+
+	/* protected by dn_struct_rwlock */
+	struct dmu_buf_impl *dn_bonus;	/* bonus buffer dbuf */
+
+	boolean_t dn_have_spill;	/* have spill or are spilling */
+
+	/* parent IO for current sync write */
+	zio_t *dn_zio;
+
+	/* used in syncing context */
+	uint64_t dn_oldused;	/* old phys used bytes */
+	uint64_t dn_oldflags;	/* old phys dn_flags */
+	uint64_t dn_olduid, dn_oldgid;
+	uint64_t dn_newuid, dn_newgid;
+	int dn_id_flags;
+
+	/* holds prefetch structure */
+	struct zfetch	dn_zfetch;
+} dnode_t;
+
+/*
+ * Adds a level of indirection between the dbuf and the dnode to avoid
+ * iterating descendent dbufs in dnode_move(). Handles are not allocated
+ * individually, but as an array of child dnodes in dnode_hold_impl().
+ */
+typedef struct dnode_handle {
+	/* Protects dnh_dnode from modification by dnode_move(). */
+	zrlock_t dnh_zrlock;
+	dnode_t *dnh_dnode;
+} dnode_handle_t;
+
+typedef struct dnode_children {
+	dmu_buf_user_t dnc_dbu;		/* User evict data */
+	size_t dnc_count;		/* number of children */
+	dnode_handle_t dnc_children[];	/* sized dynamically */
+} dnode_children_t;
+
+typedef struct free_range {
+	avl_node_t fr_node;
+	uint64_t fr_blkid;
+	uint64_t fr_nblks;
+} free_range_t;
+
+void dnode_special_open(struct objset *dd, dnode_phys_t *dnp,
+    uint64_t object, dnode_handle_t *dnh);
+void dnode_special_close(dnode_handle_t *dnh);
+
+void dnode_setbonuslen(dnode_t *dn, int newsize, dmu_tx_t *tx);
+void dnode_setbonus_type(dnode_t *dn, dmu_object_type_t, dmu_tx_t *tx);
+void dnode_rm_spill(dnode_t *dn, dmu_tx_t *tx);
+
+int dnode_hold(struct objset *dd, uint64_t object,
+    void *ref, dnode_t **dnp);
+int dnode_hold_impl(struct objset *dd, uint64_t object, int flag,
+    void *ref, dnode_t **dnp);
+boolean_t dnode_add_ref(dnode_t *dn, void *ref);
+void dnode_rele(dnode_t *dn, void *ref);
+void dnode_rele_and_unlock(dnode_t *dn, void *tag);
+void dnode_setdirty(dnode_t *dn, dmu_tx_t *tx);
+void dnode_sync(dnode_t *dn, dmu_tx_t *tx);
+void dnode_allocate(dnode_t *dn, dmu_object_type_t ot, int blocksize, int ibs,
+    dmu_object_type_t bonustype, int bonuslen, dmu_tx_t *tx);
+void dnode_reallocate(dnode_t *dn, dmu_object_type_t ot, int blocksize,
+    dmu_object_type_t bonustype, int bonuslen, dmu_tx_t *tx);
+void dnode_free(dnode_t *dn, dmu_tx_t *tx);
+void dnode_byteswap(dnode_phys_t *dnp);
+void dnode_buf_byteswap(void *buf, size_t size);
+void dnode_verify(dnode_t *dn);
+int dnode_set_blksz(dnode_t *dn, uint64_t size, int ibs, dmu_tx_t *tx);
+void dnode_free_range(dnode_t *dn, uint64_t off, uint64_t len, dmu_tx_t *tx);
+void dnode_diduse_space(dnode_t *dn, int64_t space);
+void dnode_willuse_space(dnode_t *dn, int64_t space, dmu_tx_t *tx);
+void dnode_new_blkid(dnode_t *dn, uint64_t blkid, dmu_tx_t *tx, boolean_t);
+uint64_t dnode_block_freed(dnode_t *dn, uint64_t blkid);
+void dnode_init(void);
+void dnode_fini(void);
+int dnode_next_offset(dnode_t *dn, int flags, uint64_t *off,
+    int minlvl, uint64_t blkfill, uint64_t txg);
+void dnode_evict_dbufs(dnode_t *dn);
+void dnode_evict_bonus(dnode_t *dn);
+
+#ifdef ZFS_DEBUG
+
+/*
+ * There should be a ## between the string literal and fmt, to make it
+ * clear that we're joining two strings together, but that piece of shit
+ * gcc doesn't support that preprocessor token.
+ */
+#define	dprintf_dnode(dn, fmt, ...) do { \
+	if (zfs_flags & ZFS_DEBUG_DPRINTF) { \
+	char __db_buf[32]; \
+	uint64_t __db_obj = (dn)->dn_object; \
+	if (__db_obj == DMU_META_DNODE_OBJECT) \
+		(void) strcpy(__db_buf, "mdn"); \
+	else \
+		(void) snprintf(__db_buf, sizeof (__db_buf), "%lld", \
+		    (u_longlong_t)__db_obj);\
+	dprintf_ds((dn)->dn_objset->os_dsl_dataset, "obj=%s " fmt, \
+	    __db_buf, __VA_ARGS__); \
+	} \
+_NOTE(CONSTCOND) } while (0)
+
+#define	DNODE_VERIFY(dn)		dnode_verify(dn)
+#define	FREE_VERIFY(db, start, end, tx)	free_verify(db, start, end, tx)
+
+#else
+
+#define	dprintf_dnode(db, fmt, ...)
+#define	DNODE_VERIFY(dn)
+#define	FREE_VERIFY(db, start, end, tx)
+
+#endif
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* _SYS_DNODE_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/include/sys/dsl_bookmark.h
@@ -0,0 +1,51 @@
+/*
+ * CDDL HEADER START
+ *
+ * This file and its contents are supplied under the terms of the
+ * Common Development and Distribution License ("CDDL"), version 1.0.
+ * You may only use this file in accordance with the terms of version
+ * 1.0 of the CDDL.
+ *
+ * A full copy of the text of the CDDL should have accompanied this
+ * source.  A copy of the CDDL is also available via the Internet at
+ * http://www.illumos.org/license/CDDL.
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2013 by Delphix. All rights reserved.
+ */
+
+#ifndef	_SYS_DSL_BOOKMARK_H
+#define	_SYS_DSL_BOOKMARK_H
+
+#include <sys/zfs_context.h>
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+struct dsl_pool;
+struct dsl_dataset;
+
+/*
+ * On disk zap object.
+ */
+typedef struct zfs_bookmark_phys {
+	uint64_t zbm_guid;		/* guid of bookmarked dataset */
+	uint64_t zbm_creation_txg;	/* birth transaction group */
+	uint64_t zbm_creation_time;	/* bookmark creation time */
+} zfs_bookmark_phys_t;
+
+int dsl_bookmark_create(nvlist_t *, nvlist_t *);
+int dsl_get_bookmarks(const char *, nvlist_t *, nvlist_t *);
+int dsl_get_bookmarks_impl(dsl_dataset_t *, nvlist_t *, nvlist_t *);
+int dsl_bookmark_destroy(nvlist_t *, nvlist_t *);
+int dsl_bookmark_lookup(struct dsl_pool *, const char *,
+    struct dsl_dataset *, zfs_bookmark_phys_t *);
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif /* _SYS_DSL_BOOKMARK_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/include/sys/dsl_dataset.h
@@ -0,0 +1,325 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013 by Delphix. All rights reserved.
+ * Copyright (c) 2013, Joyent, Inc. All rights reserved.
+ * Copyright (c) 2013 Steven Hartland. All rights reserved.
+ * Copyright (c) 2014 Spectra Logic Corporation, All rights reserved.
+ */
+
+#ifndef	_SYS_DSL_DATASET_H
+#define	_SYS_DSL_DATASET_H
+
+#include <sys/dmu.h>
+#include <sys/spa.h>
+#include <sys/txg.h>
+#include <sys/zio.h>
+#include <sys/bplist.h>
+#include <sys/dsl_synctask.h>
+#include <sys/zfs_context.h>
+#include <sys/dsl_deadlist.h>
+#include <sys/refcount.h>
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+struct dsl_dataset;
+struct dsl_dir;
+struct dsl_pool;
+
+#define	DS_FLAG_INCONSISTENT	(1ULL<<0)
+#define	DS_IS_INCONSISTENT(ds)	\
+	(dsl_dataset_phys(ds)->ds_flags & DS_FLAG_INCONSISTENT)
+
+/*
+ * Do not allow this dataset to be promoted.
+ */
+#define	DS_FLAG_NOPROMOTE	(1ULL<<1)
+
+/*
+ * DS_FLAG_UNIQUE_ACCURATE is set if ds_unique_bytes has been correctly
+ * calculated for head datasets (starting with SPA_VERSION_UNIQUE_ACCURATE,
+ * refquota/refreservations).
+ */
+#define	DS_FLAG_UNIQUE_ACCURATE	(1ULL<<2)
+
+/*
+ * DS_FLAG_DEFER_DESTROY is set after 'zfs destroy -d' has been called
+ * on a dataset. This allows the dataset to be destroyed using 'zfs release'.
+ */
+#define	DS_FLAG_DEFER_DESTROY	(1ULL<<3)
+#define	DS_IS_DEFER_DESTROY(ds)	\
+	(dsl_dataset_phys(ds)->ds_flags & DS_FLAG_DEFER_DESTROY)
+
+/*
+ * DS_FIELD_* are strings that are used in the "extensified" dataset zap object.
+ * They should be of the format <reverse-dns>:<field>.
+ */
+
+/*
+ * This field's value is the object ID of a zap object which contains the
+ * bookmarks of this dataset.  If it is present, then this dataset is counted
+ * in the refcount of the SPA_FEATURES_BOOKMARKS feature.
+ */
+#define	DS_FIELD_BOOKMARK_NAMES "com.delphix:bookmarks"
+
+/*
+ * This field is present (with value=0) if this dataset may contain large
+ * blocks (>128KB).  If it is present, then this dataset
+ * is counted in the refcount of the SPA_FEATURE_LARGE_BLOCKS feature.
+ */
+#define	DS_FIELD_LARGE_BLOCKS "org.open-zfs:large_blocks"
+
+/*
+ * DS_FLAG_CI_DATASET is set if the dataset contains a file system whose
+ * name lookups should be performed case-insensitively.
+ */
+#define	DS_FLAG_CI_DATASET	(1ULL<<16)
+
+#define	DS_CREATE_FLAG_NODIRTY	(1ULL<<24)
+
+typedef struct dsl_dataset_phys {
+	uint64_t ds_dir_obj;		/* DMU_OT_DSL_DIR */
+	uint64_t ds_prev_snap_obj;	/* DMU_OT_DSL_DATASET */
+	uint64_t ds_prev_snap_txg;
+	uint64_t ds_next_snap_obj;	/* DMU_OT_DSL_DATASET */
+	uint64_t ds_snapnames_zapobj;	/* DMU_OT_DSL_DS_SNAP_MAP 0 for snaps */
+	uint64_t ds_num_children;	/* clone/snap children; ==0 for head */
+	uint64_t ds_creation_time;	/* seconds since 1970 */
+	uint64_t ds_creation_txg;
+	uint64_t ds_deadlist_obj;	/* DMU_OT_DEADLIST */
+	/*
+	 * ds_referenced_bytes, ds_compressed_bytes, and ds_uncompressed_bytes
+	 * include all blocks referenced by this dataset, including those
+	 * shared with any other datasets.
+	 */
+	uint64_t ds_referenced_bytes;
+	uint64_t ds_compressed_bytes;
+	uint64_t ds_uncompressed_bytes;
+	uint64_t ds_unique_bytes;	/* only relevant to snapshots */
+	/*
+	 * The ds_fsid_guid is a 56-bit ID that can change to avoid
+	 * collisions.  The ds_guid is a 64-bit ID that will never
+	 * change, so there is a small probability that it will collide.
+	 */
+	uint64_t ds_fsid_guid;
+	uint64_t ds_guid;
+	uint64_t ds_flags;		/* DS_FLAG_* */
+	blkptr_t ds_bp;
+	uint64_t ds_next_clones_obj;	/* DMU_OT_DSL_CLONES */
+	uint64_t ds_props_obj;		/* DMU_OT_DSL_PROPS for snaps */
+	uint64_t ds_userrefs_obj;	/* DMU_OT_USERREFS */
+	uint64_t ds_pad[5]; /* pad out to 320 bytes for good measure */
+} dsl_dataset_phys_t;
+
+typedef struct dsl_dataset {
+	dmu_buf_user_t ds_dbu;
+
+	/* Immutable: */
+	struct dsl_dir *ds_dir;
+	dmu_buf_t *ds_dbuf;
+	uint64_t ds_object;
+	uint64_t ds_fsid_guid;
+	boolean_t ds_is_snapshot;
+
+	/* only used in syncing context, only valid for non-snapshots: */
+	struct dsl_dataset *ds_prev;
+	uint64_t ds_bookmarks;  /* DMU_OTN_ZAP_METADATA */
+	boolean_t ds_large_blocks;
+	boolean_t ds_need_large_blocks;
+
+	/* has internal locking: */
+	dsl_deadlist_t ds_deadlist;
+	bplist_t ds_pending_deadlist;
+
+	/* protected by lock on pool's dp_dirty_datasets list */
+	txg_node_t ds_dirty_link;
+	list_node_t ds_synced_link;
+
+	/*
+	 * ds_phys->ds_<accounting> is also protected by ds_lock.
+	 * Protected by ds_lock:
+	 */
+	kmutex_t ds_lock;
+	objset_t *ds_objset;
+	uint64_t ds_userrefs;
+	void *ds_owner;
+
+	/*
+	 * Long holds prevent the ds from being destroyed; they allow the
+	 * ds to remain held even after dropping the dp_config_rwlock.
+	 * Owning counts as a long hold.  See the comments above
+	 * dsl_pool_hold() for details.
+	 */
+	refcount_t ds_longholds;
+
+	/* no locking; only for making guesses */
+	uint64_t ds_trysnap_txg;
+
+	/* for objset_open() */
+	kmutex_t ds_opening_lock;
+
+	uint64_t ds_reserved;	/* cached refreservation */
+	uint64_t ds_quota;	/* cached refquota */
+
+	kmutex_t ds_sendstream_lock;
+	list_t ds_sendstreams;
+
+	/* Protected by ds_lock; keep at end of struct for better locality */
+	char ds_snapname[MAXNAMELEN];
+} dsl_dataset_t;
+
+static inline dsl_dataset_phys_t *
+dsl_dataset_phys(dsl_dataset_t *ds)
+{
+	return (ds->ds_dbuf->db_data);
+}
+
+/*
+ * The max length of a temporary tag prefix is the number of hex digits
+ * required to express UINT64_MAX plus one for the hyphen.
+ */
+#define	MAX_TAG_PREFIX_LEN	17
+
+#define	dsl_dataset_is_snapshot(ds) \
+	(dsl_dataset_phys(ds)->ds_num_children != 0)
+
+#define	DS_UNIQUE_IS_ACCURATE(ds)	\
+	((dsl_dataset_phys(ds)->ds_flags & DS_FLAG_UNIQUE_ACCURATE) != 0)
+
+int dsl_dataset_hold(struct dsl_pool *dp, const char *name, void *tag,
+    dsl_dataset_t **dsp);
+boolean_t dsl_dataset_try_add_ref(struct dsl_pool *dp, dsl_dataset_t *ds,
+    void *tag);
+int dsl_dataset_hold_obj(struct dsl_pool *dp, uint64_t dsobj, void *tag,
+    dsl_dataset_t **);
+void dsl_dataset_rele(dsl_dataset_t *ds, void *tag);
+int dsl_dataset_own(struct dsl_pool *dp, const char *name,
+    void *tag, dsl_dataset_t **dsp);
+int dsl_dataset_own_obj(struct dsl_pool *dp, uint64_t dsobj,
+    void *tag, dsl_dataset_t **dsp);
+void dsl_dataset_disown(dsl_dataset_t *ds, void *tag);
+void dsl_dataset_name(dsl_dataset_t *ds, char *name);
+boolean_t dsl_dataset_tryown(dsl_dataset_t *ds, void *tag);
+uint64_t dsl_dataset_create_sync(dsl_dir_t *pds, const char *lastname,
+    dsl_dataset_t *origin, uint64_t flags, cred_t *, dmu_tx_t *);
+uint64_t dsl_dataset_create_sync_dd(dsl_dir_t *dd, dsl_dataset_t *origin,
+    uint64_t flags, dmu_tx_t *tx);
+int dsl_dataset_snapshot(nvlist_t *snaps, nvlist_t *props, nvlist_t *errors);
+int dsl_dataset_promote(const char *name, char *conflsnap);
+int dsl_dataset_rename_snapshot(const char *fsname,
+    const char *oldsnapname, const char *newsnapname, boolean_t recursive);
+int dsl_dataset_snapshot_tmp(const char *fsname, const char *snapname,
+    minor_t cleanup_minor, const char *htag);
+
+blkptr_t *dsl_dataset_get_blkptr(dsl_dataset_t *ds);
+void dsl_dataset_set_blkptr(dsl_dataset_t *ds, blkptr_t *bp, dmu_tx_t *tx);
+
+spa_t *dsl_dataset_get_spa(dsl_dataset_t *ds);
+
+boolean_t dsl_dataset_modified_since_snap(dsl_dataset_t *ds,
+    dsl_dataset_t *snap);
+
+void dsl_dataset_sync(dsl_dataset_t *os, zio_t *zio, dmu_tx_t *tx);
+
+void dsl_dataset_block_born(dsl_dataset_t *ds, const blkptr_t *bp,
+    dmu_tx_t *tx);
+int dsl_dataset_block_kill(dsl_dataset_t *ds, const blkptr_t *bp,
+    dmu_tx_t *tx, boolean_t async);
+boolean_t dsl_dataset_block_freeable(dsl_dataset_t *ds, const blkptr_t *bp,
+    uint64_t blk_birth);
+uint64_t dsl_dataset_prev_snap_txg(dsl_dataset_t *ds);
+int dsl_dataset_snap_lookup(dsl_dataset_t *ds, const char *name,
+    uint64_t *value);
+
+void dsl_dataset_dirty(dsl_dataset_t *ds, dmu_tx_t *tx);
+void dsl_dataset_stats(dsl_dataset_t *os, nvlist_t *nv);
+void dsl_dataset_fast_stat(dsl_dataset_t *ds, dmu_objset_stats_t *stat);
+void dsl_dataset_space(dsl_dataset_t *ds,
+    uint64_t *refdbytesp, uint64_t *availbytesp,
+    uint64_t *usedobjsp, uint64_t *availobjsp);
+uint64_t dsl_dataset_fsid_guid(dsl_dataset_t *ds);
+int dsl_dataset_space_written(dsl_dataset_t *oldsnap, dsl_dataset_t *new,
+    uint64_t *usedp, uint64_t *compp, uint64_t *uncompp);
+int dsl_dataset_space_wouldfree(dsl_dataset_t *firstsnap, dsl_dataset_t *last,
+    uint64_t *usedp, uint64_t *compp, uint64_t *uncompp);
+boolean_t dsl_dataset_is_dirty(dsl_dataset_t *ds);
+int dsl_dataset_activate_large_blocks(const char *dsname);
+void dsl_dataset_activate_large_blocks_sync_impl(uint64_t dsobj, dmu_tx_t *tx);
+
+int dsl_dsobj_to_dsname(char *pname, uint64_t obj, char *buf);
+
+int dsl_dataset_check_quota(dsl_dataset_t *ds, boolean_t check_quota,
+    uint64_t asize, uint64_t inflight, uint64_t *used,
+    uint64_t *ref_rsrv);
+int dsl_dataset_set_refquota(const char *dsname, zprop_source_t source,
+    uint64_t quota);
+int dsl_dataset_set_refreservation(const char *dsname, zprop_source_t source,
+    uint64_t reservation);
+
+boolean_t dsl_dataset_is_before(dsl_dataset_t *later, dsl_dataset_t *earlier,
+    uint64_t earlier_txg);
+void dsl_dataset_long_hold(dsl_dataset_t *ds, void *tag);
+void dsl_dataset_long_rele(dsl_dataset_t *ds, void *tag);
+boolean_t dsl_dataset_long_held(dsl_dataset_t *ds);
+
+int dsl_dataset_clone_swap_check_impl(dsl_dataset_t *clone,
+    dsl_dataset_t *origin_head, boolean_t force, void *owner, dmu_tx_t *tx);
+void dsl_dataset_clone_swap_sync_impl(dsl_dataset_t *clone,
+    dsl_dataset_t *origin_head, dmu_tx_t *tx);
+int dsl_dataset_snapshot_check_impl(dsl_dataset_t *ds, const char *snapname,
+    dmu_tx_t *tx, boolean_t recv, uint64_t cnt, cred_t *cr);
+void dsl_dataset_snapshot_sync_impl(dsl_dataset_t *ds, const char *snapname,
+    dmu_tx_t *tx);
+
+void dsl_dataset_remove_from_next_clones(dsl_dataset_t *ds, uint64_t obj,
+    dmu_tx_t *tx);
+void dsl_dataset_recalc_head_uniq(dsl_dataset_t *ds);
+int dsl_dataset_get_snapname(dsl_dataset_t *ds);
+int dsl_dataset_snap_lookup(dsl_dataset_t *ds, const char *name,
+    uint64_t *value);
+int dsl_dataset_snap_remove(dsl_dataset_t *ds, const char *name, dmu_tx_t *tx,
+    boolean_t adj_cnt);
+void dsl_dataset_set_refreservation_sync_impl(dsl_dataset_t *ds,
+    zprop_source_t source, uint64_t value, dmu_tx_t *tx);
+void dsl_dataset_zapify(dsl_dataset_t *ds, dmu_tx_t *tx);
+int dsl_dataset_rollback(const char *fsname, void *owner, nvlist_t *result);
+
+#ifdef ZFS_DEBUG
+#define	dprintf_ds(ds, fmt, ...) do { \
+	if (zfs_flags & ZFS_DEBUG_DPRINTF) { \
+	char *__ds_name = kmem_alloc(MAXNAMELEN, KM_SLEEP); \
+	dsl_dataset_name(ds, __ds_name); \
+	dprintf("ds=%s " fmt, __ds_name, __VA_ARGS__); \
+	kmem_free(__ds_name, MAXNAMELEN); \
+	} \
+_NOTE(CONSTCOND) } while (0)
+#else
+#define	dprintf_ds(dd, fmt, ...)
+#endif
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif /* _SYS_DSL_DATASET_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/include/sys/dsl_deadlist.h
@@ -0,0 +1,87 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ */
+
+#ifndef	_SYS_DSL_DEADLIST_H
+#define	_SYS_DSL_DEADLIST_H
+
+#include <sys/bpobj.h>
+#include <sys/zfs_context.h>
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+struct dmu_buf;
+struct dsl_dataset;
+
+typedef struct dsl_deadlist_phys {
+	uint64_t dl_used;
+	uint64_t dl_comp;
+	uint64_t dl_uncomp;
+	uint64_t dl_pad[37]; /* pad out to 320b for future expansion */
+} dsl_deadlist_phys_t;
+
+typedef struct dsl_deadlist {
+	objset_t *dl_os;
+	uint64_t dl_object;
+	avl_tree_t dl_tree;
+	boolean_t dl_havetree;
+	struct dmu_buf *dl_dbuf;
+	dsl_deadlist_phys_t *dl_phys;
+	kmutex_t dl_lock;
+
+	/* if it's the old on-disk format: */
+	bpobj_t dl_bpobj;
+	boolean_t dl_oldfmt;
+} dsl_deadlist_t;
+
+typedef struct dsl_deadlist_entry {
+	avl_node_t dle_node;
+	uint64_t dle_mintxg;
+	bpobj_t dle_bpobj;
+} dsl_deadlist_entry_t;
+
+void dsl_deadlist_open(dsl_deadlist_t *dl, objset_t *os, uint64_t object);
+void dsl_deadlist_close(dsl_deadlist_t *dl);
+uint64_t dsl_deadlist_alloc(objset_t *os, dmu_tx_t *tx);
+void dsl_deadlist_free(objset_t *os, uint64_t dlobj, dmu_tx_t *tx);
+void dsl_deadlist_insert(dsl_deadlist_t *dl, const blkptr_t *bp, dmu_tx_t *tx);
+void dsl_deadlist_add_key(dsl_deadlist_t *dl, uint64_t mintxg, dmu_tx_t *tx);
+void dsl_deadlist_remove_key(dsl_deadlist_t *dl, uint64_t mintxg, dmu_tx_t *tx);
+uint64_t dsl_deadlist_clone(dsl_deadlist_t *dl, uint64_t maxtxg,
+    uint64_t mrs_obj, dmu_tx_t *tx);
+void dsl_deadlist_space(dsl_deadlist_t *dl,
+    uint64_t *usedp, uint64_t *compp, uint64_t *uncompp);
+void dsl_deadlist_space_range(dsl_deadlist_t *dl,
+    uint64_t mintxg, uint64_t maxtxg,
+    uint64_t *usedp, uint64_t *compp, uint64_t *uncompp);
+void dsl_deadlist_merge(dsl_deadlist_t *dl, uint64_t obj, dmu_tx_t *tx);
+void dsl_deadlist_move_bpobj(dsl_deadlist_t *dl, bpobj_t *bpo, uint64_t mintxg,
+    dmu_tx_t *tx);
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif /* _SYS_DSL_DEADLIST_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/include/sys/dsl_deleg.h
@@ -0,0 +1,80 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013 by Delphix. All rights reserved.
+ */
+
+#ifndef	_SYS_DSL_DELEG_H
+#define	_SYS_DSL_DELEG_H
+
+#include <sys/dmu.h>
+#include <sys/dsl_pool.h>
+#include <sys/zfs_context.h>
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+#define	ZFS_DELEG_PERM_NONE		""
+#define	ZFS_DELEG_PERM_CREATE		"create"
+#define	ZFS_DELEG_PERM_DESTROY		"destroy"
+#define	ZFS_DELEG_PERM_SNAPSHOT		"snapshot"
+#define	ZFS_DELEG_PERM_ROLLBACK		"rollback"
+#define	ZFS_DELEG_PERM_CLONE		"clone"
+#define	ZFS_DELEG_PERM_PROMOTE		"promote"
+#define	ZFS_DELEG_PERM_RENAME		"rename"
+#define	ZFS_DELEG_PERM_MOUNT		"mount"
+#define	ZFS_DELEG_PERM_SHARE		"share"
+#define	ZFS_DELEG_PERM_SEND		"send"
+#define	ZFS_DELEG_PERM_RECEIVE		"receive"
+#define	ZFS_DELEG_PERM_ALLOW		"allow"
+#define	ZFS_DELEG_PERM_USERPROP		"userprop"
+#define	ZFS_DELEG_PERM_VSCAN		"vscan"
+#define	ZFS_DELEG_PERM_USERQUOTA	"userquota"
+#define	ZFS_DELEG_PERM_GROUPQUOTA	"groupquota"
+#define	ZFS_DELEG_PERM_USERUSED		"userused"
+#define	ZFS_DELEG_PERM_GROUPUSED	"groupused"
+#define	ZFS_DELEG_PERM_HOLD		"hold"
+#define	ZFS_DELEG_PERM_RELEASE		"release"
+#define	ZFS_DELEG_PERM_DIFF		"diff"
+#define	ZFS_DELEG_PERM_BOOKMARK		"bookmark"
+
+/*
+ * Note: the names of properties that are marked delegatable are also
+ * valid delegated permissions
+ */
+
+int dsl_deleg_get(const char *ddname, nvlist_t **nvp);
+int dsl_deleg_set(const char *ddname, nvlist_t *nvp, boolean_t unset);
+int dsl_deleg_access(const char *ddname, const char *perm, cred_t *cr);
+int dsl_deleg_access_impl(struct dsl_dataset *ds, const char *perm, cred_t *cr);
+void dsl_deleg_set_create_perms(dsl_dir_t *dd, dmu_tx_t *tx, cred_t *cr);
+int dsl_deleg_can_allow(char *ddname, nvlist_t *nvp, cred_t *cr);
+int dsl_deleg_can_unallow(char *ddname, nvlist_t *nvp, cred_t *cr);
+int dsl_deleg_destroy(objset_t *os, uint64_t zapobj, dmu_tx_t *tx);
+boolean_t dsl_delegation_on(objset_t *os);
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* _SYS_DSL_DELEG_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/include/sys/dsl_destroy.h
@@ -0,0 +1,53 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013 by Delphix. All rights reserved.
+ * Copyright (c) 2012, Joyent, Inc. All rights reserved.
+ */
+
+#ifndef	_SYS_DSL_DESTROY_H
+#define	_SYS_DSL_DESTROY_H
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+struct nvlist;
+struct dsl_dataset;
+struct dmu_tx;
+
+int dsl_destroy_snapshots_nvl(struct nvlist *, boolean_t,
+    struct nvlist *);
+int dsl_destroy_snapshot(const char *, boolean_t);
+int dsl_destroy_head(const char *);
+int dsl_destroy_head_check_impl(struct dsl_dataset *, int);
+void dsl_destroy_head_sync_impl(struct dsl_dataset *, struct dmu_tx *);
+int dsl_destroy_inconsistent(const char *, void *);
+int dsl_destroy_snapshot_check_impl(struct dsl_dataset *, boolean_t);
+void dsl_destroy_snapshot_sync_impl(struct dsl_dataset *,
+    boolean_t, struct dmu_tx *);
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif /* _SYS_DSL_DESTROY_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/include/sys/dsl_dir.h
@@ -0,0 +1,194 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013 by Delphix. All rights reserved.
+ * Copyright (c) 2014, Joyent, Inc. All rights reserved.
+ * Copyright (c) 2014 Spectra Logic Corporation, All rights reserved.
+ */
+
+#ifndef	_SYS_DSL_DIR_H
+#define	_SYS_DSL_DIR_H
+
+#include <sys/dmu.h>
+#include <sys/dsl_pool.h>
+#include <sys/dsl_synctask.h>
+#include <sys/refcount.h>
+#include <sys/zfs_context.h>
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+struct dsl_dataset;
+
+/*
+ * DD_FIELD_* are strings that are used in the "extensified" dsl_dir zap object.
+ * They should be of the format <reverse-dns>:<field>.
+ */
+
+#define	DD_FIELD_FILESYSTEM_COUNT	"com.joyent:filesystem_count"
+#define	DD_FIELD_SNAPSHOT_COUNT		"com.joyent:snapshot_count"
+
+typedef enum dd_used {
+	DD_USED_HEAD,
+	DD_USED_SNAP,
+	DD_USED_CHILD,
+	DD_USED_CHILD_RSRV,
+	DD_USED_REFRSRV,
+	DD_USED_NUM
+} dd_used_t;
+
+#define	DD_FLAG_USED_BREAKDOWN (1<<0)
+
+typedef struct dsl_dir_phys {
+	uint64_t dd_creation_time; /* not actually used */
+	uint64_t dd_head_dataset_obj;
+	uint64_t dd_parent_obj;
+	uint64_t dd_origin_obj;
+	uint64_t dd_child_dir_zapobj;
+	/*
+	 * how much space our children are accounting for; for leaf
+	 * datasets, == physical space used by fs + snaps
+	 */
+	uint64_t dd_used_bytes;
+	uint64_t dd_compressed_bytes;
+	uint64_t dd_uncompressed_bytes;
+	/* Administrative quota setting */
+	uint64_t dd_quota;
+	/* Administrative reservation setting */
+	uint64_t dd_reserved;
+	uint64_t dd_props_zapobj;
+	uint64_t dd_deleg_zapobj; /* dataset delegation permissions */
+	uint64_t dd_flags;
+	uint64_t dd_used_breakdown[DD_USED_NUM];
+	uint64_t dd_clones; /* dsl_dir objects */
+	uint64_t dd_pad[13]; /* pad out to 256 bytes for good measure */
+} dsl_dir_phys_t;
+
+struct dsl_dir {
+	dmu_buf_user_t dd_dbu;
+
+	/* These are immutable; no lock needed: */
+	uint64_t dd_object;
+	dsl_pool_t *dd_pool;
+
+	/* Stable until user eviction; no lock needed: */
+	dmu_buf_t *dd_dbuf;
+
+	/* protected by lock on pool's dp_dirty_dirs list */
+	txg_node_t dd_dirty_link;
+
+	/* protected by dp_config_rwlock */
+	dsl_dir_t *dd_parent;
+
+	/* Protected by dd_lock */
+	kmutex_t dd_lock;
+	list_t dd_prop_cbs; /* list of dsl_prop_cb_record_t's */
+	timestruc_t dd_snap_cmtime; /* last time snapshot namespace changed */
+	uint64_t dd_origin_txg;
+
+	/* gross estimate of space used by in-flight tx's */
+	uint64_t dd_tempreserved[TXG_SIZE];
+	/* amount of space we expect to write; == amount of dirty data */
+	int64_t dd_space_towrite[TXG_SIZE];
+
+	/* protected by dd_lock; keep at end of struct for better locality */
+	char dd_myname[MAXNAMELEN];
+};
+
+static inline dsl_dir_phys_t *
+dsl_dir_phys(dsl_dir_t *dd)
+{
+	return (dd->dd_dbuf->db_data);
+}
+
+void dsl_dir_rele(dsl_dir_t *dd, void *tag);
+void dsl_dir_async_rele(dsl_dir_t *dd, void *tag);
+int dsl_dir_hold(dsl_pool_t *dp, const char *name, void *tag,
+    dsl_dir_t **, const char **tail);
+int dsl_dir_hold_obj(dsl_pool_t *dp, uint64_t ddobj,
+    const char *tail, void *tag, dsl_dir_t **);
+void dsl_dir_name(dsl_dir_t *dd, char *buf);
+int dsl_dir_namelen(dsl_dir_t *dd);
+uint64_t dsl_dir_create_sync(dsl_pool_t *dp, dsl_dir_t *pds,
+    const char *name, dmu_tx_t *tx);
+void dsl_dir_stats(dsl_dir_t *dd, nvlist_t *nv);
+uint64_t dsl_dir_space_available(dsl_dir_t *dd,
+    dsl_dir_t *ancestor, int64_t delta, int ondiskonly);
+void dsl_dir_dirty(dsl_dir_t *dd, dmu_tx_t *tx);
+void dsl_dir_sync(dsl_dir_t *dd, dmu_tx_t *tx);
+int dsl_dir_tempreserve_space(dsl_dir_t *dd, uint64_t mem,
+    uint64_t asize, uint64_t fsize, uint64_t usize, void **tr_cookiep,
+    dmu_tx_t *tx);
+void dsl_dir_tempreserve_clear(void *tr_cookie, dmu_tx_t *tx);
+void dsl_dir_willuse_space(dsl_dir_t *dd, int64_t space, dmu_tx_t *tx);
+void dsl_dir_diduse_space(dsl_dir_t *dd, dd_used_t type,
+    int64_t used, int64_t compressed, int64_t uncompressed, dmu_tx_t *tx);
+void dsl_dir_transfer_space(dsl_dir_t *dd, int64_t delta,
+    dd_used_t oldtype, dd_used_t newtype, dmu_tx_t *tx);
+int dsl_dir_set_quota(const char *ddname, zprop_source_t source,
+    uint64_t quota);
+int dsl_dir_set_reservation(const char *ddname, zprop_source_t source,
+    uint64_t reservation);
+int dsl_dir_activate_fs_ss_limit(const char *);
+int dsl_fs_ss_limit_check(dsl_dir_t *, uint64_t, zfs_prop_t, dsl_dir_t *,
+    cred_t *);
+void dsl_fs_ss_count_adjust(dsl_dir_t *, int64_t, const char *, dmu_tx_t *);
+int dsl_dir_rename(const char *oldname, const char *newname);
+int dsl_dir_transfer_possible(dsl_dir_t *sdd, dsl_dir_t *tdd,
+    uint64_t fs_cnt, uint64_t ss_cnt, uint64_t space, cred_t *);
+boolean_t dsl_dir_is_clone(dsl_dir_t *dd);
+void dsl_dir_new_refreservation(dsl_dir_t *dd, struct dsl_dataset *ds,
+    uint64_t reservation, cred_t *cr, dmu_tx_t *tx);
+void dsl_dir_snap_cmtime_update(dsl_dir_t *dd);
+timestruc_t dsl_dir_snap_cmtime(dsl_dir_t *dd);
+void dsl_dir_set_reservation_sync_impl(dsl_dir_t *dd, uint64_t value,
+    dmu_tx_t *tx);
+void dsl_dir_zapify(dsl_dir_t *dd, dmu_tx_t *tx);
+boolean_t dsl_dir_is_zapified(dsl_dir_t *dd);
+
+/* internal reserved dir name */
+#define	MOS_DIR_NAME "$MOS"
+#define	ORIGIN_DIR_NAME "$ORIGIN"
+#define	XLATION_DIR_NAME "$XLATION"
+#define	FREE_DIR_NAME "$FREE"
+#define	LEAK_DIR_NAME "$LEAK"
+
+#ifdef ZFS_DEBUG
+#define	dprintf_dd(dd, fmt, ...) do { \
+	if (zfs_flags & ZFS_DEBUG_DPRINTF) { \
+	char *__ds_name = kmem_alloc(MAXNAMELEN + strlen(MOS_DIR_NAME) + 1, \
+	    KM_SLEEP); \
+	dsl_dir_name(dd, __ds_name); \
+	dprintf("dd=%s " fmt, __ds_name, __VA_ARGS__); \
+	kmem_free(__ds_name, MAXNAMELEN + strlen(MOS_DIR_NAME) + 1); \
+	} \
+_NOTE(CONSTCOND) } while (0)
+#else
+#define	dprintf_dd(dd, fmt, ...)
+#endif
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif /* _SYS_DSL_DIR_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/include/sys/dsl_pool.h
@@ -0,0 +1,179 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013 by Delphix. All rights reserved.
+ */
+
+#ifndef	_SYS_DSL_POOL_H
+#define	_SYS_DSL_POOL_H
+
+#include <sys/spa.h>
+#include <sys/txg.h>
+#include <sys/txg_impl.h>
+#include <sys/zfs_context.h>
+#include <sys/zio.h>
+#include <sys/dnode.h>
+#include <sys/ddt.h>
+#include <sys/arc.h>
+#include <sys/bpobj.h>
+#include <sys/bptree.h>
+#include <sys/rrwlock.h>
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+extern int zfs_txg_synctime_ms;
+
+struct objset;
+struct dsl_dir;
+struct dsl_dataset;
+struct dsl_pool;
+struct dmu_tx;
+struct dsl_scan;
+
+extern unsigned long zfs_dirty_data_max;
+extern unsigned long zfs_dirty_data_max_max;
+extern unsigned long zfs_dirty_data_sync;
+extern int zfs_dirty_data_max_percent;
+extern int zfs_dirty_data_max_max_percent;
+extern int zfs_delay_min_dirty_percent;
+extern unsigned long zfs_delay_scale;
+
+/* These macros are for indexing into the zfs_all_blkstats_t. */
+#define	DMU_OT_DEFERRED	DMU_OT_NONE
+#define	DMU_OT_OTHER	DMU_OT_NUMTYPES /* place holder for DMU_OT() types */
+#define	DMU_OT_TOTAL	(DMU_OT_NUMTYPES + 1)
+
+typedef struct zfs_blkstat {
+	uint64_t	zb_count;
+	uint64_t	zb_asize;
+	uint64_t	zb_lsize;
+	uint64_t	zb_psize;
+	uint64_t	zb_gangs;
+	uint64_t	zb_ditto_2_of_2_samevdev;
+	uint64_t	zb_ditto_2_of_3_samevdev;
+	uint64_t	zb_ditto_3_of_3_samevdev;
+} zfs_blkstat_t;
+
+typedef struct zfs_all_blkstats {
+	zfs_blkstat_t	zab_type[DN_MAX_LEVELS + 1][DMU_OT_TOTAL + 1];
+} zfs_all_blkstats_t;
+
+
+typedef struct dsl_pool {
+	/* Immutable */
+	spa_t *dp_spa;
+	struct objset *dp_meta_objset;
+	struct dsl_dir *dp_root_dir;
+	struct dsl_dir *dp_mos_dir;
+	struct dsl_dir *dp_free_dir;
+	struct dsl_dir *dp_leak_dir;
+	struct dsl_dataset *dp_origin_snap;
+	uint64_t dp_root_dir_obj;
+	struct taskq *dp_iput_taskq;
+
+	/* No lock needed - sync context only */
+	blkptr_t dp_meta_rootbp;
+	uint64_t dp_tmp_userrefs_obj;
+	bpobj_t dp_free_bpobj;
+	uint64_t dp_bptree_obj;
+	uint64_t dp_empty_bpobj;
+
+	struct dsl_scan *dp_scan;
+
+	/* Uses dp_lock */
+	kmutex_t dp_lock;
+	kcondvar_t dp_spaceavail_cv;
+	uint64_t dp_dirty_pertxg[TXG_SIZE];
+	uint64_t dp_dirty_total;
+	uint64_t dp_mos_used_delta;
+	uint64_t dp_mos_compressed_delta;
+	uint64_t dp_mos_uncompressed_delta;
+
+	/*
+	 * Time of most recently scheduled (furthest in the future)
+	 * wakeup for delayed transactions.
+	 */
+	hrtime_t dp_last_wakeup;
+
+	/* Has its own locking */
+	tx_state_t dp_tx;
+	txg_list_t dp_dirty_datasets;
+	txg_list_t dp_dirty_zilogs;
+	txg_list_t dp_dirty_dirs;
+	txg_list_t dp_sync_tasks;
+
+	/*
+	 * Protects administrative changes (properties, namespace)
+	 *
+	 * It is only held for write in syncing context.  Therefore
+	 * syncing context does not need to ever have it for read, since
+	 * nobody else could possibly have it for write.
+	 */
+	rrwlock_t dp_config_rwlock;
+
+	zfs_all_blkstats_t *dp_blkstats;
+} dsl_pool_t;
+
+int dsl_pool_init(spa_t *spa, uint64_t txg, dsl_pool_t **dpp);
+int dsl_pool_open(dsl_pool_t *dp);
+void dsl_pool_close(dsl_pool_t *dp);
+dsl_pool_t *dsl_pool_create(spa_t *spa, nvlist_t *zplprops, uint64_t txg);
+void dsl_pool_sync(dsl_pool_t *dp, uint64_t txg);
+void dsl_pool_sync_done(dsl_pool_t *dp, uint64_t txg);
+int dsl_pool_sync_context(dsl_pool_t *dp);
+uint64_t dsl_pool_adjustedsize(dsl_pool_t *dp, boolean_t netfree);
+uint64_t dsl_pool_adjustedfree(dsl_pool_t *dp, boolean_t netfree);
+void dsl_pool_dirty_space(dsl_pool_t *dp, int64_t space, dmu_tx_t *tx);
+void dsl_pool_undirty_space(dsl_pool_t *dp, int64_t space, uint64_t txg);
+void dsl_free(dsl_pool_t *dp, uint64_t txg, const blkptr_t *bpp);
+void dsl_free_sync(zio_t *pio, dsl_pool_t *dp, uint64_t txg,
+    const blkptr_t *bpp);
+void dsl_pool_create_origin(dsl_pool_t *dp, dmu_tx_t *tx);
+void dsl_pool_upgrade_clones(dsl_pool_t *dp, dmu_tx_t *tx);
+void dsl_pool_upgrade_dir_clones(dsl_pool_t *dp, dmu_tx_t *tx);
+void dsl_pool_mos_diduse_space(dsl_pool_t *dp,
+    int64_t used, int64_t comp, int64_t uncomp);
+boolean_t dsl_pool_need_dirty_delay(dsl_pool_t *dp);
+void dsl_pool_config_enter(dsl_pool_t *dp, void *tag);
+void dsl_pool_config_enter_prio(dsl_pool_t *dp, void *tag);
+void dsl_pool_config_exit(dsl_pool_t *dp, void *tag);
+boolean_t dsl_pool_config_held(dsl_pool_t *dp);
+boolean_t dsl_pool_config_held_writer(dsl_pool_t *dp);
+
+taskq_t *dsl_pool_iput_taskq(dsl_pool_t *dp);
+
+int dsl_pool_user_hold(dsl_pool_t *dp, uint64_t dsobj,
+    const char *tag, uint64_t now, dmu_tx_t *tx);
+int dsl_pool_user_release(dsl_pool_t *dp, uint64_t dsobj,
+    const char *tag, dmu_tx_t *tx);
+void dsl_pool_clean_tmp_userrefs(dsl_pool_t *dp);
+int dsl_pool_open_special_dir(dsl_pool_t *dp, const char *name, dsl_dir_t **);
+int dsl_pool_hold(const char *name, void *tag, dsl_pool_t **dp);
+void dsl_pool_rele(dsl_pool_t *dp, void *tag);
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif /* _SYS_DSL_POOL_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/include/sys/dsl_prop.h
@@ -0,0 +1,107 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012 by Delphix. All rights reserved.
+ */
+
+#ifndef	_SYS_DSL_PROP_H
+#define	_SYS_DSL_PROP_H
+
+#include <sys/dmu.h>
+#include <sys/dsl_pool.h>
+#include <sys/zfs_context.h>
+#include <sys/dsl_synctask.h>
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+struct dsl_dataset;
+struct dsl_dir;
+
+/* The callback func may not call into the DMU or DSL! */
+typedef void (dsl_prop_changed_cb_t)(void *arg, uint64_t newval);
+
+typedef struct dsl_prop_cb_record {
+	list_node_t cbr_node; /* link on dd_prop_cbs */
+	struct dsl_dataset *cbr_ds;
+	const char *cbr_propname;
+	dsl_prop_changed_cb_t *cbr_func;
+	void *cbr_arg;
+} dsl_prop_cb_record_t;
+
+typedef struct dsl_props_arg {
+	nvlist_t *pa_props;
+	zprop_source_t pa_source;
+} dsl_props_arg_t;
+
+int dsl_prop_register(struct dsl_dataset *ds, const char *propname,
+    dsl_prop_changed_cb_t *callback, void *cbarg);
+int dsl_prop_unregister(struct dsl_dataset *ds, const char *propname,
+    dsl_prop_changed_cb_t *callback, void *cbarg);
+void dsl_prop_notify_all(struct dsl_dir *dd);
+boolean_t dsl_prop_hascb(struct dsl_dataset *ds);
+
+int dsl_prop_get(const char *ddname, const char *propname,
+    int intsz, int numints, void *buf, char *setpoint);
+int dsl_prop_get_integer(const char *ddname, const char *propname,
+    uint64_t *valuep, char *setpoint);
+int dsl_prop_get_all(objset_t *os, nvlist_t **nvp);
+int dsl_prop_get_received(const char *dsname, nvlist_t **nvp);
+int dsl_prop_get_ds(struct dsl_dataset *ds, const char *propname,
+    int intsz, int numints, void *buf, char *setpoint);
+int dsl_prop_get_int_ds(struct dsl_dataset *ds, const char *propname,
+    uint64_t *valuep);
+int dsl_prop_get_dd(struct dsl_dir *dd, const char *propname,
+    int intsz, int numints, void *buf, char *setpoint,
+    boolean_t snapshot);
+
+void dsl_props_set_sync_impl(struct dsl_dataset *ds, zprop_source_t source,
+    nvlist_t *props, dmu_tx_t *tx);
+void dsl_prop_set_sync_impl(struct dsl_dataset *ds, const char *propname,
+    zprop_source_t source, int intsz, int numints, const void *value,
+    dmu_tx_t *tx);
+int dsl_props_set(const char *dsname, zprop_source_t source, nvlist_t *nvl);
+int dsl_prop_set_int(const char *dsname, const char *propname,
+    zprop_source_t source, uint64_t value);
+int dsl_prop_set_string(const char *dsname, const char *propname,
+    zprop_source_t source, const char *value);
+int dsl_prop_inherit(const char *dsname, const char *propname,
+    zprop_source_t source);
+
+int dsl_prop_predict(dsl_dir_t *dd, const char *propname,
+    zprop_source_t source, uint64_t value, uint64_t *newvalp);
+
+/* flag first receive on or after SPA_VERSION_RECVD_PROPS */
+boolean_t dsl_prop_get_hasrecvd(const char *dsname);
+int dsl_prop_set_hasrecvd(const char *dsname);
+void dsl_prop_unset_hasrecvd(const char *dsname);
+
+void dsl_prop_nvlist_add_uint64(nvlist_t *nv, zfs_prop_t prop, uint64_t value);
+void dsl_prop_nvlist_add_string(nvlist_t *nv,
+    zfs_prop_t prop, const char *value);
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* _SYS_DSL_PROP_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/include/sys/dsl_scan.h
@@ -0,0 +1,147 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2014 by Delphix. All rights reserved.
+ */
+
+#ifndef	_SYS_DSL_SCAN_H
+#define	_SYS_DSL_SCAN_H
+
+#include <sys/zfs_context.h>
+#include <sys/zio.h>
+#include <sys/ddt.h>
+#include <sys/bplist.h>
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+struct objset;
+struct dsl_dir;
+struct dsl_dataset;
+struct dsl_pool;
+struct dmu_tx;
+
+/*
+ * All members of this structure must be uint64_t, for byteswap
+ * purposes.
+ */
+typedef struct dsl_scan_phys {
+	uint64_t scn_func; /* pool_scan_func_t */
+	uint64_t scn_state; /* dsl_scan_state_t */
+	uint64_t scn_queue_obj;
+	uint64_t scn_min_txg;
+	uint64_t scn_max_txg;
+	uint64_t scn_cur_min_txg;
+	uint64_t scn_cur_max_txg;
+	uint64_t scn_start_time;
+	uint64_t scn_end_time;
+	uint64_t scn_to_examine; /* total bytes to be scanned */
+	uint64_t scn_examined; /* bytes scanned so far */
+	uint64_t scn_to_process;
+	uint64_t scn_processed;
+	uint64_t scn_errors;	/* scan I/O error count */
+	uint64_t scn_ddt_class_max;
+	ddt_bookmark_t scn_ddt_bookmark;
+	zbookmark_phys_t scn_bookmark;
+	uint64_t scn_flags; /* dsl_scan_flags_t */
+} dsl_scan_phys_t;
+
+#define	SCAN_PHYS_NUMINTS (sizeof (dsl_scan_phys_t) / sizeof (uint64_t))
+
+typedef enum dsl_scan_flags {
+	DSF_VISIT_DS_AGAIN = 1<<0,
+} dsl_scan_flags_t;
+
+#define	DSL_SCAN_FLAGS_MASK (DSF_VISIT_DS_AGAIN)
+
+/*
+ * Every pool will have one dsl_scan_t and this structure will contain
+ * in-memory information about the scan and a pointer to the on-disk
+ * representation (i.e. dsl_scan_phys_t). Most of the state of the scan
+ * is contained on-disk to allow the scan to resume in the event of a reboot
+ * or panic. This structure maintains information about the behavior of a
+ * running scan, some caching information, and how it should traverse the pool.
+ *
+ * The following members of this structure direct the behavior of the scan:
+ *
+ * scn_pausing -	a scan that cannot be completed in a single txg or
+ *			has exceeded its allotted time will need to pause.
+ *			When this flag is set the scanner will stop traversing
+ *			the pool and write out the current state to disk.
+ *
+ * scn_restart_txg -	directs the scanner to either restart or start a
+ *			a scan at the specified txg value.
+ *
+ * scn_done_txg -	when a scan completes its traversal it will set
+ *			the completion txg to the next txg. This is necessary
+ *			to ensure that any blocks that were freed during
+ *			the scan but have not yet been processed (i.e deferred
+ *			frees) are accounted for.
+ *
+ * This structure also maintains information about deferred frees which are
+ * a special kind of traversal. Deferred free can exist in either a bptree or
+ * a bpobj structure. The scn_is_bptree flag will indicate the type of
+ * deferred free that is in progress. If the deferred free is part of an
+ * asynchronous destroy then the scn_async_destroying flag will be set.
+ */
+typedef struct dsl_scan {
+	struct dsl_pool *scn_dp;
+
+	boolean_t scn_pausing;
+	uint64_t scn_restart_txg;
+	uint64_t scn_done_txg;
+	uint64_t scn_sync_start_time;
+	zio_t *scn_zio_root;
+
+	/* for freeing blocks */
+	boolean_t scn_is_bptree;
+	boolean_t scn_async_destroying;
+	boolean_t scn_async_stalled;
+
+	/* for debugging / information */
+	uint64_t scn_visited_this_txg;
+
+	dsl_scan_phys_t scn_phys;
+} dsl_scan_t;
+
+int dsl_scan_init(struct dsl_pool *dp, uint64_t txg);
+void dsl_scan_fini(struct dsl_pool *dp);
+void dsl_scan_sync(struct dsl_pool *, dmu_tx_t *);
+int dsl_scan_cancel(struct dsl_pool *);
+int dsl_scan(struct dsl_pool *, pool_scan_func_t);
+void dsl_resilver_restart(struct dsl_pool *, uint64_t txg);
+boolean_t dsl_scan_resilvering(struct dsl_pool *dp);
+boolean_t dsl_dataset_unstable(struct dsl_dataset *ds);
+void dsl_scan_ddt_entry(dsl_scan_t *scn, enum zio_checksum checksum,
+    ddt_entry_t *dde, dmu_tx_t *tx);
+void dsl_scan_ds_destroyed(struct dsl_dataset *ds, struct dmu_tx *tx);
+void dsl_scan_ds_snapshotted(struct dsl_dataset *ds, struct dmu_tx *tx);
+void dsl_scan_ds_clone_swapped(struct dsl_dataset *ds1, struct dsl_dataset *ds2,
+    struct dmu_tx *tx);
+boolean_t dsl_scan_active(dsl_scan_t *scn);
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif /* _SYS_DSL_SCAN_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/include/sys/dsl_synctask.h
@@ -0,0 +1,93 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2014 by Delphix. All rights reserved.
+ */
+
+#ifndef	_SYS_DSL_SYNCTASK_H
+#define	_SYS_DSL_SYNCTASK_H
+
+#include <sys/txg.h>
+#include <sys/zfs_context.h>
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+struct dsl_pool;
+
+typedef int (dsl_checkfunc_t)(void *, dmu_tx_t *);
+typedef void (dsl_syncfunc_t)(void *, dmu_tx_t *);
+
+typedef enum zfs_space_check {
+	/*
+	 * Normal space check: if there is less than 3.2% free space,
+	 * the operation will fail.  Operations which are logically
+	 * creating things should use this (e.g. "zfs create", "zfs snapshot").
+	 * User writes (via the ZPL / ZVOL) also fail at this point.
+	 */
+	ZFS_SPACE_CHECK_NORMAL,
+
+	/*
+	 * Space check allows use of half the slop space.  If there
+	 * is less than 1.6% free space, the operation will fail.  Most
+	 * operations should use this (e.g. "zfs set", "zfs rename"),
+	 * because we want them to succeed even after user writes are failing,
+	 * so that they can be used as part of the space recovery process.
+	 */
+	ZFS_SPACE_CHECK_RESERVED,
+
+	/*
+	 * No space check is performed.  Only operations which we expect to
+	 * result in a net reduction in space should use this
+	 * (e.g. "zfs destroy". Setting quotas & reservations also uses
+	 * this because it needs to circumvent the quota/reservation checks).
+	 *
+	 * See also the comments above spa_slop_shift.
+	 */
+	ZFS_SPACE_CHECK_NONE,
+} zfs_space_check_t;
+
+typedef struct dsl_sync_task {
+	txg_node_t dst_node;
+	struct dsl_pool *dst_pool;
+	uint64_t dst_txg;
+	int dst_space;
+	zfs_space_check_t dst_space_check;
+	dsl_checkfunc_t *dst_checkfunc;
+	dsl_syncfunc_t *dst_syncfunc;
+	void *dst_arg;
+	int dst_error;
+	boolean_t dst_nowaiter;
+} dsl_sync_task_t;
+
+void dsl_sync_task_sync(dsl_sync_task_t *, dmu_tx_t *);
+int dsl_sync_task(const char *, dsl_checkfunc_t *,
+    dsl_syncfunc_t *, void *, int, zfs_space_check_t);
+void dsl_sync_task_nowait(struct dsl_pool *, dsl_syncfunc_t *,
+    void *, int, zfs_space_check_t, dmu_tx_t *);
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif /* _SYS_DSL_SYNCTASK_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/include/sys/dsl_userhold.h
@@ -0,0 +1,57 @@
+
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012 by Delphix. All rights reserved.
+ * Copyright (c) 2012, Joyent, Inc. All rights reserved.
+ * Copyright (c) 2013 Steven Hartland. All rights reserved.
+ */
+
+#ifndef	_SYS_DSL_USERHOLD_H
+#define	_SYS_DSL_USERHOLD_H
+
+#include <sys/nvpair.h>
+#include <sys/types.h>
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+struct dsl_pool;
+struct dsl_dataset;
+struct dmu_tx;
+
+int dsl_dataset_user_hold(nvlist_t *holds, minor_t cleanup_minor,
+    nvlist_t *errlist);
+int dsl_dataset_user_release(nvlist_t *holds, nvlist_t *errlist);
+int dsl_dataset_get_holds(const char *dsname, nvlist_t *nvl);
+void dsl_dataset_user_release_tmp(struct dsl_pool *dp, nvlist_t *holds);
+int dsl_dataset_user_hold_check_one(struct dsl_dataset *ds, const char *htag,
+    boolean_t temphold, struct dmu_tx *tx);
+void dsl_dataset_user_hold_sync_one(struct dsl_dataset *ds, const char *htag,
+    minor_t minor, uint64_t now, struct dmu_tx *tx);
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif /* _SYS_DSL_USERHOLD_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/include/sys/efi_partition.h
@@ -0,0 +1,244 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
+ */
+
+#ifndef	_SYS_EFI_PARTITION_H
+#define	_SYS_EFI_PARTITION_H
+
+#include <sys/uuid.h>
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+/*
+ * GUID Partition Table Header
+ */
+
+#define	EFI_MIN_LABEL_SIZE 92
+#define	EFI_LABEL_SIZE	512
+#define	LEN_EFI_PAD	(EFI_LABEL_SIZE - \
+			    ((5 * sizeof (diskaddr_t)) + \
+			    (7 * sizeof (uint_t)) + \
+			    (8 * sizeof (char)) + \
+			    (1 * (sizeof (struct uuid)))))
+
+#define	EFI_SIGNATURE	0x5452415020494645ULL
+
+/* EFI Guid Partition Table Header -- little endian on-disk format */
+typedef struct efi_gpt {
+	uint64_t	efi_gpt_Signature;
+	uint_t		efi_gpt_Revision;
+	uint_t		efi_gpt_HeaderSize;
+	uint_t		efi_gpt_HeaderCRC32;
+	uint_t		efi_gpt_Reserved1;
+	diskaddr_t	efi_gpt_MyLBA;
+	diskaddr_t	efi_gpt_AlternateLBA;
+	diskaddr_t	efi_gpt_FirstUsableLBA;
+	diskaddr_t	efi_gpt_LastUsableLBA;
+	struct uuid	efi_gpt_DiskGUID;
+	diskaddr_t	efi_gpt_PartitionEntryLBA;
+	uint_t		efi_gpt_NumberOfPartitionEntries;
+	uint_t		efi_gpt_SizeOfPartitionEntry;
+	uint_t		efi_gpt_PartitionEntryArrayCRC32;
+	char		efi_gpt_Reserved2[LEN_EFI_PAD];
+} efi_gpt_t;
+
+/* EFI Guid Partition Entry Attributes -- little endian format */
+typedef struct efi_gpe_Attrs {
+	uint32_t	PartitionAttrs		:16,
+			Reserved2		:16;
+	uint32_t	Reserved1		:31,
+			RequiredPartition	:1;
+} efi_gpe_Attrs_t;
+
+/*
+ * 6a96237f-1dd2-11b2-99a6-080020736631	V_UNASSIGNED (not used as such)
+ * 6a82cb45-1dd2-11b2-99a6-080020736631	V_BOOT
+ * 6a85cf4d-1dd2-11b2-99a6-080020736631	V_ROOT
+ * 6a87c46f-1dd2-11b2-99a6-080020736631	V_SWAP
+ * 6a898cc3-1dd2-11b2-99a6-080020736631	V_USR
+ * 6a8b642b-1dd2-11b2-99a6-080020736631	V_BACKUP
+ * 6a8d2ac7-1dd2-11b2-99a6-080020736631	V_STAND (not used)
+ * 6a8ef2e9-1dd2-11b2-99a6-080020736631	V_VAR
+ * 6a90ba39-1dd2-11b2-99a6-080020736631	V_HOME
+ * 6a9283a5-1dd2-11b2-99a6-080020736631	V_ALTSCTR
+ * 6a945a3b-1dd2-11b2-99a6-080020736631	V_CACHE
+ */
+
+#define	EFI_UNUSED	{ 0x00000000, 0x0000, 0x0000, 0x00, 0x00, \
+			    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
+#define	EFI_RESV1	{ 0x6a96237f, 0x1dd2, 0x11b2, 0x99, 0xa6, \
+			    { 0x08, 0x00, 0x20, 0x73, 0x66, 0x31 } }
+#define	EFI_BOOT	{ 0x6a82cb45, 0x1dd2, 0x11b2, 0x99, 0xa6, \
+			    { 0x08, 0x00, 0x20, 0x73, 0x66, 0x31 } }
+#define	EFI_ROOT	{ 0x6a85cf4d, 0x1dd2, 0x11b2, 0x99, 0xa6, \
+			    { 0x08, 0x00, 0x20, 0x73, 0x66, 0x31 } }
+#define	EFI_SWAP	{ 0x6a87c46f, 0x1dd2, 0x11b2, 0x99, 0xa6, \
+			    { 0x08, 0x00, 0x20, 0x73, 0x66, 0x31 } }
+#define	EFI_USR		{ 0x6a898cc3, 0x1dd2, 0x11b2, 0x99, 0xa6, \
+			    { 0x08, 0x00, 0x20, 0x73, 0x66, 0x31 } }
+#define	EFI_BACKUP	{ 0x6a8b642b, 0x1dd2, 0x11b2, 0x99, 0xa6, \
+			    { 0x08, 0x00, 0x20, 0x73, 0x66, 0x31 } }
+#define	EFI_RESV2	{ 0x6a8d2ac7, 0x1dd2, 0x11b2, 0x99, 0xa6, \
+			    { 0x08, 0x00, 0x20, 0x73, 0x66, 0x31 } }
+#define	EFI_VAR		{ 0x6a8ef2e9, 0x1dd2, 0x11b2, 0x99, 0xa6, \
+			    { 0x08, 0x00, 0x20, 0x73, 0x66, 0x31 } }
+#define	EFI_HOME	{ 0x6a90ba39, 0x1dd2, 0x11b2, 0x99, 0xa6, \
+			    { 0x08, 0x00, 0x20, 0x73, 0x66, 0x31 } }
+#define	EFI_ALTSCTR	{ 0x6a9283a5, 0x1dd2, 0x11b2, 0x99, 0xa6, \
+			    { 0x08, 0x00, 0x20, 0x73, 0x66, 0x31 } }
+#define	EFI_RESERVED	{ 0x6a945a3b, 0x1dd2, 0x11b2, 0x99, 0xa6, \
+			    { 0x08, 0x00, 0x20, 0x73, 0x66, 0x31 } }
+#define	EFI_SYSTEM	{ 0xC12A7328, 0xF81F, 0x11d2, 0xBA, 0x4B, \
+			    { 0x00, 0xA0, 0xC9, 0x3E, 0xC9, 0x3B } }
+#define	EFI_LEGACY_MBR	{ 0x024DEE41, 0x33E7, 0x11d3, 0x9D, 0x69, \
+			    { 0x00, 0x08, 0xC7, 0x81, 0xF3, 0x9F } }
+#define	EFI_SYMC_PUB	{ 0x6a9630d1, 0x1dd2, 0x11b2, 0x99, 0xa6, \
+			    { 0x08, 0x00, 0x20, 0x73, 0x66, 0x31 } }
+#define	EFI_SYMC_CDS	{ 0x6a980767, 0x1dd2, 0x11b2, 0x99, 0xa6, \
+			    { 0x08, 0x00, 0x20, 0x73, 0x66, 0x31 } }
+#define	EFI_MSFT_RESV	{ 0xE3C9E316, 0x0B5C, 0x4DB8, 0x81, 0x7D, \
+			    { 0xF9, 0x2D, 0xF0, 0x02, 0x15, 0xAE } }
+#define	EFI_DELL_BASIC	{ 0xebd0a0a2, 0xb9e5, 0x4433, 0x87, 0xc0, \
+			    { 0x68, 0xb6, 0xb7, 0x26, 0x99, 0xc7 } }
+#define	EFI_DELL_RAID	{ 0xa19d880f, 0x05fc, 0x4d3b, 0xa0, 0x06, \
+			    { 0x74, 0x3f, 0x0f, 0x84, 0x91, 0x1e } }
+#define	EFI_DELL_SWAP	{ 0x0657fd6d, 0xa4ab, 0x43c4, 0x84, 0xe5, \
+			    { 0x09, 0x33, 0xc8, 0x4b, 0x4f, 0x4f } }
+#define	EFI_DELL_LVM	{ 0xe6d6d379, 0xf507, 0x44c2, 0xa2, 0x3c, \
+			    { 0x23, 0x8f, 0x2a, 0x3d, 0xf9, 0x28 } }
+#define	EFI_DELL_RESV	{ 0x8da63339, 0x0007, 0x60c0, 0xc4, 0x36, \
+			    { 0x08, 0x3a, 0xc8, 0x23, 0x09, 0x08 } }
+#define	EFI_AAPL_HFS	{ 0x48465300, 0x0000, 0x11aa, 0xaa, 0x11, \
+			    { 0x00, 0x30, 0x65, 0x43, 0xec, 0xac } }
+#define	EFI_AAPL_UFS	{ 0x55465300, 0x0000, 0x11aa, 0xaa, 0x11, \
+			    { 0x00, 0x30, 0x65, 0x43, 0xec, 0xac } }
+
+/* minimum # of bytes for partition table entires, per EFI spec */
+#define	EFI_MIN_ARRAY_SIZE	(16 * 1024)
+
+#define	EFI_PART_NAME_LEN	36
+
+/* size of the "reserved" partition, in blocks */
+#define	EFI_MIN_RESV_SIZE	(16 * 1024)
+
+/* EFI Guid Partition Entry */
+typedef struct efi_gpe {
+	struct uuid	efi_gpe_PartitionTypeGUID;
+	struct uuid	efi_gpe_UniquePartitionGUID;
+	diskaddr_t	efi_gpe_StartingLBA;
+	diskaddr_t	efi_gpe_EndingLBA;
+	efi_gpe_Attrs_t	efi_gpe_Attributes;
+	ushort_t	efi_gpe_PartitionName[EFI_PART_NAME_LEN];
+} efi_gpe_t;
+
+/*
+ * passed to the useful (we hope) routines (efi_alloc_and_read and
+ * efi_write) that take this VTOC-like struct.  These routines handle
+ * converting this struct into the EFI struct, generate UUIDs and
+ * checksums, and perform any necessary byte-swapping to the on-disk
+ * format.
+ */
+/* Solaris library abstraction for EFI partitons */
+typedef struct dk_part	{
+	diskaddr_t	p_start;	/* starting LBA */
+	diskaddr_t	p_size;		/* size in blocks */
+	struct uuid	p_guid;		/* partion type GUID */
+	ushort_t	p_tag;		/* converted to part'n type GUID */
+	ushort_t	p_flag;		/* attributes */
+	char		p_name[EFI_PART_NAME_LEN]; /* partition name */
+	struct uuid	p_uguid;	/* unique partition GUID */
+	uint_t		p_resv[8];	/* future use - set to zero */
+} dk_part_t;
+
+/* Solaris library abstraction for an EFI GPT */
+#define	EFI_VERSION102		0x00010002
+#define	EFI_VERSION100		0x00010000
+#define	EFI_VERSION_CURRENT	EFI_VERSION100
+typedef struct dk_gpt {
+	uint_t		efi_version;	/* set to EFI_VERSION_CURRENT */
+	uint_t		efi_nparts;	/* number of partitions below */
+	uint_t		efi_part_size;	/* size of each partition entry */
+					/* efi_part_size is unused */
+	uint_t		efi_lbasize;	/* size of block in bytes */
+	diskaddr_t	efi_last_lba;	/* last block on the disk */
+	diskaddr_t	efi_first_u_lba; /* first block after labels */
+	diskaddr_t	efi_last_u_lba;	/* last block before backup labels */
+	struct uuid	efi_disk_uguid;	/* unique disk GUID */
+	uint_t		efi_flags;
+	uint_t		efi_reserved1;	/* future use - set to zero */
+	diskaddr_t	efi_altern_lba;	/* lba of alternate GPT header */
+	uint_t		efi_reserved[12]; /* future use - set to zero */
+	struct dk_part	efi_parts[1];	/* array of partitions */
+} dk_gpt_t;
+
+/* possible values for "efi_flags" */
+#define	EFI_GPT_PRIMARY_CORRUPT	0x1	/* primary label corrupt */
+
+/* the private ioctl between libefi and the driver */
+typedef struct dk_efi {
+	diskaddr_t	 dki_lba;	/* starting block */
+	len_t		 dki_length;	/* length in bytes */
+	union {
+		efi_gpt_t 	*_dki_data;
+		uint64_t	_dki_data_64;
+	} dki_un;
+#define	dki_data	dki_un._dki_data
+#define	dki_data_64	dki_un._dki_data_64
+} dk_efi_t;
+
+struct partition64 {
+	struct uuid	p_type;
+	uint_t		p_partno;
+	uint_t		p_resv1;
+	diskaddr_t	p_start;
+	diskaddr_t	p_size;
+};
+
+/*
+ * Number of EFI partitions
+ */
+#if defined(__linux__)
+#define	EFI_NUMPAR	128 /* Expected by parted-1.8.1 */
+#else
+#define	EFI_NUMPAR	9
+#endif
+
+#ifndef _KERNEL
+extern	int	efi_alloc_and_init(int, uint32_t, struct dk_gpt **);
+extern	int	efi_alloc_and_read(int, struct dk_gpt **);
+extern	int	efi_write(int, struct dk_gpt *);
+extern	int	efi_rescan(int);
+extern	void	efi_free(struct dk_gpt *);
+extern	int	efi_type(int);
+extern	void	efi_err_check(struct dk_gpt *);
+extern	int	efi_auto_sense(int fd, struct dk_gpt **);
+extern	int	efi_use_whole_disk(int fd);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _SYS_EFI_PARTITION_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/include/sys/fm/Makefile.am
@@ -0,0 +1,21 @@
+SUBDIRS = fs
+
+COMMON_H = \
+	$(top_srcdir)/include/sys/fm/protocol.h \
+	$(top_srcdir)/include/sys/fm/util.h
+
+KERNEL_H =
+
+USER_H =
+
+EXTRA_DIST = $(COMMON_H) $(KERNEL_H) $(USER_H)
+
+if CONFIG_USER
+libzfsdir = $(includedir)/libzfs/sys/fm
+libzfs_HEADERS = $(COMMON_H) $(USER_H)
+endif
+
+if CONFIG_KERNEL
+kerneldir = @prefix@/src/zfs-$(VERSION)/include/sys/fm
+kernel_HEADERS = $(COMMON_H) $(KERNEL_H)
+endif
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/include/sys/fm/Makefile.in
@@ -0,0 +1,872 @@
+# Makefile.in generated by automake 1.15 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2014 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+VPATH = @srcdir@
+am__is_gnu_make = { \
+  if test -z '$(MAKELEVEL)'; then \
+    false; \
+  elif test -n '$(MAKE_HOST)'; then \
+    true; \
+  elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+    true; \
+  else \
+    false; \
+  fi; \
+}
+am__make_running_with_option = \
+  case $${target_option-} in \
+      ?) ;; \
+      *) echo "am__make_running_with_option: internal error: invalid" \
+              "target option '$${target_option-}' specified" >&2; \
+         exit 1;; \
+  esac; \
+  has_opt=no; \
+  sane_makeflags=$$MAKEFLAGS; \
+  if $(am__is_gnu_make); then \
+    sane_makeflags=$$MFLAGS; \
+  else \
+    case $$MAKEFLAGS in \
+      *\\[\ \	]*) \
+        bs=\\; \
+        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
+    esac; \
+  fi; \
+  skip_next=no; \
+  strip_trailopt () \
+  { \
+    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+  }; \
+  for flg in $$sane_makeflags; do \
+    test $$skip_next = yes && { skip_next=no; continue; }; \
+    case $$flg in \
+      *=*|--*) continue;; \
+        -*I) strip_trailopt 'I'; skip_next=yes;; \
+      -*I?*) strip_trailopt 'I';; \
+        -*O) strip_trailopt 'O'; skip_next=yes;; \
+      -*O?*) strip_trailopt 'O';; \
+        -*l) strip_trailopt 'l'; skip_next=yes;; \
+      -*l?*) strip_trailopt 'l';; \
+      -[dEDm]) skip_next=yes;; \
+      -[JT]) skip_next=yes;; \
+    esac; \
+    case $$flg in \
+      *$$target_option*) has_opt=yes; break;; \
+    esac; \
+  done; \
+  test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+target_triplet = @target@
+subdir = include/sys/fm
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/config/always-no-bool-compare.m4 \
+	$(top_srcdir)/config/always-no-unused-but-set-variable.m4 \
+	$(top_srcdir)/config/dkms.m4 \
+	$(top_srcdir)/config/kernel-acl.m4 \
+	$(top_srcdir)/config/kernel-automount.m4 \
+	$(top_srcdir)/config/kernel-bdev-block-device-operations.m4 \
+	$(top_srcdir)/config/kernel-bdev-logical-size.m4 \
+	$(top_srcdir)/config/kernel-bdev-physical-size.m4 \
+	$(top_srcdir)/config/kernel-bdi-setup-and-register.m4 \
+	$(top_srcdir)/config/kernel-bio-bvec-iter.m4 \
+	$(top_srcdir)/config/kernel-bio-end-io-t-args.m4 \
+	$(top_srcdir)/config/kernel-bio-failfast.m4 \
+	$(top_srcdir)/config/kernel-bio-rw-barrier.m4 \
+	$(top_srcdir)/config/kernel-bio-rw-discard.m4 \
+	$(top_srcdir)/config/kernel-blk-queue-flush.m4 \
+	$(top_srcdir)/config/kernel-blk-queue-max-hw-sectors.m4 \
+	$(top_srcdir)/config/kernel-blk-queue-max-segments.m4 \
+	$(top_srcdir)/config/kernel-blkdev-get-by-path.m4 \
+	$(top_srcdir)/config/kernel-blkdev-get.m4 \
+	$(top_srcdir)/config/kernel-block-device-operations-release-void.m4 \
+	$(top_srcdir)/config/kernel-check-disk-size-change.m4 \
+	$(top_srcdir)/config/kernel-clear-inode.m4 \
+	$(top_srcdir)/config/kernel-commit-metadata.m4 \
+	$(top_srcdir)/config/kernel-create-nameidata.m4 \
+	$(top_srcdir)/config/kernel-current_bio_tail.m4 \
+	$(top_srcdir)/config/kernel-d-make-root.m4 \
+	$(top_srcdir)/config/kernel-d-obtain-alias.m4 \
+	$(top_srcdir)/config/kernel-d-prune-aliases.m4 \
+	$(top_srcdir)/config/kernel-declare-event-class.m4 \
+	$(top_srcdir)/config/kernel-dentry-operations.m4 \
+	$(top_srcdir)/config/kernel-dirty-inode.m4 \
+	$(top_srcdir)/config/kernel-discard-granularity.m4 \
+	$(top_srcdir)/config/kernel-elevator-change.m4 \
+	$(top_srcdir)/config/kernel-encode-fh-inode.m4 \
+	$(top_srcdir)/config/kernel-evict-inode.m4 \
+	$(top_srcdir)/config/kernel-fallocate.m4 \
+	$(top_srcdir)/config/kernel-file-inode.m4 \
+	$(top_srcdir)/config/kernel-fmode-t.m4 \
+	$(top_srcdir)/config/kernel-follow-down-one.m4 \
+	$(top_srcdir)/config/kernel-fsync.m4 \
+	$(top_srcdir)/config/kernel-generic_io_acct.m4 \
+	$(top_srcdir)/config/kernel-get-disk-ro.m4 \
+	$(top_srcdir)/config/kernel-get-gendisk.m4 \
+	$(top_srcdir)/config/kernel-get-link.m4 \
+	$(top_srcdir)/config/kernel-insert-inode-locked.m4 \
+	$(top_srcdir)/config/kernel-invalidate-bdev-args.m4 \
+	$(top_srcdir)/config/kernel-is_owner_or_cap.m4 \
+	$(top_srcdir)/config/kernel-kmap-atomic-args.m4 \
+	$(top_srcdir)/config/kernel-kobj-name-len.m4 \
+	$(top_srcdir)/config/kernel-lookup-bdev.m4 \
+	$(top_srcdir)/config/kernel-lookup-nameidata.m4 \
+	$(top_srcdir)/config/kernel-lseek-execute.m4 \
+	$(top_srcdir)/config/kernel-mk-request-fn.m4 \
+	$(top_srcdir)/config/kernel-mkdir-umode-t.m4 \
+	$(top_srcdir)/config/kernel-mount-nodev.m4 \
+	$(top_srcdir)/config/kernel-open-bdev-exclusive.m4 \
+	$(top_srcdir)/config/kernel-put-link.m4 \
+	$(top_srcdir)/config/kernel-security-inode-init.m4 \
+	$(top_srcdir)/config/kernel-set-nlink.m4 \
+	$(top_srcdir)/config/kernel-sget-args.m4 \
+	$(top_srcdir)/config/kernel-show-options.m4 \
+	$(top_srcdir)/config/kernel-shrink.m4 \
+	$(top_srcdir)/config/kernel-truncate-range.m4 \
+	$(top_srcdir)/config/kernel-truncate-setsize.m4 \
+	$(top_srcdir)/config/kernel-vfs-iterate.m4 \
+	$(top_srcdir)/config/kernel-vfs-rw-iterate.m4 \
+	$(top_srcdir)/config/kernel-xattr-handler.m4 \
+	$(top_srcdir)/config/kernel.m4 $(top_srcdir)/config/libtool.m4 \
+	$(top_srcdir)/config/ltoptions.m4 \
+	$(top_srcdir)/config/ltsugar.m4 \
+	$(top_srcdir)/config/ltversion.m4 \
+	$(top_srcdir)/config/lt~obsolete.m4 \
+	$(top_srcdir)/config/mount-helper.m4 \
+	$(top_srcdir)/config/user-arch.m4 \
+	$(top_srcdir)/config/user-dracut.m4 \
+	$(top_srcdir)/config/user-frame-larger-than.m4 \
+	$(top_srcdir)/config/user-libblkid.m4 \
+	$(top_srcdir)/config/user-libuuid.m4 \
+	$(top_srcdir)/config/user-runstatedir.m4 \
+	$(top_srcdir)/config/user-systemd.m4 \
+	$(top_srcdir)/config/user-sysvinit.m4 \
+	$(top_srcdir)/config/user-udev.m4 \
+	$(top_srcdir)/config/user-zlib.m4 $(top_srcdir)/config/user.m4 \
+	$(top_srcdir)/config/zfs-build.m4 \
+	$(top_srcdir)/config/zfs-meta.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(am__kernel_HEADERS_DIST) \
+	$(am__libzfs_HEADERS_DIST) $(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/zfs_config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo "  GEN     " $@;
+am__v_GEN_1 = 
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 = 
+SOURCES =
+DIST_SOURCES =
+RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \
+	ctags-recursive dvi-recursive html-recursive info-recursive \
+	install-data-recursive install-dvi-recursive \
+	install-exec-recursive install-html-recursive \
+	install-info-recursive install-pdf-recursive \
+	install-ps-recursive install-recursive installcheck-recursive \
+	installdirs-recursive pdf-recursive ps-recursive \
+	tags-recursive uninstall-recursive
+am__can_run_installinfo = \
+  case $$AM_UPDATE_INFO_DIR in \
+    n|no|NO) false;; \
+    *) (install-info --version) >/dev/null 2>&1;; \
+  esac
+am__kernel_HEADERS_DIST = $(top_srcdir)/include/sys/fm/protocol.h \
+	$(top_srcdir)/include/sys/fm/util.h
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+    $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+    *) f=$$p;; \
+  esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+  srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+  for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+  for p in $$list; do echo "$$p $$p"; done | \
+  sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+  $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+    if (++n[$$2] == $(am__install_max)) \
+      { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+    END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+  sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+  sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+  test -z "$$files" \
+    || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+    || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+         $(am__cd) "$$dir" && rm -f $$files; }; \
+  }
+am__installdirs = "$(DESTDIR)$(kerneldir)" "$(DESTDIR)$(libzfsdir)"
+am__libzfs_HEADERS_DIST = $(top_srcdir)/include/sys/fm/protocol.h \
+	$(top_srcdir)/include/sys/fm/util.h
+HEADERS = $(kernel_HEADERS) $(libzfs_HEADERS)
+RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive	\
+  distclean-recursive maintainer-clean-recursive
+am__recursive_targets = \
+  $(RECURSIVE_TARGETS) \
+  $(RECURSIVE_CLEAN_TARGETS) \
+  $(am__extra_recursive_targets)
+AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \
+	distdir
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates.  Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+  BEGIN { nonempty = 0; } \
+  { items[$$0] = 1; nonempty = 1; } \
+  END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique.  This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+  list='$(am__tagged_files)'; \
+  unique=`for i in $$list; do \
+    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+  done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+DIST_SUBDIRS = $(SUBDIRS)
+am__DIST_COMMON = $(srcdir)/Makefile.in
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+am__relativize = \
+  dir0=`pwd`; \
+  sed_first='s,^\([^/]*\)/.*$$,\1,'; \
+  sed_rest='s,^[^/]*/*,,'; \
+  sed_last='s,^.*/\([^/]*\)$$,\1,'; \
+  sed_butlast='s,/*[^/]*$$,,'; \
+  while test -n "$$dir1"; do \
+    first=`echo "$$dir1" | sed -e "$$sed_first"`; \
+    if test "$$first" != "."; then \
+      if test "$$first" = ".."; then \
+        dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \
+        dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \
+      else \
+        first2=`echo "$$dir2" | sed -e "$$sed_first"`; \
+        if test "$$first2" = "$$first"; then \
+          dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \
+        else \
+          dir2="../$$dir2"; \
+        fi; \
+        dir0="$$dir0"/"$$first"; \
+      fi; \
+    fi; \
+    dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \
+  done; \
+  reldir="$$dir2"
+ACLOCAL = @ACLOCAL@
+ALIEN = @ALIEN@
+ALIEN_VERSION = @ALIEN_VERSION@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCAS = @CCAS@
+CCASDEPMODE = @CCASDEPMODE@
+CCASFLAGS = @CCASFLAGS@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEBUG_CFLAGS = @DEBUG_CFLAGS@
+DEBUG_DMU_TX = @DEBUG_DMU_TX@
+DEBUG_STACKFLAGS = @DEBUG_STACKFLAGS@
+DEBUG_ZFS = @DEBUG_ZFS@
+DEFAULT_INITCONF_DIR = @DEFAULT_INITCONF_DIR@
+DEFAULT_INIT_DIR = @DEFAULT_INIT_DIR@
+DEFAULT_INIT_SCRIPT = @DEFAULT_INIT_SCRIPT@
+DEFAULT_PACKAGE = @DEFAULT_PACKAGE@
+DEFINE_INITRAMFS = @DEFINE_INITRAMFS@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DPKG = @DPKG@
+DPKGBUILD = @DPKGBUILD@
+DPKGBUILD_VERSION = @DPKGBUILD_VERSION@
+DPKG_VERSION = @DPKG_VERSION@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+FRAME_LARGER_THAN = @FRAME_LARGER_THAN@
+GREP = @GREP@
+HAVE_ALIEN = @HAVE_ALIEN@
+HAVE_DPKG = @HAVE_DPKG@
+HAVE_DPKGBUILD = @HAVE_DPKGBUILD@
+HAVE_RPM = @HAVE_RPM@
+HAVE_RPMBUILD = @HAVE_RPMBUILD@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+KERNELCPPFLAGS = @KERNELCPPFLAGS@
+KERNELMAKE_PARAMS = @KERNELMAKE_PARAMS@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBBLKID = @LIBBLKID@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIBUUID = @LIBUUID@
+LINUX = @LINUX@
+LINUX_OBJ = @LINUX_OBJ@
+LINUX_SYMBOLS = @LINUX_SYMBOLS@
+LINUX_VERSION = @LINUX_VERSION@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NO_BOOL_COMPARE = @NO_BOOL_COMPARE@
+NO_UNUSED_BUT_SET_VARIABLE = @NO_UNUSED_BUT_SET_VARIABLE@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+RANLIB = @RANLIB@
+RELEASE = @RELEASE@
+RPM = @RPM@
+RPMBUILD = @RPMBUILD@
+RPMBUILD_VERSION = @RPMBUILD_VERSION@
+RPM_DEFINE_COMMON = @RPM_DEFINE_COMMON@
+RPM_DEFINE_DKMS = @RPM_DEFINE_DKMS@
+RPM_DEFINE_KMOD = @RPM_DEFINE_KMOD@
+RPM_DEFINE_UTIL = @RPM_DEFINE_UTIL@
+RPM_SPEC_DIR = @RPM_SPEC_DIR@
+RPM_VERSION = @RPM_VERSION@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SPL = @SPL@
+SPL_OBJ = @SPL_OBJ@
+SPL_SYMBOLS = @SPL_SYMBOLS@
+SPL_VERSION = @SPL_VERSION@
+SRPM_DEFINE_COMMON = @SRPM_DEFINE_COMMON@
+SRPM_DEFINE_DKMS = @SRPM_DEFINE_DKMS@
+SRPM_DEFINE_KMOD = @SRPM_DEFINE_KMOD@
+SRPM_DEFINE_UTIL = @SRPM_DEFINE_UTIL@
+STRIP = @STRIP@
+TARGET_ASM_DIR = @TARGET_ASM_DIR@
+VENDOR = @VENDOR@
+VERSION = @VERSION@
+ZFS_CONFIG = @ZFS_CONFIG@
+ZFS_INIT_SYSTEMD = @ZFS_INIT_SYSTEMD@
+ZFS_INIT_SYSV = @ZFS_INIT_SYSV@
+ZFS_META_ALIAS = @ZFS_META_ALIAS@
+ZFS_META_AUTHOR = @ZFS_META_AUTHOR@
+ZFS_META_DATA = @ZFS_META_DATA@
+ZFS_META_LICENSE = @ZFS_META_LICENSE@
+ZFS_META_LT_AGE = @ZFS_META_LT_AGE@
+ZFS_META_LT_CURRENT = @ZFS_META_LT_CURRENT@
+ZFS_META_LT_REVISION = @ZFS_META_LT_REVISION@
+ZFS_META_NAME = @ZFS_META_NAME@
+ZFS_META_RELEASE = @ZFS_META_RELEASE@
+ZFS_META_VERSION = @ZFS_META_VERSION@
+ZFS_MODULE_LOAD = @ZFS_MODULE_LOAD@
+ZLIB = @ZLIB@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dracutdir = @dracutdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+modulesloaddir = @modulesloaddir@
+mounthelperdir = @mounthelperdir@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+runstatedir = @runstatedir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+systemdpresetdir = @systemdpresetdir@
+systemdunitdir = @systemdunitdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+udevdir = @udevdir@
+udevruledir = @udevruledir@
+SUBDIRS = fs
+COMMON_H = \
+	$(top_srcdir)/include/sys/fm/protocol.h \
+	$(top_srcdir)/include/sys/fm/util.h
+
+KERNEL_H = 
+USER_H = 
+EXTRA_DIST = $(COMMON_H) $(KERNEL_H) $(USER_H)
+@CONFIG_USER_TRUE@libzfsdir = $(includedir)/libzfs/sys/fm
+@CONFIG_USER_TRUE@libzfs_HEADERS = $(COMMON_H) $(USER_H)
+@CONFIG_KERNEL_TRUE@kerneldir = @prefix@/src/zfs-$(VERSION)/include/sys/fm
+@CONFIG_KERNEL_TRUE@kernel_HEADERS = $(COMMON_H) $(KERNEL_H)
+all: all-recursive
+
+.SUFFIXES:
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+	        && { if test -f $@; then exit 0; else break; fi; }; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu include/sys/fm/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --gnu include/sys/fm/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+	esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
+install-kernelHEADERS: $(kernel_HEADERS)
+	@$(NORMAL_INSTALL)
+	@list='$(kernel_HEADERS)'; test -n "$(kerneldir)" || list=; \
+	if test -n "$$list"; then \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(kerneldir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(kerneldir)" || exit 1; \
+	fi; \
+	for p in $$list; do \
+	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+	  echo "$$d$$p"; \
+	done | $(am__base_list) | \
+	while read files; do \
+	  echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(kerneldir)'"; \
+	  $(INSTALL_HEADER) $$files "$(DESTDIR)$(kerneldir)" || exit $$?; \
+	done
+
+uninstall-kernelHEADERS:
+	@$(NORMAL_UNINSTALL)
+	@list='$(kernel_HEADERS)'; test -n "$(kerneldir)" || list=; \
+	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+	dir='$(DESTDIR)$(kerneldir)'; $(am__uninstall_files_from_dir)
+install-libzfsHEADERS: $(libzfs_HEADERS)
+	@$(NORMAL_INSTALL)
+	@list='$(libzfs_HEADERS)'; test -n "$(libzfsdir)" || list=; \
+	if test -n "$$list"; then \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(libzfsdir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(libzfsdir)" || exit 1; \
+	fi; \
+	for p in $$list; do \
+	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+	  echo "$$d$$p"; \
+	done | $(am__base_list) | \
+	while read files; do \
+	  echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(libzfsdir)'"; \
+	  $(INSTALL_HEADER) $$files "$(DESTDIR)$(libzfsdir)" || exit $$?; \
+	done
+
+uninstall-libzfsHEADERS:
+	@$(NORMAL_UNINSTALL)
+	@list='$(libzfs_HEADERS)'; test -n "$(libzfsdir)" || list=; \
+	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+	dir='$(DESTDIR)$(libzfsdir)'; $(am__uninstall_files_from_dir)
+
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run 'make' without going through this Makefile.
+# To change the values of 'make' variables: instead of editing Makefiles,
+# (1) if the variable is set in 'config.status', edit 'config.status'
+#     (which will cause the Makefiles to be regenerated when you run 'make');
+# (2) otherwise, pass the desired values on the 'make' command line.
+$(am__recursive_targets):
+	@fail=; \
+	if $(am__make_keepgoing); then \
+	  failcom='fail=yes'; \
+	else \
+	  failcom='exit 1'; \
+	fi; \
+	dot_seen=no; \
+	target=`echo $@ | sed s/-recursive//`; \
+	case "$@" in \
+	  distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
+	  *) list='$(SUBDIRS)' ;; \
+	esac; \
+	for subdir in $$list; do \
+	  echo "Making $$target in $$subdir"; \
+	  if test "$$subdir" = "."; then \
+	    dot_seen=yes; \
+	    local_target="$$target-am"; \
+	  else \
+	    local_target="$$target"; \
+	  fi; \
+	  ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+	  || eval $$failcom; \
+	done; \
+	if test "$$dot_seen" = "no"; then \
+	  $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+	fi; test -z "$$fail"
+
+ID: $(am__tagged_files)
+	$(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-recursive
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	set x; \
+	here=`pwd`; \
+	if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
+	  include_option=--etags-include; \
+	  empty_fix=.; \
+	else \
+	  include_option=--include; \
+	  empty_fix=; \
+	fi; \
+	list='$(SUBDIRS)'; for subdir in $$list; do \
+	  if test "$$subdir" = .; then :; else \
+	    test ! -f $$subdir/TAGS || \
+	      set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \
+	  fi; \
+	done; \
+	$(am__define_uniq_tagged_files); \
+	shift; \
+	if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+	  test -n "$$unique" || unique=$$empty_fix; \
+	  if test $$# -gt 0; then \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      "$$@" $$unique; \
+	  else \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      $$unique; \
+	  fi; \
+	fi
+ctags: ctags-recursive
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	$(am__define_uniq_tagged_files); \
+	test -z "$(CTAGS_ARGS)$$unique" \
+	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+	     $$unique
+
+GTAGS:
+	here=`$(am__cd) $(top_builddir) && pwd` \
+	  && $(am__cd) $(top_srcdir) \
+	  && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-recursive
+
+cscopelist-am: $(am__tagged_files)
+	list='$(am__tagged_files)'; \
+	case "$(srcdir)" in \
+	  [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+	  *) sdir=$(subdir)/$(srcdir) ;; \
+	esac; \
+	for i in $$list; do \
+	  if test -f "$$i"; then \
+	    echo "$(subdir)/$$i"; \
+	  else \
+	    echo "$$sdir/$$i"; \
+	  fi; \
+	done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	list='$(DISTFILES)'; \
+	  dist_files=`for file in $$list; do echo $$file; done | \
+	  sed -e "s|^$$srcdirstrip/||;t" \
+	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+	case $$dist_files in \
+	  */*) $(MKDIR_P) `echo "$$dist_files" | \
+			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+			   sort -u` ;; \
+	esac; \
+	for file in $$dist_files; do \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  if test -d $$d/$$file; then \
+	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+	    if test -d "$(distdir)/$$file"; then \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+	  else \
+	    test -f "$(distdir)/$$file" \
+	    || cp -p $$d/$$file "$(distdir)/$$file" \
+	    || exit 1; \
+	  fi; \
+	done
+	@list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
+	  if test "$$subdir" = .; then :; else \
+	    $(am__make_dryrun) \
+	      || test -d "$(distdir)/$$subdir" \
+	      || $(MKDIR_P) "$(distdir)/$$subdir" \
+	      || exit 1; \
+	    dir1=$$subdir; dir2="$(distdir)/$$subdir"; \
+	    $(am__relativize); \
+	    new_distdir=$$reldir; \
+	    dir1=$$subdir; dir2="$(top_distdir)"; \
+	    $(am__relativize); \
+	    new_top_distdir=$$reldir; \
+	    echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \
+	    echo "     am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \
+	    ($(am__cd) $$subdir && \
+	      $(MAKE) $(AM_MAKEFLAGS) \
+	        top_distdir="$$new_top_distdir" \
+	        distdir="$$new_distdir" \
+		am__remove_distdir=: \
+		am__skip_length_check=: \
+		am__skip_mode_fix=: \
+	        distdir) \
+	      || exit 1; \
+	  fi; \
+	done
+check-am: all-am
+check: check-recursive
+all-am: Makefile $(HEADERS)
+installdirs: installdirs-recursive
+installdirs-am:
+	for dir in "$(DESTDIR)$(kerneldir)" "$(DESTDIR)$(libzfsdir)"; do \
+	  test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+	done
+install: install-recursive
+install-exec: install-exec-recursive
+install-data: install-data-recursive
+uninstall: uninstall-recursive
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-recursive
+install-strip:
+	if test -z '$(STRIP)'; then \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	      install; \
+	else \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+	fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+clean: clean-recursive
+
+clean-am: clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-recursive
+	-rm -f Makefile
+distclean-am: clean-am distclean-generic distclean-tags
+
+dvi: dvi-recursive
+
+dvi-am:
+
+html: html-recursive
+
+html-am:
+
+info: info-recursive
+
+info-am:
+
+install-data-am: install-kernelHEADERS install-libzfsHEADERS
+
+install-dvi: install-dvi-recursive
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-recursive
+
+install-html-am:
+
+install-info: install-info-recursive
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-recursive
+
+install-pdf-am:
+
+install-ps: install-ps-recursive
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-recursive
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-recursive
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-recursive
+
+pdf-am:
+
+ps: ps-recursive
+
+ps-am:
+
+uninstall-am: uninstall-kernelHEADERS uninstall-libzfsHEADERS
+
+.MAKE: $(am__recursive_targets) install-am install-strip
+
+.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \
+	check-am clean clean-generic clean-libtool cscopelist-am ctags \
+	ctags-am distclean distclean-generic distclean-libtool \
+	distclean-tags distdir dvi dvi-am html html-am info info-am \
+	install install-am install-data install-data-am install-dvi \
+	install-dvi-am install-exec install-exec-am install-html \
+	install-html-am install-info install-info-am \
+	install-kernelHEADERS install-libzfsHEADERS install-man \
+	install-pdf install-pdf-am install-ps install-ps-am \
+	install-strip installcheck installcheck-am installdirs \
+	installdirs-am maintainer-clean maintainer-clean-generic \
+	mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \
+	ps ps-am tags tags-am uninstall uninstall-am \
+	uninstall-kernelHEADERS uninstall-libzfsHEADERS
+
+.PRECIOUS: Makefile
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/include/sys/fm/fs/Makefile.am
@@ -0,0 +1,18 @@
+COMMON_H = \
+	$(top_srcdir)/include/sys/fm/fs/zfs.h
+
+KERNEL_H =
+
+USER_H =
+
+EXTRA_DIST = $(COMMON_H) $(KERNEL_H) $(USER_H)
+
+if CONFIG_USER
+libzfsdir = $(includedir)/libzfs/sys/fm/fs
+libzfs_HEADERS = $(COMMON_H) $(USER_H)
+endif
+
+if CONFIG_KERNEL
+kerneldir = @prefix@/src/zfs-$(VERSION)/include/sys/fm/fs
+kernel_HEADERS = $(COMMON_H) $(KERNEL_H)
+endif
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/include/sys/fm/fs/Makefile.in
@@ -0,0 +1,752 @@
+# Makefile.in generated by automake 1.15 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2014 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+VPATH = @srcdir@
+am__is_gnu_make = { \
+  if test -z '$(MAKELEVEL)'; then \
+    false; \
+  elif test -n '$(MAKE_HOST)'; then \
+    true; \
+  elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+    true; \
+  else \
+    false; \
+  fi; \
+}
+am__make_running_with_option = \
+  case $${target_option-} in \
+      ?) ;; \
+      *) echo "am__make_running_with_option: internal error: invalid" \
+              "target option '$${target_option-}' specified" >&2; \
+         exit 1;; \
+  esac; \
+  has_opt=no; \
+  sane_makeflags=$$MAKEFLAGS; \
+  if $(am__is_gnu_make); then \
+    sane_makeflags=$$MFLAGS; \
+  else \
+    case $$MAKEFLAGS in \
+      *\\[\ \	]*) \
+        bs=\\; \
+        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
+    esac; \
+  fi; \
+  skip_next=no; \
+  strip_trailopt () \
+  { \
+    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+  }; \
+  for flg in $$sane_makeflags; do \
+    test $$skip_next = yes && { skip_next=no; continue; }; \
+    case $$flg in \
+      *=*|--*) continue;; \
+        -*I) strip_trailopt 'I'; skip_next=yes;; \
+      -*I?*) strip_trailopt 'I';; \
+        -*O) strip_trailopt 'O'; skip_next=yes;; \
+      -*O?*) strip_trailopt 'O';; \
+        -*l) strip_trailopt 'l'; skip_next=yes;; \
+      -*l?*) strip_trailopt 'l';; \
+      -[dEDm]) skip_next=yes;; \
+      -[JT]) skip_next=yes;; \
+    esac; \
+    case $$flg in \
+      *$$target_option*) has_opt=yes; break;; \
+    esac; \
+  done; \
+  test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+target_triplet = @target@
+subdir = include/sys/fm/fs
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/config/always-no-bool-compare.m4 \
+	$(top_srcdir)/config/always-no-unused-but-set-variable.m4 \
+	$(top_srcdir)/config/dkms.m4 \
+	$(top_srcdir)/config/kernel-acl.m4 \
+	$(top_srcdir)/config/kernel-automount.m4 \
+	$(top_srcdir)/config/kernel-bdev-block-device-operations.m4 \
+	$(top_srcdir)/config/kernel-bdev-logical-size.m4 \
+	$(top_srcdir)/config/kernel-bdev-physical-size.m4 \
+	$(top_srcdir)/config/kernel-bdi-setup-and-register.m4 \
+	$(top_srcdir)/config/kernel-bio-bvec-iter.m4 \
+	$(top_srcdir)/config/kernel-bio-end-io-t-args.m4 \
+	$(top_srcdir)/config/kernel-bio-failfast.m4 \
+	$(top_srcdir)/config/kernel-bio-rw-barrier.m4 \
+	$(top_srcdir)/config/kernel-bio-rw-discard.m4 \
+	$(top_srcdir)/config/kernel-blk-queue-flush.m4 \
+	$(top_srcdir)/config/kernel-blk-queue-max-hw-sectors.m4 \
+	$(top_srcdir)/config/kernel-blk-queue-max-segments.m4 \
+	$(top_srcdir)/config/kernel-blkdev-get-by-path.m4 \
+	$(top_srcdir)/config/kernel-blkdev-get.m4 \
+	$(top_srcdir)/config/kernel-block-device-operations-release-void.m4 \
+	$(top_srcdir)/config/kernel-check-disk-size-change.m4 \
+	$(top_srcdir)/config/kernel-clear-inode.m4 \
+	$(top_srcdir)/config/kernel-commit-metadata.m4 \
+	$(top_srcdir)/config/kernel-create-nameidata.m4 \
+	$(top_srcdir)/config/kernel-current_bio_tail.m4 \
+	$(top_srcdir)/config/kernel-d-make-root.m4 \
+	$(top_srcdir)/config/kernel-d-obtain-alias.m4 \
+	$(top_srcdir)/config/kernel-d-prune-aliases.m4 \
+	$(top_srcdir)/config/kernel-declare-event-class.m4 \
+	$(top_srcdir)/config/kernel-dentry-operations.m4 \
+	$(top_srcdir)/config/kernel-dirty-inode.m4 \
+	$(top_srcdir)/config/kernel-discard-granularity.m4 \
+	$(top_srcdir)/config/kernel-elevator-change.m4 \
+	$(top_srcdir)/config/kernel-encode-fh-inode.m4 \
+	$(top_srcdir)/config/kernel-evict-inode.m4 \
+	$(top_srcdir)/config/kernel-fallocate.m4 \
+	$(top_srcdir)/config/kernel-file-inode.m4 \
+	$(top_srcdir)/config/kernel-fmode-t.m4 \
+	$(top_srcdir)/config/kernel-follow-down-one.m4 \
+	$(top_srcdir)/config/kernel-fsync.m4 \
+	$(top_srcdir)/config/kernel-generic_io_acct.m4 \
+	$(top_srcdir)/config/kernel-get-disk-ro.m4 \
+	$(top_srcdir)/config/kernel-get-gendisk.m4 \
+	$(top_srcdir)/config/kernel-get-link.m4 \
+	$(top_srcdir)/config/kernel-insert-inode-locked.m4 \
+	$(top_srcdir)/config/kernel-invalidate-bdev-args.m4 \
+	$(top_srcdir)/config/kernel-is_owner_or_cap.m4 \
+	$(top_srcdir)/config/kernel-kmap-atomic-args.m4 \
+	$(top_srcdir)/config/kernel-kobj-name-len.m4 \
+	$(top_srcdir)/config/kernel-lookup-bdev.m4 \
+	$(top_srcdir)/config/kernel-lookup-nameidata.m4 \
+	$(top_srcdir)/config/kernel-lseek-execute.m4 \
+	$(top_srcdir)/config/kernel-mk-request-fn.m4 \
+	$(top_srcdir)/config/kernel-mkdir-umode-t.m4 \
+	$(top_srcdir)/config/kernel-mount-nodev.m4 \
+	$(top_srcdir)/config/kernel-open-bdev-exclusive.m4 \
+	$(top_srcdir)/config/kernel-put-link.m4 \
+	$(top_srcdir)/config/kernel-security-inode-init.m4 \
+	$(top_srcdir)/config/kernel-set-nlink.m4 \
+	$(top_srcdir)/config/kernel-sget-args.m4 \
+	$(top_srcdir)/config/kernel-show-options.m4 \
+	$(top_srcdir)/config/kernel-shrink.m4 \
+	$(top_srcdir)/config/kernel-truncate-range.m4 \
+	$(top_srcdir)/config/kernel-truncate-setsize.m4 \
+	$(top_srcdir)/config/kernel-vfs-iterate.m4 \
+	$(top_srcdir)/config/kernel-vfs-rw-iterate.m4 \
+	$(top_srcdir)/config/kernel-xattr-handler.m4 \
+	$(top_srcdir)/config/kernel.m4 $(top_srcdir)/config/libtool.m4 \
+	$(top_srcdir)/config/ltoptions.m4 \
+	$(top_srcdir)/config/ltsugar.m4 \
+	$(top_srcdir)/config/ltversion.m4 \
+	$(top_srcdir)/config/lt~obsolete.m4 \
+	$(top_srcdir)/config/mount-helper.m4 \
+	$(top_srcdir)/config/user-arch.m4 \
+	$(top_srcdir)/config/user-dracut.m4 \
+	$(top_srcdir)/config/user-frame-larger-than.m4 \
+	$(top_srcdir)/config/user-libblkid.m4 \
+	$(top_srcdir)/config/user-libuuid.m4 \
+	$(top_srcdir)/config/user-runstatedir.m4 \
+	$(top_srcdir)/config/user-systemd.m4 \
+	$(top_srcdir)/config/user-sysvinit.m4 \
+	$(top_srcdir)/config/user-udev.m4 \
+	$(top_srcdir)/config/user-zlib.m4 $(top_srcdir)/config/user.m4 \
+	$(top_srcdir)/config/zfs-build.m4 \
+	$(top_srcdir)/config/zfs-meta.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(am__kernel_HEADERS_DIST) \
+	$(am__libzfs_HEADERS_DIST) $(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/zfs_config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo "  GEN     " $@;
+am__v_GEN_1 = 
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 = 
+SOURCES =
+DIST_SOURCES =
+am__can_run_installinfo = \
+  case $$AM_UPDATE_INFO_DIR in \
+    n|no|NO) false;; \
+    *) (install-info --version) >/dev/null 2>&1;; \
+  esac
+am__kernel_HEADERS_DIST = $(top_srcdir)/include/sys/fm/fs/zfs.h
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+    $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+    *) f=$$p;; \
+  esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+  srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+  for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+  for p in $$list; do echo "$$p $$p"; done | \
+  sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+  $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+    if (++n[$$2] == $(am__install_max)) \
+      { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+    END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+  sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+  sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+  test -z "$$files" \
+    || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+    || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+         $(am__cd) "$$dir" && rm -f $$files; }; \
+  }
+am__installdirs = "$(DESTDIR)$(kerneldir)" "$(DESTDIR)$(libzfsdir)"
+am__libzfs_HEADERS_DIST = $(top_srcdir)/include/sys/fm/fs/zfs.h
+HEADERS = $(kernel_HEADERS) $(libzfs_HEADERS)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates.  Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+  BEGIN { nonempty = 0; } \
+  { items[$$0] = 1; nonempty = 1; } \
+  END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique.  This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+  list='$(am__tagged_files)'; \
+  unique=`for i in $$list; do \
+    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+  done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+am__DIST_COMMON = $(srcdir)/Makefile.in
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ALIEN = @ALIEN@
+ALIEN_VERSION = @ALIEN_VERSION@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCAS = @CCAS@
+CCASDEPMODE = @CCASDEPMODE@
+CCASFLAGS = @CCASFLAGS@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEBUG_CFLAGS = @DEBUG_CFLAGS@
+DEBUG_DMU_TX = @DEBUG_DMU_TX@
+DEBUG_STACKFLAGS = @DEBUG_STACKFLAGS@
+DEBUG_ZFS = @DEBUG_ZFS@
+DEFAULT_INITCONF_DIR = @DEFAULT_INITCONF_DIR@
+DEFAULT_INIT_DIR = @DEFAULT_INIT_DIR@
+DEFAULT_INIT_SCRIPT = @DEFAULT_INIT_SCRIPT@
+DEFAULT_PACKAGE = @DEFAULT_PACKAGE@
+DEFINE_INITRAMFS = @DEFINE_INITRAMFS@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DPKG = @DPKG@
+DPKGBUILD = @DPKGBUILD@
+DPKGBUILD_VERSION = @DPKGBUILD_VERSION@
+DPKG_VERSION = @DPKG_VERSION@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+FRAME_LARGER_THAN = @FRAME_LARGER_THAN@
+GREP = @GREP@
+HAVE_ALIEN = @HAVE_ALIEN@
+HAVE_DPKG = @HAVE_DPKG@
+HAVE_DPKGBUILD = @HAVE_DPKGBUILD@
+HAVE_RPM = @HAVE_RPM@
+HAVE_RPMBUILD = @HAVE_RPMBUILD@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+KERNELCPPFLAGS = @KERNELCPPFLAGS@
+KERNELMAKE_PARAMS = @KERNELMAKE_PARAMS@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBBLKID = @LIBBLKID@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIBUUID = @LIBUUID@
+LINUX = @LINUX@
+LINUX_OBJ = @LINUX_OBJ@
+LINUX_SYMBOLS = @LINUX_SYMBOLS@
+LINUX_VERSION = @LINUX_VERSION@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NO_BOOL_COMPARE = @NO_BOOL_COMPARE@
+NO_UNUSED_BUT_SET_VARIABLE = @NO_UNUSED_BUT_SET_VARIABLE@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+RANLIB = @RANLIB@
+RELEASE = @RELEASE@
+RPM = @RPM@
+RPMBUILD = @RPMBUILD@
+RPMBUILD_VERSION = @RPMBUILD_VERSION@
+RPM_DEFINE_COMMON = @RPM_DEFINE_COMMON@
+RPM_DEFINE_DKMS = @RPM_DEFINE_DKMS@
+RPM_DEFINE_KMOD = @RPM_DEFINE_KMOD@
+RPM_DEFINE_UTIL = @RPM_DEFINE_UTIL@
+RPM_SPEC_DIR = @RPM_SPEC_DIR@
+RPM_VERSION = @RPM_VERSION@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SPL = @SPL@
+SPL_OBJ = @SPL_OBJ@
+SPL_SYMBOLS = @SPL_SYMBOLS@
+SPL_VERSION = @SPL_VERSION@
+SRPM_DEFINE_COMMON = @SRPM_DEFINE_COMMON@
+SRPM_DEFINE_DKMS = @SRPM_DEFINE_DKMS@
+SRPM_DEFINE_KMOD = @SRPM_DEFINE_KMOD@
+SRPM_DEFINE_UTIL = @SRPM_DEFINE_UTIL@
+STRIP = @STRIP@
+TARGET_ASM_DIR = @TARGET_ASM_DIR@
+VENDOR = @VENDOR@
+VERSION = @VERSION@
+ZFS_CONFIG = @ZFS_CONFIG@
+ZFS_INIT_SYSTEMD = @ZFS_INIT_SYSTEMD@
+ZFS_INIT_SYSV = @ZFS_INIT_SYSV@
+ZFS_META_ALIAS = @ZFS_META_ALIAS@
+ZFS_META_AUTHOR = @ZFS_META_AUTHOR@
+ZFS_META_DATA = @ZFS_META_DATA@
+ZFS_META_LICENSE = @ZFS_META_LICENSE@
+ZFS_META_LT_AGE = @ZFS_META_LT_AGE@
+ZFS_META_LT_CURRENT = @ZFS_META_LT_CURRENT@
+ZFS_META_LT_REVISION = @ZFS_META_LT_REVISION@
+ZFS_META_NAME = @ZFS_META_NAME@
+ZFS_META_RELEASE = @ZFS_META_RELEASE@
+ZFS_META_VERSION = @ZFS_META_VERSION@
+ZFS_MODULE_LOAD = @ZFS_MODULE_LOAD@
+ZLIB = @ZLIB@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dracutdir = @dracutdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+modulesloaddir = @modulesloaddir@
+mounthelperdir = @mounthelperdir@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+runstatedir = @runstatedir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+systemdpresetdir = @systemdpresetdir@
+systemdunitdir = @systemdunitdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+udevdir = @udevdir@
+udevruledir = @udevruledir@
+COMMON_H = \
+	$(top_srcdir)/include/sys/fm/fs/zfs.h
+
+KERNEL_H = 
+USER_H = 
+EXTRA_DIST = $(COMMON_H) $(KERNEL_H) $(USER_H)
+@CONFIG_USER_TRUE@libzfsdir = $(includedir)/libzfs/sys/fm/fs
+@CONFIG_USER_TRUE@libzfs_HEADERS = $(COMMON_H) $(USER_H)
+@CONFIG_KERNEL_TRUE@kerneldir = @prefix@/src/zfs-$(VERSION)/include/sys/fm/fs
+@CONFIG_KERNEL_TRUE@kernel_HEADERS = $(COMMON_H) $(KERNEL_H)
+all: all-am
+
+.SUFFIXES:
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+	        && { if test -f $@; then exit 0; else break; fi; }; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu include/sys/fm/fs/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --gnu include/sys/fm/fs/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+	esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
+install-kernelHEADERS: $(kernel_HEADERS)
+	@$(NORMAL_INSTALL)
+	@list='$(kernel_HEADERS)'; test -n "$(kerneldir)" || list=; \
+	if test -n "$$list"; then \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(kerneldir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(kerneldir)" || exit 1; \
+	fi; \
+	for p in $$list; do \
+	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+	  echo "$$d$$p"; \
+	done | $(am__base_list) | \
+	while read files; do \
+	  echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(kerneldir)'"; \
+	  $(INSTALL_HEADER) $$files "$(DESTDIR)$(kerneldir)" || exit $$?; \
+	done
+
+uninstall-kernelHEADERS:
+	@$(NORMAL_UNINSTALL)
+	@list='$(kernel_HEADERS)'; test -n "$(kerneldir)" || list=; \
+	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+	dir='$(DESTDIR)$(kerneldir)'; $(am__uninstall_files_from_dir)
+install-libzfsHEADERS: $(libzfs_HEADERS)
+	@$(NORMAL_INSTALL)
+	@list='$(libzfs_HEADERS)'; test -n "$(libzfsdir)" || list=; \
+	if test -n "$$list"; then \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(libzfsdir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(libzfsdir)" || exit 1; \
+	fi; \
+	for p in $$list; do \
+	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+	  echo "$$d$$p"; \
+	done | $(am__base_list) | \
+	while read files; do \
+	  echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(libzfsdir)'"; \
+	  $(INSTALL_HEADER) $$files "$(DESTDIR)$(libzfsdir)" || exit $$?; \
+	done
+
+uninstall-libzfsHEADERS:
+	@$(NORMAL_UNINSTALL)
+	@list='$(libzfs_HEADERS)'; test -n "$(libzfsdir)" || list=; \
+	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+	dir='$(DESTDIR)$(libzfsdir)'; $(am__uninstall_files_from_dir)
+
+ID: $(am__tagged_files)
+	$(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	set x; \
+	here=`pwd`; \
+	$(am__define_uniq_tagged_files); \
+	shift; \
+	if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+	  test -n "$$unique" || unique=$$empty_fix; \
+	  if test $$# -gt 0; then \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      "$$@" $$unique; \
+	  else \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      $$unique; \
+	  fi; \
+	fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	$(am__define_uniq_tagged_files); \
+	test -z "$(CTAGS_ARGS)$$unique" \
+	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+	     $$unique
+
+GTAGS:
+	here=`$(am__cd) $(top_builddir) && pwd` \
+	  && $(am__cd) $(top_srcdir) \
+	  && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+	list='$(am__tagged_files)'; \
+	case "$(srcdir)" in \
+	  [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+	  *) sdir=$(subdir)/$(srcdir) ;; \
+	esac; \
+	for i in $$list; do \
+	  if test -f "$$i"; then \
+	    echo "$(subdir)/$$i"; \
+	  else \
+	    echo "$$sdir/$$i"; \
+	  fi; \
+	done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	list='$(DISTFILES)'; \
+	  dist_files=`for file in $$list; do echo $$file; done | \
+	  sed -e "s|^$$srcdirstrip/||;t" \
+	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+	case $$dist_files in \
+	  */*) $(MKDIR_P) `echo "$$dist_files" | \
+			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+			   sort -u` ;; \
+	esac; \
+	for file in $$dist_files; do \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  if test -d $$d/$$file; then \
+	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+	    if test -d "$(distdir)/$$file"; then \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+	  else \
+	    test -f "$(distdir)/$$file" \
+	    || cp -p $$d/$$file "$(distdir)/$$file" \
+	    || exit 1; \
+	  fi; \
+	done
+check-am: all-am
+check: check-am
+all-am: Makefile $(HEADERS)
+installdirs:
+	for dir in "$(DESTDIR)$(kerneldir)" "$(DESTDIR)$(libzfsdir)"; do \
+	  test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+	done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+	if test -z '$(STRIP)'; then \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	      install; \
+	else \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+	fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-am
+	-rm -f Makefile
+distclean-am: clean-am distclean-generic distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-kernelHEADERS install-libzfsHEADERS
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-kernelHEADERS uninstall-libzfsHEADERS
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \
+	clean-libtool cscopelist-am ctags ctags-am distclean \
+	distclean-generic distclean-libtool distclean-tags distdir dvi \
+	dvi-am html html-am info info-am install install-am \
+	install-data install-data-am install-dvi install-dvi-am \
+	install-exec install-exec-am install-html install-html-am \
+	install-info install-info-am install-kernelHEADERS \
+	install-libzfsHEADERS install-man install-pdf install-pdf-am \
+	install-ps install-ps-am install-strip installcheck \
+	installcheck-am installdirs maintainer-clean \
+	maintainer-clean-generic mostlyclean mostlyclean-generic \
+	mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \
+	uninstall-am uninstall-kernelHEADERS uninstall-libzfsHEADERS
+
+.PRECIOUS: Makefile
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/include/sys/fm/fs/zfs.h
@@ -0,0 +1,126 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef	_SYS_FM_FS_ZFS_H
+#define	_SYS_FM_FS_ZFS_H
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+#define	ZFS_ERROR_CLASS				"fs.zfs"
+
+#define	FM_EREPORT_ZFS_CHECKSUM			"checksum"
+#define	FM_EREPORT_ZFS_IO			"io"
+#define	FM_EREPORT_ZFS_DATA			"data"
+#define	FM_EREPORT_ZFS_DELAY			"delay"
+#define	FM_EREPORT_ZFS_CONFIG_SYNC		"config.sync"
+#define	FM_EREPORT_ZFS_POOL			"zpool"
+#define	FM_EREPORT_ZFS_POOL_DESTROY		"zpool.destroy"
+#define	FM_EREPORT_ZFS_POOL_REGUID		"zpool.reguid"
+#define	FM_EREPORT_ZFS_DEVICE_UNKNOWN		"vdev.unknown"
+#define	FM_EREPORT_ZFS_DEVICE_OPEN_FAILED	"vdev.open_failed"
+#define	FM_EREPORT_ZFS_DEVICE_CORRUPT_DATA	"vdev.corrupt_data"
+#define	FM_EREPORT_ZFS_DEVICE_NO_REPLICAS	"vdev.no_replicas"
+#define	FM_EREPORT_ZFS_DEVICE_BAD_GUID_SUM	"vdev.bad_guid_sum"
+#define	FM_EREPORT_ZFS_DEVICE_TOO_SMALL		"vdev.too_small"
+#define	FM_EREPORT_ZFS_DEVICE_BAD_LABEL		"vdev.bad_label"
+#define	FM_EREPORT_ZFS_DEVICE_BAD_ASHIFT	"vdev.bad_ashift"
+#define	FM_EREPORT_ZFS_DEVICE_REMOVE		"vdev.remove"
+#define	FM_EREPORT_ZFS_DEVICE_CLEAR		"vdev.clear"
+#define	FM_EREPORT_ZFS_DEVICE_CHECK		"vdev.check"
+#define	FM_EREPORT_ZFS_DEVICE_SPARE		"vdev.spare"
+#define	FM_EREPORT_ZFS_DEVICE_AUTOEXPAND	"vdev.autoexpand"
+#define	FM_EREPORT_ZFS_IO_FAILURE		"io_failure"
+#define	FM_EREPORT_ZFS_PROBE_FAILURE		"probe_failure"
+#define	FM_EREPORT_ZFS_LOG_REPLAY		"log_replay"
+#define	FM_EREPORT_ZFS_RESILVER_START		"resilver.start"
+#define	FM_EREPORT_ZFS_RESILVER_FINISH		"resilver.finish"
+#define	FM_EREPORT_ZFS_SCRUB_START		"scrub.start"
+#define	FM_EREPORT_ZFS_SCRUB_FINISH		"scrub.finish"
+#define	FM_EREPORT_ZFS_BOOTFS_VDEV_ATTACH	"bootfs.vdev.attach"
+
+#define	FM_EREPORT_PAYLOAD_ZFS_POOL		"pool"
+#define	FM_EREPORT_PAYLOAD_ZFS_POOL_FAILMODE	"pool_failmode"
+#define	FM_EREPORT_PAYLOAD_ZFS_POOL_GUID	"pool_guid"
+#define	FM_EREPORT_PAYLOAD_ZFS_POOL_CONTEXT	"pool_context"
+#define	FM_EREPORT_PAYLOAD_ZFS_VDEV_GUID	"vdev_guid"
+#define	FM_EREPORT_PAYLOAD_ZFS_VDEV_TYPE	"vdev_type"
+#define	FM_EREPORT_PAYLOAD_ZFS_VDEV_PATH	"vdev_path"
+#define	FM_EREPORT_PAYLOAD_ZFS_VDEV_DEVID	"vdev_devid"
+#define	FM_EREPORT_PAYLOAD_ZFS_VDEV_FRU		"vdev_fru"
+#define	FM_EREPORT_PAYLOAD_ZFS_VDEV_STATE	"vdev_state"
+#define	FM_EREPORT_PAYLOAD_ZFS_VDEV_ASHIFT	"vdev_ashift"
+#define	FM_EREPORT_PAYLOAD_ZFS_VDEV_COMP_TS	"vdev_complete_ts"
+#define	FM_EREPORT_PAYLOAD_ZFS_VDEV_DELTA_TS	"vdev_delta_ts"
+#define	FM_EREPORT_PAYLOAD_ZFS_VDEV_SPARE_PATHS	"vdev_spare_paths"
+#define	FM_EREPORT_PAYLOAD_ZFS_VDEV_SPARE_GUIDS	"vdev_spare_guids"
+#define	FM_EREPORT_PAYLOAD_ZFS_VDEV_READ_ERRORS	"vdev_read_errors"
+#define	FM_EREPORT_PAYLOAD_ZFS_VDEV_WRITE_ERRORS "vdev_write_errors"
+#define	FM_EREPORT_PAYLOAD_ZFS_VDEV_CKSUM_ERRORS "vdev_cksum_errors"
+#define	FM_EREPORT_PAYLOAD_ZFS_PARENT_GUID	"parent_guid"
+#define	FM_EREPORT_PAYLOAD_ZFS_PARENT_TYPE	"parent_type"
+#define	FM_EREPORT_PAYLOAD_ZFS_PARENT_PATH	"parent_path"
+#define	FM_EREPORT_PAYLOAD_ZFS_PARENT_DEVID	"parent_devid"
+#define	FM_EREPORT_PAYLOAD_ZFS_ZIO_OBJSET	"zio_objset"
+#define	FM_EREPORT_PAYLOAD_ZFS_ZIO_OBJECT	"zio_object"
+#define	FM_EREPORT_PAYLOAD_ZFS_ZIO_LEVEL	"zio_level"
+#define	FM_EREPORT_PAYLOAD_ZFS_ZIO_BLKID	"zio_blkid"
+#define	FM_EREPORT_PAYLOAD_ZFS_ZIO_ERR		"zio_err"
+#define	FM_EREPORT_PAYLOAD_ZFS_ZIO_OFFSET	"zio_offset"
+#define	FM_EREPORT_PAYLOAD_ZFS_ZIO_SIZE		"zio_size"
+#define	FM_EREPORT_PAYLOAD_ZFS_ZIO_FLAGS	"zio_flags"
+#define	FM_EREPORT_PAYLOAD_ZFS_ZIO_STAGE	"zio_stage"
+#define	FM_EREPORT_PAYLOAD_ZFS_ZIO_PIPELINE	"zio_pipeline"
+#define	FM_EREPORT_PAYLOAD_ZFS_ZIO_DELAY	"zio_delay"
+#define	FM_EREPORT_PAYLOAD_ZFS_ZIO_TIMESTAMP	"zio_timestamp"
+#define	FM_EREPORT_PAYLOAD_ZFS_ZIO_DELTA	"zio_delta"
+#define	FM_EREPORT_PAYLOAD_ZFS_PREV_STATE	"prev_state"
+#define	FM_EREPORT_PAYLOAD_ZFS_CKSUM_EXPECTED	"cksum_expected"
+#define	FM_EREPORT_PAYLOAD_ZFS_CKSUM_ACTUAL	"cksum_actual"
+#define	FM_EREPORT_PAYLOAD_ZFS_CKSUM_ALGO	"cksum_algorithm"
+#define	FM_EREPORT_PAYLOAD_ZFS_CKSUM_BYTESWAP	"cksum_byteswap"
+#define	FM_EREPORT_PAYLOAD_ZFS_BAD_OFFSET_RANGES "bad_ranges"
+#define	FM_EREPORT_PAYLOAD_ZFS_BAD_RANGE_MIN_GAP "bad_ranges_min_gap"
+#define	FM_EREPORT_PAYLOAD_ZFS_BAD_RANGE_SETS	"bad_range_sets"
+#define	FM_EREPORT_PAYLOAD_ZFS_BAD_RANGE_CLEARS	"bad_range_clears"
+#define	FM_EREPORT_PAYLOAD_ZFS_BAD_SET_BITS	"bad_set_bits"
+#define	FM_EREPORT_PAYLOAD_ZFS_BAD_CLEARED_BITS	"bad_cleared_bits"
+#define	FM_EREPORT_PAYLOAD_ZFS_BAD_SET_HISTOGRAM "bad_set_histogram"
+#define	FM_EREPORT_PAYLOAD_ZFS_BAD_CLEARED_HISTOGRAM "bad_cleared_histogram"
+
+#define	FM_EREPORT_FAILMODE_WAIT		"wait"
+#define	FM_EREPORT_FAILMODE_CONTINUE		"continue"
+#define	FM_EREPORT_FAILMODE_PANIC		"panic"
+
+#define	FM_EREPORT_RESOURCE_REMOVED		"removed"
+#define	FM_EREPORT_RESOURCE_AUTOREPLACE		"autoreplace"
+#define	FM_EREPORT_RESOURCE_STATECHANGE		"statechange"
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* _SYS_FM_FS_ZFS_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/include/sys/fm/protocol.h
@@ -0,0 +1,368 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
+ */
+
+#ifndef	_SYS_FM_PROTOCOL_H
+#define	_SYS_FM_PROTOCOL_H
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+#ifdef _KERNEL
+#include <sys/varargs.h>
+#include <sys/nvpair.h>
+#else
+#include <libnvpair.h>
+#include <stdarg.h>
+#endif
+#include <sys/processor.h>
+
+/* FM common member names */
+#define	FM_CLASS			"class"
+#define	FM_VERSION			"version"
+
+/* FM protocol category 1 class names */
+#define	FM_EREPORT_CLASS		"ereport"
+#define	FM_FAULT_CLASS			"fault"
+#define	FM_DEFECT_CLASS			"defect"
+#define	FM_RSRC_CLASS			"resource"
+#define	FM_LIST_EVENT			"list"
+#define	FM_IREPORT_CLASS		"ireport"
+
+/* FM list.* event class values */
+#define	FM_LIST_SUSPECT_CLASS		FM_LIST_EVENT ".suspect"
+#define	FM_LIST_ISOLATED_CLASS		FM_LIST_EVENT ".isolated"
+#define	FM_LIST_REPAIRED_CLASS		FM_LIST_EVENT ".repaired"
+#define	FM_LIST_UPDATED_CLASS		FM_LIST_EVENT ".updated"
+#define	FM_LIST_RESOLVED_CLASS		FM_LIST_EVENT ".resolved"
+
+/* ereport class subcategory values */
+#define	FM_ERROR_CPU			"cpu"
+#define	FM_ERROR_IO			"io"
+
+/* ereport version and payload member names */
+#define	FM_EREPORT_VERS0		0
+#define	FM_EREPORT_VERSION		FM_EREPORT_VERS0
+
+/* ereport payload member names */
+#define	FM_EREPORT_DETECTOR		"detector"
+#define	FM_EREPORT_ENA			"ena"
+#define	FM_EREPORT_TIME			"time"
+#define	FM_EREPORT_EID			"eid"
+
+/* list.* event payload member names */
+#define	FM_LIST_EVENT_SIZE		"list-sz"
+
+/* ireport.* event payload member names */
+#define	FM_IREPORT_DETECTOR		"detector"
+#define	FM_IREPORT_UUID			"uuid"
+#define	FM_IREPORT_PRIORITY		"pri"
+#define	FM_IREPORT_ATTRIBUTES		"attr"
+
+/*
+ * list.suspect, isolated, updated, repaired and resolved
+ * versions/payload member names.
+ */
+#define	FM_SUSPECT_UUID			"uuid"
+#define	FM_SUSPECT_DIAG_CODE		"code"
+#define	FM_SUSPECT_DIAG_TIME		"diag-time"
+#define	FM_SUSPECT_DE			"de"
+#define	FM_SUSPECT_FAULT_LIST		"fault-list"
+#define	FM_SUSPECT_FAULT_SZ		"fault-list-sz"
+#define	FM_SUSPECT_FAULT_STATUS		"fault-status"
+#define	FM_SUSPECT_INJECTED		"__injected"
+#define	FM_SUSPECT_MESSAGE		"message"
+#define	FM_SUSPECT_RETIRE		"retire"
+#define	FM_SUSPECT_RESPONSE		"response"
+#define	FM_SUSPECT_SEVERITY		"severity"
+
+#define	FM_SUSPECT_VERS0		0
+#define	FM_SUSPECT_VERSION		FM_SUSPECT_VERS0
+
+#define	FM_SUSPECT_FAULTY		0x1
+#define	FM_SUSPECT_UNUSABLE		0x2
+#define	FM_SUSPECT_NOT_PRESENT		0x4
+#define	FM_SUSPECT_DEGRADED		0x8
+#define	FM_SUSPECT_REPAIRED		0x10
+#define	FM_SUSPECT_REPLACED		0x20
+#define	FM_SUSPECT_ACQUITTED		0x40
+
+/* fault event versions and payload member names */
+#define	FM_FAULT_VERS0			0
+#define	FM_FAULT_VERSION		FM_FAULT_VERS0
+
+#define	FM_FAULT_ASRU			"asru"
+#define	FM_FAULT_FRU			"fru"
+#define	FM_FAULT_FRU_LABEL		"fru-label"
+#define	FM_FAULT_CERTAINTY		"certainty"
+#define	FM_FAULT_RESOURCE		"resource"
+#define	FM_FAULT_LOCATION		"location"
+
+/* resource event versions and payload member names */
+#define	FM_RSRC_VERS0			0
+#define	FM_RSRC_VERSION			FM_RSRC_VERS0
+#define	FM_RSRC_RESOURCE		"resource"
+
+/* resource.fm.asru.* payload member names */
+#define	FM_RSRC_ASRU_UUID		"uuid"
+#define	FM_RSRC_ASRU_CODE		"code"
+#define	FM_RSRC_ASRU_FAULTY		"faulty"
+#define	FM_RSRC_ASRU_REPAIRED		"repaired"
+#define	FM_RSRC_ASRU_REPLACED		"replaced"
+#define	FM_RSRC_ASRU_ACQUITTED		"acquitted"
+#define	FM_RSRC_ASRU_RESOLVED		"resolved"
+#define	FM_RSRC_ASRU_UNUSABLE		"unusable"
+#define	FM_RSRC_ASRU_EVENT		"event"
+
+/* resource.fm.xprt.* versions and payload member names */
+#define	FM_RSRC_XPRT_VERS0		0
+#define	FM_RSRC_XPRT_VERSION		FM_RSRC_XPRT_VERS0
+#define	FM_RSRC_XPRT_UUID		"uuid"
+#define	FM_RSRC_XPRT_SUBCLASS		"subclass"
+#define	FM_RSRC_XPRT_FAULT_STATUS	"fault-status"
+#define	FM_RSRC_XPRT_FAULT_HAS_ASRU	"fault-has-asru"
+
+/*
+ * FM ENA Format Macros
+ */
+#define	ENA_FORMAT_MASK			0x3
+#define	ENA_FORMAT(ena)			((ena) & ENA_FORMAT_MASK)
+
+/* ENA format types */
+#define	FM_ENA_FMT0			0
+#define	FM_ENA_FMT1			1
+#define	FM_ENA_FMT2			2
+
+/* Format 1 */
+#define	ENA_FMT1_GEN_MASK		0x00000000000003FCull
+#define	ENA_FMT1_ID_MASK		0xFFFFFFFFFFFFFC00ull
+#define	ENA_FMT1_CPUID_MASK		0x00000000000FFC00ull
+#define	ENA_FMT1_TIME_MASK		0xFFFFFFFFFFF00000ull
+#define	ENA_FMT1_GEN_SHFT		2
+#define	ENA_FMT1_ID_SHFT		10
+#define	ENA_FMT1_CPUID_SHFT		ENA_FMT1_ID_SHFT
+#define	ENA_FMT1_TIME_SHFT		20
+
+/* Format 2 */
+#define	ENA_FMT2_GEN_MASK		0x00000000000003FCull
+#define	ENA_FMT2_ID_MASK		0xFFFFFFFFFFFFFC00ull
+#define	ENA_FMT2_TIME_MASK		ENA_FMT2_ID_MASK
+#define	ENA_FMT2_GEN_SHFT		2
+#define	ENA_FMT2_ID_SHFT		10
+#define	ENA_FMT2_TIME_SHFT		ENA_FMT2_ID_SHFT
+
+/* Common FMRI type names */
+#define	FM_FMRI_AUTHORITY		"authority"
+#define	FM_FMRI_SCHEME			"scheme"
+#define	FM_FMRI_SVC_AUTHORITY		"svc-authority"
+#define	FM_FMRI_FACILITY		"facility"
+
+/* FMRI authority-type member names */
+#define	FM_FMRI_AUTH_CHASSIS		"chassis-id"
+#define	FM_FMRI_AUTH_PRODUCT_SN		"product-sn"
+#define	FM_FMRI_AUTH_PRODUCT		"product-id"
+#define	FM_FMRI_AUTH_DOMAIN		"domain-id"
+#define	FM_FMRI_AUTH_SERVER		"server-id"
+#define	FM_FMRI_AUTH_HOST		"host-id"
+
+#define	FM_AUTH_VERS0			0
+#define	FM_FMRI_AUTH_VERSION		FM_AUTH_VERS0
+
+/* scheme name values */
+#define	FM_FMRI_SCHEME_FMD		"fmd"
+#define	FM_FMRI_SCHEME_DEV		"dev"
+#define	FM_FMRI_SCHEME_HC		"hc"
+#define	FM_FMRI_SCHEME_SVC		"svc"
+#define	FM_FMRI_SCHEME_CPU		"cpu"
+#define	FM_FMRI_SCHEME_MEM		"mem"
+#define	FM_FMRI_SCHEME_MOD		"mod"
+#define	FM_FMRI_SCHEME_PKG		"pkg"
+#define	FM_FMRI_SCHEME_LEGACY		"legacy-hc"
+#define	FM_FMRI_SCHEME_ZFS		"zfs"
+#define	FM_FMRI_SCHEME_SW		"sw"
+
+/* Scheme versions */
+#define	FMD_SCHEME_VERSION0		0
+#define	FM_FMD_SCHEME_VERSION		FMD_SCHEME_VERSION0
+#define	DEV_SCHEME_VERSION0		0
+#define	FM_DEV_SCHEME_VERSION		DEV_SCHEME_VERSION0
+#define	FM_HC_VERS0			0
+#define	FM_HC_SCHEME_VERSION		FM_HC_VERS0
+#define	CPU_SCHEME_VERSION0		0
+#define	CPU_SCHEME_VERSION1		1
+#define	FM_CPU_SCHEME_VERSION		CPU_SCHEME_VERSION1
+#define	MEM_SCHEME_VERSION0		0
+#define	FM_MEM_SCHEME_VERSION		MEM_SCHEME_VERSION0
+#define	MOD_SCHEME_VERSION0		0
+#define	FM_MOD_SCHEME_VERSION		MOD_SCHEME_VERSION0
+#define	PKG_SCHEME_VERSION0		0
+#define	FM_PKG_SCHEME_VERSION		PKG_SCHEME_VERSION0
+#define	LEGACY_SCHEME_VERSION0		0
+#define	FM_LEGACY_SCHEME_VERSION	LEGACY_SCHEME_VERSION0
+#define	SVC_SCHEME_VERSION0		0
+#define	FM_SVC_SCHEME_VERSION		SVC_SCHEME_VERSION0
+#define	ZFS_SCHEME_VERSION0		0
+#define	FM_ZFS_SCHEME_VERSION		ZFS_SCHEME_VERSION0
+#define	SW_SCHEME_VERSION0		0
+#define	FM_SW_SCHEME_VERSION		SW_SCHEME_VERSION0
+
+/* hc scheme member names */
+#define	FM_FMRI_HC_SERIAL_ID		"serial"
+#define	FM_FMRI_HC_PART			"part"
+#define	FM_FMRI_HC_REVISION		"revision"
+#define	FM_FMRI_HC_ROOT			"hc-root"
+#define	FM_FMRI_HC_LIST_SZ		"hc-list-sz"
+#define	FM_FMRI_HC_LIST			"hc-list"
+#define	FM_FMRI_HC_SPECIFIC		"hc-specific"
+
+/* facility member names */
+#define	FM_FMRI_FACILITY_NAME		"facility-name"
+#define	FM_FMRI_FACILITY_TYPE		"facility-type"
+
+/* hc-list version and member names */
+#define	FM_FMRI_HC_NAME			"hc-name"
+#define	FM_FMRI_HC_ID			"hc-id"
+
+#define	HC_LIST_VERSION0		0
+#define	FM_HC_LIST_VERSION		HC_LIST_VERSION0
+
+/* hc-specific member names */
+#define	FM_FMRI_HC_SPECIFIC_OFFSET	"offset"
+#define	FM_FMRI_HC_SPECIFIC_PHYSADDR	"physaddr"
+
+/* fmd module scheme member names */
+#define	FM_FMRI_FMD_NAME		"mod-name"
+#define	FM_FMRI_FMD_VERSION		"mod-version"
+
+/* dev scheme member names */
+#define	FM_FMRI_DEV_ID			"devid"
+#define	FM_FMRI_DEV_TGTPTLUN0		"target-port-l0id"
+#define	FM_FMRI_DEV_PATH		"device-path"
+
+/* pkg scheme member names */
+#define	FM_FMRI_PKG_BASEDIR		"pkg-basedir"
+#define	FM_FMRI_PKG_INST		"pkg-inst"
+#define	FM_FMRI_PKG_VERSION		"pkg-version"
+
+/* svc scheme member names */
+#define	FM_FMRI_SVC_NAME		"svc-name"
+#define	FM_FMRI_SVC_INSTANCE		"svc-instance"
+#define	FM_FMRI_SVC_CONTRACT_ID		"svc-contract-id"
+
+/* svc-authority member names */
+#define	FM_FMRI_SVC_AUTH_SCOPE		"scope"
+#define	FM_FMRI_SVC_AUTH_SYSTEM_FQN	"system-fqn"
+
+/* cpu scheme member names */
+#define	FM_FMRI_CPU_ID			"cpuid"
+#define	FM_FMRI_CPU_SERIAL_ID		"serial"
+#define	FM_FMRI_CPU_MASK		"cpumask"
+#define	FM_FMRI_CPU_VID			"cpuvid"
+#define	FM_FMRI_CPU_CPUFRU		"cpufru"
+#define	FM_FMRI_CPU_CACHE_INDEX		"cacheindex"
+#define	FM_FMRI_CPU_CACHE_WAY		"cacheway"
+#define	FM_FMRI_CPU_CACHE_BIT		"cachebit"
+#define	FM_FMRI_CPU_CACHE_TYPE		"cachetype"
+
+#define	FM_FMRI_CPU_CACHE_TYPE_L2	0
+#define	FM_FMRI_CPU_CACHE_TYPE_L3	1
+
+/* legacy-hc scheme member names */
+#define	FM_FMRI_LEGACY_HC		"component"
+#define	FM_FMRI_LEGACY_HC_PREFIX	FM_FMRI_SCHEME_HC":///" \
+    FM_FMRI_LEGACY_HC"="
+
+/* mem scheme member names */
+#define	FM_FMRI_MEM_UNUM		"unum"
+#define	FM_FMRI_MEM_SERIAL_ID		"serial"
+#define	FM_FMRI_MEM_PHYSADDR		"physaddr"
+#define	FM_FMRI_MEM_MEMCONFIG		"memconfig"
+#define	FM_FMRI_MEM_OFFSET		"offset"
+
+/* mod scheme member names */
+#define	FM_FMRI_MOD_PKG			"mod-pkg"
+#define	FM_FMRI_MOD_NAME		"mod-name"
+#define	FM_FMRI_MOD_ID			"mod-id"
+#define	FM_FMRI_MOD_DESC		"mod-desc"
+
+/* zfs scheme member names */
+#define	FM_FMRI_ZFS_POOL		"pool"
+#define	FM_FMRI_ZFS_VDEV		"vdev"
+
+/* sw scheme member names - extra indentation for members of an nvlist */
+#define	FM_FMRI_SW_OBJ			"object"
+#define	FM_FMRI_SW_OBJ_PATH			"path"
+#define	FM_FMRI_SW_OBJ_ROOT			"root"
+#define	FM_FMRI_SW_OBJ_PKG			"pkg"
+#define	FM_FMRI_SW_SITE			"site"
+#define	FM_FMRI_SW_SITE_TOKEN			"token"
+#define	FM_FMRI_SW_SITE_MODULE			"module"
+#define	FM_FMRI_SW_SITE_FILE			"file"
+#define	FM_FMRI_SW_SITE_LINE			"line"
+#define	FM_FMRI_SW_SITE_FUNC			"func"
+#define	FM_FMRI_SW_CTXT			"context"
+#define	FM_FMRI_SW_CTXT_ORIGIN			"origin"
+#define	FM_FMRI_SW_CTXT_EXECNAME		"execname"
+#define	FM_FMRI_SW_CTXT_PID			"pid"
+#define	FM_FMRI_SW_CTXT_ZONE			"zone"
+#define	FM_FMRI_SW_CTXT_CTID			"ctid"
+#define	FM_FMRI_SW_CTXT_STACK			"stack"
+#define	FM_NVA_FREE		0	/* free allocator on nvlist_destroy */
+#define	FM_NVA_RETAIN		1	/* keep allocator on nvlist_destroy */
+
+extern nv_alloc_t *fm_nva_xcreate(char *, size_t);
+extern void fm_nva_xdestroy(nv_alloc_t *);
+extern nvlist_t *fm_nvlist_create(nv_alloc_t *);
+extern void fm_nvlist_destroy(nvlist_t *, int);
+extern void fm_ereport_set(nvlist_t *, int, const char *, uint64_t,
+    const nvlist_t *, ...);
+extern void fm_payload_set(nvlist_t *, ...);
+extern int i_fm_payload_set(nvlist_t *, const char *, va_list);
+extern void fm_fmri_hc_set(nvlist_t *, int, const nvlist_t *, nvlist_t *,
+    int, ...);
+extern void fm_fmri_dev_set(nvlist_t *, int, const nvlist_t *, const char *,
+    const char *, const char *);
+extern void fm_fmri_de_set(nvlist_t *, int, const nvlist_t *, const char *);
+extern void fm_fmri_cpu_set(nvlist_t *, int, const nvlist_t *, uint32_t,
+    uint8_t *, const char *);
+extern void fm_fmri_mem_set(nvlist_t *, int, const nvlist_t *, const char *,
+    const char *, uint64_t);
+extern void fm_fmri_zfs_set(nvlist_t *, int, uint64_t, uint64_t);
+extern void fm_fmri_hc_create(nvlist_t *, int, const nvlist_t *, nvlist_t *,
+    nvlist_t *, int, ...);
+
+extern uint64_t fm_ena_increment(uint64_t);
+extern uint64_t fm_ena_generate(uint64_t, uchar_t);
+extern uint64_t fm_ena_generate_cpu(uint64_t, processorid_t, uchar_t);
+extern uint64_t fm_ena_generation_get(uint64_t);
+extern uchar_t fm_ena_format_get(uint64_t);
+extern uint64_t fm_ena_id_get(uint64_t);
+extern uint64_t fm_ena_time_get(uint64_t);
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif /* _SYS_FM_PROTOCOL_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/include/sys/fm/util.h
@@ -0,0 +1,117 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
+ */
+
+#ifndef	_SYS_FM_UTIL_H
+#define	_SYS_FM_UTIL_H
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+#include <sys/nvpair.h>
+
+/*
+ * Shared user/kernel definitions for class length, error channel name,
+ * and kernel event publisher string.
+ */
+#define	FM_MAX_CLASS 100
+#define	FM_ERROR_CHAN	"com.sun:fm:error"
+#define	FM_PUB		"fm"
+
+/*
+ * ereport dump device transport support
+ *
+ * Ereports are written out to the dump device at a proscribed offset from the
+ * end, similar to in-transit log messages.  The ereports are represented as a
+ * erpt_dump_t header followed by ed_size bytes of packed native nvlist data.
+ *
+ * NOTE: All of these constants and the header must be defined so they have the
+ * same representation for *both* 32-bit and 64-bit producers and consumers.
+ */
+#define	ERPT_MAGIC	0xf00d4eddU
+#define	ERPT_MAX_ERRS	16
+#define	ERPT_DATA_SZ	(6 * 1024)
+#define	ERPT_EVCH_MAX	256
+#define	ERPT_HIWAT	64
+
+typedef struct erpt_dump {
+	uint32_t ed_magic;	/* ERPT_MAGIC or zero to indicate end */
+	uint32_t ed_chksum;	/* checksum32() of packed nvlist data */
+	uint32_t ed_size;	/* ereport (nvl) fixed buf size */
+	uint32_t ed_pad;	/* reserved for future use */
+	hrtime_t ed_hrt_nsec;	/* hrtime of this ereport */
+	hrtime_t ed_hrt_base;	/* hrtime sample corresponding to ed_tod_base */
+	struct {
+		uint64_t sec;	/* seconds since gettimeofday() Epoch */
+		uint64_t nsec;	/* nanoseconds past ed_tod_base.sec */
+	} ed_tod_base;
+} erpt_dump_t;
+
+#ifdef _KERNEL
+
+#define	ZEVENT_SHUTDOWN		0x1
+
+typedef void zevent_cb_t(nvlist_t *, nvlist_t *);
+
+typedef struct zevent_s {
+	nvlist_t	*ev_nvl;	/* protected by the zevent_lock */
+	nvlist_t	*ev_detector;	/* " */
+	list_t		ev_ze_list;	/* " */
+	list_node_t	ev_node;	/* " */
+	zevent_cb_t	*ev_cb;		/* " */
+	uint64_t	ev_eid;
+} zevent_t;
+
+typedef struct zfs_zevent {
+	zevent_t	*ze_zevent;	/* protected by the zevent_lock */
+	list_node_t	ze_node;	/* " */
+	uint64_t	ze_dropped;	/* " */
+} zfs_zevent_t;
+
+extern void fm_init(void);
+extern void fm_fini(void);
+extern void fm_nvprint(nvlist_t *);
+extern int zfs_zevent_post(nvlist_t *, nvlist_t *, zevent_cb_t *);
+extern void zfs_zevent_drain_all(int *);
+extern int zfs_zevent_fd_hold(int, minor_t *, zfs_zevent_t **);
+extern void zfs_zevent_fd_rele(int);
+extern int zfs_zevent_next(zfs_zevent_t *, nvlist_t **, uint64_t *, uint64_t *);
+extern int zfs_zevent_wait(zfs_zevent_t *);
+extern int zfs_zevent_seek(zfs_zevent_t *, uint64_t);
+extern void zfs_zevent_init(zfs_zevent_t **);
+extern void zfs_zevent_destroy(zfs_zevent_t *);
+
+#else
+
+static inline void fm_init(void) { }
+static inline void fm_fini(void) { }
+
+#endif  /* _KERNEL */
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif /* _SYS_FM_UTIL_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/include/sys/fs/Makefile.am
@@ -0,0 +1,18 @@
+COMMON_H = \
+	$(top_srcdir)/include/sys/fs/zfs.h
+
+KERNEL_H =
+
+USER_H =
+
+EXTRA_DIST = $(COMMON_H) $(KERNEL_H) $(USER_H)
+
+if CONFIG_USER
+libzfsdir = $(includedir)/libzfs/sys/fs
+libzfs_HEADERS = $(COMMON_H) $(USER_H)
+endif
+
+if CONFIG_KERNEL
+kerneldir = @prefix@/src/zfs-$(VERSION)/include/sys/fs
+kernel_HEADERS = $(COMMON_H) $(KERNEL_H)
+endif
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/include/sys/fs/Makefile.in
@@ -0,0 +1,752 @@
+# Makefile.in generated by automake 1.15 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2014 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+VPATH = @srcdir@
+am__is_gnu_make = { \
+  if test -z '$(MAKELEVEL)'; then \
+    false; \
+  elif test -n '$(MAKE_HOST)'; then \
+    true; \
+  elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+    true; \
+  else \
+    false; \
+  fi; \
+}
+am__make_running_with_option = \
+  case $${target_option-} in \
+      ?) ;; \
+      *) echo "am__make_running_with_option: internal error: invalid" \
+              "target option '$${target_option-}' specified" >&2; \
+         exit 1;; \
+  esac; \
+  has_opt=no; \
+  sane_makeflags=$$MAKEFLAGS; \
+  if $(am__is_gnu_make); then \
+    sane_makeflags=$$MFLAGS; \
+  else \
+    case $$MAKEFLAGS in \
+      *\\[\ \	]*) \
+        bs=\\; \
+        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
+    esac; \
+  fi; \
+  skip_next=no; \
+  strip_trailopt () \
+  { \
+    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+  }; \
+  for flg in $$sane_makeflags; do \
+    test $$skip_next = yes && { skip_next=no; continue; }; \
+    case $$flg in \
+      *=*|--*) continue;; \
+        -*I) strip_trailopt 'I'; skip_next=yes;; \
+      -*I?*) strip_trailopt 'I';; \
+        -*O) strip_trailopt 'O'; skip_next=yes;; \
+      -*O?*) strip_trailopt 'O';; \
+        -*l) strip_trailopt 'l'; skip_next=yes;; \
+      -*l?*) strip_trailopt 'l';; \
+      -[dEDm]) skip_next=yes;; \
+      -[JT]) skip_next=yes;; \
+    esac; \
+    case $$flg in \
+      *$$target_option*) has_opt=yes; break;; \
+    esac; \
+  done; \
+  test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+target_triplet = @target@
+subdir = include/sys/fs
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/config/always-no-bool-compare.m4 \
+	$(top_srcdir)/config/always-no-unused-but-set-variable.m4 \
+	$(top_srcdir)/config/dkms.m4 \
+	$(top_srcdir)/config/kernel-acl.m4 \
+	$(top_srcdir)/config/kernel-automount.m4 \
+	$(top_srcdir)/config/kernel-bdev-block-device-operations.m4 \
+	$(top_srcdir)/config/kernel-bdev-logical-size.m4 \
+	$(top_srcdir)/config/kernel-bdev-physical-size.m4 \
+	$(top_srcdir)/config/kernel-bdi-setup-and-register.m4 \
+	$(top_srcdir)/config/kernel-bio-bvec-iter.m4 \
+	$(top_srcdir)/config/kernel-bio-end-io-t-args.m4 \
+	$(top_srcdir)/config/kernel-bio-failfast.m4 \
+	$(top_srcdir)/config/kernel-bio-rw-barrier.m4 \
+	$(top_srcdir)/config/kernel-bio-rw-discard.m4 \
+	$(top_srcdir)/config/kernel-blk-queue-flush.m4 \
+	$(top_srcdir)/config/kernel-blk-queue-max-hw-sectors.m4 \
+	$(top_srcdir)/config/kernel-blk-queue-max-segments.m4 \
+	$(top_srcdir)/config/kernel-blkdev-get-by-path.m4 \
+	$(top_srcdir)/config/kernel-blkdev-get.m4 \
+	$(top_srcdir)/config/kernel-block-device-operations-release-void.m4 \
+	$(top_srcdir)/config/kernel-check-disk-size-change.m4 \
+	$(top_srcdir)/config/kernel-clear-inode.m4 \
+	$(top_srcdir)/config/kernel-commit-metadata.m4 \
+	$(top_srcdir)/config/kernel-create-nameidata.m4 \
+	$(top_srcdir)/config/kernel-current_bio_tail.m4 \
+	$(top_srcdir)/config/kernel-d-make-root.m4 \
+	$(top_srcdir)/config/kernel-d-obtain-alias.m4 \
+	$(top_srcdir)/config/kernel-d-prune-aliases.m4 \
+	$(top_srcdir)/config/kernel-declare-event-class.m4 \
+	$(top_srcdir)/config/kernel-dentry-operations.m4 \
+	$(top_srcdir)/config/kernel-dirty-inode.m4 \
+	$(top_srcdir)/config/kernel-discard-granularity.m4 \
+	$(top_srcdir)/config/kernel-elevator-change.m4 \
+	$(top_srcdir)/config/kernel-encode-fh-inode.m4 \
+	$(top_srcdir)/config/kernel-evict-inode.m4 \
+	$(top_srcdir)/config/kernel-fallocate.m4 \
+	$(top_srcdir)/config/kernel-file-inode.m4 \
+	$(top_srcdir)/config/kernel-fmode-t.m4 \
+	$(top_srcdir)/config/kernel-follow-down-one.m4 \
+	$(top_srcdir)/config/kernel-fsync.m4 \
+	$(top_srcdir)/config/kernel-generic_io_acct.m4 \
+	$(top_srcdir)/config/kernel-get-disk-ro.m4 \
+	$(top_srcdir)/config/kernel-get-gendisk.m4 \
+	$(top_srcdir)/config/kernel-get-link.m4 \
+	$(top_srcdir)/config/kernel-insert-inode-locked.m4 \
+	$(top_srcdir)/config/kernel-invalidate-bdev-args.m4 \
+	$(top_srcdir)/config/kernel-is_owner_or_cap.m4 \
+	$(top_srcdir)/config/kernel-kmap-atomic-args.m4 \
+	$(top_srcdir)/config/kernel-kobj-name-len.m4 \
+	$(top_srcdir)/config/kernel-lookup-bdev.m4 \
+	$(top_srcdir)/config/kernel-lookup-nameidata.m4 \
+	$(top_srcdir)/config/kernel-lseek-execute.m4 \
+	$(top_srcdir)/config/kernel-mk-request-fn.m4 \
+	$(top_srcdir)/config/kernel-mkdir-umode-t.m4 \
+	$(top_srcdir)/config/kernel-mount-nodev.m4 \
+	$(top_srcdir)/config/kernel-open-bdev-exclusive.m4 \
+	$(top_srcdir)/config/kernel-put-link.m4 \
+	$(top_srcdir)/config/kernel-security-inode-init.m4 \
+	$(top_srcdir)/config/kernel-set-nlink.m4 \
+	$(top_srcdir)/config/kernel-sget-args.m4 \
+	$(top_srcdir)/config/kernel-show-options.m4 \
+	$(top_srcdir)/config/kernel-shrink.m4 \
+	$(top_srcdir)/config/kernel-truncate-range.m4 \
+	$(top_srcdir)/config/kernel-truncate-setsize.m4 \
+	$(top_srcdir)/config/kernel-vfs-iterate.m4 \
+	$(top_srcdir)/config/kernel-vfs-rw-iterate.m4 \
+	$(top_srcdir)/config/kernel-xattr-handler.m4 \
+	$(top_srcdir)/config/kernel.m4 $(top_srcdir)/config/libtool.m4 \
+	$(top_srcdir)/config/ltoptions.m4 \
+	$(top_srcdir)/config/ltsugar.m4 \
+	$(top_srcdir)/config/ltversion.m4 \
+	$(top_srcdir)/config/lt~obsolete.m4 \
+	$(top_srcdir)/config/mount-helper.m4 \
+	$(top_srcdir)/config/user-arch.m4 \
+	$(top_srcdir)/config/user-dracut.m4 \
+	$(top_srcdir)/config/user-frame-larger-than.m4 \
+	$(top_srcdir)/config/user-libblkid.m4 \
+	$(top_srcdir)/config/user-libuuid.m4 \
+	$(top_srcdir)/config/user-runstatedir.m4 \
+	$(top_srcdir)/config/user-systemd.m4 \
+	$(top_srcdir)/config/user-sysvinit.m4 \
+	$(top_srcdir)/config/user-udev.m4 \
+	$(top_srcdir)/config/user-zlib.m4 $(top_srcdir)/config/user.m4 \
+	$(top_srcdir)/config/zfs-build.m4 \
+	$(top_srcdir)/config/zfs-meta.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(am__kernel_HEADERS_DIST) \
+	$(am__libzfs_HEADERS_DIST) $(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/zfs_config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo "  GEN     " $@;
+am__v_GEN_1 = 
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 = 
+SOURCES =
+DIST_SOURCES =
+am__can_run_installinfo = \
+  case $$AM_UPDATE_INFO_DIR in \
+    n|no|NO) false;; \
+    *) (install-info --version) >/dev/null 2>&1;; \
+  esac
+am__kernel_HEADERS_DIST = $(top_srcdir)/include/sys/fs/zfs.h
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+    $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+    *) f=$$p;; \
+  esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+  srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+  for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+  for p in $$list; do echo "$$p $$p"; done | \
+  sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+  $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+    if (++n[$$2] == $(am__install_max)) \
+      { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+    END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+  sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+  sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+  test -z "$$files" \
+    || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+    || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+         $(am__cd) "$$dir" && rm -f $$files; }; \
+  }
+am__installdirs = "$(DESTDIR)$(kerneldir)" "$(DESTDIR)$(libzfsdir)"
+am__libzfs_HEADERS_DIST = $(top_srcdir)/include/sys/fs/zfs.h
+HEADERS = $(kernel_HEADERS) $(libzfs_HEADERS)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates.  Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+  BEGIN { nonempty = 0; } \
+  { items[$$0] = 1; nonempty = 1; } \
+  END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique.  This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+  list='$(am__tagged_files)'; \
+  unique=`for i in $$list; do \
+    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+  done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+am__DIST_COMMON = $(srcdir)/Makefile.in
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ALIEN = @ALIEN@
+ALIEN_VERSION = @ALIEN_VERSION@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCAS = @CCAS@
+CCASDEPMODE = @CCASDEPMODE@
+CCASFLAGS = @CCASFLAGS@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEBUG_CFLAGS = @DEBUG_CFLAGS@
+DEBUG_DMU_TX = @DEBUG_DMU_TX@
+DEBUG_STACKFLAGS = @DEBUG_STACKFLAGS@
+DEBUG_ZFS = @DEBUG_ZFS@
+DEFAULT_INITCONF_DIR = @DEFAULT_INITCONF_DIR@
+DEFAULT_INIT_DIR = @DEFAULT_INIT_DIR@
+DEFAULT_INIT_SCRIPT = @DEFAULT_INIT_SCRIPT@
+DEFAULT_PACKAGE = @DEFAULT_PACKAGE@
+DEFINE_INITRAMFS = @DEFINE_INITRAMFS@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DPKG = @DPKG@
+DPKGBUILD = @DPKGBUILD@
+DPKGBUILD_VERSION = @DPKGBUILD_VERSION@
+DPKG_VERSION = @DPKG_VERSION@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+FRAME_LARGER_THAN = @FRAME_LARGER_THAN@
+GREP = @GREP@
+HAVE_ALIEN = @HAVE_ALIEN@
+HAVE_DPKG = @HAVE_DPKG@
+HAVE_DPKGBUILD = @HAVE_DPKGBUILD@
+HAVE_RPM = @HAVE_RPM@
+HAVE_RPMBUILD = @HAVE_RPMBUILD@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+KERNELCPPFLAGS = @KERNELCPPFLAGS@
+KERNELMAKE_PARAMS = @KERNELMAKE_PARAMS@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBBLKID = @LIBBLKID@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIBUUID = @LIBUUID@
+LINUX = @LINUX@
+LINUX_OBJ = @LINUX_OBJ@
+LINUX_SYMBOLS = @LINUX_SYMBOLS@
+LINUX_VERSION = @LINUX_VERSION@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NO_BOOL_COMPARE = @NO_BOOL_COMPARE@
+NO_UNUSED_BUT_SET_VARIABLE = @NO_UNUSED_BUT_SET_VARIABLE@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+RANLIB = @RANLIB@
+RELEASE = @RELEASE@
+RPM = @RPM@
+RPMBUILD = @RPMBUILD@
+RPMBUILD_VERSION = @RPMBUILD_VERSION@
+RPM_DEFINE_COMMON = @RPM_DEFINE_COMMON@
+RPM_DEFINE_DKMS = @RPM_DEFINE_DKMS@
+RPM_DEFINE_KMOD = @RPM_DEFINE_KMOD@
+RPM_DEFINE_UTIL = @RPM_DEFINE_UTIL@
+RPM_SPEC_DIR = @RPM_SPEC_DIR@
+RPM_VERSION = @RPM_VERSION@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SPL = @SPL@
+SPL_OBJ = @SPL_OBJ@
+SPL_SYMBOLS = @SPL_SYMBOLS@
+SPL_VERSION = @SPL_VERSION@
+SRPM_DEFINE_COMMON = @SRPM_DEFINE_COMMON@
+SRPM_DEFINE_DKMS = @SRPM_DEFINE_DKMS@
+SRPM_DEFINE_KMOD = @SRPM_DEFINE_KMOD@
+SRPM_DEFINE_UTIL = @SRPM_DEFINE_UTIL@
+STRIP = @STRIP@
+TARGET_ASM_DIR = @TARGET_ASM_DIR@
+VENDOR = @VENDOR@
+VERSION = @VERSION@
+ZFS_CONFIG = @ZFS_CONFIG@
+ZFS_INIT_SYSTEMD = @ZFS_INIT_SYSTEMD@
+ZFS_INIT_SYSV = @ZFS_INIT_SYSV@
+ZFS_META_ALIAS = @ZFS_META_ALIAS@
+ZFS_META_AUTHOR = @ZFS_META_AUTHOR@
+ZFS_META_DATA = @ZFS_META_DATA@
+ZFS_META_LICENSE = @ZFS_META_LICENSE@
+ZFS_META_LT_AGE = @ZFS_META_LT_AGE@
+ZFS_META_LT_CURRENT = @ZFS_META_LT_CURRENT@
+ZFS_META_LT_REVISION = @ZFS_META_LT_REVISION@
+ZFS_META_NAME = @ZFS_META_NAME@
+ZFS_META_RELEASE = @ZFS_META_RELEASE@
+ZFS_META_VERSION = @ZFS_META_VERSION@
+ZFS_MODULE_LOAD = @ZFS_MODULE_LOAD@
+ZLIB = @ZLIB@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dracutdir = @dracutdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+modulesloaddir = @modulesloaddir@
+mounthelperdir = @mounthelperdir@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+runstatedir = @runstatedir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+systemdpresetdir = @systemdpresetdir@
+systemdunitdir = @systemdunitdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+udevdir = @udevdir@
+udevruledir = @udevruledir@
+COMMON_H = \
+	$(top_srcdir)/include/sys/fs/zfs.h
+
+KERNEL_H = 
+USER_H = 
+EXTRA_DIST = $(COMMON_H) $(KERNEL_H) $(USER_H)
+@CONFIG_USER_TRUE@libzfsdir = $(includedir)/libzfs/sys/fs
+@CONFIG_USER_TRUE@libzfs_HEADERS = $(COMMON_H) $(USER_H)
+@CONFIG_KERNEL_TRUE@kerneldir = @prefix@/src/zfs-$(VERSION)/include/sys/fs
+@CONFIG_KERNEL_TRUE@kernel_HEADERS = $(COMMON_H) $(KERNEL_H)
+all: all-am
+
+.SUFFIXES:
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+	        && { if test -f $@; then exit 0; else break; fi; }; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu include/sys/fs/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --gnu include/sys/fs/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+	esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
+install-kernelHEADERS: $(kernel_HEADERS)
+	@$(NORMAL_INSTALL)
+	@list='$(kernel_HEADERS)'; test -n "$(kerneldir)" || list=; \
+	if test -n "$$list"; then \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(kerneldir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(kerneldir)" || exit 1; \
+	fi; \
+	for p in $$list; do \
+	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+	  echo "$$d$$p"; \
+	done | $(am__base_list) | \
+	while read files; do \
+	  echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(kerneldir)'"; \
+	  $(INSTALL_HEADER) $$files "$(DESTDIR)$(kerneldir)" || exit $$?; \
+	done
+
+uninstall-kernelHEADERS:
+	@$(NORMAL_UNINSTALL)
+	@list='$(kernel_HEADERS)'; test -n "$(kerneldir)" || list=; \
+	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+	dir='$(DESTDIR)$(kerneldir)'; $(am__uninstall_files_from_dir)
+install-libzfsHEADERS: $(libzfs_HEADERS)
+	@$(NORMAL_INSTALL)
+	@list='$(libzfs_HEADERS)'; test -n "$(libzfsdir)" || list=; \
+	if test -n "$$list"; then \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(libzfsdir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(libzfsdir)" || exit 1; \
+	fi; \
+	for p in $$list; do \
+	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+	  echo "$$d$$p"; \
+	done | $(am__base_list) | \
+	while read files; do \
+	  echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(libzfsdir)'"; \
+	  $(INSTALL_HEADER) $$files "$(DESTDIR)$(libzfsdir)" || exit $$?; \
+	done
+
+uninstall-libzfsHEADERS:
+	@$(NORMAL_UNINSTALL)
+	@list='$(libzfs_HEADERS)'; test -n "$(libzfsdir)" || list=; \
+	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+	dir='$(DESTDIR)$(libzfsdir)'; $(am__uninstall_files_from_dir)
+
+ID: $(am__tagged_files)
+	$(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	set x; \
+	here=`pwd`; \
+	$(am__define_uniq_tagged_files); \
+	shift; \
+	if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+	  test -n "$$unique" || unique=$$empty_fix; \
+	  if test $$# -gt 0; then \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      "$$@" $$unique; \
+	  else \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      $$unique; \
+	  fi; \
+	fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	$(am__define_uniq_tagged_files); \
+	test -z "$(CTAGS_ARGS)$$unique" \
+	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+	     $$unique
+
+GTAGS:
+	here=`$(am__cd) $(top_builddir) && pwd` \
+	  && $(am__cd) $(top_srcdir) \
+	  && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+	list='$(am__tagged_files)'; \
+	case "$(srcdir)" in \
+	  [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+	  *) sdir=$(subdir)/$(srcdir) ;; \
+	esac; \
+	for i in $$list; do \
+	  if test -f "$$i"; then \
+	    echo "$(subdir)/$$i"; \
+	  else \
+	    echo "$$sdir/$$i"; \
+	  fi; \
+	done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	list='$(DISTFILES)'; \
+	  dist_files=`for file in $$list; do echo $$file; done | \
+	  sed -e "s|^$$srcdirstrip/||;t" \
+	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+	case $$dist_files in \
+	  */*) $(MKDIR_P) `echo "$$dist_files" | \
+			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+			   sort -u` ;; \
+	esac; \
+	for file in $$dist_files; do \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  if test -d $$d/$$file; then \
+	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+	    if test -d "$(distdir)/$$file"; then \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+	  else \
+	    test -f "$(distdir)/$$file" \
+	    || cp -p $$d/$$file "$(distdir)/$$file" \
+	    || exit 1; \
+	  fi; \
+	done
+check-am: all-am
+check: check-am
+all-am: Makefile $(HEADERS)
+installdirs:
+	for dir in "$(DESTDIR)$(kerneldir)" "$(DESTDIR)$(libzfsdir)"; do \
+	  test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+	done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+	if test -z '$(STRIP)'; then \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	      install; \
+	else \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+	fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-am
+	-rm -f Makefile
+distclean-am: clean-am distclean-generic distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-kernelHEADERS install-libzfsHEADERS
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-kernelHEADERS uninstall-libzfsHEADERS
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \
+	clean-libtool cscopelist-am ctags ctags-am distclean \
+	distclean-generic distclean-libtool distclean-tags distdir dvi \
+	dvi-am html html-am info info-am install install-am \
+	install-data install-data-am install-dvi install-dvi-am \
+	install-exec install-exec-am install-html install-html-am \
+	install-info install-info-am install-kernelHEADERS \
+	install-libzfsHEADERS install-man install-pdf install-pdf-am \
+	install-ps install-ps-am install-strip installcheck \
+	installcheck-am installdirs maintainer-clean \
+	maintainer-clean-generic mostlyclean mostlyclean-generic \
+	mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \
+	uninstall-am uninstall-kernelHEADERS uninstall-libzfsHEADERS
+
+.PRECIOUS: Makefile
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/include/sys/fs/zfs.h
@@ -0,0 +1,999 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2014 by Delphix. All rights reserved.
+ * Copyright 2011 Nexenta Systems, Inc.  All rights reserved.
+ * Copyright (c) 2013, Joyent, Inc. All rights reserved.
+ */
+
+/* Portions Copyright 2010 Robert Milkowski */
+
+#ifndef	_SYS_FS_ZFS_H
+#define	_SYS_FS_ZFS_H
+
+#include <sys/time.h>
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+/*
+ * Types and constants shared between userland and the kernel.
+ */
+
+/*
+ * Each dataset can be one of the following types.  These constants can be
+ * combined into masks that can be passed to various functions.
+ */
+typedef enum {
+	ZFS_TYPE_FILESYSTEM	= (1 << 0),
+	ZFS_TYPE_SNAPSHOT	= (1 << 1),
+	ZFS_TYPE_VOLUME		= (1 << 2),
+	ZFS_TYPE_POOL		= (1 << 3),
+	ZFS_TYPE_BOOKMARK	= (1 << 4)
+} zfs_type_t;
+
+typedef enum dmu_objset_type {
+	DMU_OST_NONE,
+	DMU_OST_META,
+	DMU_OST_ZFS,
+	DMU_OST_ZVOL,
+	DMU_OST_OTHER,			/* For testing only! */
+	DMU_OST_ANY,			/* Be careful! */
+	DMU_OST_NUMTYPES
+} dmu_objset_type_t;
+
+#define	ZFS_TYPE_DATASET	\
+	(ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME | ZFS_TYPE_SNAPSHOT)
+
+#define	ZAP_MAXNAMELEN 256
+#define	ZAP_MAXVALUELEN (1024 * 8)
+#define	ZAP_OLDMAXVALUELEN 1024
+
+/*
+ * Dataset properties are identified by these constants and must be added to
+ * the end of this list to ensure that external consumers are not affected
+ * by the change. If you make any changes to this list, be sure to update
+ * the property table in module/zcommon/zfs_prop.c.
+ */
+typedef enum {
+	ZFS_PROP_TYPE,
+	ZFS_PROP_CREATION,
+	ZFS_PROP_USED,
+	ZFS_PROP_AVAILABLE,
+	ZFS_PROP_REFERENCED,
+	ZFS_PROP_COMPRESSRATIO,
+	ZFS_PROP_MOUNTED,
+	ZFS_PROP_ORIGIN,
+	ZFS_PROP_QUOTA,
+	ZFS_PROP_RESERVATION,
+	ZFS_PROP_VOLSIZE,
+	ZFS_PROP_VOLBLOCKSIZE,
+	ZFS_PROP_RECORDSIZE,
+	ZFS_PROP_MOUNTPOINT,
+	ZFS_PROP_SHARENFS,
+	ZFS_PROP_CHECKSUM,
+	ZFS_PROP_COMPRESSION,
+	ZFS_PROP_ATIME,
+	ZFS_PROP_DEVICES,
+	ZFS_PROP_EXEC,
+	ZFS_PROP_SETUID,
+	ZFS_PROP_READONLY,
+	ZFS_PROP_ZONED,
+	ZFS_PROP_SNAPDIR,
+	ZFS_PROP_PRIVATE,		/* not exposed to user, temporary */
+	ZFS_PROP_ACLINHERIT,
+	ZFS_PROP_CREATETXG,		/* not exposed to the user */
+	ZFS_PROP_NAME,			/* not exposed to the user */
+	ZFS_PROP_CANMOUNT,
+	ZFS_PROP_ISCSIOPTIONS,		/* not exposed to the user */
+	ZFS_PROP_XATTR,
+	ZFS_PROP_NUMCLONES,		/* not exposed to the user */
+	ZFS_PROP_COPIES,
+	ZFS_PROP_VERSION,
+	ZFS_PROP_UTF8ONLY,
+	ZFS_PROP_NORMALIZE,
+	ZFS_PROP_CASE,
+	ZFS_PROP_VSCAN,
+	ZFS_PROP_NBMAND,
+	ZFS_PROP_SHARESMB,
+	ZFS_PROP_REFQUOTA,
+	ZFS_PROP_REFRESERVATION,
+	ZFS_PROP_GUID,
+	ZFS_PROP_PRIMARYCACHE,
+	ZFS_PROP_SECONDARYCACHE,
+	ZFS_PROP_USEDSNAP,
+	ZFS_PROP_USEDDS,
+	ZFS_PROP_USEDCHILD,
+	ZFS_PROP_USEDREFRESERV,
+	ZFS_PROP_USERACCOUNTING,	/* not exposed to the user */
+	ZFS_PROP_STMF_SHAREINFO,	/* not exposed to the user */
+	ZFS_PROP_DEFER_DESTROY,
+	ZFS_PROP_USERREFS,
+	ZFS_PROP_LOGBIAS,
+	ZFS_PROP_UNIQUE,		/* not exposed to the user */
+	ZFS_PROP_OBJSETID,		/* not exposed to the user */
+	ZFS_PROP_DEDUP,
+	ZFS_PROP_MLSLABEL,
+	ZFS_PROP_SYNC,
+	ZFS_PROP_REFRATIO,
+	ZFS_PROP_WRITTEN,
+	ZFS_PROP_CLONES,
+	ZFS_PROP_LOGICALUSED,
+	ZFS_PROP_LOGICALREFERENCED,
+	ZFS_PROP_INCONSISTENT,		/* not exposed to the user */
+	ZFS_PROP_FILESYSTEM_LIMIT,
+	ZFS_PROP_SNAPSHOT_LIMIT,
+	ZFS_PROP_FILESYSTEM_COUNT,
+	ZFS_PROP_SNAPSHOT_COUNT,
+	ZFS_PROP_SNAPDEV,
+	ZFS_PROP_ACLTYPE,
+	ZFS_PROP_SELINUX_CONTEXT,
+	ZFS_PROP_SELINUX_FSCONTEXT,
+	ZFS_PROP_SELINUX_DEFCONTEXT,
+	ZFS_PROP_SELINUX_ROOTCONTEXT,
+	ZFS_PROP_RELATIME,
+	ZFS_PROP_REDUNDANT_METADATA,
+	ZFS_PROP_OVERLAY,
+	ZFS_NUM_PROPS
+} zfs_prop_t;
+
+typedef enum {
+	ZFS_PROP_USERUSED,
+	ZFS_PROP_USERQUOTA,
+	ZFS_PROP_GROUPUSED,
+	ZFS_PROP_GROUPQUOTA,
+	ZFS_NUM_USERQUOTA_PROPS
+} zfs_userquota_prop_t;
+
+extern const char *zfs_userquota_prop_prefixes[ZFS_NUM_USERQUOTA_PROPS];
+
+/*
+ * Pool properties are identified by these constants and must be added to the
+ * end of this list to ensure that external consumers are not affected
+ * by the change. If you make any changes to this list, be sure to update
+ * the property table in module/zcommon/zpool_prop.c.
+ */
+typedef enum {
+	ZPOOL_PROP_NAME,
+	ZPOOL_PROP_SIZE,
+	ZPOOL_PROP_CAPACITY,
+	ZPOOL_PROP_ALTROOT,
+	ZPOOL_PROP_HEALTH,
+	ZPOOL_PROP_GUID,
+	ZPOOL_PROP_VERSION,
+	ZPOOL_PROP_BOOTFS,
+	ZPOOL_PROP_DELEGATION,
+	ZPOOL_PROP_AUTOREPLACE,
+	ZPOOL_PROP_CACHEFILE,
+	ZPOOL_PROP_FAILUREMODE,
+	ZPOOL_PROP_LISTSNAPS,
+	ZPOOL_PROP_AUTOEXPAND,
+	ZPOOL_PROP_DEDUPDITTO,
+	ZPOOL_PROP_DEDUPRATIO,
+	ZPOOL_PROP_FREE,
+	ZPOOL_PROP_ALLOCATED,
+	ZPOOL_PROP_READONLY,
+	ZPOOL_PROP_ASHIFT,
+	ZPOOL_PROP_COMMENT,
+	ZPOOL_PROP_EXPANDSZ,
+	ZPOOL_PROP_FREEING,
+	ZPOOL_PROP_FRAGMENTATION,
+	ZPOOL_PROP_LEAKED,
+	ZPOOL_PROP_MAXBLOCKSIZE,
+	ZPOOL_PROP_TNAME,
+	ZPOOL_NUM_PROPS
+} zpool_prop_t;
+
+/* Small enough to not hog a whole line of printout in zpool(1M). */
+#define	ZPROP_MAX_COMMENT	32
+
+#define	ZPROP_CONT		-2
+#define	ZPROP_INVAL		-1
+
+#define	ZPROP_VALUE		"value"
+#define	ZPROP_SOURCE		"source"
+
+typedef enum {
+	ZPROP_SRC_NONE = 0x1,
+	ZPROP_SRC_DEFAULT = 0x2,
+	ZPROP_SRC_TEMPORARY = 0x4,
+	ZPROP_SRC_LOCAL = 0x8,
+	ZPROP_SRC_INHERITED = 0x10,
+	ZPROP_SRC_RECEIVED = 0x20
+} zprop_source_t;
+
+#define	ZPROP_SRC_ALL	0x3f
+
+#define	ZPROP_SOURCE_VAL_RECVD	"$recvd"
+#define	ZPROP_N_MORE_ERRORS	"N_MORE_ERRORS"
+/*
+ * Dataset flag implemented as a special entry in the props zap object
+ * indicating that the dataset has received properties on or after
+ * SPA_VERSION_RECVD_PROPS. The first such receive blows away local properties
+ * just as it did in earlier versions, and thereafter, local properties are
+ * preserved.
+ */
+#define	ZPROP_HAS_RECVD		"$hasrecvd"
+
+typedef enum {
+	ZPROP_ERR_NOCLEAR = 0x1, /* failure to clear existing props */
+	ZPROP_ERR_NORESTORE = 0x2 /* failure to restore props on error */
+} zprop_errflags_t;
+
+typedef int (*zprop_func)(int, void *);
+
+/*
+ * Properties to be set on the root file system of a new pool
+ * are stuffed into their own nvlist, which is then included in
+ * the properties nvlist with the pool properties.
+ */
+#define	ZPOOL_ROOTFS_PROPS	"root-props-nvl"
+
+/*
+ * Dataset property functions shared between libzfs and kernel.
+ */
+const char *zfs_prop_default_string(zfs_prop_t);
+uint64_t zfs_prop_default_numeric(zfs_prop_t);
+boolean_t zfs_prop_readonly(zfs_prop_t);
+boolean_t zfs_prop_inheritable(zfs_prop_t);
+boolean_t zfs_prop_setonce(zfs_prop_t);
+const char *zfs_prop_to_name(zfs_prop_t);
+zfs_prop_t zfs_name_to_prop(const char *);
+boolean_t zfs_prop_user(const char *);
+boolean_t zfs_prop_userquota(const char *);
+boolean_t zfs_prop_written(const char *);
+int zfs_prop_index_to_string(zfs_prop_t, uint64_t, const char **);
+int zfs_prop_string_to_index(zfs_prop_t, const char *, uint64_t *);
+uint64_t zfs_prop_random_value(zfs_prop_t, uint64_t seed);
+boolean_t zfs_prop_valid_for_type(int, zfs_type_t, boolean_t);
+
+/*
+ * Pool property functions shared between libzfs and kernel.
+ */
+zpool_prop_t zpool_name_to_prop(const char *);
+const char *zpool_prop_to_name(zpool_prop_t);
+const char *zpool_prop_default_string(zpool_prop_t);
+uint64_t zpool_prop_default_numeric(zpool_prop_t);
+boolean_t zpool_prop_readonly(zpool_prop_t);
+boolean_t zpool_prop_feature(const char *);
+boolean_t zpool_prop_unsupported(const char *);
+int zpool_prop_index_to_string(zpool_prop_t, uint64_t, const char **);
+int zpool_prop_string_to_index(zpool_prop_t, const char *, uint64_t *);
+uint64_t zpool_prop_random_value(zpool_prop_t, uint64_t seed);
+
+/*
+ * Definitions for the Delegation.
+ */
+typedef enum {
+	ZFS_DELEG_WHO_UNKNOWN = 0,
+	ZFS_DELEG_USER = 'u',
+	ZFS_DELEG_USER_SETS = 'U',
+	ZFS_DELEG_GROUP = 'g',
+	ZFS_DELEG_GROUP_SETS = 'G',
+	ZFS_DELEG_EVERYONE = 'e',
+	ZFS_DELEG_EVERYONE_SETS = 'E',
+	ZFS_DELEG_CREATE = 'c',
+	ZFS_DELEG_CREATE_SETS = 'C',
+	ZFS_DELEG_NAMED_SET = 's',
+	ZFS_DELEG_NAMED_SET_SETS = 'S'
+} zfs_deleg_who_type_t;
+
+typedef enum {
+	ZFS_DELEG_NONE = 0,
+	ZFS_DELEG_PERM_LOCAL = 1,
+	ZFS_DELEG_PERM_DESCENDENT = 2,
+	ZFS_DELEG_PERM_LOCALDESCENDENT = 3,
+	ZFS_DELEG_PERM_CREATE = 4
+} zfs_deleg_inherit_t;
+
+#define	ZFS_DELEG_PERM_UID	"uid"
+#define	ZFS_DELEG_PERM_GID	"gid"
+#define	ZFS_DELEG_PERM_GROUPS	"groups"
+
+#define	ZFS_MLSLABEL_DEFAULT	"none"
+
+#define	ZFS_SMB_ACL_SRC		"src"
+#define	ZFS_SMB_ACL_TARGET	"target"
+
+typedef enum {
+	ZFS_CANMOUNT_OFF = 0,
+	ZFS_CANMOUNT_ON = 1,
+	ZFS_CANMOUNT_NOAUTO = 2
+} zfs_canmount_type_t;
+
+typedef enum {
+	ZFS_LOGBIAS_LATENCY = 0,
+	ZFS_LOGBIAS_THROUGHPUT = 1
+} zfs_logbias_op_t;
+
+typedef enum zfs_share_op {
+	ZFS_SHARE_NFS = 0,
+	ZFS_UNSHARE_NFS = 1,
+	ZFS_SHARE_SMB = 2,
+	ZFS_UNSHARE_SMB = 3
+} zfs_share_op_t;
+
+typedef enum zfs_smb_acl_op {
+	ZFS_SMB_ACL_ADD,
+	ZFS_SMB_ACL_REMOVE,
+	ZFS_SMB_ACL_RENAME,
+	ZFS_SMB_ACL_PURGE
+} zfs_smb_acl_op_t;
+
+typedef enum zfs_cache_type {
+	ZFS_CACHE_NONE = 0,
+	ZFS_CACHE_METADATA = 1,
+	ZFS_CACHE_ALL = 2
+} zfs_cache_type_t;
+
+typedef enum {
+	ZFS_SYNC_STANDARD = 0,
+	ZFS_SYNC_ALWAYS = 1,
+	ZFS_SYNC_DISABLED = 2
+} zfs_sync_type_t;
+
+typedef enum {
+	ZFS_XATTR_OFF = 0,
+	ZFS_XATTR_DIR = 1,
+	ZFS_XATTR_SA = 2
+} zfs_xattr_type_t;
+
+typedef enum {
+	ZFS_REDUNDANT_METADATA_ALL,
+	ZFS_REDUNDANT_METADATA_MOST
+} zfs_redundant_metadata_type_t;
+
+/*
+ * On-disk version number.
+ */
+#define	SPA_VERSION_1			1ULL
+#define	SPA_VERSION_2			2ULL
+#define	SPA_VERSION_3			3ULL
+#define	SPA_VERSION_4			4ULL
+#define	SPA_VERSION_5			5ULL
+#define	SPA_VERSION_6			6ULL
+#define	SPA_VERSION_7			7ULL
+#define	SPA_VERSION_8			8ULL
+#define	SPA_VERSION_9			9ULL
+#define	SPA_VERSION_10			10ULL
+#define	SPA_VERSION_11			11ULL
+#define	SPA_VERSION_12			12ULL
+#define	SPA_VERSION_13			13ULL
+#define	SPA_VERSION_14			14ULL
+#define	SPA_VERSION_15			15ULL
+#define	SPA_VERSION_16			16ULL
+#define	SPA_VERSION_17			17ULL
+#define	SPA_VERSION_18			18ULL
+#define	SPA_VERSION_19			19ULL
+#define	SPA_VERSION_20			20ULL
+#define	SPA_VERSION_21			21ULL
+#define	SPA_VERSION_22			22ULL
+#define	SPA_VERSION_23			23ULL
+#define	SPA_VERSION_24			24ULL
+#define	SPA_VERSION_25			25ULL
+#define	SPA_VERSION_26			26ULL
+#define	SPA_VERSION_27			27ULL
+#define	SPA_VERSION_28			28ULL
+#define	SPA_VERSION_5000		5000ULL
+
+/*
+ * When bumping up SPA_VERSION, make sure GRUB ZFS understands the on-disk
+ * format change. Go to usr/src/grub/grub-0.97/stage2/{zfs-include/, fsys_zfs*},
+ * and do the appropriate changes.  Also bump the version number in
+ * usr/src/grub/capability.
+ */
+#define	SPA_VERSION			SPA_VERSION_5000
+#define	SPA_VERSION_STRING		"5000"
+
+/*
+ * Symbolic names for the changes that caused a SPA_VERSION switch.
+ * Used in the code when checking for presence or absence of a feature.
+ * Feel free to define multiple symbolic names for each version if there
+ * were multiple changes to on-disk structures during that version.
+ *
+ * NOTE: When checking the current SPA_VERSION in your code, be sure
+ *       to use spa_version() since it reports the version of the
+ *       last synced uberblock.  Checking the in-flight version can
+ *       be dangerous in some cases.
+ */
+#define	SPA_VERSION_INITIAL		SPA_VERSION_1
+#define	SPA_VERSION_DITTO_BLOCKS	SPA_VERSION_2
+#define	SPA_VERSION_SPARES		SPA_VERSION_3
+#define	SPA_VERSION_RAIDZ2		SPA_VERSION_3
+#define	SPA_VERSION_BPOBJ_ACCOUNT	SPA_VERSION_3
+#define	SPA_VERSION_RAIDZ_DEFLATE	SPA_VERSION_3
+#define	SPA_VERSION_DNODE_BYTES		SPA_VERSION_3
+#define	SPA_VERSION_ZPOOL_HISTORY	SPA_VERSION_4
+#define	SPA_VERSION_GZIP_COMPRESSION	SPA_VERSION_5
+#define	SPA_VERSION_BOOTFS		SPA_VERSION_6
+#define	SPA_VERSION_SLOGS		SPA_VERSION_7
+#define	SPA_VERSION_DELEGATED_PERMS	SPA_VERSION_8
+#define	SPA_VERSION_FUID		SPA_VERSION_9
+#define	SPA_VERSION_REFRESERVATION	SPA_VERSION_9
+#define	SPA_VERSION_REFQUOTA		SPA_VERSION_9
+#define	SPA_VERSION_UNIQUE_ACCURATE	SPA_VERSION_9
+#define	SPA_VERSION_L2CACHE		SPA_VERSION_10
+#define	SPA_VERSION_NEXT_CLONES		SPA_VERSION_11
+#define	SPA_VERSION_ORIGIN		SPA_VERSION_11
+#define	SPA_VERSION_DSL_SCRUB		SPA_VERSION_11
+#define	SPA_VERSION_SNAP_PROPS		SPA_VERSION_12
+#define	SPA_VERSION_USED_BREAKDOWN	SPA_VERSION_13
+#define	SPA_VERSION_PASSTHROUGH_X	SPA_VERSION_14
+#define	SPA_VERSION_USERSPACE		SPA_VERSION_15
+#define	SPA_VERSION_STMF_PROP		SPA_VERSION_16
+#define	SPA_VERSION_RAIDZ3		SPA_VERSION_17
+#define	SPA_VERSION_USERREFS		SPA_VERSION_18
+#define	SPA_VERSION_HOLES		SPA_VERSION_19
+#define	SPA_VERSION_ZLE_COMPRESSION	SPA_VERSION_20
+#define	SPA_VERSION_DEDUP		SPA_VERSION_21
+#define	SPA_VERSION_RECVD_PROPS		SPA_VERSION_22
+#define	SPA_VERSION_SLIM_ZIL		SPA_VERSION_23
+#define	SPA_VERSION_SA			SPA_VERSION_24
+#define	SPA_VERSION_SCAN		SPA_VERSION_25
+#define	SPA_VERSION_DIR_CLONES		SPA_VERSION_26
+#define	SPA_VERSION_DEADLISTS		SPA_VERSION_26
+#define	SPA_VERSION_FAST_SNAP		SPA_VERSION_27
+#define	SPA_VERSION_MULTI_REPLACE	SPA_VERSION_28
+#define	SPA_VERSION_BEFORE_FEATURES	SPA_VERSION_28
+#define	SPA_VERSION_FEATURES		SPA_VERSION_5000
+
+#define	SPA_VERSION_IS_SUPPORTED(v) \
+	(((v) >= SPA_VERSION_INITIAL && (v) <= SPA_VERSION_BEFORE_FEATURES) || \
+	((v) >= SPA_VERSION_FEATURES && (v) <= SPA_VERSION))
+
+/*
+ * ZPL version - rev'd whenever an incompatible on-disk format change
+ * occurs.  This is independent of SPA/DMU/ZAP versioning.  You must
+ * also update the version_table[] and help message in zfs_prop.c.
+ *
+ * When changing, be sure to teach GRUB how to read the new format!
+ * See usr/src/grub/grub-0.97/stage2/{zfs-include/,fsys_zfs*}
+ */
+#define	ZPL_VERSION_1			1ULL
+#define	ZPL_VERSION_2			2ULL
+#define	ZPL_VERSION_3			3ULL
+#define	ZPL_VERSION_4			4ULL
+#define	ZPL_VERSION_5			5ULL
+#define	ZPL_VERSION			ZPL_VERSION_5
+#define	ZPL_VERSION_STRING		"5"
+
+#define	ZPL_VERSION_INITIAL		ZPL_VERSION_1
+#define	ZPL_VERSION_DIRENT_TYPE		ZPL_VERSION_2
+#define	ZPL_VERSION_FUID		ZPL_VERSION_3
+#define	ZPL_VERSION_NORMALIZATION	ZPL_VERSION_3
+#define	ZPL_VERSION_SYSATTR		ZPL_VERSION_3
+#define	ZPL_VERSION_USERSPACE		ZPL_VERSION_4
+#define	ZPL_VERSION_SA			ZPL_VERSION_5
+
+/* Rewind request information */
+#define	ZPOOL_NO_REWIND		1  /* No policy - default behavior */
+#define	ZPOOL_NEVER_REWIND	2  /* Do not search for best txg or rewind */
+#define	ZPOOL_TRY_REWIND	4  /* Search for best txg, but do not rewind */
+#define	ZPOOL_DO_REWIND		8  /* Rewind to best txg w/in deferred frees */
+#define	ZPOOL_EXTREME_REWIND	16 /* Allow extreme measures to find best txg */
+#define	ZPOOL_REWIND_MASK	28 /* All the possible rewind bits */
+#define	ZPOOL_REWIND_POLICIES	31 /* All the possible policy bits */
+
+typedef struct zpool_rewind_policy {
+	uint32_t	zrp_request;	/* rewind behavior requested */
+	uint64_t	zrp_maxmeta;	/* max acceptable meta-data errors */
+	uint64_t	zrp_maxdata;	/* max acceptable data errors */
+	uint64_t	zrp_txg;	/* specific txg to load */
+} zpool_rewind_policy_t;
+
+/*
+ * The following are configuration names used in the nvlist describing a pool's
+ * configuration.
+ */
+#define	ZPOOL_CONFIG_VERSION		"version"
+#define	ZPOOL_CONFIG_POOL_NAME		"name"
+#define	ZPOOL_CONFIG_POOL_STATE		"state"
+#define	ZPOOL_CONFIG_POOL_TXG		"txg"
+#define	ZPOOL_CONFIG_POOL_GUID		"pool_guid"
+#define	ZPOOL_CONFIG_CREATE_TXG		"create_txg"
+#define	ZPOOL_CONFIG_TOP_GUID		"top_guid"
+#define	ZPOOL_CONFIG_VDEV_TREE		"vdev_tree"
+#define	ZPOOL_CONFIG_TYPE		"type"
+#define	ZPOOL_CONFIG_CHILDREN		"children"
+#define	ZPOOL_CONFIG_ID			"id"
+#define	ZPOOL_CONFIG_GUID		"guid"
+#define	ZPOOL_CONFIG_PATH		"path"
+#define	ZPOOL_CONFIG_DEVID		"devid"
+#define	ZPOOL_CONFIG_METASLAB_ARRAY	"metaslab_array"
+#define	ZPOOL_CONFIG_METASLAB_SHIFT	"metaslab_shift"
+#define	ZPOOL_CONFIG_ASHIFT		"ashift"
+#define	ZPOOL_CONFIG_ASIZE		"asize"
+#define	ZPOOL_CONFIG_DTL		"DTL"
+#define	ZPOOL_CONFIG_SCAN_STATS		"scan_stats"	/* not stored on disk */
+#define	ZPOOL_CONFIG_VDEV_STATS		"vdev_stats"	/* not stored on disk */
+#define	ZPOOL_CONFIG_WHOLE_DISK		"whole_disk"
+#define	ZPOOL_CONFIG_ERRCOUNT		"error_count"
+#define	ZPOOL_CONFIG_NOT_PRESENT	"not_present"
+#define	ZPOOL_CONFIG_SPARES		"spares"
+#define	ZPOOL_CONFIG_IS_SPARE		"is_spare"
+#define	ZPOOL_CONFIG_NPARITY		"nparity"
+#define	ZPOOL_CONFIG_HOSTID		"hostid"
+#define	ZPOOL_CONFIG_HOSTNAME		"hostname"
+#define	ZPOOL_CONFIG_LOADED_TIME	"initial_load_time"
+#define	ZPOOL_CONFIG_UNSPARE		"unspare"
+#define	ZPOOL_CONFIG_PHYS_PATH		"phys_path"
+#define	ZPOOL_CONFIG_IS_LOG		"is_log"
+#define	ZPOOL_CONFIG_L2CACHE		"l2cache"
+#define	ZPOOL_CONFIG_HOLE_ARRAY		"hole_array"
+#define	ZPOOL_CONFIG_VDEV_CHILDREN	"vdev_children"
+#define	ZPOOL_CONFIG_IS_HOLE		"is_hole"
+#define	ZPOOL_CONFIG_DDT_HISTOGRAM	"ddt_histogram"
+#define	ZPOOL_CONFIG_DDT_OBJ_STATS	"ddt_object_stats"
+#define	ZPOOL_CONFIG_DDT_STATS		"ddt_stats"
+#define	ZPOOL_CONFIG_SPLIT		"splitcfg"
+#define	ZPOOL_CONFIG_ORIG_GUID		"orig_guid"
+#define	ZPOOL_CONFIG_SPLIT_GUID		"split_guid"
+#define	ZPOOL_CONFIG_SPLIT_LIST		"guid_list"
+#define	ZPOOL_CONFIG_REMOVING		"removing"
+#define	ZPOOL_CONFIG_RESILVER_TXG	"resilver_txg"
+#define	ZPOOL_CONFIG_COMMENT		"comment"
+#define	ZPOOL_CONFIG_SUSPENDED		"suspended"	/* not stored on disk */
+#define	ZPOOL_CONFIG_TIMESTAMP		"timestamp"	/* not stored on disk */
+#define	ZPOOL_CONFIG_BOOTFS		"bootfs"	/* not stored on disk */
+#define	ZPOOL_CONFIG_MISSING_DEVICES	"missing_vdevs"	/* not stored on disk */
+#define	ZPOOL_CONFIG_LOAD_INFO		"load_info"	/* not stored on disk */
+#define	ZPOOL_CONFIG_REWIND_INFO	"rewind_info"	/* not stored on disk */
+#define	ZPOOL_CONFIG_UNSUP_FEAT		"unsup_feat"	/* not stored on disk */
+#define	ZPOOL_CONFIG_ENABLED_FEAT	"enabled_feat"	/* not stored on disk */
+#define	ZPOOL_CONFIG_CAN_RDONLY		"can_rdonly"	/* not stored on disk */
+#define	ZPOOL_CONFIG_FEATURES_FOR_READ	"features_for_read"
+#define	ZPOOL_CONFIG_FEATURE_STATS	"feature_stats"	/* not stored on disk */
+#define	ZPOOL_CONFIG_ERRATA		"errata"	/* not stored on disk */
+/*
+ * The persistent vdev state is stored as separate values rather than a single
+ * 'vdev_state' entry.  This is because a device can be in multiple states, such
+ * as offline and degraded.
+ */
+#define	ZPOOL_CONFIG_OFFLINE		"offline"
+#define	ZPOOL_CONFIG_FAULTED		"faulted"
+#define	ZPOOL_CONFIG_DEGRADED		"degraded"
+#define	ZPOOL_CONFIG_REMOVED		"removed"
+#define	ZPOOL_CONFIG_FRU		"fru"
+#define	ZPOOL_CONFIG_AUX_STATE		"aux_state"
+
+/* Rewind policy parameters */
+#define	ZPOOL_REWIND_POLICY		"rewind-policy"
+#define	ZPOOL_REWIND_REQUEST		"rewind-request"
+#define	ZPOOL_REWIND_REQUEST_TXG	"rewind-request-txg"
+#define	ZPOOL_REWIND_META_THRESH	"rewind-meta-thresh"
+#define	ZPOOL_REWIND_DATA_THRESH	"rewind-data-thresh"
+
+/* Rewind data discovered */
+#define	ZPOOL_CONFIG_LOAD_TIME		"rewind_txg_ts"
+#define	ZPOOL_CONFIG_LOAD_DATA_ERRORS	"verify_data_errors"
+#define	ZPOOL_CONFIG_REWIND_TIME	"seconds_of_rewind"
+
+#define	VDEV_TYPE_ROOT			"root"
+#define	VDEV_TYPE_MIRROR		"mirror"
+#define	VDEV_TYPE_REPLACING		"replacing"
+#define	VDEV_TYPE_RAIDZ			"raidz"
+#define	VDEV_TYPE_DISK			"disk"
+#define	VDEV_TYPE_FILE			"file"
+#define	VDEV_TYPE_MISSING		"missing"
+#define	VDEV_TYPE_HOLE			"hole"
+#define	VDEV_TYPE_SPARE			"spare"
+#define	VDEV_TYPE_LOG			"log"
+#define	VDEV_TYPE_L2CACHE		"l2cache"
+
+/*
+ * This is needed in userland to report the minimum necessary device size.
+ */
+#define	SPA_MINDEVSIZE		(64ULL << 20)
+
+/*
+ * Set if the fragmentation has not yet been calculated. This can happen
+ * because the space maps have not been upgraded or the histogram feature
+ * is not enabled.
+ */
+#define	ZFS_FRAG_INVALID	UINT64_MAX
+
+/*
+ * The location of the pool configuration repository, shared between kernel and
+ * userland.
+ */
+#define	ZPOOL_CACHE		"/etc/zfs/zpool.cache"
+
+/*
+ * vdev states are ordered from least to most healthy.
+ * A vdev that's CANT_OPEN or below is considered unusable.
+ */
+typedef enum vdev_state {
+	VDEV_STATE_UNKNOWN = 0,	/* Uninitialized vdev			*/
+	VDEV_STATE_CLOSED,	/* Not currently open			*/
+	VDEV_STATE_OFFLINE,	/* Not allowed to open			*/
+	VDEV_STATE_REMOVED,	/* Explicitly removed from system	*/
+	VDEV_STATE_CANT_OPEN,	/* Tried to open, but failed		*/
+	VDEV_STATE_FAULTED,	/* External request to fault device	*/
+	VDEV_STATE_DEGRADED,	/* Replicated vdev with unhealthy kids	*/
+	VDEV_STATE_HEALTHY	/* Presumed good			*/
+} vdev_state_t;
+
+#define	VDEV_STATE_ONLINE	VDEV_STATE_HEALTHY
+
+/*
+ * vdev aux states.  When a vdev is in the CANT_OPEN state, the aux field
+ * of the vdev stats structure uses these constants to distinguish why.
+ */
+typedef enum vdev_aux {
+	VDEV_AUX_NONE,		/* no error				*/
+	VDEV_AUX_OPEN_FAILED,	/* ldi_open_*() or vn_open() failed	*/
+	VDEV_AUX_CORRUPT_DATA,	/* bad label or disk contents		*/
+	VDEV_AUX_NO_REPLICAS,	/* insufficient number of replicas	*/
+	VDEV_AUX_BAD_GUID_SUM,	/* vdev guid sum doesn't match		*/
+	VDEV_AUX_TOO_SMALL,	/* vdev size is too small		*/
+	VDEV_AUX_BAD_LABEL,	/* the label is OK but invalid		*/
+	VDEV_AUX_VERSION_NEWER,	/* on-disk version is too new		*/
+	VDEV_AUX_VERSION_OLDER,	/* on-disk version is too old		*/
+	VDEV_AUX_UNSUP_FEAT,	/* unsupported features			*/
+	VDEV_AUX_SPARED,	/* hot spare used in another pool	*/
+	VDEV_AUX_ERR_EXCEEDED,	/* too many errors			*/
+	VDEV_AUX_IO_FAILURE,	/* experienced I/O failure		*/
+	VDEV_AUX_BAD_LOG,	/* cannot read log chain(s)		*/
+	VDEV_AUX_EXTERNAL,	/* external diagnosis			*/
+	VDEV_AUX_SPLIT_POOL	/* vdev was split off into another pool	*/
+} vdev_aux_t;
+
+/*
+ * pool state.  The following states are written to disk as part of the normal
+ * SPA lifecycle: ACTIVE, EXPORTED, DESTROYED, SPARE, L2CACHE.  The remaining
+ * states are software abstractions used at various levels to communicate
+ * pool state.
+ */
+typedef enum pool_state {
+	POOL_STATE_ACTIVE = 0,		/* In active use		*/
+	POOL_STATE_EXPORTED,		/* Explicitly exported		*/
+	POOL_STATE_DESTROYED,		/* Explicitly destroyed		*/
+	POOL_STATE_SPARE,		/* Reserved for hot spare use	*/
+	POOL_STATE_L2CACHE,		/* Level 2 ARC device		*/
+	POOL_STATE_UNINITIALIZED,	/* Internal spa_t state		*/
+	POOL_STATE_UNAVAIL,		/* Internal libzfs state	*/
+	POOL_STATE_POTENTIALLY_ACTIVE	/* Internal libzfs state	*/
+} pool_state_t;
+
+/*
+ * Scan Functions.
+ */
+typedef enum pool_scan_func {
+	POOL_SCAN_NONE,
+	POOL_SCAN_SCRUB,
+	POOL_SCAN_RESILVER,
+	POOL_SCAN_FUNCS
+} pool_scan_func_t;
+
+/*
+ * ZIO types.  Needed to interpret vdev statistics below.
+ */
+typedef enum zio_type {
+	ZIO_TYPE_NULL = 0,
+	ZIO_TYPE_READ,
+	ZIO_TYPE_WRITE,
+	ZIO_TYPE_FREE,
+	ZIO_TYPE_CLAIM,
+	ZIO_TYPE_IOCTL,
+	ZIO_TYPES
+} zio_type_t;
+
+/*
+ * Pool statistics.  Note: all fields should be 64-bit because this
+ * is passed between kernel and userland as an nvlist uint64 array.
+ */
+typedef struct pool_scan_stat {
+	/* values stored on disk */
+	uint64_t	pss_func;	/* pool_scan_func_t */
+	uint64_t	pss_state;	/* dsl_scan_state_t */
+	uint64_t	pss_start_time;	/* scan start time */
+	uint64_t	pss_end_time;	/* scan end time */
+	uint64_t	pss_to_examine;	/* total bytes to scan */
+	uint64_t	pss_examined;	/* total examined bytes	*/
+	uint64_t	pss_to_process; /* total bytes to process */
+	uint64_t	pss_processed;	/* total processed bytes */
+	uint64_t	pss_errors;	/* scan errors	*/
+
+	/* values not stored on disk */
+	uint64_t	pss_pass_exam;	/* examined bytes per scan pass */
+	uint64_t	pss_pass_start;	/* start time of a scan pass */
+} pool_scan_stat_t;
+
+typedef enum dsl_scan_state {
+	DSS_NONE,
+	DSS_SCANNING,
+	DSS_FINISHED,
+	DSS_CANCELED,
+	DSS_NUM_STATES
+} dsl_scan_state_t;
+
+/*
+ * Errata described by http://zfsonlinux.org/msg/ZFS-8000-ER.  The ordering
+ * of this enum must be maintained to ensure the errata identifiers map to
+ * the correct documentation.  New errata may only be appended to the list
+ * and must contain corresponding documentation at the above link.
+ */
+typedef enum zpool_errata {
+	ZPOOL_ERRATA_NONE,
+	ZPOOL_ERRATA_ZOL_2094_SCRUB,
+	ZPOOL_ERRATA_ZOL_2094_ASYNC_DESTROY,
+} zpool_errata_t;
+
+/*
+ * Vdev statistics.  Note: all fields should be 64-bit because this
+ * is passed between kernel and userland as an nvlist uint64 array.
+ */
+typedef struct vdev_stat {
+	hrtime_t	vs_timestamp;		/* time since vdev load	*/
+	uint64_t	vs_state;		/* vdev state		*/
+	uint64_t	vs_aux;			/* see vdev_aux_t	*/
+	uint64_t	vs_alloc;		/* space allocated	*/
+	uint64_t	vs_space;		/* total capacity	*/
+	uint64_t	vs_dspace;		/* deflated capacity	*/
+	uint64_t	vs_rsize;		/* replaceable dev size */
+	uint64_t	vs_esize;		/* expandable dev size */
+	uint64_t	vs_ops[ZIO_TYPES];	/* operation count	*/
+	uint64_t	vs_bytes[ZIO_TYPES];	/* bytes read/written	*/
+	uint64_t	vs_read_errors;		/* read errors		*/
+	uint64_t	vs_write_errors;	/* write errors		*/
+	uint64_t	vs_checksum_errors;	/* checksum errors	*/
+	uint64_t	vs_self_healed;		/* self-healed bytes	*/
+	uint64_t	vs_scan_removing;	/* removing?	*/
+	uint64_t	vs_scan_processed;	/* scan processed bytes	*/
+	uint64_t	vs_fragmentation;	/* device fragmentation */
+} vdev_stat_t;
+
+/*
+ * DDT statistics.  Note: all fields should be 64-bit because this
+ * is passed between kernel and userland as an nvlist uint64 array.
+ */
+typedef struct ddt_object {
+	uint64_t	ddo_count;	/* number of elments in ddt 	*/
+	uint64_t	ddo_dspace;	/* size of ddt on disk		*/
+	uint64_t	ddo_mspace;	/* size of ddt in-core		*/
+} ddt_object_t;
+
+typedef struct ddt_stat {
+	uint64_t	dds_blocks;	/* blocks			*/
+	uint64_t	dds_lsize;	/* logical size			*/
+	uint64_t	dds_psize;	/* physical size		*/
+	uint64_t	dds_dsize;	/* deflated allocated size	*/
+	uint64_t	dds_ref_blocks;	/* referenced blocks		*/
+	uint64_t	dds_ref_lsize;	/* referenced lsize * refcnt	*/
+	uint64_t	dds_ref_psize;	/* referenced psize * refcnt	*/
+	uint64_t	dds_ref_dsize;	/* referenced dsize * refcnt	*/
+} ddt_stat_t;
+
+typedef struct ddt_histogram {
+	ddt_stat_t	ddh_stat[64];	/* power-of-two histogram buckets */
+} ddt_histogram_t;
+
+#define	ZVOL_DRIVER	"zvol"
+#define	ZFS_DRIVER	"zfs"
+#define	ZFS_DEV		"/dev/zfs"
+
+/* general zvol path */
+#define	ZVOL_DIR	"/dev"
+
+#define	ZVOL_MAJOR		230
+#define	ZVOL_MINOR_BITS		4
+#define	ZVOL_MINOR_MASK		((1U << ZVOL_MINOR_BITS) - 1)
+#define	ZVOL_MINORS		(1 << 4)
+#define	ZVOL_DEV_NAME		"zd"
+
+#define	ZVOL_PROP_NAME		"name"
+#define	ZVOL_DEFAULT_BLOCKSIZE	8192
+
+/*
+ * /dev/zfs ioctl numbers.
+ */
+typedef enum zfs_ioc {
+	/*
+	 * Illumos - 70/128 numbers reserved.
+	 */
+	ZFS_IOC_FIRST =	('Z' << 8),
+	ZFS_IOC = ZFS_IOC_FIRST,
+	ZFS_IOC_POOL_CREATE = ZFS_IOC_FIRST,
+	ZFS_IOC_POOL_DESTROY,
+	ZFS_IOC_POOL_IMPORT,
+	ZFS_IOC_POOL_EXPORT,
+	ZFS_IOC_POOL_CONFIGS,
+	ZFS_IOC_POOL_STATS,
+	ZFS_IOC_POOL_TRYIMPORT,
+	ZFS_IOC_POOL_SCAN,
+	ZFS_IOC_POOL_FREEZE,
+	ZFS_IOC_POOL_UPGRADE,
+	ZFS_IOC_POOL_GET_HISTORY,
+	ZFS_IOC_VDEV_ADD,
+	ZFS_IOC_VDEV_REMOVE,
+	ZFS_IOC_VDEV_SET_STATE,
+	ZFS_IOC_VDEV_ATTACH,
+	ZFS_IOC_VDEV_DETACH,
+	ZFS_IOC_VDEV_SETPATH,
+	ZFS_IOC_VDEV_SETFRU,
+	ZFS_IOC_OBJSET_STATS,
+	ZFS_IOC_OBJSET_ZPLPROPS,
+	ZFS_IOC_DATASET_LIST_NEXT,
+	ZFS_IOC_SNAPSHOT_LIST_NEXT,
+	ZFS_IOC_SET_PROP,
+	ZFS_IOC_CREATE,
+	ZFS_IOC_DESTROY,
+	ZFS_IOC_ROLLBACK,
+	ZFS_IOC_RENAME,
+	ZFS_IOC_RECV,
+	ZFS_IOC_SEND,
+	ZFS_IOC_INJECT_FAULT,
+	ZFS_IOC_CLEAR_FAULT,
+	ZFS_IOC_INJECT_LIST_NEXT,
+	ZFS_IOC_ERROR_LOG,
+	ZFS_IOC_CLEAR,
+	ZFS_IOC_PROMOTE,
+	ZFS_IOC_SNAPSHOT,
+	ZFS_IOC_DSOBJ_TO_DSNAME,
+	ZFS_IOC_OBJ_TO_PATH,
+	ZFS_IOC_POOL_SET_PROPS,
+	ZFS_IOC_POOL_GET_PROPS,
+	ZFS_IOC_SET_FSACL,
+	ZFS_IOC_GET_FSACL,
+	ZFS_IOC_SHARE,
+	ZFS_IOC_INHERIT_PROP,
+	ZFS_IOC_SMB_ACL,
+	ZFS_IOC_USERSPACE_ONE,
+	ZFS_IOC_USERSPACE_MANY,
+	ZFS_IOC_USERSPACE_UPGRADE,
+	ZFS_IOC_HOLD,
+	ZFS_IOC_RELEASE,
+	ZFS_IOC_GET_HOLDS,
+	ZFS_IOC_OBJSET_RECVD_PROPS,
+	ZFS_IOC_VDEV_SPLIT,
+	ZFS_IOC_NEXT_OBJ,
+	ZFS_IOC_DIFF,
+	ZFS_IOC_TMP_SNAPSHOT,
+	ZFS_IOC_OBJ_TO_STATS,
+	ZFS_IOC_SPACE_WRITTEN,
+	ZFS_IOC_SPACE_SNAPS,
+	ZFS_IOC_DESTROY_SNAPS,
+	ZFS_IOC_POOL_REGUID,
+	ZFS_IOC_POOL_REOPEN,
+	ZFS_IOC_SEND_PROGRESS,
+	ZFS_IOC_LOG_HISTORY,
+	ZFS_IOC_SEND_NEW,
+	ZFS_IOC_SEND_SPACE,
+	ZFS_IOC_CLONE,
+	ZFS_IOC_BOOKMARK,
+	ZFS_IOC_GET_BOOKMARKS,
+	ZFS_IOC_DESTROY_BOOKMARKS,
+
+	/*
+	 * Linux - 3/64 numbers reserved.
+	 */
+	ZFS_IOC_LINUX = ('Z' << 8) + 0x80,
+	ZFS_IOC_EVENTS_NEXT,
+	ZFS_IOC_EVENTS_CLEAR,
+	ZFS_IOC_EVENTS_SEEK,
+
+	/*
+	 * FreeBSD - 1/64 numbers reserved.
+	 */
+	ZFS_IOC_FREEBSD = ('Z' << 8) + 0xC0,
+
+	ZFS_IOC_LAST
+} zfs_ioc_t;
+
+/*
+ * zvol ioctl to get dataset name
+ */
+#define	BLKZNAME		_IOR(0x12, 125, char[ZFS_MAXNAMELEN])
+
+/*
+ * Internal SPA load state.  Used by FMA diagnosis engine.
+ */
+typedef enum {
+	SPA_LOAD_NONE,		/* no load in progress	*/
+	SPA_LOAD_OPEN,		/* normal open		*/
+	SPA_LOAD_IMPORT,	/* import in progress	*/
+	SPA_LOAD_TRYIMPORT,	/* tryimport in progress */
+	SPA_LOAD_RECOVER,	/* recovery requested	*/
+	SPA_LOAD_ERROR		/* load failed		*/
+} spa_load_state_t;
+
+/*
+ * Bookmark name values.
+ */
+#define	ZPOOL_ERR_LIST		"error list"
+#define	ZPOOL_ERR_DATASET	"dataset"
+#define	ZPOOL_ERR_OBJECT	"object"
+
+#define	HIS_MAX_RECORD_LEN	(MAXPATHLEN + MAXPATHLEN + 1)
+
+/*
+ * The following are names used in the nvlist describing
+ * the pool's history log.
+ */
+#define	ZPOOL_HIST_RECORD	"history record"
+#define	ZPOOL_HIST_TIME		"history time"
+#define	ZPOOL_HIST_CMD		"history command"
+#define	ZPOOL_HIST_WHO		"history who"
+#define	ZPOOL_HIST_ZONE		"history zone"
+#define	ZPOOL_HIST_HOST		"history hostname"
+#define	ZPOOL_HIST_TXG		"history txg"
+#define	ZPOOL_HIST_INT_EVENT	"history internal event"
+#define	ZPOOL_HIST_INT_STR	"history internal str"
+#define	ZPOOL_HIST_INT_NAME	"internal_name"
+#define	ZPOOL_HIST_IOCTL	"ioctl"
+#define	ZPOOL_HIST_INPUT_NVL	"in_nvl"
+#define	ZPOOL_HIST_OUTPUT_NVL	"out_nvl"
+#define	ZPOOL_HIST_DSNAME	"dsname"
+#define	ZPOOL_HIST_DSID		"dsid"
+
+/*
+ * Flags for ZFS_IOC_VDEV_SET_STATE
+ */
+#define	ZFS_ONLINE_CHECKREMOVE	0x1
+#define	ZFS_ONLINE_UNSPARE	0x2
+#define	ZFS_ONLINE_FORCEFAULT	0x4
+#define	ZFS_ONLINE_EXPAND	0x8
+#define	ZFS_OFFLINE_TEMPORARY	0x1
+
+/*
+ * Flags for ZFS_IOC_POOL_IMPORT
+ */
+#define	ZFS_IMPORT_NORMAL	0x0
+#define	ZFS_IMPORT_VERBATIM	0x1
+#define	ZFS_IMPORT_ANY_HOST	0x2
+#define	ZFS_IMPORT_MISSING_LOG	0x4
+#define	ZFS_IMPORT_ONLY		0x8
+#define	ZFS_IMPORT_TEMP_NAME	0x10
+
+/*
+ * Sysevent payload members.  ZFS will generate the following sysevents with the
+ * given payloads:
+ *
+ *	ESC_ZFS_RESILVER_START
+ *	ESC_ZFS_RESILVER_END
+ *	ESC_ZFS_POOL_DESTROY
+ *	ESC_ZFS_POOL_REGUID
+ *
+ *		ZFS_EV_POOL_NAME	DATA_TYPE_STRING
+ *		ZFS_EV_POOL_GUID	DATA_TYPE_UINT64
+ *
+ *	ESC_ZFS_VDEV_REMOVE
+ *	ESC_ZFS_VDEV_CLEAR
+ *	ESC_ZFS_VDEV_CHECK
+ *
+ *		ZFS_EV_POOL_NAME	DATA_TYPE_STRING
+ *		ZFS_EV_POOL_GUID	DATA_TYPE_UINT64
+ *		ZFS_EV_VDEV_PATH	DATA_TYPE_STRING	(optional)
+ *		ZFS_EV_VDEV_GUID	DATA_TYPE_UINT64
+ */
+#define	ZFS_EV_POOL_NAME	"pool_name"
+#define	ZFS_EV_POOL_GUID	"pool_guid"
+#define	ZFS_EV_VDEV_PATH	"vdev_path"
+#define	ZFS_EV_VDEV_GUID	"vdev_guid"
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* _SYS_FS_ZFS_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/include/sys/metaslab.h
@@ -0,0 +1,100 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2014 by Delphix. All rights reserved.
+ */
+
+#ifndef _SYS_METASLAB_H
+#define	_SYS_METASLAB_H
+
+#include <sys/spa.h>
+#include <sys/space_map.h>
+#include <sys/txg.h>
+#include <sys/zio.h>
+#include <sys/avl.h>
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+typedef struct metaslab_ops {
+	uint64_t (*msop_alloc)(metaslab_t *msp, uint64_t size);
+} metaslab_ops_t;
+
+extern metaslab_ops_t *zfs_metaslab_ops;
+
+int metaslab_init(metaslab_group_t *, uint64_t, uint64_t, uint64_t,
+    metaslab_t **);
+void metaslab_fini(metaslab_t *);
+
+void metaslab_load_wait(metaslab_t *);
+int metaslab_load(metaslab_t *);
+void metaslab_unload(metaslab_t *);
+
+void metaslab_sync(metaslab_t *, uint64_t);
+void metaslab_sync_done(metaslab_t *, uint64_t);
+void metaslab_sync_reassess(metaslab_group_t *);
+uint64_t metaslab_block_maxsize(metaslab_t *);
+
+#define	METASLAB_HINTBP_FAVOR	0x0
+#define	METASLAB_HINTBP_AVOID	0x1
+#define	METASLAB_GANG_HEADER	0x2
+#define	METASLAB_GANG_CHILD	0x4
+#define	METASLAB_GANG_AVOID	0x8
+#define	METASLAB_FASTWRITE	0x10
+
+int metaslab_alloc(spa_t *, metaslab_class_t *, uint64_t,
+    blkptr_t *, int, uint64_t, blkptr_t *, int);
+void metaslab_free(spa_t *, const blkptr_t *, uint64_t, boolean_t);
+int metaslab_claim(spa_t *, const blkptr_t *, uint64_t);
+void metaslab_check_free(spa_t *, const blkptr_t *);
+void metaslab_fastwrite_mark(spa_t *, const blkptr_t *);
+void metaslab_fastwrite_unmark(spa_t *, const blkptr_t *);
+
+metaslab_class_t *metaslab_class_create(spa_t *, metaslab_ops_t *);
+void metaslab_class_destroy(metaslab_class_t *);
+int metaslab_class_validate(metaslab_class_t *);
+void metaslab_class_histogram_verify(metaslab_class_t *);
+uint64_t metaslab_class_fragmentation(metaslab_class_t *);
+uint64_t metaslab_class_expandable_space(metaslab_class_t *);
+
+void metaslab_class_space_update(metaslab_class_t *, int64_t, int64_t,
+    int64_t, int64_t);
+uint64_t metaslab_class_get_alloc(metaslab_class_t *);
+uint64_t metaslab_class_get_space(metaslab_class_t *);
+uint64_t metaslab_class_get_dspace(metaslab_class_t *);
+uint64_t metaslab_class_get_deferred(metaslab_class_t *);
+
+metaslab_group_t *metaslab_group_create(metaslab_class_t *, vdev_t *);
+void metaslab_group_destroy(metaslab_group_t *);
+void metaslab_group_activate(metaslab_group_t *);
+void metaslab_group_passivate(metaslab_group_t *);
+uint64_t metaslab_group_get_space(metaslab_group_t *);
+void metaslab_group_histogram_verify(metaslab_group_t *);
+uint64_t metaslab_group_fragmentation(metaslab_group_t *);
+void metaslab_group_histogram_remove(metaslab_group_t *, metaslab_t *);
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* _SYS_METASLAB_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/include/sys/metaslab_impl.h
@@ -0,0 +1,202 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/*
+ * Copyright (c) 2011, 2014 by Delphix. All rights reserved.
+ */
+
+#ifndef _SYS_METASLAB_IMPL_H
+#define	_SYS_METASLAB_IMPL_H
+
+#include <sys/metaslab.h>
+#include <sys/space_map.h>
+#include <sys/range_tree.h>
+#include <sys/vdev.h>
+#include <sys/txg.h>
+#include <sys/avl.h>
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+/*
+ * A metaslab class encompasses a category of allocatable top-level vdevs.
+ * Each top-level vdev is associated with a metaslab group which defines
+ * the allocatable region for that vdev. Examples of these categories include
+ * "normal" for data block allocations (i.e. main pool allocations) or "log"
+ * for allocations designated for intent log devices (i.e. slog devices).
+ * When a block allocation is requested from the SPA it is associated with a
+ * metaslab_class_t, and only top-level vdevs (i.e. metaslab groups) belonging
+ * to the class can be used to satisfy that request. Allocations are done
+ * by traversing the metaslab groups that are linked off of the mc_rotor field.
+ * This rotor points to the next metaslab group where allocations will be
+ * attempted. Allocating a block is a 3 step process -- select the metaslab
+ * group, select the metaslab, and then allocate the block. The metaslab
+ * class defines the low-level block allocator that will be used as the
+ * final step in allocation. These allocators are pluggable allowing each class
+ * to use a block allocator that best suits that class.
+ */
+struct metaslab_class {
+	spa_t			*mc_spa;
+	metaslab_group_t	*mc_rotor;
+	metaslab_ops_t		*mc_ops;
+	uint64_t		mc_aliquot;
+	uint64_t		mc_alloc_groups; /* # of allocatable groups */
+	uint64_t		mc_alloc;	/* total allocated space */
+	uint64_t		mc_deferred;	/* total deferred frees */
+	uint64_t		mc_space;	/* total space (alloc + free) */
+	uint64_t		mc_dspace;	/* total deflated space */
+	uint64_t		mc_histogram[RANGE_TREE_HISTOGRAM_SIZE];
+	kmutex_t		mc_fastwrite_lock;
+};
+
+/*
+ * Metaslab groups encapsulate all the allocatable regions (i.e. metaslabs)
+ * of a top-level vdev. They are linked togther to form a circular linked
+ * list and can belong to only one metaslab class. Metaslab groups may become
+ * ineligible for allocations for a number of reasons such as limited free
+ * space, fragmentation, or going offline. When this happens the allocator will
+ * simply find the next metaslab group in the linked list and attempt
+ * to allocate from that group instead.
+ */
+struct metaslab_group {
+	kmutex_t		mg_lock;
+	avl_tree_t		mg_metaslab_tree;
+	uint64_t		mg_aliquot;
+	boolean_t		mg_allocatable;		/* can we allocate? */
+	uint64_t		mg_free_capacity;	/* percentage free */
+	int64_t			mg_bias;
+	int64_t			mg_activation_count;
+	metaslab_class_t	*mg_class;
+	vdev_t			*mg_vd;
+	taskq_t			*mg_taskq;
+	metaslab_group_t	*mg_prev;
+	metaslab_group_t	*mg_next;
+	uint64_t		mg_fragmentation;
+	uint64_t		mg_histogram[RANGE_TREE_HISTOGRAM_SIZE];
+};
+
+/*
+ * This value defines the number of elements in the ms_lbas array. The value
+ * of 64 was chosen as it covers all power of 2 buckets up to UINT64_MAX.
+ * This is the equivalent of highbit(UINT64_MAX).
+ */
+#define	MAX_LBAS	64
+
+/*
+ * Each metaslab maintains a set of in-core trees to track metaslab operations.
+ * The in-core free tree (ms_tree) contains the current list of free segments.
+ * As blocks are allocated, the allocated segment are removed from the ms_tree
+ * and added to a per txg allocation tree (ms_alloctree). As blocks are freed,
+ * they are added to the per txg free tree (ms_freetree). These per txg
+ * trees allow us to process all allocations and frees in syncing context
+ * where it is safe to update the on-disk space maps. One additional in-core
+ * tree is maintained to track deferred frees (ms_defertree). Once a block
+ * is freed it will move from the ms_freetree to the ms_defertree. A deferred
+ * free means that a block has been freed but cannot be used by the pool
+ * until TXG_DEFER_SIZE transactions groups later. For example, a block
+ * that is freed in txg 50 will not be available for reallocation until
+ * txg 52 (50 + TXG_DEFER_SIZE).  This provides a safety net for uberblock
+ * rollback. A pool could be safely rolled back TXG_DEFERS_SIZE
+ * transactions groups and ensure that no block has been reallocated.
+ *
+ * The simplified transition diagram looks like this:
+ *
+ *
+ *      ALLOCATE
+ *         |
+ *         V
+ *    free segment (ms_tree) --------> ms_alloctree ----> (write to space map)
+ *         ^
+ *         |
+ *         |                           ms_freetree <--- FREE
+ *         |                                 |
+ *         |                                 |
+ *         |                                 |
+ *         +----------- ms_defertree <-------+---------> (write to space map)
+ *
+ *
+ * Each metaslab's space is tracked in a single space map in the MOS,
+ * which is only updated in syncing context. Each time we sync a txg,
+ * we append the allocs and frees from that txg to the space map.
+ * The pool space is only updated once all metaslabs have finished syncing.
+ *
+ * To load the in-core free tree we read the space map from disk.
+ * This object contains a series of alloc and free records that are
+ * combined to make up the list of all free segments in this metaslab. These
+ * segments are represented in-core by the ms_tree and are stored in an
+ * AVL tree.
+ *
+ * As the space map grows (as a result of the appends) it will
+ * eventually become space-inefficient. When the metaslab's in-core free tree
+ * is zfs_condense_pct/100 times the size of the minimal on-disk
+ * representation, we rewrite it in its minimized form. If a metaslab
+ * needs to condense then we must set the ms_condensing flag to ensure
+ * that allocations are not performed on the metaslab that is being written.
+ */
+struct metaslab {
+	kmutex_t	ms_lock;
+	kcondvar_t	ms_load_cv;
+	space_map_t	*ms_sm;
+	metaslab_ops_t	*ms_ops;
+	uint64_t	ms_id;
+	uint64_t	ms_start;
+	uint64_t	ms_size;
+	uint64_t	ms_fragmentation;
+
+	range_tree_t	*ms_alloctree[TXG_SIZE];
+	range_tree_t	*ms_freetree[TXG_SIZE];
+	range_tree_t	*ms_defertree[TXG_DEFER_SIZE];
+	range_tree_t	*ms_tree;
+
+	boolean_t	ms_condensing;	/* condensing? */
+	boolean_t	ms_condense_wanted;
+	boolean_t	ms_loaded;
+	boolean_t	ms_loading;
+
+	int64_t		ms_deferspace;	/* sum of ms_defermap[] space	*/
+	uint64_t	ms_weight;	/* weight vs. others in group	*/
+	uint64_t	ms_access_txg;
+
+	/*
+	 * The metaslab block allocators can optionally use a size-ordered
+	 * range tree and/or an array of LBAs. Not all allocators use
+	 * this functionality. The ms_size_tree should always contain the
+	 * same number of segments as the ms_tree. The only difference
+	 * is that the ms_size_tree is ordered by segment sizes.
+	 */
+	avl_tree_t	ms_size_tree;
+	uint64_t	ms_lbas[MAX_LBAS];
+
+	metaslab_group_t *ms_group;	/* metaslab group		*/
+	avl_node_t	ms_group_node;	/* node in metaslab group tree	*/
+	txg_node_t	ms_txg_node;	/* per-txg dirty metaslab links	*/
+};
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* _SYS_METASLAB_IMPL_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/include/sys/mntent.h
@@ -0,0 +1,102 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ *
+ *	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T
+ *		All Rights Reserved
+ */
+
+#ifndef _SYS_MNTENT_H
+#define	_SYS_MNTENT_H
+
+#define	MNTTYPE_ZFS	"zfs"		/* ZFS file system */
+
+#define	MOUNT_SUCCESS	0x00		/* Success */
+#define	MOUNT_USAGE	0x01		/* Invalid invocation or permissions */
+#define	MOUNT_SYSERR	0x02		/* System error (ENOMEM, etc) */
+#define	MOUNT_SOFTWARE	0x04		/* Internal mount bug */
+#define	MOUNT_USER	0x08		/* Interrupted by user (EINTR) */
+#define	MOUNT_FILEIO	0x10		/* Error updating/locking /etc/mtab */
+#define	MOUNT_FAIL	0x20		/* Mount failed */
+#define	MOUNT_SOMEOK	0x40		/* At least on mount succeeded */
+#define	MOUNT_BUSY	0x80		/* Mount failed due to EBUSY */
+
+#define	MNTOPT_ASYNC	"async"		/* all I/O is asynchronous */
+#define	MNTOPT_ATIME	"atime"		/* update atime for files */
+#define	MNTOPT_NOATIME	"noatime"	/* do not update atime for files */
+#define	MNTOPT_AUTO	"auto"		/* automount */
+#define	MNTOPT_NOAUTO	"noauto"	/* do not automount */
+#define	MNTOPT_CONTEXT	"context"	/* selinux context */
+#define	MNTOPT_FSCONTEXT "fscontext"	/* selinux fscontext */
+#define	MNTOPT_DEFCONTEXT "defcontext"	/* selinux defcontext */
+#define	MNTOPT_ROOTCONTEXT "rootcontext" /* selinux rootcontext */
+#define	MNTOPT_DEFAULTS	"defaults"	/* defaults */
+#define	MNTOPT_DEVICES	"dev"		/* device-special allowed */
+#define	MNTOPT_NODEVICES "nodev"	/* device-special disallowed */
+#define	MNTOPT_DIRATIME	"diratime"	/* update atime for dirs */
+#define	MNTOPT_NODIRATIME "nodiratime"	/* do not update atime for dirs */
+#define	MNTOPT_DIRSYNC	"dirsync"	/* do dir updates synchronously */
+#define	MNTOPT_EXEC	"exec"		/* enable executables */
+#define	MNTOPT_NOEXEC	"noexec"	/* disable executables */
+#define	MNTOPT_GROUP	"group"		/* allow group mount */
+#define	MNTOPT_NOGROUP	"nogroup"	/* do not allow group mount */
+#define	MNTOPT_IVERSION	"iversion"	/* update inode version */
+#define	MNTOPT_NOIVERSION "noiversion"	/* do not update inode version */
+#define	MNTOPT_NBMAND	"mand"		/* allow non-blocking mandatory locks */
+#define	MNTOPT_NONBMAND	"nomand"	/* deny non-blocking mandatory locks */
+#define	MNTOPT_NETDEV	"_netdev"	/* network device */
+#define	MNTOPT_NOFAIL	"nofail"	/* no failure */
+#define	MNTOPT_RELATIME	"relatime"	/* allow relative time updates */
+#define	MNTOPT_NORELATIME "norelatime"	/* do not allow relative time updates */
+#define	MNTOPT_DFRATIME	"strictatime"	/* Deferred access time updates */
+#define	MNTOPT_NODFRATIME "nostrictatime" /* No Deferred access time updates */
+#define	MNTOPT_SETUID	"suid"		/* Both setuid and devices allowed */
+#define	MNTOPT_NOSETUID	"nosuid"	/* Neither setuid nor devices allowed */
+#define	MNTOPT_OWNER	"owner"		/* allow owner mount */
+#define	MNTOPT_NOOWNER	"noowner"	/* do not allow owner mount */
+#define	MNTOPT_REMOUNT	"remount"	/* change mount options */
+#define	MNTOPT_RO	"ro"		/* read only */
+#define	MNTOPT_RW	"rw"		/* read/write */
+#define	MNTOPT_SYNC	"sync"		/* all I/O is synchronous */
+#define	MNTOPT_USER	"user"		/* allow user mount */
+#define	MNTOPT_NOUSER	"nouser"	/* do not allow user mount */
+#define	MNTOPT_USERS	"users"		/* allow user mount */
+#define	MNTOPT_NOUSERS	"nousers"	/* do not allow user mount */
+#define	MNTOPT_SUB	"sub"		/* allow mounts on subdirs */
+#define	MNTOPT_NOSUB	"nosub"		/* do not allow mounts on subdirs */
+#define	MNTOPT_QUIET	"quiet"		/* quiet mount */
+#define	MNTOPT_LOUD	"loud"		/* verbose mount */
+#define	MNTOPT_BIND	"bind"		/* remount part of a tree */
+#define	MNTOPT_RBIND	"rbind"		/* include subtrees */
+#define	MNTOPT_DIRXATTR	"dirxattr"	/* enable directory xattrs */
+#define	MNTOPT_SAXATTR	"saxattr"	/* enable system-attribute xattrs */
+#define	MNTOPT_XATTR	"xattr"		/* enable extended attributes */
+#define	MNTOPT_NOXATTR	"noxattr"	/* disable extended attributes */
+#define	MNTOPT_COMMENT	"comment"	/* comment */
+#define	MNTOPT_ZFSUTIL	"zfsutil"	/* called by zfs utility */
+#define	MNTOPT_ACL	"acl"		/* passed by util-linux-2.24 mount */
+#define	MNTOPT_NOACL	"noacl"		/* likewise */
+#define	MNTOPT_POSIXACL	"posixacl"	/* likewise */
+#define	MNTOPT_MNTPOINT	"mntpoint"	/* mount point hint */
+
+#endif	/* _SYS_MNTENT_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/include/sys/multilist.h
@@ -0,0 +1,105 @@
+/*
+ * CDDL HEADER START
+ *
+ * This file and its contents are supplied under the terms of the
+ * Common Development and Distribution License ("CDDL"), version 1.0.
+ * You may only use this file in accordance with the terms of version
+ * 1.0 of the CDDL.
+ *
+ * A full copy of the text of the CDDL should have accompanied this
+ * source.  A copy of the CDDL is also available via the Internet at
+ * http://www.illumos.org/license/CDDL.
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2013, 2014 by Delphix. All rights reserved.
+ */
+
+#ifndef	_SYS_MULTILIST_H
+#define	_SYS_MULTILIST_H
+
+#include <sys/zfs_context.h>
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+typedef list_node_t multilist_node_t;
+typedef struct multilist multilist_t;
+typedef struct multilist_sublist multilist_sublist_t;
+typedef unsigned int multilist_sublist_index_func_t(multilist_t *, void *);
+
+struct multilist_sublist {
+	/*
+	 * The mutex used internally to implement thread safe insertions
+	 * and removals to this individual sublist. It can also be locked
+	 * by a consumer using multilist_sublist_{lock,unlock}, which is
+	 * useful if a consumer needs to traverse the list in a thread
+	 * safe manner.
+	 */
+	kmutex_t	mls_lock;
+	/*
+	 * The actual list object containing all objects in this sublist.
+	 */
+	list_t		mls_list;
+	/*
+	 * Pad to cache line, in an effort to try and prevent cache line
+	 * contention.
+	 */
+} ____cacheline_aligned;
+
+struct multilist {
+	/*
+	 * This is used to get to the multilist_node_t structure given
+	 * the void *object contained on the list.
+	 */
+	size_t				ml_offset;
+	/*
+	 * The number of sublists used internally by this multilist.
+	 */
+	uint64_t			ml_num_sublists;
+	/*
+	 * The array of pointers to the actual sublists.
+	 */
+	multilist_sublist_t		*ml_sublists;
+	/*
+	 * Pointer to function which determines the sublist to use
+	 * when inserting and removing objects from this multilist.
+	 * Please see the comment above multilist_create for details.
+	 */
+	multilist_sublist_index_func_t	*ml_index_func;
+};
+
+void multilist_destroy(multilist_t *);
+void multilist_create(multilist_t *, size_t, size_t, unsigned int,
+    multilist_sublist_index_func_t *);
+
+void multilist_insert(multilist_t *, void *);
+void multilist_remove(multilist_t *, void *);
+int  multilist_is_empty(multilist_t *);
+
+unsigned int multilist_get_num_sublists(multilist_t *);
+unsigned int multilist_get_random_index(multilist_t *);
+
+multilist_sublist_t *multilist_sublist_lock(multilist_t *, unsigned int);
+void multilist_sublist_unlock(multilist_sublist_t *);
+
+void multilist_sublist_insert_head(multilist_sublist_t *, void *);
+void multilist_sublist_insert_tail(multilist_sublist_t *, void *);
+void multilist_sublist_move_forward(multilist_sublist_t *mls, void *obj);
+void multilist_sublist_remove(multilist_sublist_t *, void *);
+
+void *multilist_sublist_head(multilist_sublist_t *);
+void *multilist_sublist_tail(multilist_sublist_t *);
+void *multilist_sublist_next(multilist_sublist_t *, void *);
+void *multilist_sublist_prev(multilist_sublist_t *, void *);
+
+void multilist_link_init(multilist_node_t *);
+int  multilist_link_active(multilist_node_t *);
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif /* _SYS_MULTILIST_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/include/sys/nvpair.h
@@ -0,0 +1,352 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012 by Delphix. All rights reserved.
+ */
+
+#ifndef	_SYS_NVPAIR_H
+#define	_SYS_NVPAIR_H
+
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/errno.h>
+#include <sys/va_list.h>
+
+#if defined(_KERNEL) && !defined(_BOOT)
+#include <sys/kmem.h>
+#endif
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+typedef enum {
+	DATA_TYPE_UNKNOWN = 0,
+	DATA_TYPE_BOOLEAN,
+	DATA_TYPE_BYTE,
+	DATA_TYPE_INT16,
+	DATA_TYPE_UINT16,
+	DATA_TYPE_INT32,
+	DATA_TYPE_UINT32,
+	DATA_TYPE_INT64,
+	DATA_TYPE_UINT64,
+	DATA_TYPE_STRING,
+	DATA_TYPE_BYTE_ARRAY,
+	DATA_TYPE_INT16_ARRAY,
+	DATA_TYPE_UINT16_ARRAY,
+	DATA_TYPE_INT32_ARRAY,
+	DATA_TYPE_UINT32_ARRAY,
+	DATA_TYPE_INT64_ARRAY,
+	DATA_TYPE_UINT64_ARRAY,
+	DATA_TYPE_STRING_ARRAY,
+	DATA_TYPE_HRTIME,
+	DATA_TYPE_NVLIST,
+	DATA_TYPE_NVLIST_ARRAY,
+	DATA_TYPE_BOOLEAN_VALUE,
+	DATA_TYPE_INT8,
+	DATA_TYPE_UINT8,
+	DATA_TYPE_BOOLEAN_ARRAY,
+	DATA_TYPE_INT8_ARRAY,
+#if !defined(_KERNEL)
+	DATA_TYPE_UINT8_ARRAY,
+	DATA_TYPE_DOUBLE
+#else
+	DATA_TYPE_UINT8_ARRAY
+#endif
+} data_type_t;
+
+typedef struct nvpair {
+	int32_t nvp_size;	/* size of this nvpair */
+	int16_t	nvp_name_sz;	/* length of name string */
+	int16_t	nvp_reserve;	/* not used */
+	int32_t	nvp_value_elem;	/* number of elements for array types */
+	data_type_t nvp_type;	/* type of value */
+	/* name string */
+	/* aligned ptr array for string arrays */
+	/* aligned array of data for value */
+} nvpair_t;
+
+/* nvlist header */
+typedef struct nvlist {
+	int32_t		nvl_version;
+	uint32_t	nvl_nvflag;	/* persistent flags */
+	uint64_t	nvl_priv;	/* ptr to private data if not packed */
+	uint32_t	nvl_flag;
+	int32_t		nvl_pad;	/* currently not used, for alignment */
+} nvlist_t;
+
+/* nvp implementation version */
+#define	NV_VERSION	0
+
+/* nvlist pack encoding */
+#define	NV_ENCODE_NATIVE	0
+#define	NV_ENCODE_XDR		1
+
+/* nvlist persistent unique name flags, stored in nvl_nvflags */
+#define	NV_UNIQUE_NAME		0x1
+#define	NV_UNIQUE_NAME_TYPE	0x2
+
+/* nvlist lookup pairs related flags */
+#define	NV_FLAG_NOENTOK		0x1
+
+/* convenience macros */
+#define	NV_ALIGN(x)		(((ulong_t)(x) + 7ul) & ~7ul)
+#define	NV_ALIGN4(x)		(((x) + 3) & ~3)
+
+#define	NVP_SIZE(nvp)		((nvp)->nvp_size)
+#define	NVP_NAME(nvp)		((char *)(nvp) + sizeof (nvpair_t))
+#define	NVP_TYPE(nvp)		((nvp)->nvp_type)
+#define	NVP_NELEM(nvp)		((nvp)->nvp_value_elem)
+#define	NVP_VALUE(nvp)		((char *)(nvp) + NV_ALIGN(sizeof (nvpair_t) \
+				+ (nvp)->nvp_name_sz))
+
+#define	NVL_VERSION(nvl)	((nvl)->nvl_version)
+#define	NVL_SIZE(nvl)		((nvl)->nvl_size)
+#define	NVL_FLAG(nvl)		((nvl)->nvl_flag)
+
+/* NV allocator framework */
+typedef struct nv_alloc_ops nv_alloc_ops_t;
+
+typedef struct nv_alloc {
+	const nv_alloc_ops_t *nva_ops;
+	void *nva_arg;
+} nv_alloc_t;
+
+struct nv_alloc_ops {
+	int (*nv_ao_init)(nv_alloc_t *, va_list);
+	void (*nv_ao_fini)(nv_alloc_t *);
+	void *(*nv_ao_alloc)(nv_alloc_t *, size_t);
+	void (*nv_ao_free)(nv_alloc_t *, void *, size_t);
+	void (*nv_ao_reset)(nv_alloc_t *);
+};
+
+extern const nv_alloc_ops_t *nv_fixed_ops;
+extern nv_alloc_t *nv_alloc_nosleep;
+
+#if defined(_KERNEL) && !defined(_BOOT)
+extern nv_alloc_t *nv_alloc_sleep;
+extern nv_alloc_t *nv_alloc_pushpage;
+#endif
+
+int nv_alloc_init(nv_alloc_t *, const nv_alloc_ops_t *, /* args */ ...);
+void nv_alloc_reset(nv_alloc_t *);
+void nv_alloc_fini(nv_alloc_t *);
+
+/* list management */
+int nvlist_alloc(nvlist_t **, uint_t, int);
+void nvlist_free(nvlist_t *);
+int nvlist_size(nvlist_t *, size_t *, int);
+int nvlist_pack(nvlist_t *, char **, size_t *, int, int);
+int nvlist_unpack(char *, size_t, nvlist_t **, int);
+int nvlist_dup(nvlist_t *, nvlist_t **, int);
+int nvlist_merge(nvlist_t *, nvlist_t *, int);
+
+uint_t nvlist_nvflag(nvlist_t *);
+
+int nvlist_xalloc(nvlist_t **, uint_t, nv_alloc_t *);
+int nvlist_xpack(nvlist_t *, char **, size_t *, int, nv_alloc_t *);
+int nvlist_xunpack(char *, size_t, nvlist_t **, nv_alloc_t *);
+int nvlist_xdup(nvlist_t *, nvlist_t **, nv_alloc_t *);
+nv_alloc_t *nvlist_lookup_nv_alloc(nvlist_t *);
+
+int nvlist_add_nvpair(nvlist_t *, nvpair_t *);
+int nvlist_add_boolean(nvlist_t *, const char *);
+int nvlist_add_boolean_value(nvlist_t *, const char *, boolean_t);
+int nvlist_add_byte(nvlist_t *, const char *, uchar_t);
+int nvlist_add_int8(nvlist_t *, const char *, int8_t);
+int nvlist_add_uint8(nvlist_t *, const char *, uint8_t);
+int nvlist_add_int16(nvlist_t *, const char *, int16_t);
+int nvlist_add_uint16(nvlist_t *, const char *, uint16_t);
+int nvlist_add_int32(nvlist_t *, const char *, int32_t);
+int nvlist_add_uint32(nvlist_t *, const char *, uint32_t);
+int nvlist_add_int64(nvlist_t *, const char *, int64_t);
+int nvlist_add_uint64(nvlist_t *, const char *, uint64_t);
+int nvlist_add_string(nvlist_t *, const char *, const char *);
+int nvlist_add_nvlist(nvlist_t *, const char *, nvlist_t *);
+int nvlist_add_boolean_array(nvlist_t *, const char *, boolean_t *, uint_t);
+int nvlist_add_byte_array(nvlist_t *, const char *, uchar_t *, uint_t);
+int nvlist_add_int8_array(nvlist_t *, const char *, int8_t *, uint_t);
+int nvlist_add_uint8_array(nvlist_t *, const char *, uint8_t *, uint_t);
+int nvlist_add_int16_array(nvlist_t *, const char *, int16_t *, uint_t);
+int nvlist_add_uint16_array(nvlist_t *, const char *, uint16_t *, uint_t);
+int nvlist_add_int32_array(nvlist_t *, const char *, int32_t *, uint_t);
+int nvlist_add_uint32_array(nvlist_t *, const char *, uint32_t *, uint_t);
+int nvlist_add_int64_array(nvlist_t *, const char *, int64_t *, uint_t);
+int nvlist_add_uint64_array(nvlist_t *, const char *, uint64_t *, uint_t);
+int nvlist_add_string_array(nvlist_t *, const char *, char *const *, uint_t);
+int nvlist_add_nvlist_array(nvlist_t *, const char *, nvlist_t **, uint_t);
+int nvlist_add_hrtime(nvlist_t *, const char *, hrtime_t);
+#if !defined(_KERNEL)
+int nvlist_add_double(nvlist_t *, const char *, double);
+#endif
+
+int nvlist_remove(nvlist_t *, const char *, data_type_t);
+int nvlist_remove_all(nvlist_t *, const char *);
+int nvlist_remove_nvpair(nvlist_t *, nvpair_t *);
+
+int nvlist_lookup_boolean(nvlist_t *, const char *);
+int nvlist_lookup_boolean_value(nvlist_t *, const char *, boolean_t *);
+int nvlist_lookup_byte(nvlist_t *, const char *, uchar_t *);
+int nvlist_lookup_int8(nvlist_t *, const char *, int8_t *);
+int nvlist_lookup_uint8(nvlist_t *, const char *, uint8_t *);
+int nvlist_lookup_int16(nvlist_t *, const char *, int16_t *);
+int nvlist_lookup_uint16(nvlist_t *, const char *, uint16_t *);
+int nvlist_lookup_int32(nvlist_t *, const char *, int32_t *);
+int nvlist_lookup_uint32(nvlist_t *, const char *, uint32_t *);
+int nvlist_lookup_int64(nvlist_t *, const char *, int64_t *);
+int nvlist_lookup_uint64(nvlist_t *, const char *, uint64_t *);
+int nvlist_lookup_string(nvlist_t *, const char *, char **);
+int nvlist_lookup_nvlist(nvlist_t *, const char *, nvlist_t **);
+int nvlist_lookup_boolean_array(nvlist_t *, const char *,
+    boolean_t **, uint_t *);
+int nvlist_lookup_byte_array(nvlist_t *, const char *, uchar_t **, uint_t *);
+int nvlist_lookup_int8_array(nvlist_t *, const char *, int8_t **, uint_t *);
+int nvlist_lookup_uint8_array(nvlist_t *, const char *, uint8_t **, uint_t *);
+int nvlist_lookup_int16_array(nvlist_t *, const char *, int16_t **, uint_t *);
+int nvlist_lookup_uint16_array(nvlist_t *, const char *, uint16_t **, uint_t *);
+int nvlist_lookup_int32_array(nvlist_t *, const char *, int32_t **, uint_t *);
+int nvlist_lookup_uint32_array(nvlist_t *, const char *, uint32_t **, uint_t *);
+int nvlist_lookup_int64_array(nvlist_t *, const char *, int64_t **, uint_t *);
+int nvlist_lookup_uint64_array(nvlist_t *, const char *, uint64_t **, uint_t *);
+int nvlist_lookup_string_array(nvlist_t *, const char *, char ***, uint_t *);
+int nvlist_lookup_nvlist_array(nvlist_t *, const char *,
+    nvlist_t ***, uint_t *);
+int nvlist_lookup_hrtime(nvlist_t *, const char *, hrtime_t *);
+int nvlist_lookup_pairs(nvlist_t *, int, ...);
+#if !defined(_KERNEL)
+int nvlist_lookup_double(nvlist_t *, const char *, double *);
+#endif
+
+int nvlist_lookup_nvpair(nvlist_t *, const char *, nvpair_t **);
+int nvlist_lookup_nvpair_embedded_index(nvlist_t *, const char *, nvpair_t **,
+    int *, char **);
+boolean_t nvlist_exists(nvlist_t *, const char *);
+boolean_t nvlist_empty(nvlist_t *);
+
+/* processing nvpair */
+nvpair_t *nvlist_next_nvpair(nvlist_t *, nvpair_t *);
+nvpair_t *nvlist_prev_nvpair(nvlist_t *, nvpair_t *);
+char *nvpair_name(nvpair_t *);
+data_type_t nvpair_type(nvpair_t *);
+int nvpair_type_is_array(nvpair_t *);
+int nvpair_value_boolean_value(nvpair_t *, boolean_t *);
+int nvpair_value_byte(nvpair_t *, uchar_t *);
+int nvpair_value_int8(nvpair_t *, int8_t *);
+int nvpair_value_uint8(nvpair_t *, uint8_t *);
+int nvpair_value_int16(nvpair_t *, int16_t *);
+int nvpair_value_uint16(nvpair_t *, uint16_t *);
+int nvpair_value_int32(nvpair_t *, int32_t *);
+int nvpair_value_uint32(nvpair_t *, uint32_t *);
+int nvpair_value_int64(nvpair_t *, int64_t *);
+int nvpair_value_uint64(nvpair_t *, uint64_t *);
+int nvpair_value_string(nvpair_t *, char **);
+int nvpair_value_nvlist(nvpair_t *, nvlist_t **);
+int nvpair_value_boolean_array(nvpair_t *, boolean_t **, uint_t *);
+int nvpair_value_byte_array(nvpair_t *, uchar_t **, uint_t *);
+int nvpair_value_int8_array(nvpair_t *, int8_t **, uint_t *);
+int nvpair_value_uint8_array(nvpair_t *, uint8_t **, uint_t *);
+int nvpair_value_int16_array(nvpair_t *, int16_t **, uint_t *);
+int nvpair_value_uint16_array(nvpair_t *, uint16_t **, uint_t *);
+int nvpair_value_int32_array(nvpair_t *, int32_t **, uint_t *);
+int nvpair_value_uint32_array(nvpair_t *, uint32_t **, uint_t *);
+int nvpair_value_int64_array(nvpair_t *, int64_t **, uint_t *);
+int nvpair_value_uint64_array(nvpair_t *, uint64_t **, uint_t *);
+int nvpair_value_string_array(nvpair_t *, char ***, uint_t *);
+int nvpair_value_nvlist_array(nvpair_t *, nvlist_t ***, uint_t *);
+int nvpair_value_hrtime(nvpair_t *, hrtime_t *);
+#if !defined(_KERNEL)
+int nvpair_value_double(nvpair_t *, double *);
+#endif
+
+nvlist_t *fnvlist_alloc(void);
+void fnvlist_free(nvlist_t *);
+size_t fnvlist_size(nvlist_t *);
+char *fnvlist_pack(nvlist_t *, size_t *);
+void fnvlist_pack_free(char *, size_t);
+nvlist_t *fnvlist_unpack(char *, size_t);
+nvlist_t *fnvlist_dup(nvlist_t *);
+void fnvlist_merge(nvlist_t *, nvlist_t *);
+size_t fnvlist_num_pairs(nvlist_t *);
+
+void fnvlist_add_boolean(nvlist_t *, const char *);
+void fnvlist_add_boolean_value(nvlist_t *, const char *, boolean_t);
+void fnvlist_add_byte(nvlist_t *, const char *, uchar_t);
+void fnvlist_add_int8(nvlist_t *, const char *, int8_t);
+void fnvlist_add_uint8(nvlist_t *, const char *, uint8_t);
+void fnvlist_add_int16(nvlist_t *, const char *, int16_t);
+void fnvlist_add_uint16(nvlist_t *, const char *, uint16_t);
+void fnvlist_add_int32(nvlist_t *, const char *, int32_t);
+void fnvlist_add_uint32(nvlist_t *, const char *, uint32_t);
+void fnvlist_add_int64(nvlist_t *, const char *, int64_t);
+void fnvlist_add_uint64(nvlist_t *, const char *, uint64_t);
+void fnvlist_add_string(nvlist_t *, const char *, const char *);
+void fnvlist_add_nvlist(nvlist_t *, const char *, nvlist_t *);
+void fnvlist_add_nvpair(nvlist_t *, nvpair_t *);
+void fnvlist_add_boolean_array(nvlist_t *, const char *, boolean_t *, uint_t);
+void fnvlist_add_byte_array(nvlist_t *, const char *, uchar_t *, uint_t);
+void fnvlist_add_int8_array(nvlist_t *, const char *, int8_t *, uint_t);
+void fnvlist_add_uint8_array(nvlist_t *, const char *, uint8_t *, uint_t);
+void fnvlist_add_int16_array(nvlist_t *, const char *, int16_t *, uint_t);
+void fnvlist_add_uint16_array(nvlist_t *, const char *, uint16_t *, uint_t);
+void fnvlist_add_int32_array(nvlist_t *, const char *, int32_t *, uint_t);
+void fnvlist_add_uint32_array(nvlist_t *, const char *, uint32_t *, uint_t);
+void fnvlist_add_int64_array(nvlist_t *, const char *, int64_t *, uint_t);
+void fnvlist_add_uint64_array(nvlist_t *, const char *, uint64_t *, uint_t);
+void fnvlist_add_string_array(nvlist_t *, const char *, char * const *, uint_t);
+void fnvlist_add_nvlist_array(nvlist_t *, const char *, nvlist_t **, uint_t);
+
+void fnvlist_remove(nvlist_t *, const char *);
+void fnvlist_remove_nvpair(nvlist_t *, nvpair_t *);
+
+nvpair_t *fnvlist_lookup_nvpair(nvlist_t *nvl, const char *name);
+boolean_t fnvlist_lookup_boolean(nvlist_t *nvl, const char *name);
+boolean_t fnvlist_lookup_boolean_value(nvlist_t *nvl, const char *name);
+uchar_t fnvlist_lookup_byte(nvlist_t *nvl, const char *name);
+int8_t fnvlist_lookup_int8(nvlist_t *nvl, const char *name);
+int16_t fnvlist_lookup_int16(nvlist_t *nvl, const char *name);
+int32_t fnvlist_lookup_int32(nvlist_t *nvl, const char *name);
+int64_t fnvlist_lookup_int64(nvlist_t *nvl, const char *name);
+uint8_t fnvlist_lookup_uint8(nvlist_t *nvl, const char *name);
+uint16_t fnvlist_lookup_uint16(nvlist_t *nvl, const char *name);
+uint32_t fnvlist_lookup_uint32(nvlist_t *nvl, const char *name);
+uint64_t fnvlist_lookup_uint64(nvlist_t *nvl, const char *name);
+char *fnvlist_lookup_string(nvlist_t *nvl, const char *name);
+nvlist_t *fnvlist_lookup_nvlist(nvlist_t *nvl, const char *name);
+
+boolean_t fnvpair_value_boolean_value(nvpair_t *nvp);
+uchar_t fnvpair_value_byte(nvpair_t *nvp);
+int8_t fnvpair_value_int8(nvpair_t *nvp);
+int16_t fnvpair_value_int16(nvpair_t *nvp);
+int32_t fnvpair_value_int32(nvpair_t *nvp);
+int64_t fnvpair_value_int64(nvpair_t *nvp);
+uint8_t fnvpair_value_uint8(nvpair_t *nvp);
+uint16_t fnvpair_value_uint16(nvpair_t *nvp);
+uint32_t fnvpair_value_uint32(nvpair_t *nvp);
+uint64_t fnvpair_value_uint64(nvpair_t *nvp);
+char *fnvpair_value_string(nvpair_t *nvp);
+nvlist_t *fnvpair_value_nvlist(nvpair_t *nvp);
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* _SYS_NVPAIR_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/include/sys/nvpair_impl.h
@@ -0,0 +1,73 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License").  You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef	_NVPAIR_IMPL_H
+#define	_NVPAIR_IMPL_H
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <sys/nvpair.h>
+
+/*
+ * The structures here provided for information and debugging purposes only
+ * may be changed in the future.
+ */
+
+/*
+ * implementation linked list for pre-packed data
+ */
+typedef struct i_nvp i_nvp_t;
+
+struct i_nvp {
+	union {
+		uint64_t	_nvi_align;	/* ensure alignment */
+		struct {
+			i_nvp_t	*_nvi_next;	/* pointer to next nvpair */
+			i_nvp_t	*_nvi_prev;	/* pointer to prev nvpair */
+		} _nvi;
+	} _nvi_un;
+	nvpair_t nvi_nvp;			/* nvpair */
+};
+#define	nvi_next	_nvi_un._nvi._nvi_next
+#define	nvi_prev	_nvi_un._nvi._nvi_prev
+
+typedef struct {
+	i_nvp_t		*nvp_list;	/* linked list of nvpairs */
+	i_nvp_t		*nvp_last;	/* last nvpair */
+	i_nvp_t		*nvp_curr;	/* current walker nvpair */
+	nv_alloc_t	*nvp_nva;	/* pluggable allocator */
+	uint32_t	nvp_stat;	/* internal state */
+} nvpriv_t;
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* _NVPAIR_IMPL_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/include/sys/range_tree.h
@@ -0,0 +1,97 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/*
+ * Copyright (c) 2013, 2014 by Delphix. All rights reserved.
+ */
+
+#ifndef _SYS_RANGE_TREE_H
+#define	_SYS_RANGE_TREE_H
+
+#include <sys/avl.h>
+#include <sys/dmu.h>
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+#define	RANGE_TREE_HISTOGRAM_SIZE	64
+
+typedef struct range_tree_ops range_tree_ops_t;
+
+typedef struct range_tree {
+	avl_tree_t	rt_root;	/* offset-ordered segment AVL tree */
+	uint64_t	rt_space;	/* sum of all segments in the map */
+	range_tree_ops_t *rt_ops;
+	void		*rt_arg;
+
+	/*
+	 * The rt_histogram maintains a histogram of ranges. Each bucket,
+	 * rt_histogram[i], contains the number of ranges whose size is:
+	 * 2^i <= size of range in bytes < 2^(i+1)
+	 */
+	uint64_t	rt_histogram[RANGE_TREE_HISTOGRAM_SIZE];
+	kmutex_t	*rt_lock;	/* pointer to lock that protects map */
+} range_tree_t;
+
+typedef struct range_seg {
+	avl_node_t	rs_node;	/* AVL node */
+	avl_node_t	rs_pp_node;	/* AVL picker-private node */
+	uint64_t	rs_start;	/* starting offset of this segment */
+	uint64_t	rs_end;		/* ending offset (non-inclusive) */
+} range_seg_t;
+
+struct range_tree_ops {
+	void    (*rtop_create)(range_tree_t *rt, void *arg);
+	void    (*rtop_destroy)(range_tree_t *rt, void *arg);
+	void	(*rtop_add)(range_tree_t *rt, range_seg_t *rs, void *arg);
+	void    (*rtop_remove)(range_tree_t *rt, range_seg_t *rs, void *arg);
+	void	(*rtop_vacate)(range_tree_t *rt, void *arg);
+};
+
+typedef void range_tree_func_t(void *arg, uint64_t start, uint64_t size);
+
+void range_tree_init(void);
+void range_tree_fini(void);
+range_tree_t *range_tree_create(range_tree_ops_t *ops, void *arg, kmutex_t *lp);
+void range_tree_destroy(range_tree_t *rt);
+boolean_t range_tree_contains(range_tree_t *rt, uint64_t start, uint64_t size);
+uint64_t range_tree_space(range_tree_t *rt);
+void range_tree_verify(range_tree_t *rt, uint64_t start, uint64_t size);
+void range_tree_swap(range_tree_t **rtsrc, range_tree_t **rtdst);
+void range_tree_stat_verify(range_tree_t *rt);
+
+void range_tree_add(void *arg, uint64_t start, uint64_t size);
+void range_tree_remove(void *arg, uint64_t start, uint64_t size);
+void range_tree_clear(range_tree_t *rt, uint64_t start, uint64_t size);
+
+void range_tree_vacate(range_tree_t *rt, range_tree_func_t *func, void *arg);
+void range_tree_walk(range_tree_t *rt, range_tree_func_t *func, void *arg);
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* _SYS_RANGE_TREE_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/include/sys/refcount.h
@@ -0,0 +1,110 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ */
+
+#ifndef	_SYS_REFCOUNT_H
+#define	_SYS_REFCOUNT_H
+
+#include <sys/inttypes.h>
+#include <sys/list.h>
+#include <sys/zfs_context.h>
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+/*
+ * If the reference is held only by the calling function and not any
+ * particular object, use FTAG (which is a string) for the holder_tag.
+ * Otherwise, use the object that holds the reference.
+ */
+#define	FTAG ((char *)__func__)
+
+#ifdef	ZFS_DEBUG
+typedef struct reference {
+	list_node_t ref_link;
+	void *ref_holder;
+	uint64_t ref_number;
+	uint8_t *ref_removed;
+} reference_t;
+
+typedef struct refcount {
+	kmutex_t rc_mtx;
+	boolean_t rc_tracked;
+	list_t rc_list;
+	list_t rc_removed;
+	int64_t rc_count;
+	int64_t rc_removed_count;
+} refcount_t;
+
+/* Note: refcount_t must be initialized with refcount_create[_untracked]() */
+
+void refcount_create(refcount_t *rc);
+void refcount_create_untracked(refcount_t *rc);
+void refcount_destroy(refcount_t *rc);
+void refcount_destroy_many(refcount_t *rc, uint64_t number);
+int refcount_is_zero(refcount_t *rc);
+int64_t refcount_count(refcount_t *rc);
+int64_t refcount_add(refcount_t *rc, void *holder_tag);
+int64_t refcount_remove(refcount_t *rc, void *holder_tag);
+int64_t refcount_add_many(refcount_t *rc, uint64_t number, void *holder_tag);
+int64_t refcount_remove_many(refcount_t *rc, uint64_t number, void *holder_tag);
+void refcount_transfer(refcount_t *dst, refcount_t *src);
+
+void refcount_init(void);
+void refcount_fini(void);
+
+#else	/* ZFS_DEBUG */
+
+typedef struct refcount {
+	uint64_t rc_count;
+} refcount_t;
+
+#define	refcount_create(rc) ((rc)->rc_count = 0)
+#define	refcount_create_untracked(rc) ((rc)->rc_count = 0)
+#define	refcount_destroy(rc) ((rc)->rc_count = 0)
+#define	refcount_destroy_many(rc, number) ((rc)->rc_count = 0)
+#define	refcount_is_zero(rc) ((rc)->rc_count == 0)
+#define	refcount_count(rc) ((rc)->rc_count)
+#define	refcount_add(rc, holder) atomic_add_64_nv(&(rc)->rc_count, 1)
+#define	refcount_remove(rc, holder) atomic_add_64_nv(&(rc)->rc_count, -1)
+#define	refcount_add_many(rc, number, holder) \
+	atomic_add_64_nv(&(rc)->rc_count, number)
+#define	refcount_remove_many(rc, number, holder) \
+	atomic_add_64_nv(&(rc)->rc_count, -number)
+#define	refcount_transfer(dst, src) { \
+	uint64_t __tmp = (src)->rc_count; \
+	atomic_add_64(&(src)->rc_count, -__tmp); \
+	atomic_add_64(&(dst)->rc_count, __tmp); \
+}
+
+#define	refcount_init()
+#define	refcount_fini()
+
+#endif	/* ZFS_DEBUG */
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif /* _SYS_REFCOUNT_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/include/sys/rrwlock.h
@@ -0,0 +1,115 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * Copyright (c) 2012 by Delphix. All rights reserved.
+ */
+
+#ifndef	_SYS_RR_RW_LOCK_H
+#define	_SYS_RR_RW_LOCK_H
+
+
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+#include <sys/inttypes.h>
+#include <sys/zfs_context.h>
+#include <sys/refcount.h>
+
+/*
+ * A reader-writer lock implementation that allows re-entrant reads, but
+ * still gives writers priority on "new" reads.
+ *
+ * See rrwlock.c for more details about the implementation.
+ *
+ * Fields of the rrwlock_t structure:
+ * - rr_lock: protects modification and reading of rrwlock_t fields
+ * - rr_cv: cv for waking up readers or waiting writers
+ * - rr_writer: thread id of the current writer
+ * - rr_anon_rount: number of active anonymous readers
+ * - rr_linked_rcount: total number of non-anonymous active readers
+ * - rr_writer_wanted: a writer wants the lock
+ */
+typedef struct rrwlock {
+	kmutex_t	rr_lock;
+	kcondvar_t	rr_cv;
+	kthread_t	*rr_writer;
+	refcount_t	rr_anon_rcount;
+	refcount_t	rr_linked_rcount;
+	boolean_t	rr_writer_wanted;
+	boolean_t	rr_track_all;
+} rrwlock_t;
+
+/*
+ * 'tag' is used in reference counting tracking.  The
+ * 'tag' must be the same in a rrw_enter() as in its
+ * corresponding rrw_exit().
+ */
+void rrw_init(rrwlock_t *rrl, boolean_t track_all);
+void rrw_destroy(rrwlock_t *rrl);
+void rrw_enter(rrwlock_t *rrl, krw_t rw, void *tag);
+void rrw_enter_read(rrwlock_t *rrl, void *tag);
+void rrw_enter_read_prio(rrwlock_t *rrl, void *tag);
+void rrw_enter_write(rrwlock_t *rrl);
+void rrw_exit(rrwlock_t *rrl, void *tag);
+boolean_t rrw_held(rrwlock_t *rrl, krw_t rw);
+void rrw_tsd_destroy(void *arg);
+
+#define	RRW_READ_HELD(x)	rrw_held(x, RW_READER)
+#define	RRW_WRITE_HELD(x)	rrw_held(x, RW_WRITER)
+#define	RRW_LOCK_HELD(x) \
+	(rrw_held(x, RW_WRITER) || rrw_held(x, RW_READER))
+
+/*
+ * A reader-mostly lock implementation, tuning above reader-writer locks
+ * for hightly parallel read acquisitions, pessimizing write acquisitions.
+ *
+ * This should be a prime number.  See comment in rrwlock.c near
+ * RRM_TD_LOCK() for details.
+ */
+#define	RRM_NUM_LOCKS		17
+typedef struct rrmlock {
+	rrwlock_t	locks[RRM_NUM_LOCKS];
+} rrmlock_t;
+
+void rrm_init(rrmlock_t *rrl, boolean_t track_all);
+void rrm_destroy(rrmlock_t *rrl);
+void rrm_enter(rrmlock_t *rrl, krw_t rw, void *tag);
+void rrm_enter_read(rrmlock_t *rrl, void *tag);
+void rrm_enter_write(rrmlock_t *rrl);
+void rrm_exit(rrmlock_t *rrl, void *tag);
+boolean_t rrm_held(rrmlock_t *rrl, krw_t rw);
+
+#define	RRM_READ_HELD(x)	rrm_held(x, RW_READER)
+#define	RRM_WRITE_HELD(x)	rrm_held(x, RW_WRITER)
+#define	RRM_LOCK_HELD(x) \
+	(rrm_held(x, RW_WRITER) || rrm_held(x, RW_READER))
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* _SYS_RR_RW_LOCK_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/include/sys/sa.h
@@ -0,0 +1,175 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ */
+
+#ifndef	_SYS_SA_H
+#define	_SYS_SA_H
+
+#include <sys/dmu.h>
+
+/*
+ * Currently available byteswap functions.
+ * If it all possible new attributes should used
+ * one of the already defined byteswap functions.
+ * If a new byteswap function is added then the
+ * ZPL/Pool version will need to be bumped.
+ */
+
+typedef enum sa_bswap_type {
+	SA_UINT64_ARRAY,
+	SA_UINT32_ARRAY,
+	SA_UINT16_ARRAY,
+	SA_UINT8_ARRAY,
+	SA_ACL,
+} sa_bswap_type_t;
+
+typedef uint16_t	sa_attr_type_t;
+
+/*
+ * Attribute to register support for.
+ */
+typedef struct sa_attr_reg {
+	char 			*sa_name;	/* attribute name */
+	uint16_t 		sa_length;
+	sa_bswap_type_t		sa_byteswap;	/* bswap functon enum */
+	sa_attr_type_t 		sa_attr; /* filled in during registration */
+} sa_attr_reg_t;
+
+
+typedef void (sa_data_locator_t)(void **, uint32_t *, uint32_t,
+    boolean_t, void *userptr);
+
+/*
+ * array of attributes to store.
+ *
+ * This array should be treated as opaque/private data.
+ * The SA_BULK_ADD_ATTR() macro should be used for manipulating
+ * the array.
+ *
+ * When sa_replace_all_by_template() is used the attributes
+ * will be stored in the order defined in the array, except that
+ * the attributes may be split between the bonus and the spill buffer
+ *
+ */
+typedef struct sa_bulk_attr {
+	void			*sa_data;
+	sa_data_locator_t	*sa_data_func;
+	uint16_t		sa_length;
+	sa_attr_type_t		sa_attr;
+	/* the following are private to the sa framework */
+	void 			*sa_addr;
+	uint16_t		sa_buftype;
+	uint16_t		sa_size;
+} sa_bulk_attr_t;
+
+/*
+ * The on-disk format of sa_hdr_phys_t limits SA lengths to 16-bit values.
+ */
+#define	SA_ATTR_MAX_LEN UINT16_MAX
+
+/*
+ * special macro for adding entries for bulk attr support
+ * bulk - sa_bulk_attr_t
+ * count - integer that will be incremented during each add
+ * attr - attribute to manipulate
+ * func - function for accessing data.
+ * data - pointer to data.
+ * len - length of data
+ */
+
+#define	SA_ADD_BULK_ATTR(b, idx, attr, func, data, len) \
+{ \
+	ASSERT3U(len, <=, SA_ATTR_MAX_LEN); \
+	b[idx].sa_attr = attr;\
+	b[idx].sa_data_func = func; \
+	b[idx].sa_data = data; \
+	b[idx++].sa_length = len; \
+}
+
+typedef struct sa_os sa_os_t;
+
+typedef enum sa_handle_type {
+	SA_HDL_SHARED,
+	SA_HDL_PRIVATE
+} sa_handle_type_t;
+
+struct sa_handle;
+typedef void *sa_lookup_tab_t;
+typedef struct sa_handle sa_handle_t;
+
+typedef void (sa_update_cb_t)(sa_handle_t *, dmu_tx_t *tx);
+
+int sa_handle_get(objset_t *, uint64_t, void *userp,
+    sa_handle_type_t, sa_handle_t **);
+int sa_handle_get_from_db(objset_t *, dmu_buf_t *, void *userp,
+    sa_handle_type_t, sa_handle_t **);
+void sa_handle_destroy(sa_handle_t *);
+int sa_buf_hold(objset_t *, uint64_t, void *, dmu_buf_t **);
+void sa_buf_rele(dmu_buf_t *, void *);
+int sa_lookup(sa_handle_t *, sa_attr_type_t, void *buf, uint32_t buflen);
+int sa_update(sa_handle_t *, sa_attr_type_t, void *buf,
+    uint32_t buflen, dmu_tx_t *);
+int sa_remove(sa_handle_t *, sa_attr_type_t, dmu_tx_t *);
+int sa_bulk_lookup(sa_handle_t *, sa_bulk_attr_t *, int count);
+int sa_bulk_lookup_locked(sa_handle_t *, sa_bulk_attr_t *, int count);
+int sa_bulk_update(sa_handle_t *, sa_bulk_attr_t *, int count, dmu_tx_t *);
+int sa_size(sa_handle_t *, sa_attr_type_t, int *);
+int sa_update_from_cb(sa_handle_t *, sa_attr_type_t,
+    uint32_t buflen, sa_data_locator_t *, void *userdata, dmu_tx_t *);
+void sa_object_info(sa_handle_t *, dmu_object_info_t *);
+void sa_object_size(sa_handle_t *, uint32_t *, u_longlong_t *);
+void *sa_get_userdata(sa_handle_t *);
+void sa_set_userp(sa_handle_t *, void *);
+dmu_buf_t *sa_get_db(sa_handle_t *);
+uint64_t sa_handle_object(sa_handle_t *);
+boolean_t sa_attr_would_spill(sa_handle_t *, sa_attr_type_t, int size);
+void sa_spill_rele(sa_handle_t *);
+void sa_register_update_callback(objset_t *, sa_update_cb_t *);
+int sa_setup(objset_t *, uint64_t, sa_attr_reg_t *, int, sa_attr_type_t **);
+void sa_tear_down(objset_t *);
+int sa_replace_all_by_template(sa_handle_t *, sa_bulk_attr_t *,
+    int, dmu_tx_t *);
+int sa_replace_all_by_template_locked(sa_handle_t *, sa_bulk_attr_t *,
+    int, dmu_tx_t *);
+boolean_t sa_enabled(objset_t *);
+void sa_cache_init(void);
+void sa_cache_fini(void);
+int sa_set_sa_object(objset_t *, uint64_t);
+int sa_hdrsize(void *);
+void sa_handle_lock(sa_handle_t *);
+void sa_handle_unlock(sa_handle_t *);
+
+#ifdef _KERNEL
+int sa_lookup_uio(sa_handle_t *, sa_attr_type_t, uio_t *);
+#endif
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* _SYS_SA_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/include/sys/sa_impl.h
@@ -0,0 +1,289 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013 by Delphix. All rights reserved.
+ * Copyright (c) 2014 Spectra Logic Corporation, All rights reserved.
+ */
+
+#ifndef	_SYS_SA_IMPL_H
+#define	_SYS_SA_IMPL_H
+
+#include <sys/dmu.h>
+#include <sys/refcount.h>
+#include <sys/list.h>
+
+/*
+ * Array of known attributes and their
+ * various characteristics.
+ */
+typedef struct sa_attr_table {
+	sa_attr_type_t	sa_attr;
+	uint8_t sa_registered;
+	uint16_t sa_length;
+	sa_bswap_type_t sa_byteswap;
+	char *sa_name;
+} sa_attr_table_t;
+
+/*
+ * Zap attribute format for attribute registration
+ *
+ * 64      56      48      40      32      24      16      8       0
+ * +-------+-------+-------+-------+-------+-------+-------+-------+
+ * |        unused         |      len      | bswap |   attr num    |
+ * +-------+-------+-------+-------+-------+-------+-------+-------+
+ *
+ * Zap attribute format for layout information.
+ *
+ * layout information is stored as an array of attribute numbers
+ * The name of the attribute is the layout number (0, 1, 2, ...)
+ *
+ * 16       0
+ * +---- ---+
+ * | attr # |
+ * +--------+
+ * | attr # |
+ * +--- ----+
+ *  ......
+ *
+ */
+
+#define	ATTR_BSWAP(x)	BF32_GET(x, 16, 8)
+#define	ATTR_LENGTH(x)	BF32_GET(x, 24, 16)
+#define	ATTR_NUM(x)	BF32_GET(x, 0, 16)
+#define	ATTR_ENCODE(x, attr, length, bswap) \
+{ \
+	BF64_SET(x, 24, 16, length); \
+	BF64_SET(x, 16, 8, bswap); \
+	BF64_SET(x, 0, 16, attr); \
+}
+
+#define	TOC_OFF(x)		BF32_GET(x, 0, 23)
+#define	TOC_ATTR_PRESENT(x)	BF32_GET(x, 31, 1)
+#define	TOC_LEN_IDX(x)		BF32_GET(x, 24, 4)
+#define	TOC_ATTR_ENCODE(x, len_idx, offset) \
+{ \
+	BF32_SET(x, 31, 1, 1); \
+	BF32_SET(x, 24, 7, len_idx); \
+	BF32_SET(x, 0, 24, offset); \
+}
+
+#define	SA_LAYOUTS	"LAYOUTS"
+#define	SA_REGISTRY	"REGISTRY"
+
+/*
+ * Each unique layout will have their own table
+ * sa_lot (layout_table)
+ */
+typedef struct sa_lot {
+	avl_node_t lot_num_node;
+	avl_node_t lot_hash_node;
+	uint64_t lot_num;
+	uint64_t lot_hash;
+	sa_attr_type_t *lot_attrs;	/* array of attr #'s */
+	uint32_t lot_var_sizes;	/* how many aren't fixed size */
+	uint32_t lot_attr_count;	/* total attr count */
+	list_t 	lot_idx_tab;	/* should be only a couple of entries */
+	int	lot_instance;	/* used with lot_hash to identify entry */
+} sa_lot_t;
+
+/* index table of offsets */
+typedef struct sa_idx_tab {
+	list_node_t	sa_next;
+	sa_lot_t	*sa_layout;
+	uint16_t	*sa_variable_lengths;
+	refcount_t	sa_refcount;
+	uint32_t	*sa_idx_tab;	/* array of offsets */
+} sa_idx_tab_t;
+
+/*
+ * Since the offset/index information into the actual data
+ * will usually be identical we can share that information with
+ * all handles that have the exact same offsets.
+ *
+ * You would typically only have a large number of different table of
+ * contents if you had a several variable sized attributes.
+ *
+ * Two AVL trees are used to track the attribute layout numbers.
+ * one is keyed by number and will be consulted when a DMU_OT_SA
+ * object is first read.  The second tree is keyed by the hash signature
+ * of the attributes and will be consulted when an attribute is added
+ * to determine if we already have an instance of that layout.  Both
+ * of these tree's are interconnected.  The only difference is that
+ * when an entry is found in the "hash" tree the list of attributes will
+ * need to be compared against the list of attributes you have in hand.
+ * The assumption is that typically attributes will just be updated and
+ * adding a completely new attribute is a very rare operation.
+ */
+struct sa_os {
+	kmutex_t 	sa_lock;
+	boolean_t	sa_need_attr_registration;
+	boolean_t	sa_force_spill;
+	uint64_t	sa_master_obj;
+	uint64_t	sa_reg_attr_obj;
+	uint64_t	sa_layout_attr_obj;
+	int		sa_num_attrs;
+	sa_attr_table_t *sa_attr_table;	 /* private attr table */
+	sa_update_cb_t	*sa_update_cb;
+	avl_tree_t	sa_layout_num_tree;  /* keyed by layout number */
+	avl_tree_t	sa_layout_hash_tree; /* keyed by layout hash value */
+	int		sa_user_table_sz;
+	sa_attr_type_t	*sa_user_table; /* user name->attr mapping table */
+};
+
+/*
+ * header for all bonus and spill buffers.
+ *
+ * The header has a fixed portion with a variable number
+ * of "lengths" depending on the number of variable sized
+ * attributes which are determined by the "layout number"
+ */
+
+#define	SA_MAGIC	0x2F505A  /* ZFS SA */
+typedef struct sa_hdr_phys {
+	uint32_t sa_magic;
+	/*
+	 * Encoded with hdrsize and layout number as follows:
+	 * 16      10       0
+	 * +--------+-------+
+	 * | hdrsz  |layout |
+	 * +--------+-------+
+	 *
+	 * Bits 0-10 are the layout number
+	 * Bits 11-16 are the size of the header.
+	 * The hdrsize is the number * 8
+	 *
+	 * For example.
+	 * hdrsz of 1 ==> 8 byte header
+	 *          2 ==> 16 byte header
+	 *
+	 */
+	uint16_t sa_layout_info;
+	uint16_t sa_lengths[1];	/* optional sizes for variable length attrs */
+	/* ... Data follows the lengths.  */
+} sa_hdr_phys_t;
+
+#define	SA_HDR_LAYOUT_NUM(hdr) BF32_GET(hdr->sa_layout_info, 0, 10)
+#define	SA_HDR_SIZE(hdr) BF32_GET_SB(hdr->sa_layout_info, 10, 6, 3, 0)
+#define	SA_HDR_LAYOUT_INFO_ENCODE(x, num, size) \
+{ \
+	BF32_SET_SB(x, 10, 6, 3, 0, size); \
+	BF32_SET(x, 0, 10, num); \
+}
+
+typedef enum sa_buf_type {
+	SA_BONUS = 1,
+	SA_SPILL = 2
+} sa_buf_type_t;
+
+typedef enum sa_data_op {
+	SA_LOOKUP,
+	SA_UPDATE,
+	SA_ADD,
+	SA_REPLACE,
+	SA_REMOVE
+} sa_data_op_t;
+
+/*
+ * Opaque handle used for most sa functions
+ *
+ * This needs to be kept as small as possible.
+ */
+
+struct sa_handle {
+	dmu_buf_user_t	sa_dbu;
+	kmutex_t	sa_lock;
+	dmu_buf_t	*sa_bonus;
+	dmu_buf_t	*sa_spill;
+	objset_t	*sa_os;
+	void		*sa_userp;
+	sa_idx_tab_t	*sa_bonus_tab;	 /* idx of bonus */
+	sa_idx_tab_t	*sa_spill_tab; /* only present if spill activated */
+};
+
+#define	SA_GET_DB(hdl, type)	\
+	(dmu_buf_impl_t *)((type == SA_BONUS) ? hdl->sa_bonus : hdl->sa_spill)
+
+#define	SA_GET_HDR(hdl, type) \
+	((sa_hdr_phys_t *)((dmu_buf_impl_t *)(SA_GET_DB(hdl, \
+	type))->db.db_data))
+
+#define	SA_IDX_TAB_GET(hdl, type) \
+	(type == SA_BONUS ? hdl->sa_bonus_tab : hdl->sa_spill_tab)
+
+#define	IS_SA_BONUSTYPE(a)	\
+	((a == DMU_OT_SA) ? B_TRUE : B_FALSE)
+
+#define	SA_BONUSTYPE_FROM_DB(db) \
+	(dmu_get_bonustype((dmu_buf_t *)db))
+
+#define	SA_BLKPTR_SPACE	(DN_MAX_BONUSLEN - sizeof (blkptr_t))
+
+#define	SA_LAYOUT_NUM(x, type) \
+	((!IS_SA_BONUSTYPE(type) ? 0 : (((IS_SA_BONUSTYPE(type)) && \
+	((SA_HDR_LAYOUT_NUM(x)) == 0)) ? 1 : SA_HDR_LAYOUT_NUM(x))))
+
+
+#define	SA_REGISTERED_LEN(sa, attr) sa->sa_attr_table[attr].sa_length
+
+#define	SA_ATTR_LEN(sa, idx, attr, hdr) ((SA_REGISTERED_LEN(sa, attr) == 0) ?\
+	hdr->sa_lengths[TOC_LEN_IDX(idx->sa_idx_tab[attr])] : \
+	SA_REGISTERED_LEN(sa, attr))
+
+#define	SA_SET_HDR(hdr, num, size) \
+	{ \
+		hdr->sa_magic = SA_MAGIC; \
+		SA_HDR_LAYOUT_INFO_ENCODE(hdr->sa_layout_info, num, size); \
+	}
+
+#define	SA_ATTR_INFO(sa, idx, hdr, attr, bulk, type, hdl) \
+	{ \
+		bulk.sa_size = SA_ATTR_LEN(sa, idx, attr, hdr); \
+		bulk.sa_buftype = type; \
+		bulk.sa_addr = \
+		    (void *)((uintptr_t)TOC_OFF(idx->sa_idx_tab[attr]) + \
+		    (uintptr_t)hdr); \
+}
+
+#define	SA_HDR_SIZE_MATCH_LAYOUT(hdr, tb) \
+	(SA_HDR_SIZE(hdr) == (sizeof (sa_hdr_phys_t) + \
+	(tb->lot_var_sizes > 1 ? P2ROUNDUP((tb->lot_var_sizes - 1) * \
+	sizeof (uint16_t), 8) : 0)))
+
+int sa_add_impl(sa_handle_t *, sa_attr_type_t,
+    uint32_t, sa_data_locator_t, void *, dmu_tx_t *);
+
+void sa_register_update_callback_locked(objset_t *, sa_update_cb_t *);
+int sa_size_locked(sa_handle_t *, sa_attr_type_t, int *);
+
+void sa_default_locator(void **, uint32_t *, uint32_t, boolean_t, void *);
+int sa_attr_size(sa_os_t *, sa_idx_tab_t *, sa_attr_type_t,
+    uint16_t *, sa_hdr_phys_t *);
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* _SYS_SA_IMPL_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/include/sys/sdt.h
@@ -0,0 +1,70 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License").  You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _SYS_SDT_H
+#define	_SYS_SDT_H
+
+#ifndef _KERNEL
+
+#define	ZFS_PROBE(a)			((void) 0)
+#define	ZFS_PROBE1(a, c)		((void) 0)
+#define	ZFS_PROBE2(a, c, e)		((void) 0)
+#define	ZFS_PROBE3(a, c, e, g)		((void) 0)
+#define	ZFS_PROBE4(a, c, e, g, i)	((void) 0)
+#define	ZFS_SET_ERROR(err)		((void) 0)
+
+#else
+
+#if defined(HAVE_DECLARE_EVENT_CLASS)
+
+#include <sys/trace.h>
+
+/*
+ * The set-error SDT probe is extra static, in that we declare its fake
+ * function literally, rather than with the DTRACE_PROBE1() macro.  This is
+ * necessary so that SET_ERROR() can evaluate to a value, which wouldn't
+ * be possible if it required multiple statements (to declare the function
+ * and then call it).
+ *
+ * SET_ERROR() uses the comma operator so that it can be used without much
+ * additional code.  For example, "return (EINVAL);" becomes
+ * "return (SET_ERROR(EINVAL));".  Note that the argument will be evaluated
+ * twice, so it should not have side effects (e.g. something like:
+ * "return (SET_ERROR(log_error(EINVAL, info)));" would log the error twice).
+ */
+#define	SET_ERROR(err) \
+	(trace_zfs_set__error(__FILE__, __func__, __LINE__, err), err)
+
+#else
+
+#undef SET_ERROR
+#define	SET_ERROR(err) (err)
+
+#endif /* HAVE_DECLARE_EVENT_CLASS */
+
+#endif /* _KERNEL */
+
+#endif /* _SYS_SDT_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/include/sys/spa.h
@@ -0,0 +1,922 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2014 by Delphix. All rights reserved.
+ * Copyright 2011 Nexenta Systems, Inc.  All rights reserved.
+ * Copyright (c) 2014 Spectra Logic Corporation, All rights reserved.
+ */
+
+#ifndef _SYS_SPA_H
+#define	_SYS_SPA_H
+
+#include <sys/avl.h>
+#include <sys/zfs_context.h>
+#include <sys/kstat.h>
+#include <sys/nvpair.h>
+#include <sys/sysmacros.h>
+#include <sys/types.h>
+#include <sys/fs/zfs.h>
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+/*
+ * Forward references that lots of things need.
+ */
+typedef struct spa spa_t;
+typedef struct vdev vdev_t;
+typedef struct metaslab metaslab_t;
+typedef struct metaslab_group metaslab_group_t;
+typedef struct metaslab_class metaslab_class_t;
+typedef struct zio zio_t;
+typedef struct zilog zilog_t;
+typedef struct spa_aux_vdev spa_aux_vdev_t;
+typedef struct ddt ddt_t;
+typedef struct ddt_entry ddt_entry_t;
+typedef struct zbookmark_phys zbookmark_phys_t;
+
+struct dsl_pool;
+struct dsl_dataset;
+
+/*
+ * General-purpose 32-bit and 64-bit bitfield encodings.
+ */
+#define	BF32_DECODE(x, low, len)	P2PHASE((x) >> (low), 1U << (len))
+#define	BF64_DECODE(x, low, len)	P2PHASE((x) >> (low), 1ULL << (len))
+#define	BF32_ENCODE(x, low, len)	(P2PHASE((x), 1U << (len)) << (low))
+#define	BF64_ENCODE(x, low, len)	(P2PHASE((x), 1ULL << (len)) << (low))
+
+#define	BF32_GET(x, low, len)		BF32_DECODE(x, low, len)
+#define	BF64_GET(x, low, len)		BF64_DECODE(x, low, len)
+
+#define	BF32_SET(x, low, len, val) do { \
+	ASSERT3U(val, <, 1U << (len)); \
+	ASSERT3U(low + len, <=, 32); \
+	(x) ^= BF32_ENCODE((x >> low) ^ (val), low, len); \
+_NOTE(CONSTCOND) } while (0)
+
+#define	BF64_SET(x, low, len, val) do { \
+	ASSERT3U(val, <, 1ULL << (len)); \
+	ASSERT3U(low + len, <=, 64); \
+	((x) ^= BF64_ENCODE((x >> low) ^ (val), low, len)); \
+_NOTE(CONSTCOND) } while (0)
+
+#define	BF32_GET_SB(x, low, len, shift, bias)	\
+	((BF32_GET(x, low, len) + (bias)) << (shift))
+#define	BF64_GET_SB(x, low, len, shift, bias)	\
+	((BF64_GET(x, low, len) + (bias)) << (shift))
+
+#define	BF32_SET_SB(x, low, len, shift, bias, val) do { \
+	ASSERT(IS_P2ALIGNED(val, 1U << shift)); \
+	ASSERT3S((val) >> (shift), >=, bias); \
+	BF32_SET(x, low, len, ((val) >> (shift)) - (bias)); \
+_NOTE(CONSTCOND) } while (0)
+#define	BF64_SET_SB(x, low, len, shift, bias, val) do { \
+	ASSERT(IS_P2ALIGNED(val, 1ULL << shift)); \
+	ASSERT3S((val) >> (shift), >=, bias); \
+	BF64_SET(x, low, len, ((val) >> (shift)) - (bias)); \
+_NOTE(CONSTCOND) } while (0)
+
+/*
+ * We currently support block sizes from 512 bytes to 16MB.
+ * The benefits of larger blocks, and thus larger IO, need to be weighed
+ * against the cost of COWing a giant block to modify one byte, and the
+ * large latency of reading or writing a large block.
+ *
+ * Note that although blocks up to 16MB are supported, the recordsize
+ * property can not be set larger than zfs_max_recordsize (default 1MB).
+ * See the comment near zfs_max_recordsize in dsl_dataset.c for details.
+ *
+ * Note that although the LSIZE field of the blkptr_t can store sizes up
+ * to 32MB, the dnode's dn_datablkszsec can only store sizes up to
+ * 32MB - 512 bytes.  Therefore, we limit SPA_MAXBLOCKSIZE to 16MB.
+ */
+#define	SPA_MINBLOCKSHIFT	9
+#define	SPA_OLD_MAXBLOCKSHIFT	17
+#define	SPA_MAXBLOCKSHIFT	24
+#define	SPA_MINBLOCKSIZE	(1ULL << SPA_MINBLOCKSHIFT)
+#define	SPA_OLD_MAXBLOCKSIZE	(1ULL << SPA_OLD_MAXBLOCKSHIFT)
+#define	SPA_MAXBLOCKSIZE	(1ULL << SPA_MAXBLOCKSHIFT)
+
+/*
+ * Size of block to hold the configuration data (a packed nvlist)
+ */
+#define	SPA_CONFIG_BLOCKSIZE	(1ULL << 14)
+
+/*
+ * The DVA size encodings for LSIZE and PSIZE support blocks up to 32MB.
+ * The ASIZE encoding should be at least 64 times larger (6 more bits)
+ * to support up to 4-way RAID-Z mirror mode with worst-case gang block
+ * overhead, three DVAs per bp, plus one more bit in case we do anything
+ * else that expands the ASIZE.
+ */
+#define	SPA_LSIZEBITS		16	/* LSIZE up to 32M (2^16 * 512)	*/
+#define	SPA_PSIZEBITS		16	/* PSIZE up to 32M (2^16 * 512)	*/
+#define	SPA_ASIZEBITS		24	/* ASIZE up to 64 times larger	*/
+
+/*
+ * All SPA data is represented by 128-bit data virtual addresses (DVAs).
+ * The members of the dva_t should be considered opaque outside the SPA.
+ */
+typedef struct dva {
+	uint64_t	dva_word[2];
+} dva_t;
+
+/*
+ * Each block has a 256-bit checksum -- strong enough for cryptographic hashes.
+ */
+typedef struct zio_cksum {
+	uint64_t	zc_word[4];
+} zio_cksum_t;
+
+/*
+ * Each block is described by its DVAs, time of birth, checksum, etc.
+ * The word-by-word, bit-by-bit layout of the blkptr is as follows:
+ *
+ *	64	56	48	40	32	24	16	8	0
+ *	+-------+-------+-------+-------+-------+-------+-------+-------+
+ * 0	|		vdev1		| GRID  |	  ASIZE		|
+ *	+-------+-------+-------+-------+-------+-------+-------+-------+
+ * 1	|G|			 offset1				|
+ *	+-------+-------+-------+-------+-------+-------+-------+-------+
+ * 2	|		vdev2		| GRID  |	  ASIZE		|
+ *	+-------+-------+-------+-------+-------+-------+-------+-------+
+ * 3	|G|			 offset2				|
+ *	+-------+-------+-------+-------+-------+-------+-------+-------+
+ * 4	|		vdev3		| GRID  |	  ASIZE		|
+ *	+-------+-------+-------+-------+-------+-------+-------+-------+
+ * 5	|G|			 offset3				|
+ *	+-------+-------+-------+-------+-------+-------+-------+-------+
+ * 6	|BDX|lvl| type	| cksum |E| comp|    PSIZE	|     LSIZE	|
+ *	+-------+-------+-------+-------+-------+-------+-------+-------+
+ * 7	|			padding					|
+ *	+-------+-------+-------+-------+-------+-------+-------+-------+
+ * 8	|			padding					|
+ *	+-------+-------+-------+-------+-------+-------+-------+-------+
+ * 9	|			physical birth txg			|
+ *	+-------+-------+-------+-------+-------+-------+-------+-------+
+ * a	|			logical birth txg			|
+ *	+-------+-------+-------+-------+-------+-------+-------+-------+
+ * b	|			fill count				|
+ *	+-------+-------+-------+-------+-------+-------+-------+-------+
+ * c	|			checksum[0]				|
+ *	+-------+-------+-------+-------+-------+-------+-------+-------+
+ * d	|			checksum[1]				|
+ *	+-------+-------+-------+-------+-------+-------+-------+-------+
+ * e	|			checksum[2]				|
+ *	+-------+-------+-------+-------+-------+-------+-------+-------+
+ * f	|			checksum[3]				|
+ *	+-------+-------+-------+-------+-------+-------+-------+-------+
+ *
+ * Legend:
+ *
+ * vdev		virtual device ID
+ * offset	offset into virtual device
+ * LSIZE	logical size
+ * PSIZE	physical size (after compression)
+ * ASIZE	allocated size (including RAID-Z parity and gang block headers)
+ * GRID		RAID-Z layout information (reserved for future use)
+ * cksum	checksum function
+ * comp		compression function
+ * G		gang block indicator
+ * B		byteorder (endianness)
+ * D		dedup
+ * X		encryption (on version 30, which is not supported)
+ * E		blkptr_t contains embedded data (see below)
+ * lvl		level of indirection
+ * type		DMU object type
+ * phys birth	txg of block allocation; zero if same as logical birth txg
+ * log. birth	transaction group in which the block was logically born
+ * fill count	number of non-zero blocks under this bp
+ * checksum[4]	256-bit checksum of the data this bp describes
+ */
+
+/*
+ * "Embedded" blkptr_t's don't actually point to a block, instead they
+ * have a data payload embedded in the blkptr_t itself.  See the comment
+ * in blkptr.c for more details.
+ *
+ * The blkptr_t is laid out as follows:
+ *
+ *	64	56	48	40	32	24	16	8	0
+ *	+-------+-------+-------+-------+-------+-------+-------+-------+
+ * 0	|      payload                                                  |
+ * 1	|      payload                                                  |
+ * 2	|      payload                                                  |
+ * 3	|      payload                                                  |
+ * 4	|      payload                                                  |
+ * 5	|      payload                                                  |
+ *	+-------+-------+-------+-------+-------+-------+-------+-------+
+ * 6	|BDX|lvl| type	| etype |E| comp| PSIZE|              LSIZE	|
+ *	+-------+-------+-------+-------+-------+-------+-------+-------+
+ * 7	|      payload                                                  |
+ * 8	|      payload                                                  |
+ * 9	|      payload                                                  |
+ *	+-------+-------+-------+-------+-------+-------+-------+-------+
+ * a	|			logical birth txg			|
+ *	+-------+-------+-------+-------+-------+-------+-------+-------+
+ * b	|      payload                                                  |
+ * c	|      payload                                                  |
+ * d	|      payload                                                  |
+ * e	|      payload                                                  |
+ * f	|      payload                                                  |
+ *	+-------+-------+-------+-------+-------+-------+-------+-------+
+ *
+ * Legend:
+ *
+ * payload		contains the embedded data
+ * B (byteorder)	byteorder (endianness)
+ * D (dedup)		padding (set to zero)
+ * X			encryption (set to zero; see above)
+ * E (embedded)		set to one
+ * lvl			indirection level
+ * type			DMU object type
+ * etype		how to interpret embedded data (BP_EMBEDDED_TYPE_*)
+ * comp			compression function of payload
+ * PSIZE		size of payload after compression, in bytes
+ * LSIZE		logical size of payload, in bytes
+ *			note that 25 bits is enough to store the largest
+ *			"normal" BP's LSIZE (2^16 * 2^9) in bytes
+ * log. birth		transaction group in which the block was logically born
+ *
+ * Note that LSIZE and PSIZE are stored in bytes, whereas for non-embedded
+ * bp's they are stored in units of SPA_MINBLOCKSHIFT.
+ * Generally, the generic BP_GET_*() macros can be used on embedded BP's.
+ * The B, D, X, lvl, type, and comp fields are stored the same as with normal
+ * BP's so the BP_SET_* macros can be used with them.  etype, PSIZE, LSIZE must
+ * be set with the BPE_SET_* macros.  BP_SET_EMBEDDED() should be called before
+ * other macros, as they assert that they are only used on BP's of the correct
+ * "embedded-ness".
+ */
+
+#define	BPE_GET_ETYPE(bp)	\
+	(ASSERT(BP_IS_EMBEDDED(bp)), \
+	BF64_GET((bp)->blk_prop, 40, 8))
+#define	BPE_SET_ETYPE(bp, t)	do { \
+	ASSERT(BP_IS_EMBEDDED(bp)); \
+	BF64_SET((bp)->blk_prop, 40, 8, t); \
+_NOTE(CONSTCOND) } while (0)
+
+#define	BPE_GET_LSIZE(bp)	\
+	(ASSERT(BP_IS_EMBEDDED(bp)), \
+	BF64_GET_SB((bp)->blk_prop, 0, 25, 0, 1))
+#define	BPE_SET_LSIZE(bp, x)	do { \
+	ASSERT(BP_IS_EMBEDDED(bp)); \
+	BF64_SET_SB((bp)->blk_prop, 0, 25, 0, 1, x); \
+_NOTE(CONSTCOND) } while (0)
+
+#define	BPE_GET_PSIZE(bp)	\
+	(ASSERT(BP_IS_EMBEDDED(bp)), \
+	BF64_GET_SB((bp)->blk_prop, 25, 7, 0, 1))
+#define	BPE_SET_PSIZE(bp, x)	do { \
+	ASSERT(BP_IS_EMBEDDED(bp)); \
+	BF64_SET_SB((bp)->blk_prop, 25, 7, 0, 1, x); \
+_NOTE(CONSTCOND) } while (0)
+
+typedef enum bp_embedded_type {
+	BP_EMBEDDED_TYPE_DATA,
+	BP_EMBEDDED_TYPE_RESERVED, /* Reserved for an unintegrated feature. */
+	NUM_BP_EMBEDDED_TYPES = BP_EMBEDDED_TYPE_RESERVED
+} bp_embedded_type_t;
+
+#define	BPE_NUM_WORDS 14
+#define	BPE_PAYLOAD_SIZE (BPE_NUM_WORDS * sizeof (uint64_t))
+#define	BPE_IS_PAYLOADWORD(bp, wp) \
+	((wp) != &(bp)->blk_prop && (wp) != &(bp)->blk_birth)
+
+#define	SPA_BLKPTRSHIFT	7		/* blkptr_t is 128 bytes	*/
+#define	SPA_DVAS_PER_BP	3		/* Number of DVAs in a bp	*/
+
+/*
+ * A block is a hole when it has either 1) never been written to, or
+ * 2) is zero-filled. In both cases, ZFS can return all zeroes for all reads
+ * without physically allocating disk space. Holes are represented in the
+ * blkptr_t structure by zeroed blk_dva. Correct checking for holes is
+ * done through the BP_IS_HOLE macro. For holes, the logical size, level,
+ * DMU object type, and birth times are all also stored for holes that
+ * were written to at some point (i.e. were punched after having been filled).
+ */
+typedef struct blkptr {
+	dva_t		blk_dva[SPA_DVAS_PER_BP]; /* Data Virtual Addresses */
+	uint64_t	blk_prop;	/* size, compression, type, etc	    */
+	uint64_t	blk_pad[2];	/* Extra space for the future	    */
+	uint64_t	blk_phys_birth;	/* txg when block was allocated	    */
+	uint64_t	blk_birth;	/* transaction group at birth	    */
+	uint64_t	blk_fill;	/* fill count			    */
+	zio_cksum_t	blk_cksum;	/* 256-bit checksum		    */
+} blkptr_t;
+
+/*
+ * Macros to get and set fields in a bp or DVA.
+ */
+#define	DVA_GET_ASIZE(dva)	\
+	BF64_GET_SB((dva)->dva_word[0], 0, SPA_ASIZEBITS, SPA_MINBLOCKSHIFT, 0)
+#define	DVA_SET_ASIZE(dva, x)	\
+	BF64_SET_SB((dva)->dva_word[0], 0, SPA_ASIZEBITS, \
+	SPA_MINBLOCKSHIFT, 0, x)
+
+#define	DVA_GET_GRID(dva)	BF64_GET((dva)->dva_word[0], 24, 8)
+#define	DVA_SET_GRID(dva, x)	BF64_SET((dva)->dva_word[0], 24, 8, x)
+
+#define	DVA_GET_VDEV(dva)	BF64_GET((dva)->dva_word[0], 32, 32)
+#define	DVA_SET_VDEV(dva, x)	BF64_SET((dva)->dva_word[0], 32, 32, x)
+
+#define	DVA_GET_OFFSET(dva)	\
+	BF64_GET_SB((dva)->dva_word[1], 0, 63, SPA_MINBLOCKSHIFT, 0)
+#define	DVA_SET_OFFSET(dva, x)	\
+	BF64_SET_SB((dva)->dva_word[1], 0, 63, SPA_MINBLOCKSHIFT, 0, x)
+
+#define	DVA_GET_GANG(dva)	BF64_GET((dva)->dva_word[1], 63, 1)
+#define	DVA_SET_GANG(dva, x)	BF64_SET((dva)->dva_word[1], 63, 1, x)
+
+#define	BP_GET_LSIZE(bp)	\
+	(BP_IS_EMBEDDED(bp) ?	\
+	(BPE_GET_ETYPE(bp) == BP_EMBEDDED_TYPE_DATA ? BPE_GET_LSIZE(bp) : 0): \
+	BF64_GET_SB((bp)->blk_prop, 0, SPA_LSIZEBITS, SPA_MINBLOCKSHIFT, 1))
+#define	BP_SET_LSIZE(bp, x)	do { \
+	ASSERT(!BP_IS_EMBEDDED(bp)); \
+	BF64_SET_SB((bp)->blk_prop, \
+	    0, SPA_LSIZEBITS, SPA_MINBLOCKSHIFT, 1, x); \
+_NOTE(CONSTCOND) } while (0)
+
+#define	BP_GET_PSIZE(bp)	\
+	(BP_IS_EMBEDDED(bp) ? 0 : \
+	BF64_GET_SB((bp)->blk_prop, 16, SPA_PSIZEBITS, SPA_MINBLOCKSHIFT, 1))
+#define	BP_SET_PSIZE(bp, x)	do { \
+	ASSERT(!BP_IS_EMBEDDED(bp)); \
+	BF64_SET_SB((bp)->blk_prop, \
+	    16, SPA_PSIZEBITS, SPA_MINBLOCKSHIFT, 1, x); \
+_NOTE(CONSTCOND) } while (0)
+
+#define	BP_GET_COMPRESS(bp)		BF64_GET((bp)->blk_prop, 32, 7)
+#define	BP_SET_COMPRESS(bp, x)		BF64_SET((bp)->blk_prop, 32, 7, x)
+
+#define	BP_IS_EMBEDDED(bp)		BF64_GET((bp)->blk_prop, 39, 1)
+#define	BP_SET_EMBEDDED(bp, x)		BF64_SET((bp)->blk_prop, 39, 1, x)
+
+#define	BP_GET_CHECKSUM(bp)		\
+	(BP_IS_EMBEDDED(bp) ? ZIO_CHECKSUM_OFF : \
+	BF64_GET((bp)->blk_prop, 40, 8))
+#define	BP_SET_CHECKSUM(bp, x)		do { \
+	ASSERT(!BP_IS_EMBEDDED(bp)); \
+	BF64_SET((bp)->blk_prop, 40, 8, x); \
+_NOTE(CONSTCOND) } while (0)
+
+#define	BP_GET_TYPE(bp)			BF64_GET((bp)->blk_prop, 48, 8)
+#define	BP_SET_TYPE(bp, x)		BF64_SET((bp)->blk_prop, 48, 8, x)
+
+#define	BP_GET_LEVEL(bp)		BF64_GET((bp)->blk_prop, 56, 5)
+#define	BP_SET_LEVEL(bp, x)		BF64_SET((bp)->blk_prop, 56, 5, x)
+
+#define	BP_GET_DEDUP(bp)		BF64_GET((bp)->blk_prop, 62, 1)
+#define	BP_SET_DEDUP(bp, x)		BF64_SET((bp)->blk_prop, 62, 1, x)
+
+#define	BP_GET_BYTEORDER(bp)		BF64_GET((bp)->blk_prop, 63, 1)
+#define	BP_SET_BYTEORDER(bp, x)		BF64_SET((bp)->blk_prop, 63, 1, x)
+
+#define	BP_PHYSICAL_BIRTH(bp)		\
+	(BP_IS_EMBEDDED(bp) ? 0 : \
+	(bp)->blk_phys_birth ? (bp)->blk_phys_birth : (bp)->blk_birth)
+
+#define	BP_SET_BIRTH(bp, logical, physical)	\
+{						\
+	ASSERT(!BP_IS_EMBEDDED(bp));		\
+	(bp)->blk_birth = (logical);		\
+	(bp)->blk_phys_birth = ((logical) == (physical) ? 0 : (physical)); \
+}
+
+#define	BP_GET_FILL(bp) (BP_IS_EMBEDDED(bp) ? 1 : (bp)->blk_fill)
+
+#define	BP_GET_ASIZE(bp)	\
+	(BP_IS_EMBEDDED(bp) ? 0 : \
+	DVA_GET_ASIZE(&(bp)->blk_dva[0]) + \
+	DVA_GET_ASIZE(&(bp)->blk_dva[1]) + \
+	DVA_GET_ASIZE(&(bp)->blk_dva[2]))
+
+#define	BP_GET_UCSIZE(bp) \
+	((BP_GET_LEVEL(bp) > 0 || DMU_OT_IS_METADATA(BP_GET_TYPE(bp))) ? \
+	BP_GET_PSIZE(bp) : BP_GET_LSIZE(bp))
+
+#define	BP_GET_NDVAS(bp)	\
+	(BP_IS_EMBEDDED(bp) ? 0 : \
+	!!DVA_GET_ASIZE(&(bp)->blk_dva[0]) + \
+	!!DVA_GET_ASIZE(&(bp)->blk_dva[1]) + \
+	!!DVA_GET_ASIZE(&(bp)->blk_dva[2]))
+
+#define	BP_COUNT_GANG(bp)	\
+	(BP_IS_EMBEDDED(bp) ? 0 : \
+	(DVA_GET_GANG(&(bp)->blk_dva[0]) + \
+	DVA_GET_GANG(&(bp)->blk_dva[1]) + \
+	DVA_GET_GANG(&(bp)->blk_dva[2])))
+
+#define	DVA_EQUAL(dva1, dva2)	\
+	((dva1)->dva_word[1] == (dva2)->dva_word[1] && \
+	(dva1)->dva_word[0] == (dva2)->dva_word[0])
+
+#define	BP_EQUAL(bp1, bp2)	\
+	(BP_PHYSICAL_BIRTH(bp1) == BP_PHYSICAL_BIRTH(bp2) &&	\
+	(bp1)->blk_birth == (bp2)->blk_birth &&			\
+	DVA_EQUAL(&(bp1)->blk_dva[0], &(bp2)->blk_dva[0]) &&	\
+	DVA_EQUAL(&(bp1)->blk_dva[1], &(bp2)->blk_dva[1]) &&	\
+	DVA_EQUAL(&(bp1)->blk_dva[2], &(bp2)->blk_dva[2]))
+
+#define	ZIO_CHECKSUM_EQUAL(zc1, zc2) \
+	(0 == (((zc1).zc_word[0] - (zc2).zc_word[0]) | \
+	((zc1).zc_word[1] - (zc2).zc_word[1]) | \
+	((zc1).zc_word[2] - (zc2).zc_word[2]) | \
+	((zc1).zc_word[3] - (zc2).zc_word[3])))
+
+#define	DVA_IS_VALID(dva)	(DVA_GET_ASIZE(dva) != 0)
+
+#define	ZIO_SET_CHECKSUM(zcp, w0, w1, w2, w3)	\
+{						\
+	(zcp)->zc_word[0] = w0;			\
+	(zcp)->zc_word[1] = w1;			\
+	(zcp)->zc_word[2] = w2;			\
+	(zcp)->zc_word[3] = w3;			\
+}
+
+#define	BP_IDENTITY(bp)		(ASSERT(!BP_IS_EMBEDDED(bp)), &(bp)->blk_dva[0])
+#define	BP_IS_GANG(bp)		\
+	(BP_IS_EMBEDDED(bp) ? B_FALSE : DVA_GET_GANG(BP_IDENTITY(bp)))
+#define	DVA_IS_EMPTY(dva)	((dva)->dva_word[0] == 0ULL &&	\
+				(dva)->dva_word[1] == 0ULL)
+#define	BP_IS_HOLE(bp) \
+	(!BP_IS_EMBEDDED(bp) && DVA_IS_EMPTY(BP_IDENTITY(bp)))
+
+/* BP_IS_RAIDZ(bp) assumes no block compression */
+#define	BP_IS_RAIDZ(bp)		(DVA_GET_ASIZE(&(bp)->blk_dva[0]) > \
+				BP_GET_PSIZE(bp))
+
+#define	BP_ZERO(bp)				\
+{						\
+	(bp)->blk_dva[0].dva_word[0] = 0;	\
+	(bp)->blk_dva[0].dva_word[1] = 0;	\
+	(bp)->blk_dva[1].dva_word[0] = 0;	\
+	(bp)->blk_dva[1].dva_word[1] = 0;	\
+	(bp)->blk_dva[2].dva_word[0] = 0;	\
+	(bp)->blk_dva[2].dva_word[1] = 0;	\
+	(bp)->blk_prop = 0;			\
+	(bp)->blk_pad[0] = 0;			\
+	(bp)->blk_pad[1] = 0;			\
+	(bp)->blk_phys_birth = 0;		\
+	(bp)->blk_birth = 0;			\
+	(bp)->blk_fill = 0;			\
+	ZIO_SET_CHECKSUM(&(bp)->blk_cksum, 0, 0, 0, 0);	\
+}
+
+#ifdef _BIG_ENDIAN
+#define	ZFS_HOST_BYTEORDER	(0ULL)
+#else
+#define	ZFS_HOST_BYTEORDER	(1ULL)
+#endif
+
+#define	BP_SHOULD_BYTESWAP(bp)	(BP_GET_BYTEORDER(bp) != ZFS_HOST_BYTEORDER)
+
+#define	BP_SPRINTF_LEN	320
+
+/*
+ * This macro allows code sharing between zfs, libzpool, and mdb.
+ * 'func' is either snprintf() or mdb_snprintf().
+ * 'ws' (whitespace) can be ' ' for single-line format, '\n' for multi-line.
+ */
+#define	SNPRINTF_BLKPTR(func, ws, buf, size, bp, type, checksum, compress) \
+{									\
+	static const char *copyname[] =					\
+	    { "zero", "single", "double", "triple" };			\
+	int len = 0;							\
+	int copies = 0;							\
+	int d;								\
+									\
+	if (bp == NULL) {						\
+		len += func(buf + len, size - len, "<NULL>");		\
+	} else if (BP_IS_HOLE(bp)) {					\
+		len += func(buf + len, size - len,			\
+		    "HOLE [L%llu %s] "					\
+		    "size=%llxL birth=%lluL",				\
+		    (u_longlong_t)BP_GET_LEVEL(bp),			\
+		    type,						\
+		    (u_longlong_t)BP_GET_LSIZE(bp),			\
+		    (u_longlong_t)bp->blk_birth);			\
+	} else if (BP_IS_EMBEDDED(bp)) {				\
+		len = func(buf + len, size - len,			\
+		    "EMBEDDED [L%llu %s] et=%u %s "			\
+		    "size=%llxL/%llxP birth=%lluL",			\
+		    (u_longlong_t)BP_GET_LEVEL(bp),			\
+		    type,						\
+		    (int)BPE_GET_ETYPE(bp),				\
+		    compress,						\
+		    (u_longlong_t)BPE_GET_LSIZE(bp),			\
+		    (u_longlong_t)BPE_GET_PSIZE(bp),			\
+		    (u_longlong_t)bp->blk_birth);			\
+	} else {							\
+		for (d = 0; d < BP_GET_NDVAS(bp); d++) {		\
+			const dva_t *dva = &bp->blk_dva[d];		\
+			if (DVA_IS_VALID(dva))				\
+				copies++;				\
+			len += func(buf + len, size - len,		\
+			    "DVA[%d]=<%llu:%llx:%llx>%c", d,		\
+			    (u_longlong_t)DVA_GET_VDEV(dva),		\
+			    (u_longlong_t)DVA_GET_OFFSET(dva),		\
+			    (u_longlong_t)DVA_GET_ASIZE(dva),		\
+			    ws);					\
+		}							\
+		if (BP_IS_GANG(bp) &&					\
+		    DVA_GET_ASIZE(&bp->blk_dva[2]) <=			\
+		    DVA_GET_ASIZE(&bp->blk_dva[1]) / 2)			\
+			copies--;					\
+		len += func(buf + len, size - len,			\
+		    "[L%llu %s] %s %s %s %s %s %s%c"			\
+		    "size=%llxL/%llxP birth=%lluL/%lluP fill=%llu%c"	\
+		    "cksum=%llx:%llx:%llx:%llx",			\
+		    (u_longlong_t)BP_GET_LEVEL(bp),			\
+		    type,						\
+		    checksum,						\
+		    compress,						\
+		    BP_GET_BYTEORDER(bp) == 0 ? "BE" : "LE",		\
+		    BP_IS_GANG(bp) ? "gang" : "contiguous",		\
+		    BP_GET_DEDUP(bp) ? "dedup" : "unique",		\
+		    copyname[copies],					\
+		    ws,							\
+		    (u_longlong_t)BP_GET_LSIZE(bp),			\
+		    (u_longlong_t)BP_GET_PSIZE(bp),			\
+		    (u_longlong_t)bp->blk_birth,			\
+		    (u_longlong_t)BP_PHYSICAL_BIRTH(bp),		\
+		    (u_longlong_t)BP_GET_FILL(bp),			\
+		    ws,							\
+		    (u_longlong_t)bp->blk_cksum.zc_word[0],		\
+		    (u_longlong_t)bp->blk_cksum.zc_word[1],		\
+		    (u_longlong_t)bp->blk_cksum.zc_word[2],		\
+		    (u_longlong_t)bp->blk_cksum.zc_word[3]);		\
+	}								\
+	ASSERT(len < size);						\
+}
+
+#include <sys/dmu.h>
+
+#define	BP_GET_BUFC_TYPE(bp)						\
+	(((BP_GET_LEVEL(bp) > 0) || (DMU_OT_IS_METADATA(BP_GET_TYPE(bp)))) ? \
+	ARC_BUFC_METADATA : ARC_BUFC_DATA)
+
+typedef enum spa_import_type {
+	SPA_IMPORT_EXISTING,
+	SPA_IMPORT_ASSEMBLE
+} spa_import_type_t;
+
+/* state manipulation functions */
+extern int spa_open(const char *pool, spa_t **, void *tag);
+extern int spa_open_rewind(const char *pool, spa_t **, void *tag,
+    nvlist_t *policy, nvlist_t **config);
+extern int spa_get_stats(const char *pool, nvlist_t **config, char *altroot,
+    size_t buflen);
+extern int spa_create(const char *pool, nvlist_t *config, nvlist_t *props,
+    nvlist_t *zplprops);
+extern int spa_import_rootpool(char *devpath, char *devid);
+extern int spa_import(char *pool, nvlist_t *config, nvlist_t *props,
+    uint64_t flags);
+extern nvlist_t *spa_tryimport(nvlist_t *tryconfig);
+extern int spa_destroy(char *pool);
+extern int spa_export(char *pool, nvlist_t **oldconfig, boolean_t force,
+    boolean_t hardforce);
+extern int spa_reset(char *pool);
+extern void spa_async_request(spa_t *spa, int flag);
+extern void spa_async_unrequest(spa_t *spa, int flag);
+extern void spa_async_suspend(spa_t *spa);
+extern void spa_async_resume(spa_t *spa);
+extern spa_t *spa_inject_addref(char *pool);
+extern void spa_inject_delref(spa_t *spa);
+extern void spa_scan_stat_init(spa_t *spa);
+extern int spa_scan_get_stats(spa_t *spa, pool_scan_stat_t *ps);
+
+#define	SPA_ASYNC_CONFIG_UPDATE	0x01
+#define	SPA_ASYNC_REMOVE	0x02
+#define	SPA_ASYNC_PROBE		0x04
+#define	SPA_ASYNC_RESILVER_DONE	0x08
+#define	SPA_ASYNC_RESILVER	0x10
+#define	SPA_ASYNC_AUTOEXPAND	0x20
+#define	SPA_ASYNC_REMOVE_DONE	0x40
+#define	SPA_ASYNC_REMOVE_STOP	0x80
+
+/*
+ * Controls the behavior of spa_vdev_remove().
+ */
+#define	SPA_REMOVE_UNSPARE	0x01
+#define	SPA_REMOVE_DONE		0x02
+
+/* device manipulation */
+extern int spa_vdev_add(spa_t *spa, nvlist_t *nvroot);
+extern int spa_vdev_attach(spa_t *spa, uint64_t guid, nvlist_t *nvroot,
+    int replacing);
+extern int spa_vdev_detach(spa_t *spa, uint64_t guid, uint64_t pguid,
+    int replace_done);
+extern int spa_vdev_remove(spa_t *spa, uint64_t guid, boolean_t unspare);
+extern boolean_t spa_vdev_remove_active(spa_t *spa);
+extern int spa_vdev_setpath(spa_t *spa, uint64_t guid, const char *newpath);
+extern int spa_vdev_setfru(spa_t *spa, uint64_t guid, const char *newfru);
+extern int spa_vdev_split_mirror(spa_t *spa, char *newname, nvlist_t *config,
+    nvlist_t *props, boolean_t exp);
+
+/* spare state (which is global across all pools) */
+extern void spa_spare_add(vdev_t *vd);
+extern void spa_spare_remove(vdev_t *vd);
+extern boolean_t spa_spare_exists(uint64_t guid, uint64_t *pool, int *refcnt);
+extern void spa_spare_activate(vdev_t *vd);
+
+/* L2ARC state (which is global across all pools) */
+extern void spa_l2cache_add(vdev_t *vd);
+extern void spa_l2cache_remove(vdev_t *vd);
+extern boolean_t spa_l2cache_exists(uint64_t guid, uint64_t *pool);
+extern void spa_l2cache_activate(vdev_t *vd);
+extern void spa_l2cache_drop(spa_t *spa);
+
+/* scanning */
+extern int spa_scan(spa_t *spa, pool_scan_func_t func);
+extern int spa_scan_stop(spa_t *spa);
+
+/* spa syncing */
+extern void spa_sync(spa_t *spa, uint64_t txg); /* only for DMU use */
+extern void spa_sync_allpools(void);
+
+extern int zfs_sync_pass_deferred_free;
+
+/* spa namespace global mutex */
+extern kmutex_t spa_namespace_lock;
+
+/*
+ * SPA configuration functions in spa_config.c
+ */
+
+#define	SPA_CONFIG_UPDATE_POOL	0
+#define	SPA_CONFIG_UPDATE_VDEVS	1
+
+extern void spa_config_sync(spa_t *, boolean_t, boolean_t);
+extern void spa_config_load(void);
+extern nvlist_t *spa_all_configs(uint64_t *);
+extern void spa_config_set(spa_t *spa, nvlist_t *config);
+extern nvlist_t *spa_config_generate(spa_t *spa, vdev_t *vd, uint64_t txg,
+    int getstats);
+extern void spa_config_update(spa_t *spa, int what);
+
+/*
+ * Miscellaneous SPA routines in spa_misc.c
+ */
+
+/* Namespace manipulation */
+extern spa_t *spa_lookup(const char *name);
+extern spa_t *spa_add(const char *name, nvlist_t *config, const char *altroot);
+extern void spa_remove(spa_t *spa);
+extern spa_t *spa_next(spa_t *prev);
+
+/* Refcount functions */
+extern void spa_open_ref(spa_t *spa, void *tag);
+extern void spa_close(spa_t *spa, void *tag);
+extern void spa_async_close(spa_t *spa, void *tag);
+extern boolean_t spa_refcount_zero(spa_t *spa);
+
+#define	SCL_NONE	0x00
+#define	SCL_CONFIG	0x01
+#define	SCL_STATE	0x02
+#define	SCL_L2ARC	0x04		/* hack until L2ARC 2.0 */
+#define	SCL_ALLOC	0x08
+#define	SCL_ZIO		0x10
+#define	SCL_FREE	0x20
+#define	SCL_VDEV	0x40
+#define	SCL_LOCKS	7
+#define	SCL_ALL		((1 << SCL_LOCKS) - 1)
+#define	SCL_STATE_ALL	(SCL_STATE | SCL_L2ARC | SCL_ZIO)
+
+/* Historical pool statistics */
+typedef struct spa_stats_history {
+	kmutex_t		lock;
+	uint64_t		count;
+	uint64_t		size;
+	kstat_t			*kstat;
+	void			*private;
+	list_t			list;
+} spa_stats_history_t;
+
+typedef struct spa_stats {
+	spa_stats_history_t	read_history;
+	spa_stats_history_t	txg_history;
+	spa_stats_history_t	tx_assign_histogram;
+	spa_stats_history_t	io_history;
+} spa_stats_t;
+
+typedef enum txg_state {
+	TXG_STATE_BIRTH		= 0,
+	TXG_STATE_OPEN		= 1,
+	TXG_STATE_QUIESCED	= 2,
+	TXG_STATE_WAIT_FOR_SYNC	= 3,
+	TXG_STATE_SYNCED	= 4,
+	TXG_STATE_COMMITTED	= 5,
+} txg_state_t;
+
+extern void spa_stats_init(spa_t *spa);
+extern void spa_stats_destroy(spa_t *spa);
+extern void spa_read_history_add(spa_t *spa, const zbookmark_phys_t *zb,
+    uint32_t aflags);
+extern void spa_txg_history_add(spa_t *spa, uint64_t txg, hrtime_t birth_time);
+extern int spa_txg_history_set(spa_t *spa,  uint64_t txg,
+    txg_state_t completed_state, hrtime_t completed_time);
+extern int spa_txg_history_set_io(spa_t *spa,  uint64_t txg, uint64_t nread,
+    uint64_t nwritten, uint64_t reads, uint64_t writes, uint64_t ndirty);
+extern void spa_tx_assign_add_nsecs(spa_t *spa, uint64_t nsecs);
+
+/* Pool configuration locks */
+extern int spa_config_tryenter(spa_t *spa, int locks, void *tag, krw_t rw);
+extern void spa_config_enter(spa_t *spa, int locks, void *tag, krw_t rw);
+extern void spa_config_exit(spa_t *spa, int locks, void *tag);
+extern int spa_config_held(spa_t *spa, int locks, krw_t rw);
+
+/* Pool vdev add/remove lock */
+extern uint64_t spa_vdev_enter(spa_t *spa);
+extern uint64_t spa_vdev_config_enter(spa_t *spa);
+extern void spa_vdev_config_exit(spa_t *spa, vdev_t *vd, uint64_t txg,
+    int error, char *tag);
+extern int spa_vdev_exit(spa_t *spa, vdev_t *vd, uint64_t txg, int error);
+
+/* Pool vdev state change lock */
+extern void spa_vdev_state_enter(spa_t *spa, int oplock);
+extern int spa_vdev_state_exit(spa_t *spa, vdev_t *vd, int error);
+
+/* Log state */
+typedef enum spa_log_state {
+	SPA_LOG_UNKNOWN = 0,	/* unknown log state */
+	SPA_LOG_MISSING,	/* missing log(s) */
+	SPA_LOG_CLEAR,		/* clear the log(s) */
+	SPA_LOG_GOOD,		/* log(s) are good */
+} spa_log_state_t;
+
+extern spa_log_state_t spa_get_log_state(spa_t *spa);
+extern void spa_set_log_state(spa_t *spa, spa_log_state_t state);
+extern int spa_offline_log(spa_t *spa);
+
+/* Log claim callback */
+extern void spa_claim_notify(zio_t *zio);
+extern void spa_deadman(void *);
+
+/* Accessor functions */
+extern boolean_t spa_shutting_down(spa_t *spa);
+extern struct dsl_pool *spa_get_dsl(spa_t *spa);
+extern boolean_t spa_is_initializing(spa_t *spa);
+extern blkptr_t *spa_get_rootblkptr(spa_t *spa);
+extern void spa_set_rootblkptr(spa_t *spa, const blkptr_t *bp);
+extern void spa_altroot(spa_t *, char *, size_t);
+extern int spa_sync_pass(spa_t *spa);
+extern char *spa_name(spa_t *spa);
+extern uint64_t spa_guid(spa_t *spa);
+extern uint64_t spa_load_guid(spa_t *spa);
+extern uint64_t spa_last_synced_txg(spa_t *spa);
+extern uint64_t spa_first_txg(spa_t *spa);
+extern uint64_t spa_syncing_txg(spa_t *spa);
+extern uint64_t spa_version(spa_t *spa);
+extern pool_state_t spa_state(spa_t *spa);
+extern spa_load_state_t spa_load_state(spa_t *spa);
+extern uint64_t spa_freeze_txg(spa_t *spa);
+extern uint64_t spa_get_asize(spa_t *spa, uint64_t lsize);
+extern uint64_t spa_get_dspace(spa_t *spa);
+extern uint64_t spa_get_slop_space(spa_t *spa);
+extern void spa_update_dspace(spa_t *spa);
+extern uint64_t spa_version(spa_t *spa);
+extern boolean_t spa_deflate(spa_t *spa);
+extern metaslab_class_t *spa_normal_class(spa_t *spa);
+extern metaslab_class_t *spa_log_class(spa_t *spa);
+extern void spa_evicting_os_register(spa_t *, objset_t *os);
+extern void spa_evicting_os_deregister(spa_t *, objset_t *os);
+extern void spa_evicting_os_wait(spa_t *spa);
+extern int spa_max_replication(spa_t *spa);
+extern int spa_prev_software_version(spa_t *spa);
+extern uint8_t spa_get_failmode(spa_t *spa);
+extern boolean_t spa_suspended(spa_t *spa);
+extern uint64_t spa_bootfs(spa_t *spa);
+extern uint64_t spa_delegation(spa_t *spa);
+extern objset_t *spa_meta_objset(spa_t *spa);
+extern uint64_t spa_deadman_synctime(spa_t *spa);
+
+/* Miscellaneous support routines */
+extern void spa_activate_mos_feature(spa_t *spa, const char *feature,
+    dmu_tx_t *tx);
+extern void spa_deactivate_mos_feature(spa_t *spa, const char *feature);
+extern int spa_rename(const char *oldname, const char *newname);
+extern spa_t *spa_by_guid(uint64_t pool_guid, uint64_t device_guid);
+extern boolean_t spa_guid_exists(uint64_t pool_guid, uint64_t device_guid);
+extern char *spa_strdup(const char *);
+extern void spa_strfree(char *);
+extern uint64_t spa_get_random(uint64_t range);
+extern uint64_t spa_generate_guid(spa_t *spa);
+extern void snprintf_blkptr(char *buf, size_t buflen, const blkptr_t *bp);
+extern void spa_freeze(spa_t *spa);
+extern int spa_change_guid(spa_t *spa);
+extern void spa_upgrade(spa_t *spa, uint64_t version);
+extern void spa_evict_all(void);
+extern vdev_t *spa_lookup_by_guid(spa_t *spa, uint64_t guid,
+    boolean_t l2cache);
+extern boolean_t spa_has_spare(spa_t *, uint64_t guid);
+extern uint64_t dva_get_dsize_sync(spa_t *spa, const dva_t *dva);
+extern uint64_t bp_get_dsize_sync(spa_t *spa, const blkptr_t *bp);
+extern uint64_t bp_get_dsize(spa_t *spa, const blkptr_t *bp);
+extern boolean_t spa_has_slogs(spa_t *spa);
+extern boolean_t spa_is_root(spa_t *spa);
+extern boolean_t spa_writeable(spa_t *spa);
+extern boolean_t spa_has_pending_synctask(spa_t *spa);
+extern int spa_maxblocksize(spa_t *spa);
+extern void zfs_blkptr_verify(spa_t *spa, const blkptr_t *bp);
+
+extern int spa_mode(spa_t *spa);
+extern uint64_t strtonum(const char *str, char **nptr);
+
+extern char *spa_his_ievent_table[];
+
+extern void spa_history_create_obj(spa_t *spa, dmu_tx_t *tx);
+extern int spa_history_get(spa_t *spa, uint64_t *offset, uint64_t *len_read,
+    char *his_buf);
+extern int spa_history_log(spa_t *spa, const char *his_buf);
+extern int spa_history_log_nvl(spa_t *spa, nvlist_t *nvl);
+extern void spa_history_log_version(spa_t *spa, const char *operation);
+extern void spa_history_log_internal(spa_t *spa, const char *operation,
+    dmu_tx_t *tx, const char *fmt, ...);
+extern void spa_history_log_internal_ds(struct dsl_dataset *ds, const char *op,
+    dmu_tx_t *tx, const char *fmt, ...);
+extern void spa_history_log_internal_dd(dsl_dir_t *dd, const char *operation,
+    dmu_tx_t *tx, const char *fmt, ...);
+
+/* error handling */
+struct zbookmark_phys;
+extern void spa_log_error(spa_t *spa, zio_t *zio);
+extern void zfs_ereport_post(const char *class, spa_t *spa, vdev_t *vd,
+    zio_t *zio, uint64_t stateoroffset, uint64_t length);
+extern void zfs_post_remove(spa_t *spa, vdev_t *vd);
+extern void zfs_post_state_change(spa_t *spa, vdev_t *vd);
+extern void zfs_post_autoreplace(spa_t *spa, vdev_t *vd);
+extern uint64_t spa_get_errlog_size(spa_t *spa);
+extern int spa_get_errlog(spa_t *spa, void *uaddr, size_t *count);
+extern void spa_errlog_rotate(spa_t *spa);
+extern void spa_errlog_drain(spa_t *spa);
+extern void spa_errlog_sync(spa_t *spa, uint64_t txg);
+extern void spa_get_errlists(spa_t *spa, avl_tree_t *last, avl_tree_t *scrub);
+
+/* vdev cache */
+extern void vdev_cache_stat_init(void);
+extern void vdev_cache_stat_fini(void);
+
+/* Initialization and termination */
+extern void spa_init(int flags);
+extern void spa_fini(void);
+extern void spa_boot_init(void);
+
+/* properties */
+extern int spa_prop_set(spa_t *spa, nvlist_t *nvp);
+extern int spa_prop_get(spa_t *spa, nvlist_t **nvp);
+extern void spa_prop_clear_bootfs(spa_t *spa, uint64_t obj, dmu_tx_t *tx);
+extern void spa_configfile_set(spa_t *, nvlist_t *, boolean_t);
+
+/* asynchronous event notification */
+extern void spa_event_notify(spa_t *spa, vdev_t *vdev, const char *name);
+
+#ifdef ZFS_DEBUG
+#define	dprintf_bp(bp, fmt, ...) do {				\
+	if (zfs_flags & ZFS_DEBUG_DPRINTF) {			\
+	char *__blkbuf = kmem_alloc(BP_SPRINTF_LEN, KM_SLEEP);	\
+	snprintf_blkptr(__blkbuf, BP_SPRINTF_LEN, (bp));	\
+	dprintf(fmt " %s\n", __VA_ARGS__, __blkbuf);		\
+	kmem_free(__blkbuf, BP_SPRINTF_LEN);			\
+	} \
+_NOTE(CONSTCOND) } while (0)
+#else
+#define	dprintf_bp(bp, fmt, ...)
+#endif
+
+extern boolean_t spa_debug_enabled(spa_t *spa);
+#define	spa_dbgmsg(spa, ...)			\
+{						\
+	if (spa_debug_enabled(spa))		\
+		zfs_dbgmsg(__VA_ARGS__);	\
+}
+
+extern int spa_mode_global;			/* mode, e.g. FREAD | FWRITE */
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* _SYS_SPA_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/include/sys/spa_boot.h
@@ -0,0 +1,42 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _SYS_SPA_BOOT_H
+#define	_SYS_SPA_BOOT_H
+
+#include <sys/nvpair.h>
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+extern char *spa_get_bootprop(char *prop);
+extern void spa_free_bootprop(char *prop);
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* _SYS_SPA_BOOT_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/include/sys/spa_impl.h
@@ -0,0 +1,280 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2015 by Delphix. All rights reserved.
+ * Copyright 2011 Nexenta Systems, Inc.  All rights reserved.
+ * Copyright (c) 2014 Spectra Logic Corporation, All rights reserved.
+ * Copyright (c) 2016 Actifio, Inc. All rights reserved.
+ */
+
+#ifndef _SYS_SPA_IMPL_H
+#define	_SYS_SPA_IMPL_H
+
+#include <sys/spa.h>
+#include <sys/vdev.h>
+#include <sys/metaslab.h>
+#include <sys/dmu.h>
+#include <sys/dsl_pool.h>
+#include <sys/uberblock_impl.h>
+#include <sys/zfs_context.h>
+#include <sys/avl.h>
+#include <sys/refcount.h>
+#include <sys/bplist.h>
+#include <sys/bpobj.h>
+#include <sys/zfeature.h>
+#include <zfeature_common.h>
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+typedef struct spa_error_entry {
+	zbookmark_phys_t	se_bookmark;
+	char			*se_name;
+	avl_node_t		se_avl;
+} spa_error_entry_t;
+
+typedef struct spa_history_phys {
+	uint64_t sh_pool_create_len;	/* ending offset of zpool create */
+	uint64_t sh_phys_max_off;	/* physical EOF */
+	uint64_t sh_bof;		/* logical BOF */
+	uint64_t sh_eof;		/* logical EOF */
+	uint64_t sh_records_lost;	/* num of records overwritten */
+} spa_history_phys_t;
+
+struct spa_aux_vdev {
+	uint64_t	sav_object;		/* MOS object for device list */
+	nvlist_t	*sav_config;		/* cached device config */
+	vdev_t		**sav_vdevs;		/* devices */
+	int		sav_count;		/* number devices */
+	boolean_t	sav_sync;		/* sync the device list */
+	nvlist_t	**sav_pending;		/* pending device additions */
+	uint_t		sav_npending;		/* # pending devices */
+};
+
+typedef struct spa_config_lock {
+	kmutex_t	scl_lock;
+	kthread_t	*scl_writer;
+	int		scl_write_wanted;
+	kcondvar_t	scl_cv;
+	refcount_t	scl_count;
+} spa_config_lock_t;
+
+typedef struct spa_config_dirent {
+	list_node_t	scd_link;
+	char		*scd_path;
+} spa_config_dirent_t;
+
+typedef enum zio_taskq_type {
+	ZIO_TASKQ_ISSUE = 0,
+	ZIO_TASKQ_ISSUE_HIGH,
+	ZIO_TASKQ_INTERRUPT,
+	ZIO_TASKQ_INTERRUPT_HIGH,
+	ZIO_TASKQ_TYPES
+} zio_taskq_type_t;
+
+/*
+ * State machine for the zpool-poolname process.  The states transitions
+ * are done as follows:
+ *
+ *	From		   To			Routine
+ *	PROC_NONE	-> PROC_CREATED		spa_activate()
+ *	PROC_CREATED	-> PROC_ACTIVE		spa_thread()
+ *	PROC_ACTIVE	-> PROC_DEACTIVATE	spa_deactivate()
+ *	PROC_DEACTIVATE	-> PROC_GONE		spa_thread()
+ *	PROC_GONE	-> PROC_NONE		spa_deactivate()
+ */
+typedef enum spa_proc_state {
+	SPA_PROC_NONE,		/* spa_proc = &p0, no process created */
+	SPA_PROC_CREATED,	/* spa_activate() has proc, is waiting */
+	SPA_PROC_ACTIVE,	/* taskqs created, spa_proc set */
+	SPA_PROC_DEACTIVATE,	/* spa_deactivate() requests process exit */
+	SPA_PROC_GONE		/* spa_thread() is exiting, spa_proc = &p0 */
+} spa_proc_state_t;
+
+typedef struct spa_taskqs {
+	uint_t stqs_count;
+	taskq_t **stqs_taskq;
+} spa_taskqs_t;
+
+struct spa {
+	/*
+	 * Fields protected by spa_namespace_lock.
+	 */
+	char		spa_name[MAXNAMELEN];	/* pool name */
+	char		*spa_comment;		/* comment */
+	avl_node_t	spa_avl;		/* node in spa_namespace_avl */
+	nvlist_t	*spa_config;		/* last synced config */
+	nvlist_t	*spa_config_syncing;	/* currently syncing config */
+	nvlist_t	*spa_config_splitting;	/* config for splitting */
+	nvlist_t	*spa_load_info;		/* info and errors from load */
+	uint64_t	spa_config_txg;		/* txg of last config change */
+	int		spa_sync_pass;		/* iterate-to-convergence */
+	pool_state_t	spa_state;		/* pool state */
+	int		spa_inject_ref;		/* injection references */
+	uint8_t		spa_sync_on;		/* sync threads are running */
+	spa_load_state_t spa_load_state;	/* current load operation */
+	uint64_t	spa_import_flags;	/* import specific flags */
+	spa_taskqs_t	spa_zio_taskq[ZIO_TYPES][ZIO_TASKQ_TYPES];
+	dsl_pool_t	*spa_dsl_pool;
+	boolean_t	spa_is_initializing;	/* true while opening pool */
+	metaslab_class_t *spa_normal_class;	/* normal data class */
+	metaslab_class_t *spa_log_class;	/* intent log data class */
+	uint64_t	spa_first_txg;		/* first txg after spa_open() */
+	uint64_t	spa_final_txg;		/* txg of export/destroy */
+	uint64_t	spa_freeze_txg;		/* freeze pool at this txg */
+	uint64_t	spa_load_max_txg;	/* best initial ub_txg */
+	uint64_t	spa_claim_max_txg;	/* highest claimed birth txg */
+	timespec_t	spa_loaded_ts;		/* 1st successful open time */
+	objset_t	*spa_meta_objset;	/* copy of dp->dp_meta_objset */
+	kmutex_t	spa_evicting_os_lock;	/* Evicting objset list lock */
+	list_t		spa_evicting_os_list;	/* Objsets being evicted. */
+	kcondvar_t	spa_evicting_os_cv;	/* Objset Eviction Completion */
+	txg_list_t	spa_vdev_txg_list;	/* per-txg dirty vdev list */
+	vdev_t		*spa_root_vdev;		/* top-level vdev container */
+	int		spa_min_ashift;		/* of vdevs in normal class */
+	int		spa_max_ashift;		/* of vdevs in normal class */
+	uint64_t	spa_config_guid;	/* config pool guid */
+	uint64_t	spa_load_guid;		/* spa_load initialized guid */
+	uint64_t	spa_last_synced_guid;	/* last synced guid */
+	list_t		spa_config_dirty_list;	/* vdevs with dirty config */
+	list_t		spa_state_dirty_list;	/* vdevs with dirty state */
+	spa_aux_vdev_t	spa_spares;		/* hot spares */
+	spa_aux_vdev_t	spa_l2cache;		/* L2ARC cache devices */
+	nvlist_t	*spa_label_features;	/* Features for reading MOS */
+	uint64_t	spa_config_object;	/* MOS object for pool config */
+	uint64_t	spa_config_generation;	/* config generation number */
+	uint64_t	spa_syncing_txg;	/* txg currently syncing */
+	bpobj_t		spa_deferred_bpobj;	/* deferred-free bplist */
+	bplist_t	spa_free_bplist[TXG_SIZE]; /* bplist of stuff to free */
+	uberblock_t	spa_ubsync;		/* last synced uberblock */
+	uberblock_t	spa_uberblock;		/* current uberblock */
+	boolean_t	spa_extreme_rewind;	/* rewind past deferred frees */
+	uint64_t	spa_last_io;		/* lbolt of last non-scan I/O */
+	kmutex_t	spa_scrub_lock;		/* resilver/scrub lock */
+	uint64_t	spa_scrub_inflight;	/* in-flight scrub I/Os */
+	kcondvar_t	spa_scrub_io_cv;	/* scrub I/O completion */
+	uint8_t		spa_scrub_active;	/* active or suspended? */
+	uint8_t		spa_scrub_type;		/* type of scrub we're doing */
+	uint8_t		spa_scrub_finished;	/* indicator to rotate logs */
+	uint8_t		spa_scrub_started;	/* started since last boot */
+	uint8_t		spa_scrub_reopen;	/* scrub doing vdev_reopen */
+	uint64_t	spa_scan_pass_start;	/* start time per pass/reboot */
+	uint64_t	spa_scan_pass_exam;	/* examined bytes per pass */
+	kmutex_t	spa_async_lock;		/* protect async state */
+	kthread_t	*spa_async_thread;	/* thread doing async task */
+	int		spa_async_suspended;	/* async tasks suspended */
+	kcondvar_t	spa_async_cv;		/* wait for thread_exit() */
+	uint16_t	spa_async_tasks;	/* async task mask */
+	char		*spa_root;		/* alternate root directory */
+	uint64_t	spa_ena;		/* spa-wide ereport ENA */
+	int		spa_last_open_failed;	/* error if last open failed */
+	uint64_t	spa_last_ubsync_txg;	/* "best" uberblock txg */
+	uint64_t	spa_last_ubsync_txg_ts;	/* timestamp from that ub */
+	uint64_t	spa_load_txg;		/* ub txg that loaded */
+	uint64_t	spa_load_txg_ts;	/* timestamp from that ub */
+	uint64_t	spa_load_meta_errors;	/* verify metadata err count */
+	uint64_t	spa_load_data_errors;	/* verify data err count */
+	uint64_t	spa_verify_min_txg;	/* start txg of verify scrub */
+	kmutex_t	spa_errlog_lock;	/* error log lock */
+	uint64_t	spa_errlog_last;	/* last error log object */
+	uint64_t	spa_errlog_scrub;	/* scrub error log object */
+	kmutex_t	spa_errlist_lock;	/* error list/ereport lock */
+	avl_tree_t	spa_errlist_last;	/* last error list */
+	avl_tree_t	spa_errlist_scrub;	/* scrub error list */
+	uint64_t	spa_deflate;		/* should we deflate? */
+	uint64_t	spa_history;		/* history object */
+	kmutex_t	spa_history_lock;	/* history lock */
+	vdev_t		*spa_pending_vdev;	/* pending vdev additions */
+	kmutex_t	spa_props_lock;		/* property lock */
+	uint64_t	spa_pool_props_object;	/* object for properties */
+	uint64_t	spa_bootfs;		/* default boot filesystem */
+	uint64_t	spa_failmode;		/* failure mode for the pool */
+	uint64_t	spa_delegation;		/* delegation on/off */
+	list_t		spa_config_list;	/* previous cache file(s) */
+	/* per-CPU array of root of async I/O: */
+	zio_t		**spa_async_zio_root;
+	zio_t		*spa_suspend_zio_root;	/* root of all suspended I/O */
+	kmutex_t	spa_suspend_lock;	/* protects suspend_zio_root */
+	kcondvar_t	spa_suspend_cv;		/* notification of resume */
+	uint8_t		spa_suspended;		/* pool is suspended */
+	uint8_t		spa_claiming;		/* pool is doing zil_claim() */
+	boolean_t	spa_debug;		/* debug enabled? */
+	boolean_t	spa_is_root;		/* pool is root */
+	int		spa_minref;		/* num refs when first opened */
+	int		spa_mode;		/* FREAD | FWRITE */
+	spa_log_state_t spa_log_state;		/* log state */
+	uint64_t	spa_autoexpand;		/* lun expansion on/off */
+	ddt_t		*spa_ddt[ZIO_CHECKSUM_FUNCTIONS]; /* in-core DDTs */
+	uint64_t	spa_ddt_stat_object;	/* DDT statistics */
+	uint64_t	spa_dedup_ditto;	/* dedup ditto threshold */
+	uint64_t	spa_dedup_checksum;	/* default dedup checksum */
+	uint64_t	spa_dspace;		/* dspace in normal class */
+	kmutex_t	spa_vdev_top_lock;	/* dueling offline/remove */
+	kmutex_t	spa_proc_lock;		/* protects spa_proc* */
+	kcondvar_t	spa_proc_cv;		/* spa_proc_state transitions */
+	spa_proc_state_t spa_proc_state;	/* see definition */
+	proc_t		*spa_proc;		/* "zpool-poolname" process */
+	uint64_t	spa_did;		/* if procp != p0, did of t1 */
+	boolean_t	spa_autoreplace;	/* autoreplace set in open */
+	int		spa_vdev_locks;		/* locks grabbed */
+	uint64_t	spa_creation_version;	/* version at pool creation */
+	uint64_t	spa_prev_software_version; /* See ub_software_version */
+	uint64_t	spa_feat_for_write_obj;	/* required to write to pool */
+	uint64_t	spa_feat_for_read_obj;	/* required to read from pool */
+	uint64_t	spa_feat_desc_obj;	/* Feature descriptions */
+	uint64_t	spa_feat_enabled_txg_obj; /* Feature enabled txg */
+	kmutex_t	spa_feat_stats_lock;	/* protects spa_feat_stats */
+	nvlist_t	*spa_feat_stats;	/* Cache of enabled features */
+	/* cache feature refcounts */
+	uint64_t	spa_feat_refcount_cache[SPA_FEATURES];
+	taskqid_t	spa_deadman_tqid;	/* Task id */
+	uint64_t	spa_deadman_calls;	/* number of deadman calls */
+	hrtime_t	spa_sync_starttime;	/* starting time of spa_sync */
+	uint64_t	spa_deadman_synctime;	/* deadman expiration timer */
+	uint64_t	spa_errata;		/* errata issues detected */
+	spa_stats_t	spa_stats;		/* assorted spa statistics */
+	taskq_t		*spa_zvol_taskq;	/* Taskq for minor managment */
+
+	/*
+	 * spa_refcount & spa_config_lock must be the last elements
+	 * because refcount_t changes size based on compilation options.
+	 * In order for the MDB module to function correctly, the other
+	 * fields must remain in the same location.
+	 */
+	spa_config_lock_t spa_config_lock[SCL_LOCKS]; /* config changes */
+	refcount_t	spa_refcount;		/* number of opens */
+};
+
+extern char *spa_config_path;
+
+extern void spa_taskq_dispatch_ent(spa_t *spa, zio_type_t t, zio_taskq_type_t q,
+    task_func_t *func, void *arg, uint_t flags, taskq_ent_t *ent);
+extern void spa_taskq_dispatch_sync(spa_t *, zio_type_t t, zio_taskq_type_t q,
+    task_func_t *func, void *arg, uint_t flags);
+
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* _SYS_SPA_IMPL_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/include/sys/space_map.h
@@ -0,0 +1,164 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/*
+ * Copyright (c) 2012, 2014 by Delphix. All rights reserved.
+ */
+
+#ifndef _SYS_SPACE_MAP_H
+#define	_SYS_SPACE_MAP_H
+
+#include <sys/avl.h>
+#include <sys/range_tree.h>
+#include <sys/dmu.h>
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+/*
+ * The size of the space map object has increased to include a histogram.
+ * The SPACE_MAP_SIZE_V0 designates the original size and is used to
+ * maintain backward compatibility.
+ */
+#define	SPACE_MAP_SIZE_V0	(3 * sizeof (uint64_t))
+#define	SPACE_MAP_HISTOGRAM_SIZE	32
+
+/*
+ * The space_map_phys is the on-disk representation of the space map.
+ * Consumers of space maps should never reference any of the members of this
+ * structure directly. These members may only be updated in syncing context.
+ *
+ * Note the smp_object is no longer used but remains in the structure
+ * for backward compatibility.
+ */
+typedef struct space_map_phys {
+	uint64_t	smp_object;	/* on-disk space map object */
+	uint64_t	smp_objsize;	/* size of the object */
+	uint64_t	smp_alloc;	/* space allocated from the map */
+	uint64_t	smp_pad[5];	/* reserved */
+
+	/*
+	 * The smp_histogram maintains a histogram of free regions. Each
+	 * bucket, smp_histogram[i], contains the number of free regions
+	 * whose size is:
+	 * 2^(i+sm_shift) <= size of free region in bytes < 2^(i+sm_shift+1)
+	 */
+	uint64_t	smp_histogram[SPACE_MAP_HISTOGRAM_SIZE];
+} space_map_phys_t;
+
+/*
+ * The space map object defines a region of space, its size, how much is
+ * allocated, and the on-disk object that stores this information.
+ * Consumers of space maps may only access the members of this structure.
+ */
+typedef struct space_map {
+	uint64_t	sm_start;	/* start of map */
+	uint64_t	sm_size;	/* size of map */
+	uint8_t		sm_shift;	/* unit shift */
+	uint64_t	sm_length;	/* synced length */
+	uint64_t	sm_alloc;	/* synced space allocated */
+	objset_t	*sm_os;		/* objset for this map */
+	uint64_t	sm_object;	/* object id for this map */
+	uint32_t	sm_blksz;	/* block size for space map */
+	dmu_buf_t	*sm_dbuf;	/* space_map_phys_t dbuf */
+	space_map_phys_t *sm_phys;	/* on-disk space map */
+	kmutex_t	*sm_lock;	/* pointer to lock that protects map */
+} space_map_t;
+
+/*
+ * debug entry
+ *
+ *    1      3         10                     50
+ *  ,---+--------+------------+---------------------------------.
+ *  | 1 | action |  syncpass  |        txg (lower bits)         |
+ *  `---+--------+------------+---------------------------------'
+ *   63  62    60 59        50 49                               0
+ *
+ *
+ * non-debug entry
+ *
+ *    1               47                   1           15
+ *  ,-----------------------------------------------------------.
+ *  | 0 |   offset (sm_shift units)    | type |       run       |
+ *  `-----------------------------------------------------------'
+ *   63  62                          17   16   15               0
+ */
+
+/* All this stuff takes and returns bytes */
+#define	SM_RUN_DECODE(x)	(BF64_DECODE(x, 0, 15) + 1)
+#define	SM_RUN_ENCODE(x)	BF64_ENCODE((x) - 1, 0, 15)
+#define	SM_TYPE_DECODE(x)	BF64_DECODE(x, 15, 1)
+#define	SM_TYPE_ENCODE(x)	BF64_ENCODE(x, 15, 1)
+#define	SM_OFFSET_DECODE(x)	BF64_DECODE(x, 16, 47)
+#define	SM_OFFSET_ENCODE(x)	BF64_ENCODE(x, 16, 47)
+#define	SM_DEBUG_DECODE(x)	BF64_DECODE(x, 63, 1)
+#define	SM_DEBUG_ENCODE(x)	BF64_ENCODE(x, 63, 1)
+
+#define	SM_DEBUG_ACTION_DECODE(x)	BF64_DECODE(x, 60, 3)
+#define	SM_DEBUG_ACTION_ENCODE(x)	BF64_ENCODE(x, 60, 3)
+
+#define	SM_DEBUG_SYNCPASS_DECODE(x)	BF64_DECODE(x, 50, 10)
+#define	SM_DEBUG_SYNCPASS_ENCODE(x)	BF64_ENCODE(x, 50, 10)
+
+#define	SM_DEBUG_TXG_DECODE(x)		BF64_DECODE(x, 0, 50)
+#define	SM_DEBUG_TXG_ENCODE(x)		BF64_ENCODE(x, 0, 50)
+
+#define	SM_RUN_MAX			SM_RUN_DECODE(~0ULL)
+
+typedef enum {
+	SM_ALLOC,
+	SM_FREE
+} maptype_t;
+
+int space_map_load(space_map_t *sm, range_tree_t *rt, maptype_t maptype);
+
+void space_map_histogram_clear(space_map_t *sm);
+void space_map_histogram_add(space_map_t *sm, range_tree_t *rt,
+    dmu_tx_t *tx);
+
+void space_map_update(space_map_t *sm);
+
+uint64_t space_map_object(space_map_t *sm);
+uint64_t space_map_allocated(space_map_t *sm);
+uint64_t space_map_length(space_map_t *sm);
+
+void space_map_write(space_map_t *sm, range_tree_t *rt, maptype_t maptype,
+    dmu_tx_t *tx);
+void space_map_truncate(space_map_t *sm, dmu_tx_t *tx);
+uint64_t space_map_alloc(objset_t *os, dmu_tx_t *tx);
+void space_map_free(space_map_t *sm, dmu_tx_t *tx);
+
+int space_map_open(space_map_t **smp, objset_t *os, uint64_t object,
+    uint64_t start, uint64_t size, uint8_t shift, kmutex_t *lp);
+void space_map_close(space_map_t *sm);
+
+int64_t space_map_alloc_delta(space_map_t *sm);
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* _SYS_SPACE_MAP_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/include/sys/space_reftree.h
@@ -0,0 +1,57 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/*
+ * Copyright (c) 2013 by Delphix. All rights reserved.
+ */
+
+#ifndef _SYS_SPACE_REFTREE_H
+#define	_SYS_SPACE_REFTREE_H
+
+#include <sys/range_tree.h>
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+typedef struct space_ref {
+	avl_node_t	sr_node;	/* AVL node */
+	uint64_t	sr_offset;	/* range offset (start or end) */
+	int64_t		sr_refcnt;	/* associated reference count */
+} space_ref_t;
+
+void space_reftree_create(avl_tree_t *t);
+void space_reftree_destroy(avl_tree_t *t);
+void space_reftree_add_seg(avl_tree_t *t, uint64_t start, uint64_t end,
+    int64_t refcnt);
+void space_reftree_add_map(avl_tree_t *t, range_tree_t *rt, int64_t refcnt);
+void space_reftree_generate_map(avl_tree_t *t, range_tree_t *rt,
+    int64_t minref);
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* _SYS_SPACE_REFTREE_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/include/sys/trace.h
@@ -0,0 +1,68 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+#if defined(_KERNEL) && defined(HAVE_DECLARE_EVENT_CLASS)
+
+#undef TRACE_SYSTEM
+#define	TRACE_SYSTEM zfs
+
+#if !defined(_TRACE_ZFS_H) || defined(TRACE_HEADER_MULTI_READ)
+#define	_TRACE_ZFS_H
+
+#include <linux/tracepoint.h>
+#include <sys/types.h>
+
+/*
+ * The sys/trace_dbgmsg.h header defines tracepoint events for
+ * dprintf(), dbgmsg(), and SET_ERROR().
+ */
+#define	_SYS_TRACE_DBGMSG_INDIRECT
+#include <sys/trace_dbgmsg.h>
+#undef _SYS_TRACE_DBGMSG_INDIRECT
+
+/*
+ * Redefine the DTRACE_PROBE* functions to use Linux tracepoints
+ */
+#undef DTRACE_PROBE1
+#define	DTRACE_PROBE1(name, t1, arg1) \
+	trace_zfs_##name((arg1))
+
+#undef DTRACE_PROBE2
+#define	DTRACE_PROBE2(name, t1, arg1, t2, arg2) \
+	trace_zfs_##name((arg1), (arg2))
+
+#undef DTRACE_PROBE3
+#define	DTRACE_PROBE3(name, t1, arg1, t2, arg2, t3, arg3) \
+	trace_zfs_##name((arg1), (arg2), (arg3))
+
+#undef DTRACE_PROBE4
+#define	DTRACE_PROBE4(name, t1, arg1, t2, arg2, t3, arg3, t4, arg4) \
+	trace_zfs_##name((arg1), (arg2), (arg3), (arg4))
+
+#endif /* _TRACE_ZFS_H */
+
+#undef TRACE_INCLUDE_PATH
+#undef TRACE_INCLUDE_FILE
+#define	TRACE_INCLUDE_PATH sys
+#define	TRACE_INCLUDE_FILE trace
+#include <trace/define_trace.h>
+
+#endif /* _KERNEL && HAVE_DECLARE_EVENT_CLASS */
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/include/sys/trace_acl.h
@@ -0,0 +1,165 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+#if defined(_KERNEL) && defined(HAVE_DECLARE_EVENT_CLASS)
+
+#undef TRACE_SYSTEM
+#define	TRACE_SYSTEM zfs
+
+#undef TRACE_SYSTEM_VAR
+#define	TRACE_SYSTEM_VAR zfs_acl
+
+#if !defined(_TRACE_ACL_H) || defined(TRACE_HEADER_MULTI_READ)
+#define	_TRACE_ACL_H
+
+#include <linux/tracepoint.h>
+#include <sys/types.h>
+
+/*
+ * Generic support for three argument tracepoints of the form:
+ *
+ * DTRACE_PROBE3(...,
+ *     znode_t *, ...,
+ *     zfs_ace_hdr_t *, ...,
+ *     uint32_t, ...);
+ */
+
+DECLARE_EVENT_CLASS(zfs_ace_class,
+	TP_PROTO(znode_t *zn, zfs_ace_hdr_t *ace, uint32_t mask_matched),
+	TP_ARGS(zn, ace, mask_matched),
+	TP_STRUCT__entry(
+	    __field(uint64_t,		z_id)
+	    __field(uint8_t,		z_unlinked)
+	    __field(uint8_t,		z_atime_dirty)
+	    __field(uint8_t,		z_zn_prefetch)
+	    __field(uint8_t,		z_moved)
+	    __field(uint_t,		z_blksz)
+	    __field(uint_t,		z_seq)
+	    __field(uint64_t,		z_mapcnt)
+	    __field(uint64_t,		z_gen)
+	    __field(uint64_t,		z_size)
+	    __array(uint64_t,		z_atime, 2)
+	    __field(uint64_t,		z_links)
+	    __field(uint64_t,		z_pflags)
+	    __field(uint64_t,		z_uid)
+	    __field(uint64_t,		z_gid)
+	    __field(uint32_t,		z_sync_cnt)
+	    __field(mode_t,		z_mode)
+	    __field(boolean_t,		z_is_sa)
+	    __field(boolean_t,		z_is_zvol)
+	    __field(boolean_t,		z_is_mapped)
+	    __field(boolean_t,		z_is_ctldir)
+	    __field(boolean_t,		z_is_stale)
+
+	    __field(unsigned long,	i_ino)
+	    __field(unsigned int,	i_nlink)
+	    __field(u64,		i_version)
+	    __field(loff_t,		i_size)
+	    __field(unsigned int,	i_blkbits)
+	    __field(unsigned short,	i_bytes)
+	    __field(umode_t,		i_mode)
+	    __field(__u32,		i_generation)
+
+	    __field(uint16_t,		z_type)
+	    __field(uint16_t,		z_flags)
+	    __field(uint32_t,		z_access_mask)
+
+	    __field(uint32_t,		mask_matched)
+	),
+	TP_fast_assign(
+	    __entry->z_id		= zn->z_id;
+	    __entry->z_unlinked		= zn->z_unlinked;
+	    __entry->z_atime_dirty	= zn->z_atime_dirty;
+	    __entry->z_zn_prefetch	= zn->z_zn_prefetch;
+	    __entry->z_moved		= zn->z_moved;
+	    __entry->z_blksz		= zn->z_blksz;
+	    __entry->z_seq		= zn->z_seq;
+	    __entry->z_mapcnt		= zn->z_mapcnt;
+	    __entry->z_gen		= zn->z_gen;
+	    __entry->z_size		= zn->z_size;
+	    __entry->z_atime[0]		= zn->z_atime[0];
+	    __entry->z_atime[1]		= zn->z_atime[1];
+	    __entry->z_links		= zn->z_links;
+	    __entry->z_pflags		= zn->z_pflags;
+	    __entry->z_uid		= zn->z_uid;
+	    __entry->z_gid		= zn->z_gid;
+	    __entry->z_sync_cnt		= zn->z_sync_cnt;
+	    __entry->z_mode		= zn->z_mode;
+	    __entry->z_is_sa		= zn->z_is_sa;
+	    __entry->z_is_zvol		= zn->z_is_zvol;
+	    __entry->z_is_mapped	= zn->z_is_mapped;
+	    __entry->z_is_ctldir	= zn->z_is_ctldir;
+	    __entry->z_is_stale		= zn->z_is_stale;
+
+	    __entry->i_ino		= zn->z_inode.i_ino;
+	    __entry->i_nlink		= zn->z_inode.i_nlink;
+	    __entry->i_version		= zn->z_inode.i_version;
+	    __entry->i_size		= zn->z_inode.i_size;
+	    __entry->i_blkbits		= zn->z_inode.i_blkbits;
+	    __entry->i_bytes		= zn->z_inode.i_bytes;
+	    __entry->i_mode		= zn->z_inode.i_mode;
+	    __entry->i_generation	= zn->z_inode.i_generation;
+
+	    __entry->z_type		= ace->z_type;
+	    __entry->z_flags		= ace->z_flags;
+	    __entry->z_access_mask	= ace->z_access_mask;
+
+	    __entry->mask_matched	= mask_matched;
+	),
+	TP_printk("zn { id %llu unlinked %u atime_dirty %u "
+	    "zn_prefetch %u moved %u blksz %u seq %u "
+	    "mapcnt %llu gen %llu size %llu atime 0x%llx:0x%llx "
+	    "links %llu pflags %llu uid %llu gid %llu "
+	    "sync_cnt %u mode 0x%x is_sa %d is_zvol %d "
+	    "is_mapped %d is_ctldir %d is_stale %d inode { "
+	    "ino %lu nlink %u version %llu size %lli blkbits %u "
+	    "bytes %u mode 0x%x generation %x } } ace { type %u "
+	    "flags %u access_mask %u } mask_matched %u",
+	    __entry->z_id, __entry->z_unlinked, __entry->z_atime_dirty,
+	    __entry->z_zn_prefetch, __entry->z_moved, __entry->z_blksz,
+	    __entry->z_seq, __entry->z_mapcnt, __entry->z_gen,
+	    __entry->z_size, __entry->z_atime[0], __entry->z_atime[1],
+	    __entry->z_links, __entry->z_pflags, __entry->z_uid,
+	    __entry->z_gid, __entry->z_sync_cnt, __entry->z_mode,
+	    __entry->z_is_sa, __entry->z_is_zvol, __entry->z_is_mapped,
+	    __entry->z_is_ctldir, __entry->z_is_stale, __entry->i_ino,
+	    __entry->i_nlink, __entry->i_version, __entry->i_size,
+	    __entry->i_blkbits, __entry->i_bytes, __entry->i_mode,
+	    __entry->i_generation, __entry->z_type, __entry->z_flags,
+	    __entry->z_access_mask, __entry->mask_matched)
+);
+
+#define	DEFINE_ACE_EVENT(name) \
+DEFINE_EVENT(zfs_ace_class, name, \
+	TP_PROTO(znode_t *zn, zfs_ace_hdr_t *ace, uint32_t mask_matched), \
+	TP_ARGS(zn, ace, mask_matched))
+DEFINE_ACE_EVENT(zfs_zfs__ace__denies);
+DEFINE_ACE_EVENT(zfs_zfs__ace__allows);
+
+#endif /* _TRACE_ACL_H */
+
+#undef TRACE_INCLUDE_PATH
+#undef TRACE_INCLUDE_FILE
+#define	TRACE_INCLUDE_PATH sys
+#define	TRACE_INCLUDE_FILE trace_acl
+#include <trace/define_trace.h>
+
+#endif /* _KERNEL && HAVE_DECLARE_EVENT_CLASS */
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/include/sys/trace_arc.h
@@ -0,0 +1,422 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+#include <sys/list.h>
+
+#if defined(_KERNEL) && defined(HAVE_DECLARE_EVENT_CLASS)
+
+#undef TRACE_SYSTEM
+#define	TRACE_SYSTEM zfs
+
+#undef TRACE_SYSTEM_VAR
+#define	TRACE_SYSTEM_VAR zfs_arc
+
+#if !defined(_TRACE_ARC_H) || defined(TRACE_HEADER_MULTI_READ)
+#define	_TRACE_ARC_H
+
+#include <linux/tracepoint.h>
+#include <sys/types.h>
+
+/*
+ * Generic support for one argument tracepoints of the form:
+ *
+ * DTRACE_PROBE1(...,
+ *     arc_buf_hdr_t *, ...);
+ */
+
+DECLARE_EVENT_CLASS(zfs_arc_buf_hdr_class,
+	TP_PROTO(arc_buf_hdr_t *ab),
+	TP_ARGS(ab),
+	TP_STRUCT__entry(
+	    __array(uint64_t,		hdr_dva_word, 2)
+	    __field(uint64_t,		hdr_birth)
+	    __field(uint32_t,		hdr_flags)
+	    __field(uint32_t,		hdr_datacnt)
+	    __field(arc_buf_contents_t,	hdr_type)
+	    __field(uint64_t,		hdr_size)
+	    __field(uint64_t,		hdr_spa)
+	    __field(arc_state_type_t,	hdr_state_type)
+	    __field(clock_t,		hdr_access)
+	    __field(uint32_t,		hdr_mru_hits)
+	    __field(uint32_t,		hdr_mru_ghost_hits)
+	    __field(uint32_t,		hdr_mfu_hits)
+	    __field(uint32_t,		hdr_mfu_ghost_hits)
+	    __field(uint32_t,		hdr_l2_hits)
+	    __field(int64_t,		hdr_refcount)
+	),
+	TP_fast_assign(
+	    __entry->hdr_dva_word[0]	= ab->b_dva.dva_word[0];
+	    __entry->hdr_dva_word[1]	= ab->b_dva.dva_word[1];
+	    __entry->hdr_birth		= ab->b_birth;
+	    __entry->hdr_flags		= ab->b_flags;
+	    __entry->hdr_datacnt	= ab->b_l1hdr.b_datacnt;
+	    __entry->hdr_size		= ab->b_size;
+	    __entry->hdr_spa		= ab->b_spa;
+	    __entry->hdr_state_type	= ab->b_l1hdr.b_state->arcs_state;
+	    __entry->hdr_access		= ab->b_l1hdr.b_arc_access;
+	    __entry->hdr_mru_hits	= ab->b_l1hdr.b_mru_hits;
+	    __entry->hdr_mru_ghost_hits	= ab->b_l1hdr.b_mru_ghost_hits;
+	    __entry->hdr_mfu_hits	= ab->b_l1hdr.b_mfu_hits;
+	    __entry->hdr_mfu_ghost_hits	= ab->b_l1hdr.b_mfu_ghost_hits;
+	    __entry->hdr_l2_hits	= ab->b_l1hdr.b_l2_hits;
+	    __entry->hdr_refcount	= ab->b_l1hdr.b_refcnt.rc_count;
+	),
+	TP_printk("hdr { dva 0x%llx:0x%llx birth %llu "
+	    "flags 0x%x datacnt %u type %u size %llu spa %llu "
+	    "state_type %u access %lu mru_hits %u mru_ghost_hits %u "
+	    "mfu_hits %u mfu_ghost_hits %u l2_hits %u refcount %lli }",
+	    __entry->hdr_dva_word[0], __entry->hdr_dva_word[1],
+	    __entry->hdr_birth, __entry->hdr_flags,
+	    __entry->hdr_datacnt, __entry->hdr_type, __entry->hdr_size,
+	    __entry->hdr_spa, __entry->hdr_state_type,
+	    __entry->hdr_access, __entry->hdr_mru_hits,
+	    __entry->hdr_mru_ghost_hits, __entry->hdr_mfu_hits,
+	    __entry->hdr_mfu_ghost_hits, __entry->hdr_l2_hits,
+	    __entry->hdr_refcount)
+);
+
+#define	DEFINE_ARC_BUF_HDR_EVENT(name) \
+DEFINE_EVENT(zfs_arc_buf_hdr_class, name, \
+	TP_PROTO(arc_buf_hdr_t *ab), \
+	TP_ARGS(ab))
+DEFINE_ARC_BUF_HDR_EVENT(zfs_arc__hit);
+DEFINE_ARC_BUF_HDR_EVENT(zfs_arc__evict);
+DEFINE_ARC_BUF_HDR_EVENT(zfs_arc__delete);
+DEFINE_ARC_BUF_HDR_EVENT(zfs_new_state__mru);
+DEFINE_ARC_BUF_HDR_EVENT(zfs_new_state__mfu);
+DEFINE_ARC_BUF_HDR_EVENT(zfs_l2arc__hit);
+DEFINE_ARC_BUF_HDR_EVENT(zfs_l2arc__miss);
+
+/*
+ * Generic support for two argument tracepoints of the form:
+ *
+ * DTRACE_PROBE2(...,
+ *     vdev_t *, ...,
+ *     zio_t *, ...);
+ */
+
+#define	ZIO_TP_STRUCT_ENTRY						\
+		__field(zio_type_t,		zio_type)		\
+		__field(int,			zio_cmd)		\
+		__field(zio_priority_t,		zio_priority)		\
+		__field(uint64_t,		zio_size)		\
+		__field(uint64_t,		zio_orig_size)		\
+		__field(uint64_t,		zio_offset)		\
+		__field(hrtime_t,		zio_timestamp)		\
+		__field(hrtime_t,		zio_delta)		\
+		__field(uint64_t,		zio_delay)		\
+		__field(enum zio_flag,		zio_flags)		\
+		__field(enum zio_stage,		zio_stage)		\
+		__field(enum zio_stage,		zio_pipeline)		\
+		__field(enum zio_flag,		zio_orig_flags)		\
+		__field(enum zio_stage,		zio_orig_stage)		\
+		__field(enum zio_stage,		zio_orig_pipeline)	\
+		__field(uint8_t,		zio_reexecute)		\
+		__field(uint64_t,		zio_txg)		\
+		__field(int,			zio_error)		\
+		__field(uint64_t,		zio_ena)		\
+									\
+		__field(enum zio_checksum,	zp_checksum)		\
+		__field(enum zio_compress,	zp_compress)		\
+		__field(dmu_object_type_t,	zp_type)		\
+		__field(uint8_t,		zp_level)		\
+		__field(uint8_t,		zp_copies)		\
+		__field(boolean_t,		zp_dedup)		\
+		__field(boolean_t,		zp_dedup_verify)	\
+		__field(boolean_t,		zp_nopwrite)
+
+#define	ZIO_TP_FAST_ASSIGN						    \
+		__entry->zio_type		= zio->io_type;		    \
+		__entry->zio_cmd		= zio->io_cmd;		    \
+		__entry->zio_priority		= zio->io_priority;	    \
+		__entry->zio_size		= zio->io_size;		    \
+		__entry->zio_orig_size		= zio->io_orig_size;	    \
+		__entry->zio_offset		= zio->io_offset;	    \
+		__entry->zio_timestamp		= zio->io_timestamp;	    \
+		__entry->zio_delta		= zio->io_delta;	    \
+		__entry->zio_delay		= zio->io_delay;	    \
+		__entry->zio_flags		= zio->io_flags;	    \
+		__entry->zio_stage		= zio->io_stage;	    \
+		__entry->zio_pipeline		= zio->io_pipeline;	    \
+		__entry->zio_orig_flags		= zio->io_orig_flags;	    \
+		__entry->zio_orig_stage		= zio->io_orig_stage;	    \
+		__entry->zio_orig_pipeline	= zio->io_orig_pipeline;    \
+		__entry->zio_reexecute		= zio->io_reexecute;	    \
+		__entry->zio_txg		= zio->io_txg;		    \
+		__entry->zio_error		= zio->io_error;	    \
+		__entry->zio_ena		= zio->io_ena;		    \
+									    \
+		__entry->zp_checksum		= zio->io_prop.zp_checksum; \
+		__entry->zp_compress		= zio->io_prop.zp_compress; \
+		__entry->zp_type		= zio->io_prop.zp_type;	    \
+		__entry->zp_level		= zio->io_prop.zp_level;    \
+		__entry->zp_copies		= zio->io_prop.zp_copies;   \
+		__entry->zp_dedup		= zio->io_prop.zp_dedup;    \
+		__entry->zp_nopwrite		= zio->io_prop.zp_nopwrite; \
+		__entry->zp_dedup_verify	= zio->io_prop.zp_dedup_verify;
+
+#define	ZIO_TP_PRINTK_FMT						\
+	"zio { type %u cmd %i prio %u size %llu orig_size %llu "	\
+	"offset %llu timestamp %llu delta %llu delay %llu "		\
+	"flags 0x%x stage 0x%x pipeline 0x%x orig_flags 0x%x "		\
+	"orig_stage 0x%x orig_pipeline 0x%x reexecute %u "		\
+	"txg %llu error %d ena %llu prop { checksum %u compress %u "	\
+	"type %u level %u copies %u dedup %u dedup_verify %u nopwrite %u } }"
+
+#define	ZIO_TP_PRINTK_ARGS						\
+	__entry->zio_type, __entry->zio_cmd, __entry->zio_priority,	\
+	__entry->zio_size, __entry->zio_orig_size, __entry->zio_offset,	\
+	__entry->zio_timestamp, __entry->zio_delta, __entry->zio_delay,	\
+	__entry->zio_flags, __entry->zio_stage, __entry->zio_pipeline,	\
+	__entry->zio_orig_flags, __entry->zio_orig_stage,		\
+	__entry->zio_orig_pipeline, __entry->zio_reexecute,		\
+	__entry->zio_txg, __entry->zio_error, __entry->zio_ena,		\
+	__entry->zp_checksum, __entry->zp_compress, __entry->zp_type,	\
+	__entry->zp_level, __entry->zp_copies, __entry->zp_dedup,	\
+	__entry->zp_dedup_verify, __entry->zp_nopwrite
+
+DECLARE_EVENT_CLASS(zfs_l2arc_rw_class,
+	TP_PROTO(vdev_t *vd, zio_t *zio),
+	TP_ARGS(vd, zio),
+	TP_STRUCT__entry(
+	    __field(uint64_t,	vdev_id)
+	    __field(uint64_t,	vdev_guid)
+	    __field(uint64_t,	vdev_state)
+	    ZIO_TP_STRUCT_ENTRY
+	),
+	TP_fast_assign(
+	    __entry->vdev_id	= vd->vdev_id;
+	    __entry->vdev_guid	= vd->vdev_guid;
+	    __entry->vdev_state	= vd->vdev_state;
+	    ZIO_TP_FAST_ASSIGN
+	),
+	TP_printk("vdev { id %llu guid %llu state %llu } "
+	    ZIO_TP_PRINTK_FMT, __entry->vdev_id, __entry->vdev_guid,
+	    __entry->vdev_state, ZIO_TP_PRINTK_ARGS)
+);
+
+#define	DEFINE_L2ARC_RW_EVENT(name) \
+DEFINE_EVENT(zfs_l2arc_rw_class, name, \
+	TP_PROTO(vdev_t *vd, zio_t *zio), \
+	TP_ARGS(vd, zio))
+DEFINE_L2ARC_RW_EVENT(zfs_l2arc__read);
+DEFINE_L2ARC_RW_EVENT(zfs_l2arc__write);
+
+
+/*
+ * Generic support for two argument tracepoints of the form:
+ *
+ * DTRACE_PROBE2(...,
+ *     zio_t *, ...,
+ *     l2arc_write_callback_t *, ...);
+ */
+
+DECLARE_EVENT_CLASS(zfs_l2arc_iodone_class,
+	TP_PROTO(zio_t *zio, l2arc_write_callback_t *cb),
+	TP_ARGS(zio, cb),
+	TP_STRUCT__entry(ZIO_TP_STRUCT_ENTRY),
+	TP_fast_assign(ZIO_TP_FAST_ASSIGN),
+	TP_printk(ZIO_TP_PRINTK_FMT, ZIO_TP_PRINTK_ARGS)
+);
+
+#define	DEFINE_L2ARC_IODONE_EVENT(name) \
+DEFINE_EVENT(zfs_l2arc_iodone_class, name, \
+	TP_PROTO(zio_t *zio, l2arc_write_callback_t *cb), \
+	TP_ARGS(zio, cb))
+DEFINE_L2ARC_IODONE_EVENT(zfs_l2arc__iodone);
+
+
+/*
+ * Generic support for four argument tracepoints of the form:
+ *
+ * DTRACE_PROBE4(...,
+ *     arc_buf_hdr_t *, ...,
+ *     const blkptr_t *,
+ *     uint64_t,
+ *     const zbookmark_phys_t *);
+ */
+
+DECLARE_EVENT_CLASS(zfs_arc_miss_class,
+	TP_PROTO(arc_buf_hdr_t *hdr,
+	    const blkptr_t *bp, uint64_t size, const zbookmark_phys_t *zb),
+	TP_ARGS(hdr, bp, size, zb),
+	TP_STRUCT__entry(
+	    __array(uint64_t,		hdr_dva_word, 2)
+	    __field(uint64_t,		hdr_birth)
+	    __field(uint32_t,		hdr_flags)
+	    __field(uint32_t,		hdr_datacnt)
+	    __field(arc_buf_contents_t,	hdr_type)
+	    __field(uint64_t,		hdr_size)
+	    __field(uint64_t,		hdr_spa)
+	    __field(arc_state_type_t,	hdr_state_type)
+	    __field(clock_t,		hdr_access)
+	    __field(uint32_t,		hdr_mru_hits)
+	    __field(uint32_t,		hdr_mru_ghost_hits)
+	    __field(uint32_t,		hdr_mfu_hits)
+	    __field(uint32_t,		hdr_mfu_ghost_hits)
+	    __field(uint32_t,		hdr_l2_hits)
+	    __field(int64_t,		hdr_refcount)
+
+	    __array(uint64_t,		bp_dva0, 2)
+	    __array(uint64_t,		bp_dva1, 2)
+	    __array(uint64_t,		bp_dva2, 2)
+	    __array(uint64_t,		bp_cksum, 4)
+
+	    __field(uint64_t,		bp_lsize)
+
+	    __field(uint64_t,		zb_objset)
+	    __field(uint64_t,		zb_object)
+	    __field(int64_t,		zb_level)
+	    __field(uint64_t,		zb_blkid)
+	),
+	TP_fast_assign(
+	    __entry->hdr_dva_word[0]	= hdr->b_dva.dva_word[0];
+	    __entry->hdr_dva_word[1]	= hdr->b_dva.dva_word[1];
+	    __entry->hdr_birth		= hdr->b_birth;
+	    __entry->hdr_flags		= hdr->b_flags;
+	    __entry->hdr_datacnt	= hdr->b_l1hdr.b_datacnt;
+	    __entry->hdr_size		= hdr->b_size;
+	    __entry->hdr_spa		= hdr->b_spa;
+	    __entry->hdr_state_type	= hdr->b_l1hdr.b_state->arcs_state;
+	    __entry->hdr_access		= hdr->b_l1hdr.b_arc_access;
+	    __entry->hdr_mru_hits	= hdr->b_l1hdr.b_mru_hits;
+	    __entry->hdr_mru_ghost_hits	= hdr->b_l1hdr.b_mru_ghost_hits;
+	    __entry->hdr_mfu_hits	= hdr->b_l1hdr.b_mfu_hits;
+	    __entry->hdr_mfu_ghost_hits	= hdr->b_l1hdr.b_mfu_ghost_hits;
+	    __entry->hdr_l2_hits	= hdr->b_l1hdr.b_l2_hits;
+	    __entry->hdr_refcount	= hdr->b_l1hdr.b_refcnt.rc_count;
+
+	    __entry->bp_dva0[0]		= bp->blk_dva[0].dva_word[0];
+	    __entry->bp_dva0[1]		= bp->blk_dva[0].dva_word[1];
+	    __entry->bp_dva1[0]		= bp->blk_dva[1].dva_word[0];
+	    __entry->bp_dva1[1]		= bp->blk_dva[1].dva_word[1];
+	    __entry->bp_dva2[0]		= bp->blk_dva[2].dva_word[0];
+	    __entry->bp_dva2[1]		= bp->blk_dva[2].dva_word[1];
+	    __entry->bp_cksum[0]	= bp->blk_cksum.zc_word[0];
+	    __entry->bp_cksum[1]	= bp->blk_cksum.zc_word[1];
+	    __entry->bp_cksum[2]	= bp->blk_cksum.zc_word[2];
+	    __entry->bp_cksum[3]	= bp->blk_cksum.zc_word[3];
+
+	    __entry->bp_lsize		= size;
+
+	    __entry->zb_objset		= zb->zb_objset;
+	    __entry->zb_object		= zb->zb_object;
+	    __entry->zb_level		= zb->zb_level;
+	    __entry->zb_blkid		= zb->zb_blkid;
+	),
+	TP_printk("hdr { dva 0x%llx:0x%llx birth %llu "
+	    "flags 0x%x datacnt %u size %llu spa %llu state_type %u "
+	    "access %lu mru_hits %u mru_ghost_hits %u mfu_hits %u "
+	    "mfu_ghost_hits %u l2_hits %u refcount %lli } "
+	    "bp { dva0 0x%llx:0x%llx dva1 0x%llx:0x%llx dva2 "
+	    "0x%llx:0x%llx cksum 0x%llx:0x%llx:0x%llx:0x%llx "
+	    "lsize %llu } zb { objset %llu object %llu level %lli "
+	    "blkid %llu }",
+	    __entry->hdr_dva_word[0], __entry->hdr_dva_word[1],
+	    __entry->hdr_birth, __entry->hdr_flags,
+	    __entry->hdr_datacnt, __entry->hdr_size,
+	    __entry->hdr_spa, __entry->hdr_state_type, __entry->hdr_access,
+	    __entry->hdr_mru_hits, __entry->hdr_mru_ghost_hits,
+	    __entry->hdr_mfu_hits, __entry->hdr_mfu_ghost_hits,
+	    __entry->hdr_l2_hits, __entry->hdr_refcount,
+	    __entry->bp_dva0[0], __entry->bp_dva0[1],
+	    __entry->bp_dva1[0], __entry->bp_dva1[1],
+	    __entry->bp_dva2[0], __entry->bp_dva2[1],
+	    __entry->bp_cksum[0], __entry->bp_cksum[1],
+	    __entry->bp_cksum[2], __entry->bp_cksum[3],
+	    __entry->bp_lsize, __entry->zb_objset, __entry->zb_object,
+	    __entry->zb_level, __entry->zb_blkid)
+);
+
+#define	DEFINE_ARC_MISS_EVENT(name) \
+DEFINE_EVENT(zfs_arc_miss_class, name, \
+	TP_PROTO(arc_buf_hdr_t *hdr, \
+	    const blkptr_t *bp, uint64_t size, const zbookmark_phys_t *zb), \
+	TP_ARGS(hdr, bp, size, zb))
+DEFINE_ARC_MISS_EVENT(zfs_arc__miss);
+
+/*
+ * Generic support for four argument tracepoints of the form:
+ *
+ * DTRACE_PROBE4(...,
+ *     l2arc_dev_t *, ...,
+ *     list_t *, ...,
+ *     uint64_t, ...,
+ *     boolean_t, ...);
+ */
+
+DECLARE_EVENT_CLASS(zfs_l2arc_evict_class,
+	TP_PROTO(l2arc_dev_t *dev,
+	    list_t *buflist, uint64_t taddr, boolean_t all),
+	TP_ARGS(dev, buflist, taddr, all),
+	TP_STRUCT__entry(
+	    __field(uint64_t,		vdev_id)
+	    __field(uint64_t,		vdev_guid)
+	    __field(uint64_t,		vdev_state)
+
+	    __field(uint64_t,		l2ad_hand)
+	    __field(uint64_t,		l2ad_start)
+	    __field(uint64_t,		l2ad_end)
+	    __field(boolean_t,		l2ad_first)
+	    __field(boolean_t,		l2ad_writing)
+
+	    __field(uint64_t,		taddr)
+	    __field(boolean_t,		all)
+	),
+	TP_fast_assign(
+	    __entry->vdev_id		= dev->l2ad_vdev->vdev_id;
+	    __entry->vdev_guid		= dev->l2ad_vdev->vdev_guid;
+	    __entry->vdev_state		= dev->l2ad_vdev->vdev_state;
+
+	    __entry->l2ad_hand		= dev->l2ad_hand;
+	    __entry->l2ad_start		= dev->l2ad_start;
+	    __entry->l2ad_end		= dev->l2ad_end;
+	    __entry->l2ad_first		= dev->l2ad_first;
+	    __entry->l2ad_writing	= dev->l2ad_writing;
+
+	    __entry->taddr		= taddr;
+	    __entry->all		= all;
+	),
+	TP_printk("l2ad { vdev { id %llu guid %llu state %llu } "
+	    "hand %llu start %llu end %llu "
+	    "first %d writing %d } taddr %llu all %d",
+	    __entry->vdev_id, __entry->vdev_guid, __entry->vdev_state,
+	    __entry->l2ad_hand, __entry->l2ad_start,
+	    __entry->l2ad_end, __entry->l2ad_first, __entry->l2ad_writing,
+	    __entry->taddr, __entry->all)
+);
+
+#define	DEFINE_L2ARC_EVICT_EVENT(name) \
+DEFINE_EVENT(zfs_l2arc_evict_class, name, \
+	TP_PROTO(l2arc_dev_t *dev, \
+	    list_t *buflist, uint64_t taddr, boolean_t all), \
+	TP_ARGS(dev, buflist, taddr, all))
+DEFINE_L2ARC_EVICT_EVENT(zfs_l2arc__evict);
+
+#endif /* _TRACE_ARC_H */
+
+#undef TRACE_INCLUDE_PATH
+#undef TRACE_INCLUDE_FILE
+#define	TRACE_INCLUDE_PATH sys
+#define	TRACE_INCLUDE_FILE trace_arc
+#include <trace/define_trace.h>
+
+#endif /* _KERNEL && HAVE_DECLARE_EVENT_CLASS */
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/include/sys/trace_dbgmsg.h
@@ -0,0 +1,111 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/* Do not include this file directly. Please use <sys/trace.h> instead. */
+#ifndef _SYS_TRACE_DBGMSG_INDIRECT
+#error "trace_dbgmsg.h included directly"
+#endif
+
+/*
+ * This file defines tracepoint events for use by the dbgmsg(),
+ * dprintf(), and SET_ERROR() interfaces. These are grouped here because
+ * they all provide a way to store simple messages in the debug log (as
+ * opposed to events used by the DTRACE_PROBE interfaces which typically
+ * dump structured data).
+ *
+ * This header is included inside the trace.h multiple inclusion guard,
+ * and it is guarded above against direct inclusion, so it and need not
+ * be guarded separately.
+ */
+
+/*
+ * Generic support for four argument tracepoints of the form:
+ *
+ * DTRACE_PROBE4(...,
+ *     const char *, ...,
+ *     const char *, ...,
+ *     int, ...,
+ *     const char *, ...);
+ */
+
+DECLARE_EVENT_CLASS(zfs_dprintf_class,
+	TP_PROTO(const char *file, const char *function, int line,
+	    const char *msg),
+	TP_ARGS(file, function, line, msg),
+	TP_STRUCT__entry(
+	    __field(const char *,	file)
+	    __field(const char *,	function)
+	    __field(int,		line)
+	    __string(msg, msg)
+	),
+	TP_fast_assign(
+	    __entry->file		= file;
+	    __entry->function		= function;
+	    __entry->line		= line;
+	    __assign_str(msg, msg);
+	),
+	TP_printk("%s:%d:%s(): %s", __entry->file, __entry->line,
+	    __entry->function, __get_str(msg))
+);
+
+#define	DEFINE_DPRINTF_EVENT(name) \
+DEFINE_EVENT(zfs_dprintf_class, name, \
+	TP_PROTO(const char *file, const char *function, int line, \
+	    const char *msg), \
+	TP_ARGS(file, function, line, msg))
+DEFINE_DPRINTF_EVENT(zfs_zfs__dprintf);
+
+/*
+ * Generic support for four argument tracepoints of the form:
+ *
+ * DTRACE_PROBE4(...,
+ *     const char *, ...,
+ *     const char *, ...,
+ *     int, ...,
+ *     uintptr_t, ...);
+ */
+
+DECLARE_EVENT_CLASS(zfs_set_error_class,
+	TP_PROTO(const char *file, const char *function, int line,
+	    uintptr_t error),
+	TP_ARGS(file, function, line, error),
+	TP_STRUCT__entry(
+	    __field(const char *,	file)
+	    __field(const char *,	function)
+	    __field(int,		line)
+	    __field(uintptr_t,		error)
+	),
+	TP_fast_assign(
+	    __entry->file = strchr(file, '/') ? strrchr(file, '/') + 1 : file;
+	    __entry->function		= function;
+	    __entry->line		= line;
+	    __entry->error		= error;
+	),
+	TP_printk("%s:%d:%s(): error 0x%lx", __entry->file, __entry->line,
+	    __entry->function, __entry->error)
+);
+
+#define	DEFINE_SET_ERROR_EVENT(name) \
+DEFINE_EVENT(zfs_set_error_class, name, \
+	TP_PROTO(const char *file, const char *function, int line, \
+	    uintptr_t error), \
+	TP_ARGS(file, function, line, error))
+DEFINE_SET_ERROR_EVENT(zfs_set__error);
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/include/sys/trace_dbuf.h
@@ -0,0 +1,102 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+#if defined(_KERNEL) && defined(HAVE_DECLARE_EVENT_CLASS)
+
+#undef TRACE_SYSTEM
+#define	TRACE_SYSTEM zfs
+
+#undef TRACE_SYSTEM_VAR
+#define	TRACE_SYSTEM_VAR zfs_dbuf
+
+#if !defined(_TRACE_DBUF_H) || defined(TRACE_HEADER_MULTI_READ)
+#define	_TRACE_DBUF_H
+
+#include <linux/tracepoint.h>
+#include <sys/types.h>
+
+/*
+ * Generic support for two argument tracepoints of the form:
+ *
+ * DTRACE_PROBE2(...,
+ *     dmu_buf_impl_t *, ...,
+ *     zio_t *, ...);
+ */
+
+#define	DBUF_TP_STRUCT_ENTRY					\
+	__field(const char *,	os_spa)				\
+	__field(uint64_t,	ds_object)			\
+	__field(uint64_t,	db_object)			\
+	__field(uint64_t,	db_level)			\
+	__field(uint64_t,	db_blkid)			\
+	__field(uint64_t,	db_offset)			\
+	__field(uint64_t,	db_size)			\
+	__field(uint64_t,	db_state)			\
+	__field(int64_t,	db_holds)			\
+
+#define	DBUF_TP_FAST_ASSIGN					\
+	__entry->os_spa =					\
+	    spa_name(DB_DNODE(db)->dn_objset->os_spa);		\
+								\
+	__entry->ds_object = db->db_objset->os_dsl_dataset ?	\
+	    db->db_objset->os_dsl_dataset->ds_object : 0;	\
+								\
+	__entry->db_object = db->db.db_object;			\
+	__entry->db_level  = db->db_level;			\
+	__entry->db_blkid  = db->db_blkid;			\
+	__entry->db_offset = db->db.db_offset;			\
+	__entry->db_size   = db->db.db_size;			\
+	__entry->db_state  = db->db_state;			\
+	__entry->db_holds  = refcount_count(&db->db_holds);
+
+#define	DBUF_TP_PRINTK_FMT						\
+	"dbuf { spa \"%s\" objset %llu object %llu level %llu "		\
+	"blkid %llu offset %llu size %llu state %llu holds %lld }"
+
+#define	DBUF_TP_PRINTK_ARGS					\
+	__entry->os_spa, __entry->ds_object,			\
+	__entry->db_object, __entry->db_level,			\
+	__entry->db_blkid, __entry->db_offset,			\
+	__entry->db_size, __entry->db_state, __entry->db_holds
+
+DECLARE_EVENT_CLASS(zfs_dbuf_class,
+	TP_PROTO(dmu_buf_impl_t *db, zio_t *zio),
+	TP_ARGS(db, zio),
+	TP_STRUCT__entry(DBUF_TP_STRUCT_ENTRY),
+	TP_fast_assign(DBUF_TP_FAST_ASSIGN),
+	TP_printk(DBUF_TP_PRINTK_FMT, DBUF_TP_PRINTK_ARGS)
+);
+
+#define	DEFINE_DBUF_EVENT(name) \
+DEFINE_EVENT(zfs_dbuf_class, name, \
+	TP_PROTO(dmu_buf_impl_t *db, zio_t *zio), \
+	TP_ARGS(db, zio))
+DEFINE_DBUF_EVENT(zfs_blocked__read);
+
+#endif /* _TRACE_DBUF_H */
+
+#undef TRACE_INCLUDE_PATH
+#undef TRACE_INCLUDE_FILE
+#define	TRACE_INCLUDE_PATH sys
+#define	TRACE_INCLUDE_FILE trace_dbuf
+#include <trace/define_trace.h>
+
+#endif /* _KERNEL && HAVE_DECLARE_EVENT_CLASS */
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/include/sys/trace_dmu.h
@@ -0,0 +1,120 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+#if defined(_KERNEL) && defined(HAVE_DECLARE_EVENT_CLASS)
+
+#undef TRACE_SYSTEM
+#define	TRACE_SYSTEM zfs
+
+#undef TRACE_SYSTEM_VAR
+#define	TRACE_SYSTEM_VAR zfs_dmu
+
+#if !defined(_TRACE_DMU_H) || defined(TRACE_HEADER_MULTI_READ)
+#define	_TRACE_DMU_H
+
+#include <linux/tracepoint.h>
+#include <sys/types.h>
+
+/*
+ * Generic support for three argument tracepoints of the form:
+ *
+ * DTRACE_PROBE3(...,
+ *     dmu_tx_t *, ...,
+ *     uint64_t, ...,
+ *     uint64_t, ...);
+ */
+
+DECLARE_EVENT_CLASS(zfs_delay_mintime_class,
+	TP_PROTO(dmu_tx_t *tx, uint64_t dirty, uint64_t min_tx_time),
+	TP_ARGS(tx, dirty, min_tx_time),
+	TP_STRUCT__entry(
+	    __field(uint64_t,			tx_txg)
+	    __field(uint64_t,			tx_lastsnap_txg)
+	    __field(uint64_t,			tx_lasttried_txg)
+	    __field(boolean_t,			tx_anyobj)
+	    __field(boolean_t,			tx_waited)
+	    __field(hrtime_t,			tx_start)
+	    __field(boolean_t,			tx_wait_dirty)
+	    __field(int,			tx_err)
+#ifdef DEBUG_DMU_TX
+	    __field(uint64_t,			tx_space_towrite)
+	    __field(uint64_t,			tx_space_tofree)
+	    __field(uint64_t,			tx_space_tooverwrite)
+	    __field(uint64_t,			tx_space_tounref)
+	    __field(int64_t,			tx_space_written)
+	    __field(int64_t,			tx_space_freed)
+#endif
+	    __field(uint64_t,			min_tx_time)
+	    __field(uint64_t,			dirty)
+	),
+	TP_fast_assign(
+	    __entry->tx_txg			= tx->tx_txg;
+	    __entry->tx_lastsnap_txg		= tx->tx_lastsnap_txg;
+	    __entry->tx_lasttried_txg		= tx->tx_lasttried_txg;
+	    __entry->tx_anyobj			= tx->tx_anyobj;
+	    __entry->tx_waited			= tx->tx_waited;
+	    __entry->tx_start			= tx->tx_start;
+	    __entry->tx_wait_dirty		= tx->tx_wait_dirty;
+	    __entry->tx_err			= tx->tx_err;
+#ifdef DEBUG_DMU_TX
+	    __entry->tx_space_towrite		= tx->tx_space_towrite;
+	    __entry->tx_space_tofree		= tx->tx_space_tofree;
+	    __entry->tx_space_tooverwrite	= tx->tx_space_tooverwrite;
+	    __entry->tx_space_tounref		= tx->tx_space_tounref;
+	    __entry->tx_space_written		= tx->tx_space_written.rc_count;
+	    __entry->tx_space_freed		= tx->tx_space_freed.rc_count;
+#endif
+	    __entry->dirty			= dirty;
+	    __entry->min_tx_time		= min_tx_time;
+	),
+	TP_printk("tx { txg %llu lastsnap_txg %llu tx_lasttried_txg %llu "
+	    "anyobj %d waited %d start %llu wait_dirty %d err %i "
+#ifdef DEBUG_DMU_TX
+	    "space_towrite %llu space_tofree %llu space_tooverwrite %llu "
+	    "space_tounref %llu space_written %lli space_freed %lli "
+#endif
+	    "} dirty %llu min_tx_time %llu",
+	    __entry->tx_txg, __entry->tx_lastsnap_txg,
+	    __entry->tx_lasttried_txg, __entry->tx_anyobj, __entry->tx_waited,
+	    __entry->tx_start, __entry->tx_wait_dirty, __entry->tx_err,
+#ifdef DEBUG_DMU_TX
+	    __entry->tx_space_towrite, __entry->tx_space_tofree,
+	    __entry->tx_space_tooverwrite, __entry->tx_space_tounref,
+	    __entry->tx_space_written, __entry->tx_space_freed,
+#endif
+	    __entry->dirty, __entry->min_tx_time)
+);
+
+#define	DEFINE_DELAY_MINTIME_EVENT(name) \
+DEFINE_EVENT(zfs_delay_mintime_class, name, \
+	TP_PROTO(dmu_tx_t *tx, uint64_t dirty, uint64_t min_tx_time), \
+	TP_ARGS(tx, dirty, min_tx_time))
+DEFINE_DELAY_MINTIME_EVENT(zfs_delay__mintime);
+
+#endif /* _TRACE_DMU_H */
+
+#undef TRACE_INCLUDE_PATH
+#undef TRACE_INCLUDE_FILE
+#define	TRACE_INCLUDE_PATH sys
+#define	TRACE_INCLUDE_FILE trace_dmu
+#include <trace/define_trace.h>
+
+#endif /* _KERNEL && HAVE_DECLARE_EVENT_CLASS */
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/include/sys/trace_dnode.h
@@ -0,0 +1,120 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+#if defined(_KERNEL) && defined(HAVE_DECLARE_EVENT_CLASS)
+
+#undef TRACE_SYSTEM
+#define	TRACE_SYSTEM zfs
+
+#undef TRACE_SYSTEM_VAR
+#define	TRACE_SYSTEM_VAR zfs_dnode
+
+#if !defined(_TRACE_DNODE_H) || defined(TRACE_HEADER_MULTI_READ)
+#define	_TRACE_DNODE_H
+
+#include <linux/tracepoint.h>
+#include <sys/types.h>
+
+/*
+ * Generic support for three argument tracepoints of the form:
+ *
+ * DTRACE_PROBE3(...,
+ *     dnode_t *, ...,
+ *     int64_t, ...,
+ *     uint32_t, ...);
+ */
+
+DECLARE_EVENT_CLASS(zfs_dnode_move_class,
+	TP_PROTO(dnode_t *dn, int64_t refcount, uint32_t dbufs),
+	TP_ARGS(dn, refcount, dbufs),
+	TP_STRUCT__entry(
+	    __field(uint64_t,		dn_object)
+	    __field(dmu_object_type_t,	dn_type)
+	    __field(uint16_t,		dn_bonuslen)
+	    __field(uint8_t,		dn_bonustype)
+	    __field(uint8_t,		dn_nblkptr)
+	    __field(uint8_t,		dn_checksum)
+	    __field(uint8_t,		dn_compress)
+	    __field(uint8_t,		dn_nlevels)
+	    __field(uint8_t,		dn_indblkshift)
+	    __field(uint8_t,		dn_datablkshift)
+	    __field(uint8_t,		dn_moved)
+	    __field(uint16_t,		dn_datablkszsec)
+	    __field(uint32_t,		dn_datablksz)
+	    __field(uint64_t,		dn_maxblkid)
+	    __field(int64_t,		dn_tx_holds)
+	    __field(int64_t,		dn_holds)
+	    __field(boolean_t,		dn_have_spill)
+
+	    __field(int64_t,		refcount)
+	    __field(uint32_t,		dbufs)
+	),
+	TP_fast_assign(
+	    __entry->dn_object		= dn->dn_object;
+	    __entry->dn_type		= dn->dn_type;
+	    __entry->dn_bonuslen	= dn->dn_bonuslen;
+	    __entry->dn_bonustype	= dn->dn_bonustype;
+	    __entry->dn_nblkptr		= dn->dn_nblkptr;
+	    __entry->dn_checksum	= dn->dn_checksum;
+	    __entry->dn_compress	= dn->dn_compress;
+	    __entry->dn_nlevels		= dn->dn_nlevels;
+	    __entry->dn_indblkshift	= dn->dn_indblkshift;
+	    __entry->dn_datablkshift	= dn->dn_datablkshift;
+	    __entry->dn_moved		= dn->dn_moved;
+	    __entry->dn_datablkszsec	= dn->dn_datablkszsec;
+	    __entry->dn_datablksz	= dn->dn_datablksz;
+	    __entry->dn_maxblkid	= dn->dn_maxblkid;
+	    __entry->dn_tx_holds	= dn->dn_tx_holds.rc_count;
+	    __entry->dn_holds		= dn->dn_holds.rc_count;
+	    __entry->dn_have_spill	= dn->dn_have_spill;
+
+	    __entry->refcount		= refcount;
+	    __entry->dbufs		= dbufs;
+	),
+	TP_printk("dn { object %llu type %d bonuslen %u bonustype %u "
+	    "nblkptr %u checksum %u compress %u nlevels %u indblkshift %u "
+	    "datablkshift %u moved %u datablkszsec %u datablksz %u "
+	    "maxblkid %llu tx_holds %lli holds %lli have_spill %d } "
+	    "refcount %lli dbufs %u",
+	    __entry->dn_object, __entry->dn_type, __entry->dn_bonuslen,
+	    __entry->dn_bonustype, __entry->dn_nblkptr, __entry->dn_checksum,
+	    __entry->dn_compress, __entry->dn_nlevels, __entry->dn_indblkshift,
+	    __entry->dn_datablkshift, __entry->dn_moved,
+	    __entry->dn_datablkszsec, __entry->dn_datablksz,
+	    __entry->dn_maxblkid, __entry->dn_tx_holds, __entry->dn_holds,
+	    __entry->dn_have_spill, __entry->refcount, __entry->dbufs)
+);
+
+#define	DEFINE_DNODE_MOVE_EVENT(name) \
+DEFINE_EVENT(zfs_dnode_move_class, name, \
+	TP_PROTO(dnode_t *dn, int64_t refcount, uint32_t dbufs), \
+	TP_ARGS(dn, refcount, dbufs))
+DEFINE_DNODE_MOVE_EVENT(zfs_dnode__move);
+
+#endif /* _TRACE_DNODE_H */
+
+#undef TRACE_INCLUDE_PATH
+#undef TRACE_INCLUDE_FILE
+#define	TRACE_INCLUDE_PATH sys
+#define	TRACE_INCLUDE_FILE trace_dnode
+#include <trace/define_trace.h>
+
+#endif /* _KERNEL && HAVE_DECLARE_EVENT_CLASS */
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/include/sys/trace_multilist.h
@@ -0,0 +1,79 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+#if defined(_KERNEL) && defined(HAVE_DECLARE_EVENT_CLASS)
+
+#undef TRACE_SYSTEM
+#define	TRACE_SYSTEM zfs
+
+#undef TRACE_SYSTEM_VAR
+#define	TRACE_SYSTEM_VAR zfs_multilist
+
+#if !defined(_TRACE_MULTILIST_H) || defined(TRACE_HEADER_MULTI_READ)
+#define	_TRACE_MULTILIST_H
+
+#include <linux/tracepoint.h>
+#include <sys/types.h>
+
+/*
+ * Generic support for three argument tracepoints of the form:
+ *
+ * DTRACE_PROBE3(...,
+ *     multilist_t *, ...,
+ *     unsigned int, ...,
+ *     void *, ...);
+ */
+
+DECLARE_EVENT_CLASS(zfs_multilist_insert_remove_class,
+	TP_PROTO(multilist_t *ml, unsigned sublist_idx, void *obj),
+	TP_ARGS(ml, sublist_idx, obj),
+	TP_STRUCT__entry(
+	    __field(size_t,		ml_offset)
+	    __field(uint64_t,		ml_num_sublists)
+
+	    __field(unsigned int,	sublist_idx)
+	),
+	TP_fast_assign(
+	    __entry->ml_offset		= ml->ml_offset;
+	    __entry->ml_num_sublists	= ml->ml_num_sublists;
+
+	    __entry->sublist_idx	= sublist_idx;
+	),
+	TP_printk("ml { offset %ld numsublists %llu sublistidx %u } ",
+	    __entry->ml_offset, __entry->ml_num_sublists, __entry->sublist_idx)
+);
+
+#define	DEFINE_MULTILIST_INSERT_REMOVE_EVENT(name) \
+DEFINE_EVENT(zfs_multilist_insert_remove_class, name, \
+	TP_PROTO(multilist_t *ml, unsigned int sublist_idx, void *obj), \
+	TP_ARGS(ml, sublist_idx, obj))
+DEFINE_MULTILIST_INSERT_REMOVE_EVENT(zfs_multilist__insert);
+DEFINE_MULTILIST_INSERT_REMOVE_EVENT(zfs_multilist__remove);
+
+#endif /* _TRACE_MULTILIST_H */
+
+#undef TRACE_INCLUDE_PATH
+#undef TRACE_INCLUDE_FILE
+#define	TRACE_INCLUDE_PATH sys
+#define	TRACE_INCLUDE_FILE trace_multilist
+#include <trace/define_trace.h>
+
+#endif /* _KERNEL && HAVE_DECLARE_EVENT_CLASS */
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/include/sys/trace_txg.h
@@ -0,0 +1,75 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+#if defined(_KERNEL) && defined(HAVE_DECLARE_EVENT_CLASS)
+
+#undef TRACE_SYSTEM
+#define	TRACE_SYSTEM zfs
+
+#undef TRACE_SYSTEM_VAR
+#define	TRACE_SYSTEM_VAR zfs_txg
+
+#if !defined(_TRACE_TXG_H) || defined(TRACE_HEADER_MULTI_READ)
+#define	_TRACE_TXG_H
+
+#include <linux/tracepoint.h>
+#include <sys/types.h>
+
+/*
+ * Generic support for two argument tracepoints of the form:
+ *
+ * DTRACE_PROBE2(...,
+ *     dsl_pool_t *, ...,
+ *     uint64_t, ...);
+ */
+
+DECLARE_EVENT_CLASS(zfs_txg_class,
+	TP_PROTO(dsl_pool_t *dp, uint64_t txg),
+	TP_ARGS(dp, txg),
+	TP_STRUCT__entry(
+	    __field(uint64_t, txg)
+	),
+	TP_fast_assign(
+	    __entry->txg = txg;
+	),
+	TP_printk("txg %llu", __entry->txg)
+);
+
+#define	DEFINE_TXG_EVENT(name) \
+DEFINE_EVENT(zfs_txg_class, name, \
+	TP_PROTO(dsl_pool_t *dp, uint64_t txg), \
+	TP_ARGS(dp, txg))
+DEFINE_TXG_EVENT(zfs_dsl_pool_sync__done);
+DEFINE_TXG_EVENT(zfs_txg__quiescing);
+DEFINE_TXG_EVENT(zfs_txg__opened);
+DEFINE_TXG_EVENT(zfs_txg__syncing);
+DEFINE_TXG_EVENT(zfs_txg__synced);
+DEFINE_TXG_EVENT(zfs_txg__quiesced);
+
+#endif /* _TRACE_TXG_H */
+
+#undef TRACE_INCLUDE_PATH
+#undef TRACE_INCLUDE_FILE
+#define	TRACE_INCLUDE_PATH sys
+#define	TRACE_INCLUDE_FILE trace_txg
+#include <trace/define_trace.h>
+
+#endif /* _KERNEL && HAVE_DECLARE_EVENT_CLASS */
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/include/sys/trace_zil.h
@@ -0,0 +1,130 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+#if defined(_KERNEL) && defined(HAVE_DECLARE_EVENT_CLASS)
+
+#undef TRACE_SYSTEM
+#define	TRACE_SYSTEM zfs
+
+#undef TRACE_SYSTEM_VAR
+#define	TRACE_SYSTEM_VAR zfs_zil
+
+#if !defined(_TRACE_ZIL_H) || defined(TRACE_HEADER_MULTI_READ)
+#define	_TRACE_ZIL_H
+
+#include <linux/tracepoint.h>
+#include <sys/types.h>
+
+/*
+ * Generic support for one argument tracepoints of the form:
+ *
+ * DTRACE_PROBE1(...,
+ *     zilog_t *, ...);
+ */
+
+DECLARE_EVENT_CLASS(zfs_zil_class,
+	TP_PROTO(zilog_t *zilog),
+	TP_ARGS(zilog),
+	TP_STRUCT__entry(
+	    __field(uint64_t,	zl_lr_seq)
+	    __field(uint64_t,	zl_commit_lr_seq)
+	    __field(uint64_t,	zl_destroy_txg)
+	    __field(uint64_t,	zl_replaying_seq)
+	    __field(uint32_t,	zl_suspend)
+	    __field(uint8_t,	zl_suspending)
+	    __field(uint8_t,	zl_keep_first)
+	    __field(uint8_t,	zl_replay)
+	    __field(uint8_t,	zl_stop_sync)
+	    __field(uint8_t,	zl_writer)
+	    __field(uint8_t,	zl_logbias)
+	    __field(uint8_t,	zl_sync)
+	    __field(int,	zl_parse_error)
+	    __field(uint64_t,	zl_parse_blk_seq)
+	    __field(uint64_t,	zl_parse_lr_seq)
+	    __field(uint64_t,	zl_parse_blk_count)
+	    __field(uint64_t,	zl_parse_lr_count)
+	    __field(uint64_t,	zl_next_batch)
+	    __field(uint64_t,	zl_com_batch)
+	    __field(uint64_t,	zl_itx_list_sz)
+	    __field(uint64_t,	zl_cur_used)
+	    __field(clock_t,	zl_replay_time)
+	    __field(uint64_t,	zl_replay_blks)
+	),
+	TP_fast_assign(
+	    __entry->zl_lr_seq		= zilog->zl_lr_seq;
+	    __entry->zl_commit_lr_seq	= zilog->zl_commit_lr_seq;
+	    __entry->zl_destroy_txg	= zilog->zl_destroy_txg;
+	    __entry->zl_replaying_seq	= zilog->zl_replaying_seq;
+	    __entry->zl_suspend		= zilog->zl_suspend;
+	    __entry->zl_suspending	= zilog->zl_suspending;
+	    __entry->zl_keep_first	= zilog->zl_keep_first;
+	    __entry->zl_replay		= zilog->zl_replay;
+	    __entry->zl_stop_sync	= zilog->zl_stop_sync;
+	    __entry->zl_writer		= zilog->zl_writer;
+	    __entry->zl_logbias		= zilog->zl_logbias;
+	    __entry->zl_sync		= zilog->zl_sync;
+	    __entry->zl_parse_error	= zilog->zl_parse_error;
+	    __entry->zl_parse_blk_seq	= zilog->zl_parse_blk_seq;
+	    __entry->zl_parse_lr_seq	= zilog->zl_parse_lr_seq;
+	    __entry->zl_parse_blk_count	= zilog->zl_parse_blk_count;
+	    __entry->zl_parse_lr_count	= zilog->zl_parse_lr_count;
+	    __entry->zl_next_batch	= zilog->zl_next_batch;
+	    __entry->zl_com_batch	= zilog->zl_com_batch;
+	    __entry->zl_itx_list_sz	= zilog->zl_itx_list_sz;
+	    __entry->zl_cur_used	= zilog->zl_cur_used;
+	    __entry->zl_replay_time	= zilog->zl_replay_time;
+	    __entry->zl_replay_blks	= zilog->zl_replay_blks;
+	),
+	TP_printk("zl { lr_seq %llu commit_lr_seq %llu destroy_txg %llu "
+	    "replaying_seq %llu suspend %u suspending %u keep_first %u "
+	    "replay %u stop_sync %u writer %u logbias %u sync %u "
+	    "parse_error %u parse_blk_seq %llu parse_lr_seq %llu "
+	    "parse_blk_count %llu parse_lr_count %llu next_batch %llu "
+	    "com_batch %llu itx_list_sz %llu cur_used %llu replay_time %lu "
+	    "replay_blks %llu }",
+	    __entry->zl_lr_seq, __entry->zl_commit_lr_seq,
+	    __entry->zl_destroy_txg, __entry->zl_replaying_seq,
+	    __entry->zl_suspend, __entry->zl_suspending, __entry->zl_keep_first,
+	    __entry->zl_replay, __entry->zl_stop_sync, __entry->zl_writer,
+	    __entry->zl_logbias, __entry->zl_sync, __entry->zl_parse_error,
+	    __entry->zl_parse_blk_seq, __entry->zl_parse_lr_seq,
+	    __entry->zl_parse_blk_count, __entry->zl_parse_lr_count,
+	    __entry->zl_next_batch, __entry->zl_com_batch,
+	    __entry->zl_itx_list_sz, __entry->zl_cur_used,
+	    __entry->zl_replay_time, __entry->zl_replay_blks)
+);
+
+#define	DEFINE_ZIL_EVENT(name) \
+DEFINE_EVENT(zfs_zil_class, name, \
+	TP_PROTO(zilog_t *zilog), \
+	TP_ARGS(zilog))
+DEFINE_ZIL_EVENT(zfs_zil__cw1);
+DEFINE_ZIL_EVENT(zfs_zil__cw2);
+
+#endif /* _TRACE_ZIL_H */
+
+#undef TRACE_INCLUDE_PATH
+#undef TRACE_INCLUDE_FILE
+#define	TRACE_INCLUDE_PATH sys
+#define	TRACE_INCLUDE_FILE trace_zil
+#include <trace/define_trace.h>
+
+#endif /* _KERNEL && HAVE_DECLARE_EVENT_CLASS */
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/include/sys/trace_zrlock.h
@@ -0,0 +1,87 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+#if defined(_KERNEL) && defined(HAVE_DECLARE_EVENT_CLASS)
+
+#undef TRACE_SYSTEM
+#define	TRACE_SYSTEM zfs
+
+#undef TRACE_SYSTEM_VAR
+#define	TRACE_SYSTEM_VAR zfs_zrlock
+
+#if !defined(_TRACE_ZRLOCK_H) || defined(TRACE_HEADER_MULTI_READ)
+#define	_TRACE_ZRLOCK_H
+
+#include <linux/tracepoint.h>
+#include <sys/types.h>
+
+/*
+ * Generic support for two argument tracepoints of the form:
+ *
+ * DTRACE_PROBE2(...,
+ *     zrlock_t *, ...,
+ *     uint32_t, ...);
+ */
+
+DECLARE_EVENT_CLASS(zfs_zrlock_class,
+	TP_PROTO(zrlock_t *zrl, uint32_t n),
+	TP_ARGS(zrl, n),
+	TP_STRUCT__entry(
+	    __field(int32_t,		refcount)
+#ifdef	ZFS_DEBUG
+	    __field(pid_t,		owner_pid)
+	    __field(const char *,	caller)
+#endif
+	    __field(uint32_t,		n)
+	),
+	TP_fast_assign(
+	    __entry->refcount	= zrl->zr_refcount;
+#ifdef	ZFS_DEBUG
+	    __entry->owner_pid	= zrl->zr_owner ? zrl->zr_owner->pid : 0;
+	    __entry->caller	= zrl->zr_caller;
+#endif
+	    __entry->n		= n;
+	),
+#ifdef	ZFS_DEBUG
+	TP_printk("zrl { refcount %d owner_pid %d caller %s } n %u",
+	    __entry->refcount, __entry->owner_pid, __entry->caller,
+	    __entry->n)
+#else
+	TP_printk("zrl { refcount %d } n %u",
+	    __entry->refcount, __entry->n)
+#endif
+);
+
+#define	DEFINE_ZRLOCK_EVENT(name) \
+DEFINE_EVENT(zfs_zrlock_class, name, \
+	TP_PROTO(zrlock_t *zrl, uint32_t n), \
+	TP_ARGS(zrl, n))
+DEFINE_ZRLOCK_EVENT(zfs_zrlock__reentry);
+
+#endif /* _TRACE_ZRLOCK_H */
+
+#undef TRACE_INCLUDE_PATH
+#undef TRACE_INCLUDE_FILE
+#define	TRACE_INCLUDE_PATH sys
+#define	TRACE_INCLUDE_FILE trace_zrlock
+#include <trace/define_trace.h>
+
+#endif /* _KERNEL && HAVE_DECLARE_EVENT_CLASS */
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/include/sys/txg.h
@@ -0,0 +1,137 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * Copyright (c) 2012, 2014 by Delphix. All rights reserved.
+ */
+
+#ifndef _SYS_TXG_H
+#define	_SYS_TXG_H
+
+#include <sys/spa.h>
+#include <sys/zfs_context.h>
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+#define	TXG_CONCURRENT_STATES	3	/* open, quiescing, syncing	*/
+#define	TXG_SIZE		4		/* next power of 2	*/
+#define	TXG_MASK		(TXG_SIZE - 1)	/* mask for size	*/
+#define	TXG_INITIAL		TXG_SIZE	/* initial txg 		*/
+#define	TXG_IDX			(txg & TXG_MASK)
+
+/* Number of txgs worth of frees we defer adding to in-core spacemaps */
+#define	TXG_DEFER_SIZE		2
+
+typedef struct tx_cpu tx_cpu_t;
+
+typedef struct txg_handle {
+	tx_cpu_t	*th_cpu;
+	uint64_t	th_txg;
+} txg_handle_t;
+
+typedef struct txg_node {
+	struct txg_node	*tn_next[TXG_SIZE];
+	uint8_t		tn_member[TXG_SIZE];
+} txg_node_t;
+
+typedef struct txg_list {
+	kmutex_t	tl_lock;
+	size_t		tl_offset;
+	txg_node_t	*tl_head[TXG_SIZE];
+} txg_list_t;
+
+struct dsl_pool;
+
+extern void txg_init(struct dsl_pool *dp, uint64_t txg);
+extern void txg_fini(struct dsl_pool *dp);
+extern void txg_sync_start(struct dsl_pool *dp);
+extern void txg_sync_stop(struct dsl_pool *dp);
+extern uint64_t txg_hold_open(struct dsl_pool *dp, txg_handle_t *txghp);
+extern void txg_rele_to_quiesce(txg_handle_t *txghp);
+extern void txg_rele_to_sync(txg_handle_t *txghp);
+extern void txg_register_callbacks(txg_handle_t *txghp, list_t *tx_callbacks);
+
+extern void txg_delay(struct dsl_pool *dp, uint64_t txg, hrtime_t delta,
+    hrtime_t resolution);
+extern void txg_kick(struct dsl_pool *dp);
+
+/*
+ * Wait until the given transaction group has finished syncing.
+ * Try to make this happen as soon as possible (eg. kick off any
+ * necessary syncs immediately).  If txg==0, wait for the currently open
+ * txg to finish syncing.
+ */
+extern void txg_wait_synced(struct dsl_pool *dp, uint64_t txg);
+
+/*
+ * Wait until the given transaction group, or one after it, is
+ * the open transaction group.  Try to make this happen as soon
+ * as possible (eg. kick off any necessary syncs immediately).
+ * If txg == 0, wait for the next open txg.
+ */
+extern void txg_wait_open(struct dsl_pool *dp, uint64_t txg);
+
+/*
+ * Returns TRUE if we are "backed up" waiting for the syncing
+ * transaction to complete; otherwise returns FALSE.
+ */
+extern boolean_t txg_stalled(struct dsl_pool *dp);
+
+/* returns TRUE if someone is waiting for the next txg to sync */
+extern boolean_t txg_sync_waiting(struct dsl_pool *dp);
+
+/*
+ * Wait for pending commit callbacks of already-synced transactions to finish
+ * processing.
+ */
+extern void txg_wait_callbacks(struct dsl_pool *dp);
+
+/*
+ * Per-txg object lists.
+ */
+
+#define	TXG_CLEAN(txg)	((txg) - 1)
+
+extern void txg_list_create(txg_list_t *tl, size_t offset);
+extern void txg_list_destroy(txg_list_t *tl);
+extern boolean_t txg_list_empty(txg_list_t *tl, uint64_t txg);
+extern boolean_t txg_all_lists_empty(txg_list_t *tl);
+extern boolean_t txg_list_add(txg_list_t *tl, void *p, uint64_t txg);
+extern boolean_t txg_list_add_tail(txg_list_t *tl, void *p, uint64_t txg);
+extern void *txg_list_remove(txg_list_t *tl, uint64_t txg);
+extern void *txg_list_remove_this(txg_list_t *tl, void *p, uint64_t txg);
+extern boolean_t txg_list_member(txg_list_t *tl, void *p, uint64_t txg);
+extern void *txg_list_head(txg_list_t *tl, uint64_t txg);
+extern void *txg_list_next(txg_list_t *tl, void *p, uint64_t txg);
+
+/* Global tuning */
+extern int zfs_txg_timeout;
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* _SYS_TXG_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/include/sys/txg_impl.h
@@ -0,0 +1,124 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/*
+ * Copyright (c) 2013 by Delphix. All rights reserved.
+ */
+
+#ifndef _SYS_TXG_IMPL_H
+#define	_SYS_TXG_IMPL_H
+
+#include <sys/spa.h>
+#include <sys/txg.h>
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+/*
+ * The tx_cpu structure is a per-cpu structure that is used to track
+ * the number of active transaction holds (tc_count). As transactions
+ * are assigned into a transaction group the appropriate tc_count is
+ * incremented to indicate that there are pending changes that have yet
+ * to quiesce. Consumers evenutally call txg_rele_to_sync() to decrement
+ * the tc_count. A transaction group is not considered quiesced until all
+ * tx_cpu structures have reached a tc_count of zero.
+ *
+ * This structure is a per-cpu structure by design. Updates to this structure
+ * are frequent and concurrent. Having a single structure would result in
+ * heavy lock contention so a per-cpu design was implemented. With the fanned
+ * out mutex design, consumers only need to lock the mutex associated with
+ * thread's cpu.
+ *
+ * The tx_cpu contains two locks, the tc_lock and tc_open_lock.
+ * The tc_lock is used to protect all members of the tx_cpu structure with
+ * the exception of the tc_open_lock. This lock should only be held for a
+ * short period of time, typically when updating the value of tc_count.
+ *
+ * The tc_open_lock protects the tx_open_txg member of the tx_state structure.
+ * This lock is used to ensure that transactions are only assigned into
+ * the current open transaction group. In order to move the current open
+ * transaction group to the quiesce phase, the txg_quiesce thread must
+ * grab all tc_open_locks, increment the tx_open_txg, and drop the locks.
+ * The tc_open_lock is held until the transaction is assigned into the
+ * transaction group. Typically, this is a short operation but if throttling
+ * is occuring it may be held for longer periods of time.
+ */
+struct tx_cpu {
+	kmutex_t	tc_open_lock;	/* protects tx_open_txg */
+	kmutex_t	tc_lock;	/* protects the rest of this struct */
+	kcondvar_t	tc_cv[TXG_SIZE];
+	uint64_t	tc_count[TXG_SIZE];	/* tx hold count on each txg */
+	list_t		tc_callbacks[TXG_SIZE]; /* commit cb list */
+	char		tc_pad[8];		/* pad to fill 3 cache lines */
+};
+
+/*
+ * The tx_state structure maintains the state information about the different
+ * stages of the pool's transcation groups. A per pool tx_state structure
+ * is used to track this information. The tx_state structure also points to
+ * an array of tx_cpu structures (described above). Although the tx_sync_lock
+ * is used to protect the members of this structure, it is not used to
+ * protect the tx_open_txg. Instead a special lock in the tx_cpu structure
+ * is used. Readers of tx_open_txg must grab the per-cpu tc_open_lock.
+ * Any thread wishing to update tx_open_txg must grab the tc_open_lock on
+ * every cpu (see txg_quiesce()).
+ */
+typedef struct tx_state {
+	tx_cpu_t	*tx_cpu;	/* protects access to tx_open_txg */
+	kmutex_t	tx_sync_lock;	/* protects the rest of this struct */
+
+	uint64_t	tx_open_txg;	/* currently open txg id */
+	uint64_t	tx_quiesced_txg; /* quiesced txg waiting for sync */
+	uint64_t	tx_syncing_txg;	/* currently syncing txg id */
+	uint64_t	tx_synced_txg;	/* last synced txg id */
+
+	hrtime_t	tx_open_time;	/* start time of tx_open_txg */
+
+	uint64_t	tx_sync_txg_waiting; /* txg we're waiting to sync */
+	uint64_t	tx_quiesce_txg_waiting; /* txg we're waiting to open */
+
+	kcondvar_t	tx_sync_more_cv;
+	kcondvar_t	tx_sync_done_cv;
+	kcondvar_t	tx_quiesce_more_cv;
+	kcondvar_t	tx_quiesce_done_cv;
+	kcondvar_t	tx_timeout_cv;
+	kcondvar_t	tx_exit_cv;	/* wait for all threads to exit */
+
+	uint8_t		tx_threads;	/* number of threads */
+	uint8_t		tx_exiting;	/* set when we're exiting */
+
+	kthread_t	*tx_sync_thread;
+	kthread_t	*tx_quiesce_thread;
+
+	taskq_t		*tx_commit_cb_taskq; /* commit callback taskq */
+} tx_state_t;
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* _SYS_TXG_IMPL_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/include/sys/u8_textprep.h
@@ -0,0 +1,113 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef	_SYS_U8_TEXTPREP_H
+#define	_SYS_U8_TEXTPREP_H
+
+
+
+#include <sys/isa_defs.h>
+#include <sys/types.h>
+#include <sys/errno.h>
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+/*
+ * Unicode encoding conversion functions and their macros.
+ */
+#define	UCONV_IN_BIG_ENDIAN		0x0001
+#define	UCONV_OUT_BIG_ENDIAN		0x0002
+#define	UCONV_IN_SYSTEM_ENDIAN		0x0004
+#define	UCONV_OUT_SYSTEM_ENDIAN		0x0008
+#define	UCONV_IN_LITTLE_ENDIAN		0x0010
+#define	UCONV_OUT_LITTLE_ENDIAN		0x0020
+#define	UCONV_IGNORE_NULL		0x0040
+#define	UCONV_IN_ACCEPT_BOM		0x0080
+#define	UCONV_OUT_EMIT_BOM		0x0100
+
+extern int uconv_u16tou32(const uint16_t *, size_t *, uint32_t *, size_t *,
+	int);
+extern int uconv_u16tou8(const uint16_t *, size_t *, uchar_t *, size_t *, int);
+extern int uconv_u32tou16(const uint32_t *, size_t *, uint16_t *, size_t *,
+	int);
+extern int uconv_u32tou8(const uint32_t *, size_t *, uchar_t *, size_t *, int);
+extern int uconv_u8tou16(const uchar_t *, size_t *, uint16_t *, size_t *, int);
+extern int uconv_u8tou32(const uchar_t *, size_t *, uint32_t *, size_t *, int);
+
+/*
+ * UTF-8 text preparation functions and their macros.
+ *
+ * Among the macros defined, U8_CANON_DECOMP, U8_COMPAT_DECOMP, and
+ * U8_CANON_COMP are not public interfaces and must not be used directly
+ * at the flag input argument.
+ */
+#define	U8_STRCMP_CS			(0x00000001)
+#define	U8_STRCMP_CI_UPPER		(0x00000002)
+#define	U8_STRCMP_CI_LOWER		(0x00000004)
+
+#define	U8_CANON_DECOMP			(0x00000010)
+#define	U8_COMPAT_DECOMP		(0x00000020)
+#define	U8_CANON_COMP			(0x00000040)
+
+#define	U8_STRCMP_NFD			(U8_CANON_DECOMP)
+#define	U8_STRCMP_NFC			(U8_CANON_DECOMP | U8_CANON_COMP)
+#define	U8_STRCMP_NFKD			(U8_COMPAT_DECOMP)
+#define	U8_STRCMP_NFKC			(U8_COMPAT_DECOMP | U8_CANON_COMP)
+
+#define	U8_TEXTPREP_TOUPPER		(U8_STRCMP_CI_UPPER)
+#define	U8_TEXTPREP_TOLOWER		(U8_STRCMP_CI_LOWER)
+
+#define	U8_TEXTPREP_NFD			(U8_STRCMP_NFD)
+#define	U8_TEXTPREP_NFC			(U8_STRCMP_NFC)
+#define	U8_TEXTPREP_NFKD		(U8_STRCMP_NFKD)
+#define	U8_TEXTPREP_NFKC		(U8_STRCMP_NFKC)
+
+#define	U8_TEXTPREP_IGNORE_NULL		(0x00010000)
+#define	U8_TEXTPREP_IGNORE_INVALID	(0x00020000)
+#define	U8_TEXTPREP_NOWAIT		(0x00040000)
+
+#define	U8_UNICODE_320			(0)
+#define	U8_UNICODE_500			(1)
+#define	U8_UNICODE_LATEST		(U8_UNICODE_500)
+
+#define	U8_VALIDATE_ENTIRE		(0x00100000)
+#define	U8_VALIDATE_CHECK_ADDITIONAL	(0x00200000)
+#define	U8_VALIDATE_UCS2_RANGE		(0x00400000)
+
+#define	U8_ILLEGAL_CHAR			(-1)
+#define	U8_OUT_OF_RANGE_CHAR		(-2)
+
+extern int u8_validate(char *, size_t, char **, int, int *);
+extern int u8_strcmp(const char *, const char *, size_t, int, size_t, int *);
+extern size_t u8_textprep_str(char *, size_t *, char *, size_t *, int, size_t,
+	int *);
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* _SYS_U8_TEXTPREP_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/include/sys/u8_textprep_data.h
@@ -0,0 +1,35376 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * COPYRIGHT AND PERMISSION NOTICE
+ *
+ * Copyright (c) 1991-2006 Unicode, Inc. All rights reserved. Distributed under
+ * the Terms of Use in http://www.unicode.org/copyright.html.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of the Unicode data files and any associated documentation (the
+ * "Data Files") or Unicode software and any associated documentation (the
+ * "Software") to deal in the Data Files or Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge,
+ * publish, distribute, and/or sell copies of the Data Files or Software, and
+ * to permit persons to whom the Data Files or Software are furnished to do so,
+ * provided that (a) the above copyright notice(s) and this permission notice
+ * appear with all copies of the Data Files or Software, (b) both the above
+ * copyright notice(s) and this permission notice appear in associated
+ * documentation, and (c) there is clear notice in each modified Data File or
+ * in the Software as well as in the documentation associated with the Data
+ * File(s) or Software that the data or software has been modified.
+ *
+ * THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+ * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF
+ * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS
+ * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR
+ * CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THE DATA FILES OR SOFTWARE.
+ *
+ * Except as contained in this notice, the name of a copyright holder shall not
+ * be used in advertising or otherwise to promote the sale, use or other
+ * dealings in these Data Files or Software without prior written authorization
+ * of the copyright holder.
+ *
+ * Unicode and the Unicode logo are trademarks of Unicode, Inc., and may be
+ * registered in some jurisdictions. All other trademarks and registered
+ * trademarks mentioned herein are the property of their respective owners.
+ */
+/*
+ * This file has been modified by Sun Microsystems, Inc.
+ */
+
+#ifndef _SYS_U8_TEXTPREP_DATA_H
+#define	_SYS_U8_TEXTPREP_DATA_H
+
+
+
+#include <sys/types.h>
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+/*
+ * To get to the combining class data, composition mappings, decomposition
+ * mappings, and case conversion mappings of Unicode, the data structures
+ * formulated and their meanings are like the following:
+ *
+ * Each UTF-8 character is seen as a 4-byte entity so that U+0061 (or 0x61 in
+ * UTF-8) would be seen as 0x00 0x00 0x00 0x61. Similarly, U+1D15E would be
+ * 0xF0 0x9D 0x85 0x9E in UTF-8.
+ *
+ * The first byte (MSB) value is an index to the b1_tbl, such as
+ * u8_common_b1_tbl and u8_composition_b1_tbl tables. A b1_tbl has
+ * indices to b2_tbl tables that have indices to b3_tbl. Each b3_tbl has
+ * either indices to b4_tbl or indices to b4_tbl and base values for
+ * displacement calculations later by using the u8_displacement_t type at
+ * below. Each b4_tbl table then has indices to the final tables.
+ *
+ * As an example, if we have a character with code value of U+1D15E which is
+ * 0xF0 0x9D 0x85 0x9E in UTF-8, the target decomposition character bytes
+ * that will be mapped by the mapping procedure would be the ones between
+ * the start_index and the end_index computed as like the following:
+ *
+ *	b2_tbl_id = u8_common_b1_tbl[0][0xF0];
+ *	b3_tbl_id = u8_decomp_b2_tbl[0][b2_tbl_id][0x9D];
+ *	b4_tbl_id = u8_decomp_b3_tbl[0][b3_tbl_id][0x85].tbl_id;
+ *	b4_base = u8_decomp_b3_tbl[0][b3_tbl_id][0x85].base;
+ *	if (b4_tbl_id >= 0x8000) {
+ *		b4_tbl_id -= 0x8000;
+ *      	start_index = u8_decomp_b4_16bit_tbl[0][b4_tbl_id][0x9E];
+ *      	end_index = u8_decomp_b4_16bit_tbl[0][b4_tbl_id][0x9E + 1];
+ *	} else {
+ *      	start_index = u8_decomp_b4_tbl[0][b4_tbl_id][0x9E];
+ *      	end_index = u8_decomp_b4_tbl[0][b4_tbl_id][0x9E + 1];
+ *	}
+ *
+ * The start_index and the end_index can be used to retrieve the bytes
+ * possibly of multiple UTF-8 characters from the final tables.
+ *
+ * The "[0]" at the above indicates this is for Unicode Version 3.2.0 data
+ * as of today.  Consequently, the "[1]" indicates another Unicode version
+ * data and it is Unicode 5.0.0 as of today.
+ *
+ * The mapping procedures and the data structures are more or less similar or
+ * alike among different mappings. You might want to read the u8_textprep.c
+ * for specific details.
+ *
+ * The tool programs created and used to generate the tables in this file are
+ * saved at PSARC/2007/149/materials/ as tools.tar.gz file.
+ */
+
+/* The following is a component type for the b4_tbl vectors. */
+typedef struct {
+	uint16_t	tbl_id;
+	uint16_t	base;
+} u8_displacement_t;
+
+/*
+ * The U8_TBL_ELEMENT_NOT_DEF macro indicates a byte that is not defined or
+ * used. The U8_TBL_ELEMENT_FILLER indicates the end of a UTF-8 character at
+ * the final tables.
+ */
+#define	U8_TBL_ELEMENT_NOT_DEF		(0xff)
+#define	N_				U8_TBL_ELEMENT_NOT_DEF
+
+#define	U8_TBL_ELEMENT_FILLER		(0xf7)
+#define	FIL_				U8_TBL_ELEMENT_FILLER
+
+/*
+ * The common b1_tbl for combining class, decompositions, tolower, and
+ * toupper case conversion mappings.
+ */
+static const uchar_t u8_common_b1_tbl[2][256] = {
+	{
+		0,  N_, N_, N_, N_, N_, N_, N_,
+		N_, N_, N_, N_, N_, N_, N_, N_,
+		N_, N_, N_, N_, N_, N_, N_, N_,
+		N_, N_, N_, N_, N_, N_, N_, N_,
+		N_, N_, N_, N_, N_, N_, N_, N_,
+		N_, N_, N_, N_, N_, N_, N_, N_,
+		N_, N_, N_, N_, N_, N_, N_, N_,
+		N_, N_, N_, N_, N_, N_, N_, N_,
+		N_, N_, N_, N_, N_, N_, N_, N_,
+		N_, N_, N_, N_, N_, N_, N_, N_,
+		N_, N_, N_, N_, N_, N_, N_, N_,
+		N_, N_, N_, N_, N_, N_, N_, N_,
+		N_, N_, N_, N_, N_, N_, N_, N_,
+		N_, N_, N_, N_, N_, N_, N_, N_,
+		N_, N_, N_, N_, N_, N_, N_, N_,
+		N_, N_, N_, N_, N_, N_, N_, N_,
+		N_, N_, N_, N_, N_, N_, N_, N_,
+		N_, N_, N_, N_, N_, N_, N_, N_,
+		N_, N_, N_, N_, N_, N_, N_, N_,
+		N_, N_, N_, N_, N_, N_, N_, N_,
+		N_, N_, N_, N_, N_, N_, N_, N_,
+		N_, N_, N_, N_, N_, N_, N_, N_,
+		N_, N_, N_, N_, N_, N_, N_, N_,
+		N_, N_, N_, N_, N_, N_, N_, N_,
+		N_, N_, N_, N_, N_, N_, N_, N_,
+		N_, N_, N_, N_, N_, N_, N_, N_,
+		N_, N_, N_, N_, N_, N_, N_, N_,
+		N_, N_, N_, N_, N_, N_, N_, N_,
+		N_, N_, N_, N_, N_, N_, N_, N_,
+		N_, N_, N_, N_, N_, N_, N_, N_,
+		1,  N_, N_, N_, N_, N_, N_, N_,
+		N_, N_, N_, N_, N_, N_, N_, N_,
+	},
+	{
+		0,  N_, N_, N_, N_, N_, N_, N_,
+		N_, N_, N_, N_, N_, N_, N_, N_,
+		N_, N_, N_, N_, N_, N_, N_, N_,
+		N_, N_, N_, N_, N_, N_, N_, N_,
+		N_, N_, N_, N_, N_, N_, N_, N_,
+		N_, N_, N_, N_, N_, N_, N_, N_,
+		N_, N_, N_, N_, N_, N_, N_, N_,
+		N_, N_, N_, N_, N_, N_, N_, N_,
+		N_, N_, N_, N_, N_, N_, N_, N_,
+		N_, N_, N_, N_, N_, N_, N_, N_,
+		N_, N_, N_, N_, N_, N_, N_, N_,
+		N_, N_, N_, N_, N_, N_, N_, N_,
+		N_, N_, N_, N_, N_, N_, N_, N_,
+		N_, N_, N_, N_, N_, N_, N_, N_,
+		N_, N_, N_, N_, N_, N_, N_, N_,
+		N_, N_, N_, N_, N_, N_, N_, N_,
+		N_, N_, N_, N_, N_, N_, N_, N_,
+		N_, N_, N_, N_, N_, N_, N_, N_,
+		N_, N_, N_, N_, N_, N_, N_, N_,
+		N_, N_, N_, N_, N_, N_, N_, N_,
+		N_, N_, N_, N_, N_, N_, N_, N_,
+		N_, N_, N_, N_, N_, N_, N_, N_,
+		N_, N_, N_, N_, N_, N_, N_, N_,
+		N_, N_, N_, N_, N_, N_, N_, N_,
+		N_, N_, N_, N_, N_, N_, N_, N_,
+		N_, N_, N_, N_, N_, N_, N_, N_,
+		N_, N_, N_, N_, N_, N_, N_, N_,
+		N_, N_, N_, N_, N_, N_, N_, N_,
+		N_, N_, N_, N_, N_, N_, N_, N_,
+		N_, N_, N_, N_, N_, N_, N_, N_,
+		1,  N_, N_, N_, N_, N_, N_, N_,
+		N_, N_, N_, N_, N_, N_, N_, N_,
+	},
+};
+
+static const uchar_t u8_combining_class_b2_tbl[2][2][256] = {
+	{
+		{
+			0,  N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			1,  2,  3,  4,  N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, 5,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+		},
+		{
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, 6,  N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+		},
+
+	},
+	{
+		{
+			0,  N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			1,  2,  3,  4,  N_, N_, N_, N_,
+			N_, N_, 5,  N_, N_, N_, N_, 6,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+		},
+		{
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			7,  N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, 8,  N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+		},
+
+	},
+
+};
+
+static const uchar_t u8_combining_class_b3_tbl[2][9][256] = {
+	{
+		{	/* Third byte table 0. */
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, 0,  1,  N_, N_,
+			N_, N_, 2,  N_, N_, N_, 3,  4,
+			N_, 5,  N_, 6,  7,  8,  N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+		},
+		{	/* Third byte table 1. */
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, 9,  10, 11, 12,
+			13, 14, 15, 16, 17, 18, N_, 19,
+			N_, 20, N_, 21, N_, 22, N_, 23,
+			24, 25, 26, 27, 28, 29, 30, 31,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+		},
+		{	/* Third byte table 2. */
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			32, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, 33, N_, N_, 34,
+			N_, N_, 35, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+		},
+		{	/* Third byte table 3. */
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, 36, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+		},
+		{	/* Third byte table 4. */
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			37, N_, 38, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+		},
+		{	/* Third byte table 5. */
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, 39, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			40, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+		},
+		{	/* Third byte table 6. */
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, 41, 42, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+		},
+		{	/* Third byte table 7. */
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+		},
+		{	/* Third byte table 8. */
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+		},
+	},
+	{
+		{	/* Third byte table 0. */
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, 0,  1,  N_, N_,
+			N_, N_, 2,  N_, N_, N_, 3,  4,
+			5,  6,  N_, 7,  8,  9,  N_, 10,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+		},
+		{	/* Third byte table 1. */
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, 11, 12, 13, 14,
+			15, 16, 17, 18, 19, 20, N_, 21,
+			N_, 22, 23, 24, N_, 25, N_, 26,
+			27, 28, 29, 30, 31, 32, 33, 34,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+		},
+		{	/* Third byte table 2. */
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			35, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, 36, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, 37, N_, N_, 38,
+			N_, N_, 39, N_, 40, N_, N_, N_,
+			41, N_, N_, N_, 42, 43, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, 44,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+		},
+		{	/* Third byte table 3. */
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, 45, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+		},
+		{	/* Third byte table 4. */
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			46, N_, 47, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+		},
+		{	/* Third byte table 5. */
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			48, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+		},
+		{	/* Third byte table 6. */
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, 49, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			50, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+		},
+		{	/* Third byte table 7. */
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			51, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+		},
+		{	/* Third byte table 8. */
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, 52, 53, N_,
+			N_, 54, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+		},
+	},
+};
+
+/*
+ * Unlike other b4_tbl, the b4_tbl for combining class data has
+ * the combining class values not indices to the final tables.
+ */
+static const uchar_t u8_combining_class_b4_tbl[2][55][256] = {
+	{
+		{	/* Fourth byte table 0. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			230, 230, 230, 230, 230, 230, 230, 230,
+			230, 230, 230, 230, 230, 230, 230, 230,
+			230, 230, 230, 230, 230, 232, 220, 220,
+			220, 220, 232, 216, 220, 220, 220, 220,
+			220, 202, 202, 220, 220, 220, 220, 202,
+			202, 220, 220, 220, 220, 220, 220, 220,
+			220, 220, 220, 220, 1,   1,   1,   1,
+			1,   220, 220, 220, 220, 230, 230, 230,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+		},
+		{	/* Fourth byte table 1. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			230, 230, 230, 230, 230, 240, 230, 220,
+			220, 220, 230, 230, 230, 220, 220, 0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			234, 234, 233, 230, 230, 230, 230, 230,
+			230, 230, 230, 230, 230, 230, 230, 230,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+		},
+		{	/* Fourth byte table 2. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   230, 230, 230, 230, 0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+		},
+		{	/* Fourth byte table 3. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   220, 230, 230, 230, 230, 220, 230,
+			230, 230, 222, 220, 230, 230, 230, 230,
+			230, 230, 0,   220, 220, 220, 220, 220,
+			230, 230, 220, 230, 230, 222, 228, 230,
+			10,  11,  12,  13,  14,  15,  16,  17,
+			18,  19,  0,   20,  21,  22,  0,   23,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+		},
+		{	/* Fourth byte table 4. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   24,  25,  0,   230, 0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+		},
+		{	/* Fourth byte table 5. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   27,  28,  29,  30,  31,
+			32,  33,  34,  230, 230, 220, 0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			35,  0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+		},
+		{	/* Fourth byte table 6. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   230, 230,
+			230, 230, 230, 230, 230, 0,   0,   230,
+			230, 230, 230, 220, 230, 0,   0,   230,
+			230, 0,   220, 230, 230, 220, 0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+		},
+		{	/* Fourth byte table 7. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   36,  0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			230, 220, 230, 230, 220, 230, 230, 220,
+			220, 220, 230, 220, 220, 230, 220, 230,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+		},
+		{	/* Fourth byte table 8. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			230, 230, 220, 230, 220, 230, 220, 230,
+			220, 230, 230, 0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+		},
+		{	/* Fourth byte table 9. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   7,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+		},
+		{	/* Fourth byte table 10. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   9,   0,   0,
+			0,   230, 220, 230, 230, 0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+		},
+		{	/* Fourth byte table 11. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   7,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+		},
+		{	/* Fourth byte table 12. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   9,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+		},
+		{	/* Fourth byte table 13. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   7,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+		},
+		{	/* Fourth byte table 14. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   9,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+		},
+		{	/* Fourth byte table 15. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   7,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+		},
+		{	/* Fourth byte table 16. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   9,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+		},
+		{	/* Fourth byte table 17. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   7,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+		},
+		{	/* Fourth byte table 18. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   9,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+		},
+		{	/* Fourth byte table 19. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   9,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+		},
+		{	/* Fourth byte table 20. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   9,   0,   0,
+			0,   0,   0,   0,   0,   84,  91,  0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+		},
+		{	/* Fourth byte table 21. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   9,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+		},
+		{	/* Fourth byte table 22. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   9,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+		},
+		{	/* Fourth byte table 23. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   9,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+		},
+		{	/* Fourth byte table 24. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			103, 103, 9,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+		},
+		{	/* Fourth byte table 25. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			107, 107, 107, 107, 0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+		},
+		{	/* Fourth byte table 26. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			118, 118, 0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+		},
+		{	/* Fourth byte table 27. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			122, 122, 122, 122, 0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+		},
+		{	/* Fourth byte table 28. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			220, 220, 0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   220, 0,   220,
+			0,   216, 0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+		},
+		{	/* Fourth byte table 29. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   129, 130, 0,   132, 0,   0,   0,
+			0,   0,   130, 130, 130, 130, 0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+		},
+		{	/* Fourth byte table 30. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			130, 0,   230, 230, 9,   0,   230, 230,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+		},
+		{	/* Fourth byte table 31. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   220, 0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+		},
+		{	/* Fourth byte table 32. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   7,
+			0,   9,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+		},
+		{	/* Fourth byte table 33. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   9,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   9,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+		},
+		{	/* Fourth byte table 34. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   9,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+		},
+		{	/* Fourth byte table 35. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   228, 0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+		},
+		{	/* Fourth byte table 36. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			230, 230, 1,   1,   230, 230, 230, 230,
+			1,   1,   1,   230, 230, 0,   0,   0,
+			0,   230, 0,   0,   0,   1,   1,   230,
+			220, 230, 1,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+		},
+		{	/* Fourth byte table 37. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   218, 228, 232, 222, 224, 224,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+		},
+		{	/* Fourth byte table 38. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   8,   8,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+		},
+		{	/* Fourth byte table 39. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   26,  0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+		},
+		{	/* Fourth byte table 40. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			230, 230, 230, 230, 0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+		},
+		{	/* Fourth byte table 41. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   216, 216, 1,
+			1,   1,   0,   0,   0,   226, 216, 216,
+			216, 216, 216, 0,   0,   0,   0,   0,
+			0,   0,   0,   220, 220, 220, 220, 220,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+		},
+		{	/* Fourth byte table 42. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			220, 220, 220, 0,   0,   230, 230, 230,
+			230, 230, 220, 220, 0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   230, 230, 230, 230, 0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+		},
+		{	/* Fourth byte table 43. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+		},
+		{	/* Fourth byte table 44. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+		},
+		{	/* Fourth byte table 45. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+		},
+		{	/* Fourth byte table 46. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+		},
+		{	/* Fourth byte table 47. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+		},
+		{	/* Fourth byte table 48. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+		},
+		{	/* Fourth byte table 49. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+		},
+		{	/* Fourth byte table 50. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+		},
+		{	/* Fourth byte table 51. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+		},
+		{	/* Fourth byte table 52. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+		},
+		{	/* Fourth byte table 53. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+		},
+		{	/* Fourth byte table 54. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+		},
+	},
+	{
+		{	/* Fourth byte table 0. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			230, 230, 230, 230, 230, 230, 230, 230,
+			230, 230, 230, 230, 230, 230, 230, 230,
+			230, 230, 230, 230, 230, 232, 220, 220,
+			220, 220, 232, 216, 220, 220, 220, 220,
+			220, 202, 202, 220, 220, 220, 220, 202,
+			202, 220, 220, 220, 220, 220, 220, 220,
+			220, 220, 220, 220, 1,   1,   1,   1,
+			1,   220, 220, 220, 220, 230, 230, 230,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+		},
+		{	/* Fourth byte table 1. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			230, 230, 230, 230, 230, 240, 230, 220,
+			220, 220, 230, 230, 230, 220, 220, 0,
+			230, 230, 230, 220, 220, 220, 220, 230,
+			232, 220, 220, 230, 233, 234, 234, 233,
+			234, 234, 233, 230, 230, 230, 230, 230,
+			230, 230, 230, 230, 230, 230, 230, 230,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+		},
+		{	/* Fourth byte table 2. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   230, 230, 230, 230, 0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+		},
+		{	/* Fourth byte table 3. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   220, 230, 230, 230, 230, 220, 230,
+			230, 230, 222, 220, 230, 230, 230, 230,
+			230, 230, 220, 220, 220, 220, 220, 220,
+			230, 230, 220, 230, 230, 222, 228, 230,
+			10,  11,  12,  13,  14,  15,  16,  17,
+			18,  19,  19,  20,  21,  22,  0,   23,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+		},
+		{	/* Fourth byte table 4. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   24,  25,  0,   230, 220, 0,   18,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+		},
+		{	/* Fourth byte table 5. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			230, 230, 230, 230, 230, 230, 0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+		},
+		{	/* Fourth byte table 6. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   27,  28,  29,  30,  31,
+			32,  33,  34,  230, 230, 220, 220, 230,
+			230, 230, 230, 230, 220, 230, 230, 0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			35,  0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+		},
+		{	/* Fourth byte table 7. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   230, 230,
+			230, 230, 230, 230, 230, 0,   0,   230,
+			230, 230, 230, 220, 230, 0,   0,   230,
+			230, 0,   220, 230, 230, 220, 0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+		},
+		{	/* Fourth byte table 8. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   36,  0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			230, 220, 230, 230, 220, 230, 230, 220,
+			220, 220, 230, 220, 220, 230, 220, 230,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+		},
+		{	/* Fourth byte table 9. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			230, 230, 220, 230, 220, 230, 220, 230,
+			220, 230, 230, 0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+		},
+		{	/* Fourth byte table 10. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   230, 230, 230, 230, 230,
+			230, 230, 220, 230, 0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+		},
+		{	/* Fourth byte table 11. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   7,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+		},
+		{	/* Fourth byte table 12. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   9,   0,   0,
+			0,   230, 220, 230, 230, 0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+		},
+		{	/* Fourth byte table 13. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   7,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+		},
+		{	/* Fourth byte table 14. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   9,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+		},
+		{	/* Fourth byte table 15. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   7,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+		},
+		{	/* Fourth byte table 16. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   9,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+		},
+		{	/* Fourth byte table 17. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   7,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+		},
+		{	/* Fourth byte table 18. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   9,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+		},
+		{	/* Fourth byte table 19. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   7,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+		},
+		{	/* Fourth byte table 20. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   9,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+		},
+		{	/* Fourth byte table 21. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   9,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+		},
+		{	/* Fourth byte table 22. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   9,   0,   0,
+			0,   0,   0,   0,   0,   84,  91,  0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+		},
+		{	/* Fourth byte table 23. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   7,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+		},
+		{	/* Fourth byte table 24. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   9,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+		},
+		{	/* Fourth byte table 25. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   9,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+		},
+		{	/* Fourth byte table 26. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   9,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+		},
+		{	/* Fourth byte table 27. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			103, 103, 9,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+		},
+		{	/* Fourth byte table 28. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			107, 107, 107, 107, 0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+		},
+		{	/* Fourth byte table 29. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			118, 118, 0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+		},
+		{	/* Fourth byte table 30. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			122, 122, 122, 122, 0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+		},
+		{	/* Fourth byte table 31. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			220, 220, 0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   220, 0,   220,
+			0,   216, 0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+		},
+		{	/* Fourth byte table 32. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   129, 130, 0,   132, 0,   0,   0,
+			0,   0,   130, 130, 130, 130, 0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+		},
+		{	/* Fourth byte table 33. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			130, 0,   230, 230, 9,   0,   230, 230,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+		},
+		{	/* Fourth byte table 34. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   220, 0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+		},
+		{	/* Fourth byte table 35. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   7,
+			0,   9,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+		},
+		{	/* Fourth byte table 36. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   230,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+		},
+		{	/* Fourth byte table 37. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   9,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   9,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+		},
+		{	/* Fourth byte table 38. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   9,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   230, 0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+		},
+		{	/* Fourth byte table 39. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   228, 0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+		},
+		{	/* Fourth byte table 40. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   222, 230, 220, 0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+		},
+		{	/* Fourth byte table 41. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   230,
+			220, 0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+		},
+		{	/* Fourth byte table 42. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   7,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+		},
+		{	/* Fourth byte table 43. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   9,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   230, 220, 230, 230, 230,
+			230, 230, 230, 230, 0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+		},
+		{	/* Fourth byte table 44. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			230, 230, 220, 230, 230, 230, 230, 230,
+			230, 230, 220, 0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   230, 220,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+		},
+		{	/* Fourth byte table 45. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			230, 230, 1,   1,   230, 230, 230, 230,
+			1,   1,   1,   230, 230, 0,   0,   0,
+			0,   230, 0,   0,   0,   1,   1,   230,
+			220, 230, 1,   1,   220, 220, 220, 220,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+		},
+		{	/* Fourth byte table 46. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   218, 228, 232, 222, 224, 224,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+		},
+		{	/* Fourth byte table 47. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   8,   8,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+		},
+		{	/* Fourth byte table 48. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   9,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+		},
+		{	/* Fourth byte table 49. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   26,  0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+		},
+		{	/* Fourth byte table 50. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			230, 230, 230, 230, 0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+		},
+		{	/* Fourth byte table 51. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   220, 0,   230,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			230, 1,   220, 0,   0,   0,   0,   9,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+		},
+		{	/* Fourth byte table 52. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   216, 216, 1,
+			1,   1,   0,   0,   0,   226, 216, 216,
+			216, 216, 216, 0,   0,   0,   0,   0,
+			0,   0,   0,   220, 220, 220, 220, 220,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+		},
+		{	/* Fourth byte table 53. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			220, 220, 220, 0,   0,   230, 230, 230,
+			230, 230, 220, 220, 0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   230, 230, 230, 230, 0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+		},
+		{	/* Fourth byte table 54. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   230, 230, 230, 0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+		},
+	},
+};
+
+static const uchar_t u8_composition_b1_tbl[2][256] = {
+	{
+		0,  N_, N_, N_, N_, N_, N_, N_,
+		N_, N_, N_, N_, N_, N_, N_, N_,
+		N_, N_, N_, N_, N_, N_, N_, N_,
+		N_, N_, N_, N_, N_, N_, N_, N_,
+		N_, N_, N_, N_, N_, N_, N_, N_,
+		N_, N_, N_, N_, N_, N_, N_, N_,
+		N_, N_, N_, N_, N_, N_, N_, N_,
+		N_, N_, N_, N_, N_, N_, N_, N_,
+		N_, N_, N_, N_, N_, N_, N_, N_,
+		N_, N_, N_, N_, N_, N_, N_, N_,
+		N_, N_, N_, N_, N_, N_, N_, N_,
+		N_, N_, N_, N_, N_, N_, N_, N_,
+		N_, N_, N_, N_, N_, N_, N_, N_,
+		N_, N_, N_, N_, N_, N_, N_, N_,
+		N_, N_, N_, N_, N_, N_, N_, N_,
+		N_, N_, N_, N_, N_, N_, N_, N_,
+		N_, N_, N_, N_, N_, N_, N_, N_,
+		N_, N_, N_, N_, N_, N_, N_, N_,
+		N_, N_, N_, N_, N_, N_, N_, N_,
+		N_, N_, N_, N_, N_, N_, N_, N_,
+		N_, N_, N_, N_, N_, N_, N_, N_,
+		N_, N_, N_, N_, N_, N_, N_, N_,
+		N_, N_, N_, N_, N_, N_, N_, N_,
+		N_, N_, N_, N_, N_, N_, N_, N_,
+		N_, N_, N_, N_, N_, N_, N_, N_,
+		N_, N_, N_, N_, N_, N_, N_, N_,
+		N_, N_, N_, N_, N_, N_, N_, N_,
+		N_, N_, N_, N_, N_, N_, N_, N_,
+		N_, N_, N_, N_, N_, N_, N_, N_,
+		N_, N_, N_, N_, N_, N_, N_, N_,
+		N_, N_, N_, N_, N_, N_, N_, N_,
+		N_, N_, N_, N_, N_, N_, N_, N_,
+	},
+	{
+		0,  N_, N_, N_, N_, N_, N_, N_,
+		N_, N_, N_, N_, N_, N_, N_, N_,
+		N_, N_, N_, N_, N_, N_, N_, N_,
+		N_, N_, N_, N_, N_, N_, N_, N_,
+		N_, N_, N_, N_, N_, N_, N_, N_,
+		N_, N_, N_, N_, N_, N_, N_, N_,
+		N_, N_, N_, N_, N_, N_, N_, N_,
+		N_, N_, N_, N_, N_, N_, N_, N_,
+		N_, N_, N_, N_, N_, N_, N_, N_,
+		N_, N_, N_, N_, N_, N_, N_, N_,
+		N_, N_, N_, N_, N_, N_, N_, N_,
+		N_, N_, N_, N_, N_, N_, N_, N_,
+		N_, N_, N_, N_, N_, N_, N_, N_,
+		N_, N_, N_, N_, N_, N_, N_, N_,
+		N_, N_, N_, N_, N_, N_, N_, N_,
+		N_, N_, N_, N_, N_, N_, N_, N_,
+		N_, N_, N_, N_, N_, N_, N_, N_,
+		N_, N_, N_, N_, N_, N_, N_, N_,
+		N_, N_, N_, N_, N_, N_, N_, N_,
+		N_, N_, N_, N_, N_, N_, N_, N_,
+		N_, N_, N_, N_, N_, N_, N_, N_,
+		N_, N_, N_, N_, N_, N_, N_, N_,
+		N_, N_, N_, N_, N_, N_, N_, N_,
+		N_, N_, N_, N_, N_, N_, N_, N_,
+		N_, N_, N_, N_, N_, N_, N_, N_,
+		N_, N_, N_, N_, N_, N_, N_, N_,
+		N_, N_, N_, N_, N_, N_, N_, N_,
+		N_, N_, N_, N_, N_, N_, N_, N_,
+		N_, N_, N_, N_, N_, N_, N_, N_,
+		N_, N_, N_, N_, N_, N_, N_, N_,
+		N_, N_, N_, N_, N_, N_, N_, N_,
+		N_, N_, N_, N_, N_, N_, N_, N_,
+	},
+};
+
+static const uchar_t u8_composition_b2_tbl[2][1][256] = {
+	{
+		{
+			0,  N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			1,  2,  3,  4,  N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+		},
+
+	},
+	{
+		{
+			0,  N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			1,  2,  3,  4,  N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+		},
+
+	},
+
+};
+
+static const u8_displacement_t u8_composition_b3_tbl[2][5][256] = {
+	{
+		{	/* Third byte table 0. */
+			{ 0x8000, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { 0, 2470 },
+			{ 0x8001, 2491 }, { 1, 2871 }, { 2, 2959 },
+			{ 3, 3061 }, { 4, 3212 }, { 5, 3226 },
+			{ N_, 0 }, { 6, 3270 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { 0x8002, 3277 },
+			{ 7, 3774 }, { 8, 3949 }, { 9, 4198 },
+			{ N_, 0 }, { 10, 4265 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ 11, 4293 }, { 12, 4312 }, { N_, 0 },
+			{ 13, 4326 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 },
+		},
+		{	/* Third byte table 1. */
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { 14, 4347 },
+			{ N_, 0 }, { N_, 0 }, { 15, 4374 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { 16, 4391 },
+			{ 17, 4416 }, { 18, 4425 }, { N_, 0 },
+			{ 19, 4451 }, { 20, 4460 }, { 21, 4469 },
+			{ N_, 0 }, { 22, 4503 }, { N_, 0 },
+			{ 23, 4529 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 },
+		},
+		{	/* Third byte table 2. */
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { 24, 4563 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { 25, 4572 }, { 26, 4588 },
+			{ 27, 4620 }, { 28, 4666 }, { 0x8003, 4682 },
+			{ 0x8004, 5254 }, { 29, 5616 }, { 30, 5646 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 },
+		},
+		{	/* Third byte table 3. */
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { 31, 5684 },
+			{ 32, 5708 }, { 33, 5732 }, { 34, 5780 },
+			{ 35, 5900 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 },
+		},
+		{	/* Third byte table 4. */
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ 36, 6012 }, { 37, 6241 }, { 38, 6358 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 },
+		},
+	},
+	{
+		{	/* Third byte table 0. */
+			{ 0x8000, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { 0, 2470 },
+			{ 0x8001, 2491 }, { 1, 2871 }, { 2, 2959 },
+			{ 3, 3061 }, { 4, 3212 }, { 5, 3226 },
+			{ N_, 0 }, { 6, 3270 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { 0x8002, 3277 },
+			{ 7, 3774 }, { 8, 3949 }, { 9, 4198 },
+			{ N_, 0 }, { 10, 4265 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ 11, 4293 }, { 12, 4312 }, { N_, 0 },
+			{ 13, 4326 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 },
+		},
+		{	/* Third byte table 1. */
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { 14, 4347 },
+			{ N_, 0 }, { N_, 0 }, { 15, 4374 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { 16, 4391 },
+			{ 17, 4416 }, { 18, 4425 }, { N_, 0 },
+			{ 19, 4451 }, { 20, 4460 }, { 21, 4469 },
+			{ N_, 0 }, { 22, 4503 }, { N_, 0 },
+			{ 23, 4529 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 },
+		},
+		{	/* Third byte table 2. */
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { 24, 4563 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { 25, 4572 }, { 26, 4662 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { 27, 4671 }, { 28, 4687 },
+			{ 29, 4719 }, { 30, 4765 }, { 0x8003, 4781 },
+			{ 0x8004, 5353 }, { 31, 5715 }, { 32, 5745 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 },
+		},
+		{	/* Third byte table 3. */
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { 33, 5783 },
+			{ 34, 5807 }, { 35, 5831 }, { 36, 5879 },
+			{ 37, 5999 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 },
+		},
+		{	/* Third byte table 4. */
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ 38, 6111 }, { 39, 6340 }, { 40, 6457 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 },
+		},
+	},
+};
+
+static const uchar_t u8_composition_b4_tbl[2][41][257] = {
+	{
+		{	/* Fourth byte table 0. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,
+		},
+		{	/* Fourth byte table 1. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   29,  58,  58,  58,  58,
+			58,  58,  58,  58,  58,  58,  58,  58,
+			58,  58,  58,  73,  88,  88,  88,  88,
+			88,  88,  88,  88,  88,  88,  88,  88,
+			88,  88,  88,  88,  88,  88,  88,  88,
+			88,  88,  88,  88,  88,  88,  88,  88,
+			88,  88,  88,  88,  88,  88,  88,  88,
+			88,  88,  88,  88,  88,  88,  88,  88,
+			88,  88,  88,  88,  88,  88,  88,  88,
+			88,  88,  88,  88,  88,  88,  88,  88,
+			88,  88,  88,  88,  88,  88,  88,  88,
+			88,  88,  88,  88,  88,  88,  88,  88,
+			88,  88,  88,  88,  88,  88,  88,  88,
+			88,  88,  88,  88,  88,  88,  88,  88,
+			88,  88,  88,  88,  88,  88,  88,  88,
+			88,  88,  88,  88,  88,  88,  88,  88,
+			88,
+		},
+		{	/* Fourth byte table 2. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   15,  30,  30,
+			30,  30,  30,  30,  30,  30,  30,  30,
+			30,  30,  30,  38,  46,  46,  46,  46,
+			46,  54,  62,  62,  62,  62,  62,  62,
+			62,  70,  78,  86,  94,  94,  94,  94,
+			94,  94,  94,  94,  94,  94,  94,  94,
+			94,  94,  94,  94,  94,  94,  94,  94,
+			102, 102, 102, 102, 102, 102, 102, 102,
+			102, 102, 102, 102, 102, 102, 102, 102,
+			102, 102, 102, 102, 102, 102, 102, 102,
+			102, 102, 102, 102, 102, 102, 102, 102,
+			102, 102, 102, 102, 102, 102, 102, 102,
+			102, 102, 102, 102, 102, 102, 102, 102,
+			102, 102, 102, 102, 102, 102, 102, 102,
+			102, 102, 102, 102, 102, 102, 102, 102,
+			102,
+		},
+		{	/* Fourth byte table 3. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   36,  72,  72,  72,  72,  72,  72,
+			72,  72,  72,  72,  72,  72,  72,  72,
+			108, 144, 144, 144, 144, 144, 144, 144,
+			151, 151, 151, 151, 151, 151, 151, 151,
+			151, 151, 151, 151, 151, 151, 151, 151,
+			151, 151, 151, 151, 151, 151, 151, 151,
+			151, 151, 151, 151, 151, 151, 151, 151,
+			151, 151, 151, 151, 151, 151, 151, 151,
+			151, 151, 151, 151, 151, 151, 151, 151,
+			151, 151, 151, 151, 151, 151, 151, 151,
+			151, 151, 151, 151, 151, 151, 151, 151,
+			151, 151, 151, 151, 151, 151, 151, 151,
+			151,
+		},
+		{	/* Fourth byte table 4. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   7,   14,  14,  14,  14,
+			14,  14,  14,  14,  14,  14,  14,  14,
+			14,  14,  14,  14,  14,  14,  14,  14,
+			14,  14,  14,  14,  14,  14,  14,  14,
+			14,  14,  14,  14,  14,  14,  14,  14,
+			14,  14,  14,  14,  14,  14,  14,  14,
+			14,  14,  14,  14,  14,  14,  14,  14,
+			14,  14,  14,  14,  14,  14,  14,  14,
+			14,  14,  14,  14,  14,  14,  14,  14,
+			14,  14,  14,  14,  14,  14,  14,  14,
+			14,  14,  14,  14,  14,  14,  14,  14,
+			14,
+		},
+		{	/* Fourth byte table 5. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   7,
+			14,  22,  30,  30,  30,  30,  30,  37,
+			44,  44,  44,  44,  44,  44,  44,  44,
+			44,  44,  44,  44,  44,  44,  44,  44,
+			44,  44,  44,  44,  44,  44,  44,  44,
+			44,  44,  44,  44,  44,  44,  44,  44,
+			44,  44,  44,  44,  44,  44,  44,  44,
+			44,  44,  44,  44,  44,  44,  44,  44,
+			44,  44,  44,  44,  44,  44,  44,  44,
+			44,  44,  44,  44,  44,  44,  44,  44,
+			44,  44,  44,  44,  44,  44,  44,  44,
+			44,  44,  44,  44,  44,  44,  44,  44,
+			44,
+		},
+		{	/* Fourth byte table 6. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   7,   7,   7,   7,   7,
+			7,   7,   7,   7,   7,   7,   7,   7,
+			7,   7,   7,   7,   7,   7,   7,   7,
+			7,   7,   7,   7,   7,   7,   7,   7,
+			7,   7,   7,   7,   7,   7,   7,   7,
+			7,   7,   7,   7,   7,   7,   7,   7,
+			7,   7,   7,   7,   7,   7,   7,   7,
+			7,   7,   7,   7,   7,   7,   7,   7,
+			7,   7,   7,   7,   7,   7,   7,   7,
+			7,   7,   7,   7,   7,   7,   7,   7,
+			7,   7,   7,   7,   7,   7,   7,   7,
+			7,   7,   7,   7,   7,   7,   7,   7,
+			7,   7,   7,   7,   7,   7,   7,   7,
+			7,   7,   7,   7,   7,   7,   7,   7,
+			7,
+		},
+		{	/* Fourth byte table 7. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   15,  15,  15,  15,  70,  70,
+			70,  70,  112, 133, 154, 154, 154, 162,
+			162, 162, 162, 175, 175, 175, 175, 175,
+			175, 175, 175, 175, 175, 175, 175, 175,
+			175, 175, 175, 175, 175, 175, 175, 175,
+			175, 175, 175, 175, 175, 175, 175, 175,
+			175, 175, 175, 175, 175, 175, 175, 175,
+			175, 175, 175, 175, 175, 175, 175, 175,
+			175, 175, 175, 175, 175, 175, 175, 175,
+			175, 175, 175, 175, 175, 175, 175, 175,
+			175, 175, 175, 175, 175, 175, 175, 175,
+			175, 175, 175, 175, 175, 175, 175, 175,
+			175, 175, 175, 175, 175, 175, 175, 175,
+			175, 175, 175, 175, 175, 175, 175, 175,
+			175, 175, 175, 175, 175, 175, 175, 175,
+			175, 175, 175, 175, 175, 175, 175, 175,
+			175,
+		},
+		{	/* Fourth byte table 8. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   7,
+			7,   7,   7,   7,   7,   7,   7,   7,
+			7,   20,  20,  20,  27,  27,  46,  59,
+			66,  91,  91,  98,  98,  98,  98,  105,
+			105, 105, 105, 105, 130, 130, 130, 130,
+			137, 137, 137, 137, 144, 144, 151, 151,
+			151, 164, 164, 164, 171, 171, 190, 203,
+			210, 235, 235, 242, 242, 242, 242, 249,
+			249, 249, 249, 249, 249, 249, 249, 249,
+			249, 249, 249, 249, 249, 249, 249, 249,
+			249, 249, 249, 249, 249, 249, 249, 249,
+			249, 249, 249, 249, 249, 249, 249, 249,
+			249, 249, 249, 249, 249, 249, 249, 249,
+			249, 249, 249, 249, 249, 249, 249, 249,
+			249, 249, 249, 249, 249, 249, 249, 249,
+			249, 249, 249, 249, 249, 249, 249, 249,
+			249,
+		},
+		{	/* Fourth byte table 9. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   25,  25,  25,  25,
+			32,  32,  32,  32,  39,  39,  46,  46,
+			46,  46,  46,  46,  46,  46,  46,  53,
+			53,  53,  53,  53,  53,  53,  53,  53,
+			53,  53,  53,  53,  53,  53,  53,  53,
+			53,  53,  53,  53,  53,  53,  53,  53,
+			53,  53,  53,  53,  53,  60,  67,  67,
+			67,  67,  67,  67,  67,  67,  67,  67,
+			67,  67,  67,  67,  67,  67,  67,  67,
+			67,  67,  67,  67,  67,  67,  67,  67,
+			67,  67,  67,  67,  67,  67,  67,  67,
+			67,  67,  67,  67,  67,  67,  67,  67,
+			67,  67,  67,  67,  67,  67,  67,  67,
+			67,  67,  67,  67,  67,  67,  67,  67,
+			67,  67,  67,  67,  67,  67,  67,  67,
+			67,  67,  67,  67,  67,  67,  67,  67,
+			67,
+		},
+		{	/* Fourth byte table 10. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   7,   14,  14,  14,  14,  14,  14,
+			14,  14,  14,  14,  14,  14,  14,  14,
+			14,  21,  28,  28,  28,  28,  28,  28,
+			28,  28,  28,  28,  28,  28,  28,  28,
+			28,  28,  28,  28,  28,  28,  28,  28,
+			28,  28,  28,  28,  28,  28,  28,  28,
+			28,  28,  28,  28,  28,  28,  28,  28,
+			28,  28,  28,  28,  28,  28,  28,  28,
+			28,  28,  28,  28,  28,  28,  28,  28,
+			28,  28,  28,  28,  28,  28,  28,  28,
+			28,  28,  28,  28,  28,  28,  28,  28,
+			28,  28,  28,  28,  28,  28,  28,  28,
+			28,  28,  28,  28,  28,  28,  28,  28,
+			28,
+		},
+		{	/* Fourth byte table 11. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			19,  19,  19,  19,  19,  19,  19,  19,
+			19,  19,  19,  19,  19,  19,  19,  19,
+			19,  19,  19,  19,  19,  19,  19,  19,
+			19,  19,  19,  19,  19,  19,  19,  19,
+			19,  19,  19,  19,  19,  19,  19,  19,
+			19,  19,  19,  19,  19,  19,  19,  19,
+			19,  19,  19,  19,  19,  19,  19,  19,
+			19,  19,  19,  19,  19,  19,  19,  19,
+			19,  19,  19,  19,  19,  19,  19,  19,
+			19,  19,  19,  19,  19,  19,  19,  19,
+			19,  19,  19,  19,  19,  19,  19,  19,
+			19,
+		},
+		{	/* Fourth byte table 12. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   7,   7,   14,  14,  14,  14,  14,
+			14,  14,  14,  14,  14,  14,  14,  14,
+			14,  14,  14,  14,  14,  14,  14,  14,
+			14,  14,  14,  14,  14,  14,  14,  14,
+			14,  14,  14,  14,  14,  14,  14,  14,
+			14,  14,  14,  14,  14,  14,  14,  14,
+			14,  14,  14,  14,  14,  14,  14,  14,
+			14,  14,  14,  14,  14,  14,  14,  14,
+			14,  14,  14,  14,  14,  14,  14,  14,
+			14,  14,  14,  14,  14,  14,  14,  14,
+			14,  14,  14,  14,  14,  14,  14,  14,
+			14,  14,  14,  14,  14,  14,  14,  14,
+			14,  14,  14,  14,  14,  14,  14,  14,
+			14,  14,  14,  14,  14,  14,  14,  14,
+			14,  14,  14,  14,  14,  14,  14,  14,
+			14,
+		},
+		{	/* Fourth byte table 13. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   7,   7,   7,   7,   7,   7,
+			7,   7,   7,   7,   7,   7,   7,   7,
+			7,   7,   7,   14,  14,  14,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,
+		},
+		{	/* Fourth byte table 14. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   9,   9,   9,   9,   9,   9,   9,
+			9,   18,  18,  18,  27,  27,  27,  27,
+			27,  27,  27,  27,  27,  27,  27,  27,
+			27,  27,  27,  27,  27,  27,  27,  27,
+			27,  27,  27,  27,  27,  27,  27,  27,
+			27,  27,  27,  27,  27,  27,  27,  27,
+			27,  27,  27,  27,  27,  27,  27,  27,
+			27,  27,  27,  27,  27,  27,  27,  27,
+			27,  27,  27,  27,  27,  27,  27,  27,
+			27,  27,  27,  27,  27,  27,  27,  27,
+			27,  27,  27,  27,  27,  27,  27,  27,
+			27,
+		},
+		{	/* Fourth byte table 15. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			17,  17,  17,  17,  17,  17,  17,  17,
+			17,  17,  17,  17,  17,  17,  17,  17,
+			17,  17,  17,  17,  17,  17,  17,  17,
+			17,  17,  17,  17,  17,  17,  17,  17,
+			17,  17,  17,  17,  17,  17,  17,  17,
+			17,  17,  17,  17,  17,  17,  17,  17,
+			17,  17,  17,  17,  17,  17,  17,  17,
+			17,  17,  17,  17,  17,  17,  17,  17,
+			17,  17,  17,  17,  17,  17,  17,  17,
+			17,  17,  17,  17,  17,  17,  17,  17,
+			17,  17,  17,  17,  17,  17,  17,  17,
+			17,  17,  17,  17,  17,  17,  17,  17,
+			17,  17,  17,  17,  17,  17,  17,  17,
+			17,  17,  17,  17,  17,  17,  17,  17,
+			17,  17,  17,  17,  17,  17,  17,  17,
+			17,
+		},
+		{	/* Fourth byte table 16. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			25,  25,  25,  25,  25,  25,  25,  25,
+			25,  25,  25,  25,  25,  25,  25,  25,
+			25,  25,  25,  25,  25,  25,  25,  25,
+			25,  25,  25,  25,  25,  25,  25,  25,
+			25,  25,  25,  25,  25,  25,  25,  25,
+			25,  25,  25,  25,  25,  25,  25,  25,
+			25,  25,  25,  25,  25,  25,  25,  25,
+			25,  25,  25,  25,  25,  25,  25,  25,
+			25,  25,  25,  25,  25,  25,  25,  25,
+			25,  25,  25,  25,  25,  25,  25,  25,
+			25,  25,  25,  25,  25,  25,  25,  25,
+			25,  25,  25,  25,  25,  25,  25,  25,
+			25,  25,  25,  25,  25,  25,  25,  25,
+			25,  25,  25,  25,  25,  25,  25,  25,
+			25,  25,  25,  25,  25,  25,  25,  25,
+			25,
+		},
+		{	/* Fourth byte table 17. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   9,   9,   9,   9,   9,
+			9,   9,   9,   9,   9,   9,   9,   9,
+			9,   9,   9,   9,   9,   9,   9,   9,
+			9,   9,   9,   9,   9,   9,   9,   9,
+			9,   9,   9,   9,   9,   9,   9,   9,
+			9,   9,   9,   9,   9,   9,   9,   9,
+			9,   9,   9,   9,   9,   9,   9,   9,
+			9,   9,   9,   9,   9,   9,   9,   9,
+			9,   9,   9,   9,   9,   9,   9,   9,
+			9,   9,   9,   9,   9,   9,   9,   9,
+			9,   9,   9,   9,   9,   9,   9,   9,
+			9,   9,   9,   9,   9,   9,   9,   9,
+			9,   9,   9,   9,   9,   9,   9,   9,
+			9,   9,   9,   9,   9,   9,   9,   9,
+			9,
+		},
+		{	/* Fourth byte table 18. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   17,
+			26,  26,  26,  26,  26,  26,  26,  26,
+			26,  26,  26,  26,  26,  26,  26,  26,
+			26,  26,  26,  26,  26,  26,  26,  26,
+			26,  26,  26,  26,  26,  26,  26,  26,
+			26,  26,  26,  26,  26,  26,  26,  26,
+			26,  26,  26,  26,  26,  26,  26,  26,
+			26,  26,  26,  26,  26,  26,  26,  26,
+			26,  26,  26,  26,  26,  26,  26,  26,
+			26,  26,  26,  26,  26,  26,  26,  26,
+			26,  26,  26,  26,  26,  26,  26,  26,
+			26,  26,  26,  26,  26,  26,  26,  26,
+			26,  26,  26,  26,  26,  26,  26,  26,
+			26,  26,  26,  26,  26,  26,  26,  26,
+			26,  26,  26,  26,  26,  26,  26,  26,
+			26,  26,  26,  26,  26,  26,  26,  26,
+			26,
+		},
+		{	/* Fourth byte table 19. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   9,
+			9,   9,   9,   9,   9,   9,   9,   9,
+			9,   9,   9,   9,   9,   9,   9,   9,
+			9,   9,   9,   9,   9,   9,   9,   9,
+			9,   9,   9,   9,   9,   9,   9,   9,
+			9,   9,   9,   9,   9,   9,   9,   9,
+			9,   9,   9,   9,   9,   9,   9,   9,
+			9,   9,   9,   9,   9,   9,   9,   9,
+			9,   9,   9,   9,   9,   9,   9,   9,
+			9,   9,   9,   9,   9,   9,   9,   9,
+			9,   9,   9,   9,   9,   9,   9,   9,
+			9,   9,   9,   9,   9,   9,   9,   9,
+			9,   9,   9,   9,   9,   9,   9,   9,
+			9,   9,   9,   9,   9,   9,   9,   9,
+			9,   9,   9,   9,   9,   9,   9,   9,
+			9,   9,   9,   9,   9,   9,   9,   9,
+			9,
+		},
+		{	/* Fourth byte table 20. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			9,   9,   9,   9,   9,   9,   9,   9,
+			9,   9,   9,   9,   9,   9,   9,   9,
+			9,   9,   9,   9,   9,   9,   9,   9,
+			9,   9,   9,   9,   9,   9,   9,   9,
+			9,   9,   9,   9,   9,   9,   9,   9,
+			9,   9,   9,   9,   9,   9,   9,   9,
+			9,   9,   9,   9,   9,   9,   9,   9,
+			9,   9,   9,   9,   9,   9,   9,   9,
+			9,
+		},
+		{	/* Fourth byte table 21. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   25,
+			25,  25,  25,  34,  34,  34,  34,  34,
+			34,  34,  34,  34,  34,  34,  34,  34,
+			34,  34,  34,  34,  34,  34,  34,  34,
+			34,  34,  34,  34,  34,  34,  34,  34,
+			34,  34,  34,  34,  34,  34,  34,  34,
+			34,  34,  34,  34,  34,  34,  34,  34,
+			34,  34,  34,  34,  34,  34,  34,  34,
+			34,  34,  34,  34,  34,  34,  34,  34,
+			34,  34,  34,  34,  34,  34,  34,  34,
+			34,  34,  34,  34,  34,  34,  34,  34,
+			34,  34,  34,  34,  34,  34,  34,  34,
+			34,  34,  34,  34,  34,  34,  34,  34,
+			34,  34,  34,  34,  34,  34,  34,  34,
+			34,  34,  34,  34,  34,  34,  34,  34,
+			34,  34,  34,  34,  34,  34,  34,  34,
+			34,
+		},
+		{	/* Fourth byte table 22. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   17,
+			26,  26,  26,  26,  26,  26,  26,  26,
+			26,  26,  26,  26,  26,  26,  26,  26,
+			26,  26,  26,  26,  26,  26,  26,  26,
+			26,  26,  26,  26,  26,  26,  26,  26,
+			26,  26,  26,  26,  26,  26,  26,  26,
+			26,  26,  26,  26,  26,  26,  26,  26,
+			26,  26,  26,  26,  26,  26,  26,  26,
+			26,  26,  26,  26,  26,  26,  26,  26,
+			26,  26,  26,  26,  26,  26,  26,  26,
+			26,  26,  26,  26,  26,  26,  26,  26,
+			26,  26,  26,  26,  26,  26,  26,  26,
+			26,  26,  26,  26,  26,  26,  26,  26,
+			26,  26,  26,  26,  26,  26,  26,  26,
+			26,  26,  26,  26,  26,  26,  26,  26,
+			26,  26,  26,  26,  26,  26,  26,  26,
+			26,
+		},
+		{	/* Fourth byte table 23. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   25,  25,  25,  34,  34,  34,
+			34,  34,  34,  34,  34,  34,  34,  34,
+			34,  34,  34,  34,  34,  34,  34,  34,
+			34,  34,  34,  34,  34,  34,  34,  34,
+			34,  34,  34,  34,  34,  34,  34,  34,
+			34,  34,  34,  34,  34,  34,  34,  34,
+			34,  34,  34,  34,  34,  34,  34,  34,
+			34,  34,  34,  34,  34,  34,  34,  34,
+			34,  34,  34,  34,  34,  34,  34,  34,
+			34,  34,  34,  34,  34,  34,  34,  34,
+			34,  34,  34,  34,  34,  34,  34,  34,
+			34,  34,  34,  34,  34,  34,  34,  34,
+			34,  34,  34,  34,  34,  34,  34,  34,
+			34,
+		},
+		{	/* Fourth byte table 24. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   9,   9,
+			9,   9,   9,   9,   9,   9,   9,   9,
+			9,   9,   9,   9,   9,   9,   9,   9,
+			9,   9,   9,   9,   9,   9,   9,   9,
+			9,   9,   9,   9,   9,   9,   9,   9,
+			9,   9,   9,   9,   9,   9,   9,   9,
+			9,   9,   9,   9,   9,   9,   9,   9,
+			9,   9,   9,   9,   9,   9,   9,   9,
+			9,   9,   9,   9,   9,   9,   9,   9,
+			9,   9,   9,   9,   9,   9,   9,   9,
+			9,   9,   9,   9,   9,   9,   9,   9,
+			9,   9,   9,   9,   9,   9,   9,   9,
+			9,
+		},
+		{	/* Fourth byte table 25. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   8,
+			16,  16,  16,  16,  16,  16,  16,  16,
+			16,  16,  16,  16,  16,  16,  16,  16,
+			16,  16,  16,  16,  16,  16,  16,  16,
+			16,  16,  16,  16,  16,  16,  16,  16,
+			16,  16,  16,  16,  16,  16,  16,  16,
+			16,  16,  16,  16,  16,  16,  16,  16,
+			16,  16,  16,  16,  16,  16,  16,  16,
+			16,  16,  16,  16,  16,  16,  16,  16,
+			16,  16,  16,  16,  16,  16,  16,  16,
+			16,
+		},
+		{	/* Fourth byte table 26. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   8,   16,  16,  16,  16,
+			16,  16,  16,  24,  32,  32,  32,  32,
+			32,  32,  32,  32,  32,  32,  32,  32,
+			32,  32,  32,  32,  32,  32,  32,  32,
+			32,  32,  32,  32,  32,  32,  32,  32,
+			32,  32,  32,  32,  32,  32,  32,  32,
+			32,  32,  32,  32,  32,  32,  32,  32,
+			32,  32,  32,  32,  32,  32,  32,  32,
+			32,  32,  32,  32,  32,  32,  32,  32,
+			32,  32,  32,  32,  32,  32,  32,  32,
+			32,  32,  32,  32,  32,  32,  32,  32,
+			32,  32,  32,  32,  32,  32,  32,  32,
+			32,  32,  32,  32,  32,  32,  32,  32,
+			32,
+		},
+		{	/* Fourth byte table 27. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   15,  30,  30,  30,  30,  30,  30,
+			30,  30,  30,  30,  30,  30,  30,  30,
+			30,  30,  30,  30,  30,  30,  30,  30,
+			30,  38,  46,  46,  46,  46,  46,  46,
+			46,  46,  46,  46,  46,  46,  46,  46,
+			46,  46,  46,  46,  46,  46,  46,  46,
+			46,  46,  46,  46,  46,  46,  46,  46,
+			46,  46,  46,  46,  46,  46,  46,  46,
+			46,  46,  46,  46,  46,  46,  46,  46,
+			46,  46,  46,  46,  46,  46,  46,  46,
+			46,  46,  46,  46,  46,  46,  46,  46,
+			46,  46,  46,  46,  46,  46,  46,  46,
+			46,
+		},
+		{	/* Fourth byte table 28. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   8,   16,  16,
+			16,  16,  16,  16,  16,  16,  16,  16,
+			16,  16,  16,  16,  16,  16,  16,  16,
+			16,  16,  16,  16,  16,  16,  16,  16,
+			16,  16,  16,  16,  16,  16,  16,  16,
+			16,  16,  16,  16,  16,  16,  16,  16,
+			16,  16,  16,  16,  16,  16,  16,  16,
+			16,  16,  16,  16,  16,  16,  16,  16,
+			16,  16,  16,  16,  16,  16,  16,  16,
+			16,  16,  16,  16,  16,  16,  16,  16,
+			16,  16,  16,  16,  16,  16,  16,  16,
+			16,  16,  16,  16,  16,  16,  16,  16,
+			16,  16,  16,  16,  16,  16,  16,  16,
+			16,  16,  16,  16,  16,  16,  16,  16,
+			16,  16,  16,  16,  16,  16,  16,  16,
+			16,
+		},
+		{	/* Fourth byte table 29. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   8,
+			8,   8,   8,   8,   8,   8,   8,   8,
+			30,  30,  30,  30,  30,  30,  30,  30,
+			30,  30,  30,  30,  30,  30,  30,  30,
+			30,  30,  30,  30,  30,  30,  30,  30,
+			30,  30,  30,  30,  30,  30,  30,  30,
+			30,  30,  30,  30,  30,  30,  30,  30,
+			30,  30,  30,  30,  30,  30,  30,  30,
+			30,  30,  30,  30,  30,  30,  30,  30,
+			30,  30,  30,  30,  30,  30,  30,  30,
+			30,
+		},
+		{	/* Fourth byte table 30. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   8,
+			8,   8,   8,   8,   8,   8,   8,   8,
+			8,   8,   8,   8,   8,   8,   8,   8,
+			8,   8,   8,   8,   8,   8,   8,   8,
+			8,   8,   8,   8,   8,   8,   8,   8,
+			8,   8,   8,   8,   8,   8,   8,   8,
+			8,   8,   8,   8,   8,   8,   8,   16,
+			16,  16,  16,  16,  16,  16,  16,  38,
+			38,  38,  38,  38,  38,  38,  38,  38,
+			38,  38,  38,  38,  38,  38,  38,  38,
+			38,  38,  38,  38,  38,  38,  38,  38,
+			38,  38,  38,  38,  38,  38,  38,  38,
+			38,  38,  38,  38,  38,  38,  38,  38,
+			38,  38,  38,  38,  38,  38,  38,  38,
+			38,  38,  38,  38,  38,  38,  38,  38,
+			38,  38,  38,  38,  38,  38,  38,  38,
+			38,
+		},
+		{	/* Fourth byte table 31. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   8,   8,   16,  16,  24,  24,  24,
+			24,  24,  24,  24,  24,  24,  24,  24,
+			24,  24,  24,  24,  24,  24,  24,  24,
+			24,  24,  24,  24,  24,  24,  24,  24,
+			24,  24,  24,  24,  24,  24,  24,  24,
+			24,  24,  24,  24,  24,  24,  24,  24,
+			24,  24,  24,  24,  24,  24,  24,  24,
+			24,  24,  24,  24,  24,  24,  24,  24,
+			24,  24,  24,  24,  24,  24,  24,  24,
+			24,  24,  24,  24,  24,  24,  24,  24,
+			24,  24,  24,  24,  24,  24,  24,  24,
+			24,  24,  24,  24,  24,  24,  24,  24,
+			24,  24,  24,  24,  24,  24,  24,  24,
+			24,  24,  24,  24,  24,  24,  24,  24,
+			24,
+		},
+		{	/* Fourth byte table 32. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   8,   8,   16,  16,  24,  24,  24,
+			24,  24,  24,  24,  24,  24,  24,  24,
+			24,  24,  24,  24,  24,  24,  24,  24,
+			24,  24,  24,  24,  24,  24,  24,  24,
+			24,  24,  24,  24,  24,  24,  24,  24,
+			24,  24,  24,  24,  24,  24,  24,  24,
+			24,  24,  24,  24,  24,  24,  24,  24,
+			24,  24,  24,  24,  24,  24,  24,  24,
+			24,  24,  24,  24,  24,  24,  24,  24,
+			24,  24,  24,  24,  24,  24,  24,  24,
+			24,  24,  24,  24,  24,  24,  24,  24,
+			24,  24,  24,  24,  24,  24,  24,  24,
+			24,  24,  24,  24,  24,  24,  24,  24,
+			24,  24,  24,  24,  24,  24,  24,  24,
+			24,
+		},
+		{	/* Fourth byte table 33. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   8,   8,   8,   8,
+			8,   16,  16,  16,  24,  24,  24,  24,
+			24,  24,  24,  24,  24,  24,  24,  24,
+			24,  24,  24,  24,  24,  24,  24,  24,
+			24,  24,  24,  24,  32,  32,  40,  40,
+			40,  40,  40,  40,  40,  40,  40,  40,
+			40,  40,  40,  40,  40,  40,  40,  40,
+			40,  40,  40,  40,  40,  48,  48,  48,
+			48,  48,  48,  48,  48,  48,  48,  48,
+			48,  48,  48,  48,  48,  48,  48,  48,
+			48,  48,  48,  48,  48,  48,  48,  48,
+			48,  48,  48,  48,  48,  48,  48,  48,
+			48,  48,  48,  48,  48,  48,  48,  48,
+			48,  48,  48,  48,  48,  48,  48,  48,
+			48,  48,  48,  48,  48,  48,  48,  48,
+			48,  48,  48,  48,  48,  48,  48,  48,
+			48,
+		},
+		{	/* Fourth byte table 34. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   8,   8,   16,  16,
+			16,  24,  24,  24,  24,  24,  32,  32,
+			32,  32,  32,  32,  32,  32,  32,  32,
+			32,  32,  32,  32,  32,  32,  32,  32,
+			32,  32,  40,  40,  40,  48,  56,  56,
+			56,  56,  56,  56,  56,  56,  56,  56,
+			56,  56,  56,  64,  72,  72,  72,  80,
+			88,  88,  88,  96,  104, 112, 120, 120,
+			120, 120, 120, 120, 120, 120, 120, 120,
+			120, 120, 120, 120, 120, 120, 120, 120,
+			120, 120, 120, 120, 120, 120, 120, 120,
+			120, 120, 120, 120, 120, 120, 120, 120,
+			120, 120, 120, 120, 120, 120, 120, 120,
+			120, 120, 120, 120, 120, 120, 120, 120,
+			120, 120, 120, 120, 120, 120, 120, 120,
+			120, 120, 120, 120, 120, 120, 120, 120,
+			120,
+		},
+		{	/* Fourth byte table 35. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   8,   16,  16,  16,  24,
+			32,  32,  32,  32,  32,  32,  32,  32,
+			32,  32,  40,  48,  48,  48,  48,  48,
+			48,  48,  48,  48,  48,  48,  48,  48,
+			48,  48,  48,  56,  56,  56,  56,  56,
+			56,  64,  72,  72,  80,  80,  80,  80,
+			80,  80,  80,  88,  96,  104, 112, 112,
+			112, 112, 112, 112, 112, 112, 112, 112,
+			112, 112, 112, 112, 112, 112, 112, 112,
+			112, 112, 112, 112, 112, 112, 112, 112,
+			112, 112, 112, 112, 112, 112, 112, 112,
+			112, 112, 112, 112, 112, 112, 112, 112,
+			112, 112, 112, 112, 112, 112, 112, 112,
+			112, 112, 112, 112, 112, 112, 112, 112,
+			112, 112, 112, 112, 112, 112, 112, 112,
+			112, 112, 112, 112, 112, 112, 112, 112,
+			112,
+		},
+		{	/* Fourth byte table 36. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   9,
+			9,   9,   9,   9,   18,  18,  27,  27,
+			36,  36,  45,  45,  54,  54,  63,  63,
+			72,  72,  81,  81,  90,  90,  99,  99,
+			108, 108, 117, 117, 117, 126, 126, 135,
+			135, 144, 144, 144, 144, 144, 144, 144,
+			161, 161, 161, 178, 178, 178, 195, 195,
+			195, 212, 212, 212, 229, 229, 229, 229,
+			229, 229, 229, 229, 229, 229, 229, 229,
+			229, 229, 229, 229, 229, 229, 229, 229,
+			229, 229, 229, 229, 229, 229, 229, 229,
+			229, 229, 229, 229, 229, 229, 229, 229,
+			229, 229, 229, 229, 229, 229, 229, 229,
+			229, 229, 229, 229, 229, 229, 229, 229,
+			229, 229, 229, 229, 229, 229, 229, 229,
+			229, 229, 229, 229, 229, 229, 229, 229,
+			229,
+		},
+		{	/* Fourth byte table 37. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   9,   9,
+			9,   9,   9,   9,   9,   9,   9,   18,
+			18,  18,  18,  18,  27,  27,  36,  36,
+			45,  45,  54,  54,  63,  63,  72,  72,
+			81,  81,  90,  90,  99,  99,  108, 108,
+			117, 117, 117, 117, 117, 117, 117, 117,
+			117, 117, 117, 117, 117, 117, 117, 117,
+			117, 117, 117, 117, 117, 117, 117, 117,
+			117, 117, 117, 117, 117, 117, 117, 117,
+			117, 117, 117, 117, 117, 117, 117, 117,
+			117, 117, 117, 117, 117, 117, 117, 117,
+			117, 117, 117, 117, 117, 117, 117, 117,
+			117, 117, 117, 117, 117, 117, 117, 117,
+			117,
+		},
+		{	/* Fourth byte table 38. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   9,   9,   9,   18,  18,  27,
+			27,  36,  36,  36,  36,  36,  36,  36,
+			53,  53,  53,  70,  70,  70,  87,  87,
+			87,  104, 104, 104, 121, 121, 121, 121,
+			121, 121, 121, 121, 121, 121, 121, 121,
+			121, 121, 121, 121, 121, 121, 121, 121,
+			130, 139, 148, 157, 157, 157, 157, 157,
+			157, 157, 157, 157, 157, 157, 166, 166,
+			166, 166, 166, 166, 166, 166, 166, 166,
+			166, 166, 166, 166, 166, 166, 166, 166,
+			166, 166, 166, 166, 166, 166, 166, 166,
+			166, 166, 166, 166, 166, 166, 166, 166,
+			166, 166, 166, 166, 166, 166, 166, 166,
+			166, 166, 166, 166, 166, 166, 166, 166,
+			166, 166, 166, 166, 166, 166, 166, 166,
+			166, 166, 166, 166, 166, 166, 166, 166,
+			166,
+		},
+		{	/* Fourth byte table 39. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,
+		},
+		{	/* Fourth byte table 40. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,
+		},
+	},
+	{
+		{	/* Fourth byte table 0. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,
+		},
+		{	/* Fourth byte table 1. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   29,  58,  58,  58,  58,
+			58,  58,  58,  58,  58,  58,  58,  58,
+			58,  58,  58,  73,  88,  88,  88,  88,
+			88,  88,  88,  88,  88,  88,  88,  88,
+			88,  88,  88,  88,  88,  88,  88,  88,
+			88,  88,  88,  88,  88,  88,  88,  88,
+			88,  88,  88,  88,  88,  88,  88,  88,
+			88,  88,  88,  88,  88,  88,  88,  88,
+			88,  88,  88,  88,  88,  88,  88,  88,
+			88,  88,  88,  88,  88,  88,  88,  88,
+			88,  88,  88,  88,  88,  88,  88,  88,
+			88,  88,  88,  88,  88,  88,  88,  88,
+			88,  88,  88,  88,  88,  88,  88,  88,
+			88,  88,  88,  88,  88,  88,  88,  88,
+			88,  88,  88,  88,  88,  88,  88,  88,
+			88,  88,  88,  88,  88,  88,  88,  88,
+			88,
+		},
+		{	/* Fourth byte table 2. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   15,  30,  30,
+			30,  30,  30,  30,  30,  30,  30,  30,
+			30,  30,  30,  38,  46,  46,  46,  46,
+			46,  54,  62,  62,  62,  62,  62,  62,
+			62,  70,  78,  86,  94,  94,  94,  94,
+			94,  94,  94,  94,  94,  94,  94,  94,
+			94,  94,  94,  94,  94,  94,  94,  94,
+			102, 102, 102, 102, 102, 102, 102, 102,
+			102, 102, 102, 102, 102, 102, 102, 102,
+			102, 102, 102, 102, 102, 102, 102, 102,
+			102, 102, 102, 102, 102, 102, 102, 102,
+			102, 102, 102, 102, 102, 102, 102, 102,
+			102, 102, 102, 102, 102, 102, 102, 102,
+			102, 102, 102, 102, 102, 102, 102, 102,
+			102, 102, 102, 102, 102, 102, 102, 102,
+			102,
+		},
+		{	/* Fourth byte table 3. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   36,  72,  72,  72,  72,  72,  72,
+			72,  72,  72,  72,  72,  72,  72,  72,
+			108, 144, 144, 144, 144, 144, 144, 144,
+			151, 151, 151, 151, 151, 151, 151, 151,
+			151, 151, 151, 151, 151, 151, 151, 151,
+			151, 151, 151, 151, 151, 151, 151, 151,
+			151, 151, 151, 151, 151, 151, 151, 151,
+			151, 151, 151, 151, 151, 151, 151, 151,
+			151, 151, 151, 151, 151, 151, 151, 151,
+			151, 151, 151, 151, 151, 151, 151, 151,
+			151, 151, 151, 151, 151, 151, 151, 151,
+			151, 151, 151, 151, 151, 151, 151, 151,
+			151,
+		},
+		{	/* Fourth byte table 4. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   7,   14,  14,  14,  14,
+			14,  14,  14,  14,  14,  14,  14,  14,
+			14,  14,  14,  14,  14,  14,  14,  14,
+			14,  14,  14,  14,  14,  14,  14,  14,
+			14,  14,  14,  14,  14,  14,  14,  14,
+			14,  14,  14,  14,  14,  14,  14,  14,
+			14,  14,  14,  14,  14,  14,  14,  14,
+			14,  14,  14,  14,  14,  14,  14,  14,
+			14,  14,  14,  14,  14,  14,  14,  14,
+			14,  14,  14,  14,  14,  14,  14,  14,
+			14,  14,  14,  14,  14,  14,  14,  14,
+			14,
+		},
+		{	/* Fourth byte table 5. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   7,
+			14,  22,  30,  30,  30,  30,  30,  37,
+			44,  44,  44,  44,  44,  44,  44,  44,
+			44,  44,  44,  44,  44,  44,  44,  44,
+			44,  44,  44,  44,  44,  44,  44,  44,
+			44,  44,  44,  44,  44,  44,  44,  44,
+			44,  44,  44,  44,  44,  44,  44,  44,
+			44,  44,  44,  44,  44,  44,  44,  44,
+			44,  44,  44,  44,  44,  44,  44,  44,
+			44,  44,  44,  44,  44,  44,  44,  44,
+			44,  44,  44,  44,  44,  44,  44,  44,
+			44,  44,  44,  44,  44,  44,  44,  44,
+			44,
+		},
+		{	/* Fourth byte table 6. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   7,   7,   7,   7,   7,
+			7,   7,   7,   7,   7,   7,   7,   7,
+			7,   7,   7,   7,   7,   7,   7,   7,
+			7,   7,   7,   7,   7,   7,   7,   7,
+			7,   7,   7,   7,   7,   7,   7,   7,
+			7,   7,   7,   7,   7,   7,   7,   7,
+			7,   7,   7,   7,   7,   7,   7,   7,
+			7,   7,   7,   7,   7,   7,   7,   7,
+			7,   7,   7,   7,   7,   7,   7,   7,
+			7,   7,   7,   7,   7,   7,   7,   7,
+			7,   7,   7,   7,   7,   7,   7,   7,
+			7,   7,   7,   7,   7,   7,   7,   7,
+			7,   7,   7,   7,   7,   7,   7,   7,
+			7,   7,   7,   7,   7,   7,   7,   7,
+			7,
+		},
+		{	/* Fourth byte table 7. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   15,  15,  15,  15,  70,  70,
+			70,  70,  112, 133, 154, 154, 154, 162,
+			162, 162, 162, 175, 175, 175, 175, 175,
+			175, 175, 175, 175, 175, 175, 175, 175,
+			175, 175, 175, 175, 175, 175, 175, 175,
+			175, 175, 175, 175, 175, 175, 175, 175,
+			175, 175, 175, 175, 175, 175, 175, 175,
+			175, 175, 175, 175, 175, 175, 175, 175,
+			175, 175, 175, 175, 175, 175, 175, 175,
+			175, 175, 175, 175, 175, 175, 175, 175,
+			175, 175, 175, 175, 175, 175, 175, 175,
+			175, 175, 175, 175, 175, 175, 175, 175,
+			175, 175, 175, 175, 175, 175, 175, 175,
+			175, 175, 175, 175, 175, 175, 175, 175,
+			175, 175, 175, 175, 175, 175, 175, 175,
+			175, 175, 175, 175, 175, 175, 175, 175,
+			175,
+		},
+		{	/* Fourth byte table 8. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   7,
+			7,   7,   7,   7,   7,   7,   7,   7,
+			7,   20,  20,  20,  27,  27,  46,  59,
+			66,  91,  91,  98,  98,  98,  98,  105,
+			105, 105, 105, 105, 130, 130, 130, 130,
+			137, 137, 137, 137, 144, 144, 151, 151,
+			151, 164, 164, 164, 171, 171, 190, 203,
+			210, 235, 235, 242, 242, 242, 242, 249,
+			249, 249, 249, 249, 249, 249, 249, 249,
+			249, 249, 249, 249, 249, 249, 249, 249,
+			249, 249, 249, 249, 249, 249, 249, 249,
+			249, 249, 249, 249, 249, 249, 249, 249,
+			249, 249, 249, 249, 249, 249, 249, 249,
+			249, 249, 249, 249, 249, 249, 249, 249,
+			249, 249, 249, 249, 249, 249, 249, 249,
+			249, 249, 249, 249, 249, 249, 249, 249,
+			249,
+		},
+		{	/* Fourth byte table 9. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   25,  25,  25,  25,
+			32,  32,  32,  32,  39,  39,  46,  46,
+			46,  46,  46,  46,  46,  46,  46,  53,
+			53,  53,  53,  53,  53,  53,  53,  53,
+			53,  53,  53,  53,  53,  53,  53,  53,
+			53,  53,  53,  53,  53,  53,  53,  53,
+			53,  53,  53,  53,  53,  60,  67,  67,
+			67,  67,  67,  67,  67,  67,  67,  67,
+			67,  67,  67,  67,  67,  67,  67,  67,
+			67,  67,  67,  67,  67,  67,  67,  67,
+			67,  67,  67,  67,  67,  67,  67,  67,
+			67,  67,  67,  67,  67,  67,  67,  67,
+			67,  67,  67,  67,  67,  67,  67,  67,
+			67,  67,  67,  67,  67,  67,  67,  67,
+			67,  67,  67,  67,  67,  67,  67,  67,
+			67,  67,  67,  67,  67,  67,  67,  67,
+			67,
+		},
+		{	/* Fourth byte table 10. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   7,   14,  14,  14,  14,  14,  14,
+			14,  14,  14,  14,  14,  14,  14,  14,
+			14,  21,  28,  28,  28,  28,  28,  28,
+			28,  28,  28,  28,  28,  28,  28,  28,
+			28,  28,  28,  28,  28,  28,  28,  28,
+			28,  28,  28,  28,  28,  28,  28,  28,
+			28,  28,  28,  28,  28,  28,  28,  28,
+			28,  28,  28,  28,  28,  28,  28,  28,
+			28,  28,  28,  28,  28,  28,  28,  28,
+			28,  28,  28,  28,  28,  28,  28,  28,
+			28,  28,  28,  28,  28,  28,  28,  28,
+			28,  28,  28,  28,  28,  28,  28,  28,
+			28,  28,  28,  28,  28,  28,  28,  28,
+			28,
+		},
+		{	/* Fourth byte table 11. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			19,  19,  19,  19,  19,  19,  19,  19,
+			19,  19,  19,  19,  19,  19,  19,  19,
+			19,  19,  19,  19,  19,  19,  19,  19,
+			19,  19,  19,  19,  19,  19,  19,  19,
+			19,  19,  19,  19,  19,  19,  19,  19,
+			19,  19,  19,  19,  19,  19,  19,  19,
+			19,  19,  19,  19,  19,  19,  19,  19,
+			19,  19,  19,  19,  19,  19,  19,  19,
+			19,  19,  19,  19,  19,  19,  19,  19,
+			19,  19,  19,  19,  19,  19,  19,  19,
+			19,  19,  19,  19,  19,  19,  19,  19,
+			19,
+		},
+		{	/* Fourth byte table 12. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   7,   7,   14,  14,  14,  14,  14,
+			14,  14,  14,  14,  14,  14,  14,  14,
+			14,  14,  14,  14,  14,  14,  14,  14,
+			14,  14,  14,  14,  14,  14,  14,  14,
+			14,  14,  14,  14,  14,  14,  14,  14,
+			14,  14,  14,  14,  14,  14,  14,  14,
+			14,  14,  14,  14,  14,  14,  14,  14,
+			14,  14,  14,  14,  14,  14,  14,  14,
+			14,  14,  14,  14,  14,  14,  14,  14,
+			14,  14,  14,  14,  14,  14,  14,  14,
+			14,  14,  14,  14,  14,  14,  14,  14,
+			14,  14,  14,  14,  14,  14,  14,  14,
+			14,  14,  14,  14,  14,  14,  14,  14,
+			14,  14,  14,  14,  14,  14,  14,  14,
+			14,  14,  14,  14,  14,  14,  14,  14,
+			14,
+		},
+		{	/* Fourth byte table 13. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   7,   7,   7,   7,   7,   7,
+			7,   7,   7,   7,   7,   7,   7,   7,
+			7,   7,   7,   14,  14,  14,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,
+		},
+		{	/* Fourth byte table 14. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   9,   9,   9,   9,   9,   9,   9,
+			9,   18,  18,  18,  27,  27,  27,  27,
+			27,  27,  27,  27,  27,  27,  27,  27,
+			27,  27,  27,  27,  27,  27,  27,  27,
+			27,  27,  27,  27,  27,  27,  27,  27,
+			27,  27,  27,  27,  27,  27,  27,  27,
+			27,  27,  27,  27,  27,  27,  27,  27,
+			27,  27,  27,  27,  27,  27,  27,  27,
+			27,  27,  27,  27,  27,  27,  27,  27,
+			27,  27,  27,  27,  27,  27,  27,  27,
+			27,  27,  27,  27,  27,  27,  27,  27,
+			27,
+		},
+		{	/* Fourth byte table 15. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			17,  17,  17,  17,  17,  17,  17,  17,
+			17,  17,  17,  17,  17,  17,  17,  17,
+			17,  17,  17,  17,  17,  17,  17,  17,
+			17,  17,  17,  17,  17,  17,  17,  17,
+			17,  17,  17,  17,  17,  17,  17,  17,
+			17,  17,  17,  17,  17,  17,  17,  17,
+			17,  17,  17,  17,  17,  17,  17,  17,
+			17,  17,  17,  17,  17,  17,  17,  17,
+			17,  17,  17,  17,  17,  17,  17,  17,
+			17,  17,  17,  17,  17,  17,  17,  17,
+			17,  17,  17,  17,  17,  17,  17,  17,
+			17,  17,  17,  17,  17,  17,  17,  17,
+			17,  17,  17,  17,  17,  17,  17,  17,
+			17,  17,  17,  17,  17,  17,  17,  17,
+			17,  17,  17,  17,  17,  17,  17,  17,
+			17,
+		},
+		{	/* Fourth byte table 16. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			25,  25,  25,  25,  25,  25,  25,  25,
+			25,  25,  25,  25,  25,  25,  25,  25,
+			25,  25,  25,  25,  25,  25,  25,  25,
+			25,  25,  25,  25,  25,  25,  25,  25,
+			25,  25,  25,  25,  25,  25,  25,  25,
+			25,  25,  25,  25,  25,  25,  25,  25,
+			25,  25,  25,  25,  25,  25,  25,  25,
+			25,  25,  25,  25,  25,  25,  25,  25,
+			25,  25,  25,  25,  25,  25,  25,  25,
+			25,  25,  25,  25,  25,  25,  25,  25,
+			25,  25,  25,  25,  25,  25,  25,  25,
+			25,  25,  25,  25,  25,  25,  25,  25,
+			25,  25,  25,  25,  25,  25,  25,  25,
+			25,  25,  25,  25,  25,  25,  25,  25,
+			25,  25,  25,  25,  25,  25,  25,  25,
+			25,
+		},
+		{	/* Fourth byte table 17. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   9,   9,   9,   9,   9,
+			9,   9,   9,   9,   9,   9,   9,   9,
+			9,   9,   9,   9,   9,   9,   9,   9,
+			9,   9,   9,   9,   9,   9,   9,   9,
+			9,   9,   9,   9,   9,   9,   9,   9,
+			9,   9,   9,   9,   9,   9,   9,   9,
+			9,   9,   9,   9,   9,   9,   9,   9,
+			9,   9,   9,   9,   9,   9,   9,   9,
+			9,   9,   9,   9,   9,   9,   9,   9,
+			9,   9,   9,   9,   9,   9,   9,   9,
+			9,   9,   9,   9,   9,   9,   9,   9,
+			9,   9,   9,   9,   9,   9,   9,   9,
+			9,   9,   9,   9,   9,   9,   9,   9,
+			9,   9,   9,   9,   9,   9,   9,   9,
+			9,
+		},
+		{	/* Fourth byte table 18. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   17,
+			26,  26,  26,  26,  26,  26,  26,  26,
+			26,  26,  26,  26,  26,  26,  26,  26,
+			26,  26,  26,  26,  26,  26,  26,  26,
+			26,  26,  26,  26,  26,  26,  26,  26,
+			26,  26,  26,  26,  26,  26,  26,  26,
+			26,  26,  26,  26,  26,  26,  26,  26,
+			26,  26,  26,  26,  26,  26,  26,  26,
+			26,  26,  26,  26,  26,  26,  26,  26,
+			26,  26,  26,  26,  26,  26,  26,  26,
+			26,  26,  26,  26,  26,  26,  26,  26,
+			26,  26,  26,  26,  26,  26,  26,  26,
+			26,  26,  26,  26,  26,  26,  26,  26,
+			26,  26,  26,  26,  26,  26,  26,  26,
+			26,  26,  26,  26,  26,  26,  26,  26,
+			26,  26,  26,  26,  26,  26,  26,  26,
+			26,
+		},
+		{	/* Fourth byte table 19. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   9,
+			9,   9,   9,   9,   9,   9,   9,   9,
+			9,   9,   9,   9,   9,   9,   9,   9,
+			9,   9,   9,   9,   9,   9,   9,   9,
+			9,   9,   9,   9,   9,   9,   9,   9,
+			9,   9,   9,   9,   9,   9,   9,   9,
+			9,   9,   9,   9,   9,   9,   9,   9,
+			9,   9,   9,   9,   9,   9,   9,   9,
+			9,   9,   9,   9,   9,   9,   9,   9,
+			9,   9,   9,   9,   9,   9,   9,   9,
+			9,   9,   9,   9,   9,   9,   9,   9,
+			9,   9,   9,   9,   9,   9,   9,   9,
+			9,   9,   9,   9,   9,   9,   9,   9,
+			9,   9,   9,   9,   9,   9,   9,   9,
+			9,   9,   9,   9,   9,   9,   9,   9,
+			9,   9,   9,   9,   9,   9,   9,   9,
+			9,
+		},
+		{	/* Fourth byte table 20. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			9,   9,   9,   9,   9,   9,   9,   9,
+			9,   9,   9,   9,   9,   9,   9,   9,
+			9,   9,   9,   9,   9,   9,   9,   9,
+			9,   9,   9,   9,   9,   9,   9,   9,
+			9,   9,   9,   9,   9,   9,   9,   9,
+			9,   9,   9,   9,   9,   9,   9,   9,
+			9,   9,   9,   9,   9,   9,   9,   9,
+			9,   9,   9,   9,   9,   9,   9,   9,
+			9,
+		},
+		{	/* Fourth byte table 21. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   25,
+			25,  25,  25,  34,  34,  34,  34,  34,
+			34,  34,  34,  34,  34,  34,  34,  34,
+			34,  34,  34,  34,  34,  34,  34,  34,
+			34,  34,  34,  34,  34,  34,  34,  34,
+			34,  34,  34,  34,  34,  34,  34,  34,
+			34,  34,  34,  34,  34,  34,  34,  34,
+			34,  34,  34,  34,  34,  34,  34,  34,
+			34,  34,  34,  34,  34,  34,  34,  34,
+			34,  34,  34,  34,  34,  34,  34,  34,
+			34,  34,  34,  34,  34,  34,  34,  34,
+			34,  34,  34,  34,  34,  34,  34,  34,
+			34,  34,  34,  34,  34,  34,  34,  34,
+			34,  34,  34,  34,  34,  34,  34,  34,
+			34,  34,  34,  34,  34,  34,  34,  34,
+			34,  34,  34,  34,  34,  34,  34,  34,
+			34,
+		},
+		{	/* Fourth byte table 22. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   17,
+			26,  26,  26,  26,  26,  26,  26,  26,
+			26,  26,  26,  26,  26,  26,  26,  26,
+			26,  26,  26,  26,  26,  26,  26,  26,
+			26,  26,  26,  26,  26,  26,  26,  26,
+			26,  26,  26,  26,  26,  26,  26,  26,
+			26,  26,  26,  26,  26,  26,  26,  26,
+			26,  26,  26,  26,  26,  26,  26,  26,
+			26,  26,  26,  26,  26,  26,  26,  26,
+			26,  26,  26,  26,  26,  26,  26,  26,
+			26,  26,  26,  26,  26,  26,  26,  26,
+			26,  26,  26,  26,  26,  26,  26,  26,
+			26,  26,  26,  26,  26,  26,  26,  26,
+			26,  26,  26,  26,  26,  26,  26,  26,
+			26,  26,  26,  26,  26,  26,  26,  26,
+			26,  26,  26,  26,  26,  26,  26,  26,
+			26,
+		},
+		{	/* Fourth byte table 23. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   25,  25,  25,  34,  34,  34,
+			34,  34,  34,  34,  34,  34,  34,  34,
+			34,  34,  34,  34,  34,  34,  34,  34,
+			34,  34,  34,  34,  34,  34,  34,  34,
+			34,  34,  34,  34,  34,  34,  34,  34,
+			34,  34,  34,  34,  34,  34,  34,  34,
+			34,  34,  34,  34,  34,  34,  34,  34,
+			34,  34,  34,  34,  34,  34,  34,  34,
+			34,  34,  34,  34,  34,  34,  34,  34,
+			34,  34,  34,  34,  34,  34,  34,  34,
+			34,  34,  34,  34,  34,  34,  34,  34,
+			34,  34,  34,  34,  34,  34,  34,  34,
+			34,  34,  34,  34,  34,  34,  34,  34,
+			34,
+		},
+		{	/* Fourth byte table 24. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   9,   9,
+			9,   9,   9,   9,   9,   9,   9,   9,
+			9,   9,   9,   9,   9,   9,   9,   9,
+			9,   9,   9,   9,   9,   9,   9,   9,
+			9,   9,   9,   9,   9,   9,   9,   9,
+			9,   9,   9,   9,   9,   9,   9,   9,
+			9,   9,   9,   9,   9,   9,   9,   9,
+			9,   9,   9,   9,   9,   9,   9,   9,
+			9,   9,   9,   9,   9,   9,   9,   9,
+			9,   9,   9,   9,   9,   9,   9,   9,
+			9,   9,   9,   9,   9,   9,   9,   9,
+			9,   9,   9,   9,   9,   9,   9,   9,
+			9,
+		},
+		{	/* Fourth byte table 25. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   9,   9,
+			18,  18,  27,  27,  36,  36,  45,  45,
+			45,  45,  54,  54,  54,  54,  54,  54,
+			54,  54,  54,  54,  54,  54,  54,  54,
+			54,  54,  54,  54,  54,  54,  54,  54,
+			54,  54,  54,  54,  54,  54,  54,  54,
+			54,  54,  54,  54,  54,  54,  54,  54,
+			54,  54,  54,  63,  63,  72,  72,  81,
+			90,  90,  90,  90,  90,  90,  90,  90,
+			90,  90,  90,  90,  90,  90,  90,  90,
+			90,  90,  90,  90,  90,  90,  90,  90,
+			90,  90,  90,  90,  90,  90,  90,  90,
+			90,  90,  90,  90,  90,  90,  90,  90,
+			90,  90,  90,  90,  90,  90,  90,  90,
+			90,  90,  90,  90,  90,  90,  90,  90,
+			90,  90,  90,  90,  90,  90,  90,  90,
+			90,
+		},
+		{	/* Fourth byte table 26. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   9,   9,   9,   9,   9,
+			9,   9,   9,   9,   9,   9,   9,   9,
+			9,   9,   9,   9,   9,   9,   9,   9,
+			9,   9,   9,   9,   9,   9,   9,   9,
+			9,   9,   9,   9,   9,   9,   9,   9,
+			9,   9,   9,   9,   9,   9,   9,   9,
+			9,   9,   9,   9,   9,   9,   9,   9,
+			9,   9,   9,   9,   9,   9,   9,   9,
+			9,   9,   9,   9,   9,   9,   9,   9,
+			9,   9,   9,   9,   9,   9,   9,   9,
+			9,   9,   9,   9,   9,   9,   9,   9,
+			9,   9,   9,   9,   9,   9,   9,   9,
+			9,   9,   9,   9,   9,   9,   9,   9,
+			9,   9,   9,   9,   9,   9,   9,   9,
+			9,   9,   9,   9,   9,   9,   9,   9,
+			9,   9,   9,   9,   9,   9,   9,   9,
+			9,
+		},
+		{	/* Fourth byte table 27. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   8,
+			16,  16,  16,  16,  16,  16,  16,  16,
+			16,  16,  16,  16,  16,  16,  16,  16,
+			16,  16,  16,  16,  16,  16,  16,  16,
+			16,  16,  16,  16,  16,  16,  16,  16,
+			16,  16,  16,  16,  16,  16,  16,  16,
+			16,  16,  16,  16,  16,  16,  16,  16,
+			16,  16,  16,  16,  16,  16,  16,  16,
+			16,  16,  16,  16,  16,  16,  16,  16,
+			16,  16,  16,  16,  16,  16,  16,  16,
+			16,
+		},
+		{	/* Fourth byte table 28. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   8,   16,  16,  16,  16,
+			16,  16,  16,  24,  32,  32,  32,  32,
+			32,  32,  32,  32,  32,  32,  32,  32,
+			32,  32,  32,  32,  32,  32,  32,  32,
+			32,  32,  32,  32,  32,  32,  32,  32,
+			32,  32,  32,  32,  32,  32,  32,  32,
+			32,  32,  32,  32,  32,  32,  32,  32,
+			32,  32,  32,  32,  32,  32,  32,  32,
+			32,  32,  32,  32,  32,  32,  32,  32,
+			32,  32,  32,  32,  32,  32,  32,  32,
+			32,  32,  32,  32,  32,  32,  32,  32,
+			32,  32,  32,  32,  32,  32,  32,  32,
+			32,  32,  32,  32,  32,  32,  32,  32,
+			32,
+		},
+		{	/* Fourth byte table 29. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   15,  30,  30,  30,  30,  30,  30,
+			30,  30,  30,  30,  30,  30,  30,  30,
+			30,  30,  30,  30,  30,  30,  30,  30,
+			30,  38,  46,  46,  46,  46,  46,  46,
+			46,  46,  46,  46,  46,  46,  46,  46,
+			46,  46,  46,  46,  46,  46,  46,  46,
+			46,  46,  46,  46,  46,  46,  46,  46,
+			46,  46,  46,  46,  46,  46,  46,  46,
+			46,  46,  46,  46,  46,  46,  46,  46,
+			46,  46,  46,  46,  46,  46,  46,  46,
+			46,  46,  46,  46,  46,  46,  46,  46,
+			46,  46,  46,  46,  46,  46,  46,  46,
+			46,
+		},
+		{	/* Fourth byte table 30. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   8,   16,  16,
+			16,  16,  16,  16,  16,  16,  16,  16,
+			16,  16,  16,  16,  16,  16,  16,  16,
+			16,  16,  16,  16,  16,  16,  16,  16,
+			16,  16,  16,  16,  16,  16,  16,  16,
+			16,  16,  16,  16,  16,  16,  16,  16,
+			16,  16,  16,  16,  16,  16,  16,  16,
+			16,  16,  16,  16,  16,  16,  16,  16,
+			16,  16,  16,  16,  16,  16,  16,  16,
+			16,  16,  16,  16,  16,  16,  16,  16,
+			16,  16,  16,  16,  16,  16,  16,  16,
+			16,  16,  16,  16,  16,  16,  16,  16,
+			16,  16,  16,  16,  16,  16,  16,  16,
+			16,  16,  16,  16,  16,  16,  16,  16,
+			16,  16,  16,  16,  16,  16,  16,  16,
+			16,
+		},
+		{	/* Fourth byte table 31. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   8,
+			8,   8,   8,   8,   8,   8,   8,   8,
+			30,  30,  30,  30,  30,  30,  30,  30,
+			30,  30,  30,  30,  30,  30,  30,  30,
+			30,  30,  30,  30,  30,  30,  30,  30,
+			30,  30,  30,  30,  30,  30,  30,  30,
+			30,  30,  30,  30,  30,  30,  30,  30,
+			30,  30,  30,  30,  30,  30,  30,  30,
+			30,  30,  30,  30,  30,  30,  30,  30,
+			30,  30,  30,  30,  30,  30,  30,  30,
+			30,
+		},
+		{	/* Fourth byte table 32. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   8,
+			8,   8,   8,   8,   8,   8,   8,   8,
+			8,   8,   8,   8,   8,   8,   8,   8,
+			8,   8,   8,   8,   8,   8,   8,   8,
+			8,   8,   8,   8,   8,   8,   8,   8,
+			8,   8,   8,   8,   8,   8,   8,   8,
+			8,   8,   8,   8,   8,   8,   8,   16,
+			16,  16,  16,  16,  16,  16,  16,  38,
+			38,  38,  38,  38,  38,  38,  38,  38,
+			38,  38,  38,  38,  38,  38,  38,  38,
+			38,  38,  38,  38,  38,  38,  38,  38,
+			38,  38,  38,  38,  38,  38,  38,  38,
+			38,  38,  38,  38,  38,  38,  38,  38,
+			38,  38,  38,  38,  38,  38,  38,  38,
+			38,  38,  38,  38,  38,  38,  38,  38,
+			38,  38,  38,  38,  38,  38,  38,  38,
+			38,
+		},
+		{	/* Fourth byte table 33. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   8,   8,   16,  16,  24,  24,  24,
+			24,  24,  24,  24,  24,  24,  24,  24,
+			24,  24,  24,  24,  24,  24,  24,  24,
+			24,  24,  24,  24,  24,  24,  24,  24,
+			24,  24,  24,  24,  24,  24,  24,  24,
+			24,  24,  24,  24,  24,  24,  24,  24,
+			24,  24,  24,  24,  24,  24,  24,  24,
+			24,  24,  24,  24,  24,  24,  24,  24,
+			24,  24,  24,  24,  24,  24,  24,  24,
+			24,  24,  24,  24,  24,  24,  24,  24,
+			24,  24,  24,  24,  24,  24,  24,  24,
+			24,  24,  24,  24,  24,  24,  24,  24,
+			24,  24,  24,  24,  24,  24,  24,  24,
+			24,  24,  24,  24,  24,  24,  24,  24,
+			24,
+		},
+		{	/* Fourth byte table 34. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   8,   8,   16,  16,  24,  24,  24,
+			24,  24,  24,  24,  24,  24,  24,  24,
+			24,  24,  24,  24,  24,  24,  24,  24,
+			24,  24,  24,  24,  24,  24,  24,  24,
+			24,  24,  24,  24,  24,  24,  24,  24,
+			24,  24,  24,  24,  24,  24,  24,  24,
+			24,  24,  24,  24,  24,  24,  24,  24,
+			24,  24,  24,  24,  24,  24,  24,  24,
+			24,  24,  24,  24,  24,  24,  24,  24,
+			24,  24,  24,  24,  24,  24,  24,  24,
+			24,  24,  24,  24,  24,  24,  24,  24,
+			24,  24,  24,  24,  24,  24,  24,  24,
+			24,  24,  24,  24,  24,  24,  24,  24,
+			24,  24,  24,  24,  24,  24,  24,  24,
+			24,
+		},
+		{	/* Fourth byte table 35. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   8,   8,   8,   8,
+			8,   16,  16,  16,  24,  24,  24,  24,
+			24,  24,  24,  24,  24,  24,  24,  24,
+			24,  24,  24,  24,  24,  24,  24,  24,
+			24,  24,  24,  24,  32,  32,  40,  40,
+			40,  40,  40,  40,  40,  40,  40,  40,
+			40,  40,  40,  40,  40,  40,  40,  40,
+			40,  40,  40,  40,  40,  48,  48,  48,
+			48,  48,  48,  48,  48,  48,  48,  48,
+			48,  48,  48,  48,  48,  48,  48,  48,
+			48,  48,  48,  48,  48,  48,  48,  48,
+			48,  48,  48,  48,  48,  48,  48,  48,
+			48,  48,  48,  48,  48,  48,  48,  48,
+			48,  48,  48,  48,  48,  48,  48,  48,
+			48,  48,  48,  48,  48,  48,  48,  48,
+			48,  48,  48,  48,  48,  48,  48,  48,
+			48,
+		},
+		{	/* Fourth byte table 36. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   8,   8,   16,  16,
+			16,  24,  24,  24,  24,  24,  32,  32,
+			32,  32,  32,  32,  32,  32,  32,  32,
+			32,  32,  32,  32,  32,  32,  32,  32,
+			32,  32,  40,  40,  40,  48,  56,  56,
+			56,  56,  56,  56,  56,  56,  56,  56,
+			56,  56,  56,  64,  72,  72,  72,  80,
+			88,  88,  88,  96,  104, 112, 120, 120,
+			120, 120, 120, 120, 120, 120, 120, 120,
+			120, 120, 120, 120, 120, 120, 120, 120,
+			120, 120, 120, 120, 120, 120, 120, 120,
+			120, 120, 120, 120, 120, 120, 120, 120,
+			120, 120, 120, 120, 120, 120, 120, 120,
+			120, 120, 120, 120, 120, 120, 120, 120,
+			120, 120, 120, 120, 120, 120, 120, 120,
+			120, 120, 120, 120, 120, 120, 120, 120,
+			120,
+		},
+		{	/* Fourth byte table 37. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   8,   16,  16,  16,  24,
+			32,  32,  32,  32,  32,  32,  32,  32,
+			32,  32,  40,  48,  48,  48,  48,  48,
+			48,  48,  48,  48,  48,  48,  48,  48,
+			48,  48,  48,  56,  56,  56,  56,  56,
+			56,  64,  72,  72,  80,  80,  80,  80,
+			80,  80,  80,  88,  96,  104, 112, 112,
+			112, 112, 112, 112, 112, 112, 112, 112,
+			112, 112, 112, 112, 112, 112, 112, 112,
+			112, 112, 112, 112, 112, 112, 112, 112,
+			112, 112, 112, 112, 112, 112, 112, 112,
+			112, 112, 112, 112, 112, 112, 112, 112,
+			112, 112, 112, 112, 112, 112, 112, 112,
+			112, 112, 112, 112, 112, 112, 112, 112,
+			112, 112, 112, 112, 112, 112, 112, 112,
+			112, 112, 112, 112, 112, 112, 112, 112,
+			112,
+		},
+		{	/* Fourth byte table 38. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   9,
+			9,   9,   9,   9,   18,  18,  27,  27,
+			36,  36,  45,  45,  54,  54,  63,  63,
+			72,  72,  81,  81,  90,  90,  99,  99,
+			108, 108, 117, 117, 117, 126, 126, 135,
+			135, 144, 144, 144, 144, 144, 144, 144,
+			161, 161, 161, 178, 178, 178, 195, 195,
+			195, 212, 212, 212, 229, 229, 229, 229,
+			229, 229, 229, 229, 229, 229, 229, 229,
+			229, 229, 229, 229, 229, 229, 229, 229,
+			229, 229, 229, 229, 229, 229, 229, 229,
+			229, 229, 229, 229, 229, 229, 229, 229,
+			229, 229, 229, 229, 229, 229, 229, 229,
+			229, 229, 229, 229, 229, 229, 229, 229,
+			229, 229, 229, 229, 229, 229, 229, 229,
+			229, 229, 229, 229, 229, 229, 229, 229,
+			229,
+		},
+		{	/* Fourth byte table 39. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   9,   9,
+			9,   9,   9,   9,   9,   9,   9,   18,
+			18,  18,  18,  18,  27,  27,  36,  36,
+			45,  45,  54,  54,  63,  63,  72,  72,
+			81,  81,  90,  90,  99,  99,  108, 108,
+			117, 117, 117, 117, 117, 117, 117, 117,
+			117, 117, 117, 117, 117, 117, 117, 117,
+			117, 117, 117, 117, 117, 117, 117, 117,
+			117, 117, 117, 117, 117, 117, 117, 117,
+			117, 117, 117, 117, 117, 117, 117, 117,
+			117, 117, 117, 117, 117, 117, 117, 117,
+			117, 117, 117, 117, 117, 117, 117, 117,
+			117, 117, 117, 117, 117, 117, 117, 117,
+			117,
+		},
+		{	/* Fourth byte table 40. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   9,   9,   9,   18,  18,  27,
+			27,  36,  36,  36,  36,  36,  36,  36,
+			53,  53,  53,  70,  70,  70,  87,  87,
+			87,  104, 104, 104, 121, 121, 121, 121,
+			121, 121, 121, 121, 121, 121, 121, 121,
+			121, 121, 121, 121, 121, 121, 121, 121,
+			130, 139, 148, 157, 157, 157, 157, 157,
+			157, 157, 157, 157, 157, 157, 166, 166,
+			166, 166, 166, 166, 166, 166, 166, 166,
+			166, 166, 166, 166, 166, 166, 166, 166,
+			166, 166, 166, 166, 166, 166, 166, 166,
+			166, 166, 166, 166, 166, 166, 166, 166,
+			166, 166, 166, 166, 166, 166, 166, 166,
+			166, 166, 166, 166, 166, 166, 166, 166,
+			166, 166, 166, 166, 166, 166, 166, 166,
+			166, 166, 166, 166, 166, 166, 166, 166,
+			166,
+		},
+	},
+};
+
+static const uint16_t u8_composition_b4_16bit_tbl[2][5][257] = {
+	{
+		{	/* Fourth byte 16-bit table 0. */
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    8,    16,   24,
+			24,   24,   124,  146,  177,  219,  327,  335,
+			379,  427,  521,  528,  562,  602,  624,  683,
+			782,  797,  797,  849,  894,  941,  1061, 1076,
+			1118, 1133, 1193, 1233, 1233, 1233, 1233, 1233,
+			1233, 1233, 1333, 1355, 1386, 1428, 1536, 1544,
+			1588, 1643, 1731, 1744, 1778, 1818, 1840, 1899,
+			1998, 2013, 2013, 2065, 2110, 2164, 2284, 2299,
+			2348, 2363, 2430, 2470, 2470, 2470, 2470, 2470,
+			2470, 2470, 2470, 2470, 2470, 2470, 2470, 2470,
+			2470, 2470, 2470, 2470, 2470, 2470, 2470, 2470,
+			2470, 2470, 2470, 2470, 2470, 2470, 2470, 2470,
+			2470, 2470, 2470, 2470, 2470, 2470, 2470, 2470,
+			2470, 2470, 2470, 2470, 2470, 2470, 2470, 2470,
+			2470, 2470, 2470, 2470, 2470, 2470, 2470, 2470,
+			2470, 2470, 2470, 2470, 2470, 2470, 2470, 2470,
+			2470, 2470, 2470, 2470, 2470, 2470, 2470, 2470,
+			2470, 2470, 2470, 2470, 2470, 2470, 2470, 2470,
+			2470, 2470, 2470, 2470, 2470, 2470, 2470, 2470,
+			2470, 2470, 2470, 2470, 2470, 2470, 2470, 2470,
+			2470, 2470, 2470, 2470, 2470, 2470, 2470, 2470,
+			2470, 2470, 2470, 2470, 2470, 2470, 2470, 2470,
+			2470, 2470, 2470, 2470, 2470, 2470, 2470, 2470,
+			2470, 2470, 2470, 2470, 2470, 2470, 2470, 2470,
+			2470, 2470, 2470, 2470, 2470, 2470, 2470, 2470,
+			2470,
+		},
+		{	/* Fourth byte 16-bit table 1. */
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    29,   29,   36,   43,   56,
+			64,   64,   64,   93,   93,   93,   93,   93,
+			101,  101,  101,  101,  101,  130,  151,  158,
+			158,  165,  165,  165,  165,  190,  190,  190,
+			190,  190,  190,  219,  219,  226,  233,  246,
+			254,  254,  254,  283,  283,  283,  283,  283,
+			291,  291,  291,  291,  291,  320,  341,  348,
+			348,  355,  355,  355,  355,  380,  380,  380,
+			380,  380,  380,  380,  380,  380,  380,  380,
+			380,  380,  380,  380,  380,  380,  380,  380,
+			380,  380,  380,  380,  380,  380,  380,  380,
+			380,  380,  380,  380,  380,  380,  380,  380,
+			380,  380,  380,  380,  380,  380,  380,  380,
+			380,  380,  380,  380,  380,  380,  380,  380,
+			380,  380,  380,  380,  380,  380,  380,  380,
+			380,  380,  380,  380,  380,  380,  380,  380,
+			380,
+		},
+		{	/* Fourth byte 16-bit table 2. */
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    49,   49,   49,   49,   77,   77,
+			112,  112,  160,  160,  160,  160,  160,  160,
+			188,  188,  196,  196,  196,  196,  237,  237,
+			237,  237,  272,  272,  272,  280,  280,  288,
+			288,  288,  344,  344,  344,  344,  372,  372,
+			414,  414,  469,  469,  469,  469,  469,  469,
+			497,  497,  497,  497,  497,  497,  497,  497,
+			497,  497,  497,  497,  497,  497,  497,  497,
+			497,  497,  497,  497,  497,  497,  497,  497,
+			497,  497,  497,  497,  497,  497,  497,  497,
+			497,  497,  497,  497,  497,  497,  497,  497,
+			497,  497,  497,  497,  497,  497,  497,  497,
+			497,  497,  497,  497,  497,  497,  497,  497,
+			497,  497,  497,  497,  497,  497,  497,  497,
+			497,
+		},
+		{	/* Fourth byte 16-bit table 3. */
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    29,   58,   66,   74,   82,   90,   98,
+			106,  135,  164,  172,  180,  188,  196,  204,
+			212,  227,  242,  242,  242,  242,  242,  242,
+			242,  257,  272,  272,  272,  272,  272,  272,
+			272,  301,  330,  338,  346,  354,  362,  370,
+			378,  407,  436,  444,  452,  460,  468,  476,
+			484,  506,  528,  528,  528,  528,  528,  528,
+			528,  550,  572,  572,  572,  572,  572,  572,
+			572,  572,  572,  572,  572,  572,  572,  572,
+			572,  572,  572,  572,  572,  572,  572,  572,
+			572,  572,  572,  572,  572,  572,  572,  572,
+			572,  572,  572,  572,  572,  572,  572,  572,
+			572,  572,  572,  572,  572,  572,  572,  572,
+			572,  572,  572,  572,  572,  572,  572,  572,
+			572,  572,  572,  572,  572,  572,  572,  572,
+			572,  572,  572,  572,  572,  572,  572,  572,
+			572,
+		},
+		{	/* Fourth byte 16-bit table 4. */
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    15,   30,   30,   30,   30,   30,   30,
+			30,   45,   60,   60,   60,   60,   60,   60,
+			60,   82,   104,  104,  104,  104,  104,  104,
+			104,  104,  126,  126,  126,  126,  126,  126,
+			126,  155,  184,  192,  200,  208,  216,  224,
+			232,  261,  290,  298,  306,  314,  322,  330,
+			338,  346,  346,  346,  346,  354,  354,  354,
+			354,  354,  354,  354,  354,  362,  362,  362,
+			362,  362,  362,  362,  362,  362,  362,  362,
+			362,  362,  362,  362,  362,  362,  362,  362,
+			362,  362,  362,  362,  362,  362,  362,  362,
+			362,  362,  362,  362,  362,  362,  362,  362,
+			362,  362,  362,  362,  362,  362,  362,  362,
+			362,  362,  362,  362,  362,  362,  362,  362,
+			362,  362,  362,  362,  362,  362,  362,  362,
+			362,  362,  362,  362,  362,  362,  362,  362,
+			362,
+		},
+	},
+	{
+		{	/* Fourth byte 16-bit table 0. */
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    8,    16,   24,
+			24,   24,   124,  146,  177,  219,  327,  335,
+			379,  427,  521,  528,  562,  602,  624,  683,
+			782,  797,  797,  849,  894,  941,  1061, 1076,
+			1118, 1133, 1193, 1233, 1233, 1233, 1233, 1233,
+			1233, 1233, 1333, 1355, 1386, 1428, 1536, 1544,
+			1588, 1643, 1731, 1744, 1778, 1818, 1840, 1899,
+			1998, 2013, 2013, 2065, 2110, 2164, 2284, 2299,
+			2348, 2363, 2430, 2470, 2470, 2470, 2470, 2470,
+			2470, 2470, 2470, 2470, 2470, 2470, 2470, 2470,
+			2470, 2470, 2470, 2470, 2470, 2470, 2470, 2470,
+			2470, 2470, 2470, 2470, 2470, 2470, 2470, 2470,
+			2470, 2470, 2470, 2470, 2470, 2470, 2470, 2470,
+			2470, 2470, 2470, 2470, 2470, 2470, 2470, 2470,
+			2470, 2470, 2470, 2470, 2470, 2470, 2470, 2470,
+			2470, 2470, 2470, 2470, 2470, 2470, 2470, 2470,
+			2470, 2470, 2470, 2470, 2470, 2470, 2470, 2470,
+			2470, 2470, 2470, 2470, 2470, 2470, 2470, 2470,
+			2470, 2470, 2470, 2470, 2470, 2470, 2470, 2470,
+			2470, 2470, 2470, 2470, 2470, 2470, 2470, 2470,
+			2470, 2470, 2470, 2470, 2470, 2470, 2470, 2470,
+			2470, 2470, 2470, 2470, 2470, 2470, 2470, 2470,
+			2470, 2470, 2470, 2470, 2470, 2470, 2470, 2470,
+			2470, 2470, 2470, 2470, 2470, 2470, 2470, 2470,
+			2470, 2470, 2470, 2470, 2470, 2470, 2470, 2470,
+			2470,
+		},
+		{	/* Fourth byte 16-bit table 1. */
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    29,   29,   36,   43,   56,
+			64,   64,   64,   93,   93,   93,   93,   93,
+			101,  101,  101,  101,  101,  130,  151,  158,
+			158,  165,  165,  165,  165,  190,  190,  190,
+			190,  190,  190,  219,  219,  226,  233,  246,
+			254,  254,  254,  283,  283,  283,  283,  283,
+			291,  291,  291,  291,  291,  320,  341,  348,
+			348,  355,  355,  355,  355,  380,  380,  380,
+			380,  380,  380,  380,  380,  380,  380,  380,
+			380,  380,  380,  380,  380,  380,  380,  380,
+			380,  380,  380,  380,  380,  380,  380,  380,
+			380,  380,  380,  380,  380,  380,  380,  380,
+			380,  380,  380,  380,  380,  380,  380,  380,
+			380,  380,  380,  380,  380,  380,  380,  380,
+			380,  380,  380,  380,  380,  380,  380,  380,
+			380,  380,  380,  380,  380,  380,  380,  380,
+			380,
+		},
+		{	/* Fourth byte 16-bit table 2. */
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    49,   49,   49,   49,   77,   77,
+			112,  112,  160,  160,  160,  160,  160,  160,
+			188,  188,  196,  196,  196,  196,  237,  237,
+			237,  237,  272,  272,  272,  280,  280,  288,
+			288,  288,  344,  344,  344,  344,  372,  372,
+			414,  414,  469,  469,  469,  469,  469,  469,
+			497,  497,  497,  497,  497,  497,  497,  497,
+			497,  497,  497,  497,  497,  497,  497,  497,
+			497,  497,  497,  497,  497,  497,  497,  497,
+			497,  497,  497,  497,  497,  497,  497,  497,
+			497,  497,  497,  497,  497,  497,  497,  497,
+			497,  497,  497,  497,  497,  497,  497,  497,
+			497,  497,  497,  497,  497,  497,  497,  497,
+			497,  497,  497,  497,  497,  497,  497,  497,
+			497,
+		},
+		{	/* Fourth byte 16-bit table 3. */
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    29,   58,   66,   74,   82,   90,   98,
+			106,  135,  164,  172,  180,  188,  196,  204,
+			212,  227,  242,  242,  242,  242,  242,  242,
+			242,  257,  272,  272,  272,  272,  272,  272,
+			272,  301,  330,  338,  346,  354,  362,  370,
+			378,  407,  436,  444,  452,  460,  468,  476,
+			484,  506,  528,  528,  528,  528,  528,  528,
+			528,  550,  572,  572,  572,  572,  572,  572,
+			572,  572,  572,  572,  572,  572,  572,  572,
+			572,  572,  572,  572,  572,  572,  572,  572,
+			572,  572,  572,  572,  572,  572,  572,  572,
+			572,  572,  572,  572,  572,  572,  572,  572,
+			572,  572,  572,  572,  572,  572,  572,  572,
+			572,  572,  572,  572,  572,  572,  572,  572,
+			572,  572,  572,  572,  572,  572,  572,  572,
+			572,  572,  572,  572,  572,  572,  572,  572,
+			572,
+		},
+		{	/* Fourth byte 16-bit table 4. */
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    15,   30,   30,   30,   30,   30,   30,
+			30,   45,   60,   60,   60,   60,   60,   60,
+			60,   82,   104,  104,  104,  104,  104,  104,
+			104,  104,  126,  126,  126,  126,  126,  126,
+			126,  155,  184,  192,  200,  208,  216,  224,
+			232,  261,  290,  298,  306,  314,  322,  330,
+			338,  346,  346,  346,  346,  354,  354,  354,
+			354,  354,  354,  354,  354,  362,  362,  362,
+			362,  362,  362,  362,  362,  362,  362,  362,
+			362,  362,  362,  362,  362,  362,  362,  362,
+			362,  362,  362,  362,  362,  362,  362,  362,
+			362,  362,  362,  362,  362,  362,  362,  362,
+			362,  362,  362,  362,  362,  362,  362,  362,
+			362,  362,  362,  362,  362,  362,  362,  362,
+			362,  362,  362,  362,  362,  362,  362,  362,
+			362,  362,  362,  362,  362,  362,  362,  362,
+			362,
+		},
+	},
+};
+
+static const uchar_t u8_composition_final_tbl[2][6623] = {
+	{
+		0x01, 0xCC, 0xB8, FIL_, 0xE2, 0x89, 0xAE, FIL_,
+		0x01, 0xCC, 0xB8, FIL_, 0xE2, 0x89, 0xA0, FIL_,
+		0x01, 0xCC, 0xB8, FIL_, 0xE2, 0x89, 0xAF, FIL_,
+		0x10, 0xCC, 0x86, FIL_, 0xC4, 0x82, FIL_, 0xCC,
+		0x87, FIL_, 0xC8, 0xA6, FIL_, 0xCC, 0x8F, FIL_,
+		0xC8, 0x80, FIL_, 0xCC, 0x82, FIL_, 0xC3, 0x82,
+		FIL_, 0xCC, 0x81, FIL_, 0xC3, 0x81, FIL_, 0xCC,
+		0x80, FIL_, 0xC3, 0x80, FIL_, 0xCC, 0x83, FIL_,
+		0xC3, 0x83, FIL_, 0xCC, 0xA3, FIL_, 0xE1, 0xBA,
+		0xA0, FIL_, 0xCC, 0xA5, FIL_, 0xE1, 0xB8, 0x80,
+		FIL_, 0xCC, 0x91, FIL_, 0xC8, 0x82, FIL_, 0xCC,
+		0x84, FIL_, 0xC4, 0x80, FIL_, 0xCC, 0x88, FIL_,
+		0xC3, 0x84, FIL_, 0xCC, 0x8A, FIL_, 0xC3, 0x85,
+		FIL_, 0xCC, 0xA8, FIL_, 0xC4, 0x84, FIL_, 0xCC,
+		0x89, FIL_, 0xE1, 0xBA, 0xA2, FIL_, 0xCC, 0x8C,
+		FIL_, 0xC7, 0x8D, FIL_, 0x03, 0xCC, 0x87, FIL_,
+		0xE1, 0xB8, 0x82, FIL_, 0xCC, 0xB1, FIL_, 0xE1,
+		0xB8, 0x86, FIL_, 0xCC, 0xA3, FIL_, 0xE1, 0xB8,
+		0x84, FIL_, 0x05, 0xCC, 0xA7, FIL_, 0xC3, 0x87,
+		FIL_, 0xCC, 0x81, FIL_, 0xC4, 0x86, FIL_, 0xCC,
+		0x8C, FIL_, 0xC4, 0x8C, FIL_, 0xCC, 0x87, FIL_,
+		0xC4, 0x8A, FIL_, 0xCC, 0x82, FIL_, 0xC4, 0x88,
+		FIL_, 0x06, 0xCC, 0xB1, FIL_, 0xE1, 0xB8, 0x8E,
+		FIL_, 0xCC, 0xA7, FIL_, 0xE1, 0xB8, 0x90, FIL_,
+		0xCC, 0xAD, FIL_, 0xE1, 0xB8, 0x92, FIL_, 0xCC,
+		0x87, FIL_, 0xE1, 0xB8, 0x8A, FIL_, 0xCC, 0x8C,
+		FIL_, 0xC4, 0x8E, FIL_, 0xCC, 0xA3, FIL_, 0xE1,
+		0xB8, 0x8C, FIL_, 0x11, 0xCC, 0x80, FIL_, 0xC3,
+		0x88, FIL_, 0xCC, 0x81, FIL_, 0xC3, 0x89, FIL_,
+		0xCC, 0x82, FIL_, 0xC3, 0x8A, FIL_, 0xCC, 0x88,
+		FIL_, 0xC3, 0x8B, FIL_, 0xCC, 0xA7, FIL_, 0xC8,
+		0xA8, FIL_, 0xCC, 0x91, FIL_, 0xC8, 0x86, FIL_,
+		0xCC, 0x8F, FIL_, 0xC8, 0x84, FIL_, 0xCC, 0x89,
+		FIL_, 0xE1, 0xBA, 0xBA, FIL_, 0xCC, 0xB0, FIL_,
+		0xE1, 0xB8, 0x9A, FIL_, 0xCC, 0xAD, FIL_, 0xE1,
+		0xB8, 0x98, FIL_, 0xCC, 0x83, FIL_, 0xE1, 0xBA,
+		0xBC, FIL_, 0xCC, 0xA3, FIL_, 0xE1, 0xBA, 0xB8,
+		FIL_, 0xCC, 0x84, FIL_, 0xC4, 0x92, FIL_, 0xCC,
+		0x86, FIL_, 0xC4, 0x94, FIL_, 0xCC, 0x87, FIL_,
+		0xC4, 0x96, FIL_, 0xCC, 0xA8, FIL_, 0xC4, 0x98,
+		FIL_, 0xCC, 0x8C, FIL_, 0xC4, 0x9A, FIL_, 0x01,
+		0xCC, 0x87, FIL_, 0xE1, 0xB8, 0x9E, FIL_, 0x07,
+		0xCC, 0x8C, FIL_, 0xC7, 0xA6, FIL_, 0xCC, 0x87,
+		FIL_, 0xC4, 0xA0, FIL_, 0xCC, 0x84, FIL_, 0xE1,
+		0xB8, 0xA0, FIL_, 0xCC, 0x82, FIL_, 0xC4, 0x9C,
+		FIL_, 0xCC, 0x81, FIL_, 0xC7, 0xB4, FIL_, 0xCC,
+		0xA7, FIL_, 0xC4, 0xA2, FIL_, 0xCC, 0x86, FIL_,
+		0xC4, 0x9E, FIL_, 0x07, 0xCC, 0xAE, FIL_, 0xE1,
+		0xB8, 0xAA, FIL_, 0xCC, 0x87, FIL_, 0xE1, 0xB8,
+		0xA2, FIL_, 0xCC, 0x88, FIL_, 0xE1, 0xB8, 0xA6,
+		FIL_, 0xCC, 0xA3, FIL_, 0xE1, 0xB8, 0xA4, FIL_,
+		0xCC, 0xA7, FIL_, 0xE1, 0xB8, 0xA8, FIL_, 0xCC,
+		0x8C, FIL_, 0xC8, 0x9E, FIL_, 0xCC, 0x82, FIL_,
+		0xC4, 0xA4, FIL_, 0x0F, 0xCC, 0x84, FIL_, 0xC4,
+		0xAA, FIL_, 0xCC, 0x80, FIL_, 0xC3, 0x8C, FIL_,
+		0xCC, 0xA8, FIL_, 0xC4, 0xAE, FIL_, 0xCC, 0x83,
+		FIL_, 0xC4, 0xA8, FIL_, 0xCC, 0x88, FIL_, 0xC3,
+		0x8F, FIL_, 0xCC, 0x81, FIL_, 0xC3, 0x8D, FIL_,
+		0xCC, 0x8F, FIL_, 0xC8, 0x88, FIL_, 0xCC, 0x86,
+		FIL_, 0xC4, 0xAC, FIL_, 0xCC, 0x91, FIL_, 0xC8,
+		0x8A, FIL_, 0xCC, 0x8C, FIL_, 0xC7, 0x8F, FIL_,
+		0xCC, 0x89, FIL_, 0xE1, 0xBB, 0x88, FIL_, 0xCC,
+		0x87, FIL_, 0xC4, 0xB0, FIL_, 0xCC, 0xA3, FIL_,
+		0xE1, 0xBB, 0x8A, FIL_, 0xCC, 0xB0, FIL_, 0xE1,
+		0xB8, 0xAC, FIL_, 0xCC, 0x82, FIL_, 0xC3, 0x8E,
+		FIL_, 0x01, 0xCC, 0x82, FIL_, 0xC4, 0xB4, FIL_,
+		0x05, 0xCC, 0x8C, FIL_, 0xC7, 0xA8, FIL_, 0xCC,
+		0xB1, FIL_, 0xE1, 0xB8, 0xB4, FIL_, 0xCC, 0x81,
+		FIL_, 0xE1, 0xB8, 0xB0, FIL_, 0xCC, 0xA7, FIL_,
+		0xC4, 0xB6, FIL_, 0xCC, 0xA3, FIL_, 0xE1, 0xB8,
+		0xB2, FIL_, 0x06, 0xCC, 0xA7, FIL_, 0xC4, 0xBB,
+		FIL_, 0xCC, 0x8C, FIL_, 0xC4, 0xBD, FIL_, 0xCC,
+		0xB1, FIL_, 0xE1, 0xB8, 0xBA, FIL_, 0xCC, 0xA3,
+		FIL_, 0xE1, 0xB8, 0xB6, FIL_, 0xCC, 0xAD, FIL_,
+		0xE1, 0xB8, 0xBC, FIL_, 0xCC, 0x81, FIL_, 0xC4,
+		0xB9, FIL_, 0x03, 0xCC, 0x81, FIL_, 0xE1, 0xB8,
+		0xBE, FIL_, 0xCC, 0xA3, FIL_, 0xE1, 0xB9, 0x82,
+		FIL_, 0xCC, 0x87, FIL_, 0xE1, 0xB9, 0x80, FIL_,
+		0x09, 0xCC, 0x80, FIL_, 0xC7, 0xB8, FIL_, 0xCC,
+		0xAD, FIL_, 0xE1, 0xB9, 0x8A, FIL_, 0xCC, 0x87,
+		FIL_, 0xE1, 0xB9, 0x84, FIL_, 0xCC, 0xB1, FIL_,
+		0xE1, 0xB9, 0x88, FIL_, 0xCC, 0x83, FIL_, 0xC3,
+		0x91, FIL_, 0xCC, 0xA3, FIL_, 0xE1, 0xB9, 0x86,
+		FIL_, 0xCC, 0x81, FIL_, 0xC5, 0x83, FIL_, 0xCC,
+		0xA7, FIL_, 0xC5, 0x85, FIL_, 0xCC, 0x8C, FIL_,
+		0xC5, 0x87, FIL_, 0x10, 0xCC, 0xA8, FIL_, 0xC7,
+		0xAA, FIL_, 0xCC, 0x91, FIL_, 0xC8, 0x8E, FIL_,
+		0xCC, 0x80, FIL_, 0xC3, 0x92, FIL_, 0xCC, 0x9B,
+		FIL_, 0xC6, 0xA0, FIL_, 0xCC, 0x8F, FIL_, 0xC8,
+		0x8C, FIL_, 0xCC, 0x81, FIL_, 0xC3, 0x93, FIL_,
+		0xCC, 0x87, FIL_, 0xC8, 0xAE, FIL_, 0xCC, 0x8C,
+		FIL_, 0xC7, 0x91, FIL_, 0xCC, 0xA3, FIL_, 0xE1,
+		0xBB, 0x8C, FIL_, 0xCC, 0x82, FIL_, 0xC3, 0x94,
+		FIL_, 0xCC, 0x84, FIL_, 0xC5, 0x8C, FIL_, 0xCC,
+		0x83, FIL_, 0xC3, 0x95, FIL_, 0xCC, 0x86, FIL_,
+		0xC5, 0x8E, FIL_, 0xCC, 0x88, FIL_, 0xC3, 0x96,
+		FIL_, 0xCC, 0x8B, FIL_, 0xC5, 0x90, FIL_, 0xCC,
+		0x89, FIL_, 0xE1, 0xBB, 0x8E, FIL_, 0x02, 0xCC,
+		0x87, FIL_, 0xE1, 0xB9, 0x96, FIL_, 0xCC, 0x81,
+		FIL_, 0xE1, 0xB9, 0x94, FIL_, 0x08, 0xCC, 0x91,
+		FIL_, 0xC8, 0x92, FIL_, 0xCC, 0xA7, FIL_, 0xC5,
+		0x96, FIL_, 0xCC, 0x8C, FIL_, 0xC5, 0x98, FIL_,
+		0xCC, 0xB1, FIL_, 0xE1, 0xB9, 0x9E, FIL_, 0xCC,
+		0xA3, FIL_, 0xE1, 0xB9, 0x9A, FIL_, 0xCC, 0x87,
+		FIL_, 0xE1, 0xB9, 0x98, FIL_, 0xCC, 0x81, FIL_,
+		0xC5, 0x94, FIL_, 0xCC, 0x8F, FIL_, 0xC8, 0x90,
+		FIL_, 0x07, 0xCC, 0x81, FIL_, 0xC5, 0x9A, FIL_,
+		0xCC, 0x82, FIL_, 0xC5, 0x9C, FIL_, 0xCC, 0xA7,
+		FIL_, 0xC5, 0x9E, FIL_, 0xCC, 0x8C, FIL_, 0xC5,
+		0xA0, FIL_, 0xCC, 0xA6, FIL_, 0xC8, 0x98, FIL_,
+		0xCC, 0x87, FIL_, 0xE1, 0xB9, 0xA0, FIL_, 0xCC,
+		0xA3, FIL_, 0xE1, 0xB9, 0xA2, FIL_, 0x07, 0xCC,
+		0x8C, FIL_, 0xC5, 0xA4, FIL_, 0xCC, 0xB1, FIL_,
+		0xE1, 0xB9, 0xAE, FIL_, 0xCC, 0xA6, FIL_, 0xC8,
+		0x9A, FIL_, 0xCC, 0xA7, FIL_, 0xC5, 0xA2, FIL_,
+		0xCC, 0x87, FIL_, 0xE1, 0xB9, 0xAA, FIL_, 0xCC,
+		0xAD, FIL_, 0xE1, 0xB9, 0xB0, FIL_, 0xCC, 0xA3,
+		FIL_, 0xE1, 0xB9, 0xAC, FIL_, 0x13, 0xCC, 0xA8,
+		FIL_, 0xC5, 0xB2, FIL_, 0xCC, 0x83, FIL_, 0xC5,
+		0xA8, FIL_, 0xCC, 0x84, FIL_, 0xC5, 0xAA, FIL_,
+		0xCC, 0x81, FIL_, 0xC3, 0x9A, FIL_, 0xCC, 0x86,
+		FIL_, 0xC5, 0xAC, FIL_, 0xCC, 0x8A, FIL_, 0xC5,
+		0xAE, FIL_, 0xCC, 0x80, FIL_, 0xC3, 0x99, FIL_,
+		0xCC, 0x91, FIL_, 0xC8, 0x96, FIL_, 0xCC, 0x8B,
+		FIL_, 0xC5, 0xB0, FIL_, 0xCC, 0xA4, FIL_, 0xE1,
+		0xB9, 0xB2, FIL_, 0xCC, 0xB0, FIL_, 0xE1, 0xB9,
+		0xB4, FIL_, 0xCC, 0x8F, FIL_, 0xC8, 0x94, FIL_,
+		0xCC, 0xAD, FIL_, 0xE1, 0xB9, 0xB6, FIL_, 0xCC,
+		0x9B, FIL_, 0xC6, 0xAF, FIL_, 0xCC, 0x82, FIL_,
+		0xC3, 0x9B, FIL_, 0xCC, 0x88, FIL_, 0xC3, 0x9C,
+		FIL_, 0xCC, 0x8C, FIL_, 0xC7, 0x93, FIL_, 0xCC,
+		0xA3, FIL_, 0xE1, 0xBB, 0xA4, FIL_, 0xCC, 0x89,
+		FIL_, 0xE1, 0xBB, 0xA6, FIL_, 0x02, 0xCC, 0x83,
+		FIL_, 0xE1, 0xB9, 0xBC, FIL_, 0xCC, 0xA3, FIL_,
+		0xE1, 0xB9, 0xBE, FIL_, 0x06, 0xCC, 0x82, FIL_,
+		0xC5, 0xB4, FIL_, 0xCC, 0x88, FIL_, 0xE1, 0xBA,
+		0x84, FIL_, 0xCC, 0x87, FIL_, 0xE1, 0xBA, 0x86,
+		FIL_, 0xCC, 0xA3, FIL_, 0xE1, 0xBA, 0x88, FIL_,
+		0xCC, 0x81, FIL_, 0xE1, 0xBA, 0x82, FIL_, 0xCC,
+		0x80, FIL_, 0xE1, 0xBA, 0x80, FIL_, 0x02, 0xCC,
+		0x87, FIL_, 0xE1, 0xBA, 0x8A, FIL_, 0xCC, 0x88,
+		FIL_, 0xE1, 0xBA, 0x8C, FIL_, 0x09, 0xCC, 0x89,
+		FIL_, 0xE1, 0xBB, 0xB6, FIL_, 0xCC, 0x87, FIL_,
+		0xE1, 0xBA, 0x8E, FIL_, 0xCC, 0xA3, FIL_, 0xE1,
+		0xBB, 0xB4, FIL_, 0xCC, 0x81, FIL_, 0xC3, 0x9D,
+		FIL_, 0xCC, 0x84, FIL_, 0xC8, 0xB2, FIL_, 0xCC,
+		0x82, FIL_, 0xC5, 0xB6, FIL_, 0xCC, 0x88, FIL_,
+		0xC5, 0xB8, FIL_, 0xCC, 0x80, FIL_, 0xE1, 0xBB,
+		0xB2, FIL_, 0xCC, 0x83, FIL_, 0xE1, 0xBB, 0xB8,
+		FIL_, 0x06, 0xCC, 0x87, FIL_, 0xC5, 0xBB, FIL_,
+		0xCC, 0xA3, FIL_, 0xE1, 0xBA, 0x92, FIL_, 0xCC,
+		0x8C, FIL_, 0xC5, 0xBD, FIL_, 0xCC, 0xB1, FIL_,
+		0xE1, 0xBA, 0x94, FIL_, 0xCC, 0x82, FIL_, 0xE1,
+		0xBA, 0x90, FIL_, 0xCC, 0x81, FIL_, 0xC5, 0xB9,
+		FIL_, 0x10, 0xCC, 0x8C, FIL_, 0xC7, 0x8E, FIL_,
+		0xCC, 0x8F, FIL_, 0xC8, 0x81, FIL_, 0xCC, 0xA8,
+		FIL_, 0xC4, 0x85, FIL_, 0xCC, 0xA3, FIL_, 0xE1,
+		0xBA, 0xA1, FIL_, 0xCC, 0x86, FIL_, 0xC4, 0x83,
+		FIL_, 0xCC, 0x89, FIL_, 0xE1, 0xBA, 0xA3, FIL_,
+		0xCC, 0x84, FIL_, 0xC4, 0x81, FIL_, 0xCC, 0x91,
+		FIL_, 0xC8, 0x83, FIL_, 0xCC, 0x8A, FIL_, 0xC3,
+		0xA5, FIL_, 0xCC, 0x88, FIL_, 0xC3, 0xA4, FIL_,
+		0xCC, 0x83, FIL_, 0xC3, 0xA3, FIL_, 0xCC, 0x82,
+		FIL_, 0xC3, 0xA2, FIL_, 0xCC, 0x81, FIL_, 0xC3,
+		0xA1, FIL_, 0xCC, 0x80, FIL_, 0xC3, 0xA0, FIL_,
+		0xCC, 0x87, FIL_, 0xC8, 0xA7, FIL_, 0xCC, 0xA5,
+		FIL_, 0xE1, 0xB8, 0x81, FIL_, 0x03, 0xCC, 0xB1,
+		FIL_, 0xE1, 0xB8, 0x87, FIL_, 0xCC, 0xA3, FIL_,
+		0xE1, 0xB8, 0x85, FIL_, 0xCC, 0x87, FIL_, 0xE1,
+		0xB8, 0x83, FIL_, 0x05, 0xCC, 0x87, FIL_, 0xC4,
+		0x8B, FIL_, 0xCC, 0xA7, FIL_, 0xC3, 0xA7, FIL_,
+		0xCC, 0x82, FIL_, 0xC4, 0x89, FIL_, 0xCC, 0x8C,
+		FIL_, 0xC4, 0x8D, FIL_, 0xCC, 0x81, FIL_, 0xC4,
+		0x87, FIL_, 0x06, 0xCC, 0xAD, FIL_, 0xE1, 0xB8,
+		0x93, FIL_, 0xCC, 0x87, FIL_, 0xE1, 0xB8, 0x8B,
+		FIL_, 0xCC, 0xA3, FIL_, 0xE1, 0xB8, 0x8D, FIL_,
+		0xCC, 0xB1, FIL_, 0xE1, 0xB8, 0x8F, FIL_, 0xCC,
+		0xA7, FIL_, 0xE1, 0xB8, 0x91, FIL_, 0xCC, 0x8C,
+		FIL_, 0xC4, 0x8F, FIL_, 0x11, 0xCC, 0xA8, FIL_,
+		0xC4, 0x99, FIL_, 0xCC, 0x8C, FIL_, 0xC4, 0x9B,
+		FIL_, 0xCC, 0x87, FIL_, 0xC4, 0x97, FIL_, 0xCC,
+		0x88, FIL_, 0xC3, 0xAB, FIL_, 0xCC, 0xA3, FIL_,
+		0xE1, 0xBA, 0xB9, FIL_, 0xCC, 0xB0, FIL_, 0xE1,
+		0xB8, 0x9B, FIL_, 0xCC, 0x84, FIL_, 0xC4, 0x93,
+		FIL_, 0xCC, 0xAD, FIL_, 0xE1, 0xB8, 0x99, FIL_,
+		0xCC, 0x83, FIL_, 0xE1, 0xBA, 0xBD, FIL_, 0xCC,
+		0x86, FIL_, 0xC4, 0x95, FIL_, 0xCC, 0xA7, FIL_,
+		0xC8, 0xA9, FIL_, 0xCC, 0x89, FIL_, 0xE1, 0xBA,
+		0xBB, FIL_, 0xCC, 0x8F, FIL_, 0xC8, 0x85, FIL_,
+		0xCC, 0x81, FIL_, 0xC3, 0xA9, FIL_, 0xCC, 0x91,
+		FIL_, 0xC8, 0x87, FIL_, 0xCC, 0x80, FIL_, 0xC3,
+		0xA8, FIL_, 0xCC, 0x82, FIL_, 0xC3, 0xAA, FIL_,
+		0x01, 0xCC, 0x87, FIL_, 0xE1, 0xB8, 0x9F, FIL_,
+		0x07, 0xCC, 0x86, FIL_, 0xC4, 0x9F, FIL_, 0xCC,
+		0xA7, FIL_, 0xC4, 0xA3, FIL_, 0xCC, 0x81, FIL_,
+		0xC7, 0xB5, FIL_, 0xCC, 0x82, FIL_, 0xC4, 0x9D,
+		FIL_, 0xCC, 0x87, FIL_, 0xC4, 0xA1, FIL_, 0xCC,
+		0x8C, FIL_, 0xC7, 0xA7, FIL_, 0xCC, 0x84, FIL_,
+		0xE1, 0xB8, 0xA1, FIL_, 0x08, 0xCC, 0x8C, FIL_,
+		0xC8, 0x9F, FIL_, 0xCC, 0x82, FIL_, 0xC4, 0xA5,
+		FIL_, 0xCC, 0x88, FIL_, 0xE1, 0xB8, 0xA7, FIL_,
+		0xCC, 0x87, FIL_, 0xE1, 0xB8, 0xA3, FIL_, 0xCC,
+		0xB1, FIL_, 0xE1, 0xBA, 0x96, FIL_, 0xCC, 0xA3,
+		FIL_, 0xE1, 0xB8, 0xA5, FIL_, 0xCC, 0xA7, FIL_,
+		0xE1, 0xB8, 0xA9, FIL_, 0xCC, 0xAE, FIL_, 0xE1,
+		0xB8, 0xAB, FIL_, 0x0E, 0xCC, 0x81, FIL_, 0xC3,
+		0xAD, FIL_, 0xCC, 0x80, FIL_, 0xC3, 0xAC, FIL_,
+		0xCC, 0xA3, FIL_, 0xE1, 0xBB, 0x8B, FIL_, 0xCC,
+		0x8C, FIL_, 0xC7, 0x90, FIL_, 0xCC, 0x89, FIL_,
+		0xE1, 0xBB, 0x89, FIL_, 0xCC, 0x91, FIL_, 0xC8,
+		0x8B, FIL_, 0xCC, 0x8F, FIL_, 0xC8, 0x89, FIL_,
+		0xCC, 0x82, FIL_, 0xC3, 0xAE, FIL_, 0xCC, 0xB0,
+		FIL_, 0xE1, 0xB8, 0xAD, FIL_, 0xCC, 0xA8, FIL_,
+		0xC4, 0xAF, FIL_, 0xCC, 0x86, FIL_, 0xC4, 0xAD,
+		FIL_, 0xCC, 0x84, FIL_, 0xC4, 0xAB, FIL_, 0xCC,
+		0x83, FIL_, 0xC4, 0xA9, FIL_, 0xCC, 0x88, FIL_,
+		0xC3, 0xAF, FIL_, 0x02, 0xCC, 0x82, FIL_, 0xC4,
+		0xB5, FIL_, 0xCC, 0x8C, FIL_, 0xC7, 0xB0, FIL_,
+		0x05, 0xCC, 0xA3, FIL_, 0xE1, 0xB8, 0xB3, FIL_,
+		0xCC, 0x81, FIL_, 0xE1, 0xB8, 0xB1, FIL_, 0xCC,
+		0xA7, FIL_, 0xC4, 0xB7, FIL_, 0xCC, 0x8C, FIL_,
+		0xC7, 0xA9, FIL_, 0xCC, 0xB1, FIL_, 0xE1, 0xB8,
+		0xB5, FIL_, 0x06, 0xCC, 0xA3, FIL_, 0xE1, 0xB8,
+		0xB7, FIL_, 0xCC, 0x81, FIL_, 0xC4, 0xBA, FIL_,
+		0xCC, 0xA7, FIL_, 0xC4, 0xBC, FIL_, 0xCC, 0x8C,
+		FIL_, 0xC4, 0xBE, FIL_, 0xCC, 0xB1, FIL_, 0xE1,
+		0xB8, 0xBB, FIL_, 0xCC, 0xAD, FIL_, 0xE1, 0xB8,
+		0xBD, FIL_, 0x03, 0xCC, 0xA3, FIL_, 0xE1, 0xB9,
+		0x83, FIL_, 0xCC, 0x81, FIL_, 0xE1, 0xB8, 0xBF,
+		FIL_, 0xCC, 0x87, FIL_, 0xE1, 0xB9, 0x81, FIL_,
+		0x09, 0xCC, 0xA3, FIL_, 0xE1, 0xB9, 0x87, FIL_,
+		0xCC, 0x83, FIL_, 0xC3, 0xB1, FIL_, 0xCC, 0x87,
+		FIL_, 0xE1, 0xB9, 0x85, FIL_, 0xCC, 0xB1, FIL_,
+		0xE1, 0xB9, 0x89, FIL_, 0xCC, 0x81, FIL_, 0xC5,
+		0x84, FIL_, 0xCC, 0xA7, FIL_, 0xC5, 0x86, FIL_,
+		0xCC, 0xAD, FIL_, 0xE1, 0xB9, 0x8B, FIL_, 0xCC,
+		0x8C, FIL_, 0xC5, 0x88, FIL_, 0xCC, 0x80, FIL_,
+		0xC7, 0xB9, FIL_, 0x10, 0xCC, 0x89, FIL_, 0xE1,
+		0xBB, 0x8F, FIL_, 0xCC, 0x81, FIL_, 0xC3, 0xB3,
+		FIL_, 0xCC, 0x80, FIL_, 0xC3, 0xB2, FIL_, 0xCC,
+		0x87, FIL_, 0xC8, 0xAF, FIL_, 0xCC, 0x8F, FIL_,
+		0xC8, 0x8D, FIL_, 0xCC, 0xA3, FIL_, 0xE1, 0xBB,
+		0x8D, FIL_, 0xCC, 0x84, FIL_, 0xC5, 0x8D, FIL_,
+		0xCC, 0x8C, FIL_, 0xC7, 0x92, FIL_, 0xCC, 0x86,
+		FIL_, 0xC5, 0x8F, FIL_, 0xCC, 0x8B, FIL_, 0xC5,
+		0x91, FIL_, 0xCC, 0x9B, FIL_, 0xC6, 0xA1, FIL_,
+		0xCC, 0x91, FIL_, 0xC8, 0x8F, FIL_, 0xCC, 0xA8,
+		FIL_, 0xC7, 0xAB, FIL_, 0xCC, 0x88, FIL_, 0xC3,
+		0xB6, FIL_, 0xCC, 0x83, FIL_, 0xC3, 0xB5, FIL_,
+		0xCC, 0x82, FIL_, 0xC3, 0xB4, FIL_, 0x02, 0xCC,
+		0x87, FIL_, 0xE1, 0xB9, 0x97, FIL_, 0xCC, 0x81,
+		FIL_, 0xE1, 0xB9, 0x95, FIL_, 0x08, 0xCC, 0xB1,
+		FIL_, 0xE1, 0xB9, 0x9F, FIL_, 0xCC, 0x87, FIL_,
+		0xE1, 0xB9, 0x99, FIL_, 0xCC, 0x81, FIL_, 0xC5,
+		0x95, FIL_, 0xCC, 0x8F, FIL_, 0xC8, 0x91, FIL_,
+		0xCC, 0xA3, FIL_, 0xE1, 0xB9, 0x9B, FIL_, 0xCC,
+		0x8C, FIL_, 0xC5, 0x99, FIL_, 0xCC, 0x91, FIL_,
+		0xC8, 0x93, FIL_, 0xCC, 0xA7, FIL_, 0xC5, 0x97,
+		FIL_, 0x07, 0xCC, 0xA6, FIL_, 0xC8, 0x99, FIL_,
+		0xCC, 0x8C, FIL_, 0xC5, 0xA1, FIL_, 0xCC, 0x81,
+		FIL_, 0xC5, 0x9B, FIL_, 0xCC, 0x87, FIL_, 0xE1,
+		0xB9, 0xA1, FIL_, 0xCC, 0x82, FIL_, 0xC5, 0x9D,
+		FIL_, 0xCC, 0xA7, FIL_, 0xC5, 0x9F, FIL_, 0xCC,
+		0xA3, FIL_, 0xE1, 0xB9, 0xA3, FIL_, 0x08, 0xCC,
+		0x88, FIL_, 0xE1, 0xBA, 0x97, FIL_, 0xCC, 0xAD,
+		FIL_, 0xE1, 0xB9, 0xB1, FIL_, 0xCC, 0xB1, FIL_,
+		0xE1, 0xB9, 0xAF, FIL_, 0xCC, 0xA3, FIL_, 0xE1,
+		0xB9, 0xAD, FIL_, 0xCC, 0x8C, FIL_, 0xC5, 0xA5,
+		FIL_, 0xCC, 0xA7, FIL_, 0xC5, 0xA3, FIL_, 0xCC,
+		0x87, FIL_, 0xE1, 0xB9, 0xAB, FIL_, 0xCC, 0xA6,
+		FIL_, 0xC8, 0x9B, FIL_, 0x13, 0xCC, 0x81, FIL_,
+		0xC3, 0xBA, FIL_, 0xCC, 0x91, FIL_, 0xC8, 0x97,
+		FIL_, 0xCC, 0x83, FIL_, 0xC5, 0xA9, FIL_, 0xCC,
+		0x8F, FIL_, 0xC8, 0x95, FIL_, 0xCC, 0xA8, FIL_,
+		0xC5, 0xB3, FIL_, 0xCC, 0x82, FIL_, 0xC3, 0xBB,
+		FIL_, 0xCC, 0x88, FIL_, 0xC3, 0xBC, FIL_, 0xCC,
+		0x80, FIL_, 0xC3, 0xB9, FIL_, 0xCC, 0xA3, FIL_,
+		0xE1, 0xBB, 0xA5, FIL_, 0xCC, 0xA4, FIL_, 0xE1,
+		0xB9, 0xB3, FIL_, 0xCC, 0x89, FIL_, 0xE1, 0xBB,
+		0xA7, FIL_, 0xCC, 0xB0, FIL_, 0xE1, 0xB9, 0xB5,
+		FIL_, 0xCC, 0xAD, FIL_, 0xE1, 0xB9, 0xB7, FIL_,
+		0xCC, 0x9B, FIL_, 0xC6, 0xB0, FIL_, 0xCC, 0x84,
+		FIL_, 0xC5, 0xAB, FIL_, 0xCC, 0x8B, FIL_, 0xC5,
+		0xB1, FIL_, 0xCC, 0x86, FIL_, 0xC5, 0xAD, FIL_,
+		0xCC, 0x8C, FIL_, 0xC7, 0x94, FIL_, 0xCC, 0x8A,
+		FIL_, 0xC5, 0xAF, FIL_, 0x02, 0xCC, 0x83, FIL_,
+		0xE1, 0xB9, 0xBD, FIL_, 0xCC, 0xA3, FIL_, 0xE1,
+		0xB9, 0xBF, FIL_, 0x07, 0xCC, 0x82, FIL_, 0xC5,
+		0xB5, FIL_, 0xCC, 0x80, FIL_, 0xE1, 0xBA, 0x81,
+		FIL_, 0xCC, 0x81, FIL_, 0xE1, 0xBA, 0x83, FIL_,
+		0xCC, 0x88, FIL_, 0xE1, 0xBA, 0x85, FIL_, 0xCC,
+		0xA3, FIL_, 0xE1, 0xBA, 0x89, FIL_, 0xCC, 0x87,
+		FIL_, 0xE1, 0xBA, 0x87, FIL_, 0xCC, 0x8A, FIL_,
+		0xE1, 0xBA, 0x98, FIL_, 0x02, 0xCC, 0x87, FIL_,
+		0xE1, 0xBA, 0x8B, FIL_, 0xCC, 0x88, FIL_, 0xE1,
+		0xBA, 0x8D, FIL_, 0x0A, 0xCC, 0x87, FIL_, 0xE1,
+		0xBA, 0x8F, FIL_, 0xCC, 0x83, FIL_, 0xE1, 0xBB,
+		0xB9, FIL_, 0xCC, 0x80, FIL_, 0xE1, 0xBB, 0xB3,
+		FIL_, 0xCC, 0x89, FIL_, 0xE1, 0xBB, 0xB7, FIL_,
+		0xCC, 0xA3, FIL_, 0xE1, 0xBB, 0xB5, FIL_, 0xCC,
+		0x82, FIL_, 0xC5, 0xB7, FIL_, 0xCC, 0x84, FIL_,
+		0xC8, 0xB3, FIL_, 0xCC, 0x8A, FIL_, 0xE1, 0xBA,
+		0x99, FIL_, 0xCC, 0x88, FIL_, 0xC3, 0xBF, FIL_,
+		0xCC, 0x81, FIL_, 0xC3, 0xBD, FIL_, 0x06, 0xCC,
+		0x8C, FIL_, 0xC5, 0xBE, FIL_, 0xCC, 0x87, FIL_,
+		0xC5, 0xBC, FIL_, 0xCC, 0xB1, FIL_, 0xE1, 0xBA,
+		0x95, FIL_, 0xCC, 0xA3, FIL_, 0xE1, 0xBA, 0x93,
+		FIL_, 0xCC, 0x81, FIL_, 0xC5, 0xBA, FIL_, 0xCC,
+		0x82, FIL_, 0xE1, 0xBA, 0x91, FIL_, 0x03, 0xCC,
+		0x80, FIL_, 0xE1, 0xBF, 0xAD, FIL_, 0xCD, 0x82,
+		FIL_, 0xE1, 0xBF, 0x81, FIL_, 0xCC, 0x81, FIL_,
+		0xCE, 0x85, FIL_, 0x04, 0xCC, 0x89, FIL_, 0xE1,
+		0xBA, 0xA8, FIL_, 0xCC, 0x83, FIL_, 0xE1, 0xBA,
+		0xAA, FIL_, 0xCC, 0x81, FIL_, 0xE1, 0xBA, 0xA4,
+		FIL_, 0xCC, 0x80, FIL_, 0xE1, 0xBA, 0xA6, FIL_,
+		0x01, 0xCC, 0x84, FIL_, 0xC7, 0x9E, FIL_, 0x01,
+		0xCC, 0x81, FIL_, 0xC7, 0xBA, FIL_, 0x02, 0xCC,
+		0x84, FIL_, 0xC7, 0xA2, FIL_, 0xCC, 0x81, FIL_,
+		0xC7, 0xBC, FIL_, 0x01, 0xCC, 0x81, FIL_, 0xE1,
+		0xB8, 0x88, FIL_, 0x04, 0xCC, 0x81, FIL_, 0xE1,
+		0xBA, 0xBE, FIL_, 0xCC, 0x80, FIL_, 0xE1, 0xBB,
+		0x80, FIL_, 0xCC, 0x83, FIL_, 0xE1, 0xBB, 0x84,
+		FIL_, 0xCC, 0x89, FIL_, 0xE1, 0xBB, 0x82, FIL_,
+		0x01, 0xCC, 0x81, FIL_, 0xE1, 0xB8, 0xAE, FIL_,
+		0x04, 0xCC, 0x83, FIL_, 0xE1, 0xBB, 0x96, FIL_,
+		0xCC, 0x81, FIL_, 0xE1, 0xBB, 0x90, FIL_, 0xCC,
+		0x80, FIL_, 0xE1, 0xBB, 0x92, FIL_, 0xCC, 0x89,
+		FIL_, 0xE1, 0xBB, 0x94, FIL_, 0x03, 0xCC, 0x84,
+		FIL_, 0xC8, 0xAC, FIL_, 0xCC, 0x81, FIL_, 0xE1,
+		0xB9, 0x8C, FIL_, 0xCC, 0x88, FIL_, 0xE1, 0xB9,
+		0x8E, FIL_, 0x01, 0xCC, 0x84, FIL_, 0xC8, 0xAA,
+		FIL_, 0x01, 0xCC, 0x81, FIL_, 0xC7, 0xBE, FIL_,
+		0x04, 0xCC, 0x80, FIL_, 0xC7, 0x9B, FIL_, 0xCC,
+		0x84, FIL_, 0xC7, 0x95, FIL_, 0xCC, 0x8C, FIL_,
+		0xC7, 0x99, FIL_, 0xCC, 0x81, FIL_, 0xC7, 0x97,
+		FIL_, 0x04, 0xCC, 0x89, FIL_, 0xE1, 0xBA, 0xA9,
+		FIL_, 0xCC, 0x80, FIL_, 0xE1, 0xBA, 0xA7, FIL_,
+		0xCC, 0x81, FIL_, 0xE1, 0xBA, 0xA5, FIL_, 0xCC,
+		0x83, FIL_, 0xE1, 0xBA, 0xAB, FIL_, 0x01, 0xCC,
+		0x84, FIL_, 0xC7, 0x9F, FIL_, 0x01, 0xCC, 0x81,
+		FIL_, 0xC7, 0xBB, FIL_, 0x02, 0xCC, 0x84, FIL_,
+		0xC7, 0xA3, FIL_, 0xCC, 0x81, FIL_, 0xC7, 0xBD,
+		FIL_, 0x01, 0xCC, 0x81, FIL_, 0xE1, 0xB8, 0x89,
+		FIL_, 0x04, 0xCC, 0x89, FIL_, 0xE1, 0xBB, 0x83,
+		FIL_, 0xCC, 0x81, FIL_, 0xE1, 0xBA, 0xBF, FIL_,
+		0xCC, 0x80, FIL_, 0xE1, 0xBB, 0x81, FIL_, 0xCC,
+		0x83, FIL_, 0xE1, 0xBB, 0x85, FIL_, 0x01, 0xCC,
+		0x81, FIL_, 0xE1, 0xB8, 0xAF, FIL_, 0x04, 0xCC,
+		0x83, FIL_, 0xE1, 0xBB, 0x97, FIL_, 0xCC, 0x89,
+		FIL_, 0xE1, 0xBB, 0x95, FIL_, 0xCC, 0x80, FIL_,
+		0xE1, 0xBB, 0x93, FIL_, 0xCC, 0x81, FIL_, 0xE1,
+		0xBB, 0x91, FIL_, 0x03, 0xCC, 0x81, FIL_, 0xE1,
+		0xB9, 0x8D, FIL_, 0xCC, 0x84, FIL_, 0xC8, 0xAD,
+		FIL_, 0xCC, 0x88, FIL_, 0xE1, 0xB9, 0x8F, FIL_,
+		0x01, 0xCC, 0x84, FIL_, 0xC8, 0xAB, FIL_, 0x01,
+		0xCC, 0x81, FIL_, 0xC7, 0xBF, FIL_, 0x04, 0xCC,
+		0x81, FIL_, 0xC7, 0x98, FIL_, 0xCC, 0x84, FIL_,
+		0xC7, 0x96, FIL_, 0xCC, 0x8C, FIL_, 0xC7, 0x9A,
+		FIL_, 0xCC, 0x80, FIL_, 0xC7, 0x9C, FIL_, 0x04,
+		0xCC, 0x80, FIL_, 0xE1, 0xBA, 0xB0, FIL_, 0xCC,
+		0x81, FIL_, 0xE1, 0xBA, 0xAE, FIL_, 0xCC, 0x83,
+		FIL_, 0xE1, 0xBA, 0xB4, FIL_, 0xCC, 0x89, FIL_,
+		0xE1, 0xBA, 0xB2, FIL_, 0x04, 0xCC, 0x80, FIL_,
+		0xE1, 0xBA, 0xB1, FIL_, 0xCC, 0x83, FIL_, 0xE1,
+		0xBA, 0xB5, FIL_, 0xCC, 0x81, FIL_, 0xE1, 0xBA,
+		0xAF, FIL_, 0xCC, 0x89, FIL_, 0xE1, 0xBA, 0xB3,
+		FIL_, 0x02, 0xCC, 0x81, FIL_, 0xE1, 0xB8, 0x96,
+		FIL_, 0xCC, 0x80, FIL_, 0xE1, 0xB8, 0x94, FIL_,
+		0x02, 0xCC, 0x80, FIL_, 0xE1, 0xB8, 0x95, FIL_,
+		0xCC, 0x81, FIL_, 0xE1, 0xB8, 0x97, FIL_, 0x02,
+		0xCC, 0x80, FIL_, 0xE1, 0xB9, 0x90, FIL_, 0xCC,
+		0x81, FIL_, 0xE1, 0xB9, 0x92, FIL_, 0x02, 0xCC,
+		0x80, FIL_, 0xE1, 0xB9, 0x91, FIL_, 0xCC, 0x81,
+		FIL_, 0xE1, 0xB9, 0x93, FIL_, 0x01, 0xCC, 0x87,
+		FIL_, 0xE1, 0xB9, 0xA4, FIL_, 0x01, 0xCC, 0x87,
+		FIL_, 0xE1, 0xB9, 0xA5, FIL_, 0x01, 0xCC, 0x87,
+		FIL_, 0xE1, 0xB9, 0xA6, FIL_, 0x01, 0xCC, 0x87,
+		FIL_, 0xE1, 0xB9, 0xA7, FIL_, 0x01, 0xCC, 0x81,
+		FIL_, 0xE1, 0xB9, 0xB8, FIL_, 0x01, 0xCC, 0x81,
+		FIL_, 0xE1, 0xB9, 0xB9, FIL_, 0x01, 0xCC, 0x88,
+		FIL_, 0xE1, 0xB9, 0xBA, FIL_, 0x01, 0xCC, 0x88,
+		FIL_, 0xE1, 0xB9, 0xBB, FIL_, 0x01, 0xCC, 0x87,
+		FIL_, 0xE1, 0xBA, 0x9B, FIL_, 0x05, 0xCC, 0x80,
+		FIL_, 0xE1, 0xBB, 0x9C, FIL_, 0xCC, 0x81, FIL_,
+		0xE1, 0xBB, 0x9A, FIL_, 0xCC, 0xA3, FIL_, 0xE1,
+		0xBB, 0xA2, FIL_, 0xCC, 0x83, FIL_, 0xE1, 0xBB,
+		0xA0, FIL_, 0xCC, 0x89, FIL_, 0xE1, 0xBB, 0x9E,
+		FIL_, 0x05, 0xCC, 0x83, FIL_, 0xE1, 0xBB, 0xA1,
+		FIL_, 0xCC, 0x81, FIL_, 0xE1, 0xBB, 0x9B, FIL_,
+		0xCC, 0xA3, FIL_, 0xE1, 0xBB, 0xA3, FIL_, 0xCC,
+		0x89, FIL_, 0xE1, 0xBB, 0x9F, FIL_, 0xCC, 0x80,
+		FIL_, 0xE1, 0xBB, 0x9D, FIL_, 0x05, 0xCC, 0x83,
+		FIL_, 0xE1, 0xBB, 0xAE, FIL_, 0xCC, 0xA3, FIL_,
+		0xE1, 0xBB, 0xB0, FIL_, 0xCC, 0x89, FIL_, 0xE1,
+		0xBB, 0xAC, FIL_, 0xCC, 0x81, FIL_, 0xE1, 0xBB,
+		0xA8, FIL_, 0xCC, 0x80, FIL_, 0xE1, 0xBB, 0xAA,
+		FIL_, 0x05, 0xCC, 0xA3, FIL_, 0xE1, 0xBB, 0xB1,
+		FIL_, 0xCC, 0x83, FIL_, 0xE1, 0xBB, 0xAF, FIL_,
+		0xCC, 0x89, FIL_, 0xE1, 0xBB, 0xAD, FIL_, 0xCC,
+		0x81, FIL_, 0xE1, 0xBB, 0xA9, FIL_, 0xCC, 0x80,
+		FIL_, 0xE1, 0xBB, 0xAB, FIL_, 0x01, 0xCC, 0x8C,
+		FIL_, 0xC7, 0xAE, FIL_, 0x01, 0xCC, 0x84, FIL_,
+		0xC7, 0xAC, FIL_, 0x01, 0xCC, 0x84, FIL_, 0xC7,
+		0xAD, FIL_, 0x01, 0xCC, 0x84, FIL_, 0xC7, 0xA0,
+		FIL_, 0x01, 0xCC, 0x84, FIL_, 0xC7, 0xA1, FIL_,
+		0x01, 0xCC, 0x86, FIL_, 0xE1, 0xB8, 0x9C, FIL_,
+		0x01, 0xCC, 0x86, FIL_, 0xE1, 0xB8, 0x9D, FIL_,
+		0x01, 0xCC, 0x84, FIL_, 0xC8, 0xB0, FIL_, 0x01,
+		0xCC, 0x84, FIL_, 0xC8, 0xB1, FIL_, 0x01, 0xCC,
+		0x8C, FIL_, 0xC7, 0xAF, FIL_, 0x07, 0xCC, 0x93,
+		FIL_, 0xE1, 0xBC, 0x88, FIL_, 0xCC, 0x94, FIL_,
+		0xE1, 0xBC, 0x89, FIL_, 0xCC, 0x81, FIL_, 0xCE,
+		0x86, FIL_, 0xCD, 0x85, FIL_, 0xE1, 0xBE, 0xBC,
+		FIL_, 0xCC, 0x80, FIL_, 0xE1, 0xBE, 0xBA, FIL_,
+		0xCC, 0x84, FIL_, 0xE1, 0xBE, 0xB9, FIL_, 0xCC,
+		0x86, FIL_, 0xE1, 0xBE, 0xB8, FIL_, 0x04, 0xCC,
+		0x81, FIL_, 0xCE, 0x88, FIL_, 0xCC, 0x94, FIL_,
+		0xE1, 0xBC, 0x99, FIL_, 0xCC, 0x93, FIL_, 0xE1,
+		0xBC, 0x98, FIL_, 0xCC, 0x80, FIL_, 0xE1, 0xBF,
+		0x88, FIL_, 0x05, 0xCC, 0x94, FIL_, 0xE1, 0xBC,
+		0xA9, FIL_, 0xCC, 0x80, FIL_, 0xE1, 0xBF, 0x8A,
+		FIL_, 0xCC, 0x81, FIL_, 0xCE, 0x89, FIL_, 0xCD,
+		0x85, FIL_, 0xE1, 0xBF, 0x8C, FIL_, 0xCC, 0x93,
+		FIL_, 0xE1, 0xBC, 0xA8, FIL_, 0x07, 0xCC, 0x81,
+		FIL_, 0xCE, 0x8A, FIL_, 0xCC, 0x88, FIL_, 0xCE,
+		0xAA, FIL_, 0xCC, 0x86, FIL_, 0xE1, 0xBF, 0x98,
+		FIL_, 0xCC, 0x84, FIL_, 0xE1, 0xBF, 0x99, FIL_,
+		0xCC, 0x93, FIL_, 0xE1, 0xBC, 0xB8, FIL_, 0xCC,
+		0x94, FIL_, 0xE1, 0xBC, 0xB9, FIL_, 0xCC, 0x80,
+		FIL_, 0xE1, 0xBF, 0x9A, FIL_, 0x04, 0xCC, 0x94,
+		FIL_, 0xE1, 0xBD, 0x89, FIL_, 0xCC, 0x80, FIL_,
+		0xE1, 0xBF, 0xB8, FIL_, 0xCC, 0x81, FIL_, 0xCE,
+		0x8C, FIL_, 0xCC, 0x93, FIL_, 0xE1, 0xBD, 0x88,
+		FIL_, 0x01, 0xCC, 0x94, FIL_, 0xE1, 0xBF, 0xAC,
+		FIL_, 0x06, 0xCC, 0x81, FIL_, 0xCE, 0x8E, FIL_,
+		0xCC, 0x86, FIL_, 0xE1, 0xBF, 0xA8, FIL_, 0xCC,
+		0x94, FIL_, 0xE1, 0xBD, 0x99, FIL_, 0xCC, 0x80,
+		FIL_, 0xE1, 0xBF, 0xAA, FIL_, 0xCC, 0x84, FIL_,
+		0xE1, 0xBF, 0xA9, FIL_, 0xCC, 0x88, FIL_, 0xCE,
+		0xAB, FIL_, 0x05, 0xCC, 0x80, FIL_, 0xE1, 0xBF,
+		0xBA, FIL_, 0xCC, 0x81, FIL_, 0xCE, 0x8F, FIL_,
+		0xCD, 0x85, FIL_, 0xE1, 0xBF, 0xBC, FIL_, 0xCC,
+		0x94, FIL_, 0xE1, 0xBD, 0xA9, FIL_, 0xCC, 0x93,
+		FIL_, 0xE1, 0xBD, 0xA8, FIL_, 0x01, 0xCD, 0x85,
+		FIL_, 0xE1, 0xBE, 0xB4, FIL_, 0x01, 0xCD, 0x85,
+		FIL_, 0xE1, 0xBF, 0x84, FIL_, 0x08, 0xCC, 0x81,
+		FIL_, 0xCE, 0xAC, FIL_, 0xCC, 0x80, FIL_, 0xE1,
+		0xBD, 0xB0, FIL_, 0xCC, 0x93, FIL_, 0xE1, 0xBC,
+		0x80, FIL_, 0xCC, 0x94, FIL_, 0xE1, 0xBC, 0x81,
+		FIL_, 0xCD, 0x82, FIL_, 0xE1, 0xBE, 0xB6, FIL_,
+		0xCC, 0x86, FIL_, 0xE1, 0xBE, 0xB0, FIL_, 0xCD,
+		0x85, FIL_, 0xE1, 0xBE, 0xB3, FIL_, 0xCC, 0x84,
+		FIL_, 0xE1, 0xBE, 0xB1, FIL_, 0x04, 0xCC, 0x81,
+		FIL_, 0xCE, 0xAD, FIL_, 0xCC, 0x94, FIL_, 0xE1,
+		0xBC, 0x91, FIL_, 0xCC, 0x80, FIL_, 0xE1, 0xBD,
+		0xB2, FIL_, 0xCC, 0x93, FIL_, 0xE1, 0xBC, 0x90,
+		FIL_, 0x06, 0xCC, 0x81, FIL_, 0xCE, 0xAE, FIL_,
+		0xCC, 0x80, FIL_, 0xE1, 0xBD, 0xB4, FIL_, 0xCD,
+		0x85, FIL_, 0xE1, 0xBF, 0x83, FIL_, 0xCD, 0x82,
+		FIL_, 0xE1, 0xBF, 0x86, FIL_, 0xCC, 0x94, FIL_,
+		0xE1, 0xBC, 0xA1, FIL_, 0xCC, 0x93, FIL_, 0xE1,
+		0xBC, 0xA0, FIL_, 0x08, 0xCD, 0x82, FIL_, 0xE1,
+		0xBF, 0x96, FIL_, 0xCC, 0x86, FIL_, 0xE1, 0xBF,
+		0x90, FIL_, 0xCC, 0x93, FIL_, 0xE1, 0xBC, 0xB0,
+		FIL_, 0xCC, 0x81, FIL_, 0xCE, 0xAF, FIL_, 0xCC,
+		0x94, FIL_, 0xE1, 0xBC, 0xB1, FIL_, 0xCC, 0x84,
+		FIL_, 0xE1, 0xBF, 0x91, FIL_, 0xCC, 0x88, FIL_,
+		0xCF, 0x8A, FIL_, 0xCC, 0x80, FIL_, 0xE1, 0xBD,
+		0xB6, FIL_, 0x04, 0xCC, 0x81, FIL_, 0xCF, 0x8C,
+		FIL_, 0xCC, 0x80, FIL_, 0xE1, 0xBD, 0xB8, FIL_,
+		0xCC, 0x93, FIL_, 0xE1, 0xBD, 0x80, FIL_, 0xCC,
+		0x94, FIL_, 0xE1, 0xBD, 0x81, FIL_, 0x02, 0xCC,
+		0x93, FIL_, 0xE1, 0xBF, 0xA4, FIL_, 0xCC, 0x94,
+		FIL_, 0xE1, 0xBF, 0xA5, FIL_, 0x08, 0xCC, 0x93,
+		FIL_, 0xE1, 0xBD, 0x90, FIL_, 0xCC, 0x94, FIL_,
+		0xE1, 0xBD, 0x91, FIL_, 0xCC, 0x86, FIL_, 0xE1,
+		0xBF, 0xA0, FIL_, 0xCD, 0x82, FIL_, 0xE1, 0xBF,
+		0xA6, FIL_, 0xCC, 0x84, FIL_, 0xE1, 0xBF, 0xA1,
+		FIL_, 0xCC, 0x80, FIL_, 0xE1, 0xBD, 0xBA, FIL_,
+		0xCC, 0x81, FIL_, 0xCF, 0x8D, FIL_, 0xCC, 0x88,
+		FIL_, 0xCF, 0x8B, FIL_, 0x06, 0xCC, 0x94, FIL_,
+		0xE1, 0xBD, 0xA1, FIL_, 0xCD, 0x85, FIL_, 0xE1,
+		0xBF, 0xB3, FIL_, 0xCC, 0x80, FIL_, 0xE1, 0xBD,
+		0xBC, FIL_, 0xCD, 0x82, FIL_, 0xE1, 0xBF, 0xB6,
+		FIL_, 0xCC, 0x93, FIL_, 0xE1, 0xBD, 0xA0, FIL_,
+		0xCC, 0x81, FIL_, 0xCF, 0x8E, FIL_, 0x03, 0xCD,
+		0x82, FIL_, 0xE1, 0xBF, 0x97, FIL_, 0xCC, 0x80,
+		FIL_, 0xE1, 0xBF, 0x92, FIL_, 0xCC, 0x81, FIL_,
+		0xCE, 0x90, FIL_, 0x03, 0xCC, 0x80, FIL_, 0xE1,
+		0xBF, 0xA2, FIL_, 0xCC, 0x81, FIL_, 0xCE, 0xB0,
+		FIL_, 0xCD, 0x82, FIL_, 0xE1, 0xBF, 0xA7, FIL_,
+		0x01, 0xCD, 0x85, FIL_, 0xE1, 0xBF, 0xB4, FIL_,
+		0x02, 0xCC, 0x88, FIL_, 0xCF, 0x94, FIL_, 0xCC,
+		0x81, FIL_, 0xCF, 0x93, FIL_, 0x01, 0xCC, 0x88,
+		FIL_, 0xD0, 0x87, FIL_, 0x02, 0xCC, 0x86, FIL_,
+		0xD3, 0x90, FIL_, 0xCC, 0x88, FIL_, 0xD3, 0x92,
+		FIL_, 0x01, 0xCC, 0x81, FIL_, 0xD0, 0x83, FIL_,
+		0x03, 0xCC, 0x86, FIL_, 0xD3, 0x96, FIL_, 0xCC,
+		0x80, FIL_, 0xD0, 0x80, FIL_, 0xCC, 0x88, FIL_,
+		0xD0, 0x81, FIL_, 0x02, 0xCC, 0x88, FIL_, 0xD3,
+		0x9C, FIL_, 0xCC, 0x86, FIL_, 0xD3, 0x81, FIL_,
+		0x01, 0xCC, 0x88, FIL_, 0xD3, 0x9E, FIL_, 0x04,
+		0xCC, 0x80, FIL_, 0xD0, 0x8D, FIL_, 0xCC, 0x88,
+		FIL_, 0xD3, 0xA4, FIL_, 0xCC, 0x86, FIL_, 0xD0,
+		0x99, FIL_, 0xCC, 0x84, FIL_, 0xD3, 0xA2, FIL_,
+		0x01, 0xCC, 0x81, FIL_, 0xD0, 0x8C, FIL_, 0x01,
+		0xCC, 0x88, FIL_, 0xD3, 0xA6, FIL_, 0x04, 0xCC,
+		0x86, FIL_, 0xD0, 0x8E, FIL_, 0xCC, 0x8B, FIL_,
+		0xD3, 0xB2, FIL_, 0xCC, 0x88, FIL_, 0xD3, 0xB0,
+		FIL_, 0xCC, 0x84, FIL_, 0xD3, 0xAE, FIL_, 0x01,
+		0xCC, 0x88, FIL_, 0xD3, 0xB4, FIL_, 0x01, 0xCC,
+		0x88, FIL_, 0xD3, 0xB8, FIL_, 0x01, 0xCC, 0x88,
+		FIL_, 0xD3, 0xAC, FIL_, 0x02, 0xCC, 0x86, FIL_,
+		0xD3, 0x91, FIL_, 0xCC, 0x88, FIL_, 0xD3, 0x93,
+		FIL_, 0x01, 0xCC, 0x81, FIL_, 0xD1, 0x93, FIL_,
+		0x03, 0xCC, 0x80, FIL_, 0xD1, 0x90, FIL_, 0xCC,
+		0x88, FIL_, 0xD1, 0x91, FIL_, 0xCC, 0x86, FIL_,
+		0xD3, 0x97, FIL_, 0x02, 0xCC, 0x88, FIL_, 0xD3,
+		0x9D, FIL_, 0xCC, 0x86, FIL_, 0xD3, 0x82, FIL_,
+		0x01, 0xCC, 0x88, FIL_, 0xD3, 0x9F, FIL_, 0x04,
+		0xCC, 0x88, FIL_, 0xD3, 0xA5, FIL_, 0xCC, 0x86,
+		FIL_, 0xD0, 0xB9, FIL_, 0xCC, 0x80, FIL_, 0xD1,
+		0x9D, FIL_, 0xCC, 0x84, FIL_, 0xD3, 0xA3, FIL_,
+		0x01, 0xCC, 0x81, FIL_, 0xD1, 0x9C, FIL_, 0x01,
+		0xCC, 0x88, FIL_, 0xD3, 0xA7, FIL_, 0x04, 0xCC,
+		0x84, FIL_, 0xD3, 0xAF, FIL_, 0xCC, 0x86, FIL_,
+		0xD1, 0x9E, FIL_, 0xCC, 0x8B, FIL_, 0xD3, 0xB3,
+		FIL_, 0xCC, 0x88, FIL_, 0xD3, 0xB1, FIL_, 0x01,
+		0xCC, 0x88, FIL_, 0xD3, 0xB5, FIL_, 0x01, 0xCC,
+		0x88, FIL_, 0xD3, 0xB9, FIL_, 0x01, 0xCC, 0x88,
+		FIL_, 0xD3, 0xAD, FIL_, 0x01, 0xCC, 0x88, FIL_,
+		0xD1, 0x97, FIL_, 0x01, 0xCC, 0x8F, FIL_, 0xD1,
+		0xB6, FIL_, 0x01, 0xCC, 0x8F, FIL_, 0xD1, 0xB7,
+		FIL_, 0x01, 0xCC, 0x88, FIL_, 0xD3, 0x9A, FIL_,
+		0x01, 0xCC, 0x88, FIL_, 0xD3, 0x9B, FIL_, 0x01,
+		0xCC, 0x88, FIL_, 0xD3, 0xAA, FIL_, 0x01, 0xCC,
+		0x88, FIL_, 0xD3, 0xAB, FIL_, 0x03, 0xD9, 0x94,
+		FIL_, 0xD8, 0xA3, FIL_, 0xD9, 0x93, FIL_, 0xD8,
+		0xA2, FIL_, 0xD9, 0x95, FIL_, 0xD8, 0xA5, FIL_,
+		0x01, 0xD9, 0x94, FIL_, 0xD8, 0xA4, FIL_, 0x01,
+		0xD9, 0x94, FIL_, 0xD8, 0xA6, FIL_, 0x01, 0xD9,
+		0x94, FIL_, 0xDB, 0x82, FIL_, 0x01, 0xD9, 0x94,
+		FIL_, 0xDB, 0x93, FIL_, 0x01, 0xD9, 0x94, FIL_,
+		0xDB, 0x80, FIL_, 0x01, 0xE0, 0xA4, 0xBC, FIL_,
+		0xE0, 0xA4, 0xA9, FIL_, 0x01, 0xE0, 0xA4, 0xBC,
+		FIL_, 0xE0, 0xA4, 0xB1, FIL_, 0x01, 0xE0, 0xA4,
+		0xBC, FIL_, 0xE0, 0xA4, 0xB4, FIL_, 0x02, 0xE0,
+		0xA6, 0xBE, FIL_, 0xE0, 0xA7, 0x8B, FIL_, 0xE0,
+		0xA7, 0x97, FIL_, 0xE0, 0xA7, 0x8C, FIL_, 0x03,
+		0xE0, 0xAD, 0x97, FIL_, 0xE0, 0xAD, 0x8C, FIL_,
+		0xE0, 0xAC, 0xBE, FIL_, 0xE0, 0xAD, 0x8B, FIL_,
+		0xE0, 0xAD, 0x96, FIL_, 0xE0, 0xAD, 0x88, FIL_,
+		0x01, 0xE0, 0xAF, 0x97, FIL_, 0xE0, 0xAE, 0x94,
+		FIL_, 0x02, 0xE0, 0xAE, 0xBE, FIL_, 0xE0, 0xAF,
+		0x8A, FIL_, 0xE0, 0xAF, 0x97, FIL_, 0xE0, 0xAF,
+		0x8C, FIL_, 0x01, 0xE0, 0xAE, 0xBE, FIL_, 0xE0,
+		0xAF, 0x8B, FIL_, 0x01, 0xE0, 0xB1, 0x96, FIL_,
+		0xE0, 0xB1, 0x88, FIL_, 0x01, 0xE0, 0xB3, 0x95,
+		FIL_, 0xE0, 0xB3, 0x80, FIL_, 0x03, 0xE0, 0xB3,
+		0x95, FIL_, 0xE0, 0xB3, 0x87, FIL_, 0xE0, 0xB3,
+		0x82, FIL_, 0xE0, 0xB3, 0x8A, FIL_, 0xE0, 0xB3,
+		0x96, FIL_, 0xE0, 0xB3, 0x88, FIL_, 0x01, 0xE0,
+		0xB3, 0x95, FIL_, 0xE0, 0xB3, 0x8B, FIL_, 0x02,
+		0xE0, 0xB4, 0xBE, FIL_, 0xE0, 0xB5, 0x8A, FIL_,
+		0xE0, 0xB5, 0x97, FIL_, 0xE0, 0xB5, 0x8C, FIL_,
+		0x01, 0xE0, 0xB4, 0xBE, FIL_, 0xE0, 0xB5, 0x8B,
+		FIL_, 0x03, 0xE0, 0xB7, 0x8F, FIL_, 0xE0, 0xB7,
+		0x9C, FIL_, 0xE0, 0xB7, 0x8A, FIL_, 0xE0, 0xB7,
+		0x9A, FIL_, 0xE0, 0xB7, 0x9F, FIL_, 0xE0, 0xB7,
+		0x9E, FIL_, 0x01, 0xE0, 0xB7, 0x8A, FIL_, 0xE0,
+		0xB7, 0x9D, FIL_, 0x01, 0xE1, 0x80, 0xAE, FIL_,
+		0xE1, 0x80, 0xA6, FIL_, 0x01, 0xCC, 0x84, FIL_,
+		0xE1, 0xB8, 0xB8, FIL_, 0x01, 0xCC, 0x84, FIL_,
+		0xE1, 0xB8, 0xB9, FIL_, 0x01, 0xCC, 0x84, FIL_,
+		0xE1, 0xB9, 0x9C, FIL_, 0x01, 0xCC, 0x84, FIL_,
+		0xE1, 0xB9, 0x9D, FIL_, 0x01, 0xCC, 0x87, FIL_,
+		0xE1, 0xB9, 0xA8, FIL_, 0x01, 0xCC, 0x87, FIL_,
+		0xE1, 0xB9, 0xA9, FIL_, 0x02, 0xCC, 0x86, FIL_,
+		0xE1, 0xBA, 0xB6, FIL_, 0xCC, 0x82, FIL_, 0xE1,
+		0xBA, 0xAC, FIL_, 0x02, 0xCC, 0x86, FIL_, 0xE1,
+		0xBA, 0xB7, FIL_, 0xCC, 0x82, FIL_, 0xE1, 0xBA,
+		0xAD, FIL_, 0x01, 0xCC, 0x82, FIL_, 0xE1, 0xBB,
+		0x86, FIL_, 0x01, 0xCC, 0x82, FIL_, 0xE1, 0xBB,
+		0x87, FIL_, 0x01, 0xCC, 0x82, FIL_, 0xE1, 0xBB,
+		0x98, FIL_, 0x01, 0xCC, 0x82, FIL_, 0xE1, 0xBB,
+		0x99, FIL_, 0x04, 0xCC, 0x80, FIL_, 0xE1, 0xBC,
+		0x82, FIL_, 0xCC, 0x81, FIL_, 0xE1, 0xBC, 0x84,
+		FIL_, 0xCD, 0x85, FIL_, 0xE1, 0xBE, 0x80, FIL_,
+		0xCD, 0x82, FIL_, 0xE1, 0xBC, 0x86, FIL_, 0x04,
+		0xCD, 0x82, FIL_, 0xE1, 0xBC, 0x87, FIL_, 0xCC,
+		0x80, FIL_, 0xE1, 0xBC, 0x83, FIL_, 0xCC, 0x81,
+		FIL_, 0xE1, 0xBC, 0x85, FIL_, 0xCD, 0x85, FIL_,
+		0xE1, 0xBE, 0x81, FIL_, 0x01, 0xCD, 0x85, FIL_,
+		0xE1, 0xBE, 0x82, FIL_, 0x01, 0xCD, 0x85, FIL_,
+		0xE1, 0xBE, 0x83, FIL_, 0x01, 0xCD, 0x85, FIL_,
+		0xE1, 0xBE, 0x84, FIL_, 0x01, 0xCD, 0x85, FIL_,
+		0xE1, 0xBE, 0x85, FIL_, 0x01, 0xCD, 0x85, FIL_,
+		0xE1, 0xBE, 0x86, FIL_, 0x01, 0xCD, 0x85, FIL_,
+		0xE1, 0xBE, 0x87, FIL_, 0x04, 0xCD, 0x85, FIL_,
+		0xE1, 0xBE, 0x88, FIL_, 0xCC, 0x80, FIL_, 0xE1,
+		0xBC, 0x8A, FIL_, 0xCD, 0x82, FIL_, 0xE1, 0xBC,
+		0x8E, FIL_, 0xCC, 0x81, FIL_, 0xE1, 0xBC, 0x8C,
+		FIL_, 0x04, 0xCC, 0x81, FIL_, 0xE1, 0xBC, 0x8D,
+		FIL_, 0xCC, 0x80, FIL_, 0xE1, 0xBC, 0x8B, FIL_,
+		0xCD, 0x82, FIL_, 0xE1, 0xBC, 0x8F, FIL_, 0xCD,
+		0x85, FIL_, 0xE1, 0xBE, 0x89, FIL_, 0x01, 0xCD,
+		0x85, FIL_, 0xE1, 0xBE, 0x8A, FIL_, 0x01, 0xCD,
+		0x85, FIL_, 0xE1, 0xBE, 0x8B, FIL_, 0x01, 0xCD,
+		0x85, FIL_, 0xE1, 0xBE, 0x8C, FIL_, 0x01, 0xCD,
+		0x85, FIL_, 0xE1, 0xBE, 0x8D, FIL_, 0x01, 0xCD,
+		0x85, FIL_, 0xE1, 0xBE, 0x8E, FIL_, 0x01, 0xCD,
+		0x85, FIL_, 0xE1, 0xBE, 0x8F, FIL_, 0x02, 0xCC,
+		0x80, FIL_, 0xE1, 0xBC, 0x92, FIL_, 0xCC, 0x81,
+		FIL_, 0xE1, 0xBC, 0x94, FIL_, 0x02, 0xCC, 0x80,
+		FIL_, 0xE1, 0xBC, 0x93, FIL_, 0xCC, 0x81, FIL_,
+		0xE1, 0xBC, 0x95, FIL_, 0x02, 0xCC, 0x80, FIL_,
+		0xE1, 0xBC, 0x9A, FIL_, 0xCC, 0x81, FIL_, 0xE1,
+		0xBC, 0x9C, FIL_, 0x02, 0xCC, 0x80, FIL_, 0xE1,
+		0xBC, 0x9B, FIL_, 0xCC, 0x81, FIL_, 0xE1, 0xBC,
+		0x9D, FIL_, 0x04, 0xCD, 0x82, FIL_, 0xE1, 0xBC,
+		0xA6, FIL_, 0xCD, 0x85, FIL_, 0xE1, 0xBE, 0x90,
+		FIL_, 0xCC, 0x81, FIL_, 0xE1, 0xBC, 0xA4, FIL_,
+		0xCC, 0x80, FIL_, 0xE1, 0xBC, 0xA2, FIL_, 0x04,
+		0xCC, 0x80, FIL_, 0xE1, 0xBC, 0xA3, FIL_, 0xCC,
+		0x81, FIL_, 0xE1, 0xBC, 0xA5, FIL_, 0xCD, 0x82,
+		FIL_, 0xE1, 0xBC, 0xA7, FIL_, 0xCD, 0x85, FIL_,
+		0xE1, 0xBE, 0x91, FIL_, 0x01, 0xCD, 0x85, FIL_,
+		0xE1, 0xBE, 0x92, FIL_, 0x01, 0xCD, 0x85, FIL_,
+		0xE1, 0xBE, 0x93, FIL_, 0x01, 0xCD, 0x85, FIL_,
+		0xE1, 0xBE, 0x94, FIL_, 0x01, 0xCD, 0x85, FIL_,
+		0xE1, 0xBE, 0x95, FIL_, 0x01, 0xCD, 0x85, FIL_,
+		0xE1, 0xBE, 0x96, FIL_, 0x01, 0xCD, 0x85, FIL_,
+		0xE1, 0xBE, 0x97, FIL_, 0x04, 0xCD, 0x82, FIL_,
+		0xE1, 0xBC, 0xAE, FIL_, 0xCC, 0x81, FIL_, 0xE1,
+		0xBC, 0xAC, FIL_, 0xCD, 0x85, FIL_, 0xE1, 0xBE,
+		0x98, FIL_, 0xCC, 0x80, FIL_, 0xE1, 0xBC, 0xAA,
+		FIL_, 0x04, 0xCD, 0x82, FIL_, 0xE1, 0xBC, 0xAF,
+		FIL_, 0xCD, 0x85, FIL_, 0xE1, 0xBE, 0x99, FIL_,
+		0xCC, 0x81, FIL_, 0xE1, 0xBC, 0xAD, FIL_, 0xCC,
+		0x80, FIL_, 0xE1, 0xBC, 0xAB, FIL_, 0x01, 0xCD,
+		0x85, FIL_, 0xE1, 0xBE, 0x9A, FIL_, 0x01, 0xCD,
+		0x85, FIL_, 0xE1, 0xBE, 0x9B, FIL_, 0x01, 0xCD,
+		0x85, FIL_, 0xE1, 0xBE, 0x9C, FIL_, 0x01, 0xCD,
+		0x85, FIL_, 0xE1, 0xBE, 0x9D, FIL_, 0x01, 0xCD,
+		0x85, FIL_, 0xE1, 0xBE, 0x9E, FIL_, 0x01, 0xCD,
+		0x85, FIL_, 0xE1, 0xBE, 0x9F, FIL_, 0x03, 0xCC,
+		0x81, FIL_, 0xE1, 0xBC, 0xB4, FIL_, 0xCD, 0x82,
+		FIL_, 0xE1, 0xBC, 0xB6, FIL_, 0xCC, 0x80, FIL_,
+		0xE1, 0xBC, 0xB2, FIL_, 0x03, 0xCC, 0x81, FIL_,
+		0xE1, 0xBC, 0xB5, FIL_, 0xCD, 0x82, FIL_, 0xE1,
+		0xBC, 0xB7, FIL_, 0xCC, 0x80, FIL_, 0xE1, 0xBC,
+		0xB3, FIL_, 0x03, 0xCC, 0x81, FIL_, 0xE1, 0xBC,
+		0xBC, FIL_, 0xCC, 0x80, FIL_, 0xE1, 0xBC, 0xBA,
+		FIL_, 0xCD, 0x82, FIL_, 0xE1, 0xBC, 0xBE, FIL_,
+		0x03, 0xCC, 0x80, FIL_, 0xE1, 0xBC, 0xBB, FIL_,
+		0xCD, 0x82, FIL_, 0xE1, 0xBC, 0xBF, FIL_, 0xCC,
+		0x81, FIL_, 0xE1, 0xBC, 0xBD, FIL_, 0x02, 0xCC,
+		0x80, FIL_, 0xE1, 0xBD, 0x82, FIL_, 0xCC, 0x81,
+		FIL_, 0xE1, 0xBD, 0x84, FIL_, 0x02, 0xCC, 0x80,
+		FIL_, 0xE1, 0xBD, 0x83, FIL_, 0xCC, 0x81, FIL_,
+		0xE1, 0xBD, 0x85, FIL_, 0x02, 0xCC, 0x81, FIL_,
+		0xE1, 0xBD, 0x8C, FIL_, 0xCC, 0x80, FIL_, 0xE1,
+		0xBD, 0x8A, FIL_, 0x02, 0xCC, 0x81, FIL_, 0xE1,
+		0xBD, 0x8D, FIL_, 0xCC, 0x80, FIL_, 0xE1, 0xBD,
+		0x8B, FIL_, 0x03, 0xCC, 0x81, FIL_, 0xE1, 0xBD,
+		0x94, FIL_, 0xCD, 0x82, FIL_, 0xE1, 0xBD, 0x96,
+		FIL_, 0xCC, 0x80, FIL_, 0xE1, 0xBD, 0x92, FIL_,
+		0x03, 0xCD, 0x82, FIL_, 0xE1, 0xBD, 0x97, FIL_,
+		0xCC, 0x81, FIL_, 0xE1, 0xBD, 0x95, FIL_, 0xCC,
+		0x80, FIL_, 0xE1, 0xBD, 0x93, FIL_, 0x03, 0xCC,
+		0x81, FIL_, 0xE1, 0xBD, 0x9D, FIL_, 0xCD, 0x82,
+		FIL_, 0xE1, 0xBD, 0x9F, FIL_, 0xCC, 0x80, FIL_,
+		0xE1, 0xBD, 0x9B, FIL_, 0x04, 0xCC, 0x81, FIL_,
+		0xE1, 0xBD, 0xA4, FIL_, 0xCC, 0x80, FIL_, 0xE1,
+		0xBD, 0xA2, FIL_, 0xCD, 0x82, FIL_, 0xE1, 0xBD,
+		0xA6, FIL_, 0xCD, 0x85, FIL_, 0xE1, 0xBE, 0xA0,
+		FIL_, 0x04, 0xCD, 0x82, FIL_, 0xE1, 0xBD, 0xA7,
+		FIL_, 0xCC, 0x81, FIL_, 0xE1, 0xBD, 0xA5, FIL_,
+		0xCD, 0x85, FIL_, 0xE1, 0xBE, 0xA1, FIL_, 0xCC,
+		0x80, FIL_, 0xE1, 0xBD, 0xA3, FIL_, 0x01, 0xCD,
+		0x85, FIL_, 0xE1, 0xBE, 0xA2, FIL_, 0x01, 0xCD,
+		0x85, FIL_, 0xE1, 0xBE, 0xA3, FIL_, 0x01, 0xCD,
+		0x85, FIL_, 0xE1, 0xBE, 0xA4, FIL_, 0x01, 0xCD,
+		0x85, FIL_, 0xE1, 0xBE, 0xA5, FIL_, 0x01, 0xCD,
+		0x85, FIL_, 0xE1, 0xBE, 0xA6, FIL_, 0x01, 0xCD,
+		0x85, FIL_, 0xE1, 0xBE, 0xA7, FIL_, 0x04, 0xCC,
+		0x81, FIL_, 0xE1, 0xBD, 0xAC, FIL_, 0xCC, 0x80,
+		FIL_, 0xE1, 0xBD, 0xAA, FIL_, 0xCD, 0x82, FIL_,
+		0xE1, 0xBD, 0xAE, FIL_, 0xCD, 0x85, FIL_, 0xE1,
+		0xBE, 0xA8, FIL_, 0x04, 0xCC, 0x81, FIL_, 0xE1,
+		0xBD, 0xAD, FIL_, 0xCD, 0x85, FIL_, 0xE1, 0xBE,
+		0xA9, FIL_, 0xCD, 0x82, FIL_, 0xE1, 0xBD, 0xAF,
+		FIL_, 0xCC, 0x80, FIL_, 0xE1, 0xBD, 0xAB, FIL_,
+		0x01, 0xCD, 0x85, FIL_, 0xE1, 0xBE, 0xAA, FIL_,
+		0x01, 0xCD, 0x85, FIL_, 0xE1, 0xBE, 0xAB, FIL_,
+		0x01, 0xCD, 0x85, FIL_, 0xE1, 0xBE, 0xAC, FIL_,
+		0x01, 0xCD, 0x85, FIL_, 0xE1, 0xBE, 0xAD, FIL_,
+		0x01, 0xCD, 0x85, FIL_, 0xE1, 0xBE, 0xAE, FIL_,
+		0x01, 0xCD, 0x85, FIL_, 0xE1, 0xBE, 0xAF, FIL_,
+		0x01, 0xCD, 0x85, FIL_, 0xE1, 0xBE, 0xB2, FIL_,
+		0x01, 0xCD, 0x85, FIL_, 0xE1, 0xBF, 0x82, FIL_,
+		0x01, 0xCD, 0x85, FIL_, 0xE1, 0xBF, 0xB2, FIL_,
+		0x01, 0xCD, 0x85, FIL_, 0xE1, 0xBE, 0xB7, FIL_,
+		0x03, 0xCD, 0x82, FIL_, 0xE1, 0xBF, 0x8F, FIL_,
+		0xCC, 0x80, FIL_, 0xE1, 0xBF, 0x8D, FIL_, 0xCC,
+		0x81, FIL_, 0xE1, 0xBF, 0x8E, FIL_, 0x01, 0xCD,
+		0x85, FIL_, 0xE1, 0xBF, 0x87, FIL_, 0x01, 0xCD,
+		0x85, FIL_, 0xE1, 0xBF, 0xB7, FIL_, 0x03, 0xCC,
+		0x80, FIL_, 0xE1, 0xBF, 0x9D, FIL_, 0xCD, 0x82,
+		FIL_, 0xE1, 0xBF, 0x9F, FIL_, 0xCC, 0x81, FIL_,
+		0xE1, 0xBF, 0x9E, FIL_, 0x01, 0xCC, 0xB8, FIL_,
+		0xE2, 0x86, 0x9A, FIL_, 0x01, 0xCC, 0xB8, FIL_,
+		0xE2, 0x86, 0x9B, FIL_, 0x01, 0xCC, 0xB8, FIL_,
+		0xE2, 0x86, 0xAE, FIL_, 0x01, 0xCC, 0xB8, FIL_,
+		0xE2, 0x87, 0x8D, FIL_, 0x01, 0xCC, 0xB8, FIL_,
+		0xE2, 0x87, 0x8F, FIL_, 0x01, 0xCC, 0xB8, FIL_,
+		0xE2, 0x87, 0x8E, FIL_, 0x01, 0xCC, 0xB8, FIL_,
+		0xE2, 0x88, 0x84, FIL_, 0x01, 0xCC, 0xB8, FIL_,
+		0xE2, 0x88, 0x89, FIL_, 0x01, 0xCC, 0xB8, FIL_,
+		0xE2, 0x88, 0x8C, FIL_, 0x01, 0xCC, 0xB8, FIL_,
+		0xE2, 0x88, 0xA4, FIL_, 0x01, 0xCC, 0xB8, FIL_,
+		0xE2, 0x88, 0xA6, FIL_, 0x01, 0xCC, 0xB8, FIL_,
+		0xE2, 0x89, 0x81, FIL_, 0x01, 0xCC, 0xB8, FIL_,
+		0xE2, 0x89, 0x84, FIL_, 0x01, 0xCC, 0xB8, FIL_,
+		0xE2, 0x89, 0x87, FIL_, 0x01, 0xCC, 0xB8, FIL_,
+		0xE2, 0x89, 0x89, FIL_, 0x01, 0xCC, 0xB8, FIL_,
+		0xE2, 0x89, 0xAD, FIL_, 0x01, 0xCC, 0xB8, FIL_,
+		0xE2, 0x89, 0xA2, FIL_, 0x01, 0xCC, 0xB8, FIL_,
+		0xE2, 0x89, 0xB0, FIL_, 0x01, 0xCC, 0xB8, FIL_,
+		0xE2, 0x89, 0xB1, FIL_, 0x01, 0xCC, 0xB8, FIL_,
+		0xE2, 0x89, 0xB4, FIL_, 0x01, 0xCC, 0xB8, FIL_,
+		0xE2, 0x89, 0xB5, FIL_, 0x01, 0xCC, 0xB8, FIL_,
+		0xE2, 0x89, 0xB8, FIL_, 0x01, 0xCC, 0xB8, FIL_,
+		0xE2, 0x89, 0xB9, FIL_, 0x01, 0xCC, 0xB8, FIL_,
+		0xE2, 0x8A, 0x80, FIL_, 0x01, 0xCC, 0xB8, FIL_,
+		0xE2, 0x8A, 0x81, FIL_, 0x01, 0xCC, 0xB8, FIL_,
+		0xE2, 0x8B, 0xA0, FIL_, 0x01, 0xCC, 0xB8, FIL_,
+		0xE2, 0x8B, 0xA1, FIL_, 0x01, 0xCC, 0xB8, FIL_,
+		0xE2, 0x8A, 0x84, FIL_, 0x01, 0xCC, 0xB8, FIL_,
+		0xE2, 0x8A, 0x85, FIL_, 0x01, 0xCC, 0xB8, FIL_,
+		0xE2, 0x8A, 0x88, FIL_, 0x01, 0xCC, 0xB8, FIL_,
+		0xE2, 0x8A, 0x89, FIL_, 0x01, 0xCC, 0xB8, FIL_,
+		0xE2, 0x8B, 0xA2, FIL_, 0x01, 0xCC, 0xB8, FIL_,
+		0xE2, 0x8B, 0xA3, FIL_, 0x01, 0xCC, 0xB8, FIL_,
+		0xE2, 0x8A, 0xAC, FIL_, 0x01, 0xCC, 0xB8, FIL_,
+		0xE2, 0x8A, 0xAD, FIL_, 0x01, 0xCC, 0xB8, FIL_,
+		0xE2, 0x8A, 0xAE, FIL_, 0x01, 0xCC, 0xB8, FIL_,
+		0xE2, 0x8A, 0xAF, FIL_, 0x01, 0xCC, 0xB8, FIL_,
+		0xE2, 0x8B, 0xAA, FIL_, 0x01, 0xCC, 0xB8, FIL_,
+		0xE2, 0x8B, 0xAB, FIL_, 0x01, 0xCC, 0xB8, FIL_,
+		0xE2, 0x8B, 0xAC, FIL_, 0x01, 0xCC, 0xB8, FIL_,
+		0xE2, 0x8B, 0xAD, FIL_, 0x01, 0xE3, 0x82, 0x99,
+		FIL_, 0xE3, 0x82, 0x94, FIL_, 0x01, 0xE3, 0x82,
+		0x99, FIL_, 0xE3, 0x81, 0x8C, FIL_, 0x01, 0xE3,
+		0x82, 0x99, FIL_, 0xE3, 0x81, 0x8E, FIL_, 0x01,
+		0xE3, 0x82, 0x99, FIL_, 0xE3, 0x81, 0x90, FIL_,
+		0x01, 0xE3, 0x82, 0x99, FIL_, 0xE3, 0x81, 0x92,
+		FIL_, 0x01, 0xE3, 0x82, 0x99, FIL_, 0xE3, 0x81,
+		0x94, FIL_, 0x01, 0xE3, 0x82, 0x99, FIL_, 0xE3,
+		0x81, 0x96, FIL_, 0x01, 0xE3, 0x82, 0x99, FIL_,
+		0xE3, 0x81, 0x98, FIL_, 0x01, 0xE3, 0x82, 0x99,
+		FIL_, 0xE3, 0x81, 0x9A, FIL_, 0x01, 0xE3, 0x82,
+		0x99, FIL_, 0xE3, 0x81, 0x9C, FIL_, 0x01, 0xE3,
+		0x82, 0x99, FIL_, 0xE3, 0x81, 0x9E, FIL_, 0x01,
+		0xE3, 0x82, 0x99, FIL_, 0xE3, 0x81, 0xA0, FIL_,
+		0x01, 0xE3, 0x82, 0x99, FIL_, 0xE3, 0x81, 0xA2,
+		FIL_, 0x01, 0xE3, 0x82, 0x99, FIL_, 0xE3, 0x81,
+		0xA5, FIL_, 0x01, 0xE3, 0x82, 0x99, FIL_, 0xE3,
+		0x81, 0xA7, FIL_, 0x01, 0xE3, 0x82, 0x99, FIL_,
+		0xE3, 0x81, 0xA9, FIL_, 0x02, 0xE3, 0x82, 0x9A,
+		FIL_, 0xE3, 0x81, 0xB1, FIL_, 0xE3, 0x82, 0x99,
+		FIL_, 0xE3, 0x81, 0xB0, FIL_, 0x02, 0xE3, 0x82,
+		0x9A, FIL_, 0xE3, 0x81, 0xB4, FIL_, 0xE3, 0x82,
+		0x99, FIL_, 0xE3, 0x81, 0xB3, FIL_, 0x02, 0xE3,
+		0x82, 0x9A, FIL_, 0xE3, 0x81, 0xB7, FIL_, 0xE3,
+		0x82, 0x99, FIL_, 0xE3, 0x81, 0xB6, FIL_, 0x02,
+		0xE3, 0x82, 0x99, FIL_, 0xE3, 0x81, 0xB9, FIL_,
+		0xE3, 0x82, 0x9A, FIL_, 0xE3, 0x81, 0xBA, FIL_,
+		0x02, 0xE3, 0x82, 0x99, FIL_, 0xE3, 0x81, 0xBC,
+		FIL_, 0xE3, 0x82, 0x9A, FIL_, 0xE3, 0x81, 0xBD,
+		FIL_, 0x01, 0xE3, 0x82, 0x99, FIL_, 0xE3, 0x82,
+		0x9E, FIL_, 0x01, 0xE3, 0x82, 0x99, FIL_, 0xE3,
+		0x83, 0xB4, FIL_, 0x01, 0xE3, 0x82, 0x99, FIL_,
+		0xE3, 0x82, 0xAC, FIL_, 0x01, 0xE3, 0x82, 0x99,
+		FIL_, 0xE3, 0x82, 0xAE, FIL_, 0x01, 0xE3, 0x82,
+		0x99, FIL_, 0xE3, 0x82, 0xB0, FIL_, 0x01, 0xE3,
+		0x82, 0x99, FIL_, 0xE3, 0x82, 0xB2, FIL_, 0x01,
+		0xE3, 0x82, 0x99, FIL_, 0xE3, 0x82, 0xB4, FIL_,
+		0x01, 0xE3, 0x82, 0x99, FIL_, 0xE3, 0x82, 0xB6,
+		FIL_, 0x01, 0xE3, 0x82, 0x99, FIL_, 0xE3, 0x82,
+		0xB8, FIL_, 0x01, 0xE3, 0x82, 0x99, FIL_, 0xE3,
+		0x82, 0xBA, FIL_, 0x01, 0xE3, 0x82, 0x99, FIL_,
+		0xE3, 0x82, 0xBC, FIL_, 0x01, 0xE3, 0x82, 0x99,
+		FIL_, 0xE3, 0x82, 0xBE, FIL_, 0x01, 0xE3, 0x82,
+		0x99, FIL_, 0xE3, 0x83, 0x80, FIL_, 0x01, 0xE3,
+		0x82, 0x99, FIL_, 0xE3, 0x83, 0x82, FIL_, 0x01,
+		0xE3, 0x82, 0x99, FIL_, 0xE3, 0x83, 0x85, FIL_,
+		0x01, 0xE3, 0x82, 0x99, FIL_, 0xE3, 0x83, 0x87,
+		FIL_, 0x01, 0xE3, 0x82, 0x99, FIL_, 0xE3, 0x83,
+		0x89, FIL_, 0x02, 0xE3, 0x82, 0x99, FIL_, 0xE3,
+		0x83, 0x90, FIL_, 0xE3, 0x82, 0x9A, FIL_, 0xE3,
+		0x83, 0x91, FIL_, 0x02, 0xE3, 0x82, 0x99, FIL_,
+		0xE3, 0x83, 0x93, FIL_, 0xE3, 0x82, 0x9A, FIL_,
+		0xE3, 0x83, 0x94, FIL_, 0x02, 0xE3, 0x82, 0x99,
+		FIL_, 0xE3, 0x83, 0x96, FIL_, 0xE3, 0x82, 0x9A,
+		FIL_, 0xE3, 0x83, 0x97, FIL_, 0x02, 0xE3, 0x82,
+		0x9A, FIL_, 0xE3, 0x83, 0x9A, FIL_, 0xE3, 0x82,
+		0x99, FIL_, 0xE3, 0x83, 0x99, FIL_, 0x02, 0xE3,
+		0x82, 0x9A, FIL_, 0xE3, 0x83, 0x9D, FIL_, 0xE3,
+		0x82, 0x99, FIL_, 0xE3, 0x83, 0x9C, FIL_, 0x01,
+		0xE3, 0x82, 0x99, FIL_, 0xE3, 0x83, 0xB7, FIL_,
+		0x01, 0xE3, 0x82, 0x99, FIL_, 0xE3, 0x83, 0xB8,
+		FIL_, 0x01, 0xE3, 0x82, 0x99, FIL_, 0xE3, 0x83,
+		0xB9, FIL_, 0x01, 0xE3, 0x82, 0x99, FIL_, 0xE3,
+		0x83, 0xBA, FIL_, 0x01, 0xE3, 0x82, 0x99, FIL_,
+		0xE3, 0x83, 0xBE, FIL_, 0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,
+	},
+	{
+		0x01, 0xCC, 0xB8, FIL_, 0xE2, 0x89, 0xAE, FIL_,
+		0x01, 0xCC, 0xB8, FIL_, 0xE2, 0x89, 0xA0, FIL_,
+		0x01, 0xCC, 0xB8, FIL_, 0xE2, 0x89, 0xAF, FIL_,
+		0x10, 0xCC, 0xA5, FIL_, 0xE1, 0xB8, 0x80, FIL_,
+		0xCC, 0x87, FIL_, 0xC8, 0xA6, FIL_, 0xCC, 0x83,
+		FIL_, 0xC3, 0x83, FIL_, 0xCC, 0x91, FIL_, 0xC8,
+		0x82, FIL_, 0xCC, 0x8F, FIL_, 0xC8, 0x80, FIL_,
+		0xCC, 0x8A, FIL_, 0xC3, 0x85, FIL_, 0xCC, 0x88,
+		FIL_, 0xC3, 0x84, FIL_, 0xCC, 0x89, FIL_, 0xE1,
+		0xBA, 0xA2, FIL_, 0xCC, 0xA3, FIL_, 0xE1, 0xBA,
+		0xA0, FIL_, 0xCC, 0x8C, FIL_, 0xC7, 0x8D, FIL_,
+		0xCC, 0x80, FIL_, 0xC3, 0x80, FIL_, 0xCC, 0x81,
+		FIL_, 0xC3, 0x81, FIL_, 0xCC, 0x82, FIL_, 0xC3,
+		0x82, FIL_, 0xCC, 0xA8, FIL_, 0xC4, 0x84, FIL_,
+		0xCC, 0x86, FIL_, 0xC4, 0x82, FIL_, 0xCC, 0x84,
+		FIL_, 0xC4, 0x80, FIL_, 0x03, 0xCC, 0xB1, FIL_,
+		0xE1, 0xB8, 0x86, FIL_, 0xCC, 0x87, FIL_, 0xE1,
+		0xB8, 0x82, FIL_, 0xCC, 0xA3, FIL_, 0xE1, 0xB8,
+		0x84, FIL_, 0x05, 0xCC, 0xA7, FIL_, 0xC3, 0x87,
+		FIL_, 0xCC, 0x8C, FIL_, 0xC4, 0x8C, FIL_, 0xCC,
+		0x81, FIL_, 0xC4, 0x86, FIL_, 0xCC, 0x82, FIL_,
+		0xC4, 0x88, FIL_, 0xCC, 0x87, FIL_, 0xC4, 0x8A,
+		FIL_, 0x06, 0xCC, 0xA7, FIL_, 0xE1, 0xB8, 0x90,
+		FIL_, 0xCC, 0x8C, FIL_, 0xC4, 0x8E, FIL_, 0xCC,
+		0xB1, FIL_, 0xE1, 0xB8, 0x8E, FIL_, 0xCC, 0xAD,
+		FIL_, 0xE1, 0xB8, 0x92, FIL_, 0xCC, 0xA3, FIL_,
+		0xE1, 0xB8, 0x8C, FIL_, 0xCC, 0x87, FIL_, 0xE1,
+		0xB8, 0x8A, FIL_, 0x11, 0xCC, 0x84, FIL_, 0xC4,
+		0x92, FIL_, 0xCC, 0x86, FIL_, 0xC4, 0x94, FIL_,
+		0xCC, 0xA3, FIL_, 0xE1, 0xBA, 0xB8, FIL_, 0xCC,
+		0x91, FIL_, 0xC8, 0x86, FIL_, 0xCC, 0x82, FIL_,
+		0xC3, 0x8A, FIL_, 0xCC, 0x8F, FIL_, 0xC8, 0x84,
+		FIL_, 0xCC, 0xAD, FIL_, 0xE1, 0xB8, 0x98, FIL_,
+		0xCC, 0x89, FIL_, 0xE1, 0xBA, 0xBA, FIL_, 0xCC,
+		0xA7, FIL_, 0xC8, 0xA8, FIL_, 0xCC, 0x8C, FIL_,
+		0xC4, 0x9A, FIL_, 0xCC, 0x80, FIL_, 0xC3, 0x88,
+		FIL_, 0xCC, 0xA8, FIL_, 0xC4, 0x98, FIL_, 0xCC,
+		0x83, FIL_, 0xE1, 0xBA, 0xBC, FIL_, 0xCC, 0x87,
+		FIL_, 0xC4, 0x96, FIL_, 0xCC, 0x81, FIL_, 0xC3,
+		0x89, FIL_, 0xCC, 0x88, FIL_, 0xC3, 0x8B, FIL_,
+		0xCC, 0xB0, FIL_, 0xE1, 0xB8, 0x9A, FIL_, 0x01,
+		0xCC, 0x87, FIL_, 0xE1, 0xB8, 0x9E, FIL_, 0x07,
+		0xCC, 0x8C, FIL_, 0xC7, 0xA6, FIL_, 0xCC, 0x86,
+		FIL_, 0xC4, 0x9E, FIL_, 0xCC, 0x82, FIL_, 0xC4,
+		0x9C, FIL_, 0xCC, 0xA7, FIL_, 0xC4, 0xA2, FIL_,
+		0xCC, 0x84, FIL_, 0xE1, 0xB8, 0xA0, FIL_, 0xCC,
+		0x81, FIL_, 0xC7, 0xB4, FIL_, 0xCC, 0x87, FIL_,
+		0xC4, 0xA0, FIL_, 0x07, 0xCC, 0x87, FIL_, 0xE1,
+		0xB8, 0xA2, FIL_, 0xCC, 0xA7, FIL_, 0xE1, 0xB8,
+		0xA8, FIL_, 0xCC, 0x82, FIL_, 0xC4, 0xA4, FIL_,
+		0xCC, 0x88, FIL_, 0xE1, 0xB8, 0xA6, FIL_, 0xCC,
+		0x8C, FIL_, 0xC8, 0x9E, FIL_, 0xCC, 0xAE, FIL_,
+		0xE1, 0xB8, 0xAA, FIL_, 0xCC, 0xA3, FIL_, 0xE1,
+		0xB8, 0xA4, FIL_, 0x0F, 0xCC, 0xB0, FIL_, 0xE1,
+		0xB8, 0xAC, FIL_, 0xCC, 0x8C, FIL_, 0xC7, 0x8F,
+		FIL_, 0xCC, 0x80, FIL_, 0xC3, 0x8C, FIL_, 0xCC,
+		0x89, FIL_, 0xE1, 0xBB, 0x88, FIL_, 0xCC, 0xA3,
+		FIL_, 0xE1, 0xBB, 0x8A, FIL_, 0xCC, 0x91, FIL_,
+		0xC8, 0x8A, FIL_, 0xCC, 0x88, FIL_, 0xC3, 0x8F,
+		FIL_, 0xCC, 0x82, FIL_, 0xC3, 0x8E, FIL_, 0xCC,
+		0x81, FIL_, 0xC3, 0x8D, FIL_, 0xCC, 0x83, FIL_,
+		0xC4, 0xA8, FIL_, 0xCC, 0x87, FIL_, 0xC4, 0xB0,
+		FIL_, 0xCC, 0x8F, FIL_, 0xC8, 0x88, FIL_, 0xCC,
+		0xA8, FIL_, 0xC4, 0xAE, FIL_, 0xCC, 0x86, FIL_,
+		0xC4, 0xAC, FIL_, 0xCC, 0x84, FIL_, 0xC4, 0xAA,
+		FIL_, 0x01, 0xCC, 0x82, FIL_, 0xC4, 0xB4, FIL_,
+		0x05, 0xCC, 0x81, FIL_, 0xE1, 0xB8, 0xB0, FIL_,
+		0xCC, 0x8C, FIL_, 0xC7, 0xA8, FIL_, 0xCC, 0xB1,
+		FIL_, 0xE1, 0xB8, 0xB4, FIL_, 0xCC, 0xA7, FIL_,
+		0xC4, 0xB6, FIL_, 0xCC, 0xA3, FIL_, 0xE1, 0xB8,
+		0xB2, FIL_, 0x06, 0xCC, 0xA3, FIL_, 0xE1, 0xB8,
+		0xB6, FIL_, 0xCC, 0x8C, FIL_, 0xC4, 0xBD, FIL_,
+		0xCC, 0xAD, FIL_, 0xE1, 0xB8, 0xBC, FIL_, 0xCC,
+		0xB1, FIL_, 0xE1, 0xB8, 0xBA, FIL_, 0xCC, 0xA7,
+		FIL_, 0xC4, 0xBB, FIL_, 0xCC, 0x81, FIL_, 0xC4,
+		0xB9, FIL_, 0x03, 0xCC, 0x81, FIL_, 0xE1, 0xB8,
+		0xBE, FIL_, 0xCC, 0x87, FIL_, 0xE1, 0xB9, 0x80,
+		FIL_, 0xCC, 0xA3, FIL_, 0xE1, 0xB9, 0x82, FIL_,
+		0x09, 0xCC, 0x83, FIL_, 0xC3, 0x91, FIL_, 0xCC,
+		0x81, FIL_, 0xC5, 0x83, FIL_, 0xCC, 0xA7, FIL_,
+		0xC5, 0x85, FIL_, 0xCC, 0x8C, FIL_, 0xC5, 0x87,
+		FIL_, 0xCC, 0x87, FIL_, 0xE1, 0xB9, 0x84, FIL_,
+		0xCC, 0xA3, FIL_, 0xE1, 0xB9, 0x86, FIL_, 0xCC,
+		0xB1, FIL_, 0xE1, 0xB9, 0x88, FIL_, 0xCC, 0xAD,
+		FIL_, 0xE1, 0xB9, 0x8A, FIL_, 0xCC, 0x80, FIL_,
+		0xC7, 0xB8, FIL_, 0x10, 0xCC, 0x89, FIL_, 0xE1,
+		0xBB, 0x8E, FIL_, 0xCC, 0x84, FIL_, 0xC5, 0x8C,
+		FIL_, 0xCC, 0x82, FIL_, 0xC3, 0x94, FIL_, 0xCC,
+		0x86, FIL_, 0xC5, 0x8E, FIL_, 0xCC, 0x83, FIL_,
+		0xC3, 0x95, FIL_, 0xCC, 0x8B, FIL_, 0xC5, 0x90,
+		FIL_, 0xCC, 0x88, FIL_, 0xC3, 0x96, FIL_, 0xCC,
+		0x9B, FIL_, 0xC6, 0xA0, FIL_, 0xCC, 0x91, FIL_,
+		0xC8, 0x8E, FIL_, 0xCC, 0x8C, FIL_, 0xC7, 0x91,
+		FIL_, 0xCC, 0x8F, FIL_, 0xC8, 0x8C, FIL_, 0xCC,
+		0xA3, FIL_, 0xE1, 0xBB, 0x8C, FIL_, 0xCC, 0x80,
+		FIL_, 0xC3, 0x92, FIL_, 0xCC, 0xA8, FIL_, 0xC7,
+		0xAA, FIL_, 0xCC, 0x87, FIL_, 0xC8, 0xAE, FIL_,
+		0xCC, 0x81, FIL_, 0xC3, 0x93, FIL_, 0x02, 0xCC,
+		0x87, FIL_, 0xE1, 0xB9, 0x96, FIL_, 0xCC, 0x81,
+		FIL_, 0xE1, 0xB9, 0x94, FIL_, 0x08, 0xCC, 0xA7,
+		FIL_, 0xC5, 0x96, FIL_, 0xCC, 0x8C, FIL_, 0xC5,
+		0x98, FIL_, 0xCC, 0x91, FIL_, 0xC8, 0x92, FIL_,
+		0xCC, 0x8F, FIL_, 0xC8, 0x90, FIL_, 0xCC, 0x81,
+		FIL_, 0xC5, 0x94, FIL_, 0xCC, 0x87, FIL_, 0xE1,
+		0xB9, 0x98, FIL_, 0xCC, 0xB1, FIL_, 0xE1, 0xB9,
+		0x9E, FIL_, 0xCC, 0xA3, FIL_, 0xE1, 0xB9, 0x9A,
+		FIL_, 0x07, 0xCC, 0xA6, FIL_, 0xC8, 0x98, FIL_,
+		0xCC, 0x81, FIL_, 0xC5, 0x9A, FIL_, 0xCC, 0x82,
+		FIL_, 0xC5, 0x9C, FIL_, 0xCC, 0xA7, FIL_, 0xC5,
+		0x9E, FIL_, 0xCC, 0x8C, FIL_, 0xC5, 0xA0, FIL_,
+		0xCC, 0x87, FIL_, 0xE1, 0xB9, 0xA0, FIL_, 0xCC,
+		0xA3, FIL_, 0xE1, 0xB9, 0xA2, FIL_, 0x07, 0xCC,
+		0xA6, FIL_, 0xC8, 0x9A, FIL_, 0xCC, 0x87, FIL_,
+		0xE1, 0xB9, 0xAA, FIL_, 0xCC, 0xA3, FIL_, 0xE1,
+		0xB9, 0xAC, FIL_, 0xCC, 0xB1, FIL_, 0xE1, 0xB9,
+		0xAE, FIL_, 0xCC, 0xAD, FIL_, 0xE1, 0xB9, 0xB0,
+		FIL_, 0xCC, 0xA7, FIL_, 0xC5, 0xA2, FIL_, 0xCC,
+		0x8C, FIL_, 0xC5, 0xA4, FIL_, 0x13, 0xCC, 0x8A,
+		FIL_, 0xC5, 0xAE, FIL_, 0xCC, 0x88, FIL_, 0xC3,
+		0x9C, FIL_, 0xCC, 0x8B, FIL_, 0xC5, 0xB0, FIL_,
+		0xCC, 0xAD, FIL_, 0xE1, 0xB9, 0xB6, FIL_, 0xCC,
+		0xA8, FIL_, 0xC5, 0xB2, FIL_, 0xCC, 0x8C, FIL_,
+		0xC7, 0x93, FIL_, 0xCC, 0x80, FIL_, 0xC3, 0x99,
+		FIL_, 0xCC, 0x8F, FIL_, 0xC8, 0x94, FIL_, 0xCC,
+		0xA3, FIL_, 0xE1, 0xBB, 0xA4, FIL_, 0xCC, 0xA4,
+		FIL_, 0xE1, 0xB9, 0xB2, FIL_, 0xCC, 0x81, FIL_,
+		0xC3, 0x9A, FIL_, 0xCC, 0x82, FIL_, 0xC3, 0x9B,
+		FIL_, 0xCC, 0xB0, FIL_, 0xE1, 0xB9, 0xB4, FIL_,
+		0xCC, 0x83, FIL_, 0xC5, 0xA8, FIL_, 0xCC, 0x89,
+		FIL_, 0xE1, 0xBB, 0xA6, FIL_, 0xCC, 0x84, FIL_,
+		0xC5, 0xAA, FIL_, 0xCC, 0x91, FIL_, 0xC8, 0x96,
+		FIL_, 0xCC, 0x86, FIL_, 0xC5, 0xAC, FIL_, 0xCC,
+		0x9B, FIL_, 0xC6, 0xAF, FIL_, 0x02, 0xCC, 0xA3,
+		FIL_, 0xE1, 0xB9, 0xBE, FIL_, 0xCC, 0x83, FIL_,
+		0xE1, 0xB9, 0xBC, FIL_, 0x06, 0xCC, 0x88, FIL_,
+		0xE1, 0xBA, 0x84, FIL_, 0xCC, 0x81, FIL_, 0xE1,
+		0xBA, 0x82, FIL_, 0xCC, 0x80, FIL_, 0xE1, 0xBA,
+		0x80, FIL_, 0xCC, 0xA3, FIL_, 0xE1, 0xBA, 0x88,
+		FIL_, 0xCC, 0x82, FIL_, 0xC5, 0xB4, FIL_, 0xCC,
+		0x87, FIL_, 0xE1, 0xBA, 0x86, FIL_, 0x02, 0xCC,
+		0x88, FIL_, 0xE1, 0xBA, 0x8C, FIL_, 0xCC, 0x87,
+		FIL_, 0xE1, 0xBA, 0x8A, FIL_, 0x09, 0xCC, 0x89,
+		FIL_, 0xE1, 0xBB, 0xB6, FIL_, 0xCC, 0xA3, FIL_,
+		0xE1, 0xBB, 0xB4, FIL_, 0xCC, 0x80, FIL_, 0xE1,
+		0xBB, 0xB2, FIL_, 0xCC, 0x88, FIL_, 0xC5, 0xB8,
+		FIL_, 0xCC, 0x81, FIL_, 0xC3, 0x9D, FIL_, 0xCC,
+		0x83, FIL_, 0xE1, 0xBB, 0xB8, FIL_, 0xCC, 0x87,
+		FIL_, 0xE1, 0xBA, 0x8E, FIL_, 0xCC, 0x84, FIL_,
+		0xC8, 0xB2, FIL_, 0xCC, 0x82, FIL_, 0xC5, 0xB6,
+		FIL_, 0x06, 0xCC, 0x82, FIL_, 0xE1, 0xBA, 0x90,
+		FIL_, 0xCC, 0xA3, FIL_, 0xE1, 0xBA, 0x92, FIL_,
+		0xCC, 0xB1, FIL_, 0xE1, 0xBA, 0x94, FIL_, 0xCC,
+		0x8C, FIL_, 0xC5, 0xBD, FIL_, 0xCC, 0x87, FIL_,
+		0xC5, 0xBB, FIL_, 0xCC, 0x81, FIL_, 0xC5, 0xB9,
+		FIL_, 0x10, 0xCC, 0xA3, FIL_, 0xE1, 0xBA, 0xA1,
+		FIL_, 0xCC, 0xA8, FIL_, 0xC4, 0x85, FIL_, 0xCC,
+		0x81, FIL_, 0xC3, 0xA1, FIL_, 0xCC, 0x82, FIL_,
+		0xC3, 0xA2, FIL_, 0xCC, 0x89, FIL_, 0xE1, 0xBA,
+		0xA3, FIL_, 0xCC, 0x83, FIL_, 0xC3, 0xA3, FIL_,
+		0xCC, 0x8C, FIL_, 0xC7, 0x8E, FIL_, 0xCC, 0x8A,
+		FIL_, 0xC3, 0xA5, FIL_, 0xCC, 0x88, FIL_, 0xC3,
+		0xA4, FIL_, 0xCC, 0x87, FIL_, 0xC8, 0xA7, FIL_,
+		0xCC, 0x91, FIL_, 0xC8, 0x83, FIL_, 0xCC, 0xA5,
+		FIL_, 0xE1, 0xB8, 0x81, FIL_, 0xCC, 0x84, FIL_,
+		0xC4, 0x81, FIL_, 0xCC, 0x8F, FIL_, 0xC8, 0x81,
+		FIL_, 0xCC, 0x86, FIL_, 0xC4, 0x83, FIL_, 0xCC,
+		0x80, FIL_, 0xC3, 0xA0, FIL_, 0x03, 0xCC, 0xA3,
+		FIL_, 0xE1, 0xB8, 0x85, FIL_, 0xCC, 0x87, FIL_,
+		0xE1, 0xB8, 0x83, FIL_, 0xCC, 0xB1, FIL_, 0xE1,
+		0xB8, 0x87, FIL_, 0x05, 0xCC, 0x87, FIL_, 0xC4,
+		0x8B, FIL_, 0xCC, 0x8C, FIL_, 0xC4, 0x8D, FIL_,
+		0xCC, 0x82, FIL_, 0xC4, 0x89, FIL_, 0xCC, 0x81,
+		FIL_, 0xC4, 0x87, FIL_, 0xCC, 0xA7, FIL_, 0xC3,
+		0xA7, FIL_, 0x06, 0xCC, 0x87, FIL_, 0xE1, 0xB8,
+		0x8B, FIL_, 0xCC, 0xA7, FIL_, 0xE1, 0xB8, 0x91,
+		FIL_, 0xCC, 0xB1, FIL_, 0xE1, 0xB8, 0x8F, FIL_,
+		0xCC, 0xA3, FIL_, 0xE1, 0xB8, 0x8D, FIL_, 0xCC,
+		0x8C, FIL_, 0xC4, 0x8F, FIL_, 0xCC, 0xAD, FIL_,
+		0xE1, 0xB8, 0x93, FIL_, 0x11, 0xCC, 0x80, FIL_,
+		0xC3, 0xA8, FIL_, 0xCC, 0x81, FIL_, 0xC3, 0xA9,
+		FIL_, 0xCC, 0x82, FIL_, 0xC3, 0xAA, FIL_, 0xCC,
+		0x88, FIL_, 0xC3, 0xAB, FIL_, 0xCC, 0x84, FIL_,
+		0xC4, 0x93, FIL_, 0xCC, 0x86, FIL_, 0xC4, 0x95,
+		FIL_, 0xCC, 0x87, FIL_, 0xC4, 0x97, FIL_, 0xCC,
+		0xA8, FIL_, 0xC4, 0x99, FIL_, 0xCC, 0x8C, FIL_,
+		0xC4, 0x9B, FIL_, 0xCC, 0x8F, FIL_, 0xC8, 0x85,
+		FIL_, 0xCC, 0x91, FIL_, 0xC8, 0x87, FIL_, 0xCC,
+		0xA3, FIL_, 0xE1, 0xBA, 0xB9, FIL_, 0xCC, 0xA7,
+		FIL_, 0xC8, 0xA9, FIL_, 0xCC, 0x83, FIL_, 0xE1,
+		0xBA, 0xBD, FIL_, 0xCC, 0x89, FIL_, 0xE1, 0xBA,
+		0xBB, FIL_, 0xCC, 0xAD, FIL_, 0xE1, 0xB8, 0x99,
+		FIL_, 0xCC, 0xB0, FIL_, 0xE1, 0xB8, 0x9B, FIL_,
+		0x01, 0xCC, 0x87, FIL_, 0xE1, 0xB8, 0x9F, FIL_,
+		0x07, 0xCC, 0x86, FIL_, 0xC4, 0x9F, FIL_, 0xCC,
+		0x87, FIL_, 0xC4, 0xA1, FIL_, 0xCC, 0x82, FIL_,
+		0xC4, 0x9D, FIL_, 0xCC, 0x84, FIL_, 0xE1, 0xB8,
+		0xA1, FIL_, 0xCC, 0x8C, FIL_, 0xC7, 0xA7, FIL_,
+		0xCC, 0xA7, FIL_, 0xC4, 0xA3, FIL_, 0xCC, 0x81,
+		FIL_, 0xC7, 0xB5, FIL_, 0x08, 0xCC, 0xA7, FIL_,
+		0xE1, 0xB8, 0xA9, FIL_, 0xCC, 0xB1, FIL_, 0xE1,
+		0xBA, 0x96, FIL_, 0xCC, 0x8C, FIL_, 0xC8, 0x9F,
+		FIL_, 0xCC, 0xAE, FIL_, 0xE1, 0xB8, 0xAB, FIL_,
+		0xCC, 0x88, FIL_, 0xE1, 0xB8, 0xA7, FIL_, 0xCC,
+		0xA3, FIL_, 0xE1, 0xB8, 0xA5, FIL_, 0xCC, 0x87,
+		FIL_, 0xE1, 0xB8, 0xA3, FIL_, 0xCC, 0x82, FIL_,
+		0xC4, 0xA5, FIL_, 0x0E, 0xCC, 0x88, FIL_, 0xC3,
+		0xAF, FIL_, 0xCC, 0x89, FIL_, 0xE1, 0xBB, 0x89,
+		FIL_, 0xCC, 0xA3, FIL_, 0xE1, 0xBB, 0x8B, FIL_,
+		0xCC, 0x82, FIL_, 0xC3, 0xAE, FIL_, 0xCC, 0x81,
+		FIL_, 0xC3, 0xAD, FIL_, 0xCC, 0x80, FIL_, 0xC3,
+		0xAC, FIL_, 0xCC, 0x83, FIL_, 0xC4, 0xA9, FIL_,
+		0xCC, 0x84, FIL_, 0xC4, 0xAB, FIL_, 0xCC, 0x86,
+		FIL_, 0xC4, 0xAD, FIL_, 0xCC, 0xA8, FIL_, 0xC4,
+		0xAF, FIL_, 0xCC, 0xB0, FIL_, 0xE1, 0xB8, 0xAD,
+		FIL_, 0xCC, 0x8C, FIL_, 0xC7, 0x90, FIL_, 0xCC,
+		0x91, FIL_, 0xC8, 0x8B, FIL_, 0xCC, 0x8F, FIL_,
+		0xC8, 0x89, FIL_, 0x02, 0xCC, 0x8C, FIL_, 0xC7,
+		0xB0, FIL_, 0xCC, 0x82, FIL_, 0xC4, 0xB5, FIL_,
+		0x05, 0xCC, 0xB1, FIL_, 0xE1, 0xB8, 0xB5, FIL_,
+		0xCC, 0xA7, FIL_, 0xC4, 0xB7, FIL_, 0xCC, 0x8C,
+		FIL_, 0xC7, 0xA9, FIL_, 0xCC, 0x81, FIL_, 0xE1,
+		0xB8, 0xB1, FIL_, 0xCC, 0xA3, FIL_, 0xE1, 0xB8,
+		0xB3, FIL_, 0x06, 0xCC, 0xA3, FIL_, 0xE1, 0xB8,
+		0xB7, FIL_, 0xCC, 0xAD, FIL_, 0xE1, 0xB8, 0xBD,
+		FIL_, 0xCC, 0xB1, FIL_, 0xE1, 0xB8, 0xBB, FIL_,
+		0xCC, 0xA7, FIL_, 0xC4, 0xBC, FIL_, 0xCC, 0x81,
+		FIL_, 0xC4, 0xBA, FIL_, 0xCC, 0x8C, FIL_, 0xC4,
+		0xBE, FIL_, 0x03, 0xCC, 0x87, FIL_, 0xE1, 0xB9,
+		0x81, FIL_, 0xCC, 0xA3, FIL_, 0xE1, 0xB9, 0x83,
+		FIL_, 0xCC, 0x81, FIL_, 0xE1, 0xB8, 0xBF, FIL_,
+		0x09, 0xCC, 0x80, FIL_, 0xC7, 0xB9, FIL_, 0xCC,
+		0xAD, FIL_, 0xE1, 0xB9, 0x8B, FIL_, 0xCC, 0x83,
+		FIL_, 0xC3, 0xB1, FIL_, 0xCC, 0x81, FIL_, 0xC5,
+		0x84, FIL_, 0xCC, 0xA3, FIL_, 0xE1, 0xB9, 0x87,
+		FIL_, 0xCC, 0xB1, FIL_, 0xE1, 0xB9, 0x89, FIL_,
+		0xCC, 0x87, FIL_, 0xE1, 0xB9, 0x85, FIL_, 0xCC,
+		0xA7, FIL_, 0xC5, 0x86, FIL_, 0xCC, 0x8C, FIL_,
+		0xC5, 0x88, FIL_, 0x10, 0xCC, 0xA3, FIL_, 0xE1,
+		0xBB, 0x8D, FIL_, 0xCC, 0x87, FIL_, 0xC8, 0xAF,
+		FIL_, 0xCC, 0x80, FIL_, 0xC3, 0xB2, FIL_, 0xCC,
+		0x91, FIL_, 0xC8, 0x8F, FIL_, 0xCC, 0x89, FIL_,
+		0xE1, 0xBB, 0x8F, FIL_, 0xCC, 0x88, FIL_, 0xC3,
+		0xB6, FIL_, 0xCC, 0x83, FIL_, 0xC3, 0xB5, FIL_,
+		0xCC, 0x81, FIL_, 0xC3, 0xB3, FIL_, 0xCC, 0x8C,
+		FIL_, 0xC7, 0x92, FIL_, 0xCC, 0xA8, FIL_, 0xC7,
+		0xAB, FIL_, 0xCC, 0x9B, FIL_, 0xC6, 0xA1, FIL_,
+		0xCC, 0x84, FIL_, 0xC5, 0x8D, FIL_, 0xCC, 0x86,
+		FIL_, 0xC5, 0x8F, FIL_, 0xCC, 0x8B, FIL_, 0xC5,
+		0x91, FIL_, 0xCC, 0x82, FIL_, 0xC3, 0xB4, FIL_,
+		0xCC, 0x8F, FIL_, 0xC8, 0x8D, FIL_, 0x02, 0xCC,
+		0x87, FIL_, 0xE1, 0xB9, 0x97, FIL_, 0xCC, 0x81,
+		FIL_, 0xE1, 0xB9, 0x95, FIL_, 0x08, 0xCC, 0x8C,
+		FIL_, 0xC5, 0x99, FIL_, 0xCC, 0xA3, FIL_, 0xE1,
+		0xB9, 0x9B, FIL_, 0xCC, 0x81, FIL_, 0xC5, 0x95,
+		FIL_, 0xCC, 0xA7, FIL_, 0xC5, 0x97, FIL_, 0xCC,
+		0xB1, FIL_, 0xE1, 0xB9, 0x9F, FIL_, 0xCC, 0x87,
+		FIL_, 0xE1, 0xB9, 0x99, FIL_, 0xCC, 0x91, FIL_,
+		0xC8, 0x93, FIL_, 0xCC, 0x8F, FIL_, 0xC8, 0x91,
+		FIL_, 0x07, 0xCC, 0xA7, FIL_, 0xC5, 0x9F, FIL_,
+		0xCC, 0x82, FIL_, 0xC5, 0x9D, FIL_, 0xCC, 0x87,
+		FIL_, 0xE1, 0xB9, 0xA1, FIL_, 0xCC, 0xA6, FIL_,
+		0xC8, 0x99, FIL_, 0xCC, 0x81, FIL_, 0xC5, 0x9B,
+		FIL_, 0xCC, 0xA3, FIL_, 0xE1, 0xB9, 0xA3, FIL_,
+		0xCC, 0x8C, FIL_, 0xC5, 0xA1, FIL_, 0x08, 0xCC,
+		0xA6, FIL_, 0xC8, 0x9B, FIL_, 0xCC, 0xAD, FIL_,
+		0xE1, 0xB9, 0xB1, FIL_, 0xCC, 0xB1, FIL_, 0xE1,
+		0xB9, 0xAF, FIL_, 0xCC, 0xA3, FIL_, 0xE1, 0xB9,
+		0xAD, FIL_, 0xCC, 0x87, FIL_, 0xE1, 0xB9, 0xAB,
+		FIL_, 0xCC, 0x8C, FIL_, 0xC5, 0xA5, FIL_, 0xCC,
+		0xA7, FIL_, 0xC5, 0xA3, FIL_, 0xCC, 0x88, FIL_,
+		0xE1, 0xBA, 0x97, FIL_, 0x13, 0xCC, 0x8A, FIL_,
+		0xC5, 0xAF, FIL_, 0xCC, 0x8F, FIL_, 0xC8, 0x95,
+		FIL_, 0xCC, 0x8C, FIL_, 0xC7, 0x94, FIL_, 0xCC,
+		0x80, FIL_, 0xC3, 0xB9, FIL_, 0xCC, 0x9B, FIL_,
+		0xC6, 0xB0, FIL_, 0xCC, 0x82, FIL_, 0xC3, 0xBB,
+		FIL_, 0xCC, 0x81, FIL_, 0xC3, 0xBA, FIL_, 0xCC,
+		0x88, FIL_, 0xC3, 0xBC, FIL_, 0xCC, 0x83, FIL_,
+		0xC5, 0xA9, FIL_, 0xCC, 0x89, FIL_, 0xE1, 0xBB,
+		0xA7, FIL_, 0xCC, 0x84, FIL_, 0xC5, 0xAB, FIL_,
+		0xCC, 0x86, FIL_, 0xC5, 0xAD, FIL_, 0xCC, 0xAD,
+		FIL_, 0xE1, 0xB9, 0xB7, FIL_, 0xCC, 0x8B, FIL_,
+		0xC5, 0xB1, FIL_, 0xCC, 0xA8, FIL_, 0xC5, 0xB3,
+		FIL_, 0xCC, 0x91, FIL_, 0xC8, 0x97, FIL_, 0xCC,
+		0xA4, FIL_, 0xE1, 0xB9, 0xB3, FIL_, 0xCC, 0xA3,
+		FIL_, 0xE1, 0xBB, 0xA5, FIL_, 0xCC, 0xB0, FIL_,
+		0xE1, 0xB9, 0xB5, FIL_, 0x02, 0xCC, 0x83, FIL_,
+		0xE1, 0xB9, 0xBD, FIL_, 0xCC, 0xA3, FIL_, 0xE1,
+		0xB9, 0xBF, FIL_, 0x07, 0xCC, 0x8A, FIL_, 0xE1,
+		0xBA, 0x98, FIL_, 0xCC, 0x87, FIL_, 0xE1, 0xBA,
+		0x87, FIL_, 0xCC, 0x81, FIL_, 0xE1, 0xBA, 0x83,
+		FIL_, 0xCC, 0x82, FIL_, 0xC5, 0xB5, FIL_, 0xCC,
+		0x80, FIL_, 0xE1, 0xBA, 0x81, FIL_, 0xCC, 0xA3,
+		FIL_, 0xE1, 0xBA, 0x89, FIL_, 0xCC, 0x88, FIL_,
+		0xE1, 0xBA, 0x85, FIL_, 0x02, 0xCC, 0x87, FIL_,
+		0xE1, 0xBA, 0x8B, FIL_, 0xCC, 0x88, FIL_, 0xE1,
+		0xBA, 0x8D, FIL_, 0x0A, 0xCC, 0x87, FIL_, 0xE1,
+		0xBA, 0x8F, FIL_, 0xCC, 0xA3, FIL_, 0xE1, 0xBB,
+		0xB5, FIL_, 0xCC, 0x89, FIL_, 0xE1, 0xBB, 0xB7,
+		FIL_, 0xCC, 0x8A, FIL_, 0xE1, 0xBA, 0x99, FIL_,
+		0xCC, 0x80, FIL_, 0xE1, 0xBB, 0xB3, FIL_, 0xCC,
+		0x83, FIL_, 0xE1, 0xBB, 0xB9, FIL_, 0xCC, 0x88,
+		FIL_, 0xC3, 0xBF, FIL_, 0xCC, 0x81, FIL_, 0xC3,
+		0xBD, FIL_, 0xCC, 0x84, FIL_, 0xC8, 0xB3, FIL_,
+		0xCC, 0x82, FIL_, 0xC5, 0xB7, FIL_, 0x06, 0xCC,
+		0xB1, FIL_, 0xE1, 0xBA, 0x95, FIL_, 0xCC, 0xA3,
+		FIL_, 0xE1, 0xBA, 0x93, FIL_, 0xCC, 0x82, FIL_,
+		0xE1, 0xBA, 0x91, FIL_, 0xCC, 0x81, FIL_, 0xC5,
+		0xBA, FIL_, 0xCC, 0x87, FIL_, 0xC5, 0xBC, FIL_,
+		0xCC, 0x8C, FIL_, 0xC5, 0xBE, FIL_, 0x03, 0xCC,
+		0x80, FIL_, 0xE1, 0xBF, 0xAD, FIL_, 0xCD, 0x82,
+		FIL_, 0xE1, 0xBF, 0x81, FIL_, 0xCC, 0x81, FIL_,
+		0xCE, 0x85, FIL_, 0x04, 0xCC, 0x83, FIL_, 0xE1,
+		0xBA, 0xAA, FIL_, 0xCC, 0x81, FIL_, 0xE1, 0xBA,
+		0xA4, FIL_, 0xCC, 0x89, FIL_, 0xE1, 0xBA, 0xA8,
+		FIL_, 0xCC, 0x80, FIL_, 0xE1, 0xBA, 0xA6, FIL_,
+		0x01, 0xCC, 0x84, FIL_, 0xC7, 0x9E, FIL_, 0x01,
+		0xCC, 0x81, FIL_, 0xC7, 0xBA, FIL_, 0x02, 0xCC,
+		0x84, FIL_, 0xC7, 0xA2, FIL_, 0xCC, 0x81, FIL_,
+		0xC7, 0xBC, FIL_, 0x01, 0xCC, 0x81, FIL_, 0xE1,
+		0xB8, 0x88, FIL_, 0x04, 0xCC, 0x83, FIL_, 0xE1,
+		0xBB, 0x84, FIL_, 0xCC, 0x80, FIL_, 0xE1, 0xBB,
+		0x80, FIL_, 0xCC, 0x89, FIL_, 0xE1, 0xBB, 0x82,
+		FIL_, 0xCC, 0x81, FIL_, 0xE1, 0xBA, 0xBE, FIL_,
+		0x01, 0xCC, 0x81, FIL_, 0xE1, 0xB8, 0xAE, FIL_,
+		0x04, 0xCC, 0x81, FIL_, 0xE1, 0xBB, 0x90, FIL_,
+		0xCC, 0x80, FIL_, 0xE1, 0xBB, 0x92, FIL_, 0xCC,
+		0x89, FIL_, 0xE1, 0xBB, 0x94, FIL_, 0xCC, 0x83,
+		FIL_, 0xE1, 0xBB, 0x96, FIL_, 0x03, 0xCC, 0x84,
+		FIL_, 0xC8, 0xAC, FIL_, 0xCC, 0x88, FIL_, 0xE1,
+		0xB9, 0x8E, FIL_, 0xCC, 0x81, FIL_, 0xE1, 0xB9,
+		0x8C, FIL_, 0x01, 0xCC, 0x84, FIL_, 0xC8, 0xAA,
+		FIL_, 0x01, 0xCC, 0x81, FIL_, 0xC7, 0xBE, FIL_,
+		0x04, 0xCC, 0x80, FIL_, 0xC7, 0x9B, FIL_, 0xCC,
+		0x84, FIL_, 0xC7, 0x95, FIL_, 0xCC, 0x8C, FIL_,
+		0xC7, 0x99, FIL_, 0xCC, 0x81, FIL_, 0xC7, 0x97,
+		FIL_, 0x04, 0xCC, 0x81, FIL_, 0xE1, 0xBA, 0xA5,
+		FIL_, 0xCC, 0x83, FIL_, 0xE1, 0xBA, 0xAB, FIL_,
+		0xCC, 0x89, FIL_, 0xE1, 0xBA, 0xA9, FIL_, 0xCC,
+		0x80, FIL_, 0xE1, 0xBA, 0xA7, FIL_, 0x01, 0xCC,
+		0x84, FIL_, 0xC7, 0x9F, FIL_, 0x01, 0xCC, 0x81,
+		FIL_, 0xC7, 0xBB, FIL_, 0x02, 0xCC, 0x81, FIL_,
+		0xC7, 0xBD, FIL_, 0xCC, 0x84, FIL_, 0xC7, 0xA3,
+		FIL_, 0x01, 0xCC, 0x81, FIL_, 0xE1, 0xB8, 0x89,
+		FIL_, 0x04, 0xCC, 0x89, FIL_, 0xE1, 0xBB, 0x83,
+		FIL_, 0xCC, 0x83, FIL_, 0xE1, 0xBB, 0x85, FIL_,
+		0xCC, 0x80, FIL_, 0xE1, 0xBB, 0x81, FIL_, 0xCC,
+		0x81, FIL_, 0xE1, 0xBA, 0xBF, FIL_, 0x01, 0xCC,
+		0x81, FIL_, 0xE1, 0xB8, 0xAF, FIL_, 0x04, 0xCC,
+		0x80, FIL_, 0xE1, 0xBB, 0x93, FIL_, 0xCC, 0x81,
+		FIL_, 0xE1, 0xBB, 0x91, FIL_, 0xCC, 0x83, FIL_,
+		0xE1, 0xBB, 0x97, FIL_, 0xCC, 0x89, FIL_, 0xE1,
+		0xBB, 0x95, FIL_, 0x03, 0xCC, 0x81, FIL_, 0xE1,
+		0xB9, 0x8D, FIL_, 0xCC, 0x88, FIL_, 0xE1, 0xB9,
+		0x8F, FIL_, 0xCC, 0x84, FIL_, 0xC8, 0xAD, FIL_,
+		0x01, 0xCC, 0x84, FIL_, 0xC8, 0xAB, FIL_, 0x01,
+		0xCC, 0x81, FIL_, 0xC7, 0xBF, FIL_, 0x04, 0xCC,
+		0x8C, FIL_, 0xC7, 0x9A, FIL_, 0xCC, 0x84, FIL_,
+		0xC7, 0x96, FIL_, 0xCC, 0x80, FIL_, 0xC7, 0x9C,
+		FIL_, 0xCC, 0x81, FIL_, 0xC7, 0x98, FIL_, 0x04,
+		0xCC, 0x81, FIL_, 0xE1, 0xBA, 0xAE, FIL_, 0xCC,
+		0x83, FIL_, 0xE1, 0xBA, 0xB4, FIL_, 0xCC, 0x89,
+		FIL_, 0xE1, 0xBA, 0xB2, FIL_, 0xCC, 0x80, FIL_,
+		0xE1, 0xBA, 0xB0, FIL_, 0x04, 0xCC, 0x83, FIL_,
+		0xE1, 0xBA, 0xB5, FIL_, 0xCC, 0x80, FIL_, 0xE1,
+		0xBA, 0xB1, FIL_, 0xCC, 0x81, FIL_, 0xE1, 0xBA,
+		0xAF, FIL_, 0xCC, 0x89, FIL_, 0xE1, 0xBA, 0xB3,
+		FIL_, 0x02, 0xCC, 0x81, FIL_, 0xE1, 0xB8, 0x96,
+		FIL_, 0xCC, 0x80, FIL_, 0xE1, 0xB8, 0x94, FIL_,
+		0x02, 0xCC, 0x80, FIL_, 0xE1, 0xB8, 0x95, FIL_,
+		0xCC, 0x81, FIL_, 0xE1, 0xB8, 0x97, FIL_, 0x02,
+		0xCC, 0x80, FIL_, 0xE1, 0xB9, 0x90, FIL_, 0xCC,
+		0x81, FIL_, 0xE1, 0xB9, 0x92, FIL_, 0x02, 0xCC,
+		0x81, FIL_, 0xE1, 0xB9, 0x93, FIL_, 0xCC, 0x80,
+		FIL_, 0xE1, 0xB9, 0x91, FIL_, 0x01, 0xCC, 0x87,
+		FIL_, 0xE1, 0xB9, 0xA4, FIL_, 0x01, 0xCC, 0x87,
+		FIL_, 0xE1, 0xB9, 0xA5, FIL_, 0x01, 0xCC, 0x87,
+		FIL_, 0xE1, 0xB9, 0xA6, FIL_, 0x01, 0xCC, 0x87,
+		FIL_, 0xE1, 0xB9, 0xA7, FIL_, 0x01, 0xCC, 0x81,
+		FIL_, 0xE1, 0xB9, 0xB8, FIL_, 0x01, 0xCC, 0x81,
+		FIL_, 0xE1, 0xB9, 0xB9, FIL_, 0x01, 0xCC, 0x88,
+		FIL_, 0xE1, 0xB9, 0xBA, FIL_, 0x01, 0xCC, 0x88,
+		FIL_, 0xE1, 0xB9, 0xBB, FIL_, 0x01, 0xCC, 0x87,
+		FIL_, 0xE1, 0xBA, 0x9B, FIL_, 0x05, 0xCC, 0x80,
+		FIL_, 0xE1, 0xBB, 0x9C, FIL_, 0xCC, 0x89, FIL_,
+		0xE1, 0xBB, 0x9E, FIL_, 0xCC, 0x83, FIL_, 0xE1,
+		0xBB, 0xA0, FIL_, 0xCC, 0x81, FIL_, 0xE1, 0xBB,
+		0x9A, FIL_, 0xCC, 0xA3, FIL_, 0xE1, 0xBB, 0xA2,
+		FIL_, 0x05, 0xCC, 0x83, FIL_, 0xE1, 0xBB, 0xA1,
+		FIL_, 0xCC, 0xA3, FIL_, 0xE1, 0xBB, 0xA3, FIL_,
+		0xCC, 0x81, FIL_, 0xE1, 0xBB, 0x9B, FIL_, 0xCC,
+		0x80, FIL_, 0xE1, 0xBB, 0x9D, FIL_, 0xCC, 0x89,
+		FIL_, 0xE1, 0xBB, 0x9F, FIL_, 0x05, 0xCC, 0x81,
+		FIL_, 0xE1, 0xBB, 0xA8, FIL_, 0xCC, 0x80, FIL_,
+		0xE1, 0xBB, 0xAA, FIL_, 0xCC, 0x89, FIL_, 0xE1,
+		0xBB, 0xAC, FIL_, 0xCC, 0x83, FIL_, 0xE1, 0xBB,
+		0xAE, FIL_, 0xCC, 0xA3, FIL_, 0xE1, 0xBB, 0xB0,
+		FIL_, 0x05, 0xCC, 0x80, FIL_, 0xE1, 0xBB, 0xAB,
+		FIL_, 0xCC, 0x81, FIL_, 0xE1, 0xBB, 0xA9, FIL_,
+		0xCC, 0x83, FIL_, 0xE1, 0xBB, 0xAF, FIL_, 0xCC,
+		0xA3, FIL_, 0xE1, 0xBB, 0xB1, FIL_, 0xCC, 0x89,
+		FIL_, 0xE1, 0xBB, 0xAD, FIL_, 0x01, 0xCC, 0x8C,
+		FIL_, 0xC7, 0xAE, FIL_, 0x01, 0xCC, 0x84, FIL_,
+		0xC7, 0xAC, FIL_, 0x01, 0xCC, 0x84, FIL_, 0xC7,
+		0xAD, FIL_, 0x01, 0xCC, 0x84, FIL_, 0xC7, 0xA0,
+		FIL_, 0x01, 0xCC, 0x84, FIL_, 0xC7, 0xA1, FIL_,
+		0x01, 0xCC, 0x86, FIL_, 0xE1, 0xB8, 0x9C, FIL_,
+		0x01, 0xCC, 0x86, FIL_, 0xE1, 0xB8, 0x9D, FIL_,
+		0x01, 0xCC, 0x84, FIL_, 0xC8, 0xB0, FIL_, 0x01,
+		0xCC, 0x84, FIL_, 0xC8, 0xB1, FIL_, 0x01, 0xCC,
+		0x8C, FIL_, 0xC7, 0xAF, FIL_, 0x07, 0xCC, 0x93,
+		FIL_, 0xE1, 0xBC, 0x88, FIL_, 0xCC, 0x81, FIL_,
+		0xCE, 0x86, FIL_, 0xCC, 0x86, FIL_, 0xE1, 0xBE,
+		0xB8, FIL_, 0xCC, 0x84, FIL_, 0xE1, 0xBE, 0xB9,
+		FIL_, 0xCC, 0x94, FIL_, 0xE1, 0xBC, 0x89, FIL_,
+		0xCD, 0x85, FIL_, 0xE1, 0xBE, 0xBC, FIL_, 0xCC,
+		0x80, FIL_, 0xE1, 0xBE, 0xBA, FIL_, 0x04, 0xCC,
+		0x94, FIL_, 0xE1, 0xBC, 0x99, FIL_, 0xCC, 0x80,
+		FIL_, 0xE1, 0xBF, 0x88, FIL_, 0xCC, 0x81, FIL_,
+		0xCE, 0x88, FIL_, 0xCC, 0x93, FIL_, 0xE1, 0xBC,
+		0x98, FIL_, 0x05, 0xCD, 0x85, FIL_, 0xE1, 0xBF,
+		0x8C, FIL_, 0xCC, 0x81, FIL_, 0xCE, 0x89, FIL_,
+		0xCC, 0x80, FIL_, 0xE1, 0xBF, 0x8A, FIL_, 0xCC,
+		0x93, FIL_, 0xE1, 0xBC, 0xA8, FIL_, 0xCC, 0x94,
+		FIL_, 0xE1, 0xBC, 0xA9, FIL_, 0x07, 0xCC, 0x80,
+		FIL_, 0xE1, 0xBF, 0x9A, FIL_, 0xCC, 0x84, FIL_,
+		0xE1, 0xBF, 0x99, FIL_, 0xCC, 0x93, FIL_, 0xE1,
+		0xBC, 0xB8, FIL_, 0xCC, 0x94, FIL_, 0xE1, 0xBC,
+		0xB9, FIL_, 0xCC, 0x86, FIL_, 0xE1, 0xBF, 0x98,
+		FIL_, 0xCC, 0x81, FIL_, 0xCE, 0x8A, FIL_, 0xCC,
+		0x88, FIL_, 0xCE, 0xAA, FIL_, 0x04, 0xCC, 0x81,
+		FIL_, 0xCE, 0x8C, FIL_, 0xCC, 0x94, FIL_, 0xE1,
+		0xBD, 0x89, FIL_, 0xCC, 0x93, FIL_, 0xE1, 0xBD,
+		0x88, FIL_, 0xCC, 0x80, FIL_, 0xE1, 0xBF, 0xB8,
+		FIL_, 0x01, 0xCC, 0x94, FIL_, 0xE1, 0xBF, 0xAC,
+		FIL_, 0x06, 0xCC, 0x94, FIL_, 0xE1, 0xBD, 0x99,
+		FIL_, 0xCC, 0x86, FIL_, 0xE1, 0xBF, 0xA8, FIL_,
+		0xCC, 0x88, FIL_, 0xCE, 0xAB, FIL_, 0xCC, 0x84,
+		FIL_, 0xE1, 0xBF, 0xA9, FIL_, 0xCC, 0x81, FIL_,
+		0xCE, 0x8E, FIL_, 0xCC, 0x80, FIL_, 0xE1, 0xBF,
+		0xAA, FIL_, 0x05, 0xCC, 0x93, FIL_, 0xE1, 0xBD,
+		0xA8, FIL_, 0xCD, 0x85, FIL_, 0xE1, 0xBF, 0xBC,
+		FIL_, 0xCC, 0x80, FIL_, 0xE1, 0xBF, 0xBA, FIL_,
+		0xCC, 0x94, FIL_, 0xE1, 0xBD, 0xA9, FIL_, 0xCC,
+		0x81, FIL_, 0xCE, 0x8F, FIL_, 0x01, 0xCD, 0x85,
+		FIL_, 0xE1, 0xBE, 0xB4, FIL_, 0x01, 0xCD, 0x85,
+		FIL_, 0xE1, 0xBF, 0x84, FIL_, 0x08, 0xCD, 0x85,
+		FIL_, 0xE1, 0xBE, 0xB3, FIL_, 0xCC, 0x84, FIL_,
+		0xE1, 0xBE, 0xB1, FIL_, 0xCC, 0x86, FIL_, 0xE1,
+		0xBE, 0xB0, FIL_, 0xCC, 0x80, FIL_, 0xE1, 0xBD,
+		0xB0, FIL_, 0xCC, 0x81, FIL_, 0xCE, 0xAC, FIL_,
+		0xCC, 0x94, FIL_, 0xE1, 0xBC, 0x81, FIL_, 0xCC,
+		0x93, FIL_, 0xE1, 0xBC, 0x80, FIL_, 0xCD, 0x82,
+		FIL_, 0xE1, 0xBE, 0xB6, FIL_, 0x04, 0xCC, 0x93,
+		FIL_, 0xE1, 0xBC, 0x90, FIL_, 0xCC, 0x80, FIL_,
+		0xE1, 0xBD, 0xB2, FIL_, 0xCC, 0x94, FIL_, 0xE1,
+		0xBC, 0x91, FIL_, 0xCC, 0x81, FIL_, 0xCE, 0xAD,
+		FIL_, 0x06, 0xCC, 0x94, FIL_, 0xE1, 0xBC, 0xA1,
+		FIL_, 0xCC, 0x81, FIL_, 0xCE, 0xAE, FIL_, 0xCD,
+		0x85, FIL_, 0xE1, 0xBF, 0x83, FIL_, 0xCD, 0x82,
+		FIL_, 0xE1, 0xBF, 0x86, FIL_, 0xCC, 0x93, FIL_,
+		0xE1, 0xBC, 0xA0, FIL_, 0xCC, 0x80, FIL_, 0xE1,
+		0xBD, 0xB4, FIL_, 0x08, 0xCC, 0x88, FIL_, 0xCF,
+		0x8A, FIL_, 0xCC, 0x81, FIL_, 0xCE, 0xAF, FIL_,
+		0xCC, 0x93, FIL_, 0xE1, 0xBC, 0xB0, FIL_, 0xCC,
+		0x94, FIL_, 0xE1, 0xBC, 0xB1, FIL_, 0xCC, 0x80,
+		FIL_, 0xE1, 0xBD, 0xB6, FIL_, 0xCC, 0x86, FIL_,
+		0xE1, 0xBF, 0x90, FIL_, 0xCC, 0x84, FIL_, 0xE1,
+		0xBF, 0x91, FIL_, 0xCD, 0x82, FIL_, 0xE1, 0xBF,
+		0x96, FIL_, 0x04, 0xCC, 0x93, FIL_, 0xE1, 0xBD,
+		0x80, FIL_, 0xCC, 0x80, FIL_, 0xE1, 0xBD, 0xB8,
+		FIL_, 0xCC, 0x94, FIL_, 0xE1, 0xBD, 0x81, FIL_,
+		0xCC, 0x81, FIL_, 0xCF, 0x8C, FIL_, 0x02, 0xCC,
+		0x93, FIL_, 0xE1, 0xBF, 0xA4, FIL_, 0xCC, 0x94,
+		FIL_, 0xE1, 0xBF, 0xA5, FIL_, 0x08, 0xCC, 0x81,
+		FIL_, 0xCF, 0x8D, FIL_, 0xCC, 0x94, FIL_, 0xE1,
+		0xBD, 0x91, FIL_, 0xCD, 0x82, FIL_, 0xE1, 0xBF,
+		0xA6, FIL_, 0xCC, 0x88, FIL_, 0xCF, 0x8B, FIL_,
+		0xCC, 0x84, FIL_, 0xE1, 0xBF, 0xA1, FIL_, 0xCC,
+		0x80, FIL_, 0xE1, 0xBD, 0xBA, FIL_, 0xCC, 0x93,
+		FIL_, 0xE1, 0xBD, 0x90, FIL_, 0xCC, 0x86, FIL_,
+		0xE1, 0xBF, 0xA0, FIL_, 0x06, 0xCC, 0x80, FIL_,
+		0xE1, 0xBD, 0xBC, FIL_, 0xCC, 0x94, FIL_, 0xE1,
+		0xBD, 0xA1, FIL_, 0xCC, 0x93, FIL_, 0xE1, 0xBD,
+		0xA0, FIL_, 0xCC, 0x81, FIL_, 0xCF, 0x8E, FIL_,
+		0xCD, 0x85, FIL_, 0xE1, 0xBF, 0xB3, FIL_, 0xCD,
+		0x82, FIL_, 0xE1, 0xBF, 0xB6, FIL_, 0x03, 0xCC,
+		0x80, FIL_, 0xE1, 0xBF, 0x92, FIL_, 0xCD, 0x82,
+		FIL_, 0xE1, 0xBF, 0x97, FIL_, 0xCC, 0x81, FIL_,
+		0xCE, 0x90, FIL_, 0x03, 0xCD, 0x82, FIL_, 0xE1,
+		0xBF, 0xA7, FIL_, 0xCC, 0x80, FIL_, 0xE1, 0xBF,
+		0xA2, FIL_, 0xCC, 0x81, FIL_, 0xCE, 0xB0, FIL_,
+		0x01, 0xCD, 0x85, FIL_, 0xE1, 0xBF, 0xB4, FIL_,
+		0x02, 0xCC, 0x88, FIL_, 0xCF, 0x94, FIL_, 0xCC,
+		0x81, FIL_, 0xCF, 0x93, FIL_, 0x01, 0xCC, 0x88,
+		FIL_, 0xD0, 0x87, FIL_, 0x02, 0xCC, 0x88, FIL_,
+		0xD3, 0x92, FIL_, 0xCC, 0x86, FIL_, 0xD3, 0x90,
+		FIL_, 0x01, 0xCC, 0x81, FIL_, 0xD0, 0x83, FIL_,
+		0x03, 0xCC, 0x88, FIL_, 0xD0, 0x81, FIL_, 0xCC,
+		0x80, FIL_, 0xD0, 0x80, FIL_, 0xCC, 0x86, FIL_,
+		0xD3, 0x96, FIL_, 0x02, 0xCC, 0x86, FIL_, 0xD3,
+		0x81, FIL_, 0xCC, 0x88, FIL_, 0xD3, 0x9C, FIL_,
+		0x01, 0xCC, 0x88, FIL_, 0xD3, 0x9E, FIL_, 0x04,
+		0xCC, 0x84, FIL_, 0xD3, 0xA2, FIL_, 0xCC, 0x88,
+		FIL_, 0xD3, 0xA4, FIL_, 0xCC, 0x86, FIL_, 0xD0,
+		0x99, FIL_, 0xCC, 0x80, FIL_, 0xD0, 0x8D, FIL_,
+		0x01, 0xCC, 0x81, FIL_, 0xD0, 0x8C, FIL_, 0x01,
+		0xCC, 0x88, FIL_, 0xD3, 0xA6, FIL_, 0x04, 0xCC,
+		0x8B, FIL_, 0xD3, 0xB2, FIL_, 0xCC, 0x88, FIL_,
+		0xD3, 0xB0, FIL_, 0xCC, 0x86, FIL_, 0xD0, 0x8E,
+		FIL_, 0xCC, 0x84, FIL_, 0xD3, 0xAE, FIL_, 0x01,
+		0xCC, 0x88, FIL_, 0xD3, 0xB4, FIL_, 0x01, 0xCC,
+		0x88, FIL_, 0xD3, 0xB8, FIL_, 0x01, 0xCC, 0x88,
+		FIL_, 0xD3, 0xAC, FIL_, 0x02, 0xCC, 0x86, FIL_,
+		0xD3, 0x91, FIL_, 0xCC, 0x88, FIL_, 0xD3, 0x93,
+		FIL_, 0x01, 0xCC, 0x81, FIL_, 0xD1, 0x93, FIL_,
+		0x03, 0xCC, 0x80, FIL_, 0xD1, 0x90, FIL_, 0xCC,
+		0x86, FIL_, 0xD3, 0x97, FIL_, 0xCC, 0x88, FIL_,
+		0xD1, 0x91, FIL_, 0x02, 0xCC, 0x86, FIL_, 0xD3,
+		0x82, FIL_, 0xCC, 0x88, FIL_, 0xD3, 0x9D, FIL_,
+		0x01, 0xCC, 0x88, FIL_, 0xD3, 0x9F, FIL_, 0x04,
+		0xCC, 0x86, FIL_, 0xD0, 0xB9, FIL_, 0xCC, 0x88,
+		FIL_, 0xD3, 0xA5, FIL_, 0xCC, 0x84, FIL_, 0xD3,
+		0xA3, FIL_, 0xCC, 0x80, FIL_, 0xD1, 0x9D, FIL_,
+		0x01, 0xCC, 0x81, FIL_, 0xD1, 0x9C, FIL_, 0x01,
+		0xCC, 0x88, FIL_, 0xD3, 0xA7, FIL_, 0x04, 0xCC,
+		0x8B, FIL_, 0xD3, 0xB3, FIL_, 0xCC, 0x84, FIL_,
+		0xD3, 0xAF, FIL_, 0xCC, 0x86, FIL_, 0xD1, 0x9E,
+		FIL_, 0xCC, 0x88, FIL_, 0xD3, 0xB1, FIL_, 0x01,
+		0xCC, 0x88, FIL_, 0xD3, 0xB5, FIL_, 0x01, 0xCC,
+		0x88, FIL_, 0xD3, 0xB9, FIL_, 0x01, 0xCC, 0x88,
+		FIL_, 0xD3, 0xAD, FIL_, 0x01, 0xCC, 0x88, FIL_,
+		0xD1, 0x97, FIL_, 0x01, 0xCC, 0x8F, FIL_, 0xD1,
+		0xB6, FIL_, 0x01, 0xCC, 0x8F, FIL_, 0xD1, 0xB7,
+		FIL_, 0x01, 0xCC, 0x88, FIL_, 0xD3, 0x9A, FIL_,
+		0x01, 0xCC, 0x88, FIL_, 0xD3, 0x9B, FIL_, 0x01,
+		0xCC, 0x88, FIL_, 0xD3, 0xAA, FIL_, 0x01, 0xCC,
+		0x88, FIL_, 0xD3, 0xAB, FIL_, 0x03, 0xD9, 0x94,
+		FIL_, 0xD8, 0xA3, FIL_, 0xD9, 0x95, FIL_, 0xD8,
+		0xA5, FIL_, 0xD9, 0x93, FIL_, 0xD8, 0xA2, FIL_,
+		0x01, 0xD9, 0x94, FIL_, 0xD8, 0xA4, FIL_, 0x01,
+		0xD9, 0x94, FIL_, 0xD8, 0xA6, FIL_, 0x01, 0xD9,
+		0x94, FIL_, 0xDB, 0x82, FIL_, 0x01, 0xD9, 0x94,
+		FIL_, 0xDB, 0x93, FIL_, 0x01, 0xD9, 0x94, FIL_,
+		0xDB, 0x80, FIL_, 0x01, 0xE0, 0xA4, 0xBC, FIL_,
+		0xE0, 0xA4, 0xA9, FIL_, 0x01, 0xE0, 0xA4, 0xBC,
+		FIL_, 0xE0, 0xA4, 0xB1, FIL_, 0x01, 0xE0, 0xA4,
+		0xBC, FIL_, 0xE0, 0xA4, 0xB4, FIL_, 0x02, 0xE0,
+		0xA6, 0xBE, FIL_, 0xE0, 0xA7, 0x8B, FIL_, 0xE0,
+		0xA7, 0x97, FIL_, 0xE0, 0xA7, 0x8C, FIL_, 0x03,
+		0xE0, 0xAD, 0x96, FIL_, 0xE0, 0xAD, 0x88, FIL_,
+		0xE0, 0xAC, 0xBE, FIL_, 0xE0, 0xAD, 0x8B, FIL_,
+		0xE0, 0xAD, 0x97, FIL_, 0xE0, 0xAD, 0x8C, FIL_,
+		0x01, 0xE0, 0xAF, 0x97, FIL_, 0xE0, 0xAE, 0x94,
+		FIL_, 0x02, 0xE0, 0xAF, 0x97, FIL_, 0xE0, 0xAF,
+		0x8C, FIL_, 0xE0, 0xAE, 0xBE, FIL_, 0xE0, 0xAF,
+		0x8A, FIL_, 0x01, 0xE0, 0xAE, 0xBE, FIL_, 0xE0,
+		0xAF, 0x8B, FIL_, 0x01, 0xE0, 0xB1, 0x96, FIL_,
+		0xE0, 0xB1, 0x88, FIL_, 0x01, 0xE0, 0xB3, 0x95,
+		FIL_, 0xE0, 0xB3, 0x80, FIL_, 0x03, 0xE0, 0xB3,
+		0x82, FIL_, 0xE0, 0xB3, 0x8A, FIL_, 0xE0, 0xB3,
+		0x96, FIL_, 0xE0, 0xB3, 0x88, FIL_, 0xE0, 0xB3,
+		0x95, FIL_, 0xE0, 0xB3, 0x87, FIL_, 0x01, 0xE0,
+		0xB3, 0x95, FIL_, 0xE0, 0xB3, 0x8B, FIL_, 0x02,
+		0xE0, 0xB4, 0xBE, FIL_, 0xE0, 0xB5, 0x8A, FIL_,
+		0xE0, 0xB5, 0x97, FIL_, 0xE0, 0xB5, 0x8C, FIL_,
+		0x01, 0xE0, 0xB4, 0xBE, FIL_, 0xE0, 0xB5, 0x8B,
+		FIL_, 0x03, 0xE0, 0xB7, 0x9F, FIL_, 0xE0, 0xB7,
+		0x9E, FIL_, 0xE0, 0xB7, 0x8A, FIL_, 0xE0, 0xB7,
+		0x9A, FIL_, 0xE0, 0xB7, 0x8F, FIL_, 0xE0, 0xB7,
+		0x9C, FIL_, 0x01, 0xE0, 0xB7, 0x8A, FIL_, 0xE0,
+		0xB7, 0x9D, FIL_, 0x01, 0xE1, 0x80, 0xAE, FIL_,
+		0xE1, 0x80, 0xA6, FIL_, 0x01, 0xE1, 0xAC, 0xB5,
+		FIL_, 0xE1, 0xAC, 0x86, FIL_, 0x01, 0xE1, 0xAC,
+		0xB5, FIL_, 0xE1, 0xAC, 0x88, FIL_, 0x01, 0xE1,
+		0xAC, 0xB5, FIL_, 0xE1, 0xAC, 0x8A, FIL_, 0x01,
+		0xE1, 0xAC, 0xB5, FIL_, 0xE1, 0xAC, 0x8C, FIL_,
+		0x01, 0xE1, 0xAC, 0xB5, FIL_, 0xE1, 0xAC, 0x8E,
+		FIL_, 0x01, 0xE1, 0xAC, 0xB5, FIL_, 0xE1, 0xAC,
+		0x92, FIL_, 0x01, 0xE1, 0xAC, 0xB5, FIL_, 0xE1,
+		0xAC, 0xBB, FIL_, 0x01, 0xE1, 0xAC, 0xB5, FIL_,
+		0xE1, 0xAC, 0xBD, FIL_, 0x01, 0xE1, 0xAC, 0xB5,
+		FIL_, 0xE1, 0xAD, 0x80, FIL_, 0x01, 0xE1, 0xAC,
+		0xB5, FIL_, 0xE1, 0xAD, 0x81, FIL_, 0x01, 0xE1,
+		0xAC, 0xB5, FIL_, 0xE1, 0xAD, 0x83, FIL_, 0x01,
+		0xCC, 0x84, FIL_, 0xE1, 0xB8, 0xB8, FIL_, 0x01,
+		0xCC, 0x84, FIL_, 0xE1, 0xB8, 0xB9, FIL_, 0x01,
+		0xCC, 0x84, FIL_, 0xE1, 0xB9, 0x9C, FIL_, 0x01,
+		0xCC, 0x84, FIL_, 0xE1, 0xB9, 0x9D, FIL_, 0x01,
+		0xCC, 0x87, FIL_, 0xE1, 0xB9, 0xA8, FIL_, 0x01,
+		0xCC, 0x87, FIL_, 0xE1, 0xB9, 0xA9, FIL_, 0x02,
+		0xCC, 0x86, FIL_, 0xE1, 0xBA, 0xB6, FIL_, 0xCC,
+		0x82, FIL_, 0xE1, 0xBA, 0xAC, FIL_, 0x02, 0xCC,
+		0x82, FIL_, 0xE1, 0xBA, 0xAD, FIL_, 0xCC, 0x86,
+		FIL_, 0xE1, 0xBA, 0xB7, FIL_, 0x01, 0xCC, 0x82,
+		FIL_, 0xE1, 0xBB, 0x86, FIL_, 0x01, 0xCC, 0x82,
+		FIL_, 0xE1, 0xBB, 0x87, FIL_, 0x01, 0xCC, 0x82,
+		FIL_, 0xE1, 0xBB, 0x98, FIL_, 0x01, 0xCC, 0x82,
+		FIL_, 0xE1, 0xBB, 0x99, FIL_, 0x04, 0xCD, 0x85,
+		FIL_, 0xE1, 0xBE, 0x80, FIL_, 0xCD, 0x82, FIL_,
+		0xE1, 0xBC, 0x86, FIL_, 0xCC, 0x80, FIL_, 0xE1,
+		0xBC, 0x82, FIL_, 0xCC, 0x81, FIL_, 0xE1, 0xBC,
+		0x84, FIL_, 0x04, 0xCD, 0x82, FIL_, 0xE1, 0xBC,
+		0x87, FIL_, 0xCC, 0x81, FIL_, 0xE1, 0xBC, 0x85,
+		FIL_, 0xCC, 0x80, FIL_, 0xE1, 0xBC, 0x83, FIL_,
+		0xCD, 0x85, FIL_, 0xE1, 0xBE, 0x81, FIL_, 0x01,
+		0xCD, 0x85, FIL_, 0xE1, 0xBE, 0x82, FIL_, 0x01,
+		0xCD, 0x85, FIL_, 0xE1, 0xBE, 0x83, FIL_, 0x01,
+		0xCD, 0x85, FIL_, 0xE1, 0xBE, 0x84, FIL_, 0x01,
+		0xCD, 0x85, FIL_, 0xE1, 0xBE, 0x85, FIL_, 0x01,
+		0xCD, 0x85, FIL_, 0xE1, 0xBE, 0x86, FIL_, 0x01,
+		0xCD, 0x85, FIL_, 0xE1, 0xBE, 0x87, FIL_, 0x04,
+		0xCC, 0x81, FIL_, 0xE1, 0xBC, 0x8C, FIL_, 0xCC,
+		0x80, FIL_, 0xE1, 0xBC, 0x8A, FIL_, 0xCD, 0x85,
+		FIL_, 0xE1, 0xBE, 0x88, FIL_, 0xCD, 0x82, FIL_,
+		0xE1, 0xBC, 0x8E, FIL_, 0x04, 0xCC, 0x80, FIL_,
+		0xE1, 0xBC, 0x8B, FIL_, 0xCD, 0x82, FIL_, 0xE1,
+		0xBC, 0x8F, FIL_, 0xCC, 0x81, FIL_, 0xE1, 0xBC,
+		0x8D, FIL_, 0xCD, 0x85, FIL_, 0xE1, 0xBE, 0x89,
+		FIL_, 0x01, 0xCD, 0x85, FIL_, 0xE1, 0xBE, 0x8A,
+		FIL_, 0x01, 0xCD, 0x85, FIL_, 0xE1, 0xBE, 0x8B,
+		FIL_, 0x01, 0xCD, 0x85, FIL_, 0xE1, 0xBE, 0x8C,
+		FIL_, 0x01, 0xCD, 0x85, FIL_, 0xE1, 0xBE, 0x8D,
+		FIL_, 0x01, 0xCD, 0x85, FIL_, 0xE1, 0xBE, 0x8E,
+		FIL_, 0x01, 0xCD, 0x85, FIL_, 0xE1, 0xBE, 0x8F,
+		FIL_, 0x02, 0xCC, 0x80, FIL_, 0xE1, 0xBC, 0x92,
+		FIL_, 0xCC, 0x81, FIL_, 0xE1, 0xBC, 0x94, FIL_,
+		0x02, 0xCC, 0x80, FIL_, 0xE1, 0xBC, 0x93, FIL_,
+		0xCC, 0x81, FIL_, 0xE1, 0xBC, 0x95, FIL_, 0x02,
+		0xCC, 0x80, FIL_, 0xE1, 0xBC, 0x9A, FIL_, 0xCC,
+		0x81, FIL_, 0xE1, 0xBC, 0x9C, FIL_, 0x02, 0xCC,
+		0x80, FIL_, 0xE1, 0xBC, 0x9B, FIL_, 0xCC, 0x81,
+		FIL_, 0xE1, 0xBC, 0x9D, FIL_, 0x04, 0xCC, 0x80,
+		FIL_, 0xE1, 0xBC, 0xA2, FIL_, 0xCC, 0x81, FIL_,
+		0xE1, 0xBC, 0xA4, FIL_, 0xCD, 0x82, FIL_, 0xE1,
+		0xBC, 0xA6, FIL_, 0xCD, 0x85, FIL_, 0xE1, 0xBE,
+		0x90, FIL_, 0x04, 0xCD, 0x85, FIL_, 0xE1, 0xBE,
+		0x91, FIL_, 0xCC, 0x81, FIL_, 0xE1, 0xBC, 0xA5,
+		FIL_, 0xCD, 0x82, FIL_, 0xE1, 0xBC, 0xA7, FIL_,
+		0xCC, 0x80, FIL_, 0xE1, 0xBC, 0xA3, FIL_, 0x01,
+		0xCD, 0x85, FIL_, 0xE1, 0xBE, 0x92, FIL_, 0x01,
+		0xCD, 0x85, FIL_, 0xE1, 0xBE, 0x93, FIL_, 0x01,
+		0xCD, 0x85, FIL_, 0xE1, 0xBE, 0x94, FIL_, 0x01,
+		0xCD, 0x85, FIL_, 0xE1, 0xBE, 0x95, FIL_, 0x01,
+		0xCD, 0x85, FIL_, 0xE1, 0xBE, 0x96, FIL_, 0x01,
+		0xCD, 0x85, FIL_, 0xE1, 0xBE, 0x97, FIL_, 0x04,
+		0xCC, 0x81, FIL_, 0xE1, 0xBC, 0xAC, FIL_, 0xCC,
+		0x80, FIL_, 0xE1, 0xBC, 0xAA, FIL_, 0xCD, 0x85,
+		FIL_, 0xE1, 0xBE, 0x98, FIL_, 0xCD, 0x82, FIL_,
+		0xE1, 0xBC, 0xAE, FIL_, 0x04, 0xCD, 0x82, FIL_,
+		0xE1, 0xBC, 0xAF, FIL_, 0xCD, 0x85, FIL_, 0xE1,
+		0xBE, 0x99, FIL_, 0xCC, 0x81, FIL_, 0xE1, 0xBC,
+		0xAD, FIL_, 0xCC, 0x80, FIL_, 0xE1, 0xBC, 0xAB,
+		FIL_, 0x01, 0xCD, 0x85, FIL_, 0xE1, 0xBE, 0x9A,
+		FIL_, 0x01, 0xCD, 0x85, FIL_, 0xE1, 0xBE, 0x9B,
+		FIL_, 0x01, 0xCD, 0x85, FIL_, 0xE1, 0xBE, 0x9C,
+		FIL_, 0x01, 0xCD, 0x85, FIL_, 0xE1, 0xBE, 0x9D,
+		FIL_, 0x01, 0xCD, 0x85, FIL_, 0xE1, 0xBE, 0x9E,
+		FIL_, 0x01, 0xCD, 0x85, FIL_, 0xE1, 0xBE, 0x9F,
+		FIL_, 0x03, 0xCC, 0x81, FIL_, 0xE1, 0xBC, 0xB4,
+		FIL_, 0xCC, 0x80, FIL_, 0xE1, 0xBC, 0xB2, FIL_,
+		0xCD, 0x82, FIL_, 0xE1, 0xBC, 0xB6, FIL_, 0x03,
+		0xCC, 0x80, FIL_, 0xE1, 0xBC, 0xB3, FIL_, 0xCD,
+		0x82, FIL_, 0xE1, 0xBC, 0xB7, FIL_, 0xCC, 0x81,
+		FIL_, 0xE1, 0xBC, 0xB5, FIL_, 0x03, 0xCC, 0x81,
+		FIL_, 0xE1, 0xBC, 0xBC, FIL_, 0xCC, 0x80, FIL_,
+		0xE1, 0xBC, 0xBA, FIL_, 0xCD, 0x82, FIL_, 0xE1,
+		0xBC, 0xBE, FIL_, 0x03, 0xCC, 0x80, FIL_, 0xE1,
+		0xBC, 0xBB, FIL_, 0xCD, 0x82, FIL_, 0xE1, 0xBC,
+		0xBF, FIL_, 0xCC, 0x81, FIL_, 0xE1, 0xBC, 0xBD,
+		FIL_, 0x02, 0xCC, 0x80, FIL_, 0xE1, 0xBD, 0x82,
+		FIL_, 0xCC, 0x81, FIL_, 0xE1, 0xBD, 0x84, FIL_,
+		0x02, 0xCC, 0x81, FIL_, 0xE1, 0xBD, 0x85, FIL_,
+		0xCC, 0x80, FIL_, 0xE1, 0xBD, 0x83, FIL_, 0x02,
+		0xCC, 0x80, FIL_, 0xE1, 0xBD, 0x8A, FIL_, 0xCC,
+		0x81, FIL_, 0xE1, 0xBD, 0x8C, FIL_, 0x02, 0xCC,
+		0x80, FIL_, 0xE1, 0xBD, 0x8B, FIL_, 0xCC, 0x81,
+		FIL_, 0xE1, 0xBD, 0x8D, FIL_, 0x03, 0xCD, 0x82,
+		FIL_, 0xE1, 0xBD, 0x96, FIL_, 0xCC, 0x80, FIL_,
+		0xE1, 0xBD, 0x92, FIL_, 0xCC, 0x81, FIL_, 0xE1,
+		0xBD, 0x94, FIL_, 0x03, 0xCC, 0x80, FIL_, 0xE1,
+		0xBD, 0x93, FIL_, 0xCD, 0x82, FIL_, 0xE1, 0xBD,
+		0x97, FIL_, 0xCC, 0x81, FIL_, 0xE1, 0xBD, 0x95,
+		FIL_, 0x03, 0xCC, 0x80, FIL_, 0xE1, 0xBD, 0x9B,
+		FIL_, 0xCD, 0x82, FIL_, 0xE1, 0xBD, 0x9F, FIL_,
+		0xCC, 0x81, FIL_, 0xE1, 0xBD, 0x9D, FIL_, 0x04,
+		0xCD, 0x82, FIL_, 0xE1, 0xBD, 0xA6, FIL_, 0xCD,
+		0x85, FIL_, 0xE1, 0xBE, 0xA0, FIL_, 0xCC, 0x80,
+		FIL_, 0xE1, 0xBD, 0xA2, FIL_, 0xCC, 0x81, FIL_,
+		0xE1, 0xBD, 0xA4, FIL_, 0x04, 0xCD, 0x85, FIL_,
+		0xE1, 0xBE, 0xA1, FIL_, 0xCD, 0x82, FIL_, 0xE1,
+		0xBD, 0xA7, FIL_, 0xCC, 0x81, FIL_, 0xE1, 0xBD,
+		0xA5, FIL_, 0xCC, 0x80, FIL_, 0xE1, 0xBD, 0xA3,
+		FIL_, 0x01, 0xCD, 0x85, FIL_, 0xE1, 0xBE, 0xA2,
+		FIL_, 0x01, 0xCD, 0x85, FIL_, 0xE1, 0xBE, 0xA3,
+		FIL_, 0x01, 0xCD, 0x85, FIL_, 0xE1, 0xBE, 0xA4,
+		FIL_, 0x01, 0xCD, 0x85, FIL_, 0xE1, 0xBE, 0xA5,
+		FIL_, 0x01, 0xCD, 0x85, FIL_, 0xE1, 0xBE, 0xA6,
+		FIL_, 0x01, 0xCD, 0x85, FIL_, 0xE1, 0xBE, 0xA7,
+		FIL_, 0x04, 0xCC, 0x80, FIL_, 0xE1, 0xBD, 0xAA,
+		FIL_, 0xCC, 0x81, FIL_, 0xE1, 0xBD, 0xAC, FIL_,
+		0xCD, 0x82, FIL_, 0xE1, 0xBD, 0xAE, FIL_, 0xCD,
+		0x85, FIL_, 0xE1, 0xBE, 0xA8, FIL_, 0x04, 0xCD,
+		0x82, FIL_, 0xE1, 0xBD, 0xAF, FIL_, 0xCC, 0x80,
+		FIL_, 0xE1, 0xBD, 0xAB, FIL_, 0xCD, 0x85, FIL_,
+		0xE1, 0xBE, 0xA9, FIL_, 0xCC, 0x81, FIL_, 0xE1,
+		0xBD, 0xAD, FIL_, 0x01, 0xCD, 0x85, FIL_, 0xE1,
+		0xBE, 0xAA, FIL_, 0x01, 0xCD, 0x85, FIL_, 0xE1,
+		0xBE, 0xAB, FIL_, 0x01, 0xCD, 0x85, FIL_, 0xE1,
+		0xBE, 0xAC, FIL_, 0x01, 0xCD, 0x85, FIL_, 0xE1,
+		0xBE, 0xAD, FIL_, 0x01, 0xCD, 0x85, FIL_, 0xE1,
+		0xBE, 0xAE, FIL_, 0x01, 0xCD, 0x85, FIL_, 0xE1,
+		0xBE, 0xAF, FIL_, 0x01, 0xCD, 0x85, FIL_, 0xE1,
+		0xBE, 0xB2, FIL_, 0x01, 0xCD, 0x85, FIL_, 0xE1,
+		0xBF, 0x82, FIL_, 0x01, 0xCD, 0x85, FIL_, 0xE1,
+		0xBF, 0xB2, FIL_, 0x01, 0xCD, 0x85, FIL_, 0xE1,
+		0xBE, 0xB7, FIL_, 0x03, 0xCC, 0x81, FIL_, 0xE1,
+		0xBF, 0x8E, FIL_, 0xCC, 0x80, FIL_, 0xE1, 0xBF,
+		0x8D, FIL_, 0xCD, 0x82, FIL_, 0xE1, 0xBF, 0x8F,
+		FIL_, 0x01, 0xCD, 0x85, FIL_, 0xE1, 0xBF, 0x87,
+		FIL_, 0x01, 0xCD, 0x85, FIL_, 0xE1, 0xBF, 0xB7,
+		FIL_, 0x03, 0xCC, 0x80, FIL_, 0xE1, 0xBF, 0x9D,
+		FIL_, 0xCC, 0x81, FIL_, 0xE1, 0xBF, 0x9E, FIL_,
+		0xCD, 0x82, FIL_, 0xE1, 0xBF, 0x9F, FIL_, 0x01,
+		0xCC, 0xB8, FIL_, 0xE2, 0x86, 0x9A, FIL_, 0x01,
+		0xCC, 0xB8, FIL_, 0xE2, 0x86, 0x9B, FIL_, 0x01,
+		0xCC, 0xB8, FIL_, 0xE2, 0x86, 0xAE, FIL_, 0x01,
+		0xCC, 0xB8, FIL_, 0xE2, 0x87, 0x8D, FIL_, 0x01,
+		0xCC, 0xB8, FIL_, 0xE2, 0x87, 0x8F, FIL_, 0x01,
+		0xCC, 0xB8, FIL_, 0xE2, 0x87, 0x8E, FIL_, 0x01,
+		0xCC, 0xB8, FIL_, 0xE2, 0x88, 0x84, FIL_, 0x01,
+		0xCC, 0xB8, FIL_, 0xE2, 0x88, 0x89, FIL_, 0x01,
+		0xCC, 0xB8, FIL_, 0xE2, 0x88, 0x8C, FIL_, 0x01,
+		0xCC, 0xB8, FIL_, 0xE2, 0x88, 0xA4, FIL_, 0x01,
+		0xCC, 0xB8, FIL_, 0xE2, 0x88, 0xA6, FIL_, 0x01,
+		0xCC, 0xB8, FIL_, 0xE2, 0x89, 0x81, FIL_, 0x01,
+		0xCC, 0xB8, FIL_, 0xE2, 0x89, 0x84, FIL_, 0x01,
+		0xCC, 0xB8, FIL_, 0xE2, 0x89, 0x87, FIL_, 0x01,
+		0xCC, 0xB8, FIL_, 0xE2, 0x89, 0x89, FIL_, 0x01,
+		0xCC, 0xB8, FIL_, 0xE2, 0x89, 0xAD, FIL_, 0x01,
+		0xCC, 0xB8, FIL_, 0xE2, 0x89, 0xA2, FIL_, 0x01,
+		0xCC, 0xB8, FIL_, 0xE2, 0x89, 0xB0, FIL_, 0x01,
+		0xCC, 0xB8, FIL_, 0xE2, 0x89, 0xB1, FIL_, 0x01,
+		0xCC, 0xB8, FIL_, 0xE2, 0x89, 0xB4, FIL_, 0x01,
+		0xCC, 0xB8, FIL_, 0xE2, 0x89, 0xB5, FIL_, 0x01,
+		0xCC, 0xB8, FIL_, 0xE2, 0x89, 0xB8, FIL_, 0x01,
+		0xCC, 0xB8, FIL_, 0xE2, 0x89, 0xB9, FIL_, 0x01,
+		0xCC, 0xB8, FIL_, 0xE2, 0x8A, 0x80, FIL_, 0x01,
+		0xCC, 0xB8, FIL_, 0xE2, 0x8A, 0x81, FIL_, 0x01,
+		0xCC, 0xB8, FIL_, 0xE2, 0x8B, 0xA0, FIL_, 0x01,
+		0xCC, 0xB8, FIL_, 0xE2, 0x8B, 0xA1, FIL_, 0x01,
+		0xCC, 0xB8, FIL_, 0xE2, 0x8A, 0x84, FIL_, 0x01,
+		0xCC, 0xB8, FIL_, 0xE2, 0x8A, 0x85, FIL_, 0x01,
+		0xCC, 0xB8, FIL_, 0xE2, 0x8A, 0x88, FIL_, 0x01,
+		0xCC, 0xB8, FIL_, 0xE2, 0x8A, 0x89, FIL_, 0x01,
+		0xCC, 0xB8, FIL_, 0xE2, 0x8B, 0xA2, FIL_, 0x01,
+		0xCC, 0xB8, FIL_, 0xE2, 0x8B, 0xA3, FIL_, 0x01,
+		0xCC, 0xB8, FIL_, 0xE2, 0x8A, 0xAC, FIL_, 0x01,
+		0xCC, 0xB8, FIL_, 0xE2, 0x8A, 0xAD, FIL_, 0x01,
+		0xCC, 0xB8, FIL_, 0xE2, 0x8A, 0xAE, FIL_, 0x01,
+		0xCC, 0xB8, FIL_, 0xE2, 0x8A, 0xAF, FIL_, 0x01,
+		0xCC, 0xB8, FIL_, 0xE2, 0x8B, 0xAA, FIL_, 0x01,
+		0xCC, 0xB8, FIL_, 0xE2, 0x8B, 0xAB, FIL_, 0x01,
+		0xCC, 0xB8, FIL_, 0xE2, 0x8B, 0xAC, FIL_, 0x01,
+		0xCC, 0xB8, FIL_, 0xE2, 0x8B, 0xAD, FIL_, 0x01,
+		0xE3, 0x82, 0x99, FIL_, 0xE3, 0x82, 0x94, FIL_,
+		0x01, 0xE3, 0x82, 0x99, FIL_, 0xE3, 0x81, 0x8C,
+		FIL_, 0x01, 0xE3, 0x82, 0x99, FIL_, 0xE3, 0x81,
+		0x8E, FIL_, 0x01, 0xE3, 0x82, 0x99, FIL_, 0xE3,
+		0x81, 0x90, FIL_, 0x01, 0xE3, 0x82, 0x99, FIL_,
+		0xE3, 0x81, 0x92, FIL_, 0x01, 0xE3, 0x82, 0x99,
+		FIL_, 0xE3, 0x81, 0x94, FIL_, 0x01, 0xE3, 0x82,
+		0x99, FIL_, 0xE3, 0x81, 0x96, FIL_, 0x01, 0xE3,
+		0x82, 0x99, FIL_, 0xE3, 0x81, 0x98, FIL_, 0x01,
+		0xE3, 0x82, 0x99, FIL_, 0xE3, 0x81, 0x9A, FIL_,
+		0x01, 0xE3, 0x82, 0x99, FIL_, 0xE3, 0x81, 0x9C,
+		FIL_, 0x01, 0xE3, 0x82, 0x99, FIL_, 0xE3, 0x81,
+		0x9E, FIL_, 0x01, 0xE3, 0x82, 0x99, FIL_, 0xE3,
+		0x81, 0xA0, FIL_, 0x01, 0xE3, 0x82, 0x99, FIL_,
+		0xE3, 0x81, 0xA2, FIL_, 0x01, 0xE3, 0x82, 0x99,
+		FIL_, 0xE3, 0x81, 0xA5, FIL_, 0x01, 0xE3, 0x82,
+		0x99, FIL_, 0xE3, 0x81, 0xA7, FIL_, 0x01, 0xE3,
+		0x82, 0x99, FIL_, 0xE3, 0x81, 0xA9, FIL_, 0x02,
+		0xE3, 0x82, 0x9A, FIL_, 0xE3, 0x81, 0xB1, FIL_,
+		0xE3, 0x82, 0x99, FIL_, 0xE3, 0x81, 0xB0, FIL_,
+		0x02, 0xE3, 0x82, 0x99, FIL_, 0xE3, 0x81, 0xB3,
+		FIL_, 0xE3, 0x82, 0x9A, FIL_, 0xE3, 0x81, 0xB4,
+		FIL_, 0x02, 0xE3, 0x82, 0x99, FIL_, 0xE3, 0x81,
+		0xB6, FIL_, 0xE3, 0x82, 0x9A, FIL_, 0xE3, 0x81,
+		0xB7, FIL_, 0x02, 0xE3, 0x82, 0x9A, FIL_, 0xE3,
+		0x81, 0xBA, FIL_, 0xE3, 0x82, 0x99, FIL_, 0xE3,
+		0x81, 0xB9, FIL_, 0x02, 0xE3, 0x82, 0x9A, FIL_,
+		0xE3, 0x81, 0xBD, FIL_, 0xE3, 0x82, 0x99, FIL_,
+		0xE3, 0x81, 0xBC, FIL_, 0x01, 0xE3, 0x82, 0x99,
+		FIL_, 0xE3, 0x82, 0x9E, FIL_, 0x01, 0xE3, 0x82,
+		0x99, FIL_, 0xE3, 0x83, 0xB4, FIL_, 0x01, 0xE3,
+		0x82, 0x99, FIL_, 0xE3, 0x82, 0xAC, FIL_, 0x01,
+		0xE3, 0x82, 0x99, FIL_, 0xE3, 0x82, 0xAE, FIL_,
+		0x01, 0xE3, 0x82, 0x99, FIL_, 0xE3, 0x82, 0xB0,
+		FIL_, 0x01, 0xE3, 0x82, 0x99, FIL_, 0xE3, 0x82,
+		0xB2, FIL_, 0x01, 0xE3, 0x82, 0x99, FIL_, 0xE3,
+		0x82, 0xB4, FIL_, 0x01, 0xE3, 0x82, 0x99, FIL_,
+		0xE3, 0x82, 0xB6, FIL_, 0x01, 0xE3, 0x82, 0x99,
+		FIL_, 0xE3, 0x82, 0xB8, FIL_, 0x01, 0xE3, 0x82,
+		0x99, FIL_, 0xE3, 0x82, 0xBA, FIL_, 0x01, 0xE3,
+		0x82, 0x99, FIL_, 0xE3, 0x82, 0xBC, FIL_, 0x01,
+		0xE3, 0x82, 0x99, FIL_, 0xE3, 0x82, 0xBE, FIL_,
+		0x01, 0xE3, 0x82, 0x99, FIL_, 0xE3, 0x83, 0x80,
+		FIL_, 0x01, 0xE3, 0x82, 0x99, FIL_, 0xE3, 0x83,
+		0x82, FIL_, 0x01, 0xE3, 0x82, 0x99, FIL_, 0xE3,
+		0x83, 0x85, FIL_, 0x01, 0xE3, 0x82, 0x99, FIL_,
+		0xE3, 0x83, 0x87, FIL_, 0x01, 0xE3, 0x82, 0x99,
+		FIL_, 0xE3, 0x83, 0x89, FIL_, 0x02, 0xE3, 0x82,
+		0x99, FIL_, 0xE3, 0x83, 0x90, FIL_, 0xE3, 0x82,
+		0x9A, FIL_, 0xE3, 0x83, 0x91, FIL_, 0x02, 0xE3,
+		0x82, 0x99, FIL_, 0xE3, 0x83, 0x93, FIL_, 0xE3,
+		0x82, 0x9A, FIL_, 0xE3, 0x83, 0x94, FIL_, 0x02,
+		0xE3, 0x82, 0x9A, FIL_, 0xE3, 0x83, 0x97, FIL_,
+		0xE3, 0x82, 0x99, FIL_, 0xE3, 0x83, 0x96, FIL_,
+		0x02, 0xE3, 0x82, 0x9A, FIL_, 0xE3, 0x83, 0x9A,
+		FIL_, 0xE3, 0x82, 0x99, FIL_, 0xE3, 0x83, 0x99,
+		FIL_, 0x02, 0xE3, 0x82, 0x99, FIL_, 0xE3, 0x83,
+		0x9C, FIL_, 0xE3, 0x82, 0x9A, FIL_, 0xE3, 0x83,
+		0x9D, FIL_, 0x01, 0xE3, 0x82, 0x99, FIL_, 0xE3,
+		0x83, 0xB7, FIL_, 0x01, 0xE3, 0x82, 0x99, FIL_,
+		0xE3, 0x83, 0xB8, FIL_, 0x01, 0xE3, 0x82, 0x99,
+		FIL_, 0xE3, 0x83, 0xB9, FIL_, 0x01, 0xE3, 0x82,
+		0x99, FIL_, 0xE3, 0x83, 0xBA, FIL_, 0x01, 0xE3,
+		0x82, 0x99, FIL_, 0xE3, 0x83, 0xBE, FIL_,
+	},
+};
+
+static const uchar_t u8_decomp_b2_tbl[2][2][256] = {
+	{
+		{
+			0,  N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			1,  2,  3,  4,  N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, 5,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+		},
+		{
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, 6,  N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, 7,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+		},
+
+	},
+	{
+		{
+			0,  N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			1,  2,  3,  4,  N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, 5,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+		},
+		{
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, 6,  N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, 7,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+		},
+
+	},
+
+};
+
+static const u8_displacement_t u8_decomp_b3_tbl[2][8][256] = {
+	{
+		{	/* Third byte table 0. */
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { 0, 0 },
+			{ 1, 35 }, { 2, 247 }, { 3, 474 },
+			{ 4, 693 }, { 5, 709 }, { 6, 951 },
+			{ N_, 0 }, { 7, 1139 }, { 8, 1152 },
+			{ N_, 0 }, { 9, 1177 }, { 10, 1199 },
+			{ 11, 1295 }, { 12, 1360 }, { 13, 1405 },
+			{ N_, 0 }, { 14, 1450 }, { N_, 0 },
+			{ N_, 0 }, { 15, 1620 }, { N_, 0 },
+			{ 16, 1624 }, { 17, 1649 }, { N_, 0 },
+			{ 18, 1665 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 },
+		},
+		{	/* Third byte table 1. */
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { 19, 1680 },
+			{ 20, 1701 }, { N_, 0 }, { 21, 1757 },
+			{ 22, 1792 }, { 23, 1806 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { 24, 1834 },
+			{ 25, 1869 }, { 26, 1876 }, { N_, 0 },
+			{ 27, 1897 }, { N_, 0 }, { 28, 1904 },
+			{ N_, 0 }, { 29, 1942 }, { N_, 0 },
+			{ 30, 1963 }, { 31, 1994 }, { N_, 0 },
+			{ 32, 2000 }, { 33, 2006 }, { 34, 2018 },
+			{ 35, 2021 }, { 36, 2109 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 },
+		},
+		{	/* Third byte table 2. */
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { 37, 2158 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { 0x8000, 2165 }, { 0x8001, 2445 },
+			{ 0x8002, 2741 }, { 0x8003, 3029 }, { 0x8004, 3337 },
+			{ 0x8005, 3725 }, { 0x8006, 4053 }, { 0x8007, 4536 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 },
+		},
+		{	/* Third byte table 3. */
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { 38, 4895 },
+			{ 39, 4964 }, { 40, 4999 }, { N_, 0 },
+			{ 41, 5018 }, { 42, 5098 }, { 43, 5230 },
+			{ 44, 5248 }, { 45, 5266 }, { 46, 5326 },
+			{ 47, 5410 }, { 48, 5470 }, { 49, 5518 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { 50, 5526 }, { 51, 5596 },
+			{ 52, 5767 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ 53, 5810 }, { 54, 5822 }, { N_, 0 },
+			{ 55, 5830 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ 56, 5836 }, { 57, 5839 }, { 58, 5842 },
+			{ 59, 6034 }, { 60, 6226 }, { 61, 6418 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 },
+		},
+		{	/* Third byte table 4. */
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { 62, 6484 },
+			{ 63, 6497 }, { 64, 6672 }, { 65, 6770 },
+			{ 66, 6923 }, { 67, 6968 }, { 68, 7160 },
+			{ N_, 0 }, { 0x8008, 7247 }, { 69, 7597 },
+			{ 70, 7773 }, { 71, 7950 }, { 0x8009, 8142 },
+			{ 0x800A, 8919 }, { 72, 9351 }, { 73, 9522 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 },
+		},
+		{	/* Third byte table 5. */
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { 0x800B, 9743 },
+			{ 0x800C, 9999 }, { 0x800D, 10255 }, { 0x800E, 10511 },
+			{ 74, 10767 }, { 75, 10967 }, { N_, 0 },
+			{ N_, 0 }, { 76, 11139 }, { 77, 11303 },
+			{ 78, 11468 }, { 79, 11576 }, { 0x800F, 11740 },
+			{ 0x8010, 12006 }, { 0x8011, 12280 }, { 0x8012, 12546 },
+			{ 80, 12812 }, { 0x8013, 13060 }, { 0x8014, 13348 },
+			{ 81, 13720 }, { 82, 13898 }, { 83, 13933 },
+			{ 84, 14045 }, { 85, 14197 }, { 86, 14347 },
+			{ 87, 14410 }, { 88, 14540 }, { 89, 14729 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 },
+		},
+		{	/* Third byte table 6. */
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { 90, 14829 }, { 91, 14912 },
+			{ 92, 14969 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ 93, 14982 }, { 94, 15046 }, { 95, 15109 },
+			{ 96, 15163 }, { 97, 15225 }, { 98, 15282 },
+			{ 99, 15341 }, { 100, 15405 }, { 101, 15469 },
+			{ 102, 15533 }, { 103, 15597 }, { 104, 15681 },
+			{ 105, 15812 }, { 106, 15942 }, { 107, 16072 },
+			{ 108, 16202 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 },
+		},
+		{	/* Third byte table 7. */
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { 0x8015, 16273 }, { 0x8016, 16536 },
+			{ 0x8017, 16799 }, { 0x8018, 17064 }, { 0x8019, 17329 },
+			{ 0x801A, 17601 }, { 0x801B, 17878 }, { 0x801C, 18147 },
+			{ 109, 18419 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 },
+		},
+	},
+	{
+		{	/* Third byte table 0. */
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { 0, 0 },
+			{ 1, 35 }, { 2, 247 }, { 3, 474 },
+			{ 4, 693 }, { 5, 709 }, { 6, 951 },
+			{ N_, 0 }, { 7, 1139 }, { 8, 1152 },
+			{ N_, 0 }, { 9, 1177 }, { 10, 1199 },
+			{ 11, 1295 }, { 12, 1362 }, { 13, 1407 },
+			{ N_, 0 }, { 14, 1452 }, { N_, 0 },
+			{ N_, 0 }, { 15, 1622 }, { N_, 0 },
+			{ 16, 1626 }, { 17, 1651 }, { N_, 0 },
+			{ 18, 1667 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 },
+		},
+		{	/* Third byte table 1. */
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { 19, 1682 },
+			{ 20, 1703 }, { N_, 0 }, { 21, 1759 },
+			{ 22, 1794 }, { 23, 1808 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { 24, 1836 },
+			{ 25, 1871 }, { 26, 1878 }, { N_, 0 },
+			{ 27, 1899 }, { N_, 0 }, { 28, 1906 },
+			{ N_, 0 }, { 29, 1944 }, { N_, 0 },
+			{ 30, 1965 }, { 31, 1996 }, { N_, 0 },
+			{ 32, 2002 }, { 33, 2008 }, { 34, 2020 },
+			{ 35, 2023 }, { 36, 2111 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 },
+		},
+		{	/* Third byte table 2. */
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { 37, 2160 },
+			{ N_, 0 }, { N_, 0 }, { 38, 2167 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { 39, 2170 }, { 40, 2226 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ 41, 2247 }, { 42, 2268 }, { 43, 2340 },
+			{ N_, 0 }, { 0x8000, 2414 }, { 0x8001, 2694 },
+			{ 0x8002, 2990 }, { 0x8003, 3278 }, { 0x8004, 3586 },
+			{ 0x8005, 3974 }, { 0x8006, 4302 }, { 0x8007, 4785 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 },
+		},
+		{	/* Third byte table 3. */
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { 44, 5144 },
+			{ 45, 5213 }, { 46, 5248 }, { N_, 0 },
+			{ 47, 5273 }, { 48, 5358 }, { 49, 5490 },
+			{ 50, 5508 }, { 51, 5526 }, { 52, 5586 },
+			{ 53, 5670 }, { 54, 5730 }, { 55, 5778 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { 56, 5786 }, { 57, 5856 },
+			{ 58, 6027 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ 59, 6070 }, { 60, 6082 }, { N_, 0 },
+			{ 61, 6090 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { 62, 6096 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ 63, 6099 }, { 64, 6102 }, { 65, 6105 },
+			{ 66, 6297 }, { 67, 6489 }, { 68, 6681 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 },
+		},
+		{	/* Third byte table 4. */
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { 69, 6747 },
+			{ 70, 6760 }, { 71, 6935 }, { 72, 7033 },
+			{ 73, 7186 }, { 74, 7231 }, { 75, 7423 },
+			{ N_, 0 }, { 0x8008, 7510 }, { 76, 7891 },
+			{ 77, 8103 }, { 78, 8280 }, { 0x8009, 8482 },
+			{ 0x800A, 9259 }, { 79, 9701 }, { 80, 9872 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 },
+		},
+		{	/* Third byte table 5. */
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { 0x800B, 10106 },
+			{ 0x800C, 10362 }, { 0x800D, 10618 }, { 0x800E, 10874 },
+			{ 81, 11130 }, { 82, 11330 }, { 0x800F, 11566 },
+			{ 83, 11822 }, { 84, 11932 }, { 85, 12096 },
+			{ 86, 12261 }, { 87, 12369 }, { 0x8010, 12533 },
+			{ 0x8011, 12799 }, { 0x8012, 13073 }, { 0x8013, 13339 },
+			{ 88, 13605 }, { 0x8014, 13853 }, { 0x8015, 14141 },
+			{ 89, 14513 }, { 90, 14691 }, { 91, 14746 },
+			{ 92, 14860 }, { 93, 15012 }, { 94, 15162 },
+			{ 95, 15225 }, { 96, 15355 }, { 97, 15544 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 },
+		},
+		{	/* Third byte table 6. */
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { 98, 15644 }, { 99, 15727 },
+			{ 100, 15784 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ 101, 15797 }, { 102, 15861 }, { 103, 15924 },
+			{ 104, 15978 }, { 105, 16041 }, { 106, 16098 },
+			{ 107, 16157 }, { 108, 16221 }, { 109, 16285 },
+			{ 110, 16349 }, { 111, 16413 }, { 112, 16501 },
+			{ 113, 16632 }, { 114, 16762 }, { 115, 16892 },
+			{ 116, 17022 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 },
+		},
+		{	/* Third byte table 7. */
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { 0x8016, 17097 }, { 0x8017, 17360 },
+			{ 0x8018, 17623 }, { 0x8019, 17888 }, { 0x801A, 18153 },
+			{ 0x801B, 18425 }, { 0x801C, 18702 }, { 0x801D, 18971 },
+			{ 117, 19243 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 },
+		},
+	},
+};
+
+static const uchar_t u8_decomp_b4_tbl[2][118][257] = {
+	{
+		{	/* Fourth byte table 0. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   1,   1,   1,   1,   1,   1,   1,
+			1,   4,   4,   5,   5,   5,   5,   5,
+			8,   8,   8,   9,   10,  13,  15,  15,
+			15,  18,  19,  20,  20,  25,  30,  35,
+			35,  35,  35,  35,  35,  35,  35,  35,
+			35,  35,  35,  35,  35,  35,  35,  35,
+			35,  35,  35,  35,  35,  35,  35,  35,
+			35,  35,  35,  35,  35,  35,  35,  35,
+			35,  35,  35,  35,  35,  35,  35,  35,
+			35,  35,  35,  35,  35,  35,  35,  35,
+			35,  35,  35,  35,  35,  35,  35,  35,
+			35,  35,  35,  35,  35,  35,  35,  35,
+			35,
+		},
+		{	/* Fourth byte table 1. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   4,   8,   12,  16,  20,  24,  24,
+			28,  32,  36,  40,  44,  48,  52,  56,
+			60,  60,  64,  68,  72,  76,  80,  84,
+			84,  84,  88,  92,  96,  100, 104, 104,
+			104, 108, 112, 116, 120, 124, 128, 128,
+			132, 136, 140, 144, 148, 152, 156, 160,
+			164, 164, 168, 172, 176, 180, 184, 188,
+			188, 188, 192, 196, 200, 204, 208, 208,
+			212, 212, 212, 212, 212, 212, 212, 212,
+			212, 212, 212, 212, 212, 212, 212, 212,
+			212, 212, 212, 212, 212, 212, 212, 212,
+			212, 212, 212, 212, 212, 212, 212, 212,
+			212, 212, 212, 212, 212, 212, 212, 212,
+			212, 212, 212, 212, 212, 212, 212, 212,
+			212, 212, 212, 212, 212, 212, 212, 212,
+			212, 212, 212, 212, 212, 212, 212, 212,
+			212,
+		},
+		{	/* Fourth byte table 2. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   4,   8,   12,  16,  20,  24,  28,
+			32,  36,  40,  44,  48,  52,  56,  60,
+			64,  64,  64,  68,  72,  76,  80,  84,
+			88,  92,  96,  100, 104, 108, 112, 116,
+			120, 124, 128, 132, 136, 140, 144, 144,
+			144, 148, 152, 156, 160, 164, 168, 172,
+			176, 180, 180, 182, 184, 188, 192, 196,
+			200, 200, 204, 208, 212, 216, 220, 224,
+			227, 227, 227, 227, 227, 227, 227, 227,
+			227, 227, 227, 227, 227, 227, 227, 227,
+			227, 227, 227, 227, 227, 227, 227, 227,
+			227, 227, 227, 227, 227, 227, 227, 227,
+			227, 227, 227, 227, 227, 227, 227, 227,
+			227, 227, 227, 227, 227, 227, 227, 227,
+			227, 227, 227, 227, 227, 227, 227, 227,
+			227, 227, 227, 227, 227, 227, 227, 227,
+			227,
+		},
+		{	/* Fourth byte table 3. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   3,   3,   3,   7,   11,  15,  19,
+			23,  27,  30,  30,  30,  34,  38,  42,
+			46,  50,  54,  54,  54,  58,  62,  66,
+			70,  74,  78,  82,  86,  90,  94,  98,
+			102, 106, 110, 114, 118, 122, 126, 126,
+			126, 130, 134, 138, 142, 146, 150, 154,
+			158, 162, 166, 170, 174, 178, 182, 186,
+			190, 194, 198, 202, 206, 210, 214, 218,
+			219, 219, 219, 219, 219, 219, 219, 219,
+			219, 219, 219, 219, 219, 219, 219, 219,
+			219, 219, 219, 219, 219, 219, 219, 219,
+			219, 219, 219, 219, 219, 219, 219, 219,
+			219, 219, 219, 219, 219, 219, 219, 219,
+			219, 219, 219, 219, 219, 219, 219, 219,
+			219, 219, 219, 219, 219, 219, 219, 219,
+			219, 219, 219, 219, 219, 219, 219, 219,
+			219,
+		},
+		{	/* Fourth byte table 4. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   4,   8,   8,   8,   8,   8,   8,
+			8,   8,   8,   8,   8,   8,   8,   8,
+			12,  16,  16,  16,  16,  16,  16,  16,
+			16,  16,  16,  16,  16,  16,  16,  16,
+			16,  16,  16,  16,  16,  16,  16,  16,
+			16,  16,  16,  16,  16,  16,  16,  16,
+			16,  16,  16,  16,  16,  16,  16,  16,
+			16,  16,  16,  16,  16,  16,  16,  16,
+			16,  16,  16,  16,  16,  16,  16,  16,
+			16,  16,  16,  16,  16,  16,  16,  16,
+			16,  16,  16,  16,  16,  16,  16,  16,
+			16,  16,  16,  16,  16,  16,  16,  16,
+			16,
+		},
+		{	/* Fourth byte table 5. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   4,   8,   12,
+			14,  16,  18,  20,  22,  24,  28,  32,
+			36,  40,  44,  48,  52,  56,  62,  68,
+			74,  80,  86,  92,  98,  104, 104, 110,
+			116, 122, 128, 133, 138, 138, 138, 142,
+			146, 150, 154, 158, 162, 168, 174, 179,
+			184, 188, 190, 192, 194, 198, 202, 202,
+			202, 206, 210, 216, 222, 227, 232, 237,
+			242, 242, 242, 242, 242, 242, 242, 242,
+			242, 242, 242, 242, 242, 242, 242, 242,
+			242, 242, 242, 242, 242, 242, 242, 242,
+			242, 242, 242, 242, 242, 242, 242, 242,
+			242, 242, 242, 242, 242, 242, 242, 242,
+			242, 242, 242, 242, 242, 242, 242, 242,
+			242, 242, 242, 242, 242, 242, 242, 242,
+			242, 242, 242, 242, 242, 242, 242, 242,
+			242,
+		},
+		{	/* Fourth byte table 6. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   4,   8,   12,  16,  20,  24,  28,
+			32,  36,  40,  44,  48,  52,  56,  60,
+			64,  68,  72,  76,  80,  84,  88,  92,
+			96,  100, 104, 108, 112, 112, 112, 116,
+			120, 120, 120, 120, 120, 120, 120, 124,
+			128, 132, 136, 142, 148, 154, 160, 164,
+			168, 174, 180, 184, 188, 188, 188, 188,
+			188, 188, 188, 188, 188, 188, 188, 188,
+			188, 188, 188, 188, 188, 188, 188, 188,
+			188, 188, 188, 188, 188, 188, 188, 188,
+			188, 188, 188, 188, 188, 188, 188, 188,
+			188, 188, 188, 188, 188, 188, 188, 188,
+			188, 188, 188, 188, 188, 188, 188, 188,
+			188, 188, 188, 188, 188, 188, 188, 188,
+			188, 188, 188, 188, 188, 188, 188, 188,
+			188, 188, 188, 188, 188, 188, 188, 188,
+			188,
+		},
+		{	/* Fourth byte table 7. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   1,   3,   4,   5,   7,   9,   11,
+			12,  13,  13,  13,  13,  13,  13,  13,
+			13,  13,  13,  13,  13,  13,  13,  13,
+			13,  13,  13,  13,  13,  13,  13,  13,
+			13,  13,  13,  13,  13,  13,  13,  13,
+			13,  13,  13,  13,  13,  13,  13,  13,
+			13,  13,  13,  13,  13,  13,  13,  13,
+			13,  13,  13,  13,  13,  13,  13,  13,
+			13,  13,  13,  13,  13,  13,  13,  13,
+			13,  13,  13,  13,  13,  13,  13,  13,
+			13,
+		},
+		{	/* Fourth byte table 8. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   3,   6,   9,   12,  15,  18,  18,
+			18,  20,  21,  22,  23,  25,  25,  25,
+			25,  25,  25,  25,  25,  25,  25,  25,
+			25,  25,  25,  25,  25,  25,  25,  25,
+			25,  25,  25,  25,  25,  25,  25,  25,
+			25,  25,  25,  25,  25,  25,  25,  25,
+			25,  25,  25,  25,  25,  25,  25,  25,
+			25,  25,  25,  25,  25,  25,  25,  25,
+			25,  25,  25,  25,  25,  25,  25,  25,
+			25,  25,  25,  25,  25,  25,  25,  25,
+			25,  25,  25,  25,  25,  25,  25,  25,
+			25,  25,  25,  25,  25,  25,  25,  25,
+			25,  25,  25,  25,  25,  25,  25,  25,
+			25,
+		},
+		{	/* Fourth byte table 9. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   3,   6,   6,   9,   14,  14,  14,
+			14,  14,  14,  14,  14,  14,  14,  14,
+			14,  14,  14,  14,  14,  14,  14,  14,
+			14,  14,  14,  14,  14,  14,  14,  14,
+			14,  14,  14,  14,  14,  14,  14,  14,
+			14,  14,  14,  14,  14,  14,  14,  14,
+			14,  14,  14,  14,  14,  17,  17,  17,
+			17,  17,  17,  20,  20,  20,  20,  22,
+			22,  22,  22,  22,  22,  22,  22,  22,
+			22,  22,  22,  22,  22,  22,  22,  22,
+			22,  22,  22,  22,  22,  22,  22,  22,
+			22,  22,  22,  22,  22,  22,  22,  22,
+			22,  22,  22,  22,  22,  22,  22,  22,
+			22,  22,  22,  22,  22,  22,  22,  22,
+			22,  22,  22,  22,  22,  22,  22,  22,
+			22,  22,  22,  22,  22,  22,  22,  22,
+			22,
+		},
+		{	/* Fourth byte table 10. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   3,   14,  19,
+			22,  27,  32,  37,  37,  42,  42,  47,
+			52,  59,  59,  59,  59,  59,  59,  59,
+			59,  59,  59,  59,  59,  59,  59,  59,
+			59,  59,  59,  59,  59,  59,  59,  59,
+			59,  59,  59,  64,  69,  74,  79,  84,
+			89,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,
+		},
+		{	/* Fourth byte table 11. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   5,   10,  15,  20,  25,
+			25,  27,  29,  31,  41,  51,  53,  55,
+			55,  55,  55,  55,  55,  55,  55,  55,
+			55,  55,  55,  55,  55,  55,  55,  55,
+			55,  55,  55,  55,  55,  55,  55,  55,
+			55,  57,  59,  61,  61,  63,  65,  65,
+			65,  65,  65,  65,  65,  65,  65,  65,
+			65,  65,  65,  65,  65,  65,  65,  65,
+			65,  65,  65,  65,  65,  65,  65,  65,
+			65,  65,  65,  65,  65,  65,  65,  65,
+			65,  65,  65,  65,  65,  65,  65,  65,
+			65,  65,  65,  65,  65,  65,  65,  65,
+			65,  65,  65,  65,  65,  65,  65,  65,
+			65,  65,  65,  65,  65,  65,  65,  65,
+			65,  65,  65,  65,  65,  65,  65,  65,
+			65,
+		},
+		{	/* Fourth byte table 12. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   5,   10,  10,  15,  15,  15,  15,
+			20,  20,  20,  20,  20,  25,  30,  35,
+			35,  35,  35,  35,  35,  35,  35,  35,
+			35,  35,  40,  40,  40,  40,  40,  40,
+			40,  40,  40,  40,  40,  40,  40,  40,
+			40,  40,  40,  40,  40,  40,  40,  40,
+			40,  40,  40,  40,  40,  40,  40,  40,
+			40,  40,  45,  45,  45,  45,  45,  45,
+			45,  45,  45,  45,  45,  45,  45,  45,
+			45,  45,  45,  45,  45,  45,  45,  45,
+			45,  45,  45,  45,  45,  45,  45,  45,
+			45,  45,  45,  45,  45,  45,  45,  45,
+			45,  45,  45,  45,  45,  45,  45,  45,
+			45,  45,  45,  45,  45,  45,  45,  45,
+			45,  45,  45,  45,  45,  45,  45,  45,
+			45,  45,  45,  45,  45,  45,  45,  45,
+			45,
+		},
+		{	/* Fourth byte table 13. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   5,   10,  10,  15,  15,  15,  15,
+			20,  20,  20,  20,  20,  25,  30,  35,
+			35,  35,  35,  35,  35,  35,  35,  35,
+			35,  35,  35,  35,  35,  35,  35,  35,
+			35,  35,  35,  35,  35,  35,  35,  40,
+			45,  45,  45,  45,  45,  45,  45,  45,
+			45,  45,  45,  45,  45,  45,  45,  45,
+			45,  45,  45,  45,  45,  45,  45,  45,
+			45,  45,  45,  45,  45,  45,  45,  45,
+			45,  45,  45,  45,  45,  45,  45,  45,
+			45,  45,  45,  45,  45,  45,  45,  45,
+			45,  45,  45,  45,  45,  45,  45,  45,
+			45,  45,  45,  45,  45,  45,  45,  45,
+			45,  45,  45,  45,  45,  45,  45,  45,
+			45,
+		},
+		{	/* Fourth byte table 14. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   5,   10,  10,  10,  10,  10,
+			10,  10,  10,  10,  10,  10,  10,  10,
+			10,  15,  20,  25,  30,  30,  30,  35,
+			40,  40,  40,  45,  50,  55,  60,  65,
+			70,  70,  70,  75,  80,  85,  90,  95,
+			100, 100, 100, 105, 110, 115, 120, 125,
+			130, 135, 140, 145, 150, 155, 160, 160,
+			160, 165, 170, 170, 170, 170, 170, 170,
+			170, 170, 170, 170, 170, 170, 170, 170,
+			170, 170, 170, 170, 170, 170, 170, 170,
+			170, 170, 170, 170, 170, 170, 170, 170,
+			170, 170, 170, 170, 170, 170, 170, 170,
+			170, 170, 170, 170, 170, 170, 170, 170,
+			170, 170, 170, 170, 170, 170, 170, 170,
+			170, 170, 170, 170, 170, 170, 170, 170,
+			170, 170, 170, 170, 170, 170, 170, 170,
+			170,
+		},
+		{	/* Fourth byte table 15. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			4,   4,   4,   4,   4,   4,   4,   4,
+			4,   4,   4,   4,   4,   4,   4,   4,
+			4,   4,   4,   4,   4,   4,   4,   4,
+			4,   4,   4,   4,   4,   4,   4,   4,
+			4,   4,   4,   4,   4,   4,   4,   4,
+			4,   4,   4,   4,   4,   4,   4,   4,
+			4,   4,   4,   4,   4,   4,   4,   4,
+			4,   4,   4,   4,   4,   4,   4,   4,
+			4,   4,   4,   4,   4,   4,   4,   4,
+			4,   4,   4,   4,   4,   4,   4,   4,
+			4,   4,   4,   4,   4,   4,   4,   4,
+			4,   4,   4,   4,   4,   4,   4,   4,
+			4,   4,   4,   4,   4,   4,   4,   4,
+			4,   4,   4,   4,   4,   4,   4,   4,
+			4,   4,   4,   4,   4,   4,   4,   4,
+			4,
+		},
+		{	/* Fourth byte table 16. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   5,   10,  15,  20,  25,
+			25,  25,  25,  25,  25,  25,  25,  25,
+			25,  25,  25,  25,  25,  25,  25,  25,
+			25,  25,  25,  25,  25,  25,  25,  25,
+			25,  25,  25,  25,  25,  25,  25,  25,
+			25,  25,  25,  25,  25,  25,  25,  25,
+			25,  25,  25,  25,  25,  25,  25,  25,
+			25,  25,  25,  25,  25,  25,  25,  25,
+			25,  25,  25,  25,  25,  25,  25,  25,
+			25,  25,  25,  25,  25,  25,  25,  25,
+			25,  25,  25,  25,  25,  25,  25,  25,
+			25,  25,  25,  25,  25,  25,  25,  25,
+			25,
+		},
+		{	/* Fourth byte table 17. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   4,   8,
+			12,  16,  16,  16,  16,  16,  16,  16,
+			16,  16,  16,  16,  16,  16,  16,  16,
+			16,  16,  16,  16,  16,  16,  16,  16,
+			16,  16,  16,  16,  16,  16,  16,  16,
+			16,  16,  16,  16,  16,  16,  16,  16,
+			16,  16,  16,  16,  16,  16,  16,  16,
+			16,  16,  16,  16,  16,  16,  16,  16,
+			16,  16,  16,  16,  16,  16,  16,  16,
+			16,  16,  16,  16,  16,  16,  16,  16,
+			16,
+		},
+		{	/* Fourth byte table 18. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   5,   5,   10,  10,  10,  10,  10,
+			10,  10,  10,  10,  10,  10,  10,  10,
+			10,  10,  10,  10,  15,  15,  15,  15,
+			15,  15,  15,  15,  15,  15,  15,  15,
+			15,  15,  15,  15,  15,  15,  15,  15,
+			15,  15,  15,  15,  15,  15,  15,  15,
+			15,  15,  15,  15,  15,  15,  15,  15,
+			15,  15,  15,  15,  15,  15,  15,  15,
+			15,  15,  15,  15,  15,  15,  15,  15,
+			15,  15,  15,  15,  15,  15,  15,  15,
+			15,  15,  15,  15,  15,  15,  15,  15,
+			15,  15,  15,  15,  15,  15,  15,  15,
+			15,  15,  15,  15,  15,  15,  15,  15,
+			15,  15,  15,  15,  15,  15,  15,  15,
+			15,  15,  15,  15,  15,  15,  15,  15,
+			15,  15,  15,  15,  15,  15,  15,  15,
+			15,
+		},
+		{	/* Fourth byte table 19. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   7,   7,   7,   7,   7,   7,
+			7,   7,   14,  14,  14,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,
+		},
+		{	/* Fourth byte table 20. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   7,   14,  21,  28,  35,  42,  49,
+			56,  56,  56,  56,  56,  56,  56,  56,
+			56,  56,  56,  56,  56,  56,  56,  56,
+			56,  56,  56,  56,  56,  56,  56,  56,
+			56,  56,  56,  56,  56,  56,  56,  56,
+			56,  56,  56,  56,  56,  56,  56,  56,
+			56,  56,  56,  56,  56,  56,  56,  56,
+			56,  56,  56,  56,  56,  56,  56,  56,
+			56,  56,  56,  56,  56,  56,  56,  56,
+			56,  56,  56,  56,  56,  56,  56,  56,
+			56,  56,  56,  56,  56,  56,  56,  56,
+			56,  56,  56,  56,  56,  56,  56,  56,
+			56,  56,  56,  56,  56,  56,  56,  56,
+			56,
+		},
+		{	/* Fourth byte table 21. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   7,   14,  14,  14,
+			14,  14,  14,  14,  14,  14,  14,  14,
+			14,  14,  14,  14,  14,  21,  28,  28,
+			35,  35,  35,  35,  35,  35,  35,  35,
+			35,  35,  35,  35,  35,  35,  35,  35,
+			35,  35,  35,  35,  35,  35,  35,  35,
+			35,  35,  35,  35,  35,  35,  35,  35,
+			35,  35,  35,  35,  35,  35,  35,  35,
+			35,  35,  35,  35,  35,  35,  35,  35,
+			35,  35,  35,  35,  35,  35,  35,  35,
+			35,  35,  35,  35,  35,  35,  35,  35,
+			35,  35,  35,  35,  35,  35,  35,  35,
+			35,  35,  35,  35,  35,  35,  35,  35,
+			35,  35,  35,  35,  35,  35,  35,  35,
+			35,  35,  35,  35,  35,  35,  35,  35,
+			35,
+		},
+		{	/* Fourth byte table 22. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   7,   7,   7,   14,
+			14,  14,  14,  14,  14,  14,  14,  14,
+			14,  14,  14,  14,  14,  14,  14,  14,
+			14,  14,  14,  14,  14,  14,  14,  14,
+			14,  14,  14,  14,  14,  14,  14,  14,
+			14,  14,  14,  14,  14,  14,  14,  14,
+			14,  14,  14,  14,  14,  14,  14,  14,
+			14,  14,  14,  14,  14,  14,  14,  14,
+			14,  14,  14,  14,  14,  14,  14,  14,
+			14,  14,  14,  14,  14,  14,  14,  14,
+			14,
+		},
+		{	/* Fourth byte table 23. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   7,   14,  21,  21,  21,  28,
+			28,  28,  28,  28,  28,  28,  28,  28,
+			28,  28,  28,  28,  28,  28,  28,  28,
+			28,  28,  28,  28,  28,  28,  28,  28,
+			28,  28,  28,  28,  28,  28,  28,  28,
+			28,  28,  28,  28,  28,  28,  28,  28,
+			28,  28,  28,  28,  28,  28,  28,  28,
+			28,  28,  28,  28,  28,  28,  28,  28,
+			28,  28,  28,  28,  28,  28,  28,  28,
+			28,  28,  28,  28,  28,  28,  28,  28,
+			28,  28,  28,  28,  28,  28,  28,  28,
+			28,  28,  28,  28,  28,  28,  28,  28,
+			28,  28,  28,  28,  28,  28,  28,  28,
+			28,
+		},
+		{	/* Fourth byte table 24. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   7,   7,   7,   14,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  28,  35,  35,
+			35,  35,  35,  35,  35,  35,  35,  35,
+			35,  35,  35,  35,  35,  35,  35,  35,
+			35,  35,  35,  35,  35,  35,  35,  35,
+			35,  35,  35,  35,  35,  35,  35,  35,
+			35,  35,  35,  35,  35,  35,  35,  35,
+			35,  35,  35,  35,  35,  35,  35,  35,
+			35,  35,  35,  35,  35,  35,  35,  35,
+			35,  35,  35,  35,  35,  35,  35,  35,
+			35,  35,  35,  35,  35,  35,  35,  35,
+			35,  35,  35,  35,  35,  35,  35,  35,
+			35,  35,  35,  35,  35,  35,  35,  35,
+			35,  35,  35,  35,  35,  35,  35,  35,
+			35,
+		},
+		{	/* Fourth byte table 25. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   7,   7,   7,
+			7,   7,   7,   7,   7,   7,   7,   7,
+			7,   7,   7,   7,   7,   7,   7,   7,
+			7,   7,   7,   7,   7,   7,   7,   7,
+			7,   7,   7,   7,   7,   7,   7,   7,
+			7,   7,   7,   7,   7,   7,   7,   7,
+			7,   7,   7,   7,   7,   7,   7,   7,
+			7,   7,   7,   7,   7,   7,   7,   7,
+			7,   7,   7,   7,   7,   7,   7,   7,
+			7,   7,   7,   7,   7,   7,   7,   7,
+			7,   7,   7,   7,   7,   7,   7,   7,
+			7,   7,   7,   7,   7,   7,   7,   7,
+			7,   7,   7,   7,   7,   7,   7,   7,
+			7,   7,   7,   7,   7,   7,   7,   7,
+			7,
+		},
+		{	/* Fourth byte table 26. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   7,   14,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,
+		},
+		{	/* Fourth byte table 27. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   7,   7,   7,   7,   7,   7,   7,
+			7,   7,   7,   7,   7,   7,   7,   7,
+			7,   7,   7,   7,   7,   7,   7,   7,
+			7,   7,   7,   7,   7,   7,   7,   7,
+			7,   7,   7,   7,   7,   7,   7,   7,
+			7,   7,   7,   7,   7,   7,   7,   7,
+			7,   7,   7,   7,   7,   7,   7,   7,
+			7,   7,   7,   7,   7,   7,   7,   7,
+			7,   7,   7,   7,   7,   7,   7,   7,
+			7,   7,   7,   7,   7,   7,   7,   7,
+			7,   7,   7,   7,   7,   7,   7,   7,
+			7,   7,   7,   7,   7,   7,   7,   7,
+			7,   7,   7,   7,   7,   7,   7,   7,
+			7,   7,   7,   7,   7,   7,   7,   7,
+			7,   7,   7,   7,   7,   7,   7,   7,
+			7,
+		},
+		{	/* Fourth byte table 28. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   7,   7,   7,   7,   7,   7,   7,
+			14,  21,  21,  28,  38,  38,  38,  38,
+			38,  38,  38,  38,  38,  38,  38,  38,
+			38,  38,  38,  38,  38,  38,  38,  38,
+			38,  38,  38,  38,  38,  38,  38,  38,
+			38,  38,  38,  38,  38,  38,  38,  38,
+			38,  38,  38,  38,  38,  38,  38,  38,
+			38,  38,  38,  38,  38,  38,  38,  38,
+			38,  38,  38,  38,  38,  38,  38,  38,
+			38,  38,  38,  38,  38,  38,  38,  38,
+			38,  38,  38,  38,  38,  38,  38,  38,
+			38,  38,  38,  38,  38,  38,  38,  38,
+			38,  38,  38,  38,  38,  38,  38,  38,
+			38,  38,  38,  38,  38,  38,  38,  38,
+			38,  38,  38,  38,  38,  38,  38,  38,
+			38,  38,  38,  38,  38,  38,  38,  38,
+			38,
+		},
+		{	/* Fourth byte table 29. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   7,   14,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,
+		},
+		{	/* Fourth byte table 30. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   7,   7,   14,  24,  31,
+			31,  31,  31,  31,  31,  31,  31,  31,
+			31,  31,  31,  31,  31,  31,  31,  31,
+			31,  31,  31,  31,  31,  31,  31,  31,
+			31,  31,  31,  31,  31,  31,  31,  31,
+			31,  31,  31,  31,  31,  31,  31,  31,
+			31,  31,  31,  31,  31,  31,  31,  31,
+			31,  31,  31,  31,  31,  31,  31,  31,
+			31,  31,  31,  31,  31,  31,  31,  31,
+			31,  31,  31,  31,  31,  31,  31,  31,
+			31,  31,  31,  31,  31,  31,  31,  31,
+			31,  31,  31,  31,  31,  31,  31,  31,
+			31,  31,  31,  31,  31,  31,  31,  31,
+			31,
+		},
+		{	/* Fourth byte table 31. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   6,   6,   6,   6,
+			6,   6,   6,   6,   6,   6,   6,   6,
+			6,   6,   6,   6,   6,   6,   6,   6,
+			6,   6,   6,   6,   6,   6,   6,   6,
+			6,   6,   6,   6,   6,   6,   6,   6,
+			6,   6,   6,   6,   6,   6,   6,   6,
+			6,   6,   6,   6,   6,   6,   6,   6,
+			6,   6,   6,   6,   6,   6,   6,   6,
+			6,   6,   6,   6,   6,   6,   6,   6,
+			6,   6,   6,   6,   6,   6,   6,   6,
+			6,
+		},
+		{	/* Fourth byte table 32. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   6,   6,   6,   6,
+			6,   6,   6,   6,   6,   6,   6,   6,
+			6,   6,   6,   6,   6,   6,   6,   6,
+			6,   6,   6,   6,   6,   6,   6,   6,
+			6,   6,   6,   6,   6,   6,   6,   6,
+			6,   6,   6,   6,   6,   6,   6,   6,
+			6,   6,   6,   6,   6,   6,   6,   6,
+			6,   6,   6,   6,   6,   6,   6,   6,
+			6,   6,   6,   6,   6,   6,   6,   6,
+			6,   6,   6,   6,   6,   6,   6,   6,
+			6,
+		},
+		{	/* Fourth byte table 33. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   6,   12,  12,
+			12,  12,  12,  12,  12,  12,  12,  12,
+			12,  12,  12,  12,  12,  12,  12,  12,
+			12,  12,  12,  12,  12,  12,  12,  12,
+			12,  12,  12,  12,  12,  12,  12,  12,
+			12,  12,  12,  12,  12,  12,  12,  12,
+			12,  12,  12,  12,  12,  12,  12,  12,
+			12,  12,  12,  12,  12,  12,  12,  12,
+			12,  12,  12,  12,  12,  12,  12,  12,
+			12,  12,  12,  12,  12,  12,  12,  12,
+			12,  12,  12,  12,  12,  12,  12,  12,
+			12,  12,  12,  12,  12,  12,  12,  12,
+			12,  12,  12,  12,  12,  12,  12,  12,
+			12,
+		},
+		{	/* Fourth byte table 34. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   3,   3,   3,
+			3,   3,   3,   3,   3,   3,   3,   3,
+			3,   3,   3,   3,   3,   3,   3,   3,
+			3,   3,   3,   3,   3,   3,   3,   3,
+			3,   3,   3,   3,   3,   3,   3,   3,
+			3,   3,   3,   3,   3,   3,   3,   3,
+			3,   3,   3,   3,   3,   3,   3,   3,
+			3,   3,   3,   3,   3,   3,   3,   3,
+			3,   3,   3,   3,   3,   3,   3,   3,
+			3,   3,   3,   3,   3,   3,   3,   3,
+			3,   3,   3,   3,   3,   3,   3,   3,
+			3,   3,   3,   3,   3,   3,   3,   3,
+			3,   3,   3,   3,   3,   3,   3,   3,
+			3,   3,   3,   3,   3,   3,   3,   3,
+			3,   3,   3,   3,   3,   3,   3,   3,
+			3,
+		},
+		{	/* Fourth byte table 35. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   7,   7,   7,   7,
+			7,   7,   7,   7,   7,   7,   14,  14,
+			14,  14,  14,  21,  21,  21,  21,  21,
+			28,  28,  28,  28,  28,  35,  35,  35,
+			35,  35,  35,  35,  35,  35,  35,  35,
+			35,  35,  42,  42,  42,  42,  42,  42,
+			42,  42,  42,  42,  49,  49,  56,  63,
+			72,  79,  88,  88,  88,  88,  88,  88,
+			88,  88,  88,  88,  88,  88,  88,  88,
+			88,  88,  88,  88,  88,  88,  88,  88,
+			88,  88,  88,  88,  88,  88,  88,  88,
+			88,  88,  88,  88,  88,  88,  88,  88,
+			88,  88,  88,  88,  88,  88,  88,  88,
+			88,  88,  88,  88,  88,  88,  88,  88,
+			88,  88,  88,  88,  88,  88,  88,  88,
+			88,  88,  88,  88,  88,  88,  88,  88,
+			88,
+		},
+		{	/* Fourth byte table 36. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   7,   7,   7,   7,   7,   7,
+			7,   7,   7,   7,   7,   7,   7,   7,
+			7,   7,   7,   7,   14,  14,  14,  14,
+			14,  14,  14,  14,  14,  14,  21,  21,
+			21,  21,  21,  28,  28,  28,  28,  28,
+			35,  35,  35,  35,  35,  42,  42,  42,
+			42,  42,  42,  42,  42,  42,  42,  42,
+			42,  42,  49,  49,  49,  49,  49,  49,
+			49,  49,  49,  49,  49,  49,  49,  49,
+			49,  49,  49,  49,  49,  49,  49,  49,
+			49,  49,  49,  49,  49,  49,  49,  49,
+			49,  49,  49,  49,  49,  49,  49,  49,
+			49,  49,  49,  49,  49,  49,  49,  49,
+			49,  49,  49,  49,  49,  49,  49,  49,
+			49,  49,  49,  49,  49,  49,  49,  49,
+			49,  49,  49,  49,  49,  49,  49,  49,
+			49,
+		},
+		{	/* Fourth byte table 37. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   7,
+			7,   7,   7,   7,   7,   7,   7,   7,
+			7,   7,   7,   7,   7,   7,   7,   7,
+			7,   7,   7,   7,   7,   7,   7,   7,
+			7,   7,   7,   7,   7,   7,   7,   7,
+			7,   7,   7,   7,   7,   7,   7,   7,
+			7,   7,   7,   7,   7,   7,   7,   7,
+			7,   7,   7,   7,   7,   7,   7,   7,
+			7,   7,   7,   7,   7,   7,   7,   7,
+			7,   7,   7,   7,   7,   7,   7,   7,
+			7,   7,   7,   7,   7,   7,   7,   7,
+			7,   7,   7,   7,   7,   7,   7,   7,
+			7,
+		},
+		{	/* Fourth byte table 38. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   6,   12,  13,  14,  15,  16,  17,
+			18,  19,  20,  21,  21,  21,  21,  21,
+			21,  21,  24,  24,  24,  24,  24,  24,
+			27,  27,  27,  27,  27,  27,  27,  27,
+			27,  27,  27,  27,  27,  28,  30,  33,
+			33,  33,  33,  33,  33,  33,  33,  33,
+			34,  34,  34,  34,  40,  49,  49,  55,
+			64,  64,  64,  64,  64,  66,  66,  69,
+			69,  69,  69,  69,  69,  69,  69,  69,
+			69,  69,  69,  69,  69,  69,  69,  69,
+			69,  69,  69,  69,  69,  69,  69,  69,
+			69,  69,  69,  69,  69,  69,  69,  69,
+			69,  69,  69,  69,  69,  69,  69,  69,
+			69,  69,  69,  69,  69,  69,  69,  69,
+			69,  69,  69,  69,  69,  69,  69,  69,
+			69,  69,  69,  69,  69,  69,  69,  69,
+			69,
+		},
+		{	/* Fourth byte table 39. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			2,   4,   6,   6,   6,   6,   6,   6,
+			6,   6,   6,   6,   6,   6,   6,   6,
+			18,  18,  18,  18,  18,  18,  18,  18,
+			19,  19,  19,  19,  19,  19,  19,  19,
+			19,  19,  19,  19,  19,  19,  19,  19,
+			19,  20,  21,  21,  21,  22,  23,  24,
+			25,  26,  27,  28,  31,  32,  33,  34,
+			35,  35,  35,  35,  35,  35,  35,  35,
+			35,  35,  35,  35,  35,  35,  35,  35,
+			35,  35,  35,  35,  35,  35,  35,  35,
+			35,  35,  35,  35,  35,  35,  35,  35,
+			35,  35,  35,  35,  35,  35,  35,  35,
+			35,  35,  35,  35,  35,  35,  35,  35,
+			35,  35,  35,  35,  35,  35,  35,  35,
+			35,  35,  35,  35,  35,  35,  35,  35,
+			35,
+		},
+		{	/* Fourth byte table 40. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   1,   2,   3,   4,   5,   6,   7,
+			8,   9,   10,  11,  14,  15,  16,  17,
+			17,  17,  17,  17,  17,  17,  17,  17,
+			17,  17,  17,  17,  17,  17,  17,  17,
+			17,  17,  17,  17,  17,  17,  17,  17,
+			17,  19,  19,  19,  19,  19,  19,  19,
+			19,  19,  19,  19,  19,  19,  19,  19,
+			19,  19,  19,  19,  19,  19,  19,  19,
+			19,  19,  19,  19,  19,  19,  19,  19,
+			19,  19,  19,  19,  19,  19,  19,  19,
+			19,  19,  19,  19,  19,  19,  19,  19,
+			19,  19,  19,  19,  19,  19,  19,  19,
+			19,  19,  19,  19,  19,  19,  19,  19,
+			19,  19,  19,  19,  19,  19,  19,  19,
+			19,  19,  19,  19,  19,  19,  19,  19,
+			19,  19,  19,  19,  19,  19,  19,  19,
+			19,
+		},
+		{	/* Fourth byte table 41. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   3,   6,   7,   10,  10,  13,  16,
+			18,  18,  21,  22,  23,  24,  25,  26,
+			28,  29,  30,  31,  32,  32,  33,  35,
+			35,  35,  36,  37,  38,  39,  40,  40,
+			40,  42,  45,  47,  47,  48,  48,  51,
+			51,  52,  52,  54,  58,  59,  60,  60,
+			61,  62,  63,  63,  64,  65,  67,  69,
+			71,  73,  74,  74,  74,  74,  76,  78,
+			80,  80,  80,  80,  80,  80,  80,  80,
+			80,  80,  80,  80,  80,  80,  80,  80,
+			80,  80,  80,  80,  80,  80,  80,  80,
+			80,  80,  80,  80,  80,  80,  80,  80,
+			80,  80,  80,  80,  80,  80,  80,  80,
+			80,  80,  80,  80,  80,  80,  80,  80,
+			80,  80,  80,  80,  80,  80,  80,  80,
+			80,  80,  80,  80,  80,  80,  80,  80,
+			80,
+		},
+		{	/* Fourth byte table 42. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   3,   3,   3,   3,   3,   4,   5,
+			6,   7,   8,   8,   8,   8,   8,   8,
+			8,   8,   8,   8,   13,  18,  23,  28,
+			33,  38,  43,  48,  53,  58,  63,  68,
+			72,  73,  75,  78,  80,  81,  83,  86,
+			90,  92,  93,  95,  98,  99,  100, 101,
+			102, 103, 105, 108, 110, 111, 113, 116,
+			120, 122, 123, 125, 128, 129, 130, 131,
+			132, 132, 132, 132, 132, 132, 132, 132,
+			132, 132, 132, 132, 132, 132, 132, 132,
+			132, 132, 132, 132, 132, 132, 132, 132,
+			132, 132, 132, 132, 132, 132, 132, 132,
+			132, 132, 132, 132, 132, 132, 132, 132,
+			132, 132, 132, 132, 132, 132, 132, 132,
+			132, 132, 132, 132, 132, 132, 132, 132,
+			132, 132, 132, 132, 132, 132, 132, 132,
+			132,
+		},
+		{	/* Fourth byte table 43. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   6,   12,  12,  12,  12,
+			12,  12,  12,  12,  12,  12,  12,  12,
+			12,  12,  12,  12,  12,  12,  12,  18,
+			18,  18,  18,  18,  18,  18,  18,  18,
+			18,  18,  18,  18,  18,  18,  18,  18,
+			18,  18,  18,  18,  18,  18,  18,  18,
+			18,  18,  18,  18,  18,  18,  18,  18,
+			18,  18,  18,  18,  18,  18,  18,  18,
+			18,  18,  18,  18,  18,  18,  18,  18,
+			18,  18,  18,  18,  18,  18,  18,  18,
+			18,  18,  18,  18,  18,  18,  18,  18,
+			18,  18,  18,  18,  18,  18,  18,  18,
+			18,  18,  18,  18,  18,  18,  18,  18,
+			18,
+		},
+		{	/* Fourth byte table 44. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   6,   12,
+			18,  18,  18,  18,  18,  18,  18,  18,
+			18,  18,  18,  18,  18,  18,  18,  18,
+			18,  18,  18,  18,  18,  18,  18,  18,
+			18,  18,  18,  18,  18,  18,  18,  18,
+			18,  18,  18,  18,  18,  18,  18,  18,
+			18,  18,  18,  18,  18,  18,  18,  18,
+			18,  18,  18,  18,  18,  18,  18,  18,
+			18,  18,  18,  18,  18,  18,  18,  18,
+			18,  18,  18,  18,  18,  18,  18,  18,
+			18,  18,  18,  18,  18,  18,  18,  18,
+			18,  18,  18,  18,  18,  18,  18,  18,
+			18,  18,  18,  18,  18,  18,  18,  18,
+			18,  18,  18,  18,  18,  18,  18,  18,
+			18,  18,  18,  18,  18,  18,  18,  18,
+			18,
+		},
+		{	/* Fourth byte table 45. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   6,   6,   6,
+			6,   6,   12,  12,  12,  18,  18,  18,
+			18,  18,  18,  18,  18,  18,  18,  18,
+			18,  18,  18,  18,  18,  18,  18,  18,
+			18,  18,  18,  18,  18,  24,  24,  30,
+			30,  30,  30,  30,  30,  36,  45,  45,
+			51,  60,  60,  60,  60,  60,  60,  60,
+			60,  60,  60,  60,  60,  60,  60,  60,
+			60,  60,  60,  60,  60,  60,  60,  60,
+			60,  60,  60,  60,  60,  60,  60,  60,
+			60,  60,  60,  60,  60,  60,  60,  60,
+			60,  60,  60,  60,  60,  60,  60,  60,
+			60,  60,  60,  60,  60,  60,  60,  60,
+			60,  60,  60,  60,  60,  60,  60,  60,
+			60,  60,  60,  60,  60,  60,  60,  60,
+			60,  60,  60,  60,  60,  60,  60,  60,
+			60,
+		},
+		{	/* Fourth byte table 46. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   6,   6,   6,   12,  12,  12,
+			18,  18,  24,  24,  24,  24,  24,  24,
+			24,  24,  24,  24,  24,  24,  24,  24,
+			24,  24,  24,  24,  24,  24,  24,  24,
+			24,  28,  28,  34,  34,  34,  34,  34,
+			34,  34,  34,  34,  34,  34,  40,  44,
+			48,  54,  60,  60,  60,  66,  72,  72,
+			72,  78,  84,  84,  84,  84,  84,  84,
+			84,  84,  84,  84,  84,  84,  84,  84,
+			84,  84,  84,  84,  84,  84,  84,  84,
+			84,  84,  84,  84,  84,  84,  84,  84,
+			84,  84,  84,  84,  84,  84,  84,  84,
+			84,  84,  84,  84,  84,  84,  84,  84,
+			84,  84,  84,  84,  84,  84,  84,  84,
+			84,  84,  84,  84,  84,  84,  84,  84,
+			84,  84,  84,  84,  84,  84,  84,  84,
+			84,
+		},
+		{	/* Fourth byte table 47. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   6,   12,  12,  12,  18,  24,  24,
+			24,  30,  36,  36,  36,  36,  36,  36,
+			36,  36,  36,  36,  36,  36,  36,  36,
+			36,  36,  36,  36,  36,  36,  36,  36,
+			36,  36,  36,  36,  36,  36,  36,  36,
+			36,  36,  36,  36,  36,  42,  48,  54,
+			60,  60,  60,  60,  60,  60,  60,  60,
+			60,  60,  60,  60,  60,  60,  60,  60,
+			60,  60,  60,  60,  60,  60,  60,  60,
+			60,  60,  60,  60,  60,  60,  60,  60,
+			60,  60,  60,  60,  60,  60,  60,  60,
+			60,  60,  60,  60,  60,  60,  60,  60,
+			60,  60,  60,  60,  60,  60,  60,  60,
+			60,  60,  60,  60,  60,  60,  60,  60,
+			60,  60,  60,  60,  60,  60,  60,  60,
+			60,  60,  60,  60,  60,  60,  60,  60,
+			60,
+		},
+		{	/* Fourth byte table 48. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   6,   12,  18,  24,  24,  24,  24,
+			24,  24,  24,  30,  36,  42,  48,  48,
+			48,  48,  48,  48,  48,  48,  48,  48,
+			48,  48,  48,  48,  48,  48,  48,  48,
+			48,  48,  48,  48,  48,  48,  48,  48,
+			48,  48,  48,  48,  48,  48,  48,  48,
+			48,  48,  48,  48,  48,  48,  48,  48,
+			48,  48,  48,  48,  48,  48,  48,  48,
+			48,  48,  48,  48,  48,  48,  48,  48,
+			48,  48,  48,  48,  48,  48,  48,  48,
+			48,  48,  48,  48,  48,  48,  48,  48,
+			48,  48,  48,  48,  48,  48,  48,  48,
+			48,
+		},
+		{	/* Fourth byte table 49. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   4,   8,   8,   8,   8,   8,
+			8,   8,   8,   8,   8,   8,   8,   8,
+			8,   8,   8,   8,   8,   8,   8,   8,
+			8,   8,   8,   8,   8,   8,   8,   8,
+			8,   8,   8,   8,   8,   8,   8,   8,
+			8,   8,   8,   8,   8,   8,   8,   8,
+			8,   8,   8,   8,   8,   8,   8,   8,
+			8,   8,   8,   8,   8,   8,   8,   8,
+			8,   8,   8,   8,   8,   8,   8,   8,
+			8,   8,   8,   8,   8,   8,   8,   8,
+			8,   8,   8,   8,   8,   8,   8,   8,
+			8,
+		},
+		{	/* Fourth byte table 50. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   1,   2,   3,   4,   5,   6,   7,
+			8,   9,   11,  13,  15,  17,  19,  21,
+			23,  25,  27,  29,  31,  34,  37,  40,
+			43,  46,  49,  52,  55,  58,  62,  66,
+			70,  70,  70,  70,  70,  70,  70,  70,
+			70,  70,  70,  70,  70,  70,  70,  70,
+			70,  70,  70,  70,  70,  70,  70,  70,
+			70,  70,  70,  70,  70,  70,  70,  70,
+			70,  70,  70,  70,  70,  70,  70,  70,
+			70,  70,  70,  70,  70,  70,  70,  70,
+			70,  70,  70,  70,  70,  70,  70,  70,
+			70,  70,  70,  70,  70,  70,  70,  70,
+			70,
+		},
+		{	/* Fourth byte table 51. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   4,   8,   12,  16,  20,  24,  28,
+			32,  34,  36,  38,  40,  42,  44,  46,
+			48,  50,  53,  56,  59,  62,  65,  68,
+			71,  74,  77,  80,  83,  86,  89,  92,
+			95,  98,  101, 104, 107, 110, 113, 116,
+			119, 122, 125, 128, 131, 134, 137, 140,
+			143, 146, 149, 152, 155, 158, 161, 162,
+			163, 164, 165, 166, 167, 168, 169, 170,
+			171, 171, 171, 171, 171, 171, 171, 171,
+			171, 171, 171, 171, 171, 171, 171, 171,
+			171, 171, 171, 171, 171, 171, 171, 171,
+			171, 171, 171, 171, 171, 171, 171, 171,
+			171, 171, 171, 171, 171, 171, 171, 171,
+			171, 171, 171, 171, 171, 171, 171, 171,
+			171, 171, 171, 171, 171, 171, 171, 171,
+			171, 171, 171, 171, 171, 171, 171, 171,
+			171,
+		},
+		{	/* Fourth byte table 52. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   1,   2,   3,   4,   5,   6,   7,
+			8,   9,   10,  11,  12,  13,  14,  15,
+			16,  17,  18,  19,  20,  21,  22,  23,
+			24,  25,  26,  27,  28,  29,  30,  31,
+			32,  33,  34,  35,  36,  37,  38,  39,
+			40,  41,  42,  43,  43,  43,  43,  43,
+			43,  43,  43,  43,  43,  43,  43,  43,
+			43,  43,  43,  43,  43,  43,  43,  43,
+			43,  43,  43,  43,  43,  43,  43,  43,
+			43,  43,  43,  43,  43,  43,  43,  43,
+			43,  43,  43,  43,  43,  43,  43,  43,
+			43,  43,  43,  43,  43,  43,  43,  43,
+			43,  43,  43,  43,  43,  43,  43,  43,
+			43,  43,  43,  43,  43,  43,  43,  43,
+			43,  43,  43,  43,  43,  43,  43,  43,
+			43,  43,  43,  43,  43,  43,  43,  43,
+			43,
+		},
+		{	/* Fourth byte table 53. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   12,  12,  12,
+			12,  12,  12,  12,  12,  12,  12,  12,
+			12,  12,  12,  12,  12,  12,  12,  12,
+			12,  12,  12,  12,  12,  12,  12,  12,
+			12,  12,  12,  12,  12,  12,  12,  12,
+			12,  12,  12,  12,  12,  12,  12,  12,
+			12,  12,  12,  12,  12,  12,  12,  12,
+			12,  12,  12,  12,  12,  12,  12,  12,
+			12,  12,  12,  12,  12,  12,  12,  12,
+			12,  12,  12,  12,  12,  12,  12,  12,
+			12,  12,  12,  12,  12,  12,  12,  12,
+			12,  12,  12,  12,  12,  12,  12,  12,
+			12,  12,  12,  12,  12,  12,  12,  12,
+			12,  12,  12,  12,  12,  12,  12,  12,
+			12,  12,  12,  12,  12,  12,  12,  12,
+			12,
+		},
+		{	/* Fourth byte table 54. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   3,   5,   8,
+			8,   8,   8,   8,   8,   8,   8,   8,
+			8,   8,   8,   8,   8,   8,   8,   8,
+			8,   8,   8,   8,   8,   8,   8,   8,
+			8,   8,   8,   8,   8,   8,   8,   8,
+			8,   8,   8,   8,   8,   8,   8,   8,
+			8,   8,   8,   8,   8,   8,   8,   8,
+			8,   8,   8,   8,   8,   8,   8,   8,
+			8,   8,   8,   8,   8,   8,   8,   8,
+			8,   8,   8,   8,   8,   8,   8,   8,
+			8,
+		},
+		{	/* Fourth byte table 55. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   6,   6,   6,
+			6,   6,   6,   6,   6,   6,   6,   6,
+			6,   6,   6,   6,   6,   6,   6,   6,
+			6,   6,   6,   6,   6,   6,   6,   6,
+			6,   6,   6,   6,   6,   6,   6,   6,
+			6,   6,   6,   6,   6,   6,   6,   6,
+			6,   6,   6,   6,   6,   6,   6,   6,
+			6,   6,   6,   6,   6,   6,   6,   6,
+			6,   6,   6,   6,   6,   6,   6,   6,
+			6,   6,   6,   6,   6,   6,   6,   6,
+			6,   6,   6,   6,   6,   6,   6,   6,
+			6,   6,   6,   6,   6,   6,   6,   6,
+			6,   6,   6,   6,   6,   6,   6,   6,
+			6,
+		},
+		{	/* Fourth byte table 56. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			3,   3,   3,   3,   3,   3,   3,   3,
+			3,   3,   3,   3,   3,   3,   3,   3,
+			3,   3,   3,   3,   3,   3,   3,   3,
+			3,   3,   3,   3,   3,   3,   3,   3,
+			3,   3,   3,   3,   3,   3,   3,   3,
+			3,   3,   3,   3,   3,   3,   3,   3,
+			3,   3,   3,   3,   3,   3,   3,   3,
+			3,   3,   3,   3,   3,   3,   3,   3,
+			3,   3,   3,   3,   3,   3,   3,   3,
+			3,   3,   3,   3,   3,   3,   3,   3,
+			3,   3,   3,   3,   3,   3,   3,   3,
+			3,   3,   3,   3,   3,   3,   3,   3,
+			3,
+		},
+		{	/* Fourth byte table 57. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   3,   3,   3,   3,
+			3,   3,   3,   3,   3,   3,   3,   3,
+			3,   3,   3,   3,   3,   3,   3,   3,
+			3,   3,   3,   3,   3,   3,   3,   3,
+			3,   3,   3,   3,   3,   3,   3,   3,
+			3,   3,   3,   3,   3,   3,   3,   3,
+			3,   3,   3,   3,   3,   3,   3,   3,
+			3,   3,   3,   3,   3,   3,   3,   3,
+			3,   3,   3,   3,   3,   3,   3,   3,
+			3,   3,   3,   3,   3,   3,   3,   3,
+			3,
+		},
+		{	/* Fourth byte table 58. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   3,   6,   9,   12,  15,  18,  21,
+			24,  27,  30,  33,  36,  39,  42,  45,
+			48,  51,  54,  57,  60,  63,  66,  69,
+			72,  75,  78,  81,  84,  87,  90,  93,
+			96,  99,  102, 105, 108, 111, 114, 117,
+			120, 123, 126, 129, 132, 135, 138, 141,
+			144, 147, 150, 153, 156, 159, 162, 165,
+			168, 171, 174, 177, 180, 183, 186, 189,
+			192, 192, 192, 192, 192, 192, 192, 192,
+			192, 192, 192, 192, 192, 192, 192, 192,
+			192, 192, 192, 192, 192, 192, 192, 192,
+			192, 192, 192, 192, 192, 192, 192, 192,
+			192, 192, 192, 192, 192, 192, 192, 192,
+			192, 192, 192, 192, 192, 192, 192, 192,
+			192, 192, 192, 192, 192, 192, 192, 192,
+			192, 192, 192, 192, 192, 192, 192, 192,
+			192,
+		},
+		{	/* Fourth byte table 59. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   3,   6,   9,   12,  15,  18,  21,
+			24,  27,  30,  33,  36,  39,  42,  45,
+			48,  51,  54,  57,  60,  63,  66,  69,
+			72,  75,  78,  81,  84,  87,  90,  93,
+			96,  99,  102, 105, 108, 111, 114, 117,
+			120, 123, 126, 129, 132, 135, 138, 141,
+			144, 147, 150, 153, 156, 159, 162, 165,
+			168, 171, 174, 177, 180, 183, 186, 189,
+			192, 192, 192, 192, 192, 192, 192, 192,
+			192, 192, 192, 192, 192, 192, 192, 192,
+			192, 192, 192, 192, 192, 192, 192, 192,
+			192, 192, 192, 192, 192, 192, 192, 192,
+			192, 192, 192, 192, 192, 192, 192, 192,
+			192, 192, 192, 192, 192, 192, 192, 192,
+			192, 192, 192, 192, 192, 192, 192, 192,
+			192, 192, 192, 192, 192, 192, 192, 192,
+			192,
+		},
+		{	/* Fourth byte table 60. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   3,   6,   9,   12,  15,  18,  21,
+			24,  27,  30,  33,  36,  39,  42,  45,
+			48,  51,  54,  57,  60,  63,  66,  69,
+			72,  75,  78,  81,  84,  87,  90,  93,
+			96,  99,  102, 105, 108, 111, 114, 117,
+			120, 123, 126, 129, 132, 135, 138, 141,
+			144, 147, 150, 153, 156, 159, 162, 165,
+			168, 171, 174, 177, 180, 183, 186, 189,
+			192, 192, 192, 192, 192, 192, 192, 192,
+			192, 192, 192, 192, 192, 192, 192, 192,
+			192, 192, 192, 192, 192, 192, 192, 192,
+			192, 192, 192, 192, 192, 192, 192, 192,
+			192, 192, 192, 192, 192, 192, 192, 192,
+			192, 192, 192, 192, 192, 192, 192, 192,
+			192, 192, 192, 192, 192, 192, 192, 192,
+			192, 192, 192, 192, 192, 192, 192, 192,
+			192,
+		},
+		{	/* Fourth byte table 61. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   3,   6,   9,   12,  15,  18,  21,
+			24,  27,  30,  33,  36,  39,  42,  45,
+			48,  51,  54,  57,  60,  63,  66,  66,
+			66,  66,  66,  66,  66,  66,  66,  66,
+			66,  66,  66,  66,  66,  66,  66,  66,
+			66,  66,  66,  66,  66,  66,  66,  66,
+			66,  66,  66,  66,  66,  66,  66,  66,
+			66,  66,  66,  66,  66,  66,  66,  66,
+			66,  66,  66,  66,  66,  66,  66,  66,
+			66,  66,  66,  66,  66,  66,  66,  66,
+			66,  66,  66,  66,  66,  66,  66,  66,
+			66,  66,  66,  66,  66,  66,  66,  66,
+			66,  66,  66,  66,  66,  66,  66,  66,
+			66,  66,  66,  66,  66,  66,  66,  66,
+			66,  66,  66,  66,  66,  66,  66,  66,
+			66,  66,  66,  66,  66,  66,  66,  66,
+			66,
+		},
+		{	/* Fourth byte table 62. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   1,   1,   1,   1,   1,   1,   1,
+			1,   1,   1,   1,   1,   1,   1,   1,
+			1,   1,   1,   1,   1,   1,   1,   1,
+			1,   1,   1,   1,   1,   1,   1,   1,
+			1,   1,   1,   1,   1,   1,   1,   1,
+			1,   1,   1,   1,   1,   1,   1,   1,
+			1,   1,   1,   1,   1,   1,   1,   4,
+			4,   7,   10,  13,  13,  13,  13,  13,
+			13,  13,  13,  13,  13,  13,  13,  13,
+			13,  13,  13,  13,  13,  13,  13,  13,
+			13,  13,  13,  13,  13,  13,  13,  13,
+			13,  13,  13,  13,  13,  13,  13,  13,
+			13,  13,  13,  13,  13,  13,  13,  13,
+			13,  13,  13,  13,  13,  13,  13,  13,
+			13,  13,  13,  13,  13,  13,  13,  13,
+			13,  13,  13,  13,  13,  13,  13,  13,
+			13,
+		},
+		{	/* Fourth byte table 63. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   7,   7,   14,
+			14,  21,  21,  28,  28,  35,  35,  42,
+			42,  49,  49,  56,  56,  63,  63,  70,
+			70,  77,  77,  84,  84,  84,  91,  91,
+			98,  98,  105, 105, 105, 105, 105, 105,
+			105, 112, 119, 119, 126, 133, 133, 140,
+			147, 147, 154, 161, 161, 168, 175, 175,
+			175, 175, 175, 175, 175, 175, 175, 175,
+			175, 175, 175, 175, 175, 175, 175, 175,
+			175, 175, 175, 175, 175, 175, 175, 175,
+			175, 175, 175, 175, 175, 175, 175, 175,
+			175, 175, 175, 175, 175, 175, 175, 175,
+			175, 175, 175, 175, 175, 175, 175, 175,
+			175, 175, 175, 175, 175, 175, 175, 175,
+			175, 175, 175, 175, 175, 175, 175, 175,
+			175,
+		},
+		{	/* Fourth byte table 64. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   7,   7,   7,
+			7,   7,   7,   7,   11,  15,  15,  22,
+			28,  28,  28,  28,  28,  28,  28,  28,
+			28,  28,  28,  28,  28,  35,  35,  42,
+			42,  49,  49,  56,  56,  63,  63,  70,
+			70,  77,  77,  84,  84,  91,  91,  98,
+			98,  98,  98,  98,  98,  98,  98,  98,
+			98,  98,  98,  98,  98,  98,  98,  98,
+			98,  98,  98,  98,  98,  98,  98,  98,
+			98,  98,  98,  98,  98,  98,  98,  98,
+			98,  98,  98,  98,  98,  98,  98,  98,
+			98,  98,  98,  98,  98,  98,  98,  98,
+			98,  98,  98,  98,  98,  98,  98,  98,
+			98,  98,  98,  98,  98,  98,  98,  98,
+			98,
+		},
+		{	/* Fourth byte table 65. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   7,   7,   14,  14,  14,  21,  21,
+			28,  28,  35,  35,  35,  35,  35,  35,
+			35,  42,  49,  49,  56,  63,  63,  70,
+			77,  77,  84,  91,  91,  98,  105, 105,
+			105, 105, 105, 105, 105, 105, 105, 105,
+			105, 105, 105, 105, 105, 105, 105, 105,
+			105, 105, 105, 105, 105, 112, 112, 112,
+			119, 126, 133, 140, 140, 140, 140, 147,
+			153, 153, 153, 153, 153, 153, 153, 153,
+			153, 153, 153, 153, 153, 153, 153, 153,
+			153, 153, 153, 153, 153, 153, 153, 153,
+			153, 153, 153, 153, 153, 153, 153, 153,
+			153, 153, 153, 153, 153, 153, 153, 153,
+			153, 153, 153, 153, 153, 153, 153, 153,
+			153, 153, 153, 153, 153, 153, 153, 153,
+			153, 153, 153, 153, 153, 153, 153, 153,
+			153,
+		},
+		{	/* Fourth byte table 66. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   3,   6,   9,   12,  15,  18,
+			21,  24,  27,  30,  33,  36,  39,  42,
+			45,  45,  45,  45,  45,  45,  45,  45,
+			45,  45,  45,  45,  45,  45,  45,  45,
+			45,  45,  45,  45,  45,  45,  45,  45,
+			45,  45,  45,  45,  45,  45,  45,  45,
+			45,  45,  45,  45,  45,  45,  45,  45,
+			45,  45,  45,  45,  45,  45,  45,  45,
+			45,  45,  45,  45,  45,  45,  45,  45,
+			45,  45,  45,  45,  45,  45,  45,  45,
+			45,
+		},
+		{	/* Fourth byte table 67. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   3,   6,   9,   12,  15,  18,  21,
+			24,  27,  30,  33,  36,  39,  42,  45,
+			48,  51,  54,  57,  60,  63,  66,  69,
+			72,  75,  78,  81,  84,  87,  90,  93,
+			96,  99,  102, 105, 108, 111, 114, 117,
+			120, 123, 126, 129, 132, 135, 138, 141,
+			144, 147, 150, 153, 156, 159, 162, 165,
+			168, 171, 174, 177, 180, 183, 186, 189,
+			192, 192, 192, 192, 192, 192, 192, 192,
+			192, 192, 192, 192, 192, 192, 192, 192,
+			192, 192, 192, 192, 192, 192, 192, 192,
+			192, 192, 192, 192, 192, 192, 192, 192,
+			192, 192, 192, 192, 192, 192, 192, 192,
+			192, 192, 192, 192, 192, 192, 192, 192,
+			192, 192, 192, 192, 192, 192, 192, 192,
+			192, 192, 192, 192, 192, 192, 192, 192,
+			192,
+		},
+		{	/* Fourth byte table 68. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   3,   6,   9,   12,  15,  18,  21,
+			24,  27,  30,  33,  36,  39,  42,  45,
+			45,  45,  45,  48,  51,  54,  57,  60,
+			63,  66,  69,  72,  75,  78,  81,  84,
+			87,  87,  87,  87,  87,  87,  87,  87,
+			87,  87,  87,  87,  87,  87,  87,  87,
+			87,  87,  87,  87,  87,  87,  87,  87,
+			87,  87,  87,  87,  87,  87,  87,  87,
+			87,  87,  87,  87,  87,  87,  87,  87,
+			87,  87,  87,  87,  87,  87,  87,  87,
+			87,  87,  87,  87,  87,  87,  87,  87,
+			87,  87,  87,  87,  87,  87,  87,  87,
+			87,  87,  87,  87,  87,  87,  87,  87,
+			87,  87,  87,  87,  87,  87,  87,  87,
+			87,  87,  87,  87,  87,  87,  87,  87,
+			87,  87,  87,  87,  87,  87,  87,  87,
+			87,
+		},
+		{	/* Fourth byte table 69. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   5,   10,  15,  20,  20,  20,  20,
+			20,  20,  20,  20,  20,  20,  20,  20,
+			20,  20,  22,  24,  26,  28,  30,  32,
+			34,  36,  38,  40,  42,  44,  46,  48,
+			50,  53,  56,  59,  62,  65,  68,  71,
+			74,  77,  80,  83,  86,  89,  92,  98,
+			104, 110, 116, 122, 128, 134, 140, 146,
+			152, 158, 164, 170, 176, 176, 176, 176,
+			176, 176, 176, 176, 176, 176, 176, 176,
+			176, 176, 176, 176, 176, 176, 176, 176,
+			176, 176, 176, 176, 176, 176, 176, 176,
+			176, 176, 176, 176, 176, 176, 176, 176,
+			176, 176, 176, 176, 176, 176, 176, 176,
+			176, 176, 176, 176, 176, 176, 176, 176,
+			176, 176, 176, 176, 176, 176, 176, 176,
+			176, 176, 176, 176, 176, 176, 176, 176,
+			176,
+		},
+		{	/* Fourth byte table 70. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   3,   6,   9,   12,  15,  18,  21,
+			24,  27,  30,  33,  36,  39,  42,  45,
+			48,  51,  54,  57,  60,  63,  66,  69,
+			72,  75,  78,  81,  84,  87,  90,  93,
+			96,  99,  102, 105, 108, 111, 114, 117,
+			120, 123, 126, 129, 132, 135, 138, 141,
+			144, 147, 149, 151, 153, 155, 157, 159,
+			161, 163, 165, 167, 169, 171, 173, 175,
+			177, 177, 177, 177, 177, 177, 177, 177,
+			177, 177, 177, 177, 177, 177, 177, 177,
+			177, 177, 177, 177, 177, 177, 177, 177,
+			177, 177, 177, 177, 177, 177, 177, 177,
+			177, 177, 177, 177, 177, 177, 177, 177,
+			177, 177, 177, 177, 177, 177, 177, 177,
+			177, 177, 177, 177, 177, 177, 177, 177,
+			177, 177, 177, 177, 177, 177, 177, 177,
+			177,
+		},
+		{	/* Fourth byte table 71. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   4,   8,   12,  16,  20,  24,  28,
+			32,  36,  41,  46,  51,  51,  51,  51,
+			51,  54,  57,  60,  63,  66,  69,  72,
+			75,  78,  81,  84,  87,  90,  93,  96,
+			99,  102, 105, 108, 111, 114, 117, 120,
+			123, 126, 129, 132, 135, 138, 141, 144,
+			147, 150, 153, 156, 159, 162, 165, 168,
+			171, 174, 177, 180, 183, 186, 189, 192,
+			192, 192, 192, 192, 192, 192, 192, 192,
+			192, 192, 192, 192, 192, 192, 192, 192,
+			192, 192, 192, 192, 192, 192, 192, 192,
+			192, 192, 192, 192, 192, 192, 192, 192,
+			192, 192, 192, 192, 192, 192, 192, 192,
+			192, 192, 192, 192, 192, 192, 192, 192,
+			192, 192, 192, 192, 192, 192, 192, 192,
+			192, 192, 192, 192, 192, 192, 192, 192,
+			192,
+		},
+		{	/* Fourth byte table 72. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   2,   4,   7,   9,   11,  13,  15,
+			17,  20,  24,  26,  28,  31,  34,  36,
+			38,  40,  43,  46,  49,  52,  55,  57,
+			59,  61,  63,  65,  68,  70,  72,  74,
+			77,  80,  82,  85,  88,  91,  93,  96,
+			101, 107, 109, 112, 115, 118, 121, 128,
+			136, 138, 140, 143, 145, 147, 149, 152,
+			154, 156, 158, 160, 162, 165, 167, 169,
+			171, 171, 171, 171, 171, 171, 171, 171,
+			171, 171, 171, 171, 171, 171, 171, 171,
+			171, 171, 171, 171, 171, 171, 171, 171,
+			171, 171, 171, 171, 171, 171, 171, 171,
+			171, 171, 171, 171, 171, 171, 171, 171,
+			171, 171, 171, 171, 171, 171, 171, 171,
+			171, 171, 171, 171, 171, 171, 171, 171,
+			171, 171, 171, 171, 171, 171, 171, 171,
+			171,
+		},
+		{	/* Fourth byte table 73. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   3,   6,   10,  12,  14,  16,  22,
+			25,  27,  29,  31,  33,  35,  37,  39,
+			41,  43,  45,  48,  50,  52,  55,  58,
+			60,  64,  67,  69,  71,  73,  75,  75,
+			75,  79,  83,  87,  91,  95,  99,  103,
+			107, 111, 116, 121, 126, 131, 136, 141,
+			146, 151, 156, 161, 166, 171, 176, 181,
+			186, 191, 196, 201, 206, 211, 216, 221,
+			221, 221, 221, 221, 221, 221, 221, 221,
+			221, 221, 221, 221, 221, 221, 221, 221,
+			221, 221, 221, 221, 221, 221, 221, 221,
+			221, 221, 221, 221, 221, 221, 221, 221,
+			221, 221, 221, 221, 221, 221, 221, 221,
+			221, 221, 221, 221, 221, 221, 221, 221,
+			221, 221, 221, 221, 221, 221, 221, 221,
+			221, 221, 221, 221, 221, 221, 221, 221,
+			221,
+		},
+		{	/* Fourth byte table 74. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   4,   8,   12,  16,  20,  24,  28,
+			32,  36,  40,  44,  48,  52,  56,  56,
+			56,  60,  60,  64,  64,  64,  68,  72,
+			76,  80,  84,  88,  92,  96,  100, 104,
+			104, 108, 108, 112, 112, 112, 116, 120,
+			120, 120, 120, 124, 128, 132, 136, 136,
+			136, 140, 144, 148, 152, 156, 160, 164,
+			168, 172, 176, 180, 184, 188, 192, 196,
+			200, 200, 200, 200, 200, 200, 200, 200,
+			200, 200, 200, 200, 200, 200, 200, 200,
+			200, 200, 200, 200, 200, 200, 200, 200,
+			200, 200, 200, 200, 200, 200, 200, 200,
+			200, 200, 200, 200, 200, 200, 200, 200,
+			200, 200, 200, 200, 200, 200, 200, 200,
+			200, 200, 200, 200, 200, 200, 200, 200,
+			200, 200, 200, 200, 200, 200, 200, 200,
+			200,
+		},
+		{	/* Fourth byte table 75. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   4,   8,   12,  16,  20,  24,  28,
+			32,  36,  40,  44,  48,  52,  56,  60,
+			64,  68,  72,  76,  80,  84,  88,  92,
+			96,  100, 104, 108, 112, 116, 120, 124,
+			128, 132, 136, 140, 144, 148, 152, 156,
+			160, 164, 168, 172, 172, 172, 172, 172,
+			172, 172, 172, 172, 172, 172, 172, 172,
+			172, 172, 172, 172, 172, 172, 172, 172,
+			172, 172, 172, 172, 172, 172, 172, 172,
+			172, 172, 172, 172, 172, 172, 172, 172,
+			172, 172, 172, 172, 172, 172, 172, 172,
+			172, 172, 172, 172, 172, 172, 172, 172,
+			172, 172, 172, 172, 172, 172, 172, 172,
+			172, 172, 172, 172, 172, 172, 172, 172,
+			172, 172, 172, 172, 172, 172, 172, 172,
+			172, 172, 172, 172, 172, 172, 172, 172,
+			172,
+		},
+		{	/* Fourth byte table 76. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   2,   4,   6,   9,   12,  14,  16,
+			16,  16,  16,  16,  16,  16,  16,  16,
+			16,  16,  16,  16,  20,  24,  28,  32,
+			36,  36,  36,  36,  36,  36,  41,  41,
+			46,  48,  50,  52,  54,  56,  58,  60,
+			62,  64,  65,  70,  75,  82,  89,  94,
+			99,  104, 109, 114, 119, 124, 129, 134,
+			134, 139, 144, 149, 154, 159, 159, 164,
+			164, 164, 164, 164, 164, 164, 164, 164,
+			164, 164, 164, 164, 164, 164, 164, 164,
+			164, 164, 164, 164, 164, 164, 164, 164,
+			164, 164, 164, 164, 164, 164, 164, 164,
+			164, 164, 164, 164, 164, 164, 164, 164,
+			164, 164, 164, 164, 164, 164, 164, 164,
+			164, 164, 164, 164, 164, 164, 164, 164,
+			164, 164, 164, 164, 164, 164, 164, 164,
+			164,
+		},
+		{	/* Fourth byte table 77. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   5,   10,  10,  15,  20,  20,  25,
+			30,  35,  40,  45,  50,  55,  60,  65,
+			69,  71,  73,  75,  77,  79,  81,  83,
+			85,  87,  89,  91,  93,  95,  97,  99,
+			101, 103, 105, 107, 109, 111, 113, 115,
+			117, 119, 121, 123, 125, 127, 129, 131,
+			133, 135, 137, 139, 141, 143, 145, 147,
+			149, 151, 153, 155, 157, 159, 161, 163,
+			165, 165, 165, 165, 165, 165, 165, 165,
+			165, 165, 165, 165, 165, 165, 165, 165,
+			165, 165, 165, 165, 165, 165, 165, 165,
+			165, 165, 165, 165, 165, 165, 165, 165,
+			165, 165, 165, 165, 165, 165, 165, 165,
+			165, 165, 165, 165, 165, 165, 165, 165,
+			165, 165, 165, 165, 165, 165, 165, 165,
+			165, 165, 165, 165, 165, 165, 165, 165,
+			165,
+		},
+		{	/* Fourth byte table 78. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   2,   4,   6,   8,   10,  12,  14,
+			16,  18,  20,  22,  24,  26,  28,  30,
+			32,  34,  36,  38,  40,  42,  44,  46,
+			48,  50,  52,  54,  56,  58,  60,  62,
+			64,  66,  68,  70,  72,  76,  80,  82,
+			84,  86,  88,  90,  92,  94,  96,  98,
+			100, 104, 108, 108, 108, 108, 108, 108,
+			108, 108, 108, 108, 108, 108, 108, 108,
+			108, 108, 108, 108, 108, 108, 108, 108,
+			108, 108, 108, 108, 108, 108, 108, 108,
+			108, 108, 108, 108, 108, 108, 108, 108,
+			108, 108, 108, 108, 108, 108, 108, 108,
+			108, 108, 108, 108, 108, 108, 108, 108,
+			108, 108, 108, 108, 108, 108, 108, 108,
+			108, 108, 108, 108, 108, 108, 108, 108,
+			108, 108, 108, 108, 108, 108, 108, 108,
+			108,
+		},
+		{	/* Fourth byte table 79. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   2,   4,   6,   8,
+			10,  12,  14,  16,  18,  20,  24,  26,
+			28,  30,  32,  34,  36,  38,  40,  42,
+			44,  46,  48,  54,  60,  66,  72,  78,
+			84,  90,  96,  102, 108, 114, 120, 126,
+			132, 138, 144, 150, 156, 158, 160, 162,
+			164, 164, 164, 164, 164, 164, 164, 164,
+			164, 164, 164, 164, 164, 164, 164, 164,
+			164, 164, 164, 164, 164, 164, 164, 164,
+			164, 164, 164, 164, 164, 164, 164, 164,
+			164, 164, 164, 164, 164, 164, 164, 164,
+			164, 164, 164, 164, 164, 164, 164, 164,
+			164, 164, 164, 164, 164, 164, 164, 164,
+			164, 164, 164, 164, 164, 164, 164, 164,
+			164,
+		},
+		{	/* Fourth byte table 80. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   4,   8,   12,  16,  20,  24,  28,
+			32,  36,  40,  44,  48,  52,  56,  60,
+			64,  68,  72,  76,  80,  84,  88,  92,
+			96,  100, 104, 108, 112, 116, 120, 124,
+			128, 132, 136, 140, 144, 148, 152, 156,
+			160, 164, 168, 172, 176, 180, 184, 188,
+			192, 196, 200, 204, 208, 212, 216, 220,
+			224, 228, 232, 236, 240, 244, 248, 248,
+			248, 248, 248, 248, 248, 248, 248, 248,
+			248, 248, 248, 248, 248, 248, 248, 248,
+			248, 248, 248, 248, 248, 248, 248, 248,
+			248, 248, 248, 248, 248, 248, 248, 248,
+			248, 248, 248, 248, 248, 248, 248, 248,
+			248, 248, 248, 248, 248, 248, 248, 248,
+			248, 248, 248, 248, 248, 248, 248, 248,
+			248, 248, 248, 248, 248, 248, 248, 248,
+			248,
+		},
+		{	/* Fourth byte table 81. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   6,   12,  18,  24,  30,  36,  42,
+			48,  48,  48,  48,  48,  48,  48,  48,
+			48,  48,  48,  48,  48,  48,  48,  48,
+			48,  48,  48,  48,  48,  48,  48,  48,
+			48,  48,  48,  48,  48,  48,  48,  48,
+			48,  48,  48,  48,  48,  48,  48,  48,
+			48,  54,  60,  68,  76,  84,  92,  100,
+			108, 116, 122, 155, 170, 178, 178, 178,
+			178, 178, 178, 178, 178, 178, 178, 178,
+			178, 178, 178, 178, 178, 178, 178, 178,
+			178, 178, 178, 178, 178, 178, 178, 178,
+			178, 178, 178, 178, 178, 178, 178, 178,
+			178, 178, 178, 178, 178, 178, 178, 178,
+			178, 178, 178, 178, 178, 178, 178, 178,
+			178, 178, 178, 178, 178, 178, 178, 178,
+			178, 178, 178, 178, 178, 178, 178, 178,
+			178,
+		},
+		{	/* Fourth byte table 82. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   2,   5,   8,   9,   10,  11,  12,
+			13,  14,  17,  20,  23,  26,  29,  32,
+			35,  35,  35,  35,  35,  35,  35,  35,
+			35,  35,  35,  35,  35,  35,  35,  35,
+			35,  35,  35,  35,  35,  35,  35,  35,
+			35,  35,  35,  35,  35,  35,  35,  35,
+			35,  35,  35,  35,  35,  35,  35,  35,
+			35,  35,  35,  35,  35,  35,  35,  35,
+			35,  35,  35,  35,  35,  35,  35,  35,
+			35,  35,  35,  35,  35,  35,  35,  35,
+			35,
+		},
+		{	/* Fourth byte table 83. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   3,   6,   9,   12,  15,  15,  15,
+			15,  15,  18,  21,  24,  27,  28,  29,
+			30,  31,  34,  35,  35,  36,  37,  38,
+			39,  42,  43,  44,  45,  46,  49,  52,
+			53,  54,  55,  56,  57,  58,  59,  60,
+			60,  61,  62,  63,  64,  64,  64,  64,
+			64,  67,  71,  74,  74,  77,  77,  80,
+			84,  87,  91,  94,  98,  101, 105, 108,
+			112, 112, 112, 112, 112, 112, 112, 112,
+			112, 112, 112, 112, 112, 112, 112, 112,
+			112, 112, 112, 112, 112, 112, 112, 112,
+			112, 112, 112, 112, 112, 112, 112, 112,
+			112, 112, 112, 112, 112, 112, 112, 112,
+			112, 112, 112, 112, 112, 112, 112, 112,
+			112, 112, 112, 112, 112, 112, 112, 112,
+			112, 112, 112, 112, 112, 112, 112, 112,
+			112,
+		},
+		{	/* Fourth byte table 84. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   2,   6,   10,  14,  18,  22,  26,
+			30,  34,  38,  42,  46,  50,  52,  54,
+			56,  58,  60,  62,  64,  66,  68,  70,
+			72,  74,  76,  78,  80,  82,  84,  86,
+			88,  90,  92,  94,  96,  98,  100, 102,
+			104, 106, 108, 110, 112, 114, 116, 118,
+			120, 122, 124, 126, 128, 130, 132, 134,
+			136, 138, 140, 142, 144, 146, 148, 150,
+			152, 152, 152, 152, 152, 152, 152, 152,
+			152, 152, 152, 152, 152, 152, 152, 152,
+			152, 152, 152, 152, 152, 152, 152, 152,
+			152, 152, 152, 152, 152, 152, 152, 152,
+			152, 152, 152, 152, 152, 152, 152, 152,
+			152, 152, 152, 152, 152, 152, 152, 152,
+			152, 152, 152, 152, 152, 152, 152, 152,
+			152, 152, 152, 152, 152, 152, 152, 152,
+			152,
+		},
+		{	/* Fourth byte table 85. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   2,   4,   6,   8,   10,  12,  14,
+			16,  18,  20,  22,  24,  26,  28,  30,
+			32,  34,  36,  38,  40,  42,  44,  46,
+			48,  50,  52,  54,  56,  58,  60,  62,
+			64,  66,  68,  70,  72,  74,  76,  78,
+			80,  82,  84,  86,  88,  90,  92,  94,
+			96,  98,  100, 102, 104, 106, 112, 118,
+			124, 130, 136, 142, 146, 150, 150, 150,
+			150, 150, 150, 150, 150, 150, 150, 150,
+			150, 150, 150, 150, 150, 150, 150, 150,
+			150, 150, 150, 150, 150, 150, 150, 150,
+			150, 150, 150, 150, 150, 150, 150, 150,
+			150, 150, 150, 150, 150, 150, 150, 150,
+			150, 150, 150, 150, 150, 150, 150, 150,
+			150, 150, 150, 150, 150, 150, 150, 150,
+			150, 150, 150, 150, 150, 150, 150, 150,
+			150,
+		},
+		{	/* Fourth byte table 86. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   1,   2,   3,   4,   5,   6,
+			7,   8,   9,   10,  11,  12,  13,  14,
+			15,  16,  17,  18,  19,  20,  21,  22,
+			23,  24,  25,  26,  27,  28,  29,  30,
+			31,  32,  33,  34,  35,  36,  37,  38,
+			39,  40,  41,  42,  43,  44,  45,  46,
+			47,  48,  49,  50,  51,  52,  53,  54,
+			55,  56,  57,  58,  59,  60,  61,  62,
+			63,  63,  63,  63,  63,  63,  63,  63,
+			63,  63,  63,  63,  63,  63,  63,  63,
+			63,  63,  63,  63,  63,  63,  63,  63,
+			63,  63,  63,  63,  63,  63,  63,  63,
+			63,  63,  63,  63,  63,  63,  63,  63,
+			63,  63,  63,  63,  63,  63,  63,  63,
+			63,  63,  63,  63,  63,  63,  63,  63,
+			63,  63,  63,  63,  63,  63,  63,  63,
+			63,
+		},
+		{	/* Fourth byte table 87. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   1,   2,   3,   4,   5,   6,   7,
+			8,   9,   10,  11,  12,  13,  14,  15,
+			16,  17,  18,  19,  20,  21,  22,  23,
+			24,  25,  26,  27,  28,  29,  30,  31,
+			34,  37,  40,  43,  46,  49,  52,  55,
+			58,  61,  64,  67,  70,  73,  76,  79,
+			82,  85,  88,  91,  94,  97,  100, 103,
+			106, 109, 112, 115, 118, 121, 124, 127,
+			130, 130, 130, 130, 130, 130, 130, 130,
+			130, 130, 130, 130, 130, 130, 130, 130,
+			130, 130, 130, 130, 130, 130, 130, 130,
+			130, 130, 130, 130, 130, 130, 130, 130,
+			130, 130, 130, 130, 130, 130, 130, 130,
+			130, 130, 130, 130, 130, 130, 130, 130,
+			130, 130, 130, 130, 130, 130, 130, 130,
+			130, 130, 130, 130, 130, 130, 130, 130,
+			130,
+		},
+		{	/* Fourth byte table 88. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   3,   6,   9,   12,  15,  18,  21,
+			24,  27,  30,  33,  36,  39,  42,  45,
+			48,  51,  54,  57,  60,  63,  66,  69,
+			72,  75,  78,  81,  84,  87,  90,  93,
+			96,  99,  102, 105, 108, 111, 114, 117,
+			120, 123, 126, 129, 132, 135, 138, 141,
+			144, 147, 150, 153, 156, 159, 162, 165,
+			168, 171, 174, 177, 180, 183, 186, 189,
+			189, 189, 189, 189, 189, 189, 189, 189,
+			189, 189, 189, 189, 189, 189, 189, 189,
+			189, 189, 189, 189, 189, 189, 189, 189,
+			189, 189, 189, 189, 189, 189, 189, 189,
+			189, 189, 189, 189, 189, 189, 189, 189,
+			189, 189, 189, 189, 189, 189, 189, 189,
+			189, 189, 189, 189, 189, 189, 189, 189,
+			189, 189, 189, 189, 189, 189, 189, 189,
+			189,
+		},
+		{	/* Fourth byte table 89. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   3,   6,   9,   12,  15,
+			18,  18,  18,  21,  24,  27,  30,  33,
+			36,  36,  36,  39,  42,  45,  48,  51,
+			54,  54,  54,  57,  60,  63,  63,  63,
+			63,  65,  67,  69,  72,  74,  76,  79,
+			79,  82,  85,  88,  91,  94,  97,  100,
+			100, 100, 100, 100, 100, 100, 100, 100,
+			100, 100, 100, 100, 100, 100, 100, 100,
+			100, 100, 100, 100, 100, 100, 100, 100,
+			100, 100, 100, 100, 100, 100, 100, 100,
+			100, 100, 100, 100, 100, 100, 100, 100,
+			100, 100, 100, 100, 100, 100, 100, 100,
+			100, 100, 100, 100, 100, 100, 100, 100,
+			100, 100, 100, 100, 100, 100, 100, 100,
+			100, 100, 100, 100, 100, 100, 100, 100,
+			100, 100, 100, 100, 100, 100, 100, 100,
+			100,
+		},
+		{	/* Fourth byte table 90. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   9,
+			18,  31,  44,  57,  70,  83,  83,  83,
+			83,  83,  83,  83,  83,  83,  83,  83,
+			83,  83,  83,  83,  83,  83,  83,  83,
+			83,  83,  83,  83,  83,  83,  83,  83,
+			83,  83,  83,  83,  83,  83,  83,  83,
+			83,  83,  83,  83,  83,  83,  83,  83,
+			83,  83,  83,  83,  83,  83,  83,  83,
+			83,  83,  83,  83,  83,  83,  83,  83,
+			83,  83,  83,  83,  83,  83,  83,  83,
+			83,  83,  83,  83,  83,  83,  83,  83,
+			83,  83,  83,  83,  83,  83,  83,  83,
+			83,  83,  83,  83,  83,  83,  83,  83,
+			83,
+		},
+		{	/* Fourth byte table 91. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   9,   18,  31,  44,
+			57,  57,  57,  57,  57,  57,  57,  57,
+			57,  57,  57,  57,  57,  57,  57,  57,
+			57,  57,  57,  57,  57,  57,  57,  57,
+			57,  57,  57,  57,  57,  57,  57,  57,
+			57,  57,  57,  57,  57,  57,  57,  57,
+			57,  57,  57,  57,  57,  57,  57,  57,
+			57,  57,  57,  57,  57,  57,  57,  57,
+			57,  57,  57,  57,  57,  57,  57,  57,
+			57,
+		},
+		{	/* Fourth byte table 92. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   13,  13,  13,  13,  13,  13,  13,
+			13,  13,  13,  13,  13,  13,  13,  13,
+			13,  13,  13,  13,  13,  13,  13,  13,
+			13,  13,  13,  13,  13,  13,  13,  13,
+			13,  13,  13,  13,  13,  13,  13,  13,
+			13,  13,  13,  13,  13,  13,  13,  13,
+			13,  13,  13,  13,  13,  13,  13,  13,
+			13,  13,  13,  13,  13,  13,  13,  13,
+			13,  13,  13,  13,  13,  13,  13,  13,
+			13,  13,  13,  13,  13,  13,  13,  13,
+			13,  13,  13,  13,  13,  13,  13,  13,
+			13,  13,  13,  13,  13,  13,  13,  13,
+			13,  13,  13,  13,  13,  13,  13,  13,
+			13,  13,  13,  13,  13,  13,  13,  13,
+			13,  13,  13,  13,  13,  13,  13,  13,
+			13,  13,  13,  13,  13,  13,  13,  13,
+			13,
+		},
+		{	/* Fourth byte table 93. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   1,   2,   3,   4,   5,   6,   7,
+			8,   9,   10,  11,  12,  13,  14,  15,
+			16,  17,  18,  19,  20,  21,  22,  23,
+			24,  25,  26,  27,  28,  29,  30,  31,
+			32,  33,  34,  35,  36,  37,  38,  39,
+			40,  41,  42,  43,  44,  45,  46,  47,
+			48,  49,  50,  51,  52,  53,  54,  55,
+			56,  57,  58,  59,  60,  61,  62,  63,
+			64,  64,  64,  64,  64,  64,  64,  64,
+			64,  64,  64,  64,  64,  64,  64,  64,
+			64,  64,  64,  64,  64,  64,  64,  64,
+			64,  64,  64,  64,  64,  64,  64,  64,
+			64,  64,  64,  64,  64,  64,  64,  64,
+			64,  64,  64,  64,  64,  64,  64,  64,
+			64,  64,  64,  64,  64,  64,  64,  64,
+			64,  64,  64,  64,  64,  64,  64,  64,
+			64,
+		},
+		{	/* Fourth byte table 94. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   1,   2,   3,   4,   5,   6,   7,
+			8,   9,   10,  11,  12,  13,  14,  15,
+			16,  17,  18,  19,  20,  21,  21,  22,
+			23,  24,  25,  26,  27,  28,  29,  30,
+			31,  32,  33,  34,  35,  36,  37,  38,
+			39,  40,  41,  42,  43,  44,  45,  46,
+			47,  48,  49,  50,  51,  52,  53,  54,
+			55,  56,  57,  58,  59,  60,  61,  62,
+			63,  63,  63,  63,  63,  63,  63,  63,
+			63,  63,  63,  63,  63,  63,  63,  63,
+			63,  63,  63,  63,  63,  63,  63,  63,
+			63,  63,  63,  63,  63,  63,  63,  63,
+			63,  63,  63,  63,  63,  63,  63,  63,
+			63,  63,  63,  63,  63,  63,  63,  63,
+			63,  63,  63,  63,  63,  63,  63,  63,
+			63,  63,  63,  63,  63,  63,  63,  63,
+			63,
+		},
+		{	/* Fourth byte table 95. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   1,   2,   3,   4,   5,   6,   7,
+			8,   9,   10,  11,  12,  13,  14,  15,
+			16,  17,  18,  19,  20,  21,  22,  23,
+			24,  25,  26,  27,  28,  29,  29,  30,
+			31,  31,  31,  32,  32,  32,  33,  34,
+			34,  34,  35,  36,  37,  38,  38,  39,
+			40,  41,  42,  43,  44,  45,  46,  47,
+			48,  49,  50,  50,  51,  51,  52,  53,
+			54,  54,  54,  54,  54,  54,  54,  54,
+			54,  54,  54,  54,  54,  54,  54,  54,
+			54,  54,  54,  54,  54,  54,  54,  54,
+			54,  54,  54,  54,  54,  54,  54,  54,
+			54,  54,  54,  54,  54,  54,  54,  54,
+			54,  54,  54,  54,  54,  54,  54,  54,
+			54,  54,  54,  54,  54,  54,  54,  54,
+			54,  54,  54,  54,  54,  54,  54,  54,
+			54,
+		},
+		{	/* Fourth byte table 96. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   1,   1,   2,   3,   3,   4,   5,
+			6,   7,   8,   9,   10,  11,  12,  13,
+			14,  15,  16,  17,  18,  19,  20,  21,
+			22,  23,  24,  25,  26,  27,  28,  29,
+			30,  31,  32,  33,  34,  35,  36,  37,
+			38,  39,  40,  41,  42,  43,  44,  45,
+			46,  47,  48,  49,  50,  51,  52,  53,
+			54,  55,  56,  57,  58,  59,  60,  61,
+			62,  62,  62,  62,  62,  62,  62,  62,
+			62,  62,  62,  62,  62,  62,  62,  62,
+			62,  62,  62,  62,  62,  62,  62,  62,
+			62,  62,  62,  62,  62,  62,  62,  62,
+			62,  62,  62,  62,  62,  62,  62,  62,
+			62,  62,  62,  62,  62,  62,  62,  62,
+			62,  62,  62,  62,  62,  62,  62,  62,
+			62,  62,  62,  62,  62,  62,  62,  62,
+			62,
+		},
+		{	/* Fourth byte table 97. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   1,   2,   3,   4,   5,   6,   6,
+			7,   8,   9,   10,  10,  10,  11,  12,
+			13,  14,  15,  16,  17,  18,  18,  19,
+			20,  21,  22,  23,  24,  25,  25,  26,
+			27,  28,  29,  30,  31,  32,  33,  34,
+			35,  36,  37,  38,  39,  40,  41,  42,
+			43,  44,  45,  46,  47,  48,  49,  50,
+			51,  52,  53,  53,  54,  55,  56,  57,
+			57,  57,  57,  57,  57,  57,  57,  57,
+			57,  57,  57,  57,  57,  57,  57,  57,
+			57,  57,  57,  57,  57,  57,  57,  57,
+			57,  57,  57,  57,  57,  57,  57,  57,
+			57,  57,  57,  57,  57,  57,  57,  57,
+			57,  57,  57,  57,  57,  57,  57,  57,
+			57,  57,  57,  57,  57,  57,  57,  57,
+			57,  57,  57,  57,  57,  57,  57,  57,
+			57,
+		},
+		{	/* Fourth byte table 98. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   1,   2,   3,   4,   5,   5,   6,
+			6,   6,   6,   7,   8,   9,   10,  11,
+			12,  13,  13,  14,  15,  16,  17,  18,
+			19,  20,  21,  22,  23,  24,  25,  26,
+			27,  28,  29,  30,  31,  32,  33,  34,
+			35,  36,  37,  38,  39,  40,  41,  42,
+			43,  44,  45,  46,  47,  48,  49,  50,
+			51,  52,  53,  54,  55,  56,  57,  58,
+			59,  59,  59,  59,  59,  59,  59,  59,
+			59,  59,  59,  59,  59,  59,  59,  59,
+			59,  59,  59,  59,  59,  59,  59,  59,
+			59,  59,  59,  59,  59,  59,  59,  59,
+			59,  59,  59,  59,  59,  59,  59,  59,
+			59,  59,  59,  59,  59,  59,  59,  59,
+			59,  59,  59,  59,  59,  59,  59,  59,
+			59,  59,  59,  59,  59,  59,  59,  59,
+			59,
+		},
+		{	/* Fourth byte table 99. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   1,   2,   3,   4,   5,   6,   7,
+			8,   9,   10,  11,  12,  13,  14,  15,
+			16,  17,  18,  19,  20,  21,  22,  23,
+			24,  25,  26,  27,  28,  29,  30,  31,
+			32,  33,  34,  35,  36,  37,  38,  39,
+			40,  41,  42,  43,  44,  45,  46,  47,
+			48,  49,  50,  51,  52,  53,  54,  55,
+			56,  57,  58,  59,  60,  61,  62,  63,
+			64,  64,  64,  64,  64,  64,  64,  64,
+			64,  64,  64,  64,  64,  64,  64,  64,
+			64,  64,  64,  64,  64,  64,  64,  64,
+			64,  64,  64,  64,  64,  64,  64,  64,
+			64,  64,  64,  64,  64,  64,  64,  64,
+			64,  64,  64,  64,  64,  64,  64,  64,
+			64,  64,  64,  64,  64,  64,  64,  64,
+			64,  64,  64,  64,  64,  64,  64,  64,
+			64,
+		},
+		{	/* Fourth byte table 100. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   1,   2,   3,   4,   5,   6,   7,
+			8,   9,   10,  11,  12,  13,  14,  15,
+			16,  17,  18,  19,  20,  21,  22,  23,
+			24,  25,  26,  27,  28,  29,  30,  31,
+			32,  33,  34,  35,  36,  37,  38,  39,
+			40,  41,  42,  43,  44,  45,  46,  47,
+			48,  49,  50,  51,  52,  53,  54,  55,
+			56,  57,  58,  59,  60,  61,  62,  63,
+			64,  64,  64,  64,  64,  64,  64,  64,
+			64,  64,  64,  64,  64,  64,  64,  64,
+			64,  64,  64,  64,  64,  64,  64,  64,
+			64,  64,  64,  64,  64,  64,  64,  64,
+			64,  64,  64,  64,  64,  64,  64,  64,
+			64,  64,  64,  64,  64,  64,  64,  64,
+			64,  64,  64,  64,  64,  64,  64,  64,
+			64,  64,  64,  64,  64,  64,  64,  64,
+			64,
+		},
+		{	/* Fourth byte table 101. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   1,   2,   3,   4,   5,   6,   7,
+			8,   9,   10,  11,  12,  13,  14,  15,
+			16,  17,  18,  19,  20,  21,  22,  23,
+			24,  25,  26,  27,  28,  29,  30,  31,
+			32,  33,  34,  35,  36,  37,  38,  39,
+			40,  41,  42,  43,  44,  45,  46,  47,
+			48,  49,  50,  51,  52,  53,  54,  55,
+			56,  57,  58,  59,  60,  61,  62,  63,
+			64,  64,  64,  64,  64,  64,  64,  64,
+			64,  64,  64,  64,  64,  64,  64,  64,
+			64,  64,  64,  64,  64,  64,  64,  64,
+			64,  64,  64,  64,  64,  64,  64,  64,
+			64,  64,  64,  64,  64,  64,  64,  64,
+			64,  64,  64,  64,  64,  64,  64,  64,
+			64,  64,  64,  64,  64,  64,  64,  64,
+			64,  64,  64,  64,  64,  64,  64,  64,
+			64,
+		},
+		{	/* Fourth byte table 102. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   1,   2,   3,   4,   5,   6,   7,
+			8,   9,   10,  11,  12,  13,  14,  15,
+			16,  17,  18,  19,  20,  21,  22,  23,
+			24,  25,  26,  27,  28,  29,  30,  31,
+			32,  33,  34,  35,  36,  37,  38,  39,
+			40,  41,  42,  43,  44,  45,  46,  47,
+			48,  49,  50,  51,  52,  53,  54,  55,
+			56,  57,  58,  59,  60,  61,  62,  63,
+			64,  64,  64,  64,  64,  64,  64,  64,
+			64,  64,  64,  64,  64,  64,  64,  64,
+			64,  64,  64,  64,  64,  64,  64,  64,
+			64,  64,  64,  64,  64,  64,  64,  64,
+			64,  64,  64,  64,  64,  64,  64,  64,
+			64,  64,  64,  64,  64,  64,  64,  64,
+			64,  64,  64,  64,  64,  64,  64,  64,
+			64,  64,  64,  64,  64,  64,  64,  64,
+			64,
+		},
+		{	/* Fourth byte table 103. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   1,   2,   3,   4,   5,   6,   7,
+			8,   9,   10,  11,  12,  13,  14,  15,
+			16,  17,  18,  19,  20,  21,  22,  23,
+			24,  25,  26,  27,  28,  29,  30,  31,
+			32,  33,  34,  35,  36,  36,  36,  36,
+			36,  38,  40,  42,  44,  46,  48,  50,
+			52,  54,  56,  58,  60,  62,  64,  66,
+			68,  70,  72,  74,  76,  78,  80,  82,
+			84,  84,  84,  84,  84,  84,  84,  84,
+			84,  84,  84,  84,  84,  84,  84,  84,
+			84,  84,  84,  84,  84,  84,  84,  84,
+			84,  84,  84,  84,  84,  84,  84,  84,
+			84,  84,  84,  84,  84,  84,  84,  84,
+			84,  84,  84,  84,  84,  84,  84,  84,
+			84,  84,  84,  84,  84,  84,  84,  84,
+			84,  84,  84,  84,  84,  84,  84,  84,
+			84,
+		},
+		{	/* Fourth byte table 104. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   2,   5,   7,   9,   11,  13,  15,
+			17,  19,  21,  23,  25,  27,  29,  31,
+			33,  35,  37,  39,  41,  43,  45,  47,
+			49,  51,  53,  55,  58,  60,  62,  64,
+			66,  68,  70,  72,  74,  76,  78,  80,
+			82,  84,  86,  88,  90,  92,  94,  96,
+			98,  100, 102, 104, 106, 108, 110, 112,
+			114, 116, 118, 120, 123, 125, 127, 129,
+			131, 131, 131, 131, 131, 131, 131, 131,
+			131, 131, 131, 131, 131, 131, 131, 131,
+			131, 131, 131, 131, 131, 131, 131, 131,
+			131, 131, 131, 131, 131, 131, 131, 131,
+			131, 131, 131, 131, 131, 131, 131, 131,
+			131, 131, 131, 131, 131, 131, 131, 131,
+			131, 131, 131, 131, 131, 131, 131, 131,
+			131, 131, 131, 131, 131, 131, 131, 131,
+			131,
+		},
+		{	/* Fourth byte table 105. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   2,   4,   6,   8,   10,  12,  14,
+			16,  18,  20,  22,  24,  26,  28,  30,
+			32,  34,  36,  38,  40,  42,  45,  47,
+			49,  51,  53,  55,  57,  59,  61,  63,
+			65,  67,  69,  71,  73,  75,  77,  79,
+			81,  83,  85,  87,  89,  91,  93,  95,
+			97,  99,  101, 103, 105, 107, 110, 112,
+			114, 116, 118, 120, 122, 124, 126, 128,
+			130, 130, 130, 130, 130, 130, 130, 130,
+			130, 130, 130, 130, 130, 130, 130, 130,
+			130, 130, 130, 130, 130, 130, 130, 130,
+			130, 130, 130, 130, 130, 130, 130, 130,
+			130, 130, 130, 130, 130, 130, 130, 130,
+			130, 130, 130, 130, 130, 130, 130, 130,
+			130, 130, 130, 130, 130, 130, 130, 130,
+			130, 130, 130, 130, 130, 130, 130, 130,
+			130,
+		},
+		{	/* Fourth byte table 106. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   2,   4,   6,   8,   10,  12,  14,
+			16,  18,  20,  22,  24,  26,  28,  30,
+			33,  35,  37,  39,  41,  43,  45,  47,
+			49,  51,  53,  55,  57,  59,  61,  63,
+			65,  67,  69,  71,  73,  75,  77,  79,
+			81,  83,  85,  87,  89,  91,  93,  95,
+			98,  100, 102, 104, 106, 108, 110, 112,
+			114, 116, 118, 120, 122, 124, 126, 128,
+			130, 130, 130, 130, 130, 130, 130, 130,
+			130, 130, 130, 130, 130, 130, 130, 130,
+			130, 130, 130, 130, 130, 130, 130, 130,
+			130, 130, 130, 130, 130, 130, 130, 130,
+			130, 130, 130, 130, 130, 130, 130, 130,
+			130, 130, 130, 130, 130, 130, 130, 130,
+			130, 130, 130, 130, 130, 130, 130, 130,
+			130, 130, 130, 130, 130, 130, 130, 130,
+			130,
+		},
+		{	/* Fourth byte table 107. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   2,   4,   6,   8,   10,  12,  14,
+			16,  18,  21,  23,  25,  27,  29,  31,
+			33,  35,  37,  39,  41,  43,  45,  47,
+			49,  51,  53,  55,  57,  59,  61,  63,
+			65,  67,  69,  71,  73,  75,  77,  79,
+			81,  83,  86,  88,  90,  92,  94,  96,
+			98,  100, 102, 104, 106, 108, 110, 112,
+			114, 116, 118, 120, 122, 124, 126, 128,
+			130, 130, 130, 130, 130, 130, 130, 130,
+			130, 130, 130, 130, 130, 130, 130, 130,
+			130, 130, 130, 130, 130, 130, 130, 130,
+			130, 130, 130, 130, 130, 130, 130, 130,
+			130, 130, 130, 130, 130, 130, 130, 130,
+			130, 130, 130, 130, 130, 130, 130, 130,
+			130, 130, 130, 130, 130, 130, 130, 130,
+			130, 130, 130, 130, 130, 130, 130, 130,
+			130,
+		},
+		{	/* Fourth byte table 108. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   2,   4,   6,   9,   11,  13,  15,
+			17,  19,  21,  21,  21,  21,  21,  22,
+			23,  24,  25,  26,  27,  28,  29,  30,
+			31,  32,  33,  34,  35,  36,  37,  38,
+			39,  40,  41,  42,  43,  44,  45,  46,
+			47,  48,  49,  50,  51,  52,  53,  54,
+			55,  56,  57,  58,  59,  60,  61,  62,
+			63,  64,  65,  66,  67,  68,  69,  70,
+			71,  71,  71,  71,  71,  71,  71,  71,
+			71,  71,  71,  71,  71,  71,  71,  71,
+			71,  71,  71,  71,  71,  71,  71,  71,
+			71,  71,  71,  71,  71,  71,  71,  71,
+			71,  71,  71,  71,  71,  71,  71,  71,
+			71,  71,  71,  71,  71,  71,  71,  71,
+			71,  71,  71,  71,  71,  71,  71,  71,
+			71,  71,  71,  71,  71,  71,  71,  71,
+			71,
+		},
+		{	/* Fourth byte table 109. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   4,   9,   13,  17,  21,  25,  29,
+			33,  37,  42,  46,  50,  54,  58,  62,
+			66,  71,  75,  80,  85,  90,  94,  98,
+			102, 106, 110, 114, 118, 122, 127, 127,
+			127, 127, 127, 127, 127, 127, 127, 127,
+			127, 127, 127, 127, 127, 127, 127, 127,
+			127, 127, 127, 127, 127, 127, 127, 127,
+			127, 127, 127, 127, 127, 127, 127, 127,
+			127, 127, 127, 127, 127, 127, 127, 127,
+			127, 127, 127, 127, 127, 127, 127, 127,
+			127, 127, 127, 127, 127, 127, 127, 127,
+			127, 127, 127, 127, 127, 127, 127, 127,
+			127, 127, 127, 127, 127, 127, 127, 127,
+			127, 127, 127, 127, 127, 127, 127, 127,
+			127, 127, 127, 127, 127, 127, 127, 127,
+			127, 127, 127, 127, 127, 127, 127, 127,
+			127,
+		},
+		{	/* Fourth byte table 110. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,
+		},
+		{	/* Fourth byte table 111. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,
+		},
+		{	/* Fourth byte table 112. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,
+		},
+		{	/* Fourth byte table 113. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,
+		},
+		{	/* Fourth byte table 114. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,
+		},
+		{	/* Fourth byte table 115. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,
+		},
+		{	/* Fourth byte table 116. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,
+		},
+		{	/* Fourth byte table 117. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,
+		},
+	},
+	{
+		{	/* Fourth byte table 0. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   1,   1,   1,   1,   1,   1,   1,
+			1,   4,   4,   5,   5,   5,   5,   5,
+			8,   8,   8,   9,   10,  13,  15,  15,
+			15,  18,  19,  20,  20,  25,  30,  35,
+			35,  35,  35,  35,  35,  35,  35,  35,
+			35,  35,  35,  35,  35,  35,  35,  35,
+			35,  35,  35,  35,  35,  35,  35,  35,
+			35,  35,  35,  35,  35,  35,  35,  35,
+			35,  35,  35,  35,  35,  35,  35,  35,
+			35,  35,  35,  35,  35,  35,  35,  35,
+			35,  35,  35,  35,  35,  35,  35,  35,
+			35,  35,  35,  35,  35,  35,  35,  35,
+			35,
+		},
+		{	/* Fourth byte table 1. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   4,   8,   12,  16,  20,  24,  24,
+			28,  32,  36,  40,  44,  48,  52,  56,
+			60,  60,  64,  68,  72,  76,  80,  84,
+			84,  84,  88,  92,  96,  100, 104, 104,
+			104, 108, 112, 116, 120, 124, 128, 128,
+			132, 136, 140, 144, 148, 152, 156, 160,
+			164, 164, 168, 172, 176, 180, 184, 188,
+			188, 188, 192, 196, 200, 204, 208, 208,
+			212, 212, 212, 212, 212, 212, 212, 212,
+			212, 212, 212, 212, 212, 212, 212, 212,
+			212, 212, 212, 212, 212, 212, 212, 212,
+			212, 212, 212, 212, 212, 212, 212, 212,
+			212, 212, 212, 212, 212, 212, 212, 212,
+			212, 212, 212, 212, 212, 212, 212, 212,
+			212, 212, 212, 212, 212, 212, 212, 212,
+			212, 212, 212, 212, 212, 212, 212, 212,
+			212,
+		},
+		{	/* Fourth byte table 2. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   4,   8,   12,  16,  20,  24,  28,
+			32,  36,  40,  44,  48,  52,  56,  60,
+			64,  64,  64,  68,  72,  76,  80,  84,
+			88,  92,  96,  100, 104, 108, 112, 116,
+			120, 124, 128, 132, 136, 140, 144, 144,
+			144, 148, 152, 156, 160, 164, 168, 172,
+			176, 180, 180, 182, 184, 188, 192, 196,
+			200, 200, 204, 208, 212, 216, 220, 224,
+			227, 227, 227, 227, 227, 227, 227, 227,
+			227, 227, 227, 227, 227, 227, 227, 227,
+			227, 227, 227, 227, 227, 227, 227, 227,
+			227, 227, 227, 227, 227, 227, 227, 227,
+			227, 227, 227, 227, 227, 227, 227, 227,
+			227, 227, 227, 227, 227, 227, 227, 227,
+			227, 227, 227, 227, 227, 227, 227, 227,
+			227, 227, 227, 227, 227, 227, 227, 227,
+			227,
+		},
+		{	/* Fourth byte table 3. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   3,   3,   3,   7,   11,  15,  19,
+			23,  27,  30,  30,  30,  34,  38,  42,
+			46,  50,  54,  54,  54,  58,  62,  66,
+			70,  74,  78,  82,  86,  90,  94,  98,
+			102, 106, 110, 114, 118, 122, 126, 126,
+			126, 130, 134, 138, 142, 146, 150, 154,
+			158, 162, 166, 170, 174, 178, 182, 186,
+			190, 194, 198, 202, 206, 210, 214, 218,
+			219, 219, 219, 219, 219, 219, 219, 219,
+			219, 219, 219, 219, 219, 219, 219, 219,
+			219, 219, 219, 219, 219, 219, 219, 219,
+			219, 219, 219, 219, 219, 219, 219, 219,
+			219, 219, 219, 219, 219, 219, 219, 219,
+			219, 219, 219, 219, 219, 219, 219, 219,
+			219, 219, 219, 219, 219, 219, 219, 219,
+			219, 219, 219, 219, 219, 219, 219, 219,
+			219,
+		},
+		{	/* Fourth byte table 4. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   4,   8,   8,   8,   8,   8,   8,
+			8,   8,   8,   8,   8,   8,   8,   8,
+			12,  16,  16,  16,  16,  16,  16,  16,
+			16,  16,  16,  16,  16,  16,  16,  16,
+			16,  16,  16,  16,  16,  16,  16,  16,
+			16,  16,  16,  16,  16,  16,  16,  16,
+			16,  16,  16,  16,  16,  16,  16,  16,
+			16,  16,  16,  16,  16,  16,  16,  16,
+			16,  16,  16,  16,  16,  16,  16,  16,
+			16,  16,  16,  16,  16,  16,  16,  16,
+			16,  16,  16,  16,  16,  16,  16,  16,
+			16,  16,  16,  16,  16,  16,  16,  16,
+			16,
+		},
+		{	/* Fourth byte table 5. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   4,   8,   12,
+			14,  16,  18,  20,  22,  24,  28,  32,
+			36,  40,  44,  48,  52,  56,  62,  68,
+			74,  80,  86,  92,  98,  104, 104, 110,
+			116, 122, 128, 133, 138, 138, 138, 142,
+			146, 150, 154, 158, 162, 168, 174, 179,
+			184, 188, 190, 192, 194, 198, 202, 202,
+			202, 206, 210, 216, 222, 227, 232, 237,
+			242, 242, 242, 242, 242, 242, 242, 242,
+			242, 242, 242, 242, 242, 242, 242, 242,
+			242, 242, 242, 242, 242, 242, 242, 242,
+			242, 242, 242, 242, 242, 242, 242, 242,
+			242, 242, 242, 242, 242, 242, 242, 242,
+			242, 242, 242, 242, 242, 242, 242, 242,
+			242, 242, 242, 242, 242, 242, 242, 242,
+			242, 242, 242, 242, 242, 242, 242, 242,
+			242,
+		},
+		{	/* Fourth byte table 6. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   4,   8,   12,  16,  20,  24,  28,
+			32,  36,  40,  44,  48,  52,  56,  60,
+			64,  68,  72,  76,  80,  84,  88,  92,
+			96,  100, 104, 108, 112, 112, 112, 116,
+			120, 120, 120, 120, 120, 120, 120, 124,
+			128, 132, 136, 142, 148, 154, 160, 164,
+			168, 174, 180, 184, 188, 188, 188, 188,
+			188, 188, 188, 188, 188, 188, 188, 188,
+			188, 188, 188, 188, 188, 188, 188, 188,
+			188, 188, 188, 188, 188, 188, 188, 188,
+			188, 188, 188, 188, 188, 188, 188, 188,
+			188, 188, 188, 188, 188, 188, 188, 188,
+			188, 188, 188, 188, 188, 188, 188, 188,
+			188, 188, 188, 188, 188, 188, 188, 188,
+			188, 188, 188, 188, 188, 188, 188, 188,
+			188, 188, 188, 188, 188, 188, 188, 188,
+			188,
+		},
+		{	/* Fourth byte table 7. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   1,   3,   4,   5,   7,   9,   11,
+			12,  13,  13,  13,  13,  13,  13,  13,
+			13,  13,  13,  13,  13,  13,  13,  13,
+			13,  13,  13,  13,  13,  13,  13,  13,
+			13,  13,  13,  13,  13,  13,  13,  13,
+			13,  13,  13,  13,  13,  13,  13,  13,
+			13,  13,  13,  13,  13,  13,  13,  13,
+			13,  13,  13,  13,  13,  13,  13,  13,
+			13,  13,  13,  13,  13,  13,  13,  13,
+			13,  13,  13,  13,  13,  13,  13,  13,
+			13,
+		},
+		{	/* Fourth byte table 8. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   3,   6,   9,   12,  15,  18,  18,
+			18,  20,  21,  22,  23,  25,  25,  25,
+			25,  25,  25,  25,  25,  25,  25,  25,
+			25,  25,  25,  25,  25,  25,  25,  25,
+			25,  25,  25,  25,  25,  25,  25,  25,
+			25,  25,  25,  25,  25,  25,  25,  25,
+			25,  25,  25,  25,  25,  25,  25,  25,
+			25,  25,  25,  25,  25,  25,  25,  25,
+			25,  25,  25,  25,  25,  25,  25,  25,
+			25,  25,  25,  25,  25,  25,  25,  25,
+			25,  25,  25,  25,  25,  25,  25,  25,
+			25,  25,  25,  25,  25,  25,  25,  25,
+			25,  25,  25,  25,  25,  25,  25,  25,
+			25,
+		},
+		{	/* Fourth byte table 9. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   3,   6,   6,   9,   14,  14,  14,
+			14,  14,  14,  14,  14,  14,  14,  14,
+			14,  14,  14,  14,  14,  14,  14,  14,
+			14,  14,  14,  14,  14,  14,  14,  14,
+			14,  14,  14,  14,  14,  14,  14,  14,
+			14,  14,  14,  14,  14,  14,  14,  14,
+			14,  14,  14,  14,  14,  17,  17,  17,
+			17,  17,  17,  20,  20,  20,  20,  22,
+			22,  22,  22,  22,  22,  22,  22,  22,
+			22,  22,  22,  22,  22,  22,  22,  22,
+			22,  22,  22,  22,  22,  22,  22,  22,
+			22,  22,  22,  22,  22,  22,  22,  22,
+			22,  22,  22,  22,  22,  22,  22,  22,
+			22,  22,  22,  22,  22,  22,  22,  22,
+			22,  22,  22,  22,  22,  22,  22,  22,
+			22,  22,  22,  22,  22,  22,  22,  22,
+			22,
+		},
+		{	/* Fourth byte table 10. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   3,   14,  19,
+			22,  27,  32,  37,  37,  42,  42,  47,
+			52,  59,  59,  59,  59,  59,  59,  59,
+			59,  59,  59,  59,  59,  59,  59,  59,
+			59,  59,  59,  59,  59,  59,  59,  59,
+			59,  59,  59,  64,  69,  74,  79,  84,
+			89,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,
+		},
+		{	/* Fourth byte table 11. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   5,   10,  15,  20,  25,
+			25,  27,  29,  31,  41,  51,  53,  55,
+			55,  55,  55,  55,  55,  55,  55,  55,
+			55,  55,  55,  55,  55,  55,  55,  55,
+			55,  55,  55,  55,  55,  55,  55,  55,
+			55,  57,  59,  61,  61,  63,  65,  65,
+			65,  65,  67,  67,  67,  67,  67,  67,
+			67,  67,  67,  67,  67,  67,  67,  67,
+			67,  67,  67,  67,  67,  67,  67,  67,
+			67,  67,  67,  67,  67,  67,  67,  67,
+			67,  67,  67,  67,  67,  67,  67,  67,
+			67,  67,  67,  67,  67,  67,  67,  67,
+			67,  67,  67,  67,  67,  67,  67,  67,
+			67,  67,  67,  67,  67,  67,  67,  67,
+			67,  67,  67,  67,  67,  67,  67,  67,
+			67,
+		},
+		{	/* Fourth byte table 12. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   5,   10,  10,  15,  15,  15,  15,
+			20,  20,  20,  20,  20,  25,  30,  35,
+			35,  35,  35,  35,  35,  35,  35,  35,
+			35,  35,  40,  40,  40,  40,  40,  40,
+			40,  40,  40,  40,  40,  40,  40,  40,
+			40,  40,  40,  40,  40,  40,  40,  40,
+			40,  40,  40,  40,  40,  40,  40,  40,
+			40,  40,  45,  45,  45,  45,  45,  45,
+			45,  45,  45,  45,  45,  45,  45,  45,
+			45,  45,  45,  45,  45,  45,  45,  45,
+			45,  45,  45,  45,  45,  45,  45,  45,
+			45,  45,  45,  45,  45,  45,  45,  45,
+			45,  45,  45,  45,  45,  45,  45,  45,
+			45,  45,  45,  45,  45,  45,  45,  45,
+			45,  45,  45,  45,  45,  45,  45,  45,
+			45,  45,  45,  45,  45,  45,  45,  45,
+			45,
+		},
+		{	/* Fourth byte table 13. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   5,   10,  10,  15,  15,  15,  15,
+			20,  20,  20,  20,  20,  25,  30,  35,
+			35,  35,  35,  35,  35,  35,  35,  35,
+			35,  35,  35,  35,  35,  35,  35,  35,
+			35,  35,  35,  35,  35,  35,  35,  40,
+			45,  45,  45,  45,  45,  45,  45,  45,
+			45,  45,  45,  45,  45,  45,  45,  45,
+			45,  45,  45,  45,  45,  45,  45,  45,
+			45,  45,  45,  45,  45,  45,  45,  45,
+			45,  45,  45,  45,  45,  45,  45,  45,
+			45,  45,  45,  45,  45,  45,  45,  45,
+			45,  45,  45,  45,  45,  45,  45,  45,
+			45,  45,  45,  45,  45,  45,  45,  45,
+			45,  45,  45,  45,  45,  45,  45,  45,
+			45,
+		},
+		{	/* Fourth byte table 14. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   5,   10,  10,  10,  10,  10,
+			10,  10,  10,  10,  10,  10,  10,  10,
+			10,  15,  20,  25,  30,  30,  30,  35,
+			40,  40,  40,  45,  50,  55,  60,  65,
+			70,  70,  70,  75,  80,  85,  90,  95,
+			100, 100, 100, 105, 110, 115, 120, 125,
+			130, 135, 140, 145, 150, 155, 160, 160,
+			160, 165, 170, 170, 170, 170, 170, 170,
+			170, 170, 170, 170, 170, 170, 170, 170,
+			170, 170, 170, 170, 170, 170, 170, 170,
+			170, 170, 170, 170, 170, 170, 170, 170,
+			170, 170, 170, 170, 170, 170, 170, 170,
+			170, 170, 170, 170, 170, 170, 170, 170,
+			170, 170, 170, 170, 170, 170, 170, 170,
+			170, 170, 170, 170, 170, 170, 170, 170,
+			170, 170, 170, 170, 170, 170, 170, 170,
+			170,
+		},
+		{	/* Fourth byte table 15. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			4,   4,   4,   4,   4,   4,   4,   4,
+			4,   4,   4,   4,   4,   4,   4,   4,
+			4,   4,   4,   4,   4,   4,   4,   4,
+			4,   4,   4,   4,   4,   4,   4,   4,
+			4,   4,   4,   4,   4,   4,   4,   4,
+			4,   4,   4,   4,   4,   4,   4,   4,
+			4,   4,   4,   4,   4,   4,   4,   4,
+			4,   4,   4,   4,   4,   4,   4,   4,
+			4,   4,   4,   4,   4,   4,   4,   4,
+			4,   4,   4,   4,   4,   4,   4,   4,
+			4,   4,   4,   4,   4,   4,   4,   4,
+			4,   4,   4,   4,   4,   4,   4,   4,
+			4,   4,   4,   4,   4,   4,   4,   4,
+			4,   4,   4,   4,   4,   4,   4,   4,
+			4,   4,   4,   4,   4,   4,   4,   4,
+			4,
+		},
+		{	/* Fourth byte table 16. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   5,   10,  15,  20,  25,
+			25,  25,  25,  25,  25,  25,  25,  25,
+			25,  25,  25,  25,  25,  25,  25,  25,
+			25,  25,  25,  25,  25,  25,  25,  25,
+			25,  25,  25,  25,  25,  25,  25,  25,
+			25,  25,  25,  25,  25,  25,  25,  25,
+			25,  25,  25,  25,  25,  25,  25,  25,
+			25,  25,  25,  25,  25,  25,  25,  25,
+			25,  25,  25,  25,  25,  25,  25,  25,
+			25,  25,  25,  25,  25,  25,  25,  25,
+			25,  25,  25,  25,  25,  25,  25,  25,
+			25,  25,  25,  25,  25,  25,  25,  25,
+			25,
+		},
+		{	/* Fourth byte table 17. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   4,   8,
+			12,  16,  16,  16,  16,  16,  16,  16,
+			16,  16,  16,  16,  16,  16,  16,  16,
+			16,  16,  16,  16,  16,  16,  16,  16,
+			16,  16,  16,  16,  16,  16,  16,  16,
+			16,  16,  16,  16,  16,  16,  16,  16,
+			16,  16,  16,  16,  16,  16,  16,  16,
+			16,  16,  16,  16,  16,  16,  16,  16,
+			16,  16,  16,  16,  16,  16,  16,  16,
+			16,  16,  16,  16,  16,  16,  16,  16,
+			16,
+		},
+		{	/* Fourth byte table 18. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   5,   5,   10,  10,  10,  10,  10,
+			10,  10,  10,  10,  10,  10,  10,  10,
+			10,  10,  10,  10,  15,  15,  15,  15,
+			15,  15,  15,  15,  15,  15,  15,  15,
+			15,  15,  15,  15,  15,  15,  15,  15,
+			15,  15,  15,  15,  15,  15,  15,  15,
+			15,  15,  15,  15,  15,  15,  15,  15,
+			15,  15,  15,  15,  15,  15,  15,  15,
+			15,  15,  15,  15,  15,  15,  15,  15,
+			15,  15,  15,  15,  15,  15,  15,  15,
+			15,  15,  15,  15,  15,  15,  15,  15,
+			15,  15,  15,  15,  15,  15,  15,  15,
+			15,  15,  15,  15,  15,  15,  15,  15,
+			15,  15,  15,  15,  15,  15,  15,  15,
+			15,  15,  15,  15,  15,  15,  15,  15,
+			15,  15,  15,  15,  15,  15,  15,  15,
+			15,
+		},
+		{	/* Fourth byte table 19. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   7,   7,   7,   7,   7,   7,
+			7,   7,   14,  14,  14,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,
+		},
+		{	/* Fourth byte table 20. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   7,   14,  21,  28,  35,  42,  49,
+			56,  56,  56,  56,  56,  56,  56,  56,
+			56,  56,  56,  56,  56,  56,  56,  56,
+			56,  56,  56,  56,  56,  56,  56,  56,
+			56,  56,  56,  56,  56,  56,  56,  56,
+			56,  56,  56,  56,  56,  56,  56,  56,
+			56,  56,  56,  56,  56,  56,  56,  56,
+			56,  56,  56,  56,  56,  56,  56,  56,
+			56,  56,  56,  56,  56,  56,  56,  56,
+			56,  56,  56,  56,  56,  56,  56,  56,
+			56,  56,  56,  56,  56,  56,  56,  56,
+			56,  56,  56,  56,  56,  56,  56,  56,
+			56,  56,  56,  56,  56,  56,  56,  56,
+			56,
+		},
+		{	/* Fourth byte table 21. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   7,   14,  14,  14,
+			14,  14,  14,  14,  14,  14,  14,  14,
+			14,  14,  14,  14,  14,  21,  28,  28,
+			35,  35,  35,  35,  35,  35,  35,  35,
+			35,  35,  35,  35,  35,  35,  35,  35,
+			35,  35,  35,  35,  35,  35,  35,  35,
+			35,  35,  35,  35,  35,  35,  35,  35,
+			35,  35,  35,  35,  35,  35,  35,  35,
+			35,  35,  35,  35,  35,  35,  35,  35,
+			35,  35,  35,  35,  35,  35,  35,  35,
+			35,  35,  35,  35,  35,  35,  35,  35,
+			35,  35,  35,  35,  35,  35,  35,  35,
+			35,  35,  35,  35,  35,  35,  35,  35,
+			35,  35,  35,  35,  35,  35,  35,  35,
+			35,  35,  35,  35,  35,  35,  35,  35,
+			35,
+		},
+		{	/* Fourth byte table 22. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   7,   7,   7,   14,
+			14,  14,  14,  14,  14,  14,  14,  14,
+			14,  14,  14,  14,  14,  14,  14,  14,
+			14,  14,  14,  14,  14,  14,  14,  14,
+			14,  14,  14,  14,  14,  14,  14,  14,
+			14,  14,  14,  14,  14,  14,  14,  14,
+			14,  14,  14,  14,  14,  14,  14,  14,
+			14,  14,  14,  14,  14,  14,  14,  14,
+			14,  14,  14,  14,  14,  14,  14,  14,
+			14,  14,  14,  14,  14,  14,  14,  14,
+			14,
+		},
+		{	/* Fourth byte table 23. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   7,   14,  21,  21,  21,  28,
+			28,  28,  28,  28,  28,  28,  28,  28,
+			28,  28,  28,  28,  28,  28,  28,  28,
+			28,  28,  28,  28,  28,  28,  28,  28,
+			28,  28,  28,  28,  28,  28,  28,  28,
+			28,  28,  28,  28,  28,  28,  28,  28,
+			28,  28,  28,  28,  28,  28,  28,  28,
+			28,  28,  28,  28,  28,  28,  28,  28,
+			28,  28,  28,  28,  28,  28,  28,  28,
+			28,  28,  28,  28,  28,  28,  28,  28,
+			28,  28,  28,  28,  28,  28,  28,  28,
+			28,  28,  28,  28,  28,  28,  28,  28,
+			28,  28,  28,  28,  28,  28,  28,  28,
+			28,
+		},
+		{	/* Fourth byte table 24. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   7,   7,   7,   14,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  28,  35,  35,
+			35,  35,  35,  35,  35,  35,  35,  35,
+			35,  35,  35,  35,  35,  35,  35,  35,
+			35,  35,  35,  35,  35,  35,  35,  35,
+			35,  35,  35,  35,  35,  35,  35,  35,
+			35,  35,  35,  35,  35,  35,  35,  35,
+			35,  35,  35,  35,  35,  35,  35,  35,
+			35,  35,  35,  35,  35,  35,  35,  35,
+			35,  35,  35,  35,  35,  35,  35,  35,
+			35,  35,  35,  35,  35,  35,  35,  35,
+			35,  35,  35,  35,  35,  35,  35,  35,
+			35,  35,  35,  35,  35,  35,  35,  35,
+			35,  35,  35,  35,  35,  35,  35,  35,
+			35,
+		},
+		{	/* Fourth byte table 25. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   7,   7,   7,
+			7,   7,   7,   7,   7,   7,   7,   7,
+			7,   7,   7,   7,   7,   7,   7,   7,
+			7,   7,   7,   7,   7,   7,   7,   7,
+			7,   7,   7,   7,   7,   7,   7,   7,
+			7,   7,   7,   7,   7,   7,   7,   7,
+			7,   7,   7,   7,   7,   7,   7,   7,
+			7,   7,   7,   7,   7,   7,   7,   7,
+			7,   7,   7,   7,   7,   7,   7,   7,
+			7,   7,   7,   7,   7,   7,   7,   7,
+			7,   7,   7,   7,   7,   7,   7,   7,
+			7,   7,   7,   7,   7,   7,   7,   7,
+			7,   7,   7,   7,   7,   7,   7,   7,
+			7,   7,   7,   7,   7,   7,   7,   7,
+			7,
+		},
+		{	/* Fourth byte table 26. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   7,   14,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,
+		},
+		{	/* Fourth byte table 27. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   7,   7,   7,   7,   7,   7,   7,
+			7,   7,   7,   7,   7,   7,   7,   7,
+			7,   7,   7,   7,   7,   7,   7,   7,
+			7,   7,   7,   7,   7,   7,   7,   7,
+			7,   7,   7,   7,   7,   7,   7,   7,
+			7,   7,   7,   7,   7,   7,   7,   7,
+			7,   7,   7,   7,   7,   7,   7,   7,
+			7,   7,   7,   7,   7,   7,   7,   7,
+			7,   7,   7,   7,   7,   7,   7,   7,
+			7,   7,   7,   7,   7,   7,   7,   7,
+			7,   7,   7,   7,   7,   7,   7,   7,
+			7,   7,   7,   7,   7,   7,   7,   7,
+			7,   7,   7,   7,   7,   7,   7,   7,
+			7,   7,   7,   7,   7,   7,   7,   7,
+			7,   7,   7,   7,   7,   7,   7,   7,
+			7,
+		},
+		{	/* Fourth byte table 28. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   7,   7,   7,   7,   7,   7,   7,
+			14,  21,  21,  28,  38,  38,  38,  38,
+			38,  38,  38,  38,  38,  38,  38,  38,
+			38,  38,  38,  38,  38,  38,  38,  38,
+			38,  38,  38,  38,  38,  38,  38,  38,
+			38,  38,  38,  38,  38,  38,  38,  38,
+			38,  38,  38,  38,  38,  38,  38,  38,
+			38,  38,  38,  38,  38,  38,  38,  38,
+			38,  38,  38,  38,  38,  38,  38,  38,
+			38,  38,  38,  38,  38,  38,  38,  38,
+			38,  38,  38,  38,  38,  38,  38,  38,
+			38,  38,  38,  38,  38,  38,  38,  38,
+			38,  38,  38,  38,  38,  38,  38,  38,
+			38,  38,  38,  38,  38,  38,  38,  38,
+			38,  38,  38,  38,  38,  38,  38,  38,
+			38,  38,  38,  38,  38,  38,  38,  38,
+			38,
+		},
+		{	/* Fourth byte table 29. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   7,   14,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,
+		},
+		{	/* Fourth byte table 30. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   7,   7,   14,  24,  31,
+			31,  31,  31,  31,  31,  31,  31,  31,
+			31,  31,  31,  31,  31,  31,  31,  31,
+			31,  31,  31,  31,  31,  31,  31,  31,
+			31,  31,  31,  31,  31,  31,  31,  31,
+			31,  31,  31,  31,  31,  31,  31,  31,
+			31,  31,  31,  31,  31,  31,  31,  31,
+			31,  31,  31,  31,  31,  31,  31,  31,
+			31,  31,  31,  31,  31,  31,  31,  31,
+			31,  31,  31,  31,  31,  31,  31,  31,
+			31,  31,  31,  31,  31,  31,  31,  31,
+			31,  31,  31,  31,  31,  31,  31,  31,
+			31,  31,  31,  31,  31,  31,  31,  31,
+			31,
+		},
+		{	/* Fourth byte table 31. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   6,   6,   6,   6,
+			6,   6,   6,   6,   6,   6,   6,   6,
+			6,   6,   6,   6,   6,   6,   6,   6,
+			6,   6,   6,   6,   6,   6,   6,   6,
+			6,   6,   6,   6,   6,   6,   6,   6,
+			6,   6,   6,   6,   6,   6,   6,   6,
+			6,   6,   6,   6,   6,   6,   6,   6,
+			6,   6,   6,   6,   6,   6,   6,   6,
+			6,   6,   6,   6,   6,   6,   6,   6,
+			6,   6,   6,   6,   6,   6,   6,   6,
+			6,
+		},
+		{	/* Fourth byte table 32. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   6,   6,   6,   6,
+			6,   6,   6,   6,   6,   6,   6,   6,
+			6,   6,   6,   6,   6,   6,   6,   6,
+			6,   6,   6,   6,   6,   6,   6,   6,
+			6,   6,   6,   6,   6,   6,   6,   6,
+			6,   6,   6,   6,   6,   6,   6,   6,
+			6,   6,   6,   6,   6,   6,   6,   6,
+			6,   6,   6,   6,   6,   6,   6,   6,
+			6,   6,   6,   6,   6,   6,   6,   6,
+			6,   6,   6,   6,   6,   6,   6,   6,
+			6,
+		},
+		{	/* Fourth byte table 33. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   6,   12,  12,
+			12,  12,  12,  12,  12,  12,  12,  12,
+			12,  12,  12,  12,  12,  12,  12,  12,
+			12,  12,  12,  12,  12,  12,  12,  12,
+			12,  12,  12,  12,  12,  12,  12,  12,
+			12,  12,  12,  12,  12,  12,  12,  12,
+			12,  12,  12,  12,  12,  12,  12,  12,
+			12,  12,  12,  12,  12,  12,  12,  12,
+			12,  12,  12,  12,  12,  12,  12,  12,
+			12,  12,  12,  12,  12,  12,  12,  12,
+			12,  12,  12,  12,  12,  12,  12,  12,
+			12,  12,  12,  12,  12,  12,  12,  12,
+			12,  12,  12,  12,  12,  12,  12,  12,
+			12,
+		},
+		{	/* Fourth byte table 34. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   3,   3,   3,
+			3,   3,   3,   3,   3,   3,   3,   3,
+			3,   3,   3,   3,   3,   3,   3,   3,
+			3,   3,   3,   3,   3,   3,   3,   3,
+			3,   3,   3,   3,   3,   3,   3,   3,
+			3,   3,   3,   3,   3,   3,   3,   3,
+			3,   3,   3,   3,   3,   3,   3,   3,
+			3,   3,   3,   3,   3,   3,   3,   3,
+			3,   3,   3,   3,   3,   3,   3,   3,
+			3,   3,   3,   3,   3,   3,   3,   3,
+			3,   3,   3,   3,   3,   3,   3,   3,
+			3,   3,   3,   3,   3,   3,   3,   3,
+			3,   3,   3,   3,   3,   3,   3,   3,
+			3,   3,   3,   3,   3,   3,   3,   3,
+			3,   3,   3,   3,   3,   3,   3,   3,
+			3,
+		},
+		{	/* Fourth byte table 35. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   7,   7,   7,   7,
+			7,   7,   7,   7,   7,   7,   14,  14,
+			14,  14,  14,  21,  21,  21,  21,  21,
+			28,  28,  28,  28,  28,  35,  35,  35,
+			35,  35,  35,  35,  35,  35,  35,  35,
+			35,  35,  42,  42,  42,  42,  42,  42,
+			42,  42,  42,  42,  49,  49,  56,  63,
+			72,  79,  88,  88,  88,  88,  88,  88,
+			88,  88,  88,  88,  88,  88,  88,  88,
+			88,  88,  88,  88,  88,  88,  88,  88,
+			88,  88,  88,  88,  88,  88,  88,  88,
+			88,  88,  88,  88,  88,  88,  88,  88,
+			88,  88,  88,  88,  88,  88,  88,  88,
+			88,  88,  88,  88,  88,  88,  88,  88,
+			88,  88,  88,  88,  88,  88,  88,  88,
+			88,  88,  88,  88,  88,  88,  88,  88,
+			88,
+		},
+		{	/* Fourth byte table 36. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   7,   7,   7,   7,   7,   7,
+			7,   7,   7,   7,   7,   7,   7,   7,
+			7,   7,   7,   7,   14,  14,  14,  14,
+			14,  14,  14,  14,  14,  14,  21,  21,
+			21,  21,  21,  28,  28,  28,  28,  28,
+			35,  35,  35,  35,  35,  42,  42,  42,
+			42,  42,  42,  42,  42,  42,  42,  42,
+			42,  42,  49,  49,  49,  49,  49,  49,
+			49,  49,  49,  49,  49,  49,  49,  49,
+			49,  49,  49,  49,  49,  49,  49,  49,
+			49,  49,  49,  49,  49,  49,  49,  49,
+			49,  49,  49,  49,  49,  49,  49,  49,
+			49,  49,  49,  49,  49,  49,  49,  49,
+			49,  49,  49,  49,  49,  49,  49,  49,
+			49,  49,  49,  49,  49,  49,  49,  49,
+			49,  49,  49,  49,  49,  49,  49,  49,
+			49,
+		},
+		{	/* Fourth byte table 37. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   7,
+			7,   7,   7,   7,   7,   7,   7,   7,
+			7,   7,   7,   7,   7,   7,   7,   7,
+			7,   7,   7,   7,   7,   7,   7,   7,
+			7,   7,   7,   7,   7,   7,   7,   7,
+			7,   7,   7,   7,   7,   7,   7,   7,
+			7,   7,   7,   7,   7,   7,   7,   7,
+			7,   7,   7,   7,   7,   7,   7,   7,
+			7,   7,   7,   7,   7,   7,   7,   7,
+			7,   7,   7,   7,   7,   7,   7,   7,
+			7,   7,   7,   7,   7,   7,   7,   7,
+			7,   7,   7,   7,   7,   7,   7,   7,
+			7,
+		},
+		{	/* Fourth byte table 38. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   3,   3,   3,
+			3,   3,   3,   3,   3,   3,   3,   3,
+			3,   3,   3,   3,   3,   3,   3,   3,
+			3,   3,   3,   3,   3,   3,   3,   3,
+			3,   3,   3,   3,   3,   3,   3,   3,
+			3,   3,   3,   3,   3,   3,   3,   3,
+			3,   3,   3,   3,   3,   3,   3,   3,
+			3,   3,   3,   3,   3,   3,   3,   3,
+			3,   3,   3,   3,   3,   3,   3,   3,
+			3,
+		},
+		{	/* Fourth byte table 39. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   7,
+			7,   14,  14,  21,  21,  28,  28,  35,
+			35,  35,  35,  42,  42,  42,  42,  42,
+			42,  42,  42,  42,  42,  42,  42,  42,
+			42,  42,  42,  42,  42,  42,  42,  42,
+			42,  42,  42,  42,  42,  42,  42,  42,
+			42,  42,  42,  42,  42,  42,  42,  42,
+			42,  42,  42,  42,  49,  49,  56,  56,
+			56,  56,  56,  56,  56,  56,  56,  56,
+			56,  56,  56,  56,  56,  56,  56,  56,
+			56,  56,  56,  56,  56,  56,  56,  56,
+			56,  56,  56,  56,  56,  56,  56,  56,
+			56,  56,  56,  56,  56,  56,  56,  56,
+			56,  56,  56,  56,  56,  56,  56,  56,
+			56,  56,  56,  56,  56,  56,  56,  56,
+			56,  56,  56,  56,  56,  56,  56,  56,
+			56,
+		},
+		{	/* Fourth byte table 40. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   7,   14,  14,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,
+		},
+		{	/* Fourth byte table 41. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   1,   3,   4,
+			4,   5,   6,   8,   9,   10,  11,  12,
+			13,  14,  15,  16,  16,  17,  19,  20,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,
+		},
+		{	/* Fourth byte table 42. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   1,   2,   3,   4,   6,   8,   11,
+			12,  13,  14,  16,  18,  20,  21,  21,
+			22,  23,  25,  26,  28,  31,  34,  35,
+			36,  37,  40,  42,  43,  46,  48,  50,
+			52,  54,  56,  57,  58,  59,  60,  62,
+			64,  66,  68,  70,  70,  70,  70,  70,
+			70,  70,  70,  70,  70,  70,  70,  70,
+			70,  72,  72,  72,  72,  72,  72,  72,
+			72,  72,  72,  72,  72,  72,  72,  72,
+			72,  72,  72,  72,  72,  72,  72,  72,
+			72,  72,  72,  72,  72,  72,  72,  72,
+			72,  72,  72,  72,  72,  72,  72,  72,
+			72,  72,  72,  72,  72,  72,  72,  72,
+			72,  72,  72,  72,  72,  72,  72,  72,
+			72,  72,  72,  72,  72,  72,  72,  72,
+			72,  72,  72,  72,  72,  72,  72,  72,
+			72,
+		},
+		{	/* Fourth byte table 43. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   2,   3,   5,   7,
+			9,   10,  12,  14,  16,  18,  20,  22,
+			25,  27,  29,  32,  34,  36,  38,  40,
+			42,  44,  46,  48,  50,  52,  54,  56,
+			58,  61,  63,  65,  66,  68,  70,  72,
+			74,  74,  74,  74,  74,  74,  74,  74,
+			74,  74,  74,  74,  74,  74,  74,  74,
+			74,  74,  74,  74,  74,  74,  74,  74,
+			74,  74,  74,  74,  74,  74,  74,  74,
+			74,  74,  74,  74,  74,  74,  74,  74,
+			74,  74,  74,  74,  74,  74,  74,  74,
+			74,  74,  74,  74,  74,  74,  74,  74,
+			74,  74,  74,  74,  74,  74,  74,  74,
+			74,
+		},
+		{	/* Fourth byte table 44. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   6,   12,  13,  14,  15,  16,  17,
+			18,  19,  20,  21,  21,  21,  21,  21,
+			21,  21,  24,  24,  24,  24,  24,  24,
+			27,  27,  27,  27,  27,  27,  27,  27,
+			27,  27,  27,  27,  27,  28,  30,  33,
+			33,  33,  33,  33,  33,  33,  33,  33,
+			34,  34,  34,  34,  40,  49,  49,  55,
+			64,  64,  64,  64,  64,  66,  66,  69,
+			69,  69,  69,  69,  69,  69,  69,  69,
+			69,  69,  69,  69,  69,  69,  69,  69,
+			69,  69,  69,  69,  69,  69,  69,  69,
+			69,  69,  69,  69,  69,  69,  69,  69,
+			69,  69,  69,  69,  69,  69,  69,  69,
+			69,  69,  69,  69,  69,  69,  69,  69,
+			69,  69,  69,  69,  69,  69,  69,  69,
+			69,  69,  69,  69,  69,  69,  69,  69,
+			69,
+		},
+		{	/* Fourth byte table 45. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			2,   4,   6,   6,   6,   6,   6,   6,
+			6,   6,   6,   6,   6,   6,   6,   6,
+			18,  18,  18,  18,  18,  18,  18,  18,
+			19,  19,  19,  19,  19,  19,  19,  19,
+			19,  19,  19,  19,  19,  19,  19,  19,
+			19,  20,  21,  21,  21,  22,  23,  24,
+			25,  26,  27,  28,  31,  32,  33,  34,
+			35,  35,  35,  35,  35,  35,  35,  35,
+			35,  35,  35,  35,  35,  35,  35,  35,
+			35,  35,  35,  35,  35,  35,  35,  35,
+			35,  35,  35,  35,  35,  35,  35,  35,
+			35,  35,  35,  35,  35,  35,  35,  35,
+			35,  35,  35,  35,  35,  35,  35,  35,
+			35,  35,  35,  35,  35,  35,  35,  35,
+			35,  35,  35,  35,  35,  35,  35,  35,
+			35,
+		},
+		{	/* Fourth byte table 46. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   1,   2,   3,   4,   5,   6,   7,
+			8,   9,   10,  11,  14,  15,  16,  17,
+			17,  18,  19,  20,  21,  23,  23,  23,
+			23,  23,  23,  23,  23,  23,  23,  23,
+			23,  23,  23,  23,  23,  23,  23,  23,
+			23,  25,  25,  25,  25,  25,  25,  25,
+			25,  25,  25,  25,  25,  25,  25,  25,
+			25,  25,  25,  25,  25,  25,  25,  25,
+			25,  25,  25,  25,  25,  25,  25,  25,
+			25,  25,  25,  25,  25,  25,  25,  25,
+			25,  25,  25,  25,  25,  25,  25,  25,
+			25,  25,  25,  25,  25,  25,  25,  25,
+			25,  25,  25,  25,  25,  25,  25,  25,
+			25,  25,  25,  25,  25,  25,  25,  25,
+			25,  25,  25,  25,  25,  25,  25,  25,
+			25,  25,  25,  25,  25,  25,  25,  25,
+			25,
+		},
+		{	/* Fourth byte table 47. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   3,   6,   7,   10,  10,  13,  16,
+			18,  18,  21,  22,  23,  24,  25,  26,
+			28,  29,  30,  31,  32,  32,  33,  35,
+			35,  35,  36,  37,  38,  39,  40,  40,
+			40,  42,  45,  47,  47,  48,  48,  51,
+			51,  52,  52,  54,  58,  59,  60,  60,
+			61,  62,  63,  63,  64,  65,  67,  69,
+			71,  73,  74,  74,  77,  79,  81,  83,
+			85,  85,  85,  85,  85,  85,  85,  85,
+			85,  85,  85,  85,  85,  85,  85,  85,
+			85,  85,  85,  85,  85,  85,  85,  85,
+			85,  85,  85,  85,  85,  85,  85,  85,
+			85,  85,  85,  85,  85,  85,  85,  85,
+			85,  85,  85,  85,  85,  85,  85,  85,
+			85,  85,  85,  85,  85,  85,  85,  85,
+			85,  85,  85,  85,  85,  85,  85,  85,
+			85,
+		},
+		{	/* Fourth byte table 48. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   3,   3,   3,   3,   3,   4,   5,
+			6,   7,   8,   8,   8,   8,   8,   8,
+			8,   8,   8,   8,   13,  18,  23,  28,
+			33,  38,  43,  48,  53,  58,  63,  68,
+			72,  73,  75,  78,  80,  81,  83,  86,
+			90,  92,  93,  95,  98,  99,  100, 101,
+			102, 103, 105, 108, 110, 111, 113, 116,
+			120, 122, 123, 125, 128, 129, 130, 131,
+			132, 132, 132, 132, 132, 132, 132, 132,
+			132, 132, 132, 132, 132, 132, 132, 132,
+			132, 132, 132, 132, 132, 132, 132, 132,
+			132, 132, 132, 132, 132, 132, 132, 132,
+			132, 132, 132, 132, 132, 132, 132, 132,
+			132, 132, 132, 132, 132, 132, 132, 132,
+			132, 132, 132, 132, 132, 132, 132, 132,
+			132, 132, 132, 132, 132, 132, 132, 132,
+			132,
+		},
+		{	/* Fourth byte table 49. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   6,   12,  12,  12,  12,
+			12,  12,  12,  12,  12,  12,  12,  12,
+			12,  12,  12,  12,  12,  12,  12,  18,
+			18,  18,  18,  18,  18,  18,  18,  18,
+			18,  18,  18,  18,  18,  18,  18,  18,
+			18,  18,  18,  18,  18,  18,  18,  18,
+			18,  18,  18,  18,  18,  18,  18,  18,
+			18,  18,  18,  18,  18,  18,  18,  18,
+			18,  18,  18,  18,  18,  18,  18,  18,
+			18,  18,  18,  18,  18,  18,  18,  18,
+			18,  18,  18,  18,  18,  18,  18,  18,
+			18,  18,  18,  18,  18,  18,  18,  18,
+			18,  18,  18,  18,  18,  18,  18,  18,
+			18,
+		},
+		{	/* Fourth byte table 50. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   6,   12,
+			18,  18,  18,  18,  18,  18,  18,  18,
+			18,  18,  18,  18,  18,  18,  18,  18,
+			18,  18,  18,  18,  18,  18,  18,  18,
+			18,  18,  18,  18,  18,  18,  18,  18,
+			18,  18,  18,  18,  18,  18,  18,  18,
+			18,  18,  18,  18,  18,  18,  18,  18,
+			18,  18,  18,  18,  18,  18,  18,  18,
+			18,  18,  18,  18,  18,  18,  18,  18,
+			18,  18,  18,  18,  18,  18,  18,  18,
+			18,  18,  18,  18,  18,  18,  18,  18,
+			18,  18,  18,  18,  18,  18,  18,  18,
+			18,  18,  18,  18,  18,  18,  18,  18,
+			18,  18,  18,  18,  18,  18,  18,  18,
+			18,  18,  18,  18,  18,  18,  18,  18,
+			18,
+		},
+		{	/* Fourth byte table 51. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   6,   6,   6,
+			6,   6,   12,  12,  12,  18,  18,  18,
+			18,  18,  18,  18,  18,  18,  18,  18,
+			18,  18,  18,  18,  18,  18,  18,  18,
+			18,  18,  18,  18,  18,  24,  24,  30,
+			30,  30,  30,  30,  30,  36,  45,  45,
+			51,  60,  60,  60,  60,  60,  60,  60,
+			60,  60,  60,  60,  60,  60,  60,  60,
+			60,  60,  60,  60,  60,  60,  60,  60,
+			60,  60,  60,  60,  60,  60,  60,  60,
+			60,  60,  60,  60,  60,  60,  60,  60,
+			60,  60,  60,  60,  60,  60,  60,  60,
+			60,  60,  60,  60,  60,  60,  60,  60,
+			60,  60,  60,  60,  60,  60,  60,  60,
+			60,  60,  60,  60,  60,  60,  60,  60,
+			60,  60,  60,  60,  60,  60,  60,  60,
+			60,
+		},
+		{	/* Fourth byte table 52. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   6,   6,   6,   12,  12,  12,
+			18,  18,  24,  24,  24,  24,  24,  24,
+			24,  24,  24,  24,  24,  24,  24,  24,
+			24,  24,  24,  24,  24,  24,  24,  24,
+			24,  28,  28,  34,  34,  34,  34,  34,
+			34,  34,  34,  34,  34,  34,  40,  44,
+			48,  54,  60,  60,  60,  66,  72,  72,
+			72,  78,  84,  84,  84,  84,  84,  84,
+			84,  84,  84,  84,  84,  84,  84,  84,
+			84,  84,  84,  84,  84,  84,  84,  84,
+			84,  84,  84,  84,  84,  84,  84,  84,
+			84,  84,  84,  84,  84,  84,  84,  84,
+			84,  84,  84,  84,  84,  84,  84,  84,
+			84,  84,  84,  84,  84,  84,  84,  84,
+			84,  84,  84,  84,  84,  84,  84,  84,
+			84,  84,  84,  84,  84,  84,  84,  84,
+			84,
+		},
+		{	/* Fourth byte table 53. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   6,   12,  12,  12,  18,  24,  24,
+			24,  30,  36,  36,  36,  36,  36,  36,
+			36,  36,  36,  36,  36,  36,  36,  36,
+			36,  36,  36,  36,  36,  36,  36,  36,
+			36,  36,  36,  36,  36,  36,  36,  36,
+			36,  36,  36,  36,  36,  42,  48,  54,
+			60,  60,  60,  60,  60,  60,  60,  60,
+			60,  60,  60,  60,  60,  60,  60,  60,
+			60,  60,  60,  60,  60,  60,  60,  60,
+			60,  60,  60,  60,  60,  60,  60,  60,
+			60,  60,  60,  60,  60,  60,  60,  60,
+			60,  60,  60,  60,  60,  60,  60,  60,
+			60,  60,  60,  60,  60,  60,  60,  60,
+			60,  60,  60,  60,  60,  60,  60,  60,
+			60,  60,  60,  60,  60,  60,  60,  60,
+			60,  60,  60,  60,  60,  60,  60,  60,
+			60,
+		},
+		{	/* Fourth byte table 54. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   6,   12,  18,  24,  24,  24,  24,
+			24,  24,  24,  30,  36,  42,  48,  48,
+			48,  48,  48,  48,  48,  48,  48,  48,
+			48,  48,  48,  48,  48,  48,  48,  48,
+			48,  48,  48,  48,  48,  48,  48,  48,
+			48,  48,  48,  48,  48,  48,  48,  48,
+			48,  48,  48,  48,  48,  48,  48,  48,
+			48,  48,  48,  48,  48,  48,  48,  48,
+			48,  48,  48,  48,  48,  48,  48,  48,
+			48,  48,  48,  48,  48,  48,  48,  48,
+			48,  48,  48,  48,  48,  48,  48,  48,
+			48,  48,  48,  48,  48,  48,  48,  48,
+			48,
+		},
+		{	/* Fourth byte table 55. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   4,   8,   8,   8,   8,   8,
+			8,   8,   8,   8,   8,   8,   8,   8,
+			8,   8,   8,   8,   8,   8,   8,   8,
+			8,   8,   8,   8,   8,   8,   8,   8,
+			8,   8,   8,   8,   8,   8,   8,   8,
+			8,   8,   8,   8,   8,   8,   8,   8,
+			8,   8,   8,   8,   8,   8,   8,   8,
+			8,   8,   8,   8,   8,   8,   8,   8,
+			8,   8,   8,   8,   8,   8,   8,   8,
+			8,   8,   8,   8,   8,   8,   8,   8,
+			8,   8,   8,   8,   8,   8,   8,   8,
+			8,
+		},
+		{	/* Fourth byte table 56. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   1,   2,   3,   4,   5,   6,   7,
+			8,   9,   11,  13,  15,  17,  19,  21,
+			23,  25,  27,  29,  31,  34,  37,  40,
+			43,  46,  49,  52,  55,  58,  62,  66,
+			70,  70,  70,  70,  70,  70,  70,  70,
+			70,  70,  70,  70,  70,  70,  70,  70,
+			70,  70,  70,  70,  70,  70,  70,  70,
+			70,  70,  70,  70,  70,  70,  70,  70,
+			70,  70,  70,  70,  70,  70,  70,  70,
+			70,  70,  70,  70,  70,  70,  70,  70,
+			70,  70,  70,  70,  70,  70,  70,  70,
+			70,  70,  70,  70,  70,  70,  70,  70,
+			70,
+		},
+		{	/* Fourth byte table 57. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   4,   8,   12,  16,  20,  24,  28,
+			32,  34,  36,  38,  40,  42,  44,  46,
+			48,  50,  53,  56,  59,  62,  65,  68,
+			71,  74,  77,  80,  83,  86,  89,  92,
+			95,  98,  101, 104, 107, 110, 113, 116,
+			119, 122, 125, 128, 131, 134, 137, 140,
+			143, 146, 149, 152, 155, 158, 161, 162,
+			163, 164, 165, 166, 167, 168, 169, 170,
+			171, 171, 171, 171, 171, 171, 171, 171,
+			171, 171, 171, 171, 171, 171, 171, 171,
+			171, 171, 171, 171, 171, 171, 171, 171,
+			171, 171, 171, 171, 171, 171, 171, 171,
+			171, 171, 171, 171, 171, 171, 171, 171,
+			171, 171, 171, 171, 171, 171, 171, 171,
+			171, 171, 171, 171, 171, 171, 171, 171,
+			171, 171, 171, 171, 171, 171, 171, 171,
+			171,
+		},
+		{	/* Fourth byte table 58. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   1,   2,   3,   4,   5,   6,   7,
+			8,   9,   10,  11,  12,  13,  14,  15,
+			16,  17,  18,  19,  20,  21,  22,  23,
+			24,  25,  26,  27,  28,  29,  30,  31,
+			32,  33,  34,  35,  36,  37,  38,  39,
+			40,  41,  42,  43,  43,  43,  43,  43,
+			43,  43,  43,  43,  43,  43,  43,  43,
+			43,  43,  43,  43,  43,  43,  43,  43,
+			43,  43,  43,  43,  43,  43,  43,  43,
+			43,  43,  43,  43,  43,  43,  43,  43,
+			43,  43,  43,  43,  43,  43,  43,  43,
+			43,  43,  43,  43,  43,  43,  43,  43,
+			43,  43,  43,  43,  43,  43,  43,  43,
+			43,  43,  43,  43,  43,  43,  43,  43,
+			43,  43,  43,  43,  43,  43,  43,  43,
+			43,  43,  43,  43,  43,  43,  43,  43,
+			43,
+		},
+		{	/* Fourth byte table 59. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   12,  12,  12,
+			12,  12,  12,  12,  12,  12,  12,  12,
+			12,  12,  12,  12,  12,  12,  12,  12,
+			12,  12,  12,  12,  12,  12,  12,  12,
+			12,  12,  12,  12,  12,  12,  12,  12,
+			12,  12,  12,  12,  12,  12,  12,  12,
+			12,  12,  12,  12,  12,  12,  12,  12,
+			12,  12,  12,  12,  12,  12,  12,  12,
+			12,  12,  12,  12,  12,  12,  12,  12,
+			12,  12,  12,  12,  12,  12,  12,  12,
+			12,  12,  12,  12,  12,  12,  12,  12,
+			12,  12,  12,  12,  12,  12,  12,  12,
+			12,  12,  12,  12,  12,  12,  12,  12,
+			12,  12,  12,  12,  12,  12,  12,  12,
+			12,  12,  12,  12,  12,  12,  12,  12,
+			12,
+		},
+		{	/* Fourth byte table 60. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   3,   5,   8,
+			8,   8,   8,   8,   8,   8,   8,   8,
+			8,   8,   8,   8,   8,   8,   8,   8,
+			8,   8,   8,   8,   8,   8,   8,   8,
+			8,   8,   8,   8,   8,   8,   8,   8,
+			8,   8,   8,   8,   8,   8,   8,   8,
+			8,   8,   8,   8,   8,   8,   8,   8,
+			8,   8,   8,   8,   8,   8,   8,   8,
+			8,   8,   8,   8,   8,   8,   8,   8,
+			8,   8,   8,   8,   8,   8,   8,   8,
+			8,
+		},
+		{	/* Fourth byte table 61. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   6,   6,   6,
+			6,   6,   6,   6,   6,   6,   6,   6,
+			6,   6,   6,   6,   6,   6,   6,   6,
+			6,   6,   6,   6,   6,   6,   6,   6,
+			6,   6,   6,   6,   6,   6,   6,   6,
+			6,   6,   6,   6,   6,   6,   6,   6,
+			6,   6,   6,   6,   6,   6,   6,   6,
+			6,   6,   6,   6,   6,   6,   6,   6,
+			6,   6,   6,   6,   6,   6,   6,   6,
+			6,   6,   6,   6,   6,   6,   6,   6,
+			6,   6,   6,   6,   6,   6,   6,   6,
+			6,   6,   6,   6,   6,   6,   6,   6,
+			6,   6,   6,   6,   6,   6,   6,   6,
+			6,
+		},
+		{	/* Fourth byte table 62. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			3,   3,   3,   3,   3,   3,   3,   3,
+			3,   3,   3,   3,   3,   3,   3,   3,
+			3,   3,   3,   3,   3,   3,   3,   3,
+			3,   3,   3,   3,   3,   3,   3,   3,
+			3,   3,   3,   3,   3,   3,   3,   3,
+			3,   3,   3,   3,   3,   3,   3,   3,
+			3,   3,   3,   3,   3,   3,   3,   3,
+			3,   3,   3,   3,   3,   3,   3,   3,
+			3,   3,   3,   3,   3,   3,   3,   3,
+			3,   3,   3,   3,   3,   3,   3,   3,
+			3,
+		},
+		{	/* Fourth byte table 63. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			3,   3,   3,   3,   3,   3,   3,   3,
+			3,   3,   3,   3,   3,   3,   3,   3,
+			3,   3,   3,   3,   3,   3,   3,   3,
+			3,   3,   3,   3,   3,   3,   3,   3,
+			3,   3,   3,   3,   3,   3,   3,   3,
+			3,   3,   3,   3,   3,   3,   3,   3,
+			3,   3,   3,   3,   3,   3,   3,   3,
+			3,   3,   3,   3,   3,   3,   3,   3,
+			3,   3,   3,   3,   3,   3,   3,   3,
+			3,   3,   3,   3,   3,   3,   3,   3,
+			3,   3,   3,   3,   3,   3,   3,   3,
+			3,   3,   3,   3,   3,   3,   3,   3,
+			3,
+		},
+		{	/* Fourth byte table 64. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   3,   3,   3,   3,
+			3,   3,   3,   3,   3,   3,   3,   3,
+			3,   3,   3,   3,   3,   3,   3,   3,
+			3,   3,   3,   3,   3,   3,   3,   3,
+			3,   3,   3,   3,   3,   3,   3,   3,
+			3,   3,   3,   3,   3,   3,   3,   3,
+			3,   3,   3,   3,   3,   3,   3,   3,
+			3,   3,   3,   3,   3,   3,   3,   3,
+			3,   3,   3,   3,   3,   3,   3,   3,
+			3,   3,   3,   3,   3,   3,   3,   3,
+			3,
+		},
+		{	/* Fourth byte table 65. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   3,   6,   9,   12,  15,  18,  21,
+			24,  27,  30,  33,  36,  39,  42,  45,
+			48,  51,  54,  57,  60,  63,  66,  69,
+			72,  75,  78,  81,  84,  87,  90,  93,
+			96,  99,  102, 105, 108, 111, 114, 117,
+			120, 123, 126, 129, 132, 135, 138, 141,
+			144, 147, 150, 153, 156, 159, 162, 165,
+			168, 171, 174, 177, 180, 183, 186, 189,
+			192, 192, 192, 192, 192, 192, 192, 192,
+			192, 192, 192, 192, 192, 192, 192, 192,
+			192, 192, 192, 192, 192, 192, 192, 192,
+			192, 192, 192, 192, 192, 192, 192, 192,
+			192, 192, 192, 192, 192, 192, 192, 192,
+			192, 192, 192, 192, 192, 192, 192, 192,
+			192, 192, 192, 192, 192, 192, 192, 192,
+			192, 192, 192, 192, 192, 192, 192, 192,
+			192,
+		},
+		{	/* Fourth byte table 66. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   3,   6,   9,   12,  15,  18,  21,
+			24,  27,  30,  33,  36,  39,  42,  45,
+			48,  51,  54,  57,  60,  63,  66,  69,
+			72,  75,  78,  81,  84,  87,  90,  93,
+			96,  99,  102, 105, 108, 111, 114, 117,
+			120, 123, 126, 129, 132, 135, 138, 141,
+			144, 147, 150, 153, 156, 159, 162, 165,
+			168, 171, 174, 177, 180, 183, 186, 189,
+			192, 192, 192, 192, 192, 192, 192, 192,
+			192, 192, 192, 192, 192, 192, 192, 192,
+			192, 192, 192, 192, 192, 192, 192, 192,
+			192, 192, 192, 192, 192, 192, 192, 192,
+			192, 192, 192, 192, 192, 192, 192, 192,
+			192, 192, 192, 192, 192, 192, 192, 192,
+			192, 192, 192, 192, 192, 192, 192, 192,
+			192, 192, 192, 192, 192, 192, 192, 192,
+			192,
+		},
+		{	/* Fourth byte table 67. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   3,   6,   9,   12,  15,  18,  21,
+			24,  27,  30,  33,  36,  39,  42,  45,
+			48,  51,  54,  57,  60,  63,  66,  69,
+			72,  75,  78,  81,  84,  87,  90,  93,
+			96,  99,  102, 105, 108, 111, 114, 117,
+			120, 123, 126, 129, 132, 135, 138, 141,
+			144, 147, 150, 153, 156, 159, 162, 165,
+			168, 171, 174, 177, 180, 183, 186, 189,
+			192, 192, 192, 192, 192, 192, 192, 192,
+			192, 192, 192, 192, 192, 192, 192, 192,
+			192, 192, 192, 192, 192, 192, 192, 192,
+			192, 192, 192, 192, 192, 192, 192, 192,
+			192, 192, 192, 192, 192, 192, 192, 192,
+			192, 192, 192, 192, 192, 192, 192, 192,
+			192, 192, 192, 192, 192, 192, 192, 192,
+			192, 192, 192, 192, 192, 192, 192, 192,
+			192,
+		},
+		{	/* Fourth byte table 68. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   3,   6,   9,   12,  15,  18,  21,
+			24,  27,  30,  33,  36,  39,  42,  45,
+			48,  51,  54,  57,  60,  63,  66,  66,
+			66,  66,  66,  66,  66,  66,  66,  66,
+			66,  66,  66,  66,  66,  66,  66,  66,
+			66,  66,  66,  66,  66,  66,  66,  66,
+			66,  66,  66,  66,  66,  66,  66,  66,
+			66,  66,  66,  66,  66,  66,  66,  66,
+			66,  66,  66,  66,  66,  66,  66,  66,
+			66,  66,  66,  66,  66,  66,  66,  66,
+			66,  66,  66,  66,  66,  66,  66,  66,
+			66,  66,  66,  66,  66,  66,  66,  66,
+			66,  66,  66,  66,  66,  66,  66,  66,
+			66,  66,  66,  66,  66,  66,  66,  66,
+			66,  66,  66,  66,  66,  66,  66,  66,
+			66,  66,  66,  66,  66,  66,  66,  66,
+			66,
+		},
+		{	/* Fourth byte table 69. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   1,   1,   1,   1,   1,   1,   1,
+			1,   1,   1,   1,   1,   1,   1,   1,
+			1,   1,   1,   1,   1,   1,   1,   1,
+			1,   1,   1,   1,   1,   1,   1,   1,
+			1,   1,   1,   1,   1,   1,   1,   1,
+			1,   1,   1,   1,   1,   1,   1,   1,
+			1,   1,   1,   1,   1,   1,   1,   4,
+			4,   7,   10,  13,  13,  13,  13,  13,
+			13,  13,  13,  13,  13,  13,  13,  13,
+			13,  13,  13,  13,  13,  13,  13,  13,
+			13,  13,  13,  13,  13,  13,  13,  13,
+			13,  13,  13,  13,  13,  13,  13,  13,
+			13,  13,  13,  13,  13,  13,  13,  13,
+			13,  13,  13,  13,  13,  13,  13,  13,
+			13,  13,  13,  13,  13,  13,  13,  13,
+			13,  13,  13,  13,  13,  13,  13,  13,
+			13,
+		},
+		{	/* Fourth byte table 70. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   7,   7,   14,
+			14,  21,  21,  28,  28,  35,  35,  42,
+			42,  49,  49,  56,  56,  63,  63,  70,
+			70,  77,  77,  84,  84,  84,  91,  91,
+			98,  98,  105, 105, 105, 105, 105, 105,
+			105, 112, 119, 119, 126, 133, 133, 140,
+			147, 147, 154, 161, 161, 168, 175, 175,
+			175, 175, 175, 175, 175, 175, 175, 175,
+			175, 175, 175, 175, 175, 175, 175, 175,
+			175, 175, 175, 175, 175, 175, 175, 175,
+			175, 175, 175, 175, 175, 175, 175, 175,
+			175, 175, 175, 175, 175, 175, 175, 175,
+			175, 175, 175, 175, 175, 175, 175, 175,
+			175, 175, 175, 175, 175, 175, 175, 175,
+			175, 175, 175, 175, 175, 175, 175, 175,
+			175,
+		},
+		{	/* Fourth byte table 71. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   7,   7,   7,
+			7,   7,   7,   7,   11,  15,  15,  22,
+			28,  28,  28,  28,  28,  28,  28,  28,
+			28,  28,  28,  28,  28,  35,  35,  42,
+			42,  49,  49,  56,  56,  63,  63,  70,
+			70,  77,  77,  84,  84,  91,  91,  98,
+			98,  98,  98,  98,  98,  98,  98,  98,
+			98,  98,  98,  98,  98,  98,  98,  98,
+			98,  98,  98,  98,  98,  98,  98,  98,
+			98,  98,  98,  98,  98,  98,  98,  98,
+			98,  98,  98,  98,  98,  98,  98,  98,
+			98,  98,  98,  98,  98,  98,  98,  98,
+			98,  98,  98,  98,  98,  98,  98,  98,
+			98,  98,  98,  98,  98,  98,  98,  98,
+			98,
+		},
+		{	/* Fourth byte table 72. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   7,   7,   14,  14,  14,  21,  21,
+			28,  28,  35,  35,  35,  35,  35,  35,
+			35,  42,  49,  49,  56,  63,  63,  70,
+			77,  77,  84,  91,  91,  98,  105, 105,
+			105, 105, 105, 105, 105, 105, 105, 105,
+			105, 105, 105, 105, 105, 105, 105, 105,
+			105, 105, 105, 105, 105, 112, 112, 112,
+			119, 126, 133, 140, 140, 140, 140, 147,
+			153, 153, 153, 153, 153, 153, 153, 153,
+			153, 153, 153, 153, 153, 153, 153, 153,
+			153, 153, 153, 153, 153, 153, 153, 153,
+			153, 153, 153, 153, 153, 153, 153, 153,
+			153, 153, 153, 153, 153, 153, 153, 153,
+			153, 153, 153, 153, 153, 153, 153, 153,
+			153, 153, 153, 153, 153, 153, 153, 153,
+			153, 153, 153, 153, 153, 153, 153, 153,
+			153,
+		},
+		{	/* Fourth byte table 73. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   3,   6,   9,   12,  15,  18,
+			21,  24,  27,  30,  33,  36,  39,  42,
+			45,  45,  45,  45,  45,  45,  45,  45,
+			45,  45,  45,  45,  45,  45,  45,  45,
+			45,  45,  45,  45,  45,  45,  45,  45,
+			45,  45,  45,  45,  45,  45,  45,  45,
+			45,  45,  45,  45,  45,  45,  45,  45,
+			45,  45,  45,  45,  45,  45,  45,  45,
+			45,  45,  45,  45,  45,  45,  45,  45,
+			45,  45,  45,  45,  45,  45,  45,  45,
+			45,
+		},
+		{	/* Fourth byte table 74. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   3,   6,   9,   12,  15,  18,  21,
+			24,  27,  30,  33,  36,  39,  42,  45,
+			48,  51,  54,  57,  60,  63,  66,  69,
+			72,  75,  78,  81,  84,  87,  90,  93,
+			96,  99,  102, 105, 108, 111, 114, 117,
+			120, 123, 126, 129, 132, 135, 138, 141,
+			144, 147, 150, 153, 156, 159, 162, 165,
+			168, 171, 174, 177, 180, 183, 186, 189,
+			192, 192, 192, 192, 192, 192, 192, 192,
+			192, 192, 192, 192, 192, 192, 192, 192,
+			192, 192, 192, 192, 192, 192, 192, 192,
+			192, 192, 192, 192, 192, 192, 192, 192,
+			192, 192, 192, 192, 192, 192, 192, 192,
+			192, 192, 192, 192, 192, 192, 192, 192,
+			192, 192, 192, 192, 192, 192, 192, 192,
+			192, 192, 192, 192, 192, 192, 192, 192,
+			192,
+		},
+		{	/* Fourth byte table 75. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   3,   6,   9,   12,  15,  18,  21,
+			24,  27,  30,  33,  36,  39,  42,  45,
+			45,  45,  45,  48,  51,  54,  57,  60,
+			63,  66,  69,  72,  75,  78,  81,  84,
+			87,  87,  87,  87,  87,  87,  87,  87,
+			87,  87,  87,  87,  87,  87,  87,  87,
+			87,  87,  87,  87,  87,  87,  87,  87,
+			87,  87,  87,  87,  87,  87,  87,  87,
+			87,  87,  87,  87,  87,  87,  87,  87,
+			87,  87,  87,  87,  87,  87,  87,  87,
+			87,  87,  87,  87,  87,  87,  87,  87,
+			87,  87,  87,  87,  87,  87,  87,  87,
+			87,  87,  87,  87,  87,  87,  87,  87,
+			87,  87,  87,  87,  87,  87,  87,  87,
+			87,  87,  87,  87,  87,  87,  87,  87,
+			87,  87,  87,  87,  87,  87,  87,  87,
+			87,
+		},
+		{	/* Fourth byte table 76. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   5,   10,  15,  20,  20,  20,  20,
+			20,  20,  20,  20,  20,  20,  20,  20,
+			20,  23,  25,  27,  29,  31,  33,  35,
+			37,  39,  41,  43,  45,  47,  49,  51,
+			53,  56,  59,  62,  65,  68,  71,  74,
+			77,  80,  83,  86,  89,  92,  95,  101,
+			107, 113, 119, 125, 131, 137, 143, 149,
+			155, 161, 167, 173, 179, 194, 206, 212,
+			212, 212, 212, 212, 212, 212, 212, 212,
+			212, 212, 212, 212, 212, 212, 212, 212,
+			212, 212, 212, 212, 212, 212, 212, 212,
+			212, 212, 212, 212, 212, 212, 212, 212,
+			212, 212, 212, 212, 212, 212, 212, 212,
+			212, 212, 212, 212, 212, 212, 212, 212,
+			212, 212, 212, 212, 212, 212, 212, 212,
+			212, 212, 212, 212, 212, 212, 212, 212,
+			212,
+		},
+		{	/* Fourth byte table 77. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   3,   6,   9,   12,  15,  18,  21,
+			24,  27,  30,  33,  36,  39,  42,  45,
+			48,  51,  54,  57,  60,  63,  66,  69,
+			72,  75,  78,  81,  84,  87,  90,  93,
+			96,  99,  102, 105, 108, 111, 114, 117,
+			120, 123, 126, 129, 132, 135, 138, 141,
+			144, 147, 149, 151, 153, 155, 157, 159,
+			161, 163, 165, 167, 169, 171, 173, 175,
+			177, 177, 177, 177, 177, 177, 177, 177,
+			177, 177, 177, 177, 177, 177, 177, 177,
+			177, 177, 177, 177, 177, 177, 177, 177,
+			177, 177, 177, 177, 177, 177, 177, 177,
+			177, 177, 177, 177, 177, 177, 177, 177,
+			177, 177, 177, 177, 177, 177, 177, 177,
+			177, 177, 177, 177, 177, 177, 177, 177,
+			177, 177, 177, 177, 177, 177, 177, 177,
+			177,
+		},
+		{	/* Fourth byte table 78. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   4,   8,   12,  16,  20,  24,  28,
+			32,  36,  41,  46,  51,  53,  56,  58,
+			61,  64,  67,  70,  73,  76,  79,  82,
+			85,  88,  91,  94,  97,  100, 103, 106,
+			109, 112, 115, 118, 121, 124, 127, 130,
+			133, 136, 139, 142, 145, 148, 151, 154,
+			157, 160, 163, 166, 169, 172, 175, 178,
+			181, 184, 187, 190, 193, 196, 199, 202,
+			202, 202, 202, 202, 202, 202, 202, 202,
+			202, 202, 202, 202, 202, 202, 202, 202,
+			202, 202, 202, 202, 202, 202, 202, 202,
+			202, 202, 202, 202, 202, 202, 202, 202,
+			202, 202, 202, 202, 202, 202, 202, 202,
+			202, 202, 202, 202, 202, 202, 202, 202,
+			202, 202, 202, 202, 202, 202, 202, 202,
+			202, 202, 202, 202, 202, 202, 202, 202,
+			202,
+		},
+		{	/* Fourth byte table 79. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   2,   4,   7,   9,   11,  13,  15,
+			17,  20,  24,  26,  28,  31,  34,  36,
+			38,  40,  43,  46,  49,  52,  55,  57,
+			59,  61,  63,  65,  68,  70,  72,  74,
+			77,  80,  82,  85,  88,  91,  93,  96,
+			101, 107, 109, 112, 115, 118, 121, 128,
+			136, 138, 140, 143, 145, 147, 149, 152,
+			154, 156, 158, 160, 162, 165, 167, 169,
+			171, 171, 171, 171, 171, 171, 171, 171,
+			171, 171, 171, 171, 171, 171, 171, 171,
+			171, 171, 171, 171, 171, 171, 171, 171,
+			171, 171, 171, 171, 171, 171, 171, 171,
+			171, 171, 171, 171, 171, 171, 171, 171,
+			171, 171, 171, 171, 171, 171, 171, 171,
+			171, 171, 171, 171, 171, 171, 171, 171,
+			171, 171, 171, 171, 171, 171, 171, 171,
+			171,
+		},
+		{	/* Fourth byte table 80. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   3,   6,   10,  12,  14,  16,  22,
+			25,  27,  29,  31,  33,  35,  37,  39,
+			41,  43,  45,  48,  50,  52,  55,  58,
+			60,  64,  67,  69,  71,  73,  75,  80,
+			85,  89,  93,  97,  101, 105, 109, 113,
+			117, 121, 126, 131, 136, 141, 146, 151,
+			156, 161, 166, 171, 176, 181, 186, 191,
+			196, 201, 206, 211, 216, 221, 226, 231,
+			234, 234, 234, 234, 234, 234, 234, 234,
+			234, 234, 234, 234, 234, 234, 234, 234,
+			234, 234, 234, 234, 234, 234, 234, 234,
+			234, 234, 234, 234, 234, 234, 234, 234,
+			234, 234, 234, 234, 234, 234, 234, 234,
+			234, 234, 234, 234, 234, 234, 234, 234,
+			234, 234, 234, 234, 234, 234, 234, 234,
+			234, 234, 234, 234, 234, 234, 234, 234,
+			234,
+		},
+		{	/* Fourth byte table 81. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   4,   8,   12,  16,  20,  24,  28,
+			32,  36,  40,  44,  48,  52,  56,  56,
+			56,  60,  60,  64,  64,  64,  68,  72,
+			76,  80,  84,  88,  92,  96,  100, 104,
+			104, 108, 108, 112, 112, 112, 116, 120,
+			120, 120, 120, 124, 128, 132, 136, 136,
+			136, 140, 144, 148, 152, 156, 160, 164,
+			168, 172, 176, 180, 184, 188, 192, 196,
+			200, 200, 200, 200, 200, 200, 200, 200,
+			200, 200, 200, 200, 200, 200, 200, 200,
+			200, 200, 200, 200, 200, 200, 200, 200,
+			200, 200, 200, 200, 200, 200, 200, 200,
+			200, 200, 200, 200, 200, 200, 200, 200,
+			200, 200, 200, 200, 200, 200, 200, 200,
+			200, 200, 200, 200, 200, 200, 200, 200,
+			200, 200, 200, 200, 200, 200, 200, 200,
+			200,
+		},
+		{	/* Fourth byte table 82. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   4,   8,   12,  16,  20,  24,  28,
+			32,  36,  40,  44,  48,  52,  56,  60,
+			64,  68,  72,  76,  80,  84,  88,  92,
+			96,  100, 104, 108, 112, 116, 120, 124,
+			128, 132, 136, 140, 144, 148, 152, 156,
+			160, 164, 168, 172, 172, 172, 172, 172,
+			172, 176, 180, 184, 188, 192, 196, 200,
+			204, 208, 212, 216, 220, 224, 228, 232,
+			236, 236, 236, 236, 236, 236, 236, 236,
+			236, 236, 236, 236, 236, 236, 236, 236,
+			236, 236, 236, 236, 236, 236, 236, 236,
+			236, 236, 236, 236, 236, 236, 236, 236,
+			236, 236, 236, 236, 236, 236, 236, 236,
+			236, 236, 236, 236, 236, 236, 236, 236,
+			236, 236, 236, 236, 236, 236, 236, 236,
+			236, 236, 236, 236, 236, 236, 236, 236,
+			236,
+		},
+		{	/* Fourth byte table 83. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   4,   8,   12,  16,  20,  24,  28,
+			32,  36,  40,  44,  48,  52,  56,  60,
+			65,  70,  75,  79,  83,  87,  92,  97,
+			102, 106, 110, 110, 110, 110, 110, 110,
+			110, 110, 110, 110, 110, 110, 110, 110,
+			110, 110, 110, 110, 110, 110, 110, 110,
+			110, 110, 110, 110, 110, 110, 110, 110,
+			110, 110, 110, 110, 110, 110, 110, 110,
+			110, 110, 110, 110, 110, 110, 110, 110,
+			110, 110, 110, 110, 110, 110, 110, 110,
+			110, 110, 110, 110, 110, 110, 110, 110,
+			110, 110, 110, 110, 110, 110, 110, 110,
+			110, 110, 110, 110, 110, 110, 110, 110,
+			110, 110, 110, 110, 110, 110, 110, 110,
+			110, 110, 110, 110, 110, 110, 110, 110,
+			110, 110, 110, 110, 110, 110, 110, 110,
+			110,
+		},
+		{	/* Fourth byte table 84. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   2,   4,   6,   9,   12,  14,  16,
+			16,  16,  16,  16,  16,  16,  16,  16,
+			16,  16,  16,  16,  20,  24,  28,  32,
+			36,  36,  36,  36,  36,  36,  41,  41,
+			46,  48,  50,  52,  54,  56,  58,  60,
+			62,  64,  65,  70,  75,  82,  89,  94,
+			99,  104, 109, 114, 119, 124, 129, 134,
+			134, 139, 144, 149, 154, 159, 159, 164,
+			164, 164, 164, 164, 164, 164, 164, 164,
+			164, 164, 164, 164, 164, 164, 164, 164,
+			164, 164, 164, 164, 164, 164, 164, 164,
+			164, 164, 164, 164, 164, 164, 164, 164,
+			164, 164, 164, 164, 164, 164, 164, 164,
+			164, 164, 164, 164, 164, 164, 164, 164,
+			164, 164, 164, 164, 164, 164, 164, 164,
+			164, 164, 164, 164, 164, 164, 164, 164,
+			164,
+		},
+		{	/* Fourth byte table 85. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   5,   10,  10,  15,  20,  20,  25,
+			30,  35,  40,  45,  50,  55,  60,  65,
+			69,  71,  73,  75,  77,  79,  81,  83,
+			85,  87,  89,  91,  93,  95,  97,  99,
+			101, 103, 105, 107, 109, 111, 113, 115,
+			117, 119, 121, 123, 125, 127, 129, 131,
+			133, 135, 137, 139, 141, 143, 145, 147,
+			149, 151, 153, 155, 157, 159, 161, 163,
+			165, 165, 165, 165, 165, 165, 165, 165,
+			165, 165, 165, 165, 165, 165, 165, 165,
+			165, 165, 165, 165, 165, 165, 165, 165,
+			165, 165, 165, 165, 165, 165, 165, 165,
+			165, 165, 165, 165, 165, 165, 165, 165,
+			165, 165, 165, 165, 165, 165, 165, 165,
+			165, 165, 165, 165, 165, 165, 165, 165,
+			165, 165, 165, 165, 165, 165, 165, 165,
+			165,
+		},
+		{	/* Fourth byte table 86. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   2,   4,   6,   8,   10,  12,  14,
+			16,  18,  20,  22,  24,  26,  28,  30,
+			32,  34,  36,  38,  40,  42,  44,  46,
+			48,  50,  52,  54,  56,  58,  60,  62,
+			64,  66,  68,  70,  72,  76,  80,  82,
+			84,  86,  88,  90,  92,  94,  96,  98,
+			100, 104, 108, 108, 108, 108, 108, 108,
+			108, 108, 108, 108, 108, 108, 108, 108,
+			108, 108, 108, 108, 108, 108, 108, 108,
+			108, 108, 108, 108, 108, 108, 108, 108,
+			108, 108, 108, 108, 108, 108, 108, 108,
+			108, 108, 108, 108, 108, 108, 108, 108,
+			108, 108, 108, 108, 108, 108, 108, 108,
+			108, 108, 108, 108, 108, 108, 108, 108,
+			108, 108, 108, 108, 108, 108, 108, 108,
+			108, 108, 108, 108, 108, 108, 108, 108,
+			108,
+		},
+		{	/* Fourth byte table 87. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   2,   4,   6,   8,
+			10,  12,  14,  16,  18,  20,  24,  26,
+			28,  30,  32,  34,  36,  38,  40,  42,
+			44,  46,  48,  54,  60,  66,  72,  78,
+			84,  90,  96,  102, 108, 114, 120, 126,
+			132, 138, 144, 150, 156, 158, 160, 162,
+			164, 164, 164, 164, 164, 164, 164, 164,
+			164, 164, 164, 164, 164, 164, 164, 164,
+			164, 164, 164, 164, 164, 164, 164, 164,
+			164, 164, 164, 164, 164, 164, 164, 164,
+			164, 164, 164, 164, 164, 164, 164, 164,
+			164, 164, 164, 164, 164, 164, 164, 164,
+			164, 164, 164, 164, 164, 164, 164, 164,
+			164, 164, 164, 164, 164, 164, 164, 164,
+			164,
+		},
+		{	/* Fourth byte table 88. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   4,   8,   12,  16,  20,  24,  28,
+			32,  36,  40,  44,  48,  52,  56,  60,
+			64,  68,  72,  76,  80,  84,  88,  92,
+			96,  100, 104, 108, 112, 116, 120, 124,
+			128, 132, 136, 140, 144, 148, 152, 156,
+			160, 164, 168, 172, 176, 180, 184, 188,
+			192, 196, 200, 204, 208, 212, 216, 220,
+			224, 228, 232, 236, 240, 244, 248, 248,
+			248, 248, 248, 248, 248, 248, 248, 248,
+			248, 248, 248, 248, 248, 248, 248, 248,
+			248, 248, 248, 248, 248, 248, 248, 248,
+			248, 248, 248, 248, 248, 248, 248, 248,
+			248, 248, 248, 248, 248, 248, 248, 248,
+			248, 248, 248, 248, 248, 248, 248, 248,
+			248, 248, 248, 248, 248, 248, 248, 248,
+			248, 248, 248, 248, 248, 248, 248, 248,
+			248,
+		},
+		{	/* Fourth byte table 89. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   6,   12,  18,  24,  30,  36,  42,
+			48,  48,  48,  48,  48,  48,  48,  48,
+			48,  48,  48,  48,  48,  48,  48,  48,
+			48,  48,  48,  48,  48,  48,  48,  48,
+			48,  48,  48,  48,  48,  48,  48,  48,
+			48,  48,  48,  48,  48,  48,  48,  48,
+			48,  54,  60,  68,  76,  84,  92,  100,
+			108, 116, 122, 155, 170, 178, 178, 178,
+			178, 178, 178, 178, 178, 178, 178, 178,
+			178, 178, 178, 178, 178, 178, 178, 178,
+			178, 178, 178, 178, 178, 178, 178, 178,
+			178, 178, 178, 178, 178, 178, 178, 178,
+			178, 178, 178, 178, 178, 178, 178, 178,
+			178, 178, 178, 178, 178, 178, 178, 178,
+			178, 178, 178, 178, 178, 178, 178, 178,
+			178, 178, 178, 178, 178, 178, 178, 178,
+			178,
+		},
+		{	/* Fourth byte table 90. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   1,   4,   7,   8,   9,   10,  11,
+			14,  17,  20,  20,  20,  20,  20,  20,
+			20,  20,  20,  20,  20,  20,  20,  20,
+			20,  20,  20,  20,  20,  20,  20,  20,
+			20,  22,  25,  28,  29,  30,  31,  32,
+			33,  34,  37,  40,  43,  46,  49,  52,
+			55,  55,  55,  55,  55,  55,  55,  55,
+			55,  55,  55,  55,  55,  55,  55,  55,
+			55,  55,  55,  55,  55,  55,  55,  55,
+			55,  55,  55,  55,  55,  55,  55,  55,
+			55,  55,  55,  55,  55,  55,  55,  55,
+			55,  55,  55,  55,  55,  55,  55,  55,
+			55,  55,  55,  55,  55,  55,  55,  55,
+			55,  55,  55,  55,  55,  55,  55,  55,
+			55,
+		},
+		{	/* Fourth byte table 91. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   3,   6,   9,   12,  15,  15,  15,
+			16,  17,  20,  23,  26,  29,  30,  31,
+			32,  33,  36,  37,  37,  38,  39,  40,
+			41,  44,  45,  46,  47,  48,  51,  54,
+			55,  56,  57,  58,  59,  60,  61,  62,
+			62,  63,  64,  65,  66,  66,  66,  66,
+			66,  69,  73,  76,  76,  79,  79,  82,
+			86,  89,  93,  96,  100, 103, 107, 110,
+			114, 114, 114, 114, 114, 114, 114, 114,
+			114, 114, 114, 114, 114, 114, 114, 114,
+			114, 114, 114, 114, 114, 114, 114, 114,
+			114, 114, 114, 114, 114, 114, 114, 114,
+			114, 114, 114, 114, 114, 114, 114, 114,
+			114, 114, 114, 114, 114, 114, 114, 114,
+			114, 114, 114, 114, 114, 114, 114, 114,
+			114, 114, 114, 114, 114, 114, 114, 114,
+			114,
+		},
+		{	/* Fourth byte table 92. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   2,   6,   10,  14,  18,  22,  26,
+			30,  34,  38,  42,  46,  50,  52,  54,
+			56,  58,  60,  62,  64,  66,  68,  70,
+			72,  74,  76,  78,  80,  82,  84,  86,
+			88,  90,  92,  94,  96,  98,  100, 102,
+			104, 106, 108, 110, 112, 114, 116, 118,
+			120, 122, 124, 126, 128, 130, 132, 134,
+			136, 138, 140, 142, 144, 146, 148, 150,
+			152, 152, 152, 152, 152, 152, 152, 152,
+			152, 152, 152, 152, 152, 152, 152, 152,
+			152, 152, 152, 152, 152, 152, 152, 152,
+			152, 152, 152, 152, 152, 152, 152, 152,
+			152, 152, 152, 152, 152, 152, 152, 152,
+			152, 152, 152, 152, 152, 152, 152, 152,
+			152, 152, 152, 152, 152, 152, 152, 152,
+			152, 152, 152, 152, 152, 152, 152, 152,
+			152,
+		},
+		{	/* Fourth byte table 93. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   2,   4,   6,   8,   10,  12,  14,
+			16,  18,  20,  22,  24,  26,  28,  30,
+			32,  34,  36,  38,  40,  42,  44,  46,
+			48,  50,  52,  54,  56,  58,  60,  62,
+			64,  66,  68,  70,  72,  74,  76,  78,
+			80,  82,  84,  86,  88,  90,  92,  94,
+			96,  98,  100, 102, 104, 106, 112, 118,
+			124, 130, 136, 142, 146, 150, 150, 150,
+			150, 150, 150, 150, 150, 150, 150, 150,
+			150, 150, 150, 150, 150, 150, 150, 150,
+			150, 150, 150, 150, 150, 150, 150, 150,
+			150, 150, 150, 150, 150, 150, 150, 150,
+			150, 150, 150, 150, 150, 150, 150, 150,
+			150, 150, 150, 150, 150, 150, 150, 150,
+			150, 150, 150, 150, 150, 150, 150, 150,
+			150, 150, 150, 150, 150, 150, 150, 150,
+			150,
+		},
+		{	/* Fourth byte table 94. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   1,   2,   3,   4,   5,   6,
+			7,   8,   9,   10,  11,  12,  13,  14,
+			15,  16,  17,  18,  19,  20,  21,  22,
+			23,  24,  25,  26,  27,  28,  29,  30,
+			31,  32,  33,  34,  35,  36,  37,  38,
+			39,  40,  41,  42,  43,  44,  45,  46,
+			47,  48,  49,  50,  51,  52,  53,  54,
+			55,  56,  57,  58,  59,  60,  61,  62,
+			63,  63,  63,  63,  63,  63,  63,  63,
+			63,  63,  63,  63,  63,  63,  63,  63,
+			63,  63,  63,  63,  63,  63,  63,  63,
+			63,  63,  63,  63,  63,  63,  63,  63,
+			63,  63,  63,  63,  63,  63,  63,  63,
+			63,  63,  63,  63,  63,  63,  63,  63,
+			63,  63,  63,  63,  63,  63,  63,  63,
+			63,  63,  63,  63,  63,  63,  63,  63,
+			63,
+		},
+		{	/* Fourth byte table 95. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   1,   2,   3,   4,   5,   6,   7,
+			8,   9,   10,  11,  12,  13,  14,  15,
+			16,  17,  18,  19,  20,  21,  22,  23,
+			24,  25,  26,  27,  28,  29,  30,  31,
+			34,  37,  40,  43,  46,  49,  52,  55,
+			58,  61,  64,  67,  70,  73,  76,  79,
+			82,  85,  88,  91,  94,  97,  100, 103,
+			106, 109, 112, 115, 118, 121, 124, 127,
+			130, 130, 130, 130, 130, 130, 130, 130,
+			130, 130, 130, 130, 130, 130, 130, 130,
+			130, 130, 130, 130, 130, 130, 130, 130,
+			130, 130, 130, 130, 130, 130, 130, 130,
+			130, 130, 130, 130, 130, 130, 130, 130,
+			130, 130, 130, 130, 130, 130, 130, 130,
+			130, 130, 130, 130, 130, 130, 130, 130,
+			130, 130, 130, 130, 130, 130, 130, 130,
+			130,
+		},
+		{	/* Fourth byte table 96. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   3,   6,   9,   12,  15,  18,  21,
+			24,  27,  30,  33,  36,  39,  42,  45,
+			48,  51,  54,  57,  60,  63,  66,  69,
+			72,  75,  78,  81,  84,  87,  90,  93,
+			96,  99,  102, 105, 108, 111, 114, 117,
+			120, 123, 126, 129, 132, 135, 138, 141,
+			144, 147, 150, 153, 156, 159, 162, 165,
+			168, 171, 174, 177, 180, 183, 186, 189,
+			189, 189, 189, 189, 189, 189, 189, 189,
+			189, 189, 189, 189, 189, 189, 189, 189,
+			189, 189, 189, 189, 189, 189, 189, 189,
+			189, 189, 189, 189, 189, 189, 189, 189,
+			189, 189, 189, 189, 189, 189, 189, 189,
+			189, 189, 189, 189, 189, 189, 189, 189,
+			189, 189, 189, 189, 189, 189, 189, 189,
+			189, 189, 189, 189, 189, 189, 189, 189,
+			189,
+		},
+		{	/* Fourth byte table 97. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   3,   6,   9,   12,  15,
+			18,  18,  18,  21,  24,  27,  30,  33,
+			36,  36,  36,  39,  42,  45,  48,  51,
+			54,  54,  54,  57,  60,  63,  63,  63,
+			63,  65,  67,  69,  72,  74,  76,  79,
+			79,  82,  85,  88,  91,  94,  97,  100,
+			100, 100, 100, 100, 100, 100, 100, 100,
+			100, 100, 100, 100, 100, 100, 100, 100,
+			100, 100, 100, 100, 100, 100, 100, 100,
+			100, 100, 100, 100, 100, 100, 100, 100,
+			100, 100, 100, 100, 100, 100, 100, 100,
+			100, 100, 100, 100, 100, 100, 100, 100,
+			100, 100, 100, 100, 100, 100, 100, 100,
+			100, 100, 100, 100, 100, 100, 100, 100,
+			100, 100, 100, 100, 100, 100, 100, 100,
+			100, 100, 100, 100, 100, 100, 100, 100,
+			100,
+		},
+		{	/* Fourth byte table 98. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   9,
+			18,  31,  44,  57,  70,  83,  83,  83,
+			83,  83,  83,  83,  83,  83,  83,  83,
+			83,  83,  83,  83,  83,  83,  83,  83,
+			83,  83,  83,  83,  83,  83,  83,  83,
+			83,  83,  83,  83,  83,  83,  83,  83,
+			83,  83,  83,  83,  83,  83,  83,  83,
+			83,  83,  83,  83,  83,  83,  83,  83,
+			83,  83,  83,  83,  83,  83,  83,  83,
+			83,  83,  83,  83,  83,  83,  83,  83,
+			83,  83,  83,  83,  83,  83,  83,  83,
+			83,  83,  83,  83,  83,  83,  83,  83,
+			83,  83,  83,  83,  83,  83,  83,  83,
+			83,
+		},
+		{	/* Fourth byte table 99. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   9,   18,  31,  44,
+			57,  57,  57,  57,  57,  57,  57,  57,
+			57,  57,  57,  57,  57,  57,  57,  57,
+			57,  57,  57,  57,  57,  57,  57,  57,
+			57,  57,  57,  57,  57,  57,  57,  57,
+			57,  57,  57,  57,  57,  57,  57,  57,
+			57,  57,  57,  57,  57,  57,  57,  57,
+			57,  57,  57,  57,  57,  57,  57,  57,
+			57,  57,  57,  57,  57,  57,  57,  57,
+			57,
+		},
+		{	/* Fourth byte table 100. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   13,  13,  13,  13,  13,  13,  13,
+			13,  13,  13,  13,  13,  13,  13,  13,
+			13,  13,  13,  13,  13,  13,  13,  13,
+			13,  13,  13,  13,  13,  13,  13,  13,
+			13,  13,  13,  13,  13,  13,  13,  13,
+			13,  13,  13,  13,  13,  13,  13,  13,
+			13,  13,  13,  13,  13,  13,  13,  13,
+			13,  13,  13,  13,  13,  13,  13,  13,
+			13,  13,  13,  13,  13,  13,  13,  13,
+			13,  13,  13,  13,  13,  13,  13,  13,
+			13,  13,  13,  13,  13,  13,  13,  13,
+			13,  13,  13,  13,  13,  13,  13,  13,
+			13,  13,  13,  13,  13,  13,  13,  13,
+			13,  13,  13,  13,  13,  13,  13,  13,
+			13,  13,  13,  13,  13,  13,  13,  13,
+			13,  13,  13,  13,  13,  13,  13,  13,
+			13,
+		},
+		{	/* Fourth byte table 101. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   1,   2,   3,   4,   5,   6,   7,
+			8,   9,   10,  11,  12,  13,  14,  15,
+			16,  17,  18,  19,  20,  21,  22,  23,
+			24,  25,  26,  27,  28,  29,  30,  31,
+			32,  33,  34,  35,  36,  37,  38,  39,
+			40,  41,  42,  43,  44,  45,  46,  47,
+			48,  49,  50,  51,  52,  53,  54,  55,
+			56,  57,  58,  59,  60,  61,  62,  63,
+			64,  64,  64,  64,  64,  64,  64,  64,
+			64,  64,  64,  64,  64,  64,  64,  64,
+			64,  64,  64,  64,  64,  64,  64,  64,
+			64,  64,  64,  64,  64,  64,  64,  64,
+			64,  64,  64,  64,  64,  64,  64,  64,
+			64,  64,  64,  64,  64,  64,  64,  64,
+			64,  64,  64,  64,  64,  64,  64,  64,
+			64,  64,  64,  64,  64,  64,  64,  64,
+			64,
+		},
+		{	/* Fourth byte table 102. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   1,   2,   3,   4,   5,   6,   7,
+			8,   9,   10,  11,  12,  13,  14,  15,
+			16,  17,  18,  19,  20,  21,  21,  22,
+			23,  24,  25,  26,  27,  28,  29,  30,
+			31,  32,  33,  34,  35,  36,  37,  38,
+			39,  40,  41,  42,  43,  44,  45,  46,
+			47,  48,  49,  50,  51,  52,  53,  54,
+			55,  56,  57,  58,  59,  60,  61,  62,
+			63,  63,  63,  63,  63,  63,  63,  63,
+			63,  63,  63,  63,  63,  63,  63,  63,
+			63,  63,  63,  63,  63,  63,  63,  63,
+			63,  63,  63,  63,  63,  63,  63,  63,
+			63,  63,  63,  63,  63,  63,  63,  63,
+			63,  63,  63,  63,  63,  63,  63,  63,
+			63,  63,  63,  63,  63,  63,  63,  63,
+			63,  63,  63,  63,  63,  63,  63,  63,
+			63,
+		},
+		{	/* Fourth byte table 103. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   1,   2,   3,   4,   5,   6,   7,
+			8,   9,   10,  11,  12,  13,  14,  15,
+			16,  17,  18,  19,  20,  21,  22,  23,
+			24,  25,  26,  27,  28,  29,  29,  30,
+			31,  31,  31,  32,  32,  32,  33,  34,
+			34,  34,  35,  36,  37,  38,  38,  39,
+			40,  41,  42,  43,  44,  45,  46,  47,
+			48,  49,  50,  50,  51,  51,  52,  53,
+			54,  54,  54,  54,  54,  54,  54,  54,
+			54,  54,  54,  54,  54,  54,  54,  54,
+			54,  54,  54,  54,  54,  54,  54,  54,
+			54,  54,  54,  54,  54,  54,  54,  54,
+			54,  54,  54,  54,  54,  54,  54,  54,
+			54,  54,  54,  54,  54,  54,  54,  54,
+			54,  54,  54,  54,  54,  54,  54,  54,
+			54,  54,  54,  54,  54,  54,  54,  54,
+			54,
+		},
+		{	/* Fourth byte table 104. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   1,   2,   3,   4,   4,   5,   6,
+			7,   8,   9,   10,  11,  12,  13,  14,
+			15,  16,  17,  18,  19,  20,  21,  22,
+			23,  24,  25,  26,  27,  28,  29,  30,
+			31,  32,  33,  34,  35,  36,  37,  38,
+			39,  40,  41,  42,  43,  44,  45,  46,
+			47,  48,  49,  50,  51,  52,  53,  54,
+			55,  56,  57,  58,  59,  60,  61,  62,
+			63,  63,  63,  63,  63,  63,  63,  63,
+			63,  63,  63,  63,  63,  63,  63,  63,
+			63,  63,  63,  63,  63,  63,  63,  63,
+			63,  63,  63,  63,  63,  63,  63,  63,
+			63,  63,  63,  63,  63,  63,  63,  63,
+			63,  63,  63,  63,  63,  63,  63,  63,
+			63,  63,  63,  63,  63,  63,  63,  63,
+			63,  63,  63,  63,  63,  63,  63,  63,
+			63,
+		},
+		{	/* Fourth byte table 105. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   1,   2,   3,   4,   5,   6,   6,
+			7,   8,   9,   10,  10,  10,  11,  12,
+			13,  14,  15,  16,  17,  18,  18,  19,
+			20,  21,  22,  23,  24,  25,  25,  26,
+			27,  28,  29,  30,  31,  32,  33,  34,
+			35,  36,  37,  38,  39,  40,  41,  42,
+			43,  44,  45,  46,  47,  48,  49,  50,
+			51,  52,  53,  53,  54,  55,  56,  57,
+			57,  57,  57,  57,  57,  57,  57,  57,
+			57,  57,  57,  57,  57,  57,  57,  57,
+			57,  57,  57,  57,  57,  57,  57,  57,
+			57,  57,  57,  57,  57,  57,  57,  57,
+			57,  57,  57,  57,  57,  57,  57,  57,
+			57,  57,  57,  57,  57,  57,  57,  57,
+			57,  57,  57,  57,  57,  57,  57,  57,
+			57,  57,  57,  57,  57,  57,  57,  57,
+			57,
+		},
+		{	/* Fourth byte table 106. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   1,   2,   3,   4,   5,   5,   6,
+			6,   6,   6,   7,   8,   9,   10,  11,
+			12,  13,  13,  14,  15,  16,  17,  18,
+			19,  20,  21,  22,  23,  24,  25,  26,
+			27,  28,  29,  30,  31,  32,  33,  34,
+			35,  36,  37,  38,  39,  40,  41,  42,
+			43,  44,  45,  46,  47,  48,  49,  50,
+			51,  52,  53,  54,  55,  56,  57,  58,
+			59,  59,  59,  59,  59,  59,  59,  59,
+			59,  59,  59,  59,  59,  59,  59,  59,
+			59,  59,  59,  59,  59,  59,  59,  59,
+			59,  59,  59,  59,  59,  59,  59,  59,
+			59,  59,  59,  59,  59,  59,  59,  59,
+			59,  59,  59,  59,  59,  59,  59,  59,
+			59,  59,  59,  59,  59,  59,  59,  59,
+			59,  59,  59,  59,  59,  59,  59,  59,
+			59,
+		},
+		{	/* Fourth byte table 107. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   1,   2,   3,   4,   5,   6,   7,
+			8,   9,   10,  11,  12,  13,  14,  15,
+			16,  17,  18,  19,  20,  21,  22,  23,
+			24,  25,  26,  27,  28,  29,  30,  31,
+			32,  33,  34,  35,  36,  37,  38,  39,
+			40,  41,  42,  43,  44,  45,  46,  47,
+			48,  49,  50,  51,  52,  53,  54,  55,
+			56,  57,  58,  59,  60,  61,  62,  63,
+			64,  64,  64,  64,  64,  64,  64,  64,
+			64,  64,  64,  64,  64,  64,  64,  64,
+			64,  64,  64,  64,  64,  64,  64,  64,
+			64,  64,  64,  64,  64,  64,  64,  64,
+			64,  64,  64,  64,  64,  64,  64,  64,
+			64,  64,  64,  64,  64,  64,  64,  64,
+			64,  64,  64,  64,  64,  64,  64,  64,
+			64,  64,  64,  64,  64,  64,  64,  64,
+			64,
+		},
+		{	/* Fourth byte table 108. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   1,   2,   3,   4,   5,   6,   7,
+			8,   9,   10,  11,  12,  13,  14,  15,
+			16,  17,  18,  19,  20,  21,  22,  23,
+			24,  25,  26,  27,  28,  29,  30,  31,
+			32,  33,  34,  35,  36,  37,  38,  39,
+			40,  41,  42,  43,  44,  45,  46,  47,
+			48,  49,  50,  51,  52,  53,  54,  55,
+			56,  57,  58,  59,  60,  61,  62,  63,
+			64,  64,  64,  64,  64,  64,  64,  64,
+			64,  64,  64,  64,  64,  64,  64,  64,
+			64,  64,  64,  64,  64,  64,  64,  64,
+			64,  64,  64,  64,  64,  64,  64,  64,
+			64,  64,  64,  64,  64,  64,  64,  64,
+			64,  64,  64,  64,  64,  64,  64,  64,
+			64,  64,  64,  64,  64,  64,  64,  64,
+			64,  64,  64,  64,  64,  64,  64,  64,
+			64,
+		},
+		{	/* Fourth byte table 109. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   1,   2,   3,   4,   5,   6,   7,
+			8,   9,   10,  11,  12,  13,  14,  15,
+			16,  17,  18,  19,  20,  21,  22,  23,
+			24,  25,  26,  27,  28,  29,  30,  31,
+			32,  33,  34,  35,  36,  37,  38,  39,
+			40,  41,  42,  43,  44,  45,  46,  47,
+			48,  49,  50,  51,  52,  53,  54,  55,
+			56,  57,  58,  59,  60,  61,  62,  63,
+			64,  64,  64,  64,  64,  64,  64,  64,
+			64,  64,  64,  64,  64,  64,  64,  64,
+			64,  64,  64,  64,  64,  64,  64,  64,
+			64,  64,  64,  64,  64,  64,  64,  64,
+			64,  64,  64,  64,  64,  64,  64,  64,
+			64,  64,  64,  64,  64,  64,  64,  64,
+			64,  64,  64,  64,  64,  64,  64,  64,
+			64,  64,  64,  64,  64,  64,  64,  64,
+			64,
+		},
+		{	/* Fourth byte table 110. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   1,   2,   3,   4,   5,   6,   7,
+			8,   9,   10,  11,  12,  13,  14,  15,
+			16,  17,  18,  19,  20,  21,  22,  23,
+			24,  25,  26,  27,  28,  29,  30,  31,
+			32,  33,  34,  35,  36,  37,  38,  39,
+			40,  41,  42,  43,  44,  45,  46,  47,
+			48,  49,  50,  51,  52,  53,  54,  55,
+			56,  57,  58,  59,  60,  61,  62,  63,
+			64,  64,  64,  64,  64,  64,  64,  64,
+			64,  64,  64,  64,  64,  64,  64,  64,
+			64,  64,  64,  64,  64,  64,  64,  64,
+			64,  64,  64,  64,  64,  64,  64,  64,
+			64,  64,  64,  64,  64,  64,  64,  64,
+			64,  64,  64,  64,  64,  64,  64,  64,
+			64,  64,  64,  64,  64,  64,  64,  64,
+			64,  64,  64,  64,  64,  64,  64,  64,
+			64,
+		},
+		{	/* Fourth byte table 111. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   1,   2,   3,   4,   5,   6,   7,
+			8,   9,   10,  11,  12,  13,  14,  15,
+			16,  17,  18,  19,  20,  21,  22,  23,
+			24,  25,  26,  27,  28,  29,  30,  31,
+			32,  33,  34,  35,  36,  38,  40,  40,
+			40,  42,  44,  46,  48,  50,  52,  54,
+			56,  58,  60,  62,  64,  66,  68,  70,
+			72,  74,  76,  78,  80,  82,  84,  86,
+			88,  88,  88,  88,  88,  88,  88,  88,
+			88,  88,  88,  88,  88,  88,  88,  88,
+			88,  88,  88,  88,  88,  88,  88,  88,
+			88,  88,  88,  88,  88,  88,  88,  88,
+			88,  88,  88,  88,  88,  88,  88,  88,
+			88,  88,  88,  88,  88,  88,  88,  88,
+			88,  88,  88,  88,  88,  88,  88,  88,
+			88,  88,  88,  88,  88,  88,  88,  88,
+			88,
+		},
+		{	/* Fourth byte table 112. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   2,   5,   7,   9,   11,  13,  15,
+			17,  19,  21,  23,  25,  27,  29,  31,
+			33,  35,  37,  39,  41,  43,  45,  47,
+			49,  51,  53,  55,  58,  60,  62,  64,
+			66,  68,  70,  72,  74,  76,  78,  80,
+			82,  84,  86,  88,  90,  92,  94,  96,
+			98,  100, 102, 104, 106, 108, 110, 112,
+			114, 116, 118, 120, 123, 125, 127, 129,
+			131, 131, 131, 131, 131, 131, 131, 131,
+			131, 131, 131, 131, 131, 131, 131, 131,
+			131, 131, 131, 131, 131, 131, 131, 131,
+			131, 131, 131, 131, 131, 131, 131, 131,
+			131, 131, 131, 131, 131, 131, 131, 131,
+			131, 131, 131, 131, 131, 131, 131, 131,
+			131, 131, 131, 131, 131, 131, 131, 131,
+			131, 131, 131, 131, 131, 131, 131, 131,
+			131,
+		},
+		{	/* Fourth byte table 113. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   2,   4,   6,   8,   10,  12,  14,
+			16,  18,  20,  22,  24,  26,  28,  30,
+			32,  34,  36,  38,  40,  42,  45,  47,
+			49,  51,  53,  55,  57,  59,  61,  63,
+			65,  67,  69,  71,  73,  75,  77,  79,
+			81,  83,  85,  87,  89,  91,  93,  95,
+			97,  99,  101, 103, 105, 107, 110, 112,
+			114, 116, 118, 120, 122, 124, 126, 128,
+			130, 130, 130, 130, 130, 130, 130, 130,
+			130, 130, 130, 130, 130, 130, 130, 130,
+			130, 130, 130, 130, 130, 130, 130, 130,
+			130, 130, 130, 130, 130, 130, 130, 130,
+			130, 130, 130, 130, 130, 130, 130, 130,
+			130, 130, 130, 130, 130, 130, 130, 130,
+			130, 130, 130, 130, 130, 130, 130, 130,
+			130, 130, 130, 130, 130, 130, 130, 130,
+			130,
+		},
+		{	/* Fourth byte table 114. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   2,   4,   6,   8,   10,  12,  14,
+			16,  18,  20,  22,  24,  26,  28,  30,
+			33,  35,  37,  39,  41,  43,  45,  47,
+			49,  51,  53,  55,  57,  59,  61,  63,
+			65,  67,  69,  71,  73,  75,  77,  79,
+			81,  83,  85,  87,  89,  91,  93,  95,
+			98,  100, 102, 104, 106, 108, 110, 112,
+			114, 116, 118, 120, 122, 124, 126, 128,
+			130, 130, 130, 130, 130, 130, 130, 130,
+			130, 130, 130, 130, 130, 130, 130, 130,
+			130, 130, 130, 130, 130, 130, 130, 130,
+			130, 130, 130, 130, 130, 130, 130, 130,
+			130, 130, 130, 130, 130, 130, 130, 130,
+			130, 130, 130, 130, 130, 130, 130, 130,
+			130, 130, 130, 130, 130, 130, 130, 130,
+			130, 130, 130, 130, 130, 130, 130, 130,
+			130,
+		},
+		{	/* Fourth byte table 115. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   2,   4,   6,   8,   10,  12,  14,
+			16,  18,  21,  23,  25,  27,  29,  31,
+			33,  35,  37,  39,  41,  43,  45,  47,
+			49,  51,  53,  55,  57,  59,  61,  63,
+			65,  67,  69,  71,  73,  75,  77,  79,
+			81,  83,  86,  88,  90,  92,  94,  96,
+			98,  100, 102, 104, 106, 108, 110, 112,
+			114, 116, 118, 120, 122, 124, 126, 128,
+			130, 130, 130, 130, 130, 130, 130, 130,
+			130, 130, 130, 130, 130, 130, 130, 130,
+			130, 130, 130, 130, 130, 130, 130, 130,
+			130, 130, 130, 130, 130, 130, 130, 130,
+			130, 130, 130, 130, 130, 130, 130, 130,
+			130, 130, 130, 130, 130, 130, 130, 130,
+			130, 130, 130, 130, 130, 130, 130, 130,
+			130, 130, 130, 130, 130, 130, 130, 130,
+			130,
+		},
+		{	/* Fourth byte table 116. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   2,   4,   6,   9,   11,  13,  15,
+			17,  19,  21,  23,  25,  25,  25,  26,
+			27,  28,  29,  30,  31,  32,  33,  34,
+			35,  36,  37,  38,  39,  40,  41,  42,
+			43,  44,  45,  46,  47,  48,  49,  50,
+			51,  52,  53,  54,  55,  56,  57,  58,
+			59,  60,  61,  62,  63,  64,  65,  66,
+			67,  68,  69,  70,  71,  72,  73,  74,
+			75,  75,  75,  75,  75,  75,  75,  75,
+			75,  75,  75,  75,  75,  75,  75,  75,
+			75,  75,  75,  75,  75,  75,  75,  75,
+			75,  75,  75,  75,  75,  75,  75,  75,
+			75,  75,  75,  75,  75,  75,  75,  75,
+			75,  75,  75,  75,  75,  75,  75,  75,
+			75,  75,  75,  75,  75,  75,  75,  75,
+			75,  75,  75,  75,  75,  75,  75,  75,
+			75,
+		},
+		{	/* Fourth byte table 117. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   4,   9,   13,  17,  21,  25,  29,
+			33,  37,  42,  46,  50,  54,  58,  62,
+			66,  71,  75,  80,  85,  90,  94,  98,
+			102, 106, 110, 114, 118, 122, 127, 127,
+			127, 127, 127, 127, 127, 127, 127, 127,
+			127, 127, 127, 127, 127, 127, 127, 127,
+			127, 127, 127, 127, 127, 127, 127, 127,
+			127, 127, 127, 127, 127, 127, 127, 127,
+			127, 127, 127, 127, 127, 127, 127, 127,
+			127, 127, 127, 127, 127, 127, 127, 127,
+			127, 127, 127, 127, 127, 127, 127, 127,
+			127, 127, 127, 127, 127, 127, 127, 127,
+			127, 127, 127, 127, 127, 127, 127, 127,
+			127, 127, 127, 127, 127, 127, 127, 127,
+			127, 127, 127, 127, 127, 127, 127, 127,
+			127, 127, 127, 127, 127, 127, 127, 127,
+			127,
+		},
+	},
+};
+
+static const uint16_t u8_decomp_b4_16bit_tbl[2][30][257] = {
+	{
+		{	/* Fourth byte 16-bit table 0. */
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    4,    8,    12,   16,   20,   24,   28,
+			32,   38,   44,   48,   52,   56,   60,   64,
+			68,   72,   76,   80,   84,   90,   96,   102,
+			108,  112,  116,  120,  124,  130,  136,  140,
+			144,  148,  152,  156,  160,  164,  168,  172,
+			176,  180,  184,  188,  192,  196,  200,  206,
+			212,  216,  220,  224,  228,  232,  236,  240,
+			244,  250,  256,  260,  264,  268,  272,  276,
+			280,  280,  280,  280,  280,  280,  280,  280,
+			280,  280,  280,  280,  280,  280,  280,  280,
+			280,  280,  280,  280,  280,  280,  280,  280,
+			280,  280,  280,  280,  280,  280,  280,  280,
+			280,  280,  280,  280,  280,  280,  280,  280,
+			280,  280,  280,  280,  280,  280,  280,  280,
+			280,  280,  280,  280,  280,  280,  280,  280,
+			280,  280,  280,  280,  280,  280,  280,  280,
+			280,
+		},
+		{	/* Fourth byte 16-bit table 1. */
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    4,    8,    12,   16,   20,   24,   28,
+			32,   36,   40,   44,   48,   54,   60,   66,
+			72,   78,   84,   90,   96,   100,  104,  108,
+			112,  116,  120,  124,  128,  134,  140,  144,
+			148,  152,  156,  160,  164,  170,  176,  182,
+			188,  194,  200,  204,  208,  212,  216,  220,
+			224,  228,  232,  236,  240,  244,  248,  252,
+			256,  262,  268,  274,  280,  284,  288,  292,
+			296,  296,  296,  296,  296,  296,  296,  296,
+			296,  296,  296,  296,  296,  296,  296,  296,
+			296,  296,  296,  296,  296,  296,  296,  296,
+			296,  296,  296,  296,  296,  296,  296,  296,
+			296,  296,  296,  296,  296,  296,  296,  296,
+			296,  296,  296,  296,  296,  296,  296,  296,
+			296,  296,  296,  296,  296,  296,  296,  296,
+			296,  296,  296,  296,  296,  296,  296,  296,
+			296,
+		},
+		{	/* Fourth byte 16-bit table 2. */
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    4,    8,    12,   16,   20,   24,   28,
+			32,   36,   40,   44,   48,   52,   56,   60,
+			64,   68,   72,   76,   80,   84,   88,   92,
+			96,   100,  104,  107,  116,  116,  116,  116,
+			116,  120,  124,  128,  132,  138,  144,  150,
+			156,  162,  168,  174,  180,  186,  192,  198,
+			204,  210,  216,  222,  228,  234,  240,  246,
+			252,  256,  260,  264,  268,  272,  276,  282,
+			288,  288,  288,  288,  288,  288,  288,  288,
+			288,  288,  288,  288,  288,  288,  288,  288,
+			288,  288,  288,  288,  288,  288,  288,  288,
+			288,  288,  288,  288,  288,  288,  288,  288,
+			288,  288,  288,  288,  288,  288,  288,  288,
+			288,  288,  288,  288,  288,  288,  288,  288,
+			288,  288,  288,  288,  288,  288,  288,  288,
+			288,  288,  288,  288,  288,  288,  288,  288,
+			288,
+		},
+		{	/* Fourth byte 16-bit table 3. */
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    6,    12,   18,   24,   30,   36,   42,
+			48,   52,   56,   60,   64,   68,   72,   76,
+			80,   86,   92,   98,   104,  110,  116,  122,
+			128,  134,  140,  146,  152,  158,  164,  170,
+			176,  182,  188,  194,  200,  204,  208,  212,
+			216,  222,  228,  234,  240,  246,  252,  258,
+			264,  270,  276,  280,  284,  288,  292,  296,
+			300,  304,  308,  308,  308,  308,  308,  308,
+			308,  308,  308,  308,  308,  308,  308,  308,
+			308,  308,  308,  308,  308,  308,  308,  308,
+			308,  308,  308,  308,  308,  308,  308,  308,
+			308,  308,  308,  308,  308,  308,  308,  308,
+			308,  308,  308,  308,  308,  308,  308,  308,
+			308,  308,  308,  308,  308,  308,  308,  308,
+			308,  308,  308,  308,  308,  308,  308,  308,
+			308,  308,  308,  308,  308,  308,  308,  308,
+			308,
+		},
+		{	/* Fourth byte 16-bit table 4. */
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    5,    10,   17,   24,   31,   38,   45,
+			52,   57,   62,   69,   76,   83,   90,   97,
+			104,  109,  114,  121,  128,  135,  142,  142,
+			142,  147,  152,  159,  166,  173,  180,  180,
+			180,  185,  190,  197,  204,  211,  218,  225,
+			232,  237,  242,  249,  256,  263,  270,  277,
+			284,  289,  294,  301,  308,  315,  322,  329,
+			336,  341,  346,  353,  360,  367,  374,  381,
+			388,  388,  388,  388,  388,  388,  388,  388,
+			388,  388,  388,  388,  388,  388,  388,  388,
+			388,  388,  388,  388,  388,  388,  388,  388,
+			388,  388,  388,  388,  388,  388,  388,  388,
+			388,  388,  388,  388,  388,  388,  388,  388,
+			388,  388,  388,  388,  388,  388,  388,  388,
+			388,  388,  388,  388,  388,  388,  388,  388,
+			388,  388,  388,  388,  388,  388,  388,  388,
+			388,
+		},
+		{	/* Fourth byte 16-bit table 5. */
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    5,    10,   17,   24,   31,   38,   38,
+			38,   43,   48,   55,   62,   69,   76,   76,
+			76,   81,   86,   93,   100,  107,  114,  121,
+			128,  128,  133,  133,  140,  140,  147,  147,
+			154,  159,  164,  171,  178,  185,  192,  199,
+			206,  211,  216,  223,  230,  237,  244,  251,
+			258,  263,  268,  273,  278,  283,  288,  293,
+			298,  303,  308,  313,  318,  323,  328,  328,
+			328,  328,  328,  328,  328,  328,  328,  328,
+			328,  328,  328,  328,  328,  328,  328,  328,
+			328,  328,  328,  328,  328,  328,  328,  328,
+			328,  328,  328,  328,  328,  328,  328,  328,
+			328,  328,  328,  328,  328,  328,  328,  328,
+			328,  328,  328,  328,  328,  328,  328,  328,
+			328,  328,  328,  328,  328,  328,  328,  328,
+			328,  328,  328,  328,  328,  328,  328,  328,
+			328,
+		},
+		{	/* Fourth byte 16-bit table 6. */
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    7,    14,   23,   32,   41,   50,   59,
+			68,   75,   82,   91,   100,  109,  118,  127,
+			136,  143,  150,  159,  168,  177,  186,  195,
+			204,  211,  218,  227,  236,  245,  254,  263,
+			272,  279,  286,  295,  304,  313,  322,  331,
+			340,  347,  354,  363,  372,  381,  390,  399,
+			408,  413,  418,  425,  430,  437,  437,  442,
+			449,  454,  459,  464,  469,  474,  477,  480,
+			483,  483,  483,  483,  483,  483,  483,  483,
+			483,  483,  483,  483,  483,  483,  483,  483,
+			483,  483,  483,  483,  483,  483,  483,  483,
+			483,  483,  483,  483,  483,  483,  483,  483,
+			483,  483,  483,  483,  483,  483,  483,  483,
+			483,  483,  483,  483,  483,  483,  483,  483,
+			483,  483,  483,  483,  483,  483,  483,  483,
+			483,  483,  483,  483,  483,  483,  483,  483,
+			483,
+		},
+		{	/* Fourth byte 16-bit table 7. */
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    3,    14,   21,   26,   33,   33,   38,
+			45,   50,   55,   60,   65,   70,   82,   94,
+			106,  111,  116,  123,  130,  130,  130,  135,
+			142,  147,  152,  157,  162,  162,  174,  186,
+			198,  203,  208,  215,  222,  227,  232,  237,
+			244,  249,  254,  259,  264,  269,  280,  291,
+			293,  293,  293,  300,  305,  312,  312,  317,
+			324,  329,  334,  339,  344,  349,  356,  359,
+			359,  359,  359,  359,  359,  359,  359,  359,
+			359,  359,  359,  359,  359,  359,  359,  359,
+			359,  359,  359,  359,  359,  359,  359,  359,
+			359,  359,  359,  359,  359,  359,  359,  359,
+			359,  359,  359,  359,  359,  359,  359,  359,
+			359,  359,  359,  359,  359,  359,  359,  359,
+			359,  359,  359,  359,  359,  359,  359,  359,
+			359,  359,  359,  359,  359,  359,  359,  359,
+			359,
+		},
+		{	/* Fourth byte 16-bit table 8. */
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    5,    10,   15,   20,   25,   30,   35,
+			40,   45,   50,   55,   60,   65,   70,   78,
+			86,   94,   102,  110,  118,  126,  134,  142,
+			150,  158,  166,  174,  182,  190,  190,  190,
+			190,  195,  200,  205,  210,  215,  220,  225,
+			230,  235,  240,  245,  250,  255,  260,  265,
+			270,  275,  280,  285,  290,  295,  300,  305,
+			310,  315,  320,  325,  330,  335,  340,  345,
+			350,  350,  350,  350,  350,  350,  350,  350,
+			350,  350,  350,  350,  350,  350,  350,  350,
+			350,  350,  350,  350,  350,  350,  350,  350,
+			350,  350,  350,  350,  350,  350,  350,  350,
+			350,  350,  350,  350,  350,  350,  350,  350,
+			350,  350,  350,  350,  350,  350,  350,  350,
+			350,  350,  350,  350,  350,  350,  350,  350,
+			350,  350,  350,  350,  350,  350,  350,  350,
+			350,
+		},
+		{	/* Fourth byte 16-bit table 9. */
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    15,   27,   42,   51,   66,   75,   84,
+			102,  114,  123,  132,  141,  153,  165,  177,
+			189,  201,  213,  225,  243,  249,  267,  285,
+			300,  312,  330,  348,  360,  369,  378,  390,
+			402,  417,  432,  441,  450,  462,  471,  480,
+			486,  492,  501,  510,  528,  540,  555,  573,
+			585,  594,  603,  621,  633,  651,  660,  675,
+			684,  696,  705,  717,  732,  744,  759,  771,
+			777,  777,  777,  777,  777,  777,  777,  777,
+			777,  777,  777,  777,  777,  777,  777,  777,
+			777,  777,  777,  777,  777,  777,  777,  777,
+			777,  777,  777,  777,  777,  777,  777,  777,
+			777,  777,  777,  777,  777,  777,  777,  777,
+			777,  777,  777,  777,  777,  777,  777,  777,
+			777,  777,  777,  777,  777,  777,  777,  777,
+			777,  777,  777,  777,  777,  777,  777,  777,
+			777,
+		},
+		{	/* Fourth byte 16-bit table 10. */
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    15,   24,   33,   45,   54,   63,   72,
+			87,   99,   105,  123,  132,  147,  159,  171,
+			180,  189,  201,  207,  219,  234,  240,  258,
+			267,  271,  275,  279,  283,  287,  291,  295,
+			299,  303,  307,  312,  317,  322,  327,  332,
+			337,  342,  347,  352,  357,  362,  367,  372,
+			377,  382,  385,  387,  389,  392,  394,  396,
+			396,  396,  396,  396,  402,  408,  414,  420,
+			432,  432,  432,  432,  432,  432,  432,  432,
+			432,  432,  432,  432,  432,  432,  432,  432,
+			432,  432,  432,  432,  432,  432,  432,  432,
+			432,  432,  432,  432,  432,  432,  432,  432,
+			432,  432,  432,  432,  432,  432,  432,  432,
+			432,  432,  432,  432,  432,  432,  432,  432,
+			432,  432,  432,  432,  432,  432,  432,  432,
+			432,  432,  432,  432,  432,  432,  432,  432,
+			432,
+		},
+		{	/* Fourth byte 16-bit table 11. */
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    4,    8,    12,   16,   20,   24,   28,
+			32,   36,   40,   44,   48,   52,   56,   60,
+			64,   68,   72,   76,   80,   84,   88,   92,
+			96,   100,  104,  108,  112,  116,  120,  124,
+			128,  132,  136,  140,  144,  148,  152,  156,
+			160,  164,  168,  172,  176,  180,  184,  188,
+			192,  196,  200,  204,  208,  212,  216,  220,
+			224,  228,  232,  236,  240,  244,  248,  252,
+			256,  256,  256,  256,  256,  256,  256,  256,
+			256,  256,  256,  256,  256,  256,  256,  256,
+			256,  256,  256,  256,  256,  256,  256,  256,
+			256,  256,  256,  256,  256,  256,  256,  256,
+			256,  256,  256,  256,  256,  256,  256,  256,
+			256,  256,  256,  256,  256,  256,  256,  256,
+			256,  256,  256,  256,  256,  256,  256,  256,
+			256,  256,  256,  256,  256,  256,  256,  256,
+			256,
+		},
+		{	/* Fourth byte 16-bit table 12. */
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    4,    8,    12,   16,   20,   24,   28,
+			32,   36,   40,   44,   48,   52,   56,   60,
+			64,   68,   72,   76,   80,   84,   88,   92,
+			96,   100,  104,  108,  112,  116,  120,  124,
+			128,  132,  136,  140,  144,  148,  152,  156,
+			160,  164,  168,  172,  176,  180,  184,  188,
+			192,  196,  200,  204,  208,  212,  216,  220,
+			224,  228,  232,  236,  240,  244,  248,  252,
+			256,  256,  256,  256,  256,  256,  256,  256,
+			256,  256,  256,  256,  256,  256,  256,  256,
+			256,  256,  256,  256,  256,  256,  256,  256,
+			256,  256,  256,  256,  256,  256,  256,  256,
+			256,  256,  256,  256,  256,  256,  256,  256,
+			256,  256,  256,  256,  256,  256,  256,  256,
+			256,  256,  256,  256,  256,  256,  256,  256,
+			256,  256,  256,  256,  256,  256,  256,  256,
+			256,
+		},
+		{	/* Fourth byte 16-bit table 13. */
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    4,    8,    12,   16,   20,   24,   28,
+			32,   36,   40,   44,   48,   52,   56,   60,
+			64,   68,   72,   76,   80,   84,   88,   92,
+			96,   100,  104,  108,  112,  116,  120,  124,
+			128,  132,  136,  140,  144,  148,  152,  156,
+			160,  164,  168,  172,  176,  180,  184,  188,
+			192,  196,  200,  204,  208,  212,  216,  220,
+			224,  228,  232,  236,  240,  244,  248,  252,
+			256,  256,  256,  256,  256,  256,  256,  256,
+			256,  256,  256,  256,  256,  256,  256,  256,
+			256,  256,  256,  256,  256,  256,  256,  256,
+			256,  256,  256,  256,  256,  256,  256,  256,
+			256,  256,  256,  256,  256,  256,  256,  256,
+			256,  256,  256,  256,  256,  256,  256,  256,
+			256,  256,  256,  256,  256,  256,  256,  256,
+			256,  256,  256,  256,  256,  256,  256,  256,
+			256,
+		},
+		{	/* Fourth byte 16-bit table 14. */
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    4,    8,    12,   16,   20,   24,   28,
+			32,   36,   40,   44,   48,   52,   56,   60,
+			64,   68,   72,   76,   80,   84,   88,   92,
+			96,   100,  104,  108,  112,  116,  120,  124,
+			128,  132,  136,  140,  144,  148,  152,  156,
+			160,  164,  168,  172,  176,  180,  184,  188,
+			192,  196,  200,  204,  208,  212,  216,  220,
+			224,  228,  232,  236,  240,  244,  248,  252,
+			256,  256,  256,  256,  256,  256,  256,  256,
+			256,  256,  256,  256,  256,  256,  256,  256,
+			256,  256,  256,  256,  256,  256,  256,  256,
+			256,  256,  256,  256,  256,  256,  256,  256,
+			256,  256,  256,  256,  256,  256,  256,  256,
+			256,  256,  256,  256,  256,  256,  256,  256,
+			256,  256,  256,  256,  256,  256,  256,  256,
+			256,  256,  256,  256,  256,  256,  256,  256,
+			256,
+		},
+		{	/* Fourth byte 16-bit table 15. */
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    6,    12,   18,   24,   30,   34,   38,
+			42,   46,   50,   54,   58,   62,   66,   70,
+			74,   78,   82,   86,   90,   94,   98,   102,
+			106,  110,  114,  118,  122,  126,  130,  134,
+			138,  142,  146,  150,  154,  158,  162,  166,
+			170,  174,  178,  182,  186,  190,  194,  198,
+			202,  206,  210,  214,  218,  222,  226,  230,
+			234,  238,  242,  246,  250,  254,  258,  262,
+			266,  266,  266,  266,  266,  266,  266,  266,
+			266,  266,  266,  266,  266,  266,  266,  266,
+			266,  266,  266,  266,  266,  266,  266,  266,
+			266,  266,  266,  266,  266,  266,  266,  266,
+			266,  266,  266,  266,  266,  266,  266,  266,
+			266,  266,  266,  266,  266,  266,  266,  266,
+			266,  266,  266,  266,  266,  266,  266,  266,
+			266,  266,  266,  266,  266,  266,  266,  266,
+			266,
+		},
+		{	/* Fourth byte 16-bit table 16. */
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    4,    8,    12,   16,   20,   24,   28,
+			32,   36,   40,   44,   48,   52,   56,   60,
+			64,   68,   72,   76,   80,   84,   88,   92,
+			96,   100,  104,  108,  112,  116,  120,  125,
+			130,  135,  140,  145,  150,  156,  162,  168,
+			174,  180,  186,  190,  194,  198,  202,  206,
+			210,  214,  218,  222,  226,  230,  234,  238,
+			242,  246,  250,  254,  258,  262,  266,  270,
+			274,  274,  274,  274,  274,  274,  274,  274,
+			274,  274,  274,  274,  274,  274,  274,  274,
+			274,  274,  274,  274,  274,  274,  274,  274,
+			274,  274,  274,  274,  274,  274,  274,  274,
+			274,  274,  274,  274,  274,  274,  274,  274,
+			274,  274,  274,  274,  274,  274,  274,  274,
+			274,  274,  274,  274,  274,  274,  274,  274,
+			274,  274,  274,  274,  274,  274,  274,  274,
+			274,
+		},
+		{	/* Fourth byte 16-bit table 17. */
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    4,    8,    12,   16,   20,   24,   28,
+			32,   36,   40,   44,   48,   52,   56,   60,
+			64,   68,   72,   76,   80,   84,   88,   92,
+			98,   104,  110,  116,  122,  126,  130,  134,
+			138,  142,  146,  150,  154,  158,  162,  166,
+			170,  174,  178,  182,  186,  190,  194,  198,
+			202,  206,  210,  214,  218,  222,  226,  230,
+			234,  238,  242,  246,  250,  254,  258,  262,
+			266,  266,  266,  266,  266,  266,  266,  266,
+			266,  266,  266,  266,  266,  266,  266,  266,
+			266,  266,  266,  266,  266,  266,  266,  266,
+			266,  266,  266,  266,  266,  266,  266,  266,
+			266,  266,  266,  266,  266,  266,  266,  266,
+			266,  266,  266,  266,  266,  266,  266,  266,
+			266,  266,  266,  266,  266,  266,  266,  266,
+			266,  266,  266,  266,  266,  266,  266,  266,
+			266,
+		},
+		{	/* Fourth byte 16-bit table 18. */
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    4,    8,    12,   16,   20,   24,   28,
+			32,   36,   40,   44,   48,   52,   56,   60,
+			64,   68,   72,   76,   80,   84,   88,   92,
+			96,   100,  104,  108,  112,  116,  120,  124,
+			130,  136,  140,  144,  148,  152,  156,  160,
+			164,  168,  172,  176,  180,  184,  188,  192,
+			196,  200,  204,  210,  216,  222,  226,  230,
+			234,  238,  242,  246,  250,  254,  258,  262,
+			266,  266,  266,  266,  266,  266,  266,  266,
+			266,  266,  266,  266,  266,  266,  266,  266,
+			266,  266,  266,  266,  266,  266,  266,  266,
+			266,  266,  266,  266,  266,  266,  266,  266,
+			266,  266,  266,  266,  266,  266,  266,  266,
+			266,  266,  266,  266,  266,  266,  266,  266,
+			266,  266,  266,  266,  266,  266,  266,  266,
+			266,  266,  266,  266,  266,  266,  266,  266,
+			266,
+		},
+		{	/* Fourth byte 16-bit table 19. */
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    6,    12,   18,   24,   30,   36,   42,
+			48,   54,   60,   66,   72,   78,   84,   90,
+			96,   102,  108,  114,  120,  126,  132,  138,
+			144,  150,  156,  162,  168,  174,  180,  186,
+			192,  198,  204,  210,  216,  222,  228,  234,
+			240,  246,  252,  258,  264,  270,  276,  282,
+			288,  288,  288,  288,  288,  288,  288,  288,
+			288,  288,  288,  288,  288,  288,  288,  288,
+			288,  288,  288,  288,  288,  288,  288,  288,
+			288,  288,  288,  288,  288,  288,  288,  288,
+			288,  288,  288,  288,  288,  288,  288,  288,
+			288,  288,  288,  288,  288,  288,  288,  288,
+			288,  288,  288,  288,  288,  288,  288,  288,
+			288,  288,  288,  288,  288,  288,  288,  288,
+			288,
+		},
+		{	/* Fourth byte 16-bit table 20. */
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    6,    12,   18,   24,   30,   36,   42,
+			48,   54,   60,   66,   72,   78,   84,   90,
+			96,   96,   96,   102,  108,  114,  120,  126,
+			132,  138,  144,  150,  156,  162,  168,  174,
+			180,  186,  192,  198,  204,  210,  216,  222,
+			228,  234,  240,  246,  252,  258,  264,  270,
+			276,  282,  288,  294,  300,  306,  312,  318,
+			324,  330,  336,  342,  348,  354,  360,  366,
+			372,  372,  372,  372,  372,  372,  372,  372,
+			372,  372,  372,  372,  372,  372,  372,  372,
+			372,  372,  372,  372,  372,  372,  372,  372,
+			372,  372,  372,  372,  372,  372,  372,  372,
+			372,  372,  372,  372,  372,  372,  372,  372,
+			372,  372,  372,  372,  372,  372,  372,  372,
+			372,  372,  372,  372,  372,  372,  372,  372,
+			372,  372,  372,  372,  372,  372,  372,  372,
+			372,
+		},
+		{	/* Fourth byte 16-bit table 21. */
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    4,    8,    12,   17,   21,   25,   29,
+			33,   37,   41,   45,   49,   53,   58,   62,
+			66,   70,   74,   79,   83,   87,   91,   96,
+			100,  104,  108,  112,  116,  121,  125,  129,
+			133,  137,  141,  145,  149,  153,  157,  161,
+			165,  169,  173,  177,  181,  185,  189,  193,
+			197,  201,  205,  209,  213,  218,  222,  226,
+			230,  235,  239,  243,  247,  251,  255,  259,
+			263,  263,  263,  263,  263,  263,  263,  263,
+			263,  263,  263,  263,  263,  263,  263,  263,
+			263,  263,  263,  263,  263,  263,  263,  263,
+			263,  263,  263,  263,  263,  263,  263,  263,
+			263,  263,  263,  263,  263,  263,  263,  263,
+			263,  263,  263,  263,  263,  263,  263,  263,
+			263,  263,  263,  263,  263,  263,  263,  263,
+			263,  263,  263,  263,  263,  263,  263,  263,
+			263,
+		},
+		{	/* Fourth byte 16-bit table 22. */
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    4,    8,    12,   16,   20,   24,   28,
+			32,   36,   40,   44,   48,   52,   56,   60,
+			64,   68,   72,   76,   80,   84,   88,   92,
+			96,   100,  105,  109,  113,  117,  121,  125,
+			129,  134,  139,  143,  147,  151,  155,  159,
+			163,  167,  171,  175,  179,  184,  188,  192,
+			196,  200,  205,  209,  213,  217,  221,  225,
+			229,  233,  237,  241,  246,  250,  255,  259,
+			263,  263,  263,  263,  263,  263,  263,  263,
+			263,  263,  263,  263,  263,  263,  263,  263,
+			263,  263,  263,  263,  263,  263,  263,  263,
+			263,  263,  263,  263,  263,  263,  263,  263,
+			263,  263,  263,  263,  263,  263,  263,  263,
+			263,  263,  263,  263,  263,  263,  263,  263,
+			263,  263,  263,  263,  263,  263,  263,  263,
+			263,  263,  263,  263,  263,  263,  263,  263,
+			263,
+		},
+		{	/* Fourth byte 16-bit table 23. */
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    4,    8,    12,   16,   20,   24,   28,
+			32,   36,   41,   45,   49,   53,   57,   61,
+			66,   70,   75,   80,   84,   88,   92,   96,
+			101,  106,  110,  114,  118,  122,  126,  130,
+			134,  138,  142,  146,  150,  155,  159,  163,
+			167,  171,  175,  179,  183,  187,  191,  195,
+			199,  203,  207,  211,  215,  219,  223,  227,
+			231,  236,  240,  244,  248,  252,  256,  261,
+			265,  265,  265,  265,  265,  265,  265,  265,
+			265,  265,  265,  265,  265,  265,  265,  265,
+			265,  265,  265,  265,  265,  265,  265,  265,
+			265,  265,  265,  265,  265,  265,  265,  265,
+			265,  265,  265,  265,  265,  265,  265,  265,
+			265,  265,  265,  265,  265,  265,  265,  265,
+			265,  265,  265,  265,  265,  265,  265,  265,
+			265,  265,  265,  265,  265,  265,  265,  265,
+			265,
+		},
+		{	/* Fourth byte 16-bit table 24. */
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    4,    8,    12,   16,   20,   24,   28,
+			32,   36,   40,   45,   49,   53,   57,   61,
+			65,   69,   73,   77,   81,   85,   89,   93,
+			97,   101,  105,  109,  113,  117,  122,  126,
+			130,  134,  138,  142,  147,  151,  155,  159,
+			163,  167,  171,  175,  179,  184,  188,  192,
+			196,  201,  205,  209,  213,  217,  221,  225,
+			230,  235,  240,  244,  249,  253,  257,  261,
+			265,  265,  265,  265,  265,  265,  265,  265,
+			265,  265,  265,  265,  265,  265,  265,  265,
+			265,  265,  265,  265,  265,  265,  265,  265,
+			265,  265,  265,  265,  265,  265,  265,  265,
+			265,  265,  265,  265,  265,  265,  265,  265,
+			265,  265,  265,  265,  265,  265,  265,  265,
+			265,  265,  265,  265,  265,  265,  265,  265,
+			265,  265,  265,  265,  265,  265,  265,  265,
+			265,
+		},
+		{	/* Fourth byte 16-bit table 25. */
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    4,    8,    12,   16,   20,   24,   29,
+			33,   37,   41,   45,   49,   53,   58,   62,
+			66,   71,   76,   80,   84,   88,   92,   96,
+			100,  104,  108,  112,  117,  121,  126,  130,
+			135,  139,  143,  147,  152,  156,  160,  165,
+			170,  174,  178,  182,  186,  190,  194,  198,
+			202,  206,  210,  214,  218,  222,  227,  231,
+			236,  240,  245,  249,  254,  259,  264,  268,
+			272,  272,  272,  272,  272,  272,  272,  272,
+			272,  272,  272,  272,  272,  272,  272,  272,
+			272,  272,  272,  272,  272,  272,  272,  272,
+			272,  272,  272,  272,  272,  272,  272,  272,
+			272,  272,  272,  272,  272,  272,  272,  272,
+			272,  272,  272,  272,  272,  272,  272,  272,
+			272,  272,  272,  272,  272,  272,  272,  272,
+			272,  272,  272,  272,  272,  272,  272,  272,
+			272,
+		},
+		{	/* Fourth byte 16-bit table 26. */
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    4,    9,    14,   19,   24,   28,   32,
+			36,   40,   44,   48,   52,   56,   61,   65,
+			69,   73,   77,   82,   86,   91,   96,   100,
+			104,  108,  112,  116,  120,  125,  130,  135,
+			139,  143,  148,  152,  156,  160,  165,  169,
+			173,  177,  181,  185,  190,  194,  198,  202,
+			206,  210,  214,  219,  224,  228,  233,  237,
+			242,  246,  250,  254,  259,  264,  268,  273,
+			277,  277,  277,  277,  277,  277,  277,  277,
+			277,  277,  277,  277,  277,  277,  277,  277,
+			277,  277,  277,  277,  277,  277,  277,  277,
+			277,  277,  277,  277,  277,  277,  277,  277,
+			277,  277,  277,  277,  277,  277,  277,  277,
+			277,  277,  277,  277,  277,  277,  277,  277,
+			277,  277,  277,  277,  277,  277,  277,  277,
+			277,  277,  277,  277,  277,  277,  277,  277,
+			277,
+		},
+		{	/* Fourth byte 16-bit table 27. */
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    5,    9,    13,   17,   21,   25,   29,
+			34,   39,   44,   49,   53,   57,   61,   65,
+			69,   73,   77,   81,   85,   89,   93,   97,
+			102,  106,  110,  114,  118,  122,  126,  130,
+			134,  138,  142,  146,  150,  155,  160,  165,
+			169,  173,  177,  181,  186,  190,  195,  199,
+			203,  208,  213,  217,  221,  225,  229,  233,
+			237,  241,  245,  249,  253,  257,  261,  265,
+			269,  269,  269,  269,  269,  269,  269,  269,
+			269,  269,  269,  269,  269,  269,  269,  269,
+			269,  269,  269,  269,  269,  269,  269,  269,
+			269,  269,  269,  269,  269,  269,  269,  269,
+			269,  269,  269,  269,  269,  269,  269,  269,
+			269,  269,  269,  269,  269,  269,  269,  269,
+			269,  269,  269,  269,  269,  269,  269,  269,
+			269,  269,  269,  269,  269,  269,  269,  269,
+			269,
+		},
+		{	/* Fourth byte 16-bit table 28. */
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    4,    8,    12,   16,   20,   25,   29,
+			33,   37,   41,   45,   50,   55,   59,   63,
+			67,   71,   75,   79,   84,   88,   92,   96,
+			100,  105,  110,  114,  118,  122,  127,  131,
+			135,  140,  145,  149,  153,  157,  162,  166,
+			170,  174,  178,  182,  186,  190,  195,  199,
+			203,  207,  212,  216,  220,  224,  228,  233,
+			238,  242,  246,  250,  255,  259,  264,  268,
+			272,  272,  272,  272,  272,  272,  272,  272,
+			272,  272,  272,  272,  272,  272,  272,  272,
+			272,  272,  272,  272,  272,  272,  272,  272,
+			272,  272,  272,  272,  272,  272,  272,  272,
+			272,  272,  272,  272,  272,  272,  272,  272,
+			272,  272,  272,  272,  272,  272,  272,  272,
+			272,  272,  272,  272,  272,  272,  272,  272,
+			272,  272,  272,  272,  272,  272,  272,  272,
+			272,
+		},
+		{	/* Fourth byte 16-bit table 29. */
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,
+		},
+	},
+	{
+		{	/* Fourth byte 16-bit table 0. */
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    4,    8,    12,   16,   20,   24,   28,
+			32,   38,   44,   48,   52,   56,   60,   64,
+			68,   72,   76,   80,   84,   90,   96,   102,
+			108,  112,  116,  120,  124,  130,  136,  140,
+			144,  148,  152,  156,  160,  164,  168,  172,
+			176,  180,  184,  188,  192,  196,  200,  206,
+			212,  216,  220,  224,  228,  232,  236,  240,
+			244,  250,  256,  260,  264,  268,  272,  276,
+			280,  280,  280,  280,  280,  280,  280,  280,
+			280,  280,  280,  280,  280,  280,  280,  280,
+			280,  280,  280,  280,  280,  280,  280,  280,
+			280,  280,  280,  280,  280,  280,  280,  280,
+			280,  280,  280,  280,  280,  280,  280,  280,
+			280,  280,  280,  280,  280,  280,  280,  280,
+			280,  280,  280,  280,  280,  280,  280,  280,
+			280,  280,  280,  280,  280,  280,  280,  280,
+			280,
+		},
+		{	/* Fourth byte 16-bit table 1. */
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    4,    8,    12,   16,   20,   24,   28,
+			32,   36,   40,   44,   48,   54,   60,   66,
+			72,   78,   84,   90,   96,   100,  104,  108,
+			112,  116,  120,  124,  128,  134,  140,  144,
+			148,  152,  156,  160,  164,  170,  176,  182,
+			188,  194,  200,  204,  208,  212,  216,  220,
+			224,  228,  232,  236,  240,  244,  248,  252,
+			256,  262,  268,  274,  280,  284,  288,  292,
+			296,  296,  296,  296,  296,  296,  296,  296,
+			296,  296,  296,  296,  296,  296,  296,  296,
+			296,  296,  296,  296,  296,  296,  296,  296,
+			296,  296,  296,  296,  296,  296,  296,  296,
+			296,  296,  296,  296,  296,  296,  296,  296,
+			296,  296,  296,  296,  296,  296,  296,  296,
+			296,  296,  296,  296,  296,  296,  296,  296,
+			296,  296,  296,  296,  296,  296,  296,  296,
+			296,
+		},
+		{	/* Fourth byte 16-bit table 2. */
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    4,    8,    12,   16,   20,   24,   28,
+			32,   36,   40,   44,   48,   52,   56,   60,
+			64,   68,   72,   76,   80,   84,   88,   92,
+			96,   100,  104,  107,  116,  116,  116,  116,
+			116,  120,  124,  128,  132,  138,  144,  150,
+			156,  162,  168,  174,  180,  186,  192,  198,
+			204,  210,  216,  222,  228,  234,  240,  246,
+			252,  256,  260,  264,  268,  272,  276,  282,
+			288,  288,  288,  288,  288,  288,  288,  288,
+			288,  288,  288,  288,  288,  288,  288,  288,
+			288,  288,  288,  288,  288,  288,  288,  288,
+			288,  288,  288,  288,  288,  288,  288,  288,
+			288,  288,  288,  288,  288,  288,  288,  288,
+			288,  288,  288,  288,  288,  288,  288,  288,
+			288,  288,  288,  288,  288,  288,  288,  288,
+			288,  288,  288,  288,  288,  288,  288,  288,
+			288,
+		},
+		{	/* Fourth byte 16-bit table 3. */
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    6,    12,   18,   24,   30,   36,   42,
+			48,   52,   56,   60,   64,   68,   72,   76,
+			80,   86,   92,   98,   104,  110,  116,  122,
+			128,  134,  140,  146,  152,  158,  164,  170,
+			176,  182,  188,  194,  200,  204,  208,  212,
+			216,  222,  228,  234,  240,  246,  252,  258,
+			264,  270,  276,  280,  284,  288,  292,  296,
+			300,  304,  308,  308,  308,  308,  308,  308,
+			308,  308,  308,  308,  308,  308,  308,  308,
+			308,  308,  308,  308,  308,  308,  308,  308,
+			308,  308,  308,  308,  308,  308,  308,  308,
+			308,  308,  308,  308,  308,  308,  308,  308,
+			308,  308,  308,  308,  308,  308,  308,  308,
+			308,  308,  308,  308,  308,  308,  308,  308,
+			308,  308,  308,  308,  308,  308,  308,  308,
+			308,  308,  308,  308,  308,  308,  308,  308,
+			308,
+		},
+		{	/* Fourth byte 16-bit table 4. */
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    5,    10,   17,   24,   31,   38,   45,
+			52,   57,   62,   69,   76,   83,   90,   97,
+			104,  109,  114,  121,  128,  135,  142,  142,
+			142,  147,  152,  159,  166,  173,  180,  180,
+			180,  185,  190,  197,  204,  211,  218,  225,
+			232,  237,  242,  249,  256,  263,  270,  277,
+			284,  289,  294,  301,  308,  315,  322,  329,
+			336,  341,  346,  353,  360,  367,  374,  381,
+			388,  388,  388,  388,  388,  388,  388,  388,
+			388,  388,  388,  388,  388,  388,  388,  388,
+			388,  388,  388,  388,  388,  388,  388,  388,
+			388,  388,  388,  388,  388,  388,  388,  388,
+			388,  388,  388,  388,  388,  388,  388,  388,
+			388,  388,  388,  388,  388,  388,  388,  388,
+			388,  388,  388,  388,  388,  388,  388,  388,
+			388,  388,  388,  388,  388,  388,  388,  388,
+			388,
+		},
+		{	/* Fourth byte 16-bit table 5. */
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    5,    10,   17,   24,   31,   38,   38,
+			38,   43,   48,   55,   62,   69,   76,   76,
+			76,   81,   86,   93,   100,  107,  114,  121,
+			128,  128,  133,  133,  140,  140,  147,  147,
+			154,  159,  164,  171,  178,  185,  192,  199,
+			206,  211,  216,  223,  230,  237,  244,  251,
+			258,  263,  268,  273,  278,  283,  288,  293,
+			298,  303,  308,  313,  318,  323,  328,  328,
+			328,  328,  328,  328,  328,  328,  328,  328,
+			328,  328,  328,  328,  328,  328,  328,  328,
+			328,  328,  328,  328,  328,  328,  328,  328,
+			328,  328,  328,  328,  328,  328,  328,  328,
+			328,  328,  328,  328,  328,  328,  328,  328,
+			328,  328,  328,  328,  328,  328,  328,  328,
+			328,  328,  328,  328,  328,  328,  328,  328,
+			328,  328,  328,  328,  328,  328,  328,  328,
+			328,
+		},
+		{	/* Fourth byte 16-bit table 6. */
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    7,    14,   23,   32,   41,   50,   59,
+			68,   75,   82,   91,   100,  109,  118,  127,
+			136,  143,  150,  159,  168,  177,  186,  195,
+			204,  211,  218,  227,  236,  245,  254,  263,
+			272,  279,  286,  295,  304,  313,  322,  331,
+			340,  347,  354,  363,  372,  381,  390,  399,
+			408,  413,  418,  425,  430,  437,  437,  442,
+			449,  454,  459,  464,  469,  474,  477,  480,
+			483,  483,  483,  483,  483,  483,  483,  483,
+			483,  483,  483,  483,  483,  483,  483,  483,
+			483,  483,  483,  483,  483,  483,  483,  483,
+			483,  483,  483,  483,  483,  483,  483,  483,
+			483,  483,  483,  483,  483,  483,  483,  483,
+			483,  483,  483,  483,  483,  483,  483,  483,
+			483,  483,  483,  483,  483,  483,  483,  483,
+			483,  483,  483,  483,  483,  483,  483,  483,
+			483,
+		},
+		{	/* Fourth byte 16-bit table 7. */
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    3,    14,   21,   26,   33,   33,   38,
+			45,   50,   55,   60,   65,   70,   82,   94,
+			106,  111,  116,  123,  130,  130,  130,  135,
+			142,  147,  152,  157,  162,  162,  174,  186,
+			198,  203,  208,  215,  222,  227,  232,  237,
+			244,  249,  254,  259,  264,  269,  280,  291,
+			293,  293,  293,  300,  305,  312,  312,  317,
+			324,  329,  334,  339,  344,  349,  356,  359,
+			359,  359,  359,  359,  359,  359,  359,  359,
+			359,  359,  359,  359,  359,  359,  359,  359,
+			359,  359,  359,  359,  359,  359,  359,  359,
+			359,  359,  359,  359,  359,  359,  359,  359,
+			359,  359,  359,  359,  359,  359,  359,  359,
+			359,  359,  359,  359,  359,  359,  359,  359,
+			359,  359,  359,  359,  359,  359,  359,  359,
+			359,  359,  359,  359,  359,  359,  359,  359,
+			359,
+		},
+		{	/* Fourth byte 16-bit table 8. */
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    5,    10,   15,   20,   25,   30,   35,
+			40,   45,   50,   55,   60,   65,   70,   78,
+			86,   94,   102,  110,  118,  126,  134,  142,
+			150,  158,  166,  174,  182,  190,  207,  221,
+			221,  226,  231,  236,  241,  246,  251,  256,
+			261,  266,  271,  276,  281,  286,  291,  296,
+			301,  306,  311,  316,  321,  326,  331,  336,
+			341,  346,  351,  356,  361,  366,  371,  376,
+			381,  381,  381,  381,  381,  381,  381,  381,
+			381,  381,  381,  381,  381,  381,  381,  381,
+			381,  381,  381,  381,  381,  381,  381,  381,
+			381,  381,  381,  381,  381,  381,  381,  381,
+			381,  381,  381,  381,  381,  381,  381,  381,
+			381,  381,  381,  381,  381,  381,  381,  381,
+			381,  381,  381,  381,  381,  381,  381,  381,
+			381,  381,  381,  381,  381,  381,  381,  381,
+			381,
+		},
+		{	/* Fourth byte 16-bit table 9. */
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    15,   27,   42,   51,   66,   75,   84,
+			102,  114,  123,  132,  141,  153,  165,  177,
+			189,  201,  213,  225,  243,  249,  267,  285,
+			300,  312,  330,  348,  360,  369,  378,  390,
+			402,  417,  432,  441,  450,  462,  471,  480,
+			486,  492,  501,  510,  528,  540,  555,  573,
+			585,  594,  603,  621,  633,  651,  660,  675,
+			684,  696,  705,  717,  732,  744,  759,  771,
+			777,  777,  777,  777,  777,  777,  777,  777,
+			777,  777,  777,  777,  777,  777,  777,  777,
+			777,  777,  777,  777,  777,  777,  777,  777,
+			777,  777,  777,  777,  777,  777,  777,  777,
+			777,  777,  777,  777,  777,  777,  777,  777,
+			777,  777,  777,  777,  777,  777,  777,  777,
+			777,  777,  777,  777,  777,  777,  777,  777,
+			777,  777,  777,  777,  777,  777,  777,  777,
+			777,
+		},
+		{	/* Fourth byte 16-bit table 10. */
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    15,   24,   33,   45,   54,   63,   72,
+			87,   99,   105,  123,  132,  147,  159,  171,
+			180,  189,  201,  207,  219,  234,  240,  258,
+			267,  271,  275,  279,  283,  287,  291,  295,
+			299,  303,  307,  312,  317,  322,  327,  332,
+			337,  342,  347,  352,  357,  362,  367,  372,
+			377,  382,  385,  387,  389,  392,  394,  396,
+			398,  401,  404,  406,  412,  418,  424,  430,
+			442,  442,  442,  442,  442,  442,  442,  442,
+			442,  442,  442,  442,  442,  442,  442,  442,
+			442,  442,  442,  442,  442,  442,  442,  442,
+			442,  442,  442,  442,  442,  442,  442,  442,
+			442,  442,  442,  442,  442,  442,  442,  442,
+			442,  442,  442,  442,  442,  442,  442,  442,
+			442,  442,  442,  442,  442,  442,  442,  442,
+			442,  442,  442,  442,  442,  442,  442,  442,
+			442,
+		},
+		{	/* Fourth byte 16-bit table 11. */
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    4,    8,    12,   16,   20,   24,   28,
+			32,   36,   40,   44,   48,   52,   56,   60,
+			64,   68,   72,   76,   80,   84,   88,   92,
+			96,   100,  104,  108,  112,  116,  120,  124,
+			128,  132,  136,  140,  144,  148,  152,  156,
+			160,  164,  168,  172,  176,  180,  184,  188,
+			192,  196,  200,  204,  208,  212,  216,  220,
+			224,  228,  232,  236,  240,  244,  248,  252,
+			256,  256,  256,  256,  256,  256,  256,  256,
+			256,  256,  256,  256,  256,  256,  256,  256,
+			256,  256,  256,  256,  256,  256,  256,  256,
+			256,  256,  256,  256,  256,  256,  256,  256,
+			256,  256,  256,  256,  256,  256,  256,  256,
+			256,  256,  256,  256,  256,  256,  256,  256,
+			256,  256,  256,  256,  256,  256,  256,  256,
+			256,  256,  256,  256,  256,  256,  256,  256,
+			256,
+		},
+		{	/* Fourth byte 16-bit table 12. */
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    4,    8,    12,   16,   20,   24,   28,
+			32,   36,   40,   44,   48,   52,   56,   60,
+			64,   68,   72,   76,   80,   84,   88,   92,
+			96,   100,  104,  108,  112,  116,  120,  124,
+			128,  132,  136,  140,  144,  148,  152,  156,
+			160,  164,  168,  172,  176,  180,  184,  188,
+			192,  196,  200,  204,  208,  212,  216,  220,
+			224,  228,  232,  236,  240,  244,  248,  252,
+			256,  256,  256,  256,  256,  256,  256,  256,
+			256,  256,  256,  256,  256,  256,  256,  256,
+			256,  256,  256,  256,  256,  256,  256,  256,
+			256,  256,  256,  256,  256,  256,  256,  256,
+			256,  256,  256,  256,  256,  256,  256,  256,
+			256,  256,  256,  256,  256,  256,  256,  256,
+			256,  256,  256,  256,  256,  256,  256,  256,
+			256,  256,  256,  256,  256,  256,  256,  256,
+			256,
+		},
+		{	/* Fourth byte 16-bit table 13. */
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    4,    8,    12,   16,   20,   24,   28,
+			32,   36,   40,   44,   48,   52,   56,   60,
+			64,   68,   72,   76,   80,   84,   88,   92,
+			96,   100,  104,  108,  112,  116,  120,  124,
+			128,  132,  136,  140,  144,  148,  152,  156,
+			160,  164,  168,  172,  176,  180,  184,  188,
+			192,  196,  200,  204,  208,  212,  216,  220,
+			224,  228,  232,  236,  240,  244,  248,  252,
+			256,  256,  256,  256,  256,  256,  256,  256,
+			256,  256,  256,  256,  256,  256,  256,  256,
+			256,  256,  256,  256,  256,  256,  256,  256,
+			256,  256,  256,  256,  256,  256,  256,  256,
+			256,  256,  256,  256,  256,  256,  256,  256,
+			256,  256,  256,  256,  256,  256,  256,  256,
+			256,  256,  256,  256,  256,  256,  256,  256,
+			256,  256,  256,  256,  256,  256,  256,  256,
+			256,
+		},
+		{	/* Fourth byte 16-bit table 14. */
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    4,    8,    12,   16,   20,   24,   28,
+			32,   36,   40,   44,   48,   52,   56,   60,
+			64,   68,   72,   76,   80,   84,   88,   92,
+			96,   100,  104,  108,  112,  116,  120,  124,
+			128,  132,  136,  140,  144,  148,  152,  156,
+			160,  164,  168,  172,  176,  180,  184,  188,
+			192,  196,  200,  204,  208,  212,  216,  220,
+			224,  228,  232,  236,  240,  244,  248,  252,
+			256,  256,  256,  256,  256,  256,  256,  256,
+			256,  256,  256,  256,  256,  256,  256,  256,
+			256,  256,  256,  256,  256,  256,  256,  256,
+			256,  256,  256,  256,  256,  256,  256,  256,
+			256,  256,  256,  256,  256,  256,  256,  256,
+			256,  256,  256,  256,  256,  256,  256,  256,
+			256,  256,  256,  256,  256,  256,  256,  256,
+			256,  256,  256,  256,  256,  256,  256,  256,
+			256,
+		},
+		{	/* Fourth byte 16-bit table 15. */
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    4,    8,    12,   16,   20,   24,   28,
+			32,   36,   40,   44,   48,   52,   56,   60,
+			64,   68,   72,   76,   80,   84,   88,   92,
+			96,   100,  104,  108,  112,  116,  120,  124,
+			128,  132,  136,  140,  144,  148,  152,  156,
+			160,  164,  168,  172,  176,  180,  184,  188,
+			192,  196,  200,  204,  208,  212,  216,  220,
+			224,  228,  232,  236,  240,  244,  248,  252,
+			256,  256,  256,  256,  256,  256,  256,  256,
+			256,  256,  256,  256,  256,  256,  256,  256,
+			256,  256,  256,  256,  256,  256,  256,  256,
+			256,  256,  256,  256,  256,  256,  256,  256,
+			256,  256,  256,  256,  256,  256,  256,  256,
+			256,  256,  256,  256,  256,  256,  256,  256,
+			256,  256,  256,  256,  256,  256,  256,  256,
+			256,  256,  256,  256,  256,  256,  256,  256,
+			256,
+		},
+		{	/* Fourth byte 16-bit table 16. */
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    6,    12,   18,   24,   30,   34,   38,
+			42,   46,   50,   54,   58,   62,   66,   70,
+			74,   78,   82,   86,   90,   94,   98,   102,
+			106,  110,  114,  118,  122,  126,  130,  134,
+			138,  142,  146,  150,  154,  158,  162,  166,
+			170,  174,  178,  182,  186,  190,  194,  198,
+			202,  206,  210,  214,  218,  222,  226,  230,
+			234,  238,  242,  246,  250,  254,  258,  262,
+			266,  266,  266,  266,  266,  266,  266,  266,
+			266,  266,  266,  266,  266,  266,  266,  266,
+			266,  266,  266,  266,  266,  266,  266,  266,
+			266,  266,  266,  266,  266,  266,  266,  266,
+			266,  266,  266,  266,  266,  266,  266,  266,
+			266,  266,  266,  266,  266,  266,  266,  266,
+			266,  266,  266,  266,  266,  266,  266,  266,
+			266,  266,  266,  266,  266,  266,  266,  266,
+			266,
+		},
+		{	/* Fourth byte 16-bit table 17. */
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    4,    8,    12,   16,   20,   24,   28,
+			32,   36,   40,   44,   48,   52,   56,   60,
+			64,   68,   72,   76,   80,   84,   88,   92,
+			96,   100,  104,  108,  112,  116,  120,  125,
+			130,  135,  140,  145,  150,  156,  162,  168,
+			174,  180,  186,  190,  194,  198,  202,  206,
+			210,  214,  218,  222,  226,  230,  234,  238,
+			242,  246,  250,  254,  258,  262,  266,  270,
+			274,  274,  274,  274,  274,  274,  274,  274,
+			274,  274,  274,  274,  274,  274,  274,  274,
+			274,  274,  274,  274,  274,  274,  274,  274,
+			274,  274,  274,  274,  274,  274,  274,  274,
+			274,  274,  274,  274,  274,  274,  274,  274,
+			274,  274,  274,  274,  274,  274,  274,  274,
+			274,  274,  274,  274,  274,  274,  274,  274,
+			274,  274,  274,  274,  274,  274,  274,  274,
+			274,
+		},
+		{	/* Fourth byte 16-bit table 18. */
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    4,    8,    12,   16,   20,   24,   28,
+			32,   36,   40,   44,   48,   52,   56,   60,
+			64,   68,   72,   76,   80,   84,   88,   92,
+			98,   104,  110,  116,  122,  126,  130,  134,
+			138,  142,  146,  150,  154,  158,  162,  166,
+			170,  174,  178,  182,  186,  190,  194,  198,
+			202,  206,  210,  214,  218,  222,  226,  230,
+			234,  238,  242,  246,  250,  254,  258,  262,
+			266,  266,  266,  266,  266,  266,  266,  266,
+			266,  266,  266,  266,  266,  266,  266,  266,
+			266,  266,  266,  266,  266,  266,  266,  266,
+			266,  266,  266,  266,  266,  266,  266,  266,
+			266,  266,  266,  266,  266,  266,  266,  266,
+			266,  266,  266,  266,  266,  266,  266,  266,
+			266,  266,  266,  266,  266,  266,  266,  266,
+			266,  266,  266,  266,  266,  266,  266,  266,
+			266,
+		},
+		{	/* Fourth byte 16-bit table 19. */
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    4,    8,    12,   16,   20,   24,   28,
+			32,   36,   40,   44,   48,   52,   56,   60,
+			64,   68,   72,   76,   80,   84,   88,   92,
+			96,   100,  104,  108,  112,  116,  120,  124,
+			130,  136,  140,  144,  148,  152,  156,  160,
+			164,  168,  172,  176,  180,  184,  188,  192,
+			196,  200,  204,  210,  216,  222,  226,  230,
+			234,  238,  242,  246,  250,  254,  258,  262,
+			266,  266,  266,  266,  266,  266,  266,  266,
+			266,  266,  266,  266,  266,  266,  266,  266,
+			266,  266,  266,  266,  266,  266,  266,  266,
+			266,  266,  266,  266,  266,  266,  266,  266,
+			266,  266,  266,  266,  266,  266,  266,  266,
+			266,  266,  266,  266,  266,  266,  266,  266,
+			266,  266,  266,  266,  266,  266,  266,  266,
+			266,  266,  266,  266,  266,  266,  266,  266,
+			266,
+		},
+		{	/* Fourth byte 16-bit table 20. */
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    6,    12,   18,   24,   30,   36,   42,
+			48,   54,   60,   66,   72,   78,   84,   90,
+			96,   102,  108,  114,  120,  126,  132,  138,
+			144,  150,  156,  162,  168,  174,  180,  186,
+			192,  198,  204,  210,  216,  222,  228,  234,
+			240,  246,  252,  258,  264,  270,  276,  282,
+			288,  288,  288,  288,  288,  288,  288,  288,
+			288,  288,  288,  288,  288,  288,  288,  288,
+			288,  288,  288,  288,  288,  288,  288,  288,
+			288,  288,  288,  288,  288,  288,  288,  288,
+			288,  288,  288,  288,  288,  288,  288,  288,
+			288,  288,  288,  288,  288,  288,  288,  288,
+			288,  288,  288,  288,  288,  288,  288,  288,
+			288,  288,  288,  288,  288,  288,  288,  288,
+			288,
+		},
+		{	/* Fourth byte 16-bit table 21. */
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    6,    12,   18,   24,   30,   36,   42,
+			48,   54,   60,   66,   72,   78,   84,   90,
+			96,   96,   96,   102,  108,  114,  120,  126,
+			132,  138,  144,  150,  156,  162,  168,  174,
+			180,  186,  192,  198,  204,  210,  216,  222,
+			228,  234,  240,  246,  252,  258,  264,  270,
+			276,  282,  288,  294,  300,  306,  312,  318,
+			324,  330,  336,  342,  348,  354,  360,  366,
+			372,  372,  372,  372,  372,  372,  372,  372,
+			372,  372,  372,  372,  372,  372,  372,  372,
+			372,  372,  372,  372,  372,  372,  372,  372,
+			372,  372,  372,  372,  372,  372,  372,  372,
+			372,  372,  372,  372,  372,  372,  372,  372,
+			372,  372,  372,  372,  372,  372,  372,  372,
+			372,  372,  372,  372,  372,  372,  372,  372,
+			372,  372,  372,  372,  372,  372,  372,  372,
+			372,
+		},
+		{	/* Fourth byte 16-bit table 22. */
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    4,    8,    12,   17,   21,   25,   29,
+			33,   37,   41,   45,   49,   53,   58,   62,
+			66,   70,   74,   79,   83,   87,   91,   96,
+			100,  104,  108,  112,  116,  121,  125,  129,
+			133,  137,  141,  145,  149,  153,  157,  161,
+			165,  169,  173,  177,  181,  185,  189,  193,
+			197,  201,  205,  209,  213,  218,  222,  226,
+			230,  235,  239,  243,  247,  251,  255,  259,
+			263,  263,  263,  263,  263,  263,  263,  263,
+			263,  263,  263,  263,  263,  263,  263,  263,
+			263,  263,  263,  263,  263,  263,  263,  263,
+			263,  263,  263,  263,  263,  263,  263,  263,
+			263,  263,  263,  263,  263,  263,  263,  263,
+			263,  263,  263,  263,  263,  263,  263,  263,
+			263,  263,  263,  263,  263,  263,  263,  263,
+			263,  263,  263,  263,  263,  263,  263,  263,
+			263,
+		},
+		{	/* Fourth byte 16-bit table 23. */
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    4,    8,    12,   16,   20,   24,   28,
+			32,   36,   40,   44,   48,   52,   56,   60,
+			64,   68,   72,   76,   80,   84,   88,   92,
+			96,   100,  105,  109,  113,  117,  121,  125,
+			129,  134,  139,  143,  147,  151,  155,  159,
+			163,  167,  171,  175,  179,  184,  188,  192,
+			196,  200,  205,  209,  213,  217,  221,  225,
+			229,  233,  237,  241,  246,  250,  255,  259,
+			263,  263,  263,  263,  263,  263,  263,  263,
+			263,  263,  263,  263,  263,  263,  263,  263,
+			263,  263,  263,  263,  263,  263,  263,  263,
+			263,  263,  263,  263,  263,  263,  263,  263,
+			263,  263,  263,  263,  263,  263,  263,  263,
+			263,  263,  263,  263,  263,  263,  263,  263,
+			263,  263,  263,  263,  263,  263,  263,  263,
+			263,  263,  263,  263,  263,  263,  263,  263,
+			263,
+		},
+		{	/* Fourth byte 16-bit table 24. */
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    4,    8,    12,   16,   20,   24,   28,
+			32,   36,   41,   45,   49,   53,   57,   61,
+			66,   70,   75,   80,   84,   88,   92,   96,
+			101,  106,  110,  114,  118,  122,  126,  130,
+			134,  138,  142,  146,  150,  155,  159,  163,
+			167,  171,  175,  179,  183,  187,  191,  195,
+			199,  203,  207,  211,  215,  219,  223,  227,
+			231,  236,  240,  244,  248,  252,  256,  261,
+			265,  265,  265,  265,  265,  265,  265,  265,
+			265,  265,  265,  265,  265,  265,  265,  265,
+			265,  265,  265,  265,  265,  265,  265,  265,
+			265,  265,  265,  265,  265,  265,  265,  265,
+			265,  265,  265,  265,  265,  265,  265,  265,
+			265,  265,  265,  265,  265,  265,  265,  265,
+			265,  265,  265,  265,  265,  265,  265,  265,
+			265,  265,  265,  265,  265,  265,  265,  265,
+			265,
+		},
+		{	/* Fourth byte 16-bit table 25. */
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    4,    8,    12,   16,   20,   24,   28,
+			32,   36,   40,   45,   49,   53,   57,   61,
+			65,   69,   73,   77,   81,   85,   89,   93,
+			97,   101,  105,  109,  113,  117,  122,  126,
+			130,  134,  138,  142,  147,  151,  155,  159,
+			163,  167,  171,  175,  179,  184,  188,  192,
+			196,  201,  205,  209,  213,  217,  221,  225,
+			230,  235,  240,  244,  249,  253,  257,  261,
+			265,  265,  265,  265,  265,  265,  265,  265,
+			265,  265,  265,  265,  265,  265,  265,  265,
+			265,  265,  265,  265,  265,  265,  265,  265,
+			265,  265,  265,  265,  265,  265,  265,  265,
+			265,  265,  265,  265,  265,  265,  265,  265,
+			265,  265,  265,  265,  265,  265,  265,  265,
+			265,  265,  265,  265,  265,  265,  265,  265,
+			265,  265,  265,  265,  265,  265,  265,  265,
+			265,
+		},
+		{	/* Fourth byte 16-bit table 26. */
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    4,    8,    12,   16,   20,   24,   29,
+			33,   37,   41,   45,   49,   53,   58,   62,
+			66,   71,   76,   80,   84,   88,   92,   96,
+			100,  104,  108,  112,  117,  121,  126,  130,
+			135,  139,  143,  147,  152,  156,  160,  165,
+			170,  174,  178,  182,  186,  190,  194,  198,
+			202,  206,  210,  214,  218,  222,  227,  231,
+			236,  240,  245,  249,  254,  259,  264,  268,
+			272,  272,  272,  272,  272,  272,  272,  272,
+			272,  272,  272,  272,  272,  272,  272,  272,
+			272,  272,  272,  272,  272,  272,  272,  272,
+			272,  272,  272,  272,  272,  272,  272,  272,
+			272,  272,  272,  272,  272,  272,  272,  272,
+			272,  272,  272,  272,  272,  272,  272,  272,
+			272,  272,  272,  272,  272,  272,  272,  272,
+			272,  272,  272,  272,  272,  272,  272,  272,
+			272,
+		},
+		{	/* Fourth byte 16-bit table 27. */
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    4,    9,    14,   19,   24,   28,   32,
+			36,   40,   44,   48,   52,   56,   61,   65,
+			69,   73,   77,   82,   86,   91,   96,   100,
+			104,  108,  112,  116,  120,  125,  130,  135,
+			139,  143,  148,  152,  156,  160,  165,  169,
+			173,  177,  181,  185,  190,  194,  198,  202,
+			206,  210,  214,  219,  224,  228,  233,  237,
+			242,  246,  250,  254,  259,  264,  268,  273,
+			277,  277,  277,  277,  277,  277,  277,  277,
+			277,  277,  277,  277,  277,  277,  277,  277,
+			277,  277,  277,  277,  277,  277,  277,  277,
+			277,  277,  277,  277,  277,  277,  277,  277,
+			277,  277,  277,  277,  277,  277,  277,  277,
+			277,  277,  277,  277,  277,  277,  277,  277,
+			277,  277,  277,  277,  277,  277,  277,  277,
+			277,  277,  277,  277,  277,  277,  277,  277,
+			277,
+		},
+		{	/* Fourth byte 16-bit table 28. */
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    5,    9,    13,   17,   21,   25,   29,
+			34,   39,   44,   49,   53,   57,   61,   65,
+			69,   73,   77,   81,   85,   89,   93,   97,
+			102,  106,  110,  114,  118,  122,  126,  130,
+			134,  138,  142,  146,  150,  155,  160,  165,
+			169,  173,  177,  181,  186,  190,  195,  199,
+			203,  208,  213,  217,  221,  225,  229,  233,
+			237,  241,  245,  249,  253,  257,  261,  265,
+			269,  269,  269,  269,  269,  269,  269,  269,
+			269,  269,  269,  269,  269,  269,  269,  269,
+			269,  269,  269,  269,  269,  269,  269,  269,
+			269,  269,  269,  269,  269,  269,  269,  269,
+			269,  269,  269,  269,  269,  269,  269,  269,
+			269,  269,  269,  269,  269,  269,  269,  269,
+			269,  269,  269,  269,  269,  269,  269,  269,
+			269,  269,  269,  269,  269,  269,  269,  269,
+			269,
+		},
+		{	/* Fourth byte 16-bit table 29. */
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    0,    0,    0,    0,    0,    0,    0,
+			0,    4,    8,    12,   16,   20,   25,   29,
+			33,   37,   41,   45,   50,   55,   59,   63,
+			67,   71,   75,   79,   84,   88,   92,   96,
+			100,  105,  110,  114,  118,  122,  127,  131,
+			135,  140,  145,  149,  153,  157,  162,  166,
+			170,  174,  178,  182,  186,  190,  195,  199,
+			203,  207,  212,  216,  220,  224,  228,  233,
+			238,  242,  246,  250,  255,  259,  264,  268,
+			272,  272,  272,  272,  272,  272,  272,  272,
+			272,  272,  272,  272,  272,  272,  272,  272,
+			272,  272,  272,  272,  272,  272,  272,  272,
+			272,  272,  272,  272,  272,  272,  272,  272,
+			272,  272,  272,  272,  272,  272,  272,  272,
+			272,  272,  272,  272,  272,  272,  272,  272,
+			272,  272,  272,  272,  272,  272,  272,  272,
+			272,  272,  272,  272,  272,  272,  272,  272,
+			272,
+		},
+	},
+};
+
+static const uchar_t u8_decomp_final_tbl[2][19370] = {
+	{
+		0x20, 0x20, 0xCC, 0x88, 0x61, 0x20, 0xCC, 0x84,
+		0x32, 0x33, 0x20, 0xCC, 0x81, 0xCE, 0xBC, 0x20,
+		0xCC, 0xA7, 0x31, 0x6F, 0x31, 0xE2, 0x81, 0x84,
+		0x34, 0x31, 0xE2, 0x81, 0x84, 0x32, 0x33, 0xE2,
+		0x81, 0x84, 0x34, 0xF6, 0x41, 0xCC, 0x80, 0xF6,
+		0x41, 0xCC, 0x81, 0xF6, 0x41, 0xCC, 0x82, 0xF6,
+		0x41, 0xCC, 0x83, 0xF6, 0x41, 0xCC, 0x88, 0xF6,
+		0x41, 0xCC, 0x8A, 0xF6, 0x43, 0xCC, 0xA7, 0xF6,
+		0x45, 0xCC, 0x80, 0xF6, 0x45, 0xCC, 0x81, 0xF6,
+		0x45, 0xCC, 0x82, 0xF6, 0x45, 0xCC, 0x88, 0xF6,
+		0x49, 0xCC, 0x80, 0xF6, 0x49, 0xCC, 0x81, 0xF6,
+		0x49, 0xCC, 0x82, 0xF6, 0x49, 0xCC, 0x88, 0xF6,
+		0x4E, 0xCC, 0x83, 0xF6, 0x4F, 0xCC, 0x80, 0xF6,
+		0x4F, 0xCC, 0x81, 0xF6, 0x4F, 0xCC, 0x82, 0xF6,
+		0x4F, 0xCC, 0x83, 0xF6, 0x4F, 0xCC, 0x88, 0xF6,
+		0x55, 0xCC, 0x80, 0xF6, 0x55, 0xCC, 0x81, 0xF6,
+		0x55, 0xCC, 0x82, 0xF6, 0x55, 0xCC, 0x88, 0xF6,
+		0x59, 0xCC, 0x81, 0xF6, 0x61, 0xCC, 0x80, 0xF6,
+		0x61, 0xCC, 0x81, 0xF6, 0x61, 0xCC, 0x82, 0xF6,
+		0x61, 0xCC, 0x83, 0xF6, 0x61, 0xCC, 0x88, 0xF6,
+		0x61, 0xCC, 0x8A, 0xF6, 0x63, 0xCC, 0xA7, 0xF6,
+		0x65, 0xCC, 0x80, 0xF6, 0x65, 0xCC, 0x81, 0xF6,
+		0x65, 0xCC, 0x82, 0xF6, 0x65, 0xCC, 0x88, 0xF6,
+		0x69, 0xCC, 0x80, 0xF6, 0x69, 0xCC, 0x81, 0xF6,
+		0x69, 0xCC, 0x82, 0xF6, 0x69, 0xCC, 0x88, 0xF6,
+		0x6E, 0xCC, 0x83, 0xF6, 0x6F, 0xCC, 0x80, 0xF6,
+		0x6F, 0xCC, 0x81, 0xF6, 0x6F, 0xCC, 0x82, 0xF6,
+		0x6F, 0xCC, 0x83, 0xF6, 0x6F, 0xCC, 0x88, 0xF6,
+		0x75, 0xCC, 0x80, 0xF6, 0x75, 0xCC, 0x81, 0xF6,
+		0x75, 0xCC, 0x82, 0xF6, 0x75, 0xCC, 0x88, 0xF6,
+		0x79, 0xCC, 0x81, 0xF6, 0x79, 0xCC, 0x88, 0xF6,
+		0x41, 0xCC, 0x84, 0xF6, 0x61, 0xCC, 0x84, 0xF6,
+		0x41, 0xCC, 0x86, 0xF6, 0x61, 0xCC, 0x86, 0xF6,
+		0x41, 0xCC, 0xA8, 0xF6, 0x61, 0xCC, 0xA8, 0xF6,
+		0x43, 0xCC, 0x81, 0xF6, 0x63, 0xCC, 0x81, 0xF6,
+		0x43, 0xCC, 0x82, 0xF6, 0x63, 0xCC, 0x82, 0xF6,
+		0x43, 0xCC, 0x87, 0xF6, 0x63, 0xCC, 0x87, 0xF6,
+		0x43, 0xCC, 0x8C, 0xF6, 0x63, 0xCC, 0x8C, 0xF6,
+		0x44, 0xCC, 0x8C, 0xF6, 0x64, 0xCC, 0x8C, 0xF6,
+		0x45, 0xCC, 0x84, 0xF6, 0x65, 0xCC, 0x84, 0xF6,
+		0x45, 0xCC, 0x86, 0xF6, 0x65, 0xCC, 0x86, 0xF6,
+		0x45, 0xCC, 0x87, 0xF6, 0x65, 0xCC, 0x87, 0xF6,
+		0x45, 0xCC, 0xA8, 0xF6, 0x65, 0xCC, 0xA8, 0xF6,
+		0x45, 0xCC, 0x8C, 0xF6, 0x65, 0xCC, 0x8C, 0xF6,
+		0x47, 0xCC, 0x82, 0xF6, 0x67, 0xCC, 0x82, 0xF6,
+		0x47, 0xCC, 0x86, 0xF6, 0x67, 0xCC, 0x86, 0xF6,
+		0x47, 0xCC, 0x87, 0xF6, 0x67, 0xCC, 0x87, 0xF6,
+		0x47, 0xCC, 0xA7, 0xF6, 0x67, 0xCC, 0xA7, 0xF6,
+		0x48, 0xCC, 0x82, 0xF6, 0x68, 0xCC, 0x82, 0xF6,
+		0x49, 0xCC, 0x83, 0xF6, 0x69, 0xCC, 0x83, 0xF6,
+		0x49, 0xCC, 0x84, 0xF6, 0x69, 0xCC, 0x84, 0xF6,
+		0x49, 0xCC, 0x86, 0xF6, 0x69, 0xCC, 0x86, 0xF6,
+		0x49, 0xCC, 0xA8, 0xF6, 0x69, 0xCC, 0xA8, 0xF6,
+		0x49, 0xCC, 0x87, 0x49, 0x4A, 0x69, 0x6A, 0xF6,
+		0x4A, 0xCC, 0x82, 0xF6, 0x6A, 0xCC, 0x82, 0xF6,
+		0x4B, 0xCC, 0xA7, 0xF6, 0x6B, 0xCC, 0xA7, 0xF6,
+		0x4C, 0xCC, 0x81, 0xF6, 0x6C, 0xCC, 0x81, 0xF6,
+		0x4C, 0xCC, 0xA7, 0xF6, 0x6C, 0xCC, 0xA7, 0xF6,
+		0x4C, 0xCC, 0x8C, 0xF6, 0x6C, 0xCC, 0x8C, 0x4C,
+		0xC2, 0xB7, 0x6C, 0xC2, 0xB7, 0xF6, 0x4E, 0xCC,
+		0x81, 0xF6, 0x6E, 0xCC, 0x81, 0xF6, 0x4E, 0xCC,
+		0xA7, 0xF6, 0x6E, 0xCC, 0xA7, 0xF6, 0x4E, 0xCC,
+		0x8C, 0xF6, 0x6E, 0xCC, 0x8C, 0xCA, 0xBC, 0x6E,
+		0xF6, 0x4F, 0xCC, 0x84, 0xF6, 0x6F, 0xCC, 0x84,
+		0xF6, 0x4F, 0xCC, 0x86, 0xF6, 0x6F, 0xCC, 0x86,
+		0xF6, 0x4F, 0xCC, 0x8B, 0xF6, 0x6F, 0xCC, 0x8B,
+		0xF6, 0x52, 0xCC, 0x81, 0xF6, 0x72, 0xCC, 0x81,
+		0xF6, 0x52, 0xCC, 0xA7, 0xF6, 0x72, 0xCC, 0xA7,
+		0xF6, 0x52, 0xCC, 0x8C, 0xF6, 0x72, 0xCC, 0x8C,
+		0xF6, 0x53, 0xCC, 0x81, 0xF6, 0x73, 0xCC, 0x81,
+		0xF6, 0x53, 0xCC, 0x82, 0xF6, 0x73, 0xCC, 0x82,
+		0xF6, 0x53, 0xCC, 0xA7, 0xF6, 0x73, 0xCC, 0xA7,
+		0xF6, 0x53, 0xCC, 0x8C, 0xF6, 0x73, 0xCC, 0x8C,
+		0xF6, 0x54, 0xCC, 0xA7, 0xF6, 0x74, 0xCC, 0xA7,
+		0xF6, 0x54, 0xCC, 0x8C, 0xF6, 0x74, 0xCC, 0x8C,
+		0xF6, 0x55, 0xCC, 0x83, 0xF6, 0x75, 0xCC, 0x83,
+		0xF6, 0x55, 0xCC, 0x84, 0xF6, 0x75, 0xCC, 0x84,
+		0xF6, 0x55, 0xCC, 0x86, 0xF6, 0x75, 0xCC, 0x86,
+		0xF6, 0x55, 0xCC, 0x8A, 0xF6, 0x75, 0xCC, 0x8A,
+		0xF6, 0x55, 0xCC, 0x8B, 0xF6, 0x75, 0xCC, 0x8B,
+		0xF6, 0x55, 0xCC, 0xA8, 0xF6, 0x75, 0xCC, 0xA8,
+		0xF6, 0x57, 0xCC, 0x82, 0xF6, 0x77, 0xCC, 0x82,
+		0xF6, 0x59, 0xCC, 0x82, 0xF6, 0x79, 0xCC, 0x82,
+		0xF6, 0x59, 0xCC, 0x88, 0xF6, 0x5A, 0xCC, 0x81,
+		0xF6, 0x7A, 0xCC, 0x81, 0xF6, 0x5A, 0xCC, 0x87,
+		0xF6, 0x7A, 0xCC, 0x87, 0xF6, 0x5A, 0xCC, 0x8C,
+		0xF6, 0x7A, 0xCC, 0x8C, 0x73, 0xF6, 0x4F, 0xCC,
+		0x9B, 0xF6, 0x6F, 0xCC, 0x9B, 0xF6, 0x55, 0xCC,
+		0x9B, 0xF6, 0x75, 0xCC, 0x9B, 0x44, 0x5A, 0xCC,
+		0x8C, 0x44, 0x7A, 0xCC, 0x8C, 0x64, 0x7A, 0xCC,
+		0x8C, 0x4C, 0x4A, 0x4C, 0x6A, 0x6C, 0x6A, 0x4E,
+		0x4A, 0x4E, 0x6A, 0x6E, 0x6A, 0xF6, 0x41, 0xCC,
+		0x8C, 0xF6, 0x61, 0xCC, 0x8C, 0xF6, 0x49, 0xCC,
+		0x8C, 0xF6, 0x69, 0xCC, 0x8C, 0xF6, 0x4F, 0xCC,
+		0x8C, 0xF6, 0x6F, 0xCC, 0x8C, 0xF6, 0x55, 0xCC,
+		0x8C, 0xF6, 0x75, 0xCC, 0x8C, 0xF6, 0x55, 0xCC,
+		0x88, 0xCC, 0x84, 0xF6, 0x75, 0xCC, 0x88, 0xCC,
+		0x84, 0xF6, 0x55, 0xCC, 0x88, 0xCC, 0x81, 0xF6,
+		0x75, 0xCC, 0x88, 0xCC, 0x81, 0xF6, 0x55, 0xCC,
+		0x88, 0xCC, 0x8C, 0xF6, 0x75, 0xCC, 0x88, 0xCC,
+		0x8C, 0xF6, 0x55, 0xCC, 0x88, 0xCC, 0x80, 0xF6,
+		0x75, 0xCC, 0x88, 0xCC, 0x80, 0xF6, 0x41, 0xCC,
+		0x88, 0xCC, 0x84, 0xF6, 0x61, 0xCC, 0x88, 0xCC,
+		0x84, 0xF6, 0x41, 0xCC, 0x87, 0xCC, 0x84, 0xF6,
+		0x61, 0xCC, 0x87, 0xCC, 0x84, 0xF6, 0xC3, 0x86,
+		0xCC, 0x84, 0xF6, 0xC3, 0xA6, 0xCC, 0x84, 0xF6,
+		0x47, 0xCC, 0x8C, 0xF6, 0x67, 0xCC, 0x8C, 0xF6,
+		0x4B, 0xCC, 0x8C, 0xF6, 0x6B, 0xCC, 0x8C, 0xF6,
+		0x4F, 0xCC, 0xA8, 0xF6, 0x6F, 0xCC, 0xA8, 0xF6,
+		0x4F, 0xCC, 0xA8, 0xCC, 0x84, 0xF6, 0x6F, 0xCC,
+		0xA8, 0xCC, 0x84, 0xF6, 0xC6, 0xB7, 0xCC, 0x8C,
+		0xF6, 0xCA, 0x92, 0xCC, 0x8C, 0xF6, 0x6A, 0xCC,
+		0x8C, 0x44, 0x5A, 0x44, 0x7A, 0x64, 0x7A, 0xF6,
+		0x47, 0xCC, 0x81, 0xF6, 0x67, 0xCC, 0x81, 0xF6,
+		0x4E, 0xCC, 0x80, 0xF6, 0x6E, 0xCC, 0x80, 0xF6,
+		0x41, 0xCC, 0x8A, 0xCC, 0x81, 0xF6, 0x61, 0xCC,
+		0x8A, 0xCC, 0x81, 0xF6, 0xC3, 0x86, 0xCC, 0x81,
+		0xF6, 0xC3, 0xA6, 0xCC, 0x81, 0xF6, 0xC3, 0x98,
+		0xCC, 0x81, 0xF6, 0xC3, 0xB8, 0xCC, 0x81, 0xF6,
+		0x41, 0xCC, 0x8F, 0xF6, 0x61, 0xCC, 0x8F, 0xF6,
+		0x41, 0xCC, 0x91, 0xF6, 0x61, 0xCC, 0x91, 0xF6,
+		0x45, 0xCC, 0x8F, 0xF6, 0x65, 0xCC, 0x8F, 0xF6,
+		0x45, 0xCC, 0x91, 0xF6, 0x65, 0xCC, 0x91, 0xF6,
+		0x49, 0xCC, 0x8F, 0xF6, 0x69, 0xCC, 0x8F, 0xF6,
+		0x49, 0xCC, 0x91, 0xF6, 0x69, 0xCC, 0x91, 0xF6,
+		0x4F, 0xCC, 0x8F, 0xF6, 0x6F, 0xCC, 0x8F, 0xF6,
+		0x4F, 0xCC, 0x91, 0xF6, 0x6F, 0xCC, 0x91, 0xF6,
+		0x52, 0xCC, 0x8F, 0xF6, 0x72, 0xCC, 0x8F, 0xF6,
+		0x52, 0xCC, 0x91, 0xF6, 0x72, 0xCC, 0x91, 0xF6,
+		0x55, 0xCC, 0x8F, 0xF6, 0x75, 0xCC, 0x8F, 0xF6,
+		0x55, 0xCC, 0x91, 0xF6, 0x75, 0xCC, 0x91, 0xF6,
+		0x53, 0xCC, 0xA6, 0xF6, 0x73, 0xCC, 0xA6, 0xF6,
+		0x54, 0xCC, 0xA6, 0xF6, 0x74, 0xCC, 0xA6, 0xF6,
+		0x48, 0xCC, 0x8C, 0xF6, 0x68, 0xCC, 0x8C, 0xF6,
+		0x41, 0xCC, 0x87, 0xF6, 0x61, 0xCC, 0x87, 0xF6,
+		0x45, 0xCC, 0xA7, 0xF6, 0x65, 0xCC, 0xA7, 0xF6,
+		0x4F, 0xCC, 0x88, 0xCC, 0x84, 0xF6, 0x6F, 0xCC,
+		0x88, 0xCC, 0x84, 0xF6, 0x4F, 0xCC, 0x83, 0xCC,
+		0x84, 0xF6, 0x6F, 0xCC, 0x83, 0xCC, 0x84, 0xF6,
+		0x4F, 0xCC, 0x87, 0xF6, 0x6F, 0xCC, 0x87, 0xF6,
+		0x4F, 0xCC, 0x87, 0xCC, 0x84, 0xF6, 0x6F, 0xCC,
+		0x87, 0xCC, 0x84, 0xF6, 0x59, 0xCC, 0x84, 0xF6,
+		0x79, 0xCC, 0x84, 0x68, 0xC9, 0xA6, 0x6A, 0x72,
+		0xC9, 0xB9, 0xC9, 0xBB, 0xCA, 0x81, 0x77, 0x79,
+		0x20, 0xCC, 0x86, 0x20, 0xCC, 0x87, 0x20, 0xCC,
+		0x8A, 0x20, 0xCC, 0xA8, 0x20, 0xCC, 0x83, 0x20,
+		0xCC, 0x8B, 0xC9, 0xA3, 0x6C, 0x73, 0x78, 0xCA,
+		0x95, 0xF6, 0xCC, 0x80, 0xF6, 0xCC, 0x81, 0xF6,
+		0xCC, 0x93, 0xF6, 0xCC, 0x88, 0xCC, 0x81, 0xF6,
+		0xCA, 0xB9, 0x20, 0xCD, 0x85, 0xF6, 0x3B, 0x20,
+		0xCC, 0x81, 0xF5, 0x05, 0xC2, 0xA8, 0xCC, 0x81,
+		0x20, 0xCC, 0x88, 0xCC, 0x81, 0xF6, 0xCE, 0x91,
+		0xCC, 0x81, 0xF6, 0xC2, 0xB7, 0xF6, 0xCE, 0x95,
+		0xCC, 0x81, 0xF6, 0xCE, 0x97, 0xCC, 0x81, 0xF6,
+		0xCE, 0x99, 0xCC, 0x81, 0xF6, 0xCE, 0x9F, 0xCC,
+		0x81, 0xF6, 0xCE, 0xA5, 0xCC, 0x81, 0xF6, 0xCE,
+		0xA9, 0xCC, 0x81, 0xF6, 0xCE, 0xB9, 0xCC, 0x88,
+		0xCC, 0x81, 0xF6, 0xCE, 0x99, 0xCC, 0x88, 0xF6,
+		0xCE, 0xA5, 0xCC, 0x88, 0xF6, 0xCE, 0xB1, 0xCC,
+		0x81, 0xF6, 0xCE, 0xB5, 0xCC, 0x81, 0xF6, 0xCE,
+		0xB7, 0xCC, 0x81, 0xF6, 0xCE, 0xB9, 0xCC, 0x81,
+		0xF6, 0xCF, 0x85, 0xCC, 0x88, 0xCC, 0x81, 0xF6,
+		0xCE, 0xB9, 0xCC, 0x88, 0xF6, 0xCF, 0x85, 0xCC,
+		0x88, 0xF6, 0xCE, 0xBF, 0xCC, 0x81, 0xF6, 0xCF,
+		0x85, 0xCC, 0x81, 0xF6, 0xCF, 0x89, 0xCC, 0x81,
+		0xCE, 0xB2, 0xCE, 0xB8, 0xCE, 0xA5, 0xF5, 0x05,
+		0xCF, 0x92, 0xCC, 0x81, 0xCE, 0xA5, 0xCC, 0x81,
+		0xF5, 0x05, 0xCF, 0x92, 0xCC, 0x88, 0xCE, 0xA5,
+		0xCC, 0x88, 0xCF, 0x86, 0xCF, 0x80, 0xCE, 0xBA,
+		0xCF, 0x81, 0xCF, 0x82, 0xCE, 0x98, 0xCE, 0xB5,
+		0xF6, 0xD0, 0x95, 0xCC, 0x80, 0xF6, 0xD0, 0x95,
+		0xCC, 0x88, 0xF6, 0xD0, 0x93, 0xCC, 0x81, 0xF6,
+		0xD0, 0x86, 0xCC, 0x88, 0xF6, 0xD0, 0x9A, 0xCC,
+		0x81, 0xF6, 0xD0, 0x98, 0xCC, 0x80, 0xF6, 0xD0,
+		0xA3, 0xCC, 0x86, 0xF6, 0xD0, 0x98, 0xCC, 0x86,
+		0xF6, 0xD0, 0xB8, 0xCC, 0x86, 0xF6, 0xD0, 0xB5,
+		0xCC, 0x80, 0xF6, 0xD0, 0xB5, 0xCC, 0x88, 0xF6,
+		0xD0, 0xB3, 0xCC, 0x81, 0xF6, 0xD1, 0x96, 0xCC,
+		0x88, 0xF6, 0xD0, 0xBA, 0xCC, 0x81, 0xF6, 0xD0,
+		0xB8, 0xCC, 0x80, 0xF6, 0xD1, 0x83, 0xCC, 0x86,
+		0xF6, 0xD1, 0xB4, 0xCC, 0x8F, 0xF6, 0xD1, 0xB5,
+		0xCC, 0x8F, 0xF6, 0xD0, 0x96, 0xCC, 0x86, 0xF6,
+		0xD0, 0xB6, 0xCC, 0x86, 0xF6, 0xD0, 0x90, 0xCC,
+		0x86, 0xF6, 0xD0, 0xB0, 0xCC, 0x86, 0xF6, 0xD0,
+		0x90, 0xCC, 0x88, 0xF6, 0xD0, 0xB0, 0xCC, 0x88,
+		0xF6, 0xD0, 0x95, 0xCC, 0x86, 0xF6, 0xD0, 0xB5,
+		0xCC, 0x86, 0xF6, 0xD3, 0x98, 0xCC, 0x88, 0xF6,
+		0xD3, 0x99, 0xCC, 0x88, 0xF6, 0xD0, 0x96, 0xCC,
+		0x88, 0xF6, 0xD0, 0xB6, 0xCC, 0x88, 0xF6, 0xD0,
+		0x97, 0xCC, 0x88, 0xF6, 0xD0, 0xB7, 0xCC, 0x88,
+		0xF6, 0xD0, 0x98, 0xCC, 0x84, 0xF6, 0xD0, 0xB8,
+		0xCC, 0x84, 0xF6, 0xD0, 0x98, 0xCC, 0x88, 0xF6,
+		0xD0, 0xB8, 0xCC, 0x88, 0xF6, 0xD0, 0x9E, 0xCC,
+		0x88, 0xF6, 0xD0, 0xBE, 0xCC, 0x88, 0xF6, 0xD3,
+		0xA8, 0xCC, 0x88, 0xF6, 0xD3, 0xA9, 0xCC, 0x88,
+		0xF6, 0xD0, 0xAD, 0xCC, 0x88, 0xF6, 0xD1, 0x8D,
+		0xCC, 0x88, 0xF6, 0xD0, 0xA3, 0xCC, 0x84, 0xF6,
+		0xD1, 0x83, 0xCC, 0x84, 0xF6, 0xD0, 0xA3, 0xCC,
+		0x88, 0xF6, 0xD1, 0x83, 0xCC, 0x88, 0xF6, 0xD0,
+		0xA3, 0xCC, 0x8B, 0xF6, 0xD1, 0x83, 0xCC, 0x8B,
+		0xF6, 0xD0, 0xA7, 0xCC, 0x88, 0xF6, 0xD1, 0x87,
+		0xCC, 0x88, 0xF6, 0xD0, 0xAB, 0xCC, 0x88, 0xF6,
+		0xD1, 0x8B, 0xCC, 0x88, 0xD5, 0xA5, 0xD6, 0x82,
+		0xF6, 0xD8, 0xA7, 0xD9, 0x93, 0xF6, 0xD8, 0xA7,
+		0xD9, 0x94, 0xF6, 0xD9, 0x88, 0xD9, 0x94, 0xF6,
+		0xD8, 0xA7, 0xD9, 0x95, 0xF6, 0xD9, 0x8A, 0xD9,
+		0x94, 0xD8, 0xA7, 0xD9, 0xB4, 0xD9, 0x88, 0xD9,
+		0xB4, 0xDB, 0x87, 0xD9, 0xB4, 0xD9, 0x8A, 0xD9,
+		0xB4, 0xF6, 0xDB, 0x95, 0xD9, 0x94, 0xF6, 0xDB,
+		0x81, 0xD9, 0x94, 0xF6, 0xDB, 0x92, 0xD9, 0x94,
+		0xF6, 0xE0, 0xA4, 0xA8, 0xE0, 0xA4, 0xBC, 0xF6,
+		0xE0, 0xA4, 0xB0, 0xE0, 0xA4, 0xBC, 0xF6, 0xE0,
+		0xA4, 0xB3, 0xE0, 0xA4, 0xBC, 0xF6, 0xE0, 0xA4,
+		0x95, 0xE0, 0xA4, 0xBC, 0xF6, 0xE0, 0xA4, 0x96,
+		0xE0, 0xA4, 0xBC, 0xF6, 0xE0, 0xA4, 0x97, 0xE0,
+		0xA4, 0xBC, 0xF6, 0xE0, 0xA4, 0x9C, 0xE0, 0xA4,
+		0xBC, 0xF6, 0xE0, 0xA4, 0xA1, 0xE0, 0xA4, 0xBC,
+		0xF6, 0xE0, 0xA4, 0xA2, 0xE0, 0xA4, 0xBC, 0xF6,
+		0xE0, 0xA4, 0xAB, 0xE0, 0xA4, 0xBC, 0xF6, 0xE0,
+		0xA4, 0xAF, 0xE0, 0xA4, 0xBC, 0xF6, 0xE0, 0xA7,
+		0x87, 0xE0, 0xA6, 0xBE, 0xF6, 0xE0, 0xA7, 0x87,
+		0xE0, 0xA7, 0x97, 0xF6, 0xE0, 0xA6, 0xA1, 0xE0,
+		0xA6, 0xBC, 0xF6, 0xE0, 0xA6, 0xA2, 0xE0, 0xA6,
+		0xBC, 0xF6, 0xE0, 0xA6, 0xAF, 0xE0, 0xA6, 0xBC,
+		0xF6, 0xE0, 0xA8, 0xB2, 0xE0, 0xA8, 0xBC, 0xF6,
+		0xE0, 0xA8, 0xB8, 0xE0, 0xA8, 0xBC, 0xF6, 0xE0,
+		0xA8, 0x96, 0xE0, 0xA8, 0xBC, 0xF6, 0xE0, 0xA8,
+		0x97, 0xE0, 0xA8, 0xBC, 0xF6, 0xE0, 0xA8, 0x9C,
+		0xE0, 0xA8, 0xBC, 0xF6, 0xE0, 0xA8, 0xAB, 0xE0,
+		0xA8, 0xBC, 0xF6, 0xE0, 0xAD, 0x87, 0xE0, 0xAD,
+		0x96, 0xF6, 0xE0, 0xAD, 0x87, 0xE0, 0xAC, 0xBE,
+		0xF6, 0xE0, 0xAD, 0x87, 0xE0, 0xAD, 0x97, 0xF6,
+		0xE0, 0xAC, 0xA1, 0xE0, 0xAC, 0xBC, 0xF6, 0xE0,
+		0xAC, 0xA2, 0xE0, 0xAC, 0xBC, 0xF6, 0xE0, 0xAE,
+		0x92, 0xE0, 0xAF, 0x97, 0xF6, 0xE0, 0xAF, 0x86,
+		0xE0, 0xAE, 0xBE, 0xF6, 0xE0, 0xAF, 0x87, 0xE0,
+		0xAE, 0xBE, 0xF6, 0xE0, 0xAF, 0x86, 0xE0, 0xAF,
+		0x97, 0xF6, 0xE0, 0xB1, 0x86, 0xE0, 0xB1, 0x96,
+		0xF6, 0xE0, 0xB2, 0xBF, 0xE0, 0xB3, 0x95, 0xF6,
+		0xE0, 0xB3, 0x86, 0xE0, 0xB3, 0x95, 0xF6, 0xE0,
+		0xB3, 0x86, 0xE0, 0xB3, 0x96, 0xF6, 0xE0, 0xB3,
+		0x86, 0xE0, 0xB3, 0x82, 0xF6, 0xE0, 0xB3, 0x86,
+		0xE0, 0xB3, 0x82, 0xE0, 0xB3, 0x95, 0xF6, 0xE0,
+		0xB5, 0x86, 0xE0, 0xB4, 0xBE, 0xF6, 0xE0, 0xB5,
+		0x87, 0xE0, 0xB4, 0xBE, 0xF6, 0xE0, 0xB5, 0x86,
+		0xE0, 0xB5, 0x97, 0xF6, 0xE0, 0xB7, 0x99, 0xE0,
+		0xB7, 0x8A, 0xF6, 0xE0, 0xB7, 0x99, 0xE0, 0xB7,
+		0x8F, 0xF6, 0xE0, 0xB7, 0x99, 0xE0, 0xB7, 0x8F,
+		0xE0, 0xB7, 0x8A, 0xF6, 0xE0, 0xB7, 0x99, 0xE0,
+		0xB7, 0x9F, 0xE0, 0xB9, 0x8D, 0xE0, 0xB8, 0xB2,
+		0xE0, 0xBB, 0x8D, 0xE0, 0xBA, 0xB2, 0xE0, 0xBA,
+		0xAB, 0xE0, 0xBA, 0x99, 0xE0, 0xBA, 0xAB, 0xE0,
+		0xBA, 0xA1, 0xE0, 0xBC, 0x8B, 0xF6, 0xE0, 0xBD,
+		0x82, 0xE0, 0xBE, 0xB7, 0xF6, 0xE0, 0xBD, 0x8C,
+		0xE0, 0xBE, 0xB7, 0xF6, 0xE0, 0xBD, 0x91, 0xE0,
+		0xBE, 0xB7, 0xF6, 0xE0, 0xBD, 0x96, 0xE0, 0xBE,
+		0xB7, 0xF6, 0xE0, 0xBD, 0x9B, 0xE0, 0xBE, 0xB7,
+		0xF6, 0xE0, 0xBD, 0x80, 0xE0, 0xBE, 0xB5, 0xF6,
+		0xE0, 0xBD, 0xB1, 0xE0, 0xBD, 0xB2, 0xF6, 0xE0,
+		0xBD, 0xB1, 0xE0, 0xBD, 0xB4, 0xF6, 0xE0, 0xBE,
+		0xB2, 0xE0, 0xBE, 0x80, 0xE0, 0xBE, 0xB2, 0xE0,
+		0xBD, 0xB1, 0xE0, 0xBE, 0x80, 0xF6, 0xE0, 0xBE,
+		0xB3, 0xE0, 0xBE, 0x80, 0xE0, 0xBE, 0xB3, 0xE0,
+		0xBD, 0xB1, 0xE0, 0xBE, 0x80, 0xF6, 0xE0, 0xBD,
+		0xB1, 0xE0, 0xBE, 0x80, 0xF6, 0xE0, 0xBE, 0x92,
+		0xE0, 0xBE, 0xB7, 0xF6, 0xE0, 0xBE, 0x9C, 0xE0,
+		0xBE, 0xB7, 0xF6, 0xE0, 0xBE, 0xA1, 0xE0, 0xBE,
+		0xB7, 0xF6, 0xE0, 0xBE, 0xA6, 0xE0, 0xBE, 0xB7,
+		0xF6, 0xE0, 0xBE, 0xAB, 0xE0, 0xBE, 0xB7, 0xF6,
+		0xE0, 0xBE, 0x90, 0xE0, 0xBE, 0xB5, 0xF6, 0xE1,
+		0x80, 0xA5, 0xE1, 0x80, 0xAE, 0xF6, 0x41, 0xCC,
+		0xA5, 0xF6, 0x61, 0xCC, 0xA5, 0xF6, 0x42, 0xCC,
+		0x87, 0xF6, 0x62, 0xCC, 0x87, 0xF6, 0x42, 0xCC,
+		0xA3, 0xF6, 0x62, 0xCC, 0xA3, 0xF6, 0x42, 0xCC,
+		0xB1, 0xF6, 0x62, 0xCC, 0xB1, 0xF6, 0x43, 0xCC,
+		0xA7, 0xCC, 0x81, 0xF6, 0x63, 0xCC, 0xA7, 0xCC,
+		0x81, 0xF6, 0x44, 0xCC, 0x87, 0xF6, 0x64, 0xCC,
+		0x87, 0xF6, 0x44, 0xCC, 0xA3, 0xF6, 0x64, 0xCC,
+		0xA3, 0xF6, 0x44, 0xCC, 0xB1, 0xF6, 0x64, 0xCC,
+		0xB1, 0xF6, 0x44, 0xCC, 0xA7, 0xF6, 0x64, 0xCC,
+		0xA7, 0xF6, 0x44, 0xCC, 0xAD, 0xF6, 0x64, 0xCC,
+		0xAD, 0xF6, 0x45, 0xCC, 0x84, 0xCC, 0x80, 0xF6,
+		0x65, 0xCC, 0x84, 0xCC, 0x80, 0xF6, 0x45, 0xCC,
+		0x84, 0xCC, 0x81, 0xF6, 0x65, 0xCC, 0x84, 0xCC,
+		0x81, 0xF6, 0x45, 0xCC, 0xAD, 0xF6, 0x65, 0xCC,
+		0xAD, 0xF6, 0x45, 0xCC, 0xB0, 0xF6, 0x65, 0xCC,
+		0xB0, 0xF6, 0x45, 0xCC, 0xA7, 0xCC, 0x86, 0xF6,
+		0x65, 0xCC, 0xA7, 0xCC, 0x86, 0xF6, 0x46, 0xCC,
+		0x87, 0xF6, 0x66, 0xCC, 0x87, 0xF6, 0x47, 0xCC,
+		0x84, 0xF6, 0x67, 0xCC, 0x84, 0xF6, 0x48, 0xCC,
+		0x87, 0xF6, 0x68, 0xCC, 0x87, 0xF6, 0x48, 0xCC,
+		0xA3, 0xF6, 0x68, 0xCC, 0xA3, 0xF6, 0x48, 0xCC,
+		0x88, 0xF6, 0x68, 0xCC, 0x88, 0xF6, 0x48, 0xCC,
+		0xA7, 0xF6, 0x68, 0xCC, 0xA7, 0xF6, 0x48, 0xCC,
+		0xAE, 0xF6, 0x68, 0xCC, 0xAE, 0xF6, 0x49, 0xCC,
+		0xB0, 0xF6, 0x69, 0xCC, 0xB0, 0xF6, 0x49, 0xCC,
+		0x88, 0xCC, 0x81, 0xF6, 0x69, 0xCC, 0x88, 0xCC,
+		0x81, 0xF6, 0x4B, 0xCC, 0x81, 0xF6, 0x6B, 0xCC,
+		0x81, 0xF6, 0x4B, 0xCC, 0xA3, 0xF6, 0x6B, 0xCC,
+		0xA3, 0xF6, 0x4B, 0xCC, 0xB1, 0xF6, 0x6B, 0xCC,
+		0xB1, 0xF6, 0x4C, 0xCC, 0xA3, 0xF6, 0x6C, 0xCC,
+		0xA3, 0xF6, 0x4C, 0xCC, 0xA3, 0xCC, 0x84, 0xF6,
+		0x6C, 0xCC, 0xA3, 0xCC, 0x84, 0xF6, 0x4C, 0xCC,
+		0xB1, 0xF6, 0x6C, 0xCC, 0xB1, 0xF6, 0x4C, 0xCC,
+		0xAD, 0xF6, 0x6C, 0xCC, 0xAD, 0xF6, 0x4D, 0xCC,
+		0x81, 0xF6, 0x6D, 0xCC, 0x81, 0xF6, 0x4D, 0xCC,
+		0x87, 0xF6, 0x6D, 0xCC, 0x87, 0xF6, 0x4D, 0xCC,
+		0xA3, 0xF6, 0x6D, 0xCC, 0xA3, 0xF6, 0x4E, 0xCC,
+		0x87, 0xF6, 0x6E, 0xCC, 0x87, 0xF6, 0x4E, 0xCC,
+		0xA3, 0xF6, 0x6E, 0xCC, 0xA3, 0xF6, 0x4E, 0xCC,
+		0xB1, 0xF6, 0x6E, 0xCC, 0xB1, 0xF6, 0x4E, 0xCC,
+		0xAD, 0xF6, 0x6E, 0xCC, 0xAD, 0xF6, 0x4F, 0xCC,
+		0x83, 0xCC, 0x81, 0xF6, 0x6F, 0xCC, 0x83, 0xCC,
+		0x81, 0xF6, 0x4F, 0xCC, 0x83, 0xCC, 0x88, 0xF6,
+		0x6F, 0xCC, 0x83, 0xCC, 0x88, 0xF6, 0x4F, 0xCC,
+		0x84, 0xCC, 0x80, 0xF6, 0x6F, 0xCC, 0x84, 0xCC,
+		0x80, 0xF6, 0x4F, 0xCC, 0x84, 0xCC, 0x81, 0xF6,
+		0x6F, 0xCC, 0x84, 0xCC, 0x81, 0xF6, 0x50, 0xCC,
+		0x81, 0xF6, 0x70, 0xCC, 0x81, 0xF6, 0x50, 0xCC,
+		0x87, 0xF6, 0x70, 0xCC, 0x87, 0xF6, 0x52, 0xCC,
+		0x87, 0xF6, 0x72, 0xCC, 0x87, 0xF6, 0x52, 0xCC,
+		0xA3, 0xF6, 0x72, 0xCC, 0xA3, 0xF6, 0x52, 0xCC,
+		0xA3, 0xCC, 0x84, 0xF6, 0x72, 0xCC, 0xA3, 0xCC,
+		0x84, 0xF6, 0x52, 0xCC, 0xB1, 0xF6, 0x72, 0xCC,
+		0xB1, 0xF6, 0x53, 0xCC, 0x87, 0xF6, 0x73, 0xCC,
+		0x87, 0xF6, 0x53, 0xCC, 0xA3, 0xF6, 0x73, 0xCC,
+		0xA3, 0xF6, 0x53, 0xCC, 0x81, 0xCC, 0x87, 0xF6,
+		0x73, 0xCC, 0x81, 0xCC, 0x87, 0xF6, 0x53, 0xCC,
+		0x8C, 0xCC, 0x87, 0xF6, 0x73, 0xCC, 0x8C, 0xCC,
+		0x87, 0xF6, 0x53, 0xCC, 0xA3, 0xCC, 0x87, 0xF6,
+		0x73, 0xCC, 0xA3, 0xCC, 0x87, 0xF6, 0x54, 0xCC,
+		0x87, 0xF6, 0x74, 0xCC, 0x87, 0xF6, 0x54, 0xCC,
+		0xA3, 0xF6, 0x74, 0xCC, 0xA3, 0xF6, 0x54, 0xCC,
+		0xB1, 0xF6, 0x74, 0xCC, 0xB1, 0xF6, 0x54, 0xCC,
+		0xAD, 0xF6, 0x74, 0xCC, 0xAD, 0xF6, 0x55, 0xCC,
+		0xA4, 0xF6, 0x75, 0xCC, 0xA4, 0xF6, 0x55, 0xCC,
+		0xB0, 0xF6, 0x75, 0xCC, 0xB0, 0xF6, 0x55, 0xCC,
+		0xAD, 0xF6, 0x75, 0xCC, 0xAD, 0xF6, 0x55, 0xCC,
+		0x83, 0xCC, 0x81, 0xF6, 0x75, 0xCC, 0x83, 0xCC,
+		0x81, 0xF6, 0x55, 0xCC, 0x84, 0xCC, 0x88, 0xF6,
+		0x75, 0xCC, 0x84, 0xCC, 0x88, 0xF6, 0x56, 0xCC,
+		0x83, 0xF6, 0x76, 0xCC, 0x83, 0xF6, 0x56, 0xCC,
+		0xA3, 0xF6, 0x76, 0xCC, 0xA3, 0xF6, 0x57, 0xCC,
+		0x80, 0xF6, 0x77, 0xCC, 0x80, 0xF6, 0x57, 0xCC,
+		0x81, 0xF6, 0x77, 0xCC, 0x81, 0xF6, 0x57, 0xCC,
+		0x88, 0xF6, 0x77, 0xCC, 0x88, 0xF6, 0x57, 0xCC,
+		0x87, 0xF6, 0x77, 0xCC, 0x87, 0xF6, 0x57, 0xCC,
+		0xA3, 0xF6, 0x77, 0xCC, 0xA3, 0xF6, 0x58, 0xCC,
+		0x87, 0xF6, 0x78, 0xCC, 0x87, 0xF6, 0x58, 0xCC,
+		0x88, 0xF6, 0x78, 0xCC, 0x88, 0xF6, 0x59, 0xCC,
+		0x87, 0xF6, 0x79, 0xCC, 0x87, 0xF6, 0x5A, 0xCC,
+		0x82, 0xF6, 0x7A, 0xCC, 0x82, 0xF6, 0x5A, 0xCC,
+		0xA3, 0xF6, 0x7A, 0xCC, 0xA3, 0xF6, 0x5A, 0xCC,
+		0xB1, 0xF6, 0x7A, 0xCC, 0xB1, 0xF6, 0x68, 0xCC,
+		0xB1, 0xF6, 0x74, 0xCC, 0x88, 0xF6, 0x77, 0xCC,
+		0x8A, 0xF6, 0x79, 0xCC, 0x8A, 0x61, 0xCA, 0xBE,
+		0xF5, 0x05, 0xC5, 0xBF, 0xCC, 0x87, 0x73, 0xCC,
+		0x87, 0xF6, 0x41, 0xCC, 0xA3, 0xF6, 0x61, 0xCC,
+		0xA3, 0xF6, 0x41, 0xCC, 0x89, 0xF6, 0x61, 0xCC,
+		0x89, 0xF6, 0x41, 0xCC, 0x82, 0xCC, 0x81, 0xF6,
+		0x61, 0xCC, 0x82, 0xCC, 0x81, 0xF6, 0x41, 0xCC,
+		0x82, 0xCC, 0x80, 0xF6, 0x61, 0xCC, 0x82, 0xCC,
+		0x80, 0xF6, 0x41, 0xCC, 0x82, 0xCC, 0x89, 0xF6,
+		0x61, 0xCC, 0x82, 0xCC, 0x89, 0xF6, 0x41, 0xCC,
+		0x82, 0xCC, 0x83, 0xF6, 0x61, 0xCC, 0x82, 0xCC,
+		0x83, 0xF6, 0x41, 0xCC, 0xA3, 0xCC, 0x82, 0xF6,
+		0x61, 0xCC, 0xA3, 0xCC, 0x82, 0xF6, 0x41, 0xCC,
+		0x86, 0xCC, 0x81, 0xF6, 0x61, 0xCC, 0x86, 0xCC,
+		0x81, 0xF6, 0x41, 0xCC, 0x86, 0xCC, 0x80, 0xF6,
+		0x61, 0xCC, 0x86, 0xCC, 0x80, 0xF6, 0x41, 0xCC,
+		0x86, 0xCC, 0x89, 0xF6, 0x61, 0xCC, 0x86, 0xCC,
+		0x89, 0xF6, 0x41, 0xCC, 0x86, 0xCC, 0x83, 0xF6,
+		0x61, 0xCC, 0x86, 0xCC, 0x83, 0xF6, 0x41, 0xCC,
+		0xA3, 0xCC, 0x86, 0xF6, 0x61, 0xCC, 0xA3, 0xCC,
+		0x86, 0xF6, 0x45, 0xCC, 0xA3, 0xF6, 0x65, 0xCC,
+		0xA3, 0xF6, 0x45, 0xCC, 0x89, 0xF6, 0x65, 0xCC,
+		0x89, 0xF6, 0x45, 0xCC, 0x83, 0xF6, 0x65, 0xCC,
+		0x83, 0xF6, 0x45, 0xCC, 0x82, 0xCC, 0x81, 0xF6,
+		0x65, 0xCC, 0x82, 0xCC, 0x81, 0xF6, 0x45, 0xCC,
+		0x82, 0xCC, 0x80, 0xF6, 0x65, 0xCC, 0x82, 0xCC,
+		0x80, 0xF6, 0x45, 0xCC, 0x82, 0xCC, 0x89, 0xF6,
+		0x65, 0xCC, 0x82, 0xCC, 0x89, 0xF6, 0x45, 0xCC,
+		0x82, 0xCC, 0x83, 0xF6, 0x65, 0xCC, 0x82, 0xCC,
+		0x83, 0xF6, 0x45, 0xCC, 0xA3, 0xCC, 0x82, 0xF6,
+		0x65, 0xCC, 0xA3, 0xCC, 0x82, 0xF6, 0x49, 0xCC,
+		0x89, 0xF6, 0x69, 0xCC, 0x89, 0xF6, 0x49, 0xCC,
+		0xA3, 0xF6, 0x69, 0xCC, 0xA3, 0xF6, 0x4F, 0xCC,
+		0xA3, 0xF6, 0x6F, 0xCC, 0xA3, 0xF6, 0x4F, 0xCC,
+		0x89, 0xF6, 0x6F, 0xCC, 0x89, 0xF6, 0x4F, 0xCC,
+		0x82, 0xCC, 0x81, 0xF6, 0x6F, 0xCC, 0x82, 0xCC,
+		0x81, 0xF6, 0x4F, 0xCC, 0x82, 0xCC, 0x80, 0xF6,
+		0x6F, 0xCC, 0x82, 0xCC, 0x80, 0xF6, 0x4F, 0xCC,
+		0x82, 0xCC, 0x89, 0xF6, 0x6F, 0xCC, 0x82, 0xCC,
+		0x89, 0xF6, 0x4F, 0xCC, 0x82, 0xCC, 0x83, 0xF6,
+		0x6F, 0xCC, 0x82, 0xCC, 0x83, 0xF6, 0x4F, 0xCC,
+		0xA3, 0xCC, 0x82, 0xF6, 0x6F, 0xCC, 0xA3, 0xCC,
+		0x82, 0xF6, 0x4F, 0xCC, 0x9B, 0xCC, 0x81, 0xF6,
+		0x6F, 0xCC, 0x9B, 0xCC, 0x81, 0xF6, 0x4F, 0xCC,
+		0x9B, 0xCC, 0x80, 0xF6, 0x6F, 0xCC, 0x9B, 0xCC,
+		0x80, 0xF6, 0x4F, 0xCC, 0x9B, 0xCC, 0x89, 0xF6,
+		0x6F, 0xCC, 0x9B, 0xCC, 0x89, 0xF6, 0x4F, 0xCC,
+		0x9B, 0xCC, 0x83, 0xF6, 0x6F, 0xCC, 0x9B, 0xCC,
+		0x83, 0xF6, 0x4F, 0xCC, 0x9B, 0xCC, 0xA3, 0xF6,
+		0x6F, 0xCC, 0x9B, 0xCC, 0xA3, 0xF6, 0x55, 0xCC,
+		0xA3, 0xF6, 0x75, 0xCC, 0xA3, 0xF6, 0x55, 0xCC,
+		0x89, 0xF6, 0x75, 0xCC, 0x89, 0xF6, 0x55, 0xCC,
+		0x9B, 0xCC, 0x81, 0xF6, 0x75, 0xCC, 0x9B, 0xCC,
+		0x81, 0xF6, 0x55, 0xCC, 0x9B, 0xCC, 0x80, 0xF6,
+		0x75, 0xCC, 0x9B, 0xCC, 0x80, 0xF6, 0x55, 0xCC,
+		0x9B, 0xCC, 0x89, 0xF6, 0x75, 0xCC, 0x9B, 0xCC,
+		0x89, 0xF6, 0x55, 0xCC, 0x9B, 0xCC, 0x83, 0xF6,
+		0x75, 0xCC, 0x9B, 0xCC, 0x83, 0xF6, 0x55, 0xCC,
+		0x9B, 0xCC, 0xA3, 0xF6, 0x75, 0xCC, 0x9B, 0xCC,
+		0xA3, 0xF6, 0x59, 0xCC, 0x80, 0xF6, 0x79, 0xCC,
+		0x80, 0xF6, 0x59, 0xCC, 0xA3, 0xF6, 0x79, 0xCC,
+		0xA3, 0xF6, 0x59, 0xCC, 0x89, 0xF6, 0x79, 0xCC,
+		0x89, 0xF6, 0x59, 0xCC, 0x83, 0xF6, 0x79, 0xCC,
+		0x83, 0xF6, 0xCE, 0xB1, 0xCC, 0x93, 0xF6, 0xCE,
+		0xB1, 0xCC, 0x94, 0xF6, 0xCE, 0xB1, 0xCC, 0x93,
+		0xCC, 0x80, 0xF6, 0xCE, 0xB1, 0xCC, 0x94, 0xCC,
+		0x80, 0xF6, 0xCE, 0xB1, 0xCC, 0x93, 0xCC, 0x81,
+		0xF6, 0xCE, 0xB1, 0xCC, 0x94, 0xCC, 0x81, 0xF6,
+		0xCE, 0xB1, 0xCC, 0x93, 0xCD, 0x82, 0xF6, 0xCE,
+		0xB1, 0xCC, 0x94, 0xCD, 0x82, 0xF6, 0xCE, 0x91,
+		0xCC, 0x93, 0xF6, 0xCE, 0x91, 0xCC, 0x94, 0xF6,
+		0xCE, 0x91, 0xCC, 0x93, 0xCC, 0x80, 0xF6, 0xCE,
+		0x91, 0xCC, 0x94, 0xCC, 0x80, 0xF6, 0xCE, 0x91,
+		0xCC, 0x93, 0xCC, 0x81, 0xF6, 0xCE, 0x91, 0xCC,
+		0x94, 0xCC, 0x81, 0xF6, 0xCE, 0x91, 0xCC, 0x93,
+		0xCD, 0x82, 0xF6, 0xCE, 0x91, 0xCC, 0x94, 0xCD,
+		0x82, 0xF6, 0xCE, 0xB5, 0xCC, 0x93, 0xF6, 0xCE,
+		0xB5, 0xCC, 0x94, 0xF6, 0xCE, 0xB5, 0xCC, 0x93,
+		0xCC, 0x80, 0xF6, 0xCE, 0xB5, 0xCC, 0x94, 0xCC,
+		0x80, 0xF6, 0xCE, 0xB5, 0xCC, 0x93, 0xCC, 0x81,
+		0xF6, 0xCE, 0xB5, 0xCC, 0x94, 0xCC, 0x81, 0xF6,
+		0xCE, 0x95, 0xCC, 0x93, 0xF6, 0xCE, 0x95, 0xCC,
+		0x94, 0xF6, 0xCE, 0x95, 0xCC, 0x93, 0xCC, 0x80,
+		0xF6, 0xCE, 0x95, 0xCC, 0x94, 0xCC, 0x80, 0xF6,
+		0xCE, 0x95, 0xCC, 0x93, 0xCC, 0x81, 0xF6, 0xCE,
+		0x95, 0xCC, 0x94, 0xCC, 0x81, 0xF6, 0xCE, 0xB7,
+		0xCC, 0x93, 0xF6, 0xCE, 0xB7, 0xCC, 0x94, 0xF6,
+		0xCE, 0xB7, 0xCC, 0x93, 0xCC, 0x80, 0xF6, 0xCE,
+		0xB7, 0xCC, 0x94, 0xCC, 0x80, 0xF6, 0xCE, 0xB7,
+		0xCC, 0x93, 0xCC, 0x81, 0xF6, 0xCE, 0xB7, 0xCC,
+		0x94, 0xCC, 0x81, 0xF6, 0xCE, 0xB7, 0xCC, 0x93,
+		0xCD, 0x82, 0xF6, 0xCE, 0xB7, 0xCC, 0x94, 0xCD,
+		0x82, 0xF6, 0xCE, 0x97, 0xCC, 0x93, 0xF6, 0xCE,
+		0x97, 0xCC, 0x94, 0xF6, 0xCE, 0x97, 0xCC, 0x93,
+		0xCC, 0x80, 0xF6, 0xCE, 0x97, 0xCC, 0x94, 0xCC,
+		0x80, 0xF6, 0xCE, 0x97, 0xCC, 0x93, 0xCC, 0x81,
+		0xF6, 0xCE, 0x97, 0xCC, 0x94, 0xCC, 0x81, 0xF6,
+		0xCE, 0x97, 0xCC, 0x93, 0xCD, 0x82, 0xF6, 0xCE,
+		0x97, 0xCC, 0x94, 0xCD, 0x82, 0xF6, 0xCE, 0xB9,
+		0xCC, 0x93, 0xF6, 0xCE, 0xB9, 0xCC, 0x94, 0xF6,
+		0xCE, 0xB9, 0xCC, 0x93, 0xCC, 0x80, 0xF6, 0xCE,
+		0xB9, 0xCC, 0x94, 0xCC, 0x80, 0xF6, 0xCE, 0xB9,
+		0xCC, 0x93, 0xCC, 0x81, 0xF6, 0xCE, 0xB9, 0xCC,
+		0x94, 0xCC, 0x81, 0xF6, 0xCE, 0xB9, 0xCC, 0x93,
+		0xCD, 0x82, 0xF6, 0xCE, 0xB9, 0xCC, 0x94, 0xCD,
+		0x82, 0xF6, 0xCE, 0x99, 0xCC, 0x93, 0xF6, 0xCE,
+		0x99, 0xCC, 0x94, 0xF6, 0xCE, 0x99, 0xCC, 0x93,
+		0xCC, 0x80, 0xF6, 0xCE, 0x99, 0xCC, 0x94, 0xCC,
+		0x80, 0xF6, 0xCE, 0x99, 0xCC, 0x93, 0xCC, 0x81,
+		0xF6, 0xCE, 0x99, 0xCC, 0x94, 0xCC, 0x81, 0xF6,
+		0xCE, 0x99, 0xCC, 0x93, 0xCD, 0x82, 0xF6, 0xCE,
+		0x99, 0xCC, 0x94, 0xCD, 0x82, 0xF6, 0xCE, 0xBF,
+		0xCC, 0x93, 0xF6, 0xCE, 0xBF, 0xCC, 0x94, 0xF6,
+		0xCE, 0xBF, 0xCC, 0x93, 0xCC, 0x80, 0xF6, 0xCE,
+		0xBF, 0xCC, 0x94, 0xCC, 0x80, 0xF6, 0xCE, 0xBF,
+		0xCC, 0x93, 0xCC, 0x81, 0xF6, 0xCE, 0xBF, 0xCC,
+		0x94, 0xCC, 0x81, 0xF6, 0xCE, 0x9F, 0xCC, 0x93,
+		0xF6, 0xCE, 0x9F, 0xCC, 0x94, 0xF6, 0xCE, 0x9F,
+		0xCC, 0x93, 0xCC, 0x80, 0xF6, 0xCE, 0x9F, 0xCC,
+		0x94, 0xCC, 0x80, 0xF6, 0xCE, 0x9F, 0xCC, 0x93,
+		0xCC, 0x81, 0xF6, 0xCE, 0x9F, 0xCC, 0x94, 0xCC,
+		0x81, 0xF6, 0xCF, 0x85, 0xCC, 0x93, 0xF6, 0xCF,
+		0x85, 0xCC, 0x94, 0xF6, 0xCF, 0x85, 0xCC, 0x93,
+		0xCC, 0x80, 0xF6, 0xCF, 0x85, 0xCC, 0x94, 0xCC,
+		0x80, 0xF6, 0xCF, 0x85, 0xCC, 0x93, 0xCC, 0x81,
+		0xF6, 0xCF, 0x85, 0xCC, 0x94, 0xCC, 0x81, 0xF6,
+		0xCF, 0x85, 0xCC, 0x93, 0xCD, 0x82, 0xF6, 0xCF,
+		0x85, 0xCC, 0x94, 0xCD, 0x82, 0xF6, 0xCE, 0xA5,
+		0xCC, 0x94, 0xF6, 0xCE, 0xA5, 0xCC, 0x94, 0xCC,
+		0x80, 0xF6, 0xCE, 0xA5, 0xCC, 0x94, 0xCC, 0x81,
+		0xF6, 0xCE, 0xA5, 0xCC, 0x94, 0xCD, 0x82, 0xF6,
+		0xCF, 0x89, 0xCC, 0x93, 0xF6, 0xCF, 0x89, 0xCC,
+		0x94, 0xF6, 0xCF, 0x89, 0xCC, 0x93, 0xCC, 0x80,
+		0xF6, 0xCF, 0x89, 0xCC, 0x94, 0xCC, 0x80, 0xF6,
+		0xCF, 0x89, 0xCC, 0x93, 0xCC, 0x81, 0xF6, 0xCF,
+		0x89, 0xCC, 0x94, 0xCC, 0x81, 0xF6, 0xCF, 0x89,
+		0xCC, 0x93, 0xCD, 0x82, 0xF6, 0xCF, 0x89, 0xCC,
+		0x94, 0xCD, 0x82, 0xF6, 0xCE, 0xA9, 0xCC, 0x93,
+		0xF6, 0xCE, 0xA9, 0xCC, 0x94, 0xF6, 0xCE, 0xA9,
+		0xCC, 0x93, 0xCC, 0x80, 0xF6, 0xCE, 0xA9, 0xCC,
+		0x94, 0xCC, 0x80, 0xF6, 0xCE, 0xA9, 0xCC, 0x93,
+		0xCC, 0x81, 0xF6, 0xCE, 0xA9, 0xCC, 0x94, 0xCC,
+		0x81, 0xF6, 0xCE, 0xA9, 0xCC, 0x93, 0xCD, 0x82,
+		0xF6, 0xCE, 0xA9, 0xCC, 0x94, 0xCD, 0x82, 0xF6,
+		0xCE, 0xB1, 0xCC, 0x80, 0xF6, 0xCE, 0xB1, 0xCC,
+		0x81, 0xF6, 0xCE, 0xB5, 0xCC, 0x80, 0xF6, 0xCE,
+		0xB5, 0xCC, 0x81, 0xF6, 0xCE, 0xB7, 0xCC, 0x80,
+		0xF6, 0xCE, 0xB7, 0xCC, 0x81, 0xF6, 0xCE, 0xB9,
+		0xCC, 0x80, 0xF6, 0xCE, 0xB9, 0xCC, 0x81, 0xF6,
+		0xCE, 0xBF, 0xCC, 0x80, 0xF6, 0xCE, 0xBF, 0xCC,
+		0x81, 0xF6, 0xCF, 0x85, 0xCC, 0x80, 0xF6, 0xCF,
+		0x85, 0xCC, 0x81, 0xF6, 0xCF, 0x89, 0xCC, 0x80,
+		0xF6, 0xCF, 0x89, 0xCC, 0x81, 0xF6, 0xCE, 0xB1,
+		0xCC, 0x93, 0xCD, 0x85, 0xF6, 0xCE, 0xB1, 0xCC,
+		0x94, 0xCD, 0x85, 0xF6, 0xCE, 0xB1, 0xCC, 0x93,
+		0xCC, 0x80, 0xCD, 0x85, 0xF6, 0xCE, 0xB1, 0xCC,
+		0x94, 0xCC, 0x80, 0xCD, 0x85, 0xF6, 0xCE, 0xB1,
+		0xCC, 0x93, 0xCC, 0x81, 0xCD, 0x85, 0xF6, 0xCE,
+		0xB1, 0xCC, 0x94, 0xCC, 0x81, 0xCD, 0x85, 0xF6,
+		0xCE, 0xB1, 0xCC, 0x93, 0xCD, 0x82, 0xCD, 0x85,
+		0xF6, 0xCE, 0xB1, 0xCC, 0x94, 0xCD, 0x82, 0xCD,
+		0x85, 0xF6, 0xCE, 0x91, 0xCC, 0x93, 0xCD, 0x85,
+		0xF6, 0xCE, 0x91, 0xCC, 0x94, 0xCD, 0x85, 0xF6,
+		0xCE, 0x91, 0xCC, 0x93, 0xCC, 0x80, 0xCD, 0x85,
+		0xF6, 0xCE, 0x91, 0xCC, 0x94, 0xCC, 0x80, 0xCD,
+		0x85, 0xF6, 0xCE, 0x91, 0xCC, 0x93, 0xCC, 0x81,
+		0xCD, 0x85, 0xF6, 0xCE, 0x91, 0xCC, 0x94, 0xCC,
+		0x81, 0xCD, 0x85, 0xF6, 0xCE, 0x91, 0xCC, 0x93,
+		0xCD, 0x82, 0xCD, 0x85, 0xF6, 0xCE, 0x91, 0xCC,
+		0x94, 0xCD, 0x82, 0xCD, 0x85, 0xF6, 0xCE, 0xB7,
+		0xCC, 0x93, 0xCD, 0x85, 0xF6, 0xCE, 0xB7, 0xCC,
+		0x94, 0xCD, 0x85, 0xF6, 0xCE, 0xB7, 0xCC, 0x93,
+		0xCC, 0x80, 0xCD, 0x85, 0xF6, 0xCE, 0xB7, 0xCC,
+		0x94, 0xCC, 0x80, 0xCD, 0x85, 0xF6, 0xCE, 0xB7,
+		0xCC, 0x93, 0xCC, 0x81, 0xCD, 0x85, 0xF6, 0xCE,
+		0xB7, 0xCC, 0x94, 0xCC, 0x81, 0xCD, 0x85, 0xF6,
+		0xCE, 0xB7, 0xCC, 0x93, 0xCD, 0x82, 0xCD, 0x85,
+		0xF6, 0xCE, 0xB7, 0xCC, 0x94, 0xCD, 0x82, 0xCD,
+		0x85, 0xF6, 0xCE, 0x97, 0xCC, 0x93, 0xCD, 0x85,
+		0xF6, 0xCE, 0x97, 0xCC, 0x94, 0xCD, 0x85, 0xF6,
+		0xCE, 0x97, 0xCC, 0x93, 0xCC, 0x80, 0xCD, 0x85,
+		0xF6, 0xCE, 0x97, 0xCC, 0x94, 0xCC, 0x80, 0xCD,
+		0x85, 0xF6, 0xCE, 0x97, 0xCC, 0x93, 0xCC, 0x81,
+		0xCD, 0x85, 0xF6, 0xCE, 0x97, 0xCC, 0x94, 0xCC,
+		0x81, 0xCD, 0x85, 0xF6, 0xCE, 0x97, 0xCC, 0x93,
+		0xCD, 0x82, 0xCD, 0x85, 0xF6, 0xCE, 0x97, 0xCC,
+		0x94, 0xCD, 0x82, 0xCD, 0x85, 0xF6, 0xCF, 0x89,
+		0xCC, 0x93, 0xCD, 0x85, 0xF6, 0xCF, 0x89, 0xCC,
+		0x94, 0xCD, 0x85, 0xF6, 0xCF, 0x89, 0xCC, 0x93,
+		0xCC, 0x80, 0xCD, 0x85, 0xF6, 0xCF, 0x89, 0xCC,
+		0x94, 0xCC, 0x80, 0xCD, 0x85, 0xF6, 0xCF, 0x89,
+		0xCC, 0x93, 0xCC, 0x81, 0xCD, 0x85, 0xF6, 0xCF,
+		0x89, 0xCC, 0x94, 0xCC, 0x81, 0xCD, 0x85, 0xF6,
+		0xCF, 0x89, 0xCC, 0x93, 0xCD, 0x82, 0xCD, 0x85,
+		0xF6, 0xCF, 0x89, 0xCC, 0x94, 0xCD, 0x82, 0xCD,
+		0x85, 0xF6, 0xCE, 0xA9, 0xCC, 0x93, 0xCD, 0x85,
+		0xF6, 0xCE, 0xA9, 0xCC, 0x94, 0xCD, 0x85, 0xF6,
+		0xCE, 0xA9, 0xCC, 0x93, 0xCC, 0x80, 0xCD, 0x85,
+		0xF6, 0xCE, 0xA9, 0xCC, 0x94, 0xCC, 0x80, 0xCD,
+		0x85, 0xF6, 0xCE, 0xA9, 0xCC, 0x93, 0xCC, 0x81,
+		0xCD, 0x85, 0xF6, 0xCE, 0xA9, 0xCC, 0x94, 0xCC,
+		0x81, 0xCD, 0x85, 0xF6, 0xCE, 0xA9, 0xCC, 0x93,
+		0xCD, 0x82, 0xCD, 0x85, 0xF6, 0xCE, 0xA9, 0xCC,
+		0x94, 0xCD, 0x82, 0xCD, 0x85, 0xF6, 0xCE, 0xB1,
+		0xCC, 0x86, 0xF6, 0xCE, 0xB1, 0xCC, 0x84, 0xF6,
+		0xCE, 0xB1, 0xCC, 0x80, 0xCD, 0x85, 0xF6, 0xCE,
+		0xB1, 0xCD, 0x85, 0xF6, 0xCE, 0xB1, 0xCC, 0x81,
+		0xCD, 0x85, 0xF6, 0xCE, 0xB1, 0xCD, 0x82, 0xF6,
+		0xCE, 0xB1, 0xCD, 0x82, 0xCD, 0x85, 0xF6, 0xCE,
+		0x91, 0xCC, 0x86, 0xF6, 0xCE, 0x91, 0xCC, 0x84,
+		0xF6, 0xCE, 0x91, 0xCC, 0x80, 0xF6, 0xCE, 0x91,
+		0xCC, 0x81, 0xF6, 0xCE, 0x91, 0xCD, 0x85, 0x20,
+		0xCC, 0x93, 0xF6, 0xCE, 0xB9, 0x20, 0xCC, 0x93,
+		0x20, 0xCD, 0x82, 0xF5, 0x05, 0xC2, 0xA8, 0xCD,
+		0x82, 0x20, 0xCC, 0x88, 0xCD, 0x82, 0xF6, 0xCE,
+		0xB7, 0xCC, 0x80, 0xCD, 0x85, 0xF6, 0xCE, 0xB7,
+		0xCD, 0x85, 0xF6, 0xCE, 0xB7, 0xCC, 0x81, 0xCD,
+		0x85, 0xF6, 0xCE, 0xB7, 0xCD, 0x82, 0xF6, 0xCE,
+		0xB7, 0xCD, 0x82, 0xCD, 0x85, 0xF6, 0xCE, 0x95,
+		0xCC, 0x80, 0xF6, 0xCE, 0x95, 0xCC, 0x81, 0xF6,
+		0xCE, 0x97, 0xCC, 0x80, 0xF6, 0xCE, 0x97, 0xCC,
+		0x81, 0xF6, 0xCE, 0x97, 0xCD, 0x85, 0xF5, 0x06,
+		0xE1, 0xBE, 0xBF, 0xCC, 0x80, 0x20, 0xCC, 0x93,
+		0xCC, 0x80, 0xF5, 0x06, 0xE1, 0xBE, 0xBF, 0xCC,
+		0x81, 0x20, 0xCC, 0x93, 0xCC, 0x81, 0xF5, 0x06,
+		0xE1, 0xBE, 0xBF, 0xCD, 0x82, 0x20, 0xCC, 0x93,
+		0xCD, 0x82, 0xF6, 0xCE, 0xB9, 0xCC, 0x86, 0xF6,
+		0xCE, 0xB9, 0xCC, 0x84, 0xF6, 0xCE, 0xB9, 0xCC,
+		0x88, 0xCC, 0x80, 0xF6, 0xCE, 0xB9, 0xCC, 0x88,
+		0xCC, 0x81, 0xF6, 0xCE, 0xB9, 0xCD, 0x82, 0xF6,
+		0xCE, 0xB9, 0xCC, 0x88, 0xCD, 0x82, 0xF6, 0xCE,
+		0x99, 0xCC, 0x86, 0xF6, 0xCE, 0x99, 0xCC, 0x84,
+		0xF6, 0xCE, 0x99, 0xCC, 0x80, 0xF6, 0xCE, 0x99,
+		0xCC, 0x81, 0xF5, 0x06, 0xE1, 0xBF, 0xBE, 0xCC,
+		0x80, 0x20, 0xCC, 0x94, 0xCC, 0x80, 0xF5, 0x06,
+		0xE1, 0xBF, 0xBE, 0xCC, 0x81, 0x20, 0xCC, 0x94,
+		0xCC, 0x81, 0xF5, 0x06, 0xE1, 0xBF, 0xBE, 0xCD,
+		0x82, 0x20, 0xCC, 0x94, 0xCD, 0x82, 0xF6, 0xCF,
+		0x85, 0xCC, 0x86, 0xF6, 0xCF, 0x85, 0xCC, 0x84,
+		0xF6, 0xCF, 0x85, 0xCC, 0x88, 0xCC, 0x80, 0xF6,
+		0xCF, 0x85, 0xCC, 0x88, 0xCC, 0x81, 0xF6, 0xCF,
+		0x81, 0xCC, 0x93, 0xF6, 0xCF, 0x81, 0xCC, 0x94,
+		0xF6, 0xCF, 0x85, 0xCD, 0x82, 0xF6, 0xCF, 0x85,
+		0xCC, 0x88, 0xCD, 0x82, 0xF6, 0xCE, 0xA5, 0xCC,
+		0x86, 0xF6, 0xCE, 0xA5, 0xCC, 0x84, 0xF6, 0xCE,
+		0xA5, 0xCC, 0x80, 0xF6, 0xCE, 0xA5, 0xCC, 0x81,
+		0xF6, 0xCE, 0xA1, 0xCC, 0x94, 0xF5, 0x05, 0xC2,
+		0xA8, 0xCC, 0x80, 0x20, 0xCC, 0x88, 0xCC, 0x80,
+		0xF5, 0x05, 0xC2, 0xA8, 0xCC, 0x81, 0x20, 0xCC,
+		0x88, 0xCC, 0x81, 0xF6, 0x60, 0xF6, 0xCF, 0x89,
+		0xCC, 0x80, 0xCD, 0x85, 0xF6, 0xCF, 0x89, 0xCD,
+		0x85, 0xF6, 0xCF, 0x89, 0xCC, 0x81, 0xCD, 0x85,
+		0xF6, 0xCF, 0x89, 0xCD, 0x82, 0xF6, 0xCF, 0x89,
+		0xCD, 0x82, 0xCD, 0x85, 0xF6, 0xCE, 0x9F, 0xCC,
+		0x80, 0xF6, 0xCE, 0x9F, 0xCC, 0x81, 0xF6, 0xCE,
+		0xA9, 0xCC, 0x80, 0xF6, 0xCE, 0xA9, 0xCC, 0x81,
+		0xF6, 0xCE, 0xA9, 0xCD, 0x85, 0xF5, 0x03, 0xC2,
+		0xB4, 0x20, 0xCC, 0x81, 0x20, 0xCC, 0x94, 0xF5,
+		0x04, 0xE2, 0x80, 0x82, 0x20, 0xF5, 0x04, 0xE2,
+		0x80, 0x83, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+		0x20, 0x20, 0x20, 0x20, 0xE2, 0x80, 0x90, 0x20,
+		0xCC, 0xB3, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
+		0x20, 0xE2, 0x80, 0xB2, 0xE2, 0x80, 0xB2, 0xE2,
+		0x80, 0xB2, 0xE2, 0x80, 0xB2, 0xE2, 0x80, 0xB2,
+		0xE2, 0x80, 0xB5, 0xE2, 0x80, 0xB5, 0xE2, 0x80,
+		0xB5, 0xE2, 0x80, 0xB5, 0xE2, 0x80, 0xB5, 0x21,
+		0x21, 0x20, 0xCC, 0x85, 0x3F, 0x3F, 0x3F, 0x21,
+		0x21, 0x3F, 0xE2, 0x80, 0xB2, 0xE2, 0x80, 0xB2,
+		0xE2, 0x80, 0xB2, 0xE2, 0x80, 0xB2, 0x20, 0x30,
+		0x69, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x2B,
+		0xE2, 0x88, 0x92, 0x3D, 0x28, 0x29, 0x6E, 0x30,
+		0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
+		0x39, 0x2B, 0xE2, 0x88, 0x92, 0x3D, 0x28, 0x29,
+		0x52, 0x73, 0x61, 0x2F, 0x63, 0x61, 0x2F, 0x73,
+		0x43, 0xC2, 0xB0, 0x43, 0x63, 0x2F, 0x6F, 0x63,
+		0x2F, 0x75, 0xC6, 0x90, 0xC2, 0xB0, 0x46, 0x67,
+		0x48, 0x48, 0x48, 0x68, 0xC4, 0xA7, 0x49, 0x49,
+		0x4C, 0x6C, 0x4E, 0x4E, 0x6F, 0x50, 0x51, 0x52,
+		0x52, 0x52, 0x53, 0x4D, 0x54, 0x45, 0x4C, 0x54,
+		0x4D, 0x5A, 0xF6, 0xCE, 0xA9, 0x5A, 0xF6, 0x4B,
+		0xF6, 0x41, 0xCC, 0x8A, 0x42, 0x43, 0x65, 0x45,
+		0x46, 0x4D, 0x6F, 0xD7, 0x90, 0xD7, 0x91, 0xD7,
+		0x92, 0xD7, 0x93, 0x69, 0xCE, 0xB3, 0xCE, 0x93,
+		0xCE, 0xA0, 0xE2, 0x88, 0x91, 0x44, 0x64, 0x65,
+		0x69, 0x6A, 0x31, 0xE2, 0x81, 0x84, 0x33, 0x32,
+		0xE2, 0x81, 0x84, 0x33, 0x31, 0xE2, 0x81, 0x84,
+		0x35, 0x32, 0xE2, 0x81, 0x84, 0x35, 0x33, 0xE2,
+		0x81, 0x84, 0x35, 0x34, 0xE2, 0x81, 0x84, 0x35,
+		0x31, 0xE2, 0x81, 0x84, 0x36, 0x35, 0xE2, 0x81,
+		0x84, 0x36, 0x31, 0xE2, 0x81, 0x84, 0x38, 0x33,
+		0xE2, 0x81, 0x84, 0x38, 0x35, 0xE2, 0x81, 0x84,
+		0x38, 0x37, 0xE2, 0x81, 0x84, 0x38, 0x31, 0xE2,
+		0x81, 0x84, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49,
+		0x49, 0x56, 0x56, 0x56, 0x49, 0x56, 0x49, 0x49,
+		0x56, 0x49, 0x49, 0x49, 0x49, 0x58, 0x58, 0x58,
+		0x49, 0x58, 0x49, 0x49, 0x4C, 0x43, 0x44, 0x4D,
+		0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x76,
+		0x76, 0x76, 0x69, 0x76, 0x69, 0x69, 0x76, 0x69,
+		0x69, 0x69, 0x69, 0x78, 0x78, 0x78, 0x69, 0x78,
+		0x69, 0x69, 0x6C, 0x63, 0x64, 0x6D, 0xF6, 0xE2,
+		0x86, 0x90, 0xCC, 0xB8, 0xF6, 0xE2, 0x86, 0x92,
+		0xCC, 0xB8, 0xF6, 0xE2, 0x86, 0x94, 0xCC, 0xB8,
+		0xF6, 0xE2, 0x87, 0x90, 0xCC, 0xB8, 0xF6, 0xE2,
+		0x87, 0x94, 0xCC, 0xB8, 0xF6, 0xE2, 0x87, 0x92,
+		0xCC, 0xB8, 0xF6, 0xE2, 0x88, 0x83, 0xCC, 0xB8,
+		0xF6, 0xE2, 0x88, 0x88, 0xCC, 0xB8, 0xF6, 0xE2,
+		0x88, 0x8B, 0xCC, 0xB8, 0xF6, 0xE2, 0x88, 0xA3,
+		0xCC, 0xB8, 0xF6, 0xE2, 0x88, 0xA5, 0xCC, 0xB8,
+		0xE2, 0x88, 0xAB, 0xE2, 0x88, 0xAB, 0xE2, 0x88,
+		0xAB, 0xE2, 0x88, 0xAB, 0xE2, 0x88, 0xAB, 0xE2,
+		0x88, 0xAE, 0xE2, 0x88, 0xAE, 0xE2, 0x88, 0xAE,
+		0xE2, 0x88, 0xAE, 0xE2, 0x88, 0xAE, 0xF6, 0xE2,
+		0x88, 0xBC, 0xCC, 0xB8, 0xF6, 0xE2, 0x89, 0x83,
+		0xCC, 0xB8, 0xF6, 0xE2, 0x89, 0x85, 0xCC, 0xB8,
+		0xF6, 0xE2, 0x89, 0x88, 0xCC, 0xB8, 0xF6, 0x3D,
+		0xCC, 0xB8, 0xF6, 0xE2, 0x89, 0xA1, 0xCC, 0xB8,
+		0xF6, 0xE2, 0x89, 0x8D, 0xCC, 0xB8, 0xF6, 0x3C,
+		0xCC, 0xB8, 0xF6, 0x3E, 0xCC, 0xB8, 0xF6, 0xE2,
+		0x89, 0xA4, 0xCC, 0xB8, 0xF6, 0xE2, 0x89, 0xA5,
+		0xCC, 0xB8, 0xF6, 0xE2, 0x89, 0xB2, 0xCC, 0xB8,
+		0xF6, 0xE2, 0x89, 0xB3, 0xCC, 0xB8, 0xF6, 0xE2,
+		0x89, 0xB6, 0xCC, 0xB8, 0xF6, 0xE2, 0x89, 0xB7,
+		0xCC, 0xB8, 0xF6, 0xE2, 0x89, 0xBA, 0xCC, 0xB8,
+		0xF6, 0xE2, 0x89, 0xBB, 0xCC, 0xB8, 0xF6, 0xE2,
+		0x8A, 0x82, 0xCC, 0xB8, 0xF6, 0xE2, 0x8A, 0x83,
+		0xCC, 0xB8, 0xF6, 0xE2, 0x8A, 0x86, 0xCC, 0xB8,
+		0xF6, 0xE2, 0x8A, 0x87, 0xCC, 0xB8, 0xF6, 0xE2,
+		0x8A, 0xA2, 0xCC, 0xB8, 0xF6, 0xE2, 0x8A, 0xA8,
+		0xCC, 0xB8, 0xF6, 0xE2, 0x8A, 0xA9, 0xCC, 0xB8,
+		0xF6, 0xE2, 0x8A, 0xAB, 0xCC, 0xB8, 0xF6, 0xE2,
+		0x89, 0xBC, 0xCC, 0xB8, 0xF6, 0xE2, 0x89, 0xBD,
+		0xCC, 0xB8, 0xF6, 0xE2, 0x8A, 0x91, 0xCC, 0xB8,
+		0xF6, 0xE2, 0x8A, 0x92, 0xCC, 0xB8, 0xF6, 0xE2,
+		0x8A, 0xB2, 0xCC, 0xB8, 0xF6, 0xE2, 0x8A, 0xB3,
+		0xCC, 0xB8, 0xF6, 0xE2, 0x8A, 0xB4, 0xCC, 0xB8,
+		0xF6, 0xE2, 0x8A, 0xB5, 0xCC, 0xB8, 0xF6, 0xE3,
+		0x80, 0x88, 0xF6, 0xE3, 0x80, 0x89, 0x31, 0x32,
+		0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x31,
+		0x30, 0x31, 0x31, 0x31, 0x32, 0x31, 0x33, 0x31,
+		0x34, 0x31, 0x35, 0x31, 0x36, 0x31, 0x37, 0x31,
+		0x38, 0x31, 0x39, 0x32, 0x30, 0x28, 0x31, 0x29,
+		0x28, 0x32, 0x29, 0x28, 0x33, 0x29, 0x28, 0x34,
+		0x29, 0x28, 0x35, 0x29, 0x28, 0x36, 0x29, 0x28,
+		0x37, 0x29, 0x28, 0x38, 0x29, 0x28, 0x39, 0x29,
+		0x28, 0x31, 0x30, 0x29, 0x28, 0x31, 0x31, 0x29,
+		0x28, 0x31, 0x32, 0x29, 0x28, 0x31, 0x33, 0x29,
+		0x28, 0x31, 0x34, 0x29, 0x28, 0x31, 0x35, 0x29,
+		0x28, 0x31, 0x36, 0x29, 0x28, 0x31, 0x37, 0x29,
+		0x28, 0x31, 0x38, 0x29, 0x28, 0x31, 0x39, 0x29,
+		0x28, 0x32, 0x30, 0x29, 0x31, 0x2E, 0x32, 0x2E,
+		0x33, 0x2E, 0x34, 0x2E, 0x35, 0x2E, 0x36, 0x2E,
+		0x37, 0x2E, 0x38, 0x2E, 0x39, 0x2E, 0x31, 0x30,
+		0x2E, 0x31, 0x31, 0x2E, 0x31, 0x32, 0x2E, 0x31,
+		0x33, 0x2E, 0x31, 0x34, 0x2E, 0x31, 0x35, 0x2E,
+		0x31, 0x36, 0x2E, 0x31, 0x37, 0x2E, 0x31, 0x38,
+		0x2E, 0x31, 0x39, 0x2E, 0x32, 0x30, 0x2E, 0x28,
+		0x61, 0x29, 0x28, 0x62, 0x29, 0x28, 0x63, 0x29,
+		0x28, 0x64, 0x29, 0x28, 0x65, 0x29, 0x28, 0x66,
+		0x29, 0x28, 0x67, 0x29, 0x28, 0x68, 0x29, 0x28,
+		0x69, 0x29, 0x28, 0x6A, 0x29, 0x28, 0x6B, 0x29,
+		0x28, 0x6C, 0x29, 0x28, 0x6D, 0x29, 0x28, 0x6E,
+		0x29, 0x28, 0x6F, 0x29, 0x28, 0x70, 0x29, 0x28,
+		0x71, 0x29, 0x28, 0x72, 0x29, 0x28, 0x73, 0x29,
+		0x28, 0x74, 0x29, 0x28, 0x75, 0x29, 0x28, 0x76,
+		0x29, 0x28, 0x77, 0x29, 0x28, 0x78, 0x29, 0x28,
+		0x79, 0x29, 0x28, 0x7A, 0x29, 0x41, 0x42, 0x43,
+		0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B,
+		0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53,
+		0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x61,
+		0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
+		0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71,
+		0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
+		0x7A, 0x30, 0xE2, 0x88, 0xAB, 0xE2, 0x88, 0xAB,
+		0xE2, 0x88, 0xAB, 0xE2, 0x88, 0xAB, 0x3A, 0x3A,
+		0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0xF6, 0xE2,
+		0xAB, 0x9D, 0xCC, 0xB8, 0xE6, 0xAF, 0x8D, 0xE9,
+		0xBE, 0x9F, 0xE4, 0xB8, 0x80, 0xE4, 0xB8, 0xA8,
+		0xE4, 0xB8, 0xB6, 0xE4, 0xB8, 0xBF, 0xE4, 0xB9,
+		0x99, 0xE4, 0xBA, 0x85, 0xE4, 0xBA, 0x8C, 0xE4,
+		0xBA, 0xA0, 0xE4, 0xBA, 0xBA, 0xE5, 0x84, 0xBF,
+		0xE5, 0x85, 0xA5, 0xE5, 0x85, 0xAB, 0xE5, 0x86,
+		0x82, 0xE5, 0x86, 0x96, 0xE5, 0x86, 0xAB, 0xE5,
+		0x87, 0xA0, 0xE5, 0x87, 0xB5, 0xE5, 0x88, 0x80,
+		0xE5, 0x8A, 0x9B, 0xE5, 0x8B, 0xB9, 0xE5, 0x8C,
+		0x95, 0xE5, 0x8C, 0x9A, 0xE5, 0x8C, 0xB8, 0xE5,
+		0x8D, 0x81, 0xE5, 0x8D, 0x9C, 0xE5, 0x8D, 0xA9,
+		0xE5, 0x8E, 0x82, 0xE5, 0x8E, 0xB6, 0xE5, 0x8F,
+		0x88, 0xE5, 0x8F, 0xA3, 0xE5, 0x9B, 0x97, 0xE5,
+		0x9C, 0x9F, 0xE5, 0xA3, 0xAB, 0xE5, 0xA4, 0x82,
+		0xE5, 0xA4, 0x8A, 0xE5, 0xA4, 0x95, 0xE5, 0xA4,
+		0xA7, 0xE5, 0xA5, 0xB3, 0xE5, 0xAD, 0x90, 0xE5,
+		0xAE, 0x80, 0xE5, 0xAF, 0xB8, 0xE5, 0xB0, 0x8F,
+		0xE5, 0xB0, 0xA2, 0xE5, 0xB0, 0xB8, 0xE5, 0xB1,
+		0xAE, 0xE5, 0xB1, 0xB1, 0xE5, 0xB7, 0x9B, 0xE5,
+		0xB7, 0xA5, 0xE5, 0xB7, 0xB1, 0xE5, 0xB7, 0xBE,
+		0xE5, 0xB9, 0xB2, 0xE5, 0xB9, 0xBA, 0xE5, 0xB9,
+		0xBF, 0xE5, 0xBB, 0xB4, 0xE5, 0xBB, 0xBE, 0xE5,
+		0xBC, 0x8B, 0xE5, 0xBC, 0x93, 0xE5, 0xBD, 0x90,
+		0xE5, 0xBD, 0xA1, 0xE5, 0xBD, 0xB3, 0xE5, 0xBF,
+		0x83, 0xE6, 0x88, 0x88, 0xE6, 0x88, 0xB6, 0xE6,
+		0x89, 0x8B, 0xE6, 0x94, 0xAF, 0xE6, 0x94, 0xB4,
+		0xE6, 0x96, 0x87, 0xE6, 0x96, 0x97, 0xE6, 0x96,
+		0xA4, 0xE6, 0x96, 0xB9, 0xE6, 0x97, 0xA0, 0xE6,
+		0x97, 0xA5, 0xE6, 0x9B, 0xB0, 0xE6, 0x9C, 0x88,
+		0xE6, 0x9C, 0xA8, 0xE6, 0xAC, 0xA0, 0xE6, 0xAD,
+		0xA2, 0xE6, 0xAD, 0xB9, 0xE6, 0xAE, 0xB3, 0xE6,
+		0xAF, 0x8B, 0xE6, 0xAF, 0x94, 0xE6, 0xAF, 0x9B,
+		0xE6, 0xB0, 0x8F, 0xE6, 0xB0, 0x94, 0xE6, 0xB0,
+		0xB4, 0xE7, 0x81, 0xAB, 0xE7, 0x88, 0xAA, 0xE7,
+		0x88, 0xB6, 0xE7, 0x88, 0xBB, 0xE7, 0x88, 0xBF,
+		0xE7, 0x89, 0x87, 0xE7, 0x89, 0x99, 0xE7, 0x89,
+		0x9B, 0xE7, 0x8A, 0xAC, 0xE7, 0x8E, 0x84, 0xE7,
+		0x8E, 0x89, 0xE7, 0x93, 0x9C, 0xE7, 0x93, 0xA6,
+		0xE7, 0x94, 0x98, 0xE7, 0x94, 0x9F, 0xE7, 0x94,
+		0xA8, 0xE7, 0x94, 0xB0, 0xE7, 0x96, 0x8B, 0xE7,
+		0x96, 0x92, 0xE7, 0x99, 0xB6, 0xE7, 0x99, 0xBD,
+		0xE7, 0x9A, 0xAE, 0xE7, 0x9A, 0xBF, 0xE7, 0x9B,
+		0xAE, 0xE7, 0x9F, 0x9B, 0xE7, 0x9F, 0xA2, 0xE7,
+		0x9F, 0xB3, 0xE7, 0xA4, 0xBA, 0xE7, 0xA6, 0xB8,
+		0xE7, 0xA6, 0xBE, 0xE7, 0xA9, 0xB4, 0xE7, 0xAB,
+		0x8B, 0xE7, 0xAB, 0xB9, 0xE7, 0xB1, 0xB3, 0xE7,
+		0xB3, 0xB8, 0xE7, 0xBC, 0xB6, 0xE7, 0xBD, 0x91,
+		0xE7, 0xBE, 0x8A, 0xE7, 0xBE, 0xBD, 0xE8, 0x80,
+		0x81, 0xE8, 0x80, 0x8C, 0xE8, 0x80, 0x92, 0xE8,
+		0x80, 0xB3, 0xE8, 0x81, 0xBF, 0xE8, 0x82, 0x89,
+		0xE8, 0x87, 0xA3, 0xE8, 0x87, 0xAA, 0xE8, 0x87,
+		0xB3, 0xE8, 0x87, 0xBC, 0xE8, 0x88, 0x8C, 0xE8,
+		0x88, 0x9B, 0xE8, 0x88, 0x9F, 0xE8, 0x89, 0xAE,
+		0xE8, 0x89, 0xB2, 0xE8, 0x89, 0xB8, 0xE8, 0x99,
+		0x8D, 0xE8, 0x99, 0xAB, 0xE8, 0xA1, 0x80, 0xE8,
+		0xA1, 0x8C, 0xE8, 0xA1, 0xA3, 0xE8, 0xA5, 0xBE,
+		0xE8, 0xA6, 0x8B, 0xE8, 0xA7, 0x92, 0xE8, 0xA8,
+		0x80, 0xE8, 0xB0, 0xB7, 0xE8, 0xB1, 0x86, 0xE8,
+		0xB1, 0x95, 0xE8, 0xB1, 0xB8, 0xE8, 0xB2, 0x9D,
+		0xE8, 0xB5, 0xA4, 0xE8, 0xB5, 0xB0, 0xE8, 0xB6,
+		0xB3, 0xE8, 0xBA, 0xAB, 0xE8, 0xBB, 0x8A, 0xE8,
+		0xBE, 0x9B, 0xE8, 0xBE, 0xB0, 0xE8, 0xBE, 0xB5,
+		0xE9, 0x82, 0x91, 0xE9, 0x85, 0x89, 0xE9, 0x87,
+		0x86, 0xE9, 0x87, 0x8C, 0xE9, 0x87, 0x91, 0xE9,
+		0x95, 0xB7, 0xE9, 0x96, 0x80, 0xE9, 0x98, 0x9C,
+		0xE9, 0x9A, 0xB6, 0xE9, 0x9A, 0xB9, 0xE9, 0x9B,
+		0xA8, 0xE9, 0x9D, 0x91, 0xE9, 0x9D, 0x9E, 0xE9,
+		0x9D, 0xA2, 0xE9, 0x9D, 0xA9, 0xE9, 0x9F, 0x8B,
+		0xE9, 0x9F, 0xAD, 0xE9, 0x9F, 0xB3, 0xE9, 0xA0,
+		0x81, 0xE9, 0xA2, 0xA8, 0xE9, 0xA3, 0x9B, 0xE9,
+		0xA3, 0x9F, 0xE9, 0xA6, 0x96, 0xE9, 0xA6, 0x99,
+		0xE9, 0xA6, 0xAC, 0xE9, 0xAA, 0xA8, 0xE9, 0xAB,
+		0x98, 0xE9, 0xAB, 0x9F, 0xE9, 0xAC, 0xA5, 0xE9,
+		0xAC, 0xAF, 0xE9, 0xAC, 0xB2, 0xE9, 0xAC, 0xBC,
+		0xE9, 0xAD, 0x9A, 0xE9, 0xB3, 0xA5, 0xE9, 0xB9,
+		0xB5, 0xE9, 0xB9, 0xBF, 0xE9, 0xBA, 0xA5, 0xE9,
+		0xBA, 0xBB, 0xE9, 0xBB, 0x83, 0xE9, 0xBB, 0x8D,
+		0xE9, 0xBB, 0x91, 0xE9, 0xBB, 0xB9, 0xE9, 0xBB,
+		0xBD, 0xE9, 0xBC, 0x8E, 0xE9, 0xBC, 0x93, 0xE9,
+		0xBC, 0xA0, 0xE9, 0xBC, 0xBB, 0xE9, 0xBD, 0x8A,
+		0xE9, 0xBD, 0x92, 0xE9, 0xBE, 0x8D, 0xE9, 0xBE,
+		0x9C, 0xE9, 0xBE, 0xA0, 0x20, 0xE3, 0x80, 0x92,
+		0xE5, 0x8D, 0x81, 0xE5, 0x8D, 0x84, 0xE5, 0x8D,
+		0x85, 0xF6, 0xE3, 0x81, 0x8B, 0xE3, 0x82, 0x99,
+		0xF6, 0xE3, 0x81, 0x8D, 0xE3, 0x82, 0x99, 0xF6,
+		0xE3, 0x81, 0x8F, 0xE3, 0x82, 0x99, 0xF6, 0xE3,
+		0x81, 0x91, 0xE3, 0x82, 0x99, 0xF6, 0xE3, 0x81,
+		0x93, 0xE3, 0x82, 0x99, 0xF6, 0xE3, 0x81, 0x95,
+		0xE3, 0x82, 0x99, 0xF6, 0xE3, 0x81, 0x97, 0xE3,
+		0x82, 0x99, 0xF6, 0xE3, 0x81, 0x99, 0xE3, 0x82,
+		0x99, 0xF6, 0xE3, 0x81, 0x9B, 0xE3, 0x82, 0x99,
+		0xF6, 0xE3, 0x81, 0x9D, 0xE3, 0x82, 0x99, 0xF6,
+		0xE3, 0x81, 0x9F, 0xE3, 0x82, 0x99, 0xF6, 0xE3,
+		0x81, 0xA1, 0xE3, 0x82, 0x99, 0xF6, 0xE3, 0x81,
+		0xA4, 0xE3, 0x82, 0x99, 0xF6, 0xE3, 0x81, 0xA6,
+		0xE3, 0x82, 0x99, 0xF6, 0xE3, 0x81, 0xA8, 0xE3,
+		0x82, 0x99, 0xF6, 0xE3, 0x81, 0xAF, 0xE3, 0x82,
+		0x99, 0xF6, 0xE3, 0x81, 0xAF, 0xE3, 0x82, 0x9A,
+		0xF6, 0xE3, 0x81, 0xB2, 0xE3, 0x82, 0x99, 0xF6,
+		0xE3, 0x81, 0xB2, 0xE3, 0x82, 0x9A, 0xF6, 0xE3,
+		0x81, 0xB5, 0xE3, 0x82, 0x99, 0xF6, 0xE3, 0x81,
+		0xB5, 0xE3, 0x82, 0x9A, 0xF6, 0xE3, 0x81, 0xB8,
+		0xE3, 0x82, 0x99, 0xF6, 0xE3, 0x81, 0xB8, 0xE3,
+		0x82, 0x9A, 0xF6, 0xE3, 0x81, 0xBB, 0xE3, 0x82,
+		0x99, 0xF6, 0xE3, 0x81, 0xBB, 0xE3, 0x82, 0x9A,
+		0xF6, 0xE3, 0x81, 0x86, 0xE3, 0x82, 0x99, 0x20,
+		0xE3, 0x82, 0x99, 0x20, 0xE3, 0x82, 0x9A, 0xF6,
+		0xE3, 0x82, 0x9D, 0xE3, 0x82, 0x99, 0xE3, 0x82,
+		0x88, 0xE3, 0x82, 0x8A, 0xF6, 0xE3, 0x82, 0xAB,
+		0xE3, 0x82, 0x99, 0xF6, 0xE3, 0x82, 0xAD, 0xE3,
+		0x82, 0x99, 0xF6, 0xE3, 0x82, 0xAF, 0xE3, 0x82,
+		0x99, 0xF6, 0xE3, 0x82, 0xB1, 0xE3, 0x82, 0x99,
+		0xF6, 0xE3, 0x82, 0xB3, 0xE3, 0x82, 0x99, 0xF6,
+		0xE3, 0x82, 0xB5, 0xE3, 0x82, 0x99, 0xF6, 0xE3,
+		0x82, 0xB7, 0xE3, 0x82, 0x99, 0xF6, 0xE3, 0x82,
+		0xB9, 0xE3, 0x82, 0x99, 0xF6, 0xE3, 0x82, 0xBB,
+		0xE3, 0x82, 0x99, 0xF6, 0xE3, 0x82, 0xBD, 0xE3,
+		0x82, 0x99, 0xF6, 0xE3, 0x82, 0xBF, 0xE3, 0x82,
+		0x99, 0xF6, 0xE3, 0x83, 0x81, 0xE3, 0x82, 0x99,
+		0xF6, 0xE3, 0x83, 0x84, 0xE3, 0x82, 0x99, 0xF6,
+		0xE3, 0x83, 0x86, 0xE3, 0x82, 0x99, 0xF6, 0xE3,
+		0x83, 0x88, 0xE3, 0x82, 0x99, 0xF6, 0xE3, 0x83,
+		0x8F, 0xE3, 0x82, 0x99, 0xF6, 0xE3, 0x83, 0x8F,
+		0xE3, 0x82, 0x9A, 0xF6, 0xE3, 0x83, 0x92, 0xE3,
+		0x82, 0x99, 0xF6, 0xE3, 0x83, 0x92, 0xE3, 0x82,
+		0x9A, 0xF6, 0xE3, 0x83, 0x95, 0xE3, 0x82, 0x99,
+		0xF6, 0xE3, 0x83, 0x95, 0xE3, 0x82, 0x9A, 0xF6,
+		0xE3, 0x83, 0x98, 0xE3, 0x82, 0x99, 0xF6, 0xE3,
+		0x83, 0x98, 0xE3, 0x82, 0x9A, 0xF6, 0xE3, 0x83,
+		0x9B, 0xE3, 0x82, 0x99, 0xF6, 0xE3, 0x83, 0x9B,
+		0xE3, 0x82, 0x9A, 0xF6, 0xE3, 0x82, 0xA6, 0xE3,
+		0x82, 0x99, 0xF6, 0xE3, 0x83, 0xAF, 0xE3, 0x82,
+		0x99, 0xF6, 0xE3, 0x83, 0xB0, 0xE3, 0x82, 0x99,
+		0xF6, 0xE3, 0x83, 0xB1, 0xE3, 0x82, 0x99, 0xF6,
+		0xE3, 0x83, 0xB2, 0xE3, 0x82, 0x99, 0xF6, 0xE3,
+		0x83, 0xBD, 0xE3, 0x82, 0x99, 0xE3, 0x82, 0xB3,
+		0xE3, 0x83, 0x88, 0xE1, 0x84, 0x80, 0xE1, 0x84,
+		0x81, 0xE1, 0x86, 0xAA, 0xE1, 0x84, 0x82, 0xE1,
+		0x86, 0xAC, 0xE1, 0x86, 0xAD, 0xE1, 0x84, 0x83,
+		0xE1, 0x84, 0x84, 0xE1, 0x84, 0x85, 0xE1, 0x86,
+		0xB0, 0xE1, 0x86, 0xB1, 0xE1, 0x86, 0xB2, 0xE1,
+		0x86, 0xB3, 0xE1, 0x86, 0xB4, 0xE1, 0x86, 0xB5,
+		0xE1, 0x84, 0x9A, 0xE1, 0x84, 0x86, 0xE1, 0x84,
+		0x87, 0xE1, 0x84, 0x88, 0xE1, 0x84, 0xA1, 0xE1,
+		0x84, 0x89, 0xE1, 0x84, 0x8A, 0xE1, 0x84, 0x8B,
+		0xE1, 0x84, 0x8C, 0xE1, 0x84, 0x8D, 0xE1, 0x84,
+		0x8E, 0xE1, 0x84, 0x8F, 0xE1, 0x84, 0x90, 0xE1,
+		0x84, 0x91, 0xE1, 0x84, 0x92, 0xE1, 0x85, 0xA1,
+		0xE1, 0x85, 0xA2, 0xE1, 0x85, 0xA3, 0xE1, 0x85,
+		0xA4, 0xE1, 0x85, 0xA5, 0xE1, 0x85, 0xA6, 0xE1,
+		0x85, 0xA7, 0xE1, 0x85, 0xA8, 0xE1, 0x85, 0xA9,
+		0xE1, 0x85, 0xAA, 0xE1, 0x85, 0xAB, 0xE1, 0x85,
+		0xAC, 0xE1, 0x85, 0xAD, 0xE1, 0x85, 0xAE, 0xE1,
+		0x85, 0xAF, 0xE1, 0x85, 0xB0, 0xE1, 0x85, 0xB1,
+		0xE1, 0x85, 0xB2, 0xE1, 0x85, 0xB3, 0xE1, 0x85,
+		0xB4, 0xE1, 0x85, 0xB5, 0xE1, 0x85, 0xA0, 0xE1,
+		0x84, 0x94, 0xE1, 0x84, 0x95, 0xE1, 0x87, 0x87,
+		0xE1, 0x87, 0x88, 0xE1, 0x87, 0x8C, 0xE1, 0x87,
+		0x8E, 0xE1, 0x87, 0x93, 0xE1, 0x87, 0x97, 0xE1,
+		0x87, 0x99, 0xE1, 0x84, 0x9C, 0xE1, 0x87, 0x9D,
+		0xE1, 0x87, 0x9F, 0xE1, 0x84, 0x9D, 0xE1, 0x84,
+		0x9E, 0xE1, 0x84, 0xA0, 0xE1, 0x84, 0xA2, 0xE1,
+		0x84, 0xA3, 0xE1, 0x84, 0xA7, 0xE1, 0x84, 0xA9,
+		0xE1, 0x84, 0xAB, 0xE1, 0x84, 0xAC, 0xE1, 0x84,
+		0xAD, 0xE1, 0x84, 0xAE, 0xE1, 0x84, 0xAF, 0xE1,
+		0x84, 0xB2, 0xE1, 0x84, 0xB6, 0xE1, 0x85, 0x80,
+		0xE1, 0x85, 0x87, 0xE1, 0x85, 0x8C, 0xE1, 0x87,
+		0xB1, 0xE1, 0x87, 0xB2, 0xE1, 0x85, 0x97, 0xE1,
+		0x85, 0x98, 0xE1, 0x85, 0x99, 0xE1, 0x86, 0x84,
+		0xE1, 0x86, 0x85, 0xE1, 0x86, 0x88, 0xE1, 0x86,
+		0x91, 0xE1, 0x86, 0x92, 0xE1, 0x86, 0x94, 0xE1,
+		0x86, 0x9E, 0xE1, 0x86, 0xA1, 0xE4, 0xB8, 0x80,
+		0xE4, 0xBA, 0x8C, 0xE4, 0xB8, 0x89, 0xE5, 0x9B,
+		0x9B, 0xE4, 0xB8, 0x8A, 0xE4, 0xB8, 0xAD, 0xE4,
+		0xB8, 0x8B, 0xE7, 0x94, 0xB2, 0xE4, 0xB9, 0x99,
+		0xE4, 0xB8, 0x99, 0xE4, 0xB8, 0x81, 0xE5, 0xA4,
+		0xA9, 0xE5, 0x9C, 0xB0, 0xE4, 0xBA, 0xBA, 0x28,
+		0xE1, 0x84, 0x80, 0x29, 0x28, 0xE1, 0x84, 0x82,
+		0x29, 0x28, 0xE1, 0x84, 0x83, 0x29, 0x28, 0xE1,
+		0x84, 0x85, 0x29, 0x28, 0xE1, 0x84, 0x86, 0x29,
+		0x28, 0xE1, 0x84, 0x87, 0x29, 0x28, 0xE1, 0x84,
+		0x89, 0x29, 0x28, 0xE1, 0x84, 0x8B, 0x29, 0x28,
+		0xE1, 0x84, 0x8C, 0x29, 0x28, 0xE1, 0x84, 0x8E,
+		0x29, 0x28, 0xE1, 0x84, 0x8F, 0x29, 0x28, 0xE1,
+		0x84, 0x90, 0x29, 0x28, 0xE1, 0x84, 0x91, 0x29,
+		0x28, 0xE1, 0x84, 0x92, 0x29, 0x28, 0xE1, 0x84,
+		0x80, 0xE1, 0x85, 0xA1, 0x29, 0x28, 0xE1, 0x84,
+		0x82, 0xE1, 0x85, 0xA1, 0x29, 0x28, 0xE1, 0x84,
+		0x83, 0xE1, 0x85, 0xA1, 0x29, 0x28, 0xE1, 0x84,
+		0x85, 0xE1, 0x85, 0xA1, 0x29, 0x28, 0xE1, 0x84,
+		0x86, 0xE1, 0x85, 0xA1, 0x29, 0x28, 0xE1, 0x84,
+		0x87, 0xE1, 0x85, 0xA1, 0x29, 0x28, 0xE1, 0x84,
+		0x89, 0xE1, 0x85, 0xA1, 0x29, 0x28, 0xE1, 0x84,
+		0x8B, 0xE1, 0x85, 0xA1, 0x29, 0x28, 0xE1, 0x84,
+		0x8C, 0xE1, 0x85, 0xA1, 0x29, 0x28, 0xE1, 0x84,
+		0x8E, 0xE1, 0x85, 0xA1, 0x29, 0x28, 0xE1, 0x84,
+		0x8F, 0xE1, 0x85, 0xA1, 0x29, 0x28, 0xE1, 0x84,
+		0x90, 0xE1, 0x85, 0xA1, 0x29, 0x28, 0xE1, 0x84,
+		0x91, 0xE1, 0x85, 0xA1, 0x29, 0x28, 0xE1, 0x84,
+		0x92, 0xE1, 0x85, 0xA1, 0x29, 0x28, 0xE1, 0x84,
+		0x8C, 0xE1, 0x85, 0xAE, 0x29, 0x28, 0xE4, 0xB8,
+		0x80, 0x29, 0x28, 0xE4, 0xBA, 0x8C, 0x29, 0x28,
+		0xE4, 0xB8, 0x89, 0x29, 0x28, 0xE5, 0x9B, 0x9B,
+		0x29, 0x28, 0xE4, 0xBA, 0x94, 0x29, 0x28, 0xE5,
+		0x85, 0xAD, 0x29, 0x28, 0xE4, 0xB8, 0x83, 0x29,
+		0x28, 0xE5, 0x85, 0xAB, 0x29, 0x28, 0xE4, 0xB9,
+		0x9D, 0x29, 0x28, 0xE5, 0x8D, 0x81, 0x29, 0x28,
+		0xE6, 0x9C, 0x88, 0x29, 0x28, 0xE7, 0x81, 0xAB,
+		0x29, 0x28, 0xE6, 0xB0, 0xB4, 0x29, 0x28, 0xE6,
+		0x9C, 0xA8, 0x29, 0x28, 0xE9, 0x87, 0x91, 0x29,
+		0x28, 0xE5, 0x9C, 0x9F, 0x29, 0x28, 0xE6, 0x97,
+		0xA5, 0x29, 0x28, 0xE6, 0xA0, 0xAA, 0x29, 0x28,
+		0xE6, 0x9C, 0x89, 0x29, 0x28, 0xE7, 0xA4, 0xBE,
+		0x29, 0x28, 0xE5, 0x90, 0x8D, 0x29, 0x28, 0xE7,
+		0x89, 0xB9, 0x29, 0x28, 0xE8, 0xB2, 0xA1, 0x29,
+		0x28, 0xE7, 0xA5, 0x9D, 0x29, 0x28, 0xE5, 0x8A,
+		0xB4, 0x29, 0x28, 0xE4, 0xBB, 0xA3, 0x29, 0x28,
+		0xE5, 0x91, 0xBC, 0x29, 0x28, 0xE5, 0xAD, 0xA6,
+		0x29, 0x28, 0xE7, 0x9B, 0xA3, 0x29, 0x28, 0xE4,
+		0xBC, 0x81, 0x29, 0x28, 0xE8, 0xB3, 0x87, 0x29,
+		0x28, 0xE5, 0x8D, 0x94, 0x29, 0x28, 0xE7, 0xA5,
+		0xAD, 0x29, 0x28, 0xE4, 0xBC, 0x91, 0x29, 0x28,
+		0xE8, 0x87, 0xAA, 0x29, 0x28, 0xE8, 0x87, 0xB3,
+		0x29, 0x32, 0x31, 0x32, 0x32, 0x32, 0x33, 0x32,
+		0x34, 0x32, 0x35, 0x32, 0x36, 0x32, 0x37, 0x32,
+		0x38, 0x32, 0x39, 0x33, 0x30, 0x33, 0x31, 0x33,
+		0x32, 0x33, 0x33, 0x33, 0x34, 0x33, 0x35, 0xE1,
+		0x84, 0x80, 0xE1, 0x84, 0x82, 0xE1, 0x84, 0x83,
+		0xE1, 0x84, 0x85, 0xE1, 0x84, 0x86, 0xE1, 0x84,
+		0x87, 0xE1, 0x84, 0x89, 0xE1, 0x84, 0x8B, 0xE1,
+		0x84, 0x8C, 0xE1, 0x84, 0x8E, 0xE1, 0x84, 0x8F,
+		0xE1, 0x84, 0x90, 0xE1, 0x84, 0x91, 0xE1, 0x84,
+		0x92, 0xE1, 0x84, 0x80, 0xE1, 0x85, 0xA1, 0xE1,
+		0x84, 0x82, 0xE1, 0x85, 0xA1, 0xE1, 0x84, 0x83,
+		0xE1, 0x85, 0xA1, 0xE1, 0x84, 0x85, 0xE1, 0x85,
+		0xA1, 0xE1, 0x84, 0x86, 0xE1, 0x85, 0xA1, 0xE1,
+		0x84, 0x87, 0xE1, 0x85, 0xA1, 0xE1, 0x84, 0x89,
+		0xE1, 0x85, 0xA1, 0xE1, 0x84, 0x8B, 0xE1, 0x85,
+		0xA1, 0xE1, 0x84, 0x8C, 0xE1, 0x85, 0xA1, 0xE1,
+		0x84, 0x8E, 0xE1, 0x85, 0xA1, 0xE1, 0x84, 0x8F,
+		0xE1, 0x85, 0xA1, 0xE1, 0x84, 0x90, 0xE1, 0x85,
+		0xA1, 0xE1, 0x84, 0x91, 0xE1, 0x85, 0xA1, 0xE1,
+		0x84, 0x92, 0xE1, 0x85, 0xA1, 0xE4, 0xB8, 0x80,
+		0xE4, 0xBA, 0x8C, 0xE4, 0xB8, 0x89, 0xE5, 0x9B,
+		0x9B, 0xE4, 0xBA, 0x94, 0xE5, 0x85, 0xAD, 0xE4,
+		0xB8, 0x83, 0xE5, 0x85, 0xAB, 0xE4, 0xB9, 0x9D,
+		0xE5, 0x8D, 0x81, 0xE6, 0x9C, 0x88, 0xE7, 0x81,
+		0xAB, 0xE6, 0xB0, 0xB4, 0xE6, 0x9C, 0xA8, 0xE9,
+		0x87, 0x91, 0xE5, 0x9C, 0x9F, 0xE6, 0x97, 0xA5,
+		0xE6, 0xA0, 0xAA, 0xE6, 0x9C, 0x89, 0xE7, 0xA4,
+		0xBE, 0xE5, 0x90, 0x8D, 0xE7, 0x89, 0xB9, 0xE8,
+		0xB2, 0xA1, 0xE7, 0xA5, 0x9D, 0xE5, 0x8A, 0xB4,
+		0xE7, 0xA7, 0x98, 0xE7, 0x94, 0xB7, 0xE5, 0xA5,
+		0xB3, 0xE9, 0x81, 0xA9, 0xE5, 0x84, 0xAA, 0xE5,
+		0x8D, 0xB0, 0xE6, 0xB3, 0xA8, 0xE9, 0xA0, 0x85,
+		0xE4, 0xBC, 0x91, 0xE5, 0x86, 0x99, 0xE6, 0xAD,
+		0xA3, 0xE4, 0xB8, 0x8A, 0xE4, 0xB8, 0xAD, 0xE4,
+		0xB8, 0x8B, 0xE5, 0xB7, 0xA6, 0xE5, 0x8F, 0xB3,
+		0xE5, 0x8C, 0xBB, 0xE5, 0xAE, 0x97, 0xE5, 0xAD,
+		0xA6, 0xE7, 0x9B, 0xA3, 0xE4, 0xBC, 0x81, 0xE8,
+		0xB3, 0x87, 0xE5, 0x8D, 0x94, 0xE5, 0xA4, 0x9C,
+		0x33, 0x36, 0x33, 0x37, 0x33, 0x38, 0x33, 0x39,
+		0x34, 0x30, 0x34, 0x31, 0x34, 0x32, 0x34, 0x33,
+		0x34, 0x34, 0x34, 0x35, 0x34, 0x36, 0x34, 0x37,
+		0x34, 0x38, 0x34, 0x39, 0x35, 0x30, 0x31, 0xE6,
+		0x9C, 0x88, 0x32, 0xE6, 0x9C, 0x88, 0x33, 0xE6,
+		0x9C, 0x88, 0x34, 0xE6, 0x9C, 0x88, 0x35, 0xE6,
+		0x9C, 0x88, 0x36, 0xE6, 0x9C, 0x88, 0x37, 0xE6,
+		0x9C, 0x88, 0x38, 0xE6, 0x9C, 0x88, 0x39, 0xE6,
+		0x9C, 0x88, 0x31, 0x30, 0xE6, 0x9C, 0x88, 0x31,
+		0x31, 0xE6, 0x9C, 0x88, 0x31, 0x32, 0xE6, 0x9C,
+		0x88, 0xE3, 0x82, 0xA2, 0xE3, 0x82, 0xA4, 0xE3,
+		0x82, 0xA6, 0xE3, 0x82, 0xA8, 0xE3, 0x82, 0xAA,
+		0xE3, 0x82, 0xAB, 0xE3, 0x82, 0xAD, 0xE3, 0x82,
+		0xAF, 0xE3, 0x82, 0xB1, 0xE3, 0x82, 0xB3, 0xE3,
+		0x82, 0xB5, 0xE3, 0x82, 0xB7, 0xE3, 0x82, 0xB9,
+		0xE3, 0x82, 0xBB, 0xE3, 0x82, 0xBD, 0xE3, 0x82,
+		0xBF, 0xE3, 0x83, 0x81, 0xE3, 0x83, 0x84, 0xE3,
+		0x83, 0x86, 0xE3, 0x83, 0x88, 0xE3, 0x83, 0x8A,
+		0xE3, 0x83, 0x8B, 0xE3, 0x83, 0x8C, 0xE3, 0x83,
+		0x8D, 0xE3, 0x83, 0x8E, 0xE3, 0x83, 0x8F, 0xE3,
+		0x83, 0x92, 0xE3, 0x83, 0x95, 0xE3, 0x83, 0x98,
+		0xE3, 0x83, 0x9B, 0xE3, 0x83, 0x9E, 0xE3, 0x83,
+		0x9F, 0xE3, 0x83, 0xA0, 0xE3, 0x83, 0xA1, 0xE3,
+		0x83, 0xA2, 0xE3, 0x83, 0xA4, 0xE3, 0x83, 0xA6,
+		0xE3, 0x83, 0xA8, 0xE3, 0x83, 0xA9, 0xE3, 0x83,
+		0xAA, 0xE3, 0x83, 0xAB, 0xE3, 0x83, 0xAC, 0xE3,
+		0x83, 0xAD, 0xE3, 0x83, 0xAF, 0xE3, 0x83, 0xB0,
+		0xE3, 0x83, 0xB1, 0xE3, 0x83, 0xB2, 0xE3, 0x82,
+		0xA2, 0xE3, 0x83, 0x8F, 0xE3, 0x82, 0x9A, 0xE3,
+		0x83, 0xBC, 0xE3, 0x83, 0x88, 0xE3, 0x82, 0xA2,
+		0xE3, 0x83, 0xAB, 0xE3, 0x83, 0x95, 0xE3, 0x82,
+		0xA1, 0xE3, 0x82, 0xA2, 0xE3, 0x83, 0xB3, 0xE3,
+		0x83, 0x98, 0xE3, 0x82, 0x9A, 0xE3, 0x82, 0xA2,
+		0xE3, 0x82, 0xA2, 0xE3, 0x83, 0xBC, 0xE3, 0x83,
+		0xAB, 0xE3, 0x82, 0xA4, 0xE3, 0x83, 0x8B, 0xE3,
+		0x83, 0xB3, 0xE3, 0x82, 0xAF, 0xE3, 0x82, 0x99,
+		0xE3, 0x82, 0xA4, 0xE3, 0x83, 0xB3, 0xE3, 0x83,
+		0x81, 0xE3, 0x82, 0xA6, 0xE3, 0x82, 0xA9, 0xE3,
+		0x83, 0xB3, 0xE3, 0x82, 0xA8, 0xE3, 0x82, 0xB9,
+		0xE3, 0x82, 0xAF, 0xE3, 0x83, 0xBC, 0xE3, 0x83,
+		0x88, 0xE3, 0x82, 0x99, 0xE3, 0x82, 0xA8, 0xE3,
+		0x83, 0xBC, 0xE3, 0x82, 0xAB, 0xE3, 0x83, 0xBC,
+		0xE3, 0x82, 0xAA, 0xE3, 0x83, 0xB3, 0xE3, 0x82,
+		0xB9, 0xE3, 0x82, 0xAA, 0xE3, 0x83, 0xBC, 0xE3,
+		0x83, 0xA0, 0xE3, 0x82, 0xAB, 0xE3, 0x82, 0xA4,
+		0xE3, 0x83, 0xAA, 0xE3, 0x82, 0xAB, 0xE3, 0x83,
+		0xA9, 0xE3, 0x83, 0x83, 0xE3, 0x83, 0x88, 0xE3,
+		0x82, 0xAB, 0xE3, 0x83, 0xAD, 0xE3, 0x83, 0xAA,
+		0xE3, 0x83, 0xBC, 0xE3, 0x82, 0xAB, 0xE3, 0x82,
+		0x99, 0xE3, 0x83, 0xAD, 0xE3, 0x83, 0xB3, 0xE3,
+		0x82, 0xAB, 0xE3, 0x82, 0x99, 0xE3, 0x83, 0xB3,
+		0xE3, 0x83, 0x9E, 0xE3, 0x82, 0xAD, 0xE3, 0x82,
+		0x99, 0xE3, 0x82, 0xAB, 0xE3, 0x82, 0x99, 0xE3,
+		0x82, 0xAD, 0xE3, 0x82, 0x99, 0xE3, 0x83, 0x8B,
+		0xE3, 0x83, 0xBC, 0xE3, 0x82, 0xAD, 0xE3, 0x83,
+		0xA5, 0xE3, 0x83, 0xAA, 0xE3, 0x83, 0xBC, 0xE3,
+		0x82, 0xAD, 0xE3, 0x82, 0x99, 0xE3, 0x83, 0xAB,
+		0xE3, 0x82, 0xBF, 0xE3, 0x82, 0x99, 0xE3, 0x83,
+		0xBC, 0xE3, 0x82, 0xAD, 0xE3, 0x83, 0xAD, 0xE3,
+		0x82, 0xAD, 0xE3, 0x83, 0xAD, 0xE3, 0x82, 0xAF,
+		0xE3, 0x82, 0x99, 0xE3, 0x83, 0xA9, 0xE3, 0x83,
+		0xA0, 0xE3, 0x82, 0xAD, 0xE3, 0x83, 0xAD, 0xE3,
+		0x83, 0xA1, 0xE3, 0x83, 0xBC, 0xE3, 0x83, 0x88,
+		0xE3, 0x83, 0xAB, 0xE3, 0x82, 0xAD, 0xE3, 0x83,
+		0xAD, 0xE3, 0x83, 0xAF, 0xE3, 0x83, 0x83, 0xE3,
+		0x83, 0x88, 0xE3, 0x82, 0xAF, 0xE3, 0x82, 0x99,
+		0xE3, 0x83, 0xA9, 0xE3, 0x83, 0xA0, 0xE3, 0x82,
+		0xAF, 0xE3, 0x82, 0x99, 0xE3, 0x83, 0xA9, 0xE3,
+		0x83, 0xA0, 0xE3, 0x83, 0x88, 0xE3, 0x83, 0xB3,
+		0xE3, 0x82, 0xAF, 0xE3, 0x83, 0xAB, 0xE3, 0x82,
+		0xBB, 0xE3, 0x82, 0x99, 0xE3, 0x82, 0xA4, 0xE3,
+		0x83, 0xAD, 0xE3, 0x82, 0xAF, 0xE3, 0x83, 0xAD,
+		0xE3, 0x83, 0xBC, 0xE3, 0x83, 0x8D, 0xE3, 0x82,
+		0xB1, 0xE3, 0x83, 0xBC, 0xE3, 0x82, 0xB9, 0xE3,
+		0x82, 0xB3, 0xE3, 0x83, 0xAB, 0xE3, 0x83, 0x8A,
+		0xE3, 0x82, 0xB3, 0xE3, 0x83, 0xBC, 0xE3, 0x83,
+		0x9B, 0xE3, 0x82, 0x9A, 0xE3, 0x82, 0xB5, 0xE3,
+		0x82, 0xA4, 0xE3, 0x82, 0xAF, 0xE3, 0x83, 0xAB,
+		0xE3, 0x82, 0xB5, 0xE3, 0x83, 0xB3, 0xE3, 0x83,
+		0x81, 0xE3, 0x83, 0xBC, 0xE3, 0x83, 0xA0, 0xE3,
+		0x82, 0xB7, 0xE3, 0x83, 0xAA, 0xE3, 0x83, 0xB3,
+		0xE3, 0x82, 0xAF, 0xE3, 0x82, 0x99, 0xE3, 0x82,
+		0xBB, 0xE3, 0x83, 0xB3, 0xE3, 0x83, 0x81, 0xE3,
+		0x82, 0xBB, 0xE3, 0x83, 0xB3, 0xE3, 0x83, 0x88,
+		0xE3, 0x82, 0xBF, 0xE3, 0x82, 0x99, 0xE3, 0x83,
+		0xBC, 0xE3, 0x82, 0xB9, 0xE3, 0x83, 0x86, 0xE3,
+		0x82, 0x99, 0xE3, 0x82, 0xB7, 0xE3, 0x83, 0x88,
+		0xE3, 0x82, 0x99, 0xE3, 0x83, 0xAB, 0xE3, 0x83,
+		0x88, 0xE3, 0x83, 0xB3, 0xE3, 0x83, 0x8A, 0xE3,
+		0x83, 0x8E, 0xE3, 0x83, 0x8E, 0xE3, 0x83, 0x83,
+		0xE3, 0x83, 0x88, 0xE3, 0x83, 0x8F, 0xE3, 0x82,
+		0xA4, 0xE3, 0x83, 0x84, 0xE3, 0x83, 0x8F, 0xE3,
+		0x82, 0x9A, 0xE3, 0x83, 0xBC, 0xE3, 0x82, 0xBB,
+		0xE3, 0x83, 0xB3, 0xE3, 0x83, 0x88, 0xE3, 0x83,
+		0x8F, 0xE3, 0x82, 0x9A, 0xE3, 0x83, 0xBC, 0xE3,
+		0x83, 0x84, 0xE3, 0x83, 0x8F, 0xE3, 0x82, 0x99,
+		0xE3, 0x83, 0xBC, 0xE3, 0x83, 0xAC, 0xE3, 0x83,
+		0xAB, 0xE3, 0x83, 0x92, 0xE3, 0x82, 0x9A, 0xE3,
+		0x82, 0xA2, 0xE3, 0x82, 0xB9, 0xE3, 0x83, 0x88,
+		0xE3, 0x83, 0xAB, 0xE3, 0x83, 0x92, 0xE3, 0x82,
+		0x9A, 0xE3, 0x82, 0xAF, 0xE3, 0x83, 0xAB, 0xE3,
+		0x83, 0x92, 0xE3, 0x82, 0x9A, 0xE3, 0x82, 0xB3,
+		0xE3, 0x83, 0x92, 0xE3, 0x82, 0x99, 0xE3, 0x83,
+		0xAB, 0xE3, 0x83, 0x95, 0xE3, 0x82, 0xA1, 0xE3,
+		0x83, 0xA9, 0xE3, 0x83, 0x83, 0xE3, 0x83, 0x88,
+		0xE3, 0x82, 0x99, 0xE3, 0x83, 0x95, 0xE3, 0x82,
+		0xA3, 0xE3, 0x83, 0xBC, 0xE3, 0x83, 0x88, 0xE3,
+		0x83, 0x95, 0xE3, 0x82, 0x99, 0xE3, 0x83, 0x83,
+		0xE3, 0x82, 0xB7, 0xE3, 0x82, 0xA7, 0xE3, 0x83,
+		0xAB, 0xE3, 0x83, 0x95, 0xE3, 0x83, 0xA9, 0xE3,
+		0x83, 0xB3, 0xE3, 0x83, 0x98, 0xE3, 0x82, 0xAF,
+		0xE3, 0x82, 0xBF, 0xE3, 0x83, 0xBC, 0xE3, 0x83,
+		0xAB, 0xE3, 0x83, 0x98, 0xE3, 0x82, 0x9A, 0xE3,
+		0x82, 0xBD, 0xE3, 0x83, 0x98, 0xE3, 0x82, 0x9A,
+		0xE3, 0x83, 0x8B, 0xE3, 0x83, 0x92, 0xE3, 0x83,
+		0x98, 0xE3, 0x83, 0xAB, 0xE3, 0x83, 0x84, 0xE3,
+		0x83, 0x98, 0xE3, 0x82, 0x9A, 0xE3, 0x83, 0xB3,
+		0xE3, 0x82, 0xB9, 0xE3, 0x83, 0x98, 0xE3, 0x82,
+		0x9A, 0xE3, 0x83, 0xBC, 0xE3, 0x82, 0xB7, 0xE3,
+		0x82, 0x99, 0xE3, 0x83, 0x98, 0xE3, 0x82, 0x99,
+		0xE3, 0x83, 0xBC, 0xE3, 0x82, 0xBF, 0xE3, 0x83,
+		0x9B, 0xE3, 0x82, 0x9A, 0xE3, 0x82, 0xA4, 0xE3,
+		0x83, 0xB3, 0xE3, 0x83, 0x88, 0xE3, 0x83, 0x9B,
+		0xE3, 0x82, 0x99, 0xE3, 0x83, 0xAB, 0xE3, 0x83,
+		0x88, 0xE3, 0x83, 0x9B, 0xE3, 0x83, 0xB3, 0xE3,
+		0x83, 0x9B, 0xE3, 0x82, 0x9A, 0xE3, 0x83, 0xB3,
+		0xE3, 0x83, 0x88, 0xE3, 0x82, 0x99, 0xE3, 0x83,
+		0x9B, 0xE3, 0x83, 0xBC, 0xE3, 0x83, 0xAB, 0xE3,
+		0x83, 0x9B, 0xE3, 0x83, 0xBC, 0xE3, 0x83, 0xB3,
+		0xE3, 0x83, 0x9E, 0xE3, 0x82, 0xA4, 0xE3, 0x82,
+		0xAF, 0xE3, 0x83, 0xAD, 0xE3, 0x83, 0x9E, 0xE3,
+		0x82, 0xA4, 0xE3, 0x83, 0xAB, 0xE3, 0x83, 0x9E,
+		0xE3, 0x83, 0x83, 0xE3, 0x83, 0x8F, 0xE3, 0x83,
+		0x9E, 0xE3, 0x83, 0xAB, 0xE3, 0x82, 0xAF, 0xE3,
+		0x83, 0x9E, 0xE3, 0x83, 0xB3, 0xE3, 0x82, 0xB7,
+		0xE3, 0x83, 0xA7, 0xE3, 0x83, 0xB3, 0xE3, 0x83,
+		0x9F, 0xE3, 0x82, 0xAF, 0xE3, 0x83, 0xAD, 0xE3,
+		0x83, 0xB3, 0xE3, 0x83, 0x9F, 0xE3, 0x83, 0xAA,
+		0xE3, 0x83, 0x9F, 0xE3, 0x83, 0xAA, 0xE3, 0x83,
+		0x8F, 0xE3, 0x82, 0x99, 0xE3, 0x83, 0xBC, 0xE3,
+		0x83, 0xAB, 0xE3, 0x83, 0xA1, 0xE3, 0x82, 0xAB,
+		0xE3, 0x82, 0x99, 0xE3, 0x83, 0xA1, 0xE3, 0x82,
+		0xAB, 0xE3, 0x82, 0x99, 0xE3, 0x83, 0x88, 0xE3,
+		0x83, 0xB3, 0xE3, 0x83, 0xA1, 0xE3, 0x83, 0xBC,
+		0xE3, 0x83, 0x88, 0xE3, 0x83, 0xAB, 0xE3, 0x83,
+		0xA4, 0xE3, 0x83, 0xBC, 0xE3, 0x83, 0x88, 0xE3,
+		0x82, 0x99, 0xE3, 0x83, 0xA4, 0xE3, 0x83, 0xBC,
+		0xE3, 0x83, 0xAB, 0xE3, 0x83, 0xA6, 0xE3, 0x82,
+		0xA2, 0xE3, 0x83, 0xB3, 0xE3, 0x83, 0xAA, 0xE3,
+		0x83, 0x83, 0xE3, 0x83, 0x88, 0xE3, 0x83, 0xAB,
+		0xE3, 0x83, 0xAA, 0xE3, 0x83, 0xA9, 0xE3, 0x83,
+		0xAB, 0xE3, 0x83, 0x92, 0xE3, 0x82, 0x9A, 0xE3,
+		0x83, 0xBC, 0xE3, 0x83, 0xAB, 0xE3, 0x83, 0xBC,
+		0xE3, 0x83, 0x95, 0xE3, 0x82, 0x99, 0xE3, 0x83,
+		0xAB, 0xE3, 0x83, 0xAC, 0xE3, 0x83, 0xA0, 0xE3,
+		0x83, 0xAC, 0xE3, 0x83, 0xB3, 0xE3, 0x83, 0x88,
+		0xE3, 0x82, 0xB1, 0xE3, 0x82, 0x99, 0xE3, 0x83,
+		0xB3, 0xE3, 0x83, 0xAF, 0xE3, 0x83, 0x83, 0xE3,
+		0x83, 0x88, 0x30, 0xE7, 0x82, 0xB9, 0x31, 0xE7,
+		0x82, 0xB9, 0x32, 0xE7, 0x82, 0xB9, 0x33, 0xE7,
+		0x82, 0xB9, 0x34, 0xE7, 0x82, 0xB9, 0x35, 0xE7,
+		0x82, 0xB9, 0x36, 0xE7, 0x82, 0xB9, 0x37, 0xE7,
+		0x82, 0xB9, 0x38, 0xE7, 0x82, 0xB9, 0x39, 0xE7,
+		0x82, 0xB9, 0x31, 0x30, 0xE7, 0x82, 0xB9, 0x31,
+		0x31, 0xE7, 0x82, 0xB9, 0x31, 0x32, 0xE7, 0x82,
+		0xB9, 0x31, 0x33, 0xE7, 0x82, 0xB9, 0x31, 0x34,
+		0xE7, 0x82, 0xB9, 0x31, 0x35, 0xE7, 0x82, 0xB9,
+		0x31, 0x36, 0xE7, 0x82, 0xB9, 0x31, 0x37, 0xE7,
+		0x82, 0xB9, 0x31, 0x38, 0xE7, 0x82, 0xB9, 0x31,
+		0x39, 0xE7, 0x82, 0xB9, 0x32, 0x30, 0xE7, 0x82,
+		0xB9, 0x32, 0x31, 0xE7, 0x82, 0xB9, 0x32, 0x32,
+		0xE7, 0x82, 0xB9, 0x32, 0x33, 0xE7, 0x82, 0xB9,
+		0x32, 0x34, 0xE7, 0x82, 0xB9, 0x68, 0x50, 0x61,
+		0x64, 0x61, 0x41, 0x55, 0x62, 0x61, 0x72, 0x6F,
+		0x56, 0x70, 0x63, 0xE5, 0xB9, 0xB3, 0xE6, 0x88,
+		0x90, 0xE6, 0x98, 0xAD, 0xE5, 0x92, 0x8C, 0xE5,
+		0xA4, 0xA7, 0xE6, 0xAD, 0xA3, 0xE6, 0x98, 0x8E,
+		0xE6, 0xB2, 0xBB, 0xE6, 0xA0, 0xAA, 0xE5, 0xBC,
+		0x8F, 0xE4, 0xBC, 0x9A, 0xE7, 0xA4, 0xBE, 0x70,
+		0x41, 0x6E, 0x41, 0xCE, 0xBC, 0x41, 0x6D, 0x41,
+		0x6B, 0x41, 0x4B, 0x42, 0x4D, 0x42, 0x47, 0x42,
+		0x63, 0x61, 0x6C, 0x6B, 0x63, 0x61, 0x6C, 0x70,
+		0x46, 0x6E, 0x46, 0xCE, 0xBC, 0x46, 0xCE, 0xBC,
+		0x67, 0x6D, 0x67, 0x6B, 0x67, 0x48, 0x7A, 0x6B,
+		0x48, 0x7A, 0x4D, 0x48, 0x7A, 0x47, 0x48, 0x7A,
+		0x54, 0x48, 0x7A, 0xCE, 0xBC, 0x6C, 0x6D, 0x6C,
+		0x64, 0x6C, 0x6B, 0x6C, 0x66, 0x6D, 0x6E, 0x6D,
+		0xCE, 0xBC, 0x6D, 0x6D, 0x6D, 0x63, 0x6D, 0x6B,
+		0x6D, 0x6D, 0x6D, 0x32, 0x63, 0x6D, 0x32, 0x6D,
+		0x32, 0x6B, 0x6D, 0x32, 0x6D, 0x6D, 0x33, 0x63,
+		0x6D, 0x33, 0x6D, 0x33, 0x6B, 0x6D, 0x33, 0x6D,
+		0xE2, 0x88, 0x95, 0x73, 0x6D, 0xE2, 0x88, 0x95,
+		0x73, 0x32, 0x50, 0x61, 0x6B, 0x50, 0x61, 0x4D,
+		0x50, 0x61, 0x47, 0x50, 0x61, 0x72, 0x61, 0x64,
+		0x72, 0x61, 0x64, 0xE2, 0x88, 0x95, 0x73, 0x72,
+		0x61, 0x64, 0xE2, 0x88, 0x95, 0x73, 0x32, 0x70,
+		0x73, 0x6E, 0x73, 0xCE, 0xBC, 0x73, 0x6D, 0x73,
+		0x70, 0x56, 0x6E, 0x56, 0xCE, 0xBC, 0x56, 0x6D,
+		0x56, 0x6B, 0x56, 0x4D, 0x56, 0x70, 0x57, 0x6E,
+		0x57, 0xCE, 0xBC, 0x57, 0x6D, 0x57, 0x6B, 0x57,
+		0x4D, 0x57, 0x6B, 0xCE, 0xA9, 0x4D, 0xCE, 0xA9,
+		0x61, 0x2E, 0x6D, 0x2E, 0x42, 0x71, 0x63, 0x63,
+		0x63, 0x64, 0x43, 0xE2, 0x88, 0x95, 0x6B, 0x67,
+		0x43, 0x6F, 0x2E, 0x64, 0x42, 0x47, 0x79, 0x68,
+		0x61, 0x48, 0x50, 0x69, 0x6E, 0x4B, 0x4B, 0x4B,
+		0x4D, 0x6B, 0x74, 0x6C, 0x6D, 0x6C, 0x6E, 0x6C,
+		0x6F, 0x67, 0x6C, 0x78, 0x6D, 0x62, 0x6D, 0x69,
+		0x6C, 0x6D, 0x6F, 0x6C, 0x50, 0x48, 0x70, 0x2E,
+		0x6D, 0x2E, 0x50, 0x50, 0x4D, 0x50, 0x52, 0x73,
+		0x72, 0x53, 0x76, 0x57, 0x62, 0x31, 0xE6, 0x97,
+		0xA5, 0x32, 0xE6, 0x97, 0xA5, 0x33, 0xE6, 0x97,
+		0xA5, 0x34, 0xE6, 0x97, 0xA5, 0x35, 0xE6, 0x97,
+		0xA5, 0x36, 0xE6, 0x97, 0xA5, 0x37, 0xE6, 0x97,
+		0xA5, 0x38, 0xE6, 0x97, 0xA5, 0x39, 0xE6, 0x97,
+		0xA5, 0x31, 0x30, 0xE6, 0x97, 0xA5, 0x31, 0x31,
+		0xE6, 0x97, 0xA5, 0x31, 0x32, 0xE6, 0x97, 0xA5,
+		0x31, 0x33, 0xE6, 0x97, 0xA5, 0x31, 0x34, 0xE6,
+		0x97, 0xA5, 0x31, 0x35, 0xE6, 0x97, 0xA5, 0x31,
+		0x36, 0xE6, 0x97, 0xA5, 0x31, 0x37, 0xE6, 0x97,
+		0xA5, 0x31, 0x38, 0xE6, 0x97, 0xA5, 0x31, 0x39,
+		0xE6, 0x97, 0xA5, 0x32, 0x30, 0xE6, 0x97, 0xA5,
+		0x32, 0x31, 0xE6, 0x97, 0xA5, 0x32, 0x32, 0xE6,
+		0x97, 0xA5, 0x32, 0x33, 0xE6, 0x97, 0xA5, 0x32,
+		0x34, 0xE6, 0x97, 0xA5, 0x32, 0x35, 0xE6, 0x97,
+		0xA5, 0x32, 0x36, 0xE6, 0x97, 0xA5, 0x32, 0x37,
+		0xE6, 0x97, 0xA5, 0x32, 0x38, 0xE6, 0x97, 0xA5,
+		0x32, 0x39, 0xE6, 0x97, 0xA5, 0x33, 0x30, 0xE6,
+		0x97, 0xA5, 0x33, 0x31, 0xE6, 0x97, 0xA5, 0xF6,
+		0xE8, 0xB1, 0x88, 0xF6, 0xE6, 0x9B, 0xB4, 0xF6,
+		0xE8, 0xBB, 0x8A, 0xF6, 0xE8, 0xB3, 0x88, 0xF6,
+		0xE6, 0xBB, 0x91, 0xF6, 0xE4, 0xB8, 0xB2, 0xF6,
+		0xE5, 0x8F, 0xA5, 0xF6, 0xE9, 0xBE, 0x9C, 0xF6,
+		0xE9, 0xBE, 0x9C, 0xF6, 0xE5, 0xA5, 0x91, 0xF6,
+		0xE9, 0x87, 0x91, 0xF6, 0xE5, 0x96, 0x87, 0xF6,
+		0xE5, 0xA5, 0x88, 0xF6, 0xE6, 0x87, 0xB6, 0xF6,
+		0xE7, 0x99, 0xA9, 0xF6, 0xE7, 0xBE, 0x85, 0xF6,
+		0xE8, 0x98, 0xBF, 0xF6, 0xE8, 0x9E, 0xBA, 0xF6,
+		0xE8, 0xA3, 0xB8, 0xF6, 0xE9, 0x82, 0x8F, 0xF6,
+		0xE6, 0xA8, 0x82, 0xF6, 0xE6, 0xB4, 0x9B, 0xF6,
+		0xE7, 0x83, 0x99, 0xF6, 0xE7, 0x8F, 0x9E, 0xF6,
+		0xE8, 0x90, 0xBD, 0xF6, 0xE9, 0x85, 0xAA, 0xF6,
+		0xE9, 0xA7, 0xB1, 0xF6, 0xE4, 0xBA, 0x82, 0xF6,
+		0xE5, 0x8D, 0xB5, 0xF6, 0xE6, 0xAC, 0x84, 0xF6,
+		0xE7, 0x88, 0x9B, 0xF6, 0xE8, 0x98, 0xAD, 0xF6,
+		0xE9, 0xB8, 0x9E, 0xF6, 0xE5, 0xB5, 0x90, 0xF6,
+		0xE6, 0xBF, 0xAB, 0xF6, 0xE8, 0x97, 0x8D, 0xF6,
+		0xE8, 0xA5, 0xA4, 0xF6, 0xE6, 0x8B, 0x89, 0xF6,
+		0xE8, 0x87, 0x98, 0xF6, 0xE8, 0xA0, 0x9F, 0xF6,
+		0xE5, 0xBB, 0x8A, 0xF6, 0xE6, 0x9C, 0x97, 0xF6,
+		0xE6, 0xB5, 0xAA, 0xF6, 0xE7, 0x8B, 0xBC, 0xF6,
+		0xE9, 0x83, 0x8E, 0xF6, 0xE4, 0xBE, 0x86, 0xF6,
+		0xE5, 0x86, 0xB7, 0xF6, 0xE5, 0x8B, 0x9E, 0xF6,
+		0xE6, 0x93, 0x84, 0xF6, 0xE6, 0xAB, 0x93, 0xF6,
+		0xE7, 0x88, 0x90, 0xF6, 0xE7, 0x9B, 0xA7, 0xF6,
+		0xE8, 0x80, 0x81, 0xF6, 0xE8, 0x98, 0x86, 0xF6,
+		0xE8, 0x99, 0x9C, 0xF6, 0xE8, 0xB7, 0xAF, 0xF6,
+		0xE9, 0x9C, 0xB2, 0xF6, 0xE9, 0xAD, 0xAF, 0xF6,
+		0xE9, 0xB7, 0xBA, 0xF6, 0xE7, 0xA2, 0x8C, 0xF6,
+		0xE7, 0xA5, 0xBF, 0xF6, 0xE7, 0xB6, 0xA0, 0xF6,
+		0xE8, 0x8F, 0x89, 0xF6, 0xE9, 0x8C, 0x84, 0xF6,
+		0xE9, 0xB9, 0xBF, 0xF6, 0xE8, 0xAB, 0x96, 0xF6,
+		0xE5, 0xA3, 0x9F, 0xF6, 0xE5, 0xBC, 0x84, 0xF6,
+		0xE7, 0xB1, 0xA0, 0xF6, 0xE8, 0x81, 0xBE, 0xF6,
+		0xE7, 0x89, 0xA2, 0xF6, 0xE7, 0xA3, 0x8A, 0xF6,
+		0xE8, 0xB3, 0x82, 0xF6, 0xE9, 0x9B, 0xB7, 0xF6,
+		0xE5, 0xA3, 0x98, 0xF6, 0xE5, 0xB1, 0xA2, 0xF6,
+		0xE6, 0xA8, 0x93, 0xF6, 0xE6, 0xB7, 0x9A, 0xF6,
+		0xE6, 0xBC, 0x8F, 0xF6, 0xE7, 0xB4, 0xAF, 0xF6,
+		0xE7, 0xB8, 0xB7, 0xF6, 0xE9, 0x99, 0x8B, 0xF6,
+		0xE5, 0x8B, 0x92, 0xF6, 0xE8, 0x82, 0x8B, 0xF6,
+		0xE5, 0x87, 0x9C, 0xF6, 0xE5, 0x87, 0x8C, 0xF6,
+		0xE7, 0xA8, 0x9C, 0xF6, 0xE7, 0xB6, 0xBE, 0xF6,
+		0xE8, 0x8F, 0xB1, 0xF6, 0xE9, 0x99, 0xB5, 0xF6,
+		0xE8, 0xAE, 0x80, 0xF6, 0xE6, 0x8B, 0x8F, 0xF6,
+		0xE6, 0xA8, 0x82, 0xF6, 0xE8, 0xAB, 0xBE, 0xF6,
+		0xE4, 0xB8, 0xB9, 0xF6, 0xE5, 0xAF, 0xA7, 0xF6,
+		0xE6, 0x80, 0x92, 0xF6, 0xE7, 0x8E, 0x87, 0xF6,
+		0xE7, 0x95, 0xB0, 0xF6, 0xE5, 0x8C, 0x97, 0xF6,
+		0xE7, 0xA3, 0xBB, 0xF6, 0xE4, 0xBE, 0xBF, 0xF6,
+		0xE5, 0xBE, 0xA9, 0xF6, 0xE4, 0xB8, 0x8D, 0xF6,
+		0xE6, 0xB3, 0x8C, 0xF6, 0xE6, 0x95, 0xB8, 0xF6,
+		0xE7, 0xB4, 0xA2, 0xF6, 0xE5, 0x8F, 0x83, 0xF6,
+		0xE5, 0xA1, 0x9E, 0xF6, 0xE7, 0x9C, 0x81, 0xF6,
+		0xE8, 0x91, 0x89, 0xF6, 0xE8, 0xAA, 0xAA, 0xF6,
+		0xE6, 0xAE, 0xBA, 0xF6, 0xE8, 0xBE, 0xB0, 0xF6,
+		0xE6, 0xB2, 0x88, 0xF6, 0xE6, 0x8B, 0xBE, 0xF6,
+		0xE8, 0x8B, 0xA5, 0xF6, 0xE6, 0x8E, 0xA0, 0xF6,
+		0xE7, 0x95, 0xA5, 0xF6, 0xE4, 0xBA, 0xAE, 0xF6,
+		0xE5, 0x85, 0xA9, 0xF6, 0xE5, 0x87, 0x89, 0xF6,
+		0xE6, 0xA2, 0x81, 0xF6, 0xE7, 0xB3, 0xA7, 0xF6,
+		0xE8, 0x89, 0xAF, 0xF6, 0xE8, 0xAB, 0x92, 0xF6,
+		0xE9, 0x87, 0x8F, 0xF6, 0xE5, 0x8B, 0xB5, 0xF6,
+		0xE5, 0x91, 0x82, 0xF6, 0xE5, 0xA5, 0xB3, 0xF6,
+		0xE5, 0xBB, 0xAC, 0xF6, 0xE6, 0x97, 0x85, 0xF6,
+		0xE6, 0xBF, 0xBE, 0xF6, 0xE7, 0xA4, 0xAA, 0xF6,
+		0xE9, 0x96, 0xAD, 0xF6, 0xE9, 0xA9, 0xAA, 0xF6,
+		0xE9, 0xBA, 0x97, 0xF6, 0xE9, 0xBB, 0x8E, 0xF6,
+		0xE5, 0x8A, 0x9B, 0xF6, 0xE6, 0x9B, 0x86, 0xF6,
+		0xE6, 0xAD, 0xB7, 0xF6, 0xE8, 0xBD, 0xA2, 0xF6,
+		0xE5, 0xB9, 0xB4, 0xF6, 0xE6, 0x86, 0x90, 0xF6,
+		0xE6, 0x88, 0x80, 0xF6, 0xE6, 0x92, 0x9A, 0xF6,
+		0xE6, 0xBC, 0xA3, 0xF6, 0xE7, 0x85, 0x89, 0xF6,
+		0xE7, 0x92, 0x89, 0xF6, 0xE7, 0xA7, 0x8A, 0xF6,
+		0xE7, 0xB7, 0xB4, 0xF6, 0xE8, 0x81, 0xAF, 0xF6,
+		0xE8, 0xBC, 0xA6, 0xF6, 0xE8, 0x93, 0xAE, 0xF6,
+		0xE9, 0x80, 0xA3, 0xF6, 0xE9, 0x8D, 0x8A, 0xF6,
+		0xE5, 0x88, 0x97, 0xF6, 0xE5, 0x8A, 0xA3, 0xF6,
+		0xE5, 0x92, 0xBD, 0xF6, 0xE7, 0x83, 0x88, 0xF6,
+		0xE8, 0xA3, 0x82, 0xF6, 0xE8, 0xAA, 0xAA, 0xF6,
+		0xE5, 0xBB, 0x89, 0xF6, 0xE5, 0xBF, 0xB5, 0xF6,
+		0xE6, 0x8D, 0xBB, 0xF6, 0xE6, 0xAE, 0xAE, 0xF6,
+		0xE7, 0xB0, 0xBE, 0xF6, 0xE7, 0x8D, 0xB5, 0xF6,
+		0xE4, 0xBB, 0xA4, 0xF6, 0xE5, 0x9B, 0xB9, 0xF6,
+		0xE5, 0xAF, 0xA7, 0xF6, 0xE5, 0xB6, 0xBA, 0xF6,
+		0xE6, 0x80, 0x9C, 0xF6, 0xE7, 0x8E, 0xB2, 0xF6,
+		0xE7, 0x91, 0xA9, 0xF6, 0xE7, 0xBE, 0x9A, 0xF6,
+		0xE8, 0x81, 0x86, 0xF6, 0xE9, 0x88, 0xB4, 0xF6,
+		0xE9, 0x9B, 0xB6, 0xF6, 0xE9, 0x9D, 0x88, 0xF6,
+		0xE9, 0xA0, 0x98, 0xF6, 0xE4, 0xBE, 0x8B, 0xF6,
+		0xE7, 0xA6, 0xAE, 0xF6, 0xE9, 0x86, 0xB4, 0xF6,
+		0xE9, 0x9A, 0xB8, 0xF6, 0xE6, 0x83, 0xA1, 0xF6,
+		0xE4, 0xBA, 0x86, 0xF6, 0xE5, 0x83, 0x9A, 0xF6,
+		0xE5, 0xAF, 0xAE, 0xF6, 0xE5, 0xB0, 0xBF, 0xF6,
+		0xE6, 0x96, 0x99, 0xF6, 0xE6, 0xA8, 0x82, 0xF6,
+		0xE7, 0x87, 0x8E, 0xF6, 0xE7, 0x99, 0x82, 0xF6,
+		0xE8, 0x93, 0xBC, 0xF6, 0xE9, 0x81, 0xBC, 0xF6,
+		0xE9, 0xBE, 0x8D, 0xF6, 0xE6, 0x9A, 0x88, 0xF6,
+		0xE9, 0x98, 0xAE, 0xF6, 0xE5, 0x8A, 0x89, 0xF6,
+		0xE6, 0x9D, 0xBB, 0xF6, 0xE6, 0x9F, 0xB3, 0xF6,
+		0xE6, 0xB5, 0x81, 0xF6, 0xE6, 0xBA, 0x9C, 0xF6,
+		0xE7, 0x90, 0x89, 0xF6, 0xE7, 0x95, 0x99, 0xF6,
+		0xE7, 0xA1, 0xAB, 0xF6, 0xE7, 0xB4, 0x90, 0xF6,
+		0xE9, 0xA1, 0x9E, 0xF6, 0xE5, 0x85, 0xAD, 0xF6,
+		0xE6, 0x88, 0xAE, 0xF6, 0xE9, 0x99, 0xB8, 0xF6,
+		0xE5, 0x80, 0xAB, 0xF6, 0xE5, 0xB4, 0x99, 0xF6,
+		0xE6, 0xB7, 0xAA, 0xF6, 0xE8, 0xBC, 0xAA, 0xF6,
+		0xE5, 0xBE, 0x8B, 0xF6, 0xE6, 0x85, 0x84, 0xF6,
+		0xE6, 0xA0, 0x97, 0xF6, 0xE7, 0x8E, 0x87, 0xF6,
+		0xE9, 0x9A, 0x86, 0xF6, 0xE5, 0x88, 0xA9, 0xF6,
+		0xE5, 0x90, 0x8F, 0xF6, 0xE5, 0xB1, 0xA5, 0xF6,
+		0xE6, 0x98, 0x93, 0xF6, 0xE6, 0x9D, 0x8E, 0xF6,
+		0xE6, 0xA2, 0xA8, 0xF6, 0xE6, 0xB3, 0xA5, 0xF6,
+		0xE7, 0x90, 0x86, 0xF6, 0xE7, 0x97, 0xA2, 0xF6,
+		0xE7, 0xBD, 0xB9, 0xF6, 0xE8, 0xA3, 0x8F, 0xF6,
+		0xE8, 0xA3, 0xA1, 0xF6, 0xE9, 0x87, 0x8C, 0xF6,
+		0xE9, 0x9B, 0xA2, 0xF6, 0xE5, 0x8C, 0xBF, 0xF6,
+		0xE6, 0xBA, 0xBA, 0xF6, 0xE5, 0x90, 0x9D, 0xF6,
+		0xE7, 0x87, 0x90, 0xF6, 0xE7, 0x92, 0x98, 0xF6,
+		0xE8, 0x97, 0xBA, 0xF6, 0xE9, 0x9A, 0xA3, 0xF6,
+		0xE9, 0xB1, 0x97, 0xF6, 0xE9, 0xBA, 0x9F, 0xF6,
+		0xE6, 0x9E, 0x97, 0xF6, 0xE6, 0xB7, 0x8B, 0xF6,
+		0xE8, 0x87, 0xA8, 0xF6, 0xE7, 0xAB, 0x8B, 0xF6,
+		0xE7, 0xAC, 0xA0, 0xF6, 0xE7, 0xB2, 0x92, 0xF6,
+		0xE7, 0x8B, 0x80, 0xF6, 0xE7, 0x82, 0x99, 0xF6,
+		0xE8, 0xAD, 0x98, 0xF6, 0xE4, 0xBB, 0x80, 0xF6,
+		0xE8, 0x8C, 0xB6, 0xF6, 0xE5, 0x88, 0xBA, 0xF6,
+		0xE5, 0x88, 0x87, 0xF6, 0xE5, 0xBA, 0xA6, 0xF6,
+		0xE6, 0x8B, 0x93, 0xF6, 0xE7, 0xB3, 0x96, 0xF6,
+		0xE5, 0xAE, 0x85, 0xF6, 0xE6, 0xB4, 0x9E, 0xF6,
+		0xE6, 0x9A, 0xB4, 0xF6, 0xE8, 0xBC, 0xBB, 0xF6,
+		0xE8, 0xA1, 0x8C, 0xF6, 0xE9, 0x99, 0x8D, 0xF6,
+		0xE8, 0xA6, 0x8B, 0xF6, 0xE5, 0xBB, 0x93, 0xF6,
+		0xE5, 0x85, 0x80, 0xF6, 0xE5, 0x97, 0x80, 0xF6,
+		0xE5, 0xA1, 0x9A, 0xF6, 0xE6, 0x99, 0xB4, 0xF6,
+		0xE5, 0x87, 0x9E, 0xF6, 0xE7, 0x8C, 0xAA, 0xF6,
+		0xE7, 0x9B, 0x8A, 0xF6, 0xE7, 0xA4, 0xBC, 0xF6,
+		0xE7, 0xA5, 0x9E, 0xF6, 0xE7, 0xA5, 0xA5, 0xF6,
+		0xE7, 0xA6, 0x8F, 0xF6, 0xE9, 0x9D, 0x96, 0xF6,
+		0xE7, 0xB2, 0xBE, 0xF6, 0xE7, 0xBE, 0xBD, 0xF6,
+		0xE8, 0x98, 0x92, 0xF6, 0xE8, 0xAB, 0xB8, 0xF6,
+		0xE9, 0x80, 0xB8, 0xF6, 0xE9, 0x83, 0xBD, 0xF6,
+		0xE9, 0xA3, 0xAF, 0xF6, 0xE9, 0xA3, 0xBC, 0xF6,
+		0xE9, 0xA4, 0xA8, 0xF6, 0xE9, 0xB6, 0xB4, 0xF6,
+		0xE4, 0xBE, 0xAE, 0xF6, 0xE5, 0x83, 0xA7, 0xF6,
+		0xE5, 0x85, 0x8D, 0xF6, 0xE5, 0x8B, 0x89, 0xF6,
+		0xE5, 0x8B, 0xA4, 0xF6, 0xE5, 0x8D, 0x91, 0xF6,
+		0xE5, 0x96, 0x9D, 0xF6, 0xE5, 0x98, 0x86, 0xF6,
+		0xE5, 0x99, 0xA8, 0xF6, 0xE5, 0xA1, 0x80, 0xF6,
+		0xE5, 0xA2, 0xA8, 0xF6, 0xE5, 0xB1, 0xA4, 0xF6,
+		0xE5, 0xB1, 0xAE, 0xF6, 0xE6, 0x82, 0x94, 0xF6,
+		0xE6, 0x85, 0xA8, 0xF6, 0xE6, 0x86, 0x8E, 0xF6,
+		0xE6, 0x87, 0xB2, 0xF6, 0xE6, 0x95, 0x8F, 0xF6,
+		0xE6, 0x97, 0xA2, 0xF6, 0xE6, 0x9A, 0x91, 0xF6,
+		0xE6, 0xA2, 0x85, 0xF6, 0xE6, 0xB5, 0xB7, 0xF6,
+		0xE6, 0xB8, 0x9A, 0xF6, 0xE6, 0xBC, 0xA2, 0xF6,
+		0xE7, 0x85, 0xAE, 0xF6, 0xE7, 0x88, 0xAB, 0xF6,
+		0xE7, 0x90, 0xA2, 0xF6, 0xE7, 0xA2, 0x91, 0xF6,
+		0xE7, 0xA4, 0xBE, 0xF6, 0xE7, 0xA5, 0x89, 0xF6,
+		0xE7, 0xA5, 0x88, 0xF6, 0xE7, 0xA5, 0x90, 0xF6,
+		0xE7, 0xA5, 0x96, 0xF6, 0xE7, 0xA5, 0x9D, 0xF6,
+		0xE7, 0xA6, 0x8D, 0xF6, 0xE7, 0xA6, 0x8E, 0xF6,
+		0xE7, 0xA9, 0x80, 0xF6, 0xE7, 0xAA, 0x81, 0xF6,
+		0xE7, 0xAF, 0x80, 0xF6, 0xE7, 0xB7, 0xB4, 0xF6,
+		0xE7, 0xB8, 0x89, 0xF6, 0xE7, 0xB9, 0x81, 0xF6,
+		0xE7, 0xBD, 0xB2, 0xF6, 0xE8, 0x80, 0x85, 0xF6,
+		0xE8, 0x87, 0xAD, 0xF6, 0xE8, 0x89, 0xB9, 0xF6,
+		0xE8, 0x89, 0xB9, 0xF6, 0xE8, 0x91, 0x97, 0xF6,
+		0xE8, 0xA4, 0x90, 0xF6, 0xE8, 0xA6, 0x96, 0xF6,
+		0xE8, 0xAC, 0x81, 0xF6, 0xE8, 0xAC, 0xB9, 0xF6,
+		0xE8, 0xB3, 0x93, 0xF6, 0xE8, 0xB4, 0x88, 0xF6,
+		0xE8, 0xBE, 0xB6, 0xF6, 0xE9, 0x80, 0xB8, 0xF6,
+		0xE9, 0x9B, 0xA3, 0xF6, 0xE9, 0x9F, 0xBF, 0xF6,
+		0xE9, 0xA0, 0xBB, 0x66, 0x66, 0x66, 0x69, 0x66,
+		0x6C, 0x66, 0x66, 0x69, 0x66, 0x66, 0x6C, 0x73,
+		0x74, 0x73, 0x74, 0xD5, 0xB4, 0xD5, 0xB6, 0xD5,
+		0xB4, 0xD5, 0xA5, 0xD5, 0xB4, 0xD5, 0xAB, 0xD5,
+		0xBE, 0xD5, 0xB6, 0xD5, 0xB4, 0xD5, 0xAD, 0xF6,
+		0xD7, 0x99, 0xD6, 0xB4, 0xF6, 0xD7, 0xB2, 0xD6,
+		0xB7, 0xD7, 0xA2, 0xD7, 0x90, 0xD7, 0x93, 0xD7,
+		0x94, 0xD7, 0x9B, 0xD7, 0x9C, 0xD7, 0x9D, 0xD7,
+		0xA8, 0xD7, 0xAA, 0x2B, 0xF6, 0xD7, 0xA9, 0xD7,
+		0x81, 0xF6, 0xD7, 0xA9, 0xD7, 0x82, 0xF6, 0xD7,
+		0xA9, 0xD6, 0xBC, 0xD7, 0x81, 0xF6, 0xD7, 0xA9,
+		0xD6, 0xBC, 0xD7, 0x82, 0xF6, 0xD7, 0x90, 0xD6,
+		0xB7, 0xF6, 0xD7, 0x90, 0xD6, 0xB8, 0xF6, 0xD7,
+		0x90, 0xD6, 0xBC, 0xF6, 0xD7, 0x91, 0xD6, 0xBC,
+		0xF6, 0xD7, 0x92, 0xD6, 0xBC, 0xF6, 0xD7, 0x93,
+		0xD6, 0xBC, 0xF6, 0xD7, 0x94, 0xD6, 0xBC, 0xF6,
+		0xD7, 0x95, 0xD6, 0xBC, 0xF6, 0xD7, 0x96, 0xD6,
+		0xBC, 0xF6, 0xD7, 0x98, 0xD6, 0xBC, 0xF6, 0xD7,
+		0x99, 0xD6, 0xBC, 0xF6, 0xD7, 0x9A, 0xD6, 0xBC,
+		0xF6, 0xD7, 0x9B, 0xD6, 0xBC, 0xF6, 0xD7, 0x9C,
+		0xD6, 0xBC, 0xF6, 0xD7, 0x9E, 0xD6, 0xBC, 0xF6,
+		0xD7, 0xA0, 0xD6, 0xBC, 0xF6, 0xD7, 0xA1, 0xD6,
+		0xBC, 0xF6, 0xD7, 0xA3, 0xD6, 0xBC, 0xF6, 0xD7,
+		0xA4, 0xD6, 0xBC, 0xF6, 0xD7, 0xA6, 0xD6, 0xBC,
+		0xF6, 0xD7, 0xA7, 0xD6, 0xBC, 0xF6, 0xD7, 0xA8,
+		0xD6, 0xBC, 0xF6, 0xD7, 0xA9, 0xD6, 0xBC, 0xF6,
+		0xD7, 0xAA, 0xD6, 0xBC, 0xF6, 0xD7, 0x95, 0xD6,
+		0xB9, 0xF6, 0xD7, 0x91, 0xD6, 0xBF, 0xF6, 0xD7,
+		0x9B, 0xD6, 0xBF, 0xF6, 0xD7, 0xA4, 0xD6, 0xBF,
+		0xD7, 0x90, 0xD7, 0x9C, 0xD9, 0xB1, 0xD9, 0xB1,
+		0xD9, 0xBB, 0xD9, 0xBB, 0xD9, 0xBB, 0xD9, 0xBB,
+		0xD9, 0xBE, 0xD9, 0xBE, 0xD9, 0xBE, 0xD9, 0xBE,
+		0xDA, 0x80, 0xDA, 0x80, 0xDA, 0x80, 0xDA, 0x80,
+		0xD9, 0xBA, 0xD9, 0xBA, 0xD9, 0xBA, 0xD9, 0xBA,
+		0xD9, 0xBF, 0xD9, 0xBF, 0xD9, 0xBF, 0xD9, 0xBF,
+		0xD9, 0xB9, 0xD9, 0xB9, 0xD9, 0xB9, 0xD9, 0xB9,
+		0xDA, 0xA4, 0xDA, 0xA4, 0xDA, 0xA4, 0xDA, 0xA4,
+		0xDA, 0xA6, 0xDA, 0xA6, 0xDA, 0xA6, 0xDA, 0xA6,
+		0xDA, 0x84, 0xDA, 0x84, 0xDA, 0x84, 0xDA, 0x84,
+		0xDA, 0x83, 0xDA, 0x83, 0xDA, 0x83, 0xDA, 0x83,
+		0xDA, 0x86, 0xDA, 0x86, 0xDA, 0x86, 0xDA, 0x86,
+		0xDA, 0x87, 0xDA, 0x87, 0xDA, 0x87, 0xDA, 0x87,
+		0xDA, 0x8D, 0xDA, 0x8D, 0xDA, 0x8C, 0xDA, 0x8C,
+		0xDA, 0x8E, 0xDA, 0x8E, 0xDA, 0x88, 0xDA, 0x88,
+		0xDA, 0x98, 0xDA, 0x98, 0xDA, 0x91, 0xDA, 0x91,
+		0xDA, 0xA9, 0xDA, 0xA9, 0xDA, 0xA9, 0xDA, 0xA9,
+		0xDA, 0xAF, 0xDA, 0xAF, 0xDA, 0xAF, 0xDA, 0xAF,
+		0xDA, 0xB3, 0xDA, 0xB3, 0xDA, 0xB3, 0xDA, 0xB3,
+		0xDA, 0xB1, 0xDA, 0xB1, 0xDA, 0xB1, 0xDA, 0xB1,
+		0xDA, 0xBA, 0xDA, 0xBA, 0xDA, 0xBB, 0xDA, 0xBB,
+		0xDA, 0xBB, 0xDA, 0xBB, 0xDB, 0x95, 0xD9, 0x94,
+		0xDB, 0x95, 0xD9, 0x94, 0xDB, 0x81, 0xDB, 0x81,
+		0xDB, 0x81, 0xDB, 0x81, 0xDA, 0xBE, 0xDA, 0xBE,
+		0xDA, 0xBE, 0xDA, 0xBE, 0xDB, 0x92, 0xDB, 0x92,
+		0xDB, 0x92, 0xD9, 0x94, 0xDB, 0x92, 0xD9, 0x94,
+		0xDA, 0xAD, 0xDA, 0xAD, 0xDA, 0xAD, 0xDA, 0xAD,
+		0xDB, 0x87, 0xDB, 0x87, 0xDB, 0x86, 0xDB, 0x86,
+		0xDB, 0x88, 0xDB, 0x88, 0xDB, 0x87, 0xD9, 0xB4,
+		0xDB, 0x8B, 0xDB, 0x8B, 0xDB, 0x85, 0xDB, 0x85,
+		0xDB, 0x89, 0xDB, 0x89, 0xDB, 0x90, 0xDB, 0x90,
+		0xDB, 0x90, 0xDB, 0x90, 0xD9, 0x89, 0xD9, 0x89,
+		0xD9, 0x8A, 0xD9, 0x94, 0xD8, 0xA7, 0xD9, 0x8A,
+		0xD9, 0x94, 0xD8, 0xA7, 0xD9, 0x8A, 0xD9, 0x94,
+		0xDB, 0x95, 0xD9, 0x8A, 0xD9, 0x94, 0xDB, 0x95,
+		0xD9, 0x8A, 0xD9, 0x94, 0xD9, 0x88, 0xD9, 0x8A,
+		0xD9, 0x94, 0xD9, 0x88, 0xD9, 0x8A, 0xD9, 0x94,
+		0xDB, 0x87, 0xD9, 0x8A, 0xD9, 0x94, 0xDB, 0x87,
+		0xD9, 0x8A, 0xD9, 0x94, 0xDB, 0x86, 0xD9, 0x8A,
+		0xD9, 0x94, 0xDB, 0x86, 0xD9, 0x8A, 0xD9, 0x94,
+		0xDB, 0x88, 0xD9, 0x8A, 0xD9, 0x94, 0xDB, 0x88,
+		0xD9, 0x8A, 0xD9, 0x94, 0xDB, 0x90, 0xD9, 0x8A,
+		0xD9, 0x94, 0xDB, 0x90, 0xD9, 0x8A, 0xD9, 0x94,
+		0xDB, 0x90, 0xD9, 0x8A, 0xD9, 0x94, 0xD9, 0x89,
+		0xD9, 0x8A, 0xD9, 0x94, 0xD9, 0x89, 0xD9, 0x8A,
+		0xD9, 0x94, 0xD9, 0x89, 0xDB, 0x8C, 0xDB, 0x8C,
+		0xDB, 0x8C, 0xDB, 0x8C, 0xD9, 0x8A, 0xD9, 0x94,
+		0xD8, 0xAC, 0xD9, 0x8A, 0xD9, 0x94, 0xD8, 0xAD,
+		0xD9, 0x8A, 0xD9, 0x94, 0xD9, 0x85, 0xD9, 0x8A,
+		0xD9, 0x94, 0xD9, 0x89, 0xD9, 0x8A, 0xD9, 0x94,
+		0xD9, 0x8A, 0xD8, 0xA8, 0xD8, 0xAC, 0xD8, 0xA8,
+		0xD8, 0xAD, 0xD8, 0xA8, 0xD8, 0xAE, 0xD8, 0xA8,
+		0xD9, 0x85, 0xD8, 0xA8, 0xD9, 0x89, 0xD8, 0xA8,
+		0xD9, 0x8A, 0xD8, 0xAA, 0xD8, 0xAC, 0xD8, 0xAA,
+		0xD8, 0xAD, 0xD8, 0xAA, 0xD8, 0xAE, 0xD8, 0xAA,
+		0xD9, 0x85, 0xD8, 0xAA, 0xD9, 0x89, 0xD8, 0xAA,
+		0xD9, 0x8A, 0xD8, 0xAB, 0xD8, 0xAC, 0xD8, 0xAB,
+		0xD9, 0x85, 0xD8, 0xAB, 0xD9, 0x89, 0xD8, 0xAB,
+		0xD9, 0x8A, 0xD8, 0xAC, 0xD8, 0xAD, 0xD8, 0xAC,
+		0xD9, 0x85, 0xD8, 0xAD, 0xD8, 0xAC, 0xD8, 0xAD,
+		0xD9, 0x85, 0xD8, 0xAE, 0xD8, 0xAC, 0xD8, 0xAE,
+		0xD8, 0xAD, 0xD8, 0xAE, 0xD9, 0x85, 0xD8, 0xB3,
+		0xD8, 0xAC, 0xD8, 0xB3, 0xD8, 0xAD, 0xD8, 0xB3,
+		0xD8, 0xAE, 0xD8, 0xB3, 0xD9, 0x85, 0xD8, 0xB5,
+		0xD8, 0xAD, 0xD8, 0xB5, 0xD9, 0x85, 0xD8, 0xB6,
+		0xD8, 0xAC, 0xD8, 0xB6, 0xD8, 0xAD, 0xD8, 0xB6,
+		0xD8, 0xAE, 0xD8, 0xB6, 0xD9, 0x85, 0xD8, 0xB7,
+		0xD8, 0xAD, 0xD8, 0xB7, 0xD9, 0x85, 0xD8, 0xB8,
+		0xD9, 0x85, 0xD8, 0xB9, 0xD8, 0xAC, 0xD8, 0xB9,
+		0xD9, 0x85, 0xD8, 0xBA, 0xD8, 0xAC, 0xD8, 0xBA,
+		0xD9, 0x85, 0xD9, 0x81, 0xD8, 0xAC, 0xD9, 0x81,
+		0xD8, 0xAD, 0xD9, 0x81, 0xD8, 0xAE, 0xD9, 0x81,
+		0xD9, 0x85, 0xD9, 0x81, 0xD9, 0x89, 0xD9, 0x81,
+		0xD9, 0x8A, 0xD9, 0x82, 0xD8, 0xAD, 0xD9, 0x82,
+		0xD9, 0x85, 0xD9, 0x82, 0xD9, 0x89, 0xD9, 0x82,
+		0xD9, 0x8A, 0xD9, 0x83, 0xD8, 0xA7, 0xD9, 0x83,
+		0xD8, 0xAC, 0xD9, 0x83, 0xD8, 0xAD, 0xD9, 0x83,
+		0xD8, 0xAE, 0xD9, 0x83, 0xD9, 0x84, 0xD9, 0x83,
+		0xD9, 0x85, 0xD9, 0x83, 0xD9, 0x89, 0xD9, 0x83,
+		0xD9, 0x8A, 0xD9, 0x84, 0xD8, 0xAC, 0xD9, 0x84,
+		0xD8, 0xAD, 0xD9, 0x84, 0xD8, 0xAE, 0xD9, 0x84,
+		0xD9, 0x85, 0xD9, 0x84, 0xD9, 0x89, 0xD9, 0x84,
+		0xD9, 0x8A, 0xD9, 0x85, 0xD8, 0xAC, 0xD9, 0x85,
+		0xD8, 0xAD, 0xD9, 0x85, 0xD8, 0xAE, 0xD9, 0x85,
+		0xD9, 0x85, 0xD9, 0x85, 0xD9, 0x89, 0xD9, 0x85,
+		0xD9, 0x8A, 0xD9, 0x86, 0xD8, 0xAC, 0xD9, 0x86,
+		0xD8, 0xAD, 0xD9, 0x86, 0xD8, 0xAE, 0xD9, 0x86,
+		0xD9, 0x85, 0xD9, 0x86, 0xD9, 0x89, 0xD9, 0x86,
+		0xD9, 0x8A, 0xD9, 0x87, 0xD8, 0xAC, 0xD9, 0x87,
+		0xD9, 0x85, 0xD9, 0x87, 0xD9, 0x89, 0xD9, 0x87,
+		0xD9, 0x8A, 0xD9, 0x8A, 0xD8, 0xAC, 0xD9, 0x8A,
+		0xD8, 0xAD, 0xD9, 0x8A, 0xD8, 0xAE, 0xD9, 0x8A,
+		0xD9, 0x85, 0xD9, 0x8A, 0xD9, 0x89, 0xD9, 0x8A,
+		0xD9, 0x8A, 0xD8, 0xB0, 0xD9, 0xB0, 0xD8, 0xB1,
+		0xD9, 0xB0, 0xD9, 0x89, 0xD9, 0xB0, 0x20, 0xD9,
+		0x8C, 0xD9, 0x91, 0x20, 0xD9, 0x8D, 0xD9, 0x91,
+		0x20, 0xD9, 0x8E, 0xD9, 0x91, 0x20, 0xD9, 0x8F,
+		0xD9, 0x91, 0x20, 0xD9, 0x90, 0xD9, 0x91, 0x20,
+		0xD9, 0x91, 0xD9, 0xB0, 0xD9, 0x8A, 0xD9, 0x94,
+		0xD8, 0xB1, 0xD9, 0x8A, 0xD9, 0x94, 0xD8, 0xB2,
+		0xD9, 0x8A, 0xD9, 0x94, 0xD9, 0x85, 0xD9, 0x8A,
+		0xD9, 0x94, 0xD9, 0x86, 0xD9, 0x8A, 0xD9, 0x94,
+		0xD9, 0x89, 0xD9, 0x8A, 0xD9, 0x94, 0xD9, 0x8A,
+		0xD8, 0xA8, 0xD8, 0xB1, 0xD8, 0xA8, 0xD8, 0xB2,
+		0xD8, 0xA8, 0xD9, 0x85, 0xD8, 0xA8, 0xD9, 0x86,
+		0xD8, 0xA8, 0xD9, 0x89, 0xD8, 0xA8, 0xD9, 0x8A,
+		0xD8, 0xAA, 0xD8, 0xB1, 0xD8, 0xAA, 0xD8, 0xB2,
+		0xD8, 0xAA, 0xD9, 0x85, 0xD8, 0xAA, 0xD9, 0x86,
+		0xD8, 0xAA, 0xD9, 0x89, 0xD8, 0xAA, 0xD9, 0x8A,
+		0xD8, 0xAB, 0xD8, 0xB1, 0xD8, 0xAB, 0xD8, 0xB2,
+		0xD8, 0xAB, 0xD9, 0x85, 0xD8, 0xAB, 0xD9, 0x86,
+		0xD8, 0xAB, 0xD9, 0x89, 0xD8, 0xAB, 0xD9, 0x8A,
+		0xD9, 0x81, 0xD9, 0x89, 0xD9, 0x81, 0xD9, 0x8A,
+		0xD9, 0x82, 0xD9, 0x89, 0xD9, 0x82, 0xD9, 0x8A,
+		0xD9, 0x83, 0xD8, 0xA7, 0xD9, 0x83, 0xD9, 0x84,
+		0xD9, 0x83, 0xD9, 0x85, 0xD9, 0x83, 0xD9, 0x89,
+		0xD9, 0x83, 0xD9, 0x8A, 0xD9, 0x84, 0xD9, 0x85,
+		0xD9, 0x84, 0xD9, 0x89, 0xD9, 0x84, 0xD9, 0x8A,
+		0xD9, 0x85, 0xD8, 0xA7, 0xD9, 0x85, 0xD9, 0x85,
+		0xD9, 0x86, 0xD8, 0xB1, 0xD9, 0x86, 0xD8, 0xB2,
+		0xD9, 0x86, 0xD9, 0x85, 0xD9, 0x86, 0xD9, 0x86,
+		0xD9, 0x86, 0xD9, 0x89, 0xD9, 0x86, 0xD9, 0x8A,
+		0xD9, 0x89, 0xD9, 0xB0, 0xD9, 0x8A, 0xD8, 0xB1,
+		0xD9, 0x8A, 0xD8, 0xB2, 0xD9, 0x8A, 0xD9, 0x85,
+		0xD9, 0x8A, 0xD9, 0x86, 0xD9, 0x8A, 0xD9, 0x89,
+		0xD9, 0x8A, 0xD9, 0x8A, 0xD9, 0x8A, 0xD9, 0x94,
+		0xD8, 0xAC, 0xD9, 0x8A, 0xD9, 0x94, 0xD8, 0xAD,
+		0xD9, 0x8A, 0xD9, 0x94, 0xD8, 0xAE, 0xD9, 0x8A,
+		0xD9, 0x94, 0xD9, 0x85, 0xD9, 0x8A, 0xD9, 0x94,
+		0xD9, 0x87, 0xD8, 0xA8, 0xD8, 0xAC, 0xD8, 0xA8,
+		0xD8, 0xAD, 0xD8, 0xA8, 0xD8, 0xAE, 0xD8, 0xA8,
+		0xD9, 0x85, 0xD8, 0xA8, 0xD9, 0x87, 0xD8, 0xAA,
+		0xD8, 0xAC, 0xD8, 0xAA, 0xD8, 0xAD, 0xD8, 0xAA,
+		0xD8, 0xAE, 0xD8, 0xAA, 0xD9, 0x85, 0xD8, 0xAA,
+		0xD9, 0x87, 0xD8, 0xAB, 0xD9, 0x85, 0xD8, 0xAC,
+		0xD8, 0xAD, 0xD8, 0xAC, 0xD9, 0x85, 0xD8, 0xAD,
+		0xD8, 0xAC, 0xD8, 0xAD, 0xD9, 0x85, 0xD8, 0xAE,
+		0xD8, 0xAC, 0xD8, 0xAE, 0xD9, 0x85, 0xD8, 0xB3,
+		0xD8, 0xAC, 0xD8, 0xB3, 0xD8, 0xAD, 0xD8, 0xB3,
+		0xD8, 0xAE, 0xD8, 0xB3, 0xD9, 0x85, 0xD8, 0xB5,
+		0xD8, 0xAD, 0xD8, 0xB5, 0xD8, 0xAE, 0xD8, 0xB5,
+		0xD9, 0x85, 0xD8, 0xB6, 0xD8, 0xAC, 0xD8, 0xB6,
+		0xD8, 0xAD, 0xD8, 0xB6, 0xD8, 0xAE, 0xD8, 0xB6,
+		0xD9, 0x85, 0xD8, 0xB7, 0xD8, 0xAD, 0xD8, 0xB8,
+		0xD9, 0x85, 0xD8, 0xB9, 0xD8, 0xAC, 0xD8, 0xB9,
+		0xD9, 0x85, 0xD8, 0xBA, 0xD8, 0xAC, 0xD8, 0xBA,
+		0xD9, 0x85, 0xD9, 0x81, 0xD8, 0xAC, 0xD9, 0x81,
+		0xD8, 0xAD, 0xD9, 0x81, 0xD8, 0xAE, 0xD9, 0x81,
+		0xD9, 0x85, 0xD9, 0x82, 0xD8, 0xAD, 0xD9, 0x82,
+		0xD9, 0x85, 0xD9, 0x83, 0xD8, 0xAC, 0xD9, 0x83,
+		0xD8, 0xAD, 0xD9, 0x83, 0xD8, 0xAE, 0xD9, 0x83,
+		0xD9, 0x84, 0xD9, 0x83, 0xD9, 0x85, 0xD9, 0x84,
+		0xD8, 0xAC, 0xD9, 0x84, 0xD8, 0xAD, 0xD9, 0x84,
+		0xD8, 0xAE, 0xD9, 0x84, 0xD9, 0x85, 0xD9, 0x84,
+		0xD9, 0x87, 0xD9, 0x85, 0xD8, 0xAC, 0xD9, 0x85,
+		0xD8, 0xAD, 0xD9, 0x85, 0xD8, 0xAE, 0xD9, 0x85,
+		0xD9, 0x85, 0xD9, 0x86, 0xD8, 0xAC, 0xD9, 0x86,
+		0xD8, 0xAD, 0xD9, 0x86, 0xD8, 0xAE, 0xD9, 0x86,
+		0xD9, 0x85, 0xD9, 0x86, 0xD9, 0x87, 0xD9, 0x87,
+		0xD8, 0xAC, 0xD9, 0x87, 0xD9, 0x85, 0xD9, 0x87,
+		0xD9, 0xB0, 0xD9, 0x8A, 0xD8, 0xAC, 0xD9, 0x8A,
+		0xD8, 0xAD, 0xD9, 0x8A, 0xD8, 0xAE, 0xD9, 0x8A,
+		0xD9, 0x85, 0xD9, 0x8A, 0xD9, 0x87, 0xD9, 0x8A,
+		0xD9, 0x94, 0xD9, 0x85, 0xD9, 0x8A, 0xD9, 0x94,
+		0xD9, 0x87, 0xD8, 0xA8, 0xD9, 0x85, 0xD8, 0xA8,
+		0xD9, 0x87, 0xD8, 0xAA, 0xD9, 0x85, 0xD8, 0xAA,
+		0xD9, 0x87, 0xD8, 0xAB, 0xD9, 0x85, 0xD8, 0xAB,
+		0xD9, 0x87, 0xD8, 0xB3, 0xD9, 0x85, 0xD8, 0xB3,
+		0xD9, 0x87, 0xD8, 0xB4, 0xD9, 0x85, 0xD8, 0xB4,
+		0xD9, 0x87, 0xD9, 0x83, 0xD9, 0x84, 0xD9, 0x83,
+		0xD9, 0x85, 0xD9, 0x84, 0xD9, 0x85, 0xD9, 0x86,
+		0xD9, 0x85, 0xD9, 0x86, 0xD9, 0x87, 0xD9, 0x8A,
+		0xD9, 0x85, 0xD9, 0x8A, 0xD9, 0x87, 0xD9, 0x80,
+		0xD9, 0x8E, 0xD9, 0x91, 0xD9, 0x80, 0xD9, 0x8F,
+		0xD9, 0x91, 0xD9, 0x80, 0xD9, 0x90, 0xD9, 0x91,
+		0xD8, 0xB7, 0xD9, 0x89, 0xD8, 0xB7, 0xD9, 0x8A,
+		0xD8, 0xB9, 0xD9, 0x89, 0xD8, 0xB9, 0xD9, 0x8A,
+		0xD8, 0xBA, 0xD9, 0x89, 0xD8, 0xBA, 0xD9, 0x8A,
+		0xD8, 0xB3, 0xD9, 0x89, 0xD8, 0xB3, 0xD9, 0x8A,
+		0xD8, 0xB4, 0xD9, 0x89, 0xD8, 0xB4, 0xD9, 0x8A,
+		0xD8, 0xAD, 0xD9, 0x89, 0xD8, 0xAD, 0xD9, 0x8A,
+		0xD8, 0xAC, 0xD9, 0x89, 0xD8, 0xAC, 0xD9, 0x8A,
+		0xD8, 0xAE, 0xD9, 0x89, 0xD8, 0xAE, 0xD9, 0x8A,
+		0xD8, 0xB5, 0xD9, 0x89, 0xD8, 0xB5, 0xD9, 0x8A,
+		0xD8, 0xB6, 0xD9, 0x89, 0xD8, 0xB6, 0xD9, 0x8A,
+		0xD8, 0xB4, 0xD8, 0xAC, 0xD8, 0xB4, 0xD8, 0xAD,
+		0xD8, 0xB4, 0xD8, 0xAE, 0xD8, 0xB4, 0xD9, 0x85,
+		0xD8, 0xB4, 0xD8, 0xB1, 0xD8, 0xB3, 0xD8, 0xB1,
+		0xD8, 0xB5, 0xD8, 0xB1, 0xD8, 0xB6, 0xD8, 0xB1,
+		0xD8, 0xB7, 0xD9, 0x89, 0xD8, 0xB7, 0xD9, 0x8A,
+		0xD8, 0xB9, 0xD9, 0x89, 0xD8, 0xB9, 0xD9, 0x8A,
+		0xD8, 0xBA, 0xD9, 0x89, 0xD8, 0xBA, 0xD9, 0x8A,
+		0xD8, 0xB3, 0xD9, 0x89, 0xD8, 0xB3, 0xD9, 0x8A,
+		0xD8, 0xB4, 0xD9, 0x89, 0xD8, 0xB4, 0xD9, 0x8A,
+		0xD8, 0xAD, 0xD9, 0x89, 0xD8, 0xAD, 0xD9, 0x8A,
+		0xD8, 0xAC, 0xD9, 0x89, 0xD8, 0xAC, 0xD9, 0x8A,
+		0xD8, 0xAE, 0xD9, 0x89, 0xD8, 0xAE, 0xD9, 0x8A,
+		0xD8, 0xB5, 0xD9, 0x89, 0xD8, 0xB5, 0xD9, 0x8A,
+		0xD8, 0xB6, 0xD9, 0x89, 0xD8, 0xB6, 0xD9, 0x8A,
+		0xD8, 0xB4, 0xD8, 0xAC, 0xD8, 0xB4, 0xD8, 0xAD,
+		0xD8, 0xB4, 0xD8, 0xAE, 0xD8, 0xB4, 0xD9, 0x85,
+		0xD8, 0xB4, 0xD8, 0xB1, 0xD8, 0xB3, 0xD8, 0xB1,
+		0xD8, 0xB5, 0xD8, 0xB1, 0xD8, 0xB6, 0xD8, 0xB1,
+		0xD8, 0xB4, 0xD8, 0xAC, 0xD8, 0xB4, 0xD8, 0xAD,
+		0xD8, 0xB4, 0xD8, 0xAE, 0xD8, 0xB4, 0xD9, 0x85,
+		0xD8, 0xB3, 0xD9, 0x87, 0xD8, 0xB4, 0xD9, 0x87,
+		0xD8, 0xB7, 0xD9, 0x85, 0xD8, 0xB3, 0xD8, 0xAC,
+		0xD8, 0xB3, 0xD8, 0xAD, 0xD8, 0xB3, 0xD8, 0xAE,
+		0xD8, 0xB4, 0xD8, 0xAC, 0xD8, 0xB4, 0xD8, 0xAD,
+		0xD8, 0xB4, 0xD8, 0xAE, 0xD8, 0xB7, 0xD9, 0x85,
+		0xD8, 0xB8, 0xD9, 0x85, 0xD8, 0xA7, 0xD9, 0x8B,
+		0xD8, 0xA7, 0xD9, 0x8B, 0xD8, 0xAA, 0xD8, 0xAC,
+		0xD9, 0x85, 0xD8, 0xAA, 0xD8, 0xAD, 0xD8, 0xAC,
+		0xD8, 0xAA, 0xD8, 0xAD, 0xD8, 0xAC, 0xD8, 0xAA,
+		0xD8, 0xAD, 0xD9, 0x85, 0xD8, 0xAA, 0xD8, 0xAE,
+		0xD9, 0x85, 0xD8, 0xAA, 0xD9, 0x85, 0xD8, 0xAC,
+		0xD8, 0xAA, 0xD9, 0x85, 0xD8, 0xAD, 0xD8, 0xAA,
+		0xD9, 0x85, 0xD8, 0xAE, 0xD8, 0xAC, 0xD9, 0x85,
+		0xD8, 0xAD, 0xD8, 0xAC, 0xD9, 0x85, 0xD8, 0xAD,
+		0xD8, 0xAD, 0xD9, 0x85, 0xD9, 0x8A, 0xD8, 0xAD,
+		0xD9, 0x85, 0xD9, 0x89, 0xD8, 0xB3, 0xD8, 0xAD,
+		0xD8, 0xAC, 0xD8, 0xB3, 0xD8, 0xAC, 0xD8, 0xAD,
+		0xD8, 0xB3, 0xD8, 0xAC, 0xD9, 0x89, 0xD8, 0xB3,
+		0xD9, 0x85, 0xD8, 0xAD, 0xD8, 0xB3, 0xD9, 0x85,
+		0xD8, 0xAD, 0xD8, 0xB3, 0xD9, 0x85, 0xD8, 0xAC,
+		0xD8, 0xB3, 0xD9, 0x85, 0xD9, 0x85, 0xD8, 0xB3,
+		0xD9, 0x85, 0xD9, 0x85, 0xD8, 0xB5, 0xD8, 0xAD,
+		0xD8, 0xAD, 0xD8, 0xB5, 0xD8, 0xAD, 0xD8, 0xAD,
+		0xD8, 0xB5, 0xD9, 0x85, 0xD9, 0x85, 0xD8, 0xB4,
+		0xD8, 0xAD, 0xD9, 0x85, 0xD8, 0xB4, 0xD8, 0xAD,
+		0xD9, 0x85, 0xD8, 0xB4, 0xD8, 0xAC, 0xD9, 0x8A,
+		0xD8, 0xB4, 0xD9, 0x85, 0xD8, 0xAE, 0xD8, 0xB4,
+		0xD9, 0x85, 0xD8, 0xAE, 0xD8, 0xB4, 0xD9, 0x85,
+		0xD9, 0x85, 0xD8, 0xB4, 0xD9, 0x85, 0xD9, 0x85,
+		0xD8, 0xB6, 0xD8, 0xAD, 0xD9, 0x89, 0xD8, 0xB6,
+		0xD8, 0xAE, 0xD9, 0x85, 0xD8, 0xB6, 0xD8, 0xAE,
+		0xD9, 0x85, 0xD8, 0xB7, 0xD9, 0x85, 0xD8, 0xAD,
+		0xD8, 0xB7, 0xD9, 0x85, 0xD8, 0xAD, 0xD8, 0xB7,
+		0xD9, 0x85, 0xD9, 0x85, 0xD8, 0xB7, 0xD9, 0x85,
+		0xD9, 0x8A, 0xD8, 0xB9, 0xD8, 0xAC, 0xD9, 0x85,
+		0xD8, 0xB9, 0xD9, 0x85, 0xD9, 0x85, 0xD8, 0xB9,
+		0xD9, 0x85, 0xD9, 0x85, 0xD8, 0xB9, 0xD9, 0x85,
+		0xD9, 0x89, 0xD8, 0xBA, 0xD9, 0x85, 0xD9, 0x85,
+		0xD8, 0xBA, 0xD9, 0x85, 0xD9, 0x8A, 0xD8, 0xBA,
+		0xD9, 0x85, 0xD9, 0x89, 0xD9, 0x81, 0xD8, 0xAE,
+		0xD9, 0x85, 0xD9, 0x81, 0xD8, 0xAE, 0xD9, 0x85,
+		0xD9, 0x82, 0xD9, 0x85, 0xD8, 0xAD, 0xD9, 0x82,
+		0xD9, 0x85, 0xD9, 0x85, 0xD9, 0x84, 0xD8, 0xAD,
+		0xD9, 0x85, 0xD9, 0x84, 0xD8, 0xAD, 0xD9, 0x8A,
+		0xD9, 0x84, 0xD8, 0xAD, 0xD9, 0x89, 0xD9, 0x84,
+		0xD8, 0xAC, 0xD8, 0xAC, 0xD9, 0x84, 0xD8, 0xAC,
+		0xD8, 0xAC, 0xD9, 0x84, 0xD8, 0xAE, 0xD9, 0x85,
+		0xD9, 0x84, 0xD8, 0xAE, 0xD9, 0x85, 0xD9, 0x84,
+		0xD9, 0x85, 0xD8, 0xAD, 0xD9, 0x84, 0xD9, 0x85,
+		0xD8, 0xAD, 0xD9, 0x85, 0xD8, 0xAD, 0xD8, 0xAC,
+		0xD9, 0x85, 0xD8, 0xAD, 0xD9, 0x85, 0xD9, 0x85,
+		0xD8, 0xAD, 0xD9, 0x8A, 0xD9, 0x85, 0xD8, 0xAC,
+		0xD8, 0xAD, 0xD9, 0x85, 0xD8, 0xAC, 0xD9, 0x85,
+		0xD9, 0x85, 0xD8, 0xAE, 0xD8, 0xAC, 0xD9, 0x85,
+		0xD8, 0xAE, 0xD9, 0x85, 0xD9, 0x85, 0xD8, 0xAC,
+		0xD8, 0xAE, 0xD9, 0x87, 0xD9, 0x85, 0xD8, 0xAC,
+		0xD9, 0x87, 0xD9, 0x85, 0xD9, 0x85, 0xD9, 0x86,
+		0xD8, 0xAD, 0xD9, 0x85, 0xD9, 0x86, 0xD8, 0xAD,
+		0xD9, 0x89, 0xD9, 0x86, 0xD8, 0xAC, 0xD9, 0x85,
+		0xD9, 0x86, 0xD8, 0xAC, 0xD9, 0x85, 0xD9, 0x86,
+		0xD8, 0xAC, 0xD9, 0x89, 0xD9, 0x86, 0xD9, 0x85,
+		0xD9, 0x8A, 0xD9, 0x86, 0xD9, 0x85, 0xD9, 0x89,
+		0xD9, 0x8A, 0xD9, 0x85, 0xD9, 0x85, 0xD9, 0x8A,
+		0xD9, 0x85, 0xD9, 0x85, 0xD8, 0xA8, 0xD8, 0xAE,
+		0xD9, 0x8A, 0xD8, 0xAA, 0xD8, 0xAC, 0xD9, 0x8A,
+		0xD8, 0xAA, 0xD8, 0xAC, 0xD9, 0x89, 0xD8, 0xAA,
+		0xD8, 0xAE, 0xD9, 0x8A, 0xD8, 0xAA, 0xD8, 0xAE,
+		0xD9, 0x89, 0xD8, 0xAA, 0xD9, 0x85, 0xD9, 0x8A,
+		0xD8, 0xAA, 0xD9, 0x85, 0xD9, 0x89, 0xD8, 0xAC,
+		0xD9, 0x85, 0xD9, 0x8A, 0xD8, 0xAC, 0xD8, 0xAD,
+		0xD9, 0x89, 0xD8, 0xAC, 0xD9, 0x85, 0xD9, 0x89,
+		0xD8, 0xB3, 0xD8, 0xAE, 0xD9, 0x89, 0xD8, 0xB5,
+		0xD8, 0xAD, 0xD9, 0x8A, 0xD8, 0xB4, 0xD8, 0xAD,
+		0xD9, 0x8A, 0xD8, 0xB6, 0xD8, 0xAD, 0xD9, 0x8A,
+		0xD9, 0x84, 0xD8, 0xAC, 0xD9, 0x8A, 0xD9, 0x84,
+		0xD9, 0x85, 0xD9, 0x8A, 0xD9, 0x8A, 0xD8, 0xAD,
+		0xD9, 0x8A, 0xD9, 0x8A, 0xD8, 0xAC, 0xD9, 0x8A,
+		0xD9, 0x8A, 0xD9, 0x85, 0xD9, 0x8A, 0xD9, 0x85,
+		0xD9, 0x85, 0xD9, 0x8A, 0xD9, 0x82, 0xD9, 0x85,
+		0xD9, 0x8A, 0xD9, 0x86, 0xD8, 0xAD, 0xD9, 0x8A,
+		0xD9, 0x82, 0xD9, 0x85, 0xD8, 0xAD, 0xD9, 0x84,
+		0xD8, 0xAD, 0xD9, 0x85, 0xD8, 0xB9, 0xD9, 0x85,
+		0xD9, 0x8A, 0xD9, 0x83, 0xD9, 0x85, 0xD9, 0x8A,
+		0xD9, 0x86, 0xD8, 0xAC, 0xD8, 0xAD, 0xD9, 0x85,
+		0xD8, 0xAE, 0xD9, 0x8A, 0xD9, 0x84, 0xD8, 0xAC,
+		0xD9, 0x85, 0xD9, 0x83, 0xD9, 0x85, 0xD9, 0x85,
+		0xD9, 0x84, 0xD8, 0xAC, 0xD9, 0x85, 0xD9, 0x86,
+		0xD8, 0xAC, 0xD8, 0xAD, 0xD8, 0xAC, 0xD8, 0xAD,
+		0xD9, 0x8A, 0xD8, 0xAD, 0xD8, 0xAC, 0xD9, 0x8A,
+		0xD9, 0x85, 0xD8, 0xAC, 0xD9, 0x8A, 0xD9, 0x81,
+		0xD9, 0x85, 0xD9, 0x8A, 0xD8, 0xA8, 0xD8, 0xAD,
+		0xD9, 0x8A, 0xD9, 0x83, 0xD9, 0x85, 0xD9, 0x85,
+		0xD8, 0xB9, 0xD8, 0xAC, 0xD9, 0x85, 0xD8, 0xB5,
+		0xD9, 0x85, 0xD9, 0x85, 0xD8, 0xB3, 0xD8, 0xAE,
+		0xD9, 0x8A, 0xD9, 0x86, 0xD8, 0xAC, 0xD9, 0x8A,
+		0xD8, 0xB5, 0xD9, 0x84, 0xDB, 0x92, 0xD9, 0x82,
+		0xD9, 0x84, 0xDB, 0x92, 0xD8, 0xA7, 0xD9, 0x84,
+		0xD9, 0x84, 0xD9, 0x87, 0xD8, 0xA7, 0xD9, 0x83,
+		0xD8, 0xA8, 0xD8, 0xB1, 0xD9, 0x85, 0xD8, 0xAD,
+		0xD9, 0x85, 0xD8, 0xAF, 0xD8, 0xB5, 0xD9, 0x84,
+		0xD8, 0xB9, 0xD9, 0x85, 0xD8, 0xB1, 0xD8, 0xB3,
+		0xD9, 0x88, 0xD9, 0x84, 0xD8, 0xB9, 0xD9, 0x84,
+		0xD9, 0x8A, 0xD9, 0x87, 0xD9, 0x88, 0xD8, 0xB3,
+		0xD9, 0x84, 0xD9, 0x85, 0xD8, 0xB5, 0xD9, 0x84,
+		0xD9, 0x89, 0xD8, 0xB5, 0xD9, 0x84, 0xD9, 0x89,
+		0x20, 0xD8, 0xA7, 0xD9, 0x84, 0xD9, 0x84, 0xD9,
+		0x87, 0x20, 0xD8, 0xB9, 0xD9, 0x84, 0xD9, 0x8A,
+		0xD9, 0x87, 0x20, 0xD9, 0x88, 0xD8, 0xB3, 0xD9,
+		0x84, 0xD9, 0x85, 0xD8, 0xAC, 0xD9, 0x84, 0x20,
+		0xD8, 0xAC, 0xD9, 0x84, 0xD8, 0xA7, 0xD9, 0x84,
+		0xD9, 0x87, 0xD8, 0xB1, 0xDB, 0x8C, 0xD8, 0xA7,
+		0xD9, 0x84, 0x2E, 0x2E, 0xE2, 0x80, 0x94, 0xE2,
+		0x80, 0x93, 0x5F, 0x5F, 0x28, 0x29, 0x7B, 0x7D,
+		0xE3, 0x80, 0x94, 0xE3, 0x80, 0x95, 0xE3, 0x80,
+		0x90, 0xE3, 0x80, 0x91, 0xE3, 0x80, 0x8A, 0xE3,
+		0x80, 0x8B, 0xE3, 0x80, 0x88, 0xE3, 0x80, 0x89,
+		0xE3, 0x80, 0x8C, 0xE3, 0x80, 0x8D, 0xE3, 0x80,
+		0x8E, 0xE3, 0x80, 0x8F, 0x20, 0xCC, 0x85, 0x20,
+		0xCC, 0x85, 0x20, 0xCC, 0x85, 0x20, 0xCC, 0x85,
+		0x5F, 0x5F, 0x5F, 0x2C, 0xE3, 0x80, 0x81, 0x2E,
+		0x3B, 0x3A, 0x3F, 0x21, 0xE2, 0x80, 0x94, 0x28,
+		0x29, 0x7B, 0x7D, 0xE3, 0x80, 0x94, 0xE3, 0x80,
+		0x95, 0x23, 0x26, 0x2A, 0x2B, 0x2D, 0x3C, 0x3E,
+		0x3D, 0x5C, 0x24, 0x25, 0x40, 0x20, 0xD9, 0x8B,
+		0xD9, 0x80, 0xD9, 0x8B, 0x20, 0xD9, 0x8C, 0x20,
+		0xD9, 0x8D, 0x20, 0xD9, 0x8E, 0xD9, 0x80, 0xD9,
+		0x8E, 0x20, 0xD9, 0x8F, 0xD9, 0x80, 0xD9, 0x8F,
+		0x20, 0xD9, 0x90, 0xD9, 0x80, 0xD9, 0x90, 0x20,
+		0xD9, 0x91, 0xD9, 0x80, 0xD9, 0x91, 0x20, 0xD9,
+		0x92, 0xD9, 0x80, 0xD9, 0x92, 0xD8, 0xA1, 0xD8,
+		0xA7, 0xD9, 0x93, 0xD8, 0xA7, 0xD9, 0x93, 0xD8,
+		0xA7, 0xD9, 0x94, 0xD8, 0xA7, 0xD9, 0x94, 0xD9,
+		0x88, 0xD9, 0x94, 0xD9, 0x88, 0xD9, 0x94, 0xD8,
+		0xA7, 0xD9, 0x95, 0xD8, 0xA7, 0xD9, 0x95, 0xD9,
+		0x8A, 0xD9, 0x94, 0xD9, 0x8A, 0xD9, 0x94, 0xD9,
+		0x8A, 0xD9, 0x94, 0xD9, 0x8A, 0xD9, 0x94, 0xD8,
+		0xA7, 0xD8, 0xA7, 0xD8, 0xA8, 0xD8, 0xA8, 0xD8,
+		0xA8, 0xD8, 0xA8, 0xD8, 0xA9, 0xD8, 0xA9, 0xD8,
+		0xAA, 0xD8, 0xAA, 0xD8, 0xAA, 0xD8, 0xAA, 0xD8,
+		0xAB, 0xD8, 0xAB, 0xD8, 0xAB, 0xD8, 0xAB, 0xD8,
+		0xAC, 0xD8, 0xAC, 0xD8, 0xAC, 0xD8, 0xAC, 0xD8,
+		0xAD, 0xD8, 0xAD, 0xD8, 0xAD, 0xD8, 0xAD, 0xD8,
+		0xAE, 0xD8, 0xAE, 0xD8, 0xAE, 0xD8, 0xAE, 0xD8,
+		0xAF, 0xD8, 0xAF, 0xD8, 0xB0, 0xD8, 0xB0, 0xD8,
+		0xB1, 0xD8, 0xB1, 0xD8, 0xB2, 0xD8, 0xB2, 0xD8,
+		0xB3, 0xD8, 0xB3, 0xD8, 0xB3, 0xD8, 0xB3, 0xD8,
+		0xB4, 0xD8, 0xB4, 0xD8, 0xB4, 0xD8, 0xB4, 0xD8,
+		0xB5, 0xD8, 0xB5, 0xD8, 0xB5, 0xD8, 0xB5, 0xD8,
+		0xB6, 0xD8, 0xB6, 0xD8, 0xB6, 0xD8, 0xB6, 0xD8,
+		0xB7, 0xD8, 0xB7, 0xD8, 0xB7, 0xD8, 0xB7, 0xD8,
+		0xB8, 0xD8, 0xB8, 0xD8, 0xB8, 0xD8, 0xB8, 0xD8,
+		0xB9, 0xD8, 0xB9, 0xD8, 0xB9, 0xD8, 0xB9, 0xD8,
+		0xBA, 0xD8, 0xBA, 0xD8, 0xBA, 0xD8, 0xBA, 0xD9,
+		0x81, 0xD9, 0x81, 0xD9, 0x81, 0xD9, 0x81, 0xD9,
+		0x82, 0xD9, 0x82, 0xD9, 0x82, 0xD9, 0x82, 0xD9,
+		0x83, 0xD9, 0x83, 0xD9, 0x83, 0xD9, 0x83, 0xD9,
+		0x84, 0xD9, 0x84, 0xD9, 0x84, 0xD9, 0x84, 0xD9,
+		0x85, 0xD9, 0x85, 0xD9, 0x85, 0xD9, 0x85, 0xD9,
+		0x86, 0xD9, 0x86, 0xD9, 0x86, 0xD9, 0x86, 0xD9,
+		0x87, 0xD9, 0x87, 0xD9, 0x87, 0xD9, 0x87, 0xD9,
+		0x88, 0xD9, 0x88, 0xD9, 0x89, 0xD9, 0x89, 0xD9,
+		0x8A, 0xD9, 0x8A, 0xD9, 0x8A, 0xD9, 0x8A, 0xD9,
+		0x84, 0xD8, 0xA7, 0xD9, 0x93, 0xD9, 0x84, 0xD8,
+		0xA7, 0xD9, 0x93, 0xD9, 0x84, 0xD8, 0xA7, 0xD9,
+		0x94, 0xD9, 0x84, 0xD8, 0xA7, 0xD9, 0x94, 0xD9,
+		0x84, 0xD8, 0xA7, 0xD9, 0x95, 0xD9, 0x84, 0xD8,
+		0xA7, 0xD9, 0x95, 0xD9, 0x84, 0xD8, 0xA7, 0xD9,
+		0x84, 0xD8, 0xA7, 0x21, 0x22, 0x23, 0x24, 0x25,
+		0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D,
+		0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
+		0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D,
+		0x3E, 0x3F, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45,
+		0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D,
+		0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55,
+		0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D,
+		0x5E, 0x5F, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65,
+		0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D,
+		0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75,
+		0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D,
+		0x7E, 0xE2, 0xA6, 0x85, 0xE2, 0xA6, 0x86, 0xE3,
+		0x80, 0x82, 0xE3, 0x80, 0x8C, 0xE3, 0x80, 0x8D,
+		0xE3, 0x80, 0x81, 0xE3, 0x83, 0xBB, 0xE3, 0x83,
+		0xB2, 0xE3, 0x82, 0xA1, 0xE3, 0x82, 0xA3, 0xE3,
+		0x82, 0xA5, 0xE3, 0x82, 0xA7, 0xE3, 0x82, 0xA9,
+		0xE3, 0x83, 0xA3, 0xE3, 0x83, 0xA5, 0xE3, 0x83,
+		0xA7, 0xE3, 0x83, 0x83, 0xE3, 0x83, 0xBC, 0xE3,
+		0x82, 0xA2, 0xE3, 0x82, 0xA4, 0xE3, 0x82, 0xA6,
+		0xE3, 0x82, 0xA8, 0xE3, 0x82, 0xAA, 0xE3, 0x82,
+		0xAB, 0xE3, 0x82, 0xAD, 0xE3, 0x82, 0xAF, 0xE3,
+		0x82, 0xB1, 0xE3, 0x82, 0xB3, 0xE3, 0x82, 0xB5,
+		0xE3, 0x82, 0xB7, 0xE3, 0x82, 0xB9, 0xE3, 0x82,
+		0xBB, 0xE3, 0x82, 0xBD, 0xE3, 0x82, 0xBF, 0xE3,
+		0x83, 0x81, 0xE3, 0x83, 0x84, 0xE3, 0x83, 0x86,
+		0xE3, 0x83, 0x88, 0xE3, 0x83, 0x8A, 0xE3, 0x83,
+		0x8B, 0xE3, 0x83, 0x8C, 0xE3, 0x83, 0x8D, 0xE3,
+		0x83, 0x8E, 0xE3, 0x83, 0x8F, 0xE3, 0x83, 0x92,
+		0xE3, 0x83, 0x95, 0xE3, 0x83, 0x98, 0xE3, 0x83,
+		0x9B, 0xE3, 0x83, 0x9E, 0xE3, 0x83, 0x9F, 0xE3,
+		0x83, 0xA0, 0xE3, 0x83, 0xA1, 0xE3, 0x83, 0xA2,
+		0xE3, 0x83, 0xA4, 0xE3, 0x83, 0xA6, 0xE3, 0x83,
+		0xA8, 0xE3, 0x83, 0xA9, 0xE3, 0x83, 0xAA, 0xE3,
+		0x83, 0xAB, 0xE3, 0x83, 0xAC, 0xE3, 0x83, 0xAD,
+		0xE3, 0x83, 0xAF, 0xE3, 0x83, 0xB3, 0xE3, 0x82,
+		0x99, 0xE3, 0x82, 0x9A, 0xE1, 0x85, 0xA0, 0xE1,
+		0x84, 0x80, 0xE1, 0x84, 0x81, 0xE1, 0x86, 0xAA,
+		0xE1, 0x84, 0x82, 0xE1, 0x86, 0xAC, 0xE1, 0x86,
+		0xAD, 0xE1, 0x84, 0x83, 0xE1, 0x84, 0x84, 0xE1,
+		0x84, 0x85, 0xE1, 0x86, 0xB0, 0xE1, 0x86, 0xB1,
+		0xE1, 0x86, 0xB2, 0xE1, 0x86, 0xB3, 0xE1, 0x86,
+		0xB4, 0xE1, 0x86, 0xB5, 0xE1, 0x84, 0x9A, 0xE1,
+		0x84, 0x86, 0xE1, 0x84, 0x87, 0xE1, 0x84, 0x88,
+		0xE1, 0x84, 0xA1, 0xE1, 0x84, 0x89, 0xE1, 0x84,
+		0x8A, 0xE1, 0x84, 0x8B, 0xE1, 0x84, 0x8C, 0xE1,
+		0x84, 0x8D, 0xE1, 0x84, 0x8E, 0xE1, 0x84, 0x8F,
+		0xE1, 0x84, 0x90, 0xE1, 0x84, 0x91, 0xE1, 0x84,
+		0x92, 0xE1, 0x85, 0xA1, 0xE1, 0x85, 0xA2, 0xE1,
+		0x85, 0xA3, 0xE1, 0x85, 0xA4, 0xE1, 0x85, 0xA5,
+		0xE1, 0x85, 0xA6, 0xE1, 0x85, 0xA7, 0xE1, 0x85,
+		0xA8, 0xE1, 0x85, 0xA9, 0xE1, 0x85, 0xAA, 0xE1,
+		0x85, 0xAB, 0xE1, 0x85, 0xAC, 0xE1, 0x85, 0xAD,
+		0xE1, 0x85, 0xAE, 0xE1, 0x85, 0xAF, 0xE1, 0x85,
+		0xB0, 0xE1, 0x85, 0xB1, 0xE1, 0x85, 0xB2, 0xE1,
+		0x85, 0xB3, 0xE1, 0x85, 0xB4, 0xE1, 0x85, 0xB5,
+		0xC2, 0xA2, 0xC2, 0xA3, 0xC2, 0xAC, 0x20, 0xCC,
+		0x84, 0xC2, 0xA6, 0xC2, 0xA5, 0xE2, 0x82, 0xA9,
+		0xE2, 0x94, 0x82, 0xE2, 0x86, 0x90, 0xE2, 0x86,
+		0x91, 0xE2, 0x86, 0x92, 0xE2, 0x86, 0x93, 0xE2,
+		0x96, 0xA0, 0xE2, 0x97, 0x8B, 0xF6, 0xF0, 0x9D,
+		0x85, 0x97, 0xF0, 0x9D, 0x85, 0xA5, 0xF6, 0xF0,
+		0x9D, 0x85, 0x98, 0xF0, 0x9D, 0x85, 0xA5, 0xF6,
+		0xF0, 0x9D, 0x85, 0x98, 0xF0, 0x9D, 0x85, 0xA5,
+		0xF0, 0x9D, 0x85, 0xAE, 0xF6, 0xF0, 0x9D, 0x85,
+		0x98, 0xF0, 0x9D, 0x85, 0xA5, 0xF0, 0x9D, 0x85,
+		0xAF, 0xF6, 0xF0, 0x9D, 0x85, 0x98, 0xF0, 0x9D,
+		0x85, 0xA5, 0xF0, 0x9D, 0x85, 0xB0, 0xF6, 0xF0,
+		0x9D, 0x85, 0x98, 0xF0, 0x9D, 0x85, 0xA5, 0xF0,
+		0x9D, 0x85, 0xB1, 0xF6, 0xF0, 0x9D, 0x85, 0x98,
+		0xF0, 0x9D, 0x85, 0xA5, 0xF0, 0x9D, 0x85, 0xB2,
+		0xF6, 0xF0, 0x9D, 0x86, 0xB9, 0xF0, 0x9D, 0x85,
+		0xA5, 0xF6, 0xF0, 0x9D, 0x86, 0xBA, 0xF0, 0x9D,
+		0x85, 0xA5, 0xF6, 0xF0, 0x9D, 0x86, 0xB9, 0xF0,
+		0x9D, 0x85, 0xA5, 0xF0, 0x9D, 0x85, 0xAE, 0xF6,
+		0xF0, 0x9D, 0x86, 0xBA, 0xF0, 0x9D, 0x85, 0xA5,
+		0xF0, 0x9D, 0x85, 0xAE, 0xF6, 0xF0, 0x9D, 0x86,
+		0xB9, 0xF0, 0x9D, 0x85, 0xA5, 0xF0, 0x9D, 0x85,
+		0xAF, 0xF6, 0xF0, 0x9D, 0x86, 0xBA, 0xF0, 0x9D,
+		0x85, 0xA5, 0xF0, 0x9D, 0x85, 0xAF, 0x41, 0x42,
+		0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A,
+		0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52,
+		0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A,
+		0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
+		0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70,
+		0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
+		0x79, 0x7A, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46,
+		0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E,
+		0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56,
+		0x57, 0x58, 0x59, 0x5A, 0x61, 0x62, 0x63, 0x64,
+		0x65, 0x66, 0x67, 0x69, 0x6A, 0x6B, 0x6C, 0x6D,
+		0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75,
+		0x76, 0x77, 0x78, 0x79, 0x7A, 0x41, 0x42, 0x43,
+		0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B,
+		0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53,
+		0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x61,
+		0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
+		0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71,
+		0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
+		0x7A, 0x41, 0x43, 0x44, 0x47, 0x4A, 0x4B, 0x4E,
+		0x4F, 0x50, 0x51, 0x53, 0x54, 0x55, 0x56, 0x57,
+		0x58, 0x59, 0x5A, 0x61, 0x62, 0x63, 0x64, 0x66,
+		0x68, 0x69, 0x6A, 0x6B, 0x6D, 0x6E, 0x70, 0x71,
+		0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
+		0x7A, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
+		0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
+		0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
+		0x58, 0x59, 0x5A, 0x61, 0x62, 0x63, 0x64, 0x65,
+		0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D,
+		0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75,
+		0x76, 0x77, 0x78, 0x79, 0x7A, 0x41, 0x42, 0x44,
+		0x45, 0x46, 0x47, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E,
+		0x4F, 0x50, 0x51, 0x53, 0x54, 0x55, 0x56, 0x57,
+		0x58, 0x59, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66,
+		0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E,
+		0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76,
+		0x77, 0x78, 0x79, 0x7A, 0x41, 0x42, 0x44, 0x45,
+		0x46, 0x47, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4F,
+		0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x61,
+		0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
+		0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71,
+		0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
+		0x7A, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
+		0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
+		0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
+		0x58, 0x59, 0x5A, 0x61, 0x62, 0x63, 0x64, 0x65,
+		0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D,
+		0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75,
+		0x76, 0x77, 0x78, 0x79, 0x7A, 0x41, 0x42, 0x43,
+		0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B,
+		0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53,
+		0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x61,
+		0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
+		0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71,
+		0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
+		0x7A, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
+		0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
+		0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
+		0x58, 0x59, 0x5A, 0x61, 0x62, 0x63, 0x64, 0x65,
+		0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D,
+		0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75,
+		0x76, 0x77, 0x78, 0x79, 0x7A, 0x41, 0x42, 0x43,
+		0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B,
+		0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53,
+		0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x61,
+		0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
+		0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71,
+		0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
+		0x7A, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
+		0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
+		0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
+		0x58, 0x59, 0x5A, 0x61, 0x62, 0x63, 0x64, 0x65,
+		0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D,
+		0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75,
+		0x76, 0x77, 0x78, 0x79, 0x7A, 0x41, 0x42, 0x43,
+		0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B,
+		0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53,
+		0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x61,
+		0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
+		0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71,
+		0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
+		0x7A, 0xCE, 0x91, 0xCE, 0x92, 0xCE, 0x93, 0xCE,
+		0x94, 0xCE, 0x95, 0xCE, 0x96, 0xCE, 0x97, 0xCE,
+		0x98, 0xCE, 0x99, 0xCE, 0x9A, 0xCE, 0x9B, 0xCE,
+		0x9C, 0xCE, 0x9D, 0xCE, 0x9E, 0xCE, 0x9F, 0xCE,
+		0xA0, 0xCE, 0xA1, 0xCE, 0x98, 0xCE, 0xA3, 0xCE,
+		0xA4, 0xCE, 0xA5, 0xCE, 0xA6, 0xCE, 0xA7, 0xCE,
+		0xA8, 0xCE, 0xA9, 0xE2, 0x88, 0x87, 0xCE, 0xB1,
+		0xCE, 0xB2, 0xCE, 0xB3, 0xCE, 0xB4, 0xCE, 0xB5,
+		0xCE, 0xB6, 0xCE, 0xB7, 0xCE, 0xB8, 0xCE, 0xB9,
+		0xCE, 0xBA, 0xCE, 0xBB, 0xCE, 0xBC, 0xCE, 0xBD,
+		0xCE, 0xBE, 0xCE, 0xBF, 0xCF, 0x80, 0xCF, 0x81,
+		0xCF, 0x82, 0xCF, 0x83, 0xCF, 0x84, 0xCF, 0x85,
+		0xCF, 0x86, 0xCF, 0x87, 0xCF, 0x88, 0xCF, 0x89,
+		0xE2, 0x88, 0x82, 0xCE, 0xB5, 0xCE, 0xB8, 0xCE,
+		0xBA, 0xCF, 0x86, 0xCF, 0x81, 0xCF, 0x80, 0xCE,
+		0x91, 0xCE, 0x92, 0xCE, 0x93, 0xCE, 0x94, 0xCE,
+		0x95, 0xCE, 0x96, 0xCE, 0x97, 0xCE, 0x98, 0xCE,
+		0x99, 0xCE, 0x9A, 0xCE, 0x9B, 0xCE, 0x9C, 0xCE,
+		0x9D, 0xCE, 0x9E, 0xCE, 0x9F, 0xCE, 0xA0, 0xCE,
+		0xA1, 0xCE, 0x98, 0xCE, 0xA3, 0xCE, 0xA4, 0xCE,
+		0xA5, 0xCE, 0xA6, 0xCE, 0xA7, 0xCE, 0xA8, 0xCE,
+		0xA9, 0xE2, 0x88, 0x87, 0xCE, 0xB1, 0xCE, 0xB2,
+		0xCE, 0xB3, 0xCE, 0xB4, 0xCE, 0xB5, 0xCE, 0xB6,
+		0xCE, 0xB7, 0xCE, 0xB8, 0xCE, 0xB9, 0xCE, 0xBA,
+		0xCE, 0xBB, 0xCE, 0xBC, 0xCE, 0xBD, 0xCE, 0xBE,
+		0xCE, 0xBF, 0xCF, 0x80, 0xCF, 0x81, 0xCF, 0x82,
+		0xCF, 0x83, 0xCF, 0x84, 0xCF, 0x85, 0xCF, 0x86,
+		0xCF, 0x87, 0xCF, 0x88, 0xCF, 0x89, 0xE2, 0x88,
+		0x82, 0xCE, 0xB5, 0xCE, 0xB8, 0xCE, 0xBA, 0xCF,
+		0x86, 0xCF, 0x81, 0xCF, 0x80, 0xCE, 0x91, 0xCE,
+		0x92, 0xCE, 0x93, 0xCE, 0x94, 0xCE, 0x95, 0xCE,
+		0x96, 0xCE, 0x97, 0xCE, 0x98, 0xCE, 0x99, 0xCE,
+		0x9A, 0xCE, 0x9B, 0xCE, 0x9C, 0xCE, 0x9D, 0xCE,
+		0x9E, 0xCE, 0x9F, 0xCE, 0xA0, 0xCE, 0xA1, 0xCE,
+		0x98, 0xCE, 0xA3, 0xCE, 0xA4, 0xCE, 0xA5, 0xCE,
+		0xA6, 0xCE, 0xA7, 0xCE, 0xA8, 0xCE, 0xA9, 0xE2,
+		0x88, 0x87, 0xCE, 0xB1, 0xCE, 0xB2, 0xCE, 0xB3,
+		0xCE, 0xB4, 0xCE, 0xB5, 0xCE, 0xB6, 0xCE, 0xB7,
+		0xCE, 0xB8, 0xCE, 0xB9, 0xCE, 0xBA, 0xCE, 0xBB,
+		0xCE, 0xBC, 0xCE, 0xBD, 0xCE, 0xBE, 0xCE, 0xBF,
+		0xCF, 0x80, 0xCF, 0x81, 0xCF, 0x82, 0xCF, 0x83,
+		0xCF, 0x84, 0xCF, 0x85, 0xCF, 0x86, 0xCF, 0x87,
+		0xCF, 0x88, 0xCF, 0x89, 0xE2, 0x88, 0x82, 0xCE,
+		0xB5, 0xCE, 0xB8, 0xCE, 0xBA, 0xCF, 0x86, 0xCF,
+		0x81, 0xCF, 0x80, 0xCE, 0x91, 0xCE, 0x92, 0xCE,
+		0x93, 0xCE, 0x94, 0xCE, 0x95, 0xCE, 0x96, 0xCE,
+		0x97, 0xCE, 0x98, 0xCE, 0x99, 0xCE, 0x9A, 0xCE,
+		0x9B, 0xCE, 0x9C, 0xCE, 0x9D, 0xCE, 0x9E, 0xCE,
+		0x9F, 0xCE, 0xA0, 0xCE, 0xA1, 0xCE, 0x98, 0xCE,
+		0xA3, 0xCE, 0xA4, 0xCE, 0xA5, 0xCE, 0xA6, 0xCE,
+		0xA7, 0xCE, 0xA8, 0xCE, 0xA9, 0xE2, 0x88, 0x87,
+		0xCE, 0xB1, 0xCE, 0xB2, 0xCE, 0xB3, 0xCE, 0xB4,
+		0xCE, 0xB5, 0xCE, 0xB6, 0xCE, 0xB7, 0xCE, 0xB8,
+		0xCE, 0xB9, 0xCE, 0xBA, 0xCE, 0xBB, 0xCE, 0xBC,
+		0xCE, 0xBD, 0xCE, 0xBE, 0xCE, 0xBF, 0xCF, 0x80,
+		0xCF, 0x81, 0xCF, 0x82, 0xCF, 0x83, 0xCF, 0x84,
+		0xCF, 0x85, 0xCF, 0x86, 0xCF, 0x87, 0xCF, 0x88,
+		0xCF, 0x89, 0xE2, 0x88, 0x82, 0xCE, 0xB5, 0xCE,
+		0xB8, 0xCE, 0xBA, 0xCF, 0x86, 0xCF, 0x81, 0xCF,
+		0x80, 0xCE, 0x91, 0xCE, 0x92, 0xCE, 0x93, 0xCE,
+		0x94, 0xCE, 0x95, 0xCE, 0x96, 0xCE, 0x97, 0xCE,
+		0x98, 0xCE, 0x99, 0xCE, 0x9A, 0xCE, 0x9B, 0xCE,
+		0x9C, 0xCE, 0x9D, 0xCE, 0x9E, 0xCE, 0x9F, 0xCE,
+		0xA0, 0xCE, 0xA1, 0xCE, 0x98, 0xCE, 0xA3, 0xCE,
+		0xA4, 0xCE, 0xA5, 0xCE, 0xA6, 0xCE, 0xA7, 0xCE,
+		0xA8, 0xCE, 0xA9, 0xE2, 0x88, 0x87, 0xCE, 0xB1,
+		0xCE, 0xB2, 0xCE, 0xB3, 0xCE, 0xB4, 0xCE, 0xB5,
+		0xCE, 0xB6, 0xCE, 0xB7, 0xCE, 0xB8, 0xCE, 0xB9,
+		0xCE, 0xBA, 0xCE, 0xBB, 0xCE, 0xBC, 0xCE, 0xBD,
+		0xCE, 0xBE, 0xCE, 0xBF, 0xCF, 0x80, 0xCF, 0x81,
+		0xCF, 0x82, 0xCF, 0x83, 0xCF, 0x84, 0xCF, 0x85,
+		0xCF, 0x86, 0xCF, 0x87, 0xCF, 0x88, 0xCF, 0x89,
+		0xE2, 0x88, 0x82, 0xCE, 0xB5, 0xCE, 0xB8, 0xCE,
+		0xBA, 0xCF, 0x86, 0xCF, 0x81, 0xCF, 0x80, 0x30,
+		0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
+		0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36,
+		0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34,
+		0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32,
+		0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30,
+		0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
+		0x39, 0xF6, 0xE4, 0xB8, 0xBD, 0xF6, 0xE4, 0xB8,
+		0xB8, 0xF6, 0xE4, 0xB9, 0x81, 0xF6, 0xF0, 0xA0,
+		0x84, 0xA2, 0xF6, 0xE4, 0xBD, 0xA0, 0xF6, 0xE4,
+		0xBE, 0xAE, 0xF6, 0xE4, 0xBE, 0xBB, 0xF6, 0xE5,
+		0x80, 0x82, 0xF6, 0xE5, 0x81, 0xBA, 0xF6, 0xE5,
+		0x82, 0x99, 0xF6, 0xE5, 0x83, 0xA7, 0xF6, 0xE5,
+		0x83, 0x8F, 0xF6, 0xE3, 0x92, 0x9E, 0xF6, 0xF0,
+		0xA0, 0x98, 0xBA, 0xF6, 0xE5, 0x85, 0x8D, 0xF6,
+		0xE5, 0x85, 0x94, 0xF6, 0xE5, 0x85, 0xA4, 0xF6,
+		0xE5, 0x85, 0xB7, 0xF6, 0xF0, 0xA0, 0x94, 0x9C,
+		0xF6, 0xE3, 0x92, 0xB9, 0xF6, 0xE5, 0x85, 0xA7,
+		0xF6, 0xE5, 0x86, 0x8D, 0xF6, 0xF0, 0xA0, 0x95,
+		0x8B, 0xF6, 0xE5, 0x86, 0x97, 0xF6, 0xE5, 0x86,
+		0xA4, 0xF6, 0xE4, 0xBB, 0x8C, 0xF6, 0xE5, 0x86,
+		0xAC, 0xF6, 0xE5, 0x86, 0xB5, 0xF6, 0xF0, 0xA9,
+		0x87, 0x9F, 0xF6, 0xE5, 0x87, 0xB5, 0xF6, 0xE5,
+		0x88, 0x83, 0xF6, 0xE3, 0x93, 0x9F, 0xF6, 0xE5,
+		0x88, 0xBB, 0xF6, 0xE5, 0x89, 0x86, 0xF6, 0xE5,
+		0x89, 0xB2, 0xF6, 0xE5, 0x89, 0xB7, 0xF6, 0xE3,
+		0x94, 0x95, 0xF6, 0xE5, 0x8B, 0x87, 0xF6, 0xE5,
+		0x8B, 0x89, 0xF6, 0xE5, 0x8B, 0xA4, 0xF6, 0xE5,
+		0x8B, 0xBA, 0xF6, 0xE5, 0x8C, 0x85, 0xF6, 0xE5,
+		0x8C, 0x86, 0xF6, 0xE5, 0x8C, 0x97, 0xF6, 0xE5,
+		0x8D, 0x89, 0xF6, 0xE5, 0x8D, 0x91, 0xF6, 0xE5,
+		0x8D, 0x9A, 0xF6, 0xE5, 0x8D, 0xB3, 0xF6, 0xE5,
+		0x8D, 0xBD, 0xF6, 0xE5, 0x8D, 0xBF, 0xF6, 0xE5,
+		0x8D, 0xBF, 0xF6, 0xE5, 0x8D, 0xBF, 0xF6, 0xF0,
+		0xA0, 0xA8, 0xAC, 0xF6, 0xE7, 0x81, 0xB0, 0xF6,
+		0xE5, 0x8F, 0x8A, 0xF6, 0xE5, 0x8F, 0x9F, 0xF6,
+		0xF0, 0xA0, 0xAD, 0xA3, 0xF6, 0xE5, 0x8F, 0xAB,
+		0xF6, 0xE5, 0x8F, 0xB1, 0xF6, 0xE5, 0x90, 0x86,
+		0xF6, 0xE5, 0x92, 0x9E, 0xF6, 0xE5, 0x90, 0xB8,
+		0xF6, 0xE5, 0x91, 0x88, 0xF6, 0xE5, 0x91, 0xA8,
+		0xF6, 0xE5, 0x92, 0xA2, 0xF6, 0xE5, 0x93, 0xB6,
+		0xF6, 0xE5, 0x94, 0x90, 0xF6, 0xE5, 0x95, 0x93,
+		0xF6, 0xE5, 0x95, 0xA3, 0xF6, 0xE5, 0x96, 0x84,
+		0xF6, 0xE5, 0x96, 0x84, 0xF6, 0xE5, 0x96, 0x99,
+		0xF6, 0xE5, 0x96, 0xAB, 0xF6, 0xE5, 0x96, 0xB3,
+		0xF6, 0xE5, 0x97, 0x82, 0xF6, 0xE5, 0x9C, 0x96,
+		0xF6, 0xE5, 0x98, 0x86, 0xF6, 0xE5, 0x9C, 0x97,
+		0xF6, 0xE5, 0x99, 0x91, 0xF6, 0xE5, 0x99, 0xB4,
+		0xF6, 0xE5, 0x88, 0x87, 0xF6, 0xE5, 0xA3, 0xAE,
+		0xF6, 0xE5, 0x9F, 0x8E, 0xF6, 0xE5, 0x9F, 0xB4,
+		0xF6, 0xE5, 0xA0, 0x8D, 0xF6, 0xE5, 0x9E, 0x8B,
+		0xF6, 0xE5, 0xA0, 0xB2, 0xF6, 0xE5, 0xA0, 0xB1,
+		0xF6, 0xE5, 0xA2, 0xAC, 0xF6, 0xF0, 0xA1, 0x93,
+		0xA4, 0xF6, 0xE5, 0xA3, 0xB2, 0xF6, 0xE5, 0xA3,
+		0xB7, 0xF6, 0xE5, 0xA4, 0x86, 0xF6, 0xE5, 0xA4,
+		0x9A, 0xF6, 0xE5, 0xA4, 0xA2, 0xF6, 0xE5, 0xA5,
+		0xA2, 0xF6, 0xF0, 0xA1, 0x9A, 0xA8, 0xF6, 0xF0,
+		0xA1, 0x9B, 0xAA, 0xF6, 0xE5, 0xA7, 0xAC, 0xF6,
+		0xE5, 0xA8, 0x9B, 0xF6, 0xE5, 0xA8, 0xA7, 0xF6,
+		0xE5, 0xA7, 0x98, 0xF6, 0xE5, 0xA9, 0xA6, 0xF6,
+		0xE3, 0x9B, 0xAE, 0xF6, 0xE3, 0x9B, 0xBC, 0xF6,
+		0xE5, 0xAC, 0x88, 0xF6, 0xE5, 0xAC, 0xBE, 0xF6,
+		0xE5, 0xAC, 0xBE, 0xF6, 0xF0, 0xA1, 0xA7, 0x88,
+		0xF6, 0xE5, 0xAF, 0x83, 0xF6, 0xE5, 0xAF, 0x98,
+		0xF6, 0xE5, 0xAF, 0xA7, 0xF6, 0xE5, 0xAF, 0xB3,
+		0xF6, 0xF0, 0xA1, 0xAC, 0x98, 0xF6, 0xE5, 0xAF,
+		0xBF, 0xF6, 0xE5, 0xB0, 0x86, 0xF6, 0xE5, 0xBD,
+		0x93, 0xF6, 0xE5, 0xB0, 0xA2, 0xF6, 0xE3, 0x9E,
+		0x81, 0xF6, 0xE5, 0xB1, 0xA0, 0xF6, 0xE5, 0xB1,
+		0xAE, 0xF6, 0xE5, 0xB3, 0x80, 0xF6, 0xE5, 0xB2,
+		0x8D, 0xF6, 0xF0, 0xA1, 0xB7, 0xA4, 0xF6, 0xE5,
+		0xB5, 0x83, 0xF6, 0xF0, 0xA1, 0xB7, 0xA6, 0xF6,
+		0xE5, 0xB5, 0xAE, 0xF6, 0xE5, 0xB5, 0xAB, 0xF6,
+		0xE5, 0xB5, 0xBC, 0xF6, 0xE5, 0xB7, 0xA1, 0xF6,
+		0xE5, 0xB7, 0xA2, 0xF6, 0xE3, 0xA0, 0xAF, 0xF6,
+		0xE5, 0xB7, 0xBD, 0xF6, 0xE5, 0xB8, 0xA8, 0xF6,
+		0xE5, 0xB8, 0xBD, 0xF6, 0xE5, 0xB9, 0xA9, 0xF6,
+		0xE3, 0xA1, 0xA2, 0xF6, 0xF0, 0xA2, 0x86, 0x83,
+		0xF6, 0xE3, 0xA1, 0xBC, 0xF6, 0xE5, 0xBA, 0xB0,
+		0xF6, 0xE5, 0xBA, 0xB3, 0xF6, 0xE5, 0xBA, 0xB6,
+		0xF6, 0xE5, 0xBB, 0x8A, 0xF6, 0xF0, 0xAA, 0x8E,
+		0x92, 0xF6, 0xE5, 0xBB, 0xBE, 0xF6, 0xF0, 0xA2,
+		0x8C, 0xB1, 0xF6, 0xF0, 0xA2, 0x8C, 0xB1, 0xF6,
+		0xE8, 0x88, 0x81, 0xF6, 0xE5, 0xBC, 0xA2, 0xF6,
+		0xE5, 0xBC, 0xA2, 0xF6, 0xE3, 0xA3, 0x87, 0xF6,
+		0xF0, 0xA3, 0x8A, 0xB8, 0xF6, 0xF0, 0xA6, 0x87,
+		0x9A, 0xF6, 0xE5, 0xBD, 0xA2, 0xF6, 0xE5, 0xBD,
+		0xAB, 0xF6, 0xE3, 0xA3, 0xA3, 0xF6, 0xE5, 0xBE,
+		0x9A, 0xF6, 0xE5, 0xBF, 0x8D, 0xF6, 0xE5, 0xBF,
+		0x97, 0xF6, 0xE5, 0xBF, 0xB9, 0xF6, 0xE6, 0x82,
+		0x81, 0xF6, 0xE3, 0xA4, 0xBA, 0xF6, 0xE3, 0xA4,
+		0x9C, 0xF6, 0xE6, 0x82, 0x94, 0xF6, 0xF0, 0xA2,
+		0x9B, 0x94, 0xF6, 0xE6, 0x83, 0x87, 0xF6, 0xE6,
+		0x85, 0x88, 0xF6, 0xE6, 0x85, 0x8C, 0xF6, 0xE6,
+		0x85, 0x8E, 0xF6, 0xE6, 0x85, 0x8C, 0xF6, 0xE6,
+		0x85, 0xBA, 0xF6, 0xE6, 0x86, 0x8E, 0xF6, 0xE6,
+		0x86, 0xB2, 0xF6, 0xE6, 0x86, 0xA4, 0xF6, 0xE6,
+		0x86, 0xAF, 0xF6, 0xE6, 0x87, 0x9E, 0xF6, 0xE6,
+		0x87, 0xB2, 0xF6, 0xE6, 0x87, 0xB6, 0xF6, 0xE6,
+		0x88, 0x90, 0xF6, 0xE6, 0x88, 0x9B, 0xF6, 0xE6,
+		0x89, 0x9D, 0xF6, 0xE6, 0x8A, 0xB1, 0xF6, 0xE6,
+		0x8B, 0x94, 0xF6, 0xE6, 0x8D, 0x90, 0xF6, 0xF0,
+		0xA2, 0xAC, 0x8C, 0xF6, 0xE6, 0x8C, 0xBD, 0xF6,
+		0xE6, 0x8B, 0xBC, 0xF6, 0xE6, 0x8D, 0xA8, 0xF6,
+		0xE6, 0x8E, 0x83, 0xF6, 0xE6, 0x8F, 0xA4, 0xF6,
+		0xF0, 0xA2, 0xAF, 0xB1, 0xF6, 0xE6, 0x90, 0xA2,
+		0xF6, 0xE6, 0x8F, 0x85, 0xF6, 0xE6, 0x8E, 0xA9,
+		0xF6, 0xE3, 0xA8, 0xAE, 0xF6, 0xE6, 0x91, 0xA9,
+		0xF6, 0xE6, 0x91, 0xBE, 0xF6, 0xE6, 0x92, 0x9D,
+		0xF6, 0xE6, 0x91, 0xB7, 0xF6, 0xE3, 0xA9, 0xAC,
+		0xF6, 0xE6, 0x95, 0x8F, 0xF6, 0xE6, 0x95, 0xAC,
+		0xF6, 0xF0, 0xA3, 0x80, 0x8A, 0xF6, 0xE6, 0x97,
+		0xA3, 0xF6, 0xE6, 0x9B, 0xB8, 0xF6, 0xE6, 0x99,
+		0x89, 0xF6, 0xE3, 0xAC, 0x99, 0xF6, 0xE6, 0x9A,
+		0x91, 0xF6, 0xE3, 0xAC, 0x88, 0xF6, 0xE3, 0xAB,
+		0xA4, 0xF6, 0xE5, 0x86, 0x92, 0xF6, 0xE5, 0x86,
+		0x95, 0xF6, 0xE6, 0x9C, 0x80, 0xF6, 0xE6, 0x9A,
+		0x9C, 0xF6, 0xE8, 0x82, 0xAD, 0xF6, 0xE4, 0x8F,
+		0x99, 0xF6, 0xE6, 0x9C, 0x97, 0xF6, 0xE6, 0x9C,
+		0x9B, 0xF6, 0xE6, 0x9C, 0xA1, 0xF6, 0xE6, 0x9D,
+		0x9E, 0xF6, 0xE6, 0x9D, 0x93, 0xF6, 0xF0, 0xA3,
+		0x8F, 0x83, 0xF6, 0xE3, 0xAD, 0x89, 0xF6, 0xE6,
+		0x9F, 0xBA, 0xF6, 0xE6, 0x9E, 0x85, 0xF6, 0xE6,
+		0xA1, 0x92, 0xF6, 0xE6, 0xA2, 0x85, 0xF6, 0xF0,
+		0xA3, 0x91, 0xAD, 0xF6, 0xE6, 0xA2, 0x8E, 0xF6,
+		0xE6, 0xA0, 0x9F, 0xF6, 0xE6, 0xA4, 0x94, 0xF6,
+		0xE3, 0xAE, 0x9D, 0xF6, 0xE6, 0xA5, 0x82, 0xF6,
+		0xE6, 0xA6, 0xA3, 0xF6, 0xE6, 0xA7, 0xAA, 0xF6,
+		0xE6, 0xAA, 0xA8, 0xF6, 0xF0, 0xA3, 0x9A, 0xA3,
+		0xF6, 0xE6, 0xAB, 0x9B, 0xF6, 0xE3, 0xB0, 0x98,
+		0xF6, 0xE6, 0xAC, 0xA1, 0xF6, 0xF0, 0xA3, 0xA2,
+		0xA7, 0xF6, 0xE6, 0xAD, 0x94, 0xF6, 0xE3, 0xB1,
+		0x8E, 0xF6, 0xE6, 0xAD, 0xB2, 0xF6, 0xE6, 0xAE,
+		0x9F, 0xF6, 0xE6, 0xAE, 0xBA, 0xF6, 0xE6, 0xAE,
+		0xBB, 0xF6, 0xF0, 0xA3, 0xAA, 0x8D, 0xF6, 0xF0,
+		0xA1, 0xB4, 0x8B, 0xF6, 0xF0, 0xA3, 0xAB, 0xBA,
+		0xF6, 0xE6, 0xB1, 0x8E, 0xF6, 0xF0, 0xA3, 0xB2,
+		0xBC, 0xF6, 0xE6, 0xB2, 0xBF, 0xF6, 0xE6, 0xB3,
+		0x8D, 0xF6, 0xE6, 0xB1, 0xA7, 0xF6, 0xE6, 0xB4,
+		0x96, 0xF6, 0xE6, 0xB4, 0xBE, 0xF6, 0xE6, 0xB5,
+		0xB7, 0xF6, 0xE6, 0xB5, 0x81, 0xF6, 0xE6, 0xB5,
+		0xA9, 0xF6, 0xE6, 0xB5, 0xB8, 0xF6, 0xE6, 0xB6,
+		0x85, 0xF6, 0xF0, 0xA3, 0xB4, 0x9E, 0xF6, 0xE6,
+		0xB4, 0xB4, 0xF6, 0xE6, 0xB8, 0xAF, 0xF6, 0xE6,
+		0xB9, 0xAE, 0xF6, 0xE3, 0xB4, 0xB3, 0xF6, 0xE6,
+		0xBB, 0x8B, 0xF6, 0xE6, 0xBB, 0x87, 0xF6, 0xF0,
+		0xA3, 0xBB, 0x91, 0xF6, 0xE6, 0xB7, 0xB9, 0xF6,
+		0xE6, 0xBD, 0xAE, 0xF6, 0xF0, 0xA3, 0xBD, 0x9E,
+		0xF6, 0xF0, 0xA3, 0xBE, 0x8E, 0xF6, 0xE6, 0xBF,
+		0x86, 0xF6, 0xE7, 0x80, 0xB9, 0xF6, 0xE7, 0x80,
+		0x9E, 0xF6, 0xE7, 0x80, 0x9B, 0xF6, 0xE3, 0xB6,
+		0x96, 0xF6, 0xE7, 0x81, 0x8A, 0xF6, 0xE7, 0x81,
+		0xBD, 0xF6, 0xE7, 0x81, 0xB7, 0xF6, 0xE7, 0x82,
+		0xAD, 0xF6, 0xF0, 0xA0, 0x94, 0xA5, 0xF6, 0xE7,
+		0x85, 0x85, 0xF6, 0xF0, 0xA4, 0x89, 0xA3, 0xF6,
+		0xE7, 0x86, 0x9C, 0xF6, 0xF0, 0xA4, 0x8E, 0xAB,
+		0xF6, 0xE7, 0x88, 0xA8, 0xF6, 0xE7, 0x88, 0xB5,
+		0xF6, 0xE7, 0x89, 0x90, 0xF6, 0xF0, 0xA4, 0x98,
+		0x88, 0xF6, 0xE7, 0x8A, 0x80, 0xF6, 0xE7, 0x8A,
+		0x95, 0xF6, 0xF0, 0xA4, 0x9C, 0xB5, 0xF6, 0xF0,
+		0xA4, 0xA0, 0x94, 0xF6, 0xE7, 0x8D, 0xBA, 0xF6,
+		0xE7, 0x8E, 0x8B, 0xF6, 0xE3, 0xBA, 0xAC, 0xF6,
+		0xE7, 0x8E, 0xA5, 0xF6, 0xE3, 0xBA, 0xB8, 0xF6,
+		0xE3, 0xBA, 0xB8, 0xF6, 0xE7, 0x91, 0x87, 0xF6,
+		0xE7, 0x91, 0x9C, 0xF6, 0xE7, 0x91, 0xB1, 0xF6,
+		0xE7, 0x92, 0x85, 0xF6, 0xE7, 0x93, 0x8A, 0xF6,
+		0xE3, 0xBC, 0x9B, 0xF6, 0xE7, 0x94, 0xA4, 0xF6,
+		0xF0, 0xA4, 0xB0, 0xB6, 0xF6, 0xE7, 0x94, 0xBE,
+		0xF6, 0xF0, 0xA4, 0xB2, 0x92, 0xF6, 0xE7, 0x95,
+		0xB0, 0xF6, 0xF0, 0xA2, 0x86, 0x9F, 0xF6, 0xE7,
+		0x98, 0x90, 0xF6, 0xF0, 0xA4, 0xBE, 0xA1, 0xF6,
+		0xF0, 0xA4, 0xBE, 0xB8, 0xF6, 0xF0, 0xA5, 0x81,
+		0x84, 0xF6, 0xE3, 0xBF, 0xBC, 0xF6, 0xE4, 0x80,
+		0x88, 0xF6, 0xE7, 0x9B, 0xB4, 0xF6, 0xF0, 0xA5,
+		0x83, 0xB3, 0xF6, 0xF0, 0xA5, 0x83, 0xB2, 0xF6,
+		0xF0, 0xA5, 0x84, 0x99, 0xF6, 0xF0, 0xA5, 0x84,
+		0xB3, 0xF6, 0xE7, 0x9C, 0x9E, 0xF6, 0xE7, 0x9C,
+		0x9F, 0xF6, 0xE7, 0x9C, 0x9F, 0xF6, 0xE7, 0x9D,
+		0x8A, 0xF6, 0xE4, 0x80, 0xB9, 0xF6, 0xE7, 0x9E,
+		0x8B, 0xF6, 0xE4, 0x81, 0x86, 0xF6, 0xE4, 0x82,
+		0x96, 0xF6, 0xF0, 0xA5, 0x90, 0x9D, 0xF6, 0xE7,
+		0xA1, 0x8E, 0xF6, 0xE7, 0xA2, 0x8C, 0xF6, 0xE7,
+		0xA3, 0x8C, 0xF6, 0xE4, 0x83, 0xA3, 0xF6, 0xF0,
+		0xA5, 0x98, 0xA6, 0xF6, 0xE7, 0xA5, 0x96, 0xF6,
+		0xF0, 0xA5, 0x9A, 0x9A, 0xF6, 0xF0, 0xA5, 0x9B,
+		0x85, 0xF6, 0xE7, 0xA6, 0x8F, 0xF6, 0xE7, 0xA7,
+		0xAB, 0xF6, 0xE4, 0x84, 0xAF, 0xF6, 0xE7, 0xA9,
+		0x80, 0xF6, 0xE7, 0xA9, 0x8A, 0xF6, 0xE7, 0xA9,
+		0x8F, 0xF6, 0xF0, 0xA5, 0xA5, 0xBC, 0xF6, 0xF0,
+		0xA5, 0xAA, 0xA7, 0xF6, 0xF0, 0xA5, 0xAA, 0xA7,
+		0xF6, 0xE7, 0xAB, 0xAE, 0xF6, 0xE4, 0x88, 0x82,
+		0xF6, 0xF0, 0xA5, 0xAE, 0xAB, 0xF6, 0xE7, 0xAF,
+		0x86, 0xF6, 0xE7, 0xAF, 0x89, 0xF6, 0xE4, 0x88,
+		0xA7, 0xF6, 0xF0, 0xA5, 0xB2, 0x80, 0xF6, 0xE7,
+		0xB3, 0x92, 0xF6, 0xE4, 0x8A, 0xA0, 0xF6, 0xE7,
+		0xB3, 0xA8, 0xF6, 0xE7, 0xB3, 0xA3, 0xF6, 0xE7,
+		0xB4, 0x80, 0xF6, 0xF0, 0xA5, 0xBE, 0x86, 0xF6,
+		0xE7, 0xB5, 0xA3, 0xF6, 0xE4, 0x8C, 0x81, 0xF6,
+		0xE7, 0xB7, 0x87, 0xF6, 0xE7, 0xB8, 0x82, 0xF6,
+		0xE7, 0xB9, 0x85, 0xF6, 0xE4, 0x8C, 0xB4, 0xF6,
+		0xF0, 0xA6, 0x88, 0xA8, 0xF6, 0xF0, 0xA6, 0x89,
+		0x87, 0xF6, 0xE4, 0x8D, 0x99, 0xF6, 0xF0, 0xA6,
+		0x8B, 0x99, 0xF6, 0xE7, 0xBD, 0xBA, 0xF6, 0xF0,
+		0xA6, 0x8C, 0xBE, 0xF6, 0xE7, 0xBE, 0x95, 0xF6,
+		0xE7, 0xBF, 0xBA, 0xF6, 0xE8, 0x80, 0x85, 0xF6,
+		0xF0, 0xA6, 0x93, 0x9A, 0xF6, 0xF0, 0xA6, 0x94,
+		0xA3, 0xF6, 0xE8, 0x81, 0xA0, 0xF6, 0xF0, 0xA6,
+		0x96, 0xA8, 0xF6, 0xE8, 0x81, 0xB0, 0xF6, 0xF0,
+		0xA3, 0x8D, 0x9F, 0xF6, 0xE4, 0x8F, 0x95, 0xF6,
+		0xE8, 0x82, 0xB2, 0xF6, 0xE8, 0x84, 0x83, 0xF6,
+		0xE4, 0x90, 0x8B, 0xF6, 0xE8, 0x84, 0xBE, 0xF6,
+		0xE5, 0xAA, 0xB5, 0xF6, 0xF0, 0xA6, 0x9E, 0xA7,
+		0xF6, 0xF0, 0xA6, 0x9E, 0xB5, 0xF6, 0xF0, 0xA3,
+		0x8E, 0x93, 0xF6, 0xF0, 0xA3, 0x8E, 0x9C, 0xF6,
+		0xE8, 0x88, 0x81, 0xF6, 0xE8, 0x88, 0x84, 0xF6,
+		0xE8, 0xBE, 0x9E, 0xF6, 0xE4, 0x91, 0xAB, 0xF6,
+		0xE8, 0x8A, 0x91, 0xF6, 0xE8, 0x8A, 0x8B, 0xF6,
+		0xE8, 0x8A, 0x9D, 0xF6, 0xE5, 0x8A, 0xB3, 0xF6,
+		0xE8, 0x8A, 0xB1, 0xF6, 0xE8, 0x8A, 0xB3, 0xF6,
+		0xE8, 0x8A, 0xBD, 0xF6, 0xE8, 0x8B, 0xA6, 0xF6,
+		0xF0, 0xA6, 0xAC, 0xBC, 0xF6, 0xE8, 0x8B, 0xA5,
+		0xF6, 0xE8, 0x8C, 0x9D, 0xF6, 0xE8, 0x8D, 0xA3,
+		0xF6, 0xE8, 0x8E, 0xAD, 0xF6, 0xE8, 0x8C, 0xA3,
+		0xF6, 0xE8, 0x8E, 0xBD, 0xF6, 0xE8, 0x8F, 0xA7,
+		0xF6, 0xE8, 0x91, 0x97, 0xF6, 0xE8, 0x8D, 0x93,
+		0xF6, 0xE8, 0x8F, 0x8A, 0xF6, 0xE8, 0x8F, 0x8C,
+		0xF6, 0xE8, 0x8F, 0x9C, 0xF6, 0xF0, 0xA6, 0xB0,
+		0xB6, 0xF6, 0xF0, 0xA6, 0xB5, 0xAB, 0xF6, 0xF0,
+		0xA6, 0xB3, 0x95, 0xF6, 0xE4, 0x94, 0xAB, 0xF6,
+		0xE8, 0x93, 0xB1, 0xF6, 0xE8, 0x93, 0xB3, 0xF6,
+		0xE8, 0x94, 0x96, 0xF6, 0xF0, 0xA7, 0x8F, 0x8A,
+		0xF6, 0xE8, 0x95, 0xA4, 0xF6, 0xF0, 0xA6, 0xBC,
+		0xAC, 0xF6, 0xE4, 0x95, 0x9D, 0xF6, 0xE4, 0x95,
+		0xA1, 0xF6, 0xF0, 0xA6, 0xBE, 0xB1, 0xF6, 0xF0,
+		0xA7, 0x83, 0x92, 0xF6, 0xE4, 0x95, 0xAB, 0xF6,
+		0xE8, 0x99, 0x90, 0xF6, 0xE8, 0x99, 0x9C, 0xF6,
+		0xE8, 0x99, 0xA7, 0xF6, 0xE8, 0x99, 0xA9, 0xF6,
+		0xE8, 0x9A, 0xA9, 0xF6, 0xE8, 0x9A, 0x88, 0xF6,
+		0xE8, 0x9C, 0x8E, 0xF6, 0xE8, 0x9B, 0xA2, 0xF6,
+		0xE8, 0x9D, 0xB9, 0xF6, 0xE8, 0x9C, 0xA8, 0xF6,
+		0xE8, 0x9D, 0xAB, 0xF6, 0xE8, 0x9E, 0x86, 0xF6,
+		0xE4, 0x97, 0x97, 0xF6, 0xE8, 0x9F, 0xA1, 0xF6,
+		0xE8, 0xA0, 0x81, 0xF6, 0xE4, 0x97, 0xB9, 0xF6,
+		0xE8, 0xA1, 0xA0, 0xF6, 0xE8, 0xA1, 0xA3, 0xF6,
+		0xF0, 0xA7, 0x99, 0xA7, 0xF6, 0xE8, 0xA3, 0x97,
+		0xF6, 0xE8, 0xA3, 0x9E, 0xF6, 0xE4, 0x98, 0xB5,
+		0xF6, 0xE8, 0xA3, 0xBA, 0xF6, 0xE3, 0x92, 0xBB,
+		0xF6, 0xF0, 0xA7, 0xA2, 0xAE, 0xF6, 0xF0, 0xA7,
+		0xA5, 0xA6, 0xF6, 0xE4, 0x9A, 0xBE, 0xF6, 0xE4,
+		0x9B, 0x87, 0xF6, 0xE8, 0xAA, 0xA0, 0xF6, 0xE8,
+		0xAB, 0xAD, 0xF6, 0xE8, 0xAE, 0x8A, 0xF6, 0xE8,
+		0xB1, 0x95, 0xF6, 0xF0, 0xA7, 0xB2, 0xA8, 0xF6,
+		0xE8, 0xB2, 0xAB, 0xF6, 0xE8, 0xB3, 0x81, 0xF6,
+		0xE8, 0xB4, 0x9B, 0xF6, 0xE8, 0xB5, 0xB7, 0xF6,
+		0xF0, 0xA7, 0xBC, 0xAF, 0xF6, 0xF0, 0xA0, 0xA0,
+		0x84, 0xF6, 0xE8, 0xB7, 0x8B, 0xF6, 0xE8, 0xB6,
+		0xBC, 0xF6, 0xE8, 0xB7, 0xB0, 0xF6, 0xF0, 0xA0,
+		0xA3, 0x9E, 0xF6, 0xE8, 0xBB, 0x94, 0xF6, 0xE8,
+		0xBC, 0xB8, 0xF6, 0xF0, 0xA8, 0x97, 0x92, 0xF6,
+		0xF0, 0xA8, 0x97, 0xAD, 0xF6, 0xE9, 0x82, 0x94,
+		0xF6, 0xE9, 0x83, 0xB1, 0xF6, 0xE9, 0x84, 0x91,
+		0xF6, 0xF0, 0xA8, 0x9C, 0xAE, 0xF6, 0xE9, 0x84,
+		0x9B, 0xF6, 0xE9, 0x88, 0xB8, 0xF6, 0xE9, 0x8B,
+		0x97, 0xF6, 0xE9, 0x8B, 0x98, 0xF6, 0xE9, 0x89,
+		0xBC, 0xF6, 0xE9, 0x8F, 0xB9, 0xF6, 0xE9, 0x90,
+		0x95, 0xF6, 0xF0, 0xA8, 0xAF, 0xBA, 0xF6, 0xE9,
+		0x96, 0x8B, 0xF6, 0xE4, 0xA6, 0x95, 0xF6, 0xE9,
+		0x96, 0xB7, 0xF6, 0xF0, 0xA8, 0xB5, 0xB7, 0xF6,
+		0xE4, 0xA7, 0xA6, 0xF6, 0xE9, 0x9B, 0x83, 0xF6,
+		0xE5, 0xB6, 0xB2, 0xF6, 0xE9, 0x9C, 0xA3, 0xF6,
+		0xF0, 0xA9, 0x85, 0x85, 0xF6, 0xF0, 0xA9, 0x88,
+		0x9A, 0xF6, 0xE4, 0xA9, 0xAE, 0xF6, 0xE4, 0xA9,
+		0xB6, 0xF6, 0xE9, 0x9F, 0xA0, 0xF6, 0xF0, 0xA9,
+		0x90, 0x8A, 0xF6, 0xE4, 0xAA, 0xB2, 0xF6, 0xF0,
+		0xA9, 0x92, 0x96, 0xF6, 0xE9, 0xA0, 0x8B, 0xF6,
+		0xE9, 0xA0, 0x8B, 0xF6, 0xE9, 0xA0, 0xA9, 0xF6,
+		0xF0, 0xA9, 0x96, 0xB6, 0xF6, 0xE9, 0xA3, 0xA2,
+		0xF6, 0xE4, 0xAC, 0xB3, 0xF6, 0xE9, 0xA4, 0xA9,
+		0xF6, 0xE9, 0xA6, 0xA7, 0xF6, 0xE9, 0xA7, 0x82,
+		0xF6, 0xE9, 0xA7, 0xBE, 0xF6, 0xE4, 0xAF, 0x8E,
+		0xF6, 0xF0, 0xA9, 0xAC, 0xB0, 0xF6, 0xE9, 0xAC,
+		0x92, 0xF6, 0xE9, 0xB1, 0x80, 0xF6, 0xE9, 0xB3,
+		0xBD, 0xF6, 0xE4, 0xB3, 0x8E, 0xF6, 0xE4, 0xB3,
+		0xAD, 0xF6, 0xE9, 0xB5, 0xA7, 0xF6, 0xF0, 0xAA,
+		0x83, 0x8E, 0xF6, 0xE4, 0xB3, 0xB8, 0xF6, 0xF0,
+		0xAA, 0x84, 0x85, 0xF6, 0xF0, 0xAA, 0x88, 0x8E,
+		0xF6, 0xF0, 0xAA, 0x8A, 0x91, 0xF6, 0xE9, 0xBA,
+		0xBB, 0xF6, 0xE4, 0xB5, 0x96, 0xF6, 0xE9, 0xBB,
+		0xB9, 0xF6, 0xE9, 0xBB, 0xBE, 0xF6, 0xE9, 0xBC,
+		0x85, 0xF6, 0xE9, 0xBC, 0x8F, 0xF6, 0xE9, 0xBC,
+		0x96, 0xF6, 0xE9, 0xBC, 0xBB, 0xF6, 0xF0, 0xAA,
+		0x98, 0x80, 0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,
+	},
+	{
+		0x20, 0x20, 0xCC, 0x88, 0x61, 0x20, 0xCC, 0x84,
+		0x32, 0x33, 0x20, 0xCC, 0x81, 0xCE, 0xBC, 0x20,
+		0xCC, 0xA7, 0x31, 0x6F, 0x31, 0xE2, 0x81, 0x84,
+		0x34, 0x31, 0xE2, 0x81, 0x84, 0x32, 0x33, 0xE2,
+		0x81, 0x84, 0x34, 0xF6, 0x41, 0xCC, 0x80, 0xF6,
+		0x41, 0xCC, 0x81, 0xF6, 0x41, 0xCC, 0x82, 0xF6,
+		0x41, 0xCC, 0x83, 0xF6, 0x41, 0xCC, 0x88, 0xF6,
+		0x41, 0xCC, 0x8A, 0xF6, 0x43, 0xCC, 0xA7, 0xF6,
+		0x45, 0xCC, 0x80, 0xF6, 0x45, 0xCC, 0x81, 0xF6,
+		0x45, 0xCC, 0x82, 0xF6, 0x45, 0xCC, 0x88, 0xF6,
+		0x49, 0xCC, 0x80, 0xF6, 0x49, 0xCC, 0x81, 0xF6,
+		0x49, 0xCC, 0x82, 0xF6, 0x49, 0xCC, 0x88, 0xF6,
+		0x4E, 0xCC, 0x83, 0xF6, 0x4F, 0xCC, 0x80, 0xF6,
+		0x4F, 0xCC, 0x81, 0xF6, 0x4F, 0xCC, 0x82, 0xF6,
+		0x4F, 0xCC, 0x83, 0xF6, 0x4F, 0xCC, 0x88, 0xF6,
+		0x55, 0xCC, 0x80, 0xF6, 0x55, 0xCC, 0x81, 0xF6,
+		0x55, 0xCC, 0x82, 0xF6, 0x55, 0xCC, 0x88, 0xF6,
+		0x59, 0xCC, 0x81, 0xF6, 0x61, 0xCC, 0x80, 0xF6,
+		0x61, 0xCC, 0x81, 0xF6, 0x61, 0xCC, 0x82, 0xF6,
+		0x61, 0xCC, 0x83, 0xF6, 0x61, 0xCC, 0x88, 0xF6,
+		0x61, 0xCC, 0x8A, 0xF6, 0x63, 0xCC, 0xA7, 0xF6,
+		0x65, 0xCC, 0x80, 0xF6, 0x65, 0xCC, 0x81, 0xF6,
+		0x65, 0xCC, 0x82, 0xF6, 0x65, 0xCC, 0x88, 0xF6,
+		0x69, 0xCC, 0x80, 0xF6, 0x69, 0xCC, 0x81, 0xF6,
+		0x69, 0xCC, 0x82, 0xF6, 0x69, 0xCC, 0x88, 0xF6,
+		0x6E, 0xCC, 0x83, 0xF6, 0x6F, 0xCC, 0x80, 0xF6,
+		0x6F, 0xCC, 0x81, 0xF6, 0x6F, 0xCC, 0x82, 0xF6,
+		0x6F, 0xCC, 0x83, 0xF6, 0x6F, 0xCC, 0x88, 0xF6,
+		0x75, 0xCC, 0x80, 0xF6, 0x75, 0xCC, 0x81, 0xF6,
+		0x75, 0xCC, 0x82, 0xF6, 0x75, 0xCC, 0x88, 0xF6,
+		0x79, 0xCC, 0x81, 0xF6, 0x79, 0xCC, 0x88, 0xF6,
+		0x41, 0xCC, 0x84, 0xF6, 0x61, 0xCC, 0x84, 0xF6,
+		0x41, 0xCC, 0x86, 0xF6, 0x61, 0xCC, 0x86, 0xF6,
+		0x41, 0xCC, 0xA8, 0xF6, 0x61, 0xCC, 0xA8, 0xF6,
+		0x43, 0xCC, 0x81, 0xF6, 0x63, 0xCC, 0x81, 0xF6,
+		0x43, 0xCC, 0x82, 0xF6, 0x63, 0xCC, 0x82, 0xF6,
+		0x43, 0xCC, 0x87, 0xF6, 0x63, 0xCC, 0x87, 0xF6,
+		0x43, 0xCC, 0x8C, 0xF6, 0x63, 0xCC, 0x8C, 0xF6,
+		0x44, 0xCC, 0x8C, 0xF6, 0x64, 0xCC, 0x8C, 0xF6,
+		0x45, 0xCC, 0x84, 0xF6, 0x65, 0xCC, 0x84, 0xF6,
+		0x45, 0xCC, 0x86, 0xF6, 0x65, 0xCC, 0x86, 0xF6,
+		0x45, 0xCC, 0x87, 0xF6, 0x65, 0xCC, 0x87, 0xF6,
+		0x45, 0xCC, 0xA8, 0xF6, 0x65, 0xCC, 0xA8, 0xF6,
+		0x45, 0xCC, 0x8C, 0xF6, 0x65, 0xCC, 0x8C, 0xF6,
+		0x47, 0xCC, 0x82, 0xF6, 0x67, 0xCC, 0x82, 0xF6,
+		0x47, 0xCC, 0x86, 0xF6, 0x67, 0xCC, 0x86, 0xF6,
+		0x47, 0xCC, 0x87, 0xF6, 0x67, 0xCC, 0x87, 0xF6,
+		0x47, 0xCC, 0xA7, 0xF6, 0x67, 0xCC, 0xA7, 0xF6,
+		0x48, 0xCC, 0x82, 0xF6, 0x68, 0xCC, 0x82, 0xF6,
+		0x49, 0xCC, 0x83, 0xF6, 0x69, 0xCC, 0x83, 0xF6,
+		0x49, 0xCC, 0x84, 0xF6, 0x69, 0xCC, 0x84, 0xF6,
+		0x49, 0xCC, 0x86, 0xF6, 0x69, 0xCC, 0x86, 0xF6,
+		0x49, 0xCC, 0xA8, 0xF6, 0x69, 0xCC, 0xA8, 0xF6,
+		0x49, 0xCC, 0x87, 0x49, 0x4A, 0x69, 0x6A, 0xF6,
+		0x4A, 0xCC, 0x82, 0xF6, 0x6A, 0xCC, 0x82, 0xF6,
+		0x4B, 0xCC, 0xA7, 0xF6, 0x6B, 0xCC, 0xA7, 0xF6,
+		0x4C, 0xCC, 0x81, 0xF6, 0x6C, 0xCC, 0x81, 0xF6,
+		0x4C, 0xCC, 0xA7, 0xF6, 0x6C, 0xCC, 0xA7, 0xF6,
+		0x4C, 0xCC, 0x8C, 0xF6, 0x6C, 0xCC, 0x8C, 0x4C,
+		0xC2, 0xB7, 0x6C, 0xC2, 0xB7, 0xF6, 0x4E, 0xCC,
+		0x81, 0xF6, 0x6E, 0xCC, 0x81, 0xF6, 0x4E, 0xCC,
+		0xA7, 0xF6, 0x6E, 0xCC, 0xA7, 0xF6, 0x4E, 0xCC,
+		0x8C, 0xF6, 0x6E, 0xCC, 0x8C, 0xCA, 0xBC, 0x6E,
+		0xF6, 0x4F, 0xCC, 0x84, 0xF6, 0x6F, 0xCC, 0x84,
+		0xF6, 0x4F, 0xCC, 0x86, 0xF6, 0x6F, 0xCC, 0x86,
+		0xF6, 0x4F, 0xCC, 0x8B, 0xF6, 0x6F, 0xCC, 0x8B,
+		0xF6, 0x52, 0xCC, 0x81, 0xF6, 0x72, 0xCC, 0x81,
+		0xF6, 0x52, 0xCC, 0xA7, 0xF6, 0x72, 0xCC, 0xA7,
+		0xF6, 0x52, 0xCC, 0x8C, 0xF6, 0x72, 0xCC, 0x8C,
+		0xF6, 0x53, 0xCC, 0x81, 0xF6, 0x73, 0xCC, 0x81,
+		0xF6, 0x53, 0xCC, 0x82, 0xF6, 0x73, 0xCC, 0x82,
+		0xF6, 0x53, 0xCC, 0xA7, 0xF6, 0x73, 0xCC, 0xA7,
+		0xF6, 0x53, 0xCC, 0x8C, 0xF6, 0x73, 0xCC, 0x8C,
+		0xF6, 0x54, 0xCC, 0xA7, 0xF6, 0x74, 0xCC, 0xA7,
+		0xF6, 0x54, 0xCC, 0x8C, 0xF6, 0x74, 0xCC, 0x8C,
+		0xF6, 0x55, 0xCC, 0x83, 0xF6, 0x75, 0xCC, 0x83,
+		0xF6, 0x55, 0xCC, 0x84, 0xF6, 0x75, 0xCC, 0x84,
+		0xF6, 0x55, 0xCC, 0x86, 0xF6, 0x75, 0xCC, 0x86,
+		0xF6, 0x55, 0xCC, 0x8A, 0xF6, 0x75, 0xCC, 0x8A,
+		0xF6, 0x55, 0xCC, 0x8B, 0xF6, 0x75, 0xCC, 0x8B,
+		0xF6, 0x55, 0xCC, 0xA8, 0xF6, 0x75, 0xCC, 0xA8,
+		0xF6, 0x57, 0xCC, 0x82, 0xF6, 0x77, 0xCC, 0x82,
+		0xF6, 0x59, 0xCC, 0x82, 0xF6, 0x79, 0xCC, 0x82,
+		0xF6, 0x59, 0xCC, 0x88, 0xF6, 0x5A, 0xCC, 0x81,
+		0xF6, 0x7A, 0xCC, 0x81, 0xF6, 0x5A, 0xCC, 0x87,
+		0xF6, 0x7A, 0xCC, 0x87, 0xF6, 0x5A, 0xCC, 0x8C,
+		0xF6, 0x7A, 0xCC, 0x8C, 0x73, 0xF6, 0x4F, 0xCC,
+		0x9B, 0xF6, 0x6F, 0xCC, 0x9B, 0xF6, 0x55, 0xCC,
+		0x9B, 0xF6, 0x75, 0xCC, 0x9B, 0x44, 0x5A, 0xCC,
+		0x8C, 0x44, 0x7A, 0xCC, 0x8C, 0x64, 0x7A, 0xCC,
+		0x8C, 0x4C, 0x4A, 0x4C, 0x6A, 0x6C, 0x6A, 0x4E,
+		0x4A, 0x4E, 0x6A, 0x6E, 0x6A, 0xF6, 0x41, 0xCC,
+		0x8C, 0xF6, 0x61, 0xCC, 0x8C, 0xF6, 0x49, 0xCC,
+		0x8C, 0xF6, 0x69, 0xCC, 0x8C, 0xF6, 0x4F, 0xCC,
+		0x8C, 0xF6, 0x6F, 0xCC, 0x8C, 0xF6, 0x55, 0xCC,
+		0x8C, 0xF6, 0x75, 0xCC, 0x8C, 0xF6, 0x55, 0xCC,
+		0x88, 0xCC, 0x84, 0xF6, 0x75, 0xCC, 0x88, 0xCC,
+		0x84, 0xF6, 0x55, 0xCC, 0x88, 0xCC, 0x81, 0xF6,
+		0x75, 0xCC, 0x88, 0xCC, 0x81, 0xF6, 0x55, 0xCC,
+		0x88, 0xCC, 0x8C, 0xF6, 0x75, 0xCC, 0x88, 0xCC,
+		0x8C, 0xF6, 0x55, 0xCC, 0x88, 0xCC, 0x80, 0xF6,
+		0x75, 0xCC, 0x88, 0xCC, 0x80, 0xF6, 0x41, 0xCC,
+		0x88, 0xCC, 0x84, 0xF6, 0x61, 0xCC, 0x88, 0xCC,
+		0x84, 0xF6, 0x41, 0xCC, 0x87, 0xCC, 0x84, 0xF6,
+		0x61, 0xCC, 0x87, 0xCC, 0x84, 0xF6, 0xC3, 0x86,
+		0xCC, 0x84, 0xF6, 0xC3, 0xA6, 0xCC, 0x84, 0xF6,
+		0x47, 0xCC, 0x8C, 0xF6, 0x67, 0xCC, 0x8C, 0xF6,
+		0x4B, 0xCC, 0x8C, 0xF6, 0x6B, 0xCC, 0x8C, 0xF6,
+		0x4F, 0xCC, 0xA8, 0xF6, 0x6F, 0xCC, 0xA8, 0xF6,
+		0x4F, 0xCC, 0xA8, 0xCC, 0x84, 0xF6, 0x6F, 0xCC,
+		0xA8, 0xCC, 0x84, 0xF6, 0xC6, 0xB7, 0xCC, 0x8C,
+		0xF6, 0xCA, 0x92, 0xCC, 0x8C, 0xF6, 0x6A, 0xCC,
+		0x8C, 0x44, 0x5A, 0x44, 0x7A, 0x64, 0x7A, 0xF6,
+		0x47, 0xCC, 0x81, 0xF6, 0x67, 0xCC, 0x81, 0xF6,
+		0x4E, 0xCC, 0x80, 0xF6, 0x6E, 0xCC, 0x80, 0xF6,
+		0x41, 0xCC, 0x8A, 0xCC, 0x81, 0xF6, 0x61, 0xCC,
+		0x8A, 0xCC, 0x81, 0xF6, 0xC3, 0x86, 0xCC, 0x81,
+		0xF6, 0xC3, 0xA6, 0xCC, 0x81, 0xF6, 0xC3, 0x98,
+		0xCC, 0x81, 0xF6, 0xC3, 0xB8, 0xCC, 0x81, 0xF6,
+		0x41, 0xCC, 0x8F, 0xF6, 0x61, 0xCC, 0x8F, 0xF6,
+		0x41, 0xCC, 0x91, 0xF6, 0x61, 0xCC, 0x91, 0xF6,
+		0x45, 0xCC, 0x8F, 0xF6, 0x65, 0xCC, 0x8F, 0xF6,
+		0x45, 0xCC, 0x91, 0xF6, 0x65, 0xCC, 0x91, 0xF6,
+		0x49, 0xCC, 0x8F, 0xF6, 0x69, 0xCC, 0x8F, 0xF6,
+		0x49, 0xCC, 0x91, 0xF6, 0x69, 0xCC, 0x91, 0xF6,
+		0x4F, 0xCC, 0x8F, 0xF6, 0x6F, 0xCC, 0x8F, 0xF6,
+		0x4F, 0xCC, 0x91, 0xF6, 0x6F, 0xCC, 0x91, 0xF6,
+		0x52, 0xCC, 0x8F, 0xF6, 0x72, 0xCC, 0x8F, 0xF6,
+		0x52, 0xCC, 0x91, 0xF6, 0x72, 0xCC, 0x91, 0xF6,
+		0x55, 0xCC, 0x8F, 0xF6, 0x75, 0xCC, 0x8F, 0xF6,
+		0x55, 0xCC, 0x91, 0xF6, 0x75, 0xCC, 0x91, 0xF6,
+		0x53, 0xCC, 0xA6, 0xF6, 0x73, 0xCC, 0xA6, 0xF6,
+		0x54, 0xCC, 0xA6, 0xF6, 0x74, 0xCC, 0xA6, 0xF6,
+		0x48, 0xCC, 0x8C, 0xF6, 0x68, 0xCC, 0x8C, 0xF6,
+		0x41, 0xCC, 0x87, 0xF6, 0x61, 0xCC, 0x87, 0xF6,
+		0x45, 0xCC, 0xA7, 0xF6, 0x65, 0xCC, 0xA7, 0xF6,
+		0x4F, 0xCC, 0x88, 0xCC, 0x84, 0xF6, 0x6F, 0xCC,
+		0x88, 0xCC, 0x84, 0xF6, 0x4F, 0xCC, 0x83, 0xCC,
+		0x84, 0xF6, 0x6F, 0xCC, 0x83, 0xCC, 0x84, 0xF6,
+		0x4F, 0xCC, 0x87, 0xF6, 0x6F, 0xCC, 0x87, 0xF6,
+		0x4F, 0xCC, 0x87, 0xCC, 0x84, 0xF6, 0x6F, 0xCC,
+		0x87, 0xCC, 0x84, 0xF6, 0x59, 0xCC, 0x84, 0xF6,
+		0x79, 0xCC, 0x84, 0x68, 0xC9, 0xA6, 0x6A, 0x72,
+		0xC9, 0xB9, 0xC9, 0xBB, 0xCA, 0x81, 0x77, 0x79,
+		0x20, 0xCC, 0x86, 0x20, 0xCC, 0x87, 0x20, 0xCC,
+		0x8A, 0x20, 0xCC, 0xA8, 0x20, 0xCC, 0x83, 0x20,
+		0xCC, 0x8B, 0xC9, 0xA3, 0x6C, 0x73, 0x78, 0xCA,
+		0x95, 0xF6, 0xCC, 0x80, 0xF6, 0xCC, 0x81, 0xF6,
+		0xCC, 0x93, 0xF6, 0xCC, 0x88, 0xCC, 0x81, 0xF6,
+		0xCA, 0xB9, 0x20, 0xCD, 0x85, 0xF6, 0x3B, 0x20,
+		0xCC, 0x81, 0xF5, 0x05, 0xC2, 0xA8, 0xCC, 0x81,
+		0x20, 0xCC, 0x88, 0xCC, 0x81, 0xF6, 0xCE, 0x91,
+		0xCC, 0x81, 0xF6, 0xC2, 0xB7, 0xF6, 0xCE, 0x95,
+		0xCC, 0x81, 0xF6, 0xCE, 0x97, 0xCC, 0x81, 0xF6,
+		0xCE, 0x99, 0xCC, 0x81, 0xF6, 0xCE, 0x9F, 0xCC,
+		0x81, 0xF6, 0xCE, 0xA5, 0xCC, 0x81, 0xF6, 0xCE,
+		0xA9, 0xCC, 0x81, 0xF6, 0xCE, 0xB9, 0xCC, 0x88,
+		0xCC, 0x81, 0xF6, 0xCE, 0x99, 0xCC, 0x88, 0xF6,
+		0xCE, 0xA5, 0xCC, 0x88, 0xF6, 0xCE, 0xB1, 0xCC,
+		0x81, 0xF6, 0xCE, 0xB5, 0xCC, 0x81, 0xF6, 0xCE,
+		0xB7, 0xCC, 0x81, 0xF6, 0xCE, 0xB9, 0xCC, 0x81,
+		0xF6, 0xCF, 0x85, 0xCC, 0x88, 0xCC, 0x81, 0xF6,
+		0xCE, 0xB9, 0xCC, 0x88, 0xF6, 0xCF, 0x85, 0xCC,
+		0x88, 0xF6, 0xCE, 0xBF, 0xCC, 0x81, 0xF6, 0xCF,
+		0x85, 0xCC, 0x81, 0xF6, 0xCF, 0x89, 0xCC, 0x81,
+		0xCE, 0xB2, 0xCE, 0xB8, 0xCE, 0xA5, 0xF5, 0x05,
+		0xCF, 0x92, 0xCC, 0x81, 0xCE, 0xA5, 0xCC, 0x81,
+		0xF5, 0x05, 0xCF, 0x92, 0xCC, 0x88, 0xCE, 0xA5,
+		0xCC, 0x88, 0xCF, 0x86, 0xCF, 0x80, 0xCE, 0xBA,
+		0xCF, 0x81, 0xCF, 0x82, 0xCE, 0x98, 0xCE, 0xB5,
+		0xCE, 0xA3, 0xF6, 0xD0, 0x95, 0xCC, 0x80, 0xF6,
+		0xD0, 0x95, 0xCC, 0x88, 0xF6, 0xD0, 0x93, 0xCC,
+		0x81, 0xF6, 0xD0, 0x86, 0xCC, 0x88, 0xF6, 0xD0,
+		0x9A, 0xCC, 0x81, 0xF6, 0xD0, 0x98, 0xCC, 0x80,
+		0xF6, 0xD0, 0xA3, 0xCC, 0x86, 0xF6, 0xD0, 0x98,
+		0xCC, 0x86, 0xF6, 0xD0, 0xB8, 0xCC, 0x86, 0xF6,
+		0xD0, 0xB5, 0xCC, 0x80, 0xF6, 0xD0, 0xB5, 0xCC,
+		0x88, 0xF6, 0xD0, 0xB3, 0xCC, 0x81, 0xF6, 0xD1,
+		0x96, 0xCC, 0x88, 0xF6, 0xD0, 0xBA, 0xCC, 0x81,
+		0xF6, 0xD0, 0xB8, 0xCC, 0x80, 0xF6, 0xD1, 0x83,
+		0xCC, 0x86, 0xF6, 0xD1, 0xB4, 0xCC, 0x8F, 0xF6,
+		0xD1, 0xB5, 0xCC, 0x8F, 0xF6, 0xD0, 0x96, 0xCC,
+		0x86, 0xF6, 0xD0, 0xB6, 0xCC, 0x86, 0xF6, 0xD0,
+		0x90, 0xCC, 0x86, 0xF6, 0xD0, 0xB0, 0xCC, 0x86,
+		0xF6, 0xD0, 0x90, 0xCC, 0x88, 0xF6, 0xD0, 0xB0,
+		0xCC, 0x88, 0xF6, 0xD0, 0x95, 0xCC, 0x86, 0xF6,
+		0xD0, 0xB5, 0xCC, 0x86, 0xF6, 0xD3, 0x98, 0xCC,
+		0x88, 0xF6, 0xD3, 0x99, 0xCC, 0x88, 0xF6, 0xD0,
+		0x96, 0xCC, 0x88, 0xF6, 0xD0, 0xB6, 0xCC, 0x88,
+		0xF6, 0xD0, 0x97, 0xCC, 0x88, 0xF6, 0xD0, 0xB7,
+		0xCC, 0x88, 0xF6, 0xD0, 0x98, 0xCC, 0x84, 0xF6,
+		0xD0, 0xB8, 0xCC, 0x84, 0xF6, 0xD0, 0x98, 0xCC,
+		0x88, 0xF6, 0xD0, 0xB8, 0xCC, 0x88, 0xF6, 0xD0,
+		0x9E, 0xCC, 0x88, 0xF6, 0xD0, 0xBE, 0xCC, 0x88,
+		0xF6, 0xD3, 0xA8, 0xCC, 0x88, 0xF6, 0xD3, 0xA9,
+		0xCC, 0x88, 0xF6, 0xD0, 0xAD, 0xCC, 0x88, 0xF6,
+		0xD1, 0x8D, 0xCC, 0x88, 0xF6, 0xD0, 0xA3, 0xCC,
+		0x84, 0xF6, 0xD1, 0x83, 0xCC, 0x84, 0xF6, 0xD0,
+		0xA3, 0xCC, 0x88, 0xF6, 0xD1, 0x83, 0xCC, 0x88,
+		0xF6, 0xD0, 0xA3, 0xCC, 0x8B, 0xF6, 0xD1, 0x83,
+		0xCC, 0x8B, 0xF6, 0xD0, 0xA7, 0xCC, 0x88, 0xF6,
+		0xD1, 0x87, 0xCC, 0x88, 0xF6, 0xD0, 0xAB, 0xCC,
+		0x88, 0xF6, 0xD1, 0x8B, 0xCC, 0x88, 0xD5, 0xA5,
+		0xD6, 0x82, 0xF6, 0xD8, 0xA7, 0xD9, 0x93, 0xF6,
+		0xD8, 0xA7, 0xD9, 0x94, 0xF6, 0xD9, 0x88, 0xD9,
+		0x94, 0xF6, 0xD8, 0xA7, 0xD9, 0x95, 0xF6, 0xD9,
+		0x8A, 0xD9, 0x94, 0xD8, 0xA7, 0xD9, 0xB4, 0xD9,
+		0x88, 0xD9, 0xB4, 0xDB, 0x87, 0xD9, 0xB4, 0xD9,
+		0x8A, 0xD9, 0xB4, 0xF6, 0xDB, 0x95, 0xD9, 0x94,
+		0xF6, 0xDB, 0x81, 0xD9, 0x94, 0xF6, 0xDB, 0x92,
+		0xD9, 0x94, 0xF6, 0xE0, 0xA4, 0xA8, 0xE0, 0xA4,
+		0xBC, 0xF6, 0xE0, 0xA4, 0xB0, 0xE0, 0xA4, 0xBC,
+		0xF6, 0xE0, 0xA4, 0xB3, 0xE0, 0xA4, 0xBC, 0xF6,
+		0xE0, 0xA4, 0x95, 0xE0, 0xA4, 0xBC, 0xF6, 0xE0,
+		0xA4, 0x96, 0xE0, 0xA4, 0xBC, 0xF6, 0xE0, 0xA4,
+		0x97, 0xE0, 0xA4, 0xBC, 0xF6, 0xE0, 0xA4, 0x9C,
+		0xE0, 0xA4, 0xBC, 0xF6, 0xE0, 0xA4, 0xA1, 0xE0,
+		0xA4, 0xBC, 0xF6, 0xE0, 0xA4, 0xA2, 0xE0, 0xA4,
+		0xBC, 0xF6, 0xE0, 0xA4, 0xAB, 0xE0, 0xA4, 0xBC,
+		0xF6, 0xE0, 0xA4, 0xAF, 0xE0, 0xA4, 0xBC, 0xF6,
+		0xE0, 0xA7, 0x87, 0xE0, 0xA6, 0xBE, 0xF6, 0xE0,
+		0xA7, 0x87, 0xE0, 0xA7, 0x97, 0xF6, 0xE0, 0xA6,
+		0xA1, 0xE0, 0xA6, 0xBC, 0xF6, 0xE0, 0xA6, 0xA2,
+		0xE0, 0xA6, 0xBC, 0xF6, 0xE0, 0xA6, 0xAF, 0xE0,
+		0xA6, 0xBC, 0xF6, 0xE0, 0xA8, 0xB2, 0xE0, 0xA8,
+		0xBC, 0xF6, 0xE0, 0xA8, 0xB8, 0xE0, 0xA8, 0xBC,
+		0xF6, 0xE0, 0xA8, 0x96, 0xE0, 0xA8, 0xBC, 0xF6,
+		0xE0, 0xA8, 0x97, 0xE0, 0xA8, 0xBC, 0xF6, 0xE0,
+		0xA8, 0x9C, 0xE0, 0xA8, 0xBC, 0xF6, 0xE0, 0xA8,
+		0xAB, 0xE0, 0xA8, 0xBC, 0xF6, 0xE0, 0xAD, 0x87,
+		0xE0, 0xAD, 0x96, 0xF6, 0xE0, 0xAD, 0x87, 0xE0,
+		0xAC, 0xBE, 0xF6, 0xE0, 0xAD, 0x87, 0xE0, 0xAD,
+		0x97, 0xF6, 0xE0, 0xAC, 0xA1, 0xE0, 0xAC, 0xBC,
+		0xF6, 0xE0, 0xAC, 0xA2, 0xE0, 0xAC, 0xBC, 0xF6,
+		0xE0, 0xAE, 0x92, 0xE0, 0xAF, 0x97, 0xF6, 0xE0,
+		0xAF, 0x86, 0xE0, 0xAE, 0xBE, 0xF6, 0xE0, 0xAF,
+		0x87, 0xE0, 0xAE, 0xBE, 0xF6, 0xE0, 0xAF, 0x86,
+		0xE0, 0xAF, 0x97, 0xF6, 0xE0, 0xB1, 0x86, 0xE0,
+		0xB1, 0x96, 0xF6, 0xE0, 0xB2, 0xBF, 0xE0, 0xB3,
+		0x95, 0xF6, 0xE0, 0xB3, 0x86, 0xE0, 0xB3, 0x95,
+		0xF6, 0xE0, 0xB3, 0x86, 0xE0, 0xB3, 0x96, 0xF6,
+		0xE0, 0xB3, 0x86, 0xE0, 0xB3, 0x82, 0xF6, 0xE0,
+		0xB3, 0x86, 0xE0, 0xB3, 0x82, 0xE0, 0xB3, 0x95,
+		0xF6, 0xE0, 0xB5, 0x86, 0xE0, 0xB4, 0xBE, 0xF6,
+		0xE0, 0xB5, 0x87, 0xE0, 0xB4, 0xBE, 0xF6, 0xE0,
+		0xB5, 0x86, 0xE0, 0xB5, 0x97, 0xF6, 0xE0, 0xB7,
+		0x99, 0xE0, 0xB7, 0x8A, 0xF6, 0xE0, 0xB7, 0x99,
+		0xE0, 0xB7, 0x8F, 0xF6, 0xE0, 0xB7, 0x99, 0xE0,
+		0xB7, 0x8F, 0xE0, 0xB7, 0x8A, 0xF6, 0xE0, 0xB7,
+		0x99, 0xE0, 0xB7, 0x9F, 0xE0, 0xB9, 0x8D, 0xE0,
+		0xB8, 0xB2, 0xE0, 0xBB, 0x8D, 0xE0, 0xBA, 0xB2,
+		0xE0, 0xBA, 0xAB, 0xE0, 0xBA, 0x99, 0xE0, 0xBA,
+		0xAB, 0xE0, 0xBA, 0xA1, 0xE0, 0xBC, 0x8B, 0xF6,
+		0xE0, 0xBD, 0x82, 0xE0, 0xBE, 0xB7, 0xF6, 0xE0,
+		0xBD, 0x8C, 0xE0, 0xBE, 0xB7, 0xF6, 0xE0, 0xBD,
+		0x91, 0xE0, 0xBE, 0xB7, 0xF6, 0xE0, 0xBD, 0x96,
+		0xE0, 0xBE, 0xB7, 0xF6, 0xE0, 0xBD, 0x9B, 0xE0,
+		0xBE, 0xB7, 0xF6, 0xE0, 0xBD, 0x80, 0xE0, 0xBE,
+		0xB5, 0xF6, 0xE0, 0xBD, 0xB1, 0xE0, 0xBD, 0xB2,
+		0xF6, 0xE0, 0xBD, 0xB1, 0xE0, 0xBD, 0xB4, 0xF6,
+		0xE0, 0xBE, 0xB2, 0xE0, 0xBE, 0x80, 0xE0, 0xBE,
+		0xB2, 0xE0, 0xBD, 0xB1, 0xE0, 0xBE, 0x80, 0xF6,
+		0xE0, 0xBE, 0xB3, 0xE0, 0xBE, 0x80, 0xE0, 0xBE,
+		0xB3, 0xE0, 0xBD, 0xB1, 0xE0, 0xBE, 0x80, 0xF6,
+		0xE0, 0xBD, 0xB1, 0xE0, 0xBE, 0x80, 0xF6, 0xE0,
+		0xBE, 0x92, 0xE0, 0xBE, 0xB7, 0xF6, 0xE0, 0xBE,
+		0x9C, 0xE0, 0xBE, 0xB7, 0xF6, 0xE0, 0xBE, 0xA1,
+		0xE0, 0xBE, 0xB7, 0xF6, 0xE0, 0xBE, 0xA6, 0xE0,
+		0xBE, 0xB7, 0xF6, 0xE0, 0xBE, 0xAB, 0xE0, 0xBE,
+		0xB7, 0xF6, 0xE0, 0xBE, 0x90, 0xE0, 0xBE, 0xB5,
+		0xF6, 0xE1, 0x80, 0xA5, 0xE1, 0x80, 0xAE, 0xE1,
+		0x83, 0x9C, 0xF6, 0xE1, 0xAC, 0x85, 0xE1, 0xAC,
+		0xB5, 0xF6, 0xE1, 0xAC, 0x87, 0xE1, 0xAC, 0xB5,
+		0xF6, 0xE1, 0xAC, 0x89, 0xE1, 0xAC, 0xB5, 0xF6,
+		0xE1, 0xAC, 0x8B, 0xE1, 0xAC, 0xB5, 0xF6, 0xE1,
+		0xAC, 0x8D, 0xE1, 0xAC, 0xB5, 0xF6, 0xE1, 0xAC,
+		0x91, 0xE1, 0xAC, 0xB5, 0xF6, 0xE1, 0xAC, 0xBA,
+		0xE1, 0xAC, 0xB5, 0xF6, 0xE1, 0xAC, 0xBC, 0xE1,
+		0xAC, 0xB5, 0xF6, 0xE1, 0xAC, 0xBE, 0xE1, 0xAC,
+		0xB5, 0xF6, 0xE1, 0xAC, 0xBF, 0xE1, 0xAC, 0xB5,
+		0xF6, 0xE1, 0xAD, 0x82, 0xE1, 0xAC, 0xB5, 0x41,
+		0xC3, 0x86, 0x42, 0x44, 0x45, 0xC6, 0x8E, 0x47,
+		0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
+		0xC8, 0xA2, 0x50, 0x52, 0x54, 0x55, 0x57, 0x61,
+		0xC9, 0x90, 0xC9, 0x91, 0xE1, 0xB4, 0x82, 0x62,
+		0x64, 0x65, 0xC9, 0x99, 0xC9, 0x9B, 0xC9, 0x9C,
+		0x67, 0x6B, 0x6D, 0xC5, 0x8B, 0x6F, 0xC9, 0x94,
+		0xE1, 0xB4, 0x96, 0xE1, 0xB4, 0x97, 0x70, 0x74,
+		0x75, 0xE1, 0xB4, 0x9D, 0xC9, 0xAF, 0x76, 0xE1,
+		0xB4, 0xA5, 0xCE, 0xB2, 0xCE, 0xB3, 0xCE, 0xB4,
+		0xCF, 0x86, 0xCF, 0x87, 0x69, 0x72, 0x75, 0x76,
+		0xCE, 0xB2, 0xCE, 0xB3, 0xCF, 0x81, 0xCF, 0x86,
+		0xCF, 0x87, 0xD0, 0xBD, 0xC9, 0x92, 0x63, 0xC9,
+		0x95, 0xC3, 0xB0, 0xC9, 0x9C, 0x66, 0xC9, 0x9F,
+		0xC9, 0xA1, 0xC9, 0xA5, 0xC9, 0xA8, 0xC9, 0xA9,
+		0xC9, 0xAA, 0xE1, 0xB5, 0xBB, 0xCA, 0x9D, 0xC9,
+		0xAD, 0xE1, 0xB6, 0x85, 0xCA, 0x9F, 0xC9, 0xB1,
+		0xC9, 0xB0, 0xC9, 0xB2, 0xC9, 0xB3, 0xC9, 0xB4,
+		0xC9, 0xB5, 0xC9, 0xB8, 0xCA, 0x82, 0xCA, 0x83,
+		0xC6, 0xAB, 0xCA, 0x89, 0xCA, 0x8A, 0xE1, 0xB4,
+		0x9C, 0xCA, 0x8B, 0xCA, 0x8C, 0x7A, 0xCA, 0x90,
+		0xCA, 0x91, 0xCA, 0x92, 0xCE, 0xB8, 0xF6, 0x41,
+		0xCC, 0xA5, 0xF6, 0x61, 0xCC, 0xA5, 0xF6, 0x42,
+		0xCC, 0x87, 0xF6, 0x62, 0xCC, 0x87, 0xF6, 0x42,
+		0xCC, 0xA3, 0xF6, 0x62, 0xCC, 0xA3, 0xF6, 0x42,
+		0xCC, 0xB1, 0xF6, 0x62, 0xCC, 0xB1, 0xF6, 0x43,
+		0xCC, 0xA7, 0xCC, 0x81, 0xF6, 0x63, 0xCC, 0xA7,
+		0xCC, 0x81, 0xF6, 0x44, 0xCC, 0x87, 0xF6, 0x64,
+		0xCC, 0x87, 0xF6, 0x44, 0xCC, 0xA3, 0xF6, 0x64,
+		0xCC, 0xA3, 0xF6, 0x44, 0xCC, 0xB1, 0xF6, 0x64,
+		0xCC, 0xB1, 0xF6, 0x44, 0xCC, 0xA7, 0xF6, 0x64,
+		0xCC, 0xA7, 0xF6, 0x44, 0xCC, 0xAD, 0xF6, 0x64,
+		0xCC, 0xAD, 0xF6, 0x45, 0xCC, 0x84, 0xCC, 0x80,
+		0xF6, 0x65, 0xCC, 0x84, 0xCC, 0x80, 0xF6, 0x45,
+		0xCC, 0x84, 0xCC, 0x81, 0xF6, 0x65, 0xCC, 0x84,
+		0xCC, 0x81, 0xF6, 0x45, 0xCC, 0xAD, 0xF6, 0x65,
+		0xCC, 0xAD, 0xF6, 0x45, 0xCC, 0xB0, 0xF6, 0x65,
+		0xCC, 0xB0, 0xF6, 0x45, 0xCC, 0xA7, 0xCC, 0x86,
+		0xF6, 0x65, 0xCC, 0xA7, 0xCC, 0x86, 0xF6, 0x46,
+		0xCC, 0x87, 0xF6, 0x66, 0xCC, 0x87, 0xF6, 0x47,
+		0xCC, 0x84, 0xF6, 0x67, 0xCC, 0x84, 0xF6, 0x48,
+		0xCC, 0x87, 0xF6, 0x68, 0xCC, 0x87, 0xF6, 0x48,
+		0xCC, 0xA3, 0xF6, 0x68, 0xCC, 0xA3, 0xF6, 0x48,
+		0xCC, 0x88, 0xF6, 0x68, 0xCC, 0x88, 0xF6, 0x48,
+		0xCC, 0xA7, 0xF6, 0x68, 0xCC, 0xA7, 0xF6, 0x48,
+		0xCC, 0xAE, 0xF6, 0x68, 0xCC, 0xAE, 0xF6, 0x49,
+		0xCC, 0xB0, 0xF6, 0x69, 0xCC, 0xB0, 0xF6, 0x49,
+		0xCC, 0x88, 0xCC, 0x81, 0xF6, 0x69, 0xCC, 0x88,
+		0xCC, 0x81, 0xF6, 0x4B, 0xCC, 0x81, 0xF6, 0x6B,
+		0xCC, 0x81, 0xF6, 0x4B, 0xCC, 0xA3, 0xF6, 0x6B,
+		0xCC, 0xA3, 0xF6, 0x4B, 0xCC, 0xB1, 0xF6, 0x6B,
+		0xCC, 0xB1, 0xF6, 0x4C, 0xCC, 0xA3, 0xF6, 0x6C,
+		0xCC, 0xA3, 0xF6, 0x4C, 0xCC, 0xA3, 0xCC, 0x84,
+		0xF6, 0x6C, 0xCC, 0xA3, 0xCC, 0x84, 0xF6, 0x4C,
+		0xCC, 0xB1, 0xF6, 0x6C, 0xCC, 0xB1, 0xF6, 0x4C,
+		0xCC, 0xAD, 0xF6, 0x6C, 0xCC, 0xAD, 0xF6, 0x4D,
+		0xCC, 0x81, 0xF6, 0x6D, 0xCC, 0x81, 0xF6, 0x4D,
+		0xCC, 0x87, 0xF6, 0x6D, 0xCC, 0x87, 0xF6, 0x4D,
+		0xCC, 0xA3, 0xF6, 0x6D, 0xCC, 0xA3, 0xF6, 0x4E,
+		0xCC, 0x87, 0xF6, 0x6E, 0xCC, 0x87, 0xF6, 0x4E,
+		0xCC, 0xA3, 0xF6, 0x6E, 0xCC, 0xA3, 0xF6, 0x4E,
+		0xCC, 0xB1, 0xF6, 0x6E, 0xCC, 0xB1, 0xF6, 0x4E,
+		0xCC, 0xAD, 0xF6, 0x6E, 0xCC, 0xAD, 0xF6, 0x4F,
+		0xCC, 0x83, 0xCC, 0x81, 0xF6, 0x6F, 0xCC, 0x83,
+		0xCC, 0x81, 0xF6, 0x4F, 0xCC, 0x83, 0xCC, 0x88,
+		0xF6, 0x6F, 0xCC, 0x83, 0xCC, 0x88, 0xF6, 0x4F,
+		0xCC, 0x84, 0xCC, 0x80, 0xF6, 0x6F, 0xCC, 0x84,
+		0xCC, 0x80, 0xF6, 0x4F, 0xCC, 0x84, 0xCC, 0x81,
+		0xF6, 0x6F, 0xCC, 0x84, 0xCC, 0x81, 0xF6, 0x50,
+		0xCC, 0x81, 0xF6, 0x70, 0xCC, 0x81, 0xF6, 0x50,
+		0xCC, 0x87, 0xF6, 0x70, 0xCC, 0x87, 0xF6, 0x52,
+		0xCC, 0x87, 0xF6, 0x72, 0xCC, 0x87, 0xF6, 0x52,
+		0xCC, 0xA3, 0xF6, 0x72, 0xCC, 0xA3, 0xF6, 0x52,
+		0xCC, 0xA3, 0xCC, 0x84, 0xF6, 0x72, 0xCC, 0xA3,
+		0xCC, 0x84, 0xF6, 0x52, 0xCC, 0xB1, 0xF6, 0x72,
+		0xCC, 0xB1, 0xF6, 0x53, 0xCC, 0x87, 0xF6, 0x73,
+		0xCC, 0x87, 0xF6, 0x53, 0xCC, 0xA3, 0xF6, 0x73,
+		0xCC, 0xA3, 0xF6, 0x53, 0xCC, 0x81, 0xCC, 0x87,
+		0xF6, 0x73, 0xCC, 0x81, 0xCC, 0x87, 0xF6, 0x53,
+		0xCC, 0x8C, 0xCC, 0x87, 0xF6, 0x73, 0xCC, 0x8C,
+		0xCC, 0x87, 0xF6, 0x53, 0xCC, 0xA3, 0xCC, 0x87,
+		0xF6, 0x73, 0xCC, 0xA3, 0xCC, 0x87, 0xF6, 0x54,
+		0xCC, 0x87, 0xF6, 0x74, 0xCC, 0x87, 0xF6, 0x54,
+		0xCC, 0xA3, 0xF6, 0x74, 0xCC, 0xA3, 0xF6, 0x54,
+		0xCC, 0xB1, 0xF6, 0x74, 0xCC, 0xB1, 0xF6, 0x54,
+		0xCC, 0xAD, 0xF6, 0x74, 0xCC, 0xAD, 0xF6, 0x55,
+		0xCC, 0xA4, 0xF6, 0x75, 0xCC, 0xA4, 0xF6, 0x55,
+		0xCC, 0xB0, 0xF6, 0x75, 0xCC, 0xB0, 0xF6, 0x55,
+		0xCC, 0xAD, 0xF6, 0x75, 0xCC, 0xAD, 0xF6, 0x55,
+		0xCC, 0x83, 0xCC, 0x81, 0xF6, 0x75, 0xCC, 0x83,
+		0xCC, 0x81, 0xF6, 0x55, 0xCC, 0x84, 0xCC, 0x88,
+		0xF6, 0x75, 0xCC, 0x84, 0xCC, 0x88, 0xF6, 0x56,
+		0xCC, 0x83, 0xF6, 0x76, 0xCC, 0x83, 0xF6, 0x56,
+		0xCC, 0xA3, 0xF6, 0x76, 0xCC, 0xA3, 0xF6, 0x57,
+		0xCC, 0x80, 0xF6, 0x77, 0xCC, 0x80, 0xF6, 0x57,
+		0xCC, 0x81, 0xF6, 0x77, 0xCC, 0x81, 0xF6, 0x57,
+		0xCC, 0x88, 0xF6, 0x77, 0xCC, 0x88, 0xF6, 0x57,
+		0xCC, 0x87, 0xF6, 0x77, 0xCC, 0x87, 0xF6, 0x57,
+		0xCC, 0xA3, 0xF6, 0x77, 0xCC, 0xA3, 0xF6, 0x58,
+		0xCC, 0x87, 0xF6, 0x78, 0xCC, 0x87, 0xF6, 0x58,
+		0xCC, 0x88, 0xF6, 0x78, 0xCC, 0x88, 0xF6, 0x59,
+		0xCC, 0x87, 0xF6, 0x79, 0xCC, 0x87, 0xF6, 0x5A,
+		0xCC, 0x82, 0xF6, 0x7A, 0xCC, 0x82, 0xF6, 0x5A,
+		0xCC, 0xA3, 0xF6, 0x7A, 0xCC, 0xA3, 0xF6, 0x5A,
+		0xCC, 0xB1, 0xF6, 0x7A, 0xCC, 0xB1, 0xF6, 0x68,
+		0xCC, 0xB1, 0xF6, 0x74, 0xCC, 0x88, 0xF6, 0x77,
+		0xCC, 0x8A, 0xF6, 0x79, 0xCC, 0x8A, 0x61, 0xCA,
+		0xBE, 0xF5, 0x05, 0xC5, 0xBF, 0xCC, 0x87, 0x73,
+		0xCC, 0x87, 0xF6, 0x41, 0xCC, 0xA3, 0xF6, 0x61,
+		0xCC, 0xA3, 0xF6, 0x41, 0xCC, 0x89, 0xF6, 0x61,
+		0xCC, 0x89, 0xF6, 0x41, 0xCC, 0x82, 0xCC, 0x81,
+		0xF6, 0x61, 0xCC, 0x82, 0xCC, 0x81, 0xF6, 0x41,
+		0xCC, 0x82, 0xCC, 0x80, 0xF6, 0x61, 0xCC, 0x82,
+		0xCC, 0x80, 0xF6, 0x41, 0xCC, 0x82, 0xCC, 0x89,
+		0xF6, 0x61, 0xCC, 0x82, 0xCC, 0x89, 0xF6, 0x41,
+		0xCC, 0x82, 0xCC, 0x83, 0xF6, 0x61, 0xCC, 0x82,
+		0xCC, 0x83, 0xF6, 0x41, 0xCC, 0xA3, 0xCC, 0x82,
+		0xF6, 0x61, 0xCC, 0xA3, 0xCC, 0x82, 0xF6, 0x41,
+		0xCC, 0x86, 0xCC, 0x81, 0xF6, 0x61, 0xCC, 0x86,
+		0xCC, 0x81, 0xF6, 0x41, 0xCC, 0x86, 0xCC, 0x80,
+		0xF6, 0x61, 0xCC, 0x86, 0xCC, 0x80, 0xF6, 0x41,
+		0xCC, 0x86, 0xCC, 0x89, 0xF6, 0x61, 0xCC, 0x86,
+		0xCC, 0x89, 0xF6, 0x41, 0xCC, 0x86, 0xCC, 0x83,
+		0xF6, 0x61, 0xCC, 0x86, 0xCC, 0x83, 0xF6, 0x41,
+		0xCC, 0xA3, 0xCC, 0x86, 0xF6, 0x61, 0xCC, 0xA3,
+		0xCC, 0x86, 0xF6, 0x45, 0xCC, 0xA3, 0xF6, 0x65,
+		0xCC, 0xA3, 0xF6, 0x45, 0xCC, 0x89, 0xF6, 0x65,
+		0xCC, 0x89, 0xF6, 0x45, 0xCC, 0x83, 0xF6, 0x65,
+		0xCC, 0x83, 0xF6, 0x45, 0xCC, 0x82, 0xCC, 0x81,
+		0xF6, 0x65, 0xCC, 0x82, 0xCC, 0x81, 0xF6, 0x45,
+		0xCC, 0x82, 0xCC, 0x80, 0xF6, 0x65, 0xCC, 0x82,
+		0xCC, 0x80, 0xF6, 0x45, 0xCC, 0x82, 0xCC, 0x89,
+		0xF6, 0x65, 0xCC, 0x82, 0xCC, 0x89, 0xF6, 0x45,
+		0xCC, 0x82, 0xCC, 0x83, 0xF6, 0x65, 0xCC, 0x82,
+		0xCC, 0x83, 0xF6, 0x45, 0xCC, 0xA3, 0xCC, 0x82,
+		0xF6, 0x65, 0xCC, 0xA3, 0xCC, 0x82, 0xF6, 0x49,
+		0xCC, 0x89, 0xF6, 0x69, 0xCC, 0x89, 0xF6, 0x49,
+		0xCC, 0xA3, 0xF6, 0x69, 0xCC, 0xA3, 0xF6, 0x4F,
+		0xCC, 0xA3, 0xF6, 0x6F, 0xCC, 0xA3, 0xF6, 0x4F,
+		0xCC, 0x89, 0xF6, 0x6F, 0xCC, 0x89, 0xF6, 0x4F,
+		0xCC, 0x82, 0xCC, 0x81, 0xF6, 0x6F, 0xCC, 0x82,
+		0xCC, 0x81, 0xF6, 0x4F, 0xCC, 0x82, 0xCC, 0x80,
+		0xF6, 0x6F, 0xCC, 0x82, 0xCC, 0x80, 0xF6, 0x4F,
+		0xCC, 0x82, 0xCC, 0x89, 0xF6, 0x6F, 0xCC, 0x82,
+		0xCC, 0x89, 0xF6, 0x4F, 0xCC, 0x82, 0xCC, 0x83,
+		0xF6, 0x6F, 0xCC, 0x82, 0xCC, 0x83, 0xF6, 0x4F,
+		0xCC, 0xA3, 0xCC, 0x82, 0xF6, 0x6F, 0xCC, 0xA3,
+		0xCC, 0x82, 0xF6, 0x4F, 0xCC, 0x9B, 0xCC, 0x81,
+		0xF6, 0x6F, 0xCC, 0x9B, 0xCC, 0x81, 0xF6, 0x4F,
+		0xCC, 0x9B, 0xCC, 0x80, 0xF6, 0x6F, 0xCC, 0x9B,
+		0xCC, 0x80, 0xF6, 0x4F, 0xCC, 0x9B, 0xCC, 0x89,
+		0xF6, 0x6F, 0xCC, 0x9B, 0xCC, 0x89, 0xF6, 0x4F,
+		0xCC, 0x9B, 0xCC, 0x83, 0xF6, 0x6F, 0xCC, 0x9B,
+		0xCC, 0x83, 0xF6, 0x4F, 0xCC, 0x9B, 0xCC, 0xA3,
+		0xF6, 0x6F, 0xCC, 0x9B, 0xCC, 0xA3, 0xF6, 0x55,
+		0xCC, 0xA3, 0xF6, 0x75, 0xCC, 0xA3, 0xF6, 0x55,
+		0xCC, 0x89, 0xF6, 0x75, 0xCC, 0x89, 0xF6, 0x55,
+		0xCC, 0x9B, 0xCC, 0x81, 0xF6, 0x75, 0xCC, 0x9B,
+		0xCC, 0x81, 0xF6, 0x55, 0xCC, 0x9B, 0xCC, 0x80,
+		0xF6, 0x75, 0xCC, 0x9B, 0xCC, 0x80, 0xF6, 0x55,
+		0xCC, 0x9B, 0xCC, 0x89, 0xF6, 0x75, 0xCC, 0x9B,
+		0xCC, 0x89, 0xF6, 0x55, 0xCC, 0x9B, 0xCC, 0x83,
+		0xF6, 0x75, 0xCC, 0x9B, 0xCC, 0x83, 0xF6, 0x55,
+		0xCC, 0x9B, 0xCC, 0xA3, 0xF6, 0x75, 0xCC, 0x9B,
+		0xCC, 0xA3, 0xF6, 0x59, 0xCC, 0x80, 0xF6, 0x79,
+		0xCC, 0x80, 0xF6, 0x59, 0xCC, 0xA3, 0xF6, 0x79,
+		0xCC, 0xA3, 0xF6, 0x59, 0xCC, 0x89, 0xF6, 0x79,
+		0xCC, 0x89, 0xF6, 0x59, 0xCC, 0x83, 0xF6, 0x79,
+		0xCC, 0x83, 0xF6, 0xCE, 0xB1, 0xCC, 0x93, 0xF6,
+		0xCE, 0xB1, 0xCC, 0x94, 0xF6, 0xCE, 0xB1, 0xCC,
+		0x93, 0xCC, 0x80, 0xF6, 0xCE, 0xB1, 0xCC, 0x94,
+		0xCC, 0x80, 0xF6, 0xCE, 0xB1, 0xCC, 0x93, 0xCC,
+		0x81, 0xF6, 0xCE, 0xB1, 0xCC, 0x94, 0xCC, 0x81,
+		0xF6, 0xCE, 0xB1, 0xCC, 0x93, 0xCD, 0x82, 0xF6,
+		0xCE, 0xB1, 0xCC, 0x94, 0xCD, 0x82, 0xF6, 0xCE,
+		0x91, 0xCC, 0x93, 0xF6, 0xCE, 0x91, 0xCC, 0x94,
+		0xF6, 0xCE, 0x91, 0xCC, 0x93, 0xCC, 0x80, 0xF6,
+		0xCE, 0x91, 0xCC, 0x94, 0xCC, 0x80, 0xF6, 0xCE,
+		0x91, 0xCC, 0x93, 0xCC, 0x81, 0xF6, 0xCE, 0x91,
+		0xCC, 0x94, 0xCC, 0x81, 0xF6, 0xCE, 0x91, 0xCC,
+		0x93, 0xCD, 0x82, 0xF6, 0xCE, 0x91, 0xCC, 0x94,
+		0xCD, 0x82, 0xF6, 0xCE, 0xB5, 0xCC, 0x93, 0xF6,
+		0xCE, 0xB5, 0xCC, 0x94, 0xF6, 0xCE, 0xB5, 0xCC,
+		0x93, 0xCC, 0x80, 0xF6, 0xCE, 0xB5, 0xCC, 0x94,
+		0xCC, 0x80, 0xF6, 0xCE, 0xB5, 0xCC, 0x93, 0xCC,
+		0x81, 0xF6, 0xCE, 0xB5, 0xCC, 0x94, 0xCC, 0x81,
+		0xF6, 0xCE, 0x95, 0xCC, 0x93, 0xF6, 0xCE, 0x95,
+		0xCC, 0x94, 0xF6, 0xCE, 0x95, 0xCC, 0x93, 0xCC,
+		0x80, 0xF6, 0xCE, 0x95, 0xCC, 0x94, 0xCC, 0x80,
+		0xF6, 0xCE, 0x95, 0xCC, 0x93, 0xCC, 0x81, 0xF6,
+		0xCE, 0x95, 0xCC, 0x94, 0xCC, 0x81, 0xF6, 0xCE,
+		0xB7, 0xCC, 0x93, 0xF6, 0xCE, 0xB7, 0xCC, 0x94,
+		0xF6, 0xCE, 0xB7, 0xCC, 0x93, 0xCC, 0x80, 0xF6,
+		0xCE, 0xB7, 0xCC, 0x94, 0xCC, 0x80, 0xF6, 0xCE,
+		0xB7, 0xCC, 0x93, 0xCC, 0x81, 0xF6, 0xCE, 0xB7,
+		0xCC, 0x94, 0xCC, 0x81, 0xF6, 0xCE, 0xB7, 0xCC,
+		0x93, 0xCD, 0x82, 0xF6, 0xCE, 0xB7, 0xCC, 0x94,
+		0xCD, 0x82, 0xF6, 0xCE, 0x97, 0xCC, 0x93, 0xF6,
+		0xCE, 0x97, 0xCC, 0x94, 0xF6, 0xCE, 0x97, 0xCC,
+		0x93, 0xCC, 0x80, 0xF6, 0xCE, 0x97, 0xCC, 0x94,
+		0xCC, 0x80, 0xF6, 0xCE, 0x97, 0xCC, 0x93, 0xCC,
+		0x81, 0xF6, 0xCE, 0x97, 0xCC, 0x94, 0xCC, 0x81,
+		0xF6, 0xCE, 0x97, 0xCC, 0x93, 0xCD, 0x82, 0xF6,
+		0xCE, 0x97, 0xCC, 0x94, 0xCD, 0x82, 0xF6, 0xCE,
+		0xB9, 0xCC, 0x93, 0xF6, 0xCE, 0xB9, 0xCC, 0x94,
+		0xF6, 0xCE, 0xB9, 0xCC, 0x93, 0xCC, 0x80, 0xF6,
+		0xCE, 0xB9, 0xCC, 0x94, 0xCC, 0x80, 0xF6, 0xCE,
+		0xB9, 0xCC, 0x93, 0xCC, 0x81, 0xF6, 0xCE, 0xB9,
+		0xCC, 0x94, 0xCC, 0x81, 0xF6, 0xCE, 0xB9, 0xCC,
+		0x93, 0xCD, 0x82, 0xF6, 0xCE, 0xB9, 0xCC, 0x94,
+		0xCD, 0x82, 0xF6, 0xCE, 0x99, 0xCC, 0x93, 0xF6,
+		0xCE, 0x99, 0xCC, 0x94, 0xF6, 0xCE, 0x99, 0xCC,
+		0x93, 0xCC, 0x80, 0xF6, 0xCE, 0x99, 0xCC, 0x94,
+		0xCC, 0x80, 0xF6, 0xCE, 0x99, 0xCC, 0x93, 0xCC,
+		0x81, 0xF6, 0xCE, 0x99, 0xCC, 0x94, 0xCC, 0x81,
+		0xF6, 0xCE, 0x99, 0xCC, 0x93, 0xCD, 0x82, 0xF6,
+		0xCE, 0x99, 0xCC, 0x94, 0xCD, 0x82, 0xF6, 0xCE,
+		0xBF, 0xCC, 0x93, 0xF6, 0xCE, 0xBF, 0xCC, 0x94,
+		0xF6, 0xCE, 0xBF, 0xCC, 0x93, 0xCC, 0x80, 0xF6,
+		0xCE, 0xBF, 0xCC, 0x94, 0xCC, 0x80, 0xF6, 0xCE,
+		0xBF, 0xCC, 0x93, 0xCC, 0x81, 0xF6, 0xCE, 0xBF,
+		0xCC, 0x94, 0xCC, 0x81, 0xF6, 0xCE, 0x9F, 0xCC,
+		0x93, 0xF6, 0xCE, 0x9F, 0xCC, 0x94, 0xF6, 0xCE,
+		0x9F, 0xCC, 0x93, 0xCC, 0x80, 0xF6, 0xCE, 0x9F,
+		0xCC, 0x94, 0xCC, 0x80, 0xF6, 0xCE, 0x9F, 0xCC,
+		0x93, 0xCC, 0x81, 0xF6, 0xCE, 0x9F, 0xCC, 0x94,
+		0xCC, 0x81, 0xF6, 0xCF, 0x85, 0xCC, 0x93, 0xF6,
+		0xCF, 0x85, 0xCC, 0x94, 0xF6, 0xCF, 0x85, 0xCC,
+		0x93, 0xCC, 0x80, 0xF6, 0xCF, 0x85, 0xCC, 0x94,
+		0xCC, 0x80, 0xF6, 0xCF, 0x85, 0xCC, 0x93, 0xCC,
+		0x81, 0xF6, 0xCF, 0x85, 0xCC, 0x94, 0xCC, 0x81,
+		0xF6, 0xCF, 0x85, 0xCC, 0x93, 0xCD, 0x82, 0xF6,
+		0xCF, 0x85, 0xCC, 0x94, 0xCD, 0x82, 0xF6, 0xCE,
+		0xA5, 0xCC, 0x94, 0xF6, 0xCE, 0xA5, 0xCC, 0x94,
+		0xCC, 0x80, 0xF6, 0xCE, 0xA5, 0xCC, 0x94, 0xCC,
+		0x81, 0xF6, 0xCE, 0xA5, 0xCC, 0x94, 0xCD, 0x82,
+		0xF6, 0xCF, 0x89, 0xCC, 0x93, 0xF6, 0xCF, 0x89,
+		0xCC, 0x94, 0xF6, 0xCF, 0x89, 0xCC, 0x93, 0xCC,
+		0x80, 0xF6, 0xCF, 0x89, 0xCC, 0x94, 0xCC, 0x80,
+		0xF6, 0xCF, 0x89, 0xCC, 0x93, 0xCC, 0x81, 0xF6,
+		0xCF, 0x89, 0xCC, 0x94, 0xCC, 0x81, 0xF6, 0xCF,
+		0x89, 0xCC, 0x93, 0xCD, 0x82, 0xF6, 0xCF, 0x89,
+		0xCC, 0x94, 0xCD, 0x82, 0xF6, 0xCE, 0xA9, 0xCC,
+		0x93, 0xF6, 0xCE, 0xA9, 0xCC, 0x94, 0xF6, 0xCE,
+		0xA9, 0xCC, 0x93, 0xCC, 0x80, 0xF6, 0xCE, 0xA9,
+		0xCC, 0x94, 0xCC, 0x80, 0xF6, 0xCE, 0xA9, 0xCC,
+		0x93, 0xCC, 0x81, 0xF6, 0xCE, 0xA9, 0xCC, 0x94,
+		0xCC, 0x81, 0xF6, 0xCE, 0xA9, 0xCC, 0x93, 0xCD,
+		0x82, 0xF6, 0xCE, 0xA9, 0xCC, 0x94, 0xCD, 0x82,
+		0xF6, 0xCE, 0xB1, 0xCC, 0x80, 0xF6, 0xCE, 0xB1,
+		0xCC, 0x81, 0xF6, 0xCE, 0xB5, 0xCC, 0x80, 0xF6,
+		0xCE, 0xB5, 0xCC, 0x81, 0xF6, 0xCE, 0xB7, 0xCC,
+		0x80, 0xF6, 0xCE, 0xB7, 0xCC, 0x81, 0xF6, 0xCE,
+		0xB9, 0xCC, 0x80, 0xF6, 0xCE, 0xB9, 0xCC, 0x81,
+		0xF6, 0xCE, 0xBF, 0xCC, 0x80, 0xF6, 0xCE, 0xBF,
+		0xCC, 0x81, 0xF6, 0xCF, 0x85, 0xCC, 0x80, 0xF6,
+		0xCF, 0x85, 0xCC, 0x81, 0xF6, 0xCF, 0x89, 0xCC,
+		0x80, 0xF6, 0xCF, 0x89, 0xCC, 0x81, 0xF6, 0xCE,
+		0xB1, 0xCC, 0x93, 0xCD, 0x85, 0xF6, 0xCE, 0xB1,
+		0xCC, 0x94, 0xCD, 0x85, 0xF6, 0xCE, 0xB1, 0xCC,
+		0x93, 0xCC, 0x80, 0xCD, 0x85, 0xF6, 0xCE, 0xB1,
+		0xCC, 0x94, 0xCC, 0x80, 0xCD, 0x85, 0xF6, 0xCE,
+		0xB1, 0xCC, 0x93, 0xCC, 0x81, 0xCD, 0x85, 0xF6,
+		0xCE, 0xB1, 0xCC, 0x94, 0xCC, 0x81, 0xCD, 0x85,
+		0xF6, 0xCE, 0xB1, 0xCC, 0x93, 0xCD, 0x82, 0xCD,
+		0x85, 0xF6, 0xCE, 0xB1, 0xCC, 0x94, 0xCD, 0x82,
+		0xCD, 0x85, 0xF6, 0xCE, 0x91, 0xCC, 0x93, 0xCD,
+		0x85, 0xF6, 0xCE, 0x91, 0xCC, 0x94, 0xCD, 0x85,
+		0xF6, 0xCE, 0x91, 0xCC, 0x93, 0xCC, 0x80, 0xCD,
+		0x85, 0xF6, 0xCE, 0x91, 0xCC, 0x94, 0xCC, 0x80,
+		0xCD, 0x85, 0xF6, 0xCE, 0x91, 0xCC, 0x93, 0xCC,
+		0x81, 0xCD, 0x85, 0xF6, 0xCE, 0x91, 0xCC, 0x94,
+		0xCC, 0x81, 0xCD, 0x85, 0xF6, 0xCE, 0x91, 0xCC,
+		0x93, 0xCD, 0x82, 0xCD, 0x85, 0xF6, 0xCE, 0x91,
+		0xCC, 0x94, 0xCD, 0x82, 0xCD, 0x85, 0xF6, 0xCE,
+		0xB7, 0xCC, 0x93, 0xCD, 0x85, 0xF6, 0xCE, 0xB7,
+		0xCC, 0x94, 0xCD, 0x85, 0xF6, 0xCE, 0xB7, 0xCC,
+		0x93, 0xCC, 0x80, 0xCD, 0x85, 0xF6, 0xCE, 0xB7,
+		0xCC, 0x94, 0xCC, 0x80, 0xCD, 0x85, 0xF6, 0xCE,
+		0xB7, 0xCC, 0x93, 0xCC, 0x81, 0xCD, 0x85, 0xF6,
+		0xCE, 0xB7, 0xCC, 0x94, 0xCC, 0x81, 0xCD, 0x85,
+		0xF6, 0xCE, 0xB7, 0xCC, 0x93, 0xCD, 0x82, 0xCD,
+		0x85, 0xF6, 0xCE, 0xB7, 0xCC, 0x94, 0xCD, 0x82,
+		0xCD, 0x85, 0xF6, 0xCE, 0x97, 0xCC, 0x93, 0xCD,
+		0x85, 0xF6, 0xCE, 0x97, 0xCC, 0x94, 0xCD, 0x85,
+		0xF6, 0xCE, 0x97, 0xCC, 0x93, 0xCC, 0x80, 0xCD,
+		0x85, 0xF6, 0xCE, 0x97, 0xCC, 0x94, 0xCC, 0x80,
+		0xCD, 0x85, 0xF6, 0xCE, 0x97, 0xCC, 0x93, 0xCC,
+		0x81, 0xCD, 0x85, 0xF6, 0xCE, 0x97, 0xCC, 0x94,
+		0xCC, 0x81, 0xCD, 0x85, 0xF6, 0xCE, 0x97, 0xCC,
+		0x93, 0xCD, 0x82, 0xCD, 0x85, 0xF6, 0xCE, 0x97,
+		0xCC, 0x94, 0xCD, 0x82, 0xCD, 0x85, 0xF6, 0xCF,
+		0x89, 0xCC, 0x93, 0xCD, 0x85, 0xF6, 0xCF, 0x89,
+		0xCC, 0x94, 0xCD, 0x85, 0xF6, 0xCF, 0x89, 0xCC,
+		0x93, 0xCC, 0x80, 0xCD, 0x85, 0xF6, 0xCF, 0x89,
+		0xCC, 0x94, 0xCC, 0x80, 0xCD, 0x85, 0xF6, 0xCF,
+		0x89, 0xCC, 0x93, 0xCC, 0x81, 0xCD, 0x85, 0xF6,
+		0xCF, 0x89, 0xCC, 0x94, 0xCC, 0x81, 0xCD, 0x85,
+		0xF6, 0xCF, 0x89, 0xCC, 0x93, 0xCD, 0x82, 0xCD,
+		0x85, 0xF6, 0xCF, 0x89, 0xCC, 0x94, 0xCD, 0x82,
+		0xCD, 0x85, 0xF6, 0xCE, 0xA9, 0xCC, 0x93, 0xCD,
+		0x85, 0xF6, 0xCE, 0xA9, 0xCC, 0x94, 0xCD, 0x85,
+		0xF6, 0xCE, 0xA9, 0xCC, 0x93, 0xCC, 0x80, 0xCD,
+		0x85, 0xF6, 0xCE, 0xA9, 0xCC, 0x94, 0xCC, 0x80,
+		0xCD, 0x85, 0xF6, 0xCE, 0xA9, 0xCC, 0x93, 0xCC,
+		0x81, 0xCD, 0x85, 0xF6, 0xCE, 0xA9, 0xCC, 0x94,
+		0xCC, 0x81, 0xCD, 0x85, 0xF6, 0xCE, 0xA9, 0xCC,
+		0x93, 0xCD, 0x82, 0xCD, 0x85, 0xF6, 0xCE, 0xA9,
+		0xCC, 0x94, 0xCD, 0x82, 0xCD, 0x85, 0xF6, 0xCE,
+		0xB1, 0xCC, 0x86, 0xF6, 0xCE, 0xB1, 0xCC, 0x84,
+		0xF6, 0xCE, 0xB1, 0xCC, 0x80, 0xCD, 0x85, 0xF6,
+		0xCE, 0xB1, 0xCD, 0x85, 0xF6, 0xCE, 0xB1, 0xCC,
+		0x81, 0xCD, 0x85, 0xF6, 0xCE, 0xB1, 0xCD, 0x82,
+		0xF6, 0xCE, 0xB1, 0xCD, 0x82, 0xCD, 0x85, 0xF6,
+		0xCE, 0x91, 0xCC, 0x86, 0xF6, 0xCE, 0x91, 0xCC,
+		0x84, 0xF6, 0xCE, 0x91, 0xCC, 0x80, 0xF6, 0xCE,
+		0x91, 0xCC, 0x81, 0xF6, 0xCE, 0x91, 0xCD, 0x85,
+		0x20, 0xCC, 0x93, 0xF6, 0xCE, 0xB9, 0x20, 0xCC,
+		0x93, 0x20, 0xCD, 0x82, 0xF5, 0x05, 0xC2, 0xA8,
+		0xCD, 0x82, 0x20, 0xCC, 0x88, 0xCD, 0x82, 0xF6,
+		0xCE, 0xB7, 0xCC, 0x80, 0xCD, 0x85, 0xF6, 0xCE,
+		0xB7, 0xCD, 0x85, 0xF6, 0xCE, 0xB7, 0xCC, 0x81,
+		0xCD, 0x85, 0xF6, 0xCE, 0xB7, 0xCD, 0x82, 0xF6,
+		0xCE, 0xB7, 0xCD, 0x82, 0xCD, 0x85, 0xF6, 0xCE,
+		0x95, 0xCC, 0x80, 0xF6, 0xCE, 0x95, 0xCC, 0x81,
+		0xF6, 0xCE, 0x97, 0xCC, 0x80, 0xF6, 0xCE, 0x97,
+		0xCC, 0x81, 0xF6, 0xCE, 0x97, 0xCD, 0x85, 0xF5,
+		0x06, 0xE1, 0xBE, 0xBF, 0xCC, 0x80, 0x20, 0xCC,
+		0x93, 0xCC, 0x80, 0xF5, 0x06, 0xE1, 0xBE, 0xBF,
+		0xCC, 0x81, 0x20, 0xCC, 0x93, 0xCC, 0x81, 0xF5,
+		0x06, 0xE1, 0xBE, 0xBF, 0xCD, 0x82, 0x20, 0xCC,
+		0x93, 0xCD, 0x82, 0xF6, 0xCE, 0xB9, 0xCC, 0x86,
+		0xF6, 0xCE, 0xB9, 0xCC, 0x84, 0xF6, 0xCE, 0xB9,
+		0xCC, 0x88, 0xCC, 0x80, 0xF6, 0xCE, 0xB9, 0xCC,
+		0x88, 0xCC, 0x81, 0xF6, 0xCE, 0xB9, 0xCD, 0x82,
+		0xF6, 0xCE, 0xB9, 0xCC, 0x88, 0xCD, 0x82, 0xF6,
+		0xCE, 0x99, 0xCC, 0x86, 0xF6, 0xCE, 0x99, 0xCC,
+		0x84, 0xF6, 0xCE, 0x99, 0xCC, 0x80, 0xF6, 0xCE,
+		0x99, 0xCC, 0x81, 0xF5, 0x06, 0xE1, 0xBF, 0xBE,
+		0xCC, 0x80, 0x20, 0xCC, 0x94, 0xCC, 0x80, 0xF5,
+		0x06, 0xE1, 0xBF, 0xBE, 0xCC, 0x81, 0x20, 0xCC,
+		0x94, 0xCC, 0x81, 0xF5, 0x06, 0xE1, 0xBF, 0xBE,
+		0xCD, 0x82, 0x20, 0xCC, 0x94, 0xCD, 0x82, 0xF6,
+		0xCF, 0x85, 0xCC, 0x86, 0xF6, 0xCF, 0x85, 0xCC,
+		0x84, 0xF6, 0xCF, 0x85, 0xCC, 0x88, 0xCC, 0x80,
+		0xF6, 0xCF, 0x85, 0xCC, 0x88, 0xCC, 0x81, 0xF6,
+		0xCF, 0x81, 0xCC, 0x93, 0xF6, 0xCF, 0x81, 0xCC,
+		0x94, 0xF6, 0xCF, 0x85, 0xCD, 0x82, 0xF6, 0xCF,
+		0x85, 0xCC, 0x88, 0xCD, 0x82, 0xF6, 0xCE, 0xA5,
+		0xCC, 0x86, 0xF6, 0xCE, 0xA5, 0xCC, 0x84, 0xF6,
+		0xCE, 0xA5, 0xCC, 0x80, 0xF6, 0xCE, 0xA5, 0xCC,
+		0x81, 0xF6, 0xCE, 0xA1, 0xCC, 0x94, 0xF5, 0x05,
+		0xC2, 0xA8, 0xCC, 0x80, 0x20, 0xCC, 0x88, 0xCC,
+		0x80, 0xF5, 0x05, 0xC2, 0xA8, 0xCC, 0x81, 0x20,
+		0xCC, 0x88, 0xCC, 0x81, 0xF6, 0x60, 0xF6, 0xCF,
+		0x89, 0xCC, 0x80, 0xCD, 0x85, 0xF6, 0xCF, 0x89,
+		0xCD, 0x85, 0xF6, 0xCF, 0x89, 0xCC, 0x81, 0xCD,
+		0x85, 0xF6, 0xCF, 0x89, 0xCD, 0x82, 0xF6, 0xCF,
+		0x89, 0xCD, 0x82, 0xCD, 0x85, 0xF6, 0xCE, 0x9F,
+		0xCC, 0x80, 0xF6, 0xCE, 0x9F, 0xCC, 0x81, 0xF6,
+		0xCE, 0xA9, 0xCC, 0x80, 0xF6, 0xCE, 0xA9, 0xCC,
+		0x81, 0xF6, 0xCE, 0xA9, 0xCD, 0x85, 0xF5, 0x03,
+		0xC2, 0xB4, 0x20, 0xCC, 0x81, 0x20, 0xCC, 0x94,
+		0xF5, 0x04, 0xE2, 0x80, 0x82, 0x20, 0xF5, 0x04,
+		0xE2, 0x80, 0x83, 0x20, 0x20, 0x20, 0x20, 0x20,
+		0x20, 0x20, 0x20, 0x20, 0x20, 0xE2, 0x80, 0x90,
+		0x20, 0xCC, 0xB3, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
+		0x2E, 0x20, 0xE2, 0x80, 0xB2, 0xE2, 0x80, 0xB2,
+		0xE2, 0x80, 0xB2, 0xE2, 0x80, 0xB2, 0xE2, 0x80,
+		0xB2, 0xE2, 0x80, 0xB5, 0xE2, 0x80, 0xB5, 0xE2,
+		0x80, 0xB5, 0xE2, 0x80, 0xB5, 0xE2, 0x80, 0xB5,
+		0x21, 0x21, 0x20, 0xCC, 0x85, 0x3F, 0x3F, 0x3F,
+		0x21, 0x21, 0x3F, 0xE2, 0x80, 0xB2, 0xE2, 0x80,
+		0xB2, 0xE2, 0x80, 0xB2, 0xE2, 0x80, 0xB2, 0x20,
+		0x30, 0x69, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
+		0x2B, 0xE2, 0x88, 0x92, 0x3D, 0x28, 0x29, 0x6E,
+		0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+		0x38, 0x39, 0x2B, 0xE2, 0x88, 0x92, 0x3D, 0x28,
+		0x29, 0x61, 0x65, 0x6F, 0x78, 0xC9, 0x99, 0x52,
+		0x73, 0x61, 0x2F, 0x63, 0x61, 0x2F, 0x73, 0x43,
+		0xC2, 0xB0, 0x43, 0x63, 0x2F, 0x6F, 0x63, 0x2F,
+		0x75, 0xC6, 0x90, 0xC2, 0xB0, 0x46, 0x67, 0x48,
+		0x48, 0x48, 0x68, 0xC4, 0xA7, 0x49, 0x49, 0x4C,
+		0x6C, 0x4E, 0x4E, 0x6F, 0x50, 0x51, 0x52, 0x52,
+		0x52, 0x53, 0x4D, 0x54, 0x45, 0x4C, 0x54, 0x4D,
+		0x5A, 0xF6, 0xCE, 0xA9, 0x5A, 0xF6, 0x4B, 0xF6,
+		0x41, 0xCC, 0x8A, 0x42, 0x43, 0x65, 0x45, 0x46,
+		0x4D, 0x6F, 0xD7, 0x90, 0xD7, 0x91, 0xD7, 0x92,
+		0xD7, 0x93, 0x69, 0x46, 0x41, 0x58, 0xCF, 0x80,
+		0xCE, 0xB3, 0xCE, 0x93, 0xCE, 0xA0, 0xE2, 0x88,
+		0x91, 0x44, 0x64, 0x65, 0x69, 0x6A, 0x31, 0xE2,
+		0x81, 0x84, 0x33, 0x32, 0xE2, 0x81, 0x84, 0x33,
+		0x31, 0xE2, 0x81, 0x84, 0x35, 0x32, 0xE2, 0x81,
+		0x84, 0x35, 0x33, 0xE2, 0x81, 0x84, 0x35, 0x34,
+		0xE2, 0x81, 0x84, 0x35, 0x31, 0xE2, 0x81, 0x84,
+		0x36, 0x35, 0xE2, 0x81, 0x84, 0x36, 0x31, 0xE2,
+		0x81, 0x84, 0x38, 0x33, 0xE2, 0x81, 0x84, 0x38,
+		0x35, 0xE2, 0x81, 0x84, 0x38, 0x37, 0xE2, 0x81,
+		0x84, 0x38, 0x31, 0xE2, 0x81, 0x84, 0x49, 0x49,
+		0x49, 0x49, 0x49, 0x49, 0x49, 0x56, 0x56, 0x56,
+		0x49, 0x56, 0x49, 0x49, 0x56, 0x49, 0x49, 0x49,
+		0x49, 0x58, 0x58, 0x58, 0x49, 0x58, 0x49, 0x49,
+		0x4C, 0x43, 0x44, 0x4D, 0x69, 0x69, 0x69, 0x69,
+		0x69, 0x69, 0x69, 0x76, 0x76, 0x76, 0x69, 0x76,
+		0x69, 0x69, 0x76, 0x69, 0x69, 0x69, 0x69, 0x78,
+		0x78, 0x78, 0x69, 0x78, 0x69, 0x69, 0x6C, 0x63,
+		0x64, 0x6D, 0xF6, 0xE2, 0x86, 0x90, 0xCC, 0xB8,
+		0xF6, 0xE2, 0x86, 0x92, 0xCC, 0xB8, 0xF6, 0xE2,
+		0x86, 0x94, 0xCC, 0xB8, 0xF6, 0xE2, 0x87, 0x90,
+		0xCC, 0xB8, 0xF6, 0xE2, 0x87, 0x94, 0xCC, 0xB8,
+		0xF6, 0xE2, 0x87, 0x92, 0xCC, 0xB8, 0xF6, 0xE2,
+		0x88, 0x83, 0xCC, 0xB8, 0xF6, 0xE2, 0x88, 0x88,
+		0xCC, 0xB8, 0xF6, 0xE2, 0x88, 0x8B, 0xCC, 0xB8,
+		0xF6, 0xE2, 0x88, 0xA3, 0xCC, 0xB8, 0xF6, 0xE2,
+		0x88, 0xA5, 0xCC, 0xB8, 0xE2, 0x88, 0xAB, 0xE2,
+		0x88, 0xAB, 0xE2, 0x88, 0xAB, 0xE2, 0x88, 0xAB,
+		0xE2, 0x88, 0xAB, 0xE2, 0x88, 0xAE, 0xE2, 0x88,
+		0xAE, 0xE2, 0x88, 0xAE, 0xE2, 0x88, 0xAE, 0xE2,
+		0x88, 0xAE, 0xF6, 0xE2, 0x88, 0xBC, 0xCC, 0xB8,
+		0xF6, 0xE2, 0x89, 0x83, 0xCC, 0xB8, 0xF6, 0xE2,
+		0x89, 0x85, 0xCC, 0xB8, 0xF6, 0xE2, 0x89, 0x88,
+		0xCC, 0xB8, 0xF6, 0x3D, 0xCC, 0xB8, 0xF6, 0xE2,
+		0x89, 0xA1, 0xCC, 0xB8, 0xF6, 0xE2, 0x89, 0x8D,
+		0xCC, 0xB8, 0xF6, 0x3C, 0xCC, 0xB8, 0xF6, 0x3E,
+		0xCC, 0xB8, 0xF6, 0xE2, 0x89, 0xA4, 0xCC, 0xB8,
+		0xF6, 0xE2, 0x89, 0xA5, 0xCC, 0xB8, 0xF6, 0xE2,
+		0x89, 0xB2, 0xCC, 0xB8, 0xF6, 0xE2, 0x89, 0xB3,
+		0xCC, 0xB8, 0xF6, 0xE2, 0x89, 0xB6, 0xCC, 0xB8,
+		0xF6, 0xE2, 0x89, 0xB7, 0xCC, 0xB8, 0xF6, 0xE2,
+		0x89, 0xBA, 0xCC, 0xB8, 0xF6, 0xE2, 0x89, 0xBB,
+		0xCC, 0xB8, 0xF6, 0xE2, 0x8A, 0x82, 0xCC, 0xB8,
+		0xF6, 0xE2, 0x8A, 0x83, 0xCC, 0xB8, 0xF6, 0xE2,
+		0x8A, 0x86, 0xCC, 0xB8, 0xF6, 0xE2, 0x8A, 0x87,
+		0xCC, 0xB8, 0xF6, 0xE2, 0x8A, 0xA2, 0xCC, 0xB8,
+		0xF6, 0xE2, 0x8A, 0xA8, 0xCC, 0xB8, 0xF6, 0xE2,
+		0x8A, 0xA9, 0xCC, 0xB8, 0xF6, 0xE2, 0x8A, 0xAB,
+		0xCC, 0xB8, 0xF6, 0xE2, 0x89, 0xBC, 0xCC, 0xB8,
+		0xF6, 0xE2, 0x89, 0xBD, 0xCC, 0xB8, 0xF6, 0xE2,
+		0x8A, 0x91, 0xCC, 0xB8, 0xF6, 0xE2, 0x8A, 0x92,
+		0xCC, 0xB8, 0xF6, 0xE2, 0x8A, 0xB2, 0xCC, 0xB8,
+		0xF6, 0xE2, 0x8A, 0xB3, 0xCC, 0xB8, 0xF6, 0xE2,
+		0x8A, 0xB4, 0xCC, 0xB8, 0xF6, 0xE2, 0x8A, 0xB5,
+		0xCC, 0xB8, 0xF6, 0xE3, 0x80, 0x88, 0xF6, 0xE3,
+		0x80, 0x89, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36,
+		0x37, 0x38, 0x39, 0x31, 0x30, 0x31, 0x31, 0x31,
+		0x32, 0x31, 0x33, 0x31, 0x34, 0x31, 0x35, 0x31,
+		0x36, 0x31, 0x37, 0x31, 0x38, 0x31, 0x39, 0x32,
+		0x30, 0x28, 0x31, 0x29, 0x28, 0x32, 0x29, 0x28,
+		0x33, 0x29, 0x28, 0x34, 0x29, 0x28, 0x35, 0x29,
+		0x28, 0x36, 0x29, 0x28, 0x37, 0x29, 0x28, 0x38,
+		0x29, 0x28, 0x39, 0x29, 0x28, 0x31, 0x30, 0x29,
+		0x28, 0x31, 0x31, 0x29, 0x28, 0x31, 0x32, 0x29,
+		0x28, 0x31, 0x33, 0x29, 0x28, 0x31, 0x34, 0x29,
+		0x28, 0x31, 0x35, 0x29, 0x28, 0x31, 0x36, 0x29,
+		0x28, 0x31, 0x37, 0x29, 0x28, 0x31, 0x38, 0x29,
+		0x28, 0x31, 0x39, 0x29, 0x28, 0x32, 0x30, 0x29,
+		0x31, 0x2E, 0x32, 0x2E, 0x33, 0x2E, 0x34, 0x2E,
+		0x35, 0x2E, 0x36, 0x2E, 0x37, 0x2E, 0x38, 0x2E,
+		0x39, 0x2E, 0x31, 0x30, 0x2E, 0x31, 0x31, 0x2E,
+		0x31, 0x32, 0x2E, 0x31, 0x33, 0x2E, 0x31, 0x34,
+		0x2E, 0x31, 0x35, 0x2E, 0x31, 0x36, 0x2E, 0x31,
+		0x37, 0x2E, 0x31, 0x38, 0x2E, 0x31, 0x39, 0x2E,
+		0x32, 0x30, 0x2E, 0x28, 0x61, 0x29, 0x28, 0x62,
+		0x29, 0x28, 0x63, 0x29, 0x28, 0x64, 0x29, 0x28,
+		0x65, 0x29, 0x28, 0x66, 0x29, 0x28, 0x67, 0x29,
+		0x28, 0x68, 0x29, 0x28, 0x69, 0x29, 0x28, 0x6A,
+		0x29, 0x28, 0x6B, 0x29, 0x28, 0x6C, 0x29, 0x28,
+		0x6D, 0x29, 0x28, 0x6E, 0x29, 0x28, 0x6F, 0x29,
+		0x28, 0x70, 0x29, 0x28, 0x71, 0x29, 0x28, 0x72,
+		0x29, 0x28, 0x73, 0x29, 0x28, 0x74, 0x29, 0x28,
+		0x75, 0x29, 0x28, 0x76, 0x29, 0x28, 0x77, 0x29,
+		0x28, 0x78, 0x29, 0x28, 0x79, 0x29, 0x28, 0x7A,
+		0x29, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
+		0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
+		0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
+		0x58, 0x59, 0x5A, 0x61, 0x62, 0x63, 0x64, 0x65,
+		0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D,
+		0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75,
+		0x76, 0x77, 0x78, 0x79, 0x7A, 0x30, 0xE2, 0x88,
+		0xAB, 0xE2, 0x88, 0xAB, 0xE2, 0x88, 0xAB, 0xE2,
+		0x88, 0xAB, 0x3A, 0x3A, 0x3D, 0x3D, 0x3D, 0x3D,
+		0x3D, 0x3D, 0xF6, 0xE2, 0xAB, 0x9D, 0xCC, 0xB8,
+		0xE2, 0xB5, 0xA1, 0xE6, 0xAF, 0x8D, 0xE9, 0xBE,
+		0x9F, 0xE4, 0xB8, 0x80, 0xE4, 0xB8, 0xA8, 0xE4,
+		0xB8, 0xB6, 0xE4, 0xB8, 0xBF, 0xE4, 0xB9, 0x99,
+		0xE4, 0xBA, 0x85, 0xE4, 0xBA, 0x8C, 0xE4, 0xBA,
+		0xA0, 0xE4, 0xBA, 0xBA, 0xE5, 0x84, 0xBF, 0xE5,
+		0x85, 0xA5, 0xE5, 0x85, 0xAB, 0xE5, 0x86, 0x82,
+		0xE5, 0x86, 0x96, 0xE5, 0x86, 0xAB, 0xE5, 0x87,
+		0xA0, 0xE5, 0x87, 0xB5, 0xE5, 0x88, 0x80, 0xE5,
+		0x8A, 0x9B, 0xE5, 0x8B, 0xB9, 0xE5, 0x8C, 0x95,
+		0xE5, 0x8C, 0x9A, 0xE5, 0x8C, 0xB8, 0xE5, 0x8D,
+		0x81, 0xE5, 0x8D, 0x9C, 0xE5, 0x8D, 0xA9, 0xE5,
+		0x8E, 0x82, 0xE5, 0x8E, 0xB6, 0xE5, 0x8F, 0x88,
+		0xE5, 0x8F, 0xA3, 0xE5, 0x9B, 0x97, 0xE5, 0x9C,
+		0x9F, 0xE5, 0xA3, 0xAB, 0xE5, 0xA4, 0x82, 0xE5,
+		0xA4, 0x8A, 0xE5, 0xA4, 0x95, 0xE5, 0xA4, 0xA7,
+		0xE5, 0xA5, 0xB3, 0xE5, 0xAD, 0x90, 0xE5, 0xAE,
+		0x80, 0xE5, 0xAF, 0xB8, 0xE5, 0xB0, 0x8F, 0xE5,
+		0xB0, 0xA2, 0xE5, 0xB0, 0xB8, 0xE5, 0xB1, 0xAE,
+		0xE5, 0xB1, 0xB1, 0xE5, 0xB7, 0x9B, 0xE5, 0xB7,
+		0xA5, 0xE5, 0xB7, 0xB1, 0xE5, 0xB7, 0xBE, 0xE5,
+		0xB9, 0xB2, 0xE5, 0xB9, 0xBA, 0xE5, 0xB9, 0xBF,
+		0xE5, 0xBB, 0xB4, 0xE5, 0xBB, 0xBE, 0xE5, 0xBC,
+		0x8B, 0xE5, 0xBC, 0x93, 0xE5, 0xBD, 0x90, 0xE5,
+		0xBD, 0xA1, 0xE5, 0xBD, 0xB3, 0xE5, 0xBF, 0x83,
+		0xE6, 0x88, 0x88, 0xE6, 0x88, 0xB6, 0xE6, 0x89,
+		0x8B, 0xE6, 0x94, 0xAF, 0xE6, 0x94, 0xB4, 0xE6,
+		0x96, 0x87, 0xE6, 0x96, 0x97, 0xE6, 0x96, 0xA4,
+		0xE6, 0x96, 0xB9, 0xE6, 0x97, 0xA0, 0xE6, 0x97,
+		0xA5, 0xE6, 0x9B, 0xB0, 0xE6, 0x9C, 0x88, 0xE6,
+		0x9C, 0xA8, 0xE6, 0xAC, 0xA0, 0xE6, 0xAD, 0xA2,
+		0xE6, 0xAD, 0xB9, 0xE6, 0xAE, 0xB3, 0xE6, 0xAF,
+		0x8B, 0xE6, 0xAF, 0x94, 0xE6, 0xAF, 0x9B, 0xE6,
+		0xB0, 0x8F, 0xE6, 0xB0, 0x94, 0xE6, 0xB0, 0xB4,
+		0xE7, 0x81, 0xAB, 0xE7, 0x88, 0xAA, 0xE7, 0x88,
+		0xB6, 0xE7, 0x88, 0xBB, 0xE7, 0x88, 0xBF, 0xE7,
+		0x89, 0x87, 0xE7, 0x89, 0x99, 0xE7, 0x89, 0x9B,
+		0xE7, 0x8A, 0xAC, 0xE7, 0x8E, 0x84, 0xE7, 0x8E,
+		0x89, 0xE7, 0x93, 0x9C, 0xE7, 0x93, 0xA6, 0xE7,
+		0x94, 0x98, 0xE7, 0x94, 0x9F, 0xE7, 0x94, 0xA8,
+		0xE7, 0x94, 0xB0, 0xE7, 0x96, 0x8B, 0xE7, 0x96,
+		0x92, 0xE7, 0x99, 0xB6, 0xE7, 0x99, 0xBD, 0xE7,
+		0x9A, 0xAE, 0xE7, 0x9A, 0xBF, 0xE7, 0x9B, 0xAE,
+		0xE7, 0x9F, 0x9B, 0xE7, 0x9F, 0xA2, 0xE7, 0x9F,
+		0xB3, 0xE7, 0xA4, 0xBA, 0xE7, 0xA6, 0xB8, 0xE7,
+		0xA6, 0xBE, 0xE7, 0xA9, 0xB4, 0xE7, 0xAB, 0x8B,
+		0xE7, 0xAB, 0xB9, 0xE7, 0xB1, 0xB3, 0xE7, 0xB3,
+		0xB8, 0xE7, 0xBC, 0xB6, 0xE7, 0xBD, 0x91, 0xE7,
+		0xBE, 0x8A, 0xE7, 0xBE, 0xBD, 0xE8, 0x80, 0x81,
+		0xE8, 0x80, 0x8C, 0xE8, 0x80, 0x92, 0xE8, 0x80,
+		0xB3, 0xE8, 0x81, 0xBF, 0xE8, 0x82, 0x89, 0xE8,
+		0x87, 0xA3, 0xE8, 0x87, 0xAA, 0xE8, 0x87, 0xB3,
+		0xE8, 0x87, 0xBC, 0xE8, 0x88, 0x8C, 0xE8, 0x88,
+		0x9B, 0xE8, 0x88, 0x9F, 0xE8, 0x89, 0xAE, 0xE8,
+		0x89, 0xB2, 0xE8, 0x89, 0xB8, 0xE8, 0x99, 0x8D,
+		0xE8, 0x99, 0xAB, 0xE8, 0xA1, 0x80, 0xE8, 0xA1,
+		0x8C, 0xE8, 0xA1, 0xA3, 0xE8, 0xA5, 0xBE, 0xE8,
+		0xA6, 0x8B, 0xE8, 0xA7, 0x92, 0xE8, 0xA8, 0x80,
+		0xE8, 0xB0, 0xB7, 0xE8, 0xB1, 0x86, 0xE8, 0xB1,
+		0x95, 0xE8, 0xB1, 0xB8, 0xE8, 0xB2, 0x9D, 0xE8,
+		0xB5, 0xA4, 0xE8, 0xB5, 0xB0, 0xE8, 0xB6, 0xB3,
+		0xE8, 0xBA, 0xAB, 0xE8, 0xBB, 0x8A, 0xE8, 0xBE,
+		0x9B, 0xE8, 0xBE, 0xB0, 0xE8, 0xBE, 0xB5, 0xE9,
+		0x82, 0x91, 0xE9, 0x85, 0x89, 0xE9, 0x87, 0x86,
+		0xE9, 0x87, 0x8C, 0xE9, 0x87, 0x91, 0xE9, 0x95,
+		0xB7, 0xE9, 0x96, 0x80, 0xE9, 0x98, 0x9C, 0xE9,
+		0x9A, 0xB6, 0xE9, 0x9A, 0xB9, 0xE9, 0x9B, 0xA8,
+		0xE9, 0x9D, 0x91, 0xE9, 0x9D, 0x9E, 0xE9, 0x9D,
+		0xA2, 0xE9, 0x9D, 0xA9, 0xE9, 0x9F, 0x8B, 0xE9,
+		0x9F, 0xAD, 0xE9, 0x9F, 0xB3, 0xE9, 0xA0, 0x81,
+		0xE9, 0xA2, 0xA8, 0xE9, 0xA3, 0x9B, 0xE9, 0xA3,
+		0x9F, 0xE9, 0xA6, 0x96, 0xE9, 0xA6, 0x99, 0xE9,
+		0xA6, 0xAC, 0xE9, 0xAA, 0xA8, 0xE9, 0xAB, 0x98,
+		0xE9, 0xAB, 0x9F, 0xE9, 0xAC, 0xA5, 0xE9, 0xAC,
+		0xAF, 0xE9, 0xAC, 0xB2, 0xE9, 0xAC, 0xBC, 0xE9,
+		0xAD, 0x9A, 0xE9, 0xB3, 0xA5, 0xE9, 0xB9, 0xB5,
+		0xE9, 0xB9, 0xBF, 0xE9, 0xBA, 0xA5, 0xE9, 0xBA,
+		0xBB, 0xE9, 0xBB, 0x83, 0xE9, 0xBB, 0x8D, 0xE9,
+		0xBB, 0x91, 0xE9, 0xBB, 0xB9, 0xE9, 0xBB, 0xBD,
+		0xE9, 0xBC, 0x8E, 0xE9, 0xBC, 0x93, 0xE9, 0xBC,
+		0xA0, 0xE9, 0xBC, 0xBB, 0xE9, 0xBD, 0x8A, 0xE9,
+		0xBD, 0x92, 0xE9, 0xBE, 0x8D, 0xE9, 0xBE, 0x9C,
+		0xE9, 0xBE, 0xA0, 0x20, 0xE3, 0x80, 0x92, 0xE5,
+		0x8D, 0x81, 0xE5, 0x8D, 0x84, 0xE5, 0x8D, 0x85,
+		0xF6, 0xE3, 0x81, 0x8B, 0xE3, 0x82, 0x99, 0xF6,
+		0xE3, 0x81, 0x8D, 0xE3, 0x82, 0x99, 0xF6, 0xE3,
+		0x81, 0x8F, 0xE3, 0x82, 0x99, 0xF6, 0xE3, 0x81,
+		0x91, 0xE3, 0x82, 0x99, 0xF6, 0xE3, 0x81, 0x93,
+		0xE3, 0x82, 0x99, 0xF6, 0xE3, 0x81, 0x95, 0xE3,
+		0x82, 0x99, 0xF6, 0xE3, 0x81, 0x97, 0xE3, 0x82,
+		0x99, 0xF6, 0xE3, 0x81, 0x99, 0xE3, 0x82, 0x99,
+		0xF6, 0xE3, 0x81, 0x9B, 0xE3, 0x82, 0x99, 0xF6,
+		0xE3, 0x81, 0x9D, 0xE3, 0x82, 0x99, 0xF6, 0xE3,
+		0x81, 0x9F, 0xE3, 0x82, 0x99, 0xF6, 0xE3, 0x81,
+		0xA1, 0xE3, 0x82, 0x99, 0xF6, 0xE3, 0x81, 0xA4,
+		0xE3, 0x82, 0x99, 0xF6, 0xE3, 0x81, 0xA6, 0xE3,
+		0x82, 0x99, 0xF6, 0xE3, 0x81, 0xA8, 0xE3, 0x82,
+		0x99, 0xF6, 0xE3, 0x81, 0xAF, 0xE3, 0x82, 0x99,
+		0xF6, 0xE3, 0x81, 0xAF, 0xE3, 0x82, 0x9A, 0xF6,
+		0xE3, 0x81, 0xB2, 0xE3, 0x82, 0x99, 0xF6, 0xE3,
+		0x81, 0xB2, 0xE3, 0x82, 0x9A, 0xF6, 0xE3, 0x81,
+		0xB5, 0xE3, 0x82, 0x99, 0xF6, 0xE3, 0x81, 0xB5,
+		0xE3, 0x82, 0x9A, 0xF6, 0xE3, 0x81, 0xB8, 0xE3,
+		0x82, 0x99, 0xF6, 0xE3, 0x81, 0xB8, 0xE3, 0x82,
+		0x9A, 0xF6, 0xE3, 0x81, 0xBB, 0xE3, 0x82, 0x99,
+		0xF6, 0xE3, 0x81, 0xBB, 0xE3, 0x82, 0x9A, 0xF6,
+		0xE3, 0x81, 0x86, 0xE3, 0x82, 0x99, 0x20, 0xE3,
+		0x82, 0x99, 0x20, 0xE3, 0x82, 0x9A, 0xF6, 0xE3,
+		0x82, 0x9D, 0xE3, 0x82, 0x99, 0xE3, 0x82, 0x88,
+		0xE3, 0x82, 0x8A, 0xF6, 0xE3, 0x82, 0xAB, 0xE3,
+		0x82, 0x99, 0xF6, 0xE3, 0x82, 0xAD, 0xE3, 0x82,
+		0x99, 0xF6, 0xE3, 0x82, 0xAF, 0xE3, 0x82, 0x99,
+		0xF6, 0xE3, 0x82, 0xB1, 0xE3, 0x82, 0x99, 0xF6,
+		0xE3, 0x82, 0xB3, 0xE3, 0x82, 0x99, 0xF6, 0xE3,
+		0x82, 0xB5, 0xE3, 0x82, 0x99, 0xF6, 0xE3, 0x82,
+		0xB7, 0xE3, 0x82, 0x99, 0xF6, 0xE3, 0x82, 0xB9,
+		0xE3, 0x82, 0x99, 0xF6, 0xE3, 0x82, 0xBB, 0xE3,
+		0x82, 0x99, 0xF6, 0xE3, 0x82, 0xBD, 0xE3, 0x82,
+		0x99, 0xF6, 0xE3, 0x82, 0xBF, 0xE3, 0x82, 0x99,
+		0xF6, 0xE3, 0x83, 0x81, 0xE3, 0x82, 0x99, 0xF6,
+		0xE3, 0x83, 0x84, 0xE3, 0x82, 0x99, 0xF6, 0xE3,
+		0x83, 0x86, 0xE3, 0x82, 0x99, 0xF6, 0xE3, 0x83,
+		0x88, 0xE3, 0x82, 0x99, 0xF6, 0xE3, 0x83, 0x8F,
+		0xE3, 0x82, 0x99, 0xF6, 0xE3, 0x83, 0x8F, 0xE3,
+		0x82, 0x9A, 0xF6, 0xE3, 0x83, 0x92, 0xE3, 0x82,
+		0x99, 0xF6, 0xE3, 0x83, 0x92, 0xE3, 0x82, 0x9A,
+		0xF6, 0xE3, 0x83, 0x95, 0xE3, 0x82, 0x99, 0xF6,
+		0xE3, 0x83, 0x95, 0xE3, 0x82, 0x9A, 0xF6, 0xE3,
+		0x83, 0x98, 0xE3, 0x82, 0x99, 0xF6, 0xE3, 0x83,
+		0x98, 0xE3, 0x82, 0x9A, 0xF6, 0xE3, 0x83, 0x9B,
+		0xE3, 0x82, 0x99, 0xF6, 0xE3, 0x83, 0x9B, 0xE3,
+		0x82, 0x9A, 0xF6, 0xE3, 0x82, 0xA6, 0xE3, 0x82,
+		0x99, 0xF6, 0xE3, 0x83, 0xAF, 0xE3, 0x82, 0x99,
+		0xF6, 0xE3, 0x83, 0xB0, 0xE3, 0x82, 0x99, 0xF6,
+		0xE3, 0x83, 0xB1, 0xE3, 0x82, 0x99, 0xF6, 0xE3,
+		0x83, 0xB2, 0xE3, 0x82, 0x99, 0xF6, 0xE3, 0x83,
+		0xBD, 0xE3, 0x82, 0x99, 0xE3, 0x82, 0xB3, 0xE3,
+		0x83, 0x88, 0xE1, 0x84, 0x80, 0xE1, 0x84, 0x81,
+		0xE1, 0x86, 0xAA, 0xE1, 0x84, 0x82, 0xE1, 0x86,
+		0xAC, 0xE1, 0x86, 0xAD, 0xE1, 0x84, 0x83, 0xE1,
+		0x84, 0x84, 0xE1, 0x84, 0x85, 0xE1, 0x86, 0xB0,
+		0xE1, 0x86, 0xB1, 0xE1, 0x86, 0xB2, 0xE1, 0x86,
+		0xB3, 0xE1, 0x86, 0xB4, 0xE1, 0x86, 0xB5, 0xE1,
+		0x84, 0x9A, 0xE1, 0x84, 0x86, 0xE1, 0x84, 0x87,
+		0xE1, 0x84, 0x88, 0xE1, 0x84, 0xA1, 0xE1, 0x84,
+		0x89, 0xE1, 0x84, 0x8A, 0xE1, 0x84, 0x8B, 0xE1,
+		0x84, 0x8C, 0xE1, 0x84, 0x8D, 0xE1, 0x84, 0x8E,
+		0xE1, 0x84, 0x8F, 0xE1, 0x84, 0x90, 0xE1, 0x84,
+		0x91, 0xE1, 0x84, 0x92, 0xE1, 0x85, 0xA1, 0xE1,
+		0x85, 0xA2, 0xE1, 0x85, 0xA3, 0xE1, 0x85, 0xA4,
+		0xE1, 0x85, 0xA5, 0xE1, 0x85, 0xA6, 0xE1, 0x85,
+		0xA7, 0xE1, 0x85, 0xA8, 0xE1, 0x85, 0xA9, 0xE1,
+		0x85, 0xAA, 0xE1, 0x85, 0xAB, 0xE1, 0x85, 0xAC,
+		0xE1, 0x85, 0xAD, 0xE1, 0x85, 0xAE, 0xE1, 0x85,
+		0xAF, 0xE1, 0x85, 0xB0, 0xE1, 0x85, 0xB1, 0xE1,
+		0x85, 0xB2, 0xE1, 0x85, 0xB3, 0xE1, 0x85, 0xB4,
+		0xE1, 0x85, 0xB5, 0xE1, 0x85, 0xA0, 0xE1, 0x84,
+		0x94, 0xE1, 0x84, 0x95, 0xE1, 0x87, 0x87, 0xE1,
+		0x87, 0x88, 0xE1, 0x87, 0x8C, 0xE1, 0x87, 0x8E,
+		0xE1, 0x87, 0x93, 0xE1, 0x87, 0x97, 0xE1, 0x87,
+		0x99, 0xE1, 0x84, 0x9C, 0xE1, 0x87, 0x9D, 0xE1,
+		0x87, 0x9F, 0xE1, 0x84, 0x9D, 0xE1, 0x84, 0x9E,
+		0xE1, 0x84, 0xA0, 0xE1, 0x84, 0xA2, 0xE1, 0x84,
+		0xA3, 0xE1, 0x84, 0xA7, 0xE1, 0x84, 0xA9, 0xE1,
+		0x84, 0xAB, 0xE1, 0x84, 0xAC, 0xE1, 0x84, 0xAD,
+		0xE1, 0x84, 0xAE, 0xE1, 0x84, 0xAF, 0xE1, 0x84,
+		0xB2, 0xE1, 0x84, 0xB6, 0xE1, 0x85, 0x80, 0xE1,
+		0x85, 0x87, 0xE1, 0x85, 0x8C, 0xE1, 0x87, 0xB1,
+		0xE1, 0x87, 0xB2, 0xE1, 0x85, 0x97, 0xE1, 0x85,
+		0x98, 0xE1, 0x85, 0x99, 0xE1, 0x86, 0x84, 0xE1,
+		0x86, 0x85, 0xE1, 0x86, 0x88, 0xE1, 0x86, 0x91,
+		0xE1, 0x86, 0x92, 0xE1, 0x86, 0x94, 0xE1, 0x86,
+		0x9E, 0xE1, 0x86, 0xA1, 0xE4, 0xB8, 0x80, 0xE4,
+		0xBA, 0x8C, 0xE4, 0xB8, 0x89, 0xE5, 0x9B, 0x9B,
+		0xE4, 0xB8, 0x8A, 0xE4, 0xB8, 0xAD, 0xE4, 0xB8,
+		0x8B, 0xE7, 0x94, 0xB2, 0xE4, 0xB9, 0x99, 0xE4,
+		0xB8, 0x99, 0xE4, 0xB8, 0x81, 0xE5, 0xA4, 0xA9,
+		0xE5, 0x9C, 0xB0, 0xE4, 0xBA, 0xBA, 0x28, 0xE1,
+		0x84, 0x80, 0x29, 0x28, 0xE1, 0x84, 0x82, 0x29,
+		0x28, 0xE1, 0x84, 0x83, 0x29, 0x28, 0xE1, 0x84,
+		0x85, 0x29, 0x28, 0xE1, 0x84, 0x86, 0x29, 0x28,
+		0xE1, 0x84, 0x87, 0x29, 0x28, 0xE1, 0x84, 0x89,
+		0x29, 0x28, 0xE1, 0x84, 0x8B, 0x29, 0x28, 0xE1,
+		0x84, 0x8C, 0x29, 0x28, 0xE1, 0x84, 0x8E, 0x29,
+		0x28, 0xE1, 0x84, 0x8F, 0x29, 0x28, 0xE1, 0x84,
+		0x90, 0x29, 0x28, 0xE1, 0x84, 0x91, 0x29, 0x28,
+		0xE1, 0x84, 0x92, 0x29, 0x28, 0xE1, 0x84, 0x80,
+		0xE1, 0x85, 0xA1, 0x29, 0x28, 0xE1, 0x84, 0x82,
+		0xE1, 0x85, 0xA1, 0x29, 0x28, 0xE1, 0x84, 0x83,
+		0xE1, 0x85, 0xA1, 0x29, 0x28, 0xE1, 0x84, 0x85,
+		0xE1, 0x85, 0xA1, 0x29, 0x28, 0xE1, 0x84, 0x86,
+		0xE1, 0x85, 0xA1, 0x29, 0x28, 0xE1, 0x84, 0x87,
+		0xE1, 0x85, 0xA1, 0x29, 0x28, 0xE1, 0x84, 0x89,
+		0xE1, 0x85, 0xA1, 0x29, 0x28, 0xE1, 0x84, 0x8B,
+		0xE1, 0x85, 0xA1, 0x29, 0x28, 0xE1, 0x84, 0x8C,
+		0xE1, 0x85, 0xA1, 0x29, 0x28, 0xE1, 0x84, 0x8E,
+		0xE1, 0x85, 0xA1, 0x29, 0x28, 0xE1, 0x84, 0x8F,
+		0xE1, 0x85, 0xA1, 0x29, 0x28, 0xE1, 0x84, 0x90,
+		0xE1, 0x85, 0xA1, 0x29, 0x28, 0xE1, 0x84, 0x91,
+		0xE1, 0x85, 0xA1, 0x29, 0x28, 0xE1, 0x84, 0x92,
+		0xE1, 0x85, 0xA1, 0x29, 0x28, 0xE1, 0x84, 0x8C,
+		0xE1, 0x85, 0xAE, 0x29, 0x28, 0xE1, 0x84, 0x8B,
+		0xE1, 0x85, 0xA9, 0xE1, 0x84, 0x8C, 0xE1, 0x85,
+		0xA5, 0xE1, 0x86, 0xAB, 0x29, 0x28, 0xE1, 0x84,
+		0x8B, 0xE1, 0x85, 0xA9, 0xE1, 0x84, 0x92, 0xE1,
+		0x85, 0xAE, 0x29, 0x28, 0xE4, 0xB8, 0x80, 0x29,
+		0x28, 0xE4, 0xBA, 0x8C, 0x29, 0x28, 0xE4, 0xB8,
+		0x89, 0x29, 0x28, 0xE5, 0x9B, 0x9B, 0x29, 0x28,
+		0xE4, 0xBA, 0x94, 0x29, 0x28, 0xE5, 0x85, 0xAD,
+		0x29, 0x28, 0xE4, 0xB8, 0x83, 0x29, 0x28, 0xE5,
+		0x85, 0xAB, 0x29, 0x28, 0xE4, 0xB9, 0x9D, 0x29,
+		0x28, 0xE5, 0x8D, 0x81, 0x29, 0x28, 0xE6, 0x9C,
+		0x88, 0x29, 0x28, 0xE7, 0x81, 0xAB, 0x29, 0x28,
+		0xE6, 0xB0, 0xB4, 0x29, 0x28, 0xE6, 0x9C, 0xA8,
+		0x29, 0x28, 0xE9, 0x87, 0x91, 0x29, 0x28, 0xE5,
+		0x9C, 0x9F, 0x29, 0x28, 0xE6, 0x97, 0xA5, 0x29,
+		0x28, 0xE6, 0xA0, 0xAA, 0x29, 0x28, 0xE6, 0x9C,
+		0x89, 0x29, 0x28, 0xE7, 0xA4, 0xBE, 0x29, 0x28,
+		0xE5, 0x90, 0x8D, 0x29, 0x28, 0xE7, 0x89, 0xB9,
+		0x29, 0x28, 0xE8, 0xB2, 0xA1, 0x29, 0x28, 0xE7,
+		0xA5, 0x9D, 0x29, 0x28, 0xE5, 0x8A, 0xB4, 0x29,
+		0x28, 0xE4, 0xBB, 0xA3, 0x29, 0x28, 0xE5, 0x91,
+		0xBC, 0x29, 0x28, 0xE5, 0xAD, 0xA6, 0x29, 0x28,
+		0xE7, 0x9B, 0xA3, 0x29, 0x28, 0xE4, 0xBC, 0x81,
+		0x29, 0x28, 0xE8, 0xB3, 0x87, 0x29, 0x28, 0xE5,
+		0x8D, 0x94, 0x29, 0x28, 0xE7, 0xA5, 0xAD, 0x29,
+		0x28, 0xE4, 0xBC, 0x91, 0x29, 0x28, 0xE8, 0x87,
+		0xAA, 0x29, 0x28, 0xE8, 0x87, 0xB3, 0x29, 0x50,
+		0x54, 0x45, 0x32, 0x31, 0x32, 0x32, 0x32, 0x33,
+		0x32, 0x34, 0x32, 0x35, 0x32, 0x36, 0x32, 0x37,
+		0x32, 0x38, 0x32, 0x39, 0x33, 0x30, 0x33, 0x31,
+		0x33, 0x32, 0x33, 0x33, 0x33, 0x34, 0x33, 0x35,
+		0xE1, 0x84, 0x80, 0xE1, 0x84, 0x82, 0xE1, 0x84,
+		0x83, 0xE1, 0x84, 0x85, 0xE1, 0x84, 0x86, 0xE1,
+		0x84, 0x87, 0xE1, 0x84, 0x89, 0xE1, 0x84, 0x8B,
+		0xE1, 0x84, 0x8C, 0xE1, 0x84, 0x8E, 0xE1, 0x84,
+		0x8F, 0xE1, 0x84, 0x90, 0xE1, 0x84, 0x91, 0xE1,
+		0x84, 0x92, 0xE1, 0x84, 0x80, 0xE1, 0x85, 0xA1,
+		0xE1, 0x84, 0x82, 0xE1, 0x85, 0xA1, 0xE1, 0x84,
+		0x83, 0xE1, 0x85, 0xA1, 0xE1, 0x84, 0x85, 0xE1,
+		0x85, 0xA1, 0xE1, 0x84, 0x86, 0xE1, 0x85, 0xA1,
+		0xE1, 0x84, 0x87, 0xE1, 0x85, 0xA1, 0xE1, 0x84,
+		0x89, 0xE1, 0x85, 0xA1, 0xE1, 0x84, 0x8B, 0xE1,
+		0x85, 0xA1, 0xE1, 0x84, 0x8C, 0xE1, 0x85, 0xA1,
+		0xE1, 0x84, 0x8E, 0xE1, 0x85, 0xA1, 0xE1, 0x84,
+		0x8F, 0xE1, 0x85, 0xA1, 0xE1, 0x84, 0x90, 0xE1,
+		0x85, 0xA1, 0xE1, 0x84, 0x91, 0xE1, 0x85, 0xA1,
+		0xE1, 0x84, 0x92, 0xE1, 0x85, 0xA1, 0xE1, 0x84,
+		0x8E, 0xE1, 0x85, 0xA1, 0xE1, 0x86, 0xB7, 0xE1,
+		0x84, 0x80, 0xE1, 0x85, 0xA9, 0xE1, 0x84, 0x8C,
+		0xE1, 0x85, 0xAE, 0xE1, 0x84, 0x8B, 0xE1, 0x85,
+		0xB4, 0xE1, 0x84, 0x8B, 0xE1, 0x85, 0xAE, 0xE4,
+		0xB8, 0x80, 0xE4, 0xBA, 0x8C, 0xE4, 0xB8, 0x89,
+		0xE5, 0x9B, 0x9B, 0xE4, 0xBA, 0x94, 0xE5, 0x85,
+		0xAD, 0xE4, 0xB8, 0x83, 0xE5, 0x85, 0xAB, 0xE4,
+		0xB9, 0x9D, 0xE5, 0x8D, 0x81, 0xE6, 0x9C, 0x88,
+		0xE7, 0x81, 0xAB, 0xE6, 0xB0, 0xB4, 0xE6, 0x9C,
+		0xA8, 0xE9, 0x87, 0x91, 0xE5, 0x9C, 0x9F, 0xE6,
+		0x97, 0xA5, 0xE6, 0xA0, 0xAA, 0xE6, 0x9C, 0x89,
+		0xE7, 0xA4, 0xBE, 0xE5, 0x90, 0x8D, 0xE7, 0x89,
+		0xB9, 0xE8, 0xB2, 0xA1, 0xE7, 0xA5, 0x9D, 0xE5,
+		0x8A, 0xB4, 0xE7, 0xA7, 0x98, 0xE7, 0x94, 0xB7,
+		0xE5, 0xA5, 0xB3, 0xE9, 0x81, 0xA9, 0xE5, 0x84,
+		0xAA, 0xE5, 0x8D, 0xB0, 0xE6, 0xB3, 0xA8, 0xE9,
+		0xA0, 0x85, 0xE4, 0xBC, 0x91, 0xE5, 0x86, 0x99,
+		0xE6, 0xAD, 0xA3, 0xE4, 0xB8, 0x8A, 0xE4, 0xB8,
+		0xAD, 0xE4, 0xB8, 0x8B, 0xE5, 0xB7, 0xA6, 0xE5,
+		0x8F, 0xB3, 0xE5, 0x8C, 0xBB, 0xE5, 0xAE, 0x97,
+		0xE5, 0xAD, 0xA6, 0xE7, 0x9B, 0xA3, 0xE4, 0xBC,
+		0x81, 0xE8, 0xB3, 0x87, 0xE5, 0x8D, 0x94, 0xE5,
+		0xA4, 0x9C, 0x33, 0x36, 0x33, 0x37, 0x33, 0x38,
+		0x33, 0x39, 0x34, 0x30, 0x34, 0x31, 0x34, 0x32,
+		0x34, 0x33, 0x34, 0x34, 0x34, 0x35, 0x34, 0x36,
+		0x34, 0x37, 0x34, 0x38, 0x34, 0x39, 0x35, 0x30,
+		0x31, 0xE6, 0x9C, 0x88, 0x32, 0xE6, 0x9C, 0x88,
+		0x33, 0xE6, 0x9C, 0x88, 0x34, 0xE6, 0x9C, 0x88,
+		0x35, 0xE6, 0x9C, 0x88, 0x36, 0xE6, 0x9C, 0x88,
+		0x37, 0xE6, 0x9C, 0x88, 0x38, 0xE6, 0x9C, 0x88,
+		0x39, 0xE6, 0x9C, 0x88, 0x31, 0x30, 0xE6, 0x9C,
+		0x88, 0x31, 0x31, 0xE6, 0x9C, 0x88, 0x31, 0x32,
+		0xE6, 0x9C, 0x88, 0x48, 0x67, 0x65, 0x72, 0x67,
+		0x65, 0x56, 0x4C, 0x54, 0x44, 0xE3, 0x82, 0xA2,
+		0xE3, 0x82, 0xA4, 0xE3, 0x82, 0xA6, 0xE3, 0x82,
+		0xA8, 0xE3, 0x82, 0xAA, 0xE3, 0x82, 0xAB, 0xE3,
+		0x82, 0xAD, 0xE3, 0x82, 0xAF, 0xE3, 0x82, 0xB1,
+		0xE3, 0x82, 0xB3, 0xE3, 0x82, 0xB5, 0xE3, 0x82,
+		0xB7, 0xE3, 0x82, 0xB9, 0xE3, 0x82, 0xBB, 0xE3,
+		0x82, 0xBD, 0xE3, 0x82, 0xBF, 0xE3, 0x83, 0x81,
+		0xE3, 0x83, 0x84, 0xE3, 0x83, 0x86, 0xE3, 0x83,
+		0x88, 0xE3, 0x83, 0x8A, 0xE3, 0x83, 0x8B, 0xE3,
+		0x83, 0x8C, 0xE3, 0x83, 0x8D, 0xE3, 0x83, 0x8E,
+		0xE3, 0x83, 0x8F, 0xE3, 0x83, 0x92, 0xE3, 0x83,
+		0x95, 0xE3, 0x83, 0x98, 0xE3, 0x83, 0x9B, 0xE3,
+		0x83, 0x9E, 0xE3, 0x83, 0x9F, 0xE3, 0x83, 0xA0,
+		0xE3, 0x83, 0xA1, 0xE3, 0x83, 0xA2, 0xE3, 0x83,
+		0xA4, 0xE3, 0x83, 0xA6, 0xE3, 0x83, 0xA8, 0xE3,
+		0x83, 0xA9, 0xE3, 0x83, 0xAA, 0xE3, 0x83, 0xAB,
+		0xE3, 0x83, 0xAC, 0xE3, 0x83, 0xAD, 0xE3, 0x83,
+		0xAF, 0xE3, 0x83, 0xB0, 0xE3, 0x83, 0xB1, 0xE3,
+		0x83, 0xB2, 0xE3, 0x82, 0xA2, 0xE3, 0x83, 0x8F,
+		0xE3, 0x82, 0x9A, 0xE3, 0x83, 0xBC, 0xE3, 0x83,
+		0x88, 0xE3, 0x82, 0xA2, 0xE3, 0x83, 0xAB, 0xE3,
+		0x83, 0x95, 0xE3, 0x82, 0xA1, 0xE3, 0x82, 0xA2,
+		0xE3, 0x83, 0xB3, 0xE3, 0x83, 0x98, 0xE3, 0x82,
+		0x9A, 0xE3, 0x82, 0xA2, 0xE3, 0x82, 0xA2, 0xE3,
+		0x83, 0xBC, 0xE3, 0x83, 0xAB, 0xE3, 0x82, 0xA4,
+		0xE3, 0x83, 0x8B, 0xE3, 0x83, 0xB3, 0xE3, 0x82,
+		0xAF, 0xE3, 0x82, 0x99, 0xE3, 0x82, 0xA4, 0xE3,
+		0x83, 0xB3, 0xE3, 0x83, 0x81, 0xE3, 0x82, 0xA6,
+		0xE3, 0x82, 0xA9, 0xE3, 0x83, 0xB3, 0xE3, 0x82,
+		0xA8, 0xE3, 0x82, 0xB9, 0xE3, 0x82, 0xAF, 0xE3,
+		0x83, 0xBC, 0xE3, 0x83, 0x88, 0xE3, 0x82, 0x99,
+		0xE3, 0x82, 0xA8, 0xE3, 0x83, 0xBC, 0xE3, 0x82,
+		0xAB, 0xE3, 0x83, 0xBC, 0xE3, 0x82, 0xAA, 0xE3,
+		0x83, 0xB3, 0xE3, 0x82, 0xB9, 0xE3, 0x82, 0xAA,
+		0xE3, 0x83, 0xBC, 0xE3, 0x83, 0xA0, 0xE3, 0x82,
+		0xAB, 0xE3, 0x82, 0xA4, 0xE3, 0x83, 0xAA, 0xE3,
+		0x82, 0xAB, 0xE3, 0x83, 0xA9, 0xE3, 0x83, 0x83,
+		0xE3, 0x83, 0x88, 0xE3, 0x82, 0xAB, 0xE3, 0x83,
+		0xAD, 0xE3, 0x83, 0xAA, 0xE3, 0x83, 0xBC, 0xE3,
+		0x82, 0xAB, 0xE3, 0x82, 0x99, 0xE3, 0x83, 0xAD,
+		0xE3, 0x83, 0xB3, 0xE3, 0x82, 0xAB, 0xE3, 0x82,
+		0x99, 0xE3, 0x83, 0xB3, 0xE3, 0x83, 0x9E, 0xE3,
+		0x82, 0xAD, 0xE3, 0x82, 0x99, 0xE3, 0x82, 0xAB,
+		0xE3, 0x82, 0x99, 0xE3, 0x82, 0xAD, 0xE3, 0x82,
+		0x99, 0xE3, 0x83, 0x8B, 0xE3, 0x83, 0xBC, 0xE3,
+		0x82, 0xAD, 0xE3, 0x83, 0xA5, 0xE3, 0x83, 0xAA,
+		0xE3, 0x83, 0xBC, 0xE3, 0x82, 0xAD, 0xE3, 0x82,
+		0x99, 0xE3, 0x83, 0xAB, 0xE3, 0x82, 0xBF, 0xE3,
+		0x82, 0x99, 0xE3, 0x83, 0xBC, 0xE3, 0x82, 0xAD,
+		0xE3, 0x83, 0xAD, 0xE3, 0x82, 0xAD, 0xE3, 0x83,
+		0xAD, 0xE3, 0x82, 0xAF, 0xE3, 0x82, 0x99, 0xE3,
+		0x83, 0xA9, 0xE3, 0x83, 0xA0, 0xE3, 0x82, 0xAD,
+		0xE3, 0x83, 0xAD, 0xE3, 0x83, 0xA1, 0xE3, 0x83,
+		0xBC, 0xE3, 0x83, 0x88, 0xE3, 0x83, 0xAB, 0xE3,
+		0x82, 0xAD, 0xE3, 0x83, 0xAD, 0xE3, 0x83, 0xAF,
+		0xE3, 0x83, 0x83, 0xE3, 0x83, 0x88, 0xE3, 0x82,
+		0xAF, 0xE3, 0x82, 0x99, 0xE3, 0x83, 0xA9, 0xE3,
+		0x83, 0xA0, 0xE3, 0x82, 0xAF, 0xE3, 0x82, 0x99,
+		0xE3, 0x83, 0xA9, 0xE3, 0x83, 0xA0, 0xE3, 0x83,
+		0x88, 0xE3, 0x83, 0xB3, 0xE3, 0x82, 0xAF, 0xE3,
+		0x83, 0xAB, 0xE3, 0x82, 0xBB, 0xE3, 0x82, 0x99,
+		0xE3, 0x82, 0xA4, 0xE3, 0x83, 0xAD, 0xE3, 0x82,
+		0xAF, 0xE3, 0x83, 0xAD, 0xE3, 0x83, 0xBC, 0xE3,
+		0x83, 0x8D, 0xE3, 0x82, 0xB1, 0xE3, 0x83, 0xBC,
+		0xE3, 0x82, 0xB9, 0xE3, 0x82, 0xB3, 0xE3, 0x83,
+		0xAB, 0xE3, 0x83, 0x8A, 0xE3, 0x82, 0xB3, 0xE3,
+		0x83, 0xBC, 0xE3, 0x83, 0x9B, 0xE3, 0x82, 0x9A,
+		0xE3, 0x82, 0xB5, 0xE3, 0x82, 0xA4, 0xE3, 0x82,
+		0xAF, 0xE3, 0x83, 0xAB, 0xE3, 0x82, 0xB5, 0xE3,
+		0x83, 0xB3, 0xE3, 0x83, 0x81, 0xE3, 0x83, 0xBC,
+		0xE3, 0x83, 0xA0, 0xE3, 0x82, 0xB7, 0xE3, 0x83,
+		0xAA, 0xE3, 0x83, 0xB3, 0xE3, 0x82, 0xAF, 0xE3,
+		0x82, 0x99, 0xE3, 0x82, 0xBB, 0xE3, 0x83, 0xB3,
+		0xE3, 0x83, 0x81, 0xE3, 0x82, 0xBB, 0xE3, 0x83,
+		0xB3, 0xE3, 0x83, 0x88, 0xE3, 0x82, 0xBF, 0xE3,
+		0x82, 0x99, 0xE3, 0x83, 0xBC, 0xE3, 0x82, 0xB9,
+		0xE3, 0x83, 0x86, 0xE3, 0x82, 0x99, 0xE3, 0x82,
+		0xB7, 0xE3, 0x83, 0x88, 0xE3, 0x82, 0x99, 0xE3,
+		0x83, 0xAB, 0xE3, 0x83, 0x88, 0xE3, 0x83, 0xB3,
+		0xE3, 0x83, 0x8A, 0xE3, 0x83, 0x8E, 0xE3, 0x83,
+		0x8E, 0xE3, 0x83, 0x83, 0xE3, 0x83, 0x88, 0xE3,
+		0x83, 0x8F, 0xE3, 0x82, 0xA4, 0xE3, 0x83, 0x84,
+		0xE3, 0x83, 0x8F, 0xE3, 0x82, 0x9A, 0xE3, 0x83,
+		0xBC, 0xE3, 0x82, 0xBB, 0xE3, 0x83, 0xB3, 0xE3,
+		0x83, 0x88, 0xE3, 0x83, 0x8F, 0xE3, 0x82, 0x9A,
+		0xE3, 0x83, 0xBC, 0xE3, 0x83, 0x84, 0xE3, 0x83,
+		0x8F, 0xE3, 0x82, 0x99, 0xE3, 0x83, 0xBC, 0xE3,
+		0x83, 0xAC, 0xE3, 0x83, 0xAB, 0xE3, 0x83, 0x92,
+		0xE3, 0x82, 0x9A, 0xE3, 0x82, 0xA2, 0xE3, 0x82,
+		0xB9, 0xE3, 0x83, 0x88, 0xE3, 0x83, 0xAB, 0xE3,
+		0x83, 0x92, 0xE3, 0x82, 0x9A, 0xE3, 0x82, 0xAF,
+		0xE3, 0x83, 0xAB, 0xE3, 0x83, 0x92, 0xE3, 0x82,
+		0x9A, 0xE3, 0x82, 0xB3, 0xE3, 0x83, 0x92, 0xE3,
+		0x82, 0x99, 0xE3, 0x83, 0xAB, 0xE3, 0x83, 0x95,
+		0xE3, 0x82, 0xA1, 0xE3, 0x83, 0xA9, 0xE3, 0x83,
+		0x83, 0xE3, 0x83, 0x88, 0xE3, 0x82, 0x99, 0xE3,
+		0x83, 0x95, 0xE3, 0x82, 0xA3, 0xE3, 0x83, 0xBC,
+		0xE3, 0x83, 0x88, 0xE3, 0x83, 0x95, 0xE3, 0x82,
+		0x99, 0xE3, 0x83, 0x83, 0xE3, 0x82, 0xB7, 0xE3,
+		0x82, 0xA7, 0xE3, 0x83, 0xAB, 0xE3, 0x83, 0x95,
+		0xE3, 0x83, 0xA9, 0xE3, 0x83, 0xB3, 0xE3, 0x83,
+		0x98, 0xE3, 0x82, 0xAF, 0xE3, 0x82, 0xBF, 0xE3,
+		0x83, 0xBC, 0xE3, 0x83, 0xAB, 0xE3, 0x83, 0x98,
+		0xE3, 0x82, 0x9A, 0xE3, 0x82, 0xBD, 0xE3, 0x83,
+		0x98, 0xE3, 0x82, 0x9A, 0xE3, 0x83, 0x8B, 0xE3,
+		0x83, 0x92, 0xE3, 0x83, 0x98, 0xE3, 0x83, 0xAB,
+		0xE3, 0x83, 0x84, 0xE3, 0x83, 0x98, 0xE3, 0x82,
+		0x9A, 0xE3, 0x83, 0xB3, 0xE3, 0x82, 0xB9, 0xE3,
+		0x83, 0x98, 0xE3, 0x82, 0x9A, 0xE3, 0x83, 0xBC,
+		0xE3, 0x82, 0xB7, 0xE3, 0x82, 0x99, 0xE3, 0x83,
+		0x98, 0xE3, 0x82, 0x99, 0xE3, 0x83, 0xBC, 0xE3,
+		0x82, 0xBF, 0xE3, 0x83, 0x9B, 0xE3, 0x82, 0x9A,
+		0xE3, 0x82, 0xA4, 0xE3, 0x83, 0xB3, 0xE3, 0x83,
+		0x88, 0xE3, 0x83, 0x9B, 0xE3, 0x82, 0x99, 0xE3,
+		0x83, 0xAB, 0xE3, 0x83, 0x88, 0xE3, 0x83, 0x9B,
+		0xE3, 0x83, 0xB3, 0xE3, 0x83, 0x9B, 0xE3, 0x82,
+		0x9A, 0xE3, 0x83, 0xB3, 0xE3, 0x83, 0x88, 0xE3,
+		0x82, 0x99, 0xE3, 0x83, 0x9B, 0xE3, 0x83, 0xBC,
+		0xE3, 0x83, 0xAB, 0xE3, 0x83, 0x9B, 0xE3, 0x83,
+		0xBC, 0xE3, 0x83, 0xB3, 0xE3, 0x83, 0x9E, 0xE3,
+		0x82, 0xA4, 0xE3, 0x82, 0xAF, 0xE3, 0x83, 0xAD,
+		0xE3, 0x83, 0x9E, 0xE3, 0x82, 0xA4, 0xE3, 0x83,
+		0xAB, 0xE3, 0x83, 0x9E, 0xE3, 0x83, 0x83, 0xE3,
+		0x83, 0x8F, 0xE3, 0x83, 0x9E, 0xE3, 0x83, 0xAB,
+		0xE3, 0x82, 0xAF, 0xE3, 0x83, 0x9E, 0xE3, 0x83,
+		0xB3, 0xE3, 0x82, 0xB7, 0xE3, 0x83, 0xA7, 0xE3,
+		0x83, 0xB3, 0xE3, 0x83, 0x9F, 0xE3, 0x82, 0xAF,
+		0xE3, 0x83, 0xAD, 0xE3, 0x83, 0xB3, 0xE3, 0x83,
+		0x9F, 0xE3, 0x83, 0xAA, 0xE3, 0x83, 0x9F, 0xE3,
+		0x83, 0xAA, 0xE3, 0x83, 0x8F, 0xE3, 0x82, 0x99,
+		0xE3, 0x83, 0xBC, 0xE3, 0x83, 0xAB, 0xE3, 0x83,
+		0xA1, 0xE3, 0x82, 0xAB, 0xE3, 0x82, 0x99, 0xE3,
+		0x83, 0xA1, 0xE3, 0x82, 0xAB, 0xE3, 0x82, 0x99,
+		0xE3, 0x83, 0x88, 0xE3, 0x83, 0xB3, 0xE3, 0x83,
+		0xA1, 0xE3, 0x83, 0xBC, 0xE3, 0x83, 0x88, 0xE3,
+		0x83, 0xAB, 0xE3, 0x83, 0xA4, 0xE3, 0x83, 0xBC,
+		0xE3, 0x83, 0x88, 0xE3, 0x82, 0x99, 0xE3, 0x83,
+		0xA4, 0xE3, 0x83, 0xBC, 0xE3, 0x83, 0xAB, 0xE3,
+		0x83, 0xA6, 0xE3, 0x82, 0xA2, 0xE3, 0x83, 0xB3,
+		0xE3, 0x83, 0xAA, 0xE3, 0x83, 0x83, 0xE3, 0x83,
+		0x88, 0xE3, 0x83, 0xAB, 0xE3, 0x83, 0xAA, 0xE3,
+		0x83, 0xA9, 0xE3, 0x83, 0xAB, 0xE3, 0x83, 0x92,
+		0xE3, 0x82, 0x9A, 0xE3, 0x83, 0xBC, 0xE3, 0x83,
+		0xAB, 0xE3, 0x83, 0xBC, 0xE3, 0x83, 0x95, 0xE3,
+		0x82, 0x99, 0xE3, 0x83, 0xAB, 0xE3, 0x83, 0xAC,
+		0xE3, 0x83, 0xA0, 0xE3, 0x83, 0xAC, 0xE3, 0x83,
+		0xB3, 0xE3, 0x83, 0x88, 0xE3, 0x82, 0xB1, 0xE3,
+		0x82, 0x99, 0xE3, 0x83, 0xB3, 0xE3, 0x83, 0xAF,
+		0xE3, 0x83, 0x83, 0xE3, 0x83, 0x88, 0x30, 0xE7,
+		0x82, 0xB9, 0x31, 0xE7, 0x82, 0xB9, 0x32, 0xE7,
+		0x82, 0xB9, 0x33, 0xE7, 0x82, 0xB9, 0x34, 0xE7,
+		0x82, 0xB9, 0x35, 0xE7, 0x82, 0xB9, 0x36, 0xE7,
+		0x82, 0xB9, 0x37, 0xE7, 0x82, 0xB9, 0x38, 0xE7,
+		0x82, 0xB9, 0x39, 0xE7, 0x82, 0xB9, 0x31, 0x30,
+		0xE7, 0x82, 0xB9, 0x31, 0x31, 0xE7, 0x82, 0xB9,
+		0x31, 0x32, 0xE7, 0x82, 0xB9, 0x31, 0x33, 0xE7,
+		0x82, 0xB9, 0x31, 0x34, 0xE7, 0x82, 0xB9, 0x31,
+		0x35, 0xE7, 0x82, 0xB9, 0x31, 0x36, 0xE7, 0x82,
+		0xB9, 0x31, 0x37, 0xE7, 0x82, 0xB9, 0x31, 0x38,
+		0xE7, 0x82, 0xB9, 0x31, 0x39, 0xE7, 0x82, 0xB9,
+		0x32, 0x30, 0xE7, 0x82, 0xB9, 0x32, 0x31, 0xE7,
+		0x82, 0xB9, 0x32, 0x32, 0xE7, 0x82, 0xB9, 0x32,
+		0x33, 0xE7, 0x82, 0xB9, 0x32, 0x34, 0xE7, 0x82,
+		0xB9, 0x68, 0x50, 0x61, 0x64, 0x61, 0x41, 0x55,
+		0x62, 0x61, 0x72, 0x6F, 0x56, 0x70, 0x63, 0x64,
+		0x6D, 0x64, 0x6D, 0x32, 0x64, 0x6D, 0x33, 0x49,
+		0x55, 0xE5, 0xB9, 0xB3, 0xE6, 0x88, 0x90, 0xE6,
+		0x98, 0xAD, 0xE5, 0x92, 0x8C, 0xE5, 0xA4, 0xA7,
+		0xE6, 0xAD, 0xA3, 0xE6, 0x98, 0x8E, 0xE6, 0xB2,
+		0xBB, 0xE6, 0xA0, 0xAA, 0xE5, 0xBC, 0x8F, 0xE4,
+		0xBC, 0x9A, 0xE7, 0xA4, 0xBE, 0x70, 0x41, 0x6E,
+		0x41, 0xCE, 0xBC, 0x41, 0x6D, 0x41, 0x6B, 0x41,
+		0x4B, 0x42, 0x4D, 0x42, 0x47, 0x42, 0x63, 0x61,
+		0x6C, 0x6B, 0x63, 0x61, 0x6C, 0x70, 0x46, 0x6E,
+		0x46, 0xCE, 0xBC, 0x46, 0xCE, 0xBC, 0x67, 0x6D,
+		0x67, 0x6B, 0x67, 0x48, 0x7A, 0x6B, 0x48, 0x7A,
+		0x4D, 0x48, 0x7A, 0x47, 0x48, 0x7A, 0x54, 0x48,
+		0x7A, 0xCE, 0xBC, 0x6C, 0x6D, 0x6C, 0x64, 0x6C,
+		0x6B, 0x6C, 0x66, 0x6D, 0x6E, 0x6D, 0xCE, 0xBC,
+		0x6D, 0x6D, 0x6D, 0x63, 0x6D, 0x6B, 0x6D, 0x6D,
+		0x6D, 0x32, 0x63, 0x6D, 0x32, 0x6D, 0x32, 0x6B,
+		0x6D, 0x32, 0x6D, 0x6D, 0x33, 0x63, 0x6D, 0x33,
+		0x6D, 0x33, 0x6B, 0x6D, 0x33, 0x6D, 0xE2, 0x88,
+		0x95, 0x73, 0x6D, 0xE2, 0x88, 0x95, 0x73, 0x32,
+		0x50, 0x61, 0x6B, 0x50, 0x61, 0x4D, 0x50, 0x61,
+		0x47, 0x50, 0x61, 0x72, 0x61, 0x64, 0x72, 0x61,
+		0x64, 0xE2, 0x88, 0x95, 0x73, 0x72, 0x61, 0x64,
+		0xE2, 0x88, 0x95, 0x73, 0x32, 0x70, 0x73, 0x6E,
+		0x73, 0xCE, 0xBC, 0x73, 0x6D, 0x73, 0x70, 0x56,
+		0x6E, 0x56, 0xCE, 0xBC, 0x56, 0x6D, 0x56, 0x6B,
+		0x56, 0x4D, 0x56, 0x70, 0x57, 0x6E, 0x57, 0xCE,
+		0xBC, 0x57, 0x6D, 0x57, 0x6B, 0x57, 0x4D, 0x57,
+		0x6B, 0xCE, 0xA9, 0x4D, 0xCE, 0xA9, 0x61, 0x2E,
+		0x6D, 0x2E, 0x42, 0x71, 0x63, 0x63, 0x63, 0x64,
+		0x43, 0xE2, 0x88, 0x95, 0x6B, 0x67, 0x43, 0x6F,
+		0x2E, 0x64, 0x42, 0x47, 0x79, 0x68, 0x61, 0x48,
+		0x50, 0x69, 0x6E, 0x4B, 0x4B, 0x4B, 0x4D, 0x6B,
+		0x74, 0x6C, 0x6D, 0x6C, 0x6E, 0x6C, 0x6F, 0x67,
+		0x6C, 0x78, 0x6D, 0x62, 0x6D, 0x69, 0x6C, 0x6D,
+		0x6F, 0x6C, 0x50, 0x48, 0x70, 0x2E, 0x6D, 0x2E,
+		0x50, 0x50, 0x4D, 0x50, 0x52, 0x73, 0x72, 0x53,
+		0x76, 0x57, 0x62, 0x56, 0xE2, 0x88, 0x95, 0x6D,
+		0x41, 0xE2, 0x88, 0x95, 0x6D, 0x31, 0xE6, 0x97,
+		0xA5, 0x32, 0xE6, 0x97, 0xA5, 0x33, 0xE6, 0x97,
+		0xA5, 0x34, 0xE6, 0x97, 0xA5, 0x35, 0xE6, 0x97,
+		0xA5, 0x36, 0xE6, 0x97, 0xA5, 0x37, 0xE6, 0x97,
+		0xA5, 0x38, 0xE6, 0x97, 0xA5, 0x39, 0xE6, 0x97,
+		0xA5, 0x31, 0x30, 0xE6, 0x97, 0xA5, 0x31, 0x31,
+		0xE6, 0x97, 0xA5, 0x31, 0x32, 0xE6, 0x97, 0xA5,
+		0x31, 0x33, 0xE6, 0x97, 0xA5, 0x31, 0x34, 0xE6,
+		0x97, 0xA5, 0x31, 0x35, 0xE6, 0x97, 0xA5, 0x31,
+		0x36, 0xE6, 0x97, 0xA5, 0x31, 0x37, 0xE6, 0x97,
+		0xA5, 0x31, 0x38, 0xE6, 0x97, 0xA5, 0x31, 0x39,
+		0xE6, 0x97, 0xA5, 0x32, 0x30, 0xE6, 0x97, 0xA5,
+		0x32, 0x31, 0xE6, 0x97, 0xA5, 0x32, 0x32, 0xE6,
+		0x97, 0xA5, 0x32, 0x33, 0xE6, 0x97, 0xA5, 0x32,
+		0x34, 0xE6, 0x97, 0xA5, 0x32, 0x35, 0xE6, 0x97,
+		0xA5, 0x32, 0x36, 0xE6, 0x97, 0xA5, 0x32, 0x37,
+		0xE6, 0x97, 0xA5, 0x32, 0x38, 0xE6, 0x97, 0xA5,
+		0x32, 0x39, 0xE6, 0x97, 0xA5, 0x33, 0x30, 0xE6,
+		0x97, 0xA5, 0x33, 0x31, 0xE6, 0x97, 0xA5, 0x67,
+		0x61, 0x6C, 0xF6, 0xE8, 0xB1, 0x88, 0xF6, 0xE6,
+		0x9B, 0xB4, 0xF6, 0xE8, 0xBB, 0x8A, 0xF6, 0xE8,
+		0xB3, 0x88, 0xF6, 0xE6, 0xBB, 0x91, 0xF6, 0xE4,
+		0xB8, 0xB2, 0xF6, 0xE5, 0x8F, 0xA5, 0xF6, 0xE9,
+		0xBE, 0x9C, 0xF6, 0xE9, 0xBE, 0x9C, 0xF6, 0xE5,
+		0xA5, 0x91, 0xF6, 0xE9, 0x87, 0x91, 0xF6, 0xE5,
+		0x96, 0x87, 0xF6, 0xE5, 0xA5, 0x88, 0xF6, 0xE6,
+		0x87, 0xB6, 0xF6, 0xE7, 0x99, 0xA9, 0xF6, 0xE7,
+		0xBE, 0x85, 0xF6, 0xE8, 0x98, 0xBF, 0xF6, 0xE8,
+		0x9E, 0xBA, 0xF6, 0xE8, 0xA3, 0xB8, 0xF6, 0xE9,
+		0x82, 0x8F, 0xF6, 0xE6, 0xA8, 0x82, 0xF6, 0xE6,
+		0xB4, 0x9B, 0xF6, 0xE7, 0x83, 0x99, 0xF6, 0xE7,
+		0x8F, 0x9E, 0xF6, 0xE8, 0x90, 0xBD, 0xF6, 0xE9,
+		0x85, 0xAA, 0xF6, 0xE9, 0xA7, 0xB1, 0xF6, 0xE4,
+		0xBA, 0x82, 0xF6, 0xE5, 0x8D, 0xB5, 0xF6, 0xE6,
+		0xAC, 0x84, 0xF6, 0xE7, 0x88, 0x9B, 0xF6, 0xE8,
+		0x98, 0xAD, 0xF6, 0xE9, 0xB8, 0x9E, 0xF6, 0xE5,
+		0xB5, 0x90, 0xF6, 0xE6, 0xBF, 0xAB, 0xF6, 0xE8,
+		0x97, 0x8D, 0xF6, 0xE8, 0xA5, 0xA4, 0xF6, 0xE6,
+		0x8B, 0x89, 0xF6, 0xE8, 0x87, 0x98, 0xF6, 0xE8,
+		0xA0, 0x9F, 0xF6, 0xE5, 0xBB, 0x8A, 0xF6, 0xE6,
+		0x9C, 0x97, 0xF6, 0xE6, 0xB5, 0xAA, 0xF6, 0xE7,
+		0x8B, 0xBC, 0xF6, 0xE9, 0x83, 0x8E, 0xF6, 0xE4,
+		0xBE, 0x86, 0xF6, 0xE5, 0x86, 0xB7, 0xF6, 0xE5,
+		0x8B, 0x9E, 0xF6, 0xE6, 0x93, 0x84, 0xF6, 0xE6,
+		0xAB, 0x93, 0xF6, 0xE7, 0x88, 0x90, 0xF6, 0xE7,
+		0x9B, 0xA7, 0xF6, 0xE8, 0x80, 0x81, 0xF6, 0xE8,
+		0x98, 0x86, 0xF6, 0xE8, 0x99, 0x9C, 0xF6, 0xE8,
+		0xB7, 0xAF, 0xF6, 0xE9, 0x9C, 0xB2, 0xF6, 0xE9,
+		0xAD, 0xAF, 0xF6, 0xE9, 0xB7, 0xBA, 0xF6, 0xE7,
+		0xA2, 0x8C, 0xF6, 0xE7, 0xA5, 0xBF, 0xF6, 0xE7,
+		0xB6, 0xA0, 0xF6, 0xE8, 0x8F, 0x89, 0xF6, 0xE9,
+		0x8C, 0x84, 0xF6, 0xE9, 0xB9, 0xBF, 0xF6, 0xE8,
+		0xAB, 0x96, 0xF6, 0xE5, 0xA3, 0x9F, 0xF6, 0xE5,
+		0xBC, 0x84, 0xF6, 0xE7, 0xB1, 0xA0, 0xF6, 0xE8,
+		0x81, 0xBE, 0xF6, 0xE7, 0x89, 0xA2, 0xF6, 0xE7,
+		0xA3, 0x8A, 0xF6, 0xE8, 0xB3, 0x82, 0xF6, 0xE9,
+		0x9B, 0xB7, 0xF6, 0xE5, 0xA3, 0x98, 0xF6, 0xE5,
+		0xB1, 0xA2, 0xF6, 0xE6, 0xA8, 0x93, 0xF6, 0xE6,
+		0xB7, 0x9A, 0xF6, 0xE6, 0xBC, 0x8F, 0xF6, 0xE7,
+		0xB4, 0xAF, 0xF6, 0xE7, 0xB8, 0xB7, 0xF6, 0xE9,
+		0x99, 0x8B, 0xF6, 0xE5, 0x8B, 0x92, 0xF6, 0xE8,
+		0x82, 0x8B, 0xF6, 0xE5, 0x87, 0x9C, 0xF6, 0xE5,
+		0x87, 0x8C, 0xF6, 0xE7, 0xA8, 0x9C, 0xF6, 0xE7,
+		0xB6, 0xBE, 0xF6, 0xE8, 0x8F, 0xB1, 0xF6, 0xE9,
+		0x99, 0xB5, 0xF6, 0xE8, 0xAE, 0x80, 0xF6, 0xE6,
+		0x8B, 0x8F, 0xF6, 0xE6, 0xA8, 0x82, 0xF6, 0xE8,
+		0xAB, 0xBE, 0xF6, 0xE4, 0xB8, 0xB9, 0xF6, 0xE5,
+		0xAF, 0xA7, 0xF6, 0xE6, 0x80, 0x92, 0xF6, 0xE7,
+		0x8E, 0x87, 0xF6, 0xE7, 0x95, 0xB0, 0xF6, 0xE5,
+		0x8C, 0x97, 0xF6, 0xE7, 0xA3, 0xBB, 0xF6, 0xE4,
+		0xBE, 0xBF, 0xF6, 0xE5, 0xBE, 0xA9, 0xF6, 0xE4,
+		0xB8, 0x8D, 0xF6, 0xE6, 0xB3, 0x8C, 0xF6, 0xE6,
+		0x95, 0xB8, 0xF6, 0xE7, 0xB4, 0xA2, 0xF6, 0xE5,
+		0x8F, 0x83, 0xF6, 0xE5, 0xA1, 0x9E, 0xF6, 0xE7,
+		0x9C, 0x81, 0xF6, 0xE8, 0x91, 0x89, 0xF6, 0xE8,
+		0xAA, 0xAA, 0xF6, 0xE6, 0xAE, 0xBA, 0xF6, 0xE8,
+		0xBE, 0xB0, 0xF6, 0xE6, 0xB2, 0x88, 0xF6, 0xE6,
+		0x8B, 0xBE, 0xF6, 0xE8, 0x8B, 0xA5, 0xF6, 0xE6,
+		0x8E, 0xA0, 0xF6, 0xE7, 0x95, 0xA5, 0xF6, 0xE4,
+		0xBA, 0xAE, 0xF6, 0xE5, 0x85, 0xA9, 0xF6, 0xE5,
+		0x87, 0x89, 0xF6, 0xE6, 0xA2, 0x81, 0xF6, 0xE7,
+		0xB3, 0xA7, 0xF6, 0xE8, 0x89, 0xAF, 0xF6, 0xE8,
+		0xAB, 0x92, 0xF6, 0xE9, 0x87, 0x8F, 0xF6, 0xE5,
+		0x8B, 0xB5, 0xF6, 0xE5, 0x91, 0x82, 0xF6, 0xE5,
+		0xA5, 0xB3, 0xF6, 0xE5, 0xBB, 0xAC, 0xF6, 0xE6,
+		0x97, 0x85, 0xF6, 0xE6, 0xBF, 0xBE, 0xF6, 0xE7,
+		0xA4, 0xAA, 0xF6, 0xE9, 0x96, 0xAD, 0xF6, 0xE9,
+		0xA9, 0xAA, 0xF6, 0xE9, 0xBA, 0x97, 0xF6, 0xE9,
+		0xBB, 0x8E, 0xF6, 0xE5, 0x8A, 0x9B, 0xF6, 0xE6,
+		0x9B, 0x86, 0xF6, 0xE6, 0xAD, 0xB7, 0xF6, 0xE8,
+		0xBD, 0xA2, 0xF6, 0xE5, 0xB9, 0xB4, 0xF6, 0xE6,
+		0x86, 0x90, 0xF6, 0xE6, 0x88, 0x80, 0xF6, 0xE6,
+		0x92, 0x9A, 0xF6, 0xE6, 0xBC, 0xA3, 0xF6, 0xE7,
+		0x85, 0x89, 0xF6, 0xE7, 0x92, 0x89, 0xF6, 0xE7,
+		0xA7, 0x8A, 0xF6, 0xE7, 0xB7, 0xB4, 0xF6, 0xE8,
+		0x81, 0xAF, 0xF6, 0xE8, 0xBC, 0xA6, 0xF6, 0xE8,
+		0x93, 0xAE, 0xF6, 0xE9, 0x80, 0xA3, 0xF6, 0xE9,
+		0x8D, 0x8A, 0xF6, 0xE5, 0x88, 0x97, 0xF6, 0xE5,
+		0x8A, 0xA3, 0xF6, 0xE5, 0x92, 0xBD, 0xF6, 0xE7,
+		0x83, 0x88, 0xF6, 0xE8, 0xA3, 0x82, 0xF6, 0xE8,
+		0xAA, 0xAA, 0xF6, 0xE5, 0xBB, 0x89, 0xF6, 0xE5,
+		0xBF, 0xB5, 0xF6, 0xE6, 0x8D, 0xBB, 0xF6, 0xE6,
+		0xAE, 0xAE, 0xF6, 0xE7, 0xB0, 0xBE, 0xF6, 0xE7,
+		0x8D, 0xB5, 0xF6, 0xE4, 0xBB, 0xA4, 0xF6, 0xE5,
+		0x9B, 0xB9, 0xF6, 0xE5, 0xAF, 0xA7, 0xF6, 0xE5,
+		0xB6, 0xBA, 0xF6, 0xE6, 0x80, 0x9C, 0xF6, 0xE7,
+		0x8E, 0xB2, 0xF6, 0xE7, 0x91, 0xA9, 0xF6, 0xE7,
+		0xBE, 0x9A, 0xF6, 0xE8, 0x81, 0x86, 0xF6, 0xE9,
+		0x88, 0xB4, 0xF6, 0xE9, 0x9B, 0xB6, 0xF6, 0xE9,
+		0x9D, 0x88, 0xF6, 0xE9, 0xA0, 0x98, 0xF6, 0xE4,
+		0xBE, 0x8B, 0xF6, 0xE7, 0xA6, 0xAE, 0xF6, 0xE9,
+		0x86, 0xB4, 0xF6, 0xE9, 0x9A, 0xB8, 0xF6, 0xE6,
+		0x83, 0xA1, 0xF6, 0xE4, 0xBA, 0x86, 0xF6, 0xE5,
+		0x83, 0x9A, 0xF6, 0xE5, 0xAF, 0xAE, 0xF6, 0xE5,
+		0xB0, 0xBF, 0xF6, 0xE6, 0x96, 0x99, 0xF6, 0xE6,
+		0xA8, 0x82, 0xF6, 0xE7, 0x87, 0x8E, 0xF6, 0xE7,
+		0x99, 0x82, 0xF6, 0xE8, 0x93, 0xBC, 0xF6, 0xE9,
+		0x81, 0xBC, 0xF6, 0xE9, 0xBE, 0x8D, 0xF6, 0xE6,
+		0x9A, 0x88, 0xF6, 0xE9, 0x98, 0xAE, 0xF6, 0xE5,
+		0x8A, 0x89, 0xF6, 0xE6, 0x9D, 0xBB, 0xF6, 0xE6,
+		0x9F, 0xB3, 0xF6, 0xE6, 0xB5, 0x81, 0xF6, 0xE6,
+		0xBA, 0x9C, 0xF6, 0xE7, 0x90, 0x89, 0xF6, 0xE7,
+		0x95, 0x99, 0xF6, 0xE7, 0xA1, 0xAB, 0xF6, 0xE7,
+		0xB4, 0x90, 0xF6, 0xE9, 0xA1, 0x9E, 0xF6, 0xE5,
+		0x85, 0xAD, 0xF6, 0xE6, 0x88, 0xAE, 0xF6, 0xE9,
+		0x99, 0xB8, 0xF6, 0xE5, 0x80, 0xAB, 0xF6, 0xE5,
+		0xB4, 0x99, 0xF6, 0xE6, 0xB7, 0xAA, 0xF6, 0xE8,
+		0xBC, 0xAA, 0xF6, 0xE5, 0xBE, 0x8B, 0xF6, 0xE6,
+		0x85, 0x84, 0xF6, 0xE6, 0xA0, 0x97, 0xF6, 0xE7,
+		0x8E, 0x87, 0xF6, 0xE9, 0x9A, 0x86, 0xF6, 0xE5,
+		0x88, 0xA9, 0xF6, 0xE5, 0x90, 0x8F, 0xF6, 0xE5,
+		0xB1, 0xA5, 0xF6, 0xE6, 0x98, 0x93, 0xF6, 0xE6,
+		0x9D, 0x8E, 0xF6, 0xE6, 0xA2, 0xA8, 0xF6, 0xE6,
+		0xB3, 0xA5, 0xF6, 0xE7, 0x90, 0x86, 0xF6, 0xE7,
+		0x97, 0xA2, 0xF6, 0xE7, 0xBD, 0xB9, 0xF6, 0xE8,
+		0xA3, 0x8F, 0xF6, 0xE8, 0xA3, 0xA1, 0xF6, 0xE9,
+		0x87, 0x8C, 0xF6, 0xE9, 0x9B, 0xA2, 0xF6, 0xE5,
+		0x8C, 0xBF, 0xF6, 0xE6, 0xBA, 0xBA, 0xF6, 0xE5,
+		0x90, 0x9D, 0xF6, 0xE7, 0x87, 0x90, 0xF6, 0xE7,
+		0x92, 0x98, 0xF6, 0xE8, 0x97, 0xBA, 0xF6, 0xE9,
+		0x9A, 0xA3, 0xF6, 0xE9, 0xB1, 0x97, 0xF6, 0xE9,
+		0xBA, 0x9F, 0xF6, 0xE6, 0x9E, 0x97, 0xF6, 0xE6,
+		0xB7, 0x8B, 0xF6, 0xE8, 0x87, 0xA8, 0xF6, 0xE7,
+		0xAB, 0x8B, 0xF6, 0xE7, 0xAC, 0xA0, 0xF6, 0xE7,
+		0xB2, 0x92, 0xF6, 0xE7, 0x8B, 0x80, 0xF6, 0xE7,
+		0x82, 0x99, 0xF6, 0xE8, 0xAD, 0x98, 0xF6, 0xE4,
+		0xBB, 0x80, 0xF6, 0xE8, 0x8C, 0xB6, 0xF6, 0xE5,
+		0x88, 0xBA, 0xF6, 0xE5, 0x88, 0x87, 0xF6, 0xE5,
+		0xBA, 0xA6, 0xF6, 0xE6, 0x8B, 0x93, 0xF6, 0xE7,
+		0xB3, 0x96, 0xF6, 0xE5, 0xAE, 0x85, 0xF6, 0xE6,
+		0xB4, 0x9E, 0xF6, 0xE6, 0x9A, 0xB4, 0xF6, 0xE8,
+		0xBC, 0xBB, 0xF6, 0xE8, 0xA1, 0x8C, 0xF6, 0xE9,
+		0x99, 0x8D, 0xF6, 0xE8, 0xA6, 0x8B, 0xF6, 0xE5,
+		0xBB, 0x93, 0xF6, 0xE5, 0x85, 0x80, 0xF6, 0xE5,
+		0x97, 0x80, 0xF6, 0xE5, 0xA1, 0x9A, 0xF6, 0xE6,
+		0x99, 0xB4, 0xF6, 0xE5, 0x87, 0x9E, 0xF6, 0xE7,
+		0x8C, 0xAA, 0xF6, 0xE7, 0x9B, 0x8A, 0xF6, 0xE7,
+		0xA4, 0xBC, 0xF6, 0xE7, 0xA5, 0x9E, 0xF6, 0xE7,
+		0xA5, 0xA5, 0xF6, 0xE7, 0xA6, 0x8F, 0xF6, 0xE9,
+		0x9D, 0x96, 0xF6, 0xE7, 0xB2, 0xBE, 0xF6, 0xE7,
+		0xBE, 0xBD, 0xF6, 0xE8, 0x98, 0x92, 0xF6, 0xE8,
+		0xAB, 0xB8, 0xF6, 0xE9, 0x80, 0xB8, 0xF6, 0xE9,
+		0x83, 0xBD, 0xF6, 0xE9, 0xA3, 0xAF, 0xF6, 0xE9,
+		0xA3, 0xBC, 0xF6, 0xE9, 0xA4, 0xA8, 0xF6, 0xE9,
+		0xB6, 0xB4, 0xF6, 0xE4, 0xBE, 0xAE, 0xF6, 0xE5,
+		0x83, 0xA7, 0xF6, 0xE5, 0x85, 0x8D, 0xF6, 0xE5,
+		0x8B, 0x89, 0xF6, 0xE5, 0x8B, 0xA4, 0xF6, 0xE5,
+		0x8D, 0x91, 0xF6, 0xE5, 0x96, 0x9D, 0xF6, 0xE5,
+		0x98, 0x86, 0xF6, 0xE5, 0x99, 0xA8, 0xF6, 0xE5,
+		0xA1, 0x80, 0xF6, 0xE5, 0xA2, 0xA8, 0xF6, 0xE5,
+		0xB1, 0xA4, 0xF6, 0xE5, 0xB1, 0xAE, 0xF6, 0xE6,
+		0x82, 0x94, 0xF6, 0xE6, 0x85, 0xA8, 0xF6, 0xE6,
+		0x86, 0x8E, 0xF6, 0xE6, 0x87, 0xB2, 0xF6, 0xE6,
+		0x95, 0x8F, 0xF6, 0xE6, 0x97, 0xA2, 0xF6, 0xE6,
+		0x9A, 0x91, 0xF6, 0xE6, 0xA2, 0x85, 0xF6, 0xE6,
+		0xB5, 0xB7, 0xF6, 0xE6, 0xB8, 0x9A, 0xF6, 0xE6,
+		0xBC, 0xA2, 0xF6, 0xE7, 0x85, 0xAE, 0xF6, 0xE7,
+		0x88, 0xAB, 0xF6, 0xE7, 0x90, 0xA2, 0xF6, 0xE7,
+		0xA2, 0x91, 0xF6, 0xE7, 0xA4, 0xBE, 0xF6, 0xE7,
+		0xA5, 0x89, 0xF6, 0xE7, 0xA5, 0x88, 0xF6, 0xE7,
+		0xA5, 0x90, 0xF6, 0xE7, 0xA5, 0x96, 0xF6, 0xE7,
+		0xA5, 0x9D, 0xF6, 0xE7, 0xA6, 0x8D, 0xF6, 0xE7,
+		0xA6, 0x8E, 0xF6, 0xE7, 0xA9, 0x80, 0xF6, 0xE7,
+		0xAA, 0x81, 0xF6, 0xE7, 0xAF, 0x80, 0xF6, 0xE7,
+		0xB7, 0xB4, 0xF6, 0xE7, 0xB8, 0x89, 0xF6, 0xE7,
+		0xB9, 0x81, 0xF6, 0xE7, 0xBD, 0xB2, 0xF6, 0xE8,
+		0x80, 0x85, 0xF6, 0xE8, 0x87, 0xAD, 0xF6, 0xE8,
+		0x89, 0xB9, 0xF6, 0xE8, 0x89, 0xB9, 0xF6, 0xE8,
+		0x91, 0x97, 0xF6, 0xE8, 0xA4, 0x90, 0xF6, 0xE8,
+		0xA6, 0x96, 0xF6, 0xE8, 0xAC, 0x81, 0xF6, 0xE8,
+		0xAC, 0xB9, 0xF6, 0xE8, 0xB3, 0x93, 0xF6, 0xE8,
+		0xB4, 0x88, 0xF6, 0xE8, 0xBE, 0xB6, 0xF6, 0xE9,
+		0x80, 0xB8, 0xF6, 0xE9, 0x9B, 0xA3, 0xF6, 0xE9,
+		0x9F, 0xBF, 0xF6, 0xE9, 0xA0, 0xBB, 0xF6, 0xE4,
+		0xB8, 0xA6, 0xF6, 0xE5, 0x86, 0xB5, 0xF6, 0xE5,
+		0x85, 0xA8, 0xF6, 0xE4, 0xBE, 0x80, 0xF6, 0xE5,
+		0x85, 0x85, 0xF6, 0xE5, 0x86, 0x80, 0xF6, 0xE5,
+		0x8B, 0x87, 0xF6, 0xE5, 0x8B, 0xBA, 0xF6, 0xE5,
+		0x96, 0x9D, 0xF6, 0xE5, 0x95, 0x95, 0xF6, 0xE5,
+		0x96, 0x99, 0xF6, 0xE5, 0x97, 0xA2, 0xF6, 0xE5,
+		0xA1, 0x9A, 0xF6, 0xE5, 0xA2, 0xB3, 0xF6, 0xE5,
+		0xA5, 0x84, 0xF6, 0xE5, 0xA5, 0x94, 0xF6, 0xE5,
+		0xA9, 0xA2, 0xF6, 0xE5, 0xAC, 0xA8, 0xF6, 0xE5,
+		0xBB, 0x92, 0xF6, 0xE5, 0xBB, 0x99, 0xF6, 0xE5,
+		0xBD, 0xA9, 0xF6, 0xE5, 0xBE, 0xAD, 0xF6, 0xE6,
+		0x83, 0x98, 0xF6, 0xE6, 0x85, 0x8E, 0xF6, 0xE6,
+		0x84, 0x88, 0xF6, 0xE6, 0x86, 0x8E, 0xF6, 0xE6,
+		0x85, 0xA0, 0xF6, 0xE6, 0x87, 0xB2, 0xF6, 0xE6,
+		0x88, 0xB4, 0xF6, 0xE6, 0x8F, 0x84, 0xF6, 0xE6,
+		0x90, 0x9C, 0xF6, 0xE6, 0x91, 0x92, 0xF6, 0xE6,
+		0x95, 0x96, 0xF6, 0xE6, 0x99, 0xB4, 0xF6, 0xE6,
+		0x9C, 0x97, 0xF6, 0xE6, 0x9C, 0x9B, 0xF6, 0xE6,
+		0x9D, 0x96, 0xF6, 0xE6, 0xAD, 0xB9, 0xF6, 0xE6,
+		0xAE, 0xBA, 0xF6, 0xE6, 0xB5, 0x81, 0xF6, 0xE6,
+		0xBB, 0x9B, 0xF6, 0xE6, 0xBB, 0x8B, 0xF6, 0xE6,
+		0xBC, 0xA2, 0xF6, 0xE7, 0x80, 0x9E, 0xF6, 0xE7,
+		0x85, 0xAE, 0xF6, 0xE7, 0x9E, 0xA7, 0xF6, 0xE7,
+		0x88, 0xB5, 0xF6, 0xE7, 0x8A, 0xAF, 0xF6, 0xE7,
+		0x8C, 0xAA, 0xF6, 0xE7, 0x91, 0xB1, 0xF6, 0xE7,
+		0x94, 0x86, 0xF6, 0xE7, 0x94, 0xBB, 0xF6, 0xE7,
+		0x98, 0x9D, 0xF6, 0xE7, 0x98, 0x9F, 0xF6, 0xE7,
+		0x9B, 0x8A, 0xF6, 0xE7, 0x9B, 0x9B, 0xF6, 0xE7,
+		0x9B, 0xB4, 0xF6, 0xE7, 0x9D, 0x8A, 0xF6, 0xE7,
+		0x9D, 0x80, 0xF6, 0xE7, 0xA3, 0x8C, 0xF6, 0xE7,
+		0xAA, 0xB1, 0xF6, 0xE7, 0xAF, 0x80, 0xF6, 0xE7,
+		0xB1, 0xBB, 0xF6, 0xE7, 0xB5, 0x9B, 0xF6, 0xE7,
+		0xB7, 0xB4, 0xF6, 0xE7, 0xBC, 0xBE, 0xF6, 0xE8,
+		0x80, 0x85, 0xF6, 0xE8, 0x8D, 0x92, 0xF6, 0xE8,
+		0x8F, 0xAF, 0xF6, 0xE8, 0x9D, 0xB9, 0xF6, 0xE8,
+		0xA5, 0x81, 0xF6, 0xE8, 0xA6, 0x86, 0xF6, 0xE8,
+		0xA6, 0x96, 0xF6, 0xE8, 0xAA, 0xBF, 0xF6, 0xE8,
+		0xAB, 0xB8, 0xF6, 0xE8, 0xAB, 0x8B, 0xF6, 0xE8,
+		0xAC, 0x81, 0xF6, 0xE8, 0xAB, 0xBE, 0xF6, 0xE8,
+		0xAB, 0xAD, 0xF6, 0xE8, 0xAC, 0xB9, 0xF6, 0xE8,
+		0xAE, 0x8A, 0xF6, 0xE8, 0xB4, 0x88, 0xF6, 0xE8,
+		0xBC, 0xB8, 0xF6, 0xE9, 0x81, 0xB2, 0xF6, 0xE9,
+		0x86, 0x99, 0xF6, 0xE9, 0x89, 0xB6, 0xF6, 0xE9,
+		0x99, 0xBC, 0xF6, 0xE9, 0x9B, 0xA3, 0xF6, 0xE9,
+		0x9D, 0x96, 0xF6, 0xE9, 0x9F, 0x9B, 0xF6, 0xE9,
+		0x9F, 0xBF, 0xF6, 0xE9, 0xA0, 0x8B, 0xF6, 0xE9,
+		0xA0, 0xBB, 0xF6, 0xE9, 0xAC, 0x92, 0xF6, 0xE9,
+		0xBE, 0x9C, 0xF6, 0xF0, 0xA2, 0xA1, 0x8A, 0xF6,
+		0xF0, 0xA2, 0xA1, 0x84, 0xF6, 0xF0, 0xA3, 0x8F,
+		0x95, 0xF6, 0xE3, 0xAE, 0x9D, 0xF6, 0xE4, 0x80,
+		0x98, 0xF6, 0xE4, 0x80, 0xB9, 0xF6, 0xF0, 0xA5,
+		0x89, 0x89, 0xF6, 0xF0, 0xA5, 0xB3, 0x90, 0xF6,
+		0xF0, 0xA7, 0xBB, 0x93, 0xF6, 0xE9, 0xBD, 0x83,
+		0xF6, 0xE9, 0xBE, 0x8E, 0x66, 0x66, 0x66, 0x69,
+		0x66, 0x6C, 0x66, 0x66, 0x69, 0x66, 0x66, 0x6C,
+		0x73, 0x74, 0x73, 0x74, 0xD5, 0xB4, 0xD5, 0xB6,
+		0xD5, 0xB4, 0xD5, 0xA5, 0xD5, 0xB4, 0xD5, 0xAB,
+		0xD5, 0xBE, 0xD5, 0xB6, 0xD5, 0xB4, 0xD5, 0xAD,
+		0xF6, 0xD7, 0x99, 0xD6, 0xB4, 0xF6, 0xD7, 0xB2,
+		0xD6, 0xB7, 0xD7, 0xA2, 0xD7, 0x90, 0xD7, 0x93,
+		0xD7, 0x94, 0xD7, 0x9B, 0xD7, 0x9C, 0xD7, 0x9D,
+		0xD7, 0xA8, 0xD7, 0xAA, 0x2B, 0xF6, 0xD7, 0xA9,
+		0xD7, 0x81, 0xF6, 0xD7, 0xA9, 0xD7, 0x82, 0xF6,
+		0xD7, 0xA9, 0xD6, 0xBC, 0xD7, 0x81, 0xF6, 0xD7,
+		0xA9, 0xD6, 0xBC, 0xD7, 0x82, 0xF6, 0xD7, 0x90,
+		0xD6, 0xB7, 0xF6, 0xD7, 0x90, 0xD6, 0xB8, 0xF6,
+		0xD7, 0x90, 0xD6, 0xBC, 0xF6, 0xD7, 0x91, 0xD6,
+		0xBC, 0xF6, 0xD7, 0x92, 0xD6, 0xBC, 0xF6, 0xD7,
+		0x93, 0xD6, 0xBC, 0xF6, 0xD7, 0x94, 0xD6, 0xBC,
+		0xF6, 0xD7, 0x95, 0xD6, 0xBC, 0xF6, 0xD7, 0x96,
+		0xD6, 0xBC, 0xF6, 0xD7, 0x98, 0xD6, 0xBC, 0xF6,
+		0xD7, 0x99, 0xD6, 0xBC, 0xF6, 0xD7, 0x9A, 0xD6,
+		0xBC, 0xF6, 0xD7, 0x9B, 0xD6, 0xBC, 0xF6, 0xD7,
+		0x9C, 0xD6, 0xBC, 0xF6, 0xD7, 0x9E, 0xD6, 0xBC,
+		0xF6, 0xD7, 0xA0, 0xD6, 0xBC, 0xF6, 0xD7, 0xA1,
+		0xD6, 0xBC, 0xF6, 0xD7, 0xA3, 0xD6, 0xBC, 0xF6,
+		0xD7, 0xA4, 0xD6, 0xBC, 0xF6, 0xD7, 0xA6, 0xD6,
+		0xBC, 0xF6, 0xD7, 0xA7, 0xD6, 0xBC, 0xF6, 0xD7,
+		0xA8, 0xD6, 0xBC, 0xF6, 0xD7, 0xA9, 0xD6, 0xBC,
+		0xF6, 0xD7, 0xAA, 0xD6, 0xBC, 0xF6, 0xD7, 0x95,
+		0xD6, 0xB9, 0xF6, 0xD7, 0x91, 0xD6, 0xBF, 0xF6,
+		0xD7, 0x9B, 0xD6, 0xBF, 0xF6, 0xD7, 0xA4, 0xD6,
+		0xBF, 0xD7, 0x90, 0xD7, 0x9C, 0xD9, 0xB1, 0xD9,
+		0xB1, 0xD9, 0xBB, 0xD9, 0xBB, 0xD9, 0xBB, 0xD9,
+		0xBB, 0xD9, 0xBE, 0xD9, 0xBE, 0xD9, 0xBE, 0xD9,
+		0xBE, 0xDA, 0x80, 0xDA, 0x80, 0xDA, 0x80, 0xDA,
+		0x80, 0xD9, 0xBA, 0xD9, 0xBA, 0xD9, 0xBA, 0xD9,
+		0xBA, 0xD9, 0xBF, 0xD9, 0xBF, 0xD9, 0xBF, 0xD9,
+		0xBF, 0xD9, 0xB9, 0xD9, 0xB9, 0xD9, 0xB9, 0xD9,
+		0xB9, 0xDA, 0xA4, 0xDA, 0xA4, 0xDA, 0xA4, 0xDA,
+		0xA4, 0xDA, 0xA6, 0xDA, 0xA6, 0xDA, 0xA6, 0xDA,
+		0xA6, 0xDA, 0x84, 0xDA, 0x84, 0xDA, 0x84, 0xDA,
+		0x84, 0xDA, 0x83, 0xDA, 0x83, 0xDA, 0x83, 0xDA,
+		0x83, 0xDA, 0x86, 0xDA, 0x86, 0xDA, 0x86, 0xDA,
+		0x86, 0xDA, 0x87, 0xDA, 0x87, 0xDA, 0x87, 0xDA,
+		0x87, 0xDA, 0x8D, 0xDA, 0x8D, 0xDA, 0x8C, 0xDA,
+		0x8C, 0xDA, 0x8E, 0xDA, 0x8E, 0xDA, 0x88, 0xDA,
+		0x88, 0xDA, 0x98, 0xDA, 0x98, 0xDA, 0x91, 0xDA,
+		0x91, 0xDA, 0xA9, 0xDA, 0xA9, 0xDA, 0xA9, 0xDA,
+		0xA9, 0xDA, 0xAF, 0xDA, 0xAF, 0xDA, 0xAF, 0xDA,
+		0xAF, 0xDA, 0xB3, 0xDA, 0xB3, 0xDA, 0xB3, 0xDA,
+		0xB3, 0xDA, 0xB1, 0xDA, 0xB1, 0xDA, 0xB1, 0xDA,
+		0xB1, 0xDA, 0xBA, 0xDA, 0xBA, 0xDA, 0xBB, 0xDA,
+		0xBB, 0xDA, 0xBB, 0xDA, 0xBB, 0xDB, 0x95, 0xD9,
+		0x94, 0xDB, 0x95, 0xD9, 0x94, 0xDB, 0x81, 0xDB,
+		0x81, 0xDB, 0x81, 0xDB, 0x81, 0xDA, 0xBE, 0xDA,
+		0xBE, 0xDA, 0xBE, 0xDA, 0xBE, 0xDB, 0x92, 0xDB,
+		0x92, 0xDB, 0x92, 0xD9, 0x94, 0xDB, 0x92, 0xD9,
+		0x94, 0xDA, 0xAD, 0xDA, 0xAD, 0xDA, 0xAD, 0xDA,
+		0xAD, 0xDB, 0x87, 0xDB, 0x87, 0xDB, 0x86, 0xDB,
+		0x86, 0xDB, 0x88, 0xDB, 0x88, 0xDB, 0x87, 0xD9,
+		0xB4, 0xDB, 0x8B, 0xDB, 0x8B, 0xDB, 0x85, 0xDB,
+		0x85, 0xDB, 0x89, 0xDB, 0x89, 0xDB, 0x90, 0xDB,
+		0x90, 0xDB, 0x90, 0xDB, 0x90, 0xD9, 0x89, 0xD9,
+		0x89, 0xD9, 0x8A, 0xD9, 0x94, 0xD8, 0xA7, 0xD9,
+		0x8A, 0xD9, 0x94, 0xD8, 0xA7, 0xD9, 0x8A, 0xD9,
+		0x94, 0xDB, 0x95, 0xD9, 0x8A, 0xD9, 0x94, 0xDB,
+		0x95, 0xD9, 0x8A, 0xD9, 0x94, 0xD9, 0x88, 0xD9,
+		0x8A, 0xD9, 0x94, 0xD9, 0x88, 0xD9, 0x8A, 0xD9,
+		0x94, 0xDB, 0x87, 0xD9, 0x8A, 0xD9, 0x94, 0xDB,
+		0x87, 0xD9, 0x8A, 0xD9, 0x94, 0xDB, 0x86, 0xD9,
+		0x8A, 0xD9, 0x94, 0xDB, 0x86, 0xD9, 0x8A, 0xD9,
+		0x94, 0xDB, 0x88, 0xD9, 0x8A, 0xD9, 0x94, 0xDB,
+		0x88, 0xD9, 0x8A, 0xD9, 0x94, 0xDB, 0x90, 0xD9,
+		0x8A, 0xD9, 0x94, 0xDB, 0x90, 0xD9, 0x8A, 0xD9,
+		0x94, 0xDB, 0x90, 0xD9, 0x8A, 0xD9, 0x94, 0xD9,
+		0x89, 0xD9, 0x8A, 0xD9, 0x94, 0xD9, 0x89, 0xD9,
+		0x8A, 0xD9, 0x94, 0xD9, 0x89, 0xDB, 0x8C, 0xDB,
+		0x8C, 0xDB, 0x8C, 0xDB, 0x8C, 0xD9, 0x8A, 0xD9,
+		0x94, 0xD8, 0xAC, 0xD9, 0x8A, 0xD9, 0x94, 0xD8,
+		0xAD, 0xD9, 0x8A, 0xD9, 0x94, 0xD9, 0x85, 0xD9,
+		0x8A, 0xD9, 0x94, 0xD9, 0x89, 0xD9, 0x8A, 0xD9,
+		0x94, 0xD9, 0x8A, 0xD8, 0xA8, 0xD8, 0xAC, 0xD8,
+		0xA8, 0xD8, 0xAD, 0xD8, 0xA8, 0xD8, 0xAE, 0xD8,
+		0xA8, 0xD9, 0x85, 0xD8, 0xA8, 0xD9, 0x89, 0xD8,
+		0xA8, 0xD9, 0x8A, 0xD8, 0xAA, 0xD8, 0xAC, 0xD8,
+		0xAA, 0xD8, 0xAD, 0xD8, 0xAA, 0xD8, 0xAE, 0xD8,
+		0xAA, 0xD9, 0x85, 0xD8, 0xAA, 0xD9, 0x89, 0xD8,
+		0xAA, 0xD9, 0x8A, 0xD8, 0xAB, 0xD8, 0xAC, 0xD8,
+		0xAB, 0xD9, 0x85, 0xD8, 0xAB, 0xD9, 0x89, 0xD8,
+		0xAB, 0xD9, 0x8A, 0xD8, 0xAC, 0xD8, 0xAD, 0xD8,
+		0xAC, 0xD9, 0x85, 0xD8, 0xAD, 0xD8, 0xAC, 0xD8,
+		0xAD, 0xD9, 0x85, 0xD8, 0xAE, 0xD8, 0xAC, 0xD8,
+		0xAE, 0xD8, 0xAD, 0xD8, 0xAE, 0xD9, 0x85, 0xD8,
+		0xB3, 0xD8, 0xAC, 0xD8, 0xB3, 0xD8, 0xAD, 0xD8,
+		0xB3, 0xD8, 0xAE, 0xD8, 0xB3, 0xD9, 0x85, 0xD8,
+		0xB5, 0xD8, 0xAD, 0xD8, 0xB5, 0xD9, 0x85, 0xD8,
+		0xB6, 0xD8, 0xAC, 0xD8, 0xB6, 0xD8, 0xAD, 0xD8,
+		0xB6, 0xD8, 0xAE, 0xD8, 0xB6, 0xD9, 0x85, 0xD8,
+		0xB7, 0xD8, 0xAD, 0xD8, 0xB7, 0xD9, 0x85, 0xD8,
+		0xB8, 0xD9, 0x85, 0xD8, 0xB9, 0xD8, 0xAC, 0xD8,
+		0xB9, 0xD9, 0x85, 0xD8, 0xBA, 0xD8, 0xAC, 0xD8,
+		0xBA, 0xD9, 0x85, 0xD9, 0x81, 0xD8, 0xAC, 0xD9,
+		0x81, 0xD8, 0xAD, 0xD9, 0x81, 0xD8, 0xAE, 0xD9,
+		0x81, 0xD9, 0x85, 0xD9, 0x81, 0xD9, 0x89, 0xD9,
+		0x81, 0xD9, 0x8A, 0xD9, 0x82, 0xD8, 0xAD, 0xD9,
+		0x82, 0xD9, 0x85, 0xD9, 0x82, 0xD9, 0x89, 0xD9,
+		0x82, 0xD9, 0x8A, 0xD9, 0x83, 0xD8, 0xA7, 0xD9,
+		0x83, 0xD8, 0xAC, 0xD9, 0x83, 0xD8, 0xAD, 0xD9,
+		0x83, 0xD8, 0xAE, 0xD9, 0x83, 0xD9, 0x84, 0xD9,
+		0x83, 0xD9, 0x85, 0xD9, 0x83, 0xD9, 0x89, 0xD9,
+		0x83, 0xD9, 0x8A, 0xD9, 0x84, 0xD8, 0xAC, 0xD9,
+		0x84, 0xD8, 0xAD, 0xD9, 0x84, 0xD8, 0xAE, 0xD9,
+		0x84, 0xD9, 0x85, 0xD9, 0x84, 0xD9, 0x89, 0xD9,
+		0x84, 0xD9, 0x8A, 0xD9, 0x85, 0xD8, 0xAC, 0xD9,
+		0x85, 0xD8, 0xAD, 0xD9, 0x85, 0xD8, 0xAE, 0xD9,
+		0x85, 0xD9, 0x85, 0xD9, 0x85, 0xD9, 0x89, 0xD9,
+		0x85, 0xD9, 0x8A, 0xD9, 0x86, 0xD8, 0xAC, 0xD9,
+		0x86, 0xD8, 0xAD, 0xD9, 0x86, 0xD8, 0xAE, 0xD9,
+		0x86, 0xD9, 0x85, 0xD9, 0x86, 0xD9, 0x89, 0xD9,
+		0x86, 0xD9, 0x8A, 0xD9, 0x87, 0xD8, 0xAC, 0xD9,
+		0x87, 0xD9, 0x85, 0xD9, 0x87, 0xD9, 0x89, 0xD9,
+		0x87, 0xD9, 0x8A, 0xD9, 0x8A, 0xD8, 0xAC, 0xD9,
+		0x8A, 0xD8, 0xAD, 0xD9, 0x8A, 0xD8, 0xAE, 0xD9,
+		0x8A, 0xD9, 0x85, 0xD9, 0x8A, 0xD9, 0x89, 0xD9,
+		0x8A, 0xD9, 0x8A, 0xD8, 0xB0, 0xD9, 0xB0, 0xD8,
+		0xB1, 0xD9, 0xB0, 0xD9, 0x89, 0xD9, 0xB0, 0x20,
+		0xD9, 0x8C, 0xD9, 0x91, 0x20, 0xD9, 0x8D, 0xD9,
+		0x91, 0x20, 0xD9, 0x8E, 0xD9, 0x91, 0x20, 0xD9,
+		0x8F, 0xD9, 0x91, 0x20, 0xD9, 0x90, 0xD9, 0x91,
+		0x20, 0xD9, 0x91, 0xD9, 0xB0, 0xD9, 0x8A, 0xD9,
+		0x94, 0xD8, 0xB1, 0xD9, 0x8A, 0xD9, 0x94, 0xD8,
+		0xB2, 0xD9, 0x8A, 0xD9, 0x94, 0xD9, 0x85, 0xD9,
+		0x8A, 0xD9, 0x94, 0xD9, 0x86, 0xD9, 0x8A, 0xD9,
+		0x94, 0xD9, 0x89, 0xD9, 0x8A, 0xD9, 0x94, 0xD9,
+		0x8A, 0xD8, 0xA8, 0xD8, 0xB1, 0xD8, 0xA8, 0xD8,
+		0xB2, 0xD8, 0xA8, 0xD9, 0x85, 0xD8, 0xA8, 0xD9,
+		0x86, 0xD8, 0xA8, 0xD9, 0x89, 0xD8, 0xA8, 0xD9,
+		0x8A, 0xD8, 0xAA, 0xD8, 0xB1, 0xD8, 0xAA, 0xD8,
+		0xB2, 0xD8, 0xAA, 0xD9, 0x85, 0xD8, 0xAA, 0xD9,
+		0x86, 0xD8, 0xAA, 0xD9, 0x89, 0xD8, 0xAA, 0xD9,
+		0x8A, 0xD8, 0xAB, 0xD8, 0xB1, 0xD8, 0xAB, 0xD8,
+		0xB2, 0xD8, 0xAB, 0xD9, 0x85, 0xD8, 0xAB, 0xD9,
+		0x86, 0xD8, 0xAB, 0xD9, 0x89, 0xD8, 0xAB, 0xD9,
+		0x8A, 0xD9, 0x81, 0xD9, 0x89, 0xD9, 0x81, 0xD9,
+		0x8A, 0xD9, 0x82, 0xD9, 0x89, 0xD9, 0x82, 0xD9,
+		0x8A, 0xD9, 0x83, 0xD8, 0xA7, 0xD9, 0x83, 0xD9,
+		0x84, 0xD9, 0x83, 0xD9, 0x85, 0xD9, 0x83, 0xD9,
+		0x89, 0xD9, 0x83, 0xD9, 0x8A, 0xD9, 0x84, 0xD9,
+		0x85, 0xD9, 0x84, 0xD9, 0x89, 0xD9, 0x84, 0xD9,
+		0x8A, 0xD9, 0x85, 0xD8, 0xA7, 0xD9, 0x85, 0xD9,
+		0x85, 0xD9, 0x86, 0xD8, 0xB1, 0xD9, 0x86, 0xD8,
+		0xB2, 0xD9, 0x86, 0xD9, 0x85, 0xD9, 0x86, 0xD9,
+		0x86, 0xD9, 0x86, 0xD9, 0x89, 0xD9, 0x86, 0xD9,
+		0x8A, 0xD9, 0x89, 0xD9, 0xB0, 0xD9, 0x8A, 0xD8,
+		0xB1, 0xD9, 0x8A, 0xD8, 0xB2, 0xD9, 0x8A, 0xD9,
+		0x85, 0xD9, 0x8A, 0xD9, 0x86, 0xD9, 0x8A, 0xD9,
+		0x89, 0xD9, 0x8A, 0xD9, 0x8A, 0xD9, 0x8A, 0xD9,
+		0x94, 0xD8, 0xAC, 0xD9, 0x8A, 0xD9, 0x94, 0xD8,
+		0xAD, 0xD9, 0x8A, 0xD9, 0x94, 0xD8, 0xAE, 0xD9,
+		0x8A, 0xD9, 0x94, 0xD9, 0x85, 0xD9, 0x8A, 0xD9,
+		0x94, 0xD9, 0x87, 0xD8, 0xA8, 0xD8, 0xAC, 0xD8,
+		0xA8, 0xD8, 0xAD, 0xD8, 0xA8, 0xD8, 0xAE, 0xD8,
+		0xA8, 0xD9, 0x85, 0xD8, 0xA8, 0xD9, 0x87, 0xD8,
+		0xAA, 0xD8, 0xAC, 0xD8, 0xAA, 0xD8, 0xAD, 0xD8,
+		0xAA, 0xD8, 0xAE, 0xD8, 0xAA, 0xD9, 0x85, 0xD8,
+		0xAA, 0xD9, 0x87, 0xD8, 0xAB, 0xD9, 0x85, 0xD8,
+		0xAC, 0xD8, 0xAD, 0xD8, 0xAC, 0xD9, 0x85, 0xD8,
+		0xAD, 0xD8, 0xAC, 0xD8, 0xAD, 0xD9, 0x85, 0xD8,
+		0xAE, 0xD8, 0xAC, 0xD8, 0xAE, 0xD9, 0x85, 0xD8,
+		0xB3, 0xD8, 0xAC, 0xD8, 0xB3, 0xD8, 0xAD, 0xD8,
+		0xB3, 0xD8, 0xAE, 0xD8, 0xB3, 0xD9, 0x85, 0xD8,
+		0xB5, 0xD8, 0xAD, 0xD8, 0xB5, 0xD8, 0xAE, 0xD8,
+		0xB5, 0xD9, 0x85, 0xD8, 0xB6, 0xD8, 0xAC, 0xD8,
+		0xB6, 0xD8, 0xAD, 0xD8, 0xB6, 0xD8, 0xAE, 0xD8,
+		0xB6, 0xD9, 0x85, 0xD8, 0xB7, 0xD8, 0xAD, 0xD8,
+		0xB8, 0xD9, 0x85, 0xD8, 0xB9, 0xD8, 0xAC, 0xD8,
+		0xB9, 0xD9, 0x85, 0xD8, 0xBA, 0xD8, 0xAC, 0xD8,
+		0xBA, 0xD9, 0x85, 0xD9, 0x81, 0xD8, 0xAC, 0xD9,
+		0x81, 0xD8, 0xAD, 0xD9, 0x81, 0xD8, 0xAE, 0xD9,
+		0x81, 0xD9, 0x85, 0xD9, 0x82, 0xD8, 0xAD, 0xD9,
+		0x82, 0xD9, 0x85, 0xD9, 0x83, 0xD8, 0xAC, 0xD9,
+		0x83, 0xD8, 0xAD, 0xD9, 0x83, 0xD8, 0xAE, 0xD9,
+		0x83, 0xD9, 0x84, 0xD9, 0x83, 0xD9, 0x85, 0xD9,
+		0x84, 0xD8, 0xAC, 0xD9, 0x84, 0xD8, 0xAD, 0xD9,
+		0x84, 0xD8, 0xAE, 0xD9, 0x84, 0xD9, 0x85, 0xD9,
+		0x84, 0xD9, 0x87, 0xD9, 0x85, 0xD8, 0xAC, 0xD9,
+		0x85, 0xD8, 0xAD, 0xD9, 0x85, 0xD8, 0xAE, 0xD9,
+		0x85, 0xD9, 0x85, 0xD9, 0x86, 0xD8, 0xAC, 0xD9,
+		0x86, 0xD8, 0xAD, 0xD9, 0x86, 0xD8, 0xAE, 0xD9,
+		0x86, 0xD9, 0x85, 0xD9, 0x86, 0xD9, 0x87, 0xD9,
+		0x87, 0xD8, 0xAC, 0xD9, 0x87, 0xD9, 0x85, 0xD9,
+		0x87, 0xD9, 0xB0, 0xD9, 0x8A, 0xD8, 0xAC, 0xD9,
+		0x8A, 0xD8, 0xAD, 0xD9, 0x8A, 0xD8, 0xAE, 0xD9,
+		0x8A, 0xD9, 0x85, 0xD9, 0x8A, 0xD9, 0x87, 0xD9,
+		0x8A, 0xD9, 0x94, 0xD9, 0x85, 0xD9, 0x8A, 0xD9,
+		0x94, 0xD9, 0x87, 0xD8, 0xA8, 0xD9, 0x85, 0xD8,
+		0xA8, 0xD9, 0x87, 0xD8, 0xAA, 0xD9, 0x85, 0xD8,
+		0xAA, 0xD9, 0x87, 0xD8, 0xAB, 0xD9, 0x85, 0xD8,
+		0xAB, 0xD9, 0x87, 0xD8, 0xB3, 0xD9, 0x85, 0xD8,
+		0xB3, 0xD9, 0x87, 0xD8, 0xB4, 0xD9, 0x85, 0xD8,
+		0xB4, 0xD9, 0x87, 0xD9, 0x83, 0xD9, 0x84, 0xD9,
+		0x83, 0xD9, 0x85, 0xD9, 0x84, 0xD9, 0x85, 0xD9,
+		0x86, 0xD9, 0x85, 0xD9, 0x86, 0xD9, 0x87, 0xD9,
+		0x8A, 0xD9, 0x85, 0xD9, 0x8A, 0xD9, 0x87, 0xD9,
+		0x80, 0xD9, 0x8E, 0xD9, 0x91, 0xD9, 0x80, 0xD9,
+		0x8F, 0xD9, 0x91, 0xD9, 0x80, 0xD9, 0x90, 0xD9,
+		0x91, 0xD8, 0xB7, 0xD9, 0x89, 0xD8, 0xB7, 0xD9,
+		0x8A, 0xD8, 0xB9, 0xD9, 0x89, 0xD8, 0xB9, 0xD9,
+		0x8A, 0xD8, 0xBA, 0xD9, 0x89, 0xD8, 0xBA, 0xD9,
+		0x8A, 0xD8, 0xB3, 0xD9, 0x89, 0xD8, 0xB3, 0xD9,
+		0x8A, 0xD8, 0xB4, 0xD9, 0x89, 0xD8, 0xB4, 0xD9,
+		0x8A, 0xD8, 0xAD, 0xD9, 0x89, 0xD8, 0xAD, 0xD9,
+		0x8A, 0xD8, 0xAC, 0xD9, 0x89, 0xD8, 0xAC, 0xD9,
+		0x8A, 0xD8, 0xAE, 0xD9, 0x89, 0xD8, 0xAE, 0xD9,
+		0x8A, 0xD8, 0xB5, 0xD9, 0x89, 0xD8, 0xB5, 0xD9,
+		0x8A, 0xD8, 0xB6, 0xD9, 0x89, 0xD8, 0xB6, 0xD9,
+		0x8A, 0xD8, 0xB4, 0xD8, 0xAC, 0xD8, 0xB4, 0xD8,
+		0xAD, 0xD8, 0xB4, 0xD8, 0xAE, 0xD8, 0xB4, 0xD9,
+		0x85, 0xD8, 0xB4, 0xD8, 0xB1, 0xD8, 0xB3, 0xD8,
+		0xB1, 0xD8, 0xB5, 0xD8, 0xB1, 0xD8, 0xB6, 0xD8,
+		0xB1, 0xD8, 0xB7, 0xD9, 0x89, 0xD8, 0xB7, 0xD9,
+		0x8A, 0xD8, 0xB9, 0xD9, 0x89, 0xD8, 0xB9, 0xD9,
+		0x8A, 0xD8, 0xBA, 0xD9, 0x89, 0xD8, 0xBA, 0xD9,
+		0x8A, 0xD8, 0xB3, 0xD9, 0x89, 0xD8, 0xB3, 0xD9,
+		0x8A, 0xD8, 0xB4, 0xD9, 0x89, 0xD8, 0xB4, 0xD9,
+		0x8A, 0xD8, 0xAD, 0xD9, 0x89, 0xD8, 0xAD, 0xD9,
+		0x8A, 0xD8, 0xAC, 0xD9, 0x89, 0xD8, 0xAC, 0xD9,
+		0x8A, 0xD8, 0xAE, 0xD9, 0x89, 0xD8, 0xAE, 0xD9,
+		0x8A, 0xD8, 0xB5, 0xD9, 0x89, 0xD8, 0xB5, 0xD9,
+		0x8A, 0xD8, 0xB6, 0xD9, 0x89, 0xD8, 0xB6, 0xD9,
+		0x8A, 0xD8, 0xB4, 0xD8, 0xAC, 0xD8, 0xB4, 0xD8,
+		0xAD, 0xD8, 0xB4, 0xD8, 0xAE, 0xD8, 0xB4, 0xD9,
+		0x85, 0xD8, 0xB4, 0xD8, 0xB1, 0xD8, 0xB3, 0xD8,
+		0xB1, 0xD8, 0xB5, 0xD8, 0xB1, 0xD8, 0xB6, 0xD8,
+		0xB1, 0xD8, 0xB4, 0xD8, 0xAC, 0xD8, 0xB4, 0xD8,
+		0xAD, 0xD8, 0xB4, 0xD8, 0xAE, 0xD8, 0xB4, 0xD9,
+		0x85, 0xD8, 0xB3, 0xD9, 0x87, 0xD8, 0xB4, 0xD9,
+		0x87, 0xD8, 0xB7, 0xD9, 0x85, 0xD8, 0xB3, 0xD8,
+		0xAC, 0xD8, 0xB3, 0xD8, 0xAD, 0xD8, 0xB3, 0xD8,
+		0xAE, 0xD8, 0xB4, 0xD8, 0xAC, 0xD8, 0xB4, 0xD8,
+		0xAD, 0xD8, 0xB4, 0xD8, 0xAE, 0xD8, 0xB7, 0xD9,
+		0x85, 0xD8, 0xB8, 0xD9, 0x85, 0xD8, 0xA7, 0xD9,
+		0x8B, 0xD8, 0xA7, 0xD9, 0x8B, 0xD8, 0xAA, 0xD8,
+		0xAC, 0xD9, 0x85, 0xD8, 0xAA, 0xD8, 0xAD, 0xD8,
+		0xAC, 0xD8, 0xAA, 0xD8, 0xAD, 0xD8, 0xAC, 0xD8,
+		0xAA, 0xD8, 0xAD, 0xD9, 0x85, 0xD8, 0xAA, 0xD8,
+		0xAE, 0xD9, 0x85, 0xD8, 0xAA, 0xD9, 0x85, 0xD8,
+		0xAC, 0xD8, 0xAA, 0xD9, 0x85, 0xD8, 0xAD, 0xD8,
+		0xAA, 0xD9, 0x85, 0xD8, 0xAE, 0xD8, 0xAC, 0xD9,
+		0x85, 0xD8, 0xAD, 0xD8, 0xAC, 0xD9, 0x85, 0xD8,
+		0xAD, 0xD8, 0xAD, 0xD9, 0x85, 0xD9, 0x8A, 0xD8,
+		0xAD, 0xD9, 0x85, 0xD9, 0x89, 0xD8, 0xB3, 0xD8,
+		0xAD, 0xD8, 0xAC, 0xD8, 0xB3, 0xD8, 0xAC, 0xD8,
+		0xAD, 0xD8, 0xB3, 0xD8, 0xAC, 0xD9, 0x89, 0xD8,
+		0xB3, 0xD9, 0x85, 0xD8, 0xAD, 0xD8, 0xB3, 0xD9,
+		0x85, 0xD8, 0xAD, 0xD8, 0xB3, 0xD9, 0x85, 0xD8,
+		0xAC, 0xD8, 0xB3, 0xD9, 0x85, 0xD9, 0x85, 0xD8,
+		0xB3, 0xD9, 0x85, 0xD9, 0x85, 0xD8, 0xB5, 0xD8,
+		0xAD, 0xD8, 0xAD, 0xD8, 0xB5, 0xD8, 0xAD, 0xD8,
+		0xAD, 0xD8, 0xB5, 0xD9, 0x85, 0xD9, 0x85, 0xD8,
+		0xB4, 0xD8, 0xAD, 0xD9, 0x85, 0xD8, 0xB4, 0xD8,
+		0xAD, 0xD9, 0x85, 0xD8, 0xB4, 0xD8, 0xAC, 0xD9,
+		0x8A, 0xD8, 0xB4, 0xD9, 0x85, 0xD8, 0xAE, 0xD8,
+		0xB4, 0xD9, 0x85, 0xD8, 0xAE, 0xD8, 0xB4, 0xD9,
+		0x85, 0xD9, 0x85, 0xD8, 0xB4, 0xD9, 0x85, 0xD9,
+		0x85, 0xD8, 0xB6, 0xD8, 0xAD, 0xD9, 0x89, 0xD8,
+		0xB6, 0xD8, 0xAE, 0xD9, 0x85, 0xD8, 0xB6, 0xD8,
+		0xAE, 0xD9, 0x85, 0xD8, 0xB7, 0xD9, 0x85, 0xD8,
+		0xAD, 0xD8, 0xB7, 0xD9, 0x85, 0xD8, 0xAD, 0xD8,
+		0xB7, 0xD9, 0x85, 0xD9, 0x85, 0xD8, 0xB7, 0xD9,
+		0x85, 0xD9, 0x8A, 0xD8, 0xB9, 0xD8, 0xAC, 0xD9,
+		0x85, 0xD8, 0xB9, 0xD9, 0x85, 0xD9, 0x85, 0xD8,
+		0xB9, 0xD9, 0x85, 0xD9, 0x85, 0xD8, 0xB9, 0xD9,
+		0x85, 0xD9, 0x89, 0xD8, 0xBA, 0xD9, 0x85, 0xD9,
+		0x85, 0xD8, 0xBA, 0xD9, 0x85, 0xD9, 0x8A, 0xD8,
+		0xBA, 0xD9, 0x85, 0xD9, 0x89, 0xD9, 0x81, 0xD8,
+		0xAE, 0xD9, 0x85, 0xD9, 0x81, 0xD8, 0xAE, 0xD9,
+		0x85, 0xD9, 0x82, 0xD9, 0x85, 0xD8, 0xAD, 0xD9,
+		0x82, 0xD9, 0x85, 0xD9, 0x85, 0xD9, 0x84, 0xD8,
+		0xAD, 0xD9, 0x85, 0xD9, 0x84, 0xD8, 0xAD, 0xD9,
+		0x8A, 0xD9, 0x84, 0xD8, 0xAD, 0xD9, 0x89, 0xD9,
+		0x84, 0xD8, 0xAC, 0xD8, 0xAC, 0xD9, 0x84, 0xD8,
+		0xAC, 0xD8, 0xAC, 0xD9, 0x84, 0xD8, 0xAE, 0xD9,
+		0x85, 0xD9, 0x84, 0xD8, 0xAE, 0xD9, 0x85, 0xD9,
+		0x84, 0xD9, 0x85, 0xD8, 0xAD, 0xD9, 0x84, 0xD9,
+		0x85, 0xD8, 0xAD, 0xD9, 0x85, 0xD8, 0xAD, 0xD8,
+		0xAC, 0xD9, 0x85, 0xD8, 0xAD, 0xD9, 0x85, 0xD9,
+		0x85, 0xD8, 0xAD, 0xD9, 0x8A, 0xD9, 0x85, 0xD8,
+		0xAC, 0xD8, 0xAD, 0xD9, 0x85, 0xD8, 0xAC, 0xD9,
+		0x85, 0xD9, 0x85, 0xD8, 0xAE, 0xD8, 0xAC, 0xD9,
+		0x85, 0xD8, 0xAE, 0xD9, 0x85, 0xD9, 0x85, 0xD8,
+		0xAC, 0xD8, 0xAE, 0xD9, 0x87, 0xD9, 0x85, 0xD8,
+		0xAC, 0xD9, 0x87, 0xD9, 0x85, 0xD9, 0x85, 0xD9,
+		0x86, 0xD8, 0xAD, 0xD9, 0x85, 0xD9, 0x86, 0xD8,
+		0xAD, 0xD9, 0x89, 0xD9, 0x86, 0xD8, 0xAC, 0xD9,
+		0x85, 0xD9, 0x86, 0xD8, 0xAC, 0xD9, 0x85, 0xD9,
+		0x86, 0xD8, 0xAC, 0xD9, 0x89, 0xD9, 0x86, 0xD9,
+		0x85, 0xD9, 0x8A, 0xD9, 0x86, 0xD9, 0x85, 0xD9,
+		0x89, 0xD9, 0x8A, 0xD9, 0x85, 0xD9, 0x85, 0xD9,
+		0x8A, 0xD9, 0x85, 0xD9, 0x85, 0xD8, 0xA8, 0xD8,
+		0xAE, 0xD9, 0x8A, 0xD8, 0xAA, 0xD8, 0xAC, 0xD9,
+		0x8A, 0xD8, 0xAA, 0xD8, 0xAC, 0xD9, 0x89, 0xD8,
+		0xAA, 0xD8, 0xAE, 0xD9, 0x8A, 0xD8, 0xAA, 0xD8,
+		0xAE, 0xD9, 0x89, 0xD8, 0xAA, 0xD9, 0x85, 0xD9,
+		0x8A, 0xD8, 0xAA, 0xD9, 0x85, 0xD9, 0x89, 0xD8,
+		0xAC, 0xD9, 0x85, 0xD9, 0x8A, 0xD8, 0xAC, 0xD8,
+		0xAD, 0xD9, 0x89, 0xD8, 0xAC, 0xD9, 0x85, 0xD9,
+		0x89, 0xD8, 0xB3, 0xD8, 0xAE, 0xD9, 0x89, 0xD8,
+		0xB5, 0xD8, 0xAD, 0xD9, 0x8A, 0xD8, 0xB4, 0xD8,
+		0xAD, 0xD9, 0x8A, 0xD8, 0xB6, 0xD8, 0xAD, 0xD9,
+		0x8A, 0xD9, 0x84, 0xD8, 0xAC, 0xD9, 0x8A, 0xD9,
+		0x84, 0xD9, 0x85, 0xD9, 0x8A, 0xD9, 0x8A, 0xD8,
+		0xAD, 0xD9, 0x8A, 0xD9, 0x8A, 0xD8, 0xAC, 0xD9,
+		0x8A, 0xD9, 0x8A, 0xD9, 0x85, 0xD9, 0x8A, 0xD9,
+		0x85, 0xD9, 0x85, 0xD9, 0x8A, 0xD9, 0x82, 0xD9,
+		0x85, 0xD9, 0x8A, 0xD9, 0x86, 0xD8, 0xAD, 0xD9,
+		0x8A, 0xD9, 0x82, 0xD9, 0x85, 0xD8, 0xAD, 0xD9,
+		0x84, 0xD8, 0xAD, 0xD9, 0x85, 0xD8, 0xB9, 0xD9,
+		0x85, 0xD9, 0x8A, 0xD9, 0x83, 0xD9, 0x85, 0xD9,
+		0x8A, 0xD9, 0x86, 0xD8, 0xAC, 0xD8, 0xAD, 0xD9,
+		0x85, 0xD8, 0xAE, 0xD9, 0x8A, 0xD9, 0x84, 0xD8,
+		0xAC, 0xD9, 0x85, 0xD9, 0x83, 0xD9, 0x85, 0xD9,
+		0x85, 0xD9, 0x84, 0xD8, 0xAC, 0xD9, 0x85, 0xD9,
+		0x86, 0xD8, 0xAC, 0xD8, 0xAD, 0xD8, 0xAC, 0xD8,
+		0xAD, 0xD9, 0x8A, 0xD8, 0xAD, 0xD8, 0xAC, 0xD9,
+		0x8A, 0xD9, 0x85, 0xD8, 0xAC, 0xD9, 0x8A, 0xD9,
+		0x81, 0xD9, 0x85, 0xD9, 0x8A, 0xD8, 0xA8, 0xD8,
+		0xAD, 0xD9, 0x8A, 0xD9, 0x83, 0xD9, 0x85, 0xD9,
+		0x85, 0xD8, 0xB9, 0xD8, 0xAC, 0xD9, 0x85, 0xD8,
+		0xB5, 0xD9, 0x85, 0xD9, 0x85, 0xD8, 0xB3, 0xD8,
+		0xAE, 0xD9, 0x8A, 0xD9, 0x86, 0xD8, 0xAC, 0xD9,
+		0x8A, 0xD8, 0xB5, 0xD9, 0x84, 0xDB, 0x92, 0xD9,
+		0x82, 0xD9, 0x84, 0xDB, 0x92, 0xD8, 0xA7, 0xD9,
+		0x84, 0xD9, 0x84, 0xD9, 0x87, 0xD8, 0xA7, 0xD9,
+		0x83, 0xD8, 0xA8, 0xD8, 0xB1, 0xD9, 0x85, 0xD8,
+		0xAD, 0xD9, 0x85, 0xD8, 0xAF, 0xD8, 0xB5, 0xD9,
+		0x84, 0xD8, 0xB9, 0xD9, 0x85, 0xD8, 0xB1, 0xD8,
+		0xB3, 0xD9, 0x88, 0xD9, 0x84, 0xD8, 0xB9, 0xD9,
+		0x84, 0xD9, 0x8A, 0xD9, 0x87, 0xD9, 0x88, 0xD8,
+		0xB3, 0xD9, 0x84, 0xD9, 0x85, 0xD8, 0xB5, 0xD9,
+		0x84, 0xD9, 0x89, 0xD8, 0xB5, 0xD9, 0x84, 0xD9,
+		0x89, 0x20, 0xD8, 0xA7, 0xD9, 0x84, 0xD9, 0x84,
+		0xD9, 0x87, 0x20, 0xD8, 0xB9, 0xD9, 0x84, 0xD9,
+		0x8A, 0xD9, 0x87, 0x20, 0xD9, 0x88, 0xD8, 0xB3,
+		0xD9, 0x84, 0xD9, 0x85, 0xD8, 0xAC, 0xD9, 0x84,
+		0x20, 0xD8, 0xAC, 0xD9, 0x84, 0xD8, 0xA7, 0xD9,
+		0x84, 0xD9, 0x87, 0xD8, 0xB1, 0xDB, 0x8C, 0xD8,
+		0xA7, 0xD9, 0x84, 0x2C, 0xE3, 0x80, 0x81, 0xE3,
+		0x80, 0x82, 0x3A, 0x3B, 0x21, 0x3F, 0xE3, 0x80,
+		0x96, 0xE3, 0x80, 0x97, 0x2E, 0x2E, 0x2E, 0x2E,
+		0x2E, 0xE2, 0x80, 0x94, 0xE2, 0x80, 0x93, 0x5F,
+		0x5F, 0x28, 0x29, 0x7B, 0x7D, 0xE3, 0x80, 0x94,
+		0xE3, 0x80, 0x95, 0xE3, 0x80, 0x90, 0xE3, 0x80,
+		0x91, 0xE3, 0x80, 0x8A, 0xE3, 0x80, 0x8B, 0xE3,
+		0x80, 0x88, 0xE3, 0x80, 0x89, 0xE3, 0x80, 0x8C,
+		0xE3, 0x80, 0x8D, 0xE3, 0x80, 0x8E, 0xE3, 0x80,
+		0x8F, 0x5B, 0x5D, 0x20, 0xCC, 0x85, 0x20, 0xCC,
+		0x85, 0x20, 0xCC, 0x85, 0x20, 0xCC, 0x85, 0x5F,
+		0x5F, 0x5F, 0x2C, 0xE3, 0x80, 0x81, 0x2E, 0x3B,
+		0x3A, 0x3F, 0x21, 0xE2, 0x80, 0x94, 0x28, 0x29,
+		0x7B, 0x7D, 0xE3, 0x80, 0x94, 0xE3, 0x80, 0x95,
+		0x23, 0x26, 0x2A, 0x2B, 0x2D, 0x3C, 0x3E, 0x3D,
+		0x5C, 0x24, 0x25, 0x40, 0x20, 0xD9, 0x8B, 0xD9,
+		0x80, 0xD9, 0x8B, 0x20, 0xD9, 0x8C, 0x20, 0xD9,
+		0x8D, 0x20, 0xD9, 0x8E, 0xD9, 0x80, 0xD9, 0x8E,
+		0x20, 0xD9, 0x8F, 0xD9, 0x80, 0xD9, 0x8F, 0x20,
+		0xD9, 0x90, 0xD9, 0x80, 0xD9, 0x90, 0x20, 0xD9,
+		0x91, 0xD9, 0x80, 0xD9, 0x91, 0x20, 0xD9, 0x92,
+		0xD9, 0x80, 0xD9, 0x92, 0xD8, 0xA1, 0xD8, 0xA7,
+		0xD9, 0x93, 0xD8, 0xA7, 0xD9, 0x93, 0xD8, 0xA7,
+		0xD9, 0x94, 0xD8, 0xA7, 0xD9, 0x94, 0xD9, 0x88,
+		0xD9, 0x94, 0xD9, 0x88, 0xD9, 0x94, 0xD8, 0xA7,
+		0xD9, 0x95, 0xD8, 0xA7, 0xD9, 0x95, 0xD9, 0x8A,
+		0xD9, 0x94, 0xD9, 0x8A, 0xD9, 0x94, 0xD9, 0x8A,
+		0xD9, 0x94, 0xD9, 0x8A, 0xD9, 0x94, 0xD8, 0xA7,
+		0xD8, 0xA7, 0xD8, 0xA8, 0xD8, 0xA8, 0xD8, 0xA8,
+		0xD8, 0xA8, 0xD8, 0xA9, 0xD8, 0xA9, 0xD8, 0xAA,
+		0xD8, 0xAA, 0xD8, 0xAA, 0xD8, 0xAA, 0xD8, 0xAB,
+		0xD8, 0xAB, 0xD8, 0xAB, 0xD8, 0xAB, 0xD8, 0xAC,
+		0xD8, 0xAC, 0xD8, 0xAC, 0xD8, 0xAC, 0xD8, 0xAD,
+		0xD8, 0xAD, 0xD8, 0xAD, 0xD8, 0xAD, 0xD8, 0xAE,
+		0xD8, 0xAE, 0xD8, 0xAE, 0xD8, 0xAE, 0xD8, 0xAF,
+		0xD8, 0xAF, 0xD8, 0xB0, 0xD8, 0xB0, 0xD8, 0xB1,
+		0xD8, 0xB1, 0xD8, 0xB2, 0xD8, 0xB2, 0xD8, 0xB3,
+		0xD8, 0xB3, 0xD8, 0xB3, 0xD8, 0xB3, 0xD8, 0xB4,
+		0xD8, 0xB4, 0xD8, 0xB4, 0xD8, 0xB4, 0xD8, 0xB5,
+		0xD8, 0xB5, 0xD8, 0xB5, 0xD8, 0xB5, 0xD8, 0xB6,
+		0xD8, 0xB6, 0xD8, 0xB6, 0xD8, 0xB6, 0xD8, 0xB7,
+		0xD8, 0xB7, 0xD8, 0xB7, 0xD8, 0xB7, 0xD8, 0xB8,
+		0xD8, 0xB8, 0xD8, 0xB8, 0xD8, 0xB8, 0xD8, 0xB9,
+		0xD8, 0xB9, 0xD8, 0xB9, 0xD8, 0xB9, 0xD8, 0xBA,
+		0xD8, 0xBA, 0xD8, 0xBA, 0xD8, 0xBA, 0xD9, 0x81,
+		0xD9, 0x81, 0xD9, 0x81, 0xD9, 0x81, 0xD9, 0x82,
+		0xD9, 0x82, 0xD9, 0x82, 0xD9, 0x82, 0xD9, 0x83,
+		0xD9, 0x83, 0xD9, 0x83, 0xD9, 0x83, 0xD9, 0x84,
+		0xD9, 0x84, 0xD9, 0x84, 0xD9, 0x84, 0xD9, 0x85,
+		0xD9, 0x85, 0xD9, 0x85, 0xD9, 0x85, 0xD9, 0x86,
+		0xD9, 0x86, 0xD9, 0x86, 0xD9, 0x86, 0xD9, 0x87,
+		0xD9, 0x87, 0xD9, 0x87, 0xD9, 0x87, 0xD9, 0x88,
+		0xD9, 0x88, 0xD9, 0x89, 0xD9, 0x89, 0xD9, 0x8A,
+		0xD9, 0x8A, 0xD9, 0x8A, 0xD9, 0x8A, 0xD9, 0x84,
+		0xD8, 0xA7, 0xD9, 0x93, 0xD9, 0x84, 0xD8, 0xA7,
+		0xD9, 0x93, 0xD9, 0x84, 0xD8, 0xA7, 0xD9, 0x94,
+		0xD9, 0x84, 0xD8, 0xA7, 0xD9, 0x94, 0xD9, 0x84,
+		0xD8, 0xA7, 0xD9, 0x95, 0xD9, 0x84, 0xD8, 0xA7,
+		0xD9, 0x95, 0xD9, 0x84, 0xD8, 0xA7, 0xD9, 0x84,
+		0xD8, 0xA7, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26,
+		0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E,
+		0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36,
+		0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E,
+		0x3F, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46,
+		0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E,
+		0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56,
+		0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E,
+		0x5F, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66,
+		0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E,
+		0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76,
+		0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E,
+		0xE2, 0xA6, 0x85, 0xE2, 0xA6, 0x86, 0xE3, 0x80,
+		0x82, 0xE3, 0x80, 0x8C, 0xE3, 0x80, 0x8D, 0xE3,
+		0x80, 0x81, 0xE3, 0x83, 0xBB, 0xE3, 0x83, 0xB2,
+		0xE3, 0x82, 0xA1, 0xE3, 0x82, 0xA3, 0xE3, 0x82,
+		0xA5, 0xE3, 0x82, 0xA7, 0xE3, 0x82, 0xA9, 0xE3,
+		0x83, 0xA3, 0xE3, 0x83, 0xA5, 0xE3, 0x83, 0xA7,
+		0xE3, 0x83, 0x83, 0xE3, 0x83, 0xBC, 0xE3, 0x82,
+		0xA2, 0xE3, 0x82, 0xA4, 0xE3, 0x82, 0xA6, 0xE3,
+		0x82, 0xA8, 0xE3, 0x82, 0xAA, 0xE3, 0x82, 0xAB,
+		0xE3, 0x82, 0xAD, 0xE3, 0x82, 0xAF, 0xE3, 0x82,
+		0xB1, 0xE3, 0x82, 0xB3, 0xE3, 0x82, 0xB5, 0xE3,
+		0x82, 0xB7, 0xE3, 0x82, 0xB9, 0xE3, 0x82, 0xBB,
+		0xE3, 0x82, 0xBD, 0xE3, 0x82, 0xBF, 0xE3, 0x83,
+		0x81, 0xE3, 0x83, 0x84, 0xE3, 0x83, 0x86, 0xE3,
+		0x83, 0x88, 0xE3, 0x83, 0x8A, 0xE3, 0x83, 0x8B,
+		0xE3, 0x83, 0x8C, 0xE3, 0x83, 0x8D, 0xE3, 0x83,
+		0x8E, 0xE3, 0x83, 0x8F, 0xE3, 0x83, 0x92, 0xE3,
+		0x83, 0x95, 0xE3, 0x83, 0x98, 0xE3, 0x83, 0x9B,
+		0xE3, 0x83, 0x9E, 0xE3, 0x83, 0x9F, 0xE3, 0x83,
+		0xA0, 0xE3, 0x83, 0xA1, 0xE3, 0x83, 0xA2, 0xE3,
+		0x83, 0xA4, 0xE3, 0x83, 0xA6, 0xE3, 0x83, 0xA8,
+		0xE3, 0x83, 0xA9, 0xE3, 0x83, 0xAA, 0xE3, 0x83,
+		0xAB, 0xE3, 0x83, 0xAC, 0xE3, 0x83, 0xAD, 0xE3,
+		0x83, 0xAF, 0xE3, 0x83, 0xB3, 0xE3, 0x82, 0x99,
+		0xE3, 0x82, 0x9A, 0xE1, 0x85, 0xA0, 0xE1, 0x84,
+		0x80, 0xE1, 0x84, 0x81, 0xE1, 0x86, 0xAA, 0xE1,
+		0x84, 0x82, 0xE1, 0x86, 0xAC, 0xE1, 0x86, 0xAD,
+		0xE1, 0x84, 0x83, 0xE1, 0x84, 0x84, 0xE1, 0x84,
+		0x85, 0xE1, 0x86, 0xB0, 0xE1, 0x86, 0xB1, 0xE1,
+		0x86, 0xB2, 0xE1, 0x86, 0xB3, 0xE1, 0x86, 0xB4,
+		0xE1, 0x86, 0xB5, 0xE1, 0x84, 0x9A, 0xE1, 0x84,
+		0x86, 0xE1, 0x84, 0x87, 0xE1, 0x84, 0x88, 0xE1,
+		0x84, 0xA1, 0xE1, 0x84, 0x89, 0xE1, 0x84, 0x8A,
+		0xE1, 0x84, 0x8B, 0xE1, 0x84, 0x8C, 0xE1, 0x84,
+		0x8D, 0xE1, 0x84, 0x8E, 0xE1, 0x84, 0x8F, 0xE1,
+		0x84, 0x90, 0xE1, 0x84, 0x91, 0xE1, 0x84, 0x92,
+		0xE1, 0x85, 0xA1, 0xE1, 0x85, 0xA2, 0xE1, 0x85,
+		0xA3, 0xE1, 0x85, 0xA4, 0xE1, 0x85, 0xA5, 0xE1,
+		0x85, 0xA6, 0xE1, 0x85, 0xA7, 0xE1, 0x85, 0xA8,
+		0xE1, 0x85, 0xA9, 0xE1, 0x85, 0xAA, 0xE1, 0x85,
+		0xAB, 0xE1, 0x85, 0xAC, 0xE1, 0x85, 0xAD, 0xE1,
+		0x85, 0xAE, 0xE1, 0x85, 0xAF, 0xE1, 0x85, 0xB0,
+		0xE1, 0x85, 0xB1, 0xE1, 0x85, 0xB2, 0xE1, 0x85,
+		0xB3, 0xE1, 0x85, 0xB4, 0xE1, 0x85, 0xB5, 0xC2,
+		0xA2, 0xC2, 0xA3, 0xC2, 0xAC, 0x20, 0xCC, 0x84,
+		0xC2, 0xA6, 0xC2, 0xA5, 0xE2, 0x82, 0xA9, 0xE2,
+		0x94, 0x82, 0xE2, 0x86, 0x90, 0xE2, 0x86, 0x91,
+		0xE2, 0x86, 0x92, 0xE2, 0x86, 0x93, 0xE2, 0x96,
+		0xA0, 0xE2, 0x97, 0x8B, 0xF6, 0xF0, 0x9D, 0x85,
+		0x97, 0xF0, 0x9D, 0x85, 0xA5, 0xF6, 0xF0, 0x9D,
+		0x85, 0x98, 0xF0, 0x9D, 0x85, 0xA5, 0xF6, 0xF0,
+		0x9D, 0x85, 0x98, 0xF0, 0x9D, 0x85, 0xA5, 0xF0,
+		0x9D, 0x85, 0xAE, 0xF6, 0xF0, 0x9D, 0x85, 0x98,
+		0xF0, 0x9D, 0x85, 0xA5, 0xF0, 0x9D, 0x85, 0xAF,
+		0xF6, 0xF0, 0x9D, 0x85, 0x98, 0xF0, 0x9D, 0x85,
+		0xA5, 0xF0, 0x9D, 0x85, 0xB0, 0xF6, 0xF0, 0x9D,
+		0x85, 0x98, 0xF0, 0x9D, 0x85, 0xA5, 0xF0, 0x9D,
+		0x85, 0xB1, 0xF6, 0xF0, 0x9D, 0x85, 0x98, 0xF0,
+		0x9D, 0x85, 0xA5, 0xF0, 0x9D, 0x85, 0xB2, 0xF6,
+		0xF0, 0x9D, 0x86, 0xB9, 0xF0, 0x9D, 0x85, 0xA5,
+		0xF6, 0xF0, 0x9D, 0x86, 0xBA, 0xF0, 0x9D, 0x85,
+		0xA5, 0xF6, 0xF0, 0x9D, 0x86, 0xB9, 0xF0, 0x9D,
+		0x85, 0xA5, 0xF0, 0x9D, 0x85, 0xAE, 0xF6, 0xF0,
+		0x9D, 0x86, 0xBA, 0xF0, 0x9D, 0x85, 0xA5, 0xF0,
+		0x9D, 0x85, 0xAE, 0xF6, 0xF0, 0x9D, 0x86, 0xB9,
+		0xF0, 0x9D, 0x85, 0xA5, 0xF0, 0x9D, 0x85, 0xAF,
+		0xF6, 0xF0, 0x9D, 0x86, 0xBA, 0xF0, 0x9D, 0x85,
+		0xA5, 0xF0, 0x9D, 0x85, 0xAF, 0x41, 0x42, 0x43,
+		0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B,
+		0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53,
+		0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x61,
+		0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
+		0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71,
+		0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
+		0x7A, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
+		0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
+		0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
+		0x58, 0x59, 0x5A, 0x61, 0x62, 0x63, 0x64, 0x65,
+		0x66, 0x67, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E,
+		0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76,
+		0x77, 0x78, 0x79, 0x7A, 0x41, 0x42, 0x43, 0x44,
+		0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C,
+		0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54,
+		0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x61, 0x62,
+		0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A,
+		0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72,
+		0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A,
+		0x41, 0x43, 0x44, 0x47, 0x4A, 0x4B, 0x4E, 0x4F,
+		0x50, 0x51, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
+		0x59, 0x5A, 0x61, 0x62, 0x63, 0x64, 0x66, 0x68,
+		0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x70, 0x71,
+		0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
+		0x7A, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
+		0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
+		0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
+		0x58, 0x59, 0x5A, 0x61, 0x62, 0x63, 0x64, 0x65,
+		0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D,
+		0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75,
+		0x76, 0x77, 0x78, 0x79, 0x7A, 0x41, 0x42, 0x44,
+		0x45, 0x46, 0x47, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E,
+		0x4F, 0x50, 0x51, 0x53, 0x54, 0x55, 0x56, 0x57,
+		0x58, 0x59, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66,
+		0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E,
+		0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76,
+		0x77, 0x78, 0x79, 0x7A, 0x41, 0x42, 0x44, 0x45,
+		0x46, 0x47, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4F,
+		0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x61,
+		0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
+		0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71,
+		0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
+		0x7A, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
+		0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
+		0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
+		0x58, 0x59, 0x5A, 0x61, 0x62, 0x63, 0x64, 0x65,
+		0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D,
+		0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75,
+		0x76, 0x77, 0x78, 0x79, 0x7A, 0x41, 0x42, 0x43,
+		0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B,
+		0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53,
+		0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x61,
+		0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
+		0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71,
+		0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
+		0x7A, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
+		0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
+		0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
+		0x58, 0x59, 0x5A, 0x61, 0x62, 0x63, 0x64, 0x65,
+		0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D,
+		0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75,
+		0x76, 0x77, 0x78, 0x79, 0x7A, 0x41, 0x42, 0x43,
+		0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B,
+		0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53,
+		0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x61,
+		0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
+		0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71,
+		0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
+		0x7A, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
+		0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
+		0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
+		0x58, 0x59, 0x5A, 0x61, 0x62, 0x63, 0x64, 0x65,
+		0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D,
+		0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75,
+		0x76, 0x77, 0x78, 0x79, 0x7A, 0x41, 0x42, 0x43,
+		0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B,
+		0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53,
+		0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x61,
+		0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
+		0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71,
+		0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
+		0x7A, 0xC4, 0xB1, 0xC8, 0xB7, 0xCE, 0x91, 0xCE,
+		0x92, 0xCE, 0x93, 0xCE, 0x94, 0xCE, 0x95, 0xCE,
+		0x96, 0xCE, 0x97, 0xCE, 0x98, 0xCE, 0x99, 0xCE,
+		0x9A, 0xCE, 0x9B, 0xCE, 0x9C, 0xCE, 0x9D, 0xCE,
+		0x9E, 0xCE, 0x9F, 0xCE, 0xA0, 0xCE, 0xA1, 0xCE,
+		0x98, 0xCE, 0xA3, 0xCE, 0xA4, 0xCE, 0xA5, 0xCE,
+		0xA6, 0xCE, 0xA7, 0xCE, 0xA8, 0xCE, 0xA9, 0xE2,
+		0x88, 0x87, 0xCE, 0xB1, 0xCE, 0xB2, 0xCE, 0xB3,
+		0xCE, 0xB4, 0xCE, 0xB5, 0xCE, 0xB6, 0xCE, 0xB7,
+		0xCE, 0xB8, 0xCE, 0xB9, 0xCE, 0xBA, 0xCE, 0xBB,
+		0xCE, 0xBC, 0xCE, 0xBD, 0xCE, 0xBE, 0xCE, 0xBF,
+		0xCF, 0x80, 0xCF, 0x81, 0xCF, 0x82, 0xCF, 0x83,
+		0xCF, 0x84, 0xCF, 0x85, 0xCF, 0x86, 0xCF, 0x87,
+		0xCF, 0x88, 0xCF, 0x89, 0xE2, 0x88, 0x82, 0xCE,
+		0xB5, 0xCE, 0xB8, 0xCE, 0xBA, 0xCF, 0x86, 0xCF,
+		0x81, 0xCF, 0x80, 0xCE, 0x91, 0xCE, 0x92, 0xCE,
+		0x93, 0xCE, 0x94, 0xCE, 0x95, 0xCE, 0x96, 0xCE,
+		0x97, 0xCE, 0x98, 0xCE, 0x99, 0xCE, 0x9A, 0xCE,
+		0x9B, 0xCE, 0x9C, 0xCE, 0x9D, 0xCE, 0x9E, 0xCE,
+		0x9F, 0xCE, 0xA0, 0xCE, 0xA1, 0xCE, 0x98, 0xCE,
+		0xA3, 0xCE, 0xA4, 0xCE, 0xA5, 0xCE, 0xA6, 0xCE,
+		0xA7, 0xCE, 0xA8, 0xCE, 0xA9, 0xE2, 0x88, 0x87,
+		0xCE, 0xB1, 0xCE, 0xB2, 0xCE, 0xB3, 0xCE, 0xB4,
+		0xCE, 0xB5, 0xCE, 0xB6, 0xCE, 0xB7, 0xCE, 0xB8,
+		0xCE, 0xB9, 0xCE, 0xBA, 0xCE, 0xBB, 0xCE, 0xBC,
+		0xCE, 0xBD, 0xCE, 0xBE, 0xCE, 0xBF, 0xCF, 0x80,
+		0xCF, 0x81, 0xCF, 0x82, 0xCF, 0x83, 0xCF, 0x84,
+		0xCF, 0x85, 0xCF, 0x86, 0xCF, 0x87, 0xCF, 0x88,
+		0xCF, 0x89, 0xE2, 0x88, 0x82, 0xCE, 0xB5, 0xCE,
+		0xB8, 0xCE, 0xBA, 0xCF, 0x86, 0xCF, 0x81, 0xCF,
+		0x80, 0xCE, 0x91, 0xCE, 0x92, 0xCE, 0x93, 0xCE,
+		0x94, 0xCE, 0x95, 0xCE, 0x96, 0xCE, 0x97, 0xCE,
+		0x98, 0xCE, 0x99, 0xCE, 0x9A, 0xCE, 0x9B, 0xCE,
+		0x9C, 0xCE, 0x9D, 0xCE, 0x9E, 0xCE, 0x9F, 0xCE,
+		0xA0, 0xCE, 0xA1, 0xCE, 0x98, 0xCE, 0xA3, 0xCE,
+		0xA4, 0xCE, 0xA5, 0xCE, 0xA6, 0xCE, 0xA7, 0xCE,
+		0xA8, 0xCE, 0xA9, 0xE2, 0x88, 0x87, 0xCE, 0xB1,
+		0xCE, 0xB2, 0xCE, 0xB3, 0xCE, 0xB4, 0xCE, 0xB5,
+		0xCE, 0xB6, 0xCE, 0xB7, 0xCE, 0xB8, 0xCE, 0xB9,
+		0xCE, 0xBA, 0xCE, 0xBB, 0xCE, 0xBC, 0xCE, 0xBD,
+		0xCE, 0xBE, 0xCE, 0xBF, 0xCF, 0x80, 0xCF, 0x81,
+		0xCF, 0x82, 0xCF, 0x83, 0xCF, 0x84, 0xCF, 0x85,
+		0xCF, 0x86, 0xCF, 0x87, 0xCF, 0x88, 0xCF, 0x89,
+		0xE2, 0x88, 0x82, 0xCE, 0xB5, 0xCE, 0xB8, 0xCE,
+		0xBA, 0xCF, 0x86, 0xCF, 0x81, 0xCF, 0x80, 0xCE,
+		0x91, 0xCE, 0x92, 0xCE, 0x93, 0xCE, 0x94, 0xCE,
+		0x95, 0xCE, 0x96, 0xCE, 0x97, 0xCE, 0x98, 0xCE,
+		0x99, 0xCE, 0x9A, 0xCE, 0x9B, 0xCE, 0x9C, 0xCE,
+		0x9D, 0xCE, 0x9E, 0xCE, 0x9F, 0xCE, 0xA0, 0xCE,
+		0xA1, 0xCE, 0x98, 0xCE, 0xA3, 0xCE, 0xA4, 0xCE,
+		0xA5, 0xCE, 0xA6, 0xCE, 0xA7, 0xCE, 0xA8, 0xCE,
+		0xA9, 0xE2, 0x88, 0x87, 0xCE, 0xB1, 0xCE, 0xB2,
+		0xCE, 0xB3, 0xCE, 0xB4, 0xCE, 0xB5, 0xCE, 0xB6,
+		0xCE, 0xB7, 0xCE, 0xB8, 0xCE, 0xB9, 0xCE, 0xBA,
+		0xCE, 0xBB, 0xCE, 0xBC, 0xCE, 0xBD, 0xCE, 0xBE,
+		0xCE, 0xBF, 0xCF, 0x80, 0xCF, 0x81, 0xCF, 0x82,
+		0xCF, 0x83, 0xCF, 0x84, 0xCF, 0x85, 0xCF, 0x86,
+		0xCF, 0x87, 0xCF, 0x88, 0xCF, 0x89, 0xE2, 0x88,
+		0x82, 0xCE, 0xB5, 0xCE, 0xB8, 0xCE, 0xBA, 0xCF,
+		0x86, 0xCF, 0x81, 0xCF, 0x80, 0xCE, 0x91, 0xCE,
+		0x92, 0xCE, 0x93, 0xCE, 0x94, 0xCE, 0x95, 0xCE,
+		0x96, 0xCE, 0x97, 0xCE, 0x98, 0xCE, 0x99, 0xCE,
+		0x9A, 0xCE, 0x9B, 0xCE, 0x9C, 0xCE, 0x9D, 0xCE,
+		0x9E, 0xCE, 0x9F, 0xCE, 0xA0, 0xCE, 0xA1, 0xCE,
+		0x98, 0xCE, 0xA3, 0xCE, 0xA4, 0xCE, 0xA5, 0xCE,
+		0xA6, 0xCE, 0xA7, 0xCE, 0xA8, 0xCE, 0xA9, 0xE2,
+		0x88, 0x87, 0xCE, 0xB1, 0xCE, 0xB2, 0xCE, 0xB3,
+		0xCE, 0xB4, 0xCE, 0xB5, 0xCE, 0xB6, 0xCE, 0xB7,
+		0xCE, 0xB8, 0xCE, 0xB9, 0xCE, 0xBA, 0xCE, 0xBB,
+		0xCE, 0xBC, 0xCE, 0xBD, 0xCE, 0xBE, 0xCE, 0xBF,
+		0xCF, 0x80, 0xCF, 0x81, 0xCF, 0x82, 0xCF, 0x83,
+		0xCF, 0x84, 0xCF, 0x85, 0xCF, 0x86, 0xCF, 0x87,
+		0xCF, 0x88, 0xCF, 0x89, 0xE2, 0x88, 0x82, 0xCE,
+		0xB5, 0xCE, 0xB8, 0xCE, 0xBA, 0xCF, 0x86, 0xCF,
+		0x81, 0xCF, 0x80, 0xCF, 0x9C, 0xCF, 0x9D, 0x30,
+		0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
+		0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36,
+		0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34,
+		0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32,
+		0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30,
+		0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
+		0x39, 0xF6, 0xE4, 0xB8, 0xBD, 0xF6, 0xE4, 0xB8,
+		0xB8, 0xF6, 0xE4, 0xB9, 0x81, 0xF6, 0xF0, 0xA0,
+		0x84, 0xA2, 0xF6, 0xE4, 0xBD, 0xA0, 0xF6, 0xE4,
+		0xBE, 0xAE, 0xF6, 0xE4, 0xBE, 0xBB, 0xF6, 0xE5,
+		0x80, 0x82, 0xF6, 0xE5, 0x81, 0xBA, 0xF6, 0xE5,
+		0x82, 0x99, 0xF6, 0xE5, 0x83, 0xA7, 0xF6, 0xE5,
+		0x83, 0x8F, 0xF6, 0xE3, 0x92, 0x9E, 0xF6, 0xF0,
+		0xA0, 0x98, 0xBA, 0xF6, 0xE5, 0x85, 0x8D, 0xF6,
+		0xE5, 0x85, 0x94, 0xF6, 0xE5, 0x85, 0xA4, 0xF6,
+		0xE5, 0x85, 0xB7, 0xF6, 0xF0, 0xA0, 0x94, 0x9C,
+		0xF6, 0xE3, 0x92, 0xB9, 0xF6, 0xE5, 0x85, 0xA7,
+		0xF6, 0xE5, 0x86, 0x8D, 0xF6, 0xF0, 0xA0, 0x95,
+		0x8B, 0xF6, 0xE5, 0x86, 0x97, 0xF6, 0xE5, 0x86,
+		0xA4, 0xF6, 0xE4, 0xBB, 0x8C, 0xF6, 0xE5, 0x86,
+		0xAC, 0xF6, 0xE5, 0x86, 0xB5, 0xF6, 0xF0, 0xA9,
+		0x87, 0x9F, 0xF6, 0xE5, 0x87, 0xB5, 0xF6, 0xE5,
+		0x88, 0x83, 0xF6, 0xE3, 0x93, 0x9F, 0xF6, 0xE5,
+		0x88, 0xBB, 0xF6, 0xE5, 0x89, 0x86, 0xF6, 0xE5,
+		0x89, 0xB2, 0xF6, 0xE5, 0x89, 0xB7, 0xF6, 0xE3,
+		0x94, 0x95, 0xF6, 0xE5, 0x8B, 0x87, 0xF6, 0xE5,
+		0x8B, 0x89, 0xF6, 0xE5, 0x8B, 0xA4, 0xF6, 0xE5,
+		0x8B, 0xBA, 0xF6, 0xE5, 0x8C, 0x85, 0xF6, 0xE5,
+		0x8C, 0x86, 0xF6, 0xE5, 0x8C, 0x97, 0xF6, 0xE5,
+		0x8D, 0x89, 0xF6, 0xE5, 0x8D, 0x91, 0xF6, 0xE5,
+		0x8D, 0x9A, 0xF6, 0xE5, 0x8D, 0xB3, 0xF6, 0xE5,
+		0x8D, 0xBD, 0xF6, 0xE5, 0x8D, 0xBF, 0xF6, 0xE5,
+		0x8D, 0xBF, 0xF6, 0xE5, 0x8D, 0xBF, 0xF6, 0xF0,
+		0xA0, 0xA8, 0xAC, 0xF6, 0xE7, 0x81, 0xB0, 0xF6,
+		0xE5, 0x8F, 0x8A, 0xF6, 0xE5, 0x8F, 0x9F, 0xF6,
+		0xF0, 0xA0, 0xAD, 0xA3, 0xF6, 0xE5, 0x8F, 0xAB,
+		0xF6, 0xE5, 0x8F, 0xB1, 0xF6, 0xE5, 0x90, 0x86,
+		0xF6, 0xE5, 0x92, 0x9E, 0xF6, 0xE5, 0x90, 0xB8,
+		0xF6, 0xE5, 0x91, 0x88, 0xF6, 0xE5, 0x91, 0xA8,
+		0xF6, 0xE5, 0x92, 0xA2, 0xF6, 0xE5, 0x93, 0xB6,
+		0xF6, 0xE5, 0x94, 0x90, 0xF6, 0xE5, 0x95, 0x93,
+		0xF6, 0xE5, 0x95, 0xA3, 0xF6, 0xE5, 0x96, 0x84,
+		0xF6, 0xE5, 0x96, 0x84, 0xF6, 0xE5, 0x96, 0x99,
+		0xF6, 0xE5, 0x96, 0xAB, 0xF6, 0xE5, 0x96, 0xB3,
+		0xF6, 0xE5, 0x97, 0x82, 0xF6, 0xE5, 0x9C, 0x96,
+		0xF6, 0xE5, 0x98, 0x86, 0xF6, 0xE5, 0x9C, 0x97,
+		0xF6, 0xE5, 0x99, 0x91, 0xF6, 0xE5, 0x99, 0xB4,
+		0xF6, 0xE5, 0x88, 0x87, 0xF6, 0xE5, 0xA3, 0xAE,
+		0xF6, 0xE5, 0x9F, 0x8E, 0xF6, 0xE5, 0x9F, 0xB4,
+		0xF6, 0xE5, 0xA0, 0x8D, 0xF6, 0xE5, 0x9E, 0x8B,
+		0xF6, 0xE5, 0xA0, 0xB2, 0xF6, 0xE5, 0xA0, 0xB1,
+		0xF6, 0xE5, 0xA2, 0xAC, 0xF6, 0xF0, 0xA1, 0x93,
+		0xA4, 0xF6, 0xE5, 0xA3, 0xB2, 0xF6, 0xE5, 0xA3,
+		0xB7, 0xF6, 0xE5, 0xA4, 0x86, 0xF6, 0xE5, 0xA4,
+		0x9A, 0xF6, 0xE5, 0xA4, 0xA2, 0xF6, 0xE5, 0xA5,
+		0xA2, 0xF6, 0xF0, 0xA1, 0x9A, 0xA8, 0xF6, 0xF0,
+		0xA1, 0x9B, 0xAA, 0xF6, 0xE5, 0xA7, 0xAC, 0xF6,
+		0xE5, 0xA8, 0x9B, 0xF6, 0xE5, 0xA8, 0xA7, 0xF6,
+		0xE5, 0xA7, 0x98, 0xF6, 0xE5, 0xA9, 0xA6, 0xF6,
+		0xE3, 0x9B, 0xAE, 0xF6, 0xE3, 0x9B, 0xBC, 0xF6,
+		0xE5, 0xAC, 0x88, 0xF6, 0xE5, 0xAC, 0xBE, 0xF6,
+		0xE5, 0xAC, 0xBE, 0xF6, 0xF0, 0xA1, 0xA7, 0x88,
+		0xF6, 0xE5, 0xAF, 0x83, 0xF6, 0xE5, 0xAF, 0x98,
+		0xF6, 0xE5, 0xAF, 0xA7, 0xF6, 0xE5, 0xAF, 0xB3,
+		0xF6, 0xF0, 0xA1, 0xAC, 0x98, 0xF6, 0xE5, 0xAF,
+		0xBF, 0xF6, 0xE5, 0xB0, 0x86, 0xF6, 0xE5, 0xBD,
+		0x93, 0xF6, 0xE5, 0xB0, 0xA2, 0xF6, 0xE3, 0x9E,
+		0x81, 0xF6, 0xE5, 0xB1, 0xA0, 0xF6, 0xE5, 0xB1,
+		0xAE, 0xF6, 0xE5, 0xB3, 0x80, 0xF6, 0xE5, 0xB2,
+		0x8D, 0xF6, 0xF0, 0xA1, 0xB7, 0xA4, 0xF6, 0xE5,
+		0xB5, 0x83, 0xF6, 0xF0, 0xA1, 0xB7, 0xA6, 0xF6,
+		0xE5, 0xB5, 0xAE, 0xF6, 0xE5, 0xB5, 0xAB, 0xF6,
+		0xE5, 0xB5, 0xBC, 0xF6, 0xE5, 0xB7, 0xA1, 0xF6,
+		0xE5, 0xB7, 0xA2, 0xF6, 0xE3, 0xA0, 0xAF, 0xF6,
+		0xE5, 0xB7, 0xBD, 0xF6, 0xE5, 0xB8, 0xA8, 0xF6,
+		0xE5, 0xB8, 0xBD, 0xF6, 0xE5, 0xB9, 0xA9, 0xF6,
+		0xE3, 0xA1, 0xA2, 0xF6, 0xF0, 0xA2, 0x86, 0x83,
+		0xF6, 0xE3, 0xA1, 0xBC, 0xF6, 0xE5, 0xBA, 0xB0,
+		0xF6, 0xE5, 0xBA, 0xB3, 0xF6, 0xE5, 0xBA, 0xB6,
+		0xF6, 0xE5, 0xBB, 0x8A, 0xF6, 0xF0, 0xAA, 0x8E,
+		0x92, 0xF6, 0xE5, 0xBB, 0xBE, 0xF6, 0xF0, 0xA2,
+		0x8C, 0xB1, 0xF6, 0xF0, 0xA2, 0x8C, 0xB1, 0xF6,
+		0xE8, 0x88, 0x81, 0xF6, 0xE5, 0xBC, 0xA2, 0xF6,
+		0xE5, 0xBC, 0xA2, 0xF6, 0xE3, 0xA3, 0x87, 0xF6,
+		0xF0, 0xA3, 0x8A, 0xB8, 0xF6, 0xF0, 0xA6, 0x87,
+		0x9A, 0xF6, 0xE5, 0xBD, 0xA2, 0xF6, 0xE5, 0xBD,
+		0xAB, 0xF6, 0xE3, 0xA3, 0xA3, 0xF6, 0xE5, 0xBE,
+		0x9A, 0xF6, 0xE5, 0xBF, 0x8D, 0xF6, 0xE5, 0xBF,
+		0x97, 0xF6, 0xE5, 0xBF, 0xB9, 0xF6, 0xE6, 0x82,
+		0x81, 0xF6, 0xE3, 0xA4, 0xBA, 0xF6, 0xE3, 0xA4,
+		0x9C, 0xF6, 0xE6, 0x82, 0x94, 0xF6, 0xF0, 0xA2,
+		0x9B, 0x94, 0xF6, 0xE6, 0x83, 0x87, 0xF6, 0xE6,
+		0x85, 0x88, 0xF6, 0xE6, 0x85, 0x8C, 0xF6, 0xE6,
+		0x85, 0x8E, 0xF6, 0xE6, 0x85, 0x8C, 0xF6, 0xE6,
+		0x85, 0xBA, 0xF6, 0xE6, 0x86, 0x8E, 0xF6, 0xE6,
+		0x86, 0xB2, 0xF6, 0xE6, 0x86, 0xA4, 0xF6, 0xE6,
+		0x86, 0xAF, 0xF6, 0xE6, 0x87, 0x9E, 0xF6, 0xE6,
+		0x87, 0xB2, 0xF6, 0xE6, 0x87, 0xB6, 0xF6, 0xE6,
+		0x88, 0x90, 0xF6, 0xE6, 0x88, 0x9B, 0xF6, 0xE6,
+		0x89, 0x9D, 0xF6, 0xE6, 0x8A, 0xB1, 0xF6, 0xE6,
+		0x8B, 0x94, 0xF6, 0xE6, 0x8D, 0x90, 0xF6, 0xF0,
+		0xA2, 0xAC, 0x8C, 0xF6, 0xE6, 0x8C, 0xBD, 0xF6,
+		0xE6, 0x8B, 0xBC, 0xF6, 0xE6, 0x8D, 0xA8, 0xF6,
+		0xE6, 0x8E, 0x83, 0xF6, 0xE6, 0x8F, 0xA4, 0xF6,
+		0xF0, 0xA2, 0xAF, 0xB1, 0xF6, 0xE6, 0x90, 0xA2,
+		0xF6, 0xE6, 0x8F, 0x85, 0xF6, 0xE6, 0x8E, 0xA9,
+		0xF6, 0xE3, 0xA8, 0xAE, 0xF6, 0xE6, 0x91, 0xA9,
+		0xF6, 0xE6, 0x91, 0xBE, 0xF6, 0xE6, 0x92, 0x9D,
+		0xF6, 0xE6, 0x91, 0xB7, 0xF6, 0xE3, 0xA9, 0xAC,
+		0xF6, 0xE6, 0x95, 0x8F, 0xF6, 0xE6, 0x95, 0xAC,
+		0xF6, 0xF0, 0xA3, 0x80, 0x8A, 0xF6, 0xE6, 0x97,
+		0xA3, 0xF6, 0xE6, 0x9B, 0xB8, 0xF6, 0xE6, 0x99,
+		0x89, 0xF6, 0xE3, 0xAC, 0x99, 0xF6, 0xE6, 0x9A,
+		0x91, 0xF6, 0xE3, 0xAC, 0x88, 0xF6, 0xE3, 0xAB,
+		0xA4, 0xF6, 0xE5, 0x86, 0x92, 0xF6, 0xE5, 0x86,
+		0x95, 0xF6, 0xE6, 0x9C, 0x80, 0xF6, 0xE6, 0x9A,
+		0x9C, 0xF6, 0xE8, 0x82, 0xAD, 0xF6, 0xE4, 0x8F,
+		0x99, 0xF6, 0xE6, 0x9C, 0x97, 0xF6, 0xE6, 0x9C,
+		0x9B, 0xF6, 0xE6, 0x9C, 0xA1, 0xF6, 0xE6, 0x9D,
+		0x9E, 0xF6, 0xE6, 0x9D, 0x93, 0xF6, 0xF0, 0xA3,
+		0x8F, 0x83, 0xF6, 0xE3, 0xAD, 0x89, 0xF6, 0xE6,
+		0x9F, 0xBA, 0xF6, 0xE6, 0x9E, 0x85, 0xF6, 0xE6,
+		0xA1, 0x92, 0xF6, 0xE6, 0xA2, 0x85, 0xF6, 0xF0,
+		0xA3, 0x91, 0xAD, 0xF6, 0xE6, 0xA2, 0x8E, 0xF6,
+		0xE6, 0xA0, 0x9F, 0xF6, 0xE6, 0xA4, 0x94, 0xF6,
+		0xE3, 0xAE, 0x9D, 0xF6, 0xE6, 0xA5, 0x82, 0xF6,
+		0xE6, 0xA6, 0xA3, 0xF6, 0xE6, 0xA7, 0xAA, 0xF6,
+		0xE6, 0xAA, 0xA8, 0xF6, 0xF0, 0xA3, 0x9A, 0xA3,
+		0xF6, 0xE6, 0xAB, 0x9B, 0xF6, 0xE3, 0xB0, 0x98,
+		0xF6, 0xE6, 0xAC, 0xA1, 0xF6, 0xF0, 0xA3, 0xA2,
+		0xA7, 0xF6, 0xE6, 0xAD, 0x94, 0xF6, 0xE3, 0xB1,
+		0x8E, 0xF6, 0xE6, 0xAD, 0xB2, 0xF6, 0xE6, 0xAE,
+		0x9F, 0xF6, 0xE6, 0xAE, 0xBA, 0xF6, 0xE6, 0xAE,
+		0xBB, 0xF6, 0xF0, 0xA3, 0xAA, 0x8D, 0xF6, 0xF0,
+		0xA1, 0xB4, 0x8B, 0xF6, 0xF0, 0xA3, 0xAB, 0xBA,
+		0xF6, 0xE6, 0xB1, 0x8E, 0xF6, 0xF0, 0xA3, 0xB2,
+		0xBC, 0xF6, 0xE6, 0xB2, 0xBF, 0xF6, 0xE6, 0xB3,
+		0x8D, 0xF6, 0xE6, 0xB1, 0xA7, 0xF6, 0xE6, 0xB4,
+		0x96, 0xF6, 0xE6, 0xB4, 0xBE, 0xF6, 0xE6, 0xB5,
+		0xB7, 0xF6, 0xE6, 0xB5, 0x81, 0xF6, 0xE6, 0xB5,
+		0xA9, 0xF6, 0xE6, 0xB5, 0xB8, 0xF6, 0xE6, 0xB6,
+		0x85, 0xF6, 0xF0, 0xA3, 0xB4, 0x9E, 0xF6, 0xE6,
+		0xB4, 0xB4, 0xF6, 0xE6, 0xB8, 0xAF, 0xF6, 0xE6,
+		0xB9, 0xAE, 0xF6, 0xE3, 0xB4, 0xB3, 0xF6, 0xE6,
+		0xBB, 0x8B, 0xF6, 0xE6, 0xBB, 0x87, 0xF6, 0xF0,
+		0xA3, 0xBB, 0x91, 0xF6, 0xE6, 0xB7, 0xB9, 0xF6,
+		0xE6, 0xBD, 0xAE, 0xF6, 0xF0, 0xA3, 0xBD, 0x9E,
+		0xF6, 0xF0, 0xA3, 0xBE, 0x8E, 0xF6, 0xE6, 0xBF,
+		0x86, 0xF6, 0xE7, 0x80, 0xB9, 0xF6, 0xE7, 0x80,
+		0x9E, 0xF6, 0xE7, 0x80, 0x9B, 0xF6, 0xE3, 0xB6,
+		0x96, 0xF6, 0xE7, 0x81, 0x8A, 0xF6, 0xE7, 0x81,
+		0xBD, 0xF6, 0xE7, 0x81, 0xB7, 0xF6, 0xE7, 0x82,
+		0xAD, 0xF6, 0xF0, 0xA0, 0x94, 0xA5, 0xF6, 0xE7,
+		0x85, 0x85, 0xF6, 0xF0, 0xA4, 0x89, 0xA3, 0xF6,
+		0xE7, 0x86, 0x9C, 0xF6, 0xF0, 0xA4, 0x8E, 0xAB,
+		0xF6, 0xE7, 0x88, 0xA8, 0xF6, 0xE7, 0x88, 0xB5,
+		0xF6, 0xE7, 0x89, 0x90, 0xF6, 0xF0, 0xA4, 0x98,
+		0x88, 0xF6, 0xE7, 0x8A, 0x80, 0xF6, 0xE7, 0x8A,
+		0x95, 0xF6, 0xF0, 0xA4, 0x9C, 0xB5, 0xF6, 0xF0,
+		0xA4, 0xA0, 0x94, 0xF6, 0xE7, 0x8D, 0xBA, 0xF6,
+		0xE7, 0x8E, 0x8B, 0xF6, 0xE3, 0xBA, 0xAC, 0xF6,
+		0xE7, 0x8E, 0xA5, 0xF6, 0xE3, 0xBA, 0xB8, 0xF6,
+		0xE3, 0xBA, 0xB8, 0xF6, 0xE7, 0x91, 0x87, 0xF6,
+		0xE7, 0x91, 0x9C, 0xF6, 0xE7, 0x91, 0xB1, 0xF6,
+		0xE7, 0x92, 0x85, 0xF6, 0xE7, 0x93, 0x8A, 0xF6,
+		0xE3, 0xBC, 0x9B, 0xF6, 0xE7, 0x94, 0xA4, 0xF6,
+		0xF0, 0xA4, 0xB0, 0xB6, 0xF6, 0xE7, 0x94, 0xBE,
+		0xF6, 0xF0, 0xA4, 0xB2, 0x92, 0xF6, 0xE7, 0x95,
+		0xB0, 0xF6, 0xF0, 0xA2, 0x86, 0x9F, 0xF6, 0xE7,
+		0x98, 0x90, 0xF6, 0xF0, 0xA4, 0xBE, 0xA1, 0xF6,
+		0xF0, 0xA4, 0xBE, 0xB8, 0xF6, 0xF0, 0xA5, 0x81,
+		0x84, 0xF6, 0xE3, 0xBF, 0xBC, 0xF6, 0xE4, 0x80,
+		0x88, 0xF6, 0xE7, 0x9B, 0xB4, 0xF6, 0xF0, 0xA5,
+		0x83, 0xB3, 0xF6, 0xF0, 0xA5, 0x83, 0xB2, 0xF6,
+		0xF0, 0xA5, 0x84, 0x99, 0xF6, 0xF0, 0xA5, 0x84,
+		0xB3, 0xF6, 0xE7, 0x9C, 0x9E, 0xF6, 0xE7, 0x9C,
+		0x9F, 0xF6, 0xE7, 0x9C, 0x9F, 0xF6, 0xE7, 0x9D,
+		0x8A, 0xF6, 0xE4, 0x80, 0xB9, 0xF6, 0xE7, 0x9E,
+		0x8B, 0xF6, 0xE4, 0x81, 0x86, 0xF6, 0xE4, 0x82,
+		0x96, 0xF6, 0xF0, 0xA5, 0x90, 0x9D, 0xF6, 0xE7,
+		0xA1, 0x8E, 0xF6, 0xE7, 0xA2, 0x8C, 0xF6, 0xE7,
+		0xA3, 0x8C, 0xF6, 0xE4, 0x83, 0xA3, 0xF6, 0xF0,
+		0xA5, 0x98, 0xA6, 0xF6, 0xE7, 0xA5, 0x96, 0xF6,
+		0xF0, 0xA5, 0x9A, 0x9A, 0xF6, 0xF0, 0xA5, 0x9B,
+		0x85, 0xF6, 0xE7, 0xA6, 0x8F, 0xF6, 0xE7, 0xA7,
+		0xAB, 0xF6, 0xE4, 0x84, 0xAF, 0xF6, 0xE7, 0xA9,
+		0x80, 0xF6, 0xE7, 0xA9, 0x8A, 0xF6, 0xE7, 0xA9,
+		0x8F, 0xF6, 0xF0, 0xA5, 0xA5, 0xBC, 0xF6, 0xF0,
+		0xA5, 0xAA, 0xA7, 0xF6, 0xF0, 0xA5, 0xAA, 0xA7,
+		0xF6, 0xE7, 0xAB, 0xAE, 0xF6, 0xE4, 0x88, 0x82,
+		0xF6, 0xF0, 0xA5, 0xAE, 0xAB, 0xF6, 0xE7, 0xAF,
+		0x86, 0xF6, 0xE7, 0xAF, 0x89, 0xF6, 0xE4, 0x88,
+		0xA7, 0xF6, 0xF0, 0xA5, 0xB2, 0x80, 0xF6, 0xE7,
+		0xB3, 0x92, 0xF6, 0xE4, 0x8A, 0xA0, 0xF6, 0xE7,
+		0xB3, 0xA8, 0xF6, 0xE7, 0xB3, 0xA3, 0xF6, 0xE7,
+		0xB4, 0x80, 0xF6, 0xF0, 0xA5, 0xBE, 0x86, 0xF6,
+		0xE7, 0xB5, 0xA3, 0xF6, 0xE4, 0x8C, 0x81, 0xF6,
+		0xE7, 0xB7, 0x87, 0xF6, 0xE7, 0xB8, 0x82, 0xF6,
+		0xE7, 0xB9, 0x85, 0xF6, 0xE4, 0x8C, 0xB4, 0xF6,
+		0xF0, 0xA6, 0x88, 0xA8, 0xF6, 0xF0, 0xA6, 0x89,
+		0x87, 0xF6, 0xE4, 0x8D, 0x99, 0xF6, 0xF0, 0xA6,
+		0x8B, 0x99, 0xF6, 0xE7, 0xBD, 0xBA, 0xF6, 0xF0,
+		0xA6, 0x8C, 0xBE, 0xF6, 0xE7, 0xBE, 0x95, 0xF6,
+		0xE7, 0xBF, 0xBA, 0xF6, 0xE8, 0x80, 0x85, 0xF6,
+		0xF0, 0xA6, 0x93, 0x9A, 0xF6, 0xF0, 0xA6, 0x94,
+		0xA3, 0xF6, 0xE8, 0x81, 0xA0, 0xF6, 0xF0, 0xA6,
+		0x96, 0xA8, 0xF6, 0xE8, 0x81, 0xB0, 0xF6, 0xF0,
+		0xA3, 0x8D, 0x9F, 0xF6, 0xE4, 0x8F, 0x95, 0xF6,
+		0xE8, 0x82, 0xB2, 0xF6, 0xE8, 0x84, 0x83, 0xF6,
+		0xE4, 0x90, 0x8B, 0xF6, 0xE8, 0x84, 0xBE, 0xF6,
+		0xE5, 0xAA, 0xB5, 0xF6, 0xF0, 0xA6, 0x9E, 0xA7,
+		0xF6, 0xF0, 0xA6, 0x9E, 0xB5, 0xF6, 0xF0, 0xA3,
+		0x8E, 0x93, 0xF6, 0xF0, 0xA3, 0x8E, 0x9C, 0xF6,
+		0xE8, 0x88, 0x81, 0xF6, 0xE8, 0x88, 0x84, 0xF6,
+		0xE8, 0xBE, 0x9E, 0xF6, 0xE4, 0x91, 0xAB, 0xF6,
+		0xE8, 0x8A, 0x91, 0xF6, 0xE8, 0x8A, 0x8B, 0xF6,
+		0xE8, 0x8A, 0x9D, 0xF6, 0xE5, 0x8A, 0xB3, 0xF6,
+		0xE8, 0x8A, 0xB1, 0xF6, 0xE8, 0x8A, 0xB3, 0xF6,
+		0xE8, 0x8A, 0xBD, 0xF6, 0xE8, 0x8B, 0xA6, 0xF6,
+		0xF0, 0xA6, 0xAC, 0xBC, 0xF6, 0xE8, 0x8B, 0xA5,
+		0xF6, 0xE8, 0x8C, 0x9D, 0xF6, 0xE8, 0x8D, 0xA3,
+		0xF6, 0xE8, 0x8E, 0xAD, 0xF6, 0xE8, 0x8C, 0xA3,
+		0xF6, 0xE8, 0x8E, 0xBD, 0xF6, 0xE8, 0x8F, 0xA7,
+		0xF6, 0xE8, 0x91, 0x97, 0xF6, 0xE8, 0x8D, 0x93,
+		0xF6, 0xE8, 0x8F, 0x8A, 0xF6, 0xE8, 0x8F, 0x8C,
+		0xF6, 0xE8, 0x8F, 0x9C, 0xF6, 0xF0, 0xA6, 0xB0,
+		0xB6, 0xF6, 0xF0, 0xA6, 0xB5, 0xAB, 0xF6, 0xF0,
+		0xA6, 0xB3, 0x95, 0xF6, 0xE4, 0x94, 0xAB, 0xF6,
+		0xE8, 0x93, 0xB1, 0xF6, 0xE8, 0x93, 0xB3, 0xF6,
+		0xE8, 0x94, 0x96, 0xF6, 0xF0, 0xA7, 0x8F, 0x8A,
+		0xF6, 0xE8, 0x95, 0xA4, 0xF6, 0xF0, 0xA6, 0xBC,
+		0xAC, 0xF6, 0xE4, 0x95, 0x9D, 0xF6, 0xE4, 0x95,
+		0xA1, 0xF6, 0xF0, 0xA6, 0xBE, 0xB1, 0xF6, 0xF0,
+		0xA7, 0x83, 0x92, 0xF6, 0xE4, 0x95, 0xAB, 0xF6,
+		0xE8, 0x99, 0x90, 0xF6, 0xE8, 0x99, 0x9C, 0xF6,
+		0xE8, 0x99, 0xA7, 0xF6, 0xE8, 0x99, 0xA9, 0xF6,
+		0xE8, 0x9A, 0xA9, 0xF6, 0xE8, 0x9A, 0x88, 0xF6,
+		0xE8, 0x9C, 0x8E, 0xF6, 0xE8, 0x9B, 0xA2, 0xF6,
+		0xE8, 0x9D, 0xB9, 0xF6, 0xE8, 0x9C, 0xA8, 0xF6,
+		0xE8, 0x9D, 0xAB, 0xF6, 0xE8, 0x9E, 0x86, 0xF6,
+		0xE4, 0x97, 0x97, 0xF6, 0xE8, 0x9F, 0xA1, 0xF6,
+		0xE8, 0xA0, 0x81, 0xF6, 0xE4, 0x97, 0xB9, 0xF6,
+		0xE8, 0xA1, 0xA0, 0xF6, 0xE8, 0xA1, 0xA3, 0xF6,
+		0xF0, 0xA7, 0x99, 0xA7, 0xF6, 0xE8, 0xA3, 0x97,
+		0xF6, 0xE8, 0xA3, 0x9E, 0xF6, 0xE4, 0x98, 0xB5,
+		0xF6, 0xE8, 0xA3, 0xBA, 0xF6, 0xE3, 0x92, 0xBB,
+		0xF6, 0xF0, 0xA7, 0xA2, 0xAE, 0xF6, 0xF0, 0xA7,
+		0xA5, 0xA6, 0xF6, 0xE4, 0x9A, 0xBE, 0xF6, 0xE4,
+		0x9B, 0x87, 0xF6, 0xE8, 0xAA, 0xA0, 0xF6, 0xE8,
+		0xAB, 0xAD, 0xF6, 0xE8, 0xAE, 0x8A, 0xF6, 0xE8,
+		0xB1, 0x95, 0xF6, 0xF0, 0xA7, 0xB2, 0xA8, 0xF6,
+		0xE8, 0xB2, 0xAB, 0xF6, 0xE8, 0xB3, 0x81, 0xF6,
+		0xE8, 0xB4, 0x9B, 0xF6, 0xE8, 0xB5, 0xB7, 0xF6,
+		0xF0, 0xA7, 0xBC, 0xAF, 0xF6, 0xF0, 0xA0, 0xA0,
+		0x84, 0xF6, 0xE8, 0xB7, 0x8B, 0xF6, 0xE8, 0xB6,
+		0xBC, 0xF6, 0xE8, 0xB7, 0xB0, 0xF6, 0xF0, 0xA0,
+		0xA3, 0x9E, 0xF6, 0xE8, 0xBB, 0x94, 0xF6, 0xE8,
+		0xBC, 0xB8, 0xF6, 0xF0, 0xA8, 0x97, 0x92, 0xF6,
+		0xF0, 0xA8, 0x97, 0xAD, 0xF6, 0xE9, 0x82, 0x94,
+		0xF6, 0xE9, 0x83, 0xB1, 0xF6, 0xE9, 0x84, 0x91,
+		0xF6, 0xF0, 0xA8, 0x9C, 0xAE, 0xF6, 0xE9, 0x84,
+		0x9B, 0xF6, 0xE9, 0x88, 0xB8, 0xF6, 0xE9, 0x8B,
+		0x97, 0xF6, 0xE9, 0x8B, 0x98, 0xF6, 0xE9, 0x89,
+		0xBC, 0xF6, 0xE9, 0x8F, 0xB9, 0xF6, 0xE9, 0x90,
+		0x95, 0xF6, 0xF0, 0xA8, 0xAF, 0xBA, 0xF6, 0xE9,
+		0x96, 0x8B, 0xF6, 0xE4, 0xA6, 0x95, 0xF6, 0xE9,
+		0x96, 0xB7, 0xF6, 0xF0, 0xA8, 0xB5, 0xB7, 0xF6,
+		0xE4, 0xA7, 0xA6, 0xF6, 0xE9, 0x9B, 0x83, 0xF6,
+		0xE5, 0xB6, 0xB2, 0xF6, 0xE9, 0x9C, 0xA3, 0xF6,
+		0xF0, 0xA9, 0x85, 0x85, 0xF6, 0xF0, 0xA9, 0x88,
+		0x9A, 0xF6, 0xE4, 0xA9, 0xAE, 0xF6, 0xE4, 0xA9,
+		0xB6, 0xF6, 0xE9, 0x9F, 0xA0, 0xF6, 0xF0, 0xA9,
+		0x90, 0x8A, 0xF6, 0xE4, 0xAA, 0xB2, 0xF6, 0xF0,
+		0xA9, 0x92, 0x96, 0xF6, 0xE9, 0xA0, 0x8B, 0xF6,
+		0xE9, 0xA0, 0x8B, 0xF6, 0xE9, 0xA0, 0xA9, 0xF6,
+		0xF0, 0xA9, 0x96, 0xB6, 0xF6, 0xE9, 0xA3, 0xA2,
+		0xF6, 0xE4, 0xAC, 0xB3, 0xF6, 0xE9, 0xA4, 0xA9,
+		0xF6, 0xE9, 0xA6, 0xA7, 0xF6, 0xE9, 0xA7, 0x82,
+		0xF6, 0xE9, 0xA7, 0xBE, 0xF6, 0xE4, 0xAF, 0x8E,
+		0xF6, 0xF0, 0xA9, 0xAC, 0xB0, 0xF6, 0xE9, 0xAC,
+		0x92, 0xF6, 0xE9, 0xB1, 0x80, 0xF6, 0xE9, 0xB3,
+		0xBD, 0xF6, 0xE4, 0xB3, 0x8E, 0xF6, 0xE4, 0xB3,
+		0xAD, 0xF6, 0xE9, 0xB5, 0xA7, 0xF6, 0xF0, 0xAA,
+		0x83, 0x8E, 0xF6, 0xE4, 0xB3, 0xB8, 0xF6, 0xF0,
+		0xAA, 0x84, 0x85, 0xF6, 0xF0, 0xAA, 0x88, 0x8E,
+		0xF6, 0xF0, 0xAA, 0x8A, 0x91, 0xF6, 0xE9, 0xBA,
+		0xBB, 0xF6, 0xE4, 0xB5, 0x96, 0xF6, 0xE9, 0xBB,
+		0xB9, 0xF6, 0xE9, 0xBB, 0xBE, 0xF6, 0xE9, 0xBC,
+		0x85, 0xF6, 0xE9, 0xBC, 0x8F, 0xF6, 0xE9, 0xBC,
+		0x96, 0xF6, 0xE9, 0xBC, 0xBB, 0xF6, 0xF0, 0xAA,
+		0x98, 0x80,
+	},
+};
+
+static const uchar_t u8_case_common_b2_tbl[2][2][256] = {
+	{
+		{
+			0,  N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, 1,  2,  N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, 3,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+		},
+		{
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			4,  N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+		},
+
+	},
+	{
+		{
+			0,  N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, 1,  2,  N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, 3,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+		},
+		{
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			4,  N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+			N_, N_, N_, N_, N_, N_, N_, N_,
+		},
+
+	},
+
+};
+
+static const u8_displacement_t u8_tolower_b3_tbl[2][5][256] = {
+	{
+		{	/* Third byte table 0. */
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { 0, 0 },
+			{ 1, 60 }, { 2, 123 }, { 3, 185 }, { 4, 257 },
+			{ 5, 321 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { 6, 373 }, { 7, 439 },
+			{ 8, 465 }, { 9, 561 }, { 10, 593 }, { 11, 649 },
+			{ 12, 703 }, { 13, 749 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+		},
+		{	/* Third byte table 1. */
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ 14, 795 }, { 15, 891 }, { 16, 987 }, { 17, 1068 },
+			{ 18, 1155 }, { 19, 1245 }, { 20, 1299 }, { 21, 1386 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+		},
+		{	/* Third byte table 2. */
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ 22, 1443 }, { 23, 1448 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { 24, 1496 }, { 25, 1526 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+		},
+		{	/* Third byte table 3. */
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ 26, 1574 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+		},
+		{	/* Third byte table 4. */
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ 27, 1652 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+		},
+	},
+	{
+		{	/* Third byte table 0. */
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { 0, 0 },
+			{ 1, 60 }, { 2, 123 }, { 3, 185 }, { 4, 257 },
+			{ 5, 321 }, { 6, 383 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { 7, 401 }, { 8, 467 },
+			{ 9, 505 }, { 10, 601 }, { 11, 633 }, { 12, 689 },
+			{ 13, 753 }, { 14, 803 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+		},
+		{	/* Third byte table 1. */
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { 15, 849 }, { 16, 945 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ 17, 963 }, { 18, 1059 }, { 19, 1155 }, { 20, 1236 },
+			{ 21, 1323 }, { 22, 1413 }, { 23, 1467 }, { 24, 1554 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+		},
+		{	/* Third byte table 2. */
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ 25, 1611 }, { 26, 1619 }, { 27, 1667 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { 28, 1670 }, { 29, 1700 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ 30, 1748 }, { 31, 1889 }, { 32, 1911 }, { 33, 2007 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+		},
+		{	/* Third byte table 3. */
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ 34, 2061 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+		},
+		{	/* Third byte table 4. */
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ 35, 2139 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+		},
+	},
+};
+
+static const uchar_t u8_tolower_b4_tbl[2][36][257] = {
+	{
+		{	/* Fourth byte table 0. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   2,   4,   6,   8,   10,  12,  14,
+			16,  18,  20,  22,  24,  26,  28,  30,
+			32,  34,  36,  38,  40,  42,  44,  46,
+			46,  48,  50,  52,  54,  56,  58,  60,
+			60,  60,  60,  60,  60,  60,  60,  60,
+			60,  60,  60,  60,  60,  60,  60,  60,
+			60,  60,  60,  60,  60,  60,  60,  60,
+			60,  60,  60,  60,  60,  60,  60,  60,
+			60,  60,  60,  60,  60,  60,  60,  60,
+			60,  60,  60,  60,  60,  60,  60,  60,
+			60,  60,  60,  60,  60,  60,  60,  60,
+			60,  60,  60,  60,  60,  60,  60,  60,
+			60,  60,  60,  60,  60,  60,  60,  60,
+			60,  60,  60,  60,  60,  60,  60,  60,
+			60,  60,  60,  60,  60,  60,  60,  60,
+			60,  60,  60,  60,  60,  60,  60,  60,
+			60,
+		},
+		{	/* Fourth byte table 1. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   2,   2,   4,   4,   6,   6,   8,
+			8,   10,  10,  12,  12,  14,  14,  16,
+			16,  18,  18,  20,  20,  22,  22,  24,
+			24,  26,  26,  28,  28,  30,  30,  32,
+			32,  34,  34,  36,  36,  38,  38,  40,
+			40,  42,  42,  44,  44,  46,  46,  48,
+			48,  49,  49,  51,  51,  53,  53,  55,
+			55,  55,  57,  57,  59,  59,  61,  61,
+			63,  63,  63,  63,  63,  63,  63,  63,
+			63,  63,  63,  63,  63,  63,  63,  63,
+			63,  63,  63,  63,  63,  63,  63,  63,
+			63,  63,  63,  63,  63,  63,  63,  63,
+			63,  63,  63,  63,  63,  63,  63,  63,
+			63,  63,  63,  63,  63,  63,  63,  63,
+			63,  63,  63,  63,  63,  63,  63,  63,
+			63,  63,  63,  63,  63,  63,  63,  63,
+			63,
+		},
+		{	/* Fourth byte table 2. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   2,   2,   4,   4,   6,   6,
+			8,   8,   8,   10,  10,  12,  12,  14,
+			14,  16,  16,  18,  18,  20,  20,  22,
+			22,  24,  24,  26,  26,  28,  28,  30,
+			30,  32,  32,  34,  34,  36,  36,  38,
+			38,  40,  40,  42,  42,  44,  44,  46,
+			46,  48,  48,  50,  50,  52,  52,  54,
+			54,  56,  58,  58,  60,  60,  62,  62,
+			62,  62,  62,  62,  62,  62,  62,  62,
+			62,  62,  62,  62,  62,  62,  62,  62,
+			62,  62,  62,  62,  62,  62,  62,  62,
+			62,  62,  62,  62,  62,  62,  62,  62,
+			62,  62,  62,  62,  62,  62,  62,  62,
+			62,  62,  62,  62,  62,  62,  62,  62,
+			62,  62,  62,  62,  62,  62,  62,  62,
+			62,  62,  62,  62,  62,  62,  62,  62,
+			62,
+		},
+		{	/* Fourth byte table 3. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   2,   4,   4,   6,   6,   8,
+			10,  10,  12,  14,  16,  16,  16,  18,
+			20,  22,  24,  24,  26,  28,  28,  30,
+			32,  34,  34,  34,  34,  36,  38,  38,
+			40,  42,  42,  44,  44,  46,  46,  48,
+			50,  50,  52,  52,  52,  54,  54,  56,
+			58,  58,  60,  62,  64,  64,  66,  66,
+			68,  70,  70,  70,  70,  72,  72,  72,
+			72,  72,  72,  72,  72,  72,  72,  72,
+			72,  72,  72,  72,  72,  72,  72,  72,
+			72,  72,  72,  72,  72,  72,  72,  72,
+			72,  72,  72,  72,  72,  72,  72,  72,
+			72,  72,  72,  72,  72,  72,  72,  72,
+			72,  72,  72,  72,  72,  72,  72,  72,
+			72,  72,  72,  72,  72,  72,  72,  72,
+			72,  72,  72,  72,  72,  72,  72,  72,
+			72,
+		},
+		{	/* Fourth byte table 4. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   2,   4,   4,
+			6,   8,   8,   10,  12,  12,  14,  14,
+			16,  16,  18,  18,  20,  20,  22,  22,
+			24,  24,  26,  26,  28,  28,  28,  30,
+			30,  32,  32,  34,  34,  36,  36,  38,
+			38,  40,  40,  42,  42,  44,  44,  46,
+			46,  46,  48,  50,  50,  52,  52,  54,
+			56,  58,  58,  60,  60,  62,  62,  64,
+			64,  64,  64,  64,  64,  64,  64,  64,
+			64,  64,  64,  64,  64,  64,  64,  64,
+			64,  64,  64,  64,  64,  64,  64,  64,
+			64,  64,  64,  64,  64,  64,  64,  64,
+			64,  64,  64,  64,  64,  64,  64,  64,
+			64,  64,  64,  64,  64,  64,  64,  64,
+			64,  64,  64,  64,  64,  64,  64,  64,
+			64,  64,  64,  64,  64,  64,  64,  64,
+			64,
+		},
+		{	/* Fourth byte table 5. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   2,   2,   4,   4,   6,   6,   8,
+			8,   10,  10,  12,  12,  14,  14,  16,
+			16,  18,  18,  20,  20,  22,  22,  24,
+			24,  26,  26,  28,  28,  30,  30,  32,
+			32,  34,  34,  36,  36,  38,  38,  40,
+			40,  42,  42,  44,  44,  46,  46,  48,
+			48,  50,  50,  52,  52,  52,  52,  52,
+			52,  52,  52,  52,  52,  52,  52,  52,
+			52,  52,  52,  52,  52,  52,  52,  52,
+			52,  52,  52,  52,  52,  52,  52,  52,
+			52,  52,  52,  52,  52,  52,  52,  52,
+			52,  52,  52,  52,  52,  52,  52,  52,
+			52,  52,  52,  52,  52,  52,  52,  52,
+			52,  52,  52,  52,  52,  52,  52,  52,
+			52,  52,  52,  52,  52,  52,  52,  52,
+			52,  52,  52,  52,  52,  52,  52,  52,
+			52,
+		},
+		{	/* Fourth byte table 6. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   2,
+			2,   4,   6,   8,   8,   10,  10,  12,
+			14,  14,  16,  18,  20,  22,  24,  26,
+			28,  30,  32,  34,  36,  38,  40,  42,
+			44,  46,  48,  48,  50,  52,  54,  56,
+			58,  60,  62,  64,  66,  66,  66,  66,
+			66,  66,  66,  66,  66,  66,  66,  66,
+			66,  66,  66,  66,  66,  66,  66,  66,
+			66,  66,  66,  66,  66,  66,  66,  66,
+			66,  66,  66,  66,  66,  66,  66,  66,
+			66,  66,  66,  66,  66,  66,  66,  66,
+			66,  66,  66,  66,  66,  66,  66,  66,
+			66,  66,  66,  66,  66,  66,  66,  66,
+			66,  66,  66,  66,  66,  66,  66,  66,
+			66,  66,  66,  66,  66,  66,  66,  66,
+			66,  66,  66,  66,  66,  66,  66,  66,
+			66,
+		},
+		{	/* Fourth byte table 7. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   2,   2,   4,   4,   6,   6,   8,
+			8,   10,  10,  12,  12,  14,  14,  16,
+			16,  18,  18,  20,  20,  22,  22,  24,
+			24,  24,  24,  24,  24,  26,  26,  26,
+			26,  26,  26,  26,  26,  26,  26,  26,
+			26,  26,  26,  26,  26,  26,  26,  26,
+			26,  26,  26,  26,  26,  26,  26,  26,
+			26,  26,  26,  26,  26,  26,  26,  26,
+			26,  26,  26,  26,  26,  26,  26,  26,
+			26,  26,  26,  26,  26,  26,  26,  26,
+			26,  26,  26,  26,  26,  26,  26,  26,
+			26,  26,  26,  26,  26,  26,  26,  26,
+			26,  26,  26,  26,  26,  26,  26,  26,
+			26,
+		},
+		{	/* Fourth byte table 8. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   2,   4,   6,   8,   10,  12,  14,
+			16,  18,  20,  22,  24,  26,  28,  30,
+			32,  34,  36,  38,  40,  42,  44,  46,
+			48,  50,  52,  54,  56,  58,  60,  62,
+			64,  66,  68,  70,  72,  74,  76,  78,
+			80,  82,  84,  86,  88,  90,  92,  94,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,
+		},
+		{	/* Fourth byte table 9. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   2,   2,   4,   4,   6,   6,   8,
+			8,   10,  10,  12,  12,  14,  14,  16,
+			16,  18,  18,  20,  20,  22,  22,  24,
+			24,  26,  26,  28,  28,  30,  30,  32,
+			32,  32,  32,  32,  32,  32,  32,  32,
+			32,  32,  32,  32,  32,  32,  32,  32,
+			32,  32,  32,  32,  32,  32,  32,  32,
+			32,  32,  32,  32,  32,  32,  32,  32,
+			32,  32,  32,  32,  32,  32,  32,  32,
+			32,  32,  32,  32,  32,  32,  32,  32,
+			32,  32,  32,  32,  32,  32,  32,  32,
+			32,  32,  32,  32,  32,  32,  32,  32,
+			32,
+		},
+		{	/* Fourth byte table 10. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   2,   2,   2,   2,   2,   2,   2,
+			2,   2,   2,   4,   4,   6,   6,   8,
+			8,   10,  10,  12,  12,  14,  14,  16,
+			16,  18,  18,  20,  20,  22,  22,  24,
+			24,  26,  26,  28,  28,  30,  30,  32,
+			32,  34,  34,  36,  36,  38,  38,  40,
+			40,  42,  42,  44,  44,  46,  46,  48,
+			48,  50,  50,  52,  52,  54,  54,  56,
+			56,  56,  56,  56,  56,  56,  56,  56,
+			56,  56,  56,  56,  56,  56,  56,  56,
+			56,  56,  56,  56,  56,  56,  56,  56,
+			56,  56,  56,  56,  56,  56,  56,  56,
+			56,  56,  56,  56,  56,  56,  56,  56,
+			56,  56,  56,  56,  56,  56,  56,  56,
+			56,  56,  56,  56,  56,  56,  56,  56,
+			56,  56,  56,  56,  56,  56,  56,  56,
+			56,
+		},
+		{	/* Fourth byte table 11. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   2,   2,   4,   4,   6,   6,
+			8,   8,   10,  10,  12,  12,  14,  14,
+			14,  16,  16,  18,  18,  20,  20,  22,
+			22,  24,  24,  26,  26,  28,  28,  30,
+			30,  32,  32,  34,  34,  36,  36,  38,
+			38,  40,  40,  42,  42,  44,  44,  46,
+			46,  48,  48,  50,  50,  52,  52,  52,
+			52,  54,  54,  54,  54,  54,  54,  54,
+			54,  54,  54,  54,  54,  54,  54,  54,
+			54,  54,  54,  54,  54,  54,  54,  54,
+			54,  54,  54,  54,  54,  54,  54,  54,
+			54,  54,  54,  54,  54,  54,  54,  54,
+			54,  54,  54,  54,  54,  54,  54,  54,
+			54,  54,  54,  54,  54,  54,  54,  54,
+			54,  54,  54,  54,  54,  54,  54,  54,
+			54,  54,  54,  54,  54,  54,  54,  54,
+			54,
+		},
+		{	/* Fourth byte table 12. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   2,   2,   4,   4,   6,   6,   8,
+			8,   10,  10,  12,  12,  14,  14,  16,
+			16,  16,  16,  16,  16,  16,  16,  16,
+			16,  16,  16,  16,  16,  16,  16,  16,
+			16,  16,  16,  16,  16,  16,  16,  16,
+			16,  16,  16,  16,  16,  16,  16,  16,
+			16,  16,  18,  20,  22,  24,  26,  28,
+			30,  32,  34,  36,  38,  40,  42,  44,
+			46,  46,  46,  46,  46,  46,  46,  46,
+			46,  46,  46,  46,  46,  46,  46,  46,
+			46,  46,  46,  46,  46,  46,  46,  46,
+			46,  46,  46,  46,  46,  46,  46,  46,
+			46,  46,  46,  46,  46,  46,  46,  46,
+			46,  46,  46,  46,  46,  46,  46,  46,
+			46,  46,  46,  46,  46,  46,  46,  46,
+			46,  46,  46,  46,  46,  46,  46,  46,
+			46,
+		},
+		{	/* Fourth byte table 13. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   2,   4,   6,   8,   10,  12,  14,
+			16,  18,  20,  22,  24,  26,  28,  30,
+			32,  34,  36,  38,  40,  42,  44,  46,
+			46,  46,  46,  46,  46,  46,  46,  46,
+			46,  46,  46,  46,  46,  46,  46,  46,
+			46,  46,  46,  46,  46,  46,  46,  46,
+			46,  46,  46,  46,  46,  46,  46,  46,
+			46,  46,  46,  46,  46,  46,  46,  46,
+			46,  46,  46,  46,  46,  46,  46,  46,
+			46,  46,  46,  46,  46,  46,  46,  46,
+			46,  46,  46,  46,  46,  46,  46,  46,
+			46,  46,  46,  46,  46,  46,  46,  46,
+			46,  46,  46,  46,  46,  46,  46,  46,
+			46,  46,  46,  46,  46,  46,  46,  46,
+			46,  46,  46,  46,  46,  46,  46,  46,
+			46,  46,  46,  46,  46,  46,  46,  46,
+			46,
+		},
+		{	/* Fourth byte table 14. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   3,   3,   6,   6,   9,   9,   12,
+			12,  15,  15,  18,  18,  21,  21,  24,
+			24,  27,  27,  30,  30,  33,  33,  36,
+			36,  39,  39,  42,  42,  45,  45,  48,
+			48,  51,  51,  54,  54,  57,  57,  60,
+			60,  63,  63,  66,  66,  69,  69,  72,
+			72,  75,  75,  78,  78,  81,  81,  84,
+			84,  87,  87,  90,  90,  93,  93,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,
+		},
+		{	/* Fourth byte table 15. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   3,   3,   6,   6,   9,   9,   12,
+			12,  15,  15,  18,  18,  21,  21,  24,
+			24,  27,  27,  30,  30,  33,  33,  36,
+			36,  39,  39,  42,  42,  45,  45,  48,
+			48,  51,  51,  54,  54,  57,  57,  60,
+			60,  63,  63,  66,  66,  69,  69,  72,
+			72,  75,  75,  78,  78,  81,  81,  84,
+			84,  87,  87,  90,  90,  93,  93,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,
+		},
+		{	/* Fourth byte table 16. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   3,   3,   6,   6,   9,   9,   12,
+			12,  15,  15,  18,  18,  21,  21,  24,
+			24,  27,  27,  30,  30,  33,  33,  33,
+			33,  33,  33,  33,  33,  33,  33,  33,
+			33,  36,  36,  39,  39,  42,  42,  45,
+			45,  48,  48,  51,  51,  54,  54,  57,
+			57,  60,  60,  63,  63,  66,  66,  69,
+			69,  72,  72,  75,  75,  78,  78,  81,
+			81,  81,  81,  81,  81,  81,  81,  81,
+			81,  81,  81,  81,  81,  81,  81,  81,
+			81,  81,  81,  81,  81,  81,  81,  81,
+			81,  81,  81,  81,  81,  81,  81,  81,
+			81,  81,  81,  81,  81,  81,  81,  81,
+			81,  81,  81,  81,  81,  81,  81,  81,
+			81,  81,  81,  81,  81,  81,  81,  81,
+			81,  81,  81,  81,  81,  81,  81,  81,
+			81,
+		},
+		{	/* Fourth byte table 17. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   3,   3,   6,   6,   9,   9,   12,
+			12,  15,  15,  18,  18,  21,  21,  24,
+			24,  27,  27,  30,  30,  33,  33,  36,
+			36,  39,  39,  42,  42,  45,  45,  48,
+			48,  51,  51,  54,  54,  57,  57,  60,
+			60,  63,  63,  66,  66,  69,  69,  72,
+			72,  75,  75,  78,  78,  81,  81,  84,
+			84,  87,  87,  87,  87,  87,  87,  87,
+			87,  87,  87,  87,  87,  87,  87,  87,
+			87,  87,  87,  87,  87,  87,  87,  87,
+			87,  87,  87,  87,  87,  87,  87,  87,
+			87,  87,  87,  87,  87,  87,  87,  87,
+			87,  87,  87,  87,  87,  87,  87,  87,
+			87,  87,  87,  87,  87,  87,  87,  87,
+			87,  87,  87,  87,  87,  87,  87,  87,
+			87,  87,  87,  87,  87,  87,  87,  87,
+			87,
+		},
+		{	/* Fourth byte table 18. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   3,   6,   9,   12,  15,  18,  21,
+			24,  24,  24,  24,  24,  24,  24,  24,
+			24,  27,  30,  33,  36,  39,  42,  42,
+			42,  42,  42,  42,  42,  42,  42,  42,
+			42,  45,  48,  51,  54,  57,  60,  63,
+			66,  66,  66,  66,  66,  66,  66,  66,
+			66,  69,  72,  75,  78,  81,  84,  87,
+			90,  90,  90,  90,  90,  90,  90,  90,
+			90,  90,  90,  90,  90,  90,  90,  90,
+			90,  90,  90,  90,  90,  90,  90,  90,
+			90,  90,  90,  90,  90,  90,  90,  90,
+			90,  90,  90,  90,  90,  90,  90,  90,
+			90,  90,  90,  90,  90,  90,  90,  90,
+			90,  90,  90,  90,  90,  90,  90,  90,
+			90,  90,  90,  90,  90,  90,  90,  90,
+			90,
+		},
+		{	/* Fourth byte table 19. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   3,   6,   9,   12,  15,  18,  18,
+			18,  18,  18,  18,  18,  18,  18,  18,
+			18,  18,  21,  21,  24,  24,  27,  27,
+			30,  30,  30,  30,  30,  30,  30,  30,
+			30,  33,  36,  39,  42,  45,  48,  51,
+			54,  54,  54,  54,  54,  54,  54,  54,
+			54,  54,  54,  54,  54,  54,  54,  54,
+			54,  54,  54,  54,  54,  54,  54,  54,
+			54,  54,  54,  54,  54,  54,  54,  54,
+			54,  54,  54,  54,  54,  54,  54,  54,
+			54,  54,  54,  54,  54,  54,  54,  54,
+			54,  54,  54,  54,  54,  54,  54,  54,
+			54,  54,  54,  54,  54,  54,  54,  54,
+			54,  54,  54,  54,  54,  54,  54,  54,
+			54,  54,  54,  54,  54,  54,  54,  54,
+			54,
+		},
+		{	/* Fourth byte table 20. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   3,   6,   9,   12,  15,  18,  21,
+			24,  24,  24,  24,  24,  24,  24,  24,
+			24,  27,  30,  33,  36,  39,  42,  45,
+			48,  48,  48,  48,  48,  48,  48,  48,
+			48,  51,  54,  57,  60,  63,  66,  69,
+			72,  72,  72,  72,  72,  72,  72,  72,
+			72,  75,  78,  81,  84,  87,  87,  87,
+			87,  87,  87,  87,  87,  87,  87,  87,
+			87,  87,  87,  87,  87,  87,  87,  87,
+			87,  87,  87,  87,  87,  87,  87,  87,
+			87,  87,  87,  87,  87,  87,  87,  87,
+			87,  87,  87,  87,  87,  87,  87,  87,
+			87,  87,  87,  87,  87,  87,  87,  87,
+			87,  87,  87,  87,  87,  87,  87,  87,
+			87,  87,  87,  87,  87,  87,  87,  87,
+			87,
+		},
+		{	/* Fourth byte table 21. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   3,   6,   9,   12,  15,  15,  15,
+			15,  15,  15,  15,  15,  15,  15,  15,
+			15,  18,  21,  24,  27,  27,  27,  27,
+			27,  27,  27,  27,  27,  27,  27,  27,
+			27,  30,  33,  36,  39,  42,  42,  42,
+			42,  42,  42,  42,  42,  42,  42,  42,
+			42,  45,  48,  51,  54,  57,  57,  57,
+			57,  57,  57,  57,  57,  57,  57,  57,
+			57,  57,  57,  57,  57,  57,  57,  57,
+			57,  57,  57,  57,  57,  57,  57,  57,
+			57,  57,  57,  57,  57,  57,  57,  57,
+			57,  57,  57,  57,  57,  57,  57,  57,
+			57,  57,  57,  57,  57,  57,  57,  57,
+			57,  57,  57,  57,  57,  57,  57,  57,
+			57,  57,  57,  57,  57,  57,  57,  57,
+			57,
+		},
+		{	/* Fourth byte table 22. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   2,
+			2,   2,   2,   3,   5,   5,   5,   5,
+			5,   5,   5,   5,   5,   5,   5,   5,
+			5,   5,   5,   5,   5,   5,   5,   5,
+			5,   5,   5,   5,   5,   5,   5,   5,
+			5,   5,   5,   5,   5,   5,   5,   5,
+			5,   5,   5,   5,   5,   5,   5,   5,
+			5,   5,   5,   5,   5,   5,   5,   5,
+			5,   5,   5,   5,   5,   5,   5,   5,
+			5,   5,   5,   5,   5,   5,   5,   5,
+			5,   5,   5,   5,   5,   5,   5,   5,
+			5,   5,   5,   5,   5,   5,   5,   5,
+			5,
+		},
+		{	/* Fourth byte table 23. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   3,   6,   9,   12,  15,  18,  21,
+			24,  27,  30,  33,  36,  39,  42,  45,
+			48,  48,  48,  48,  48,  48,  48,  48,
+			48,  48,  48,  48,  48,  48,  48,  48,
+			48,  48,  48,  48,  48,  48,  48,  48,
+			48,  48,  48,  48,  48,  48,  48,  48,
+			48,  48,  48,  48,  48,  48,  48,  48,
+			48,  48,  48,  48,  48,  48,  48,  48,
+			48,  48,  48,  48,  48,  48,  48,  48,
+			48,  48,  48,  48,  48,  48,  48,  48,
+			48,  48,  48,  48,  48,  48,  48,  48,
+			48,  48,  48,  48,  48,  48,  48,  48,
+			48,
+		},
+		{	/* Fourth byte table 24. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   3,
+			6,   9,   12,  15,  18,  21,  24,  27,
+			30,  30,  30,  30,  30,  30,  30,  30,
+			30,  30,  30,  30,  30,  30,  30,  30,
+			30,  30,  30,  30,  30,  30,  30,  30,
+			30,  30,  30,  30,  30,  30,  30,  30,
+			30,  30,  30,  30,  30,  30,  30,  30,
+			30,  30,  30,  30,  30,  30,  30,  30,
+			30,  30,  30,  30,  30,  30,  30,  30,
+			30,  30,  30,  30,  30,  30,  30,  30,
+			30,
+		},
+		{	/* Fourth byte table 25. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   3,   6,   9,   12,  15,  18,  21,
+			24,  27,  30,  33,  36,  39,  42,  45,
+			48,  48,  48,  48,  48,  48,  48,  48,
+			48,  48,  48,  48,  48,  48,  48,  48,
+			48,  48,  48,  48,  48,  48,  48,  48,
+			48,  48,  48,  48,  48,  48,  48,  48,
+			48,  48,  48,  48,  48,  48,  48,  48,
+			48,  48,  48,  48,  48,  48,  48,  48,
+			48,  48,  48,  48,  48,  48,  48,  48,
+			48,  48,  48,  48,  48,  48,  48,  48,
+			48,  48,  48,  48,  48,  48,  48,  48,
+			48,  48,  48,  48,  48,  48,  48,  48,
+			48,  48,  48,  48,  48,  48,  48,  48,
+			48,  48,  48,  48,  48,  48,  48,  48,
+			48,  48,  48,  48,  48,  48,  48,  48,
+			48,  48,  48,  48,  48,  48,  48,  48,
+			48,
+		},
+		{	/* Fourth byte table 26. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   3,   6,   9,   12,  15,  18,
+			21,  24,  27,  30,  33,  36,  39,  42,
+			45,  48,  51,  54,  57,  60,  63,  66,
+			69,  72,  75,  78,  78,  78,  78,  78,
+			78,  78,  78,  78,  78,  78,  78,  78,
+			78,  78,  78,  78,  78,  78,  78,  78,
+			78,  78,  78,  78,  78,  78,  78,  78,
+			78,  78,  78,  78,  78,  78,  78,  78,
+			78,  78,  78,  78,  78,  78,  78,  78,
+			78,  78,  78,  78,  78,  78,  78,  78,
+			78,  78,  78,  78,  78,  78,  78,  78,
+			78,  78,  78,  78,  78,  78,  78,  78,
+			78,
+		},
+		{	/* Fourth byte table 27. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   4,   8,   12,  16,  20,  24,  28,
+			32,  36,  40,  44,  48,  52,  56,  60,
+			64,  68,  72,  76,  80,  84,  88,  92,
+			96,  100, 104, 108, 112, 116, 120, 124,
+			128, 132, 136, 140, 144, 148, 152, 152,
+			152, 152, 152, 152, 152, 152, 152, 152,
+			152, 152, 152, 152, 152, 152, 152, 152,
+			152, 152, 152, 152, 152, 152, 152, 152,
+			152, 152, 152, 152, 152, 152, 152, 152,
+			152, 152, 152, 152, 152, 152, 152, 152,
+			152, 152, 152, 152, 152, 152, 152, 152,
+			152, 152, 152, 152, 152, 152, 152, 152,
+			152, 152, 152, 152, 152, 152, 152, 152,
+			152, 152, 152, 152, 152, 152, 152, 152,
+			152, 152, 152, 152, 152, 152, 152, 152,
+			152, 152, 152, 152, 152, 152, 152, 152,
+			152,
+		},
+		{	/* Fourth byte table 28. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,
+		},
+		{	/* Fourth byte table 29. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,
+		},
+		{	/* Fourth byte table 30. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,
+		},
+		{	/* Fourth byte table 31. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,
+		},
+		{	/* Fourth byte table 32. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,
+		},
+		{	/* Fourth byte table 33. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,
+		},
+		{	/* Fourth byte table 34. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,
+		},
+		{	/* Fourth byte table 35. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,
+		},
+	},
+	{
+		{	/* Fourth byte table 0. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   2,   4,   6,   8,   10,  12,  14,
+			16,  18,  20,  22,  24,  26,  28,  30,
+			32,  34,  36,  38,  40,  42,  44,  46,
+			46,  48,  50,  52,  54,  56,  58,  60,
+			60,  60,  60,  60,  60,  60,  60,  60,
+			60,  60,  60,  60,  60,  60,  60,  60,
+			60,  60,  60,  60,  60,  60,  60,  60,
+			60,  60,  60,  60,  60,  60,  60,  60,
+			60,  60,  60,  60,  60,  60,  60,  60,
+			60,  60,  60,  60,  60,  60,  60,  60,
+			60,  60,  60,  60,  60,  60,  60,  60,
+			60,  60,  60,  60,  60,  60,  60,  60,
+			60,  60,  60,  60,  60,  60,  60,  60,
+			60,  60,  60,  60,  60,  60,  60,  60,
+			60,  60,  60,  60,  60,  60,  60,  60,
+			60,  60,  60,  60,  60,  60,  60,  60,
+			60,
+		},
+		{	/* Fourth byte table 1. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   2,   2,   4,   4,   6,   6,   8,
+			8,   10,  10,  12,  12,  14,  14,  16,
+			16,  18,  18,  20,  20,  22,  22,  24,
+			24,  26,  26,  28,  28,  30,  30,  32,
+			32,  34,  34,  36,  36,  38,  38,  40,
+			40,  42,  42,  44,  44,  46,  46,  48,
+			48,  49,  49,  51,  51,  53,  53,  55,
+			55,  55,  57,  57,  59,  59,  61,  61,
+			63,  63,  63,  63,  63,  63,  63,  63,
+			63,  63,  63,  63,  63,  63,  63,  63,
+			63,  63,  63,  63,  63,  63,  63,  63,
+			63,  63,  63,  63,  63,  63,  63,  63,
+			63,  63,  63,  63,  63,  63,  63,  63,
+			63,  63,  63,  63,  63,  63,  63,  63,
+			63,  63,  63,  63,  63,  63,  63,  63,
+			63,  63,  63,  63,  63,  63,  63,  63,
+			63,
+		},
+		{	/* Fourth byte table 2. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   2,   2,   4,   4,   6,   6,
+			8,   8,   8,   10,  10,  12,  12,  14,
+			14,  16,  16,  18,  18,  20,  20,  22,
+			22,  24,  24,  26,  26,  28,  28,  30,
+			30,  32,  32,  34,  34,  36,  36,  38,
+			38,  40,  40,  42,  42,  44,  44,  46,
+			46,  48,  48,  50,  50,  52,  52,  54,
+			54,  56,  58,  58,  60,  60,  62,  62,
+			62,  62,  62,  62,  62,  62,  62,  62,
+			62,  62,  62,  62,  62,  62,  62,  62,
+			62,  62,  62,  62,  62,  62,  62,  62,
+			62,  62,  62,  62,  62,  62,  62,  62,
+			62,  62,  62,  62,  62,  62,  62,  62,
+			62,  62,  62,  62,  62,  62,  62,  62,
+			62,  62,  62,  62,  62,  62,  62,  62,
+			62,  62,  62,  62,  62,  62,  62,  62,
+			62,
+		},
+		{	/* Fourth byte table 3. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   2,   4,   4,   6,   6,   8,
+			10,  10,  12,  14,  16,  16,  16,  18,
+			20,  22,  24,  24,  26,  28,  28,  30,
+			32,  34,  34,  34,  34,  36,  38,  38,
+			40,  42,  42,  44,  44,  46,  46,  48,
+			50,  50,  52,  52,  52,  54,  54,  56,
+			58,  58,  60,  62,  64,  64,  66,  66,
+			68,  70,  70,  70,  70,  72,  72,  72,
+			72,  72,  72,  72,  72,  72,  72,  72,
+			72,  72,  72,  72,  72,  72,  72,  72,
+			72,  72,  72,  72,  72,  72,  72,  72,
+			72,  72,  72,  72,  72,  72,  72,  72,
+			72,  72,  72,  72,  72,  72,  72,  72,
+			72,  72,  72,  72,  72,  72,  72,  72,
+			72,  72,  72,  72,  72,  72,  72,  72,
+			72,  72,  72,  72,  72,  72,  72,  72,
+			72,
+		},
+		{	/* Fourth byte table 4. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   2,   4,   4,
+			6,   8,   8,   10,  12,  12,  14,  14,
+			16,  16,  18,  18,  20,  20,  22,  22,
+			24,  24,  26,  26,  28,  28,  28,  30,
+			30,  32,  32,  34,  34,  36,  36,  38,
+			38,  40,  40,  42,  42,  44,  44,  46,
+			46,  46,  48,  50,  50,  52,  52,  54,
+			56,  58,  58,  60,  60,  62,  62,  64,
+			64,  64,  64,  64,  64,  64,  64,  64,
+			64,  64,  64,  64,  64,  64,  64,  64,
+			64,  64,  64,  64,  64,  64,  64,  64,
+			64,  64,  64,  64,  64,  64,  64,  64,
+			64,  64,  64,  64,  64,  64,  64,  64,
+			64,  64,  64,  64,  64,  64,  64,  64,
+			64,  64,  64,  64,  64,  64,  64,  64,
+			64,  64,  64,  64,  64,  64,  64,  64,
+			64,
+		},
+		{	/* Fourth byte table 5. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   2,   2,   4,   4,   6,   6,   8,
+			8,   10,  10,  12,  12,  14,  14,  16,
+			16,  18,  18,  20,  20,  22,  22,  24,
+			24,  26,  26,  28,  28,  30,  30,  32,
+			32,  34,  34,  36,  36,  38,  38,  40,
+			40,  42,  42,  44,  44,  46,  46,  48,
+			48,  50,  50,  52,  52,  52,  52,  52,
+			52,  52,  52,  55,  57,  57,  59,  62,
+			62,  62,  62,  62,  62,  62,  62,  62,
+			62,  62,  62,  62,  62,  62,  62,  62,
+			62,  62,  62,  62,  62,  62,  62,  62,
+			62,  62,  62,  62,  62,  62,  62,  62,
+			62,  62,  62,  62,  62,  62,  62,  62,
+			62,  62,  62,  62,  62,  62,  62,  62,
+			62,  62,  62,  62,  62,  62,  62,  62,
+			62,  62,  62,  62,  62,  62,  62,  62,
+			62,
+		},
+		{	/* Fourth byte table 6. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   2,   2,   4,   6,   8,   10,
+			10,  12,  12,  14,  14,  16,  16,  18,
+			18,  18,  18,  18,  18,  18,  18,  18,
+			18,  18,  18,  18,  18,  18,  18,  18,
+			18,  18,  18,  18,  18,  18,  18,  18,
+			18,  18,  18,  18,  18,  18,  18,  18,
+			18,  18,  18,  18,  18,  18,  18,  18,
+			18,  18,  18,  18,  18,  18,  18,  18,
+			18,  18,  18,  18,  18,  18,  18,  18,
+			18,  18,  18,  18,  18,  18,  18,  18,
+			18,  18,  18,  18,  18,  18,  18,  18,
+			18,  18,  18,  18,  18,  18,  18,  18,
+			18,  18,  18,  18,  18,  18,  18,  18,
+			18,  18,  18,  18,  18,  18,  18,  18,
+			18,  18,  18,  18,  18,  18,  18,  18,
+			18,  18,  18,  18,  18,  18,  18,  18,
+			18,
+		},
+		{	/* Fourth byte table 7. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   2,
+			2,   4,   6,   8,   8,   10,  10,  12,
+			14,  14,  16,  18,  20,  22,  24,  26,
+			28,  30,  32,  34,  36,  38,  40,  42,
+			44,  46,  48,  48,  50,  52,  54,  56,
+			58,  60,  62,  64,  66,  66,  66,  66,
+			66,  66,  66,  66,  66,  66,  66,  66,
+			66,  66,  66,  66,  66,  66,  66,  66,
+			66,  66,  66,  66,  66,  66,  66,  66,
+			66,  66,  66,  66,  66,  66,  66,  66,
+			66,  66,  66,  66,  66,  66,  66,  66,
+			66,  66,  66,  66,  66,  66,  66,  66,
+			66,  66,  66,  66,  66,  66,  66,  66,
+			66,  66,  66,  66,  66,  66,  66,  66,
+			66,  66,  66,  66,  66,  66,  66,  66,
+			66,  66,  66,  66,  66,  66,  66,  66,
+			66,
+		},
+		{	/* Fourth byte table 8. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   2,   2,   4,   4,   6,   6,   8,
+			8,   10,  10,  12,  12,  14,  14,  16,
+			16,  18,  18,  20,  20,  22,  22,  24,
+			24,  24,  24,  24,  24,  26,  26,  26,
+			28,  28,  30,  32,  32,  32,  34,  36,
+			38,  38,  38,  38,  38,  38,  38,  38,
+			38,  38,  38,  38,  38,  38,  38,  38,
+			38,  38,  38,  38,  38,  38,  38,  38,
+			38,  38,  38,  38,  38,  38,  38,  38,
+			38,  38,  38,  38,  38,  38,  38,  38,
+			38,  38,  38,  38,  38,  38,  38,  38,
+			38,  38,  38,  38,  38,  38,  38,  38,
+			38,  38,  38,  38,  38,  38,  38,  38,
+			38,
+		},
+		{	/* Fourth byte table 9. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   2,   4,   6,   8,   10,  12,  14,
+			16,  18,  20,  22,  24,  26,  28,  30,
+			32,  34,  36,  38,  40,  42,  44,  46,
+			48,  50,  52,  54,  56,  58,  60,  62,
+			64,  66,  68,  70,  72,  74,  76,  78,
+			80,  82,  84,  86,  88,  90,  92,  94,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,
+		},
+		{	/* Fourth byte table 10. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   2,   2,   4,   4,   6,   6,   8,
+			8,   10,  10,  12,  12,  14,  14,  16,
+			16,  18,  18,  20,  20,  22,  22,  24,
+			24,  26,  26,  28,  28,  30,  30,  32,
+			32,  32,  32,  32,  32,  32,  32,  32,
+			32,  32,  32,  32,  32,  32,  32,  32,
+			32,  32,  32,  32,  32,  32,  32,  32,
+			32,  32,  32,  32,  32,  32,  32,  32,
+			32,  32,  32,  32,  32,  32,  32,  32,
+			32,  32,  32,  32,  32,  32,  32,  32,
+			32,  32,  32,  32,  32,  32,  32,  32,
+			32,  32,  32,  32,  32,  32,  32,  32,
+			32,
+		},
+		{	/* Fourth byte table 11. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   2,   2,   2,   2,   2,   2,   2,
+			2,   2,   2,   4,   4,   6,   6,   8,
+			8,   10,  10,  12,  12,  14,  14,  16,
+			16,  18,  18,  20,  20,  22,  22,  24,
+			24,  26,  26,  28,  28,  30,  30,  32,
+			32,  34,  34,  36,  36,  38,  38,  40,
+			40,  42,  42,  44,  44,  46,  46,  48,
+			48,  50,  50,  52,  52,  54,  54,  56,
+			56,  56,  56,  56,  56,  56,  56,  56,
+			56,  56,  56,  56,  56,  56,  56,  56,
+			56,  56,  56,  56,  56,  56,  56,  56,
+			56,  56,  56,  56,  56,  56,  56,  56,
+			56,  56,  56,  56,  56,  56,  56,  56,
+			56,  56,  56,  56,  56,  56,  56,  56,
+			56,  56,  56,  56,  56,  56,  56,  56,
+			56,  56,  56,  56,  56,  56,  56,  56,
+			56,
+		},
+		{	/* Fourth byte table 12. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   2,   4,   4,   6,   6,   8,   8,
+			10,  10,  12,  12,  14,  14,  16,  16,
+			16,  18,  18,  20,  20,  22,  22,  24,
+			24,  26,  26,  28,  28,  30,  30,  32,
+			32,  34,  34,  36,  36,  38,  38,  40,
+			40,  42,  42,  44,  44,  46,  46,  48,
+			48,  50,  50,  52,  52,  54,  54,  56,
+			56,  58,  58,  60,  60,  62,  62,  64,
+			64,  64,  64,  64,  64,  64,  64,  64,
+			64,  64,  64,  64,  64,  64,  64,  64,
+			64,  64,  64,  64,  64,  64,  64,  64,
+			64,  64,  64,  64,  64,  64,  64,  64,
+			64,  64,  64,  64,  64,  64,  64,  64,
+			64,  64,  64,  64,  64,  64,  64,  64,
+			64,  64,  64,  64,  64,  64,  64,  64,
+			64,  64,  64,  64,  64,  64,  64,  64,
+			64,
+		},
+		{	/* Fourth byte table 13. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   2,   2,   4,   4,   6,   6,   8,
+			8,   10,  10,  12,  12,  14,  14,  16,
+			16,  18,  18,  20,  20,  20,  20,  20,
+			20,  20,  20,  20,  20,  20,  20,  20,
+			20,  20,  20,  20,  20,  20,  20,  20,
+			20,  20,  20,  20,  20,  20,  20,  20,
+			20,  20,  22,  24,  26,  28,  30,  32,
+			34,  36,  38,  40,  42,  44,  46,  48,
+			50,  50,  50,  50,  50,  50,  50,  50,
+			50,  50,  50,  50,  50,  50,  50,  50,
+			50,  50,  50,  50,  50,  50,  50,  50,
+			50,  50,  50,  50,  50,  50,  50,  50,
+			50,  50,  50,  50,  50,  50,  50,  50,
+			50,  50,  50,  50,  50,  50,  50,  50,
+			50,  50,  50,  50,  50,  50,  50,  50,
+			50,  50,  50,  50,  50,  50,  50,  50,
+			50,
+		},
+		{	/* Fourth byte table 14. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   2,   4,   6,   8,   10,  12,  14,
+			16,  18,  20,  22,  24,  26,  28,  30,
+			32,  34,  36,  38,  40,  42,  44,  46,
+			46,  46,  46,  46,  46,  46,  46,  46,
+			46,  46,  46,  46,  46,  46,  46,  46,
+			46,  46,  46,  46,  46,  46,  46,  46,
+			46,  46,  46,  46,  46,  46,  46,  46,
+			46,  46,  46,  46,  46,  46,  46,  46,
+			46,  46,  46,  46,  46,  46,  46,  46,
+			46,  46,  46,  46,  46,  46,  46,  46,
+			46,  46,  46,  46,  46,  46,  46,  46,
+			46,  46,  46,  46,  46,  46,  46,  46,
+			46,  46,  46,  46,  46,  46,  46,  46,
+			46,  46,  46,  46,  46,  46,  46,  46,
+			46,  46,  46,  46,  46,  46,  46,  46,
+			46,  46,  46,  46,  46,  46,  46,  46,
+			46,
+		},
+		{	/* Fourth byte table 15. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   3,   6,   9,   12,  15,  18,  21,
+			24,  27,  30,  33,  36,  39,  42,  45,
+			48,  51,  54,  57,  60,  63,  66,  69,
+			72,  75,  78,  81,  84,  87,  90,  93,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,
+		},
+		{	/* Fourth byte table 16. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   3,   6,   9,   12,  15,  18,  18,
+			18,  18,  18,  18,  18,  18,  18,  18,
+			18,  18,  18,  18,  18,  18,  18,  18,
+			18,  18,  18,  18,  18,  18,  18,  18,
+			18,  18,  18,  18,  18,  18,  18,  18,
+			18,  18,  18,  18,  18,  18,  18,  18,
+			18,  18,  18,  18,  18,  18,  18,  18,
+			18,  18,  18,  18,  18,  18,  18,  18,
+			18,  18,  18,  18,  18,  18,  18,  18,
+			18,  18,  18,  18,  18,  18,  18,  18,
+			18,  18,  18,  18,  18,  18,  18,  18,
+			18,  18,  18,  18,  18,  18,  18,  18,
+			18,  18,  18,  18,  18,  18,  18,  18,
+			18,  18,  18,  18,  18,  18,  18,  18,
+			18,  18,  18,  18,  18,  18,  18,  18,
+			18,  18,  18,  18,  18,  18,  18,  18,
+			18,
+		},
+		{	/* Fourth byte table 17. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   3,   3,   6,   6,   9,   9,   12,
+			12,  15,  15,  18,  18,  21,  21,  24,
+			24,  27,  27,  30,  30,  33,  33,  36,
+			36,  39,  39,  42,  42,  45,  45,  48,
+			48,  51,  51,  54,  54,  57,  57,  60,
+			60,  63,  63,  66,  66,  69,  69,  72,
+			72,  75,  75,  78,  78,  81,  81,  84,
+			84,  87,  87,  90,  90,  93,  93,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,
+		},
+		{	/* Fourth byte table 18. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   3,   3,   6,   6,   9,   9,   12,
+			12,  15,  15,  18,  18,  21,  21,  24,
+			24,  27,  27,  30,  30,  33,  33,  36,
+			36,  39,  39,  42,  42,  45,  45,  48,
+			48,  51,  51,  54,  54,  57,  57,  60,
+			60,  63,  63,  66,  66,  69,  69,  72,
+			72,  75,  75,  78,  78,  81,  81,  84,
+			84,  87,  87,  90,  90,  93,  93,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,
+		},
+		{	/* Fourth byte table 19. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   3,   3,   6,   6,   9,   9,   12,
+			12,  15,  15,  18,  18,  21,  21,  24,
+			24,  27,  27,  30,  30,  33,  33,  33,
+			33,  33,  33,  33,  33,  33,  33,  33,
+			33,  36,  36,  39,  39,  42,  42,  45,
+			45,  48,  48,  51,  51,  54,  54,  57,
+			57,  60,  60,  63,  63,  66,  66,  69,
+			69,  72,  72,  75,  75,  78,  78,  81,
+			81,  81,  81,  81,  81,  81,  81,  81,
+			81,  81,  81,  81,  81,  81,  81,  81,
+			81,  81,  81,  81,  81,  81,  81,  81,
+			81,  81,  81,  81,  81,  81,  81,  81,
+			81,  81,  81,  81,  81,  81,  81,  81,
+			81,  81,  81,  81,  81,  81,  81,  81,
+			81,  81,  81,  81,  81,  81,  81,  81,
+			81,  81,  81,  81,  81,  81,  81,  81,
+			81,
+		},
+		{	/* Fourth byte table 20. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   3,   3,   6,   6,   9,   9,   12,
+			12,  15,  15,  18,  18,  21,  21,  24,
+			24,  27,  27,  30,  30,  33,  33,  36,
+			36,  39,  39,  42,  42,  45,  45,  48,
+			48,  51,  51,  54,  54,  57,  57,  60,
+			60,  63,  63,  66,  66,  69,  69,  72,
+			72,  75,  75,  78,  78,  81,  81,  84,
+			84,  87,  87,  87,  87,  87,  87,  87,
+			87,  87,  87,  87,  87,  87,  87,  87,
+			87,  87,  87,  87,  87,  87,  87,  87,
+			87,  87,  87,  87,  87,  87,  87,  87,
+			87,  87,  87,  87,  87,  87,  87,  87,
+			87,  87,  87,  87,  87,  87,  87,  87,
+			87,  87,  87,  87,  87,  87,  87,  87,
+			87,  87,  87,  87,  87,  87,  87,  87,
+			87,  87,  87,  87,  87,  87,  87,  87,
+			87,
+		},
+		{	/* Fourth byte table 21. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   3,   6,   9,   12,  15,  18,  21,
+			24,  24,  24,  24,  24,  24,  24,  24,
+			24,  27,  30,  33,  36,  39,  42,  42,
+			42,  42,  42,  42,  42,  42,  42,  42,
+			42,  45,  48,  51,  54,  57,  60,  63,
+			66,  66,  66,  66,  66,  66,  66,  66,
+			66,  69,  72,  75,  78,  81,  84,  87,
+			90,  90,  90,  90,  90,  90,  90,  90,
+			90,  90,  90,  90,  90,  90,  90,  90,
+			90,  90,  90,  90,  90,  90,  90,  90,
+			90,  90,  90,  90,  90,  90,  90,  90,
+			90,  90,  90,  90,  90,  90,  90,  90,
+			90,  90,  90,  90,  90,  90,  90,  90,
+			90,  90,  90,  90,  90,  90,  90,  90,
+			90,  90,  90,  90,  90,  90,  90,  90,
+			90,
+		},
+		{	/* Fourth byte table 22. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   3,   6,   9,   12,  15,  18,  18,
+			18,  18,  18,  18,  18,  18,  18,  18,
+			18,  18,  21,  21,  24,  24,  27,  27,
+			30,  30,  30,  30,  30,  30,  30,  30,
+			30,  33,  36,  39,  42,  45,  48,  51,
+			54,  54,  54,  54,  54,  54,  54,  54,
+			54,  54,  54,  54,  54,  54,  54,  54,
+			54,  54,  54,  54,  54,  54,  54,  54,
+			54,  54,  54,  54,  54,  54,  54,  54,
+			54,  54,  54,  54,  54,  54,  54,  54,
+			54,  54,  54,  54,  54,  54,  54,  54,
+			54,  54,  54,  54,  54,  54,  54,  54,
+			54,  54,  54,  54,  54,  54,  54,  54,
+			54,  54,  54,  54,  54,  54,  54,  54,
+			54,  54,  54,  54,  54,  54,  54,  54,
+			54,
+		},
+		{	/* Fourth byte table 23. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   3,   6,   9,   12,  15,  18,  21,
+			24,  24,  24,  24,  24,  24,  24,  24,
+			24,  27,  30,  33,  36,  39,  42,  45,
+			48,  48,  48,  48,  48,  48,  48,  48,
+			48,  51,  54,  57,  60,  63,  66,  69,
+			72,  72,  72,  72,  72,  72,  72,  72,
+			72,  75,  78,  81,  84,  87,  87,  87,
+			87,  87,  87,  87,  87,  87,  87,  87,
+			87,  87,  87,  87,  87,  87,  87,  87,
+			87,  87,  87,  87,  87,  87,  87,  87,
+			87,  87,  87,  87,  87,  87,  87,  87,
+			87,  87,  87,  87,  87,  87,  87,  87,
+			87,  87,  87,  87,  87,  87,  87,  87,
+			87,  87,  87,  87,  87,  87,  87,  87,
+			87,  87,  87,  87,  87,  87,  87,  87,
+			87,
+		},
+		{	/* Fourth byte table 24. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   3,   6,   9,   12,  15,  15,  15,
+			15,  15,  15,  15,  15,  15,  15,  15,
+			15,  18,  21,  24,  27,  27,  27,  27,
+			27,  27,  27,  27,  27,  27,  27,  27,
+			27,  30,  33,  36,  39,  42,  42,  42,
+			42,  42,  42,  42,  42,  42,  42,  42,
+			42,  45,  48,  51,  54,  57,  57,  57,
+			57,  57,  57,  57,  57,  57,  57,  57,
+			57,  57,  57,  57,  57,  57,  57,  57,
+			57,  57,  57,  57,  57,  57,  57,  57,
+			57,  57,  57,  57,  57,  57,  57,  57,
+			57,  57,  57,  57,  57,  57,  57,  57,
+			57,  57,  57,  57,  57,  57,  57,  57,
+			57,  57,  57,  57,  57,  57,  57,  57,
+			57,  57,  57,  57,  57,  57,  57,  57,
+			57,
+		},
+		{	/* Fourth byte table 25. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   2,
+			2,   2,   2,   3,   5,   5,   5,   5,
+			5,   5,   5,   8,   8,   8,   8,   8,
+			8,   8,   8,   8,   8,   8,   8,   8,
+			8,   8,   8,   8,   8,   8,   8,   8,
+			8,   8,   8,   8,   8,   8,   8,   8,
+			8,   8,   8,   8,   8,   8,   8,   8,
+			8,   8,   8,   8,   8,   8,   8,   8,
+			8,   8,   8,   8,   8,   8,   8,   8,
+			8,   8,   8,   8,   8,   8,   8,   8,
+			8,   8,   8,   8,   8,   8,   8,   8,
+			8,   8,   8,   8,   8,   8,   8,   8,
+			8,
+		},
+		{	/* Fourth byte table 26. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   3,   6,   9,   12,  15,  18,  21,
+			24,  27,  30,  33,  36,  39,  42,  45,
+			48,  48,  48,  48,  48,  48,  48,  48,
+			48,  48,  48,  48,  48,  48,  48,  48,
+			48,  48,  48,  48,  48,  48,  48,  48,
+			48,  48,  48,  48,  48,  48,  48,  48,
+			48,  48,  48,  48,  48,  48,  48,  48,
+			48,  48,  48,  48,  48,  48,  48,  48,
+			48,  48,  48,  48,  48,  48,  48,  48,
+			48,  48,  48,  48,  48,  48,  48,  48,
+			48,  48,  48,  48,  48,  48,  48,  48,
+			48,  48,  48,  48,  48,  48,  48,  48,
+			48,
+		},
+		{	/* Fourth byte table 27. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   3,   3,   3,   3,
+			3,   3,   3,   3,   3,   3,   3,   3,
+			3,   3,   3,   3,   3,   3,   3,   3,
+			3,   3,   3,   3,   3,   3,   3,   3,
+			3,   3,   3,   3,   3,   3,   3,   3,
+			3,   3,   3,   3,   3,   3,   3,   3,
+			3,   3,   3,   3,   3,   3,   3,   3,
+			3,   3,   3,   3,   3,   3,   3,   3,
+			3,   3,   3,   3,   3,   3,   3,   3,
+			3,   3,   3,   3,   3,   3,   3,   3,
+			3,   3,   3,   3,   3,   3,   3,   3,
+			3,   3,   3,   3,   3,   3,   3,   3,
+			3,   3,   3,   3,   3,   3,   3,   3,
+			3,   3,   3,   3,   3,   3,   3,   3,
+			3,   3,   3,   3,   3,   3,   3,   3,
+			3,   3,   3,   3,   3,   3,   3,   3,
+			3,
+		},
+		{	/* Fourth byte table 28. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   3,
+			6,   9,   12,  15,  18,  21,  24,  27,
+			30,  30,  30,  30,  30,  30,  30,  30,
+			30,  30,  30,  30,  30,  30,  30,  30,
+			30,  30,  30,  30,  30,  30,  30,  30,
+			30,  30,  30,  30,  30,  30,  30,  30,
+			30,  30,  30,  30,  30,  30,  30,  30,
+			30,  30,  30,  30,  30,  30,  30,  30,
+			30,  30,  30,  30,  30,  30,  30,  30,
+			30,  30,  30,  30,  30,  30,  30,  30,
+			30,
+		},
+		{	/* Fourth byte table 29. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   3,   6,   9,   12,  15,  18,  21,
+			24,  27,  30,  33,  36,  39,  42,  45,
+			48,  48,  48,  48,  48,  48,  48,  48,
+			48,  48,  48,  48,  48,  48,  48,  48,
+			48,  48,  48,  48,  48,  48,  48,  48,
+			48,  48,  48,  48,  48,  48,  48,  48,
+			48,  48,  48,  48,  48,  48,  48,  48,
+			48,  48,  48,  48,  48,  48,  48,  48,
+			48,  48,  48,  48,  48,  48,  48,  48,
+			48,  48,  48,  48,  48,  48,  48,  48,
+			48,  48,  48,  48,  48,  48,  48,  48,
+			48,  48,  48,  48,  48,  48,  48,  48,
+			48,  48,  48,  48,  48,  48,  48,  48,
+			48,  48,  48,  48,  48,  48,  48,  48,
+			48,  48,  48,  48,  48,  48,  48,  48,
+			48,  48,  48,  48,  48,  48,  48,  48,
+			48,
+		},
+		{	/* Fourth byte table 30. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   3,   6,   9,   12,  15,  18,  21,
+			24,  27,  30,  33,  36,  39,  42,  45,
+			48,  51,  54,  57,  60,  63,  66,  69,
+			72,  75,  78,  81,  84,  87,  90,  93,
+			96,  99,  102, 105, 108, 111, 114, 117,
+			120, 123, 126, 129, 132, 135, 138, 141,
+			141, 141, 141, 141, 141, 141, 141, 141,
+			141, 141, 141, 141, 141, 141, 141, 141,
+			141, 141, 141, 141, 141, 141, 141, 141,
+			141, 141, 141, 141, 141, 141, 141, 141,
+			141, 141, 141, 141, 141, 141, 141, 141,
+			141, 141, 141, 141, 141, 141, 141, 141,
+			141, 141, 141, 141, 141, 141, 141, 141,
+			141, 141, 141, 141, 141, 141, 141, 141,
+			141, 141, 141, 141, 141, 141, 141, 141,
+			141, 141, 141, 141, 141, 141, 141, 141,
+			141,
+		},
+		{	/* Fourth byte table 31. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   3,   3,   5,   8,   10,  10,  10,
+			13,  13,  16,  16,  19,  19,  19,  19,
+			19,  19,  19,  19,  19,  19,  22,  22,
+			22,  22,  22,  22,  22,  22,  22,  22,
+			22,  22,  22,  22,  22,  22,  22,  22,
+			22,  22,  22,  22,  22,  22,  22,  22,
+			22,  22,  22,  22,  22,  22,  22,  22,
+			22,  22,  22,  22,  22,  22,  22,  22,
+			22,  22,  22,  22,  22,  22,  22,  22,
+			22,  22,  22,  22,  22,  22,  22,  22,
+			22,  22,  22,  22,  22,  22,  22,  22,
+			22,  22,  22,  22,  22,  22,  22,  22,
+			22,
+		},
+		{	/* Fourth byte table 32. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   3,   3,   6,   6,   9,   9,   12,
+			12,  15,  15,  18,  18,  21,  21,  24,
+			24,  27,  27,  30,  30,  33,  33,  36,
+			36,  39,  39,  42,  42,  45,  45,  48,
+			48,  51,  51,  54,  54,  57,  57,  60,
+			60,  63,  63,  66,  66,  69,  69,  72,
+			72,  75,  75,  78,  78,  81,  81,  84,
+			84,  87,  87,  90,  90,  93,  93,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,
+		},
+		{	/* Fourth byte table 33. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   3,   3,   6,   6,   9,   9,   12,
+			12,  15,  15,  18,  18,  21,  21,  24,
+			24,  27,  27,  30,  30,  33,  33,  36,
+			36,  39,  39,  42,  42,  45,  45,  48,
+			48,  51,  51,  54,  54,  54,  54,  54,
+			54,  54,  54,  54,  54,  54,  54,  54,
+			54,  54,  54,  54,  54,  54,  54,  54,
+			54,  54,  54,  54,  54,  54,  54,  54,
+			54,  54,  54,  54,  54,  54,  54,  54,
+			54,  54,  54,  54,  54,  54,  54,  54,
+			54,  54,  54,  54,  54,  54,  54,  54,
+			54,  54,  54,  54,  54,  54,  54,  54,
+			54,  54,  54,  54,  54,  54,  54,  54,
+			54,  54,  54,  54,  54,  54,  54,  54,
+			54,  54,  54,  54,  54,  54,  54,  54,
+			54,  54,  54,  54,  54,  54,  54,  54,
+			54,
+		},
+		{	/* Fourth byte table 34. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   3,   6,   9,   12,  15,  18,
+			21,  24,  27,  30,  33,  36,  39,  42,
+			45,  48,  51,  54,  57,  60,  63,  66,
+			69,  72,  75,  78,  78,  78,  78,  78,
+			78,  78,  78,  78,  78,  78,  78,  78,
+			78,  78,  78,  78,  78,  78,  78,  78,
+			78,  78,  78,  78,  78,  78,  78,  78,
+			78,  78,  78,  78,  78,  78,  78,  78,
+			78,  78,  78,  78,  78,  78,  78,  78,
+			78,  78,  78,  78,  78,  78,  78,  78,
+			78,  78,  78,  78,  78,  78,  78,  78,
+			78,  78,  78,  78,  78,  78,  78,  78,
+			78,
+		},
+		{	/* Fourth byte table 35. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   4,   8,   12,  16,  20,  24,  28,
+			32,  36,  40,  44,  48,  52,  56,  60,
+			64,  68,  72,  76,  80,  84,  88,  92,
+			96,  100, 104, 108, 112, 116, 120, 124,
+			128, 132, 136, 140, 144, 148, 152, 156,
+			160, 160, 160, 160, 160, 160, 160, 160,
+			160, 160, 160, 160, 160, 160, 160, 160,
+			160, 160, 160, 160, 160, 160, 160, 160,
+			160, 160, 160, 160, 160, 160, 160, 160,
+			160, 160, 160, 160, 160, 160, 160, 160,
+			160, 160, 160, 160, 160, 160, 160, 160,
+			160, 160, 160, 160, 160, 160, 160, 160,
+			160, 160, 160, 160, 160, 160, 160, 160,
+			160, 160, 160, 160, 160, 160, 160, 160,
+			160, 160, 160, 160, 160, 160, 160, 160,
+			160, 160, 160, 160, 160, 160, 160, 160,
+			160,
+		},
+	},
+};
+
+static const uchar_t u8_tolower_final_tbl[2][2299] = {
+	{
+		0xC3, 0xA0, 0xC3, 0xA1, 0xC3, 0xA2, 0xC3, 0xA3,
+		0xC3, 0xA4, 0xC3, 0xA5, 0xC3, 0xA6, 0xC3, 0xA7,
+		0xC3, 0xA8, 0xC3, 0xA9, 0xC3, 0xAA, 0xC3, 0xAB,
+		0xC3, 0xAC, 0xC3, 0xAD, 0xC3, 0xAE, 0xC3, 0xAF,
+		0xC3, 0xB0, 0xC3, 0xB1, 0xC3, 0xB2, 0xC3, 0xB3,
+		0xC3, 0xB4, 0xC3, 0xB5, 0xC3, 0xB6, 0xC3, 0xB8,
+		0xC3, 0xB9, 0xC3, 0xBA, 0xC3, 0xBB, 0xC3, 0xBC,
+		0xC3, 0xBD, 0xC3, 0xBE, 0xC4, 0x81, 0xC4, 0x83,
+		0xC4, 0x85, 0xC4, 0x87, 0xC4, 0x89, 0xC4, 0x8B,
+		0xC4, 0x8D, 0xC4, 0x8F, 0xC4, 0x91, 0xC4, 0x93,
+		0xC4, 0x95, 0xC4, 0x97, 0xC4, 0x99, 0xC4, 0x9B,
+		0xC4, 0x9D, 0xC4, 0x9F, 0xC4, 0xA1, 0xC4, 0xA3,
+		0xC4, 0xA5, 0xC4, 0xA7, 0xC4, 0xA9, 0xC4, 0xAB,
+		0xC4, 0xAD, 0xC4, 0xAF, 0x69, 0xC4, 0xB3, 0xC4,
+		0xB5, 0xC4, 0xB7, 0xC4, 0xBA, 0xC4, 0xBC, 0xC4,
+		0xBE, 0xC5, 0x80, 0xC5, 0x82, 0xC5, 0x84, 0xC5,
+		0x86, 0xC5, 0x88, 0xC5, 0x8B, 0xC5, 0x8D, 0xC5,
+		0x8F, 0xC5, 0x91, 0xC5, 0x93, 0xC5, 0x95, 0xC5,
+		0x97, 0xC5, 0x99, 0xC5, 0x9B, 0xC5, 0x9D, 0xC5,
+		0x9F, 0xC5, 0xA1, 0xC5, 0xA3, 0xC5, 0xA5, 0xC5,
+		0xA7, 0xC5, 0xA9, 0xC5, 0xAB, 0xC5, 0xAD, 0xC5,
+		0xAF, 0xC5, 0xB1, 0xC5, 0xB3, 0xC5, 0xB5, 0xC5,
+		0xB7, 0xC3, 0xBF, 0xC5, 0xBA, 0xC5, 0xBC, 0xC5,
+		0xBE, 0xC9, 0x93, 0xC6, 0x83, 0xC6, 0x85, 0xC9,
+		0x94, 0xC6, 0x88, 0xC9, 0x96, 0xC9, 0x97, 0xC6,
+		0x8C, 0xC7, 0x9D, 0xC9, 0x99, 0xC9, 0x9B, 0xC6,
+		0x92, 0xC9, 0xA0, 0xC9, 0xA3, 0xC9, 0xA9, 0xC9,
+		0xA8, 0xC6, 0x99, 0xC9, 0xAF, 0xC9, 0xB2, 0xC9,
+		0xB5, 0xC6, 0xA1, 0xC6, 0xA3, 0xC6, 0xA5, 0xCA,
+		0x80, 0xC6, 0xA8, 0xCA, 0x83, 0xC6, 0xAD, 0xCA,
+		0x88, 0xC6, 0xB0, 0xCA, 0x8A, 0xCA, 0x8B, 0xC6,
+		0xB4, 0xC6, 0xB6, 0xCA, 0x92, 0xC6, 0xB9, 0xC6,
+		0xBD, 0xC7, 0x86, 0xC7, 0x86, 0xC7, 0x89, 0xC7,
+		0x89, 0xC7, 0x8C, 0xC7, 0x8C, 0xC7, 0x8E, 0xC7,
+		0x90, 0xC7, 0x92, 0xC7, 0x94, 0xC7, 0x96, 0xC7,
+		0x98, 0xC7, 0x9A, 0xC7, 0x9C, 0xC7, 0x9F, 0xC7,
+		0xA1, 0xC7, 0xA3, 0xC7, 0xA5, 0xC7, 0xA7, 0xC7,
+		0xA9, 0xC7, 0xAB, 0xC7, 0xAD, 0xC7, 0xAF, 0xC7,
+		0xB3, 0xC7, 0xB3, 0xC7, 0xB5, 0xC6, 0x95, 0xC6,
+		0xBF, 0xC7, 0xB9, 0xC7, 0xBB, 0xC7, 0xBD, 0xC7,
+		0xBF, 0xC8, 0x81, 0xC8, 0x83, 0xC8, 0x85, 0xC8,
+		0x87, 0xC8, 0x89, 0xC8, 0x8B, 0xC8, 0x8D, 0xC8,
+		0x8F, 0xC8, 0x91, 0xC8, 0x93, 0xC8, 0x95, 0xC8,
+		0x97, 0xC8, 0x99, 0xC8, 0x9B, 0xC8, 0x9D, 0xC8,
+		0x9F, 0xC6, 0x9E, 0xC8, 0xA3, 0xC8, 0xA5, 0xC8,
+		0xA7, 0xC8, 0xA9, 0xC8, 0xAB, 0xC8, 0xAD, 0xC8,
+		0xAF, 0xC8, 0xB1, 0xC8, 0xB3, 0xCE, 0xAC, 0xCE,
+		0xAD, 0xCE, 0xAE, 0xCE, 0xAF, 0xCF, 0x8C, 0xCF,
+		0x8D, 0xCF, 0x8E, 0xCE, 0xB1, 0xCE, 0xB2, 0xCE,
+		0xB3, 0xCE, 0xB4, 0xCE, 0xB5, 0xCE, 0xB6, 0xCE,
+		0xB7, 0xCE, 0xB8, 0xCE, 0xB9, 0xCE, 0xBA, 0xCE,
+		0xBB, 0xCE, 0xBC, 0xCE, 0xBD, 0xCE, 0xBE, 0xCE,
+		0xBF, 0xCF, 0x80, 0xCF, 0x81, 0xCF, 0x83, 0xCF,
+		0x84, 0xCF, 0x85, 0xCF, 0x86, 0xCF, 0x87, 0xCF,
+		0x88, 0xCF, 0x89, 0xCF, 0x8A, 0xCF, 0x8B, 0xCF,
+		0x99, 0xCF, 0x9B, 0xCF, 0x9D, 0xCF, 0x9F, 0xCF,
+		0xA1, 0xCF, 0xA3, 0xCF, 0xA5, 0xCF, 0xA7, 0xCF,
+		0xA9, 0xCF, 0xAB, 0xCF, 0xAD, 0xCF, 0xAF, 0xCE,
+		0xB8, 0xD1, 0x90, 0xD1, 0x91, 0xD1, 0x92, 0xD1,
+		0x93, 0xD1, 0x94, 0xD1, 0x95, 0xD1, 0x96, 0xD1,
+		0x97, 0xD1, 0x98, 0xD1, 0x99, 0xD1, 0x9A, 0xD1,
+		0x9B, 0xD1, 0x9C, 0xD1, 0x9D, 0xD1, 0x9E, 0xD1,
+		0x9F, 0xD0, 0xB0, 0xD0, 0xB1, 0xD0, 0xB2, 0xD0,
+		0xB3, 0xD0, 0xB4, 0xD0, 0xB5, 0xD0, 0xB6, 0xD0,
+		0xB7, 0xD0, 0xB8, 0xD0, 0xB9, 0xD0, 0xBA, 0xD0,
+		0xBB, 0xD0, 0xBC, 0xD0, 0xBD, 0xD0, 0xBE, 0xD0,
+		0xBF, 0xD1, 0x80, 0xD1, 0x81, 0xD1, 0x82, 0xD1,
+		0x83, 0xD1, 0x84, 0xD1, 0x85, 0xD1, 0x86, 0xD1,
+		0x87, 0xD1, 0x88, 0xD1, 0x89, 0xD1, 0x8A, 0xD1,
+		0x8B, 0xD1, 0x8C, 0xD1, 0x8D, 0xD1, 0x8E, 0xD1,
+		0x8F, 0xD1, 0xA1, 0xD1, 0xA3, 0xD1, 0xA5, 0xD1,
+		0xA7, 0xD1, 0xA9, 0xD1, 0xAB, 0xD1, 0xAD, 0xD1,
+		0xAF, 0xD1, 0xB1, 0xD1, 0xB3, 0xD1, 0xB5, 0xD1,
+		0xB7, 0xD1, 0xB9, 0xD1, 0xBB, 0xD1, 0xBD, 0xD1,
+		0xBF, 0xD2, 0x81, 0xD2, 0x8B, 0xD2, 0x8D, 0xD2,
+		0x8F, 0xD2, 0x91, 0xD2, 0x93, 0xD2, 0x95, 0xD2,
+		0x97, 0xD2, 0x99, 0xD2, 0x9B, 0xD2, 0x9D, 0xD2,
+		0x9F, 0xD2, 0xA1, 0xD2, 0xA3, 0xD2, 0xA5, 0xD2,
+		0xA7, 0xD2, 0xA9, 0xD2, 0xAB, 0xD2, 0xAD, 0xD2,
+		0xAF, 0xD2, 0xB1, 0xD2, 0xB3, 0xD2, 0xB5, 0xD2,
+		0xB7, 0xD2, 0xB9, 0xD2, 0xBB, 0xD2, 0xBD, 0xD2,
+		0xBF, 0xD3, 0x82, 0xD3, 0x84, 0xD3, 0x86, 0xD3,
+		0x88, 0xD3, 0x8A, 0xD3, 0x8C, 0xD3, 0x8E, 0xD3,
+		0x91, 0xD3, 0x93, 0xD3, 0x95, 0xD3, 0x97, 0xD3,
+		0x99, 0xD3, 0x9B, 0xD3, 0x9D, 0xD3, 0x9F, 0xD3,
+		0xA1, 0xD3, 0xA3, 0xD3, 0xA5, 0xD3, 0xA7, 0xD3,
+		0xA9, 0xD3, 0xAB, 0xD3, 0xAD, 0xD3, 0xAF, 0xD3,
+		0xB1, 0xD3, 0xB3, 0xD3, 0xB5, 0xD3, 0xB9, 0xD4,
+		0x81, 0xD4, 0x83, 0xD4, 0x85, 0xD4, 0x87, 0xD4,
+		0x89, 0xD4, 0x8B, 0xD4, 0x8D, 0xD4, 0x8F, 0xD5,
+		0xA1, 0xD5, 0xA2, 0xD5, 0xA3, 0xD5, 0xA4, 0xD5,
+		0xA5, 0xD5, 0xA6, 0xD5, 0xA7, 0xD5, 0xA8, 0xD5,
+		0xA9, 0xD5, 0xAA, 0xD5, 0xAB, 0xD5, 0xAC, 0xD5,
+		0xAD, 0xD5, 0xAE, 0xD5, 0xAF, 0xD5, 0xB0, 0xD5,
+		0xB1, 0xD5, 0xB2, 0xD5, 0xB3, 0xD5, 0xB4, 0xD5,
+		0xB5, 0xD5, 0xB6, 0xD5, 0xB7, 0xD5, 0xB8, 0xD5,
+		0xB9, 0xD5, 0xBA, 0xD5, 0xBB, 0xD5, 0xBC, 0xD5,
+		0xBD, 0xD5, 0xBE, 0xD5, 0xBF, 0xD6, 0x80, 0xD6,
+		0x81, 0xD6, 0x82, 0xD6, 0x83, 0xD6, 0x84, 0xD6,
+		0x85, 0xD6, 0x86, 0xE1, 0xB8, 0x81, 0xE1, 0xB8,
+		0x83, 0xE1, 0xB8, 0x85, 0xE1, 0xB8, 0x87, 0xE1,
+		0xB8, 0x89, 0xE1, 0xB8, 0x8B, 0xE1, 0xB8, 0x8D,
+		0xE1, 0xB8, 0x8F, 0xE1, 0xB8, 0x91, 0xE1, 0xB8,
+		0x93, 0xE1, 0xB8, 0x95, 0xE1, 0xB8, 0x97, 0xE1,
+		0xB8, 0x99, 0xE1, 0xB8, 0x9B, 0xE1, 0xB8, 0x9D,
+		0xE1, 0xB8, 0x9F, 0xE1, 0xB8, 0xA1, 0xE1, 0xB8,
+		0xA3, 0xE1, 0xB8, 0xA5, 0xE1, 0xB8, 0xA7, 0xE1,
+		0xB8, 0xA9, 0xE1, 0xB8, 0xAB, 0xE1, 0xB8, 0xAD,
+		0xE1, 0xB8, 0xAF, 0xE1, 0xB8, 0xB1, 0xE1, 0xB8,
+		0xB3, 0xE1, 0xB8, 0xB5, 0xE1, 0xB8, 0xB7, 0xE1,
+		0xB8, 0xB9, 0xE1, 0xB8, 0xBB, 0xE1, 0xB8, 0xBD,
+		0xE1, 0xB8, 0xBF, 0xE1, 0xB9, 0x81, 0xE1, 0xB9,
+		0x83, 0xE1, 0xB9, 0x85, 0xE1, 0xB9, 0x87, 0xE1,
+		0xB9, 0x89, 0xE1, 0xB9, 0x8B, 0xE1, 0xB9, 0x8D,
+		0xE1, 0xB9, 0x8F, 0xE1, 0xB9, 0x91, 0xE1, 0xB9,
+		0x93, 0xE1, 0xB9, 0x95, 0xE1, 0xB9, 0x97, 0xE1,
+		0xB9, 0x99, 0xE1, 0xB9, 0x9B, 0xE1, 0xB9, 0x9D,
+		0xE1, 0xB9, 0x9F, 0xE1, 0xB9, 0xA1, 0xE1, 0xB9,
+		0xA3, 0xE1, 0xB9, 0xA5, 0xE1, 0xB9, 0xA7, 0xE1,
+		0xB9, 0xA9, 0xE1, 0xB9, 0xAB, 0xE1, 0xB9, 0xAD,
+		0xE1, 0xB9, 0xAF, 0xE1, 0xB9, 0xB1, 0xE1, 0xB9,
+		0xB3, 0xE1, 0xB9, 0xB5, 0xE1, 0xB9, 0xB7, 0xE1,
+		0xB9, 0xB9, 0xE1, 0xB9, 0xBB, 0xE1, 0xB9, 0xBD,
+		0xE1, 0xB9, 0xBF, 0xE1, 0xBA, 0x81, 0xE1, 0xBA,
+		0x83, 0xE1, 0xBA, 0x85, 0xE1, 0xBA, 0x87, 0xE1,
+		0xBA, 0x89, 0xE1, 0xBA, 0x8B, 0xE1, 0xBA, 0x8D,
+		0xE1, 0xBA, 0x8F, 0xE1, 0xBA, 0x91, 0xE1, 0xBA,
+		0x93, 0xE1, 0xBA, 0x95, 0xE1, 0xBA, 0xA1, 0xE1,
+		0xBA, 0xA3, 0xE1, 0xBA, 0xA5, 0xE1, 0xBA, 0xA7,
+		0xE1, 0xBA, 0xA9, 0xE1, 0xBA, 0xAB, 0xE1, 0xBA,
+		0xAD, 0xE1, 0xBA, 0xAF, 0xE1, 0xBA, 0xB1, 0xE1,
+		0xBA, 0xB3, 0xE1, 0xBA, 0xB5, 0xE1, 0xBA, 0xB7,
+		0xE1, 0xBA, 0xB9, 0xE1, 0xBA, 0xBB, 0xE1, 0xBA,
+		0xBD, 0xE1, 0xBA, 0xBF, 0xE1, 0xBB, 0x81, 0xE1,
+		0xBB, 0x83, 0xE1, 0xBB, 0x85, 0xE1, 0xBB, 0x87,
+		0xE1, 0xBB, 0x89, 0xE1, 0xBB, 0x8B, 0xE1, 0xBB,
+		0x8D, 0xE1, 0xBB, 0x8F, 0xE1, 0xBB, 0x91, 0xE1,
+		0xBB, 0x93, 0xE1, 0xBB, 0x95, 0xE1, 0xBB, 0x97,
+		0xE1, 0xBB, 0x99, 0xE1, 0xBB, 0x9B, 0xE1, 0xBB,
+		0x9D, 0xE1, 0xBB, 0x9F, 0xE1, 0xBB, 0xA1, 0xE1,
+		0xBB, 0xA3, 0xE1, 0xBB, 0xA5, 0xE1, 0xBB, 0xA7,
+		0xE1, 0xBB, 0xA9, 0xE1, 0xBB, 0xAB, 0xE1, 0xBB,
+		0xAD, 0xE1, 0xBB, 0xAF, 0xE1, 0xBB, 0xB1, 0xE1,
+		0xBB, 0xB3, 0xE1, 0xBB, 0xB5, 0xE1, 0xBB, 0xB7,
+		0xE1, 0xBB, 0xB9, 0xE1, 0xBC, 0x80, 0xE1, 0xBC,
+		0x81, 0xE1, 0xBC, 0x82, 0xE1, 0xBC, 0x83, 0xE1,
+		0xBC, 0x84, 0xE1, 0xBC, 0x85, 0xE1, 0xBC, 0x86,
+		0xE1, 0xBC, 0x87, 0xE1, 0xBC, 0x90, 0xE1, 0xBC,
+		0x91, 0xE1, 0xBC, 0x92, 0xE1, 0xBC, 0x93, 0xE1,
+		0xBC, 0x94, 0xE1, 0xBC, 0x95, 0xE1, 0xBC, 0xA0,
+		0xE1, 0xBC, 0xA1, 0xE1, 0xBC, 0xA2, 0xE1, 0xBC,
+		0xA3, 0xE1, 0xBC, 0xA4, 0xE1, 0xBC, 0xA5, 0xE1,
+		0xBC, 0xA6, 0xE1, 0xBC, 0xA7, 0xE1, 0xBC, 0xB0,
+		0xE1, 0xBC, 0xB1, 0xE1, 0xBC, 0xB2, 0xE1, 0xBC,
+		0xB3, 0xE1, 0xBC, 0xB4, 0xE1, 0xBC, 0xB5, 0xE1,
+		0xBC, 0xB6, 0xE1, 0xBC, 0xB7, 0xE1, 0xBD, 0x80,
+		0xE1, 0xBD, 0x81, 0xE1, 0xBD, 0x82, 0xE1, 0xBD,
+		0x83, 0xE1, 0xBD, 0x84, 0xE1, 0xBD, 0x85, 0xE1,
+		0xBD, 0x91, 0xE1, 0xBD, 0x93, 0xE1, 0xBD, 0x95,
+		0xE1, 0xBD, 0x97, 0xE1, 0xBD, 0xA0, 0xE1, 0xBD,
+		0xA1, 0xE1, 0xBD, 0xA2, 0xE1, 0xBD, 0xA3, 0xE1,
+		0xBD, 0xA4, 0xE1, 0xBD, 0xA5, 0xE1, 0xBD, 0xA6,
+		0xE1, 0xBD, 0xA7, 0xE1, 0xBE, 0x80, 0xE1, 0xBE,
+		0x81, 0xE1, 0xBE, 0x82, 0xE1, 0xBE, 0x83, 0xE1,
+		0xBE, 0x84, 0xE1, 0xBE, 0x85, 0xE1, 0xBE, 0x86,
+		0xE1, 0xBE, 0x87, 0xE1, 0xBE, 0x90, 0xE1, 0xBE,
+		0x91, 0xE1, 0xBE, 0x92, 0xE1, 0xBE, 0x93, 0xE1,
+		0xBE, 0x94, 0xE1, 0xBE, 0x95, 0xE1, 0xBE, 0x96,
+		0xE1, 0xBE, 0x97, 0xE1, 0xBE, 0xA0, 0xE1, 0xBE,
+		0xA1, 0xE1, 0xBE, 0xA2, 0xE1, 0xBE, 0xA3, 0xE1,
+		0xBE, 0xA4, 0xE1, 0xBE, 0xA5, 0xE1, 0xBE, 0xA6,
+		0xE1, 0xBE, 0xA7, 0xE1, 0xBE, 0xB0, 0xE1, 0xBE,
+		0xB1, 0xE1, 0xBD, 0xB0, 0xE1, 0xBD, 0xB1, 0xE1,
+		0xBE, 0xB3, 0xE1, 0xBD, 0xB2, 0xE1, 0xBD, 0xB3,
+		0xE1, 0xBD, 0xB4, 0xE1, 0xBD, 0xB5, 0xE1, 0xBF,
+		0x83, 0xE1, 0xBF, 0x90, 0xE1, 0xBF, 0x91, 0xE1,
+		0xBD, 0xB6, 0xE1, 0xBD, 0xB7, 0xE1, 0xBF, 0xA0,
+		0xE1, 0xBF, 0xA1, 0xE1, 0xBD, 0xBA, 0xE1, 0xBD,
+		0xBB, 0xE1, 0xBF, 0xA5, 0xE1, 0xBD, 0xB8, 0xE1,
+		0xBD, 0xB9, 0xE1, 0xBD, 0xBC, 0xE1, 0xBD, 0xBD,
+		0xE1, 0xBF, 0xB3, 0xCF, 0x89, 0x6B, 0xC3, 0xA5,
+		0xE2, 0x85, 0xB0, 0xE2, 0x85, 0xB1, 0xE2, 0x85,
+		0xB2, 0xE2, 0x85, 0xB3, 0xE2, 0x85, 0xB4, 0xE2,
+		0x85, 0xB5, 0xE2, 0x85, 0xB6, 0xE2, 0x85, 0xB7,
+		0xE2, 0x85, 0xB8, 0xE2, 0x85, 0xB9, 0xE2, 0x85,
+		0xBA, 0xE2, 0x85, 0xBB, 0xE2, 0x85, 0xBC, 0xE2,
+		0x85, 0xBD, 0xE2, 0x85, 0xBE, 0xE2, 0x85, 0xBF,
+		0xE2, 0x93, 0x90, 0xE2, 0x93, 0x91, 0xE2, 0x93,
+		0x92, 0xE2, 0x93, 0x93, 0xE2, 0x93, 0x94, 0xE2,
+		0x93, 0x95, 0xE2, 0x93, 0x96, 0xE2, 0x93, 0x97,
+		0xE2, 0x93, 0x98, 0xE2, 0x93, 0x99, 0xE2, 0x93,
+		0x9A, 0xE2, 0x93, 0x9B, 0xE2, 0x93, 0x9C, 0xE2,
+		0x93, 0x9D, 0xE2, 0x93, 0x9E, 0xE2, 0x93, 0x9F,
+		0xE2, 0x93, 0xA0, 0xE2, 0x93, 0xA1, 0xE2, 0x93,
+		0xA2, 0xE2, 0x93, 0xA3, 0xE2, 0x93, 0xA4, 0xE2,
+		0x93, 0xA5, 0xE2, 0x93, 0xA6, 0xE2, 0x93, 0xA7,
+		0xE2, 0x93, 0xA8, 0xE2, 0x93, 0xA9, 0xEF, 0xBD,
+		0x81, 0xEF, 0xBD, 0x82, 0xEF, 0xBD, 0x83, 0xEF,
+		0xBD, 0x84, 0xEF, 0xBD, 0x85, 0xEF, 0xBD, 0x86,
+		0xEF, 0xBD, 0x87, 0xEF, 0xBD, 0x88, 0xEF, 0xBD,
+		0x89, 0xEF, 0xBD, 0x8A, 0xEF, 0xBD, 0x8B, 0xEF,
+		0xBD, 0x8C, 0xEF, 0xBD, 0x8D, 0xEF, 0xBD, 0x8E,
+		0xEF, 0xBD, 0x8F, 0xEF, 0xBD, 0x90, 0xEF, 0xBD,
+		0x91, 0xEF, 0xBD, 0x92, 0xEF, 0xBD, 0x93, 0xEF,
+		0xBD, 0x94, 0xEF, 0xBD, 0x95, 0xEF, 0xBD, 0x96,
+		0xEF, 0xBD, 0x97, 0xEF, 0xBD, 0x98, 0xEF, 0xBD,
+		0x99, 0xEF, 0xBD, 0x9A, 0xF0, 0x90, 0x90, 0xA8,
+		0xF0, 0x90, 0x90, 0xA9, 0xF0, 0x90, 0x90, 0xAA,
+		0xF0, 0x90, 0x90, 0xAB, 0xF0, 0x90, 0x90, 0xAC,
+		0xF0, 0x90, 0x90, 0xAD, 0xF0, 0x90, 0x90, 0xAE,
+		0xF0, 0x90, 0x90, 0xAF, 0xF0, 0x90, 0x90, 0xB0,
+		0xF0, 0x90, 0x90, 0xB1, 0xF0, 0x90, 0x90, 0xB2,
+		0xF0, 0x90, 0x90, 0xB3, 0xF0, 0x90, 0x90, 0xB4,
+		0xF0, 0x90, 0x90, 0xB5, 0xF0, 0x90, 0x90, 0xB6,
+		0xF0, 0x90, 0x90, 0xB7, 0xF0, 0x90, 0x90, 0xB8,
+		0xF0, 0x90, 0x90, 0xB9, 0xF0, 0x90, 0x90, 0xBA,
+		0xF0, 0x90, 0x90, 0xBB, 0xF0, 0x90, 0x90, 0xBC,
+		0xF0, 0x90, 0x90, 0xBD, 0xF0, 0x90, 0x90, 0xBE,
+		0xF0, 0x90, 0x90, 0xBF, 0xF0, 0x90, 0x91, 0x80,
+		0xF0, 0x90, 0x91, 0x81, 0xF0, 0x90, 0x91, 0x82,
+		0xF0, 0x90, 0x91, 0x83, 0xF0, 0x90, 0x91, 0x84,
+		0xF0, 0x90, 0x91, 0x85, 0xF0, 0x90, 0x91, 0x86,
+		0xF0, 0x90, 0x91, 0x87, 0xF0, 0x90, 0x91, 0x88,
+		0xF0, 0x90, 0x91, 0x89, 0xF0, 0x90, 0x91, 0x8A,
+		0xF0, 0x90, 0x91, 0x8B, 0xF0, 0x90, 0x91, 0x8C,
+		0xF0, 0x90, 0x91, 0x8D, 0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,
+	},
+	{
+		0xC3, 0xA0, 0xC3, 0xA1, 0xC3, 0xA2, 0xC3, 0xA3,
+		0xC3, 0xA4, 0xC3, 0xA5, 0xC3, 0xA6, 0xC3, 0xA7,
+		0xC3, 0xA8, 0xC3, 0xA9, 0xC3, 0xAA, 0xC3, 0xAB,
+		0xC3, 0xAC, 0xC3, 0xAD, 0xC3, 0xAE, 0xC3, 0xAF,
+		0xC3, 0xB0, 0xC3, 0xB1, 0xC3, 0xB2, 0xC3, 0xB3,
+		0xC3, 0xB4, 0xC3, 0xB5, 0xC3, 0xB6, 0xC3, 0xB8,
+		0xC3, 0xB9, 0xC3, 0xBA, 0xC3, 0xBB, 0xC3, 0xBC,
+		0xC3, 0xBD, 0xC3, 0xBE, 0xC4, 0x81, 0xC4, 0x83,
+		0xC4, 0x85, 0xC4, 0x87, 0xC4, 0x89, 0xC4, 0x8B,
+		0xC4, 0x8D, 0xC4, 0x8F, 0xC4, 0x91, 0xC4, 0x93,
+		0xC4, 0x95, 0xC4, 0x97, 0xC4, 0x99, 0xC4, 0x9B,
+		0xC4, 0x9D, 0xC4, 0x9F, 0xC4, 0xA1, 0xC4, 0xA3,
+		0xC4, 0xA5, 0xC4, 0xA7, 0xC4, 0xA9, 0xC4, 0xAB,
+		0xC4, 0xAD, 0xC4, 0xAF, 0x69, 0xC4, 0xB3, 0xC4,
+		0xB5, 0xC4, 0xB7, 0xC4, 0xBA, 0xC4, 0xBC, 0xC4,
+		0xBE, 0xC5, 0x80, 0xC5, 0x82, 0xC5, 0x84, 0xC5,
+		0x86, 0xC5, 0x88, 0xC5, 0x8B, 0xC5, 0x8D, 0xC5,
+		0x8F, 0xC5, 0x91, 0xC5, 0x93, 0xC5, 0x95, 0xC5,
+		0x97, 0xC5, 0x99, 0xC5, 0x9B, 0xC5, 0x9D, 0xC5,
+		0x9F, 0xC5, 0xA1, 0xC5, 0xA3, 0xC5, 0xA5, 0xC5,
+		0xA7, 0xC5, 0xA9, 0xC5, 0xAB, 0xC5, 0xAD, 0xC5,
+		0xAF, 0xC5, 0xB1, 0xC5, 0xB3, 0xC5, 0xB5, 0xC5,
+		0xB7, 0xC3, 0xBF, 0xC5, 0xBA, 0xC5, 0xBC, 0xC5,
+		0xBE, 0xC9, 0x93, 0xC6, 0x83, 0xC6, 0x85, 0xC9,
+		0x94, 0xC6, 0x88, 0xC9, 0x96, 0xC9, 0x97, 0xC6,
+		0x8C, 0xC7, 0x9D, 0xC9, 0x99, 0xC9, 0x9B, 0xC6,
+		0x92, 0xC9, 0xA0, 0xC9, 0xA3, 0xC9, 0xA9, 0xC9,
+		0xA8, 0xC6, 0x99, 0xC9, 0xAF, 0xC9, 0xB2, 0xC9,
+		0xB5, 0xC6, 0xA1, 0xC6, 0xA3, 0xC6, 0xA5, 0xCA,
+		0x80, 0xC6, 0xA8, 0xCA, 0x83, 0xC6, 0xAD, 0xCA,
+		0x88, 0xC6, 0xB0, 0xCA, 0x8A, 0xCA, 0x8B, 0xC6,
+		0xB4, 0xC6, 0xB6, 0xCA, 0x92, 0xC6, 0xB9, 0xC6,
+		0xBD, 0xC7, 0x86, 0xC7, 0x86, 0xC7, 0x89, 0xC7,
+		0x89, 0xC7, 0x8C, 0xC7, 0x8C, 0xC7, 0x8E, 0xC7,
+		0x90, 0xC7, 0x92, 0xC7, 0x94, 0xC7, 0x96, 0xC7,
+		0x98, 0xC7, 0x9A, 0xC7, 0x9C, 0xC7, 0x9F, 0xC7,
+		0xA1, 0xC7, 0xA3, 0xC7, 0xA5, 0xC7, 0xA7, 0xC7,
+		0xA9, 0xC7, 0xAB, 0xC7, 0xAD, 0xC7, 0xAF, 0xC7,
+		0xB3, 0xC7, 0xB3, 0xC7, 0xB5, 0xC6, 0x95, 0xC6,
+		0xBF, 0xC7, 0xB9, 0xC7, 0xBB, 0xC7, 0xBD, 0xC7,
+		0xBF, 0xC8, 0x81, 0xC8, 0x83, 0xC8, 0x85, 0xC8,
+		0x87, 0xC8, 0x89, 0xC8, 0x8B, 0xC8, 0x8D, 0xC8,
+		0x8F, 0xC8, 0x91, 0xC8, 0x93, 0xC8, 0x95, 0xC8,
+		0x97, 0xC8, 0x99, 0xC8, 0x9B, 0xC8, 0x9D, 0xC8,
+		0x9F, 0xC6, 0x9E, 0xC8, 0xA3, 0xC8, 0xA5, 0xC8,
+		0xA7, 0xC8, 0xA9, 0xC8, 0xAB, 0xC8, 0xAD, 0xC8,
+		0xAF, 0xC8, 0xB1, 0xC8, 0xB3, 0xE2, 0xB1, 0xA5,
+		0xC8, 0xBC, 0xC6, 0x9A, 0xE2, 0xB1, 0xA6, 0xC9,
+		0x82, 0xC6, 0x80, 0xCA, 0x89, 0xCA, 0x8C, 0xC9,
+		0x87, 0xC9, 0x89, 0xC9, 0x8B, 0xC9, 0x8D, 0xC9,
+		0x8F, 0xCE, 0xAC, 0xCE, 0xAD, 0xCE, 0xAE, 0xCE,
+		0xAF, 0xCF, 0x8C, 0xCF, 0x8D, 0xCF, 0x8E, 0xCE,
+		0xB1, 0xCE, 0xB2, 0xCE, 0xB3, 0xCE, 0xB4, 0xCE,
+		0xB5, 0xCE, 0xB6, 0xCE, 0xB7, 0xCE, 0xB8, 0xCE,
+		0xB9, 0xCE, 0xBA, 0xCE, 0xBB, 0xCE, 0xBC, 0xCE,
+		0xBD, 0xCE, 0xBE, 0xCE, 0xBF, 0xCF, 0x80, 0xCF,
+		0x81, 0xCF, 0x83, 0xCF, 0x84, 0xCF, 0x85, 0xCF,
+		0x86, 0xCF, 0x87, 0xCF, 0x88, 0xCF, 0x89, 0xCF,
+		0x8A, 0xCF, 0x8B, 0xCF, 0x99, 0xCF, 0x9B, 0xCF,
+		0x9D, 0xCF, 0x9F, 0xCF, 0xA1, 0xCF, 0xA3, 0xCF,
+		0xA5, 0xCF, 0xA7, 0xCF, 0xA9, 0xCF, 0xAB, 0xCF,
+		0xAD, 0xCF, 0xAF, 0xCE, 0xB8, 0xCF, 0xB8, 0xCF,
+		0xB2, 0xCF, 0xBB, 0xCD, 0xBB, 0xCD, 0xBC, 0xCD,
+		0xBD, 0xD1, 0x90, 0xD1, 0x91, 0xD1, 0x92, 0xD1,
+		0x93, 0xD1, 0x94, 0xD1, 0x95, 0xD1, 0x96, 0xD1,
+		0x97, 0xD1, 0x98, 0xD1, 0x99, 0xD1, 0x9A, 0xD1,
+		0x9B, 0xD1, 0x9C, 0xD1, 0x9D, 0xD1, 0x9E, 0xD1,
+		0x9F, 0xD0, 0xB0, 0xD0, 0xB1, 0xD0, 0xB2, 0xD0,
+		0xB3, 0xD0, 0xB4, 0xD0, 0xB5, 0xD0, 0xB6, 0xD0,
+		0xB7, 0xD0, 0xB8, 0xD0, 0xB9, 0xD0, 0xBA, 0xD0,
+		0xBB, 0xD0, 0xBC, 0xD0, 0xBD, 0xD0, 0xBE, 0xD0,
+		0xBF, 0xD1, 0x80, 0xD1, 0x81, 0xD1, 0x82, 0xD1,
+		0x83, 0xD1, 0x84, 0xD1, 0x85, 0xD1, 0x86, 0xD1,
+		0x87, 0xD1, 0x88, 0xD1, 0x89, 0xD1, 0x8A, 0xD1,
+		0x8B, 0xD1, 0x8C, 0xD1, 0x8D, 0xD1, 0x8E, 0xD1,
+		0x8F, 0xD1, 0xA1, 0xD1, 0xA3, 0xD1, 0xA5, 0xD1,
+		0xA7, 0xD1, 0xA9, 0xD1, 0xAB, 0xD1, 0xAD, 0xD1,
+		0xAF, 0xD1, 0xB1, 0xD1, 0xB3, 0xD1, 0xB5, 0xD1,
+		0xB7, 0xD1, 0xB9, 0xD1, 0xBB, 0xD1, 0xBD, 0xD1,
+		0xBF, 0xD2, 0x81, 0xD2, 0x8B, 0xD2, 0x8D, 0xD2,
+		0x8F, 0xD2, 0x91, 0xD2, 0x93, 0xD2, 0x95, 0xD2,
+		0x97, 0xD2, 0x99, 0xD2, 0x9B, 0xD2, 0x9D, 0xD2,
+		0x9F, 0xD2, 0xA1, 0xD2, 0xA3, 0xD2, 0xA5, 0xD2,
+		0xA7, 0xD2, 0xA9, 0xD2, 0xAB, 0xD2, 0xAD, 0xD2,
+		0xAF, 0xD2, 0xB1, 0xD2, 0xB3, 0xD2, 0xB5, 0xD2,
+		0xB7, 0xD2, 0xB9, 0xD2, 0xBB, 0xD2, 0xBD, 0xD2,
+		0xBF, 0xD3, 0x8F, 0xD3, 0x82, 0xD3, 0x84, 0xD3,
+		0x86, 0xD3, 0x88, 0xD3, 0x8A, 0xD3, 0x8C, 0xD3,
+		0x8E, 0xD3, 0x91, 0xD3, 0x93, 0xD3, 0x95, 0xD3,
+		0x97, 0xD3, 0x99, 0xD3, 0x9B, 0xD3, 0x9D, 0xD3,
+		0x9F, 0xD3, 0xA1, 0xD3, 0xA3, 0xD3, 0xA5, 0xD3,
+		0xA7, 0xD3, 0xA9, 0xD3, 0xAB, 0xD3, 0xAD, 0xD3,
+		0xAF, 0xD3, 0xB1, 0xD3, 0xB3, 0xD3, 0xB5, 0xD3,
+		0xB7, 0xD3, 0xB9, 0xD3, 0xBB, 0xD3, 0xBD, 0xD3,
+		0xBF, 0xD4, 0x81, 0xD4, 0x83, 0xD4, 0x85, 0xD4,
+		0x87, 0xD4, 0x89, 0xD4, 0x8B, 0xD4, 0x8D, 0xD4,
+		0x8F, 0xD4, 0x91, 0xD4, 0x93, 0xD5, 0xA1, 0xD5,
+		0xA2, 0xD5, 0xA3, 0xD5, 0xA4, 0xD5, 0xA5, 0xD5,
+		0xA6, 0xD5, 0xA7, 0xD5, 0xA8, 0xD5, 0xA9, 0xD5,
+		0xAA, 0xD5, 0xAB, 0xD5, 0xAC, 0xD5, 0xAD, 0xD5,
+		0xAE, 0xD5, 0xAF, 0xD5, 0xB0, 0xD5, 0xB1, 0xD5,
+		0xB2, 0xD5, 0xB3, 0xD5, 0xB4, 0xD5, 0xB5, 0xD5,
+		0xB6, 0xD5, 0xB7, 0xD5, 0xB8, 0xD5, 0xB9, 0xD5,
+		0xBA, 0xD5, 0xBB, 0xD5, 0xBC, 0xD5, 0xBD, 0xD5,
+		0xBE, 0xD5, 0xBF, 0xD6, 0x80, 0xD6, 0x81, 0xD6,
+		0x82, 0xD6, 0x83, 0xD6, 0x84, 0xD6, 0x85, 0xD6,
+		0x86, 0xE2, 0xB4, 0x80, 0xE2, 0xB4, 0x81, 0xE2,
+		0xB4, 0x82, 0xE2, 0xB4, 0x83, 0xE2, 0xB4, 0x84,
+		0xE2, 0xB4, 0x85, 0xE2, 0xB4, 0x86, 0xE2, 0xB4,
+		0x87, 0xE2, 0xB4, 0x88, 0xE2, 0xB4, 0x89, 0xE2,
+		0xB4, 0x8A, 0xE2, 0xB4, 0x8B, 0xE2, 0xB4, 0x8C,
+		0xE2, 0xB4, 0x8D, 0xE2, 0xB4, 0x8E, 0xE2, 0xB4,
+		0x8F, 0xE2, 0xB4, 0x90, 0xE2, 0xB4, 0x91, 0xE2,
+		0xB4, 0x92, 0xE2, 0xB4, 0x93, 0xE2, 0xB4, 0x94,
+		0xE2, 0xB4, 0x95, 0xE2, 0xB4, 0x96, 0xE2, 0xB4,
+		0x97, 0xE2, 0xB4, 0x98, 0xE2, 0xB4, 0x99, 0xE2,
+		0xB4, 0x9A, 0xE2, 0xB4, 0x9B, 0xE2, 0xB4, 0x9C,
+		0xE2, 0xB4, 0x9D, 0xE2, 0xB4, 0x9E, 0xE2, 0xB4,
+		0x9F, 0xE2, 0xB4, 0xA0, 0xE2, 0xB4, 0xA1, 0xE2,
+		0xB4, 0xA2, 0xE2, 0xB4, 0xA3, 0xE2, 0xB4, 0xA4,
+		0xE2, 0xB4, 0xA5, 0xE1, 0xB8, 0x81, 0xE1, 0xB8,
+		0x83, 0xE1, 0xB8, 0x85, 0xE1, 0xB8, 0x87, 0xE1,
+		0xB8, 0x89, 0xE1, 0xB8, 0x8B, 0xE1, 0xB8, 0x8D,
+		0xE1, 0xB8, 0x8F, 0xE1, 0xB8, 0x91, 0xE1, 0xB8,
+		0x93, 0xE1, 0xB8, 0x95, 0xE1, 0xB8, 0x97, 0xE1,
+		0xB8, 0x99, 0xE1, 0xB8, 0x9B, 0xE1, 0xB8, 0x9D,
+		0xE1, 0xB8, 0x9F, 0xE1, 0xB8, 0xA1, 0xE1, 0xB8,
+		0xA3, 0xE1, 0xB8, 0xA5, 0xE1, 0xB8, 0xA7, 0xE1,
+		0xB8, 0xA9, 0xE1, 0xB8, 0xAB, 0xE1, 0xB8, 0xAD,
+		0xE1, 0xB8, 0xAF, 0xE1, 0xB8, 0xB1, 0xE1, 0xB8,
+		0xB3, 0xE1, 0xB8, 0xB5, 0xE1, 0xB8, 0xB7, 0xE1,
+		0xB8, 0xB9, 0xE1, 0xB8, 0xBB, 0xE1, 0xB8, 0xBD,
+		0xE1, 0xB8, 0xBF, 0xE1, 0xB9, 0x81, 0xE1, 0xB9,
+		0x83, 0xE1, 0xB9, 0x85, 0xE1, 0xB9, 0x87, 0xE1,
+		0xB9, 0x89, 0xE1, 0xB9, 0x8B, 0xE1, 0xB9, 0x8D,
+		0xE1, 0xB9, 0x8F, 0xE1, 0xB9, 0x91, 0xE1, 0xB9,
+		0x93, 0xE1, 0xB9, 0x95, 0xE1, 0xB9, 0x97, 0xE1,
+		0xB9, 0x99, 0xE1, 0xB9, 0x9B, 0xE1, 0xB9, 0x9D,
+		0xE1, 0xB9, 0x9F, 0xE1, 0xB9, 0xA1, 0xE1, 0xB9,
+		0xA3, 0xE1, 0xB9, 0xA5, 0xE1, 0xB9, 0xA7, 0xE1,
+		0xB9, 0xA9, 0xE1, 0xB9, 0xAB, 0xE1, 0xB9, 0xAD,
+		0xE1, 0xB9, 0xAF, 0xE1, 0xB9, 0xB1, 0xE1, 0xB9,
+		0xB3, 0xE1, 0xB9, 0xB5, 0xE1, 0xB9, 0xB7, 0xE1,
+		0xB9, 0xB9, 0xE1, 0xB9, 0xBB, 0xE1, 0xB9, 0xBD,
+		0xE1, 0xB9, 0xBF, 0xE1, 0xBA, 0x81, 0xE1, 0xBA,
+		0x83, 0xE1, 0xBA, 0x85, 0xE1, 0xBA, 0x87, 0xE1,
+		0xBA, 0x89, 0xE1, 0xBA, 0x8B, 0xE1, 0xBA, 0x8D,
+		0xE1, 0xBA, 0x8F, 0xE1, 0xBA, 0x91, 0xE1, 0xBA,
+		0x93, 0xE1, 0xBA, 0x95, 0xE1, 0xBA, 0xA1, 0xE1,
+		0xBA, 0xA3, 0xE1, 0xBA, 0xA5, 0xE1, 0xBA, 0xA7,
+		0xE1, 0xBA, 0xA9, 0xE1, 0xBA, 0xAB, 0xE1, 0xBA,
+		0xAD, 0xE1, 0xBA, 0xAF, 0xE1, 0xBA, 0xB1, 0xE1,
+		0xBA, 0xB3, 0xE1, 0xBA, 0xB5, 0xE1, 0xBA, 0xB7,
+		0xE1, 0xBA, 0xB9, 0xE1, 0xBA, 0xBB, 0xE1, 0xBA,
+		0xBD, 0xE1, 0xBA, 0xBF, 0xE1, 0xBB, 0x81, 0xE1,
+		0xBB, 0x83, 0xE1, 0xBB, 0x85, 0xE1, 0xBB, 0x87,
+		0xE1, 0xBB, 0x89, 0xE1, 0xBB, 0x8B, 0xE1, 0xBB,
+		0x8D, 0xE1, 0xBB, 0x8F, 0xE1, 0xBB, 0x91, 0xE1,
+		0xBB, 0x93, 0xE1, 0xBB, 0x95, 0xE1, 0xBB, 0x97,
+		0xE1, 0xBB, 0x99, 0xE1, 0xBB, 0x9B, 0xE1, 0xBB,
+		0x9D, 0xE1, 0xBB, 0x9F, 0xE1, 0xBB, 0xA1, 0xE1,
+		0xBB, 0xA3, 0xE1, 0xBB, 0xA5, 0xE1, 0xBB, 0xA7,
+		0xE1, 0xBB, 0xA9, 0xE1, 0xBB, 0xAB, 0xE1, 0xBB,
+		0xAD, 0xE1, 0xBB, 0xAF, 0xE1, 0xBB, 0xB1, 0xE1,
+		0xBB, 0xB3, 0xE1, 0xBB, 0xB5, 0xE1, 0xBB, 0xB7,
+		0xE1, 0xBB, 0xB9, 0xE1, 0xBC, 0x80, 0xE1, 0xBC,
+		0x81, 0xE1, 0xBC, 0x82, 0xE1, 0xBC, 0x83, 0xE1,
+		0xBC, 0x84, 0xE1, 0xBC, 0x85, 0xE1, 0xBC, 0x86,
+		0xE1, 0xBC, 0x87, 0xE1, 0xBC, 0x90, 0xE1, 0xBC,
+		0x91, 0xE1, 0xBC, 0x92, 0xE1, 0xBC, 0x93, 0xE1,
+		0xBC, 0x94, 0xE1, 0xBC, 0x95, 0xE1, 0xBC, 0xA0,
+		0xE1, 0xBC, 0xA1, 0xE1, 0xBC, 0xA2, 0xE1, 0xBC,
+		0xA3, 0xE1, 0xBC, 0xA4, 0xE1, 0xBC, 0xA5, 0xE1,
+		0xBC, 0xA6, 0xE1, 0xBC, 0xA7, 0xE1, 0xBC, 0xB0,
+		0xE1, 0xBC, 0xB1, 0xE1, 0xBC, 0xB2, 0xE1, 0xBC,
+		0xB3, 0xE1, 0xBC, 0xB4, 0xE1, 0xBC, 0xB5, 0xE1,
+		0xBC, 0xB6, 0xE1, 0xBC, 0xB7, 0xE1, 0xBD, 0x80,
+		0xE1, 0xBD, 0x81, 0xE1, 0xBD, 0x82, 0xE1, 0xBD,
+		0x83, 0xE1, 0xBD, 0x84, 0xE1, 0xBD, 0x85, 0xE1,
+		0xBD, 0x91, 0xE1, 0xBD, 0x93, 0xE1, 0xBD, 0x95,
+		0xE1, 0xBD, 0x97, 0xE1, 0xBD, 0xA0, 0xE1, 0xBD,
+		0xA1, 0xE1, 0xBD, 0xA2, 0xE1, 0xBD, 0xA3, 0xE1,
+		0xBD, 0xA4, 0xE1, 0xBD, 0xA5, 0xE1, 0xBD, 0xA6,
+		0xE1, 0xBD, 0xA7, 0xE1, 0xBE, 0x80, 0xE1, 0xBE,
+		0x81, 0xE1, 0xBE, 0x82, 0xE1, 0xBE, 0x83, 0xE1,
+		0xBE, 0x84, 0xE1, 0xBE, 0x85, 0xE1, 0xBE, 0x86,
+		0xE1, 0xBE, 0x87, 0xE1, 0xBE, 0x90, 0xE1, 0xBE,
+		0x91, 0xE1, 0xBE, 0x92, 0xE1, 0xBE, 0x93, 0xE1,
+		0xBE, 0x94, 0xE1, 0xBE, 0x95, 0xE1, 0xBE, 0x96,
+		0xE1, 0xBE, 0x97, 0xE1, 0xBE, 0xA0, 0xE1, 0xBE,
+		0xA1, 0xE1, 0xBE, 0xA2, 0xE1, 0xBE, 0xA3, 0xE1,
+		0xBE, 0xA4, 0xE1, 0xBE, 0xA5, 0xE1, 0xBE, 0xA6,
+		0xE1, 0xBE, 0xA7, 0xE1, 0xBE, 0xB0, 0xE1, 0xBE,
+		0xB1, 0xE1, 0xBD, 0xB0, 0xE1, 0xBD, 0xB1, 0xE1,
+		0xBE, 0xB3, 0xE1, 0xBD, 0xB2, 0xE1, 0xBD, 0xB3,
+		0xE1, 0xBD, 0xB4, 0xE1, 0xBD, 0xB5, 0xE1, 0xBF,
+		0x83, 0xE1, 0xBF, 0x90, 0xE1, 0xBF, 0x91, 0xE1,
+		0xBD, 0xB6, 0xE1, 0xBD, 0xB7, 0xE1, 0xBF, 0xA0,
+		0xE1, 0xBF, 0xA1, 0xE1, 0xBD, 0xBA, 0xE1, 0xBD,
+		0xBB, 0xE1, 0xBF, 0xA5, 0xE1, 0xBD, 0xB8, 0xE1,
+		0xBD, 0xB9, 0xE1, 0xBD, 0xBC, 0xE1, 0xBD, 0xBD,
+		0xE1, 0xBF, 0xB3, 0xCF, 0x89, 0x6B, 0xC3, 0xA5,
+		0xE2, 0x85, 0x8E, 0xE2, 0x85, 0xB0, 0xE2, 0x85,
+		0xB1, 0xE2, 0x85, 0xB2, 0xE2, 0x85, 0xB3, 0xE2,
+		0x85, 0xB4, 0xE2, 0x85, 0xB5, 0xE2, 0x85, 0xB6,
+		0xE2, 0x85, 0xB7, 0xE2, 0x85, 0xB8, 0xE2, 0x85,
+		0xB9, 0xE2, 0x85, 0xBA, 0xE2, 0x85, 0xBB, 0xE2,
+		0x85, 0xBC, 0xE2, 0x85, 0xBD, 0xE2, 0x85, 0xBE,
+		0xE2, 0x85, 0xBF, 0xE2, 0x86, 0x84, 0xE2, 0x93,
+		0x90, 0xE2, 0x93, 0x91, 0xE2, 0x93, 0x92, 0xE2,
+		0x93, 0x93, 0xE2, 0x93, 0x94, 0xE2, 0x93, 0x95,
+		0xE2, 0x93, 0x96, 0xE2, 0x93, 0x97, 0xE2, 0x93,
+		0x98, 0xE2, 0x93, 0x99, 0xE2, 0x93, 0x9A, 0xE2,
+		0x93, 0x9B, 0xE2, 0x93, 0x9C, 0xE2, 0x93, 0x9D,
+		0xE2, 0x93, 0x9E, 0xE2, 0x93, 0x9F, 0xE2, 0x93,
+		0xA0, 0xE2, 0x93, 0xA1, 0xE2, 0x93, 0xA2, 0xE2,
+		0x93, 0xA3, 0xE2, 0x93, 0xA4, 0xE2, 0x93, 0xA5,
+		0xE2, 0x93, 0xA6, 0xE2, 0x93, 0xA7, 0xE2, 0x93,
+		0xA8, 0xE2, 0x93, 0xA9, 0xE2, 0xB0, 0xB0, 0xE2,
+		0xB0, 0xB1, 0xE2, 0xB0, 0xB2, 0xE2, 0xB0, 0xB3,
+		0xE2, 0xB0, 0xB4, 0xE2, 0xB0, 0xB5, 0xE2, 0xB0,
+		0xB6, 0xE2, 0xB0, 0xB7, 0xE2, 0xB0, 0xB8, 0xE2,
+		0xB0, 0xB9, 0xE2, 0xB0, 0xBA, 0xE2, 0xB0, 0xBB,
+		0xE2, 0xB0, 0xBC, 0xE2, 0xB0, 0xBD, 0xE2, 0xB0,
+		0xBE, 0xE2, 0xB0, 0xBF, 0xE2, 0xB1, 0x80, 0xE2,
+		0xB1, 0x81, 0xE2, 0xB1, 0x82, 0xE2, 0xB1, 0x83,
+		0xE2, 0xB1, 0x84, 0xE2, 0xB1, 0x85, 0xE2, 0xB1,
+		0x86, 0xE2, 0xB1, 0x87, 0xE2, 0xB1, 0x88, 0xE2,
+		0xB1, 0x89, 0xE2, 0xB1, 0x8A, 0xE2, 0xB1, 0x8B,
+		0xE2, 0xB1, 0x8C, 0xE2, 0xB1, 0x8D, 0xE2, 0xB1,
+		0x8E, 0xE2, 0xB1, 0x8F, 0xE2, 0xB1, 0x90, 0xE2,
+		0xB1, 0x91, 0xE2, 0xB1, 0x92, 0xE2, 0xB1, 0x93,
+		0xE2, 0xB1, 0x94, 0xE2, 0xB1, 0x95, 0xE2, 0xB1,
+		0x96, 0xE2, 0xB1, 0x97, 0xE2, 0xB1, 0x98, 0xE2,
+		0xB1, 0x99, 0xE2, 0xB1, 0x9A, 0xE2, 0xB1, 0x9B,
+		0xE2, 0xB1, 0x9C, 0xE2, 0xB1, 0x9D, 0xE2, 0xB1,
+		0x9E, 0xE2, 0xB1, 0xA1, 0xC9, 0xAB, 0xE1, 0xB5,
+		0xBD, 0xC9, 0xBD, 0xE2, 0xB1, 0xA8, 0xE2, 0xB1,
+		0xAA, 0xE2, 0xB1, 0xAC, 0xE2, 0xB1, 0xB6, 0xE2,
+		0xB2, 0x81, 0xE2, 0xB2, 0x83, 0xE2, 0xB2, 0x85,
+		0xE2, 0xB2, 0x87, 0xE2, 0xB2, 0x89, 0xE2, 0xB2,
+		0x8B, 0xE2, 0xB2, 0x8D, 0xE2, 0xB2, 0x8F, 0xE2,
+		0xB2, 0x91, 0xE2, 0xB2, 0x93, 0xE2, 0xB2, 0x95,
+		0xE2, 0xB2, 0x97, 0xE2, 0xB2, 0x99, 0xE2, 0xB2,
+		0x9B, 0xE2, 0xB2, 0x9D, 0xE2, 0xB2, 0x9F, 0xE2,
+		0xB2, 0xA1, 0xE2, 0xB2, 0xA3, 0xE2, 0xB2, 0xA5,
+		0xE2, 0xB2, 0xA7, 0xE2, 0xB2, 0xA9, 0xE2, 0xB2,
+		0xAB, 0xE2, 0xB2, 0xAD, 0xE2, 0xB2, 0xAF, 0xE2,
+		0xB2, 0xB1, 0xE2, 0xB2, 0xB3, 0xE2, 0xB2, 0xB5,
+		0xE2, 0xB2, 0xB7, 0xE2, 0xB2, 0xB9, 0xE2, 0xB2,
+		0xBB, 0xE2, 0xB2, 0xBD, 0xE2, 0xB2, 0xBF, 0xE2,
+		0xB3, 0x81, 0xE2, 0xB3, 0x83, 0xE2, 0xB3, 0x85,
+		0xE2, 0xB3, 0x87, 0xE2, 0xB3, 0x89, 0xE2, 0xB3,
+		0x8B, 0xE2, 0xB3, 0x8D, 0xE2, 0xB3, 0x8F, 0xE2,
+		0xB3, 0x91, 0xE2, 0xB3, 0x93, 0xE2, 0xB3, 0x95,
+		0xE2, 0xB3, 0x97, 0xE2, 0xB3, 0x99, 0xE2, 0xB3,
+		0x9B, 0xE2, 0xB3, 0x9D, 0xE2, 0xB3, 0x9F, 0xE2,
+		0xB3, 0xA1, 0xE2, 0xB3, 0xA3, 0xEF, 0xBD, 0x81,
+		0xEF, 0xBD, 0x82, 0xEF, 0xBD, 0x83, 0xEF, 0xBD,
+		0x84, 0xEF, 0xBD, 0x85, 0xEF, 0xBD, 0x86, 0xEF,
+		0xBD, 0x87, 0xEF, 0xBD, 0x88, 0xEF, 0xBD, 0x89,
+		0xEF, 0xBD, 0x8A, 0xEF, 0xBD, 0x8B, 0xEF, 0xBD,
+		0x8C, 0xEF, 0xBD, 0x8D, 0xEF, 0xBD, 0x8E, 0xEF,
+		0xBD, 0x8F, 0xEF, 0xBD, 0x90, 0xEF, 0xBD, 0x91,
+		0xEF, 0xBD, 0x92, 0xEF, 0xBD, 0x93, 0xEF, 0xBD,
+		0x94, 0xEF, 0xBD, 0x95, 0xEF, 0xBD, 0x96, 0xEF,
+		0xBD, 0x97, 0xEF, 0xBD, 0x98, 0xEF, 0xBD, 0x99,
+		0xEF, 0xBD, 0x9A, 0xF0, 0x90, 0x90, 0xA8, 0xF0,
+		0x90, 0x90, 0xA9, 0xF0, 0x90, 0x90, 0xAA, 0xF0,
+		0x90, 0x90, 0xAB, 0xF0, 0x90, 0x90, 0xAC, 0xF0,
+		0x90, 0x90, 0xAD, 0xF0, 0x90, 0x90, 0xAE, 0xF0,
+		0x90, 0x90, 0xAF, 0xF0, 0x90, 0x90, 0xB0, 0xF0,
+		0x90, 0x90, 0xB1, 0xF0, 0x90, 0x90, 0xB2, 0xF0,
+		0x90, 0x90, 0xB3, 0xF0, 0x90, 0x90, 0xB4, 0xF0,
+		0x90, 0x90, 0xB5, 0xF0, 0x90, 0x90, 0xB6, 0xF0,
+		0x90, 0x90, 0xB7, 0xF0, 0x90, 0x90, 0xB8, 0xF0,
+		0x90, 0x90, 0xB9, 0xF0, 0x90, 0x90, 0xBA, 0xF0,
+		0x90, 0x90, 0xBB, 0xF0, 0x90, 0x90, 0xBC, 0xF0,
+		0x90, 0x90, 0xBD, 0xF0, 0x90, 0x90, 0xBE, 0xF0,
+		0x90, 0x90, 0xBF, 0xF0, 0x90, 0x91, 0x80, 0xF0,
+		0x90, 0x91, 0x81, 0xF0, 0x90, 0x91, 0x82, 0xF0,
+		0x90, 0x91, 0x83, 0xF0, 0x90, 0x91, 0x84, 0xF0,
+		0x90, 0x91, 0x85, 0xF0, 0x90, 0x91, 0x86, 0xF0,
+		0x90, 0x91, 0x87, 0xF0, 0x90, 0x91, 0x88, 0xF0,
+		0x90, 0x91, 0x89, 0xF0, 0x90, 0x91, 0x8A, 0xF0,
+		0x90, 0x91, 0x8B, 0xF0, 0x90, 0x91, 0x8C, 0xF0,
+		0x90, 0x91, 0x8D, 0xF0, 0x90, 0x91, 0x8E, 0xF0,
+		0x90, 0x91, 0x8F,
+	},
+};
+
+static const u8_displacement_t u8_toupper_b3_tbl[2][5][256] = {
+	{
+		{	/* Third byte table 0. */
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { 0, 0 }, { 1, 2 },
+			{ 2, 64 }, { 3, 125 }, { 4, 188 }, { 5, 226 },
+			{ 6, 288 }, { 7, 338 }, { 8, 364 }, { N_, 0 },
+			{ N_, 0 }, { 9, 376 }, { 10, 378 }, { 11, 416 },
+			{ 12, 486 }, { 13, 518 }, { 14, 614 }, { 15, 670 },
+			{ 16, 724 }, { 17, 740 }, { 18, 802 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+		},
+		{	/* Third byte table 1. */
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ 19, 816 }, { 20, 912 }, { 21, 1008 }, { 22, 1092 },
+			{ 23, 1179 }, { 24, 1269 }, { 25, 1365 }, { 26, 1448 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+		},
+		{	/* Third byte table 2. */
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { 27, 1469 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { 28, 1517 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+		},
+		{	/* Third byte table 3. */
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { 29, 1595 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+		},
+		{	/* Third byte table 4. */
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ 30, 1673 }, { 31, 1769 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+		},
+	},
+	{
+		{	/* Third byte table 0. */
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { 0, 0 }, { 1, 2 },
+			{ 2, 64 }, { 3, 125 }, { 4, 188 }, { 5, 230 },
+			{ 6, 292 }, { 7, 344 }, { 8, 388 }, { N_, 0 },
+			{ N_, 0 }, { 9, 404 }, { 10, 412 }, { 11, 450 },
+			{ 12, 524 }, { 13, 556 }, { 14, 652 }, { 15, 708 },
+			{ 16, 772 }, { 17, 792 }, { 18, 854 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+		},
+		{	/* Third byte table 1. */
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { 19, 868 }, { N_, 0 }, { N_, 0 },
+			{ 20, 871 }, { 21, 967 }, { 22, 1063 }, { 23, 1147 },
+			{ 24, 1234 }, { 25, 1324 }, { 26, 1420 }, { 27, 1503 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+		},
+		{	/* Third byte table 2. */
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { 28, 1524 }, { 29, 1575 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { 30, 1578 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ 31, 1656 }, { 32, 1704 }, { 33, 1816 }, { 34, 1912 },
+			{ 35, 1966 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+		},
+		{	/* Third byte table 3. */
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { 36, 2080 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+		},
+		{	/* Third byte table 4. */
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ 37, 2158 }, { 38, 2254 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+			{ N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 },
+		},
+	},
+};
+
+static const uchar_t u8_toupper_b4_tbl[2][39][257] = {
+	{
+		{	/* Fourth byte table 0. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   2,   2,
+			2,   2,   2,   2,   2,   2,   2,   2,
+			2,   2,   2,   2,   2,   2,   2,   2,
+			2,   2,   2,   2,   2,   2,   2,   2,
+			2,   2,   2,   2,   2,   2,   2,   2,
+			2,   2,   2,   2,   2,   2,   2,   2,
+			2,   2,   2,   2,   2,   2,   2,   2,
+			2,   2,   2,   2,   2,   2,   2,   2,
+			2,   2,   2,   2,   2,   2,   2,   2,
+			2,   2,   2,   2,   2,   2,   2,   2,
+			2,
+		},
+		{	/* Fourth byte table 1. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   2,   4,   6,   8,   10,  12,  14,
+			16,  18,  20,  22,  24,  26,  28,  30,
+			32,  34,  36,  38,  40,  42,  44,  46,
+			46,  48,  50,  52,  54,  56,  58,  60,
+			62,  62,  62,  62,  62,  62,  62,  62,
+			62,  62,  62,  62,  62,  62,  62,  62,
+			62,  62,  62,  62,  62,  62,  62,  62,
+			62,  62,  62,  62,  62,  62,  62,  62,
+			62,  62,  62,  62,  62,  62,  62,  62,
+			62,  62,  62,  62,  62,  62,  62,  62,
+			62,  62,  62,  62,  62,  62,  62,  62,
+			62,  62,  62,  62,  62,  62,  62,  62,
+			62,
+		},
+		{	/* Fourth byte table 2. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   2,   2,   4,   4,   6,   6,
+			8,   8,   10,  10,  12,  12,  14,  14,
+			16,  16,  18,  18,  20,  20,  22,  22,
+			24,  24,  26,  26,  28,  28,  30,  30,
+			32,  32,  34,  34,  36,  36,  38,  38,
+			40,  40,  42,  42,  44,  44,  46,  46,
+			48,  48,  49,  49,  51,  51,  53,  53,
+			55,  55,  55,  57,  57,  59,  59,  61,
+			61,  61,  61,  61,  61,  61,  61,  61,
+			61,  61,  61,  61,  61,  61,  61,  61,
+			61,  61,  61,  61,  61,  61,  61,  61,
+			61,  61,  61,  61,  61,  61,  61,  61,
+			61,  61,  61,  61,  61,  61,  61,  61,
+			61,  61,  61,  61,  61,  61,  61,  61,
+			61,  61,  61,  61,  61,  61,  61,  61,
+			61,  61,  61,  61,  61,  61,  61,  61,
+			61,
+		},
+		{	/* Fourth byte table 3. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   2,   2,   4,   4,   6,   6,   8,
+			8,   10,  10,  10,  12,  12,  14,  14,
+			16,  16,  18,  18,  20,  20,  22,  22,
+			24,  24,  26,  26,  28,  28,  30,  30,
+			32,  32,  34,  34,  36,  36,  38,  38,
+			40,  40,  42,  42,  44,  44,  46,  46,
+			48,  48,  50,  50,  52,  52,  54,  54,
+			56,  56,  56,  58,  58,  60,  60,  62,
+			63,  63,  63,  63,  63,  63,  63,  63,
+			63,  63,  63,  63,  63,  63,  63,  63,
+			63,  63,  63,  63,  63,  63,  63,  63,
+			63,  63,  63,  63,  63,  63,  63,  63,
+			63,  63,  63,  63,  63,  63,  63,  63,
+			63,  63,  63,  63,  63,  63,  63,  63,
+			63,  63,  63,  63,  63,  63,  63,  63,
+			63,  63,  63,  63,  63,  63,  63,  63,
+			63,
+		},
+		{	/* Fourth byte table 4. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   2,   2,   4,   4,
+			4,   6,   6,   6,   6,   8,   8,   8,
+			8,   8,   8,   10,  10,  10,  12,  12,
+			12,  12,  14,  14,  14,  14,  14,  16,
+			16,  16,  18,  18,  20,  20,  22,  22,
+			22,  24,  24,  24,  24,  24,  26,  26,
+			26,  28,  28,  28,  28,  30,  30,  32,
+			32,  32,  34,  34,  34,  34,  36,  36,
+			38,  38,  38,  38,  38,  38,  38,  38,
+			38,  38,  38,  38,  38,  38,  38,  38,
+			38,  38,  38,  38,  38,  38,  38,  38,
+			38,  38,  38,  38,  38,  38,  38,  38,
+			38,  38,  38,  38,  38,  38,  38,  38,
+			38,  38,  38,  38,  38,  38,  38,  38,
+			38,  38,  38,  38,  38,  38,  38,  38,
+			38,  38,  38,  38,  38,  38,  38,  38,
+			38,
+		},
+		{	/* Fourth byte table 5. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   2,   4,
+			4,   6,   8,   8,   10,  12,  12,  14,
+			14,  16,  16,  18,  18,  20,  20,  22,
+			22,  24,  24,  26,  26,  28,  30,  30,
+			32,  32,  34,  34,  36,  36,  38,  38,
+			40,  40,  42,  42,  44,  44,  46,  46,
+			48,  48,  48,  50,  52,  52,  54,  54,
+			54,  54,  56,  56,  58,  58,  60,  60,
+			62,  62,  62,  62,  62,  62,  62,  62,
+			62,  62,  62,  62,  62,  62,  62,  62,
+			62,  62,  62,  62,  62,  62,  62,  62,
+			62,  62,  62,  62,  62,  62,  62,  62,
+			62,  62,  62,  62,  62,  62,  62,  62,
+			62,  62,  62,  62,  62,  62,  62,  62,
+			62,  62,  62,  62,  62,  62,  62,  62,
+			62,  62,  62,  62,  62,  62,  62,  62,
+			62,
+		},
+		{	/* Fourth byte table 6. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   2,   2,   4,   4,   6,   6,
+			8,   8,   10,  10,  12,  12,  14,  14,
+			16,  16,  18,  18,  20,  20,  22,  22,
+			24,  24,  26,  26,  28,  28,  30,  30,
+			32,  32,  32,  32,  34,  34,  36,  36,
+			38,  38,  40,  40,  42,  42,  44,  44,
+			46,  46,  48,  48,  50,  50,  50,  50,
+			50,  50,  50,  50,  50,  50,  50,  50,
+			50,  50,  50,  50,  50,  50,  50,  50,
+			50,  50,  50,  50,  50,  50,  50,  50,
+			50,  50,  50,  50,  50,  50,  50,  50,
+			50,  50,  50,  50,  50,  50,  50,  50,
+			50,  50,  50,  50,  50,  50,  50,  50,
+			50,  50,  50,  50,  50,  50,  50,  50,
+			50,  50,  50,  50,  50,  50,  50,  50,
+			50,  50,  50,  50,  50,  50,  50,  50,
+			50,
+		},
+		{	/* Fourth byte table 7. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   2,   4,   4,   6,
+			8,   8,   10,  10,  12,  12,  12,  12,
+			12,  14,  14,  14,  16,  16,  16,  16,
+			16,  18,  20,  20,  20,  20,  20,  20,
+			22,  22,  22,  24,  24,  24,  26,  26,
+			26,  26,  26,  26,  26,  26,  26,  26,
+			26,  26,  26,  26,  26,  26,  26,  26,
+			26,  26,  26,  26,  26,  26,  26,  26,
+			26,  26,  26,  26,  26,  26,  26,  26,
+			26,  26,  26,  26,  26,  26,  26,  26,
+			26,  26,  26,  26,  26,  26,  26,  26,
+			26,  26,  26,  26,  26,  26,  26,  26,
+			26,  26,  26,  26,  26,  26,  26,  26,
+			26,  26,  26,  26,  26,  26,  26,  26,
+			26,
+		},
+		{	/* Fourth byte table 8. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   2,   2,   2,   4,   4,   4,   4,
+			4,   6,   6,   8,   10,  10,  10,  10,
+			10,  10,  10,  12,  12,  12,  12,  12,
+			12,  12,  12,  12,  12,  12,  12,  12,
+			12,  12,  12,  12,  12,  12,  12,  12,
+			12,  12,  12,  12,  12,  12,  12,  12,
+			12,  12,  12,  12,  12,  12,  12,  12,
+			12,  12,  12,  12,  12,  12,  12,  12,
+			12,  12,  12,  12,  12,  12,  12,  12,
+			12,  12,  12,  12,  12,  12,  12,  12,
+			12,  12,  12,  12,  12,  12,  12,  12,
+			12,  12,  12,  12,  12,  12,  12,  12,
+			12,  12,  12,  12,  12,  12,  12,  12,
+			12,  12,  12,  12,  12,  12,  12,  12,
+			12,  12,  12,  12,  12,  12,  12,  12,
+			12,  12,  12,  12,  12,  12,  12,  12,
+			12,
+		},
+		{	/* Fourth byte table 9. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   2,   2,
+			2,   2,   2,   2,   2,   2,   2,   2,
+			2,   2,   2,   2,   2,   2,   2,   2,
+			2,   2,   2,   2,   2,   2,   2,   2,
+			2,   2,   2,   2,   2,   2,   2,   2,
+			2,   2,   2,   2,   2,   2,   2,   2,
+			2,   2,   2,   2,   2,   2,   2,   2,
+			2,   2,   2,   2,   2,   2,   2,   2,
+			2,   2,   2,   2,   2,   2,   2,   2,
+			2,   2,   2,   2,   2,   2,   2,   2,
+			2,   2,   2,   2,   2,   2,   2,   2,
+			2,   2,   2,   2,   2,   2,   2,   2,
+			2,   2,   2,   2,   2,   2,   2,   2,
+			2,   2,   2,   2,   2,   2,   2,   2,
+			2,   2,   2,   2,   2,   2,   2,   2,
+			2,   2,   2,   2,   2,   2,   2,   2,
+			2,
+		},
+		{	/* Fourth byte table 10. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   2,   4,   6,
+			8,   8,   10,  12,  14,  16,  18,  20,
+			22,  24,  26,  28,  30,  32,  34,  36,
+			38,  38,  38,  38,  38,  38,  38,  38,
+			38,  38,  38,  38,  38,  38,  38,  38,
+			38,  38,  38,  38,  38,  38,  38,  38,
+			38,  38,  38,  38,  38,  38,  38,  38,
+			38,  38,  38,  38,  38,  38,  38,  38,
+			38,  38,  38,  38,  38,  38,  38,  38,
+			38,  38,  38,  38,  38,  38,  38,  38,
+			38,  38,  38,  38,  38,  38,  38,  38,
+			38,
+		},
+		{	/* Fourth byte table 11. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   2,   4,   6,   8,   10,  12,  14,
+			16,  18,  20,  22,  24,  26,  28,  30,
+			30,  32,  34,  34,  34,  34,  36,  38,
+			38,  38,  40,  40,  42,  42,  44,  44,
+			46,  46,  48,  48,  50,  50,  52,  52,
+			54,  54,  56,  56,  58,  58,  60,  60,
+			62,  64,  66,  68,  68,  68,  70,  70,
+			70,  70,  70,  70,  70,  70,  70,  70,
+			70,  70,  70,  70,  70,  70,  70,  70,
+			70,  70,  70,  70,  70,  70,  70,  70,
+			70,  70,  70,  70,  70,  70,  70,  70,
+			70,  70,  70,  70,  70,  70,  70,  70,
+			70,  70,  70,  70,  70,  70,  70,  70,
+			70,  70,  70,  70,  70,  70,  70,  70,
+			70,  70,  70,  70,  70,  70,  70,  70,
+			70,  70,  70,  70,  70,  70,  70,  70,
+			70,
+		},
+		{	/* Fourth byte table 12. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   2,   4,   6,   8,   10,  12,  14,
+			16,  18,  20,  22,  24,  26,  28,  30,
+			32,  32,  32,  32,  32,  32,  32,  32,
+			32,  32,  32,  32,  32,  32,  32,  32,
+			32,  32,  32,  32,  32,  32,  32,  32,
+			32,  32,  32,  32,  32,  32,  32,  32,
+			32,  32,  32,  32,  32,  32,  32,  32,
+			32,  32,  32,  32,  32,  32,  32,  32,
+			32,  32,  32,  32,  32,  32,  32,  32,
+			32,  32,  32,  32,  32,  32,  32,  32,
+			32,
+		},
+		{	/* Fourth byte table 13. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   2,   4,   6,   8,   10,  12,  14,
+			16,  18,  20,  22,  24,  26,  28,  30,
+			32,  34,  36,  38,  40,  42,  44,  46,
+			48,  50,  52,  54,  56,  58,  60,  62,
+			64,  64,  66,  66,  68,  68,  70,  70,
+			72,  72,  74,  74,  76,  76,  78,  78,
+			80,  80,  82,  82,  84,  84,  86,  86,
+			88,  88,  90,  90,  92,  92,  94,  94,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,
+		},
+		{	/* Fourth byte table 14. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   2,   2,   2,   2,   2,   2,
+			2,   2,   2,   2,   4,   4,   6,   6,
+			8,   8,   10,  10,  12,  12,  14,  14,
+			16,  16,  18,  18,  20,  20,  22,  22,
+			24,  24,  26,  26,  28,  28,  30,  30,
+			32,  32,  34,  34,  36,  36,  38,  38,
+			40,  40,  42,  42,  44,  44,  46,  46,
+			48,  48,  50,  50,  52,  52,  54,  54,
+			56,  56,  56,  56,  56,  56,  56,  56,
+			56,  56,  56,  56,  56,  56,  56,  56,
+			56,  56,  56,  56,  56,  56,  56,  56,
+			56,  56,  56,  56,  56,  56,  56,  56,
+			56,  56,  56,  56,  56,  56,  56,  56,
+			56,  56,  56,  56,  56,  56,  56,  56,
+			56,  56,  56,  56,  56,  56,  56,  56,
+			56,  56,  56,  56,  56,  56,  56,  56,
+			56,
+		},
+		{	/* Fourth byte table 15. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   2,   2,   4,   4,   6,
+			6,   8,   8,   10,  10,  12,  12,  14,
+			14,  14,  16,  16,  18,  18,  20,  20,
+			22,  22,  24,  24,  26,  26,  28,  28,
+			30,  30,  32,  32,  34,  34,  36,  36,
+			38,  38,  40,  40,  42,  42,  44,  44,
+			46,  46,  48,  48,  50,  50,  52,  52,
+			52,  52,  54,  54,  54,  54,  54,  54,
+			54,  54,  54,  54,  54,  54,  54,  54,
+			54,  54,  54,  54,  54,  54,  54,  54,
+			54,  54,  54,  54,  54,  54,  54,  54,
+			54,  54,  54,  54,  54,  54,  54,  54,
+			54,  54,  54,  54,  54,  54,  54,  54,
+			54,  54,  54,  54,  54,  54,  54,  54,
+			54,  54,  54,  54,  54,  54,  54,  54,
+			54,  54,  54,  54,  54,  54,  54,  54,
+			54,
+		},
+		{	/* Fourth byte table 16. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   2,   2,   4,   4,   6,   6,
+			8,   8,   10,  10,  12,  12,  14,  14,
+			16,  16,  16,  16,  16,  16,  16,  16,
+			16,  16,  16,  16,  16,  16,  16,  16,
+			16,  16,  16,  16,  16,  16,  16,  16,
+			16,  16,  16,  16,  16,  16,  16,  16,
+			16,  16,  16,  16,  16,  16,  16,  16,
+			16,  16,  16,  16,  16,  16,  16,  16,
+			16,  16,  16,  16,  16,  16,  16,  16,
+			16,  16,  16,  16,  16,  16,  16,  16,
+			16,  16,  16,  16,  16,  16,  16,  16,
+			16,  16,  16,  16,  16,  16,  16,  16,
+			16,  16,  16,  16,  16,  16,  16,  16,
+			16,  16,  16,  16,  16,  16,  16,  16,
+			16,  16,  16,  16,  16,  16,  16,  16,
+			16,  16,  16,  16,  16,  16,  16,  16,
+			16,
+		},
+		{	/* Fourth byte table 17. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   2,   4,   6,   8,   10,  12,
+			14,  16,  18,  20,  22,  24,  26,  28,
+			30,  32,  34,  36,  38,  40,  42,  44,
+			46,  48,  50,  52,  54,  56,  58,  60,
+			62,  62,  62,  62,  62,  62,  62,  62,
+			62,  62,  62,  62,  62,  62,  62,  62,
+			62,  62,  62,  62,  62,  62,  62,  62,
+			62,  62,  62,  62,  62,  62,  62,  62,
+			62,  62,  62,  62,  62,  62,  62,  62,
+			62,  62,  62,  62,  62,  62,  62,  62,
+			62,  62,  62,  62,  62,  62,  62,  62,
+			62,  62,  62,  62,  62,  62,  62,  62,
+			62,
+		},
+		{	/* Fourth byte table 18. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   2,   4,   6,   8,   10,  12,  14,
+			14,  14,  14,  14,  14,  14,  14,  14,
+			14,  14,  14,  14,  14,  14,  14,  14,
+			14,  14,  14,  14,  14,  14,  14,  14,
+			14,  14,  14,  14,  14,  14,  14,  14,
+			14,  14,  14,  14,  14,  14,  14,  14,
+			14,  14,  14,  14,  14,  14,  14,  14,
+			14,  14,  14,  14,  14,  14,  14,  14,
+			14,  14,  14,  14,  14,  14,  14,  14,
+			14,  14,  14,  14,  14,  14,  14,  14,
+			14,  14,  14,  14,  14,  14,  14,  14,
+			14,  14,  14,  14,  14,  14,  14,  14,
+			14,  14,  14,  14,  14,  14,  14,  14,
+			14,  14,  14,  14,  14,  14,  14,  14,
+			14,  14,  14,  14,  14,  14,  14,  14,
+			14,  14,  14,  14,  14,  14,  14,  14,
+			14,
+		},
+		{	/* Fourth byte table 19. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   3,   3,   6,   6,   9,   9,
+			12,  12,  15,  15,  18,  18,  21,  21,
+			24,  24,  27,  27,  30,  30,  33,  33,
+			36,  36,  39,  39,  42,  42,  45,  45,
+			48,  48,  51,  51,  54,  54,  57,  57,
+			60,  60,  63,  63,  66,  66,  69,  69,
+			72,  72,  75,  75,  78,  78,  81,  81,
+			84,  84,  87,  87,  90,  90,  93,  93,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,
+		},
+		{	/* Fourth byte table 20. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   3,   3,   6,   6,   9,   9,
+			12,  12,  15,  15,  18,  18,  21,  21,
+			24,  24,  27,  27,  30,  30,  33,  33,
+			36,  36,  39,  39,  42,  42,  45,  45,
+			48,  48,  51,  51,  54,  54,  57,  57,
+			60,  60,  63,  63,  66,  66,  69,  69,
+			72,  72,  75,  75,  78,  78,  81,  81,
+			84,  84,  87,  87,  90,  90,  93,  93,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,
+		},
+		{	/* Fourth byte table 21. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   3,   3,   6,   6,   9,   9,
+			12,  12,  15,  15,  18,  18,  21,  21,
+			24,  24,  27,  27,  30,  30,  33,  33,
+			33,  33,  33,  33,  36,  36,  36,  36,
+			36,  36,  39,  39,  42,  42,  45,  45,
+			48,  48,  51,  51,  54,  54,  57,  57,
+			60,  60,  63,  63,  66,  66,  69,  69,
+			72,  72,  75,  75,  78,  78,  81,  81,
+			84,  84,  84,  84,  84,  84,  84,  84,
+			84,  84,  84,  84,  84,  84,  84,  84,
+			84,  84,  84,  84,  84,  84,  84,  84,
+			84,  84,  84,  84,  84,  84,  84,  84,
+			84,  84,  84,  84,  84,  84,  84,  84,
+			84,  84,  84,  84,  84,  84,  84,  84,
+			84,  84,  84,  84,  84,  84,  84,  84,
+			84,  84,  84,  84,  84,  84,  84,  84,
+			84,
+		},
+		{	/* Fourth byte table 22. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   3,   3,   6,   6,   9,   9,
+			12,  12,  15,  15,  18,  18,  21,  21,
+			24,  24,  27,  27,  30,  30,  33,  33,
+			36,  36,  39,  39,  42,  42,  45,  45,
+			48,  48,  51,  51,  54,  54,  57,  57,
+			60,  60,  63,  63,  66,  66,  69,  69,
+			72,  72,  75,  75,  78,  78,  81,  81,
+			84,  84,  87,  87,  87,  87,  87,  87,
+			87,  87,  87,  87,  87,  87,  87,  87,
+			87,  87,  87,  87,  87,  87,  87,  87,
+			87,  87,  87,  87,  87,  87,  87,  87,
+			87,  87,  87,  87,  87,  87,  87,  87,
+			87,  87,  87,  87,  87,  87,  87,  87,
+			87,  87,  87,  87,  87,  87,  87,  87,
+			87,  87,  87,  87,  87,  87,  87,  87,
+			87,  87,  87,  87,  87,  87,  87,  87,
+			87,
+		},
+		{	/* Fourth byte table 23. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   3,   6,   9,   12,  15,  18,  21,
+			24,  24,  24,  24,  24,  24,  24,  24,
+			24,  27,  30,  33,  36,  39,  42,  42,
+			42,  42,  42,  42,  42,  42,  42,  42,
+			42,  45,  48,  51,  54,  57,  60,  63,
+			66,  66,  66,  66,  66,  66,  66,  66,
+			66,  69,  72,  75,  78,  81,  84,  87,
+			90,  90,  90,  90,  90,  90,  90,  90,
+			90,  90,  90,  90,  90,  90,  90,  90,
+			90,  90,  90,  90,  90,  90,  90,  90,
+			90,  90,  90,  90,  90,  90,  90,  90,
+			90,  90,  90,  90,  90,  90,  90,  90,
+			90,  90,  90,  90,  90,  90,  90,  90,
+			90,  90,  90,  90,  90,  90,  90,  90,
+			90,  90,  90,  90,  90,  90,  90,  90,
+			90,  90,  90,  90,  90,  90,  90,  90,
+			90,
+		},
+		{	/* Fourth byte table 24. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   3,   6,   9,   12,  15,  18,  18,
+			18,  18,  18,  18,  18,  18,  18,  18,
+			18,  18,  21,  21,  24,  24,  27,  27,
+			30,  30,  30,  30,  30,  30,  30,  30,
+			30,  33,  36,  39,  42,  45,  48,  51,
+			54,  54,  54,  54,  54,  54,  54,  54,
+			54,  57,  60,  63,  66,  69,  72,  75,
+			78,  81,  84,  87,  90,  93,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,
+		},
+		{	/* Fourth byte table 25. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   3,   6,   9,   12,  15,  18,  21,
+			24,  24,  24,  24,  24,  24,  24,  24,
+			24,  27,  30,  33,  36,  39,  42,  45,
+			48,  48,  48,  48,  48,  48,  48,  48,
+			48,  51,  54,  57,  60,  63,  66,  69,
+			72,  72,  72,  72,  72,  72,  72,  72,
+			72,  75,  78,  78,  81,  81,  81,  81,
+			81,  81,  81,  81,  81,  81,  81,  83,
+			83,  83,  83,  83,  83,  83,  83,  83,
+			83,  83,  83,  83,  83,  83,  83,  83,
+			83,  83,  83,  83,  83,  83,  83,  83,
+			83,  83,  83,  83,  83,  83,  83,  83,
+			83,  83,  83,  83,  83,  83,  83,  83,
+			83,  83,  83,  83,  83,  83,  83,  83,
+			83,  83,  83,  83,  83,  83,  83,  83,
+			83,  83,  83,  83,  83,  83,  83,  83,
+			83,
+		},
+		{	/* Fourth byte table 26. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   3,   3,   3,   3,
+			3,   3,   3,   3,   3,   3,   3,   3,
+			3,   6,   9,   9,   9,   9,   9,   9,
+			9,   9,   9,   9,   9,   9,   9,   9,
+			9,   12,  15,  15,  15,  15,  18,  18,
+			18,  18,  18,  18,  18,  18,  18,  18,
+			18,  18,  18,  18,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,
+		},
+		{	/* Fourth byte table 27. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   3,   6,   9,   12,  15,  18,  21,
+			24,  27,  30,  33,  36,  39,  42,  45,
+			48,  48,  48,  48,  48,  48,  48,  48,
+			48,  48,  48,  48,  48,  48,  48,  48,
+			48,  48,  48,  48,  48,  48,  48,  48,
+			48,  48,  48,  48,  48,  48,  48,  48,
+			48,  48,  48,  48,  48,  48,  48,  48,
+			48,  48,  48,  48,  48,  48,  48,  48,
+			48,  48,  48,  48,  48,  48,  48,  48,
+			48,  48,  48,  48,  48,  48,  48,  48,
+			48,
+		},
+		{	/* Fourth byte table 28. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   3,   6,   9,   12,  15,  18,  21,
+			24,  27,  30,  33,  36,  39,  42,  45,
+			48,  51,  54,  57,  60,  63,  66,  69,
+			72,  75,  78,  78,  78,  78,  78,  78,
+			78,  78,  78,  78,  78,  78,  78,  78,
+			78,  78,  78,  78,  78,  78,  78,  78,
+			78,  78,  78,  78,  78,  78,  78,  78,
+			78,  78,  78,  78,  78,  78,  78,  78,
+			78,  78,  78,  78,  78,  78,  78,  78,
+			78,  78,  78,  78,  78,  78,  78,  78,
+			78,  78,  78,  78,  78,  78,  78,  78,
+			78,  78,  78,  78,  78,  78,  78,  78,
+			78,  78,  78,  78,  78,  78,  78,  78,
+			78,  78,  78,  78,  78,  78,  78,  78,
+			78,
+		},
+		{	/* Fourth byte table 29. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   3,   6,   9,   12,  15,  18,
+			21,  24,  27,  30,  33,  36,  39,  42,
+			45,  48,  51,  54,  57,  60,  63,  66,
+			69,  72,  75,  78,  78,  78,  78,  78,
+			78,  78,  78,  78,  78,  78,  78,  78,
+			78,  78,  78,  78,  78,  78,  78,  78,
+			78,  78,  78,  78,  78,  78,  78,  78,
+			78,  78,  78,  78,  78,  78,  78,  78,
+			78,  78,  78,  78,  78,  78,  78,  78,
+			78,  78,  78,  78,  78,  78,  78,  78,
+			78,  78,  78,  78,  78,  78,  78,  78,
+			78,  78,  78,  78,  78,  78,  78,  78,
+			78,  78,  78,  78,  78,  78,  78,  78,
+			78,  78,  78,  78,  78,  78,  78,  78,
+			78,  78,  78,  78,  78,  78,  78,  78,
+			78,  78,  78,  78,  78,  78,  78,  78,
+			78,
+		},
+		{	/* Fourth byte table 30. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   4,   8,   12,  16,  20,  24,  28,
+			32,  36,  40,  44,  48,  52,  56,  60,
+			64,  68,  72,  76,  80,  84,  88,  92,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,
+		},
+		{	/* Fourth byte table 31. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   4,   8,   12,  16,  20,  24,  28,
+			32,  36,  40,  44,  48,  52,  56,  56,
+			56,  56,  56,  56,  56,  56,  56,  56,
+			56,  56,  56,  56,  56,  56,  56,  56,
+			56,  56,  56,  56,  56,  56,  56,  56,
+			56,  56,  56,  56,  56,  56,  56,  56,
+			56,  56,  56,  56,  56,  56,  56,  56,
+			56,  56,  56,  56,  56,  56,  56,  56,
+			56,  56,  56,  56,  56,  56,  56,  56,
+			56,  56,  56,  56,  56,  56,  56,  56,
+			56,  56,  56,  56,  56,  56,  56,  56,
+			56,  56,  56,  56,  56,  56,  56,  56,
+			56,  56,  56,  56,  56,  56,  56,  56,
+			56,  56,  56,  56,  56,  56,  56,  56,
+			56,  56,  56,  56,  56,  56,  56,  56,
+			56,  56,  56,  56,  56,  56,  56,  56,
+			56,
+		},
+		{	/* Fourth byte table 32. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,
+		},
+		{	/* Fourth byte table 33. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,
+		},
+		{	/* Fourth byte table 34. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,
+		},
+		{	/* Fourth byte table 35. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,
+		},
+		{	/* Fourth byte table 36. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,
+		},
+		{	/* Fourth byte table 37. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,
+		},
+		{	/* Fourth byte table 38. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,
+		},
+	},
+	{
+		{	/* Fourth byte table 0. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   2,   2,
+			2,   2,   2,   2,   2,   2,   2,   2,
+			2,   2,   2,   2,   2,   2,   2,   2,
+			2,   2,   2,   2,   2,   2,   2,   2,
+			2,   2,   2,   2,   2,   2,   2,   2,
+			2,   2,   2,   2,   2,   2,   2,   2,
+			2,   2,   2,   2,   2,   2,   2,   2,
+			2,   2,   2,   2,   2,   2,   2,   2,
+			2,   2,   2,   2,   2,   2,   2,   2,
+			2,   2,   2,   2,   2,   2,   2,   2,
+			2,
+		},
+		{	/* Fourth byte table 1. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   2,   4,   6,   8,   10,  12,  14,
+			16,  18,  20,  22,  24,  26,  28,  30,
+			32,  34,  36,  38,  40,  42,  44,  46,
+			46,  48,  50,  52,  54,  56,  58,  60,
+			62,  62,  62,  62,  62,  62,  62,  62,
+			62,  62,  62,  62,  62,  62,  62,  62,
+			62,  62,  62,  62,  62,  62,  62,  62,
+			62,  62,  62,  62,  62,  62,  62,  62,
+			62,  62,  62,  62,  62,  62,  62,  62,
+			62,  62,  62,  62,  62,  62,  62,  62,
+			62,  62,  62,  62,  62,  62,  62,  62,
+			62,  62,  62,  62,  62,  62,  62,  62,
+			62,
+		},
+		{	/* Fourth byte table 2. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   2,   2,   4,   4,   6,   6,
+			8,   8,   10,  10,  12,  12,  14,  14,
+			16,  16,  18,  18,  20,  20,  22,  22,
+			24,  24,  26,  26,  28,  28,  30,  30,
+			32,  32,  34,  34,  36,  36,  38,  38,
+			40,  40,  42,  42,  44,  44,  46,  46,
+			48,  48,  49,  49,  51,  51,  53,  53,
+			55,  55,  55,  57,  57,  59,  59,  61,
+			61,  61,  61,  61,  61,  61,  61,  61,
+			61,  61,  61,  61,  61,  61,  61,  61,
+			61,  61,  61,  61,  61,  61,  61,  61,
+			61,  61,  61,  61,  61,  61,  61,  61,
+			61,  61,  61,  61,  61,  61,  61,  61,
+			61,  61,  61,  61,  61,  61,  61,  61,
+			61,  61,  61,  61,  61,  61,  61,  61,
+			61,  61,  61,  61,  61,  61,  61,  61,
+			61,
+		},
+		{	/* Fourth byte table 3. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   2,   2,   4,   4,   6,   6,   8,
+			8,   10,  10,  10,  12,  12,  14,  14,
+			16,  16,  18,  18,  20,  20,  22,  22,
+			24,  24,  26,  26,  28,  28,  30,  30,
+			32,  32,  34,  34,  36,  36,  38,  38,
+			40,  40,  42,  42,  44,  44,  46,  46,
+			48,  48,  50,  50,  52,  52,  54,  54,
+			56,  56,  56,  58,  58,  60,  60,  62,
+			63,  63,  63,  63,  63,  63,  63,  63,
+			63,  63,  63,  63,  63,  63,  63,  63,
+			63,  63,  63,  63,  63,  63,  63,  63,
+			63,  63,  63,  63,  63,  63,  63,  63,
+			63,  63,  63,  63,  63,  63,  63,  63,
+			63,  63,  63,  63,  63,  63,  63,  63,
+			63,  63,  63,  63,  63,  63,  63,  63,
+			63,  63,  63,  63,  63,  63,  63,  63,
+			63,
+		},
+		{	/* Fourth byte table 4. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   2,   2,   2,   4,   4,   6,   6,
+			6,   8,   8,   8,   8,   10,  10,  10,
+			10,  10,  10,  12,  12,  12,  14,  14,
+			14,  14,  16,  18,  18,  18,  18,  20,
+			20,  20,  22,  22,  24,  24,  26,  26,
+			26,  28,  28,  28,  28,  28,  30,  30,
+			30,  32,  32,  32,  32,  34,  34,  36,
+			36,  36,  38,  38,  38,  38,  40,  40,
+			42,  42,  42,  42,  42,  42,  42,  42,
+			42,  42,  42,  42,  42,  42,  42,  42,
+			42,  42,  42,  42,  42,  42,  42,  42,
+			42,  42,  42,  42,  42,  42,  42,  42,
+			42,  42,  42,  42,  42,  42,  42,  42,
+			42,  42,  42,  42,  42,  42,  42,  42,
+			42,  42,  42,  42,  42,  42,  42,  42,
+			42,  42,  42,  42,  42,  42,  42,  42,
+			42,
+		},
+		{	/* Fourth byte table 5. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   2,   4,
+			4,   6,   8,   8,   10,  12,  12,  14,
+			14,  16,  16,  18,  18,  20,  20,  22,
+			22,  24,  24,  26,  26,  28,  30,  30,
+			32,  32,  34,  34,  36,  36,  38,  38,
+			40,  40,  42,  42,  44,  44,  46,  46,
+			48,  48,  48,  50,  52,  52,  54,  54,
+			54,  54,  56,  56,  58,  58,  60,  60,
+			62,  62,  62,  62,  62,  62,  62,  62,
+			62,  62,  62,  62,  62,  62,  62,  62,
+			62,  62,  62,  62,  62,  62,  62,  62,
+			62,  62,  62,  62,  62,  62,  62,  62,
+			62,  62,  62,  62,  62,  62,  62,  62,
+			62,  62,  62,  62,  62,  62,  62,  62,
+			62,  62,  62,  62,  62,  62,  62,  62,
+			62,  62,  62,  62,  62,  62,  62,  62,
+			62,
+		},
+		{	/* Fourth byte table 6. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   2,   2,   4,   4,   6,   6,
+			8,   8,   10,  10,  12,  12,  14,  14,
+			16,  16,  18,  18,  20,  20,  22,  22,
+			24,  24,  26,  26,  28,  28,  30,  30,
+			32,  32,  32,  32,  34,  34,  36,  36,
+			38,  38,  40,  40,  42,  42,  44,  44,
+			46,  46,  48,  48,  50,  50,  50,  50,
+			50,  50,  50,  50,  50,  52,  52,  52,
+			52,  52,  52,  52,  52,  52,  52,  52,
+			52,  52,  52,  52,  52,  52,  52,  52,
+			52,  52,  52,  52,  52,  52,  52,  52,
+			52,  52,  52,  52,  52,  52,  52,  52,
+			52,  52,  52,  52,  52,  52,  52,  52,
+			52,  52,  52,  52,  52,  52,  52,  52,
+			52,  52,  52,  52,  52,  52,  52,  52,
+			52,  52,  52,  52,  52,  52,  52,  52,
+			52,
+		},
+		{	/* Fourth byte table 7. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   2,   2,   2,   2,   2,
+			4,   4,   6,   6,   8,   8,   10,  10,
+			12,  12,  12,  12,  14,  16,  16,  18,
+			20,  20,  22,  22,  24,  24,  24,  24,
+			24,  26,  26,  26,  28,  28,  28,  28,
+			28,  30,  32,  32,  35,  35,  35,  35,
+			37,  37,  37,  39,  39,  39,  41,  41,
+			41,  41,  41,  41,  41,  41,  44,  44,
+			44,  44,  44,  44,  44,  44,  44,  44,
+			44,  44,  44,  44,  44,  44,  44,  44,
+			44,  44,  44,  44,  44,  44,  44,  44,
+			44,  44,  44,  44,  44,  44,  44,  44,
+			44,  44,  44,  44,  44,  44,  44,  44,
+			44,  44,  44,  44,  44,  44,  44,  44,
+			44,  44,  44,  44,  44,  44,  44,  44,
+			44,  44,  44,  44,  44,  44,  44,  44,
+			44,
+		},
+		{	/* Fourth byte table 8. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   2,   2,   2,   4,   4,   4,   4,
+			4,   6,   8,   10,  12,  14,  14,  14,
+			14,  14,  14,  16,  16,  16,  16,  16,
+			16,  16,  16,  16,  16,  16,  16,  16,
+			16,  16,  16,  16,  16,  16,  16,  16,
+			16,  16,  16,  16,  16,  16,  16,  16,
+			16,  16,  16,  16,  16,  16,  16,  16,
+			16,  16,  16,  16,  16,  16,  16,  16,
+			16,  16,  16,  16,  16,  16,  16,  16,
+			16,  16,  16,  16,  16,  16,  16,  16,
+			16,  16,  16,  16,  16,  16,  16,  16,
+			16,  16,  16,  16,  16,  16,  16,  16,
+			16,  16,  16,  16,  16,  16,  16,  16,
+			16,  16,  16,  16,  16,  16,  16,  16,
+			16,  16,  16,  16,  16,  16,  16,  16,
+			16,  16,  16,  16,  16,  16,  16,  16,
+			16,
+		},
+		{	/* Fourth byte table 9. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   2,   2,
+			2,   2,   2,   2,   2,   2,   2,   2,
+			2,   2,   2,   2,   2,   2,   2,   2,
+			2,   2,   2,   2,   2,   2,   2,   2,
+			2,   2,   2,   2,   2,   2,   2,   2,
+			2,   2,   2,   2,   2,   2,   2,   2,
+			2,   2,   2,   2,   2,   2,   2,   2,
+			2,   2,   2,   2,   4,   6,   8,   8,
+			8,   8,   8,   8,   8,   8,   8,   8,
+			8,   8,   8,   8,   8,   8,   8,   8,
+			8,   8,   8,   8,   8,   8,   8,   8,
+			8,   8,   8,   8,   8,   8,   8,   8,
+			8,   8,   8,   8,   8,   8,   8,   8,
+			8,   8,   8,   8,   8,   8,   8,   8,
+			8,   8,   8,   8,   8,   8,   8,   8,
+			8,   8,   8,   8,   8,   8,   8,   8,
+			8,
+		},
+		{	/* Fourth byte table 10. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   2,   4,   6,
+			8,   8,   10,  12,  14,  16,  18,  20,
+			22,  24,  26,  28,  30,  32,  34,  36,
+			38,  38,  38,  38,  38,  38,  38,  38,
+			38,  38,  38,  38,  38,  38,  38,  38,
+			38,  38,  38,  38,  38,  38,  38,  38,
+			38,  38,  38,  38,  38,  38,  38,  38,
+			38,  38,  38,  38,  38,  38,  38,  38,
+			38,  38,  38,  38,  38,  38,  38,  38,
+			38,  38,  38,  38,  38,  38,  38,  38,
+			38,  38,  38,  38,  38,  38,  38,  38,
+			38,
+		},
+		{	/* Fourth byte table 11. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   2,   4,   6,   8,   10,  12,  14,
+			16,  18,  20,  22,  24,  26,  28,  30,
+			30,  32,  34,  34,  34,  34,  36,  38,
+			38,  38,  40,  40,  42,  42,  44,  44,
+			46,  46,  48,  48,  50,  50,  52,  52,
+			54,  54,  56,  56,  58,  58,  60,  60,
+			62,  64,  66,  68,  68,  68,  70,  70,
+			70,  72,  72,  72,  74,  74,  74,  74,
+			74,  74,  74,  74,  74,  74,  74,  74,
+			74,  74,  74,  74,  74,  74,  74,  74,
+			74,  74,  74,  74,  74,  74,  74,  74,
+			74,  74,  74,  74,  74,  74,  74,  74,
+			74,  74,  74,  74,  74,  74,  74,  74,
+			74,  74,  74,  74,  74,  74,  74,  74,
+			74,  74,  74,  74,  74,  74,  74,  74,
+			74,  74,  74,  74,  74,  74,  74,  74,
+			74,
+		},
+		{	/* Fourth byte table 12. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   2,   4,   6,   8,   10,  12,  14,
+			16,  18,  20,  22,  24,  26,  28,  30,
+			32,  32,  32,  32,  32,  32,  32,  32,
+			32,  32,  32,  32,  32,  32,  32,  32,
+			32,  32,  32,  32,  32,  32,  32,  32,
+			32,  32,  32,  32,  32,  32,  32,  32,
+			32,  32,  32,  32,  32,  32,  32,  32,
+			32,  32,  32,  32,  32,  32,  32,  32,
+			32,  32,  32,  32,  32,  32,  32,  32,
+			32,  32,  32,  32,  32,  32,  32,  32,
+			32,
+		},
+		{	/* Fourth byte table 13. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   2,   4,   6,   8,   10,  12,  14,
+			16,  18,  20,  22,  24,  26,  28,  30,
+			32,  34,  36,  38,  40,  42,  44,  46,
+			48,  50,  52,  54,  56,  58,  60,  62,
+			64,  64,  66,  66,  68,  68,  70,  70,
+			72,  72,  74,  74,  76,  76,  78,  78,
+			80,  80,  82,  82,  84,  84,  86,  86,
+			88,  88,  90,  90,  92,  92,  94,  94,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,
+		},
+		{	/* Fourth byte table 14. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   2,   2,   2,   2,   2,   2,
+			2,   2,   2,   2,   4,   4,   6,   6,
+			8,   8,   10,  10,  12,  12,  14,  14,
+			16,  16,  18,  18,  20,  20,  22,  22,
+			24,  24,  26,  26,  28,  28,  30,  30,
+			32,  32,  34,  34,  36,  36,  38,  38,
+			40,  40,  42,  42,  44,  44,  46,  46,
+			48,  48,  50,  50,  52,  52,  54,  54,
+			56,  56,  56,  56,  56,  56,  56,  56,
+			56,  56,  56,  56,  56,  56,  56,  56,
+			56,  56,  56,  56,  56,  56,  56,  56,
+			56,  56,  56,  56,  56,  56,  56,  56,
+			56,  56,  56,  56,  56,  56,  56,  56,
+			56,  56,  56,  56,  56,  56,  56,  56,
+			56,  56,  56,  56,  56,  56,  56,  56,
+			56,  56,  56,  56,  56,  56,  56,  56,
+			56,
+		},
+		{	/* Fourth byte table 15. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   2,   2,   4,   4,   6,
+			6,   8,   8,   10,  10,  12,  12,  14,
+			16,  16,  18,  18,  20,  20,  22,  22,
+			24,  24,  26,  26,  28,  28,  30,  30,
+			32,  32,  34,  34,  36,  36,  38,  38,
+			40,  40,  42,  42,  44,  44,  46,  46,
+			48,  48,  50,  50,  52,  52,  54,  54,
+			56,  56,  58,  58,  60,  60,  62,  62,
+			64,  64,  64,  64,  64,  64,  64,  64,
+			64,  64,  64,  64,  64,  64,  64,  64,
+			64,  64,  64,  64,  64,  64,  64,  64,
+			64,  64,  64,  64,  64,  64,  64,  64,
+			64,  64,  64,  64,  64,  64,  64,  64,
+			64,  64,  64,  64,  64,  64,  64,  64,
+			64,  64,  64,  64,  64,  64,  64,  64,
+			64,  64,  64,  64,  64,  64,  64,  64,
+			64,
+		},
+		{	/* Fourth byte table 16. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   2,   2,   4,   4,   6,   6,
+			8,   8,   10,  10,  12,  12,  14,  14,
+			16,  16,  18,  18,  20,  20,  20,  20,
+			20,  20,  20,  20,  20,  20,  20,  20,
+			20,  20,  20,  20,  20,  20,  20,  20,
+			20,  20,  20,  20,  20,  20,  20,  20,
+			20,  20,  20,  20,  20,  20,  20,  20,
+			20,  20,  20,  20,  20,  20,  20,  20,
+			20,  20,  20,  20,  20,  20,  20,  20,
+			20,  20,  20,  20,  20,  20,  20,  20,
+			20,  20,  20,  20,  20,  20,  20,  20,
+			20,  20,  20,  20,  20,  20,  20,  20,
+			20,  20,  20,  20,  20,  20,  20,  20,
+			20,  20,  20,  20,  20,  20,  20,  20,
+			20,  20,  20,  20,  20,  20,  20,  20,
+			20,  20,  20,  20,  20,  20,  20,  20,
+			20,
+		},
+		{	/* Fourth byte table 17. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   2,   4,   6,   8,   10,  12,
+			14,  16,  18,  20,  22,  24,  26,  28,
+			30,  32,  34,  36,  38,  40,  42,  44,
+			46,  48,  50,  52,  54,  56,  58,  60,
+			62,  62,  62,  62,  62,  62,  62,  62,
+			62,  62,  62,  62,  62,  62,  62,  62,
+			62,  62,  62,  62,  62,  62,  62,  62,
+			62,  62,  62,  62,  62,  62,  62,  62,
+			62,  62,  62,  62,  62,  62,  62,  62,
+			62,  62,  62,  62,  62,  62,  62,  62,
+			62,  62,  62,  62,  62,  62,  62,  62,
+			62,  62,  62,  62,  62,  62,  62,  62,
+			62,
+		},
+		{	/* Fourth byte table 18. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   2,   4,   6,   8,   10,  12,  14,
+			14,  14,  14,  14,  14,  14,  14,  14,
+			14,  14,  14,  14,  14,  14,  14,  14,
+			14,  14,  14,  14,  14,  14,  14,  14,
+			14,  14,  14,  14,  14,  14,  14,  14,
+			14,  14,  14,  14,  14,  14,  14,  14,
+			14,  14,  14,  14,  14,  14,  14,  14,
+			14,  14,  14,  14,  14,  14,  14,  14,
+			14,  14,  14,  14,  14,  14,  14,  14,
+			14,  14,  14,  14,  14,  14,  14,  14,
+			14,  14,  14,  14,  14,  14,  14,  14,
+			14,  14,  14,  14,  14,  14,  14,  14,
+			14,  14,  14,  14,  14,  14,  14,  14,
+			14,  14,  14,  14,  14,  14,  14,  14,
+			14,  14,  14,  14,  14,  14,  14,  14,
+			14,  14,  14,  14,  14,  14,  14,  14,
+			14,
+		},
+		{	/* Fourth byte table 19. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   3,   3,
+			3,   3,   3,   3,   3,   3,   3,   3,
+			3,   3,   3,   3,   3,   3,   3,   3,
+			3,   3,   3,   3,   3,   3,   3,   3,
+			3,   3,   3,   3,   3,   3,   3,   3,
+			3,   3,   3,   3,   3,   3,   3,   3,
+			3,   3,   3,   3,   3,   3,   3,   3,
+			3,   3,   3,   3,   3,   3,   3,   3,
+			3,   3,   3,   3,   3,   3,   3,   3,
+			3,
+		},
+		{	/* Fourth byte table 20. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   3,   3,   6,   6,   9,   9,
+			12,  12,  15,  15,  18,  18,  21,  21,
+			24,  24,  27,  27,  30,  30,  33,  33,
+			36,  36,  39,  39,  42,  42,  45,  45,
+			48,  48,  51,  51,  54,  54,  57,  57,
+			60,  60,  63,  63,  66,  66,  69,  69,
+			72,  72,  75,  75,  78,  78,  81,  81,
+			84,  84,  87,  87,  90,  90,  93,  93,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,
+		},
+		{	/* Fourth byte table 21. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   3,   3,   6,   6,   9,   9,
+			12,  12,  15,  15,  18,  18,  21,  21,
+			24,  24,  27,  27,  30,  30,  33,  33,
+			36,  36,  39,  39,  42,  42,  45,  45,
+			48,  48,  51,  51,  54,  54,  57,  57,
+			60,  60,  63,  63,  66,  66,  69,  69,
+			72,  72,  75,  75,  78,  78,  81,  81,
+			84,  84,  87,  87,  90,  90,  93,  93,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,
+		},
+		{	/* Fourth byte table 22. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   3,   3,   6,   6,   9,   9,
+			12,  12,  15,  15,  18,  18,  21,  21,
+			24,  24,  27,  27,  30,  30,  33,  33,
+			33,  33,  33,  33,  36,  36,  36,  36,
+			36,  36,  39,  39,  42,  42,  45,  45,
+			48,  48,  51,  51,  54,  54,  57,  57,
+			60,  60,  63,  63,  66,  66,  69,  69,
+			72,  72,  75,  75,  78,  78,  81,  81,
+			84,  84,  84,  84,  84,  84,  84,  84,
+			84,  84,  84,  84,  84,  84,  84,  84,
+			84,  84,  84,  84,  84,  84,  84,  84,
+			84,  84,  84,  84,  84,  84,  84,  84,
+			84,  84,  84,  84,  84,  84,  84,  84,
+			84,  84,  84,  84,  84,  84,  84,  84,
+			84,  84,  84,  84,  84,  84,  84,  84,
+			84,  84,  84,  84,  84,  84,  84,  84,
+			84,
+		},
+		{	/* Fourth byte table 23. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   3,   3,   6,   6,   9,   9,
+			12,  12,  15,  15,  18,  18,  21,  21,
+			24,  24,  27,  27,  30,  30,  33,  33,
+			36,  36,  39,  39,  42,  42,  45,  45,
+			48,  48,  51,  51,  54,  54,  57,  57,
+			60,  60,  63,  63,  66,  66,  69,  69,
+			72,  72,  75,  75,  78,  78,  81,  81,
+			84,  84,  87,  87,  87,  87,  87,  87,
+			87,  87,  87,  87,  87,  87,  87,  87,
+			87,  87,  87,  87,  87,  87,  87,  87,
+			87,  87,  87,  87,  87,  87,  87,  87,
+			87,  87,  87,  87,  87,  87,  87,  87,
+			87,  87,  87,  87,  87,  87,  87,  87,
+			87,  87,  87,  87,  87,  87,  87,  87,
+			87,  87,  87,  87,  87,  87,  87,  87,
+			87,  87,  87,  87,  87,  87,  87,  87,
+			87,
+		},
+		{	/* Fourth byte table 24. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   3,   6,   9,   12,  15,  18,  21,
+			24,  24,  24,  24,  24,  24,  24,  24,
+			24,  27,  30,  33,  36,  39,  42,  42,
+			42,  42,  42,  42,  42,  42,  42,  42,
+			42,  45,  48,  51,  54,  57,  60,  63,
+			66,  66,  66,  66,  66,  66,  66,  66,
+			66,  69,  72,  75,  78,  81,  84,  87,
+			90,  90,  90,  90,  90,  90,  90,  90,
+			90,  90,  90,  90,  90,  90,  90,  90,
+			90,  90,  90,  90,  90,  90,  90,  90,
+			90,  90,  90,  90,  90,  90,  90,  90,
+			90,  90,  90,  90,  90,  90,  90,  90,
+			90,  90,  90,  90,  90,  90,  90,  90,
+			90,  90,  90,  90,  90,  90,  90,  90,
+			90,  90,  90,  90,  90,  90,  90,  90,
+			90,  90,  90,  90,  90,  90,  90,  90,
+			90,
+		},
+		{	/* Fourth byte table 25. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   3,   6,   9,   12,  15,  18,  18,
+			18,  18,  18,  18,  18,  18,  18,  18,
+			18,  18,  21,  21,  24,  24,  27,  27,
+			30,  30,  30,  30,  30,  30,  30,  30,
+			30,  33,  36,  39,  42,  45,  48,  51,
+			54,  54,  54,  54,  54,  54,  54,  54,
+			54,  57,  60,  63,  66,  69,  72,  75,
+			78,  81,  84,  87,  90,  93,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,
+		},
+		{	/* Fourth byte table 26. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   3,   6,   9,   12,  15,  18,  21,
+			24,  24,  24,  24,  24,  24,  24,  24,
+			24,  27,  30,  33,  36,  39,  42,  45,
+			48,  48,  48,  48,  48,  48,  48,  48,
+			48,  51,  54,  57,  60,  63,  66,  69,
+			72,  72,  72,  72,  72,  72,  72,  72,
+			72,  75,  78,  78,  81,  81,  81,  81,
+			81,  81,  81,  81,  81,  81,  81,  83,
+			83,  83,  83,  83,  83,  83,  83,  83,
+			83,  83,  83,  83,  83,  83,  83,  83,
+			83,  83,  83,  83,  83,  83,  83,  83,
+			83,  83,  83,  83,  83,  83,  83,  83,
+			83,  83,  83,  83,  83,  83,  83,  83,
+			83,  83,  83,  83,  83,  83,  83,  83,
+			83,  83,  83,  83,  83,  83,  83,  83,
+			83,  83,  83,  83,  83,  83,  83,  83,
+			83,
+		},
+		{	/* Fourth byte table 27. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   3,   3,   3,   3,
+			3,   3,   3,   3,   3,   3,   3,   3,
+			3,   6,   9,   9,   9,   9,   9,   9,
+			9,   9,   9,   9,   9,   9,   9,   9,
+			9,   12,  15,  15,  15,  15,  18,  18,
+			18,  18,  18,  18,  18,  18,  18,  18,
+			18,  18,  18,  18,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,  21,  21,  21,  21,  21,  21,  21,
+			21,
+		},
+		{	/* Fourth byte table 28. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   3,
+			3,   3,   3,   3,   3,   3,   3,   3,
+			3,   3,   3,   3,   3,   3,   3,   3,
+			3,   3,   3,   3,   3,   3,   3,   3,
+			3,   3,   3,   3,   3,   3,   3,   3,
+			3,   6,   9,   12,  15,  18,  21,  24,
+			27,  30,  33,  36,  39,  42,  45,  48,
+			51,  51,  51,  51,  51,  51,  51,  51,
+			51,  51,  51,  51,  51,  51,  51,  51,
+			51,  51,  51,  51,  51,  51,  51,  51,
+			51,  51,  51,  51,  51,  51,  51,  51,
+			51,  51,  51,  51,  51,  51,  51,  51,
+			51,  51,  51,  51,  51,  51,  51,  51,
+			51,  51,  51,  51,  51,  51,  51,  51,
+			51,  51,  51,  51,  51,  51,  51,  51,
+			51,
+		},
+		{	/* Fourth byte table 29. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   3,   3,   3,
+			3,   3,   3,   3,   3,   3,   3,   3,
+			3,   3,   3,   3,   3,   3,   3,   3,
+			3,   3,   3,   3,   3,   3,   3,   3,
+			3,   3,   3,   3,   3,   3,   3,   3,
+			3,   3,   3,   3,   3,   3,   3,   3,
+			3,   3,   3,   3,   3,   3,   3,   3,
+			3,   3,   3,   3,   3,   3,   3,   3,
+			3,   3,   3,   3,   3,   3,   3,   3,
+			3,   3,   3,   3,   3,   3,   3,   3,
+			3,   3,   3,   3,   3,   3,   3,   3,
+			3,   3,   3,   3,   3,   3,   3,   3,
+			3,   3,   3,   3,   3,   3,   3,   3,
+			3,   3,   3,   3,   3,   3,   3,   3,
+			3,   3,   3,   3,   3,   3,   3,   3,
+			3,   3,   3,   3,   3,   3,   3,   3,
+			3,
+		},
+		{	/* Fourth byte table 30. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   3,   6,   9,   12,  15,  18,  21,
+			24,  27,  30,  33,  36,  39,  42,  45,
+			48,  51,  54,  57,  60,  63,  66,  69,
+			72,  75,  78,  78,  78,  78,  78,  78,
+			78,  78,  78,  78,  78,  78,  78,  78,
+			78,  78,  78,  78,  78,  78,  78,  78,
+			78,  78,  78,  78,  78,  78,  78,  78,
+			78,  78,  78,  78,  78,  78,  78,  78,
+			78,  78,  78,  78,  78,  78,  78,  78,
+			78,  78,  78,  78,  78,  78,  78,  78,
+			78,  78,  78,  78,  78,  78,  78,  78,
+			78,  78,  78,  78,  78,  78,  78,  78,
+			78,  78,  78,  78,  78,  78,  78,  78,
+			78,  78,  78,  78,  78,  78,  78,  78,
+			78,
+		},
+		{	/* Fourth byte table 31. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   3,   6,   9,   12,  15,  18,  21,
+			24,  27,  30,  33,  36,  39,  42,  45,
+			48,  48,  48,  48,  48,  48,  48,  48,
+			48,  48,  48,  48,  48,  48,  48,  48,
+			48,  48,  48,  48,  48,  48,  48,  48,
+			48,  48,  48,  48,  48,  48,  48,  48,
+			48,  48,  48,  48,  48,  48,  48,  48,
+			48,  48,  48,  48,  48,  48,  48,  48,
+			48,  48,  48,  48,  48,  48,  48,  48,
+			48,  48,  48,  48,  48,  48,  48,  48,
+			48,
+		},
+		{	/* Fourth byte table 32. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   3,   6,   9,   12,  15,  18,  21,
+			24,  27,  30,  33,  36,  39,  42,  45,
+			48,  51,  54,  57,  60,  63,  66,  69,
+			72,  75,  78,  81,  84,  87,  90,  93,
+			93,  93,  96,  96,  96,  96,  98,  100,
+			100, 103, 103, 106, 106, 109, 109, 109,
+			109, 109, 109, 109, 109, 109, 109, 112,
+			112, 112, 112, 112, 112, 112, 112, 112,
+			112, 112, 112, 112, 112, 112, 112, 112,
+			112, 112, 112, 112, 112, 112, 112, 112,
+			112, 112, 112, 112, 112, 112, 112, 112,
+			112, 112, 112, 112, 112, 112, 112, 112,
+			112, 112, 112, 112, 112, 112, 112, 112,
+			112, 112, 112, 112, 112, 112, 112, 112,
+			112, 112, 112, 112, 112, 112, 112, 112,
+			112, 112, 112, 112, 112, 112, 112, 112,
+			112,
+		},
+		{	/* Fourth byte table 33. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   3,   3,   6,   6,   9,   9,
+			12,  12,  15,  15,  18,  18,  21,  21,
+			24,  24,  27,  27,  30,  30,  33,  33,
+			36,  36,  39,  39,  42,  42,  45,  45,
+			48,  48,  51,  51,  54,  54,  57,  57,
+			60,  60,  63,  63,  66,  66,  69,  69,
+			72,  72,  75,  75,  78,  78,  81,  81,
+			84,  84,  87,  87,  90,  90,  93,  93,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,
+		},
+		{	/* Fourth byte table 34. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   3,   3,   6,   6,   9,   9,
+			12,  12,  15,  15,  18,  18,  21,  21,
+			24,  24,  27,  27,  30,  30,  33,  33,
+			36,  36,  39,  39,  42,  42,  45,  45,
+			48,  48,  51,  51,  54,  54,  54,  54,
+			54,  54,  54,  54,  54,  54,  54,  54,
+			54,  54,  54,  54,  54,  54,  54,  54,
+			54,  54,  54,  54,  54,  54,  54,  54,
+			54,  54,  54,  54,  54,  54,  54,  54,
+			54,  54,  54,  54,  54,  54,  54,  54,
+			54,  54,  54,  54,  54,  54,  54,  54,
+			54,  54,  54,  54,  54,  54,  54,  54,
+			54,  54,  54,  54,  54,  54,  54,  54,
+			54,  54,  54,  54,  54,  54,  54,  54,
+			54,  54,  54,  54,  54,  54,  54,  54,
+			54,  54,  54,  54,  54,  54,  54,  54,
+			54,
+		},
+		{	/* Fourth byte table 35. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   3,   6,   9,   12,  15,  18,  21,
+			24,  27,  30,  33,  36,  39,  42,  45,
+			48,  51,  54,  57,  60,  63,  66,  69,
+			72,  75,  78,  81,  84,  87,  90,  93,
+			96,  99,  102, 105, 108, 111, 114, 114,
+			114, 114, 114, 114, 114, 114, 114, 114,
+			114, 114, 114, 114, 114, 114, 114, 114,
+			114, 114, 114, 114, 114, 114, 114, 114,
+			114, 114, 114, 114, 114, 114, 114, 114,
+			114, 114, 114, 114, 114, 114, 114, 114,
+			114, 114, 114, 114, 114, 114, 114, 114,
+			114, 114, 114, 114, 114, 114, 114, 114,
+			114, 114, 114, 114, 114, 114, 114, 114,
+			114, 114, 114, 114, 114, 114, 114, 114,
+			114, 114, 114, 114, 114, 114, 114, 114,
+			114, 114, 114, 114, 114, 114, 114, 114,
+			114,
+		},
+		{	/* Fourth byte table 36. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   3,   6,   9,   12,  15,  18,
+			21,  24,  27,  30,  33,  36,  39,  42,
+			45,  48,  51,  54,  57,  60,  63,  66,
+			69,  72,  75,  78,  78,  78,  78,  78,
+			78,  78,  78,  78,  78,  78,  78,  78,
+			78,  78,  78,  78,  78,  78,  78,  78,
+			78,  78,  78,  78,  78,  78,  78,  78,
+			78,  78,  78,  78,  78,  78,  78,  78,
+			78,  78,  78,  78,  78,  78,  78,  78,
+			78,  78,  78,  78,  78,  78,  78,  78,
+			78,  78,  78,  78,  78,  78,  78,  78,
+			78,  78,  78,  78,  78,  78,  78,  78,
+			78,  78,  78,  78,  78,  78,  78,  78,
+			78,  78,  78,  78,  78,  78,  78,  78,
+			78,  78,  78,  78,  78,  78,  78,  78,
+			78,  78,  78,  78,  78,  78,  78,  78,
+			78,
+		},
+		{	/* Fourth byte table 37. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   4,   8,   12,  16,  20,  24,  28,
+			32,  36,  40,  44,  48,  52,  56,  60,
+			64,  68,  72,  76,  80,  84,  88,  92,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,  96,  96,  96,  96,  96,  96,  96,
+			96,
+		},
+		{	/* Fourth byte table 38. */
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   0,   0,   0,   0,   0,   0,   0,
+			0,   4,   8,   12,  16,  20,  24,  28,
+			32,  36,  40,  44,  48,  52,  56,  60,
+			64,  64,  64,  64,  64,  64,  64,  64,
+			64,  64,  64,  64,  64,  64,  64,  64,
+			64,  64,  64,  64,  64,  64,  64,  64,
+			64,  64,  64,  64,  64,  64,  64,  64,
+			64,  64,  64,  64,  64,  64,  64,  64,
+			64,  64,  64,  64,  64,  64,  64,  64,
+			64,  64,  64,  64,  64,  64,  64,  64,
+			64,  64,  64,  64,  64,  64,  64,  64,
+			64,  64,  64,  64,  64,  64,  64,  64,
+			64,  64,  64,  64,  64,  64,  64,  64,
+			64,  64,  64,  64,  64,  64,  64,  64,
+			64,  64,  64,  64,  64,  64,  64,  64,
+			64,  64,  64,  64,  64,  64,  64,  64,
+			64,  64,  64,  64,  64,  64,  64,  64,
+			64,
+		},
+	},
+};
+
+static const uchar_t u8_toupper_final_tbl[2][2318] = {
+	{
+		0xCE, 0x9C, 0xC3, 0x80, 0xC3, 0x81, 0xC3, 0x82,
+		0xC3, 0x83, 0xC3, 0x84, 0xC3, 0x85, 0xC3, 0x86,
+		0xC3, 0x87, 0xC3, 0x88, 0xC3, 0x89, 0xC3, 0x8A,
+		0xC3, 0x8B, 0xC3, 0x8C, 0xC3, 0x8D, 0xC3, 0x8E,
+		0xC3, 0x8F, 0xC3, 0x90, 0xC3, 0x91, 0xC3, 0x92,
+		0xC3, 0x93, 0xC3, 0x94, 0xC3, 0x95, 0xC3, 0x96,
+		0xC3, 0x98, 0xC3, 0x99, 0xC3, 0x9A, 0xC3, 0x9B,
+		0xC3, 0x9C, 0xC3, 0x9D, 0xC3, 0x9E, 0xC5, 0xB8,
+		0xC4, 0x80, 0xC4, 0x82, 0xC4, 0x84, 0xC4, 0x86,
+		0xC4, 0x88, 0xC4, 0x8A, 0xC4, 0x8C, 0xC4, 0x8E,
+		0xC4, 0x90, 0xC4, 0x92, 0xC4, 0x94, 0xC4, 0x96,
+		0xC4, 0x98, 0xC4, 0x9A, 0xC4, 0x9C, 0xC4, 0x9E,
+		0xC4, 0xA0, 0xC4, 0xA2, 0xC4, 0xA4, 0xC4, 0xA6,
+		0xC4, 0xA8, 0xC4, 0xAA, 0xC4, 0xAC, 0xC4, 0xAE,
+		0x49, 0xC4, 0xB2, 0xC4, 0xB4, 0xC4, 0xB6, 0xC4,
+		0xB9, 0xC4, 0xBB, 0xC4, 0xBD, 0xC4, 0xBF, 0xC5,
+		0x81, 0xC5, 0x83, 0xC5, 0x85, 0xC5, 0x87, 0xC5,
+		0x8A, 0xC5, 0x8C, 0xC5, 0x8E, 0xC5, 0x90, 0xC5,
+		0x92, 0xC5, 0x94, 0xC5, 0x96, 0xC5, 0x98, 0xC5,
+		0x9A, 0xC5, 0x9C, 0xC5, 0x9E, 0xC5, 0xA0, 0xC5,
+		0xA2, 0xC5, 0xA4, 0xC5, 0xA6, 0xC5, 0xA8, 0xC5,
+		0xAA, 0xC5, 0xAC, 0xC5, 0xAE, 0xC5, 0xB0, 0xC5,
+		0xB2, 0xC5, 0xB4, 0xC5, 0xB6, 0xC5, 0xB9, 0xC5,
+		0xBB, 0xC5, 0xBD, 0x53, 0xC6, 0x82, 0xC6, 0x84,
+		0xC6, 0x87, 0xC6, 0x8B, 0xC6, 0x91, 0xC7, 0xB6,
+		0xC6, 0x98, 0xC8, 0xA0, 0xC6, 0xA0, 0xC6, 0xA2,
+		0xC6, 0xA4, 0xC6, 0xA7, 0xC6, 0xAC, 0xC6, 0xAF,
+		0xC6, 0xB3, 0xC6, 0xB5, 0xC6, 0xB8, 0xC6, 0xBC,
+		0xC7, 0xB7, 0xC7, 0x84, 0xC7, 0x84, 0xC7, 0x87,
+		0xC7, 0x87, 0xC7, 0x8A, 0xC7, 0x8A, 0xC7, 0x8D,
+		0xC7, 0x8F, 0xC7, 0x91, 0xC7, 0x93, 0xC7, 0x95,
+		0xC7, 0x97, 0xC7, 0x99, 0xC7, 0x9B, 0xC6, 0x8E,
+		0xC7, 0x9E, 0xC7, 0xA0, 0xC7, 0xA2, 0xC7, 0xA4,
+		0xC7, 0xA6, 0xC7, 0xA8, 0xC7, 0xAA, 0xC7, 0xAC,
+		0xC7, 0xAE, 0xC7, 0xB1, 0xC7, 0xB1, 0xC7, 0xB4,
+		0xC7, 0xB8, 0xC7, 0xBA, 0xC7, 0xBC, 0xC7, 0xBE,
+		0xC8, 0x80, 0xC8, 0x82, 0xC8, 0x84, 0xC8, 0x86,
+		0xC8, 0x88, 0xC8, 0x8A, 0xC8, 0x8C, 0xC8, 0x8E,
+		0xC8, 0x90, 0xC8, 0x92, 0xC8, 0x94, 0xC8, 0x96,
+		0xC8, 0x98, 0xC8, 0x9A, 0xC8, 0x9C, 0xC8, 0x9E,
+		0xC8, 0xA2, 0xC8, 0xA4, 0xC8, 0xA6, 0xC8, 0xA8,
+		0xC8, 0xAA, 0xC8, 0xAC, 0xC8, 0xAE, 0xC8, 0xB0,
+		0xC8, 0xB2, 0xC6, 0x81, 0xC6, 0x86, 0xC6, 0x89,
+		0xC6, 0x8A, 0xC6, 0x8F, 0xC6, 0x90, 0xC6, 0x93,
+		0xC6, 0x94, 0xC6, 0x97, 0xC6, 0x96, 0xC6, 0x9C,
+		0xC6, 0x9D, 0xC6, 0x9F, 0xC6, 0xA6, 0xC6, 0xA9,
+		0xC6, 0xAE, 0xC6, 0xB1, 0xC6, 0xB2, 0xC6, 0xB7,
+		0xCE, 0x99, 0xCE, 0x86, 0xCE, 0x88, 0xCE, 0x89,
+		0xCE, 0x8A, 0xCE, 0x91, 0xCE, 0x92, 0xCE, 0x93,
+		0xCE, 0x94, 0xCE, 0x95, 0xCE, 0x96, 0xCE, 0x97,
+		0xCE, 0x98, 0xCE, 0x99, 0xCE, 0x9A, 0xCE, 0x9B,
+		0xCE, 0x9C, 0xCE, 0x9D, 0xCE, 0x9E, 0xCE, 0x9F,
+		0xCE, 0xA0, 0xCE, 0xA1, 0xCE, 0xA3, 0xCE, 0xA3,
+		0xCE, 0xA4, 0xCE, 0xA5, 0xCE, 0xA6, 0xCE, 0xA7,
+		0xCE, 0xA8, 0xCE, 0xA9, 0xCE, 0xAA, 0xCE, 0xAB,
+		0xCE, 0x8C, 0xCE, 0x8E, 0xCE, 0x8F, 0xCE, 0x92,
+		0xCE, 0x98, 0xCE, 0xA6, 0xCE, 0xA0, 0xCF, 0x98,
+		0xCF, 0x9A, 0xCF, 0x9C, 0xCF, 0x9E, 0xCF, 0xA0,
+		0xCF, 0xA2, 0xCF, 0xA4, 0xCF, 0xA6, 0xCF, 0xA8,
+		0xCF, 0xAA, 0xCF, 0xAC, 0xCF, 0xAE, 0xCE, 0x9A,
+		0xCE, 0xA1, 0xCE, 0xA3, 0xCE, 0x95, 0xD0, 0x90,
+		0xD0, 0x91, 0xD0, 0x92, 0xD0, 0x93, 0xD0, 0x94,
+		0xD0, 0x95, 0xD0, 0x96, 0xD0, 0x97, 0xD0, 0x98,
+		0xD0, 0x99, 0xD0, 0x9A, 0xD0, 0x9B, 0xD0, 0x9C,
+		0xD0, 0x9D, 0xD0, 0x9E, 0xD0, 0x9F, 0xD0, 0xA0,
+		0xD0, 0xA1, 0xD0, 0xA2, 0xD0, 0xA3, 0xD0, 0xA4,
+		0xD0, 0xA5, 0xD0, 0xA6, 0xD0, 0xA7, 0xD0, 0xA8,
+		0xD0, 0xA9, 0xD0, 0xAA, 0xD0, 0xAB, 0xD0, 0xAC,
+		0xD0, 0xAD, 0xD0, 0xAE, 0xD0, 0xAF, 0xD0, 0x80,
+		0xD0, 0x81, 0xD0, 0x82, 0xD0, 0x83, 0xD0, 0x84,
+		0xD0, 0x85, 0xD0, 0x86, 0xD0, 0x87, 0xD0, 0x88,
+		0xD0, 0x89, 0xD0, 0x8A, 0xD0, 0x8B, 0xD0, 0x8C,
+		0xD0, 0x8D, 0xD0, 0x8E, 0xD0, 0x8F, 0xD1, 0xA0,
+		0xD1, 0xA2, 0xD1, 0xA4, 0xD1, 0xA6, 0xD1, 0xA8,
+		0xD1, 0xAA, 0xD1, 0xAC, 0xD1, 0xAE, 0xD1, 0xB0,
+		0xD1, 0xB2, 0xD1, 0xB4, 0xD1, 0xB6, 0xD1, 0xB8,
+		0xD1, 0xBA, 0xD1, 0xBC, 0xD1, 0xBE, 0xD2, 0x80,
+		0xD2, 0x8A, 0xD2, 0x8C, 0xD2, 0x8E, 0xD2, 0x90,
+		0xD2, 0x92, 0xD2, 0x94, 0xD2, 0x96, 0xD2, 0x98,
+		0xD2, 0x9A, 0xD2, 0x9C, 0xD2, 0x9E, 0xD2, 0xA0,
+		0xD2, 0xA2, 0xD2, 0xA4, 0xD2, 0xA6, 0xD2, 0xA8,
+		0xD2, 0xAA, 0xD2, 0xAC, 0xD2, 0xAE, 0xD2, 0xB0,
+		0xD2, 0xB2, 0xD2, 0xB4, 0xD2, 0xB6, 0xD2, 0xB8,
+		0xD2, 0xBA, 0xD2, 0xBC, 0xD2, 0xBE, 0xD3, 0x81,
+		0xD3, 0x83, 0xD3, 0x85, 0xD3, 0x87, 0xD3, 0x89,
+		0xD3, 0x8B, 0xD3, 0x8D, 0xD3, 0x90, 0xD3, 0x92,
+		0xD3, 0x94, 0xD3, 0x96, 0xD3, 0x98, 0xD3, 0x9A,
+		0xD3, 0x9C, 0xD3, 0x9E, 0xD3, 0xA0, 0xD3, 0xA2,
+		0xD3, 0xA4, 0xD3, 0xA6, 0xD3, 0xA8, 0xD3, 0xAA,
+		0xD3, 0xAC, 0xD3, 0xAE, 0xD3, 0xB0, 0xD3, 0xB2,
+		0xD3, 0xB4, 0xD3, 0xB8, 0xD4, 0x80, 0xD4, 0x82,
+		0xD4, 0x84, 0xD4, 0x86, 0xD4, 0x88, 0xD4, 0x8A,
+		0xD4, 0x8C, 0xD4, 0x8E, 0xD4, 0xB1, 0xD4, 0xB2,
+		0xD4, 0xB3, 0xD4, 0xB4, 0xD4, 0xB5, 0xD4, 0xB6,
+		0xD4, 0xB7, 0xD4, 0xB8, 0xD4, 0xB9, 0xD4, 0xBA,
+		0xD4, 0xBB, 0xD4, 0xBC, 0xD4, 0xBD, 0xD4, 0xBE,
+		0xD4, 0xBF, 0xD5, 0x80, 0xD5, 0x81, 0xD5, 0x82,
+		0xD5, 0x83, 0xD5, 0x84, 0xD5, 0x85, 0xD5, 0x86,
+		0xD5, 0x87, 0xD5, 0x88, 0xD5, 0x89, 0xD5, 0x8A,
+		0xD5, 0x8B, 0xD5, 0x8C, 0xD5, 0x8D, 0xD5, 0x8E,
+		0xD5, 0x8F, 0xD5, 0x90, 0xD5, 0x91, 0xD5, 0x92,
+		0xD5, 0x93, 0xD5, 0x94, 0xD5, 0x95, 0xD5, 0x96,
+		0xE1, 0xB8, 0x80, 0xE1, 0xB8, 0x82, 0xE1, 0xB8,
+		0x84, 0xE1, 0xB8, 0x86, 0xE1, 0xB8, 0x88, 0xE1,
+		0xB8, 0x8A, 0xE1, 0xB8, 0x8C, 0xE1, 0xB8, 0x8E,
+		0xE1, 0xB8, 0x90, 0xE1, 0xB8, 0x92, 0xE1, 0xB8,
+		0x94, 0xE1, 0xB8, 0x96, 0xE1, 0xB8, 0x98, 0xE1,
+		0xB8, 0x9A, 0xE1, 0xB8, 0x9C, 0xE1, 0xB8, 0x9E,
+		0xE1, 0xB8, 0xA0, 0xE1, 0xB8, 0xA2, 0xE1, 0xB8,
+		0xA4, 0xE1, 0xB8, 0xA6, 0xE1, 0xB8, 0xA8, 0xE1,
+		0xB8, 0xAA, 0xE1, 0xB8, 0xAC, 0xE1, 0xB8, 0xAE,
+		0xE1, 0xB8, 0xB0, 0xE1, 0xB8, 0xB2, 0xE1, 0xB8,
+		0xB4, 0xE1, 0xB8, 0xB6, 0xE1, 0xB8, 0xB8, 0xE1,
+		0xB8, 0xBA, 0xE1, 0xB8, 0xBC, 0xE1, 0xB8, 0xBE,
+		0xE1, 0xB9, 0x80, 0xE1, 0xB9, 0x82, 0xE1, 0xB9,
+		0x84, 0xE1, 0xB9, 0x86, 0xE1, 0xB9, 0x88, 0xE1,
+		0xB9, 0x8A, 0xE1, 0xB9, 0x8C, 0xE1, 0xB9, 0x8E,
+		0xE1, 0xB9, 0x90, 0xE1, 0xB9, 0x92, 0xE1, 0xB9,
+		0x94, 0xE1, 0xB9, 0x96, 0xE1, 0xB9, 0x98, 0xE1,
+		0xB9, 0x9A, 0xE1, 0xB9, 0x9C, 0xE1, 0xB9, 0x9E,
+		0xE1, 0xB9, 0xA0, 0xE1, 0xB9, 0xA2, 0xE1, 0xB9,
+		0xA4, 0xE1, 0xB9, 0xA6, 0xE1, 0xB9, 0xA8, 0xE1,
+		0xB9, 0xAA, 0xE1, 0xB9, 0xAC, 0xE1, 0xB9, 0xAE,
+		0xE1, 0xB9, 0xB0, 0xE1, 0xB9, 0xB2, 0xE1, 0xB9,
+		0xB4, 0xE1, 0xB9, 0xB6, 0xE1, 0xB9, 0xB8, 0xE1,
+		0xB9, 0xBA, 0xE1, 0xB9, 0xBC, 0xE1, 0xB9, 0xBE,
+		0xE1, 0xBA, 0x80, 0xE1, 0xBA, 0x82, 0xE1, 0xBA,
+		0x84, 0xE1, 0xBA, 0x86, 0xE1, 0xBA, 0x88, 0xE1,
+		0xBA, 0x8A, 0xE1, 0xBA, 0x8C, 0xE1, 0xBA, 0x8E,
+		0xE1, 0xBA, 0x90, 0xE1, 0xBA, 0x92, 0xE1, 0xBA,
+		0x94, 0xE1, 0xB9, 0xA0, 0xE1, 0xBA, 0xA0, 0xE1,
+		0xBA, 0xA2, 0xE1, 0xBA, 0xA4, 0xE1, 0xBA, 0xA6,
+		0xE1, 0xBA, 0xA8, 0xE1, 0xBA, 0xAA, 0xE1, 0xBA,
+		0xAC, 0xE1, 0xBA, 0xAE, 0xE1, 0xBA, 0xB0, 0xE1,
+		0xBA, 0xB2, 0xE1, 0xBA, 0xB4, 0xE1, 0xBA, 0xB6,
+		0xE1, 0xBA, 0xB8, 0xE1, 0xBA, 0xBA, 0xE1, 0xBA,
+		0xBC, 0xE1, 0xBA, 0xBE, 0xE1, 0xBB, 0x80, 0xE1,
+		0xBB, 0x82, 0xE1, 0xBB, 0x84, 0xE1, 0xBB, 0x86,
+		0xE1, 0xBB, 0x88, 0xE1, 0xBB, 0x8A, 0xE1, 0xBB,
+		0x8C, 0xE1, 0xBB, 0x8E, 0xE1, 0xBB, 0x90, 0xE1,
+		0xBB, 0x92, 0xE1, 0xBB, 0x94, 0xE1, 0xBB, 0x96,
+		0xE1, 0xBB, 0x98, 0xE1, 0xBB, 0x9A, 0xE1, 0xBB,
+		0x9C, 0xE1, 0xBB, 0x9E, 0xE1, 0xBB, 0xA0, 0xE1,
+		0xBB, 0xA2, 0xE1, 0xBB, 0xA4, 0xE1, 0xBB, 0xA6,
+		0xE1, 0xBB, 0xA8, 0xE1, 0xBB, 0xAA, 0xE1, 0xBB,
+		0xAC, 0xE1, 0xBB, 0xAE, 0xE1, 0xBB, 0xB0, 0xE1,
+		0xBB, 0xB2, 0xE1, 0xBB, 0xB4, 0xE1, 0xBB, 0xB6,
+		0xE1, 0xBB, 0xB8, 0xE1, 0xBC, 0x88, 0xE1, 0xBC,
+		0x89, 0xE1, 0xBC, 0x8A, 0xE1, 0xBC, 0x8B, 0xE1,
+		0xBC, 0x8C, 0xE1, 0xBC, 0x8D, 0xE1, 0xBC, 0x8E,
+		0xE1, 0xBC, 0x8F, 0xE1, 0xBC, 0x98, 0xE1, 0xBC,
+		0x99, 0xE1, 0xBC, 0x9A, 0xE1, 0xBC, 0x9B, 0xE1,
+		0xBC, 0x9C, 0xE1, 0xBC, 0x9D, 0xE1, 0xBC, 0xA8,
+		0xE1, 0xBC, 0xA9, 0xE1, 0xBC, 0xAA, 0xE1, 0xBC,
+		0xAB, 0xE1, 0xBC, 0xAC, 0xE1, 0xBC, 0xAD, 0xE1,
+		0xBC, 0xAE, 0xE1, 0xBC, 0xAF, 0xE1, 0xBC, 0xB8,
+		0xE1, 0xBC, 0xB9, 0xE1, 0xBC, 0xBA, 0xE1, 0xBC,
+		0xBB, 0xE1, 0xBC, 0xBC, 0xE1, 0xBC, 0xBD, 0xE1,
+		0xBC, 0xBE, 0xE1, 0xBC, 0xBF, 0xE1, 0xBD, 0x88,
+		0xE1, 0xBD, 0x89, 0xE1, 0xBD, 0x8A, 0xE1, 0xBD,
+		0x8B, 0xE1, 0xBD, 0x8C, 0xE1, 0xBD, 0x8D, 0xE1,
+		0xBD, 0x99, 0xE1, 0xBD, 0x9B, 0xE1, 0xBD, 0x9D,
+		0xE1, 0xBD, 0x9F, 0xE1, 0xBD, 0xA8, 0xE1, 0xBD,
+		0xA9, 0xE1, 0xBD, 0xAA, 0xE1, 0xBD, 0xAB, 0xE1,
+		0xBD, 0xAC, 0xE1, 0xBD, 0xAD, 0xE1, 0xBD, 0xAE,
+		0xE1, 0xBD, 0xAF, 0xE1, 0xBE, 0xBA, 0xE1, 0xBE,
+		0xBB, 0xE1, 0xBF, 0x88, 0xE1, 0xBF, 0x89, 0xE1,
+		0xBF, 0x8A, 0xE1, 0xBF, 0x8B, 0xE1, 0xBF, 0x9A,
+		0xE1, 0xBF, 0x9B, 0xE1, 0xBF, 0xB8, 0xE1, 0xBF,
+		0xB9, 0xE1, 0xBF, 0xAA, 0xE1, 0xBF, 0xAB, 0xE1,
+		0xBF, 0xBA, 0xE1, 0xBF, 0xBB, 0xE1, 0xBE, 0x88,
+		0xE1, 0xBE, 0x89, 0xE1, 0xBE, 0x8A, 0xE1, 0xBE,
+		0x8B, 0xE1, 0xBE, 0x8C, 0xE1, 0xBE, 0x8D, 0xE1,
+		0xBE, 0x8E, 0xE1, 0xBE, 0x8F, 0xE1, 0xBE, 0x98,
+		0xE1, 0xBE, 0x99, 0xE1, 0xBE, 0x9A, 0xE1, 0xBE,
+		0x9B, 0xE1, 0xBE, 0x9C, 0xE1, 0xBE, 0x9D, 0xE1,
+		0xBE, 0x9E, 0xE1, 0xBE, 0x9F, 0xE1, 0xBE, 0xA8,
+		0xE1, 0xBE, 0xA9, 0xE1, 0xBE, 0xAA, 0xE1, 0xBE,
+		0xAB, 0xE1, 0xBE, 0xAC, 0xE1, 0xBE, 0xAD, 0xE1,
+		0xBE, 0xAE, 0xE1, 0xBE, 0xAF, 0xE1, 0xBE, 0xB8,
+		0xE1, 0xBE, 0xB9, 0xE1, 0xBE, 0xBC, 0xCE, 0x99,
+		0xE1, 0xBF, 0x8C, 0xE1, 0xBF, 0x98, 0xE1, 0xBF,
+		0x99, 0xE1, 0xBF, 0xA8, 0xE1, 0xBF, 0xA9, 0xE1,
+		0xBF, 0xAC, 0xE1, 0xBF, 0xBC, 0xE2, 0x85, 0xA0,
+		0xE2, 0x85, 0xA1, 0xE2, 0x85, 0xA2, 0xE2, 0x85,
+		0xA3, 0xE2, 0x85, 0xA4, 0xE2, 0x85, 0xA5, 0xE2,
+		0x85, 0xA6, 0xE2, 0x85, 0xA7, 0xE2, 0x85, 0xA8,
+		0xE2, 0x85, 0xA9, 0xE2, 0x85, 0xAA, 0xE2, 0x85,
+		0xAB, 0xE2, 0x85, 0xAC, 0xE2, 0x85, 0xAD, 0xE2,
+		0x85, 0xAE, 0xE2, 0x85, 0xAF, 0xE2, 0x92, 0xB6,
+		0xE2, 0x92, 0xB7, 0xE2, 0x92, 0xB8, 0xE2, 0x92,
+		0xB9, 0xE2, 0x92, 0xBA, 0xE2, 0x92, 0xBB, 0xE2,
+		0x92, 0xBC, 0xE2, 0x92, 0xBD, 0xE2, 0x92, 0xBE,
+		0xE2, 0x92, 0xBF, 0xE2, 0x93, 0x80, 0xE2, 0x93,
+		0x81, 0xE2, 0x93, 0x82, 0xE2, 0x93, 0x83, 0xE2,
+		0x93, 0x84, 0xE2, 0x93, 0x85, 0xE2, 0x93, 0x86,
+		0xE2, 0x93, 0x87, 0xE2, 0x93, 0x88, 0xE2, 0x93,
+		0x89, 0xE2, 0x93, 0x8A, 0xE2, 0x93, 0x8B, 0xE2,
+		0x93, 0x8C, 0xE2, 0x93, 0x8D, 0xE2, 0x93, 0x8E,
+		0xE2, 0x93, 0x8F, 0xEF, 0xBC, 0xA1, 0xEF, 0xBC,
+		0xA2, 0xEF, 0xBC, 0xA3, 0xEF, 0xBC, 0xA4, 0xEF,
+		0xBC, 0xA5, 0xEF, 0xBC, 0xA6, 0xEF, 0xBC, 0xA7,
+		0xEF, 0xBC, 0xA8, 0xEF, 0xBC, 0xA9, 0xEF, 0xBC,
+		0xAA, 0xEF, 0xBC, 0xAB, 0xEF, 0xBC, 0xAC, 0xEF,
+		0xBC, 0xAD, 0xEF, 0xBC, 0xAE, 0xEF, 0xBC, 0xAF,
+		0xEF, 0xBC, 0xB0, 0xEF, 0xBC, 0xB1, 0xEF, 0xBC,
+		0xB2, 0xEF, 0xBC, 0xB3, 0xEF, 0xBC, 0xB4, 0xEF,
+		0xBC, 0xB5, 0xEF, 0xBC, 0xB6, 0xEF, 0xBC, 0xB7,
+		0xEF, 0xBC, 0xB8, 0xEF, 0xBC, 0xB9, 0xEF, 0xBC,
+		0xBA, 0xF0, 0x90, 0x90, 0x80, 0xF0, 0x90, 0x90,
+		0x81, 0xF0, 0x90, 0x90, 0x82, 0xF0, 0x90, 0x90,
+		0x83, 0xF0, 0x90, 0x90, 0x84, 0xF0, 0x90, 0x90,
+		0x85, 0xF0, 0x90, 0x90, 0x86, 0xF0, 0x90, 0x90,
+		0x87, 0xF0, 0x90, 0x90, 0x88, 0xF0, 0x90, 0x90,
+		0x89, 0xF0, 0x90, 0x90, 0x8A, 0xF0, 0x90, 0x90,
+		0x8B, 0xF0, 0x90, 0x90, 0x8C, 0xF0, 0x90, 0x90,
+		0x8D, 0xF0, 0x90, 0x90, 0x8E, 0xF0, 0x90, 0x90,
+		0x8F, 0xF0, 0x90, 0x90, 0x90, 0xF0, 0x90, 0x90,
+		0x91, 0xF0, 0x90, 0x90, 0x92, 0xF0, 0x90, 0x90,
+		0x93, 0xF0, 0x90, 0x90, 0x94, 0xF0, 0x90, 0x90,
+		0x95, 0xF0, 0x90, 0x90, 0x96, 0xF0, 0x90, 0x90,
+		0x97, 0xF0, 0x90, 0x90, 0x98, 0xF0, 0x90, 0x90,
+		0x99, 0xF0, 0x90, 0x90, 0x9A, 0xF0, 0x90, 0x90,
+		0x9B, 0xF0, 0x90, 0x90, 0x9C, 0xF0, 0x90, 0x90,
+		0x9D, 0xF0, 0x90, 0x90, 0x9E, 0xF0, 0x90, 0x90,
+		0x9F, 0xF0, 0x90, 0x90, 0xA0, 0xF0, 0x90, 0x90,
+		0xA1, 0xF0, 0x90, 0x90, 0xA2, 0xF0, 0x90, 0x90,
+		0xA3, 0xF0, 0x90, 0x90, 0xA4, 0xF0, 0x90, 0x90,
+		0xA5, 0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,
+	},
+	{
+		0xCE, 0x9C, 0xC3, 0x80, 0xC3, 0x81, 0xC3, 0x82,
+		0xC3, 0x83, 0xC3, 0x84, 0xC3, 0x85, 0xC3, 0x86,
+		0xC3, 0x87, 0xC3, 0x88, 0xC3, 0x89, 0xC3, 0x8A,
+		0xC3, 0x8B, 0xC3, 0x8C, 0xC3, 0x8D, 0xC3, 0x8E,
+		0xC3, 0x8F, 0xC3, 0x90, 0xC3, 0x91, 0xC3, 0x92,
+		0xC3, 0x93, 0xC3, 0x94, 0xC3, 0x95, 0xC3, 0x96,
+		0xC3, 0x98, 0xC3, 0x99, 0xC3, 0x9A, 0xC3, 0x9B,
+		0xC3, 0x9C, 0xC3, 0x9D, 0xC3, 0x9E, 0xC5, 0xB8,
+		0xC4, 0x80, 0xC4, 0x82, 0xC4, 0x84, 0xC4, 0x86,
+		0xC4, 0x88, 0xC4, 0x8A, 0xC4, 0x8C, 0xC4, 0x8E,
+		0xC4, 0x90, 0xC4, 0x92, 0xC4, 0x94, 0xC4, 0x96,
+		0xC4, 0x98, 0xC4, 0x9A, 0xC4, 0x9C, 0xC4, 0x9E,
+		0xC4, 0xA0, 0xC4, 0xA2, 0xC4, 0xA4, 0xC4, 0xA6,
+		0xC4, 0xA8, 0xC4, 0xAA, 0xC4, 0xAC, 0xC4, 0xAE,
+		0x49, 0xC4, 0xB2, 0xC4, 0xB4, 0xC4, 0xB6, 0xC4,
+		0xB9, 0xC4, 0xBB, 0xC4, 0xBD, 0xC4, 0xBF, 0xC5,
+		0x81, 0xC5, 0x83, 0xC5, 0x85, 0xC5, 0x87, 0xC5,
+		0x8A, 0xC5, 0x8C, 0xC5, 0x8E, 0xC5, 0x90, 0xC5,
+		0x92, 0xC5, 0x94, 0xC5, 0x96, 0xC5, 0x98, 0xC5,
+		0x9A, 0xC5, 0x9C, 0xC5, 0x9E, 0xC5, 0xA0, 0xC5,
+		0xA2, 0xC5, 0xA4, 0xC5, 0xA6, 0xC5, 0xA8, 0xC5,
+		0xAA, 0xC5, 0xAC, 0xC5, 0xAE, 0xC5, 0xB0, 0xC5,
+		0xB2, 0xC5, 0xB4, 0xC5, 0xB6, 0xC5, 0xB9, 0xC5,
+		0xBB, 0xC5, 0xBD, 0x53, 0xC9, 0x83, 0xC6, 0x82,
+		0xC6, 0x84, 0xC6, 0x87, 0xC6, 0x8B, 0xC6, 0x91,
+		0xC7, 0xB6, 0xC6, 0x98, 0xC8, 0xBD, 0xC8, 0xA0,
+		0xC6, 0xA0, 0xC6, 0xA2, 0xC6, 0xA4, 0xC6, 0xA7,
+		0xC6, 0xAC, 0xC6, 0xAF, 0xC6, 0xB3, 0xC6, 0xB5,
+		0xC6, 0xB8, 0xC6, 0xBC, 0xC7, 0xB7, 0xC7, 0x84,
+		0xC7, 0x84, 0xC7, 0x87, 0xC7, 0x87, 0xC7, 0x8A,
+		0xC7, 0x8A, 0xC7, 0x8D, 0xC7, 0x8F, 0xC7, 0x91,
+		0xC7, 0x93, 0xC7, 0x95, 0xC7, 0x97, 0xC7, 0x99,
+		0xC7, 0x9B, 0xC6, 0x8E, 0xC7, 0x9E, 0xC7, 0xA0,
+		0xC7, 0xA2, 0xC7, 0xA4, 0xC7, 0xA6, 0xC7, 0xA8,
+		0xC7, 0xAA, 0xC7, 0xAC, 0xC7, 0xAE, 0xC7, 0xB1,
+		0xC7, 0xB1, 0xC7, 0xB4, 0xC7, 0xB8, 0xC7, 0xBA,
+		0xC7, 0xBC, 0xC7, 0xBE, 0xC8, 0x80, 0xC8, 0x82,
+		0xC8, 0x84, 0xC8, 0x86, 0xC8, 0x88, 0xC8, 0x8A,
+		0xC8, 0x8C, 0xC8, 0x8E, 0xC8, 0x90, 0xC8, 0x92,
+		0xC8, 0x94, 0xC8, 0x96, 0xC8, 0x98, 0xC8, 0x9A,
+		0xC8, 0x9C, 0xC8, 0x9E, 0xC8, 0xA2, 0xC8, 0xA4,
+		0xC8, 0xA6, 0xC8, 0xA8, 0xC8, 0xAA, 0xC8, 0xAC,
+		0xC8, 0xAE, 0xC8, 0xB0, 0xC8, 0xB2, 0xC8, 0xBB,
+		0xC9, 0x81, 0xC9, 0x86, 0xC9, 0x88, 0xC9, 0x8A,
+		0xC9, 0x8C, 0xC9, 0x8E, 0xC6, 0x81, 0xC6, 0x86,
+		0xC6, 0x89, 0xC6, 0x8A, 0xC6, 0x8F, 0xC6, 0x90,
+		0xC6, 0x93, 0xC6, 0x94, 0xC6, 0x97, 0xC6, 0x96,
+		0xE2, 0xB1, 0xA2, 0xC6, 0x9C, 0xC6, 0x9D, 0xC6,
+		0x9F, 0xE2, 0xB1, 0xA4, 0xC6, 0xA6, 0xC6, 0xA9,
+		0xC6, 0xAE, 0xC9, 0x84, 0xC6, 0xB1, 0xC6, 0xB2,
+		0xC9, 0x85, 0xC6, 0xB7, 0xCE, 0x99, 0xCF, 0xBD,
+		0xCF, 0xBE, 0xCF, 0xBF, 0xCE, 0x86, 0xCE, 0x88,
+		0xCE, 0x89, 0xCE, 0x8A, 0xCE, 0x91, 0xCE, 0x92,
+		0xCE, 0x93, 0xCE, 0x94, 0xCE, 0x95, 0xCE, 0x96,
+		0xCE, 0x97, 0xCE, 0x98, 0xCE, 0x99, 0xCE, 0x9A,
+		0xCE, 0x9B, 0xCE, 0x9C, 0xCE, 0x9D, 0xCE, 0x9E,
+		0xCE, 0x9F, 0xCE, 0xA0, 0xCE, 0xA1, 0xCE, 0xA3,
+		0xCE, 0xA3, 0xCE, 0xA4, 0xCE, 0xA5, 0xCE, 0xA6,
+		0xCE, 0xA7, 0xCE, 0xA8, 0xCE, 0xA9, 0xCE, 0xAA,
+		0xCE, 0xAB, 0xCE, 0x8C, 0xCE, 0x8E, 0xCE, 0x8F,
+		0xCE, 0x92, 0xCE, 0x98, 0xCE, 0xA6, 0xCE, 0xA0,
+		0xCF, 0x98, 0xCF, 0x9A, 0xCF, 0x9C, 0xCF, 0x9E,
+		0xCF, 0xA0, 0xCF, 0xA2, 0xCF, 0xA4, 0xCF, 0xA6,
+		0xCF, 0xA8, 0xCF, 0xAA, 0xCF, 0xAC, 0xCF, 0xAE,
+		0xCE, 0x9A, 0xCE, 0xA1, 0xCF, 0xB9, 0xCE, 0x95,
+		0xCF, 0xB7, 0xCF, 0xBA, 0xD0, 0x90, 0xD0, 0x91,
+		0xD0, 0x92, 0xD0, 0x93, 0xD0, 0x94, 0xD0, 0x95,
+		0xD0, 0x96, 0xD0, 0x97, 0xD0, 0x98, 0xD0, 0x99,
+		0xD0, 0x9A, 0xD0, 0x9B, 0xD0, 0x9C, 0xD0, 0x9D,
+		0xD0, 0x9E, 0xD0, 0x9F, 0xD0, 0xA0, 0xD0, 0xA1,
+		0xD0, 0xA2, 0xD0, 0xA3, 0xD0, 0xA4, 0xD0, 0xA5,
+		0xD0, 0xA6, 0xD0, 0xA7, 0xD0, 0xA8, 0xD0, 0xA9,
+		0xD0, 0xAA, 0xD0, 0xAB, 0xD0, 0xAC, 0xD0, 0xAD,
+		0xD0, 0xAE, 0xD0, 0xAF, 0xD0, 0x80, 0xD0, 0x81,
+		0xD0, 0x82, 0xD0, 0x83, 0xD0, 0x84, 0xD0, 0x85,
+		0xD0, 0x86, 0xD0, 0x87, 0xD0, 0x88, 0xD0, 0x89,
+		0xD0, 0x8A, 0xD0, 0x8B, 0xD0, 0x8C, 0xD0, 0x8D,
+		0xD0, 0x8E, 0xD0, 0x8F, 0xD1, 0xA0, 0xD1, 0xA2,
+		0xD1, 0xA4, 0xD1, 0xA6, 0xD1, 0xA8, 0xD1, 0xAA,
+		0xD1, 0xAC, 0xD1, 0xAE, 0xD1, 0xB0, 0xD1, 0xB2,
+		0xD1, 0xB4, 0xD1, 0xB6, 0xD1, 0xB8, 0xD1, 0xBA,
+		0xD1, 0xBC, 0xD1, 0xBE, 0xD2, 0x80, 0xD2, 0x8A,
+		0xD2, 0x8C, 0xD2, 0x8E, 0xD2, 0x90, 0xD2, 0x92,
+		0xD2, 0x94, 0xD2, 0x96, 0xD2, 0x98, 0xD2, 0x9A,
+		0xD2, 0x9C, 0xD2, 0x9E, 0xD2, 0xA0, 0xD2, 0xA2,
+		0xD2, 0xA4, 0xD2, 0xA6, 0xD2, 0xA8, 0xD2, 0xAA,
+		0xD2, 0xAC, 0xD2, 0xAE, 0xD2, 0xB0, 0xD2, 0xB2,
+		0xD2, 0xB4, 0xD2, 0xB6, 0xD2, 0xB8, 0xD2, 0xBA,
+		0xD2, 0xBC, 0xD2, 0xBE, 0xD3, 0x81, 0xD3, 0x83,
+		0xD3, 0x85, 0xD3, 0x87, 0xD3, 0x89, 0xD3, 0x8B,
+		0xD3, 0x8D, 0xD3, 0x80, 0xD3, 0x90, 0xD3, 0x92,
+		0xD3, 0x94, 0xD3, 0x96, 0xD3, 0x98, 0xD3, 0x9A,
+		0xD3, 0x9C, 0xD3, 0x9E, 0xD3, 0xA0, 0xD3, 0xA2,
+		0xD3, 0xA4, 0xD3, 0xA6, 0xD3, 0xA8, 0xD3, 0xAA,
+		0xD3, 0xAC, 0xD3, 0xAE, 0xD3, 0xB0, 0xD3, 0xB2,
+		0xD3, 0xB4, 0xD3, 0xB6, 0xD3, 0xB8, 0xD3, 0xBA,
+		0xD3, 0xBC, 0xD3, 0xBE, 0xD4, 0x80, 0xD4, 0x82,
+		0xD4, 0x84, 0xD4, 0x86, 0xD4, 0x88, 0xD4, 0x8A,
+		0xD4, 0x8C, 0xD4, 0x8E, 0xD4, 0x90, 0xD4, 0x92,
+		0xD4, 0xB1, 0xD4, 0xB2, 0xD4, 0xB3, 0xD4, 0xB4,
+		0xD4, 0xB5, 0xD4, 0xB6, 0xD4, 0xB7, 0xD4, 0xB8,
+		0xD4, 0xB9, 0xD4, 0xBA, 0xD4, 0xBB, 0xD4, 0xBC,
+		0xD4, 0xBD, 0xD4, 0xBE, 0xD4, 0xBF, 0xD5, 0x80,
+		0xD5, 0x81, 0xD5, 0x82, 0xD5, 0x83, 0xD5, 0x84,
+		0xD5, 0x85, 0xD5, 0x86, 0xD5, 0x87, 0xD5, 0x88,
+		0xD5, 0x89, 0xD5, 0x8A, 0xD5, 0x8B, 0xD5, 0x8C,
+		0xD5, 0x8D, 0xD5, 0x8E, 0xD5, 0x8F, 0xD5, 0x90,
+		0xD5, 0x91, 0xD5, 0x92, 0xD5, 0x93, 0xD5, 0x94,
+		0xD5, 0x95, 0xD5, 0x96, 0xE2, 0xB1, 0xA3, 0xE1,
+		0xB8, 0x80, 0xE1, 0xB8, 0x82, 0xE1, 0xB8, 0x84,
+		0xE1, 0xB8, 0x86, 0xE1, 0xB8, 0x88, 0xE1, 0xB8,
+		0x8A, 0xE1, 0xB8, 0x8C, 0xE1, 0xB8, 0x8E, 0xE1,
+		0xB8, 0x90, 0xE1, 0xB8, 0x92, 0xE1, 0xB8, 0x94,
+		0xE1, 0xB8, 0x96, 0xE1, 0xB8, 0x98, 0xE1, 0xB8,
+		0x9A, 0xE1, 0xB8, 0x9C, 0xE1, 0xB8, 0x9E, 0xE1,
+		0xB8, 0xA0, 0xE1, 0xB8, 0xA2, 0xE1, 0xB8, 0xA4,
+		0xE1, 0xB8, 0xA6, 0xE1, 0xB8, 0xA8, 0xE1, 0xB8,
+		0xAA, 0xE1, 0xB8, 0xAC, 0xE1, 0xB8, 0xAE, 0xE1,
+		0xB8, 0xB0, 0xE1, 0xB8, 0xB2, 0xE1, 0xB8, 0xB4,
+		0xE1, 0xB8, 0xB6, 0xE1, 0xB8, 0xB8, 0xE1, 0xB8,
+		0xBA, 0xE1, 0xB8, 0xBC, 0xE1, 0xB8, 0xBE, 0xE1,
+		0xB9, 0x80, 0xE1, 0xB9, 0x82, 0xE1, 0xB9, 0x84,
+		0xE1, 0xB9, 0x86, 0xE1, 0xB9, 0x88, 0xE1, 0xB9,
+		0x8A, 0xE1, 0xB9, 0x8C, 0xE1, 0xB9, 0x8E, 0xE1,
+		0xB9, 0x90, 0xE1, 0xB9, 0x92, 0xE1, 0xB9, 0x94,
+		0xE1, 0xB9, 0x96, 0xE1, 0xB9, 0x98, 0xE1, 0xB9,
+		0x9A, 0xE1, 0xB9, 0x9C, 0xE1, 0xB9, 0x9E, 0xE1,
+		0xB9, 0xA0, 0xE1, 0xB9, 0xA2, 0xE1, 0xB9, 0xA4,
+		0xE1, 0xB9, 0xA6, 0xE1, 0xB9, 0xA8, 0xE1, 0xB9,
+		0xAA, 0xE1, 0xB9, 0xAC, 0xE1, 0xB9, 0xAE, 0xE1,
+		0xB9, 0xB0, 0xE1, 0xB9, 0xB2, 0xE1, 0xB9, 0xB4,
+		0xE1, 0xB9, 0xB6, 0xE1, 0xB9, 0xB8, 0xE1, 0xB9,
+		0xBA, 0xE1, 0xB9, 0xBC, 0xE1, 0xB9, 0xBE, 0xE1,
+		0xBA, 0x80, 0xE1, 0xBA, 0x82, 0xE1, 0xBA, 0x84,
+		0xE1, 0xBA, 0x86, 0xE1, 0xBA, 0x88, 0xE1, 0xBA,
+		0x8A, 0xE1, 0xBA, 0x8C, 0xE1, 0xBA, 0x8E, 0xE1,
+		0xBA, 0x90, 0xE1, 0xBA, 0x92, 0xE1, 0xBA, 0x94,
+		0xE1, 0xB9, 0xA0, 0xE1, 0xBA, 0xA0, 0xE1, 0xBA,
+		0xA2, 0xE1, 0xBA, 0xA4, 0xE1, 0xBA, 0xA6, 0xE1,
+		0xBA, 0xA8, 0xE1, 0xBA, 0xAA, 0xE1, 0xBA, 0xAC,
+		0xE1, 0xBA, 0xAE, 0xE1, 0xBA, 0xB0, 0xE1, 0xBA,
+		0xB2, 0xE1, 0xBA, 0xB4, 0xE1, 0xBA, 0xB6, 0xE1,
+		0xBA, 0xB8, 0xE1, 0xBA, 0xBA, 0xE1, 0xBA, 0xBC,
+		0xE1, 0xBA, 0xBE, 0xE1, 0xBB, 0x80, 0xE1, 0xBB,
+		0x82, 0xE1, 0xBB, 0x84, 0xE1, 0xBB, 0x86, 0xE1,
+		0xBB, 0x88, 0xE1, 0xBB, 0x8A, 0xE1, 0xBB, 0x8C,
+		0xE1, 0xBB, 0x8E, 0xE1, 0xBB, 0x90, 0xE1, 0xBB,
+		0x92, 0xE1, 0xBB, 0x94, 0xE1, 0xBB, 0x96, 0xE1,
+		0xBB, 0x98, 0xE1, 0xBB, 0x9A, 0xE1, 0xBB, 0x9C,
+		0xE1, 0xBB, 0x9E, 0xE1, 0xBB, 0xA0, 0xE1, 0xBB,
+		0xA2, 0xE1, 0xBB, 0xA4, 0xE1, 0xBB, 0xA6, 0xE1,
+		0xBB, 0xA8, 0xE1, 0xBB, 0xAA, 0xE1, 0xBB, 0xAC,
+		0xE1, 0xBB, 0xAE, 0xE1, 0xBB, 0xB0, 0xE1, 0xBB,
+		0xB2, 0xE1, 0xBB, 0xB4, 0xE1, 0xBB, 0xB6, 0xE1,
+		0xBB, 0xB8, 0xE1, 0xBC, 0x88, 0xE1, 0xBC, 0x89,
+		0xE1, 0xBC, 0x8A, 0xE1, 0xBC, 0x8B, 0xE1, 0xBC,
+		0x8C, 0xE1, 0xBC, 0x8D, 0xE1, 0xBC, 0x8E, 0xE1,
+		0xBC, 0x8F, 0xE1, 0xBC, 0x98, 0xE1, 0xBC, 0x99,
+		0xE1, 0xBC, 0x9A, 0xE1, 0xBC, 0x9B, 0xE1, 0xBC,
+		0x9C, 0xE1, 0xBC, 0x9D, 0xE1, 0xBC, 0xA8, 0xE1,
+		0xBC, 0xA9, 0xE1, 0xBC, 0xAA, 0xE1, 0xBC, 0xAB,
+		0xE1, 0xBC, 0xAC, 0xE1, 0xBC, 0xAD, 0xE1, 0xBC,
+		0xAE, 0xE1, 0xBC, 0xAF, 0xE1, 0xBC, 0xB8, 0xE1,
+		0xBC, 0xB9, 0xE1, 0xBC, 0xBA, 0xE1, 0xBC, 0xBB,
+		0xE1, 0xBC, 0xBC, 0xE1, 0xBC, 0xBD, 0xE1, 0xBC,
+		0xBE, 0xE1, 0xBC, 0xBF, 0xE1, 0xBD, 0x88, 0xE1,
+		0xBD, 0x89, 0xE1, 0xBD, 0x8A, 0xE1, 0xBD, 0x8B,
+		0xE1, 0xBD, 0x8C, 0xE1, 0xBD, 0x8D, 0xE1, 0xBD,
+		0x99, 0xE1, 0xBD, 0x9B, 0xE1, 0xBD, 0x9D, 0xE1,
+		0xBD, 0x9F, 0xE1, 0xBD, 0xA8, 0xE1, 0xBD, 0xA9,
+		0xE1, 0xBD, 0xAA, 0xE1, 0xBD, 0xAB, 0xE1, 0xBD,
+		0xAC, 0xE1, 0xBD, 0xAD, 0xE1, 0xBD, 0xAE, 0xE1,
+		0xBD, 0xAF, 0xE1, 0xBE, 0xBA, 0xE1, 0xBE, 0xBB,
+		0xE1, 0xBF, 0x88, 0xE1, 0xBF, 0x89, 0xE1, 0xBF,
+		0x8A, 0xE1, 0xBF, 0x8B, 0xE1, 0xBF, 0x9A, 0xE1,
+		0xBF, 0x9B, 0xE1, 0xBF, 0xB8, 0xE1, 0xBF, 0xB9,
+		0xE1, 0xBF, 0xAA, 0xE1, 0xBF, 0xAB, 0xE1, 0xBF,
+		0xBA, 0xE1, 0xBF, 0xBB, 0xE1, 0xBE, 0x88, 0xE1,
+		0xBE, 0x89, 0xE1, 0xBE, 0x8A, 0xE1, 0xBE, 0x8B,
+		0xE1, 0xBE, 0x8C, 0xE1, 0xBE, 0x8D, 0xE1, 0xBE,
+		0x8E, 0xE1, 0xBE, 0x8F, 0xE1, 0xBE, 0x98, 0xE1,
+		0xBE, 0x99, 0xE1, 0xBE, 0x9A, 0xE1, 0xBE, 0x9B,
+		0xE1, 0xBE, 0x9C, 0xE1, 0xBE, 0x9D, 0xE1, 0xBE,
+		0x9E, 0xE1, 0xBE, 0x9F, 0xE1, 0xBE, 0xA8, 0xE1,
+		0xBE, 0xA9, 0xE1, 0xBE, 0xAA, 0xE1, 0xBE, 0xAB,
+		0xE1, 0xBE, 0xAC, 0xE1, 0xBE, 0xAD, 0xE1, 0xBE,
+		0xAE, 0xE1, 0xBE, 0xAF, 0xE1, 0xBE, 0xB8, 0xE1,
+		0xBE, 0xB9, 0xE1, 0xBE, 0xBC, 0xCE, 0x99, 0xE1,
+		0xBF, 0x8C, 0xE1, 0xBF, 0x98, 0xE1, 0xBF, 0x99,
+		0xE1, 0xBF, 0xA8, 0xE1, 0xBF, 0xA9, 0xE1, 0xBF,
+		0xAC, 0xE1, 0xBF, 0xBC, 0xE2, 0x84, 0xB2, 0xE2,
+		0x85, 0xA0, 0xE2, 0x85, 0xA1, 0xE2, 0x85, 0xA2,
+		0xE2, 0x85, 0xA3, 0xE2, 0x85, 0xA4, 0xE2, 0x85,
+		0xA5, 0xE2, 0x85, 0xA6, 0xE2, 0x85, 0xA7, 0xE2,
+		0x85, 0xA8, 0xE2, 0x85, 0xA9, 0xE2, 0x85, 0xAA,
+		0xE2, 0x85, 0xAB, 0xE2, 0x85, 0xAC, 0xE2, 0x85,
+		0xAD, 0xE2, 0x85, 0xAE, 0xE2, 0x85, 0xAF, 0xE2,
+		0x86, 0x83, 0xE2, 0x92, 0xB6, 0xE2, 0x92, 0xB7,
+		0xE2, 0x92, 0xB8, 0xE2, 0x92, 0xB9, 0xE2, 0x92,
+		0xBA, 0xE2, 0x92, 0xBB, 0xE2, 0x92, 0xBC, 0xE2,
+		0x92, 0xBD, 0xE2, 0x92, 0xBE, 0xE2, 0x92, 0xBF,
+		0xE2, 0x93, 0x80, 0xE2, 0x93, 0x81, 0xE2, 0x93,
+		0x82, 0xE2, 0x93, 0x83, 0xE2, 0x93, 0x84, 0xE2,
+		0x93, 0x85, 0xE2, 0x93, 0x86, 0xE2, 0x93, 0x87,
+		0xE2, 0x93, 0x88, 0xE2, 0x93, 0x89, 0xE2, 0x93,
+		0x8A, 0xE2, 0x93, 0x8B, 0xE2, 0x93, 0x8C, 0xE2,
+		0x93, 0x8D, 0xE2, 0x93, 0x8E, 0xE2, 0x93, 0x8F,
+		0xE2, 0xB0, 0x80, 0xE2, 0xB0, 0x81, 0xE2, 0xB0,
+		0x82, 0xE2, 0xB0, 0x83, 0xE2, 0xB0, 0x84, 0xE2,
+		0xB0, 0x85, 0xE2, 0xB0, 0x86, 0xE2, 0xB0, 0x87,
+		0xE2, 0xB0, 0x88, 0xE2, 0xB0, 0x89, 0xE2, 0xB0,
+		0x8A, 0xE2, 0xB0, 0x8B, 0xE2, 0xB0, 0x8C, 0xE2,
+		0xB0, 0x8D, 0xE2, 0xB0, 0x8E, 0xE2, 0xB0, 0x8F,
+		0xE2, 0xB0, 0x90, 0xE2, 0xB0, 0x91, 0xE2, 0xB0,
+		0x92, 0xE2, 0xB0, 0x93, 0xE2, 0xB0, 0x94, 0xE2,
+		0xB0, 0x95, 0xE2, 0xB0, 0x96, 0xE2, 0xB0, 0x97,
+		0xE2, 0xB0, 0x98, 0xE2, 0xB0, 0x99, 0xE2, 0xB0,
+		0x9A, 0xE2, 0xB0, 0x9B, 0xE2, 0xB0, 0x9C, 0xE2,
+		0xB0, 0x9D, 0xE2, 0xB0, 0x9E, 0xE2, 0xB0, 0x9F,
+		0xE2, 0xB0, 0xA0, 0xE2, 0xB0, 0xA1, 0xE2, 0xB0,
+		0xA2, 0xE2, 0xB0, 0xA3, 0xE2, 0xB0, 0xA4, 0xE2,
+		0xB0, 0xA5, 0xE2, 0xB0, 0xA6, 0xE2, 0xB0, 0xA7,
+		0xE2, 0xB0, 0xA8, 0xE2, 0xB0, 0xA9, 0xE2, 0xB0,
+		0xAA, 0xE2, 0xB0, 0xAB, 0xE2, 0xB0, 0xAC, 0xE2,
+		0xB0, 0xAD, 0xE2, 0xB0, 0xAE, 0xE2, 0xB1, 0xA0,
+		0xC8, 0xBA, 0xC8, 0xBE, 0xE2, 0xB1, 0xA7, 0xE2,
+		0xB1, 0xA9, 0xE2, 0xB1, 0xAB, 0xE2, 0xB1, 0xB5,
+		0xE2, 0xB2, 0x80, 0xE2, 0xB2, 0x82, 0xE2, 0xB2,
+		0x84, 0xE2, 0xB2, 0x86, 0xE2, 0xB2, 0x88, 0xE2,
+		0xB2, 0x8A, 0xE2, 0xB2, 0x8C, 0xE2, 0xB2, 0x8E,
+		0xE2, 0xB2, 0x90, 0xE2, 0xB2, 0x92, 0xE2, 0xB2,
+		0x94, 0xE2, 0xB2, 0x96, 0xE2, 0xB2, 0x98, 0xE2,
+		0xB2, 0x9A, 0xE2, 0xB2, 0x9C, 0xE2, 0xB2, 0x9E,
+		0xE2, 0xB2, 0xA0, 0xE2, 0xB2, 0xA2, 0xE2, 0xB2,
+		0xA4, 0xE2, 0xB2, 0xA6, 0xE2, 0xB2, 0xA8, 0xE2,
+		0xB2, 0xAA, 0xE2, 0xB2, 0xAC, 0xE2, 0xB2, 0xAE,
+		0xE2, 0xB2, 0xB0, 0xE2, 0xB2, 0xB2, 0xE2, 0xB2,
+		0xB4, 0xE2, 0xB2, 0xB6, 0xE2, 0xB2, 0xB8, 0xE2,
+		0xB2, 0xBA, 0xE2, 0xB2, 0xBC, 0xE2, 0xB2, 0xBE,
+		0xE2, 0xB3, 0x80, 0xE2, 0xB3, 0x82, 0xE2, 0xB3,
+		0x84, 0xE2, 0xB3, 0x86, 0xE2, 0xB3, 0x88, 0xE2,
+		0xB3, 0x8A, 0xE2, 0xB3, 0x8C, 0xE2, 0xB3, 0x8E,
+		0xE2, 0xB3, 0x90, 0xE2, 0xB3, 0x92, 0xE2, 0xB3,
+		0x94, 0xE2, 0xB3, 0x96, 0xE2, 0xB3, 0x98, 0xE2,
+		0xB3, 0x9A, 0xE2, 0xB3, 0x9C, 0xE2, 0xB3, 0x9E,
+		0xE2, 0xB3, 0xA0, 0xE2, 0xB3, 0xA2, 0xE1, 0x82,
+		0xA0, 0xE1, 0x82, 0xA1, 0xE1, 0x82, 0xA2, 0xE1,
+		0x82, 0xA3, 0xE1, 0x82, 0xA4, 0xE1, 0x82, 0xA5,
+		0xE1, 0x82, 0xA6, 0xE1, 0x82, 0xA7, 0xE1, 0x82,
+		0xA8, 0xE1, 0x82, 0xA9, 0xE1, 0x82, 0xAA, 0xE1,
+		0x82, 0xAB, 0xE1, 0x82, 0xAC, 0xE1, 0x82, 0xAD,
+		0xE1, 0x82, 0xAE, 0xE1, 0x82, 0xAF, 0xE1, 0x82,
+		0xB0, 0xE1, 0x82, 0xB1, 0xE1, 0x82, 0xB2, 0xE1,
+		0x82, 0xB3, 0xE1, 0x82, 0xB4, 0xE1, 0x82, 0xB5,
+		0xE1, 0x82, 0xB6, 0xE1, 0x82, 0xB7, 0xE1, 0x82,
+		0xB8, 0xE1, 0x82, 0xB9, 0xE1, 0x82, 0xBA, 0xE1,
+		0x82, 0xBB, 0xE1, 0x82, 0xBC, 0xE1, 0x82, 0xBD,
+		0xE1, 0x82, 0xBE, 0xE1, 0x82, 0xBF, 0xE1, 0x83,
+		0x80, 0xE1, 0x83, 0x81, 0xE1, 0x83, 0x82, 0xE1,
+		0x83, 0x83, 0xE1, 0x83, 0x84, 0xE1, 0x83, 0x85,
+		0xEF, 0xBC, 0xA1, 0xEF, 0xBC, 0xA2, 0xEF, 0xBC,
+		0xA3, 0xEF, 0xBC, 0xA4, 0xEF, 0xBC, 0xA5, 0xEF,
+		0xBC, 0xA6, 0xEF, 0xBC, 0xA7, 0xEF, 0xBC, 0xA8,
+		0xEF, 0xBC, 0xA9, 0xEF, 0xBC, 0xAA, 0xEF, 0xBC,
+		0xAB, 0xEF, 0xBC, 0xAC, 0xEF, 0xBC, 0xAD, 0xEF,
+		0xBC, 0xAE, 0xEF, 0xBC, 0xAF, 0xEF, 0xBC, 0xB0,
+		0xEF, 0xBC, 0xB1, 0xEF, 0xBC, 0xB2, 0xEF, 0xBC,
+		0xB3, 0xEF, 0xBC, 0xB4, 0xEF, 0xBC, 0xB5, 0xEF,
+		0xBC, 0xB6, 0xEF, 0xBC, 0xB7, 0xEF, 0xBC, 0xB8,
+		0xEF, 0xBC, 0xB9, 0xEF, 0xBC, 0xBA, 0xF0, 0x90,
+		0x90, 0x80, 0xF0, 0x90, 0x90, 0x81, 0xF0, 0x90,
+		0x90, 0x82, 0xF0, 0x90, 0x90, 0x83, 0xF0, 0x90,
+		0x90, 0x84, 0xF0, 0x90, 0x90, 0x85, 0xF0, 0x90,
+		0x90, 0x86, 0xF0, 0x90, 0x90, 0x87, 0xF0, 0x90,
+		0x90, 0x88, 0xF0, 0x90, 0x90, 0x89, 0xF0, 0x90,
+		0x90, 0x8A, 0xF0, 0x90, 0x90, 0x8B, 0xF0, 0x90,
+		0x90, 0x8C, 0xF0, 0x90, 0x90, 0x8D, 0xF0, 0x90,
+		0x90, 0x8E, 0xF0, 0x90, 0x90, 0x8F, 0xF0, 0x90,
+		0x90, 0x90, 0xF0, 0x90, 0x90, 0x91, 0xF0, 0x90,
+		0x90, 0x92, 0xF0, 0x90, 0x90, 0x93, 0xF0, 0x90,
+		0x90, 0x94, 0xF0, 0x90, 0x90, 0x95, 0xF0, 0x90,
+		0x90, 0x96, 0xF0, 0x90, 0x90, 0x97, 0xF0, 0x90,
+		0x90, 0x98, 0xF0, 0x90, 0x90, 0x99, 0xF0, 0x90,
+		0x90, 0x9A, 0xF0, 0x90, 0x90, 0x9B, 0xF0, 0x90,
+		0x90, 0x9C, 0xF0, 0x90, 0x90, 0x9D, 0xF0, 0x90,
+		0x90, 0x9E, 0xF0, 0x90, 0x90, 0x9F, 0xF0, 0x90,
+		0x90, 0xA0, 0xF0, 0x90, 0x90, 0xA1, 0xF0, 0x90,
+		0x90, 0xA2, 0xF0, 0x90, 0x90, 0xA3, 0xF0, 0x90,
+		0x90, 0xA4, 0xF0, 0x90, 0x90, 0xA5, 0xF0, 0x90,
+		0x90, 0xA6, 0xF0, 0x90, 0x90, 0xA7,
+	},
+};
+
+#undef	N_
+#undef	FIL_
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* _SYS_U8_TEXTPREP_DATA_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/include/sys/uberblock.h
@@ -0,0 +1,49 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * Copyright (c) 2014 by Delphix. All rights reserved.
+ */
+
+#ifndef _SYS_UBERBLOCK_H
+#define	_SYS_UBERBLOCK_H
+
+#include <sys/spa.h>
+#include <sys/vdev.h>
+#include <sys/zio.h>
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+typedef struct uberblock uberblock_t;
+
+extern int uberblock_verify(uberblock_t *);
+extern boolean_t uberblock_update(uberblock_t *, vdev_t *, uint64_t);
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* _SYS_UBERBLOCK_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/include/sys/uberblock_impl.h
@@ -0,0 +1,63 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ */
+
+#ifndef _SYS_UBERBLOCK_IMPL_H
+#define	_SYS_UBERBLOCK_IMPL_H
+
+#include <sys/uberblock.h>
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+/*
+ * The uberblock version is incremented whenever an incompatible on-disk
+ * format change is made to the SPA, DMU, or ZAP.
+ *
+ * Note: the first two fields should never be moved.  When a storage pool
+ * is opened, the uberblock must be read off the disk before the version
+ * can be checked.  If the ub_version field is moved, we may not detect
+ * version mismatch.  If the ub_magic field is moved, applications that
+ * expect the magic number in the first word won't work.
+ */
+#define	UBERBLOCK_MAGIC		0x00bab10c		/* oo-ba-bloc!	*/
+#define	UBERBLOCK_SHIFT		10			/* up to 1K	*/
+
+struct uberblock {
+	uint64_t	ub_magic;	/* UBERBLOCK_MAGIC		*/
+	uint64_t	ub_version;	/* SPA_VERSION			*/
+	uint64_t	ub_txg;		/* txg of last sync		*/
+	uint64_t	ub_guid_sum;	/* sum of all vdev guids	*/
+	uint64_t	ub_timestamp;	/* UTC time of last sync	*/
+	blkptr_t	ub_rootbp;	/* MOS objset_phys_t		*/
+
+	/* highest SPA_VERSION supported by software that wrote this txg */
+	uint64_t	ub_software_version;
+};
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* _SYS_UBERBLOCK_IMPL_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/include/sys/uio_impl.h
@@ -0,0 +1,49 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
+/*	  All Rights Reserved	*/
+
+/*
+ * University Copyright- Copyright (c) 1982, 1986, 1988
+ * The Regents of the University of California
+ * All Rights Reserved
+ *
+ * University Acknowledgment- Portions of this document are derived from
+ * software developed by the University of California, Berkeley, and its
+ * contributors.
+ */
+
+#ifndef _SYS_UIO_IMPL_H
+#define	_SYS_UIO_IMPL_H
+
+#include <sys/uio.h>
+
+extern int uiomove(void *, size_t, enum uio_rw, uio_t *);
+extern void uio_prefaultpages(ssize_t, uio_t *);
+extern int uiocopy(void *, size_t, enum uio_rw, uio_t *, size_t *);
+extern void uioskip(uio_t *, size_t);
+
+#endif	/* _SYS_UIO_IMPL_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/include/sys/unique.h
@@ -0,0 +1,57 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef	_SYS_UNIQUE_H
+#define	_SYS_UNIQUE_H
+
+#include <sys/zfs_context.h>
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+/* The number of significant bits in each unique value. */
+#define	UNIQUE_BITS	56
+
+void unique_init(void);
+void unique_fini(void);
+
+/*
+ * Return a new unique value (which will not be uniquified against until
+ * it is unique_insert()-ed).
+ */
+uint64_t unique_create(void);
+
+/* Return a unique value, which equals the one passed in if possible. */
+uint64_t unique_insert(uint64_t value);
+
+/* Indicate that this value no longer needs to be uniquified against. */
+void unique_remove(uint64_t value);
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif /* _SYS_UNIQUE_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/include/sys/uuid.h
@@ -0,0 +1,94 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License").  You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef	_SYS_UUID_H
+#define	_SYS_UUID_H
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+/*
+ * The copyright in this file is taken from the original Leach
+ * & Salz UUID specification, from which this implementation
+ * is derived.
+ */
+
+/*
+ * Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc.
+ * Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. &
+ * Digital Equipment Corporation, Maynard, Mass.  Copyright (c) 1998
+ * Microsoft.  To anyone who acknowledges that this file is provided
+ * "AS IS" without any express or implied warranty: permission to use,
+ * copy, modify, and distribute this file for any purpose is hereby
+ * granted without fee, provided that the above copyright notices and
+ * this notice appears in all source code copies, and that none of the
+ * names of Open Software Foundation, Inc., Hewlett-Packard Company,
+ * or Digital Equipment Corporation be used in advertising or
+ * publicity pertaining to distribution of the software without
+ * specific, written prior permission.  Neither Open Software
+ * Foundation, Inc., Hewlett-Packard Company, Microsoft, nor Digital
+ * Equipment Corporation makes any representations about the
+ * suitability of this software for any purpose.
+ */
+
+#include <sys/types.h>
+#include <sys/byteorder.h>
+
+typedef struct {
+	uint8_t		nodeID[6];
+} uuid_node_t;
+
+/*
+ * The uuid type used throughout when referencing uuids themselves
+ */
+struct uuid {
+	uint32_t	time_low;
+	uint16_t	time_mid;
+	uint16_t	time_hi_and_version;
+	uint8_t		clock_seq_hi_and_reserved;
+	uint8_t		clock_seq_low;
+	uint8_t		node_addr[6];
+};
+
+#define	UUID_PRINTABLE_STRING_LENGTH 37
+
+/*
+ * Convert a uuid to/from little-endian format
+ */
+#define	UUID_LE_CONVERT(dest, src)					\
+{									\
+	(dest) = (src);							\
+	(dest).time_low = LE_32((dest).time_low);			\
+	(dest).time_mid = LE_16((dest).time_mid);			\
+	(dest).time_hi_and_version = LE_16((dest).time_hi_and_version);	\
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _SYS_UUID_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/include/sys/vdev.h
@@ -0,0 +1,164 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013 by Delphix. All rights reserved.
+ */
+
+#ifndef _SYS_VDEV_H
+#define	_SYS_VDEV_H
+
+#include <sys/spa.h>
+#include <sys/zio.h>
+#include <sys/dmu.h>
+#include <sys/space_map.h>
+#include <sys/fs/zfs.h>
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+typedef enum vdev_dtl_type {
+	DTL_MISSING,	/* 0% replication: no copies of the data */
+	DTL_PARTIAL,	/* less than 100% replication: some copies missing */
+	DTL_SCRUB,	/* unable to fully repair during scrub/resilver */
+	DTL_OUTAGE,	/* temporarily missing (used to attempt detach) */
+	DTL_TYPES
+} vdev_dtl_type_t;
+
+extern int zfs_nocacheflush;
+
+extern int vdev_open(vdev_t *);
+extern void vdev_open_children(vdev_t *);
+extern int vdev_validate(vdev_t *, boolean_t);
+extern void vdev_close(vdev_t *);
+extern int vdev_create(vdev_t *, uint64_t txg, boolean_t isreplace);
+extern void vdev_reopen(vdev_t *);
+extern int vdev_validate_aux(vdev_t *vd);
+extern zio_t *vdev_probe(vdev_t *vd, zio_t *pio);
+
+extern boolean_t vdev_is_bootable(vdev_t *vd);
+extern vdev_t *vdev_lookup_top(spa_t *spa, uint64_t vdev);
+extern vdev_t *vdev_lookup_by_guid(vdev_t *vd, uint64_t guid);
+extern int vdev_count_leaves(spa_t *spa);
+extern void vdev_dtl_dirty(vdev_t *vd, vdev_dtl_type_t d,
+    uint64_t txg, uint64_t size);
+extern boolean_t vdev_dtl_contains(vdev_t *vd, vdev_dtl_type_t d,
+    uint64_t txg, uint64_t size);
+extern boolean_t vdev_dtl_empty(vdev_t *vd, vdev_dtl_type_t d);
+extern void vdev_dtl_reassess(vdev_t *vd, uint64_t txg, uint64_t scrub_txg,
+    int scrub_done);
+extern boolean_t vdev_dtl_required(vdev_t *vd);
+extern boolean_t vdev_resilver_needed(vdev_t *vd,
+    uint64_t *minp, uint64_t *maxp);
+
+extern void vdev_hold(vdev_t *);
+extern void vdev_rele(vdev_t *);
+
+extern int vdev_metaslab_init(vdev_t *vd, uint64_t txg);
+extern void vdev_metaslab_fini(vdev_t *vd);
+extern void vdev_metaslab_set_size(vdev_t *);
+extern void vdev_expand(vdev_t *vd, uint64_t txg);
+extern void vdev_split(vdev_t *vd);
+extern void vdev_deadman(vdev_t *vd);
+
+
+extern void vdev_get_stats(vdev_t *vd, vdev_stat_t *vs);
+extern void vdev_clear_stats(vdev_t *vd);
+extern void vdev_stat_update(zio_t *zio, uint64_t psize);
+extern void vdev_scan_stat_init(vdev_t *vd);
+extern void vdev_propagate_state(vdev_t *vd);
+extern void vdev_set_state(vdev_t *vd, boolean_t isopen, vdev_state_t state,
+    vdev_aux_t aux);
+
+extern void vdev_space_update(vdev_t *vd,
+    int64_t alloc_delta, int64_t defer_delta, int64_t space_delta);
+
+extern uint64_t vdev_psize_to_asize(vdev_t *vd, uint64_t psize);
+
+extern int vdev_fault(spa_t *spa, uint64_t guid, vdev_aux_t aux);
+extern int vdev_degrade(spa_t *spa, uint64_t guid, vdev_aux_t aux);
+extern int vdev_online(spa_t *spa, uint64_t guid, uint64_t flags,
+    vdev_state_t *);
+extern int vdev_offline(spa_t *spa, uint64_t guid, uint64_t flags);
+extern void vdev_clear(spa_t *spa, vdev_t *vd);
+
+extern boolean_t vdev_is_dead(vdev_t *vd);
+extern boolean_t vdev_readable(vdev_t *vd);
+extern boolean_t vdev_writeable(vdev_t *vd);
+extern boolean_t vdev_allocatable(vdev_t *vd);
+extern boolean_t vdev_accessible(vdev_t *vd, zio_t *zio);
+
+extern void vdev_cache_init(vdev_t *vd);
+extern void vdev_cache_fini(vdev_t *vd);
+extern boolean_t vdev_cache_read(zio_t *zio);
+extern void vdev_cache_write(zio_t *zio);
+extern void vdev_cache_purge(vdev_t *vd);
+
+extern void vdev_queue_init(vdev_t *vd);
+extern void vdev_queue_fini(vdev_t *vd);
+extern zio_t *vdev_queue_io(zio_t *zio);
+extern void vdev_queue_io_done(zio_t *zio);
+
+extern void vdev_config_dirty(vdev_t *vd);
+extern void vdev_config_clean(vdev_t *vd);
+extern int vdev_config_sync(vdev_t **svd, int svdcount, uint64_t txg,
+    boolean_t);
+
+extern void vdev_state_dirty(vdev_t *vd);
+extern void vdev_state_clean(vdev_t *vd);
+
+typedef enum vdev_config_flag {
+	VDEV_CONFIG_SPARE = 1 << 0,
+	VDEV_CONFIG_L2CACHE = 1 << 1,
+	VDEV_CONFIG_REMOVING = 1 << 2
+} vdev_config_flag_t;
+
+extern void vdev_top_config_generate(spa_t *spa, nvlist_t *config);
+extern nvlist_t *vdev_config_generate(spa_t *spa, vdev_t *vd,
+    boolean_t getstats, vdev_config_flag_t flags);
+
+/*
+ * Label routines
+ */
+struct uberblock;
+extern uint64_t vdev_label_offset(uint64_t psize, int l, uint64_t offset);
+extern int vdev_label_number(uint64_t psise, uint64_t offset);
+extern nvlist_t *vdev_label_read_config(vdev_t *vd, uint64_t txg);
+extern void vdev_uberblock_load(vdev_t *, struct uberblock *, nvlist_t **);
+
+typedef enum {
+	VDEV_LABEL_CREATE,	/* create/add a new device */
+	VDEV_LABEL_REPLACE,	/* replace an existing device */
+	VDEV_LABEL_SPARE,	/* add a new hot spare */
+	VDEV_LABEL_REMOVE,	/* remove an existing device */
+	VDEV_LABEL_L2CACHE,	/* add an L2ARC cache device */
+	VDEV_LABEL_SPLIT	/* generating new label for split-off dev */
+} vdev_labeltype_t;
+
+extern int vdev_label_init(vdev_t *vd, uint64_t txg, vdev_labeltype_t reason);
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* _SYS_VDEV_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/include/sys/vdev_disk.h
@@ -0,0 +1,45 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (C) 2008-2010 Lawrence Livermore National Security, LLC.
+ * Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ * Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ * LLNL-CODE-403049.
+ */
+
+#ifndef _SYS_VDEV_DISK_H
+#define	_SYS_VDEV_DISK_H
+
+#ifdef _KERNEL
+#include <sys/vdev.h>
+
+typedef struct vdev_disk {
+	ddi_devid_t		vd_devid;
+	char			*vd_minor;
+	struct block_device	*vd_bdev;
+} vdev_disk_t;
+
+extern int vdev_disk_physio(struct block_device *, caddr_t,
+			    size_t, uint64_t, int);
+extern int vdev_disk_read_rootlabel(char *, char *, nvlist_t **);
+
+#endif /* _KERNEL */
+#endif /* _SYS_VDEV_DISK_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/include/sys/vdev_file.h
@@ -0,0 +1,44 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License").  You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _SYS_VDEV_FILE_H
+#define	_SYS_VDEV_FILE_H
+
+#include <sys/vdev.h>
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+typedef struct vdev_file {
+	vnode_t		*vf_vnode;
+} vdev_file_t;
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* _SYS_VDEV_FILE_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/include/sys/vdev_impl.h
@@ -0,0 +1,351 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2015 by Delphix. All rights reserved.
+ */
+
+#ifndef _SYS_VDEV_IMPL_H
+#define	_SYS_VDEV_IMPL_H
+
+#include <sys/avl.h>
+#include <sys/dmu.h>
+#include <sys/metaslab.h>
+#include <sys/nvpair.h>
+#include <sys/space_map.h>
+#include <sys/vdev.h>
+#include <sys/dkio.h>
+#include <sys/uberblock_impl.h>
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+/*
+ * Virtual device descriptors.
+ *
+ * All storage pool operations go through the virtual device framework,
+ * which provides data replication and I/O scheduling.
+ */
+
+/*
+ * Forward declarations that lots of things need.
+ */
+typedef struct vdev_queue vdev_queue_t;
+typedef struct vdev_cache vdev_cache_t;
+typedef struct vdev_cache_entry vdev_cache_entry_t;
+
+/*
+ * Virtual device operations
+ */
+typedef int	vdev_open_func_t(vdev_t *vd, uint64_t *size, uint64_t *max_size,
+    uint64_t *ashift);
+typedef void	vdev_close_func_t(vdev_t *vd);
+typedef uint64_t vdev_asize_func_t(vdev_t *vd, uint64_t psize);
+typedef void	vdev_io_start_func_t(zio_t *zio);
+typedef void	vdev_io_done_func_t(zio_t *zio);
+typedef void	vdev_state_change_func_t(vdev_t *vd, int, int);
+typedef void	vdev_hold_func_t(vdev_t *vd);
+typedef void	vdev_rele_func_t(vdev_t *vd);
+
+typedef const struct vdev_ops {
+	vdev_open_func_t		*vdev_op_open;
+	vdev_close_func_t		*vdev_op_close;
+	vdev_asize_func_t		*vdev_op_asize;
+	vdev_io_start_func_t		*vdev_op_io_start;
+	vdev_io_done_func_t		*vdev_op_io_done;
+	vdev_state_change_func_t	*vdev_op_state_change;
+	vdev_hold_func_t		*vdev_op_hold;
+	vdev_rele_func_t		*vdev_op_rele;
+	char				vdev_op_type[16];
+	boolean_t			vdev_op_leaf;
+} vdev_ops_t;
+
+/*
+ * Virtual device properties
+ */
+struct vdev_cache_entry {
+	char		*ve_data;
+	uint64_t	ve_offset;
+	clock_t		ve_lastused;
+	avl_node_t	ve_offset_node;
+	avl_node_t	ve_lastused_node;
+	uint32_t	ve_hits;
+	uint16_t	ve_missed_update;
+	zio_t		*ve_fill_io;
+};
+
+struct vdev_cache {
+	avl_tree_t	vc_offset_tree;
+	avl_tree_t	vc_lastused_tree;
+	kmutex_t	vc_lock;
+};
+
+typedef struct vdev_queue_class {
+	uint32_t	vqc_active;
+
+	/*
+	 * Sorted by offset or timestamp, depending on if the queue is
+	 * LBA-ordered vs FIFO.
+	 */
+	avl_tree_t	vqc_queued_tree;
+} vdev_queue_class_t;
+
+struct vdev_queue {
+	vdev_t		*vq_vdev;
+	vdev_queue_class_t vq_class[ZIO_PRIORITY_NUM_QUEUEABLE];
+	avl_tree_t	vq_active_tree;
+	avl_tree_t	vq_read_offset_tree;
+	avl_tree_t	vq_write_offset_tree;
+	uint64_t	vq_last_offset;
+	hrtime_t	vq_io_complete_ts; /* time last i/o completed */
+	hrtime_t	vq_io_delta_ts;
+	zio_t		vq_io_search; /* used as local for stack reduction */
+	kmutex_t	vq_lock;
+};
+
+/*
+ * Virtual device descriptor
+ */
+struct vdev {
+	/*
+	 * Common to all vdev types.
+	 */
+	uint64_t	vdev_id;	/* child number in vdev parent	*/
+	uint64_t	vdev_guid;	/* unique ID for this vdev	*/
+	uint64_t	vdev_guid_sum;	/* self guid + all child guids	*/
+	uint64_t	vdev_orig_guid;	/* orig. guid prior to remove	*/
+	uint64_t	vdev_asize;	/* allocatable device capacity	*/
+	uint64_t	vdev_min_asize;	/* min acceptable asize		*/
+	uint64_t	vdev_max_asize;	/* max acceptable asize		*/
+	uint64_t	vdev_ashift;	/* block alignment shift	*/
+	uint64_t	vdev_state;	/* see VDEV_STATE_* #defines	*/
+	uint64_t	vdev_prevstate;	/* used when reopening a vdev	*/
+	vdev_ops_t	*vdev_ops;	/* vdev operations		*/
+	spa_t		*vdev_spa;	/* spa for this vdev		*/
+	void		*vdev_tsd;	/* type-specific data		*/
+	vnode_t		*vdev_name_vp;	/* vnode for pathname		*/
+	vnode_t		*vdev_devid_vp;	/* vnode for devid		*/
+	vdev_t		*vdev_top;	/* top-level vdev		*/
+	vdev_t		*vdev_parent;	/* parent vdev			*/
+	vdev_t		**vdev_child;	/* array of children		*/
+	uint64_t	vdev_children;	/* number of children		*/
+	vdev_stat_t	vdev_stat;	/* virtual device statistics	*/
+	boolean_t	vdev_expanding;	/* expand the vdev?		*/
+	boolean_t	vdev_reopening;	/* reopen in progress?		*/
+	boolean_t	vdev_nonrot;	/* true if solid state		*/
+	int		vdev_open_error; /* error on last open		*/
+	kthread_t	*vdev_open_thread; /* thread opening children	*/
+	uint64_t	vdev_crtxg;	/* txg when top-level was added */
+
+	/*
+	 * Top-level vdev state.
+	 */
+	uint64_t	vdev_ms_array;	/* metaslab array object	*/
+	uint64_t	vdev_ms_shift;	/* metaslab size shift		*/
+	uint64_t	vdev_ms_count;	/* number of metaslabs		*/
+	metaslab_group_t *vdev_mg;	/* metaslab group		*/
+	metaslab_t	**vdev_ms;	/* metaslab array		*/
+	uint64_t	vdev_pending_fastwrite; /* allocated fastwrites */
+	txg_list_t	vdev_ms_list;	/* per-txg dirty metaslab lists	*/
+	txg_list_t	vdev_dtl_list;	/* per-txg dirty DTL lists	*/
+	txg_node_t	vdev_txg_node;	/* per-txg dirty vdev linkage	*/
+	boolean_t	vdev_remove_wanted; /* async remove wanted?	*/
+	boolean_t	vdev_probe_wanted; /* async probe wanted?	*/
+	list_node_t	vdev_config_dirty_node; /* config dirty list	*/
+	list_node_t	vdev_state_dirty_node; /* state dirty list	*/
+	uint64_t	vdev_deflate_ratio; /* deflation ratio (x512)	*/
+	uint64_t	vdev_islog;	/* is an intent log device	*/
+	uint64_t	vdev_removing;	/* device is being removed?	*/
+	boolean_t	vdev_ishole;	/* is a hole in the namespace 	*/
+
+	/*
+	 * Leaf vdev state.
+	 */
+	range_tree_t	*vdev_dtl[DTL_TYPES]; /* dirty time logs	*/
+	space_map_t	*vdev_dtl_sm;	/* dirty time log space map	*/
+	txg_node_t	vdev_dtl_node;	/* per-txg dirty DTL linkage	*/
+	uint64_t	vdev_dtl_object; /* DTL object			*/
+	uint64_t	vdev_psize;	/* physical device capacity	*/
+	uint64_t	vdev_wholedisk;	/* true if this is a whole disk */
+	uint64_t	vdev_offline;	/* persistent offline state	*/
+	uint64_t	vdev_faulted;	/* persistent faulted state	*/
+	uint64_t	vdev_degraded;	/* persistent degraded state	*/
+	uint64_t	vdev_removed;	/* persistent removed state	*/
+	uint64_t	vdev_resilver_txg; /* persistent resilvering state */
+	uint64_t	vdev_nparity;	/* number of parity devices for raidz */
+	char		*vdev_path;	/* vdev path (if any)		*/
+	char		*vdev_devid;	/* vdev devid (if any)		*/
+	char		*vdev_physpath;	/* vdev device path (if any)	*/
+	char		*vdev_fru;	/* physical FRU location	*/
+	uint64_t	vdev_not_present; /* not present during import	*/
+	uint64_t	vdev_unspare;	/* unspare when resilvering done */
+	boolean_t	vdev_nowritecache; /* true if flushwritecache failed */
+	boolean_t	vdev_checkremove; /* temporary online test	*/
+	boolean_t	vdev_forcefault; /* force online fault		*/
+	boolean_t	vdev_splitting;	/* split or repair in progress  */
+	boolean_t	vdev_delayed_close; /* delayed device close?	*/
+	boolean_t	vdev_tmpoffline; /* device taken offline temporarily? */
+	boolean_t	vdev_detached;	/* device detached?		*/
+	boolean_t	vdev_cant_read;	/* vdev is failing all reads	*/
+	boolean_t	vdev_cant_write; /* vdev is failing all writes	*/
+	boolean_t	vdev_isspare;	/* was a hot spare		*/
+	boolean_t	vdev_isl2cache;	/* was a l2cache device		*/
+	vdev_queue_t	vdev_queue;	/* I/O deadline schedule queue	*/
+	vdev_cache_t	vdev_cache;	/* physical block cache		*/
+	spa_aux_vdev_t	*vdev_aux;	/* for l2cache and spares vdevs	*/
+	zio_t		*vdev_probe_zio; /* root of current probe	*/
+	vdev_aux_t	vdev_label_aux;	/* on-disk aux state		*/
+
+	/*
+	 * For DTrace to work in userland (libzpool) context, these fields must
+	 * remain at the end of the structure.  DTrace will use the kernel's
+	 * CTF definition for 'struct vdev', and since the size of a kmutex_t is
+	 * larger in userland, the offsets for the rest of the fields would be
+	 * incorrect.
+	 */
+	kmutex_t	vdev_dtl_lock;	/* vdev_dtl_{map,resilver}	*/
+	kmutex_t	vdev_stat_lock;	/* vdev_stat			*/
+	kmutex_t	vdev_probe_lock; /* protects vdev_probe_zio	*/
+};
+
+#define	VDEV_RAIDZ_MAXPARITY	3
+
+#define	VDEV_PAD_SIZE		(8 << 10)
+/* 2 padding areas (vl_pad1 and vl_pad2) to skip */
+#define	VDEV_SKIP_SIZE		VDEV_PAD_SIZE * 2
+#define	VDEV_PHYS_SIZE		(112 << 10)
+#define	VDEV_UBERBLOCK_RING	(128 << 10)
+
+/* The largest uberblock we support is 8k. */
+#define	MAX_UBERBLOCK_SHIFT (13)
+#define	VDEV_UBERBLOCK_SHIFT(vd)	\
+	MIN(MAX((vd)->vdev_top->vdev_ashift, UBERBLOCK_SHIFT), \
+	    MAX_UBERBLOCK_SHIFT)
+#define	VDEV_UBERBLOCK_COUNT(vd)	\
+	(VDEV_UBERBLOCK_RING >> VDEV_UBERBLOCK_SHIFT(vd))
+#define	VDEV_UBERBLOCK_OFFSET(vd, n)	\
+	offsetof(vdev_label_t, vl_uberblock[(n) << VDEV_UBERBLOCK_SHIFT(vd)])
+#define	VDEV_UBERBLOCK_SIZE(vd)		(1ULL << VDEV_UBERBLOCK_SHIFT(vd))
+
+typedef struct vdev_phys {
+	char		vp_nvlist[VDEV_PHYS_SIZE - sizeof (zio_eck_t)];
+	zio_eck_t	vp_zbt;
+} vdev_phys_t;
+
+typedef struct vdev_label {
+	char		vl_pad1[VDEV_PAD_SIZE];			/*  8K */
+	char		vl_pad2[VDEV_PAD_SIZE];			/*  8K */
+	vdev_phys_t	vl_vdev_phys;				/* 112K	*/
+	char		vl_uberblock[VDEV_UBERBLOCK_RING];	/* 128K	*/
+} vdev_label_t;							/* 256K total */
+
+/*
+ * vdev_dirty() flags
+ */
+#define	VDD_METASLAB	0x01
+#define	VDD_DTL		0x02
+
+/* Offset of embedded boot loader region on each label */
+#define	VDEV_BOOT_OFFSET	(2 * sizeof (vdev_label_t))
+/*
+ * Size of embedded boot loader region on each label.
+ * The total size of the first two labels plus the boot area is 4MB.
+ */
+#define	VDEV_BOOT_SIZE		(7ULL << 19)			/* 3.5M */
+
+/*
+ * Size of label regions at the start and end of each leaf device.
+ */
+#define	VDEV_LABEL_START_SIZE	(2 * sizeof (vdev_label_t) + VDEV_BOOT_SIZE)
+#define	VDEV_LABEL_END_SIZE	(2 * sizeof (vdev_label_t))
+#define	VDEV_LABELS		4
+#define	VDEV_BEST_LABEL		VDEV_LABELS
+
+#define	VDEV_ALLOC_LOAD		0
+#define	VDEV_ALLOC_ADD		1
+#define	VDEV_ALLOC_SPARE	2
+#define	VDEV_ALLOC_L2CACHE	3
+#define	VDEV_ALLOC_ROOTPOOL	4
+#define	VDEV_ALLOC_SPLIT	5
+#define	VDEV_ALLOC_ATTACH	6
+
+/*
+ * Allocate or free a vdev
+ */
+extern vdev_t *vdev_alloc_common(spa_t *spa, uint_t id, uint64_t guid,
+    vdev_ops_t *ops);
+extern int vdev_alloc(spa_t *spa, vdev_t **vdp, nvlist_t *config,
+    vdev_t *parent, uint_t id, int alloctype);
+extern void vdev_free(vdev_t *vd);
+
+/*
+ * Add or remove children and parents
+ */
+extern void vdev_add_child(vdev_t *pvd, vdev_t *cvd);
+extern void vdev_remove_child(vdev_t *pvd, vdev_t *cvd);
+extern void vdev_compact_children(vdev_t *pvd);
+extern vdev_t *vdev_add_parent(vdev_t *cvd, vdev_ops_t *ops);
+extern void vdev_remove_parent(vdev_t *cvd);
+
+/*
+ * vdev sync load and sync
+ */
+extern void vdev_load_log_state(vdev_t *nvd, vdev_t *ovd);
+extern boolean_t vdev_log_state_valid(vdev_t *vd);
+extern void vdev_load(vdev_t *vd);
+extern int vdev_dtl_load(vdev_t *vd);
+extern void vdev_sync(vdev_t *vd, uint64_t txg);
+extern void vdev_sync_done(vdev_t *vd, uint64_t txg);
+extern void vdev_dirty(vdev_t *vd, int flags, void *arg, uint64_t txg);
+extern void vdev_dirty_leaves(vdev_t *vd, int flags, uint64_t txg);
+
+/*
+ * Available vdev types.
+ */
+extern vdev_ops_t vdev_root_ops;
+extern vdev_ops_t vdev_mirror_ops;
+extern vdev_ops_t vdev_replacing_ops;
+extern vdev_ops_t vdev_raidz_ops;
+extern vdev_ops_t vdev_disk_ops;
+extern vdev_ops_t vdev_file_ops;
+extern vdev_ops_t vdev_missing_ops;
+extern vdev_ops_t vdev_hole_ops;
+extern vdev_ops_t vdev_spare_ops;
+
+/*
+ * Common size functions
+ */
+extern uint64_t vdev_default_asize(vdev_t *vd, uint64_t psize);
+extern uint64_t vdev_get_min_asize(vdev_t *vd);
+extern void vdev_set_min_asize(vdev_t *vd);
+
+/*
+ * Global variables
+ */
+/* zdb uses this tunable, so it must be declared here to make lint happy. */
+extern int zfs_vdev_cache_size;
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* _SYS_VDEV_IMPL_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/include/sys/xvattr.h
@@ -0,0 +1,330 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 1988, 2010, Oracle and/or its affiliates. All rights reserved.
+ */
+
+/*	Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T	*/
+/*	  All Rights Reserved  	*/
+
+/*
+ * University Copyright- Copyright (c) 1982, 1986, 1988
+ * The Regents of the University of California
+ * All Rights Reserved
+ *
+ * University Acknowledgment- Portions of this document are derived from
+ * software developed by the University of California, Berkeley, and its
+ * contributors.
+ */
+
+#ifndef _SYS_XVATTR_H
+#define	_SYS_XVATTR_H
+
+#include <sys/vnode.h>
+
+#define	AV_SCANSTAMP_SZ	32		/* length of anti-virus scanstamp */
+
+/*
+ * Structure of all optional attributes.
+ */
+typedef struct xoptattr {
+	timestruc_t	xoa_createtime;	/* Create time of file */
+	uint8_t		xoa_archive;
+	uint8_t		xoa_system;
+	uint8_t		xoa_readonly;
+	uint8_t		xoa_hidden;
+	uint8_t		xoa_nounlink;
+	uint8_t		xoa_immutable;
+	uint8_t		xoa_appendonly;
+	uint8_t		xoa_nodump;
+	uint8_t		xoa_opaque;
+	uint8_t		xoa_av_quarantined;
+	uint8_t		xoa_av_modified;
+	uint8_t		xoa_av_scanstamp[AV_SCANSTAMP_SZ];
+	uint8_t		xoa_reparse;
+	uint64_t	xoa_generation;
+	uint8_t		xoa_offline;
+	uint8_t		xoa_sparse;
+} xoptattr_t;
+
+/*
+ * The xvattr structure is really a variable length structure that
+ * is made up of:
+ * - The classic vattr_t (xva_vattr)
+ * - a 32 bit quantity (xva_mapsize) that specifies the size of the
+ *   attribute bitmaps in 32 bit words.
+ * - A pointer to the returned attribute bitmap (needed because the
+ *   previous element, the requested attribute bitmap) is variable lenth.
+ * - The requested attribute bitmap, which is an array of 32 bit words.
+ *   Callers use the XVA_SET_REQ() macro to set the bits corresponding to
+ *   the attributes that are being requested.
+ * - The returned attribute bitmap, which is an array of 32 bit words.
+ *   File systems that support optional attributes use the XVA_SET_RTN()
+ *   macro to set the bits corresponding to the attributes that are being
+ *   returned.
+ * - The xoptattr_t structure which contains the attribute values
+ *
+ * xva_mapsize determines how many words in the attribute bitmaps.
+ * Immediately following the attribute bitmaps is the xoptattr_t.
+ * xva_getxoptattr() is used to get the pointer to the xoptattr_t
+ * section.
+ */
+
+#define	XVA_MAPSIZE	3		/* Size of attr bitmaps */
+#define	XVA_MAGIC	0x78766174	/* Magic # for verification */
+
+/*
+ * The xvattr structure is an extensible structure which permits optional
+ * attributes to be requested/returned.  File systems may or may not support
+ * optional attributes.  They do so at their own discretion but if they do
+ * support optional attributes, they must register the VFSFT_XVATTR feature
+ * so that the optional attributes can be set/retrived.
+ *
+ * The fields of the xvattr structure are:
+ *
+ * xva_vattr - The first element of an xvattr is a legacy vattr structure
+ * which includes the common attributes.  If AT_XVATTR is set in the va_mask
+ * then the entire structure is treated as an xvattr.  If AT_XVATTR is not
+ * set, then only the xva_vattr structure can be used.
+ *
+ * xva_magic - 0x78766174 (hex for "xvat"). Magic number for verification.
+ *
+ * xva_mapsize - Size of requested and returned attribute bitmaps.
+ *
+ * xva_rtnattrmapp - Pointer to xva_rtnattrmap[].  We need this since the
+ * size of the array before it, xva_reqattrmap[], could change which means
+ * the location of xva_rtnattrmap[] could change.  This will allow unbundled
+ * file systems to find the location of xva_rtnattrmap[] when the sizes change.
+ *
+ * xva_reqattrmap[] - Array of requested attributes.  Attributes are
+ * represented by a specific bit in a specific element of the attribute
+ * map array.  Callers set the bits corresponding to the attributes
+ * that the caller wants to get/set.
+ *
+ * xva_rtnattrmap[] - Array of attributes that the file system was able to
+ * process.  Not all file systems support all optional attributes.  This map
+ * informs the caller which attributes the underlying file system was able
+ * to set/get.  (Same structure as the requested attributes array in terms
+ * of each attribute  corresponding to specific bits and array elements.)
+ *
+ * xva_xoptattrs - Structure containing values of optional attributes.
+ * These values are only valid if the corresponding bits in xva_reqattrmap
+ * are set and the underlying file system supports those attributes.
+ */
+typedef struct xvattr {
+	vattr_t		xva_vattr;	/* Embedded vattr structure */
+	uint32_t	xva_magic;	/* Magic Number */
+	uint32_t	xva_mapsize;	/* Size of attr bitmap (32-bit words) */
+	uint32_t	*xva_rtnattrmapp;	/* Ptr to xva_rtnattrmap[] */
+	uint32_t	xva_reqattrmap[XVA_MAPSIZE];	/* Requested attrs */
+	uint32_t	xva_rtnattrmap[XVA_MAPSIZE];	/* Returned attrs */
+	xoptattr_t	xva_xoptattrs;	/* Optional attributes */
+} xvattr_t;
+
+/*
+ * Attribute bits used in the extensible attribute's (xva's) attribute
+ * bitmaps.  Note that the bitmaps are made up of a variable length number
+ * of 32-bit words.  The convention is to use XAT{n}_{attrname} where "n"
+ * is the element in the bitmap (starting at 1).  This convention is for
+ * the convenience of the maintainer to keep track of which element each
+ * attribute belongs to.
+ *
+ * NOTE THAT CONSUMERS MUST *NOT* USE THE XATn_* DEFINES DIRECTLY.  CONSUMERS
+ * MUST USE THE XAT_* DEFINES.
+ */
+#define	XAT0_INDEX	0LL		/* Index into bitmap for XAT0 attrs */
+#define	XAT0_CREATETIME	0x00000001	/* Create time of file */
+#define	XAT0_ARCHIVE	0x00000002	/* Archive */
+#define	XAT0_SYSTEM	0x00000004	/* System */
+#define	XAT0_READONLY	0x00000008	/* Readonly */
+#define	XAT0_HIDDEN	0x00000010	/* Hidden */
+#define	XAT0_NOUNLINK	0x00000020	/* Nounlink */
+#define	XAT0_IMMUTABLE	0x00000040	/* immutable */
+#define	XAT0_APPENDONLY	0x00000080	/* appendonly */
+#define	XAT0_NODUMP	0x00000100	/* nodump */
+#define	XAT0_OPAQUE	0x00000200	/* opaque */
+#define	XAT0_AV_QUARANTINED	0x00000400	/* anti-virus quarantine */
+#define	XAT0_AV_MODIFIED	0x00000800	/* anti-virus modified */
+#define	XAT0_AV_SCANSTAMP	0x00001000	/* anti-virus scanstamp */
+#define	XAT0_REPARSE	0x00002000	/* FS reparse point */
+#define	XAT0_GEN	0x00004000	/* object generation number */
+#define	XAT0_OFFLINE	0x00008000	/* offline */
+#define	XAT0_SPARSE	0x00010000	/* sparse */
+
+#define	XAT0_ALL_ATTRS	(XAT0_CREATETIME|XAT0_ARCHIVE|XAT0_SYSTEM| \
+    XAT0_READONLY|XAT0_HIDDEN|XAT0_NOUNLINK|XAT0_IMMUTABLE|XAT0_APPENDONLY| \
+    XAT0_NODUMP|XAT0_OPAQUE|XAT0_AV_QUARANTINED|  XAT0_AV_MODIFIED| \
+    XAT0_AV_SCANSTAMP|XAT0_REPARSE|XATO_GEN|XAT0_OFFLINE|XAT0_SPARSE)
+
+/* Support for XAT_* optional attributes */
+#define	XVA_MASK		0xffffffff	/* Used to mask off 32 bits */
+#define	XVA_SHFT		32		/* Used to shift index */
+
+/*
+ * Used to pry out the index and attribute bits from the XAT_* attributes
+ * defined below.  Note that we're masking things down to 32 bits then
+ * casting to uint32_t.
+ */
+#define	XVA_INDEX(attr)		((uint32_t)(((attr) >> XVA_SHFT) & XVA_MASK))
+#define	XVA_ATTRBIT(attr)	((uint32_t)((attr) & XVA_MASK))
+
+/*
+ * The following defines present a "flat namespace" so that consumers don't
+ * need to keep track of which element belongs to which bitmap entry.
+ *
+ * NOTE THAT THESE MUST NEVER BE OR-ed TOGETHER
+ */
+#define	XAT_CREATETIME		((XAT0_INDEX << XVA_SHFT) | XAT0_CREATETIME)
+#define	XAT_ARCHIVE		((XAT0_INDEX << XVA_SHFT) | XAT0_ARCHIVE)
+#define	XAT_SYSTEM		((XAT0_INDEX << XVA_SHFT) | XAT0_SYSTEM)
+#define	XAT_READONLY		((XAT0_INDEX << XVA_SHFT) | XAT0_READONLY)
+#define	XAT_HIDDEN		((XAT0_INDEX << XVA_SHFT) | XAT0_HIDDEN)
+#define	XAT_NOUNLINK		((XAT0_INDEX << XVA_SHFT) | XAT0_NOUNLINK)
+#define	XAT_IMMUTABLE		((XAT0_INDEX << XVA_SHFT) | XAT0_IMMUTABLE)
+#define	XAT_APPENDONLY		((XAT0_INDEX << XVA_SHFT) | XAT0_APPENDONLY)
+#define	XAT_NODUMP		((XAT0_INDEX << XVA_SHFT) | XAT0_NODUMP)
+#define	XAT_OPAQUE		((XAT0_INDEX << XVA_SHFT) | XAT0_OPAQUE)
+#define	XAT_AV_QUARANTINED	((XAT0_INDEX << XVA_SHFT) | XAT0_AV_QUARANTINED)
+#define	XAT_AV_MODIFIED		((XAT0_INDEX << XVA_SHFT) | XAT0_AV_MODIFIED)
+#define	XAT_AV_SCANSTAMP	((XAT0_INDEX << XVA_SHFT) | XAT0_AV_SCANSTAMP)
+#define	XAT_REPARSE		((XAT0_INDEX << XVA_SHFT) | XAT0_REPARSE)
+#define	XAT_GEN			((XAT0_INDEX << XVA_SHFT) | XAT0_GEN)
+#define	XAT_OFFLINE		((XAT0_INDEX << XVA_SHFT) | XAT0_OFFLINE)
+#define	XAT_SPARSE		((XAT0_INDEX << XVA_SHFT) | XAT0_SPARSE)
+
+/*
+ * The returned attribute map array (xva_rtnattrmap[]) is located past the
+ * requested attribute map array (xva_reqattrmap[]).  Its location changes
+ * when the array sizes change.  We use a separate pointer in a known location
+ * (xva_rtnattrmapp) to hold the location of xva_rtnattrmap[].  This is
+ * set in xva_init()
+ */
+#define	XVA_RTNATTRMAP(xvap)	((xvap)->xva_rtnattrmapp)
+
+/*
+ * XVA_SET_REQ() sets an attribute bit in the proper element in the bitmap
+ * of requested attributes (xva_reqattrmap[]).
+ */
+#define	XVA_SET_REQ(xvap, attr)					\
+	ASSERT((xvap)->xva_vattr.va_mask | AT_XVATTR);		\
+	ASSERT((xvap)->xva_magic == XVA_MAGIC);			\
+	(xvap)->xva_reqattrmap[XVA_INDEX(attr)] |= XVA_ATTRBIT(attr)
+/*
+ * XVA_CLR_REQ() clears an attribute bit in the proper element in the bitmap
+ * of requested attributes (xva_reqattrmap[]).
+ */
+#define	XVA_CLR_REQ(xvap, attr)					\
+	ASSERT((xvap)->xva_vattr.va_mask | AT_XVATTR);		\
+	ASSERT((xvap)->xva_magic == XVA_MAGIC);			\
+	(xvap)->xva_reqattrmap[XVA_INDEX(attr)] &= ~XVA_ATTRBIT(attr)
+
+/*
+ * XVA_SET_RTN() sets an attribute bit in the proper element in the bitmap
+ * of returned attributes (xva_rtnattrmap[]).
+ */
+#define	XVA_SET_RTN(xvap, attr)					\
+	ASSERT((xvap)->xva_vattr.va_mask | AT_XVATTR);		\
+	ASSERT((xvap)->xva_magic == XVA_MAGIC);			\
+	(XVA_RTNATTRMAP(xvap))[XVA_INDEX(attr)] |= XVA_ATTRBIT(attr)
+
+/*
+ * XVA_ISSET_REQ() checks the requested attribute bitmap (xva_reqattrmap[])
+ * to see of the corresponding attribute bit is set.  If so, returns non-zero.
+ */
+#define	XVA_ISSET_REQ(xvap, attr)					\
+	((((xvap)->xva_vattr.va_mask | AT_XVATTR) &&			\
+		((xvap)->xva_magic == XVA_MAGIC) &&			\
+		((xvap)->xva_mapsize > XVA_INDEX(attr))) ?		\
+	((xvap)->xva_reqattrmap[XVA_INDEX(attr)] & XVA_ATTRBIT(attr)) :	0)
+
+/*
+ * XVA_ISSET_RTN() checks the returned attribute bitmap (xva_rtnattrmap[])
+ * to see of the corresponding attribute bit is set.  If so, returns non-zero.
+ */
+#define	XVA_ISSET_RTN(xvap, attr)					\
+	((((xvap)->xva_vattr.va_mask | AT_XVATTR) &&			\
+		((xvap)->xva_magic == XVA_MAGIC) &&			\
+		((xvap)->xva_mapsize > XVA_INDEX(attr))) ?		\
+	((XVA_RTNATTRMAP(xvap))[XVA_INDEX(attr)] & XVA_ATTRBIT(attr)) : 0)
+
+/*
+ * Zero out the structure, set the size of the requested/returned bitmaps,
+ * set AT_XVATTR in the embedded vattr_t's va_mask, and set up the pointer
+ * to the returned attributes array.
+ */
+static inline void
+xva_init(xvattr_t *xvap)
+{
+	bzero(xvap, sizeof (xvattr_t));
+	xvap->xva_mapsize = XVA_MAPSIZE;
+	xvap->xva_magic = XVA_MAGIC;
+	xvap->xva_vattr.va_mask = ATTR_XVATTR;
+	xvap->xva_rtnattrmapp = &(xvap->xva_rtnattrmap)[0];
+}
+
+/*
+ * If AT_XVATTR is set, returns a pointer to the embedded xoptattr_t
+ * structure.  Otherwise, returns NULL.
+ */
+static inline xoptattr_t *
+xva_getxoptattr(xvattr_t *xvap)
+{
+	xoptattr_t *xoap = NULL;
+	if (xvap->xva_vattr.va_mask & AT_XVATTR)
+			xoap = &xvap->xva_xoptattrs;
+	return (xoap);
+}
+
+#define	MODEMASK	07777		/* mode bits plus permission bits */
+#define	PERMMASK	00777		/* permission bits */
+
+/*
+ * VOP_ACCESS flags
+ */
+#define	V_ACE_MASK	0x1	/* mask represents  NFSv4 ACE permissions */
+#define	V_APPEND	0x2	/* want to do append only check */
+
+/*
+ * Structure used on VOP_GETSECATTR and VOP_SETSECATTR operations
+ */
+
+typedef struct vsecattr {
+	uint_t		vsa_mask;	/* See below */
+	int		vsa_aclcnt;	/* ACL entry count */
+	void		*vsa_aclentp;	/* pointer to ACL entries */
+	int		vsa_dfaclcnt;	/* default ACL entry count */
+	void		*vsa_dfaclentp;	/* pointer to default ACL entries */
+	size_t		vsa_aclentsz;	/* ACE size in bytes of vsa_aclentp */
+	uint_t		vsa_aclflags;	/* ACE ACL flags */
+} vsecattr_t;
+
+/* vsa_mask values */
+#define	VSA_ACL			0x0001
+#define	VSA_ACLCNT		0x0002
+#define	VSA_DFACL		0x0004
+#define	VSA_DFACLCNT		0x0008
+#define	VSA_ACE			0x0010
+#define	VSA_ACECNT		0x0020
+#define	VSA_ACE_ALLTYPES	0x0040
+#define	VSA_ACE_ACLFLAGS	0x0080	/* get/set ACE ACL flags */
+
+#endif /* _SYS_XVATTR_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/include/sys/zap.h
@@ -0,0 +1,490 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013 by Delphix. All rights reserved.
+ */
+
+#ifndef	_SYS_ZAP_H
+#define	_SYS_ZAP_H
+
+/*
+ * ZAP - ZFS Attribute Processor
+ *
+ * The ZAP is a module which sits on top of the DMU (Data Management
+ * Unit) and implements a higher-level storage primitive using DMU
+ * objects.  Its primary consumer is the ZPL (ZFS Posix Layer).
+ *
+ * A "zapobj" is a DMU object which the ZAP uses to stores attributes.
+ * Users should use only zap routines to access a zapobj - they should
+ * not access the DMU object directly using DMU routines.
+ *
+ * The attributes stored in a zapobj are name-value pairs.  The name is
+ * a zero-terminated string of up to ZAP_MAXNAMELEN bytes (including
+ * terminating NULL).  The value is an array of integers, which may be
+ * 1, 2, 4, or 8 bytes long.  The total space used by the array (number
+ * of integers * integer length) can be up to ZAP_MAXVALUELEN bytes.
+ * Note that an 8-byte integer value can be used to store the location
+ * (object number) of another dmu object (which may be itself a zapobj).
+ * Note that you can use a zero-length attribute to store a single bit
+ * of information - the attribute is present or not.
+ *
+ * The ZAP routines are thread-safe.  However, you must observe the
+ * DMU's restriction that a transaction may not be operated on
+ * concurrently.
+ *
+ * Any of the routines that return an int may return an I/O error (EIO
+ * or ECHECKSUM).
+ *
+ *
+ * Implementation / Performance Notes:
+ *
+ * The ZAP is intended to operate most efficiently on attributes with
+ * short (49 bytes or less) names and single 8-byte values, for which
+ * the microzap will be used.  The ZAP should be efficient enough so
+ * that the user does not need to cache these attributes.
+ *
+ * The ZAP's locking scheme makes its routines thread-safe.  Operations
+ * on different zapobjs will be processed concurrently.  Operations on
+ * the same zapobj which only read data will be processed concurrently.
+ * Operations on the same zapobj which modify data will be processed
+ * concurrently when there are many attributes in the zapobj (because
+ * the ZAP uses per-block locking - more than 128 * (number of cpus)
+ * small attributes will suffice).
+ */
+
+/*
+ * We're using zero-terminated byte strings (ie. ASCII or UTF-8 C
+ * strings) for the names of attributes, rather than a byte string
+ * bounded by an explicit length.  If some day we want to support names
+ * in character sets which have embedded zeros (eg. UTF-16, UTF-32),
+ * we'll have to add routines for using length-bounded strings.
+ */
+
+#include <sys/dmu.h>
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+/*
+ * Specifies matching criteria for ZAP lookups.
+ */
+typedef enum matchtype
+{
+	/* Only find an exact match (non-normalized) */
+	MT_EXACT,
+	/*
+	 * If there is an exact match, find that, otherwise find the
+	 * first normalized match.
+	 */
+	MT_BEST,
+	/*
+	 * Find the "first" normalized (case and Unicode form) match;
+	 * the designated "first" match will not change as long as the
+	 * set of entries with this normalization doesn't change.
+	 */
+	MT_FIRST
+} matchtype_t;
+
+typedef enum zap_flags {
+	/* Use 64-bit hash value (serialized cursors will always use 64-bits) */
+	ZAP_FLAG_HASH64 = 1 << 0,
+	/* Key is binary, not string (zap_add_uint64() can be used) */
+	ZAP_FLAG_UINT64_KEY = 1 << 1,
+	/*
+	 * First word of key (which must be an array of uint64) is
+	 * already randomly distributed.
+	 */
+	ZAP_FLAG_PRE_HASHED_KEY = 1 << 2,
+} zap_flags_t;
+
+/*
+ * Create a new zapobj with no attributes and return its object number.
+ * MT_EXACT will cause the zap object to only support MT_EXACT lookups,
+ * otherwise any matchtype can be used for lookups.
+ *
+ * normflags specifies what normalization will be done.  values are:
+ * 0: no normalization (legacy on-disk format, supports MT_EXACT matching
+ *     only)
+ * U8_TEXTPREP_TOLOWER: case normalization will be performed.
+ *     MT_FIRST/MT_BEST matching will find entries that match without
+ *     regard to case (eg. looking for "foo" can find an entry "Foo").
+ * Eventually, other flags will permit unicode normalization as well.
+ */
+uint64_t zap_create(objset_t *ds, dmu_object_type_t ot,
+    dmu_object_type_t bonustype, int bonuslen, dmu_tx_t *tx);
+uint64_t zap_create_norm(objset_t *ds, int normflags, dmu_object_type_t ot,
+    dmu_object_type_t bonustype, int bonuslen, dmu_tx_t *tx);
+uint64_t zap_create_flags(objset_t *os, int normflags, zap_flags_t flags,
+    dmu_object_type_t ot, int leaf_blockshift, int indirect_blockshift,
+    dmu_object_type_t bonustype, int bonuslen, dmu_tx_t *tx);
+uint64_t zap_create_link(objset_t *os, dmu_object_type_t ot,
+    uint64_t parent_obj, const char *name, dmu_tx_t *tx);
+
+/*
+ * Initialize an already-allocated object.
+ */
+void mzap_create_impl(objset_t *os, uint64_t obj, int normflags,
+    zap_flags_t flags, dmu_tx_t *tx);
+
+/*
+ * Create a new zapobj with no attributes from the given (unallocated)
+ * object number.
+ */
+int zap_create_claim(objset_t *ds, uint64_t obj, dmu_object_type_t ot,
+    dmu_object_type_t bonustype, int bonuslen, dmu_tx_t *tx);
+int zap_create_claim_norm(objset_t *ds, uint64_t obj,
+    int normflags, dmu_object_type_t ot,
+    dmu_object_type_t bonustype, int bonuslen, dmu_tx_t *tx);
+
+/*
+ * The zapobj passed in must be a valid ZAP object for all of the
+ * following routines.
+ */
+
+/*
+ * Destroy this zapobj and all its attributes.
+ *
+ * Frees the object number using dmu_object_free.
+ */
+int zap_destroy(objset_t *ds, uint64_t zapobj, dmu_tx_t *tx);
+
+/*
+ * Manipulate attributes.
+ *
+ * 'integer_size' is in bytes, and must be 1, 2, 4, or 8.
+ */
+
+/*
+ * Retrieve the contents of the attribute with the given name.
+ *
+ * If the requested attribute does not exist, the call will fail and
+ * return ENOENT.
+ *
+ * If 'integer_size' is smaller than the attribute's integer size, the
+ * call will fail and return EINVAL.
+ *
+ * If 'integer_size' is equal to or larger than the attribute's integer
+ * size, the call will succeed and return 0.
+ *
+ * When converting to a larger integer size, the integers will be treated as
+ * unsigned (ie. no sign-extension will be performed).
+ *
+ * 'num_integers' is the length (in integers) of 'buf'.
+ *
+ * If the attribute is longer than the buffer, as many integers as will
+ * fit will be transferred to 'buf'.  If the entire attribute was not
+ * transferred, the call will return EOVERFLOW.
+ */
+int zap_lookup(objset_t *ds, uint64_t zapobj, const char *name,
+    uint64_t integer_size, uint64_t num_integers, void *buf);
+
+/*
+ * If rn_len is nonzero, realname will be set to the name of the found
+ * entry (which may be different from the requested name if matchtype is
+ * not MT_EXACT).
+ *
+ * If normalization_conflictp is not NULL, it will be set if there is
+ * another name with the same case/unicode normalized form.
+ */
+int zap_lookup_norm(objset_t *ds, uint64_t zapobj, const char *name,
+    uint64_t integer_size, uint64_t num_integers, void *buf,
+    matchtype_t mt, char *realname, int rn_len,
+    boolean_t *normalization_conflictp);
+int zap_lookup_uint64(objset_t *os, uint64_t zapobj, const uint64_t *key,
+    int key_numints, uint64_t integer_size, uint64_t num_integers, void *buf);
+int zap_contains(objset_t *ds, uint64_t zapobj, const char *name);
+int zap_prefetch(objset_t *os, uint64_t zapobj, const char *name);
+int zap_prefetch_uint64(objset_t *os, uint64_t zapobj, const uint64_t *key,
+    int key_numints);
+
+int zap_count_write(objset_t *os, uint64_t zapobj, const char *name,
+    int add, uint64_t *towrite, uint64_t *tooverwrite);
+
+/*
+ * Create an attribute with the given name and value.
+ *
+ * If an attribute with the given name already exists, the call will
+ * fail and return EEXIST.
+ */
+int zap_add(objset_t *ds, uint64_t zapobj, const char *key,
+    int integer_size, uint64_t num_integers,
+    const void *val, dmu_tx_t *tx);
+int zap_add_uint64(objset_t *ds, uint64_t zapobj, const uint64_t *key,
+    int key_numints, int integer_size, uint64_t num_integers,
+    const void *val, dmu_tx_t *tx);
+
+/*
+ * Set the attribute with the given name to the given value.  If an
+ * attribute with the given name does not exist, it will be created.  If
+ * an attribute with the given name already exists, the previous value
+ * will be overwritten.  The integer_size may be different from the
+ * existing attribute's integer size, in which case the attribute's
+ * integer size will be updated to the new value.
+ */
+int zap_update(objset_t *ds, uint64_t zapobj, const char *name,
+    int integer_size, uint64_t num_integers, const void *val, dmu_tx_t *tx);
+int zap_update_uint64(objset_t *os, uint64_t zapobj, const uint64_t *key,
+    int key_numints,
+    int integer_size, uint64_t num_integers, const void *val, dmu_tx_t *tx);
+
+/*
+ * Get the length (in integers) and the integer size of the specified
+ * attribute.
+ *
+ * If the requested attribute does not exist, the call will fail and
+ * return ENOENT.
+ */
+int zap_length(objset_t *ds, uint64_t zapobj, const char *name,
+    uint64_t *integer_size, uint64_t *num_integers);
+int zap_length_uint64(objset_t *os, uint64_t zapobj, const uint64_t *key,
+    int key_numints, uint64_t *integer_size, uint64_t *num_integers);
+
+/*
+ * Remove the specified attribute.
+ *
+ * If the specified attribute does not exist, the call will fail and
+ * return ENOENT.
+ */
+int zap_remove(objset_t *ds, uint64_t zapobj, const char *name, dmu_tx_t *tx);
+int zap_remove_norm(objset_t *ds, uint64_t zapobj, const char *name,
+    matchtype_t mt, dmu_tx_t *tx);
+int zap_remove_uint64(objset_t *os, uint64_t zapobj, const uint64_t *key,
+    int key_numints, dmu_tx_t *tx);
+
+/*
+ * Returns (in *count) the number of attributes in the specified zap
+ * object.
+ */
+int zap_count(objset_t *ds, uint64_t zapobj, uint64_t *count);
+
+/*
+ * Returns (in name) the name of the entry whose (value & mask)
+ * (za_first_integer) is value, or ENOENT if not found.  The string
+ * pointed to by name must be at least 256 bytes long.  If mask==0, the
+ * match must be exact (ie, same as mask=-1ULL).
+ */
+int zap_value_search(objset_t *os, uint64_t zapobj,
+    uint64_t value, uint64_t mask, char *name);
+
+/*
+ * Transfer all the entries from fromobj into intoobj.  Only works on
+ * int_size=8 num_integers=1 values.  Fails if there are any duplicated
+ * entries.
+ */
+int zap_join(objset_t *os, uint64_t fromobj, uint64_t intoobj, dmu_tx_t *tx);
+
+/* Same as zap_join, but set the values to 'value'. */
+int zap_join_key(objset_t *os, uint64_t fromobj, uint64_t intoobj,
+    uint64_t value, dmu_tx_t *tx);
+
+/* Same as zap_join, but add together any duplicated entries. */
+int zap_join_increment(objset_t *os, uint64_t fromobj, uint64_t intoobj,
+    dmu_tx_t *tx);
+
+/*
+ * Manipulate entries where the name + value are the "same" (the name is
+ * a stringified version of the value).
+ */
+int zap_add_int(objset_t *os, uint64_t obj, uint64_t value, dmu_tx_t *tx);
+int zap_remove_int(objset_t *os, uint64_t obj, uint64_t value, dmu_tx_t *tx);
+int zap_lookup_int(objset_t *os, uint64_t obj, uint64_t value);
+int zap_increment_int(objset_t *os, uint64_t obj, uint64_t key, int64_t delta,
+    dmu_tx_t *tx);
+
+/* Here the key is an int and the value is a different int. */
+int zap_add_int_key(objset_t *os, uint64_t obj,
+    uint64_t key, uint64_t value, dmu_tx_t *tx);
+int zap_update_int_key(objset_t *os, uint64_t obj,
+    uint64_t key, uint64_t value, dmu_tx_t *tx);
+int zap_lookup_int_key(objset_t *os, uint64_t obj,
+    uint64_t key, uint64_t *valuep);
+
+int zap_increment(objset_t *os, uint64_t obj, const char *name, int64_t delta,
+    dmu_tx_t *tx);
+
+struct zap;
+struct zap_leaf;
+typedef struct zap_cursor {
+	/* This structure is opaque! */
+	objset_t *zc_objset;
+	struct zap *zc_zap;
+	struct zap_leaf *zc_leaf;
+	uint64_t zc_zapobj;
+	uint64_t zc_serialized;
+	uint64_t zc_hash;
+	uint32_t zc_cd;
+} zap_cursor_t;
+
+typedef struct {
+	int za_integer_length;
+	/*
+	 * za_normalization_conflict will be set if there are additional
+	 * entries with this normalized form (eg, "foo" and "Foo").
+	 */
+	boolean_t za_normalization_conflict;
+	uint64_t za_num_integers;
+	uint64_t za_first_integer;	/* no sign extension for <8byte ints */
+	char za_name[MAXNAMELEN];
+} zap_attribute_t;
+
+/*
+ * The interface for listing all the attributes of a zapobj can be
+ * thought of as cursor moving down a list of the attributes one by
+ * one.  The cookie returned by the zap_cursor_serialize routine is
+ * persistent across system calls (and across reboot, even).
+ */
+
+/*
+ * Initialize a zap cursor, pointing to the "first" attribute of the
+ * zapobj.  You must _fini the cursor when you are done with it.
+ */
+void zap_cursor_init(zap_cursor_t *zc, objset_t *ds, uint64_t zapobj);
+void zap_cursor_fini(zap_cursor_t *zc);
+
+/*
+ * Get the attribute currently pointed to by the cursor.  Returns
+ * ENOENT if at the end of the attributes.
+ */
+int zap_cursor_retrieve(zap_cursor_t *zc, zap_attribute_t *za);
+
+/*
+ * Advance the cursor to the next attribute.
+ */
+void zap_cursor_advance(zap_cursor_t *zc);
+
+/*
+ * Get a persistent cookie pointing to the current position of the zap
+ * cursor.  The low 4 bits in the cookie are always zero, and thus can
+ * be used as to differentiate a serialized cookie from a different type
+ * of value.  The cookie will be less than 2^32 as long as there are
+ * fewer than 2^22 (4.2 million) entries in the zap object.
+ */
+uint64_t zap_cursor_serialize(zap_cursor_t *zc);
+
+/*
+ * Initialize a zap cursor pointing to the position recorded by
+ * zap_cursor_serialize (in the "serialized" argument).  You can also
+ * use a "serialized" argument of 0 to start at the beginning of the
+ * zapobj (ie.  zap_cursor_init_serialized(..., 0) is equivalent to
+ * zap_cursor_init(...).)
+ */
+void zap_cursor_init_serialized(zap_cursor_t *zc, objset_t *ds,
+    uint64_t zapobj, uint64_t serialized);
+
+
+#define	ZAP_HISTOGRAM_SIZE 10
+
+typedef struct zap_stats {
+	/*
+	 * Size of the pointer table (in number of entries).
+	 * This is always a power of 2, or zero if it's a microzap.
+	 * In general, it should be considerably greater than zs_num_leafs.
+	 */
+	uint64_t zs_ptrtbl_len;
+
+	uint64_t zs_blocksize;		/* size of zap blocks */
+
+	/*
+	 * The number of blocks used.  Note that some blocks may be
+	 * wasted because old ptrtbl's and large name/value blocks are
+	 * not reused.  (Although their space is reclaimed, we don't
+	 * reuse those offsets in the object.)
+	 */
+	uint64_t zs_num_blocks;
+
+	/*
+	 * Pointer table values from zap_ptrtbl in the zap_phys_t
+	 */
+	uint64_t zs_ptrtbl_nextblk;	  /* next (larger) copy start block */
+	uint64_t zs_ptrtbl_blks_copied;   /* number source blocks copied */
+	uint64_t zs_ptrtbl_zt_blk;	  /* starting block number */
+	uint64_t zs_ptrtbl_zt_numblks;    /* number of blocks */
+	uint64_t zs_ptrtbl_zt_shift;	  /* bits to index it */
+
+	/*
+	 * Values of the other members of the zap_phys_t
+	 */
+	uint64_t zs_block_type;		/* ZBT_HEADER */
+	uint64_t zs_magic;		/* ZAP_MAGIC */
+	uint64_t zs_num_leafs;		/* The number of leaf blocks */
+	uint64_t zs_num_entries;	/* The number of zap entries */
+	uint64_t zs_salt;		/* salt to stir into hash function */
+
+	/*
+	 * Histograms.  For all histograms, the last index
+	 * (ZAP_HISTOGRAM_SIZE-1) includes any values which are greater
+	 * than what can be represented.  For example
+	 * zs_leafs_with_n5_entries[ZAP_HISTOGRAM_SIZE-1] is the number
+	 * of leafs with more than 45 entries.
+	 */
+
+	/*
+	 * zs_leafs_with_n_pointers[n] is the number of leafs with
+	 * 2^n pointers to it.
+	 */
+	uint64_t zs_leafs_with_2n_pointers[ZAP_HISTOGRAM_SIZE];
+
+	/*
+	 * zs_leafs_with_n_entries[n] is the number of leafs with
+	 * [n*5, (n+1)*5) entries.  In the current implementation, there
+	 * can be at most 55 entries in any block, but there may be
+	 * fewer if the name or value is large, or the block is not
+	 * completely full.
+	 */
+	uint64_t zs_blocks_with_n5_entries[ZAP_HISTOGRAM_SIZE];
+
+	/*
+	 * zs_leafs_n_tenths_full[n] is the number of leafs whose
+	 * fullness is in the range [n/10, (n+1)/10).
+	 */
+	uint64_t zs_blocks_n_tenths_full[ZAP_HISTOGRAM_SIZE];
+
+	/*
+	 * zs_entries_using_n_chunks[n] is the number of entries which
+	 * consume n 24-byte chunks.  (Note, large names/values only use
+	 * one chunk, but contribute to zs_num_blocks_large.)
+	 */
+	uint64_t zs_entries_using_n_chunks[ZAP_HISTOGRAM_SIZE];
+
+	/*
+	 * zs_buckets_with_n_entries[n] is the number of buckets (each
+	 * leaf has 64 buckets) with n entries.
+	 * zs_buckets_with_n_entries[1] should be very close to
+	 * zs_num_entries.
+	 */
+	uint64_t zs_buckets_with_n_entries[ZAP_HISTOGRAM_SIZE];
+} zap_stats_t;
+
+/*
+ * Get statistics about a ZAP object.  Note: you need to be aware of the
+ * internal implementation of the ZAP to correctly interpret some of the
+ * statistics.  This interface shouldn't be relied on unless you really
+ * know what you're doing.
+ */
+int zap_get_stats(objset_t *ds, uint64_t zapobj, zap_stats_t *zs);
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* _SYS_ZAP_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/include/sys/zap_impl.h
@@ -0,0 +1,237 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014 Spectra Logic Corporation, All rights reserved.
+ */
+
+#ifndef	_SYS_ZAP_IMPL_H
+#define	_SYS_ZAP_IMPL_H
+
+#include <sys/zap.h>
+#include <sys/zfs_context.h>
+#include <sys/avl.h>
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+extern int fzap_default_block_shift;
+
+#define	ZAP_MAGIC 0x2F52AB2ABULL
+
+#define	FZAP_BLOCK_SHIFT(zap)	((zap)->zap_f.zap_block_shift)
+
+#define	MZAP_ENT_LEN		64
+#define	MZAP_NAME_LEN		(MZAP_ENT_LEN - 8 - 4 - 2)
+#define	MZAP_MAX_BLKSZ		SPA_OLD_MAXBLOCKSIZE
+
+#define	ZAP_NEED_CD		(-1U)
+
+typedef struct mzap_ent_phys {
+	uint64_t mze_value;
+	uint32_t mze_cd;
+	uint16_t mze_pad;	/* in case we want to chain them someday */
+	char mze_name[MZAP_NAME_LEN];
+} mzap_ent_phys_t;
+
+typedef struct mzap_phys {
+	uint64_t mz_block_type;	/* ZBT_MICRO */
+	uint64_t mz_salt;
+	uint64_t mz_normflags;
+	uint64_t mz_pad[5];
+	mzap_ent_phys_t mz_chunk[1];
+	/* actually variable size depending on block size */
+} mzap_phys_t;
+
+typedef struct mzap_ent {
+	avl_node_t mze_node;
+	int mze_chunkid;
+	uint64_t mze_hash;
+	uint32_t mze_cd; /* copy from mze_phys->mze_cd */
+} mzap_ent_t;
+
+#define	MZE_PHYS(zap, mze) \
+	(&zap_m_phys(zap)->mz_chunk[(mze)->mze_chunkid])
+
+/*
+ * The (fat) zap is stored in one object. It is an array of
+ * 1<<FZAP_BLOCK_SHIFT byte blocks. The layout looks like one of:
+ *
+ * ptrtbl fits in first block:
+ * 	[zap_phys_t zap_ptrtbl_shift < 6] [zap_leaf_t] ...
+ *
+ * ptrtbl too big for first block:
+ * 	[zap_phys_t zap_ptrtbl_shift >= 6] [zap_leaf_t] [ptrtbl] ...
+ *
+ */
+
+struct dmu_buf;
+struct zap_leaf;
+
+#define	ZBT_LEAF		((1ULL << 63) + 0)
+#define	ZBT_HEADER		((1ULL << 63) + 1)
+#define	ZBT_MICRO		((1ULL << 63) + 3)
+/* any other values are ptrtbl blocks */
+
+/*
+ * the embedded pointer table takes up half a block:
+ * block size / entry size (2^3) / 2
+ */
+#define	ZAP_EMBEDDED_PTRTBL_SHIFT(zap) (FZAP_BLOCK_SHIFT(zap) - 3 - 1)
+
+/*
+ * The embedded pointer table starts half-way through the block.  Since
+ * the pointer table itself is half the block, it starts at (64-bit)
+ * word number (1<<ZAP_EMBEDDED_PTRTBL_SHIFT(zap)).
+ */
+#define	ZAP_EMBEDDED_PTRTBL_ENT(zap, idx) \
+	((uint64_t *)zap_f_phys(zap)) \
+	[(idx) + (1<<ZAP_EMBEDDED_PTRTBL_SHIFT(zap))]
+
+/*
+ * TAKE NOTE:
+ * If zap_phys_t is modified, zap_byteswap() must be modified.
+ */
+typedef struct zap_phys {
+	uint64_t zap_block_type;	/* ZBT_HEADER */
+	uint64_t zap_magic;		/* ZAP_MAGIC */
+
+	struct zap_table_phys {
+		uint64_t zt_blk;	/* starting block number */
+		uint64_t zt_numblks;	/* number of blocks */
+		uint64_t zt_shift;	/* bits to index it */
+		uint64_t zt_nextblk;	/* next (larger) copy start block */
+		uint64_t zt_blks_copied; /* number source blocks copied */
+	} zap_ptrtbl;
+
+	uint64_t zap_freeblk;		/* the next free block */
+	uint64_t zap_num_leafs;		/* number of leafs */
+	uint64_t zap_num_entries;	/* number of entries */
+	uint64_t zap_salt;		/* salt to stir into hash function */
+	uint64_t zap_normflags;		/* flags for u8_textprep_str() */
+	uint64_t zap_flags;		/* zap_flags_t */
+	/*
+	 * This structure is followed by padding, and then the embedded
+	 * pointer table.  The embedded pointer table takes up second
+	 * half of the block.  It is accessed using the
+	 * ZAP_EMBEDDED_PTRTBL_ENT() macro.
+	 */
+} zap_phys_t;
+
+typedef struct zap_table_phys zap_table_phys_t;
+
+typedef struct zap {
+	dmu_buf_user_t zap_dbu;
+	objset_t *zap_objset;
+	uint64_t zap_object;
+	struct dmu_buf *zap_dbuf;
+	krwlock_t zap_rwlock;
+	boolean_t zap_ismicro;
+	int zap_normflags;
+	uint64_t zap_salt;
+	union {
+		struct {
+			/*
+			 * zap_num_entries_mtx protects
+			 * zap_num_entries
+			 */
+			kmutex_t zap_num_entries_mtx;
+			int zap_block_shift;
+		} zap_fat;
+		struct {
+			int16_t zap_num_entries;
+			int16_t zap_num_chunks;
+			int16_t zap_alloc_next;
+			avl_tree_t zap_avl;
+		} zap_micro;
+	} zap_u;
+} zap_t;
+
+static inline zap_phys_t *
+zap_f_phys(zap_t *zap)
+{
+	return (zap->zap_dbuf->db_data);
+}
+
+static inline mzap_phys_t *
+zap_m_phys(zap_t *zap)
+{
+	return (zap->zap_dbuf->db_data);
+}
+
+typedef struct zap_name {
+	zap_t *zn_zap;
+	int zn_key_intlen;
+	const void *zn_key_orig;
+	int zn_key_orig_numints;
+	const void *zn_key_norm;
+	int zn_key_norm_numints;
+	uint64_t zn_hash;
+	matchtype_t zn_matchtype;
+	char zn_normbuf[ZAP_MAXNAMELEN];
+} zap_name_t;
+
+#define	zap_f	zap_u.zap_fat
+#define	zap_m	zap_u.zap_micro
+
+boolean_t zap_match(zap_name_t *zn, const char *matchname);
+int zap_lockdir(objset_t *os, uint64_t obj, dmu_tx_t *tx,
+    krw_t lti, boolean_t fatreader, boolean_t adding, zap_t **zapp);
+void zap_unlockdir(zap_t *zap);
+void zap_evict(void *dbu);
+zap_name_t *zap_name_alloc(zap_t *zap, const char *key, matchtype_t mt);
+void zap_name_free(zap_name_t *zn);
+int zap_hashbits(zap_t *zap);
+uint32_t zap_maxcd(zap_t *zap);
+uint64_t zap_getflags(zap_t *zap);
+
+#define	ZAP_HASH_IDX(hash, n) (((n) == 0) ? 0 : ((hash) >> (64 - (n))))
+
+void fzap_byteswap(void *buf, size_t size);
+int fzap_count(zap_t *zap, uint64_t *count);
+int fzap_lookup(zap_name_t *zn,
+    uint64_t integer_size, uint64_t num_integers, void *buf,
+    char *realname, int rn_len, boolean_t *normalization_conflictp);
+void fzap_prefetch(zap_name_t *zn);
+int fzap_count_write(zap_name_t *zn, int add, uint64_t *towrite,
+    uint64_t *tooverwrite);
+int fzap_add(zap_name_t *zn, uint64_t integer_size, uint64_t num_integers,
+    const void *val, dmu_tx_t *tx);
+int fzap_update(zap_name_t *zn,
+    int integer_size, uint64_t num_integers, const void *val, dmu_tx_t *tx);
+int fzap_length(zap_name_t *zn,
+    uint64_t *integer_size, uint64_t *num_integers);
+int fzap_remove(zap_name_t *zn, dmu_tx_t *tx);
+int fzap_cursor_retrieve(zap_t *zap, zap_cursor_t *zc, zap_attribute_t *za);
+void fzap_get_stats(zap_t *zap, zap_stats_t *zs);
+void zap_put_leaf(struct zap_leaf *l);
+
+int fzap_add_cd(zap_name_t *zn,
+    uint64_t integer_size, uint64_t num_integers,
+    const void *val, uint32_t cd, dmu_tx_t *tx);
+void fzap_upgrade(zap_t *zap, dmu_tx_t *tx, zap_flags_t flags);
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif /* _SYS_ZAP_IMPL_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/include/sys/zap_leaf.h
@@ -0,0 +1,248 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014 Spectra Logic Corporation, All rights reserved.
+ */
+
+#ifndef	_SYS_ZAP_LEAF_H
+#define	_SYS_ZAP_LEAF_H
+
+#include <sys/zap.h>
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+struct zap;
+struct zap_name;
+struct zap_stats;
+
+#define	ZAP_LEAF_MAGIC 0x2AB1EAF
+
+/* chunk size = 24 bytes */
+#define	ZAP_LEAF_CHUNKSIZE 24
+
+/*
+ * The amount of space available for chunks is:
+ * block size (1<<l->l_bs) - hash entry size (2) * number of hash
+ * entries - header space (2*chunksize)
+ */
+#define	ZAP_LEAF_NUMCHUNKS(l) \
+	(((1<<(l)->l_bs) - 2*ZAP_LEAF_HASH_NUMENTRIES(l)) / \
+	ZAP_LEAF_CHUNKSIZE - 2)
+
+/*
+ * The amount of space within the chunk available for the array is:
+ * chunk size - space for type (1) - space for next pointer (2)
+ */
+#define	ZAP_LEAF_ARRAY_BYTES (ZAP_LEAF_CHUNKSIZE - 3)
+
+#define	ZAP_LEAF_ARRAY_NCHUNKS(bytes) \
+	(((bytes)+ZAP_LEAF_ARRAY_BYTES-1)/ZAP_LEAF_ARRAY_BYTES)
+
+/*
+ * Low water mark:  when there are only this many chunks free, start
+ * growing the ptrtbl.  Ideally, this should be larger than a
+ * "reasonably-sized" entry.  20 chunks is more than enough for the
+ * largest directory entry (MAXNAMELEN (256) byte name, 8-byte value),
+ * while still being only around 3% for 16k blocks.
+ */
+#define	ZAP_LEAF_LOW_WATER (20)
+
+/*
+ * The leaf hash table has block size / 2^5 (32) number of entries,
+ * which should be more than enough for the maximum number of entries,
+ * which is less than block size / CHUNKSIZE (24) / minimum number of
+ * chunks per entry (3).
+ */
+#define	ZAP_LEAF_HASH_SHIFT(l) ((l)->l_bs - 5)
+#define	ZAP_LEAF_HASH_NUMENTRIES(l) (1 << ZAP_LEAF_HASH_SHIFT(l))
+
+/*
+ * The chunks start immediately after the hash table.  The end of the
+ * hash table is at l_hash + HASH_NUMENTRIES, which we simply cast to a
+ * chunk_t.
+ */
+#define	ZAP_LEAF_CHUNK(l, idx) \
+	((zap_leaf_chunk_t *) \
+	(zap_leaf_phys(l)->l_hash + ZAP_LEAF_HASH_NUMENTRIES(l)))[idx]
+#define	ZAP_LEAF_ENTRY(l, idx) (&ZAP_LEAF_CHUNK(l, idx).l_entry)
+
+typedef enum zap_chunk_type {
+	ZAP_CHUNK_FREE = 253,
+	ZAP_CHUNK_ENTRY = 252,
+	ZAP_CHUNK_ARRAY = 251,
+	ZAP_CHUNK_TYPE_MAX = 250
+} zap_chunk_type_t;
+
+#define	ZLF_ENTRIES_CDSORTED (1<<0)
+
+/*
+ * TAKE NOTE:
+ * If zap_leaf_phys_t is modified, zap_leaf_byteswap() must be modified.
+ */
+typedef struct zap_leaf_phys {
+	struct zap_leaf_header {
+		/* Public to ZAP */
+		uint64_t lh_block_type;		/* ZBT_LEAF */
+		uint64_t lh_pad1;
+		uint64_t lh_prefix;		/* hash prefix of this leaf */
+		uint32_t lh_magic;		/* ZAP_LEAF_MAGIC */
+		uint16_t lh_nfree;		/* number free chunks */
+		uint16_t lh_nentries;		/* number of entries */
+		uint16_t lh_prefix_len;		/* num bits used to id this */
+
+		/* Private to zap_leaf */
+		uint16_t lh_freelist;		/* chunk head of free list */
+		uint8_t lh_flags;		/* ZLF_* flags */
+		uint8_t lh_pad2[11];
+	} l_hdr; /* 2 24-byte chunks */
+
+	/*
+	 * The header is followed by a hash table with
+	 * ZAP_LEAF_HASH_NUMENTRIES(zap) entries.  The hash table is
+	 * followed by an array of ZAP_LEAF_NUMCHUNKS(zap)
+	 * zap_leaf_chunk structures.  These structures are accessed
+	 * with the ZAP_LEAF_CHUNK() macro.
+	 */
+
+	uint16_t l_hash[1];
+} zap_leaf_phys_t;
+
+typedef union zap_leaf_chunk {
+	struct zap_leaf_entry {
+		uint8_t le_type; 		/* always ZAP_CHUNK_ENTRY */
+		uint8_t le_value_intlen;	/* size of value's ints */
+		uint16_t le_next;		/* next entry in hash chain */
+		uint16_t le_name_chunk;		/* first chunk of the name */
+		uint16_t le_name_numints;	/* ints in name (incl null) */
+		uint16_t le_value_chunk;	/* first chunk of the value */
+		uint16_t le_value_numints;	/* value length in ints */
+		uint32_t le_cd;			/* collision differentiator */
+		uint64_t le_hash;		/* hash value of the name */
+	} l_entry;
+	struct zap_leaf_array {
+		uint8_t la_type;		/* always ZAP_CHUNK_ARRAY */
+		uint8_t la_array[ZAP_LEAF_ARRAY_BYTES];
+		uint16_t la_next;		/* next blk or CHAIN_END */
+	} l_array;
+	struct zap_leaf_free {
+		uint8_t lf_type;		/* always ZAP_CHUNK_FREE */
+		uint8_t lf_pad[ZAP_LEAF_ARRAY_BYTES];
+		uint16_t lf_next;	/* next in free list, or CHAIN_END */
+	} l_free;
+} zap_leaf_chunk_t;
+
+typedef struct zap_leaf {
+	dmu_buf_user_t l_dbu;
+	krwlock_t l_rwlock;
+	uint64_t l_blkid;		/* 1<<ZAP_BLOCK_SHIFT byte block off */
+	int l_bs;			/* block size shift */
+	dmu_buf_t *l_dbuf;
+} zap_leaf_t;
+
+static inline zap_leaf_phys_t *
+zap_leaf_phys(zap_leaf_t *l)
+{
+	return (l->l_dbuf->db_data);
+}
+
+typedef struct zap_entry_handle {
+	/* Set by zap_leaf and public to ZAP */
+	uint64_t zeh_num_integers;
+	uint64_t zeh_hash;
+	uint32_t zeh_cd;
+	uint8_t zeh_integer_size;
+
+	/* Private to zap_leaf */
+	uint16_t zeh_fakechunk;
+	uint16_t *zeh_chunkp;
+	zap_leaf_t *zeh_leaf;
+} zap_entry_handle_t;
+
+/*
+ * Return a handle to the named entry, or ENOENT if not found.  The hash
+ * value must equal zap_hash(name).
+ */
+extern int zap_leaf_lookup(zap_leaf_t *l,
+    struct zap_name *zn, zap_entry_handle_t *zeh);
+
+/*
+ * Return a handle to the entry with this hash+cd, or the entry with the
+ * next closest hash+cd.
+ */
+extern int zap_leaf_lookup_closest(zap_leaf_t *l,
+    uint64_t hash, uint32_t cd, zap_entry_handle_t *zeh);
+
+/*
+ * Read the first num_integers in the attribute.  Integer size
+ * conversion will be done without sign extension.  Return EINVAL if
+ * integer_size is too small.  Return EOVERFLOW if there are more than
+ * num_integers in the attribute.
+ */
+extern int zap_entry_read(const zap_entry_handle_t *zeh,
+    uint8_t integer_size, uint64_t num_integers, void *buf);
+
+extern int zap_entry_read_name(struct zap *zap, const zap_entry_handle_t *zeh,
+    uint16_t buflen, char *buf);
+
+/*
+ * Replace the value of an existing entry.
+ *
+ * May fail if it runs out of space (ENOSPC).
+ */
+extern int zap_entry_update(zap_entry_handle_t *zeh,
+    uint8_t integer_size, uint64_t num_integers, const void *buf);
+
+/*
+ * Remove an entry.
+ */
+extern void zap_entry_remove(zap_entry_handle_t *zeh);
+
+/*
+ * Create an entry. An equal entry must not exist, and this entry must
+ * belong in this leaf (according to its hash value).  Fills in the
+ * entry handle on success.  Returns 0 on success or ENOSPC on failure.
+ */
+extern int zap_entry_create(zap_leaf_t *l, struct zap_name *zn, uint32_t cd,
+    uint8_t integer_size, uint64_t num_integers, const void *buf,
+    zap_entry_handle_t *zeh);
+
+/* Determine whether there is another entry with the same normalized form. */
+extern boolean_t zap_entry_normalization_conflict(zap_entry_handle_t *zeh,
+    struct zap_name *zn, const char *name, struct zap *zap);
+
+/*
+ * Other stuff.
+ */
+
+extern void zap_leaf_init(zap_leaf_t *l, boolean_t sort);
+extern void zap_leaf_byteswap(zap_leaf_phys_t *buf, int len);
+extern void zap_leaf_split(zap_leaf_t *l, zap_leaf_t *nl, boolean_t sort);
+extern void zap_leaf_stats(struct zap *zap, zap_leaf_t *l,
+    struct zap_stats *zs);
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif /* _SYS_ZAP_LEAF_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/include/sys/zfeature.h
@@ -0,0 +1,73 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2013 by Delphix. All rights reserved.
+ */
+
+#ifndef _SYS_ZFEATURE_H
+#define	_SYS_ZFEATURE_H
+
+#include <sys/nvpair.h>
+#include <sys/txg.h>
+#include "zfeature_common.h"
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+#define	VALID_FEATURE_FID(fid)	((fid) >= 0 && (fid) < SPA_FEATURES)
+#define	VALID_FEATURE_OR_NONE(fid)	((fid) == SPA_FEATURE_NONE ||	\
+    VALID_FEATURE_FID(fid))
+
+struct spa;
+struct dmu_tx;
+struct objset;
+
+extern void spa_feature_create_zap_objects(struct spa *, struct dmu_tx *);
+extern void spa_feature_enable(struct spa *, spa_feature_t,
+    struct dmu_tx *);
+extern void spa_feature_incr(struct spa *, spa_feature_t, struct dmu_tx *);
+extern void spa_feature_decr(struct spa *, spa_feature_t, struct dmu_tx *);
+extern boolean_t spa_feature_is_enabled(struct spa *, spa_feature_t);
+extern boolean_t spa_feature_is_active(struct spa *, spa_feature_t);
+extern boolean_t spa_feature_enabled_txg(spa_t *spa, spa_feature_t fid,
+    uint64_t *txg);
+extern uint64_t spa_feature_refcount(spa_t *, spa_feature_t, uint64_t);
+extern boolean_t spa_features_check(spa_t *, boolean_t, nvlist_t *, nvlist_t *);
+
+/*
+ * These functions are only exported for zhack and zdb; normal callers should
+ * use the above interfaces.
+ */
+extern int feature_get_refcount(struct spa *, zfeature_info_t *, uint64_t *);
+extern int feature_get_refcount_from_disk(spa_t *spa, zfeature_info_t *feature,
+    uint64_t *res);
+extern void feature_enable_sync(struct spa *, zfeature_info_t *,
+    struct dmu_tx *);
+extern void feature_sync(struct spa *, zfeature_info_t *, uint64_t,
+    struct dmu_tx *);
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif /* _SYS_ZFEATURE_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/include/sys/zfs_acl.h
@@ -0,0 +1,247 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ */
+
+#ifndef	_SYS_FS_ZFS_ACL_H
+#define	_SYS_FS_ZFS_ACL_H
+
+#ifdef _KERNEL
+#include <sys/isa_defs.h>
+#include <sys/types32.h>
+#include <sys/xvattr.h>
+#endif
+#include <sys/acl.h>
+#include <sys/dmu.h>
+#include <sys/zfs_fuid.h>
+#include <sys/sa.h>
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+struct znode_phys;
+
+#define	ACE_SLOT_CNT	6
+#define	ZFS_ACL_VERSION_INITIAL 0ULL
+#define	ZFS_ACL_VERSION_FUID	1ULL
+#define	ZFS_ACL_VERSION		ZFS_ACL_VERSION_FUID
+
+/*
+ * ZFS ACLs (Access Control Lists) are stored in various forms.
+ *
+ * Files created with ACL version ZFS_ACL_VERSION_INITIAL
+ * will all be created with fixed length ACEs of type
+ * zfs_oldace_t.
+ *
+ * Files with ACL version ZFS_ACL_VERSION_FUID will be created
+ * with various sized ACEs.  The abstraction entries will utilize
+ * zfs_ace_hdr_t, normal user/group entries will use zfs_ace_t
+ * and some specialized CIFS ACEs will use zfs_object_ace_t.
+ */
+
+/*
+ * All ACEs have a common hdr.  For
+ * owner@, group@, and everyone@ this is all
+ * thats needed.
+ */
+typedef struct zfs_ace_hdr {
+	uint16_t z_type;
+	uint16_t z_flags;
+	uint32_t z_access_mask;
+} zfs_ace_hdr_t;
+
+typedef zfs_ace_hdr_t zfs_ace_abstract_t;
+
+/*
+ * Standard ACE
+ */
+typedef struct zfs_ace {
+	zfs_ace_hdr_t	z_hdr;
+	uint64_t	z_fuid;
+} zfs_ace_t;
+
+/*
+ * The following type only applies to ACE_ACCESS_ALLOWED|DENIED_OBJECT_ACE_TYPE
+ * and will only be set/retrieved in a CIFS context.
+ */
+
+typedef struct zfs_object_ace {
+	zfs_ace_t	z_ace;
+	uint8_t		z_object_type[16]; /* object type */
+	uint8_t		z_inherit_type[16]; /* inherited object type */
+} zfs_object_ace_t;
+
+typedef struct zfs_oldace {
+	uint32_t	z_fuid;		/* "who" */
+	uint32_t	z_access_mask;  /* access mask */
+	uint16_t	z_flags;	/* flags, i.e inheritance */
+	uint16_t	z_type;		/* type of entry allow/deny */
+} zfs_oldace_t;
+
+typedef struct zfs_acl_phys_v0 {
+	uint64_t	z_acl_extern_obj;	/* ext acl pieces */
+	uint32_t	z_acl_count;		/* Number of ACEs */
+	uint16_t	z_acl_version;		/* acl version */
+	uint16_t	z_acl_pad;		/* pad */
+	zfs_oldace_t	z_ace_data[ACE_SLOT_CNT]; /* 6 standard ACEs */
+} zfs_acl_phys_v0_t;
+
+#define	ZFS_ACE_SPACE	(sizeof (zfs_oldace_t) * ACE_SLOT_CNT)
+
+/*
+ * Size of ACL count is always 2 bytes.
+ * Necessary to for dealing with both V0 ACL and V1 ACL layout
+ */
+#define	ZFS_ACL_COUNT_SIZE	(sizeof (uint16_t))
+
+typedef struct zfs_acl_phys {
+	uint64_t	z_acl_extern_obj;	  /* ext acl pieces */
+	uint32_t	z_acl_size;		  /* Number of bytes in ACL */
+	uint16_t	z_acl_version;		  /* acl version */
+	uint16_t	z_acl_count;		  /* ace count */
+	uint8_t	z_ace_data[ZFS_ACE_SPACE]; /* space for embedded ACEs */
+} zfs_acl_phys_t;
+
+typedef struct acl_ops {
+	uint32_t	(*ace_mask_get) (void *acep); /* get  access mask */
+	void 		(*ace_mask_set) (void *acep,
+			    uint32_t mask); /* set access mask */
+	uint16_t	(*ace_flags_get) (void *acep);	/* get flags */
+	void		(*ace_flags_set) (void *acep,
+			    uint16_t flags); /* set flags */
+	uint16_t	(*ace_type_get)(void *acep); /* get type */
+	void		(*ace_type_set)(void *acep,
+			    uint16_t type); /* set type */
+	uint64_t	(*ace_who_get)(void *acep); /* get who/fuid */
+	void		(*ace_who_set)(void *acep,
+			    uint64_t who); /* set who/fuid */
+	size_t		(*ace_size)(void *acep); /* how big is this ace */
+	size_t		(*ace_abstract_size)(void); /* sizeof abstract entry */
+	int		(*ace_mask_off)(void); /* off of access mask in ace */
+	/* ptr to data if any */
+	int		(*ace_data)(void *acep, void **datap);
+} acl_ops_t;
+
+/*
+ * A zfs_acl_t structure is composed of a list of zfs_acl_node_t's.
+ * Each node will have one or more ACEs associated with it.  You will
+ * only have multiple nodes during a chmod operation.   Normally only
+ * one node is required.
+ */
+typedef struct zfs_acl_node {
+	list_node_t	z_next;		/* Next chunk of ACEs */
+	void		*z_acldata;	/* pointer into actual ACE(s) */
+	void		*z_allocdata;	/* pointer to kmem allocated memory */
+	size_t		z_allocsize;	/* Size of blob in bytes */
+	size_t		z_size;		/* length of ACL data */
+	uint64_t	z_ace_count;	/* number of ACEs in this acl node */
+	int		z_ace_idx;	/* ace iterator positioned on */
+} zfs_acl_node_t;
+
+typedef struct zfs_acl {
+	uint64_t	z_acl_count;	/* Number of ACEs */
+	size_t		z_acl_bytes;	/* Number of bytes in ACL */
+	uint_t		z_version;	/* version of ACL */
+	void		*z_next_ace;	/* pointer to next ACE */
+	uint64_t	z_hints;	/* ACL hints (ZFS_INHERIT_ACE ...) */
+	zfs_acl_node_t	*z_curr_node;	/* current node iterator is handling */
+	list_t		z_acl;		/* chunks of ACE data */
+	acl_ops_t	*z_ops;		/* ACL operations */
+} zfs_acl_t;
+
+typedef struct acl_locator_cb {
+	zfs_acl_t *cb_aclp;
+	zfs_acl_node_t *cb_acl_node;
+} zfs_acl_locator_cb_t;
+
+#define	ACL_DATA_ALLOCED	0x1
+#define	ZFS_ACL_SIZE(aclcnt)	(sizeof (ace_t) * (aclcnt))
+
+struct zfs_fuid_info;
+
+typedef struct zfs_acl_ids {
+	uint64_t		z_fuid;		/* file owner fuid */
+	uint64_t		z_fgid;		/* file group owner fuid */
+	uint64_t		z_mode;		/* mode to set on create */
+	zfs_acl_t		*z_aclp;	/* ACL to create with file */
+	struct zfs_fuid_info 	*z_fuidp;	/* for tracking fuids for log */
+} zfs_acl_ids_t;
+
+/*
+ * Property values for acl_mode and acl_inherit.
+ *
+ * acl_mode can take discard, noallow, groupmask and passthrough.
+ * whereas acl_inherit has secure instead of groupmask.
+ */
+
+#define	ZFS_ACL_DISCARD		0
+#define	ZFS_ACL_NOALLOW		1
+#define	ZFS_ACL_GROUPMASK	2
+#define	ZFS_ACL_PASSTHROUGH	3
+#define	ZFS_ACL_RESTRICTED	4
+#define	ZFS_ACL_PASSTHROUGH_X	5
+
+struct znode;
+struct zfs_sb;
+
+#ifdef _KERNEL
+int zfs_acl_ids_create(struct znode *, int, vattr_t *,
+    cred_t *, vsecattr_t *, zfs_acl_ids_t *);
+void zfs_acl_ids_free(zfs_acl_ids_t *);
+boolean_t zfs_acl_ids_overquota(struct zfs_sb *, zfs_acl_ids_t *);
+int zfs_getacl(struct znode *, vsecattr_t *, boolean_t, cred_t *);
+int zfs_setacl(struct znode *, vsecattr_t *, boolean_t, cred_t *);
+void zfs_acl_rele(void *);
+void zfs_oldace_byteswap(ace_t *, int);
+void zfs_ace_byteswap(void *, size_t, boolean_t);
+extern boolean_t zfs_has_access(struct znode *zp, cred_t *cr);
+extern int zfs_zaccess(struct znode *, int, int, boolean_t, cred_t *);
+int zfs_fastaccesschk_execute(struct znode *, cred_t *);
+extern int zfs_zaccess_rwx(struct znode *, mode_t, int, cred_t *);
+extern int zfs_zaccess_unix(struct znode *, mode_t, cred_t *);
+extern int zfs_acl_access(struct znode *, int, cred_t *);
+void zfs_acl_chmod_setattr(struct znode *, zfs_acl_t **, uint64_t);
+int zfs_zaccess_delete(struct znode *, struct znode *, cred_t *);
+int zfs_zaccess_rename(struct znode *, struct znode *,
+    struct znode *, struct znode *, cred_t *cr);
+void zfs_acl_free(zfs_acl_t *);
+int zfs_vsec_2_aclp(struct zfs_sb *, umode_t, vsecattr_t *, cred_t *,
+    struct zfs_fuid_info **, zfs_acl_t **);
+int zfs_aclset_common(struct znode *, zfs_acl_t *, cred_t *, dmu_tx_t *);
+uint64_t zfs_external_acl(struct znode *);
+int zfs_znode_acl_version(struct znode *);
+int zfs_acl_size(struct znode *, int *);
+zfs_acl_t *zfs_acl_alloc(int);
+zfs_acl_node_t *zfs_acl_node_alloc(size_t);
+void zfs_acl_xform(struct znode *, zfs_acl_t *, cred_t *);
+void zfs_acl_data_locator(void **, uint32_t *, uint32_t, boolean_t, void *);
+uint64_t zfs_mode_compute(uint64_t, zfs_acl_t *,
+    uint64_t *, uint64_t, uint64_t);
+int zfs_acl_chown_setattr(struct znode *);
+
+#endif
+
+#ifdef	__cplusplus
+}
+#endif
+#endif	/* _SYS_FS_ZFS_ACL_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/include/sys/zfs_context.h
@@ -0,0 +1,753 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
+ * Copyright (c) 2012, Joyent, Inc. All rights reserved.
+ * Copyright (c) 2012, 2014 by Delphix. All rights reserved.
+ */
+
+#ifndef _SYS_ZFS_CONTEXT_H
+#define	_SYS_ZFS_CONTEXT_H
+
+#ifdef __KERNEL__
+
+#include <sys/note.h>
+#include <sys/types.h>
+#include <sys/t_lock.h>
+#include <sys/atomic.h>
+#include <sys/sysmacros.h>
+#include <sys/bitmap.h>
+#include <sys/cmn_err.h>
+#include <sys/kmem.h>
+#include <sys/kmem_cache.h>
+#include <sys/vmem.h>
+#include <sys/taskq.h>
+#include <sys/buf.h>
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/cpuvar.h>
+#include <sys/kobj.h>
+#include <sys/conf.h>
+#include <sys/disp.h>
+#include <sys/debug.h>
+#include <sys/random.h>
+#include <sys/byteorder.h>
+#include <sys/systm.h>
+#include <sys/list.h>
+#include <sys/uio_impl.h>
+#include <sys/dirent.h>
+#include <sys/time.h>
+#include <vm/seg_kmem.h>
+#include <sys/zone.h>
+#include <sys/sdt.h>
+#include <sys/zfs_debug.h>
+#include <sys/zfs_delay.h>
+#include <sys/fm/fs/zfs.h>
+#include <sys/sunddi.h>
+#include <sys/ctype.h>
+#include <sys/disp.h>
+#include <sys/trace.h>
+#include <linux/dcache_compat.h>
+#include <linux/utsname_compat.h>
+
+#else /* _KERNEL */
+
+#define	_SYS_MUTEX_H
+#define	_SYS_RWLOCK_H
+#define	_SYS_CONDVAR_H
+#define	_SYS_SYSTM_H
+#define	_SYS_T_LOCK_H
+#define	_SYS_VNODE_H
+#define	_SYS_VFS_H
+#define	_SYS_SUNDDI_H
+#define	_SYS_CALLB_H
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <stdarg.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <errno.h>
+#include <string.h>
+#include <strings.h>
+#include <pthread.h>
+#include <synch.h>
+#include <assert.h>
+#include <alloca.h>
+#include <umem.h>
+#include <limits.h>
+#include <atomic.h>
+#include <dirent.h>
+#include <time.h>
+#include <ctype.h>
+#include <signal.h>
+#include <sys/mman.h>
+#include <sys/note.h>
+#include <sys/types.h>
+#include <sys/cred.h>
+#include <sys/sysmacros.h>
+#include <sys/bitmap.h>
+#include <sys/resource.h>
+#include <sys/byteorder.h>
+#include <sys/list.h>
+#include <sys/uio.h>
+#include <sys/zfs_debug.h>
+#include <sys/sdt.h>
+#include <sys/kstat.h>
+#include <sys/u8_textprep.h>
+#include <sys/fm/fs/zfs.h>
+#include <sys/sunddi.h>
+#include <sys/debug.h>
+#include <sys/utsname.h>
+
+/*
+ * Stack
+ */
+
+#define	noinline	__attribute__((noinline))
+
+/*
+ * Debugging
+ */
+
+/*
+ * Note that we are not using the debugging levels.
+ */
+
+#define	CE_CONT		0	/* continuation		*/
+#define	CE_NOTE		1	/* notice		*/
+#define	CE_WARN		2	/* warning		*/
+#define	CE_PANIC	3	/* panic		*/
+#define	CE_IGNORE	4	/* print nothing	*/
+
+/*
+ * ZFS debugging
+ */
+
+extern void dprintf_setup(int *argc, char **argv);
+
+extern void cmn_err(int, const char *, ...);
+extern void vcmn_err(int, const char *, va_list);
+extern void panic(const char *, ...);
+extern void vpanic(const char *, va_list);
+
+#define	fm_panic	panic
+
+extern int aok;
+
+/*
+ * DTrace SDT probes have different signatures in userland than they do in
+ * kernel.  If they're being used in kernel code, re-define them out of
+ * existence for their counterparts in libzpool.
+ */
+
+#ifdef DTRACE_PROBE
+#undef	DTRACE_PROBE
+#endif	/* DTRACE_PROBE */
+#define	DTRACE_PROBE(a) \
+	ZFS_PROBE0(#a)
+
+#ifdef DTRACE_PROBE1
+#undef	DTRACE_PROBE1
+#endif	/* DTRACE_PROBE1 */
+#define	DTRACE_PROBE1(a, b, c) \
+	ZFS_PROBE1(#a, (unsigned long)c)
+
+#ifdef DTRACE_PROBE2
+#undef	DTRACE_PROBE2
+#endif	/* DTRACE_PROBE2 */
+#define	DTRACE_PROBE2(a, b, c, d, e) \
+	ZFS_PROBE2(#a, (unsigned long)c, (unsigned long)e)
+
+#ifdef DTRACE_PROBE3
+#undef	DTRACE_PROBE3
+#endif	/* DTRACE_PROBE3 */
+#define	DTRACE_PROBE3(a, b, c, d, e, f, g) \
+	ZFS_PROBE3(#a, (unsigned long)c, (unsigned long)e, (unsigned long)g)
+
+#ifdef DTRACE_PROBE4
+#undef	DTRACE_PROBE4
+#endif	/* DTRACE_PROBE4 */
+#define	DTRACE_PROBE4(a, b, c, d, e, f, g, h, i) \
+	ZFS_PROBE4(#a, (unsigned long)c, (unsigned long)e, (unsigned long)g, \
+	(unsigned long)i)
+
+/*
+ * We use the comma operator so that this macro can be used without much
+ * additional code.  For example, "return (EINVAL);" becomes
+ * "return (SET_ERROR(EINVAL));".  Note that the argument will be evaluated
+ * twice, so it should not have side effects (e.g. something like:
+ * "return (SET_ERROR(log_error(EINVAL, info)));" would log the error twice).
+ */
+#define	SET_ERROR(err) (ZFS_SET_ERROR(err), err)
+
+/*
+ * Threads.  TS_STACK_MIN is dictated by the minimum allowed pthread stack
+ * size.  While TS_STACK_MAX is somewhat arbitrary, it was selected to be
+ * large enough for the expected stack depth while small enough to avoid
+ * exhausting address space with high thread counts.
+ */
+#define	TS_MAGIC		0x72f158ab4261e538ull
+#define	TS_RUN			0x00000002
+#define	TS_STACK_MIN		PTHREAD_STACK_MIN
+#define	TS_STACK_MAX		(256 * 1024)
+
+/* in libzpool, p0 exists only to have its address taken */
+typedef struct proc {
+	uintptr_t	this_is_never_used_dont_dereference_it;
+} proc_t;
+
+extern struct proc p0;
+#define	curproc		(&p0)
+
+typedef void (*thread_func_t)(void *);
+typedef void (*thread_func_arg_t)(void *);
+typedef pthread_t kt_did_t;
+
+#define	kpreempt(x)	((void)0)
+
+typedef struct kthread {
+	kt_did_t	t_tid;
+	thread_func_t	t_func;
+	void *		t_arg;
+	pri_t		t_pri;
+} kthread_t;
+
+#define	curthread			zk_thread_current()
+#define	getcomm()			"unknown"
+#define	thread_exit			zk_thread_exit
+#define	thread_create(stk, stksize, func, arg, len, pp, state, pri)	\
+	zk_thread_create(stk, stksize, (thread_func_t)func, arg,	\
+	    len, NULL, state, pri, PTHREAD_CREATE_DETACHED)
+#define	thread_join(t)			zk_thread_join(t)
+#define	newproc(f, a, cid, pri, ctp, pid)	(ENOSYS)
+
+extern kthread_t *zk_thread_current(void);
+extern void zk_thread_exit(void);
+extern kthread_t *zk_thread_create(caddr_t stk, size_t  stksize,
+	thread_func_t func, void *arg, size_t len,
+	proc_t *pp, int state, pri_t pri, int detachstate);
+extern void zk_thread_join(kt_did_t tid);
+
+#define	kpreempt_disable()	((void)0)
+#define	kpreempt_enable()	((void)0)
+
+#define	PS_NONE		-1
+
+#define	issig(why)	(FALSE)
+#define	ISSIG(thr, why)	(FALSE)
+
+/*
+ * Mutexes
+ */
+#define	MTX_MAGIC	0x9522f51362a6e326ull
+#define	MTX_INIT	((void *)NULL)
+#define	MTX_DEST	((void *)-1UL)
+
+typedef struct kmutex {
+	void		*m_owner;
+	uint64_t	m_magic;
+	pthread_mutex_t	m_lock;
+} kmutex_t;
+
+#define	MUTEX_DEFAULT	0
+#define	MUTEX_HELD(m)	((m)->m_owner == curthread)
+#define	MUTEX_NOT_HELD(m) (!MUTEX_HELD(m))
+
+extern void mutex_init(kmutex_t *mp, char *name, int type, void *cookie);
+extern void mutex_destroy(kmutex_t *mp);
+extern void mutex_enter(kmutex_t *mp);
+extern void mutex_exit(kmutex_t *mp);
+extern int mutex_tryenter(kmutex_t *mp);
+extern void *mutex_owner(kmutex_t *mp);
+extern int mutex_held(kmutex_t *mp);
+
+/*
+ * RW locks
+ */
+#define	RW_MAGIC	0x4d31fb123648e78aull
+#define	RW_INIT		((void *)NULL)
+#define	RW_DEST		((void *)-1UL)
+
+typedef struct krwlock {
+	void			*rw_owner;
+	void			*rw_wr_owner;
+	uint64_t		rw_magic;
+	pthread_rwlock_t	rw_lock;
+	uint_t			rw_readers;
+} krwlock_t;
+
+typedef int krw_t;
+
+#define	RW_READER	0
+#define	RW_WRITER	1
+#define	RW_DEFAULT	RW_READER
+
+#define	RW_READ_HELD(x)		((x)->rw_readers > 0)
+#define	RW_WRITE_HELD(x)	((x)->rw_wr_owner == curthread)
+#define	RW_LOCK_HELD(x)		(RW_READ_HELD(x) || RW_WRITE_HELD(x))
+
+#undef RW_LOCK_HELD
+#define	RW_LOCK_HELD(x)		(RW_READ_HELD(x) || RW_WRITE_HELD(x))
+
+#undef RW_LOCK_HELD
+#define	RW_LOCK_HELD(x)		(RW_READ_HELD(x) || RW_WRITE_HELD(x))
+
+extern void rw_init(krwlock_t *rwlp, char *name, int type, void *arg);
+extern void rw_destroy(krwlock_t *rwlp);
+extern void rw_enter(krwlock_t *rwlp, krw_t rw);
+extern int rw_tryenter(krwlock_t *rwlp, krw_t rw);
+extern int rw_tryupgrade(krwlock_t *rwlp);
+extern void rw_exit(krwlock_t *rwlp);
+#define	rw_downgrade(rwlp) do { } while (0)
+
+extern uid_t crgetuid(cred_t *cr);
+extern uid_t crgetruid(cred_t *cr);
+extern gid_t crgetgid(cred_t *cr);
+extern int crgetngroups(cred_t *cr);
+extern gid_t *crgetgroups(cred_t *cr);
+
+/*
+ * Condition variables
+ */
+#define	CV_MAGIC	0xd31ea9a83b1b30c4ull
+
+typedef struct kcondvar {
+	uint64_t		cv_magic;
+	pthread_cond_t		cv;
+} kcondvar_t;
+
+#define	CV_DEFAULT	0
+
+extern void cv_init(kcondvar_t *cv, char *name, int type, void *arg);
+extern void cv_destroy(kcondvar_t *cv);
+extern void cv_wait(kcondvar_t *cv, kmutex_t *mp);
+extern clock_t cv_timedwait(kcondvar_t *cv, kmutex_t *mp, clock_t abstime);
+extern clock_t cv_timedwait_hires(kcondvar_t *cvp, kmutex_t *mp, hrtime_t tim,
+    hrtime_t res, int flag);
+extern void cv_signal(kcondvar_t *cv);
+extern void cv_broadcast(kcondvar_t *cv);
+#define	cv_timedwait_sig(cv, mp, at)		cv_timedwait(cv, mp, at)
+#define	cv_wait_sig(cv, mp)			cv_wait(cv, mp)
+#define	cv_wait_io(cv, mp)			cv_wait(cv, mp)
+
+/*
+ * Thread-specific data
+ */
+#define	tsd_get(k) pthread_getspecific(k)
+#define	tsd_set(k, v) pthread_setspecific(k, v)
+#define	tsd_create(kp, d) pthread_key_create(kp, d)
+#define	tsd_destroy(kp) /* nothing */
+
+/*
+ * Thread-specific data
+ */
+#define	tsd_get(k) pthread_getspecific(k)
+#define	tsd_set(k, v) pthread_setspecific(k, v)
+#define	tsd_create(kp, d) pthread_key_create(kp, d)
+#define	tsd_destroy(kp) /* nothing */
+
+/*
+ * kstat creation, installation and deletion
+ */
+extern kstat_t *kstat_create(const char *, int,
+    const char *, const char *, uchar_t, ulong_t, uchar_t);
+extern void kstat_install(kstat_t *);
+extern void kstat_delete(kstat_t *);
+extern void kstat_waitq_enter(kstat_io_t *);
+extern void kstat_waitq_exit(kstat_io_t *);
+extern void kstat_runq_enter(kstat_io_t *);
+extern void kstat_runq_exit(kstat_io_t *);
+extern void kstat_waitq_to_runq(kstat_io_t *);
+extern void kstat_runq_back_to_waitq(kstat_io_t *);
+extern void kstat_set_raw_ops(kstat_t *ksp,
+    int (*headers)(char *buf, size_t size),
+    int (*data)(char *buf, size_t size, void *data),
+    void *(*addr)(kstat_t *ksp, loff_t index));
+
+/*
+ * Kernel memory
+ */
+#define	KM_SLEEP		UMEM_NOFAIL
+#define	KM_PUSHPAGE		KM_SLEEP
+#define	KM_NOSLEEP		UMEM_DEFAULT
+#define	KMC_NODEBUG		UMC_NODEBUG
+#define	KMC_KMEM		0x0
+#define	KMC_VMEM		0x0
+#define	kmem_alloc(_s, _f)	umem_alloc(_s, _f)
+#define	kmem_zalloc(_s, _f)	umem_zalloc(_s, _f)
+#define	kmem_free(_b, _s)	umem_free(_b, _s)
+#define	vmem_alloc(_s, _f)	kmem_alloc(_s, _f)
+#define	vmem_zalloc(_s, _f)	kmem_zalloc(_s, _f)
+#define	vmem_free(_b, _s)	kmem_free(_b, _s)
+#define	kmem_cache_create(_a, _b, _c, _d, _e, _f, _g, _h, _i) \
+	umem_cache_create(_a, _b, _c, _d, _e, _f, _g, _h, _i)
+#define	kmem_cache_destroy(_c)	umem_cache_destroy(_c)
+#define	kmem_cache_alloc(_c, _f) umem_cache_alloc(_c, _f)
+#define	kmem_cache_free(_c, _b)	umem_cache_free(_c, _b)
+#define	kmem_debugging()	0
+#define	kmem_cache_reap_now(_c)	umem_cache_reap_now(_c);
+#define	kmem_cache_set_move(_c, _cb)	/* nothing */
+#define	vmem_qcache_reap(_v)		/* nothing */
+#define	POINTER_INVALIDATE(_pp)		/* nothing */
+#define	POINTER_IS_VALID(_p)	0
+
+extern vmem_t *zio_arena;
+
+typedef umem_cache_t kmem_cache_t;
+
+typedef enum kmem_cbrc {
+	KMEM_CBRC_YES,
+	KMEM_CBRC_NO,
+	KMEM_CBRC_LATER,
+	KMEM_CBRC_DONT_NEED,
+	KMEM_CBRC_DONT_KNOW
+} kmem_cbrc_t;
+
+/*
+ * Task queues
+ */
+typedef struct taskq taskq_t;
+typedef uintptr_t taskqid_t;
+typedef void (task_func_t)(void *);
+
+typedef struct taskq_ent {
+	struct taskq_ent	*tqent_next;
+	struct taskq_ent	*tqent_prev;
+	task_func_t		*tqent_func;
+	void			*tqent_arg;
+	uintptr_t		tqent_flags;
+} taskq_ent_t;
+
+#define	TQENT_FLAG_PREALLOC	0x1	/* taskq_dispatch_ent used */
+
+#define	TASKQ_PREPOPULATE	0x0001
+#define	TASKQ_CPR_SAFE		0x0002	/* Use CPR safe protocol */
+#define	TASKQ_DYNAMIC		0x0004	/* Use dynamic thread scheduling */
+#define	TASKQ_THREADS_CPU_PCT	0x0008	/* Scale # threads by # cpus */
+#define	TASKQ_DC_BATCH		0x0010	/* Mark threads as batch */
+
+#define	TQ_SLEEP	KM_SLEEP	/* Can block for memory */
+#define	TQ_NOSLEEP	KM_NOSLEEP	/* cannot block for memory; may fail */
+#define	TQ_NOQUEUE	0x02		/* Do not enqueue if can't dispatch */
+#define	TQ_FRONT	0x08		/* Queue in front */
+
+extern taskq_t *system_taskq;
+
+extern taskq_t	*taskq_create(const char *, int, pri_t, int, int, uint_t);
+#define	taskq_create_proc(a, b, c, d, e, p, f) \
+	    (taskq_create(a, b, c, d, e, f))
+#define	taskq_create_sysdc(a, b, d, e, p, dc, f) \
+	    (taskq_create(a, b, maxclsyspri, d, e, f))
+extern taskqid_t taskq_dispatch(taskq_t *, task_func_t, void *, uint_t);
+extern taskqid_t taskq_dispatch_delay(taskq_t *, task_func_t, void *, uint_t,
+    clock_t);
+extern void	taskq_dispatch_ent(taskq_t *, task_func_t, void *, uint_t,
+    taskq_ent_t *);
+extern int	taskq_empty_ent(taskq_ent_t *);
+extern void	taskq_init_ent(taskq_ent_t *);
+extern void	taskq_destroy(taskq_t *);
+extern void	taskq_wait(taskq_t *);
+extern void	taskq_wait_id(taskq_t *, taskqid_t);
+extern void	taskq_wait_outstanding(taskq_t *, taskqid_t);
+extern int	taskq_member(taskq_t *, kthread_t *);
+extern int	taskq_cancel_id(taskq_t *, taskqid_t);
+extern void	system_taskq_init(void);
+extern void	system_taskq_fini(void);
+
+#define	XVA_MAPSIZE	3
+#define	XVA_MAGIC	0x78766174
+
+/*
+ * vnodes
+ */
+typedef struct vnode {
+	uint64_t	v_size;
+	int		v_fd;
+	char		*v_path;
+} vnode_t;
+
+#define	AV_SCANSTAMP_SZ	32		/* length of anti-virus scanstamp */
+
+typedef struct xoptattr {
+	timestruc_t	xoa_createtime;	/* Create time of file */
+	uint8_t		xoa_archive;
+	uint8_t		xoa_system;
+	uint8_t		xoa_readonly;
+	uint8_t		xoa_hidden;
+	uint8_t		xoa_nounlink;
+	uint8_t		xoa_immutable;
+	uint8_t		xoa_appendonly;
+	uint8_t		xoa_nodump;
+	uint8_t		xoa_settable;
+	uint8_t		xoa_opaque;
+	uint8_t		xoa_av_quarantined;
+	uint8_t		xoa_av_modified;
+	uint8_t		xoa_av_scanstamp[AV_SCANSTAMP_SZ];
+	uint8_t		xoa_reparse;
+	uint8_t		xoa_offline;
+	uint8_t		xoa_sparse;
+} xoptattr_t;
+
+typedef struct vattr {
+	uint_t		va_mask;	/* bit-mask of attributes */
+	u_offset_t	va_size;	/* file size in bytes */
+} vattr_t;
+
+
+typedef struct xvattr {
+	vattr_t		xva_vattr;	/* Embedded vattr structure */
+	uint32_t	xva_magic;	/* Magic Number */
+	uint32_t	xva_mapsize;	/* Size of attr bitmap (32-bit words) */
+	uint32_t	*xva_rtnattrmapp;	/* Ptr to xva_rtnattrmap[] */
+	uint32_t	xva_reqattrmap[XVA_MAPSIZE];	/* Requested attrs */
+	uint32_t	xva_rtnattrmap[XVA_MAPSIZE];	/* Returned attrs */
+	xoptattr_t	xva_xoptattrs;	/* Optional attributes */
+} xvattr_t;
+
+typedef struct vsecattr {
+	uint_t		vsa_mask;	/* See below */
+	int		vsa_aclcnt;	/* ACL entry count */
+	void		*vsa_aclentp;	/* pointer to ACL entries */
+	int		vsa_dfaclcnt;	/* default ACL entry count */
+	void		*vsa_dfaclentp;	/* pointer to default ACL entries */
+	size_t		vsa_aclentsz;	/* ACE size in bytes of vsa_aclentp */
+} vsecattr_t;
+
+#define	AT_TYPE		0x00001
+#define	AT_MODE		0x00002
+#define	AT_UID		0x00004
+#define	AT_GID		0x00008
+#define	AT_FSID		0x00010
+#define	AT_NODEID	0x00020
+#define	AT_NLINK	0x00040
+#define	AT_SIZE		0x00080
+#define	AT_ATIME	0x00100
+#define	AT_MTIME	0x00200
+#define	AT_CTIME	0x00400
+#define	AT_RDEV		0x00800
+#define	AT_BLKSIZE	0x01000
+#define	AT_NBLOCKS	0x02000
+#define	AT_SEQ		0x08000
+#define	AT_XVATTR	0x10000
+
+#define	CRCREAT		0
+
+extern int fop_getattr(vnode_t *vp, vattr_t *vap);
+
+#define	VOP_CLOSE(vp, f, c, o, cr, ct)	vn_close(vp)
+#define	VOP_PUTPAGE(vp, of, sz, fl, cr, ct)	0
+#define	VOP_GETATTR(vp, vap, fl, cr, ct)  fop_getattr((vp), (vap));
+
+#define	VOP_FSYNC(vp, f, cr, ct)	fsync((vp)->v_fd)
+
+#define	VN_RELE(vp)	vn_close(vp)
+
+extern int vn_open(char *path, int x1, int oflags, int mode, vnode_t **vpp,
+    int x2, int x3);
+extern int vn_openat(char *path, int x1, int oflags, int mode, vnode_t **vpp,
+    int x2, int x3, vnode_t *vp, int fd);
+extern int vn_rdwr(int uio, vnode_t *vp, void *addr, ssize_t len,
+    offset_t offset, int x1, int x2, rlim64_t x3, void *x4, ssize_t *residp);
+extern void vn_close(vnode_t *vp);
+
+#define	vn_remove(path, x1, x2)		remove(path)
+#define	vn_rename(from, to, seg)	rename((from), (to))
+#define	vn_is_readonly(vp)		B_FALSE
+
+extern vnode_t *rootdir;
+
+#include <sys/file.h>		/* for FREAD, FWRITE, etc */
+
+/*
+ * Random stuff
+ */
+#define	ddi_get_lbolt()		(gethrtime() >> 23)
+#define	ddi_get_lbolt64()	(gethrtime() >> 23)
+#define	hz	119	/* frequency when using gethrtime() >> 23 for lbolt */
+
+#define	ddi_time_before(a, b)		(a < b)
+#define	ddi_time_after(a, b)		ddi_time_before(b, a)
+#define	ddi_time_before_eq(a, b)	(!ddi_time_after(a, b))
+#define	ddi_time_after_eq(a, b)		ddi_time_before_eq(b, a)
+
+#define	ddi_time_before64(a, b)		(a < b)
+#define	ddi_time_after64(a, b)		ddi_time_before64(b, a)
+#define	ddi_time_before_eq64(a, b)	(!ddi_time_after64(a, b))
+#define	ddi_time_after_eq64(a, b)	ddi_time_before_eq64(b, a)
+
+extern void delay(clock_t ticks);
+
+#define	SEC_TO_TICK(sec)	((sec) * hz)
+#define	MSEC_TO_TICK(msec)	((msec) / (MILLISEC / hz))
+#define	USEC_TO_TICK(usec)	((usec) / (MICROSEC / hz))
+#define	NSEC_TO_TICK(usec)	((usec) / (NANOSEC / hz))
+
+#define	gethrestime_sec() time(NULL)
+#define	gethrestime(t) \
+	do {\
+		(t)->tv_sec = gethrestime_sec();\
+		(t)->tv_nsec = 0;\
+	} while (0);
+
+#define	max_ncpus	64
+#define	boot_ncpus	(sysconf(_SC_NPROCESSORS_ONLN))
+
+/*
+ * Process priorities as defined by setpriority(2) and getpriority(2).
+ */
+#define	minclsyspri	19
+#define	maxclsyspri	-20
+#define	defclsyspri	0
+
+#define	CPU_SEQID	(pthread_self() & (max_ncpus - 1))
+
+#define	kcred		NULL
+#define	CRED()		NULL
+
+#define	ptob(x)		((x) * PAGESIZE)
+
+extern uint64_t physmem;
+
+extern int highbit64(uint64_t i);
+extern int random_get_bytes(uint8_t *ptr, size_t len);
+extern int random_get_pseudo_bytes(uint8_t *ptr, size_t len);
+
+extern void kernel_init(int);
+extern void kernel_fini(void);
+
+struct spa;
+extern void nicenum(uint64_t num, char *buf);
+extern void show_pool_stats(struct spa *);
+
+typedef struct callb_cpr {
+	kmutex_t	*cc_lockp;
+} callb_cpr_t;
+
+#define	CALLB_CPR_INIT(cp, lockp, func, name)	{		\
+	(cp)->cc_lockp = lockp;					\
+}
+
+#define	CALLB_CPR_SAFE_BEGIN(cp) {				\
+	ASSERT(MUTEX_HELD((cp)->cc_lockp));			\
+}
+
+#define	CALLB_CPR_SAFE_END(cp, lockp) {				\
+	ASSERT(MUTEX_HELD((cp)->cc_lockp));			\
+}
+
+#define	CALLB_CPR_EXIT(cp) {					\
+	ASSERT(MUTEX_HELD((cp)->cc_lockp));			\
+	mutex_exit((cp)->cc_lockp);				\
+}
+
+#define	zone_dataset_visible(x, y)	(1)
+#define	INGLOBALZONE(z)			(1)
+
+extern char *kmem_vasprintf(const char *fmt, va_list adx);
+extern char *kmem_asprintf(const char *fmt, ...);
+#define	strfree(str) kmem_free((str), strlen(str) + 1)
+
+/*
+ * Hostname information
+ */
+extern char hw_serial[];	/* for userland-emulated hostid access */
+extern int ddi_strtoul(const char *str, char **nptr, int base,
+    unsigned long *result);
+
+extern int ddi_strtoull(const char *str, char **nptr, int base,
+    u_longlong_t *result);
+
+typedef struct utsname	utsname_t;
+extern utsname_t *utsname(void);
+
+/* ZFS Boot Related stuff. */
+
+struct _buf {
+	intptr_t	_fd;
+};
+
+struct bootstat {
+	uint64_t st_size;
+};
+
+typedef struct ace_object {
+	uid_t		a_who;
+	uint32_t	a_access_mask;
+	uint16_t	a_flags;
+	uint16_t	a_type;
+	uint8_t		a_obj_type[16];
+	uint8_t		a_inherit_obj_type[16];
+} ace_object_t;
+
+
+#define	ACE_ACCESS_ALLOWED_OBJECT_ACE_TYPE	0x05
+#define	ACE_ACCESS_DENIED_OBJECT_ACE_TYPE	0x06
+#define	ACE_SYSTEM_AUDIT_OBJECT_ACE_TYPE	0x07
+#define	ACE_SYSTEM_ALARM_OBJECT_ACE_TYPE	0x08
+
+extern struct _buf *kobj_open_file(char *name);
+extern int kobj_read_file(struct _buf *file, char *buf, unsigned size,
+    unsigned off);
+extern void kobj_close_file(struct _buf *file);
+extern int kobj_get_filesize(struct _buf *file, uint64_t *size);
+extern int zfs_secpolicy_snapshot_perms(const char *name, cred_t *cr);
+extern int zfs_secpolicy_rename_perms(const char *from, const char *to,
+    cred_t *cr);
+extern int zfs_secpolicy_destroy_perms(const char *name, cred_t *cr);
+extern zoneid_t getzoneid(void);
+
+/* SID stuff */
+typedef struct ksiddomain {
+	uint_t	kd_ref;
+	uint_t	kd_len;
+	char	*kd_name;
+} ksiddomain_t;
+
+ksiddomain_t *ksid_lookupdomain(const char *);
+void ksiddomain_rele(ksiddomain_t *);
+
+#define	DDI_SLEEP	KM_SLEEP
+#define	ddi_log_sysevent(_a, _b, _c, _d, _e, _f, _g) \
+	sysevent_post_event(_c, _d, _b, "libzpool", _e, _f)
+
+#define	zfs_sleep_until(wakeup)						\
+	do {								\
+		hrtime_t delta = wakeup - gethrtime();			\
+		struct timespec ts;					\
+		ts.tv_sec = delta / NANOSEC;				\
+		ts.tv_nsec = delta % NANOSEC;				\
+		(void) nanosleep(&ts, NULL);				\
+	} while (0)
+
+typedef int fstrans_cookie_t;
+
+extern fstrans_cookie_t spl_fstrans_mark(void);
+extern void spl_fstrans_unmark(fstrans_cookie_t);
+extern int spl_fstrans_check(void);
+
+#endif /* _KERNEL */
+#endif	/* _SYS_ZFS_CONTEXT_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/include/sys/zfs_ctldir.h
@@ -0,0 +1,104 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (C) 2011 Lawrence Livermore National Security, LLC.
+ * Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ * LLNL-CODE-403049.
+ * Rewritten for Linux by:
+ *   Rohan Puri <rohan.puri15@gmail.com>
+ *   Brian Behlendorf <behlendorf1@llnl.gov>
+ */
+
+#ifndef	_ZFS_CTLDIR_H
+#define	_ZFS_CTLDIR_H
+
+#include <sys/vnode.h>
+#include <sys/pathname.h>
+#include <sys/zfs_vfsops.h>
+#include <sys/zfs_znode.h>
+
+#define	ZFS_CTLDIR_NAME		".zfs"
+#define	ZFS_SNAPDIR_NAME	"snapshot"
+#define	ZFS_SHAREDIR_NAME	"shares"
+
+#define	zfs_has_ctldir(zdp)	\
+	((zdp)->z_id == ZTOZSB(zdp)->z_root && \
+	(ZTOZSB(zdp)->z_ctldir != NULL))
+#define	zfs_show_ctldir(zdp)	\
+	(zfs_has_ctldir(zdp) && \
+	(ZTOZSB(zdp)->z_show_ctldir))
+
+extern int zfs_expire_snapshot;
+
+/* zfsctl generic functions */
+extern int zfsctl_create(zfs_sb_t *zsb);
+extern void zfsctl_destroy(zfs_sb_t *zsb);
+extern struct inode *zfsctl_root(znode_t *zp);
+extern void zfsctl_init(void);
+extern void zfsctl_fini(void);
+extern boolean_t zfsctl_is_node(struct inode *ip);
+extern boolean_t zfsctl_is_snapdir(struct inode *ip);
+extern int zfsctl_fid(struct inode *ip, fid_t *fidp);
+
+/* zfsctl '.zfs' functions */
+extern int zfsctl_root_lookup(struct inode *dip, char *name,
+    struct inode **ipp, int flags, cred_t *cr, int *direntflags,
+    pathname_t *realpnp);
+
+/* zfsctl '.zfs/snapshot' functions */
+extern int zfsctl_snapdir_lookup(struct inode *dip, char *name,
+    struct inode **ipp, int flags, cred_t *cr, int *direntflags,
+    pathname_t *realpnp);
+extern int zfsctl_snapdir_rename(struct inode *sdip, char *sname,
+    struct inode *tdip, char *tname, cred_t *cr, int flags);
+extern int zfsctl_snapdir_remove(struct inode *dip, char *name, cred_t *cr,
+    int flags);
+extern int zfsctl_snapdir_mkdir(struct inode *dip, char *dirname, vattr_t *vap,
+    struct inode **ipp, cred_t *cr, int flags);
+extern void zfsctl_snapdir_inactive(struct inode *ip);
+extern int zfsctl_snapshot_mount(struct path *path, int flags);
+extern int zfsctl_snapshot_unmount(char *snapname, int flags);
+extern int zfsctl_snapshot_unmount_delay(spa_t *spa, uint64_t objsetid,
+    int delay);
+extern int zfsctl_lookup_objset(struct super_block *sb, uint64_t objsetid,
+    zfs_sb_t **zsb);
+
+/* zfsctl '.zfs/shares' functions */
+extern int zfsctl_shares_lookup(struct inode *dip, char *name,
+    struct inode **ipp, int flags, cred_t *cr, int *direntflags,
+    pathname_t *realpnp);
+
+/*
+ * These inodes numbers are reserved for the .zfs control directory.
+ * It is important that they be no larger that 48-bits because only
+ * 6 bytes are reserved in the NFS file handle for the object number.
+ * However, they should be as large as possible to avoid conflicts
+ * with the objects which are assigned monotonically by the dmu.
+ */
+#define	ZFSCTL_INO_ROOT		0x0000FFFFFFFFFFFFULL
+#define	ZFSCTL_INO_SHARES	0x0000FFFFFFFFFFFEULL
+#define	ZFSCTL_INO_SNAPDIR	0x0000FFFFFFFFFFFDULL
+#define	ZFSCTL_INO_SNAPDIRS	0x0000FFFFFFFFFFFCULL
+
+#define	ZFSCTL_EXPIRE_SNAPSHOT	300
+
+#endif	/* _ZFS_CTLDIR_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/include/sys/zfs_debug.h
@@ -0,0 +1,81 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2014 by Delphix. All rights reserved.
+ */
+
+#ifndef _SYS_ZFS_DEBUG_H
+#define	_SYS_ZFS_DEBUG_H
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+#ifndef TRUE
+#define	TRUE 1
+#endif
+
+#ifndef FALSE
+#define	FALSE 0
+#endif
+
+extern int zfs_flags;
+extern int zfs_recover;
+extern int zfs_free_leak_on_eio;
+
+#define	ZFS_DEBUG_DPRINTF		(1<<0)
+#define	ZFS_DEBUG_DBUF_VERIFY		(1<<1)
+#define	ZFS_DEBUG_DNODE_VERIFY		(1<<2)
+#define	ZFS_DEBUG_SNAPNAMES		(1<<3)
+#define	ZFS_DEBUG_MODIFY		(1<<4)
+#define	ZFS_DEBUG_SPA			(1<<5)
+#define	ZFS_DEBUG_ZIO_FREE		(1<<6)
+#define	ZFS_DEBUG_HISTOGRAM_VERIFY	(1<<7)
+
+extern void __dprintf(const char *file, const char *func,
+    int line, const char *fmt, ...);
+#define	dprintf(...) \
+	__dprintf(__FILE__, __func__, __LINE__, __VA_ARGS__)
+#define	zfs_dbgmsg(...) \
+	__dprintf(__FILE__, __func__, __LINE__, __VA_ARGS__)
+
+extern void zfs_panic_recover(const char *fmt, ...);
+
+typedef struct zfs_dbgmsg {
+	list_node_t zdm_node;
+	time_t zdm_timestamp;
+	int zdm_size;
+	char zdm_msg[1]; /* variable length allocation */
+} zfs_dbgmsg_t;
+
+extern void zfs_dbgmsg_init(void);
+extern void zfs_dbgmsg_fini(void);
+
+#ifndef _KERNEL
+extern int dprintf_find_string(const char *string);
+#endif
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* _SYS_ZFS_DEBUG_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/include/sys/zfs_delay.h
@@ -0,0 +1,41 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+#ifndef	_SYS_FS_ZFS_DELAY_H
+#define	_SYS_FS_ZFS_DELAY_H
+
+#include <linux/delay_compat.h>
+
+/*
+ * Generic wrapper to sleep until a given time.
+ */
+#define	zfs_sleep_until(wakeup)						\
+	do {								\
+		hrtime_t delta = wakeup - gethrtime();			\
+									\
+		if (delta > 0) {					\
+			unsigned long delta_us;				\
+			delta_us = delta / (NANOSEC / MICROSEC);	\
+			usleep_range(delta_us, delta_us + 100);		\
+		}							\
+	} while (0)
+
+#endif	/* _SYS_FS_ZFS_DELAY_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/include/sys/zfs_dir.h
@@ -0,0 +1,74 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef	_SYS_FS_ZFS_DIR_H
+#define	_SYS_FS_ZFS_DIR_H
+
+#include <sys/pathname.h>
+#include <sys/dmu.h>
+#include <sys/zfs_znode.h>
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+/* zfs_dirent_lock() flags */
+#define	ZNEW		0x0001		/* entry should not exist */
+#define	ZEXISTS		0x0002		/* entry should exist */
+#define	ZSHARED		0x0004		/* shared access (zfs_dirlook()) */
+#define	ZXATTR		0x0008		/* we want the xattr dir */
+#define	ZRENAMING	0x0010		/* znode is being renamed */
+#define	ZCILOOK		0x0020		/* case-insensitive lookup requested */
+#define	ZCIEXACT	0x0040		/* c-i requires c-s match (rename) */
+#define	ZHAVELOCK	0x0080		/* z_name_lock is already held */
+
+/* mknode flags */
+#define	IS_ROOT_NODE	0x01		/* create a root node */
+#define	IS_XATTR	0x02		/* create an extended attribute node */
+
+extern int zfs_dirent_lock(zfs_dirlock_t **, znode_t *, char *, znode_t **,
+    int, int *, pathname_t *);
+extern void zfs_dirent_unlock(zfs_dirlock_t *);
+extern int zfs_link_create(zfs_dirlock_t *, znode_t *, dmu_tx_t *, int);
+extern int zfs_link_destroy(zfs_dirlock_t *, znode_t *, dmu_tx_t *, int,
+    boolean_t *);
+extern int zfs_dirlook(znode_t *, char *, struct inode **, int, int *,
+    pathname_t *);
+extern void zfs_mknode(znode_t *, vattr_t *, dmu_tx_t *, cred_t *,
+    uint_t, znode_t **, zfs_acl_ids_t *);
+extern void zfs_rmnode(znode_t *);
+extern void zfs_dl_name_switch(zfs_dirlock_t *dl, char *new, char **old);
+extern boolean_t zfs_dirempty(znode_t *);
+extern void zfs_unlinked_add(znode_t *, dmu_tx_t *);
+extern void zfs_unlinked_drain(zfs_sb_t *);
+extern int zfs_sticky_remove_access(znode_t *, znode_t *, cred_t *cr);
+extern int zfs_get_xattrdir(znode_t *, struct inode **, cred_t *, int);
+extern int zfs_make_xattrdir(znode_t *, vattr_t *, struct inode **, cred_t *);
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* _SYS_FS_ZFS_DIR_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/include/sys/zfs_fuid.h
@@ -0,0 +1,132 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef	_SYS_FS_ZFS_FUID_H
+#define	_SYS_FS_ZFS_FUID_H
+
+#ifdef _KERNEL
+#include <sys/kidmap.h>
+#include <sys/sid.h>
+#include <sys/dmu.h>
+#include <sys/zfs_vfsops.h>
+#endif
+#include <sys/avl.h>
+#include <sys/list.h>
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+typedef enum {
+	ZFS_OWNER,
+	ZFS_GROUP,
+	ZFS_ACE_USER,
+	ZFS_ACE_GROUP
+} zfs_fuid_type_t;
+
+/*
+ * Estimate space needed for one more fuid table entry.
+ * for now assume its current size + 1K
+ */
+#define	FUID_SIZE_ESTIMATE(z) ((z)->z_fuid_size + (SPA_MINBLOCKSIZE << 1))
+
+#define	FUID_INDEX(x)	((x) >> 32)
+#define	FUID_RID(x)	((x) & 0xffffffff)
+#define	FUID_ENCODE(idx, rid) (((uint64_t)(idx) << 32) | (rid))
+/*
+ * FUIDs cause problems for the intent log
+ * we need to replay the creation of the FUID,
+ * but we can't count on the idmapper to be around
+ * and during replay the FUID index may be different than
+ * before.  Also, if an ACL has 100 ACEs and 12 different
+ * domains we don't want to log 100 domain strings, but rather
+ * just the unique 12.
+ */
+
+/*
+ * The FUIDs in the log will index into
+ * domain string table and the bottom half will be the rid.
+ * Used for mapping ephemeral uid/gid during ACL setting to FUIDs
+ */
+typedef struct zfs_fuid {
+	list_node_t 	z_next;
+	uint64_t 	z_id;		/* uid/gid being converted to fuid */
+	uint64_t	z_domidx;	/* index in AVL domain table */
+	uint64_t	z_logfuid;	/* index for domain in log */
+} zfs_fuid_t;
+
+/* list of unique domains */
+typedef struct zfs_fuid_domain {
+	list_node_t	z_next;
+	uint64_t	z_domidx;	/* AVL tree idx */
+	const char	*z_domain;	/* domain string */
+} zfs_fuid_domain_t;
+
+/*
+ * FUID information necessary for logging create, setattr, and setacl.
+ */
+typedef struct zfs_fuid_info {
+	list_t	z_fuids;
+	list_t	z_domains;
+	uint64_t z_fuid_owner;
+	uint64_t z_fuid_group;
+	char **z_domain_table;  /* Used during replay */
+	uint32_t z_fuid_cnt;	/* How many fuids in z_fuids */
+	uint32_t z_domain_cnt;	/* How many domains */
+	size_t	z_domain_str_sz; /* len of domain strings z_domain list */
+} zfs_fuid_info_t;
+
+#ifdef _KERNEL
+struct znode;
+extern uid_t zfs_fuid_map_id(zfs_sb_t *, uint64_t, cred_t *, zfs_fuid_type_t);
+extern void zfs_fuid_node_add(zfs_fuid_info_t **, const char *, uint32_t,
+    uint64_t, uint64_t, zfs_fuid_type_t);
+extern void zfs_fuid_destroy(zfs_sb_t *);
+extern uint64_t zfs_fuid_create_cred(zfs_sb_t *, zfs_fuid_type_t,
+    cred_t *, zfs_fuid_info_t **);
+extern uint64_t zfs_fuid_create(zfs_sb_t *, uint64_t, cred_t *, zfs_fuid_type_t,
+    zfs_fuid_info_t **);
+extern void zfs_fuid_map_ids(struct znode *zp, cred_t *cr,
+    uid_t *uid, uid_t *gid);
+extern zfs_fuid_info_t *zfs_fuid_info_alloc(void);
+extern void zfs_fuid_info_free(zfs_fuid_info_t *);
+extern boolean_t zfs_groupmember(zfs_sb_t *, uint64_t, cred_t *);
+void zfs_fuid_sync(zfs_sb_t *, dmu_tx_t *);
+extern int zfs_fuid_find_by_domain(zfs_sb_t *, const char *domain,
+    char **retdomain, boolean_t addok);
+extern const char *zfs_fuid_find_by_idx(zfs_sb_t *zsb, uint32_t idx);
+extern void zfs_fuid_txhold(zfs_sb_t *zsb, dmu_tx_t *tx);
+#endif
+
+char *zfs_fuid_idx_domain(avl_tree_t *, uint32_t);
+void zfs_fuid_avl_tree_create(avl_tree_t *, avl_tree_t *);
+uint64_t zfs_fuid_table_load(objset_t *, uint64_t, avl_tree_t *, avl_tree_t *);
+void zfs_fuid_table_destroy(avl_tree_t *, avl_tree_t *);
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* _SYS_FS_ZFS_FUID_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/include/sys/zfs_ioctl.h
@@ -0,0 +1,419 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013 by Delphix. All rights reserved.
+ */
+
+#ifndef	_SYS_ZFS_IOCTL_H
+#define	_SYS_ZFS_IOCTL_H
+
+#include <sys/cred.h>
+#include <sys/dmu.h>
+#include <sys/zio.h>
+#include <sys/dsl_deleg.h>
+#include <sys/spa.h>
+#include <sys/zfs_stat.h>
+
+#ifdef _KERNEL
+#include <sys/nvpair.h>
+#endif	/* _KERNEL */
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+/*
+ * The structures in this file are passed between userland and the
+ * kernel.  Userland may be running a 32-bit process, while the kernel
+ * is 64-bit.  Therefore, these structures need to compile the same in
+ * 32-bit and 64-bit.  This means not using type "long", and adding
+ * explicit padding so that the 32-bit structure will not be packed more
+ * tightly than the 64-bit structure (which requires 64-bit alignment).
+ */
+
+/*
+ * Property values for snapdir
+ */
+#define	ZFS_SNAPDIR_HIDDEN		0
+#define	ZFS_SNAPDIR_VISIBLE		1
+
+/*
+ * Property values for snapdev
+ */
+#define	ZFS_SNAPDEV_HIDDEN		0
+#define	ZFS_SNAPDEV_VISIBLE		1
+/*
+ * Property values for acltype
+ */
+#define	ZFS_ACLTYPE_OFF			0
+#define	ZFS_ACLTYPE_POSIXACL		1
+
+/*
+ * Field manipulation macros for the drr_versioninfo field of the
+ * send stream header.
+ */
+
+/*
+ * Header types for zfs send streams.
+ */
+typedef enum drr_headertype {
+	DMU_SUBSTREAM = 0x1,
+	DMU_COMPOUNDSTREAM = 0x2
+} drr_headertype_t;
+
+#define	DMU_GET_STREAM_HDRTYPE(vi)	BF64_GET((vi), 0, 2)
+#define	DMU_SET_STREAM_HDRTYPE(vi, x)	BF64_SET((vi), 0, 2, x)
+
+#define	DMU_GET_FEATUREFLAGS(vi)	BF64_GET((vi), 2, 30)
+#define	DMU_SET_FEATUREFLAGS(vi, x)	BF64_SET((vi), 2, 30, x)
+
+/*
+ * Feature flags for zfs send streams (flags in drr_versioninfo)
+ */
+
+#define	DMU_BACKUP_FEATURE_DEDUP		(1<<0)
+#define	DMU_BACKUP_FEATURE_DEDUPPROPS		(1<<1)
+#define	DMU_BACKUP_FEATURE_SA_SPILL		(1<<2)
+/* flags #3 - #15 are reserved for incompatible closed-source implementations */
+#define	DMU_BACKUP_FEATURE_EMBED_DATA		(1<<16)
+#define	DMU_BACKUP_FEATURE_EMBED_DATA_LZ4	(1<<17)
+/* flag #18 is reserved for a Delphix feature */
+#define	DMU_BACKUP_FEATURE_LARGE_BLOCKS		(1<<19)
+
+/*
+ * Mask of all supported backup features
+ */
+#define	DMU_BACKUP_FEATURE_MASK	(DMU_BACKUP_FEATURE_DEDUP | \
+    DMU_BACKUP_FEATURE_DEDUPPROPS | DMU_BACKUP_FEATURE_SA_SPILL | \
+    DMU_BACKUP_FEATURE_EMBED_DATA | DMU_BACKUP_FEATURE_EMBED_DATA_LZ4 | \
+    DMU_BACKUP_FEATURE_LARGE_BLOCKS)
+
+/* Are all features in the given flag word currently supported? */
+#define	DMU_STREAM_SUPPORTED(x)	(!((x) & ~DMU_BACKUP_FEATURE_MASK))
+
+/*
+ * The drr_versioninfo field of the dmu_replay_record has the
+ * following layout:
+ *
+ *	64	56	48	40	32	24	16	8	0
+ *	+-------+-------+-------+-------+-------+-------+-------+-------+
+ *  	|		reserved	|        feature-flags	    |C|S|
+ *	+-------+-------+-------+-------+-------+-------+-------+-------+
+ *
+ * The low order two bits indicate the header type: SUBSTREAM (0x1)
+ * or COMPOUNDSTREAM (0x2).  Using two bits for this is historical:
+ * this field used to be a version number, where the two version types
+ * were 1 and 2.  Using two bits for this allows earlier versions of
+ * the code to be able to recognize send streams that don't use any
+ * of the features indicated by feature flags.
+ */
+
+#define	DMU_BACKUP_MAGIC 0x2F5bacbacULL
+
+#define	DRR_FLAG_CLONE		(1<<0)
+#define	DRR_FLAG_CI_DATA	(1<<1)
+
+/*
+ * flags in the drr_checksumflags field in the DRR_WRITE and
+ * DRR_WRITE_BYREF blocks
+ */
+#define	DRR_CHECKSUM_DEDUP	(1<<0)
+
+#define	DRR_IS_DEDUP_CAPABLE(flags)	((flags) & DRR_CHECKSUM_DEDUP)
+
+/*
+ * zfs ioctl command structure
+ */
+typedef struct dmu_replay_record {
+	enum {
+		DRR_BEGIN, DRR_OBJECT, DRR_FREEOBJECTS,
+		DRR_WRITE, DRR_FREE, DRR_END, DRR_WRITE_BYREF,
+		DRR_SPILL, DRR_WRITE_EMBEDDED, DRR_NUMTYPES
+	} drr_type;
+	uint32_t drr_payloadlen;
+	union {
+		struct drr_begin {
+			uint64_t drr_magic;
+			uint64_t drr_versioninfo; /* was drr_version */
+			uint64_t drr_creation_time;
+			dmu_objset_type_t drr_type;
+			uint32_t drr_flags;
+			uint64_t drr_toguid;
+			uint64_t drr_fromguid;
+			char drr_toname[MAXNAMELEN];
+		} drr_begin;
+		struct drr_end {
+			zio_cksum_t drr_checksum;
+			uint64_t drr_toguid;
+		} drr_end;
+		struct drr_object {
+			uint64_t drr_object;
+			dmu_object_type_t drr_type;
+			dmu_object_type_t drr_bonustype;
+			uint32_t drr_blksz;
+			uint32_t drr_bonuslen;
+			uint8_t drr_checksumtype;
+			uint8_t drr_compress;
+			uint8_t drr_pad[6];
+			uint64_t drr_toguid;
+			/* bonus content follows */
+		} drr_object;
+		struct drr_freeobjects {
+			uint64_t drr_firstobj;
+			uint64_t drr_numobjs;
+			uint64_t drr_toguid;
+		} drr_freeobjects;
+		struct drr_write {
+			uint64_t drr_object;
+			dmu_object_type_t drr_type;
+			uint32_t drr_pad;
+			uint64_t drr_offset;
+			uint64_t drr_length;
+			uint64_t drr_toguid;
+			uint8_t drr_checksumtype;
+			uint8_t drr_checksumflags;
+			uint8_t drr_pad2[6];
+			ddt_key_t drr_key; /* deduplication key */
+			/* content follows */
+		} drr_write;
+		struct drr_free {
+			uint64_t drr_object;
+			uint64_t drr_offset;
+			uint64_t drr_length;
+			uint64_t drr_toguid;
+		} drr_free;
+		struct drr_write_byref {
+			/* where to put the data */
+			uint64_t drr_object;
+			uint64_t drr_offset;
+			uint64_t drr_length;
+			uint64_t drr_toguid;
+			/* where to find the prior copy of the data */
+			uint64_t drr_refguid;
+			uint64_t drr_refobject;
+			uint64_t drr_refoffset;
+			/* properties of the data */
+			uint8_t drr_checksumtype;
+			uint8_t drr_checksumflags;
+			uint8_t drr_pad2[6];
+			ddt_key_t drr_key; /* deduplication key */
+		} drr_write_byref;
+		struct drr_spill {
+			uint64_t drr_object;
+			uint64_t drr_length;
+			uint64_t drr_toguid;
+			uint64_t drr_pad[4]; /* needed for crypto */
+			/* spill data follows */
+		} drr_spill;
+		struct drr_write_embedded {
+			uint64_t drr_object;
+			uint64_t drr_offset;
+			/* logical length, should equal blocksize */
+			uint64_t drr_length;
+			uint64_t drr_toguid;
+			uint8_t drr_compression;
+			uint8_t drr_etype;
+			uint8_t drr_pad[6];
+			uint32_t drr_lsize; /* uncompressed size of payload */
+			uint32_t drr_psize; /* compr. (real) size of payload */
+			/* (possibly compressed) content follows */
+		} drr_write_embedded;
+	} drr_u;
+} dmu_replay_record_t;
+
+/* diff record range types */
+typedef enum diff_type {
+	DDR_NONE = 0x1,
+	DDR_INUSE = 0x2,
+	DDR_FREE = 0x4
+} diff_type_t;
+
+/*
+ * The diff reports back ranges of free or in-use objects.
+ */
+typedef struct dmu_diff_record {
+	uint64_t ddr_type;
+	uint64_t ddr_first;
+	uint64_t ddr_last;
+} dmu_diff_record_t;
+
+typedef struct zinject_record {
+	uint64_t	zi_objset;
+	uint64_t	zi_object;
+	uint64_t	zi_start;
+	uint64_t	zi_end;
+	uint64_t	zi_guid;
+	uint32_t	zi_level;
+	uint32_t	zi_error;
+	uint64_t	zi_type;
+	uint32_t	zi_freq;
+	uint32_t	zi_failfast;
+	char		zi_func[MAXNAMELEN];
+	uint32_t	zi_iotype;
+	int32_t		zi_duration;
+	uint64_t	zi_timer;
+	uint32_t	zi_cmd;
+	uint32_t	zi_pad;
+} zinject_record_t;
+
+#define	ZINJECT_NULL		0x1
+#define	ZINJECT_FLUSH_ARC	0x2
+#define	ZINJECT_UNLOAD_SPA	0x4
+
+#define	ZEVENT_NONE		0x0
+#define	ZEVENT_NONBLOCK		0x1
+#define	ZEVENT_SIZE		1024
+
+#define	ZEVENT_SEEK_START	0
+#define	ZEVENT_SEEK_END		UINT64_MAX
+
+typedef enum zinject_type {
+	ZINJECT_UNINITIALIZED,
+	ZINJECT_DATA_FAULT,
+	ZINJECT_DEVICE_FAULT,
+	ZINJECT_LABEL_FAULT,
+	ZINJECT_IGNORED_WRITES,
+	ZINJECT_PANIC,
+	ZINJECT_DELAY_IO,
+} zinject_type_t;
+
+typedef struct zfs_share {
+	uint64_t	z_exportdata;
+	uint64_t	z_sharedata;
+	uint64_t	z_sharetype;	/* 0 = share, 1 = unshare */
+	uint64_t	z_sharemax;  /* max length of share string */
+} zfs_share_t;
+
+/*
+ * ZFS file systems may behave the usual, POSIX-compliant way, where
+ * name lookups are case-sensitive.  They may also be set up so that
+ * all the name lookups are case-insensitive, or so that only some
+ * lookups, the ones that set an FIGNORECASE flag, are case-insensitive.
+ */
+typedef enum zfs_case {
+	ZFS_CASE_SENSITIVE,
+	ZFS_CASE_INSENSITIVE,
+	ZFS_CASE_MIXED
+} zfs_case_t;
+
+typedef struct zfs_cmd {
+	char		zc_name[MAXPATHLEN];	/* name of pool or dataset */
+	uint64_t	zc_nvlist_src;		/* really (char *) */
+	uint64_t	zc_nvlist_src_size;
+	uint64_t	zc_nvlist_dst;		/* really (char *) */
+	uint64_t	zc_nvlist_dst_size;
+	boolean_t	zc_nvlist_dst_filled;	/* put an nvlist in dst? */
+	int		zc_pad2;
+
+	/*
+	 * The following members are for legacy ioctls which haven't been
+	 * converted to the new method.
+	 */
+	uint64_t	zc_history;		/* really (char *) */
+	char		zc_value[MAXPATHLEN * 2];
+	char		zc_string[MAXNAMELEN];
+	uint64_t	zc_guid;
+	uint64_t	zc_nvlist_conf;		/* really (char *) */
+	uint64_t	zc_nvlist_conf_size;
+	uint64_t	zc_cookie;
+	uint64_t	zc_objset_type;
+	uint64_t	zc_perm_action;
+	uint64_t	zc_history_len;
+	uint64_t	zc_history_offset;
+	uint64_t	zc_obj;
+	uint64_t	zc_iflags;		/* internal to zfs(7fs) */
+	zfs_share_t	zc_share;
+	dmu_objset_stats_t zc_objset_stats;
+	struct drr_begin zc_begin_record;
+	zinject_record_t zc_inject_record;
+	uint32_t	zc_defer_destroy;
+	uint32_t	zc_flags;
+	uint64_t	zc_action_handle;
+	int		zc_cleanup_fd;
+	uint8_t		zc_simple;
+	uint8_t		zc_pad[3];		/* alignment */
+	uint64_t	zc_sendobj;
+	uint64_t	zc_fromobj;
+	uint64_t	zc_createtxg;
+	zfs_stat_t	zc_stat;
+} zfs_cmd_t;
+
+typedef struct zfs_useracct {
+	char zu_domain[256];
+	uid_t zu_rid;
+	uint32_t zu_pad;
+	uint64_t zu_space;
+} zfs_useracct_t;
+
+#define	ZFSDEV_MAX_MINOR	(1 << 16)
+#define	ZFS_MIN_MINOR	(ZFSDEV_MAX_MINOR + 1)
+
+#define	ZPOOL_EXPORT_AFTER_SPLIT 0x1
+
+#ifdef _KERNEL
+
+typedef struct zfs_creat {
+	nvlist_t	*zct_zplprops;
+	nvlist_t	*zct_props;
+} zfs_creat_t;
+
+extern int zfs_secpolicy_snapshot_perms(const char *name, cred_t *cr);
+extern int zfs_secpolicy_rename_perms(const char *from,
+    const char *to, cred_t *cr);
+extern int zfs_secpolicy_destroy_perms(const char *name, cred_t *cr);
+extern int zfs_unmount_snap(const char *);
+extern void zfs_destroy_unmount_origin(const char *);
+
+extern boolean_t dataset_name_hidden(const char *name);
+
+enum zfsdev_state_type {
+	ZST_ONEXIT,
+	ZST_ZEVENT,
+	ZST_ALL,
+};
+
+/*
+ * The zfsdev_state_t structure is managed as a singly-linked list
+ * from which items are never deleted.  This allows for lock-free
+ * reading of the list so long as assignments to the zs_next and
+ * reads from zs_minor are performed atomically.  Empty items are
+ * indicated by storing -1 into zs_minor.
+ */
+typedef struct zfsdev_state {
+	struct zfsdev_state	*zs_next;	/* next zfsdev_state_t link */
+	struct file		*zs_file;	/* associated file struct */
+	minor_t			zs_minor;	/* made up minor number */
+	void			*zs_onexit;	/* onexit data */
+	void			*zs_zevent;	/* zevent data */
+} zfsdev_state_t;
+
+extern void *zfsdev_get_state(minor_t minor, enum zfsdev_state_type which);
+extern int zfsdev_getminor(struct file *filp, minor_t *minorp);
+extern minor_t zfsdev_minor_alloc(void);
+
+#endif	/* _KERNEL */
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* _SYS_ZFS_IOCTL_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/include/sys/zfs_onexit.h
@@ -0,0 +1,66 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ */
+
+#ifndef	_SYS_ZFS_ONEXIT_H
+#define	_SYS_ZFS_ONEXIT_H
+
+#include <sys/zfs_context.h>
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+#ifdef _KERNEL
+
+typedef struct zfs_onexit {
+	kmutex_t	zo_lock;
+	list_t		zo_actions;
+} zfs_onexit_t;
+
+typedef struct zfs_onexit_action_node {
+	list_node_t	za_link;
+	void		(*za_func)(void *);
+	void		*za_data;
+} zfs_onexit_action_node_t;
+
+extern void zfs_onexit_init(zfs_onexit_t **zo);
+extern void zfs_onexit_destroy(zfs_onexit_t *zo);
+
+#endif
+
+extern int zfs_onexit_fd_hold(int fd, minor_t *minorp);
+extern void zfs_onexit_fd_rele(int fd);
+extern int zfs_onexit_add_cb(minor_t minor, void (*func)(void *), void *data,
+    uint64_t *action_handle);
+extern int zfs_onexit_del_cb(minor_t minor, uint64_t action_handle,
+    boolean_t fire);
+extern int zfs_onexit_cb_data(minor_t minor, uint64_t action_handle,
+    void **data);
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* _SYS_ZFS_ONEXIT_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/include/sys/zfs_rlock.h
@@ -0,0 +1,87 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef	_SYS_FS_ZFS_RLOCK_H
+#define	_SYS_FS_ZFS_RLOCK_H
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+#ifdef _KERNEL
+
+#include <sys/zfs_znode.h>
+
+typedef enum {
+	RL_READER,
+	RL_WRITER,
+	RL_APPEND
+} rl_type_t;
+
+typedef struct rl {
+	znode_t *r_zp;		/* znode this lock applies to */
+	avl_node_t r_node;	/* avl node link */
+	uint64_t r_off;		/* file range offset */
+	uint64_t r_len;		/* file range length */
+	uint_t r_cnt;		/* range reference count in tree */
+	rl_type_t r_type;	/* range type */
+	kcondvar_t r_wr_cv;	/* cv for waiting writers */
+	kcondvar_t r_rd_cv;	/* cv for waiting readers */
+	uint8_t r_proxy;	/* acting for original range */
+	uint8_t r_write_wanted;	/* writer wants to lock this range */
+	uint8_t r_read_wanted;	/* reader wants to lock this range */
+	list_node_t rl_node;	/* used for deferred release */
+} rl_t;
+
+/*
+ * Lock a range (offset, length) as either shared (RL_READER)
+ * or exclusive (RL_WRITER or RL_APPEND).  RL_APPEND is a special type that
+ * is converted to RL_WRITER that specified to lock from the start of the
+ * end of file.  Returns the range lock structure.
+ */
+rl_t *zfs_range_lock(znode_t *zp, uint64_t off, uint64_t len, rl_type_t type);
+
+/* Unlock range and destroy range lock structure. */
+void zfs_range_unlock(rl_t *rl);
+
+/*
+ * Reduce range locked as RW_WRITER from whole file to specified range.
+ * Asserts the whole file was previously locked.
+ */
+void zfs_range_reduce(rl_t *rl, uint64_t off, uint64_t len);
+
+/*
+ * AVL comparison function used to order range locks
+ * Locks are ordered on the start offset of the range.
+ */
+int zfs_range_compare(const void *arg1, const void *arg2);
+
+#endif /* _KERNEL */
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* _SYS_FS_ZFS_RLOCK_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/include/sys/zfs_sa.h
@@ -0,0 +1,150 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef	_SYS_ZFS_SA_H
+#define	_SYS_ZFS_SA_H
+
+#ifdef _KERNEL
+#include <sys/types32.h>
+#include <sys/list.h>
+#include <sys/dmu.h>
+#include <sys/zfs_acl.h>
+#include <sys/zfs_znode.h>
+#include <sys/sa.h>
+#include <sys/zil.h>
+
+
+#endif
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+/*
+ * This is the list of known attributes
+ * to the ZPL.  The values of the actual
+ * attributes are not defined by the order
+ * the enums.  It is controlled by the attribute
+ * registration mechanism.  Two different file system
+ * could have different numeric values for the same
+ * attributes.  this list is only used for dereferencing
+ * into the table that will hold the actual numeric value.
+ */
+typedef enum zpl_attr {
+	ZPL_ATIME,
+	ZPL_MTIME,
+	ZPL_CTIME,
+	ZPL_CRTIME,
+	ZPL_GEN,
+	ZPL_MODE,
+	ZPL_SIZE,
+	ZPL_PARENT,
+	ZPL_LINKS,
+	ZPL_XATTR,
+	ZPL_RDEV,
+	ZPL_FLAGS,
+	ZPL_UID,
+	ZPL_GID,
+	ZPL_PAD,
+	ZPL_ZNODE_ACL,
+	ZPL_DACL_COUNT,
+	ZPL_SYMLINK,
+	ZPL_SCANSTAMP,
+	ZPL_DACL_ACES,
+	ZPL_DXATTR,
+	ZPL_END
+} zpl_attr_t;
+
+#define	ZFS_OLD_ZNODE_PHYS_SIZE	0x108
+#define	ZFS_SA_BASE_ATTR_SIZE	(ZFS_OLD_ZNODE_PHYS_SIZE - \
+    sizeof (zfs_acl_phys_t))
+
+#define	SA_MODE_OFFSET		0
+#define	SA_SIZE_OFFSET		8
+#define	SA_GEN_OFFSET		16
+#define	SA_UID_OFFSET		24
+#define	SA_GID_OFFSET		32
+#define	SA_PARENT_OFFSET	40
+
+extern sa_attr_reg_t zfs_attr_table[ZPL_END + 1];
+extern sa_attr_reg_t zfs_legacy_attr_table[ZPL_END + 1];
+
+/*
+ * This is a deprecated data structure that only exists for
+ * dealing with file systems create prior to ZPL version 5.
+ */
+typedef struct znode_phys {
+	uint64_t zp_atime[2];		/*  0 - last file access time */
+	uint64_t zp_mtime[2];		/* 16 - last file modification time */
+	uint64_t zp_ctime[2];		/* 32 - last file change time */
+	uint64_t zp_crtime[2];		/* 48 - creation time */
+	uint64_t zp_gen;		/* 64 - generation (txg of creation) */
+	uint64_t zp_mode;		/* 72 - file mode bits */
+	uint64_t zp_size;		/* 80 - size of file */
+	uint64_t zp_parent;		/* 88 - directory parent (`..') */
+	uint64_t zp_links;		/* 96 - number of links to file */
+	uint64_t zp_xattr;		/* 104 - DMU object for xattrs */
+	uint64_t zp_rdev;		/* 112 - dev_t for VBLK & VCHR files */
+	uint64_t zp_flags;		/* 120 - persistent flags */
+	uint64_t zp_uid;		/* 128 - file owner */
+	uint64_t zp_gid;		/* 136 - owning group */
+	uint64_t zp_zap;		/* 144 - extra attributes */
+	uint64_t zp_pad[3];		/* 152 - future */
+	zfs_acl_phys_t zp_acl;		/* 176 - 263 ACL */
+	/*
+	 * Data may pad out any remaining bytes in the znode buffer, eg:
+	 *
+	 * |<---------------------- dnode_phys (512) ------------------------>|
+	 * |<-- dnode (192) --->|<----------- "bonus" buffer (320) ---------->|
+	 *			|<---- znode (264) ---->|<---- data (56) ---->|
+	 *
+	 * At present, we use this space for the following:
+	 *  - symbolic links
+	 *  - 32-byte anti-virus scanstamp (regular files only)
+	 */
+} znode_phys_t;
+
+#ifdef _KERNEL
+
+#define	DXATTR_MAX_ENTRY_SIZE	(32768)
+#define	DXATTR_MAX_SA_SIZE	(SPA_OLD_MAXBLOCKSIZE >> 1)
+
+int zfs_sa_readlink(struct znode *, uio_t *);
+void zfs_sa_symlink(struct znode *, char *link, int len, dmu_tx_t *);
+void zfs_sa_get_scanstamp(struct znode *, xvattr_t *);
+void zfs_sa_set_scanstamp(struct znode *, xvattr_t *, dmu_tx_t *);
+int zfs_sa_get_xattr(struct znode *);
+int zfs_sa_set_xattr(struct znode *);
+void zfs_sa_upgrade(struct sa_handle  *, dmu_tx_t *);
+void zfs_sa_upgrade_txholds(dmu_tx_t *, struct znode *);
+void zfs_sa_init(void);
+void zfs_sa_fini(void);
+#endif
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* _SYS_ZFS_SA_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/include/sys/zfs_stat.h
@@ -0,0 +1,56 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ */
+
+#ifndef	_SYS_FS_ZFS_STAT_H
+#define	_SYS_FS_ZFS_STAT_H
+
+#ifdef _KERNEL
+#include <sys/isa_defs.h>
+#include <sys/types32.h>
+#include <sys/dmu.h>
+#endif
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+/*
+ * A limited number of zpl level stats are retrievable
+ * with an ioctl.  zfs diff is the current consumer.
+ */
+typedef struct zfs_stat {
+	uint64_t	zs_gen;
+	uint64_t	zs_mode;
+	uint64_t	zs_links;
+	uint64_t	zs_ctime[2];
+} zfs_stat_t;
+
+extern int zfs_obj_to_stats(objset_t *osp, uint64_t obj, zfs_stat_t *sb,
+    char *buf, int len);
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* _SYS_FS_ZFS_STAT_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/include/sys/zfs_vfsops.h
@@ -0,0 +1,222 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ */
+
+#ifndef	_SYS_FS_ZFS_VFSOPS_H
+#define	_SYS_FS_ZFS_VFSOPS_H
+
+#include <sys/isa_defs.h>
+#include <sys/types32.h>
+#include <sys/list.h>
+#include <sys/vfs.h>
+#include <sys/zil.h>
+#include <sys/sa.h>
+#include <sys/rrwlock.h>
+#include <sys/zfs_ioctl.h>
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+struct zfs_sb;
+struct znode;
+
+typedef struct zfs_mntopts {
+	char		*z_osname;	/* Objset name */
+	char		*z_mntpoint;	/* Primary mount point */
+	uint64_t	z_xattr;
+	boolean_t	z_readonly;
+	boolean_t	z_do_readonly;
+	boolean_t	z_setuid;
+	boolean_t	z_do_setuid;
+	boolean_t	z_exec;
+	boolean_t	z_do_exec;
+	boolean_t	z_devices;
+	boolean_t	z_do_devices;
+	boolean_t	z_do_xattr;
+	boolean_t	z_atime;
+	boolean_t	z_do_atime;
+	boolean_t	z_relatime;
+	boolean_t	z_do_relatime;
+	boolean_t	z_nbmand;
+	boolean_t	z_do_nbmand;
+} zfs_mntopts_t;
+
+typedef struct zfs_sb {
+	struct super_block *z_sb;	/* generic super_block */
+	struct backing_dev_info z_bdi;	/* generic backing dev info */
+	struct zfs_sb	*z_parent;	/* parent fs */
+	objset_t	*z_os;		/* objset reference */
+	zfs_mntopts_t	*z_mntopts;	/* passed mount options */
+	uint64_t	z_flags;	/* super_block flags */
+	uint64_t	z_root;		/* id of root znode */
+	uint64_t	z_unlinkedobj;	/* id of unlinked zapobj */
+	uint64_t	z_max_blksz;	/* maximum block size for files */
+	uint64_t	z_fuid_obj;	/* fuid table object number */
+	uint64_t	z_fuid_size;	/* fuid table size */
+	avl_tree_t	z_fuid_idx;	/* fuid tree keyed by index */
+	avl_tree_t	z_fuid_domain;	/* fuid tree keyed by domain */
+	krwlock_t	z_fuid_lock;	/* fuid lock */
+	boolean_t	z_fuid_loaded;	/* fuid tables are loaded */
+	boolean_t	z_fuid_dirty;   /* need to sync fuid table ? */
+	struct zfs_fuid_info	*z_fuid_replay; /* fuid info for replay */
+	zilog_t		*z_log;		/* intent log pointer */
+	uint_t		z_acl_inherit;	/* acl inheritance behavior */
+	uint_t		z_acl_type;	/* type of ACL usable on this FS */
+	zfs_case_t	z_case;		/* case-sense */
+	boolean_t	z_utf8;		/* utf8-only */
+	int		z_norm;		/* normalization flags */
+	boolean_t	z_atime;	/* enable atimes mount option */
+	boolean_t	z_relatime;	/* enable relatime mount option */
+	boolean_t	z_unmounted;	/* unmounted */
+	rrmlock_t	z_teardown_lock;
+	krwlock_t	z_teardown_inactive_lock;
+	list_t		z_all_znodes;	/* all znodes in the fs */
+	uint64_t	z_nr_znodes;	/* number of znodes in the fs */
+	unsigned long	z_rollback_time; /* last online rollback time */
+	unsigned long	z_snap_defer_time; /* last snapshot unmount deferal */
+	kmutex_t	z_znodes_lock;	/* lock for z_all_znodes */
+	arc_prune_t	*z_arc_prune;	/* called by ARC to prune caches */
+	struct inode	*z_ctldir;	/* .zfs directory inode */
+	boolean_t	z_show_ctldir;	/* expose .zfs in the root dir */
+	boolean_t	z_issnap;	/* true if this is a snapshot */
+	boolean_t	z_vscan;	/* virus scan on/off */
+	boolean_t	z_use_fuids;	/* version allows fuids */
+	boolean_t	z_replay;	/* set during ZIL replay */
+	boolean_t	z_use_sa;	/* version allow system attributes */
+	boolean_t	z_xattr_sa;	/* allow xattrs to be stores as SA */
+	uint64_t	z_version;	/* ZPL version */
+	uint64_t	z_shares_dir;	/* hidden shares dir */
+	kmutex_t	z_lock;
+	uint64_t	z_userquota_obj;
+	uint64_t	z_groupquota_obj;
+	uint64_t	z_replay_eof;	/* New end of file - replay only */
+	sa_attr_type_t	*z_attr_table;	/* SA attr mapping->id */
+	uint64_t	z_hold_size;	/* znode hold array size */
+	avl_tree_t	*z_hold_trees;	/* znode hold trees */
+	kmutex_t	*z_hold_locks;	/* znode hold locks */
+} zfs_sb_t;
+
+#define	ZFS_SUPER_MAGIC	0x2fc12fc1
+
+#define	ZSB_XATTR	0x0001		/* Enable user xattrs */
+
+/*
+ * Allow a maximum number of links.  While ZFS does not internally limit
+ * this the inode->i_nlink member is defined as an unsigned int.  To be
+ * safe we use 2^31-1 as the limit.
+ */
+#define	ZFS_LINK_MAX		((1U << 31) - 1U)
+
+/*
+ * Normal filesystems (those not under .zfs/snapshot) have a total
+ * file ID size limited to 12 bytes (including the length field) due to
+ * NFSv2 protocol's limitation of 32 bytes for a filehandle.  For historical
+ * reasons, this same limit is being imposed by the Solaris NFSv3 implementation
+ * (although the NFSv3 protocol actually permits a maximum of 64 bytes).  It
+ * is not possible to expand beyond 12 bytes without abandoning support
+ * of NFSv2.
+ *
+ * For normal filesystems, we partition up the available space as follows:
+ *	2 bytes		fid length (required)
+ *	6 bytes		object number (48 bits)
+ *	4 bytes		generation number (32 bits)
+ *
+ * We reserve only 48 bits for the object number, as this is the limit
+ * currently defined and imposed by the DMU.
+ */
+typedef struct zfid_short {
+	uint16_t	zf_len;
+	uint8_t		zf_object[6];		/* obj[i] = obj >> (8 * i) */
+	uint8_t		zf_gen[4];		/* gen[i] = gen >> (8 * i) */
+} zfid_short_t;
+
+/*
+ * Filesystems under .zfs/snapshot have a total file ID size of 22 bytes
+ * (including the length field).  This makes files under .zfs/snapshot
+ * accessible by NFSv3 and NFSv4, but not NFSv2.
+ *
+ * For files under .zfs/snapshot, we partition up the available space
+ * as follows:
+ *	2 bytes		fid length (required)
+ *	6 bytes		object number (48 bits)
+ *	4 bytes		generation number (32 bits)
+ *	6 bytes		objset id (48 bits)
+ *	4 bytes		currently just zero (32 bits)
+ *
+ * We reserve only 48 bits for the object number and objset id, as these are
+ * the limits currently defined and imposed by the DMU.
+ */
+typedef struct zfid_long {
+	zfid_short_t	z_fid;
+	uint8_t		zf_setid[6];		/* obj[i] = obj >> (8 * i) */
+	uint8_t		zf_setgen[4];		/* gen[i] = gen >> (8 * i) */
+} zfid_long_t;
+
+#define	SHORT_FID_LEN	(sizeof (zfid_short_t) - sizeof (uint16_t))
+#define	LONG_FID_LEN	(sizeof (zfid_long_t) - sizeof (uint16_t))
+
+extern uint_t zfs_fsyncer_key;
+
+extern int zfs_suspend_fs(zfs_sb_t *zsb);
+extern int zfs_resume_fs(zfs_sb_t *zsb, const char *osname);
+extern int zfs_userspace_one(zfs_sb_t *zsb, zfs_userquota_prop_t type,
+    const char *domain, uint64_t rid, uint64_t *valuep);
+extern int zfs_userspace_many(zfs_sb_t *zsb, zfs_userquota_prop_t type,
+    uint64_t *cookiep, void *vbuf, uint64_t *bufsizep);
+extern int zfs_set_userquota(zfs_sb_t *zsb, zfs_userquota_prop_t type,
+    const char *domain, uint64_t rid, uint64_t quota);
+extern boolean_t zfs_owner_overquota(zfs_sb_t *zsb, struct znode *,
+    boolean_t isgroup);
+extern boolean_t zfs_fuid_overquota(zfs_sb_t *zsb, boolean_t isgroup,
+    uint64_t fuid);
+extern int zfs_set_version(zfs_sb_t *zsb, uint64_t newvers);
+extern int zfs_get_zplprop(objset_t *os, zfs_prop_t prop,
+    uint64_t *value);
+extern zfs_mntopts_t *zfs_mntopts_alloc(void);
+extern void zfs_mntopts_free(zfs_mntopts_t *zmo);
+extern int zfs_sb_create(const char *name, zfs_mntopts_t *zmo,
+    zfs_sb_t **zsbp);
+extern int zfs_sb_setup(zfs_sb_t *zsb, boolean_t mounting);
+extern void zfs_sb_free(zfs_sb_t *zsb);
+extern int zfs_sb_prune(struct super_block *sb, unsigned long nr_to_scan,
+    int *objects);
+extern int zfs_sb_teardown(zfs_sb_t *zsb, boolean_t unmounting);
+extern int zfs_check_global_label(const char *dsname, const char *hexsl);
+extern boolean_t zfs_is_readonly(zfs_sb_t *zsb);
+
+extern int zfs_register_callbacks(zfs_sb_t *zsb);
+extern void zfs_unregister_callbacks(zfs_sb_t *zsb);
+extern int zfs_domount(struct super_block *sb, zfs_mntopts_t *zmo, int silent);
+extern void zfs_preumount(struct super_block *sb);
+extern int zfs_umount(struct super_block *sb);
+extern int zfs_remount(struct super_block *sb, int *flags, zfs_mntopts_t *zmo);
+extern int zfs_root(zfs_sb_t *zsb, struct inode **ipp);
+extern int zfs_statvfs(struct dentry *dentry, struct kstatfs *statp);
+extern int zfs_vget(struct super_block *sb, struct inode **ipp, fid_t *fidp);
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* _SYS_FS_ZFS_VFSOPS_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/include/sys/zfs_vnops.h
@@ -0,0 +1,88 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ */
+
+#ifndef	_SYS_FS_ZFS_VNOPS_H
+#define	_SYS_FS_ZFS_VNOPS_H
+
+#include <sys/vnode.h>
+#include <sys/xvattr.h>
+#include <sys/uio.h>
+#include <sys/cred.h>
+#include <sys/fcntl.h>
+#include <sys/pathname.h>
+#include <sys/zpl.h>
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+extern int zfs_open(struct inode *ip, int mode, int flag, cred_t *cr);
+extern int zfs_close(struct inode *ip, int flag, cred_t *cr);
+extern int zfs_holey(struct inode *ip, int cmd, loff_t *off);
+extern int zfs_read(struct inode *ip, uio_t *uio, int ioflag, cred_t *cr);
+extern int zfs_write(struct inode *ip, uio_t *uio, int ioflag, cred_t *cr);
+extern int zfs_access(struct inode *ip, int mode, int flag, cred_t *cr);
+extern int zfs_lookup(struct inode *dip, char *nm, struct inode **ipp,
+    int flags, cred_t *cr, int *direntflags, pathname_t *realpnp);
+extern int zfs_create(struct inode *dip, char *name, vattr_t *vap, int excl,
+    int mode, struct inode **ipp, cred_t *cr, int flag, vsecattr_t *vsecp);
+extern int zfs_remove(struct inode *dip, char *name, cred_t *cr);
+extern int zfs_mkdir(struct inode *dip, char *dirname, vattr_t *vap,
+    struct inode **ipp, cred_t *cr, int flags, vsecattr_t *vsecp);
+extern int zfs_rmdir(struct inode *dip, char *name, struct inode *cwd,
+    cred_t *cr, int flags);
+extern int zfs_readdir(struct inode *ip, struct dir_context *ctx, cred_t *cr);
+extern int zfs_fsync(struct inode *ip, int syncflag, cred_t *cr);
+extern int zfs_getattr(struct inode *ip, vattr_t *vap, int flag, cred_t *cr);
+extern int zfs_getattr_fast(struct inode *ip, struct kstat *sp);
+extern int zfs_setattr(struct inode *ip, vattr_t *vap, int flag, cred_t *cr);
+extern int zfs_rename(struct inode *sdip, char *snm, struct inode *tdip,
+    char *tnm, cred_t *cr, int flags);
+extern int zfs_symlink(struct inode *dip, char *name, vattr_t *vap,
+    char *link, struct inode **ipp, cred_t *cr, int flags);
+extern int zfs_follow_link(struct dentry *dentry, struct nameidata *nd);
+extern int zfs_readlink(struct inode *ip, uio_t *uio, cred_t *cr);
+extern int zfs_link(struct inode *tdip, struct inode *sip,
+    char *name, cred_t *cr);
+extern void zfs_inactive(struct inode *ip);
+extern int zfs_space(struct inode *ip, int cmd, flock64_t *bfp, int flag,
+    offset_t offset, cred_t *cr);
+extern int zfs_fid(struct inode *ip, fid_t *fidp);
+extern int zfs_getsecattr(struct inode *ip, vsecattr_t *vsecp, int flag,
+    cred_t *cr);
+extern int zfs_setsecattr(struct inode *ip, vsecattr_t *vsecp, int flag,
+    cred_t *cr);
+extern int zfs_getpage(struct inode *ip, struct page *pl[], int nr_pages);
+extern int zfs_putpage(struct inode *ip, struct page *pp,
+    struct writeback_control *wbc);
+extern int zfs_dirty_inode(struct inode *ip, int flags);
+extern int zfs_map(struct inode *ip, offset_t off, caddr_t *addrp,
+    size_t len, unsigned long vm_flags);
+extern void zfs_iput_async(struct inode *ip);
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* _SYS_FS_ZFS_VNOPS_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/include/sys/zfs_znode.h
@@ -0,0 +1,384 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012 by Delphix. All rights reserved.
+ */
+
+#ifndef	_SYS_FS_ZFS_ZNODE_H
+#define	_SYS_FS_ZFS_ZNODE_H
+
+#ifdef _KERNEL
+#include <sys/isa_defs.h>
+#include <sys/types32.h>
+#include <sys/attr.h>
+#include <sys/list.h>
+#include <sys/dmu.h>
+#include <sys/sa.h>
+#include <sys/zfs_vfsops.h>
+#include <sys/rrwlock.h>
+#include <sys/zfs_sa.h>
+#include <sys/zfs_stat.h>
+#endif
+#include <sys/zfs_acl.h>
+#include <sys/zil.h>
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+/*
+ * Additional file level attributes, that are stored
+ * in the upper half of zp_flags
+ */
+#define	ZFS_READONLY		0x0000000100000000ull
+#define	ZFS_HIDDEN		0x0000000200000000ull
+#define	ZFS_SYSTEM		0x0000000400000000ull
+#define	ZFS_ARCHIVE		0x0000000800000000ull
+#define	ZFS_IMMUTABLE		0x0000001000000000ull
+#define	ZFS_NOUNLINK		0x0000002000000000ull
+#define	ZFS_APPENDONLY		0x0000004000000000ull
+#define	ZFS_NODUMP		0x0000008000000000ull
+#define	ZFS_OPAQUE		0x0000010000000000ull
+#define	ZFS_AV_QUARANTINED	0x0000020000000000ull
+#define	ZFS_AV_MODIFIED		0x0000040000000000ull
+#define	ZFS_REPARSE		0x0000080000000000ull
+#define	ZFS_OFFLINE		0x0000100000000000ull
+#define	ZFS_SPARSE		0x0000200000000000ull
+
+#define	ZFS_ATTR_SET(zp, attr, value, pflags, tx) \
+{ \
+	if (value) \
+		pflags |= attr; \
+	else \
+		pflags &= ~attr; \
+	VERIFY(0 == sa_update(zp->z_sa_hdl, SA_ZPL_FLAGS(ZTOZSB(zp)), \
+	    &pflags, sizeof (pflags), tx)); \
+}
+
+/*
+ * Define special zfs pflags
+ */
+#define	ZFS_XATTR		0x1		/* is an extended attribute */
+#define	ZFS_INHERIT_ACE		0x2		/* ace has inheritable ACEs */
+#define	ZFS_ACL_TRIVIAL		0x4		/* files ACL is trivial */
+#define	ZFS_ACL_OBJ_ACE		0x8		/* ACL has CMPLX Object ACE */
+#define	ZFS_ACL_PROTECTED	0x10		/* ACL protected */
+#define	ZFS_ACL_DEFAULTED	0x20		/* ACL should be defaulted */
+#define	ZFS_ACL_AUTO_INHERIT	0x40		/* ACL should be inherited */
+#define	ZFS_BONUS_SCANSTAMP	0x80		/* Scanstamp in bonus area */
+#define	ZFS_NO_EXECS_DENIED	0x100		/* exec was given to everyone */
+
+#define	SA_ZPL_ATIME(z)		z->z_attr_table[ZPL_ATIME]
+#define	SA_ZPL_MTIME(z)		z->z_attr_table[ZPL_MTIME]
+#define	SA_ZPL_CTIME(z)		z->z_attr_table[ZPL_CTIME]
+#define	SA_ZPL_CRTIME(z)	z->z_attr_table[ZPL_CRTIME]
+#define	SA_ZPL_GEN(z)		z->z_attr_table[ZPL_GEN]
+#define	SA_ZPL_DACL_ACES(z)	z->z_attr_table[ZPL_DACL_ACES]
+#define	SA_ZPL_XATTR(z)		z->z_attr_table[ZPL_XATTR]
+#define	SA_ZPL_SYMLINK(z)	z->z_attr_table[ZPL_SYMLINK]
+#define	SA_ZPL_RDEV(z)		z->z_attr_table[ZPL_RDEV]
+#define	SA_ZPL_SCANSTAMP(z)	z->z_attr_table[ZPL_SCANSTAMP]
+#define	SA_ZPL_UID(z)		z->z_attr_table[ZPL_UID]
+#define	SA_ZPL_GID(z)		z->z_attr_table[ZPL_GID]
+#define	SA_ZPL_PARENT(z)	z->z_attr_table[ZPL_PARENT]
+#define	SA_ZPL_LINKS(z)		z->z_attr_table[ZPL_LINKS]
+#define	SA_ZPL_MODE(z)		z->z_attr_table[ZPL_MODE]
+#define	SA_ZPL_DACL_COUNT(z)	z->z_attr_table[ZPL_DACL_COUNT]
+#define	SA_ZPL_FLAGS(z)		z->z_attr_table[ZPL_FLAGS]
+#define	SA_ZPL_SIZE(z)		z->z_attr_table[ZPL_SIZE]
+#define	SA_ZPL_ZNODE_ACL(z)	z->z_attr_table[ZPL_ZNODE_ACL]
+#define	SA_ZPL_DXATTR(z)	z->z_attr_table[ZPL_DXATTR]
+#define	SA_ZPL_PAD(z)		z->z_attr_table[ZPL_PAD]
+
+/*
+ * Is ID ephemeral?
+ */
+#define	IS_EPHEMERAL(x)		(x > MAXUID)
+
+/*
+ * Should we use FUIDs?
+ */
+#define	USE_FUIDS(version, os)	(version >= ZPL_VERSION_FUID && \
+    spa_version(dmu_objset_spa(os)) >= SPA_VERSION_FUID)
+#define	USE_SA(version, os) (version >= ZPL_VERSION_SA && \
+    spa_version(dmu_objset_spa(os)) >= SPA_VERSION_SA)
+
+#define	MASTER_NODE_OBJ	1
+
+/*
+ * Special attributes for master node.
+ * "userquota@" and "groupquota@" are also valid (from
+ * zfs_userquota_prop_prefixes[]).
+ */
+#define	ZFS_FSID		"FSID"
+#define	ZFS_UNLINKED_SET	"DELETE_QUEUE"
+#define	ZFS_ROOT_OBJ		"ROOT"
+#define	ZPL_VERSION_STR		"VERSION"
+#define	ZFS_FUID_TABLES		"FUID"
+#define	ZFS_SHARES_DIR		"SHARES"
+#define	ZFS_SA_ATTRS		"SA_ATTRS"
+
+/*
+ * Path component length
+ *
+ * The generic fs code uses MAXNAMELEN to represent
+ * what the largest component length is.  Unfortunately,
+ * this length includes the terminating NULL.  ZFS needs
+ * to tell the users via pathconf() and statvfs() what the
+ * true maximum length of a component is, excluding the NULL.
+ */
+#define	ZFS_MAXNAMELEN	(MAXNAMELEN - 1)
+
+/*
+ * Convert mode bits (zp_mode) to BSD-style DT_* values for storing in
+ * the directory entries.  On Linux systems this value is already
+ * defined correctly as part of the /usr/include/dirent.h header file.
+ */
+#ifndef IFTODT
+#define	IFTODT(mode) (((mode) & S_IFMT) >> 12)
+#endif
+
+/*
+ * The directory entry has the type (currently unused on Solaris) in the
+ * top 4 bits, and the object number in the low 48 bits.  The "middle"
+ * 12 bits are unused.
+ */
+#define	ZFS_DIRENT_TYPE(de) BF64_GET(de, 60, 4)
+#define	ZFS_DIRENT_OBJ(de) BF64_GET(de, 0, 48)
+
+/*
+ * Directory entry locks control access to directory entries.
+ * They are used to protect creates, deletes, and renames.
+ * Each directory znode has a mutex and a list of locked names.
+ */
+#ifdef _KERNEL
+typedef struct zfs_dirlock {
+	char		*dl_name;	/* directory entry being locked */
+	uint32_t	dl_sharecnt;	/* 0 if exclusive, > 0 if shared */
+	uint8_t		dl_namelock;	/* 1 if z_name_lock is NOT held */
+	uint16_t	dl_namesize;	/* set if dl_name was allocated */
+	kcondvar_t	dl_cv;		/* wait for entry to be unlocked */
+	struct znode	*dl_dzp;	/* directory znode */
+	struct zfs_dirlock *dl_next;	/* next in z_dirlocks list */
+} zfs_dirlock_t;
+
+typedef struct znode {
+	uint64_t	z_id;		/* object ID for this znode */
+	kmutex_t	z_lock;		/* znode modification lock */
+	krwlock_t	z_parent_lock;	/* parent lock for directories */
+	krwlock_t	z_name_lock;	/* "master" lock for dirent locks */
+	zfs_dirlock_t	*z_dirlocks;	/* directory entry lock list */
+	kmutex_t	z_range_lock;	/* protects changes to z_range_avl */
+	avl_tree_t	z_range_avl;	/* avl tree of file range locks */
+	uint8_t		z_unlinked;	/* file has been unlinked */
+	uint8_t		z_atime_dirty;	/* atime needs to be synced */
+	uint8_t		z_zn_prefetch;	/* Prefetch znodes? */
+	uint8_t		z_moved;	/* Has this znode been moved? */
+	uint_t		z_blksz;	/* block size in bytes */
+	uint_t		z_seq;		/* modification sequence number */
+	uint64_t	z_mapcnt;	/* number of pages mapped to file */
+	uint64_t	z_gen;		/* generation (cached) */
+	uint64_t	z_size;		/* file size (cached) */
+	uint64_t	z_atime[2];	/* atime (cached) */
+	uint64_t	z_links;	/* file links (cached) */
+	uint64_t	z_pflags;	/* pflags (cached) */
+	uint64_t	z_uid;		/* uid fuid (cached) */
+	uint64_t	z_gid;		/* gid fuid (cached) */
+	uint32_t	z_sync_cnt;	/* synchronous open count */
+	mode_t		z_mode;		/* mode (cached) */
+	kmutex_t	z_acl_lock;	/* acl data lock */
+	zfs_acl_t	*z_acl_cached;	/* cached acl */
+	krwlock_t	z_xattr_lock;	/* xattr data lock */
+	nvlist_t	*z_xattr_cached; /* cached xattrs */
+	struct znode	*z_xattr_parent; /* xattr parent znode */
+	list_node_t	z_link_node;	/* all znodes in fs link */
+	sa_handle_t	*z_sa_hdl;	/* handle to sa data */
+	boolean_t	z_is_sa;	/* are we native sa? */
+	boolean_t	z_is_zvol;	/* are we used by the zvol */
+	boolean_t	z_is_mapped;	/* are we mmap'ed */
+	boolean_t	z_is_ctldir;	/* are we .zfs entry */
+	boolean_t	z_is_stale;	/* are we stale due to rollback? */
+	struct inode	z_inode;	/* generic vfs inode */
+} znode_t;
+
+typedef struct znode_hold {
+	uint64_t	zh_obj;		/* object id */
+	kmutex_t	zh_lock;	/* lock serializing object access */
+	avl_node_t	zh_node;	/* avl tree linkage */
+	refcount_t	zh_refcount;	/* active consumer reference count */
+} znode_hold_t;
+
+/*
+ * Range locking rules
+ * --------------------
+ * 1. When truncating a file (zfs_create, zfs_setattr, zfs_space) the whole
+ *    file range needs to be locked as RL_WRITER. Only then can the pages be
+ *    freed etc and zp_size reset. zp_size must be set within range lock.
+ * 2. For writes and punching holes (zfs_write & zfs_space) just the range
+ *    being written or freed needs to be locked as RL_WRITER.
+ *    Multiple writes at the end of the file must coordinate zp_size updates
+ *    to ensure data isn't lost. A compare and swap loop is currently used
+ *    to ensure the file size is at least the offset last written.
+ * 3. For reads (zfs_read, zfs_get_data & zfs_putapage) just the range being
+ *    read needs to be locked as RL_READER. A check against zp_size can then
+ *    be made for reading beyond end of file.
+ */
+
+/*
+ * Convert between znode pointers and inode pointers
+ */
+#define	ZTOI(znode)	(&((znode)->z_inode))
+#define	ITOZ(inode)	(container_of((inode), znode_t, z_inode))
+#define	ZTOZSB(znode)	((zfs_sb_t *)(ZTOI(znode)->i_sb->s_fs_info))
+#define	ITOZSB(inode)	((zfs_sb_t *)((inode)->i_sb->s_fs_info))
+
+#define	S_ISDEV(mode)	(S_ISCHR(mode) || S_ISBLK(mode) || S_ISFIFO(mode))
+
+/* Called on entry to each ZFS vnode and vfs operation  */
+#define	ZFS_ENTER(zsb) \
+	{ \
+		rrm_enter_read(&(zsb)->z_teardown_lock, FTAG); \
+		if ((zsb)->z_unmounted) { \
+			ZFS_EXIT(zsb); \
+			return (EIO); \
+		} \
+	}
+
+/* Must be called before exiting the vop */
+#define	ZFS_EXIT(zsb) \
+	{ \
+		rrm_exit(&(zsb)->z_teardown_lock, FTAG); \
+	}
+
+/* Verifies the znode is valid */
+#define	ZFS_VERIFY_ZP(zp) \
+	if ((zp)->z_sa_hdl == NULL) { \
+		ZFS_EXIT(ZTOZSB(zp)); \
+		return (EIO); \
+	}
+
+/*
+ * Macros for dealing with dmu_buf_hold
+ */
+#define	ZFS_OBJ_MTX_SZ		64
+#define	ZFS_OBJ_MTX_MAX		(1024 * 1024)
+#define	ZFS_OBJ_HASH(zsb, obj)	((obj) & ((zsb->z_hold_size) - 1))
+
+extern unsigned int zfs_object_mutex_size;
+
+/* Encode ZFS stored time values from a struct timespec */
+#define	ZFS_TIME_ENCODE(tp, stmp)		\
+{						\
+	(stmp)[0] = (uint64_t)(tp)->tv_sec;	\
+	(stmp)[1] = (uint64_t)(tp)->tv_nsec;	\
+}
+
+/* Decode ZFS stored time values to a struct timespec */
+#define	ZFS_TIME_DECODE(tp, stmp)		\
+{						\
+	(tp)->tv_sec = (time_t)(stmp)[0];		\
+	(tp)->tv_nsec = (long)(stmp)[1];		\
+}
+
+/*
+ * Timestamp defines
+ */
+#define	ACCESSED		(ATTR_ATIME)
+#define	STATE_CHANGED		(ATTR_CTIME)
+#define	CONTENT_MODIFIED	(ATTR_MTIME | ATTR_CTIME)
+
+#define	ZFS_ACCESSTIME_STAMP(zsb, zp) \
+	if ((zsb)->z_atime && !(zfs_is_readonly(zsb))) \
+		zfs_tstamp_update_setup(zp, ACCESSED, NULL, NULL, B_FALSE);
+
+extern int	zfs_init_fs(zfs_sb_t *, znode_t **);
+extern void	zfs_set_dataprop(objset_t *);
+extern void	zfs_create_fs(objset_t *os, cred_t *cr, nvlist_t *,
+    dmu_tx_t *tx);
+extern void	zfs_tstamp_update_setup(znode_t *, uint_t, uint64_t [2],
+    uint64_t [2], boolean_t);
+extern void	zfs_grow_blocksize(znode_t *, uint64_t, dmu_tx_t *);
+extern int	zfs_freesp(znode_t *, uint64_t, uint64_t, int, boolean_t);
+extern void	zfs_znode_init(void);
+extern void	zfs_znode_fini(void);
+extern int	zfs_znode_hold_compare(const void *, const void *);
+extern int	zfs_zget(zfs_sb_t *, uint64_t, znode_t **);
+extern int	zfs_rezget(znode_t *);
+extern void	zfs_zinactive(znode_t *);
+extern void	zfs_znode_delete(znode_t *, dmu_tx_t *);
+extern void	zfs_remove_op_tables(void);
+extern int	zfs_create_op_tables(void);
+extern int	zfs_sync(struct super_block *, int, cred_t *);
+extern dev_t	zfs_cmpldev(uint64_t);
+extern int	zfs_get_zplprop(objset_t *os, zfs_prop_t prop, uint64_t *value);
+extern int	zfs_get_stats(objset_t *os, nvlist_t *nv);
+extern void	zfs_znode_dmu_fini(znode_t *);
+extern int	zfs_inode_alloc(struct super_block *, struct inode **ip);
+extern void	zfs_inode_destroy(struct inode *);
+extern void	zfs_inode_update(znode_t *);
+extern void	zfs_mark_inode_dirty(struct inode *);
+
+extern void zfs_log_create(zilog_t *zilog, dmu_tx_t *tx, uint64_t txtype,
+    znode_t *dzp, znode_t *zp, char *name, vsecattr_t *, zfs_fuid_info_t *,
+    vattr_t *vap);
+extern int zfs_log_create_txtype(zil_create_t, vsecattr_t *vsecp,
+    vattr_t *vap);
+extern void zfs_log_remove(zilog_t *zilog, dmu_tx_t *tx, uint64_t txtype,
+    znode_t *dzp, char *name, uint64_t foid);
+#define	ZFS_NO_OBJECT	0	/* no object id */
+extern void zfs_log_link(zilog_t *zilog, dmu_tx_t *tx, uint64_t txtype,
+    znode_t *dzp, znode_t *zp, char *name);
+extern void zfs_log_symlink(zilog_t *zilog, dmu_tx_t *tx, uint64_t txtype,
+    znode_t *dzp, znode_t *zp, char *name, char *link);
+extern void zfs_log_rename(zilog_t *zilog, dmu_tx_t *tx, uint64_t txtype,
+    znode_t *sdzp, char *sname, znode_t *tdzp, char *dname, znode_t *szp);
+extern void zfs_log_write(zilog_t *zilog, dmu_tx_t *tx, int txtype,
+    znode_t *zp, offset_t off, ssize_t len, int ioflag,
+    zil_callback_t callback, void *callback_data);
+extern void zfs_log_truncate(zilog_t *zilog, dmu_tx_t *tx, int txtype,
+    znode_t *zp, uint64_t off, uint64_t len);
+extern void zfs_log_setattr(zilog_t *zilog, dmu_tx_t *tx, int txtype,
+    znode_t *zp, vattr_t *vap, uint_t mask_applied, zfs_fuid_info_t *fuidp);
+extern void zfs_log_acl(zilog_t *zilog, dmu_tx_t *tx, znode_t *zp,
+    vsecattr_t *vsecp, zfs_fuid_info_t *fuidp);
+extern void zfs_xvattr_set(znode_t *zp, xvattr_t *xvap, dmu_tx_t *tx);
+extern void zfs_upgrade(zfs_sb_t *zsb, dmu_tx_t *tx);
+extern int zfs_create_share_dir(zfs_sb_t *zsb, dmu_tx_t *tx);
+
+#if defined(HAVE_UIO_RW)
+extern caddr_t zfs_map_page(page_t *, enum seg_rw);
+extern void zfs_unmap_page(page_t *, caddr_t);
+#endif /* HAVE_UIO_RW */
+
+extern zil_get_data_t zfs_get_data;
+extern zil_replay_func_t zfs_replay_vector[TX_MAX_TYPE];
+extern int zfsfstype;
+
+#endif /* _KERNEL */
+
+extern int zfs_obj_to_path(objset_t *osp, uint64_t obj, char *buf, int len);
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* _SYS_FS_ZFS_ZNODE_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/include/sys/zil.h
@@ -0,0 +1,495 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012 by Delphix. All rights reserved.
+ */
+
+/* Portions Copyright 2010 Robert Milkowski */
+
+#ifndef	_SYS_ZIL_H
+#define	_SYS_ZIL_H
+
+#include <sys/types.h>
+#include <sys/spa.h>
+#include <sys/zio.h>
+#include <sys/dmu.h>
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+struct dsl_pool;
+struct dsl_dataset;
+
+/*
+ * Intent log format:
+ *
+ * Each objset has its own intent log.  The log header (zil_header_t)
+ * for objset N's intent log is kept in the Nth object of the SPA's
+ * intent_log objset.  The log header points to a chain of log blocks,
+ * each of which contains log records (i.e., transactions) followed by
+ * a log block trailer (zil_trailer_t).  The format of a log record
+ * depends on the record (or transaction) type, but all records begin
+ * with a common structure that defines the type, length, and txg.
+ */
+
+/*
+ * Intent log header - this on disk structure holds fields to manage
+ * the log.  All fields are 64 bit to easily handle cross architectures.
+ */
+typedef struct zil_header {
+	uint64_t zh_claim_txg;	/* txg in which log blocks were claimed */
+	uint64_t zh_replay_seq;	/* highest replayed sequence number */
+	blkptr_t zh_log;	/* log chain */
+	uint64_t zh_claim_blk_seq; /* highest claimed block sequence number */
+	uint64_t zh_flags;	/* header flags */
+	uint64_t zh_claim_lr_seq; /* highest claimed lr sequence number */
+	uint64_t zh_pad[3];
+} zil_header_t;
+
+/*
+ * zh_flags bit settings
+ */
+#define	ZIL_REPLAY_NEEDED	0x1	/* replay needed - internal only */
+#define	ZIL_CLAIM_LR_SEQ_VALID	0x2	/* zh_claim_lr_seq field is valid */
+
+/*
+ * Log block chaining.
+ *
+ * Log blocks are chained together. Originally they were chained at the
+ * end of the block. For performance reasons the chain was moved to the
+ * beginning of the block which allows writes for only the data being used.
+ * The older position is supported for backwards compatability.
+ *
+ * The zio_eck_t contains a zec_cksum which for the intent log is
+ * the sequence number of this log block. A seq of 0 is invalid.
+ * The zec_cksum is checked by the SPA against the sequence
+ * number passed in the blk_cksum field of the blkptr_t
+ */
+typedef struct zil_chain {
+	uint64_t zc_pad;
+	blkptr_t zc_next_blk;	/* next block in chain */
+	uint64_t zc_nused;	/* bytes in log block used */
+	zio_eck_t zc_eck;	/* block trailer */
+} zil_chain_t;
+
+#define	ZIL_MIN_BLKSZ	4096ULL
+
+/*
+ * The words of a log block checksum.
+ */
+#define	ZIL_ZC_GUID_0	0
+#define	ZIL_ZC_GUID_1	1
+#define	ZIL_ZC_OBJSET	2
+#define	ZIL_ZC_SEQ	3
+
+typedef enum zil_create {
+	Z_FILE,
+	Z_DIR,
+	Z_XATTRDIR,
+} zil_create_t;
+
+/*
+ * size of xvattr log section.
+ * its composed of lr_attr_t + xvattr bitmap + 2 64 bit timestamps
+ * for create time and a single 64 bit integer for all of the attributes,
+ * and 4 64 bit integers (32 bytes) for the scanstamp.
+ *
+ */
+
+#define	ZIL_XVAT_SIZE(mapsize) \
+	sizeof (lr_attr_t) + (sizeof (uint32_t) * (mapsize - 1)) + \
+	(sizeof (uint64_t) * 7)
+
+/*
+ * Size of ACL in log.  The ACE data is padded out to properly align
+ * on 8 byte boundary.
+ */
+
+#define	ZIL_ACE_LENGTH(x)	(roundup(x, sizeof (uint64_t)))
+
+/*
+ * Intent log transaction types and record structures
+ */
+#define	TX_CREATE		1	/* Create file */
+#define	TX_MKDIR		2	/* Make directory */
+#define	TX_MKXATTR		3	/* Make XATTR directory */
+#define	TX_SYMLINK		4	/* Create symbolic link to a file */
+#define	TX_REMOVE		5	/* Remove file */
+#define	TX_RMDIR		6	/* Remove directory */
+#define	TX_LINK			7	/* Create hard link to a file */
+#define	TX_RENAME		8	/* Rename a file */
+#define	TX_WRITE		9	/* File write */
+#define	TX_TRUNCATE		10	/* Truncate a file */
+#define	TX_SETATTR		11	/* Set file attributes */
+#define	TX_ACL_V0		12	/* Set old formatted ACL */
+#define	TX_ACL			13	/* Set ACL */
+#define	TX_CREATE_ACL		14	/* create with ACL */
+#define	TX_CREATE_ATTR		15	/* create + attrs */
+#define	TX_CREATE_ACL_ATTR 	16	/* create with ACL + attrs */
+#define	TX_MKDIR_ACL		17	/* mkdir with ACL */
+#define	TX_MKDIR_ATTR		18	/* mkdir with attr */
+#define	TX_MKDIR_ACL_ATTR	19	/* mkdir with ACL + attrs */
+#define	TX_WRITE2		20	/* dmu_sync EALREADY write */
+#define	TX_MAX_TYPE		21	/* Max transaction type */
+
+/*
+ * The transactions for mkdir, symlink, remove, rmdir, link, and rename
+ * may have the following bit set, indicating the original request
+ * specified case-insensitive handling of names.
+ */
+#define	TX_CI	((uint64_t)0x1 << 63) /* case-insensitive behavior requested */
+
+/*
+ * Transactions for write, truncate, setattr, acl_v0, and acl can be logged
+ * out of order.  For convenience in the code, all such records must have
+ * lr_foid at the same offset.
+ */
+#define	TX_OOO(txtype)			\
+	((txtype) == TX_WRITE ||	\
+	(txtype) == TX_TRUNCATE ||	\
+	(txtype) == TX_SETATTR ||	\
+	(txtype) == TX_ACL_V0 ||	\
+	(txtype) == TX_ACL ||		\
+	(txtype) == TX_WRITE2)
+
+/*
+ * Format of log records.
+ * The fields are carefully defined to allow them to be aligned
+ * and sized the same on sparc & intel architectures.
+ * Each log record has a common structure at the beginning.
+ *
+ * The log record on disk (lrc_seq) holds the sequence number of all log
+ * records which is used to ensure we don't replay the same record.
+ */
+typedef struct {			/* common log record header */
+	uint64_t	lrc_txtype;	/* intent log transaction type */
+	uint64_t	lrc_reclen;	/* transaction record length */
+	uint64_t	lrc_txg;	/* dmu transaction group number */
+	uint64_t	lrc_seq;	/* see comment above */
+} lr_t;
+
+/*
+ * Common start of all out-of-order record types (TX_OOO() above).
+ */
+typedef struct {
+	lr_t		lr_common;	/* common portion of log record */
+	uint64_t	lr_foid;	/* object id */
+} lr_ooo_t;
+
+/*
+ * Handle option extended vattr attributes.
+ *
+ * Whenever new attributes are added the version number
+ * will need to be updated as will code in
+ * zfs_log.c and zfs_replay.c
+ */
+typedef struct {
+	uint32_t	lr_attr_masksize; /* number of elements in array */
+	uint32_t	lr_attr_bitmap; /* First entry of array */
+	/* remainder of array and any additional fields */
+} lr_attr_t;
+
+/*
+ * log record for creates without optional ACL.
+ * This log record does support optional xvattr_t attributes.
+ */
+typedef struct {
+	lr_t		lr_common;	/* common portion of log record */
+	uint64_t	lr_doid;	/* object id of directory */
+	uint64_t	lr_foid;	/* object id of created file object */
+	uint64_t	lr_mode;	/* mode of object */
+	uint64_t	lr_uid;		/* uid of object */
+	uint64_t	lr_gid;		/* gid of object */
+	uint64_t	lr_gen;		/* generation (txg of creation) */
+	uint64_t	lr_crtime[2];	/* creation time */
+	uint64_t	lr_rdev;	/* rdev of object to create */
+	/* name of object to create follows this */
+	/* for symlinks, link content follows name */
+	/* for creates with xvattr data, the name follows the xvattr info */
+} lr_create_t;
+
+/*
+ * FUID ACL record will be an array of ACEs from the original ACL.
+ * If this array includes ephemeral IDs, the record will also include
+ * an array of log-specific FUIDs to replace the ephemeral IDs.
+ * Only one copy of each unique domain will be present, so the log-specific
+ * FUIDs will use an index into a compressed domain table.  On replay this
+ * information will be used to construct real FUIDs (and bypass idmap,
+ * since it may not be available).
+ */
+
+/*
+ * Log record for creates with optional ACL
+ * This log record is also used for recording any FUID
+ * information needed for replaying the create.  If the
+ * file doesn't have any actual ACEs then the lr_aclcnt
+ * would be zero.
+ *
+ * After lr_acl_flags, there are a lr_acl_bytes number of variable sized ace's.
+ * If create is also setting xvattr's, then acl data follows xvattr.
+ * If ACE FUIDs are needed then they will follow the xvattr_t.  Following
+ * the FUIDs will be the domain table information.  The FUIDs for the owner
+ * and group will be in lr_create.  Name follows ACL data.
+ */
+typedef struct {
+	lr_create_t	lr_create;	/* common create portion */
+	uint64_t	lr_aclcnt;	/* number of ACEs in ACL */
+	uint64_t	lr_domcnt;	/* number of unique domains */
+	uint64_t	lr_fuidcnt;	/* number of real fuids */
+	uint64_t	lr_acl_bytes;	/* number of bytes in ACL */
+	uint64_t	lr_acl_flags;	/* ACL flags */
+} lr_acl_create_t;
+
+typedef struct {
+	lr_t		lr_common;	/* common portion of log record */
+	uint64_t	lr_doid;	/* obj id of directory */
+	/* name of object to remove follows this */
+} lr_remove_t;
+
+typedef struct {
+	lr_t		lr_common;	/* common portion of log record */
+	uint64_t	lr_doid;	/* obj id of directory */
+	uint64_t	lr_link_obj;	/* obj id of link */
+	/* name of object to link follows this */
+} lr_link_t;
+
+typedef struct {
+	lr_t		lr_common;	/* common portion of log record */
+	uint64_t	lr_sdoid;	/* obj id of source directory */
+	uint64_t	lr_tdoid;	/* obj id of target directory */
+	/* 2 strings: names of source and destination follow this */
+} lr_rename_t;
+
+typedef struct {
+	lr_t		lr_common;	/* common portion of log record */
+	uint64_t	lr_foid;	/* file object to write */
+	uint64_t	lr_offset;	/* offset to write to */
+	uint64_t	lr_length;	/* user data length to write */
+	uint64_t	lr_blkoff;	/* no longer used */
+	blkptr_t	lr_blkptr;	/* spa block pointer for replay */
+	/* write data will follow for small writes */
+} lr_write_t;
+
+typedef struct {
+	lr_t		lr_common;	/* common portion of log record */
+	uint64_t	lr_foid;	/* object id of file to truncate */
+	uint64_t	lr_offset;	/* offset to truncate from */
+	uint64_t	lr_length;	/* length to truncate */
+} lr_truncate_t;
+
+typedef struct {
+	lr_t		lr_common;	/* common portion of log record */
+	uint64_t	lr_foid;	/* file object to change attributes */
+	uint64_t	lr_mask;	/* mask of attributes to set */
+	uint64_t	lr_mode;	/* mode to set */
+	uint64_t	lr_uid;		/* uid to set */
+	uint64_t	lr_gid;		/* gid to set */
+	uint64_t	lr_size;	/* size to set */
+	uint64_t	lr_atime[2];	/* access time */
+	uint64_t	lr_mtime[2];	/* modification time */
+	/* optional attribute lr_attr_t may be here */
+} lr_setattr_t;
+
+typedef struct {
+	lr_t		lr_common;	/* common portion of log record */
+	uint64_t	lr_foid;	/* obj id of file */
+	uint64_t	lr_aclcnt;	/* number of acl entries */
+	/* lr_aclcnt number of ace_t entries follow this */
+} lr_acl_v0_t;
+
+typedef struct {
+	lr_t		lr_common;	/* common portion of log record */
+	uint64_t	lr_foid;	/* obj id of file */
+	uint64_t	lr_aclcnt;	/* number of ACEs in ACL */
+	uint64_t	lr_domcnt;	/* number of unique domains */
+	uint64_t	lr_fuidcnt;	/* number of real fuids */
+	uint64_t	lr_acl_bytes;	/* number of bytes in ACL */
+	uint64_t	lr_acl_flags;	/* ACL flags */
+	/* lr_acl_bytes number of variable sized ace's follows */
+} lr_acl_t;
+
+/*
+ * ZIL structure definitions, interface function prototype and globals.
+ */
+
+/*
+ * Writes are handled in three different ways:
+ *
+ * WR_INDIRECT:
+ *    In this mode, if we need to commit the write later, then the block
+ *    is immediately written into the file system (using dmu_sync),
+ *    and a pointer to the block is put into the log record.
+ *    When the txg commits the block is linked in.
+ *    This saves additionally writing the data into the log record.
+ *    There are a few requirements for this to occur:
+ *	- write is greater than zfs/zvol_immediate_write_sz
+ *	- not using slogs (as slogs are assumed to always be faster
+ *	  than writing into the main pool)
+ *	- the write occupies only one block
+ * WR_COPIED:
+ *    If we know we'll immediately be committing the
+ *    transaction (FSYNC or FDSYNC), the we allocate a larger
+ *    log record here for the data and copy the data in.
+ * WR_NEED_COPY:
+ *    Otherwise we don't allocate a buffer, and *if* we need to
+ *    flush the write later then a buffer is allocated and
+ *    we retrieve the data using the dmu.
+ */
+typedef enum {
+	WR_INDIRECT,	/* indirect - a large write (dmu_sync() data */
+			/* and put blkptr in log, rather than actual data) */
+	WR_COPIED,	/* immediate - data is copied into lr_write_t */
+	WR_NEED_COPY,	/* immediate - data needs to be copied if pushed */
+	WR_NUM_STATES	/* number of states */
+} itx_wr_state_t;
+
+typedef void (*zil_callback_t)(void *data);
+
+typedef struct itx {
+	list_node_t	itx_node;	/* linkage on zl_itx_list */
+	void		*itx_private;	/* type-specific opaque data */
+	itx_wr_state_t	itx_wr_state;	/* write state */
+	uint8_t		itx_sync;	/* synchronous transaction */
+	zil_callback_t	itx_callback;   /* Called when the itx is persistent */
+	void		*itx_callback_data; /* User data for the callback */
+	uint64_t	itx_sod;	/* record size on disk */
+	uint64_t	itx_oid;	/* object id */
+	lr_t		itx_lr;		/* common part of log record */
+	/* followed by type-specific part of lr_xx_t and its immediate data */
+} itx_t;
+
+/*
+ * Used for zil kstat.
+ */
+typedef struct zil_stats {
+	/*
+	 * Number of times a ZIL commit (e.g. fsync) has been requested.
+	 */
+	kstat_named_t zil_commit_count;
+
+	/*
+	 * Number of times the ZIL has been flushed to stable storage.
+	 * This is less than zil_commit_count when commits are "merged"
+	 * (see the documentation above zil_commit()).
+	 */
+	kstat_named_t zil_commit_writer_count;
+
+	/*
+	 * Number of transactions (reads, writes, renames, etc.)
+	 * that have been commited.
+	 */
+	kstat_named_t zil_itx_count;
+
+	/*
+	 * See the documentation for itx_wr_state_t above.
+	 * Note that "bytes" accumulates the length of the transactions
+	 * (i.e. data), not the actual log record sizes.
+	 */
+	kstat_named_t zil_itx_indirect_count;
+	kstat_named_t zil_itx_indirect_bytes;
+	kstat_named_t zil_itx_copied_count;
+	kstat_named_t zil_itx_copied_bytes;
+	kstat_named_t zil_itx_needcopy_count;
+	kstat_named_t zil_itx_needcopy_bytes;
+
+	/*
+	 * Transactions which have been allocated to the "normal"
+	 * (i.e. not slog) storage pool. Note that "bytes" accumulate
+	 * the actual log record sizes - which do not include the actual
+	 * data in case of indirect writes.
+	 */
+	kstat_named_t zil_itx_metaslab_normal_count;
+	kstat_named_t zil_itx_metaslab_normal_bytes;
+
+	/*
+	 * Transactions which have been allocated to the "slog" storage pool.
+	 * If there are no separate log devices, this is the same as the
+	 * "normal" pool.
+	 */
+	kstat_named_t zil_itx_metaslab_slog_count;
+	kstat_named_t zil_itx_metaslab_slog_bytes;
+} zil_stats_t;
+
+extern zil_stats_t zil_stats;
+
+#define	ZIL_STAT_INCR(stat, val) \
+    atomic_add_64(&zil_stats.stat.value.ui64, (val));
+#define	ZIL_STAT_BUMP(stat) \
+    ZIL_STAT_INCR(stat, 1);
+
+typedef int zil_parse_blk_func_t(zilog_t *zilog, blkptr_t *bp, void *arg,
+    uint64_t txg);
+typedef int zil_parse_lr_func_t(zilog_t *zilog, lr_t *lr, void *arg,
+    uint64_t txg);
+typedef int (*const zil_replay_func_t)(void *, char *, boolean_t);
+typedef int zil_get_data_t(void *arg, lr_write_t *lr, char *dbuf, zio_t *zio);
+
+extern int zil_parse(zilog_t *zilog, zil_parse_blk_func_t *parse_blk_func,
+    zil_parse_lr_func_t *parse_lr_func, void *arg, uint64_t txg);
+
+extern void	zil_init(void);
+extern void	zil_fini(void);
+
+extern zilog_t	*zil_alloc(objset_t *os, zil_header_t *zh_phys);
+extern void	zil_free(zilog_t *zilog);
+
+extern zilog_t	*zil_open(objset_t *os, zil_get_data_t *get_data);
+extern void	zil_close(zilog_t *zilog);
+
+extern void	zil_replay(objset_t *os, void *arg,
+    zil_replay_func_t replay_func[TX_MAX_TYPE]);
+extern boolean_t zil_replaying(zilog_t *zilog, dmu_tx_t *tx);
+extern void	zil_destroy(zilog_t *zilog, boolean_t keep_first);
+extern void	zil_destroy_sync(zilog_t *zilog, dmu_tx_t *tx);
+
+extern itx_t	*zil_itx_create(uint64_t txtype, size_t lrsize);
+extern void	zil_itx_destroy(itx_t *itx);
+extern void	zil_itx_assign(zilog_t *zilog, itx_t *itx, dmu_tx_t *tx);
+
+extern void	zil_commit(zilog_t *zilog, uint64_t oid);
+
+extern int	zil_vdev_offline(const char *osname, void *txarg);
+extern int	zil_claim(struct dsl_pool *dp,
+    struct dsl_dataset *ds, void *txarg);
+extern int 	zil_check_log_chain(struct dsl_pool *dp,
+    struct dsl_dataset *ds, void *tx);
+extern void	zil_sync(zilog_t *zilog, dmu_tx_t *tx);
+extern void	zil_clean(zilog_t *zilog, uint64_t synced_txg);
+
+extern int	zil_suspend(const char *osname, void **cookiep);
+extern void	zil_resume(void *cookie);
+
+extern void	zil_add_block(zilog_t *zilog, const blkptr_t *bp);
+extern int	zil_bp_tree_add(zilog_t *zilog, const blkptr_t *bp);
+
+extern void	zil_set_sync(zilog_t *zilog, uint64_t syncval);
+
+extern void	zil_set_logbias(zilog_t *zilog, uint64_t slogval);
+
+extern int zil_replay_disable;
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* _SYS_ZIL_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/include/sys/zil_impl.h
@@ -0,0 +1,150 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012 by Delphix. All rights reserved.
+ */
+
+/* Portions Copyright 2010 Robert Milkowski */
+
+#ifndef	_SYS_ZIL_IMPL_H
+#define	_SYS_ZIL_IMPL_H
+
+#include <sys/zil.h>
+#include <sys/dmu_objset.h>
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+/*
+ * Log write buffer.
+ */
+typedef struct lwb {
+	zilog_t		*lwb_zilog;	/* back pointer to log struct */
+	blkptr_t	lwb_blk;	/* on disk address of this log blk */
+	boolean_t	lwb_fastwrite;	/* is blk marked for fastwrite? */
+	int		lwb_nused;	/* # used bytes in buffer */
+	int		lwb_sz;		/* size of block and buffer */
+	char		*lwb_buf;	/* log write buffer */
+	zio_t		*lwb_zio;	/* zio for this buffer */
+	dmu_tx_t	*lwb_tx;	/* tx for log block allocation */
+	uint64_t	lwb_max_txg;	/* highest txg in this lwb */
+	list_node_t	lwb_node;	/* zilog->zl_lwb_list linkage */
+} lwb_t;
+
+/*
+ * Intent log transaction lists
+ */
+typedef struct itxs {
+	list_t		i_sync_list;	/* list of synchronous itxs */
+	avl_tree_t	i_async_tree;	/* tree of foids for async itxs */
+} itxs_t;
+
+typedef struct itxg {
+	kmutex_t	itxg_lock;	/* lock for this structure */
+	uint64_t	itxg_txg;	/* txg for this chain */
+	uint64_t	itxg_sod;	/* total size on disk for this txg */
+	itxs_t		*itxg_itxs;	/* sync and async itxs */
+} itxg_t;
+
+/* for async nodes we build up an AVL tree of lists of async itxs per file */
+typedef struct itx_async_node {
+	uint64_t	ia_foid;	/* file object id */
+	list_t		ia_list;	/* list of async itxs for this foid */
+	avl_node_t	ia_node;	/* AVL tree linkage */
+} itx_async_node_t;
+
+/*
+ * Vdev flushing: during a zil_commit(), we build up an AVL tree of the vdevs
+ * we've touched so we know which ones need a write cache flush at the end.
+ */
+typedef struct zil_vdev_node {
+	uint64_t	zv_vdev;	/* vdev to be flushed */
+	avl_node_t	zv_node;	/* AVL tree linkage */
+} zil_vdev_node_t;
+
+#define	ZIL_PREV_BLKS 16
+
+/*
+ * Stable storage intent log management structure.  One per dataset.
+ */
+struct zilog {
+	kmutex_t	zl_lock;	/* protects most zilog_t fields */
+	struct dsl_pool	*zl_dmu_pool;	/* DSL pool */
+	spa_t		*zl_spa;	/* handle for read/write log */
+	const zil_header_t *zl_header;	/* log header buffer */
+	objset_t	*zl_os;		/* object set we're logging */
+	zil_get_data_t	*zl_get_data;	/* callback to get object content */
+	zio_t		*zl_root_zio;	/* log writer root zio */
+	uint64_t	zl_lr_seq;	/* on-disk log record sequence number */
+	uint64_t	zl_commit_lr_seq; /* last committed on-disk lr seq */
+	uint64_t	zl_destroy_txg;	/* txg of last zil_destroy() */
+	uint64_t	zl_replayed_seq[TXG_SIZE]; /* last replayed rec seq */
+	uint64_t	zl_replaying_seq; /* current replay seq number */
+	uint32_t	zl_suspend;	/* log suspend count */
+	kcondvar_t	zl_cv_writer;	/* log writer thread completion */
+	kcondvar_t	zl_cv_suspend;	/* log suspend completion */
+	uint8_t		zl_suspending;	/* log is currently suspending */
+	uint8_t		zl_keep_first;	/* keep first log block in destroy */
+	uint8_t		zl_replay;	/* replaying records while set */
+	uint8_t		zl_stop_sync;	/* for debugging */
+	uint8_t		zl_writer;	/* boolean: write setup in progress */
+	uint8_t		zl_logbias;	/* latency or throughput */
+	uint8_t		zl_sync;	/* synchronous or asynchronous */
+	int		zl_parse_error;	/* last zil_parse() error */
+	uint64_t	zl_parse_blk_seq; /* highest blk seq on last parse */
+	uint64_t	zl_parse_lr_seq; /* highest lr seq on last parse */
+	uint64_t	zl_parse_blk_count; /* number of blocks parsed */
+	uint64_t	zl_parse_lr_count; /* number of log records parsed */
+	uint64_t	zl_next_batch;	/* next batch number */
+	uint64_t	zl_com_batch;	/* committed batch number */
+	kcondvar_t	zl_cv_batch[2];	/* batch condition variables */
+	itxg_t		zl_itxg[TXG_SIZE]; /* intent log txg chains */
+	list_t		zl_itx_commit_list; /* itx list to be committed */
+	uint64_t	zl_itx_list_sz;	/* total size of records on list */
+	uint64_t	zl_cur_used;	/* current commit log size used */
+	list_t		zl_lwb_list;	/* in-flight log write list */
+	kmutex_t	zl_vdev_lock;	/* protects zl_vdev_tree */
+	avl_tree_t	zl_vdev_tree;	/* vdevs to flush in zil_commit() */
+	taskq_t		*zl_clean_taskq; /* runs lwb and itx clean tasks */
+	avl_tree_t	zl_bp_tree;	/* track bps during log parse */
+	clock_t		zl_replay_time;	/* lbolt of when replay started */
+	uint64_t	zl_replay_blks;	/* number of log blocks replayed */
+	zil_header_t	zl_old_header;	/* debugging aid */
+	uint_t		zl_prev_blks[ZIL_PREV_BLKS]; /* size - sector rounded */
+	uint_t		zl_prev_rotor;	/* rotor for zl_prev[] */
+	txg_node_t	zl_dirty_link;	/* protected by dp_dirty_zilogs list */
+};
+
+typedef struct zil_bp_node {
+	dva_t		zn_dva;
+	avl_node_t	zn_node;
+} zil_bp_node_t;
+
+#define	ZIL_MAX_LOG_DATA (SPA_OLD_MAXBLOCKSIZE - sizeof (zil_chain_t) - \
+    sizeof (lr_write_t))
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* _SYS_ZIL_IMPL_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/include/sys/zio.h
@@ -0,0 +1,609 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
+ * Copyright (c) 2012, 2014 by Delphix. All rights reserved.
+ * Copyright (c) 2013 by Saso Kiselkov. All rights reserved.
+ */
+
+#ifndef _ZIO_H
+#define	_ZIO_H
+
+#include <sys/zfs_context.h>
+#include <sys/spa.h>
+#include <sys/txg.h>
+#include <sys/avl.h>
+#include <sys/fs/zfs.h>
+#include <sys/zio_impl.h>
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+/*
+ * Embedded checksum
+ */
+#define	ZEC_MAGIC	0x210da7ab10c7a11ULL
+
+typedef struct zio_eck {
+	uint64_t	zec_magic;	/* for validation, endianness	*/
+	zio_cksum_t	zec_cksum;	/* 256-bit checksum		*/
+} zio_eck_t;
+
+/*
+ * Gang block headers are self-checksumming and contain an array
+ * of block pointers.
+ */
+#define	SPA_GANGBLOCKSIZE	SPA_MINBLOCKSIZE
+#define	SPA_GBH_NBLKPTRS	((SPA_GANGBLOCKSIZE - \
+	sizeof (zio_eck_t)) / sizeof (blkptr_t))
+#define	SPA_GBH_FILLER		((SPA_GANGBLOCKSIZE - \
+	sizeof (zio_eck_t) - \
+	(SPA_GBH_NBLKPTRS * sizeof (blkptr_t))) /\
+	sizeof (uint64_t))
+
+typedef struct zio_gbh {
+	blkptr_t		zg_blkptr[SPA_GBH_NBLKPTRS];
+	uint64_t		zg_filler[SPA_GBH_FILLER];
+	zio_eck_t		zg_tail;
+} zio_gbh_phys_t;
+
+enum zio_checksum {
+	ZIO_CHECKSUM_INHERIT = 0,
+	ZIO_CHECKSUM_ON,
+	ZIO_CHECKSUM_OFF,
+	ZIO_CHECKSUM_LABEL,
+	ZIO_CHECKSUM_GANG_HEADER,
+	ZIO_CHECKSUM_ZILOG,
+	ZIO_CHECKSUM_FLETCHER_2,
+	ZIO_CHECKSUM_FLETCHER_4,
+	ZIO_CHECKSUM_SHA256,
+	ZIO_CHECKSUM_ZILOG2,
+	ZIO_CHECKSUM_FUNCTIONS
+};
+
+/*
+ * The number of "legacy" compression functions which can be set on individual
+ * objects.
+ */
+#define	ZIO_CHECKSUM_LEGACY_FUNCTIONS ZIO_CHECKSUM_ZILOG2
+
+#define	ZIO_CHECKSUM_ON_VALUE	ZIO_CHECKSUM_FLETCHER_4
+#define	ZIO_CHECKSUM_DEFAULT	ZIO_CHECKSUM_ON
+
+#define	ZIO_CHECKSUM_MASK	0xffULL
+#define	ZIO_CHECKSUM_VERIFY	(1 << 8)
+
+#define	ZIO_DEDUPCHECKSUM	ZIO_CHECKSUM_SHA256
+#define	ZIO_DEDUPDITTO_MIN	100
+
+enum zio_compress {
+	ZIO_COMPRESS_INHERIT = 0,
+	ZIO_COMPRESS_ON,
+	ZIO_COMPRESS_OFF,
+	ZIO_COMPRESS_LZJB,
+	ZIO_COMPRESS_EMPTY,
+	ZIO_COMPRESS_GZIP_1,
+	ZIO_COMPRESS_GZIP_2,
+	ZIO_COMPRESS_GZIP_3,
+	ZIO_COMPRESS_GZIP_4,
+	ZIO_COMPRESS_GZIP_5,
+	ZIO_COMPRESS_GZIP_6,
+	ZIO_COMPRESS_GZIP_7,
+	ZIO_COMPRESS_GZIP_8,
+	ZIO_COMPRESS_GZIP_9,
+	ZIO_COMPRESS_ZLE,
+	ZIO_COMPRESS_LZ4,
+	ZIO_COMPRESS_FUNCTIONS
+};
+
+/*
+ * The number of "legacy" compression functions which can be set on individual
+ * objects.
+ */
+#define	ZIO_COMPRESS_LEGACY_FUNCTIONS ZIO_COMPRESS_LZ4
+
+/*
+ * The meaning of "compress = on" selected by the compression features enabled
+ * on a given pool.
+ */
+#define	ZIO_COMPRESS_LEGACY_ON_VALUE	ZIO_COMPRESS_LZJB
+#define	ZIO_COMPRESS_LZ4_ON_VALUE	ZIO_COMPRESS_LZ4
+
+#define	ZIO_COMPRESS_DEFAULT		ZIO_COMPRESS_OFF
+
+#define	BOOTFS_COMPRESS_VALID(compress)			\
+	((compress) == ZIO_COMPRESS_LZJB ||		\
+	(compress) == ZIO_COMPRESS_LZ4 ||		\
+	(compress) == ZIO_COMPRESS_ON ||		\
+	(compress) == ZIO_COMPRESS_OFF)
+
+/*
+ * Default Linux timeout for a sd device.
+ */
+#define	ZIO_DELAY_MAX			(30 * MILLISEC)
+
+#define	ZIO_FAILURE_MODE_WAIT		0
+#define	ZIO_FAILURE_MODE_CONTINUE	1
+#define	ZIO_FAILURE_MODE_PANIC		2
+
+typedef enum zio_priority {
+	ZIO_PRIORITY_SYNC_READ,
+	ZIO_PRIORITY_SYNC_WRITE,	/* ZIL */
+	ZIO_PRIORITY_ASYNC_READ,	/* prefetch */
+	ZIO_PRIORITY_ASYNC_WRITE,	/* spa_sync() */
+	ZIO_PRIORITY_SCRUB,		/* asynchronous scrub/resilver reads */
+	ZIO_PRIORITY_NUM_QUEUEABLE,
+
+	ZIO_PRIORITY_NOW		/* non-queued i/os (e.g. free) */
+} zio_priority_t;
+
+enum zio_flag {
+	/*
+	 * Flags inherited by gang, ddt, and vdev children,
+	 * and that must be equal for two zios to aggregate
+	 */
+	ZIO_FLAG_DONT_AGGREGATE	= 1 << 0,
+	ZIO_FLAG_IO_REPAIR	= 1 << 1,
+	ZIO_FLAG_SELF_HEAL	= 1 << 2,
+	ZIO_FLAG_RESILVER	= 1 << 3,
+	ZIO_FLAG_SCRUB		= 1 << 4,
+	ZIO_FLAG_SCAN_THREAD	= 1 << 5,
+	ZIO_FLAG_PHYSICAL	= 1 << 6,
+
+#define	ZIO_FLAG_AGG_INHERIT	(ZIO_FLAG_CANFAIL - 1)
+
+	/*
+	 * Flags inherited by ddt, gang, and vdev children.
+	 */
+	ZIO_FLAG_CANFAIL	= 1 << 7,	/* must be first for INHERIT */
+	ZIO_FLAG_SPECULATIVE	= 1 << 8,
+	ZIO_FLAG_CONFIG_WRITER	= 1 << 9,
+	ZIO_FLAG_DONT_RETRY	= 1 << 10,
+	ZIO_FLAG_DONT_CACHE	= 1 << 11,
+	ZIO_FLAG_NODATA		= 1 << 12,
+	ZIO_FLAG_INDUCE_DAMAGE	= 1 << 13,
+
+#define	ZIO_FLAG_DDT_INHERIT	(ZIO_FLAG_IO_RETRY - 1)
+#define	ZIO_FLAG_GANG_INHERIT	(ZIO_FLAG_IO_RETRY - 1)
+
+	/*
+	 * Flags inherited by vdev children.
+	 */
+	ZIO_FLAG_IO_RETRY	= 1 << 14,	/* must be first for INHERIT */
+	ZIO_FLAG_PROBE		= 1 << 15,
+	ZIO_FLAG_TRYHARD	= 1 << 16,
+	ZIO_FLAG_OPTIONAL	= 1 << 17,
+
+#define	ZIO_FLAG_VDEV_INHERIT	(ZIO_FLAG_DONT_QUEUE - 1)
+
+	/*
+	 * Flags not inherited by any children.
+	 */
+	ZIO_FLAG_DONT_QUEUE	= 1 << 18,	/* must be first for INHERIT */
+	ZIO_FLAG_DONT_PROPAGATE	= 1 << 19,
+	ZIO_FLAG_IO_BYPASS	= 1 << 20,
+	ZIO_FLAG_IO_REWRITE	= 1 << 21,
+	ZIO_FLAG_RAW		= 1 << 22,
+	ZIO_FLAG_GANG_CHILD	= 1 << 23,
+	ZIO_FLAG_DDT_CHILD	= 1 << 24,
+	ZIO_FLAG_GODFATHER	= 1 << 25,
+	ZIO_FLAG_NOPWRITE	= 1 << 26,
+	ZIO_FLAG_REEXECUTED	= 1 << 27,
+	ZIO_FLAG_DELEGATED	= 1 << 28,
+	ZIO_FLAG_FASTWRITE	= 1 << 29,
+};
+
+#define	ZIO_FLAG_MUSTSUCCEED		0
+
+#define	ZIO_DDT_CHILD_FLAGS(zio)				\
+	(((zio)->io_flags & ZIO_FLAG_DDT_INHERIT) |		\
+	ZIO_FLAG_DDT_CHILD | ZIO_FLAG_CANFAIL)
+
+#define	ZIO_GANG_CHILD_FLAGS(zio)				\
+	(((zio)->io_flags & ZIO_FLAG_GANG_INHERIT) |		\
+	ZIO_FLAG_GANG_CHILD | ZIO_FLAG_CANFAIL)
+
+#define	ZIO_VDEV_CHILD_FLAGS(zio)				\
+	(((zio)->io_flags & ZIO_FLAG_VDEV_INHERIT) |		\
+	ZIO_FLAG_CANFAIL)
+
+enum zio_child {
+	ZIO_CHILD_VDEV = 0,
+	ZIO_CHILD_GANG,
+	ZIO_CHILD_DDT,
+	ZIO_CHILD_LOGICAL,
+	ZIO_CHILD_TYPES
+};
+
+enum zio_wait_type {
+	ZIO_WAIT_READY = 0,
+	ZIO_WAIT_DONE,
+	ZIO_WAIT_TYPES
+};
+
+/*
+ * We'll take the unused errnos, 'EBADE' and 'EBADR' (from the Convergent
+ * graveyard) to indicate checksum errors and fragmentation.
+ */
+#define	ECKSUM	EBADE
+#define	EFRAGS	EBADR
+
+typedef void zio_done_func_t(zio_t *zio);
+
+extern const char *zio_type_name[ZIO_TYPES];
+
+/*
+ * A bookmark is a four-tuple <objset, object, level, blkid> that uniquely
+ * identifies any block in the pool.  By convention, the meta-objset (MOS)
+ * is objset 0, and the meta-dnode is object 0.  This covers all blocks
+ * except root blocks and ZIL blocks, which are defined as follows:
+ *
+ * Root blocks (objset_phys_t) are object 0, level -1:  <objset, 0, -1, 0>.
+ * ZIL blocks are bookmarked <objset, 0, -2, blkid == ZIL sequence number>.
+ * dmu_sync()ed ZIL data blocks are bookmarked <objset, object, -2, blkid>.
+ *
+ * Note: this structure is called a bookmark because its original purpose
+ * was to remember where to resume a pool-wide traverse.
+ *
+ * Note: this structure is passed between userland and the kernel, and is
+ * stored on disk (by virtue of being incorporated into other on-disk
+ * structures, e.g. dsl_scan_phys_t).
+ */
+struct zbookmark_phys {
+	uint64_t	zb_objset;
+	uint64_t	zb_object;
+	int64_t		zb_level;
+	uint64_t	zb_blkid;
+};
+
+#define	SET_BOOKMARK(zb, objset, object, level, blkid)  \
+{                                                       \
+	(zb)->zb_objset = objset;                       \
+	(zb)->zb_object = object;                       \
+	(zb)->zb_level = level;                         \
+	(zb)->zb_blkid = blkid;                         \
+}
+
+#define	ZB_DESTROYED_OBJSET	(-1ULL)
+
+#define	ZB_ROOT_OBJECT		(0ULL)
+#define	ZB_ROOT_LEVEL		(-1LL)
+#define	ZB_ROOT_BLKID		(0ULL)
+
+#define	ZB_ZIL_OBJECT		(0ULL)
+#define	ZB_ZIL_LEVEL		(-2LL)
+
+#define	ZB_IS_ZERO(zb)						\
+	((zb)->zb_objset == 0 && (zb)->zb_object == 0 &&	\
+	(zb)->zb_level == 0 && (zb)->zb_blkid == 0)
+#define	ZB_IS_ROOT(zb)				\
+	((zb)->zb_object == ZB_ROOT_OBJECT &&	\
+	(zb)->zb_level == ZB_ROOT_LEVEL &&	\
+	(zb)->zb_blkid == ZB_ROOT_BLKID)
+
+typedef struct zio_prop {
+	enum zio_checksum	zp_checksum;
+	enum zio_compress	zp_compress;
+	dmu_object_type_t	zp_type;
+	uint8_t			zp_level;
+	uint8_t			zp_copies;
+	boolean_t		zp_dedup;
+	boolean_t		zp_dedup_verify;
+	boolean_t		zp_nopwrite;
+} zio_prop_t;
+
+typedef struct zio_cksum_report zio_cksum_report_t;
+
+typedef void zio_cksum_finish_f(zio_cksum_report_t *rep,
+    const void *good_data);
+typedef void zio_cksum_free_f(void *cbdata, size_t size);
+
+struct zio_bad_cksum;				/* defined in zio_checksum.h */
+struct dnode_phys;
+
+struct zio_cksum_report {
+	struct zio_cksum_report *zcr_next;
+	nvlist_t		*zcr_ereport;
+	nvlist_t		*zcr_detector;
+	void			*zcr_cbdata;
+	size_t			zcr_cbinfo;	/* passed to zcr_free() */
+	uint64_t		zcr_align;
+	uint64_t		zcr_length;
+	zio_cksum_finish_f	*zcr_finish;
+	zio_cksum_free_f	*zcr_free;
+
+	/* internal use only */
+	struct zio_bad_cksum	*zcr_ckinfo;	/* information from failure */
+};
+
+typedef void zio_vsd_cksum_report_f(zio_t *zio, zio_cksum_report_t *zcr,
+    void *arg);
+
+zio_vsd_cksum_report_f	zio_vsd_default_cksum_report;
+
+typedef struct zio_vsd_ops {
+	zio_done_func_t		*vsd_free;
+	zio_vsd_cksum_report_f	*vsd_cksum_report;
+} zio_vsd_ops_t;
+
+typedef struct zio_gang_node {
+	zio_gbh_phys_t		*gn_gbh;
+	struct zio_gang_node	*gn_child[SPA_GBH_NBLKPTRS];
+} zio_gang_node_t;
+
+typedef zio_t *zio_gang_issue_func_t(zio_t *zio, blkptr_t *bp,
+    zio_gang_node_t *gn, void *data);
+
+typedef void zio_transform_func_t(zio_t *zio, void *data, uint64_t size);
+
+typedef struct zio_transform {
+	void			*zt_orig_data;
+	uint64_t		zt_orig_size;
+	uint64_t		zt_bufsize;
+	zio_transform_func_t	*zt_transform;
+	struct zio_transform	*zt_next;
+} zio_transform_t;
+
+typedef int zio_pipe_stage_t(zio_t *zio);
+
+/*
+ * The io_reexecute flags are distinct from io_flags because the child must
+ * be able to propagate them to the parent.  The normal io_flags are local
+ * to the zio, not protected by any lock, and not modifiable by children;
+ * the reexecute flags are protected by io_lock, modifiable by children,
+ * and always propagated -- even when ZIO_FLAG_DONT_PROPAGATE is set.
+ */
+#define	ZIO_REEXECUTE_NOW	0x01
+#define	ZIO_REEXECUTE_SUSPEND	0x02
+
+typedef struct zio_link {
+	zio_t		*zl_parent;
+	zio_t		*zl_child;
+	list_node_t	zl_parent_node;
+	list_node_t	zl_child_node;
+} zio_link_t;
+
+struct zio {
+	/* Core information about this I/O */
+	zbookmark_phys_t	io_bookmark;
+	zio_prop_t	io_prop;
+	zio_type_t	io_type;
+	enum zio_child	io_child_type;
+	int		io_cmd;
+	zio_priority_t	io_priority;
+	uint8_t		io_reexecute;
+	uint8_t		io_state[ZIO_WAIT_TYPES];
+	uint64_t	io_txg;
+	spa_t		*io_spa;
+	blkptr_t	*io_bp;
+	blkptr_t	*io_bp_override;
+	blkptr_t	io_bp_copy;
+	list_t		io_parent_list;
+	list_t		io_child_list;
+	zio_link_t	*io_walk_link;
+	zio_t		*io_logical;
+	zio_transform_t *io_transform_stack;
+
+	/* Callback info */
+	zio_done_func_t *io_ready;
+	zio_done_func_t	*io_physdone;
+	zio_done_func_t	*io_done;
+	void		*io_private;
+	int64_t		io_prev_space_delta;	/* DMU private */
+	blkptr_t	io_bp_orig;
+
+	/* Data represented by this I/O */
+	void		*io_data;
+	void		*io_orig_data;
+	uint64_t	io_size;
+	uint64_t	io_orig_size;
+
+	/* Stuff for the vdev stack */
+	vdev_t		*io_vd;
+	void		*io_vsd;
+	const zio_vsd_ops_t *io_vsd_ops;
+
+	uint64_t	io_offset;
+	hrtime_t	io_timestamp;	/* submitted at */
+	hrtime_t	io_delta;	/* vdev queue service delta */
+	uint64_t	io_delay;	/* vdev disk service delta (ticks) */
+	avl_node_t	io_queue_node;
+	avl_node_t	io_offset_node;
+
+	/* Internal pipeline state */
+	enum zio_flag	io_flags;
+	enum zio_stage	io_stage;
+	enum zio_stage	io_pipeline;
+	enum zio_flag	io_orig_flags;
+	enum zio_stage	io_orig_stage;
+	enum zio_stage	io_orig_pipeline;
+	int		io_error;
+	int		io_child_error[ZIO_CHILD_TYPES];
+	uint64_t	io_children[ZIO_CHILD_TYPES][ZIO_WAIT_TYPES];
+	uint64_t	io_child_count;
+	uint64_t	io_phys_children;
+	uint64_t	io_parent_count;
+	uint64_t	*io_stall;
+	zio_t		*io_gang_leader;
+	zio_gang_node_t	*io_gang_tree;
+	void		*io_executor;
+	void		*io_waiter;
+	kmutex_t	io_lock;
+	kcondvar_t	io_cv;
+
+	/* FMA state */
+	zio_cksum_report_t *io_cksum_report;
+	uint64_t	io_ena;
+
+	/* Taskq dispatching state */
+	taskq_ent_t	io_tqent;
+};
+
+extern zio_t *zio_null(zio_t *pio, spa_t *spa, vdev_t *vd,
+    zio_done_func_t *done, void *private, enum zio_flag flags);
+
+extern zio_t *zio_root(spa_t *spa,
+    zio_done_func_t *done, void *private, enum zio_flag flags);
+
+extern zio_t *zio_read(zio_t *pio, spa_t *spa, const blkptr_t *bp, void *data,
+    uint64_t size, zio_done_func_t *done, void *private,
+    zio_priority_t priority, enum zio_flag flags, const zbookmark_phys_t *zb);
+
+extern zio_t *zio_write(zio_t *pio, spa_t *spa, uint64_t txg, blkptr_t *bp,
+    void *data, uint64_t size, const zio_prop_t *zp,
+    zio_done_func_t *ready, zio_done_func_t *physdone, zio_done_func_t *done,
+    void *private,
+    zio_priority_t priority, enum zio_flag flags, const zbookmark_phys_t *zb);
+
+extern zio_t *zio_rewrite(zio_t *pio, spa_t *spa, uint64_t txg, blkptr_t *bp,
+    void *data, uint64_t size, zio_done_func_t *done, void *private,
+    zio_priority_t priority, enum zio_flag flags, zbookmark_phys_t *zb);
+
+extern void zio_write_override(zio_t *zio, blkptr_t *bp, int copies,
+    boolean_t nopwrite);
+
+extern void zio_free(spa_t *spa, uint64_t txg, const blkptr_t *bp);
+
+extern zio_t *zio_claim(zio_t *pio, spa_t *spa, uint64_t txg,
+    const blkptr_t *bp,
+    zio_done_func_t *done, void *private, enum zio_flag flags);
+
+extern zio_t *zio_ioctl(zio_t *pio, spa_t *spa, vdev_t *vd, int cmd,
+    zio_done_func_t *done, void *private, enum zio_flag flags);
+
+extern zio_t *zio_read_phys(zio_t *pio, vdev_t *vd, uint64_t offset,
+    uint64_t size, void *data, int checksum,
+    zio_done_func_t *done, void *private, zio_priority_t priority,
+    enum zio_flag flags, boolean_t labels);
+
+extern zio_t *zio_write_phys(zio_t *pio, vdev_t *vd, uint64_t offset,
+    uint64_t size, void *data, int checksum,
+    zio_done_func_t *done, void *private, zio_priority_t priority,
+    enum zio_flag flags, boolean_t labels);
+
+extern zio_t *zio_free_sync(zio_t *pio, spa_t *spa, uint64_t txg,
+    const blkptr_t *bp, enum zio_flag flags);
+
+extern int zio_alloc_zil(spa_t *spa, uint64_t txg, blkptr_t *new_bp,
+    uint64_t size, boolean_t use_slog);
+extern void zio_free_zil(spa_t *spa, uint64_t txg, blkptr_t *bp);
+extern void zio_flush(zio_t *zio, vdev_t *vd);
+extern void zio_shrink(zio_t *zio, uint64_t size);
+
+extern int zio_wait(zio_t *zio);
+extern void zio_nowait(zio_t *zio);
+extern void zio_execute(zio_t *zio);
+extern void zio_interrupt(zio_t *zio);
+
+extern zio_t *zio_walk_parents(zio_t *cio);
+extern zio_t *zio_walk_children(zio_t *pio);
+extern zio_t *zio_unique_parent(zio_t *cio);
+extern void zio_add_child(zio_t *pio, zio_t *cio);
+
+extern void *zio_buf_alloc(size_t size);
+extern void zio_buf_free(void *buf, size_t size);
+extern void *zio_data_buf_alloc(size_t size);
+extern void zio_data_buf_free(void *buf, size_t size);
+extern void *zio_buf_alloc_flags(size_t size, int flags);
+
+extern void zio_resubmit_stage_async(void *);
+
+extern zio_t *zio_vdev_child_io(zio_t *zio, blkptr_t *bp, vdev_t *vd,
+    uint64_t offset, void *data, uint64_t size, int type,
+    zio_priority_t priority, enum zio_flag flags,
+    zio_done_func_t *done, void *private);
+
+extern zio_t *zio_vdev_delegated_io(vdev_t *vd, uint64_t offset,
+    void *data, uint64_t size, int type, zio_priority_t priority,
+    enum zio_flag flags, zio_done_func_t *done, void *private);
+
+extern void zio_vdev_io_bypass(zio_t *zio);
+extern void zio_vdev_io_reissue(zio_t *zio);
+extern void zio_vdev_io_redone(zio_t *zio);
+
+extern void zio_checksum_verified(zio_t *zio);
+extern int zio_worst_error(int e1, int e2);
+
+extern enum zio_checksum zio_checksum_select(enum zio_checksum child,
+    enum zio_checksum parent);
+extern enum zio_checksum zio_checksum_dedup_select(spa_t *spa,
+    enum zio_checksum child, enum zio_checksum parent);
+extern enum zio_compress zio_compress_select(spa_t *spa,
+    enum zio_compress child, enum zio_compress parent);
+
+extern void zio_suspend(spa_t *spa, zio_t *zio);
+extern int zio_resume(spa_t *spa);
+extern void zio_resume_wait(spa_t *spa);
+
+/*
+ * Initial setup and teardown.
+ */
+extern void zio_init(void);
+extern void zio_fini(void);
+
+/*
+ * Fault injection
+ */
+struct zinject_record;
+extern uint32_t zio_injection_enabled;
+extern int zio_inject_fault(char *name, int flags, int *id,
+    struct zinject_record *record);
+extern int zio_inject_list_next(int *id, char *name, size_t buflen,
+    struct zinject_record *record);
+extern int zio_clear_fault(int id);
+extern void zio_handle_panic_injection(spa_t *spa, char *tag, uint64_t type);
+extern int zio_handle_fault_injection(zio_t *zio, int error);
+extern int zio_handle_device_injection(vdev_t *vd, zio_t *zio, int error);
+extern int zio_handle_label_injection(zio_t *zio, int error);
+extern void zio_handle_ignored_writes(zio_t *zio);
+extern uint64_t zio_handle_io_delay(zio_t *zio);
+
+/*
+ * Checksum ereport functions
+ */
+extern void zfs_ereport_start_checksum(spa_t *spa, vdev_t *vd, struct zio *zio,
+    uint64_t offset, uint64_t length, void *arg, struct zio_bad_cksum *info);
+extern void zfs_ereport_finish_checksum(zio_cksum_report_t *report,
+    const void *good_data, const void *bad_data, boolean_t drop_if_identical);
+
+extern void zfs_ereport_send_interim_checksum(zio_cksum_report_t *report);
+extern void zfs_ereport_free_checksum(zio_cksum_report_t *report);
+
+/* If we have the good data in hand, this function can be used */
+extern void zfs_ereport_post_checksum(spa_t *spa, vdev_t *vd,
+    struct zio *zio, uint64_t offset, uint64_t length,
+    const void *good_data, const void *bad_data, struct zio_bad_cksum *info);
+
+/* Called from spa_sync(), but primarily an injection handler */
+extern void spa_handle_ignored_writes(spa_t *spa);
+
+/* zbookmark_phys functions */
+boolean_t zbookmark_is_before(const struct dnode_phys *dnp,
+    const zbookmark_phys_t *zb1, const zbookmark_phys_t *zb2);
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* _ZIO_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/include/sys/zio_checksum.h
@@ -0,0 +1,75 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ */
+
+#ifndef _SYS_ZIO_CHECKSUM_H
+#define	_SYS_ZIO_CHECKSUM_H
+
+#include <sys/zio.h>
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+/*
+ * Signature for checksum functions.
+ */
+typedef void zio_checksum_t(const void *data, uint64_t size, zio_cksum_t *zcp);
+
+/*
+ * Information about each checksum function.
+ */
+typedef const struct zio_checksum_info {
+	zio_checksum_t	*ci_func[2]; /* checksum function for each byteorder */
+	int		ci_correctable;	/* number of correctable bits	*/
+	int		ci_eck;		/* uses zio embedded checksum? */
+	int		ci_dedup;	/* strong enough for dedup? */
+	char		*ci_name;	/* descriptive name */
+} zio_checksum_info_t;
+
+typedef struct zio_bad_cksum {
+	zio_cksum_t		zbc_expected;
+	zio_cksum_t		zbc_actual;
+	const char		*zbc_checksum_name;
+	uint8_t			zbc_byteswapped;
+	uint8_t			zbc_injected;
+	uint8_t			zbc_has_cksum;	/* expected/actual valid */
+} zio_bad_cksum_t;
+
+extern zio_checksum_info_t zio_checksum_table[ZIO_CHECKSUM_FUNCTIONS];
+
+/*
+ * Checksum routines.
+ */
+extern zio_checksum_t zio_checksum_SHA256;
+
+extern void zio_checksum_compute(zio_t *zio, enum zio_checksum checksum,
+    void *data, uint64_t size);
+extern int zio_checksum_error(zio_t *zio, zio_bad_cksum_t *out);
+extern enum zio_checksum spa_dedup_checksum(spa_t *spa);
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* _SYS_ZIO_CHECKSUM_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/include/sys/zio_compress.h
@@ -0,0 +1,93 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _SYS_ZIO_COMPRESS_H
+#define	_SYS_ZIO_COMPRESS_H
+
+#include <sys/zio.h>
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+/* Common signature for all zio compress functions. */
+typedef size_t zio_compress_func_t(void *src, void *dst,
+    size_t s_len, size_t d_len, int);
+/* Common signature for all zio decompress functions. */
+typedef int zio_decompress_func_t(void *src, void *dst,
+    size_t s_len, size_t d_len, int);
+
+/*
+ * Information about each compression function.
+ */
+typedef const struct zio_compress_info {
+	zio_compress_func_t	*ci_compress;	/* compression function */
+	zio_decompress_func_t	*ci_decompress;	/* decompression function */
+	int			ci_level;	/* level parameter */
+	char			*ci_name;	/* algorithm name */
+} zio_compress_info_t;
+
+extern zio_compress_info_t zio_compress_table[ZIO_COMPRESS_FUNCTIONS];
+
+/*
+ * lz4 compression init & free
+ */
+extern void lz4_init(void);
+extern void lz4_fini(void);
+
+/*
+ * Compression routines.
+ */
+extern size_t lzjb_compress(void *src, void *dst, size_t s_len, size_t d_len,
+    int level);
+extern int lzjb_decompress(void *src, void *dst, size_t s_len, size_t d_len,
+    int level);
+extern size_t gzip_compress(void *src, void *dst, size_t s_len, size_t d_len,
+    int level);
+extern int gzip_decompress(void *src, void *dst, size_t s_len, size_t d_len,
+    int level);
+extern size_t zle_compress(void *src, void *dst, size_t s_len, size_t d_len,
+    int level);
+extern int zle_decompress(void *src, void *dst, size_t s_len, size_t d_len,
+    int level);
+extern size_t lz4_compress_zfs(void *src, void *dst, size_t s_len, size_t d_len,
+    int level);
+extern int lz4_decompress_zfs(void *src, void *dst, size_t s_len, size_t d_len,
+    int level);
+
+/*
+ * Compress and decompress data if necessary.
+ */
+extern size_t zio_compress_data(enum zio_compress c, void *src, void *dst,
+    size_t s_len);
+extern int zio_decompress_data(enum zio_compress c, void *src, void *dst,
+    size_t s_len, size_t d_len);
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* _SYS_ZIO_COMPRESS_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/include/sys/zio_impl.h
@@ -0,0 +1,245 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/*
+ * Copyright (c) 2013 by Delphix. All rights reserved.
+ */
+
+#ifndef _ZIO_IMPL_H
+#define	_ZIO_IMPL_H
+
+#include <sys/zfs_context.h>
+#include <sys/zio.h>
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+/*
+ * XXX -- Describe ZFS I/O pipeline here. Fill in as needed.
+ *
+ * The ZFS I/O pipeline is comprised of various stages which are defined
+ * in the zio_stage enum below. The individual stages are used to construct
+ * these basic I/O operations: Read, Write, Free, Claim, and Ioctl.
+ *
+ * I/O operations: (XXX - provide detail for each of the operations)
+ *
+ * Read:
+ * Write:
+ * Free:
+ * Claim:
+ * Ioctl:
+ *
+ * Although the most common pipeline are used by the basic I/O operations
+ * above, there are some helper pipelines (one could consider them
+ * sub-pipelines) which are used internally by the ZIO module and are
+ * explained below:
+ *
+ * Interlock Pipeline:
+ * The interlock pipeline is the most basic pipeline and is used by all
+ * of the I/O operations. The interlock pipeline does not perform any I/O
+ * and is used to coordinate the dependencies between I/Os that are being
+ * issued (i.e. the parent/child relationship).
+ *
+ * Vdev child Pipeline:
+ * The vdev child pipeline is responsible for performing the physical I/O.
+ * It is in this pipeline where the I/O are queued and possibly cached.
+ *
+ * In addition to performing I/O, the pipeline is also responsible for
+ * data transformations. The transformations performed are based on the
+ * specific properties that user may have selected and modify the
+ * behavior of the pipeline. Examples of supported transformations are
+ * compression, dedup, and nop writes. Transformations will either modify
+ * the data or the pipeline. This list below further describes each of
+ * the supported transformations:
+ *
+ * Compression:
+ * ZFS supports three different flavors of compression -- gzip, lzjb, and
+ * zle. Compression occurs as part of the write pipeline and is performed
+ * in the ZIO_STAGE_WRITE_BP_INIT stage.
+ *
+ * Dedup:
+ * Dedup reads are handled by the ZIO_STAGE_DDT_READ_START and
+ * ZIO_STAGE_DDT_READ_DONE stages. These stages are added to an existing
+ * read pipeline if the dedup bit is set on the block pointer.
+ * Writing a dedup block is performed by the ZIO_STAGE_DDT_WRITE stage
+ * and added to a write pipeline if a user has enabled dedup on that
+ * particular dataset.
+ *
+ * NOP Write:
+ * The NOP write feature is performed by the ZIO_STAGE_NOP_WRITE stage
+ * and is added to an existing write pipeline if a crypographically
+ * secure checksum (i.e. SHA256) is enabled and compression is turned on.
+ * The NOP write stage will compare the checksums of the current data
+ * on-disk (level-0 blocks only) and the data that is currently being written.
+ * If the checksum values are identical then the pipeline is converted to
+ * an interlock pipeline skipping block allocation and bypassing the
+ * physical I/O.  The nop write feature can handle writes in either
+ * syncing or open context (i.e. zil writes) and as a result is mutually
+ * exclusive with dedup.
+ */
+
+/*
+ * zio pipeline stage definitions
+ */
+enum zio_stage {
+	ZIO_STAGE_OPEN			= 1 << 0,	/* RWFCI */
+
+	ZIO_STAGE_READ_BP_INIT		= 1 << 1,	/* R---- */
+	ZIO_STAGE_FREE_BP_INIT		= 1 << 2,	/* --F-- */
+	ZIO_STAGE_ISSUE_ASYNC		= 1 << 3,	/* RWF-- */
+	ZIO_STAGE_WRITE_BP_INIT		= 1 << 4,	/* -W--- */
+
+	ZIO_STAGE_CHECKSUM_GENERATE	= 1 << 5,	/* -W--- */
+
+	ZIO_STAGE_NOP_WRITE		= 1 << 6,	/* -W--- */
+
+	ZIO_STAGE_DDT_READ_START	= 1 << 7,	/* R---- */
+	ZIO_STAGE_DDT_READ_DONE		= 1 << 8,	/* R---- */
+	ZIO_STAGE_DDT_WRITE		= 1 << 9,	/* -W--- */
+	ZIO_STAGE_DDT_FREE		= 1 << 10,	/* --F-- */
+
+	ZIO_STAGE_GANG_ASSEMBLE		= 1 << 11,	/* RWFC- */
+	ZIO_STAGE_GANG_ISSUE		= 1 << 12,	/* RWFC- */
+
+	ZIO_STAGE_DVA_ALLOCATE		= 1 << 13,	/* -W--- */
+	ZIO_STAGE_DVA_FREE		= 1 << 14,	/* --F-- */
+	ZIO_STAGE_DVA_CLAIM		= 1 << 15,	/* ---C- */
+
+	ZIO_STAGE_READY			= 1 << 16,	/* RWFCI */
+
+	ZIO_STAGE_VDEV_IO_START		= 1 << 17,	/* RW--I */
+	ZIO_STAGE_VDEV_IO_DONE		= 1 << 18,	/* RW--I */
+	ZIO_STAGE_VDEV_IO_ASSESS	= 1 << 19,	/* RW--I */
+
+	ZIO_STAGE_CHECKSUM_VERIFY	= 1 << 20,	/* R---- */
+
+	ZIO_STAGE_DONE			= 1 << 21	/* RWFCI */
+};
+
+#define	ZIO_INTERLOCK_STAGES			\
+	(ZIO_STAGE_READY |			\
+	ZIO_STAGE_DONE)
+
+#define	ZIO_INTERLOCK_PIPELINE			\
+	ZIO_INTERLOCK_STAGES
+
+#define	ZIO_VDEV_IO_STAGES			\
+	(ZIO_STAGE_VDEV_IO_START |		\
+	ZIO_STAGE_VDEV_IO_DONE |		\
+	ZIO_STAGE_VDEV_IO_ASSESS)
+
+#define	ZIO_VDEV_CHILD_PIPELINE			\
+	(ZIO_VDEV_IO_STAGES |			\
+	ZIO_STAGE_DONE)
+
+#define	ZIO_READ_COMMON_STAGES			\
+	(ZIO_INTERLOCK_STAGES |			\
+	ZIO_VDEV_IO_STAGES |			\
+	ZIO_STAGE_CHECKSUM_VERIFY)
+
+#define	ZIO_READ_PHYS_PIPELINE			\
+	ZIO_READ_COMMON_STAGES
+
+#define	ZIO_READ_PIPELINE			\
+	(ZIO_READ_COMMON_STAGES |		\
+	ZIO_STAGE_READ_BP_INIT)
+
+#define	ZIO_DDT_CHILD_READ_PIPELINE		\
+	ZIO_READ_COMMON_STAGES
+
+#define	ZIO_DDT_READ_PIPELINE			\
+	(ZIO_INTERLOCK_STAGES |			\
+	ZIO_STAGE_READ_BP_INIT |		\
+	ZIO_STAGE_DDT_READ_START |		\
+	ZIO_STAGE_DDT_READ_DONE)
+
+#define	ZIO_WRITE_COMMON_STAGES			\
+	(ZIO_INTERLOCK_STAGES |			\
+	ZIO_VDEV_IO_STAGES |			\
+	ZIO_STAGE_ISSUE_ASYNC |			\
+	ZIO_STAGE_CHECKSUM_GENERATE)
+
+#define	ZIO_WRITE_PHYS_PIPELINE			\
+	ZIO_WRITE_COMMON_STAGES
+
+#define	ZIO_REWRITE_PIPELINE			\
+	(ZIO_WRITE_COMMON_STAGES |		\
+	ZIO_STAGE_WRITE_BP_INIT)
+
+#define	ZIO_WRITE_PIPELINE			\
+	(ZIO_WRITE_COMMON_STAGES |		\
+	ZIO_STAGE_WRITE_BP_INIT |		\
+	ZIO_STAGE_DVA_ALLOCATE)
+
+#define	ZIO_DDT_CHILD_WRITE_PIPELINE		\
+	(ZIO_INTERLOCK_STAGES |			\
+	ZIO_VDEV_IO_STAGES |			\
+	ZIO_STAGE_DVA_ALLOCATE)
+
+#define	ZIO_DDT_WRITE_PIPELINE			\
+	(ZIO_INTERLOCK_STAGES |			\
+	ZIO_STAGE_ISSUE_ASYNC |			\
+	ZIO_STAGE_WRITE_BP_INIT |		\
+	ZIO_STAGE_CHECKSUM_GENERATE |		\
+	ZIO_STAGE_DDT_WRITE)
+
+#define	ZIO_GANG_STAGES				\
+	(ZIO_STAGE_GANG_ASSEMBLE |		\
+	ZIO_STAGE_GANG_ISSUE)
+
+#define	ZIO_FREE_PIPELINE			\
+	(ZIO_INTERLOCK_STAGES |			\
+	ZIO_STAGE_FREE_BP_INIT |		\
+	ZIO_STAGE_DVA_FREE)
+
+#define	ZIO_DDT_FREE_PIPELINE			\
+	(ZIO_INTERLOCK_STAGES |			\
+	ZIO_STAGE_FREE_BP_INIT |		\
+	ZIO_STAGE_ISSUE_ASYNC |			\
+	ZIO_STAGE_DDT_FREE)
+
+#define	ZIO_CLAIM_PIPELINE			\
+	(ZIO_INTERLOCK_STAGES |			\
+	ZIO_STAGE_DVA_CLAIM)
+
+#define	ZIO_IOCTL_PIPELINE			\
+	(ZIO_INTERLOCK_STAGES |			\
+	ZIO_STAGE_VDEV_IO_START |		\
+	ZIO_STAGE_VDEV_IO_ASSESS)
+
+#define	ZIO_BLOCKING_STAGES			\
+	(ZIO_STAGE_DVA_ALLOCATE |		\
+	ZIO_STAGE_DVA_CLAIM |			\
+	ZIO_STAGE_VDEV_IO_START)
+
+extern void zio_inject_init(void);
+extern void zio_inject_fini(void);
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* _ZIO_IMPL_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/include/sys/zpl.h
@@ -0,0 +1,186 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2011, Lawrence Livermore National Security, LLC.
+ */
+
+#ifndef	_SYS_ZPL_H
+#define	_SYS_ZPL_H
+
+#include <sys/mntent.h>
+#include <sys/vfs.h>
+#include <linux/aio.h>
+#include <linux/dcache_compat.h>
+#include <linux/exportfs.h>
+#include <linux/falloc.h>
+#include <linux/file_compat.h>
+#include <linux/parser.h>
+#include <linux/task_io_accounting_ops.h>
+#include <linux/vfs_compat.h>
+#include <linux/writeback.h>
+#include <linux/xattr_compat.h>
+
+/* zpl_inode.c */
+extern void zpl_vap_init(vattr_t *vap, struct inode *dir,
+    zpl_umode_t mode, cred_t *cr);
+
+extern const struct inode_operations zpl_inode_operations;
+extern const struct inode_operations zpl_dir_inode_operations;
+extern const struct inode_operations zpl_symlink_inode_operations;
+extern const struct inode_operations zpl_special_inode_operations;
+extern dentry_operations_t zpl_dentry_operations;
+
+/* zpl_file.c */
+extern ssize_t zpl_read_common(struct inode *ip, const char *buf,
+    size_t len, loff_t *ppos, uio_seg_t segment, int flags,
+    cred_t *cr);
+extern ssize_t zpl_write_common(struct inode *ip, const char *buf,
+    size_t len, loff_t *ppos, uio_seg_t segment, int flags,
+    cred_t *cr);
+#if defined(HAVE_FILE_FALLOCATE) || defined(HAVE_INODE_FALLOCATE)
+extern long zpl_fallocate_common(struct inode *ip, int mode,
+    loff_t offset, loff_t len);
+#endif /* defined(HAVE_FILE_FALLOCATE) || defined(HAVE_INODE_FALLOCATE) */
+
+extern const struct address_space_operations zpl_address_space_operations;
+extern const struct file_operations zpl_file_operations;
+extern const struct file_operations zpl_dir_file_operations;
+
+/* zpl_super.c */
+extern void zpl_prune_sb(int64_t nr_to_scan, void *arg);
+
+extern const struct super_operations zpl_super_operations;
+extern const struct export_operations zpl_export_operations;
+extern struct file_system_type zpl_fs_type;
+
+/* zpl_xattr.c */
+extern ssize_t zpl_xattr_list(struct dentry *dentry, char *buf, size_t size);
+extern int zpl_xattr_security_init(struct inode *ip, struct inode *dip,
+    const struct qstr *qstr);
+#if defined(CONFIG_FS_POSIX_ACL)
+extern int zpl_set_acl(struct inode *ip, int type, struct posix_acl *acl);
+extern struct posix_acl *zpl_get_acl(struct inode *ip, int type);
+#if !defined(HAVE_GET_ACL)
+#if defined(HAVE_CHECK_ACL_WITH_FLAGS)
+extern int zpl_check_acl(struct inode *inode, int mask, unsigned int flags);
+#elif defined(HAVE_CHECK_ACL)
+extern int zpl_check_acl(struct inode *inode, int mask);
+#elif defined(HAVE_PERMISSION_WITH_NAMEIDATA)
+extern int zpl_permission(struct inode *ip, int mask, struct nameidata *nd);
+#elif defined(HAVE_PERMISSION)
+extern int zpl_permission(struct inode *ip, int mask);
+#endif /*  HAVE_CHECK_ACL | HAVE_PERMISSION */
+#endif /* HAVE_GET_ACL */
+
+extern int zpl_init_acl(struct inode *ip, struct inode *dir);
+extern int zpl_chmod_acl(struct inode *ip);
+#else
+static inline int
+zpl_init_acl(struct inode *ip, struct inode *dir)
+{
+	return (0);
+}
+
+static inline int
+zpl_chmod_acl(struct inode *ip)
+{
+	return (0);
+}
+#endif /* CONFIG_FS_POSIX_ACL */
+
+extern xattr_handler_t *zpl_xattr_handlers[];
+
+/* zpl_ctldir.c */
+extern const struct file_operations zpl_fops_root;
+extern const struct inode_operations zpl_ops_root;
+
+extern const struct file_operations zpl_fops_snapdir;
+extern const struct inode_operations zpl_ops_snapdir;
+#ifdef HAVE_AUTOMOUNT
+extern const struct dentry_operations zpl_dops_snapdirs;
+#else
+extern const struct inode_operations zpl_ops_snapdirs;
+#endif /* HAVE_AUTOMOUNT */
+
+extern const struct file_operations zpl_fops_shares;
+extern const struct inode_operations zpl_ops_shares;
+
+#ifdef HAVE_VFS_ITERATE
+
+#define	DIR_CONTEXT_INIT(_dirent, _actor, _pos) {	\
+	.actor = _actor,				\
+	.pos = _pos,					\
+}
+
+#else
+
+typedef struct dir_context {
+	void *dirent;
+	const filldir_t actor;
+	loff_t pos;
+} dir_context_t;
+
+#define	DIR_CONTEXT_INIT(_dirent, _actor, _pos) {	\
+	.dirent = _dirent,				\
+	.actor = _actor,				\
+	.pos = _pos,					\
+}
+
+static inline bool
+dir_emit(struct dir_context *ctx, const char *name, int namelen,
+    uint64_t ino, unsigned type)
+{
+	return (ctx->actor(ctx->dirent, name, namelen, ctx->pos, ino, type)
+		== 0);
+}
+
+static inline bool
+dir_emit_dot(struct file *file, struct dir_context *ctx)
+{
+	return (ctx->actor(ctx->dirent, ".", 1, ctx->pos,
+	    file->f_path.dentry->d_inode->i_ino, DT_DIR) == 0);
+}
+
+static inline bool
+dir_emit_dotdot(struct file *file, struct dir_context *ctx)
+{
+	return (ctx->actor(ctx->dirent, "..", 2, ctx->pos,
+	    parent_ino(file->f_path.dentry), DT_DIR) == 0);
+}
+
+static inline bool
+dir_emit_dots(struct file *file, struct dir_context *ctx)
+{
+	if (ctx->pos == 0) {
+		if (!dir_emit_dot(file, ctx))
+			return (false);
+		ctx->pos = 1;
+	}
+	if (ctx->pos == 1) {
+		if (!dir_emit_dotdot(file, ctx))
+			return (false);
+		ctx->pos = 2;
+	}
+	return (true);
+}
+#endif /* HAVE_VFS_ITERATE */
+
+#endif	/* _SYS_ZPL_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/include/sys/zrlock.h
@@ -0,0 +1,66 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ */
+
+#ifndef	_SYS_ZRLOCK_H
+#define	_SYS_ZRLOCK_H
+
+#include <sys/zfs_context.h>
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+typedef struct zrlock {
+	kmutex_t zr_mtx;
+	volatile int32_t zr_refcount;
+	kcondvar_t zr_cv;
+	uint16_t zr_pad;
+#ifdef	ZFS_DEBUG
+	kthread_t *zr_owner;
+	const char *zr_caller;
+#endif
+} zrlock_t;
+
+extern void zrl_init(zrlock_t *);
+extern void zrl_destroy(zrlock_t *);
+#ifdef	ZFS_DEBUG
+#define	zrl_add(_z)	zrl_add_debug((_z), __func__)
+extern void zrl_add_debug(zrlock_t *, const char *);
+#else
+extern void zrl_add(zrlock_t *);
+#endif
+extern void zrl_remove(zrlock_t *);
+extern int zrl_tryenter(zrlock_t *);
+extern void zrl_exit(zrlock_t *);
+extern int zrl_is_zero(zrlock_t *);
+extern int zrl_is_locked(zrlock_t *);
+#ifdef	ZFS_DEBUG
+extern kthread_t *zrl_owner(zrlock_t *);
+#endif
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif /* _SYS_ZRLOCK_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/include/sys/zvol.h
@@ -0,0 +1,53 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016 Actifio, Inc. All rights reserved.
+ */
+
+#ifndef	_SYS_ZVOL_H
+#define	_SYS_ZVOL_H
+
+#include <sys/zfs_context.h>
+
+#define	ZVOL_OBJ		1ULL
+#define	ZVOL_ZAP_OBJ		2ULL
+
+extern void zvol_create_minors(spa_t *spa, const char *name, boolean_t async);
+extern void zvol_remove_minors(spa_t *spa, const char *name, boolean_t async);
+extern void zvol_rename_minors(spa_t *spa, const char *oldname,
+    const char *newname, boolean_t async);
+
+#ifdef _KERNEL
+extern int zvol_check_volsize(uint64_t volsize, uint64_t blocksize);
+extern int zvol_check_volblocksize(const char *name, uint64_t volblocksize);
+extern int zvol_get_stats(objset_t *os, nvlist_t *nv);
+extern boolean_t zvol_is_zvol(const char *);
+extern void zvol_create_cb(objset_t *os, void *arg, cred_t *cr, dmu_tx_t *tx);
+extern int zvol_set_volsize(const char *, uint64_t);
+extern int zvol_set_volblocksize(const char *, uint64_t);
+extern int zvol_set_snapdev(const char *, zprop_source_t, uint64_t);
+
+extern int zvol_init(void);
+extern void zvol_fini(void);
+#endif /* _KERNEL */
+#endif /* _SYS_ZVOL_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/include/zfeature_common.h
@@ -0,0 +1,89 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2013 by Delphix. All rights reserved.
+ * Copyright (c) 2013 by Saso Kiselkov. All rights reserved.
+ */
+
+#ifndef _ZFEATURE_COMMON_H
+#define	_ZFEATURE_COMMON_H
+
+#include <sys/fs/zfs.h>
+#include <sys/inttypes.h>
+#include <sys/types.h>
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+struct zfeature_info;
+
+typedef enum spa_feature {
+	SPA_FEATURE_NONE = -1,
+	SPA_FEATURE_ASYNC_DESTROY,
+	SPA_FEATURE_EMPTY_BPOBJ,
+	SPA_FEATURE_LZ4_COMPRESS,
+	SPA_FEATURE_SPACEMAP_HISTOGRAM,
+	SPA_FEATURE_ENABLED_TXG,
+	SPA_FEATURE_HOLE_BIRTH,
+	SPA_FEATURE_EXTENSIBLE_DATASET,
+	SPA_FEATURE_EMBEDDED_DATA,
+	SPA_FEATURE_BOOKMARKS,
+	SPA_FEATURE_FS_SS_LIMIT,
+	SPA_FEATURE_LARGE_BLOCKS,
+	SPA_FEATURES
+} spa_feature_t;
+
+#define	SPA_FEATURE_DISABLED	(-1ULL)
+
+typedef struct zfeature_info {
+	spa_feature_t fi_feature;
+	const char *fi_uname;	/* User-facing feature name */
+	const char *fi_guid;	/* On-disk feature identifier */
+	const char *fi_desc;	/* Feature description */
+	boolean_t fi_can_readonly; /* Can open pool readonly w/o support? */
+	boolean_t fi_mos;	/* Is the feature necessary to read the MOS? */
+	/* Activate this feature at the same time it is enabled */
+	boolean_t fi_activate_on_enable;
+	/* array of dependencies, terminated by SPA_FEATURE_NONE */
+	const spa_feature_t *fi_depends;
+} zfeature_info_t;
+
+typedef int (zfeature_func_t)(zfeature_info_t *, void *);
+
+#define	ZFS_FEATURE_DEBUG
+
+extern zfeature_info_t spa_feature_table[SPA_FEATURES];
+
+extern boolean_t zfeature_is_valid_guid(const char *);
+
+extern boolean_t zfeature_is_supported(const char *);
+extern int zfeature_lookup_name(const char *, spa_feature_t *);
+extern boolean_t zfeature_depends_on(spa_feature_t, spa_feature_t);
+
+extern void zpool_feature_init(void);
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* _ZFEATURE_COMMON_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/include/zfs_comutil.h
@@ -0,0 +1,48 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012 by Delphix. All rights reserved.
+ */
+
+#ifndef	_ZFS_COMUTIL_H
+#define	_ZFS_COMUTIL_H
+
+#include <sys/fs/zfs.h>
+#include <sys/types.h>
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+extern boolean_t zfs_allocatable_devs(nvlist_t *);
+extern void zpool_get_rewind_policy(nvlist_t *, zpool_rewind_policy_t *);
+
+extern int zfs_zpl_version_map(int spa_version);
+extern int zfs_spa_version_map(int zpl_version);
+#define	ZFS_NUM_LEGACY_HISTORY_EVENTS 41
+extern const char *zfs_history_event_names[ZFS_NUM_LEGACY_HISTORY_EVENTS];
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* _ZFS_COMUTIL_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/include/zfs_deleg.h
@@ -0,0 +1,89 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2010 Nexenta Systems, Inc. All rights reserved.
+ * Copyright (c) 2013 by Delphix. All rights reserved.
+ */
+
+#ifndef	_ZFS_DELEG_H
+#define	_ZFS_DELEG_H
+
+#include <sys/fs/zfs.h>
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+#define	ZFS_DELEG_SET_NAME_CHR		'@'		/* set name lead char */
+#define	ZFS_DELEG_FIELD_SEP_CHR		'$'		/* field separator */
+
+/*
+ * Max name length for a delegation attribute
+ */
+#define	ZFS_MAX_DELEG_NAME	128
+
+#define	ZFS_DELEG_LOCAL		'l'
+#define	ZFS_DELEG_DESCENDENT	'd'
+#define	ZFS_DELEG_NA		'-'
+
+typedef enum {
+	ZFS_DELEG_NOTE_CREATE,
+	ZFS_DELEG_NOTE_DESTROY,
+	ZFS_DELEG_NOTE_SNAPSHOT,
+	ZFS_DELEG_NOTE_ROLLBACK,
+	ZFS_DELEG_NOTE_CLONE,
+	ZFS_DELEG_NOTE_PROMOTE,
+	ZFS_DELEG_NOTE_RENAME,
+	ZFS_DELEG_NOTE_SEND,
+	ZFS_DELEG_NOTE_RECEIVE,
+	ZFS_DELEG_NOTE_ALLOW,
+	ZFS_DELEG_NOTE_USERPROP,
+	ZFS_DELEG_NOTE_MOUNT,
+	ZFS_DELEG_NOTE_SHARE,
+	ZFS_DELEG_NOTE_USERQUOTA,
+	ZFS_DELEG_NOTE_GROUPQUOTA,
+	ZFS_DELEG_NOTE_USERUSED,
+	ZFS_DELEG_NOTE_GROUPUSED,
+	ZFS_DELEG_NOTE_HOLD,
+	ZFS_DELEG_NOTE_RELEASE,
+	ZFS_DELEG_NOTE_DIFF,
+	ZFS_DELEG_NOTE_BOOKMARK,
+	ZFS_DELEG_NOTE_NONE
+} zfs_deleg_note_t;
+
+typedef struct zfs_deleg_perm_tab {
+	char *z_perm;
+	zfs_deleg_note_t z_note;
+} zfs_deleg_perm_tab_t;
+
+extern zfs_deleg_perm_tab_t zfs_deleg_perm_tab[];
+
+int zfs_deleg_verify_nvlist(nvlist_t *nvlist);
+void zfs_deleg_whokey(char *attr, zfs_deleg_who_type_t type,
+    char checkflag, void *data);
+const char *zfs_deleg_canonicalize_perm(const char *perm);
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* _ZFS_DELEG_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/include/zfs_fletcher.h
@@ -0,0 +1,53 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef	_ZFS_FLETCHER_H
+#define	_ZFS_FLETCHER_H
+
+#include <sys/types.h>
+#include <sys/spa.h>
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+/*
+ * fletcher checksum functions
+ */
+
+void fletcher_2_native(const void *, uint64_t, zio_cksum_t *);
+void fletcher_2_byteswap(const void *, uint64_t, zio_cksum_t *);
+void fletcher_4_native(const void *, uint64_t, zio_cksum_t *);
+void fletcher_4_byteswap(const void *, uint64_t, zio_cksum_t *);
+void fletcher_4_incremental_native(const void *, uint64_t,
+    zio_cksum_t *);
+void fletcher_4_incremental_byteswap(const void *, uint64_t,
+    zio_cksum_t *);
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* _ZFS_FLETCHER_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/include/zfs_namecheck.h
@@ -0,0 +1,61 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * Copyright (c) 2013 by Delphix. All rights reserved.
+ */
+
+#ifndef	_ZFS_NAMECHECK_H
+#define	_ZFS_NAMECHECK_H
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+typedef enum {
+	NAME_ERR_LEADING_SLASH,		/* name begins with leading slash */
+	NAME_ERR_EMPTY_COMPONENT,	/* name contains an empty component */
+	NAME_ERR_TRAILING_SLASH,	/* name ends with a slash */
+	NAME_ERR_INVALCHAR,		/* invalid character found */
+	NAME_ERR_MULTIPLE_AT,		/* multiple '@' characters found */
+	NAME_ERR_NOLETTER,		/* pool doesn't begin with a letter */
+	NAME_ERR_RESERVED,		/* entire name is reserved */
+	NAME_ERR_DISKLIKE,		/* reserved disk name (c[0-9].*) */
+	NAME_ERR_TOOLONG,		/* name is too long */
+	NAME_ERR_NO_AT,			/* permission set is missing '@' */
+} namecheck_err_t;
+
+#define	ZFS_PERMSET_MAXLEN	64
+
+int pool_namecheck(const char *, namecheck_err_t *, char *);
+int dataset_namecheck(const char *, namecheck_err_t *, char *);
+int mountpoint_namecheck(const char *, namecheck_err_t *);
+int zfs_component_namecheck(const char *, namecheck_err_t *, char *);
+int permset_namecheck(const char *, namecheck_err_t *, char *);
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* _ZFS_NAMECHECK_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/include/zfs_prop.h
@@ -0,0 +1,129 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef	_ZFS_PROP_H
+#define	_ZFS_PROP_H
+
+#include <sys/fs/zfs.h>
+#include <sys/types.h>
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+/*
+ * For index types (e.g. compression and checksum), we want the numeric value
+ * in the kernel, but the string value in userland.
+ */
+typedef enum {
+	PROP_TYPE_NUMBER,	/* numeric value */
+	PROP_TYPE_STRING,	/* string value */
+	PROP_TYPE_INDEX		/* numeric value indexed by string */
+} zprop_type_t;
+
+typedef enum {
+	PROP_DEFAULT,
+	PROP_READONLY,
+	PROP_INHERIT,
+	/*
+	 * ONETIME properties are a sort of conglomeration of READONLY
+	 * and INHERIT.  They can be set only during object creation,
+	 * after that they are READONLY.  If not explicitly set during
+	 * creation, they can be inherited.
+	 */
+	PROP_ONETIME
+} zprop_attr_t;
+
+typedef struct zfs_index {
+	const char *pi_name;
+	uint64_t pi_value;
+} zprop_index_t;
+
+typedef struct {
+	const char *pd_name;		/* human-readable property name */
+	int pd_propnum;			/* property number */
+	zprop_type_t pd_proptype;	/* string, boolean, index, number */
+	const char *pd_strdefault;	/* default for strings */
+	uint64_t pd_numdefault;		/* for boolean / index / number */
+	zprop_attr_t pd_attr;		/* default, readonly, inherit */
+	int pd_types;			/* bitfield of valid dataset types */
+					/* fs | vol | snap; or pool */
+	const char *pd_values;		/* string telling acceptable values */
+	const char *pd_colname;		/* column header for "zfs list" */
+	boolean_t pd_rightalign;	/* column alignment for "zfs list" */
+	boolean_t pd_visible;		/* do we list this property with the */
+					/* "zfs get" help message */
+	const zprop_index_t *pd_table;	/* for index properties, a table */
+					/* defining the possible values */
+	size_t pd_table_size;		/* number of entries in pd_table[] */
+} zprop_desc_t;
+
+/*
+ * zfs dataset property functions
+ */
+void zfs_prop_init(void);
+zprop_type_t zfs_prop_get_type(zfs_prop_t);
+boolean_t zfs_prop_delegatable(zfs_prop_t prop);
+zprop_desc_t *zfs_prop_get_table(void);
+
+/*
+ * zpool property functions
+ */
+void zpool_prop_init(void);
+zprop_type_t zpool_prop_get_type(zpool_prop_t);
+zprop_desc_t *zpool_prop_get_table(void);
+
+/*
+ * Common routines to initialize property tables
+ */
+void zprop_register_impl(int, const char *, zprop_type_t, uint64_t,
+    const char *, zprop_attr_t, int, const char *, const char *,
+    boolean_t, boolean_t, const zprop_index_t *);
+void zprop_register_string(int, const char *, const char *,
+    zprop_attr_t attr, int, const char *, const char *);
+void zprop_register_number(int, const char *, uint64_t, zprop_attr_t, int,
+    const char *, const char *);
+void zprop_register_index(int, const char *, uint64_t, zprop_attr_t, int,
+    const char *, const char *, const zprop_index_t *);
+void zprop_register_hidden(int, const char *, zprop_type_t, zprop_attr_t,
+    int, const char *);
+
+/*
+ * Common routines for zfs and zpool property management
+ */
+int zprop_iter_common(zprop_func, void *, boolean_t, boolean_t, zfs_type_t);
+int zprop_name_to_prop(const char *, zfs_type_t);
+int zprop_string_to_index(int, const char *, uint64_t *, zfs_type_t);
+int zprop_index_to_string(int, uint64_t, const char **, zfs_type_t);
+uint64_t zprop_random_value(int, uint64_t, zfs_type_t);
+const char *zprop_values(int, zfs_type_t);
+size_t zprop_width(int, boolean_t *, zfs_type_t);
+boolean_t zprop_valid_for_type(int, zfs_type_t, boolean_t);
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* _ZFS_PROP_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/include/zpios-ctl.h
@@ -0,0 +1,203 @@
+/*
+ *  ZPIOS is a heavily modified version of the original PIOS test code.
+ *  It is designed to have the test code running in the Linux kernel
+ *  against ZFS while still being flexibly controled from user space.
+ *
+ *  Copyright (C) 2008-2010 Lawrence Livermore National Security, LLC.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  LLNL-CODE-403049
+ *
+ *  Original PIOS Test Code
+ *  Copyright (C) 2004 Cluster File Systems, Inc.
+ *  Written by Peter Braam <braam@clusterfs.com>
+ *             Atul Vidwansa <atul@clusterfs.com>
+ *             Milind Dumbare <milind@clusterfs.com>
+ *
+ *  This file is part of ZFS on Linux.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  ZPIOS is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  ZPIOS is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with ZPIOS.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _ZPIOS_CTL_H
+#define	_ZPIOS_CTL_H
+
+/*
+ * Contains shared definitions which both the userspace
+ * and kernelspace portions of zpios must agree on.
+ */
+#ifndef _KERNEL
+#include <stdint.h>
+#endif
+
+#define	ZPIOS_NAME			"zpios"
+#define	ZPIOS_DEV			"/dev/zpios"
+
+#define	DMU_IO				0x01
+
+#define	DMU_WRITE			0x0001
+#define	DMU_READ			0x0002
+#define	DMU_VERIFY			0x0004
+#define	DMU_REMOVE			0x0008
+#define	DMU_FPP				0x0010
+#define	DMU_WRITE_ZC			0x0020 /* Incompatible w/DMU_VERIFY */
+#define	DMU_READ_ZC			0x0040 /* Incompatible w/DMU_VERIFY */
+#define	DMU_WRITE_NOWAIT		0x0080
+#define	DMU_READ_NOPF			0x0100
+
+#define	ZPIOS_NAME_SIZE			16
+#define	ZPIOS_PATH_SIZE			128
+
+#define	PHASE_PRE_RUN			"pre-run"
+#define	PHASE_PRE_CREATE		"pre-create"
+#define	PHASE_PRE_WRITE			"pre-write"
+#define	PHASE_PRE_READ			"pre-read"
+#define	PHASE_PRE_REMOVE		"pre-remove"
+#define	PHASE_POST_RUN			"post-run"
+#define	PHASE_POST_CREATE		"post-create"
+#define	PHASE_POST_WRITE		"post-write"
+#define	PHASE_POST_READ			"post-read"
+#define	PHASE_POST_REMOVE		"post-remove"
+
+#define	ZPIOS_CFG_MAGIC			0x87237190U
+typedef struct zpios_cfg {
+	uint32_t cfg_magic;		/* Unique magic */
+	int32_t cfg_cmd;		/* Config command */
+	int32_t cfg_arg1;		/* Config command arg 1 */
+	int32_t cfg_rc1;		/* Config response 1 */
+} zpios_cfg_t;
+
+typedef struct zpios_timespec {
+	uint32_t ts_sec;
+	uint32_t ts_nsec;
+} zpios_timespec_t;
+
+typedef struct zpios_time {
+	zpios_timespec_t start;
+	zpios_timespec_t stop;
+	zpios_timespec_t delta;
+} zpios_time_t;
+
+typedef struct zpios_stats {
+	zpios_time_t total_time;
+	zpios_time_t cr_time;
+	zpios_time_t rm_time;
+	zpios_time_t wr_time;
+	zpios_time_t rd_time;
+	uint64_t wr_data;
+	uint64_t wr_chunks;
+	uint64_t rd_data;
+	uint64_t rd_chunks;
+} zpios_stats_t;
+
+#define	ZPIOS_CMD_MAGIC			0x49715385U
+typedef struct zpios_cmd {
+	uint32_t cmd_magic;		/* Unique magic */
+	uint32_t cmd_id;		/* Run ID */
+	char cmd_pool[ZPIOS_NAME_SIZE];	/* Pool name */
+	uint64_t cmd_chunk_size;	/* Chunk size */
+	uint32_t cmd_thread_count;	/* Thread count */
+	uint32_t cmd_region_count;	/* Region count */
+	uint64_t cmd_region_size;	/* Region size */
+	uint64_t cmd_offset;		/* Region offset */
+	uint32_t cmd_region_noise;	/* Region noise */
+	uint32_t cmd_chunk_noise;	/* Chunk noise */
+	uint32_t cmd_thread_delay;	/* Thread delay */
+	uint32_t cmd_flags;		/* Test flags */
+	char cmd_pre[ZPIOS_PATH_SIZE];	/* Pre-exec hook */
+	char cmd_post[ZPIOS_PATH_SIZE];	/* Post-exec hook */
+	char cmd_log[ZPIOS_PATH_SIZE];  /* Requested log dir */
+	uint64_t cmd_data_size;		/* Opaque data size */
+	char cmd_data_str[0];		/* Opaque data region */
+} zpios_cmd_t;
+
+/* Valid ioctls */
+#define	ZPIOS_CFG			_IOWR('f', 101, zpios_cfg_t)
+#define	ZPIOS_CMD			_IOWR('f', 102, zpios_cmd_t)
+
+/* Valid configuration commands */
+#define	ZPIOS_CFG_BUFFER_CLEAR		0x001	/* Clear text buffer */
+#define	ZPIOS_CFG_BUFFER_SIZE		0x002	/* Resize text buffer */
+
+#ifndef NSEC_PER_SEC
+#define	NSEC_PER_SEC    1000000000L
+#endif
+
+static inline
+void
+zpios_timespec_normalize(zpios_timespec_t *ts, uint32_t sec, uint32_t nsec)
+{
+	while (nsec >= NSEC_PER_SEC) {
+		nsec -= NSEC_PER_SEC;
+		sec++;
+	}
+	while (nsec < 0) {
+		nsec += NSEC_PER_SEC;
+		sec--;
+	}
+	ts->ts_sec = sec;
+	ts->ts_nsec = nsec;
+}
+
+static inline
+zpios_timespec_t
+zpios_timespec_add(zpios_timespec_t lhs, zpios_timespec_t rhs)
+{
+	zpios_timespec_t ts_delta;
+	zpios_timespec_normalize(&ts_delta, lhs.ts_sec + rhs.ts_sec,
+	    lhs.ts_nsec + rhs.ts_nsec);
+	return (ts_delta);
+}
+
+static inline
+zpios_timespec_t
+zpios_timespec_sub(zpios_timespec_t lhs, zpios_timespec_t rhs)
+{
+	zpios_timespec_t ts_delta;
+	zpios_timespec_normalize(&ts_delta, lhs.ts_sec - rhs.ts_sec,
+	    lhs.ts_nsec - rhs.ts_nsec);
+	return (ts_delta);
+}
+
+#ifdef _KERNEL
+
+static inline
+zpios_timespec_t
+zpios_timespec_now(void)
+{
+	zpios_timespec_t zts_now;
+	struct timespec ts_now;
+
+	ts_now = current_kernel_time();
+	zts_now.ts_sec  = ts_now.tv_sec;
+	zts_now.ts_nsec = ts_now.tv_nsec;
+
+	return (zts_now);
+}
+
+#else
+
+static inline
+double
+zpios_timespec_to_double(zpios_timespec_t ts)
+{
+	return
+	    ((double)(ts.ts_sec) +
+	    ((double)(ts.ts_nsec) / (double)(NSEC_PER_SEC)));
+}
+
+#endif /* _KERNEL */
+
+#endif /* _ZPIOS_CTL_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/include/zpios-internal.h
@@ -0,0 +1,112 @@
+/*
+ *  ZPIOS is a heavily modified version of the original PIOS test code.
+ *  It is designed to have the test code running in the Linux kernel
+ *  against ZFS while still being flexibly controled from user space.
+ *
+ *  Copyright (C) 2008-2010 Lawrence Livermore National Security, LLC.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  LLNL-CODE-403049
+ *
+ *  Original PIOS Test Code
+ *  Copyright (C) 2004 Cluster File Systems, Inc.
+ *  Written by Peter Braam <braam@clusterfs.com>
+ *             Atul Vidwansa <atul@clusterfs.com>
+ *             Milind Dumbare <milind@clusterfs.com>
+ *
+ *  This file is part of ZFS on Linux.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  ZPIOS is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  ZPIOS is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with ZPIOS.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _ZPIOS_INTERNAL_H
+#define	_ZPIOS_INTERNAL_H
+
+#include "zpios-ctl.h"
+
+#define	OBJ_SIZE	64
+
+struct run_args;
+
+typedef struct dmu_obj {
+	objset_t *os;
+	uint64_t obj;
+} dmu_obj_t;
+
+/* thread doing the IO data */
+typedef struct thread_data {
+	struct run_args *run_args;
+	int thread_no;
+	int rc;
+	zpios_stats_t stats;
+	kmutex_t lock;
+} thread_data_t;
+
+/* region for IO data */
+typedef struct zpios_region {
+	__u64 wr_offset;
+	__u64 rd_offset;
+	__u64 init_offset;
+	__u64 max_offset;
+	dmu_obj_t obj;
+	zpios_stats_t stats;
+	kmutex_t lock;
+} zpios_region_t;
+
+/* arguments for one run */
+typedef struct run_args {
+	/* Config args */
+	int id;
+	char pool[ZPIOS_NAME_SIZE];
+	__u64 chunk_size;
+	__u32 thread_count;
+	__u32 region_count;
+	__u64 region_size;
+	__u64 offset;
+	__u32 region_noise;
+	__u32 chunk_noise;
+	__u32 thread_delay;
+	__u32 flags;
+	char pre[ZPIOS_PATH_SIZE];
+	char post[ZPIOS_PATH_SIZE];
+	char log[ZPIOS_PATH_SIZE];
+
+	/* Control data */
+	objset_t *os;
+	wait_queue_head_t waitq;
+	volatile uint64_t threads_done;
+	kmutex_t lock_work;
+	kmutex_t lock_ctl;
+	__u32 region_next;
+
+	/* Results data */
+	struct file *file;
+	zpios_stats_t stats;
+
+	thread_data_t **threads;
+	zpios_region_t regions[0]; /* Must be last element */
+} run_args_t;
+
+#define	ZPIOS_INFO_BUFFER_SIZE		65536
+#define	ZPIOS_INFO_BUFFER_REDZONE	1024
+
+typedef struct zpios_info {
+	spinlock_t info_lock;
+	int info_size;
+	char *info_buffer;
+	char *info_head;	/* Internal kernel use only */
+} zpios_info_t;
+
+#endif /* _ZPIOS_INTERNAL_H */
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/lib/Makefile.in
@@ -0,0 +1,2 @@
+%:
+	#
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/lib/libavl/Makefile.in
@@ -0,0 +1,2 @@
+%:
+	#
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/lib/libefi/Makefile.in
@@ -0,0 +1,2 @@
+%:
+	#
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/lib/libnvpair/Makefile.in
@@ -0,0 +1,2 @@
+%:
+	#
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/lib/libshare/Makefile.in
@@ -0,0 +1,2 @@
+%:
+	#
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/lib/libspl/Makefile.in
@@ -0,0 +1,2 @@
+%:
+	#
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/lib/libspl/asm-generic/Makefile.in
@@ -0,0 +1,2 @@
+%:
+	#
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/lib/libspl/asm-i386/Makefile.in
@@ -0,0 +1,2 @@
+%:
+	#
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/lib/libspl/asm-x86_64/Makefile.in
@@ -0,0 +1,2 @@
+%:
+	#
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/lib/libspl/include/Makefile.in
@@ -0,0 +1,2 @@
+%:
+	#
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/lib/libspl/include/ia32/Makefile.in
@@ -0,0 +1,2 @@
+%:
+	#
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/lib/libspl/include/ia32/sys/Makefile.in
@@ -0,0 +1,2 @@
+%:
+	#
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/lib/libspl/include/rpc/Makefile.in
@@ -0,0 +1,2 @@
+%:
+	#
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/lib/libspl/include/sys/Makefile.in
@@ -0,0 +1,2 @@
+%:
+	#
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/lib/libspl/include/sys/dktp/Makefile.in
@@ -0,0 +1,2 @@
+%:
+	#
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/lib/libspl/include/sys/sysevent/Makefile.in
@@ -0,0 +1,2 @@
+%:
+	#
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/lib/libspl/include/util/Makefile.in
@@ -0,0 +1,2 @@
+%:
+	#
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/lib/libunicode/Makefile.in
@@ -0,0 +1,2 @@
+%:
+	#
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/lib/libuutil/Makefile.in
@@ -0,0 +1,2 @@
+%:
+	#
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/lib/libzfs/Makefile.in
@@ -0,0 +1,2 @@
+%:
+	#
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/lib/libzfs/libzfs.pc.in
@@ -0,0 +1,2 @@
+%:
+	#
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/lib/libzfs/libzfs_core.pc.in
@@ -0,0 +1,2 @@
+%:
+	#
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/lib/libzfs_core/Makefile.in
@@ -0,0 +1,2 @@
+%:
+	#
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/lib/libzpool/Makefile.in
@@ -0,0 +1,2 @@
+%:
+	#
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/man/Makefile.in
@@ -0,0 +1,2 @@
+%:
+	#
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/man/man1/Makefile.in
@@ -0,0 +1,2 @@
+%:
+	#
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/man/man5/Makefile.in
@@ -0,0 +1,2 @@
+%:
+	#
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/man/man8/Makefile.in
@@ -0,0 +1,2 @@
+%:
+	#
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/man/man8/zed.8.in
@@ -0,0 +1,2 @@
+%:
+	#
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/module/Makefile.in
@@ -0,0 +1,75 @@
+subdir-m += avl
+subdir-m += nvpair
+subdir-m += unicode
+subdir-m += zcommon
+subdir-m += zfs
+subdir-m += zpios
+
+INSTALL_MOD_DIR ?= extra
+
+ZFS_MODULE_CFLAGS += -include @SPL_OBJ@/spl_config.h
+ZFS_MODULE_CFLAGS += -include @abs_top_builddir@/zfs_config.h
+ZFS_MODULE_CFLAGS += -I@abs_top_srcdir@/include -I@SPL@/include -I@SPL@
+export ZFS_MODULE_CFLAGS
+
+modules:
+	@# Make the exported SPL symbols available to these modules.
+	@# They may be in the root of SPL_OBJ when building against
+	@# installed devel headers, or they may be in the module
+	@# subdirectory when building against the spl source tree.
+	@if [ -f @SPL_OBJ@/@SPL_SYMBOLS@ ]; then \
+		/bin/cp @SPL_OBJ@/@SPL_SYMBOLS@ .; \
+	elif [ -f @SPL_OBJ@/module/@SPL_SYMBOLS@ ]; then \
+		/bin/cp @SPL_OBJ@/module/@SPL_SYMBOLS@ .; \
+	else \
+		echo -e "\n" \
+		"*** Missing spl symbols ensure you have built the spl:\n" \
+		"*** - @SPL_OBJ@/@SPL_SYMBOLS@, or\n" \
+		"*** - @SPL_OBJ@/module/@SPL_SYMBOLS@\n"; \
+		exit 1; \
+	fi
+	$(MAKE) -C @LINUX_OBJ@ SUBDIRS=`pwd` @KERNELMAKE_PARAMS@ CONFIG_ZFS=m $@
+
+clean:
+	@# Only cleanup the kernel build directories when CONFIG_KERNEL
+	@# is defined.  This indicates that kernel modules should be built.
+@CONFIG_KERNEL_TRUE@	$(MAKE) -C @LINUX_OBJ@ SUBDIRS=`pwd` @KERNELMAKE_PARAMS@ $@
+
+	if [ -f @SPL_SYMBOLS@ ]; then $(RM) @SPL_SYMBOLS@; fi
+	if [ -f @LINUX_SYMBOLS@ ]; then $(RM) @LINUX_SYMBOLS@; fi
+	if [ -f Module.markers ]; then $(RM) Module.markers; fi
+
+modules_install:
+	@# Install the kernel modules
+	$(MAKE) -C @LINUX_OBJ@ SUBDIRS=`pwd` $@ \
+		INSTALL_MOD_PATH=$(DESTDIR)$(INSTALL_MOD_PATH) \
+		INSTALL_MOD_DIR=$(INSTALL_MOD_DIR) \
+		KERNELRELEASE=@LINUX_VERSION@
+	@# Remove extraneous build products when packaging
+	kmoddir=$(DESTDIR)$(INSTALL_MOD_PATH)/lib/modules/@LINUX_VERSION@; \
+	if [ -n "$(DESTDIR)" ]; then \
+		find $$kmoddir -name 'modules.*' | xargs $(RM); \
+	fi
+	sysmap=$(DESTDIR)$(INSTALL_MOD_PATH)/boot/System.map-@LINUX_VERSION@; \
+	if [ -f $$sysmap ]; then \
+		depmod -ae -F $$sysmap @LINUX_VERSION@; \
+	fi
+
+modules_uninstall:
+	@# Uninstall the kernel modules
+	kmoddir=$(DESTDIR)$(INSTALL_MOD_PATH)/lib/modules/@LINUX_VERSION@
+	list='$(subdir-m)'; for subdir in $$list; do \
+		$(RM) -R $$kmoddir/$(INSTALL_MOD_DIR)/$$subdir; \
+	done
+
+distdir:
+	list='$(subdir-m)'; for subdir in $$list; do \
+		(find @top_srcdir@/module/$$subdir -name '*.c' -o -name '*.h' |\
+		xargs /bin/cp -t $$distdir/$$subdir); \
+	done
+
+distclean maintainer-clean: clean
+install: modules_install
+uninstall: modules_uninstall
+all: modules
+check:
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/module/avl/Makefile.in
@@ -0,0 +1,10 @@
+src = @abs_top_srcdir@/module/avl
+obj = @abs_builddir@
+
+MODULE := zavl
+
+EXTRA_CFLAGS = $(ZFS_MODULE_CFLAGS) @KERNELCPPFLAGS@
+
+obj-$(CONFIG_ZFS) := $(MODULE).o
+
+$(MODULE)-objs += avl.o
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/module/avl/avl.c
@@ -0,0 +1,1096 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/*
+ * Copyright (c) 2014 by Delphix. All rights reserved.
+ */
+
+/*
+ * AVL - generic AVL tree implementation for kernel use
+ *
+ * A complete description of AVL trees can be found in many CS textbooks.
+ *
+ * Here is a very brief overview. An AVL tree is a binary search tree that is
+ * almost perfectly balanced. By "almost" perfectly balanced, we mean that at
+ * any given node, the left and right subtrees are allowed to differ in height
+ * by at most 1 level.
+ *
+ * This relaxation from a perfectly balanced binary tree allows doing
+ * insertion and deletion relatively efficiently. Searching the tree is
+ * still a fast operation, roughly O(log(N)).
+ *
+ * The key to insertion and deletion is a set of tree manipulations called
+ * rotations, which bring unbalanced subtrees back into the semi-balanced state.
+ *
+ * This implementation of AVL trees has the following peculiarities:
+ *
+ *	- The AVL specific data structures are physically embedded as fields
+ *	  in the "using" data structures.  To maintain generality the code
+ *	  must constantly translate between "avl_node_t *" and containing
+ *	  data structure "void *"s by adding/subtracting the avl_offset.
+ *
+ *	- Since the AVL data is always embedded in other structures, there is
+ *	  no locking or memory allocation in the AVL routines. This must be
+ *	  provided for by the enclosing data structure's semantics. Typically,
+ *	  avl_insert()/_add()/_remove()/avl_insert_here() require some kind of
+ *	  exclusive write lock. Other operations require a read lock.
+ *
+ *      - The implementation uses iteration instead of explicit recursion,
+ *	  since it is intended to run on limited size kernel stacks. Since
+ *	  there is no recursion stack present to move "up" in the tree,
+ *	  there is an explicit "parent" link in the avl_node_t.
+ *
+ *      - The left/right children pointers of a node are in an array.
+ *	  In the code, variables (instead of constants) are used to represent
+ *	  left and right indices.  The implementation is written as if it only
+ *	  dealt with left handed manipulations.  By changing the value assigned
+ *	  to "left", the code also works for right handed trees.  The
+ *	  following variables/terms are frequently used:
+ *
+ *		int left;	// 0 when dealing with left children,
+ *				// 1 for dealing with right children
+ *
+ *		int left_heavy;	// -1 when left subtree is taller at some node,
+ *				// +1 when right subtree is taller
+ *
+ *		int right;	// will be the opposite of left (0 or 1)
+ *		int right_heavy;// will be the opposite of left_heavy (-1 or 1)
+ *
+ *		int direction;  // 0 for "<" (ie. left child); 1 for ">" (right)
+ *
+ *	  Though it is a little more confusing to read the code, the approach
+ *	  allows using half as much code (and hence cache footprint) for tree
+ *	  manipulations and eliminates many conditional branches.
+ *
+ *	- The avl_index_t is an opaque "cookie" used to find nodes at or
+ *	  adjacent to where a new value would be inserted in the tree. The value
+ *	  is a modified "avl_node_t *".  The bottom bit (normally 0 for a
+ *	  pointer) is set to indicate if that the new node has a value greater
+ *	  than the value of the indicated "avl_node_t *".
+ *
+ * Note - in addition to userland (e.g. libavl and libutil) and the kernel
+ * (e.g. genunix), avl.c is compiled into ld.so and kmdb's genunix module,
+ * which each have their own compilation environments and subsequent
+ * requirements. Each of these environments must be considered when adding
+ * dependencies from avl.c.
+ */
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/debug.h>
+#include <sys/avl.h>
+#include <sys/cmn_err.h>
+
+/*
+ * Small arrays to translate between balance (or diff) values and child indices.
+ *
+ * Code that deals with binary tree data structures will randomly use
+ * left and right children when examining a tree.  C "if()" statements
+ * which evaluate randomly suffer from very poor hardware branch prediction.
+ * In this code we avoid some of the branch mispredictions by using the
+ * following translation arrays. They replace random branches with an
+ * additional memory reference. Since the translation arrays are both very
+ * small the data should remain efficiently in cache.
+ */
+static const int  avl_child2balance[2]	= {-1, 1};
+static const int  avl_balance2child[]	= {0, 0, 1};
+
+
+/*
+ * Walk from one node to the previous valued node (ie. an infix walk
+ * towards the left). At any given node we do one of 2 things:
+ *
+ * - If there is a left child, go to it, then to it's rightmost descendant.
+ *
+ * - otherwise we return through parent nodes until we've come from a right
+ *   child.
+ *
+ * Return Value:
+ * NULL - if at the end of the nodes
+ * otherwise next node
+ */
+void *
+avl_walk(avl_tree_t *tree, void	*oldnode, int left)
+{
+	size_t off = tree->avl_offset;
+	avl_node_t *node = AVL_DATA2NODE(oldnode, off);
+	int right = 1 - left;
+	int was_child;
+
+
+	/*
+	 * nowhere to walk to if tree is empty
+	 */
+	if (node == NULL)
+		return (NULL);
+
+	/*
+	 * Visit the previous valued node. There are two possibilities:
+	 *
+	 * If this node has a left child, go down one left, then all
+	 * the way right.
+	 */
+	if (node->avl_child[left] != NULL) {
+		for (node = node->avl_child[left];
+		    node->avl_child[right] != NULL;
+		    node = node->avl_child[right])
+			;
+	/*
+	 * Otherwise, return thru left children as far as we can.
+	 */
+	} else {
+		for (;;) {
+			was_child = AVL_XCHILD(node);
+			node = AVL_XPARENT(node);
+			if (node == NULL)
+				return (NULL);
+			if (was_child == right)
+				break;
+		}
+	}
+
+	return (AVL_NODE2DATA(node, off));
+}
+
+/*
+ * Return the lowest valued node in a tree or NULL.
+ * (leftmost child from root of tree)
+ */
+void *
+avl_first(avl_tree_t *tree)
+{
+	avl_node_t *node;
+	avl_node_t *prev = NULL;
+	size_t off = tree->avl_offset;
+
+	for (node = tree->avl_root; node != NULL; node = node->avl_child[0])
+		prev = node;
+
+	if (prev != NULL)
+		return (AVL_NODE2DATA(prev, off));
+	return (NULL);
+}
+
+/*
+ * Return the highest valued node in a tree or NULL.
+ * (rightmost child from root of tree)
+ */
+void *
+avl_last(avl_tree_t *tree)
+{
+	avl_node_t *node;
+	avl_node_t *prev = NULL;
+	size_t off = tree->avl_offset;
+
+	for (node = tree->avl_root; node != NULL; node = node->avl_child[1])
+		prev = node;
+
+	if (prev != NULL)
+		return (AVL_NODE2DATA(prev, off));
+	return (NULL);
+}
+
+/*
+ * Access the node immediately before or after an insertion point.
+ *
+ * "avl_index_t" is a (avl_node_t *) with the bottom bit indicating a child
+ *
+ * Return value:
+ *	NULL: no node in the given direction
+ *	"void *"  of the found tree node
+ */
+void *
+avl_nearest(avl_tree_t *tree, avl_index_t where, int direction)
+{
+	int child = AVL_INDEX2CHILD(where);
+	avl_node_t *node = AVL_INDEX2NODE(where);
+	void *data;
+	size_t off = tree->avl_offset;
+
+	if (node == NULL) {
+		ASSERT(tree->avl_root == NULL);
+		return (NULL);
+	}
+	data = AVL_NODE2DATA(node, off);
+	if (child != direction)
+		return (data);
+
+	return (avl_walk(tree, data, direction));
+}
+
+
+/*
+ * Search for the node which contains "value".  The algorithm is a
+ * simple binary tree search.
+ *
+ * return value:
+ *	NULL: the value is not in the AVL tree
+ *		*where (if not NULL)  is set to indicate the insertion point
+ *	"void *"  of the found tree node
+ */
+void *
+avl_find(avl_tree_t *tree, const void *value, avl_index_t *where)
+{
+	avl_node_t *node;
+	avl_node_t *prev = NULL;
+	int child = 0;
+	int diff;
+	size_t off = tree->avl_offset;
+
+	for (node = tree->avl_root; node != NULL;
+	    node = node->avl_child[child]) {
+
+		prev = node;
+
+		diff = tree->avl_compar(value, AVL_NODE2DATA(node, off));
+		ASSERT(-1 <= diff && diff <= 1);
+		if (diff == 0) {
+#ifdef DEBUG
+			if (where != NULL)
+				*where = 0;
+#endif
+			return (AVL_NODE2DATA(node, off));
+		}
+		child = avl_balance2child[1 + diff];
+
+	}
+
+	if (where != NULL)
+		*where = AVL_MKINDEX(prev, child);
+
+	return (NULL);
+}
+
+
+/*
+ * Perform a rotation to restore balance at the subtree given by depth.
+ *
+ * This routine is used by both insertion and deletion. The return value
+ * indicates:
+ *	 0 : subtree did not change height
+ *	!0 : subtree was reduced in height
+ *
+ * The code is written as if handling left rotations, right rotations are
+ * symmetric and handled by swapping values of variables right/left[_heavy]
+ *
+ * On input balance is the "new" balance at "node". This value is either
+ * -2 or +2.
+ */
+static int
+avl_rotation(avl_tree_t *tree, avl_node_t *node, int balance)
+{
+	int left = !(balance < 0);	/* when balance = -2, left will be 0 */
+	int right = 1 - left;
+	int left_heavy = balance >> 1;
+	int right_heavy = -left_heavy;
+	avl_node_t *parent = AVL_XPARENT(node);
+	avl_node_t *child = node->avl_child[left];
+	avl_node_t *cright;
+	avl_node_t *gchild;
+	avl_node_t *gright;
+	avl_node_t *gleft;
+	int which_child = AVL_XCHILD(node);
+	int child_bal = AVL_XBALANCE(child);
+
+	/* BEGIN CSTYLED */
+	/*
+	 * case 1 : node is overly left heavy, the left child is balanced or
+	 * also left heavy. This requires the following rotation.
+	 *
+	 *                   (node bal:-2)
+	 *                    /           \
+	 *                   /             \
+	 *              (child bal:0 or -1)
+	 *              /    \
+	 *             /      \
+	 *                     cright
+	 *
+	 * becomes:
+	 *
+	 *              (child bal:1 or 0)
+	 *              /        \
+	 *             /          \
+	 *                        (node bal:-1 or 0)
+	 *                         /     \
+	 *                        /       \
+	 *                     cright
+	 *
+	 * we detect this situation by noting that child's balance is not
+	 * right_heavy.
+	 */
+	/* END CSTYLED */
+	if (child_bal != right_heavy) {
+
+		/*
+		 * compute new balance of nodes
+		 *
+		 * If child used to be left heavy (now balanced) we reduced
+		 * the height of this sub-tree -- used in "return...;" below
+		 */
+		child_bal += right_heavy; /* adjust towards right */
+
+		/*
+		 * move "cright" to be node's left child
+		 */
+		cright = child->avl_child[right];
+		node->avl_child[left] = cright;
+		if (cright != NULL) {
+			AVL_SETPARENT(cright, node);
+			AVL_SETCHILD(cright, left);
+		}
+
+		/*
+		 * move node to be child's right child
+		 */
+		child->avl_child[right] = node;
+		AVL_SETBALANCE(node, -child_bal);
+		AVL_SETCHILD(node, right);
+		AVL_SETPARENT(node, child);
+
+		/*
+		 * update the pointer into this subtree
+		 */
+		AVL_SETBALANCE(child, child_bal);
+		AVL_SETCHILD(child, which_child);
+		AVL_SETPARENT(child, parent);
+		if (parent != NULL)
+			parent->avl_child[which_child] = child;
+		else
+			tree->avl_root = child;
+
+		return (child_bal == 0);
+	}
+
+	/* BEGIN CSTYLED */
+	/*
+	 * case 2 : When node is left heavy, but child is right heavy we use
+	 * a different rotation.
+	 *
+	 *                   (node b:-2)
+	 *                    /   \
+	 *                   /     \
+	 *                  /       \
+	 *             (child b:+1)
+	 *              /     \
+	 *             /       \
+	 *                   (gchild b: != 0)
+	 *                     /  \
+	 *                    /    \
+	 *                 gleft   gright
+	 *
+	 * becomes:
+	 *
+	 *              (gchild b:0)
+	 *              /       \
+	 *             /         \
+	 *            /           \
+	 *        (child b:?)   (node b:?)
+	 *         /  \          /   \
+	 *        /    \        /     \
+	 *            gleft   gright
+	 *
+	 * computing the new balances is more complicated. As an example:
+	 *	 if gchild was right_heavy, then child is now left heavy
+	 *		else it is balanced
+	 */
+	/* END CSTYLED */
+	gchild = child->avl_child[right];
+	gleft = gchild->avl_child[left];
+	gright = gchild->avl_child[right];
+
+	/*
+	 * move gright to left child of node and
+	 *
+	 * move gleft to right child of node
+	 */
+	node->avl_child[left] = gright;
+	if (gright != NULL) {
+		AVL_SETPARENT(gright, node);
+		AVL_SETCHILD(gright, left);
+	}
+
+	child->avl_child[right] = gleft;
+	if (gleft != NULL) {
+		AVL_SETPARENT(gleft, child);
+		AVL_SETCHILD(gleft, right);
+	}
+
+	/*
+	 * move child to left child of gchild and
+	 *
+	 * move node to right child of gchild and
+	 *
+	 * fixup parent of all this to point to gchild
+	 */
+	balance = AVL_XBALANCE(gchild);
+	gchild->avl_child[left] = child;
+	AVL_SETBALANCE(child, (balance == right_heavy ? left_heavy : 0));
+	AVL_SETPARENT(child, gchild);
+	AVL_SETCHILD(child, left);
+
+	gchild->avl_child[right] = node;
+	AVL_SETBALANCE(node, (balance == left_heavy ? right_heavy : 0));
+	AVL_SETPARENT(node, gchild);
+	AVL_SETCHILD(node, right);
+
+	AVL_SETBALANCE(gchild, 0);
+	AVL_SETPARENT(gchild, parent);
+	AVL_SETCHILD(gchild, which_child);
+	if (parent != NULL)
+		parent->avl_child[which_child] = gchild;
+	else
+		tree->avl_root = gchild;
+
+	return (1);	/* the new tree is always shorter */
+}
+
+
+/*
+ * Insert a new node into an AVL tree at the specified (from avl_find()) place.
+ *
+ * Newly inserted nodes are always leaf nodes in the tree, since avl_find()
+ * searches out to the leaf positions.  The avl_index_t indicates the node
+ * which will be the parent of the new node.
+ *
+ * After the node is inserted, a single rotation further up the tree may
+ * be necessary to maintain an acceptable AVL balance.
+ */
+void
+avl_insert(avl_tree_t *tree, void *new_data, avl_index_t where)
+{
+	avl_node_t *node;
+	avl_node_t *parent = AVL_INDEX2NODE(where);
+	int old_balance;
+	int new_balance;
+	int which_child = AVL_INDEX2CHILD(where);
+	size_t off = tree->avl_offset;
+
+	ASSERT(tree);
+#ifdef _LP64
+	ASSERT(((uintptr_t)new_data & 0x7) == 0);
+#endif
+
+	node = AVL_DATA2NODE(new_data, off);
+
+	/*
+	 * First, add the node to the tree at the indicated position.
+	 */
+	++tree->avl_numnodes;
+
+	node->avl_child[0] = NULL;
+	node->avl_child[1] = NULL;
+
+	AVL_SETCHILD(node, which_child);
+	AVL_SETBALANCE(node, 0);
+	AVL_SETPARENT(node, parent);
+	if (parent != NULL) {
+		ASSERT(parent->avl_child[which_child] == NULL);
+		parent->avl_child[which_child] = node;
+	} else {
+		ASSERT(tree->avl_root == NULL);
+		tree->avl_root = node;
+	}
+	/*
+	 * Now, back up the tree modifying the balance of all nodes above the
+	 * insertion point. If we get to a highly unbalanced ancestor, we
+	 * need to do a rotation.  If we back out of the tree we are done.
+	 * If we brought any subtree into perfect balance (0), we are also done.
+	 */
+	for (;;) {
+		node = parent;
+		if (node == NULL)
+			return;
+
+		/*
+		 * Compute the new balance
+		 */
+		old_balance = AVL_XBALANCE(node);
+		new_balance = old_balance + avl_child2balance[which_child];
+
+		/*
+		 * If we introduced equal balance, then we are done immediately
+		 */
+		if (new_balance == 0) {
+			AVL_SETBALANCE(node, 0);
+			return;
+		}
+
+		/*
+		 * If both old and new are not zero we went
+		 * from -1 to -2 balance, do a rotation.
+		 */
+		if (old_balance != 0)
+			break;
+
+		AVL_SETBALANCE(node, new_balance);
+		parent = AVL_XPARENT(node);
+		which_child = AVL_XCHILD(node);
+	}
+
+	/*
+	 * perform a rotation to fix the tree and return
+	 */
+	(void) avl_rotation(tree, node, new_balance);
+}
+
+/*
+ * Insert "new_data" in "tree" in the given "direction" either after or
+ * before (AVL_AFTER, AVL_BEFORE) the data "here".
+ *
+ * Insertions can only be done at empty leaf points in the tree, therefore
+ * if the given child of the node is already present we move to either
+ * the AVL_PREV or AVL_NEXT and reverse the insertion direction. Since
+ * every other node in the tree is a leaf, this always works.
+ *
+ * To help developers using this interface, we assert that the new node
+ * is correctly ordered at every step of the way in DEBUG kernels.
+ */
+void
+avl_insert_here(
+	avl_tree_t *tree,
+	void *new_data,
+	void *here,
+	int direction)
+{
+	avl_node_t *node;
+	int child = direction;	/* rely on AVL_BEFORE == 0, AVL_AFTER == 1 */
+#ifdef DEBUG
+	int diff;
+#endif
+
+	ASSERT(tree != NULL);
+	ASSERT(new_data != NULL);
+	ASSERT(here != NULL);
+	ASSERT(direction == AVL_BEFORE || direction == AVL_AFTER);
+
+	/*
+	 * If corresponding child of node is not NULL, go to the neighboring
+	 * node and reverse the insertion direction.
+	 */
+	node = AVL_DATA2NODE(here, tree->avl_offset);
+
+#ifdef DEBUG
+	diff = tree->avl_compar(new_data, here);
+	ASSERT(-1 <= diff && diff <= 1);
+	ASSERT(diff != 0);
+	ASSERT(diff > 0 ? child == 1 : child == 0);
+#endif
+
+	if (node->avl_child[child] != NULL) {
+		node = node->avl_child[child];
+		child = 1 - child;
+		while (node->avl_child[child] != NULL) {
+#ifdef DEBUG
+			diff = tree->avl_compar(new_data,
+			    AVL_NODE2DATA(node, tree->avl_offset));
+			ASSERT(-1 <= diff && diff <= 1);
+			ASSERT(diff != 0);
+			ASSERT(diff > 0 ? child == 1 : child == 0);
+#endif
+			node = node->avl_child[child];
+		}
+#ifdef DEBUG
+		diff = tree->avl_compar(new_data,
+		    AVL_NODE2DATA(node, tree->avl_offset));
+		ASSERT(-1 <= diff && diff <= 1);
+		ASSERT(diff != 0);
+		ASSERT(diff > 0 ? child == 1 : child == 0);
+#endif
+	}
+	ASSERT(node->avl_child[child] == NULL);
+
+	avl_insert(tree, new_data, AVL_MKINDEX(node, child));
+}
+
+/*
+ * Add a new node to an AVL tree.
+ */
+void
+avl_add(avl_tree_t *tree, void *new_node)
+{
+	avl_index_t where;
+
+	/*
+	 * This is unfortunate.  We want to call panic() here, even for
+	 * non-DEBUG kernels.  In userland, however, we can't depend on anything
+	 * in libc or else the rtld build process gets confused.  So, all we can
+	 * do in userland is resort to a normal ASSERT().
+	 */
+	if (avl_find(tree, new_node, &where) != NULL)
+#ifdef _KERNEL
+		panic("avl_find() succeeded inside avl_add()");
+#else
+		ASSERT(0);
+#endif
+	avl_insert(tree, new_node, where);
+}
+
+/*
+ * Delete a node from the AVL tree.  Deletion is similar to insertion, but
+ * with 2 complications.
+ *
+ * First, we may be deleting an interior node. Consider the following subtree:
+ *
+ *     d           c            c
+ *    / \         / \          / \
+ *   b   e       b   e        b   e
+ *  / \	        / \          /
+ * a   c       a            a
+ *
+ * When we are deleting node (d), we find and bring up an adjacent valued leaf
+ * node, say (c), to take the interior node's place. In the code this is
+ * handled by temporarily swapping (d) and (c) in the tree and then using
+ * common code to delete (d) from the leaf position.
+ *
+ * Secondly, an interior deletion from a deep tree may require more than one
+ * rotation to fix the balance. This is handled by moving up the tree through
+ * parents and applying rotations as needed. The return value from
+ * avl_rotation() is used to detect when a subtree did not change overall
+ * height due to a rotation.
+ */
+void
+avl_remove(avl_tree_t *tree, void *data)
+{
+	avl_node_t *delete;
+	avl_node_t *parent;
+	avl_node_t *node;
+	avl_node_t tmp;
+	int old_balance;
+	int new_balance;
+	int left;
+	int right;
+	int which_child;
+	size_t off = tree->avl_offset;
+
+	ASSERT(tree);
+
+	delete = AVL_DATA2NODE(data, off);
+
+	/*
+	 * Deletion is easiest with a node that has at most 1 child.
+	 * We swap a node with 2 children with a sequentially valued
+	 * neighbor node. That node will have at most 1 child. Note this
+	 * has no effect on the ordering of the remaining nodes.
+	 *
+	 * As an optimization, we choose the greater neighbor if the tree
+	 * is right heavy, otherwise the left neighbor. This reduces the
+	 * number of rotations needed.
+	 */
+	if (delete->avl_child[0] != NULL && delete->avl_child[1] != NULL) {
+
+		/*
+		 * choose node to swap from whichever side is taller
+		 */
+		old_balance = AVL_XBALANCE(delete);
+		left = avl_balance2child[old_balance + 1];
+		right = 1 - left;
+
+		/*
+		 * get to the previous value'd node
+		 * (down 1 left, as far as possible right)
+		 */
+		for (node = delete->avl_child[left];
+		    node->avl_child[right] != NULL;
+		    node = node->avl_child[right])
+			;
+
+		/*
+		 * create a temp placeholder for 'node'
+		 * move 'node' to delete's spot in the tree
+		 */
+		tmp = *node;
+
+		*node = *delete;
+		if (node->avl_child[left] == node)
+			node->avl_child[left] = &tmp;
+
+		parent = AVL_XPARENT(node);
+		if (parent != NULL)
+			parent->avl_child[AVL_XCHILD(node)] = node;
+		else
+			tree->avl_root = node;
+		AVL_SETPARENT(node->avl_child[left], node);
+		AVL_SETPARENT(node->avl_child[right], node);
+
+		/*
+		 * Put tmp where node used to be (just temporary).
+		 * It always has a parent and at most 1 child.
+		 */
+		delete = &tmp;
+		parent = AVL_XPARENT(delete);
+		parent->avl_child[AVL_XCHILD(delete)] = delete;
+		which_child = (delete->avl_child[1] != 0);
+		if (delete->avl_child[which_child] != NULL)
+			AVL_SETPARENT(delete->avl_child[which_child], delete);
+	}
+
+
+	/*
+	 * Here we know "delete" is at least partially a leaf node. It can
+	 * be easily removed from the tree.
+	 */
+	ASSERT(tree->avl_numnodes > 0);
+	--tree->avl_numnodes;
+	parent = AVL_XPARENT(delete);
+	which_child = AVL_XCHILD(delete);
+	if (delete->avl_child[0] != NULL)
+		node = delete->avl_child[0];
+	else
+		node = delete->avl_child[1];
+
+	/*
+	 * Connect parent directly to node (leaving out delete).
+	 */
+	if (node != NULL) {
+		AVL_SETPARENT(node, parent);
+		AVL_SETCHILD(node, which_child);
+	}
+	if (parent == NULL) {
+		tree->avl_root = node;
+		return;
+	}
+	parent->avl_child[which_child] = node;
+
+
+	/*
+	 * Since the subtree is now shorter, begin adjusting parent balances
+	 * and performing any needed rotations.
+	 */
+	do {
+
+		/*
+		 * Move up the tree and adjust the balance
+		 *
+		 * Capture the parent and which_child values for the next
+		 * iteration before any rotations occur.
+		 */
+		node = parent;
+		old_balance = AVL_XBALANCE(node);
+		new_balance = old_balance - avl_child2balance[which_child];
+		parent = AVL_XPARENT(node);
+		which_child = AVL_XCHILD(node);
+
+		/*
+		 * If a node was in perfect balance but isn't anymore then
+		 * we can stop, since the height didn't change above this point
+		 * due to a deletion.
+		 */
+		if (old_balance == 0) {
+			AVL_SETBALANCE(node, new_balance);
+			break;
+		}
+
+		/*
+		 * If the new balance is zero, we don't need to rotate
+		 * else
+		 * need a rotation to fix the balance.
+		 * If the rotation doesn't change the height
+		 * of the sub-tree we have finished adjusting.
+		 */
+		if (new_balance == 0)
+			AVL_SETBALANCE(node, new_balance);
+		else if (!avl_rotation(tree, node, new_balance))
+			break;
+	} while (parent != NULL);
+}
+
+#define	AVL_REINSERT(tree, obj)		\
+	avl_remove((tree), (obj));	\
+	avl_add((tree), (obj))
+
+boolean_t
+avl_update_lt(avl_tree_t *t, void *obj)
+{
+	void *neighbor;
+
+	ASSERT(((neighbor = AVL_NEXT(t, obj)) == NULL) ||
+	    (t->avl_compar(obj, neighbor) <= 0));
+
+	neighbor = AVL_PREV(t, obj);
+	if ((neighbor != NULL) && (t->avl_compar(obj, neighbor) < 0)) {
+		AVL_REINSERT(t, obj);
+		return (B_TRUE);
+	}
+
+	return (B_FALSE);
+}
+
+boolean_t
+avl_update_gt(avl_tree_t *t, void *obj)
+{
+	void *neighbor;
+
+	ASSERT(((neighbor = AVL_PREV(t, obj)) == NULL) ||
+	    (t->avl_compar(obj, neighbor) >= 0));
+
+	neighbor = AVL_NEXT(t, obj);
+	if ((neighbor != NULL) && (t->avl_compar(obj, neighbor) > 0)) {
+		AVL_REINSERT(t, obj);
+		return (B_TRUE);
+	}
+
+	return (B_FALSE);
+}
+
+boolean_t
+avl_update(avl_tree_t *t, void *obj)
+{
+	void *neighbor;
+
+	neighbor = AVL_PREV(t, obj);
+	if ((neighbor != NULL) && (t->avl_compar(obj, neighbor) < 0)) {
+		AVL_REINSERT(t, obj);
+		return (B_TRUE);
+	}
+
+	neighbor = AVL_NEXT(t, obj);
+	if ((neighbor != NULL) && (t->avl_compar(obj, neighbor) > 0)) {
+		AVL_REINSERT(t, obj);
+		return (B_TRUE);
+	}
+
+	return (B_FALSE);
+}
+
+void
+avl_swap(avl_tree_t *tree1, avl_tree_t *tree2)
+{
+	avl_node_t *temp_node;
+	ulong_t temp_numnodes;
+
+	ASSERT3P(tree1->avl_compar, ==, tree2->avl_compar);
+	ASSERT3U(tree1->avl_offset, ==, tree2->avl_offset);
+	ASSERT3U(tree1->avl_size, ==, tree2->avl_size);
+
+	temp_node = tree1->avl_root;
+	temp_numnodes = tree1->avl_numnodes;
+	tree1->avl_root = tree2->avl_root;
+	tree1->avl_numnodes = tree2->avl_numnodes;
+	tree2->avl_root = temp_node;
+	tree2->avl_numnodes = temp_numnodes;
+}
+
+/*
+ * initialize a new AVL tree
+ */
+void
+avl_create(avl_tree_t *tree, int (*compar) (const void *, const void *),
+    size_t size, size_t offset)
+{
+	ASSERT(tree);
+	ASSERT(compar);
+	ASSERT(size > 0);
+	ASSERT(size >= offset + sizeof (avl_node_t));
+#ifdef _LP64
+	ASSERT((offset & 0x7) == 0);
+#endif
+
+	tree->avl_compar = compar;
+	tree->avl_root = NULL;
+	tree->avl_numnodes = 0;
+	tree->avl_size = size;
+	tree->avl_offset = offset;
+}
+
+/*
+ * Delete a tree.
+ */
+/* ARGSUSED */
+void
+avl_destroy(avl_tree_t *tree)
+{
+	ASSERT(tree);
+	ASSERT(tree->avl_numnodes == 0);
+	ASSERT(tree->avl_root == NULL);
+}
+
+
+/*
+ * Return the number of nodes in an AVL tree.
+ */
+ulong_t
+avl_numnodes(avl_tree_t *tree)
+{
+	ASSERT(tree);
+	return (tree->avl_numnodes);
+}
+
+boolean_t
+avl_is_empty(avl_tree_t *tree)
+{
+	ASSERT(tree);
+	return (tree->avl_numnodes == 0);
+}
+
+#define	CHILDBIT	(1L)
+
+/*
+ * Post-order tree walk used to visit all tree nodes and destroy the tree
+ * in post order. This is used for destroying a tree without paying any cost
+ * for rebalancing it.
+ *
+ * example:
+ *
+ *	void *cookie = NULL;
+ *	my_data_t *node;
+ *
+ *	while ((node = avl_destroy_nodes(tree, &cookie)) != NULL)
+ *		free(node);
+ *	avl_destroy(tree);
+ *
+ * The cookie is really an avl_node_t to the current node's parent and
+ * an indication of which child you looked at last.
+ *
+ * On input, a cookie value of CHILDBIT indicates the tree is done.
+ */
+void *
+avl_destroy_nodes(avl_tree_t *tree, void **cookie)
+{
+	avl_node_t	*node;
+	avl_node_t	*parent;
+	int		child;
+	void		*first;
+	size_t		off = tree->avl_offset;
+
+	/*
+	 * Initial calls go to the first node or it's right descendant.
+	 */
+	if (*cookie == NULL) {
+		first = avl_first(tree);
+
+		/*
+		 * deal with an empty tree
+		 */
+		if (first == NULL) {
+			*cookie = (void *)CHILDBIT;
+			return (NULL);
+		}
+
+		node = AVL_DATA2NODE(first, off);
+		parent = AVL_XPARENT(node);
+		goto check_right_side;
+	}
+
+	/*
+	 * If there is no parent to return to we are done.
+	 */
+	parent = (avl_node_t *)((uintptr_t)(*cookie) & ~CHILDBIT);
+	if (parent == NULL) {
+		if (tree->avl_root != NULL) {
+			ASSERT(tree->avl_numnodes == 1);
+			tree->avl_root = NULL;
+			tree->avl_numnodes = 0;
+		}
+		return (NULL);
+	}
+
+	/*
+	 * Remove the child pointer we just visited from the parent and tree.
+	 */
+	child = (uintptr_t)(*cookie) & CHILDBIT;
+	parent->avl_child[child] = NULL;
+	ASSERT(tree->avl_numnodes > 1);
+	--tree->avl_numnodes;
+
+	/*
+	 * If we just did a right child or there isn't one, go up to parent.
+	 */
+	if (child == 1 || parent->avl_child[1] == NULL) {
+		node = parent;
+		parent = AVL_XPARENT(parent);
+		goto done;
+	}
+
+	/*
+	 * Do parent's right child, then leftmost descendent.
+	 */
+	node = parent->avl_child[1];
+	while (node->avl_child[0] != NULL) {
+		parent = node;
+		node = node->avl_child[0];
+	}
+
+	/*
+	 * If here, we moved to a left child. It may have one
+	 * child on the right (when balance == +1).
+	 */
+check_right_side:
+	if (node->avl_child[1] != NULL) {
+		ASSERT(AVL_XBALANCE(node) == 1);
+		parent = node;
+		node = node->avl_child[1];
+		ASSERT(node->avl_child[0] == NULL &&
+		    node->avl_child[1] == NULL);
+	} else {
+		ASSERT(AVL_XBALANCE(node) <= 0);
+	}
+
+done:
+	if (parent == NULL) {
+		*cookie = (void *)CHILDBIT;
+		ASSERT(node == tree->avl_root);
+	} else {
+		*cookie = (void *)((uintptr_t)parent | AVL_XCHILD(node));
+	}
+
+	return (AVL_NODE2DATA(node, off));
+}
+
+#if defined(_KERNEL) && defined(HAVE_SPL)
+static int __init
+avl_init(void)
+{
+	return (0);
+}
+
+static void __exit
+avl_fini(void)
+{
+}
+
+module_init(avl_init);
+module_exit(avl_fini);
+
+MODULE_DESCRIPTION("Generic AVL tree implementation");
+MODULE_AUTHOR(ZFS_META_AUTHOR);
+MODULE_LICENSE(ZFS_META_LICENSE);
+MODULE_VERSION(ZFS_META_VERSION "-" ZFS_META_RELEASE);
+
+EXPORT_SYMBOL(avl_create);
+EXPORT_SYMBOL(avl_find);
+EXPORT_SYMBOL(avl_insert);
+EXPORT_SYMBOL(avl_insert_here);
+EXPORT_SYMBOL(avl_walk);
+EXPORT_SYMBOL(avl_first);
+EXPORT_SYMBOL(avl_last);
+EXPORT_SYMBOL(avl_nearest);
+EXPORT_SYMBOL(avl_add);
+EXPORT_SYMBOL(avl_swap);
+EXPORT_SYMBOL(avl_is_empty);
+EXPORT_SYMBOL(avl_remove);
+EXPORT_SYMBOL(avl_numnodes);
+EXPORT_SYMBOL(avl_destroy_nodes);
+EXPORT_SYMBOL(avl_destroy);
+#endif
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/module/nvpair/Makefile.in
@@ -0,0 +1,13 @@
+src = @abs_top_srcdir@/module/nvpair
+obj = @abs_builddir@
+
+MODULE := znvpair
+
+EXTRA_CFLAGS = $(ZFS_MODULE_CFLAGS) @KERNELCPPFLAGS@
+
+obj-$(CONFIG_ZFS) := $(MODULE).o
+
+$(MODULE)-objs += nvpair.o
+$(MODULE)-objs += fnvpair.o
+$(MODULE)-objs += nvpair_alloc_spl.o
+$(MODULE)-objs += nvpair_alloc_fixed.o
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/module/nvpair/fnvpair.c
@@ -0,0 +1,581 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2012 by Delphix. All rights reserved.
+ */
+
+#include <sys/nvpair.h>
+#include <sys/kmem.h>
+#include <sys/debug.h>
+#include <sys/param.h>
+#ifndef _KERNEL
+#include <stdlib.h>
+#endif
+
+/*
+ * "Force" nvlist wrapper.
+ *
+ * These functions wrap the nvlist_* functions with assertions that assume
+ * the operation is successful.  This allows the caller's code to be much
+ * more readable, especially for the fnvlist_lookup_* and fnvpair_value_*
+ * functions, which can return the requested value (rather than filling in
+ * a pointer).
+ *
+ * These functions use NV_UNIQUE_NAME, encoding NV_ENCODE_NATIVE, and allocate
+ * with KM_SLEEP.
+ *
+ * More wrappers should be added as needed -- for example
+ * nvlist_lookup_*_array and nvpair_value_*_array.
+ */
+
+nvlist_t *
+fnvlist_alloc(void)
+{
+	nvlist_t *nvl;
+	VERIFY0(nvlist_alloc(&nvl, NV_UNIQUE_NAME, KM_SLEEP));
+	return (nvl);
+}
+
+void
+fnvlist_free(nvlist_t *nvl)
+{
+	nvlist_free(nvl);
+}
+
+size_t
+fnvlist_size(nvlist_t *nvl)
+{
+	size_t size;
+	VERIFY0(nvlist_size(nvl, &size, NV_ENCODE_NATIVE));
+	return (size);
+}
+
+/*
+ * Returns allocated buffer of size *sizep.  Caller must free the buffer with
+ * fnvlist_pack_free().
+ */
+char *
+fnvlist_pack(nvlist_t *nvl, size_t *sizep)
+{
+	char *packed = 0;
+	VERIFY3U(nvlist_pack(nvl, &packed, sizep, NV_ENCODE_NATIVE,
+	    KM_SLEEP), ==, 0);
+	return (packed);
+}
+
+/*ARGSUSED*/
+void
+fnvlist_pack_free(char *pack, size_t size)
+{
+#ifdef _KERNEL
+	kmem_free(pack, size);
+#else
+	free(pack);
+#endif
+}
+
+nvlist_t *
+fnvlist_unpack(char *buf, size_t buflen)
+{
+	nvlist_t *rv;
+	VERIFY0(nvlist_unpack(buf, buflen, &rv, KM_SLEEP));
+	return (rv);
+}
+
+nvlist_t *
+fnvlist_dup(nvlist_t *nvl)
+{
+	nvlist_t *rv;
+	VERIFY0(nvlist_dup(nvl, &rv, KM_SLEEP));
+	return (rv);
+}
+
+void
+fnvlist_merge(nvlist_t *dst, nvlist_t *src)
+{
+	VERIFY0(nvlist_merge(dst, src, KM_SLEEP));
+}
+
+size_t
+fnvlist_num_pairs(nvlist_t *nvl)
+{
+	size_t count = 0;
+	nvpair_t *pair;
+
+	for (pair = nvlist_next_nvpair(nvl, 0); pair != NULL;
+	    pair = nvlist_next_nvpair(nvl, pair))
+		count++;
+	return (count);
+}
+
+void
+fnvlist_add_boolean(nvlist_t *nvl, const char *name)
+{
+	VERIFY0(nvlist_add_boolean(nvl, name));
+}
+
+void
+fnvlist_add_boolean_value(nvlist_t *nvl, const char *name, boolean_t val)
+{
+	VERIFY0(nvlist_add_boolean_value(nvl, name, val));
+}
+
+void
+fnvlist_add_byte(nvlist_t *nvl, const char *name, uchar_t val)
+{
+	VERIFY0(nvlist_add_byte(nvl, name, val));
+}
+
+void
+fnvlist_add_int8(nvlist_t *nvl, const char *name, int8_t val)
+{
+	VERIFY0(nvlist_add_int8(nvl, name, val));
+}
+
+void
+fnvlist_add_uint8(nvlist_t *nvl, const char *name, uint8_t val)
+{
+	VERIFY0(nvlist_add_uint8(nvl, name, val));
+}
+
+void
+fnvlist_add_int16(nvlist_t *nvl, const char *name, int16_t val)
+{
+	VERIFY0(nvlist_add_int16(nvl, name, val));
+}
+
+void
+fnvlist_add_uint16(nvlist_t *nvl, const char *name, uint16_t val)
+{
+	VERIFY0(nvlist_add_uint16(nvl, name, val));
+}
+
+void
+fnvlist_add_int32(nvlist_t *nvl, const char *name, int32_t val)
+{
+	VERIFY0(nvlist_add_int32(nvl, name, val));
+}
+
+void
+fnvlist_add_uint32(nvlist_t *nvl, const char *name, uint32_t val)
+{
+	VERIFY0(nvlist_add_uint32(nvl, name, val));
+}
+
+void
+fnvlist_add_int64(nvlist_t *nvl, const char *name, int64_t val)
+{
+	VERIFY0(nvlist_add_int64(nvl, name, val));
+}
+
+void
+fnvlist_add_uint64(nvlist_t *nvl, const char *name, uint64_t val)
+{
+	VERIFY0(nvlist_add_uint64(nvl, name, val));
+}
+
+void
+fnvlist_add_string(nvlist_t *nvl, const char *name, const char *val)
+{
+	VERIFY0(nvlist_add_string(nvl, name, val));
+}
+
+void
+fnvlist_add_nvlist(nvlist_t *nvl, const char *name, nvlist_t *val)
+{
+	VERIFY0(nvlist_add_nvlist(nvl, name, val));
+}
+
+void
+fnvlist_add_nvpair(nvlist_t *nvl, nvpair_t *pair)
+{
+	VERIFY0(nvlist_add_nvpair(nvl, pair));
+}
+
+void
+fnvlist_add_boolean_array(nvlist_t *nvl, const char *name,
+    boolean_t *val, uint_t n)
+{
+	VERIFY0(nvlist_add_boolean_array(nvl, name, val, n));
+}
+
+void
+fnvlist_add_byte_array(nvlist_t *nvl, const char *name, uchar_t *val, uint_t n)
+{
+	VERIFY0(nvlist_add_byte_array(nvl, name, val, n));
+}
+
+void
+fnvlist_add_int8_array(nvlist_t *nvl, const char *name, int8_t *val, uint_t n)
+{
+	VERIFY0(nvlist_add_int8_array(nvl, name, val, n));
+}
+
+void
+fnvlist_add_uint8_array(nvlist_t *nvl, const char *name, uint8_t *val, uint_t n)
+{
+	VERIFY0(nvlist_add_uint8_array(nvl, name, val, n));
+}
+
+void
+fnvlist_add_int16_array(nvlist_t *nvl, const char *name, int16_t *val, uint_t n)
+{
+	VERIFY0(nvlist_add_int16_array(nvl, name, val, n));
+}
+
+void
+fnvlist_add_uint16_array(nvlist_t *nvl, const char *name,
+    uint16_t *val, uint_t n)
+{
+	VERIFY0(nvlist_add_uint16_array(nvl, name, val, n));
+}
+
+void
+fnvlist_add_int32_array(nvlist_t *nvl, const char *name, int32_t *val, uint_t n)
+{
+	VERIFY0(nvlist_add_int32_array(nvl, name, val, n));
+}
+
+void
+fnvlist_add_uint32_array(nvlist_t *nvl, const char *name,
+    uint32_t *val, uint_t n)
+{
+	VERIFY0(nvlist_add_uint32_array(nvl, name, val, n));
+}
+
+void
+fnvlist_add_int64_array(nvlist_t *nvl, const char *name, int64_t *val, uint_t n)
+{
+	VERIFY0(nvlist_add_int64_array(nvl, name, val, n));
+}
+
+void
+fnvlist_add_uint64_array(nvlist_t *nvl, const char *name,
+    uint64_t *val, uint_t n)
+{
+	VERIFY0(nvlist_add_uint64_array(nvl, name, val, n));
+}
+
+void
+fnvlist_add_string_array(nvlist_t *nvl, const char *name,
+    char * const *val, uint_t n)
+{
+	VERIFY0(nvlist_add_string_array(nvl, name, val, n));
+}
+
+void
+fnvlist_add_nvlist_array(nvlist_t *nvl, const char *name,
+    nvlist_t **val, uint_t n)
+{
+	VERIFY0(nvlist_add_nvlist_array(nvl, name, val, n));
+}
+
+void
+fnvlist_remove(nvlist_t *nvl, const char *name)
+{
+	VERIFY0(nvlist_remove_all(nvl, name));
+}
+
+void
+fnvlist_remove_nvpair(nvlist_t *nvl, nvpair_t *pair)
+{
+	VERIFY0(nvlist_remove_nvpair(nvl, pair));
+}
+
+nvpair_t *
+fnvlist_lookup_nvpair(nvlist_t *nvl, const char *name)
+{
+	nvpair_t *rv;
+	VERIFY0(nvlist_lookup_nvpair(nvl, name, &rv));
+	return (rv);
+}
+
+/* returns B_TRUE if the entry exists */
+boolean_t
+fnvlist_lookup_boolean(nvlist_t *nvl, const char *name)
+{
+	return (nvlist_lookup_boolean(nvl, name) == 0);
+}
+
+boolean_t
+fnvlist_lookup_boolean_value(nvlist_t *nvl, const char *name)
+{
+	boolean_t rv;
+	VERIFY0(nvlist_lookup_boolean_value(nvl, name, &rv));
+	return (rv);
+}
+
+uchar_t
+fnvlist_lookup_byte(nvlist_t *nvl, const char *name)
+{
+	uchar_t rv;
+	VERIFY0(nvlist_lookup_byte(nvl, name, &rv));
+	return (rv);
+}
+
+int8_t
+fnvlist_lookup_int8(nvlist_t *nvl, const char *name)
+{
+	int8_t rv;
+	VERIFY0(nvlist_lookup_int8(nvl, name, &rv));
+	return (rv);
+}
+
+int16_t
+fnvlist_lookup_int16(nvlist_t *nvl, const char *name)
+{
+	int16_t rv;
+	VERIFY0(nvlist_lookup_int16(nvl, name, &rv));
+	return (rv);
+}
+
+int32_t
+fnvlist_lookup_int32(nvlist_t *nvl, const char *name)
+{
+	int32_t rv;
+	VERIFY0(nvlist_lookup_int32(nvl, name, &rv));
+	return (rv);
+}
+
+int64_t
+fnvlist_lookup_int64(nvlist_t *nvl, const char *name)
+{
+	int64_t rv;
+	VERIFY0(nvlist_lookup_int64(nvl, name, &rv));
+	return (rv);
+}
+
+uint8_t
+fnvlist_lookup_uint8(nvlist_t *nvl, const char *name)
+{
+	uint8_t rv;
+	VERIFY0(nvlist_lookup_uint8(nvl, name, &rv));
+	return (rv);
+}
+
+uint16_t
+fnvlist_lookup_uint16(nvlist_t *nvl, const char *name)
+{
+	uint16_t rv;
+	VERIFY0(nvlist_lookup_uint16(nvl, name, &rv));
+	return (rv);
+}
+
+uint32_t
+fnvlist_lookup_uint32(nvlist_t *nvl, const char *name)
+{
+	uint32_t rv;
+	VERIFY0(nvlist_lookup_uint32(nvl, name, &rv));
+	return (rv);
+}
+
+uint64_t
+fnvlist_lookup_uint64(nvlist_t *nvl, const char *name)
+{
+	uint64_t rv;
+	VERIFY0(nvlist_lookup_uint64(nvl, name, &rv));
+	return (rv);
+}
+
+char *
+fnvlist_lookup_string(nvlist_t *nvl, const char *name)
+{
+	char *rv;
+	VERIFY0(nvlist_lookup_string(nvl, name, &rv));
+	return (rv);
+}
+
+nvlist_t *
+fnvlist_lookup_nvlist(nvlist_t *nvl, const char *name)
+{
+	nvlist_t *rv;
+	VERIFY0(nvlist_lookup_nvlist(nvl, name, &rv));
+	return (rv);
+}
+
+boolean_t
+fnvpair_value_boolean_value(nvpair_t *nvp)
+{
+	boolean_t rv;
+	VERIFY0(nvpair_value_boolean_value(nvp, &rv));
+	return (rv);
+}
+
+uchar_t
+fnvpair_value_byte(nvpair_t *nvp)
+{
+	uchar_t rv;
+	VERIFY0(nvpair_value_byte(nvp, &rv));
+	return (rv);
+}
+
+int8_t
+fnvpair_value_int8(nvpair_t *nvp)
+{
+	int8_t rv;
+	VERIFY0(nvpair_value_int8(nvp, &rv));
+	return (rv);
+}
+
+int16_t
+fnvpair_value_int16(nvpair_t *nvp)
+{
+	int16_t rv;
+	VERIFY0(nvpair_value_int16(nvp, &rv));
+	return (rv);
+}
+
+int32_t
+fnvpair_value_int32(nvpair_t *nvp)
+{
+	int32_t rv;
+	VERIFY0(nvpair_value_int32(nvp, &rv));
+	return (rv);
+}
+
+int64_t
+fnvpair_value_int64(nvpair_t *nvp)
+{
+	int64_t rv;
+	VERIFY0(nvpair_value_int64(nvp, &rv));
+	return (rv);
+}
+
+uint8_t
+fnvpair_value_uint8(nvpair_t *nvp)
+{
+	uint8_t rv;
+	VERIFY0(nvpair_value_uint8(nvp, &rv));
+	return (rv);
+}
+
+uint16_t
+fnvpair_value_uint16(nvpair_t *nvp)
+{
+	uint16_t rv;
+	VERIFY0(nvpair_value_uint16(nvp, &rv));
+	return (rv);
+}
+
+uint32_t
+fnvpair_value_uint32(nvpair_t *nvp)
+{
+	uint32_t rv;
+	VERIFY0(nvpair_value_uint32(nvp, &rv));
+	return (rv);
+}
+
+uint64_t
+fnvpair_value_uint64(nvpair_t *nvp)
+{
+	uint64_t rv;
+	VERIFY0(nvpair_value_uint64(nvp, &rv));
+	return (rv);
+}
+
+char *
+fnvpair_value_string(nvpair_t *nvp)
+{
+	char *rv;
+	VERIFY0(nvpair_value_string(nvp, &rv));
+	return (rv);
+}
+
+nvlist_t *
+fnvpair_value_nvlist(nvpair_t *nvp)
+{
+	nvlist_t *rv;
+	VERIFY0(nvpair_value_nvlist(nvp, &rv));
+	return (rv);
+}
+
+#if defined(_KERNEL) && defined(HAVE_SPL)
+
+EXPORT_SYMBOL(fnvlist_alloc);
+EXPORT_SYMBOL(fnvlist_free);
+EXPORT_SYMBOL(fnvlist_size);
+EXPORT_SYMBOL(fnvlist_pack);
+EXPORT_SYMBOL(fnvlist_pack_free);
+EXPORT_SYMBOL(fnvlist_unpack);
+EXPORT_SYMBOL(fnvlist_dup);
+EXPORT_SYMBOL(fnvlist_merge);
+
+EXPORT_SYMBOL(fnvlist_add_nvpair);
+EXPORT_SYMBOL(fnvlist_add_boolean);
+EXPORT_SYMBOL(fnvlist_add_boolean_value);
+EXPORT_SYMBOL(fnvlist_add_byte);
+EXPORT_SYMBOL(fnvlist_add_int8);
+EXPORT_SYMBOL(fnvlist_add_uint8);
+EXPORT_SYMBOL(fnvlist_add_int16);
+EXPORT_SYMBOL(fnvlist_add_uint16);
+EXPORT_SYMBOL(fnvlist_add_int32);
+EXPORT_SYMBOL(fnvlist_add_uint32);
+EXPORT_SYMBOL(fnvlist_add_int64);
+EXPORT_SYMBOL(fnvlist_add_uint64);
+EXPORT_SYMBOL(fnvlist_add_string);
+EXPORT_SYMBOL(fnvlist_add_nvlist);
+EXPORT_SYMBOL(fnvlist_add_boolean_array);
+EXPORT_SYMBOL(fnvlist_add_byte_array);
+EXPORT_SYMBOL(fnvlist_add_int8_array);
+EXPORT_SYMBOL(fnvlist_add_uint8_array);
+EXPORT_SYMBOL(fnvlist_add_int16_array);
+EXPORT_SYMBOL(fnvlist_add_uint16_array);
+EXPORT_SYMBOL(fnvlist_add_int32_array);
+EXPORT_SYMBOL(fnvlist_add_uint32_array);
+EXPORT_SYMBOL(fnvlist_add_int64_array);
+EXPORT_SYMBOL(fnvlist_add_uint64_array);
+EXPORT_SYMBOL(fnvlist_add_string_array);
+EXPORT_SYMBOL(fnvlist_add_nvlist_array);
+
+EXPORT_SYMBOL(fnvlist_remove);
+EXPORT_SYMBOL(fnvlist_remove_nvpair);
+
+EXPORT_SYMBOL(fnvlist_lookup_nvpair);
+EXPORT_SYMBOL(fnvlist_lookup_boolean);
+EXPORT_SYMBOL(fnvlist_lookup_boolean_value);
+EXPORT_SYMBOL(fnvlist_lookup_byte);
+EXPORT_SYMBOL(fnvlist_lookup_int8);
+EXPORT_SYMBOL(fnvlist_lookup_uint8);
+EXPORT_SYMBOL(fnvlist_lookup_int16);
+EXPORT_SYMBOL(fnvlist_lookup_uint16);
+EXPORT_SYMBOL(fnvlist_lookup_int32);
+EXPORT_SYMBOL(fnvlist_lookup_uint32);
+EXPORT_SYMBOL(fnvlist_lookup_int64);
+EXPORT_SYMBOL(fnvlist_lookup_uint64);
+EXPORT_SYMBOL(fnvlist_lookup_string);
+EXPORT_SYMBOL(fnvlist_lookup_nvlist);
+
+EXPORT_SYMBOL(fnvpair_value_boolean_value);
+EXPORT_SYMBOL(fnvpair_value_byte);
+EXPORT_SYMBOL(fnvpair_value_int8);
+EXPORT_SYMBOL(fnvpair_value_uint8);
+EXPORT_SYMBOL(fnvpair_value_int16);
+EXPORT_SYMBOL(fnvpair_value_uint16);
+EXPORT_SYMBOL(fnvpair_value_int32);
+EXPORT_SYMBOL(fnvpair_value_uint32);
+EXPORT_SYMBOL(fnvpair_value_int64);
+EXPORT_SYMBOL(fnvpair_value_uint64);
+EXPORT_SYMBOL(fnvpair_value_string);
+EXPORT_SYMBOL(fnvpair_value_nvlist);
+EXPORT_SYMBOL(fnvlist_num_pairs);
+
+#endif
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/module/nvpair/nvpair.c
@@ -0,0 +1,3429 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+ */
+
+#include <sys/stropts.h>
+#include <sys/debug.h>
+#include <sys/isa_defs.h>
+#include <sys/int_limits.h>
+#include <sys/nvpair.h>
+#include <sys/nvpair_impl.h>
+#include <rpc/types.h>
+#include <rpc/xdr.h>
+
+#if defined(_KERNEL) && !defined(_BOOT)
+#include <sys/varargs.h>
+#include <sys/ddi.h>
+#include <sys/sunddi.h>
+#else
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+#include <strings.h>
+#endif
+
+#ifndef	offsetof
+#define	offsetof(s, m)		((size_t)(&(((s *)0)->m)))
+#endif
+#define	skip_whitespace(p)	while ((*(p) == ' ') || (*(p) == '\t')) p++
+
+/*
+ * nvpair.c - Provides kernel & userland interfaces for manipulating
+ *	name-value pairs.
+ *
+ * Overview Diagram
+ *
+ *  +--------------+
+ *  |  nvlist_t    |
+ *  |--------------|
+ *  | nvl_version  |
+ *  | nvl_nvflag   |
+ *  | nvl_priv    -+-+
+ *  | nvl_flag     | |
+ *  | nvl_pad      | |
+ *  +--------------+ |
+ *                   V
+ *      +--------------+      last i_nvp in list
+ *      | nvpriv_t     |  +--------------------->
+ *      |--------------|  |
+ *   +--+- nvp_list    |  |   +------------+
+ *   |  |  nvp_last   -+--+   + nv_alloc_t |
+ *   |  |  nvp_curr    |      |------------|
+ *   |  |  nvp_nva    -+----> | nva_ops    |
+ *   |  |  nvp_stat    |      | nva_arg    |
+ *   |  +--------------+      +------------+
+ *   |
+ *   +-------+
+ *           V
+ *   +---------------------+      +-------------------+
+ *   |  i_nvp_t            |  +-->|  i_nvp_t          |  +-->
+ *   |---------------------|  |   |-------------------|  |
+ *   | nvi_next           -+--+   | nvi_next         -+--+
+ *   | nvi_prev (NULL)     | <----+ nvi_prev          |
+ *   | . . . . . . . . . . |      | . . . . . . . . . |
+ *   | nvp (nvpair_t)      |      | nvp (nvpair_t)    |
+ *   |  - nvp_size         |      |  - nvp_size       |
+ *   |  - nvp_name_sz      |      |  - nvp_name_sz    |
+ *   |  - nvp_value_elem   |      |  - nvp_value_elem |
+ *   |  - nvp_type         |      |  - nvp_type       |
+ *   |  - data ...         |      |  - data ...       |
+ *   +---------------------+      +-------------------+
+ *
+ *
+ *
+ *   +---------------------+              +---------------------+
+ *   |  i_nvp_t            |  +-->    +-->|  i_nvp_t (last)     |
+ *   |---------------------|  |       |   |---------------------|
+ *   |  nvi_next          -+--+ ... --+   | nvi_next (NULL)     |
+ * <-+- nvi_prev           |<-- ...  <----+ nvi_prev            |
+ *   | . . . . . . . . .   |              | . . . . . . . . .   |
+ *   | nvp (nvpair_t)      |              | nvp (nvpair_t)      |
+ *   |  - nvp_size         |              |  - nvp_size         |
+ *   |  - nvp_name_sz      |              |  - nvp_name_sz      |
+ *   |  - nvp_value_elem   |              |  - nvp_value_elem   |
+ *   |  - DATA_TYPE_NVLIST |              |  - nvp_type         |
+ *   |  - data (embedded)  |              |  - data ...         |
+ *   |    nvlist name      |              +---------------------+
+ *   |  +--------------+   |
+ *   |  |  nvlist_t    |   |
+ *   |  |--------------|   |
+ *   |  | nvl_version  |   |
+ *   |  | nvl_nvflag   |   |
+ *   |  | nvl_priv   --+---+---->
+ *   |  | nvl_flag     |   |
+ *   |  | nvl_pad      |   |
+ *   |  +--------------+   |
+ *   +---------------------+
+ *
+ *
+ * N.B. nvpair_t may be aligned on 4 byte boundary, so +4 will
+ * allow value to be aligned on 8 byte boundary
+ *
+ * name_len is the length of the name string including the null terminator
+ * so it must be >= 1
+ */
+#define	NVP_SIZE_CALC(name_len, data_len) \
+	(NV_ALIGN((sizeof (nvpair_t)) + name_len) + NV_ALIGN(data_len))
+
+static int i_get_value_size(data_type_t type, const void *data, uint_t nelem);
+static int nvlist_add_common(nvlist_t *nvl, const char *name, data_type_t type,
+    uint_t nelem, const void *data);
+
+#define	NV_STAT_EMBEDDED	0x1
+#define	EMBEDDED_NVL(nvp)	((nvlist_t *)(void *)NVP_VALUE(nvp))
+#define	EMBEDDED_NVL_ARRAY(nvp)	((nvlist_t **)(void *)NVP_VALUE(nvp))
+
+#define	NVP_VALOFF(nvp)	(NV_ALIGN(sizeof (nvpair_t) + (nvp)->nvp_name_sz))
+#define	NVPAIR2I_NVP(nvp) \
+	((i_nvp_t *)((size_t)(nvp) - offsetof(i_nvp_t, nvi_nvp)))
+
+
+int
+nv_alloc_init(nv_alloc_t *nva, const nv_alloc_ops_t *nvo, /* args */ ...)
+{
+	va_list valist;
+	int err = 0;
+
+	nva->nva_ops = nvo;
+	nva->nva_arg = NULL;
+
+	va_start(valist, nvo);
+	if (nva->nva_ops->nv_ao_init != NULL)
+		err = nva->nva_ops->nv_ao_init(nva, valist);
+	va_end(valist);
+
+	return (err);
+}
+
+void
+nv_alloc_reset(nv_alloc_t *nva)
+{
+	if (nva->nva_ops->nv_ao_reset != NULL)
+		nva->nva_ops->nv_ao_reset(nva);
+}
+
+void
+nv_alloc_fini(nv_alloc_t *nva)
+{
+	if (nva->nva_ops->nv_ao_fini != NULL)
+		nva->nva_ops->nv_ao_fini(nva);
+}
+
+nv_alloc_t *
+nvlist_lookup_nv_alloc(nvlist_t *nvl)
+{
+	nvpriv_t *priv;
+
+	if (nvl == NULL ||
+	    (priv = (nvpriv_t *)(uintptr_t)nvl->nvl_priv) == NULL)
+		return (NULL);
+
+	return (priv->nvp_nva);
+}
+
+static void *
+nv_mem_zalloc(nvpriv_t *nvp, size_t size)
+{
+	nv_alloc_t *nva = nvp->nvp_nva;
+	void *buf;
+
+	if ((buf = nva->nva_ops->nv_ao_alloc(nva, size)) != NULL)
+		bzero(buf, size);
+
+	return (buf);
+}
+
+static void
+nv_mem_free(nvpriv_t *nvp, void *buf, size_t size)
+{
+	nv_alloc_t *nva = nvp->nvp_nva;
+
+	nva->nva_ops->nv_ao_free(nva, buf, size);
+}
+
+static void
+nv_priv_init(nvpriv_t *priv, nv_alloc_t *nva, uint32_t stat)
+{
+	bzero(priv, sizeof (nvpriv_t));
+
+	priv->nvp_nva = nva;
+	priv->nvp_stat = stat;
+}
+
+static nvpriv_t *
+nv_priv_alloc(nv_alloc_t *nva)
+{
+	nvpriv_t *priv;
+
+	/*
+	 * nv_mem_alloc() cannot called here because it needs the priv
+	 * argument.
+	 */
+	if ((priv = nva->nva_ops->nv_ao_alloc(nva, sizeof (nvpriv_t))) == NULL)
+		return (NULL);
+
+	nv_priv_init(priv, nva, 0);
+
+	return (priv);
+}
+
+/*
+ * Embedded lists need their own nvpriv_t's.  We create a new
+ * nvpriv_t using the parameters and allocator from the parent
+ * list's nvpriv_t.
+ */
+static nvpriv_t *
+nv_priv_alloc_embedded(nvpriv_t *priv)
+{
+	nvpriv_t *emb_priv;
+
+	if ((emb_priv = nv_mem_zalloc(priv, sizeof (nvpriv_t))) == NULL)
+		return (NULL);
+
+	nv_priv_init(emb_priv, priv->nvp_nva, NV_STAT_EMBEDDED);
+
+	return (emb_priv);
+}
+
+static void
+nvlist_init(nvlist_t *nvl, uint32_t nvflag, nvpriv_t *priv)
+{
+	nvl->nvl_version = NV_VERSION;
+	nvl->nvl_nvflag = nvflag & (NV_UNIQUE_NAME|NV_UNIQUE_NAME_TYPE);
+	nvl->nvl_priv = (uint64_t)(uintptr_t)priv;
+	nvl->nvl_flag = 0;
+	nvl->nvl_pad = 0;
+}
+
+uint_t
+nvlist_nvflag(nvlist_t *nvl)
+{
+	return (nvl->nvl_nvflag);
+}
+
+static nv_alloc_t *
+nvlist_nv_alloc(int kmflag)
+{
+#if defined(_KERNEL) && !defined(_BOOT)
+	switch (kmflag) {
+	case KM_SLEEP:
+		return (nv_alloc_sleep);
+	case KM_PUSHPAGE:
+		return (nv_alloc_pushpage);
+	default:
+		return (nv_alloc_nosleep);
+	}
+#else
+	return (nv_alloc_nosleep);
+#endif /* _KERNEL && !_BOOT */
+}
+
+/*
+ * nvlist_alloc - Allocate nvlist.
+ */
+int
+nvlist_alloc(nvlist_t **nvlp, uint_t nvflag, int kmflag)
+{
+	return (nvlist_xalloc(nvlp, nvflag, nvlist_nv_alloc(kmflag)));
+}
+
+int
+nvlist_xalloc(nvlist_t **nvlp, uint_t nvflag, nv_alloc_t *nva)
+{
+	nvpriv_t *priv;
+
+	if (nvlp == NULL || nva == NULL)
+		return (EINVAL);
+
+	if ((priv = nv_priv_alloc(nva)) == NULL)
+		return (ENOMEM);
+
+	if ((*nvlp = nv_mem_zalloc(priv,
+	    NV_ALIGN(sizeof (nvlist_t)))) == NULL) {
+		nv_mem_free(priv, priv, sizeof (nvpriv_t));
+		return (ENOMEM);
+	}
+
+	nvlist_init(*nvlp, nvflag, priv);
+
+	return (0);
+}
+
+/*
+ * nvp_buf_alloc - Allocate i_nvp_t for storing a new nv pair.
+ */
+static nvpair_t *
+nvp_buf_alloc(nvlist_t *nvl, size_t len)
+{
+	nvpriv_t *priv = (nvpriv_t *)(uintptr_t)nvl->nvl_priv;
+	i_nvp_t *buf;
+	nvpair_t *nvp;
+	size_t nvsize;
+
+	/*
+	 * Allocate the buffer
+	 */
+	nvsize = len + offsetof(i_nvp_t, nvi_nvp);
+
+	if ((buf = nv_mem_zalloc(priv, nvsize)) == NULL)
+		return (NULL);
+
+	nvp = &buf->nvi_nvp;
+	nvp->nvp_size = len;
+
+	return (nvp);
+}
+
+/*
+ * nvp_buf_free - de-Allocate an i_nvp_t.
+ */
+static void
+nvp_buf_free(nvlist_t *nvl, nvpair_t *nvp)
+{
+	nvpriv_t *priv = (nvpriv_t *)(uintptr_t)nvl->nvl_priv;
+	size_t nvsize = nvp->nvp_size + offsetof(i_nvp_t, nvi_nvp);
+
+	nv_mem_free(priv, NVPAIR2I_NVP(nvp), nvsize);
+}
+
+/*
+ * nvp_buf_link - link a new nv pair into the nvlist.
+ */
+static void
+nvp_buf_link(nvlist_t *nvl, nvpair_t *nvp)
+{
+	nvpriv_t *priv = (nvpriv_t *)(uintptr_t)nvl->nvl_priv;
+	i_nvp_t *curr = NVPAIR2I_NVP(nvp);
+
+	/* Put element at end of nvlist */
+	if (priv->nvp_list == NULL) {
+		priv->nvp_list = priv->nvp_last = curr;
+	} else {
+		curr->nvi_prev = priv->nvp_last;
+		priv->nvp_last->nvi_next = curr;
+		priv->nvp_last = curr;
+	}
+}
+
+/*
+ * nvp_buf_unlink - unlink an removed nvpair out of the nvlist.
+ */
+static void
+nvp_buf_unlink(nvlist_t *nvl, nvpair_t *nvp)
+{
+	nvpriv_t *priv = (nvpriv_t *)(uintptr_t)nvl->nvl_priv;
+	i_nvp_t *curr = NVPAIR2I_NVP(nvp);
+
+	/*
+	 * protect nvlist_next_nvpair() against walking on freed memory.
+	 */
+	if (priv->nvp_curr == curr)
+		priv->nvp_curr = curr->nvi_next;
+
+	if (curr == priv->nvp_list)
+		priv->nvp_list = curr->nvi_next;
+	else
+		curr->nvi_prev->nvi_next = curr->nvi_next;
+
+	if (curr == priv->nvp_last)
+		priv->nvp_last = curr->nvi_prev;
+	else
+		curr->nvi_next->nvi_prev = curr->nvi_prev;
+}
+
+/*
+ * take a nvpair type and number of elements and make sure the are valid
+ */
+static int
+i_validate_type_nelem(data_type_t type, uint_t nelem)
+{
+	switch (type) {
+	case DATA_TYPE_BOOLEAN:
+		if (nelem != 0)
+			return (EINVAL);
+		break;
+	case DATA_TYPE_BOOLEAN_VALUE:
+	case DATA_TYPE_BYTE:
+	case DATA_TYPE_INT8:
+	case DATA_TYPE_UINT8:
+	case DATA_TYPE_INT16:
+	case DATA_TYPE_UINT16:
+	case DATA_TYPE_INT32:
+	case DATA_TYPE_UINT32:
+	case DATA_TYPE_INT64:
+	case DATA_TYPE_UINT64:
+	case DATA_TYPE_STRING:
+	case DATA_TYPE_HRTIME:
+	case DATA_TYPE_NVLIST:
+#if !defined(_KERNEL)
+	case DATA_TYPE_DOUBLE:
+#endif
+		if (nelem != 1)
+			return (EINVAL);
+		break;
+	case DATA_TYPE_BOOLEAN_ARRAY:
+	case DATA_TYPE_BYTE_ARRAY:
+	case DATA_TYPE_INT8_ARRAY:
+	case DATA_TYPE_UINT8_ARRAY:
+	case DATA_TYPE_INT16_ARRAY:
+	case DATA_TYPE_UINT16_ARRAY:
+	case DATA_TYPE_INT32_ARRAY:
+	case DATA_TYPE_UINT32_ARRAY:
+	case DATA_TYPE_INT64_ARRAY:
+	case DATA_TYPE_UINT64_ARRAY:
+	case DATA_TYPE_STRING_ARRAY:
+	case DATA_TYPE_NVLIST_ARRAY:
+		/* we allow arrays with 0 elements */
+		break;
+	default:
+		return (EINVAL);
+	}
+	return (0);
+}
+
+/*
+ * Verify nvp_name_sz and check the name string length.
+ */
+static int
+i_validate_nvpair_name(nvpair_t *nvp)
+{
+	if ((nvp->nvp_name_sz <= 0) ||
+	    (nvp->nvp_size < NVP_SIZE_CALC(nvp->nvp_name_sz, 0)))
+		return (EFAULT);
+
+	/* verify the name string, make sure its terminated */
+	if (NVP_NAME(nvp)[nvp->nvp_name_sz - 1] != '\0')
+		return (EFAULT);
+
+	return (strlen(NVP_NAME(nvp)) == nvp->nvp_name_sz - 1 ? 0 : EFAULT);
+}
+
+static int
+i_validate_nvpair_value(data_type_t type, uint_t nelem, const void *data)
+{
+	switch (type) {
+	case DATA_TYPE_BOOLEAN_VALUE:
+		if (*(boolean_t *)data != B_TRUE &&
+		    *(boolean_t *)data != B_FALSE)
+			return (EINVAL);
+		break;
+	case DATA_TYPE_BOOLEAN_ARRAY: {
+		int i;
+
+		for (i = 0; i < nelem; i++)
+			if (((boolean_t *)data)[i] != B_TRUE &&
+			    ((boolean_t *)data)[i] != B_FALSE)
+				return (EINVAL);
+		break;
+	}
+	default:
+		break;
+	}
+
+	return (0);
+}
+
+/*
+ * This function takes a pointer to what should be a nvpair and it's size
+ * and then verifies that all the nvpair fields make sense and can be
+ * trusted.  This function is used when decoding packed nvpairs.
+ */
+static int
+i_validate_nvpair(nvpair_t *nvp)
+{
+	data_type_t type = NVP_TYPE(nvp);
+	int size1, size2;
+
+	/* verify nvp_name_sz, check the name string length */
+	if (i_validate_nvpair_name(nvp) != 0)
+		return (EFAULT);
+
+	if (i_validate_nvpair_value(type, NVP_NELEM(nvp), NVP_VALUE(nvp)) != 0)
+		return (EFAULT);
+
+	/*
+	 * verify nvp_type, nvp_value_elem, and also possibly
+	 * verify string values and get the value size.
+	 */
+	size2 = i_get_value_size(type, NVP_VALUE(nvp), NVP_NELEM(nvp));
+	size1 = nvp->nvp_size - NVP_VALOFF(nvp);
+	if (size2 < 0 || size1 != NV_ALIGN(size2))
+		return (EFAULT);
+
+	return (0);
+}
+
+static int
+nvlist_copy_pairs(nvlist_t *snvl, nvlist_t *dnvl)
+{
+	nvpriv_t *priv;
+	i_nvp_t *curr;
+
+	if ((priv = (nvpriv_t *)(uintptr_t)snvl->nvl_priv) == NULL)
+		return (EINVAL);
+
+	for (curr = priv->nvp_list; curr != NULL; curr = curr->nvi_next) {
+		nvpair_t *nvp = &curr->nvi_nvp;
+		int err;
+
+		if ((err = nvlist_add_common(dnvl, NVP_NAME(nvp), NVP_TYPE(nvp),
+		    NVP_NELEM(nvp), NVP_VALUE(nvp))) != 0)
+			return (err);
+	}
+
+	return (0);
+}
+
+/*
+ * Frees all memory allocated for an nvpair (like embedded lists) with
+ * the exception of the nvpair buffer itself.
+ */
+static void
+nvpair_free(nvpair_t *nvp)
+{
+	switch (NVP_TYPE(nvp)) {
+	case DATA_TYPE_NVLIST:
+		nvlist_free(EMBEDDED_NVL(nvp));
+		break;
+	case DATA_TYPE_NVLIST_ARRAY: {
+		nvlist_t **nvlp = EMBEDDED_NVL_ARRAY(nvp);
+		int i;
+
+		for (i = 0; i < NVP_NELEM(nvp); i++)
+			if (nvlp[i] != NULL)
+				nvlist_free(nvlp[i]);
+		break;
+	}
+	default:
+		break;
+	}
+}
+
+/*
+ * nvlist_free - free an unpacked nvlist
+ */
+void
+nvlist_free(nvlist_t *nvl)
+{
+	nvpriv_t *priv;
+	i_nvp_t *curr;
+
+	if (nvl == NULL ||
+	    (priv = (nvpriv_t *)(uintptr_t)nvl->nvl_priv) == NULL)
+		return;
+
+	/*
+	 * Unpacked nvlist are linked through i_nvp_t
+	 */
+	curr = priv->nvp_list;
+	while (curr != NULL) {
+		nvpair_t *nvp = &curr->nvi_nvp;
+		curr = curr->nvi_next;
+
+		nvpair_free(nvp);
+		nvp_buf_free(nvl, nvp);
+	}
+
+	if (!(priv->nvp_stat & NV_STAT_EMBEDDED))
+		nv_mem_free(priv, nvl, NV_ALIGN(sizeof (nvlist_t)));
+	else
+		nvl->nvl_priv = 0;
+
+	nv_mem_free(priv, priv, sizeof (nvpriv_t));
+}
+
+static int
+nvlist_contains_nvp(nvlist_t *nvl, nvpair_t *nvp)
+{
+	nvpriv_t *priv = (nvpriv_t *)(uintptr_t)nvl->nvl_priv;
+	i_nvp_t *curr;
+
+	if (nvp == NULL)
+		return (0);
+
+	for (curr = priv->nvp_list; curr != NULL; curr = curr->nvi_next)
+		if (&curr->nvi_nvp == nvp)
+			return (1);
+
+	return (0);
+}
+
+/*
+ * Make a copy of nvlist
+ */
+int
+nvlist_dup(nvlist_t *nvl, nvlist_t **nvlp, int kmflag)
+{
+	return (nvlist_xdup(nvl, nvlp, nvlist_nv_alloc(kmflag)));
+}
+
+int
+nvlist_xdup(nvlist_t *nvl, nvlist_t **nvlp, nv_alloc_t *nva)
+{
+	int err;
+	nvlist_t *ret;
+
+	if (nvl == NULL || nvlp == NULL)
+		return (EINVAL);
+
+	if ((err = nvlist_xalloc(&ret, nvl->nvl_nvflag, nva)) != 0)
+		return (err);
+
+	if ((err = nvlist_copy_pairs(nvl, ret)) != 0)
+		nvlist_free(ret);
+	else
+		*nvlp = ret;
+
+	return (err);
+}
+
+/*
+ * Remove all with matching name
+ */
+int
+nvlist_remove_all(nvlist_t *nvl, const char *name)
+{
+	nvpriv_t *priv;
+	i_nvp_t *curr;
+	int error = ENOENT;
+
+	if (nvl == NULL || name == NULL ||
+	    (priv = (nvpriv_t *)(uintptr_t)nvl->nvl_priv) == NULL)
+		return (EINVAL);
+
+	curr = priv->nvp_list;
+	while (curr != NULL) {
+		nvpair_t *nvp = &curr->nvi_nvp;
+
+		curr = curr->nvi_next;
+		if (strcmp(name, NVP_NAME(nvp)) != 0)
+			continue;
+
+		nvp_buf_unlink(nvl, nvp);
+		nvpair_free(nvp);
+		nvp_buf_free(nvl, nvp);
+
+		error = 0;
+	}
+
+	return (error);
+}
+
+/*
+ * Remove first one with matching name and type
+ */
+int
+nvlist_remove(nvlist_t *nvl, const char *name, data_type_t type)
+{
+	nvpriv_t *priv;
+	i_nvp_t *curr;
+
+	if (nvl == NULL || name == NULL ||
+	    (priv = (nvpriv_t *)(uintptr_t)nvl->nvl_priv) == NULL)
+		return (EINVAL);
+
+	curr = priv->nvp_list;
+	while (curr != NULL) {
+		nvpair_t *nvp = &curr->nvi_nvp;
+
+		if (strcmp(name, NVP_NAME(nvp)) == 0 && NVP_TYPE(nvp) == type) {
+			nvp_buf_unlink(nvl, nvp);
+			nvpair_free(nvp);
+			nvp_buf_free(nvl, nvp);
+
+			return (0);
+		}
+		curr = curr->nvi_next;
+	}
+
+	return (ENOENT);
+}
+
+int
+nvlist_remove_nvpair(nvlist_t *nvl, nvpair_t *nvp)
+{
+	if (nvl == NULL || nvp == NULL)
+		return (EINVAL);
+
+	nvp_buf_unlink(nvl, nvp);
+	nvpair_free(nvp);
+	nvp_buf_free(nvl, nvp);
+	return (0);
+}
+
+/*
+ * This function calculates the size of an nvpair value.
+ *
+ * The data argument controls the behavior in case of the data types
+ * 	DATA_TYPE_STRING    	and
+ *	DATA_TYPE_STRING_ARRAY
+ * Is data == NULL then the size of the string(s) is excluded.
+ */
+static int
+i_get_value_size(data_type_t type, const void *data, uint_t nelem)
+{
+	uint64_t value_sz;
+
+	if (i_validate_type_nelem(type, nelem) != 0)
+		return (-1);
+
+	/* Calculate required size for holding value */
+	switch (type) {
+	case DATA_TYPE_BOOLEAN:
+		value_sz = 0;
+		break;
+	case DATA_TYPE_BOOLEAN_VALUE:
+		value_sz = sizeof (boolean_t);
+		break;
+	case DATA_TYPE_BYTE:
+		value_sz = sizeof (uchar_t);
+		break;
+	case DATA_TYPE_INT8:
+		value_sz = sizeof (int8_t);
+		break;
+	case DATA_TYPE_UINT8:
+		value_sz = sizeof (uint8_t);
+		break;
+	case DATA_TYPE_INT16:
+		value_sz = sizeof (int16_t);
+		break;
+	case DATA_TYPE_UINT16:
+		value_sz = sizeof (uint16_t);
+		break;
+	case DATA_TYPE_INT32:
+		value_sz = sizeof (int32_t);
+		break;
+	case DATA_TYPE_UINT32:
+		value_sz = sizeof (uint32_t);
+		break;
+	case DATA_TYPE_INT64:
+		value_sz = sizeof (int64_t);
+		break;
+	case DATA_TYPE_UINT64:
+		value_sz = sizeof (uint64_t);
+		break;
+#if !defined(_KERNEL)
+	case DATA_TYPE_DOUBLE:
+		value_sz = sizeof (double);
+		break;
+#endif
+	case DATA_TYPE_STRING:
+		if (data == NULL)
+			value_sz = 0;
+		else
+			value_sz = strlen(data) + 1;
+		break;
+	case DATA_TYPE_BOOLEAN_ARRAY:
+		value_sz = (uint64_t)nelem * sizeof (boolean_t);
+		break;
+	case DATA_TYPE_BYTE_ARRAY:
+		value_sz = (uint64_t)nelem * sizeof (uchar_t);
+		break;
+	case DATA_TYPE_INT8_ARRAY:
+		value_sz = (uint64_t)nelem * sizeof (int8_t);
+		break;
+	case DATA_TYPE_UINT8_ARRAY:
+		value_sz = (uint64_t)nelem * sizeof (uint8_t);
+		break;
+	case DATA_TYPE_INT16_ARRAY:
+		value_sz = (uint64_t)nelem * sizeof (int16_t);
+		break;
+	case DATA_TYPE_UINT16_ARRAY:
+		value_sz = (uint64_t)nelem * sizeof (uint16_t);
+		break;
+	case DATA_TYPE_INT32_ARRAY:
+		value_sz = (uint64_t)nelem * sizeof (int32_t);
+		break;
+	case DATA_TYPE_UINT32_ARRAY:
+		value_sz = (uint64_t)nelem * sizeof (uint32_t);
+		break;
+	case DATA_TYPE_INT64_ARRAY:
+		value_sz = (uint64_t)nelem * sizeof (int64_t);
+		break;
+	case DATA_TYPE_UINT64_ARRAY:
+		value_sz = (uint64_t)nelem * sizeof (uint64_t);
+		break;
+	case DATA_TYPE_STRING_ARRAY:
+		value_sz = (uint64_t)nelem * sizeof (uint64_t);
+
+		if (data != NULL) {
+			char *const *strs = data;
+			uint_t i;
+
+			/* no alignment requirement for strings */
+			for (i = 0; i < nelem; i++) {
+				if (strs[i] == NULL)
+					return (-1);
+				value_sz += strlen(strs[i]) + 1;
+			}
+		}
+		break;
+	case DATA_TYPE_HRTIME:
+		value_sz = sizeof (hrtime_t);
+		break;
+	case DATA_TYPE_NVLIST:
+		value_sz = NV_ALIGN(sizeof (nvlist_t));
+		break;
+	case DATA_TYPE_NVLIST_ARRAY:
+		value_sz = (uint64_t)nelem * sizeof (uint64_t) +
+		    (uint64_t)nelem * NV_ALIGN(sizeof (nvlist_t));
+		break;
+	default:
+		return (-1);
+	}
+
+	return (value_sz > INT32_MAX ? -1 : (int)value_sz);
+}
+
+static int
+nvlist_copy_embedded(nvlist_t *nvl, nvlist_t *onvl, nvlist_t *emb_nvl)
+{
+	nvpriv_t *priv;
+	int err;
+
+	if ((priv = nv_priv_alloc_embedded((nvpriv_t *)(uintptr_t)
+	    nvl->nvl_priv)) == NULL)
+		return (ENOMEM);
+
+	nvlist_init(emb_nvl, onvl->nvl_nvflag, priv);
+
+	if ((err = nvlist_copy_pairs(onvl, emb_nvl)) != 0) {
+		nvlist_free(emb_nvl);
+		emb_nvl->nvl_priv = 0;
+	}
+
+	return (err);
+}
+
+/*
+ * nvlist_add_common - Add new <name,value> pair to nvlist
+ */
+static int
+nvlist_add_common(nvlist_t *nvl, const char *name,
+    data_type_t type, uint_t nelem, const void *data)
+{
+	nvpair_t *nvp;
+	uint_t i;
+
+	int nvp_sz, name_sz, value_sz;
+	int err = 0;
+
+	if (name == NULL || nvl == NULL || nvl->nvl_priv == 0)
+		return (EINVAL);
+
+	if (nelem != 0 && data == NULL)
+		return (EINVAL);
+
+	/*
+	 * Verify type and nelem and get the value size.
+	 * In case of data types DATA_TYPE_STRING and DATA_TYPE_STRING_ARRAY
+	 * is the size of the string(s) included.
+	 */
+	if ((value_sz = i_get_value_size(type, data, nelem)) < 0)
+		return (EINVAL);
+
+	if (i_validate_nvpair_value(type, nelem, data) != 0)
+		return (EINVAL);
+
+	/*
+	 * If we're adding an nvlist or nvlist array, ensure that we are not
+	 * adding the input nvlist to itself, which would cause recursion,
+	 * and ensure that no NULL nvlist pointers are present.
+	 */
+	switch (type) {
+	case DATA_TYPE_NVLIST:
+		if (data == nvl || data == NULL)
+			return (EINVAL);
+		break;
+	case DATA_TYPE_NVLIST_ARRAY: {
+		nvlist_t **onvlp = (nvlist_t **)data;
+		for (i = 0; i < nelem; i++) {
+			if (onvlp[i] == nvl || onvlp[i] == NULL)
+				return (EINVAL);
+		}
+		break;
+	}
+	default:
+		break;
+	}
+
+	/* calculate sizes of the nvpair elements and the nvpair itself */
+	name_sz = strlen(name) + 1;
+
+	nvp_sz = NVP_SIZE_CALC(name_sz, value_sz);
+
+	if ((nvp = nvp_buf_alloc(nvl, nvp_sz)) == NULL)
+		return (ENOMEM);
+
+	ASSERT(nvp->nvp_size == nvp_sz);
+	nvp->nvp_name_sz = name_sz;
+	nvp->nvp_value_elem = nelem;
+	nvp->nvp_type = type;
+	bcopy(name, NVP_NAME(nvp), name_sz);
+
+	switch (type) {
+	case DATA_TYPE_BOOLEAN:
+		break;
+	case DATA_TYPE_STRING_ARRAY: {
+		char *const *strs = data;
+		char *buf = NVP_VALUE(nvp);
+		char **cstrs = (void *)buf;
+
+		/* skip pre-allocated space for pointer array */
+		buf += nelem * sizeof (uint64_t);
+		for (i = 0; i < nelem; i++) {
+			int slen = strlen(strs[i]) + 1;
+			bcopy(strs[i], buf, slen);
+			cstrs[i] = buf;
+			buf += slen;
+		}
+		break;
+	}
+	case DATA_TYPE_NVLIST: {
+		nvlist_t *nnvl = EMBEDDED_NVL(nvp);
+		nvlist_t *onvl = (nvlist_t *)data;
+
+		if ((err = nvlist_copy_embedded(nvl, onvl, nnvl)) != 0) {
+			nvp_buf_free(nvl, nvp);
+			return (err);
+		}
+		break;
+	}
+	case DATA_TYPE_NVLIST_ARRAY: {
+		nvlist_t **onvlp = (nvlist_t **)data;
+		nvlist_t **nvlp = EMBEDDED_NVL_ARRAY(nvp);
+		nvlist_t *embedded = (nvlist_t *)
+		    ((uintptr_t)nvlp + nelem * sizeof (uint64_t));
+
+		for (i = 0; i < nelem; i++) {
+			if ((err = nvlist_copy_embedded(nvl,
+			    onvlp[i], embedded)) != 0) {
+				/*
+				 * Free any successfully created lists
+				 */
+				nvpair_free(nvp);
+				nvp_buf_free(nvl, nvp);
+				return (err);
+			}
+
+			nvlp[i] = embedded++;
+		}
+		break;
+	}
+	default:
+		bcopy(data, NVP_VALUE(nvp), value_sz);
+	}
+
+	/* if unique name, remove before add */
+	if (nvl->nvl_nvflag & NV_UNIQUE_NAME)
+		(void) nvlist_remove_all(nvl, name);
+	else if (nvl->nvl_nvflag & NV_UNIQUE_NAME_TYPE)
+		(void) nvlist_remove(nvl, name, type);
+
+	nvp_buf_link(nvl, nvp);
+
+	return (0);
+}
+
+int
+nvlist_add_boolean(nvlist_t *nvl, const char *name)
+{
+	return (nvlist_add_common(nvl, name, DATA_TYPE_BOOLEAN, 0, NULL));
+}
+
+int
+nvlist_add_boolean_value(nvlist_t *nvl, const char *name, boolean_t val)
+{
+	return (nvlist_add_common(nvl, name, DATA_TYPE_BOOLEAN_VALUE, 1, &val));
+}
+
+int
+nvlist_add_byte(nvlist_t *nvl, const char *name, uchar_t val)
+{
+	return (nvlist_add_common(nvl, name, DATA_TYPE_BYTE, 1, &val));
+}
+
+int
+nvlist_add_int8(nvlist_t *nvl, const char *name, int8_t val)
+{
+	return (nvlist_add_common(nvl, name, DATA_TYPE_INT8, 1, &val));
+}
+
+int
+nvlist_add_uint8(nvlist_t *nvl, const char *name, uint8_t val)
+{
+	return (nvlist_add_common(nvl, name, DATA_TYPE_UINT8, 1, &val));
+}
+
+int
+nvlist_add_int16(nvlist_t *nvl, const char *name, int16_t val)
+{
+	return (nvlist_add_common(nvl, name, DATA_TYPE_INT16, 1, &val));
+}
+
+int
+nvlist_add_uint16(nvlist_t *nvl, const char *name, uint16_t val)
+{
+	return (nvlist_add_common(nvl, name, DATA_TYPE_UINT16, 1, &val));
+}
+
+int
+nvlist_add_int32(nvlist_t *nvl, const char *name, int32_t val)
+{
+	return (nvlist_add_common(nvl, name, DATA_TYPE_INT32, 1, &val));
+}
+
+int
+nvlist_add_uint32(nvlist_t *nvl, const char *name, uint32_t val)
+{
+	return (nvlist_add_common(nvl, name, DATA_TYPE_UINT32, 1, &val));
+}
+
+int
+nvlist_add_int64(nvlist_t *nvl, const char *name, int64_t val)
+{
+	return (nvlist_add_common(nvl, name, DATA_TYPE_INT64, 1, &val));
+}
+
+int
+nvlist_add_uint64(nvlist_t *nvl, const char *name, uint64_t val)
+{
+	return (nvlist_add_common(nvl, name, DATA_TYPE_UINT64, 1, &val));
+}
+
+#if !defined(_KERNEL)
+int
+nvlist_add_double(nvlist_t *nvl, const char *name, double val)
+{
+	return (nvlist_add_common(nvl, name, DATA_TYPE_DOUBLE, 1, &val));
+}
+#endif
+
+int
+nvlist_add_string(nvlist_t *nvl, const char *name, const char *val)
+{
+	return (nvlist_add_common(nvl, name, DATA_TYPE_STRING, 1, (void *)val));
+}
+
+int
+nvlist_add_boolean_array(nvlist_t *nvl, const char *name,
+    boolean_t *a, uint_t n)
+{
+	return (nvlist_add_common(nvl, name, DATA_TYPE_BOOLEAN_ARRAY, n, a));
+}
+
+int
+nvlist_add_byte_array(nvlist_t *nvl, const char *name, uchar_t *a, uint_t n)
+{
+	return (nvlist_add_common(nvl, name, DATA_TYPE_BYTE_ARRAY, n, a));
+}
+
+int
+nvlist_add_int8_array(nvlist_t *nvl, const char *name, int8_t *a, uint_t n)
+{
+	return (nvlist_add_common(nvl, name, DATA_TYPE_INT8_ARRAY, n, a));
+}
+
+int
+nvlist_add_uint8_array(nvlist_t *nvl, const char *name, uint8_t *a, uint_t n)
+{
+	return (nvlist_add_common(nvl, name, DATA_TYPE_UINT8_ARRAY, n, a));
+}
+
+int
+nvlist_add_int16_array(nvlist_t *nvl, const char *name, int16_t *a, uint_t n)
+{
+	return (nvlist_add_common(nvl, name, DATA_TYPE_INT16_ARRAY, n, a));
+}
+
+int
+nvlist_add_uint16_array(nvlist_t *nvl, const char *name, uint16_t *a, uint_t n)
+{
+	return (nvlist_add_common(nvl, name, DATA_TYPE_UINT16_ARRAY, n, a));
+}
+
+int
+nvlist_add_int32_array(nvlist_t *nvl, const char *name, int32_t *a, uint_t n)
+{
+	return (nvlist_add_common(nvl, name, DATA_TYPE_INT32_ARRAY, n, a));
+}
+
+int
+nvlist_add_uint32_array(nvlist_t *nvl, const char *name, uint32_t *a, uint_t n)
+{
+	return (nvlist_add_common(nvl, name, DATA_TYPE_UINT32_ARRAY, n, a));
+}
+
+int
+nvlist_add_int64_array(nvlist_t *nvl, const char *name, int64_t *a, uint_t n)
+{
+	return (nvlist_add_common(nvl, name, DATA_TYPE_INT64_ARRAY, n, a));
+}
+
+int
+nvlist_add_uint64_array(nvlist_t *nvl, const char *name, uint64_t *a, uint_t n)
+{
+	return (nvlist_add_common(nvl, name, DATA_TYPE_UINT64_ARRAY, n, a));
+}
+
+int
+nvlist_add_string_array(nvlist_t *nvl, const char *name,
+    char *const *a, uint_t n)
+{
+	return (nvlist_add_common(nvl, name, DATA_TYPE_STRING_ARRAY, n, a));
+}
+
+int
+nvlist_add_hrtime(nvlist_t *nvl, const char *name, hrtime_t val)
+{
+	return (nvlist_add_common(nvl, name, DATA_TYPE_HRTIME, 1, &val));
+}
+
+int
+nvlist_add_nvlist(nvlist_t *nvl, const char *name, nvlist_t *val)
+{
+	return (nvlist_add_common(nvl, name, DATA_TYPE_NVLIST, 1, val));
+}
+
+int
+nvlist_add_nvlist_array(nvlist_t *nvl, const char *name, nvlist_t **a, uint_t n)
+{
+	return (nvlist_add_common(nvl, name, DATA_TYPE_NVLIST_ARRAY, n, a));
+}
+
+/* reading name-value pairs */
+nvpair_t *
+nvlist_next_nvpair(nvlist_t *nvl, nvpair_t *nvp)
+{
+	nvpriv_t *priv;
+	i_nvp_t *curr;
+
+	if (nvl == NULL ||
+	    (priv = (nvpriv_t *)(uintptr_t)nvl->nvl_priv) == NULL)
+		return (NULL);
+
+	curr = NVPAIR2I_NVP(nvp);
+
+	/*
+	 * Ensure that nvp is a valid nvpair on this nvlist.
+	 * NB: nvp_curr is used only as a hint so that we don't always
+	 * have to walk the list to determine if nvp is still on the list.
+	 */
+	if (nvp == NULL)
+		curr = priv->nvp_list;
+	else if (priv->nvp_curr == curr || nvlist_contains_nvp(nvl, nvp))
+		curr = curr->nvi_next;
+	else
+		curr = NULL;
+
+	priv->nvp_curr = curr;
+
+	return (curr != NULL ? &curr->nvi_nvp : NULL);
+}
+
+nvpair_t *
+nvlist_prev_nvpair(nvlist_t *nvl, nvpair_t *nvp)
+{
+	nvpriv_t *priv;
+	i_nvp_t *curr;
+
+	if (nvl == NULL ||
+	    (priv = (nvpriv_t *)(uintptr_t)nvl->nvl_priv) == NULL)
+		return (NULL);
+
+	curr = NVPAIR2I_NVP(nvp);
+
+	if (nvp == NULL)
+		curr = priv->nvp_last;
+	else if (priv->nvp_curr == curr || nvlist_contains_nvp(nvl, nvp))
+		curr = curr->nvi_prev;
+	else
+		curr = NULL;
+
+	priv->nvp_curr = curr;
+
+	return (curr != NULL ? &curr->nvi_nvp : NULL);
+}
+
+boolean_t
+nvlist_empty(nvlist_t *nvl)
+{
+	nvpriv_t *priv;
+
+	if (nvl == NULL ||
+	    (priv = (nvpriv_t *)(uintptr_t)nvl->nvl_priv) == NULL)
+		return (B_TRUE);
+
+	return (priv->nvp_list == NULL);
+}
+
+char *
+nvpair_name(nvpair_t *nvp)
+{
+	return (NVP_NAME(nvp));
+}
+
+data_type_t
+nvpair_type(nvpair_t *nvp)
+{
+	return (NVP_TYPE(nvp));
+}
+
+int
+nvpair_type_is_array(nvpair_t *nvp)
+{
+	data_type_t type = NVP_TYPE(nvp);
+
+	if ((type == DATA_TYPE_BYTE_ARRAY) ||
+	    (type == DATA_TYPE_UINT8_ARRAY) ||
+	    (type == DATA_TYPE_INT16_ARRAY) ||
+	    (type == DATA_TYPE_UINT16_ARRAY) ||
+	    (type == DATA_TYPE_INT32_ARRAY) ||
+	    (type == DATA_TYPE_UINT32_ARRAY) ||
+	    (type == DATA_TYPE_INT64_ARRAY) ||
+	    (type == DATA_TYPE_UINT64_ARRAY) ||
+	    (type == DATA_TYPE_BOOLEAN_ARRAY) ||
+	    (type == DATA_TYPE_STRING_ARRAY) ||
+	    (type == DATA_TYPE_NVLIST_ARRAY))
+		return (1);
+	return (0);
+
+}
+
+static int
+nvpair_value_common(nvpair_t *nvp, data_type_t type, uint_t *nelem, void *data)
+{
+	if (nvp == NULL || nvpair_type(nvp) != type)
+		return (EINVAL);
+
+	/*
+	 * For non-array types, we copy the data.
+	 * For array types (including string), we set a pointer.
+	 */
+	switch (type) {
+	case DATA_TYPE_BOOLEAN:
+		if (nelem != NULL)
+			*nelem = 0;
+		break;
+
+	case DATA_TYPE_BOOLEAN_VALUE:
+	case DATA_TYPE_BYTE:
+	case DATA_TYPE_INT8:
+	case DATA_TYPE_UINT8:
+	case DATA_TYPE_INT16:
+	case DATA_TYPE_UINT16:
+	case DATA_TYPE_INT32:
+	case DATA_TYPE_UINT32:
+	case DATA_TYPE_INT64:
+	case DATA_TYPE_UINT64:
+	case DATA_TYPE_HRTIME:
+#if !defined(_KERNEL)
+	case DATA_TYPE_DOUBLE:
+#endif
+		if (data == NULL)
+			return (EINVAL);
+		bcopy(NVP_VALUE(nvp), data,
+		    (size_t)i_get_value_size(type, NULL, 1));
+		if (nelem != NULL)
+			*nelem = 1;
+		break;
+
+	case DATA_TYPE_NVLIST:
+	case DATA_TYPE_STRING:
+		if (data == NULL)
+			return (EINVAL);
+		*(void **)data = (void *)NVP_VALUE(nvp);
+		if (nelem != NULL)
+			*nelem = 1;
+		break;
+
+	case DATA_TYPE_BOOLEAN_ARRAY:
+	case DATA_TYPE_BYTE_ARRAY:
+	case DATA_TYPE_INT8_ARRAY:
+	case DATA_TYPE_UINT8_ARRAY:
+	case DATA_TYPE_INT16_ARRAY:
+	case DATA_TYPE_UINT16_ARRAY:
+	case DATA_TYPE_INT32_ARRAY:
+	case DATA_TYPE_UINT32_ARRAY:
+	case DATA_TYPE_INT64_ARRAY:
+	case DATA_TYPE_UINT64_ARRAY:
+	case DATA_TYPE_STRING_ARRAY:
+	case DATA_TYPE_NVLIST_ARRAY:
+		if (nelem == NULL || data == NULL)
+			return (EINVAL);
+		if ((*nelem = NVP_NELEM(nvp)) != 0)
+			*(void **)data = (void *)NVP_VALUE(nvp);
+		else
+			*(void **)data = NULL;
+		break;
+
+	default:
+		return (ENOTSUP);
+	}
+
+	return (0);
+}
+
+static int
+nvlist_lookup_common(nvlist_t *nvl, const char *name, data_type_t type,
+    uint_t *nelem, void *data)
+{
+	nvpriv_t *priv;
+	nvpair_t *nvp;
+	i_nvp_t *curr;
+
+	if (name == NULL || nvl == NULL ||
+	    (priv = (nvpriv_t *)(uintptr_t)nvl->nvl_priv) == NULL)
+		return (EINVAL);
+
+	if (!(nvl->nvl_nvflag & (NV_UNIQUE_NAME | NV_UNIQUE_NAME_TYPE)))
+		return (ENOTSUP);
+
+	for (curr = priv->nvp_list; curr != NULL; curr = curr->nvi_next) {
+		nvp = &curr->nvi_nvp;
+
+		if (strcmp(name, NVP_NAME(nvp)) == 0 && NVP_TYPE(nvp) == type)
+			return (nvpair_value_common(nvp, type, nelem, data));
+	}
+
+	return (ENOENT);
+}
+
+int
+nvlist_lookup_boolean(nvlist_t *nvl, const char *name)
+{
+	return (nvlist_lookup_common(nvl, name, DATA_TYPE_BOOLEAN, NULL, NULL));
+}
+
+int
+nvlist_lookup_boolean_value(nvlist_t *nvl, const char *name, boolean_t *val)
+{
+	return (nvlist_lookup_common(nvl, name,
+	    DATA_TYPE_BOOLEAN_VALUE, NULL, val));
+}
+
+int
+nvlist_lookup_byte(nvlist_t *nvl, const char *name, uchar_t *val)
+{
+	return (nvlist_lookup_common(nvl, name, DATA_TYPE_BYTE, NULL, val));
+}
+
+int
+nvlist_lookup_int8(nvlist_t *nvl, const char *name, int8_t *val)
+{
+	return (nvlist_lookup_common(nvl, name, DATA_TYPE_INT8, NULL, val));
+}
+
+int
+nvlist_lookup_uint8(nvlist_t *nvl, const char *name, uint8_t *val)
+{
+	return (nvlist_lookup_common(nvl, name, DATA_TYPE_UINT8, NULL, val));
+}
+
+int
+nvlist_lookup_int16(nvlist_t *nvl, const char *name, int16_t *val)
+{
+	return (nvlist_lookup_common(nvl, name, DATA_TYPE_INT16, NULL, val));
+}
+
+int
+nvlist_lookup_uint16(nvlist_t *nvl, const char *name, uint16_t *val)
+{
+	return (nvlist_lookup_common(nvl, name, DATA_TYPE_UINT16, NULL, val));
+}
+
+int
+nvlist_lookup_int32(nvlist_t *nvl, const char *name, int32_t *val)
+{
+	return (nvlist_lookup_common(nvl, name, DATA_TYPE_INT32, NULL, val));
+}
+
+int
+nvlist_lookup_uint32(nvlist_t *nvl, const char *name, uint32_t *val)
+{
+	return (nvlist_lookup_common(nvl, name, DATA_TYPE_UINT32, NULL, val));
+}
+
+int
+nvlist_lookup_int64(nvlist_t *nvl, const char *name, int64_t *val)
+{
+	return (nvlist_lookup_common(nvl, name, DATA_TYPE_INT64, NULL, val));
+}
+
+int
+nvlist_lookup_uint64(nvlist_t *nvl, const char *name, uint64_t *val)
+{
+	return (nvlist_lookup_common(nvl, name, DATA_TYPE_UINT64, NULL, val));
+}
+
+#if !defined(_KERNEL)
+int
+nvlist_lookup_double(nvlist_t *nvl, const char *name, double *val)
+{
+	return (nvlist_lookup_common(nvl, name, DATA_TYPE_DOUBLE, NULL, val));
+}
+#endif
+
+int
+nvlist_lookup_string(nvlist_t *nvl, const char *name, char **val)
+{
+	return (nvlist_lookup_common(nvl, name, DATA_TYPE_STRING, NULL, val));
+}
+
+int
+nvlist_lookup_nvlist(nvlist_t *nvl, const char *name, nvlist_t **val)
+{
+	return (nvlist_lookup_common(nvl, name, DATA_TYPE_NVLIST, NULL, val));
+}
+
+int
+nvlist_lookup_boolean_array(nvlist_t *nvl, const char *name,
+    boolean_t **a, uint_t *n)
+{
+	return (nvlist_lookup_common(nvl, name,
+	    DATA_TYPE_BOOLEAN_ARRAY, n, a));
+}
+
+int
+nvlist_lookup_byte_array(nvlist_t *nvl, const char *name,
+    uchar_t **a, uint_t *n)
+{
+	return (nvlist_lookup_common(nvl, name, DATA_TYPE_BYTE_ARRAY, n, a));
+}
+
+int
+nvlist_lookup_int8_array(nvlist_t *nvl, const char *name, int8_t **a, uint_t *n)
+{
+	return (nvlist_lookup_common(nvl, name, DATA_TYPE_INT8_ARRAY, n, a));
+}
+
+int
+nvlist_lookup_uint8_array(nvlist_t *nvl, const char *name,
+    uint8_t **a, uint_t *n)
+{
+	return (nvlist_lookup_common(nvl, name, DATA_TYPE_UINT8_ARRAY, n, a));
+}
+
+int
+nvlist_lookup_int16_array(nvlist_t *nvl, const char *name,
+    int16_t **a, uint_t *n)
+{
+	return (nvlist_lookup_common(nvl, name, DATA_TYPE_INT16_ARRAY, n, a));
+}
+
+int
+nvlist_lookup_uint16_array(nvlist_t *nvl, const char *name,
+    uint16_t **a, uint_t *n)
+{
+	return (nvlist_lookup_common(nvl, name, DATA_TYPE_UINT16_ARRAY, n, a));
+}
+
+int
+nvlist_lookup_int32_array(nvlist_t *nvl, const char *name,
+    int32_t **a, uint_t *n)
+{
+	return (nvlist_lookup_common(nvl, name, DATA_TYPE_INT32_ARRAY, n, a));
+}
+
+int
+nvlist_lookup_uint32_array(nvlist_t *nvl, const char *name,
+    uint32_t **a, uint_t *n)
+{
+	return (nvlist_lookup_common(nvl, name, DATA_TYPE_UINT32_ARRAY, n, a));
+}
+
+int
+nvlist_lookup_int64_array(nvlist_t *nvl, const char *name,
+    int64_t **a, uint_t *n)
+{
+	return (nvlist_lookup_common(nvl, name, DATA_TYPE_INT64_ARRAY, n, a));
+}
+
+int
+nvlist_lookup_uint64_array(nvlist_t *nvl, const char *name,
+    uint64_t **a, uint_t *n)
+{
+	return (nvlist_lookup_common(nvl, name, DATA_TYPE_UINT64_ARRAY, n, a));
+}
+
+int
+nvlist_lookup_string_array(nvlist_t *nvl, const char *name,
+    char ***a, uint_t *n)
+{
+	return (nvlist_lookup_common(nvl, name, DATA_TYPE_STRING_ARRAY, n, a));
+}
+
+int
+nvlist_lookup_nvlist_array(nvlist_t *nvl, const char *name,
+    nvlist_t ***a, uint_t *n)
+{
+	return (nvlist_lookup_common(nvl, name, DATA_TYPE_NVLIST_ARRAY, n, a));
+}
+
+int
+nvlist_lookup_hrtime(nvlist_t *nvl, const char *name, hrtime_t *val)
+{
+	return (nvlist_lookup_common(nvl, name, DATA_TYPE_HRTIME, NULL, val));
+}
+
+int
+nvlist_lookup_pairs(nvlist_t *nvl, int flag, ...)
+{
+	va_list ap;
+	char *name;
+	int noentok = (flag & NV_FLAG_NOENTOK ? 1 : 0);
+	int ret = 0;
+
+	va_start(ap, flag);
+	while (ret == 0 && (name = va_arg(ap, char *)) != NULL) {
+		data_type_t type;
+		void *val;
+		uint_t *nelem;
+
+		switch (type = va_arg(ap, data_type_t)) {
+		case DATA_TYPE_BOOLEAN:
+			ret = nvlist_lookup_common(nvl, name, type, NULL, NULL);
+			break;
+
+		case DATA_TYPE_BOOLEAN_VALUE:
+		case DATA_TYPE_BYTE:
+		case DATA_TYPE_INT8:
+		case DATA_TYPE_UINT8:
+		case DATA_TYPE_INT16:
+		case DATA_TYPE_UINT16:
+		case DATA_TYPE_INT32:
+		case DATA_TYPE_UINT32:
+		case DATA_TYPE_INT64:
+		case DATA_TYPE_UINT64:
+		case DATA_TYPE_HRTIME:
+		case DATA_TYPE_STRING:
+		case DATA_TYPE_NVLIST:
+#if !defined(_KERNEL)
+		case DATA_TYPE_DOUBLE:
+#endif
+			val = va_arg(ap, void *);
+			ret = nvlist_lookup_common(nvl, name, type, NULL, val);
+			break;
+
+		case DATA_TYPE_BYTE_ARRAY:
+		case DATA_TYPE_BOOLEAN_ARRAY:
+		case DATA_TYPE_INT8_ARRAY:
+		case DATA_TYPE_UINT8_ARRAY:
+		case DATA_TYPE_INT16_ARRAY:
+		case DATA_TYPE_UINT16_ARRAY:
+		case DATA_TYPE_INT32_ARRAY:
+		case DATA_TYPE_UINT32_ARRAY:
+		case DATA_TYPE_INT64_ARRAY:
+		case DATA_TYPE_UINT64_ARRAY:
+		case DATA_TYPE_STRING_ARRAY:
+		case DATA_TYPE_NVLIST_ARRAY:
+			val = va_arg(ap, void *);
+			nelem = va_arg(ap, uint_t *);
+			ret = nvlist_lookup_common(nvl, name, type, nelem, val);
+			break;
+
+		default:
+			ret = EINVAL;
+		}
+
+		if (ret == ENOENT && noentok)
+			ret = 0;
+	}
+	va_end(ap);
+
+	return (ret);
+}
+
+/*
+ * Find the 'name'ed nvpair in the nvlist 'nvl'. If 'name' found, the function
+ * returns zero and a pointer to the matching nvpair is returned in '*ret'
+ * (given 'ret' is non-NULL). If 'sep' is specified then 'name' will penitrate
+ * multiple levels of embedded nvlists, with 'sep' as the separator. As an
+ * example, if sep is '.', name might look like: "a" or "a.b" or "a.c[3]" or
+ * "a.d[3].e[1]".  This matches the C syntax for array embed (for convience,
+ * code also supports "a.d[3]e[1]" syntax).
+ *
+ * If 'ip' is non-NULL and the last name component is an array, return the
+ * value of the "...[index]" array index in *ip. For an array reference that
+ * is not indexed, *ip will be returned as -1. If there is a syntax error in
+ * 'name', and 'ep' is non-NULL then *ep will be set to point to the location
+ * inside the 'name' string where the syntax error was detected.
+ */
+static int
+nvlist_lookup_nvpair_ei_sep(nvlist_t *nvl, const char *name, const char sep,
+    nvpair_t **ret, int *ip, char **ep)
+{
+	nvpair_t	*nvp;
+	const char	*np;
+	char		*sepp = NULL;
+	char		*idxp, *idxep;
+	nvlist_t	**nva;
+	long		idx = 0;
+	int		n;
+
+	if (ip)
+		*ip = -1;			/* not indexed */
+	if (ep)
+		*ep = NULL;
+
+	if ((nvl == NULL) || (name == NULL))
+		return (EINVAL);
+
+	/* step through components of name */
+	for (np = name; np && *np; np = sepp) {
+		/* ensure unique names */
+		if (!(nvl->nvl_nvflag & NV_UNIQUE_NAME))
+			return (ENOTSUP);
+
+		/* skip white space */
+		skip_whitespace(np);
+		if (*np == 0)
+			break;
+
+		/* set 'sepp' to end of current component 'np' */
+		if (sep)
+			sepp = strchr(np, sep);
+		else
+			sepp = NULL;
+
+		/* find start of next "[ index ]..." */
+		idxp = strchr(np, '[');
+
+		/* if sepp comes first, set idxp to NULL */
+		if (sepp && idxp && (sepp < idxp))
+			idxp = NULL;
+
+		/*
+		 * At this point 'idxp' is set if there is an index
+		 * expected for the current component.
+		 */
+		if (idxp) {
+			/* set 'n' to length of current 'np' name component */
+			n = idxp++ - np;
+
+			/* keep sepp up to date for *ep use as we advance */
+			skip_whitespace(idxp);
+			sepp = idxp;
+
+			/* determine the index value */
+#if defined(_KERNEL) && !defined(_BOOT)
+			if (ddi_strtol(idxp, &idxep, 0, &idx))
+				goto fail;
+#else
+			idx = strtol(idxp, &idxep, 0);
+#endif
+			if (idxep == idxp)
+				goto fail;
+
+			/* keep sepp up to date for *ep use as we advance */
+			sepp = idxep;
+
+			/* skip white space index value and check for ']' */
+			skip_whitespace(sepp);
+			if (*sepp++ != ']')
+				goto fail;
+
+			/* for embedded arrays, support C syntax: "a[1].b" */
+			skip_whitespace(sepp);
+			if (sep && (*sepp == sep))
+				sepp++;
+		} else if (sepp) {
+			n = sepp++ - np;
+		} else {
+			n = strlen(np);
+		}
+
+		/* trim trailing whitespace by reducing length of 'np' */
+		if (n == 0)
+			goto fail;
+		for (n--; (np[n] == ' ') || (np[n] == '\t'); n--)
+			;
+		n++;
+
+		/* skip whitespace, and set sepp to NULL if complete */
+		if (sepp) {
+			skip_whitespace(sepp);
+			if (*sepp == 0)
+				sepp = NULL;
+		}
+
+		/*
+		 * At this point:
+		 * o  'n' is the length of current 'np' component.
+		 * o  'idxp' is set if there was an index, and value 'idx'.
+		 * o  'sepp' is set to the beginning of the next component,
+		 *    and set to NULL if we have no more components.
+		 *
+		 * Search for nvpair with matching component name.
+		 */
+		for (nvp = nvlist_next_nvpair(nvl, NULL); nvp != NULL;
+		    nvp = nvlist_next_nvpair(nvl, nvp)) {
+
+			/* continue if no match on name */
+			if (strncmp(np, nvpair_name(nvp), n) ||
+			    (strlen(nvpair_name(nvp)) != n))
+				continue;
+
+			/* if indexed, verify type is array oriented */
+			if (idxp && !nvpair_type_is_array(nvp))
+				goto fail;
+
+			/*
+			 * Full match found, return nvp and idx if this
+			 * was the last component.
+			 */
+			if (sepp == NULL) {
+				if (ret)
+					*ret = nvp;
+				if (ip && idxp)
+					*ip = (int)idx;	/* return index */
+				return (0);		/* found */
+			}
+
+			/*
+			 * More components: current match must be
+			 * of DATA_TYPE_NVLIST or DATA_TYPE_NVLIST_ARRAY
+			 * to support going deeper.
+			 */
+			if (nvpair_type(nvp) == DATA_TYPE_NVLIST) {
+				nvl = EMBEDDED_NVL(nvp);
+				break;
+			} else if (nvpair_type(nvp) == DATA_TYPE_NVLIST_ARRAY) {
+				(void) nvpair_value_nvlist_array(nvp,
+				    &nva, (uint_t *)&n);
+				if ((n < 0) || (idx >= n))
+					goto fail;
+				nvl = nva[idx];
+				break;
+			}
+
+			/* type does not support more levels */
+			goto fail;
+		}
+		if (nvp == NULL)
+			goto fail;		/* 'name' not found */
+
+		/* search for match of next component in embedded 'nvl' list */
+	}
+
+fail:	if (ep && sepp)
+		*ep = sepp;
+	return (EINVAL);
+}
+
+/*
+ * Return pointer to nvpair with specified 'name'.
+ */
+int
+nvlist_lookup_nvpair(nvlist_t *nvl, const char *name, nvpair_t **ret)
+{
+	return (nvlist_lookup_nvpair_ei_sep(nvl, name, 0, ret, NULL, NULL));
+}
+
+/*
+ * Determine if named nvpair exists in nvlist (use embedded separator of '.'
+ * and return array index).  See nvlist_lookup_nvpair_ei_sep for more detailed
+ * description.
+ */
+int nvlist_lookup_nvpair_embedded_index(nvlist_t *nvl,
+    const char *name, nvpair_t **ret, int *ip, char **ep)
+{
+	return (nvlist_lookup_nvpair_ei_sep(nvl, name, '.', ret, ip, ep));
+}
+
+boolean_t
+nvlist_exists(nvlist_t *nvl, const char *name)
+{
+	nvpriv_t *priv;
+	nvpair_t *nvp;
+	i_nvp_t *curr;
+
+	if (name == NULL || nvl == NULL ||
+	    (priv = (nvpriv_t *)(uintptr_t)nvl->nvl_priv) == NULL)
+		return (B_FALSE);
+
+	for (curr = priv->nvp_list; curr != NULL; curr = curr->nvi_next) {
+		nvp = &curr->nvi_nvp;
+
+		if (strcmp(name, NVP_NAME(nvp)) == 0)
+			return (B_TRUE);
+	}
+
+	return (B_FALSE);
+}
+
+int
+nvpair_value_boolean_value(nvpair_t *nvp, boolean_t *val)
+{
+	return (nvpair_value_common(nvp, DATA_TYPE_BOOLEAN_VALUE, NULL, val));
+}
+
+int
+nvpair_value_byte(nvpair_t *nvp, uchar_t *val)
+{
+	return (nvpair_value_common(nvp, DATA_TYPE_BYTE, NULL, val));
+}
+
+int
+nvpair_value_int8(nvpair_t *nvp, int8_t *val)
+{
+	return (nvpair_value_common(nvp, DATA_TYPE_INT8, NULL, val));
+}
+
+int
+nvpair_value_uint8(nvpair_t *nvp, uint8_t *val)
+{
+	return (nvpair_value_common(nvp, DATA_TYPE_UINT8, NULL, val));
+}
+
+int
+nvpair_value_int16(nvpair_t *nvp, int16_t *val)
+{
+	return (nvpair_value_common(nvp, DATA_TYPE_INT16, NULL, val));
+}
+
+int
+nvpair_value_uint16(nvpair_t *nvp, uint16_t *val)
+{
+	return (nvpair_value_common(nvp, DATA_TYPE_UINT16, NULL, val));
+}
+
+int
+nvpair_value_int32(nvpair_t *nvp, int32_t *val)
+{
+	return (nvpair_value_common(nvp, DATA_TYPE_INT32, NULL, val));
+}
+
+int
+nvpair_value_uint32(nvpair_t *nvp, uint32_t *val)
+{
+	return (nvpair_value_common(nvp, DATA_TYPE_UINT32, NULL, val));
+}
+
+int
+nvpair_value_int64(nvpair_t *nvp, int64_t *val)
+{
+	return (nvpair_value_common(nvp, DATA_TYPE_INT64, NULL, val));
+}
+
+int
+nvpair_value_uint64(nvpair_t *nvp, uint64_t *val)
+{
+	return (nvpair_value_common(nvp, DATA_TYPE_UINT64, NULL, val));
+}
+
+#if !defined(_KERNEL)
+int
+nvpair_value_double(nvpair_t *nvp, double *val)
+{
+	return (nvpair_value_common(nvp, DATA_TYPE_DOUBLE, NULL, val));
+}
+#endif
+
+int
+nvpair_value_string(nvpair_t *nvp, char **val)
+{
+	return (nvpair_value_common(nvp, DATA_TYPE_STRING, NULL, val));
+}
+
+int
+nvpair_value_nvlist(nvpair_t *nvp, nvlist_t **val)
+{
+	return (nvpair_value_common(nvp, DATA_TYPE_NVLIST, NULL, val));
+}
+
+int
+nvpair_value_boolean_array(nvpair_t *nvp, boolean_t **val, uint_t *nelem)
+{
+	return (nvpair_value_common(nvp, DATA_TYPE_BOOLEAN_ARRAY, nelem, val));
+}
+
+int
+nvpair_value_byte_array(nvpair_t *nvp, uchar_t **val, uint_t *nelem)
+{
+	return (nvpair_value_common(nvp, DATA_TYPE_BYTE_ARRAY, nelem, val));
+}
+
+int
+nvpair_value_int8_array(nvpair_t *nvp, int8_t **val, uint_t *nelem)
+{
+	return (nvpair_value_common(nvp, DATA_TYPE_INT8_ARRAY, nelem, val));
+}
+
+int
+nvpair_value_uint8_array(nvpair_t *nvp, uint8_t **val, uint_t *nelem)
+{
+	return (nvpair_value_common(nvp, DATA_TYPE_UINT8_ARRAY, nelem, val));
+}
+
+int
+nvpair_value_int16_array(nvpair_t *nvp, int16_t **val, uint_t *nelem)
+{
+	return (nvpair_value_common(nvp, DATA_TYPE_INT16_ARRAY, nelem, val));
+}
+
+int
+nvpair_value_uint16_array(nvpair_t *nvp, uint16_t **val, uint_t *nelem)
+{
+	return (nvpair_value_common(nvp, DATA_TYPE_UINT16_ARRAY, nelem, val));
+}
+
+int
+nvpair_value_int32_array(nvpair_t *nvp, int32_t **val, uint_t *nelem)
+{
+	return (nvpair_value_common(nvp, DATA_TYPE_INT32_ARRAY, nelem, val));
+}
+
+int
+nvpair_value_uint32_array(nvpair_t *nvp, uint32_t **val, uint_t *nelem)
+{
+	return (nvpair_value_common(nvp, DATA_TYPE_UINT32_ARRAY, nelem, val));
+}
+
+int
+nvpair_value_int64_array(nvpair_t *nvp, int64_t **val, uint_t *nelem)
+{
+	return (nvpair_value_common(nvp, DATA_TYPE_INT64_ARRAY, nelem, val));
+}
+
+int
+nvpair_value_uint64_array(nvpair_t *nvp, uint64_t **val, uint_t *nelem)
+{
+	return (nvpair_value_common(nvp, DATA_TYPE_UINT64_ARRAY, nelem, val));
+}
+
+int
+nvpair_value_string_array(nvpair_t *nvp, char ***val, uint_t *nelem)
+{
+	return (nvpair_value_common(nvp, DATA_TYPE_STRING_ARRAY, nelem, val));
+}
+
+int
+nvpair_value_nvlist_array(nvpair_t *nvp, nvlist_t ***val, uint_t *nelem)
+{
+	return (nvpair_value_common(nvp, DATA_TYPE_NVLIST_ARRAY, nelem, val));
+}
+
+int
+nvpair_value_hrtime(nvpair_t *nvp, hrtime_t *val)
+{
+	return (nvpair_value_common(nvp, DATA_TYPE_HRTIME, NULL, val));
+}
+
+/*
+ * Add specified pair to the list.
+ */
+int
+nvlist_add_nvpair(nvlist_t *nvl, nvpair_t *nvp)
+{
+	if (nvl == NULL || nvp == NULL)
+		return (EINVAL);
+
+	return (nvlist_add_common(nvl, NVP_NAME(nvp), NVP_TYPE(nvp),
+	    NVP_NELEM(nvp), NVP_VALUE(nvp)));
+}
+
+/*
+ * Merge the supplied nvlists and put the result in dst.
+ * The merged list will contain all names specified in both lists,
+ * the values are taken from nvl in the case of duplicates.
+ * Return 0 on success.
+ */
+/*ARGSUSED*/
+int
+nvlist_merge(nvlist_t *dst, nvlist_t *nvl, int flag)
+{
+	if (nvl == NULL || dst == NULL)
+		return (EINVAL);
+
+	if (dst != nvl)
+		return (nvlist_copy_pairs(nvl, dst));
+
+	return (0);
+}
+
+/*
+ * Encoding related routines
+ */
+#define	NVS_OP_ENCODE	0
+#define	NVS_OP_DECODE	1
+#define	NVS_OP_GETSIZE	2
+
+typedef struct nvs_ops nvs_ops_t;
+
+typedef struct {
+	int		nvs_op;
+	const nvs_ops_t	*nvs_ops;
+	void		*nvs_private;
+	nvpriv_t	*nvs_priv;
+} nvstream_t;
+
+/*
+ * nvs operations are:
+ *   - nvs_nvlist
+ *     encoding / decoding of a nvlist header (nvlist_t)
+ *     calculates the size used for header and end detection
+ *
+ *   - nvs_nvpair
+ *     responsible for the first part of encoding / decoding of an nvpair
+ *     calculates the decoded size of an nvpair
+ *
+ *   - nvs_nvp_op
+ *     second part of encoding / decoding of an nvpair
+ *
+ *   - nvs_nvp_size
+ *     calculates the encoding size of an nvpair
+ *
+ *   - nvs_nvl_fini
+ *     encodes the end detection mark (zeros).
+ */
+struct nvs_ops {
+	int (*nvs_nvlist)(nvstream_t *, nvlist_t *, size_t *);
+	int (*nvs_nvpair)(nvstream_t *, nvpair_t *, size_t *);
+	int (*nvs_nvp_op)(nvstream_t *, nvpair_t *);
+	int (*nvs_nvp_size)(nvstream_t *, nvpair_t *, size_t *);
+	int (*nvs_nvl_fini)(nvstream_t *);
+};
+
+typedef struct {
+	char	nvh_encoding;	/* nvs encoding method */
+	char	nvh_endian;	/* nvs endian */
+	char	nvh_reserved1;	/* reserved for future use */
+	char	nvh_reserved2;	/* reserved for future use */
+} nvs_header_t;
+
+static int
+nvs_encode_pairs(nvstream_t *nvs, nvlist_t *nvl)
+{
+	nvpriv_t *priv = (nvpriv_t *)(uintptr_t)nvl->nvl_priv;
+	i_nvp_t *curr;
+
+	/*
+	 * Walk nvpair in list and encode each nvpair
+	 */
+	for (curr = priv->nvp_list; curr != NULL; curr = curr->nvi_next)
+		if (nvs->nvs_ops->nvs_nvpair(nvs, &curr->nvi_nvp, NULL) != 0)
+			return (EFAULT);
+
+	return (nvs->nvs_ops->nvs_nvl_fini(nvs));
+}
+
+static int
+nvs_decode_pairs(nvstream_t *nvs, nvlist_t *nvl)
+{
+	nvpair_t *nvp;
+	size_t nvsize;
+	int err;
+
+	/*
+	 * Get decoded size of next pair in stream, alloc
+	 * memory for nvpair_t, then decode the nvpair
+	 */
+	while ((err = nvs->nvs_ops->nvs_nvpair(nvs, NULL, &nvsize)) == 0) {
+		if (nvsize == 0) /* end of list */
+			break;
+
+		/* make sure len makes sense */
+		if (nvsize < NVP_SIZE_CALC(1, 0))
+			return (EFAULT);
+
+		if ((nvp = nvp_buf_alloc(nvl, nvsize)) == NULL)
+			return (ENOMEM);
+
+		if ((err = nvs->nvs_ops->nvs_nvp_op(nvs, nvp)) != 0) {
+			nvp_buf_free(nvl, nvp);
+			return (err);
+		}
+
+		if (i_validate_nvpair(nvp) != 0) {
+			nvpair_free(nvp);
+			nvp_buf_free(nvl, nvp);
+			return (EFAULT);
+		}
+
+		nvp_buf_link(nvl, nvp);
+	}
+	return (err);
+}
+
+static int
+nvs_getsize_pairs(nvstream_t *nvs, nvlist_t *nvl, size_t *buflen)
+{
+	nvpriv_t *priv = (nvpriv_t *)(uintptr_t)nvl->nvl_priv;
+	i_nvp_t *curr;
+	uint64_t nvsize = *buflen;
+	size_t size;
+
+	/*
+	 * Get encoded size of nvpairs in nvlist
+	 */
+	for (curr = priv->nvp_list; curr != NULL; curr = curr->nvi_next) {
+		if (nvs->nvs_ops->nvs_nvp_size(nvs, &curr->nvi_nvp, &size) != 0)
+			return (EINVAL);
+
+		if ((nvsize += size) > INT32_MAX)
+			return (EINVAL);
+	}
+
+	*buflen = nvsize;
+	return (0);
+}
+
+static int
+nvs_operation(nvstream_t *nvs, nvlist_t *nvl, size_t *buflen)
+{
+	int err;
+
+	if (nvl->nvl_priv == 0)
+		return (EFAULT);
+
+	/*
+	 * Perform the operation, starting with header, then each nvpair
+	 */
+	if ((err = nvs->nvs_ops->nvs_nvlist(nvs, nvl, buflen)) != 0)
+		return (err);
+
+	switch (nvs->nvs_op) {
+	case NVS_OP_ENCODE:
+		err = nvs_encode_pairs(nvs, nvl);
+		break;
+
+	case NVS_OP_DECODE:
+		err = nvs_decode_pairs(nvs, nvl);
+		break;
+
+	case NVS_OP_GETSIZE:
+		err = nvs_getsize_pairs(nvs, nvl, buflen);
+		break;
+
+	default:
+		err = EINVAL;
+	}
+
+	return (err);
+}
+
+static int
+nvs_embedded(nvstream_t *nvs, nvlist_t *embedded)
+{
+	switch (nvs->nvs_op) {
+	case NVS_OP_ENCODE:
+		return (nvs_operation(nvs, embedded, NULL));
+
+	case NVS_OP_DECODE: {
+		nvpriv_t *priv;
+		int err;
+
+		if (embedded->nvl_version != NV_VERSION)
+			return (ENOTSUP);
+
+		if ((priv = nv_priv_alloc_embedded(nvs->nvs_priv)) == NULL)
+			return (ENOMEM);
+
+		nvlist_init(embedded, embedded->nvl_nvflag, priv);
+
+		if ((err = nvs_operation(nvs, embedded, NULL)) != 0)
+			nvlist_free(embedded);
+		return (err);
+	}
+	default:
+		break;
+	}
+
+	return (EINVAL);
+}
+
+static int
+nvs_embedded_nvl_array(nvstream_t *nvs, nvpair_t *nvp, size_t *size)
+{
+	size_t nelem = NVP_NELEM(nvp);
+	nvlist_t **nvlp = EMBEDDED_NVL_ARRAY(nvp);
+	int i;
+
+	switch (nvs->nvs_op) {
+	case NVS_OP_ENCODE:
+		for (i = 0; i < nelem; i++)
+			if (nvs_embedded(nvs, nvlp[i]) != 0)
+				return (EFAULT);
+		break;
+
+	case NVS_OP_DECODE: {
+		size_t len = nelem * sizeof (uint64_t);
+		nvlist_t *embedded = (nvlist_t *)((uintptr_t)nvlp + len);
+
+		bzero(nvlp, len);	/* don't trust packed data */
+		for (i = 0; i < nelem; i++) {
+			if (nvs_embedded(nvs, embedded) != 0) {
+				nvpair_free(nvp);
+				return (EFAULT);
+			}
+
+			nvlp[i] = embedded++;
+		}
+		break;
+	}
+	case NVS_OP_GETSIZE: {
+		uint64_t nvsize = 0;
+
+		for (i = 0; i < nelem; i++) {
+			size_t nvp_sz = 0;
+
+			if (nvs_operation(nvs, nvlp[i], &nvp_sz) != 0)
+				return (EINVAL);
+
+			if ((nvsize += nvp_sz) > INT32_MAX)
+				return (EINVAL);
+		}
+
+		*size = nvsize;
+		break;
+	}
+	default:
+		return (EINVAL);
+	}
+
+	return (0);
+}
+
+static int nvs_native(nvstream_t *, nvlist_t *, char *, size_t *);
+static int nvs_xdr(nvstream_t *, nvlist_t *, char *, size_t *);
+
+/*
+ * Common routine for nvlist operations:
+ * encode, decode, getsize (encoded size).
+ */
+static int
+nvlist_common(nvlist_t *nvl, char *buf, size_t *buflen, int encoding,
+    int nvs_op)
+{
+	int err = 0;
+	nvstream_t nvs;
+	int nvl_endian;
+#ifdef	_LITTLE_ENDIAN
+	int host_endian = 1;
+#else
+	int host_endian = 0;
+#endif	/* _LITTLE_ENDIAN */
+	nvs_header_t *nvh = (void *)buf;
+
+	if (buflen == NULL || nvl == NULL ||
+	    (nvs.nvs_priv = (nvpriv_t *)(uintptr_t)nvl->nvl_priv) == NULL)
+		return (EINVAL);
+
+	nvs.nvs_op = nvs_op;
+
+	/*
+	 * For NVS_OP_ENCODE and NVS_OP_DECODE make sure an nvlist and
+	 * a buffer is allocated.  The first 4 bytes in the buffer are
+	 * used for encoding method and host endian.
+	 */
+	switch (nvs_op) {
+	case NVS_OP_ENCODE:
+		if (buf == NULL || *buflen < sizeof (nvs_header_t))
+			return (EINVAL);
+
+		nvh->nvh_encoding = encoding;
+		nvh->nvh_endian = nvl_endian = host_endian;
+		nvh->nvh_reserved1 = 0;
+		nvh->nvh_reserved2 = 0;
+		break;
+
+	case NVS_OP_DECODE:
+		if (buf == NULL || *buflen < sizeof (nvs_header_t))
+			return (EINVAL);
+
+		/* get method of encoding from first byte */
+		encoding = nvh->nvh_encoding;
+		nvl_endian = nvh->nvh_endian;
+		break;
+
+	case NVS_OP_GETSIZE:
+		nvl_endian = host_endian;
+
+		/*
+		 * add the size for encoding
+		 */
+		*buflen = sizeof (nvs_header_t);
+		break;
+
+	default:
+		return (ENOTSUP);
+	}
+
+	/*
+	 * Create an nvstream with proper encoding method
+	 */
+	switch (encoding) {
+	case NV_ENCODE_NATIVE:
+		/*
+		 * check endianness, in case we are unpacking
+		 * from a file
+		 */
+		if (nvl_endian != host_endian)
+			return (ENOTSUP);
+		err = nvs_native(&nvs, nvl, buf, buflen);
+		break;
+	case NV_ENCODE_XDR:
+		err = nvs_xdr(&nvs, nvl, buf, buflen);
+		break;
+	default:
+		err = ENOTSUP;
+		break;
+	}
+
+	return (err);
+}
+
+int
+nvlist_size(nvlist_t *nvl, size_t *size, int encoding)
+{
+	return (nvlist_common(nvl, NULL, size, encoding, NVS_OP_GETSIZE));
+}
+
+/*
+ * Pack nvlist into contiguous memory
+ */
+int
+nvlist_pack(nvlist_t *nvl, char **bufp, size_t *buflen, int encoding,
+    int kmflag)
+{
+	return (nvlist_xpack(nvl, bufp, buflen, encoding,
+	    nvlist_nv_alloc(kmflag)));
+}
+
+int
+nvlist_xpack(nvlist_t *nvl, char **bufp, size_t *buflen, int encoding,
+    nv_alloc_t *nva)
+{
+	nvpriv_t nvpriv;
+	size_t alloc_size;
+	char *buf;
+	int err;
+
+	if (nva == NULL || nvl == NULL || bufp == NULL || buflen == NULL)
+		return (EINVAL);
+
+	if (*bufp != NULL)
+		return (nvlist_common(nvl, *bufp, buflen, encoding,
+		    NVS_OP_ENCODE));
+
+	/*
+	 * Here is a difficult situation:
+	 * 1. The nvlist has fixed allocator properties.
+	 *    All other nvlist routines (like nvlist_add_*, ...) use
+	 *    these properties.
+	 * 2. When using nvlist_pack() the user can specify his own
+	 *    allocator properties (e.g. by using KM_NOSLEEP).
+	 *
+	 * We use the user specified properties (2). A clearer solution
+	 * will be to remove the kmflag from nvlist_pack(), but we will
+	 * not change the interface.
+	 */
+	nv_priv_init(&nvpriv, nva, 0);
+
+	if ((err = nvlist_size(nvl, &alloc_size, encoding)))
+		return (err);
+
+	if ((buf = nv_mem_zalloc(&nvpriv, alloc_size)) == NULL)
+		return (ENOMEM);
+
+	if ((err = nvlist_common(nvl, buf, &alloc_size, encoding,
+	    NVS_OP_ENCODE)) != 0) {
+		nv_mem_free(&nvpriv, buf, alloc_size);
+	} else {
+		*buflen = alloc_size;
+		*bufp = buf;
+	}
+
+	return (err);
+}
+
+/*
+ * Unpack buf into an nvlist_t
+ */
+int
+nvlist_unpack(char *buf, size_t buflen, nvlist_t **nvlp, int kmflag)
+{
+	return (nvlist_xunpack(buf, buflen, nvlp, nvlist_nv_alloc(kmflag)));
+}
+
+int
+nvlist_xunpack(char *buf, size_t buflen, nvlist_t **nvlp, nv_alloc_t *nva)
+{
+	nvlist_t *nvl;
+	int err;
+
+	if (nvlp == NULL)
+		return (EINVAL);
+
+	if ((err = nvlist_xalloc(&nvl, 0, nva)) != 0)
+		return (err);
+
+	if ((err = nvlist_common(nvl, buf, &buflen, 0, NVS_OP_DECODE)) != 0)
+		nvlist_free(nvl);
+	else
+		*nvlp = nvl;
+
+	return (err);
+}
+
+/*
+ * Native encoding functions
+ */
+typedef struct {
+	/*
+	 * This structure is used when decoding a packed nvpair in
+	 * the native format.  n_base points to a buffer containing the
+	 * packed nvpair.  n_end is a pointer to the end of the buffer.
+	 * (n_end actually points to the first byte past the end of the
+	 * buffer.)  n_curr is a pointer that lies between n_base and n_end.
+	 * It points to the current data that we are decoding.
+	 * The amount of data left in the buffer is equal to n_end - n_curr.
+	 * n_flag is used to recognize a packed embedded list.
+	 */
+	caddr_t n_base;
+	caddr_t n_end;
+	caddr_t n_curr;
+	uint_t  n_flag;
+} nvs_native_t;
+
+static int
+nvs_native_create(nvstream_t *nvs, nvs_native_t *native, char *buf,
+    size_t buflen)
+{
+	switch (nvs->nvs_op) {
+	case NVS_OP_ENCODE:
+	case NVS_OP_DECODE:
+		nvs->nvs_private = native;
+		native->n_curr = native->n_base = buf;
+		native->n_end = buf + buflen;
+		native->n_flag = 0;
+		return (0);
+
+	case NVS_OP_GETSIZE:
+		nvs->nvs_private = native;
+		native->n_curr = native->n_base = native->n_end = NULL;
+		native->n_flag = 0;
+		return (0);
+	default:
+		return (EINVAL);
+	}
+}
+
+/*ARGSUSED*/
+static void
+nvs_native_destroy(nvstream_t *nvs)
+{
+}
+
+static int
+native_cp(nvstream_t *nvs, void *buf, size_t size)
+{
+	nvs_native_t *native = (nvs_native_t *)nvs->nvs_private;
+
+	if (native->n_curr + size > native->n_end)
+		return (EFAULT);
+
+	/*
+	 * The bcopy() below eliminates alignment requirement
+	 * on the buffer (stream) and is preferred over direct access.
+	 */
+	switch (nvs->nvs_op) {
+	case NVS_OP_ENCODE:
+		bcopy(buf, native->n_curr, size);
+		break;
+	case NVS_OP_DECODE:
+		bcopy(native->n_curr, buf, size);
+		break;
+	default:
+		return (EINVAL);
+	}
+
+	native->n_curr += size;
+	return (0);
+}
+
+/*
+ * operate on nvlist_t header
+ */
+static int
+nvs_native_nvlist(nvstream_t *nvs, nvlist_t *nvl, size_t *size)
+{
+	nvs_native_t *native = nvs->nvs_private;
+
+	switch (nvs->nvs_op) {
+	case NVS_OP_ENCODE:
+	case NVS_OP_DECODE:
+		if (native->n_flag)
+			return (0);	/* packed embedded list */
+
+		native->n_flag = 1;
+
+		/* copy version and nvflag of the nvlist_t */
+		if (native_cp(nvs, &nvl->nvl_version, sizeof (int32_t)) != 0 ||
+		    native_cp(nvs, &nvl->nvl_nvflag, sizeof (int32_t)) != 0)
+			return (EFAULT);
+
+		return (0);
+
+	case NVS_OP_GETSIZE:
+		/*
+		 * if calculate for packed embedded list
+		 * 	4 for end of the embedded list
+		 * else
+		 * 	2 * sizeof (int32_t) for nvl_version and nvl_nvflag
+		 * 	and 4 for end of the entire list
+		 */
+		if (native->n_flag) {
+			*size += 4;
+		} else {
+			native->n_flag = 1;
+			*size += 2 * sizeof (int32_t) + 4;
+		}
+
+		return (0);
+
+	default:
+		return (EINVAL);
+	}
+}
+
+static int
+nvs_native_nvl_fini(nvstream_t *nvs)
+{
+	if (nvs->nvs_op == NVS_OP_ENCODE) {
+		nvs_native_t *native = (nvs_native_t *)nvs->nvs_private;
+		/*
+		 * Add 4 zero bytes at end of nvlist. They are used
+		 * for end detection by the decode routine.
+		 */
+		if (native->n_curr + sizeof (int) > native->n_end)
+			return (EFAULT);
+
+		bzero(native->n_curr, sizeof (int));
+		native->n_curr += sizeof (int);
+	}
+
+	return (0);
+}
+
+static int
+nvpair_native_embedded(nvstream_t *nvs, nvpair_t *nvp)
+{
+	if (nvs->nvs_op == NVS_OP_ENCODE) {
+		nvs_native_t *native = (nvs_native_t *)nvs->nvs_private;
+		nvlist_t *packed = (void *)
+		    (native->n_curr - nvp->nvp_size + NVP_VALOFF(nvp));
+		/*
+		 * Null out the pointer that is meaningless in the packed
+		 * structure. The address may not be aligned, so we have
+		 * to use bzero.
+		 */
+		bzero((char *)packed + offsetof(nvlist_t, nvl_priv),
+		    sizeof (uint64_t));
+	}
+
+	return (nvs_embedded(nvs, EMBEDDED_NVL(nvp)));
+}
+
+static int
+nvpair_native_embedded_array(nvstream_t *nvs, nvpair_t *nvp)
+{
+	if (nvs->nvs_op == NVS_OP_ENCODE) {
+		nvs_native_t *native = (nvs_native_t *)nvs->nvs_private;
+		char *value = native->n_curr - nvp->nvp_size + NVP_VALOFF(nvp);
+		size_t len = NVP_NELEM(nvp) * sizeof (uint64_t);
+		nvlist_t *packed = (nvlist_t *)((uintptr_t)value + len);
+		int i;
+		/*
+		 * Null out pointers that are meaningless in the packed
+		 * structure. The addresses may not be aligned, so we have
+		 * to use bzero.
+		 */
+		bzero(value, len);
+
+		for (i = 0; i < NVP_NELEM(nvp); i++, packed++)
+			/*
+			 * Null out the pointer that is meaningless in the
+			 * packed structure. The address may not be aligned,
+			 * so we have to use bzero.
+			 */
+			bzero((char *)packed + offsetof(nvlist_t, nvl_priv),
+			    sizeof (uint64_t));
+	}
+
+	return (nvs_embedded_nvl_array(nvs, nvp, NULL));
+}
+
+static void
+nvpair_native_string_array(nvstream_t *nvs, nvpair_t *nvp)
+{
+	switch (nvs->nvs_op) {
+	case NVS_OP_ENCODE: {
+		nvs_native_t *native = (nvs_native_t *)nvs->nvs_private;
+		uint64_t *strp = (void *)
+		    (native->n_curr - nvp->nvp_size + NVP_VALOFF(nvp));
+		/*
+		 * Null out pointers that are meaningless in the packed
+		 * structure. The addresses may not be aligned, so we have
+		 * to use bzero.
+		 */
+		bzero(strp, NVP_NELEM(nvp) * sizeof (uint64_t));
+		break;
+	}
+	case NVS_OP_DECODE: {
+		char **strp = (void *)NVP_VALUE(nvp);
+		char *buf = ((char *)strp + NVP_NELEM(nvp) * sizeof (uint64_t));
+		int i;
+
+		for (i = 0; i < NVP_NELEM(nvp); i++) {
+			strp[i] = buf;
+			buf += strlen(buf) + 1;
+		}
+		break;
+	}
+	}
+}
+
+static int
+nvs_native_nvp_op(nvstream_t *nvs, nvpair_t *nvp)
+{
+	data_type_t type;
+	int value_sz;
+	int ret = 0;
+
+	/*
+	 * We do the initial bcopy of the data before we look at
+	 * the nvpair type, because when we're decoding, we won't
+	 * have the correct values for the pair until we do the bcopy.
+	 */
+	switch (nvs->nvs_op) {
+	case NVS_OP_ENCODE:
+	case NVS_OP_DECODE:
+		if (native_cp(nvs, nvp, nvp->nvp_size) != 0)
+			return (EFAULT);
+		break;
+	default:
+		return (EINVAL);
+	}
+
+	/* verify nvp_name_sz, check the name string length */
+	if (i_validate_nvpair_name(nvp) != 0)
+		return (EFAULT);
+
+	type = NVP_TYPE(nvp);
+
+	/*
+	 * Verify type and nelem and get the value size.
+	 * In case of data types DATA_TYPE_STRING and DATA_TYPE_STRING_ARRAY
+	 * is the size of the string(s) excluded.
+	 */
+	if ((value_sz = i_get_value_size(type, NULL, NVP_NELEM(nvp))) < 0)
+		return (EFAULT);
+
+	if (NVP_SIZE_CALC(nvp->nvp_name_sz, value_sz) > nvp->nvp_size)
+		return (EFAULT);
+
+	switch (type) {
+	case DATA_TYPE_NVLIST:
+		ret = nvpair_native_embedded(nvs, nvp);
+		break;
+	case DATA_TYPE_NVLIST_ARRAY:
+		ret = nvpair_native_embedded_array(nvs, nvp);
+		break;
+	case DATA_TYPE_STRING_ARRAY:
+		nvpair_native_string_array(nvs, nvp);
+		break;
+	default:
+		break;
+	}
+
+	return (ret);
+}
+
+static int
+nvs_native_nvp_size(nvstream_t *nvs, nvpair_t *nvp, size_t *size)
+{
+	uint64_t nvp_sz = nvp->nvp_size;
+
+	switch (NVP_TYPE(nvp)) {
+	case DATA_TYPE_NVLIST: {
+		size_t nvsize = 0;
+
+		if (nvs_operation(nvs, EMBEDDED_NVL(nvp), &nvsize) != 0)
+			return (EINVAL);
+
+		nvp_sz += nvsize;
+		break;
+	}
+	case DATA_TYPE_NVLIST_ARRAY: {
+		size_t nvsize;
+
+		if (nvs_embedded_nvl_array(nvs, nvp, &nvsize) != 0)
+			return (EINVAL);
+
+		nvp_sz += nvsize;
+		break;
+	}
+	default:
+		break;
+	}
+
+	if (nvp_sz > INT32_MAX)
+		return (EINVAL);
+
+	*size = nvp_sz;
+
+	return (0);
+}
+
+static int
+nvs_native_nvpair(nvstream_t *nvs, nvpair_t *nvp, size_t *size)
+{
+	switch (nvs->nvs_op) {
+	case NVS_OP_ENCODE:
+		return (nvs_native_nvp_op(nvs, nvp));
+
+	case NVS_OP_DECODE: {
+		nvs_native_t *native = (nvs_native_t *)nvs->nvs_private;
+		int32_t decode_len;
+
+		/* try to read the size value from the stream */
+		if (native->n_curr + sizeof (int32_t) > native->n_end)
+			return (EFAULT);
+		bcopy(native->n_curr, &decode_len, sizeof (int32_t));
+
+		/* sanity check the size value */
+		if (decode_len < 0 ||
+		    decode_len > native->n_end - native->n_curr)
+			return (EFAULT);
+
+		*size = decode_len;
+
+		/*
+		 * If at the end of the stream then move the cursor
+		 * forward, otherwise nvpair_native_op() will read
+		 * the entire nvpair at the same cursor position.
+		 */
+		if (*size == 0)
+			native->n_curr += sizeof (int32_t);
+		break;
+	}
+
+	default:
+		return (EINVAL);
+	}
+
+	return (0);
+}
+
+static const nvs_ops_t nvs_native_ops = {
+	nvs_native_nvlist,
+	nvs_native_nvpair,
+	nvs_native_nvp_op,
+	nvs_native_nvp_size,
+	nvs_native_nvl_fini
+};
+
+static int
+nvs_native(nvstream_t *nvs, nvlist_t *nvl, char *buf, size_t *buflen)
+{
+	nvs_native_t native;
+	int err;
+
+	nvs->nvs_ops = &nvs_native_ops;
+
+	if ((err = nvs_native_create(nvs, &native, buf + sizeof (nvs_header_t),
+	    *buflen - sizeof (nvs_header_t))) != 0)
+		return (err);
+
+	err = nvs_operation(nvs, nvl, buflen);
+
+	nvs_native_destroy(nvs);
+
+	return (err);
+}
+
+/*
+ * XDR encoding functions
+ *
+ * An xdr packed nvlist is encoded as:
+ *
+ *  - encoding methode and host endian (4 bytes)
+ *  - nvl_version (4 bytes)
+ *  - nvl_nvflag (4 bytes)
+ *
+ *  - encoded nvpairs, the format of one xdr encoded nvpair is:
+ *	- encoded size of the nvpair (4 bytes)
+ *	- decoded size of the nvpair (4 bytes)
+ *	- name string, (4 + sizeof(NV_ALIGN4(string))
+ *	  a string is coded as size (4 bytes) and data
+ *	- data type (4 bytes)
+ *	- number of elements in the nvpair (4 bytes)
+ *	- data
+ *
+ *  - 2 zero's for end of the entire list (8 bytes)
+ */
+static int
+nvs_xdr_create(nvstream_t *nvs, XDR *xdr, char *buf, size_t buflen)
+{
+	/* xdr data must be 4 byte aligned */
+	if ((ulong_t)buf % 4 != 0)
+		return (EFAULT);
+
+	switch (nvs->nvs_op) {
+	case NVS_OP_ENCODE:
+		xdrmem_create(xdr, buf, (uint_t)buflen, XDR_ENCODE);
+		nvs->nvs_private = xdr;
+		return (0);
+	case NVS_OP_DECODE:
+		xdrmem_create(xdr, buf, (uint_t)buflen, XDR_DECODE);
+		nvs->nvs_private = xdr;
+		return (0);
+	case NVS_OP_GETSIZE:
+		nvs->nvs_private = NULL;
+		return (0);
+	default:
+		return (EINVAL);
+	}
+}
+
+static void
+nvs_xdr_destroy(nvstream_t *nvs)
+{
+	switch (nvs->nvs_op) {
+	case NVS_OP_ENCODE:
+	case NVS_OP_DECODE:
+		xdr_destroy((XDR *)nvs->nvs_private);
+		break;
+	default:
+		break;
+	}
+}
+
+static int
+nvs_xdr_nvlist(nvstream_t *nvs, nvlist_t *nvl, size_t *size)
+{
+	switch (nvs->nvs_op) {
+	case NVS_OP_ENCODE:
+	case NVS_OP_DECODE: {
+		XDR 	*xdr = nvs->nvs_private;
+
+		if (!xdr_int(xdr, &nvl->nvl_version) ||
+		    !xdr_u_int(xdr, &nvl->nvl_nvflag))
+			return (EFAULT);
+		break;
+	}
+	case NVS_OP_GETSIZE: {
+		/*
+		 * 2 * 4 for nvl_version + nvl_nvflag
+		 * and 8 for end of the entire list
+		 */
+		*size += 2 * 4 + 8;
+		break;
+	}
+	default:
+		return (EINVAL);
+	}
+	return (0);
+}
+
+static int
+nvs_xdr_nvl_fini(nvstream_t *nvs)
+{
+	if (nvs->nvs_op == NVS_OP_ENCODE) {
+		XDR *xdr = nvs->nvs_private;
+		int zero = 0;
+
+		if (!xdr_int(xdr, &zero) || !xdr_int(xdr, &zero))
+			return (EFAULT);
+	}
+
+	return (0);
+}
+
+/*
+ * The format of xdr encoded nvpair is:
+ * encode_size, decode_size, name string, data type, nelem, data
+ */
+static int
+nvs_xdr_nvp_op(nvstream_t *nvs, nvpair_t *nvp)
+{
+	data_type_t type;
+	char	*buf;
+	char	*buf_end = (char *)nvp + nvp->nvp_size;
+	int	value_sz;
+	uint_t	nelem, buflen;
+	bool_t	ret = FALSE;
+	XDR	*xdr = nvs->nvs_private;
+
+	ASSERT(xdr != NULL && nvp != NULL);
+
+	/* name string */
+	if ((buf = NVP_NAME(nvp)) >= buf_end)
+		return (EFAULT);
+	buflen = buf_end - buf;
+
+	if (!xdr_string(xdr, &buf, buflen - 1))
+		return (EFAULT);
+	nvp->nvp_name_sz = strlen(buf) + 1;
+
+	/* type and nelem */
+	if (!xdr_int(xdr, (int *)&nvp->nvp_type) ||
+	    !xdr_int(xdr, &nvp->nvp_value_elem))
+		return (EFAULT);
+
+	type = NVP_TYPE(nvp);
+	nelem = nvp->nvp_value_elem;
+
+	/*
+	 * Verify type and nelem and get the value size.
+	 * In case of data types DATA_TYPE_STRING and DATA_TYPE_STRING_ARRAY
+	 * is the size of the string(s) excluded.
+	 */
+	if ((value_sz = i_get_value_size(type, NULL, nelem)) < 0)
+		return (EFAULT);
+
+	/* if there is no data to extract then return */
+	if (nelem == 0)
+		return (0);
+
+	/* value */
+	if ((buf = NVP_VALUE(nvp)) >= buf_end)
+		return (EFAULT);
+	buflen = buf_end - buf;
+
+	if (buflen < value_sz)
+		return (EFAULT);
+
+	switch (type) {
+	case DATA_TYPE_NVLIST:
+		if (nvs_embedded(nvs, (void *)buf) == 0)
+			return (0);
+		break;
+
+	case DATA_TYPE_NVLIST_ARRAY:
+		if (nvs_embedded_nvl_array(nvs, nvp, NULL) == 0)
+			return (0);
+		break;
+
+	case DATA_TYPE_BOOLEAN:
+		ret = TRUE;
+		break;
+
+	case DATA_TYPE_BYTE:
+	case DATA_TYPE_INT8:
+	case DATA_TYPE_UINT8:
+		ret = xdr_char(xdr, buf);
+		break;
+
+	case DATA_TYPE_INT16:
+		ret = xdr_short(xdr, (void *)buf);
+		break;
+
+	case DATA_TYPE_UINT16:
+		ret = xdr_u_short(xdr, (void *)buf);
+		break;
+
+	case DATA_TYPE_BOOLEAN_VALUE:
+	case DATA_TYPE_INT32:
+		ret = xdr_int(xdr, (void *)buf);
+		break;
+
+	case DATA_TYPE_UINT32:
+		ret = xdr_u_int(xdr, (void *)buf);
+		break;
+
+	case DATA_TYPE_INT64:
+		ret = xdr_longlong_t(xdr, (void *)buf);
+		break;
+
+	case DATA_TYPE_UINT64:
+		ret = xdr_u_longlong_t(xdr, (void *)buf);
+		break;
+
+	case DATA_TYPE_HRTIME:
+		/*
+		 * NOTE: must expose the definition of hrtime_t here
+		 */
+		ret = xdr_longlong_t(xdr, (void *)buf);
+		break;
+#if !defined(_KERNEL)
+	case DATA_TYPE_DOUBLE:
+		ret = xdr_double(xdr, (void *)buf);
+		break;
+#endif
+	case DATA_TYPE_STRING:
+		ret = xdr_string(xdr, &buf, buflen - 1);
+		break;
+
+	case DATA_TYPE_BYTE_ARRAY:
+		ret = xdr_opaque(xdr, buf, nelem);
+		break;
+
+	case DATA_TYPE_INT8_ARRAY:
+	case DATA_TYPE_UINT8_ARRAY:
+		ret = xdr_array(xdr, &buf, &nelem, buflen, sizeof (int8_t),
+		    (xdrproc_t)xdr_char);
+		break;
+
+	case DATA_TYPE_INT16_ARRAY:
+		ret = xdr_array(xdr, &buf, &nelem, buflen / sizeof (int16_t),
+		    sizeof (int16_t), (xdrproc_t)xdr_short);
+		break;
+
+	case DATA_TYPE_UINT16_ARRAY:
+		ret = xdr_array(xdr, &buf, &nelem, buflen / sizeof (uint16_t),
+		    sizeof (uint16_t), (xdrproc_t)xdr_u_short);
+		break;
+
+	case DATA_TYPE_BOOLEAN_ARRAY:
+	case DATA_TYPE_INT32_ARRAY:
+		ret = xdr_array(xdr, &buf, &nelem, buflen / sizeof (int32_t),
+		    sizeof (int32_t), (xdrproc_t)xdr_int);
+		break;
+
+	case DATA_TYPE_UINT32_ARRAY:
+		ret = xdr_array(xdr, &buf, &nelem, buflen / sizeof (uint32_t),
+		    sizeof (uint32_t), (xdrproc_t)xdr_u_int);
+		break;
+
+	case DATA_TYPE_INT64_ARRAY:
+		ret = xdr_array(xdr, &buf, &nelem, buflen / sizeof (int64_t),
+		    sizeof (int64_t), (xdrproc_t)xdr_longlong_t);
+		break;
+
+	case DATA_TYPE_UINT64_ARRAY:
+		ret = xdr_array(xdr, &buf, &nelem, buflen / sizeof (uint64_t),
+		    sizeof (uint64_t), (xdrproc_t)xdr_u_longlong_t);
+		break;
+
+	case DATA_TYPE_STRING_ARRAY: {
+		size_t len = nelem * sizeof (uint64_t);
+		char **strp = (void *)buf;
+		int i;
+
+		if (nvs->nvs_op == NVS_OP_DECODE)
+			bzero(buf, len);	/* don't trust packed data */
+
+		for (i = 0; i < nelem; i++) {
+			if (buflen <= len)
+				return (EFAULT);
+
+			buf += len;
+			buflen -= len;
+
+			if (xdr_string(xdr, &buf, buflen - 1) != TRUE)
+				return (EFAULT);
+
+			if (nvs->nvs_op == NVS_OP_DECODE)
+				strp[i] = buf;
+			len = strlen(buf) + 1;
+		}
+		ret = TRUE;
+		break;
+	}
+	default:
+		break;
+	}
+
+	return (ret == TRUE ? 0 : EFAULT);
+}
+
+static int
+nvs_xdr_nvp_size(nvstream_t *nvs, nvpair_t *nvp, size_t *size)
+{
+	data_type_t type = NVP_TYPE(nvp);
+	/*
+	 * encode_size + decode_size + name string size + data type + nelem
+	 * where name string size = 4 + NV_ALIGN4(strlen(NVP_NAME(nvp)))
+	 */
+	uint64_t nvp_sz = 4 + 4 + 4 + NV_ALIGN4(strlen(NVP_NAME(nvp))) + 4 + 4;
+
+	switch (type) {
+	case DATA_TYPE_BOOLEAN:
+		break;
+
+	case DATA_TYPE_BOOLEAN_VALUE:
+	case DATA_TYPE_BYTE:
+	case DATA_TYPE_INT8:
+	case DATA_TYPE_UINT8:
+	case DATA_TYPE_INT16:
+	case DATA_TYPE_UINT16:
+	case DATA_TYPE_INT32:
+	case DATA_TYPE_UINT32:
+		nvp_sz += 4;	/* 4 is the minimum xdr unit */
+		break;
+
+	case DATA_TYPE_INT64:
+	case DATA_TYPE_UINT64:
+	case DATA_TYPE_HRTIME:
+#if !defined(_KERNEL)
+	case DATA_TYPE_DOUBLE:
+#endif
+		nvp_sz += 8;
+		break;
+
+	case DATA_TYPE_STRING:
+		nvp_sz += 4 + NV_ALIGN4(strlen((char *)NVP_VALUE(nvp)));
+		break;
+
+	case DATA_TYPE_BYTE_ARRAY:
+		nvp_sz += NV_ALIGN4(NVP_NELEM(nvp));
+		break;
+
+	case DATA_TYPE_BOOLEAN_ARRAY:
+	case DATA_TYPE_INT8_ARRAY:
+	case DATA_TYPE_UINT8_ARRAY:
+	case DATA_TYPE_INT16_ARRAY:
+	case DATA_TYPE_UINT16_ARRAY:
+	case DATA_TYPE_INT32_ARRAY:
+	case DATA_TYPE_UINT32_ARRAY:
+		nvp_sz += 4 + 4 * (uint64_t)NVP_NELEM(nvp);
+		break;
+
+	case DATA_TYPE_INT64_ARRAY:
+	case DATA_TYPE_UINT64_ARRAY:
+		nvp_sz += 4 + 8 * (uint64_t)NVP_NELEM(nvp);
+		break;
+
+	case DATA_TYPE_STRING_ARRAY: {
+		int i;
+		char **strs = (void *)NVP_VALUE(nvp);
+
+		for (i = 0; i < NVP_NELEM(nvp); i++)
+			nvp_sz += 4 + NV_ALIGN4(strlen(strs[i]));
+
+		break;
+	}
+
+	case DATA_TYPE_NVLIST:
+	case DATA_TYPE_NVLIST_ARRAY: {
+		size_t nvsize = 0;
+		int old_nvs_op = nvs->nvs_op;
+		int err;
+
+		nvs->nvs_op = NVS_OP_GETSIZE;
+		if (type == DATA_TYPE_NVLIST)
+			err = nvs_operation(nvs, EMBEDDED_NVL(nvp), &nvsize);
+		else
+			err = nvs_embedded_nvl_array(nvs, nvp, &nvsize);
+		nvs->nvs_op = old_nvs_op;
+
+		if (err != 0)
+			return (EINVAL);
+
+		nvp_sz += nvsize;
+		break;
+	}
+
+	default:
+		return (EINVAL);
+	}
+
+	if (nvp_sz > INT32_MAX)
+		return (EINVAL);
+
+	*size = nvp_sz;
+
+	return (0);
+}
+
+
+/*
+ * The NVS_XDR_MAX_LEN macro takes a packed xdr buffer of size x and estimates
+ * the largest nvpair that could be encoded in the buffer.
+ *
+ * See comments above nvpair_xdr_op() for the format of xdr encoding.
+ * The size of a xdr packed nvpair without any data is 5 words.
+ *
+ * Using the size of the data directly as an estimate would be ok
+ * in all cases except one.  If the data type is of DATA_TYPE_STRING_ARRAY
+ * then the actual nvpair has space for an array of pointers to index
+ * the strings.  These pointers are not encoded into the packed xdr buffer.
+ *
+ * If the data is of type DATA_TYPE_STRING_ARRAY and all the strings are
+ * of length 0, then each string is endcoded in xdr format as a single word.
+ * Therefore when expanded to an nvpair there will be 2.25 word used for
+ * each string.  (a int64_t allocated for pointer usage, and a single char
+ * for the null termination.)
+ *
+ * This is the calculation performed by the NVS_XDR_MAX_LEN macro.
+ */
+#define	NVS_XDR_HDR_LEN		((size_t)(5 * 4))
+#define	NVS_XDR_DATA_LEN(y)	(((size_t)(y) <= NVS_XDR_HDR_LEN) ? \
+					0 : ((size_t)(y) - NVS_XDR_HDR_LEN))
+#define	NVS_XDR_MAX_LEN(x)	(NVP_SIZE_CALC(1, 0) + \
+					(NVS_XDR_DATA_LEN(x) * 2) + \
+					NV_ALIGN4((NVS_XDR_DATA_LEN(x) / 4)))
+
+static int
+nvs_xdr_nvpair(nvstream_t *nvs, nvpair_t *nvp, size_t *size)
+{
+	XDR 	*xdr = nvs->nvs_private;
+	int32_t	encode_len, decode_len;
+
+	switch (nvs->nvs_op) {
+	case NVS_OP_ENCODE: {
+		size_t nvsize;
+
+		if (nvs_xdr_nvp_size(nvs, nvp, &nvsize) != 0)
+			return (EFAULT);
+
+		decode_len = nvp->nvp_size;
+		encode_len = nvsize;
+		if (!xdr_int(xdr, &encode_len) || !xdr_int(xdr, &decode_len))
+			return (EFAULT);
+
+		return (nvs_xdr_nvp_op(nvs, nvp));
+	}
+	case NVS_OP_DECODE: {
+		struct xdr_bytesrec bytesrec;
+
+		/* get the encode and decode size */
+		if (!xdr_int(xdr, &encode_len) || !xdr_int(xdr, &decode_len))
+			return (EFAULT);
+		*size = decode_len;
+
+		/* are we at the end of the stream? */
+		if (*size == 0)
+			return (0);
+
+		/* sanity check the size parameter */
+		if (!xdr_control(xdr, XDR_GET_BYTES_AVAIL, &bytesrec))
+			return (EFAULT);
+
+		if (*size > NVS_XDR_MAX_LEN(bytesrec.xc_num_avail))
+			return (EFAULT);
+		break;
+	}
+
+	default:
+		return (EINVAL);
+	}
+	return (0);
+}
+
+static const struct nvs_ops nvs_xdr_ops = {
+	nvs_xdr_nvlist,
+	nvs_xdr_nvpair,
+	nvs_xdr_nvp_op,
+	nvs_xdr_nvp_size,
+	nvs_xdr_nvl_fini
+};
+
+static int
+nvs_xdr(nvstream_t *nvs, nvlist_t *nvl, char *buf, size_t *buflen)
+{
+	XDR xdr;
+	int err;
+
+	nvs->nvs_ops = &nvs_xdr_ops;
+
+	if ((err = nvs_xdr_create(nvs, &xdr, buf + sizeof (nvs_header_t),
+	    *buflen - sizeof (nvs_header_t))) != 0)
+		return (err);
+
+	err = nvs_operation(nvs, nvl, buflen);
+
+	nvs_xdr_destroy(nvs);
+
+	return (err);
+}
+
+#if defined(_KERNEL) && defined(HAVE_SPL)
+static int __init
+nvpair_init(void)
+{
+	return (0);
+}
+
+static void __exit
+nvpair_fini(void)
+{
+}
+
+module_init(nvpair_init);
+module_exit(nvpair_fini);
+
+MODULE_DESCRIPTION("Generic name/value pair implementation");
+MODULE_AUTHOR(ZFS_META_AUTHOR);
+MODULE_LICENSE(ZFS_META_LICENSE);
+MODULE_VERSION(ZFS_META_VERSION "-" ZFS_META_RELEASE);
+
+EXPORT_SYMBOL(nv_alloc_init);
+EXPORT_SYMBOL(nv_alloc_reset);
+EXPORT_SYMBOL(nv_alloc_fini);
+
+/* list management */
+EXPORT_SYMBOL(nvlist_alloc);
+EXPORT_SYMBOL(nvlist_free);
+EXPORT_SYMBOL(nvlist_size);
+EXPORT_SYMBOL(nvlist_pack);
+EXPORT_SYMBOL(nvlist_unpack);
+EXPORT_SYMBOL(nvlist_dup);
+EXPORT_SYMBOL(nvlist_merge);
+
+EXPORT_SYMBOL(nvlist_xalloc);
+EXPORT_SYMBOL(nvlist_xpack);
+EXPORT_SYMBOL(nvlist_xunpack);
+EXPORT_SYMBOL(nvlist_xdup);
+EXPORT_SYMBOL(nvlist_lookup_nv_alloc);
+
+EXPORT_SYMBOL(nvlist_add_nvpair);
+EXPORT_SYMBOL(nvlist_add_boolean);
+EXPORT_SYMBOL(nvlist_add_boolean_value);
+EXPORT_SYMBOL(nvlist_add_byte);
+EXPORT_SYMBOL(nvlist_add_int8);
+EXPORT_SYMBOL(nvlist_add_uint8);
+EXPORT_SYMBOL(nvlist_add_int16);
+EXPORT_SYMBOL(nvlist_add_uint16);
+EXPORT_SYMBOL(nvlist_add_int32);
+EXPORT_SYMBOL(nvlist_add_uint32);
+EXPORT_SYMBOL(nvlist_add_int64);
+EXPORT_SYMBOL(nvlist_add_uint64);
+EXPORT_SYMBOL(nvlist_add_string);
+EXPORT_SYMBOL(nvlist_add_nvlist);
+EXPORT_SYMBOL(nvlist_add_boolean_array);
+EXPORT_SYMBOL(nvlist_add_byte_array);
+EXPORT_SYMBOL(nvlist_add_int8_array);
+EXPORT_SYMBOL(nvlist_add_uint8_array);
+EXPORT_SYMBOL(nvlist_add_int16_array);
+EXPORT_SYMBOL(nvlist_add_uint16_array);
+EXPORT_SYMBOL(nvlist_add_int32_array);
+EXPORT_SYMBOL(nvlist_add_uint32_array);
+EXPORT_SYMBOL(nvlist_add_int64_array);
+EXPORT_SYMBOL(nvlist_add_uint64_array);
+EXPORT_SYMBOL(nvlist_add_string_array);
+EXPORT_SYMBOL(nvlist_add_nvlist_array);
+EXPORT_SYMBOL(nvlist_next_nvpair);
+EXPORT_SYMBOL(nvlist_prev_nvpair);
+EXPORT_SYMBOL(nvlist_empty);
+EXPORT_SYMBOL(nvlist_add_hrtime);
+
+EXPORT_SYMBOL(nvlist_remove);
+EXPORT_SYMBOL(nvlist_remove_nvpair);
+EXPORT_SYMBOL(nvlist_remove_all);
+
+EXPORT_SYMBOL(nvlist_lookup_boolean);
+EXPORT_SYMBOL(nvlist_lookup_boolean_value);
+EXPORT_SYMBOL(nvlist_lookup_byte);
+EXPORT_SYMBOL(nvlist_lookup_int8);
+EXPORT_SYMBOL(nvlist_lookup_uint8);
+EXPORT_SYMBOL(nvlist_lookup_int16);
+EXPORT_SYMBOL(nvlist_lookup_uint16);
+EXPORT_SYMBOL(nvlist_lookup_int32);
+EXPORT_SYMBOL(nvlist_lookup_uint32);
+EXPORT_SYMBOL(nvlist_lookup_int64);
+EXPORT_SYMBOL(nvlist_lookup_uint64);
+EXPORT_SYMBOL(nvlist_lookup_string);
+EXPORT_SYMBOL(nvlist_lookup_nvlist);
+EXPORT_SYMBOL(nvlist_lookup_boolean_array);
+EXPORT_SYMBOL(nvlist_lookup_byte_array);
+EXPORT_SYMBOL(nvlist_lookup_int8_array);
+EXPORT_SYMBOL(nvlist_lookup_uint8_array);
+EXPORT_SYMBOL(nvlist_lookup_int16_array);
+EXPORT_SYMBOL(nvlist_lookup_uint16_array);
+EXPORT_SYMBOL(nvlist_lookup_int32_array);
+EXPORT_SYMBOL(nvlist_lookup_uint32_array);
+EXPORT_SYMBOL(nvlist_lookup_int64_array);
+EXPORT_SYMBOL(nvlist_lookup_uint64_array);
+EXPORT_SYMBOL(nvlist_lookup_string_array);
+EXPORT_SYMBOL(nvlist_lookup_nvlist_array);
+EXPORT_SYMBOL(nvlist_lookup_hrtime);
+EXPORT_SYMBOL(nvlist_lookup_pairs);
+
+EXPORT_SYMBOL(nvlist_lookup_nvpair);
+EXPORT_SYMBOL(nvlist_exists);
+
+/* processing nvpair */
+EXPORT_SYMBOL(nvpair_name);
+EXPORT_SYMBOL(nvpair_type);
+EXPORT_SYMBOL(nvpair_value_boolean_value);
+EXPORT_SYMBOL(nvpair_value_byte);
+EXPORT_SYMBOL(nvpair_value_int8);
+EXPORT_SYMBOL(nvpair_value_uint8);
+EXPORT_SYMBOL(nvpair_value_int16);
+EXPORT_SYMBOL(nvpair_value_uint16);
+EXPORT_SYMBOL(nvpair_value_int32);
+EXPORT_SYMBOL(nvpair_value_uint32);
+EXPORT_SYMBOL(nvpair_value_int64);
+EXPORT_SYMBOL(nvpair_value_uint64);
+EXPORT_SYMBOL(nvpair_value_string);
+EXPORT_SYMBOL(nvpair_value_nvlist);
+EXPORT_SYMBOL(nvpair_value_boolean_array);
+EXPORT_SYMBOL(nvpair_value_byte_array);
+EXPORT_SYMBOL(nvpair_value_int8_array);
+EXPORT_SYMBOL(nvpair_value_uint8_array);
+EXPORT_SYMBOL(nvpair_value_int16_array);
+EXPORT_SYMBOL(nvpair_value_uint16_array);
+EXPORT_SYMBOL(nvpair_value_int32_array);
+EXPORT_SYMBOL(nvpair_value_uint32_array);
+EXPORT_SYMBOL(nvpair_value_int64_array);
+EXPORT_SYMBOL(nvpair_value_uint64_array);
+EXPORT_SYMBOL(nvpair_value_string_array);
+EXPORT_SYMBOL(nvpair_value_nvlist_array);
+EXPORT_SYMBOL(nvpair_value_hrtime);
+
+#endif
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/module/nvpair/nvpair_alloc_fixed.c
@@ -0,0 +1,124 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+
+#include <sys/stropts.h>
+#include <sys/isa_defs.h>
+#include <sys/nvpair.h>
+#include <sys/sysmacros.h>
+#if defined(_KERNEL) && !defined(_BOOT)
+#include <sys/varargs.h>
+#else
+#include <stdarg.h>
+#include <strings.h>
+#endif
+
+/*
+ * This allocator is very simple.
+ *  - it uses a pre-allocated buffer for memory allocations.
+ *  - it does _not_ free memory in the pre-allocated buffer.
+ *
+ * The reason for the selected implemention is simplicity.
+ * This allocator is designed for the usage in interrupt context when
+ * the caller may not wait for free memory.
+ */
+
+/* pre-allocated buffer for memory allocations */
+typedef struct nvbuf {
+	uintptr_t	nvb_buf;	/* address of pre-allocated buffer */
+	uintptr_t 	nvb_lim;	/* limit address in the buffer */
+	uintptr_t	nvb_cur;	/* current address in the buffer */
+} nvbuf_t;
+
+/*
+ * Initialize the pre-allocated buffer allocator. The caller needs to supply
+ *
+ *   buf	address of pre-allocated buffer
+ *   bufsz	size of pre-allocated buffer
+ *
+ * nv_fixed_init() calculates the remaining members of nvbuf_t.
+ */
+static int
+nv_fixed_init(nv_alloc_t *nva, va_list valist)
+{
+	uintptr_t base = va_arg(valist, uintptr_t);
+	uintptr_t lim = base + va_arg(valist, size_t);
+	nvbuf_t *nvb = (nvbuf_t *)P2ROUNDUP(base, sizeof (uintptr_t));
+
+	if (base == 0 || (uintptr_t)&nvb[1] > lim)
+		return (EINVAL);
+
+	nvb->nvb_buf = (uintptr_t)&nvb[0];
+	nvb->nvb_cur = (uintptr_t)&nvb[1];
+	nvb->nvb_lim = lim;
+	nva->nva_arg = nvb;
+
+	return (0);
+}
+
+static void *
+nv_fixed_alloc(nv_alloc_t *nva, size_t size)
+{
+	nvbuf_t *nvb = nva->nva_arg;
+	uintptr_t new = nvb->nvb_cur;
+
+	if (size == 0 || new + size > nvb->nvb_lim)
+		return (NULL);
+
+	nvb->nvb_cur = P2ROUNDUP(new + size, sizeof (uintptr_t));
+
+	return ((void *)new);
+}
+
+/*ARGSUSED*/
+static void
+nv_fixed_free(nv_alloc_t *nva, void *buf, size_t size)
+{
+	/* don't free memory in the pre-allocated buffer */
+}
+
+static void
+nv_fixed_reset(nv_alloc_t *nva)
+{
+	nvbuf_t *nvb = nva->nva_arg;
+
+	nvb->nvb_cur = (uintptr_t)&nvb[1];
+}
+
+const nv_alloc_ops_t nv_fixed_ops_def = {
+	nv_fixed_init,	/* nv_ao_init() */
+	NULL,		/* nv_ao_fini() */
+	nv_fixed_alloc,	/* nv_ao_alloc() */
+	nv_fixed_free,	/* nv_ao_free() */
+	nv_fixed_reset	/* nv_ao_reset() */
+};
+
+const nv_alloc_ops_t *nv_fixed_ops = &nv_fixed_ops_def;
+
+#if defined(_KERNEL) && defined(HAVE_SPL)
+EXPORT_SYMBOL(nv_fixed_ops);
+#endif
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/module/nvpair/nvpair_alloc_spl.c
@@ -0,0 +1,96 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License").  You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at * usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#include <sys/nvpair.h>
+#include <sys/kmem.h>
+#include <sys/vmem.h>
+
+static void *
+nv_alloc_sleep_spl(nv_alloc_t *nva, size_t size)
+{
+	return (vmem_alloc(size, KM_SLEEP));
+}
+
+static void *
+nv_alloc_pushpage_spl(nv_alloc_t *nva, size_t size)
+{
+	return (vmem_alloc(size, KM_PUSHPAGE));
+}
+
+static void *
+nv_alloc_nosleep_spl(nv_alloc_t *nva, size_t size)
+{
+	return (kmem_alloc(size, KM_NOSLEEP));
+}
+
+static void
+nv_free_spl(nv_alloc_t *nva, void *buf, size_t size)
+{
+	kmem_free(buf, size);
+}
+
+const nv_alloc_ops_t spl_sleep_ops_def = {
+	NULL,			/* nv_ao_init() */
+	NULL,			/* nv_ao_fini() */
+	nv_alloc_sleep_spl,	/* nv_ao_alloc() */
+	nv_free_spl,		/* nv_ao_free() */
+	NULL			/* nv_ao_reset() */
+};
+
+const nv_alloc_ops_t spl_pushpage_ops_def = {
+	NULL,			/* nv_ao_init() */
+	NULL,			/* nv_ao_fini() */
+	nv_alloc_pushpage_spl,	/* nv_ao_alloc() */
+	nv_free_spl,		/* nv_ao_free() */
+	NULL			/* nv_ao_reset() */
+};
+
+const nv_alloc_ops_t spl_nosleep_ops_def = {
+	NULL,			/* nv_ao_init() */
+	NULL,			/* nv_ao_fini() */
+	nv_alloc_nosleep_spl,	/* nv_ao_alloc() */
+	nv_free_spl,		/* nv_ao_free() */
+	NULL			/* nv_ao_reset() */
+};
+
+nv_alloc_t nv_alloc_sleep_def = {
+	&spl_sleep_ops_def,
+	NULL
+};
+
+nv_alloc_t nv_alloc_pushpage_def = {
+	&spl_pushpage_ops_def,
+	NULL
+};
+
+nv_alloc_t nv_alloc_nosleep_def = {
+	&spl_nosleep_ops_def,
+	NULL
+};
+
+nv_alloc_t *nv_alloc_sleep = &nv_alloc_sleep_def;
+nv_alloc_t *nv_alloc_pushpage = &nv_alloc_pushpage_def;
+nv_alloc_t *nv_alloc_nosleep = &nv_alloc_nosleep_def;
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/module/unicode/Makefile.in
@@ -0,0 +1,11 @@
+src = @abs_top_srcdir@/module/unicode
+obj = @abs_builddir@
+
+MODULE := zunicode
+
+EXTRA_CFLAGS = $(ZFS_MODULE_CFLAGS) @KERNELCPPFLAGS@
+
+obj-$(CONFIG_ZFS) := $(MODULE).o
+
+$(MODULE)-objs += u8_textprep.o
+$(MODULE)-objs += uconv.o
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/module/unicode/u8_textprep.c
@@ -0,0 +1,2157 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+
+
+/*
+ * UTF-8 text preparation functions (PSARC/2007/149, PSARC/2007/458).
+ *
+ * Man pages: u8_textprep_open(9F), u8_textprep_buf(9F), u8_textprep_close(9F),
+ * u8_textprep_str(9F), u8_strcmp(9F), and u8_validate(9F). See also
+ * the section 3C man pages.
+ * Interface stability: Committed.
+ */
+
+#include <sys/types.h>
+#ifdef	_KERNEL
+#include <sys/param.h>
+#include <sys/sysmacros.h>
+#include <sys/systm.h>
+#include <sys/debug.h>
+#include <sys/kmem.h>
+#include <sys/ddi.h>
+#include <sys/sunddi.h>
+#else
+#include <sys/u8_textprep.h>
+#include <strings.h>
+#endif	/* _KERNEL */
+#include <sys/byteorder.h>
+#include <sys/errno.h>
+#include <sys/u8_textprep_data.h>
+
+
+/* The maximum possible number of bytes in a UTF-8 character. */
+#define	U8_MB_CUR_MAX			(4)
+
+/*
+ * The maximum number of bytes needed for a UTF-8 character to cover
+ * U+0000 - U+FFFF, i.e., the coding space of now deprecated UCS-2.
+ */
+#define	U8_MAX_BYTES_UCS2		(3)
+
+/* The maximum possible number of bytes in a Stream-Safe Text. */
+#define	U8_STREAM_SAFE_TEXT_MAX		(128)
+
+/*
+ * The maximum number of characters in a combining/conjoining sequence and
+ * the actual upperbound limit of a combining/conjoining sequence.
+ */
+#define	U8_MAX_CHARS_A_SEQ		(32)
+#define	U8_UPPER_LIMIT_IN_A_SEQ		(31)
+
+/* The combining class value for Starter. */
+#define	U8_COMBINING_CLASS_STARTER	(0)
+
+/*
+ * Some Hangul related macros at below.
+ *
+ * The first and the last of Hangul syllables, Hangul Jamo Leading consonants,
+ * Vowels, and optional Trailing consonants in Unicode scalar values.
+ *
+ * Please be noted that the U8_HANGUL_JAMO_T_FIRST is 0x11A7 at below not
+ * the actual U+11A8. This is due to that the trailing consonant is optional
+ * and thus we are doing a pre-calculation of subtracting one.
+ *
+ * Each of 19 modern leading consonants has total 588 possible syllables since
+ * Hangul has 21 modern vowels and 27 modern trailing consonants plus 1 for
+ * no trailing consonant case, i.e., 21 x 28 = 588.
+ *
+ * We also have bunch of Hangul related macros at below. Please bear in mind
+ * that the U8_HANGUL_JAMO_1ST_BYTE can be used to check whether it is
+ * a Hangul Jamo or not but the value does not guarantee that it is a Hangul
+ * Jamo; it just guarantee that it will be most likely.
+ */
+#define	U8_HANGUL_SYL_FIRST		(0xAC00U)
+#define	U8_HANGUL_SYL_LAST		(0xD7A3U)
+
+#define	U8_HANGUL_JAMO_L_FIRST		(0x1100U)
+#define	U8_HANGUL_JAMO_L_LAST		(0x1112U)
+#define	U8_HANGUL_JAMO_V_FIRST		(0x1161U)
+#define	U8_HANGUL_JAMO_V_LAST		(0x1175U)
+#define	U8_HANGUL_JAMO_T_FIRST		(0x11A7U)
+#define	U8_HANGUL_JAMO_T_LAST		(0x11C2U)
+
+#define	U8_HANGUL_V_COUNT		(21)
+#define	U8_HANGUL_VT_COUNT		(588)
+#define	U8_HANGUL_T_COUNT		(28)
+
+#define	U8_HANGUL_JAMO_1ST_BYTE		(0xE1U)
+
+#define	U8_SAVE_HANGUL_AS_UTF8(s, i, j, k, b) \
+	(s)[(i)] = (uchar_t)(0xE0U | ((uint32_t)(b) & 0xF000U) >> 12); \
+	(s)[(j)] = (uchar_t)(0x80U | ((uint32_t)(b) & 0x0FC0U) >> 6); \
+	(s)[(k)] = (uchar_t)(0x80U | ((uint32_t)(b) & 0x003FU));
+
+#define	U8_HANGUL_JAMO_L(u) \
+	((u) >= U8_HANGUL_JAMO_L_FIRST && (u) <= U8_HANGUL_JAMO_L_LAST)
+
+#define	U8_HANGUL_JAMO_V(u) \
+	((u) >= U8_HANGUL_JAMO_V_FIRST && (u) <= U8_HANGUL_JAMO_V_LAST)
+
+#define	U8_HANGUL_JAMO_T(u) \
+	((u) > U8_HANGUL_JAMO_T_FIRST && (u) <= U8_HANGUL_JAMO_T_LAST)
+
+#define	U8_HANGUL_JAMO(u) \
+	((u) >= U8_HANGUL_JAMO_L_FIRST && (u) <= U8_HANGUL_JAMO_T_LAST)
+
+#define	U8_HANGUL_SYLLABLE(u) \
+	((u) >= U8_HANGUL_SYL_FIRST && (u) <= U8_HANGUL_SYL_LAST)
+
+#define	U8_HANGUL_COMPOSABLE_L_V(s, u) \
+	((s) == U8_STATE_HANGUL_L && U8_HANGUL_JAMO_V((u)))
+
+#define	U8_HANGUL_COMPOSABLE_LV_T(s, u) \
+	((s) == U8_STATE_HANGUL_LV && U8_HANGUL_JAMO_T((u)))
+
+/* The types of decomposition mappings. */
+#define	U8_DECOMP_BOTH			(0xF5U)
+#define	U8_DECOMP_CANONICAL		(0xF6U)
+
+/* The indicator for 16-bit table. */
+#define	U8_16BIT_TABLE_INDICATOR	(0x8000U)
+
+/* The following are some convenience macros. */
+#define	U8_PUT_3BYTES_INTO_UTF32(u, b1, b2, b3)  \
+	(u) = ((((uint32_t)(b1) & 0x0F) << 12) | \
+		(((uint32_t)(b2) & 0x3F) << 6)  | \
+		((uint32_t)(b3) & 0x3F));
+
+#define	U8_SIMPLE_SWAP(a, b, t) \
+	(t) = (a); \
+	(a) = (b); \
+	(b) = (t);
+
+#define	U8_ASCII_TOUPPER(c) \
+	(((c) >= 'a' && (c) <= 'z') ? (c) - 'a' + 'A' : (c))
+
+#define	U8_ASCII_TOLOWER(c) \
+	(((c) >= 'A' && (c) <= 'Z') ? (c) - 'A' + 'a' : (c))
+
+#define	U8_ISASCII(c)			(((uchar_t)(c)) < 0x80U)
+/*
+ * The following macro assumes that the two characters that are to be
+ * swapped are adjacent to each other and 'a' comes before 'b'.
+ *
+ * If the assumptions are not met, then, the macro will fail.
+ */
+#define	U8_SWAP_COMB_MARKS(a, b) \
+	for (k = 0; k < disp[(a)]; k++) \
+		u8t[k] = u8s[start[(a)] + k]; \
+	for (k = 0; k < disp[(b)]; k++) \
+		u8s[start[(a)] + k] = u8s[start[(b)] + k]; \
+	start[(b)] = start[(a)] + disp[(b)]; \
+	for (k = 0; k < disp[(a)]; k++) \
+		u8s[start[(b)] + k] = u8t[k]; \
+	U8_SIMPLE_SWAP(comb_class[(a)], comb_class[(b)], tc); \
+	U8_SIMPLE_SWAP(disp[(a)], disp[(b)], tc);
+
+/* The possible states during normalization. */
+typedef enum {
+	U8_STATE_START = 0,
+	U8_STATE_HANGUL_L = 1,
+	U8_STATE_HANGUL_LV = 2,
+	U8_STATE_HANGUL_LVT = 3,
+	U8_STATE_HANGUL_V = 4,
+	U8_STATE_HANGUL_T = 5,
+	U8_STATE_COMBINING_MARK = 6
+} u8_normalization_states_t;
+
+/*
+ * The three vectors at below are used to check bytes of a given UTF-8
+ * character are valid and not containing any malformed byte values.
+ *
+ * We used to have a quite relaxed UTF-8 binary representation but then there
+ * was some security related issues and so the Unicode Consortium defined
+ * and announced the UTF-8 Corrigendum at Unicode 3.1 and then refined it
+ * one more time at the Unicode 3.2. The following three tables are based on
+ * that.
+ */
+
+#define	U8_ILLEGAL_NEXT_BYTE_COMMON(c)	((c) < 0x80 || (c) > 0xBF)
+
+#define	I_				U8_ILLEGAL_CHAR
+#define	O_				U8_OUT_OF_RANGE_CHAR
+
+const int8_t u8_number_of_bytes[0x100] = {
+	1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
+	1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
+	1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
+	1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
+	1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
+	1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
+	1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
+	1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
+
+/*	80  81  82  83  84  85  86  87  88  89  8A  8B  8C  8D  8E  8F  */
+	I_, I_, I_, I_, I_, I_, I_, I_, I_, I_, I_, I_, I_, I_, I_, I_,
+
+/*  	90  91  92  93  94  95  96  97  98  99  9A  9B  9C  9D  9E  9F  */
+	I_, I_, I_, I_, I_, I_, I_, I_, I_, I_, I_, I_, I_, I_, I_, I_,
+
+/*  	A0  A1  A2  A3  A4  A5  A6  A7  A8  A9  AA  AB  AC  AD  AE  AF  */
+	I_, I_, I_, I_, I_, I_, I_, I_, I_, I_, I_, I_, I_, I_, I_, I_,
+
+/*	B0  B1  B2  B3  B4  B5  B6  B7  B8  B9  BA  BB  BC  BD  BE  BF  */
+	I_, I_, I_, I_, I_, I_, I_, I_, I_, I_, I_, I_, I_, I_, I_, I_,
+
+/*	C0  C1  C2  C3  C4  C5  C6  C7  C8  C9  CA  CB  CC  CD  CE  CF  */
+	I_, I_, 2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,
+
+/*	D0  D1  D2  D3  D4  D5  D6  D7  D8  D9  DA  DB  DC  DD  DE  DF  */
+	2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,
+
+/*	E0  E1  E2  E3  E4  E5  E6  E7  E8  E9  EA  EB  EC  ED  EE  EF  */
+	3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,
+
+/*	F0  F1  F2  F3  F4  F5  F6  F7  F8  F9  FA  FB  FC  FD  FE  FF  */
+	4,  4,  4,  4,  4,  O_, O_, O_, O_, O_, O_, O_, O_, O_, O_, O_,
+};
+
+#undef	I_
+#undef	O_
+
+const uint8_t u8_valid_min_2nd_byte[0x100] = {
+	0,    0,    0,    0,    0,    0,    0,    0,
+	0,    0,    0,    0,    0,    0,    0,    0,
+	0,    0,    0,    0,    0,    0,    0,    0,
+	0,    0,    0,    0,    0,    0,    0,    0,
+	0,    0,    0,    0,    0,    0,    0,    0,
+	0,    0,    0,    0,    0,    0,    0,    0,
+	0,    0,    0,    0,    0,    0,    0,    0,
+	0,    0,    0,    0,    0,    0,    0,    0,
+	0,    0,    0,    0,    0,    0,    0,    0,
+	0,    0,    0,    0,    0,    0,    0,    0,
+	0,    0,    0,    0,    0,    0,    0,    0,
+	0,    0,    0,    0,    0,    0,    0,    0,
+	0,    0,    0,    0,    0,    0,    0,    0,
+	0,    0,    0,    0,    0,    0,    0,    0,
+	0,    0,    0,    0,    0,    0,    0,    0,
+	0,    0,    0,    0,    0,    0,    0,    0,
+	0,    0,    0,    0,    0,    0,    0,    0,
+	0,    0,    0,    0,    0,    0,    0,    0,
+	0,    0,    0,    0,    0,    0,    0,    0,
+	0,    0,    0,    0,    0,    0,    0,    0,
+	0,    0,    0,    0,    0,    0,    0,    0,
+	0,    0,    0,    0,    0,    0,    0,    0,
+	0,    0,    0,    0,    0,    0,    0,    0,
+	0,    0,    0,    0,    0,    0,    0,    0,
+/*	C0    C1    C2    C3    C4    C5    C6    C7    */
+	0,    0,    0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+/*	C8    C9    CA    CB    CC    CD    CE    CF    */
+	0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+/*	D0    D1    D2    D3    D4    D5    D6    D7    */
+	0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+/*	D8    D9    DA    DB    DC    DD    DE    DF    */
+	0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+/*	E0    E1    E2    E3    E4    E5    E6    E7    */
+	0xa0, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+/*	E8    E9    EA    EB    EC    ED    EE    EF    */
+	0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+/*	F0    F1    F2    F3    F4    F5    F6    F7    */
+	0x90, 0x80, 0x80, 0x80, 0x80, 0,    0,    0,
+	0,    0,    0,    0,    0,    0,    0,    0,
+};
+
+const uint8_t u8_valid_max_2nd_byte[0x100] = {
+	0,    0,    0,    0,    0,    0,    0,    0,
+	0,    0,    0,    0,    0,    0,    0,    0,
+	0,    0,    0,    0,    0,    0,    0,    0,
+	0,    0,    0,    0,    0,    0,    0,    0,
+	0,    0,    0,    0,    0,    0,    0,    0,
+	0,    0,    0,    0,    0,    0,    0,    0,
+	0,    0,    0,    0,    0,    0,    0,    0,
+	0,    0,    0,    0,    0,    0,    0,    0,
+	0,    0,    0,    0,    0,    0,    0,    0,
+	0,    0,    0,    0,    0,    0,    0,    0,
+	0,    0,    0,    0,    0,    0,    0,    0,
+	0,    0,    0,    0,    0,    0,    0,    0,
+	0,    0,    0,    0,    0,    0,    0,    0,
+	0,    0,    0,    0,    0,    0,    0,    0,
+	0,    0,    0,    0,    0,    0,    0,    0,
+	0,    0,    0,    0,    0,    0,    0,    0,
+	0,    0,    0,    0,    0,    0,    0,    0,
+	0,    0,    0,    0,    0,    0,    0,    0,
+	0,    0,    0,    0,    0,    0,    0,    0,
+	0,    0,    0,    0,    0,    0,    0,    0,
+	0,    0,    0,    0,    0,    0,    0,    0,
+	0,    0,    0,    0,    0,    0,    0,    0,
+	0,    0,    0,    0,    0,    0,    0,    0,
+	0,    0,    0,    0,    0,    0,    0,    0,
+/*	C0    C1    C2    C3    C4    C5    C6    C7    */
+	0,    0,    0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf,
+/*	C8    C9    CA    CB    CC    CD    CE    CF    */
+	0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf,
+/*	D0    D1    D2    D3    D4    D5    D6    D7    */
+	0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf,
+/*	D8    D9    DA    DB    DC    DD    DE    DF    */
+	0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf,
+/*	E0    E1    E2    E3    E4    E5    E6    E7    */
+	0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf,
+/*	E8    E9    EA    EB    EC    ED    EE    EF    */
+	0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0x9f, 0xbf, 0xbf,
+/*	F0    F1    F2    F3    F4    F5    F6    F7    */
+	0xbf, 0xbf, 0xbf, 0xbf, 0x8f, 0,    0,    0,
+	0,    0,    0,    0,    0,    0,    0,    0,
+};
+
+
+/*
+ * The u8_validate() validates on the given UTF-8 character string and
+ * calculate the byte length. It is quite similar to mblen(3C) except that
+ * this will validate against the list of characters if required and
+ * specific to UTF-8 and Unicode.
+ */
+int
+u8_validate(char *u8str, size_t n, char **list, int flag, int *errnum)
+{
+	uchar_t *ib;
+	uchar_t *ibtail;
+	uchar_t **p;
+	uchar_t *s1;
+	uchar_t *s2;
+	uchar_t f;
+	int sz;
+	size_t i;
+	int ret_val;
+	boolean_t second;
+	boolean_t no_need_to_validate_entire;
+	boolean_t check_additional;
+	boolean_t validate_ucs2_range_only;
+
+	if (! u8str)
+		return (0);
+
+	ib = (uchar_t *)u8str;
+	ibtail = ib + n;
+
+	ret_val = 0;
+
+	no_need_to_validate_entire = ! (flag & U8_VALIDATE_ENTIRE);
+	check_additional = flag & U8_VALIDATE_CHECK_ADDITIONAL;
+	validate_ucs2_range_only = flag & U8_VALIDATE_UCS2_RANGE;
+
+	while (ib < ibtail) {
+		/*
+		 * The first byte of a UTF-8 character tells how many
+		 * bytes will follow for the character. If the first byte
+		 * is an illegal byte value or out of range value, we just
+		 * return -1 with an appropriate error number.
+		 */
+		sz = u8_number_of_bytes[*ib];
+		if (sz == U8_ILLEGAL_CHAR) {
+			*errnum = EILSEQ;
+			return (-1);
+		}
+
+		if (sz == U8_OUT_OF_RANGE_CHAR ||
+		    (validate_ucs2_range_only && sz > U8_MAX_BYTES_UCS2)) {
+			*errnum = ERANGE;
+			return (-1);
+		}
+
+		/*
+		 * If we don't have enough bytes to check on, that's also
+		 * an error. As you can see, we give illegal byte sequence
+		 * checking higher priority then EINVAL cases.
+		 */
+		if ((ibtail - ib) < sz) {
+			*errnum = EINVAL;
+			return (-1);
+		}
+
+		if (sz == 1) {
+			ib++;
+			ret_val++;
+		} else {
+			/*
+			 * Check on the multi-byte UTF-8 character. For more
+			 * details on this, see comment added for the used
+			 * data structures at the beginning of the file.
+			 */
+			f = *ib++;
+			ret_val++;
+			second = B_TRUE;
+			for (i = 1; i < sz; i++) {
+				if (second) {
+					if (*ib < u8_valid_min_2nd_byte[f] ||
+					    *ib > u8_valid_max_2nd_byte[f]) {
+						*errnum = EILSEQ;
+						return (-1);
+					}
+					second = B_FALSE;
+				} else if (U8_ILLEGAL_NEXT_BYTE_COMMON(*ib)) {
+					*errnum = EILSEQ;
+					return (-1);
+				}
+				ib++;
+				ret_val++;
+			}
+		}
+
+		if (check_additional) {
+			for (p = (uchar_t **)list, i = 0; p[i]; i++) {
+				s1 = ib - sz;
+				s2 = p[i];
+				while (s1 < ib) {
+					if (*s1 != *s2 || *s2 == '\0')
+						break;
+					s1++;
+					s2++;
+				}
+
+				if (s1 >= ib && *s2 == '\0') {
+					*errnum = EBADF;
+					return (-1);
+				}
+			}
+		}
+
+		if (no_need_to_validate_entire)
+			break;
+	}
+
+	return (ret_val);
+}
+
+/*
+ * The do_case_conv() looks at the mapping tables and returns found
+ * bytes if any. If not found, the input bytes are returned. The function
+ * always terminate the return bytes with a null character assuming that
+ * there are plenty of room to do so.
+ *
+ * The case conversions are simple case conversions mapping a character to
+ * another character as specified in the Unicode data. The byte size of
+ * the mapped character could be different from that of the input character.
+ *
+ * The return value is the byte length of the returned character excluding
+ * the terminating null byte.
+ */
+static size_t
+do_case_conv(int uv, uchar_t *u8s, uchar_t *s, int sz, boolean_t is_it_toupper)
+{
+	size_t i;
+	uint16_t b1 = 0;
+	uint16_t b2 = 0;
+	uint16_t b3 = 0;
+	uint16_t b3_tbl;
+	uint16_t b3_base;
+	uint16_t b4 = 0;
+	size_t start_id;
+	size_t end_id;
+
+	/*
+	 * At this point, the only possible values for sz are 2, 3, and 4.
+	 * The u8s should point to a vector that is well beyond the size of
+	 * 5 bytes.
+	 */
+	if (sz == 2) {
+		b3 = u8s[0] = s[0];
+		b4 = u8s[1] = s[1];
+	} else if (sz == 3) {
+		b2 = u8s[0] = s[0];
+		b3 = u8s[1] = s[1];
+		b4 = u8s[2] = s[2];
+	} else if (sz == 4) {
+		b1 = u8s[0] = s[0];
+		b2 = u8s[1] = s[1];
+		b3 = u8s[2] = s[2];
+		b4 = u8s[3] = s[3];
+	} else {
+		/* This is not possible but just in case as a fallback. */
+		if (is_it_toupper)
+			*u8s = U8_ASCII_TOUPPER(*s);
+		else
+			*u8s = U8_ASCII_TOLOWER(*s);
+		u8s[1] = '\0';
+
+		return (1);
+	}
+	u8s[sz] = '\0';
+
+	/*
+	 * Let's find out if we have a corresponding character.
+	 */
+	b1 = u8_common_b1_tbl[uv][b1];
+	if (b1 == U8_TBL_ELEMENT_NOT_DEF)
+		return ((size_t)sz);
+
+	b2 = u8_case_common_b2_tbl[uv][b1][b2];
+	if (b2 == U8_TBL_ELEMENT_NOT_DEF)
+		return ((size_t)sz);
+
+	if (is_it_toupper) {
+		b3_tbl = u8_toupper_b3_tbl[uv][b2][b3].tbl_id;
+		if (b3_tbl == U8_TBL_ELEMENT_NOT_DEF)
+			return ((size_t)sz);
+
+		start_id = u8_toupper_b4_tbl[uv][b3_tbl][b4];
+		end_id = u8_toupper_b4_tbl[uv][b3_tbl][b4 + 1];
+
+		/* Either there is no match or an error at the table. */
+		if (start_id >= end_id || (end_id - start_id) > U8_MB_CUR_MAX)
+			return ((size_t)sz);
+
+		b3_base = u8_toupper_b3_tbl[uv][b2][b3].base;
+
+		for (i = 0; start_id < end_id; start_id++)
+			u8s[i++] = u8_toupper_final_tbl[uv][b3_base + start_id];
+	} else {
+		b3_tbl = u8_tolower_b3_tbl[uv][b2][b3].tbl_id;
+		if (b3_tbl == U8_TBL_ELEMENT_NOT_DEF)
+			return ((size_t)sz);
+
+		start_id = u8_tolower_b4_tbl[uv][b3_tbl][b4];
+		end_id = u8_tolower_b4_tbl[uv][b3_tbl][b4 + 1];
+
+		if (start_id >= end_id || (end_id - start_id) > U8_MB_CUR_MAX)
+			return ((size_t)sz);
+
+		b3_base = u8_tolower_b3_tbl[uv][b2][b3].base;
+
+		for (i = 0; start_id < end_id; start_id++)
+			u8s[i++] = u8_tolower_final_tbl[uv][b3_base + start_id];
+	}
+
+	/*
+	 * If i is still zero, that means there is no corresponding character.
+	 */
+	if (i == 0)
+		return ((size_t)sz);
+
+	u8s[i] = '\0';
+
+	return (i);
+}
+
+/*
+ * The do_case_compare() function compares the two input strings, s1 and s2,
+ * one character at a time doing case conversions if applicable and return
+ * the comparison result as like strcmp().
+ *
+ * Since, in empirical sense, most of text data are 7-bit ASCII characters,
+ * we treat the 7-bit ASCII characters as a special case trying to yield
+ * faster processing time.
+ */
+static int
+do_case_compare(size_t uv, uchar_t *s1, uchar_t *s2, size_t n1,
+	size_t n2, boolean_t is_it_toupper, int *errnum)
+{
+	int f;
+	int sz1;
+	int sz2;
+	size_t j;
+	size_t i1;
+	size_t i2;
+	uchar_t u8s1[U8_MB_CUR_MAX + 1];
+	uchar_t u8s2[U8_MB_CUR_MAX + 1];
+
+	i1 = i2 = 0;
+	while (i1 < n1 && i2 < n2) {
+		/*
+		 * Find out what would be the byte length for this UTF-8
+		 * character at string s1 and also find out if this is
+		 * an illegal start byte or not and if so, issue a proper
+		 * error number and yet treat this byte as a character.
+		 */
+		sz1 = u8_number_of_bytes[*s1];
+		if (sz1 < 0) {
+			*errnum = EILSEQ;
+			sz1 = 1;
+		}
+
+		/*
+		 * For 7-bit ASCII characters mainly, we do a quick case
+		 * conversion right at here.
+		 *
+		 * If we don't have enough bytes for this character, issue
+		 * an EINVAL error and use what are available.
+		 *
+		 * If we have enough bytes, find out if there is
+		 * a corresponding uppercase character and if so, copy over
+		 * the bytes for a comparison later. If there is no
+		 * corresponding uppercase character, then, use what we have
+		 * for the comparison.
+		 */
+		if (sz1 == 1) {
+			if (is_it_toupper)
+				u8s1[0] = U8_ASCII_TOUPPER(*s1);
+			else
+				u8s1[0] = U8_ASCII_TOLOWER(*s1);
+			s1++;
+			u8s1[1] = '\0';
+		} else if ((i1 + sz1) > n1) {
+			*errnum = EINVAL;
+			for (j = 0; (i1 + j) < n1; )
+				u8s1[j++] = *s1++;
+			u8s1[j] = '\0';
+		} else {
+			(void) do_case_conv(uv, u8s1, s1, sz1, is_it_toupper);
+			s1 += sz1;
+		}
+
+		/* Do the same for the string s2. */
+		sz2 = u8_number_of_bytes[*s2];
+		if (sz2 < 0) {
+			*errnum = EILSEQ;
+			sz2 = 1;
+		}
+
+		if (sz2 == 1) {
+			if (is_it_toupper)
+				u8s2[0] = U8_ASCII_TOUPPER(*s2);
+			else
+				u8s2[0] = U8_ASCII_TOLOWER(*s2);
+			s2++;
+			u8s2[1] = '\0';
+		} else if ((i2 + sz2) > n2) {
+			*errnum = EINVAL;
+			for (j = 0; (i2 + j) < n2; )
+				u8s2[j++] = *s2++;
+			u8s2[j] = '\0';
+		} else {
+			(void) do_case_conv(uv, u8s2, s2, sz2, is_it_toupper);
+			s2 += sz2;
+		}
+
+		/* Now compare the two characters. */
+		if (sz1 == 1 && sz2 == 1) {
+			if (*u8s1 > *u8s2)
+				return (1);
+			if (*u8s1 < *u8s2)
+				return (-1);
+		} else {
+			f = strcmp((const char *)u8s1, (const char *)u8s2);
+			if (f != 0)
+				return (f);
+		}
+
+		/*
+		 * They were the same. Let's move on to the next
+		 * characters then.
+		 */
+		i1 += sz1;
+		i2 += sz2;
+	}
+
+	/*
+	 * We compared until the end of either or both strings.
+	 *
+	 * If we reached to or went over the ends for the both, that means
+	 * they are the same.
+	 *
+	 * If we reached only one of the two ends, that means the other string
+	 * has something which then the fact can be used to determine
+	 * the return value.
+	 */
+	if (i1 >= n1) {
+		if (i2 >= n2)
+			return (0);
+		return (-1);
+	}
+	return (1);
+}
+
+/*
+ * The combining_class() function checks on the given bytes and find out
+ * the corresponding Unicode combining class value. The return value 0 means
+ * it is a Starter. Any illegal UTF-8 character will also be treated as
+ * a Starter.
+ */
+static uchar_t
+combining_class(size_t uv, uchar_t *s, size_t sz)
+{
+	uint16_t b1 = 0;
+	uint16_t b2 = 0;
+	uint16_t b3 = 0;
+	uint16_t b4 = 0;
+
+	if (sz == 1 || sz > 4)
+		return (0);
+
+	if (sz == 2) {
+		b3 = s[0];
+		b4 = s[1];
+	} else if (sz == 3) {
+		b2 = s[0];
+		b3 = s[1];
+		b4 = s[2];
+	} else if (sz == 4) {
+		b1 = s[0];
+		b2 = s[1];
+		b3 = s[2];
+		b4 = s[3];
+	}
+
+	b1 = u8_common_b1_tbl[uv][b1];
+	if (b1 == U8_TBL_ELEMENT_NOT_DEF)
+		return (0);
+
+	b2 = u8_combining_class_b2_tbl[uv][b1][b2];
+	if (b2 == U8_TBL_ELEMENT_NOT_DEF)
+		return (0);
+
+	b3 = u8_combining_class_b3_tbl[uv][b2][b3];
+	if (b3 == U8_TBL_ELEMENT_NOT_DEF)
+		return (0);
+
+	return (u8_combining_class_b4_tbl[uv][b3][b4]);
+}
+
+/*
+ * The do_decomp() function finds out a matching decomposition if any
+ * and return. If there is no match, the input bytes are copied and returned.
+ * The function also checks if there is a Hangul, decomposes it if necessary
+ * and returns.
+ *
+ * To save time, a single byte 7-bit ASCII character should be handled by
+ * the caller.
+ *
+ * The function returns the number of bytes returned sans always terminating
+ * the null byte. It will also return a state that will tell if there was
+ * a Hangul character decomposed which then will be used by the caller.
+ */
+static size_t
+do_decomp(size_t uv, uchar_t *u8s, uchar_t *s, int sz,
+	boolean_t canonical_decomposition, u8_normalization_states_t *state)
+{
+	uint16_t b1 = 0;
+	uint16_t b2 = 0;
+	uint16_t b3 = 0;
+	uint16_t b3_tbl;
+	uint16_t b3_base;
+	uint16_t b4 = 0;
+	size_t start_id;
+	size_t end_id;
+	size_t i;
+	uint32_t u1;
+
+	if (sz == 2) {
+		b3 = u8s[0] = s[0];
+		b4 = u8s[1] = s[1];
+		u8s[2] = '\0';
+	} else if (sz == 3) {
+		/* Convert it to a Unicode scalar value. */
+		U8_PUT_3BYTES_INTO_UTF32(u1, s[0], s[1], s[2]);
+
+		/*
+		 * If this is a Hangul syllable, we decompose it into
+		 * a leading consonant, a vowel, and an optional trailing
+		 * consonant and then return.
+		 */
+		if (U8_HANGUL_SYLLABLE(u1)) {
+			u1 -= U8_HANGUL_SYL_FIRST;
+
+			b1 = U8_HANGUL_JAMO_L_FIRST + u1 / U8_HANGUL_VT_COUNT;
+			b2 = U8_HANGUL_JAMO_V_FIRST + (u1 % U8_HANGUL_VT_COUNT)
+			    / U8_HANGUL_T_COUNT;
+			b3 = u1 % U8_HANGUL_T_COUNT;
+
+			U8_SAVE_HANGUL_AS_UTF8(u8s, 0, 1, 2, b1);
+			U8_SAVE_HANGUL_AS_UTF8(u8s, 3, 4, 5, b2);
+			if (b3) {
+				b3 += U8_HANGUL_JAMO_T_FIRST;
+				U8_SAVE_HANGUL_AS_UTF8(u8s, 6, 7, 8, b3);
+
+				u8s[9] = '\0';
+				*state = U8_STATE_HANGUL_LVT;
+				return (9);
+			}
+
+			u8s[6] = '\0';
+			*state = U8_STATE_HANGUL_LV;
+			return (6);
+		}
+
+		b2 = u8s[0] = s[0];
+		b3 = u8s[1] = s[1];
+		b4 = u8s[2] = s[2];
+		u8s[3] = '\0';
+
+		/*
+		 * If this is a Hangul Jamo, we know there is nothing
+		 * further that we can decompose.
+		 */
+		if (U8_HANGUL_JAMO_L(u1)) {
+			*state = U8_STATE_HANGUL_L;
+			return (3);
+		}
+
+		if (U8_HANGUL_JAMO_V(u1)) {
+			if (*state == U8_STATE_HANGUL_L)
+				*state = U8_STATE_HANGUL_LV;
+			else
+				*state = U8_STATE_HANGUL_V;
+			return (3);
+		}
+
+		if (U8_HANGUL_JAMO_T(u1)) {
+			if (*state == U8_STATE_HANGUL_LV)
+				*state = U8_STATE_HANGUL_LVT;
+			else
+				*state = U8_STATE_HANGUL_T;
+			return (3);
+		}
+	} else if (sz == 4) {
+		b1 = u8s[0] = s[0];
+		b2 = u8s[1] = s[1];
+		b3 = u8s[2] = s[2];
+		b4 = u8s[3] = s[3];
+		u8s[4] = '\0';
+	} else {
+		/*
+		 * This is a fallback and should not happen if the function
+		 * was called properly.
+		 */
+		u8s[0] = s[0];
+		u8s[1] = '\0';
+		*state = U8_STATE_START;
+		return (1);
+	}
+
+	/*
+	 * At this point, this rountine does not know what it would get.
+	 * The caller should sort it out if the state isn't a Hangul one.
+	 */
+	*state = U8_STATE_START;
+
+	/* Try to find matching decomposition mapping byte sequence. */
+	b1 = u8_common_b1_tbl[uv][b1];
+	if (b1 == U8_TBL_ELEMENT_NOT_DEF)
+		return ((size_t)sz);
+
+	b2 = u8_decomp_b2_tbl[uv][b1][b2];
+	if (b2 == U8_TBL_ELEMENT_NOT_DEF)
+		return ((size_t)sz);
+
+	b3_tbl = u8_decomp_b3_tbl[uv][b2][b3].tbl_id;
+	if (b3_tbl == U8_TBL_ELEMENT_NOT_DEF)
+		return ((size_t)sz);
+
+	/*
+	 * If b3_tbl is bigger than or equal to U8_16BIT_TABLE_INDICATOR
+	 * which is 0x8000, this means we couldn't fit the mappings into
+	 * the cardinality of a unsigned byte.
+	 */
+	if (b3_tbl >= U8_16BIT_TABLE_INDICATOR) {
+		b3_tbl -= U8_16BIT_TABLE_INDICATOR;
+		start_id = u8_decomp_b4_16bit_tbl[uv][b3_tbl][b4];
+		end_id = u8_decomp_b4_16bit_tbl[uv][b3_tbl][b4 + 1];
+	} else {
+		start_id = u8_decomp_b4_tbl[uv][b3_tbl][b4];
+		end_id = u8_decomp_b4_tbl[uv][b3_tbl][b4 + 1];
+	}
+
+	/* This also means there wasn't any matching decomposition. */
+	if (start_id >= end_id)
+		return ((size_t)sz);
+
+	/*
+	 * The final table for decomposition mappings has three types of
+	 * byte sequences depending on whether a mapping is for compatibility
+	 * decomposition, canonical decomposition, or both like the following:
+	 *
+	 * (1) Compatibility decomposition mappings:
+	 *
+	 *	+---+---+-...-+---+
+	 *	| B0| B1| ... | Bm|
+	 *	+---+---+-...-+---+
+	 *
+	 *	The first byte, B0, is always less then 0xF5 (U8_DECOMP_BOTH).
+	 *
+	 * (2) Canonical decomposition mappings:
+	 *
+	 *	+---+---+---+-...-+---+
+	 *	| T | b0| b1| ... | bn|
+	 *	+---+---+---+-...-+---+
+	 *
+	 *	where the first byte, T, is 0xF6 (U8_DECOMP_CANONICAL).
+	 *
+	 * (3) Both mappings:
+	 *
+	 *	+---+---+---+---+-...-+---+---+---+-...-+---+
+	 *	| T | D | b0| b1| ... | bn| B0| B1| ... | Bm|
+	 *	+---+---+---+---+-...-+---+---+---+-...-+---+
+	 *
+	 *	where T is 0xF5 (U8_DECOMP_BOTH) and D is a displacement
+	 *	byte, b0 to bn are canonical mapping bytes and B0 to Bm are
+	 *	compatibility mapping bytes.
+	 *
+	 * Note that compatibility decomposition means doing recursive
+	 * decompositions using both compatibility decomposition mappings and
+	 * canonical decomposition mappings. On the other hand, canonical
+	 * decomposition means doing recursive decompositions using only
+	 * canonical decomposition mappings. Since the table we have has gone
+	 * through the recursions already, we do not need to do so during
+	 * runtime, i.e., the table has been completely flattened out
+	 * already.
+	 */
+
+	b3_base = u8_decomp_b3_tbl[uv][b2][b3].base;
+
+	/* Get the type, T, of the byte sequence. */
+	b1 = u8_decomp_final_tbl[uv][b3_base + start_id];
+
+	/*
+	 * If necessary, adjust start_id, end_id, or both. Note that if
+	 * this is compatibility decomposition mapping, there is no
+	 * adjustment.
+	 */
+	if (canonical_decomposition) {
+		/* Is the mapping only for compatibility decomposition? */
+		if (b1 < U8_DECOMP_BOTH)
+			return ((size_t)sz);
+
+		start_id++;
+
+		if (b1 == U8_DECOMP_BOTH) {
+			end_id = start_id +
+			    u8_decomp_final_tbl[uv][b3_base + start_id];
+			start_id++;
+		}
+	} else {
+		/*
+		 * Unless this is a compatibility decomposition mapping,
+		 * we adjust the start_id.
+		 */
+		if (b1 == U8_DECOMP_BOTH) {
+			start_id++;
+			start_id += u8_decomp_final_tbl[uv][b3_base + start_id];
+		} else if (b1 == U8_DECOMP_CANONICAL) {
+			start_id++;
+		}
+	}
+
+	for (i = 0; start_id < end_id; start_id++)
+		u8s[i++] = u8_decomp_final_tbl[uv][b3_base + start_id];
+	u8s[i] = '\0';
+
+	return (i);
+}
+
+/*
+ * The find_composition_start() function uses the character bytes given and
+ * find out the matching composition mappings if any and return the address
+ * to the composition mappings as explained in the do_composition().
+ */
+static uchar_t *
+find_composition_start(size_t uv, uchar_t *s, size_t sz)
+{
+	uint16_t b1 = 0;
+	uint16_t b2 = 0;
+	uint16_t b3 = 0;
+	uint16_t b3_tbl;
+	uint16_t b3_base;
+	uint16_t b4 = 0;
+	size_t start_id;
+	size_t end_id;
+
+	if (sz == 1) {
+		b4 = s[0];
+	} else if (sz == 2) {
+		b3 = s[0];
+		b4 = s[1];
+	} else if (sz == 3) {
+		b2 = s[0];
+		b3 = s[1];
+		b4 = s[2];
+	} else if (sz == 4) {
+		b1 = s[0];
+		b2 = s[1];
+		b3 = s[2];
+		b4 = s[3];
+	} else {
+		/*
+		 * This is a fallback and should not happen if the function
+		 * was called properly.
+		 */
+		return (NULL);
+	}
+
+	b1 = u8_composition_b1_tbl[uv][b1];
+	if (b1 == U8_TBL_ELEMENT_NOT_DEF)
+		return (NULL);
+
+	b2 = u8_composition_b2_tbl[uv][b1][b2];
+	if (b2 == U8_TBL_ELEMENT_NOT_DEF)
+		return (NULL);
+
+	b3_tbl = u8_composition_b3_tbl[uv][b2][b3].tbl_id;
+	if (b3_tbl == U8_TBL_ELEMENT_NOT_DEF)
+		return (NULL);
+
+	if (b3_tbl >= U8_16BIT_TABLE_INDICATOR) {
+		b3_tbl -= U8_16BIT_TABLE_INDICATOR;
+		start_id = u8_composition_b4_16bit_tbl[uv][b3_tbl][b4];
+		end_id = u8_composition_b4_16bit_tbl[uv][b3_tbl][b4 + 1];
+	} else {
+		start_id = u8_composition_b4_tbl[uv][b3_tbl][b4];
+		end_id = u8_composition_b4_tbl[uv][b3_tbl][b4 + 1];
+	}
+
+	if (start_id >= end_id)
+		return (NULL);
+
+	b3_base = u8_composition_b3_tbl[uv][b2][b3].base;
+
+	return ((uchar_t *)&(u8_composition_final_tbl[uv][b3_base + start_id]));
+}
+
+/*
+ * The blocked() function checks on the combining class values of previous
+ * characters in this sequence and return whether it is blocked or not.
+ */
+static boolean_t
+blocked(uchar_t *comb_class, size_t last)
+{
+	uchar_t my_comb_class;
+	size_t i;
+
+	my_comb_class = comb_class[last];
+	for (i = 1; i < last; i++)
+		if (comb_class[i] >= my_comb_class ||
+		    comb_class[i] == U8_COMBINING_CLASS_STARTER)
+			return (B_TRUE);
+
+	return (B_FALSE);
+}
+
+/*
+ * The do_composition() reads the character string pointed by 's' and
+ * do necessary canonical composition and then copy over the result back to
+ * the 's'.
+ *
+ * The input argument 's' cannot contain more than 32 characters.
+ */
+static size_t
+do_composition(size_t uv, uchar_t *s, uchar_t *comb_class, uchar_t *start,
+	uchar_t *disp, size_t last, uchar_t **os, uchar_t *oslast)
+{
+	uchar_t t[U8_STREAM_SAFE_TEXT_MAX + 1];
+	uchar_t tc[U8_MB_CUR_MAX];
+	uint8_t saved_marks[U8_MAX_CHARS_A_SEQ];
+	size_t saved_marks_count;
+	uchar_t *p;
+	uchar_t *saved_p;
+	uchar_t *q;
+	size_t i;
+	size_t saved_i;
+	size_t j;
+	size_t k;
+	size_t l;
+	size_t C;
+	size_t saved_l;
+	size_t size;
+	uint32_t u1;
+	uint32_t u2;
+	boolean_t match_not_found = B_TRUE;
+
+	/*
+	 * This should never happen unless the callers are doing some strange
+	 * and unexpected things.
+	 *
+	 * The "last" is the index pointing to the last character not last + 1.
+	 */
+	if (last >= U8_MAX_CHARS_A_SEQ)
+		last = U8_UPPER_LIMIT_IN_A_SEQ;
+
+	for (i = l = 0; i <= last; i++) {
+		/*
+		 * The last or any non-Starters at the beginning, we don't
+		 * have any chance to do composition and so we just copy them
+		 * to the temporary buffer.
+		 */
+		if (i >= last || comb_class[i] != U8_COMBINING_CLASS_STARTER) {
+SAVE_THE_CHAR:
+			p = s + start[i];
+			size = disp[i];
+			for (k = 0; k < size; k++)
+				t[l++] = *p++;
+			continue;
+		}
+
+		/*
+		 * If this could be a start of Hangul Jamos, then, we try to
+		 * conjoin them.
+		 */
+		if (s[start[i]] == U8_HANGUL_JAMO_1ST_BYTE) {
+			U8_PUT_3BYTES_INTO_UTF32(u1, s[start[i]],
+			    s[start[i] + 1], s[start[i] + 2]);
+			U8_PUT_3BYTES_INTO_UTF32(u2, s[start[i] + 3],
+			    s[start[i] + 4], s[start[i] + 5]);
+
+			if (U8_HANGUL_JAMO_L(u1) && U8_HANGUL_JAMO_V(u2)) {
+				u1 -= U8_HANGUL_JAMO_L_FIRST;
+				u2 -= U8_HANGUL_JAMO_V_FIRST;
+				u1 = U8_HANGUL_SYL_FIRST +
+				    (u1 * U8_HANGUL_V_COUNT + u2) *
+				    U8_HANGUL_T_COUNT;
+
+				i += 2;
+				if (i <= last) {
+					U8_PUT_3BYTES_INTO_UTF32(u2,
+					    s[start[i]], s[start[i] + 1],
+					    s[start[i] + 2]);
+
+					if (U8_HANGUL_JAMO_T(u2)) {
+						u1 += u2 -
+						    U8_HANGUL_JAMO_T_FIRST;
+						i++;
+					}
+				}
+
+				U8_SAVE_HANGUL_AS_UTF8(t + l, 0, 1, 2, u1);
+				i--;
+				l += 3;
+				continue;
+			}
+		}
+
+		/*
+		 * Let's then find out if this Starter has composition
+		 * mapping.
+		 */
+		p = find_composition_start(uv, s + start[i], disp[i]);
+		if (p == NULL)
+			goto SAVE_THE_CHAR;
+
+		/*
+		 * We have a Starter with composition mapping and the next
+		 * character is a non-Starter. Let's try to find out if
+		 * we can do composition.
+		 */
+
+		saved_p = p;
+		saved_i = i;
+		saved_l = l;
+		saved_marks_count = 0;
+
+TRY_THE_NEXT_MARK:
+		q = s + start[++i];
+		size = disp[i];
+
+		/*
+		 * The next for() loop compares the non-Starter pointed by
+		 * 'q' with the possible (joinable) characters pointed by 'p'.
+		 *
+		 * The composition final table entry pointed by the 'p'
+		 * looks like the following:
+		 *
+		 * +---+---+---+-...-+---+---+---+---+-...-+---+---+
+		 * | C | b0| b2| ... | bn| F | B0| B1| ... | Bm| F |
+		 * +---+---+---+-...-+---+---+---+---+-...-+---+---+
+		 *
+		 * where C is the count byte indicating the number of
+		 * mapping pairs where each pair would be look like
+		 * (b0-bn F, B0-Bm F). The b0-bn are the bytes of the second
+		 * character of a canonical decomposition and the B0-Bm are
+		 * the bytes of a matching composite character. The F is
+		 * a filler byte after each character as the separator.
+		 */
+
+		match_not_found = B_TRUE;
+
+		for (C = *p++; C > 0; C--) {
+			for (k = 0; k < size; p++, k++)
+				if (*p != q[k])
+					break;
+
+			/* Have we found it? */
+			if (k >= size && *p == U8_TBL_ELEMENT_FILLER) {
+				match_not_found = B_FALSE;
+
+				l = saved_l;
+
+				while (*++p != U8_TBL_ELEMENT_FILLER)
+					t[l++] = *p;
+
+				break;
+			}
+
+			/* We didn't find; skip to the next pair. */
+			if (*p != U8_TBL_ELEMENT_FILLER)
+				while (*++p != U8_TBL_ELEMENT_FILLER)
+					;
+			while (*++p != U8_TBL_ELEMENT_FILLER)
+				;
+			p++;
+		}
+
+		/*
+		 * If there was no match, we will need to save the combining
+		 * mark for later appending. After that, if the next one
+		 * is a non-Starter and not blocked, then, we try once
+		 * again to do composition with the next non-Starter.
+		 *
+		 * If there was no match and this was a Starter, then,
+		 * this is a new start.
+		 *
+		 * If there was a match and a composition done and we have
+		 * more to check on, then, we retrieve a new composition final
+		 * table entry for the composite and then try to do the
+		 * composition again.
+		 */
+
+		if (match_not_found) {
+			if (comb_class[i] == U8_COMBINING_CLASS_STARTER) {
+				i--;
+				goto SAVE_THE_CHAR;
+			}
+
+			saved_marks[saved_marks_count++] = i;
+		}
+
+		if (saved_l == l) {
+			while (i < last) {
+				if (blocked(comb_class, i + 1))
+					saved_marks[saved_marks_count++] = ++i;
+				else
+					break;
+			}
+			if (i < last) {
+				p = saved_p;
+				goto TRY_THE_NEXT_MARK;
+			}
+		} else if (i < last) {
+			p = find_composition_start(uv, t + saved_l,
+			    l - saved_l);
+			if (p != NULL) {
+				saved_p = p;
+				goto TRY_THE_NEXT_MARK;
+			}
+		}
+
+		/*
+		 * There is no more composition possible.
+		 *
+		 * If there was no composition what so ever then we copy
+		 * over the original Starter and then append any non-Starters
+		 * remaining at the target string sequentially after that.
+		 */
+
+		if (saved_l == l) {
+			p = s + start[saved_i];
+			size = disp[saved_i];
+			for (j = 0; j < size; j++)
+				t[l++] = *p++;
+		}
+
+		for (k = 0; k < saved_marks_count; k++) {
+			p = s + start[saved_marks[k]];
+			size = disp[saved_marks[k]];
+			for (j = 0; j < size; j++)
+				t[l++] = *p++;
+		}
+	}
+
+	/*
+	 * If the last character is a Starter and if we have a character
+	 * (possibly another Starter) that can be turned into a composite,
+	 * we do so and we do so until there is no more of composition
+	 * possible.
+	 */
+	if (comb_class[last] == U8_COMBINING_CLASS_STARTER) {
+		p = *os;
+		saved_l = l - disp[last];
+
+		while (p < oslast) {
+			size = u8_number_of_bytes[*p];
+			if (size <= 1 || (p + size) > oslast)
+				break;
+
+			saved_p = p;
+
+			for (i = 0; i < size; i++)
+				tc[i] = *p++;
+
+			q = find_composition_start(uv, t + saved_l,
+			    l - saved_l);
+			if (q == NULL) {
+				p = saved_p;
+				break;
+			}
+
+			match_not_found = B_TRUE;
+
+			for (C = *q++; C > 0; C--) {
+				for (k = 0; k < size; q++, k++)
+					if (*q != tc[k])
+						break;
+
+				if (k >= size && *q == U8_TBL_ELEMENT_FILLER) {
+					match_not_found = B_FALSE;
+
+					l = saved_l;
+
+					while (*++q != U8_TBL_ELEMENT_FILLER) {
+						/*
+						 * This is practically
+						 * impossible but we don't
+						 * want to take any chances.
+						 */
+						if (l >=
+						    U8_STREAM_SAFE_TEXT_MAX) {
+							p = saved_p;
+							goto SAFE_RETURN;
+						}
+						t[l++] = *q;
+					}
+
+					break;
+				}
+
+				if (*q != U8_TBL_ELEMENT_FILLER)
+					while (*++q != U8_TBL_ELEMENT_FILLER)
+						;
+				while (*++q != U8_TBL_ELEMENT_FILLER)
+					;
+				q++;
+			}
+
+			if (match_not_found) {
+				p = saved_p;
+				break;
+			}
+		}
+SAFE_RETURN:
+		*os = p;
+	}
+
+	/*
+	 * Now we copy over the temporary string to the target string.
+	 * Since composition always reduces the number of characters or
+	 * the number of characters stay, we don't need to worry about
+	 * the buffer overflow here.
+	 */
+	for (i = 0; i < l; i++)
+		s[i] = t[i];
+	s[l] = '\0';
+
+	return (l);
+}
+
+/*
+ * The collect_a_seq() function checks on the given string s, collect
+ * a sequence of characters at u8s, and return the sequence. While it collects
+ * a sequence, it also applies case conversion, canonical or compatibility
+ * decomposition, canonical decomposition, or some or all of them and
+ * in that order.
+ *
+ * The collected sequence cannot be bigger than 32 characters since if
+ * it is having more than 31 characters, the sequence will be terminated
+ * with a U+034F COMBINING GRAPHEME JOINER (CGJ) character and turned into
+ * a Stream-Safe Text. The collected sequence is always terminated with
+ * a null byte and the return value is the byte length of the sequence
+ * including 0. The return value does not include the terminating
+ * null byte.
+ */
+static size_t
+collect_a_seq(size_t uv, uchar_t *u8s, uchar_t **source, uchar_t *slast,
+	boolean_t is_it_toupper,
+	boolean_t is_it_tolower,
+	boolean_t canonical_decomposition,
+	boolean_t compatibility_decomposition,
+	boolean_t canonical_composition,
+	int *errnum, u8_normalization_states_t *state)
+{
+	uchar_t *s;
+	int sz;
+	int saved_sz;
+	size_t i;
+	size_t j;
+	size_t k;
+	size_t l;
+	uchar_t comb_class[U8_MAX_CHARS_A_SEQ];
+	uchar_t disp[U8_MAX_CHARS_A_SEQ];
+	uchar_t start[U8_MAX_CHARS_A_SEQ];
+	uchar_t u8t[U8_MB_CUR_MAX];
+	uchar_t uts[U8_STREAM_SAFE_TEXT_MAX + 1];
+	uchar_t tc;
+	size_t last;
+	size_t saved_last;
+	uint32_t u1;
+
+	/*
+	 * Save the source string pointer which we will return a changed
+	 * pointer if we do processing.
+	 */
+	s = *source;
+
+	/*
+	 * The following is a fallback for just in case callers are not
+	 * checking the string boundaries before the calling.
+	 */
+	if (s >= slast) {
+		u8s[0] = '\0';
+
+		return (0);
+	}
+
+	/*
+	 * As the first thing, let's collect a character and do case
+	 * conversion if necessary.
+	 */
+
+	sz = u8_number_of_bytes[*s];
+
+	if (sz < 0) {
+		*errnum = EILSEQ;
+
+		u8s[0] = *s++;
+		u8s[1] = '\0';
+
+		*source = s;
+
+		return (1);
+	}
+
+	if (sz == 1) {
+		if (is_it_toupper)
+			u8s[0] = U8_ASCII_TOUPPER(*s);
+		else if (is_it_tolower)
+			u8s[0] = U8_ASCII_TOLOWER(*s);
+		else
+			u8s[0] = *s;
+		s++;
+		u8s[1] = '\0';
+	} else if ((s + sz) > slast) {
+		*errnum = EINVAL;
+
+		for (i = 0; s < slast; )
+			u8s[i++] = *s++;
+		u8s[i] = '\0';
+
+		*source = s;
+
+		return (i);
+	} else {
+		if (is_it_toupper || is_it_tolower) {
+			i = do_case_conv(uv, u8s, s, sz, is_it_toupper);
+			s += sz;
+			sz = i;
+		} else {
+			for (i = 0; i < sz; )
+				u8s[i++] = *s++;
+			u8s[i] = '\0';
+		}
+	}
+
+	/*
+	 * And then canonical/compatibility decomposition followed by
+	 * an optional canonical composition. Please be noted that
+	 * canonical composition is done only when a decomposition is
+	 * done.
+	 */
+	if (canonical_decomposition || compatibility_decomposition) {
+		if (sz == 1) {
+			*state = U8_STATE_START;
+
+			saved_sz = 1;
+
+			comb_class[0] = 0;
+			start[0] = 0;
+			disp[0] = 1;
+
+			last = 1;
+		} else {
+			saved_sz = do_decomp(uv, u8s, u8s, sz,
+			    canonical_decomposition, state);
+
+			last = 0;
+
+			for (i = 0; i < saved_sz; ) {
+				sz = u8_number_of_bytes[u8s[i]];
+
+				comb_class[last] = combining_class(uv,
+				    u8s + i, sz);
+				start[last] = i;
+				disp[last] = sz;
+
+				last++;
+				i += sz;
+			}
+
+			/*
+			 * Decomposition yields various Hangul related
+			 * states but not on combining marks. We need to
+			 * find out at here by checking on the last
+			 * character.
+			 */
+			if (*state == U8_STATE_START) {
+				if (comb_class[last - 1])
+					*state = U8_STATE_COMBINING_MARK;
+			}
+		}
+
+		saved_last = last;
+
+		while (s < slast) {
+			sz = u8_number_of_bytes[*s];
+
+			/*
+			 * If this is an illegal character, an incomplete
+			 * character, or an 7-bit ASCII Starter character,
+			 * then we have collected a sequence; break and let
+			 * the next call deal with the two cases.
+			 *
+			 * Note that this is okay only if you are using this
+			 * function with a fixed length string, not on
+			 * a buffer with multiple calls of one chunk at a time.
+			 */
+			if (sz <= 1) {
+				break;
+			} else if ((s + sz) > slast) {
+				break;
+			} else {
+				/*
+				 * If the previous character was a Hangul Jamo
+				 * and this character is a Hangul Jamo that
+				 * can be conjoined, we collect the Jamo.
+				 */
+				if (*s == U8_HANGUL_JAMO_1ST_BYTE) {
+					U8_PUT_3BYTES_INTO_UTF32(u1,
+					    *s, *(s + 1), *(s + 2));
+
+					if (U8_HANGUL_COMPOSABLE_L_V(*state,
+					    u1)) {
+						i = 0;
+						*state = U8_STATE_HANGUL_LV;
+						goto COLLECT_A_HANGUL;
+					}
+
+					if (U8_HANGUL_COMPOSABLE_LV_T(*state,
+					    u1)) {
+						i = 0;
+						*state = U8_STATE_HANGUL_LVT;
+						goto COLLECT_A_HANGUL;
+					}
+				}
+
+				/*
+				 * Regardless of whatever it was, if this is
+				 * a Starter, we don't collect the character
+				 * since that's a new start and we will deal
+				 * with it at the next time.
+				 */
+				i = combining_class(uv, s, sz);
+				if (i == U8_COMBINING_CLASS_STARTER)
+					break;
+
+				/*
+				 * We know the current character is a combining
+				 * mark. If the previous character wasn't
+				 * a Starter (not Hangul) or a combining mark,
+				 * then, we don't collect this combining mark.
+				 */
+				if (*state != U8_STATE_START &&
+				    *state != U8_STATE_COMBINING_MARK)
+					break;
+
+				*state = U8_STATE_COMBINING_MARK;
+COLLECT_A_HANGUL:
+				/*
+				 * If we collected a Starter and combining
+				 * marks up to 30, i.e., total 31 characters,
+				 * then, we terminate this degenerately long
+				 * combining sequence with a U+034F COMBINING
+				 * GRAPHEME JOINER (CGJ) which is 0xCD 0x8F in
+				 * UTF-8 and turn this into a Stream-Safe
+				 * Text. This will be extremely rare but
+				 * possible.
+				 *
+				 * The following will also guarantee that
+				 * we are not writing more than 32 characters
+				 * plus a NULL at u8s[].
+				 */
+				if (last >= U8_UPPER_LIMIT_IN_A_SEQ) {
+TURN_STREAM_SAFE:
+					*state = U8_STATE_START;
+					comb_class[last] = 0;
+					start[last] = saved_sz;
+					disp[last] = 2;
+					last++;
+
+					u8s[saved_sz++] = 0xCD;
+					u8s[saved_sz++] = 0x8F;
+
+					break;
+				}
+
+				/*
+				 * Some combining marks also do decompose into
+				 * another combining mark or marks.
+				 */
+				if (*state == U8_STATE_COMBINING_MARK) {
+					k = last;
+					l = sz;
+					i = do_decomp(uv, uts, s, sz,
+					    canonical_decomposition, state);
+					for (j = 0; j < i; ) {
+						sz = u8_number_of_bytes[uts[j]];
+
+						comb_class[last] =
+						    combining_class(uv,
+						    uts + j, sz);
+						start[last] = saved_sz + j;
+						disp[last] = sz;
+
+						last++;
+						if (last >=
+						    U8_UPPER_LIMIT_IN_A_SEQ) {
+							last = k;
+							goto TURN_STREAM_SAFE;
+						}
+						j += sz;
+					}
+
+					*state = U8_STATE_COMBINING_MARK;
+					sz = i;
+					s += l;
+
+					for (i = 0; i < sz; i++)
+						u8s[saved_sz++] = uts[i];
+				} else {
+					comb_class[last] = i;
+					start[last] = saved_sz;
+					disp[last] = sz;
+					last++;
+
+					for (i = 0; i < sz; i++)
+						u8s[saved_sz++] = *s++;
+				}
+
+				/*
+				 * If this is U+0345 COMBINING GREEK
+				 * YPOGEGRAMMENI (0xCD 0x85 in UTF-8), a.k.a.,
+				 * iota subscript, and need to be converted to
+				 * uppercase letter, convert it to U+0399 GREEK
+				 * CAPITAL LETTER IOTA (0xCE 0x99 in UTF-8),
+				 * i.e., convert to capital adscript form as
+				 * specified in the Unicode standard.
+				 *
+				 * This is the only special case of (ambiguous)
+				 * case conversion at combining marks and
+				 * probably the standard will never have
+				 * anything similar like this in future.
+				 */
+				if (is_it_toupper && sz >= 2 &&
+				    u8s[saved_sz - 2] == 0xCD &&
+				    u8s[saved_sz - 1] == 0x85) {
+					u8s[saved_sz - 2] = 0xCE;
+					u8s[saved_sz - 1] = 0x99;
+				}
+			}
+		}
+
+		/*
+		 * Let's try to ensure a canonical ordering for the collected
+		 * combining marks. We do this only if we have collected
+		 * at least one more non-Starter. (The decomposition mapping
+		 * data tables have fully (and recursively) expanded and
+		 * canonically ordered decompositions.)
+		 *
+		 * The U8_SWAP_COMB_MARKS() convenience macro has some
+		 * assumptions and we are meeting the assumptions.
+		 */
+		last--;
+		if (last >= saved_last) {
+			for (i = 0; i < last; i++)
+				for (j = last; j > i; j--)
+					if (comb_class[j] &&
+					    comb_class[j - 1] > comb_class[j]) {
+						U8_SWAP_COMB_MARKS(j - 1, j);
+					}
+		}
+
+		*source = s;
+
+		if (! canonical_composition) {
+			u8s[saved_sz] = '\0';
+			return (saved_sz);
+		}
+
+		/*
+		 * Now do the canonical composition. Note that we do this
+		 * only after a canonical or compatibility decomposition to
+		 * finish up NFC or NFKC.
+		 */
+		sz = do_composition(uv, u8s, comb_class, start, disp, last,
+		    &s, slast);
+	}
+
+	*source = s;
+
+	return ((size_t)sz);
+}
+
+/*
+ * The do_norm_compare() function does string comparion based on Unicode
+ * simple case mappings and Unicode Normalization definitions.
+ *
+ * It does so by collecting a sequence of character at a time and comparing
+ * the collected sequences from the strings.
+ *
+ * The meanings on the return values are the same as the usual strcmp().
+ */
+static int
+do_norm_compare(size_t uv, uchar_t *s1, uchar_t *s2, size_t n1, size_t n2,
+	int flag, int *errnum)
+{
+	int result;
+	size_t sz1;
+	size_t sz2;
+	uchar_t u8s1[U8_STREAM_SAFE_TEXT_MAX + 1];
+	uchar_t u8s2[U8_STREAM_SAFE_TEXT_MAX + 1];
+	uchar_t *s1last;
+	uchar_t *s2last;
+	boolean_t is_it_toupper;
+	boolean_t is_it_tolower;
+	boolean_t canonical_decomposition;
+	boolean_t compatibility_decomposition;
+	boolean_t canonical_composition;
+	u8_normalization_states_t state;
+
+	s1last = s1 + n1;
+	s2last = s2 + n2;
+
+	is_it_toupper = flag & U8_TEXTPREP_TOUPPER;
+	is_it_tolower = flag & U8_TEXTPREP_TOLOWER;
+	canonical_decomposition = flag & U8_CANON_DECOMP;
+	compatibility_decomposition = flag & U8_COMPAT_DECOMP;
+	canonical_composition = flag & U8_CANON_COMP;
+
+	while (s1 < s1last && s2 < s2last) {
+		/*
+		 * If the current character is a 7-bit ASCII and the last
+		 * character, or, if the current character and the next
+		 * character are both some 7-bit ASCII characters then
+		 * we treat the current character as a sequence.
+		 *
+		 * In any other cases, we need to call collect_a_seq().
+		 */
+
+		if (U8_ISASCII(*s1) && ((s1 + 1) >= s1last ||
+		    ((s1 + 1) < s1last && U8_ISASCII(*(s1 + 1))))) {
+			if (is_it_toupper)
+				u8s1[0] = U8_ASCII_TOUPPER(*s1);
+			else if (is_it_tolower)
+				u8s1[0] = U8_ASCII_TOLOWER(*s1);
+			else
+				u8s1[0] = *s1;
+			u8s1[1] = '\0';
+			sz1 = 1;
+			s1++;
+		} else {
+			state = U8_STATE_START;
+			sz1 = collect_a_seq(uv, u8s1, &s1, s1last,
+			    is_it_toupper, is_it_tolower,
+			    canonical_decomposition,
+			    compatibility_decomposition,
+			    canonical_composition, errnum, &state);
+		}
+
+		if (U8_ISASCII(*s2) && ((s2 + 1) >= s2last ||
+		    ((s2 + 1) < s2last && U8_ISASCII(*(s2 + 1))))) {
+			if (is_it_toupper)
+				u8s2[0] = U8_ASCII_TOUPPER(*s2);
+			else if (is_it_tolower)
+				u8s2[0] = U8_ASCII_TOLOWER(*s2);
+			else
+				u8s2[0] = *s2;
+			u8s2[1] = '\0';
+			sz2 = 1;
+			s2++;
+		} else {
+			state = U8_STATE_START;
+			sz2 = collect_a_seq(uv, u8s2, &s2, s2last,
+			    is_it_toupper, is_it_tolower,
+			    canonical_decomposition,
+			    compatibility_decomposition,
+			    canonical_composition, errnum, &state);
+		}
+
+		/*
+		 * Now compare the two characters. If they are the same,
+		 * we move on to the next character sequences.
+		 */
+		if (sz1 == 1 && sz2 == 1) {
+			if (*u8s1 > *u8s2)
+				return (1);
+			if (*u8s1 < *u8s2)
+				return (-1);
+		} else {
+			result = strcmp((const char *)u8s1, (const char *)u8s2);
+			if (result != 0)
+				return (result);
+		}
+	}
+
+	/*
+	 * We compared until the end of either or both strings.
+	 *
+	 * If we reached to or went over the ends for the both, that means
+	 * they are the same.
+	 *
+	 * If we reached only one end, that means the other string has
+	 * something which then can be used to determine the return value.
+	 */
+	if (s1 >= s1last) {
+		if (s2 >= s2last)
+			return (0);
+		return (-1);
+	}
+	return (1);
+}
+
+/*
+ * The u8_strcmp() function compares two UTF-8 strings quite similar to
+ * the strcmp(). For the comparison, however, Unicode Normalization specific
+ * equivalency and Unicode simple case conversion mappings based equivalency
+ * can be requested and checked against.
+ */
+int
+u8_strcmp(const char *s1, const char *s2, size_t n, int flag, size_t uv,
+		int *errnum)
+{
+	int f;
+	size_t n1;
+	size_t n2;
+
+	*errnum = 0;
+
+	/*
+	 * Check on the requested Unicode version, case conversion, and
+	 * normalization flag values.
+	 */
+
+	if (uv > U8_UNICODE_LATEST) {
+		*errnum = ERANGE;
+		uv = U8_UNICODE_LATEST;
+	}
+
+	if (flag == 0) {
+		flag = U8_STRCMP_CS;
+	} else {
+		f = flag & (U8_STRCMP_CS | U8_STRCMP_CI_UPPER |
+		    U8_STRCMP_CI_LOWER);
+		if (f == 0) {
+			flag |= U8_STRCMP_CS;
+		} else if (f != U8_STRCMP_CS && f != U8_STRCMP_CI_UPPER &&
+		    f != U8_STRCMP_CI_LOWER) {
+			*errnum = EBADF;
+			flag = U8_STRCMP_CS;
+		}
+
+		f = flag & (U8_CANON_DECOMP | U8_COMPAT_DECOMP | U8_CANON_COMP);
+		if (f && f != U8_STRCMP_NFD && f != U8_STRCMP_NFC &&
+		    f != U8_STRCMP_NFKD && f != U8_STRCMP_NFKC) {
+			*errnum = EBADF;
+			flag = U8_STRCMP_CS;
+		}
+	}
+
+	if (flag == U8_STRCMP_CS) {
+		return (n == 0 ? strcmp(s1, s2) : strncmp(s1, s2, n));
+	}
+
+	n1 = strlen(s1);
+	n2 = strlen(s2);
+	if (n != 0) {
+		if (n < n1)
+			n1 = n;
+		if (n < n2)
+			n2 = n;
+	}
+
+	/*
+	 * Simple case conversion can be done much faster and so we do
+	 * them separately here.
+	 */
+	if (flag == U8_STRCMP_CI_UPPER) {
+		return (do_case_compare(uv, (uchar_t *)s1, (uchar_t *)s2,
+		    n1, n2, B_TRUE, errnum));
+	} else if (flag == U8_STRCMP_CI_LOWER) {
+		return (do_case_compare(uv, (uchar_t *)s1, (uchar_t *)s2,
+		    n1, n2, B_FALSE, errnum));
+	}
+
+	return (do_norm_compare(uv, (uchar_t *)s1, (uchar_t *)s2, n1, n2,
+	    flag, errnum));
+}
+
+size_t
+u8_textprep_str(char *inarray, size_t *inlen, char *outarray, size_t *outlen,
+	int flag, size_t unicode_version, int *errnum)
+{
+	int f;
+	int sz;
+	uchar_t *ib;
+	uchar_t *ibtail;
+	uchar_t *ob;
+	uchar_t *obtail;
+	boolean_t do_not_ignore_null;
+	boolean_t do_not_ignore_invalid;
+	boolean_t is_it_toupper;
+	boolean_t is_it_tolower;
+	boolean_t canonical_decomposition;
+	boolean_t compatibility_decomposition;
+	boolean_t canonical_composition;
+	size_t ret_val;
+	size_t i;
+	size_t j;
+	uchar_t u8s[U8_STREAM_SAFE_TEXT_MAX + 1];
+	u8_normalization_states_t state;
+
+	if (unicode_version > U8_UNICODE_LATEST) {
+		*errnum = ERANGE;
+		return ((size_t)-1);
+	}
+
+	f = flag & (U8_TEXTPREP_TOUPPER | U8_TEXTPREP_TOLOWER);
+	if (f == (U8_TEXTPREP_TOUPPER | U8_TEXTPREP_TOLOWER)) {
+		*errnum = EBADF;
+		return ((size_t)-1);
+	}
+
+	f = flag & (U8_CANON_DECOMP | U8_COMPAT_DECOMP | U8_CANON_COMP);
+	if (f && f != U8_TEXTPREP_NFD && f != U8_TEXTPREP_NFC &&
+	    f != U8_TEXTPREP_NFKD && f != U8_TEXTPREP_NFKC) {
+		*errnum = EBADF;
+		return ((size_t)-1);
+	}
+
+	if (inarray == NULL || *inlen == 0)
+		return (0);
+
+	if (outarray == NULL) {
+		*errnum = E2BIG;
+		return ((size_t)-1);
+	}
+
+	ib = (uchar_t *)inarray;
+	ob = (uchar_t *)outarray;
+	ibtail = ib + *inlen;
+	obtail = ob + *outlen;
+
+	do_not_ignore_null = !(flag & U8_TEXTPREP_IGNORE_NULL);
+	do_not_ignore_invalid = !(flag & U8_TEXTPREP_IGNORE_INVALID);
+	is_it_toupper = flag & U8_TEXTPREP_TOUPPER;
+	is_it_tolower = flag & U8_TEXTPREP_TOLOWER;
+
+	ret_val = 0;
+
+	/*
+	 * If we don't have a normalization flag set, we do the simple case
+	 * conversion based text preparation separately below. Text
+	 * preparation involving Normalization will be done in the false task
+	 * block, again, separately since it will take much more time and
+	 * resource than doing simple case conversions.
+	 */
+	if (f == 0) {
+		while (ib < ibtail) {
+			if (*ib == '\0' && do_not_ignore_null)
+				break;
+
+			sz = u8_number_of_bytes[*ib];
+
+			if (sz < 0) {
+				if (do_not_ignore_invalid) {
+					*errnum = EILSEQ;
+					ret_val = (size_t)-1;
+					break;
+				}
+
+				sz = 1;
+				ret_val++;
+			}
+
+			if (sz == 1) {
+				if (ob >= obtail) {
+					*errnum = E2BIG;
+					ret_val = (size_t)-1;
+					break;
+				}
+
+				if (is_it_toupper)
+					*ob = U8_ASCII_TOUPPER(*ib);
+				else if (is_it_tolower)
+					*ob = U8_ASCII_TOLOWER(*ib);
+				else
+					*ob = *ib;
+				ib++;
+				ob++;
+			} else if ((ib + sz) > ibtail) {
+				if (do_not_ignore_invalid) {
+					*errnum = EINVAL;
+					ret_val = (size_t)-1;
+					break;
+				}
+
+				if ((obtail - ob) < (ibtail - ib)) {
+					*errnum = E2BIG;
+					ret_val = (size_t)-1;
+					break;
+				}
+
+				/*
+				 * We treat the remaining incomplete character
+				 * bytes as a character.
+				 */
+				ret_val++;
+
+				while (ib < ibtail)
+					*ob++ = *ib++;
+			} else {
+				if (is_it_toupper || is_it_tolower) {
+					i = do_case_conv(unicode_version, u8s,
+					    ib, sz, is_it_toupper);
+
+					if ((obtail - ob) < i) {
+						*errnum = E2BIG;
+						ret_val = (size_t)-1;
+						break;
+					}
+
+					ib += sz;
+
+					for (sz = 0; sz < i; sz++)
+						*ob++ = u8s[sz];
+				} else {
+					if ((obtail - ob) < sz) {
+						*errnum = E2BIG;
+						ret_val = (size_t)-1;
+						break;
+					}
+
+					for (i = 0; i < sz; i++)
+						*ob++ = *ib++;
+				}
+			}
+		}
+	} else {
+		canonical_decomposition = flag & U8_CANON_DECOMP;
+		compatibility_decomposition = flag & U8_COMPAT_DECOMP;
+		canonical_composition = flag & U8_CANON_COMP;
+
+		while (ib < ibtail) {
+			if (*ib == '\0' && do_not_ignore_null)
+				break;
+
+			/*
+			 * If the current character is a 7-bit ASCII
+			 * character and it is the last character, or,
+			 * if the current character is a 7-bit ASCII
+			 * character and the next character is also a 7-bit
+			 * ASCII character, then, we copy over this
+			 * character without going through collect_a_seq().
+			 *
+			 * In any other cases, we need to look further with
+			 * the collect_a_seq() function.
+			 */
+			if (U8_ISASCII(*ib) && ((ib + 1) >= ibtail ||
+			    ((ib + 1) < ibtail && U8_ISASCII(*(ib + 1))))) {
+				if (ob >= obtail) {
+					*errnum = E2BIG;
+					ret_val = (size_t)-1;
+					break;
+				}
+
+				if (is_it_toupper)
+					*ob = U8_ASCII_TOUPPER(*ib);
+				else if (is_it_tolower)
+					*ob = U8_ASCII_TOLOWER(*ib);
+				else
+					*ob = *ib;
+				ib++;
+				ob++;
+			} else {
+				*errnum = 0;
+				state = U8_STATE_START;
+
+				j = collect_a_seq(unicode_version, u8s,
+				    &ib, ibtail,
+				    is_it_toupper,
+				    is_it_tolower,
+				    canonical_decomposition,
+				    compatibility_decomposition,
+				    canonical_composition,
+				    errnum, &state);
+
+				if (*errnum && do_not_ignore_invalid) {
+					ret_val = (size_t)-1;
+					break;
+				}
+
+				if ((obtail - ob) < j) {
+					*errnum = E2BIG;
+					ret_val = (size_t)-1;
+					break;
+				}
+
+				for (i = 0; i < j; i++)
+					*ob++ = u8s[i];
+			}
+		}
+	}
+
+	*inlen = ibtail - ib;
+	*outlen = obtail - ob;
+
+	return (ret_val);
+}
+
+#if defined(_KERNEL) && defined(HAVE_SPL)
+static int __init
+unicode_init(void) {
+	return (0);
+}
+
+static void __exit
+unicode_fini(void)
+{
+}
+
+module_init(unicode_init);
+module_exit(unicode_fini);
+
+MODULE_DESCRIPTION("Unicode implementation");
+MODULE_AUTHOR(ZFS_META_AUTHOR);
+MODULE_LICENSE(ZFS_META_LICENSE);
+MODULE_VERSION(ZFS_META_VERSION "-" ZFS_META_RELEASE);
+
+EXPORT_SYMBOL(u8_validate);
+EXPORT_SYMBOL(u8_strcmp);
+EXPORT_SYMBOL(u8_textprep_str);
+#endif
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/module/unicode/uconv.c
@@ -0,0 +1,864 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+
+/*
+ * Unicode encoding conversion functions among UTF-8, UTF-16, and UTF-32.
+ * (PSARC/2005/446, PSARC/2007/038, PSARC/2007/517)
+ * Man pages: uconv_u16tou32(9F), uconv_u16tou8(9F), uconv_u32tou16(9F),
+ * uconv_u32tou8(9F), uconv_u8tou16(9F), and uconv_u8tou32(9F). See also
+ * the section 3C man pages.
+ * Interface stability: Committed
+ */
+
+#include <sys/types.h>
+#ifdef	_KERNEL
+#include <sys/param.h>
+#include <sys/sysmacros.h>
+#include <sys/systm.h>
+#include <sys/debug.h>
+#include <sys/kmem.h>
+#include <sys/sunddi.h>
+#else
+#include <sys/u8_textprep.h>
+#endif	/* _KERNEL */
+#include <sys/byteorder.h>
+#include <sys/errno.h>
+
+
+/*
+ * The max and min values of high and low surrogate pairs of UTF-16,
+ * UTF-16 bit shift value, bit mask, and starting value outside of BMP.
+ */
+#define	UCONV_U16_HI_MIN	(0xd800U)
+#define	UCONV_U16_HI_MAX	(0xdbffU)
+#define	UCONV_U16_LO_MIN	(0xdc00U)
+#define	UCONV_U16_LO_MAX	(0xdfffU)
+#define	UCONV_U16_BIT_SHIFT	(0x0400U)
+#define	UCONV_U16_BIT_MASK	(0x0fffffU)
+#define	UCONV_U16_START		(0x010000U)
+
+/* The maximum value of Unicode coding space and ASCII coding space. */
+#define	UCONV_UNICODE_MAX	(0x10ffffU)
+#define	UCONV_ASCII_MAX		(0x7fU)
+
+/* The mask values for input and output endians. */
+#define	UCONV_IN_ENDIAN_MASKS	(UCONV_IN_BIG_ENDIAN | UCONV_IN_LITTLE_ENDIAN)
+#define	UCONV_OUT_ENDIAN_MASKS	(UCONV_OUT_BIG_ENDIAN | UCONV_OUT_LITTLE_ENDIAN)
+
+/* Native and reversed endian macros. */
+#ifdef	_BIG_ENDIAN
+#define	UCONV_IN_NAT_ENDIAN	UCONV_IN_BIG_ENDIAN
+#define	UCONV_IN_REV_ENDIAN	UCONV_IN_LITTLE_ENDIAN
+#define	UCONV_OUT_NAT_ENDIAN	UCONV_OUT_BIG_ENDIAN
+#define	UCONV_OUT_REV_ENDIAN	UCONV_OUT_LITTLE_ENDIAN
+#else
+#define	UCONV_IN_NAT_ENDIAN	UCONV_IN_LITTLE_ENDIAN
+#define	UCONV_IN_REV_ENDIAN	UCONV_IN_BIG_ENDIAN
+#define	UCONV_OUT_NAT_ENDIAN	UCONV_OUT_LITTLE_ENDIAN
+#define	UCONV_OUT_REV_ENDIAN	UCONV_OUT_BIG_ENDIAN
+#endif	/* _BIG_ENDIAN */
+
+/* The Byte Order Mark (BOM) character in normal and reversed byte orderings. */
+#define	UCONV_BOM_NORMAL	(0xfeffU)
+#define	UCONV_BOM_SWAPPED	(0xfffeU)
+#define	UCONV_BOM_SWAPPED_32	(0xfffe0000U)
+
+/* UTF-32 boundaries based on UTF-8 character byte lengths. */
+#define	UCONV_U8_ONE_BYTE	(0x7fU)
+#define	UCONV_U8_TWO_BYTES	(0x7ffU)
+#define	UCONV_U8_THREE_BYTES	(0xffffU)
+#define	UCONV_U8_FOUR_BYTES	(0x10ffffU)
+
+/* The common minimum and maximum values at the UTF-8 character bytes. */
+#define	UCONV_U8_BYTE_MIN	(0x80U)
+#define	UCONV_U8_BYTE_MAX	(0xbfU)
+
+/*
+ * The following "6" and "0x3f" came from "10xx xxxx" bit representation of
+ * UTF-8 character bytes.
+ */
+#define	UCONV_U8_BIT_SHIFT	6
+#define	UCONV_U8_BIT_MASK	0x3f
+
+/*
+ * The following vector shows remaining bytes in a UTF-8 character.
+ * Index will be the first byte of the character.
+ */
+static const uchar_t remaining_bytes_tbl[0x100] = {
+	0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+	0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+	0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+	0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+	0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+	0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+	0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+	0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+	0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+	0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+	0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+	0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+
+/*	C0  C1  C2  C3  C4  C5  C6  C7  C8  C9  CA  CB  CC  CD  CE  CF */
+	0,  0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
+
+/*	D0  D1  D2  D3  D4  D5  D6  D7  D8  D9  DA  DB  DC  DD  DE  DF */
+	1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
+
+/*	E0  E1  E2  E3  E4  E5  E6  E7  E8  E9  EA  EB  EC  ED  EE  EF */
+	2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,
+
+/*	F0  F1  F2  F3  F4  F5  F6  F7  F8  F9  FA  FB  FC  FD  FE  FF */
+	3,  3,  3,  3,  3,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0
+};
+
+/*
+ * The following is a vector of bit-masks to get used bits in
+ * the first byte of a UTF-8 character.  Index is remaining bytes at above of
+ * the character.
+ */
+#ifdef	_KERNEL
+const uchar_t u8_masks_tbl[6] = { 0x00, 0x1f, 0x0f, 0x07, 0x03, 0x01 };
+#else
+static const uchar_t u8_masks_tbl[6] = { 0x00, 0x1f, 0x0f, 0x07, 0x03, 0x01 };
+#endif	/* _KERNEL */
+
+/*
+ * The following two vectors are to provide valid minimum and
+ * maximum values for the 2'nd byte of a multibyte UTF-8 character for
+ * better illegal sequence checking. The index value must be the value of
+ * the first byte of the UTF-8 character.
+ */
+static const uchar_t valid_min_2nd_byte[0x100] = {
+	0,    0,    0,    0,    0,    0,    0,    0,
+	0,    0,    0,    0,    0,    0,    0,    0,
+	0,    0,    0,    0,    0,    0,    0,    0,
+	0,    0,    0,    0,    0,    0,    0,    0,
+	0,    0,    0,    0,    0,    0,    0,    0,
+	0,    0,    0,    0,    0,    0,    0,    0,
+	0,    0,    0,    0,    0,    0,    0,    0,
+	0,    0,    0,    0,    0,    0,    0,    0,
+	0,    0,    0,    0,    0,    0,    0,    0,
+	0,    0,    0,    0,    0,    0,    0,    0,
+	0,    0,    0,    0,    0,    0,    0,    0,
+	0,    0,    0,    0,    0,    0,    0,    0,
+	0,    0,    0,    0,    0,    0,    0,    0,
+	0,    0,    0,    0,    0,    0,    0,    0,
+	0,    0,    0,    0,    0,    0,    0,    0,
+	0,    0,    0,    0,    0,    0,    0,    0,
+	0,    0,    0,    0,    0,    0,    0,    0,
+	0,    0,    0,    0,    0,    0,    0,    0,
+	0,    0,    0,    0,    0,    0,    0,    0,
+	0,    0,    0,    0,    0,    0,    0,    0,
+	0,    0,    0,    0,    0,    0,    0,    0,
+	0,    0,    0,    0,    0,    0,    0,    0,
+	0,    0,    0,    0,    0,    0,    0,    0,
+	0,    0,    0,    0,    0,    0,    0,    0,
+
+/*	C0    C1    C2    C3    C4    C5    C6    C7 */
+	0,    0,    0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+
+/*	C8    C9    CA    CB    CC    CD    CE    CF */
+	0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+
+/*	D0    D1    D2    D3    D4    D5    D6    D7 */
+	0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+
+/*	D8    D9    DA    DB    DC    DD    DE    DF */
+	0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+
+/*	E0    E1    E2    E3    E4    E5    E6    E7 */
+	0xa0, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+
+/*	E8    E9    EA    EB    EC    ED    EE    EF */
+	0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+
+/*	F0    F1    F2    F3    F4    F5    F6    F7 */
+	0x90, 0x80, 0x80, 0x80, 0x80, 0,    0,    0,
+
+	0,    0,    0,    0,    0,    0,    0,    0
+};
+
+static const uchar_t valid_max_2nd_byte[0x100] = {
+	0,    0,    0,    0,    0,    0,    0,    0,
+	0,    0,    0,    0,    0,    0,    0,    0,
+	0,    0,    0,    0,    0,    0,    0,    0,
+	0,    0,    0,    0,    0,    0,    0,    0,
+	0,    0,    0,    0,    0,    0,    0,    0,
+	0,    0,    0,    0,    0,    0,    0,    0,
+	0,    0,    0,    0,    0,    0,    0,    0,
+	0,    0,    0,    0,    0,    0,    0,    0,
+	0,    0,    0,    0,    0,    0,    0,    0,
+	0,    0,    0,    0,    0,    0,    0,    0,
+	0,    0,    0,    0,    0,    0,    0,    0,
+	0,    0,    0,    0,    0,    0,    0,    0,
+	0,    0,    0,    0,    0,    0,    0,    0,
+	0,    0,    0,    0,    0,    0,    0,    0,
+	0,    0,    0,    0,    0,    0,    0,    0,
+	0,    0,    0,    0,    0,    0,    0,    0,
+	0,    0,    0,    0,    0,    0,    0,    0,
+	0,    0,    0,    0,    0,    0,    0,    0,
+	0,    0,    0,    0,    0,    0,    0,    0,
+	0,    0,    0,    0,    0,    0,    0,    0,
+	0,    0,    0,    0,    0,    0,    0,    0,
+	0,    0,    0,    0,    0,    0,    0,    0,
+	0,    0,    0,    0,    0,    0,    0,    0,
+	0,    0,    0,    0,    0,    0,    0,    0,
+
+/*	C0    C1    C2    C3    C4    C5    C6    C7 */
+	0,    0,    0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf,
+
+/*	C8    C9    CA    CB    CC    CD    CE    CF */
+	0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf,
+
+/*	D0    D1    D2    D3    D4    D5    D6    D7 */
+	0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf,
+
+/*	D8    D9    DA    DB    DC    DD    DE    DF */
+	0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf,
+
+/*	E0    E1    E2    E3    E4    E5    E6    E7 */
+	0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf,
+
+/*	E8    E9    EA    EB    EC    ED    EE    EF */
+	0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0x9f, 0xbf, 0xbf,
+
+/*	F0    F1    F2    F3    F4    F5    F6    F7 */
+	0xbf, 0xbf, 0xbf, 0xbf, 0x8f, 0,    0,    0,
+
+	0,    0,    0,    0,    0,    0,    0,    0
+};
+
+
+static int
+check_endian(int flag, int *in, int *out)
+{
+	*in = flag & UCONV_IN_ENDIAN_MASKS;
+
+	/* You cannot have both. */
+	if (*in == UCONV_IN_ENDIAN_MASKS)
+		return (EBADF);
+
+	if (*in == 0)
+		*in = UCONV_IN_NAT_ENDIAN;
+
+	*out = flag & UCONV_OUT_ENDIAN_MASKS;
+
+	/* You cannot have both. */
+	if (*out == UCONV_OUT_ENDIAN_MASKS)
+		return (EBADF);
+
+	if (*out == 0)
+		*out = UCONV_OUT_NAT_ENDIAN;
+
+	return (0);
+}
+
+static boolean_t
+check_bom16(const uint16_t *u16s, size_t u16l, int *in)
+{
+	if (u16l > 0) {
+		if (*u16s == UCONV_BOM_NORMAL) {
+			*in = UCONV_IN_NAT_ENDIAN;
+			return (B_TRUE);
+		}
+		if (*u16s == UCONV_BOM_SWAPPED) {
+			*in = UCONV_IN_REV_ENDIAN;
+			return (B_TRUE);
+		}
+	}
+
+	return (B_FALSE);
+}
+
+static boolean_t
+check_bom32(const uint32_t *u32s, size_t u32l, int *in)
+{
+	if (u32l > 0) {
+		if (*u32s == UCONV_BOM_NORMAL) {
+			*in = UCONV_IN_NAT_ENDIAN;
+			return (B_TRUE);
+		}
+		if (*u32s == UCONV_BOM_SWAPPED_32) {
+			*in = UCONV_IN_REV_ENDIAN;
+			return (B_TRUE);
+		}
+	}
+
+	return (B_FALSE);
+}
+
+int
+uconv_u16tou32(const uint16_t *u16s, size_t *utf16len,
+    uint32_t *u32s, size_t *utf32len, int flag)
+{
+	int inendian;
+	int outendian;
+	size_t u16l;
+	size_t u32l;
+	uint32_t hi;
+	uint32_t lo;
+	boolean_t do_not_ignore_null;
+
+	/*
+	 * Do preliminary validity checks on parameters and collect info on
+	 * endians.
+	 */
+	if (u16s == NULL || utf16len == NULL)
+		return (EILSEQ);
+
+	if (u32s == NULL || utf32len == NULL)
+		return (E2BIG);
+
+	if (check_endian(flag, &inendian, &outendian) != 0)
+		return (EBADF);
+
+	/*
+	 * Initialize input and output parameter buffer indices and
+	 * temporary variables.
+	 */
+	u16l = u32l = 0;
+	hi = 0;
+	do_not_ignore_null = ((flag & UCONV_IGNORE_NULL) == 0);
+
+	/*
+	 * Check on the BOM at the beginning of the input buffer if required
+	 * and if there is indeed one, process it.
+	 */
+	if ((flag & UCONV_IN_ACCEPT_BOM) &&
+	    check_bom16(u16s, *utf16len, &inendian))
+		u16l++;
+
+	/*
+	 * Reset inendian and outendian so that after this point, those can be
+	 * used as condition values.
+	 */
+	inendian &= UCONV_IN_NAT_ENDIAN;
+	outendian &= UCONV_OUT_NAT_ENDIAN;
+
+	/*
+	 * If there is something in the input buffer and if necessary and
+	 * requested, save the BOM at the output buffer.
+	 */
+	if (*utf16len > 0 && *utf32len > 0 && (flag & UCONV_OUT_EMIT_BOM))
+		u32s[u32l++] = (outendian) ? UCONV_BOM_NORMAL :
+		    UCONV_BOM_SWAPPED_32;
+
+	/*
+	 * Do conversion; if encounter a surrogate pair, assemble high and
+	 * low pair values to form a UTF-32 character. If a half of a pair
+	 * exists alone, then, either it is an illegal (EILSEQ) or
+	 * invalid (EINVAL) value.
+	 */
+	for (; u16l < *utf16len; u16l++) {
+		if (u16s[u16l] == 0 && do_not_ignore_null)
+			break;
+
+		lo = (uint32_t)((inendian) ? u16s[u16l] : BSWAP_16(u16s[u16l]));
+
+		if (lo >= UCONV_U16_HI_MIN && lo <= UCONV_U16_HI_MAX) {
+			if (hi)
+				return (EILSEQ);
+			hi = lo;
+			continue;
+		} else if (lo >= UCONV_U16_LO_MIN && lo <= UCONV_U16_LO_MAX) {
+			if (! hi)
+				return (EILSEQ);
+			lo = (((hi - UCONV_U16_HI_MIN) * UCONV_U16_BIT_SHIFT +
+			    lo - UCONV_U16_LO_MIN) & UCONV_U16_BIT_MASK)
+			    + UCONV_U16_START;
+			hi = 0;
+		} else if (hi) {
+			return (EILSEQ);
+		}
+
+		if (u32l >= *utf32len)
+			return (E2BIG);
+
+		u32s[u32l++] = (outendian) ? lo : BSWAP_32(lo);
+	}
+
+	/*
+	 * If high half didn't see low half, then, it's most likely the input
+	 * parameter is incomplete.
+	 */
+	if (hi)
+		return (EINVAL);
+
+	/*
+	 * Save the number of consumed and saved characters. They do not
+	 * include terminating NULL character (U+0000) at the end of
+	 * the input buffer (even when UCONV_IGNORE_NULL isn't specified and
+	 * the input buffer length is big enough to include the terminating
+	 * NULL character).
+	 */
+	*utf16len = u16l;
+	*utf32len = u32l;
+
+	return (0);
+}
+
+int
+uconv_u16tou8(const uint16_t *u16s, size_t *utf16len,
+    uchar_t *u8s, size_t *utf8len, int flag)
+{
+	int inendian;
+	int outendian;
+	size_t u16l;
+	size_t u8l;
+	uint32_t hi;
+	uint32_t lo;
+	boolean_t do_not_ignore_null;
+
+	if (u16s == NULL || utf16len == NULL)
+		return (EILSEQ);
+
+	if (u8s == NULL || utf8len == NULL)
+		return (E2BIG);
+
+	if (check_endian(flag, &inendian, &outendian) != 0)
+		return (EBADF);
+
+	u16l = u8l = 0;
+	hi = 0;
+	do_not_ignore_null = ((flag & UCONV_IGNORE_NULL) == 0);
+
+	if ((flag & UCONV_IN_ACCEPT_BOM) &&
+	    check_bom16(u16s, *utf16len, &inendian))
+		u16l++;
+
+	inendian &= UCONV_IN_NAT_ENDIAN;
+
+	for (; u16l < *utf16len; u16l++) {
+		if (u16s[u16l] == 0 && do_not_ignore_null)
+			break;
+
+		lo = (uint32_t)((inendian) ? u16s[u16l] : BSWAP_16(u16s[u16l]));
+
+		if (lo >= UCONV_U16_HI_MIN && lo <= UCONV_U16_HI_MAX) {
+			if (hi)
+				return (EILSEQ);
+			hi = lo;
+			continue;
+		} else if (lo >= UCONV_U16_LO_MIN && lo <= UCONV_U16_LO_MAX) {
+			if (! hi)
+				return (EILSEQ);
+			lo = (((hi - UCONV_U16_HI_MIN) * UCONV_U16_BIT_SHIFT +
+			    lo - UCONV_U16_LO_MIN) & UCONV_U16_BIT_MASK)
+			    + UCONV_U16_START;
+			hi = 0;
+		} else if (hi) {
+			return (EILSEQ);
+		}
+
+		/*
+		 * Now we convert a UTF-32 character into a UTF-8 character.
+		 * Unicode coding space is between U+0000 and U+10FFFF;
+		 * anything bigger is an illegal character.
+		 */
+		if (lo <= UCONV_U8_ONE_BYTE) {
+			if (u8l >= *utf8len)
+				return (E2BIG);
+			u8s[u8l++] = (uchar_t)lo;
+		} else if (lo <= UCONV_U8_TWO_BYTES) {
+			if ((u8l + 1) >= *utf8len)
+				return (E2BIG);
+			u8s[u8l++] = (uchar_t)(0xc0 | ((lo & 0x07c0) >> 6));
+			u8s[u8l++] = (uchar_t)(0x80 |  (lo & 0x003f));
+		} else if (lo <= UCONV_U8_THREE_BYTES) {
+			if ((u8l + 2) >= *utf8len)
+				return (E2BIG);
+			u8s[u8l++] = (uchar_t)(0xe0 | ((lo & 0x0f000) >> 12));
+			u8s[u8l++] = (uchar_t)(0x80 | ((lo & 0x00fc0) >> 6));
+			u8s[u8l++] = (uchar_t)(0x80 |  (lo & 0x0003f));
+		} else if (lo <= UCONV_U8_FOUR_BYTES) {
+			if ((u8l + 3) >= *utf8len)
+				return (E2BIG);
+			u8s[u8l++] = (uchar_t)(0xf0 | ((lo & 0x01c0000) >> 18));
+			u8s[u8l++] = (uchar_t)(0x80 | ((lo & 0x003f000) >> 12));
+			u8s[u8l++] = (uchar_t)(0x80 | ((lo & 0x0000fc0) >> 6));
+			u8s[u8l++] = (uchar_t)(0x80 |  (lo & 0x000003f));
+		} else {
+			return (EILSEQ);
+		}
+	}
+
+	if (hi)
+		return (EINVAL);
+
+	*utf16len = u16l;
+	*utf8len = u8l;
+
+	return (0);
+}
+
+int
+uconv_u32tou16(const uint32_t *u32s, size_t *utf32len,
+    uint16_t *u16s, size_t *utf16len, int flag)
+{
+	int inendian;
+	int outendian;
+	size_t u16l;
+	size_t u32l;
+	uint32_t hi;
+	uint32_t lo;
+	boolean_t do_not_ignore_null;
+
+	if (u32s == NULL || utf32len == NULL)
+		return (EILSEQ);
+
+	if (u16s == NULL || utf16len == NULL)
+		return (E2BIG);
+
+	if (check_endian(flag, &inendian, &outendian) != 0)
+		return (EBADF);
+
+	u16l = u32l = 0;
+	do_not_ignore_null = ((flag & UCONV_IGNORE_NULL) == 0);
+
+	if ((flag & UCONV_IN_ACCEPT_BOM) &&
+	    check_bom32(u32s, *utf32len, &inendian))
+		u32l++;
+
+	inendian &= UCONV_IN_NAT_ENDIAN;
+	outendian &= UCONV_OUT_NAT_ENDIAN;
+
+	if (*utf32len > 0 && *utf16len > 0 && (flag & UCONV_OUT_EMIT_BOM))
+		u16s[u16l++] = (outendian) ? UCONV_BOM_NORMAL :
+		    UCONV_BOM_SWAPPED;
+
+	for (; u32l < *utf32len; u32l++) {
+		if (u32s[u32l] == 0 && do_not_ignore_null)
+			break;
+
+		hi = (inendian) ? u32s[u32l] : BSWAP_32(u32s[u32l]);
+
+		/*
+		 * Anything bigger than the Unicode coding space, i.e.,
+		 * Unicode scalar value bigger than U+10FFFF, is an illegal
+		 * character.
+		 */
+		if (hi > UCONV_UNICODE_MAX)
+			return (EILSEQ);
+
+		/*
+		 * Anything bigger than U+FFFF must be converted into
+		 * a surrogate pair in UTF-16.
+		 */
+		if (hi >= UCONV_U16_START) {
+			lo = ((hi - UCONV_U16_START) % UCONV_U16_BIT_SHIFT) +
+			    UCONV_U16_LO_MIN;
+			hi = ((hi - UCONV_U16_START) / UCONV_U16_BIT_SHIFT) +
+			    UCONV_U16_HI_MIN;
+
+			if ((u16l + 1) >= *utf16len)
+				return (E2BIG);
+
+			if (outendian) {
+				u16s[u16l++] = (uint16_t)hi;
+				u16s[u16l++] = (uint16_t)lo;
+			} else {
+				u16s[u16l++] = BSWAP_16(((uint16_t)hi));
+				u16s[u16l++] = BSWAP_16(((uint16_t)lo));
+			}
+		} else {
+			if (u16l >= *utf16len)
+				return (E2BIG);
+			u16s[u16l++] = (outendian) ? (uint16_t)hi :
+			    BSWAP_16(((uint16_t)hi));
+		}
+	}
+
+	*utf16len = u16l;
+	*utf32len = u32l;
+
+	return (0);
+}
+
+int
+uconv_u32tou8(const uint32_t *u32s, size_t *utf32len,
+    uchar_t *u8s, size_t *utf8len, int flag)
+{
+	int inendian;
+	int outendian;
+	size_t u32l;
+	size_t u8l;
+	uint32_t lo;
+	boolean_t do_not_ignore_null;
+
+	if (u32s == NULL || utf32len == NULL)
+		return (EILSEQ);
+
+	if (u8s == NULL || utf8len == NULL)
+		return (E2BIG);
+
+	if (check_endian(flag, &inendian, &outendian) != 0)
+		return (EBADF);
+
+	u32l = u8l = 0;
+	do_not_ignore_null = ((flag & UCONV_IGNORE_NULL) == 0);
+
+	if ((flag & UCONV_IN_ACCEPT_BOM) &&
+	    check_bom32(u32s, *utf32len, &inendian))
+		u32l++;
+
+	inendian &= UCONV_IN_NAT_ENDIAN;
+
+	for (; u32l < *utf32len; u32l++) {
+		if (u32s[u32l] == 0 && do_not_ignore_null)
+			break;
+
+		lo = (inendian) ? u32s[u32l] : BSWAP_32(u32s[u32l]);
+
+		if (lo <= UCONV_U8_ONE_BYTE) {
+			if (u8l >= *utf8len)
+				return (E2BIG);
+			u8s[u8l++] = (uchar_t)lo;
+		} else if (lo <= UCONV_U8_TWO_BYTES) {
+			if ((u8l + 1) >= *utf8len)
+				return (E2BIG);
+			u8s[u8l++] = (uchar_t)(0xc0 | ((lo & 0x07c0) >> 6));
+			u8s[u8l++] = (uchar_t)(0x80 |  (lo & 0x003f));
+		} else if (lo <= UCONV_U8_THREE_BYTES) {
+			if ((u8l + 2) >= *utf8len)
+				return (E2BIG);
+			u8s[u8l++] = (uchar_t)(0xe0 | ((lo & 0x0f000) >> 12));
+			u8s[u8l++] = (uchar_t)(0x80 | ((lo & 0x00fc0) >> 6));
+			u8s[u8l++] = (uchar_t)(0x80 |  (lo & 0x0003f));
+		} else if (lo <= UCONV_U8_FOUR_BYTES) {
+			if ((u8l + 3) >= *utf8len)
+				return (E2BIG);
+			u8s[u8l++] = (uchar_t)(0xf0 | ((lo & 0x01c0000) >> 18));
+			u8s[u8l++] = (uchar_t)(0x80 | ((lo & 0x003f000) >> 12));
+			u8s[u8l++] = (uchar_t)(0x80 | ((lo & 0x0000fc0) >> 6));
+			u8s[u8l++] = (uchar_t)(0x80 |  (lo & 0x000003f));
+		} else {
+			return (EILSEQ);
+		}
+	}
+
+	*utf32len = u32l;
+	*utf8len = u8l;
+
+	return (0);
+}
+
+int
+uconv_u8tou16(const uchar_t *u8s, size_t *utf8len,
+    uint16_t *u16s, size_t *utf16len, int flag)
+{
+	int inendian;
+	int outendian;
+	size_t u16l;
+	size_t u8l;
+	uint32_t hi;
+	uint32_t lo;
+	int remaining_bytes;
+	int first_b;
+	boolean_t do_not_ignore_null;
+
+	if (u8s == NULL || utf8len == NULL)
+		return (EILSEQ);
+
+	if (u16s == NULL || utf16len == NULL)
+		return (E2BIG);
+
+	if (check_endian(flag, &inendian, &outendian) != 0)
+		return (EBADF);
+
+	u16l = u8l = 0;
+	do_not_ignore_null = ((flag & UCONV_IGNORE_NULL) == 0);
+
+	outendian &= UCONV_OUT_NAT_ENDIAN;
+
+	if (*utf8len > 0 && *utf16len > 0 && (flag & UCONV_OUT_EMIT_BOM))
+		u16s[u16l++] = (outendian) ? UCONV_BOM_NORMAL :
+		    UCONV_BOM_SWAPPED;
+
+	for (; u8l < *utf8len; ) {
+		if (u8s[u8l] == 0 && do_not_ignore_null)
+			break;
+
+		/*
+		 * Collect a UTF-8 character and convert it to a UTF-32
+		 * character. In doing so, we screen out illegally formed
+		 * UTF-8 characters and treat such as illegal characters.
+		 * The algorithm at below also screens out anything bigger
+		 * than the U+10FFFF.
+		 *
+		 * See Unicode 3.1 UTF-8 Corrigendum and Unicode 3.2 for
+		 * more details on the illegal values of UTF-8 character
+		 * bytes.
+		 */
+		hi = (uint32_t)u8s[u8l++];
+
+		if (hi > UCONV_ASCII_MAX) {
+			if ((remaining_bytes = remaining_bytes_tbl[hi]) == 0)
+				return (EILSEQ);
+
+			first_b = hi;
+			hi = hi & u8_masks_tbl[remaining_bytes];
+
+			for (; remaining_bytes > 0; remaining_bytes--) {
+				/*
+				 * If we have no more bytes, the current
+				 * UTF-8 character is incomplete.
+				 */
+				if (u8l >= *utf8len)
+					return (EINVAL);
+
+				lo = (uint32_t)u8s[u8l++];
+
+				if (first_b) {
+					if (lo < valid_min_2nd_byte[first_b] ||
+					    lo > valid_max_2nd_byte[first_b])
+						return (EILSEQ);
+					first_b = 0;
+				} else if (lo < UCONV_U8_BYTE_MIN ||
+				    lo > UCONV_U8_BYTE_MAX) {
+					return (EILSEQ);
+				}
+				hi = (hi << UCONV_U8_BIT_SHIFT) |
+				    (lo & UCONV_U8_BIT_MASK);
+			}
+		}
+
+		if (hi >= UCONV_U16_START) {
+			lo = ((hi - UCONV_U16_START) % UCONV_U16_BIT_SHIFT) +
+			    UCONV_U16_LO_MIN;
+			hi = ((hi - UCONV_U16_START) / UCONV_U16_BIT_SHIFT) +
+			    UCONV_U16_HI_MIN;
+
+			if ((u16l + 1) >= *utf16len)
+				return (E2BIG);
+
+			if (outendian) {
+				u16s[u16l++] = (uint16_t)hi;
+				u16s[u16l++] = (uint16_t)lo;
+			} else {
+				u16s[u16l++] = BSWAP_16(((uint16_t)hi));
+				u16s[u16l++] = BSWAP_16(((uint16_t)lo));
+			}
+		} else {
+			if (u16l >= *utf16len)
+				return (E2BIG);
+
+			u16s[u16l++] = (outendian) ? (uint16_t)hi :
+			    BSWAP_16(((uint16_t)hi));
+		}
+	}
+
+	*utf16len = u16l;
+	*utf8len = u8l;
+
+	return (0);
+}
+
+int
+uconv_u8tou32(const uchar_t *u8s, size_t *utf8len,
+    uint32_t *u32s, size_t *utf32len, int flag)
+{
+	int inendian;
+	int outendian;
+	size_t u32l;
+	size_t u8l;
+	uint32_t hi;
+	uint32_t c;
+	int remaining_bytes;
+	int first_b;
+	boolean_t do_not_ignore_null;
+
+	if (u8s == NULL || utf8len == NULL)
+		return (EILSEQ);
+
+	if (u32s == NULL || utf32len == NULL)
+		return (E2BIG);
+
+	if (check_endian(flag, &inendian, &outendian) != 0)
+		return (EBADF);
+
+	u32l = u8l = 0;
+	do_not_ignore_null = ((flag & UCONV_IGNORE_NULL) == 0);
+
+	outendian &= UCONV_OUT_NAT_ENDIAN;
+
+	if (*utf8len > 0 && *utf32len > 0 && (flag & UCONV_OUT_EMIT_BOM))
+		u32s[u32l++] = (outendian) ? UCONV_BOM_NORMAL :
+		    UCONV_BOM_SWAPPED_32;
+
+	for (; u8l < *utf8len; ) {
+		if (u8s[u8l] == 0 && do_not_ignore_null)
+			break;
+
+		hi = (uint32_t)u8s[u8l++];
+
+		if (hi > UCONV_ASCII_MAX) {
+			if ((remaining_bytes = remaining_bytes_tbl[hi]) == 0)
+				return (EILSEQ);
+
+			first_b = hi;
+			hi = hi & u8_masks_tbl[remaining_bytes];
+
+			for (; remaining_bytes > 0; remaining_bytes--) {
+				if (u8l >= *utf8len)
+					return (EINVAL);
+
+				c = (uint32_t)u8s[u8l++];
+
+				if (first_b) {
+					if (c < valid_min_2nd_byte[first_b] ||
+					    c > valid_max_2nd_byte[first_b])
+						return (EILSEQ);
+					first_b = 0;
+				} else if (c < UCONV_U8_BYTE_MIN ||
+				    c > UCONV_U8_BYTE_MAX) {
+					return (EILSEQ);
+				}
+				hi = (hi << UCONV_U8_BIT_SHIFT) |
+				    (c & UCONV_U8_BIT_MASK);
+			}
+		}
+
+		if (u32l >= *utf32len)
+			return (E2BIG);
+
+		u32s[u32l++] = (outendian) ? hi : BSWAP_32(hi);
+	}
+
+	*utf32len = u32l;
+	*utf8len = u8l;
+
+	return (0);
+}
+
+#if defined(_KERNEL) && defined(HAVE_SPL)
+EXPORT_SYMBOL(uconv_u16tou32);
+EXPORT_SYMBOL(uconv_u16tou8);
+EXPORT_SYMBOL(uconv_u32tou16);
+EXPORT_SYMBOL(uconv_u32tou8);
+EXPORT_SYMBOL(uconv_u8tou16);
+EXPORT_SYMBOL(uconv_u8tou32);
+#endif
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/module/zcommon/Makefile.in
@@ -0,0 +1,17 @@
+src = @abs_top_srcdir@/module/zcommon
+obj = @abs_builddir@
+
+MODULE := zcommon
+
+EXTRA_CFLAGS = $(ZFS_MODULE_CFLAGS) @KERNELCPPFLAGS@
+
+obj-$(CONFIG_ZFS) := $(MODULE).o
+
+$(MODULE)-objs += zfs_deleg.o
+$(MODULE)-objs += zfs_prop.o
+$(MODULE)-objs += zprop_common.o
+$(MODULE)-objs += zfs_namecheck.o
+$(MODULE)-objs += zfs_comutil.o
+$(MODULE)-objs += zfs_fletcher.o
+$(MODULE)-objs += zfs_uio.o
+$(MODULE)-objs += zpool_prop.o
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/module/zcommon/zfs_comutil.c
@@ -0,0 +1,215 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012 by Delphix. All rights reserved.
+ */
+
+/*
+ * This file is intended for functions that ought to be common between user
+ * land (libzfs) and the kernel. When many common routines need to be shared
+ * then a separate file should to be created.
+ */
+
+#if defined(_KERNEL)
+#include <sys/systm.h>
+#else
+#include <string.h>
+#endif
+
+#include <sys/types.h>
+#include <sys/fs/zfs.h>
+#include <sys/int_limits.h>
+#include <sys/nvpair.h>
+#include "zfs_comutil.h"
+
+/*
+ * Are there allocatable vdevs?
+ */
+boolean_t
+zfs_allocatable_devs(nvlist_t *nv)
+{
+	uint64_t is_log;
+	uint_t c;
+	nvlist_t **child;
+	uint_t children;
+
+	if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
+	    &child, &children) != 0) {
+		return (B_FALSE);
+	}
+	for (c = 0; c < children; c++) {
+		is_log = 0;
+		(void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_LOG,
+		    &is_log);
+		if (!is_log)
+			return (B_TRUE);
+	}
+	return (B_FALSE);
+}
+
+void
+zpool_get_rewind_policy(nvlist_t *nvl, zpool_rewind_policy_t *zrpp)
+{
+	nvlist_t *policy;
+	nvpair_t *elem;
+	char *nm;
+
+	/* Defaults */
+	zrpp->zrp_request = ZPOOL_NO_REWIND;
+	zrpp->zrp_maxmeta = 0;
+	zrpp->zrp_maxdata = UINT64_MAX;
+	zrpp->zrp_txg = UINT64_MAX;
+
+	if (nvl == NULL)
+		return;
+
+	elem = NULL;
+	while ((elem = nvlist_next_nvpair(nvl, elem)) != NULL) {
+		nm = nvpair_name(elem);
+		if (strcmp(nm, ZPOOL_REWIND_POLICY) == 0) {
+			if (nvpair_value_nvlist(elem, &policy) == 0)
+				zpool_get_rewind_policy(policy, zrpp);
+			return;
+		} else if (strcmp(nm, ZPOOL_REWIND_REQUEST) == 0) {
+			if (nvpair_value_uint32(elem, &zrpp->zrp_request) == 0)
+				if (zrpp->zrp_request & ~ZPOOL_REWIND_POLICIES)
+					zrpp->zrp_request = ZPOOL_NO_REWIND;
+		} else if (strcmp(nm, ZPOOL_REWIND_REQUEST_TXG) == 0) {
+			(void) nvpair_value_uint64(elem, &zrpp->zrp_txg);
+		} else if (strcmp(nm, ZPOOL_REWIND_META_THRESH) == 0) {
+			(void) nvpair_value_uint64(elem, &zrpp->zrp_maxmeta);
+		} else if (strcmp(nm, ZPOOL_REWIND_DATA_THRESH) == 0) {
+			(void) nvpair_value_uint64(elem, &zrpp->zrp_maxdata);
+		}
+	}
+	if (zrpp->zrp_request == 0)
+		zrpp->zrp_request = ZPOOL_NO_REWIND;
+}
+
+typedef struct zfs_version_spa_map {
+	int	version_zpl;
+	int	version_spa;
+} zfs_version_spa_map_t;
+
+/*
+ * Keep this table in monotonically increasing version number order.
+ */
+static zfs_version_spa_map_t zfs_version_table[] = {
+	{ZPL_VERSION_INITIAL, SPA_VERSION_INITIAL},
+	{ZPL_VERSION_DIRENT_TYPE, SPA_VERSION_INITIAL},
+	{ZPL_VERSION_FUID, SPA_VERSION_FUID},
+	{ZPL_VERSION_USERSPACE, SPA_VERSION_USERSPACE},
+	{ZPL_VERSION_SA, SPA_VERSION_SA},
+	{0, 0}
+};
+
+/*
+ * Return the max zpl version for a corresponding spa version
+ * -1 is returned if no mapping exists.
+ */
+int
+zfs_zpl_version_map(int spa_version)
+{
+	int i;
+	int version = -1;
+
+	for (i = 0; zfs_version_table[i].version_spa; i++) {
+		if (spa_version >= zfs_version_table[i].version_spa)
+			version = zfs_version_table[i].version_zpl;
+	}
+
+	return (version);
+}
+
+/*
+ * Return the min spa version for a corresponding spa version
+ * -1 is returned if no mapping exists.
+ */
+int
+zfs_spa_version_map(int zpl_version)
+{
+	int i;
+	int version = -1;
+
+	for (i = 0; zfs_version_table[i].version_zpl; i++) {
+		if (zfs_version_table[i].version_zpl >= zpl_version)
+			return (zfs_version_table[i].version_spa);
+	}
+
+	return (version);
+}
+
+/*
+ * This is the table of legacy internal event names; it should not be modified.
+ * The internal events are now stored in the history log as strings.
+ */
+const char *zfs_history_event_names[ZFS_NUM_LEGACY_HISTORY_EVENTS] = {
+	"invalid event",
+	"pool create",
+	"vdev add",
+	"pool remove",
+	"pool destroy",
+	"pool export",
+	"pool import",
+	"vdev attach",
+	"vdev replace",
+	"vdev detach",
+	"vdev online",
+	"vdev offline",
+	"vdev upgrade",
+	"pool clear",
+	"pool scrub",
+	"pool property set",
+	"create",
+	"clone",
+	"destroy",
+	"destroy_begin_sync",
+	"inherit",
+	"property set",
+	"quota set",
+	"permission update",
+	"permission remove",
+	"permission who remove",
+	"promote",
+	"receive",
+	"rename",
+	"reservation set",
+	"replay_inc_sync",
+	"replay_full_sync",
+	"rollback",
+	"snapshot",
+	"filesystem version upgrade",
+	"refquota set",
+	"refreservation set",
+	"pool scrub done",
+	"user hold",
+	"user release",
+	"pool split",
+};
+
+#if defined(_KERNEL) && defined(HAVE_SPL)
+EXPORT_SYMBOL(zfs_allocatable_devs);
+EXPORT_SYMBOL(zpool_get_rewind_policy);
+EXPORT_SYMBOL(zfs_zpl_version_map);
+EXPORT_SYMBOL(zfs_spa_version_map);
+EXPORT_SYMBOL(zfs_history_event_names);
+#endif
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/module/zcommon/zfs_deleg.c
@@ -0,0 +1,238 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2010 Nexenta Systems, Inc. All rights reserved.
+ * Copyright (c) 2013 by Delphix. All rights reserved.
+ */
+
+#include <sys/zfs_context.h>
+
+#if defined(_KERNEL)
+#include <sys/systm.h>
+#include <sys/sunddi.h>
+#include <sys/ctype.h>
+#else
+#include <stdio.h>
+#include <unistd.h>
+#include <strings.h>
+#include <libnvpair.h>
+#include <ctype.h>
+#endif
+#include <sys/dsl_deleg.h>
+#include "zfs_prop.h"
+#include "zfs_deleg.h"
+#include "zfs_namecheck.h"
+
+zfs_deleg_perm_tab_t zfs_deleg_perm_tab[] = {
+	{ZFS_DELEG_PERM_ALLOW},
+	{ZFS_DELEG_PERM_BOOKMARK},
+	{ZFS_DELEG_PERM_CLONE},
+	{ZFS_DELEG_PERM_CREATE},
+	{ZFS_DELEG_PERM_DESTROY},
+	{ZFS_DELEG_PERM_DIFF},
+	{ZFS_DELEG_PERM_MOUNT},
+	{ZFS_DELEG_PERM_PROMOTE},
+	{ZFS_DELEG_PERM_RECEIVE},
+	{ZFS_DELEG_PERM_RENAME},
+	{ZFS_DELEG_PERM_ROLLBACK},
+	{ZFS_DELEG_PERM_SNAPSHOT},
+	{ZFS_DELEG_PERM_SHARE},
+	{ZFS_DELEG_PERM_SEND},
+	{ZFS_DELEG_PERM_USERPROP},
+	{ZFS_DELEG_PERM_USERQUOTA},
+	{ZFS_DELEG_PERM_GROUPQUOTA},
+	{ZFS_DELEG_PERM_USERUSED},
+	{ZFS_DELEG_PERM_GROUPUSED},
+	{ZFS_DELEG_PERM_HOLD},
+	{ZFS_DELEG_PERM_RELEASE},
+	{NULL}
+};
+
+static int
+zfs_valid_permission_name(const char *perm)
+{
+	if (zfs_deleg_canonicalize_perm(perm))
+		return (0);
+
+	return (permset_namecheck(perm, NULL, NULL));
+}
+
+const char *
+zfs_deleg_canonicalize_perm(const char *perm)
+{
+	int i;
+	zfs_prop_t prop;
+
+	for (i = 0; zfs_deleg_perm_tab[i].z_perm != NULL; i++) {
+		if (strcmp(perm, zfs_deleg_perm_tab[i].z_perm) == 0)
+			return (perm);
+	}
+
+	prop = zfs_name_to_prop(perm);
+	if (prop != ZPROP_INVAL && zfs_prop_delegatable(prop))
+		return (zfs_prop_to_name(prop));
+	return (NULL);
+
+}
+
+static int
+zfs_validate_who(char *who)
+{
+	char *p;
+
+	if (who[2] != ZFS_DELEG_FIELD_SEP_CHR)
+		return (-1);
+
+	switch (who[0]) {
+	case ZFS_DELEG_USER:
+	case ZFS_DELEG_GROUP:
+	case ZFS_DELEG_USER_SETS:
+	case ZFS_DELEG_GROUP_SETS:
+		if (who[1] != ZFS_DELEG_LOCAL && who[1] != ZFS_DELEG_DESCENDENT)
+			return (-1);
+		for (p = &who[3]; *p; p++)
+			if (!isdigit(*p))
+				return (-1);
+		break;
+
+	case ZFS_DELEG_NAMED_SET:
+	case ZFS_DELEG_NAMED_SET_SETS:
+		if (who[1] != ZFS_DELEG_NA)
+			return (-1);
+		return (permset_namecheck(&who[3], NULL, NULL));
+
+	case ZFS_DELEG_CREATE:
+	case ZFS_DELEG_CREATE_SETS:
+		if (who[1] != ZFS_DELEG_NA)
+			return (-1);
+		if (who[3] != '\0')
+			return (-1);
+		break;
+
+	case ZFS_DELEG_EVERYONE:
+	case ZFS_DELEG_EVERYONE_SETS:
+		if (who[1] != ZFS_DELEG_LOCAL && who[1] != ZFS_DELEG_DESCENDENT)
+			return (-1);
+		if (who[3] != '\0')
+			return (-1);
+		break;
+
+	default:
+		return (-1);
+	}
+
+	return (0);
+}
+
+int
+zfs_deleg_verify_nvlist(nvlist_t *nvp)
+{
+	nvpair_t *who, *perm_name;
+	nvlist_t *perms;
+	int error;
+
+	if (nvp == NULL)
+		return (-1);
+
+	who = nvlist_next_nvpair(nvp, NULL);
+	if (who == NULL)
+		return (-1);
+
+	do {
+		if (zfs_validate_who(nvpair_name(who)))
+			return (-1);
+
+		error = nvlist_lookup_nvlist(nvp, nvpair_name(who), &perms);
+
+		if (error && error != ENOENT)
+			return (-1);
+		if (error == ENOENT)
+			continue;
+
+		perm_name = nvlist_next_nvpair(perms, NULL);
+		if (perm_name == NULL) {
+			return (-1);
+		}
+		do {
+			error = zfs_valid_permission_name(
+			    nvpair_name(perm_name));
+			if (error)
+				return (-1);
+		} while ((perm_name = nvlist_next_nvpair(perms, perm_name)));
+	} while ((who = nvlist_next_nvpair(nvp, who)));
+	return (0);
+}
+
+/*
+ * Construct the base attribute name.  The base attribute names
+ * are the "key" to locate the jump objects which contain the actual
+ * permissions.  The base attribute names are encoded based on
+ * type of entry and whether it is a local or descendent permission.
+ *
+ * Arguments:
+ * attr - attribute name return string, attribute is assumed to be
+ *        ZFS_MAX_DELEG_NAME long.
+ * type - type of entry to construct
+ * inheritchr - inheritance type (local,descendent, or NA for create and
+ *                               permission set definitions
+ * data - is either a permission set name or a 64 bit uid/gid.
+ */
+void
+zfs_deleg_whokey(char *attr, zfs_deleg_who_type_t type,
+    char inheritchr, void *data)
+{
+	int len = ZFS_MAX_DELEG_NAME;
+	uint64_t *id = data;
+
+	switch (type) {
+	case ZFS_DELEG_USER:
+	case ZFS_DELEG_GROUP:
+	case ZFS_DELEG_USER_SETS:
+	case ZFS_DELEG_GROUP_SETS:
+		(void) snprintf(attr, len, "%c%c%c%lld", type, inheritchr,
+		    ZFS_DELEG_FIELD_SEP_CHR, (longlong_t)*id);
+		break;
+	case ZFS_DELEG_NAMED_SET_SETS:
+	case ZFS_DELEG_NAMED_SET:
+		(void) snprintf(attr, len, "%c-%c%s", type,
+		    ZFS_DELEG_FIELD_SEP_CHR, (char *)data);
+		break;
+	case ZFS_DELEG_CREATE:
+	case ZFS_DELEG_CREATE_SETS:
+		(void) snprintf(attr, len, "%c-%c", type,
+		    ZFS_DELEG_FIELD_SEP_CHR);
+		break;
+	case ZFS_DELEG_EVERYONE:
+	case ZFS_DELEG_EVERYONE_SETS:
+		(void) snprintf(attr, len, "%c%c%c", type, inheritchr,
+		    ZFS_DELEG_FIELD_SEP_CHR);
+		break;
+	default:
+		cmn_err(CE_PANIC, "bad zfs_deleg_who_type_t %d", type);
+	}
+}
+
+#if defined(_KERNEL) && defined(HAVE_SPL)
+EXPORT_SYMBOL(zfs_deleg_verify_nvlist);
+EXPORT_SYMBOL(zfs_deleg_whokey);
+EXPORT_SYMBOL(zfs_deleg_canonicalize_perm);
+#endif
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/module/zcommon/zfs_fletcher.c
@@ -0,0 +1,255 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/*
+ * Fletcher Checksums
+ * ------------------
+ *
+ * ZFS's 2nd and 4th order Fletcher checksums are defined by the following
+ * recurrence relations:
+ *
+ *	a  = a    + f
+ *	 i    i-1    i-1
+ *
+ *	b  = b    + a
+ *	 i    i-1    i
+ *
+ *	c  = c    + b		(fletcher-4 only)
+ *	 i    i-1    i
+ *
+ *	d  = d    + c		(fletcher-4 only)
+ *	 i    i-1    i
+ *
+ * Where
+ *	a_0 = b_0 = c_0 = d_0 = 0
+ * and
+ *	f_0 .. f_(n-1) are the input data.
+ *
+ * Using standard techniques, these translate into the following series:
+ *
+ *	     __n_			     __n_
+ *	     \   |			     \   |
+ *	a  =  >     f			b  =  >     i * f
+ *	 n   /___|   n - i		 n   /___|	 n - i
+ *	     i = 1			     i = 1
+ *
+ *
+ *	     __n_			     __n_
+ *	     \   |  i*(i+1)		     \   |  i*(i+1)*(i+2)
+ *	c  =  >     ------- f		d  =  >     ------------- f
+ *	 n   /___|     2     n - i	 n   /___|	  6	   n - i
+ *	     i = 1			     i = 1
+ *
+ * For fletcher-2, the f_is are 64-bit, and [ab]_i are 64-bit accumulators.
+ * Since the additions are done mod (2^64), errors in the high bits may not
+ * be noticed.  For this reason, fletcher-2 is deprecated.
+ *
+ * For fletcher-4, the f_is are 32-bit, and [abcd]_i are 64-bit accumulators.
+ * A conservative estimate of how big the buffer can get before we overflow
+ * can be estimated using f_i = 0xffffffff for all i:
+ *
+ * % bc
+ *  f=2^32-1;d=0; for (i = 1; d<2^64; i++) { d += f*i*(i+1)*(i+2)/6 }; (i-1)*4
+ * 2264
+ *  quit
+ * %
+ *
+ * So blocks of up to 2k will not overflow.  Our largest block size is
+ * 128k, which has 32k 4-byte words, so we can compute the largest possible
+ * accumulators, then divide by 2^64 to figure the max amount of overflow:
+ *
+ * % bc
+ *  a=b=c=d=0; f=2^32-1; for (i=1; i<=32*1024; i++) { a+=f; b+=a; c+=b; d+=c }
+ *  a/2^64;b/2^64;c/2^64;d/2^64
+ * 0
+ * 0
+ * 1365
+ * 11186858
+ *  quit
+ * %
+ *
+ * So a and b cannot overflow.  To make sure each bit of input has some
+ * effect on the contents of c and d, we can look at what the factors of
+ * the coefficients in the equations for c_n and d_n are.  The number of 2s
+ * in the factors determines the lowest set bit in the multiplier.  Running
+ * through the cases for n*(n+1)/2 reveals that the highest power of 2 is
+ * 2^14, and for n*(n+1)*(n+2)/6 it is 2^15.  So while some data may overflow
+ * the 64-bit accumulators, every bit of every f_i effects every accumulator,
+ * even for 128k blocks.
+ *
+ * If we wanted to make a stronger version of fletcher4 (fletcher4c?),
+ * we could do our calculations mod (2^32 - 1) by adding in the carries
+ * periodically, and store the number of carries in the top 32-bits.
+ *
+ * --------------------
+ * Checksum Performance
+ * --------------------
+ *
+ * There are two interesting components to checksum performance: cached and
+ * uncached performance.  With cached data, fletcher-2 is about four times
+ * faster than fletcher-4.  With uncached data, the performance difference is
+ * negligible, since the cost of a cache fill dominates the processing time.
+ * Even though fletcher-4 is slower than fletcher-2, it is still a pretty
+ * efficient pass over the data.
+ *
+ * In normal operation, the data which is being checksummed is in a buffer
+ * which has been filled either by:
+ *
+ *	1. a compression step, which will be mostly cached, or
+ *	2. a bcopy() or copyin(), which will be uncached (because the
+ *	   copy is cache-bypassing).
+ *
+ * For both cached and uncached data, both fletcher checksums are much faster
+ * than sha-256, and slower than 'off', which doesn't touch the data at all.
+ */
+
+#include <sys/types.h>
+#include <sys/sysmacros.h>
+#include <sys/byteorder.h>
+#include <sys/zio.h>
+#include <sys/spa.h>
+
+void
+fletcher_2_native(const void *buf, uint64_t size, zio_cksum_t *zcp)
+{
+	const uint64_t *ip = buf;
+	const uint64_t *ipend = ip + (size / sizeof (uint64_t));
+	uint64_t a0, b0, a1, b1;
+
+	for (a0 = b0 = a1 = b1 = 0; ip < ipend; ip += 2) {
+		a0 += ip[0];
+		a1 += ip[1];
+		b0 += a0;
+		b1 += a1;
+	}
+
+	ZIO_SET_CHECKSUM(zcp, a0, a1, b0, b1);
+}
+
+void
+fletcher_2_byteswap(const void *buf, uint64_t size, zio_cksum_t *zcp)
+{
+	const uint64_t *ip = buf;
+	const uint64_t *ipend = ip + (size / sizeof (uint64_t));
+	uint64_t a0, b0, a1, b1;
+
+	for (a0 = b0 = a1 = b1 = 0; ip < ipend; ip += 2) {
+		a0 += BSWAP_64(ip[0]);
+		a1 += BSWAP_64(ip[1]);
+		b0 += a0;
+		b1 += a1;
+	}
+
+	ZIO_SET_CHECKSUM(zcp, a0, a1, b0, b1);
+}
+
+void
+fletcher_4_native(const void *buf, uint64_t size, zio_cksum_t *zcp)
+{
+	const uint32_t *ip = buf;
+	const uint32_t *ipend = ip + (size / sizeof (uint32_t));
+	uint64_t a, b, c, d;
+
+	for (a = b = c = d = 0; ip < ipend; ip++) {
+		a += ip[0];
+		b += a;
+		c += b;
+		d += c;
+	}
+
+	ZIO_SET_CHECKSUM(zcp, a, b, c, d);
+}
+
+void
+fletcher_4_byteswap(const void *buf, uint64_t size, zio_cksum_t *zcp)
+{
+	const uint32_t *ip = buf;
+	const uint32_t *ipend = ip + (size / sizeof (uint32_t));
+	uint64_t a, b, c, d;
+
+	for (a = b = c = d = 0; ip < ipend; ip++) {
+		a += BSWAP_32(ip[0]);
+		b += a;
+		c += b;
+		d += c;
+	}
+
+	ZIO_SET_CHECKSUM(zcp, a, b, c, d);
+}
+
+void
+fletcher_4_incremental_native(const void *buf, uint64_t size,
+    zio_cksum_t *zcp)
+{
+	const uint32_t *ip = buf;
+	const uint32_t *ipend = ip + (size / sizeof (uint32_t));
+	uint64_t a, b, c, d;
+
+	a = zcp->zc_word[0];
+	b = zcp->zc_word[1];
+	c = zcp->zc_word[2];
+	d = zcp->zc_word[3];
+
+	for (; ip < ipend; ip++) {
+		a += ip[0];
+		b += a;
+		c += b;
+		d += c;
+	}
+
+	ZIO_SET_CHECKSUM(zcp, a, b, c, d);
+}
+
+void
+fletcher_4_incremental_byteswap(const void *buf, uint64_t size,
+    zio_cksum_t *zcp)
+{
+	const uint32_t *ip = buf;
+	const uint32_t *ipend = ip + (size / sizeof (uint32_t));
+	uint64_t a, b, c, d;
+
+	a = zcp->zc_word[0];
+	b = zcp->zc_word[1];
+	c = zcp->zc_word[2];
+	d = zcp->zc_word[3];
+
+	for (; ip < ipend; ip++) {
+		a += BSWAP_32(ip[0]);
+		b += a;
+		c += b;
+		d += c;
+	}
+
+	ZIO_SET_CHECKSUM(zcp, a, b, c, d);
+}
+
+#if defined(_KERNEL) && defined(HAVE_SPL)
+EXPORT_SYMBOL(fletcher_2_native);
+EXPORT_SYMBOL(fletcher_2_byteswap);
+EXPORT_SYMBOL(fletcher_4_native);
+EXPORT_SYMBOL(fletcher_4_byteswap);
+EXPORT_SYMBOL(fletcher_4_incremental_native);
+EXPORT_SYMBOL(fletcher_4_incremental_byteswap);
+#endif
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/module/zcommon/zfs_namecheck.c
@@ -0,0 +1,381 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * Copyright (c) 2013 by Delphix. All rights reserved.
+ */
+
+/*
+ * Common name validation routines for ZFS.  These routines are shared by the
+ * userland code as well as the ioctl() layer to ensure that we don't
+ * inadvertently expose a hole through direct ioctl()s that never gets tested.
+ * In userland, however, we want significantly more information about _why_ the
+ * name is invalid.  In the kernel, we only care whether it's valid or not.
+ * Each routine therefore takes a 'namecheck_err_t' which describes exactly why
+ * the name failed to validate.
+ *
+ * Each function returns 0 on success, -1 on error.
+ */
+
+#if defined(_KERNEL)
+#include <sys/systm.h>
+#else
+#include <string.h>
+#endif
+
+#include <sys/param.h>
+#include <sys/nvpair.h>
+#include "zfs_namecheck.h"
+#include "zfs_deleg.h"
+
+static int
+valid_char(char c)
+{
+	return ((c >= 'a' && c <= 'z') ||
+	    (c >= 'A' && c <= 'Z') ||
+	    (c >= '0' && c <= '9') ||
+	    c == '-' || c == '_' || c == '.' || c == ':' || c == ' ');
+}
+
+/*
+ * Snapshot names must be made up of alphanumeric characters plus the following
+ * characters:
+ *
+ * 	[-_.: ]
+ */
+int
+zfs_component_namecheck(const char *path, namecheck_err_t *why, char *what)
+{
+	const char *loc;
+
+	if (strlen(path) >= MAXNAMELEN) {
+		if (why)
+			*why = NAME_ERR_TOOLONG;
+		return (-1);
+	}
+
+	if (path[0] == '\0') {
+		if (why)
+			*why = NAME_ERR_EMPTY_COMPONENT;
+		return (-1);
+	}
+
+	for (loc = path; *loc; loc++) {
+		if (!valid_char(*loc)) {
+			if (why) {
+				*why = NAME_ERR_INVALCHAR;
+				*what = *loc;
+			}
+			return (-1);
+		}
+	}
+	return (0);
+}
+
+
+/*
+ * Permissions set name must start with the letter '@' followed by the
+ * same character restrictions as snapshot names, except that the name
+ * cannot exceed 64 characters.
+ */
+int
+permset_namecheck(const char *path, namecheck_err_t *why, char *what)
+{
+	if (strlen(path) >= ZFS_PERMSET_MAXLEN) {
+		if (why)
+			*why = NAME_ERR_TOOLONG;
+		return (-1);
+	}
+
+	if (path[0] != '@') {
+		if (why) {
+			*why = NAME_ERR_NO_AT;
+			*what = path[0];
+		}
+		return (-1);
+	}
+
+	return (zfs_component_namecheck(&path[1], why, what));
+}
+
+/*
+ * Dataset names must be of the following form:
+ *
+ * 	[component][/]*[component][@component]
+ *
+ * Where each component is made up of alphanumeric characters plus the following
+ * characters:
+ *
+ * 	[-_.:%]
+ *
+ * We allow '%' here as we use that character internally to create unique
+ * names for temporary clones (for online recv).
+ */
+int
+dataset_namecheck(const char *path, namecheck_err_t *why, char *what)
+{
+	const char *loc, *end;
+	int found_snapshot;
+
+	/*
+	 * Make sure the name is not too long.
+	 *
+	 * ZFS_MAXNAMELEN is the maximum dataset length used in the userland
+	 * which is the same as MAXNAMELEN used in the kernel.
+	 * If ZFS_MAXNAMELEN value is changed, make sure to cleanup all
+	 * places using MAXNAMELEN.
+	 *
+	 * When HAVE_KOBJ_NAME_LEN is defined the maximum safe kobject name
+	 * length is 20 bytes.  This 20 bytes is broken down as follows to
+	 * provide a maximum safe <pool>/<dataset>[@snapshot] length of only
+	 * 18 bytes.  To ensure bytes are left for <dataset>[@snapshot] the
+	 * <pool> portition is futher limited to 9 bytes.  For 2.6.27 and
+	 * newer kernels this limit is set to MAXNAMELEN.
+	 *
+	 *   <pool>/<dataset> + <partition> + <newline>
+	 *   (18)             + (1)         + (1)
+	 */
+#ifdef HAVE_KOBJ_NAME_LEN
+	if (strlen(path) > 18) {
+#else
+	if (strlen(path) >= MAXNAMELEN) {
+#endif /* HAVE_KOBJ_NAME_LEN */
+		if (why)
+			*why = NAME_ERR_TOOLONG;
+		return (-1);
+	}
+
+	/* Explicitly check for a leading slash.  */
+	if (path[0] == '/') {
+		if (why)
+			*why = NAME_ERR_LEADING_SLASH;
+		return (-1);
+	}
+
+	if (path[0] == '\0') {
+		if (why)
+			*why = NAME_ERR_EMPTY_COMPONENT;
+		return (-1);
+	}
+
+	loc = path;
+	found_snapshot = 0;
+	for (;;) {
+		/* Find the end of this component */
+		end = loc;
+		while (*end != '/' && *end != '@' && *end != '\0')
+			end++;
+
+		if (*end == '\0' && end[-1] == '/') {
+			/* trailing slashes are not allowed */
+			if (why)
+				*why = NAME_ERR_TRAILING_SLASH;
+			return (-1);
+		}
+
+		/* Zero-length components are not allowed */
+		if (loc == end) {
+			if (why) {
+				/*
+				 * Make sure this is really a zero-length
+				 * component and not a '@@'.
+				 */
+				if (*end == '@' && found_snapshot) {
+					*why = NAME_ERR_MULTIPLE_AT;
+				} else {
+					*why = NAME_ERR_EMPTY_COMPONENT;
+				}
+			}
+
+			return (-1);
+		}
+
+		/* Validate the contents of this component */
+		while (loc != end) {
+			if (!valid_char(*loc) && *loc != '%') {
+				if (why) {
+					*why = NAME_ERR_INVALCHAR;
+					*what = *loc;
+				}
+				return (-1);
+			}
+			loc++;
+		}
+
+		/* If we've reached the end of the string, we're OK */
+		if (*end == '\0')
+			return (0);
+
+		if (*end == '@') {
+			/*
+			 * If we've found an @ symbol, indicate that we're in
+			 * the snapshot component, and report a second '@'
+			 * character as an error.
+			 */
+			if (found_snapshot) {
+				if (why)
+					*why = NAME_ERR_MULTIPLE_AT;
+				return (-1);
+			}
+
+			found_snapshot = 1;
+		}
+
+		/*
+		 * If there is a '/' in a snapshot name
+		 * then report an error
+		 */
+		if (*end == '/' && found_snapshot) {
+			if (why)
+				*why = NAME_ERR_TRAILING_SLASH;
+			return (-1);
+		}
+
+		/* Update to the next component */
+		loc = end + 1;
+	}
+}
+
+
+/*
+ * mountpoint names must be of the following form:
+ *
+ *	/[component][/]*[component][/]
+ */
+int
+mountpoint_namecheck(const char *path, namecheck_err_t *why)
+{
+	const char *start, *end;
+
+	/*
+	 * Make sure none of the mountpoint component names are too long.
+	 * If a component name is too long then the mkdir of the mountpoint
+	 * will fail but then the mountpoint property will be set to a value
+	 * that can never be mounted.  Better to fail before setting the prop.
+	 * Extra slashes are OK, they will be tossed by the mountpoint mkdir.
+	 */
+
+	if (path == NULL || *path != '/') {
+		if (why)
+			*why = NAME_ERR_LEADING_SLASH;
+		return (-1);
+	}
+
+	/* Skip leading slash  */
+	start = &path[1];
+	do {
+		end = start;
+		while (*end != '/' && *end != '\0')
+			end++;
+
+		if (end - start >= MAXNAMELEN) {
+			if (why)
+				*why = NAME_ERR_TOOLONG;
+			return (-1);
+		}
+		start = end + 1;
+
+	} while (*end != '\0');
+
+	return (0);
+}
+
+/*
+ * For pool names, we have the same set of valid characters as described in
+ * dataset names, with the additional restriction that the pool name must begin
+ * with a letter.  The pool names 'raidz' and 'mirror' are also reserved names
+ * that cannot be used.
+ */
+int
+pool_namecheck(const char *pool, namecheck_err_t *why, char *what)
+{
+	const char *c;
+
+	/*
+	 * Make sure the name is not too long.
+	 *
+	 * ZPOOL_MAXNAMELEN is the maximum pool length used in the userland
+	 * which is the same as MAXNAMELEN used in the kernel.
+	 * If ZPOOL_MAXNAMELEN value is changed, make sure to cleanup all
+	 * places using MAXNAMELEN.
+	 *
+	 * When HAVE_KOBJ_NAME_LEN is defined the maximum safe kobject name
+	 * length is 20 bytes.  This 20 bytes is broken down as follows to
+	 * provide a maximum safe <pool>/<dataset>[@snapshot] length of only
+	 * 18 bytes.  To ensure bytes are left for <dataset>[@snapshot] the
+	 * <pool> portition is futher limited to 8 bytes.  For 2.6.27 and
+	 * newer kernels this limit is set to MAXNAMELEN.
+	 *
+	 *   <pool>/<dataset> + <partition> + <newline>
+	 *   (18)             + (1)         + (1)
+	 */
+#ifdef HAVE_KOBJ_NAME_LEN
+	if (strlen(pool) > 8) {
+#else
+	if (strlen(pool) >= MAXNAMELEN) {
+#endif /* HAVE_KOBJ_NAME_LEN */
+		if (why)
+			*why = NAME_ERR_TOOLONG;
+		return (-1);
+	}
+
+	c = pool;
+	while (*c != '\0') {
+		if (!valid_char(*c)) {
+			if (why) {
+				*why = NAME_ERR_INVALCHAR;
+				*what = *c;
+			}
+			return (-1);
+		}
+		c++;
+	}
+
+	if (!(*pool >= 'a' && *pool <= 'z') &&
+	    !(*pool >= 'A' && *pool <= 'Z')) {
+		if (why)
+			*why = NAME_ERR_NOLETTER;
+		return (-1);
+	}
+
+	if (strcmp(pool, "mirror") == 0 || strcmp(pool, "raidz") == 0) {
+		if (why)
+			*why = NAME_ERR_RESERVED;
+		return (-1);
+	}
+
+	if (pool[0] == 'c' && (pool[1] >= '0' && pool[1] <= '9')) {
+		if (why)
+			*why = NAME_ERR_DISKLIKE;
+		return (-1);
+	}
+
+	return (0);
+}
+
+#if defined(_KERNEL) && defined(HAVE_SPL)
+EXPORT_SYMBOL(pool_namecheck);
+EXPORT_SYMBOL(dataset_namecheck);
+EXPORT_SYMBOL(zfs_component_namecheck);
+#endif
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/module/zcommon/zfs_prop.c
@@ -0,0 +1,733 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2014 by Delphix. All rights reserved.
+ * Copyright (c) 2013 by Saso Kiselkov. All rights reserved.
+ */
+
+/* Portions Copyright 2010 Robert Milkowski */
+
+#include <sys/zio.h>
+#include <sys/spa.h>
+#include <sys/u8_textprep.h>
+#include <sys/zfs_acl.h>
+#include <sys/zfs_ioctl.h>
+#include <sys/zfs_znode.h>
+
+#include "zfs_prop.h"
+#include "zfs_deleg.h"
+
+#if defined(_KERNEL)
+#include <sys/systm.h>
+#else
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#endif
+
+static zprop_desc_t zfs_prop_table[ZFS_NUM_PROPS];
+
+/* Note this is indexed by zfs_userquota_prop_t, keep the order the same */
+const char *zfs_userquota_prop_prefixes[] = {
+	"userused@",
+	"userquota@",
+	"groupused@",
+	"groupquota@"
+};
+
+zprop_desc_t *
+zfs_prop_get_table(void)
+{
+	return (zfs_prop_table);
+}
+
+void
+zfs_prop_init(void)
+{
+	static zprop_index_t checksum_table[] = {
+		{ "on",		ZIO_CHECKSUM_ON },
+		{ "off",	ZIO_CHECKSUM_OFF },
+		{ "fletcher2",	ZIO_CHECKSUM_FLETCHER_2 },
+		{ "fletcher4",	ZIO_CHECKSUM_FLETCHER_4 },
+		{ "sha256",	ZIO_CHECKSUM_SHA256 },
+		{ NULL }
+	};
+
+	static zprop_index_t dedup_table[] = {
+		{ "on",		ZIO_CHECKSUM_ON },
+		{ "off",	ZIO_CHECKSUM_OFF },
+		{ "verify",	ZIO_CHECKSUM_ON | ZIO_CHECKSUM_VERIFY },
+		{ "sha256",	ZIO_CHECKSUM_SHA256 },
+		{ "sha256,verify",
+				ZIO_CHECKSUM_SHA256 | ZIO_CHECKSUM_VERIFY },
+		{ NULL }
+	};
+
+	static zprop_index_t compress_table[] = {
+		{ "on",		ZIO_COMPRESS_ON },
+		{ "off",	ZIO_COMPRESS_OFF },
+		{ "lzjb",	ZIO_COMPRESS_LZJB },
+		{ "gzip",	ZIO_COMPRESS_GZIP_6 },	/* gzip default */
+		{ "gzip-1",	ZIO_COMPRESS_GZIP_1 },
+		{ "gzip-2",	ZIO_COMPRESS_GZIP_2 },
+		{ "gzip-3",	ZIO_COMPRESS_GZIP_3 },
+		{ "gzip-4",	ZIO_COMPRESS_GZIP_4 },
+		{ "gzip-5",	ZIO_COMPRESS_GZIP_5 },
+		{ "gzip-6",	ZIO_COMPRESS_GZIP_6 },
+		{ "gzip-7",	ZIO_COMPRESS_GZIP_7 },
+		{ "gzip-8",	ZIO_COMPRESS_GZIP_8 },
+		{ "gzip-9",	ZIO_COMPRESS_GZIP_9 },
+		{ "zle",	ZIO_COMPRESS_ZLE },
+		{ "lz4",	ZIO_COMPRESS_LZ4 },
+		{ NULL }
+	};
+
+	static zprop_index_t snapdir_table[] = {
+		{ "hidden",	ZFS_SNAPDIR_HIDDEN },
+		{ "visible",	ZFS_SNAPDIR_VISIBLE },
+		{ NULL }
+	};
+
+	static zprop_index_t snapdev_table[] = {
+		{ "hidden",	ZFS_SNAPDEV_HIDDEN },
+		{ "visible",	ZFS_SNAPDEV_VISIBLE },
+		{ NULL }
+	};
+
+	static zprop_index_t acltype_table[] = {
+		{ "off",	ZFS_ACLTYPE_OFF },
+		{ "disabled",	ZFS_ACLTYPE_OFF },
+		{ "noacl",	ZFS_ACLTYPE_OFF },
+		{ "posixacl",	ZFS_ACLTYPE_POSIXACL },
+		{ NULL }
+	};
+
+	static zprop_index_t acl_inherit_table[] = {
+		{ "discard",	ZFS_ACL_DISCARD },
+		{ "noallow",	ZFS_ACL_NOALLOW },
+		{ "restricted",	ZFS_ACL_RESTRICTED },
+		{ "passthrough", ZFS_ACL_PASSTHROUGH },
+		{ "secure",	ZFS_ACL_RESTRICTED }, /* bkwrd compatability */
+		{ "passthrough-x", ZFS_ACL_PASSTHROUGH_X },
+		{ NULL }
+	};
+
+	static zprop_index_t case_table[] = {
+		{ "sensitive",		ZFS_CASE_SENSITIVE },
+		{ "insensitive",	ZFS_CASE_INSENSITIVE },
+		{ "mixed",		ZFS_CASE_MIXED },
+		{ NULL }
+	};
+
+	static zprop_index_t copies_table[] = {
+		{ "1",		1 },
+		{ "2",		2 },
+		{ "3",		3 },
+		{ NULL }
+	};
+
+	/*
+	 * Use the unique flags we have to send to u8_strcmp() and/or
+	 * u8_textprep() to represent the various normalization property
+	 * values.
+	 */
+	static zprop_index_t normalize_table[] = {
+		{ "none",	0 },
+		{ "formD",	U8_TEXTPREP_NFD },
+		{ "formKC",	U8_TEXTPREP_NFKC },
+		{ "formC",	U8_TEXTPREP_NFC },
+		{ "formKD",	U8_TEXTPREP_NFKD },
+		{ NULL }
+	};
+
+	static zprop_index_t version_table[] = {
+		{ "1",		1 },
+		{ "2",		2 },
+		{ "3",		3 },
+		{ "4",		4 },
+		{ "5",		5 },
+		{ "current",	ZPL_VERSION },
+		{ NULL }
+	};
+
+	static zprop_index_t boolean_table[] = {
+		{ "off",	0 },
+		{ "on",		1 },
+		{ NULL }
+	};
+
+	static zprop_index_t logbias_table[] = {
+		{ "latency",	ZFS_LOGBIAS_LATENCY },
+		{ "throughput",	ZFS_LOGBIAS_THROUGHPUT },
+		{ NULL }
+	};
+
+	static zprop_index_t canmount_table[] = {
+		{ "off",	ZFS_CANMOUNT_OFF },
+		{ "on",		ZFS_CANMOUNT_ON },
+		{ "noauto",	ZFS_CANMOUNT_NOAUTO },
+		{ NULL }
+	};
+
+	static zprop_index_t cache_table[] = {
+		{ "none",	ZFS_CACHE_NONE },
+		{ "metadata",	ZFS_CACHE_METADATA },
+		{ "all",	ZFS_CACHE_ALL },
+		{ NULL }
+	};
+
+	static zprop_index_t sync_table[] = {
+		{ "standard",	ZFS_SYNC_STANDARD },
+		{ "always",	ZFS_SYNC_ALWAYS },
+		{ "disabled",	ZFS_SYNC_DISABLED },
+		{ NULL }
+	};
+
+	static zprop_index_t xattr_table[] = {
+		{ "off",	ZFS_XATTR_OFF },
+		{ "on",		ZFS_XATTR_DIR },
+		{ "sa",		ZFS_XATTR_SA },
+		{ "dir",	ZFS_XATTR_DIR },
+		{ NULL }
+	};
+
+	static zprop_index_t redundant_metadata_table[] = {
+		{ "all",	ZFS_REDUNDANT_METADATA_ALL },
+		{ "most",	ZFS_REDUNDANT_METADATA_MOST },
+		{ NULL }
+	};
+
+	/* inherit index properties */
+	zprop_register_index(ZFS_PROP_REDUNDANT_METADATA, "redundant_metadata",
+	    ZFS_REDUNDANT_METADATA_ALL,
+	    PROP_INHERIT, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME,
+	    "all | most", "REDUND_MD",
+	    redundant_metadata_table);
+	zprop_register_index(ZFS_PROP_SYNC, "sync", ZFS_SYNC_STANDARD,
+	    PROP_INHERIT, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME,
+	    "standard | always | disabled", "SYNC",
+	    sync_table);
+	zprop_register_index(ZFS_PROP_CHECKSUM, "checksum",
+	    ZIO_CHECKSUM_DEFAULT, PROP_INHERIT, ZFS_TYPE_FILESYSTEM |
+	    ZFS_TYPE_VOLUME,
+	    "on | off | fletcher2 | fletcher4 | sha256", "CHECKSUM",
+	    checksum_table);
+	zprop_register_index(ZFS_PROP_DEDUP, "dedup", ZIO_CHECKSUM_OFF,
+	    PROP_INHERIT, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME,
+	    "on | off | verify | sha256[,verify]", "DEDUP",
+	    dedup_table);
+	zprop_register_index(ZFS_PROP_COMPRESSION, "compression",
+	    ZIO_COMPRESS_DEFAULT, PROP_INHERIT,
+	    ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME,
+	    "on | off | lzjb | gzip | gzip-[1-9] | zle | lz4", "COMPRESS",
+	    compress_table);
+	zprop_register_index(ZFS_PROP_SNAPDIR, "snapdir", ZFS_SNAPDIR_HIDDEN,
+	    PROP_INHERIT, ZFS_TYPE_FILESYSTEM,
+	    "hidden | visible", "SNAPDIR", snapdir_table);
+	zprop_register_index(ZFS_PROP_SNAPDEV, "snapdev", ZFS_SNAPDEV_HIDDEN,
+	    PROP_INHERIT, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME,
+	    "hidden | visible", "SNAPDEV", snapdev_table);
+	zprop_register_index(ZFS_PROP_ACLTYPE, "acltype", ZFS_ACLTYPE_OFF,
+	    PROP_INHERIT, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_SNAPSHOT,
+	    "noacl | posixacl", "ACLTYPE", acltype_table);
+	zprop_register_index(ZFS_PROP_ACLINHERIT, "aclinherit",
+	    ZFS_ACL_RESTRICTED, PROP_INHERIT, ZFS_TYPE_FILESYSTEM,
+	    "discard | noallow | restricted | passthrough | passthrough-x",
+	    "ACLINHERIT", acl_inherit_table);
+	zprop_register_index(ZFS_PROP_COPIES, "copies", 1, PROP_INHERIT,
+	    ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME,
+	    "1 | 2 | 3", "COPIES", copies_table);
+	zprop_register_index(ZFS_PROP_PRIMARYCACHE, "primarycache",
+	    ZFS_CACHE_ALL, PROP_INHERIT,
+	    ZFS_TYPE_FILESYSTEM | ZFS_TYPE_SNAPSHOT | ZFS_TYPE_VOLUME,
+	    "all | none | metadata", "PRIMARYCACHE", cache_table);
+	zprop_register_index(ZFS_PROP_SECONDARYCACHE, "secondarycache",
+	    ZFS_CACHE_ALL, PROP_INHERIT,
+	    ZFS_TYPE_FILESYSTEM | ZFS_TYPE_SNAPSHOT | ZFS_TYPE_VOLUME,
+	    "all | none | metadata", "SECONDARYCACHE", cache_table);
+	zprop_register_index(ZFS_PROP_LOGBIAS, "logbias", ZFS_LOGBIAS_LATENCY,
+	    PROP_INHERIT, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME,
+	    "latency | throughput", "LOGBIAS", logbias_table);
+	zprop_register_index(ZFS_PROP_XATTR, "xattr", ZFS_XATTR_DIR,
+	    PROP_INHERIT, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_SNAPSHOT,
+	    "on | off | dir | sa", "XATTR", xattr_table);
+
+	/* inherit index (boolean) properties */
+	zprop_register_index(ZFS_PROP_ATIME, "atime", 1, PROP_INHERIT,
+	    ZFS_TYPE_FILESYSTEM, "on | off", "ATIME", boolean_table);
+	zprop_register_index(ZFS_PROP_RELATIME, "relatime", 0, PROP_INHERIT,
+	    ZFS_TYPE_FILESYSTEM, "on | off", "RELATIME", boolean_table);
+	zprop_register_index(ZFS_PROP_DEVICES, "devices", 1, PROP_INHERIT,
+	    ZFS_TYPE_FILESYSTEM | ZFS_TYPE_SNAPSHOT, "on | off", "DEVICES",
+	    boolean_table);
+	zprop_register_index(ZFS_PROP_EXEC, "exec", 1, PROP_INHERIT,
+	    ZFS_TYPE_FILESYSTEM | ZFS_TYPE_SNAPSHOT, "on | off", "EXEC",
+	    boolean_table);
+	zprop_register_index(ZFS_PROP_SETUID, "setuid", 1, PROP_INHERIT,
+	    ZFS_TYPE_FILESYSTEM | ZFS_TYPE_SNAPSHOT, "on | off", "SETUID",
+	    boolean_table);
+	zprop_register_index(ZFS_PROP_READONLY, "readonly", 0, PROP_INHERIT,
+	    ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME, "on | off", "RDONLY",
+	    boolean_table);
+	zprop_register_index(ZFS_PROP_ZONED, "zoned", 0, PROP_INHERIT,
+	    ZFS_TYPE_FILESYSTEM, "on | off", "ZONED", boolean_table);
+	zprop_register_index(ZFS_PROP_VSCAN, "vscan", 0, PROP_INHERIT,
+	    ZFS_TYPE_FILESYSTEM, "on | off", "VSCAN", boolean_table);
+	zprop_register_index(ZFS_PROP_NBMAND, "nbmand", 0, PROP_INHERIT,
+	    ZFS_TYPE_FILESYSTEM | ZFS_TYPE_SNAPSHOT, "on | off", "NBMAND",
+	    boolean_table);
+	zprop_register_index(ZFS_PROP_OVERLAY, "overlay", 0, PROP_INHERIT,
+	    ZFS_TYPE_FILESYSTEM, "on | off", "OVERLAY", boolean_table);
+
+	/* default index properties */
+	zprop_register_index(ZFS_PROP_VERSION, "version", 0, PROP_DEFAULT,
+	    ZFS_TYPE_FILESYSTEM | ZFS_TYPE_SNAPSHOT,
+	    "1 | 2 | 3 | 4 | 5 | current", "VERSION", version_table);
+	zprop_register_index(ZFS_PROP_CANMOUNT, "canmount", ZFS_CANMOUNT_ON,
+	    PROP_DEFAULT, ZFS_TYPE_FILESYSTEM, "on | off | noauto",
+	    "CANMOUNT", canmount_table);
+
+	/* readonly index (boolean) properties */
+	zprop_register_index(ZFS_PROP_MOUNTED, "mounted", 0, PROP_READONLY,
+	    ZFS_TYPE_FILESYSTEM, "yes | no", "MOUNTED", boolean_table);
+	zprop_register_index(ZFS_PROP_DEFER_DESTROY, "defer_destroy", 0,
+	    PROP_READONLY, ZFS_TYPE_SNAPSHOT, "yes | no", "DEFER_DESTROY",
+	    boolean_table);
+
+	/* set once index properties */
+	zprop_register_index(ZFS_PROP_NORMALIZE, "normalization", 0,
+	    PROP_ONETIME, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_SNAPSHOT,
+	    "none | formC | formD | formKC | formKD", "NORMALIZATION",
+	    normalize_table);
+	zprop_register_index(ZFS_PROP_CASE, "casesensitivity",
+	    ZFS_CASE_SENSITIVE, PROP_ONETIME, ZFS_TYPE_FILESYSTEM |
+	    ZFS_TYPE_SNAPSHOT,
+	    "sensitive | insensitive | mixed", "CASE", case_table);
+
+	/* set once index (boolean) properties */
+	zprop_register_index(ZFS_PROP_UTF8ONLY, "utf8only", 0, PROP_ONETIME,
+	    ZFS_TYPE_FILESYSTEM | ZFS_TYPE_SNAPSHOT,
+	    "on | off", "UTF8ONLY", boolean_table);
+
+	/* string properties */
+	zprop_register_string(ZFS_PROP_ORIGIN, "origin", NULL, PROP_READONLY,
+	    ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME, "<snapshot>", "ORIGIN");
+	zprop_register_string(ZFS_PROP_CLONES, "clones", NULL, PROP_READONLY,
+	    ZFS_TYPE_SNAPSHOT, "<dataset>[,...]", "CLONES");
+	zprop_register_string(ZFS_PROP_MOUNTPOINT, "mountpoint", "/",
+	    PROP_INHERIT, ZFS_TYPE_FILESYSTEM, "<path> | legacy | none",
+	    "MOUNTPOINT");
+	zprop_register_string(ZFS_PROP_SHARENFS, "sharenfs", "off",
+	    PROP_INHERIT, ZFS_TYPE_FILESYSTEM, "on | off | share(1M) options",
+	    "SHARENFS");
+	zprop_register_string(ZFS_PROP_TYPE, "type", NULL, PROP_READONLY,
+	    ZFS_TYPE_DATASET | ZFS_TYPE_BOOKMARK,
+	    "filesystem | volume | snapshot | bookmark", "TYPE");
+	zprop_register_string(ZFS_PROP_SHARESMB, "sharesmb", "off",
+	    PROP_INHERIT, ZFS_TYPE_FILESYSTEM,
+	    "on | off | sharemgr(1M) options", "SHARESMB");
+	zprop_register_string(ZFS_PROP_MLSLABEL, "mlslabel",
+	    ZFS_MLSLABEL_DEFAULT, PROP_INHERIT, ZFS_TYPE_DATASET,
+	    "<sensitivity label>", "MLSLABEL");
+	zprop_register_string(ZFS_PROP_SELINUX_CONTEXT, "context",
+	    "none", PROP_DEFAULT, ZFS_TYPE_DATASET, "<selinux context>",
+	    "CONTEXT");
+	zprop_register_string(ZFS_PROP_SELINUX_FSCONTEXT, "fscontext",
+	    "none", PROP_DEFAULT, ZFS_TYPE_DATASET, "<selinux fscontext>",
+	    "FSCONTEXT");
+	zprop_register_string(ZFS_PROP_SELINUX_DEFCONTEXT, "defcontext",
+	    "none", PROP_DEFAULT, ZFS_TYPE_DATASET, "<selinux defcontext>",
+	    "DEFCONTEXT");
+	zprop_register_string(ZFS_PROP_SELINUX_ROOTCONTEXT, "rootcontext",
+	    "none", PROP_DEFAULT, ZFS_TYPE_DATASET, "<selinux rootcontext>",
+	    "ROOTCONTEXT");
+
+	/* readonly number properties */
+	zprop_register_number(ZFS_PROP_USED, "used", 0, PROP_READONLY,
+	    ZFS_TYPE_DATASET, "<size>", "USED");
+	zprop_register_number(ZFS_PROP_AVAILABLE, "available", 0, PROP_READONLY,
+	    ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME, "<size>", "AVAIL");
+	zprop_register_number(ZFS_PROP_REFERENCED, "referenced", 0,
+	    PROP_READONLY, ZFS_TYPE_DATASET, "<size>", "REFER");
+	zprop_register_number(ZFS_PROP_COMPRESSRATIO, "compressratio", 0,
+	    PROP_READONLY, ZFS_TYPE_DATASET,
+	    "<1.00x or higher if compressed>", "RATIO");
+	zprop_register_number(ZFS_PROP_REFRATIO, "refcompressratio", 0,
+	    PROP_READONLY, ZFS_TYPE_DATASET,
+	    "<1.00x or higher if compressed>", "REFRATIO");
+	zprop_register_number(ZFS_PROP_VOLBLOCKSIZE, "volblocksize",
+	    ZVOL_DEFAULT_BLOCKSIZE, PROP_ONETIME,
+	    ZFS_TYPE_VOLUME, "512 to 128k, power of 2",	"VOLBLOCK");
+	zprop_register_number(ZFS_PROP_USEDSNAP, "usedbysnapshots", 0,
+	    PROP_READONLY, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME, "<size>",
+	    "USEDSNAP");
+	zprop_register_number(ZFS_PROP_USEDDS, "usedbydataset", 0,
+	    PROP_READONLY, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME, "<size>",
+	    "USEDDS");
+	zprop_register_number(ZFS_PROP_USEDCHILD, "usedbychildren", 0,
+	    PROP_READONLY, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME, "<size>",
+	    "USEDCHILD");
+	zprop_register_number(ZFS_PROP_USEDREFRESERV, "usedbyrefreservation", 0,
+	    PROP_READONLY,
+	    ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME, "<size>", "USEDREFRESERV");
+	zprop_register_number(ZFS_PROP_USERREFS, "userrefs", 0, PROP_READONLY,
+	    ZFS_TYPE_SNAPSHOT, "<count>", "USERREFS");
+	zprop_register_number(ZFS_PROP_WRITTEN, "written", 0, PROP_READONLY,
+	    ZFS_TYPE_DATASET, "<size>", "WRITTEN");
+	zprop_register_number(ZFS_PROP_LOGICALUSED, "logicalused", 0,
+	    PROP_READONLY, ZFS_TYPE_DATASET, "<size>", "LUSED");
+	zprop_register_number(ZFS_PROP_LOGICALREFERENCED, "logicalreferenced",
+	    0, PROP_READONLY, ZFS_TYPE_DATASET, "<size>", "LREFER");
+
+	/* default number properties */
+	zprop_register_number(ZFS_PROP_QUOTA, "quota", 0, PROP_DEFAULT,
+	    ZFS_TYPE_FILESYSTEM, "<size> | none", "QUOTA");
+	zprop_register_number(ZFS_PROP_RESERVATION, "reservation", 0,
+	    PROP_DEFAULT, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME,
+	    "<size> | none", "RESERV");
+	zprop_register_number(ZFS_PROP_VOLSIZE, "volsize", 0, PROP_DEFAULT,
+	    ZFS_TYPE_SNAPSHOT | ZFS_TYPE_VOLUME, "<size>", "VOLSIZE");
+	zprop_register_number(ZFS_PROP_REFQUOTA, "refquota", 0, PROP_DEFAULT,
+	    ZFS_TYPE_FILESYSTEM, "<size> | none", "REFQUOTA");
+	zprop_register_number(ZFS_PROP_REFRESERVATION, "refreservation", 0,
+	    PROP_DEFAULT, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME,
+	    "<size> | none", "REFRESERV");
+	zprop_register_number(ZFS_PROP_FILESYSTEM_LIMIT, "filesystem_limit",
+	    UINT64_MAX, PROP_DEFAULT, ZFS_TYPE_FILESYSTEM,
+	    "<count> | none", "FSLIMIT");
+	zprop_register_number(ZFS_PROP_SNAPSHOT_LIMIT, "snapshot_limit",
+	    UINT64_MAX, PROP_DEFAULT, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME,
+	    "<count> | none", "SSLIMIT");
+	zprop_register_number(ZFS_PROP_FILESYSTEM_COUNT, "filesystem_count",
+	    UINT64_MAX, PROP_DEFAULT, ZFS_TYPE_FILESYSTEM,
+	    "<count>", "FSCOUNT");
+	zprop_register_number(ZFS_PROP_SNAPSHOT_COUNT, "snapshot_count",
+	    UINT64_MAX, PROP_DEFAULT, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME,
+	    "<count>", "SSCOUNT");
+
+	/* inherit number properties */
+	zprop_register_number(ZFS_PROP_RECORDSIZE, "recordsize",
+	    SPA_OLD_MAXBLOCKSIZE, PROP_INHERIT,
+	    ZFS_TYPE_FILESYSTEM, "512 to 1M, power of 2", "RECSIZE");
+
+	/* hidden properties */
+	zprop_register_hidden(ZFS_PROP_CREATETXG, "createtxg", PROP_TYPE_NUMBER,
+	    PROP_READONLY, ZFS_TYPE_DATASET | ZFS_TYPE_BOOKMARK, "CREATETXG");
+	zprop_register_hidden(ZFS_PROP_NUMCLONES, "numclones", PROP_TYPE_NUMBER,
+	    PROP_READONLY, ZFS_TYPE_SNAPSHOT, "NUMCLONES");
+	zprop_register_hidden(ZFS_PROP_NAME, "name", PROP_TYPE_STRING,
+	    PROP_READONLY, ZFS_TYPE_DATASET | ZFS_TYPE_BOOKMARK, "NAME");
+	zprop_register_hidden(ZFS_PROP_ISCSIOPTIONS, "iscsioptions",
+	    PROP_TYPE_STRING, PROP_INHERIT, ZFS_TYPE_VOLUME, "ISCSIOPTIONS");
+	zprop_register_hidden(ZFS_PROP_STMF_SHAREINFO, "stmf_sbd_lu",
+	    PROP_TYPE_STRING, PROP_INHERIT, ZFS_TYPE_VOLUME,
+	    "STMF_SBD_LU");
+	zprop_register_hidden(ZFS_PROP_GUID, "guid", PROP_TYPE_NUMBER,
+	    PROP_READONLY, ZFS_TYPE_DATASET | ZFS_TYPE_BOOKMARK, "GUID");
+	zprop_register_hidden(ZFS_PROP_USERACCOUNTING, "useraccounting",
+	    PROP_TYPE_NUMBER, PROP_READONLY, ZFS_TYPE_DATASET,
+	    "USERACCOUNTING");
+	zprop_register_hidden(ZFS_PROP_UNIQUE, "unique", PROP_TYPE_NUMBER,
+	    PROP_READONLY, ZFS_TYPE_DATASET, "UNIQUE");
+	zprop_register_hidden(ZFS_PROP_OBJSETID, "objsetid", PROP_TYPE_NUMBER,
+	    PROP_READONLY, ZFS_TYPE_DATASET, "OBJSETID");
+	zprop_register_hidden(ZFS_PROP_INCONSISTENT, "inconsistent",
+	    PROP_TYPE_NUMBER, PROP_READONLY, ZFS_TYPE_DATASET, "INCONSISTENT");
+
+	/*
+	 * Property to be removed once libbe is integrated
+	 */
+	zprop_register_hidden(ZFS_PROP_PRIVATE, "priv_prop",
+	    PROP_TYPE_NUMBER, PROP_READONLY, ZFS_TYPE_FILESYSTEM,
+	    "PRIV_PROP");
+
+	/* oddball properties */
+	zprop_register_impl(ZFS_PROP_CREATION, "creation", PROP_TYPE_NUMBER, 0,
+	    NULL, PROP_READONLY, ZFS_TYPE_DATASET | ZFS_TYPE_BOOKMARK,
+	    "<date>", "CREATION", B_FALSE, B_TRUE, NULL);
+}
+
+boolean_t
+zfs_prop_delegatable(zfs_prop_t prop)
+{
+	zprop_desc_t *pd = &zfs_prop_table[prop];
+
+	/* The mlslabel property is never delegatable. */
+	if (prop == ZFS_PROP_MLSLABEL)
+		return (B_FALSE);
+
+	return (pd->pd_attr != PROP_READONLY);
+}
+
+/*
+ * Given a zfs dataset property name, returns the corresponding property ID.
+ */
+zfs_prop_t
+zfs_name_to_prop(const char *propname)
+{
+	return (zprop_name_to_prop(propname, ZFS_TYPE_DATASET));
+}
+
+/*
+ * For user property names, we allow all lowercase alphanumeric characters, plus
+ * a few useful punctuation characters.
+ */
+static int
+valid_char(char c)
+{
+	return ((c >= 'a' && c <= 'z') ||
+	    (c >= '0' && c <= '9') ||
+	    c == '-' || c == '_' || c == '.' || c == ':');
+}
+
+/*
+ * Returns true if this is a valid user-defined property (one with a ':').
+ */
+boolean_t
+zfs_prop_user(const char *name)
+{
+	int i;
+	char c;
+	boolean_t foundsep = B_FALSE;
+
+	for (i = 0; i < strlen(name); i++) {
+		c = name[i];
+		if (!valid_char(c))
+			return (B_FALSE);
+		if (c == ':')
+			foundsep = B_TRUE;
+	}
+
+	if (!foundsep)
+		return (B_FALSE);
+
+	return (B_TRUE);
+}
+
+/*
+ * Returns true if this is a valid userspace-type property (one with a '@').
+ * Note that after the @, any character is valid (eg, another @, for SID
+ * user@domain).
+ */
+boolean_t
+zfs_prop_userquota(const char *name)
+{
+	zfs_userquota_prop_t prop;
+
+	for (prop = 0; prop < ZFS_NUM_USERQUOTA_PROPS; prop++) {
+		if (strncmp(name, zfs_userquota_prop_prefixes[prop],
+		    strlen(zfs_userquota_prop_prefixes[prop])) == 0) {
+			return (B_TRUE);
+		}
+	}
+
+	return (B_FALSE);
+}
+
+/*
+ * Returns true if this is a valid written@ property.
+ * Note that after the @, any character is valid (eg, another @, for
+ * written@pool/fs@origin).
+ */
+boolean_t
+zfs_prop_written(const char *name)
+{
+	static const char *prefix = "written@";
+	return (strncmp(name, prefix, strlen(prefix)) == 0);
+}
+
+/*
+ * Tables of index types, plus functions to convert between the user view
+ * (strings) and internal representation (uint64_t).
+ */
+int
+zfs_prop_string_to_index(zfs_prop_t prop, const char *string, uint64_t *index)
+{
+	return (zprop_string_to_index(prop, string, index, ZFS_TYPE_DATASET));
+}
+
+int
+zfs_prop_index_to_string(zfs_prop_t prop, uint64_t index, const char **string)
+{
+	return (zprop_index_to_string(prop, index, string, ZFS_TYPE_DATASET));
+}
+
+uint64_t
+zfs_prop_random_value(zfs_prop_t prop, uint64_t seed)
+{
+	return (zprop_random_value(prop, seed, ZFS_TYPE_DATASET));
+}
+
+/*
+ * Returns TRUE if the property applies to any of the given dataset types.
+ */
+boolean_t
+zfs_prop_valid_for_type(int prop, zfs_type_t types, boolean_t headcheck)
+{
+	return (zprop_valid_for_type(prop, types, headcheck));
+}
+
+zprop_type_t
+zfs_prop_get_type(zfs_prop_t prop)
+{
+	return (zfs_prop_table[prop].pd_proptype);
+}
+
+/*
+ * Returns TRUE if the property is readonly.
+ */
+boolean_t
+zfs_prop_readonly(zfs_prop_t prop)
+{
+	return (zfs_prop_table[prop].pd_attr == PROP_READONLY ||
+	    zfs_prop_table[prop].pd_attr == PROP_ONETIME);
+}
+
+/*
+ * Returns TRUE if the property is only allowed to be set once.
+ */
+boolean_t
+zfs_prop_setonce(zfs_prop_t prop)
+{
+	return (zfs_prop_table[prop].pd_attr == PROP_ONETIME);
+}
+
+const char *
+zfs_prop_default_string(zfs_prop_t prop)
+{
+	return (zfs_prop_table[prop].pd_strdefault);
+}
+
+uint64_t
+zfs_prop_default_numeric(zfs_prop_t prop)
+{
+	return (zfs_prop_table[prop].pd_numdefault);
+}
+
+/*
+ * Given a dataset property ID, returns the corresponding name.
+ * Assuming the zfs dataset property ID is valid.
+ */
+const char *
+zfs_prop_to_name(zfs_prop_t prop)
+{
+	return (zfs_prop_table[prop].pd_name);
+}
+
+/*
+ * Returns TRUE if the property is inheritable.
+ */
+boolean_t
+zfs_prop_inheritable(zfs_prop_t prop)
+{
+	return (zfs_prop_table[prop].pd_attr == PROP_INHERIT ||
+	    zfs_prop_table[prop].pd_attr == PROP_ONETIME);
+}
+
+#ifndef _KERNEL
+
+/*
+ * Returns a string describing the set of acceptable values for the given
+ * zfs property, or NULL if it cannot be set.
+ */
+const char *
+zfs_prop_values(zfs_prop_t prop)
+{
+	return (zfs_prop_table[prop].pd_values);
+}
+
+/*
+ * Returns TRUE if this property is a string type.  Note that index types
+ * (compression, checksum) are treated as strings in userland, even though they
+ * are stored numerically on disk.
+ */
+int
+zfs_prop_is_string(zfs_prop_t prop)
+{
+	return (zfs_prop_table[prop].pd_proptype == PROP_TYPE_STRING ||
+	    zfs_prop_table[prop].pd_proptype == PROP_TYPE_INDEX);
+}
+
+/*
+ * Returns the column header for the given property.  Used only in
+ * 'zfs list -o', but centralized here with the other property information.
+ */
+const char *
+zfs_prop_column_name(zfs_prop_t prop)
+{
+	return (zfs_prop_table[prop].pd_colname);
+}
+
+/*
+ * Returns whether the given property should be displayed right-justified for
+ * 'zfs list'.
+ */
+boolean_t
+zfs_prop_align_right(zfs_prop_t prop)
+{
+	return (zfs_prop_table[prop].pd_rightalign);
+}
+
+#endif
+
+#if defined(_KERNEL) && defined(HAVE_SPL)
+static int __init
+zcommon_init(void)
+{
+	return (0);
+}
+
+static void __exit
+zcommon_fini(void)
+{
+}
+
+module_init(zcommon_init);
+module_exit(zcommon_fini);
+
+MODULE_DESCRIPTION("Generic ZFS support");
+MODULE_AUTHOR(ZFS_META_AUTHOR);
+MODULE_LICENSE(ZFS_META_LICENSE);
+MODULE_VERSION(ZFS_META_VERSION "-" ZFS_META_RELEASE);
+
+/* zfs dataset property functions */
+EXPORT_SYMBOL(zfs_userquota_prop_prefixes);
+EXPORT_SYMBOL(zfs_prop_init);
+EXPORT_SYMBOL(zfs_prop_get_type);
+EXPORT_SYMBOL(zfs_prop_get_table);
+EXPORT_SYMBOL(zfs_prop_delegatable);
+
+/* Dataset property functions shared between libzfs and kernel. */
+EXPORT_SYMBOL(zfs_prop_default_string);
+EXPORT_SYMBOL(zfs_prop_default_numeric);
+EXPORT_SYMBOL(zfs_prop_readonly);
+EXPORT_SYMBOL(zfs_prop_inheritable);
+EXPORT_SYMBOL(zfs_prop_setonce);
+EXPORT_SYMBOL(zfs_prop_to_name);
+EXPORT_SYMBOL(zfs_name_to_prop);
+EXPORT_SYMBOL(zfs_prop_user);
+EXPORT_SYMBOL(zfs_prop_userquota);
+EXPORT_SYMBOL(zfs_prop_index_to_string);
+EXPORT_SYMBOL(zfs_prop_string_to_index);
+EXPORT_SYMBOL(zfs_prop_valid_for_type);
+
+#endif
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/module/zcommon/zfs_uio.c
@@ -0,0 +1,257 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
+/*	  All Rights Reserved	*/
+
+/*
+ * University Copyright- Copyright (c) 1982, 1986, 1988
+ * The Regents of the University of California
+ * All Rights Reserved
+ *
+ * University Acknowledgment- Portions of this document are derived from
+ * software developed by the University of California, Berkeley, and its
+ * contributors.
+ */
+/*
+ * Copyright (c) 2015 by Chunwei Chen. All rights reserved.
+ */
+
+/*
+ * The uio support from OpenSolaris has been added as a short term
+ * work around.  The hope is to adopt native Linux type and drop the
+ * use of uio's entirely.  Under Linux they only add overhead and
+ * when possible we want to use native APIs for the ZPL layer.
+ */
+#ifdef _KERNEL
+
+#include <sys/types.h>
+#include <sys/uio_impl.h>
+#include <linux/kmap_compat.h>
+
+/*
+ * Move "n" bytes at byte address "p"; "rw" indicates the direction
+ * of the move, and the I/O parameters are provided in "uio", which is
+ * update to reflect the data which was moved.  Returns 0 on success or
+ * a non-zero errno on failure.
+ */
+static int
+uiomove_iov(void *p, size_t n, enum uio_rw rw, struct uio *uio)
+{
+	const struct iovec *iov = uio->uio_iov;
+	size_t skip = uio->uio_skip;
+	ulong_t cnt;
+
+	while (n && uio->uio_resid) {
+		cnt = MIN(iov->iov_len - skip, n);
+		switch (uio->uio_segflg) {
+		case UIO_USERSPACE:
+		case UIO_USERISPACE:
+			/*
+			 * p = kernel data pointer
+			 * iov->iov_base = user data pointer
+			 */
+			if (rw == UIO_READ) {
+				if (copy_to_user(iov->iov_base+skip, p, cnt))
+					return (EFAULT);
+			} else {
+				if (copy_from_user(p, iov->iov_base+skip, cnt))
+					return (EFAULT);
+			}
+			break;
+		case UIO_SYSSPACE:
+			if (rw == UIO_READ)
+				bcopy(p, iov->iov_base + skip, cnt);
+			else
+				bcopy(iov->iov_base + skip, p, cnt);
+			break;
+		default:
+			ASSERT(0);
+		}
+		skip += cnt;
+		if (skip == iov->iov_len) {
+			skip = 0;
+			uio->uio_iov = (++iov);
+			uio->uio_iovcnt--;
+		}
+		uio->uio_skip = skip;
+		uio->uio_resid -= cnt;
+		uio->uio_loffset += cnt;
+		p = (caddr_t)p + cnt;
+		n -= cnt;
+	}
+	return (0);
+}
+
+static int
+uiomove_bvec(void *p, size_t n, enum uio_rw rw, struct uio *uio)
+{
+	const struct bio_vec *bv = uio->uio_bvec;
+	size_t skip = uio->uio_skip;
+	ulong_t cnt;
+
+	while (n && uio->uio_resid) {
+		void *paddr;
+		cnt = MIN(bv->bv_len - skip, n);
+
+		paddr = zfs_kmap_atomic(bv->bv_page, KM_USER1);
+		if (rw == UIO_READ)
+			bcopy(p, paddr + bv->bv_offset + skip, cnt);
+		else
+			bcopy(paddr + bv->bv_offset + skip, p, cnt);
+		zfs_kunmap_atomic(paddr, KM_USER1);
+
+		skip += cnt;
+		if (skip == bv->bv_len) {
+			skip = 0;
+			uio->uio_bvec = (++bv);
+			uio->uio_iovcnt--;
+		}
+		uio->uio_skip = skip;
+		uio->uio_resid -= cnt;
+		uio->uio_loffset += cnt;
+		p = (caddr_t)p + cnt;
+		n -= cnt;
+	}
+	return (0);
+}
+
+int
+uiomove(void *p, size_t n, enum uio_rw rw, struct uio *uio)
+{
+	if (uio->uio_segflg != UIO_BVEC)
+		return (uiomove_iov(p, n, rw, uio));
+	else
+		return (uiomove_bvec(p, n, rw, uio));
+}
+EXPORT_SYMBOL(uiomove);
+
+#define	fuword8(uptr, vptr)	get_user((*vptr), (uptr))
+
+/*
+ * Fault in the pages of the first n bytes specified by the uio structure.
+ * 1 byte in each page is touched and the uio struct is unmodified. Any
+ * error will terminate the process as this is only a best attempt to get
+ * the pages resident.
+ */
+void
+uio_prefaultpages(ssize_t n, struct uio *uio)
+{
+	const struct iovec *iov;
+	ulong_t cnt, incr;
+	caddr_t p;
+	uint8_t tmp;
+	int iovcnt;
+	size_t skip = uio->uio_skip;
+
+	/* no need to fault in kernel pages */
+	switch (uio->uio_segflg) {
+		case UIO_SYSSPACE:
+		case UIO_BVEC:
+			return;
+		case UIO_USERSPACE:
+		case UIO_USERISPACE:
+			break;
+		default:
+			ASSERT(0);
+	}
+
+	iov = uio->uio_iov;
+	iovcnt = uio->uio_iovcnt;
+
+	while ((n > 0) && (iovcnt > 0)) {
+		cnt = MIN(iov->iov_len - skip, n);
+		n -= cnt;
+		/*
+		 * touch each page in this segment.
+		 */
+		p = iov->iov_base + skip;
+		while (cnt) {
+			if (fuword8((uint8_t *) p, &tmp))
+				return;
+			incr = MIN(cnt, PAGESIZE);
+			p += incr;
+			cnt -= incr;
+		}
+		/*
+		 * touch the last byte in case it straddles a page.
+		 */
+		p--;
+		if (fuword8((uint8_t *) p, &tmp))
+			return;
+		iov++;
+		iovcnt--;
+		skip = 0;
+	}
+}
+EXPORT_SYMBOL(uio_prefaultpages);
+
+/*
+ * same as uiomove() but doesn't modify uio structure.
+ * return in cbytes how many bytes were copied.
+ */
+int
+uiocopy(void *p, size_t n, enum uio_rw rw, struct uio *uio, size_t *cbytes)
+{
+	struct uio uio_copy;
+	int ret;
+
+	bcopy(uio, &uio_copy, sizeof (struct uio));
+	ret = uiomove(p, n, rw, &uio_copy);
+	*cbytes = uio->uio_resid - uio_copy.uio_resid;
+	return (ret);
+}
+EXPORT_SYMBOL(uiocopy);
+
+/*
+ * Drop the next n chars out of *uiop.
+ */
+void
+uioskip(uio_t *uiop, size_t n)
+{
+	if (n > uiop->uio_resid)
+		return;
+
+	uiop->uio_skip += n;
+	if (uiop->uio_segflg != UIO_BVEC) {
+		while (uiop->uio_iovcnt &&
+		    uiop->uio_skip >= uiop->uio_iov->iov_len) {
+			uiop->uio_skip -= uiop->uio_iov->iov_len;
+			uiop->uio_iov++;
+			uiop->uio_iovcnt--;
+		}
+	} else {
+		while (uiop->uio_iovcnt &&
+		    uiop->uio_skip >= uiop->uio_bvec->bv_len) {
+			uiop->uio_skip -= uiop->uio_bvec->bv_len;
+			uiop->uio_bvec++;
+			uiop->uio_iovcnt--;
+		}
+	}
+	uiop->uio_loffset += n;
+	uiop->uio_resid -= n;
+}
+EXPORT_SYMBOL(uioskip);
+#endif /* _KERNEL */
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/module/zcommon/zpool_prop.c
@@ -0,0 +1,260 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
+ * Copyright (c) 2012, 2014 by Delphix. All rights reserved.
+ */
+
+#include <sys/zio.h>
+#include <sys/spa.h>
+#include <sys/zfs_acl.h>
+#include <sys/zfs_ioctl.h>
+#include <sys/fs/zfs.h>
+
+#include "zfs_prop.h"
+
+#if defined(_KERNEL)
+#include <sys/systm.h>
+#else
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#endif
+
+static zprop_desc_t zpool_prop_table[ZPOOL_NUM_PROPS];
+
+zprop_desc_t *
+zpool_prop_get_table(void)
+{
+	return (zpool_prop_table);
+}
+
+void
+zpool_prop_init(void)
+{
+	static zprop_index_t boolean_table[] = {
+		{ "off",	0},
+		{ "on",		1},
+		{ NULL }
+	};
+
+	static zprop_index_t failuremode_table[] = {
+		{ "wait",	ZIO_FAILURE_MODE_WAIT },
+		{ "continue",	ZIO_FAILURE_MODE_CONTINUE },
+		{ "panic",	ZIO_FAILURE_MODE_PANIC },
+		{ NULL }
+	};
+
+	/* string properties */
+	zprop_register_string(ZPOOL_PROP_ALTROOT, "altroot", NULL, PROP_DEFAULT,
+	    ZFS_TYPE_POOL, "<path>", "ALTROOT");
+	zprop_register_string(ZPOOL_PROP_BOOTFS, "bootfs", NULL, PROP_DEFAULT,
+	    ZFS_TYPE_POOL, "<filesystem>", "BOOTFS");
+	zprop_register_string(ZPOOL_PROP_CACHEFILE, "cachefile", NULL,
+	    PROP_DEFAULT, ZFS_TYPE_POOL, "<file> | none", "CACHEFILE");
+	zprop_register_string(ZPOOL_PROP_COMMENT, "comment", NULL,
+	    PROP_DEFAULT, ZFS_TYPE_POOL, "<comment-string>", "COMMENT");
+
+	/* readonly number properties */
+	zprop_register_number(ZPOOL_PROP_SIZE, "size", 0, PROP_READONLY,
+	    ZFS_TYPE_POOL, "<size>", "SIZE");
+	zprop_register_number(ZPOOL_PROP_FREE, "free", 0, PROP_READONLY,
+	    ZFS_TYPE_POOL, "<size>", "FREE");
+	zprop_register_number(ZPOOL_PROP_FREEING, "freeing", 0, PROP_READONLY,
+	    ZFS_TYPE_POOL, "<size>", "FREEING");
+	zprop_register_number(ZPOOL_PROP_LEAKED, "leaked", 0, PROP_READONLY,
+	    ZFS_TYPE_POOL, "<size>", "LEAKED");
+	zprop_register_number(ZPOOL_PROP_ALLOCATED, "allocated", 0,
+	    PROP_READONLY, ZFS_TYPE_POOL, "<size>", "ALLOC");
+	zprop_register_number(ZPOOL_PROP_EXPANDSZ, "expandsize", 0,
+	    PROP_READONLY, ZFS_TYPE_POOL, "<size>", "EXPANDSZ");
+	zprop_register_number(ZPOOL_PROP_FRAGMENTATION, "fragmentation", 0,
+	    PROP_READONLY, ZFS_TYPE_POOL, "<percent>", "FRAG");
+	zprop_register_number(ZPOOL_PROP_CAPACITY, "capacity", 0, PROP_READONLY,
+	    ZFS_TYPE_POOL, "<size>", "CAP");
+	zprop_register_number(ZPOOL_PROP_GUID, "guid", 0, PROP_READONLY,
+	    ZFS_TYPE_POOL, "<guid>", "GUID");
+	zprop_register_number(ZPOOL_PROP_HEALTH, "health", 0, PROP_READONLY,
+	    ZFS_TYPE_POOL, "<state>", "HEALTH");
+	zprop_register_number(ZPOOL_PROP_DEDUPRATIO, "dedupratio", 0,
+	    PROP_READONLY, ZFS_TYPE_POOL, "<1.00x or higher if deduped>",
+	    "DEDUP");
+
+	/* readonly onetime number properties */
+	zprop_register_number(ZPOOL_PROP_ASHIFT, "ashift", 0, PROP_ONETIME,
+	    ZFS_TYPE_POOL, "<ashift, 9-13, or 0=default>", "ASHIFT");
+
+	/* default number properties */
+	zprop_register_number(ZPOOL_PROP_VERSION, "version", SPA_VERSION,
+	    PROP_DEFAULT, ZFS_TYPE_POOL, "<version>", "VERSION");
+	zprop_register_number(ZPOOL_PROP_DEDUPDITTO, "dedupditto", 0,
+	    PROP_DEFAULT, ZFS_TYPE_POOL, "<threshold (min 100)>", "DEDUPDITTO");
+
+	/* default index (boolean) properties */
+	zprop_register_index(ZPOOL_PROP_DELEGATION, "delegation", 1,
+	    PROP_DEFAULT, ZFS_TYPE_POOL, "on | off", "DELEGATION",
+	    boolean_table);
+	zprop_register_index(ZPOOL_PROP_AUTOREPLACE, "autoreplace", 0,
+	    PROP_DEFAULT, ZFS_TYPE_POOL, "on | off", "REPLACE", boolean_table);
+	zprop_register_index(ZPOOL_PROP_LISTSNAPS, "listsnapshots", 0,
+	    PROP_DEFAULT, ZFS_TYPE_POOL, "on | off", "LISTSNAPS",
+	    boolean_table);
+	zprop_register_index(ZPOOL_PROP_AUTOEXPAND, "autoexpand", 0,
+	    PROP_DEFAULT, ZFS_TYPE_POOL, "on | off", "EXPAND", boolean_table);
+	zprop_register_index(ZPOOL_PROP_READONLY, "readonly", 0,
+	    PROP_DEFAULT, ZFS_TYPE_POOL, "on | off", "RDONLY", boolean_table);
+
+	/* default index properties */
+	zprop_register_index(ZPOOL_PROP_FAILUREMODE, "failmode",
+	    ZIO_FAILURE_MODE_WAIT, PROP_DEFAULT, ZFS_TYPE_POOL,
+	    "wait | continue | panic", "FAILMODE", failuremode_table);
+
+	/* hidden properties */
+	zprop_register_hidden(ZPOOL_PROP_NAME, "name", PROP_TYPE_STRING,
+	    PROP_READONLY, ZFS_TYPE_POOL, "NAME");
+	zprop_register_hidden(ZPOOL_PROP_MAXBLOCKSIZE, "maxblocksize",
+	    PROP_TYPE_NUMBER, PROP_READONLY, ZFS_TYPE_POOL, "MAXBLOCKSIZE");
+	zprop_register_hidden(ZPOOL_PROP_TNAME, "tname", PROP_TYPE_STRING,
+	    PROP_ONETIME, ZFS_TYPE_POOL, "TNAME");
+}
+
+/*
+ * Given a property name and its type, returns the corresponding property ID.
+ */
+zpool_prop_t
+zpool_name_to_prop(const char *propname)
+{
+	return (zprop_name_to_prop(propname, ZFS_TYPE_POOL));
+}
+
+/*
+ * Given a pool property ID, returns the corresponding name.
+ * Assuming the pool propety ID is valid.
+ */
+const char *
+zpool_prop_to_name(zpool_prop_t prop)
+{
+	return (zpool_prop_table[prop].pd_name);
+}
+
+zprop_type_t
+zpool_prop_get_type(zpool_prop_t prop)
+{
+	return (zpool_prop_table[prop].pd_proptype);
+}
+
+boolean_t
+zpool_prop_readonly(zpool_prop_t prop)
+{
+	return (zpool_prop_table[prop].pd_attr == PROP_READONLY);
+}
+
+const char *
+zpool_prop_default_string(zpool_prop_t prop)
+{
+	return (zpool_prop_table[prop].pd_strdefault);
+}
+
+uint64_t
+zpool_prop_default_numeric(zpool_prop_t prop)
+{
+	return (zpool_prop_table[prop].pd_numdefault);
+}
+
+/*
+ * Returns true if this is a valid feature@ property.
+ */
+boolean_t
+zpool_prop_feature(const char *name)
+{
+	static const char *prefix = "feature@";
+	return (strncmp(name, prefix, strlen(prefix)) == 0);
+}
+
+/*
+ * Returns true if this is a valid unsupported@ property.
+ */
+boolean_t
+zpool_prop_unsupported(const char *name)
+{
+	static const char *prefix = "unsupported@";
+	return (strncmp(name, prefix, strlen(prefix)) == 0);
+}
+
+int
+zpool_prop_string_to_index(zpool_prop_t prop, const char *string,
+    uint64_t *index)
+{
+	return (zprop_string_to_index(prop, string, index, ZFS_TYPE_POOL));
+}
+
+int
+zpool_prop_index_to_string(zpool_prop_t prop, uint64_t index,
+    const char **string)
+{
+	return (zprop_index_to_string(prop, index, string, ZFS_TYPE_POOL));
+}
+
+uint64_t
+zpool_prop_random_value(zpool_prop_t prop, uint64_t seed)
+{
+	return (zprop_random_value(prop, seed, ZFS_TYPE_POOL));
+}
+
+#ifndef _KERNEL
+
+const char *
+zpool_prop_values(zpool_prop_t prop)
+{
+	return (zpool_prop_table[prop].pd_values);
+}
+
+const char *
+zpool_prop_column_name(zpool_prop_t prop)
+{
+	return (zpool_prop_table[prop].pd_colname);
+}
+
+boolean_t
+zpool_prop_align_right(zpool_prop_t prop)
+{
+	return (zpool_prop_table[prop].pd_rightalign);
+}
+#endif
+
+#if defined(_KERNEL) && defined(HAVE_SPL)
+/* zpool property functions */
+EXPORT_SYMBOL(zpool_prop_init);
+EXPORT_SYMBOL(zpool_prop_get_type);
+EXPORT_SYMBOL(zpool_prop_get_table);
+
+/* Pool property functions shared between libzfs and kernel. */
+EXPORT_SYMBOL(zpool_name_to_prop);
+EXPORT_SYMBOL(zpool_prop_to_name);
+EXPORT_SYMBOL(zpool_prop_default_string);
+EXPORT_SYMBOL(zpool_prop_default_numeric);
+EXPORT_SYMBOL(zpool_prop_readonly);
+EXPORT_SYMBOL(zpool_prop_feature);
+EXPORT_SYMBOL(zpool_prop_unsupported);
+EXPORT_SYMBOL(zpool_prop_index_to_string);
+EXPORT_SYMBOL(zpool_prop_string_to_index);
+#endif
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/module/zcommon/zprop_common.c
@@ -0,0 +1,454 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * Copyright (c) 2012 by Delphix. All rights reserved.
+ */
+
+/*
+ * Common routines used by zfs and zpool property management.
+ */
+
+#include <sys/zio.h>
+#include <sys/spa.h>
+#include <sys/zfs_acl.h>
+#include <sys/zfs_ioctl.h>
+#include <sys/zfs_znode.h>
+#include <sys/fs/zfs.h>
+
+#include "zfs_prop.h"
+#include "zfs_deleg.h"
+
+#if defined(_KERNEL)
+#include <sys/systm.h>
+#include <util/qsort.h>
+#else
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#endif
+
+static zprop_desc_t *
+zprop_get_proptable(zfs_type_t type)
+{
+	if (type == ZFS_TYPE_POOL)
+		return (zpool_prop_get_table());
+	else
+		return (zfs_prop_get_table());
+}
+
+static int
+zprop_get_numprops(zfs_type_t type)
+{
+	if (type == ZFS_TYPE_POOL)
+		return (ZPOOL_NUM_PROPS);
+	else
+		return (ZFS_NUM_PROPS);
+}
+
+void
+zprop_register_impl(int prop, const char *name, zprop_type_t type,
+    uint64_t numdefault, const char *strdefault, zprop_attr_t attr,
+    int objset_types, const char *values, const char *colname,
+    boolean_t rightalign, boolean_t visible, const zprop_index_t *idx_tbl)
+{
+	zprop_desc_t *prop_tbl = zprop_get_proptable(objset_types);
+	zprop_desc_t *pd;
+
+	pd = &prop_tbl[prop];
+
+	ASSERT(pd->pd_name == NULL || pd->pd_name == name);
+	ASSERT(name != NULL);
+	ASSERT(colname != NULL);
+
+	pd->pd_name = name;
+	pd->pd_propnum = prop;
+	pd->pd_proptype = type;
+	pd->pd_numdefault = numdefault;
+	pd->pd_strdefault = strdefault;
+	pd->pd_attr = attr;
+	pd->pd_types = objset_types;
+	pd->pd_values = values;
+	pd->pd_colname = colname;
+	pd->pd_rightalign = rightalign;
+	pd->pd_visible = visible;
+	pd->pd_table = idx_tbl;
+	pd->pd_table_size = 0;
+	while (idx_tbl && (idx_tbl++)->pi_name != NULL)
+		pd->pd_table_size++;
+}
+
+void
+zprop_register_string(int prop, const char *name, const char *def,
+    zprop_attr_t attr, int objset_types, const char *values,
+    const char *colname)
+{
+	zprop_register_impl(prop, name, PROP_TYPE_STRING, 0, def, attr,
+	    objset_types, values, colname, B_FALSE, B_TRUE, NULL);
+
+}
+
+void
+zprop_register_number(int prop, const char *name, uint64_t def,
+    zprop_attr_t attr, int objset_types, const char *values,
+    const char *colname)
+{
+	zprop_register_impl(prop, name, PROP_TYPE_NUMBER, def, NULL, attr,
+	    objset_types, values, colname, B_TRUE, B_TRUE, NULL);
+}
+
+void
+zprop_register_index(int prop, const char *name, uint64_t def,
+    zprop_attr_t attr, int objset_types, const char *values,
+    const char *colname, const zprop_index_t *idx_tbl)
+{
+	zprop_register_impl(prop, name, PROP_TYPE_INDEX, def, NULL, attr,
+	    objset_types, values, colname, B_TRUE, B_TRUE, idx_tbl);
+}
+
+void
+zprop_register_hidden(int prop, const char *name, zprop_type_t type,
+    zprop_attr_t attr, int objset_types, const char *colname)
+{
+	zprop_register_impl(prop, name, type, 0, NULL, attr,
+	    objset_types, NULL, colname,
+	    type == PROP_TYPE_NUMBER, B_FALSE, NULL);
+}
+
+
+/*
+ * A comparison function we can use to order indexes into property tables.
+ */
+static int
+zprop_compare(const void *arg1, const void *arg2)
+{
+	const zprop_desc_t *p1 = *((zprop_desc_t **)arg1);
+	const zprop_desc_t *p2 = *((zprop_desc_t **)arg2);
+	boolean_t p1ro, p2ro;
+
+	p1ro = (p1->pd_attr == PROP_READONLY);
+	p2ro = (p2->pd_attr == PROP_READONLY);
+
+	if (p1ro == p2ro)
+		return (strcmp(p1->pd_name, p2->pd_name));
+
+	return (p1ro ? -1 : 1);
+}
+
+/*
+ * Iterate over all properties in the given property table, calling back
+ * into the specified function for each property. We will continue to
+ * iterate until we either reach the end or the callback function returns
+ * something other than ZPROP_CONT.
+ */
+int
+zprop_iter_common(zprop_func func, void *cb, boolean_t show_all,
+    boolean_t ordered, zfs_type_t type)
+{
+	int i, j, num_props, size, prop;
+	zprop_desc_t *prop_tbl;
+	zprop_desc_t **order;
+
+	prop_tbl = zprop_get_proptable(type);
+	num_props = zprop_get_numprops(type);
+	size = num_props * sizeof (zprop_desc_t *);
+
+#if defined(_KERNEL)
+	order = kmem_alloc(size, KM_SLEEP);
+#else
+	if ((order = malloc(size)) == NULL)
+		return (ZPROP_CONT);
+#endif
+
+	for (j = 0; j < num_props; j++)
+		order[j] = &prop_tbl[j];
+
+	if (ordered) {
+		qsort((void *)order, num_props, sizeof (zprop_desc_t *),
+		    zprop_compare);
+	}
+
+	prop = ZPROP_CONT;
+	for (i = 0; i < num_props; i++) {
+		if ((order[i]->pd_visible || show_all) &&
+		    (func(order[i]->pd_propnum, cb) != ZPROP_CONT)) {
+			prop = order[i]->pd_propnum;
+			break;
+		}
+	}
+
+#if defined(_KERNEL)
+	kmem_free(order, size);
+#else
+	free(order);
+#endif
+	return (prop);
+}
+
+static boolean_t
+propname_match(const char *p, size_t len, zprop_desc_t *prop_entry)
+{
+	const char *propname = prop_entry->pd_name;
+#ifndef _KERNEL
+	const char *colname = prop_entry->pd_colname;
+	int c;
+#endif
+
+	if (len == strlen(propname) &&
+	    strncmp(p, propname, len) == 0)
+		return (B_TRUE);
+
+#ifndef _KERNEL
+	if (colname == NULL || len != strlen(colname))
+		return (B_FALSE);
+
+	for (c = 0; c < len; c++)
+		if (p[c] != tolower(colname[c]))
+			break;
+
+	return (colname[c] == '\0');
+#else
+	return (B_FALSE);
+#endif
+}
+
+typedef struct name_to_prop_cb {
+	const char *propname;
+	zprop_desc_t *prop_tbl;
+} name_to_prop_cb_t;
+
+static int
+zprop_name_to_prop_cb(int prop, void *cb_data)
+{
+	name_to_prop_cb_t *data = cb_data;
+
+	if (propname_match(data->propname, strlen(data->propname),
+	    &data->prop_tbl[prop]))
+		return (prop);
+
+	return (ZPROP_CONT);
+}
+
+int
+zprop_name_to_prop(const char *propname, zfs_type_t type)
+{
+	int prop;
+	name_to_prop_cb_t cb_data;
+
+	cb_data.propname = propname;
+	cb_data.prop_tbl = zprop_get_proptable(type);
+
+	prop = zprop_iter_common(zprop_name_to_prop_cb, &cb_data,
+	    B_TRUE, B_FALSE, type);
+
+	return (prop == ZPROP_CONT ? ZPROP_INVAL : prop);
+}
+
+int
+zprop_string_to_index(int prop, const char *string, uint64_t *index,
+    zfs_type_t type)
+{
+	zprop_desc_t *prop_tbl;
+	const zprop_index_t *idx_tbl;
+	int i;
+
+	if (prop == ZPROP_INVAL || prop == ZPROP_CONT)
+		return (-1);
+
+	ASSERT(prop < zprop_get_numprops(type));
+	prop_tbl = zprop_get_proptable(type);
+	if ((idx_tbl = prop_tbl[prop].pd_table) == NULL)
+		return (-1);
+
+	for (i = 0; idx_tbl[i].pi_name != NULL; i++) {
+		if (strcmp(string, idx_tbl[i].pi_name) == 0) {
+			*index = idx_tbl[i].pi_value;
+			return (0);
+		}
+	}
+
+	return (-1);
+}
+
+int
+zprop_index_to_string(int prop, uint64_t index, const char **string,
+    zfs_type_t type)
+{
+	zprop_desc_t *prop_tbl;
+	const zprop_index_t *idx_tbl;
+	int i;
+
+	if (prop == ZPROP_INVAL || prop == ZPROP_CONT)
+		return (-1);
+
+	ASSERT(prop < zprop_get_numprops(type));
+	prop_tbl = zprop_get_proptable(type);
+	if ((idx_tbl = prop_tbl[prop].pd_table) == NULL)
+		return (-1);
+
+	for (i = 0; idx_tbl[i].pi_name != NULL; i++) {
+		if (idx_tbl[i].pi_value == index) {
+			*string = idx_tbl[i].pi_name;
+			return (0);
+		}
+	}
+
+	return (-1);
+}
+
+/*
+ * Return a random valid property value.  Used by ztest.
+ */
+uint64_t
+zprop_random_value(int prop, uint64_t seed, zfs_type_t type)
+{
+	zprop_desc_t *prop_tbl;
+	const zprop_index_t *idx_tbl;
+
+	ASSERT((uint_t)prop < zprop_get_numprops(type));
+	prop_tbl = zprop_get_proptable(type);
+	idx_tbl = prop_tbl[prop].pd_table;
+
+	if (idx_tbl == NULL)
+		return (seed);
+
+	return (idx_tbl[seed % prop_tbl[prop].pd_table_size].pi_value);
+}
+
+const char *
+zprop_values(int prop, zfs_type_t type)
+{
+	zprop_desc_t *prop_tbl;
+
+	ASSERT(prop != ZPROP_INVAL && prop != ZPROP_CONT);
+	ASSERT(prop < zprop_get_numprops(type));
+
+	prop_tbl = zprop_get_proptable(type);
+
+	return (prop_tbl[prop].pd_values);
+}
+
+/*
+ * Returns TRUE if the property applies to any of the given dataset types.
+ *
+ * If headcheck is set, the check is being made against the head dataset
+ * type of a snapshot which requires to return B_TRUE when the property
+ * is only valid for snapshots.
+ */
+boolean_t
+zprop_valid_for_type(int prop, zfs_type_t type, boolean_t headcheck)
+{
+	zprop_desc_t *prop_tbl;
+
+	if (prop == ZPROP_INVAL || prop == ZPROP_CONT)
+		return (B_FALSE);
+
+	ASSERT(prop < zprop_get_numprops(type));
+	prop_tbl = zprop_get_proptable(type);
+	if (headcheck && prop_tbl[prop].pd_types == ZFS_TYPE_SNAPSHOT)
+		return (B_TRUE);
+	return ((prop_tbl[prop].pd_types & type) != 0);
+}
+
+#ifndef _KERNEL
+
+/*
+ * Determines the minimum width for the column, and indicates whether it's fixed
+ * or not.  Only string columns are non-fixed.
+ */
+size_t
+zprop_width(int prop, boolean_t *fixed, zfs_type_t type)
+{
+	zprop_desc_t *prop_tbl, *pd;
+	const zprop_index_t *idx;
+	size_t ret;
+	int i;
+
+	ASSERT(prop != ZPROP_INVAL && prop != ZPROP_CONT);
+	ASSERT(prop < zprop_get_numprops(type));
+
+	prop_tbl = zprop_get_proptable(type);
+	pd = &prop_tbl[prop];
+
+	*fixed = B_TRUE;
+
+	/*
+	 * Start with the width of the column name.
+	 */
+	ret = strlen(pd->pd_colname);
+
+	/*
+	 * For fixed-width values, make sure the width is large enough to hold
+	 * any possible value.
+	 */
+	switch (pd->pd_proptype) {
+	case PROP_TYPE_NUMBER:
+		/*
+		 * The maximum length of a human-readable number is 5 characters
+		 * ("20.4M", for example).
+		 */
+		if (ret < 5)
+			ret = 5;
+		/*
+		 * 'creation' is handled specially because it's a number
+		 * internally, but displayed as a date string.
+		 */
+		if (prop == ZFS_PROP_CREATION)
+			*fixed = B_FALSE;
+		break;
+	case PROP_TYPE_INDEX:
+		idx = prop_tbl[prop].pd_table;
+		for (i = 0; idx[i].pi_name != NULL; i++) {
+			if (strlen(idx[i].pi_name) > ret)
+				ret = strlen(idx[i].pi_name);
+		}
+		break;
+
+	case PROP_TYPE_STRING:
+		*fixed = B_FALSE;
+		break;
+	}
+
+	return (ret);
+}
+
+#endif
+
+#if defined(_KERNEL) && defined(HAVE_SPL)
+/* Common routines to initialize property tables */
+EXPORT_SYMBOL(zprop_register_impl);
+EXPORT_SYMBOL(zprop_register_string);
+EXPORT_SYMBOL(zprop_register_number);
+EXPORT_SYMBOL(zprop_register_index);
+EXPORT_SYMBOL(zprop_register_hidden);
+
+/* Common routines for zfs and zpool property management */
+EXPORT_SYMBOL(zprop_iter_common);
+EXPORT_SYMBOL(zprop_name_to_prop);
+EXPORT_SYMBOL(zprop_string_to_index);
+EXPORT_SYMBOL(zprop_index_to_string);
+EXPORT_SYMBOL(zprop_random_value);
+EXPORT_SYMBOL(zprop_values);
+EXPORT_SYMBOL(zprop_valid_for_type);
+#endif
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/module/zfs/Makefile.in
@@ -0,0 +1,108 @@
+src = @abs_top_srcdir@/module/zfs
+obj = @abs_builddir@
+
+MODULE := zfs
+
+EXTRA_CFLAGS = $(ZFS_MODULE_CFLAGS) @KERNELCPPFLAGS@
+
+obj-$(CONFIG_ZFS) := $(MODULE).o
+
+$(MODULE)-objs += arc.o
+$(MODULE)-objs += blkptr.o
+$(MODULE)-objs += bplist.o
+$(MODULE)-objs += bpobj.o
+$(MODULE)-objs += dbuf.o
+$(MODULE)-objs += dbuf_stats.o
+$(MODULE)-objs += bptree.o
+$(MODULE)-objs += ddt.o
+$(MODULE)-objs += ddt_zap.o
+$(MODULE)-objs += dmu.o
+$(MODULE)-objs += dmu_diff.o
+$(MODULE)-objs += dmu_object.o
+$(MODULE)-objs += dmu_objset.o
+$(MODULE)-objs += dmu_send.o
+$(MODULE)-objs += dmu_traverse.o
+$(MODULE)-objs += dmu_tx.o
+$(MODULE)-objs += dmu_zfetch.o
+$(MODULE)-objs += dnode.o
+$(MODULE)-objs += dnode_sync.o
+$(MODULE)-objs += dsl_dataset.o
+$(MODULE)-objs += dsl_deadlist.o
+$(MODULE)-objs += dsl_deleg.o
+$(MODULE)-objs += dsl_bookmark.o
+$(MODULE)-objs += dsl_dir.o
+$(MODULE)-objs += dsl_pool.o
+$(MODULE)-objs += dsl_prop.o
+$(MODULE)-objs += dsl_scan.o
+$(MODULE)-objs += dsl_synctask.o
+$(MODULE)-objs += fm.o
+$(MODULE)-objs += gzip.o
+$(MODULE)-objs += lzjb.o
+$(MODULE)-objs += lz4.o
+$(MODULE)-objs += metaslab.o
+$(MODULE)-objs += multilist.o
+$(MODULE)-objs += range_tree.o
+$(MODULE)-objs += refcount.o
+$(MODULE)-objs += rrwlock.o
+$(MODULE)-objs += sa.o
+$(MODULE)-objs += sha256.o
+$(MODULE)-objs += spa.o
+$(MODULE)-objs += spa_boot.o
+$(MODULE)-objs += spa_config.o
+$(MODULE)-objs += spa_errlog.o
+$(MODULE)-objs += spa_history.o
+$(MODULE)-objs += spa_misc.o
+$(MODULE)-objs += spa_stats.o
+$(MODULE)-objs += space_map.o
+$(MODULE)-objs += space_reftree.o
+$(MODULE)-objs += txg.o
+$(MODULE)-objs += trace.o
+$(MODULE)-objs += uberblock.o
+$(MODULE)-objs += unique.o
+$(MODULE)-objs += vdev.o
+$(MODULE)-objs += vdev_cache.o
+$(MODULE)-objs += vdev_disk.o
+$(MODULE)-objs += vdev_file.o
+$(MODULE)-objs += vdev_label.o
+$(MODULE)-objs += vdev_mirror.o
+$(MODULE)-objs += vdev_missing.o
+$(MODULE)-objs += vdev_queue.o
+$(MODULE)-objs += vdev_raidz.o
+$(MODULE)-objs += vdev_root.o
+$(MODULE)-objs += zap.o
+$(MODULE)-objs += zap_leaf.o
+$(MODULE)-objs += zap_micro.o
+$(MODULE)-objs += zfeature.o
+$(MODULE)-objs += zfeature_common.o
+$(MODULE)-objs += zfs_acl.o
+$(MODULE)-objs += zfs_byteswap.o
+$(MODULE)-objs += zfs_ctldir.o
+$(MODULE)-objs += zfs_debug.o
+$(MODULE)-objs += zfs_dir.o
+$(MODULE)-objs += zfs_fm.o
+$(MODULE)-objs += zfs_fuid.o
+$(MODULE)-objs += zfs_ioctl.o
+$(MODULE)-objs += zfs_log.o
+$(MODULE)-objs += zfs_onexit.o
+$(MODULE)-objs += zfs_replay.o
+$(MODULE)-objs += zfs_rlock.o
+$(MODULE)-objs += zfs_sa.o
+$(MODULE)-objs += zfs_vfsops.o
+$(MODULE)-objs += zfs_vnops.o
+$(MODULE)-objs += zfs_znode.o
+$(MODULE)-objs += zil.o
+$(MODULE)-objs += zio.o
+$(MODULE)-objs += zio_checksum.o
+$(MODULE)-objs += zio_compress.o
+$(MODULE)-objs += zio_inject.o
+$(MODULE)-objs += zle.o
+$(MODULE)-objs += zpl_ctldir.o
+$(MODULE)-objs += zpl_export.o
+$(MODULE)-objs += zpl_file.o
+$(MODULE)-objs += zpl_inode.o
+$(MODULE)-objs += zpl_super.o
+$(MODULE)-objs += zpl_xattr.o
+$(MODULE)-objs += zrlock.o
+$(MODULE)-objs += zvol.o
+$(MODULE)-objs += dsl_destroy.o
+$(MODULE)-objs += dsl_userhold.o
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/module/zfs/arc.c
@@ -0,0 +1,7093 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, Joyent, Inc. All rights reserved.
+ * Copyright (c) 2011, 2015 by Delphix. All rights reserved.
+ * Copyright (c) 2014 by Saso Kiselkov. All rights reserved.
+ * Copyright 2014 Nexenta Systems, Inc.  All rights reserved.
+ */
+
+/*
+ * DVA-based Adjustable Replacement Cache
+ *
+ * While much of the theory of operation used here is
+ * based on the self-tuning, low overhead replacement cache
+ * presented by Megiddo and Modha at FAST 2003, there are some
+ * significant differences:
+ *
+ * 1. The Megiddo and Modha model assumes any page is evictable.
+ * Pages in its cache cannot be "locked" into memory.  This makes
+ * the eviction algorithm simple: evict the last page in the list.
+ * This also make the performance characteristics easy to reason
+ * about.  Our cache is not so simple.  At any given moment, some
+ * subset of the blocks in the cache are un-evictable because we
+ * have handed out a reference to them.  Blocks are only evictable
+ * when there are no external references active.  This makes
+ * eviction far more problematic:  we choose to evict the evictable
+ * blocks that are the "lowest" in the list.
+ *
+ * There are times when it is not possible to evict the requested
+ * space.  In these circumstances we are unable to adjust the cache
+ * size.  To prevent the cache growing unbounded at these times we
+ * implement a "cache throttle" that slows the flow of new data
+ * into the cache until we can make space available.
+ *
+ * 2. The Megiddo and Modha model assumes a fixed cache size.
+ * Pages are evicted when the cache is full and there is a cache
+ * miss.  Our model has a variable sized cache.  It grows with
+ * high use, but also tries to react to memory pressure from the
+ * operating system: decreasing its size when system memory is
+ * tight.
+ *
+ * 3. The Megiddo and Modha model assumes a fixed page size. All
+ * elements of the cache are therefore exactly the same size.  So
+ * when adjusting the cache size following a cache miss, its simply
+ * a matter of choosing a single page to evict.  In our model, we
+ * have variable sized cache blocks (rangeing from 512 bytes to
+ * 128K bytes).  We therefore choose a set of blocks to evict to make
+ * space for a cache miss that approximates as closely as possible
+ * the space used by the new block.
+ *
+ * See also:  "ARC: A Self-Tuning, Low Overhead Replacement Cache"
+ * by N. Megiddo & D. Modha, FAST 2003
+ */
+
+/*
+ * The locking model:
+ *
+ * A new reference to a cache buffer can be obtained in two
+ * ways: 1) via a hash table lookup using the DVA as a key,
+ * or 2) via one of the ARC lists.  The arc_read() interface
+ * uses method 1, while the internal arc algorithms for
+ * adjusting the cache use method 2.  We therefore provide two
+ * types of locks: 1) the hash table lock array, and 2) the
+ * arc list locks.
+ *
+ * Buffers do not have their own mutexes, rather they rely on the
+ * hash table mutexes for the bulk of their protection (i.e. most
+ * fields in the arc_buf_hdr_t are protected by these mutexes).
+ *
+ * buf_hash_find() returns the appropriate mutex (held) when it
+ * locates the requested buffer in the hash table.  It returns
+ * NULL for the mutex if the buffer was not in the table.
+ *
+ * buf_hash_remove() expects the appropriate hash mutex to be
+ * already held before it is invoked.
+ *
+ * Each arc state also has a mutex which is used to protect the
+ * buffer list associated with the state.  When attempting to
+ * obtain a hash table lock while holding an arc list lock you
+ * must use: mutex_tryenter() to avoid deadlock.  Also note that
+ * the active state mutex must be held before the ghost state mutex.
+ *
+ * Arc buffers may have an associated eviction callback function.
+ * This function will be invoked prior to removing the buffer (e.g.
+ * in arc_do_user_evicts()).  Note however that the data associated
+ * with the buffer may be evicted prior to the callback.  The callback
+ * must be made with *no locks held* (to prevent deadlock).  Additionally,
+ * the users of callbacks must ensure that their private data is
+ * protected from simultaneous callbacks from arc_clear_callback()
+ * and arc_do_user_evicts().
+ *
+ * It as also possible to register a callback which is run when the
+ * arc_meta_limit is reached and no buffers can be safely evicted.  In
+ * this case the arc user should drop a reference on some arc buffers so
+ * they can be reclaimed and the arc_meta_limit honored.  For example,
+ * when using the ZPL each dentry holds a references on a znode.  These
+ * dentries must be pruned before the arc buffer holding the znode can
+ * be safely evicted.
+ *
+ * Note that the majority of the performance stats are manipulated
+ * with atomic operations.
+ *
+ * The L2ARC uses the l2ad_mtx on each vdev for the following:
+ *
+ *	- L2ARC buflist creation
+ *	- L2ARC buflist eviction
+ *	- L2ARC write completion, which walks L2ARC buflists
+ *	- ARC header destruction, as it removes from L2ARC buflists
+ *	- ARC header release, as it removes from L2ARC buflists
+ */
+
+#include <sys/spa.h>
+#include <sys/zio.h>
+#include <sys/zio_compress.h>
+#include <sys/zfs_context.h>
+#include <sys/arc.h>
+#include <sys/refcount.h>
+#include <sys/vdev.h>
+#include <sys/vdev_impl.h>
+#include <sys/dsl_pool.h>
+#include <sys/multilist.h>
+#ifdef _KERNEL
+#include <sys/vmsystm.h>
+#include <vm/anon.h>
+#include <sys/fs/swapnode.h>
+#include <sys/zpl.h>
+#include <linux/mm_compat.h>
+#endif
+#include <sys/callb.h>
+#include <sys/kstat.h>
+#include <sys/dmu_tx.h>
+#include <zfs_fletcher.h>
+#include <sys/arc_impl.h>
+#include <sys/trace_arc.h>
+
+#ifndef _KERNEL
+/* set with ZFS_DEBUG=watch, to enable watchpoints on frozen buffers */
+boolean_t arc_watch = B_FALSE;
+#endif
+
+static kmutex_t		arc_reclaim_lock;
+static kcondvar_t	arc_reclaim_thread_cv;
+static boolean_t	arc_reclaim_thread_exit;
+static kcondvar_t	arc_reclaim_waiters_cv;
+
+static kmutex_t		arc_user_evicts_lock;
+static kcondvar_t	arc_user_evicts_cv;
+static boolean_t	arc_user_evicts_thread_exit;
+
+/*
+ * The number of headers to evict in arc_evict_state_impl() before
+ * dropping the sublist lock and evicting from another sublist. A lower
+ * value means we're more likely to evict the "correct" header (i.e. the
+ * oldest header in the arc state), but comes with higher overhead
+ * (i.e. more invocations of arc_evict_state_impl()).
+ */
+int zfs_arc_evict_batch_limit = 10;
+
+/*
+ * The number of sublists used for each of the arc state lists. If this
+ * is not set to a suitable value by the user, it will be configured to
+ * the number of CPUs on the system in arc_init().
+ */
+int zfs_arc_num_sublists_per_state = 0;
+
+/* number of seconds before growing cache again */
+static int		arc_grow_retry = 5;
+
+/* shift of arc_c for calculating overflow limit in arc_get_data_buf */
+int		zfs_arc_overflow_shift = 8;
+
+/* shift of arc_c for calculating both min and max arc_p */
+static int		arc_p_min_shift = 4;
+
+/* log2(fraction of arc to reclaim) */
+static int		arc_shrink_shift = 7;
+
+/*
+ * log2(fraction of ARC which must be free to allow growing).
+ * I.e. If there is less than arc_c >> arc_no_grow_shift free memory,
+ * when reading a new block into the ARC, we will evict an equal-sized block
+ * from the ARC.
+ *
+ * This must be less than arc_shrink_shift, so that when we shrink the ARC,
+ * we will still not allow it to grow.
+ */
+int			arc_no_grow_shift = 5;
+
+
+/*
+ * minimum lifespan of a prefetch block in clock ticks
+ * (initialized in arc_init())
+ */
+static int		arc_min_prefetch_lifespan;
+
+/*
+ * If this percent of memory is free, don't throttle.
+ */
+int arc_lotsfree_percent = 10;
+
+static int arc_dead;
+
+/*
+ * The arc has filled available memory and has now warmed up.
+ */
+static boolean_t arc_warm;
+
+/*
+ * These tunables are for performance analysis.
+ */
+unsigned long zfs_arc_max = 0;
+unsigned long zfs_arc_min = 0;
+unsigned long zfs_arc_meta_limit = 0;
+unsigned long zfs_arc_meta_min = 0;
+int zfs_arc_grow_retry = 0;
+int zfs_arc_shrink_shift = 0;
+int zfs_arc_p_min_shift = 0;
+int zfs_disable_dup_eviction = 0;
+int zfs_arc_average_blocksize = 8 * 1024; /* 8KB */
+
+/*
+ * These tunables are Linux specific
+ */
+unsigned long zfs_arc_sys_free = 0;
+int zfs_arc_min_prefetch_lifespan = 0;
+int zfs_arc_p_aggressive_disable = 1;
+int zfs_arc_p_dampener_disable = 1;
+int zfs_arc_meta_prune = 10000;
+int zfs_arc_meta_strategy = ARC_STRATEGY_META_BALANCED;
+int zfs_arc_meta_adjust_restarts = 4096;
+int zfs_arc_lotsfree_percent = 10;
+
+/* The 6 states: */
+static arc_state_t ARC_anon;
+static arc_state_t ARC_mru;
+static arc_state_t ARC_mru_ghost;
+static arc_state_t ARC_mfu;
+static arc_state_t ARC_mfu_ghost;
+static arc_state_t ARC_l2c_only;
+
+typedef struct arc_stats {
+	kstat_named_t arcstat_hits;
+	kstat_named_t arcstat_misses;
+	kstat_named_t arcstat_demand_data_hits;
+	kstat_named_t arcstat_demand_data_misses;
+	kstat_named_t arcstat_demand_metadata_hits;
+	kstat_named_t arcstat_demand_metadata_misses;
+	kstat_named_t arcstat_prefetch_data_hits;
+	kstat_named_t arcstat_prefetch_data_misses;
+	kstat_named_t arcstat_prefetch_metadata_hits;
+	kstat_named_t arcstat_prefetch_metadata_misses;
+	kstat_named_t arcstat_mru_hits;
+	kstat_named_t arcstat_mru_ghost_hits;
+	kstat_named_t arcstat_mfu_hits;
+	kstat_named_t arcstat_mfu_ghost_hits;
+	kstat_named_t arcstat_deleted;
+	/*
+	 * Number of buffers that could not be evicted because the hash lock
+	 * was held by another thread.  The lock may not necessarily be held
+	 * by something using the same buffer, since hash locks are shared
+	 * by multiple buffers.
+	 */
+	kstat_named_t arcstat_mutex_miss;
+	/*
+	 * Number of buffers skipped because they have I/O in progress, are
+	 * indrect prefetch buffers that have not lived long enough, or are
+	 * not from the spa we're trying to evict from.
+	 */
+	kstat_named_t arcstat_evict_skip;
+	/*
+	 * Number of times arc_evict_state() was unable to evict enough
+	 * buffers to reach its target amount.
+	 */
+	kstat_named_t arcstat_evict_not_enough;
+	kstat_named_t arcstat_evict_l2_cached;
+	kstat_named_t arcstat_evict_l2_eligible;
+	kstat_named_t arcstat_evict_l2_ineligible;
+	kstat_named_t arcstat_evict_l2_skip;
+	kstat_named_t arcstat_hash_elements;
+	kstat_named_t arcstat_hash_elements_max;
+	kstat_named_t arcstat_hash_collisions;
+	kstat_named_t arcstat_hash_chains;
+	kstat_named_t arcstat_hash_chain_max;
+	kstat_named_t arcstat_p;
+	kstat_named_t arcstat_c;
+	kstat_named_t arcstat_c_min;
+	kstat_named_t arcstat_c_max;
+	kstat_named_t arcstat_size;
+	/*
+	 * Number of bytes consumed by internal ARC structures necessary
+	 * for tracking purposes; these structures are not actually
+	 * backed by ARC buffers. This includes arc_buf_hdr_t structures
+	 * (allocated via arc_buf_hdr_t_full and arc_buf_hdr_t_l2only
+	 * caches), and arc_buf_t structures (allocated via arc_buf_t
+	 * cache).
+	 */
+	kstat_named_t arcstat_hdr_size;
+	/*
+	 * Number of bytes consumed by ARC buffers of type equal to
+	 * ARC_BUFC_DATA. This is generally consumed by buffers backing
+	 * on disk user data (e.g. plain file contents).
+	 */
+	kstat_named_t arcstat_data_size;
+	/*
+	 * Number of bytes consumed by ARC buffers of type equal to
+	 * ARC_BUFC_METADATA. This is generally consumed by buffers
+	 * backing on disk data that is used for internal ZFS
+	 * structures (e.g. ZAP, dnode, indirect blocks, etc).
+	 */
+	kstat_named_t arcstat_metadata_size;
+	/*
+	 * Number of bytes consumed by various buffers and structures
+	 * not actually backed with ARC buffers. This includes bonus
+	 * buffers (allocated directly via zio_buf_* functions),
+	 * dmu_buf_impl_t structures (allocated via dmu_buf_impl_t
+	 * cache), and dnode_t structures (allocated via dnode_t cache).
+	 */
+	kstat_named_t arcstat_other_size;
+	/*
+	 * Total number of bytes consumed by ARC buffers residing in the
+	 * arc_anon state. This includes *all* buffers in the arc_anon
+	 * state; e.g. data, metadata, evictable, and unevictable buffers
+	 * are all included in this value.
+	 */
+	kstat_named_t arcstat_anon_size;
+	/*
+	 * Number of bytes consumed by ARC buffers that meet the
+	 * following criteria: backing buffers of type ARC_BUFC_DATA,
+	 * residing in the arc_anon state, and are eligible for eviction
+	 * (e.g. have no outstanding holds on the buffer).
+	 */
+	kstat_named_t arcstat_anon_evictable_data;
+	/*
+	 * Number of bytes consumed by ARC buffers that meet the
+	 * following criteria: backing buffers of type ARC_BUFC_METADATA,
+	 * residing in the arc_anon state, and are eligible for eviction
+	 * (e.g. have no outstanding holds on the buffer).
+	 */
+	kstat_named_t arcstat_anon_evictable_metadata;
+	/*
+	 * Total number of bytes consumed by ARC buffers residing in the
+	 * arc_mru state. This includes *all* buffers in the arc_mru
+	 * state; e.g. data, metadata, evictable, and unevictable buffers
+	 * are all included in this value.
+	 */
+	kstat_named_t arcstat_mru_size;
+	/*
+	 * Number of bytes consumed by ARC buffers that meet the
+	 * following criteria: backing buffers of type ARC_BUFC_DATA,
+	 * residing in the arc_mru state, and are eligible for eviction
+	 * (e.g. have no outstanding holds on the buffer).
+	 */
+	kstat_named_t arcstat_mru_evictable_data;
+	/*
+	 * Number of bytes consumed by ARC buffers that meet the
+	 * following criteria: backing buffers of type ARC_BUFC_METADATA,
+	 * residing in the arc_mru state, and are eligible for eviction
+	 * (e.g. have no outstanding holds on the buffer).
+	 */
+	kstat_named_t arcstat_mru_evictable_metadata;
+	/*
+	 * Total number of bytes that *would have been* consumed by ARC
+	 * buffers in the arc_mru_ghost state. The key thing to note
+	 * here, is the fact that this size doesn't actually indicate
+	 * RAM consumption. The ghost lists only consist of headers and
+	 * don't actually have ARC buffers linked off of these headers.
+	 * Thus, *if* the headers had associated ARC buffers, these
+	 * buffers *would have* consumed this number of bytes.
+	 */
+	kstat_named_t arcstat_mru_ghost_size;
+	/*
+	 * Number of bytes that *would have been* consumed by ARC
+	 * buffers that are eligible for eviction, of type
+	 * ARC_BUFC_DATA, and linked off the arc_mru_ghost state.
+	 */
+	kstat_named_t arcstat_mru_ghost_evictable_data;
+	/*
+	 * Number of bytes that *would have been* consumed by ARC
+	 * buffers that are eligible for eviction, of type
+	 * ARC_BUFC_METADATA, and linked off the arc_mru_ghost state.
+	 */
+	kstat_named_t arcstat_mru_ghost_evictable_metadata;
+	/*
+	 * Total number of bytes consumed by ARC buffers residing in the
+	 * arc_mfu state. This includes *all* buffers in the arc_mfu
+	 * state; e.g. data, metadata, evictable, and unevictable buffers
+	 * are all included in this value.
+	 */
+	kstat_named_t arcstat_mfu_size;
+	/*
+	 * Number of bytes consumed by ARC buffers that are eligible for
+	 * eviction, of type ARC_BUFC_DATA, and reside in the arc_mfu
+	 * state.
+	 */
+	kstat_named_t arcstat_mfu_evictable_data;
+	/*
+	 * Number of bytes consumed by ARC buffers that are eligible for
+	 * eviction, of type ARC_BUFC_METADATA, and reside in the
+	 * arc_mfu state.
+	 */
+	kstat_named_t arcstat_mfu_evictable_metadata;
+	/*
+	 * Total number of bytes that *would have been* consumed by ARC
+	 * buffers in the arc_mfu_ghost state. See the comment above
+	 * arcstat_mru_ghost_size for more details.
+	 */
+	kstat_named_t arcstat_mfu_ghost_size;
+	/*
+	 * Number of bytes that *would have been* consumed by ARC
+	 * buffers that are eligible for eviction, of type
+	 * ARC_BUFC_DATA, and linked off the arc_mfu_ghost state.
+	 */
+	kstat_named_t arcstat_mfu_ghost_evictable_data;
+	/*
+	 * Number of bytes that *would have been* consumed by ARC
+	 * buffers that are eligible for eviction, of type
+	 * ARC_BUFC_METADATA, and linked off the arc_mru_ghost state.
+	 */
+	kstat_named_t arcstat_mfu_ghost_evictable_metadata;
+	kstat_named_t arcstat_l2_hits;
+	kstat_named_t arcstat_l2_misses;
+	kstat_named_t arcstat_l2_feeds;
+	kstat_named_t arcstat_l2_rw_clash;
+	kstat_named_t arcstat_l2_read_bytes;
+	kstat_named_t arcstat_l2_write_bytes;
+	kstat_named_t arcstat_l2_writes_sent;
+	kstat_named_t arcstat_l2_writes_done;
+	kstat_named_t arcstat_l2_writes_error;
+	kstat_named_t arcstat_l2_writes_lock_retry;
+	kstat_named_t arcstat_l2_evict_lock_retry;
+	kstat_named_t arcstat_l2_evict_reading;
+	kstat_named_t arcstat_l2_evict_l1cached;
+	kstat_named_t arcstat_l2_free_on_write;
+	kstat_named_t arcstat_l2_cdata_free_on_write;
+	kstat_named_t arcstat_l2_abort_lowmem;
+	kstat_named_t arcstat_l2_cksum_bad;
+	kstat_named_t arcstat_l2_io_error;
+	kstat_named_t arcstat_l2_size;
+	kstat_named_t arcstat_l2_asize;
+	kstat_named_t arcstat_l2_hdr_size;
+	kstat_named_t arcstat_l2_compress_successes;
+	kstat_named_t arcstat_l2_compress_zeros;
+	kstat_named_t arcstat_l2_compress_failures;
+	kstat_named_t arcstat_memory_throttle_count;
+	kstat_named_t arcstat_duplicate_buffers;
+	kstat_named_t arcstat_duplicate_buffers_size;
+	kstat_named_t arcstat_duplicate_reads;
+	kstat_named_t arcstat_memory_direct_count;
+	kstat_named_t arcstat_memory_indirect_count;
+	kstat_named_t arcstat_no_grow;
+	kstat_named_t arcstat_tempreserve;
+	kstat_named_t arcstat_loaned_bytes;
+	kstat_named_t arcstat_prune;
+	kstat_named_t arcstat_meta_used;
+	kstat_named_t arcstat_meta_limit;
+	kstat_named_t arcstat_meta_max;
+	kstat_named_t arcstat_meta_min;
+	kstat_named_t arcstat_need_free;
+	kstat_named_t arcstat_sys_free;
+} arc_stats_t;
+
+static arc_stats_t arc_stats = {
+	{ "hits",			KSTAT_DATA_UINT64 },
+	{ "misses",			KSTAT_DATA_UINT64 },
+	{ "demand_data_hits",		KSTAT_DATA_UINT64 },
+	{ "demand_data_misses",		KSTAT_DATA_UINT64 },
+	{ "demand_metadata_hits",	KSTAT_DATA_UINT64 },
+	{ "demand_metadata_misses",	KSTAT_DATA_UINT64 },
+	{ "prefetch_data_hits",		KSTAT_DATA_UINT64 },
+	{ "prefetch_data_misses",	KSTAT_DATA_UINT64 },
+	{ "prefetch_metadata_hits",	KSTAT_DATA_UINT64 },
+	{ "prefetch_metadata_misses",	KSTAT_DATA_UINT64 },
+	{ "mru_hits",			KSTAT_DATA_UINT64 },
+	{ "mru_ghost_hits",		KSTAT_DATA_UINT64 },
+	{ "mfu_hits",			KSTAT_DATA_UINT64 },
+	{ "mfu_ghost_hits",		KSTAT_DATA_UINT64 },
+	{ "deleted",			KSTAT_DATA_UINT64 },
+	{ "mutex_miss",			KSTAT_DATA_UINT64 },
+	{ "evict_skip",			KSTAT_DATA_UINT64 },
+	{ "evict_not_enough",		KSTAT_DATA_UINT64 },
+	{ "evict_l2_cached",		KSTAT_DATA_UINT64 },
+	{ "evict_l2_eligible",		KSTAT_DATA_UINT64 },
+	{ "evict_l2_ineligible",	KSTAT_DATA_UINT64 },
+	{ "evict_l2_skip",		KSTAT_DATA_UINT64 },
+	{ "hash_elements",		KSTAT_DATA_UINT64 },
+	{ "hash_elements_max",		KSTAT_DATA_UINT64 },
+	{ "hash_collisions",		KSTAT_DATA_UINT64 },
+	{ "hash_chains",		KSTAT_DATA_UINT64 },
+	{ "hash_chain_max",		KSTAT_DATA_UINT64 },
+	{ "p",				KSTAT_DATA_UINT64 },
+	{ "c",				KSTAT_DATA_UINT64 },
+	{ "c_min",			KSTAT_DATA_UINT64 },
+	{ "c_max",			KSTAT_DATA_UINT64 },
+	{ "size",			KSTAT_DATA_UINT64 },
+	{ "hdr_size",			KSTAT_DATA_UINT64 },
+	{ "data_size",			KSTAT_DATA_UINT64 },
+	{ "metadata_size",		KSTAT_DATA_UINT64 },
+	{ "other_size",			KSTAT_DATA_UINT64 },
+	{ "anon_size",			KSTAT_DATA_UINT64 },
+	{ "anon_evictable_data",	KSTAT_DATA_UINT64 },
+	{ "anon_evictable_metadata",	KSTAT_DATA_UINT64 },
+	{ "mru_size",			KSTAT_DATA_UINT64 },
+	{ "mru_evictable_data",		KSTAT_DATA_UINT64 },
+	{ "mru_evictable_metadata",	KSTAT_DATA_UINT64 },
+	{ "mru_ghost_size",		KSTAT_DATA_UINT64 },
+	{ "mru_ghost_evictable_data",	KSTAT_DATA_UINT64 },
+	{ "mru_ghost_evictable_metadata", KSTAT_DATA_UINT64 },
+	{ "mfu_size",			KSTAT_DATA_UINT64 },
+	{ "mfu_evictable_data",		KSTAT_DATA_UINT64 },
+	{ "mfu_evictable_metadata",	KSTAT_DATA_UINT64 },
+	{ "mfu_ghost_size",		KSTAT_DATA_UINT64 },
+	{ "mfu_ghost_evictable_data",	KSTAT_DATA_UINT64 },
+	{ "mfu_ghost_evictable_metadata", KSTAT_DATA_UINT64 },
+	{ "l2_hits",			KSTAT_DATA_UINT64 },
+	{ "l2_misses",			KSTAT_DATA_UINT64 },
+	{ "l2_feeds",			KSTAT_DATA_UINT64 },
+	{ "l2_rw_clash",		KSTAT_DATA_UINT64 },
+	{ "l2_read_bytes",		KSTAT_DATA_UINT64 },
+	{ "l2_write_bytes",		KSTAT_DATA_UINT64 },
+	{ "l2_writes_sent",		KSTAT_DATA_UINT64 },
+	{ "l2_writes_done",		KSTAT_DATA_UINT64 },
+	{ "l2_writes_error",		KSTAT_DATA_UINT64 },
+	{ "l2_writes_lock_retry",	KSTAT_DATA_UINT64 },
+	{ "l2_evict_lock_retry",	KSTAT_DATA_UINT64 },
+	{ "l2_evict_reading",		KSTAT_DATA_UINT64 },
+	{ "l2_evict_l1cached",		KSTAT_DATA_UINT64 },
+	{ "l2_free_on_write",		KSTAT_DATA_UINT64 },
+	{ "l2_cdata_free_on_write",	KSTAT_DATA_UINT64 },
+	{ "l2_abort_lowmem",		KSTAT_DATA_UINT64 },
+	{ "l2_cksum_bad",		KSTAT_DATA_UINT64 },
+	{ "l2_io_error",		KSTAT_DATA_UINT64 },
+	{ "l2_size",			KSTAT_DATA_UINT64 },
+	{ "l2_asize",			KSTAT_DATA_UINT64 },
+	{ "l2_hdr_size",		KSTAT_DATA_UINT64 },
+	{ "l2_compress_successes",	KSTAT_DATA_UINT64 },
+	{ "l2_compress_zeros",		KSTAT_DATA_UINT64 },
+	{ "l2_compress_failures",	KSTAT_DATA_UINT64 },
+	{ "memory_throttle_count",	KSTAT_DATA_UINT64 },
+	{ "duplicate_buffers",		KSTAT_DATA_UINT64 },
+	{ "duplicate_buffers_size",	KSTAT_DATA_UINT64 },
+	{ "duplicate_reads",		KSTAT_DATA_UINT64 },
+	{ "memory_direct_count",	KSTAT_DATA_UINT64 },
+	{ "memory_indirect_count",	KSTAT_DATA_UINT64 },
+	{ "arc_no_grow",		KSTAT_DATA_UINT64 },
+	{ "arc_tempreserve",		KSTAT_DATA_UINT64 },
+	{ "arc_loaned_bytes",		KSTAT_DATA_UINT64 },
+	{ "arc_prune",			KSTAT_DATA_UINT64 },
+	{ "arc_meta_used",		KSTAT_DATA_UINT64 },
+	{ "arc_meta_limit",		KSTAT_DATA_UINT64 },
+	{ "arc_meta_max",		KSTAT_DATA_UINT64 },
+	{ "arc_meta_min",		KSTAT_DATA_UINT64 },
+	{ "arc_need_free",		KSTAT_DATA_UINT64 },
+	{ "arc_sys_free",		KSTAT_DATA_UINT64 }
+};
+
+#define	ARCSTAT(stat)	(arc_stats.stat.value.ui64)
+
+#define	ARCSTAT_INCR(stat, val) \
+	atomic_add_64(&arc_stats.stat.value.ui64, (val))
+
+#define	ARCSTAT_BUMP(stat)	ARCSTAT_INCR(stat, 1)
+#define	ARCSTAT_BUMPDOWN(stat)	ARCSTAT_INCR(stat, -1)
+
+#define	ARCSTAT_MAX(stat, val) {					\
+	uint64_t m;							\
+	while ((val) > (m = arc_stats.stat.value.ui64) &&		\
+	    (m != atomic_cas_64(&arc_stats.stat.value.ui64, m, (val))))	\
+		continue;						\
+}
+
+#define	ARCSTAT_MAXSTAT(stat) \
+	ARCSTAT_MAX(stat##_max, arc_stats.stat.value.ui64)
+
+/*
+ * We define a macro to allow ARC hits/misses to be easily broken down by
+ * two separate conditions, giving a total of four different subtypes for
+ * each of hits and misses (so eight statistics total).
+ */
+#define	ARCSTAT_CONDSTAT(cond1, stat1, notstat1, cond2, stat2, notstat2, stat) \
+	if (cond1) {							\
+		if (cond2) {						\
+			ARCSTAT_BUMP(arcstat_##stat1##_##stat2##_##stat); \
+		} else {						\
+			ARCSTAT_BUMP(arcstat_##stat1##_##notstat2##_##stat); \
+		}							\
+	} else {							\
+		if (cond2) {						\
+			ARCSTAT_BUMP(arcstat_##notstat1##_##stat2##_##stat); \
+		} else {						\
+			ARCSTAT_BUMP(arcstat_##notstat1##_##notstat2##_##stat);\
+		}							\
+	}
+
+kstat_t			*arc_ksp;
+static arc_state_t	*arc_anon;
+static arc_state_t	*arc_mru;
+static arc_state_t	*arc_mru_ghost;
+static arc_state_t	*arc_mfu;
+static arc_state_t	*arc_mfu_ghost;
+static arc_state_t	*arc_l2c_only;
+
+/*
+ * There are several ARC variables that are critical to export as kstats --
+ * but we don't want to have to grovel around in the kstat whenever we wish to
+ * manipulate them.  For these variables, we therefore define them to be in
+ * terms of the statistic variable.  This assures that we are not introducing
+ * the possibility of inconsistency by having shadow copies of the variables,
+ * while still allowing the code to be readable.
+ */
+#define	arc_size	ARCSTAT(arcstat_size)	/* actual total arc size */
+#define	arc_p		ARCSTAT(arcstat_p)	/* target size of MRU */
+#define	arc_c		ARCSTAT(arcstat_c)	/* target size of cache */
+#define	arc_c_min	ARCSTAT(arcstat_c_min)	/* min target cache size */
+#define	arc_c_max	ARCSTAT(arcstat_c_max)	/* max target cache size */
+#define	arc_no_grow	ARCSTAT(arcstat_no_grow)
+#define	arc_tempreserve	ARCSTAT(arcstat_tempreserve)
+#define	arc_loaned_bytes	ARCSTAT(arcstat_loaned_bytes)
+#define	arc_meta_limit	ARCSTAT(arcstat_meta_limit) /* max size for metadata */
+#define	arc_meta_min	ARCSTAT(arcstat_meta_min) /* min size for metadata */
+#define	arc_meta_used	ARCSTAT(arcstat_meta_used) /* size of metadata */
+#define	arc_meta_max	ARCSTAT(arcstat_meta_max) /* max size of metadata */
+#define	arc_need_free	ARCSTAT(arcstat_need_free) /* bytes to be freed */
+#define	arc_sys_free	ARCSTAT(arcstat_sys_free) /* target system free bytes */
+
+#define	L2ARC_IS_VALID_COMPRESS(_c_) \
+	((_c_) == ZIO_COMPRESS_LZ4 || (_c_) == ZIO_COMPRESS_EMPTY)
+
+static list_t arc_prune_list;
+static kmutex_t arc_prune_mtx;
+static taskq_t *arc_prune_taskq;
+static arc_buf_t *arc_eviction_list;
+static arc_buf_hdr_t arc_eviction_hdr;
+
+#define	GHOST_STATE(state)	\
+	((state) == arc_mru_ghost || (state) == arc_mfu_ghost ||	\
+	(state) == arc_l2c_only)
+
+#define	HDR_IN_HASH_TABLE(hdr)	((hdr)->b_flags & ARC_FLAG_IN_HASH_TABLE)
+#define	HDR_IO_IN_PROGRESS(hdr)	((hdr)->b_flags & ARC_FLAG_IO_IN_PROGRESS)
+#define	HDR_IO_ERROR(hdr)	((hdr)->b_flags & ARC_FLAG_IO_ERROR)
+#define	HDR_PREFETCH(hdr)	((hdr)->b_flags & ARC_FLAG_PREFETCH)
+#define	HDR_FREED_IN_READ(hdr)	((hdr)->b_flags & ARC_FLAG_FREED_IN_READ)
+#define	HDR_BUF_AVAILABLE(hdr)	((hdr)->b_flags & ARC_FLAG_BUF_AVAILABLE)
+
+#define	HDR_L2CACHE(hdr)	((hdr)->b_flags & ARC_FLAG_L2CACHE)
+#define	HDR_L2COMPRESS(hdr)	((hdr)->b_flags & ARC_FLAG_L2COMPRESS)
+#define	HDR_L2_READING(hdr)	\
+	    (((hdr)->b_flags & ARC_FLAG_IO_IN_PROGRESS) &&	\
+	    ((hdr)->b_flags & ARC_FLAG_HAS_L2HDR))
+#define	HDR_L2_WRITING(hdr)	((hdr)->b_flags & ARC_FLAG_L2_WRITING)
+#define	HDR_L2_EVICTED(hdr)	((hdr)->b_flags & ARC_FLAG_L2_EVICTED)
+#define	HDR_L2_WRITE_HEAD(hdr)	((hdr)->b_flags & ARC_FLAG_L2_WRITE_HEAD)
+
+#define	HDR_ISTYPE_METADATA(hdr)	\
+	    ((hdr)->b_flags & ARC_FLAG_BUFC_METADATA)
+#define	HDR_ISTYPE_DATA(hdr)	(!HDR_ISTYPE_METADATA(hdr))
+
+#define	HDR_HAS_L1HDR(hdr)	((hdr)->b_flags & ARC_FLAG_HAS_L1HDR)
+#define	HDR_HAS_L2HDR(hdr)	((hdr)->b_flags & ARC_FLAG_HAS_L2HDR)
+
+/*
+ * Other sizes
+ */
+
+#define	HDR_FULL_SIZE ((int64_t)sizeof (arc_buf_hdr_t))
+#define	HDR_L2ONLY_SIZE ((int64_t)offsetof(arc_buf_hdr_t, b_l1hdr))
+
+/*
+ * Hash table routines
+ */
+
+#define	HT_LOCK_ALIGN	64
+#define	HT_LOCK_PAD	(P2NPHASE(sizeof (kmutex_t), (HT_LOCK_ALIGN)))
+
+struct ht_lock {
+	kmutex_t	ht_lock;
+#ifdef _KERNEL
+	unsigned char	pad[HT_LOCK_PAD];
+#endif
+};
+
+#define	BUF_LOCKS 8192
+typedef struct buf_hash_table {
+	uint64_t ht_mask;
+	arc_buf_hdr_t **ht_table;
+	struct ht_lock ht_locks[BUF_LOCKS];
+} buf_hash_table_t;
+
+static buf_hash_table_t buf_hash_table;
+
+#define	BUF_HASH_INDEX(spa, dva, birth) \
+	(buf_hash(spa, dva, birth) & buf_hash_table.ht_mask)
+#define	BUF_HASH_LOCK_NTRY(idx) (buf_hash_table.ht_locks[idx & (BUF_LOCKS-1)])
+#define	BUF_HASH_LOCK(idx)	(&(BUF_HASH_LOCK_NTRY(idx).ht_lock))
+#define	HDR_LOCK(hdr) \
+	(BUF_HASH_LOCK(BUF_HASH_INDEX(hdr->b_spa, &hdr->b_dva, hdr->b_birth)))
+
+uint64_t zfs_crc64_table[256];
+
+/*
+ * Level 2 ARC
+ */
+
+#define	L2ARC_WRITE_SIZE	(8 * 1024 * 1024)	/* initial write max */
+#define	L2ARC_HEADROOM		2			/* num of writes */
+/*
+ * If we discover during ARC scan any buffers to be compressed, we boost
+ * our headroom for the next scanning cycle by this percentage multiple.
+ */
+#define	L2ARC_HEADROOM_BOOST	200
+#define	L2ARC_FEED_SECS		1		/* caching interval secs */
+#define	L2ARC_FEED_MIN_MS	200		/* min caching interval ms */
+
+/*
+ * Used to distinguish headers that are being process by
+ * l2arc_write_buffers(), but have yet to be assigned to a l2arc disk
+ * address. This can happen when the header is added to the l2arc's list
+ * of buffers to write in the first stage of l2arc_write_buffers(), but
+ * has not yet been written out which happens in the second stage of
+ * l2arc_write_buffers().
+ */
+#define	L2ARC_ADDR_UNSET	((uint64_t)(-1))
+
+#define	l2arc_writes_sent	ARCSTAT(arcstat_l2_writes_sent)
+#define	l2arc_writes_done	ARCSTAT(arcstat_l2_writes_done)
+
+/* L2ARC Performance Tunables */
+unsigned long l2arc_write_max = L2ARC_WRITE_SIZE;	/* def max write size */
+unsigned long l2arc_write_boost = L2ARC_WRITE_SIZE;	/* extra warmup write */
+unsigned long l2arc_headroom = L2ARC_HEADROOM;		/* # of dev writes */
+unsigned long l2arc_headroom_boost = L2ARC_HEADROOM_BOOST;
+unsigned long l2arc_feed_secs = L2ARC_FEED_SECS;	/* interval seconds */
+unsigned long l2arc_feed_min_ms = L2ARC_FEED_MIN_MS;	/* min interval msecs */
+int l2arc_noprefetch = B_TRUE;			/* don't cache prefetch bufs */
+int l2arc_nocompress = B_FALSE;			/* don't compress bufs */
+int l2arc_feed_again = B_TRUE;			/* turbo warmup */
+int l2arc_norw = B_FALSE;			/* no reads during writes */
+
+/*
+ * L2ARC Internals
+ */
+static list_t L2ARC_dev_list;			/* device list */
+static list_t *l2arc_dev_list;			/* device list pointer */
+static kmutex_t l2arc_dev_mtx;			/* device list mutex */
+static l2arc_dev_t *l2arc_dev_last;		/* last device used */
+static list_t L2ARC_free_on_write;		/* free after write buf list */
+static list_t *l2arc_free_on_write;		/* free after write list ptr */
+static kmutex_t l2arc_free_on_write_mtx;	/* mutex for list */
+static uint64_t l2arc_ndev;			/* number of devices */
+
+typedef struct l2arc_read_callback {
+	arc_buf_t		*l2rcb_buf;		/* read buffer */
+	spa_t			*l2rcb_spa;		/* spa */
+	blkptr_t		l2rcb_bp;		/* original blkptr */
+	zbookmark_phys_t	l2rcb_zb;		/* original bookmark */
+	int			l2rcb_flags;		/* original flags */
+	enum zio_compress	l2rcb_compress;		/* applied compress */
+} l2arc_read_callback_t;
+
+typedef struct l2arc_data_free {
+	/* protected by l2arc_free_on_write_mtx */
+	void		*l2df_data;
+	size_t		l2df_size;
+	void		(*l2df_func)(void *, size_t);
+	list_node_t	l2df_list_node;
+} l2arc_data_free_t;
+
+static kmutex_t l2arc_feed_thr_lock;
+static kcondvar_t l2arc_feed_thr_cv;
+static uint8_t l2arc_thread_exit;
+
+static void arc_get_data_buf(arc_buf_t *);
+static void arc_access(arc_buf_hdr_t *, kmutex_t *);
+static boolean_t arc_is_overflowing(void);
+static void arc_buf_watch(arc_buf_t *);
+static void arc_tuning_update(void);
+
+static arc_buf_contents_t arc_buf_type(arc_buf_hdr_t *);
+static uint32_t arc_bufc_to_flags(arc_buf_contents_t);
+
+static boolean_t l2arc_write_eligible(uint64_t, arc_buf_hdr_t *);
+static void l2arc_read_done(zio_t *);
+
+static boolean_t l2arc_compress_buf(arc_buf_hdr_t *);
+static void l2arc_decompress_zio(zio_t *, arc_buf_hdr_t *, enum zio_compress);
+static void l2arc_release_cdata_buf(arc_buf_hdr_t *);
+
+static uint64_t
+buf_hash(uint64_t spa, const dva_t *dva, uint64_t birth)
+{
+	uint8_t *vdva = (uint8_t *)dva;
+	uint64_t crc = -1ULL;
+	int i;
+
+	ASSERT(zfs_crc64_table[128] == ZFS_CRC64_POLY);
+
+	for (i = 0; i < sizeof (dva_t); i++)
+		crc = (crc >> 8) ^ zfs_crc64_table[(crc ^ vdva[i]) & 0xFF];
+
+	crc ^= (spa>>8) ^ birth;
+
+	return (crc);
+}
+
+#define	BUF_EMPTY(buf)						\
+	((buf)->b_dva.dva_word[0] == 0 &&			\
+	(buf)->b_dva.dva_word[1] == 0)
+
+#define	BUF_EQUAL(spa, dva, birth, buf)				\
+	((buf)->b_dva.dva_word[0] == (dva)->dva_word[0]) &&	\
+	((buf)->b_dva.dva_word[1] == (dva)->dva_word[1]) &&	\
+	((buf)->b_birth == birth) && ((buf)->b_spa == spa)
+
+static void
+buf_discard_identity(arc_buf_hdr_t *hdr)
+{
+	hdr->b_dva.dva_word[0] = 0;
+	hdr->b_dva.dva_word[1] = 0;
+	hdr->b_birth = 0;
+}
+
+static arc_buf_hdr_t *
+buf_hash_find(uint64_t spa, const blkptr_t *bp, kmutex_t **lockp)
+{
+	const dva_t *dva = BP_IDENTITY(bp);
+	uint64_t birth = BP_PHYSICAL_BIRTH(bp);
+	uint64_t idx = BUF_HASH_INDEX(spa, dva, birth);
+	kmutex_t *hash_lock = BUF_HASH_LOCK(idx);
+	arc_buf_hdr_t *hdr;
+
+	mutex_enter(hash_lock);
+	for (hdr = buf_hash_table.ht_table[idx]; hdr != NULL;
+	    hdr = hdr->b_hash_next) {
+		if (BUF_EQUAL(spa, dva, birth, hdr)) {
+			*lockp = hash_lock;
+			return (hdr);
+		}
+	}
+	mutex_exit(hash_lock);
+	*lockp = NULL;
+	return (NULL);
+}
+
+/*
+ * Insert an entry into the hash table.  If there is already an element
+ * equal to elem in the hash table, then the already existing element
+ * will be returned and the new element will not be inserted.
+ * Otherwise returns NULL.
+ * If lockp == NULL, the caller is assumed to already hold the hash lock.
+ */
+static arc_buf_hdr_t *
+buf_hash_insert(arc_buf_hdr_t *hdr, kmutex_t **lockp)
+{
+	uint64_t idx = BUF_HASH_INDEX(hdr->b_spa, &hdr->b_dva, hdr->b_birth);
+	kmutex_t *hash_lock = BUF_HASH_LOCK(idx);
+	arc_buf_hdr_t *fhdr;
+	uint32_t i;
+
+	ASSERT(!DVA_IS_EMPTY(&hdr->b_dva));
+	ASSERT(hdr->b_birth != 0);
+	ASSERT(!HDR_IN_HASH_TABLE(hdr));
+
+	if (lockp != NULL) {
+		*lockp = hash_lock;
+		mutex_enter(hash_lock);
+	} else {
+		ASSERT(MUTEX_HELD(hash_lock));
+	}
+
+	for (fhdr = buf_hash_table.ht_table[idx], i = 0; fhdr != NULL;
+	    fhdr = fhdr->b_hash_next, i++) {
+		if (BUF_EQUAL(hdr->b_spa, &hdr->b_dva, hdr->b_birth, fhdr))
+			return (fhdr);
+	}
+
+	hdr->b_hash_next = buf_hash_table.ht_table[idx];
+	buf_hash_table.ht_table[idx] = hdr;
+	hdr->b_flags |= ARC_FLAG_IN_HASH_TABLE;
+
+	/* collect some hash table performance data */
+	if (i > 0) {
+		ARCSTAT_BUMP(arcstat_hash_collisions);
+		if (i == 1)
+			ARCSTAT_BUMP(arcstat_hash_chains);
+
+		ARCSTAT_MAX(arcstat_hash_chain_max, i);
+	}
+
+	ARCSTAT_BUMP(arcstat_hash_elements);
+	ARCSTAT_MAXSTAT(arcstat_hash_elements);
+
+	return (NULL);
+}
+
+static void
+buf_hash_remove(arc_buf_hdr_t *hdr)
+{
+	arc_buf_hdr_t *fhdr, **hdrp;
+	uint64_t idx = BUF_HASH_INDEX(hdr->b_spa, &hdr->b_dva, hdr->b_birth);
+
+	ASSERT(MUTEX_HELD(BUF_HASH_LOCK(idx)));
+	ASSERT(HDR_IN_HASH_TABLE(hdr));
+
+	hdrp = &buf_hash_table.ht_table[idx];
+	while ((fhdr = *hdrp) != hdr) {
+		ASSERT(fhdr != NULL);
+		hdrp = &fhdr->b_hash_next;
+	}
+	*hdrp = hdr->b_hash_next;
+	hdr->b_hash_next = NULL;
+	hdr->b_flags &= ~ARC_FLAG_IN_HASH_TABLE;
+
+	/* collect some hash table performance data */
+	ARCSTAT_BUMPDOWN(arcstat_hash_elements);
+
+	if (buf_hash_table.ht_table[idx] &&
+	    buf_hash_table.ht_table[idx]->b_hash_next == NULL)
+		ARCSTAT_BUMPDOWN(arcstat_hash_chains);
+}
+
+/*
+ * Global data structures and functions for the buf kmem cache.
+ */
+static kmem_cache_t *hdr_full_cache;
+static kmem_cache_t *hdr_l2only_cache;
+static kmem_cache_t *buf_cache;
+
+static void
+buf_fini(void)
+{
+	int i;
+
+#if defined(_KERNEL) && defined(HAVE_SPL)
+	/*
+	 * Large allocations which do not require contiguous pages
+	 * should be using vmem_free() in the linux kernel\
+	 */
+	vmem_free(buf_hash_table.ht_table,
+	    (buf_hash_table.ht_mask + 1) * sizeof (void *));
+#else
+	kmem_free(buf_hash_table.ht_table,
+	    (buf_hash_table.ht_mask + 1) * sizeof (void *));
+#endif
+	for (i = 0; i < BUF_LOCKS; i++)
+		mutex_destroy(&buf_hash_table.ht_locks[i].ht_lock);
+	kmem_cache_destroy(hdr_full_cache);
+	kmem_cache_destroy(hdr_l2only_cache);
+	kmem_cache_destroy(buf_cache);
+}
+
+/*
+ * Constructor callback - called when the cache is empty
+ * and a new buf is requested.
+ */
+/* ARGSUSED */
+static int
+hdr_full_cons(void *vbuf, void *unused, int kmflag)
+{
+	arc_buf_hdr_t *hdr = vbuf;
+
+	bzero(hdr, HDR_FULL_SIZE);
+	cv_init(&hdr->b_l1hdr.b_cv, NULL, CV_DEFAULT, NULL);
+	refcount_create(&hdr->b_l1hdr.b_refcnt);
+	mutex_init(&hdr->b_l1hdr.b_freeze_lock, NULL, MUTEX_DEFAULT, NULL);
+	list_link_init(&hdr->b_l1hdr.b_arc_node);
+	list_link_init(&hdr->b_l2hdr.b_l2node);
+	multilist_link_init(&hdr->b_l1hdr.b_arc_node);
+	arc_space_consume(HDR_FULL_SIZE, ARC_SPACE_HDRS);
+
+	return (0);
+}
+
+/* ARGSUSED */
+static int
+hdr_l2only_cons(void *vbuf, void *unused, int kmflag)
+{
+	arc_buf_hdr_t *hdr = vbuf;
+
+	bzero(hdr, HDR_L2ONLY_SIZE);
+	arc_space_consume(HDR_L2ONLY_SIZE, ARC_SPACE_L2HDRS);
+
+	return (0);
+}
+
+/* ARGSUSED */
+static int
+buf_cons(void *vbuf, void *unused, int kmflag)
+{
+	arc_buf_t *buf = vbuf;
+
+	bzero(buf, sizeof (arc_buf_t));
+	mutex_init(&buf->b_evict_lock, NULL, MUTEX_DEFAULT, NULL);
+	arc_space_consume(sizeof (arc_buf_t), ARC_SPACE_HDRS);
+
+	return (0);
+}
+
+/*
+ * Destructor callback - called when a cached buf is
+ * no longer required.
+ */
+/* ARGSUSED */
+static void
+hdr_full_dest(void *vbuf, void *unused)
+{
+	arc_buf_hdr_t *hdr = vbuf;
+
+	ASSERT(BUF_EMPTY(hdr));
+	cv_destroy(&hdr->b_l1hdr.b_cv);
+	refcount_destroy(&hdr->b_l1hdr.b_refcnt);
+	mutex_destroy(&hdr->b_l1hdr.b_freeze_lock);
+	ASSERT(!multilist_link_active(&hdr->b_l1hdr.b_arc_node));
+	arc_space_return(HDR_FULL_SIZE, ARC_SPACE_HDRS);
+}
+
+/* ARGSUSED */
+static void
+hdr_l2only_dest(void *vbuf, void *unused)
+{
+	ASSERTV(arc_buf_hdr_t *hdr = vbuf);
+
+	ASSERT(BUF_EMPTY(hdr));
+	arc_space_return(HDR_L2ONLY_SIZE, ARC_SPACE_L2HDRS);
+}
+
+/* ARGSUSED */
+static void
+buf_dest(void *vbuf, void *unused)
+{
+	arc_buf_t *buf = vbuf;
+
+	mutex_destroy(&buf->b_evict_lock);
+	arc_space_return(sizeof (arc_buf_t), ARC_SPACE_HDRS);
+}
+
+/*
+ * Reclaim callback -- invoked when memory is low.
+ */
+/* ARGSUSED */
+static void
+hdr_recl(void *unused)
+{
+	dprintf("hdr_recl called\n");
+	/*
+	 * umem calls the reclaim func when we destroy the buf cache,
+	 * which is after we do arc_fini().
+	 */
+	if (!arc_dead)
+		cv_signal(&arc_reclaim_thread_cv);
+}
+
+static void
+buf_init(void)
+{
+	uint64_t *ct;
+	uint64_t hsize = 1ULL << 12;
+	int i, j;
+
+	/*
+	 * The hash table is big enough to fill all of physical memory
+	 * with an average block size of zfs_arc_average_blocksize (default 8K).
+	 * By default, the table will take up
+	 * totalmem * sizeof(void*) / 8K (1MB per GB with 8-byte pointers).
+	 */
+	while (hsize * zfs_arc_average_blocksize < physmem * PAGESIZE)
+		hsize <<= 1;
+retry:
+	buf_hash_table.ht_mask = hsize - 1;
+#if defined(_KERNEL) && defined(HAVE_SPL)
+	/*
+	 * Large allocations which do not require contiguous pages
+	 * should be using vmem_alloc() in the linux kernel
+	 */
+	buf_hash_table.ht_table =
+	    vmem_zalloc(hsize * sizeof (void*), KM_SLEEP);
+#else
+	buf_hash_table.ht_table =
+	    kmem_zalloc(hsize * sizeof (void*), KM_NOSLEEP);
+#endif
+	if (buf_hash_table.ht_table == NULL) {
+		ASSERT(hsize > (1ULL << 8));
+		hsize >>= 1;
+		goto retry;
+	}
+
+	hdr_full_cache = kmem_cache_create("arc_buf_hdr_t_full", HDR_FULL_SIZE,
+	    0, hdr_full_cons, hdr_full_dest, hdr_recl, NULL, NULL, 0);
+	hdr_l2only_cache = kmem_cache_create("arc_buf_hdr_t_l2only",
+	    HDR_L2ONLY_SIZE, 0, hdr_l2only_cons, hdr_l2only_dest, hdr_recl,
+	    NULL, NULL, 0);
+	buf_cache = kmem_cache_create("arc_buf_t", sizeof (arc_buf_t),
+	    0, buf_cons, buf_dest, NULL, NULL, NULL, 0);
+
+	for (i = 0; i < 256; i++)
+		for (ct = zfs_crc64_table + i, *ct = i, j = 8; j > 0; j--)
+			*ct = (*ct >> 1) ^ (-(*ct & 1) & ZFS_CRC64_POLY);
+
+	for (i = 0; i < BUF_LOCKS; i++) {
+		mutex_init(&buf_hash_table.ht_locks[i].ht_lock,
+		    NULL, MUTEX_DEFAULT, NULL);
+	}
+}
+
+/*
+ * Transition between the two allocation states for the arc_buf_hdr struct.
+ * The arc_buf_hdr struct can be allocated with (hdr_full_cache) or without
+ * (hdr_l2only_cache) the fields necessary for the L1 cache - the smaller
+ * version is used when a cache buffer is only in the L2ARC in order to reduce
+ * memory usage.
+ */
+static arc_buf_hdr_t *
+arc_hdr_realloc(arc_buf_hdr_t *hdr, kmem_cache_t *old, kmem_cache_t *new)
+{
+	arc_buf_hdr_t *nhdr;
+	l2arc_dev_t *dev;
+
+	ASSERT(HDR_HAS_L2HDR(hdr));
+	ASSERT((old == hdr_full_cache && new == hdr_l2only_cache) ||
+	    (old == hdr_l2only_cache && new == hdr_full_cache));
+
+	dev = hdr->b_l2hdr.b_dev;
+	nhdr = kmem_cache_alloc(new, KM_PUSHPAGE);
+
+	ASSERT(MUTEX_HELD(HDR_LOCK(hdr)));
+	buf_hash_remove(hdr);
+
+	bcopy(hdr, nhdr, HDR_L2ONLY_SIZE);
+
+	if (new == hdr_full_cache) {
+		nhdr->b_flags |= ARC_FLAG_HAS_L1HDR;
+		/*
+		 * arc_access and arc_change_state need to be aware that a
+		 * header has just come out of L2ARC, so we set its state to
+		 * l2c_only even though it's about to change.
+		 */
+		nhdr->b_l1hdr.b_state = arc_l2c_only;
+
+		/* Verify previous threads set to NULL before freeing */
+		ASSERT3P(nhdr->b_l1hdr.b_tmp_cdata, ==, NULL);
+	} else {
+		ASSERT(hdr->b_l1hdr.b_buf == NULL);
+		ASSERT0(hdr->b_l1hdr.b_datacnt);
+
+		/*
+		 * If we've reached here, We must have been called from
+		 * arc_evict_hdr(), as such we should have already been
+		 * removed from any ghost list we were previously on
+		 * (which protects us from racing with arc_evict_state),
+		 * thus no locking is needed during this check.
+		 */
+		ASSERT(!multilist_link_active(&hdr->b_l1hdr.b_arc_node));
+
+		/*
+		 * A buffer must not be moved into the arc_l2c_only
+		 * state if it's not finished being written out to the
+		 * l2arc device. Otherwise, the b_l1hdr.b_tmp_cdata field
+		 * might try to be accessed, even though it was removed.
+		 */
+		VERIFY(!HDR_L2_WRITING(hdr));
+		VERIFY3P(hdr->b_l1hdr.b_tmp_cdata, ==, NULL);
+
+		nhdr->b_flags &= ~ARC_FLAG_HAS_L1HDR;
+	}
+	/*
+	 * The header has been reallocated so we need to re-insert it into any
+	 * lists it was on.
+	 */
+	(void) buf_hash_insert(nhdr, NULL);
+
+	ASSERT(list_link_active(&hdr->b_l2hdr.b_l2node));
+
+	mutex_enter(&dev->l2ad_mtx);
+
+	/*
+	 * We must place the realloc'ed header back into the list at
+	 * the same spot. Otherwise, if it's placed earlier in the list,
+	 * l2arc_write_buffers() could find it during the function's
+	 * write phase, and try to write it out to the l2arc.
+	 */
+	list_insert_after(&dev->l2ad_buflist, hdr, nhdr);
+	list_remove(&dev->l2ad_buflist, hdr);
+
+	mutex_exit(&dev->l2ad_mtx);
+
+	/*
+	 * Since we're using the pointer address as the tag when
+	 * incrementing and decrementing the l2ad_alloc refcount, we
+	 * must remove the old pointer (that we're about to destroy) and
+	 * add the new pointer to the refcount. Otherwise we'd remove
+	 * the wrong pointer address when calling arc_hdr_destroy() later.
+	 */
+
+	(void) refcount_remove_many(&dev->l2ad_alloc,
+	    hdr->b_l2hdr.b_asize, hdr);
+
+	(void) refcount_add_many(&dev->l2ad_alloc,
+	    nhdr->b_l2hdr.b_asize, nhdr);
+
+	buf_discard_identity(hdr);
+	hdr->b_freeze_cksum = NULL;
+	kmem_cache_free(old, hdr);
+
+	return (nhdr);
+}
+
+
+#define	ARC_MINTIME	(hz>>4) /* 62 ms */
+
+static void
+arc_cksum_verify(arc_buf_t *buf)
+{
+	zio_cksum_t zc;
+
+	if (!(zfs_flags & ZFS_DEBUG_MODIFY))
+		return;
+
+	mutex_enter(&buf->b_hdr->b_l1hdr.b_freeze_lock);
+	if (buf->b_hdr->b_freeze_cksum == NULL || HDR_IO_ERROR(buf->b_hdr)) {
+		mutex_exit(&buf->b_hdr->b_l1hdr.b_freeze_lock);
+		return;
+	}
+	fletcher_2_native(buf->b_data, buf->b_hdr->b_size, &zc);
+	if (!ZIO_CHECKSUM_EQUAL(*buf->b_hdr->b_freeze_cksum, zc))
+		panic("buffer modified while frozen!");
+	mutex_exit(&buf->b_hdr->b_l1hdr.b_freeze_lock);
+}
+
+static int
+arc_cksum_equal(arc_buf_t *buf)
+{
+	zio_cksum_t zc;
+	int equal;
+
+	mutex_enter(&buf->b_hdr->b_l1hdr.b_freeze_lock);
+	fletcher_2_native(buf->b_data, buf->b_hdr->b_size, &zc);
+	equal = ZIO_CHECKSUM_EQUAL(*buf->b_hdr->b_freeze_cksum, zc);
+	mutex_exit(&buf->b_hdr->b_l1hdr.b_freeze_lock);
+
+	return (equal);
+}
+
+static void
+arc_cksum_compute(arc_buf_t *buf, boolean_t force)
+{
+	if (!force && !(zfs_flags & ZFS_DEBUG_MODIFY))
+		return;
+
+	mutex_enter(&buf->b_hdr->b_l1hdr.b_freeze_lock);
+	if (buf->b_hdr->b_freeze_cksum != NULL) {
+		mutex_exit(&buf->b_hdr->b_l1hdr.b_freeze_lock);
+		return;
+	}
+	buf->b_hdr->b_freeze_cksum = kmem_alloc(sizeof (zio_cksum_t), KM_SLEEP);
+	fletcher_2_native(buf->b_data, buf->b_hdr->b_size,
+	    buf->b_hdr->b_freeze_cksum);
+	mutex_exit(&buf->b_hdr->b_l1hdr.b_freeze_lock);
+	arc_buf_watch(buf);
+}
+
+#ifndef _KERNEL
+void
+arc_buf_sigsegv(int sig, siginfo_t *si, void *unused)
+{
+	panic("Got SIGSEGV at address: 0x%lx\n", (long) si->si_addr);
+}
+#endif
+
+/* ARGSUSED */
+static void
+arc_buf_unwatch(arc_buf_t *buf)
+{
+#ifndef _KERNEL
+	if (arc_watch) {
+		ASSERT0(mprotect(buf->b_data, buf->b_hdr->b_size,
+		    PROT_READ | PROT_WRITE));
+	}
+#endif
+}
+
+/* ARGSUSED */
+static void
+arc_buf_watch(arc_buf_t *buf)
+{
+#ifndef _KERNEL
+	if (arc_watch)
+		ASSERT0(mprotect(buf->b_data, buf->b_hdr->b_size, PROT_READ));
+#endif
+}
+
+static arc_buf_contents_t
+arc_buf_type(arc_buf_hdr_t *hdr)
+{
+	if (HDR_ISTYPE_METADATA(hdr)) {
+		return (ARC_BUFC_METADATA);
+	} else {
+		return (ARC_BUFC_DATA);
+	}
+}
+
+static uint32_t
+arc_bufc_to_flags(arc_buf_contents_t type)
+{
+	switch (type) {
+	case ARC_BUFC_DATA:
+		/* metadata field is 0 if buffer contains normal data */
+		return (0);
+	case ARC_BUFC_METADATA:
+		return (ARC_FLAG_BUFC_METADATA);
+	default:
+		break;
+	}
+	panic("undefined ARC buffer type!");
+	return ((uint32_t)-1);
+}
+
+void
+arc_buf_thaw(arc_buf_t *buf)
+{
+	if (zfs_flags & ZFS_DEBUG_MODIFY) {
+		if (buf->b_hdr->b_l1hdr.b_state != arc_anon)
+			panic("modifying non-anon buffer!");
+		if (HDR_IO_IN_PROGRESS(buf->b_hdr))
+			panic("modifying buffer while i/o in progress!");
+		arc_cksum_verify(buf);
+	}
+
+	mutex_enter(&buf->b_hdr->b_l1hdr.b_freeze_lock);
+	if (buf->b_hdr->b_freeze_cksum != NULL) {
+		kmem_free(buf->b_hdr->b_freeze_cksum, sizeof (zio_cksum_t));
+		buf->b_hdr->b_freeze_cksum = NULL;
+	}
+
+	mutex_exit(&buf->b_hdr->b_l1hdr.b_freeze_lock);
+
+	arc_buf_unwatch(buf);
+}
+
+void
+arc_buf_freeze(arc_buf_t *buf)
+{
+	kmutex_t *hash_lock;
+
+	if (!(zfs_flags & ZFS_DEBUG_MODIFY))
+		return;
+
+	hash_lock = HDR_LOCK(buf->b_hdr);
+	mutex_enter(hash_lock);
+
+	ASSERT(buf->b_hdr->b_freeze_cksum != NULL ||
+	    buf->b_hdr->b_l1hdr.b_state == arc_anon);
+	arc_cksum_compute(buf, B_FALSE);
+	mutex_exit(hash_lock);
+
+}
+
+static void
+add_reference(arc_buf_hdr_t *hdr, kmutex_t *hash_lock, void *tag)
+{
+	arc_state_t *state;
+
+	ASSERT(HDR_HAS_L1HDR(hdr));
+	ASSERT(MUTEX_HELD(hash_lock));
+
+	state = hdr->b_l1hdr.b_state;
+
+	if ((refcount_add(&hdr->b_l1hdr.b_refcnt, tag) == 1) &&
+	    (state != arc_anon)) {
+		/* We don't use the L2-only state list. */
+		if (state != arc_l2c_only) {
+			arc_buf_contents_t type = arc_buf_type(hdr);
+			uint64_t delta = hdr->b_size * hdr->b_l1hdr.b_datacnt;
+			multilist_t *list = &state->arcs_list[type];
+			uint64_t *size = &state->arcs_lsize[type];
+
+			multilist_remove(list, hdr);
+
+			if (GHOST_STATE(state)) {
+				ASSERT0(hdr->b_l1hdr.b_datacnt);
+				ASSERT3P(hdr->b_l1hdr.b_buf, ==, NULL);
+				delta = hdr->b_size;
+			}
+			ASSERT(delta > 0);
+			ASSERT3U(*size, >=, delta);
+			atomic_add_64(size, -delta);
+		}
+		/* remove the prefetch flag if we get a reference */
+		hdr->b_flags &= ~ARC_FLAG_PREFETCH;
+	}
+}
+
+static int
+remove_reference(arc_buf_hdr_t *hdr, kmutex_t *hash_lock, void *tag)
+{
+	int cnt;
+	arc_state_t *state = hdr->b_l1hdr.b_state;
+
+	ASSERT(HDR_HAS_L1HDR(hdr));
+	ASSERT(state == arc_anon || MUTEX_HELD(hash_lock));
+	ASSERT(!GHOST_STATE(state));
+
+	/*
+	 * arc_l2c_only counts as a ghost state so we don't need to explicitly
+	 * check to prevent usage of the arc_l2c_only list.
+	 */
+	if (((cnt = refcount_remove(&hdr->b_l1hdr.b_refcnt, tag)) == 0) &&
+	    (state != arc_anon)) {
+		arc_buf_contents_t type = arc_buf_type(hdr);
+		multilist_t *list = &state->arcs_list[type];
+		uint64_t *size = &state->arcs_lsize[type];
+
+		multilist_insert(list, hdr);
+
+		ASSERT(hdr->b_l1hdr.b_datacnt > 0);
+		atomic_add_64(size, hdr->b_size *
+		    hdr->b_l1hdr.b_datacnt);
+	}
+	return (cnt);
+}
+
+/*
+ * Returns detailed information about a specific arc buffer.  When the
+ * state_index argument is set the function will calculate the arc header
+ * list position for its arc state.  Since this requires a linear traversal
+ * callers are strongly encourage not to do this.  However, it can be helpful
+ * for targeted analysis so the functionality is provided.
+ */
+void
+arc_buf_info(arc_buf_t *ab, arc_buf_info_t *abi, int state_index)
+{
+	arc_buf_hdr_t *hdr = ab->b_hdr;
+	l1arc_buf_hdr_t *l1hdr = NULL;
+	l2arc_buf_hdr_t *l2hdr = NULL;
+	arc_state_t *state = NULL;
+
+	if (HDR_HAS_L1HDR(hdr)) {
+		l1hdr = &hdr->b_l1hdr;
+		state = l1hdr->b_state;
+	}
+	if (HDR_HAS_L2HDR(hdr))
+		l2hdr = &hdr->b_l2hdr;
+
+	memset(abi, 0, sizeof (arc_buf_info_t));
+	abi->abi_flags = hdr->b_flags;
+
+	if (l1hdr) {
+		abi->abi_datacnt = l1hdr->b_datacnt;
+		abi->abi_access = l1hdr->b_arc_access;
+		abi->abi_mru_hits = l1hdr->b_mru_hits;
+		abi->abi_mru_ghost_hits = l1hdr->b_mru_ghost_hits;
+		abi->abi_mfu_hits = l1hdr->b_mfu_hits;
+		abi->abi_mfu_ghost_hits = l1hdr->b_mfu_ghost_hits;
+		abi->abi_holds = refcount_count(&l1hdr->b_refcnt);
+	}
+
+	if (l2hdr) {
+		abi->abi_l2arc_dattr = l2hdr->b_daddr;
+		abi->abi_l2arc_asize = l2hdr->b_asize;
+		abi->abi_l2arc_compress = l2hdr->b_compress;
+		abi->abi_l2arc_hits = l2hdr->b_hits;
+	}
+
+	abi->abi_state_type = state ? state->arcs_state : ARC_STATE_ANON;
+	abi->abi_state_contents = arc_buf_type(hdr);
+	abi->abi_size = hdr->b_size;
+}
+
+/*
+ * Move the supplied buffer to the indicated state. The hash lock
+ * for the buffer must be held by the caller.
+ */
+static void
+arc_change_state(arc_state_t *new_state, arc_buf_hdr_t *hdr,
+    kmutex_t *hash_lock)
+{
+	arc_state_t *old_state;
+	int64_t refcnt;
+	uint32_t datacnt;
+	uint64_t from_delta, to_delta;
+	arc_buf_contents_t buftype = arc_buf_type(hdr);
+
+	/*
+	 * We almost always have an L1 hdr here, since we call arc_hdr_realloc()
+	 * in arc_read() when bringing a buffer out of the L2ARC.  However, the
+	 * L1 hdr doesn't always exist when we change state to arc_anon before
+	 * destroying a header, in which case reallocating to add the L1 hdr is
+	 * pointless.
+	 */
+	if (HDR_HAS_L1HDR(hdr)) {
+		old_state = hdr->b_l1hdr.b_state;
+		refcnt = refcount_count(&hdr->b_l1hdr.b_refcnt);
+		datacnt = hdr->b_l1hdr.b_datacnt;
+	} else {
+		old_state = arc_l2c_only;
+		refcnt = 0;
+		datacnt = 0;
+	}
+
+	ASSERT(MUTEX_HELD(hash_lock));
+	ASSERT3P(new_state, !=, old_state);
+	ASSERT(refcnt == 0 || datacnt > 0);
+	ASSERT(!GHOST_STATE(new_state) || datacnt == 0);
+	ASSERT(old_state != arc_anon || datacnt <= 1);
+
+	from_delta = to_delta = datacnt * hdr->b_size;
+
+	/*
+	 * If this buffer is evictable, transfer it from the
+	 * old state list to the new state list.
+	 */
+	if (refcnt == 0) {
+		if (old_state != arc_anon && old_state != arc_l2c_only) {
+			uint64_t *size = &old_state->arcs_lsize[buftype];
+
+			ASSERT(HDR_HAS_L1HDR(hdr));
+			multilist_remove(&old_state->arcs_list[buftype], hdr);
+
+			/*
+			 * If prefetching out of the ghost cache,
+			 * we will have a non-zero datacnt.
+			 */
+			if (GHOST_STATE(old_state) && datacnt == 0) {
+				/* ghost elements have a ghost size */
+				ASSERT(hdr->b_l1hdr.b_buf == NULL);
+				from_delta = hdr->b_size;
+			}
+			ASSERT3U(*size, >=, from_delta);
+			atomic_add_64(size, -from_delta);
+		}
+		if (new_state != arc_anon && new_state != arc_l2c_only) {
+			uint64_t *size = &new_state->arcs_lsize[buftype];
+
+			/*
+			 * An L1 header always exists here, since if we're
+			 * moving to some L1-cached state (i.e. not l2c_only or
+			 * anonymous), we realloc the header to add an L1hdr
+			 * beforehand.
+			 */
+			ASSERT(HDR_HAS_L1HDR(hdr));
+			multilist_insert(&new_state->arcs_list[buftype], hdr);
+
+			/* ghost elements have a ghost size */
+			if (GHOST_STATE(new_state)) {
+				ASSERT0(datacnt);
+				ASSERT(hdr->b_l1hdr.b_buf == NULL);
+				to_delta = hdr->b_size;
+			}
+			atomic_add_64(size, to_delta);
+		}
+	}
+
+	ASSERT(!BUF_EMPTY(hdr));
+	if (new_state == arc_anon && HDR_IN_HASH_TABLE(hdr))
+		buf_hash_remove(hdr);
+
+	/* adjust state sizes (ignore arc_l2c_only) */
+
+	if (to_delta && new_state != arc_l2c_only) {
+		ASSERT(HDR_HAS_L1HDR(hdr));
+		if (GHOST_STATE(new_state)) {
+			ASSERT0(datacnt);
+
+			/*
+			 * We moving a header to a ghost state, we first
+			 * remove all arc buffers. Thus, we'll have a
+			 * datacnt of zero, and no arc buffer to use for
+			 * the reference. As a result, we use the arc
+			 * header pointer for the reference.
+			 */
+			(void) refcount_add_many(&new_state->arcs_size,
+			    hdr->b_size, hdr);
+		} else {
+			arc_buf_t *buf;
+			ASSERT3U(datacnt, !=, 0);
+
+			/*
+			 * Each individual buffer holds a unique reference,
+			 * thus we must remove each of these references one
+			 * at a time.
+			 */
+			for (buf = hdr->b_l1hdr.b_buf; buf != NULL;
+			    buf = buf->b_next) {
+				(void) refcount_add_many(&new_state->arcs_size,
+				    hdr->b_size, buf);
+			}
+		}
+	}
+
+	if (from_delta && old_state != arc_l2c_only) {
+		ASSERT(HDR_HAS_L1HDR(hdr));
+		if (GHOST_STATE(old_state)) {
+			/*
+			 * When moving a header off of a ghost state,
+			 * there's the possibility for datacnt to be
+			 * non-zero. This is because we first add the
+			 * arc buffer to the header prior to changing
+			 * the header's state. Since we used the header
+			 * for the reference when putting the header on
+			 * the ghost state, we must balance that and use
+			 * the header when removing off the ghost state
+			 * (even though datacnt is non zero).
+			 */
+
+			IMPLY(datacnt == 0, new_state == arc_anon ||
+			    new_state == arc_l2c_only);
+
+			(void) refcount_remove_many(&old_state->arcs_size,
+			    hdr->b_size, hdr);
+		} else {
+			arc_buf_t *buf;
+			ASSERT3U(datacnt, !=, 0);
+
+			/*
+			 * Each individual buffer holds a unique reference,
+			 * thus we must remove each of these references one
+			 * at a time.
+			 */
+			for (buf = hdr->b_l1hdr.b_buf; buf != NULL;
+			    buf = buf->b_next) {
+				(void) refcount_remove_many(
+				    &old_state->arcs_size, hdr->b_size, buf);
+			}
+		}
+	}
+
+	if (HDR_HAS_L1HDR(hdr))
+		hdr->b_l1hdr.b_state = new_state;
+
+	/*
+	 * L2 headers should never be on the L2 state list since they don't
+	 * have L1 headers allocated.
+	 */
+	ASSERT(multilist_is_empty(&arc_l2c_only->arcs_list[ARC_BUFC_DATA]) &&
+	    multilist_is_empty(&arc_l2c_only->arcs_list[ARC_BUFC_METADATA]));
+}
+
+void
+arc_space_consume(uint64_t space, arc_space_type_t type)
+{
+	ASSERT(type >= 0 && type < ARC_SPACE_NUMTYPES);
+
+	switch (type) {
+	default:
+		break;
+	case ARC_SPACE_DATA:
+		ARCSTAT_INCR(arcstat_data_size, space);
+		break;
+	case ARC_SPACE_META:
+		ARCSTAT_INCR(arcstat_metadata_size, space);
+		break;
+	case ARC_SPACE_OTHER:
+		ARCSTAT_INCR(arcstat_other_size, space);
+		break;
+	case ARC_SPACE_HDRS:
+		ARCSTAT_INCR(arcstat_hdr_size, space);
+		break;
+	case ARC_SPACE_L2HDRS:
+		ARCSTAT_INCR(arcstat_l2_hdr_size, space);
+		break;
+	}
+
+	if (type != ARC_SPACE_DATA)
+		ARCSTAT_INCR(arcstat_meta_used, space);
+
+	atomic_add_64(&arc_size, space);
+}
+
+void
+arc_space_return(uint64_t space, arc_space_type_t type)
+{
+	ASSERT(type >= 0 && type < ARC_SPACE_NUMTYPES);
+
+	switch (type) {
+	default:
+		break;
+	case ARC_SPACE_DATA:
+		ARCSTAT_INCR(arcstat_data_size, -space);
+		break;
+	case ARC_SPACE_META:
+		ARCSTAT_INCR(arcstat_metadata_size, -space);
+		break;
+	case ARC_SPACE_OTHER:
+		ARCSTAT_INCR(arcstat_other_size, -space);
+		break;
+	case ARC_SPACE_HDRS:
+		ARCSTAT_INCR(arcstat_hdr_size, -space);
+		break;
+	case ARC_SPACE_L2HDRS:
+		ARCSTAT_INCR(arcstat_l2_hdr_size, -space);
+		break;
+	}
+
+	if (type != ARC_SPACE_DATA) {
+		ASSERT(arc_meta_used >= space);
+		if (arc_meta_max < arc_meta_used)
+			arc_meta_max = arc_meta_used;
+		ARCSTAT_INCR(arcstat_meta_used, -space);
+	}
+
+	ASSERT(arc_size >= space);
+	atomic_add_64(&arc_size, -space);
+}
+
+arc_buf_t *
+arc_buf_alloc(spa_t *spa, uint64_t size, void *tag, arc_buf_contents_t type)
+{
+	arc_buf_hdr_t *hdr;
+	arc_buf_t *buf;
+
+	VERIFY3U(size, <=, spa_maxblocksize(spa));
+	hdr = kmem_cache_alloc(hdr_full_cache, KM_PUSHPAGE);
+	ASSERT(BUF_EMPTY(hdr));
+	ASSERT3P(hdr->b_freeze_cksum, ==, NULL);
+	hdr->b_size = size;
+	hdr->b_spa = spa_load_guid(spa);
+	hdr->b_l1hdr.b_mru_hits = 0;
+	hdr->b_l1hdr.b_mru_ghost_hits = 0;
+	hdr->b_l1hdr.b_mfu_hits = 0;
+	hdr->b_l1hdr.b_mfu_ghost_hits = 0;
+	hdr->b_l1hdr.b_l2_hits = 0;
+
+	buf = kmem_cache_alloc(buf_cache, KM_PUSHPAGE);
+	buf->b_hdr = hdr;
+	buf->b_data = NULL;
+	buf->b_efunc = NULL;
+	buf->b_private = NULL;
+	buf->b_next = NULL;
+
+	hdr->b_flags = arc_bufc_to_flags(type);
+	hdr->b_flags |= ARC_FLAG_HAS_L1HDR;
+
+	hdr->b_l1hdr.b_buf = buf;
+	hdr->b_l1hdr.b_state = arc_anon;
+	hdr->b_l1hdr.b_arc_access = 0;
+	hdr->b_l1hdr.b_datacnt = 1;
+	hdr->b_l1hdr.b_tmp_cdata = NULL;
+
+	arc_get_data_buf(buf);
+	ASSERT(refcount_is_zero(&hdr->b_l1hdr.b_refcnt));
+	(void) refcount_add(&hdr->b_l1hdr.b_refcnt, tag);
+
+	return (buf);
+}
+
+static char *arc_onloan_tag = "onloan";
+
+/*
+ * Loan out an anonymous arc buffer. Loaned buffers are not counted as in
+ * flight data by arc_tempreserve_space() until they are "returned". Loaned
+ * buffers must be returned to the arc before they can be used by the DMU or
+ * freed.
+ */
+arc_buf_t *
+arc_loan_buf(spa_t *spa, uint64_t size)
+{
+	arc_buf_t *buf;
+
+	buf = arc_buf_alloc(spa, size, arc_onloan_tag, ARC_BUFC_DATA);
+
+	atomic_add_64(&arc_loaned_bytes, size);
+	return (buf);
+}
+
+/*
+ * Return a loaned arc buffer to the arc.
+ */
+void
+arc_return_buf(arc_buf_t *buf, void *tag)
+{
+	arc_buf_hdr_t *hdr = buf->b_hdr;
+
+	ASSERT(buf->b_data != NULL);
+	ASSERT(HDR_HAS_L1HDR(hdr));
+	(void) refcount_add(&hdr->b_l1hdr.b_refcnt, tag);
+	(void) refcount_remove(&hdr->b_l1hdr.b_refcnt, arc_onloan_tag);
+
+	atomic_add_64(&arc_loaned_bytes, -hdr->b_size);
+}
+
+/* Detach an arc_buf from a dbuf (tag) */
+void
+arc_loan_inuse_buf(arc_buf_t *buf, void *tag)
+{
+	arc_buf_hdr_t *hdr = buf->b_hdr;
+
+	ASSERT(buf->b_data != NULL);
+	ASSERT(HDR_HAS_L1HDR(hdr));
+	(void) refcount_add(&hdr->b_l1hdr.b_refcnt, arc_onloan_tag);
+	(void) refcount_remove(&hdr->b_l1hdr.b_refcnt, tag);
+	buf->b_efunc = NULL;
+	buf->b_private = NULL;
+
+	atomic_add_64(&arc_loaned_bytes, hdr->b_size);
+}
+
+static arc_buf_t *
+arc_buf_clone(arc_buf_t *from)
+{
+	arc_buf_t *buf;
+	arc_buf_hdr_t *hdr = from->b_hdr;
+	uint64_t size = hdr->b_size;
+
+	ASSERT(HDR_HAS_L1HDR(hdr));
+	ASSERT(hdr->b_l1hdr.b_state != arc_anon);
+
+	buf = kmem_cache_alloc(buf_cache, KM_PUSHPAGE);
+	buf->b_hdr = hdr;
+	buf->b_data = NULL;
+	buf->b_efunc = NULL;
+	buf->b_private = NULL;
+	buf->b_next = hdr->b_l1hdr.b_buf;
+	hdr->b_l1hdr.b_buf = buf;
+	arc_get_data_buf(buf);
+	bcopy(from->b_data, buf->b_data, size);
+
+	/*
+	 * This buffer already exists in the arc so create a duplicate
+	 * copy for the caller.  If the buffer is associated with user data
+	 * then track the size and number of duplicates.  These stats will be
+	 * updated as duplicate buffers are created and destroyed.
+	 */
+	if (HDR_ISTYPE_DATA(hdr)) {
+		ARCSTAT_BUMP(arcstat_duplicate_buffers);
+		ARCSTAT_INCR(arcstat_duplicate_buffers_size, size);
+	}
+	hdr->b_l1hdr.b_datacnt += 1;
+	return (buf);
+}
+
+void
+arc_buf_add_ref(arc_buf_t *buf, void* tag)
+{
+	arc_buf_hdr_t *hdr;
+	kmutex_t *hash_lock;
+
+	/*
+	 * Check to see if this buffer is evicted.  Callers
+	 * must verify b_data != NULL to know if the add_ref
+	 * was successful.
+	 */
+	mutex_enter(&buf->b_evict_lock);
+	if (buf->b_data == NULL) {
+		mutex_exit(&buf->b_evict_lock);
+		return;
+	}
+	hash_lock = HDR_LOCK(buf->b_hdr);
+	mutex_enter(hash_lock);
+	hdr = buf->b_hdr;
+	ASSERT(HDR_HAS_L1HDR(hdr));
+	ASSERT3P(hash_lock, ==, HDR_LOCK(hdr));
+	mutex_exit(&buf->b_evict_lock);
+
+	ASSERT(hdr->b_l1hdr.b_state == arc_mru ||
+	    hdr->b_l1hdr.b_state == arc_mfu);
+
+	add_reference(hdr, hash_lock, tag);
+	DTRACE_PROBE1(arc__hit, arc_buf_hdr_t *, hdr);
+	arc_access(hdr, hash_lock);
+	mutex_exit(hash_lock);
+	ARCSTAT_BUMP(arcstat_hits);
+	ARCSTAT_CONDSTAT(!HDR_PREFETCH(hdr),
+	    demand, prefetch, !HDR_ISTYPE_METADATA(hdr),
+	    data, metadata, hits);
+}
+
+static void
+arc_buf_free_on_write(void *data, size_t size,
+    void (*free_func)(void *, size_t))
+{
+	l2arc_data_free_t *df;
+
+	df = kmem_alloc(sizeof (*df), KM_SLEEP);
+	df->l2df_data = data;
+	df->l2df_size = size;
+	df->l2df_func = free_func;
+	mutex_enter(&l2arc_free_on_write_mtx);
+	list_insert_head(l2arc_free_on_write, df);
+	mutex_exit(&l2arc_free_on_write_mtx);
+}
+
+/*
+ * Free the arc data buffer.  If it is an l2arc write in progress,
+ * the buffer is placed on l2arc_free_on_write to be freed later.
+ */
+static void
+arc_buf_data_free(arc_buf_t *buf, void (*free_func)(void *, size_t))
+{
+	arc_buf_hdr_t *hdr = buf->b_hdr;
+
+	if (HDR_L2_WRITING(hdr)) {
+		arc_buf_free_on_write(buf->b_data, hdr->b_size, free_func);
+		ARCSTAT_BUMP(arcstat_l2_free_on_write);
+	} else {
+		free_func(buf->b_data, hdr->b_size);
+	}
+}
+
+static void
+arc_buf_l2_cdata_free(arc_buf_hdr_t *hdr)
+{
+	ASSERT(HDR_HAS_L2HDR(hdr));
+	ASSERT(MUTEX_HELD(&hdr->b_l2hdr.b_dev->l2ad_mtx));
+
+	/*
+	 * The b_tmp_cdata field is linked off of the b_l1hdr, so if
+	 * that doesn't exist, the header is in the arc_l2c_only state,
+	 * and there isn't anything to free (it's already been freed).
+	 */
+	if (!HDR_HAS_L1HDR(hdr))
+		return;
+
+	/*
+	 * The header isn't being written to the l2arc device, thus it
+	 * shouldn't have a b_tmp_cdata to free.
+	 */
+	if (!HDR_L2_WRITING(hdr)) {
+		ASSERT3P(hdr->b_l1hdr.b_tmp_cdata, ==, NULL);
+		return;
+	}
+
+	/*
+	 * The header does not have compression enabled. This can be due
+	 * to the buffer not being compressible, or because we're
+	 * freeing the buffer before the second phase of
+	 * l2arc_write_buffer() has started (which does the compression
+	 * step). In either case, b_tmp_cdata does not point to a
+	 * separately compressed buffer, so there's nothing to free (it
+	 * points to the same buffer as the arc_buf_t's b_data field).
+	 */
+	if (hdr->b_l2hdr.b_compress == ZIO_COMPRESS_OFF) {
+		hdr->b_l1hdr.b_tmp_cdata = NULL;
+		return;
+	}
+
+	/*
+	 * There's nothing to free since the buffer was all zero's and
+	 * compressed to a zero length buffer.
+	 */
+	if (hdr->b_l2hdr.b_compress == ZIO_COMPRESS_EMPTY) {
+		ASSERT3P(hdr->b_l1hdr.b_tmp_cdata, ==, NULL);
+		return;
+	}
+
+	ASSERT(L2ARC_IS_VALID_COMPRESS(hdr->b_l2hdr.b_compress));
+
+	arc_buf_free_on_write(hdr->b_l1hdr.b_tmp_cdata,
+	    hdr->b_size, zio_data_buf_free);
+
+	ARCSTAT_BUMP(arcstat_l2_cdata_free_on_write);
+	hdr->b_l1hdr.b_tmp_cdata = NULL;
+}
+
+/*
+ * Free up buf->b_data and if 'remove' is set, then pull the
+ * arc_buf_t off of the the arc_buf_hdr_t's list and free it.
+ */
+static void
+arc_buf_destroy(arc_buf_t *buf, boolean_t remove)
+{
+	arc_buf_t **bufp;
+
+	/* free up data associated with the buf */
+	if (buf->b_data != NULL) {
+		arc_state_t *state = buf->b_hdr->b_l1hdr.b_state;
+		uint64_t size = buf->b_hdr->b_size;
+		arc_buf_contents_t type = arc_buf_type(buf->b_hdr);
+
+		arc_cksum_verify(buf);
+		arc_buf_unwatch(buf);
+
+		if (type == ARC_BUFC_METADATA) {
+			arc_buf_data_free(buf, zio_buf_free);
+			arc_space_return(size, ARC_SPACE_META);
+		} else {
+			ASSERT(type == ARC_BUFC_DATA);
+			arc_buf_data_free(buf, zio_data_buf_free);
+			arc_space_return(size, ARC_SPACE_DATA);
+		}
+
+		/* protected by hash lock, if in the hash table */
+		if (multilist_link_active(&buf->b_hdr->b_l1hdr.b_arc_node)) {
+			uint64_t *cnt = &state->arcs_lsize[type];
+
+			ASSERT(refcount_is_zero(
+			    &buf->b_hdr->b_l1hdr.b_refcnt));
+			ASSERT(state != arc_anon && state != arc_l2c_only);
+
+			ASSERT3U(*cnt, >=, size);
+			atomic_add_64(cnt, -size);
+		}
+
+		(void) refcount_remove_many(&state->arcs_size, size, buf);
+		buf->b_data = NULL;
+
+		/*
+		 * If we're destroying a duplicate buffer make sure
+		 * that the appropriate statistics are updated.
+		 */
+		if (buf->b_hdr->b_l1hdr.b_datacnt > 1 &&
+		    HDR_ISTYPE_DATA(buf->b_hdr)) {
+			ARCSTAT_BUMPDOWN(arcstat_duplicate_buffers);
+			ARCSTAT_INCR(arcstat_duplicate_buffers_size, -size);
+		}
+		ASSERT(buf->b_hdr->b_l1hdr.b_datacnt > 0);
+		buf->b_hdr->b_l1hdr.b_datacnt -= 1;
+	}
+
+	/* only remove the buf if requested */
+	if (!remove)
+		return;
+
+	/* remove the buf from the hdr list */
+	for (bufp = &buf->b_hdr->b_l1hdr.b_buf; *bufp != buf;
+	    bufp = &(*bufp)->b_next)
+		continue;
+	*bufp = buf->b_next;
+	buf->b_next = NULL;
+
+	ASSERT(buf->b_efunc == NULL);
+
+	/* clean up the buf */
+	buf->b_hdr = NULL;
+	kmem_cache_free(buf_cache, buf);
+}
+
+static void
+arc_hdr_l2hdr_destroy(arc_buf_hdr_t *hdr)
+{
+	l2arc_buf_hdr_t *l2hdr = &hdr->b_l2hdr;
+	l2arc_dev_t *dev = l2hdr->b_dev;
+
+	ASSERT(MUTEX_HELD(&dev->l2ad_mtx));
+	ASSERT(HDR_HAS_L2HDR(hdr));
+
+	list_remove(&dev->l2ad_buflist, hdr);
+
+	/*
+	 * We don't want to leak the b_tmp_cdata buffer that was
+	 * allocated in l2arc_write_buffers()
+	 */
+	arc_buf_l2_cdata_free(hdr);
+
+	/*
+	 * If the l2hdr's b_daddr is equal to L2ARC_ADDR_UNSET, then
+	 * this header is being processed by l2arc_write_buffers() (i.e.
+	 * it's in the first stage of l2arc_write_buffers()).
+	 * Re-affirming that truth here, just to serve as a reminder. If
+	 * b_daddr does not equal L2ARC_ADDR_UNSET, then the header may or
+	 * may not have its HDR_L2_WRITING flag set. (the write may have
+	 * completed, in which case HDR_L2_WRITING will be false and the
+	 * b_daddr field will point to the address of the buffer on disk).
+	 */
+	IMPLY(l2hdr->b_daddr == L2ARC_ADDR_UNSET, HDR_L2_WRITING(hdr));
+
+	/*
+	 * If b_daddr is equal to L2ARC_ADDR_UNSET, we're racing with
+	 * l2arc_write_buffers(). Since we've just removed this header
+	 * from the l2arc buffer list, this header will never reach the
+	 * second stage of l2arc_write_buffers(), which increments the
+	 * accounting stats for this header. Thus, we must be careful
+	 * not to decrement them for this header either.
+	 */
+	if (l2hdr->b_daddr != L2ARC_ADDR_UNSET) {
+		ARCSTAT_INCR(arcstat_l2_asize, -l2hdr->b_asize);
+		ARCSTAT_INCR(arcstat_l2_size, -hdr->b_size);
+
+		vdev_space_update(dev->l2ad_vdev,
+		    -l2hdr->b_asize, 0, 0);
+
+		(void) refcount_remove_many(&dev->l2ad_alloc,
+		    l2hdr->b_asize, hdr);
+	}
+
+	hdr->b_flags &= ~ARC_FLAG_HAS_L2HDR;
+}
+
+static void
+arc_hdr_destroy(arc_buf_hdr_t *hdr)
+{
+	if (HDR_HAS_L1HDR(hdr)) {
+		ASSERT(hdr->b_l1hdr.b_buf == NULL ||
+		    hdr->b_l1hdr.b_datacnt > 0);
+		ASSERT(refcount_is_zero(&hdr->b_l1hdr.b_refcnt));
+		ASSERT3P(hdr->b_l1hdr.b_state, ==, arc_anon);
+	}
+	ASSERT(!HDR_IO_IN_PROGRESS(hdr));
+	ASSERT(!HDR_IN_HASH_TABLE(hdr));
+
+	if (HDR_HAS_L2HDR(hdr)) {
+		l2arc_dev_t *dev = hdr->b_l2hdr.b_dev;
+		boolean_t buflist_held = MUTEX_HELD(&dev->l2ad_mtx);
+
+		if (!buflist_held)
+			mutex_enter(&dev->l2ad_mtx);
+
+		/*
+		 * Even though we checked this conditional above, we
+		 * need to check this again now that we have the
+		 * l2ad_mtx. This is because we could be racing with
+		 * another thread calling l2arc_evict() which might have
+		 * destroyed this header's L2 portion as we were waiting
+		 * to acquire the l2ad_mtx. If that happens, we don't
+		 * want to re-destroy the header's L2 portion.
+		 */
+		if (HDR_HAS_L2HDR(hdr))
+			arc_hdr_l2hdr_destroy(hdr);
+
+		if (!buflist_held)
+			mutex_exit(&dev->l2ad_mtx);
+	}
+
+	if (!BUF_EMPTY(hdr))
+		buf_discard_identity(hdr);
+
+	if (hdr->b_freeze_cksum != NULL) {
+		kmem_free(hdr->b_freeze_cksum, sizeof (zio_cksum_t));
+		hdr->b_freeze_cksum = NULL;
+	}
+
+	if (HDR_HAS_L1HDR(hdr)) {
+		while (hdr->b_l1hdr.b_buf) {
+			arc_buf_t *buf = hdr->b_l1hdr.b_buf;
+
+			if (buf->b_efunc != NULL) {
+				mutex_enter(&arc_user_evicts_lock);
+				mutex_enter(&buf->b_evict_lock);
+				ASSERT(buf->b_hdr != NULL);
+				arc_buf_destroy(hdr->b_l1hdr.b_buf, FALSE);
+				hdr->b_l1hdr.b_buf = buf->b_next;
+				buf->b_hdr = &arc_eviction_hdr;
+				buf->b_next = arc_eviction_list;
+				arc_eviction_list = buf;
+				mutex_exit(&buf->b_evict_lock);
+				cv_signal(&arc_user_evicts_cv);
+				mutex_exit(&arc_user_evicts_lock);
+			} else {
+				arc_buf_destroy(hdr->b_l1hdr.b_buf, TRUE);
+			}
+		}
+	}
+
+	ASSERT3P(hdr->b_hash_next, ==, NULL);
+	if (HDR_HAS_L1HDR(hdr)) {
+		ASSERT(!multilist_link_active(&hdr->b_l1hdr.b_arc_node));
+		ASSERT3P(hdr->b_l1hdr.b_acb, ==, NULL);
+		kmem_cache_free(hdr_full_cache, hdr);
+	} else {
+		kmem_cache_free(hdr_l2only_cache, hdr);
+	}
+}
+
+void
+arc_buf_free(arc_buf_t *buf, void *tag)
+{
+	arc_buf_hdr_t *hdr = buf->b_hdr;
+	int hashed = hdr->b_l1hdr.b_state != arc_anon;
+
+	ASSERT(buf->b_efunc == NULL);
+	ASSERT(buf->b_data != NULL);
+
+	if (hashed) {
+		kmutex_t *hash_lock = HDR_LOCK(hdr);
+
+		mutex_enter(hash_lock);
+		hdr = buf->b_hdr;
+		ASSERT3P(hash_lock, ==, HDR_LOCK(hdr));
+
+		(void) remove_reference(hdr, hash_lock, tag);
+		if (hdr->b_l1hdr.b_datacnt > 1) {
+			arc_buf_destroy(buf, TRUE);
+		} else {
+			ASSERT(buf == hdr->b_l1hdr.b_buf);
+			ASSERT(buf->b_efunc == NULL);
+			hdr->b_flags |= ARC_FLAG_BUF_AVAILABLE;
+		}
+		mutex_exit(hash_lock);
+	} else if (HDR_IO_IN_PROGRESS(hdr)) {
+		int destroy_hdr;
+		/*
+		 * We are in the middle of an async write.  Don't destroy
+		 * this buffer unless the write completes before we finish
+		 * decrementing the reference count.
+		 */
+		mutex_enter(&arc_user_evicts_lock);
+		(void) remove_reference(hdr, NULL, tag);
+		ASSERT(refcount_is_zero(&hdr->b_l1hdr.b_refcnt));
+		destroy_hdr = !HDR_IO_IN_PROGRESS(hdr);
+		mutex_exit(&arc_user_evicts_lock);
+		if (destroy_hdr)
+			arc_hdr_destroy(hdr);
+	} else {
+		if (remove_reference(hdr, NULL, tag) > 0)
+			arc_buf_destroy(buf, TRUE);
+		else
+			arc_hdr_destroy(hdr);
+	}
+}
+
+boolean_t
+arc_buf_remove_ref(arc_buf_t *buf, void* tag)
+{
+	arc_buf_hdr_t *hdr = buf->b_hdr;
+	kmutex_t *hash_lock = HDR_LOCK(hdr);
+	boolean_t no_callback = (buf->b_efunc == NULL);
+
+	if (hdr->b_l1hdr.b_state == arc_anon) {
+		ASSERT(hdr->b_l1hdr.b_datacnt == 1);
+		arc_buf_free(buf, tag);
+		return (no_callback);
+	}
+
+	mutex_enter(hash_lock);
+	hdr = buf->b_hdr;
+	ASSERT(hdr->b_l1hdr.b_datacnt > 0);
+	ASSERT3P(hash_lock, ==, HDR_LOCK(hdr));
+	ASSERT(hdr->b_l1hdr.b_state != arc_anon);
+	ASSERT(buf->b_data != NULL);
+
+	(void) remove_reference(hdr, hash_lock, tag);
+	if (hdr->b_l1hdr.b_datacnt > 1) {
+		if (no_callback)
+			arc_buf_destroy(buf, TRUE);
+	} else if (no_callback) {
+		ASSERT(hdr->b_l1hdr.b_buf == buf && buf->b_next == NULL);
+		ASSERT(buf->b_efunc == NULL);
+		hdr->b_flags |= ARC_FLAG_BUF_AVAILABLE;
+	}
+	ASSERT(no_callback || hdr->b_l1hdr.b_datacnt > 1 ||
+	    refcount_is_zero(&hdr->b_l1hdr.b_refcnt));
+	mutex_exit(hash_lock);
+	return (no_callback);
+}
+
+uint64_t
+arc_buf_size(arc_buf_t *buf)
+{
+	return (buf->b_hdr->b_size);
+}
+
+/*
+ * Called from the DMU to determine if the current buffer should be
+ * evicted. In order to ensure proper locking, the eviction must be initiated
+ * from the DMU. Return true if the buffer is associated with user data and
+ * duplicate buffers still exist.
+ */
+boolean_t
+arc_buf_eviction_needed(arc_buf_t *buf)
+{
+	arc_buf_hdr_t *hdr;
+	boolean_t evict_needed = B_FALSE;
+
+	if (zfs_disable_dup_eviction)
+		return (B_FALSE);
+
+	mutex_enter(&buf->b_evict_lock);
+	hdr = buf->b_hdr;
+	if (hdr == NULL) {
+		/*
+		 * We are in arc_do_user_evicts(); let that function
+		 * perform the eviction.
+		 */
+		ASSERT(buf->b_data == NULL);
+		mutex_exit(&buf->b_evict_lock);
+		return (B_FALSE);
+	} else if (buf->b_data == NULL) {
+		/*
+		 * We have already been added to the arc eviction list;
+		 * recommend eviction.
+		 */
+		ASSERT3P(hdr, ==, &arc_eviction_hdr);
+		mutex_exit(&buf->b_evict_lock);
+		return (B_TRUE);
+	}
+
+	if (hdr->b_l1hdr.b_datacnt > 1 && HDR_ISTYPE_DATA(hdr))
+		evict_needed = B_TRUE;
+
+	mutex_exit(&buf->b_evict_lock);
+	return (evict_needed);
+}
+
+/*
+ * Evict the arc_buf_hdr that is provided as a parameter. The resultant
+ * state of the header is dependent on its state prior to entering this
+ * function. The following transitions are possible:
+ *
+ *    - arc_mru -> arc_mru_ghost
+ *    - arc_mfu -> arc_mfu_ghost
+ *    - arc_mru_ghost -> arc_l2c_only
+ *    - arc_mru_ghost -> deleted
+ *    - arc_mfu_ghost -> arc_l2c_only
+ *    - arc_mfu_ghost -> deleted
+ */
+static int64_t
+arc_evict_hdr(arc_buf_hdr_t *hdr, kmutex_t *hash_lock)
+{
+	arc_state_t *evicted_state, *state;
+	int64_t bytes_evicted = 0;
+
+	ASSERT(MUTEX_HELD(hash_lock));
+	ASSERT(HDR_HAS_L1HDR(hdr));
+
+	state = hdr->b_l1hdr.b_state;
+	if (GHOST_STATE(state)) {
+		ASSERT(!HDR_IO_IN_PROGRESS(hdr));
+		ASSERT(hdr->b_l1hdr.b_buf == NULL);
+
+		/*
+		 * l2arc_write_buffers() relies on a header's L1 portion
+		 * (i.e. its b_tmp_cdata field) during its write phase.
+		 * Thus, we cannot push a header onto the arc_l2c_only
+		 * state (removing its L1 piece) until the header is
+		 * done being written to the l2arc.
+		 */
+		if (HDR_HAS_L2HDR(hdr) && HDR_L2_WRITING(hdr)) {
+			ARCSTAT_BUMP(arcstat_evict_l2_skip);
+			return (bytes_evicted);
+		}
+
+		ARCSTAT_BUMP(arcstat_deleted);
+		bytes_evicted += hdr->b_size;
+
+		DTRACE_PROBE1(arc__delete, arc_buf_hdr_t *, hdr);
+
+		if (HDR_HAS_L2HDR(hdr)) {
+			/*
+			 * This buffer is cached on the 2nd Level ARC;
+			 * don't destroy the header.
+			 */
+			arc_change_state(arc_l2c_only, hdr, hash_lock);
+			/*
+			 * dropping from L1+L2 cached to L2-only,
+			 * realloc to remove the L1 header.
+			 */
+			hdr = arc_hdr_realloc(hdr, hdr_full_cache,
+			    hdr_l2only_cache);
+		} else {
+			arc_change_state(arc_anon, hdr, hash_lock);
+			arc_hdr_destroy(hdr);
+		}
+		return (bytes_evicted);
+	}
+
+	ASSERT(state == arc_mru || state == arc_mfu);
+	evicted_state = (state == arc_mru) ? arc_mru_ghost : arc_mfu_ghost;
+
+	/* prefetch buffers have a minimum lifespan */
+	if (HDR_IO_IN_PROGRESS(hdr) ||
+	    ((hdr->b_flags & (ARC_FLAG_PREFETCH | ARC_FLAG_INDIRECT)) &&
+	    ddi_get_lbolt() - hdr->b_l1hdr.b_arc_access <
+	    arc_min_prefetch_lifespan)) {
+		ARCSTAT_BUMP(arcstat_evict_skip);
+		return (bytes_evicted);
+	}
+
+	ASSERT0(refcount_count(&hdr->b_l1hdr.b_refcnt));
+	ASSERT3U(hdr->b_l1hdr.b_datacnt, >, 0);
+	while (hdr->b_l1hdr.b_buf) {
+		arc_buf_t *buf = hdr->b_l1hdr.b_buf;
+		if (!mutex_tryenter(&buf->b_evict_lock)) {
+			ARCSTAT_BUMP(arcstat_mutex_miss);
+			break;
+		}
+		if (buf->b_data != NULL)
+			bytes_evicted += hdr->b_size;
+		if (buf->b_efunc != NULL) {
+			mutex_enter(&arc_user_evicts_lock);
+			arc_buf_destroy(buf, FALSE);
+			hdr->b_l1hdr.b_buf = buf->b_next;
+			buf->b_hdr = &arc_eviction_hdr;
+			buf->b_next = arc_eviction_list;
+			arc_eviction_list = buf;
+			cv_signal(&arc_user_evicts_cv);
+			mutex_exit(&arc_user_evicts_lock);
+			mutex_exit(&buf->b_evict_lock);
+		} else {
+			mutex_exit(&buf->b_evict_lock);
+			arc_buf_destroy(buf, TRUE);
+		}
+	}
+
+	if (HDR_HAS_L2HDR(hdr)) {
+		ARCSTAT_INCR(arcstat_evict_l2_cached, hdr->b_size);
+	} else {
+		if (l2arc_write_eligible(hdr->b_spa, hdr))
+			ARCSTAT_INCR(arcstat_evict_l2_eligible, hdr->b_size);
+		else
+			ARCSTAT_INCR(arcstat_evict_l2_ineligible, hdr->b_size);
+	}
+
+	if (hdr->b_l1hdr.b_datacnt == 0) {
+		arc_change_state(evicted_state, hdr, hash_lock);
+		ASSERT(HDR_IN_HASH_TABLE(hdr));
+		hdr->b_flags |= ARC_FLAG_IN_HASH_TABLE;
+		hdr->b_flags &= ~ARC_FLAG_BUF_AVAILABLE;
+		DTRACE_PROBE1(arc__evict, arc_buf_hdr_t *, hdr);
+	}
+
+	return (bytes_evicted);
+}
+
+static uint64_t
+arc_evict_state_impl(multilist_t *ml, int idx, arc_buf_hdr_t *marker,
+    uint64_t spa, int64_t bytes)
+{
+	multilist_sublist_t *mls;
+	uint64_t bytes_evicted = 0;
+	arc_buf_hdr_t *hdr;
+	kmutex_t *hash_lock;
+	int evict_count = 0;
+
+	ASSERT3P(marker, !=, NULL);
+	IMPLY(bytes < 0, bytes == ARC_EVICT_ALL);
+
+	mls = multilist_sublist_lock(ml, idx);
+
+	for (hdr = multilist_sublist_prev(mls, marker); hdr != NULL;
+	    hdr = multilist_sublist_prev(mls, marker)) {
+		if ((bytes != ARC_EVICT_ALL && bytes_evicted >= bytes) ||
+		    (evict_count >= zfs_arc_evict_batch_limit))
+			break;
+
+		/*
+		 * To keep our iteration location, move the marker
+		 * forward. Since we're not holding hdr's hash lock, we
+		 * must be very careful and not remove 'hdr' from the
+		 * sublist. Otherwise, other consumers might mistake the
+		 * 'hdr' as not being on a sublist when they call the
+		 * multilist_link_active() function (they all rely on
+		 * the hash lock protecting concurrent insertions and
+		 * removals). multilist_sublist_move_forward() was
+		 * specifically implemented to ensure this is the case
+		 * (only 'marker' will be removed and re-inserted).
+		 */
+		multilist_sublist_move_forward(mls, marker);
+
+		/*
+		 * The only case where the b_spa field should ever be
+		 * zero, is the marker headers inserted by
+		 * arc_evict_state(). It's possible for multiple threads
+		 * to be calling arc_evict_state() concurrently (e.g.
+		 * dsl_pool_close() and zio_inject_fault()), so we must
+		 * skip any markers we see from these other threads.
+		 */
+		if (hdr->b_spa == 0)
+			continue;
+
+		/* we're only interested in evicting buffers of a certain spa */
+		if (spa != 0 && hdr->b_spa != spa) {
+			ARCSTAT_BUMP(arcstat_evict_skip);
+			continue;
+		}
+
+		hash_lock = HDR_LOCK(hdr);
+
+		/*
+		 * We aren't calling this function from any code path
+		 * that would already be holding a hash lock, so we're
+		 * asserting on this assumption to be defensive in case
+		 * this ever changes. Without this check, it would be
+		 * possible to incorrectly increment arcstat_mutex_miss
+		 * below (e.g. if the code changed such that we called
+		 * this function with a hash lock held).
+		 */
+		ASSERT(!MUTEX_HELD(hash_lock));
+
+		if (mutex_tryenter(hash_lock)) {
+			uint64_t evicted = arc_evict_hdr(hdr, hash_lock);
+			mutex_exit(hash_lock);
+
+			bytes_evicted += evicted;
+
+			/*
+			 * If evicted is zero, arc_evict_hdr() must have
+			 * decided to skip this header, don't increment
+			 * evict_count in this case.
+			 */
+			if (evicted != 0)
+				evict_count++;
+
+			/*
+			 * If arc_size isn't overflowing, signal any
+			 * threads that might happen to be waiting.
+			 *
+			 * For each header evicted, we wake up a single
+			 * thread. If we used cv_broadcast, we could
+			 * wake up "too many" threads causing arc_size
+			 * to significantly overflow arc_c; since
+			 * arc_get_data_buf() doesn't check for overflow
+			 * when it's woken up (it doesn't because it's
+			 * possible for the ARC to be overflowing while
+			 * full of un-evictable buffers, and the
+			 * function should proceed in this case).
+			 *
+			 * If threads are left sleeping, due to not
+			 * using cv_broadcast, they will be woken up
+			 * just before arc_reclaim_thread() sleeps.
+			 */
+			mutex_enter(&arc_reclaim_lock);
+			if (!arc_is_overflowing())
+				cv_signal(&arc_reclaim_waiters_cv);
+			mutex_exit(&arc_reclaim_lock);
+		} else {
+			ARCSTAT_BUMP(arcstat_mutex_miss);
+		}
+	}
+
+	multilist_sublist_unlock(mls);
+
+	return (bytes_evicted);
+}
+
+/*
+ * Evict buffers from the given arc state, until we've removed the
+ * specified number of bytes. Move the removed buffers to the
+ * appropriate evict state.
+ *
+ * This function makes a "best effort". It skips over any buffers
+ * it can't get a hash_lock on, and so, may not catch all candidates.
+ * It may also return without evicting as much space as requested.
+ *
+ * If bytes is specified using the special value ARC_EVICT_ALL, this
+ * will evict all available (i.e. unlocked and evictable) buffers from
+ * the given arc state; which is used by arc_flush().
+ */
+static uint64_t
+arc_evict_state(arc_state_t *state, uint64_t spa, int64_t bytes,
+    arc_buf_contents_t type)
+{
+	uint64_t total_evicted = 0;
+	multilist_t *ml = &state->arcs_list[type];
+	int num_sublists;
+	arc_buf_hdr_t **markers;
+	int i;
+
+	IMPLY(bytes < 0, bytes == ARC_EVICT_ALL);
+
+	num_sublists = multilist_get_num_sublists(ml);
+
+	/*
+	 * If we've tried to evict from each sublist, made some
+	 * progress, but still have not hit the target number of bytes
+	 * to evict, we want to keep trying. The markers allow us to
+	 * pick up where we left off for each individual sublist, rather
+	 * than starting from the tail each time.
+	 */
+	markers = kmem_zalloc(sizeof (*markers) * num_sublists, KM_SLEEP);
+	for (i = 0; i < num_sublists; i++) {
+		multilist_sublist_t *mls;
+
+		markers[i] = kmem_cache_alloc(hdr_full_cache, KM_SLEEP);
+
+		/*
+		 * A b_spa of 0 is used to indicate that this header is
+		 * a marker. This fact is used in arc_adjust_type() and
+		 * arc_evict_state_impl().
+		 */
+		markers[i]->b_spa = 0;
+
+		mls = multilist_sublist_lock(ml, i);
+		multilist_sublist_insert_tail(mls, markers[i]);
+		multilist_sublist_unlock(mls);
+	}
+
+	/*
+	 * While we haven't hit our target number of bytes to evict, or
+	 * we're evicting all available buffers.
+	 */
+	while (total_evicted < bytes || bytes == ARC_EVICT_ALL) {
+		/*
+		 * Start eviction using a randomly selected sublist,
+		 * this is to try and evenly balance eviction across all
+		 * sublists. Always starting at the same sublist
+		 * (e.g. index 0) would cause evictions to favor certain
+		 * sublists over others.
+		 */
+		int sublist_idx = multilist_get_random_index(ml);
+		uint64_t scan_evicted = 0;
+
+		for (i = 0; i < num_sublists; i++) {
+			uint64_t bytes_remaining;
+			uint64_t bytes_evicted;
+
+			if (bytes == ARC_EVICT_ALL)
+				bytes_remaining = ARC_EVICT_ALL;
+			else if (total_evicted < bytes)
+				bytes_remaining = bytes - total_evicted;
+			else
+				break;
+
+			bytes_evicted = arc_evict_state_impl(ml, sublist_idx,
+			    markers[sublist_idx], spa, bytes_remaining);
+
+			scan_evicted += bytes_evicted;
+			total_evicted += bytes_evicted;
+
+			/* we've reached the end, wrap to the beginning */
+			if (++sublist_idx >= num_sublists)
+				sublist_idx = 0;
+		}
+
+		/*
+		 * If we didn't evict anything during this scan, we have
+		 * no reason to believe we'll evict more during another
+		 * scan, so break the loop.
+		 */
+		if (scan_evicted == 0) {
+			/* This isn't possible, let's make that obvious */
+			ASSERT3S(bytes, !=, 0);
+
+			/*
+			 * When bytes is ARC_EVICT_ALL, the only way to
+			 * break the loop is when scan_evicted is zero.
+			 * In that case, we actually have evicted enough,
+			 * so we don't want to increment the kstat.
+			 */
+			if (bytes != ARC_EVICT_ALL) {
+				ASSERT3S(total_evicted, <, bytes);
+				ARCSTAT_BUMP(arcstat_evict_not_enough);
+			}
+
+			break;
+		}
+	}
+
+	for (i = 0; i < num_sublists; i++) {
+		multilist_sublist_t *mls = multilist_sublist_lock(ml, i);
+		multilist_sublist_remove(mls, markers[i]);
+		multilist_sublist_unlock(mls);
+
+		kmem_cache_free(hdr_full_cache, markers[i]);
+	}
+	kmem_free(markers, sizeof (*markers) * num_sublists);
+
+	return (total_evicted);
+}
+
+/*
+ * Flush all "evictable" data of the given type from the arc state
+ * specified. This will not evict any "active" buffers (i.e. referenced).
+ *
+ * When 'retry' is set to FALSE, the function will make a single pass
+ * over the state and evict any buffers that it can. Since it doesn't
+ * continually retry the eviction, it might end up leaving some buffers
+ * in the ARC due to lock misses.
+ *
+ * When 'retry' is set to TRUE, the function will continually retry the
+ * eviction until *all* evictable buffers have been removed from the
+ * state. As a result, if concurrent insertions into the state are
+ * allowed (e.g. if the ARC isn't shutting down), this function might
+ * wind up in an infinite loop, continually trying to evict buffers.
+ */
+static uint64_t
+arc_flush_state(arc_state_t *state, uint64_t spa, arc_buf_contents_t type,
+    boolean_t retry)
+{
+	uint64_t evicted = 0;
+
+	while (state->arcs_lsize[type] != 0) {
+		evicted += arc_evict_state(state, spa, ARC_EVICT_ALL, type);
+
+		if (!retry)
+			break;
+	}
+
+	return (evicted);
+}
+
+/*
+ * Helper function for arc_prune_async() it is responsible for safely
+ * handling the execution of a registered arc_prune_func_t.
+ */
+static void
+arc_prune_task(void *ptr)
+{
+	arc_prune_t *ap = (arc_prune_t *)ptr;
+	arc_prune_func_t *func = ap->p_pfunc;
+
+	if (func != NULL)
+		func(ap->p_adjust, ap->p_private);
+
+	/* Callback unregistered concurrently with execution */
+	if (refcount_remove(&ap->p_refcnt, func) == 0) {
+		ASSERT(!list_link_active(&ap->p_node));
+		refcount_destroy(&ap->p_refcnt);
+		kmem_free(ap, sizeof (*ap));
+	}
+}
+
+/*
+ * Notify registered consumers they must drop holds on a portion of the ARC
+ * buffered they reference.  This provides a mechanism to ensure the ARC can
+ * honor the arc_meta_limit and reclaim otherwise pinned ARC buffers.  This
+ * is analogous to dnlc_reduce_cache() but more generic.
+ *
+ * This operation is performed asynchronously so it may be safely called
+ * in the context of the arc_reclaim_thread().  A reference is taken here
+ * for each registered arc_prune_t and the arc_prune_task() is responsible
+ * for releasing it once the registered arc_prune_func_t has completed.
+ */
+static void
+arc_prune_async(int64_t adjust)
+{
+	arc_prune_t *ap;
+
+	mutex_enter(&arc_prune_mtx);
+	for (ap = list_head(&arc_prune_list); ap != NULL;
+	    ap = list_next(&arc_prune_list, ap)) {
+
+		if (refcount_count(&ap->p_refcnt) >= 2)
+			continue;
+
+		refcount_add(&ap->p_refcnt, ap->p_pfunc);
+		ap->p_adjust = adjust;
+		taskq_dispatch(arc_prune_taskq, arc_prune_task, ap, TQ_SLEEP);
+		ARCSTAT_BUMP(arcstat_prune);
+	}
+	mutex_exit(&arc_prune_mtx);
+}
+
+/*
+ * Evict the specified number of bytes from the state specified,
+ * restricting eviction to the spa and type given. This function
+ * prevents us from trying to evict more from a state's list than
+ * is "evictable", and to skip evicting altogether when passed a
+ * negative value for "bytes". In contrast, arc_evict_state() will
+ * evict everything it can, when passed a negative value for "bytes".
+ */
+static uint64_t
+arc_adjust_impl(arc_state_t *state, uint64_t spa, int64_t bytes,
+    arc_buf_contents_t type)
+{
+	int64_t delta;
+
+	if (bytes > 0 && state->arcs_lsize[type] > 0) {
+		delta = MIN(state->arcs_lsize[type], bytes);
+		return (arc_evict_state(state, spa, delta, type));
+	}
+
+	return (0);
+}
+
+/*
+ * The goal of this function is to evict enough meta data buffers from the
+ * ARC in order to enforce the arc_meta_limit.  Achieving this is slightly
+ * more complicated than it appears because it is common for data buffers
+ * to have holds on meta data buffers.  In addition, dnode meta data buffers
+ * will be held by the dnodes in the block preventing them from being freed.
+ * This means we can't simply traverse the ARC and expect to always find
+ * enough unheld meta data buffer to release.
+ *
+ * Therefore, this function has been updated to make alternating passes
+ * over the ARC releasing data buffers and then newly unheld meta data
+ * buffers.  This ensures forward progress is maintained and arc_meta_used
+ * will decrease.  Normally this is sufficient, but if required the ARC
+ * will call the registered prune callbacks causing dentry and inodes to
+ * be dropped from the VFS cache.  This will make dnode meta data buffers
+ * available for reclaim.
+ */
+static uint64_t
+arc_adjust_meta_balanced(void)
+{
+	int64_t adjustmnt, delta, prune = 0;
+	uint64_t total_evicted = 0;
+	arc_buf_contents_t type = ARC_BUFC_DATA;
+	int restarts = MAX(zfs_arc_meta_adjust_restarts, 0);
+
+restart:
+	/*
+	 * This slightly differs than the way we evict from the mru in
+	 * arc_adjust because we don't have a "target" value (i.e. no
+	 * "meta" arc_p). As a result, I think we can completely
+	 * cannibalize the metadata in the MRU before we evict the
+	 * metadata from the MFU. I think we probably need to implement a
+	 * "metadata arc_p" value to do this properly.
+	 */
+	adjustmnt = arc_meta_used - arc_meta_limit;
+
+	if (adjustmnt > 0 && arc_mru->arcs_lsize[type] > 0) {
+		delta = MIN(arc_mru->arcs_lsize[type], adjustmnt);
+		total_evicted += arc_adjust_impl(arc_mru, 0, delta, type);
+		adjustmnt -= delta;
+	}
+
+	/*
+	 * We can't afford to recalculate adjustmnt here. If we do,
+	 * new metadata buffers can sneak into the MRU or ANON lists,
+	 * thus penalize the MFU metadata. Although the fudge factor is
+	 * small, it has been empirically shown to be significant for
+	 * certain workloads (e.g. creating many empty directories). As
+	 * such, we use the original calculation for adjustmnt, and
+	 * simply decrement the amount of data evicted from the MRU.
+	 */
+
+	if (adjustmnt > 0 && arc_mfu->arcs_lsize[type] > 0) {
+		delta = MIN(arc_mfu->arcs_lsize[type], adjustmnt);
+		total_evicted += arc_adjust_impl(arc_mfu, 0, delta, type);
+	}
+
+	adjustmnt = arc_meta_used - arc_meta_limit;
+
+	if (adjustmnt > 0 && arc_mru_ghost->arcs_lsize[type] > 0) {
+		delta = MIN(adjustmnt,
+		    arc_mru_ghost->arcs_lsize[type]);
+		total_evicted += arc_adjust_impl(arc_mru_ghost, 0, delta, type);
+		adjustmnt -= delta;
+	}
+
+	if (adjustmnt > 0 && arc_mfu_ghost->arcs_lsize[type] > 0) {
+		delta = MIN(adjustmnt,
+		    arc_mfu_ghost->arcs_lsize[type]);
+		total_evicted += arc_adjust_impl(arc_mfu_ghost, 0, delta, type);
+	}
+
+	/*
+	 * If after attempting to make the requested adjustment to the ARC
+	 * the meta limit is still being exceeded then request that the
+	 * higher layers drop some cached objects which have holds on ARC
+	 * meta buffers.  Requests to the upper layers will be made with
+	 * increasingly large scan sizes until the ARC is below the limit.
+	 */
+	if (arc_meta_used > arc_meta_limit) {
+		if (type == ARC_BUFC_DATA) {
+			type = ARC_BUFC_METADATA;
+		} else {
+			type = ARC_BUFC_DATA;
+
+			if (zfs_arc_meta_prune) {
+				prune += zfs_arc_meta_prune;
+				arc_prune_async(prune);
+			}
+		}
+
+		if (restarts > 0) {
+			restarts--;
+			goto restart;
+		}
+	}
+	return (total_evicted);
+}
+
+/*
+ * Evict metadata buffers from the cache, such that arc_meta_used is
+ * capped by the arc_meta_limit tunable.
+ */
+static uint64_t
+arc_adjust_meta_only(void)
+{
+	uint64_t total_evicted = 0;
+	int64_t target;
+
+	/*
+	 * If we're over the meta limit, we want to evict enough
+	 * metadata to get back under the meta limit. We don't want to
+	 * evict so much that we drop the MRU below arc_p, though. If
+	 * we're over the meta limit more than we're over arc_p, we
+	 * evict some from the MRU here, and some from the MFU below.
+	 */
+	target = MIN((int64_t)(arc_meta_used - arc_meta_limit),
+	    (int64_t)(refcount_count(&arc_anon->arcs_size) +
+	    refcount_count(&arc_mru->arcs_size) - arc_p));
+
+	total_evicted += arc_adjust_impl(arc_mru, 0, target, ARC_BUFC_METADATA);
+
+	/*
+	 * Similar to the above, we want to evict enough bytes to get us
+	 * below the meta limit, but not so much as to drop us below the
+	 * space alloted to the MFU (which is defined as arc_c - arc_p).
+	 */
+	target = MIN((int64_t)(arc_meta_used - arc_meta_limit),
+	    (int64_t)(refcount_count(&arc_mfu->arcs_size) - (arc_c - arc_p)));
+
+	total_evicted += arc_adjust_impl(arc_mfu, 0, target, ARC_BUFC_METADATA);
+
+	return (total_evicted);
+}
+
+static uint64_t
+arc_adjust_meta(void)
+{
+	if (zfs_arc_meta_strategy == ARC_STRATEGY_META_ONLY)
+		return (arc_adjust_meta_only());
+	else
+		return (arc_adjust_meta_balanced());
+}
+
+/*
+ * Return the type of the oldest buffer in the given arc state
+ *
+ * This function will select a random sublist of type ARC_BUFC_DATA and
+ * a random sublist of type ARC_BUFC_METADATA. The tail of each sublist
+ * is compared, and the type which contains the "older" buffer will be
+ * returned.
+ */
+static arc_buf_contents_t
+arc_adjust_type(arc_state_t *state)
+{
+	multilist_t *data_ml = &state->arcs_list[ARC_BUFC_DATA];
+	multilist_t *meta_ml = &state->arcs_list[ARC_BUFC_METADATA];
+	int data_idx = multilist_get_random_index(data_ml);
+	int meta_idx = multilist_get_random_index(meta_ml);
+	multilist_sublist_t *data_mls;
+	multilist_sublist_t *meta_mls;
+	arc_buf_contents_t type;
+	arc_buf_hdr_t *data_hdr;
+	arc_buf_hdr_t *meta_hdr;
+
+	/*
+	 * We keep the sublist lock until we're finished, to prevent
+	 * the headers from being destroyed via arc_evict_state().
+	 */
+	data_mls = multilist_sublist_lock(data_ml, data_idx);
+	meta_mls = multilist_sublist_lock(meta_ml, meta_idx);
+
+	/*
+	 * These two loops are to ensure we skip any markers that
+	 * might be at the tail of the lists due to arc_evict_state().
+	 */
+
+	for (data_hdr = multilist_sublist_tail(data_mls); data_hdr != NULL;
+	    data_hdr = multilist_sublist_prev(data_mls, data_hdr)) {
+		if (data_hdr->b_spa != 0)
+			break;
+	}
+
+	for (meta_hdr = multilist_sublist_tail(meta_mls); meta_hdr != NULL;
+	    meta_hdr = multilist_sublist_prev(meta_mls, meta_hdr)) {
+		if (meta_hdr->b_spa != 0)
+			break;
+	}
+
+	if (data_hdr == NULL && meta_hdr == NULL) {
+		type = ARC_BUFC_DATA;
+	} else if (data_hdr == NULL) {
+		ASSERT3P(meta_hdr, !=, NULL);
+		type = ARC_BUFC_METADATA;
+	} else if (meta_hdr == NULL) {
+		ASSERT3P(data_hdr, !=, NULL);
+		type = ARC_BUFC_DATA;
+	} else {
+		ASSERT3P(data_hdr, !=, NULL);
+		ASSERT3P(meta_hdr, !=, NULL);
+
+		/* The headers can't be on the sublist without an L1 header */
+		ASSERT(HDR_HAS_L1HDR(data_hdr));
+		ASSERT(HDR_HAS_L1HDR(meta_hdr));
+
+		if (data_hdr->b_l1hdr.b_arc_access <
+		    meta_hdr->b_l1hdr.b_arc_access) {
+			type = ARC_BUFC_DATA;
+		} else {
+			type = ARC_BUFC_METADATA;
+		}
+	}
+
+	multilist_sublist_unlock(meta_mls);
+	multilist_sublist_unlock(data_mls);
+
+	return (type);
+}
+
+/*
+ * Evict buffers from the cache, such that arc_size is capped by arc_c.
+ */
+static uint64_t
+arc_adjust(void)
+{
+	uint64_t total_evicted = 0;
+	uint64_t bytes;
+	int64_t target;
+
+	/*
+	 * If we're over arc_meta_limit, we want to correct that before
+	 * potentially evicting data buffers below.
+	 */
+	total_evicted += arc_adjust_meta();
+
+	/*
+	 * Adjust MRU size
+	 *
+	 * If we're over the target cache size, we want to evict enough
+	 * from the list to get back to our target size. We don't want
+	 * to evict too much from the MRU, such that it drops below
+	 * arc_p. So, if we're over our target cache size more than
+	 * the MRU is over arc_p, we'll evict enough to get back to
+	 * arc_p here, and then evict more from the MFU below.
+	 */
+	target = MIN((int64_t)(arc_size - arc_c),
+	    (int64_t)(refcount_count(&arc_anon->arcs_size) +
+	    refcount_count(&arc_mru->arcs_size) + arc_meta_used - arc_p));
+
+	/*
+	 * If we're below arc_meta_min, always prefer to evict data.
+	 * Otherwise, try to satisfy the requested number of bytes to
+	 * evict from the type which contains older buffers; in an
+	 * effort to keep newer buffers in the cache regardless of their
+	 * type. If we cannot satisfy the number of bytes from this
+	 * type, spill over into the next type.
+	 */
+	if (arc_adjust_type(arc_mru) == ARC_BUFC_METADATA &&
+	    arc_meta_used > arc_meta_min) {
+		bytes = arc_adjust_impl(arc_mru, 0, target, ARC_BUFC_METADATA);
+		total_evicted += bytes;
+
+		/*
+		 * If we couldn't evict our target number of bytes from
+		 * metadata, we try to get the rest from data.
+		 */
+		target -= bytes;
+
+		total_evicted +=
+		    arc_adjust_impl(arc_mru, 0, target, ARC_BUFC_DATA);
+	} else {
+		bytes = arc_adjust_impl(arc_mru, 0, target, ARC_BUFC_DATA);
+		total_evicted += bytes;
+
+		/*
+		 * If we couldn't evict our target number of bytes from
+		 * data, we try to get the rest from metadata.
+		 */
+		target -= bytes;
+
+		total_evicted +=
+		    arc_adjust_impl(arc_mru, 0, target, ARC_BUFC_METADATA);
+	}
+
+	/*
+	 * Adjust MFU size
+	 *
+	 * Now that we've tried to evict enough from the MRU to get its
+	 * size back to arc_p, if we're still above the target cache
+	 * size, we evict the rest from the MFU.
+	 */
+	target = arc_size - arc_c;
+
+	if (arc_adjust_type(arc_mfu) == ARC_BUFC_METADATA &&
+	    arc_meta_used > arc_meta_min) {
+		bytes = arc_adjust_impl(arc_mfu, 0, target, ARC_BUFC_METADATA);
+		total_evicted += bytes;
+
+		/*
+		 * If we couldn't evict our target number of bytes from
+		 * metadata, we try to get the rest from data.
+		 */
+		target -= bytes;
+
+		total_evicted +=
+		    arc_adjust_impl(arc_mfu, 0, target, ARC_BUFC_DATA);
+	} else {
+		bytes = arc_adjust_impl(arc_mfu, 0, target, ARC_BUFC_DATA);
+		total_evicted += bytes;
+
+		/*
+		 * If we couldn't evict our target number of bytes from
+		 * data, we try to get the rest from data.
+		 */
+		target -= bytes;
+
+		total_evicted +=
+		    arc_adjust_impl(arc_mfu, 0, target, ARC_BUFC_METADATA);
+	}
+
+	/*
+	 * Adjust ghost lists
+	 *
+	 * In addition to the above, the ARC also defines target values
+	 * for the ghost lists. The sum of the mru list and mru ghost
+	 * list should never exceed the target size of the cache, and
+	 * the sum of the mru list, mfu list, mru ghost list, and mfu
+	 * ghost list should never exceed twice the target size of the
+	 * cache. The following logic enforces these limits on the ghost
+	 * caches, and evicts from them as needed.
+	 */
+	target = refcount_count(&arc_mru->arcs_size) +
+	    refcount_count(&arc_mru_ghost->arcs_size) - arc_c;
+
+	bytes = arc_adjust_impl(arc_mru_ghost, 0, target, ARC_BUFC_DATA);
+	total_evicted += bytes;
+
+	target -= bytes;
+
+	total_evicted +=
+	    arc_adjust_impl(arc_mru_ghost, 0, target, ARC_BUFC_METADATA);
+
+	/*
+	 * We assume the sum of the mru list and mfu list is less than
+	 * or equal to arc_c (we enforced this above), which means we
+	 * can use the simpler of the two equations below:
+	 *
+	 *	mru + mfu + mru ghost + mfu ghost <= 2 * arc_c
+	 *		    mru ghost + mfu ghost <= arc_c
+	 */
+	target = refcount_count(&arc_mru_ghost->arcs_size) +
+	    refcount_count(&arc_mfu_ghost->arcs_size) - arc_c;
+
+	bytes = arc_adjust_impl(arc_mfu_ghost, 0, target, ARC_BUFC_DATA);
+	total_evicted += bytes;
+
+	target -= bytes;
+
+	total_evicted +=
+	    arc_adjust_impl(arc_mfu_ghost, 0, target, ARC_BUFC_METADATA);
+
+	return (total_evicted);
+}
+
+static void
+arc_do_user_evicts(void)
+{
+	mutex_enter(&arc_user_evicts_lock);
+	while (arc_eviction_list != NULL) {
+		arc_buf_t *buf = arc_eviction_list;
+		arc_eviction_list = buf->b_next;
+		mutex_enter(&buf->b_evict_lock);
+		buf->b_hdr = NULL;
+		mutex_exit(&buf->b_evict_lock);
+		mutex_exit(&arc_user_evicts_lock);
+
+		if (buf->b_efunc != NULL)
+			VERIFY0(buf->b_efunc(buf->b_private));
+
+		buf->b_efunc = NULL;
+		buf->b_private = NULL;
+		kmem_cache_free(buf_cache, buf);
+		mutex_enter(&arc_user_evicts_lock);
+	}
+	mutex_exit(&arc_user_evicts_lock);
+}
+
+void
+arc_flush(spa_t *spa, boolean_t retry)
+{
+	uint64_t guid = 0;
+
+	/*
+	 * If retry is TRUE, a spa must not be specified since we have
+	 * no good way to determine if all of a spa's buffers have been
+	 * evicted from an arc state.
+	 */
+	ASSERT(!retry || spa == 0);
+
+	if (spa != NULL)
+		guid = spa_load_guid(spa);
+
+	(void) arc_flush_state(arc_mru, guid, ARC_BUFC_DATA, retry);
+	(void) arc_flush_state(arc_mru, guid, ARC_BUFC_METADATA, retry);
+
+	(void) arc_flush_state(arc_mfu, guid, ARC_BUFC_DATA, retry);
+	(void) arc_flush_state(arc_mfu, guid, ARC_BUFC_METADATA, retry);
+
+	(void) arc_flush_state(arc_mru_ghost, guid, ARC_BUFC_DATA, retry);
+	(void) arc_flush_state(arc_mru_ghost, guid, ARC_BUFC_METADATA, retry);
+
+	(void) arc_flush_state(arc_mfu_ghost, guid, ARC_BUFC_DATA, retry);
+	(void) arc_flush_state(arc_mfu_ghost, guid, ARC_BUFC_METADATA, retry);
+
+	arc_do_user_evicts();
+	ASSERT(spa || arc_eviction_list == NULL);
+}
+
+void
+arc_shrink(int64_t to_free)
+{
+	uint64_t c = arc_c;
+
+	if (c > to_free && c - to_free > arc_c_min) {
+		arc_c = c - to_free;
+		atomic_add_64(&arc_p, -(arc_p >> arc_shrink_shift));
+		if (arc_c > arc_size)
+			arc_c = MAX(arc_size, arc_c_min);
+		if (arc_p > arc_c)
+			arc_p = (arc_c >> 1);
+		ASSERT(arc_c >= arc_c_min);
+		ASSERT((int64_t)arc_p >= 0);
+	} else {
+		arc_c = arc_c_min;
+	}
+
+	if (arc_size > arc_c)
+		(void) arc_adjust();
+}
+
+typedef enum free_memory_reason_t {
+	FMR_UNKNOWN,
+	FMR_NEEDFREE,
+	FMR_LOTSFREE,
+	FMR_SWAPFS_MINFREE,
+	FMR_PAGES_PP_MAXIMUM,
+	FMR_HEAP_ARENA,
+	FMR_ZIO_ARENA,
+} free_memory_reason_t;
+
+int64_t last_free_memory;
+free_memory_reason_t last_free_reason;
+
+#ifdef _KERNEL
+/*
+ * Additional reserve of pages for pp_reserve.
+ */
+int64_t arc_pages_pp_reserve = 64;
+
+/*
+ * Additional reserve of pages for swapfs.
+ */
+int64_t arc_swapfs_reserve = 64;
+#endif /* _KERNEL */
+
+/*
+ * Return the amount of memory that can be consumed before reclaim will be
+ * needed.  Positive if there is sufficient free memory, negative indicates
+ * the amount of memory that needs to be freed up.
+ */
+static int64_t
+arc_available_memory(void)
+{
+	int64_t lowest = INT64_MAX;
+	free_memory_reason_t r = FMR_UNKNOWN;
+#ifdef _KERNEL
+	int64_t n;
+#ifdef __linux__
+	pgcnt_t needfree = btop(arc_need_free);
+	pgcnt_t lotsfree = btop(arc_sys_free);
+	pgcnt_t desfree = 0;
+#endif
+
+	if (needfree > 0) {
+		n = PAGESIZE * (-needfree);
+		if (n < lowest) {
+			lowest = n;
+			r = FMR_NEEDFREE;
+		}
+	}
+
+	/*
+	 * check that we're out of range of the pageout scanner.  It starts to
+	 * schedule paging if freemem is less than lotsfree and needfree.
+	 * lotsfree is the high-water mark for pageout, and needfree is the
+	 * number of needed free pages.  We add extra pages here to make sure
+	 * the scanner doesn't start up while we're freeing memory.
+	 */
+	n = PAGESIZE * (freemem - lotsfree - needfree - desfree);
+	if (n < lowest) {
+		lowest = n;
+		r = FMR_LOTSFREE;
+	}
+
+#ifndef __linux__
+	/*
+	 * check to make sure that swapfs has enough space so that anon
+	 * reservations can still succeed. anon_resvmem() checks that the
+	 * availrmem is greater than swapfs_minfree, and the number of reserved
+	 * swap pages.  We also add a bit of extra here just to prevent
+	 * circumstances from getting really dire.
+	 */
+	n = PAGESIZE * (availrmem - swapfs_minfree - swapfs_reserve -
+	    desfree - arc_swapfs_reserve);
+	if (n < lowest) {
+		lowest = n;
+		r = FMR_SWAPFS_MINFREE;
+	}
+
+
+	/*
+	 * Check that we have enough availrmem that memory locking (e.g., via
+	 * mlock(3C) or memcntl(2)) can still succeed.  (pages_pp_maximum
+	 * stores the number of pages that cannot be locked; when availrmem
+	 * drops below pages_pp_maximum, page locking mechanisms such as
+	 * page_pp_lock() will fail.)
+	 */
+	n = PAGESIZE * (availrmem - pages_pp_maximum -
+	    arc_pages_pp_reserve);
+	if (n < lowest) {
+		lowest = n;
+		r = FMR_PAGES_PP_MAXIMUM;
+	}
+#endif
+
+#if defined(__i386)
+	/*
+	 * If we're on an i386 platform, it's possible that we'll exhaust the
+	 * kernel heap space before we ever run out of available physical
+	 * memory.  Most checks of the size of the heap_area compare against
+	 * tune.t_minarmem, which is the minimum available real memory that we
+	 * can have in the system.  However, this is generally fixed at 25 pages
+	 * which is so low that it's useless.  In this comparison, we seek to
+	 * calculate the total heap-size, and reclaim if more than 3/4ths of the
+	 * heap is allocated.  (Or, in the calculation, if less than 1/4th is
+	 * free)
+	 */
+	n = vmem_size(heap_arena, VMEM_FREE) -
+	    (vmem_size(heap_arena, VMEM_FREE | VMEM_ALLOC) >> 2);
+	if (n < lowest) {
+		lowest = n;
+		r = FMR_HEAP_ARENA;
+	}
+#endif
+
+	/*
+	 * If zio data pages are being allocated out of a separate heap segment,
+	 * then enforce that the size of available vmem for this arena remains
+	 * above about 1/16th free.
+	 *
+	 * Note: The 1/16th arena free requirement was put in place
+	 * to aggressively evict memory from the arc in order to avoid
+	 * memory fragmentation issues.
+	 */
+	if (zio_arena != NULL) {
+		n = vmem_size(zio_arena, VMEM_FREE) -
+		    (vmem_size(zio_arena, VMEM_ALLOC) >> 4);
+		if (n < lowest) {
+			lowest = n;
+			r = FMR_ZIO_ARENA;
+		}
+	}
+#else /* _KERNEL */
+	/* Every 100 calls, free a small amount */
+	if (spa_get_random(100) == 0)
+		lowest = -1024;
+#endif /* _KERNEL */
+
+	last_free_memory = lowest;
+	last_free_reason = r;
+
+	return (lowest);
+}
+
+/*
+ * Determine if the system is under memory pressure and is asking
+ * to reclaim memory. A return value of TRUE indicates that the system
+ * is under memory pressure and that the arc should adjust accordingly.
+ */
+static boolean_t
+arc_reclaim_needed(void)
+{
+	return (arc_available_memory() < 0);
+}
+
+static void
+arc_kmem_reap_now(void)
+{
+	size_t			i;
+	kmem_cache_t		*prev_cache = NULL;
+	kmem_cache_t		*prev_data_cache = NULL;
+	extern kmem_cache_t	*zio_buf_cache[];
+	extern kmem_cache_t	*zio_data_buf_cache[];
+	extern kmem_cache_t	*range_seg_cache;
+
+	if ((arc_meta_used >= arc_meta_limit) && zfs_arc_meta_prune) {
+		/*
+		 * We are exceeding our meta-data cache limit.
+		 * Prune some entries to release holds on meta-data.
+		 */
+		arc_prune_async(zfs_arc_meta_prune);
+	}
+
+	for (i = 0; i < SPA_MAXBLOCKSIZE >> SPA_MINBLOCKSHIFT; i++) {
+#ifdef _ILP32
+		/* reach upper limit of cache size on 32-bit */
+		if (zio_buf_cache[i] == NULL)
+			break;
+#endif
+		if (zio_buf_cache[i] != prev_cache) {
+			prev_cache = zio_buf_cache[i];
+			kmem_cache_reap_now(zio_buf_cache[i]);
+		}
+		if (zio_data_buf_cache[i] != prev_data_cache) {
+			prev_data_cache = zio_data_buf_cache[i];
+			kmem_cache_reap_now(zio_data_buf_cache[i]);
+		}
+	}
+	kmem_cache_reap_now(buf_cache);
+	kmem_cache_reap_now(hdr_full_cache);
+	kmem_cache_reap_now(hdr_l2only_cache);
+	kmem_cache_reap_now(range_seg_cache);
+
+	if (zio_arena != NULL) {
+		/*
+		 * Ask the vmem arena to reclaim unused memory from its
+		 * quantum caches.
+		 */
+		vmem_qcache_reap(zio_arena);
+	}
+}
+
+/*
+ * Threads can block in arc_get_data_buf() waiting for this thread to evict
+ * enough data and signal them to proceed. When this happens, the threads in
+ * arc_get_data_buf() are sleeping while holding the hash lock for their
+ * particular arc header. Thus, we must be careful to never sleep on a
+ * hash lock in this thread. This is to prevent the following deadlock:
+ *
+ *  - Thread A sleeps on CV in arc_get_data_buf() holding hash lock "L",
+ *    waiting for the reclaim thread to signal it.
+ *
+ *  - arc_reclaim_thread() tries to acquire hash lock "L" using mutex_enter,
+ *    fails, and goes to sleep forever.
+ *
+ * This possible deadlock is avoided by always acquiring a hash lock
+ * using mutex_tryenter() from arc_reclaim_thread().
+ */
+static void
+arc_reclaim_thread(void)
+{
+	fstrans_cookie_t	cookie = spl_fstrans_mark();
+	clock_t			growtime = 0;
+	callb_cpr_t		cpr;
+
+	CALLB_CPR_INIT(&cpr, &arc_reclaim_lock, callb_generic_cpr, FTAG);
+
+	mutex_enter(&arc_reclaim_lock);
+	while (!arc_reclaim_thread_exit) {
+		int64_t to_free;
+		int64_t free_memory = arc_available_memory();
+		uint64_t evicted = 0;
+
+		arc_tuning_update();
+
+		mutex_exit(&arc_reclaim_lock);
+
+		if (free_memory < 0) {
+
+			arc_no_grow = B_TRUE;
+			arc_warm = B_TRUE;
+
+			/*
+			 * Wait at least zfs_grow_retry (default 5) seconds
+			 * before considering growing.
+			 */
+			growtime = ddi_get_lbolt() + (arc_grow_retry * hz);
+
+			arc_kmem_reap_now();
+
+			/*
+			 * If we are still low on memory, shrink the ARC
+			 * so that we have arc_shrink_min free space.
+			 */
+			free_memory = arc_available_memory();
+
+			to_free = (arc_c >> arc_shrink_shift) - free_memory;
+			if (to_free > 0) {
+#ifdef _KERNEL
+				to_free = MAX(to_free, arc_need_free);
+#endif
+				arc_shrink(to_free);
+			}
+		} else if (free_memory < arc_c >> arc_no_grow_shift) {
+			arc_no_grow = B_TRUE;
+		} else if (ddi_get_lbolt() >= growtime) {
+			arc_no_grow = B_FALSE;
+		}
+
+		evicted = arc_adjust();
+
+		mutex_enter(&arc_reclaim_lock);
+
+		/*
+		 * If evicted is zero, we couldn't evict anything via
+		 * arc_adjust(). This could be due to hash lock
+		 * collisions, but more likely due to the majority of
+		 * arc buffers being unevictable. Therefore, even if
+		 * arc_size is above arc_c, another pass is unlikely to
+		 * be helpful and could potentially cause us to enter an
+		 * infinite loop.
+		 */
+		if (arc_size <= arc_c || evicted == 0) {
+			/*
+			 * We're either no longer overflowing, or we
+			 * can't evict anything more, so we should wake
+			 * up any threads before we go to sleep and clear
+			 * arc_need_free since nothing more can be done.
+			 */
+			cv_broadcast(&arc_reclaim_waiters_cv);
+			arc_need_free = 0;
+
+			/*
+			 * Block until signaled, or after one second (we
+			 * might need to perform arc_kmem_reap_now()
+			 * even if we aren't being signalled)
+			 */
+			CALLB_CPR_SAFE_BEGIN(&cpr);
+			(void) cv_timedwait_sig(&arc_reclaim_thread_cv,
+			    &arc_reclaim_lock, ddi_get_lbolt() + hz);
+			CALLB_CPR_SAFE_END(&cpr, &arc_reclaim_lock);
+		}
+	}
+
+	arc_reclaim_thread_exit = FALSE;
+	cv_broadcast(&arc_reclaim_thread_cv);
+	CALLB_CPR_EXIT(&cpr);		/* drops arc_reclaim_lock */
+	spl_fstrans_unmark(cookie);
+	thread_exit();
+}
+
+static void
+arc_user_evicts_thread(void)
+{
+	fstrans_cookie_t	cookie = spl_fstrans_mark();
+	callb_cpr_t cpr;
+
+	CALLB_CPR_INIT(&cpr, &arc_user_evicts_lock, callb_generic_cpr, FTAG);
+
+	mutex_enter(&arc_user_evicts_lock);
+	while (!arc_user_evicts_thread_exit) {
+		mutex_exit(&arc_user_evicts_lock);
+
+		arc_do_user_evicts();
+
+		/*
+		 * This is necessary in order for the mdb ::arc dcmd to
+		 * show up to date information. Since the ::arc command
+		 * does not call the kstat's update function, without
+		 * this call, the command may show stale stats for the
+		 * anon, mru, mru_ghost, mfu, and mfu_ghost lists. Even
+		 * with this change, the data might be up to 1 second
+		 * out of date; but that should suffice. The arc_state_t
+		 * structures can be queried directly if more accurate
+		 * information is needed.
+		 */
+		if (arc_ksp != NULL)
+			arc_ksp->ks_update(arc_ksp, KSTAT_READ);
+
+		mutex_enter(&arc_user_evicts_lock);
+
+		/*
+		 * Block until signaled, or after one second (we need to
+		 * call the arc's kstat update function regularly).
+		 */
+		CALLB_CPR_SAFE_BEGIN(&cpr);
+		(void) cv_timedwait_sig(&arc_user_evicts_cv,
+		    &arc_user_evicts_lock, ddi_get_lbolt() + hz);
+		CALLB_CPR_SAFE_END(&cpr, &arc_user_evicts_lock);
+	}
+
+	arc_user_evicts_thread_exit = FALSE;
+	cv_broadcast(&arc_user_evicts_cv);
+	CALLB_CPR_EXIT(&cpr);		/* drops arc_user_evicts_lock */
+	spl_fstrans_unmark(cookie);
+	thread_exit();
+}
+
+#ifdef _KERNEL
+/*
+ * Determine the amount of memory eligible for eviction contained in the
+ * ARC. All clean data reported by the ghost lists can always be safely
+ * evicted. Due to arc_c_min, the same does not hold for all clean data
+ * contained by the regular mru and mfu lists.
+ *
+ * In the case of the regular mru and mfu lists, we need to report as
+ * much clean data as possible, such that evicting that same reported
+ * data will not bring arc_size below arc_c_min. Thus, in certain
+ * circumstances, the total amount of clean data in the mru and mfu
+ * lists might not actually be evictable.
+ *
+ * The following two distinct cases are accounted for:
+ *
+ * 1. The sum of the amount of dirty data contained by both the mru and
+ *    mfu lists, plus the ARC's other accounting (e.g. the anon list),
+ *    is greater than or equal to arc_c_min.
+ *    (i.e. amount of dirty data >= arc_c_min)
+ *
+ *    This is the easy case; all clean data contained by the mru and mfu
+ *    lists is evictable. Evicting all clean data can only drop arc_size
+ *    to the amount of dirty data, which is greater than arc_c_min.
+ *
+ * 2. The sum of the amount of dirty data contained by both the mru and
+ *    mfu lists, plus the ARC's other accounting (e.g. the anon list),
+ *    is less than arc_c_min.
+ *    (i.e. arc_c_min > amount of dirty data)
+ *
+ *    2.1. arc_size is greater than or equal arc_c_min.
+ *         (i.e. arc_size >= arc_c_min > amount of dirty data)
+ *
+ *         In this case, not all clean data from the regular mru and mfu
+ *         lists is actually evictable; we must leave enough clean data
+ *         to keep arc_size above arc_c_min. Thus, the maximum amount of
+ *         evictable data from the two lists combined, is exactly the
+ *         difference between arc_size and arc_c_min.
+ *
+ *    2.2. arc_size is less than arc_c_min
+ *         (i.e. arc_c_min > arc_size > amount of dirty data)
+ *
+ *         In this case, none of the data contained in the mru and mfu
+ *         lists is evictable, even if it's clean. Since arc_size is
+ *         already below arc_c_min, evicting any more would only
+ *         increase this negative difference.
+ */
+static uint64_t
+arc_evictable_memory(void) {
+	uint64_t arc_clean =
+	    arc_mru->arcs_lsize[ARC_BUFC_DATA] +
+	    arc_mru->arcs_lsize[ARC_BUFC_METADATA] +
+	    arc_mfu->arcs_lsize[ARC_BUFC_DATA] +
+	    arc_mfu->arcs_lsize[ARC_BUFC_METADATA];
+	uint64_t ghost_clean =
+	    arc_mru_ghost->arcs_lsize[ARC_BUFC_DATA] +
+	    arc_mru_ghost->arcs_lsize[ARC_BUFC_METADATA] +
+	    arc_mfu_ghost->arcs_lsize[ARC_BUFC_DATA] +
+	    arc_mfu_ghost->arcs_lsize[ARC_BUFC_METADATA];
+	uint64_t arc_dirty = MAX((int64_t)arc_size - (int64_t)arc_clean, 0);
+
+	if (arc_dirty >= arc_c_min)
+		return (ghost_clean + arc_clean);
+
+	return (ghost_clean + MAX((int64_t)arc_size - (int64_t)arc_c_min, 0));
+}
+
+/*
+ * If sc->nr_to_scan is zero, the caller is requesting a query of the
+ * number of objects which can potentially be freed.  If it is nonzero,
+ * the request is to free that many objects.
+ *
+ * Linux kernels >= 3.12 have the count_objects and scan_objects callbacks
+ * in struct shrinker and also require the shrinker to return the number
+ * of objects freed.
+ *
+ * Older kernels require the shrinker to return the number of freeable
+ * objects following the freeing of nr_to_free.
+ */
+static spl_shrinker_t
+__arc_shrinker_func(struct shrinker *shrink, struct shrink_control *sc)
+{
+	int64_t pages;
+
+	/* The arc is considered warm once reclaim has occurred */
+	if (unlikely(arc_warm == B_FALSE))
+		arc_warm = B_TRUE;
+
+	/* Return the potential number of reclaimable pages */
+	pages = btop((int64_t)arc_evictable_memory());
+	if (sc->nr_to_scan == 0)
+		return (pages);
+
+	/* Not allowed to perform filesystem reclaim */
+	if (!(sc->gfp_mask & __GFP_FS))
+		return (SHRINK_STOP);
+
+	/* Reclaim in progress */
+	if (mutex_tryenter(&arc_reclaim_lock) == 0)
+		return (SHRINK_STOP);
+
+	mutex_exit(&arc_reclaim_lock);
+
+	/*
+	 * Evict the requested number of pages by shrinking arc_c the
+	 * requested amount.  If there is nothing left to evict just
+	 * reap whatever we can from the various arc slabs.
+	 */
+	if (pages > 0) {
+		arc_shrink(ptob(sc->nr_to_scan));
+		arc_kmem_reap_now();
+#ifdef HAVE_SPLIT_SHRINKER_CALLBACK
+		pages = MAX(pages - btop(arc_evictable_memory()), 0);
+#else
+		pages = btop(arc_evictable_memory());
+#endif
+	} else {
+		arc_kmem_reap_now();
+		pages = SHRINK_STOP;
+	}
+
+	/*
+	 * We've reaped what we can, wake up threads.
+	 */
+	cv_broadcast(&arc_reclaim_waiters_cv);
+
+	/*
+	 * When direct reclaim is observed it usually indicates a rapid
+	 * increase in memory pressure.  This occurs because the kswapd
+	 * threads were unable to asynchronously keep enough free memory
+	 * available.  In this case set arc_no_grow to briefly pause arc
+	 * growth to avoid compounding the memory pressure.
+	 */
+	if (current_is_kswapd()) {
+		ARCSTAT_BUMP(arcstat_memory_indirect_count);
+	} else {
+		arc_no_grow = B_TRUE;
+		arc_need_free = ptob(sc->nr_to_scan);
+		ARCSTAT_BUMP(arcstat_memory_direct_count);
+	}
+
+	return (pages);
+}
+SPL_SHRINKER_CALLBACK_WRAPPER(arc_shrinker_func);
+
+SPL_SHRINKER_DECLARE(arc_shrinker, arc_shrinker_func, DEFAULT_SEEKS);
+#endif /* _KERNEL */
+
+/*
+ * Adapt arc info given the number of bytes we are trying to add and
+ * the state that we are comming from.  This function is only called
+ * when we are adding new content to the cache.
+ */
+static void
+arc_adapt(int bytes, arc_state_t *state)
+{
+	int mult;
+	uint64_t arc_p_min = (arc_c >> arc_p_min_shift);
+	int64_t mrug_size = refcount_count(&arc_mru_ghost->arcs_size);
+	int64_t mfug_size = refcount_count(&arc_mfu_ghost->arcs_size);
+
+	if (state == arc_l2c_only)
+		return;
+
+	ASSERT(bytes > 0);
+	/*
+	 * Adapt the target size of the MRU list:
+	 *	- if we just hit in the MRU ghost list, then increase
+	 *	  the target size of the MRU list.
+	 *	- if we just hit in the MFU ghost list, then increase
+	 *	  the target size of the MFU list by decreasing the
+	 *	  target size of the MRU list.
+	 */
+	if (state == arc_mru_ghost) {
+		mult = (mrug_size >= mfug_size) ? 1 : (mfug_size / mrug_size);
+		if (!zfs_arc_p_dampener_disable)
+			mult = MIN(mult, 10); /* avoid wild arc_p adjustment */
+
+		arc_p = MIN(arc_c - arc_p_min, arc_p + bytes * mult);
+	} else if (state == arc_mfu_ghost) {
+		uint64_t delta;
+
+		mult = (mfug_size >= mrug_size) ? 1 : (mrug_size / mfug_size);
+		if (!zfs_arc_p_dampener_disable)
+			mult = MIN(mult, 10);
+
+		delta = MIN(bytes * mult, arc_p);
+		arc_p = MAX(arc_p_min, arc_p - delta);
+	}
+	ASSERT((int64_t)arc_p >= 0);
+
+	if (arc_reclaim_needed()) {
+		cv_signal(&arc_reclaim_thread_cv);
+		return;
+	}
+
+	if (arc_no_grow)
+		return;
+
+	if (arc_c >= arc_c_max)
+		return;
+
+	/*
+	 * If we're within (2 * maxblocksize) bytes of the target
+	 * cache size, increment the target cache size
+	 */
+	ASSERT3U(arc_c, >=, 2ULL << SPA_MAXBLOCKSHIFT);
+	if (arc_size >= arc_c - (2ULL << SPA_MAXBLOCKSHIFT)) {
+		atomic_add_64(&arc_c, (int64_t)bytes);
+		if (arc_c > arc_c_max)
+			arc_c = arc_c_max;
+		else if (state == arc_anon)
+			atomic_add_64(&arc_p, (int64_t)bytes);
+		if (arc_p > arc_c)
+			arc_p = arc_c;
+	}
+	ASSERT((int64_t)arc_p >= 0);
+}
+
+/*
+ * Check if arc_size has grown past our upper threshold, determined by
+ * zfs_arc_overflow_shift.
+ */
+static boolean_t
+arc_is_overflowing(void)
+{
+	/* Always allow at least one block of overflow */
+	uint64_t overflow = MAX(SPA_MAXBLOCKSIZE,
+	    arc_c >> zfs_arc_overflow_shift);
+
+	return (arc_size >= arc_c + overflow);
+}
+
+/*
+ * The buffer, supplied as the first argument, needs a data block. If we
+ * are hitting the hard limit for the cache size, we must sleep, waiting
+ * for the eviction thread to catch up. If we're past the target size
+ * but below the hard limit, we'll only signal the reclaim thread and
+ * continue on.
+ */
+static void
+arc_get_data_buf(arc_buf_t *buf)
+{
+	arc_state_t		*state = buf->b_hdr->b_l1hdr.b_state;
+	uint64_t		size = buf->b_hdr->b_size;
+	arc_buf_contents_t	type = arc_buf_type(buf->b_hdr);
+
+	arc_adapt(size, state);
+
+	/*
+	 * If arc_size is currently overflowing, and has grown past our
+	 * upper limit, we must be adding data faster than the evict
+	 * thread can evict. Thus, to ensure we don't compound the
+	 * problem by adding more data and forcing arc_size to grow even
+	 * further past it's target size, we halt and wait for the
+	 * eviction thread to catch up.
+	 *
+	 * It's also possible that the reclaim thread is unable to evict
+	 * enough buffers to get arc_size below the overflow limit (e.g.
+	 * due to buffers being un-evictable, or hash lock collisions).
+	 * In this case, we want to proceed regardless if we're
+	 * overflowing; thus we don't use a while loop here.
+	 */
+	if (arc_is_overflowing()) {
+		mutex_enter(&arc_reclaim_lock);
+
+		/*
+		 * Now that we've acquired the lock, we may no longer be
+		 * over the overflow limit, lets check.
+		 *
+		 * We're ignoring the case of spurious wake ups. If that
+		 * were to happen, it'd let this thread consume an ARC
+		 * buffer before it should have (i.e. before we're under
+		 * the overflow limit and were signalled by the reclaim
+		 * thread). As long as that is a rare occurrence, it
+		 * shouldn't cause any harm.
+		 */
+		if (arc_is_overflowing()) {
+			cv_signal(&arc_reclaim_thread_cv);
+			cv_wait(&arc_reclaim_waiters_cv, &arc_reclaim_lock);
+		}
+
+		mutex_exit(&arc_reclaim_lock);
+	}
+
+	if (type == ARC_BUFC_METADATA) {
+		buf->b_data = zio_buf_alloc(size);
+		arc_space_consume(size, ARC_SPACE_META);
+	} else {
+		ASSERT(type == ARC_BUFC_DATA);
+		buf->b_data = zio_data_buf_alloc(size);
+		arc_space_consume(size, ARC_SPACE_DATA);
+	}
+
+	/*
+	 * Update the state size.  Note that ghost states have a
+	 * "ghost size" and so don't need to be updated.
+	 */
+	if (!GHOST_STATE(buf->b_hdr->b_l1hdr.b_state)) {
+		arc_buf_hdr_t *hdr = buf->b_hdr;
+		arc_state_t *state = hdr->b_l1hdr.b_state;
+
+		(void) refcount_add_many(&state->arcs_size, size, buf);
+
+		/*
+		 * If this is reached via arc_read, the link is
+		 * protected by the hash lock. If reached via
+		 * arc_buf_alloc, the header should not be accessed by
+		 * any other thread. And, if reached via arc_read_done,
+		 * the hash lock will protect it if it's found in the
+		 * hash table; otherwise no other thread should be
+		 * trying to [add|remove]_reference it.
+		 */
+		if (multilist_link_active(&hdr->b_l1hdr.b_arc_node)) {
+			ASSERT(refcount_is_zero(&hdr->b_l1hdr.b_refcnt));
+			atomic_add_64(&hdr->b_l1hdr.b_state->arcs_lsize[type],
+			    size);
+		}
+		/*
+		 * If we are growing the cache, and we are adding anonymous
+		 * data, and we have outgrown arc_p, update arc_p
+		 */
+		if (arc_size < arc_c && hdr->b_l1hdr.b_state == arc_anon &&
+		    (refcount_count(&arc_anon->arcs_size) +
+		    refcount_count(&arc_mru->arcs_size) > arc_p))
+			arc_p = MIN(arc_c, arc_p + size);
+	}
+}
+
+/*
+ * This routine is called whenever a buffer is accessed.
+ * NOTE: the hash lock is dropped in this function.
+ */
+static void
+arc_access(arc_buf_hdr_t *hdr, kmutex_t *hash_lock)
+{
+	clock_t now;
+
+	ASSERT(MUTEX_HELD(hash_lock));
+	ASSERT(HDR_HAS_L1HDR(hdr));
+
+	if (hdr->b_l1hdr.b_state == arc_anon) {
+		/*
+		 * This buffer is not in the cache, and does not
+		 * appear in our "ghost" list.  Add the new buffer
+		 * to the MRU state.
+		 */
+
+		ASSERT0(hdr->b_l1hdr.b_arc_access);
+		hdr->b_l1hdr.b_arc_access = ddi_get_lbolt();
+		DTRACE_PROBE1(new_state__mru, arc_buf_hdr_t *, hdr);
+		arc_change_state(arc_mru, hdr, hash_lock);
+
+	} else if (hdr->b_l1hdr.b_state == arc_mru) {
+		now = ddi_get_lbolt();
+
+		/*
+		 * If this buffer is here because of a prefetch, then either:
+		 * - clear the flag if this is a "referencing" read
+		 *   (any subsequent access will bump this into the MFU state).
+		 * or
+		 * - move the buffer to the head of the list if this is
+		 *   another prefetch (to make it less likely to be evicted).
+		 */
+		if (HDR_PREFETCH(hdr)) {
+			if (refcount_count(&hdr->b_l1hdr.b_refcnt) == 0) {
+				/* link protected by hash lock */
+				ASSERT(multilist_link_active(
+				    &hdr->b_l1hdr.b_arc_node));
+			} else {
+				hdr->b_flags &= ~ARC_FLAG_PREFETCH;
+				atomic_inc_32(&hdr->b_l1hdr.b_mru_hits);
+				ARCSTAT_BUMP(arcstat_mru_hits);
+			}
+			hdr->b_l1hdr.b_arc_access = now;
+			return;
+		}
+
+		/*
+		 * This buffer has been "accessed" only once so far,
+		 * but it is still in the cache. Move it to the MFU
+		 * state.
+		 */
+		if (ddi_time_after(now, hdr->b_l1hdr.b_arc_access +
+		    ARC_MINTIME)) {
+			/*
+			 * More than 125ms have passed since we
+			 * instantiated this buffer.  Move it to the
+			 * most frequently used state.
+			 */
+			hdr->b_l1hdr.b_arc_access = now;
+			DTRACE_PROBE1(new_state__mfu, arc_buf_hdr_t *, hdr);
+			arc_change_state(arc_mfu, hdr, hash_lock);
+		}
+		atomic_inc_32(&hdr->b_l1hdr.b_mru_hits);
+		ARCSTAT_BUMP(arcstat_mru_hits);
+	} else if (hdr->b_l1hdr.b_state == arc_mru_ghost) {
+		arc_state_t	*new_state;
+		/*
+		 * This buffer has been "accessed" recently, but
+		 * was evicted from the cache.  Move it to the
+		 * MFU state.
+		 */
+
+		if (HDR_PREFETCH(hdr)) {
+			new_state = arc_mru;
+			if (refcount_count(&hdr->b_l1hdr.b_refcnt) > 0)
+				hdr->b_flags &= ~ARC_FLAG_PREFETCH;
+			DTRACE_PROBE1(new_state__mru, arc_buf_hdr_t *, hdr);
+		} else {
+			new_state = arc_mfu;
+			DTRACE_PROBE1(new_state__mfu, arc_buf_hdr_t *, hdr);
+		}
+
+		hdr->b_l1hdr.b_arc_access = ddi_get_lbolt();
+		arc_change_state(new_state, hdr, hash_lock);
+
+		atomic_inc_32(&hdr->b_l1hdr.b_mru_ghost_hits);
+		ARCSTAT_BUMP(arcstat_mru_ghost_hits);
+	} else if (hdr->b_l1hdr.b_state == arc_mfu) {
+		/*
+		 * This buffer has been accessed more than once and is
+		 * still in the cache.  Keep it in the MFU state.
+		 *
+		 * NOTE: an add_reference() that occurred when we did
+		 * the arc_read() will have kicked this off the list.
+		 * If it was a prefetch, we will explicitly move it to
+		 * the head of the list now.
+		 */
+		if ((HDR_PREFETCH(hdr)) != 0) {
+			ASSERT(refcount_is_zero(&hdr->b_l1hdr.b_refcnt));
+			/* link protected by hash_lock */
+			ASSERT(multilist_link_active(&hdr->b_l1hdr.b_arc_node));
+		}
+		atomic_inc_32(&hdr->b_l1hdr.b_mfu_hits);
+		ARCSTAT_BUMP(arcstat_mfu_hits);
+		hdr->b_l1hdr.b_arc_access = ddi_get_lbolt();
+	} else if (hdr->b_l1hdr.b_state == arc_mfu_ghost) {
+		arc_state_t	*new_state = arc_mfu;
+		/*
+		 * This buffer has been accessed more than once but has
+		 * been evicted from the cache.  Move it back to the
+		 * MFU state.
+		 */
+
+		if (HDR_PREFETCH(hdr)) {
+			/*
+			 * This is a prefetch access...
+			 * move this block back to the MRU state.
+			 */
+			ASSERT0(refcount_count(&hdr->b_l1hdr.b_refcnt));
+			new_state = arc_mru;
+		}
+
+		hdr->b_l1hdr.b_arc_access = ddi_get_lbolt();
+		DTRACE_PROBE1(new_state__mfu, arc_buf_hdr_t *, hdr);
+		arc_change_state(new_state, hdr, hash_lock);
+
+		atomic_inc_32(&hdr->b_l1hdr.b_mfu_ghost_hits);
+		ARCSTAT_BUMP(arcstat_mfu_ghost_hits);
+	} else if (hdr->b_l1hdr.b_state == arc_l2c_only) {
+		/*
+		 * This buffer is on the 2nd Level ARC.
+		 */
+
+		hdr->b_l1hdr.b_arc_access = ddi_get_lbolt();
+		DTRACE_PROBE1(new_state__mfu, arc_buf_hdr_t *, hdr);
+		arc_change_state(arc_mfu, hdr, hash_lock);
+	} else {
+		cmn_err(CE_PANIC, "invalid arc state 0x%p",
+		    hdr->b_l1hdr.b_state);
+	}
+}
+
+/* a generic arc_done_func_t which you can use */
+/* ARGSUSED */
+void
+arc_bcopy_func(zio_t *zio, arc_buf_t *buf, void *arg)
+{
+	if (zio == NULL || zio->io_error == 0)
+		bcopy(buf->b_data, arg, buf->b_hdr->b_size);
+	VERIFY(arc_buf_remove_ref(buf, arg));
+}
+
+/* a generic arc_done_func_t */
+void
+arc_getbuf_func(zio_t *zio, arc_buf_t *buf, void *arg)
+{
+	arc_buf_t **bufp = arg;
+	if (zio && zio->io_error) {
+		VERIFY(arc_buf_remove_ref(buf, arg));
+		*bufp = NULL;
+	} else {
+		*bufp = buf;
+		ASSERT(buf->b_data);
+	}
+}
+
+static void
+arc_read_done(zio_t *zio)
+{
+	arc_buf_hdr_t	*hdr;
+	arc_buf_t	*buf;
+	arc_buf_t	*abuf;	/* buffer we're assigning to callback */
+	kmutex_t	*hash_lock = NULL;
+	arc_callback_t	*callback_list, *acb;
+	int		freeable = FALSE;
+
+	buf = zio->io_private;
+	hdr = buf->b_hdr;
+
+	/*
+	 * The hdr was inserted into hash-table and removed from lists
+	 * prior to starting I/O.  We should find this header, since
+	 * it's in the hash table, and it should be legit since it's
+	 * not possible to evict it during the I/O.  The only possible
+	 * reason for it not to be found is if we were freed during the
+	 * read.
+	 */
+	if (HDR_IN_HASH_TABLE(hdr)) {
+		arc_buf_hdr_t *found;
+
+		ASSERT3U(hdr->b_birth, ==, BP_PHYSICAL_BIRTH(zio->io_bp));
+		ASSERT3U(hdr->b_dva.dva_word[0], ==,
+		    BP_IDENTITY(zio->io_bp)->dva_word[0]);
+		ASSERT3U(hdr->b_dva.dva_word[1], ==,
+		    BP_IDENTITY(zio->io_bp)->dva_word[1]);
+
+		found = buf_hash_find(hdr->b_spa, zio->io_bp,
+		    &hash_lock);
+
+		ASSERT((found == NULL && HDR_FREED_IN_READ(hdr) &&
+		    hash_lock == NULL) ||
+		    (found == hdr &&
+		    DVA_EQUAL(&hdr->b_dva, BP_IDENTITY(zio->io_bp))) ||
+		    (found == hdr && HDR_L2_READING(hdr)));
+	}
+
+	hdr->b_flags &= ~ARC_FLAG_L2_EVICTED;
+	if (l2arc_noprefetch && HDR_PREFETCH(hdr))
+		hdr->b_flags &= ~ARC_FLAG_L2CACHE;
+
+	/* byteswap if necessary */
+	callback_list = hdr->b_l1hdr.b_acb;
+	ASSERT(callback_list != NULL);
+	if (BP_SHOULD_BYTESWAP(zio->io_bp) && zio->io_error == 0) {
+		dmu_object_byteswap_t bswap =
+		    DMU_OT_BYTESWAP(BP_GET_TYPE(zio->io_bp));
+		if (BP_GET_LEVEL(zio->io_bp) > 0)
+		    byteswap_uint64_array(buf->b_data, hdr->b_size);
+		else
+		    dmu_ot_byteswap[bswap].ob_func(buf->b_data, hdr->b_size);
+	}
+
+	arc_cksum_compute(buf, B_FALSE);
+	arc_buf_watch(buf);
+
+	if (hash_lock && zio->io_error == 0 &&
+	    hdr->b_l1hdr.b_state == arc_anon) {
+		/*
+		 * Only call arc_access on anonymous buffers.  This is because
+		 * if we've issued an I/O for an evicted buffer, we've already
+		 * called arc_access (to prevent any simultaneous readers from
+		 * getting confused).
+		 */
+		arc_access(hdr, hash_lock);
+	}
+
+	/* create copies of the data buffer for the callers */
+	abuf = buf;
+	for (acb = callback_list; acb; acb = acb->acb_next) {
+		if (acb->acb_done) {
+			if (abuf == NULL) {
+				ARCSTAT_BUMP(arcstat_duplicate_reads);
+				abuf = arc_buf_clone(buf);
+			}
+			acb->acb_buf = abuf;
+			abuf = NULL;
+		}
+	}
+	hdr->b_l1hdr.b_acb = NULL;
+	hdr->b_flags &= ~ARC_FLAG_IO_IN_PROGRESS;
+	ASSERT(!HDR_BUF_AVAILABLE(hdr));
+	if (abuf == buf) {
+		ASSERT(buf->b_efunc == NULL);
+		ASSERT(hdr->b_l1hdr.b_datacnt == 1);
+		hdr->b_flags |= ARC_FLAG_BUF_AVAILABLE;
+	}
+
+	ASSERT(refcount_is_zero(&hdr->b_l1hdr.b_refcnt) ||
+	    callback_list != NULL);
+
+	if (zio->io_error != 0) {
+		hdr->b_flags |= ARC_FLAG_IO_ERROR;
+		if (hdr->b_l1hdr.b_state != arc_anon)
+			arc_change_state(arc_anon, hdr, hash_lock);
+		if (HDR_IN_HASH_TABLE(hdr))
+			buf_hash_remove(hdr);
+		freeable = refcount_is_zero(&hdr->b_l1hdr.b_refcnt);
+	}
+
+	/*
+	 * Broadcast before we drop the hash_lock to avoid the possibility
+	 * that the hdr (and hence the cv) might be freed before we get to
+	 * the cv_broadcast().
+	 */
+	cv_broadcast(&hdr->b_l1hdr.b_cv);
+
+	if (hash_lock != NULL) {
+		mutex_exit(hash_lock);
+	} else {
+		/*
+		 * This block was freed while we waited for the read to
+		 * complete.  It has been removed from the hash table and
+		 * moved to the anonymous state (so that it won't show up
+		 * in the cache).
+		 */
+		ASSERT3P(hdr->b_l1hdr.b_state, ==, arc_anon);
+		freeable = refcount_is_zero(&hdr->b_l1hdr.b_refcnt);
+	}
+
+	/* execute each callback and free its structure */
+	while ((acb = callback_list) != NULL) {
+		if (acb->acb_done)
+			acb->acb_done(zio, acb->acb_buf, acb->acb_private);
+
+		if (acb->acb_zio_dummy != NULL) {
+			acb->acb_zio_dummy->io_error = zio->io_error;
+			zio_nowait(acb->acb_zio_dummy);
+		}
+
+		callback_list = acb->acb_next;
+		kmem_free(acb, sizeof (arc_callback_t));
+	}
+
+	if (freeable)
+		arc_hdr_destroy(hdr);
+}
+
+/*
+ * "Read" the block at the specified DVA (in bp) via the
+ * cache.  If the block is found in the cache, invoke the provided
+ * callback immediately and return.  Note that the `zio' parameter
+ * in the callback will be NULL in this case, since no IO was
+ * required.  If the block is not in the cache pass the read request
+ * on to the spa with a substitute callback function, so that the
+ * requested block will be added to the cache.
+ *
+ * If a read request arrives for a block that has a read in-progress,
+ * either wait for the in-progress read to complete (and return the
+ * results); or, if this is a read with a "done" func, add a record
+ * to the read to invoke the "done" func when the read completes,
+ * and return; or just return.
+ *
+ * arc_read_done() will invoke all the requested "done" functions
+ * for readers of this block.
+ */
+int
+arc_read(zio_t *pio, spa_t *spa, const blkptr_t *bp, arc_done_func_t *done,
+    void *private, zio_priority_t priority, int zio_flags,
+    arc_flags_t *arc_flags, const zbookmark_phys_t *zb)
+{
+	arc_buf_hdr_t *hdr = NULL;
+	arc_buf_t *buf = NULL;
+	kmutex_t *hash_lock = NULL;
+	zio_t *rzio;
+	uint64_t guid = spa_load_guid(spa);
+	int rc = 0;
+
+	ASSERT(!BP_IS_EMBEDDED(bp) ||
+	    BPE_GET_ETYPE(bp) == BP_EMBEDDED_TYPE_DATA);
+
+top:
+	if (!BP_IS_EMBEDDED(bp)) {
+		/*
+		 * Embedded BP's have no DVA and require no I/O to "read".
+		 * Create an anonymous arc buf to back it.
+		 */
+		hdr = buf_hash_find(guid, bp, &hash_lock);
+	}
+
+	if (hdr != NULL && HDR_HAS_L1HDR(hdr) && hdr->b_l1hdr.b_datacnt > 0) {
+
+		*arc_flags |= ARC_FLAG_CACHED;
+
+		if (HDR_IO_IN_PROGRESS(hdr)) {
+
+			if (*arc_flags & ARC_FLAG_WAIT) {
+				cv_wait(&hdr->b_l1hdr.b_cv, hash_lock);
+				mutex_exit(hash_lock);
+				goto top;
+			}
+			ASSERT(*arc_flags & ARC_FLAG_NOWAIT);
+
+			if (done) {
+				arc_callback_t	*acb = NULL;
+
+				acb = kmem_zalloc(sizeof (arc_callback_t),
+				    KM_SLEEP);
+				acb->acb_done = done;
+				acb->acb_private = private;
+				if (pio != NULL)
+					acb->acb_zio_dummy = zio_null(pio,
+					    spa, NULL, NULL, NULL, zio_flags);
+
+				ASSERT(acb->acb_done != NULL);
+				acb->acb_next = hdr->b_l1hdr.b_acb;
+				hdr->b_l1hdr.b_acb = acb;
+				add_reference(hdr, hash_lock, private);
+				mutex_exit(hash_lock);
+				goto out;
+			}
+			mutex_exit(hash_lock);
+			goto out;
+		}
+
+		ASSERT(hdr->b_l1hdr.b_state == arc_mru ||
+		    hdr->b_l1hdr.b_state == arc_mfu);
+
+		if (done) {
+			add_reference(hdr, hash_lock, private);
+			/*
+			 * If this block is already in use, create a new
+			 * copy of the data so that we will be guaranteed
+			 * that arc_release() will always succeed.
+			 */
+			buf = hdr->b_l1hdr.b_buf;
+			ASSERT(buf);
+			ASSERT(buf->b_data);
+			if (HDR_BUF_AVAILABLE(hdr)) {
+				ASSERT(buf->b_efunc == NULL);
+				hdr->b_flags &= ~ARC_FLAG_BUF_AVAILABLE;
+			} else {
+				buf = arc_buf_clone(buf);
+			}
+
+		} else if (*arc_flags & ARC_FLAG_PREFETCH &&
+		    refcount_count(&hdr->b_l1hdr.b_refcnt) == 0) {
+			hdr->b_flags |= ARC_FLAG_PREFETCH;
+		}
+		DTRACE_PROBE1(arc__hit, arc_buf_hdr_t *, hdr);
+		arc_access(hdr, hash_lock);
+		if (*arc_flags & ARC_FLAG_L2CACHE)
+			hdr->b_flags |= ARC_FLAG_L2CACHE;
+		if (*arc_flags & ARC_FLAG_L2COMPRESS)
+			hdr->b_flags |= ARC_FLAG_L2COMPRESS;
+		mutex_exit(hash_lock);
+		ARCSTAT_BUMP(arcstat_hits);
+		ARCSTAT_CONDSTAT(!HDR_PREFETCH(hdr),
+		    demand, prefetch, !HDR_ISTYPE_METADATA(hdr),
+		    data, metadata, hits);
+
+		if (done)
+			done(NULL, buf, private);
+	} else {
+		uint64_t size = BP_GET_LSIZE(bp);
+		arc_callback_t *acb;
+		vdev_t *vd = NULL;
+		uint64_t addr = 0;
+		boolean_t devw = B_FALSE;
+		enum zio_compress b_compress = ZIO_COMPRESS_OFF;
+		int32_t b_asize = 0;
+
+		/*
+		 * Gracefully handle a damaged logical block size as a
+		 * checksum error by passing a dummy zio to the done callback.
+		 */
+		if (size > spa_maxblocksize(spa)) {
+			if (done) {
+				rzio = zio_null(pio, spa, NULL,
+				    NULL, NULL, zio_flags);
+				rzio->io_error = ECKSUM;
+				done(rzio, buf, private);
+				zio_nowait(rzio);
+			}
+			rc = ECKSUM;
+			goto out;
+		}
+
+		if (hdr == NULL) {
+			/* this block is not in the cache */
+			arc_buf_hdr_t *exists = NULL;
+			arc_buf_contents_t type = BP_GET_BUFC_TYPE(bp);
+			buf = arc_buf_alloc(spa, size, private, type);
+			hdr = buf->b_hdr;
+			if (!BP_IS_EMBEDDED(bp)) {
+				hdr->b_dva = *BP_IDENTITY(bp);
+				hdr->b_birth = BP_PHYSICAL_BIRTH(bp);
+				exists = buf_hash_insert(hdr, &hash_lock);
+			}
+			if (exists != NULL) {
+				/* somebody beat us to the hash insert */
+				mutex_exit(hash_lock);
+				buf_discard_identity(hdr);
+				(void) arc_buf_remove_ref(buf, private);
+				goto top; /* restart the IO request */
+			}
+
+			/* if this is a prefetch, we don't have a reference */
+			if (*arc_flags & ARC_FLAG_PREFETCH) {
+				(void) remove_reference(hdr, hash_lock,
+				    private);
+				hdr->b_flags |= ARC_FLAG_PREFETCH;
+			}
+			if (*arc_flags & ARC_FLAG_L2CACHE)
+				hdr->b_flags |= ARC_FLAG_L2CACHE;
+			if (*arc_flags & ARC_FLAG_L2COMPRESS)
+				hdr->b_flags |= ARC_FLAG_L2COMPRESS;
+			if (BP_GET_LEVEL(bp) > 0)
+				hdr->b_flags |= ARC_FLAG_INDIRECT;
+		} else {
+			/*
+			 * This block is in the ghost cache. If it was L2-only
+			 * (and thus didn't have an L1 hdr), we realloc the
+			 * header to add an L1 hdr.
+			 */
+			if (!HDR_HAS_L1HDR(hdr)) {
+				hdr = arc_hdr_realloc(hdr, hdr_l2only_cache,
+				    hdr_full_cache);
+			}
+
+			ASSERT(GHOST_STATE(hdr->b_l1hdr.b_state));
+			ASSERT(!HDR_IO_IN_PROGRESS(hdr));
+			ASSERT(refcount_is_zero(&hdr->b_l1hdr.b_refcnt));
+			ASSERT3P(hdr->b_l1hdr.b_buf, ==, NULL);
+
+			/* if this is a prefetch, we don't have a reference */
+			if (*arc_flags & ARC_FLAG_PREFETCH)
+				hdr->b_flags |= ARC_FLAG_PREFETCH;
+			else
+				add_reference(hdr, hash_lock, private);
+			if (*arc_flags & ARC_FLAG_L2CACHE)
+				hdr->b_flags |= ARC_FLAG_L2CACHE;
+			if (*arc_flags & ARC_FLAG_L2COMPRESS)
+				hdr->b_flags |= ARC_FLAG_L2COMPRESS;
+			buf = kmem_cache_alloc(buf_cache, KM_PUSHPAGE);
+			buf->b_hdr = hdr;
+			buf->b_data = NULL;
+			buf->b_efunc = NULL;
+			buf->b_private = NULL;
+			buf->b_next = NULL;
+			hdr->b_l1hdr.b_buf = buf;
+			ASSERT0(hdr->b_l1hdr.b_datacnt);
+			hdr->b_l1hdr.b_datacnt = 1;
+			arc_get_data_buf(buf);
+			arc_access(hdr, hash_lock);
+		}
+
+		ASSERT(!GHOST_STATE(hdr->b_l1hdr.b_state));
+
+		acb = kmem_zalloc(sizeof (arc_callback_t), KM_SLEEP);
+		acb->acb_done = done;
+		acb->acb_private = private;
+
+		ASSERT(hdr->b_l1hdr.b_acb == NULL);
+		hdr->b_l1hdr.b_acb = acb;
+		hdr->b_flags |= ARC_FLAG_IO_IN_PROGRESS;
+
+		if (HDR_HAS_L2HDR(hdr) &&
+		    (vd = hdr->b_l2hdr.b_dev->l2ad_vdev) != NULL) {
+			devw = hdr->b_l2hdr.b_dev->l2ad_writing;
+			addr = hdr->b_l2hdr.b_daddr;
+			b_compress = hdr->b_l2hdr.b_compress;
+			b_asize = hdr->b_l2hdr.b_asize;
+			/*
+			 * Lock out device removal.
+			 */
+			if (vdev_is_dead(vd) ||
+			    !spa_config_tryenter(spa, SCL_L2ARC, vd, RW_READER))
+				vd = NULL;
+		}
+
+		if (hash_lock != NULL)
+			mutex_exit(hash_lock);
+
+		/*
+		 * At this point, we have a level 1 cache miss.  Try again in
+		 * L2ARC if possible.
+		 */
+		ASSERT3U(hdr->b_size, ==, size);
+		DTRACE_PROBE4(arc__miss, arc_buf_hdr_t *, hdr, blkptr_t *, bp,
+		    uint64_t, size, zbookmark_phys_t *, zb);
+		ARCSTAT_BUMP(arcstat_misses);
+		ARCSTAT_CONDSTAT(!HDR_PREFETCH(hdr),
+		    demand, prefetch, !HDR_ISTYPE_METADATA(hdr),
+		    data, metadata, misses);
+
+		if (vd != NULL && l2arc_ndev != 0 && !(l2arc_norw && devw)) {
+			/*
+			 * Read from the L2ARC if the following are true:
+			 * 1. The L2ARC vdev was previously cached.
+			 * 2. This buffer still has L2ARC metadata.
+			 * 3. This buffer isn't currently writing to the L2ARC.
+			 * 4. The L2ARC entry wasn't evicted, which may
+			 *    also have invalidated the vdev.
+			 * 5. This isn't prefetch and l2arc_noprefetch is set.
+			 */
+			if (HDR_HAS_L2HDR(hdr) &&
+			    !HDR_L2_WRITING(hdr) && !HDR_L2_EVICTED(hdr) &&
+			    !(l2arc_noprefetch && HDR_PREFETCH(hdr))) {
+				l2arc_read_callback_t *cb;
+
+				DTRACE_PROBE1(l2arc__hit, arc_buf_hdr_t *, hdr);
+				ARCSTAT_BUMP(arcstat_l2_hits);
+				atomic_inc_32(&hdr->b_l2hdr.b_hits);
+
+				cb = kmem_zalloc(sizeof (l2arc_read_callback_t),
+				    KM_SLEEP);
+				cb->l2rcb_buf = buf;
+				cb->l2rcb_spa = spa;
+				cb->l2rcb_bp = *bp;
+				cb->l2rcb_zb = *zb;
+				cb->l2rcb_flags = zio_flags;
+				cb->l2rcb_compress = b_compress;
+
+				ASSERT(addr >= VDEV_LABEL_START_SIZE &&
+				    addr + size < vd->vdev_psize -
+				    VDEV_LABEL_END_SIZE);
+
+				/*
+				 * l2arc read.  The SCL_L2ARC lock will be
+				 * released by l2arc_read_done().
+				 * Issue a null zio if the underlying buffer
+				 * was squashed to zero size by compression.
+				 */
+				if (b_compress == ZIO_COMPRESS_EMPTY) {
+					rzio = zio_null(pio, spa, vd,
+					    l2arc_read_done, cb,
+					    zio_flags | ZIO_FLAG_DONT_CACHE |
+					    ZIO_FLAG_CANFAIL |
+					    ZIO_FLAG_DONT_PROPAGATE |
+					    ZIO_FLAG_DONT_RETRY);
+				} else {
+					rzio = zio_read_phys(pio, vd, addr,
+					    b_asize, buf->b_data,
+					    ZIO_CHECKSUM_OFF,
+					    l2arc_read_done, cb, priority,
+					    zio_flags | ZIO_FLAG_DONT_CACHE |
+					    ZIO_FLAG_CANFAIL |
+					    ZIO_FLAG_DONT_PROPAGATE |
+					    ZIO_FLAG_DONT_RETRY, B_FALSE);
+				}
+				DTRACE_PROBE2(l2arc__read, vdev_t *, vd,
+				    zio_t *, rzio);
+				ARCSTAT_INCR(arcstat_l2_read_bytes, b_asize);
+
+				if (*arc_flags & ARC_FLAG_NOWAIT) {
+					zio_nowait(rzio);
+					goto out;
+				}
+
+				ASSERT(*arc_flags & ARC_FLAG_WAIT);
+				if (zio_wait(rzio) == 0)
+					goto out;
+
+				/* l2arc read error; goto zio_read() */
+			} else {
+				DTRACE_PROBE1(l2arc__miss,
+				    arc_buf_hdr_t *, hdr);
+				ARCSTAT_BUMP(arcstat_l2_misses);
+				if (HDR_L2_WRITING(hdr))
+					ARCSTAT_BUMP(arcstat_l2_rw_clash);
+				spa_config_exit(spa, SCL_L2ARC, vd);
+			}
+		} else {
+			if (vd != NULL)
+				spa_config_exit(spa, SCL_L2ARC, vd);
+			if (l2arc_ndev != 0) {
+				DTRACE_PROBE1(l2arc__miss,
+				    arc_buf_hdr_t *, hdr);
+				ARCSTAT_BUMP(arcstat_l2_misses);
+			}
+		}
+
+		rzio = zio_read(pio, spa, bp, buf->b_data, size,
+		    arc_read_done, buf, priority, zio_flags, zb);
+
+		if (*arc_flags & ARC_FLAG_WAIT) {
+			rc = zio_wait(rzio);
+			goto out;
+		}
+
+		ASSERT(*arc_flags & ARC_FLAG_NOWAIT);
+		zio_nowait(rzio);
+	}
+
+out:
+	spa_read_history_add(spa, zb, *arc_flags);
+	return (rc);
+}
+
+arc_prune_t *
+arc_add_prune_callback(arc_prune_func_t *func, void *private)
+{
+	arc_prune_t *p;
+
+	p = kmem_alloc(sizeof (*p), KM_SLEEP);
+	p->p_pfunc = func;
+	p->p_private = private;
+	list_link_init(&p->p_node);
+	refcount_create(&p->p_refcnt);
+
+	mutex_enter(&arc_prune_mtx);
+	refcount_add(&p->p_refcnt, &arc_prune_list);
+	list_insert_head(&arc_prune_list, p);
+	mutex_exit(&arc_prune_mtx);
+
+	return (p);
+}
+
+void
+arc_remove_prune_callback(arc_prune_t *p)
+{
+	mutex_enter(&arc_prune_mtx);
+	list_remove(&arc_prune_list, p);
+	if (refcount_remove(&p->p_refcnt, &arc_prune_list) == 0) {
+		refcount_destroy(&p->p_refcnt);
+		kmem_free(p, sizeof (*p));
+	}
+	mutex_exit(&arc_prune_mtx);
+}
+
+void
+arc_set_callback(arc_buf_t *buf, arc_evict_func_t *func, void *private)
+{
+	ASSERT(buf->b_hdr != NULL);
+	ASSERT(buf->b_hdr->b_l1hdr.b_state != arc_anon);
+	ASSERT(!refcount_is_zero(&buf->b_hdr->b_l1hdr.b_refcnt) ||
+	    func == NULL);
+	ASSERT(buf->b_efunc == NULL);
+	ASSERT(!HDR_BUF_AVAILABLE(buf->b_hdr));
+
+	buf->b_efunc = func;
+	buf->b_private = private;
+}
+
+/*
+ * Notify the arc that a block was freed, and thus will never be used again.
+ */
+void
+arc_freed(spa_t *spa, const blkptr_t *bp)
+{
+	arc_buf_hdr_t *hdr;
+	kmutex_t *hash_lock;
+	uint64_t guid = spa_load_guid(spa);
+
+	ASSERT(!BP_IS_EMBEDDED(bp));
+
+	hdr = buf_hash_find(guid, bp, &hash_lock);
+	if (hdr == NULL)
+		return;
+	if (HDR_BUF_AVAILABLE(hdr)) {
+		arc_buf_t *buf = hdr->b_l1hdr.b_buf;
+		add_reference(hdr, hash_lock, FTAG);
+		hdr->b_flags &= ~ARC_FLAG_BUF_AVAILABLE;
+		mutex_exit(hash_lock);
+
+		arc_release(buf, FTAG);
+		(void) arc_buf_remove_ref(buf, FTAG);
+	} else {
+		mutex_exit(hash_lock);
+	}
+
+}
+
+/*
+ * Clear the user eviction callback set by arc_set_callback(), first calling
+ * it if it exists.  Because the presence of a callback keeps an arc_buf cached
+ * clearing the callback may result in the arc_buf being destroyed.  However,
+ * it will not result in the *last* arc_buf being destroyed, hence the data
+ * will remain cached in the ARC. We make a copy of the arc buffer here so
+ * that we can process the callback without holding any locks.
+ *
+ * It's possible that the callback is already in the process of being cleared
+ * by another thread.  In this case we can not clear the callback.
+ *
+ * Returns B_TRUE if the callback was successfully called and cleared.
+ */
+boolean_t
+arc_clear_callback(arc_buf_t *buf)
+{
+	arc_buf_hdr_t *hdr;
+	kmutex_t *hash_lock;
+	arc_evict_func_t *efunc = buf->b_efunc;
+	void *private = buf->b_private;
+
+	mutex_enter(&buf->b_evict_lock);
+	hdr = buf->b_hdr;
+	if (hdr == NULL) {
+		/*
+		 * We are in arc_do_user_evicts().
+		 */
+		ASSERT(buf->b_data == NULL);
+		mutex_exit(&buf->b_evict_lock);
+		return (B_FALSE);
+	} else if (buf->b_data == NULL) {
+		/*
+		 * We are on the eviction list; process this buffer now
+		 * but let arc_do_user_evicts() do the reaping.
+		 */
+		buf->b_efunc = NULL;
+		mutex_exit(&buf->b_evict_lock);
+		VERIFY0(efunc(private));
+		return (B_TRUE);
+	}
+	hash_lock = HDR_LOCK(hdr);
+	mutex_enter(hash_lock);
+	hdr = buf->b_hdr;
+	ASSERT3P(hash_lock, ==, HDR_LOCK(hdr));
+
+	ASSERT3U(refcount_count(&hdr->b_l1hdr.b_refcnt), <,
+	    hdr->b_l1hdr.b_datacnt);
+	ASSERT(hdr->b_l1hdr.b_state == arc_mru ||
+	    hdr->b_l1hdr.b_state == arc_mfu);
+
+	buf->b_efunc = NULL;
+	buf->b_private = NULL;
+
+	if (hdr->b_l1hdr.b_datacnt > 1) {
+		mutex_exit(&buf->b_evict_lock);
+		arc_buf_destroy(buf, TRUE);
+	} else {
+		ASSERT(buf == hdr->b_l1hdr.b_buf);
+		hdr->b_flags |= ARC_FLAG_BUF_AVAILABLE;
+		mutex_exit(&buf->b_evict_lock);
+	}
+
+	mutex_exit(hash_lock);
+	VERIFY0(efunc(private));
+	return (B_TRUE);
+}
+
+/*
+ * Release this buffer from the cache, making it an anonymous buffer.  This
+ * must be done after a read and prior to modifying the buffer contents.
+ * If the buffer has more than one reference, we must make
+ * a new hdr for the buffer.
+ */
+void
+arc_release(arc_buf_t *buf, void *tag)
+{
+	kmutex_t *hash_lock;
+	arc_state_t *state;
+	arc_buf_hdr_t *hdr = buf->b_hdr;
+
+	/*
+	 * It would be nice to assert that if its DMU metadata (level >
+	 * 0 || it's the dnode file), then it must be syncing context.
+	 * But we don't know that information at this level.
+	 */
+
+	mutex_enter(&buf->b_evict_lock);
+
+	ASSERT(HDR_HAS_L1HDR(hdr));
+
+	/*
+	 * We don't grab the hash lock prior to this check, because if
+	 * the buffer's header is in the arc_anon state, it won't be
+	 * linked into the hash table.
+	 */
+	if (hdr->b_l1hdr.b_state == arc_anon) {
+		mutex_exit(&buf->b_evict_lock);
+		ASSERT(!HDR_IO_IN_PROGRESS(hdr));
+		ASSERT(!HDR_IN_HASH_TABLE(hdr));
+		ASSERT(!HDR_HAS_L2HDR(hdr));
+		ASSERT(BUF_EMPTY(hdr));
+
+		ASSERT3U(hdr->b_l1hdr.b_datacnt, ==, 1);
+		ASSERT3S(refcount_count(&hdr->b_l1hdr.b_refcnt), ==, 1);
+		ASSERT(!list_link_active(&hdr->b_l1hdr.b_arc_node));
+
+		ASSERT3P(buf->b_efunc, ==, NULL);
+		ASSERT3P(buf->b_private, ==, NULL);
+
+		hdr->b_l1hdr.b_arc_access = 0;
+		arc_buf_thaw(buf);
+
+		return;
+	}
+
+	hash_lock = HDR_LOCK(hdr);
+	mutex_enter(hash_lock);
+
+	/*
+	 * This assignment is only valid as long as the hash_lock is
+	 * held, we must be careful not to reference state or the
+	 * b_state field after dropping the lock.
+	 */
+	state = hdr->b_l1hdr.b_state;
+	ASSERT3P(hash_lock, ==, HDR_LOCK(hdr));
+	ASSERT3P(state, !=, arc_anon);
+
+	/* this buffer is not on any list */
+	ASSERT(refcount_count(&hdr->b_l1hdr.b_refcnt) > 0);
+
+	if (HDR_HAS_L2HDR(hdr)) {
+		mutex_enter(&hdr->b_l2hdr.b_dev->l2ad_mtx);
+
+		/*
+		 * We have to recheck this conditional again now that
+		 * we're holding the l2ad_mtx to prevent a race with
+		 * another thread which might be concurrently calling
+		 * l2arc_evict(). In that case, l2arc_evict() might have
+		 * destroyed the header's L2 portion as we were waiting
+		 * to acquire the l2ad_mtx.
+		 */
+		if (HDR_HAS_L2HDR(hdr))
+			arc_hdr_l2hdr_destroy(hdr);
+
+		mutex_exit(&hdr->b_l2hdr.b_dev->l2ad_mtx);
+	}
+
+	/*
+	 * Do we have more than one buf?
+	 */
+	if (hdr->b_l1hdr.b_datacnt > 1) {
+		arc_buf_hdr_t *nhdr;
+		arc_buf_t **bufp;
+		uint64_t blksz = hdr->b_size;
+		uint64_t spa = hdr->b_spa;
+		arc_buf_contents_t type = arc_buf_type(hdr);
+		uint32_t flags = hdr->b_flags;
+
+		ASSERT(hdr->b_l1hdr.b_buf != buf || buf->b_next != NULL);
+		/*
+		 * Pull the data off of this hdr and attach it to
+		 * a new anonymous hdr.
+		 */
+		(void) remove_reference(hdr, hash_lock, tag);
+		bufp = &hdr->b_l1hdr.b_buf;
+		while (*bufp != buf)
+			bufp = &(*bufp)->b_next;
+		*bufp = buf->b_next;
+		buf->b_next = NULL;
+
+		ASSERT3P(state, !=, arc_l2c_only);
+
+		(void) refcount_remove_many(
+		    &state->arcs_size, hdr->b_size, buf);
+
+		if (refcount_is_zero(&hdr->b_l1hdr.b_refcnt)) {
+			uint64_t *size;
+
+			ASSERT3P(state, !=, arc_l2c_only);
+			size = &state->arcs_lsize[type];
+			ASSERT3U(*size, >=, hdr->b_size);
+			atomic_add_64(size, -hdr->b_size);
+		}
+
+		/*
+		 * We're releasing a duplicate user data buffer, update
+		 * our statistics accordingly.
+		 */
+		if (HDR_ISTYPE_DATA(hdr)) {
+			ARCSTAT_BUMPDOWN(arcstat_duplicate_buffers);
+			ARCSTAT_INCR(arcstat_duplicate_buffers_size,
+			    -hdr->b_size);
+		}
+		hdr->b_l1hdr.b_datacnt -= 1;
+		arc_cksum_verify(buf);
+		arc_buf_unwatch(buf);
+
+		mutex_exit(hash_lock);
+
+		nhdr = kmem_cache_alloc(hdr_full_cache, KM_PUSHPAGE);
+		nhdr->b_size = blksz;
+		nhdr->b_spa = spa;
+
+		nhdr->b_l1hdr.b_mru_hits = 0;
+		nhdr->b_l1hdr.b_mru_ghost_hits = 0;
+		nhdr->b_l1hdr.b_mfu_hits = 0;
+		nhdr->b_l1hdr.b_mfu_ghost_hits = 0;
+		nhdr->b_l1hdr.b_l2_hits = 0;
+		nhdr->b_flags = flags & ARC_FLAG_L2_WRITING;
+		nhdr->b_flags |= arc_bufc_to_flags(type);
+		nhdr->b_flags |= ARC_FLAG_HAS_L1HDR;
+
+		nhdr->b_l1hdr.b_buf = buf;
+		nhdr->b_l1hdr.b_datacnt = 1;
+		nhdr->b_l1hdr.b_state = arc_anon;
+		nhdr->b_l1hdr.b_arc_access = 0;
+		nhdr->b_l1hdr.b_tmp_cdata = NULL;
+		nhdr->b_freeze_cksum = NULL;
+
+		(void) refcount_add(&nhdr->b_l1hdr.b_refcnt, tag);
+		buf->b_hdr = nhdr;
+		mutex_exit(&buf->b_evict_lock);
+		(void) refcount_add_many(&arc_anon->arcs_size, blksz, buf);
+	} else {
+		mutex_exit(&buf->b_evict_lock);
+		ASSERT(refcount_count(&hdr->b_l1hdr.b_refcnt) == 1);
+		/* protected by hash lock, or hdr is on arc_anon */
+		ASSERT(!multilist_link_active(&hdr->b_l1hdr.b_arc_node));
+		ASSERT(!HDR_IO_IN_PROGRESS(hdr));
+		hdr->b_l1hdr.b_mru_hits = 0;
+		hdr->b_l1hdr.b_mru_ghost_hits = 0;
+		hdr->b_l1hdr.b_mfu_hits = 0;
+		hdr->b_l1hdr.b_mfu_ghost_hits = 0;
+		hdr->b_l1hdr.b_l2_hits = 0;
+		arc_change_state(arc_anon, hdr, hash_lock);
+		hdr->b_l1hdr.b_arc_access = 0;
+		mutex_exit(hash_lock);
+
+		buf_discard_identity(hdr);
+		arc_buf_thaw(buf);
+	}
+	buf->b_efunc = NULL;
+	buf->b_private = NULL;
+}
+
+int
+arc_released(arc_buf_t *buf)
+{
+	int released;
+
+	mutex_enter(&buf->b_evict_lock);
+	released = (buf->b_data != NULL &&
+	    buf->b_hdr->b_l1hdr.b_state == arc_anon);
+	mutex_exit(&buf->b_evict_lock);
+	return (released);
+}
+
+#ifdef ZFS_DEBUG
+int
+arc_referenced(arc_buf_t *buf)
+{
+	int referenced;
+
+	mutex_enter(&buf->b_evict_lock);
+	referenced = (refcount_count(&buf->b_hdr->b_l1hdr.b_refcnt));
+	mutex_exit(&buf->b_evict_lock);
+	return (referenced);
+}
+#endif
+
+static void
+arc_write_ready(zio_t *zio)
+{
+	arc_write_callback_t *callback = zio->io_private;
+	arc_buf_t *buf = callback->awcb_buf;
+	arc_buf_hdr_t *hdr = buf->b_hdr;
+
+	ASSERT(HDR_HAS_L1HDR(hdr));
+	ASSERT(!refcount_is_zero(&buf->b_hdr->b_l1hdr.b_refcnt));
+	ASSERT(hdr->b_l1hdr.b_datacnt > 0);
+	callback->awcb_ready(zio, buf, callback->awcb_private);
+
+	/*
+	 * If the IO is already in progress, then this is a re-write
+	 * attempt, so we need to thaw and re-compute the cksum.
+	 * It is the responsibility of the callback to handle the
+	 * accounting for any re-write attempt.
+	 */
+	if (HDR_IO_IN_PROGRESS(hdr)) {
+		mutex_enter(&hdr->b_l1hdr.b_freeze_lock);
+		if (hdr->b_freeze_cksum != NULL) {
+			kmem_free(hdr->b_freeze_cksum, sizeof (zio_cksum_t));
+			hdr->b_freeze_cksum = NULL;
+		}
+		mutex_exit(&hdr->b_l1hdr.b_freeze_lock);
+	}
+	arc_cksum_compute(buf, B_FALSE);
+	hdr->b_flags |= ARC_FLAG_IO_IN_PROGRESS;
+}
+
+/*
+ * The SPA calls this callback for each physical write that happens on behalf
+ * of a logical write.  See the comment in dbuf_write_physdone() for details.
+ */
+static void
+arc_write_physdone(zio_t *zio)
+{
+	arc_write_callback_t *cb = zio->io_private;
+	if (cb->awcb_physdone != NULL)
+		cb->awcb_physdone(zio, cb->awcb_buf, cb->awcb_private);
+}
+
+static void
+arc_write_done(zio_t *zio)
+{
+	arc_write_callback_t *callback = zio->io_private;
+	arc_buf_t *buf = callback->awcb_buf;
+	arc_buf_hdr_t *hdr = buf->b_hdr;
+
+	ASSERT(hdr->b_l1hdr.b_acb == NULL);
+
+	if (zio->io_error == 0) {
+		if (BP_IS_HOLE(zio->io_bp) || BP_IS_EMBEDDED(zio->io_bp)) {
+			buf_discard_identity(hdr);
+		} else {
+			hdr->b_dva = *BP_IDENTITY(zio->io_bp);
+			hdr->b_birth = BP_PHYSICAL_BIRTH(zio->io_bp);
+		}
+	} else {
+		ASSERT(BUF_EMPTY(hdr));
+	}
+
+	/*
+	 * If the block to be written was all-zero or compressed enough to be
+	 * embedded in the BP, no write was performed so there will be no
+	 * dva/birth/checksum.  The buffer must therefore remain anonymous
+	 * (and uncached).
+	 */
+	if (!BUF_EMPTY(hdr)) {
+		arc_buf_hdr_t *exists;
+		kmutex_t *hash_lock;
+
+		ASSERT(zio->io_error == 0);
+
+		arc_cksum_verify(buf);
+
+		exists = buf_hash_insert(hdr, &hash_lock);
+		if (exists != NULL) {
+			/*
+			 * This can only happen if we overwrite for
+			 * sync-to-convergence, because we remove
+			 * buffers from the hash table when we arc_free().
+			 */
+			if (zio->io_flags & ZIO_FLAG_IO_REWRITE) {
+				if (!BP_EQUAL(&zio->io_bp_orig, zio->io_bp))
+					panic("bad overwrite, hdr=%p exists=%p",
+					    (void *)hdr, (void *)exists);
+				ASSERT(refcount_is_zero(
+				    &exists->b_l1hdr.b_refcnt));
+				arc_change_state(arc_anon, exists, hash_lock);
+				mutex_exit(hash_lock);
+				arc_hdr_destroy(exists);
+				exists = buf_hash_insert(hdr, &hash_lock);
+				ASSERT3P(exists, ==, NULL);
+			} else if (zio->io_flags & ZIO_FLAG_NOPWRITE) {
+				/* nopwrite */
+				ASSERT(zio->io_prop.zp_nopwrite);
+				if (!BP_EQUAL(&zio->io_bp_orig, zio->io_bp))
+					panic("bad nopwrite, hdr=%p exists=%p",
+					    (void *)hdr, (void *)exists);
+			} else {
+				/* Dedup */
+				ASSERT(hdr->b_l1hdr.b_datacnt == 1);
+				ASSERT(hdr->b_l1hdr.b_state == arc_anon);
+				ASSERT(BP_GET_DEDUP(zio->io_bp));
+				ASSERT(BP_GET_LEVEL(zio->io_bp) == 0);
+			}
+		}
+		hdr->b_flags &= ~ARC_FLAG_IO_IN_PROGRESS;
+		/* if it's not anon, we are doing a scrub */
+		if (exists == NULL && hdr->b_l1hdr.b_state == arc_anon)
+			arc_access(hdr, hash_lock);
+		mutex_exit(hash_lock);
+	} else {
+		hdr->b_flags &= ~ARC_FLAG_IO_IN_PROGRESS;
+	}
+
+	ASSERT(!refcount_is_zero(&hdr->b_l1hdr.b_refcnt));
+	callback->awcb_done(zio, buf, callback->awcb_private);
+
+	kmem_free(callback, sizeof (arc_write_callback_t));
+}
+
+zio_t *
+arc_write(zio_t *pio, spa_t *spa, uint64_t txg,
+    blkptr_t *bp, arc_buf_t *buf, boolean_t l2arc, boolean_t l2arc_compress,
+    const zio_prop_t *zp, arc_done_func_t *ready, arc_done_func_t *physdone,
+    arc_done_func_t *done, void *private, zio_priority_t priority,
+    int zio_flags, const zbookmark_phys_t *zb)
+{
+	arc_buf_hdr_t *hdr = buf->b_hdr;
+	arc_write_callback_t *callback;
+	zio_t *zio;
+
+	ASSERT(ready != NULL);
+	ASSERT(done != NULL);
+	ASSERT(!HDR_IO_ERROR(hdr));
+	ASSERT(!HDR_IO_IN_PROGRESS(hdr));
+	ASSERT(hdr->b_l1hdr.b_acb == NULL);
+	ASSERT(hdr->b_l1hdr.b_datacnt > 0);
+	if (l2arc)
+		hdr->b_flags |= ARC_FLAG_L2CACHE;
+	if (l2arc_compress)
+		hdr->b_flags |= ARC_FLAG_L2COMPRESS;
+	callback = kmem_zalloc(sizeof (arc_write_callback_t), KM_SLEEP);
+	callback->awcb_ready = ready;
+	callback->awcb_physdone = physdone;
+	callback->awcb_done = done;
+	callback->awcb_private = private;
+	callback->awcb_buf = buf;
+
+	zio = zio_write(pio, spa, txg, bp, buf->b_data, hdr->b_size, zp,
+	    arc_write_ready, arc_write_physdone, arc_write_done, callback,
+	    priority, zio_flags, zb);
+
+	return (zio);
+}
+
+static int
+arc_memory_throttle(uint64_t reserve, uint64_t txg)
+{
+#ifdef _KERNEL
+	uint64_t available_memory = ptob(freemem);
+	static uint64_t page_load = 0;
+	static uint64_t last_txg = 0;
+#ifdef __linux__
+	pgcnt_t minfree = btop(arc_sys_free / 4);
+#endif
+
+	if (freemem > physmem * arc_lotsfree_percent / 100)
+		return (0);
+
+	if (txg > last_txg) {
+		last_txg = txg;
+		page_load = 0;
+	}
+
+	/*
+	 * If we are in pageout, we know that memory is already tight,
+	 * the arc is already going to be evicting, so we just want to
+	 * continue to let page writes occur as quickly as possible.
+	 */
+	if (current_is_kswapd()) {
+		if (page_load > MAX(ptob(minfree), available_memory) / 4) {
+			DMU_TX_STAT_BUMP(dmu_tx_memory_reclaim);
+			return (SET_ERROR(ERESTART));
+		}
+		/* Note: reserve is inflated, so we deflate */
+		page_load += reserve / 8;
+		return (0);
+	} else if (page_load > 0 && arc_reclaim_needed()) {
+		/* memory is low, delay before restarting */
+		ARCSTAT_INCR(arcstat_memory_throttle_count, 1);
+		DMU_TX_STAT_BUMP(dmu_tx_memory_reclaim);
+		return (SET_ERROR(EAGAIN));
+	}
+	page_load = 0;
+#endif
+	return (0);
+}
+
+void
+arc_tempreserve_clear(uint64_t reserve)
+{
+	atomic_add_64(&arc_tempreserve, -reserve);
+	ASSERT((int64_t)arc_tempreserve >= 0);
+}
+
+int
+arc_tempreserve_space(uint64_t reserve, uint64_t txg)
+{
+	int error;
+	uint64_t anon_size;
+
+	if (!arc_no_grow &&
+	    reserve > arc_c/4 &&
+	    reserve * 4 > (2ULL << SPA_MAXBLOCKSHIFT))
+		arc_c = MIN(arc_c_max, reserve * 4);
+
+	/*
+	 * Throttle when the calculated memory footprint for the TXG
+	 * exceeds the target ARC size.
+	 */
+	if (reserve > arc_c) {
+		DMU_TX_STAT_BUMP(dmu_tx_memory_reserve);
+		return (SET_ERROR(ERESTART));
+	}
+
+	/*
+	 * Don't count loaned bufs as in flight dirty data to prevent long
+	 * network delays from blocking transactions that are ready to be
+	 * assigned to a txg.
+	 */
+	anon_size = MAX((int64_t)(refcount_count(&arc_anon->arcs_size) -
+	    arc_loaned_bytes), 0);
+
+	/*
+	 * Writes will, almost always, require additional memory allocations
+	 * in order to compress/encrypt/etc the data.  We therefore need to
+	 * make sure that there is sufficient available memory for this.
+	 */
+	error = arc_memory_throttle(reserve, txg);
+	if (error != 0)
+		return (error);
+
+	/*
+	 * Throttle writes when the amount of dirty data in the cache
+	 * gets too large.  We try to keep the cache less than half full
+	 * of dirty blocks so that our sync times don't grow too large.
+	 * Note: if two requests come in concurrently, we might let them
+	 * both succeed, when one of them should fail.  Not a huge deal.
+	 */
+
+	if (reserve + arc_tempreserve + anon_size > arc_c / 2 &&
+	    anon_size > arc_c / 4) {
+		dprintf("failing, arc_tempreserve=%lluK anon_meta=%lluK "
+		    "anon_data=%lluK tempreserve=%lluK arc_c=%lluK\n",
+		    arc_tempreserve>>10,
+		    arc_anon->arcs_lsize[ARC_BUFC_METADATA]>>10,
+		    arc_anon->arcs_lsize[ARC_BUFC_DATA]>>10,
+		    reserve>>10, arc_c>>10);
+		DMU_TX_STAT_BUMP(dmu_tx_dirty_throttle);
+		return (SET_ERROR(ERESTART));
+	}
+	atomic_add_64(&arc_tempreserve, reserve);
+	return (0);
+}
+
+static void
+arc_kstat_update_state(arc_state_t *state, kstat_named_t *size,
+    kstat_named_t *evict_data, kstat_named_t *evict_metadata)
+{
+	size->value.ui64 = refcount_count(&state->arcs_size);
+	evict_data->value.ui64 = state->arcs_lsize[ARC_BUFC_DATA];
+	evict_metadata->value.ui64 = state->arcs_lsize[ARC_BUFC_METADATA];
+}
+
+static int
+arc_kstat_update(kstat_t *ksp, int rw)
+{
+	arc_stats_t *as = ksp->ks_data;
+
+	if (rw == KSTAT_WRITE) {
+		return (EACCES);
+	} else {
+		arc_kstat_update_state(arc_anon,
+		    &as->arcstat_anon_size,
+		    &as->arcstat_anon_evictable_data,
+		    &as->arcstat_anon_evictable_metadata);
+		arc_kstat_update_state(arc_mru,
+		    &as->arcstat_mru_size,
+		    &as->arcstat_mru_evictable_data,
+		    &as->arcstat_mru_evictable_metadata);
+		arc_kstat_update_state(arc_mru_ghost,
+		    &as->arcstat_mru_ghost_size,
+		    &as->arcstat_mru_ghost_evictable_data,
+		    &as->arcstat_mru_ghost_evictable_metadata);
+		arc_kstat_update_state(arc_mfu,
+		    &as->arcstat_mfu_size,
+		    &as->arcstat_mfu_evictable_data,
+		    &as->arcstat_mfu_evictable_metadata);
+		arc_kstat_update_state(arc_mfu_ghost,
+		    &as->arcstat_mfu_ghost_size,
+		    &as->arcstat_mfu_ghost_evictable_data,
+		    &as->arcstat_mfu_ghost_evictable_metadata);
+	}
+
+	return (0);
+}
+
+/*
+ * This function *must* return indices evenly distributed between all
+ * sublists of the multilist. This is needed due to how the ARC eviction
+ * code is laid out; arc_evict_state() assumes ARC buffers are evenly
+ * distributed between all sublists and uses this assumption when
+ * deciding which sublist to evict from and how much to evict from it.
+ */
+unsigned int
+arc_state_multilist_index_func(multilist_t *ml, void *obj)
+{
+	arc_buf_hdr_t *hdr = obj;
+
+	/*
+	 * We rely on b_dva to generate evenly distributed index
+	 * numbers using buf_hash below. So, as an added precaution,
+	 * let's make sure we never add empty buffers to the arc lists.
+	 */
+	ASSERT(!BUF_EMPTY(hdr));
+
+	/*
+	 * The assumption here, is the hash value for a given
+	 * arc_buf_hdr_t will remain constant throughout its lifetime
+	 * (i.e. its b_spa, b_dva, and b_birth fields don't change).
+	 * Thus, we don't need to store the header's sublist index
+	 * on insertion, as this index can be recalculated on removal.
+	 *
+	 * Also, the low order bits of the hash value are thought to be
+	 * distributed evenly. Otherwise, in the case that the multilist
+	 * has a power of two number of sublists, each sublists' usage
+	 * would not be evenly distributed.
+	 */
+	return (buf_hash(hdr->b_spa, &hdr->b_dva, hdr->b_birth) %
+	    multilist_get_num_sublists(ml));
+}
+
+/*
+ * Called during module initialization and periodically thereafter to
+ * apply reasonable changes to the exposed performance tunings.  Non-zero
+ * zfs_* values which differ from the currently set values will be applied.
+ */
+static void
+arc_tuning_update(void)
+{
+	/* Valid range: 64M - <all physical memory> */
+	if ((zfs_arc_max) && (zfs_arc_max != arc_c_max) &&
+	    (zfs_arc_max > 64 << 20) && (zfs_arc_max < ptob(physmem)) &&
+	    (zfs_arc_max > arc_c_min)) {
+		arc_c_max = zfs_arc_max;
+		arc_c = arc_c_max;
+		arc_p = (arc_c >> 1);
+		arc_meta_limit = MIN(arc_meta_limit, arc_c_max);
+	}
+
+	/* Valid range: 32M - <arc_c_max> */
+	if ((zfs_arc_min) && (zfs_arc_min != arc_c_min) &&
+	    (zfs_arc_min >= 2ULL << SPA_MAXBLOCKSHIFT) &&
+	    (zfs_arc_min <= arc_c_max)) {
+		arc_c_min = zfs_arc_min;
+		arc_c = MAX(arc_c, arc_c_min);
+	}
+
+	/* Valid range: 16M - <arc_c_max> */
+	if ((zfs_arc_meta_min) && (zfs_arc_meta_min != arc_meta_min) &&
+	    (zfs_arc_meta_min >= 1ULL << SPA_MAXBLOCKSHIFT) &&
+	    (zfs_arc_meta_min <= arc_c_max)) {
+		arc_meta_min = zfs_arc_meta_min;
+		arc_meta_limit = MAX(arc_meta_limit, arc_meta_min);
+	}
+
+	/* Valid range: <arc_meta_min> - <arc_c_max> */
+	if ((zfs_arc_meta_limit) && (zfs_arc_meta_limit != arc_meta_limit) &&
+	    (zfs_arc_meta_limit >= zfs_arc_meta_min) &&
+	    (zfs_arc_meta_limit <= arc_c_max))
+		arc_meta_limit = zfs_arc_meta_limit;
+
+	/* Valid range: 1 - N */
+	if (zfs_arc_grow_retry)
+		arc_grow_retry = zfs_arc_grow_retry;
+
+	/* Valid range: 1 - N */
+	if (zfs_arc_shrink_shift) {
+		arc_shrink_shift = zfs_arc_shrink_shift;
+		arc_no_grow_shift = MIN(arc_no_grow_shift, arc_shrink_shift -1);
+	}
+
+	/* Valid range: 1 - N */
+	if (zfs_arc_p_min_shift)
+		arc_p_min_shift = zfs_arc_p_min_shift;
+
+	/* Valid range: 1 - N ticks */
+	if (zfs_arc_min_prefetch_lifespan)
+		arc_min_prefetch_lifespan = zfs_arc_min_prefetch_lifespan;
+
+	/* Valid range: 0 - 100 */
+	if ((zfs_arc_lotsfree_percent >= 0) &&
+	    (zfs_arc_lotsfree_percent <= 100))
+		arc_lotsfree_percent = zfs_arc_lotsfree_percent;
+
+	/* Valid range: 0 - <all physical memory> */
+	if ((zfs_arc_sys_free) && (zfs_arc_sys_free != arc_sys_free))
+		arc_sys_free = MIN(MAX(zfs_arc_sys_free, 0), ptob(physmem));
+
+}
+
+void
+arc_init(void)
+{
+	/*
+	 * allmem is "all memory that we could possibly use".
+	 */
+#ifdef _KERNEL
+	uint64_t allmem = ptob(physmem);
+#else
+	uint64_t allmem = (physmem * PAGESIZE) / 2;
+#endif
+
+	mutex_init(&arc_reclaim_lock, NULL, MUTEX_DEFAULT, NULL);
+	cv_init(&arc_reclaim_thread_cv, NULL, CV_DEFAULT, NULL);
+	cv_init(&arc_reclaim_waiters_cv, NULL, CV_DEFAULT, NULL);
+
+	mutex_init(&arc_user_evicts_lock, NULL, MUTEX_DEFAULT, NULL);
+	cv_init(&arc_user_evicts_cv, NULL, CV_DEFAULT, NULL);
+
+	/* Convert seconds to clock ticks */
+	arc_min_prefetch_lifespan = 1 * hz;
+
+	/* Start out with 1/8 of all memory */
+	arc_c = allmem / 8;
+
+#ifdef _KERNEL
+	/*
+	 * On architectures where the physical memory can be larger
+	 * than the addressable space (intel in 32-bit mode), we may
+	 * need to limit the cache to 1/8 of VM size.
+	 */
+	arc_c = MIN(arc_c, vmem_size(heap_arena, VMEM_ALLOC | VMEM_FREE) / 8);
+
+	/*
+	 * Register a shrinker to support synchronous (direct) memory
+	 * reclaim from the arc.  This is done to prevent kswapd from
+	 * swapping out pages when it is preferable to shrink the arc.
+	 */
+	spl_register_shrinker(&arc_shrinker);
+
+	/* Set to 1/64 of all memory or a minimum of 512K */
+	arc_sys_free = MAX(ptob(physmem / 64), (512 * 1024));
+	arc_need_free = 0;
+#endif
+
+	/* Set min cache to allow safe operation of arc_adapt() */
+	arc_c_min = 2ULL << SPA_MAXBLOCKSHIFT;
+	/* Set max to 1/2 of all memory */
+	arc_c_max = allmem / 2;
+
+	arc_c = arc_c_max;
+	arc_p = (arc_c >> 1);
+
+	/* Set min to 1/2 of arc_c_min */
+	arc_meta_min = 1ULL << SPA_MAXBLOCKSHIFT;
+	/* Initialize maximum observed usage to zero */
+	arc_meta_max = 0;
+	/* Set limit to 3/4 of arc_c_max with a floor of arc_meta_min */
+	arc_meta_limit = MAX((3 * arc_c_max) / 4, arc_meta_min);
+
+	/* Apply user specified tunings */
+	arc_tuning_update();
+
+	if (zfs_arc_num_sublists_per_state < 1)
+		zfs_arc_num_sublists_per_state = MAX(boot_ncpus, 1);
+
+	/* if kmem_flags are set, lets try to use less memory */
+	if (kmem_debugging())
+		arc_c = arc_c / 2;
+	if (arc_c < arc_c_min)
+		arc_c = arc_c_min;
+
+	arc_anon = &ARC_anon;
+	arc_mru = &ARC_mru;
+	arc_mru_ghost = &ARC_mru_ghost;
+	arc_mfu = &ARC_mfu;
+	arc_mfu_ghost = &ARC_mfu_ghost;
+	arc_l2c_only = &ARC_l2c_only;
+	arc_size = 0;
+
+	multilist_create(&arc_mru->arcs_list[ARC_BUFC_METADATA],
+	    sizeof (arc_buf_hdr_t),
+	    offsetof(arc_buf_hdr_t, b_l1hdr.b_arc_node),
+	    zfs_arc_num_sublists_per_state, arc_state_multilist_index_func);
+	multilist_create(&arc_mru->arcs_list[ARC_BUFC_DATA],
+	    sizeof (arc_buf_hdr_t),
+	    offsetof(arc_buf_hdr_t, b_l1hdr.b_arc_node),
+	    zfs_arc_num_sublists_per_state, arc_state_multilist_index_func);
+	multilist_create(&arc_mru_ghost->arcs_list[ARC_BUFC_METADATA],
+	    sizeof (arc_buf_hdr_t),
+	    offsetof(arc_buf_hdr_t, b_l1hdr.b_arc_node),
+	    zfs_arc_num_sublists_per_state, arc_state_multilist_index_func);
+	multilist_create(&arc_mru_ghost->arcs_list[ARC_BUFC_DATA],
+	    sizeof (arc_buf_hdr_t),
+	    offsetof(arc_buf_hdr_t, b_l1hdr.b_arc_node),
+	    zfs_arc_num_sublists_per_state, arc_state_multilist_index_func);
+	multilist_create(&arc_mfu->arcs_list[ARC_BUFC_METADATA],
+	    sizeof (arc_buf_hdr_t),
+	    offsetof(arc_buf_hdr_t, b_l1hdr.b_arc_node),
+	    zfs_arc_num_sublists_per_state, arc_state_multilist_index_func);
+	multilist_create(&arc_mfu->arcs_list[ARC_BUFC_DATA],
+	    sizeof (arc_buf_hdr_t),
+	    offsetof(arc_buf_hdr_t, b_l1hdr.b_arc_node),
+	    zfs_arc_num_sublists_per_state, arc_state_multilist_index_func);
+	multilist_create(&arc_mfu_ghost->arcs_list[ARC_BUFC_METADATA],
+	    sizeof (arc_buf_hdr_t),
+	    offsetof(arc_buf_hdr_t, b_l1hdr.b_arc_node),
+	    zfs_arc_num_sublists_per_state, arc_state_multilist_index_func);
+	multilist_create(&arc_mfu_ghost->arcs_list[ARC_BUFC_DATA],
+	    sizeof (arc_buf_hdr_t),
+	    offsetof(arc_buf_hdr_t, b_l1hdr.b_arc_node),
+	    zfs_arc_num_sublists_per_state, arc_state_multilist_index_func);
+	multilist_create(&arc_l2c_only->arcs_list[ARC_BUFC_METADATA],
+	    sizeof (arc_buf_hdr_t),
+	    offsetof(arc_buf_hdr_t, b_l1hdr.b_arc_node),
+	    zfs_arc_num_sublists_per_state, arc_state_multilist_index_func);
+	multilist_create(&arc_l2c_only->arcs_list[ARC_BUFC_DATA],
+	    sizeof (arc_buf_hdr_t),
+	    offsetof(arc_buf_hdr_t, b_l1hdr.b_arc_node),
+	    zfs_arc_num_sublists_per_state, arc_state_multilist_index_func);
+
+	arc_anon->arcs_state = ARC_STATE_ANON;
+	arc_mru->arcs_state = ARC_STATE_MRU;
+	arc_mru_ghost->arcs_state = ARC_STATE_MRU_GHOST;
+	arc_mfu->arcs_state = ARC_STATE_MFU;
+	arc_mfu_ghost->arcs_state = ARC_STATE_MFU_GHOST;
+	arc_l2c_only->arcs_state = ARC_STATE_L2C_ONLY;
+
+	refcount_create(&arc_anon->arcs_size);
+	refcount_create(&arc_mru->arcs_size);
+	refcount_create(&arc_mru_ghost->arcs_size);
+	refcount_create(&arc_mfu->arcs_size);
+	refcount_create(&arc_mfu_ghost->arcs_size);
+	refcount_create(&arc_l2c_only->arcs_size);
+
+	buf_init();
+
+	arc_reclaim_thread_exit = FALSE;
+	arc_user_evicts_thread_exit = FALSE;
+	list_create(&arc_prune_list, sizeof (arc_prune_t),
+	    offsetof(arc_prune_t, p_node));
+	arc_eviction_list = NULL;
+	mutex_init(&arc_prune_mtx, NULL, MUTEX_DEFAULT, NULL);
+	bzero(&arc_eviction_hdr, sizeof (arc_buf_hdr_t));
+
+	arc_prune_taskq = taskq_create("arc_prune", max_ncpus, defclsyspri,
+	    max_ncpus, INT_MAX, TASKQ_PREPOPULATE | TASKQ_DYNAMIC);
+
+	arc_ksp = kstat_create("zfs", 0, "arcstats", "misc", KSTAT_TYPE_NAMED,
+	    sizeof (arc_stats) / sizeof (kstat_named_t), KSTAT_FLAG_VIRTUAL);
+
+	if (arc_ksp != NULL) {
+		arc_ksp->ks_data = &arc_stats;
+		arc_ksp->ks_update = arc_kstat_update;
+		kstat_install(arc_ksp);
+	}
+
+	(void) thread_create(NULL, 0, arc_reclaim_thread, NULL, 0, &p0,
+	    TS_RUN, defclsyspri);
+
+	(void) thread_create(NULL, 0, arc_user_evicts_thread, NULL, 0, &p0,
+	    TS_RUN, defclsyspri);
+
+	arc_dead = FALSE;
+	arc_warm = B_FALSE;
+
+	/*
+	 * Calculate maximum amount of dirty data per pool.
+	 *
+	 * If it has been set by a module parameter, take that.
+	 * Otherwise, use a percentage of physical memory defined by
+	 * zfs_dirty_data_max_percent (default 10%) with a cap at
+	 * zfs_dirty_data_max_max (default 25% of physical memory).
+	 */
+	if (zfs_dirty_data_max_max == 0)
+		zfs_dirty_data_max_max = (uint64_t)physmem * PAGESIZE *
+		    zfs_dirty_data_max_max_percent / 100;
+
+	if (zfs_dirty_data_max == 0) {
+		zfs_dirty_data_max = (uint64_t)physmem * PAGESIZE *
+		    zfs_dirty_data_max_percent / 100;
+		zfs_dirty_data_max = MIN(zfs_dirty_data_max,
+		    zfs_dirty_data_max_max);
+	}
+}
+
+void
+arc_fini(void)
+{
+	arc_prune_t *p;
+
+#ifdef _KERNEL
+	spl_unregister_shrinker(&arc_shrinker);
+#endif /* _KERNEL */
+
+	mutex_enter(&arc_reclaim_lock);
+	arc_reclaim_thread_exit = TRUE;
+	/*
+	 * The reclaim thread will set arc_reclaim_thread_exit back to
+	 * FALSE when it is finished exiting; we're waiting for that.
+	 */
+	while (arc_reclaim_thread_exit) {
+		cv_signal(&arc_reclaim_thread_cv);
+		cv_wait(&arc_reclaim_thread_cv, &arc_reclaim_lock);
+	}
+	mutex_exit(&arc_reclaim_lock);
+
+	mutex_enter(&arc_user_evicts_lock);
+	arc_user_evicts_thread_exit = TRUE;
+	/*
+	 * The user evicts thread will set arc_user_evicts_thread_exit
+	 * to FALSE when it is finished exiting; we're waiting for that.
+	 */
+	while (arc_user_evicts_thread_exit) {
+		cv_signal(&arc_user_evicts_cv);
+		cv_wait(&arc_user_evicts_cv, &arc_user_evicts_lock);
+	}
+	mutex_exit(&arc_user_evicts_lock);
+
+	/* Use TRUE to ensure *all* buffers are evicted */
+	arc_flush(NULL, TRUE);
+
+	arc_dead = TRUE;
+
+	if (arc_ksp != NULL) {
+		kstat_delete(arc_ksp);
+		arc_ksp = NULL;
+	}
+
+	taskq_wait(arc_prune_taskq);
+	taskq_destroy(arc_prune_taskq);
+
+	mutex_enter(&arc_prune_mtx);
+	while ((p = list_head(&arc_prune_list)) != NULL) {
+		list_remove(&arc_prune_list, p);
+		refcount_remove(&p->p_refcnt, &arc_prune_list);
+		refcount_destroy(&p->p_refcnt);
+		kmem_free(p, sizeof (*p));
+	}
+	mutex_exit(&arc_prune_mtx);
+
+	list_destroy(&arc_prune_list);
+	mutex_destroy(&arc_prune_mtx);
+	mutex_destroy(&arc_reclaim_lock);
+	cv_destroy(&arc_reclaim_thread_cv);
+	cv_destroy(&arc_reclaim_waiters_cv);
+
+	mutex_destroy(&arc_user_evicts_lock);
+	cv_destroy(&arc_user_evicts_cv);
+
+	refcount_destroy(&arc_anon->arcs_size);
+	refcount_destroy(&arc_mru->arcs_size);
+	refcount_destroy(&arc_mru_ghost->arcs_size);
+	refcount_destroy(&arc_mfu->arcs_size);
+	refcount_destroy(&arc_mfu_ghost->arcs_size);
+	refcount_destroy(&arc_l2c_only->arcs_size);
+
+	multilist_destroy(&arc_mru->arcs_list[ARC_BUFC_METADATA]);
+	multilist_destroy(&arc_mru_ghost->arcs_list[ARC_BUFC_METADATA]);
+	multilist_destroy(&arc_mfu->arcs_list[ARC_BUFC_METADATA]);
+	multilist_destroy(&arc_mfu_ghost->arcs_list[ARC_BUFC_METADATA]);
+	multilist_destroy(&arc_mru->arcs_list[ARC_BUFC_DATA]);
+	multilist_destroy(&arc_mru_ghost->arcs_list[ARC_BUFC_DATA]);
+	multilist_destroy(&arc_mfu->arcs_list[ARC_BUFC_DATA]);
+	multilist_destroy(&arc_mfu_ghost->arcs_list[ARC_BUFC_DATA]);
+	multilist_destroy(&arc_l2c_only->arcs_list[ARC_BUFC_METADATA]);
+	multilist_destroy(&arc_l2c_only->arcs_list[ARC_BUFC_DATA]);
+
+	buf_fini();
+
+	ASSERT0(arc_loaned_bytes);
+}
+
+/*
+ * Level 2 ARC
+ *
+ * The level 2 ARC (L2ARC) is a cache layer in-between main memory and disk.
+ * It uses dedicated storage devices to hold cached data, which are populated
+ * using large infrequent writes.  The main role of this cache is to boost
+ * the performance of random read workloads.  The intended L2ARC devices
+ * include short-stroked disks, solid state disks, and other media with
+ * substantially faster read latency than disk.
+ *
+ *                 +-----------------------+
+ *                 |         ARC           |
+ *                 +-----------------------+
+ *                    |         ^     ^
+ *                    |         |     |
+ *      l2arc_feed_thread()    arc_read()
+ *                    |         |     |
+ *                    |  l2arc read   |
+ *                    V         |     |
+ *               +---------------+    |
+ *               |     L2ARC     |    |
+ *               +---------------+    |
+ *                   |    ^           |
+ *          l2arc_write() |           |
+ *                   |    |           |
+ *                   V    |           |
+ *                 +-------+      +-------+
+ *                 | vdev  |      | vdev  |
+ *                 | cache |      | cache |
+ *                 +-------+      +-------+
+ *                 +=========+     .-----.
+ *                 :  L2ARC  :    |-_____-|
+ *                 : devices :    | Disks |
+ *                 +=========+    `-_____-'
+ *
+ * Read requests are satisfied from the following sources, in order:
+ *
+ *	1) ARC
+ *	2) vdev cache of L2ARC devices
+ *	3) L2ARC devices
+ *	4) vdev cache of disks
+ *	5) disks
+ *
+ * Some L2ARC device types exhibit extremely slow write performance.
+ * To accommodate for this there are some significant differences between
+ * the L2ARC and traditional cache design:
+ *
+ * 1. There is no eviction path from the ARC to the L2ARC.  Evictions from
+ * the ARC behave as usual, freeing buffers and placing headers on ghost
+ * lists.  The ARC does not send buffers to the L2ARC during eviction as
+ * this would add inflated write latencies for all ARC memory pressure.
+ *
+ * 2. The L2ARC attempts to cache data from the ARC before it is evicted.
+ * It does this by periodically scanning buffers from the eviction-end of
+ * the MFU and MRU ARC lists, copying them to the L2ARC devices if they are
+ * not already there. It scans until a headroom of buffers is satisfied,
+ * which itself is a buffer for ARC eviction. If a compressible buffer is
+ * found during scanning and selected for writing to an L2ARC device, we
+ * temporarily boost scanning headroom during the next scan cycle to make
+ * sure we adapt to compression effects (which might significantly reduce
+ * the data volume we write to L2ARC). The thread that does this is
+ * l2arc_feed_thread(), illustrated below; example sizes are included to
+ * provide a better sense of ratio than this diagram:
+ *
+ *	       head -->                        tail
+ *	        +---------------------+----------+
+ *	ARC_mfu |:::::#:::::::::::::::|o#o###o###|-->.   # already on L2ARC
+ *	        +---------------------+----------+   |   o L2ARC eligible
+ *	ARC_mru |:#:::::::::::::::::::|#o#ooo####|-->|   : ARC buffer
+ *	        +---------------------+----------+   |
+ *	             15.9 Gbytes      ^ 32 Mbytes    |
+ *	                           headroom          |
+ *	                                      l2arc_feed_thread()
+ *	                                             |
+ *	                 l2arc write hand <--[oooo]--'
+ *	                         |           8 Mbyte
+ *	                         |          write max
+ *	                         V
+ *		  +==============================+
+ *	L2ARC dev |####|#|###|###|    |####| ... |
+ *	          +==============================+
+ *	                     32 Gbytes
+ *
+ * 3. If an ARC buffer is copied to the L2ARC but then hit instead of
+ * evicted, then the L2ARC has cached a buffer much sooner than it probably
+ * needed to, potentially wasting L2ARC device bandwidth and storage.  It is
+ * safe to say that this is an uncommon case, since buffers at the end of
+ * the ARC lists have moved there due to inactivity.
+ *
+ * 4. If the ARC evicts faster than the L2ARC can maintain a headroom,
+ * then the L2ARC simply misses copying some buffers.  This serves as a
+ * pressure valve to prevent heavy read workloads from both stalling the ARC
+ * with waits and clogging the L2ARC with writes.  This also helps prevent
+ * the potential for the L2ARC to churn if it attempts to cache content too
+ * quickly, such as during backups of the entire pool.
+ *
+ * 5. After system boot and before the ARC has filled main memory, there are
+ * no evictions from the ARC and so the tails of the ARC_mfu and ARC_mru
+ * lists can remain mostly static.  Instead of searching from tail of these
+ * lists as pictured, the l2arc_feed_thread() will search from the list heads
+ * for eligible buffers, greatly increasing its chance of finding them.
+ *
+ * The L2ARC device write speed is also boosted during this time so that
+ * the L2ARC warms up faster.  Since there have been no ARC evictions yet,
+ * there are no L2ARC reads, and no fear of degrading read performance
+ * through increased writes.
+ *
+ * 6. Writes to the L2ARC devices are grouped and sent in-sequence, so that
+ * the vdev queue can aggregate them into larger and fewer writes.  Each
+ * device is written to in a rotor fashion, sweeping writes through
+ * available space then repeating.
+ *
+ * 7. The L2ARC does not store dirty content.  It never needs to flush
+ * write buffers back to disk based storage.
+ *
+ * 8. If an ARC buffer is written (and dirtied) which also exists in the
+ * L2ARC, the now stale L2ARC buffer is immediately dropped.
+ *
+ * The performance of the L2ARC can be tweaked by a number of tunables, which
+ * may be necessary for different workloads:
+ *
+ *	l2arc_write_max		max write bytes per interval
+ *	l2arc_write_boost	extra write bytes during device warmup
+ *	l2arc_noprefetch	skip caching prefetched buffers
+ *	l2arc_nocompress	skip compressing buffers
+ *	l2arc_headroom		number of max device writes to precache
+ *	l2arc_headroom_boost	when we find compressed buffers during ARC
+ *				scanning, we multiply headroom by this
+ *				percentage factor for the next scan cycle,
+ *				since more compressed buffers are likely to
+ *				be present
+ *	l2arc_feed_secs		seconds between L2ARC writing
+ *
+ * Tunables may be removed or added as future performance improvements are
+ * integrated, and also may become zpool properties.
+ *
+ * There are three key functions that control how the L2ARC warms up:
+ *
+ *	l2arc_write_eligible()	check if a buffer is eligible to cache
+ *	l2arc_write_size()	calculate how much to write
+ *	l2arc_write_interval()	calculate sleep delay between writes
+ *
+ * These three functions determine what to write, how much, and how quickly
+ * to send writes.
+ */
+
+static boolean_t
+l2arc_write_eligible(uint64_t spa_guid, arc_buf_hdr_t *hdr)
+{
+	/*
+	 * A buffer is *not* eligible for the L2ARC if it:
+	 * 1. belongs to a different spa.
+	 * 2. is already cached on the L2ARC.
+	 * 3. has an I/O in progress (it may be an incomplete read).
+	 * 4. is flagged not eligible (zfs property).
+	 */
+	if (hdr->b_spa != spa_guid || HDR_HAS_L2HDR(hdr) ||
+	    HDR_IO_IN_PROGRESS(hdr) || !HDR_L2CACHE(hdr))
+		return (B_FALSE);
+
+	return (B_TRUE);
+}
+
+static uint64_t
+l2arc_write_size(void)
+{
+	uint64_t size;
+
+	/*
+	 * Make sure our globals have meaningful values in case the user
+	 * altered them.
+	 */
+	size = l2arc_write_max;
+	if (size == 0) {
+		cmn_err(CE_NOTE, "Bad value for l2arc_write_max, value must "
+		    "be greater than zero, resetting it to the default (%d)",
+		    L2ARC_WRITE_SIZE);
+		size = l2arc_write_max = L2ARC_WRITE_SIZE;
+	}
+
+	if (arc_warm == B_FALSE)
+		size += l2arc_write_boost;
+
+	return (size);
+
+}
+
+static clock_t
+l2arc_write_interval(clock_t began, uint64_t wanted, uint64_t wrote)
+{
+	clock_t interval, next, now;
+
+	/*
+	 * If the ARC lists are busy, increase our write rate; if the
+	 * lists are stale, idle back.  This is achieved by checking
+	 * how much we previously wrote - if it was more than half of
+	 * what we wanted, schedule the next write much sooner.
+	 */
+	if (l2arc_feed_again && wrote > (wanted / 2))
+		interval = (hz * l2arc_feed_min_ms) / 1000;
+	else
+		interval = hz * l2arc_feed_secs;
+
+	now = ddi_get_lbolt();
+	next = MAX(now, MIN(now + interval, began + interval));
+
+	return (next);
+}
+
+/*
+ * Cycle through L2ARC devices.  This is how L2ARC load balances.
+ * If a device is returned, this also returns holding the spa config lock.
+ */
+static l2arc_dev_t *
+l2arc_dev_get_next(void)
+{
+	l2arc_dev_t *first, *next = NULL;
+
+	/*
+	 * Lock out the removal of spas (spa_namespace_lock), then removal
+	 * of cache devices (l2arc_dev_mtx).  Once a device has been selected,
+	 * both locks will be dropped and a spa config lock held instead.
+	 */
+	mutex_enter(&spa_namespace_lock);
+	mutex_enter(&l2arc_dev_mtx);
+
+	/* if there are no vdevs, there is nothing to do */
+	if (l2arc_ndev == 0)
+		goto out;
+
+	first = NULL;
+	next = l2arc_dev_last;
+	do {
+		/* loop around the list looking for a non-faulted vdev */
+		if (next == NULL) {
+			next = list_head(l2arc_dev_list);
+		} else {
+			next = list_next(l2arc_dev_list, next);
+			if (next == NULL)
+				next = list_head(l2arc_dev_list);
+		}
+
+		/* if we have come back to the start, bail out */
+		if (first == NULL)
+			first = next;
+		else if (next == first)
+			break;
+
+	} while (vdev_is_dead(next->l2ad_vdev));
+
+	/* if we were unable to find any usable vdevs, return NULL */
+	if (vdev_is_dead(next->l2ad_vdev))
+		next = NULL;
+
+	l2arc_dev_last = next;
+
+out:
+	mutex_exit(&l2arc_dev_mtx);
+
+	/*
+	 * Grab the config lock to prevent the 'next' device from being
+	 * removed while we are writing to it.
+	 */
+	if (next != NULL)
+		spa_config_enter(next->l2ad_spa, SCL_L2ARC, next, RW_READER);
+	mutex_exit(&spa_namespace_lock);
+
+	return (next);
+}
+
+/*
+ * Free buffers that were tagged for destruction.
+ */
+static void
+l2arc_do_free_on_write(void)
+{
+	list_t *buflist;
+	l2arc_data_free_t *df, *df_prev;
+
+	mutex_enter(&l2arc_free_on_write_mtx);
+	buflist = l2arc_free_on_write;
+
+	for (df = list_tail(buflist); df; df = df_prev) {
+		df_prev = list_prev(buflist, df);
+		ASSERT(df->l2df_data != NULL);
+		ASSERT(df->l2df_func != NULL);
+		df->l2df_func(df->l2df_data, df->l2df_size);
+		list_remove(buflist, df);
+		kmem_free(df, sizeof (l2arc_data_free_t));
+	}
+
+	mutex_exit(&l2arc_free_on_write_mtx);
+}
+
+/*
+ * A write to a cache device has completed.  Update all headers to allow
+ * reads from these buffers to begin.
+ */
+static void
+l2arc_write_done(zio_t *zio)
+{
+	l2arc_write_callback_t *cb;
+	l2arc_dev_t *dev;
+	list_t *buflist;
+	arc_buf_hdr_t *head, *hdr, *hdr_prev;
+	kmutex_t *hash_lock;
+	int64_t bytes_dropped = 0;
+
+	cb = zio->io_private;
+	ASSERT(cb != NULL);
+	dev = cb->l2wcb_dev;
+	ASSERT(dev != NULL);
+	head = cb->l2wcb_head;
+	ASSERT(head != NULL);
+	buflist = &dev->l2ad_buflist;
+	ASSERT(buflist != NULL);
+	DTRACE_PROBE2(l2arc__iodone, zio_t *, zio,
+	    l2arc_write_callback_t *, cb);
+
+	if (zio->io_error != 0)
+		ARCSTAT_BUMP(arcstat_l2_writes_error);
+
+	/*
+	 * All writes completed, or an error was hit.
+	 */
+top:
+	mutex_enter(&dev->l2ad_mtx);
+	for (hdr = list_prev(buflist, head); hdr; hdr = hdr_prev) {
+		hdr_prev = list_prev(buflist, hdr);
+
+		hash_lock = HDR_LOCK(hdr);
+
+		/*
+		 * We cannot use mutex_enter or else we can deadlock
+		 * with l2arc_write_buffers (due to swapping the order
+		 * the hash lock and l2ad_mtx are taken).
+		 */
+		if (!mutex_tryenter(hash_lock)) {
+			/*
+			 * Missed the hash lock. We must retry so we
+			 * don't leave the ARC_FLAG_L2_WRITING bit set.
+			 */
+			ARCSTAT_BUMP(arcstat_l2_writes_lock_retry);
+
+			/*
+			 * We don't want to rescan the headers we've
+			 * already marked as having been written out, so
+			 * we reinsert the head node so we can pick up
+			 * where we left off.
+			 */
+			list_remove(buflist, head);
+			list_insert_after(buflist, hdr, head);
+
+			mutex_exit(&dev->l2ad_mtx);
+
+			/*
+			 * We wait for the hash lock to become available
+			 * to try and prevent busy waiting, and increase
+			 * the chance we'll be able to acquire the lock
+			 * the next time around.
+			 */
+			mutex_enter(hash_lock);
+			mutex_exit(hash_lock);
+			goto top;
+		}
+
+		/*
+		 * We could not have been moved into the arc_l2c_only
+		 * state while in-flight due to our ARC_FLAG_L2_WRITING
+		 * bit being set. Let's just ensure that's being enforced.
+		 */
+		ASSERT(HDR_HAS_L1HDR(hdr));
+
+		/*
+		 * We may have allocated a buffer for L2ARC compression,
+		 * we must release it to avoid leaking this data.
+		 */
+		l2arc_release_cdata_buf(hdr);
+
+		if (zio->io_error != 0) {
+			/*
+			 * Error - drop L2ARC entry.
+			 */
+			list_remove(buflist, hdr);
+			hdr->b_flags &= ~ARC_FLAG_HAS_L2HDR;
+
+			ARCSTAT_INCR(arcstat_l2_asize, -hdr->b_l2hdr.b_asize);
+			ARCSTAT_INCR(arcstat_l2_size, -hdr->b_size);
+
+			bytes_dropped += hdr->b_l2hdr.b_asize;
+			(void) refcount_remove_many(&dev->l2ad_alloc,
+			    hdr->b_l2hdr.b_asize, hdr);
+		}
+
+		/*
+		 * Allow ARC to begin reads and ghost list evictions to
+		 * this L2ARC entry.
+		 */
+		hdr->b_flags &= ~ARC_FLAG_L2_WRITING;
+
+		mutex_exit(hash_lock);
+	}
+
+	atomic_inc_64(&l2arc_writes_done);
+	list_remove(buflist, head);
+	ASSERT(!HDR_HAS_L1HDR(head));
+	kmem_cache_free(hdr_l2only_cache, head);
+	mutex_exit(&dev->l2ad_mtx);
+
+	vdev_space_update(dev->l2ad_vdev, -bytes_dropped, 0, 0);
+
+	l2arc_do_free_on_write();
+
+	kmem_free(cb, sizeof (l2arc_write_callback_t));
+}
+
+/*
+ * A read to a cache device completed.  Validate buffer contents before
+ * handing over to the regular ARC routines.
+ */
+static void
+l2arc_read_done(zio_t *zio)
+{
+	l2arc_read_callback_t *cb;
+	arc_buf_hdr_t *hdr;
+	arc_buf_t *buf;
+	kmutex_t *hash_lock;
+	int equal;
+
+	ASSERT(zio->io_vd != NULL);
+	ASSERT(zio->io_flags & ZIO_FLAG_DONT_PROPAGATE);
+
+	spa_config_exit(zio->io_spa, SCL_L2ARC, zio->io_vd);
+
+	cb = zio->io_private;
+	ASSERT(cb != NULL);
+	buf = cb->l2rcb_buf;
+	ASSERT(buf != NULL);
+
+	hash_lock = HDR_LOCK(buf->b_hdr);
+	mutex_enter(hash_lock);
+	hdr = buf->b_hdr;
+	ASSERT3P(hash_lock, ==, HDR_LOCK(hdr));
+
+	/*
+	 * If the buffer was compressed, decompress it first.
+	 */
+	if (cb->l2rcb_compress != ZIO_COMPRESS_OFF)
+		l2arc_decompress_zio(zio, hdr, cb->l2rcb_compress);
+	ASSERT(zio->io_data != NULL);
+	ASSERT3U(zio->io_size, ==, hdr->b_size);
+	ASSERT3U(BP_GET_LSIZE(&cb->l2rcb_bp), ==, hdr->b_size);
+
+	/*
+	 * Check this survived the L2ARC journey.
+	 */
+	equal = arc_cksum_equal(buf);
+	if (equal && zio->io_error == 0 && !HDR_L2_EVICTED(hdr)) {
+		mutex_exit(hash_lock);
+		zio->io_private = buf;
+		zio->io_bp_copy = cb->l2rcb_bp;	/* XXX fix in L2ARC 2.0	*/
+		zio->io_bp = &zio->io_bp_copy;	/* XXX fix in L2ARC 2.0	*/
+		arc_read_done(zio);
+	} else {
+		mutex_exit(hash_lock);
+		/*
+		 * Buffer didn't survive caching.  Increment stats and
+		 * reissue to the original storage device.
+		 */
+		if (zio->io_error != 0) {
+			ARCSTAT_BUMP(arcstat_l2_io_error);
+		} else {
+			zio->io_error = SET_ERROR(EIO);
+		}
+		if (!equal)
+			ARCSTAT_BUMP(arcstat_l2_cksum_bad);
+
+		/*
+		 * If there's no waiter, issue an async i/o to the primary
+		 * storage now.  If there *is* a waiter, the caller must
+		 * issue the i/o in a context where it's OK to block.
+		 */
+		if (zio->io_waiter == NULL) {
+			zio_t *pio = zio_unique_parent(zio);
+
+			ASSERT(!pio || pio->io_child_type == ZIO_CHILD_LOGICAL);
+
+			zio_nowait(zio_read(pio, cb->l2rcb_spa, &cb->l2rcb_bp,
+			    buf->b_data, hdr->b_size, arc_read_done, buf,
+			    zio->io_priority, cb->l2rcb_flags, &cb->l2rcb_zb));
+		}
+	}
+
+	kmem_free(cb, sizeof (l2arc_read_callback_t));
+}
+
+/*
+ * This is the list priority from which the L2ARC will search for pages to
+ * cache.  This is used within loops (0..3) to cycle through lists in the
+ * desired order.  This order can have a significant effect on cache
+ * performance.
+ *
+ * Currently the metadata lists are hit first, MFU then MRU, followed by
+ * the data lists.  This function returns a locked list, and also returns
+ * the lock pointer.
+ */
+static multilist_sublist_t *
+l2arc_sublist_lock(int list_num)
+{
+	multilist_t *ml = NULL;
+	unsigned int idx;
+
+	ASSERT(list_num >= 0 && list_num <= 3);
+
+	switch (list_num) {
+	case 0:
+		ml = &arc_mfu->arcs_list[ARC_BUFC_METADATA];
+		break;
+	case 1:
+		ml = &arc_mru->arcs_list[ARC_BUFC_METADATA];
+		break;
+	case 2:
+		ml = &arc_mfu->arcs_list[ARC_BUFC_DATA];
+		break;
+	case 3:
+		ml = &arc_mru->arcs_list[ARC_BUFC_DATA];
+		break;
+	}
+
+	/*
+	 * Return a randomly-selected sublist. This is acceptable
+	 * because the caller feeds only a little bit of data for each
+	 * call (8MB). Subsequent calls will result in different
+	 * sublists being selected.
+	 */
+	idx = multilist_get_random_index(ml);
+	return (multilist_sublist_lock(ml, idx));
+}
+
+/*
+ * Evict buffers from the device write hand to the distance specified in
+ * bytes.  This distance may span populated buffers, it may span nothing.
+ * This is clearing a region on the L2ARC device ready for writing.
+ * If the 'all' boolean is set, every buffer is evicted.
+ */
+static void
+l2arc_evict(l2arc_dev_t *dev, uint64_t distance, boolean_t all)
+{
+	list_t *buflist;
+	arc_buf_hdr_t *hdr, *hdr_prev;
+	kmutex_t *hash_lock;
+	uint64_t taddr;
+
+	buflist = &dev->l2ad_buflist;
+
+	if (!all && dev->l2ad_first) {
+		/*
+		 * This is the first sweep through the device.  There is
+		 * nothing to evict.
+		 */
+		return;
+	}
+
+	if (dev->l2ad_hand >= (dev->l2ad_end - (2 * distance))) {
+		/*
+		 * When nearing the end of the device, evict to the end
+		 * before the device write hand jumps to the start.
+		 */
+		taddr = dev->l2ad_end;
+	} else {
+		taddr = dev->l2ad_hand + distance;
+	}
+	DTRACE_PROBE4(l2arc__evict, l2arc_dev_t *, dev, list_t *, buflist,
+	    uint64_t, taddr, boolean_t, all);
+
+top:
+	mutex_enter(&dev->l2ad_mtx);
+	for (hdr = list_tail(buflist); hdr; hdr = hdr_prev) {
+		hdr_prev = list_prev(buflist, hdr);
+
+		hash_lock = HDR_LOCK(hdr);
+
+		/*
+		 * We cannot use mutex_enter or else we can deadlock
+		 * with l2arc_write_buffers (due to swapping the order
+		 * the hash lock and l2ad_mtx are taken).
+		 */
+		if (!mutex_tryenter(hash_lock)) {
+			/*
+			 * Missed the hash lock.  Retry.
+			 */
+			ARCSTAT_BUMP(arcstat_l2_evict_lock_retry);
+			mutex_exit(&dev->l2ad_mtx);
+			mutex_enter(hash_lock);
+			mutex_exit(hash_lock);
+			goto top;
+		}
+
+		if (HDR_L2_WRITE_HEAD(hdr)) {
+			/*
+			 * We hit a write head node.  Leave it for
+			 * l2arc_write_done().
+			 */
+			list_remove(buflist, hdr);
+			mutex_exit(hash_lock);
+			continue;
+		}
+
+		if (!all && HDR_HAS_L2HDR(hdr) &&
+		    (hdr->b_l2hdr.b_daddr > taddr ||
+		    hdr->b_l2hdr.b_daddr < dev->l2ad_hand)) {
+			/*
+			 * We've evicted to the target address,
+			 * or the end of the device.
+			 */
+			mutex_exit(hash_lock);
+			break;
+		}
+
+		ASSERT(HDR_HAS_L2HDR(hdr));
+		if (!HDR_HAS_L1HDR(hdr)) {
+			ASSERT(!HDR_L2_READING(hdr));
+			/*
+			 * This doesn't exist in the ARC.  Destroy.
+			 * arc_hdr_destroy() will call list_remove()
+			 * and decrement arcstat_l2_size.
+			 */
+			arc_change_state(arc_anon, hdr, hash_lock);
+			arc_hdr_destroy(hdr);
+		} else {
+			ASSERT(hdr->b_l1hdr.b_state != arc_l2c_only);
+			ARCSTAT_BUMP(arcstat_l2_evict_l1cached);
+			/*
+			 * Invalidate issued or about to be issued
+			 * reads, since we may be about to write
+			 * over this location.
+			 */
+			if (HDR_L2_READING(hdr)) {
+				ARCSTAT_BUMP(arcstat_l2_evict_reading);
+				hdr->b_flags |= ARC_FLAG_L2_EVICTED;
+			}
+
+			/* Ensure this header has finished being written */
+			ASSERT(!HDR_L2_WRITING(hdr));
+			ASSERT3P(hdr->b_l1hdr.b_tmp_cdata, ==, NULL);
+
+			arc_hdr_l2hdr_destroy(hdr);
+		}
+		mutex_exit(hash_lock);
+	}
+	mutex_exit(&dev->l2ad_mtx);
+}
+
+/*
+ * Find and write ARC buffers to the L2ARC device.
+ *
+ * An ARC_FLAG_L2_WRITING flag is set so that the L2ARC buffers are not valid
+ * for reading until they have completed writing.
+ * The headroom_boost is an in-out parameter used to maintain headroom boost
+ * state between calls to this function.
+ *
+ * Returns the number of bytes actually written (which may be smaller than
+ * the delta by which the device hand has changed due to alignment).
+ */
+static uint64_t
+l2arc_write_buffers(spa_t *spa, l2arc_dev_t *dev, uint64_t target_sz,
+    boolean_t *headroom_boost)
+{
+	arc_buf_hdr_t *hdr, *hdr_prev, *head;
+	uint64_t write_asize, write_sz, headroom, buf_compress_minsz,
+	    stats_size;
+	void *buf_data;
+	boolean_t full;
+	l2arc_write_callback_t *cb;
+	zio_t *pio, *wzio;
+	uint64_t guid = spa_load_guid(spa);
+	int try;
+	const boolean_t do_headroom_boost = *headroom_boost;
+
+	ASSERT(dev->l2ad_vdev != NULL);
+
+	/* Lower the flag now, we might want to raise it again later. */
+	*headroom_boost = B_FALSE;
+
+	pio = NULL;
+	write_sz = write_asize = 0;
+	full = B_FALSE;
+	head = kmem_cache_alloc(hdr_l2only_cache, KM_PUSHPAGE);
+	head->b_flags |= ARC_FLAG_L2_WRITE_HEAD;
+	head->b_flags |= ARC_FLAG_HAS_L2HDR;
+
+	/*
+	 * We will want to try to compress buffers that are at least 2x the
+	 * device sector size.
+	 */
+	buf_compress_minsz = 2 << dev->l2ad_vdev->vdev_ashift;
+
+	/*
+	 * Copy buffers for L2ARC writing.
+	 */
+	for (try = 0; try <= 3; try++) {
+		multilist_sublist_t *mls = l2arc_sublist_lock(try);
+		uint64_t passed_sz = 0;
+
+		/*
+		 * L2ARC fast warmup.
+		 *
+		 * Until the ARC is warm and starts to evict, read from the
+		 * head of the ARC lists rather than the tail.
+		 */
+		if (arc_warm == B_FALSE)
+			hdr = multilist_sublist_head(mls);
+		else
+			hdr = multilist_sublist_tail(mls);
+
+		headroom = target_sz * l2arc_headroom;
+		if (do_headroom_boost)
+			headroom = (headroom * l2arc_headroom_boost) / 100;
+
+		for (; hdr; hdr = hdr_prev) {
+			kmutex_t *hash_lock;
+			uint64_t buf_sz;
+			uint64_t buf_a_sz;
+
+			if (arc_warm == B_FALSE)
+				hdr_prev = multilist_sublist_next(mls, hdr);
+			else
+				hdr_prev = multilist_sublist_prev(mls, hdr);
+
+			hash_lock = HDR_LOCK(hdr);
+			if (!mutex_tryenter(hash_lock)) {
+				/*
+				 * Skip this buffer rather than waiting.
+				 */
+				continue;
+			}
+
+			passed_sz += hdr->b_size;
+			if (passed_sz > headroom) {
+				/*
+				 * Searched too far.
+				 */
+				mutex_exit(hash_lock);
+				break;
+			}
+
+			if (!l2arc_write_eligible(guid, hdr)) {
+				mutex_exit(hash_lock);
+				continue;
+			}
+
+			/*
+			 * Assume that the buffer is not going to be compressed
+			 * and could take more space on disk because of a larger
+			 * disk block size.
+			 */
+			buf_sz = hdr->b_size;
+			buf_a_sz = vdev_psize_to_asize(dev->l2ad_vdev, buf_sz);
+
+			if ((write_asize + buf_a_sz) > target_sz) {
+				full = B_TRUE;
+				mutex_exit(hash_lock);
+				break;
+			}
+
+			if (pio == NULL) {
+				/*
+				 * Insert a dummy header on the buflist so
+				 * l2arc_write_done() can find where the
+				 * write buffers begin without searching.
+				 */
+				mutex_enter(&dev->l2ad_mtx);
+				list_insert_head(&dev->l2ad_buflist, head);
+				mutex_exit(&dev->l2ad_mtx);
+
+				cb = kmem_alloc(
+				    sizeof (l2arc_write_callback_t), KM_SLEEP);
+				cb->l2wcb_dev = dev;
+				cb->l2wcb_head = head;
+				pio = zio_root(spa, l2arc_write_done, cb,
+				    ZIO_FLAG_CANFAIL);
+			}
+
+			/*
+			 * Create and add a new L2ARC header.
+			 */
+			hdr->b_l2hdr.b_dev = dev;
+			hdr->b_flags |= ARC_FLAG_L2_WRITING;
+			/*
+			 * Temporarily stash the data buffer in b_tmp_cdata.
+			 * The subsequent write step will pick it up from
+			 * there. This is because can't access b_l1hdr.b_buf
+			 * without holding the hash_lock, which we in turn
+			 * can't access without holding the ARC list locks
+			 * (which we want to avoid during compression/writing)
+			 */
+			hdr->b_l2hdr.b_compress = ZIO_COMPRESS_OFF;
+			hdr->b_l2hdr.b_asize = hdr->b_size;
+			hdr->b_l2hdr.b_hits = 0;
+			hdr->b_l1hdr.b_tmp_cdata = hdr->b_l1hdr.b_buf->b_data;
+
+			/*
+			 * Explicitly set the b_daddr field to a known
+			 * value which means "invalid address". This
+			 * enables us to differentiate which stage of
+			 * l2arc_write_buffers() the particular header
+			 * is in (e.g. this loop, or the one below).
+			 * ARC_FLAG_L2_WRITING is not enough to make
+			 * this distinction, and we need to know in
+			 * order to do proper l2arc vdev accounting in
+			 * arc_release() and arc_hdr_destroy().
+			 *
+			 * Note, we can't use a new flag to distinguish
+			 * the two stages because we don't hold the
+			 * header's hash_lock below, in the second stage
+			 * of this function. Thus, we can't simply
+			 * change the b_flags field to denote that the
+			 * IO has been sent. We can change the b_daddr
+			 * field of the L2 portion, though, since we'll
+			 * be holding the l2ad_mtx; which is why we're
+			 * using it to denote the header's state change.
+			 */
+			hdr->b_l2hdr.b_daddr = L2ARC_ADDR_UNSET;
+			hdr->b_flags |= ARC_FLAG_HAS_L2HDR;
+
+			mutex_enter(&dev->l2ad_mtx);
+			list_insert_head(&dev->l2ad_buflist, hdr);
+			mutex_exit(&dev->l2ad_mtx);
+
+			/*
+			 * Compute and store the buffer cksum before
+			 * writing.  On debug the cksum is verified first.
+			 */
+			arc_cksum_verify(hdr->b_l1hdr.b_buf);
+			arc_cksum_compute(hdr->b_l1hdr.b_buf, B_TRUE);
+
+			mutex_exit(hash_lock);
+
+			write_sz += buf_sz;
+			write_asize += buf_a_sz;
+		}
+
+		multilist_sublist_unlock(mls);
+
+		if (full == B_TRUE)
+			break;
+	}
+
+	/* No buffers selected for writing? */
+	if (pio == NULL) {
+		ASSERT0(write_sz);
+		ASSERT(!HDR_HAS_L1HDR(head));
+		kmem_cache_free(hdr_l2only_cache, head);
+		return (0);
+	}
+
+	mutex_enter(&dev->l2ad_mtx);
+
+	/*
+	 * Note that elsewhere in this file arcstat_l2_asize
+	 * and the used space on l2ad_vdev are updated using b_asize,
+	 * which is not necessarily rounded up to the device block size.
+	 * Too keep accounting consistent we do the same here as well:
+	 * stats_size accumulates the sum of b_asize of the written buffers,
+	 * while write_asize accumulates the sum of b_asize rounded up
+	 * to the device block size.
+	 * The latter sum is used only to validate the corectness of the code.
+	 */
+	stats_size = 0;
+	write_asize = 0;
+
+	/*
+	 * Now start writing the buffers. We're starting at the write head
+	 * and work backwards, retracing the course of the buffer selector
+	 * loop above.
+	 */
+	for (hdr = list_prev(&dev->l2ad_buflist, head); hdr;
+	    hdr = list_prev(&dev->l2ad_buflist, hdr)) {
+		uint64_t buf_sz;
+
+		/*
+		 * We rely on the L1 portion of the header below, so
+		 * it's invalid for this header to have been evicted out
+		 * of the ghost cache, prior to being written out. The
+		 * ARC_FLAG_L2_WRITING bit ensures this won't happen.
+		 */
+		ASSERT(HDR_HAS_L1HDR(hdr));
+
+		/*
+		 * We shouldn't need to lock the buffer here, since we flagged
+		 * it as ARC_FLAG_L2_WRITING in the previous step, but we must
+		 * take care to only access its L2 cache parameters. In
+		 * particular, hdr->l1hdr.b_buf may be invalid by now due to
+		 * ARC eviction.
+		 */
+		hdr->b_l2hdr.b_daddr = dev->l2ad_hand;
+
+		if ((!l2arc_nocompress && HDR_L2COMPRESS(hdr)) &&
+		    hdr->b_l2hdr.b_asize >= buf_compress_minsz) {
+			if (l2arc_compress_buf(hdr)) {
+				/*
+				 * If compression succeeded, enable headroom
+				 * boost on the next scan cycle.
+				 */
+				*headroom_boost = B_TRUE;
+			}
+		}
+
+		/*
+		 * Pick up the buffer data we had previously stashed away
+		 * (and now potentially also compressed).
+		 */
+		buf_data = hdr->b_l1hdr.b_tmp_cdata;
+		buf_sz = hdr->b_l2hdr.b_asize;
+
+		/*
+		 * We need to do this regardless if buf_sz is zero or
+		 * not, otherwise, when this l2hdr is evicted we'll
+		 * remove a reference that was never added.
+		 */
+		(void) refcount_add_many(&dev->l2ad_alloc, buf_sz, hdr);
+
+		/* Compression may have squashed the buffer to zero length. */
+		if (buf_sz != 0) {
+			uint64_t buf_a_sz;
+
+			wzio = zio_write_phys(pio, dev->l2ad_vdev,
+			    dev->l2ad_hand, buf_sz, buf_data, ZIO_CHECKSUM_OFF,
+			    NULL, NULL, ZIO_PRIORITY_ASYNC_WRITE,
+			    ZIO_FLAG_CANFAIL, B_FALSE);
+
+			DTRACE_PROBE2(l2arc__write, vdev_t *, dev->l2ad_vdev,
+			    zio_t *, wzio);
+			(void) zio_nowait(wzio);
+
+			stats_size += buf_sz;
+
+			/*
+			 * Keep the clock hand suitably device-aligned.
+			 */
+			buf_a_sz = vdev_psize_to_asize(dev->l2ad_vdev, buf_sz);
+			write_asize += buf_a_sz;
+			dev->l2ad_hand += buf_a_sz;
+		}
+	}
+
+	mutex_exit(&dev->l2ad_mtx);
+
+	ASSERT3U(write_asize, <=, target_sz);
+	ARCSTAT_BUMP(arcstat_l2_writes_sent);
+	ARCSTAT_INCR(arcstat_l2_write_bytes, write_asize);
+	ARCSTAT_INCR(arcstat_l2_size, write_sz);
+	ARCSTAT_INCR(arcstat_l2_asize, stats_size);
+	vdev_space_update(dev->l2ad_vdev, stats_size, 0, 0);
+
+	/*
+	 * Bump device hand to the device start if it is approaching the end.
+	 * l2arc_evict() will already have evicted ahead for this case.
+	 */
+	if (dev->l2ad_hand >= (dev->l2ad_end - target_sz)) {
+		dev->l2ad_hand = dev->l2ad_start;
+		dev->l2ad_first = B_FALSE;
+	}
+
+	dev->l2ad_writing = B_TRUE;
+	(void) zio_wait(pio);
+	dev->l2ad_writing = B_FALSE;
+
+	return (write_asize);
+}
+
+/*
+ * Compresses an L2ARC buffer.
+ * The data to be compressed must be prefilled in l1hdr.b_tmp_cdata and its
+ * size in l2hdr->b_asize. This routine tries to compress the data and
+ * depending on the compression result there are three possible outcomes:
+ * *) The buffer was incompressible. The original l2hdr contents were left
+ *    untouched and are ready for writing to an L2 device.
+ * *) The buffer was all-zeros, so there is no need to write it to an L2
+ *    device. To indicate this situation b_tmp_cdata is NULL'ed, b_asize is
+ *    set to zero and b_compress is set to ZIO_COMPRESS_EMPTY.
+ * *) Compression succeeded and b_tmp_cdata was replaced with a temporary
+ *    data buffer which holds the compressed data to be written, and b_asize
+ *    tells us how much data there is. b_compress is set to the appropriate
+ *    compression algorithm. Once writing is done, invoke
+ *    l2arc_release_cdata_buf on this l2hdr to free this temporary buffer.
+ *
+ * Returns B_TRUE if compression succeeded, or B_FALSE if it didn't (the
+ * buffer was incompressible).
+ */
+static boolean_t
+l2arc_compress_buf(arc_buf_hdr_t *hdr)
+{
+	void *cdata;
+	size_t csize, len, rounded;
+	l2arc_buf_hdr_t *l2hdr;
+
+	ASSERT(HDR_HAS_L2HDR(hdr));
+
+	l2hdr = &hdr->b_l2hdr;
+
+	ASSERT(HDR_HAS_L1HDR(hdr));
+	ASSERT3U(l2hdr->b_compress, ==, ZIO_COMPRESS_OFF);
+	ASSERT(hdr->b_l1hdr.b_tmp_cdata != NULL);
+
+	len = l2hdr->b_asize;
+	cdata = zio_data_buf_alloc(len);
+	ASSERT3P(cdata, !=, NULL);
+	csize = zio_compress_data(ZIO_COMPRESS_LZ4, hdr->b_l1hdr.b_tmp_cdata,
+	    cdata, l2hdr->b_asize);
+
+	rounded = P2ROUNDUP(csize, (size_t)SPA_MINBLOCKSIZE);
+	if (rounded > csize) {
+		bzero((char *)cdata + csize, rounded - csize);
+		csize = rounded;
+	}
+
+	if (csize == 0) {
+		/* zero block, indicate that there's nothing to write */
+		zio_data_buf_free(cdata, len);
+		l2hdr->b_compress = ZIO_COMPRESS_EMPTY;
+		l2hdr->b_asize = 0;
+		hdr->b_l1hdr.b_tmp_cdata = NULL;
+		ARCSTAT_BUMP(arcstat_l2_compress_zeros);
+		return (B_TRUE);
+	} else if (csize > 0 && csize < len) {
+		/*
+		 * Compression succeeded, we'll keep the cdata around for
+		 * writing and release it afterwards.
+		 */
+		l2hdr->b_compress = ZIO_COMPRESS_LZ4;
+		l2hdr->b_asize = csize;
+		hdr->b_l1hdr.b_tmp_cdata = cdata;
+		ARCSTAT_BUMP(arcstat_l2_compress_successes);
+		return (B_TRUE);
+	} else {
+		/*
+		 * Compression failed, release the compressed buffer.
+		 * l2hdr will be left unmodified.
+		 */
+		zio_data_buf_free(cdata, len);
+		ARCSTAT_BUMP(arcstat_l2_compress_failures);
+		return (B_FALSE);
+	}
+}
+
+/*
+ * Decompresses a zio read back from an l2arc device. On success, the
+ * underlying zio's io_data buffer is overwritten by the uncompressed
+ * version. On decompression error (corrupt compressed stream), the
+ * zio->io_error value is set to signal an I/O error.
+ *
+ * Please note that the compressed data stream is not checksummed, so
+ * if the underlying device is experiencing data corruption, we may feed
+ * corrupt data to the decompressor, so the decompressor needs to be
+ * able to handle this situation (LZ4 does).
+ */
+static void
+l2arc_decompress_zio(zio_t *zio, arc_buf_hdr_t *hdr, enum zio_compress c)
+{
+	uint64_t csize;
+	void *cdata;
+
+	ASSERT(L2ARC_IS_VALID_COMPRESS(c));
+
+	if (zio->io_error != 0) {
+		/*
+		 * An io error has occured, just restore the original io
+		 * size in preparation for a main pool read.
+		 */
+		zio->io_orig_size = zio->io_size = hdr->b_size;
+		return;
+	}
+
+	if (c == ZIO_COMPRESS_EMPTY) {
+		/*
+		 * An empty buffer results in a null zio, which means we
+		 * need to fill its io_data after we're done restoring the
+		 * buffer's contents.
+		 */
+		ASSERT(hdr->b_l1hdr.b_buf != NULL);
+		bzero(hdr->b_l1hdr.b_buf->b_data, hdr->b_size);
+		zio->io_data = zio->io_orig_data = hdr->b_l1hdr.b_buf->b_data;
+	} else {
+		ASSERT(zio->io_data != NULL);
+		/*
+		 * We copy the compressed data from the start of the arc buffer
+		 * (the zio_read will have pulled in only what we need, the
+		 * rest is garbage which we will overwrite at decompression)
+		 * and then decompress back to the ARC data buffer. This way we
+		 * can minimize copying by simply decompressing back over the
+		 * original compressed data (rather than decompressing to an
+		 * aux buffer and then copying back the uncompressed buffer,
+		 * which is likely to be much larger).
+		 */
+		csize = zio->io_size;
+		cdata = zio_data_buf_alloc(csize);
+		bcopy(zio->io_data, cdata, csize);
+		if (zio_decompress_data(c, cdata, zio->io_data, csize,
+		    hdr->b_size) != 0)
+			zio->io_error = EIO;
+		zio_data_buf_free(cdata, csize);
+	}
+
+	/* Restore the expected uncompressed IO size. */
+	zio->io_orig_size = zio->io_size = hdr->b_size;
+}
+
+/*
+ * Releases the temporary b_tmp_cdata buffer in an l2arc header structure.
+ * This buffer serves as a temporary holder of compressed data while
+ * the buffer entry is being written to an l2arc device. Once that is
+ * done, we can dispose of it.
+ */
+static void
+l2arc_release_cdata_buf(arc_buf_hdr_t *hdr)
+{
+	enum zio_compress comp;
+
+	ASSERT(HDR_HAS_L1HDR(hdr));
+	ASSERT(HDR_HAS_L2HDR(hdr));
+	comp = hdr->b_l2hdr.b_compress;
+	ASSERT(comp == ZIO_COMPRESS_OFF || L2ARC_IS_VALID_COMPRESS(comp));
+
+	if (comp == ZIO_COMPRESS_OFF) {
+		/*
+		 * In this case, b_tmp_cdata points to the same buffer
+		 * as the arc_buf_t's b_data field. We don't want to
+		 * free it, since the arc_buf_t will handle that.
+		 */
+		hdr->b_l1hdr.b_tmp_cdata = NULL;
+	} else if (comp == ZIO_COMPRESS_EMPTY) {
+		/*
+		 * In this case, b_tmp_cdata was compressed to an empty
+		 * buffer, thus there's nothing to free and b_tmp_cdata
+		 * should have been set to NULL in l2arc_write_buffers().
+		 */
+		ASSERT3P(hdr->b_l1hdr.b_tmp_cdata, ==, NULL);
+	} else {
+		/*
+		 * If the data was compressed, then we've allocated a
+		 * temporary buffer for it, so now we need to release it.
+		 */
+		ASSERT(hdr->b_l1hdr.b_tmp_cdata != NULL);
+		zio_data_buf_free(hdr->b_l1hdr.b_tmp_cdata,
+		    hdr->b_size);
+		hdr->b_l1hdr.b_tmp_cdata = NULL;
+	}
+
+}
+
+/*
+ * This thread feeds the L2ARC at regular intervals.  This is the beating
+ * heart of the L2ARC.
+ */
+static void
+l2arc_feed_thread(void)
+{
+	callb_cpr_t cpr;
+	l2arc_dev_t *dev;
+	spa_t *spa;
+	uint64_t size, wrote;
+	clock_t begin, next = ddi_get_lbolt();
+	boolean_t headroom_boost = B_FALSE;
+	fstrans_cookie_t cookie;
+
+	CALLB_CPR_INIT(&cpr, &l2arc_feed_thr_lock, callb_generic_cpr, FTAG);
+
+	mutex_enter(&l2arc_feed_thr_lock);
+
+	cookie = spl_fstrans_mark();
+	while (l2arc_thread_exit == 0) {
+		CALLB_CPR_SAFE_BEGIN(&cpr);
+		(void) cv_timedwait_sig(&l2arc_feed_thr_cv,
+		    &l2arc_feed_thr_lock, next);
+		CALLB_CPR_SAFE_END(&cpr, &l2arc_feed_thr_lock);
+		next = ddi_get_lbolt() + hz;
+
+		/*
+		 * Quick check for L2ARC devices.
+		 */
+		mutex_enter(&l2arc_dev_mtx);
+		if (l2arc_ndev == 0) {
+			mutex_exit(&l2arc_dev_mtx);
+			continue;
+		}
+		mutex_exit(&l2arc_dev_mtx);
+		begin = ddi_get_lbolt();
+
+		/*
+		 * This selects the next l2arc device to write to, and in
+		 * doing so the next spa to feed from: dev->l2ad_spa.   This
+		 * will return NULL if there are now no l2arc devices or if
+		 * they are all faulted.
+		 *
+		 * If a device is returned, its spa's config lock is also
+		 * held to prevent device removal.  l2arc_dev_get_next()
+		 * will grab and release l2arc_dev_mtx.
+		 */
+		if ((dev = l2arc_dev_get_next()) == NULL)
+			continue;
+
+		spa = dev->l2ad_spa;
+		ASSERT(spa != NULL);
+
+		/*
+		 * If the pool is read-only then force the feed thread to
+		 * sleep a little longer.
+		 */
+		if (!spa_writeable(spa)) {
+			next = ddi_get_lbolt() + 5 * l2arc_feed_secs * hz;
+			spa_config_exit(spa, SCL_L2ARC, dev);
+			continue;
+		}
+
+		/*
+		 * Avoid contributing to memory pressure.
+		 */
+		if (arc_reclaim_needed()) {
+			ARCSTAT_BUMP(arcstat_l2_abort_lowmem);
+			spa_config_exit(spa, SCL_L2ARC, dev);
+			continue;
+		}
+
+		ARCSTAT_BUMP(arcstat_l2_feeds);
+
+		size = l2arc_write_size();
+
+		/*
+		 * Evict L2ARC buffers that will be overwritten.
+		 */
+		l2arc_evict(dev, size, B_FALSE);
+
+		/*
+		 * Write ARC buffers.
+		 */
+		wrote = l2arc_write_buffers(spa, dev, size, &headroom_boost);
+
+		/*
+		 * Calculate interval between writes.
+		 */
+		next = l2arc_write_interval(begin, size, wrote);
+		spa_config_exit(spa, SCL_L2ARC, dev);
+	}
+	spl_fstrans_unmark(cookie);
+
+	l2arc_thread_exit = 0;
+	cv_broadcast(&l2arc_feed_thr_cv);
+	CALLB_CPR_EXIT(&cpr);		/* drops l2arc_feed_thr_lock */
+	thread_exit();
+}
+
+boolean_t
+l2arc_vdev_present(vdev_t *vd)
+{
+	l2arc_dev_t *dev;
+
+	mutex_enter(&l2arc_dev_mtx);
+	for (dev = list_head(l2arc_dev_list); dev != NULL;
+	    dev = list_next(l2arc_dev_list, dev)) {
+		if (dev->l2ad_vdev == vd)
+			break;
+	}
+	mutex_exit(&l2arc_dev_mtx);
+
+	return (dev != NULL);
+}
+
+/*
+ * Add a vdev for use by the L2ARC.  By this point the spa has already
+ * validated the vdev and opened it.
+ */
+void
+l2arc_add_vdev(spa_t *spa, vdev_t *vd)
+{
+	l2arc_dev_t *adddev;
+
+	ASSERT(!l2arc_vdev_present(vd));
+
+	/*
+	 * Create a new l2arc device entry.
+	 */
+	adddev = kmem_zalloc(sizeof (l2arc_dev_t), KM_SLEEP);
+	adddev->l2ad_spa = spa;
+	adddev->l2ad_vdev = vd;
+	adddev->l2ad_start = VDEV_LABEL_START_SIZE;
+	adddev->l2ad_end = VDEV_LABEL_START_SIZE + vdev_get_min_asize(vd);
+	adddev->l2ad_hand = adddev->l2ad_start;
+	adddev->l2ad_first = B_TRUE;
+	adddev->l2ad_writing = B_FALSE;
+	list_link_init(&adddev->l2ad_node);
+
+	mutex_init(&adddev->l2ad_mtx, NULL, MUTEX_DEFAULT, NULL);
+	/*
+	 * This is a list of all ARC buffers that are still valid on the
+	 * device.
+	 */
+	list_create(&adddev->l2ad_buflist, sizeof (arc_buf_hdr_t),
+	    offsetof(arc_buf_hdr_t, b_l2hdr.b_l2node));
+
+	vdev_space_update(vd, 0, 0, adddev->l2ad_end - adddev->l2ad_hand);
+	refcount_create(&adddev->l2ad_alloc);
+
+	/*
+	 * Add device to global list
+	 */
+	mutex_enter(&l2arc_dev_mtx);
+	list_insert_head(l2arc_dev_list, adddev);
+	atomic_inc_64(&l2arc_ndev);
+	mutex_exit(&l2arc_dev_mtx);
+}
+
+/*
+ * Remove a vdev from the L2ARC.
+ */
+void
+l2arc_remove_vdev(vdev_t *vd)
+{
+	l2arc_dev_t *dev, *nextdev, *remdev = NULL;
+
+	/*
+	 * Find the device by vdev
+	 */
+	mutex_enter(&l2arc_dev_mtx);
+	for (dev = list_head(l2arc_dev_list); dev; dev = nextdev) {
+		nextdev = list_next(l2arc_dev_list, dev);
+		if (vd == dev->l2ad_vdev) {
+			remdev = dev;
+			break;
+		}
+	}
+	ASSERT(remdev != NULL);
+
+	/*
+	 * Remove device from global list
+	 */
+	list_remove(l2arc_dev_list, remdev);
+	l2arc_dev_last = NULL;		/* may have been invalidated */
+	atomic_dec_64(&l2arc_ndev);
+	mutex_exit(&l2arc_dev_mtx);
+
+	/*
+	 * Clear all buflists and ARC references.  L2ARC device flush.
+	 */
+	l2arc_evict(remdev, 0, B_TRUE);
+	list_destroy(&remdev->l2ad_buflist);
+	mutex_destroy(&remdev->l2ad_mtx);
+	refcount_destroy(&remdev->l2ad_alloc);
+	kmem_free(remdev, sizeof (l2arc_dev_t));
+}
+
+void
+l2arc_init(void)
+{
+	l2arc_thread_exit = 0;
+	l2arc_ndev = 0;
+	l2arc_writes_sent = 0;
+	l2arc_writes_done = 0;
+
+	mutex_init(&l2arc_feed_thr_lock, NULL, MUTEX_DEFAULT, NULL);
+	cv_init(&l2arc_feed_thr_cv, NULL, CV_DEFAULT, NULL);
+	mutex_init(&l2arc_dev_mtx, NULL, MUTEX_DEFAULT, NULL);
+	mutex_init(&l2arc_free_on_write_mtx, NULL, MUTEX_DEFAULT, NULL);
+
+	l2arc_dev_list = &L2ARC_dev_list;
+	l2arc_free_on_write = &L2ARC_free_on_write;
+	list_create(l2arc_dev_list, sizeof (l2arc_dev_t),
+	    offsetof(l2arc_dev_t, l2ad_node));
+	list_create(l2arc_free_on_write, sizeof (l2arc_data_free_t),
+	    offsetof(l2arc_data_free_t, l2df_list_node));
+}
+
+void
+l2arc_fini(void)
+{
+	/*
+	 * This is called from dmu_fini(), which is called from spa_fini();
+	 * Because of this, we can assume that all l2arc devices have
+	 * already been removed when the pools themselves were removed.
+	 */
+
+	l2arc_do_free_on_write();
+
+	mutex_destroy(&l2arc_feed_thr_lock);
+	cv_destroy(&l2arc_feed_thr_cv);
+	mutex_destroy(&l2arc_dev_mtx);
+	mutex_destroy(&l2arc_free_on_write_mtx);
+
+	list_destroy(l2arc_dev_list);
+	list_destroy(l2arc_free_on_write);
+}
+
+void
+l2arc_start(void)
+{
+	if (!(spa_mode_global & FWRITE))
+		return;
+
+	(void) thread_create(NULL, 0, l2arc_feed_thread, NULL, 0, &p0,
+	    TS_RUN, defclsyspri);
+}
+
+void
+l2arc_stop(void)
+{
+	if (!(spa_mode_global & FWRITE))
+		return;
+
+	mutex_enter(&l2arc_feed_thr_lock);
+	cv_signal(&l2arc_feed_thr_cv);	/* kick thread out of startup */
+	l2arc_thread_exit = 1;
+	while (l2arc_thread_exit != 0)
+		cv_wait(&l2arc_feed_thr_cv, &l2arc_feed_thr_lock);
+	mutex_exit(&l2arc_feed_thr_lock);
+}
+
+#if defined(_KERNEL) && defined(HAVE_SPL)
+EXPORT_SYMBOL(arc_buf_size);
+EXPORT_SYMBOL(arc_write);
+EXPORT_SYMBOL(arc_read);
+EXPORT_SYMBOL(arc_buf_remove_ref);
+EXPORT_SYMBOL(arc_buf_info);
+EXPORT_SYMBOL(arc_getbuf_func);
+EXPORT_SYMBOL(arc_add_prune_callback);
+EXPORT_SYMBOL(arc_remove_prune_callback);
+
+module_param(zfs_arc_min, ulong, 0644);
+MODULE_PARM_DESC(zfs_arc_min, "Min arc size");
+
+module_param(zfs_arc_max, ulong, 0644);
+MODULE_PARM_DESC(zfs_arc_max, "Max arc size");
+
+module_param(zfs_arc_meta_limit, ulong, 0644);
+MODULE_PARM_DESC(zfs_arc_meta_limit, "Meta limit for arc size");
+
+module_param(zfs_arc_meta_min, ulong, 0644);
+MODULE_PARM_DESC(zfs_arc_meta_min, "Min arc metadata");
+
+module_param(zfs_arc_meta_prune, int, 0644);
+MODULE_PARM_DESC(zfs_arc_meta_prune, "Meta objects to scan for prune");
+
+module_param(zfs_arc_meta_adjust_restarts, int, 0644);
+MODULE_PARM_DESC(zfs_arc_meta_adjust_restarts,
+	"Limit number of restarts in arc_adjust_meta");
+
+module_param(zfs_arc_meta_strategy, int, 0644);
+MODULE_PARM_DESC(zfs_arc_meta_strategy, "Meta reclaim strategy");
+
+module_param(zfs_arc_grow_retry, int, 0644);
+MODULE_PARM_DESC(zfs_arc_grow_retry, "Seconds before growing arc size");
+
+module_param(zfs_arc_p_aggressive_disable, int, 0644);
+MODULE_PARM_DESC(zfs_arc_p_aggressive_disable, "disable aggressive arc_p grow");
+
+module_param(zfs_arc_p_dampener_disable, int, 0644);
+MODULE_PARM_DESC(zfs_arc_p_dampener_disable, "disable arc_p adapt dampener");
+
+module_param(zfs_arc_shrink_shift, int, 0644);
+MODULE_PARM_DESC(zfs_arc_shrink_shift, "log2(fraction of arc to reclaim)");
+
+module_param(zfs_arc_p_min_shift, int, 0644);
+MODULE_PARM_DESC(zfs_arc_p_min_shift, "arc_c shift to calc min/max arc_p");
+
+module_param(zfs_disable_dup_eviction, int, 0644);
+MODULE_PARM_DESC(zfs_disable_dup_eviction, "disable duplicate buffer eviction");
+
+module_param(zfs_arc_average_blocksize, int, 0444);
+MODULE_PARM_DESC(zfs_arc_average_blocksize, "Target average block size");
+
+module_param(zfs_arc_min_prefetch_lifespan, int, 0644);
+MODULE_PARM_DESC(zfs_arc_min_prefetch_lifespan, "Min life of prefetch block");
+
+module_param(zfs_arc_num_sublists_per_state, int, 0644);
+MODULE_PARM_DESC(zfs_arc_num_sublists_per_state,
+	"Number of sublists used in each of the ARC state lists");
+
+module_param(l2arc_write_max, ulong, 0644);
+MODULE_PARM_DESC(l2arc_write_max, "Max write bytes per interval");
+
+module_param(l2arc_write_boost, ulong, 0644);
+MODULE_PARM_DESC(l2arc_write_boost, "Extra write bytes during device warmup");
+
+module_param(l2arc_headroom, ulong, 0644);
+MODULE_PARM_DESC(l2arc_headroom, "Number of max device writes to precache");
+
+module_param(l2arc_headroom_boost, ulong, 0644);
+MODULE_PARM_DESC(l2arc_headroom_boost, "Compressed l2arc_headroom multiplier");
+
+module_param(l2arc_feed_secs, ulong, 0644);
+MODULE_PARM_DESC(l2arc_feed_secs, "Seconds between L2ARC writing");
+
+module_param(l2arc_feed_min_ms, ulong, 0644);
+MODULE_PARM_DESC(l2arc_feed_min_ms, "Min feed interval in milliseconds");
+
+module_param(l2arc_noprefetch, int, 0644);
+MODULE_PARM_DESC(l2arc_noprefetch, "Skip caching prefetched buffers");
+
+module_param(l2arc_nocompress, int, 0644);
+MODULE_PARM_DESC(l2arc_nocompress, "Skip compressing L2ARC buffers");
+
+module_param(l2arc_feed_again, int, 0644);
+MODULE_PARM_DESC(l2arc_feed_again, "Turbo L2ARC warmup");
+
+module_param(l2arc_norw, int, 0644);
+MODULE_PARM_DESC(l2arc_norw, "No reads during writes");
+
+module_param(zfs_arc_lotsfree_percent, int, 0644);
+MODULE_PARM_DESC(zfs_arc_lotsfree_percent,
+	"System free memory I/O throttle in bytes");
+
+module_param(zfs_arc_sys_free, ulong, 0644);
+MODULE_PARM_DESC(zfs_arc_sys_free, "System free memory target size in bytes");
+
+#endif
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/module/zfs/blkptr.c
@@ -0,0 +1,121 @@
+/*
+ * CDDL HEADER START
+ *
+ * This file and its contents are supplied under the terms of the
+ * Common Development and Distribution License ("CDDL"), version 1.0.
+ * You may only use this file in accordance with the terms of version
+ * 1.0 of the CDDL.
+ *
+ * A full copy of the text of the CDDL should have accompanied this
+ * source.  A copy of the CDDL is also available via the Internet at
+ * http://www.illumos.org/license/CDDL.
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2013 by Delphix. All rights reserved.
+ */
+
+#include <sys/zfs_context.h>
+#include <sys/zio.h>
+#include <sys/zio_compress.h>
+
+/*
+ * Embedded-data Block Pointers
+ *
+ * Normally, block pointers point (via their DVAs) to a block which holds data.
+ * If the data that we need to store is very small, this is an inefficient
+ * use of space, because a block must be at minimum 1 sector (typically 512
+ * bytes or 4KB).  Additionally, reading these small blocks tends to generate
+ * more random reads.
+ *
+ * Embedded-data Block Pointers allow small pieces of data (the "payload",
+ * up to 112 bytes) to be stored in the block pointer itself, instead of
+ * being pointed to.  The "Pointer" part of this name is a bit of a
+ * misnomer, as nothing is pointed to.
+ *
+ * BP_EMBEDDED_TYPE_DATA block pointers allow highly-compressible data to
+ * be embedded in the block pointer.  The logic for this is handled in
+ * the SPA, by the zio pipeline.  Therefore most code outside the zio
+ * pipeline doesn't need special-cases to handle these block pointers.
+ *
+ * See spa.h for details on the exact layout of embedded block pointers.
+ */
+
+void
+encode_embedded_bp_compressed(blkptr_t *bp, void *data,
+    enum zio_compress comp, int uncompressed_size, int compressed_size)
+{
+	uint64_t *bp64 = (uint64_t *)bp;
+	uint64_t w = 0;
+	uint8_t *data8 = data;
+	int i;
+
+	ASSERT3U(compressed_size, <=, BPE_PAYLOAD_SIZE);
+	ASSERT(uncompressed_size == compressed_size ||
+	    comp != ZIO_COMPRESS_OFF);
+	ASSERT3U(comp, >=, ZIO_COMPRESS_OFF);
+	ASSERT3U(comp, <, ZIO_COMPRESS_FUNCTIONS);
+
+	bzero(bp, sizeof (*bp));
+	BP_SET_EMBEDDED(bp, B_TRUE);
+	BP_SET_COMPRESS(bp, comp);
+	BP_SET_BYTEORDER(bp, ZFS_HOST_BYTEORDER);
+	BPE_SET_LSIZE(bp, uncompressed_size);
+	BPE_SET_PSIZE(bp, compressed_size);
+
+	/*
+	 * Encode the byte array into the words of the block pointer.
+	 * First byte goes into low bits of first word (little endian).
+	 */
+	for (i = 0; i < compressed_size; i++) {
+		BF64_SET(w, (i % sizeof (w)) * NBBY, NBBY, data8[i]);
+		if (i % sizeof (w) == sizeof (w) - 1) {
+			/* we've reached the end of a word */
+			ASSERT3P(bp64, <, bp + 1);
+			*bp64 = w;
+			bp64++;
+			if (!BPE_IS_PAYLOADWORD(bp, bp64))
+				bp64++;
+			w = 0;
+		}
+	}
+	/* write last partial word */
+	if (bp64 < (uint64_t *)(bp + 1))
+		*bp64 = w;
+}
+
+/*
+ * buf must be at least BPE_GET_PSIZE(bp) bytes long (which will never be
+ * more than BPE_PAYLOAD_SIZE bytes).
+ */
+void
+decode_embedded_bp_compressed(const blkptr_t *bp, void *buf)
+{
+	int psize;
+	uint8_t *buf8 = buf;
+	uint64_t w = 0;
+	const uint64_t *bp64 = (const uint64_t *)bp;
+	int i;
+
+	ASSERT(BP_IS_EMBEDDED(bp));
+
+	psize = BPE_GET_PSIZE(bp);
+
+	/*
+	 * Decode the words of the block pointer into the byte array.
+	 * Low bits of first word are the first byte (little endian).
+	 */
+	for (i = 0; i < psize; i++) {
+		if (i % sizeof (w) == 0) {
+			/* beginning of a word */
+			ASSERT3P(bp64, <, bp + 1);
+			w = *bp64;
+			bp64++;
+			if (!BPE_IS_PAYLOADWORD(bp, bp64))
+				bp64++;
+		}
+		buf8[i] = BF64_GET(w, (i % sizeof (w)) * NBBY, NBBY);
+	}
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/module/zfs/bplist.c
@@ -0,0 +1,77 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012 by Delphix. All rights reserved.
+ */
+
+#include <sys/bplist.h>
+#include <sys/zfs_context.h>
+
+
+void
+bplist_create(bplist_t *bpl)
+{
+	mutex_init(&bpl->bpl_lock, NULL, MUTEX_DEFAULT, NULL);
+	list_create(&bpl->bpl_list, sizeof (bplist_entry_t),
+	    offsetof(bplist_entry_t, bpe_node));
+}
+
+void
+bplist_destroy(bplist_t *bpl)
+{
+	list_destroy(&bpl->bpl_list);
+	mutex_destroy(&bpl->bpl_lock);
+}
+
+void
+bplist_append(bplist_t *bpl, const blkptr_t *bp)
+{
+	bplist_entry_t *bpe = kmem_alloc(sizeof (*bpe), KM_SLEEP);
+
+	mutex_enter(&bpl->bpl_lock);
+	bpe->bpe_blk = *bp;
+	list_insert_tail(&bpl->bpl_list, bpe);
+	mutex_exit(&bpl->bpl_lock);
+}
+
+/*
+ * To aid debugging, we keep the most recently removed entry.  This way if
+ * we are in the callback, we can easily locate the entry.
+ */
+static bplist_entry_t *bplist_iterate_last_removed;
+
+void
+bplist_iterate(bplist_t *bpl, bplist_itor_t *func, void *arg, dmu_tx_t *tx)
+{
+	bplist_entry_t *bpe;
+
+	mutex_enter(&bpl->bpl_lock);
+	while ((bpe = list_head(&bpl->bpl_list))) {
+		bplist_iterate_last_removed = bpe;
+		list_remove(&bpl->bpl_list, bpe);
+		mutex_exit(&bpl->bpl_lock);
+		func(arg, &bpe->bpe_blk, tx);
+		kmem_free(bpe, sizeof (*bpe));
+		mutex_enter(&bpl->bpl_lock);
+	}
+	mutex_exit(&bpl->bpl_lock);
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/module/zfs/bpobj.c
@@ -0,0 +1,591 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2014 by Delphix. All rights reserved.
+ */
+
+#include <sys/bpobj.h>
+#include <sys/zfs_context.h>
+#include <sys/refcount.h>
+#include <sys/dsl_pool.h>
+#include <sys/zfeature.h>
+#include <sys/zap.h>
+
+/*
+ * Return an empty bpobj, preferably the empty dummy one (dp_empty_bpobj).
+ */
+uint64_t
+bpobj_alloc_empty(objset_t *os, int blocksize, dmu_tx_t *tx)
+{
+	spa_t *spa = dmu_objset_spa(os);
+	dsl_pool_t *dp = dmu_objset_pool(os);
+
+	if (spa_feature_is_enabled(spa, SPA_FEATURE_EMPTY_BPOBJ)) {
+		if (!spa_feature_is_active(spa, SPA_FEATURE_EMPTY_BPOBJ)) {
+			ASSERT0(dp->dp_empty_bpobj);
+			dp->dp_empty_bpobj =
+			    bpobj_alloc(os, SPA_OLD_MAXBLOCKSIZE, tx);
+			VERIFY(zap_add(os,
+			    DMU_POOL_DIRECTORY_OBJECT,
+			    DMU_POOL_EMPTY_BPOBJ, sizeof (uint64_t), 1,
+			    &dp->dp_empty_bpobj, tx) == 0);
+		}
+		spa_feature_incr(spa, SPA_FEATURE_EMPTY_BPOBJ, tx);
+		ASSERT(dp->dp_empty_bpobj != 0);
+		return (dp->dp_empty_bpobj);
+	} else {
+		return (bpobj_alloc(os, blocksize, tx));
+	}
+}
+
+void
+bpobj_decr_empty(objset_t *os, dmu_tx_t *tx)
+{
+	dsl_pool_t *dp = dmu_objset_pool(os);
+
+	spa_feature_decr(dmu_objset_spa(os), SPA_FEATURE_EMPTY_BPOBJ, tx);
+	if (!spa_feature_is_active(dmu_objset_spa(os),
+	    SPA_FEATURE_EMPTY_BPOBJ)) {
+		VERIFY3U(0, ==, zap_remove(dp->dp_meta_objset,
+		    DMU_POOL_DIRECTORY_OBJECT,
+		    DMU_POOL_EMPTY_BPOBJ, tx));
+		VERIFY3U(0, ==, dmu_object_free(os, dp->dp_empty_bpobj, tx));
+		dp->dp_empty_bpobj = 0;
+	}
+}
+
+uint64_t
+bpobj_alloc(objset_t *os, int blocksize, dmu_tx_t *tx)
+{
+	int size;
+
+	if (spa_version(dmu_objset_spa(os)) < SPA_VERSION_BPOBJ_ACCOUNT)
+		size = BPOBJ_SIZE_V0;
+	else if (spa_version(dmu_objset_spa(os)) < SPA_VERSION_DEADLISTS)
+		size = BPOBJ_SIZE_V1;
+	else
+		size = sizeof (bpobj_phys_t);
+
+	return (dmu_object_alloc(os, DMU_OT_BPOBJ, blocksize,
+	    DMU_OT_BPOBJ_HDR, size, tx));
+}
+
+void
+bpobj_free(objset_t *os, uint64_t obj, dmu_tx_t *tx)
+{
+	int64_t i;
+	bpobj_t bpo;
+	dmu_object_info_t doi;
+	int epb;
+	dmu_buf_t *dbuf = NULL;
+
+	ASSERT(obj != dmu_objset_pool(os)->dp_empty_bpobj);
+	VERIFY3U(0, ==, bpobj_open(&bpo, os, obj));
+
+	mutex_enter(&bpo.bpo_lock);
+
+	if (!bpo.bpo_havesubobj || bpo.bpo_phys->bpo_subobjs == 0)
+		goto out;
+
+	VERIFY3U(0, ==, dmu_object_info(os, bpo.bpo_phys->bpo_subobjs, &doi));
+	epb = doi.doi_data_block_size / sizeof (uint64_t);
+
+	for (i = bpo.bpo_phys->bpo_num_subobjs - 1; i >= 0; i--) {
+		uint64_t *objarray;
+		uint64_t offset, blkoff;
+
+		offset = i * sizeof (uint64_t);
+		blkoff = P2PHASE(i, epb);
+
+		if (dbuf == NULL || dbuf->db_offset > offset) {
+			if (dbuf)
+				dmu_buf_rele(dbuf, FTAG);
+			VERIFY3U(0, ==, dmu_buf_hold(os,
+			    bpo.bpo_phys->bpo_subobjs, offset, FTAG, &dbuf, 0));
+		}
+
+		ASSERT3U(offset, >=, dbuf->db_offset);
+		ASSERT3U(offset, <, dbuf->db_offset + dbuf->db_size);
+
+		objarray = dbuf->db_data;
+		bpobj_free(os, objarray[blkoff], tx);
+	}
+	if (dbuf) {
+		dmu_buf_rele(dbuf, FTAG);
+		dbuf = NULL;
+	}
+	VERIFY3U(0, ==, dmu_object_free(os, bpo.bpo_phys->bpo_subobjs, tx));
+
+out:
+	mutex_exit(&bpo.bpo_lock);
+	bpobj_close(&bpo);
+
+	VERIFY3U(0, ==, dmu_object_free(os, obj, tx));
+}
+
+int
+bpobj_open(bpobj_t *bpo, objset_t *os, uint64_t object)
+{
+	dmu_object_info_t doi;
+	int err;
+
+	err = dmu_object_info(os, object, &doi);
+	if (err)
+		return (err);
+
+	bzero(bpo, sizeof (*bpo));
+	mutex_init(&bpo->bpo_lock, NULL, MUTEX_DEFAULT, NULL);
+
+	ASSERT(bpo->bpo_dbuf == NULL);
+	ASSERT(bpo->bpo_phys == NULL);
+	ASSERT(object != 0);
+	ASSERT3U(doi.doi_type, ==, DMU_OT_BPOBJ);
+	ASSERT3U(doi.doi_bonus_type, ==, DMU_OT_BPOBJ_HDR);
+
+	err = dmu_bonus_hold(os, object, bpo, &bpo->bpo_dbuf);
+	if (err)
+		return (err);
+
+	bpo->bpo_os = os;
+	bpo->bpo_object = object;
+	bpo->bpo_epb = doi.doi_data_block_size >> SPA_BLKPTRSHIFT;
+	bpo->bpo_havecomp = (doi.doi_bonus_size > BPOBJ_SIZE_V0);
+	bpo->bpo_havesubobj = (doi.doi_bonus_size > BPOBJ_SIZE_V1);
+	bpo->bpo_phys = bpo->bpo_dbuf->db_data;
+	return (0);
+}
+
+void
+bpobj_close(bpobj_t *bpo)
+{
+	/* Lame workaround for closing a bpobj that was never opened. */
+	if (bpo->bpo_object == 0)
+		return;
+
+	dmu_buf_rele(bpo->bpo_dbuf, bpo);
+	if (bpo->bpo_cached_dbuf != NULL)
+		dmu_buf_rele(bpo->bpo_cached_dbuf, bpo);
+	bpo->bpo_dbuf = NULL;
+	bpo->bpo_phys = NULL;
+	bpo->bpo_cached_dbuf = NULL;
+	bpo->bpo_object = 0;
+
+	mutex_destroy(&bpo->bpo_lock);
+}
+
+static boolean_t
+bpobj_hasentries(bpobj_t *bpo)
+{
+	return (bpo->bpo_phys->bpo_num_blkptrs != 0 ||
+	    (bpo->bpo_havesubobj && bpo->bpo_phys->bpo_num_subobjs != 0));
+}
+
+static int
+bpobj_iterate_impl(bpobj_t *bpo, bpobj_itor_t func, void *arg, dmu_tx_t *tx,
+    boolean_t free)
+{
+	dmu_object_info_t doi;
+	int epb;
+	int64_t i;
+	int err = 0;
+	dmu_buf_t *dbuf = NULL;
+
+	mutex_enter(&bpo->bpo_lock);
+
+	if (free)
+		dmu_buf_will_dirty(bpo->bpo_dbuf, tx);
+
+	for (i = bpo->bpo_phys->bpo_num_blkptrs - 1; i >= 0; i--) {
+		blkptr_t *bparray;
+		blkptr_t *bp;
+		uint64_t offset, blkoff;
+
+		offset = i * sizeof (blkptr_t);
+		blkoff = P2PHASE(i, bpo->bpo_epb);
+
+		if (dbuf == NULL || dbuf->db_offset > offset) {
+			if (dbuf)
+				dmu_buf_rele(dbuf, FTAG);
+			err = dmu_buf_hold(bpo->bpo_os, bpo->bpo_object, offset,
+			    FTAG, &dbuf, 0);
+			if (err)
+				break;
+		}
+
+		ASSERT3U(offset, >=, dbuf->db_offset);
+		ASSERT3U(offset, <, dbuf->db_offset + dbuf->db_size);
+
+		bparray = dbuf->db_data;
+		bp = &bparray[blkoff];
+		err = func(arg, bp, tx);
+		if (err)
+			break;
+		if (free) {
+			bpo->bpo_phys->bpo_bytes -=
+			    bp_get_dsize_sync(dmu_objset_spa(bpo->bpo_os), bp);
+			ASSERT3S(bpo->bpo_phys->bpo_bytes, >=, 0);
+			if (bpo->bpo_havecomp) {
+				bpo->bpo_phys->bpo_comp -= BP_GET_PSIZE(bp);
+				bpo->bpo_phys->bpo_uncomp -= BP_GET_UCSIZE(bp);
+			}
+			bpo->bpo_phys->bpo_num_blkptrs--;
+			ASSERT3S(bpo->bpo_phys->bpo_num_blkptrs, >=, 0);
+		}
+	}
+	if (dbuf) {
+		dmu_buf_rele(dbuf, FTAG);
+		dbuf = NULL;
+	}
+	if (free) {
+		VERIFY3U(0, ==, dmu_free_range(bpo->bpo_os, bpo->bpo_object,
+		    (i + 1) * sizeof (blkptr_t), -1ULL, tx));
+	}
+	if (err || !bpo->bpo_havesubobj || bpo->bpo_phys->bpo_subobjs == 0)
+		goto out;
+
+	ASSERT(bpo->bpo_havecomp);
+	err = dmu_object_info(bpo->bpo_os, bpo->bpo_phys->bpo_subobjs, &doi);
+	if (err) {
+		mutex_exit(&bpo->bpo_lock);
+		return (err);
+	}
+	ASSERT3U(doi.doi_type, ==, DMU_OT_BPOBJ_SUBOBJ);
+	epb = doi.doi_data_block_size / sizeof (uint64_t);
+
+	for (i = bpo->bpo_phys->bpo_num_subobjs - 1; i >= 0; i--) {
+		uint64_t *objarray;
+		uint64_t offset, blkoff;
+		bpobj_t sublist;
+		uint64_t used_before, comp_before, uncomp_before;
+		uint64_t used_after, comp_after, uncomp_after;
+
+		offset = i * sizeof (uint64_t);
+		blkoff = P2PHASE(i, epb);
+
+		if (dbuf == NULL || dbuf->db_offset > offset) {
+			if (dbuf)
+				dmu_buf_rele(dbuf, FTAG);
+			err = dmu_buf_hold(bpo->bpo_os,
+			    bpo->bpo_phys->bpo_subobjs, offset, FTAG, &dbuf, 0);
+			if (err)
+				break;
+		}
+
+		ASSERT3U(offset, >=, dbuf->db_offset);
+		ASSERT3U(offset, <, dbuf->db_offset + dbuf->db_size);
+
+		objarray = dbuf->db_data;
+		err = bpobj_open(&sublist, bpo->bpo_os, objarray[blkoff]);
+		if (err)
+			break;
+		if (free) {
+			err = bpobj_space(&sublist,
+			    &used_before, &comp_before, &uncomp_before);
+			if (err != 0) {
+				bpobj_close(&sublist);
+				break;
+			}
+		}
+		err = bpobj_iterate_impl(&sublist, func, arg, tx, free);
+		if (free) {
+			VERIFY3U(0, ==, bpobj_space(&sublist,
+			    &used_after, &comp_after, &uncomp_after));
+			bpo->bpo_phys->bpo_bytes -= used_before - used_after;
+			ASSERT3S(bpo->bpo_phys->bpo_bytes, >=, 0);
+			bpo->bpo_phys->bpo_comp -= comp_before - comp_after;
+			bpo->bpo_phys->bpo_uncomp -=
+			    uncomp_before - uncomp_after;
+		}
+
+		bpobj_close(&sublist);
+		if (err)
+			break;
+		if (free) {
+			err = dmu_object_free(bpo->bpo_os,
+			    objarray[blkoff], tx);
+			if (err)
+				break;
+			bpo->bpo_phys->bpo_num_subobjs--;
+			ASSERT3S(bpo->bpo_phys->bpo_num_subobjs, >=, 0);
+		}
+	}
+	if (dbuf) {
+		dmu_buf_rele(dbuf, FTAG);
+		dbuf = NULL;
+	}
+	if (free) {
+		VERIFY3U(0, ==, dmu_free_range(bpo->bpo_os,
+		    bpo->bpo_phys->bpo_subobjs,
+		    (i + 1) * sizeof (uint64_t), -1ULL, tx));
+	}
+
+out:
+	/* If there are no entries, there should be no bytes. */
+	if (!bpobj_hasentries(bpo)) {
+		ASSERT0(bpo->bpo_phys->bpo_bytes);
+		ASSERT0(bpo->bpo_phys->bpo_comp);
+		ASSERT0(bpo->bpo_phys->bpo_uncomp);
+	}
+
+	mutex_exit(&bpo->bpo_lock);
+	return (err);
+}
+
+/*
+ * Iterate and remove the entries.  If func returns nonzero, iteration
+ * will stop and that entry will not be removed.
+ */
+int
+bpobj_iterate(bpobj_t *bpo, bpobj_itor_t func, void *arg, dmu_tx_t *tx)
+{
+	return (bpobj_iterate_impl(bpo, func, arg, tx, B_TRUE));
+}
+
+/*
+ * Iterate the entries.  If func returns nonzero, iteration will stop.
+ */
+int
+bpobj_iterate_nofree(bpobj_t *bpo, bpobj_itor_t func, void *arg, dmu_tx_t *tx)
+{
+	return (bpobj_iterate_impl(bpo, func, arg, tx, B_FALSE));
+}
+
+void
+bpobj_enqueue_subobj(bpobj_t *bpo, uint64_t subobj, dmu_tx_t *tx)
+{
+	bpobj_t subbpo;
+	uint64_t used, comp, uncomp, subsubobjs;
+	ASSERTV(dmu_object_info_t doi);
+
+	ASSERT(bpo->bpo_havesubobj);
+	ASSERT(bpo->bpo_havecomp);
+	ASSERT(bpo->bpo_object != dmu_objset_pool(bpo->bpo_os)->dp_empty_bpobj);
+
+	if (subobj == dmu_objset_pool(bpo->bpo_os)->dp_empty_bpobj) {
+		bpobj_decr_empty(bpo->bpo_os, tx);
+		return;
+	}
+
+	VERIFY3U(0, ==, bpobj_open(&subbpo, bpo->bpo_os, subobj));
+	VERIFY3U(0, ==, bpobj_space(&subbpo, &used, &comp, &uncomp));
+
+	if (!bpobj_hasentries(&subbpo)) {
+		/* No point in having an empty subobj. */
+		bpobj_close(&subbpo);
+		bpobj_free(bpo->bpo_os, subobj, tx);
+		return;
+	}
+
+	dmu_buf_will_dirty(bpo->bpo_dbuf, tx);
+	if (bpo->bpo_phys->bpo_subobjs == 0) {
+		bpo->bpo_phys->bpo_subobjs = dmu_object_alloc(bpo->bpo_os,
+		    DMU_OT_BPOBJ_SUBOBJ, SPA_OLD_MAXBLOCKSIZE,
+		    DMU_OT_NONE, 0, tx);
+	}
+
+	ASSERT0(dmu_object_info(bpo->bpo_os, bpo->bpo_phys->bpo_subobjs, &doi));
+	ASSERT3U(doi.doi_type, ==, DMU_OT_BPOBJ_SUBOBJ);
+
+	mutex_enter(&bpo->bpo_lock);
+	dmu_write(bpo->bpo_os, bpo->bpo_phys->bpo_subobjs,
+	    bpo->bpo_phys->bpo_num_subobjs * sizeof (subobj),
+	    sizeof (subobj), &subobj, tx);
+	bpo->bpo_phys->bpo_num_subobjs++;
+
+	/*
+	 * If subobj has only one block of subobjs, then move subobj's
+	 * subobjs to bpo's subobj list directly.  This reduces
+	 * recursion in bpobj_iterate due to nested subobjs.
+	 */
+	subsubobjs = subbpo.bpo_phys->bpo_subobjs;
+	if (subsubobjs != 0) {
+		dmu_object_info_t doi;
+
+		VERIFY3U(0, ==, dmu_object_info(bpo->bpo_os, subsubobjs, &doi));
+		if (doi.doi_max_offset == doi.doi_data_block_size) {
+			dmu_buf_t *subdb;
+			uint64_t numsubsub = subbpo.bpo_phys->bpo_num_subobjs;
+
+			VERIFY3U(0, ==, dmu_buf_hold(bpo->bpo_os, subsubobjs,
+			    0, FTAG, &subdb, 0));
+			/*
+			 * Make sure that we are not asking dmu_write()
+			 * to write more data than we have in our buffer.
+			 */
+			VERIFY3U(subdb->db_size, >=,
+			    numsubsub * sizeof (subobj));
+			dmu_write(bpo->bpo_os, bpo->bpo_phys->bpo_subobjs,
+			    bpo->bpo_phys->bpo_num_subobjs * sizeof (subobj),
+			    numsubsub * sizeof (subobj), subdb->db_data, tx);
+			dmu_buf_rele(subdb, FTAG);
+			bpo->bpo_phys->bpo_num_subobjs += numsubsub;
+
+			dmu_buf_will_dirty(subbpo.bpo_dbuf, tx);
+			subbpo.bpo_phys->bpo_subobjs = 0;
+			VERIFY3U(0, ==, dmu_object_free(bpo->bpo_os,
+			    subsubobjs, tx));
+		}
+	}
+	bpo->bpo_phys->bpo_bytes += used;
+	bpo->bpo_phys->bpo_comp += comp;
+	bpo->bpo_phys->bpo_uncomp += uncomp;
+	mutex_exit(&bpo->bpo_lock);
+
+	bpobj_close(&subbpo);
+}
+
+void
+bpobj_enqueue(bpobj_t *bpo, const blkptr_t *bp, dmu_tx_t *tx)
+{
+	blkptr_t stored_bp = *bp;
+	uint64_t offset;
+	int blkoff;
+	blkptr_t *bparray;
+
+	ASSERT(!BP_IS_HOLE(bp));
+	ASSERT(bpo->bpo_object != dmu_objset_pool(bpo->bpo_os)->dp_empty_bpobj);
+
+	if (BP_IS_EMBEDDED(bp)) {
+		/*
+		 * The bpobj will compress better without the payload.
+		 *
+		 * Note that we store EMBEDDED bp's because they have an
+		 * uncompressed size, which must be accounted for.  An
+		 * alternative would be to add their size to bpo_uncomp
+		 * without storing the bp, but that would create additional
+		 * complications: bpo_uncomp would be inconsistent with the
+		 * set of BP's stored, and bpobj_iterate() wouldn't visit
+		 * all the space accounted for in the bpobj.
+		 */
+		bzero(&stored_bp, sizeof (stored_bp));
+		stored_bp.blk_prop = bp->blk_prop;
+		stored_bp.blk_birth = bp->blk_birth;
+	} else if (!BP_GET_DEDUP(bp)) {
+		/* The bpobj will compress better without the checksum */
+		bzero(&stored_bp.blk_cksum, sizeof (stored_bp.blk_cksum));
+	}
+
+	/* We never need the fill count. */
+	stored_bp.blk_fill = 0;
+
+	mutex_enter(&bpo->bpo_lock);
+
+	offset = bpo->bpo_phys->bpo_num_blkptrs * sizeof (stored_bp);
+	blkoff = P2PHASE(bpo->bpo_phys->bpo_num_blkptrs, bpo->bpo_epb);
+
+	if (bpo->bpo_cached_dbuf == NULL ||
+	    offset < bpo->bpo_cached_dbuf->db_offset ||
+	    offset >= bpo->bpo_cached_dbuf->db_offset +
+	    bpo->bpo_cached_dbuf->db_size) {
+		if (bpo->bpo_cached_dbuf)
+			dmu_buf_rele(bpo->bpo_cached_dbuf, bpo);
+		VERIFY3U(0, ==, dmu_buf_hold(bpo->bpo_os, bpo->bpo_object,
+		    offset, bpo, &bpo->bpo_cached_dbuf, 0));
+	}
+
+	dmu_buf_will_dirty(bpo->bpo_cached_dbuf, tx);
+	bparray = bpo->bpo_cached_dbuf->db_data;
+	bparray[blkoff] = stored_bp;
+
+	dmu_buf_will_dirty(bpo->bpo_dbuf, tx);
+	bpo->bpo_phys->bpo_num_blkptrs++;
+	bpo->bpo_phys->bpo_bytes +=
+	    bp_get_dsize_sync(dmu_objset_spa(bpo->bpo_os), bp);
+	if (bpo->bpo_havecomp) {
+		bpo->bpo_phys->bpo_comp += BP_GET_PSIZE(bp);
+		bpo->bpo_phys->bpo_uncomp += BP_GET_UCSIZE(bp);
+	}
+	mutex_exit(&bpo->bpo_lock);
+}
+
+struct space_range_arg {
+	spa_t *spa;
+	uint64_t mintxg;
+	uint64_t maxtxg;
+	uint64_t used;
+	uint64_t comp;
+	uint64_t uncomp;
+};
+
+/* ARGSUSED */
+static int
+space_range_cb(void *arg, const blkptr_t *bp, dmu_tx_t *tx)
+{
+	struct space_range_arg *sra = arg;
+
+	if (bp->blk_birth > sra->mintxg && bp->blk_birth <= sra->maxtxg) {
+		if (dsl_pool_sync_context(spa_get_dsl(sra->spa)))
+			sra->used += bp_get_dsize_sync(sra->spa, bp);
+		else
+			sra->used += bp_get_dsize(sra->spa, bp);
+		sra->comp += BP_GET_PSIZE(bp);
+		sra->uncomp += BP_GET_UCSIZE(bp);
+	}
+	return (0);
+}
+
+int
+bpobj_space(bpobj_t *bpo, uint64_t *usedp, uint64_t *compp, uint64_t *uncompp)
+{
+	mutex_enter(&bpo->bpo_lock);
+
+	*usedp = bpo->bpo_phys->bpo_bytes;
+	if (bpo->bpo_havecomp) {
+		*compp = bpo->bpo_phys->bpo_comp;
+		*uncompp = bpo->bpo_phys->bpo_uncomp;
+		mutex_exit(&bpo->bpo_lock);
+		return (0);
+	} else {
+		mutex_exit(&bpo->bpo_lock);
+		return (bpobj_space_range(bpo, 0, UINT64_MAX,
+		    usedp, compp, uncompp));
+	}
+}
+
+/*
+ * Return the amount of space in the bpobj which is:
+ * mintxg < blk_birth <= maxtxg
+ */
+int
+bpobj_space_range(bpobj_t *bpo, uint64_t mintxg, uint64_t maxtxg,
+    uint64_t *usedp, uint64_t *compp, uint64_t *uncompp)
+{
+	struct space_range_arg sra = { 0 };
+	int err;
+
+	/*
+	 * As an optimization, if they want the whole txg range, just
+	 * get bpo_bytes rather than iterating over the bps.
+	 */
+	if (mintxg < TXG_INITIAL && maxtxg == UINT64_MAX && bpo->bpo_havecomp)
+		return (bpobj_space(bpo, usedp, compp, uncompp));
+
+	sra.spa = dmu_objset_spa(bpo->bpo_os);
+	sra.mintxg = mintxg;
+	sra.maxtxg = maxtxg;
+
+	err = bpobj_iterate_nofree(bpo, space_range_cb, &sra, NULL);
+	*usedp = sra.used;
+	*compp = sra.comp;
+	*uncompp = sra.uncomp;
+	return (err);
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/module/zfs/bptree.c
@@ -0,0 +1,301 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2011, 2014 by Delphix. All rights reserved.
+ */
+
+#include <sys/arc.h>
+#include <sys/bptree.h>
+#include <sys/dmu.h>
+#include <sys/dmu_objset.h>
+#include <sys/dmu_tx.h>
+#include <sys/dmu_traverse.h>
+#include <sys/dsl_dataset.h>
+#include <sys/dsl_dir.h>
+#include <sys/dsl_pool.h>
+#include <sys/dnode.h>
+#include <sys/refcount.h>
+#include <sys/spa.h>
+
+/*
+ * A bptree is a queue of root block pointers from destroyed datasets. When a
+ * dataset is destroyed its root block pointer is put on the end of the pool's
+ * bptree queue so the dataset's blocks can be freed asynchronously by
+ * dsl_scan_sync. This allows the delete operation to finish without traversing
+ * all the dataset's blocks.
+ *
+ * Note that while bt_begin and bt_end are only ever incremented in this code,
+ * they are effectively reset to 0 every time the entire bptree is freed because
+ * the bptree's object is destroyed and re-created.
+ */
+
+struct bptree_args {
+	bptree_phys_t *ba_phys;	/* data in bonus buffer, dirtied if freeing */
+	boolean_t ba_free;	/* true if freeing during traversal */
+
+	bptree_itor_t *ba_func;	/* function to call for each blockpointer */
+	void *ba_arg;		/* caller supplied argument to ba_func */
+	dmu_tx_t *ba_tx;	/* caller supplied tx, NULL if not freeing */
+} bptree_args_t;
+
+uint64_t
+bptree_alloc(objset_t *os, dmu_tx_t *tx)
+{
+	uint64_t obj;
+	dmu_buf_t *db;
+	bptree_phys_t *bt;
+
+	obj = dmu_object_alloc(os, DMU_OTN_UINT64_METADATA,
+	    SPA_OLD_MAXBLOCKSIZE, DMU_OTN_UINT64_METADATA,
+	    sizeof (bptree_phys_t), tx);
+
+	/*
+	 * Bonus buffer contents are already initialized to 0, but for
+	 * readability we make it explicit.
+	 */
+	VERIFY3U(0, ==, dmu_bonus_hold(os, obj, FTAG, &db));
+	dmu_buf_will_dirty(db, tx);
+	bt = db->db_data;
+	bt->bt_begin = 0;
+	bt->bt_end = 0;
+	bt->bt_bytes = 0;
+	bt->bt_comp = 0;
+	bt->bt_uncomp = 0;
+	dmu_buf_rele(db, FTAG);
+
+	return (obj);
+}
+
+int
+bptree_free(objset_t *os, uint64_t obj, dmu_tx_t *tx)
+{
+	dmu_buf_t *db;
+	bptree_phys_t *bt;
+
+	VERIFY3U(0, ==, dmu_bonus_hold(os, obj, FTAG, &db));
+	bt = db->db_data;
+	ASSERT3U(bt->bt_begin, ==, bt->bt_end);
+	ASSERT0(bt->bt_bytes);
+	ASSERT0(bt->bt_comp);
+	ASSERT0(bt->bt_uncomp);
+	dmu_buf_rele(db, FTAG);
+
+	return (dmu_object_free(os, obj, tx));
+}
+
+boolean_t
+bptree_is_empty(objset_t *os, uint64_t obj)
+{
+	dmu_buf_t *db;
+	bptree_phys_t *bt;
+	boolean_t rv;
+
+	VERIFY0(dmu_bonus_hold(os, obj, FTAG, &db));
+	bt = db->db_data;
+	rv = (bt->bt_begin == bt->bt_end);
+	dmu_buf_rele(db, FTAG);
+	return (rv);
+}
+
+void
+bptree_add(objset_t *os, uint64_t obj, blkptr_t *bp, uint64_t birth_txg,
+    uint64_t bytes, uint64_t comp, uint64_t uncomp, dmu_tx_t *tx)
+{
+	dmu_buf_t *db;
+	bptree_phys_t *bt;
+	bptree_entry_phys_t *bte;
+
+	/*
+	 * bptree objects are in the pool mos, therefore they can only be
+	 * modified in syncing context. Furthermore, this is only modified
+	 * by the sync thread, so no locking is necessary.
+	 */
+	ASSERT(dmu_tx_is_syncing(tx));
+
+	VERIFY3U(0, ==, dmu_bonus_hold(os, obj, FTAG, &db));
+	bt = db->db_data;
+
+	bte = kmem_zalloc(sizeof (*bte), KM_SLEEP);
+	bte->be_birth_txg = birth_txg;
+	bte->be_bp = *bp;
+	dmu_write(os, obj, bt->bt_end * sizeof (*bte), sizeof (*bte), bte, tx);
+	kmem_free(bte, sizeof (*bte));
+
+	dmu_buf_will_dirty(db, tx);
+	bt->bt_end++;
+	bt->bt_bytes += bytes;
+	bt->bt_comp += comp;
+	bt->bt_uncomp += uncomp;
+	dmu_buf_rele(db, FTAG);
+}
+
+/* ARGSUSED */
+static int
+bptree_visit_cb(spa_t *spa, zilog_t *zilog, const blkptr_t *bp,
+    const zbookmark_phys_t *zb, const dnode_phys_t *dnp, void *arg)
+{
+	int err;
+	struct bptree_args *ba = arg;
+
+	if (BP_IS_HOLE(bp))
+		return (0);
+
+	err = ba->ba_func(ba->ba_arg, bp, ba->ba_tx);
+	if (err == 0 && ba->ba_free) {
+		ba->ba_phys->bt_bytes -= bp_get_dsize_sync(spa, bp);
+		ba->ba_phys->bt_comp -= BP_GET_PSIZE(bp);
+		ba->ba_phys->bt_uncomp -= BP_GET_UCSIZE(bp);
+	}
+	return (err);
+}
+
+/*
+ * If "free" is set:
+ *  - It is assumed that "func" will be freeing the block pointers.
+ *  - If "func" returns nonzero, the bookmark will be remembered and
+ *    iteration will be restarted from this point on next invocation.
+ *  - If an i/o error is encountered (e.g. "func" returns EIO or ECKSUM),
+ *    bptree_iterate will remember the bookmark, continue traversing
+ *    any additional entries, and return 0.
+ *
+ * If "free" is not set, traversal will stop and return an error if
+ * an i/o error is encountered.
+ *
+ * In either case, if zfs_free_leak_on_eio is set, i/o errors will be
+ * ignored and traversal will continue (i.e. TRAVERSE_HARD will be passed to
+ * traverse_dataset_destroyed()).
+ */
+int
+bptree_iterate(objset_t *os, uint64_t obj, boolean_t free, bptree_itor_t func,
+    void *arg, dmu_tx_t *tx)
+{
+	boolean_t ioerr = B_FALSE;
+	int err;
+	uint64_t i;
+	dmu_buf_t *db;
+	struct bptree_args ba;
+
+	ASSERT(!free || dmu_tx_is_syncing(tx));
+
+	err = dmu_bonus_hold(os, obj, FTAG, &db);
+	if (err != 0)
+		return (err);
+
+	if (free)
+		dmu_buf_will_dirty(db, tx);
+
+	ba.ba_phys = db->db_data;
+	ba.ba_free = free;
+	ba.ba_func = func;
+	ba.ba_arg = arg;
+	ba.ba_tx = tx;
+
+	err = 0;
+	for (i = ba.ba_phys->bt_begin; i < ba.ba_phys->bt_end; i++) {
+		bptree_entry_phys_t bte;
+		int flags = TRAVERSE_PREFETCH_METADATA | TRAVERSE_POST;
+
+		err = dmu_read(os, obj, i * sizeof (bte), sizeof (bte),
+		    &bte, DMU_READ_NO_PREFETCH);
+		if (err != 0)
+			break;
+
+		if (zfs_free_leak_on_eio)
+			flags |= TRAVERSE_HARD;
+		zfs_dbgmsg("bptree index %lld: traversing from min_txg=%lld "
+		    "bookmark %lld/%lld/%lld/%lld",
+		    i, (longlong_t)bte.be_birth_txg,
+		    (longlong_t)bte.be_zb.zb_objset,
+		    (longlong_t)bte.be_zb.zb_object,
+		    (longlong_t)bte.be_zb.zb_level,
+		    (longlong_t)bte.be_zb.zb_blkid);
+		err = traverse_dataset_destroyed(os->os_spa, &bte.be_bp,
+		    bte.be_birth_txg, &bte.be_zb, flags,
+		    bptree_visit_cb, &ba);
+		if (free) {
+			/*
+			 * The callback has freed the visited block pointers.
+			 * Record our traversal progress on disk, either by
+			 * updating this record's bookmark, or by logically
+			 * removing this record by advancing bt_begin.
+			 */
+			if (err != 0) {
+				/* save bookmark for future resume */
+				ASSERT3U(bte.be_zb.zb_objset, ==,
+				    ZB_DESTROYED_OBJSET);
+				ASSERT0(bte.be_zb.zb_level);
+				dmu_write(os, obj, i * sizeof (bte),
+				    sizeof (bte), &bte, tx);
+				if (err == EIO || err == ECKSUM ||
+				    err == ENXIO) {
+					/*
+					 * Skip the rest of this tree and
+					 * continue on to the next entry.
+					 */
+					err = 0;
+					ioerr = B_TRUE;
+				} else {
+					break;
+				}
+			} else if (ioerr) {
+				/*
+				 * This entry is finished, but there were
+				 * i/o errors on previous entries, so we
+				 * can't adjust bt_begin.  Set this entry's
+				 * be_birth_txg such that it will be
+				 * treated as a no-op in future traversals.
+				 */
+				bte.be_birth_txg = UINT64_MAX;
+				dmu_write(os, obj, i * sizeof (bte),
+				    sizeof (bte), &bte, tx);
+			}
+
+			if (!ioerr) {
+				ba.ba_phys->bt_begin++;
+				(void) dmu_free_range(os, obj,
+				    i * sizeof (bte), sizeof (bte), tx);
+			}
+		} else if (err != 0) {
+			break;
+		}
+	}
+
+	ASSERT(!free || err != 0 || ioerr ||
+	    ba.ba_phys->bt_begin == ba.ba_phys->bt_end);
+
+	/* if all blocks are free there should be no used space */
+	if (ba.ba_phys->bt_begin == ba.ba_phys->bt_end) {
+		if (zfs_free_leak_on_eio) {
+			ba.ba_phys->bt_bytes = 0;
+			ba.ba_phys->bt_comp = 0;
+			ba.ba_phys->bt_uncomp = 0;
+		}
+
+		ASSERT0(ba.ba_phys->bt_bytes);
+		ASSERT0(ba.ba_phys->bt_comp);
+		ASSERT0(ba.ba_phys->bt_uncomp);
+	}
+
+	dmu_buf_rele(db, FTAG);
+
+	return (err);
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/module/zfs/dbuf.c
@@ -0,0 +1,3148 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2011 Nexenta Systems, Inc.  All rights reserved.
+ * Copyright (c) 2012, 2015 by Delphix. All rights reserved.
+ * Copyright (c) 2013 by Saso Kiselkov. All rights reserved.
+ * Copyright (c) 2014 Spectra Logic Corporation, All rights reserved.
+ */
+
+#include <sys/zfs_context.h>
+#include <sys/arc.h>
+#include <sys/dmu.h>
+#include <sys/dmu_send.h>
+#include <sys/dmu_impl.h>
+#include <sys/dbuf.h>
+#include <sys/dmu_objset.h>
+#include <sys/dsl_dataset.h>
+#include <sys/dsl_dir.h>
+#include <sys/dmu_tx.h>
+#include <sys/spa.h>
+#include <sys/zio.h>
+#include <sys/dmu_zfetch.h>
+#include <sys/sa.h>
+#include <sys/sa_impl.h>
+#include <sys/zfeature.h>
+#include <sys/blkptr.h>
+#include <sys/range_tree.h>
+#include <sys/trace_dbuf.h>
+
+struct dbuf_hold_impl_data {
+	/* Function arguments */
+	dnode_t *dh_dn;
+	uint8_t dh_level;
+	uint64_t dh_blkid;
+	int dh_fail_sparse;
+	void *dh_tag;
+	dmu_buf_impl_t **dh_dbp;
+	/* Local variables */
+	dmu_buf_impl_t *dh_db;
+	dmu_buf_impl_t *dh_parent;
+	blkptr_t *dh_bp;
+	int dh_err;
+	dbuf_dirty_record_t *dh_dr;
+	arc_buf_contents_t dh_type;
+	int dh_depth;
+};
+
+static void __dbuf_hold_impl_init(struct dbuf_hold_impl_data *dh,
+    dnode_t *dn, uint8_t level, uint64_t blkid, int fail_sparse,
+    void *tag, dmu_buf_impl_t **dbp, int depth);
+static int __dbuf_hold_impl(struct dbuf_hold_impl_data *dh);
+
+/*
+ * Number of times that zfs_free_range() took the slow path while doing
+ * a zfs receive.  A nonzero value indicates a potential performance problem.
+ */
+uint64_t zfs_free_range_recv_miss;
+
+static void dbuf_destroy(dmu_buf_impl_t *db);
+static boolean_t dbuf_undirty(dmu_buf_impl_t *db, dmu_tx_t *tx);
+static void dbuf_write(dbuf_dirty_record_t *dr, arc_buf_t *data, dmu_tx_t *tx);
+
+#ifndef __lint
+extern inline void dmu_buf_init_user(dmu_buf_user_t *dbu,
+    dmu_buf_evict_func_t *evict_func, dmu_buf_t **clear_on_evict_dbufp);
+#endif /* ! __lint */
+
+/*
+ * Global data structures and functions for the dbuf cache.
+ */
+static kmem_cache_t *dbuf_cache;
+static taskq_t *dbu_evict_taskq;
+
+/* ARGSUSED */
+static int
+dbuf_cons(void *vdb, void *unused, int kmflag)
+{
+	dmu_buf_impl_t *db = vdb;
+	bzero(db, sizeof (dmu_buf_impl_t));
+
+	mutex_init(&db->db_mtx, NULL, MUTEX_DEFAULT, NULL);
+	cv_init(&db->db_changed, NULL, CV_DEFAULT, NULL);
+	refcount_create(&db->db_holds);
+
+	return (0);
+}
+
+/* ARGSUSED */
+static void
+dbuf_dest(void *vdb, void *unused)
+{
+	dmu_buf_impl_t *db = vdb;
+	mutex_destroy(&db->db_mtx);
+	cv_destroy(&db->db_changed);
+	refcount_destroy(&db->db_holds);
+}
+
+/*
+ * dbuf hash table routines
+ */
+static dbuf_hash_table_t dbuf_hash_table;
+
+static uint64_t dbuf_hash_count;
+
+static uint64_t
+dbuf_hash(void *os, uint64_t obj, uint8_t lvl, uint64_t blkid)
+{
+	uintptr_t osv = (uintptr_t)os;
+	uint64_t crc = -1ULL;
+
+	ASSERT(zfs_crc64_table[128] == ZFS_CRC64_POLY);
+	crc = (crc >> 8) ^ zfs_crc64_table[(crc ^ (lvl)) & 0xFF];
+	crc = (crc >> 8) ^ zfs_crc64_table[(crc ^ (osv >> 6)) & 0xFF];
+	crc = (crc >> 8) ^ zfs_crc64_table[(crc ^ (obj >> 0)) & 0xFF];
+	crc = (crc >> 8) ^ zfs_crc64_table[(crc ^ (obj >> 8)) & 0xFF];
+	crc = (crc >> 8) ^ zfs_crc64_table[(crc ^ (blkid >> 0)) & 0xFF];
+	crc = (crc >> 8) ^ zfs_crc64_table[(crc ^ (blkid >> 8)) & 0xFF];
+
+	crc ^= (osv>>14) ^ (obj>>16) ^ (blkid>>16);
+
+	return (crc);
+}
+
+#define	DBUF_HASH(os, obj, level, blkid) dbuf_hash(os, obj, level, blkid);
+
+#define	DBUF_EQUAL(dbuf, os, obj, level, blkid)		\
+	((dbuf)->db.db_object == (obj) &&		\
+	(dbuf)->db_objset == (os) &&			\
+	(dbuf)->db_level == (level) &&			\
+	(dbuf)->db_blkid == (blkid))
+
+dmu_buf_impl_t *
+dbuf_find(objset_t *os, uint64_t obj, uint8_t level, uint64_t blkid)
+{
+	dbuf_hash_table_t *h = &dbuf_hash_table;
+	uint64_t hv;
+	uint64_t idx;
+	dmu_buf_impl_t *db;
+
+	hv = DBUF_HASH(os, obj, level, blkid);
+	idx = hv & h->hash_table_mask;
+
+	mutex_enter(DBUF_HASH_MUTEX(h, idx));
+	for (db = h->hash_table[idx]; db != NULL; db = db->db_hash_next) {
+		if (DBUF_EQUAL(db, os, obj, level, blkid)) {
+			mutex_enter(&db->db_mtx);
+			if (db->db_state != DB_EVICTING) {
+				mutex_exit(DBUF_HASH_MUTEX(h, idx));
+				return (db);
+			}
+			mutex_exit(&db->db_mtx);
+		}
+	}
+	mutex_exit(DBUF_HASH_MUTEX(h, idx));
+	return (NULL);
+}
+
+static dmu_buf_impl_t *
+dbuf_find_bonus(objset_t *os, uint64_t object)
+{
+	dnode_t *dn;
+	dmu_buf_impl_t *db = NULL;
+
+	if (dnode_hold(os, object, FTAG, &dn) == 0) {
+		rw_enter(&dn->dn_struct_rwlock, RW_READER);
+		if (dn->dn_bonus != NULL) {
+			db = dn->dn_bonus;
+			mutex_enter(&db->db_mtx);
+		}
+		rw_exit(&dn->dn_struct_rwlock);
+		dnode_rele(dn, FTAG);
+	}
+	return (db);
+}
+
+/*
+ * Insert an entry into the hash table.  If there is already an element
+ * equal to elem in the hash table, then the already existing element
+ * will be returned and the new element will not be inserted.
+ * Otherwise returns NULL.
+ */
+static dmu_buf_impl_t *
+dbuf_hash_insert(dmu_buf_impl_t *db)
+{
+	dbuf_hash_table_t *h = &dbuf_hash_table;
+	objset_t *os = db->db_objset;
+	uint64_t obj = db->db.db_object;
+	int level = db->db_level;
+	uint64_t blkid, hv, idx;
+	dmu_buf_impl_t *dbf;
+
+	blkid = db->db_blkid;
+	hv = DBUF_HASH(os, obj, level, blkid);
+	idx = hv & h->hash_table_mask;
+
+	mutex_enter(DBUF_HASH_MUTEX(h, idx));
+	for (dbf = h->hash_table[idx]; dbf != NULL; dbf = dbf->db_hash_next) {
+		if (DBUF_EQUAL(dbf, os, obj, level, blkid)) {
+			mutex_enter(&dbf->db_mtx);
+			if (dbf->db_state != DB_EVICTING) {
+				mutex_exit(DBUF_HASH_MUTEX(h, idx));
+				return (dbf);
+			}
+			mutex_exit(&dbf->db_mtx);
+		}
+	}
+
+	mutex_enter(&db->db_mtx);
+	db->db_hash_next = h->hash_table[idx];
+	h->hash_table[idx] = db;
+	mutex_exit(DBUF_HASH_MUTEX(h, idx));
+	atomic_add_64(&dbuf_hash_count, 1);
+
+	return (NULL);
+}
+
+/*
+ * Remove an entry from the hash table.  It must be in the EVICTING state.
+ */
+static void
+dbuf_hash_remove(dmu_buf_impl_t *db)
+{
+	dbuf_hash_table_t *h = &dbuf_hash_table;
+	uint64_t hv, idx;
+	dmu_buf_impl_t *dbf, **dbp;
+
+	hv = DBUF_HASH(db->db_objset, db->db.db_object,
+	    db->db_level, db->db_blkid);
+	idx = hv & h->hash_table_mask;
+
+	/*
+	 * We musn't hold db_mtx to maintain lock ordering:
+	 * DBUF_HASH_MUTEX > db_mtx.
+	 */
+	ASSERT(refcount_is_zero(&db->db_holds));
+	ASSERT(db->db_state == DB_EVICTING);
+	ASSERT(!MUTEX_HELD(&db->db_mtx));
+
+	mutex_enter(DBUF_HASH_MUTEX(h, idx));
+	dbp = &h->hash_table[idx];
+	while ((dbf = *dbp) != db) {
+		dbp = &dbf->db_hash_next;
+		ASSERT(dbf != NULL);
+	}
+	*dbp = db->db_hash_next;
+	db->db_hash_next = NULL;
+	mutex_exit(DBUF_HASH_MUTEX(h, idx));
+	atomic_add_64(&dbuf_hash_count, -1);
+}
+
+static arc_evict_func_t dbuf_do_evict;
+
+typedef enum {
+	DBVU_EVICTING,
+	DBVU_NOT_EVICTING
+} dbvu_verify_type_t;
+
+static void
+dbuf_verify_user(dmu_buf_impl_t *db, dbvu_verify_type_t verify_type)
+{
+#ifdef ZFS_DEBUG
+	int64_t holds;
+
+	if (db->db_user == NULL)
+		return;
+
+	/* Only data blocks support the attachment of user data. */
+	ASSERT(db->db_level == 0);
+
+	/* Clients must resolve a dbuf before attaching user data. */
+	ASSERT(db->db.db_data != NULL);
+	ASSERT3U(db->db_state, ==, DB_CACHED);
+
+	holds = refcount_count(&db->db_holds);
+	if (verify_type == DBVU_EVICTING) {
+		/*
+		 * Immediate eviction occurs when holds == dirtycnt.
+		 * For normal eviction buffers, holds is zero on
+		 * eviction, except when dbuf_fix_old_data() calls
+		 * dbuf_clear_data().  However, the hold count can grow
+		 * during eviction even though db_mtx is held (see
+		 * dmu_bonus_hold() for an example), so we can only
+		 * test the generic invariant that holds >= dirtycnt.
+		 */
+		ASSERT3U(holds, >=, db->db_dirtycnt);
+	} else {
+		if (db->db_user_immediate_evict == TRUE)
+			ASSERT3U(holds, >=, db->db_dirtycnt);
+		else
+			ASSERT3U(holds, >, 0);
+	}
+#endif
+}
+
+static void
+dbuf_evict_user(dmu_buf_impl_t *db)
+{
+	dmu_buf_user_t *dbu = db->db_user;
+
+	ASSERT(MUTEX_HELD(&db->db_mtx));
+
+	if (dbu == NULL)
+		return;
+
+	dbuf_verify_user(db, DBVU_EVICTING);
+	db->db_user = NULL;
+
+#ifdef ZFS_DEBUG
+	if (dbu->dbu_clear_on_evict_dbufp != NULL)
+		*dbu->dbu_clear_on_evict_dbufp = NULL;
+#endif
+
+	/*
+	 * Invoke the callback from a taskq to avoid lock order reversals
+	 * and limit stack depth.
+	 */
+	taskq_dispatch_ent(dbu_evict_taskq, dbu->dbu_evict_func, dbu, 0,
+	    &dbu->dbu_tqent);
+}
+
+boolean_t
+dbuf_is_metadata(dmu_buf_impl_t *db)
+{
+	/*
+	 * Consider indirect blocks and spill blocks to be meta data.
+	 */
+	if (db->db_level > 0 || db->db_blkid == DMU_SPILL_BLKID) {
+		return (B_TRUE);
+	} else {
+		boolean_t is_metadata;
+
+		DB_DNODE_ENTER(db);
+		is_metadata = DMU_OT_IS_METADATA(DB_DNODE(db)->dn_type);
+		DB_DNODE_EXIT(db);
+
+		return (is_metadata);
+	}
+}
+
+void
+dbuf_evict(dmu_buf_impl_t *db)
+{
+	ASSERT(MUTEX_HELD(&db->db_mtx));
+	ASSERT(db->db_buf == NULL);
+	ASSERT(db->db_data_pending == NULL);
+
+	dbuf_clear(db);
+	dbuf_destroy(db);
+}
+
+void
+dbuf_init(void)
+{
+	uint64_t hsize = 1ULL << 16;
+	dbuf_hash_table_t *h = &dbuf_hash_table;
+	int i;
+
+	/*
+	 * The hash table is big enough to fill all of physical memory
+	 * with an average block size of zfs_arc_average_blocksize (default 8K).
+	 * By default, the table will take up
+	 * totalmem * sizeof(void*) / 8K (1MB per GB with 8-byte pointers).
+	 */
+	while (hsize * zfs_arc_average_blocksize < physmem * PAGESIZE)
+		hsize <<= 1;
+
+retry:
+	h->hash_table_mask = hsize - 1;
+#if defined(_KERNEL) && defined(HAVE_SPL)
+	/*
+	 * Large allocations which do not require contiguous pages
+	 * should be using vmem_alloc() in the linux kernel
+	 */
+	h->hash_table = vmem_zalloc(hsize * sizeof (void *), KM_SLEEP);
+#else
+	h->hash_table = kmem_zalloc(hsize * sizeof (void *), KM_NOSLEEP);
+#endif
+	if (h->hash_table == NULL) {
+		/* XXX - we should really return an error instead of assert */
+		ASSERT(hsize > (1ULL << 10));
+		hsize >>= 1;
+		goto retry;
+	}
+
+	dbuf_cache = kmem_cache_create("dmu_buf_impl_t",
+	    sizeof (dmu_buf_impl_t),
+	    0, dbuf_cons, dbuf_dest, NULL, NULL, NULL, 0);
+
+	for (i = 0; i < DBUF_MUTEXES; i++)
+		mutex_init(&h->hash_mutexes[i], NULL, MUTEX_DEFAULT, NULL);
+
+	dbuf_stats_init(h);
+
+	/*
+	 * All entries are queued via taskq_dispatch_ent(), so min/maxalloc
+	 * configuration is not required.
+	 */
+	dbu_evict_taskq = taskq_create("dbu_evict", 1, defclsyspri, 0, 0, 0);
+}
+
+void
+dbuf_fini(void)
+{
+	dbuf_hash_table_t *h = &dbuf_hash_table;
+	int i;
+
+	dbuf_stats_destroy();
+
+	for (i = 0; i < DBUF_MUTEXES; i++)
+		mutex_destroy(&h->hash_mutexes[i]);
+#if defined(_KERNEL) && defined(HAVE_SPL)
+	/*
+	 * Large allocations which do not require contiguous pages
+	 * should be using vmem_free() in the linux kernel
+	 */
+	vmem_free(h->hash_table, (h->hash_table_mask + 1) * sizeof (void *));
+#else
+	kmem_free(h->hash_table, (h->hash_table_mask + 1) * sizeof (void *));
+#endif
+	kmem_cache_destroy(dbuf_cache);
+	taskq_destroy(dbu_evict_taskq);
+}
+
+/*
+ * Other stuff.
+ */
+
+#ifdef ZFS_DEBUG
+static void
+dbuf_verify(dmu_buf_impl_t *db)
+{
+	dnode_t *dn;
+	dbuf_dirty_record_t *dr;
+
+	ASSERT(MUTEX_HELD(&db->db_mtx));
+
+	if (!(zfs_flags & ZFS_DEBUG_DBUF_VERIFY))
+		return;
+
+	ASSERT(db->db_objset != NULL);
+	DB_DNODE_ENTER(db);
+	dn = DB_DNODE(db);
+	if (dn == NULL) {
+		ASSERT(db->db_parent == NULL);
+		ASSERT(db->db_blkptr == NULL);
+	} else {
+		ASSERT3U(db->db.db_object, ==, dn->dn_object);
+		ASSERT3P(db->db_objset, ==, dn->dn_objset);
+		ASSERT3U(db->db_level, <, dn->dn_nlevels);
+		ASSERT(db->db_blkid == DMU_BONUS_BLKID ||
+		    db->db_blkid == DMU_SPILL_BLKID ||
+		    !avl_is_empty(&dn->dn_dbufs));
+	}
+	if (db->db_blkid == DMU_BONUS_BLKID) {
+		ASSERT(dn != NULL);
+		ASSERT3U(db->db.db_size, >=, dn->dn_bonuslen);
+		ASSERT3U(db->db.db_offset, ==, DMU_BONUS_BLKID);
+	} else if (db->db_blkid == DMU_SPILL_BLKID) {
+		ASSERT(dn != NULL);
+		ASSERT3U(db->db.db_size, >=, dn->dn_bonuslen);
+		ASSERT0(db->db.db_offset);
+	} else {
+		ASSERT3U(db->db.db_offset, ==, db->db_blkid * db->db.db_size);
+	}
+
+	for (dr = db->db_data_pending; dr != NULL; dr = dr->dr_next)
+		ASSERT(dr->dr_dbuf == db);
+
+	for (dr = db->db_last_dirty; dr != NULL; dr = dr->dr_next)
+		ASSERT(dr->dr_dbuf == db);
+
+	/*
+	 * We can't assert that db_size matches dn_datablksz because it
+	 * can be momentarily different when another thread is doing
+	 * dnode_set_blksz().
+	 */
+	if (db->db_level == 0 && db->db.db_object == DMU_META_DNODE_OBJECT) {
+		dr = db->db_data_pending;
+		/*
+		 * It should only be modified in syncing context, so
+		 * make sure we only have one copy of the data.
+		 */
+		ASSERT(dr == NULL || dr->dt.dl.dr_data == db->db_buf);
+	}
+
+	/* verify db->db_blkptr */
+	if (db->db_blkptr) {
+		if (db->db_parent == dn->dn_dbuf) {
+			/* db is pointed to by the dnode */
+			/* ASSERT3U(db->db_blkid, <, dn->dn_nblkptr); */
+			if (DMU_OBJECT_IS_SPECIAL(db->db.db_object))
+				ASSERT(db->db_parent == NULL);
+			else
+				ASSERT(db->db_parent != NULL);
+			if (db->db_blkid != DMU_SPILL_BLKID)
+				ASSERT3P(db->db_blkptr, ==,
+				    &dn->dn_phys->dn_blkptr[db->db_blkid]);
+		} else {
+			/* db is pointed to by an indirect block */
+			ASSERTV(int epb = db->db_parent->db.db_size >>
+				SPA_BLKPTRSHIFT);
+			ASSERT3U(db->db_parent->db_level, ==, db->db_level+1);
+			ASSERT3U(db->db_parent->db.db_object, ==,
+			    db->db.db_object);
+			/*
+			 * dnode_grow_indblksz() can make this fail if we don't
+			 * have the struct_rwlock.  XXX indblksz no longer
+			 * grows.  safe to do this now?
+			 */
+			if (RW_WRITE_HELD(&dn->dn_struct_rwlock)) {
+				ASSERT3P(db->db_blkptr, ==,
+				    ((blkptr_t *)db->db_parent->db.db_data +
+				    db->db_blkid % epb));
+			}
+		}
+	}
+	if ((db->db_blkptr == NULL || BP_IS_HOLE(db->db_blkptr)) &&
+	    (db->db_buf == NULL || db->db_buf->b_data) &&
+	    db->db.db_data && db->db_blkid != DMU_BONUS_BLKID &&
+	    db->db_state != DB_FILL && !dn->dn_free_txg) {
+		/*
+		 * If the blkptr isn't set but they have nonzero data,
+		 * it had better be dirty, otherwise we'll lose that
+		 * data when we evict this buffer.
+		 */
+		if (db->db_dirtycnt == 0) {
+			ASSERTV(uint64_t *buf = db->db.db_data);
+			int i;
+
+			for (i = 0; i < db->db.db_size >> 3; i++) {
+				ASSERT(buf[i] == 0);
+			}
+		}
+	}
+	DB_DNODE_EXIT(db);
+}
+#endif
+
+static void
+dbuf_clear_data(dmu_buf_impl_t *db)
+{
+	ASSERT(MUTEX_HELD(&db->db_mtx));
+	dbuf_evict_user(db);
+	db->db_buf = NULL;
+	db->db.db_data = NULL;
+	if (db->db_state != DB_NOFILL)
+		db->db_state = DB_UNCACHED;
+}
+
+static void
+dbuf_set_data(dmu_buf_impl_t *db, arc_buf_t *buf)
+{
+	ASSERT(MUTEX_HELD(&db->db_mtx));
+	ASSERT(buf != NULL);
+
+	db->db_buf = buf;
+	ASSERT(buf->b_data != NULL);
+	db->db.db_data = buf->b_data;
+	if (!arc_released(buf))
+		arc_set_callback(buf, dbuf_do_evict, db);
+}
+
+/*
+ * Loan out an arc_buf for read.  Return the loaned arc_buf.
+ */
+arc_buf_t *
+dbuf_loan_arcbuf(dmu_buf_impl_t *db)
+{
+	arc_buf_t *abuf;
+
+	mutex_enter(&db->db_mtx);
+	if (arc_released(db->db_buf) || refcount_count(&db->db_holds) > 1) {
+		int blksz = db->db.db_size;
+		spa_t *spa = db->db_objset->os_spa;
+
+		mutex_exit(&db->db_mtx);
+		abuf = arc_loan_buf(spa, blksz);
+		bcopy(db->db.db_data, abuf->b_data, blksz);
+	} else {
+		abuf = db->db_buf;
+		arc_loan_inuse_buf(abuf, db);
+		dbuf_clear_data(db);
+		mutex_exit(&db->db_mtx);
+	}
+	return (abuf);
+}
+
+uint64_t
+dbuf_whichblock(dnode_t *dn, uint64_t offset)
+{
+	if (dn->dn_datablkshift) {
+		return (offset >> dn->dn_datablkshift);
+	} else {
+		ASSERT3U(offset, <, dn->dn_datablksz);
+		return (0);
+	}
+}
+
+static void
+dbuf_read_done(zio_t *zio, arc_buf_t *buf, void *vdb)
+{
+	dmu_buf_impl_t *db = vdb;
+
+	mutex_enter(&db->db_mtx);
+	ASSERT3U(db->db_state, ==, DB_READ);
+	/*
+	 * All reads are synchronous, so we must have a hold on the dbuf
+	 */
+	ASSERT(refcount_count(&db->db_holds) > 0);
+	ASSERT(db->db_buf == NULL);
+	ASSERT(db->db.db_data == NULL);
+	if (db->db_level == 0 && db->db_freed_in_flight) {
+		/* we were freed in flight; disregard any error */
+		arc_release(buf, db);
+		bzero(buf->b_data, db->db.db_size);
+		arc_buf_freeze(buf);
+		db->db_freed_in_flight = FALSE;
+		dbuf_set_data(db, buf);
+		db->db_state = DB_CACHED;
+	} else if (zio == NULL || zio->io_error == 0) {
+		dbuf_set_data(db, buf);
+		db->db_state = DB_CACHED;
+	} else {
+		ASSERT(db->db_blkid != DMU_BONUS_BLKID);
+		ASSERT3P(db->db_buf, ==, NULL);
+		VERIFY(arc_buf_remove_ref(buf, db));
+		db->db_state = DB_UNCACHED;
+	}
+	cv_broadcast(&db->db_changed);
+	dbuf_rele_and_unlock(db, NULL);
+}
+
+static int
+dbuf_read_impl(dmu_buf_impl_t *db, zio_t *zio, uint32_t *flags)
+{
+	dnode_t *dn;
+	zbookmark_phys_t zb;
+	uint32_t aflags = ARC_FLAG_NOWAIT;
+	int err;
+
+	DB_DNODE_ENTER(db);
+	dn = DB_DNODE(db);
+	ASSERT(!refcount_is_zero(&db->db_holds));
+	/* We need the struct_rwlock to prevent db_blkptr from changing. */
+	ASSERT(RW_LOCK_HELD(&dn->dn_struct_rwlock));
+	ASSERT(MUTEX_HELD(&db->db_mtx));
+	ASSERT(db->db_state == DB_UNCACHED);
+	ASSERT(db->db_buf == NULL);
+
+	if (db->db_blkid == DMU_BONUS_BLKID) {
+		int bonuslen = MIN(dn->dn_bonuslen, dn->dn_phys->dn_bonuslen);
+
+		ASSERT3U(bonuslen, <=, db->db.db_size);
+		db->db.db_data = zio_buf_alloc(DN_MAX_BONUSLEN);
+		arc_space_consume(DN_MAX_BONUSLEN, ARC_SPACE_OTHER);
+		if (bonuslen < DN_MAX_BONUSLEN)
+			bzero(db->db.db_data, DN_MAX_BONUSLEN);
+		if (bonuslen)
+			bcopy(DN_BONUS(dn->dn_phys), db->db.db_data, bonuslen);
+		DB_DNODE_EXIT(db);
+		db->db_state = DB_CACHED;
+		mutex_exit(&db->db_mtx);
+		return (0);
+	}
+
+	/*
+	 * Recheck BP_IS_HOLE() after dnode_block_freed() in case dnode_sync()
+	 * processes the delete record and clears the bp while we are waiting
+	 * for the dn_mtx (resulting in a "no" from block_freed).
+	 */
+	if (db->db_blkptr == NULL || BP_IS_HOLE(db->db_blkptr) ||
+	    (db->db_level == 0 && (dnode_block_freed(dn, db->db_blkid) ||
+	    BP_IS_HOLE(db->db_blkptr)))) {
+		arc_buf_contents_t type = DBUF_GET_BUFC_TYPE(db);
+
+		DB_DNODE_EXIT(db);
+		dbuf_set_data(db, arc_buf_alloc(db->db_objset->os_spa,
+		    db->db.db_size, db, type));
+		bzero(db->db.db_data, db->db.db_size);
+		db->db_state = DB_CACHED;
+		*flags |= DB_RF_CACHED;
+		mutex_exit(&db->db_mtx);
+		return (0);
+	}
+
+	DB_DNODE_EXIT(db);
+
+	db->db_state = DB_READ;
+	mutex_exit(&db->db_mtx);
+
+	if (DBUF_IS_L2CACHEABLE(db))
+		aflags |= ARC_FLAG_L2CACHE;
+	if (DBUF_IS_L2COMPRESSIBLE(db))
+		aflags |= ARC_FLAG_L2COMPRESS;
+
+	SET_BOOKMARK(&zb, db->db_objset->os_dsl_dataset ?
+	    db->db_objset->os_dsl_dataset->ds_object : DMU_META_OBJSET,
+	    db->db.db_object, db->db_level, db->db_blkid);
+
+	dbuf_add_ref(db, NULL);
+
+	err = arc_read(zio, db->db_objset->os_spa, db->db_blkptr,
+	    dbuf_read_done, db, ZIO_PRIORITY_SYNC_READ,
+	    (*flags & DB_RF_CANFAIL) ? ZIO_FLAG_CANFAIL : ZIO_FLAG_MUSTSUCCEED,
+	    &aflags, &zb);
+	if (aflags & ARC_FLAG_CACHED)
+		*flags |= DB_RF_CACHED;
+
+	return (SET_ERROR(err));
+}
+
+int
+dbuf_read(dmu_buf_impl_t *db, zio_t *zio, uint32_t flags)
+{
+	int err = 0;
+	boolean_t havepzio = (zio != NULL);
+	boolean_t prefetch;
+	dnode_t *dn;
+
+	/*
+	 * We don't have to hold the mutex to check db_state because it
+	 * can't be freed while we have a hold on the buffer.
+	 */
+	ASSERT(!refcount_is_zero(&db->db_holds));
+
+	if (db->db_state == DB_NOFILL)
+		return (SET_ERROR(EIO));
+
+	DB_DNODE_ENTER(db);
+	dn = DB_DNODE(db);
+	if ((flags & DB_RF_HAVESTRUCT) == 0)
+		rw_enter(&dn->dn_struct_rwlock, RW_READER);
+
+	prefetch = db->db_level == 0 && db->db_blkid != DMU_BONUS_BLKID &&
+	    (flags & DB_RF_NOPREFETCH) == 0 && dn != NULL &&
+	    DBUF_IS_CACHEABLE(db);
+
+	mutex_enter(&db->db_mtx);
+	if (db->db_state == DB_CACHED) {
+		mutex_exit(&db->db_mtx);
+		if (prefetch)
+			dmu_zfetch(&dn->dn_zfetch, db->db.db_offset,
+			    db->db.db_size, TRUE);
+		if ((flags & DB_RF_HAVESTRUCT) == 0)
+			rw_exit(&dn->dn_struct_rwlock);
+		DB_DNODE_EXIT(db);
+	} else if (db->db_state == DB_UNCACHED) {
+		spa_t *spa = dn->dn_objset->os_spa;
+
+		if (zio == NULL)
+			zio = zio_root(spa, NULL, NULL, ZIO_FLAG_CANFAIL);
+
+		err = dbuf_read_impl(db, zio, &flags);
+
+		/* dbuf_read_impl has dropped db_mtx for us */
+
+		if (!err && prefetch)
+			dmu_zfetch(&dn->dn_zfetch, db->db.db_offset,
+			    db->db.db_size, flags & DB_RF_CACHED);
+
+		if ((flags & DB_RF_HAVESTRUCT) == 0)
+			rw_exit(&dn->dn_struct_rwlock);
+		DB_DNODE_EXIT(db);
+
+		if (!err && !havepzio)
+			err = zio_wait(zio);
+	} else {
+		/*
+		 * Another reader came in while the dbuf was in flight
+		 * between UNCACHED and CACHED.  Either a writer will finish
+		 * writing the buffer (sending the dbuf to CACHED) or the
+		 * first reader's request will reach the read_done callback
+		 * and send the dbuf to CACHED.  Otherwise, a failure
+		 * occurred and the dbuf went to UNCACHED.
+		 */
+		mutex_exit(&db->db_mtx);
+		if (prefetch)
+			dmu_zfetch(&dn->dn_zfetch, db->db.db_offset,
+			    db->db.db_size, TRUE);
+		if ((flags & DB_RF_HAVESTRUCT) == 0)
+			rw_exit(&dn->dn_struct_rwlock);
+		DB_DNODE_EXIT(db);
+
+		/* Skip the wait per the caller's request. */
+		mutex_enter(&db->db_mtx);
+		if ((flags & DB_RF_NEVERWAIT) == 0) {
+			while (db->db_state == DB_READ ||
+			    db->db_state == DB_FILL) {
+				ASSERT(db->db_state == DB_READ ||
+				    (flags & DB_RF_HAVESTRUCT) == 0);
+				DTRACE_PROBE2(blocked__read, dmu_buf_impl_t *,
+				    db, zio_t *, zio);
+				cv_wait(&db->db_changed, &db->db_mtx);
+			}
+			if (db->db_state == DB_UNCACHED)
+				err = SET_ERROR(EIO);
+		}
+		mutex_exit(&db->db_mtx);
+	}
+
+	ASSERT(err || havepzio || db->db_state == DB_CACHED);
+	return (err);
+}
+
+static void
+dbuf_noread(dmu_buf_impl_t *db)
+{
+	ASSERT(!refcount_is_zero(&db->db_holds));
+	ASSERT(db->db_blkid != DMU_BONUS_BLKID);
+	mutex_enter(&db->db_mtx);
+	while (db->db_state == DB_READ || db->db_state == DB_FILL)
+		cv_wait(&db->db_changed, &db->db_mtx);
+	if (db->db_state == DB_UNCACHED) {
+		arc_buf_contents_t type = DBUF_GET_BUFC_TYPE(db);
+		spa_t *spa = db->db_objset->os_spa;
+
+		ASSERT(db->db_buf == NULL);
+		ASSERT(db->db.db_data == NULL);
+		dbuf_set_data(db, arc_buf_alloc(spa, db->db.db_size, db, type));
+		db->db_state = DB_FILL;
+	} else if (db->db_state == DB_NOFILL) {
+		dbuf_clear_data(db);
+	} else {
+		ASSERT3U(db->db_state, ==, DB_CACHED);
+	}
+	mutex_exit(&db->db_mtx);
+}
+
+/*
+ * This is our just-in-time copy function.  It makes a copy of
+ * buffers, that have been modified in a previous transaction
+ * group, before we modify them in the current active group.
+ *
+ * This function is used in two places: when we are dirtying a
+ * buffer for the first time in a txg, and when we are freeing
+ * a range in a dnode that includes this buffer.
+ *
+ * Note that when we are called from dbuf_free_range() we do
+ * not put a hold on the buffer, we just traverse the active
+ * dbuf list for the dnode.
+ */
+static void
+dbuf_fix_old_data(dmu_buf_impl_t *db, uint64_t txg)
+{
+	dbuf_dirty_record_t *dr = db->db_last_dirty;
+
+	ASSERT(MUTEX_HELD(&db->db_mtx));
+	ASSERT(db->db.db_data != NULL);
+	ASSERT(db->db_level == 0);
+	ASSERT(db->db.db_object != DMU_META_DNODE_OBJECT);
+
+	if (dr == NULL ||
+	    (dr->dt.dl.dr_data !=
+	    ((db->db_blkid  == DMU_BONUS_BLKID) ? db->db.db_data : db->db_buf)))
+		return;
+
+	/*
+	 * If the last dirty record for this dbuf has not yet synced
+	 * and its referencing the dbuf data, either:
+	 *	reset the reference to point to a new copy,
+	 * or (if there a no active holders)
+	 *	just null out the current db_data pointer.
+	 */
+	ASSERT(dr->dr_txg >= txg - 2);
+	if (db->db_blkid == DMU_BONUS_BLKID) {
+		/* Note that the data bufs here are zio_bufs */
+		dr->dt.dl.dr_data = zio_buf_alloc(DN_MAX_BONUSLEN);
+		arc_space_consume(DN_MAX_BONUSLEN, ARC_SPACE_OTHER);
+		bcopy(db->db.db_data, dr->dt.dl.dr_data, DN_MAX_BONUSLEN);
+	} else if (refcount_count(&db->db_holds) > db->db_dirtycnt) {
+		int size = db->db.db_size;
+		arc_buf_contents_t type = DBUF_GET_BUFC_TYPE(db);
+		spa_t *spa = db->db_objset->os_spa;
+
+		dr->dt.dl.dr_data = arc_buf_alloc(spa, size, db, type);
+		bcopy(db->db.db_data, dr->dt.dl.dr_data->b_data, size);
+	} else {
+		dbuf_clear_data(db);
+	}
+}
+
+void
+dbuf_unoverride(dbuf_dirty_record_t *dr)
+{
+	dmu_buf_impl_t *db = dr->dr_dbuf;
+	blkptr_t *bp = &dr->dt.dl.dr_overridden_by;
+	uint64_t txg = dr->dr_txg;
+
+	ASSERT(MUTEX_HELD(&db->db_mtx));
+	ASSERT(dr->dt.dl.dr_override_state != DR_IN_DMU_SYNC);
+	ASSERT(db->db_level == 0);
+
+	if (db->db_blkid == DMU_BONUS_BLKID ||
+	    dr->dt.dl.dr_override_state == DR_NOT_OVERRIDDEN)
+		return;
+
+	ASSERT(db->db_data_pending != dr);
+
+	/* free this block */
+	if (!BP_IS_HOLE(bp) && !dr->dt.dl.dr_nopwrite)
+		zio_free(db->db_objset->os_spa, txg, bp);
+
+	dr->dt.dl.dr_override_state = DR_NOT_OVERRIDDEN;
+	dr->dt.dl.dr_nopwrite = B_FALSE;
+
+	/*
+	 * Release the already-written buffer, so we leave it in
+	 * a consistent dirty state.  Note that all callers are
+	 * modifying the buffer, so they will immediately do
+	 * another (redundant) arc_release().  Therefore, leave
+	 * the buf thawed to save the effort of freezing &
+	 * immediately re-thawing it.
+	 */
+	arc_release(dr->dt.dl.dr_data, db);
+}
+
+/*
+ * Evict (if its unreferenced) or clear (if its referenced) any level-0
+ * data blocks in the free range, so that any future readers will find
+ * empty blocks.
+ *
+ * This is a no-op if the dataset is in the middle of an incremental
+ * receive; see comment below for details.
+ */
+void
+dbuf_free_range(dnode_t *dn, uint64_t start_blkid, uint64_t end_blkid,
+    dmu_tx_t *tx)
+{
+	dmu_buf_impl_t *db_search;
+	dmu_buf_impl_t *db, *db_next;
+	uint64_t txg = tx->tx_txg;
+	avl_index_t where;
+	boolean_t freespill =
+	    (start_blkid == DMU_SPILL_BLKID || end_blkid == DMU_SPILL_BLKID);
+
+	if (end_blkid > dn->dn_maxblkid && !freespill)
+		end_blkid = dn->dn_maxblkid;
+	dprintf_dnode(dn, "start=%llu end=%llu\n", start_blkid, end_blkid);
+
+	db_search = kmem_alloc(sizeof (dmu_buf_impl_t), KM_SLEEP);
+	db_search->db_level = 0;
+	db_search->db_blkid = start_blkid;
+	db_search->db_state = DB_SEARCH;
+
+	mutex_enter(&dn->dn_dbufs_mtx);
+	if (start_blkid >= dn->dn_unlisted_l0_blkid && !freespill) {
+		/* There can't be any dbufs in this range; no need to search. */
+#ifdef DEBUG
+		db = avl_find(&dn->dn_dbufs, db_search, &where);
+		ASSERT3P(db, ==, NULL);
+		db = avl_nearest(&dn->dn_dbufs, where, AVL_AFTER);
+		ASSERT(db == NULL || db->db_level > 0);
+#endif
+		goto out;
+	} else if (dmu_objset_is_receiving(dn->dn_objset)) {
+		/*
+		 * If we are receiving, we expect there to be no dbufs in
+		 * the range to be freed, because receive modifies each
+		 * block at most once, and in offset order.  If this is
+		 * not the case, it can lead to performance problems,
+		 * so note that we unexpectedly took the slow path.
+		 */
+		atomic_inc_64(&zfs_free_range_recv_miss);
+	}
+
+	db = avl_find(&dn->dn_dbufs, db_search, &where);
+	ASSERT3P(db, ==, NULL);
+	db = avl_nearest(&dn->dn_dbufs, where, AVL_AFTER);
+
+	for (; db != NULL; db = db_next) {
+		db_next = AVL_NEXT(&dn->dn_dbufs, db);
+		ASSERT(db->db_blkid != DMU_BONUS_BLKID);
+
+		if (db->db_level != 0 || db->db_blkid > end_blkid) {
+			break;
+		}
+		ASSERT3U(db->db_blkid, >=, start_blkid);
+
+		/* found a level 0 buffer in the range */
+		mutex_enter(&db->db_mtx);
+		if (dbuf_undirty(db, tx)) {
+			/* mutex has been dropped and dbuf destroyed */
+			continue;
+		}
+
+		if (db->db_state == DB_UNCACHED ||
+		    db->db_state == DB_NOFILL ||
+		    db->db_state == DB_EVICTING) {
+			ASSERT(db->db.db_data == NULL);
+			mutex_exit(&db->db_mtx);
+			continue;
+		}
+		if (db->db_state == DB_READ || db->db_state == DB_FILL) {
+			/* will be handled in dbuf_read_done or dbuf_rele */
+			db->db_freed_in_flight = TRUE;
+			mutex_exit(&db->db_mtx);
+			continue;
+		}
+		if (refcount_count(&db->db_holds) == 0) {
+			ASSERT(db->db_buf);
+			dbuf_clear(db);
+			continue;
+		}
+		/* The dbuf is referenced */
+
+		if (db->db_last_dirty != NULL) {
+			dbuf_dirty_record_t *dr = db->db_last_dirty;
+
+			if (dr->dr_txg == txg) {
+				/*
+				 * This buffer is "in-use", re-adjust the file
+				 * size to reflect that this buffer may
+				 * contain new data when we sync.
+				 */
+				if (db->db_blkid != DMU_SPILL_BLKID &&
+				    db->db_blkid > dn->dn_maxblkid)
+					dn->dn_maxblkid = db->db_blkid;
+				dbuf_unoverride(dr);
+			} else {
+				/*
+				 * This dbuf is not dirty in the open context.
+				 * Either uncache it (if its not referenced in
+				 * the open context) or reset its contents to
+				 * empty.
+				 */
+				dbuf_fix_old_data(db, txg);
+			}
+		}
+		/* clear the contents if its cached */
+		if (db->db_state == DB_CACHED) {
+			ASSERT(db->db.db_data != NULL);
+			arc_release(db->db_buf, db);
+			bzero(db->db.db_data, db->db.db_size);
+			arc_buf_freeze(db->db_buf);
+		}
+
+		mutex_exit(&db->db_mtx);
+	}
+
+out:
+	kmem_free(db_search, sizeof (dmu_buf_impl_t));
+	mutex_exit(&dn->dn_dbufs_mtx);
+}
+
+static int
+dbuf_block_freeable(dmu_buf_impl_t *db)
+{
+	dsl_dataset_t *ds = db->db_objset->os_dsl_dataset;
+	uint64_t birth_txg = 0;
+
+	/*
+	 * We don't need any locking to protect db_blkptr:
+	 * If it's syncing, then db_last_dirty will be set
+	 * so we'll ignore db_blkptr.
+	 *
+	 * This logic ensures that only block births for
+	 * filled blocks are considered.
+	 */
+	ASSERT(MUTEX_HELD(&db->db_mtx));
+	if (db->db_last_dirty && (db->db_blkptr == NULL ||
+	    !BP_IS_HOLE(db->db_blkptr))) {
+		birth_txg = db->db_last_dirty->dr_txg;
+	} else if (db->db_blkptr != NULL && !BP_IS_HOLE(db->db_blkptr)) {
+		birth_txg = db->db_blkptr->blk_birth;
+	}
+
+	/*
+	 * If this block don't exist or is in a snapshot, it can't be freed.
+	 * Don't pass the bp to dsl_dataset_block_freeable() since we
+	 * are holding the db_mtx lock and might deadlock if we are
+	 * prefetching a dedup-ed block.
+	 */
+	if (birth_txg != 0)
+		return (ds == NULL ||
+		    dsl_dataset_block_freeable(ds, NULL, birth_txg));
+	else
+		return (B_FALSE);
+}
+
+void
+dbuf_new_size(dmu_buf_impl_t *db, int size, dmu_tx_t *tx)
+{
+	arc_buf_t *buf, *obuf;
+	int osize = db->db.db_size;
+	arc_buf_contents_t type = DBUF_GET_BUFC_TYPE(db);
+	dnode_t *dn;
+
+	ASSERT(db->db_blkid != DMU_BONUS_BLKID);
+
+	DB_DNODE_ENTER(db);
+	dn = DB_DNODE(db);
+
+	/* XXX does *this* func really need the lock? */
+	ASSERT(RW_WRITE_HELD(&dn->dn_struct_rwlock));
+
+	/*
+	 * This call to dmu_buf_will_dirty() with the dn_struct_rwlock held
+	 * is OK, because there can be no other references to the db
+	 * when we are changing its size, so no concurrent DB_FILL can
+	 * be happening.
+	 */
+	/*
+	 * XXX we should be doing a dbuf_read, checking the return
+	 * value and returning that up to our callers
+	 */
+	dmu_buf_will_dirty(&db->db, tx);
+
+	/* create the data buffer for the new block */
+	buf = arc_buf_alloc(dn->dn_objset->os_spa, size, db, type);
+
+	/* copy old block data to the new block */
+	obuf = db->db_buf;
+	bcopy(obuf->b_data, buf->b_data, MIN(osize, size));
+	/* zero the remainder */
+	if (size > osize)
+		bzero((uint8_t *)buf->b_data + osize, size - osize);
+
+	mutex_enter(&db->db_mtx);
+	dbuf_set_data(db, buf);
+	VERIFY(arc_buf_remove_ref(obuf, db));
+	db->db.db_size = size;
+
+	if (db->db_level == 0) {
+		ASSERT3U(db->db_last_dirty->dr_txg, ==, tx->tx_txg);
+		db->db_last_dirty->dt.dl.dr_data = buf;
+	}
+	mutex_exit(&db->db_mtx);
+
+	dnode_willuse_space(dn, size-osize, tx);
+	DB_DNODE_EXIT(db);
+}
+
+void
+dbuf_release_bp(dmu_buf_impl_t *db)
+{
+	ASSERTV(objset_t *os = db->db_objset);
+
+	ASSERT(dsl_pool_sync_context(dmu_objset_pool(os)));
+	ASSERT(arc_released(os->os_phys_buf) ||
+	    list_link_active(&os->os_dsl_dataset->ds_synced_link));
+	ASSERT(db->db_parent == NULL || arc_released(db->db_parent->db_buf));
+
+	(void) arc_release(db->db_buf, db);
+}
+
+dbuf_dirty_record_t *
+dbuf_dirty(dmu_buf_impl_t *db, dmu_tx_t *tx)
+{
+	dnode_t *dn;
+	objset_t *os;
+	dbuf_dirty_record_t **drp, *dr;
+	int drop_struct_lock = FALSE;
+	boolean_t do_free_accounting = B_FALSE;
+	int txgoff = tx->tx_txg & TXG_MASK;
+
+	ASSERT(tx->tx_txg != 0);
+	ASSERT(!refcount_is_zero(&db->db_holds));
+	DMU_TX_DIRTY_BUF(tx, db);
+
+	DB_DNODE_ENTER(db);
+	dn = DB_DNODE(db);
+	/*
+	 * Shouldn't dirty a regular buffer in syncing context.  Private
+	 * objects may be dirtied in syncing context, but only if they
+	 * were already pre-dirtied in open context.
+	 */
+	ASSERT(!dmu_tx_is_syncing(tx) ||
+	    BP_IS_HOLE(dn->dn_objset->os_rootbp) ||
+	    DMU_OBJECT_IS_SPECIAL(dn->dn_object) ||
+	    dn->dn_objset->os_dsl_dataset == NULL);
+	/*
+	 * We make this assert for private objects as well, but after we
+	 * check if we're already dirty.  They are allowed to re-dirty
+	 * in syncing context.
+	 */
+	ASSERT(dn->dn_object == DMU_META_DNODE_OBJECT ||
+	    dn->dn_dirtyctx == DN_UNDIRTIED || dn->dn_dirtyctx ==
+	    (dmu_tx_is_syncing(tx) ? DN_DIRTY_SYNC : DN_DIRTY_OPEN));
+
+	mutex_enter(&db->db_mtx);
+	/*
+	 * XXX make this true for indirects too?  The problem is that
+	 * transactions created with dmu_tx_create_assigned() from
+	 * syncing context don't bother holding ahead.
+	 */
+	ASSERT(db->db_level != 0 ||
+	    db->db_state == DB_CACHED || db->db_state == DB_FILL ||
+	    db->db_state == DB_NOFILL);
+
+	mutex_enter(&dn->dn_mtx);
+	/*
+	 * Don't set dirtyctx to SYNC if we're just modifying this as we
+	 * initialize the objset.
+	 */
+	if (dn->dn_dirtyctx == DN_UNDIRTIED &&
+	    !BP_IS_HOLE(dn->dn_objset->os_rootbp)) {
+		dn->dn_dirtyctx =
+		    (dmu_tx_is_syncing(tx) ? DN_DIRTY_SYNC : DN_DIRTY_OPEN);
+		ASSERT(dn->dn_dirtyctx_firstset == NULL);
+		dn->dn_dirtyctx_firstset = kmem_alloc(1, KM_SLEEP);
+	}
+	mutex_exit(&dn->dn_mtx);
+
+	if (db->db_blkid == DMU_SPILL_BLKID)
+		dn->dn_have_spill = B_TRUE;
+
+	/*
+	 * If this buffer is already dirty, we're done.
+	 */
+	drp = &db->db_last_dirty;
+	ASSERT(*drp == NULL || (*drp)->dr_txg <= tx->tx_txg ||
+	    db->db.db_object == DMU_META_DNODE_OBJECT);
+	while ((dr = *drp) != NULL && dr->dr_txg > tx->tx_txg)
+		drp = &dr->dr_next;
+	if (dr && dr->dr_txg == tx->tx_txg) {
+		DB_DNODE_EXIT(db);
+
+		if (db->db_level == 0 && db->db_blkid != DMU_BONUS_BLKID) {
+			/*
+			 * If this buffer has already been written out,
+			 * we now need to reset its state.
+			 */
+			dbuf_unoverride(dr);
+			if (db->db.db_object != DMU_META_DNODE_OBJECT &&
+			    db->db_state != DB_NOFILL)
+				arc_buf_thaw(db->db_buf);
+		}
+		mutex_exit(&db->db_mtx);
+		return (dr);
+	}
+
+	/*
+	 * Only valid if not already dirty.
+	 */
+	ASSERT(dn->dn_object == 0 ||
+	    dn->dn_dirtyctx == DN_UNDIRTIED || dn->dn_dirtyctx ==
+	    (dmu_tx_is_syncing(tx) ? DN_DIRTY_SYNC : DN_DIRTY_OPEN));
+
+	ASSERT3U(dn->dn_nlevels, >, db->db_level);
+	ASSERT((dn->dn_phys->dn_nlevels == 0 && db->db_level == 0) ||
+	    dn->dn_phys->dn_nlevels > db->db_level ||
+	    dn->dn_next_nlevels[txgoff] > db->db_level ||
+	    dn->dn_next_nlevels[(tx->tx_txg-1) & TXG_MASK] > db->db_level ||
+	    dn->dn_next_nlevels[(tx->tx_txg-2) & TXG_MASK] > db->db_level);
+
+	/*
+	 * We should only be dirtying in syncing context if it's the
+	 * mos or we're initializing the os or it's a special object.
+	 * However, we are allowed to dirty in syncing context provided
+	 * we already dirtied it in open context.  Hence we must make
+	 * this assertion only if we're not already dirty.
+	 */
+	os = dn->dn_objset;
+	ASSERT(!dmu_tx_is_syncing(tx) || DMU_OBJECT_IS_SPECIAL(dn->dn_object) ||
+	    os->os_dsl_dataset == NULL || BP_IS_HOLE(os->os_rootbp));
+	ASSERT(db->db.db_size != 0);
+
+	dprintf_dbuf(db, "size=%llx\n", (u_longlong_t)db->db.db_size);
+
+	if (db->db_blkid != DMU_BONUS_BLKID) {
+		/*
+		 * Update the accounting.
+		 * Note: we delay "free accounting" until after we drop
+		 * the db_mtx.  This keeps us from grabbing other locks
+		 * (and possibly deadlocking) in bp_get_dsize() while
+		 * also holding the db_mtx.
+		 */
+		dnode_willuse_space(dn, db->db.db_size, tx);
+		do_free_accounting = dbuf_block_freeable(db);
+	}
+
+	/*
+	 * If this buffer is dirty in an old transaction group we need
+	 * to make a copy of it so that the changes we make in this
+	 * transaction group won't leak out when we sync the older txg.
+	 */
+	dr = kmem_zalloc(sizeof (dbuf_dirty_record_t), KM_SLEEP);
+	list_link_init(&dr->dr_dirty_node);
+	if (db->db_level == 0) {
+		void *data_old = db->db_buf;
+
+		if (db->db_state != DB_NOFILL) {
+			if (db->db_blkid == DMU_BONUS_BLKID) {
+				dbuf_fix_old_data(db, tx->tx_txg);
+				data_old = db->db.db_data;
+			} else if (db->db.db_object != DMU_META_DNODE_OBJECT) {
+				/*
+				 * Release the data buffer from the cache so
+				 * that we can modify it without impacting
+				 * possible other users of this cached data
+				 * block.  Note that indirect blocks and
+				 * private objects are not released until the
+				 * syncing state (since they are only modified
+				 * then).
+				 */
+				arc_release(db->db_buf, db);
+				dbuf_fix_old_data(db, tx->tx_txg);
+				data_old = db->db_buf;
+			}
+			ASSERT(data_old != NULL);
+		}
+		dr->dt.dl.dr_data = data_old;
+	} else {
+		mutex_init(&dr->dt.di.dr_mtx, NULL, MUTEX_DEFAULT, NULL);
+		list_create(&dr->dt.di.dr_children,
+		    sizeof (dbuf_dirty_record_t),
+		    offsetof(dbuf_dirty_record_t, dr_dirty_node));
+	}
+	if (db->db_blkid != DMU_BONUS_BLKID && os->os_dsl_dataset != NULL)
+		dr->dr_accounted = db->db.db_size;
+	dr->dr_dbuf = db;
+	dr->dr_txg = tx->tx_txg;
+	dr->dr_next = *drp;
+	*drp = dr;
+
+	/*
+	 * We could have been freed_in_flight between the dbuf_noread
+	 * and dbuf_dirty.  We win, as though the dbuf_noread() had
+	 * happened after the free.
+	 */
+	if (db->db_level == 0 && db->db_blkid != DMU_BONUS_BLKID &&
+	    db->db_blkid != DMU_SPILL_BLKID) {
+		mutex_enter(&dn->dn_mtx);
+		if (dn->dn_free_ranges[txgoff] != NULL) {
+			range_tree_clear(dn->dn_free_ranges[txgoff],
+			    db->db_blkid, 1);
+		}
+		mutex_exit(&dn->dn_mtx);
+		db->db_freed_in_flight = FALSE;
+	}
+
+	/*
+	 * This buffer is now part of this txg
+	 */
+	dbuf_add_ref(db, (void *)(uintptr_t)tx->tx_txg);
+	db->db_dirtycnt += 1;
+	ASSERT3U(db->db_dirtycnt, <=, 3);
+
+	mutex_exit(&db->db_mtx);
+
+	if (db->db_blkid == DMU_BONUS_BLKID ||
+	    db->db_blkid == DMU_SPILL_BLKID) {
+		mutex_enter(&dn->dn_mtx);
+		ASSERT(!list_link_active(&dr->dr_dirty_node));
+		list_insert_tail(&dn->dn_dirty_records[txgoff], dr);
+		mutex_exit(&dn->dn_mtx);
+		dnode_setdirty(dn, tx);
+		DB_DNODE_EXIT(db);
+		return (dr);
+	} else if (do_free_accounting) {
+		blkptr_t *bp = db->db_blkptr;
+		int64_t willfree = (bp && !BP_IS_HOLE(bp)) ?
+		    bp_get_dsize(os->os_spa, bp) : db->db.db_size;
+		/*
+		 * This is only a guess -- if the dbuf is dirty
+		 * in a previous txg, we don't know how much
+		 * space it will use on disk yet.  We should
+		 * really have the struct_rwlock to access
+		 * db_blkptr, but since this is just a guess,
+		 * it's OK if we get an odd answer.
+		 */
+		ddt_prefetch(os->os_spa, bp);
+		dnode_willuse_space(dn, -willfree, tx);
+	}
+
+	if (!RW_WRITE_HELD(&dn->dn_struct_rwlock)) {
+		rw_enter(&dn->dn_struct_rwlock, RW_READER);
+		drop_struct_lock = TRUE;
+	}
+
+	if (db->db_level == 0) {
+		dnode_new_blkid(dn, db->db_blkid, tx, drop_struct_lock);
+		ASSERT(dn->dn_maxblkid >= db->db_blkid);
+	}
+
+	if (db->db_level+1 < dn->dn_nlevels) {
+		dmu_buf_impl_t *parent = db->db_parent;
+		dbuf_dirty_record_t *di;
+		int parent_held = FALSE;
+
+		if (db->db_parent == NULL || db->db_parent == dn->dn_dbuf) {
+			int epbs = dn->dn_indblkshift - SPA_BLKPTRSHIFT;
+
+			parent = dbuf_hold_level(dn, db->db_level+1,
+			    db->db_blkid >> epbs, FTAG);
+			ASSERT(parent != NULL);
+			parent_held = TRUE;
+		}
+		if (drop_struct_lock)
+			rw_exit(&dn->dn_struct_rwlock);
+		ASSERT3U(db->db_level+1, ==, parent->db_level);
+		di = dbuf_dirty(parent, tx);
+		if (parent_held)
+			dbuf_rele(parent, FTAG);
+
+		mutex_enter(&db->db_mtx);
+		/*
+		 * Since we've dropped the mutex, it's possible that
+		 * dbuf_undirty() might have changed this out from under us.
+		 */
+		if (db->db_last_dirty == dr ||
+		    dn->dn_object == DMU_META_DNODE_OBJECT) {
+			mutex_enter(&di->dt.di.dr_mtx);
+			ASSERT3U(di->dr_txg, ==, tx->tx_txg);
+			ASSERT(!list_link_active(&dr->dr_dirty_node));
+			list_insert_tail(&di->dt.di.dr_children, dr);
+			mutex_exit(&di->dt.di.dr_mtx);
+			dr->dr_parent = di;
+		}
+		mutex_exit(&db->db_mtx);
+	} else {
+		ASSERT(db->db_level+1 == dn->dn_nlevels);
+		ASSERT(db->db_blkid < dn->dn_nblkptr);
+		ASSERT(db->db_parent == NULL || db->db_parent == dn->dn_dbuf);
+		mutex_enter(&dn->dn_mtx);
+		ASSERT(!list_link_active(&dr->dr_dirty_node));
+		list_insert_tail(&dn->dn_dirty_records[txgoff], dr);
+		mutex_exit(&dn->dn_mtx);
+		if (drop_struct_lock)
+			rw_exit(&dn->dn_struct_rwlock);
+	}
+
+	dnode_setdirty(dn, tx);
+	DB_DNODE_EXIT(db);
+	return (dr);
+}
+
+/*
+ * Undirty a buffer in the transaction group referenced by the given
+ * transaction.  Return whether this evicted the dbuf.
+ */
+static boolean_t
+dbuf_undirty(dmu_buf_impl_t *db, dmu_tx_t *tx)
+{
+	dnode_t *dn;
+	uint64_t txg = tx->tx_txg;
+	dbuf_dirty_record_t *dr, **drp;
+
+	ASSERT(txg != 0);
+
+	/*
+	 * Due to our use of dn_nlevels below, this can only be called
+	 * in open context, unless we are operating on the MOS.
+	 * From syncing context, dn_nlevels may be different from the
+	 * dn_nlevels used when dbuf was dirtied.
+	 */
+	ASSERT(db->db_objset ==
+	    dmu_objset_pool(db->db_objset)->dp_meta_objset ||
+	    txg != spa_syncing_txg(dmu_objset_spa(db->db_objset)));
+	ASSERT(db->db_blkid != DMU_BONUS_BLKID);
+	ASSERT0(db->db_level);
+	ASSERT(MUTEX_HELD(&db->db_mtx));
+
+	/*
+	 * If this buffer is not dirty, we're done.
+	 */
+	for (drp = &db->db_last_dirty; (dr = *drp) != NULL; drp = &dr->dr_next)
+		if (dr->dr_txg <= txg)
+			break;
+	if (dr == NULL || dr->dr_txg < txg)
+		return (B_FALSE);
+	ASSERT(dr->dr_txg == txg);
+	ASSERT(dr->dr_dbuf == db);
+
+	DB_DNODE_ENTER(db);
+	dn = DB_DNODE(db);
+
+	dprintf_dbuf(db, "size=%llx\n", (u_longlong_t)db->db.db_size);
+
+	ASSERT(db->db.db_size != 0);
+
+	dsl_pool_undirty_space(dmu_objset_pool(dn->dn_objset),
+	    dr->dr_accounted, txg);
+
+	*drp = dr->dr_next;
+
+	/*
+	 * Note that there are three places in dbuf_dirty()
+	 * where this dirty record may be put on a list.
+	 * Make sure to do a list_remove corresponding to
+	 * every one of those list_insert calls.
+	 */
+	if (dr->dr_parent) {
+		mutex_enter(&dr->dr_parent->dt.di.dr_mtx);
+		list_remove(&dr->dr_parent->dt.di.dr_children, dr);
+		mutex_exit(&dr->dr_parent->dt.di.dr_mtx);
+	} else if (db->db_blkid == DMU_SPILL_BLKID ||
+	    db->db_level + 1 == dn->dn_nlevels) {
+		ASSERT(db->db_blkptr == NULL || db->db_parent == dn->dn_dbuf);
+		mutex_enter(&dn->dn_mtx);
+		list_remove(&dn->dn_dirty_records[txg & TXG_MASK], dr);
+		mutex_exit(&dn->dn_mtx);
+	}
+	DB_DNODE_EXIT(db);
+
+	if (db->db_state != DB_NOFILL) {
+		dbuf_unoverride(dr);
+
+		ASSERT(db->db_buf != NULL);
+		ASSERT(dr->dt.dl.dr_data != NULL);
+		if (dr->dt.dl.dr_data != db->db_buf)
+			VERIFY(arc_buf_remove_ref(dr->dt.dl.dr_data, db));
+	}
+
+	kmem_free(dr, sizeof (dbuf_dirty_record_t));
+
+	ASSERT(db->db_dirtycnt > 0);
+	db->db_dirtycnt -= 1;
+
+	if (refcount_remove(&db->db_holds, (void *)(uintptr_t)txg) == 0) {
+		arc_buf_t *buf = db->db_buf;
+
+		ASSERT(db->db_state == DB_NOFILL || arc_released(buf));
+		dbuf_clear_data(db);
+		VERIFY(arc_buf_remove_ref(buf, db));
+		dbuf_evict(db);
+		return (B_TRUE);
+	}
+
+	return (B_FALSE);
+}
+
+void
+dmu_buf_will_dirty(dmu_buf_t *db_fake, dmu_tx_t *tx)
+{
+	dmu_buf_impl_t *db = (dmu_buf_impl_t *)db_fake;
+	int rf = DB_RF_MUST_SUCCEED | DB_RF_NOPREFETCH;
+
+	ASSERT(tx->tx_txg != 0);
+	ASSERT(!refcount_is_zero(&db->db_holds));
+
+	DB_DNODE_ENTER(db);
+	if (RW_WRITE_HELD(&DB_DNODE(db)->dn_struct_rwlock))
+		rf |= DB_RF_HAVESTRUCT;
+	DB_DNODE_EXIT(db);
+	(void) dbuf_read(db, NULL, rf);
+	(void) dbuf_dirty(db, tx);
+}
+
+void
+dmu_buf_will_not_fill(dmu_buf_t *db_fake, dmu_tx_t *tx)
+{
+	dmu_buf_impl_t *db = (dmu_buf_impl_t *)db_fake;
+
+	db->db_state = DB_NOFILL;
+
+	dmu_buf_will_fill(db_fake, tx);
+}
+
+void
+dmu_buf_will_fill(dmu_buf_t *db_fake, dmu_tx_t *tx)
+{
+	dmu_buf_impl_t *db = (dmu_buf_impl_t *)db_fake;
+
+	ASSERT(db->db_blkid != DMU_BONUS_BLKID);
+	ASSERT(tx->tx_txg != 0);
+	ASSERT(db->db_level == 0);
+	ASSERT(!refcount_is_zero(&db->db_holds));
+
+	ASSERT(db->db.db_object != DMU_META_DNODE_OBJECT ||
+	    dmu_tx_private_ok(tx));
+
+	dbuf_noread(db);
+	(void) dbuf_dirty(db, tx);
+}
+
+#pragma weak dmu_buf_fill_done = dbuf_fill_done
+/* ARGSUSED */
+void
+dbuf_fill_done(dmu_buf_impl_t *db, dmu_tx_t *tx)
+{
+	mutex_enter(&db->db_mtx);
+	DBUF_VERIFY(db);
+
+	if (db->db_state == DB_FILL) {
+		if (db->db_level == 0 && db->db_freed_in_flight) {
+			ASSERT(db->db_blkid != DMU_BONUS_BLKID);
+			/* we were freed while filling */
+			/* XXX dbuf_undirty? */
+			bzero(db->db.db_data, db->db.db_size);
+			db->db_freed_in_flight = FALSE;
+		}
+		db->db_state = DB_CACHED;
+		cv_broadcast(&db->db_changed);
+	}
+	mutex_exit(&db->db_mtx);
+}
+
+void
+dmu_buf_write_embedded(dmu_buf_t *dbuf, void *data,
+    bp_embedded_type_t etype, enum zio_compress comp,
+    int uncompressed_size, int compressed_size, int byteorder,
+    dmu_tx_t *tx)
+{
+	dmu_buf_impl_t *db = (dmu_buf_impl_t *)dbuf;
+	struct dirty_leaf *dl;
+	dmu_object_type_t type;
+
+	DB_DNODE_ENTER(db);
+	type = DB_DNODE(db)->dn_type;
+	DB_DNODE_EXIT(db);
+
+	ASSERT0(db->db_level);
+	ASSERT(db->db_blkid != DMU_BONUS_BLKID);
+
+	dmu_buf_will_not_fill(dbuf, tx);
+
+	ASSERT3U(db->db_last_dirty->dr_txg, ==, tx->tx_txg);
+	dl = &db->db_last_dirty->dt.dl;
+	encode_embedded_bp_compressed(&dl->dr_overridden_by,
+	    data, comp, uncompressed_size, compressed_size);
+	BPE_SET_ETYPE(&dl->dr_overridden_by, etype);
+	BP_SET_TYPE(&dl->dr_overridden_by, type);
+	BP_SET_LEVEL(&dl->dr_overridden_by, 0);
+	BP_SET_BYTEORDER(&dl->dr_overridden_by, byteorder);
+
+	dl->dr_override_state = DR_OVERRIDDEN;
+	dl->dr_overridden_by.blk_birth = db->db_last_dirty->dr_txg;
+}
+
+/*
+ * Directly assign a provided arc buf to a given dbuf if it's not referenced
+ * by anybody except our caller. Otherwise copy arcbuf's contents to dbuf.
+ */
+void
+dbuf_assign_arcbuf(dmu_buf_impl_t *db, arc_buf_t *buf, dmu_tx_t *tx)
+{
+	ASSERT(!refcount_is_zero(&db->db_holds));
+	ASSERT(db->db_blkid != DMU_BONUS_BLKID);
+	ASSERT(db->db_level == 0);
+	ASSERT(DBUF_GET_BUFC_TYPE(db) == ARC_BUFC_DATA);
+	ASSERT(buf != NULL);
+	ASSERT(arc_buf_size(buf) == db->db.db_size);
+	ASSERT(tx->tx_txg != 0);
+
+	arc_return_buf(buf, db);
+	ASSERT(arc_released(buf));
+
+	mutex_enter(&db->db_mtx);
+
+	while (db->db_state == DB_READ || db->db_state == DB_FILL)
+		cv_wait(&db->db_changed, &db->db_mtx);
+
+	ASSERT(db->db_state == DB_CACHED || db->db_state == DB_UNCACHED);
+
+	if (db->db_state == DB_CACHED &&
+	    refcount_count(&db->db_holds) - 1 > db->db_dirtycnt) {
+		mutex_exit(&db->db_mtx);
+		(void) dbuf_dirty(db, tx);
+		bcopy(buf->b_data, db->db.db_data, db->db.db_size);
+		VERIFY(arc_buf_remove_ref(buf, db));
+		xuio_stat_wbuf_copied();
+		return;
+	}
+
+	xuio_stat_wbuf_nocopy();
+	if (db->db_state == DB_CACHED) {
+		dbuf_dirty_record_t *dr = db->db_last_dirty;
+
+		ASSERT(db->db_buf != NULL);
+		if (dr != NULL && dr->dr_txg == tx->tx_txg) {
+			ASSERT(dr->dt.dl.dr_data == db->db_buf);
+			if (!arc_released(db->db_buf)) {
+				ASSERT(dr->dt.dl.dr_override_state ==
+				    DR_OVERRIDDEN);
+				arc_release(db->db_buf, db);
+			}
+			dr->dt.dl.dr_data = buf;
+			VERIFY(arc_buf_remove_ref(db->db_buf, db));
+		} else if (dr == NULL || dr->dt.dl.dr_data != db->db_buf) {
+			arc_release(db->db_buf, db);
+			VERIFY(arc_buf_remove_ref(db->db_buf, db));
+		}
+		db->db_buf = NULL;
+	}
+	ASSERT(db->db_buf == NULL);
+	dbuf_set_data(db, buf);
+	db->db_state = DB_FILL;
+	mutex_exit(&db->db_mtx);
+	(void) dbuf_dirty(db, tx);
+	dmu_buf_fill_done(&db->db, tx);
+}
+
+/*
+ * "Clear" the contents of this dbuf.  This will mark the dbuf
+ * EVICTING and clear *most* of its references.  Unfortunately,
+ * when we are not holding the dn_dbufs_mtx, we can't clear the
+ * entry in the dn_dbufs list.  We have to wait until dbuf_destroy()
+ * in this case.  For callers from the DMU we will usually see:
+ *	dbuf_clear()->arc_clear_callback()->dbuf_do_evict()->dbuf_destroy()
+ * For the arc callback, we will usually see:
+ *	dbuf_do_evict()->dbuf_clear();dbuf_destroy()
+ * Sometimes, though, we will get a mix of these two:
+ *	DMU: dbuf_clear()->arc_clear_callback()
+ *	ARC: dbuf_do_evict()->dbuf_destroy()
+ *
+ * This routine will dissociate the dbuf from the arc, by calling
+ * arc_clear_callback(), but will not evict the data from the ARC.
+ */
+void
+dbuf_clear(dmu_buf_impl_t *db)
+{
+	dnode_t *dn;
+	dmu_buf_impl_t *parent = db->db_parent;
+	dmu_buf_impl_t *dndb;
+	boolean_t dbuf_gone = B_FALSE;
+
+	ASSERT(MUTEX_HELD(&db->db_mtx));
+	ASSERT(refcount_is_zero(&db->db_holds));
+
+	dbuf_evict_user(db);
+
+	if (db->db_state == DB_CACHED) {
+		ASSERT(db->db.db_data != NULL);
+		if (db->db_blkid == DMU_BONUS_BLKID) {
+			zio_buf_free(db->db.db_data, DN_MAX_BONUSLEN);
+			arc_space_return(DN_MAX_BONUSLEN, ARC_SPACE_OTHER);
+		}
+		db->db.db_data = NULL;
+		db->db_state = DB_UNCACHED;
+	}
+
+	ASSERT(db->db_state == DB_UNCACHED || db->db_state == DB_NOFILL);
+	ASSERT(db->db_data_pending == NULL);
+
+	db->db_state = DB_EVICTING;
+	db->db_blkptr = NULL;
+
+	DB_DNODE_ENTER(db);
+	dn = DB_DNODE(db);
+	dndb = dn->dn_dbuf;
+	if (db->db_blkid != DMU_BONUS_BLKID && MUTEX_HELD(&dn->dn_dbufs_mtx)) {
+		avl_remove(&dn->dn_dbufs, db);
+		atomic_dec_32(&dn->dn_dbufs_count);
+		membar_producer();
+		DB_DNODE_EXIT(db);
+		/*
+		 * Decrementing the dbuf count means that the hold corresponding
+		 * to the removed dbuf is no longer discounted in dnode_move(),
+		 * so the dnode cannot be moved until after we release the hold.
+		 * The membar_producer() ensures visibility of the decremented
+		 * value in dnode_move(), since DB_DNODE_EXIT doesn't actually
+		 * release any lock.
+		 */
+		dnode_rele(dn, db);
+		db->db_dnode_handle = NULL;
+	} else {
+		DB_DNODE_EXIT(db);
+	}
+
+	if (db->db_buf)
+		dbuf_gone = arc_clear_callback(db->db_buf);
+
+	if (!dbuf_gone)
+		mutex_exit(&db->db_mtx);
+
+	/*
+	 * If this dbuf is referenced from an indirect dbuf,
+	 * decrement the ref count on the indirect dbuf.
+	 */
+	if (parent && parent != dndb)
+		dbuf_rele(parent, db);
+}
+
+__attribute__((always_inline))
+static inline int
+dbuf_findbp(dnode_t *dn, int level, uint64_t blkid, int fail_sparse,
+    dmu_buf_impl_t **parentp, blkptr_t **bpp, struct dbuf_hold_impl_data *dh)
+{
+	int nlevels, epbs;
+
+	*parentp = NULL;
+	*bpp = NULL;
+
+	ASSERT(blkid != DMU_BONUS_BLKID);
+
+	if (blkid == DMU_SPILL_BLKID) {
+		mutex_enter(&dn->dn_mtx);
+		if (dn->dn_have_spill &&
+		    (dn->dn_phys->dn_flags & DNODE_FLAG_SPILL_BLKPTR))
+			*bpp = &dn->dn_phys->dn_spill;
+		else
+			*bpp = NULL;
+		dbuf_add_ref(dn->dn_dbuf, NULL);
+		*parentp = dn->dn_dbuf;
+		mutex_exit(&dn->dn_mtx);
+		return (0);
+	}
+
+	if (dn->dn_phys->dn_nlevels == 0)
+		nlevels = 1;
+	else
+		nlevels = dn->dn_phys->dn_nlevels;
+
+	epbs = dn->dn_indblkshift - SPA_BLKPTRSHIFT;
+
+	ASSERT3U(level * epbs, <, 64);
+	ASSERT(RW_LOCK_HELD(&dn->dn_struct_rwlock));
+	if (level >= nlevels ||
+	    (blkid > (dn->dn_phys->dn_maxblkid >> (level * epbs)))) {
+		/* the buffer has no parent yet */
+		return (SET_ERROR(ENOENT));
+	} else if (level < nlevels-1) {
+		/* this block is referenced from an indirect block */
+		int err;
+		if (dh == NULL) {
+			err = dbuf_hold_impl(dn, level+1, blkid >> epbs,
+					fail_sparse, NULL, parentp);
+		} else {
+			__dbuf_hold_impl_init(dh + 1, dn, dh->dh_level + 1,
+					blkid >> epbs, fail_sparse, NULL,
+					parentp, dh->dh_depth + 1);
+			err = __dbuf_hold_impl(dh + 1);
+		}
+		if (err)
+			return (err);
+		err = dbuf_read(*parentp, NULL,
+		    (DB_RF_HAVESTRUCT | DB_RF_NOPREFETCH | DB_RF_CANFAIL));
+		if (err) {
+			dbuf_rele(*parentp, NULL);
+			*parentp = NULL;
+			return (err);
+		}
+		*bpp = ((blkptr_t *)(*parentp)->db.db_data) +
+		    (blkid & ((1ULL << epbs) - 1));
+		return (0);
+	} else {
+		/* the block is referenced from the dnode */
+		ASSERT3U(level, ==, nlevels-1);
+		ASSERT(dn->dn_phys->dn_nblkptr == 0 ||
+		    blkid < dn->dn_phys->dn_nblkptr);
+		if (dn->dn_dbuf) {
+			dbuf_add_ref(dn->dn_dbuf, NULL);
+			*parentp = dn->dn_dbuf;
+		}
+		*bpp = &dn->dn_phys->dn_blkptr[blkid];
+		return (0);
+	}
+}
+
+static dmu_buf_impl_t *
+dbuf_create(dnode_t *dn, uint8_t level, uint64_t blkid,
+    dmu_buf_impl_t *parent, blkptr_t *blkptr)
+{
+	objset_t *os = dn->dn_objset;
+	dmu_buf_impl_t *db, *odb;
+
+	ASSERT(RW_LOCK_HELD(&dn->dn_struct_rwlock));
+	ASSERT(dn->dn_type != DMU_OT_NONE);
+
+	db = kmem_cache_alloc(dbuf_cache, KM_SLEEP);
+
+	db->db_objset = os;
+	db->db.db_object = dn->dn_object;
+	db->db_level = level;
+	db->db_blkid = blkid;
+	db->db_last_dirty = NULL;
+	db->db_dirtycnt = 0;
+	db->db_dnode_handle = dn->dn_handle;
+	db->db_parent = parent;
+	db->db_blkptr = blkptr;
+
+	db->db_user = NULL;
+	db->db_user_immediate_evict = FALSE;
+	db->db_freed_in_flight = FALSE;
+	db->db_pending_evict = FALSE;
+
+	if (blkid == DMU_BONUS_BLKID) {
+		ASSERT3P(parent, ==, dn->dn_dbuf);
+		db->db.db_size = DN_MAX_BONUSLEN -
+		    (dn->dn_nblkptr-1) * sizeof (blkptr_t);
+		ASSERT3U(db->db.db_size, >=, dn->dn_bonuslen);
+		db->db.db_offset = DMU_BONUS_BLKID;
+		db->db_state = DB_UNCACHED;
+		/* the bonus dbuf is not placed in the hash table */
+		arc_space_consume(sizeof (dmu_buf_impl_t), ARC_SPACE_OTHER);
+		return (db);
+	} else if (blkid == DMU_SPILL_BLKID) {
+		db->db.db_size = (blkptr != NULL) ?
+		    BP_GET_LSIZE(blkptr) : SPA_MINBLOCKSIZE;
+		db->db.db_offset = 0;
+	} else {
+		int blocksize =
+		    db->db_level ? 1 << dn->dn_indblkshift : dn->dn_datablksz;
+		db->db.db_size = blocksize;
+		db->db.db_offset = db->db_blkid * blocksize;
+	}
+
+	/*
+	 * Hold the dn_dbufs_mtx while we get the new dbuf
+	 * in the hash table *and* added to the dbufs list.
+	 * This prevents a possible deadlock with someone
+	 * trying to look up this dbuf before its added to the
+	 * dn_dbufs list.
+	 */
+	mutex_enter(&dn->dn_dbufs_mtx);
+	db->db_state = DB_EVICTING;
+	if ((odb = dbuf_hash_insert(db)) != NULL) {
+		/* someone else inserted it first */
+		kmem_cache_free(dbuf_cache, db);
+		mutex_exit(&dn->dn_dbufs_mtx);
+		return (odb);
+	}
+	avl_add(&dn->dn_dbufs, db);
+	if (db->db_level == 0 && db->db_blkid >=
+	    dn->dn_unlisted_l0_blkid)
+		dn->dn_unlisted_l0_blkid = db->db_blkid + 1;
+	db->db_state = DB_UNCACHED;
+	mutex_exit(&dn->dn_dbufs_mtx);
+	arc_space_consume(sizeof (dmu_buf_impl_t), ARC_SPACE_OTHER);
+
+	if (parent && parent != dn->dn_dbuf)
+		dbuf_add_ref(parent, db);
+
+	ASSERT(dn->dn_object == DMU_META_DNODE_OBJECT ||
+	    refcount_count(&dn->dn_holds) > 0);
+	(void) refcount_add(&dn->dn_holds, db);
+	atomic_inc_32(&dn->dn_dbufs_count);
+
+	dprintf_dbuf(db, "db=%p\n", db);
+
+	return (db);
+}
+
+static int
+dbuf_do_evict(void *private)
+{
+	dmu_buf_impl_t *db = private;
+
+	if (!MUTEX_HELD(&db->db_mtx))
+		mutex_enter(&db->db_mtx);
+
+	ASSERT(refcount_is_zero(&db->db_holds));
+
+	if (db->db_state != DB_EVICTING) {
+		ASSERT(db->db_state == DB_CACHED);
+		DBUF_VERIFY(db);
+		db->db_buf = NULL;
+		dbuf_evict(db);
+	} else {
+		mutex_exit(&db->db_mtx);
+		dbuf_destroy(db);
+	}
+	return (0);
+}
+
+static void
+dbuf_destroy(dmu_buf_impl_t *db)
+{
+	ASSERT(refcount_is_zero(&db->db_holds));
+
+	if (db->db_blkid != DMU_BONUS_BLKID) {
+		/*
+		 * If this dbuf is still on the dn_dbufs list,
+		 * remove it from that list.
+		 */
+		if (db->db_dnode_handle != NULL) {
+			dnode_t *dn;
+
+			DB_DNODE_ENTER(db);
+			dn = DB_DNODE(db);
+			mutex_enter(&dn->dn_dbufs_mtx);
+			avl_remove(&dn->dn_dbufs, db);
+			atomic_dec_32(&dn->dn_dbufs_count);
+			mutex_exit(&dn->dn_dbufs_mtx);
+			DB_DNODE_EXIT(db);
+			/*
+			 * Decrementing the dbuf count means that the hold
+			 * corresponding to the removed dbuf is no longer
+			 * discounted in dnode_move(), so the dnode cannot be
+			 * moved until after we release the hold.
+			 */
+			dnode_rele(dn, db);
+			db->db_dnode_handle = NULL;
+		}
+		dbuf_hash_remove(db);
+	}
+	db->db_parent = NULL;
+	db->db_buf = NULL;
+
+	ASSERT(db->db.db_data == NULL);
+	ASSERT(db->db_hash_next == NULL);
+	ASSERT(db->db_blkptr == NULL);
+	ASSERT(db->db_data_pending == NULL);
+
+	kmem_cache_free(dbuf_cache, db);
+	arc_space_return(sizeof (dmu_buf_impl_t), ARC_SPACE_OTHER);
+}
+
+void
+dbuf_prefetch(dnode_t *dn, uint64_t blkid, zio_priority_t prio)
+{
+	dmu_buf_impl_t *db = NULL;
+	blkptr_t *bp = NULL;
+
+	ASSERT(blkid != DMU_BONUS_BLKID);
+	ASSERT(RW_LOCK_HELD(&dn->dn_struct_rwlock));
+
+	if (dnode_block_freed(dn, blkid))
+		return;
+
+	/* dbuf_find() returns with db_mtx held */
+	if ((db = dbuf_find(dn->dn_objset, dn->dn_object, 0, blkid))) {
+		/*
+		 * This dbuf is already in the cache.  We assume that
+		 * it is already CACHED, or else about to be either
+		 * read or filled.
+		 */
+		mutex_exit(&db->db_mtx);
+		return;
+	}
+
+	if (dbuf_findbp(dn, 0, blkid, TRUE, &db, &bp, NULL) == 0) {
+		if (bp && !BP_IS_HOLE(bp) && !BP_IS_EMBEDDED(bp)) {
+			dsl_dataset_t *ds = dn->dn_objset->os_dsl_dataset;
+			arc_flags_t aflags =
+			    ARC_FLAG_NOWAIT | ARC_FLAG_PREFETCH;
+			zbookmark_phys_t zb;
+
+			SET_BOOKMARK(&zb, ds ? ds->ds_object : DMU_META_OBJSET,
+			    dn->dn_object, 0, blkid);
+
+			(void) arc_read(NULL, dn->dn_objset->os_spa,
+			    bp, NULL, NULL, prio,
+			    ZIO_FLAG_CANFAIL | ZIO_FLAG_SPECULATIVE,
+			    &aflags, &zb);
+		}
+		if (db)
+			dbuf_rele(db, NULL);
+	}
+}
+
+#define	DBUF_HOLD_IMPL_MAX_DEPTH	20
+
+/*
+ * Returns with db_holds incremented, and db_mtx not held.
+ * Note: dn_struct_rwlock must be held.
+ */
+static int
+__dbuf_hold_impl(struct dbuf_hold_impl_data *dh)
+{
+	ASSERT3S(dh->dh_depth, <, DBUF_HOLD_IMPL_MAX_DEPTH);
+	dh->dh_parent = NULL;
+
+	ASSERT(dh->dh_blkid != DMU_BONUS_BLKID);
+	ASSERT(RW_LOCK_HELD(&dh->dh_dn->dn_struct_rwlock));
+	ASSERT3U(dh->dh_dn->dn_nlevels, >, dh->dh_level);
+
+	*(dh->dh_dbp) = NULL;
+top:
+	/* dbuf_find() returns with db_mtx held */
+	dh->dh_db = dbuf_find(dh->dh_dn->dn_objset, dh->dh_dn->dn_object,
+	    dh->dh_level, dh->dh_blkid);
+
+	if (dh->dh_db == NULL) {
+		dh->dh_bp = NULL;
+
+		ASSERT3P(dh->dh_parent, ==, NULL);
+		dh->dh_err = dbuf_findbp(dh->dh_dn, dh->dh_level, dh->dh_blkid,
+					dh->dh_fail_sparse, &dh->dh_parent,
+					&dh->dh_bp, dh);
+		if (dh->dh_fail_sparse) {
+			if (dh->dh_err == 0 &&
+			    dh->dh_bp && BP_IS_HOLE(dh->dh_bp))
+				dh->dh_err = SET_ERROR(ENOENT);
+			if (dh->dh_err) {
+				if (dh->dh_parent)
+					dbuf_rele(dh->dh_parent, NULL);
+				return (dh->dh_err);
+			}
+		}
+		if (dh->dh_err && dh->dh_err != ENOENT)
+			return (dh->dh_err);
+		dh->dh_db = dbuf_create(dh->dh_dn, dh->dh_level, dh->dh_blkid,
+					dh->dh_parent, dh->dh_bp);
+	}
+
+	if (dh->dh_db->db_buf && refcount_is_zero(&dh->dh_db->db_holds)) {
+		arc_buf_add_ref(dh->dh_db->db_buf, dh->dh_db);
+		if (dh->dh_db->db_buf->b_data == NULL) {
+			dbuf_clear(dh->dh_db);
+			if (dh->dh_parent) {
+				dbuf_rele(dh->dh_parent, NULL);
+				dh->dh_parent = NULL;
+			}
+			goto top;
+		}
+		ASSERT3P(dh->dh_db->db.db_data, ==, dh->dh_db->db_buf->b_data);
+	}
+
+	ASSERT(dh->dh_db->db_buf == NULL || arc_referenced(dh->dh_db->db_buf));
+
+	/*
+	 * If this buffer is currently syncing out, and we are are
+	 * still referencing it from db_data, we need to make a copy
+	 * of it in case we decide we want to dirty it again in this txg.
+	 */
+	if (dh->dh_db->db_level == 0 &&
+	    dh->dh_db->db_blkid != DMU_BONUS_BLKID &&
+	    dh->dh_dn->dn_object != DMU_META_DNODE_OBJECT &&
+	    dh->dh_db->db_state == DB_CACHED && dh->dh_db->db_data_pending) {
+		dh->dh_dr = dh->dh_db->db_data_pending;
+
+		if (dh->dh_dr->dt.dl.dr_data == dh->dh_db->db_buf) {
+			dh->dh_type = DBUF_GET_BUFC_TYPE(dh->dh_db);
+
+			dbuf_set_data(dh->dh_db,
+			    arc_buf_alloc(dh->dh_dn->dn_objset->os_spa,
+			    dh->dh_db->db.db_size, dh->dh_db, dh->dh_type));
+			bcopy(dh->dh_dr->dt.dl.dr_data->b_data,
+			    dh->dh_db->db.db_data, dh->dh_db->db.db_size);
+		}
+	}
+
+	(void) refcount_add(&dh->dh_db->db_holds, dh->dh_tag);
+	DBUF_VERIFY(dh->dh_db);
+	mutex_exit(&dh->dh_db->db_mtx);
+
+	/* NOTE: we can't rele the parent until after we drop the db_mtx */
+	if (dh->dh_parent)
+		dbuf_rele(dh->dh_parent, NULL);
+
+	ASSERT3P(DB_DNODE(dh->dh_db), ==, dh->dh_dn);
+	ASSERT3U(dh->dh_db->db_blkid, ==, dh->dh_blkid);
+	ASSERT3U(dh->dh_db->db_level, ==, dh->dh_level);
+	*(dh->dh_dbp) = dh->dh_db;
+
+	return (0);
+}
+
+/*
+ * The following code preserves the recursive function dbuf_hold_impl()
+ * but moves the local variables AND function arguments to the heap to
+ * minimize the stack frame size.  Enough space is initially allocated
+ * on the stack for 20 levels of recursion.
+ */
+int
+dbuf_hold_impl(dnode_t *dn, uint8_t level, uint64_t blkid, int fail_sparse,
+    void *tag, dmu_buf_impl_t **dbp)
+{
+	struct dbuf_hold_impl_data *dh;
+	int error;
+
+	dh = kmem_zalloc(sizeof (struct dbuf_hold_impl_data) *
+	    DBUF_HOLD_IMPL_MAX_DEPTH, KM_SLEEP);
+	__dbuf_hold_impl_init(dh, dn, level, blkid, fail_sparse, tag, dbp, 0);
+
+	error = __dbuf_hold_impl(dh);
+
+	kmem_free(dh, sizeof (struct dbuf_hold_impl_data) *
+	    DBUF_HOLD_IMPL_MAX_DEPTH);
+
+	return (error);
+}
+
+static void
+__dbuf_hold_impl_init(struct dbuf_hold_impl_data *dh,
+    dnode_t *dn, uint8_t level, uint64_t blkid, int fail_sparse,
+    void *tag, dmu_buf_impl_t **dbp, int depth)
+{
+	dh->dh_dn = dn;
+	dh->dh_level = level;
+	dh->dh_blkid = blkid;
+	dh->dh_fail_sparse = fail_sparse;
+	dh->dh_tag = tag;
+	dh->dh_dbp = dbp;
+	dh->dh_depth = depth;
+}
+
+dmu_buf_impl_t *
+dbuf_hold(dnode_t *dn, uint64_t blkid, void *tag)
+{
+	dmu_buf_impl_t *db;
+	int err = dbuf_hold_impl(dn, 0, blkid, FALSE, tag, &db);
+	return (err ? NULL : db);
+}
+
+dmu_buf_impl_t *
+dbuf_hold_level(dnode_t *dn, int level, uint64_t blkid, void *tag)
+{
+	dmu_buf_impl_t *db;
+	int err = dbuf_hold_impl(dn, level, blkid, FALSE, tag, &db);
+	return (err ? NULL : db);
+}
+
+void
+dbuf_create_bonus(dnode_t *dn)
+{
+	ASSERT(RW_WRITE_HELD(&dn->dn_struct_rwlock));
+
+	ASSERT(dn->dn_bonus == NULL);
+	dn->dn_bonus = dbuf_create(dn, 0, DMU_BONUS_BLKID, dn->dn_dbuf, NULL);
+}
+
+int
+dbuf_spill_set_blksz(dmu_buf_t *db_fake, uint64_t blksz, dmu_tx_t *tx)
+{
+	dmu_buf_impl_t *db = (dmu_buf_impl_t *)db_fake;
+	dnode_t *dn;
+
+	if (db->db_blkid != DMU_SPILL_BLKID)
+		return (SET_ERROR(ENOTSUP));
+	if (blksz == 0)
+		blksz = SPA_MINBLOCKSIZE;
+	ASSERT3U(blksz, <=, spa_maxblocksize(dmu_objset_spa(db->db_objset)));
+	blksz = P2ROUNDUP(blksz, SPA_MINBLOCKSIZE);
+
+	DB_DNODE_ENTER(db);
+	dn = DB_DNODE(db);
+	rw_enter(&dn->dn_struct_rwlock, RW_WRITER);
+	dbuf_new_size(db, blksz, tx);
+	rw_exit(&dn->dn_struct_rwlock);
+	DB_DNODE_EXIT(db);
+
+	return (0);
+}
+
+void
+dbuf_rm_spill(dnode_t *dn, dmu_tx_t *tx)
+{
+	dbuf_free_range(dn, DMU_SPILL_BLKID, DMU_SPILL_BLKID, tx);
+}
+
+#pragma weak dmu_buf_add_ref = dbuf_add_ref
+void
+dbuf_add_ref(dmu_buf_impl_t *db, void *tag)
+{
+	VERIFY(refcount_add(&db->db_holds, tag) > 1);
+}
+
+#pragma weak dmu_buf_try_add_ref = dbuf_try_add_ref
+boolean_t
+dbuf_try_add_ref(dmu_buf_t *db_fake, objset_t *os, uint64_t obj, uint64_t blkid,
+    void *tag)
+{
+	dmu_buf_impl_t *db = (dmu_buf_impl_t *)db_fake;
+	dmu_buf_impl_t *found_db;
+	boolean_t result = B_FALSE;
+
+	if (blkid == DMU_BONUS_BLKID)
+		found_db = dbuf_find_bonus(os, obj);
+	else
+		found_db = dbuf_find(os, obj, 0, blkid);
+
+	if (found_db != NULL) {
+		if (db == found_db && dbuf_refcount(db) > db->db_dirtycnt) {
+			(void) refcount_add(&db->db_holds, tag);
+			result = B_TRUE;
+		}
+		mutex_exit(&found_db->db_mtx);
+	}
+	return (result);
+}
+
+/*
+ * If you call dbuf_rele() you had better not be referencing the dnode handle
+ * unless you have some other direct or indirect hold on the dnode. (An indirect
+ * hold is a hold on one of the dnode's dbufs, including the bonus buffer.)
+ * Without that, the dbuf_rele() could lead to a dnode_rele() followed by the
+ * dnode's parent dbuf evicting its dnode handles.
+ */
+void
+dbuf_rele(dmu_buf_impl_t *db, void *tag)
+{
+	mutex_enter(&db->db_mtx);
+	dbuf_rele_and_unlock(db, tag);
+}
+
+void
+dmu_buf_rele(dmu_buf_t *db, void *tag)
+{
+	dbuf_rele((dmu_buf_impl_t *)db, tag);
+}
+
+/*
+ * dbuf_rele() for an already-locked dbuf.  This is necessary to allow
+ * db_dirtycnt and db_holds to be updated atomically.
+ */
+void
+dbuf_rele_and_unlock(dmu_buf_impl_t *db, void *tag)
+{
+	int64_t holds;
+
+	ASSERT(MUTEX_HELD(&db->db_mtx));
+	DBUF_VERIFY(db);
+
+	/*
+	 * Remove the reference to the dbuf before removing its hold on the
+	 * dnode so we can guarantee in dnode_move() that a referenced bonus
+	 * buffer has a corresponding dnode hold.
+	 */
+	holds = refcount_remove(&db->db_holds, tag);
+	ASSERT(holds >= 0);
+
+	/*
+	 * We can't freeze indirects if there is a possibility that they
+	 * may be modified in the current syncing context.
+	 */
+	if (db->db_buf && holds == (db->db_level == 0 ? db->db_dirtycnt : 0))
+		arc_buf_freeze(db->db_buf);
+
+	if (holds == db->db_dirtycnt &&
+	    db->db_level == 0 && db->db_user_immediate_evict)
+		dbuf_evict_user(db);
+
+	if (holds == 0) {
+		if (db->db_blkid == DMU_BONUS_BLKID) {
+			dnode_t *dn;
+			boolean_t evict_dbuf = db->db_pending_evict;
+
+			/*
+			 * If the dnode moves here, we cannot cross this
+			 * barrier until the move completes.
+			 */
+			DB_DNODE_ENTER(db);
+
+			dn = DB_DNODE(db);
+			atomic_dec_32(&dn->dn_dbufs_count);
+
+			/*
+			 * Decrementing the dbuf count means that the bonus
+			 * buffer's dnode hold is no longer discounted in
+			 * dnode_move(). The dnode cannot move until after
+			 * the dnode_rele() below.
+			 */
+			DB_DNODE_EXIT(db);
+
+			/*
+			 * Do not reference db after its lock is dropped.
+			 * Another thread may evict it.
+			 */
+			mutex_exit(&db->db_mtx);
+
+			if (evict_dbuf)
+				dnode_evict_bonus(dn);
+
+			dnode_rele(dn, db);
+		} else if (db->db_buf == NULL) {
+			/*
+			 * This is a special case: we never associated this
+			 * dbuf with any data allocated from the ARC.
+			 */
+			ASSERT(db->db_state == DB_UNCACHED ||
+			    db->db_state == DB_NOFILL);
+			dbuf_evict(db);
+		} else if (arc_released(db->db_buf)) {
+			arc_buf_t *buf = db->db_buf;
+			/*
+			 * This dbuf has anonymous data associated with it.
+			 */
+			dbuf_clear_data(db);
+			VERIFY(arc_buf_remove_ref(buf, db));
+			dbuf_evict(db);
+		} else {
+			VERIFY(!arc_buf_remove_ref(db->db_buf, db));
+
+			/*
+			 * A dbuf will be eligible for eviction if either the
+			 * 'primarycache' property is set or a duplicate
+			 * copy of this buffer is already cached in the arc.
+			 *
+			 * In the case of the 'primarycache' a buffer
+			 * is considered for eviction if it matches the
+			 * criteria set in the property.
+			 *
+			 * To decide if our buffer is considered a
+			 * duplicate, we must call into the arc to determine
+			 * if multiple buffers are referencing the same
+			 * block on-disk. If so, then we simply evict
+			 * ourselves.
+			 */
+			if (!DBUF_IS_CACHEABLE(db)) {
+				if (db->db_blkptr != NULL &&
+				    !BP_IS_HOLE(db->db_blkptr) &&
+				    !BP_IS_EMBEDDED(db->db_blkptr)) {
+					spa_t *spa =
+					    dmu_objset_spa(db->db_objset);
+					blkptr_t bp = *db->db_blkptr;
+					dbuf_clear(db);
+					arc_freed(spa, &bp);
+				} else {
+					dbuf_clear(db);
+				}
+			} else if (db->db_pending_evict ||
+			    arc_buf_eviction_needed(db->db_buf)) {
+				dbuf_clear(db);
+			} else {
+				mutex_exit(&db->db_mtx);
+			}
+		}
+	} else {
+		mutex_exit(&db->db_mtx);
+	}
+}
+
+#pragma weak dmu_buf_refcount = dbuf_refcount
+uint64_t
+dbuf_refcount(dmu_buf_impl_t *db)
+{
+	return (refcount_count(&db->db_holds));
+}
+
+void *
+dmu_buf_replace_user(dmu_buf_t *db_fake, dmu_buf_user_t *old_user,
+    dmu_buf_user_t *new_user)
+{
+	dmu_buf_impl_t *db = (dmu_buf_impl_t *)db_fake;
+
+	mutex_enter(&db->db_mtx);
+	dbuf_verify_user(db, DBVU_NOT_EVICTING);
+	if (db->db_user == old_user)
+		db->db_user = new_user;
+	else
+		old_user = db->db_user;
+	dbuf_verify_user(db, DBVU_NOT_EVICTING);
+	mutex_exit(&db->db_mtx);
+
+	return (old_user);
+}
+
+void *
+dmu_buf_set_user(dmu_buf_t *db_fake, dmu_buf_user_t *user)
+{
+	return (dmu_buf_replace_user(db_fake, NULL, user));
+}
+
+void *
+dmu_buf_set_user_ie(dmu_buf_t *db_fake, dmu_buf_user_t *user)
+{
+	dmu_buf_impl_t *db = (dmu_buf_impl_t *)db_fake;
+
+	db->db_user_immediate_evict = TRUE;
+	return (dmu_buf_set_user(db_fake, user));
+}
+
+void *
+dmu_buf_remove_user(dmu_buf_t *db_fake, dmu_buf_user_t *user)
+{
+	return (dmu_buf_replace_user(db_fake, user, NULL));
+}
+
+void *
+dmu_buf_get_user(dmu_buf_t *db_fake)
+{
+	dmu_buf_impl_t *db = (dmu_buf_impl_t *)db_fake;
+
+	dbuf_verify_user(db, DBVU_NOT_EVICTING);
+	return (db->db_user);
+}
+
+void
+dmu_buf_user_evict_wait()
+{
+	taskq_wait(dbu_evict_taskq);
+}
+
+boolean_t
+dmu_buf_freeable(dmu_buf_t *dbuf)
+{
+	boolean_t res = B_FALSE;
+	dmu_buf_impl_t *db = (dmu_buf_impl_t *)dbuf;
+
+	if (db->db_blkptr)
+		res = dsl_dataset_block_freeable(db->db_objset->os_dsl_dataset,
+		    db->db_blkptr, db->db_blkptr->blk_birth);
+
+	return (res);
+}
+
+blkptr_t *
+dmu_buf_get_blkptr(dmu_buf_t *db)
+{
+	dmu_buf_impl_t *dbi = (dmu_buf_impl_t *)db;
+	return (dbi->db_blkptr);
+}
+
+static void
+dbuf_check_blkptr(dnode_t *dn, dmu_buf_impl_t *db)
+{
+	/* ASSERT(dmu_tx_is_syncing(tx) */
+	ASSERT(MUTEX_HELD(&db->db_mtx));
+
+	if (db->db_blkptr != NULL)
+		return;
+
+	if (db->db_blkid == DMU_SPILL_BLKID) {
+		db->db_blkptr = &dn->dn_phys->dn_spill;
+		BP_ZERO(db->db_blkptr);
+		return;
+	}
+	if (db->db_level == dn->dn_phys->dn_nlevels-1) {
+		/*
+		 * This buffer was allocated at a time when there was
+		 * no available blkptrs from the dnode, or it was
+		 * inappropriate to hook it in (i.e., nlevels mis-match).
+		 */
+		ASSERT(db->db_blkid < dn->dn_phys->dn_nblkptr);
+		ASSERT(db->db_parent == NULL);
+		db->db_parent = dn->dn_dbuf;
+		db->db_blkptr = &dn->dn_phys->dn_blkptr[db->db_blkid];
+		DBUF_VERIFY(db);
+	} else {
+		dmu_buf_impl_t *parent = db->db_parent;
+		int epbs = dn->dn_phys->dn_indblkshift - SPA_BLKPTRSHIFT;
+
+		ASSERT(dn->dn_phys->dn_nlevels > 1);
+		if (parent == NULL) {
+			mutex_exit(&db->db_mtx);
+			rw_enter(&dn->dn_struct_rwlock, RW_READER);
+			(void) dbuf_hold_impl(dn, db->db_level+1,
+			    db->db_blkid >> epbs, FALSE, db, &parent);
+			rw_exit(&dn->dn_struct_rwlock);
+			mutex_enter(&db->db_mtx);
+			db->db_parent = parent;
+		}
+		db->db_blkptr = (blkptr_t *)parent->db.db_data +
+		    (db->db_blkid & ((1ULL << epbs) - 1));
+		DBUF_VERIFY(db);
+	}
+}
+
+/*
+ * dbuf_sync_indirect() is called recursively from dbuf_sync_list() so it
+ * is critical the we not allow the compiler to inline this function in to
+ * dbuf_sync_list() thereby drastically bloating the stack usage.
+ */
+noinline static void
+dbuf_sync_indirect(dbuf_dirty_record_t *dr, dmu_tx_t *tx)
+{
+	dmu_buf_impl_t *db = dr->dr_dbuf;
+	dnode_t *dn;
+	zio_t *zio;
+
+	ASSERT(dmu_tx_is_syncing(tx));
+
+	dprintf_dbuf_bp(db, db->db_blkptr, "blkptr=%p", db->db_blkptr);
+
+	mutex_enter(&db->db_mtx);
+
+	ASSERT(db->db_level > 0);
+	DBUF_VERIFY(db);
+
+	/* Read the block if it hasn't been read yet. */
+	if (db->db_buf == NULL) {
+		mutex_exit(&db->db_mtx);
+		(void) dbuf_read(db, NULL, DB_RF_MUST_SUCCEED);
+		mutex_enter(&db->db_mtx);
+	}
+	ASSERT3U(db->db_state, ==, DB_CACHED);
+	ASSERT(db->db_buf != NULL);
+
+	DB_DNODE_ENTER(db);
+	dn = DB_DNODE(db);
+	/* Indirect block size must match what the dnode thinks it is. */
+	ASSERT3U(db->db.db_size, ==, 1<<dn->dn_phys->dn_indblkshift);
+	dbuf_check_blkptr(dn, db);
+	DB_DNODE_EXIT(db);
+
+	/* Provide the pending dirty record to child dbufs */
+	db->db_data_pending = dr;
+
+	mutex_exit(&db->db_mtx);
+	dbuf_write(dr, db->db_buf, tx);
+
+	zio = dr->dr_zio;
+	mutex_enter(&dr->dt.di.dr_mtx);
+	dbuf_sync_list(&dr->dt.di.dr_children, db->db_level - 1, tx);
+	ASSERT(list_head(&dr->dt.di.dr_children) == NULL);
+	mutex_exit(&dr->dt.di.dr_mtx);
+	zio_nowait(zio);
+}
+
+/*
+ * dbuf_sync_leaf() is called recursively from dbuf_sync_list() so it is
+ * critical the we not allow the compiler to inline this function in to
+ * dbuf_sync_list() thereby drastically bloating the stack usage.
+ */
+noinline static void
+dbuf_sync_leaf(dbuf_dirty_record_t *dr, dmu_tx_t *tx)
+{
+	arc_buf_t **datap = &dr->dt.dl.dr_data;
+	dmu_buf_impl_t *db = dr->dr_dbuf;
+	dnode_t *dn;
+	objset_t *os;
+	uint64_t txg = tx->tx_txg;
+
+	ASSERT(dmu_tx_is_syncing(tx));
+
+	dprintf_dbuf_bp(db, db->db_blkptr, "blkptr=%p", db->db_blkptr);
+
+	mutex_enter(&db->db_mtx);
+	/*
+	 * To be synced, we must be dirtied.  But we
+	 * might have been freed after the dirty.
+	 */
+	if (db->db_state == DB_UNCACHED) {
+		/* This buffer has been freed since it was dirtied */
+		ASSERT(db->db.db_data == NULL);
+	} else if (db->db_state == DB_FILL) {
+		/* This buffer was freed and is now being re-filled */
+		ASSERT(db->db.db_data != dr->dt.dl.dr_data);
+	} else {
+		ASSERT(db->db_state == DB_CACHED || db->db_state == DB_NOFILL);
+	}
+	DBUF_VERIFY(db);
+
+	DB_DNODE_ENTER(db);
+	dn = DB_DNODE(db);
+
+	if (db->db_blkid == DMU_SPILL_BLKID) {
+		mutex_enter(&dn->dn_mtx);
+		dn->dn_phys->dn_flags |= DNODE_FLAG_SPILL_BLKPTR;
+		mutex_exit(&dn->dn_mtx);
+	}
+
+	/*
+	 * If this is a bonus buffer, simply copy the bonus data into the
+	 * dnode.  It will be written out when the dnode is synced (and it
+	 * will be synced, since it must have been dirty for dbuf_sync to
+	 * be called).
+	 */
+	if (db->db_blkid == DMU_BONUS_BLKID) {
+		dbuf_dirty_record_t **drp;
+
+		ASSERT(*datap != NULL);
+		ASSERT0(db->db_level);
+		ASSERT3U(dn->dn_phys->dn_bonuslen, <=, DN_MAX_BONUSLEN);
+		bcopy(*datap, DN_BONUS(dn->dn_phys), dn->dn_phys->dn_bonuslen);
+		DB_DNODE_EXIT(db);
+
+		if (*datap != db->db.db_data) {
+			zio_buf_free(*datap, DN_MAX_BONUSLEN);
+			arc_space_return(DN_MAX_BONUSLEN, ARC_SPACE_OTHER);
+		}
+		db->db_data_pending = NULL;
+		drp = &db->db_last_dirty;
+		while (*drp != dr)
+			drp = &(*drp)->dr_next;
+		ASSERT(dr->dr_next == NULL);
+		ASSERT(dr->dr_dbuf == db);
+		*drp = dr->dr_next;
+		if (dr->dr_dbuf->db_level != 0) {
+			mutex_destroy(&dr->dt.di.dr_mtx);
+			list_destroy(&dr->dt.di.dr_children);
+		}
+		kmem_free(dr, sizeof (dbuf_dirty_record_t));
+		ASSERT(db->db_dirtycnt > 0);
+		db->db_dirtycnt -= 1;
+		dbuf_rele_and_unlock(db, (void *)(uintptr_t)txg);
+		return;
+	}
+
+	os = dn->dn_objset;
+
+	/*
+	 * This function may have dropped the db_mtx lock allowing a dmu_sync
+	 * operation to sneak in. As a result, we need to ensure that we
+	 * don't check the dr_override_state until we have returned from
+	 * dbuf_check_blkptr.
+	 */
+	dbuf_check_blkptr(dn, db);
+
+	/*
+	 * If this buffer is in the middle of an immediate write,
+	 * wait for the synchronous IO to complete.
+	 */
+	while (dr->dt.dl.dr_override_state == DR_IN_DMU_SYNC) {
+		ASSERT(dn->dn_object != DMU_META_DNODE_OBJECT);
+		cv_wait(&db->db_changed, &db->db_mtx);
+		ASSERT(dr->dt.dl.dr_override_state != DR_NOT_OVERRIDDEN);
+	}
+
+	if (db->db_state != DB_NOFILL &&
+	    dn->dn_object != DMU_META_DNODE_OBJECT &&
+	    refcount_count(&db->db_holds) > 1 &&
+	    dr->dt.dl.dr_override_state != DR_OVERRIDDEN &&
+	    *datap == db->db_buf) {
+		/*
+		 * If this buffer is currently "in use" (i.e., there
+		 * are active holds and db_data still references it),
+		 * then make a copy before we start the write so that
+		 * any modifications from the open txg will not leak
+		 * into this write.
+		 *
+		 * NOTE: this copy does not need to be made for
+		 * objects only modified in the syncing context (e.g.
+		 * DNONE_DNODE blocks).
+		 */
+		int blksz = arc_buf_size(*datap);
+		arc_buf_contents_t type = DBUF_GET_BUFC_TYPE(db);
+		*datap = arc_buf_alloc(os->os_spa, blksz, db, type);
+		bcopy(db->db.db_data, (*datap)->b_data, blksz);
+	}
+	db->db_data_pending = dr;
+
+	mutex_exit(&db->db_mtx);
+
+	dbuf_write(dr, *datap, tx);
+
+	ASSERT(!list_link_active(&dr->dr_dirty_node));
+	if (dn->dn_object == DMU_META_DNODE_OBJECT) {
+		list_insert_tail(&dn->dn_dirty_records[txg&TXG_MASK], dr);
+		DB_DNODE_EXIT(db);
+	} else {
+		/*
+		 * Although zio_nowait() does not "wait for an IO", it does
+		 * initiate the IO. If this is an empty write it seems plausible
+		 * that the IO could actually be completed before the nowait
+		 * returns. We need to DB_DNODE_EXIT() first in case
+		 * zio_nowait() invalidates the dbuf.
+		 */
+		DB_DNODE_EXIT(db);
+		zio_nowait(dr->dr_zio);
+	}
+}
+
+void
+dbuf_sync_list(list_t *list, int level, dmu_tx_t *tx)
+{
+	dbuf_dirty_record_t *dr;
+
+	while ((dr = list_head(list))) {
+		if (dr->dr_zio != NULL) {
+			/*
+			 * If we find an already initialized zio then we
+			 * are processing the meta-dnode, and we have finished.
+			 * The dbufs for all dnodes are put back on the list
+			 * during processing, so that we can zio_wait()
+			 * these IOs after initiating all child IOs.
+			 */
+			ASSERT3U(dr->dr_dbuf->db.db_object, ==,
+			    DMU_META_DNODE_OBJECT);
+			break;
+		}
+		if (dr->dr_dbuf->db_blkid != DMU_BONUS_BLKID &&
+		    dr->dr_dbuf->db_blkid != DMU_SPILL_BLKID) {
+			VERIFY3U(dr->dr_dbuf->db_level, ==, level);
+		}
+		list_remove(list, dr);
+		if (dr->dr_dbuf->db_level > 0)
+			dbuf_sync_indirect(dr, tx);
+		else
+			dbuf_sync_leaf(dr, tx);
+	}
+}
+
+/* ARGSUSED */
+static void
+dbuf_write_ready(zio_t *zio, arc_buf_t *buf, void *vdb)
+{
+	dmu_buf_impl_t *db = vdb;
+	dnode_t *dn;
+	blkptr_t *bp = zio->io_bp;
+	blkptr_t *bp_orig = &zio->io_bp_orig;
+	spa_t *spa = zio->io_spa;
+	int64_t delta;
+	uint64_t fill = 0;
+	int i;
+
+	ASSERT3P(db->db_blkptr, ==, bp);
+
+	DB_DNODE_ENTER(db);
+	dn = DB_DNODE(db);
+	delta = bp_get_dsize_sync(spa, bp) - bp_get_dsize_sync(spa, bp_orig);
+	dnode_diduse_space(dn, delta - zio->io_prev_space_delta);
+	zio->io_prev_space_delta = delta;
+
+	if (bp->blk_birth != 0) {
+		ASSERT((db->db_blkid != DMU_SPILL_BLKID &&
+		    BP_GET_TYPE(bp) == dn->dn_type) ||
+		    (db->db_blkid == DMU_SPILL_BLKID &&
+		    BP_GET_TYPE(bp) == dn->dn_bonustype) ||
+		    BP_IS_EMBEDDED(bp));
+		ASSERT(BP_GET_LEVEL(bp) == db->db_level);
+	}
+
+	mutex_enter(&db->db_mtx);
+
+#ifdef ZFS_DEBUG
+	if (db->db_blkid == DMU_SPILL_BLKID) {
+		ASSERT(dn->dn_phys->dn_flags & DNODE_FLAG_SPILL_BLKPTR);
+		ASSERT(!(BP_IS_HOLE(db->db_blkptr)) &&
+		    db->db_blkptr == &dn->dn_phys->dn_spill);
+	}
+#endif
+
+	if (db->db_level == 0) {
+		mutex_enter(&dn->dn_mtx);
+		if (db->db_blkid > dn->dn_phys->dn_maxblkid &&
+		    db->db_blkid != DMU_SPILL_BLKID)
+			dn->dn_phys->dn_maxblkid = db->db_blkid;
+		mutex_exit(&dn->dn_mtx);
+
+		if (dn->dn_type == DMU_OT_DNODE) {
+			dnode_phys_t *dnp = db->db.db_data;
+			for (i = db->db.db_size >> DNODE_SHIFT; i > 0;
+			    i--, dnp++) {
+				if (dnp->dn_type != DMU_OT_NONE)
+					fill++;
+			}
+		} else {
+			if (BP_IS_HOLE(bp)) {
+				fill = 0;
+			} else {
+				fill = 1;
+			}
+		}
+	} else {
+		blkptr_t *ibp = db->db.db_data;
+		ASSERT3U(db->db.db_size, ==, 1<<dn->dn_phys->dn_indblkshift);
+		for (i = db->db.db_size >> SPA_BLKPTRSHIFT; i > 0; i--, ibp++) {
+			if (BP_IS_HOLE(ibp))
+				continue;
+			fill += BP_GET_FILL(ibp);
+		}
+	}
+	DB_DNODE_EXIT(db);
+
+	if (!BP_IS_EMBEDDED(bp))
+		bp->blk_fill = fill;
+
+	mutex_exit(&db->db_mtx);
+}
+
+/*
+ * The SPA will call this callback several times for each zio - once
+ * for every physical child i/o (zio->io_phys_children times).  This
+ * allows the DMU to monitor the progress of each logical i/o.  For example,
+ * there may be 2 copies of an indirect block, or many fragments of a RAID-Z
+ * block.  There may be a long delay before all copies/fragments are completed,
+ * so this callback allows us to retire dirty space gradually, as the physical
+ * i/os complete.
+ */
+/* ARGSUSED */
+static void
+dbuf_write_physdone(zio_t *zio, arc_buf_t *buf, void *arg)
+{
+	dmu_buf_impl_t *db = arg;
+	objset_t *os = db->db_objset;
+	dsl_pool_t *dp = dmu_objset_pool(os);
+	dbuf_dirty_record_t *dr;
+	int delta = 0;
+
+	dr = db->db_data_pending;
+	ASSERT3U(dr->dr_txg, ==, zio->io_txg);
+
+	/*
+	 * The callback will be called io_phys_children times.  Retire one
+	 * portion of our dirty space each time we are called.  Any rounding
+	 * error will be cleaned up by dsl_pool_sync()'s call to
+	 * dsl_pool_undirty_space().
+	 */
+	delta = dr->dr_accounted / zio->io_phys_children;
+	dsl_pool_undirty_space(dp, delta, zio->io_txg);
+}
+
+/* ARGSUSED */
+static void
+dbuf_write_done(zio_t *zio, arc_buf_t *buf, void *vdb)
+{
+	dmu_buf_impl_t *db = vdb;
+	blkptr_t *bp_orig = &zio->io_bp_orig;
+	blkptr_t *bp = db->db_blkptr;
+	objset_t *os = db->db_objset;
+	dmu_tx_t *tx = os->os_synctx;
+	dbuf_dirty_record_t **drp, *dr;
+
+	ASSERT0(zio->io_error);
+	ASSERT(db->db_blkptr == bp);
+
+	/*
+	 * For nopwrites and rewrites we ensure that the bp matches our
+	 * original and bypass all the accounting.
+	 */
+	if (zio->io_flags & (ZIO_FLAG_IO_REWRITE | ZIO_FLAG_NOPWRITE)) {
+		ASSERT(BP_EQUAL(bp, bp_orig));
+	} else {
+		dsl_dataset_t *ds = os->os_dsl_dataset;
+		(void) dsl_dataset_block_kill(ds, bp_orig, tx, B_TRUE);
+		dsl_dataset_block_born(ds, bp, tx);
+	}
+
+	mutex_enter(&db->db_mtx);
+
+	DBUF_VERIFY(db);
+
+	drp = &db->db_last_dirty;
+	while ((dr = *drp) != db->db_data_pending)
+		drp = &dr->dr_next;
+	ASSERT(!list_link_active(&dr->dr_dirty_node));
+	ASSERT(dr->dr_dbuf == db);
+	ASSERT(dr->dr_next == NULL);
+	*drp = dr->dr_next;
+
+#ifdef ZFS_DEBUG
+	if (db->db_blkid == DMU_SPILL_BLKID) {
+		dnode_t *dn;
+
+		DB_DNODE_ENTER(db);
+		dn = DB_DNODE(db);
+		ASSERT(dn->dn_phys->dn_flags & DNODE_FLAG_SPILL_BLKPTR);
+		ASSERT(!(BP_IS_HOLE(db->db_blkptr)) &&
+		    db->db_blkptr == &dn->dn_phys->dn_spill);
+		DB_DNODE_EXIT(db);
+	}
+#endif
+
+	if (db->db_level == 0) {
+		ASSERT(db->db_blkid != DMU_BONUS_BLKID);
+		ASSERT(dr->dt.dl.dr_override_state == DR_NOT_OVERRIDDEN);
+		if (db->db_state != DB_NOFILL) {
+			if (dr->dt.dl.dr_data != db->db_buf)
+				VERIFY(arc_buf_remove_ref(dr->dt.dl.dr_data,
+				    db));
+			else if (!arc_released(db->db_buf))
+				arc_set_callback(db->db_buf, dbuf_do_evict, db);
+		}
+	} else {
+		dnode_t *dn;
+
+		DB_DNODE_ENTER(db);
+		dn = DB_DNODE(db);
+		ASSERT(list_head(&dr->dt.di.dr_children) == NULL);
+		ASSERT3U(db->db.db_size, ==, 1 << dn->dn_phys->dn_indblkshift);
+		if (!BP_IS_HOLE(db->db_blkptr)) {
+			ASSERTV(int epbs = dn->dn_phys->dn_indblkshift -
+			    SPA_BLKPTRSHIFT);
+			ASSERT3U(db->db_blkid, <=,
+			    dn->dn_phys->dn_maxblkid >> (db->db_level * epbs));
+			ASSERT3U(BP_GET_LSIZE(db->db_blkptr), ==,
+			    db->db.db_size);
+			if (!arc_released(db->db_buf))
+				arc_set_callback(db->db_buf, dbuf_do_evict, db);
+		}
+		DB_DNODE_EXIT(db);
+		mutex_destroy(&dr->dt.di.dr_mtx);
+		list_destroy(&dr->dt.di.dr_children);
+	}
+	kmem_free(dr, sizeof (dbuf_dirty_record_t));
+
+	cv_broadcast(&db->db_changed);
+	ASSERT(db->db_dirtycnt > 0);
+	db->db_dirtycnt -= 1;
+	db->db_data_pending = NULL;
+	dbuf_rele_and_unlock(db, (void *)(uintptr_t)tx->tx_txg);
+}
+
+static void
+dbuf_write_nofill_ready(zio_t *zio)
+{
+	dbuf_write_ready(zio, NULL, zio->io_private);
+}
+
+static void
+dbuf_write_nofill_done(zio_t *zio)
+{
+	dbuf_write_done(zio, NULL, zio->io_private);
+}
+
+static void
+dbuf_write_override_ready(zio_t *zio)
+{
+	dbuf_dirty_record_t *dr = zio->io_private;
+	dmu_buf_impl_t *db = dr->dr_dbuf;
+
+	dbuf_write_ready(zio, NULL, db);
+}
+
+static void
+dbuf_write_override_done(zio_t *zio)
+{
+	dbuf_dirty_record_t *dr = zio->io_private;
+	dmu_buf_impl_t *db = dr->dr_dbuf;
+	blkptr_t *obp = &dr->dt.dl.dr_overridden_by;
+
+	mutex_enter(&db->db_mtx);
+	if (!BP_EQUAL(zio->io_bp, obp)) {
+		if (!BP_IS_HOLE(obp))
+			dsl_free(spa_get_dsl(zio->io_spa), zio->io_txg, obp);
+		arc_release(dr->dt.dl.dr_data, db);
+	}
+	mutex_exit(&db->db_mtx);
+
+	dbuf_write_done(zio, NULL, db);
+}
+
+/* Issue I/O to commit a dirty buffer to disk. */
+static void
+dbuf_write(dbuf_dirty_record_t *dr, arc_buf_t *data, dmu_tx_t *tx)
+{
+	dmu_buf_impl_t *db = dr->dr_dbuf;
+	dnode_t *dn;
+	objset_t *os;
+	dmu_buf_impl_t *parent = db->db_parent;
+	uint64_t txg = tx->tx_txg;
+	zbookmark_phys_t zb;
+	zio_prop_t zp;
+	zio_t *zio;
+	int wp_flag = 0;
+
+	DB_DNODE_ENTER(db);
+	dn = DB_DNODE(db);
+	os = dn->dn_objset;
+
+	if (db->db_state != DB_NOFILL) {
+		if (db->db_level > 0 || dn->dn_type == DMU_OT_DNODE) {
+			/*
+			 * Private object buffers are released here rather
+			 * than in dbuf_dirty() since they are only modified
+			 * in the syncing context and we don't want the
+			 * overhead of making multiple copies of the data.
+			 */
+			if (BP_IS_HOLE(db->db_blkptr)) {
+				arc_buf_thaw(data);
+			} else {
+				dbuf_release_bp(db);
+			}
+		}
+	}
+
+	if (parent != dn->dn_dbuf) {
+		/* Our parent is an indirect block. */
+		/* We have a dirty parent that has been scheduled for write. */
+		ASSERT(parent && parent->db_data_pending);
+		/* Our parent's buffer is one level closer to the dnode. */
+		ASSERT(db->db_level == parent->db_level-1);
+		/*
+		 * We're about to modify our parent's db_data by modifying
+		 * our block pointer, so the parent must be released.
+		 */
+		ASSERT(arc_released(parent->db_buf));
+		zio = parent->db_data_pending->dr_zio;
+	} else {
+		/* Our parent is the dnode itself. */
+		ASSERT((db->db_level == dn->dn_phys->dn_nlevels-1 &&
+		    db->db_blkid != DMU_SPILL_BLKID) ||
+		    (db->db_blkid == DMU_SPILL_BLKID && db->db_level == 0));
+		if (db->db_blkid != DMU_SPILL_BLKID)
+			ASSERT3P(db->db_blkptr, ==,
+			    &dn->dn_phys->dn_blkptr[db->db_blkid]);
+		zio = dn->dn_zio;
+	}
+
+	ASSERT(db->db_level == 0 || data == db->db_buf);
+	ASSERT3U(db->db_blkptr->blk_birth, <=, txg);
+	ASSERT(zio);
+
+	SET_BOOKMARK(&zb, os->os_dsl_dataset ?
+	    os->os_dsl_dataset->ds_object : DMU_META_OBJSET,
+	    db->db.db_object, db->db_level, db->db_blkid);
+
+	if (db->db_blkid == DMU_SPILL_BLKID)
+		wp_flag = WP_SPILL;
+	wp_flag |= (db->db_state == DB_NOFILL) ? WP_NOFILL : 0;
+
+	dmu_write_policy(os, dn, db->db_level, wp_flag, &zp);
+	DB_DNODE_EXIT(db);
+
+	if (db->db_level == 0 &&
+	    dr->dt.dl.dr_override_state == DR_OVERRIDDEN) {
+		/*
+		 * The BP for this block has been provided by open context
+		 * (by dmu_sync() or dmu_buf_write_embedded()).
+		 */
+		void *contents = (data != NULL) ? data->b_data : NULL;
+
+		dr->dr_zio = zio_write(zio, os->os_spa, txg,
+		    db->db_blkptr, contents, db->db.db_size, &zp,
+		    dbuf_write_override_ready, NULL, dbuf_write_override_done,
+		    dr, ZIO_PRIORITY_ASYNC_WRITE, ZIO_FLAG_MUSTSUCCEED, &zb);
+		mutex_enter(&db->db_mtx);
+		dr->dt.dl.dr_override_state = DR_NOT_OVERRIDDEN;
+		zio_write_override(dr->dr_zio, &dr->dt.dl.dr_overridden_by,
+		    dr->dt.dl.dr_copies, dr->dt.dl.dr_nopwrite);
+		mutex_exit(&db->db_mtx);
+	} else if (db->db_state == DB_NOFILL) {
+		ASSERT(zp.zp_checksum == ZIO_CHECKSUM_OFF);
+		dr->dr_zio = zio_write(zio, os->os_spa, txg,
+		    db->db_blkptr, NULL, db->db.db_size, &zp,
+		    dbuf_write_nofill_ready, NULL, dbuf_write_nofill_done, db,
+		    ZIO_PRIORITY_ASYNC_WRITE,
+		    ZIO_FLAG_MUSTSUCCEED | ZIO_FLAG_NODATA, &zb);
+	} else {
+		ASSERT(arc_released(data));
+		dr->dr_zio = arc_write(zio, os->os_spa, txg,
+		    db->db_blkptr, data, DBUF_IS_L2CACHEABLE(db),
+		    DBUF_IS_L2COMPRESSIBLE(db), &zp, dbuf_write_ready,
+		    dbuf_write_physdone, dbuf_write_done, db,
+		    ZIO_PRIORITY_ASYNC_WRITE, ZIO_FLAG_MUSTSUCCEED, &zb);
+	}
+}
+
+#if defined(_KERNEL) && defined(HAVE_SPL)
+EXPORT_SYMBOL(dbuf_find);
+EXPORT_SYMBOL(dbuf_is_metadata);
+EXPORT_SYMBOL(dbuf_evict);
+EXPORT_SYMBOL(dbuf_loan_arcbuf);
+EXPORT_SYMBOL(dbuf_whichblock);
+EXPORT_SYMBOL(dbuf_read);
+EXPORT_SYMBOL(dbuf_unoverride);
+EXPORT_SYMBOL(dbuf_free_range);
+EXPORT_SYMBOL(dbuf_new_size);
+EXPORT_SYMBOL(dbuf_release_bp);
+EXPORT_SYMBOL(dbuf_dirty);
+EXPORT_SYMBOL(dmu_buf_will_dirty);
+EXPORT_SYMBOL(dmu_buf_will_not_fill);
+EXPORT_SYMBOL(dmu_buf_will_fill);
+EXPORT_SYMBOL(dmu_buf_fill_done);
+EXPORT_SYMBOL(dmu_buf_rele);
+EXPORT_SYMBOL(dbuf_assign_arcbuf);
+EXPORT_SYMBOL(dbuf_clear);
+EXPORT_SYMBOL(dbuf_prefetch);
+EXPORT_SYMBOL(dbuf_hold_impl);
+EXPORT_SYMBOL(dbuf_hold);
+EXPORT_SYMBOL(dbuf_hold_level);
+EXPORT_SYMBOL(dbuf_create_bonus);
+EXPORT_SYMBOL(dbuf_spill_set_blksz);
+EXPORT_SYMBOL(dbuf_rm_spill);
+EXPORT_SYMBOL(dbuf_add_ref);
+EXPORT_SYMBOL(dbuf_rele);
+EXPORT_SYMBOL(dbuf_rele_and_unlock);
+EXPORT_SYMBOL(dbuf_refcount);
+EXPORT_SYMBOL(dbuf_sync_list);
+EXPORT_SYMBOL(dmu_buf_set_user);
+EXPORT_SYMBOL(dmu_buf_set_user_ie);
+EXPORT_SYMBOL(dmu_buf_get_user);
+EXPORT_SYMBOL(dmu_buf_freeable);
+EXPORT_SYMBOL(dmu_buf_get_blkptr);
+#endif
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/module/zfs/dbuf_stats.c
@@ -0,0 +1,233 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+#include <sys/zfs_context.h>
+#include <sys/dbuf.h>
+#include <sys/dmu_objset.h>
+
+/*
+ * Calculate the index of the arc header for the state, disabled by default.
+ */
+int zfs_dbuf_state_index = 0;
+
+/*
+ * ==========================================================================
+ * Dbuf Hash Read Routines
+ * ==========================================================================
+ */
+typedef struct dbuf_stats_t {
+	kmutex_t		lock;
+	kstat_t			*kstat;
+	dbuf_hash_table_t	*hash;
+	int			idx;
+} dbuf_stats_t;
+
+static dbuf_stats_t dbuf_stats_hash_table;
+
+static int
+dbuf_stats_hash_table_headers(char *buf, size_t size)
+{
+	(void) snprintf(buf, size,
+	    "%-88s | %-124s | %s\n"
+	    "%-16s %-8s %-8s %-8s %-8s %-8s %-8s %-5s %-5s %5s | "
+	    "%-5s %-5s %-8s %-6s %-8s %-12s "
+	    "%-6s %-6s %-6s %-6s %-6s %-8s %-8s %-8s %-5s | "
+	    "%-6s %-6s %-8s %-8s %-6s %-6s %-5s %-8s %-8s\n",
+	    "dbuf", "arcbuf", "dnode", "pool", "objset", "object", "level",
+	    "blkid", "offset", "dbsize", "meta", "state", "dbholds", "list",
+	    "atype", "flags", "count", "asize", "access",
+	    "mru", "gmru", "mfu", "gmfu", "l2", "l2_dattr", "l2_asize",
+	    "l2_comp", "aholds", "dtype", "btype", "data_bs", "meta_bs",
+	    "bsize", "lvls", "dholds", "blocks", "dsize");
+
+	return (0);
+}
+
+int
+__dbuf_stats_hash_table_data(char *buf, size_t size, dmu_buf_impl_t *db)
+{
+	arc_buf_info_t abi = { 0 };
+	dmu_object_info_t doi = { 0 };
+	dnode_t *dn = DB_DNODE(db);
+	size_t nwritten;
+
+	if (db->db_buf)
+		arc_buf_info(db->db_buf, &abi, zfs_dbuf_state_index);
+
+	if (dn)
+		__dmu_object_info_from_dnode(dn, &doi);
+
+	nwritten = snprintf(buf, size,
+	    "%-16s %-8llu %-8lld %-8lld %-8lld %-8llu %-8llu %-5d %-5d %-5lu | "
+	    "%-5d %-5d 0x%-6x %-6lu %-8llu %-12llu "
+	    "%-6lu %-6lu %-6lu %-6lu %-6lu %-8llu %-8llu %-8d %-5lu | "
+	    "%-6d %-6d %-8lu %-8lu %-6llu %-6lu %-5lu %-8llu %-8llu\n",
+	    /* dmu_buf_impl_t */
+	    spa_name(dn->dn_objset->os_spa),
+	    (u_longlong_t)dmu_objset_id(db->db_objset),
+	    (longlong_t)db->db.db_object,
+	    (longlong_t)db->db_level,
+	    (longlong_t)db->db_blkid,
+	    (u_longlong_t)db->db.db_offset,
+	    (u_longlong_t)db->db.db_size,
+	    !!dbuf_is_metadata(db),
+	    db->db_state,
+	    (ulong_t)refcount_count(&db->db_holds),
+	    /* arc_buf_info_t */
+	    abi.abi_state_type,
+	    abi.abi_state_contents,
+	    abi.abi_flags,
+	    (ulong_t)abi.abi_datacnt,
+	    (u_longlong_t)abi.abi_size,
+	    (u_longlong_t)abi.abi_access,
+	    (ulong_t)abi.abi_mru_hits,
+	    (ulong_t)abi.abi_mru_ghost_hits,
+	    (ulong_t)abi.abi_mfu_hits,
+	    (ulong_t)abi.abi_mfu_ghost_hits,
+	    (ulong_t)abi.abi_l2arc_hits,
+	    (u_longlong_t)abi.abi_l2arc_dattr,
+	    (u_longlong_t)abi.abi_l2arc_asize,
+	    abi.abi_l2arc_compress,
+	    (ulong_t)abi.abi_holds,
+	    /* dmu_object_info_t */
+	    doi.doi_type,
+	    doi.doi_bonus_type,
+	    (ulong_t)doi.doi_data_block_size,
+	    (ulong_t)doi.doi_metadata_block_size,
+	    (u_longlong_t)doi.doi_bonus_size,
+	    (ulong_t)doi.doi_indirection,
+	    (ulong_t)refcount_count(&dn->dn_holds),
+	    (u_longlong_t)doi.doi_fill_count,
+	    (u_longlong_t)doi.doi_max_offset);
+
+	if (nwritten >= size)
+		return (size);
+
+	return (nwritten + 1);
+}
+
+static int
+dbuf_stats_hash_table_data(char *buf, size_t size, void *data)
+{
+	dbuf_stats_t *dsh = (dbuf_stats_t *)data;
+	dbuf_hash_table_t *h = dsh->hash;
+	dmu_buf_impl_t *db;
+	int length, error = 0;
+
+	ASSERT3S(dsh->idx, >=, 0);
+	ASSERT3S(dsh->idx, <=, h->hash_table_mask);
+	memset(buf, 0, size);
+
+	mutex_enter(DBUF_HASH_MUTEX(h, dsh->idx));
+	for (db = h->hash_table[dsh->idx]; db != NULL; db = db->db_hash_next) {
+		/*
+		 * Returning ENOMEM will cause the data and header functions
+		 * to be called with a larger scratch buffers.
+		 */
+		if (size < 512) {
+			error = ENOMEM;
+			break;
+		}
+
+		mutex_enter(&db->db_mtx);
+		mutex_exit(DBUF_HASH_MUTEX(h, dsh->idx));
+
+		if (db->db_state != DB_EVICTING) {
+			length = __dbuf_stats_hash_table_data(buf, size, db);
+			buf += length;
+			size -= length;
+		}
+
+		mutex_exit(&db->db_mtx);
+		mutex_enter(DBUF_HASH_MUTEX(h, dsh->idx));
+	}
+	mutex_exit(DBUF_HASH_MUTEX(h, dsh->idx));
+
+	return (error);
+}
+
+static void *
+dbuf_stats_hash_table_addr(kstat_t *ksp, loff_t n)
+{
+	dbuf_stats_t *dsh = ksp->ks_private;
+
+	ASSERT(MUTEX_HELD(&dsh->lock));
+
+	if (n <= dsh->hash->hash_table_mask) {
+		dsh->idx = n;
+		return (dsh);
+	}
+
+	return (NULL);
+}
+
+static void
+dbuf_stats_hash_table_init(dbuf_hash_table_t *hash)
+{
+	dbuf_stats_t *dsh = &dbuf_stats_hash_table;
+	kstat_t *ksp;
+
+	mutex_init(&dsh->lock, NULL, MUTEX_DEFAULT, NULL);
+	dsh->hash = hash;
+
+	ksp = kstat_create("zfs", 0, "dbufs", "misc",
+	    KSTAT_TYPE_RAW, 0, KSTAT_FLAG_VIRTUAL);
+	dsh->kstat = ksp;
+
+	if (ksp) {
+		ksp->ks_lock = &dsh->lock;
+		ksp->ks_ndata = UINT32_MAX;
+		ksp->ks_private = dsh;
+		kstat_set_raw_ops(ksp, dbuf_stats_hash_table_headers,
+		    dbuf_stats_hash_table_data, dbuf_stats_hash_table_addr);
+		kstat_install(ksp);
+	}
+}
+
+static void
+dbuf_stats_hash_table_destroy(void)
+{
+	dbuf_stats_t *dsh = &dbuf_stats_hash_table;
+	kstat_t *ksp;
+
+	ksp = dsh->kstat;
+	if (ksp)
+		kstat_delete(ksp);
+
+	mutex_destroy(&dsh->lock);
+}
+
+void
+dbuf_stats_init(dbuf_hash_table_t *hash)
+{
+	dbuf_stats_hash_table_init(hash);
+}
+
+void
+dbuf_stats_destroy(void)
+{
+	dbuf_stats_hash_table_destroy();
+}
+
+#if defined(_KERNEL) && defined(HAVE_SPL)
+module_param(zfs_dbuf_state_index, int, 0644);
+MODULE_PARM_DESC(zfs_dbuf_state_index, "Calculate arc header index");
+#endif
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/module/zfs/ddt.c
@@ -0,0 +1,1235 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2014 by Delphix. All rights reserved.
+ */
+
+#include <sys/zfs_context.h>
+#include <sys/spa.h>
+#include <sys/spa_impl.h>
+#include <sys/zio.h>
+#include <sys/ddt.h>
+#include <sys/zap.h>
+#include <sys/dmu_tx.h>
+#include <sys/arc.h>
+#include <sys/dsl_pool.h>
+#include <sys/zio_checksum.h>
+#include <sys/zio_compress.h>
+#include <sys/dsl_scan.h>
+
+static kmem_cache_t *ddt_cache;
+static kmem_cache_t *ddt_entry_cache;
+
+/*
+ * Enable/disable prefetching of dedup-ed blocks which are going to be freed.
+ */
+int zfs_dedup_prefetch = 0;
+
+static const ddt_ops_t *ddt_ops[DDT_TYPES] = {
+	&ddt_zap_ops,
+};
+
+static const char *ddt_class_name[DDT_CLASSES] = {
+	"ditto",
+	"duplicate",
+	"unique",
+};
+
+static void
+ddt_object_create(ddt_t *ddt, enum ddt_type type, enum ddt_class class,
+    dmu_tx_t *tx)
+{
+	spa_t *spa = ddt->ddt_spa;
+	objset_t *os = ddt->ddt_os;
+	uint64_t *objectp = &ddt->ddt_object[type][class];
+	boolean_t prehash = zio_checksum_table[ddt->ddt_checksum].ci_dedup;
+	char name[DDT_NAMELEN];
+
+	ddt_object_name(ddt, type, class, name);
+
+	ASSERT(*objectp == 0);
+	VERIFY(ddt_ops[type]->ddt_op_create(os, objectp, tx, prehash) == 0);
+	ASSERT(*objectp != 0);
+
+	VERIFY(zap_add(os, DMU_POOL_DIRECTORY_OBJECT, name,
+	    sizeof (uint64_t), 1, objectp, tx) == 0);
+
+	VERIFY(zap_add(os, spa->spa_ddt_stat_object, name,
+	    sizeof (uint64_t), sizeof (ddt_histogram_t) / sizeof (uint64_t),
+	    &ddt->ddt_histogram[type][class], tx) == 0);
+}
+
+static void
+ddt_object_destroy(ddt_t *ddt, enum ddt_type type, enum ddt_class class,
+    dmu_tx_t *tx)
+{
+	spa_t *spa = ddt->ddt_spa;
+	objset_t *os = ddt->ddt_os;
+	uint64_t *objectp = &ddt->ddt_object[type][class];
+	uint64_t count;
+	char name[DDT_NAMELEN];
+
+	ddt_object_name(ddt, type, class, name);
+
+	ASSERT(*objectp != 0);
+	ASSERT(ddt_histogram_empty(&ddt->ddt_histogram[type][class]));
+	VERIFY(ddt_object_count(ddt, type, class, &count) == 0 && count == 0);
+	VERIFY(zap_remove(os, DMU_POOL_DIRECTORY_OBJECT, name, tx) == 0);
+	VERIFY(zap_remove(os, spa->spa_ddt_stat_object, name, tx) == 0);
+	VERIFY(ddt_ops[type]->ddt_op_destroy(os, *objectp, tx) == 0);
+	bzero(&ddt->ddt_object_stats[type][class], sizeof (ddt_object_t));
+
+	*objectp = 0;
+}
+
+static int
+ddt_object_load(ddt_t *ddt, enum ddt_type type, enum ddt_class class)
+{
+	ddt_object_t *ddo = &ddt->ddt_object_stats[type][class];
+	dmu_object_info_t doi;
+	uint64_t count;
+	char name[DDT_NAMELEN];
+	int error;
+
+	ddt_object_name(ddt, type, class, name);
+
+	error = zap_lookup(ddt->ddt_os, DMU_POOL_DIRECTORY_OBJECT, name,
+	    sizeof (uint64_t), 1, &ddt->ddt_object[type][class]);
+	if (error != 0)
+		return (error);
+
+	error = zap_lookup(ddt->ddt_os, ddt->ddt_spa->spa_ddt_stat_object, name,
+	    sizeof (uint64_t), sizeof (ddt_histogram_t) / sizeof (uint64_t),
+	    &ddt->ddt_histogram[type][class]);
+	if (error != 0)
+		return (error);
+
+	/*
+	 * Seed the cached statistics.
+	 */
+	error = ddt_object_info(ddt, type, class, &doi);
+	if (error)
+		return (error);
+
+	error = ddt_object_count(ddt, type, class, &count);
+	if (error)
+		return (error);
+
+	ddo->ddo_count = count;
+	ddo->ddo_dspace = doi.doi_physical_blocks_512 << 9;
+	ddo->ddo_mspace = doi.doi_fill_count * doi.doi_data_block_size;
+
+	return (0);
+}
+
+static void
+ddt_object_sync(ddt_t *ddt, enum ddt_type type, enum ddt_class class,
+    dmu_tx_t *tx)
+{
+	ddt_object_t *ddo = &ddt->ddt_object_stats[type][class];
+	dmu_object_info_t doi;
+	uint64_t count;
+	char name[DDT_NAMELEN];
+
+	ddt_object_name(ddt, type, class, name);
+
+	VERIFY(zap_update(ddt->ddt_os, ddt->ddt_spa->spa_ddt_stat_object, name,
+	    sizeof (uint64_t), sizeof (ddt_histogram_t) / sizeof (uint64_t),
+	    &ddt->ddt_histogram[type][class], tx) == 0);
+
+	/*
+	 * Cache DDT statistics; this is the only time they'll change.
+	 */
+	VERIFY(ddt_object_info(ddt, type, class, &doi) == 0);
+	VERIFY(ddt_object_count(ddt, type, class, &count) == 0);
+
+	ddo->ddo_count = count;
+	ddo->ddo_dspace = doi.doi_physical_blocks_512 << 9;
+	ddo->ddo_mspace = doi.doi_fill_count * doi.doi_data_block_size;
+}
+
+static int
+ddt_object_lookup(ddt_t *ddt, enum ddt_type type, enum ddt_class class,
+    ddt_entry_t *dde)
+{
+	if (!ddt_object_exists(ddt, type, class))
+		return (SET_ERROR(ENOENT));
+
+	return (ddt_ops[type]->ddt_op_lookup(ddt->ddt_os,
+	    ddt->ddt_object[type][class], dde));
+}
+
+static void
+ddt_object_prefetch(ddt_t *ddt, enum ddt_type type, enum ddt_class class,
+    ddt_entry_t *dde)
+{
+	if (!ddt_object_exists(ddt, type, class))
+		return;
+
+	ddt_ops[type]->ddt_op_prefetch(ddt->ddt_os,
+	    ddt->ddt_object[type][class], dde);
+}
+
+int
+ddt_object_update(ddt_t *ddt, enum ddt_type type, enum ddt_class class,
+    ddt_entry_t *dde, dmu_tx_t *tx)
+{
+	ASSERT(ddt_object_exists(ddt, type, class));
+
+	return (ddt_ops[type]->ddt_op_update(ddt->ddt_os,
+	    ddt->ddt_object[type][class], dde, tx));
+}
+
+static int
+ddt_object_remove(ddt_t *ddt, enum ddt_type type, enum ddt_class class,
+    ddt_entry_t *dde, dmu_tx_t *tx)
+{
+	ASSERT(ddt_object_exists(ddt, type, class));
+
+	return (ddt_ops[type]->ddt_op_remove(ddt->ddt_os,
+	    ddt->ddt_object[type][class], dde, tx));
+}
+
+int
+ddt_object_walk(ddt_t *ddt, enum ddt_type type, enum ddt_class class,
+    uint64_t *walk, ddt_entry_t *dde)
+{
+	ASSERT(ddt_object_exists(ddt, type, class));
+
+	return (ddt_ops[type]->ddt_op_walk(ddt->ddt_os,
+	    ddt->ddt_object[type][class], dde, walk));
+}
+
+int
+ddt_object_count(ddt_t *ddt, enum ddt_type type, enum ddt_class class,
+    uint64_t *count)
+{
+	ASSERT(ddt_object_exists(ddt, type, class));
+
+	return (ddt_ops[type]->ddt_op_count(ddt->ddt_os,
+	    ddt->ddt_object[type][class], count));
+}
+
+int
+ddt_object_info(ddt_t *ddt, enum ddt_type type, enum ddt_class class,
+    dmu_object_info_t *doi)
+{
+	if (!ddt_object_exists(ddt, type, class))
+		return (SET_ERROR(ENOENT));
+
+	return (dmu_object_info(ddt->ddt_os, ddt->ddt_object[type][class],
+	    doi));
+}
+
+boolean_t
+ddt_object_exists(ddt_t *ddt, enum ddt_type type, enum ddt_class class)
+{
+	return (!!ddt->ddt_object[type][class]);
+}
+
+void
+ddt_object_name(ddt_t *ddt, enum ddt_type type, enum ddt_class class,
+    char *name)
+{
+	(void) sprintf(name, DMU_POOL_DDT,
+	    zio_checksum_table[ddt->ddt_checksum].ci_name,
+	    ddt_ops[type]->ddt_op_name, ddt_class_name[class]);
+}
+
+void
+ddt_bp_fill(const ddt_phys_t *ddp, blkptr_t *bp, uint64_t txg)
+{
+	int d;
+	ASSERT(txg != 0);
+
+	for (d = 0; d < SPA_DVAS_PER_BP; d++)
+		bp->blk_dva[d] = ddp->ddp_dva[d];
+	BP_SET_BIRTH(bp, txg, ddp->ddp_phys_birth);
+}
+
+void
+ddt_bp_create(enum zio_checksum checksum,
+    const ddt_key_t *ddk, const ddt_phys_t *ddp, blkptr_t *bp)
+{
+	BP_ZERO(bp);
+
+	if (ddp != NULL)
+		ddt_bp_fill(ddp, bp, ddp->ddp_phys_birth);
+
+	bp->blk_cksum = ddk->ddk_cksum;
+	bp->blk_fill = 1;
+
+	BP_SET_LSIZE(bp, DDK_GET_LSIZE(ddk));
+	BP_SET_PSIZE(bp, DDK_GET_PSIZE(ddk));
+	BP_SET_COMPRESS(bp, DDK_GET_COMPRESS(ddk));
+	BP_SET_CHECKSUM(bp, checksum);
+	BP_SET_TYPE(bp, DMU_OT_DEDUP);
+	BP_SET_LEVEL(bp, 0);
+	BP_SET_DEDUP(bp, 0);
+	BP_SET_BYTEORDER(bp, ZFS_HOST_BYTEORDER);
+}
+
+void
+ddt_key_fill(ddt_key_t *ddk, const blkptr_t *bp)
+{
+	ddk->ddk_cksum = bp->blk_cksum;
+	ddk->ddk_prop = 0;
+
+	DDK_SET_LSIZE(ddk, BP_GET_LSIZE(bp));
+	DDK_SET_PSIZE(ddk, BP_GET_PSIZE(bp));
+	DDK_SET_COMPRESS(ddk, BP_GET_COMPRESS(bp));
+}
+
+void
+ddt_phys_fill(ddt_phys_t *ddp, const blkptr_t *bp)
+{
+	int d;
+	ASSERT(ddp->ddp_phys_birth == 0);
+
+	for (d = 0; d < SPA_DVAS_PER_BP; d++)
+		ddp->ddp_dva[d] = bp->blk_dva[d];
+	ddp->ddp_phys_birth = BP_PHYSICAL_BIRTH(bp);
+}
+
+void
+ddt_phys_clear(ddt_phys_t *ddp)
+{
+	bzero(ddp, sizeof (*ddp));
+}
+
+void
+ddt_phys_addref(ddt_phys_t *ddp)
+{
+	ddp->ddp_refcnt++;
+}
+
+void
+ddt_phys_decref(ddt_phys_t *ddp)
+{
+	if (ddp) {
+		ASSERT(ddp->ddp_refcnt > 0);
+		ddp->ddp_refcnt--;
+	}
+}
+
+void
+ddt_phys_free(ddt_t *ddt, ddt_key_t *ddk, ddt_phys_t *ddp, uint64_t txg)
+{
+	blkptr_t blk;
+
+	ddt_bp_create(ddt->ddt_checksum, ddk, ddp, &blk);
+	ddt_phys_clear(ddp);
+	zio_free(ddt->ddt_spa, txg, &blk);
+}
+
+ddt_phys_t *
+ddt_phys_select(const ddt_entry_t *dde, const blkptr_t *bp)
+{
+	ddt_phys_t *ddp = (ddt_phys_t *)dde->dde_phys;
+	int p;
+
+	for (p = 0; p < DDT_PHYS_TYPES; p++, ddp++) {
+		if (DVA_EQUAL(BP_IDENTITY(bp), &ddp->ddp_dva[0]) &&
+		    BP_PHYSICAL_BIRTH(bp) == ddp->ddp_phys_birth)
+			return (ddp);
+	}
+	return (NULL);
+}
+
+uint64_t
+ddt_phys_total_refcnt(const ddt_entry_t *dde)
+{
+	uint64_t refcnt = 0;
+	int p;
+
+	for (p = DDT_PHYS_SINGLE; p <= DDT_PHYS_TRIPLE; p++)
+		refcnt += dde->dde_phys[p].ddp_refcnt;
+
+	return (refcnt);
+}
+
+static void
+ddt_stat_generate(ddt_t *ddt, ddt_entry_t *dde, ddt_stat_t *dds)
+{
+	spa_t *spa = ddt->ddt_spa;
+	ddt_phys_t *ddp = dde->dde_phys;
+	ddt_key_t *ddk = &dde->dde_key;
+	uint64_t lsize = DDK_GET_LSIZE(ddk);
+	uint64_t psize = DDK_GET_PSIZE(ddk);
+	int p, d;
+
+	bzero(dds, sizeof (*dds));
+
+	for (p = 0; p < DDT_PHYS_TYPES; p++, ddp++) {
+		uint64_t dsize = 0;
+		uint64_t refcnt = ddp->ddp_refcnt;
+
+		if (ddp->ddp_phys_birth == 0)
+			continue;
+
+		for (d = 0; d < SPA_DVAS_PER_BP; d++)
+			dsize += dva_get_dsize_sync(spa, &ddp->ddp_dva[d]);
+
+		dds->dds_blocks += 1;
+		dds->dds_lsize += lsize;
+		dds->dds_psize += psize;
+		dds->dds_dsize += dsize;
+
+		dds->dds_ref_blocks += refcnt;
+		dds->dds_ref_lsize += lsize * refcnt;
+		dds->dds_ref_psize += psize * refcnt;
+		dds->dds_ref_dsize += dsize * refcnt;
+	}
+}
+
+void
+ddt_stat_add(ddt_stat_t *dst, const ddt_stat_t *src, uint64_t neg)
+{
+	const uint64_t *s = (const uint64_t *)src;
+	uint64_t *d = (uint64_t *)dst;
+	uint64_t *d_end = (uint64_t *)(dst + 1);
+
+	ASSERT(neg == 0 || neg == -1ULL);	/* add or subtract */
+
+	while (d < d_end)
+		*d++ += (*s++ ^ neg) - neg;
+}
+
+static void
+ddt_stat_update(ddt_t *ddt, ddt_entry_t *dde, uint64_t neg)
+{
+	ddt_stat_t dds;
+	ddt_histogram_t *ddh;
+	int bucket;
+
+	ddt_stat_generate(ddt, dde, &dds);
+
+	bucket = highbit64(dds.dds_ref_blocks) - 1;
+	ASSERT(bucket >= 0);
+
+	ddh = &ddt->ddt_histogram[dde->dde_type][dde->dde_class];
+
+	ddt_stat_add(&ddh->ddh_stat[bucket], &dds, neg);
+}
+
+void
+ddt_histogram_add(ddt_histogram_t *dst, const ddt_histogram_t *src)
+{
+	int h;
+
+	for (h = 0; h < 64; h++)
+		ddt_stat_add(&dst->ddh_stat[h], &src->ddh_stat[h], 0);
+}
+
+void
+ddt_histogram_stat(ddt_stat_t *dds, const ddt_histogram_t *ddh)
+{
+	int h;
+
+	bzero(dds, sizeof (*dds));
+
+	for (h = 0; h < 64; h++)
+		ddt_stat_add(dds, &ddh->ddh_stat[h], 0);
+}
+
+boolean_t
+ddt_histogram_empty(const ddt_histogram_t *ddh)
+{
+	const uint64_t *s = (const uint64_t *)ddh;
+	const uint64_t *s_end = (const uint64_t *)(ddh + 1);
+
+	while (s < s_end)
+		if (*s++ != 0)
+			return (B_FALSE);
+
+	return (B_TRUE);
+}
+
+void
+ddt_get_dedup_object_stats(spa_t *spa, ddt_object_t *ddo_total)
+{
+	enum zio_checksum c;
+	enum ddt_type type;
+	enum ddt_class class;
+
+	/* Sum the statistics we cached in ddt_object_sync(). */
+	for (c = 0; c < ZIO_CHECKSUM_FUNCTIONS; c++) {
+		ddt_t *ddt = spa->spa_ddt[c];
+		for (type = 0; type < DDT_TYPES; type++) {
+			for (class = 0; class < DDT_CLASSES;
+			    class++) {
+				ddt_object_t *ddo =
+				    &ddt->ddt_object_stats[type][class];
+				ddo_total->ddo_count += ddo->ddo_count;
+				ddo_total->ddo_dspace += ddo->ddo_dspace;
+				ddo_total->ddo_mspace += ddo->ddo_mspace;
+			}
+		}
+	}
+
+	/* ... and compute the averages. */
+	if (ddo_total->ddo_count != 0) {
+		ddo_total->ddo_dspace /= ddo_total->ddo_count;
+		ddo_total->ddo_mspace /= ddo_total->ddo_count;
+	}
+}
+
+void
+ddt_get_dedup_histogram(spa_t *spa, ddt_histogram_t *ddh)
+{
+	enum zio_checksum c;
+	enum ddt_type type;
+	enum ddt_class class;
+
+	for (c = 0; c < ZIO_CHECKSUM_FUNCTIONS; c++) {
+		ddt_t *ddt = spa->spa_ddt[c];
+		for (type = 0; type < DDT_TYPES; type++) {
+			for (class = 0; class < DDT_CLASSES;
+			    class++) {
+				ddt_histogram_add(ddh,
+				    &ddt->ddt_histogram_cache[type][class]);
+			}
+		}
+	}
+}
+
+void
+ddt_get_dedup_stats(spa_t *spa, ddt_stat_t *dds_total)
+{
+	ddt_histogram_t *ddh_total;
+
+	ddh_total = kmem_zalloc(sizeof (ddt_histogram_t), KM_SLEEP);
+	ddt_get_dedup_histogram(spa, ddh_total);
+	ddt_histogram_stat(dds_total, ddh_total);
+	kmem_free(ddh_total, sizeof (ddt_histogram_t));
+}
+
+uint64_t
+ddt_get_dedup_dspace(spa_t *spa)
+{
+	ddt_stat_t dds_total = { 0 };
+
+	ddt_get_dedup_stats(spa, &dds_total);
+	return (dds_total.dds_ref_dsize - dds_total.dds_dsize);
+}
+
+uint64_t
+ddt_get_pool_dedup_ratio(spa_t *spa)
+{
+	ddt_stat_t dds_total = { 0 };
+
+	ddt_get_dedup_stats(spa, &dds_total);
+	if (dds_total.dds_dsize == 0)
+		return (100);
+
+	return (dds_total.dds_ref_dsize * 100 / dds_total.dds_dsize);
+}
+
+int
+ddt_ditto_copies_needed(ddt_t *ddt, ddt_entry_t *dde, ddt_phys_t *ddp_willref)
+{
+	spa_t *spa = ddt->ddt_spa;
+	uint64_t total_refcnt = 0;
+	uint64_t ditto = spa->spa_dedup_ditto;
+	int total_copies = 0;
+	int desired_copies = 0;
+	int p;
+
+	for (p = DDT_PHYS_SINGLE; p <= DDT_PHYS_TRIPLE; p++) {
+		ddt_phys_t *ddp = &dde->dde_phys[p];
+		zio_t *zio = dde->dde_lead_zio[p];
+		uint64_t refcnt = ddp->ddp_refcnt;	/* committed refs */
+		if (zio != NULL)
+			refcnt += zio->io_parent_count;	/* pending refs */
+		if (ddp == ddp_willref)
+			refcnt++;			/* caller's ref */
+		if (refcnt != 0) {
+			total_refcnt += refcnt;
+			total_copies += p;
+		}
+	}
+
+	if (ditto == 0 || ditto > UINT32_MAX)
+		ditto = UINT32_MAX;
+
+	if (total_refcnt >= 1)
+		desired_copies++;
+	if (total_refcnt >= ditto)
+		desired_copies++;
+	if (total_refcnt >= ditto * ditto)
+		desired_copies++;
+
+	return (MAX(desired_copies, total_copies) - total_copies);
+}
+
+int
+ddt_ditto_copies_present(ddt_entry_t *dde)
+{
+	ddt_phys_t *ddp = &dde->dde_phys[DDT_PHYS_DITTO];
+	dva_t *dva = ddp->ddp_dva;
+	int copies = 0 - DVA_GET_GANG(dva);
+	int d;
+
+	for (d = 0; d < SPA_DVAS_PER_BP; d++, dva++)
+		if (DVA_IS_VALID(dva))
+			copies++;
+
+	ASSERT(copies >= 0 && copies < SPA_DVAS_PER_BP);
+
+	return (copies);
+}
+
+size_t
+ddt_compress(void *src, uchar_t *dst, size_t s_len, size_t d_len)
+{
+	uchar_t *version = dst++;
+	int cpfunc = ZIO_COMPRESS_ZLE;
+	zio_compress_info_t *ci = &zio_compress_table[cpfunc];
+	size_t c_len;
+
+	ASSERT(d_len >= s_len + 1);	/* no compression plus version byte */
+
+	c_len = ci->ci_compress(src, dst, s_len, d_len - 1, ci->ci_level);
+
+	if (c_len == s_len) {
+		cpfunc = ZIO_COMPRESS_OFF;
+		bcopy(src, dst, s_len);
+	}
+
+	*version = cpfunc;
+	/* CONSTCOND */
+	if (ZFS_HOST_BYTEORDER)
+		*version |= DDT_COMPRESS_BYTEORDER_MASK;
+
+	return (c_len + 1);
+}
+
+void
+ddt_decompress(uchar_t *src, void *dst, size_t s_len, size_t d_len)
+{
+	uchar_t version = *src++;
+	int cpfunc = version & DDT_COMPRESS_FUNCTION_MASK;
+	zio_compress_info_t *ci = &zio_compress_table[cpfunc];
+
+	if (ci->ci_decompress != NULL)
+		(void) ci->ci_decompress(src, dst, s_len, d_len, ci->ci_level);
+	else
+		bcopy(src, dst, d_len);
+
+	if (((version & DDT_COMPRESS_BYTEORDER_MASK) != 0) !=
+	    (ZFS_HOST_BYTEORDER != 0))
+		byteswap_uint64_array(dst, d_len);
+}
+
+ddt_t *
+ddt_select_by_checksum(spa_t *spa, enum zio_checksum c)
+{
+	return (spa->spa_ddt[c]);
+}
+
+ddt_t *
+ddt_select(spa_t *spa, const blkptr_t *bp)
+{
+	return (spa->spa_ddt[BP_GET_CHECKSUM(bp)]);
+}
+
+void
+ddt_enter(ddt_t *ddt)
+{
+	mutex_enter(&ddt->ddt_lock);
+}
+
+void
+ddt_exit(ddt_t *ddt)
+{
+	mutex_exit(&ddt->ddt_lock);
+}
+
+void
+ddt_init(void)
+{
+	ddt_cache = kmem_cache_create("ddt_cache",
+	    sizeof (ddt_t), 0, NULL, NULL, NULL, NULL, NULL, 0);
+	ddt_entry_cache = kmem_cache_create("ddt_entry_cache",
+	    sizeof (ddt_entry_t), 0, NULL, NULL, NULL, NULL, NULL, 0);
+}
+
+void
+ddt_fini(void)
+{
+	kmem_cache_destroy(ddt_entry_cache);
+	kmem_cache_destroy(ddt_cache);
+}
+
+static ddt_entry_t *
+ddt_alloc(const ddt_key_t *ddk)
+{
+	ddt_entry_t *dde;
+
+	dde = kmem_cache_alloc(ddt_entry_cache, KM_SLEEP);
+	bzero(dde, sizeof (ddt_entry_t));
+	cv_init(&dde->dde_cv, NULL, CV_DEFAULT, NULL);
+
+	dde->dde_key = *ddk;
+
+	return (dde);
+}
+
+static void
+ddt_free(ddt_entry_t *dde)
+{
+	int p;
+
+	ASSERT(!dde->dde_loading);
+
+	for (p = 0; p < DDT_PHYS_TYPES; p++)
+		ASSERT(dde->dde_lead_zio[p] == NULL);
+
+	if (dde->dde_repair_data != NULL)
+		zio_buf_free(dde->dde_repair_data,
+		    DDK_GET_PSIZE(&dde->dde_key));
+
+	cv_destroy(&dde->dde_cv);
+	kmem_cache_free(ddt_entry_cache, dde);
+}
+
+void
+ddt_remove(ddt_t *ddt, ddt_entry_t *dde)
+{
+	ASSERT(MUTEX_HELD(&ddt->ddt_lock));
+
+	avl_remove(&ddt->ddt_tree, dde);
+	ddt_free(dde);
+}
+
+ddt_entry_t *
+ddt_lookup(ddt_t *ddt, const blkptr_t *bp, boolean_t add)
+{
+	ddt_entry_t *dde, dde_search;
+	enum ddt_type type;
+	enum ddt_class class;
+	avl_index_t where;
+	int error;
+
+	ASSERT(MUTEX_HELD(&ddt->ddt_lock));
+
+	ddt_key_fill(&dde_search.dde_key, bp);
+
+	dde = avl_find(&ddt->ddt_tree, &dde_search, &where);
+	if (dde == NULL) {
+		if (!add)
+			return (NULL);
+		dde = ddt_alloc(&dde_search.dde_key);
+		avl_insert(&ddt->ddt_tree, dde, where);
+	}
+
+	while (dde->dde_loading)
+		cv_wait(&dde->dde_cv, &ddt->ddt_lock);
+
+	if (dde->dde_loaded)
+		return (dde);
+
+	dde->dde_loading = B_TRUE;
+
+	ddt_exit(ddt);
+
+	error = ENOENT;
+
+	for (type = 0; type < DDT_TYPES; type++) {
+		for (class = 0; class < DDT_CLASSES; class++) {
+			error = ddt_object_lookup(ddt, type, class, dde);
+			if (error != ENOENT)
+				break;
+		}
+		if (error != ENOENT)
+			break;
+	}
+
+	ASSERT(error == 0 || error == ENOENT);
+
+	ddt_enter(ddt);
+
+	ASSERT(dde->dde_loaded == B_FALSE);
+	ASSERT(dde->dde_loading == B_TRUE);
+
+	dde->dde_type = type;	/* will be DDT_TYPES if no entry found */
+	dde->dde_class = class;	/* will be DDT_CLASSES if no entry found */
+	dde->dde_loaded = B_TRUE;
+	dde->dde_loading = B_FALSE;
+
+	if (error == 0)
+		ddt_stat_update(ddt, dde, -1ULL);
+
+	cv_broadcast(&dde->dde_cv);
+
+	return (dde);
+}
+
+void
+ddt_prefetch(spa_t *spa, const blkptr_t *bp)
+{
+	ddt_t *ddt;
+	ddt_entry_t dde;
+	enum ddt_type type;
+	enum ddt_class class;
+
+	if (!zfs_dedup_prefetch || bp == NULL || !BP_GET_DEDUP(bp))
+		return;
+
+	/*
+	 * We only remove the DDT once all tables are empty and only
+	 * prefetch dedup blocks when there are entries in the DDT.
+	 * Thus no locking is required as the DDT can't disappear on us.
+	 */
+	ddt = ddt_select(spa, bp);
+	ddt_key_fill(&dde.dde_key, bp);
+
+	for (type = 0; type < DDT_TYPES; type++) {
+		for (class = 0; class < DDT_CLASSES; class++) {
+			ddt_object_prefetch(ddt, type, class, &dde);
+		}
+	}
+}
+
+int
+ddt_entry_compare(const void *x1, const void *x2)
+{
+	const ddt_entry_t *dde1 = x1;
+	const ddt_entry_t *dde2 = x2;
+	const uint64_t *u1 = (const uint64_t *)&dde1->dde_key;
+	const uint64_t *u2 = (const uint64_t *)&dde2->dde_key;
+	int i;
+
+	for (i = 0; i < DDT_KEY_WORDS; i++) {
+		if (u1[i] < u2[i])
+			return (-1);
+		if (u1[i] > u2[i])
+			return (1);
+	}
+
+	return (0);
+}
+
+static ddt_t *
+ddt_table_alloc(spa_t *spa, enum zio_checksum c)
+{
+	ddt_t *ddt;
+
+	ddt = kmem_cache_alloc(ddt_cache, KM_SLEEP);
+	bzero(ddt, sizeof (ddt_t));
+
+	mutex_init(&ddt->ddt_lock, NULL, MUTEX_DEFAULT, NULL);
+	avl_create(&ddt->ddt_tree, ddt_entry_compare,
+	    sizeof (ddt_entry_t), offsetof(ddt_entry_t, dde_node));
+	avl_create(&ddt->ddt_repair_tree, ddt_entry_compare,
+	    sizeof (ddt_entry_t), offsetof(ddt_entry_t, dde_node));
+	ddt->ddt_checksum = c;
+	ddt->ddt_spa = spa;
+	ddt->ddt_os = spa->spa_meta_objset;
+
+	return (ddt);
+}
+
+static void
+ddt_table_free(ddt_t *ddt)
+{
+	ASSERT(avl_numnodes(&ddt->ddt_tree) == 0);
+	ASSERT(avl_numnodes(&ddt->ddt_repair_tree) == 0);
+	avl_destroy(&ddt->ddt_tree);
+	avl_destroy(&ddt->ddt_repair_tree);
+	mutex_destroy(&ddt->ddt_lock);
+	kmem_cache_free(ddt_cache, ddt);
+}
+
+void
+ddt_create(spa_t *spa)
+{
+	enum zio_checksum c;
+
+	spa->spa_dedup_checksum = ZIO_DEDUPCHECKSUM;
+
+	for (c = 0; c < ZIO_CHECKSUM_FUNCTIONS; c++)
+		spa->spa_ddt[c] = ddt_table_alloc(spa, c);
+}
+
+int
+ddt_load(spa_t *spa)
+{
+	enum zio_checksum c;
+	enum ddt_type type;
+	enum ddt_class class;
+	int error;
+
+	ddt_create(spa);
+
+	error = zap_lookup(spa->spa_meta_objset, DMU_POOL_DIRECTORY_OBJECT,
+	    DMU_POOL_DDT_STATS, sizeof (uint64_t), 1,
+	    &spa->spa_ddt_stat_object);
+
+	if (error)
+		return (error == ENOENT ? 0 : error);
+
+	for (c = 0; c < ZIO_CHECKSUM_FUNCTIONS; c++) {
+		ddt_t *ddt = spa->spa_ddt[c];
+		for (type = 0; type < DDT_TYPES; type++) {
+			for (class = 0; class < DDT_CLASSES;
+			    class++) {
+				error = ddt_object_load(ddt, type, class);
+				if (error != 0 && error != ENOENT)
+					return (error);
+			}
+		}
+
+		/*
+		 * Seed the cached histograms.
+		 */
+		bcopy(ddt->ddt_histogram, &ddt->ddt_histogram_cache,
+		    sizeof (ddt->ddt_histogram));
+	}
+
+	return (0);
+}
+
+void
+ddt_unload(spa_t *spa)
+{
+	enum zio_checksum c;
+
+	for (c = 0; c < ZIO_CHECKSUM_FUNCTIONS; c++) {
+		if (spa->spa_ddt[c]) {
+			ddt_table_free(spa->spa_ddt[c]);
+			spa->spa_ddt[c] = NULL;
+		}
+	}
+}
+
+boolean_t
+ddt_class_contains(spa_t *spa, enum ddt_class max_class, const blkptr_t *bp)
+{
+	ddt_t *ddt;
+	ddt_entry_t *dde;
+	enum ddt_type type;
+	enum ddt_class class;
+
+	if (!BP_GET_DEDUP(bp))
+		return (B_FALSE);
+
+	if (max_class == DDT_CLASS_UNIQUE)
+		return (B_TRUE);
+
+	ddt = spa->spa_ddt[BP_GET_CHECKSUM(bp)];
+	dde = kmem_cache_alloc(ddt_entry_cache, KM_SLEEP);
+
+	ddt_key_fill(&(dde->dde_key), bp);
+
+	for (type = 0; type < DDT_TYPES; type++) {
+		for (class = 0; class <= max_class; class++) {
+			if (ddt_object_lookup(ddt, type, class, dde) == 0) {
+				kmem_cache_free(ddt_entry_cache, dde);
+				return (B_TRUE);
+			}
+		}
+	}
+
+	kmem_cache_free(ddt_entry_cache, dde);
+	return (B_FALSE);
+}
+
+ddt_entry_t *
+ddt_repair_start(ddt_t *ddt, const blkptr_t *bp)
+{
+	ddt_key_t ddk;
+	ddt_entry_t *dde;
+	enum ddt_type type;
+	enum ddt_class class;
+
+	ddt_key_fill(&ddk, bp);
+
+	dde = ddt_alloc(&ddk);
+
+	for (type = 0; type < DDT_TYPES; type++) {
+		for (class = 0; class < DDT_CLASSES; class++) {
+			/*
+			 * We can only do repair if there are multiple copies
+			 * of the block.  For anything in the UNIQUE class,
+			 * there's definitely only one copy, so don't even try.
+			 */
+			if (class != DDT_CLASS_UNIQUE &&
+			    ddt_object_lookup(ddt, type, class, dde) == 0)
+				return (dde);
+		}
+	}
+
+	bzero(dde->dde_phys, sizeof (dde->dde_phys));
+
+	return (dde);
+}
+
+void
+ddt_repair_done(ddt_t *ddt, ddt_entry_t *dde)
+{
+	avl_index_t where;
+
+	ddt_enter(ddt);
+
+	if (dde->dde_repair_data != NULL && spa_writeable(ddt->ddt_spa) &&
+	    avl_find(&ddt->ddt_repair_tree, dde, &where) == NULL)
+		avl_insert(&ddt->ddt_repair_tree, dde, where);
+	else
+		ddt_free(dde);
+
+	ddt_exit(ddt);
+}
+
+static void
+ddt_repair_entry_done(zio_t *zio)
+{
+	ddt_entry_t *rdde = zio->io_private;
+
+	ddt_free(rdde);
+}
+
+static void
+ddt_repair_entry(ddt_t *ddt, ddt_entry_t *dde, ddt_entry_t *rdde, zio_t *rio)
+{
+	ddt_phys_t *ddp = dde->dde_phys;
+	ddt_phys_t *rddp = rdde->dde_phys;
+	ddt_key_t *ddk = &dde->dde_key;
+	ddt_key_t *rddk = &rdde->dde_key;
+	zio_t *zio;
+	blkptr_t blk;
+	int p;
+
+	zio = zio_null(rio, rio->io_spa, NULL,
+	    ddt_repair_entry_done, rdde, rio->io_flags);
+
+	for (p = 0; p < DDT_PHYS_TYPES; p++, ddp++, rddp++) {
+		if (ddp->ddp_phys_birth == 0 ||
+		    ddp->ddp_phys_birth != rddp->ddp_phys_birth ||
+		    bcmp(ddp->ddp_dva, rddp->ddp_dva, sizeof (ddp->ddp_dva)))
+			continue;
+		ddt_bp_create(ddt->ddt_checksum, ddk, ddp, &blk);
+		zio_nowait(zio_rewrite(zio, zio->io_spa, 0, &blk,
+		    rdde->dde_repair_data, DDK_GET_PSIZE(rddk), NULL, NULL,
+		    ZIO_PRIORITY_SYNC_WRITE, ZIO_DDT_CHILD_FLAGS(zio), NULL));
+	}
+
+	zio_nowait(zio);
+}
+
+static void
+ddt_repair_table(ddt_t *ddt, zio_t *rio)
+{
+	spa_t *spa = ddt->ddt_spa;
+	ddt_entry_t *dde, *rdde_next, *rdde;
+	avl_tree_t *t = &ddt->ddt_repair_tree;
+	blkptr_t blk;
+
+	if (spa_sync_pass(spa) > 1)
+		return;
+
+	ddt_enter(ddt);
+	for (rdde = avl_first(t); rdde != NULL; rdde = rdde_next) {
+		rdde_next = AVL_NEXT(t, rdde);
+		avl_remove(&ddt->ddt_repair_tree, rdde);
+		ddt_exit(ddt);
+		ddt_bp_create(ddt->ddt_checksum, &rdde->dde_key, NULL, &blk);
+		dde = ddt_repair_start(ddt, &blk);
+		ddt_repair_entry(ddt, dde, rdde, rio);
+		ddt_repair_done(ddt, dde);
+		ddt_enter(ddt);
+	}
+	ddt_exit(ddt);
+}
+
+static void
+ddt_sync_entry(ddt_t *ddt, ddt_entry_t *dde, dmu_tx_t *tx, uint64_t txg)
+{
+	dsl_pool_t *dp = ddt->ddt_spa->spa_dsl_pool;
+	ddt_phys_t *ddp = dde->dde_phys;
+	ddt_key_t *ddk = &dde->dde_key;
+	enum ddt_type otype = dde->dde_type;
+	enum ddt_type ntype = DDT_TYPE_CURRENT;
+	enum ddt_class oclass = dde->dde_class;
+	enum ddt_class nclass;
+	uint64_t total_refcnt = 0;
+	int p;
+
+	ASSERT(dde->dde_loaded);
+	ASSERT(!dde->dde_loading);
+
+	for (p = 0; p < DDT_PHYS_TYPES; p++, ddp++) {
+		ASSERT(dde->dde_lead_zio[p] == NULL);
+		if (ddp->ddp_phys_birth == 0) {
+			ASSERT(ddp->ddp_refcnt == 0);
+			continue;
+		}
+		if (p == DDT_PHYS_DITTO) {
+			if (ddt_ditto_copies_needed(ddt, dde, NULL) == 0)
+				ddt_phys_free(ddt, ddk, ddp, txg);
+			continue;
+		}
+		if (ddp->ddp_refcnt == 0)
+			ddt_phys_free(ddt, ddk, ddp, txg);
+		total_refcnt += ddp->ddp_refcnt;
+	}
+
+	if (dde->dde_phys[DDT_PHYS_DITTO].ddp_phys_birth != 0)
+		nclass = DDT_CLASS_DITTO;
+	else if (total_refcnt > 1)
+		nclass = DDT_CLASS_DUPLICATE;
+	else
+		nclass = DDT_CLASS_UNIQUE;
+
+	if (otype != DDT_TYPES &&
+	    (otype != ntype || oclass != nclass || total_refcnt == 0)) {
+		VERIFY(ddt_object_remove(ddt, otype, oclass, dde, tx) == 0);
+		ASSERT(ddt_object_lookup(ddt, otype, oclass, dde) == ENOENT);
+	}
+
+	if (total_refcnt != 0) {
+		dde->dde_type = ntype;
+		dde->dde_class = nclass;
+		ddt_stat_update(ddt, dde, 0);
+		if (!ddt_object_exists(ddt, ntype, nclass))
+			ddt_object_create(ddt, ntype, nclass, tx);
+		VERIFY(ddt_object_update(ddt, ntype, nclass, dde, tx) == 0);
+
+		/*
+		 * If the class changes, the order that we scan this bp
+		 * changes.  If it decreases, we could miss it, so
+		 * scan it right now.  (This covers both class changing
+		 * while we are doing ddt_walk(), and when we are
+		 * traversing.)
+		 */
+		if (nclass < oclass) {
+			dsl_scan_ddt_entry(dp->dp_scan,
+			    ddt->ddt_checksum, dde, tx);
+		}
+	}
+}
+
+static void
+ddt_sync_table(ddt_t *ddt, dmu_tx_t *tx, uint64_t txg)
+{
+	spa_t *spa = ddt->ddt_spa;
+	ddt_entry_t *dde;
+	void *cookie = NULL;
+	enum ddt_type type;
+	enum ddt_class class;
+
+	if (avl_numnodes(&ddt->ddt_tree) == 0)
+		return;
+
+	ASSERT(spa->spa_uberblock.ub_version >= SPA_VERSION_DEDUP);
+
+	if (spa->spa_ddt_stat_object == 0) {
+		spa->spa_ddt_stat_object = zap_create_link(ddt->ddt_os,
+		    DMU_OT_DDT_STATS, DMU_POOL_DIRECTORY_OBJECT,
+		    DMU_POOL_DDT_STATS, tx);
+	}
+
+	while ((dde = avl_destroy_nodes(&ddt->ddt_tree, &cookie)) != NULL) {
+		ddt_sync_entry(ddt, dde, tx, txg);
+		ddt_free(dde);
+	}
+
+	for (type = 0; type < DDT_TYPES; type++) {
+		uint64_t add, count = 0;
+		for (class = 0; class < DDT_CLASSES; class++) {
+			if (ddt_object_exists(ddt, type, class)) {
+				ddt_object_sync(ddt, type, class, tx);
+				VERIFY(ddt_object_count(ddt, type, class,
+				    &add) == 0);
+				count += add;
+			}
+		}
+		for (class = 0; class < DDT_CLASSES; class++) {
+			if (count == 0 && ddt_object_exists(ddt, type, class))
+				ddt_object_destroy(ddt, type, class, tx);
+		}
+	}
+
+	bcopy(ddt->ddt_histogram, &ddt->ddt_histogram_cache,
+	    sizeof (ddt->ddt_histogram));
+}
+
+void
+ddt_sync(spa_t *spa, uint64_t txg)
+{
+	dmu_tx_t *tx;
+	zio_t *rio = zio_root(spa, NULL, NULL,
+	    ZIO_FLAG_CANFAIL | ZIO_FLAG_SPECULATIVE);
+	enum zio_checksum c;
+
+	ASSERT(spa_syncing_txg(spa) == txg);
+
+	tx = dmu_tx_create_assigned(spa->spa_dsl_pool, txg);
+
+	for (c = 0; c < ZIO_CHECKSUM_FUNCTIONS; c++) {
+		ddt_t *ddt = spa->spa_ddt[c];
+		if (ddt == NULL)
+			continue;
+		ddt_sync_table(ddt, tx, txg);
+		ddt_repair_table(ddt, rio);
+	}
+
+	(void) zio_wait(rio);
+
+	dmu_tx_commit(tx);
+}
+
+int
+ddt_walk(spa_t *spa, ddt_bookmark_t *ddb, ddt_entry_t *dde)
+{
+	do {
+		do {
+			do {
+				ddt_t *ddt = spa->spa_ddt[ddb->ddb_checksum];
+				int error = ENOENT;
+				if (ddt_object_exists(ddt, ddb->ddb_type,
+				    ddb->ddb_class)) {
+					error = ddt_object_walk(ddt,
+					    ddb->ddb_type, ddb->ddb_class,
+					    &ddb->ddb_cursor, dde);
+				}
+				dde->dde_type = ddb->ddb_type;
+				dde->dde_class = ddb->ddb_class;
+				if (error == 0)
+					return (0);
+				if (error != ENOENT)
+					return (error);
+				ddb->ddb_cursor = 0;
+			} while (++ddb->ddb_checksum < ZIO_CHECKSUM_FUNCTIONS);
+			ddb->ddb_checksum = 0;
+		} while (++ddb->ddb_type < DDT_TYPES);
+		ddb->ddb_type = 0;
+	} while (++ddb->ddb_class < DDT_CLASSES);
+
+	return (SET_ERROR(ENOENT));
+}
+
+#if defined(_KERNEL) && defined(HAVE_SPL)
+module_param(zfs_dedup_prefetch, int, 0644);
+MODULE_PARM_DESC(zfs_dedup_prefetch, "Enable prefetching dedup-ed blks");
+#endif
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/module/zfs/ddt_zap.c
@@ -0,0 +1,157 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
+ */
+
+#include <sys/zfs_context.h>
+#include <sys/spa.h>
+#include <sys/zio.h>
+#include <sys/ddt.h>
+#include <sys/zap.h>
+#include <sys/dmu_tx.h>
+#include <util/sscanf.h>
+
+int ddt_zap_leaf_blockshift = 12;
+int ddt_zap_indirect_blockshift = 12;
+
+static int
+ddt_zap_create(objset_t *os, uint64_t *objectp, dmu_tx_t *tx, boolean_t prehash)
+{
+	zap_flags_t flags = ZAP_FLAG_HASH64 | ZAP_FLAG_UINT64_KEY;
+
+	if (prehash)
+		flags |= ZAP_FLAG_PRE_HASHED_KEY;
+
+	*objectp = zap_create_flags(os, 0, flags, DMU_OT_DDT_ZAP,
+	    ddt_zap_leaf_blockshift, ddt_zap_indirect_blockshift,
+	    DMU_OT_NONE, 0, tx);
+
+	return (*objectp == 0 ? ENOTSUP : 0);
+}
+
+static int
+ddt_zap_destroy(objset_t *os, uint64_t object, dmu_tx_t *tx)
+{
+	return (zap_destroy(os, object, tx));
+}
+
+static int
+ddt_zap_lookup(objset_t *os, uint64_t object, ddt_entry_t *dde)
+{
+	uchar_t *cbuf;
+	uint64_t one, csize;
+	int error;
+
+	cbuf = kmem_alloc(sizeof (dde->dde_phys) + 1, KM_SLEEP);
+
+	error = zap_length_uint64(os, object, (uint64_t *)&dde->dde_key,
+	    DDT_KEY_WORDS, &one, &csize);
+	if (error)
+		goto out;
+
+	ASSERT(one == 1);
+	ASSERT(csize <= (sizeof (dde->dde_phys) + 1));
+
+	error = zap_lookup_uint64(os, object, (uint64_t *)&dde->dde_key,
+	    DDT_KEY_WORDS, 1, csize, cbuf);
+	if (error)
+		goto out;
+
+	ddt_decompress(cbuf, dde->dde_phys, csize, sizeof (dde->dde_phys));
+out:
+	kmem_free(cbuf, sizeof (dde->dde_phys) + 1);
+
+	return (error);
+}
+
+static void
+ddt_zap_prefetch(objset_t *os, uint64_t object, ddt_entry_t *dde)
+{
+	(void) zap_prefetch_uint64(os, object, (uint64_t *)&dde->dde_key,
+	    DDT_KEY_WORDS);
+}
+
+static int
+ddt_zap_update(objset_t *os, uint64_t object, ddt_entry_t *dde, dmu_tx_t *tx)
+{
+	uchar_t cbuf[sizeof (dde->dde_phys) + 1];
+	uint64_t csize;
+
+	csize = ddt_compress(dde->dde_phys, cbuf,
+	    sizeof (dde->dde_phys), sizeof (cbuf));
+
+	return (zap_update_uint64(os, object, (uint64_t *)&dde->dde_key,
+	    DDT_KEY_WORDS, 1, csize, cbuf, tx));
+}
+
+static int
+ddt_zap_remove(objset_t *os, uint64_t object, ddt_entry_t *dde, dmu_tx_t *tx)
+{
+	return (zap_remove_uint64(os, object, (uint64_t *)&dde->dde_key,
+	    DDT_KEY_WORDS, tx));
+}
+
+static int
+ddt_zap_walk(objset_t *os, uint64_t object, ddt_entry_t *dde, uint64_t *walk)
+{
+	zap_cursor_t zc;
+	zap_attribute_t za;
+	int error;
+
+	zap_cursor_init_serialized(&zc, os, object, *walk);
+	if ((error = zap_cursor_retrieve(&zc, &za)) == 0) {
+		uchar_t cbuf[sizeof (dde->dde_phys) + 1];
+		uint64_t csize = za.za_num_integers;
+		ASSERT(za.za_integer_length == 1);
+		error = zap_lookup_uint64(os, object, (uint64_t *)za.za_name,
+		    DDT_KEY_WORDS, 1, csize, cbuf);
+		ASSERT(error == 0);
+		if (error == 0) {
+			ddt_decompress(cbuf, dde->dde_phys, csize,
+			    sizeof (dde->dde_phys));
+			dde->dde_key = *(ddt_key_t *)za.za_name;
+		}
+		zap_cursor_advance(&zc);
+		*walk = zap_cursor_serialize(&zc);
+	}
+	zap_cursor_fini(&zc);
+	return (error);
+}
+
+static int
+ddt_zap_count(objset_t *os, uint64_t object, uint64_t *count)
+{
+	return (zap_count(os, object, count));
+}
+
+const ddt_ops_t ddt_zap_ops = {
+	"zap",
+	ddt_zap_create,
+	ddt_zap_destroy,
+	ddt_zap_lookup,
+	ddt_zap_prefetch,
+	ddt_zap_update,
+	ddt_zap_remove,
+	ddt_zap_walk,
+	ddt_zap_count,
+};
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/module/zfs/dmu.c
@@ -0,0 +1,2182 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2014 by Delphix. All rights reserved.
+ * Copyright (c) 2013 by Saso Kiselkov. All rights reserved.
+ * Copyright (c) 2014, Nexenta Systems, Inc. All rights reserved.
+ * Copyright (c) 2015 by Chunwei Chen. All rights reserved.
+ */
+
+#include <sys/dmu.h>
+#include <sys/dmu_impl.h>
+#include <sys/dmu_tx.h>
+#include <sys/dbuf.h>
+#include <sys/dnode.h>
+#include <sys/zfs_context.h>
+#include <sys/dmu_objset.h>
+#include <sys/dmu_traverse.h>
+#include <sys/dsl_dataset.h>
+#include <sys/dsl_dir.h>
+#include <sys/dsl_pool.h>
+#include <sys/dsl_synctask.h>
+#include <sys/dsl_prop.h>
+#include <sys/dmu_zfetch.h>
+#include <sys/zfs_ioctl.h>
+#include <sys/zap.h>
+#include <sys/zio_checksum.h>
+#include <sys/zio_compress.h>
+#include <sys/sa.h>
+#include <sys/zfeature.h>
+#ifdef _KERNEL
+#include <sys/vmsystm.h>
+#include <sys/zfs_znode.h>
+#endif
+
+/*
+ * Enable/disable nopwrite feature.
+ */
+int zfs_nopwrite_enabled = 1;
+
+const dmu_object_type_info_t dmu_ot[DMU_OT_NUMTYPES] = {
+	{	DMU_BSWAP_UINT8,	TRUE,	"unallocated"		},
+	{	DMU_BSWAP_ZAP,		TRUE,	"object directory"	},
+	{	DMU_BSWAP_UINT64,	TRUE,	"object array"		},
+	{	DMU_BSWAP_UINT8,	TRUE,	"packed nvlist"		},
+	{	DMU_BSWAP_UINT64,	TRUE,	"packed nvlist size"	},
+	{	DMU_BSWAP_UINT64,	TRUE,	"bpobj"			},
+	{	DMU_BSWAP_UINT64,	TRUE,	"bpobj header"		},
+	{	DMU_BSWAP_UINT64,	TRUE,	"SPA space map header"	},
+	{	DMU_BSWAP_UINT64,	TRUE,	"SPA space map"		},
+	{	DMU_BSWAP_UINT64,	TRUE,	"ZIL intent log"	},
+	{	DMU_BSWAP_DNODE,	TRUE,	"DMU dnode"		},
+	{	DMU_BSWAP_OBJSET,	TRUE,	"DMU objset"		},
+	{	DMU_BSWAP_UINT64,	TRUE,	"DSL directory"		},
+	{	DMU_BSWAP_ZAP,		TRUE,	"DSL directory child map"},
+	{	DMU_BSWAP_ZAP,		TRUE,	"DSL dataset snap map"	},
+	{	DMU_BSWAP_ZAP,		TRUE,	"DSL props"		},
+	{	DMU_BSWAP_UINT64,	TRUE,	"DSL dataset"		},
+	{	DMU_BSWAP_ZNODE,	TRUE,	"ZFS znode"		},
+	{	DMU_BSWAP_OLDACL,	TRUE,	"ZFS V0 ACL"		},
+	{	DMU_BSWAP_UINT8,	FALSE,	"ZFS plain file"	},
+	{	DMU_BSWAP_ZAP,		TRUE,	"ZFS directory"		},
+	{	DMU_BSWAP_ZAP,		TRUE,	"ZFS master node"	},
+	{	DMU_BSWAP_ZAP,		TRUE,	"ZFS delete queue"	},
+	{	DMU_BSWAP_UINT8,	FALSE,	"zvol object"		},
+	{	DMU_BSWAP_ZAP,		TRUE,	"zvol prop"		},
+	{	DMU_BSWAP_UINT8,	FALSE,	"other uint8[]"		},
+	{	DMU_BSWAP_UINT64,	FALSE,	"other uint64[]"	},
+	{	DMU_BSWAP_ZAP,		TRUE,	"other ZAP"		},
+	{	DMU_BSWAP_ZAP,		TRUE,	"persistent error log"	},
+	{	DMU_BSWAP_UINT8,	TRUE,	"SPA history"		},
+	{	DMU_BSWAP_UINT64,	TRUE,	"SPA history offsets"	},
+	{	DMU_BSWAP_ZAP,		TRUE,	"Pool properties"	},
+	{	DMU_BSWAP_ZAP,		TRUE,	"DSL permissions"	},
+	{	DMU_BSWAP_ACL,		TRUE,	"ZFS ACL"		},
+	{	DMU_BSWAP_UINT8,	TRUE,	"ZFS SYSACL"		},
+	{	DMU_BSWAP_UINT8,	TRUE,	"FUID table"		},
+	{	DMU_BSWAP_UINT64,	TRUE,	"FUID table size"	},
+	{	DMU_BSWAP_ZAP,		TRUE,	"DSL dataset next clones"},
+	{	DMU_BSWAP_ZAP,		TRUE,	"scan work queue"	},
+	{	DMU_BSWAP_ZAP,		TRUE,	"ZFS user/group used"	},
+	{	DMU_BSWAP_ZAP,		TRUE,	"ZFS user/group quota"	},
+	{	DMU_BSWAP_ZAP,		TRUE,	"snapshot refcount tags"},
+	{	DMU_BSWAP_ZAP,		TRUE,	"DDT ZAP algorithm"	},
+	{	DMU_BSWAP_ZAP,		TRUE,	"DDT statistics"	},
+	{	DMU_BSWAP_UINT8,	TRUE,	"System attributes"	},
+	{	DMU_BSWAP_ZAP,		TRUE,	"SA master node"	},
+	{	DMU_BSWAP_ZAP,		TRUE,	"SA attr registration"	},
+	{	DMU_BSWAP_ZAP,		TRUE,	"SA attr layouts"	},
+	{	DMU_BSWAP_ZAP,		TRUE,	"scan translations"	},
+	{	DMU_BSWAP_UINT8,	FALSE,	"deduplicated block"	},
+	{	DMU_BSWAP_ZAP,		TRUE,	"DSL deadlist map"	},
+	{	DMU_BSWAP_UINT64,	TRUE,	"DSL deadlist map hdr"	},
+	{	DMU_BSWAP_ZAP,		TRUE,	"DSL dir clones"	},
+	{	DMU_BSWAP_UINT64,	TRUE,	"bpobj subobj"		}
+};
+
+const dmu_object_byteswap_info_t dmu_ot_byteswap[DMU_BSWAP_NUMFUNCS] = {
+	{	byteswap_uint8_array,	"uint8"		},
+	{	byteswap_uint16_array,	"uint16"	},
+	{	byteswap_uint32_array,	"uint32"	},
+	{	byteswap_uint64_array,	"uint64"	},
+	{	zap_byteswap,		"zap"		},
+	{	dnode_buf_byteswap,	"dnode"		},
+	{	dmu_objset_byteswap,	"objset"	},
+	{	zfs_znode_byteswap,	"znode"		},
+	{	zfs_oldacl_byteswap,	"oldacl"	},
+	{	zfs_acl_byteswap,	"acl"		}
+};
+
+int
+dmu_buf_hold_noread(objset_t *os, uint64_t object, uint64_t offset,
+    void *tag, dmu_buf_t **dbp)
+{
+	dnode_t *dn;
+	uint64_t blkid;
+	dmu_buf_impl_t *db;
+	int err;
+
+	err = dnode_hold(os, object, FTAG, &dn);
+	if (err)
+		return (err);
+	blkid = dbuf_whichblock(dn, offset);
+	rw_enter(&dn->dn_struct_rwlock, RW_READER);
+	db = dbuf_hold(dn, blkid, tag);
+	rw_exit(&dn->dn_struct_rwlock);
+	dnode_rele(dn, FTAG);
+
+	if (db == NULL) {
+		*dbp = NULL;
+		return (SET_ERROR(EIO));
+	}
+
+	*dbp = &db->db;
+	return (err);
+}
+
+int
+dmu_buf_hold(objset_t *os, uint64_t object, uint64_t offset,
+    void *tag, dmu_buf_t **dbp, int flags)
+{
+	int err;
+	int db_flags = DB_RF_CANFAIL;
+
+	if (flags & DMU_READ_NO_PREFETCH)
+		db_flags |= DB_RF_NOPREFETCH;
+
+	err = dmu_buf_hold_noread(os, object, offset, tag, dbp);
+	if (err == 0) {
+		dmu_buf_impl_t *db = (dmu_buf_impl_t *)(*dbp);
+		err = dbuf_read(db, NULL, db_flags);
+		if (err != 0) {
+			dbuf_rele(db, tag);
+			*dbp = NULL;
+		}
+	}
+
+	return (err);
+}
+
+int
+dmu_bonus_max(void)
+{
+	return (DN_MAX_BONUSLEN);
+}
+
+int
+dmu_set_bonus(dmu_buf_t *db_fake, int newsize, dmu_tx_t *tx)
+{
+	dmu_buf_impl_t *db = (dmu_buf_impl_t *)db_fake;
+	dnode_t *dn;
+	int error;
+
+	DB_DNODE_ENTER(db);
+	dn = DB_DNODE(db);
+
+	if (dn->dn_bonus != db) {
+		error = SET_ERROR(EINVAL);
+	} else if (newsize < 0 || newsize > db_fake->db_size) {
+		error = SET_ERROR(EINVAL);
+	} else {
+		dnode_setbonuslen(dn, newsize, tx);
+		error = 0;
+	}
+
+	DB_DNODE_EXIT(db);
+	return (error);
+}
+
+int
+dmu_set_bonustype(dmu_buf_t *db_fake, dmu_object_type_t type, dmu_tx_t *tx)
+{
+	dmu_buf_impl_t *db = (dmu_buf_impl_t *)db_fake;
+	dnode_t *dn;
+	int error;
+
+	DB_DNODE_ENTER(db);
+	dn = DB_DNODE(db);
+
+	if (!DMU_OT_IS_VALID(type)) {
+		error = SET_ERROR(EINVAL);
+	} else if (dn->dn_bonus != db) {
+		error = SET_ERROR(EINVAL);
+	} else {
+		dnode_setbonus_type(dn, type, tx);
+		error = 0;
+	}
+
+	DB_DNODE_EXIT(db);
+	return (error);
+}
+
+dmu_object_type_t
+dmu_get_bonustype(dmu_buf_t *db_fake)
+{
+	dmu_buf_impl_t *db = (dmu_buf_impl_t *)db_fake;
+	dnode_t *dn;
+	dmu_object_type_t type;
+
+	DB_DNODE_ENTER(db);
+	dn = DB_DNODE(db);
+	type = dn->dn_bonustype;
+	DB_DNODE_EXIT(db);
+
+	return (type);
+}
+
+int
+dmu_rm_spill(objset_t *os, uint64_t object, dmu_tx_t *tx)
+{
+	dnode_t *dn;
+	int error;
+
+	error = dnode_hold(os, object, FTAG, &dn);
+	dbuf_rm_spill(dn, tx);
+	rw_enter(&dn->dn_struct_rwlock, RW_WRITER);
+	dnode_rm_spill(dn, tx);
+	rw_exit(&dn->dn_struct_rwlock);
+	dnode_rele(dn, FTAG);
+	return (error);
+}
+
+/*
+ * returns ENOENT, EIO, or 0.
+ */
+int
+dmu_bonus_hold(objset_t *os, uint64_t object, void *tag, dmu_buf_t **dbp)
+{
+	dnode_t *dn;
+	dmu_buf_impl_t *db;
+	int error;
+
+	error = dnode_hold(os, object, FTAG, &dn);
+	if (error)
+		return (error);
+
+	rw_enter(&dn->dn_struct_rwlock, RW_READER);
+	if (dn->dn_bonus == NULL) {
+		rw_exit(&dn->dn_struct_rwlock);
+		rw_enter(&dn->dn_struct_rwlock, RW_WRITER);
+		if (dn->dn_bonus == NULL)
+			dbuf_create_bonus(dn);
+	}
+	db = dn->dn_bonus;
+
+	/* as long as the bonus buf is held, the dnode will be held */
+	if (refcount_add(&db->db_holds, tag) == 1) {
+		VERIFY(dnode_add_ref(dn, db));
+		atomic_inc_32(&dn->dn_dbufs_count);
+	}
+
+	/*
+	 * Wait to drop dn_struct_rwlock until after adding the bonus dbuf's
+	 * hold and incrementing the dbuf count to ensure that dnode_move() sees
+	 * a dnode hold for every dbuf.
+	 */
+	rw_exit(&dn->dn_struct_rwlock);
+
+	dnode_rele(dn, FTAG);
+
+	VERIFY(0 == dbuf_read(db, NULL, DB_RF_MUST_SUCCEED | DB_RF_NOPREFETCH));
+
+	*dbp = &db->db;
+	return (0);
+}
+
+/*
+ * returns ENOENT, EIO, or 0.
+ *
+ * This interface will allocate a blank spill dbuf when a spill blk
+ * doesn't already exist on the dnode.
+ *
+ * if you only want to find an already existing spill db, then
+ * dmu_spill_hold_existing() should be used.
+ */
+int
+dmu_spill_hold_by_dnode(dnode_t *dn, uint32_t flags, void *tag, dmu_buf_t **dbp)
+{
+	dmu_buf_impl_t *db = NULL;
+	int err;
+
+	if ((flags & DB_RF_HAVESTRUCT) == 0)
+		rw_enter(&dn->dn_struct_rwlock, RW_READER);
+
+	db = dbuf_hold(dn, DMU_SPILL_BLKID, tag);
+
+	if ((flags & DB_RF_HAVESTRUCT) == 0)
+		rw_exit(&dn->dn_struct_rwlock);
+
+	ASSERT(db != NULL);
+	err = dbuf_read(db, NULL, flags);
+	if (err == 0)
+		*dbp = &db->db;
+	else
+		dbuf_rele(db, tag);
+	return (err);
+}
+
+int
+dmu_spill_hold_existing(dmu_buf_t *bonus, void *tag, dmu_buf_t **dbp)
+{
+	dmu_buf_impl_t *db = (dmu_buf_impl_t *)bonus;
+	dnode_t *dn;
+	int err;
+
+	DB_DNODE_ENTER(db);
+	dn = DB_DNODE(db);
+
+	if (spa_version(dn->dn_objset->os_spa) < SPA_VERSION_SA) {
+		err = SET_ERROR(EINVAL);
+	} else {
+		rw_enter(&dn->dn_struct_rwlock, RW_READER);
+
+		if (!dn->dn_have_spill) {
+			err = SET_ERROR(ENOENT);
+		} else {
+			err = dmu_spill_hold_by_dnode(dn,
+			    DB_RF_HAVESTRUCT | DB_RF_CANFAIL, tag, dbp);
+		}
+
+		rw_exit(&dn->dn_struct_rwlock);
+	}
+
+	DB_DNODE_EXIT(db);
+	return (err);
+}
+
+int
+dmu_spill_hold_by_bonus(dmu_buf_t *bonus, void *tag, dmu_buf_t **dbp)
+{
+	dmu_buf_impl_t *db = (dmu_buf_impl_t *)bonus;
+	dnode_t *dn;
+	int err;
+
+	DB_DNODE_ENTER(db);
+	dn = DB_DNODE(db);
+	err = dmu_spill_hold_by_dnode(dn, DB_RF_CANFAIL, tag, dbp);
+	DB_DNODE_EXIT(db);
+
+	return (err);
+}
+
+/*
+ * Note: longer-term, we should modify all of the dmu_buf_*() interfaces
+ * to take a held dnode rather than <os, object> -- the lookup is wasteful,
+ * and can induce severe lock contention when writing to several files
+ * whose dnodes are in the same block.
+ */
+static int
+dmu_buf_hold_array_by_dnode(dnode_t *dn, uint64_t offset, uint64_t length,
+    int read, void *tag, int *numbufsp, dmu_buf_t ***dbpp, uint32_t flags)
+{
+	dmu_buf_t **dbp;
+	uint64_t blkid, nblks, i;
+	uint32_t dbuf_flags;
+	int err;
+	zio_t *zio;
+
+	ASSERT(length <= DMU_MAX_ACCESS);
+
+	dbuf_flags = DB_RF_CANFAIL | DB_RF_NEVERWAIT | DB_RF_HAVESTRUCT;
+	if (flags & DMU_READ_NO_PREFETCH || length > zfetch_array_rd_sz)
+		dbuf_flags |= DB_RF_NOPREFETCH;
+
+	rw_enter(&dn->dn_struct_rwlock, RW_READER);
+	if (dn->dn_datablkshift) {
+		int blkshift = dn->dn_datablkshift;
+		nblks = (P2ROUNDUP(offset+length, 1ULL<<blkshift) -
+		    P2ALIGN(offset, 1ULL<<blkshift)) >> blkshift;
+	} else {
+		if (offset + length > dn->dn_datablksz) {
+			zfs_panic_recover("zfs: accessing past end of object "
+			    "%llx/%llx (size=%u access=%llu+%llu)",
+			    (longlong_t)dn->dn_objset->
+			    os_dsl_dataset->ds_object,
+			    (longlong_t)dn->dn_object, dn->dn_datablksz,
+			    (longlong_t)offset, (longlong_t)length);
+			rw_exit(&dn->dn_struct_rwlock);
+			return (SET_ERROR(EIO));
+		}
+		nblks = 1;
+	}
+	dbp = kmem_zalloc(sizeof (dmu_buf_t *) * nblks, KM_SLEEP);
+
+	zio = zio_root(dn->dn_objset->os_spa, NULL, NULL, ZIO_FLAG_CANFAIL);
+	blkid = dbuf_whichblock(dn, offset);
+	for (i = 0; i < nblks; i++) {
+		dmu_buf_impl_t *db = dbuf_hold(dn, blkid+i, tag);
+		if (db == NULL) {
+			rw_exit(&dn->dn_struct_rwlock);
+			dmu_buf_rele_array(dbp, nblks, tag);
+			zio_nowait(zio);
+			return (SET_ERROR(EIO));
+		}
+		/* initiate async i/o */
+		if (read) {
+			(void) dbuf_read(db, zio, dbuf_flags);
+		}
+		dbp[i] = &db->db;
+	}
+	rw_exit(&dn->dn_struct_rwlock);
+
+	/* wait for async i/o */
+	err = zio_wait(zio);
+	if (err) {
+		dmu_buf_rele_array(dbp, nblks, tag);
+		return (err);
+	}
+
+	/* wait for other io to complete */
+	if (read) {
+		for (i = 0; i < nblks; i++) {
+			dmu_buf_impl_t *db = (dmu_buf_impl_t *)dbp[i];
+			mutex_enter(&db->db_mtx);
+			while (db->db_state == DB_READ ||
+			    db->db_state == DB_FILL)
+				cv_wait(&db->db_changed, &db->db_mtx);
+			if (db->db_state == DB_UNCACHED)
+				err = SET_ERROR(EIO);
+			mutex_exit(&db->db_mtx);
+			if (err) {
+				dmu_buf_rele_array(dbp, nblks, tag);
+				return (err);
+			}
+		}
+	}
+
+	*numbufsp = nblks;
+	*dbpp = dbp;
+	return (0);
+}
+
+static int
+dmu_buf_hold_array(objset_t *os, uint64_t object, uint64_t offset,
+    uint64_t length, int read, void *tag, int *numbufsp, dmu_buf_t ***dbpp)
+{
+	dnode_t *dn;
+	int err;
+
+	err = dnode_hold(os, object, FTAG, &dn);
+	if (err)
+		return (err);
+
+	err = dmu_buf_hold_array_by_dnode(dn, offset, length, read, tag,
+	    numbufsp, dbpp, DMU_READ_PREFETCH);
+
+	dnode_rele(dn, FTAG);
+
+	return (err);
+}
+
+int
+dmu_buf_hold_array_by_bonus(dmu_buf_t *db_fake, uint64_t offset,
+    uint64_t length, int read, void *tag, int *numbufsp, dmu_buf_t ***dbpp)
+{
+	dmu_buf_impl_t *db = (dmu_buf_impl_t *)db_fake;
+	dnode_t *dn;
+	int err;
+
+	DB_DNODE_ENTER(db);
+	dn = DB_DNODE(db);
+	err = dmu_buf_hold_array_by_dnode(dn, offset, length, read, tag,
+	    numbufsp, dbpp, DMU_READ_PREFETCH);
+	DB_DNODE_EXIT(db);
+
+	return (err);
+}
+
+void
+dmu_buf_rele_array(dmu_buf_t **dbp_fake, int numbufs, void *tag)
+{
+	int i;
+	dmu_buf_impl_t **dbp = (dmu_buf_impl_t **)dbp_fake;
+
+	if (numbufs == 0)
+		return;
+
+	for (i = 0; i < numbufs; i++) {
+		if (dbp[i])
+			dbuf_rele(dbp[i], tag);
+	}
+
+	kmem_free(dbp, sizeof (dmu_buf_t *) * numbufs);
+}
+
+/*
+ * Issue prefetch i/os for the given blocks.
+ *
+ * Note: The assumption is that we *know* these blocks will be needed
+ * almost immediately.  Therefore, the prefetch i/os will be issued at
+ * ZIO_PRIORITY_SYNC_READ
+ *
+ * Note: indirect blocks and other metadata will be read synchronously,
+ * causing this function to block if they are not already cached.
+ */
+void
+dmu_prefetch(objset_t *os, uint64_t object, uint64_t offset, uint64_t len)
+{
+	dnode_t *dn;
+	uint64_t blkid;
+	int nblks, err;
+
+	if (zfs_prefetch_disable)
+		return;
+
+	if (len == 0) {  /* they're interested in the bonus buffer */
+		dn = DMU_META_DNODE(os);
+
+		if (object == 0 || object >= DN_MAX_OBJECT)
+			return;
+
+		rw_enter(&dn->dn_struct_rwlock, RW_READER);
+		blkid = dbuf_whichblock(dn, object * sizeof (dnode_phys_t));
+		dbuf_prefetch(dn, blkid, ZIO_PRIORITY_SYNC_READ);
+		rw_exit(&dn->dn_struct_rwlock);
+		return;
+	}
+
+	/*
+	 * XXX - Note, if the dnode for the requested object is not
+	 * already cached, we will do a *synchronous* read in the
+	 * dnode_hold() call.  The same is true for any indirects.
+	 */
+	err = dnode_hold(os, object, FTAG, &dn);
+	if (err != 0)
+		return;
+
+	rw_enter(&dn->dn_struct_rwlock, RW_READER);
+	if (dn->dn_datablkshift) {
+		int blkshift = dn->dn_datablkshift;
+		nblks = (P2ROUNDUP(offset + len, 1 << blkshift) -
+		    P2ALIGN(offset, 1 << blkshift)) >> blkshift;
+	} else {
+		nblks = (offset < dn->dn_datablksz);
+	}
+
+	if (nblks != 0) {
+		int i;
+
+		blkid = dbuf_whichblock(dn, offset);
+		for (i = 0; i < nblks; i++)
+			dbuf_prefetch(dn, blkid + i, ZIO_PRIORITY_SYNC_READ);
+	}
+
+	rw_exit(&dn->dn_struct_rwlock);
+
+	dnode_rele(dn, FTAG);
+}
+
+/*
+ * Get the next "chunk" of file data to free.  We traverse the file from
+ * the end so that the file gets shorter over time (if we crashes in the
+ * middle, this will leave us in a better state).  We find allocated file
+ * data by simply searching the allocated level 1 indirects.
+ *
+ * On input, *start should be the first offset that does not need to be
+ * freed (e.g. "offset + length").  On return, *start will be the first
+ * offset that should be freed.
+ */
+static int
+get_next_chunk(dnode_t *dn, uint64_t *start, uint64_t minimum)
+{
+	uint64_t maxblks = DMU_MAX_ACCESS >> (dn->dn_indblkshift + 1);
+	/* bytes of data covered by a level-1 indirect block */
+	uint64_t iblkrange =
+	    dn->dn_datablksz * EPB(dn->dn_indblkshift, SPA_BLKPTRSHIFT);
+	uint64_t blks;
+
+	ASSERT3U(minimum, <=, *start);
+
+	if (*start - minimum <= iblkrange * maxblks) {
+		*start = minimum;
+		return (0);
+	}
+	ASSERT(ISP2(iblkrange));
+
+	for (blks = 0; *start > minimum && blks < maxblks; blks++) {
+		int err;
+
+		/*
+		 * dnode_next_offset(BACKWARDS) will find an allocated L1
+		 * indirect block at or before the input offset.  We must
+		 * decrement *start so that it is at the end of the region
+		 * to search.
+		 */
+		(*start)--;
+		err = dnode_next_offset(dn,
+		    DNODE_FIND_BACKWARDS, start, 2, 1, 0);
+
+		/* if there are no indirect blocks before start, we are done */
+		if (err == ESRCH) {
+			*start = minimum;
+			break;
+		} else if (err != 0) {
+			return (err);
+		}
+
+		/* set start to the beginning of this L1 indirect */
+		*start = P2ALIGN(*start, iblkrange);
+	}
+	if (*start < minimum)
+		*start = minimum;
+	return (0);
+}
+
+static int
+dmu_free_long_range_impl(objset_t *os, dnode_t *dn, uint64_t offset,
+    uint64_t length)
+{
+	uint64_t object_size;
+	int err;
+
+	if (dn == NULL)
+		return (SET_ERROR(EINVAL));
+
+	object_size = (dn->dn_maxblkid + 1) * dn->dn_datablksz;
+	if (offset >= object_size)
+		return (0);
+
+	if (length == DMU_OBJECT_END || offset + length > object_size)
+		length = object_size - offset;
+
+	while (length != 0) {
+		uint64_t chunk_end, chunk_begin;
+		dmu_tx_t *tx;
+
+		chunk_end = chunk_begin = offset + length;
+
+		/* move chunk_begin backwards to the beginning of this chunk */
+		err = get_next_chunk(dn, &chunk_begin, offset);
+		if (err)
+			return (err);
+		ASSERT3U(chunk_begin, >=, offset);
+		ASSERT3U(chunk_begin, <=, chunk_end);
+
+		tx = dmu_tx_create(os);
+		dmu_tx_hold_free(tx, dn->dn_object,
+		    chunk_begin, chunk_end - chunk_begin);
+		err = dmu_tx_assign(tx, TXG_WAIT);
+		if (err) {
+			dmu_tx_abort(tx);
+			return (err);
+		}
+		dnode_free_range(dn, chunk_begin, chunk_end - chunk_begin, tx);
+		dmu_tx_commit(tx);
+
+		length -= chunk_end - chunk_begin;
+	}
+	return (0);
+}
+
+int
+dmu_free_long_range(objset_t *os, uint64_t object,
+    uint64_t offset, uint64_t length)
+{
+	dnode_t *dn;
+	int err;
+
+	err = dnode_hold(os, object, FTAG, &dn);
+	if (err != 0)
+		return (err);
+	err = dmu_free_long_range_impl(os, dn, offset, length);
+
+	/*
+	 * It is important to zero out the maxblkid when freeing the entire
+	 * file, so that (a) subsequent calls to dmu_free_long_range_impl()
+	 * will take the fast path, and (b) dnode_reallocate() can verify
+	 * that the entire file has been freed.
+	 */
+	if (err == 0 && offset == 0 && length == DMU_OBJECT_END)
+		dn->dn_maxblkid = 0;
+
+	dnode_rele(dn, FTAG);
+	return (err);
+}
+
+int
+dmu_free_long_object(objset_t *os, uint64_t object)
+{
+	dmu_tx_t *tx;
+	int err;
+
+	err = dmu_free_long_range(os, object, 0, DMU_OBJECT_END);
+	if (err != 0)
+		return (err);
+
+	tx = dmu_tx_create(os);
+	dmu_tx_hold_bonus(tx, object);
+	dmu_tx_hold_free(tx, object, 0, DMU_OBJECT_END);
+	err = dmu_tx_assign(tx, TXG_WAIT);
+	if (err == 0) {
+		err = dmu_object_free(os, object, tx);
+		dmu_tx_commit(tx);
+	} else {
+		dmu_tx_abort(tx);
+	}
+
+	return (err);
+}
+
+int
+dmu_free_range(objset_t *os, uint64_t object, uint64_t offset,
+    uint64_t size, dmu_tx_t *tx)
+{
+	dnode_t *dn;
+	int err = dnode_hold(os, object, FTAG, &dn);
+	if (err)
+		return (err);
+	ASSERT(offset < UINT64_MAX);
+	ASSERT(size == -1ULL || size <= UINT64_MAX - offset);
+	dnode_free_range(dn, offset, size, tx);
+	dnode_rele(dn, FTAG);
+	return (0);
+}
+
+int
+dmu_read(objset_t *os, uint64_t object, uint64_t offset, uint64_t size,
+    void *buf, uint32_t flags)
+{
+	dnode_t *dn;
+	dmu_buf_t **dbp;
+	int numbufs, err;
+
+	err = dnode_hold(os, object, FTAG, &dn);
+	if (err)
+		return (err);
+
+	/*
+	 * Deal with odd block sizes, where there can't be data past the first
+	 * block.  If we ever do the tail block optimization, we will need to
+	 * handle that here as well.
+	 */
+	if (dn->dn_maxblkid == 0) {
+		uint64_t newsz = offset > dn->dn_datablksz ? 0 :
+		    MIN(size, dn->dn_datablksz - offset);
+		bzero((char *)buf + newsz, size - newsz);
+		size = newsz;
+	}
+
+	while (size > 0) {
+		uint64_t mylen = MIN(size, DMU_MAX_ACCESS / 2);
+		int i;
+
+		/*
+		 * NB: we could do this block-at-a-time, but it's nice
+		 * to be reading in parallel.
+		 */
+		err = dmu_buf_hold_array_by_dnode(dn, offset, mylen,
+		    TRUE, FTAG, &numbufs, &dbp, flags);
+		if (err)
+			break;
+
+		for (i = 0; i < numbufs; i++) {
+			uint64_t tocpy;
+			int64_t bufoff;
+			dmu_buf_t *db = dbp[i];
+
+			ASSERT(size > 0);
+
+			bufoff = offset - db->db_offset;
+			tocpy = MIN(db->db_size - bufoff, size);
+
+			(void) memcpy(buf, (char *)db->db_data + bufoff, tocpy);
+
+			offset += tocpy;
+			size -= tocpy;
+			buf = (char *)buf + tocpy;
+		}
+		dmu_buf_rele_array(dbp, numbufs, FTAG);
+	}
+	dnode_rele(dn, FTAG);
+	return (err);
+}
+
+void
+dmu_write(objset_t *os, uint64_t object, uint64_t offset, uint64_t size,
+    const void *buf, dmu_tx_t *tx)
+{
+	dmu_buf_t **dbp;
+	int numbufs, i;
+
+	if (size == 0)
+		return;
+
+	VERIFY0(dmu_buf_hold_array(os, object, offset, size,
+	    FALSE, FTAG, &numbufs, &dbp));
+
+	for (i = 0; i < numbufs; i++) {
+		uint64_t tocpy;
+		int64_t bufoff;
+		dmu_buf_t *db = dbp[i];
+
+		ASSERT(size > 0);
+
+		bufoff = offset - db->db_offset;
+		tocpy = MIN(db->db_size - bufoff, size);
+
+		ASSERT(i == 0 || i == numbufs-1 || tocpy == db->db_size);
+
+		if (tocpy == db->db_size)
+			dmu_buf_will_fill(db, tx);
+		else
+			dmu_buf_will_dirty(db, tx);
+
+		(void) memcpy((char *)db->db_data + bufoff, buf, tocpy);
+
+		if (tocpy == db->db_size)
+			dmu_buf_fill_done(db, tx);
+
+		offset += tocpy;
+		size -= tocpy;
+		buf = (char *)buf + tocpy;
+	}
+	dmu_buf_rele_array(dbp, numbufs, FTAG);
+}
+
+void
+dmu_prealloc(objset_t *os, uint64_t object, uint64_t offset, uint64_t size,
+    dmu_tx_t *tx)
+{
+	dmu_buf_t **dbp;
+	int numbufs, i;
+
+	if (size == 0)
+		return;
+
+	VERIFY(0 == dmu_buf_hold_array(os, object, offset, size,
+	    FALSE, FTAG, &numbufs, &dbp));
+
+	for (i = 0; i < numbufs; i++) {
+		dmu_buf_t *db = dbp[i];
+
+		dmu_buf_will_not_fill(db, tx);
+	}
+	dmu_buf_rele_array(dbp, numbufs, FTAG);
+}
+
+void
+dmu_write_embedded(objset_t *os, uint64_t object, uint64_t offset,
+    void *data, uint8_t etype, uint8_t comp, int uncompressed_size,
+    int compressed_size, int byteorder, dmu_tx_t *tx)
+{
+	dmu_buf_t *db;
+
+	ASSERT3U(etype, <, NUM_BP_EMBEDDED_TYPES);
+	ASSERT3U(comp, <, ZIO_COMPRESS_FUNCTIONS);
+	VERIFY0(dmu_buf_hold_noread(os, object, offset,
+	    FTAG, &db));
+
+	dmu_buf_write_embedded(db,
+	    data, (bp_embedded_type_t)etype, (enum zio_compress)comp,
+	    uncompressed_size, compressed_size, byteorder, tx);
+
+	dmu_buf_rele(db, FTAG);
+}
+
+/*
+ * DMU support for xuio
+ */
+kstat_t *xuio_ksp = NULL;
+
+typedef struct xuio_stats {
+	/* loaned yet not returned arc_buf */
+	kstat_named_t xuiostat_onloan_rbuf;
+	kstat_named_t xuiostat_onloan_wbuf;
+	/* whether a copy is made when loaning out a read buffer */
+	kstat_named_t xuiostat_rbuf_copied;
+	kstat_named_t xuiostat_rbuf_nocopy;
+	/* whether a copy is made when assigning a write buffer */
+	kstat_named_t xuiostat_wbuf_copied;
+	kstat_named_t xuiostat_wbuf_nocopy;
+} xuio_stats_t;
+
+static xuio_stats_t xuio_stats = {
+	{ "onloan_read_buf",	KSTAT_DATA_UINT64 },
+	{ "onloan_write_buf",	KSTAT_DATA_UINT64 },
+	{ "read_buf_copied",	KSTAT_DATA_UINT64 },
+	{ "read_buf_nocopy",	KSTAT_DATA_UINT64 },
+	{ "write_buf_copied",	KSTAT_DATA_UINT64 },
+	{ "write_buf_nocopy",	KSTAT_DATA_UINT64 }
+};
+
+#define	XUIOSTAT_INCR(stat, val)        \
+	atomic_add_64(&xuio_stats.stat.value.ui64, (val))
+#define	XUIOSTAT_BUMP(stat)	XUIOSTAT_INCR(stat, 1)
+
+int
+dmu_xuio_init(xuio_t *xuio, int nblk)
+{
+	dmu_xuio_t *priv;
+	uio_t *uio = &xuio->xu_uio;
+
+	uio->uio_iovcnt = nblk;
+	uio->uio_iov = kmem_zalloc(nblk * sizeof (iovec_t), KM_SLEEP);
+
+	priv = kmem_zalloc(sizeof (dmu_xuio_t), KM_SLEEP);
+	priv->cnt = nblk;
+	priv->bufs = kmem_zalloc(nblk * sizeof (arc_buf_t *), KM_SLEEP);
+	priv->iovp = (iovec_t *)uio->uio_iov;
+	XUIO_XUZC_PRIV(xuio) = priv;
+
+	if (XUIO_XUZC_RW(xuio) == UIO_READ)
+		XUIOSTAT_INCR(xuiostat_onloan_rbuf, nblk);
+	else
+		XUIOSTAT_INCR(xuiostat_onloan_wbuf, nblk);
+
+	return (0);
+}
+
+void
+dmu_xuio_fini(xuio_t *xuio)
+{
+	dmu_xuio_t *priv = XUIO_XUZC_PRIV(xuio);
+	int nblk = priv->cnt;
+
+	kmem_free(priv->iovp, nblk * sizeof (iovec_t));
+	kmem_free(priv->bufs, nblk * sizeof (arc_buf_t *));
+	kmem_free(priv, sizeof (dmu_xuio_t));
+
+	if (XUIO_XUZC_RW(xuio) == UIO_READ)
+		XUIOSTAT_INCR(xuiostat_onloan_rbuf, -nblk);
+	else
+		XUIOSTAT_INCR(xuiostat_onloan_wbuf, -nblk);
+}
+
+/*
+ * Initialize iov[priv->next] and priv->bufs[priv->next] with { off, n, abuf }
+ * and increase priv->next by 1.
+ */
+int
+dmu_xuio_add(xuio_t *xuio, arc_buf_t *abuf, offset_t off, size_t n)
+{
+	struct iovec *iov;
+	uio_t *uio = &xuio->xu_uio;
+	dmu_xuio_t *priv = XUIO_XUZC_PRIV(xuio);
+	int i = priv->next++;
+
+	ASSERT(i < priv->cnt);
+	ASSERT(off + n <= arc_buf_size(abuf));
+	iov = (iovec_t *)uio->uio_iov + i;
+	iov->iov_base = (char *)abuf->b_data + off;
+	iov->iov_len = n;
+	priv->bufs[i] = abuf;
+	return (0);
+}
+
+int
+dmu_xuio_cnt(xuio_t *xuio)
+{
+	dmu_xuio_t *priv = XUIO_XUZC_PRIV(xuio);
+	return (priv->cnt);
+}
+
+arc_buf_t *
+dmu_xuio_arcbuf(xuio_t *xuio, int i)
+{
+	dmu_xuio_t *priv = XUIO_XUZC_PRIV(xuio);
+
+	ASSERT(i < priv->cnt);
+	return (priv->bufs[i]);
+}
+
+void
+dmu_xuio_clear(xuio_t *xuio, int i)
+{
+	dmu_xuio_t *priv = XUIO_XUZC_PRIV(xuio);
+
+	ASSERT(i < priv->cnt);
+	priv->bufs[i] = NULL;
+}
+
+static void
+xuio_stat_init(void)
+{
+	xuio_ksp = kstat_create("zfs", 0, "xuio_stats", "misc",
+	    KSTAT_TYPE_NAMED, sizeof (xuio_stats) / sizeof (kstat_named_t),
+	    KSTAT_FLAG_VIRTUAL);
+	if (xuio_ksp != NULL) {
+		xuio_ksp->ks_data = &xuio_stats;
+		kstat_install(xuio_ksp);
+	}
+}
+
+static void
+xuio_stat_fini(void)
+{
+	if (xuio_ksp != NULL) {
+		kstat_delete(xuio_ksp);
+		xuio_ksp = NULL;
+	}
+}
+
+void
+xuio_stat_wbuf_copied()
+{
+	XUIOSTAT_BUMP(xuiostat_wbuf_copied);
+}
+
+void
+xuio_stat_wbuf_nocopy()
+{
+	XUIOSTAT_BUMP(xuiostat_wbuf_nocopy);
+}
+
+#ifdef _KERNEL
+
+/*
+ * Copy up to size bytes between arg_buf and req based on the data direction
+ * described by the req.  If an entire req's data cannot be transfered in one
+ * pass, you should pass in @req_offset to indicate where to continue. The
+ * return value is the number of bytes successfully copied to arg_buf.
+ */
+static int
+dmu_bio_copy(void *arg_buf, int size, struct bio *bio, size_t bio_offset)
+{
+	struct bio_vec bv, *bvp = &bv;
+	bvec_iterator_t iter;
+	char *bv_buf;
+	int tocpy, bv_len, bv_offset;
+	int offset = 0;
+
+	bio_for_each_segment4(bv, bvp, bio, iter) {
+
+		/*
+		 * Fully consumed the passed arg_buf. We use goto here because
+		 * rq_for_each_segment is a double loop
+		 */
+		ASSERT3S(offset, <=, size);
+		if (size == offset)
+			goto out;
+
+		/* Skip already copied bvp */
+		if (bio_offset >= bvp->bv_len) {
+			bio_offset -= bvp->bv_len;
+			continue;
+		}
+
+		bv_len = bvp->bv_len - bio_offset;
+		bv_offset = bvp->bv_offset + bio_offset;
+		bio_offset = 0;
+
+		tocpy = MIN(bv_len, size - offset);
+		ASSERT3S(tocpy, >=, 0);
+
+		bv_buf = page_address(bvp->bv_page) + bv_offset;
+		ASSERT3P(bv_buf, !=, NULL);
+
+		if (bio_data_dir(bio) == WRITE)
+			memcpy(arg_buf + offset, bv_buf, tocpy);
+		else
+			memcpy(bv_buf, arg_buf + offset, tocpy);
+
+		offset += tocpy;
+	}
+out:
+	return (offset);
+}
+
+int
+dmu_read_bio(objset_t *os, uint64_t object, struct bio *bio)
+{
+	uint64_t offset = BIO_BI_SECTOR(bio) << 9;
+	uint64_t size = BIO_BI_SIZE(bio);
+	dmu_buf_t **dbp;
+	int numbufs, i, err;
+	size_t bio_offset;
+
+	/*
+	 * NB: we could do this block-at-a-time, but it's nice
+	 * to be reading in parallel.
+	 */
+	err = dmu_buf_hold_array(os, object, offset, size, TRUE, FTAG,
+	    &numbufs, &dbp);
+	if (err)
+		return (err);
+
+	bio_offset = 0;
+	for (i = 0; i < numbufs; i++) {
+		uint64_t tocpy;
+		int64_t bufoff;
+		int didcpy;
+		dmu_buf_t *db = dbp[i];
+
+		bufoff = offset - db->db_offset;
+		ASSERT3S(bufoff, >=, 0);
+
+		tocpy = MIN(db->db_size - bufoff, size);
+		if (tocpy == 0)
+			break;
+
+		didcpy = dmu_bio_copy(db->db_data + bufoff, tocpy, bio,
+		    bio_offset);
+
+		if (didcpy < tocpy)
+			err = EIO;
+
+		if (err)
+			break;
+
+		size -= tocpy;
+		offset += didcpy;
+		bio_offset += didcpy;
+		err = 0;
+	}
+	dmu_buf_rele_array(dbp, numbufs, FTAG);
+
+	return (err);
+}
+
+int
+dmu_write_bio(objset_t *os, uint64_t object, struct bio *bio, dmu_tx_t *tx)
+{
+	uint64_t offset = BIO_BI_SECTOR(bio) << 9;
+	uint64_t size = BIO_BI_SIZE(bio);
+	dmu_buf_t **dbp;
+	int numbufs, i, err;
+	size_t bio_offset;
+
+	if (size == 0)
+		return (0);
+
+	err = dmu_buf_hold_array(os, object, offset, size, FALSE, FTAG,
+	    &numbufs, &dbp);
+	if (err)
+		return (err);
+
+	bio_offset = 0;
+	for (i = 0; i < numbufs; i++) {
+		uint64_t tocpy;
+		int64_t bufoff;
+		int didcpy;
+		dmu_buf_t *db = dbp[i];
+
+		bufoff = offset - db->db_offset;
+		ASSERT3S(bufoff, >=, 0);
+
+		tocpy = MIN(db->db_size - bufoff, size);
+		if (tocpy == 0)
+			break;
+
+		ASSERT(i == 0 || i == numbufs-1 || tocpy == db->db_size);
+
+		if (tocpy == db->db_size)
+			dmu_buf_will_fill(db, tx);
+		else
+			dmu_buf_will_dirty(db, tx);
+
+		didcpy = dmu_bio_copy(db->db_data + bufoff, tocpy, bio,
+		    bio_offset);
+
+		if (tocpy == db->db_size)
+			dmu_buf_fill_done(db, tx);
+
+		if (didcpy < tocpy)
+			err = EIO;
+
+		if (err)
+			break;
+
+		size -= tocpy;
+		offset += didcpy;
+		bio_offset += didcpy;
+		err = 0;
+	}
+
+	dmu_buf_rele_array(dbp, numbufs, FTAG);
+	return (err);
+}
+
+static int
+dmu_read_uio_dnode(dnode_t *dn, uio_t *uio, uint64_t size)
+{
+	dmu_buf_t **dbp;
+	int numbufs, i, err;
+	xuio_t *xuio = NULL;
+
+	/*
+	 * NB: we could do this block-at-a-time, but it's nice
+	 * to be reading in parallel.
+	 */
+	err = dmu_buf_hold_array_by_dnode(dn, uio->uio_loffset, size,
+	    TRUE, FTAG, &numbufs, &dbp, 0);
+	if (err)
+		return (err);
+
+	for (i = 0; i < numbufs; i++) {
+		uint64_t tocpy;
+		int64_t bufoff;
+		dmu_buf_t *db = dbp[i];
+
+		ASSERT(size > 0);
+
+		bufoff = uio->uio_loffset - db->db_offset;
+		tocpy = MIN(db->db_size - bufoff, size);
+
+		if (xuio) {
+			dmu_buf_impl_t *dbi = (dmu_buf_impl_t *)db;
+			arc_buf_t *dbuf_abuf = dbi->db_buf;
+			arc_buf_t *abuf = dbuf_loan_arcbuf(dbi);
+			err = dmu_xuio_add(xuio, abuf, bufoff, tocpy);
+			if (!err) {
+				uio->uio_resid -= tocpy;
+				uio->uio_loffset += tocpy;
+			}
+
+			if (abuf == dbuf_abuf)
+				XUIOSTAT_BUMP(xuiostat_rbuf_nocopy);
+			else
+				XUIOSTAT_BUMP(xuiostat_rbuf_copied);
+		} else {
+			err = uiomove((char *)db->db_data + bufoff, tocpy,
+			    UIO_READ, uio);
+		}
+		if (err)
+			break;
+
+		size -= tocpy;
+	}
+	dmu_buf_rele_array(dbp, numbufs, FTAG);
+
+	return (err);
+}
+
+/*
+ * Read 'size' bytes into the uio buffer.
+ * From object zdb->db_object.
+ * Starting at offset uio->uio_loffset.
+ *
+ * If the caller already has a dbuf in the target object
+ * (e.g. its bonus buffer), this routine is faster than dmu_read_uio(),
+ * because we don't have to find the dnode_t for the object.
+ */
+int
+dmu_read_uio_dbuf(dmu_buf_t *zdb, uio_t *uio, uint64_t size)
+{
+	dmu_buf_impl_t *db = (dmu_buf_impl_t *)zdb;
+	dnode_t *dn;
+	int err;
+
+	if (size == 0)
+		return (0);
+
+	DB_DNODE_ENTER(db);
+	dn = DB_DNODE(db);
+	err = dmu_read_uio_dnode(dn, uio, size);
+	DB_DNODE_EXIT(db);
+
+	return (err);
+}
+
+/*
+ * Read 'size' bytes into the uio buffer.
+ * From the specified object
+ * Starting at offset uio->uio_loffset.
+ */
+int
+dmu_read_uio(objset_t *os, uint64_t object, uio_t *uio, uint64_t size)
+{
+	dnode_t *dn;
+	int err;
+
+	if (size == 0)
+		return (0);
+
+	err = dnode_hold(os, object, FTAG, &dn);
+	if (err)
+		return (err);
+
+	err = dmu_read_uio_dnode(dn, uio, size);
+
+	dnode_rele(dn, FTAG);
+
+	return (err);
+}
+
+static int
+dmu_write_uio_dnode(dnode_t *dn, uio_t *uio, uint64_t size, dmu_tx_t *tx)
+{
+	dmu_buf_t **dbp;
+	int numbufs;
+	int err = 0;
+	int i;
+
+	err = dmu_buf_hold_array_by_dnode(dn, uio->uio_loffset, size,
+	    FALSE, FTAG, &numbufs, &dbp, DMU_READ_PREFETCH);
+	if (err)
+		return (err);
+
+	for (i = 0; i < numbufs; i++) {
+		uint64_t tocpy;
+		int64_t bufoff;
+		dmu_buf_t *db = dbp[i];
+
+		ASSERT(size > 0);
+
+		bufoff = uio->uio_loffset - db->db_offset;
+		tocpy = MIN(db->db_size - bufoff, size);
+
+		ASSERT(i == 0 || i == numbufs-1 || tocpy == db->db_size);
+
+		if (tocpy == db->db_size)
+			dmu_buf_will_fill(db, tx);
+		else
+			dmu_buf_will_dirty(db, tx);
+
+		/*
+		 * XXX uiomove could block forever (eg.nfs-backed
+		 * pages).  There needs to be a uiolockdown() function
+		 * to lock the pages in memory, so that uiomove won't
+		 * block.
+		 */
+		err = uiomove((char *)db->db_data + bufoff, tocpy,
+		    UIO_WRITE, uio);
+
+		if (tocpy == db->db_size)
+			dmu_buf_fill_done(db, tx);
+
+		if (err)
+			break;
+
+		size -= tocpy;
+	}
+
+	dmu_buf_rele_array(dbp, numbufs, FTAG);
+	return (err);
+}
+
+/*
+ * Write 'size' bytes from the uio buffer.
+ * To object zdb->db_object.
+ * Starting at offset uio->uio_loffset.
+ *
+ * If the caller already has a dbuf in the target object
+ * (e.g. its bonus buffer), this routine is faster than dmu_write_uio(),
+ * because we don't have to find the dnode_t for the object.
+ */
+int
+dmu_write_uio_dbuf(dmu_buf_t *zdb, uio_t *uio, uint64_t size,
+    dmu_tx_t *tx)
+{
+	dmu_buf_impl_t *db = (dmu_buf_impl_t *)zdb;
+	dnode_t *dn;
+	int err;
+
+	if (size == 0)
+		return (0);
+
+	DB_DNODE_ENTER(db);
+	dn = DB_DNODE(db);
+	err = dmu_write_uio_dnode(dn, uio, size, tx);
+	DB_DNODE_EXIT(db);
+
+	return (err);
+}
+
+/*
+ * Write 'size' bytes from the uio buffer.
+ * To the specified object.
+ * Starting at offset uio->uio_loffset.
+ */
+int
+dmu_write_uio(objset_t *os, uint64_t object, uio_t *uio, uint64_t size,
+    dmu_tx_t *tx)
+{
+	dnode_t *dn;
+	int err;
+
+	if (size == 0)
+		return (0);
+
+	err = dnode_hold(os, object, FTAG, &dn);
+	if (err)
+		return (err);
+
+	err = dmu_write_uio_dnode(dn, uio, size, tx);
+
+	dnode_rele(dn, FTAG);
+
+	return (err);
+}
+#endif /* _KERNEL */
+
+/*
+ * Allocate a loaned anonymous arc buffer.
+ */
+arc_buf_t *
+dmu_request_arcbuf(dmu_buf_t *handle, int size)
+{
+	dmu_buf_impl_t *db = (dmu_buf_impl_t *)handle;
+
+	return (arc_loan_buf(db->db_objset->os_spa, size));
+}
+
+/*
+ * Free a loaned arc buffer.
+ */
+void
+dmu_return_arcbuf(arc_buf_t *buf)
+{
+	arc_return_buf(buf, FTAG);
+	VERIFY(arc_buf_remove_ref(buf, FTAG));
+}
+
+/*
+ * When possible directly assign passed loaned arc buffer to a dbuf.
+ * If this is not possible copy the contents of passed arc buf via
+ * dmu_write().
+ */
+void
+dmu_assign_arcbuf(dmu_buf_t *handle, uint64_t offset, arc_buf_t *buf,
+    dmu_tx_t *tx)
+{
+	dmu_buf_impl_t *dbuf = (dmu_buf_impl_t *)handle;
+	dnode_t *dn;
+	dmu_buf_impl_t *db;
+	uint32_t blksz = (uint32_t)arc_buf_size(buf);
+	uint64_t blkid;
+
+	DB_DNODE_ENTER(dbuf);
+	dn = DB_DNODE(dbuf);
+	rw_enter(&dn->dn_struct_rwlock, RW_READER);
+	blkid = dbuf_whichblock(dn, offset);
+	VERIFY((db = dbuf_hold(dn, blkid, FTAG)) != NULL);
+	rw_exit(&dn->dn_struct_rwlock);
+	DB_DNODE_EXIT(dbuf);
+
+	/*
+	 * We can only assign if the offset is aligned, the arc buf is the
+	 * same size as the dbuf, and the dbuf is not metadata.  It
+	 * can't be metadata because the loaned arc buf comes from the
+	 * user-data kmem area.
+	 */
+	if (offset == db->db.db_offset && blksz == db->db.db_size &&
+	    DBUF_GET_BUFC_TYPE(db) == ARC_BUFC_DATA) {
+		dbuf_assign_arcbuf(db, buf, tx);
+		dbuf_rele(db, FTAG);
+	} else {
+		objset_t *os;
+		uint64_t object;
+
+		DB_DNODE_ENTER(dbuf);
+		dn = DB_DNODE(dbuf);
+		os = dn->dn_objset;
+		object = dn->dn_object;
+		DB_DNODE_EXIT(dbuf);
+
+		dbuf_rele(db, FTAG);
+		dmu_write(os, object, offset, blksz, buf->b_data, tx);
+		dmu_return_arcbuf(buf);
+		XUIOSTAT_BUMP(xuiostat_wbuf_copied);
+	}
+}
+
+typedef struct {
+	dbuf_dirty_record_t	*dsa_dr;
+	dmu_sync_cb_t		*dsa_done;
+	zgd_t			*dsa_zgd;
+	dmu_tx_t		*dsa_tx;
+} dmu_sync_arg_t;
+
+/* ARGSUSED */
+static void
+dmu_sync_ready(zio_t *zio, arc_buf_t *buf, void *varg)
+{
+	dmu_sync_arg_t *dsa = varg;
+	dmu_buf_t *db = dsa->dsa_zgd->zgd_db;
+	blkptr_t *bp = zio->io_bp;
+
+	if (zio->io_error == 0) {
+		if (BP_IS_HOLE(bp)) {
+			/*
+			 * A block of zeros may compress to a hole, but the
+			 * block size still needs to be known for replay.
+			 */
+			BP_SET_LSIZE(bp, db->db_size);
+		} else if (!BP_IS_EMBEDDED(bp)) {
+			ASSERT(BP_GET_LEVEL(bp) == 0);
+			bp->blk_fill = 1;
+		}
+	}
+}
+
+static void
+dmu_sync_late_arrival_ready(zio_t *zio)
+{
+	dmu_sync_ready(zio, NULL, zio->io_private);
+}
+
+/* ARGSUSED */
+static void
+dmu_sync_done(zio_t *zio, arc_buf_t *buf, void *varg)
+{
+	dmu_sync_arg_t *dsa = varg;
+	dbuf_dirty_record_t *dr = dsa->dsa_dr;
+	dmu_buf_impl_t *db = dr->dr_dbuf;
+
+	mutex_enter(&db->db_mtx);
+	ASSERT(dr->dt.dl.dr_override_state == DR_IN_DMU_SYNC);
+	if (zio->io_error == 0) {
+		dr->dt.dl.dr_nopwrite = !!(zio->io_flags & ZIO_FLAG_NOPWRITE);
+		if (dr->dt.dl.dr_nopwrite) {
+			ASSERTV(blkptr_t *bp = zio->io_bp);
+			ASSERTV(blkptr_t *bp_orig = &zio->io_bp_orig);
+			ASSERTV(uint8_t chksum = BP_GET_CHECKSUM(bp_orig));
+
+			ASSERT(BP_EQUAL(bp, bp_orig));
+			ASSERT(zio->io_prop.zp_compress != ZIO_COMPRESS_OFF);
+			ASSERT(zio_checksum_table[chksum].ci_dedup);
+		}
+		dr->dt.dl.dr_overridden_by = *zio->io_bp;
+		dr->dt.dl.dr_override_state = DR_OVERRIDDEN;
+		dr->dt.dl.dr_copies = zio->io_prop.zp_copies;
+
+		/*
+		 * Old style holes are filled with all zeros, whereas
+		 * new-style holes maintain their lsize, type, level,
+		 * and birth time (see zio_write_compress). While we
+		 * need to reset the BP_SET_LSIZE() call that happened
+		 * in dmu_sync_ready for old style holes, we do *not*
+		 * want to wipe out the information contained in new
+		 * style holes. Thus, only zero out the block pointer if
+		 * it's an old style hole.
+		 */
+		if (BP_IS_HOLE(&dr->dt.dl.dr_overridden_by) &&
+		    dr->dt.dl.dr_overridden_by.blk_birth == 0)
+			BP_ZERO(&dr->dt.dl.dr_overridden_by);
+	} else {
+		dr->dt.dl.dr_override_state = DR_NOT_OVERRIDDEN;
+	}
+	cv_broadcast(&db->db_changed);
+	mutex_exit(&db->db_mtx);
+
+	dsa->dsa_done(dsa->dsa_zgd, zio->io_error);
+
+	kmem_free(dsa, sizeof (*dsa));
+}
+
+static void
+dmu_sync_late_arrival_done(zio_t *zio)
+{
+	blkptr_t *bp = zio->io_bp;
+	dmu_sync_arg_t *dsa = zio->io_private;
+	ASSERTV(blkptr_t *bp_orig = &zio->io_bp_orig);
+
+	if (zio->io_error == 0 && !BP_IS_HOLE(bp)) {
+		/*
+		 * If we didn't allocate a new block (i.e. ZIO_FLAG_NOPWRITE)
+		 * then there is nothing to do here. Otherwise, free the
+		 * newly allocated block in this txg.
+		 */
+		if (zio->io_flags & ZIO_FLAG_NOPWRITE) {
+			ASSERT(BP_EQUAL(bp, bp_orig));
+		} else {
+			ASSERT(BP_IS_HOLE(bp_orig) || !BP_EQUAL(bp, bp_orig));
+			ASSERT(zio->io_bp->blk_birth == zio->io_txg);
+			ASSERT(zio->io_txg > spa_syncing_txg(zio->io_spa));
+			zio_free(zio->io_spa, zio->io_txg, zio->io_bp);
+		}
+	}
+
+	dmu_tx_commit(dsa->dsa_tx);
+
+	dsa->dsa_done(dsa->dsa_zgd, zio->io_error);
+
+	kmem_free(dsa, sizeof (*dsa));
+}
+
+static int
+dmu_sync_late_arrival(zio_t *pio, objset_t *os, dmu_sync_cb_t *done, zgd_t *zgd,
+    zio_prop_t *zp, zbookmark_phys_t *zb)
+{
+	dmu_sync_arg_t *dsa;
+	dmu_tx_t *tx;
+
+	tx = dmu_tx_create(os);
+	dmu_tx_hold_space(tx, zgd->zgd_db->db_size);
+	if (dmu_tx_assign(tx, TXG_WAIT) != 0) {
+		dmu_tx_abort(tx);
+		/* Make zl_get_data do txg_waited_synced() */
+		return (SET_ERROR(EIO));
+	}
+
+	dsa = kmem_alloc(sizeof (dmu_sync_arg_t), KM_SLEEP);
+	dsa->dsa_dr = NULL;
+	dsa->dsa_done = done;
+	dsa->dsa_zgd = zgd;
+	dsa->dsa_tx = tx;
+
+	zio_nowait(zio_write(pio, os->os_spa, dmu_tx_get_txg(tx), zgd->zgd_bp,
+	    zgd->zgd_db->db_data, zgd->zgd_db->db_size, zp,
+	    dmu_sync_late_arrival_ready, NULL, dmu_sync_late_arrival_done, dsa,
+	    ZIO_PRIORITY_SYNC_WRITE, ZIO_FLAG_CANFAIL|ZIO_FLAG_FASTWRITE, zb));
+
+	return (0);
+}
+
+/*
+ * Intent log support: sync the block associated with db to disk.
+ * N.B. and XXX: the caller is responsible for making sure that the
+ * data isn't changing while dmu_sync() is writing it.
+ *
+ * Return values:
+ *
+ *	EEXIST: this txg has already been synced, so there's nothing to do.
+ *		The caller should not log the write.
+ *
+ *	ENOENT: the block was dbuf_free_range()'d, so there's nothing to do.
+ *		The caller should not log the write.
+ *
+ *	EALREADY: this block is already in the process of being synced.
+ *		The caller should track its progress (somehow).
+ *
+ *	EIO: could not do the I/O.
+ *		The caller should do a txg_wait_synced().
+ *
+ *	0: the I/O has been initiated.
+ *		The caller should log this blkptr in the done callback.
+ *		It is possible that the I/O will fail, in which case
+ *		the error will be reported to the done callback and
+ *		propagated to pio from zio_done().
+ */
+int
+dmu_sync(zio_t *pio, uint64_t txg, dmu_sync_cb_t *done, zgd_t *zgd)
+{
+	blkptr_t *bp = zgd->zgd_bp;
+	dmu_buf_impl_t *db = (dmu_buf_impl_t *)zgd->zgd_db;
+	objset_t *os = db->db_objset;
+	dsl_dataset_t *ds = os->os_dsl_dataset;
+	dbuf_dirty_record_t *dr;
+	dmu_sync_arg_t *dsa;
+	zbookmark_phys_t zb;
+	zio_prop_t zp;
+	dnode_t *dn;
+
+	ASSERT(pio != NULL);
+	ASSERT(txg != 0);
+
+	SET_BOOKMARK(&zb, ds->ds_object,
+	    db->db.db_object, db->db_level, db->db_blkid);
+
+	DB_DNODE_ENTER(db);
+	dn = DB_DNODE(db);
+	dmu_write_policy(os, dn, db->db_level, WP_DMU_SYNC, &zp);
+	DB_DNODE_EXIT(db);
+
+	/*
+	 * If we're frozen (running ziltest), we always need to generate a bp.
+	 */
+	if (txg > spa_freeze_txg(os->os_spa))
+		return (dmu_sync_late_arrival(pio, os, done, zgd, &zp, &zb));
+
+	/*
+	 * Grabbing db_mtx now provides a barrier between dbuf_sync_leaf()
+	 * and us.  If we determine that this txg is not yet syncing,
+	 * but it begins to sync a moment later, that's OK because the
+	 * sync thread will block in dbuf_sync_leaf() until we drop db_mtx.
+	 */
+	mutex_enter(&db->db_mtx);
+
+	if (txg <= spa_last_synced_txg(os->os_spa)) {
+		/*
+		 * This txg has already synced.  There's nothing to do.
+		 */
+		mutex_exit(&db->db_mtx);
+		return (SET_ERROR(EEXIST));
+	}
+
+	if (txg <= spa_syncing_txg(os->os_spa)) {
+		/*
+		 * This txg is currently syncing, so we can't mess with
+		 * the dirty record anymore; just write a new log block.
+		 */
+		mutex_exit(&db->db_mtx);
+		return (dmu_sync_late_arrival(pio, os, done, zgd, &zp, &zb));
+	}
+
+	dr = db->db_last_dirty;
+	while (dr && dr->dr_txg != txg)
+		dr = dr->dr_next;
+
+	if (dr == NULL) {
+		/*
+		 * There's no dr for this dbuf, so it must have been freed.
+		 * There's no need to log writes to freed blocks, so we're done.
+		 */
+		mutex_exit(&db->db_mtx);
+		return (SET_ERROR(ENOENT));
+	}
+
+	ASSERT(dr->dr_next == NULL || dr->dr_next->dr_txg < txg);
+
+	/*
+	 * Assume the on-disk data is X, the current syncing data (in
+	 * txg - 1) is Y, and the current in-memory data is Z (currently
+	 * in dmu_sync).
+	 *
+	 * We usually want to perform a nopwrite if X and Z are the
+	 * same.  However, if Y is different (i.e. the BP is going to
+	 * change before this write takes effect), then a nopwrite will
+	 * be incorrect - we would override with X, which could have
+	 * been freed when Y was written.
+	 *
+	 * (Note that this is not a concern when we are nop-writing from
+	 * syncing context, because X and Y must be identical, because
+	 * all previous txgs have been synced.)
+	 *
+	 * Therefore, we disable nopwrite if the current BP could change
+	 * before this TXG.  There are two ways it could change: by
+	 * being dirty (dr_next is non-NULL), or by being freed
+	 * (dnode_block_freed()).  This behavior is verified by
+	 * zio_done(), which VERIFYs that the override BP is identical
+	 * to the on-disk BP.
+	 */
+	DB_DNODE_ENTER(db);
+	dn = DB_DNODE(db);
+	if (dr->dr_next != NULL || dnode_block_freed(dn, db->db_blkid))
+		zp.zp_nopwrite = B_FALSE;
+	DB_DNODE_EXIT(db);
+
+	ASSERT(dr->dr_txg == txg);
+	if (dr->dt.dl.dr_override_state == DR_IN_DMU_SYNC ||
+	    dr->dt.dl.dr_override_state == DR_OVERRIDDEN) {
+		/*
+		 * We have already issued a sync write for this buffer,
+		 * or this buffer has already been synced.  It could not
+		 * have been dirtied since, or we would have cleared the state.
+		 */
+		mutex_exit(&db->db_mtx);
+		return (SET_ERROR(EALREADY));
+	}
+
+	ASSERT(dr->dt.dl.dr_override_state == DR_NOT_OVERRIDDEN);
+	dr->dt.dl.dr_override_state = DR_IN_DMU_SYNC;
+	mutex_exit(&db->db_mtx);
+
+	dsa = kmem_alloc(sizeof (dmu_sync_arg_t), KM_SLEEP);
+	dsa->dsa_dr = dr;
+	dsa->dsa_done = done;
+	dsa->dsa_zgd = zgd;
+	dsa->dsa_tx = NULL;
+
+	zio_nowait(arc_write(pio, os->os_spa, txg,
+	    bp, dr->dt.dl.dr_data, DBUF_IS_L2CACHEABLE(db),
+	    DBUF_IS_L2COMPRESSIBLE(db), &zp, dmu_sync_ready,
+	    NULL, dmu_sync_done, dsa, ZIO_PRIORITY_SYNC_WRITE,
+	    ZIO_FLAG_CANFAIL, &zb));
+
+	return (0);
+}
+
+int
+dmu_object_set_blocksize(objset_t *os, uint64_t object, uint64_t size, int ibs,
+	dmu_tx_t *tx)
+{
+	dnode_t *dn;
+	int err;
+
+	err = dnode_hold(os, object, FTAG, &dn);
+	if (err)
+		return (err);
+	err = dnode_set_blksz(dn, size, ibs, tx);
+	dnode_rele(dn, FTAG);
+	return (err);
+}
+
+void
+dmu_object_set_checksum(objset_t *os, uint64_t object, uint8_t checksum,
+	dmu_tx_t *tx)
+{
+	dnode_t *dn;
+
+	/*
+	 * Send streams include each object's checksum function.  This
+	 * check ensures that the receiving system can understand the
+	 * checksum function transmitted.
+	 */
+	ASSERT3U(checksum, <, ZIO_CHECKSUM_LEGACY_FUNCTIONS);
+
+	VERIFY0(dnode_hold(os, object, FTAG, &dn));
+	ASSERT3U(checksum, <, ZIO_CHECKSUM_FUNCTIONS);
+	dn->dn_checksum = checksum;
+	dnode_setdirty(dn, tx);
+	dnode_rele(dn, FTAG);
+}
+
+void
+dmu_object_set_compress(objset_t *os, uint64_t object, uint8_t compress,
+	dmu_tx_t *tx)
+{
+	dnode_t *dn;
+
+	/*
+	 * Send streams include each object's compression function.  This
+	 * check ensures that the receiving system can understand the
+	 * compression function transmitted.
+	 */
+	ASSERT3U(compress, <, ZIO_COMPRESS_LEGACY_FUNCTIONS);
+
+	VERIFY0(dnode_hold(os, object, FTAG, &dn));
+	dn->dn_compress = compress;
+	dnode_setdirty(dn, tx);
+	dnode_rele(dn, FTAG);
+}
+
+int zfs_mdcomp_disable = 0;
+
+/*
+ * When the "redundant_metadata" property is set to "most", only indirect
+ * blocks of this level and higher will have an additional ditto block.
+ */
+int zfs_redundant_metadata_most_ditto_level = 2;
+
+void
+dmu_write_policy(objset_t *os, dnode_t *dn, int level, int wp, zio_prop_t *zp)
+{
+	dmu_object_type_t type = dn ? dn->dn_type : DMU_OT_OBJSET;
+	boolean_t ismd = (level > 0 || DMU_OT_IS_METADATA(type) ||
+	    (wp & WP_SPILL));
+	enum zio_checksum checksum = os->os_checksum;
+	enum zio_compress compress = os->os_compress;
+	enum zio_checksum dedup_checksum = os->os_dedup_checksum;
+	boolean_t dedup = B_FALSE;
+	boolean_t nopwrite = B_FALSE;
+	boolean_t dedup_verify = os->os_dedup_verify;
+	int copies = os->os_copies;
+
+	/*
+	 * We maintain different write policies for each of the following
+	 * types of data:
+	 *	 1. metadata
+	 *	 2. preallocated blocks (i.e. level-0 blocks of a dump device)
+	 *	 3. all other level 0 blocks
+	 */
+	if (ismd) {
+		if (zfs_mdcomp_disable) {
+			compress = ZIO_COMPRESS_EMPTY;
+		} else {
+			/*
+			 * XXX -- we should design a compression algorithm
+			 * that specializes in arrays of bps.
+			 */
+			compress = zio_compress_select(os->os_spa,
+			    ZIO_COMPRESS_ON, ZIO_COMPRESS_ON);
+		}
+
+		/*
+		 * Metadata always gets checksummed.  If the data
+		 * checksum is multi-bit correctable, and it's not a
+		 * ZBT-style checksum, then it's suitable for metadata
+		 * as well.  Otherwise, the metadata checksum defaults
+		 * to fletcher4.
+		 */
+		if (zio_checksum_table[checksum].ci_correctable < 1 ||
+		    zio_checksum_table[checksum].ci_eck)
+			checksum = ZIO_CHECKSUM_FLETCHER_4;
+
+		if (os->os_redundant_metadata == ZFS_REDUNDANT_METADATA_ALL ||
+		    (os->os_redundant_metadata ==
+		    ZFS_REDUNDANT_METADATA_MOST &&
+		    (level >= zfs_redundant_metadata_most_ditto_level ||
+		    DMU_OT_IS_METADATA(type) || (wp & WP_SPILL))))
+			copies++;
+	} else if (wp & WP_NOFILL) {
+		ASSERT(level == 0);
+
+		/*
+		 * If we're writing preallocated blocks, we aren't actually
+		 * writing them so don't set any policy properties.  These
+		 * blocks are currently only used by an external subsystem
+		 * outside of zfs (i.e. dump) and not written by the zio
+		 * pipeline.
+		 */
+		compress = ZIO_COMPRESS_OFF;
+		checksum = ZIO_CHECKSUM_OFF;
+	} else {
+		compress = zio_compress_select(os->os_spa, dn->dn_compress,
+		    compress);
+
+		checksum = (dedup_checksum == ZIO_CHECKSUM_OFF) ?
+		    zio_checksum_select(dn->dn_checksum, checksum) :
+		    dedup_checksum;
+
+		/*
+		 * Determine dedup setting.  If we are in dmu_sync(),
+		 * we won't actually dedup now because that's all
+		 * done in syncing context; but we do want to use the
+		 * dedup checkum.  If the checksum is not strong
+		 * enough to ensure unique signatures, force
+		 * dedup_verify.
+		 */
+		if (dedup_checksum != ZIO_CHECKSUM_OFF) {
+			dedup = (wp & WP_DMU_SYNC) ? B_FALSE : B_TRUE;
+			if (!zio_checksum_table[checksum].ci_dedup)
+				dedup_verify = B_TRUE;
+		}
+
+		/*
+		 * Enable nopwrite if we have a cryptographically secure
+		 * checksum that has no known collisions (i.e. SHA-256)
+		 * and compression is enabled.  We don't enable nopwrite if
+		 * dedup is enabled as the two features are mutually exclusive.
+		 */
+		nopwrite = (!dedup && zio_checksum_table[checksum].ci_dedup &&
+		    compress != ZIO_COMPRESS_OFF && zfs_nopwrite_enabled);
+	}
+
+	zp->zp_checksum = checksum;
+	zp->zp_compress = compress;
+	zp->zp_type = (wp & WP_SPILL) ? dn->dn_bonustype : type;
+	zp->zp_level = level;
+	zp->zp_copies = MIN(copies, spa_max_replication(os->os_spa));
+	zp->zp_dedup = dedup;
+	zp->zp_dedup_verify = dedup && dedup_verify;
+	zp->zp_nopwrite = nopwrite;
+}
+
+int
+dmu_offset_next(objset_t *os, uint64_t object, boolean_t hole, uint64_t *off)
+{
+	dnode_t *dn;
+	int i, err;
+
+	err = dnode_hold(os, object, FTAG, &dn);
+	if (err)
+		return (err);
+	/*
+	 * Sync any current changes before
+	 * we go trundling through the block pointers.
+	 */
+	for (i = 0; i < TXG_SIZE; i++) {
+		if (list_link_active(&dn->dn_dirty_link[i]))
+			break;
+	}
+	if (i != TXG_SIZE) {
+		dnode_rele(dn, FTAG);
+		txg_wait_synced(dmu_objset_pool(os), 0);
+		err = dnode_hold(os, object, FTAG, &dn);
+		if (err)
+			return (err);
+	}
+
+	err = dnode_next_offset(dn, (hole ? DNODE_FIND_HOLE : 0), off, 1, 1, 0);
+	dnode_rele(dn, FTAG);
+
+	return (err);
+}
+
+void
+__dmu_object_info_from_dnode(dnode_t *dn, dmu_object_info_t *doi)
+{
+	dnode_phys_t *dnp = dn->dn_phys;
+	int i;
+
+	doi->doi_data_block_size = dn->dn_datablksz;
+	doi->doi_metadata_block_size = dn->dn_indblkshift ?
+	    1ULL << dn->dn_indblkshift : 0;
+	doi->doi_type = dn->dn_type;
+	doi->doi_bonus_type = dn->dn_bonustype;
+	doi->doi_bonus_size = dn->dn_bonuslen;
+	doi->doi_indirection = dn->dn_nlevels;
+	doi->doi_checksum = dn->dn_checksum;
+	doi->doi_compress = dn->dn_compress;
+	doi->doi_nblkptr = dn->dn_nblkptr;
+	doi->doi_physical_blocks_512 = (DN_USED_BYTES(dnp) + 256) >> 9;
+	doi->doi_max_offset = (dn->dn_maxblkid + 1) * dn->dn_datablksz;
+	doi->doi_fill_count = 0;
+	for (i = 0; i < dnp->dn_nblkptr; i++)
+		doi->doi_fill_count += BP_GET_FILL(&dnp->dn_blkptr[i]);
+}
+
+void
+dmu_object_info_from_dnode(dnode_t *dn, dmu_object_info_t *doi)
+{
+	rw_enter(&dn->dn_struct_rwlock, RW_READER);
+	mutex_enter(&dn->dn_mtx);
+
+	__dmu_object_info_from_dnode(dn, doi);
+
+	mutex_exit(&dn->dn_mtx);
+	rw_exit(&dn->dn_struct_rwlock);
+}
+
+/*
+ * Get information on a DMU object.
+ * If doi is NULL, just indicates whether the object exists.
+ */
+int
+dmu_object_info(objset_t *os, uint64_t object, dmu_object_info_t *doi)
+{
+	dnode_t *dn;
+	int err = dnode_hold(os, object, FTAG, &dn);
+
+	if (err)
+		return (err);
+
+	if (doi != NULL)
+		dmu_object_info_from_dnode(dn, doi);
+
+	dnode_rele(dn, FTAG);
+	return (0);
+}
+
+/*
+ * As above, but faster; can be used when you have a held dbuf in hand.
+ */
+void
+dmu_object_info_from_db(dmu_buf_t *db_fake, dmu_object_info_t *doi)
+{
+	dmu_buf_impl_t *db = (dmu_buf_impl_t *)db_fake;
+
+	DB_DNODE_ENTER(db);
+	dmu_object_info_from_dnode(DB_DNODE(db), doi);
+	DB_DNODE_EXIT(db);
+}
+
+/*
+ * Faster still when you only care about the size.
+ * This is specifically optimized for zfs_getattr().
+ */
+void
+dmu_object_size_from_db(dmu_buf_t *db_fake, uint32_t *blksize,
+    u_longlong_t *nblk512)
+{
+	dmu_buf_impl_t *db = (dmu_buf_impl_t *)db_fake;
+	dnode_t *dn;
+
+	DB_DNODE_ENTER(db);
+	dn = DB_DNODE(db);
+
+	*blksize = dn->dn_datablksz;
+	/* add 1 for dnode space */
+	*nblk512 = ((DN_USED_BYTES(dn->dn_phys) + SPA_MINBLOCKSIZE/2) >>
+	    SPA_MINBLOCKSHIFT) + 1;
+	DB_DNODE_EXIT(db);
+}
+
+void
+byteswap_uint64_array(void *vbuf, size_t size)
+{
+	uint64_t *buf = vbuf;
+	size_t count = size >> 3;
+	int i;
+
+	ASSERT((size & 7) == 0);
+
+	for (i = 0; i < count; i++)
+		buf[i] = BSWAP_64(buf[i]);
+}
+
+void
+byteswap_uint32_array(void *vbuf, size_t size)
+{
+	uint32_t *buf = vbuf;
+	size_t count = size >> 2;
+	int i;
+
+	ASSERT((size & 3) == 0);
+
+	for (i = 0; i < count; i++)
+		buf[i] = BSWAP_32(buf[i]);
+}
+
+void
+byteswap_uint16_array(void *vbuf, size_t size)
+{
+	uint16_t *buf = vbuf;
+	size_t count = size >> 1;
+	int i;
+
+	ASSERT((size & 1) == 0);
+
+	for (i = 0; i < count; i++)
+		buf[i] = BSWAP_16(buf[i]);
+}
+
+/* ARGSUSED */
+void
+byteswap_uint8_array(void *vbuf, size_t size)
+{
+}
+
+void
+dmu_init(void)
+{
+	zfs_dbgmsg_init();
+	sa_cache_init();
+	xuio_stat_init();
+	dmu_objset_init();
+	dnode_init();
+	dbuf_init();
+	zfetch_init();
+	dmu_tx_init();
+	l2arc_init();
+	arc_init();
+}
+
+void
+dmu_fini(void)
+{
+	arc_fini(); /* arc depends on l2arc, so arc must go first */
+	l2arc_fini();
+	dmu_tx_fini();
+	zfetch_fini();
+	dbuf_fini();
+	dnode_fini();
+	dmu_objset_fini();
+	xuio_stat_fini();
+	sa_cache_fini();
+	zfs_dbgmsg_fini();
+}
+
+#if defined(_KERNEL) && defined(HAVE_SPL)
+EXPORT_SYMBOL(dmu_bonus_hold);
+EXPORT_SYMBOL(dmu_buf_hold_array_by_bonus);
+EXPORT_SYMBOL(dmu_buf_rele_array);
+EXPORT_SYMBOL(dmu_prefetch);
+EXPORT_SYMBOL(dmu_free_range);
+EXPORT_SYMBOL(dmu_free_long_range);
+EXPORT_SYMBOL(dmu_free_long_object);
+EXPORT_SYMBOL(dmu_read);
+EXPORT_SYMBOL(dmu_write);
+EXPORT_SYMBOL(dmu_prealloc);
+EXPORT_SYMBOL(dmu_object_info);
+EXPORT_SYMBOL(dmu_object_info_from_dnode);
+EXPORT_SYMBOL(dmu_object_info_from_db);
+EXPORT_SYMBOL(dmu_object_size_from_db);
+EXPORT_SYMBOL(dmu_object_set_blocksize);
+EXPORT_SYMBOL(dmu_object_set_checksum);
+EXPORT_SYMBOL(dmu_object_set_compress);
+EXPORT_SYMBOL(dmu_write_policy);
+EXPORT_SYMBOL(dmu_sync);
+EXPORT_SYMBOL(dmu_request_arcbuf);
+EXPORT_SYMBOL(dmu_return_arcbuf);
+EXPORT_SYMBOL(dmu_assign_arcbuf);
+EXPORT_SYMBOL(dmu_buf_hold);
+EXPORT_SYMBOL(dmu_ot);
+
+module_param(zfs_mdcomp_disable, int, 0644);
+MODULE_PARM_DESC(zfs_mdcomp_disable, "Disable meta data compression");
+
+module_param(zfs_nopwrite_enabled, int, 0644);
+MODULE_PARM_DESC(zfs_nopwrite_enabled, "Enable NOP writes");
+
+#endif
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/module/zfs/dmu_diff.c
@@ -0,0 +1,223 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2014 by Delphix. All rights reserved.
+ */
+
+#include <sys/dmu.h>
+#include <sys/dmu_impl.h>
+#include <sys/dmu_tx.h>
+#include <sys/dbuf.h>
+#include <sys/dnode.h>
+#include <sys/zfs_context.h>
+#include <sys/dmu_objset.h>
+#include <sys/dmu_traverse.h>
+#include <sys/dsl_dataset.h>
+#include <sys/dsl_dir.h>
+#include <sys/dsl_pool.h>
+#include <sys/dsl_synctask.h>
+#include <sys/zfs_ioctl.h>
+#include <sys/zap.h>
+#include <sys/zio_checksum.h>
+#include <sys/zfs_znode.h>
+
+struct diffarg {
+	struct vnode *da_vp;		/* file to which we are reporting */
+	offset_t *da_offp;
+	int da_err;			/* error that stopped diff search */
+	dmu_diff_record_t da_ddr;
+};
+
+static int
+write_record(struct diffarg *da)
+{
+	ssize_t resid; /* have to get resid to get detailed errno */
+
+	if (da->da_ddr.ddr_type == DDR_NONE) {
+		da->da_err = 0;
+		return (0);
+	}
+
+	da->da_err = vn_rdwr(UIO_WRITE, da->da_vp, (caddr_t)&da->da_ddr,
+	    sizeof (da->da_ddr), 0, UIO_SYSSPACE, FAPPEND,
+	    RLIM64_INFINITY, CRED(), &resid);
+	*da->da_offp += sizeof (da->da_ddr);
+	return (da->da_err);
+}
+
+static int
+report_free_dnode_range(struct diffarg *da, uint64_t first, uint64_t last)
+{
+	ASSERT(first <= last);
+	if (da->da_ddr.ddr_type != DDR_FREE ||
+	    first != da->da_ddr.ddr_last + 1) {
+		if (write_record(da) != 0)
+			return (da->da_err);
+		da->da_ddr.ddr_type = DDR_FREE;
+		da->da_ddr.ddr_first = first;
+		da->da_ddr.ddr_last = last;
+		return (0);
+	}
+	da->da_ddr.ddr_last = last;
+	return (0);
+}
+
+static int
+report_dnode(struct diffarg *da, uint64_t object, dnode_phys_t *dnp)
+{
+	ASSERT(dnp != NULL);
+	if (dnp->dn_type == DMU_OT_NONE)
+		return (report_free_dnode_range(da, object, object));
+
+	if (da->da_ddr.ddr_type != DDR_INUSE ||
+	    object != da->da_ddr.ddr_last + 1) {
+		if (write_record(da) != 0)
+			return (da->da_err);
+		da->da_ddr.ddr_type = DDR_INUSE;
+		da->da_ddr.ddr_first = da->da_ddr.ddr_last = object;
+		return (0);
+	}
+	da->da_ddr.ddr_last = object;
+	return (0);
+}
+
+#define	DBP_SPAN(dnp, level)				  \
+	(((uint64_t)dnp->dn_datablkszsec) << (SPA_MINBLOCKSHIFT + \
+	(level) * (dnp->dn_indblkshift - SPA_BLKPTRSHIFT)))
+
+/* ARGSUSED */
+static int
+diff_cb(spa_t *spa, zilog_t *zilog, const blkptr_t *bp,
+    const zbookmark_phys_t *zb, const dnode_phys_t *dnp, void *arg)
+{
+	struct diffarg *da = arg;
+	int err = 0;
+
+	if (issig(JUSTLOOKING) && issig(FORREAL))
+		return (SET_ERROR(EINTR));
+
+	if (zb->zb_object != DMU_META_DNODE_OBJECT)
+		return (0);
+
+	if (BP_IS_HOLE(bp)) {
+		uint64_t span = DBP_SPAN(dnp, zb->zb_level);
+		uint64_t dnobj = (zb->zb_blkid * span) >> DNODE_SHIFT;
+
+		err = report_free_dnode_range(da, dnobj,
+		    dnobj + (span >> DNODE_SHIFT) - 1);
+		if (err)
+			return (err);
+	} else if (zb->zb_level == 0) {
+		dnode_phys_t *blk;
+		arc_buf_t *abuf;
+		arc_flags_t aflags = ARC_FLAG_WAIT;
+		int blksz = BP_GET_LSIZE(bp);
+		int i;
+
+		if (arc_read(NULL, spa, bp, arc_getbuf_func, &abuf,
+		    ZIO_PRIORITY_ASYNC_READ, ZIO_FLAG_CANFAIL,
+		    &aflags, zb) != 0)
+			return (SET_ERROR(EIO));
+
+		blk = abuf->b_data;
+		for (i = 0; i < blksz >> DNODE_SHIFT; i++) {
+			uint64_t dnobj = (zb->zb_blkid <<
+			    (DNODE_BLOCK_SHIFT - DNODE_SHIFT)) + i;
+			err = report_dnode(da, dnobj, blk+i);
+			if (err)
+				break;
+		}
+		(void) arc_buf_remove_ref(abuf, &abuf);
+		if (err)
+			return (err);
+		/* Don't care about the data blocks */
+		return (TRAVERSE_VISIT_NO_CHILDREN);
+	}
+	return (0);
+}
+
+int
+dmu_diff(const char *tosnap_name, const char *fromsnap_name,
+    struct vnode *vp, offset_t *offp)
+{
+	struct diffarg da;
+	dsl_dataset_t *fromsnap;
+	dsl_dataset_t *tosnap;
+	dsl_pool_t *dp;
+	int error;
+	uint64_t fromtxg;
+
+	if (strchr(tosnap_name, '@') == NULL ||
+	    strchr(fromsnap_name, '@') == NULL)
+		return (SET_ERROR(EINVAL));
+
+	error = dsl_pool_hold(tosnap_name, FTAG, &dp);
+	if (error != 0)
+		return (error);
+
+	error = dsl_dataset_hold(dp, tosnap_name, FTAG, &tosnap);
+	if (error != 0) {
+		dsl_pool_rele(dp, FTAG);
+		return (error);
+	}
+
+	error = dsl_dataset_hold(dp, fromsnap_name, FTAG, &fromsnap);
+	if (error != 0) {
+		dsl_dataset_rele(tosnap, FTAG);
+		dsl_pool_rele(dp, FTAG);
+		return (error);
+	}
+
+	if (!dsl_dataset_is_before(tosnap, fromsnap, 0)) {
+		dsl_dataset_rele(fromsnap, FTAG);
+		dsl_dataset_rele(tosnap, FTAG);
+		dsl_pool_rele(dp, FTAG);
+		return (SET_ERROR(EXDEV));
+	}
+
+	fromtxg = dsl_dataset_phys(fromsnap)->ds_creation_txg;
+	dsl_dataset_rele(fromsnap, FTAG);
+
+	dsl_dataset_long_hold(tosnap, FTAG);
+	dsl_pool_rele(dp, FTAG);
+
+	da.da_vp = vp;
+	da.da_offp = offp;
+	da.da_ddr.ddr_type = DDR_NONE;
+	da.da_ddr.ddr_first = da.da_ddr.ddr_last = 0;
+	da.da_err = 0;
+
+	error = traverse_dataset(tosnap, fromtxg,
+	    TRAVERSE_PRE | TRAVERSE_PREFETCH_METADATA, diff_cb, &da);
+
+	if (error != 0) {
+		da.da_err = error;
+	} else {
+		/* we set the da.da_err we return as side-effect */
+		(void) write_record(&da);
+	}
+
+	dsl_dataset_long_rele(tosnap, FTAG);
+	dsl_dataset_rele(tosnap, FTAG);
+
+	return (da.da_err);
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/module/zfs/dmu_object.c
@@ -0,0 +1,230 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2015 by Delphix. All rights reserved.
+ * Copyright 2014 HybridCluster. All rights reserved.
+ */
+
+#include <sys/dmu.h>
+#include <sys/dmu_objset.h>
+#include <sys/dmu_tx.h>
+#include <sys/dnode.h>
+#include <sys/zap.h>
+#include <sys/zfeature.h>
+
+uint64_t
+dmu_object_alloc(objset_t *os, dmu_object_type_t ot, int blocksize,
+    dmu_object_type_t bonustype, int bonuslen, dmu_tx_t *tx)
+{
+	uint64_t object;
+	uint64_t L2_dnode_count = DNODES_PER_BLOCK <<
+	    (DMU_META_DNODE(os)->dn_indblkshift - SPA_BLKPTRSHIFT);
+	dnode_t *dn = NULL;
+	int restarted = B_FALSE;
+
+	mutex_enter(&os->os_obj_lock);
+	for (;;) {
+		object = os->os_obj_next;
+		/*
+		 * Each time we polish off an L2 bp worth of dnodes
+		 * (2^13 objects), move to another L2 bp that's still
+		 * reasonably sparse (at most 1/4 full).  Look from the
+		 * beginning once, but after that keep looking from here.
+		 * If we can't find one, just keep going from here.
+		 *
+		 * Note that dmu_traverse depends on the behavior that we use
+		 * multiple blocks of the dnode object before going back to
+		 * reuse objects.  Any change to this algorithm should preserve
+		 * that property or find another solution to the issues
+		 * described in traverse_visitbp.
+		 */
+		if (P2PHASE(object, L2_dnode_count) == 0) {
+			uint64_t offset = restarted ? object << DNODE_SHIFT : 0;
+			int error = dnode_next_offset(DMU_META_DNODE(os),
+			    DNODE_FIND_HOLE,
+			    &offset, 2, DNODES_PER_BLOCK >> 2, 0);
+			restarted = B_TRUE;
+			if (error == 0)
+				object = offset >> DNODE_SHIFT;
+		}
+		os->os_obj_next = ++object;
+
+		/*
+		 * XXX We should check for an i/o error here and return
+		 * up to our caller.  Actually we should pre-read it in
+		 * dmu_tx_assign(), but there is currently no mechanism
+		 * to do so.
+		 */
+		(void) dnode_hold_impl(os, object, DNODE_MUST_BE_FREE,
+		    FTAG, &dn);
+		if (dn)
+			break;
+
+		if (dmu_object_next(os, &object, B_TRUE, 0) == 0)
+			os->os_obj_next = object - 1;
+	}
+
+	dnode_allocate(dn, ot, blocksize, 0, bonustype, bonuslen, tx);
+	dnode_rele(dn, FTAG);
+
+	mutex_exit(&os->os_obj_lock);
+
+	dmu_tx_add_new_object(tx, os, object);
+	return (object);
+}
+
+int
+dmu_object_claim(objset_t *os, uint64_t object, dmu_object_type_t ot,
+    int blocksize, dmu_object_type_t bonustype, int bonuslen, dmu_tx_t *tx)
+{
+	dnode_t *dn;
+	int err;
+
+	if (object == DMU_META_DNODE_OBJECT && !dmu_tx_private_ok(tx))
+		return (SET_ERROR(EBADF));
+
+	err = dnode_hold_impl(os, object, DNODE_MUST_BE_FREE, FTAG, &dn);
+	if (err)
+		return (err);
+	dnode_allocate(dn, ot, blocksize, 0, bonustype, bonuslen, tx);
+	dnode_rele(dn, FTAG);
+
+	dmu_tx_add_new_object(tx, os, object);
+	return (0);
+}
+
+int
+dmu_object_reclaim(objset_t *os, uint64_t object, dmu_object_type_t ot,
+    int blocksize, dmu_object_type_t bonustype, int bonuslen, dmu_tx_t *tx)
+{
+	dnode_t *dn;
+	int err;
+
+	if (object == DMU_META_DNODE_OBJECT)
+		return (SET_ERROR(EBADF));
+
+	err = dnode_hold_impl(os, object, DNODE_MUST_BE_ALLOCATED,
+	    FTAG, &dn);
+	if (err)
+		return (err);
+
+	dnode_reallocate(dn, ot, blocksize, bonustype, bonuslen, tx);
+
+	dnode_rele(dn, FTAG);
+	return (err);
+}
+
+int
+dmu_object_free(objset_t *os, uint64_t object, dmu_tx_t *tx)
+{
+	dnode_t *dn;
+	int err;
+
+	ASSERT(object != DMU_META_DNODE_OBJECT || dmu_tx_private_ok(tx));
+
+	err = dnode_hold_impl(os, object, DNODE_MUST_BE_ALLOCATED,
+	    FTAG, &dn);
+	if (err)
+		return (err);
+
+	ASSERT(dn->dn_type != DMU_OT_NONE);
+	dnode_free_range(dn, 0, DMU_OBJECT_END, tx);
+	dnode_free(dn, tx);
+	dnode_rele(dn, FTAG);
+
+	return (0);
+}
+
+int
+dmu_object_next(objset_t *os, uint64_t *objectp, boolean_t hole, uint64_t txg)
+{
+	uint64_t offset = (*objectp + 1) << DNODE_SHIFT;
+	int error;
+
+	error = dnode_next_offset(DMU_META_DNODE(os),
+	    (hole ? DNODE_FIND_HOLE : 0), &offset, 0, DNODES_PER_BLOCK, txg);
+
+	*objectp = offset >> DNODE_SHIFT;
+
+	return (error);
+}
+
+/*
+ * Turn this object from old_type into DMU_OTN_ZAP_METADATA, and bump the
+ * refcount on SPA_FEATURE_EXTENSIBLE_DATASET.
+ *
+ * Only for use from syncing context, on MOS objects.
+ */
+void
+dmu_object_zapify(objset_t *mos, uint64_t object, dmu_object_type_t old_type,
+    dmu_tx_t *tx)
+{
+	dnode_t *dn;
+
+	ASSERT(dmu_tx_is_syncing(tx));
+
+	VERIFY0(dnode_hold(mos, object, FTAG, &dn));
+	if (dn->dn_type == DMU_OTN_ZAP_METADATA) {
+		dnode_rele(dn, FTAG);
+		return;
+	}
+	ASSERT3U(dn->dn_type, ==, old_type);
+	ASSERT0(dn->dn_maxblkid);
+	dn->dn_next_type[tx->tx_txg & TXG_MASK] = dn->dn_type =
+	    DMU_OTN_ZAP_METADATA;
+	dnode_setdirty(dn, tx);
+	dnode_rele(dn, FTAG);
+
+	mzap_create_impl(mos, object, 0, 0, tx);
+
+	spa_feature_incr(dmu_objset_spa(mos),
+	    SPA_FEATURE_EXTENSIBLE_DATASET, tx);
+}
+
+void
+dmu_object_free_zapified(objset_t *mos, uint64_t object, dmu_tx_t *tx)
+{
+	dnode_t *dn;
+	dmu_object_type_t t;
+
+	ASSERT(dmu_tx_is_syncing(tx));
+
+	VERIFY0(dnode_hold(mos, object, FTAG, &dn));
+	t = dn->dn_type;
+	dnode_rele(dn, FTAG);
+
+	if (t == DMU_OTN_ZAP_METADATA) {
+		spa_feature_decr(dmu_objset_spa(mos),
+		    SPA_FEATURE_EXTENSIBLE_DATASET, tx);
+	}
+	VERIFY0(dmu_object_free(mos, object, tx));
+}
+
+#if defined(_KERNEL) && defined(HAVE_SPL)
+EXPORT_SYMBOL(dmu_object_alloc);
+EXPORT_SYMBOL(dmu_object_claim);
+EXPORT_SYMBOL(dmu_object_reclaim);
+EXPORT_SYMBOL(dmu_object_free);
+EXPORT_SYMBOL(dmu_object_next);
+EXPORT_SYMBOL(dmu_object_zapify);
+EXPORT_SYMBOL(dmu_object_free_zapified);
+#endif
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/module/zfs/dmu_objset.c
@@ -0,0 +1,2052 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2014 by Delphix. All rights reserved.
+ * Copyright (c) 2013 by Saso Kiselkov. All rights reserved.
+ * Copyright (c) 2013, Joyent, Inc. All rights reserved.
+ * Copyright (c) 2014 Spectra Logic Corporation, All rights reserved.
+ * Copyright (c) 2015 Nexenta Systems, Inc. All rights reserved.
+ * Copyright (c) 2015, STRATO AG, Inc. All rights reserved.
+ * Copyright (c) 2016 Actifio, Inc. All rights reserved.
+ */
+
+/* Portions Copyright 2010 Robert Milkowski */
+
+#include <sys/cred.h>
+#include <sys/zfs_context.h>
+#include <sys/dmu_objset.h>
+#include <sys/dsl_dir.h>
+#include <sys/dsl_dataset.h>
+#include <sys/dsl_prop.h>
+#include <sys/dsl_pool.h>
+#include <sys/dsl_synctask.h>
+#include <sys/dsl_deleg.h>
+#include <sys/dnode.h>
+#include <sys/dbuf.h>
+#include <sys/zvol.h>
+#include <sys/dmu_tx.h>
+#include <sys/zap.h>
+#include <sys/zil.h>
+#include <sys/dmu_impl.h>
+#include <sys/zfs_ioctl.h>
+#include <sys/sa.h>
+#include <sys/zfs_onexit.h>
+#include <sys/dsl_destroy.h>
+#include <sys/vdev.h>
+
+/*
+ * Needed to close a window in dnode_move() that allows the objset to be freed
+ * before it can be safely accessed.
+ */
+krwlock_t os_lock;
+
+/*
+ * Tunable to overwrite the maximum number of threads for the parallization
+ * of dmu_objset_find_dp, needed to speed up the import of pools with many
+ * datasets.
+ * Default is 4 times the number of leaf vdevs.
+ */
+int dmu_find_threads = 0;
+
+static void dmu_objset_find_dp_cb(void *arg);
+
+void
+dmu_objset_init(void)
+{
+	rw_init(&os_lock, NULL, RW_DEFAULT, NULL);
+}
+
+void
+dmu_objset_fini(void)
+{
+	rw_destroy(&os_lock);
+}
+
+spa_t *
+dmu_objset_spa(objset_t *os)
+{
+	return (os->os_spa);
+}
+
+zilog_t *
+dmu_objset_zil(objset_t *os)
+{
+	return (os->os_zil);
+}
+
+dsl_pool_t *
+dmu_objset_pool(objset_t *os)
+{
+	dsl_dataset_t *ds;
+
+	if ((ds = os->os_dsl_dataset) != NULL && ds->ds_dir)
+		return (ds->ds_dir->dd_pool);
+	else
+		return (spa_get_dsl(os->os_spa));
+}
+
+dsl_dataset_t *
+dmu_objset_ds(objset_t *os)
+{
+	return (os->os_dsl_dataset);
+}
+
+dmu_objset_type_t
+dmu_objset_type(objset_t *os)
+{
+	return (os->os_phys->os_type);
+}
+
+void
+dmu_objset_name(objset_t *os, char *buf)
+{
+	dsl_dataset_name(os->os_dsl_dataset, buf);
+}
+
+uint64_t
+dmu_objset_id(objset_t *os)
+{
+	dsl_dataset_t *ds = os->os_dsl_dataset;
+
+	return (ds ? ds->ds_object : 0);
+}
+
+zfs_sync_type_t
+dmu_objset_syncprop(objset_t *os)
+{
+	return (os->os_sync);
+}
+
+zfs_logbias_op_t
+dmu_objset_logbias(objset_t *os)
+{
+	return (os->os_logbias);
+}
+
+static void
+checksum_changed_cb(void *arg, uint64_t newval)
+{
+	objset_t *os = arg;
+
+	/*
+	 * Inheritance should have been done by now.
+	 */
+	ASSERT(newval != ZIO_CHECKSUM_INHERIT);
+
+	os->os_checksum = zio_checksum_select(newval, ZIO_CHECKSUM_ON_VALUE);
+}
+
+static void
+compression_changed_cb(void *arg, uint64_t newval)
+{
+	objset_t *os = arg;
+
+	/*
+	 * Inheritance and range checking should have been done by now.
+	 */
+	ASSERT(newval != ZIO_COMPRESS_INHERIT);
+
+	os->os_compress = zio_compress_select(os->os_spa, newval,
+	    ZIO_COMPRESS_ON);
+}
+
+static void
+copies_changed_cb(void *arg, uint64_t newval)
+{
+	objset_t *os = arg;
+
+	/*
+	 * Inheritance and range checking should have been done by now.
+	 */
+	ASSERT(newval > 0);
+	ASSERT(newval <= spa_max_replication(os->os_spa));
+
+	os->os_copies = newval;
+}
+
+static void
+dedup_changed_cb(void *arg, uint64_t newval)
+{
+	objset_t *os = arg;
+	spa_t *spa = os->os_spa;
+	enum zio_checksum checksum;
+
+	/*
+	 * Inheritance should have been done by now.
+	 */
+	ASSERT(newval != ZIO_CHECKSUM_INHERIT);
+
+	checksum = zio_checksum_dedup_select(spa, newval, ZIO_CHECKSUM_OFF);
+
+	os->os_dedup_checksum = checksum & ZIO_CHECKSUM_MASK;
+	os->os_dedup_verify = !!(checksum & ZIO_CHECKSUM_VERIFY);
+}
+
+static void
+primary_cache_changed_cb(void *arg, uint64_t newval)
+{
+	objset_t *os = arg;
+
+	/*
+	 * Inheritance and range checking should have been done by now.
+	 */
+	ASSERT(newval == ZFS_CACHE_ALL || newval == ZFS_CACHE_NONE ||
+	    newval == ZFS_CACHE_METADATA);
+
+	os->os_primary_cache = newval;
+}
+
+static void
+secondary_cache_changed_cb(void *arg, uint64_t newval)
+{
+	objset_t *os = arg;
+
+	/*
+	 * Inheritance and range checking should have been done by now.
+	 */
+	ASSERT(newval == ZFS_CACHE_ALL || newval == ZFS_CACHE_NONE ||
+	    newval == ZFS_CACHE_METADATA);
+
+	os->os_secondary_cache = newval;
+}
+
+static void
+sync_changed_cb(void *arg, uint64_t newval)
+{
+	objset_t *os = arg;
+
+	/*
+	 * Inheritance and range checking should have been done by now.
+	 */
+	ASSERT(newval == ZFS_SYNC_STANDARD || newval == ZFS_SYNC_ALWAYS ||
+	    newval == ZFS_SYNC_DISABLED);
+
+	os->os_sync = newval;
+	if (os->os_zil)
+		zil_set_sync(os->os_zil, newval);
+}
+
+static void
+redundant_metadata_changed_cb(void *arg, uint64_t newval)
+{
+	objset_t *os = arg;
+
+	/*
+	 * Inheritance and range checking should have been done by now.
+	 */
+	ASSERT(newval == ZFS_REDUNDANT_METADATA_ALL ||
+	    newval == ZFS_REDUNDANT_METADATA_MOST);
+
+	os->os_redundant_metadata = newval;
+}
+
+static void
+logbias_changed_cb(void *arg, uint64_t newval)
+{
+	objset_t *os = arg;
+
+	ASSERT(newval == ZFS_LOGBIAS_LATENCY ||
+	    newval == ZFS_LOGBIAS_THROUGHPUT);
+	os->os_logbias = newval;
+	if (os->os_zil)
+		zil_set_logbias(os->os_zil, newval);
+}
+
+static void
+recordsize_changed_cb(void *arg, uint64_t newval)
+{
+	objset_t *os = arg;
+
+	os->os_recordsize = newval;
+}
+
+void
+dmu_objset_byteswap(void *buf, size_t size)
+{
+	objset_phys_t *osp = buf;
+
+	ASSERT(size == OBJSET_OLD_PHYS_SIZE || size == sizeof (objset_phys_t));
+	dnode_byteswap(&osp->os_meta_dnode);
+	byteswap_uint64_array(&osp->os_zil_header, sizeof (zil_header_t));
+	osp->os_type = BSWAP_64(osp->os_type);
+	osp->os_flags = BSWAP_64(osp->os_flags);
+	if (size == sizeof (objset_phys_t)) {
+		dnode_byteswap(&osp->os_userused_dnode);
+		dnode_byteswap(&osp->os_groupused_dnode);
+	}
+}
+
+int
+dmu_objset_open_impl(spa_t *spa, dsl_dataset_t *ds, blkptr_t *bp,
+    objset_t **osp)
+{
+	objset_t *os;
+	int i, err;
+
+	ASSERT(ds == NULL || MUTEX_HELD(&ds->ds_opening_lock));
+
+	os = kmem_zalloc(sizeof (objset_t), KM_SLEEP);
+	os->os_dsl_dataset = ds;
+	os->os_spa = spa;
+	os->os_rootbp = bp;
+	if (!BP_IS_HOLE(os->os_rootbp)) {
+		arc_flags_t aflags = ARC_FLAG_WAIT;
+		zbookmark_phys_t zb;
+		SET_BOOKMARK(&zb, ds ? ds->ds_object : DMU_META_OBJSET,
+		    ZB_ROOT_OBJECT, ZB_ROOT_LEVEL, ZB_ROOT_BLKID);
+
+		if (DMU_OS_IS_L2CACHEABLE(os))
+			aflags |= ARC_FLAG_L2CACHE;
+		if (DMU_OS_IS_L2COMPRESSIBLE(os))
+			aflags |= ARC_FLAG_L2COMPRESS;
+
+		dprintf_bp(os->os_rootbp, "reading %s", "");
+		err = arc_read(NULL, spa, os->os_rootbp,
+		    arc_getbuf_func, &os->os_phys_buf,
+		    ZIO_PRIORITY_SYNC_READ, ZIO_FLAG_CANFAIL, &aflags, &zb);
+		if (err != 0) {
+			kmem_free(os, sizeof (objset_t));
+			/* convert checksum errors into IO errors */
+			if (err == ECKSUM)
+				err = SET_ERROR(EIO);
+			return (err);
+		}
+
+		/* Increase the blocksize if we are permitted. */
+		if (spa_version(spa) >= SPA_VERSION_USERSPACE &&
+		    arc_buf_size(os->os_phys_buf) < sizeof (objset_phys_t)) {
+			arc_buf_t *buf = arc_buf_alloc(spa,
+			    sizeof (objset_phys_t), &os->os_phys_buf,
+			    ARC_BUFC_METADATA);
+			bzero(buf->b_data, sizeof (objset_phys_t));
+			bcopy(os->os_phys_buf->b_data, buf->b_data,
+			    arc_buf_size(os->os_phys_buf));
+			(void) arc_buf_remove_ref(os->os_phys_buf,
+			    &os->os_phys_buf);
+			os->os_phys_buf = buf;
+		}
+
+		os->os_phys = os->os_phys_buf->b_data;
+		os->os_flags = os->os_phys->os_flags;
+	} else {
+		int size = spa_version(spa) >= SPA_VERSION_USERSPACE ?
+		    sizeof (objset_phys_t) : OBJSET_OLD_PHYS_SIZE;
+		os->os_phys_buf = arc_buf_alloc(spa, size,
+		    &os->os_phys_buf, ARC_BUFC_METADATA);
+		os->os_phys = os->os_phys_buf->b_data;
+		bzero(os->os_phys, size);
+	}
+
+	/*
+	 * Note: the changed_cb will be called once before the register
+	 * func returns, thus changing the checksum/compression from the
+	 * default (fletcher2/off).  Snapshots don't need to know about
+	 * checksum/compression/copies.
+	 */
+	if (ds != NULL) {
+		err = dsl_prop_register(ds,
+		    zfs_prop_to_name(ZFS_PROP_PRIMARYCACHE),
+		    primary_cache_changed_cb, os);
+		if (err == 0) {
+			err = dsl_prop_register(ds,
+			    zfs_prop_to_name(ZFS_PROP_SECONDARYCACHE),
+			    secondary_cache_changed_cb, os);
+		}
+		if (!ds->ds_is_snapshot) {
+			if (err == 0) {
+				err = dsl_prop_register(ds,
+				    zfs_prop_to_name(ZFS_PROP_CHECKSUM),
+				    checksum_changed_cb, os);
+			}
+			if (err == 0) {
+				err = dsl_prop_register(ds,
+				    zfs_prop_to_name(ZFS_PROP_COMPRESSION),
+				    compression_changed_cb, os);
+			}
+			if (err == 0) {
+				err = dsl_prop_register(ds,
+				    zfs_prop_to_name(ZFS_PROP_COPIES),
+				    copies_changed_cb, os);
+			}
+			if (err == 0) {
+				err = dsl_prop_register(ds,
+				    zfs_prop_to_name(ZFS_PROP_DEDUP),
+				    dedup_changed_cb, os);
+			}
+			if (err == 0) {
+				err = dsl_prop_register(ds,
+				    zfs_prop_to_name(ZFS_PROP_LOGBIAS),
+				    logbias_changed_cb, os);
+			}
+			if (err == 0) {
+				err = dsl_prop_register(ds,
+				    zfs_prop_to_name(ZFS_PROP_SYNC),
+				    sync_changed_cb, os);
+			}
+			if (err == 0) {
+				err = dsl_prop_register(ds,
+				    zfs_prop_to_name(
+				    ZFS_PROP_REDUNDANT_METADATA),
+				    redundant_metadata_changed_cb, os);
+			}
+			if (err == 0) {
+				err = dsl_prop_register(ds,
+				    zfs_prop_to_name(ZFS_PROP_RECORDSIZE),
+				    recordsize_changed_cb, os);
+			}
+		}
+		if (err != 0) {
+			VERIFY(arc_buf_remove_ref(os->os_phys_buf,
+			    &os->os_phys_buf));
+			kmem_free(os, sizeof (objset_t));
+			return (err);
+		}
+	} else {
+		/* It's the meta-objset. */
+		os->os_checksum = ZIO_CHECKSUM_FLETCHER_4;
+		os->os_compress = ZIO_COMPRESS_ON;
+		os->os_copies = spa_max_replication(spa);
+		os->os_dedup_checksum = ZIO_CHECKSUM_OFF;
+		os->os_dedup_verify = B_FALSE;
+		os->os_logbias = ZFS_LOGBIAS_LATENCY;
+		os->os_sync = ZFS_SYNC_STANDARD;
+		os->os_primary_cache = ZFS_CACHE_ALL;
+		os->os_secondary_cache = ZFS_CACHE_ALL;
+	}
+
+	if (ds == NULL || !ds->ds_is_snapshot)
+		os->os_zil_header = os->os_phys->os_zil_header;
+	os->os_zil = zil_alloc(os, &os->os_zil_header);
+
+	for (i = 0; i < TXG_SIZE; i++) {
+		list_create(&os->os_dirty_dnodes[i], sizeof (dnode_t),
+		    offsetof(dnode_t, dn_dirty_link[i]));
+		list_create(&os->os_free_dnodes[i], sizeof (dnode_t),
+		    offsetof(dnode_t, dn_dirty_link[i]));
+	}
+	list_create(&os->os_dnodes, sizeof (dnode_t),
+	    offsetof(dnode_t, dn_link));
+	list_create(&os->os_downgraded_dbufs, sizeof (dmu_buf_impl_t),
+	    offsetof(dmu_buf_impl_t, db_link));
+
+	list_link_init(&os->os_evicting_node);
+
+	mutex_init(&os->os_lock, NULL, MUTEX_DEFAULT, NULL);
+	mutex_init(&os->os_obj_lock, NULL, MUTEX_DEFAULT, NULL);
+	mutex_init(&os->os_user_ptr_lock, NULL, MUTEX_DEFAULT, NULL);
+
+	dnode_special_open(os, &os->os_phys->os_meta_dnode,
+	    DMU_META_DNODE_OBJECT, &os->os_meta_dnode);
+	if (arc_buf_size(os->os_phys_buf) >= sizeof (objset_phys_t)) {
+		dnode_special_open(os, &os->os_phys->os_userused_dnode,
+		    DMU_USERUSED_OBJECT, &os->os_userused_dnode);
+		dnode_special_open(os, &os->os_phys->os_groupused_dnode,
+		    DMU_GROUPUSED_OBJECT, &os->os_groupused_dnode);
+	}
+
+	*osp = os;
+	return (0);
+}
+
+int
+dmu_objset_from_ds(dsl_dataset_t *ds, objset_t **osp)
+{
+	int err = 0;
+
+	mutex_enter(&ds->ds_opening_lock);
+	if (ds->ds_objset == NULL) {
+		objset_t *os;
+		err = dmu_objset_open_impl(dsl_dataset_get_spa(ds),
+		    ds, dsl_dataset_get_blkptr(ds), &os);
+
+		if (err == 0) {
+			mutex_enter(&ds->ds_lock);
+			ASSERT(ds->ds_objset == NULL);
+			ds->ds_objset = os;
+			mutex_exit(&ds->ds_lock);
+		}
+	}
+	*osp = ds->ds_objset;
+	mutex_exit(&ds->ds_opening_lock);
+	return (err);
+}
+
+/*
+ * Holds the pool while the objset is held.  Therefore only one objset
+ * can be held at a time.
+ */
+int
+dmu_objset_hold(const char *name, void *tag, objset_t **osp)
+{
+	dsl_pool_t *dp;
+	dsl_dataset_t *ds;
+	int err;
+
+	err = dsl_pool_hold(name, tag, &dp);
+	if (err != 0)
+		return (err);
+	err = dsl_dataset_hold(dp, name, tag, &ds);
+	if (err != 0) {
+		dsl_pool_rele(dp, tag);
+		return (err);
+	}
+
+	err = dmu_objset_from_ds(ds, osp);
+	if (err != 0) {
+		dsl_dataset_rele(ds, tag);
+		dsl_pool_rele(dp, tag);
+	}
+
+	return (err);
+}
+
+static int
+dmu_objset_own_impl(dsl_dataset_t *ds, dmu_objset_type_t type,
+    boolean_t readonly, void *tag, objset_t **osp)
+{
+	int err;
+
+	err = dmu_objset_from_ds(ds, osp);
+	if (err != 0) {
+		dsl_dataset_disown(ds, tag);
+	} else if (type != DMU_OST_ANY && type != (*osp)->os_phys->os_type) {
+		dsl_dataset_disown(ds, tag);
+		return (SET_ERROR(EINVAL));
+	} else if (!readonly && dsl_dataset_is_snapshot(ds)) {
+		dsl_dataset_disown(ds, tag);
+		return (SET_ERROR(EROFS));
+	}
+	return (err);
+}
+
+/*
+ * dsl_pool must not be held when this is called.
+ * Upon successful return, there will be a longhold on the dataset,
+ * and the dsl_pool will not be held.
+ */
+int
+dmu_objset_own(const char *name, dmu_objset_type_t type,
+    boolean_t readonly, void *tag, objset_t **osp)
+{
+	dsl_pool_t *dp;
+	dsl_dataset_t *ds;
+	int err;
+
+	err = dsl_pool_hold(name, FTAG, &dp);
+	if (err != 0)
+		return (err);
+	err = dsl_dataset_own(dp, name, tag, &ds);
+	if (err != 0) {
+		dsl_pool_rele(dp, FTAG);
+		return (err);
+	}
+	err = dmu_objset_own_impl(ds, type, readonly, tag, osp);
+	dsl_pool_rele(dp, FTAG);
+
+	return (err);
+}
+
+int
+dmu_objset_own_obj(dsl_pool_t *dp, uint64_t obj, dmu_objset_type_t type,
+    boolean_t readonly, void *tag, objset_t **osp)
+{
+	dsl_dataset_t *ds;
+	int err;
+
+	err = dsl_dataset_own_obj(dp, obj, tag, &ds);
+	if (err != 0)
+		return (err);
+
+	return (dmu_objset_own_impl(ds, type, readonly, tag, osp));
+}
+
+void
+dmu_objset_rele(objset_t *os, void *tag)
+{
+	dsl_pool_t *dp = dmu_objset_pool(os);
+	dsl_dataset_rele(os->os_dsl_dataset, tag);
+	dsl_pool_rele(dp, tag);
+}
+
+/*
+ * When we are called, os MUST refer to an objset associated with a dataset
+ * that is owned by 'tag'; that is, is held and long held by 'tag' and ds_owner
+ * == tag.  We will then release and reacquire ownership of the dataset while
+ * holding the pool config_rwlock to avoid intervening namespace or ownership
+ * changes may occur.
+ *
+ * This exists solely to accommodate zfs_ioc_userspace_upgrade()'s desire to
+ * release the hold on its dataset and acquire a new one on the dataset of the
+ * same name so that it can be partially torn down and reconstructed.
+ */
+void
+dmu_objset_refresh_ownership(objset_t *os, void *tag)
+{
+	dsl_pool_t *dp;
+	dsl_dataset_t *ds, *newds;
+	char name[MAXNAMELEN];
+
+	ds = os->os_dsl_dataset;
+	VERIFY3P(ds, !=, NULL);
+	VERIFY3P(ds->ds_owner, ==, tag);
+	VERIFY(dsl_dataset_long_held(ds));
+
+	dsl_dataset_name(ds, name);
+	dp = dmu_objset_pool(os);
+	dsl_pool_config_enter(dp, FTAG);
+	dmu_objset_disown(os, tag);
+	VERIFY0(dsl_dataset_own(dp, name, tag, &newds));
+	VERIFY3P(newds, ==, os->os_dsl_dataset);
+	dsl_pool_config_exit(dp, FTAG);
+}
+
+void
+dmu_objset_disown(objset_t *os, void *tag)
+{
+	dsl_dataset_disown(os->os_dsl_dataset, tag);
+}
+
+void
+dmu_objset_evict_dbufs(objset_t *os)
+{
+	dnode_t *dn_marker;
+	dnode_t *dn;
+
+	dn_marker = kmem_alloc(sizeof (dnode_t), KM_SLEEP);
+
+	mutex_enter(&os->os_lock);
+	dn = list_head(&os->os_dnodes);
+	while (dn != NULL) {
+		/*
+		 * Skip dnodes without holds.  We have to do this dance
+		 * because dnode_add_ref() only works if there is already a
+		 * hold.  If the dnode has no holds, then it has no dbufs.
+		 */
+		if (dnode_add_ref(dn, FTAG)) {
+			list_insert_after(&os->os_dnodes, dn, dn_marker);
+			mutex_exit(&os->os_lock);
+
+			dnode_evict_dbufs(dn);
+			dnode_rele(dn, FTAG);
+
+			mutex_enter(&os->os_lock);
+			dn = list_next(&os->os_dnodes, dn_marker);
+			list_remove(&os->os_dnodes, dn_marker);
+		} else {
+			dn = list_next(&os->os_dnodes, dn);
+		}
+	}
+	mutex_exit(&os->os_lock);
+
+	kmem_free(dn_marker, sizeof (dnode_t));
+
+	if (DMU_USERUSED_DNODE(os) != NULL) {
+		dnode_evict_dbufs(DMU_GROUPUSED_DNODE(os));
+		dnode_evict_dbufs(DMU_USERUSED_DNODE(os));
+	}
+	dnode_evict_dbufs(DMU_META_DNODE(os));
+}
+
+/*
+ * Objset eviction processing is split into into two pieces.
+ * The first marks the objset as evicting, evicts any dbufs that
+ * have a refcount of zero, and then queues up the objset for the
+ * second phase of eviction.  Once os->os_dnodes has been cleared by
+ * dnode_buf_pageout()->dnode_destroy(), the second phase is executed.
+ * The second phase closes the special dnodes, dequeues the objset from
+ * the list of those undergoing eviction, and finally frees the objset.
+ *
+ * NOTE: Due to asynchronous eviction processing (invocation of
+ *       dnode_buf_pageout()), it is possible for the meta dnode for the
+ *       objset to have no holds even though os->os_dnodes is not empty.
+ */
+void
+dmu_objset_evict(objset_t *os)
+{
+	int t;
+
+	dsl_dataset_t *ds = os->os_dsl_dataset;
+
+	for (t = 0; t < TXG_SIZE; t++)
+		ASSERT(!dmu_objset_is_dirty(os, t));
+
+	if (ds) {
+		if (!ds->ds_is_snapshot) {
+			VERIFY0(dsl_prop_unregister(ds,
+			    zfs_prop_to_name(ZFS_PROP_CHECKSUM),
+			    checksum_changed_cb, os));
+			VERIFY0(dsl_prop_unregister(ds,
+			    zfs_prop_to_name(ZFS_PROP_COMPRESSION),
+			    compression_changed_cb, os));
+			VERIFY0(dsl_prop_unregister(ds,
+			    zfs_prop_to_name(ZFS_PROP_COPIES),
+			    copies_changed_cb, os));
+			VERIFY0(dsl_prop_unregister(ds,
+			    zfs_prop_to_name(ZFS_PROP_DEDUP),
+			    dedup_changed_cb, os));
+			VERIFY0(dsl_prop_unregister(ds,
+			    zfs_prop_to_name(ZFS_PROP_LOGBIAS),
+			    logbias_changed_cb, os));
+			VERIFY0(dsl_prop_unregister(ds,
+			    zfs_prop_to_name(ZFS_PROP_SYNC),
+			    sync_changed_cb, os));
+			VERIFY0(dsl_prop_unregister(ds,
+			    zfs_prop_to_name(ZFS_PROP_REDUNDANT_METADATA),
+			    redundant_metadata_changed_cb, os));
+			VERIFY0(dsl_prop_unregister(ds,
+			    zfs_prop_to_name(ZFS_PROP_RECORDSIZE),
+			    recordsize_changed_cb, os));
+		}
+		VERIFY0(dsl_prop_unregister(ds,
+		    zfs_prop_to_name(ZFS_PROP_PRIMARYCACHE),
+		    primary_cache_changed_cb, os));
+		VERIFY0(dsl_prop_unregister(ds,
+		    zfs_prop_to_name(ZFS_PROP_SECONDARYCACHE),
+		    secondary_cache_changed_cb, os));
+	}
+
+	if (os->os_sa)
+		sa_tear_down(os);
+
+	dmu_objset_evict_dbufs(os);
+
+	mutex_enter(&os->os_lock);
+	spa_evicting_os_register(os->os_spa, os);
+	if (list_is_empty(&os->os_dnodes)) {
+		mutex_exit(&os->os_lock);
+		dmu_objset_evict_done(os);
+	} else {
+		mutex_exit(&os->os_lock);
+	}
+}
+
+void
+dmu_objset_evict_done(objset_t *os)
+{
+	ASSERT3P(list_head(&os->os_dnodes), ==, NULL);
+
+	dnode_special_close(&os->os_meta_dnode);
+	if (DMU_USERUSED_DNODE(os)) {
+		dnode_special_close(&os->os_userused_dnode);
+		dnode_special_close(&os->os_groupused_dnode);
+	}
+	zil_free(os->os_zil);
+
+	VERIFY(arc_buf_remove_ref(os->os_phys_buf, &os->os_phys_buf));
+
+	/*
+	 * This is a barrier to prevent the objset from going away in
+	 * dnode_move() until we can safely ensure that the objset is still in
+	 * use. We consider the objset valid before the barrier and invalid
+	 * after the barrier.
+	 */
+	rw_enter(&os_lock, RW_READER);
+	rw_exit(&os_lock);
+
+	mutex_destroy(&os->os_lock);
+	mutex_destroy(&os->os_obj_lock);
+	mutex_destroy(&os->os_user_ptr_lock);
+	spa_evicting_os_deregister(os->os_spa, os);
+	kmem_free(os, sizeof (objset_t));
+}
+
+timestruc_t
+dmu_objset_snap_cmtime(objset_t *os)
+{
+	return (dsl_dir_snap_cmtime(os->os_dsl_dataset->ds_dir));
+}
+
+/* called from dsl for meta-objset */
+objset_t *
+dmu_objset_create_impl(spa_t *spa, dsl_dataset_t *ds, blkptr_t *bp,
+    dmu_objset_type_t type, dmu_tx_t *tx)
+{
+	objset_t *os;
+	dnode_t *mdn;
+
+	ASSERT(dmu_tx_is_syncing(tx));
+
+	if (ds != NULL)
+		VERIFY0(dmu_objset_from_ds(ds, &os));
+	else
+		VERIFY0(dmu_objset_open_impl(spa, NULL, bp, &os));
+
+	mdn = DMU_META_DNODE(os);
+
+	dnode_allocate(mdn, DMU_OT_DNODE, 1 << DNODE_BLOCK_SHIFT,
+	    DN_MAX_INDBLKSHIFT, DMU_OT_NONE, 0, tx);
+
+	/*
+	 * We don't want to have to increase the meta-dnode's nlevels
+	 * later, because then we could do it in quescing context while
+	 * we are also accessing it in open context.
+	 *
+	 * This precaution is not necessary for the MOS (ds == NULL),
+	 * because the MOS is only updated in syncing context.
+	 * This is most fortunate: the MOS is the only objset that
+	 * needs to be synced multiple times as spa_sync() iterates
+	 * to convergence, so minimizing its dn_nlevels matters.
+	 */
+	if (ds != NULL) {
+		int levels = 1;
+
+		/*
+		 * Determine the number of levels necessary for the meta-dnode
+		 * to contain DN_MAX_OBJECT dnodes.
+		 */
+		while ((uint64_t)mdn->dn_nblkptr << (mdn->dn_datablkshift +
+		    (levels - 1) * (mdn->dn_indblkshift - SPA_BLKPTRSHIFT)) <
+		    DN_MAX_OBJECT * sizeof (dnode_phys_t))
+			levels++;
+
+		mdn->dn_next_nlevels[tx->tx_txg & TXG_MASK] =
+		    mdn->dn_nlevels = levels;
+	}
+
+	ASSERT(type != DMU_OST_NONE);
+	ASSERT(type != DMU_OST_ANY);
+	ASSERT(type < DMU_OST_NUMTYPES);
+	os->os_phys->os_type = type;
+	if (dmu_objset_userused_enabled(os)) {
+		os->os_phys->os_flags |= OBJSET_FLAG_USERACCOUNTING_COMPLETE;
+		os->os_flags = os->os_phys->os_flags;
+	}
+
+	dsl_dataset_dirty(ds, tx);
+
+	return (os);
+}
+
+typedef struct dmu_objset_create_arg {
+	const char *doca_name;
+	cred_t *doca_cred;
+	void (*doca_userfunc)(objset_t *os, void *arg,
+	    cred_t *cr, dmu_tx_t *tx);
+	void *doca_userarg;
+	dmu_objset_type_t doca_type;
+	uint64_t doca_flags;
+} dmu_objset_create_arg_t;
+
+/*ARGSUSED*/
+static int
+dmu_objset_create_check(void *arg, dmu_tx_t *tx)
+{
+	dmu_objset_create_arg_t *doca = arg;
+	dsl_pool_t *dp = dmu_tx_pool(tx);
+	dsl_dir_t *pdd;
+	const char *tail;
+	int error;
+
+	if (strchr(doca->doca_name, '@') != NULL)
+		return (SET_ERROR(EINVAL));
+
+	error = dsl_dir_hold(dp, doca->doca_name, FTAG, &pdd, &tail);
+	if (error != 0)
+		return (error);
+	if (tail == NULL) {
+		dsl_dir_rele(pdd, FTAG);
+		return (SET_ERROR(EEXIST));
+	}
+	error = dsl_fs_ss_limit_check(pdd, 1, ZFS_PROP_FILESYSTEM_LIMIT, NULL,
+	    doca->doca_cred);
+	dsl_dir_rele(pdd, FTAG);
+
+	return (error);
+}
+
+static void
+dmu_objset_create_sync(void *arg, dmu_tx_t *tx)
+{
+	dmu_objset_create_arg_t *doca = arg;
+	dsl_pool_t *dp = dmu_tx_pool(tx);
+	dsl_dir_t *pdd;
+	const char *tail;
+	dsl_dataset_t *ds;
+	uint64_t obj;
+	blkptr_t *bp;
+	objset_t *os;
+
+	VERIFY0(dsl_dir_hold(dp, doca->doca_name, FTAG, &pdd, &tail));
+
+	obj = dsl_dataset_create_sync(pdd, tail, NULL, doca->doca_flags,
+	    doca->doca_cred, tx);
+
+	VERIFY0(dsl_dataset_hold_obj(pdd->dd_pool, obj, FTAG, &ds));
+	bp = dsl_dataset_get_blkptr(ds);
+	os = dmu_objset_create_impl(pdd->dd_pool->dp_spa,
+	    ds, bp, doca->doca_type, tx);
+
+	if (doca->doca_userfunc != NULL) {
+		doca->doca_userfunc(os, doca->doca_userarg,
+		    doca->doca_cred, tx);
+	}
+
+	spa_history_log_internal_ds(ds, "create", tx, "");
+	zvol_create_minors(dp->dp_spa, doca->doca_name, B_TRUE);
+
+	dsl_dataset_rele(ds, FTAG);
+	dsl_dir_rele(pdd, FTAG);
+}
+
+int
+dmu_objset_create(const char *name, dmu_objset_type_t type, uint64_t flags,
+    void (*func)(objset_t *os, void *arg, cred_t *cr, dmu_tx_t *tx), void *arg)
+{
+	dmu_objset_create_arg_t doca;
+
+	doca.doca_name = name;
+	doca.doca_cred = CRED();
+	doca.doca_flags = flags;
+	doca.doca_userfunc = func;
+	doca.doca_userarg = arg;
+	doca.doca_type = type;
+
+	return (dsl_sync_task(name,
+	    dmu_objset_create_check, dmu_objset_create_sync, &doca,
+	    5, ZFS_SPACE_CHECK_NORMAL));
+}
+
+typedef struct dmu_objset_clone_arg {
+	const char *doca_clone;
+	const char *doca_origin;
+	cred_t *doca_cred;
+} dmu_objset_clone_arg_t;
+
+/*ARGSUSED*/
+static int
+dmu_objset_clone_check(void *arg, dmu_tx_t *tx)
+{
+	dmu_objset_clone_arg_t *doca = arg;
+	dsl_dir_t *pdd;
+	const char *tail;
+	int error;
+	dsl_dataset_t *origin;
+	dsl_pool_t *dp = dmu_tx_pool(tx);
+
+	if (strchr(doca->doca_clone, '@') != NULL)
+		return (SET_ERROR(EINVAL));
+
+	error = dsl_dir_hold(dp, doca->doca_clone, FTAG, &pdd, &tail);
+	if (error != 0)
+		return (error);
+	if (tail == NULL) {
+		dsl_dir_rele(pdd, FTAG);
+		return (SET_ERROR(EEXIST));
+	}
+
+	error = dsl_fs_ss_limit_check(pdd, 1, ZFS_PROP_FILESYSTEM_LIMIT, NULL,
+	    doca->doca_cred);
+	if (error != 0) {
+		dsl_dir_rele(pdd, FTAG);
+		return (SET_ERROR(EDQUOT));
+	}
+	dsl_dir_rele(pdd, FTAG);
+
+	error = dsl_dataset_hold(dp, doca->doca_origin, FTAG, &origin);
+	if (error != 0)
+		return (error);
+
+	/* You can only clone snapshots, not the head datasets. */
+	if (!origin->ds_is_snapshot) {
+		dsl_dataset_rele(origin, FTAG);
+		return (SET_ERROR(EINVAL));
+	}
+	dsl_dataset_rele(origin, FTAG);
+
+	return (0);
+}
+
+static void
+dmu_objset_clone_sync(void *arg, dmu_tx_t *tx)
+{
+	dmu_objset_clone_arg_t *doca = arg;
+	dsl_pool_t *dp = dmu_tx_pool(tx);
+	dsl_dir_t *pdd;
+	const char *tail;
+	dsl_dataset_t *origin, *ds;
+	uint64_t obj;
+	char namebuf[MAXNAMELEN];
+
+	VERIFY0(dsl_dir_hold(dp, doca->doca_clone, FTAG, &pdd, &tail));
+	VERIFY0(dsl_dataset_hold(dp, doca->doca_origin, FTAG, &origin));
+
+	obj = dsl_dataset_create_sync(pdd, tail, origin, 0,
+	    doca->doca_cred, tx);
+
+	VERIFY0(dsl_dataset_hold_obj(pdd->dd_pool, obj, FTAG, &ds));
+	dsl_dataset_name(origin, namebuf);
+	spa_history_log_internal_ds(ds, "clone", tx,
+	    "origin=%s (%llu)", namebuf, origin->ds_object);
+	zvol_create_minors(dp->dp_spa, doca->doca_clone, B_TRUE);
+	dsl_dataset_rele(ds, FTAG);
+	dsl_dataset_rele(origin, FTAG);
+	dsl_dir_rele(pdd, FTAG);
+}
+
+int
+dmu_objset_clone(const char *clone, const char *origin)
+{
+	dmu_objset_clone_arg_t doca;
+
+	doca.doca_clone = clone;
+	doca.doca_origin = origin;
+	doca.doca_cred = CRED();
+
+	return (dsl_sync_task(clone,
+	    dmu_objset_clone_check, dmu_objset_clone_sync, &doca,
+	    5, ZFS_SPACE_CHECK_NORMAL));
+}
+
+int
+dmu_objset_snapshot_one(const char *fsname, const char *snapname)
+{
+	int err;
+	char *longsnap = kmem_asprintf("%s@%s", fsname, snapname);
+	nvlist_t *snaps = fnvlist_alloc();
+
+	fnvlist_add_boolean(snaps, longsnap);
+	strfree(longsnap);
+	err = dsl_dataset_snapshot(snaps, NULL, NULL);
+	fnvlist_free(snaps);
+	return (err);
+}
+
+static void
+dmu_objset_sync_dnodes(list_t *list, list_t *newlist, dmu_tx_t *tx)
+{
+	dnode_t *dn;
+
+	while ((dn = list_head(list))) {
+		ASSERT(dn->dn_object != DMU_META_DNODE_OBJECT);
+		ASSERT(dn->dn_dbuf->db_data_pending);
+		/*
+		 * Initialize dn_zio outside dnode_sync() because the
+		 * meta-dnode needs to set it ouside dnode_sync().
+		 */
+		dn->dn_zio = dn->dn_dbuf->db_data_pending->dr_zio;
+		ASSERT(dn->dn_zio);
+
+		ASSERT3U(dn->dn_nlevels, <=, DN_MAX_LEVELS);
+		list_remove(list, dn);
+
+		if (newlist) {
+			(void) dnode_add_ref(dn, newlist);
+			list_insert_tail(newlist, dn);
+		}
+
+		dnode_sync(dn, tx);
+	}
+}
+
+/* ARGSUSED */
+static void
+dmu_objset_write_ready(zio_t *zio, arc_buf_t *abuf, void *arg)
+{
+	int i;
+
+	blkptr_t *bp = zio->io_bp;
+	objset_t *os = arg;
+	dnode_phys_t *dnp = &os->os_phys->os_meta_dnode;
+
+	ASSERT(!BP_IS_EMBEDDED(bp));
+	ASSERT3P(bp, ==, os->os_rootbp);
+	ASSERT3U(BP_GET_TYPE(bp), ==, DMU_OT_OBJSET);
+	ASSERT0(BP_GET_LEVEL(bp));
+
+	/*
+	 * Update rootbp fill count: it should be the number of objects
+	 * allocated in the object set (not counting the "special"
+	 * objects that are stored in the objset_phys_t -- the meta
+	 * dnode and user/group accounting objects).
+	 */
+	bp->blk_fill = 0;
+	for (i = 0; i < dnp->dn_nblkptr; i++)
+		bp->blk_fill += BP_GET_FILL(&dnp->dn_blkptr[i]);
+}
+
+/* ARGSUSED */
+static void
+dmu_objset_write_done(zio_t *zio, arc_buf_t *abuf, void *arg)
+{
+	blkptr_t *bp = zio->io_bp;
+	blkptr_t *bp_orig = &zio->io_bp_orig;
+	objset_t *os = arg;
+
+	if (zio->io_flags & ZIO_FLAG_IO_REWRITE) {
+		ASSERT(BP_EQUAL(bp, bp_orig));
+	} else {
+		dsl_dataset_t *ds = os->os_dsl_dataset;
+		dmu_tx_t *tx = os->os_synctx;
+
+		(void) dsl_dataset_block_kill(ds, bp_orig, tx, B_TRUE);
+		dsl_dataset_block_born(ds, bp, tx);
+	}
+}
+
+/* called from dsl */
+void
+dmu_objset_sync(objset_t *os, zio_t *pio, dmu_tx_t *tx)
+{
+	int txgoff;
+	zbookmark_phys_t zb;
+	zio_prop_t zp;
+	zio_t *zio;
+	list_t *list;
+	list_t *newlist = NULL;
+	dbuf_dirty_record_t *dr;
+
+	dprintf_ds(os->os_dsl_dataset, "txg=%llu\n", tx->tx_txg);
+
+	ASSERT(dmu_tx_is_syncing(tx));
+	/* XXX the write_done callback should really give us the tx... */
+	os->os_synctx = tx;
+
+	if (os->os_dsl_dataset == NULL) {
+		/*
+		 * This is the MOS.  If we have upgraded,
+		 * spa_max_replication() could change, so reset
+		 * os_copies here.
+		 */
+		os->os_copies = spa_max_replication(os->os_spa);
+	}
+
+	/*
+	 * Create the root block IO
+	 */
+	SET_BOOKMARK(&zb, os->os_dsl_dataset ?
+	    os->os_dsl_dataset->ds_object : DMU_META_OBJSET,
+	    ZB_ROOT_OBJECT, ZB_ROOT_LEVEL, ZB_ROOT_BLKID);
+	arc_release(os->os_phys_buf, &os->os_phys_buf);
+
+	dmu_write_policy(os, NULL, 0, 0, &zp);
+
+	zio = arc_write(pio, os->os_spa, tx->tx_txg,
+	    os->os_rootbp, os->os_phys_buf, DMU_OS_IS_L2CACHEABLE(os),
+	    DMU_OS_IS_L2COMPRESSIBLE(os), &zp, dmu_objset_write_ready,
+	    NULL, dmu_objset_write_done, os, ZIO_PRIORITY_ASYNC_WRITE,
+	    ZIO_FLAG_MUSTSUCCEED, &zb);
+
+	/*
+	 * Sync special dnodes - the parent IO for the sync is the root block
+	 */
+	DMU_META_DNODE(os)->dn_zio = zio;
+	dnode_sync(DMU_META_DNODE(os), tx);
+
+	os->os_phys->os_flags = os->os_flags;
+
+	if (DMU_USERUSED_DNODE(os) &&
+	    DMU_USERUSED_DNODE(os)->dn_type != DMU_OT_NONE) {
+		DMU_USERUSED_DNODE(os)->dn_zio = zio;
+		dnode_sync(DMU_USERUSED_DNODE(os), tx);
+		DMU_GROUPUSED_DNODE(os)->dn_zio = zio;
+		dnode_sync(DMU_GROUPUSED_DNODE(os), tx);
+	}
+
+	txgoff = tx->tx_txg & TXG_MASK;
+
+	if (dmu_objset_userused_enabled(os)) {
+		newlist = &os->os_synced_dnodes;
+		/*
+		 * We must create the list here because it uses the
+		 * dn_dirty_link[] of this txg.
+		 */
+		list_create(newlist, sizeof (dnode_t),
+		    offsetof(dnode_t, dn_dirty_link[txgoff]));
+	}
+
+	dmu_objset_sync_dnodes(&os->os_free_dnodes[txgoff], newlist, tx);
+	dmu_objset_sync_dnodes(&os->os_dirty_dnodes[txgoff], newlist, tx);
+
+	list = &DMU_META_DNODE(os)->dn_dirty_records[txgoff];
+	while ((dr = list_head(list))) {
+		ASSERT0(dr->dr_dbuf->db_level);
+		list_remove(list, dr);
+		if (dr->dr_zio)
+			zio_nowait(dr->dr_zio);
+	}
+	/*
+	 * Free intent log blocks up to this tx.
+	 */
+	zil_sync(os->os_zil, tx);
+	os->os_phys->os_zil_header = os->os_zil_header;
+	zio_nowait(zio);
+}
+
+boolean_t
+dmu_objset_is_dirty(objset_t *os, uint64_t txg)
+{
+	return (!list_is_empty(&os->os_dirty_dnodes[txg & TXG_MASK]) ||
+	    !list_is_empty(&os->os_free_dnodes[txg & TXG_MASK]));
+}
+
+static objset_used_cb_t *used_cbs[DMU_OST_NUMTYPES];
+
+void
+dmu_objset_register_type(dmu_objset_type_t ost, objset_used_cb_t *cb)
+{
+	used_cbs[ost] = cb;
+}
+
+boolean_t
+dmu_objset_userused_enabled(objset_t *os)
+{
+	return (spa_version(os->os_spa) >= SPA_VERSION_USERSPACE &&
+	    used_cbs[os->os_phys->os_type] != NULL &&
+	    DMU_USERUSED_DNODE(os) != NULL);
+}
+
+static void
+do_userquota_update(objset_t *os, uint64_t used, uint64_t flags,
+    uint64_t user, uint64_t group, boolean_t subtract, dmu_tx_t *tx)
+{
+	if ((flags & DNODE_FLAG_USERUSED_ACCOUNTED)) {
+		int64_t delta = DNODE_SIZE + used;
+		if (subtract)
+			delta = -delta;
+		VERIFY3U(0, ==, zap_increment_int(os, DMU_USERUSED_OBJECT,
+		    user, delta, tx));
+		VERIFY3U(0, ==, zap_increment_int(os, DMU_GROUPUSED_OBJECT,
+		    group, delta, tx));
+	}
+}
+
+void
+dmu_objset_do_userquota_updates(objset_t *os, dmu_tx_t *tx)
+{
+	dnode_t *dn;
+	list_t *list = &os->os_synced_dnodes;
+
+	ASSERT(list_head(list) == NULL || dmu_objset_userused_enabled(os));
+
+	while ((dn = list_head(list))) {
+		int flags;
+		ASSERT(!DMU_OBJECT_IS_SPECIAL(dn->dn_object));
+		ASSERT(dn->dn_phys->dn_type == DMU_OT_NONE ||
+		    dn->dn_phys->dn_flags &
+		    DNODE_FLAG_USERUSED_ACCOUNTED);
+
+		/* Allocate the user/groupused objects if necessary. */
+		if (DMU_USERUSED_DNODE(os)->dn_type == DMU_OT_NONE) {
+			VERIFY(0 == zap_create_claim(os,
+			    DMU_USERUSED_OBJECT,
+			    DMU_OT_USERGROUP_USED, DMU_OT_NONE, 0, tx));
+			VERIFY(0 == zap_create_claim(os,
+			    DMU_GROUPUSED_OBJECT,
+			    DMU_OT_USERGROUP_USED, DMU_OT_NONE, 0, tx));
+		}
+
+		/*
+		 * We intentionally modify the zap object even if the
+		 * net delta is zero.  Otherwise
+		 * the block of the zap obj could be shared between
+		 * datasets but need to be different between them after
+		 * a bprewrite.
+		 */
+
+		flags = dn->dn_id_flags;
+		ASSERT(flags);
+		if (flags & DN_ID_OLD_EXIST)  {
+			do_userquota_update(os, dn->dn_oldused, dn->dn_oldflags,
+			    dn->dn_olduid, dn->dn_oldgid, B_TRUE, tx);
+		}
+		if (flags & DN_ID_NEW_EXIST) {
+			do_userquota_update(os, DN_USED_BYTES(dn->dn_phys),
+			    dn->dn_phys->dn_flags,  dn->dn_newuid,
+			    dn->dn_newgid, B_FALSE, tx);
+		}
+
+		mutex_enter(&dn->dn_mtx);
+		dn->dn_oldused = 0;
+		dn->dn_oldflags = 0;
+		if (dn->dn_id_flags & DN_ID_NEW_EXIST) {
+			dn->dn_olduid = dn->dn_newuid;
+			dn->dn_oldgid = dn->dn_newgid;
+			dn->dn_id_flags |= DN_ID_OLD_EXIST;
+			if (dn->dn_bonuslen == 0)
+				dn->dn_id_flags |= DN_ID_CHKED_SPILL;
+			else
+				dn->dn_id_flags |= DN_ID_CHKED_BONUS;
+		}
+		dn->dn_id_flags &= ~(DN_ID_NEW_EXIST);
+		mutex_exit(&dn->dn_mtx);
+
+		list_remove(list, dn);
+		dnode_rele(dn, list);
+	}
+}
+
+/*
+ * Returns a pointer to data to find uid/gid from
+ *
+ * If a dirty record for transaction group that is syncing can't
+ * be found then NULL is returned.  In the NULL case it is assumed
+ * the uid/gid aren't changing.
+ */
+static void *
+dmu_objset_userquota_find_data(dmu_buf_impl_t *db, dmu_tx_t *tx)
+{
+	dbuf_dirty_record_t *dr, **drp;
+	void *data;
+
+	if (db->db_dirtycnt == 0)
+		return (db->db.db_data);  /* Nothing is changing */
+
+	for (drp = &db->db_last_dirty; (dr = *drp) != NULL; drp = &dr->dr_next)
+		if (dr->dr_txg == tx->tx_txg)
+			break;
+
+	if (dr == NULL) {
+		data = NULL;
+	} else {
+		dnode_t *dn;
+
+		DB_DNODE_ENTER(dr->dr_dbuf);
+		dn = DB_DNODE(dr->dr_dbuf);
+
+		if (dn->dn_bonuslen == 0 &&
+		    dr->dr_dbuf->db_blkid == DMU_SPILL_BLKID)
+			data = dr->dt.dl.dr_data->b_data;
+		else
+			data = dr->dt.dl.dr_data;
+
+		DB_DNODE_EXIT(dr->dr_dbuf);
+	}
+
+	return (data);
+}
+
+void
+dmu_objset_userquota_get_ids(dnode_t *dn, boolean_t before, dmu_tx_t *tx)
+{
+	objset_t *os = dn->dn_objset;
+	void *data = NULL;
+	dmu_buf_impl_t *db = NULL;
+	uint64_t *user = NULL;
+	uint64_t *group = NULL;
+	int flags = dn->dn_id_flags;
+	int error;
+	boolean_t have_spill = B_FALSE;
+
+	if (!dmu_objset_userused_enabled(dn->dn_objset))
+		return;
+
+	if (before && (flags & (DN_ID_CHKED_BONUS|DN_ID_OLD_EXIST|
+	    DN_ID_CHKED_SPILL)))
+		return;
+
+	if (before && dn->dn_bonuslen != 0)
+		data = DN_BONUS(dn->dn_phys);
+	else if (!before && dn->dn_bonuslen != 0) {
+		if (dn->dn_bonus) {
+			db = dn->dn_bonus;
+			mutex_enter(&db->db_mtx);
+			data = dmu_objset_userquota_find_data(db, tx);
+		} else {
+			data = DN_BONUS(dn->dn_phys);
+		}
+	} else if (dn->dn_bonuslen == 0 && dn->dn_bonustype == DMU_OT_SA) {
+			int rf = 0;
+
+			if (RW_WRITE_HELD(&dn->dn_struct_rwlock))
+				rf |= DB_RF_HAVESTRUCT;
+			error = dmu_spill_hold_by_dnode(dn,
+			    rf | DB_RF_MUST_SUCCEED,
+			    FTAG, (dmu_buf_t **)&db);
+			ASSERT(error == 0);
+			mutex_enter(&db->db_mtx);
+			data = (before) ? db->db.db_data :
+			    dmu_objset_userquota_find_data(db, tx);
+			have_spill = B_TRUE;
+	} else {
+		mutex_enter(&dn->dn_mtx);
+		dn->dn_id_flags |= DN_ID_CHKED_BONUS;
+		mutex_exit(&dn->dn_mtx);
+		return;
+	}
+
+	if (before) {
+		ASSERT(data);
+		user = &dn->dn_olduid;
+		group = &dn->dn_oldgid;
+	} else if (data) {
+		user = &dn->dn_newuid;
+		group = &dn->dn_newgid;
+	}
+
+	/*
+	 * Must always call the callback in case the object
+	 * type has changed and that type isn't an object type to track
+	 */
+	error = used_cbs[os->os_phys->os_type](dn->dn_bonustype, data,
+	    user, group);
+
+	/*
+	 * Preserve existing uid/gid when the callback can't determine
+	 * what the new uid/gid are and the callback returned EEXIST.
+	 * The EEXIST error tells us to just use the existing uid/gid.
+	 * If we don't know what the old values are then just assign
+	 * them to 0, since that is a new file  being created.
+	 */
+	if (!before && data == NULL && error == EEXIST) {
+		if (flags & DN_ID_OLD_EXIST) {
+			dn->dn_newuid = dn->dn_olduid;
+			dn->dn_newgid = dn->dn_oldgid;
+		} else {
+			dn->dn_newuid = 0;
+			dn->dn_newgid = 0;
+		}
+		error = 0;
+	}
+
+	if (db)
+		mutex_exit(&db->db_mtx);
+
+	mutex_enter(&dn->dn_mtx);
+	if (error == 0 && before)
+		dn->dn_id_flags |= DN_ID_OLD_EXIST;
+	if (error == 0 && !before)
+		dn->dn_id_flags |= DN_ID_NEW_EXIST;
+
+	if (have_spill) {
+		dn->dn_id_flags |= DN_ID_CHKED_SPILL;
+	} else {
+		dn->dn_id_flags |= DN_ID_CHKED_BONUS;
+	}
+	mutex_exit(&dn->dn_mtx);
+	if (have_spill)
+		dmu_buf_rele((dmu_buf_t *)db, FTAG);
+}
+
+boolean_t
+dmu_objset_userspace_present(objset_t *os)
+{
+	return (os->os_phys->os_flags &
+	    OBJSET_FLAG_USERACCOUNTING_COMPLETE);
+}
+
+int
+dmu_objset_userspace_upgrade(objset_t *os)
+{
+	uint64_t obj;
+	int err = 0;
+
+	if (dmu_objset_userspace_present(os))
+		return (0);
+	if (!dmu_objset_userused_enabled(os))
+		return (SET_ERROR(ENOTSUP));
+	if (dmu_objset_is_snapshot(os))
+		return (SET_ERROR(EINVAL));
+
+	/*
+	 * We simply need to mark every object dirty, so that it will be
+	 * synced out and now accounted.  If this is called
+	 * concurrently, or if we already did some work before crashing,
+	 * that's fine, since we track each object's accounted state
+	 * independently.
+	 */
+
+	for (obj = 0; err == 0; err = dmu_object_next(os, &obj, FALSE, 0)) {
+		dmu_tx_t *tx;
+		dmu_buf_t *db;
+		int objerr;
+
+		if (issig(JUSTLOOKING) && issig(FORREAL))
+			return (SET_ERROR(EINTR));
+
+		objerr = dmu_bonus_hold(os, obj, FTAG, &db);
+		if (objerr != 0)
+			continue;
+		tx = dmu_tx_create(os);
+		dmu_tx_hold_bonus(tx, obj);
+		objerr = dmu_tx_assign(tx, TXG_WAIT);
+		if (objerr != 0) {
+			dmu_tx_abort(tx);
+			continue;
+		}
+		dmu_buf_will_dirty(db, tx);
+		dmu_buf_rele(db, FTAG);
+		dmu_tx_commit(tx);
+	}
+
+	os->os_flags |= OBJSET_FLAG_USERACCOUNTING_COMPLETE;
+	txg_wait_synced(dmu_objset_pool(os), 0);
+	return (0);
+}
+
+void
+dmu_objset_space(objset_t *os, uint64_t *refdbytesp, uint64_t *availbytesp,
+    uint64_t *usedobjsp, uint64_t *availobjsp)
+{
+	dsl_dataset_space(os->os_dsl_dataset, refdbytesp, availbytesp,
+	    usedobjsp, availobjsp);
+}
+
+uint64_t
+dmu_objset_fsid_guid(objset_t *os)
+{
+	return (dsl_dataset_fsid_guid(os->os_dsl_dataset));
+}
+
+void
+dmu_objset_fast_stat(objset_t *os, dmu_objset_stats_t *stat)
+{
+	stat->dds_type = os->os_phys->os_type;
+	if (os->os_dsl_dataset)
+		dsl_dataset_fast_stat(os->os_dsl_dataset, stat);
+}
+
+void
+dmu_objset_stats(objset_t *os, nvlist_t *nv)
+{
+	ASSERT(os->os_dsl_dataset ||
+	    os->os_phys->os_type == DMU_OST_META);
+
+	if (os->os_dsl_dataset != NULL)
+		dsl_dataset_stats(os->os_dsl_dataset, nv);
+
+	dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_TYPE,
+	    os->os_phys->os_type);
+	dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_USERACCOUNTING,
+	    dmu_objset_userspace_present(os));
+}
+
+int
+dmu_objset_is_snapshot(objset_t *os)
+{
+	if (os->os_dsl_dataset != NULL)
+		return (os->os_dsl_dataset->ds_is_snapshot);
+	else
+		return (B_FALSE);
+}
+
+int
+dmu_snapshot_realname(objset_t *os, char *name, char *real, int maxlen,
+    boolean_t *conflict)
+{
+	dsl_dataset_t *ds = os->os_dsl_dataset;
+	uint64_t ignored;
+
+	if (dsl_dataset_phys(ds)->ds_snapnames_zapobj == 0)
+		return (SET_ERROR(ENOENT));
+
+	return (zap_lookup_norm(ds->ds_dir->dd_pool->dp_meta_objset,
+	    dsl_dataset_phys(ds)->ds_snapnames_zapobj, name, 8, 1, &ignored,
+	    MT_FIRST, real, maxlen, conflict));
+}
+
+int
+dmu_snapshot_list_next(objset_t *os, int namelen, char *name,
+    uint64_t *idp, uint64_t *offp, boolean_t *case_conflict)
+{
+	dsl_dataset_t *ds = os->os_dsl_dataset;
+	zap_cursor_t cursor;
+	zap_attribute_t attr;
+
+	ASSERT(dsl_pool_config_held(dmu_objset_pool(os)));
+
+	if (dsl_dataset_phys(ds)->ds_snapnames_zapobj == 0)
+		return (SET_ERROR(ENOENT));
+
+	zap_cursor_init_serialized(&cursor,
+	    ds->ds_dir->dd_pool->dp_meta_objset,
+	    dsl_dataset_phys(ds)->ds_snapnames_zapobj, *offp);
+
+	if (zap_cursor_retrieve(&cursor, &attr) != 0) {
+		zap_cursor_fini(&cursor);
+		return (SET_ERROR(ENOENT));
+	}
+
+	if (strlen(attr.za_name) + 1 > namelen) {
+		zap_cursor_fini(&cursor);
+		return (SET_ERROR(ENAMETOOLONG));
+	}
+
+	(void) strcpy(name, attr.za_name);
+	if (idp)
+		*idp = attr.za_first_integer;
+	if (case_conflict)
+		*case_conflict = attr.za_normalization_conflict;
+	zap_cursor_advance(&cursor);
+	*offp = zap_cursor_serialize(&cursor);
+	zap_cursor_fini(&cursor);
+
+	return (0);
+}
+
+int
+dmu_snapshot_lookup(objset_t *os, const char *name, uint64_t *value)
+{
+	return (dsl_dataset_snap_lookup(os->os_dsl_dataset, name, value));
+}
+
+int
+dmu_dir_list_next(objset_t *os, int namelen, char *name,
+    uint64_t *idp, uint64_t *offp)
+{
+	dsl_dir_t *dd = os->os_dsl_dataset->ds_dir;
+	zap_cursor_t cursor;
+	zap_attribute_t attr;
+
+	/* there is no next dir on a snapshot! */
+	if (os->os_dsl_dataset->ds_object !=
+	    dsl_dir_phys(dd)->dd_head_dataset_obj)
+		return (SET_ERROR(ENOENT));
+
+	zap_cursor_init_serialized(&cursor,
+	    dd->dd_pool->dp_meta_objset,
+	    dsl_dir_phys(dd)->dd_child_dir_zapobj, *offp);
+
+	if (zap_cursor_retrieve(&cursor, &attr) != 0) {
+		zap_cursor_fini(&cursor);
+		return (SET_ERROR(ENOENT));
+	}
+
+	if (strlen(attr.za_name) + 1 > namelen) {
+		zap_cursor_fini(&cursor);
+		return (SET_ERROR(ENAMETOOLONG));
+	}
+
+	(void) strcpy(name, attr.za_name);
+	if (idp)
+		*idp = attr.za_first_integer;
+	zap_cursor_advance(&cursor);
+	*offp = zap_cursor_serialize(&cursor);
+	zap_cursor_fini(&cursor);
+
+	return (0);
+}
+
+typedef struct dmu_objset_find_ctx {
+	taskq_t		*dc_tq;
+	dsl_pool_t	*dc_dp;
+	uint64_t	dc_ddobj;
+	int		(*dc_func)(dsl_pool_t *, dsl_dataset_t *, void *);
+	void		*dc_arg;
+	int		dc_flags;
+	kmutex_t	*dc_error_lock;
+	int		*dc_error;
+} dmu_objset_find_ctx_t;
+
+static void
+dmu_objset_find_dp_impl(dmu_objset_find_ctx_t *dcp)
+{
+	dsl_pool_t *dp = dcp->dc_dp;
+	dmu_objset_find_ctx_t *child_dcp;
+	dsl_dir_t *dd;
+	dsl_dataset_t *ds;
+	zap_cursor_t zc;
+	zap_attribute_t *attr;
+	uint64_t thisobj;
+	int err = 0;
+
+	/* don't process if there already was an error */
+	if (*dcp->dc_error != 0)
+		goto out;
+
+	err = dsl_dir_hold_obj(dp, dcp->dc_ddobj, NULL, FTAG, &dd);
+	if (err != 0)
+		goto out;
+
+	/* Don't visit hidden ($MOS & $ORIGIN) objsets. */
+	if (dd->dd_myname[0] == '$') {
+		dsl_dir_rele(dd, FTAG);
+		goto out;
+	}
+
+	thisobj = dsl_dir_phys(dd)->dd_head_dataset_obj;
+	attr = kmem_alloc(sizeof (zap_attribute_t), KM_SLEEP);
+
+	/*
+	 * Iterate over all children.
+	 */
+	if (dcp->dc_flags & DS_FIND_CHILDREN) {
+		for (zap_cursor_init(&zc, dp->dp_meta_objset,
+		    dsl_dir_phys(dd)->dd_child_dir_zapobj);
+		    zap_cursor_retrieve(&zc, attr) == 0;
+		    (void) zap_cursor_advance(&zc)) {
+			ASSERT3U(attr->za_integer_length, ==,
+			    sizeof (uint64_t));
+			ASSERT3U(attr->za_num_integers, ==, 1);
+
+			child_dcp = kmem_alloc(sizeof (*child_dcp), KM_SLEEP);
+			*child_dcp = *dcp;
+			child_dcp->dc_ddobj = attr->za_first_integer;
+			if (dcp->dc_tq != NULL)
+				(void) taskq_dispatch(dcp->dc_tq,
+				    dmu_objset_find_dp_cb, child_dcp, TQ_SLEEP);
+			else
+				dmu_objset_find_dp_impl(child_dcp);
+		}
+		zap_cursor_fini(&zc);
+	}
+
+	/*
+	 * Iterate over all snapshots.
+	 */
+	if (dcp->dc_flags & DS_FIND_SNAPSHOTS) {
+		dsl_dataset_t *ds;
+		err = dsl_dataset_hold_obj(dp, thisobj, FTAG, &ds);
+
+		if (err == 0) {
+			uint64_t snapobj;
+
+			snapobj = dsl_dataset_phys(ds)->ds_snapnames_zapobj;
+			dsl_dataset_rele(ds, FTAG);
+
+			for (zap_cursor_init(&zc, dp->dp_meta_objset, snapobj);
+			    zap_cursor_retrieve(&zc, attr) == 0;
+			    (void) zap_cursor_advance(&zc)) {
+				ASSERT3U(attr->za_integer_length, ==,
+				    sizeof (uint64_t));
+				ASSERT3U(attr->za_num_integers, ==, 1);
+
+				err = dsl_dataset_hold_obj(dp,
+				    attr->za_first_integer, FTAG, &ds);
+				if (err != 0)
+					break;
+				err = dcp->dc_func(dp, ds, dcp->dc_arg);
+				dsl_dataset_rele(ds, FTAG);
+				if (err != 0)
+					break;
+			}
+			zap_cursor_fini(&zc);
+		}
+	}
+
+	dsl_dir_rele(dd, FTAG);
+	kmem_free(attr, sizeof (zap_attribute_t));
+
+	if (err != 0)
+		goto out;
+
+	/*
+	 * Apply to self.
+	 */
+	err = dsl_dataset_hold_obj(dp, thisobj, FTAG, &ds);
+	if (err != 0)
+		goto out;
+	err = dcp->dc_func(dp, ds, dcp->dc_arg);
+	dsl_dataset_rele(ds, FTAG);
+
+out:
+	if (err != 0) {
+		mutex_enter(dcp->dc_error_lock);
+		/* only keep first error */
+		if (*dcp->dc_error == 0)
+			*dcp->dc_error = err;
+		mutex_exit(dcp->dc_error_lock);
+	}
+
+	kmem_free(dcp, sizeof (*dcp));
+}
+
+static void
+dmu_objset_find_dp_cb(void *arg)
+{
+	dmu_objset_find_ctx_t *dcp = arg;
+	dsl_pool_t *dp = dcp->dc_dp;
+
+	/*
+	 * We need to get a pool_config_lock here, as there are several
+	 * asssert(pool_config_held) down the stack. Getting a lock via
+	 * dsl_pool_config_enter is risky, as it might be stalled by a
+	 * pending writer. This would deadlock, as the write lock can
+	 * only be granted when our parent thread gives up the lock.
+	 * The _prio interface gives us priority over a pending writer.
+	 */
+	dsl_pool_config_enter_prio(dp, FTAG);
+
+	dmu_objset_find_dp_impl(dcp);
+
+	dsl_pool_config_exit(dp, FTAG);
+}
+
+/*
+ * Find objsets under and including ddobj, call func(ds) on each.
+ * The order for the enumeration is completely undefined.
+ * func is called with dsl_pool_config held.
+ */
+int
+dmu_objset_find_dp(dsl_pool_t *dp, uint64_t ddobj,
+    int func(dsl_pool_t *, dsl_dataset_t *, void *), void *arg, int flags)
+{
+	int error = 0;
+	taskq_t *tq = NULL;
+	int ntasks;
+	dmu_objset_find_ctx_t *dcp;
+	kmutex_t err_lock;
+
+	mutex_init(&err_lock, NULL, MUTEX_DEFAULT, NULL);
+	dcp = kmem_alloc(sizeof (*dcp), KM_SLEEP);
+	dcp->dc_tq = NULL;
+	dcp->dc_dp = dp;
+	dcp->dc_ddobj = ddobj;
+	dcp->dc_func = func;
+	dcp->dc_arg = arg;
+	dcp->dc_flags = flags;
+	dcp->dc_error_lock = &err_lock;
+	dcp->dc_error = &error;
+
+	if ((flags & DS_FIND_SERIALIZE) || dsl_pool_config_held_writer(dp)) {
+		/*
+		 * In case a write lock is held we can't make use of
+		 * parallelism, as down the stack of the worker threads
+		 * the lock is asserted via dsl_pool_config_held.
+		 * In case of a read lock this is solved by getting a read
+		 * lock in each worker thread, which isn't possible in case
+		 * of a writer lock. So we fall back to the synchronous path
+		 * here.
+		 * In the future it might be possible to get some magic into
+		 * dsl_pool_config_held in a way that it returns true for
+		 * the worker threads so that a single lock held from this
+		 * thread suffices. For now, stay single threaded.
+		 */
+		dmu_objset_find_dp_impl(dcp);
+
+		return (error);
+	}
+
+	ntasks = dmu_find_threads;
+	if (ntasks == 0)
+		ntasks = vdev_count_leaves(dp->dp_spa) * 4;
+	tq = taskq_create("dmu_objset_find", ntasks, maxclsyspri, ntasks,
+	    INT_MAX, 0);
+	if (tq == NULL) {
+		kmem_free(dcp, sizeof (*dcp));
+		return (SET_ERROR(ENOMEM));
+	}
+	dcp->dc_tq = tq;
+
+	/* dcp will be freed by task */
+	(void) taskq_dispatch(tq, dmu_objset_find_dp_cb, dcp, TQ_SLEEP);
+
+	/*
+	 * PORTING: this code relies on the property of taskq_wait to wait
+	 * until no more tasks are queued and no more tasks are active. As
+	 * we always queue new tasks from within other tasks, task_wait
+	 * reliably waits for the full recursion to finish, even though we
+	 * enqueue new tasks after taskq_wait has been called.
+	 * On platforms other than illumos, taskq_wait may not have this
+	 * property.
+	 */
+	taskq_wait(tq);
+	taskq_destroy(tq);
+	mutex_destroy(&err_lock);
+
+	return (error);
+}
+
+/*
+ * Find all objsets under name, and for each, call 'func(child_name, arg)'.
+ * The dp_config_rwlock must not be held when this is called, and it
+ * will not be held when the callback is called.
+ * Therefore this function should only be used when the pool is not changing
+ * (e.g. in syncing context), or the callback can deal with the possible races.
+ */
+static int
+dmu_objset_find_impl(spa_t *spa, const char *name,
+    int func(const char *, void *), void *arg, int flags)
+{
+	dsl_dir_t *dd;
+	dsl_pool_t *dp = spa_get_dsl(spa);
+	dsl_dataset_t *ds;
+	zap_cursor_t zc;
+	zap_attribute_t *attr;
+	char *child;
+	uint64_t thisobj;
+	int err;
+
+	dsl_pool_config_enter(dp, FTAG);
+
+	err = dsl_dir_hold(dp, name, FTAG, &dd, NULL);
+	if (err != 0) {
+		dsl_pool_config_exit(dp, FTAG);
+		return (err);
+	}
+
+	/* Don't visit hidden ($MOS & $ORIGIN) objsets. */
+	if (dd->dd_myname[0] == '$') {
+		dsl_dir_rele(dd, FTAG);
+		dsl_pool_config_exit(dp, FTAG);
+		return (0);
+	}
+
+	thisobj = dsl_dir_phys(dd)->dd_head_dataset_obj;
+	attr = kmem_alloc(sizeof (zap_attribute_t), KM_SLEEP);
+
+	/*
+	 * Iterate over all children.
+	 */
+	if (flags & DS_FIND_CHILDREN) {
+		for (zap_cursor_init(&zc, dp->dp_meta_objset,
+		    dsl_dir_phys(dd)->dd_child_dir_zapobj);
+		    zap_cursor_retrieve(&zc, attr) == 0;
+		    (void) zap_cursor_advance(&zc)) {
+			ASSERT3U(attr->za_integer_length, ==,
+			    sizeof (uint64_t));
+			ASSERT3U(attr->za_num_integers, ==, 1);
+
+			child = kmem_asprintf("%s/%s", name, attr->za_name);
+			dsl_pool_config_exit(dp, FTAG);
+			err = dmu_objset_find_impl(spa, child,
+			    func, arg, flags);
+			dsl_pool_config_enter(dp, FTAG);
+			strfree(child);
+			if (err != 0)
+				break;
+		}
+		zap_cursor_fini(&zc);
+
+		if (err != 0) {
+			dsl_dir_rele(dd, FTAG);
+			dsl_pool_config_exit(dp, FTAG);
+			kmem_free(attr, sizeof (zap_attribute_t));
+			return (err);
+		}
+	}
+
+	/*
+	 * Iterate over all snapshots.
+	 */
+	if (flags & DS_FIND_SNAPSHOTS) {
+		err = dsl_dataset_hold_obj(dp, thisobj, FTAG, &ds);
+
+		if (err == 0) {
+			uint64_t snapobj;
+
+			snapobj = dsl_dataset_phys(ds)->ds_snapnames_zapobj;
+			dsl_dataset_rele(ds, FTAG);
+
+			for (zap_cursor_init(&zc, dp->dp_meta_objset, snapobj);
+			    zap_cursor_retrieve(&zc, attr) == 0;
+			    (void) zap_cursor_advance(&zc)) {
+				ASSERT3U(attr->za_integer_length, ==,
+				    sizeof (uint64_t));
+				ASSERT3U(attr->za_num_integers, ==, 1);
+
+				child = kmem_asprintf("%s@%s",
+				    name, attr->za_name);
+				dsl_pool_config_exit(dp, FTAG);
+				err = func(child, arg);
+				dsl_pool_config_enter(dp, FTAG);
+				strfree(child);
+				if (err != 0)
+					break;
+			}
+			zap_cursor_fini(&zc);
+		}
+	}
+
+	dsl_dir_rele(dd, FTAG);
+	kmem_free(attr, sizeof (zap_attribute_t));
+	dsl_pool_config_exit(dp, FTAG);
+
+	if (err != 0)
+		return (err);
+
+	/* Apply to self. */
+	return (func(name, arg));
+}
+
+/*
+ * See comment above dmu_objset_find_impl().
+ */
+int
+dmu_objset_find(char *name, int func(const char *, void *), void *arg,
+    int flags)
+{
+	spa_t *spa;
+	int error;
+
+	error = spa_open(name, &spa, FTAG);
+	if (error != 0)
+		return (error);
+	error = dmu_objset_find_impl(spa, name, func, arg, flags);
+	spa_close(spa, FTAG);
+	return (error);
+}
+
+void
+dmu_objset_set_user(objset_t *os, void *user_ptr)
+{
+	ASSERT(MUTEX_HELD(&os->os_user_ptr_lock));
+	os->os_user_ptr = user_ptr;
+}
+
+void *
+dmu_objset_get_user(objset_t *os)
+{
+	ASSERT(MUTEX_HELD(&os->os_user_ptr_lock));
+	return (os->os_user_ptr);
+}
+
+/*
+ * Determine name of filesystem, given name of snapshot.
+ * buf must be at least MAXNAMELEN bytes
+ */
+int
+dmu_fsname(const char *snapname, char *buf)
+{
+	char *atp = strchr(snapname, '@');
+	if (atp == NULL)
+		return (SET_ERROR(EINVAL));
+	if (atp - snapname >= MAXNAMELEN)
+		return (SET_ERROR(ENAMETOOLONG));
+	(void) strlcpy(buf, snapname, atp - snapname + 1);
+	return (0);
+}
+
+#if defined(_KERNEL) && defined(HAVE_SPL)
+EXPORT_SYMBOL(dmu_objset_zil);
+EXPORT_SYMBOL(dmu_objset_pool);
+EXPORT_SYMBOL(dmu_objset_ds);
+EXPORT_SYMBOL(dmu_objset_type);
+EXPORT_SYMBOL(dmu_objset_name);
+EXPORT_SYMBOL(dmu_objset_hold);
+EXPORT_SYMBOL(dmu_objset_own);
+EXPORT_SYMBOL(dmu_objset_rele);
+EXPORT_SYMBOL(dmu_objset_disown);
+EXPORT_SYMBOL(dmu_objset_from_ds);
+EXPORT_SYMBOL(dmu_objset_create);
+EXPORT_SYMBOL(dmu_objset_clone);
+EXPORT_SYMBOL(dmu_objset_stats);
+EXPORT_SYMBOL(dmu_objset_fast_stat);
+EXPORT_SYMBOL(dmu_objset_spa);
+EXPORT_SYMBOL(dmu_objset_space);
+EXPORT_SYMBOL(dmu_objset_fsid_guid);
+EXPORT_SYMBOL(dmu_objset_find);
+EXPORT_SYMBOL(dmu_objset_byteswap);
+EXPORT_SYMBOL(dmu_objset_evict_dbufs);
+EXPORT_SYMBOL(dmu_objset_snap_cmtime);
+
+EXPORT_SYMBOL(dmu_objset_sync);
+EXPORT_SYMBOL(dmu_objset_is_dirty);
+EXPORT_SYMBOL(dmu_objset_create_impl);
+EXPORT_SYMBOL(dmu_objset_open_impl);
+EXPORT_SYMBOL(dmu_objset_evict);
+EXPORT_SYMBOL(dmu_objset_register_type);
+EXPORT_SYMBOL(dmu_objset_do_userquota_updates);
+EXPORT_SYMBOL(dmu_objset_userquota_get_ids);
+EXPORT_SYMBOL(dmu_objset_userused_enabled);
+EXPORT_SYMBOL(dmu_objset_userspace_upgrade);
+EXPORT_SYMBOL(dmu_objset_userspace_present);
+#endif
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/module/zfs/dmu_send.c
@@ -0,0 +1,2277 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011 by Delphix. All rights reserved.
+ * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
+ * Copyright (c) 2014, Joyent, Inc. All rights reserved.
+ * Copyright (c) 2011, 2014 by Delphix. All rights reserved.
+ * Copyright (c) 2016 Actifio, Inc. All rights reserved.
+ */
+
+#include <sys/dmu.h>
+#include <sys/dmu_impl.h>
+#include <sys/dmu_tx.h>
+#include <sys/dbuf.h>
+#include <sys/dnode.h>
+#include <sys/zfs_context.h>
+#include <sys/dmu_objset.h>
+#include <sys/dmu_traverse.h>
+#include <sys/dsl_dataset.h>
+#include <sys/dsl_dir.h>
+#include <sys/dsl_prop.h>
+#include <sys/dsl_pool.h>
+#include <sys/dsl_synctask.h>
+#include <sys/spa_impl.h>
+#include <sys/zfs_ioctl.h>
+#include <sys/zap.h>
+#include <sys/zio_checksum.h>
+#include <sys/zfs_znode.h>
+#include <zfs_fletcher.h>
+#include <sys/avl.h>
+#include <sys/ddt.h>
+#include <sys/zfs_onexit.h>
+#include <sys/dmu_send.h>
+#include <sys/dsl_destroy.h>
+#include <sys/blkptr.h>
+#include <sys/dsl_bookmark.h>
+#include <sys/zfeature.h>
+#include <sys/zvol.h>
+
+/* Set this tunable to TRUE to replace corrupt data with 0x2f5baddb10c */
+int zfs_send_corrupt_data = B_FALSE;
+
+static char *dmu_recv_tag = "dmu_recv_tag";
+static const char *recv_clone_name = "%recv";
+
+typedef struct dump_bytes_io {
+	dmu_sendarg_t	*dbi_dsp;
+	void		*dbi_buf;
+	int		dbi_len;
+} dump_bytes_io_t;
+
+static void
+dump_bytes_strategy(void *arg)
+{
+	dump_bytes_io_t *dbi = (dump_bytes_io_t *)arg;
+	dmu_sendarg_t *dsp = dbi->dbi_dsp;
+	dsl_dataset_t *ds = dsp->dsa_os->os_dsl_dataset;
+	ssize_t resid; /* have to get resid to get detailed errno */
+	ASSERT0(dbi->dbi_len % 8);
+
+	fletcher_4_incremental_native(dbi->dbi_buf, dbi->dbi_len, &dsp->dsa_zc);
+	dsp->dsa_err = vn_rdwr(UIO_WRITE, dsp->dsa_vp,
+	    (caddr_t)dbi->dbi_buf, dbi->dbi_len,
+	    0, UIO_SYSSPACE, FAPPEND, RLIM64_INFINITY, CRED(), &resid);
+
+	mutex_enter(&ds->ds_sendstream_lock);
+	*dsp->dsa_off += dbi->dbi_len;
+	mutex_exit(&ds->ds_sendstream_lock);
+}
+
+static int
+dump_bytes(dmu_sendarg_t *dsp, void *buf, int len)
+{
+	dump_bytes_io_t dbi;
+
+	dbi.dbi_dsp = dsp;
+	dbi.dbi_buf = buf;
+	dbi.dbi_len = len;
+
+	/*
+	 * The vn_rdwr() call is performed in a taskq to ensure that there is
+	 * always enough stack space to write safely to the target filesystem.
+	 * The ZIO_TYPE_FREE threads are used because there can be a lot of
+	 * them and they are used in vdev_file.c for a similar purpose.
+	 */
+	spa_taskq_dispatch_sync(dmu_objset_spa(dsp->dsa_os), ZIO_TYPE_FREE,
+	    ZIO_TASKQ_ISSUE, dump_bytes_strategy, &dbi, TQ_SLEEP);
+
+	return (dsp->dsa_err);
+}
+
+static int
+dump_free(dmu_sendarg_t *dsp, uint64_t object, uint64_t offset,
+    uint64_t length)
+{
+	struct drr_free *drrf = &(dsp->dsa_drr->drr_u.drr_free);
+
+	/*
+	 * When we receive a free record, dbuf_free_range() assumes
+	 * that the receiving system doesn't have any dbufs in the range
+	 * being freed.  This is always true because there is a one-record
+	 * constraint: we only send one WRITE record for any given
+	 * object+offset.  We know that the one-record constraint is
+	 * true because we always send data in increasing order by
+	 * object,offset.
+	 *
+	 * If the increasing-order constraint ever changes, we should find
+	 * another way to assert that the one-record constraint is still
+	 * satisfied.
+	 */
+	ASSERT(object > dsp->dsa_last_data_object ||
+	    (object == dsp->dsa_last_data_object &&
+	    offset > dsp->dsa_last_data_offset));
+
+	/*
+	 * If we are doing a non-incremental send, then there can't
+	 * be any data in the dataset we're receiving into.  Therefore
+	 * a free record would simply be a no-op.  Save space by not
+	 * sending it to begin with.
+	 */
+	if (!dsp->dsa_incremental)
+		return (0);
+
+	if (length != -1ULL && offset + length < offset)
+		length = -1ULL;
+
+	/*
+	 * If there is a pending op, but it's not PENDING_FREE, push it out,
+	 * since free block aggregation can only be done for blocks of the
+	 * same type (i.e., DRR_FREE records can only be aggregated with
+	 * other DRR_FREE records.  DRR_FREEOBJECTS records can only be
+	 * aggregated with other DRR_FREEOBJECTS records.
+	 */
+	if (dsp->dsa_pending_op != PENDING_NONE &&
+	    dsp->dsa_pending_op != PENDING_FREE) {
+		if (dump_bytes(dsp, dsp->dsa_drr,
+		    sizeof (dmu_replay_record_t)) != 0)
+			return (SET_ERROR(EINTR));
+		dsp->dsa_pending_op = PENDING_NONE;
+	}
+
+	if (dsp->dsa_pending_op == PENDING_FREE) {
+		/*
+		 * There should never be a PENDING_FREE if length is -1
+		 * (because dump_dnode is the only place where this
+		 * function is called with a -1, and only after flushing
+		 * any pending record).
+		 */
+		ASSERT(length != -1ULL);
+		/*
+		 * Check to see whether this free block can be aggregated
+		 * with pending one.
+		 */
+		if (drrf->drr_object == object && drrf->drr_offset +
+		    drrf->drr_length == offset) {
+			drrf->drr_length += length;
+			return (0);
+		} else {
+			/* not a continuation.  Push out pending record */
+			if (dump_bytes(dsp, dsp->dsa_drr,
+			    sizeof (dmu_replay_record_t)) != 0)
+				return (SET_ERROR(EINTR));
+			dsp->dsa_pending_op = PENDING_NONE;
+		}
+	}
+	/* create a FREE record and make it pending */
+	bzero(dsp->dsa_drr, sizeof (dmu_replay_record_t));
+	dsp->dsa_drr->drr_type = DRR_FREE;
+	drrf->drr_object = object;
+	drrf->drr_offset = offset;
+	drrf->drr_length = length;
+	drrf->drr_toguid = dsp->dsa_toguid;
+	if (length == -1ULL) {
+		if (dump_bytes(dsp, dsp->dsa_drr,
+		    sizeof (dmu_replay_record_t)) != 0)
+			return (SET_ERROR(EINTR));
+	} else {
+		dsp->dsa_pending_op = PENDING_FREE;
+	}
+
+	return (0);
+}
+
+static int
+dump_write(dmu_sendarg_t *dsp, dmu_object_type_t type,
+    uint64_t object, uint64_t offset, int blksz, const blkptr_t *bp, void *data)
+{
+	struct drr_write *drrw = &(dsp->dsa_drr->drr_u.drr_write);
+
+	/*
+	 * We send data in increasing object, offset order.
+	 * See comment in dump_free() for details.
+	 */
+	ASSERT(object > dsp->dsa_last_data_object ||
+	    (object == dsp->dsa_last_data_object &&
+	    offset > dsp->dsa_last_data_offset));
+	dsp->dsa_last_data_object = object;
+	dsp->dsa_last_data_offset = offset + blksz - 1;
+
+	/*
+	 * If there is any kind of pending aggregation (currently either
+	 * a grouping of free objects or free blocks), push it out to
+	 * the stream, since aggregation can't be done across operations
+	 * of different types.
+	 */
+	if (dsp->dsa_pending_op != PENDING_NONE) {
+		if (dump_bytes(dsp, dsp->dsa_drr,
+		    sizeof (dmu_replay_record_t)) != 0)
+			return (SET_ERROR(EINTR));
+		dsp->dsa_pending_op = PENDING_NONE;
+	}
+	/* write a DATA record */
+	bzero(dsp->dsa_drr, sizeof (dmu_replay_record_t));
+	dsp->dsa_drr->drr_type = DRR_WRITE;
+	drrw->drr_object = object;
+	drrw->drr_type = type;
+	drrw->drr_offset = offset;
+	drrw->drr_length = blksz;
+	drrw->drr_toguid = dsp->dsa_toguid;
+	if (bp == NULL || BP_IS_EMBEDDED(bp)) {
+		/*
+		 * There's no pre-computed checksum for partial-block
+		 * writes or embedded BP's, so (like
+		 * fletcher4-checkummed blocks) userland will have to
+		 * compute a dedup-capable checksum itself.
+		 */
+		drrw->drr_checksumtype = ZIO_CHECKSUM_OFF;
+	} else {
+		drrw->drr_checksumtype = BP_GET_CHECKSUM(bp);
+		if (zio_checksum_table[drrw->drr_checksumtype].ci_dedup)
+			drrw->drr_checksumflags |= DRR_CHECKSUM_DEDUP;
+		DDK_SET_LSIZE(&drrw->drr_key, BP_GET_LSIZE(bp));
+		DDK_SET_PSIZE(&drrw->drr_key, BP_GET_PSIZE(bp));
+		DDK_SET_COMPRESS(&drrw->drr_key, BP_GET_COMPRESS(bp));
+		drrw->drr_key.ddk_cksum = bp->blk_cksum;
+	}
+
+	if (dump_bytes(dsp, dsp->dsa_drr, sizeof (dmu_replay_record_t)) != 0)
+		return (SET_ERROR(EINTR));
+	if (dump_bytes(dsp, data, blksz) != 0)
+		return (SET_ERROR(EINTR));
+	return (0);
+}
+
+static int
+dump_write_embedded(dmu_sendarg_t *dsp, uint64_t object, uint64_t offset,
+    int blksz, const blkptr_t *bp)
+{
+	char buf[BPE_PAYLOAD_SIZE];
+	struct drr_write_embedded *drrw =
+	    &(dsp->dsa_drr->drr_u.drr_write_embedded);
+
+	if (dsp->dsa_pending_op != PENDING_NONE) {
+		if (dump_bytes(dsp, dsp->dsa_drr,
+		    sizeof (dmu_replay_record_t)) != 0)
+			return (EINTR);
+		dsp->dsa_pending_op = PENDING_NONE;
+	}
+
+	ASSERT(BP_IS_EMBEDDED(bp));
+
+	bzero(dsp->dsa_drr, sizeof (dmu_replay_record_t));
+	dsp->dsa_drr->drr_type = DRR_WRITE_EMBEDDED;
+	drrw->drr_object = object;
+	drrw->drr_offset = offset;
+	drrw->drr_length = blksz;
+	drrw->drr_toguid = dsp->dsa_toguid;
+	drrw->drr_compression = BP_GET_COMPRESS(bp);
+	drrw->drr_etype = BPE_GET_ETYPE(bp);
+	drrw->drr_lsize = BPE_GET_LSIZE(bp);
+	drrw->drr_psize = BPE_GET_PSIZE(bp);
+
+	decode_embedded_bp_compressed(bp, buf);
+
+	if (dump_bytes(dsp, dsp->dsa_drr, sizeof (dmu_replay_record_t)) != 0)
+		return (EINTR);
+	if (dump_bytes(dsp, buf, P2ROUNDUP(drrw->drr_psize, 8)) != 0)
+		return (EINTR);
+	return (0);
+}
+
+static int
+dump_spill(dmu_sendarg_t *dsp, uint64_t object, int blksz, void *data)
+{
+	struct drr_spill *drrs = &(dsp->dsa_drr->drr_u.drr_spill);
+
+	if (dsp->dsa_pending_op != PENDING_NONE) {
+		if (dump_bytes(dsp, dsp->dsa_drr,
+		    sizeof (dmu_replay_record_t)) != 0)
+			return (SET_ERROR(EINTR));
+		dsp->dsa_pending_op = PENDING_NONE;
+	}
+
+	/* write a SPILL record */
+	bzero(dsp->dsa_drr, sizeof (dmu_replay_record_t));
+	dsp->dsa_drr->drr_type = DRR_SPILL;
+	drrs->drr_object = object;
+	drrs->drr_length = blksz;
+	drrs->drr_toguid = dsp->dsa_toguid;
+
+	if (dump_bytes(dsp, dsp->dsa_drr, sizeof (dmu_replay_record_t)))
+		return (SET_ERROR(EINTR));
+	if (dump_bytes(dsp, data, blksz))
+		return (SET_ERROR(EINTR));
+	return (0);
+}
+
+static int
+dump_freeobjects(dmu_sendarg_t *dsp, uint64_t firstobj, uint64_t numobjs)
+{
+	struct drr_freeobjects *drrfo = &(dsp->dsa_drr->drr_u.drr_freeobjects);
+
+	/* See comment in dump_free(). */
+	if (!dsp->dsa_incremental)
+		return (0);
+
+	/*
+	 * If there is a pending op, but it's not PENDING_FREEOBJECTS,
+	 * push it out, since free block aggregation can only be done for
+	 * blocks of the same type (i.e., DRR_FREE records can only be
+	 * aggregated with other DRR_FREE records.  DRR_FREEOBJECTS records
+	 * can only be aggregated with other DRR_FREEOBJECTS records.
+	 */
+	if (dsp->dsa_pending_op != PENDING_NONE &&
+	    dsp->dsa_pending_op != PENDING_FREEOBJECTS) {
+		if (dump_bytes(dsp, dsp->dsa_drr,
+		    sizeof (dmu_replay_record_t)) != 0)
+			return (SET_ERROR(EINTR));
+		dsp->dsa_pending_op = PENDING_NONE;
+	}
+	if (dsp->dsa_pending_op == PENDING_FREEOBJECTS) {
+		/*
+		 * See whether this free object array can be aggregated
+		 * with pending one
+		 */
+		if (drrfo->drr_firstobj + drrfo->drr_numobjs == firstobj) {
+			drrfo->drr_numobjs += numobjs;
+			return (0);
+		} else {
+			/* can't be aggregated.  Push out pending record */
+			if (dump_bytes(dsp, dsp->dsa_drr,
+			    sizeof (dmu_replay_record_t)) != 0)
+				return (SET_ERROR(EINTR));
+			dsp->dsa_pending_op = PENDING_NONE;
+		}
+	}
+
+	/* write a FREEOBJECTS record */
+	bzero(dsp->dsa_drr, sizeof (dmu_replay_record_t));
+	dsp->dsa_drr->drr_type = DRR_FREEOBJECTS;
+	drrfo->drr_firstobj = firstobj;
+	drrfo->drr_numobjs = numobjs;
+	drrfo->drr_toguid = dsp->dsa_toguid;
+
+	dsp->dsa_pending_op = PENDING_FREEOBJECTS;
+
+	return (0);
+}
+
+static int
+dump_dnode(dmu_sendarg_t *dsp, uint64_t object, dnode_phys_t *dnp)
+{
+	struct drr_object *drro = &(dsp->dsa_drr->drr_u.drr_object);
+
+	if (dnp == NULL || dnp->dn_type == DMU_OT_NONE)
+		return (dump_freeobjects(dsp, object, 1));
+
+	if (dsp->dsa_pending_op != PENDING_NONE) {
+		if (dump_bytes(dsp, dsp->dsa_drr,
+		    sizeof (dmu_replay_record_t)) != 0)
+			return (SET_ERROR(EINTR));
+		dsp->dsa_pending_op = PENDING_NONE;
+	}
+
+	/* write an OBJECT record */
+	bzero(dsp->dsa_drr, sizeof (dmu_replay_record_t));
+	dsp->dsa_drr->drr_type = DRR_OBJECT;
+	drro->drr_object = object;
+	drro->drr_type = dnp->dn_type;
+	drro->drr_bonustype = dnp->dn_bonustype;
+	drro->drr_blksz = dnp->dn_datablkszsec << SPA_MINBLOCKSHIFT;
+	drro->drr_bonuslen = dnp->dn_bonuslen;
+	drro->drr_checksumtype = dnp->dn_checksum;
+	drro->drr_compress = dnp->dn_compress;
+	drro->drr_toguid = dsp->dsa_toguid;
+
+	if (!(dsp->dsa_featureflags & DMU_BACKUP_FEATURE_LARGE_BLOCKS) &&
+	    drro->drr_blksz > SPA_OLD_MAXBLOCKSIZE)
+		drro->drr_blksz = SPA_OLD_MAXBLOCKSIZE;
+
+	if (dump_bytes(dsp, dsp->dsa_drr, sizeof (dmu_replay_record_t)) != 0)
+		return (SET_ERROR(EINTR));
+
+	if (dump_bytes(dsp, DN_BONUS(dnp), P2ROUNDUP(dnp->dn_bonuslen, 8)) != 0)
+		return (SET_ERROR(EINTR));
+
+	/* Free anything past the end of the file. */
+	if (dump_free(dsp, object, (dnp->dn_maxblkid + 1) *
+	    (dnp->dn_datablkszsec << SPA_MINBLOCKSHIFT), -1ULL) != 0)
+		return (SET_ERROR(EINTR));
+	if (dsp->dsa_err != 0)
+		return (SET_ERROR(EINTR));
+	return (0);
+}
+
+static boolean_t
+backup_do_embed(dmu_sendarg_t *dsp, const blkptr_t *bp)
+{
+	if (!BP_IS_EMBEDDED(bp))
+		return (B_FALSE);
+
+	/*
+	 * Compression function must be legacy, or explicitly enabled.
+	 */
+	if ((BP_GET_COMPRESS(bp) >= ZIO_COMPRESS_LEGACY_FUNCTIONS &&
+	    !(dsp->dsa_featureflags & DMU_BACKUP_FEATURE_EMBED_DATA_LZ4)))
+		return (B_FALSE);
+
+	/*
+	 * Embed type must be explicitly enabled.
+	 */
+	switch (BPE_GET_ETYPE(bp)) {
+	case BP_EMBEDDED_TYPE_DATA:
+		if (dsp->dsa_featureflags & DMU_BACKUP_FEATURE_EMBED_DATA)
+			return (B_TRUE);
+		break;
+	default:
+		return (B_FALSE);
+	}
+	return (B_FALSE);
+}
+
+#define	BP_SPAN(dnp, level) \
+	(((uint64_t)dnp->dn_datablkszsec) << (SPA_MINBLOCKSHIFT + \
+	(level) * (dnp->dn_indblkshift - SPA_BLKPTRSHIFT)))
+
+/* ARGSUSED */
+static int
+backup_cb(spa_t *spa, zilog_t *zilog, const blkptr_t *bp,
+    const zbookmark_phys_t *zb, const dnode_phys_t *dnp, void *arg)
+{
+	dmu_sendarg_t *dsp = arg;
+	dmu_object_type_t type = bp ? BP_GET_TYPE(bp) : DMU_OT_NONE;
+	int err = 0;
+
+	if (issig(JUSTLOOKING) && issig(FORREAL))
+		return (SET_ERROR(EINTR));
+
+	if (zb->zb_object != DMU_META_DNODE_OBJECT &&
+	    DMU_OBJECT_IS_SPECIAL(zb->zb_object)) {
+		return (0);
+	} else if (zb->zb_level == ZB_ZIL_LEVEL) {
+		/*
+		 * If we are sending a non-snapshot (which is allowed on
+		 * read-only pools), it may have a ZIL, which must be ignored.
+		 */
+		return (0);
+	} else if (BP_IS_HOLE(bp) &&
+	    zb->zb_object == DMU_META_DNODE_OBJECT) {
+		uint64_t span = BP_SPAN(dnp, zb->zb_level);
+		uint64_t dnobj = (zb->zb_blkid * span) >> DNODE_SHIFT;
+		err = dump_freeobjects(dsp, dnobj, span >> DNODE_SHIFT);
+	} else if (BP_IS_HOLE(bp)) {
+		uint64_t span = BP_SPAN(dnp, zb->zb_level);
+		err = dump_free(dsp, zb->zb_object, zb->zb_blkid * span, span);
+	} else if (zb->zb_level > 0 || type == DMU_OT_OBJSET) {
+		return (0);
+	} else if (type == DMU_OT_DNODE) {
+		dnode_phys_t *blk;
+		int i;
+		int blksz = BP_GET_LSIZE(bp);
+		arc_flags_t aflags = ARC_FLAG_WAIT;
+		arc_buf_t *abuf;
+
+		if (arc_read(NULL, spa, bp, arc_getbuf_func, &abuf,
+		    ZIO_PRIORITY_ASYNC_READ, ZIO_FLAG_CANFAIL,
+		    &aflags, zb) != 0)
+			return (SET_ERROR(EIO));
+
+		blk = abuf->b_data;
+		for (i = 0; i < blksz >> DNODE_SHIFT; i++) {
+			uint64_t dnobj = (zb->zb_blkid <<
+			    (DNODE_BLOCK_SHIFT - DNODE_SHIFT)) + i;
+			err = dump_dnode(dsp, dnobj, blk+i);
+			if (err != 0)
+				break;
+		}
+		(void) arc_buf_remove_ref(abuf, &abuf);
+	} else if (type == DMU_OT_SA) {
+		arc_flags_t aflags = ARC_FLAG_WAIT;
+		arc_buf_t *abuf;
+		int blksz = BP_GET_LSIZE(bp);
+
+		if (arc_read(NULL, spa, bp, arc_getbuf_func, &abuf,
+		    ZIO_PRIORITY_ASYNC_READ, ZIO_FLAG_CANFAIL,
+		    &aflags, zb) != 0)
+			return (SET_ERROR(EIO));
+
+		err = dump_spill(dsp, zb->zb_object, blksz, abuf->b_data);
+		(void) arc_buf_remove_ref(abuf, &abuf);
+	} else if (backup_do_embed(dsp, bp)) {
+		/* it's an embedded level-0 block of a regular object */
+		int blksz = dnp->dn_datablkszsec << SPA_MINBLOCKSHIFT;
+		err = dump_write_embedded(dsp, zb->zb_object,
+		    zb->zb_blkid * blksz, blksz, bp);
+	} else { /* it's a level-0 block of a regular object */
+		uint64_t offset;
+		arc_flags_t aflags = ARC_FLAG_WAIT;
+		arc_buf_t *abuf;
+		int blksz = BP_GET_LSIZE(bp);
+
+		ASSERT3U(blksz, ==, dnp->dn_datablkszsec << SPA_MINBLOCKSHIFT);
+		ASSERT0(zb->zb_level);
+		if (arc_read(NULL, spa, bp, arc_getbuf_func, &abuf,
+		    ZIO_PRIORITY_ASYNC_READ, ZIO_FLAG_CANFAIL,
+		    &aflags, zb) != 0) {
+			if (zfs_send_corrupt_data) {
+				uint64_t *ptr;
+				/* Send a block filled with 0x"zfs badd bloc" */
+				abuf = arc_buf_alloc(spa, blksz, &abuf,
+				    ARC_BUFC_DATA);
+				for (ptr = abuf->b_data;
+				    (char *)ptr < (char *)abuf->b_data + blksz;
+				    ptr++)
+					*ptr = 0x2f5baddb10cULL;
+			} else {
+				return (SET_ERROR(EIO));
+			}
+		}
+
+		offset = zb->zb_blkid * blksz;
+
+		if (!(dsp->dsa_featureflags &
+		    DMU_BACKUP_FEATURE_LARGE_BLOCKS) &&
+		    blksz > SPA_OLD_MAXBLOCKSIZE) {
+			char *buf = abuf->b_data;
+			while (blksz > 0 && err == 0) {
+				int n = MIN(blksz, SPA_OLD_MAXBLOCKSIZE);
+				err = dump_write(dsp, type, zb->zb_object,
+				    offset, n, NULL, buf);
+				offset += n;
+				buf += n;
+				blksz -= n;
+			}
+		} else {
+			err = dump_write(dsp, type, zb->zb_object,
+			    offset, blksz, bp, abuf->b_data);
+		}
+		(void) arc_buf_remove_ref(abuf, &abuf);
+	}
+
+	ASSERT(err == 0 || err == EINTR);
+	return (err);
+}
+
+/*
+ * Releases dp using the specified tag.
+ */
+static int
+dmu_send_impl(void *tag, dsl_pool_t *dp, dsl_dataset_t *ds,
+    zfs_bookmark_phys_t *fromzb, boolean_t is_clone, boolean_t embedok,
+    boolean_t large_block_ok, int outfd, vnode_t *vp, offset_t *off)
+{
+	objset_t *os;
+	dmu_replay_record_t *drr;
+	dmu_sendarg_t *dsp;
+	int err;
+	uint64_t fromtxg = 0;
+	uint64_t featureflags = 0;
+
+	err = dmu_objset_from_ds(ds, &os);
+	if (err != 0) {
+		dsl_pool_rele(dp, tag);
+		return (err);
+	}
+
+	drr = kmem_zalloc(sizeof (dmu_replay_record_t), KM_SLEEP);
+	drr->drr_type = DRR_BEGIN;
+	drr->drr_u.drr_begin.drr_magic = DMU_BACKUP_MAGIC;
+	DMU_SET_STREAM_HDRTYPE(drr->drr_u.drr_begin.drr_versioninfo,
+	    DMU_SUBSTREAM);
+
+#ifdef _KERNEL
+	if (dmu_objset_type(os) == DMU_OST_ZFS) {
+		uint64_t version;
+		if (zfs_get_zplprop(os, ZFS_PROP_VERSION, &version) != 0) {
+			kmem_free(drr, sizeof (dmu_replay_record_t));
+			dsl_pool_rele(dp, tag);
+			return (SET_ERROR(EINVAL));
+		}
+		if (version >= ZPL_VERSION_SA) {
+			featureflags |= DMU_BACKUP_FEATURE_SA_SPILL;
+		}
+	}
+#endif
+
+	if (large_block_ok && ds->ds_large_blocks)
+		featureflags |= DMU_BACKUP_FEATURE_LARGE_BLOCKS;
+	if (embedok &&
+	    spa_feature_is_active(dp->dp_spa, SPA_FEATURE_EMBEDDED_DATA)) {
+		featureflags |= DMU_BACKUP_FEATURE_EMBED_DATA;
+		if (spa_feature_is_active(dp->dp_spa, SPA_FEATURE_LZ4_COMPRESS))
+			featureflags |= DMU_BACKUP_FEATURE_EMBED_DATA_LZ4;
+	} else {
+		embedok = B_FALSE;
+	}
+
+	DMU_SET_FEATUREFLAGS(drr->drr_u.drr_begin.drr_versioninfo,
+	    featureflags);
+
+	drr->drr_u.drr_begin.drr_creation_time =
+	    dsl_dataset_phys(ds)->ds_creation_time;
+	drr->drr_u.drr_begin.drr_type = dmu_objset_type(os);
+	if (is_clone)
+		drr->drr_u.drr_begin.drr_flags |= DRR_FLAG_CLONE;
+	drr->drr_u.drr_begin.drr_toguid = dsl_dataset_phys(ds)->ds_guid;
+	if (dsl_dataset_phys(ds)->ds_flags & DS_FLAG_CI_DATASET)
+		drr->drr_u.drr_begin.drr_flags |= DRR_FLAG_CI_DATA;
+
+	if (fromzb != NULL) {
+		drr->drr_u.drr_begin.drr_fromguid = fromzb->zbm_guid;
+		fromtxg = fromzb->zbm_creation_txg;
+	}
+	dsl_dataset_name(ds, drr->drr_u.drr_begin.drr_toname);
+	if (!ds->ds_is_snapshot) {
+		(void) strlcat(drr->drr_u.drr_begin.drr_toname, "@--head--",
+		    sizeof (drr->drr_u.drr_begin.drr_toname));
+	}
+
+	dsp = kmem_zalloc(sizeof (dmu_sendarg_t), KM_SLEEP);
+
+	dsp->dsa_drr = drr;
+	dsp->dsa_vp = vp;
+	dsp->dsa_outfd = outfd;
+	dsp->dsa_proc = curproc;
+	dsp->dsa_os = os;
+	dsp->dsa_off = off;
+	dsp->dsa_toguid = dsl_dataset_phys(ds)->ds_guid;
+	ZIO_SET_CHECKSUM(&dsp->dsa_zc, 0, 0, 0, 0);
+	dsp->dsa_pending_op = PENDING_NONE;
+	dsp->dsa_incremental = (fromzb != NULL);
+	dsp->dsa_featureflags = featureflags;
+
+	mutex_enter(&ds->ds_sendstream_lock);
+	list_insert_head(&ds->ds_sendstreams, dsp);
+	mutex_exit(&ds->ds_sendstream_lock);
+
+	dsl_dataset_long_hold(ds, FTAG);
+	dsl_pool_rele(dp, tag);
+
+	if (dump_bytes(dsp, drr, sizeof (dmu_replay_record_t)) != 0) {
+		err = dsp->dsa_err;
+		goto out;
+	}
+
+	err = traverse_dataset(ds, fromtxg, TRAVERSE_PRE | TRAVERSE_PREFETCH,
+	    backup_cb, dsp);
+
+	if (dsp->dsa_pending_op != PENDING_NONE)
+		if (dump_bytes(dsp, drr, sizeof (dmu_replay_record_t)) != 0)
+			err = SET_ERROR(EINTR);
+
+	if (err != 0) {
+		if (err == EINTR && dsp->dsa_err != 0)
+			err = dsp->dsa_err;
+		goto out;
+	}
+
+	bzero(drr, sizeof (dmu_replay_record_t));
+	drr->drr_type = DRR_END;
+	drr->drr_u.drr_end.drr_checksum = dsp->dsa_zc;
+	drr->drr_u.drr_end.drr_toguid = dsp->dsa_toguid;
+
+	if (dump_bytes(dsp, drr, sizeof (dmu_replay_record_t)) != 0) {
+		err = dsp->dsa_err;
+		goto out;
+	}
+
+out:
+	mutex_enter(&ds->ds_sendstream_lock);
+	list_remove(&ds->ds_sendstreams, dsp);
+	mutex_exit(&ds->ds_sendstream_lock);
+
+	kmem_free(drr, sizeof (dmu_replay_record_t));
+	kmem_free(dsp, sizeof (dmu_sendarg_t));
+
+	dsl_dataset_long_rele(ds, FTAG);
+
+	return (err);
+}
+
+int
+dmu_send_obj(const char *pool, uint64_t tosnap, uint64_t fromsnap,
+    boolean_t embedok, boolean_t large_block_ok,
+    int outfd, vnode_t *vp, offset_t *off)
+{
+	dsl_pool_t *dp;
+	dsl_dataset_t *ds;
+	dsl_dataset_t *fromds = NULL;
+	int err;
+
+	err = dsl_pool_hold(pool, FTAG, &dp);
+	if (err != 0)
+		return (err);
+
+	err = dsl_dataset_hold_obj(dp, tosnap, FTAG, &ds);
+	if (err != 0) {
+		dsl_pool_rele(dp, FTAG);
+		return (err);
+	}
+
+	if (fromsnap != 0) {
+		zfs_bookmark_phys_t zb;
+		boolean_t is_clone;
+
+		err = dsl_dataset_hold_obj(dp, fromsnap, FTAG, &fromds);
+		if (err != 0) {
+			dsl_dataset_rele(ds, FTAG);
+			dsl_pool_rele(dp, FTAG);
+			return (err);
+		}
+		if (!dsl_dataset_is_before(ds, fromds, 0))
+			err = SET_ERROR(EXDEV);
+		zb.zbm_creation_time =
+		    dsl_dataset_phys(fromds)->ds_creation_time;
+		zb.zbm_creation_txg = dsl_dataset_phys(fromds)->ds_creation_txg;
+		zb.zbm_guid = dsl_dataset_phys(fromds)->ds_guid;
+		is_clone = (fromds->ds_dir != ds->ds_dir);
+		dsl_dataset_rele(fromds, FTAG);
+		err = dmu_send_impl(FTAG, dp, ds, &zb, is_clone,
+		    embedok, large_block_ok, outfd, vp, off);
+	} else {
+		err = dmu_send_impl(FTAG, dp, ds, NULL, B_FALSE,
+		    embedok, large_block_ok, outfd, vp, off);
+	}
+	dsl_dataset_rele(ds, FTAG);
+	return (err);
+}
+
+int
+dmu_send(const char *tosnap, const char *fromsnap,
+    boolean_t embedok, boolean_t large_block_ok,
+    int outfd, vnode_t *vp, offset_t *off)
+{
+	dsl_pool_t *dp;
+	dsl_dataset_t *ds;
+	int err;
+	boolean_t owned = B_FALSE;
+
+	if (fromsnap != NULL && strpbrk(fromsnap, "@#") == NULL)
+		return (SET_ERROR(EINVAL));
+
+	err = dsl_pool_hold(tosnap, FTAG, &dp);
+	if (err != 0)
+		return (err);
+
+	if (strchr(tosnap, '@') == NULL && spa_writeable(dp->dp_spa)) {
+		/*
+		 * We are sending a filesystem or volume.  Ensure
+		 * that it doesn't change by owning the dataset.
+		 */
+		err = dsl_dataset_own(dp, tosnap, FTAG, &ds);
+		owned = B_TRUE;
+	} else {
+		err = dsl_dataset_hold(dp, tosnap, FTAG, &ds);
+	}
+	if (err != 0) {
+		dsl_pool_rele(dp, FTAG);
+		return (err);
+	}
+
+	if (fromsnap != NULL) {
+		zfs_bookmark_phys_t zb;
+		boolean_t is_clone = B_FALSE;
+		int fsnamelen = strchr(tosnap, '@') - tosnap;
+
+		/*
+		 * If the fromsnap is in a different filesystem, then
+		 * mark the send stream as a clone.
+		 */
+		if (strncmp(tosnap, fromsnap, fsnamelen) != 0 ||
+		    (fromsnap[fsnamelen] != '@' &&
+		    fromsnap[fsnamelen] != '#')) {
+			is_clone = B_TRUE;
+		}
+
+		if (strchr(fromsnap, '@')) {
+			dsl_dataset_t *fromds;
+			err = dsl_dataset_hold(dp, fromsnap, FTAG, &fromds);
+			if (err == 0) {
+				if (!dsl_dataset_is_before(ds, fromds, 0))
+					err = SET_ERROR(EXDEV);
+				zb.zbm_creation_time =
+				    dsl_dataset_phys(fromds)->ds_creation_time;
+				zb.zbm_creation_txg =
+				    dsl_dataset_phys(fromds)->ds_creation_txg;
+				zb.zbm_guid = dsl_dataset_phys(fromds)->ds_guid;
+				is_clone = (ds->ds_dir != fromds->ds_dir);
+				dsl_dataset_rele(fromds, FTAG);
+			}
+		} else {
+			err = dsl_bookmark_lookup(dp, fromsnap, ds, &zb);
+		}
+		if (err != 0) {
+			dsl_dataset_rele(ds, FTAG);
+			dsl_pool_rele(dp, FTAG);
+			return (err);
+		}
+		err = dmu_send_impl(FTAG, dp, ds, &zb, is_clone,
+		    embedok, large_block_ok, outfd, vp, off);
+	} else {
+		err = dmu_send_impl(FTAG, dp, ds, NULL, B_FALSE,
+		    embedok, large_block_ok, outfd, vp, off);
+	}
+	if (owned)
+		dsl_dataset_disown(ds, FTAG);
+	else
+		dsl_dataset_rele(ds, FTAG);
+	return (err);
+}
+
+static int
+dmu_adjust_send_estimate_for_indirects(dsl_dataset_t *ds, uint64_t size,
+    uint64_t *sizep)
+{
+	int err;
+	/*
+	 * Assume that space (both on-disk and in-stream) is dominated by
+	 * data.  We will adjust for indirect blocks and the copies property,
+	 * but ignore per-object space used (eg, dnodes and DRR_OBJECT records).
+	 */
+
+	/*
+	 * Subtract out approximate space used by indirect blocks.
+	 * Assume most space is used by data blocks (non-indirect, non-dnode).
+	 * Assume all blocks are recordsize.  Assume ditto blocks and
+	 * internal fragmentation counter out compression.
+	 *
+	 * Therefore, space used by indirect blocks is sizeof(blkptr_t) per
+	 * block, which we observe in practice.
+	 */
+	uint64_t recordsize;
+	err = dsl_prop_get_int_ds(ds, "recordsize", &recordsize);
+	if (err != 0)
+		return (err);
+	size -= size / recordsize * sizeof (blkptr_t);
+
+	/* Add in the space for the record associated with each block. */
+	size += size / recordsize * sizeof (dmu_replay_record_t);
+
+	*sizep = size;
+
+	return (0);
+}
+
+int
+dmu_send_estimate(dsl_dataset_t *ds, dsl_dataset_t *fromds, uint64_t *sizep)
+{
+	int err;
+	uint64_t size;
+
+	ASSERT(dsl_pool_config_held(ds->ds_dir->dd_pool));
+
+	/* tosnap must be a snapshot */
+	if (!ds->ds_is_snapshot)
+		return (SET_ERROR(EINVAL));
+
+	/* fromsnap, if provided, must be a snapshot */
+	if (fromds != NULL && !fromds->ds_is_snapshot)
+		return (SET_ERROR(EINVAL));
+
+	/*
+	 * fromsnap must be an earlier snapshot from the same fs as tosnap,
+	 * or the origin's fs.
+	 */
+	if (fromds != NULL && !dsl_dataset_is_before(ds, fromds, 0))
+		return (SET_ERROR(EXDEV));
+
+	/* Get uncompressed size estimate of changed data. */
+	if (fromds == NULL) {
+		size = dsl_dataset_phys(ds)->ds_uncompressed_bytes;
+	} else {
+		uint64_t used, comp;
+		err = dsl_dataset_space_written(fromds, ds,
+		    &used, &comp, &size);
+		if (err != 0)
+			return (err);
+	}
+
+	err = dmu_adjust_send_estimate_for_indirects(ds, size, sizep);
+	return (err);
+}
+
+/*
+ * Simple callback used to traverse the blocks of a snapshot and sum their
+ * uncompressed size
+ */
+/* ARGSUSED */
+static int
+dmu_calculate_send_traversal(spa_t *spa, zilog_t *zilog, const blkptr_t *bp,
+    const zbookmark_phys_t *zb, const dnode_phys_t *dnp, void *arg)
+{
+	uint64_t *spaceptr = arg;
+	if (bp != NULL && !BP_IS_HOLE(bp)) {
+		*spaceptr += BP_GET_UCSIZE(bp);
+	}
+	return (0);
+}
+
+/*
+ * Given a desination snapshot and a TXG, calculate the approximate size of a
+ * send stream sent from that TXG. from_txg may be zero, indicating that the
+ * whole snapshot will be sent.
+ */
+int
+dmu_send_estimate_from_txg(dsl_dataset_t *ds, uint64_t from_txg,
+    uint64_t *sizep)
+{
+	int err;
+	uint64_t size = 0;
+
+	ASSERT(dsl_pool_config_held(ds->ds_dir->dd_pool));
+
+	/* tosnap must be a snapshot */
+	if (!dsl_dataset_is_snapshot(ds))
+		return (SET_ERROR(EINVAL));
+
+	/* verify that from_txg is before the provided snapshot was taken */
+	if (from_txg >= dsl_dataset_phys(ds)->ds_creation_txg) {
+		return (SET_ERROR(EXDEV));
+	}
+	/*
+	 * traverse the blocks of the snapshot with birth times after
+	 * from_txg, summing their uncompressed size
+	 */
+	err = traverse_dataset(ds, from_txg, TRAVERSE_POST,
+	    dmu_calculate_send_traversal, &size);
+	if (err)
+		return (err);
+
+	err = dmu_adjust_send_estimate_for_indirects(ds, size, sizep);
+	return (err);
+}
+
+typedef struct dmu_recv_begin_arg {
+	const char *drba_origin;
+	dmu_recv_cookie_t *drba_cookie;
+	cred_t *drba_cred;
+	uint64_t drba_snapobj;
+} dmu_recv_begin_arg_t;
+
+static int
+recv_begin_check_existing_impl(dmu_recv_begin_arg_t *drba, dsl_dataset_t *ds,
+    uint64_t fromguid)
+{
+	uint64_t val;
+	int error;
+	dsl_pool_t *dp = ds->ds_dir->dd_pool;
+
+	/* temporary clone name must not exist */
+	error = zap_lookup(dp->dp_meta_objset,
+	    dsl_dir_phys(ds->ds_dir)->dd_child_dir_zapobj, recv_clone_name,
+	    8, 1, &val);
+	if (error != ENOENT)
+		return (error == 0 ? EBUSY : error);
+
+	/* new snapshot name must not exist */
+	error = zap_lookup(dp->dp_meta_objset,
+	    dsl_dataset_phys(ds)->ds_snapnames_zapobj,
+	    drba->drba_cookie->drc_tosnap, 8, 1, &val);
+	if (error != ENOENT)
+		return (error == 0 ? EEXIST : error);
+
+	/*
+	 * Check snapshot limit before receiving. We'll recheck again at the
+	 * end, but might as well abort before receiving if we're already over
+	 * the limit.
+	 *
+	 * Note that we do not check the file system limit with
+	 * dsl_dir_fscount_check because the temporary %clones don't count
+	 * against that limit.
+	 */
+	error = dsl_fs_ss_limit_check(ds->ds_dir, 1, ZFS_PROP_SNAPSHOT_LIMIT,
+	    NULL, drba->drba_cred);
+	if (error != 0)
+		return (error);
+
+	if (fromguid != 0) {
+		dsl_dataset_t *snap;
+		uint64_t obj = dsl_dataset_phys(ds)->ds_prev_snap_obj;
+
+		/* Find snapshot in this dir that matches fromguid. */
+		while (obj != 0) {
+			error = dsl_dataset_hold_obj(dp, obj, FTAG,
+			    &snap);
+			if (error != 0)
+				return (SET_ERROR(ENODEV));
+			if (snap->ds_dir != ds->ds_dir) {
+				dsl_dataset_rele(snap, FTAG);
+				return (SET_ERROR(ENODEV));
+			}
+			if (dsl_dataset_phys(snap)->ds_guid == fromguid)
+				break;
+			obj = dsl_dataset_phys(snap)->ds_prev_snap_obj;
+			dsl_dataset_rele(snap, FTAG);
+		}
+		if (obj == 0)
+			return (SET_ERROR(ENODEV));
+
+		if (drba->drba_cookie->drc_force) {
+			drba->drba_snapobj = obj;
+		} else {
+			/*
+			 * If we are not forcing, there must be no
+			 * changes since fromsnap.
+			 */
+			if (dsl_dataset_modified_since_snap(ds, snap)) {
+				dsl_dataset_rele(snap, FTAG);
+				return (SET_ERROR(ETXTBSY));
+			}
+			drba->drba_snapobj = ds->ds_prev->ds_object;
+		}
+
+		dsl_dataset_rele(snap, FTAG);
+	} else {
+		/* if full, then must be forced */
+		if (!drba->drba_cookie->drc_force)
+			return (SET_ERROR(EEXIST));
+		/* start from $ORIGIN@$ORIGIN, if supported */
+		drba->drba_snapobj = dp->dp_origin_snap != NULL ?
+		    dp->dp_origin_snap->ds_object : 0;
+	}
+
+	return (0);
+
+}
+
+static int
+dmu_recv_begin_check(void *arg, dmu_tx_t *tx)
+{
+	dmu_recv_begin_arg_t *drba = arg;
+	dsl_pool_t *dp = dmu_tx_pool(tx);
+	struct drr_begin *drrb = drba->drba_cookie->drc_drrb;
+	uint64_t fromguid = drrb->drr_fromguid;
+	int flags = drrb->drr_flags;
+	int error;
+	uint64_t featureflags = DMU_GET_FEATUREFLAGS(drrb->drr_versioninfo);
+	dsl_dataset_t *ds;
+	const char *tofs = drba->drba_cookie->drc_tofs;
+
+	/* already checked */
+	ASSERT3U(drrb->drr_magic, ==, DMU_BACKUP_MAGIC);
+
+	if (DMU_GET_STREAM_HDRTYPE(drrb->drr_versioninfo) ==
+	    DMU_COMPOUNDSTREAM ||
+	    drrb->drr_type >= DMU_OST_NUMTYPES ||
+	    ((flags & DRR_FLAG_CLONE) && drba->drba_origin == NULL))
+		return (SET_ERROR(EINVAL));
+
+	/* Verify pool version supports SA if SA_SPILL feature set */
+	if ((featureflags & DMU_BACKUP_FEATURE_SA_SPILL) &&
+	    spa_version(dp->dp_spa) < SPA_VERSION_SA)
+		return (SET_ERROR(ENOTSUP));
+
+	/*
+	 * The receiving code doesn't know how to translate a WRITE_EMBEDDED
+	 * record to a plan WRITE record, so the pool must have the
+	 * EMBEDDED_DATA feature enabled if the stream has WRITE_EMBEDDED
+	 * records.  Same with WRITE_EMBEDDED records that use LZ4 compression.
+	 */
+	if ((featureflags & DMU_BACKUP_FEATURE_EMBED_DATA) &&
+	    !spa_feature_is_enabled(dp->dp_spa, SPA_FEATURE_EMBEDDED_DATA))
+		return (SET_ERROR(ENOTSUP));
+	if ((featureflags & DMU_BACKUP_FEATURE_EMBED_DATA_LZ4) &&
+	    !spa_feature_is_enabled(dp->dp_spa, SPA_FEATURE_LZ4_COMPRESS))
+		return (SET_ERROR(ENOTSUP));
+
+	/*
+	 * The receiving code doesn't know how to translate large blocks
+	 * to smaller ones, so the pool must have the LARGE_BLOCKS
+	 * feature enabled if the stream has LARGE_BLOCKS.
+	 */
+	if ((featureflags & DMU_BACKUP_FEATURE_LARGE_BLOCKS) &&
+	    !spa_feature_is_enabled(dp->dp_spa, SPA_FEATURE_LARGE_BLOCKS))
+		return (SET_ERROR(ENOTSUP));
+
+	error = dsl_dataset_hold(dp, tofs, FTAG, &ds);
+	if (error == 0) {
+		/* target fs already exists; recv into temp clone */
+
+		/* Can't recv a clone into an existing fs */
+		if (flags & DRR_FLAG_CLONE) {
+			dsl_dataset_rele(ds, FTAG);
+			return (SET_ERROR(EINVAL));
+		}
+
+		error = recv_begin_check_existing_impl(drba, ds, fromguid);
+		dsl_dataset_rele(ds, FTAG);
+	} else if (error == ENOENT) {
+		/* target fs does not exist; must be a full backup or clone */
+		char buf[MAXNAMELEN];
+
+		/*
+		 * If it's a non-clone incremental, we are missing the
+		 * target fs, so fail the recv.
+		 */
+		if (fromguid != 0 && !(flags & DRR_FLAG_CLONE))
+			return (SET_ERROR(ENOENT));
+
+		/* Open the parent of tofs */
+		ASSERT3U(strlen(tofs), <, MAXNAMELEN);
+		(void) strlcpy(buf, tofs, strrchr(tofs, '/') - tofs + 1);
+		error = dsl_dataset_hold(dp, buf, FTAG, &ds);
+		if (error != 0)
+			return (error);
+
+		/*
+		 * Check filesystem and snapshot limits before receiving. We'll
+		 * recheck snapshot limits again at the end (we create the
+		 * filesystems and increment those counts during begin_sync).
+		 */
+		error = dsl_fs_ss_limit_check(ds->ds_dir, 1,
+		    ZFS_PROP_FILESYSTEM_LIMIT, NULL, drba->drba_cred);
+		if (error != 0) {
+			dsl_dataset_rele(ds, FTAG);
+			return (error);
+		}
+
+		error = dsl_fs_ss_limit_check(ds->ds_dir, 1,
+		    ZFS_PROP_SNAPSHOT_LIMIT, NULL, drba->drba_cred);
+		if (error != 0) {
+			dsl_dataset_rele(ds, FTAG);
+			return (error);
+		}
+
+		if (drba->drba_origin != NULL) {
+			dsl_dataset_t *origin;
+			error = dsl_dataset_hold(dp, drba->drba_origin,
+			    FTAG, &origin);
+			if (error != 0) {
+				dsl_dataset_rele(ds, FTAG);
+				return (error);
+			}
+			if (!origin->ds_is_snapshot) {
+				dsl_dataset_rele(origin, FTAG);
+				dsl_dataset_rele(ds, FTAG);
+				return (SET_ERROR(EINVAL));
+			}
+			if (dsl_dataset_phys(origin)->ds_guid != fromguid) {
+				dsl_dataset_rele(origin, FTAG);
+				dsl_dataset_rele(ds, FTAG);
+				return (SET_ERROR(ENODEV));
+			}
+			dsl_dataset_rele(origin, FTAG);
+		}
+		dsl_dataset_rele(ds, FTAG);
+		error = 0;
+	}
+	return (error);
+}
+
+static void
+dmu_recv_begin_sync(void *arg, dmu_tx_t *tx)
+{
+	dmu_recv_begin_arg_t *drba = arg;
+	dsl_pool_t *dp = dmu_tx_pool(tx);
+	struct drr_begin *drrb = drba->drba_cookie->drc_drrb;
+	const char *tofs = drba->drba_cookie->drc_tofs;
+	dsl_dataset_t *ds, *newds;
+	uint64_t dsobj;
+	int error;
+	uint64_t crflags;
+
+	crflags = (drrb->drr_flags & DRR_FLAG_CI_DATA) ?
+	    DS_FLAG_CI_DATASET : 0;
+
+	error = dsl_dataset_hold(dp, tofs, FTAG, &ds);
+	if (error == 0) {
+		/* create temporary clone */
+		dsl_dataset_t *snap = NULL;
+		if (drba->drba_snapobj != 0) {
+			VERIFY0(dsl_dataset_hold_obj(dp,
+			    drba->drba_snapobj, FTAG, &snap));
+		}
+		dsobj = dsl_dataset_create_sync(ds->ds_dir, recv_clone_name,
+		    snap, crflags, drba->drba_cred, tx);
+		dsl_dataset_rele(snap, FTAG);
+		dsl_dataset_rele(ds, FTAG);
+	} else {
+		dsl_dir_t *dd;
+		const char *tail;
+		dsl_dataset_t *origin = NULL;
+
+		VERIFY0(dsl_dir_hold(dp, tofs, FTAG, &dd, &tail));
+
+		if (drba->drba_origin != NULL) {
+			VERIFY0(dsl_dataset_hold(dp, drba->drba_origin,
+			    FTAG, &origin));
+		}
+
+		/* Create new dataset. */
+		dsobj = dsl_dataset_create_sync(dd,
+		    strrchr(tofs, '/') + 1,
+		    origin, crflags, drba->drba_cred, tx);
+		if (origin != NULL)
+			dsl_dataset_rele(origin, FTAG);
+		dsl_dir_rele(dd, FTAG);
+		drba->drba_cookie->drc_newfs = B_TRUE;
+	}
+	VERIFY0(dsl_dataset_own_obj(dp, dsobj, dmu_recv_tag, &newds));
+
+	if ((DMU_GET_FEATUREFLAGS(drrb->drr_versioninfo) &
+	    DMU_BACKUP_FEATURE_LARGE_BLOCKS) &&
+	    !newds->ds_large_blocks) {
+		dsl_dataset_activate_large_blocks_sync_impl(dsobj, tx);
+		newds->ds_large_blocks = B_TRUE;
+	}
+
+	dmu_buf_will_dirty(newds->ds_dbuf, tx);
+	dsl_dataset_phys(newds)->ds_flags |= DS_FLAG_INCONSISTENT;
+
+	/*
+	 * If we actually created a non-clone, we need to create the
+	 * objset in our new dataset.
+	 */
+	if (BP_IS_HOLE(dsl_dataset_get_blkptr(newds))) {
+		(void) dmu_objset_create_impl(dp->dp_spa,
+		    newds, dsl_dataset_get_blkptr(newds), drrb->drr_type, tx);
+	}
+
+	drba->drba_cookie->drc_ds = newds;
+
+	spa_history_log_internal_ds(newds, "receive", tx, "");
+}
+
+/*
+ * NB: callers *MUST* call dmu_recv_stream() if dmu_recv_begin()
+ * succeeds; otherwise we will leak the holds on the datasets.
+ */
+int
+dmu_recv_begin(char *tofs, char *tosnap, struct drr_begin *drrb,
+    boolean_t force, char *origin, dmu_recv_cookie_t *drc)
+{
+	dmu_recv_begin_arg_t drba = { 0 };
+	dmu_replay_record_t *drr;
+
+	bzero(drc, sizeof (dmu_recv_cookie_t));
+	drc->drc_drrb = drrb;
+	drc->drc_tosnap = tosnap;
+	drc->drc_tofs = tofs;
+	drc->drc_force = force;
+	drc->drc_cred = CRED();
+
+	if (drrb->drr_magic == BSWAP_64(DMU_BACKUP_MAGIC))
+		drc->drc_byteswap = B_TRUE;
+	else if (drrb->drr_magic != DMU_BACKUP_MAGIC)
+		return (SET_ERROR(EINVAL));
+
+	drr = kmem_zalloc(sizeof (dmu_replay_record_t), KM_SLEEP);
+	drr->drr_type = DRR_BEGIN;
+	drr->drr_u.drr_begin = *drc->drc_drrb;
+	if (drc->drc_byteswap) {
+		fletcher_4_incremental_byteswap(drr,
+		    sizeof (dmu_replay_record_t), &drc->drc_cksum);
+	} else {
+		fletcher_4_incremental_native(drr,
+		    sizeof (dmu_replay_record_t), &drc->drc_cksum);
+	}
+	kmem_free(drr, sizeof (dmu_replay_record_t));
+
+	if (drc->drc_byteswap) {
+		drrb->drr_magic = BSWAP_64(drrb->drr_magic);
+		drrb->drr_versioninfo = BSWAP_64(drrb->drr_versioninfo);
+		drrb->drr_creation_time = BSWAP_64(drrb->drr_creation_time);
+		drrb->drr_type = BSWAP_32(drrb->drr_type);
+		drrb->drr_toguid = BSWAP_64(drrb->drr_toguid);
+		drrb->drr_fromguid = BSWAP_64(drrb->drr_fromguid);
+	}
+
+	drba.drba_origin = origin;
+	drba.drba_cookie = drc;
+	drba.drba_cred = CRED();
+
+	return (dsl_sync_task(tofs, dmu_recv_begin_check, dmu_recv_begin_sync,
+	    &drba, 5, ZFS_SPACE_CHECK_NORMAL));
+}
+
+struct restorearg {
+	int err;
+	boolean_t byteswap;
+	vnode_t *vp;
+	char *buf;
+	uint64_t voff;
+	int bufsize; /* amount of memory allocated for buf */
+	zio_cksum_t cksum;
+	avl_tree_t *guid_to_ds_map;
+};
+
+typedef struct guid_map_entry {
+	uint64_t	guid;
+	dsl_dataset_t	*gme_ds;
+	avl_node_t	avlnode;
+} guid_map_entry_t;
+
+static int
+guid_compare(const void *arg1, const void *arg2)
+{
+	const guid_map_entry_t *gmep1 = arg1;
+	const guid_map_entry_t *gmep2 = arg2;
+
+	if (gmep1->guid < gmep2->guid)
+		return (-1);
+	else if (gmep1->guid > gmep2->guid)
+		return (1);
+	return (0);
+}
+
+static void
+free_guid_map_onexit(void *arg)
+{
+	avl_tree_t *ca = arg;
+	void *cookie = NULL;
+	guid_map_entry_t *gmep;
+
+	while ((gmep = avl_destroy_nodes(ca, &cookie)) != NULL) {
+		dsl_dataset_long_rele(gmep->gme_ds, gmep);
+		dsl_dataset_rele(gmep->gme_ds, gmep);
+		kmem_free(gmep, sizeof (guid_map_entry_t));
+	}
+	avl_destroy(ca);
+	kmem_free(ca, sizeof (avl_tree_t));
+}
+
+static void *
+restore_read(struct restorearg *ra, int len, char *buf)
+{
+	int done = 0;
+
+	if (buf == NULL)
+		buf = ra->buf;
+
+	/* some things will require 8-byte alignment, so everything must */
+	ASSERT0(len % 8);
+	ASSERT3U(len, <=, ra->bufsize);
+
+	while (done < len) {
+		ssize_t resid;
+
+		ra->err = vn_rdwr(UIO_READ, ra->vp,
+		    buf + done, len - done,
+		    ra->voff, UIO_SYSSPACE, FAPPEND,
+		    RLIM64_INFINITY, CRED(), &resid);
+
+		if (resid == len - done)
+			ra->err = SET_ERROR(EINVAL);
+		ra->voff += len - done - resid;
+		done = len - resid;
+		if (ra->err != 0)
+			return (NULL);
+	}
+
+	ASSERT3U(done, ==, len);
+	if (ra->byteswap)
+		fletcher_4_incremental_byteswap(buf, len, &ra->cksum);
+	else
+		fletcher_4_incremental_native(buf, len, &ra->cksum);
+	return (buf);
+}
+
+noinline static void
+backup_byteswap(dmu_replay_record_t *drr)
+{
+#define	DO64(X) (drr->drr_u.X = BSWAP_64(drr->drr_u.X))
+#define	DO32(X) (drr->drr_u.X = BSWAP_32(drr->drr_u.X))
+	drr->drr_type = BSWAP_32(drr->drr_type);
+	drr->drr_payloadlen = BSWAP_32(drr->drr_payloadlen);
+	switch (drr->drr_type) {
+	case DRR_BEGIN:
+		DO64(drr_begin.drr_magic);
+		DO64(drr_begin.drr_versioninfo);
+		DO64(drr_begin.drr_creation_time);
+		DO32(drr_begin.drr_type);
+		DO32(drr_begin.drr_flags);
+		DO64(drr_begin.drr_toguid);
+		DO64(drr_begin.drr_fromguid);
+		break;
+	case DRR_OBJECT:
+		DO64(drr_object.drr_object);
+		DO32(drr_object.drr_type);
+		DO32(drr_object.drr_bonustype);
+		DO32(drr_object.drr_blksz);
+		DO32(drr_object.drr_bonuslen);
+		DO64(drr_object.drr_toguid);
+		break;
+	case DRR_FREEOBJECTS:
+		DO64(drr_freeobjects.drr_firstobj);
+		DO64(drr_freeobjects.drr_numobjs);
+		DO64(drr_freeobjects.drr_toguid);
+		break;
+	case DRR_WRITE:
+		DO64(drr_write.drr_object);
+		DO32(drr_write.drr_type);
+		DO64(drr_write.drr_offset);
+		DO64(drr_write.drr_length);
+		DO64(drr_write.drr_toguid);
+		DO64(drr_write.drr_key.ddk_cksum.zc_word[0]);
+		DO64(drr_write.drr_key.ddk_cksum.zc_word[1]);
+		DO64(drr_write.drr_key.ddk_cksum.zc_word[2]);
+		DO64(drr_write.drr_key.ddk_cksum.zc_word[3]);
+		DO64(drr_write.drr_key.ddk_prop);
+		break;
+	case DRR_WRITE_BYREF:
+		DO64(drr_write_byref.drr_object);
+		DO64(drr_write_byref.drr_offset);
+		DO64(drr_write_byref.drr_length);
+		DO64(drr_write_byref.drr_toguid);
+		DO64(drr_write_byref.drr_refguid);
+		DO64(drr_write_byref.drr_refobject);
+		DO64(drr_write_byref.drr_refoffset);
+		DO64(drr_write_byref.drr_key.ddk_cksum.zc_word[0]);
+		DO64(drr_write_byref.drr_key.ddk_cksum.zc_word[1]);
+		DO64(drr_write_byref.drr_key.ddk_cksum.zc_word[2]);
+		DO64(drr_write_byref.drr_key.ddk_cksum.zc_word[3]);
+		DO64(drr_write_byref.drr_key.ddk_prop);
+		break;
+	case DRR_WRITE_EMBEDDED:
+		DO64(drr_write_embedded.drr_object);
+		DO64(drr_write_embedded.drr_offset);
+		DO64(drr_write_embedded.drr_length);
+		DO64(drr_write_embedded.drr_toguid);
+		DO32(drr_write_embedded.drr_lsize);
+		DO32(drr_write_embedded.drr_psize);
+		break;
+	case DRR_FREE:
+		DO64(drr_free.drr_object);
+		DO64(drr_free.drr_offset);
+		DO64(drr_free.drr_length);
+		DO64(drr_free.drr_toguid);
+		break;
+	case DRR_SPILL:
+		DO64(drr_spill.drr_object);
+		DO64(drr_spill.drr_length);
+		DO64(drr_spill.drr_toguid);
+		break;
+	case DRR_END:
+		DO64(drr_end.drr_checksum.zc_word[0]);
+		DO64(drr_end.drr_checksum.zc_word[1]);
+		DO64(drr_end.drr_checksum.zc_word[2]);
+		DO64(drr_end.drr_checksum.zc_word[3]);
+		DO64(drr_end.drr_toguid);
+		break;
+	default:
+		break;
+	}
+#undef DO64
+#undef DO32
+}
+
+static inline uint8_t
+deduce_nblkptr(dmu_object_type_t bonus_type, uint64_t bonus_size)
+{
+	if (bonus_type == DMU_OT_SA) {
+		return (1);
+	} else {
+		return (1 +
+		    ((DN_MAX_BONUSLEN - bonus_size) >> SPA_BLKPTRSHIFT));
+	}
+}
+
+noinline static int
+restore_object(struct restorearg *ra, objset_t *os, struct drr_object *drro)
+{
+	dmu_object_info_t doi;
+	dmu_tx_t *tx;
+	void *data = NULL;
+	uint64_t object;
+	int err;
+
+	if (drro->drr_type == DMU_OT_NONE ||
+	    !DMU_OT_IS_VALID(drro->drr_type) ||
+	    !DMU_OT_IS_VALID(drro->drr_bonustype) ||
+	    drro->drr_checksumtype >= ZIO_CHECKSUM_FUNCTIONS ||
+	    drro->drr_compress >= ZIO_COMPRESS_FUNCTIONS ||
+	    P2PHASE(drro->drr_blksz, SPA_MINBLOCKSIZE) ||
+	    drro->drr_blksz < SPA_MINBLOCKSIZE ||
+	    drro->drr_blksz > spa_maxblocksize(dmu_objset_spa(os)) ||
+	    drro->drr_bonuslen > DN_MAX_BONUSLEN) {
+		return (SET_ERROR(EINVAL));
+	}
+
+	err = dmu_object_info(os, drro->drr_object, &doi);
+
+	if (err != 0 && err != ENOENT)
+		return (SET_ERROR(EINVAL));
+	object = err == 0 ? drro->drr_object : DMU_NEW_OBJECT;
+
+	if (drro->drr_bonuslen) {
+		data = restore_read(ra, P2ROUNDUP(drro->drr_bonuslen, 8), NULL);
+		if (ra->err != 0)
+			return (ra->err);
+	}
+
+	/*
+	 * If we are losing blkptrs or changing the block size this must
+	 * be a new file instance.  We must clear out the previous file
+	 * contents before we can change this type of metadata in the dnode.
+	 */
+	if (err == 0) {
+		int nblkptr;
+
+		nblkptr = deduce_nblkptr(drro->drr_bonustype,
+		    drro->drr_bonuslen);
+
+		if (drro->drr_blksz != doi.doi_data_block_size ||
+		    nblkptr < doi.doi_nblkptr) {
+			err = dmu_free_long_range(os, drro->drr_object,
+			    0, DMU_OBJECT_END);
+			if (err != 0)
+				return (SET_ERROR(EINVAL));
+		}
+	}
+
+	tx = dmu_tx_create(os);
+	dmu_tx_hold_bonus(tx, object);
+	err = dmu_tx_assign(tx, TXG_WAIT);
+	if (err != 0) {
+		dmu_tx_abort(tx);
+		return (err);
+	}
+
+	if (object == DMU_NEW_OBJECT) {
+		/* currently free, want to be allocated */
+		err = dmu_object_claim(os, drro->drr_object,
+		    drro->drr_type, drro->drr_blksz,
+		    drro->drr_bonustype, drro->drr_bonuslen, tx);
+	} else if (drro->drr_type != doi.doi_type ||
+	    drro->drr_blksz != doi.doi_data_block_size ||
+	    drro->drr_bonustype != doi.doi_bonus_type ||
+	    drro->drr_bonuslen != doi.doi_bonus_size) {
+		/* currently allocated, but with different properties */
+		err = dmu_object_reclaim(os, drro->drr_object,
+		    drro->drr_type, drro->drr_blksz,
+		    drro->drr_bonustype, drro->drr_bonuslen, tx);
+	}
+	if (err != 0) {
+		dmu_tx_commit(tx);
+		return (SET_ERROR(EINVAL));
+	}
+
+	dmu_object_set_checksum(os, drro->drr_object, drro->drr_checksumtype,
+	    tx);
+	dmu_object_set_compress(os, drro->drr_object, drro->drr_compress, tx);
+
+	if (data != NULL) {
+		dmu_buf_t *db;
+
+		VERIFY(0 == dmu_bonus_hold(os, drro->drr_object, FTAG, &db));
+		dmu_buf_will_dirty(db, tx);
+
+		ASSERT3U(db->db_size, >=, drro->drr_bonuslen);
+		bcopy(data, db->db_data, drro->drr_bonuslen);
+		if (ra->byteswap) {
+			dmu_object_byteswap_t byteswap =
+			    DMU_OT_BYTESWAP(drro->drr_bonustype);
+			dmu_ot_byteswap[byteswap].ob_func(db->db_data,
+			    drro->drr_bonuslen);
+		}
+		dmu_buf_rele(db, FTAG);
+	}
+	dmu_tx_commit(tx);
+	return (0);
+}
+
+/* ARGSUSED */
+noinline static int
+restore_freeobjects(struct restorearg *ra, objset_t *os,
+    struct drr_freeobjects *drrfo)
+{
+	uint64_t obj;
+
+	if (drrfo->drr_firstobj + drrfo->drr_numobjs < drrfo->drr_firstobj)
+		return (SET_ERROR(EINVAL));
+
+	for (obj = drrfo->drr_firstobj;
+	    obj < drrfo->drr_firstobj + drrfo->drr_numobjs;
+	    (void) dmu_object_next(os, &obj, FALSE, 0)) {
+		int err;
+
+		if (dmu_object_info(os, obj, NULL) != 0)
+			continue;
+
+		err = dmu_free_long_object(os, obj);
+		if (err != 0)
+			return (err);
+	}
+	return (0);
+}
+
+noinline static int
+restore_write(struct restorearg *ra, objset_t *os,
+    struct drr_write *drrw)
+{
+	dmu_tx_t *tx;
+	dmu_buf_t *bonus;
+	arc_buf_t *abuf;
+	void *data;
+	int err;
+
+	if (drrw->drr_offset + drrw->drr_length < drrw->drr_offset ||
+	    !DMU_OT_IS_VALID(drrw->drr_type))
+		return (SET_ERROR(EINVAL));
+
+	if (dmu_object_info(os, drrw->drr_object, NULL) != 0)
+		return (SET_ERROR(EINVAL));
+
+	if (dmu_bonus_hold(os, drrw->drr_object, FTAG, &bonus) != 0)
+		return (SET_ERROR(EINVAL));
+
+	abuf = dmu_request_arcbuf(bonus, drrw->drr_length);
+
+	data = restore_read(ra, drrw->drr_length, abuf->b_data);
+	if (data == NULL) {
+		dmu_return_arcbuf(abuf);
+		dmu_buf_rele(bonus, FTAG);
+		return (ra->err);
+	}
+
+	tx = dmu_tx_create(os);
+
+	dmu_tx_hold_write(tx, drrw->drr_object,
+	    drrw->drr_offset, drrw->drr_length);
+	err = dmu_tx_assign(tx, TXG_WAIT);
+	if (err != 0) {
+		dmu_return_arcbuf(abuf);
+		dmu_buf_rele(bonus, FTAG);
+		dmu_tx_abort(tx);
+		return (err);
+	}
+	if (ra->byteswap) {
+		dmu_object_byteswap_t byteswap =
+		    DMU_OT_BYTESWAP(drrw->drr_type);
+		dmu_ot_byteswap[byteswap].ob_func(data, drrw->drr_length);
+	}
+	dmu_assign_arcbuf(bonus, drrw->drr_offset, abuf, tx);
+	dmu_tx_commit(tx);
+	dmu_buf_rele(bonus, FTAG);
+	return (0);
+}
+
+/*
+ * Handle a DRR_WRITE_BYREF record.  This record is used in dedup'ed
+ * streams to refer to a copy of the data that is already on the
+ * system because it came in earlier in the stream.  This function
+ * finds the earlier copy of the data, and uses that copy instead of
+ * data from the stream to fulfill this write.
+ */
+static int
+restore_write_byref(struct restorearg *ra, objset_t *os,
+    struct drr_write_byref *drrwbr)
+{
+	dmu_tx_t *tx;
+	int err;
+	guid_map_entry_t gmesrch;
+	guid_map_entry_t *gmep;
+	avl_index_t where;
+	objset_t *ref_os = NULL;
+	dmu_buf_t *dbp;
+
+	if (drrwbr->drr_offset + drrwbr->drr_length < drrwbr->drr_offset)
+		return (SET_ERROR(EINVAL));
+
+	/*
+	 * If the GUID of the referenced dataset is different from the
+	 * GUID of the target dataset, find the referenced dataset.
+	 */
+	if (drrwbr->drr_toguid != drrwbr->drr_refguid) {
+		gmesrch.guid = drrwbr->drr_refguid;
+		if ((gmep = avl_find(ra->guid_to_ds_map, &gmesrch,
+		    &where)) == NULL) {
+			return (SET_ERROR(EINVAL));
+		}
+		if (dmu_objset_from_ds(gmep->gme_ds, &ref_os))
+			return (SET_ERROR(EINVAL));
+	} else {
+		ref_os = os;
+	}
+
+	err = dmu_buf_hold(ref_os, drrwbr->drr_refobject,
+	    drrwbr->drr_refoffset, FTAG, &dbp, DMU_READ_PREFETCH);
+	if (err != 0)
+		return (err);
+
+	tx = dmu_tx_create(os);
+
+	dmu_tx_hold_write(tx, drrwbr->drr_object,
+	    drrwbr->drr_offset, drrwbr->drr_length);
+	err = dmu_tx_assign(tx, TXG_WAIT);
+	if (err != 0) {
+		dmu_tx_abort(tx);
+		return (err);
+	}
+	dmu_write(os, drrwbr->drr_object,
+	    drrwbr->drr_offset, drrwbr->drr_length, dbp->db_data, tx);
+	dmu_buf_rele(dbp, FTAG);
+	dmu_tx_commit(tx);
+	return (0);
+}
+
+static int
+restore_write_embedded(struct restorearg *ra, objset_t *os,
+    struct drr_write_embedded *drrwnp)
+{
+	dmu_tx_t *tx;
+	int err;
+	void *data;
+
+	if (drrwnp->drr_offset + drrwnp->drr_length < drrwnp->drr_offset)
+		return (EINVAL);
+
+	if (drrwnp->drr_psize > BPE_PAYLOAD_SIZE)
+		return (EINVAL);
+
+	if (drrwnp->drr_etype >= NUM_BP_EMBEDDED_TYPES)
+		return (EINVAL);
+	if (drrwnp->drr_compression >= ZIO_COMPRESS_FUNCTIONS)
+		return (EINVAL);
+
+	data = restore_read(ra, P2ROUNDUP(drrwnp->drr_psize, 8), NULL);
+	if (data == NULL)
+		return (ra->err);
+
+	tx = dmu_tx_create(os);
+
+	dmu_tx_hold_write(tx, drrwnp->drr_object,
+	    drrwnp->drr_offset, drrwnp->drr_length);
+	err = dmu_tx_assign(tx, TXG_WAIT);
+	if (err != 0) {
+		dmu_tx_abort(tx);
+		return (err);
+	}
+
+	dmu_write_embedded(os, drrwnp->drr_object,
+	    drrwnp->drr_offset, data, drrwnp->drr_etype,
+	    drrwnp->drr_compression, drrwnp->drr_lsize, drrwnp->drr_psize,
+	    ra->byteswap ^ ZFS_HOST_BYTEORDER, tx);
+
+	dmu_tx_commit(tx);
+	return (0);
+}
+
+static int
+restore_spill(struct restorearg *ra, objset_t *os, struct drr_spill *drrs)
+{
+	dmu_tx_t *tx;
+	void *data;
+	dmu_buf_t *db, *db_spill;
+	int err;
+
+	if (drrs->drr_length < SPA_MINBLOCKSIZE ||
+	    drrs->drr_length > spa_maxblocksize(dmu_objset_spa(os)))
+		return (SET_ERROR(EINVAL));
+
+	data = restore_read(ra, drrs->drr_length, NULL);
+	if (data == NULL)
+		return (ra->err);
+
+	if (dmu_object_info(os, drrs->drr_object, NULL) != 0)
+		return (SET_ERROR(EINVAL));
+
+	VERIFY(0 == dmu_bonus_hold(os, drrs->drr_object, FTAG, &db));
+	if ((err = dmu_spill_hold_by_bonus(db, FTAG, &db_spill)) != 0) {
+		dmu_buf_rele(db, FTAG);
+		return (err);
+	}
+
+	tx = dmu_tx_create(os);
+
+	dmu_tx_hold_spill(tx, db->db_object);
+
+	err = dmu_tx_assign(tx, TXG_WAIT);
+	if (err != 0) {
+		dmu_buf_rele(db, FTAG);
+		dmu_buf_rele(db_spill, FTAG);
+		dmu_tx_abort(tx);
+		return (err);
+	}
+	dmu_buf_will_dirty(db_spill, tx);
+
+	if (db_spill->db_size < drrs->drr_length)
+		VERIFY(0 == dbuf_spill_set_blksz(db_spill,
+		    drrs->drr_length, tx));
+	bcopy(data, db_spill->db_data, drrs->drr_length);
+
+	dmu_buf_rele(db, FTAG);
+	dmu_buf_rele(db_spill, FTAG);
+
+	dmu_tx_commit(tx);
+	return (0);
+}
+
+/* ARGSUSED */
+noinline static int
+restore_free(struct restorearg *ra, objset_t *os,
+    struct drr_free *drrf)
+{
+	int err;
+
+	if (drrf->drr_length != -1ULL &&
+	    drrf->drr_offset + drrf->drr_length < drrf->drr_offset)
+		return (SET_ERROR(EINVAL));
+
+	if (dmu_object_info(os, drrf->drr_object, NULL) != 0)
+		return (SET_ERROR(EINVAL));
+
+	err = dmu_free_long_range(os, drrf->drr_object,
+	    drrf->drr_offset, drrf->drr_length);
+	return (err);
+}
+
+/* used to destroy the drc_ds on error */
+static void
+dmu_recv_cleanup_ds(dmu_recv_cookie_t *drc)
+{
+	char name[MAXNAMELEN];
+	dsl_dataset_name(drc->drc_ds, name);
+	dsl_dataset_disown(drc->drc_ds, dmu_recv_tag);
+	(void) dsl_destroy_head(name);
+}
+
+/*
+ * NB: callers *must* call dmu_recv_end() if this succeeds.
+ */
+int
+dmu_recv_stream(dmu_recv_cookie_t *drc, vnode_t *vp, offset_t *voffp,
+    int cleanup_fd, uint64_t *action_handlep)
+{
+	struct restorearg ra = { 0 };
+	dmu_replay_record_t *drr;
+	objset_t *os;
+	zio_cksum_t pcksum;
+	int featureflags;
+
+	ra.byteswap = drc->drc_byteswap;
+	ra.cksum = drc->drc_cksum;
+	ra.vp = vp;
+	ra.voff = *voffp;
+	ra.bufsize = SPA_MAXBLOCKSIZE;
+	ra.buf = vmem_alloc(ra.bufsize, KM_SLEEP);
+
+	/* these were verified in dmu_recv_begin */
+	ASSERT3U(DMU_GET_STREAM_HDRTYPE(drc->drc_drrb->drr_versioninfo), ==,
+	    DMU_SUBSTREAM);
+	ASSERT3U(drc->drc_drrb->drr_type, <, DMU_OST_NUMTYPES);
+
+	/*
+	 * Open the objset we are modifying.
+	 */
+	VERIFY0(dmu_objset_from_ds(drc->drc_ds, &os));
+
+	ASSERT(dsl_dataset_phys(drc->drc_ds)->ds_flags & DS_FLAG_INCONSISTENT);
+
+	featureflags = DMU_GET_FEATUREFLAGS(drc->drc_drrb->drr_versioninfo);
+
+	/* if this stream is dedup'ed, set up the avl tree for guid mapping */
+	if (featureflags & DMU_BACKUP_FEATURE_DEDUP) {
+		minor_t minor;
+
+		if (cleanup_fd == -1) {
+			ra.err = SET_ERROR(EBADF);
+			goto out;
+		}
+		ra.err = zfs_onexit_fd_hold(cleanup_fd, &minor);
+		if (ra.err != 0) {
+			cleanup_fd = -1;
+			goto out;
+		}
+
+		if (*action_handlep == 0) {
+			ra.guid_to_ds_map =
+			    kmem_alloc(sizeof (avl_tree_t), KM_SLEEP);
+			avl_create(ra.guid_to_ds_map, guid_compare,
+			    sizeof (guid_map_entry_t),
+			    offsetof(guid_map_entry_t, avlnode));
+			ra.err = zfs_onexit_add_cb(minor,
+			    free_guid_map_onexit, ra.guid_to_ds_map,
+			    action_handlep);
+			if (ra.err != 0)
+				goto out;
+		} else {
+			ra.err = zfs_onexit_cb_data(minor, *action_handlep,
+			    (void **)&ra.guid_to_ds_map);
+			if (ra.err != 0)
+				goto out;
+		}
+
+		drc->drc_guid_to_ds_map = ra.guid_to_ds_map;
+	}
+
+	/*
+	 * Read records and process them.
+	 */
+	pcksum = ra.cksum;
+	while (ra.err == 0 &&
+	    NULL != (drr = restore_read(&ra, sizeof (*drr), NULL))) {
+		if (issig(JUSTLOOKING) && issig(FORREAL)) {
+			ra.err = SET_ERROR(EINTR);
+			goto out;
+		}
+
+		if (ra.byteswap)
+			backup_byteswap(drr);
+
+		switch (drr->drr_type) {
+		case DRR_OBJECT:
+		{
+			/*
+			 * We need to make a copy of the record header,
+			 * because restore_{object,write} may need to
+			 * restore_read(), which will invalidate drr.
+			 */
+			struct drr_object drro = drr->drr_u.drr_object;
+			ra.err = restore_object(&ra, os, &drro);
+			break;
+		}
+		case DRR_FREEOBJECTS:
+		{
+			struct drr_freeobjects drrfo =
+			    drr->drr_u.drr_freeobjects;
+			ra.err = restore_freeobjects(&ra, os, &drrfo);
+			break;
+		}
+		case DRR_WRITE:
+		{
+			struct drr_write drrw = drr->drr_u.drr_write;
+			ra.err = restore_write(&ra, os, &drrw);
+			break;
+		}
+		case DRR_WRITE_BYREF:
+		{
+			struct drr_write_byref drrwbr =
+			    drr->drr_u.drr_write_byref;
+			ra.err = restore_write_byref(&ra, os, &drrwbr);
+			break;
+		}
+		case DRR_WRITE_EMBEDDED:
+		{
+			struct drr_write_embedded drrwe =
+			    drr->drr_u.drr_write_embedded;
+			ra.err = restore_write_embedded(&ra, os, &drrwe);
+			break;
+		}
+		case DRR_FREE:
+		{
+			struct drr_free drrf = drr->drr_u.drr_free;
+			ra.err = restore_free(&ra, os, &drrf);
+			break;
+		}
+		case DRR_END:
+		{
+			struct drr_end drre = drr->drr_u.drr_end;
+			/*
+			 * We compare against the *previous* checksum
+			 * value, because the stored checksum is of
+			 * everything before the DRR_END record.
+			 */
+			if (!ZIO_CHECKSUM_EQUAL(drre.drr_checksum, pcksum))
+				ra.err = SET_ERROR(ECKSUM);
+			goto out;
+		}
+		case DRR_SPILL:
+		{
+			struct drr_spill drrs = drr->drr_u.drr_spill;
+			ra.err = restore_spill(&ra, os, &drrs);
+			break;
+		}
+		default:
+			ra.err = SET_ERROR(EINVAL);
+			goto out;
+		}
+		pcksum = ra.cksum;
+	}
+	ASSERT(ra.err != 0);
+
+out:
+	if ((featureflags & DMU_BACKUP_FEATURE_DEDUP) && (cleanup_fd != -1))
+		zfs_onexit_fd_rele(cleanup_fd);
+
+	if (ra.err != 0) {
+		/*
+		 * destroy what we created, so we don't leave it in the
+		 * inconsistent restoring state.
+		 */
+		dmu_recv_cleanup_ds(drc);
+	}
+
+	vmem_free(ra.buf, ra.bufsize);
+	*voffp = ra.voff;
+	return (ra.err);
+}
+
+static int
+dmu_recv_end_check(void *arg, dmu_tx_t *tx)
+{
+	dmu_recv_cookie_t *drc = arg;
+	dsl_pool_t *dp = dmu_tx_pool(tx);
+	int error;
+
+	ASSERT3P(drc->drc_ds->ds_owner, ==, dmu_recv_tag);
+
+	if (!drc->drc_newfs) {
+		dsl_dataset_t *origin_head;
+
+		error = dsl_dataset_hold(dp, drc->drc_tofs, FTAG, &origin_head);
+		if (error != 0)
+			return (error);
+		if (drc->drc_force) {
+			/*
+			 * We will destroy any snapshots in tofs (i.e. before
+			 * origin_head) that are after the origin (which is
+			 * the snap before drc_ds, because drc_ds can not
+			 * have any snaps of its own).
+			 */
+			uint64_t obj;
+
+			obj = dsl_dataset_phys(origin_head)->ds_prev_snap_obj;
+			while (obj !=
+			    dsl_dataset_phys(drc->drc_ds)->ds_prev_snap_obj) {
+				dsl_dataset_t *snap;
+				error = dsl_dataset_hold_obj(dp, obj, FTAG,
+				    &snap);
+				if (error != 0)
+					break;
+				if (snap->ds_dir != origin_head->ds_dir)
+					error = SET_ERROR(EINVAL);
+				if (error == 0)  {
+					error = dsl_destroy_snapshot_check_impl(
+					    snap, B_FALSE);
+				}
+				obj = dsl_dataset_phys(snap)->ds_prev_snap_obj;
+				dsl_dataset_rele(snap, FTAG);
+				if (error != 0)
+					break;
+			}
+			if (error != 0) {
+				dsl_dataset_rele(origin_head, FTAG);
+				return (error);
+			}
+		}
+		error = dsl_dataset_clone_swap_check_impl(drc->drc_ds,
+		    origin_head, drc->drc_force, drc->drc_owner, tx);
+		if (error != 0) {
+			dsl_dataset_rele(origin_head, FTAG);
+			return (error);
+		}
+		error = dsl_dataset_snapshot_check_impl(origin_head,
+		    drc->drc_tosnap, tx, B_TRUE, 1, drc->drc_cred);
+		dsl_dataset_rele(origin_head, FTAG);
+		if (error != 0)
+			return (error);
+
+		error = dsl_destroy_head_check_impl(drc->drc_ds, 1);
+	} else {
+		error = dsl_dataset_snapshot_check_impl(drc->drc_ds,
+		    drc->drc_tosnap, tx, B_TRUE, 1, drc->drc_cred);
+	}
+	return (error);
+}
+
+static void
+dmu_recv_end_sync(void *arg, dmu_tx_t *tx)
+{
+	dmu_recv_cookie_t *drc = arg;
+	dsl_pool_t *dp = dmu_tx_pool(tx);
+
+	spa_history_log_internal_ds(drc->drc_ds, "finish receiving",
+	    tx, "snap=%s", drc->drc_tosnap);
+
+	if (!drc->drc_newfs) {
+		dsl_dataset_t *origin_head;
+
+		VERIFY0(dsl_dataset_hold(dp, drc->drc_tofs, FTAG,
+		    &origin_head));
+
+		if (drc->drc_force) {
+			/*
+			 * Destroy any snapshots of drc_tofs (origin_head)
+			 * after the origin (the snap before drc_ds).
+			 */
+			uint64_t obj;
+
+			obj = dsl_dataset_phys(origin_head)->ds_prev_snap_obj;
+			while (obj !=
+			    dsl_dataset_phys(drc->drc_ds)->ds_prev_snap_obj) {
+				dsl_dataset_t *snap;
+				VERIFY0(dsl_dataset_hold_obj(dp, obj, FTAG,
+				    &snap));
+				ASSERT3P(snap->ds_dir, ==, origin_head->ds_dir);
+				obj = dsl_dataset_phys(snap)->ds_prev_snap_obj;
+				dsl_destroy_snapshot_sync_impl(snap,
+				    B_FALSE, tx);
+				dsl_dataset_rele(snap, FTAG);
+			}
+		}
+		VERIFY3P(drc->drc_ds->ds_prev, ==,
+		    origin_head->ds_prev);
+
+		dsl_dataset_clone_swap_sync_impl(drc->drc_ds,
+		    origin_head, tx);
+		dsl_dataset_snapshot_sync_impl(origin_head,
+		    drc->drc_tosnap, tx);
+
+		/* set snapshot's creation time and guid */
+		dmu_buf_will_dirty(origin_head->ds_prev->ds_dbuf, tx);
+		dsl_dataset_phys(origin_head->ds_prev)->ds_creation_time =
+		    drc->drc_drrb->drr_creation_time;
+		dsl_dataset_phys(origin_head->ds_prev)->ds_guid =
+		    drc->drc_drrb->drr_toguid;
+		dsl_dataset_phys(origin_head->ds_prev)->ds_flags &=
+		    ~DS_FLAG_INCONSISTENT;
+
+		dmu_buf_will_dirty(origin_head->ds_dbuf, tx);
+		dsl_dataset_phys(origin_head)->ds_flags &=
+		    ~DS_FLAG_INCONSISTENT;
+
+		dsl_dataset_rele(origin_head, FTAG);
+		dsl_destroy_head_sync_impl(drc->drc_ds, tx);
+
+		if (drc->drc_owner != NULL)
+			VERIFY3P(origin_head->ds_owner, ==, drc->drc_owner);
+	} else {
+		dsl_dataset_t *ds = drc->drc_ds;
+
+		dsl_dataset_snapshot_sync_impl(ds, drc->drc_tosnap, tx);
+
+		/* set snapshot's creation time and guid */
+		dmu_buf_will_dirty(ds->ds_prev->ds_dbuf, tx);
+		dsl_dataset_phys(ds->ds_prev)->ds_creation_time =
+		    drc->drc_drrb->drr_creation_time;
+		dsl_dataset_phys(ds->ds_prev)->ds_guid =
+		    drc->drc_drrb->drr_toguid;
+		dsl_dataset_phys(ds->ds_prev)->ds_flags &=
+		    ~DS_FLAG_INCONSISTENT;
+
+		dmu_buf_will_dirty(ds->ds_dbuf, tx);
+		dsl_dataset_phys(ds)->ds_flags &= ~DS_FLAG_INCONSISTENT;
+	}
+	drc->drc_newsnapobj = dsl_dataset_phys(drc->drc_ds)->ds_prev_snap_obj;
+	zvol_create_minors(dp->dp_spa, drc->drc_tofs, B_TRUE);
+	/*
+	 * Release the hold from dmu_recv_begin.  This must be done before
+	 * we return to open context, so that when we free the dataset's dnode,
+	 * we can evict its bonus buffer.
+	 */
+	dsl_dataset_disown(drc->drc_ds, dmu_recv_tag);
+	drc->drc_ds = NULL;
+}
+
+static int
+add_ds_to_guidmap(const char *name, avl_tree_t *guid_map, uint64_t snapobj)
+{
+	dsl_pool_t *dp;
+	dsl_dataset_t *snapds;
+	guid_map_entry_t *gmep;
+	int err;
+
+	ASSERT(guid_map != NULL);
+
+	err = dsl_pool_hold(name, FTAG, &dp);
+	if (err != 0)
+		return (err);
+	gmep = kmem_alloc(sizeof (*gmep), KM_SLEEP);
+	err = dsl_dataset_hold_obj(dp, snapobj, gmep, &snapds);
+	if (err == 0) {
+		gmep->guid = dsl_dataset_phys(snapds)->ds_guid;
+		gmep->gme_ds = snapds;
+		avl_add(guid_map, gmep);
+		dsl_dataset_long_hold(snapds, gmep);
+	} else {
+		kmem_free(gmep, sizeof (*gmep));
+	}
+
+	dsl_pool_rele(dp, FTAG);
+	return (err);
+}
+
+static int dmu_recv_end_modified_blocks = 3;
+
+static int
+dmu_recv_existing_end(dmu_recv_cookie_t *drc)
+{
+	int error;
+
+#ifdef _KERNEL
+	char *name;
+
+	/*
+	 * We will be destroying the ds; make sure its origin is unmounted if
+	 * necessary.
+	 */
+	name = kmem_alloc(MAXNAMELEN, KM_SLEEP);
+	dsl_dataset_name(drc->drc_ds, name);
+	zfs_destroy_unmount_origin(name);
+	kmem_free(name, MAXNAMELEN);
+#endif
+
+	error = dsl_sync_task(drc->drc_tofs,
+	    dmu_recv_end_check, dmu_recv_end_sync, drc,
+	    dmu_recv_end_modified_blocks, ZFS_SPACE_CHECK_NORMAL);
+
+	if (error != 0)
+		dmu_recv_cleanup_ds(drc);
+	return (error);
+}
+
+static int
+dmu_recv_new_end(dmu_recv_cookie_t *drc)
+{
+	int error;
+
+	error = dsl_sync_task(drc->drc_tofs,
+	    dmu_recv_end_check, dmu_recv_end_sync, drc,
+	    dmu_recv_end_modified_blocks, ZFS_SPACE_CHECK_NORMAL);
+
+	if (error != 0) {
+		dmu_recv_cleanup_ds(drc);
+	} else if (drc->drc_guid_to_ds_map != NULL) {
+		(void) add_ds_to_guidmap(drc->drc_tofs,
+		    drc->drc_guid_to_ds_map,
+		    drc->drc_newsnapobj);
+	}
+	return (error);
+}
+
+int
+dmu_recv_end(dmu_recv_cookie_t *drc, void *owner)
+{
+	drc->drc_owner = owner;
+
+	if (drc->drc_newfs)
+		return (dmu_recv_new_end(drc));
+	else
+		return (dmu_recv_existing_end(drc));
+}
+
+/*
+ * Return TRUE if this objset is currently being received into.
+ */
+boolean_t
+dmu_objset_is_receiving(objset_t *os)
+{
+	return (os->os_dsl_dataset != NULL &&
+	    os->os_dsl_dataset->ds_owner == dmu_recv_tag);
+}
+
+#if defined(_KERNEL)
+module_param(zfs_send_corrupt_data, int, 0644);
+MODULE_PARM_DESC(zfs_send_corrupt_data, "Allow sending corrupt data");
+#endif
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/module/zfs/dmu_traverse.c
@@ -0,0 +1,695 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2016 by Delphix. All rights reserved.
+ */
+
+#include <sys/zfs_context.h>
+#include <sys/dmu_objset.h>
+#include <sys/dmu_traverse.h>
+#include <sys/dsl_dataset.h>
+#include <sys/dsl_dir.h>
+#include <sys/dsl_pool.h>
+#include <sys/dnode.h>
+#include <sys/spa.h>
+#include <sys/zio.h>
+#include <sys/dmu_impl.h>
+#include <sys/sa.h>
+#include <sys/sa_impl.h>
+#include <sys/callb.h>
+#include <sys/zfeature.h>
+
+int32_t zfs_pd_bytes_max = 50 * 1024 * 1024;	/* 50MB */
+
+typedef struct prefetch_data {
+	kmutex_t pd_mtx;
+	kcondvar_t pd_cv;
+	int32_t pd_bytes_fetched;
+	int pd_flags;
+	boolean_t pd_cancel;
+	boolean_t pd_exited;
+} prefetch_data_t;
+
+typedef struct traverse_data {
+	spa_t *td_spa;
+	uint64_t td_objset;
+	blkptr_t *td_rootbp;
+	uint64_t td_min_txg;
+	zbookmark_phys_t *td_resume;
+	int td_flags;
+	prefetch_data_t *td_pfd;
+	boolean_t td_paused;
+	uint64_t td_hole_birth_enabled_txg;
+	blkptr_cb_t *td_func;
+	void *td_arg;
+	boolean_t td_realloc_possible;
+} traverse_data_t;
+
+static int traverse_dnode(traverse_data_t *td, const dnode_phys_t *dnp,
+    uint64_t objset, uint64_t object);
+static void prefetch_dnode_metadata(traverse_data_t *td, const dnode_phys_t *,
+    uint64_t objset, uint64_t object);
+
+static int
+traverse_zil_block(zilog_t *zilog, blkptr_t *bp, void *arg, uint64_t claim_txg)
+{
+	traverse_data_t *td = arg;
+	zbookmark_phys_t zb;
+
+	if (BP_IS_HOLE(bp))
+		return (0);
+
+	if (claim_txg == 0 && bp->blk_birth >= spa_first_txg(td->td_spa))
+		return (0);
+
+	SET_BOOKMARK(&zb, td->td_objset, ZB_ZIL_OBJECT, ZB_ZIL_LEVEL,
+	    bp->blk_cksum.zc_word[ZIL_ZC_SEQ]);
+
+	(void) td->td_func(td->td_spa, zilog, bp, &zb, NULL, td->td_arg);
+
+	return (0);
+}
+
+static int
+traverse_zil_record(zilog_t *zilog, lr_t *lrc, void *arg, uint64_t claim_txg)
+{
+	traverse_data_t *td = arg;
+
+	if (lrc->lrc_txtype == TX_WRITE) {
+		lr_write_t *lr = (lr_write_t *)lrc;
+		blkptr_t *bp = &lr->lr_blkptr;
+		zbookmark_phys_t zb;
+
+		if (BP_IS_HOLE(bp))
+			return (0);
+
+		if (claim_txg == 0 || bp->blk_birth < claim_txg)
+			return (0);
+
+		SET_BOOKMARK(&zb, td->td_objset, lr->lr_foid,
+		    ZB_ZIL_LEVEL, lr->lr_offset / BP_GET_LSIZE(bp));
+
+		(void) td->td_func(td->td_spa, zilog, bp, &zb, NULL,
+		    td->td_arg);
+	}
+	return (0);
+}
+
+static void
+traverse_zil(traverse_data_t *td, zil_header_t *zh)
+{
+	uint64_t claim_txg = zh->zh_claim_txg;
+	zilog_t *zilog;
+
+	/*
+	 * We only want to visit blocks that have been claimed but not yet
+	 * replayed; plus, in read-only mode, blocks that are already stable.
+	 */
+	if (claim_txg == 0 && spa_writeable(td->td_spa))
+		return;
+
+	zilog = zil_alloc(spa_get_dsl(td->td_spa)->dp_meta_objset, zh);
+
+	(void) zil_parse(zilog, traverse_zil_block, traverse_zil_record, td,
+	    claim_txg);
+
+	zil_free(zilog);
+}
+
+typedef enum resume_skip {
+	RESUME_SKIP_ALL,
+	RESUME_SKIP_NONE,
+	RESUME_SKIP_CHILDREN
+} resume_skip_t;
+
+/*
+ * Returns RESUME_SKIP_ALL if td indicates that we are resuming a traversal and
+ * the block indicated by zb does not need to be visited at all. Returns
+ * RESUME_SKIP_CHILDREN if we are resuming a post traversal and we reach the
+ * resume point. This indicates that this block should be visited but not its
+ * children (since they must have been visited in a previous traversal).
+ * Otherwise returns RESUME_SKIP_NONE.
+ */
+static resume_skip_t
+resume_skip_check(traverse_data_t *td, const dnode_phys_t *dnp,
+    const zbookmark_phys_t *zb)
+{
+	if (td->td_resume != NULL && !ZB_IS_ZERO(td->td_resume)) {
+		/*
+		 * If we already visited this bp & everything below,
+		 * don't bother doing it again.
+		 */
+		if (zbookmark_is_before(dnp, zb, td->td_resume))
+			return (RESUME_SKIP_ALL);
+
+		/*
+		 * If we found the block we're trying to resume from, zero
+		 * the bookmark out to indicate that we have resumed.
+		 */
+		if (bcmp(zb, td->td_resume, sizeof (*zb)) == 0) {
+			bzero(td->td_resume, sizeof (*zb));
+			if (td->td_flags & TRAVERSE_POST)
+				return (RESUME_SKIP_CHILDREN);
+		}
+	}
+	return (RESUME_SKIP_NONE);
+}
+
+static void
+traverse_prefetch_metadata(traverse_data_t *td,
+    const blkptr_t *bp, const zbookmark_phys_t *zb)
+{
+	arc_flags_t flags = ARC_FLAG_NOWAIT | ARC_FLAG_PREFETCH;
+
+	if (!(td->td_flags & TRAVERSE_PREFETCH_METADATA))
+		return;
+	/*
+	 * If we are in the process of resuming, don't prefetch, because
+	 * some children will not be needed (and in fact may have already
+	 * been freed).
+	 */
+	if (td->td_resume != NULL && !ZB_IS_ZERO(td->td_resume))
+		return;
+	if (BP_IS_HOLE(bp) || bp->blk_birth <= td->td_min_txg)
+		return;
+	if (BP_GET_LEVEL(bp) == 0 && BP_GET_TYPE(bp) != DMU_OT_DNODE)
+		return;
+
+	(void) arc_read(NULL, td->td_spa, bp, NULL, NULL,
+	    ZIO_PRIORITY_ASYNC_READ, ZIO_FLAG_CANFAIL, &flags, zb);
+}
+
+static boolean_t
+prefetch_needed(prefetch_data_t *pfd, const blkptr_t *bp)
+{
+	ASSERT(pfd->pd_flags & TRAVERSE_PREFETCH_DATA);
+	if (BP_IS_HOLE(bp) || BP_IS_EMBEDDED(bp) ||
+	    BP_GET_TYPE(bp) == DMU_OT_INTENT_LOG)
+		return (B_FALSE);
+	return (B_TRUE);
+}
+
+static int
+traverse_visitbp(traverse_data_t *td, const dnode_phys_t *dnp,
+    const blkptr_t *bp, const zbookmark_phys_t *zb)
+{
+	int err = 0;
+	arc_buf_t *buf = NULL;
+	prefetch_data_t *pd = td->td_pfd;
+
+	switch (resume_skip_check(td, dnp, zb)) {
+	case RESUME_SKIP_ALL:
+		return (0);
+	case RESUME_SKIP_CHILDREN:
+		goto post;
+	case RESUME_SKIP_NONE:
+		break;
+	default:
+		ASSERT(0);
+	}
+
+	if (bp->blk_birth == 0) {
+		/*
+		 * Since this block has a birth time of 0 it must be one of
+		 * two things: a hole created before the
+		 * SPA_FEATURE_HOLE_BIRTH feature was enabled, or a hole
+		 * which has always been a hole in an object.
+		 *
+		 * If a file is written sparsely, then the unwritten parts of
+		 * the file were "always holes" -- that is, they have been
+		 * holes since this object was allocated.  However, we (and
+		 * our callers) can not necessarily tell when an object was
+		 * allocated.  Therefore, if it's possible that this object
+		 * was freed and then its object number reused, we need to
+		 * visit all the holes with birth==0.
+		 *
+		 * If it isn't possible that the object number was reused,
+		 * then if SPA_FEATURE_HOLE_BIRTH was enabled before we wrote
+		 * all the blocks we will visit as part of this traversal,
+		 * then this hole must have always existed, so we can skip
+		 * it.  We visit blocks born after (exclusive) td_min_txg.
+		 *
+		 * Note that the meta-dnode cannot be reallocated.
+		 */
+		if ((!td->td_realloc_possible ||
+			zb->zb_object == DMU_META_DNODE_OBJECT) &&
+			td->td_hole_birth_enabled_txg <= td->td_min_txg)
+			return (0);
+	} else if (bp->blk_birth <= td->td_min_txg) {
+		return (0);
+	}
+
+	if (pd != NULL && !pd->pd_exited && prefetch_needed(pd, bp)) {
+		uint64_t size = BP_GET_LSIZE(bp);
+		mutex_enter(&pd->pd_mtx);
+		ASSERT(pd->pd_bytes_fetched >= 0);
+		while (pd->pd_bytes_fetched < size && !pd->pd_exited)
+			cv_wait_sig(&pd->pd_cv, &pd->pd_mtx);
+		pd->pd_bytes_fetched -= size;
+		cv_broadcast(&pd->pd_cv);
+		mutex_exit(&pd->pd_mtx);
+	}
+
+	if (BP_IS_HOLE(bp)) {
+		err = td->td_func(td->td_spa, NULL, bp, zb, dnp, td->td_arg);
+		if (err != 0)
+			goto post;
+		return (0);
+	}
+
+	if (td->td_flags & TRAVERSE_PRE) {
+		err = td->td_func(td->td_spa, NULL, bp, zb, dnp,
+		    td->td_arg);
+		if (err == TRAVERSE_VISIT_NO_CHILDREN)
+			return (0);
+		if (err != 0)
+			goto post;
+	}
+
+	if (BP_GET_LEVEL(bp) > 0) {
+		uint32_t flags = ARC_FLAG_WAIT;
+		int32_t i;
+		int32_t epb = BP_GET_LSIZE(bp) >> SPA_BLKPTRSHIFT;
+		zbookmark_phys_t *czb;
+
+		err = arc_read(NULL, td->td_spa, bp, arc_getbuf_func, &buf,
+		    ZIO_PRIORITY_ASYNC_READ, ZIO_FLAG_CANFAIL, &flags, zb);
+		if (err != 0)
+			goto post;
+
+		czb = kmem_alloc(sizeof (zbookmark_phys_t), KM_SLEEP);
+
+		for (i = 0; i < epb; i++) {
+			SET_BOOKMARK(czb, zb->zb_objset, zb->zb_object,
+			    zb->zb_level - 1,
+			    zb->zb_blkid * epb + i);
+			traverse_prefetch_metadata(td,
+			    &((blkptr_t *)buf->b_data)[i], czb);
+		}
+
+		/* recursively visitbp() blocks below this */
+		for (i = 0; i < epb; i++) {
+			SET_BOOKMARK(czb, zb->zb_objset, zb->zb_object,
+			    zb->zb_level - 1,
+			    zb->zb_blkid * epb + i);
+			err = traverse_visitbp(td, dnp,
+			    &((blkptr_t *)buf->b_data)[i], czb);
+			if (err != 0)
+				break;
+		}
+
+		kmem_free(czb, sizeof (zbookmark_phys_t));
+
+	} else if (BP_GET_TYPE(bp) == DMU_OT_DNODE) {
+		uint32_t flags = ARC_FLAG_WAIT;
+		int32_t i;
+		int32_t epb = BP_GET_LSIZE(bp) >> DNODE_SHIFT;
+		dnode_phys_t *cdnp;
+
+		err = arc_read(NULL, td->td_spa, bp, arc_getbuf_func, &buf,
+		    ZIO_PRIORITY_ASYNC_READ, ZIO_FLAG_CANFAIL, &flags, zb);
+		if (err != 0)
+			goto post;
+		cdnp = buf->b_data;
+
+		for (i = 0; i < epb; i++) {
+			prefetch_dnode_metadata(td, &cdnp[i], zb->zb_objset,
+			    zb->zb_blkid * epb + i);
+		}
+
+		/* recursively visitbp() blocks below this */
+		for (i = 0; i < epb; i++) {
+			err = traverse_dnode(td, &cdnp[i], zb->zb_objset,
+			    zb->zb_blkid * epb + i);
+			if (err != 0)
+				break;
+		}
+	} else if (BP_GET_TYPE(bp) == DMU_OT_OBJSET) {
+		arc_flags_t flags = ARC_FLAG_WAIT;
+		objset_phys_t *osp;
+		dnode_phys_t *mdnp, *gdnp, *udnp;
+
+		err = arc_read(NULL, td->td_spa, bp, arc_getbuf_func, &buf,
+		    ZIO_PRIORITY_ASYNC_READ, ZIO_FLAG_CANFAIL, &flags, zb);
+		if (err != 0)
+			goto post;
+
+		osp = buf->b_data;
+		mdnp = &osp->os_meta_dnode;
+		gdnp = &osp->os_groupused_dnode;
+		udnp = &osp->os_userused_dnode;
+
+		prefetch_dnode_metadata(td, mdnp, zb->zb_objset,
+		    DMU_META_DNODE_OBJECT);
+		/*
+		 * See the block comment above for the goal of this variable.
+		 * If the maxblkid of the meta-dnode is 0, then we know that
+		 * we've never had more than DNODES_PER_BLOCK objects in the
+		 * dataset, which means we can't have reused any object ids.
+		 */
+		if (osp->os_meta_dnode.dn_maxblkid == 0)
+			td->td_realloc_possible = B_FALSE;
+
+		if (arc_buf_size(buf) >= sizeof (objset_phys_t)) {
+			prefetch_dnode_metadata(td, gdnp, zb->zb_objset,
+			    DMU_GROUPUSED_OBJECT);
+			prefetch_dnode_metadata(td, udnp, zb->zb_objset,
+			    DMU_USERUSED_OBJECT);
+		}
+
+		err = traverse_dnode(td, mdnp, zb->zb_objset,
+		    DMU_META_DNODE_OBJECT);
+		if (err == 0 && arc_buf_size(buf) >= sizeof (objset_phys_t)) {
+			err = traverse_dnode(td, gdnp, zb->zb_objset,
+			    DMU_GROUPUSED_OBJECT);
+		}
+		if (err == 0 && arc_buf_size(buf) >= sizeof (objset_phys_t)) {
+			err = traverse_dnode(td, udnp, zb->zb_objset,
+			    DMU_USERUSED_OBJECT);
+		}
+	}
+
+	if (buf)
+		(void) arc_buf_remove_ref(buf, &buf);
+
+post:
+	if (err == 0 && (td->td_flags & TRAVERSE_POST))
+		err = td->td_func(td->td_spa, NULL, bp, zb, dnp, td->td_arg);
+
+	if ((td->td_flags & TRAVERSE_HARD) && (err == EIO || err == ECKSUM)) {
+		/*
+		 * Ignore this disk error as requested by the HARD flag,
+		 * and continue traversal.
+		 */
+		err = 0;
+	}
+
+	/*
+	 * If we are stopping here, set td_resume.
+	 */
+	if (td->td_resume != NULL && err != 0 && !td->td_paused) {
+		td->td_resume->zb_objset = zb->zb_objset;
+		td->td_resume->zb_object = zb->zb_object;
+		td->td_resume->zb_level = 0;
+		/*
+		 * If we have stopped on an indirect block (e.g. due to
+		 * i/o error), we have not visited anything below it.
+		 * Set the bookmark to the first level-0 block that we need
+		 * to visit.  This way, the resuming code does not need to
+		 * deal with resuming from indirect blocks.
+		 */
+		td->td_resume->zb_blkid = zb->zb_blkid <<
+		    (zb->zb_level * (dnp->dn_indblkshift - SPA_BLKPTRSHIFT));
+		td->td_paused = B_TRUE;
+	}
+
+	return (err);
+}
+
+static void
+prefetch_dnode_metadata(traverse_data_t *td, const dnode_phys_t *dnp,
+    uint64_t objset, uint64_t object)
+{
+	int j;
+	zbookmark_phys_t czb;
+
+	for (j = 0; j < dnp->dn_nblkptr; j++) {
+		SET_BOOKMARK(&czb, objset, object, dnp->dn_nlevels - 1, j);
+		traverse_prefetch_metadata(td, &dnp->dn_blkptr[j], &czb);
+	}
+
+	if (dnp->dn_flags & DNODE_FLAG_SPILL_BLKPTR) {
+		SET_BOOKMARK(&czb, objset, object, 0, DMU_SPILL_BLKID);
+		traverse_prefetch_metadata(td, &dnp->dn_spill, &czb);
+	}
+}
+
+static int
+traverse_dnode(traverse_data_t *td, const dnode_phys_t *dnp,
+    uint64_t objset, uint64_t object)
+{
+	int j, err = 0;
+	zbookmark_phys_t czb;
+
+	for (j = 0; j < dnp->dn_nblkptr; j++) {
+		SET_BOOKMARK(&czb, objset, object, dnp->dn_nlevels - 1, j);
+		err = traverse_visitbp(td, dnp, &dnp->dn_blkptr[j], &czb);
+		if (err != 0)
+			break;
+	}
+
+	if (err == 0 && dnp->dn_flags & DNODE_FLAG_SPILL_BLKPTR) {
+		SET_BOOKMARK(&czb, objset, object, 0, DMU_SPILL_BLKID);
+		err = traverse_visitbp(td, dnp, &dnp->dn_spill, &czb);
+	}
+	return (err);
+}
+
+/* ARGSUSED */
+static int
+traverse_prefetcher(spa_t *spa, zilog_t *zilog, const blkptr_t *bp,
+    const zbookmark_phys_t *zb, const dnode_phys_t *dnp, void *arg)
+{
+	prefetch_data_t *pfd = arg;
+	arc_flags_t aflags = ARC_FLAG_NOWAIT | ARC_FLAG_PREFETCH;
+
+	ASSERT(pfd->pd_bytes_fetched >= 0);
+	if (pfd->pd_cancel)
+		return (SET_ERROR(EINTR));
+
+	if (!prefetch_needed(pfd, bp))
+		return (0);
+
+	mutex_enter(&pfd->pd_mtx);
+	while (!pfd->pd_cancel && pfd->pd_bytes_fetched >= zfs_pd_bytes_max)
+		cv_wait_sig(&pfd->pd_cv, &pfd->pd_mtx);
+	pfd->pd_bytes_fetched += BP_GET_LSIZE(bp);
+	cv_broadcast(&pfd->pd_cv);
+	mutex_exit(&pfd->pd_mtx);
+
+	(void) arc_read(NULL, spa, bp, NULL, NULL, ZIO_PRIORITY_ASYNC_READ,
+	    ZIO_FLAG_CANFAIL | ZIO_FLAG_SPECULATIVE, &aflags, zb);
+
+	return (0);
+}
+
+static void
+traverse_prefetch_thread(void *arg)
+{
+	traverse_data_t *td_main = arg;
+	traverse_data_t td = *td_main;
+	zbookmark_phys_t czb;
+	fstrans_cookie_t cookie = spl_fstrans_mark();
+
+	td.td_func = traverse_prefetcher;
+	td.td_arg = td_main->td_pfd;
+	td.td_pfd = NULL;
+
+	SET_BOOKMARK(&czb, td.td_objset,
+	    ZB_ROOT_OBJECT, ZB_ROOT_LEVEL, ZB_ROOT_BLKID);
+	(void) traverse_visitbp(&td, NULL, td.td_rootbp, &czb);
+
+	mutex_enter(&td_main->td_pfd->pd_mtx);
+	td_main->td_pfd->pd_exited = B_TRUE;
+	cv_broadcast(&td_main->td_pfd->pd_cv);
+	mutex_exit(&td_main->td_pfd->pd_mtx);
+	spl_fstrans_unmark(cookie);
+}
+
+/*
+ * NB: dataset must not be changing on-disk (eg, is a snapshot or we are
+ * in syncing context).
+ */
+static int
+traverse_impl(spa_t *spa, dsl_dataset_t *ds, uint64_t objset, blkptr_t *rootbp,
+    uint64_t txg_start, zbookmark_phys_t *resume, int flags,
+    blkptr_cb_t func, void *arg)
+{
+	traverse_data_t *td;
+	prefetch_data_t *pd;
+	zbookmark_phys_t *czb;
+	int err;
+
+	ASSERT(ds == NULL || objset == ds->ds_object);
+	ASSERT(!(flags & TRAVERSE_PRE) || !(flags & TRAVERSE_POST));
+
+	/*
+	 * The data prefetching mechanism (the prefetch thread) is incompatible
+	 * with resuming from a bookmark.
+	 */
+	ASSERT(resume == NULL || !(flags & TRAVERSE_PREFETCH_DATA));
+
+	td = kmem_alloc(sizeof (traverse_data_t), KM_SLEEP);
+	pd = kmem_zalloc(sizeof (prefetch_data_t), KM_SLEEP);
+	czb = kmem_alloc(sizeof (zbookmark_phys_t), KM_SLEEP);
+
+	td->td_spa = spa;
+	td->td_objset = objset;
+	td->td_rootbp = rootbp;
+	td->td_min_txg = txg_start;
+	td->td_resume = resume;
+	td->td_func = func;
+	td->td_arg = arg;
+	td->td_pfd = pd;
+	td->td_flags = flags;
+	td->td_paused = B_FALSE;
+	td->td_realloc_possible = (txg_start == 0 ? B_FALSE : B_TRUE);
+
+	if (spa_feature_is_active(spa, SPA_FEATURE_HOLE_BIRTH)) {
+		VERIFY(spa_feature_enabled_txg(spa,
+		    SPA_FEATURE_HOLE_BIRTH, &td->td_hole_birth_enabled_txg));
+	} else {
+		td->td_hole_birth_enabled_txg = UINT64_MAX;
+	}
+
+	pd->pd_flags = flags;
+	mutex_init(&pd->pd_mtx, NULL, MUTEX_DEFAULT, NULL);
+	cv_init(&pd->pd_cv, NULL, CV_DEFAULT, NULL);
+
+	SET_BOOKMARK(czb, td->td_objset,
+	    ZB_ROOT_OBJECT, ZB_ROOT_LEVEL, ZB_ROOT_BLKID);
+
+	/* See comment on ZIL traversal in dsl_scan_visitds. */
+	if (ds != NULL && !ds->ds_is_snapshot && !BP_IS_HOLE(rootbp)) {
+		uint32_t flags = ARC_FLAG_WAIT;
+		objset_phys_t *osp;
+		arc_buf_t *buf;
+
+		err = arc_read(NULL, td->td_spa, rootbp,
+		    arc_getbuf_func, &buf,
+		    ZIO_PRIORITY_ASYNC_READ, ZIO_FLAG_CANFAIL, &flags, czb);
+		if (err != 0)
+			return (err);
+
+		osp = buf->b_data;
+		traverse_zil(td, &osp->os_zil_header);
+		(void) arc_buf_remove_ref(buf, &buf);
+	}
+
+	if (!(flags & TRAVERSE_PREFETCH_DATA) ||
+	    0 == taskq_dispatch(system_taskq, traverse_prefetch_thread,
+	    td, TQ_NOQUEUE))
+		pd->pd_exited = B_TRUE;
+
+	err = traverse_visitbp(td, NULL, rootbp, czb);
+
+	mutex_enter(&pd->pd_mtx);
+	pd->pd_cancel = B_TRUE;
+	cv_broadcast(&pd->pd_cv);
+	while (!pd->pd_exited)
+		cv_wait_sig(&pd->pd_cv, &pd->pd_mtx);
+	mutex_exit(&pd->pd_mtx);
+
+	mutex_destroy(&pd->pd_mtx);
+	cv_destroy(&pd->pd_cv);
+
+	kmem_free(czb, sizeof (zbookmark_phys_t));
+	kmem_free(pd, sizeof (struct prefetch_data));
+	kmem_free(td, sizeof (struct traverse_data));
+
+	return (err);
+}
+
+/*
+ * NB: dataset must not be changing on-disk (eg, is a snapshot or we are
+ * in syncing context).
+ */
+int
+traverse_dataset(dsl_dataset_t *ds, uint64_t txg_start, int flags,
+    blkptr_cb_t func, void *arg)
+{
+	return (traverse_impl(ds->ds_dir->dd_pool->dp_spa, ds, ds->ds_object,
+	    &dsl_dataset_phys(ds)->ds_bp, txg_start, NULL, flags, func, arg));
+}
+
+int
+traverse_dataset_destroyed(spa_t *spa, blkptr_t *blkptr,
+    uint64_t txg_start, zbookmark_phys_t *resume, int flags,
+    blkptr_cb_t func, void *arg)
+{
+	return (traverse_impl(spa, NULL, ZB_DESTROYED_OBJSET,
+	    blkptr, txg_start, resume, flags, func, arg));
+}
+
+/*
+ * NB: pool must not be changing on-disk (eg, from zdb or sync context).
+ */
+int
+traverse_pool(spa_t *spa, uint64_t txg_start, int flags,
+    blkptr_cb_t func, void *arg)
+{
+	int err;
+	uint64_t obj;
+	dsl_pool_t *dp = spa_get_dsl(spa);
+	objset_t *mos = dp->dp_meta_objset;
+	boolean_t hard = (flags & TRAVERSE_HARD);
+
+	/* visit the MOS */
+	err = traverse_impl(spa, NULL, 0, spa_get_rootblkptr(spa),
+	    txg_start, NULL, flags, func, arg);
+	if (err != 0)
+		return (err);
+
+	/* visit each dataset */
+	for (obj = 1; err == 0;
+	    err = dmu_object_next(mos, &obj, FALSE, txg_start)) {
+		dmu_object_info_t doi;
+
+		err = dmu_object_info(mos, obj, &doi);
+		if (err != 0) {
+			if (hard)
+				continue;
+			break;
+		}
+
+		if (doi.doi_bonus_type == DMU_OT_DSL_DATASET) {
+			dsl_dataset_t *ds;
+			uint64_t txg = txg_start;
+
+			dsl_pool_config_enter(dp, FTAG);
+			err = dsl_dataset_hold_obj(dp, obj, FTAG, &ds);
+			dsl_pool_config_exit(dp, FTAG);
+			if (err != 0) {
+				if (hard)
+					continue;
+				break;
+			}
+			if (dsl_dataset_phys(ds)->ds_prev_snap_txg > txg)
+				txg = dsl_dataset_phys(ds)->ds_prev_snap_txg;
+			err = traverse_dataset(ds, txg, flags, func, arg);
+			dsl_dataset_rele(ds, FTAG);
+			if (err != 0)
+				break;
+		}
+	}
+	if (err == ESRCH)
+		err = 0;
+	return (err);
+}
+
+#if defined(_KERNEL) && defined(HAVE_SPL)
+EXPORT_SYMBOL(traverse_dataset);
+EXPORT_SYMBOL(traverse_pool);
+
+module_param(zfs_pd_bytes_max, int, 0644);
+MODULE_PARM_DESC(zfs_pd_bytes_max, "Max number of bytes to prefetch");
+#endif
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/module/zfs/dmu_tx.c
@@ -0,0 +1,1692 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2011 Nexenta Systems, Inc.  All rights reserved.
+ * Copyright (c) 2012, 2015 by Delphix. All rights reserved.
+ */
+
+#include <sys/dmu.h>
+#include <sys/dmu_impl.h>
+#include <sys/dbuf.h>
+#include <sys/dmu_tx.h>
+#include <sys/dmu_objset.h>
+#include <sys/dsl_dataset.h> /* for dsl_dataset_block_freeable() */
+#include <sys/dsl_dir.h> /* for dsl_dir_tempreserve_*() */
+#include <sys/dsl_pool.h>
+#include <sys/zap_impl.h> /* for fzap_default_block_shift */
+#include <sys/spa.h>
+#include <sys/sa.h>
+#include <sys/sa_impl.h>
+#include <sys/zfs_context.h>
+#include <sys/varargs.h>
+#include <sys/trace_dmu.h>
+
+typedef void (*dmu_tx_hold_func_t)(dmu_tx_t *tx, struct dnode *dn,
+    uint64_t arg1, uint64_t arg2);
+
+dmu_tx_stats_t dmu_tx_stats = {
+	{ "dmu_tx_assigned",		KSTAT_DATA_UINT64 },
+	{ "dmu_tx_delay",		KSTAT_DATA_UINT64 },
+	{ "dmu_tx_error",		KSTAT_DATA_UINT64 },
+	{ "dmu_tx_suspended",		KSTAT_DATA_UINT64 },
+	{ "dmu_tx_group",		KSTAT_DATA_UINT64 },
+	{ "dmu_tx_memory_reserve",	KSTAT_DATA_UINT64 },
+	{ "dmu_tx_memory_reclaim",	KSTAT_DATA_UINT64 },
+	{ "dmu_tx_dirty_throttle",	KSTAT_DATA_UINT64 },
+	{ "dmu_tx_dirty_delay",		KSTAT_DATA_UINT64 },
+	{ "dmu_tx_dirty_over_max",	KSTAT_DATA_UINT64 },
+	{ "dmu_tx_quota",		KSTAT_DATA_UINT64 },
+};
+
+static kstat_t *dmu_tx_ksp;
+
+dmu_tx_t *
+dmu_tx_create_dd(dsl_dir_t *dd)
+{
+	dmu_tx_t *tx = kmem_zalloc(sizeof (dmu_tx_t), KM_SLEEP);
+	tx->tx_dir = dd;
+	if (dd != NULL)
+		tx->tx_pool = dd->dd_pool;
+	list_create(&tx->tx_holds, sizeof (dmu_tx_hold_t),
+	    offsetof(dmu_tx_hold_t, txh_node));
+	list_create(&tx->tx_callbacks, sizeof (dmu_tx_callback_t),
+	    offsetof(dmu_tx_callback_t, dcb_node));
+	tx->tx_start = gethrtime();
+#ifdef DEBUG_DMU_TX
+	refcount_create(&tx->tx_space_written);
+	refcount_create(&tx->tx_space_freed);
+#endif
+	return (tx);
+}
+
+dmu_tx_t *
+dmu_tx_create(objset_t *os)
+{
+	dmu_tx_t *tx = dmu_tx_create_dd(os->os_dsl_dataset->ds_dir);
+	tx->tx_objset = os;
+	tx->tx_lastsnap_txg = dsl_dataset_prev_snap_txg(os->os_dsl_dataset);
+	return (tx);
+}
+
+dmu_tx_t *
+dmu_tx_create_assigned(struct dsl_pool *dp, uint64_t txg)
+{
+	dmu_tx_t *tx = dmu_tx_create_dd(NULL);
+
+	ASSERT3U(txg, <=, dp->dp_tx.tx_open_txg);
+	tx->tx_pool = dp;
+	tx->tx_txg = txg;
+	tx->tx_anyobj = TRUE;
+
+	return (tx);
+}
+
+int
+dmu_tx_is_syncing(dmu_tx_t *tx)
+{
+	return (tx->tx_anyobj);
+}
+
+int
+dmu_tx_private_ok(dmu_tx_t *tx)
+{
+	return (tx->tx_anyobj);
+}
+
+static dmu_tx_hold_t *
+dmu_tx_hold_object_impl(dmu_tx_t *tx, objset_t *os, uint64_t object,
+    enum dmu_tx_hold_type type, uint64_t arg1, uint64_t arg2)
+{
+	dmu_tx_hold_t *txh;
+	dnode_t *dn = NULL;
+	int err;
+
+	if (object != DMU_NEW_OBJECT) {
+		err = dnode_hold(os, object, tx, &dn);
+		if (err) {
+			tx->tx_err = err;
+			return (NULL);
+		}
+
+		if (err == 0 && tx->tx_txg != 0) {
+			mutex_enter(&dn->dn_mtx);
+			/*
+			 * dn->dn_assigned_txg == tx->tx_txg doesn't pose a
+			 * problem, but there's no way for it to happen (for
+			 * now, at least).
+			 */
+			ASSERT(dn->dn_assigned_txg == 0);
+			dn->dn_assigned_txg = tx->tx_txg;
+			(void) refcount_add(&dn->dn_tx_holds, tx);
+			mutex_exit(&dn->dn_mtx);
+		}
+	}
+
+	txh = kmem_zalloc(sizeof (dmu_tx_hold_t), KM_SLEEP);
+	txh->txh_tx = tx;
+	txh->txh_dnode = dn;
+#ifdef DEBUG_DMU_TX
+	txh->txh_type = type;
+	txh->txh_arg1 = arg1;
+	txh->txh_arg2 = arg2;
+#endif
+	list_insert_tail(&tx->tx_holds, txh);
+
+	return (txh);
+}
+
+void
+dmu_tx_add_new_object(dmu_tx_t *tx, objset_t *os, uint64_t object)
+{
+	/*
+	 * If we're syncing, they can manipulate any object anyhow, and
+	 * the hold on the dnode_t can cause problems.
+	 */
+	if (!dmu_tx_is_syncing(tx)) {
+		(void) dmu_tx_hold_object_impl(tx, os,
+		    object, THT_NEWOBJECT, 0, 0);
+	}
+}
+
+static int
+dmu_tx_check_ioerr(zio_t *zio, dnode_t *dn, int level, uint64_t blkid)
+{
+	int err;
+	dmu_buf_impl_t *db;
+
+	rw_enter(&dn->dn_struct_rwlock, RW_READER);
+	db = dbuf_hold_level(dn, level, blkid, FTAG);
+	rw_exit(&dn->dn_struct_rwlock);
+	if (db == NULL)
+		return (SET_ERROR(EIO));
+	err = dbuf_read(db, zio, DB_RF_CANFAIL | DB_RF_NOPREFETCH);
+	dbuf_rele(db, FTAG);
+	return (err);
+}
+
+static void
+dmu_tx_count_twig(dmu_tx_hold_t *txh, dnode_t *dn, dmu_buf_impl_t *db,
+    int level, uint64_t blkid, boolean_t freeable, uint64_t *history)
+{
+	objset_t *os = dn->dn_objset;
+	dsl_dataset_t *ds = os->os_dsl_dataset;
+	int epbs = dn->dn_indblkshift - SPA_BLKPTRSHIFT;
+	dmu_buf_impl_t *parent = NULL;
+	blkptr_t *bp = NULL;
+	uint64_t space;
+
+	if (level >= dn->dn_nlevels || history[level] == blkid)
+		return;
+
+	history[level] = blkid;
+
+	space = (level == 0) ? dn->dn_datablksz : (1ULL << dn->dn_indblkshift);
+
+	if (db == NULL || db == dn->dn_dbuf) {
+		ASSERT(level != 0);
+		db = NULL;
+	} else {
+		ASSERT(DB_DNODE(db) == dn);
+		ASSERT(db->db_level == level);
+		ASSERT(db->db.db_size == space);
+		ASSERT(db->db_blkid == blkid);
+		bp = db->db_blkptr;
+		parent = db->db_parent;
+	}
+
+	freeable = (bp && (freeable ||
+	    dsl_dataset_block_freeable(ds, bp, bp->blk_birth)));
+
+	if (freeable)
+		txh->txh_space_tooverwrite += space;
+	else
+		txh->txh_space_towrite += space;
+	if (bp)
+		txh->txh_space_tounref += bp_get_dsize(os->os_spa, bp);
+
+	dmu_tx_count_twig(txh, dn, parent, level + 1,
+	    blkid >> epbs, freeable, history);
+}
+
+/* ARGSUSED */
+static void
+dmu_tx_count_write(dmu_tx_hold_t *txh, uint64_t off, uint64_t len)
+{
+	dnode_t *dn = txh->txh_dnode;
+	uint64_t start, end, i;
+	int min_bs, max_bs, min_ibs, max_ibs, epbs, bits;
+	int err = 0;
+	int l;
+
+	if (len == 0)
+		return;
+
+	min_bs = SPA_MINBLOCKSHIFT;
+	max_bs = highbit64(txh->txh_tx->tx_objset->os_recordsize) - 1;
+	min_ibs = DN_MIN_INDBLKSHIFT;
+	max_ibs = DN_MAX_INDBLKSHIFT;
+
+	if (dn) {
+		uint64_t history[DN_MAX_LEVELS];
+		int nlvls = dn->dn_nlevels;
+		int delta;
+
+		/*
+		 * For i/o error checking, read the first and last level-0
+		 * blocks (if they are not aligned), and all the level-1 blocks.
+		 */
+		if (dn->dn_maxblkid == 0) {
+			delta = dn->dn_datablksz;
+			start = (off < dn->dn_datablksz) ? 0 : 1;
+			end = (off+len <= dn->dn_datablksz) ? 0 : 1;
+			if (start == 0 && (off > 0 || len < dn->dn_datablksz)) {
+				err = dmu_tx_check_ioerr(NULL, dn, 0, 0);
+				if (err)
+					goto out;
+				delta -= off;
+			}
+		} else {
+			zio_t *zio = zio_root(dn->dn_objset->os_spa,
+			    NULL, NULL, ZIO_FLAG_CANFAIL);
+
+			/* first level-0 block */
+			start = off >> dn->dn_datablkshift;
+			if (P2PHASE(off, dn->dn_datablksz) ||
+			    len < dn->dn_datablksz) {
+				err = dmu_tx_check_ioerr(zio, dn, 0, start);
+				if (err)
+					goto out;
+			}
+
+			/* last level-0 block */
+			end = (off+len-1) >> dn->dn_datablkshift;
+			if (end != start && end <= dn->dn_maxblkid &&
+			    P2PHASE(off+len, dn->dn_datablksz)) {
+				err = dmu_tx_check_ioerr(zio, dn, 0, end);
+				if (err)
+					goto out;
+			}
+
+			/* level-1 blocks */
+			if (nlvls > 1) {
+				int shft = dn->dn_indblkshift - SPA_BLKPTRSHIFT;
+				for (i = (start>>shft)+1; i < end>>shft; i++) {
+					err = dmu_tx_check_ioerr(zio, dn, 1, i);
+					if (err)
+						goto out;
+				}
+			}
+
+			err = zio_wait(zio);
+			if (err)
+				goto out;
+			delta = P2NPHASE(off, dn->dn_datablksz);
+		}
+
+		min_ibs = max_ibs = dn->dn_indblkshift;
+		if (dn->dn_maxblkid > 0) {
+			/*
+			 * The blocksize can't change,
+			 * so we can make a more precise estimate.
+			 */
+			ASSERT(dn->dn_datablkshift != 0);
+			min_bs = max_bs = dn->dn_datablkshift;
+		} else {
+			/*
+			 * The blocksize can increase up to the recordsize,
+			 * or if it is already more than the recordsize,
+			 * up to the next power of 2.
+			 */
+			min_bs = highbit64(dn->dn_datablksz - 1);
+			max_bs = MAX(max_bs, highbit64(dn->dn_datablksz - 1));
+		}
+
+		/*
+		 * If this write is not off the end of the file
+		 * we need to account for overwrites/unref.
+		 */
+		if (start <= dn->dn_maxblkid) {
+			for (l = 0; l < DN_MAX_LEVELS; l++)
+				history[l] = -1ULL;
+		}
+		while (start <= dn->dn_maxblkid) {
+			dmu_buf_impl_t *db;
+
+			rw_enter(&dn->dn_struct_rwlock, RW_READER);
+			err = dbuf_hold_impl(dn, 0, start, FALSE, FTAG, &db);
+			rw_exit(&dn->dn_struct_rwlock);
+
+			if (err) {
+				txh->txh_tx->tx_err = err;
+				return;
+			}
+
+			dmu_tx_count_twig(txh, dn, db, 0, start, B_FALSE,
+			    history);
+			dbuf_rele(db, FTAG);
+			if (++start > end) {
+				/*
+				 * Account for new indirects appearing
+				 * before this IO gets assigned into a txg.
+				 */
+				bits = 64 - min_bs;
+				epbs = min_ibs - SPA_BLKPTRSHIFT;
+				for (bits -= epbs * (nlvls - 1);
+				    bits >= 0; bits -= epbs)
+					txh->txh_fudge += 1ULL << max_ibs;
+				goto out;
+			}
+			off += delta;
+			if (len >= delta)
+				len -= delta;
+			delta = dn->dn_datablksz;
+		}
+	}
+
+	/*
+	 * 'end' is the last thing we will access, not one past.
+	 * This way we won't overflow when accessing the last byte.
+	 */
+	start = P2ALIGN(off, 1ULL << max_bs);
+	end = P2ROUNDUP(off + len, 1ULL << max_bs) - 1;
+	txh->txh_space_towrite += end - start + 1;
+
+	start >>= min_bs;
+	end >>= min_bs;
+
+	epbs = min_ibs - SPA_BLKPTRSHIFT;
+
+	/*
+	 * The object contains at most 2^(64 - min_bs) blocks,
+	 * and each indirect level maps 2^epbs.
+	 */
+	for (bits = 64 - min_bs; bits >= 0; bits -= epbs) {
+		start >>= epbs;
+		end >>= epbs;
+		ASSERT3U(end, >=, start);
+		txh->txh_space_towrite += (end - start + 1) << max_ibs;
+		if (start != 0) {
+			/*
+			 * We also need a new blkid=0 indirect block
+			 * to reference any existing file data.
+			 */
+			txh->txh_space_towrite += 1ULL << max_ibs;
+		}
+	}
+
+out:
+	if (txh->txh_space_towrite + txh->txh_space_tooverwrite >
+	    2 * DMU_MAX_ACCESS)
+		err = SET_ERROR(EFBIG);
+
+	if (err)
+		txh->txh_tx->tx_err = err;
+}
+
+static void
+dmu_tx_count_dnode(dmu_tx_hold_t *txh)
+{
+	dnode_t *dn = txh->txh_dnode;
+	dnode_t *mdn = DMU_META_DNODE(txh->txh_tx->tx_objset);
+	uint64_t space = mdn->dn_datablksz +
+	    ((mdn->dn_nlevels-1) << mdn->dn_indblkshift);
+
+	if (dn && dn->dn_dbuf->db_blkptr &&
+	    dsl_dataset_block_freeable(dn->dn_objset->os_dsl_dataset,
+	    dn->dn_dbuf->db_blkptr, dn->dn_dbuf->db_blkptr->blk_birth)) {
+		txh->txh_space_tooverwrite += space;
+		txh->txh_space_tounref += space;
+	} else {
+		txh->txh_space_towrite += space;
+		if (dn && dn->dn_dbuf->db_blkptr)
+			txh->txh_space_tounref += space;
+	}
+}
+
+void
+dmu_tx_hold_write(dmu_tx_t *tx, uint64_t object, uint64_t off, int len)
+{
+	dmu_tx_hold_t *txh;
+
+	ASSERT(tx->tx_txg == 0);
+	ASSERT(len <= DMU_MAX_ACCESS);
+	ASSERT(len == 0 || UINT64_MAX - off >= len - 1);
+
+	txh = dmu_tx_hold_object_impl(tx, tx->tx_objset,
+	    object, THT_WRITE, off, len);
+	if (txh == NULL)
+		return;
+
+	dmu_tx_count_write(txh, off, len);
+	dmu_tx_count_dnode(txh);
+}
+
+static void
+dmu_tx_count_free(dmu_tx_hold_t *txh, uint64_t off, uint64_t len)
+{
+	uint64_t blkid, nblks, lastblk;
+	uint64_t space = 0, unref = 0, skipped = 0;
+	dnode_t *dn = txh->txh_dnode;
+	dsl_dataset_t *ds = dn->dn_objset->os_dsl_dataset;
+	spa_t *spa = txh->txh_tx->tx_pool->dp_spa;
+	int epbs;
+	uint64_t l0span = 0, nl1blks = 0;
+
+	if (dn->dn_nlevels == 0)
+		return;
+
+	/*
+	 * The struct_rwlock protects us against dn_nlevels
+	 * changing, in case (against all odds) we manage to dirty &
+	 * sync out the changes after we check for being dirty.
+	 * Also, dbuf_hold_impl() wants us to have the struct_rwlock.
+	 */
+	rw_enter(&dn->dn_struct_rwlock, RW_READER);
+	epbs = dn->dn_indblkshift - SPA_BLKPTRSHIFT;
+	if (dn->dn_maxblkid == 0) {
+		if (off == 0 && len >= dn->dn_datablksz) {
+			blkid = 0;
+			nblks = 1;
+		} else {
+			rw_exit(&dn->dn_struct_rwlock);
+			return;
+		}
+	} else {
+		blkid = off >> dn->dn_datablkshift;
+		nblks = (len + dn->dn_datablksz - 1) >> dn->dn_datablkshift;
+
+		if (blkid > dn->dn_maxblkid) {
+			rw_exit(&dn->dn_struct_rwlock);
+			return;
+		}
+		if (blkid + nblks > dn->dn_maxblkid)
+			nblks = dn->dn_maxblkid - blkid + 1;
+
+	}
+	l0span = nblks;    /* save for later use to calc level > 1 overhead */
+	if (dn->dn_nlevels == 1) {
+		int i;
+		for (i = 0; i < nblks; i++) {
+			blkptr_t *bp = dn->dn_phys->dn_blkptr;
+			ASSERT3U(blkid + i, <, dn->dn_nblkptr);
+			bp += blkid + i;
+			if (dsl_dataset_block_freeable(ds, bp, bp->blk_birth)) {
+				dprintf_bp(bp, "can free old%s", "");
+				space += bp_get_dsize(spa, bp);
+			}
+			unref += BP_GET_ASIZE(bp);
+		}
+		nl1blks = 1;
+		nblks = 0;
+	}
+
+	lastblk = blkid + nblks - 1;
+	while (nblks) {
+		dmu_buf_impl_t *dbuf;
+		uint64_t ibyte, new_blkid;
+		int epb = 1 << epbs;
+		int err, i, blkoff, tochk;
+		blkptr_t *bp;
+
+		ibyte = blkid << dn->dn_datablkshift;
+		err = dnode_next_offset(dn,
+		    DNODE_FIND_HAVELOCK, &ibyte, 2, 1, 0);
+		new_blkid = ibyte >> dn->dn_datablkshift;
+		if (err == ESRCH) {
+			skipped += (lastblk >> epbs) - (blkid >> epbs) + 1;
+			break;
+		}
+		if (err) {
+			txh->txh_tx->tx_err = err;
+			break;
+		}
+		if (new_blkid > lastblk) {
+			skipped += (lastblk >> epbs) - (blkid >> epbs) + 1;
+			break;
+		}
+
+		if (new_blkid > blkid) {
+			ASSERT((new_blkid >> epbs) > (blkid >> epbs));
+			skipped += (new_blkid >> epbs) - (blkid >> epbs) - 1;
+			nblks -= new_blkid - blkid;
+			blkid = new_blkid;
+		}
+		blkoff = P2PHASE(blkid, epb);
+		tochk = MIN(epb - blkoff, nblks);
+
+		err = dbuf_hold_impl(dn, 1, blkid >> epbs, FALSE, FTAG, &dbuf);
+		if (err) {
+			txh->txh_tx->tx_err = err;
+			break;
+		}
+
+		txh->txh_memory_tohold += dbuf->db.db_size;
+
+		/*
+		 * We don't check memory_tohold against DMU_MAX_ACCESS because
+		 * memory_tohold is an over-estimation (especially the >L1
+		 * indirect blocks), so it could fail.  Callers should have
+		 * already verified that they will not be holding too much
+		 * memory.
+		 */
+
+		err = dbuf_read(dbuf, NULL, DB_RF_HAVESTRUCT | DB_RF_CANFAIL);
+		if (err != 0) {
+			txh->txh_tx->tx_err = err;
+			dbuf_rele(dbuf, FTAG);
+			break;
+		}
+
+		bp = dbuf->db.db_data;
+		bp += blkoff;
+
+		for (i = 0; i < tochk; i++) {
+			if (dsl_dataset_block_freeable(ds, &bp[i],
+			    bp[i].blk_birth)) {
+				dprintf_bp(&bp[i], "can free old%s", "");
+				space += bp_get_dsize(spa, &bp[i]);
+			}
+			unref += BP_GET_ASIZE(bp);
+		}
+		dbuf_rele(dbuf, FTAG);
+
+		++nl1blks;
+		blkid += tochk;
+		nblks -= tochk;
+	}
+	rw_exit(&dn->dn_struct_rwlock);
+
+	/*
+	 * Add in memory requirements of higher-level indirects.
+	 * This assumes a worst-possible scenario for dn_nlevels and a
+	 * worst-possible distribution of l1-blocks over the region to free.
+	 */
+	{
+		uint64_t blkcnt = 1 + ((l0span >> epbs) >> epbs);
+		int level = 2;
+		/*
+		 * Here we don't use DN_MAX_LEVEL, but calculate it with the
+		 * given datablkshift and indblkshift. This makes the
+		 * difference between 19 and 8 on large files.
+		 */
+		int maxlevel = 2 + (DN_MAX_OFFSET_SHIFT - dn->dn_datablkshift) /
+		    (dn->dn_indblkshift - SPA_BLKPTRSHIFT);
+
+		while (level++ < maxlevel) {
+			txh->txh_memory_tohold += MAX(MIN(blkcnt, nl1blks), 1)
+			    << dn->dn_indblkshift;
+			blkcnt = 1 + (blkcnt >> epbs);
+		}
+	}
+
+	/* account for new level 1 indirect blocks that might show up */
+	if (skipped > 0) {
+		txh->txh_fudge += skipped << dn->dn_indblkshift;
+		skipped = MIN(skipped, DMU_MAX_DELETEBLKCNT >> epbs);
+		txh->txh_memory_tohold += skipped << dn->dn_indblkshift;
+	}
+	txh->txh_space_tofree += space;
+	txh->txh_space_tounref += unref;
+}
+
+void
+dmu_tx_hold_free(dmu_tx_t *tx, uint64_t object, uint64_t off, uint64_t len)
+{
+	dmu_tx_hold_t *txh;
+	dnode_t *dn;
+	int err;
+	zio_t *zio;
+
+	ASSERT(tx->tx_txg == 0);
+
+	txh = dmu_tx_hold_object_impl(tx, tx->tx_objset,
+	    object, THT_FREE, off, len);
+	if (txh == NULL)
+		return;
+	dn = txh->txh_dnode;
+	dmu_tx_count_dnode(txh);
+
+	if (off >= (dn->dn_maxblkid+1) * dn->dn_datablksz)
+		return;
+	if (len == DMU_OBJECT_END)
+		len = (dn->dn_maxblkid+1) * dn->dn_datablksz - off;
+
+	dmu_tx_count_dnode(txh);
+
+	/*
+	 * For i/o error checking, we read the first and last level-0
+	 * blocks if they are not aligned, and all the level-1 blocks.
+	 *
+	 * Note:  dbuf_free_range() assumes that we have not instantiated
+	 * any level-0 dbufs that will be completely freed.  Therefore we must
+	 * exercise care to not read or count the first and last blocks
+	 * if they are blocksize-aligned.
+	 */
+	if (dn->dn_datablkshift == 0) {
+		if (off != 0 || len < dn->dn_datablksz)
+			dmu_tx_count_write(txh, 0, dn->dn_datablksz);
+	} else {
+		/* first block will be modified if it is not aligned */
+		if (!IS_P2ALIGNED(off, 1 << dn->dn_datablkshift))
+			dmu_tx_count_write(txh, off, 1);
+		/* last block will be modified if it is not aligned */
+		if (!IS_P2ALIGNED(off + len, 1 << dn->dn_datablkshift))
+			dmu_tx_count_write(txh, off+len, 1);
+	}
+
+	/*
+	 * Check level-1 blocks.
+	 */
+	if (dn->dn_nlevels > 1) {
+		int shift = dn->dn_datablkshift + dn->dn_indblkshift -
+		    SPA_BLKPTRSHIFT;
+		uint64_t start = off >> shift;
+		uint64_t end = (off + len) >> shift;
+		uint64_t i;
+
+		ASSERT(dn->dn_indblkshift != 0);
+
+		/*
+		 * dnode_reallocate() can result in an object with indirect
+		 * blocks having an odd data block size.  In this case,
+		 * just check the single block.
+		 */
+		if (dn->dn_datablkshift == 0)
+			start = end = 0;
+
+		zio = zio_root(tx->tx_pool->dp_spa,
+		    NULL, NULL, ZIO_FLAG_CANFAIL);
+		for (i = start; i <= end; i++) {
+			uint64_t ibyte = i << shift;
+			err = dnode_next_offset(dn, 0, &ibyte, 2, 1, 0);
+			i = ibyte >> shift;
+			if (err == ESRCH || i > end)
+				break;
+			if (err) {
+				tx->tx_err = err;
+				return;
+			}
+
+			err = dmu_tx_check_ioerr(zio, dn, 1, i);
+			if (err) {
+				tx->tx_err = err;
+				return;
+			}
+		}
+		err = zio_wait(zio);
+		if (err) {
+			tx->tx_err = err;
+			return;
+		}
+	}
+
+	dmu_tx_count_free(txh, off, len);
+}
+
+void
+dmu_tx_hold_zap(dmu_tx_t *tx, uint64_t object, int add, const char *name)
+{
+	dmu_tx_hold_t *txh;
+	dnode_t *dn;
+	dsl_dataset_phys_t *ds_phys;
+	uint64_t nblocks;
+	int epbs, err;
+
+	ASSERT(tx->tx_txg == 0);
+
+	txh = dmu_tx_hold_object_impl(tx, tx->tx_objset,
+	    object, THT_ZAP, add, (uintptr_t)name);
+	if (txh == NULL)
+		return;
+	dn = txh->txh_dnode;
+
+	dmu_tx_count_dnode(txh);
+
+	if (dn == NULL) {
+		/*
+		 * We will be able to fit a new object's entries into one leaf
+		 * block.  So there will be at most 2 blocks total,
+		 * including the header block.
+		 */
+		dmu_tx_count_write(txh, 0, 2 << fzap_default_block_shift);
+		return;
+	}
+
+	ASSERT3U(DMU_OT_BYTESWAP(dn->dn_type), ==, DMU_BSWAP_ZAP);
+
+	if (dn->dn_maxblkid == 0 && !add) {
+		blkptr_t *bp;
+
+		/*
+		 * If there is only one block  (i.e. this is a micro-zap)
+		 * and we are not adding anything, the accounting is simple.
+		 */
+		err = dmu_tx_check_ioerr(NULL, dn, 0, 0);
+		if (err) {
+			tx->tx_err = err;
+			return;
+		}
+
+		/*
+		 * Use max block size here, since we don't know how much
+		 * the size will change between now and the dbuf dirty call.
+		 */
+		bp = &dn->dn_phys->dn_blkptr[0];
+		if (dsl_dataset_block_freeable(dn->dn_objset->os_dsl_dataset,
+		    bp, bp->blk_birth))
+			txh->txh_space_tooverwrite += MZAP_MAX_BLKSZ;
+		else
+			txh->txh_space_towrite += MZAP_MAX_BLKSZ;
+		if (!BP_IS_HOLE(bp))
+			txh->txh_space_tounref += MZAP_MAX_BLKSZ;
+		return;
+	}
+
+	if (dn->dn_maxblkid > 0 && name) {
+		/*
+		 * access the name in this fat-zap so that we'll check
+		 * for i/o errors to the leaf blocks, etc.
+		 */
+		err = zap_lookup(dn->dn_objset, dn->dn_object, name,
+		    8, 0, NULL);
+		if (err == EIO) {
+			tx->tx_err = err;
+			return;
+		}
+	}
+
+	err = zap_count_write(dn->dn_objset, dn->dn_object, name, add,
+	    &txh->txh_space_towrite, &txh->txh_space_tooverwrite);
+
+	/*
+	 * If the modified blocks are scattered to the four winds,
+	 * we'll have to modify an indirect twig for each.
+	 */
+	epbs = dn->dn_indblkshift - SPA_BLKPTRSHIFT;
+	ds_phys = dsl_dataset_phys(dn->dn_objset->os_dsl_dataset);
+	for (nblocks = dn->dn_maxblkid >> epbs; nblocks != 0; nblocks >>= epbs)
+		if (ds_phys->ds_prev_snap_obj)
+			txh->txh_space_towrite += 3 << dn->dn_indblkshift;
+		else
+			txh->txh_space_tooverwrite += 3 << dn->dn_indblkshift;
+}
+
+void
+dmu_tx_hold_bonus(dmu_tx_t *tx, uint64_t object)
+{
+	dmu_tx_hold_t *txh;
+
+	ASSERT(tx->tx_txg == 0);
+
+	txh = dmu_tx_hold_object_impl(tx, tx->tx_objset,
+	    object, THT_BONUS, 0, 0);
+	if (txh)
+		dmu_tx_count_dnode(txh);
+}
+
+void
+dmu_tx_hold_space(dmu_tx_t *tx, uint64_t space)
+{
+	dmu_tx_hold_t *txh;
+
+	ASSERT(tx->tx_txg == 0);
+
+	txh = dmu_tx_hold_object_impl(tx, tx->tx_objset,
+	    DMU_NEW_OBJECT, THT_SPACE, space, 0);
+	if (txh)
+		txh->txh_space_towrite += space;
+}
+
+int
+dmu_tx_holds(dmu_tx_t *tx, uint64_t object)
+{
+	dmu_tx_hold_t *txh;
+	int holds = 0;
+
+	/*
+	 * By asserting that the tx is assigned, we're counting the
+	 * number of dn_tx_holds, which is the same as the number of
+	 * dn_holds.  Otherwise, we'd be counting dn_holds, but
+	 * dn_tx_holds could be 0.
+	 */
+	ASSERT(tx->tx_txg != 0);
+
+	/* if (tx->tx_anyobj == TRUE) */
+		/* return (0); */
+
+	for (txh = list_head(&tx->tx_holds); txh;
+	    txh = list_next(&tx->tx_holds, txh)) {
+		if (txh->txh_dnode && txh->txh_dnode->dn_object == object)
+			holds++;
+	}
+
+	return (holds);
+}
+
+#ifdef DEBUG_DMU_TX
+void
+dmu_tx_dirty_buf(dmu_tx_t *tx, dmu_buf_impl_t *db)
+{
+	dmu_tx_hold_t *txh;
+	int match_object = FALSE, match_offset = FALSE;
+	dnode_t *dn;
+
+	DB_DNODE_ENTER(db);
+	dn = DB_DNODE(db);
+	ASSERT(dn != NULL);
+	ASSERT(tx->tx_txg != 0);
+	ASSERT(tx->tx_objset == NULL || dn->dn_objset == tx->tx_objset);
+	ASSERT3U(dn->dn_object, ==, db->db.db_object);
+
+	if (tx->tx_anyobj) {
+		DB_DNODE_EXIT(db);
+		return;
+	}
+
+	/* XXX No checking on the meta dnode for now */
+	if (db->db.db_object == DMU_META_DNODE_OBJECT) {
+		DB_DNODE_EXIT(db);
+		return;
+	}
+
+	for (txh = list_head(&tx->tx_holds); txh;
+	    txh = list_next(&tx->tx_holds, txh)) {
+		ASSERT3U(dn->dn_assigned_txg, ==, tx->tx_txg);
+		if (txh->txh_dnode == dn && txh->txh_type != THT_NEWOBJECT)
+			match_object = TRUE;
+		if (txh->txh_dnode == NULL || txh->txh_dnode == dn) {
+			int datablkshift = dn->dn_datablkshift ?
+			    dn->dn_datablkshift : SPA_MAXBLOCKSHIFT;
+			int epbs = dn->dn_indblkshift - SPA_BLKPTRSHIFT;
+			int shift = datablkshift + epbs * db->db_level;
+			uint64_t beginblk = shift >= 64 ? 0 :
+			    (txh->txh_arg1 >> shift);
+			uint64_t endblk = shift >= 64 ? 0 :
+			    ((txh->txh_arg1 + txh->txh_arg2 - 1) >> shift);
+			uint64_t blkid = db->db_blkid;
+
+			/* XXX txh_arg2 better not be zero... */
+
+			dprintf("found txh type %x beginblk=%llx endblk=%llx\n",
+			    txh->txh_type, beginblk, endblk);
+
+			switch (txh->txh_type) {
+			case THT_WRITE:
+				if (blkid >= beginblk && blkid <= endblk)
+					match_offset = TRUE;
+				/*
+				 * We will let this hold work for the bonus
+				 * or spill buffer so that we don't need to
+				 * hold it when creating a new object.
+				 */
+				if (blkid == DMU_BONUS_BLKID ||
+				    blkid == DMU_SPILL_BLKID)
+					match_offset = TRUE;
+				/*
+				 * They might have to increase nlevels,
+				 * thus dirtying the new TLIBs.  Or the
+				 * might have to change the block size,
+				 * thus dirying the new lvl=0 blk=0.
+				 */
+				if (blkid == 0)
+					match_offset = TRUE;
+				break;
+			case THT_FREE:
+				/*
+				 * We will dirty all the level 1 blocks in
+				 * the free range and perhaps the first and
+				 * last level 0 block.
+				 */
+				if (blkid >= beginblk && (blkid <= endblk ||
+				    txh->txh_arg2 == DMU_OBJECT_END))
+					match_offset = TRUE;
+				break;
+			case THT_SPILL:
+				if (blkid == DMU_SPILL_BLKID)
+					match_offset = TRUE;
+				break;
+			case THT_BONUS:
+				if (blkid == DMU_BONUS_BLKID)
+					match_offset = TRUE;
+				break;
+			case THT_ZAP:
+				match_offset = TRUE;
+				break;
+			case THT_NEWOBJECT:
+				match_object = TRUE;
+				break;
+			default:
+				cmn_err(CE_PANIC, "bad txh_type %d",
+				    txh->txh_type);
+			}
+		}
+		if (match_object && match_offset) {
+			DB_DNODE_EXIT(db);
+			return;
+		}
+	}
+	DB_DNODE_EXIT(db);
+	panic("dirtying dbuf obj=%llx lvl=%u blkid=%llx but not tx_held\n",
+	    (u_longlong_t)db->db.db_object, db->db_level,
+	    (u_longlong_t)db->db_blkid);
+}
+#endif
+
+/*
+ * If we can't do 10 iops, something is wrong.  Let us go ahead
+ * and hit zfs_dirty_data_max.
+ */
+hrtime_t zfs_delay_max_ns = 100 * MICROSEC; /* 100 milliseconds */
+int zfs_delay_resolution_ns = 100 * 1000; /* 100 microseconds */
+
+/*
+ * We delay transactions when we've determined that the backend storage
+ * isn't able to accommodate the rate of incoming writes.
+ *
+ * If there is already a transaction waiting, we delay relative to when
+ * that transaction finishes waiting.  This way the calculated min_time
+ * is independent of the number of threads concurrently executing
+ * transactions.
+ *
+ * If we are the only waiter, wait relative to when the transaction
+ * started, rather than the current time.  This credits the transaction for
+ * "time already served", e.g. reading indirect blocks.
+ *
+ * The minimum time for a transaction to take is calculated as:
+ *     min_time = scale * (dirty - min) / (max - dirty)
+ *     min_time is then capped at zfs_delay_max_ns.
+ *
+ * The delay has two degrees of freedom that can be adjusted via tunables.
+ * The percentage of dirty data at which we start to delay is defined by
+ * zfs_delay_min_dirty_percent. This should typically be at or above
+ * zfs_vdev_async_write_active_max_dirty_percent so that we only start to
+ * delay after writing at full speed has failed to keep up with the incoming
+ * write rate. The scale of the curve is defined by zfs_delay_scale. Roughly
+ * speaking, this variable determines the amount of delay at the midpoint of
+ * the curve.
+ *
+ * delay
+ *  10ms +-------------------------------------------------------------*+
+ *       |                                                             *|
+ *   9ms +                                                             *+
+ *       |                                                             *|
+ *   8ms +                                                             *+
+ *       |                                                            * |
+ *   7ms +                                                            * +
+ *       |                                                            * |
+ *   6ms +                                                            * +
+ *       |                                                            * |
+ *   5ms +                                                           *  +
+ *       |                                                           *  |
+ *   4ms +                                                           *  +
+ *       |                                                           *  |
+ *   3ms +                                                          *   +
+ *       |                                                          *   |
+ *   2ms +                                              (midpoint) *    +
+ *       |                                                  |    **     |
+ *   1ms +                                                  v ***       +
+ *       |             zfs_delay_scale ---------->     ********         |
+ *     0 +-------------------------------------*********----------------+
+ *       0%                    <- zfs_dirty_data_max ->               100%
+ *
+ * Note that since the delay is added to the outstanding time remaining on the
+ * most recent transaction, the delay is effectively the inverse of IOPS.
+ * Here the midpoint of 500us translates to 2000 IOPS. The shape of the curve
+ * was chosen such that small changes in the amount of accumulated dirty data
+ * in the first 3/4 of the curve yield relatively small differences in the
+ * amount of delay.
+ *
+ * The effects can be easier to understand when the amount of delay is
+ * represented on a log scale:
+ *
+ * delay
+ * 100ms +-------------------------------------------------------------++
+ *       +                                                              +
+ *       |                                                              |
+ *       +                                                             *+
+ *  10ms +                                                             *+
+ *       +                                                           ** +
+ *       |                                              (midpoint)  **  |
+ *       +                                                  |     **    +
+ *   1ms +                                                  v ****      +
+ *       +             zfs_delay_scale ---------->        *****         +
+ *       |                                             ****             |
+ *       +                                          ****                +
+ * 100us +                                        **                    +
+ *       +                                       *                      +
+ *       |                                      *                       |
+ *       +                                     *                        +
+ *  10us +                                     *                        +
+ *       +                                                              +
+ *       |                                                              |
+ *       +                                                              +
+ *       +--------------------------------------------------------------+
+ *       0%                    <- zfs_dirty_data_max ->               100%
+ *
+ * Note here that only as the amount of dirty data approaches its limit does
+ * the delay start to increase rapidly. The goal of a properly tuned system
+ * should be to keep the amount of dirty data out of that range by first
+ * ensuring that the appropriate limits are set for the I/O scheduler to reach
+ * optimal throughput on the backend storage, and then by changing the value
+ * of zfs_delay_scale to increase the steepness of the curve.
+ */
+static void
+dmu_tx_delay(dmu_tx_t *tx, uint64_t dirty)
+{
+	dsl_pool_t *dp = tx->tx_pool;
+	uint64_t delay_min_bytes =
+	    zfs_dirty_data_max * zfs_delay_min_dirty_percent / 100;
+	hrtime_t wakeup, min_tx_time, now;
+
+	if (dirty <= delay_min_bytes)
+		return;
+
+	/*
+	 * The caller has already waited until we are under the max.
+	 * We make them pass us the amount of dirty data so we don't
+	 * have to handle the case of it being >= the max, which could
+	 * cause a divide-by-zero if it's == the max.
+	 */
+	ASSERT3U(dirty, <, zfs_dirty_data_max);
+
+	now = gethrtime();
+	min_tx_time = zfs_delay_scale *
+	    (dirty - delay_min_bytes) / (zfs_dirty_data_max - dirty);
+	min_tx_time = MIN(min_tx_time, zfs_delay_max_ns);
+	if (now > tx->tx_start + min_tx_time)
+		return;
+
+	DTRACE_PROBE3(delay__mintime, dmu_tx_t *, tx, uint64_t, dirty,
+	    uint64_t, min_tx_time);
+
+	mutex_enter(&dp->dp_lock);
+	wakeup = MAX(tx->tx_start + min_tx_time,
+	    dp->dp_last_wakeup + min_tx_time);
+	dp->dp_last_wakeup = wakeup;
+	mutex_exit(&dp->dp_lock);
+
+	zfs_sleep_until(wakeup);
+}
+
+static int
+dmu_tx_try_assign(dmu_tx_t *tx, txg_how_t txg_how)
+{
+	dmu_tx_hold_t *txh;
+	spa_t *spa = tx->tx_pool->dp_spa;
+	uint64_t memory, asize, fsize, usize;
+	uint64_t towrite, tofree, tooverwrite, tounref, tohold, fudge;
+
+	ASSERT0(tx->tx_txg);
+
+	if (tx->tx_err) {
+		DMU_TX_STAT_BUMP(dmu_tx_error);
+		return (tx->tx_err);
+	}
+
+	if (spa_suspended(spa)) {
+		DMU_TX_STAT_BUMP(dmu_tx_suspended);
+
+		/*
+		 * If the user has indicated a blocking failure mode
+		 * then return ERESTART which will block in dmu_tx_wait().
+		 * Otherwise, return EIO so that an error can get
+		 * propagated back to the VOP calls.
+		 *
+		 * Note that we always honor the txg_how flag regardless
+		 * of the failuremode setting.
+		 */
+		if (spa_get_failmode(spa) == ZIO_FAILURE_MODE_CONTINUE &&
+		    txg_how != TXG_WAIT)
+			return (SET_ERROR(EIO));
+
+		return (SET_ERROR(ERESTART));
+	}
+
+	if (!tx->tx_waited &&
+	    dsl_pool_need_dirty_delay(tx->tx_pool)) {
+		tx->tx_wait_dirty = B_TRUE;
+		DMU_TX_STAT_BUMP(dmu_tx_dirty_delay);
+		return (ERESTART);
+	}
+
+	tx->tx_txg = txg_hold_open(tx->tx_pool, &tx->tx_txgh);
+	tx->tx_needassign_txh = NULL;
+
+	/*
+	 * NB: No error returns are allowed after txg_hold_open, but
+	 * before processing the dnode holds, due to the
+	 * dmu_tx_unassign() logic.
+	 */
+
+	towrite = tofree = tooverwrite = tounref = tohold = fudge = 0;
+	for (txh = list_head(&tx->tx_holds); txh;
+	    txh = list_next(&tx->tx_holds, txh)) {
+		dnode_t *dn = txh->txh_dnode;
+		if (dn != NULL) {
+			mutex_enter(&dn->dn_mtx);
+			if (dn->dn_assigned_txg == tx->tx_txg - 1) {
+				mutex_exit(&dn->dn_mtx);
+				tx->tx_needassign_txh = txh;
+				DMU_TX_STAT_BUMP(dmu_tx_group);
+				return (SET_ERROR(ERESTART));
+			}
+			if (dn->dn_assigned_txg == 0)
+				dn->dn_assigned_txg = tx->tx_txg;
+			ASSERT3U(dn->dn_assigned_txg, ==, tx->tx_txg);
+			(void) refcount_add(&dn->dn_tx_holds, tx);
+			mutex_exit(&dn->dn_mtx);
+		}
+		towrite += txh->txh_space_towrite;
+		tofree += txh->txh_space_tofree;
+		tooverwrite += txh->txh_space_tooverwrite;
+		tounref += txh->txh_space_tounref;
+		tohold += txh->txh_memory_tohold;
+		fudge += txh->txh_fudge;
+	}
+
+	/*
+	 * If a snapshot has been taken since we made our estimates,
+	 * assume that we won't be able to free or overwrite anything.
+	 */
+	if (tx->tx_objset &&
+	    dsl_dataset_prev_snap_txg(tx->tx_objset->os_dsl_dataset) >
+	    tx->tx_lastsnap_txg) {
+		towrite += tooverwrite;
+		tooverwrite = tofree = 0;
+	}
+
+	/* needed allocation: worst-case estimate of write space */
+	asize = spa_get_asize(tx->tx_pool->dp_spa, towrite + tooverwrite);
+	/* freed space estimate: worst-case overwrite + free estimate */
+	fsize = spa_get_asize(tx->tx_pool->dp_spa, tooverwrite) + tofree;
+	/* convert unrefd space to worst-case estimate */
+	usize = spa_get_asize(tx->tx_pool->dp_spa, tounref);
+	/* calculate memory footprint estimate */
+	memory = towrite + tooverwrite + tohold;
+
+#ifdef DEBUG_DMU_TX
+	/*
+	 * Add in 'tohold' to account for our dirty holds on this memory
+	 * XXX - the "fudge" factor is to account for skipped blocks that
+	 * we missed because dnode_next_offset() misses in-core-only blocks.
+	 */
+	tx->tx_space_towrite = asize +
+	    spa_get_asize(tx->tx_pool->dp_spa, tohold + fudge);
+	tx->tx_space_tofree = tofree;
+	tx->tx_space_tooverwrite = tooverwrite;
+	tx->tx_space_tounref = tounref;
+#endif
+
+	if (tx->tx_dir && asize != 0) {
+		int err = dsl_dir_tempreserve_space(tx->tx_dir, memory,
+		    asize, fsize, usize, &tx->tx_tempreserve_cookie, tx);
+		if (err)
+			return (err);
+	}
+
+	DMU_TX_STAT_BUMP(dmu_tx_assigned);
+
+	return (0);
+}
+
+static void
+dmu_tx_unassign(dmu_tx_t *tx)
+{
+	dmu_tx_hold_t *txh;
+
+	if (tx->tx_txg == 0)
+		return;
+
+	txg_rele_to_quiesce(&tx->tx_txgh);
+
+	/*
+	 * Walk the transaction's hold list, removing the hold on the
+	 * associated dnode, and notifying waiters if the refcount drops to 0.
+	 */
+	for (txh = list_head(&tx->tx_holds); txh != tx->tx_needassign_txh;
+	    txh = list_next(&tx->tx_holds, txh)) {
+		dnode_t *dn = txh->txh_dnode;
+
+		if (dn == NULL)
+			continue;
+		mutex_enter(&dn->dn_mtx);
+		ASSERT3U(dn->dn_assigned_txg, ==, tx->tx_txg);
+
+		if (refcount_remove(&dn->dn_tx_holds, tx) == 0) {
+			dn->dn_assigned_txg = 0;
+			cv_broadcast(&dn->dn_notxholds);
+		}
+		mutex_exit(&dn->dn_mtx);
+	}
+
+	txg_rele_to_sync(&tx->tx_txgh);
+
+	tx->tx_lasttried_txg = tx->tx_txg;
+	tx->tx_txg = 0;
+}
+
+/*
+ * Assign tx to a transaction group.  txg_how can be one of:
+ *
+ * (1)	TXG_WAIT.  If the current open txg is full, waits until there's
+ *	a new one.  This should be used when you're not holding locks.
+ *	It will only fail if we're truly out of space (or over quota).
+ *
+ * (2)	TXG_NOWAIT.  If we can't assign into the current open txg without
+ *	blocking, returns immediately with ERESTART.  This should be used
+ *	whenever you're holding locks.  On an ERESTART error, the caller
+ *	should drop locks, do a dmu_tx_wait(tx), and try again.
+ *
+ * (3)	TXG_WAITED.  Like TXG_NOWAIT, but indicates that dmu_tx_wait()
+ *	has already been called on behalf of this operation (though
+ *	most likely on a different tx).
+ */
+int
+dmu_tx_assign(dmu_tx_t *tx, txg_how_t txg_how)
+{
+	int err;
+
+	ASSERT(tx->tx_txg == 0);
+	ASSERT(txg_how == TXG_WAIT || txg_how == TXG_NOWAIT ||
+	    txg_how == TXG_WAITED);
+	ASSERT(!dsl_pool_sync_context(tx->tx_pool));
+
+	if (txg_how == TXG_WAITED)
+		tx->tx_waited = B_TRUE;
+
+	/* If we might wait, we must not hold the config lock. */
+	ASSERT(txg_how != TXG_WAIT || !dsl_pool_config_held(tx->tx_pool));
+
+	while ((err = dmu_tx_try_assign(tx, txg_how)) != 0) {
+		dmu_tx_unassign(tx);
+
+		if (err != ERESTART || txg_how != TXG_WAIT)
+			return (err);
+
+		dmu_tx_wait(tx);
+	}
+
+	txg_rele_to_quiesce(&tx->tx_txgh);
+
+	return (0);
+}
+
+void
+dmu_tx_wait(dmu_tx_t *tx)
+{
+	spa_t *spa = tx->tx_pool->dp_spa;
+	dsl_pool_t *dp = tx->tx_pool;
+	hrtime_t before;
+
+	ASSERT(tx->tx_txg == 0);
+	ASSERT(!dsl_pool_config_held(tx->tx_pool));
+
+	before = gethrtime();
+
+	if (tx->tx_wait_dirty) {
+		uint64_t dirty;
+
+		/*
+		 * dmu_tx_try_assign() has determined that we need to wait
+		 * because we've consumed much or all of the dirty buffer
+		 * space.
+		 */
+		mutex_enter(&dp->dp_lock);
+		if (dp->dp_dirty_total >= zfs_dirty_data_max)
+			DMU_TX_STAT_BUMP(dmu_tx_dirty_over_max);
+		while (dp->dp_dirty_total >= zfs_dirty_data_max)
+			cv_wait(&dp->dp_spaceavail_cv, &dp->dp_lock);
+		dirty = dp->dp_dirty_total;
+		mutex_exit(&dp->dp_lock);
+
+		dmu_tx_delay(tx, dirty);
+
+		tx->tx_wait_dirty = B_FALSE;
+
+		/*
+		 * Note: setting tx_waited only has effect if the caller
+		 * used TX_WAIT.  Otherwise they are going to destroy
+		 * this tx and try again.  The common case, zfs_write(),
+		 * uses TX_WAIT.
+		 */
+		tx->tx_waited = B_TRUE;
+	} else if (spa_suspended(spa) || tx->tx_lasttried_txg == 0) {
+		/*
+		 * If the pool is suspended we need to wait until it
+		 * is resumed.  Note that it's possible that the pool
+		 * has become active after this thread has tried to
+		 * obtain a tx.  If that's the case then tx_lasttried_txg
+		 * would not have been set.
+		 */
+		txg_wait_synced(dp, spa_last_synced_txg(spa) + 1);
+	} else if (tx->tx_needassign_txh) {
+		dnode_t *dn = tx->tx_needassign_txh->txh_dnode;
+
+		mutex_enter(&dn->dn_mtx);
+		while (dn->dn_assigned_txg == tx->tx_lasttried_txg - 1)
+			cv_wait(&dn->dn_notxholds, &dn->dn_mtx);
+		mutex_exit(&dn->dn_mtx);
+		tx->tx_needassign_txh = NULL;
+	} else {
+		/*
+		 * A dnode is assigned to the quiescing txg.  Wait for its
+		 * transaction to complete.
+		 */
+		txg_wait_open(tx->tx_pool, tx->tx_lasttried_txg + 1);
+	}
+
+	spa_tx_assign_add_nsecs(spa, gethrtime() - before);
+}
+
+void
+dmu_tx_willuse_space(dmu_tx_t *tx, int64_t delta)
+{
+#ifdef DEBUG_DMU_TX
+	if (tx->tx_dir == NULL || delta == 0)
+		return;
+
+	if (delta > 0) {
+		ASSERT3U(refcount_count(&tx->tx_space_written) + delta, <=,
+		    tx->tx_space_towrite);
+		(void) refcount_add_many(&tx->tx_space_written, delta, NULL);
+	} else {
+		(void) refcount_add_many(&tx->tx_space_freed, -delta, NULL);
+	}
+#endif
+}
+
+void
+dmu_tx_commit(dmu_tx_t *tx)
+{
+	dmu_tx_hold_t *txh;
+
+	ASSERT(tx->tx_txg != 0);
+
+	/*
+	 * Go through the transaction's hold list and remove holds on
+	 * associated dnodes, notifying waiters if no holds remain.
+	 */
+	while ((txh = list_head(&tx->tx_holds))) {
+		dnode_t *dn = txh->txh_dnode;
+
+		list_remove(&tx->tx_holds, txh);
+		kmem_free(txh, sizeof (dmu_tx_hold_t));
+		if (dn == NULL)
+			continue;
+		mutex_enter(&dn->dn_mtx);
+		ASSERT3U(dn->dn_assigned_txg, ==, tx->tx_txg);
+
+		if (refcount_remove(&dn->dn_tx_holds, tx) == 0) {
+			dn->dn_assigned_txg = 0;
+			cv_broadcast(&dn->dn_notxholds);
+		}
+		mutex_exit(&dn->dn_mtx);
+		dnode_rele(dn, tx);
+	}
+
+	if (tx->tx_tempreserve_cookie)
+		dsl_dir_tempreserve_clear(tx->tx_tempreserve_cookie, tx);
+
+	if (!list_is_empty(&tx->tx_callbacks))
+		txg_register_callbacks(&tx->tx_txgh, &tx->tx_callbacks);
+
+	if (tx->tx_anyobj == FALSE)
+		txg_rele_to_sync(&tx->tx_txgh);
+
+	list_destroy(&tx->tx_callbacks);
+	list_destroy(&tx->tx_holds);
+#ifdef DEBUG_DMU_TX
+	dprintf("towrite=%llu written=%llu tofree=%llu freed=%llu\n",
+	    tx->tx_space_towrite, refcount_count(&tx->tx_space_written),
+	    tx->tx_space_tofree, refcount_count(&tx->tx_space_freed));
+	refcount_destroy_many(&tx->tx_space_written,
+	    refcount_count(&tx->tx_space_written));
+	refcount_destroy_many(&tx->tx_space_freed,
+	    refcount_count(&tx->tx_space_freed));
+#endif
+	kmem_free(tx, sizeof (dmu_tx_t));
+}
+
+void
+dmu_tx_abort(dmu_tx_t *tx)
+{
+	dmu_tx_hold_t *txh;
+
+	ASSERT(tx->tx_txg == 0);
+
+	while ((txh = list_head(&tx->tx_holds))) {
+		dnode_t *dn = txh->txh_dnode;
+
+		list_remove(&tx->tx_holds, txh);
+		kmem_free(txh, sizeof (dmu_tx_hold_t));
+		if (dn != NULL)
+			dnode_rele(dn, tx);
+	}
+
+	/*
+	 * Call any registered callbacks with an error code.
+	 */
+	if (!list_is_empty(&tx->tx_callbacks))
+		dmu_tx_do_callbacks(&tx->tx_callbacks, ECANCELED);
+
+	list_destroy(&tx->tx_callbacks);
+	list_destroy(&tx->tx_holds);
+#ifdef DEBUG_DMU_TX
+	refcount_destroy_many(&tx->tx_space_written,
+	    refcount_count(&tx->tx_space_written));
+	refcount_destroy_many(&tx->tx_space_freed,
+	    refcount_count(&tx->tx_space_freed));
+#endif
+	kmem_free(tx, sizeof (dmu_tx_t));
+}
+
+uint64_t
+dmu_tx_get_txg(dmu_tx_t *tx)
+{
+	ASSERT(tx->tx_txg != 0);
+	return (tx->tx_txg);
+}
+
+dsl_pool_t *
+dmu_tx_pool(dmu_tx_t *tx)
+{
+	ASSERT(tx->tx_pool != NULL);
+	return (tx->tx_pool);
+}
+
+void
+dmu_tx_callback_register(dmu_tx_t *tx, dmu_tx_callback_func_t *func, void *data)
+{
+	dmu_tx_callback_t *dcb;
+
+	dcb = kmem_alloc(sizeof (dmu_tx_callback_t), KM_SLEEP);
+
+	dcb->dcb_func = func;
+	dcb->dcb_data = data;
+
+	list_insert_tail(&tx->tx_callbacks, dcb);
+}
+
+/*
+ * Call all the commit callbacks on a list, with a given error code.
+ */
+void
+dmu_tx_do_callbacks(list_t *cb_list, int error)
+{
+	dmu_tx_callback_t *dcb;
+
+	while ((dcb = list_head(cb_list))) {
+		list_remove(cb_list, dcb);
+		dcb->dcb_func(dcb->dcb_data, error);
+		kmem_free(dcb, sizeof (dmu_tx_callback_t));
+	}
+}
+
+/*
+ * Interface to hold a bunch of attributes.
+ * used for creating new files.
+ * attrsize is the total size of all attributes
+ * to be added during object creation
+ *
+ * For updating/adding a single attribute dmu_tx_hold_sa() should be used.
+ */
+
+/*
+ * hold necessary attribute name for attribute registration.
+ * should be a very rare case where this is needed.  If it does
+ * happen it would only happen on the first write to the file system.
+ */
+static void
+dmu_tx_sa_registration_hold(sa_os_t *sa, dmu_tx_t *tx)
+{
+	int i;
+
+	if (!sa->sa_need_attr_registration)
+		return;
+
+	for (i = 0; i != sa->sa_num_attrs; i++) {
+		if (!sa->sa_attr_table[i].sa_registered) {
+			if (sa->sa_reg_attr_obj)
+				dmu_tx_hold_zap(tx, sa->sa_reg_attr_obj,
+				    B_TRUE, sa->sa_attr_table[i].sa_name);
+			else
+				dmu_tx_hold_zap(tx, DMU_NEW_OBJECT,
+				    B_TRUE, sa->sa_attr_table[i].sa_name);
+		}
+	}
+}
+
+
+void
+dmu_tx_hold_spill(dmu_tx_t *tx, uint64_t object)
+{
+	dnode_t *dn;
+	dmu_tx_hold_t *txh;
+
+	txh = dmu_tx_hold_object_impl(tx, tx->tx_objset, object,
+	    THT_SPILL, 0, 0);
+	if (txh == NULL)
+		return;
+
+	dn = txh->txh_dnode;
+
+	if (dn == NULL)
+		return;
+
+	/* If blkptr doesn't exist then add space to towrite */
+	if (!(dn->dn_phys->dn_flags & DNODE_FLAG_SPILL_BLKPTR)) {
+		txh->txh_space_towrite += SPA_OLD_MAXBLOCKSIZE;
+	} else {
+		blkptr_t *bp;
+
+		bp = &dn->dn_phys->dn_spill;
+		if (dsl_dataset_block_freeable(dn->dn_objset->os_dsl_dataset,
+		    bp, bp->blk_birth))
+			txh->txh_space_tooverwrite += SPA_OLD_MAXBLOCKSIZE;
+		else
+			txh->txh_space_towrite += SPA_OLD_MAXBLOCKSIZE;
+		if (!BP_IS_HOLE(bp))
+			txh->txh_space_tounref += SPA_OLD_MAXBLOCKSIZE;
+	}
+}
+
+void
+dmu_tx_hold_sa_create(dmu_tx_t *tx, int attrsize)
+{
+	sa_os_t *sa = tx->tx_objset->os_sa;
+
+	dmu_tx_hold_bonus(tx, DMU_NEW_OBJECT);
+
+	if (tx->tx_objset->os_sa->sa_master_obj == 0)
+		return;
+
+	if (tx->tx_objset->os_sa->sa_layout_attr_obj)
+		dmu_tx_hold_zap(tx, sa->sa_layout_attr_obj, B_TRUE, NULL);
+	else {
+		dmu_tx_hold_zap(tx, sa->sa_master_obj, B_TRUE, SA_LAYOUTS);
+		dmu_tx_hold_zap(tx, sa->sa_master_obj, B_TRUE, SA_REGISTRY);
+		dmu_tx_hold_zap(tx, DMU_NEW_OBJECT, B_TRUE, NULL);
+		dmu_tx_hold_zap(tx, DMU_NEW_OBJECT, B_TRUE, NULL);
+	}
+
+	dmu_tx_sa_registration_hold(sa, tx);
+
+	if (attrsize <= DN_MAX_BONUSLEN && !sa->sa_force_spill)
+		return;
+
+	(void) dmu_tx_hold_object_impl(tx, tx->tx_objset, DMU_NEW_OBJECT,
+	    THT_SPILL, 0, 0);
+}
+
+/*
+ * Hold SA attribute
+ *
+ * dmu_tx_hold_sa(dmu_tx_t *tx, sa_handle_t *, attribute, add, size)
+ *
+ * variable_size is the total size of all variable sized attributes
+ * passed to this function.  It is not the total size of all
+ * variable size attributes that *may* exist on this object.
+ */
+void
+dmu_tx_hold_sa(dmu_tx_t *tx, sa_handle_t *hdl, boolean_t may_grow)
+{
+	uint64_t object;
+	sa_os_t *sa = tx->tx_objset->os_sa;
+
+	ASSERT(hdl != NULL);
+
+	object = sa_handle_object(hdl);
+
+	dmu_tx_hold_bonus(tx, object);
+
+	if (tx->tx_objset->os_sa->sa_master_obj == 0)
+		return;
+
+	if (tx->tx_objset->os_sa->sa_reg_attr_obj == 0 ||
+	    tx->tx_objset->os_sa->sa_layout_attr_obj == 0) {
+		dmu_tx_hold_zap(tx, sa->sa_master_obj, B_TRUE, SA_LAYOUTS);
+		dmu_tx_hold_zap(tx, sa->sa_master_obj, B_TRUE, SA_REGISTRY);
+		dmu_tx_hold_zap(tx, DMU_NEW_OBJECT, B_TRUE, NULL);
+		dmu_tx_hold_zap(tx, DMU_NEW_OBJECT, B_TRUE, NULL);
+	}
+
+	dmu_tx_sa_registration_hold(sa, tx);
+
+	if (may_grow && tx->tx_objset->os_sa->sa_layout_attr_obj)
+		dmu_tx_hold_zap(tx, sa->sa_layout_attr_obj, B_TRUE, NULL);
+
+	if (sa->sa_force_spill || may_grow || hdl->sa_spill) {
+		ASSERT(tx->tx_txg == 0);
+		dmu_tx_hold_spill(tx, object);
+	} else {
+		dmu_buf_impl_t *db = (dmu_buf_impl_t *)hdl->sa_bonus;
+		dnode_t *dn;
+
+		DB_DNODE_ENTER(db);
+		dn = DB_DNODE(db);
+		if (dn->dn_have_spill) {
+			ASSERT(tx->tx_txg == 0);
+			dmu_tx_hold_spill(tx, object);
+		}
+		DB_DNODE_EXIT(db);
+	}
+}
+
+void
+dmu_tx_init(void)
+{
+	dmu_tx_ksp = kstat_create("zfs", 0, "dmu_tx", "misc",
+	    KSTAT_TYPE_NAMED, sizeof (dmu_tx_stats) / sizeof (kstat_named_t),
+	    KSTAT_FLAG_VIRTUAL);
+
+	if (dmu_tx_ksp != NULL) {
+		dmu_tx_ksp->ks_data = &dmu_tx_stats;
+		kstat_install(dmu_tx_ksp);
+	}
+}
+
+void
+dmu_tx_fini(void)
+{
+	if (dmu_tx_ksp != NULL) {
+		kstat_delete(dmu_tx_ksp);
+		dmu_tx_ksp = NULL;
+	}
+}
+
+#if defined(_KERNEL) && defined(HAVE_SPL)
+EXPORT_SYMBOL(dmu_tx_create);
+EXPORT_SYMBOL(dmu_tx_hold_write);
+EXPORT_SYMBOL(dmu_tx_hold_free);
+EXPORT_SYMBOL(dmu_tx_hold_zap);
+EXPORT_SYMBOL(dmu_tx_hold_bonus);
+EXPORT_SYMBOL(dmu_tx_abort);
+EXPORT_SYMBOL(dmu_tx_assign);
+EXPORT_SYMBOL(dmu_tx_wait);
+EXPORT_SYMBOL(dmu_tx_commit);
+EXPORT_SYMBOL(dmu_tx_get_txg);
+EXPORT_SYMBOL(dmu_tx_callback_register);
+EXPORT_SYMBOL(dmu_tx_do_callbacks);
+EXPORT_SYMBOL(dmu_tx_hold_spill);
+EXPORT_SYMBOL(dmu_tx_hold_sa_create);
+EXPORT_SYMBOL(dmu_tx_hold_sa);
+#endif
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/module/zfs/dmu_zfetch.c
@@ -0,0 +1,748 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/*
+ * Copyright (c) 2013 by Delphix. All rights reserved.
+ */
+
+#include <sys/zfs_context.h>
+#include <sys/dnode.h>
+#include <sys/dmu_objset.h>
+#include <sys/dmu_zfetch.h>
+#include <sys/dmu.h>
+#include <sys/dbuf.h>
+#include <sys/kstat.h>
+
+/*
+ * I'm against tune-ables, but these should probably exist as tweakable globals
+ * until we can get this working the way we want it to.
+ */
+
+int zfs_prefetch_disable = 0;
+
+/* max # of streams per zfetch */
+unsigned int	zfetch_max_streams = 8;
+/* min time before stream reclaim */
+unsigned int	zfetch_min_sec_reap = 2;
+/* max number of blocks to fetch at a time */
+unsigned int	zfetch_block_cap = 256;
+/* number of bytes in a array_read at which we stop prefetching (1Mb) */
+unsigned long	zfetch_array_rd_sz = 1024 * 1024;
+
+/* forward decls for static routines */
+static boolean_t	dmu_zfetch_colinear(zfetch_t *, zstream_t *);
+static void		dmu_zfetch_dofetch(zfetch_t *, zstream_t *);
+static uint64_t		dmu_zfetch_fetch(dnode_t *, uint64_t, uint64_t);
+static uint64_t		dmu_zfetch_fetchsz(dnode_t *, uint64_t, uint64_t);
+static boolean_t	dmu_zfetch_find(zfetch_t *, zstream_t *, int);
+static int		dmu_zfetch_stream_insert(zfetch_t *, zstream_t *);
+static zstream_t	*dmu_zfetch_stream_reclaim(zfetch_t *);
+static void		dmu_zfetch_stream_remove(zfetch_t *, zstream_t *);
+static int		dmu_zfetch_streams_equal(zstream_t *, zstream_t *);
+
+typedef struct zfetch_stats {
+	kstat_named_t zfetchstat_hits;
+	kstat_named_t zfetchstat_misses;
+	kstat_named_t zfetchstat_colinear_hits;
+	kstat_named_t zfetchstat_colinear_misses;
+	kstat_named_t zfetchstat_stride_hits;
+	kstat_named_t zfetchstat_stride_misses;
+	kstat_named_t zfetchstat_reclaim_successes;
+	kstat_named_t zfetchstat_reclaim_failures;
+	kstat_named_t zfetchstat_stream_resets;
+	kstat_named_t zfetchstat_stream_noresets;
+	kstat_named_t zfetchstat_bogus_streams;
+} zfetch_stats_t;
+
+static zfetch_stats_t zfetch_stats = {
+	{ "hits",			KSTAT_DATA_UINT64 },
+	{ "misses",			KSTAT_DATA_UINT64 },
+	{ "colinear_hits",		KSTAT_DATA_UINT64 },
+	{ "colinear_misses",		KSTAT_DATA_UINT64 },
+	{ "stride_hits",		KSTAT_DATA_UINT64 },
+	{ "stride_misses",		KSTAT_DATA_UINT64 },
+	{ "reclaim_successes",		KSTAT_DATA_UINT64 },
+	{ "reclaim_failures",		KSTAT_DATA_UINT64 },
+	{ "streams_resets",		KSTAT_DATA_UINT64 },
+	{ "streams_noresets",		KSTAT_DATA_UINT64 },
+	{ "bogus_streams",		KSTAT_DATA_UINT64 },
+};
+
+#define	ZFETCHSTAT_INCR(stat, val) \
+	atomic_add_64(&zfetch_stats.stat.value.ui64, (val));
+
+#define	ZFETCHSTAT_BUMP(stat)		ZFETCHSTAT_INCR(stat, 1);
+
+kstat_t		*zfetch_ksp;
+
+/*
+ * Given a zfetch structure and a zstream structure, determine whether the
+ * blocks to be read are part of a co-linear pair of existing prefetch
+ * streams.  If a set is found, coalesce the streams, removing one, and
+ * configure the prefetch so it looks for a strided access pattern.
+ *
+ * In other words: if we find two sequential access streams that are
+ * the same length and distance N appart, and this read is N from the
+ * last stream, then we are probably in a strided access pattern.  So
+ * combine the two sequential streams into a single strided stream.
+ *
+ * Returns whether co-linear streams were found.
+ */
+static boolean_t
+dmu_zfetch_colinear(zfetch_t *zf, zstream_t *zh)
+{
+	zstream_t	*z_walk;
+	zstream_t	*z_comp;
+
+	if (! rw_tryenter(&zf->zf_rwlock, RW_WRITER))
+		return (0);
+
+	if (zh == NULL) {
+		rw_exit(&zf->zf_rwlock);
+		return (0);
+	}
+
+	for (z_walk = list_head(&zf->zf_stream); z_walk;
+	    z_walk = list_next(&zf->zf_stream, z_walk)) {
+		for (z_comp = list_next(&zf->zf_stream, z_walk); z_comp;
+		    z_comp = list_next(&zf->zf_stream, z_comp)) {
+			int64_t		diff;
+
+			if (z_walk->zst_len != z_walk->zst_stride ||
+			    z_comp->zst_len != z_comp->zst_stride) {
+				continue;
+			}
+
+			diff = z_comp->zst_offset - z_walk->zst_offset;
+			if (z_comp->zst_offset + diff == zh->zst_offset) {
+				z_walk->zst_offset = zh->zst_offset;
+				z_walk->zst_direction = diff < 0 ?
+				    ZFETCH_BACKWARD : ZFETCH_FORWARD;
+				z_walk->zst_stride =
+				    diff * z_walk->zst_direction;
+				z_walk->zst_ph_offset =
+				    zh->zst_offset + z_walk->zst_stride;
+				dmu_zfetch_stream_remove(zf, z_comp);
+				mutex_destroy(&z_comp->zst_lock);
+				kmem_free(z_comp, sizeof (zstream_t));
+
+				dmu_zfetch_dofetch(zf, z_walk);
+
+				rw_exit(&zf->zf_rwlock);
+				return (1);
+			}
+
+			diff = z_walk->zst_offset - z_comp->zst_offset;
+			if (z_walk->zst_offset + diff == zh->zst_offset) {
+				z_walk->zst_offset = zh->zst_offset;
+				z_walk->zst_direction = diff < 0 ?
+				    ZFETCH_BACKWARD : ZFETCH_FORWARD;
+				z_walk->zst_stride =
+				    diff * z_walk->zst_direction;
+				z_walk->zst_ph_offset =
+				    zh->zst_offset + z_walk->zst_stride;
+				dmu_zfetch_stream_remove(zf, z_comp);
+				mutex_destroy(&z_comp->zst_lock);
+				kmem_free(z_comp, sizeof (zstream_t));
+
+				dmu_zfetch_dofetch(zf, z_walk);
+
+				rw_exit(&zf->zf_rwlock);
+				return (1);
+			}
+		}
+	}
+
+	rw_exit(&zf->zf_rwlock);
+	return (0);
+}
+
+/*
+ * Given a zstream_t, determine the bounds of the prefetch.  Then call the
+ * routine that actually prefetches the individual blocks.
+ */
+static void
+dmu_zfetch_dofetch(zfetch_t *zf, zstream_t *zs)
+{
+	uint64_t	prefetch_tail;
+	uint64_t	prefetch_limit;
+	uint64_t	prefetch_ofst;
+	uint64_t	prefetch_len;
+	uint64_t	blocks_fetched;
+
+	zs->zst_stride = MAX((int64_t)zs->zst_stride, zs->zst_len);
+	zs->zst_cap = MIN(zfetch_block_cap, 2 * zs->zst_cap);
+
+	prefetch_tail = MAX((int64_t)zs->zst_ph_offset,
+	    (int64_t)(zs->zst_offset + zs->zst_stride));
+	/*
+	 * XXX: use a faster division method?
+	 */
+	prefetch_limit = zs->zst_offset + zs->zst_len +
+	    (zs->zst_cap * zs->zst_stride) / zs->zst_len;
+
+	while (prefetch_tail < prefetch_limit) {
+		prefetch_ofst = zs->zst_offset + zs->zst_direction *
+		    (prefetch_tail - zs->zst_offset);
+
+		prefetch_len = zs->zst_len;
+
+		/*
+		 * Don't prefetch beyond the end of the file, if working
+		 * backwards.
+		 */
+		if ((zs->zst_direction == ZFETCH_BACKWARD) &&
+		    (prefetch_ofst > prefetch_tail)) {
+			prefetch_len += prefetch_ofst;
+			prefetch_ofst = 0;
+		}
+
+		/* don't prefetch more than we're supposed to */
+		if (prefetch_len > zs->zst_len)
+			break;
+
+		blocks_fetched = dmu_zfetch_fetch(zf->zf_dnode,
+		    prefetch_ofst, zs->zst_len);
+
+		prefetch_tail += zs->zst_stride;
+		/* stop if we've run out of stuff to prefetch */
+		if (blocks_fetched < zs->zst_len)
+			break;
+	}
+	zs->zst_ph_offset = prefetch_tail;
+	zs->zst_last = ddi_get_lbolt();
+}
+
+void
+zfetch_init(void)
+{
+
+	zfetch_ksp = kstat_create("zfs", 0, "zfetchstats", "misc",
+	    KSTAT_TYPE_NAMED, sizeof (zfetch_stats) / sizeof (kstat_named_t),
+	    KSTAT_FLAG_VIRTUAL);
+
+	if (zfetch_ksp != NULL) {
+		zfetch_ksp->ks_data = &zfetch_stats;
+		kstat_install(zfetch_ksp);
+	}
+}
+
+void
+zfetch_fini(void)
+{
+	if (zfetch_ksp != NULL) {
+		kstat_delete(zfetch_ksp);
+		zfetch_ksp = NULL;
+	}
+}
+
+/*
+ * This takes a pointer to a zfetch structure and a dnode.  It performs the
+ * necessary setup for the zfetch structure, grokking data from the
+ * associated dnode.
+ */
+void
+dmu_zfetch_init(zfetch_t *zf, dnode_t *dno)
+{
+	if (zf == NULL) {
+		return;
+	}
+
+	zf->zf_dnode = dno;
+	zf->zf_stream_cnt = 0;
+	zf->zf_alloc_fail = 0;
+
+	list_create(&zf->zf_stream, sizeof (zstream_t),
+	    offsetof(zstream_t, zst_node));
+
+	rw_init(&zf->zf_rwlock, NULL, RW_DEFAULT, NULL);
+}
+
+/*
+ * This function computes the actual size, in blocks, that can be prefetched,
+ * and fetches it.
+ */
+static uint64_t
+dmu_zfetch_fetch(dnode_t *dn, uint64_t blkid, uint64_t nblks)
+{
+	uint64_t	fetchsz;
+	uint64_t	i;
+
+	fetchsz = dmu_zfetch_fetchsz(dn, blkid, nblks);
+
+	for (i = 0; i < fetchsz; i++) {
+		dbuf_prefetch(dn, blkid + i, ZIO_PRIORITY_ASYNC_READ);
+	}
+
+	return (fetchsz);
+}
+
+/*
+ * this function returns the number of blocks that would be prefetched, based
+ * upon the supplied dnode, blockid, and nblks.  This is used so that we can
+ * update streams in place, and then prefetch with their old value after the
+ * fact.  This way, we can delay the prefetch, but subsequent accesses to the
+ * stream won't result in the same data being prefetched multiple times.
+ */
+static uint64_t
+dmu_zfetch_fetchsz(dnode_t *dn, uint64_t blkid, uint64_t nblks)
+{
+	uint64_t	fetchsz;
+
+	if (blkid > dn->dn_maxblkid) {
+		return (0);
+	}
+
+	/* compute fetch size */
+	if (blkid + nblks + 1 > dn->dn_maxblkid) {
+		fetchsz = (dn->dn_maxblkid - blkid) + 1;
+		ASSERT(blkid + fetchsz - 1 <= dn->dn_maxblkid);
+	} else {
+		fetchsz = nblks;
+	}
+
+
+	return (fetchsz);
+}
+
+/*
+ * given a zfetch and a zstream structure, see if there is an associated zstream
+ * for this block read.  If so, it starts a prefetch for the stream it
+ * located and returns true, otherwise it returns false
+ */
+static boolean_t
+dmu_zfetch_find(zfetch_t *zf, zstream_t *zh, int prefetched)
+{
+	zstream_t	*zs;
+	int64_t		diff;
+	int		reset = !prefetched;
+	int		rc = 0;
+
+	if (zh == NULL)
+		return (0);
+
+	/*
+	 * XXX: This locking strategy is a bit coarse; however, it's impact has
+	 * yet to be tested.  If this turns out to be an issue, it can be
+	 * modified in a number of different ways.
+	 */
+
+	rw_enter(&zf->zf_rwlock, RW_READER);
+top:
+
+	for (zs = list_head(&zf->zf_stream); zs;
+	    zs = list_next(&zf->zf_stream, zs)) {
+
+		/*
+		 * XXX - should this be an assert?
+		 */
+		if (zs->zst_len == 0) {
+			/* bogus stream */
+			ZFETCHSTAT_BUMP(zfetchstat_bogus_streams);
+			continue;
+		}
+
+		/*
+		 * We hit this case when we are in a strided prefetch stream:
+		 * we will read "len" blocks before "striding".
+		 */
+		if (zh->zst_offset >= zs->zst_offset &&
+		    zh->zst_offset < zs->zst_offset + zs->zst_len) {
+			if (prefetched) {
+				/* already fetched */
+				ZFETCHSTAT_BUMP(zfetchstat_stride_hits);
+				rc = 1;
+				goto out;
+			} else {
+				ZFETCHSTAT_BUMP(zfetchstat_stride_misses);
+			}
+		}
+
+		/*
+		 * This is the forward sequential read case: we increment
+		 * len by one each time we hit here, so we will enter this
+		 * case on every read.
+		 */
+		if (zh->zst_offset == zs->zst_offset + zs->zst_len) {
+
+			reset = !prefetched && zs->zst_len > 1;
+
+			mutex_enter(&zs->zst_lock);
+
+			if (zh->zst_offset != zs->zst_offset + zs->zst_len) {
+				mutex_exit(&zs->zst_lock);
+				goto top;
+			}
+			zs->zst_len += zh->zst_len;
+			diff = zs->zst_len - zfetch_block_cap;
+			if (diff > 0) {
+				zs->zst_offset += diff;
+				zs->zst_len = zs->zst_len > diff ?
+				    zs->zst_len - diff : 0;
+			}
+			zs->zst_direction = ZFETCH_FORWARD;
+
+			break;
+
+		/*
+		 * Same as above, but reading backwards through the file.
+		 */
+		} else if (zh->zst_offset == zs->zst_offset - zh->zst_len) {
+			/* backwards sequential access */
+
+			reset = !prefetched && zs->zst_len > 1;
+
+			mutex_enter(&zs->zst_lock);
+
+			if (zh->zst_offset != zs->zst_offset - zh->zst_len) {
+				mutex_exit(&zs->zst_lock);
+				goto top;
+			}
+
+			zs->zst_offset = zs->zst_offset > zh->zst_len ?
+			    zs->zst_offset - zh->zst_len : 0;
+			zs->zst_ph_offset = zs->zst_ph_offset > zh->zst_len ?
+			    zs->zst_ph_offset - zh->zst_len : 0;
+			zs->zst_len += zh->zst_len;
+
+			diff = zs->zst_len - zfetch_block_cap;
+			if (diff > 0) {
+				zs->zst_ph_offset = zs->zst_ph_offset > diff ?
+				    zs->zst_ph_offset - diff : 0;
+				zs->zst_len = zs->zst_len > diff ?
+				    zs->zst_len - diff : zs->zst_len;
+			}
+			zs->zst_direction = ZFETCH_BACKWARD;
+
+			break;
+
+		} else if ((zh->zst_offset - zs->zst_offset - zs->zst_stride <
+		    zs->zst_len) && (zs->zst_len != zs->zst_stride)) {
+			/* strided forward access */
+
+			mutex_enter(&zs->zst_lock);
+
+			if ((zh->zst_offset - zs->zst_offset - zs->zst_stride >=
+			    zs->zst_len) || (zs->zst_len == zs->zst_stride)) {
+				mutex_exit(&zs->zst_lock);
+				goto top;
+			}
+
+			zs->zst_offset += zs->zst_stride;
+			zs->zst_direction = ZFETCH_FORWARD;
+
+			break;
+
+		} else if ((zh->zst_offset - zs->zst_offset + zs->zst_stride <
+		    zs->zst_len) && (zs->zst_len != zs->zst_stride)) {
+			/* strided reverse access */
+
+			mutex_enter(&zs->zst_lock);
+
+			if ((zh->zst_offset - zs->zst_offset + zs->zst_stride >=
+			    zs->zst_len) || (zs->zst_len == zs->zst_stride)) {
+				mutex_exit(&zs->zst_lock);
+				goto top;
+			}
+
+			zs->zst_offset = zs->zst_offset > zs->zst_stride ?
+			    zs->zst_offset - zs->zst_stride : 0;
+			zs->zst_ph_offset = (zs->zst_ph_offset >
+			    (2 * zs->zst_stride)) ?
+			    (zs->zst_ph_offset - (2 * zs->zst_stride)) : 0;
+			zs->zst_direction = ZFETCH_BACKWARD;
+
+			break;
+		}
+	}
+
+	if (zs) {
+		if (reset) {
+			zstream_t *remove = zs;
+
+			ZFETCHSTAT_BUMP(zfetchstat_stream_resets);
+			rc = 0;
+			mutex_exit(&zs->zst_lock);
+			rw_exit(&zf->zf_rwlock);
+			rw_enter(&zf->zf_rwlock, RW_WRITER);
+			/*
+			 * Relocate the stream, in case someone removes
+			 * it while we were acquiring the WRITER lock.
+			 */
+			for (zs = list_head(&zf->zf_stream); zs;
+			    zs = list_next(&zf->zf_stream, zs)) {
+				if (zs == remove) {
+					dmu_zfetch_stream_remove(zf, zs);
+					mutex_destroy(&zs->zst_lock);
+					kmem_free(zs, sizeof (zstream_t));
+					break;
+				}
+			}
+		} else {
+			ZFETCHSTAT_BUMP(zfetchstat_stream_noresets);
+			rc = 1;
+			dmu_zfetch_dofetch(zf, zs);
+			mutex_exit(&zs->zst_lock);
+		}
+	}
+out:
+	rw_exit(&zf->zf_rwlock);
+	return (rc);
+}
+
+/*
+ * Clean-up state associated with a zfetch structure.  This frees allocated
+ * structure members, empties the zf_stream tree, and generally makes things
+ * nice.  This doesn't free the zfetch_t itself, that's left to the caller.
+ */
+void
+dmu_zfetch_rele(zfetch_t *zf)
+{
+	zstream_t	*zs;
+	zstream_t	*zs_next;
+
+	ASSERT(!RW_LOCK_HELD(&zf->zf_rwlock));
+
+	for (zs = list_head(&zf->zf_stream); zs; zs = zs_next) {
+		zs_next = list_next(&zf->zf_stream, zs);
+
+		list_remove(&zf->zf_stream, zs);
+		mutex_destroy(&zs->zst_lock);
+		kmem_free(zs, sizeof (zstream_t));
+	}
+	list_destroy(&zf->zf_stream);
+	rw_destroy(&zf->zf_rwlock);
+
+	zf->zf_dnode = NULL;
+}
+
+/*
+ * Given a zfetch and zstream structure, insert the zstream structure into the
+ * AVL tree contained within the zfetch structure.  Peform the appropriate
+ * book-keeping.  It is possible that another thread has inserted a stream which
+ * matches one that we are about to insert, so we must be sure to check for this
+ * case.  If one is found, return failure, and let the caller cleanup the
+ * duplicates.
+ */
+static int
+dmu_zfetch_stream_insert(zfetch_t *zf, zstream_t *zs)
+{
+	zstream_t	*zs_walk;
+	zstream_t	*zs_next;
+
+	ASSERT(RW_WRITE_HELD(&zf->zf_rwlock));
+
+	for (zs_walk = list_head(&zf->zf_stream); zs_walk; zs_walk = zs_next) {
+		zs_next = list_next(&zf->zf_stream, zs_walk);
+
+		if (dmu_zfetch_streams_equal(zs_walk, zs)) {
+			return (0);
+		}
+	}
+
+	list_insert_head(&zf->zf_stream, zs);
+	zf->zf_stream_cnt++;
+	return (1);
+}
+
+
+/*
+ * Walk the list of zstreams in the given zfetch, find an old one (by time), and
+ * reclaim it for use by the caller.
+ */
+static zstream_t *
+dmu_zfetch_stream_reclaim(zfetch_t *zf)
+{
+	zstream_t	*zs;
+
+	if (! rw_tryenter(&zf->zf_rwlock, RW_WRITER))
+		return (0);
+
+	for (zs = list_head(&zf->zf_stream); zs;
+	    zs = list_next(&zf->zf_stream, zs)) {
+
+		if (((ddi_get_lbolt() - zs->zst_last)/hz) > zfetch_min_sec_reap)
+			break;
+	}
+
+	if (zs) {
+		dmu_zfetch_stream_remove(zf, zs);
+		mutex_destroy(&zs->zst_lock);
+		bzero(zs, sizeof (zstream_t));
+	} else {
+		zf->zf_alloc_fail++;
+	}
+	rw_exit(&zf->zf_rwlock);
+
+	return (zs);
+}
+
+/*
+ * Given a zfetch and zstream structure, remove the zstream structure from its
+ * container in the zfetch structure.  Perform the appropriate book-keeping.
+ */
+static void
+dmu_zfetch_stream_remove(zfetch_t *zf, zstream_t *zs)
+{
+	ASSERT(RW_WRITE_HELD(&zf->zf_rwlock));
+
+	list_remove(&zf->zf_stream, zs);
+	zf->zf_stream_cnt--;
+}
+
+static int
+dmu_zfetch_streams_equal(zstream_t *zs1, zstream_t *zs2)
+{
+	if (zs1->zst_offset != zs2->zst_offset)
+		return (0);
+
+	if (zs1->zst_len != zs2->zst_len)
+		return (0);
+
+	if (zs1->zst_stride != zs2->zst_stride)
+		return (0);
+
+	if (zs1->zst_ph_offset != zs2->zst_ph_offset)
+		return (0);
+
+	if (zs1->zst_cap != zs2->zst_cap)
+		return (0);
+
+	if (zs1->zst_direction != zs2->zst_direction)
+		return (0);
+
+	return (1);
+}
+
+/*
+ * This is the prefetch entry point.  It calls all of the other dmu_zfetch
+ * routines to create, delete, find, or operate upon prefetch streams.
+ */
+void
+dmu_zfetch(zfetch_t *zf, uint64_t offset, uint64_t size, int prefetched)
+{
+	zstream_t	zst;
+	zstream_t	*newstream;
+	boolean_t	fetched;
+	int		inserted;
+	unsigned int	blkshft;
+	uint64_t	blksz;
+
+	if (zfs_prefetch_disable)
+		return;
+
+	/* files that aren't ln2 blocksz are only one block -- nothing to do */
+	if (!zf->zf_dnode->dn_datablkshift)
+		return;
+
+	/* convert offset and size, into blockid and nblocks */
+	blkshft = zf->zf_dnode->dn_datablkshift;
+	blksz = (1 << blkshft);
+
+	bzero(&zst, sizeof (zstream_t));
+	zst.zst_offset = offset >> blkshft;
+	zst.zst_len = (P2ROUNDUP(offset + size, blksz) -
+	    P2ALIGN(offset, blksz)) >> blkshft;
+
+	fetched = dmu_zfetch_find(zf, &zst, prefetched);
+	if (fetched) {
+		ZFETCHSTAT_BUMP(zfetchstat_hits);
+	} else {
+		ZFETCHSTAT_BUMP(zfetchstat_misses);
+		if ((fetched = dmu_zfetch_colinear(zf, &zst))) {
+			ZFETCHSTAT_BUMP(zfetchstat_colinear_hits);
+		} else {
+			ZFETCHSTAT_BUMP(zfetchstat_colinear_misses);
+		}
+	}
+
+	if (!fetched) {
+		newstream = dmu_zfetch_stream_reclaim(zf);
+
+		/*
+		 * we still couldn't find a stream, drop the lock, and allocate
+		 * one if possible.  Otherwise, give up and go home.
+		 */
+		if (newstream) {
+			ZFETCHSTAT_BUMP(zfetchstat_reclaim_successes);
+		} else {
+			uint64_t	maxblocks;
+			uint32_t	max_streams;
+			uint32_t	cur_streams;
+
+			ZFETCHSTAT_BUMP(zfetchstat_reclaim_failures);
+			cur_streams = zf->zf_stream_cnt;
+			maxblocks = zf->zf_dnode->dn_maxblkid;
+
+			max_streams = MIN(zfetch_max_streams,
+			    (maxblocks / zfetch_block_cap));
+			if (max_streams == 0) {
+				max_streams++;
+			}
+
+			if (cur_streams >= max_streams) {
+				return;
+			}
+			newstream =
+			    kmem_zalloc(sizeof (zstream_t), KM_SLEEP);
+		}
+
+		newstream->zst_offset = zst.zst_offset;
+		newstream->zst_len = zst.zst_len;
+		newstream->zst_stride = zst.zst_len;
+		newstream->zst_ph_offset = zst.zst_len + zst.zst_offset;
+		newstream->zst_cap = zst.zst_len;
+		newstream->zst_direction = ZFETCH_FORWARD;
+		newstream->zst_last = ddi_get_lbolt();
+
+		mutex_init(&newstream->zst_lock, NULL, MUTEX_DEFAULT, NULL);
+
+		rw_enter(&zf->zf_rwlock, RW_WRITER);
+		inserted = dmu_zfetch_stream_insert(zf, newstream);
+		rw_exit(&zf->zf_rwlock);
+
+		if (!inserted) {
+			mutex_destroy(&newstream->zst_lock);
+			kmem_free(newstream, sizeof (zstream_t));
+		}
+	}
+}
+
+#if defined(_KERNEL) && defined(HAVE_SPL)
+module_param(zfs_prefetch_disable, int, 0644);
+MODULE_PARM_DESC(zfs_prefetch_disable, "Disable all ZFS prefetching");
+
+module_param(zfetch_max_streams, uint, 0644);
+MODULE_PARM_DESC(zfetch_max_streams, "Max number of streams per zfetch");
+
+module_param(zfetch_min_sec_reap, uint, 0644);
+MODULE_PARM_DESC(zfetch_min_sec_reap, "Min time before stream reclaim");
+
+module_param(zfetch_block_cap, uint, 0644);
+MODULE_PARM_DESC(zfetch_block_cap, "Max number of blocks to fetch at a time");
+
+module_param(zfetch_array_rd_sz, ulong, 0644);
+MODULE_PARM_DESC(zfetch_array_rd_sz, "Number of bytes in a array_read");
+#endif
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/module/zfs/dnode.c
@@ -0,0 +1,2044 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2015 by Delphix. All rights reserved.
+ * Copyright (c) 2014 Spectra Logic Corporation, All rights reserved.
+ */
+
+#include <sys/zfs_context.h>
+#include <sys/dbuf.h>
+#include <sys/dnode.h>
+#include <sys/dmu.h>
+#include <sys/dmu_impl.h>
+#include <sys/dmu_tx.h>
+#include <sys/dmu_objset.h>
+#include <sys/dsl_dir.h>
+#include <sys/dsl_dataset.h>
+#include <sys/spa.h>
+#include <sys/zio.h>
+#include <sys/dmu_zfetch.h>
+#include <sys/range_tree.h>
+#include <sys/trace_dnode.h>
+
+static kmem_cache_t *dnode_cache;
+/*
+ * Define DNODE_STATS to turn on statistic gathering. By default, it is only
+ * turned on when DEBUG is also defined.
+ */
+#ifdef	DEBUG
+#define	DNODE_STATS
+#endif	/* DEBUG */
+
+#ifdef	DNODE_STATS
+#define	DNODE_STAT_ADD(stat)			((stat)++)
+#else
+#define	DNODE_STAT_ADD(stat)			/* nothing */
+#endif	/* DNODE_STATS */
+
+ASSERTV(static dnode_phys_t dnode_phys_zero);
+
+int zfs_default_bs = SPA_MINBLOCKSHIFT;
+int zfs_default_ibs = DN_MAX_INDBLKSHIFT;
+
+#ifdef	_KERNEL
+static kmem_cbrc_t dnode_move(void *, void *, size_t, void *);
+#endif /* _KERNEL */
+
+static int
+dbuf_compare(const void *x1, const void *x2)
+{
+	const dmu_buf_impl_t *d1 = x1;
+	const dmu_buf_impl_t *d2 = x2;
+
+	if (d1->db_level < d2->db_level) {
+		return (-1);
+	}
+	if (d1->db_level > d2->db_level) {
+		return (1);
+	}
+
+	if (d1->db_blkid < d2->db_blkid) {
+		return (-1);
+	}
+	if (d1->db_blkid > d2->db_blkid) {
+		return (1);
+	}
+
+	if (d1->db_state == DB_SEARCH) {
+		ASSERT3S(d2->db_state, !=, DB_SEARCH);
+		return (-1);
+	} else if (d2->db_state == DB_SEARCH) {
+		ASSERT3S(d1->db_state, !=, DB_SEARCH);
+		return (1);
+	}
+
+	if ((uintptr_t)d1 < (uintptr_t)d2) {
+		return (-1);
+	}
+	if ((uintptr_t)d1 > (uintptr_t)d2) {
+		return (1);
+	}
+	return (0);
+}
+
+/* ARGSUSED */
+static int
+dnode_cons(void *arg, void *unused, int kmflag)
+{
+	dnode_t *dn = arg;
+	int i;
+
+	rw_init(&dn->dn_struct_rwlock, NULL, RW_DEFAULT, NULL);
+	mutex_init(&dn->dn_mtx, NULL, MUTEX_DEFAULT, NULL);
+	mutex_init(&dn->dn_dbufs_mtx, NULL, MUTEX_DEFAULT, NULL);
+	cv_init(&dn->dn_notxholds, NULL, CV_DEFAULT, NULL);
+
+	/*
+	 * Every dbuf has a reference, and dropping a tracked reference is
+	 * O(number of references), so don't track dn_holds.
+	 */
+	refcount_create_untracked(&dn->dn_holds);
+	refcount_create(&dn->dn_tx_holds);
+	list_link_init(&dn->dn_link);
+
+	bzero(&dn->dn_next_nblkptr[0], sizeof (dn->dn_next_nblkptr));
+	bzero(&dn->dn_next_nlevels[0], sizeof (dn->dn_next_nlevels));
+	bzero(&dn->dn_next_indblkshift[0], sizeof (dn->dn_next_indblkshift));
+	bzero(&dn->dn_next_bonustype[0], sizeof (dn->dn_next_bonustype));
+	bzero(&dn->dn_rm_spillblk[0], sizeof (dn->dn_rm_spillblk));
+	bzero(&dn->dn_next_bonuslen[0], sizeof (dn->dn_next_bonuslen));
+	bzero(&dn->dn_next_blksz[0], sizeof (dn->dn_next_blksz));
+
+	for (i = 0; i < TXG_SIZE; i++) {
+		list_link_init(&dn->dn_dirty_link[i]);
+		dn->dn_free_ranges[i] = NULL;
+		list_create(&dn->dn_dirty_records[i],
+		    sizeof (dbuf_dirty_record_t),
+		    offsetof(dbuf_dirty_record_t, dr_dirty_node));
+	}
+
+	dn->dn_allocated_txg = 0;
+	dn->dn_free_txg = 0;
+	dn->dn_assigned_txg = 0;
+	dn->dn_dirtyctx = 0;
+	dn->dn_dirtyctx_firstset = NULL;
+	dn->dn_bonus = NULL;
+	dn->dn_have_spill = B_FALSE;
+	dn->dn_zio = NULL;
+	dn->dn_oldused = 0;
+	dn->dn_oldflags = 0;
+	dn->dn_olduid = 0;
+	dn->dn_oldgid = 0;
+	dn->dn_newuid = 0;
+	dn->dn_newgid = 0;
+	dn->dn_id_flags = 0;
+
+	dn->dn_dbufs_count = 0;
+	dn->dn_unlisted_l0_blkid = 0;
+	avl_create(&dn->dn_dbufs, dbuf_compare, sizeof (dmu_buf_impl_t),
+	    offsetof(dmu_buf_impl_t, db_link));
+
+	dn->dn_moved = 0;
+	return (0);
+}
+
+/* ARGSUSED */
+static void
+dnode_dest(void *arg, void *unused)
+{
+	int i;
+	dnode_t *dn = arg;
+
+	rw_destroy(&dn->dn_struct_rwlock);
+	mutex_destroy(&dn->dn_mtx);
+	mutex_destroy(&dn->dn_dbufs_mtx);
+	cv_destroy(&dn->dn_notxholds);
+	refcount_destroy(&dn->dn_holds);
+	refcount_destroy(&dn->dn_tx_holds);
+	ASSERT(!list_link_active(&dn->dn_link));
+
+	for (i = 0; i < TXG_SIZE; i++) {
+		ASSERT(!list_link_active(&dn->dn_dirty_link[i]));
+		ASSERT3P(dn->dn_free_ranges[i], ==, NULL);
+		list_destroy(&dn->dn_dirty_records[i]);
+		ASSERT0(dn->dn_next_nblkptr[i]);
+		ASSERT0(dn->dn_next_nlevels[i]);
+		ASSERT0(dn->dn_next_indblkshift[i]);
+		ASSERT0(dn->dn_next_bonustype[i]);
+		ASSERT0(dn->dn_rm_spillblk[i]);
+		ASSERT0(dn->dn_next_bonuslen[i]);
+		ASSERT0(dn->dn_next_blksz[i]);
+	}
+
+	ASSERT0(dn->dn_allocated_txg);
+	ASSERT0(dn->dn_free_txg);
+	ASSERT0(dn->dn_assigned_txg);
+	ASSERT0(dn->dn_dirtyctx);
+	ASSERT3P(dn->dn_dirtyctx_firstset, ==, NULL);
+	ASSERT3P(dn->dn_bonus, ==, NULL);
+	ASSERT(!dn->dn_have_spill);
+	ASSERT3P(dn->dn_zio, ==, NULL);
+	ASSERT0(dn->dn_oldused);
+	ASSERT0(dn->dn_oldflags);
+	ASSERT0(dn->dn_olduid);
+	ASSERT0(dn->dn_oldgid);
+	ASSERT0(dn->dn_newuid);
+	ASSERT0(dn->dn_newgid);
+	ASSERT0(dn->dn_id_flags);
+
+	ASSERT0(dn->dn_dbufs_count);
+	ASSERT0(dn->dn_unlisted_l0_blkid);
+	avl_destroy(&dn->dn_dbufs);
+}
+
+void
+dnode_init(void)
+{
+	ASSERT(dnode_cache == NULL);
+	dnode_cache = kmem_cache_create("dnode_t", sizeof (dnode_t),
+	    0, dnode_cons, dnode_dest, NULL, NULL, NULL, 0);
+	kmem_cache_set_move(dnode_cache, dnode_move);
+}
+
+void
+dnode_fini(void)
+{
+	kmem_cache_destroy(dnode_cache);
+	dnode_cache = NULL;
+}
+
+
+#ifdef ZFS_DEBUG
+void
+dnode_verify(dnode_t *dn)
+{
+	int drop_struct_lock = FALSE;
+
+	ASSERT(dn->dn_phys);
+	ASSERT(dn->dn_objset);
+	ASSERT(dn->dn_handle->dnh_dnode == dn);
+
+	ASSERT(DMU_OT_IS_VALID(dn->dn_phys->dn_type));
+
+	if (!(zfs_flags & ZFS_DEBUG_DNODE_VERIFY))
+		return;
+
+	if (!RW_WRITE_HELD(&dn->dn_struct_rwlock)) {
+		rw_enter(&dn->dn_struct_rwlock, RW_READER);
+		drop_struct_lock = TRUE;
+	}
+	if (dn->dn_phys->dn_type != DMU_OT_NONE || dn->dn_allocated_txg != 0) {
+		int i;
+		ASSERT3U(dn->dn_indblkshift, <=, SPA_MAXBLOCKSHIFT);
+		if (dn->dn_datablkshift) {
+			ASSERT3U(dn->dn_datablkshift, >=, SPA_MINBLOCKSHIFT);
+			ASSERT3U(dn->dn_datablkshift, <=, SPA_MAXBLOCKSHIFT);
+			ASSERT3U(1<<dn->dn_datablkshift, ==, dn->dn_datablksz);
+		}
+		ASSERT3U(dn->dn_nlevels, <=, 30);
+		ASSERT(DMU_OT_IS_VALID(dn->dn_type));
+		ASSERT3U(dn->dn_nblkptr, >=, 1);
+		ASSERT3U(dn->dn_nblkptr, <=, DN_MAX_NBLKPTR);
+		ASSERT3U(dn->dn_bonuslen, <=, DN_MAX_BONUSLEN);
+		ASSERT3U(dn->dn_datablksz, ==,
+		    dn->dn_datablkszsec << SPA_MINBLOCKSHIFT);
+		ASSERT3U(ISP2(dn->dn_datablksz), ==, dn->dn_datablkshift != 0);
+		ASSERT3U((dn->dn_nblkptr - 1) * sizeof (blkptr_t) +
+		    dn->dn_bonuslen, <=, DN_MAX_BONUSLEN);
+		for (i = 0; i < TXG_SIZE; i++) {
+			ASSERT3U(dn->dn_next_nlevels[i], <=, dn->dn_nlevels);
+		}
+	}
+	if (dn->dn_phys->dn_type != DMU_OT_NONE)
+		ASSERT3U(dn->dn_phys->dn_nlevels, <=, dn->dn_nlevels);
+	ASSERT(DMU_OBJECT_IS_SPECIAL(dn->dn_object) || dn->dn_dbuf != NULL);
+	if (dn->dn_dbuf != NULL) {
+		ASSERT3P(dn->dn_phys, ==,
+		    (dnode_phys_t *)dn->dn_dbuf->db.db_data +
+		    (dn->dn_object % (dn->dn_dbuf->db.db_size >> DNODE_SHIFT)));
+	}
+	if (drop_struct_lock)
+		rw_exit(&dn->dn_struct_rwlock);
+}
+#endif
+
+void
+dnode_byteswap(dnode_phys_t *dnp)
+{
+	uint64_t *buf64 = (void*)&dnp->dn_blkptr;
+	int i;
+
+	if (dnp->dn_type == DMU_OT_NONE) {
+		bzero(dnp, sizeof (dnode_phys_t));
+		return;
+	}
+
+	dnp->dn_datablkszsec = BSWAP_16(dnp->dn_datablkszsec);
+	dnp->dn_bonuslen = BSWAP_16(dnp->dn_bonuslen);
+	dnp->dn_maxblkid = BSWAP_64(dnp->dn_maxblkid);
+	dnp->dn_used = BSWAP_64(dnp->dn_used);
+
+	/*
+	 * dn_nblkptr is only one byte, so it's OK to read it in either
+	 * byte order.  We can't read dn_bouslen.
+	 */
+	ASSERT(dnp->dn_indblkshift <= SPA_MAXBLOCKSHIFT);
+	ASSERT(dnp->dn_nblkptr <= DN_MAX_NBLKPTR);
+	for (i = 0; i < dnp->dn_nblkptr * sizeof (blkptr_t)/8; i++)
+		buf64[i] = BSWAP_64(buf64[i]);
+
+	/*
+	 * OK to check dn_bonuslen for zero, because it won't matter if
+	 * we have the wrong byte order.  This is necessary because the
+	 * dnode dnode is smaller than a regular dnode.
+	 */
+	if (dnp->dn_bonuslen != 0) {
+		/*
+		 * Note that the bonus length calculated here may be
+		 * longer than the actual bonus buffer.  This is because
+		 * we always put the bonus buffer after the last block
+		 * pointer (instead of packing it against the end of the
+		 * dnode buffer).
+		 */
+		int off = (dnp->dn_nblkptr-1) * sizeof (blkptr_t);
+		size_t len = DN_MAX_BONUSLEN - off;
+		dmu_object_byteswap_t byteswap;
+		ASSERT(DMU_OT_IS_VALID(dnp->dn_bonustype));
+		byteswap = DMU_OT_BYTESWAP(dnp->dn_bonustype);
+		dmu_ot_byteswap[byteswap].ob_func(dnp->dn_bonus + off, len);
+	}
+
+	/* Swap SPILL block if we have one */
+	if (dnp->dn_flags & DNODE_FLAG_SPILL_BLKPTR)
+		byteswap_uint64_array(&dnp->dn_spill, sizeof (blkptr_t));
+
+}
+
+void
+dnode_buf_byteswap(void *vbuf, size_t size)
+{
+	dnode_phys_t *buf = vbuf;
+	int i;
+
+	ASSERT3U(sizeof (dnode_phys_t), ==, (1<<DNODE_SHIFT));
+	ASSERT((size & (sizeof (dnode_phys_t)-1)) == 0);
+
+	size >>= DNODE_SHIFT;
+	for (i = 0; i < size; i++) {
+		dnode_byteswap(buf);
+		buf++;
+	}
+}
+
+void
+dnode_setbonuslen(dnode_t *dn, int newsize, dmu_tx_t *tx)
+{
+	ASSERT3U(refcount_count(&dn->dn_holds), >=, 1);
+
+	dnode_setdirty(dn, tx);
+	rw_enter(&dn->dn_struct_rwlock, RW_WRITER);
+	ASSERT3U(newsize, <=, DN_MAX_BONUSLEN -
+	    (dn->dn_nblkptr-1) * sizeof (blkptr_t));
+	dn->dn_bonuslen = newsize;
+	if (newsize == 0)
+		dn->dn_next_bonuslen[tx->tx_txg & TXG_MASK] = DN_ZERO_BONUSLEN;
+	else
+		dn->dn_next_bonuslen[tx->tx_txg & TXG_MASK] = dn->dn_bonuslen;
+	rw_exit(&dn->dn_struct_rwlock);
+}
+
+void
+dnode_setbonus_type(dnode_t *dn, dmu_object_type_t newtype, dmu_tx_t *tx)
+{
+	ASSERT3U(refcount_count(&dn->dn_holds), >=, 1);
+	dnode_setdirty(dn, tx);
+	rw_enter(&dn->dn_struct_rwlock, RW_WRITER);
+	dn->dn_bonustype = newtype;
+	dn->dn_next_bonustype[tx->tx_txg & TXG_MASK] = dn->dn_bonustype;
+	rw_exit(&dn->dn_struct_rwlock);
+}
+
+void
+dnode_rm_spill(dnode_t *dn, dmu_tx_t *tx)
+{
+	ASSERT3U(refcount_count(&dn->dn_holds), >=, 1);
+	ASSERT(RW_WRITE_HELD(&dn->dn_struct_rwlock));
+	dnode_setdirty(dn, tx);
+	dn->dn_rm_spillblk[tx->tx_txg&TXG_MASK] = DN_KILL_SPILLBLK;
+	dn->dn_have_spill = B_FALSE;
+}
+
+static void
+dnode_setdblksz(dnode_t *dn, int size)
+{
+	ASSERT0(P2PHASE(size, SPA_MINBLOCKSIZE));
+	ASSERT3U(size, <=, SPA_MAXBLOCKSIZE);
+	ASSERT3U(size, >=, SPA_MINBLOCKSIZE);
+	ASSERT3U(size >> SPA_MINBLOCKSHIFT, <,
+	    1<<(sizeof (dn->dn_phys->dn_datablkszsec) * 8));
+	dn->dn_datablksz = size;
+	dn->dn_datablkszsec = size >> SPA_MINBLOCKSHIFT;
+	dn->dn_datablkshift = ISP2(size) ? highbit64(size - 1) : 0;
+}
+
+static dnode_t *
+dnode_create(objset_t *os, dnode_phys_t *dnp, dmu_buf_impl_t *db,
+    uint64_t object, dnode_handle_t *dnh)
+{
+	dnode_t *dn;
+
+	dn = kmem_cache_alloc(dnode_cache, KM_SLEEP);
+	ASSERT(!POINTER_IS_VALID(dn->dn_objset));
+	dn->dn_moved = 0;
+
+	/*
+	 * Defer setting dn_objset until the dnode is ready to be a candidate
+	 * for the dnode_move() callback.
+	 */
+	dn->dn_object = object;
+	dn->dn_dbuf = db;
+	dn->dn_handle = dnh;
+	dn->dn_phys = dnp;
+
+	if (dnp->dn_datablkszsec) {
+		dnode_setdblksz(dn, dnp->dn_datablkszsec << SPA_MINBLOCKSHIFT);
+	} else {
+		dn->dn_datablksz = 0;
+		dn->dn_datablkszsec = 0;
+		dn->dn_datablkshift = 0;
+	}
+	dn->dn_indblkshift = dnp->dn_indblkshift;
+	dn->dn_nlevels = dnp->dn_nlevels;
+	dn->dn_type = dnp->dn_type;
+	dn->dn_nblkptr = dnp->dn_nblkptr;
+	dn->dn_checksum = dnp->dn_checksum;
+	dn->dn_compress = dnp->dn_compress;
+	dn->dn_bonustype = dnp->dn_bonustype;
+	dn->dn_bonuslen = dnp->dn_bonuslen;
+	dn->dn_maxblkid = dnp->dn_maxblkid;
+	dn->dn_have_spill = ((dnp->dn_flags & DNODE_FLAG_SPILL_BLKPTR) != 0);
+	dn->dn_id_flags = 0;
+
+	dmu_zfetch_init(&dn->dn_zfetch, dn);
+
+	ASSERT(DMU_OT_IS_VALID(dn->dn_phys->dn_type));
+
+	mutex_enter(&os->os_lock);
+	if (dnh->dnh_dnode != NULL) {
+		/* Lost the allocation race. */
+		mutex_exit(&os->os_lock);
+		kmem_cache_free(dnode_cache, dn);
+		return (dnh->dnh_dnode);
+	}
+
+	/*
+	 * Exclude special dnodes from os_dnodes so an empty os_dnodes
+	 * signifies that the special dnodes have no references from
+	 * their children (the entries in os_dnodes).  This allows
+	 * dnode_destroy() to easily determine if the last child has
+	 * been removed and then complete eviction of the objset.
+	 */
+	if (!DMU_OBJECT_IS_SPECIAL(object))
+		list_insert_head(&os->os_dnodes, dn);
+	membar_producer();
+
+	/*
+	 * Everything else must be valid before assigning dn_objset
+	 * makes the dnode eligible for dnode_move().
+	 */
+	dn->dn_objset = os;
+
+	dnh->dnh_dnode = dn;
+	mutex_exit(&os->os_lock);
+
+	arc_space_consume(sizeof (dnode_t), ARC_SPACE_OTHER);
+	return (dn);
+}
+
+/*
+ * Caller must be holding the dnode handle, which is released upon return.
+ */
+static void
+dnode_destroy(dnode_t *dn)
+{
+	objset_t *os = dn->dn_objset;
+	boolean_t complete_os_eviction = B_FALSE;
+
+	ASSERT((dn->dn_id_flags & DN_ID_NEW_EXIST) == 0);
+
+	mutex_enter(&os->os_lock);
+	POINTER_INVALIDATE(&dn->dn_objset);
+	if (!DMU_OBJECT_IS_SPECIAL(dn->dn_object)) {
+		list_remove(&os->os_dnodes, dn);
+		complete_os_eviction =
+		    list_is_empty(&os->os_dnodes) &&
+		    list_link_active(&os->os_evicting_node);
+	}
+	mutex_exit(&os->os_lock);
+
+	/* the dnode can no longer move, so we can release the handle */
+	zrl_remove(&dn->dn_handle->dnh_zrlock);
+
+	dn->dn_allocated_txg = 0;
+	dn->dn_free_txg = 0;
+	dn->dn_assigned_txg = 0;
+
+	dn->dn_dirtyctx = 0;
+	if (dn->dn_dirtyctx_firstset != NULL) {
+		kmem_free(dn->dn_dirtyctx_firstset, 1);
+		dn->dn_dirtyctx_firstset = NULL;
+	}
+	if (dn->dn_bonus != NULL) {
+		mutex_enter(&dn->dn_bonus->db_mtx);
+		dbuf_evict(dn->dn_bonus);
+		dn->dn_bonus = NULL;
+	}
+	dn->dn_zio = NULL;
+
+	dn->dn_have_spill = B_FALSE;
+	dn->dn_oldused = 0;
+	dn->dn_oldflags = 0;
+	dn->dn_olduid = 0;
+	dn->dn_oldgid = 0;
+	dn->dn_newuid = 0;
+	dn->dn_newgid = 0;
+	dn->dn_id_flags = 0;
+	dn->dn_unlisted_l0_blkid = 0;
+
+	dmu_zfetch_rele(&dn->dn_zfetch);
+	kmem_cache_free(dnode_cache, dn);
+	arc_space_return(sizeof (dnode_t), ARC_SPACE_OTHER);
+
+	if (complete_os_eviction)
+		dmu_objset_evict_done(os);
+}
+
+void
+dnode_allocate(dnode_t *dn, dmu_object_type_t ot, int blocksize, int ibs,
+    dmu_object_type_t bonustype, int bonuslen, dmu_tx_t *tx)
+{
+	int i;
+
+	ASSERT3U(blocksize, <=,
+	    spa_maxblocksize(dmu_objset_spa(dn->dn_objset)));
+	if (blocksize == 0)
+		blocksize = 1 << zfs_default_bs;
+	else
+		blocksize = P2ROUNDUP(blocksize, SPA_MINBLOCKSIZE);
+
+	if (ibs == 0)
+		ibs = zfs_default_ibs;
+
+	ibs = MIN(MAX(ibs, DN_MIN_INDBLKSHIFT), DN_MAX_INDBLKSHIFT);
+
+	dprintf("os=%p obj=%llu txg=%llu blocksize=%d ibs=%d\n", dn->dn_objset,
+	    dn->dn_object, tx->tx_txg, blocksize, ibs);
+
+	ASSERT(dn->dn_type == DMU_OT_NONE);
+	ASSERT(bcmp(dn->dn_phys, &dnode_phys_zero, sizeof (dnode_phys_t)) == 0);
+	ASSERT(dn->dn_phys->dn_type == DMU_OT_NONE);
+	ASSERT(ot != DMU_OT_NONE);
+	ASSERT(DMU_OT_IS_VALID(ot));
+	ASSERT((bonustype == DMU_OT_NONE && bonuslen == 0) ||
+	    (bonustype == DMU_OT_SA && bonuslen == 0) ||
+	    (bonustype != DMU_OT_NONE && bonuslen != 0));
+	ASSERT(DMU_OT_IS_VALID(bonustype));
+	ASSERT3U(bonuslen, <=, DN_MAX_BONUSLEN);
+	ASSERT(dn->dn_type == DMU_OT_NONE);
+	ASSERT0(dn->dn_maxblkid);
+	ASSERT0(dn->dn_allocated_txg);
+	ASSERT0(dn->dn_assigned_txg);
+	ASSERT(refcount_is_zero(&dn->dn_tx_holds));
+	ASSERT3U(refcount_count(&dn->dn_holds), <=, 1);
+	ASSERT(avl_is_empty(&dn->dn_dbufs));
+
+	for (i = 0; i < TXG_SIZE; i++) {
+		ASSERT0(dn->dn_next_nblkptr[i]);
+		ASSERT0(dn->dn_next_nlevels[i]);
+		ASSERT0(dn->dn_next_indblkshift[i]);
+		ASSERT0(dn->dn_next_bonuslen[i]);
+		ASSERT0(dn->dn_next_bonustype[i]);
+		ASSERT0(dn->dn_rm_spillblk[i]);
+		ASSERT0(dn->dn_next_blksz[i]);
+		ASSERT(!list_link_active(&dn->dn_dirty_link[i]));
+		ASSERT3P(list_head(&dn->dn_dirty_records[i]), ==, NULL);
+		ASSERT3P(dn->dn_free_ranges[i], ==, NULL);
+	}
+
+	dn->dn_type = ot;
+	dnode_setdblksz(dn, blocksize);
+	dn->dn_indblkshift = ibs;
+	dn->dn_nlevels = 1;
+	if (bonustype == DMU_OT_SA) /* Maximize bonus space for SA */
+		dn->dn_nblkptr = 1;
+	else
+		dn->dn_nblkptr = 1 +
+		    ((DN_MAX_BONUSLEN - bonuslen) >> SPA_BLKPTRSHIFT);
+	dn->dn_bonustype = bonustype;
+	dn->dn_bonuslen = bonuslen;
+	dn->dn_checksum = ZIO_CHECKSUM_INHERIT;
+	dn->dn_compress = ZIO_COMPRESS_INHERIT;
+	dn->dn_dirtyctx = 0;
+
+	dn->dn_free_txg = 0;
+	if (dn->dn_dirtyctx_firstset) {
+		kmem_free(dn->dn_dirtyctx_firstset, 1);
+		dn->dn_dirtyctx_firstset = NULL;
+	}
+
+	dn->dn_allocated_txg = tx->tx_txg;
+	dn->dn_id_flags = 0;
+
+	dnode_setdirty(dn, tx);
+	dn->dn_next_indblkshift[tx->tx_txg & TXG_MASK] = ibs;
+	dn->dn_next_bonuslen[tx->tx_txg & TXG_MASK] = dn->dn_bonuslen;
+	dn->dn_next_bonustype[tx->tx_txg & TXG_MASK] = dn->dn_bonustype;
+	dn->dn_next_blksz[tx->tx_txg & TXG_MASK] = dn->dn_datablksz;
+}
+
+void
+dnode_reallocate(dnode_t *dn, dmu_object_type_t ot, int blocksize,
+    dmu_object_type_t bonustype, int bonuslen, dmu_tx_t *tx)
+{
+	int nblkptr;
+
+	ASSERT3U(blocksize, >=, SPA_MINBLOCKSIZE);
+	ASSERT3U(blocksize, <=,
+	    spa_maxblocksize(dmu_objset_spa(dn->dn_objset)));
+	ASSERT0(blocksize % SPA_MINBLOCKSIZE);
+	ASSERT(dn->dn_object != DMU_META_DNODE_OBJECT || dmu_tx_private_ok(tx));
+	ASSERT(tx->tx_txg != 0);
+	ASSERT((bonustype == DMU_OT_NONE && bonuslen == 0) ||
+	    (bonustype != DMU_OT_NONE && bonuslen != 0) ||
+	    (bonustype == DMU_OT_SA && bonuslen == 0));
+	ASSERT(DMU_OT_IS_VALID(bonustype));
+	ASSERT3U(bonuslen, <=, DN_MAX_BONUSLEN);
+
+	/* clean up any unreferenced dbufs */
+	dnode_evict_dbufs(dn);
+
+	dn->dn_id_flags = 0;
+
+	rw_enter(&dn->dn_struct_rwlock, RW_WRITER);
+	dnode_setdirty(dn, tx);
+	if (dn->dn_datablksz != blocksize) {
+		/* change blocksize */
+		ASSERT(dn->dn_maxblkid == 0 &&
+		    (BP_IS_HOLE(&dn->dn_phys->dn_blkptr[0]) ||
+		    dnode_block_freed(dn, 0)));
+		dnode_setdblksz(dn, blocksize);
+		dn->dn_next_blksz[tx->tx_txg&TXG_MASK] = blocksize;
+	}
+	if (dn->dn_bonuslen != bonuslen)
+		dn->dn_next_bonuslen[tx->tx_txg&TXG_MASK] = bonuslen;
+
+	if (bonustype == DMU_OT_SA) /* Maximize bonus space for SA */
+		nblkptr = 1;
+	else
+		nblkptr = 1 + ((DN_MAX_BONUSLEN - bonuslen) >> SPA_BLKPTRSHIFT);
+	if (dn->dn_bonustype != bonustype)
+		dn->dn_next_bonustype[tx->tx_txg&TXG_MASK] = bonustype;
+	if (dn->dn_nblkptr != nblkptr)
+		dn->dn_next_nblkptr[tx->tx_txg&TXG_MASK] = nblkptr;
+	if (dn->dn_phys->dn_flags & DNODE_FLAG_SPILL_BLKPTR) {
+		dbuf_rm_spill(dn, tx);
+		dnode_rm_spill(dn, tx);
+	}
+	rw_exit(&dn->dn_struct_rwlock);
+
+	/* change type */
+	dn->dn_type = ot;
+
+	/* change bonus size and type */
+	mutex_enter(&dn->dn_mtx);
+	dn->dn_bonustype = bonustype;
+	dn->dn_bonuslen = bonuslen;
+	dn->dn_nblkptr = nblkptr;
+	dn->dn_checksum = ZIO_CHECKSUM_INHERIT;
+	dn->dn_compress = ZIO_COMPRESS_INHERIT;
+	ASSERT3U(dn->dn_nblkptr, <=, DN_MAX_NBLKPTR);
+
+	/* fix up the bonus db_size */
+	if (dn->dn_bonus) {
+		dn->dn_bonus->db.db_size =
+		    DN_MAX_BONUSLEN - (dn->dn_nblkptr-1) * sizeof (blkptr_t);
+		ASSERT(dn->dn_bonuslen <= dn->dn_bonus->db.db_size);
+	}
+
+	dn->dn_allocated_txg = tx->tx_txg;
+	mutex_exit(&dn->dn_mtx);
+}
+
+#ifdef	_KERNEL
+#ifdef	DNODE_STATS
+static struct {
+	uint64_t dms_dnode_invalid;
+	uint64_t dms_dnode_recheck1;
+	uint64_t dms_dnode_recheck2;
+	uint64_t dms_dnode_special;
+	uint64_t dms_dnode_handle;
+	uint64_t dms_dnode_rwlock;
+	uint64_t dms_dnode_active;
+} dnode_move_stats;
+#endif	/* DNODE_STATS */
+
+static void
+dnode_move_impl(dnode_t *odn, dnode_t *ndn)
+{
+	int i;
+
+	ASSERT(!RW_LOCK_HELD(&odn->dn_struct_rwlock));
+	ASSERT(MUTEX_NOT_HELD(&odn->dn_mtx));
+	ASSERT(MUTEX_NOT_HELD(&odn->dn_dbufs_mtx));
+	ASSERT(!RW_LOCK_HELD(&odn->dn_zfetch.zf_rwlock));
+
+	/* Copy fields. */
+	ndn->dn_objset = odn->dn_objset;
+	ndn->dn_object = odn->dn_object;
+	ndn->dn_dbuf = odn->dn_dbuf;
+	ndn->dn_handle = odn->dn_handle;
+	ndn->dn_phys = odn->dn_phys;
+	ndn->dn_type = odn->dn_type;
+	ndn->dn_bonuslen = odn->dn_bonuslen;
+	ndn->dn_bonustype = odn->dn_bonustype;
+	ndn->dn_nblkptr = odn->dn_nblkptr;
+	ndn->dn_checksum = odn->dn_checksum;
+	ndn->dn_compress = odn->dn_compress;
+	ndn->dn_nlevels = odn->dn_nlevels;
+	ndn->dn_indblkshift = odn->dn_indblkshift;
+	ndn->dn_datablkshift = odn->dn_datablkshift;
+	ndn->dn_datablkszsec = odn->dn_datablkszsec;
+	ndn->dn_datablksz = odn->dn_datablksz;
+	ndn->dn_maxblkid = odn->dn_maxblkid;
+	bcopy(&odn->dn_next_nblkptr[0], &ndn->dn_next_nblkptr[0],
+	    sizeof (odn->dn_next_nblkptr));
+	bcopy(&odn->dn_next_nlevels[0], &ndn->dn_next_nlevels[0],
+	    sizeof (odn->dn_next_nlevels));
+	bcopy(&odn->dn_next_indblkshift[0], &ndn->dn_next_indblkshift[0],
+	    sizeof (odn->dn_next_indblkshift));
+	bcopy(&odn->dn_next_bonustype[0], &ndn->dn_next_bonustype[0],
+	    sizeof (odn->dn_next_bonustype));
+	bcopy(&odn->dn_rm_spillblk[0], &ndn->dn_rm_spillblk[0],
+	    sizeof (odn->dn_rm_spillblk));
+	bcopy(&odn->dn_next_bonuslen[0], &ndn->dn_next_bonuslen[0],
+	    sizeof (odn->dn_next_bonuslen));
+	bcopy(&odn->dn_next_blksz[0], &ndn->dn_next_blksz[0],
+	    sizeof (odn->dn_next_blksz));
+	for (i = 0; i < TXG_SIZE; i++) {
+		list_move_tail(&ndn->dn_dirty_records[i],
+		    &odn->dn_dirty_records[i]);
+	}
+	bcopy(&odn->dn_free_ranges[0], &ndn->dn_free_ranges[0],
+	    sizeof (odn->dn_free_ranges));
+	ndn->dn_allocated_txg = odn->dn_allocated_txg;
+	ndn->dn_free_txg = odn->dn_free_txg;
+	ndn->dn_assigned_txg = odn->dn_assigned_txg;
+	ndn->dn_dirtyctx = odn->dn_dirtyctx;
+	ndn->dn_dirtyctx_firstset = odn->dn_dirtyctx_firstset;
+	ASSERT(refcount_count(&odn->dn_tx_holds) == 0);
+	refcount_transfer(&ndn->dn_holds, &odn->dn_holds);
+	ASSERT(avl_is_empty(&ndn->dn_dbufs));
+	avl_swap(&ndn->dn_dbufs, &odn->dn_dbufs);
+	ndn->dn_dbufs_count = odn->dn_dbufs_count;
+	ndn->dn_unlisted_l0_blkid = odn->dn_unlisted_l0_blkid;
+	ndn->dn_bonus = odn->dn_bonus;
+	ndn->dn_have_spill = odn->dn_have_spill;
+	ndn->dn_zio = odn->dn_zio;
+	ndn->dn_oldused = odn->dn_oldused;
+	ndn->dn_oldflags = odn->dn_oldflags;
+	ndn->dn_olduid = odn->dn_olduid;
+	ndn->dn_oldgid = odn->dn_oldgid;
+	ndn->dn_newuid = odn->dn_newuid;
+	ndn->dn_newgid = odn->dn_newgid;
+	ndn->dn_id_flags = odn->dn_id_flags;
+	dmu_zfetch_init(&ndn->dn_zfetch, NULL);
+	list_move_tail(&ndn->dn_zfetch.zf_stream, &odn->dn_zfetch.zf_stream);
+	ndn->dn_zfetch.zf_dnode = odn->dn_zfetch.zf_dnode;
+	ndn->dn_zfetch.zf_stream_cnt = odn->dn_zfetch.zf_stream_cnt;
+	ndn->dn_zfetch.zf_alloc_fail = odn->dn_zfetch.zf_alloc_fail;
+
+	/*
+	 * Update back pointers. Updating the handle fixes the back pointer of
+	 * every descendant dbuf as well as the bonus dbuf.
+	 */
+	ASSERT(ndn->dn_handle->dnh_dnode == odn);
+	ndn->dn_handle->dnh_dnode = ndn;
+	if (ndn->dn_zfetch.zf_dnode == odn) {
+		ndn->dn_zfetch.zf_dnode = ndn;
+	}
+
+	/*
+	 * Invalidate the original dnode by clearing all of its back pointers.
+	 */
+	odn->dn_dbuf = NULL;
+	odn->dn_handle = NULL;
+	avl_create(&odn->dn_dbufs, dbuf_compare, sizeof (dmu_buf_impl_t),
+	    offsetof(dmu_buf_impl_t, db_link));
+	odn->dn_dbufs_count = 0;
+	odn->dn_unlisted_l0_blkid = 0;
+	odn->dn_bonus = NULL;
+	odn->dn_zfetch.zf_dnode = NULL;
+
+	/*
+	 * Set the low bit of the objset pointer to ensure that dnode_move()
+	 * recognizes the dnode as invalid in any subsequent callback.
+	 */
+	POINTER_INVALIDATE(&odn->dn_objset);
+
+	/*
+	 * Satisfy the destructor.
+	 */
+	for (i = 0; i < TXG_SIZE; i++) {
+		list_create(&odn->dn_dirty_records[i],
+		    sizeof (dbuf_dirty_record_t),
+		    offsetof(dbuf_dirty_record_t, dr_dirty_node));
+		odn->dn_free_ranges[i] = NULL;
+		odn->dn_next_nlevels[i] = 0;
+		odn->dn_next_indblkshift[i] = 0;
+		odn->dn_next_bonustype[i] = 0;
+		odn->dn_rm_spillblk[i] = 0;
+		odn->dn_next_bonuslen[i] = 0;
+		odn->dn_next_blksz[i] = 0;
+	}
+	odn->dn_allocated_txg = 0;
+	odn->dn_free_txg = 0;
+	odn->dn_assigned_txg = 0;
+	odn->dn_dirtyctx = 0;
+	odn->dn_dirtyctx_firstset = NULL;
+	odn->dn_have_spill = B_FALSE;
+	odn->dn_zio = NULL;
+	odn->dn_oldused = 0;
+	odn->dn_oldflags = 0;
+	odn->dn_olduid = 0;
+	odn->dn_oldgid = 0;
+	odn->dn_newuid = 0;
+	odn->dn_newgid = 0;
+	odn->dn_id_flags = 0;
+
+	/*
+	 * Mark the dnode.
+	 */
+	ndn->dn_moved = 1;
+	odn->dn_moved = (uint8_t)-1;
+}
+
+/*ARGSUSED*/
+static kmem_cbrc_t
+dnode_move(void *buf, void *newbuf, size_t size, void *arg)
+{
+	dnode_t *odn = buf, *ndn = newbuf;
+	objset_t *os;
+	int64_t refcount;
+	uint32_t dbufs;
+
+	/*
+	 * The dnode is on the objset's list of known dnodes if the objset
+	 * pointer is valid. We set the low bit of the objset pointer when
+	 * freeing the dnode to invalidate it, and the memory patterns written
+	 * by kmem (baddcafe and deadbeef) set at least one of the two low bits.
+	 * A newly created dnode sets the objset pointer last of all to indicate
+	 * that the dnode is known and in a valid state to be moved by this
+	 * function.
+	 */
+	os = odn->dn_objset;
+	if (!POINTER_IS_VALID(os)) {
+		DNODE_STAT_ADD(dnode_move_stats.dms_dnode_invalid);
+		return (KMEM_CBRC_DONT_KNOW);
+	}
+
+	/*
+	 * Ensure that the objset does not go away during the move.
+	 */
+	rw_enter(&os_lock, RW_WRITER);
+	if (os != odn->dn_objset) {
+		rw_exit(&os_lock);
+		DNODE_STAT_ADD(dnode_move_stats.dms_dnode_recheck1);
+		return (KMEM_CBRC_DONT_KNOW);
+	}
+
+	/*
+	 * If the dnode is still valid, then so is the objset. We know that no
+	 * valid objset can be freed while we hold os_lock, so we can safely
+	 * ensure that the objset remains in use.
+	 */
+	mutex_enter(&os->os_lock);
+
+	/*
+	 * Recheck the objset pointer in case the dnode was removed just before
+	 * acquiring the lock.
+	 */
+	if (os != odn->dn_objset) {
+		mutex_exit(&os->os_lock);
+		rw_exit(&os_lock);
+		DNODE_STAT_ADD(dnode_move_stats.dms_dnode_recheck2);
+		return (KMEM_CBRC_DONT_KNOW);
+	}
+
+	/*
+	 * At this point we know that as long as we hold os->os_lock, the dnode
+	 * cannot be freed and fields within the dnode can be safely accessed.
+	 * The objset listing this dnode cannot go away as long as this dnode is
+	 * on its list.
+	 */
+	rw_exit(&os_lock);
+	if (DMU_OBJECT_IS_SPECIAL(odn->dn_object)) {
+		mutex_exit(&os->os_lock);
+		DNODE_STAT_ADD(dnode_move_stats.dms_dnode_special);
+		return (KMEM_CBRC_NO);
+	}
+	ASSERT(odn->dn_dbuf != NULL); /* only "special" dnodes have no parent */
+
+	/*
+	 * Lock the dnode handle to prevent the dnode from obtaining any new
+	 * holds. This also prevents the descendant dbufs and the bonus dbuf
+	 * from accessing the dnode, so that we can discount their holds. The
+	 * handle is safe to access because we know that while the dnode cannot
+	 * go away, neither can its handle. Once we hold dnh_zrlock, we can
+	 * safely move any dnode referenced only by dbufs.
+	 */
+	if (!zrl_tryenter(&odn->dn_handle->dnh_zrlock)) {
+		mutex_exit(&os->os_lock);
+		DNODE_STAT_ADD(dnode_move_stats.dms_dnode_handle);
+		return (KMEM_CBRC_LATER);
+	}
+
+	/*
+	 * Ensure a consistent view of the dnode's holds and the dnode's dbufs.
+	 * We need to guarantee that there is a hold for every dbuf in order to
+	 * determine whether the dnode is actively referenced. Falsely matching
+	 * a dbuf to an active hold would lead to an unsafe move. It's possible
+	 * that a thread already having an active dnode hold is about to add a
+	 * dbuf, and we can't compare hold and dbuf counts while the add is in
+	 * progress.
+	 */
+	if (!rw_tryenter(&odn->dn_struct_rwlock, RW_WRITER)) {
+		zrl_exit(&odn->dn_handle->dnh_zrlock);
+		mutex_exit(&os->os_lock);
+		DNODE_STAT_ADD(dnode_move_stats.dms_dnode_rwlock);
+		return (KMEM_CBRC_LATER);
+	}
+
+	/*
+	 * A dbuf may be removed (evicted) without an active dnode hold. In that
+	 * case, the dbuf count is decremented under the handle lock before the
+	 * dbuf's hold is released. This order ensures that if we count the hold
+	 * after the dbuf is removed but before its hold is released, we will
+	 * treat the unmatched hold as active and exit safely. If we count the
+	 * hold before the dbuf is removed, the hold is discounted, and the
+	 * removal is blocked until the move completes.
+	 */
+	refcount = refcount_count(&odn->dn_holds);
+	ASSERT(refcount >= 0);
+	dbufs = odn->dn_dbufs_count;
+
+	/* We can't have more dbufs than dnode holds. */
+	ASSERT3U(dbufs, <=, refcount);
+	DTRACE_PROBE3(dnode__move, dnode_t *, odn, int64_t, refcount,
+	    uint32_t, dbufs);
+
+	if (refcount > dbufs) {
+		rw_exit(&odn->dn_struct_rwlock);
+		zrl_exit(&odn->dn_handle->dnh_zrlock);
+		mutex_exit(&os->os_lock);
+		DNODE_STAT_ADD(dnode_move_stats.dms_dnode_active);
+		return (KMEM_CBRC_LATER);
+	}
+
+	rw_exit(&odn->dn_struct_rwlock);
+
+	/*
+	 * At this point we know that anyone with a hold on the dnode is not
+	 * actively referencing it. The dnode is known and in a valid state to
+	 * move. We're holding the locks needed to execute the critical section.
+	 */
+	dnode_move_impl(odn, ndn);
+
+	list_link_replace(&odn->dn_link, &ndn->dn_link);
+	/* If the dnode was safe to move, the refcount cannot have changed. */
+	ASSERT(refcount == refcount_count(&ndn->dn_holds));
+	ASSERT(dbufs == ndn->dn_dbufs_count);
+	zrl_exit(&ndn->dn_handle->dnh_zrlock); /* handle has moved */
+	mutex_exit(&os->os_lock);
+
+	return (KMEM_CBRC_YES);
+}
+#endif	/* _KERNEL */
+
+void
+dnode_special_close(dnode_handle_t *dnh)
+{
+	dnode_t *dn = dnh->dnh_dnode;
+
+	/*
+	 * Wait for final references to the dnode to clear.  This can
+	 * only happen if the arc is asyncronously evicting state that
+	 * has a hold on this dnode while we are trying to evict this
+	 * dnode.
+	 */
+	while (refcount_count(&dn->dn_holds) > 0)
+		delay(1);
+	ASSERT(dn->dn_dbuf == NULL ||
+	    dmu_buf_get_user(&dn->dn_dbuf->db) == NULL);
+	zrl_add(&dnh->dnh_zrlock);
+	dnode_destroy(dn); /* implicit zrl_remove() */
+	zrl_destroy(&dnh->dnh_zrlock);
+	dnh->dnh_dnode = NULL;
+}
+
+void
+dnode_special_open(objset_t *os, dnode_phys_t *dnp, uint64_t object,
+    dnode_handle_t *dnh)
+{
+	dnode_t *dn;
+
+	dn = dnode_create(os, dnp, NULL, object, dnh);
+	zrl_init(&dnh->dnh_zrlock);
+	DNODE_VERIFY(dn);
+}
+
+static void
+dnode_buf_pageout(void *dbu)
+{
+	dnode_children_t *children_dnodes = dbu;
+	int i;
+
+	for (i = 0; i < children_dnodes->dnc_count; i++) {
+		dnode_handle_t *dnh = &children_dnodes->dnc_children[i];
+		dnode_t *dn;
+
+		/*
+		 * The dnode handle lock guards against the dnode moving to
+		 * another valid address, so there is no need here to guard
+		 * against changes to or from NULL.
+		 */
+		if (dnh->dnh_dnode == NULL) {
+			zrl_destroy(&dnh->dnh_zrlock);
+			continue;
+		}
+
+		zrl_add(&dnh->dnh_zrlock);
+		dn = dnh->dnh_dnode;
+		/*
+		 * If there are holds on this dnode, then there should
+		 * be holds on the dnode's containing dbuf as well; thus
+		 * it wouldn't be eligible for eviction and this function
+		 * would not have been called.
+		 */
+		ASSERT(refcount_is_zero(&dn->dn_holds));
+		ASSERT(refcount_is_zero(&dn->dn_tx_holds));
+
+		dnode_destroy(dn); /* implicit zrl_remove() */
+		zrl_destroy(&dnh->dnh_zrlock);
+		dnh->dnh_dnode = NULL;
+	}
+	kmem_free(children_dnodes, sizeof (dnode_children_t) +
+	    children_dnodes->dnc_count * sizeof (dnode_handle_t));
+}
+
+/*
+ * errors:
+ * EINVAL - invalid object number.
+ * EIO - i/o error.
+ * succeeds even for free dnodes.
+ */
+int
+dnode_hold_impl(objset_t *os, uint64_t object, int flag,
+    void *tag, dnode_t **dnp)
+{
+	int epb, idx, err;
+	int drop_struct_lock = FALSE;
+	int type;
+	uint64_t blk;
+	dnode_t *mdn, *dn;
+	dmu_buf_impl_t *db;
+	dnode_children_t *children_dnodes;
+	dnode_handle_t *dnh;
+
+	/*
+	 * If you are holding the spa config lock as writer, you shouldn't
+	 * be asking the DMU to do *anything* unless it's the root pool
+	 * which may require us to read from the root filesystem while
+	 * holding some (not all) of the locks as writer.
+	 */
+	ASSERT(spa_config_held(os->os_spa, SCL_ALL, RW_WRITER) == 0 ||
+	    (spa_is_root(os->os_spa) &&
+	    spa_config_held(os->os_spa, SCL_STATE, RW_WRITER)));
+
+	if (object == DMU_USERUSED_OBJECT || object == DMU_GROUPUSED_OBJECT) {
+		dn = (object == DMU_USERUSED_OBJECT) ?
+		    DMU_USERUSED_DNODE(os) : DMU_GROUPUSED_DNODE(os);
+		if (dn == NULL)
+			return (SET_ERROR(ENOENT));
+		type = dn->dn_type;
+		if ((flag & DNODE_MUST_BE_ALLOCATED) && type == DMU_OT_NONE)
+			return (SET_ERROR(ENOENT));
+		if ((flag & DNODE_MUST_BE_FREE) && type != DMU_OT_NONE)
+			return (SET_ERROR(EEXIST));
+		DNODE_VERIFY(dn);
+		(void) refcount_add(&dn->dn_holds, tag);
+		*dnp = dn;
+		return (0);
+	}
+
+	if (object == 0 || object >= DN_MAX_OBJECT)
+		return (SET_ERROR(EINVAL));
+
+	mdn = DMU_META_DNODE(os);
+	ASSERT(mdn->dn_object == DMU_META_DNODE_OBJECT);
+
+	DNODE_VERIFY(mdn);
+
+	if (!RW_WRITE_HELD(&mdn->dn_struct_rwlock)) {
+		rw_enter(&mdn->dn_struct_rwlock, RW_READER);
+		drop_struct_lock = TRUE;
+	}
+
+	blk = dbuf_whichblock(mdn, object * sizeof (dnode_phys_t));
+
+	db = dbuf_hold(mdn, blk, FTAG);
+	if (drop_struct_lock)
+		rw_exit(&mdn->dn_struct_rwlock);
+	if (db == NULL)
+		return (SET_ERROR(EIO));
+	err = dbuf_read(db, NULL, DB_RF_CANFAIL);
+	if (err) {
+		dbuf_rele(db, FTAG);
+		return (err);
+	}
+
+	ASSERT3U(db->db.db_size, >=, 1<<DNODE_SHIFT);
+	epb = db->db.db_size >> DNODE_SHIFT;
+
+	idx = object & (epb-1);
+
+	ASSERT(DB_DNODE(db)->dn_type == DMU_OT_DNODE);
+	children_dnodes = dmu_buf_get_user(&db->db);
+	if (children_dnodes == NULL) {
+		int i;
+		dnode_children_t *winner;
+		children_dnodes = kmem_zalloc(sizeof (dnode_children_t) +
+		    epb * sizeof (dnode_handle_t), KM_SLEEP);
+		children_dnodes->dnc_count = epb;
+		dnh = &children_dnodes->dnc_children[0];
+		for (i = 0; i < epb; i++) {
+			zrl_init(&dnh[i].dnh_zrlock);
+		}
+		dmu_buf_init_user(&children_dnodes->dnc_dbu,
+		    dnode_buf_pageout, NULL);
+		winner = dmu_buf_set_user(&db->db, &children_dnodes->dnc_dbu);
+		if (winner != NULL) {
+
+			for (i = 0; i < epb; i++) {
+				zrl_destroy(&dnh[i].dnh_zrlock);
+			}
+
+			kmem_free(children_dnodes, sizeof (dnode_children_t) +
+			    epb * sizeof (dnode_handle_t));
+			children_dnodes = winner;
+		}
+	}
+	ASSERT(children_dnodes->dnc_count == epb);
+
+	dnh = &children_dnodes->dnc_children[idx];
+	zrl_add(&dnh->dnh_zrlock);
+	dn = dnh->dnh_dnode;
+	if (dn == NULL) {
+		dnode_phys_t *phys = (dnode_phys_t *)db->db.db_data+idx;
+
+		dn = dnode_create(os, phys, db, object, dnh);
+	}
+
+	mutex_enter(&dn->dn_mtx);
+	type = dn->dn_type;
+	if (dn->dn_free_txg ||
+	    ((flag & DNODE_MUST_BE_ALLOCATED) && type == DMU_OT_NONE) ||
+	    ((flag & DNODE_MUST_BE_FREE) &&
+	    (type != DMU_OT_NONE || !refcount_is_zero(&dn->dn_holds)))) {
+		mutex_exit(&dn->dn_mtx);
+		zrl_remove(&dnh->dnh_zrlock);
+		dbuf_rele(db, FTAG);
+		return (type == DMU_OT_NONE ? ENOENT : EEXIST);
+	}
+	if (refcount_add(&dn->dn_holds, tag) == 1)
+		dbuf_add_ref(db, dnh);
+	mutex_exit(&dn->dn_mtx);
+
+	/* Now we can rely on the hold to prevent the dnode from moving. */
+	zrl_remove(&dnh->dnh_zrlock);
+
+	DNODE_VERIFY(dn);
+	ASSERT3P(dn->dn_dbuf, ==, db);
+	ASSERT3U(dn->dn_object, ==, object);
+	dbuf_rele(db, FTAG);
+
+	*dnp = dn;
+	return (0);
+}
+
+/*
+ * Return held dnode if the object is allocated, NULL if not.
+ */
+int
+dnode_hold(objset_t *os, uint64_t object, void *tag, dnode_t **dnp)
+{
+	return (dnode_hold_impl(os, object, DNODE_MUST_BE_ALLOCATED, tag, dnp));
+}
+
+/*
+ * Can only add a reference if there is already at least one
+ * reference on the dnode.  Returns FALSE if unable to add a
+ * new reference.
+ */
+boolean_t
+dnode_add_ref(dnode_t *dn, void *tag)
+{
+	mutex_enter(&dn->dn_mtx);
+	if (refcount_is_zero(&dn->dn_holds)) {
+		mutex_exit(&dn->dn_mtx);
+		return (FALSE);
+	}
+	VERIFY(1 < refcount_add(&dn->dn_holds, tag));
+	mutex_exit(&dn->dn_mtx);
+	return (TRUE);
+}
+
+void
+dnode_rele(dnode_t *dn, void *tag)
+{
+	mutex_enter(&dn->dn_mtx);
+	dnode_rele_and_unlock(dn, tag);
+}
+
+void
+dnode_rele_and_unlock(dnode_t *dn, void *tag)
+{
+	uint64_t refs;
+	/* Get while the hold prevents the dnode from moving. */
+	dmu_buf_impl_t *db = dn->dn_dbuf;
+	dnode_handle_t *dnh = dn->dn_handle;
+
+	refs = refcount_remove(&dn->dn_holds, tag);
+	mutex_exit(&dn->dn_mtx);
+
+	/*
+	 * It's unsafe to release the last hold on a dnode by dnode_rele() or
+	 * indirectly by dbuf_rele() while relying on the dnode handle to
+	 * prevent the dnode from moving, since releasing the last hold could
+	 * result in the dnode's parent dbuf evicting its dnode handles. For
+	 * that reason anyone calling dnode_rele() or dbuf_rele() without some
+	 * other direct or indirect hold on the dnode must first drop the dnode
+	 * handle.
+	 */
+	ASSERT(refs > 0 || dnh->dnh_zrlock.zr_owner != curthread);
+
+	/* NOTE: the DNODE_DNODE does not have a dn_dbuf */
+	if (refs == 0 && db != NULL) {
+		/*
+		 * Another thread could add a hold to the dnode handle in
+		 * dnode_hold_impl() while holding the parent dbuf. Since the
+		 * hold on the parent dbuf prevents the handle from being
+		 * destroyed, the hold on the handle is OK. We can't yet assert
+		 * that the handle has zero references, but that will be
+		 * asserted anyway when the handle gets destroyed.
+		 */
+		dbuf_rele(db, dnh);
+	}
+}
+
+void
+dnode_setdirty(dnode_t *dn, dmu_tx_t *tx)
+{
+	objset_t *os = dn->dn_objset;
+	uint64_t txg = tx->tx_txg;
+
+	if (DMU_OBJECT_IS_SPECIAL(dn->dn_object)) {
+		dsl_dataset_dirty(os->os_dsl_dataset, tx);
+		return;
+	}
+
+	DNODE_VERIFY(dn);
+
+#ifdef ZFS_DEBUG
+	mutex_enter(&dn->dn_mtx);
+	ASSERT(dn->dn_phys->dn_type || dn->dn_allocated_txg);
+	ASSERT(dn->dn_free_txg == 0 || dn->dn_free_txg >= txg);
+	mutex_exit(&dn->dn_mtx);
+#endif
+
+	/*
+	 * Determine old uid/gid when necessary
+	 */
+	dmu_objset_userquota_get_ids(dn, B_TRUE, tx);
+
+	mutex_enter(&os->os_lock);
+
+	/*
+	 * If we are already marked dirty, we're done.
+	 */
+	if (list_link_active(&dn->dn_dirty_link[txg & TXG_MASK])) {
+		mutex_exit(&os->os_lock);
+		return;
+	}
+
+	ASSERT(!refcount_is_zero(&dn->dn_holds) ||
+	    !avl_is_empty(&dn->dn_dbufs));
+	ASSERT(dn->dn_datablksz != 0);
+	ASSERT0(dn->dn_next_bonuslen[txg&TXG_MASK]);
+	ASSERT0(dn->dn_next_blksz[txg&TXG_MASK]);
+	ASSERT0(dn->dn_next_bonustype[txg&TXG_MASK]);
+
+	dprintf_ds(os->os_dsl_dataset, "obj=%llu txg=%llu\n",
+	    dn->dn_object, txg);
+
+	if (dn->dn_free_txg > 0 && dn->dn_free_txg <= txg) {
+		list_insert_tail(&os->os_free_dnodes[txg&TXG_MASK], dn);
+	} else {
+		list_insert_tail(&os->os_dirty_dnodes[txg&TXG_MASK], dn);
+	}
+
+	mutex_exit(&os->os_lock);
+
+	/*
+	 * The dnode maintains a hold on its containing dbuf as
+	 * long as there are holds on it.  Each instantiated child
+	 * dbuf maintains a hold on the dnode.  When the last child
+	 * drops its hold, the dnode will drop its hold on the
+	 * containing dbuf. We add a "dirty hold" here so that the
+	 * dnode will hang around after we finish processing its
+	 * children.
+	 */
+	VERIFY(dnode_add_ref(dn, (void *)(uintptr_t)tx->tx_txg));
+
+	(void) dbuf_dirty(dn->dn_dbuf, tx);
+
+	dsl_dataset_dirty(os->os_dsl_dataset, tx);
+}
+
+void
+dnode_free(dnode_t *dn, dmu_tx_t *tx)
+{
+	int txgoff = tx->tx_txg & TXG_MASK;
+
+	dprintf("dn=%p txg=%llu\n", dn, tx->tx_txg);
+
+	/* we should be the only holder... hopefully */
+	/* ASSERT3U(refcount_count(&dn->dn_holds), ==, 1); */
+
+	mutex_enter(&dn->dn_mtx);
+	if (dn->dn_type == DMU_OT_NONE || dn->dn_free_txg) {
+		mutex_exit(&dn->dn_mtx);
+		return;
+	}
+	dn->dn_free_txg = tx->tx_txg;
+	mutex_exit(&dn->dn_mtx);
+
+	/*
+	 * If the dnode is already dirty, it needs to be moved from
+	 * the dirty list to the free list.
+	 */
+	mutex_enter(&dn->dn_objset->os_lock);
+	if (list_link_active(&dn->dn_dirty_link[txgoff])) {
+		list_remove(&dn->dn_objset->os_dirty_dnodes[txgoff], dn);
+		list_insert_tail(&dn->dn_objset->os_free_dnodes[txgoff], dn);
+		mutex_exit(&dn->dn_objset->os_lock);
+	} else {
+		mutex_exit(&dn->dn_objset->os_lock);
+		dnode_setdirty(dn, tx);
+	}
+}
+
+/*
+ * Try to change the block size for the indicated dnode.  This can only
+ * succeed if there are no blocks allocated or dirty beyond first block
+ */
+int
+dnode_set_blksz(dnode_t *dn, uint64_t size, int ibs, dmu_tx_t *tx)
+{
+	dmu_buf_impl_t *db;
+	int err;
+
+	ASSERT3U(size, <=, spa_maxblocksize(dmu_objset_spa(dn->dn_objset)));
+	if (size == 0)
+		size = SPA_MINBLOCKSIZE;
+	else
+		size = P2ROUNDUP(size, SPA_MINBLOCKSIZE);
+
+	if (ibs == dn->dn_indblkshift)
+		ibs = 0;
+
+	if (size >> SPA_MINBLOCKSHIFT == dn->dn_datablkszsec && ibs == 0)
+		return (0);
+
+	rw_enter(&dn->dn_struct_rwlock, RW_WRITER);
+
+	/* Check for any allocated blocks beyond the first */
+	if (dn->dn_maxblkid != 0)
+		goto fail;
+
+	mutex_enter(&dn->dn_dbufs_mtx);
+	for (db = avl_first(&dn->dn_dbufs); db != NULL;
+	    db = AVL_NEXT(&dn->dn_dbufs, db)) {
+		if (db->db_blkid != 0 && db->db_blkid != DMU_BONUS_BLKID &&
+		    db->db_blkid != DMU_SPILL_BLKID) {
+			mutex_exit(&dn->dn_dbufs_mtx);
+			goto fail;
+		}
+	}
+	mutex_exit(&dn->dn_dbufs_mtx);
+
+	if (ibs && dn->dn_nlevels != 1)
+		goto fail;
+
+	/* resize the old block */
+	err = dbuf_hold_impl(dn, 0, 0, TRUE, FTAG, &db);
+	if (err == 0)
+		dbuf_new_size(db, size, tx);
+	else if (err != ENOENT)
+		goto fail;
+
+	dnode_setdblksz(dn, size);
+	dnode_setdirty(dn, tx);
+	dn->dn_next_blksz[tx->tx_txg&TXG_MASK] = size;
+	if (ibs) {
+		dn->dn_indblkshift = ibs;
+		dn->dn_next_indblkshift[tx->tx_txg&TXG_MASK] = ibs;
+	}
+	/* rele after we have fixed the blocksize in the dnode */
+	if (db)
+		dbuf_rele(db, FTAG);
+
+	rw_exit(&dn->dn_struct_rwlock);
+	return (0);
+
+fail:
+	rw_exit(&dn->dn_struct_rwlock);
+	return (SET_ERROR(ENOTSUP));
+}
+
+/* read-holding callers must not rely on the lock being continuously held */
+void
+dnode_new_blkid(dnode_t *dn, uint64_t blkid, dmu_tx_t *tx, boolean_t have_read)
+{
+	uint64_t txgoff = tx->tx_txg & TXG_MASK;
+	int epbs, new_nlevels;
+	uint64_t sz;
+
+	ASSERT(blkid != DMU_BONUS_BLKID);
+
+	ASSERT(have_read ?
+	    RW_READ_HELD(&dn->dn_struct_rwlock) :
+	    RW_WRITE_HELD(&dn->dn_struct_rwlock));
+
+	/*
+	 * if we have a read-lock, check to see if we need to do any work
+	 * before upgrading to a write-lock.
+	 */
+	if (have_read) {
+		if (blkid <= dn->dn_maxblkid)
+			return;
+
+		if (!rw_tryupgrade(&dn->dn_struct_rwlock)) {
+			rw_exit(&dn->dn_struct_rwlock);
+			rw_enter(&dn->dn_struct_rwlock, RW_WRITER);
+		}
+	}
+
+	if (blkid <= dn->dn_maxblkid)
+		goto out;
+
+	dn->dn_maxblkid = blkid;
+
+	/*
+	 * Compute the number of levels necessary to support the new maxblkid.
+	 */
+	new_nlevels = 1;
+	epbs = dn->dn_indblkshift - SPA_BLKPTRSHIFT;
+	for (sz = dn->dn_nblkptr;
+	    sz <= blkid && sz >= dn->dn_nblkptr; sz <<= epbs)
+		new_nlevels++;
+
+	if (new_nlevels > dn->dn_nlevels) {
+		int old_nlevels = dn->dn_nlevels;
+		dmu_buf_impl_t *db;
+		list_t *list;
+		dbuf_dirty_record_t *new, *dr, *dr_next;
+
+		dn->dn_nlevels = new_nlevels;
+
+		ASSERT3U(new_nlevels, >, dn->dn_next_nlevels[txgoff]);
+		dn->dn_next_nlevels[txgoff] = new_nlevels;
+
+		/* dirty the left indirects */
+		db = dbuf_hold_level(dn, old_nlevels, 0, FTAG);
+		ASSERT(db != NULL);
+		new = dbuf_dirty(db, tx);
+		dbuf_rele(db, FTAG);
+
+		/* transfer the dirty records to the new indirect */
+		mutex_enter(&dn->dn_mtx);
+		mutex_enter(&new->dt.di.dr_mtx);
+		list = &dn->dn_dirty_records[txgoff];
+		for (dr = list_head(list); dr; dr = dr_next) {
+			dr_next = list_next(&dn->dn_dirty_records[txgoff], dr);
+			if (dr->dr_dbuf->db_level != new_nlevels-1 &&
+			    dr->dr_dbuf->db_blkid != DMU_BONUS_BLKID &&
+			    dr->dr_dbuf->db_blkid != DMU_SPILL_BLKID) {
+				ASSERT(dr->dr_dbuf->db_level == old_nlevels-1);
+				list_remove(&dn->dn_dirty_records[txgoff], dr);
+				list_insert_tail(&new->dt.di.dr_children, dr);
+				dr->dr_parent = new;
+			}
+		}
+		mutex_exit(&new->dt.di.dr_mtx);
+		mutex_exit(&dn->dn_mtx);
+	}
+
+out:
+	if (have_read)
+		rw_downgrade(&dn->dn_struct_rwlock);
+}
+
+static void
+dnode_dirty_l1(dnode_t *dn, uint64_t l1blkid, dmu_tx_t *tx)
+{
+	dmu_buf_impl_t *db = dbuf_hold_level(dn, 1, l1blkid, FTAG);
+	if (db != NULL) {
+		dmu_buf_will_dirty(&db->db, tx);
+		dbuf_rele(db, FTAG);
+	}
+}
+
+void
+dnode_free_range(dnode_t *dn, uint64_t off, uint64_t len, dmu_tx_t *tx)
+{
+	dmu_buf_impl_t *db;
+	uint64_t blkoff, blkid, nblks;
+	int blksz, blkshift, head, tail;
+	int trunc = FALSE;
+	int epbs;
+
+	rw_enter(&dn->dn_struct_rwlock, RW_WRITER);
+	blksz = dn->dn_datablksz;
+	blkshift = dn->dn_datablkshift;
+	epbs = dn->dn_indblkshift - SPA_BLKPTRSHIFT;
+
+	if (len == DMU_OBJECT_END) {
+		len = UINT64_MAX - off;
+		trunc = TRUE;
+	}
+
+	/*
+	 * First, block align the region to free:
+	 */
+	if (ISP2(blksz)) {
+		head = P2NPHASE(off, blksz);
+		blkoff = P2PHASE(off, blksz);
+		if ((off >> blkshift) > dn->dn_maxblkid)
+			goto out;
+	} else {
+		ASSERT(dn->dn_maxblkid == 0);
+		if (off == 0 && len >= blksz) {
+			/*
+			 * Freeing the whole block; fast-track this request.
+			 * Note that we won't dirty any indirect blocks,
+			 * which is fine because we will be freeing the entire
+			 * file and thus all indirect blocks will be freed
+			 * by free_children().
+			 */
+			blkid = 0;
+			nblks = 1;
+			goto done;
+		} else if (off >= blksz) {
+			/* Freeing past end-of-data */
+			goto out;
+		} else {
+			/* Freeing part of the block. */
+			head = blksz - off;
+			ASSERT3U(head, >, 0);
+		}
+		blkoff = off;
+	}
+	/* zero out any partial block data at the start of the range */
+	if (head) {
+		ASSERT3U(blkoff + head, ==, blksz);
+		if (len < head)
+			head = len;
+		if (dbuf_hold_impl(dn, 0, dbuf_whichblock(dn, off), TRUE,
+		    FTAG, &db) == 0) {
+			caddr_t data;
+
+			/* don't dirty if it isn't on disk and isn't dirty */
+			if (db->db_last_dirty ||
+			    (db->db_blkptr && !BP_IS_HOLE(db->db_blkptr))) {
+				rw_exit(&dn->dn_struct_rwlock);
+				dmu_buf_will_dirty(&db->db, tx);
+				rw_enter(&dn->dn_struct_rwlock, RW_WRITER);
+				data = db->db.db_data;
+				bzero(data + blkoff, head);
+			}
+			dbuf_rele(db, FTAG);
+		}
+		off += head;
+		len -= head;
+	}
+
+	/* If the range was less than one block, we're done */
+	if (len == 0)
+		goto out;
+
+	/* If the remaining range is past end of file, we're done */
+	if ((off >> blkshift) > dn->dn_maxblkid)
+		goto out;
+
+	ASSERT(ISP2(blksz));
+	if (trunc)
+		tail = 0;
+	else
+		tail = P2PHASE(len, blksz);
+
+	ASSERT0(P2PHASE(off, blksz));
+	/* zero out any partial block data at the end of the range */
+	if (tail) {
+		if (len < tail)
+			tail = len;
+		if (dbuf_hold_impl(dn, 0, dbuf_whichblock(dn, off+len),
+		    TRUE, FTAG, &db) == 0) {
+			/* don't dirty if not on disk and not dirty */
+			if (db->db_last_dirty ||
+			    (db->db_blkptr && !BP_IS_HOLE(db->db_blkptr))) {
+				rw_exit(&dn->dn_struct_rwlock);
+				dmu_buf_will_dirty(&db->db, tx);
+				rw_enter(&dn->dn_struct_rwlock, RW_WRITER);
+				bzero(db->db.db_data, tail);
+			}
+			dbuf_rele(db, FTAG);
+		}
+		len -= tail;
+	}
+
+	/* If the range did not include a full block, we are done */
+	if (len == 0)
+		goto out;
+
+	ASSERT(IS_P2ALIGNED(off, blksz));
+	ASSERT(trunc || IS_P2ALIGNED(len, blksz));
+	blkid = off >> blkshift;
+	nblks = len >> blkshift;
+	if (trunc)
+		nblks += 1;
+
+	/*
+	 * Dirty all the indirect blocks in this range.  Note that only
+	 * the first and last indirect blocks can actually be written
+	 * (if they were partially freed) -- they must be dirtied, even if
+	 * they do not exist on disk yet.  The interior blocks will
+	 * be freed by free_children(), so they will not actually be written.
+	 * Even though these interior blocks will not be written, we
+	 * dirty them for two reasons:
+	 *
+	 *  - It ensures that the indirect blocks remain in memory until
+	 *    syncing context.  (They have already been prefetched by
+	 *    dmu_tx_hold_free(), so we don't have to worry about reading
+	 *    them serially here.)
+	 *
+	 *  - The dirty space accounting will put pressure on the txg sync
+	 *    mechanism to begin syncing, and to delay transactions if there
+	 *    is a large amount of freeing.  Even though these indirect
+	 *    blocks will not be written, we could need to write the same
+	 *    amount of space if we copy the freed BPs into deadlists.
+	 */
+	if (dn->dn_nlevels > 1) {
+		uint64_t first, last, i, ibyte;
+		int shift, err;
+
+		first = blkid >> epbs;
+		dnode_dirty_l1(dn, first, tx);
+		if (trunc)
+			last = dn->dn_maxblkid >> epbs;
+		else
+			last = (blkid + nblks - 1) >> epbs;
+		if (last != first)
+			dnode_dirty_l1(dn, last, tx);
+
+		shift = dn->dn_datablkshift + dn->dn_indblkshift -
+		    SPA_BLKPTRSHIFT;
+		for (i = first + 1; i < last; i++) {
+			/*
+			 * Set i to the blockid of the next non-hole
+			 * level-1 indirect block at or after i.  Note
+			 * that dnode_next_offset() operates in terms of
+			 * level-0-equivalent bytes.
+			 */
+			ibyte = i << shift;
+			err = dnode_next_offset(dn, DNODE_FIND_HAVELOCK,
+			    &ibyte, 2, 1, 0);
+			i = ibyte >> shift;
+			if (i >= last)
+				break;
+
+			/*
+			 * Normally we should not see an error, either
+			 * from dnode_next_offset() or dbuf_hold_level()
+			 * (except for ESRCH from dnode_next_offset).
+			 * If there is an i/o error, then when we read
+			 * this block in syncing context, it will use
+			 * ZIO_FLAG_MUSTSUCCEED, and thus hang/panic according
+			 * to the "failmode" property.  dnode_next_offset()
+			 * doesn't have a flag to indicate MUSTSUCCEED.
+			 */
+			if (err != 0)
+				break;
+
+			dnode_dirty_l1(dn, i, tx);
+		}
+	}
+
+done:
+	/*
+	 * Add this range to the dnode range list.
+	 * We will finish up this free operation in the syncing phase.
+	 */
+	mutex_enter(&dn->dn_mtx);
+	{
+	int txgoff = tx->tx_txg & TXG_MASK;
+	if (dn->dn_free_ranges[txgoff] == NULL) {
+		dn->dn_free_ranges[txgoff] =
+		    range_tree_create(NULL, NULL, &dn->dn_mtx);
+	}
+	range_tree_clear(dn->dn_free_ranges[txgoff], blkid, nblks);
+	range_tree_add(dn->dn_free_ranges[txgoff], blkid, nblks);
+	}
+	dprintf_dnode(dn, "blkid=%llu nblks=%llu txg=%llu\n",
+	    blkid, nblks, tx->tx_txg);
+	mutex_exit(&dn->dn_mtx);
+
+	dbuf_free_range(dn, blkid, blkid + nblks - 1, tx);
+	dnode_setdirty(dn, tx);
+out:
+
+	rw_exit(&dn->dn_struct_rwlock);
+}
+
+static boolean_t
+dnode_spill_freed(dnode_t *dn)
+{
+	int i;
+
+	mutex_enter(&dn->dn_mtx);
+	for (i = 0; i < TXG_SIZE; i++) {
+		if (dn->dn_rm_spillblk[i] == DN_KILL_SPILLBLK)
+			break;
+	}
+	mutex_exit(&dn->dn_mtx);
+	return (i < TXG_SIZE);
+}
+
+/* return TRUE if this blkid was freed in a recent txg, or FALSE if it wasn't */
+uint64_t
+dnode_block_freed(dnode_t *dn, uint64_t blkid)
+{
+	void *dp = spa_get_dsl(dn->dn_objset->os_spa);
+	int i;
+
+	if (blkid == DMU_BONUS_BLKID)
+		return (FALSE);
+
+	/*
+	 * If we're in the process of opening the pool, dp will not be
+	 * set yet, but there shouldn't be anything dirty.
+	 */
+	if (dp == NULL)
+		return (FALSE);
+
+	if (dn->dn_free_txg)
+		return (TRUE);
+
+	if (blkid == DMU_SPILL_BLKID)
+		return (dnode_spill_freed(dn));
+
+	mutex_enter(&dn->dn_mtx);
+	for (i = 0; i < TXG_SIZE; i++) {
+		if (dn->dn_free_ranges[i] != NULL &&
+		    range_tree_contains(dn->dn_free_ranges[i], blkid, 1))
+			break;
+	}
+	mutex_exit(&dn->dn_mtx);
+	return (i < TXG_SIZE);
+}
+
+/* call from syncing context when we actually write/free space for this dnode */
+void
+dnode_diduse_space(dnode_t *dn, int64_t delta)
+{
+	uint64_t space;
+	dprintf_dnode(dn, "dn=%p dnp=%p used=%llu delta=%lld\n",
+	    dn, dn->dn_phys,
+	    (u_longlong_t)dn->dn_phys->dn_used,
+	    (longlong_t)delta);
+
+	mutex_enter(&dn->dn_mtx);
+	space = DN_USED_BYTES(dn->dn_phys);
+	if (delta > 0) {
+		ASSERT3U(space + delta, >=, space); /* no overflow */
+	} else {
+		ASSERT3U(space, >=, -delta); /* no underflow */
+	}
+	space += delta;
+	if (spa_version(dn->dn_objset->os_spa) < SPA_VERSION_DNODE_BYTES) {
+		ASSERT((dn->dn_phys->dn_flags & DNODE_FLAG_USED_BYTES) == 0);
+		ASSERT0(P2PHASE(space, 1<<DEV_BSHIFT));
+		dn->dn_phys->dn_used = space >> DEV_BSHIFT;
+	} else {
+		dn->dn_phys->dn_used = space;
+		dn->dn_phys->dn_flags |= DNODE_FLAG_USED_BYTES;
+	}
+	mutex_exit(&dn->dn_mtx);
+}
+
+/*
+ * Call when we think we're going to write/free space in open context to track
+ * the amount of memory in use by the currently open txg.
+ */
+void
+dnode_willuse_space(dnode_t *dn, int64_t space, dmu_tx_t *tx)
+{
+	objset_t *os = dn->dn_objset;
+	dsl_dataset_t *ds = os->os_dsl_dataset;
+	int64_t aspace = spa_get_asize(os->os_spa, space);
+
+	if (ds != NULL) {
+		dsl_dir_willuse_space(ds->ds_dir, aspace, tx);
+		dsl_pool_dirty_space(dmu_tx_pool(tx), space, tx);
+	}
+
+	dmu_tx_willuse_space(tx, aspace);
+}
+
+/*
+ * Scans a block at the indicated "level" looking for a hole or data,
+ * depending on 'flags'.
+ *
+ * If level > 0, then we are scanning an indirect block looking at its
+ * pointers.  If level == 0, then we are looking at a block of dnodes.
+ *
+ * If we don't find what we are looking for in the block, we return ESRCH.
+ * Otherwise, return with *offset pointing to the beginning (if searching
+ * forwards) or end (if searching backwards) of the range covered by the
+ * block pointer we matched on (or dnode).
+ *
+ * The basic search algorithm used below by dnode_next_offset() is to
+ * use this function to search up the block tree (widen the search) until
+ * we find something (i.e., we don't return ESRCH) and then search back
+ * down the tree (narrow the search) until we reach our original search
+ * level.
+ */
+static int
+dnode_next_offset_level(dnode_t *dn, int flags, uint64_t *offset,
+	int lvl, uint64_t blkfill, uint64_t txg)
+{
+	dmu_buf_impl_t *db = NULL;
+	void *data = NULL;
+	uint64_t epbs = dn->dn_phys->dn_indblkshift - SPA_BLKPTRSHIFT;
+	uint64_t epb = 1ULL << epbs;
+	uint64_t minfill, maxfill;
+	boolean_t hole;
+	int i, inc, error, span;
+
+	dprintf("probing object %llu offset %llx level %d of %u\n",
+	    dn->dn_object, *offset, lvl, dn->dn_phys->dn_nlevels);
+
+	hole = ((flags & DNODE_FIND_HOLE) != 0);
+	inc = (flags & DNODE_FIND_BACKWARDS) ? -1 : 1;
+	ASSERT(txg == 0 || !hole);
+
+	if (lvl == dn->dn_phys->dn_nlevels) {
+		error = 0;
+		epb = dn->dn_phys->dn_nblkptr;
+		data = dn->dn_phys->dn_blkptr;
+	} else {
+		uint64_t blkid = dbuf_whichblock(dn, *offset) >> (epbs * lvl);
+		error = dbuf_hold_impl(dn, lvl, blkid, TRUE, FTAG, &db);
+		if (error) {
+			if (error != ENOENT)
+				return (error);
+			if (hole)
+				return (0);
+			/*
+			 * This can only happen when we are searching up
+			 * the block tree for data.  We don't really need to
+			 * adjust the offset, as we will just end up looking
+			 * at the pointer to this block in its parent, and its
+			 * going to be unallocated, so we will skip over it.
+			 */
+			return (SET_ERROR(ESRCH));
+		}
+		error = dbuf_read(db, NULL, DB_RF_CANFAIL | DB_RF_HAVESTRUCT);
+		if (error) {
+			dbuf_rele(db, FTAG);
+			return (error);
+		}
+		data = db->db.db_data;
+	}
+
+
+	if (db != NULL && txg != 0 && (db->db_blkptr == NULL ||
+	    db->db_blkptr->blk_birth <= txg ||
+	    BP_IS_HOLE(db->db_blkptr))) {
+		/*
+		 * This can only happen when we are searching up the tree
+		 * and these conditions mean that we need to keep climbing.
+		 */
+		error = SET_ERROR(ESRCH);
+	} else if (lvl == 0) {
+		dnode_phys_t *dnp = data;
+		span = DNODE_SHIFT;
+		ASSERT(dn->dn_type == DMU_OT_DNODE);
+
+		for (i = (*offset >> span) & (blkfill - 1);
+		    i >= 0 && i < blkfill; i += inc) {
+			if ((dnp[i].dn_type == DMU_OT_NONE) == hole)
+				break;
+			*offset += (1ULL << span) * inc;
+		}
+		if (i < 0 || i == blkfill)
+			error = SET_ERROR(ESRCH);
+	} else {
+		blkptr_t *bp = data;
+		uint64_t start = *offset;
+		span = (lvl - 1) * epbs + dn->dn_datablkshift;
+		minfill = 0;
+		maxfill = blkfill << ((lvl - 1) * epbs);
+
+		if (hole)
+			maxfill--;
+		else
+			minfill++;
+
+		*offset = *offset >> span;
+		for (i = BF64_GET(*offset, 0, epbs);
+		    i >= 0 && i < epb; i += inc) {
+			if (BP_GET_FILL(&bp[i]) >= minfill &&
+			    BP_GET_FILL(&bp[i]) <= maxfill &&
+			    (hole || bp[i].blk_birth > txg))
+				break;
+			if (inc > 0 || *offset > 0)
+				*offset += inc;
+		}
+		*offset = *offset << span;
+		if (inc < 0) {
+			/* traversing backwards; position offset at the end */
+			ASSERT3U(*offset, <=, start);
+			*offset = MIN(*offset + (1ULL << span) - 1, start);
+		} else if (*offset < start) {
+			*offset = start;
+		}
+		if (i < 0 || i >= epb)
+			error = SET_ERROR(ESRCH);
+	}
+
+	if (db)
+		dbuf_rele(db, FTAG);
+
+	return (error);
+}
+
+/*
+ * Find the next hole, data, or sparse region at or after *offset.
+ * The value 'blkfill' tells us how many items we expect to find
+ * in an L0 data block; this value is 1 for normal objects,
+ * DNODES_PER_BLOCK for the meta dnode, and some fraction of
+ * DNODES_PER_BLOCK when searching for sparse regions thereof.
+ *
+ * Examples:
+ *
+ * dnode_next_offset(dn, flags, offset, 1, 1, 0);
+ *	Finds the next/previous hole/data in a file.
+ *	Used in dmu_offset_next().
+ *
+ * dnode_next_offset(mdn, flags, offset, 0, DNODES_PER_BLOCK, txg);
+ *	Finds the next free/allocated dnode an objset's meta-dnode.
+ *	Only finds objects that have new contents since txg (ie.
+ *	bonus buffer changes and content removal are ignored).
+ *	Used in dmu_object_next().
+ *
+ * dnode_next_offset(mdn, DNODE_FIND_HOLE, offset, 2, DNODES_PER_BLOCK >> 2, 0);
+ *	Finds the next L2 meta-dnode bp that's at most 1/4 full.
+ *	Used in dmu_object_alloc().
+ */
+int
+dnode_next_offset(dnode_t *dn, int flags, uint64_t *offset,
+    int minlvl, uint64_t blkfill, uint64_t txg)
+{
+	uint64_t initial_offset = *offset;
+	int lvl, maxlvl;
+	int error = 0;
+
+	if (!(flags & DNODE_FIND_HAVELOCK))
+		rw_enter(&dn->dn_struct_rwlock, RW_READER);
+
+	if (dn->dn_phys->dn_nlevels == 0) {
+		error = SET_ERROR(ESRCH);
+		goto out;
+	}
+
+	if (dn->dn_datablkshift == 0) {
+		if (*offset < dn->dn_datablksz) {
+			if (flags & DNODE_FIND_HOLE)
+				*offset = dn->dn_datablksz;
+		} else {
+			error = SET_ERROR(ESRCH);
+		}
+		goto out;
+	}
+
+	maxlvl = dn->dn_phys->dn_nlevels;
+
+	for (lvl = minlvl; lvl <= maxlvl; lvl++) {
+		error = dnode_next_offset_level(dn,
+		    flags, offset, lvl, blkfill, txg);
+		if (error != ESRCH)
+			break;
+	}
+
+	while (error == 0 && --lvl >= minlvl) {
+		error = dnode_next_offset_level(dn,
+		    flags, offset, lvl, blkfill, txg);
+	}
+
+	/*
+	 * There's always a "virtual hole" at the end of the object, even
+	 * if all BP's which physically exist are non-holes.
+	 */
+	if ((flags & DNODE_FIND_HOLE) && error == ESRCH && txg == 0 &&
+	    minlvl == 1 && blkfill == 1 && !(flags & DNODE_FIND_BACKWARDS)) {
+		error = 0;
+	}
+
+	if (error == 0 && (flags & DNODE_FIND_BACKWARDS ?
+	    initial_offset < *offset : initial_offset > *offset))
+		error = SET_ERROR(ESRCH);
+out:
+	if (!(flags & DNODE_FIND_HAVELOCK))
+		rw_exit(&dn->dn_struct_rwlock);
+
+	return (error);
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/module/zfs/dnode_sync.c
@@ -0,0 +1,737 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2015 by Delphix. All rights reserved.
+ * Copyright (c) 2014 Spectra Logic Corporation, All rights reserved.
+ */
+
+#include <sys/zfs_context.h>
+#include <sys/dbuf.h>
+#include <sys/dnode.h>
+#include <sys/dmu.h>
+#include <sys/dmu_tx.h>
+#include <sys/dmu_objset.h>
+#include <sys/dsl_dataset.h>
+#include <sys/spa.h>
+#include <sys/range_tree.h>
+#include <sys/zfeature.h>
+
+static void
+dnode_increase_indirection(dnode_t *dn, dmu_tx_t *tx)
+{
+	dmu_buf_impl_t *db;
+	int txgoff = tx->tx_txg & TXG_MASK;
+	int nblkptr = dn->dn_phys->dn_nblkptr;
+	int old_toplvl = dn->dn_phys->dn_nlevels - 1;
+	int new_level = dn->dn_next_nlevels[txgoff];
+	int i;
+
+	rw_enter(&dn->dn_struct_rwlock, RW_WRITER);
+
+	/* this dnode can't be paged out because it's dirty */
+	ASSERT(dn->dn_phys->dn_type != DMU_OT_NONE);
+	ASSERT(RW_WRITE_HELD(&dn->dn_struct_rwlock));
+	ASSERT(new_level > 1 && dn->dn_phys->dn_nlevels > 0);
+
+	db = dbuf_hold_level(dn, dn->dn_phys->dn_nlevels, 0, FTAG);
+	ASSERT(db != NULL);
+
+	dn->dn_phys->dn_nlevels = new_level;
+	dprintf("os=%p obj=%llu, increase to %d\n", dn->dn_objset,
+	    dn->dn_object, dn->dn_phys->dn_nlevels);
+
+	/* check for existing blkptrs in the dnode */
+	for (i = 0; i < nblkptr; i++)
+		if (!BP_IS_HOLE(&dn->dn_phys->dn_blkptr[i]))
+			break;
+	if (i != nblkptr) {
+		/* transfer dnode's block pointers to new indirect block */
+		(void) dbuf_read(db, NULL, DB_RF_MUST_SUCCEED|DB_RF_HAVESTRUCT);
+		ASSERT(db->db.db_data);
+		ASSERT(arc_released(db->db_buf));
+		ASSERT3U(sizeof (blkptr_t) * nblkptr, <=, db->db.db_size);
+		bcopy(dn->dn_phys->dn_blkptr, db->db.db_data,
+		    sizeof (blkptr_t) * nblkptr);
+		arc_buf_freeze(db->db_buf);
+	}
+
+	/* set dbuf's parent pointers to new indirect buf */
+	for (i = 0; i < nblkptr; i++) {
+		dmu_buf_impl_t *child =
+		    dbuf_find(dn->dn_objset, dn->dn_object, old_toplvl, i);
+
+		if (child == NULL)
+			continue;
+#ifdef	DEBUG
+		DB_DNODE_ENTER(child);
+		ASSERT3P(DB_DNODE(child), ==, dn);
+		DB_DNODE_EXIT(child);
+#endif	/* DEBUG */
+		if (child->db_parent && child->db_parent != dn->dn_dbuf) {
+			ASSERT(child->db_parent->db_level == db->db_level);
+			ASSERT(child->db_blkptr !=
+			    &dn->dn_phys->dn_blkptr[child->db_blkid]);
+			mutex_exit(&child->db_mtx);
+			continue;
+		}
+		ASSERT(child->db_parent == NULL ||
+		    child->db_parent == dn->dn_dbuf);
+
+		child->db_parent = db;
+		dbuf_add_ref(db, child);
+		if (db->db.db_data)
+			child->db_blkptr = (blkptr_t *)db->db.db_data + i;
+		else
+			child->db_blkptr = NULL;
+		dprintf_dbuf_bp(child, child->db_blkptr,
+		    "changed db_blkptr to new indirect %s", "");
+
+		mutex_exit(&child->db_mtx);
+	}
+
+	bzero(dn->dn_phys->dn_blkptr, sizeof (blkptr_t) * nblkptr);
+
+	dbuf_rele(db, FTAG);
+
+	rw_exit(&dn->dn_struct_rwlock);
+}
+
+static void
+free_blocks(dnode_t *dn, blkptr_t *bp, int num, dmu_tx_t *tx)
+{
+	dsl_dataset_t *ds = dn->dn_objset->os_dsl_dataset;
+	uint64_t bytesfreed = 0;
+	int i;
+
+	dprintf("ds=%p obj=%llx num=%d\n", ds, dn->dn_object, num);
+
+	for (i = 0; i < num; i++, bp++) {
+		uint64_t lsize, lvl;
+		dmu_object_type_t type;
+
+		if (BP_IS_HOLE(bp))
+			continue;
+
+		bytesfreed += dsl_dataset_block_kill(ds, bp, tx, B_FALSE);
+		ASSERT3U(bytesfreed, <=, DN_USED_BYTES(dn->dn_phys));
+
+		/*
+		 * Save some useful information on the holes being
+		 * punched, including logical size, type, and indirection
+		 * level. Retaining birth time enables detection of when
+		 * holes are punched for reducing the number of free
+		 * records transmitted during a zfs send.
+		 */
+
+		lsize = BP_GET_LSIZE(bp);
+		type = BP_GET_TYPE(bp);
+		lvl = BP_GET_LEVEL(bp);
+
+		bzero(bp, sizeof (blkptr_t));
+
+		if (spa_feature_is_active(dn->dn_objset->os_spa,
+		    SPA_FEATURE_HOLE_BIRTH)) {
+			BP_SET_LSIZE(bp, lsize);
+			BP_SET_TYPE(bp, type);
+			BP_SET_LEVEL(bp, lvl);
+			BP_SET_BIRTH(bp, dmu_tx_get_txg(tx), 0);
+		}
+	}
+	dnode_diduse_space(dn, -bytesfreed);
+}
+
+#ifdef ZFS_DEBUG
+static void
+free_verify(dmu_buf_impl_t *db, uint64_t start, uint64_t end, dmu_tx_t *tx)
+{
+	int off, num;
+	int i, err, epbs;
+	uint64_t txg = tx->tx_txg;
+	dnode_t *dn;
+
+	DB_DNODE_ENTER(db);
+	dn = DB_DNODE(db);
+	epbs = dn->dn_phys->dn_indblkshift - SPA_BLKPTRSHIFT;
+	off = start - (db->db_blkid * 1<<epbs);
+	num = end - start + 1;
+
+	ASSERT3U(off, >=, 0);
+	ASSERT3U(num, >=, 0);
+	ASSERT3U(db->db_level, >, 0);
+	ASSERT3U(db->db.db_size, ==, 1 << dn->dn_phys->dn_indblkshift);
+	ASSERT3U(off+num, <=, db->db.db_size >> SPA_BLKPTRSHIFT);
+	ASSERT(db->db_blkptr != NULL);
+
+	for (i = off; i < off+num; i++) {
+		uint64_t *buf;
+		dmu_buf_impl_t *child;
+		dbuf_dirty_record_t *dr;
+		int j;
+
+		ASSERT(db->db_level == 1);
+
+		rw_enter(&dn->dn_struct_rwlock, RW_READER);
+		err = dbuf_hold_impl(dn, db->db_level-1,
+		    (db->db_blkid << epbs) + i, TRUE, FTAG, &child);
+		rw_exit(&dn->dn_struct_rwlock);
+		if (err == ENOENT)
+			continue;
+		ASSERT(err == 0);
+		ASSERT(child->db_level == 0);
+		dr = child->db_last_dirty;
+		while (dr && dr->dr_txg > txg)
+			dr = dr->dr_next;
+		ASSERT(dr == NULL || dr->dr_txg == txg);
+
+		/* data_old better be zeroed */
+		if (dr) {
+			buf = dr->dt.dl.dr_data->b_data;
+			for (j = 0; j < child->db.db_size >> 3; j++) {
+				if (buf[j] != 0) {
+					panic("freed data not zero: "
+					    "child=%p i=%d off=%d num=%d\n",
+					    (void *)child, i, off, num);
+				}
+			}
+		}
+
+		/*
+		 * db_data better be zeroed unless it's dirty in a
+		 * future txg.
+		 */
+		mutex_enter(&child->db_mtx);
+		buf = child->db.db_data;
+		if (buf != NULL && child->db_state != DB_FILL &&
+		    child->db_last_dirty == NULL) {
+			for (j = 0; j < child->db.db_size >> 3; j++) {
+				if (buf[j] != 0) {
+					panic("freed data not zero: "
+					    "child=%p i=%d off=%d num=%d\n",
+					    (void *)child, i, off, num);
+				}
+			}
+		}
+		mutex_exit(&child->db_mtx);
+
+		dbuf_rele(child, FTAG);
+	}
+	DB_DNODE_EXIT(db);
+}
+#endif
+
+static void
+free_children(dmu_buf_impl_t *db, uint64_t blkid, uint64_t nblks,
+    dmu_tx_t *tx)
+{
+	dnode_t *dn;
+	blkptr_t *bp;
+	dmu_buf_impl_t *subdb;
+	uint64_t start, end, dbstart, dbend, i;
+	int epbs, shift;
+
+	/*
+	 * There is a small possibility that this block will not be cached:
+	 *   1 - if level > 1 and there are no children with level <= 1
+	 *   2 - if this block was evicted since we read it from
+	 *	 dmu_tx_hold_free().
+	 */
+	if (db->db_state != DB_CACHED)
+		(void) dbuf_read(db, NULL, DB_RF_MUST_SUCCEED);
+
+	dbuf_release_bp(db);
+	bp = db->db.db_data;
+
+	DB_DNODE_ENTER(db);
+	dn = DB_DNODE(db);
+	epbs = dn->dn_phys->dn_indblkshift - SPA_BLKPTRSHIFT;
+	shift = (db->db_level - 1) * epbs;
+	dbstart = db->db_blkid << epbs;
+	start = blkid >> shift;
+	if (dbstart < start) {
+		bp += start - dbstart;
+	} else {
+		start = dbstart;
+	}
+	dbend = ((db->db_blkid + 1) << epbs) - 1;
+	end = (blkid + nblks - 1) >> shift;
+	if (dbend <= end)
+		end = dbend;
+
+	ASSERT3U(start, <=, end);
+
+	if (db->db_level == 1) {
+		FREE_VERIFY(db, start, end, tx);
+		free_blocks(dn, bp, end-start+1, tx);
+	} else {
+		for (i = start; i <= end; i++, bp++) {
+			if (BP_IS_HOLE(bp))
+				continue;
+			rw_enter(&dn->dn_struct_rwlock, RW_READER);
+			VERIFY0(dbuf_hold_impl(dn, db->db_level - 1,
+			    i, B_TRUE, FTAG, &subdb));
+			rw_exit(&dn->dn_struct_rwlock);
+			ASSERT3P(bp, ==, subdb->db_blkptr);
+
+			free_children(subdb, blkid, nblks, tx);
+			dbuf_rele(subdb, FTAG);
+		}
+	}
+
+	/* If this whole block is free, free ourself too. */
+	for (i = 0, bp = db->db.db_data; i < 1 << epbs; i++, bp++) {
+		if (!BP_IS_HOLE(bp))
+			break;
+	}
+	if (i == 1 << epbs) {
+		/* didn't find any non-holes */
+		bzero(db->db.db_data, db->db.db_size);
+		free_blocks(dn, db->db_blkptr, 1, tx);
+	} else {
+		/*
+		 * Partial block free; must be marked dirty so that it
+		 * will be written out.
+		 */
+		ASSERT(db->db_dirtycnt > 0);
+	}
+
+	DB_DNODE_EXIT(db);
+	arc_buf_freeze(db->db_buf);
+}
+
+/*
+ * Traverse the indicated range of the provided file
+ * and "free" all the blocks contained there.
+ */
+static void
+dnode_sync_free_range_impl(dnode_t *dn, uint64_t blkid, uint64_t nblks,
+    dmu_tx_t *tx)
+{
+	blkptr_t *bp = dn->dn_phys->dn_blkptr;
+	int dnlevel = dn->dn_phys->dn_nlevels;
+	boolean_t trunc = B_FALSE;
+
+	if (blkid > dn->dn_phys->dn_maxblkid)
+		return;
+
+	ASSERT(dn->dn_phys->dn_maxblkid < UINT64_MAX);
+	if (blkid + nblks > dn->dn_phys->dn_maxblkid) {
+		nblks = dn->dn_phys->dn_maxblkid - blkid + 1;
+		trunc = B_TRUE;
+	}
+
+	/* There are no indirect blocks in the object */
+	if (dnlevel == 1) {
+		if (blkid >= dn->dn_phys->dn_nblkptr) {
+			/* this range was never made persistent */
+			return;
+		}
+		ASSERT3U(blkid + nblks, <=, dn->dn_phys->dn_nblkptr);
+		free_blocks(dn, bp + blkid, nblks, tx);
+	} else {
+		int shift = (dnlevel - 1) *
+		    (dn->dn_phys->dn_indblkshift - SPA_BLKPTRSHIFT);
+		int start = blkid >> shift;
+		int end = (blkid + nblks - 1) >> shift;
+		dmu_buf_impl_t *db;
+		int i;
+
+		ASSERT(start < dn->dn_phys->dn_nblkptr);
+		bp += start;
+		for (i = start; i <= end; i++, bp++) {
+			if (BP_IS_HOLE(bp))
+				continue;
+			rw_enter(&dn->dn_struct_rwlock, RW_READER);
+			VERIFY0(dbuf_hold_impl(dn, dnlevel - 1, i,
+			    TRUE, FTAG, &db));
+			rw_exit(&dn->dn_struct_rwlock);
+
+			free_children(db, blkid, nblks, tx);
+			dbuf_rele(db, FTAG);
+		}
+	}
+
+	if (trunc) {
+		ASSERTV(uint64_t off);
+		dn->dn_phys->dn_maxblkid = blkid == 0 ? 0 : blkid - 1;
+
+		ASSERTV(off = (dn->dn_phys->dn_maxblkid + 1) *
+		    (dn->dn_phys->dn_datablkszsec << SPA_MINBLOCKSHIFT));
+		ASSERT(off < dn->dn_phys->dn_maxblkid ||
+		    dn->dn_phys->dn_maxblkid == 0 ||
+		    dnode_next_offset(dn, 0, &off, 1, 1, 0) != 0);
+	}
+}
+
+typedef struct dnode_sync_free_range_arg {
+	dnode_t *dsfra_dnode;
+	dmu_tx_t *dsfra_tx;
+} dnode_sync_free_range_arg_t;
+
+static void
+dnode_sync_free_range(void *arg, uint64_t blkid, uint64_t nblks)
+{
+	dnode_sync_free_range_arg_t *dsfra = arg;
+	dnode_t *dn = dsfra->dsfra_dnode;
+
+	mutex_exit(&dn->dn_mtx);
+	dnode_sync_free_range_impl(dn, blkid, nblks, dsfra->dsfra_tx);
+	mutex_enter(&dn->dn_mtx);
+}
+
+/*
+ * Try to kick all the dnode's dbufs out of the cache...
+ */
+void
+dnode_evict_dbufs(dnode_t *dn)
+{
+	dmu_buf_impl_t *db_marker;
+	dmu_buf_impl_t *db, *db_next;
+
+	db_marker = kmem_alloc(sizeof (dmu_buf_impl_t), KM_SLEEP);
+
+	mutex_enter(&dn->dn_dbufs_mtx);
+	for (db = avl_first(&dn->dn_dbufs); db != NULL; db = db_next) {
+
+#ifdef	DEBUG
+		DB_DNODE_ENTER(db);
+		ASSERT3P(DB_DNODE(db), ==, dn);
+		DB_DNODE_EXIT(db);
+#endif	/* DEBUG */
+
+		mutex_enter(&db->db_mtx);
+		if (db->db_state != DB_EVICTING &&
+		    refcount_is_zero(&db->db_holds)) {
+			db_marker->db_level = db->db_level;
+			db_marker->db_blkid = db->db_blkid;
+			db_marker->db_state = DB_SEARCH;
+			avl_insert_here(&dn->dn_dbufs, db_marker, db,
+			    AVL_BEFORE);
+
+			dbuf_clear(db);
+
+			db_next = AVL_NEXT(&dn->dn_dbufs, db_marker);
+			avl_remove(&dn->dn_dbufs, db_marker);
+		} else {
+			db->db_pending_evict = TRUE;
+			mutex_exit(&db->db_mtx);
+			db_next = AVL_NEXT(&dn->dn_dbufs, db);
+		}
+	}
+	mutex_exit(&dn->dn_dbufs_mtx);
+
+	kmem_free(db_marker, sizeof (dmu_buf_impl_t));
+
+	dnode_evict_bonus(dn);
+}
+
+void
+dnode_evict_bonus(dnode_t *dn)
+{
+	rw_enter(&dn->dn_struct_rwlock, RW_WRITER);
+	if (dn->dn_bonus != NULL) {
+		if (refcount_is_zero(&dn->dn_bonus->db_holds)) {
+			mutex_enter(&dn->dn_bonus->db_mtx);
+			dbuf_evict(dn->dn_bonus);
+			dn->dn_bonus = NULL;
+		} else {
+			dn->dn_bonus->db_pending_evict = TRUE;
+		}
+	}
+	rw_exit(&dn->dn_struct_rwlock);
+}
+
+static void
+dnode_undirty_dbufs(list_t *list)
+{
+	dbuf_dirty_record_t *dr;
+
+	while ((dr = list_head(list))) {
+		dmu_buf_impl_t *db = dr->dr_dbuf;
+		uint64_t txg = dr->dr_txg;
+
+		if (db->db_level != 0)
+			dnode_undirty_dbufs(&dr->dt.di.dr_children);
+
+		mutex_enter(&db->db_mtx);
+		/* XXX - use dbuf_undirty()? */
+		list_remove(list, dr);
+		ASSERT(db->db_last_dirty == dr);
+		db->db_last_dirty = NULL;
+		db->db_dirtycnt -= 1;
+		if (db->db_level == 0) {
+			ASSERT(db->db_blkid == DMU_BONUS_BLKID ||
+			    dr->dt.dl.dr_data == db->db_buf);
+			dbuf_unoverride(dr);
+		} else {
+			mutex_destroy(&dr->dt.di.dr_mtx);
+			list_destroy(&dr->dt.di.dr_children);
+		}
+		kmem_free(dr, sizeof (dbuf_dirty_record_t));
+		dbuf_rele_and_unlock(db, (void *)(uintptr_t)txg);
+	}
+}
+
+static void
+dnode_sync_free(dnode_t *dn, dmu_tx_t *tx)
+{
+	int txgoff = tx->tx_txg & TXG_MASK;
+
+	ASSERT(dmu_tx_is_syncing(tx));
+
+	/*
+	 * Our contents should have been freed in dnode_sync() by the
+	 * free range record inserted by the caller of dnode_free().
+	 */
+	ASSERT0(DN_USED_BYTES(dn->dn_phys));
+	ASSERT(BP_IS_HOLE(dn->dn_phys->dn_blkptr));
+
+	dnode_undirty_dbufs(&dn->dn_dirty_records[txgoff]);
+	dnode_evict_dbufs(dn);
+
+	/*
+	 * XXX - It would be nice to assert this, but we may still
+	 * have residual holds from async evictions from the arc...
+	 *
+	 * zfs_obj_to_path() also depends on this being
+	 * commented out.
+	 *
+	 * ASSERT3U(refcount_count(&dn->dn_holds), ==, 1);
+	 */
+
+	/* Undirty next bits */
+	dn->dn_next_nlevels[txgoff] = 0;
+	dn->dn_next_indblkshift[txgoff] = 0;
+	dn->dn_next_blksz[txgoff] = 0;
+
+	/* ASSERT(blkptrs are zero); */
+	ASSERT(dn->dn_phys->dn_type != DMU_OT_NONE);
+	ASSERT(dn->dn_type != DMU_OT_NONE);
+
+	ASSERT(dn->dn_free_txg > 0);
+	if (dn->dn_allocated_txg != dn->dn_free_txg)
+		dmu_buf_will_dirty(&dn->dn_dbuf->db, tx);
+	bzero(dn->dn_phys, sizeof (dnode_phys_t));
+
+	mutex_enter(&dn->dn_mtx);
+	dn->dn_type = DMU_OT_NONE;
+	dn->dn_maxblkid = 0;
+	dn->dn_allocated_txg = 0;
+	dn->dn_free_txg = 0;
+	dn->dn_have_spill = B_FALSE;
+	mutex_exit(&dn->dn_mtx);
+
+	ASSERT(dn->dn_object != DMU_META_DNODE_OBJECT);
+
+	dnode_rele(dn, (void *)(uintptr_t)tx->tx_txg);
+	/*
+	 * Now that we've released our hold, the dnode may
+	 * be evicted, so we musn't access it.
+	 */
+}
+
+/*
+ * Write out the dnode's dirty buffers.
+ */
+void
+dnode_sync(dnode_t *dn, dmu_tx_t *tx)
+{
+	dnode_phys_t *dnp = dn->dn_phys;
+	int txgoff = tx->tx_txg & TXG_MASK;
+	list_t *list = &dn->dn_dirty_records[txgoff];
+	boolean_t kill_spill = B_FALSE;
+	boolean_t freeing_dnode;
+	ASSERTV(static const dnode_phys_t zerodn = { 0 });
+
+	ASSERT(dmu_tx_is_syncing(tx));
+	ASSERT(dnp->dn_type != DMU_OT_NONE || dn->dn_allocated_txg);
+	ASSERT(dnp->dn_type != DMU_OT_NONE ||
+	    bcmp(dnp, &zerodn, DNODE_SIZE) == 0);
+	DNODE_VERIFY(dn);
+
+	ASSERT(dn->dn_dbuf == NULL || arc_released(dn->dn_dbuf->db_buf));
+
+	if (dmu_objset_userused_enabled(dn->dn_objset) &&
+	    !DMU_OBJECT_IS_SPECIAL(dn->dn_object)) {
+		mutex_enter(&dn->dn_mtx);
+		dn->dn_oldused = DN_USED_BYTES(dn->dn_phys);
+		dn->dn_oldflags = dn->dn_phys->dn_flags;
+		dn->dn_phys->dn_flags |= DNODE_FLAG_USERUSED_ACCOUNTED;
+		mutex_exit(&dn->dn_mtx);
+		dmu_objset_userquota_get_ids(dn, B_FALSE, tx);
+	} else {
+		/* Once we account for it, we should always account for it. */
+		ASSERT(!(dn->dn_phys->dn_flags &
+		    DNODE_FLAG_USERUSED_ACCOUNTED));
+	}
+
+	mutex_enter(&dn->dn_mtx);
+	if (dn->dn_allocated_txg == tx->tx_txg) {
+		/* The dnode is newly allocated or reallocated */
+		if (dnp->dn_type == DMU_OT_NONE) {
+			/* this is a first alloc, not a realloc */
+			dnp->dn_nlevels = 1;
+			dnp->dn_nblkptr = dn->dn_nblkptr;
+		}
+
+		dnp->dn_type = dn->dn_type;
+		dnp->dn_bonustype = dn->dn_bonustype;
+		dnp->dn_bonuslen = dn->dn_bonuslen;
+	}
+	ASSERT(dnp->dn_nlevels > 1 ||
+	    BP_IS_HOLE(&dnp->dn_blkptr[0]) ||
+	    BP_IS_EMBEDDED(&dnp->dn_blkptr[0]) ||
+	    BP_GET_LSIZE(&dnp->dn_blkptr[0]) ==
+	    dnp->dn_datablkszsec << SPA_MINBLOCKSHIFT);
+	ASSERT(dnp->dn_nlevels < 2 ||
+	    BP_IS_HOLE(&dnp->dn_blkptr[0]) ||
+	    BP_GET_LSIZE(&dnp->dn_blkptr[0]) == 1 << dnp->dn_indblkshift);
+
+	if (dn->dn_next_type[txgoff] != 0) {
+		dnp->dn_type = dn->dn_type;
+		dn->dn_next_type[txgoff] = 0;
+	}
+
+	if (dn->dn_next_blksz[txgoff] != 0) {
+		ASSERT(P2PHASE(dn->dn_next_blksz[txgoff],
+		    SPA_MINBLOCKSIZE) == 0);
+		ASSERT(BP_IS_HOLE(&dnp->dn_blkptr[0]) ||
+		    dn->dn_maxblkid == 0 || list_head(list) != NULL ||
+		    dn->dn_next_blksz[txgoff] >> SPA_MINBLOCKSHIFT ==
+		    dnp->dn_datablkszsec ||
+		    range_tree_space(dn->dn_free_ranges[txgoff]) != 0);
+		dnp->dn_datablkszsec =
+		    dn->dn_next_blksz[txgoff] >> SPA_MINBLOCKSHIFT;
+		dn->dn_next_blksz[txgoff] = 0;
+	}
+
+	if (dn->dn_next_bonuslen[txgoff] != 0) {
+		if (dn->dn_next_bonuslen[txgoff] == DN_ZERO_BONUSLEN)
+			dnp->dn_bonuslen = 0;
+		else
+			dnp->dn_bonuslen = dn->dn_next_bonuslen[txgoff];
+		ASSERT(dnp->dn_bonuslen <= DN_MAX_BONUSLEN);
+		dn->dn_next_bonuslen[txgoff] = 0;
+	}
+
+	if (dn->dn_next_bonustype[txgoff] != 0) {
+		ASSERT(DMU_OT_IS_VALID(dn->dn_next_bonustype[txgoff]));
+		dnp->dn_bonustype = dn->dn_next_bonustype[txgoff];
+		dn->dn_next_bonustype[txgoff] = 0;
+	}
+
+	freeing_dnode = dn->dn_free_txg > 0 && dn->dn_free_txg <= tx->tx_txg;
+
+	/*
+	 * Remove the spill block if we have been explicitly asked to
+	 * remove it, or if the object is being removed.
+	 */
+	if (dn->dn_rm_spillblk[txgoff] || freeing_dnode) {
+		if (dnp->dn_flags & DNODE_FLAG_SPILL_BLKPTR)
+			kill_spill = B_TRUE;
+		dn->dn_rm_spillblk[txgoff] = 0;
+	}
+
+	if (dn->dn_next_indblkshift[txgoff] != 0) {
+		ASSERT(dnp->dn_nlevels == 1);
+		dnp->dn_indblkshift = dn->dn_next_indblkshift[txgoff];
+		dn->dn_next_indblkshift[txgoff] = 0;
+	}
+
+	/*
+	 * Just take the live (open-context) values for checksum and compress.
+	 * Strictly speaking it's a future leak, but nothing bad happens if we
+	 * start using the new checksum or compress algorithm a little early.
+	 */
+	dnp->dn_checksum = dn->dn_checksum;
+	dnp->dn_compress = dn->dn_compress;
+
+	mutex_exit(&dn->dn_mtx);
+
+	if (kill_spill) {
+		free_blocks(dn, &dn->dn_phys->dn_spill, 1, tx);
+		mutex_enter(&dn->dn_mtx);
+		dnp->dn_flags &= ~DNODE_FLAG_SPILL_BLKPTR;
+		mutex_exit(&dn->dn_mtx);
+	}
+
+	/* process all the "freed" ranges in the file */
+	if (dn->dn_free_ranges[txgoff] != NULL) {
+		dnode_sync_free_range_arg_t dsfra;
+		dsfra.dsfra_dnode = dn;
+		dsfra.dsfra_tx = tx;
+		mutex_enter(&dn->dn_mtx);
+		range_tree_vacate(dn->dn_free_ranges[txgoff],
+		    dnode_sync_free_range, &dsfra);
+		range_tree_destroy(dn->dn_free_ranges[txgoff]);
+		dn->dn_free_ranges[txgoff] = NULL;
+		mutex_exit(&dn->dn_mtx);
+	}
+
+	if (freeing_dnode) {
+		dnode_sync_free(dn, tx);
+		return;
+	}
+
+	if (dn->dn_next_nlevels[txgoff]) {
+		dnode_increase_indirection(dn, tx);
+		dn->dn_next_nlevels[txgoff] = 0;
+	}
+
+	if (dn->dn_next_nblkptr[txgoff]) {
+		/* this should only happen on a realloc */
+		ASSERT(dn->dn_allocated_txg == tx->tx_txg);
+		if (dn->dn_next_nblkptr[txgoff] > dnp->dn_nblkptr) {
+			/* zero the new blkptrs we are gaining */
+			bzero(dnp->dn_blkptr + dnp->dn_nblkptr,
+			    sizeof (blkptr_t) *
+			    (dn->dn_next_nblkptr[txgoff] - dnp->dn_nblkptr));
+#ifdef ZFS_DEBUG
+		} else {
+			int i;
+			ASSERT(dn->dn_next_nblkptr[txgoff] < dnp->dn_nblkptr);
+			/* the blkptrs we are losing better be unallocated */
+			for (i = 0; i < dnp->dn_nblkptr; i++) {
+				if (i >= dn->dn_next_nblkptr[txgoff])
+					ASSERT(BP_IS_HOLE(&dnp->dn_blkptr[i]));
+			}
+#endif
+		}
+		mutex_enter(&dn->dn_mtx);
+		dnp->dn_nblkptr = dn->dn_next_nblkptr[txgoff];
+		dn->dn_next_nblkptr[txgoff] = 0;
+		mutex_exit(&dn->dn_mtx);
+	}
+
+	dbuf_sync_list(list, dn->dn_phys->dn_nlevels - 1, tx);
+
+	if (!DMU_OBJECT_IS_SPECIAL(dn->dn_object)) {
+		ASSERT3P(list_head(list), ==, NULL);
+		dnode_rele(dn, (void *)(uintptr_t)tx->tx_txg);
+	}
+
+	/*
+	 * Although we have dropped our reference to the dnode, it
+	 * can't be evicted until its written, and we haven't yet
+	 * initiated the IO for the dnode's dbuf.
+	 */
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/module/zfs/dsl_bookmark.c
@@ -0,0 +1,462 @@
+/*
+ * CDDL HEADER START
+ *
+ * This file and its contents are supplied under the terms of the
+ * Common Development and Distribution License ("CDDL"), version 1.0.
+ * You may only use this file in accordance with the terms of version
+ * 1.0 of the CDDL.
+ *
+ * A full copy of the text of the CDDL should have accompanied this
+ * source.  A copy of the CDDL is also available via the Internet at
+ * http://www.illumos.org/license/CDDL.
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2013, 2014 by Delphix. All rights reserved.
+ */
+
+#include <sys/zfs_context.h>
+#include <sys/dsl_dataset.h>
+#include <sys/dsl_dir.h>
+#include <sys/dsl_prop.h>
+#include <sys/dsl_synctask.h>
+#include <sys/dmu_impl.h>
+#include <sys/dmu_tx.h>
+#include <sys/arc.h>
+#include <sys/zap.h>
+#include <sys/zfeature.h>
+#include <sys/spa.h>
+#include <sys/dsl_bookmark.h>
+#include <zfs_namecheck.h>
+
+static int
+dsl_bookmark_hold_ds(dsl_pool_t *dp, const char *fullname,
+    dsl_dataset_t **dsp, void *tag, char **shortnamep)
+{
+	char buf[MAXNAMELEN];
+	char *hashp;
+
+	if (strlen(fullname) >= MAXNAMELEN)
+		return (SET_ERROR(ENAMETOOLONG));
+	hashp = strchr(fullname, '#');
+	if (hashp == NULL)
+		return (SET_ERROR(EINVAL));
+
+	*shortnamep = hashp + 1;
+	if (zfs_component_namecheck(*shortnamep, NULL, NULL))
+		return (SET_ERROR(EINVAL));
+	(void) strlcpy(buf, fullname, hashp - fullname + 1);
+	return (dsl_dataset_hold(dp, buf, tag, dsp));
+}
+
+/*
+ * Returns ESRCH if bookmark is not found.
+ */
+static int
+dsl_dataset_bmark_lookup(dsl_dataset_t *ds, const char *shortname,
+    zfs_bookmark_phys_t *bmark_phys)
+{
+	objset_t *mos = ds->ds_dir->dd_pool->dp_meta_objset;
+	uint64_t bmark_zapobj = ds->ds_bookmarks;
+	matchtype_t mt;
+	int err;
+
+	if (bmark_zapobj == 0)
+		return (SET_ERROR(ESRCH));
+
+	if (dsl_dataset_phys(ds)->ds_flags & DS_FLAG_CI_DATASET)
+		mt = MT_FIRST;
+	else
+		mt = MT_EXACT;
+
+	err = zap_lookup_norm(mos, bmark_zapobj, shortname, sizeof (uint64_t),
+	    sizeof (*bmark_phys) / sizeof (uint64_t), bmark_phys, mt,
+	    NULL, 0, NULL);
+
+	return (err == ENOENT ? ESRCH : err);
+}
+
+/*
+ * If later_ds is non-NULL, this will return EXDEV if the the specified bookmark
+ * does not represents an earlier point in later_ds's timeline.
+ *
+ * Returns ENOENT if the dataset containing the bookmark does not exist.
+ * Returns ESRCH if the dataset exists but the bookmark was not found in it.
+ */
+int
+dsl_bookmark_lookup(dsl_pool_t *dp, const char *fullname,
+    dsl_dataset_t *later_ds, zfs_bookmark_phys_t *bmp)
+{
+	char *shortname;
+	dsl_dataset_t *ds;
+	int error;
+
+	error = dsl_bookmark_hold_ds(dp, fullname, &ds, FTAG, &shortname);
+	if (error != 0)
+		return (error);
+
+	error = dsl_dataset_bmark_lookup(ds, shortname, bmp);
+	if (error == 0 && later_ds != NULL) {
+		if (!dsl_dataset_is_before(later_ds, ds, bmp->zbm_creation_txg))
+			error = SET_ERROR(EXDEV);
+	}
+	dsl_dataset_rele(ds, FTAG);
+	return (error);
+}
+
+typedef struct dsl_bookmark_create_arg {
+	nvlist_t *dbca_bmarks;
+	nvlist_t *dbca_errors;
+} dsl_bookmark_create_arg_t;
+
+static int
+dsl_bookmark_create_check_impl(dsl_dataset_t *snapds, const char *bookmark_name,
+    dmu_tx_t *tx)
+{
+	dsl_pool_t *dp = dmu_tx_pool(tx);
+	dsl_dataset_t *bmark_fs;
+	char *shortname;
+	int error;
+	zfs_bookmark_phys_t bmark_phys;
+
+	if (!snapds->ds_is_snapshot)
+		return (SET_ERROR(EINVAL));
+
+	error = dsl_bookmark_hold_ds(dp, bookmark_name,
+	    &bmark_fs, FTAG, &shortname);
+	if (error != 0)
+		return (error);
+
+	if (!dsl_dataset_is_before(bmark_fs, snapds, 0)) {
+		dsl_dataset_rele(bmark_fs, FTAG);
+		return (SET_ERROR(EINVAL));
+	}
+
+	error = dsl_dataset_bmark_lookup(bmark_fs, shortname,
+	    &bmark_phys);
+	dsl_dataset_rele(bmark_fs, FTAG);
+	if (error == 0)
+		return (SET_ERROR(EEXIST));
+	if (error == ESRCH)
+		return (0);
+	return (error);
+}
+
+static int
+dsl_bookmark_create_check(void *arg, dmu_tx_t *tx)
+{
+	dsl_bookmark_create_arg_t *dbca = arg;
+	dsl_pool_t *dp = dmu_tx_pool(tx);
+	int rv = 0;
+	nvpair_t *pair;
+
+	if (!spa_feature_is_enabled(dp->dp_spa, SPA_FEATURE_BOOKMARKS))
+		return (SET_ERROR(ENOTSUP));
+
+	for (pair = nvlist_next_nvpair(dbca->dbca_bmarks, NULL);
+	    pair != NULL; pair = nvlist_next_nvpair(dbca->dbca_bmarks, pair)) {
+		dsl_dataset_t *snapds;
+		int error;
+
+		/* note: validity of nvlist checked by ioctl layer */
+		error = dsl_dataset_hold(dp, fnvpair_value_string(pair),
+		    FTAG, &snapds);
+		if (error == 0) {
+			error = dsl_bookmark_create_check_impl(snapds,
+			    nvpair_name(pair), tx);
+			dsl_dataset_rele(snapds, FTAG);
+		}
+		if (error != 0) {
+			fnvlist_add_int32(dbca->dbca_errors,
+			    nvpair_name(pair), error);
+			rv = error;
+		}
+	}
+
+	return (rv);
+}
+
+static void
+dsl_bookmark_create_sync(void *arg, dmu_tx_t *tx)
+{
+	dsl_bookmark_create_arg_t *dbca = arg;
+	dsl_pool_t *dp = dmu_tx_pool(tx);
+	objset_t *mos = dp->dp_meta_objset;
+	nvpair_t *pair;
+
+	ASSERT(spa_feature_is_enabled(dp->dp_spa, SPA_FEATURE_BOOKMARKS));
+
+	for (pair = nvlist_next_nvpair(dbca->dbca_bmarks, NULL);
+	    pair != NULL; pair = nvlist_next_nvpair(dbca->dbca_bmarks, pair)) {
+		dsl_dataset_t *snapds, *bmark_fs;
+		zfs_bookmark_phys_t bmark_phys;
+		char *shortname;
+
+		VERIFY0(dsl_dataset_hold(dp, fnvpair_value_string(pair),
+		    FTAG, &snapds));
+		VERIFY0(dsl_bookmark_hold_ds(dp, nvpair_name(pair),
+		    &bmark_fs, FTAG, &shortname));
+		if (bmark_fs->ds_bookmarks == 0) {
+			bmark_fs->ds_bookmarks =
+			    zap_create_norm(mos, U8_TEXTPREP_TOUPPER,
+			    DMU_OTN_ZAP_METADATA, DMU_OT_NONE, 0, tx);
+			spa_feature_incr(dp->dp_spa, SPA_FEATURE_BOOKMARKS, tx);
+
+			dsl_dataset_zapify(bmark_fs, tx);
+			VERIFY0(zap_add(mos, bmark_fs->ds_object,
+			    DS_FIELD_BOOKMARK_NAMES,
+			    sizeof (bmark_fs->ds_bookmarks), 1,
+			    &bmark_fs->ds_bookmarks, tx));
+		}
+
+		bmark_phys.zbm_guid = dsl_dataset_phys(snapds)->ds_guid;
+		bmark_phys.zbm_creation_txg =
+		    dsl_dataset_phys(snapds)->ds_creation_txg;
+		bmark_phys.zbm_creation_time =
+		    dsl_dataset_phys(snapds)->ds_creation_time;
+
+		VERIFY0(zap_add(mos, bmark_fs->ds_bookmarks,
+		    shortname, sizeof (uint64_t),
+		    sizeof (zfs_bookmark_phys_t) / sizeof (uint64_t),
+		    &bmark_phys, tx));
+
+		spa_history_log_internal_ds(bmark_fs, "bookmark", tx,
+		    "name=%s creation_txg=%llu target_snap=%llu",
+		    shortname,
+		    (longlong_t)bmark_phys.zbm_creation_txg,
+		    (longlong_t)snapds->ds_object);
+
+		dsl_dataset_rele(bmark_fs, FTAG);
+		dsl_dataset_rele(snapds, FTAG);
+	}
+}
+
+/*
+ * The bookmarks must all be in the same pool.
+ */
+int
+dsl_bookmark_create(nvlist_t *bmarks, nvlist_t *errors)
+{
+	nvpair_t *pair;
+	dsl_bookmark_create_arg_t dbca;
+
+	pair = nvlist_next_nvpair(bmarks, NULL);
+	if (pair == NULL)
+		return (0);
+
+	dbca.dbca_bmarks = bmarks;
+	dbca.dbca_errors = errors;
+
+	return (dsl_sync_task(nvpair_name(pair), dsl_bookmark_create_check,
+	    dsl_bookmark_create_sync, &dbca,
+	    fnvlist_num_pairs(bmarks), ZFS_SPACE_CHECK_NORMAL));
+}
+
+int
+dsl_get_bookmarks_impl(dsl_dataset_t *ds, nvlist_t *props, nvlist_t *outnvl)
+{
+	int err = 0;
+	zap_cursor_t zc;
+	zap_attribute_t attr;
+	dsl_pool_t *dp = ds->ds_dir->dd_pool;
+
+	uint64_t bmark_zapobj = ds->ds_bookmarks;
+	if (bmark_zapobj == 0)
+		return (0);
+
+	for (zap_cursor_init(&zc, dp->dp_meta_objset, bmark_zapobj);
+	    zap_cursor_retrieve(&zc, &attr) == 0;
+	    zap_cursor_advance(&zc)) {
+		nvlist_t *out_props;
+		char *bmark_name = attr.za_name;
+		zfs_bookmark_phys_t bmark_phys;
+
+		err = dsl_dataset_bmark_lookup(ds, bmark_name, &bmark_phys);
+		ASSERT3U(err, !=, ENOENT);
+		if (err != 0)
+			break;
+
+		out_props = fnvlist_alloc();
+		if (nvlist_exists(props,
+		    zfs_prop_to_name(ZFS_PROP_GUID))) {
+			dsl_prop_nvlist_add_uint64(out_props,
+			    ZFS_PROP_GUID, bmark_phys.zbm_guid);
+		}
+		if (nvlist_exists(props,
+		    zfs_prop_to_name(ZFS_PROP_CREATETXG))) {
+			dsl_prop_nvlist_add_uint64(out_props,
+			    ZFS_PROP_CREATETXG, bmark_phys.zbm_creation_txg);
+		}
+		if (nvlist_exists(props,
+		    zfs_prop_to_name(ZFS_PROP_CREATION))) {
+			dsl_prop_nvlist_add_uint64(out_props,
+			    ZFS_PROP_CREATION, bmark_phys.zbm_creation_time);
+		}
+
+		fnvlist_add_nvlist(outnvl, bmark_name, out_props);
+		fnvlist_free(out_props);
+	}
+	zap_cursor_fini(&zc);
+	return (err);
+}
+
+/*
+ * Retrieve the bookmarks that exist in the specified dataset, and the
+ * requested properties of each bookmark.
+ *
+ * The "props" nvlist specifies which properties are requested.
+ * See lzc_get_bookmarks() for the list of valid properties.
+ */
+int
+dsl_get_bookmarks(const char *dsname, nvlist_t *props, nvlist_t *outnvl)
+{
+	dsl_pool_t *dp;
+	dsl_dataset_t *ds;
+	int err;
+
+	err = dsl_pool_hold(dsname, FTAG, &dp);
+	if (err != 0)
+		return (err);
+	err = dsl_dataset_hold(dp, dsname, FTAG, &ds);
+	if (err != 0) {
+		dsl_pool_rele(dp, FTAG);
+		return (err);
+	}
+
+	err = dsl_get_bookmarks_impl(ds, props, outnvl);
+
+	dsl_dataset_rele(ds, FTAG);
+	dsl_pool_rele(dp, FTAG);
+	return (err);
+}
+
+typedef struct dsl_bookmark_destroy_arg {
+	nvlist_t *dbda_bmarks;
+	nvlist_t *dbda_success;
+	nvlist_t *dbda_errors;
+} dsl_bookmark_destroy_arg_t;
+
+static int
+dsl_dataset_bookmark_remove(dsl_dataset_t *ds, const char *name, dmu_tx_t *tx)
+{
+	objset_t *mos = ds->ds_dir->dd_pool->dp_meta_objset;
+	uint64_t bmark_zapobj = ds->ds_bookmarks;
+	matchtype_t mt;
+
+	if (dsl_dataset_phys(ds)->ds_flags & DS_FLAG_CI_DATASET)
+		mt = MT_FIRST;
+	else
+		mt = MT_EXACT;
+
+	return (zap_remove_norm(mos, bmark_zapobj, name, mt, tx));
+}
+
+static int
+dsl_bookmark_destroy_check(void *arg, dmu_tx_t *tx)
+{
+	dsl_bookmark_destroy_arg_t *dbda = arg;
+	dsl_pool_t *dp = dmu_tx_pool(tx);
+	int rv = 0;
+	nvpair_t *pair;
+
+	if (!spa_feature_is_enabled(dp->dp_spa, SPA_FEATURE_BOOKMARKS))
+		return (0);
+
+	for (pair = nvlist_next_nvpair(dbda->dbda_bmarks, NULL);
+	    pair != NULL; pair = nvlist_next_nvpair(dbda->dbda_bmarks, pair)) {
+		const char *fullname = nvpair_name(pair);
+		dsl_dataset_t *ds;
+		zfs_bookmark_phys_t bm;
+		int error;
+		char *shortname;
+
+		error = dsl_bookmark_hold_ds(dp, fullname, &ds,
+		    FTAG, &shortname);
+		if (error == ENOENT) {
+			/* ignore it; the bookmark is "already destroyed" */
+			continue;
+		}
+		if (error == 0) {
+			error = dsl_dataset_bmark_lookup(ds, shortname, &bm);
+			dsl_dataset_rele(ds, FTAG);
+			if (error == ESRCH) {
+				/*
+				 * ignore it; the bookmark is
+				 * "already destroyed"
+				 */
+				continue;
+			}
+		}
+		if (error == 0) {
+			fnvlist_add_boolean(dbda->dbda_success, fullname);
+		} else {
+			fnvlist_add_int32(dbda->dbda_errors, fullname, error);
+			rv = error;
+		}
+	}
+	return (rv);
+}
+
+static void
+dsl_bookmark_destroy_sync(void *arg, dmu_tx_t *tx)
+{
+	dsl_bookmark_destroy_arg_t *dbda = arg;
+	dsl_pool_t *dp = dmu_tx_pool(tx);
+	objset_t *mos = dp->dp_meta_objset;
+	nvpair_t *pair;
+
+	for (pair = nvlist_next_nvpair(dbda->dbda_success, NULL);
+	    pair != NULL; pair = nvlist_next_nvpair(dbda->dbda_success, pair)) {
+		dsl_dataset_t *ds;
+		char *shortname;
+		uint64_t zap_cnt;
+
+		VERIFY0(dsl_bookmark_hold_ds(dp, nvpair_name(pair),
+		    &ds, FTAG, &shortname));
+		VERIFY0(dsl_dataset_bookmark_remove(ds, shortname, tx));
+
+		/*
+		 * If all of this dataset's bookmarks have been destroyed,
+		 * free the zap object and decrement the feature's use count.
+		 */
+		VERIFY0(zap_count(mos, ds->ds_bookmarks,
+		    &zap_cnt));
+		if (zap_cnt == 0) {
+			dmu_buf_will_dirty(ds->ds_dbuf, tx);
+			VERIFY0(zap_destroy(mos, ds->ds_bookmarks, tx));
+			ds->ds_bookmarks = 0;
+			spa_feature_decr(dp->dp_spa, SPA_FEATURE_BOOKMARKS, tx);
+			VERIFY0(zap_remove(mos, ds->ds_object,
+			    DS_FIELD_BOOKMARK_NAMES, tx));
+		}
+
+		spa_history_log_internal_ds(ds, "remove bookmark", tx,
+		    "name=%s", shortname);
+
+		dsl_dataset_rele(ds, FTAG);
+	}
+}
+
+/*
+ * The bookmarks must all be in the same pool.
+ */
+int
+dsl_bookmark_destroy(nvlist_t *bmarks, nvlist_t *errors)
+{
+	int rv;
+	dsl_bookmark_destroy_arg_t dbda;
+	nvpair_t *pair = nvlist_next_nvpair(bmarks, NULL);
+	if (pair == NULL)
+		return (0);
+
+	dbda.dbda_bmarks = bmarks;
+	dbda.dbda_errors = errors;
+	dbda.dbda_success = fnvlist_alloc();
+
+	rv = dsl_sync_task(nvpair_name(pair), dsl_bookmark_destroy_check,
+	    dsl_bookmark_destroy_sync, &dbda, fnvlist_num_pairs(bmarks),
+	    ZFS_SPACE_CHECK_RESERVED);
+	fnvlist_free(dbda.dbda_success);
+	return (rv);
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/module/zfs/dsl_dataset.c
@@ -0,0 +1,3413 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013 by Delphix. All rights reserved.
+ * Copyright (c) 2014, Joyent, Inc. All rights reserved.
+ * Copyright (c) 2014 RackTop Systems.
+ * Copyright (c) 2014 Spectra Logic Corporation, All rights reserved.
+ * Copyright (c) 2016 Actifio, Inc. All rights reserved.
+ */
+
+#include <sys/dmu_objset.h>
+#include <sys/dsl_dataset.h>
+#include <sys/dsl_dir.h>
+#include <sys/dsl_prop.h>
+#include <sys/dsl_synctask.h>
+#include <sys/dmu_traverse.h>
+#include <sys/dmu_impl.h>
+#include <sys/dmu_tx.h>
+#include <sys/arc.h>
+#include <sys/zio.h>
+#include <sys/zap.h>
+#include <sys/zfeature.h>
+#include <sys/unique.h>
+#include <sys/zfs_context.h>
+#include <sys/zfs_ioctl.h>
+#include <sys/spa.h>
+#include <sys/zfs_znode.h>
+#include <sys/zfs_onexit.h>
+#include <sys/zvol.h>
+#include <sys/dsl_scan.h>
+#include <sys/dsl_deadlist.h>
+#include <sys/dsl_destroy.h>
+#include <sys/dsl_userhold.h>
+#include <sys/dsl_bookmark.h>
+
+/*
+ * The SPA supports block sizes up to 16MB.  However, very large blocks
+ * can have an impact on i/o latency (e.g. tying up a spinning disk for
+ * ~300ms), and also potentially on the memory allocator.  Therefore,
+ * we do not allow the recordsize to be set larger than zfs_max_recordsize
+ * (default 1MB).  Larger blocks can be created by changing this tunable,
+ * and pools with larger blocks can always be imported and used, regardless
+ * of this setting.
+ */
+int zfs_max_recordsize = 1 * 1024 * 1024;
+
+#define	SWITCH64(x, y) \
+	{ \
+		uint64_t __tmp = (x); \
+		(x) = (y); \
+		(y) = __tmp; \
+	}
+
+#define	DS_REF_MAX	(1ULL << 62)
+
+extern inline dsl_dataset_phys_t *dsl_dataset_phys(dsl_dataset_t *ds);
+
+/*
+ * Figure out how much of this delta should be propogated to the dsl_dir
+ * layer.  If there's a refreservation, that space has already been
+ * partially accounted for in our ancestors.
+ */
+static int64_t
+parent_delta(dsl_dataset_t *ds, int64_t delta)
+{
+	dsl_dataset_phys_t *ds_phys;
+	uint64_t old_bytes, new_bytes;
+
+	if (ds->ds_reserved == 0)
+		return (delta);
+
+	ds_phys = dsl_dataset_phys(ds);
+	old_bytes = MAX(ds_phys->ds_unique_bytes, ds->ds_reserved);
+	new_bytes = MAX(ds_phys->ds_unique_bytes + delta, ds->ds_reserved);
+
+	ASSERT3U(ABS((int64_t)(new_bytes - old_bytes)), <=, ABS(delta));
+	return (new_bytes - old_bytes);
+}
+
+void
+dsl_dataset_block_born(dsl_dataset_t *ds, const blkptr_t *bp, dmu_tx_t *tx)
+{
+	int used, compressed, uncompressed;
+	int64_t delta;
+
+	used = bp_get_dsize_sync(tx->tx_pool->dp_spa, bp);
+	compressed = BP_GET_PSIZE(bp);
+	uncompressed = BP_GET_UCSIZE(bp);
+
+	dprintf_bp(bp, "ds=%p", ds);
+
+	ASSERT(dmu_tx_is_syncing(tx));
+	/* It could have been compressed away to nothing */
+	if (BP_IS_HOLE(bp))
+		return;
+	ASSERT(BP_GET_TYPE(bp) != DMU_OT_NONE);
+	ASSERT(DMU_OT_IS_VALID(BP_GET_TYPE(bp)));
+	if (ds == NULL) {
+		dsl_pool_mos_diduse_space(tx->tx_pool,
+		    used, compressed, uncompressed);
+		return;
+	}
+
+	dmu_buf_will_dirty(ds->ds_dbuf, tx);
+	mutex_enter(&ds->ds_lock);
+	delta = parent_delta(ds, used);
+	dsl_dataset_phys(ds)->ds_referenced_bytes += used;
+	dsl_dataset_phys(ds)->ds_compressed_bytes += compressed;
+	dsl_dataset_phys(ds)->ds_uncompressed_bytes += uncompressed;
+	dsl_dataset_phys(ds)->ds_unique_bytes += used;
+	if (BP_GET_LSIZE(bp) > SPA_OLD_MAXBLOCKSIZE)
+		ds->ds_need_large_blocks = B_TRUE;
+	mutex_exit(&ds->ds_lock);
+	dsl_dir_diduse_space(ds->ds_dir, DD_USED_HEAD, delta,
+	    compressed, uncompressed, tx);
+	dsl_dir_transfer_space(ds->ds_dir, used - delta,
+	    DD_USED_REFRSRV, DD_USED_HEAD, tx);
+}
+
+int
+dsl_dataset_block_kill(dsl_dataset_t *ds, const blkptr_t *bp, dmu_tx_t *tx,
+    boolean_t async)
+{
+	int used = bp_get_dsize_sync(tx->tx_pool->dp_spa, bp);
+	int compressed = BP_GET_PSIZE(bp);
+	int uncompressed = BP_GET_UCSIZE(bp);
+
+	if (BP_IS_HOLE(bp))
+		return (0);
+
+	ASSERT(dmu_tx_is_syncing(tx));
+	ASSERT(bp->blk_birth <= tx->tx_txg);
+
+	if (ds == NULL) {
+		dsl_free(tx->tx_pool, tx->tx_txg, bp);
+		dsl_pool_mos_diduse_space(tx->tx_pool,
+		    -used, -compressed, -uncompressed);
+		return (used);
+	}
+	ASSERT3P(tx->tx_pool, ==, ds->ds_dir->dd_pool);
+
+	ASSERT(!ds->ds_is_snapshot);
+	dmu_buf_will_dirty(ds->ds_dbuf, tx);
+
+	if (bp->blk_birth > dsl_dataset_phys(ds)->ds_prev_snap_txg) {
+		int64_t delta;
+
+		dprintf_bp(bp, "freeing ds=%llu", ds->ds_object);
+		dsl_free(tx->tx_pool, tx->tx_txg, bp);
+
+		mutex_enter(&ds->ds_lock);
+		ASSERT(dsl_dataset_phys(ds)->ds_unique_bytes >= used ||
+		    !DS_UNIQUE_IS_ACCURATE(ds));
+		delta = parent_delta(ds, -used);
+		dsl_dataset_phys(ds)->ds_unique_bytes -= used;
+		mutex_exit(&ds->ds_lock);
+		dsl_dir_diduse_space(ds->ds_dir, DD_USED_HEAD,
+		    delta, -compressed, -uncompressed, tx);
+		dsl_dir_transfer_space(ds->ds_dir, -used - delta,
+		    DD_USED_REFRSRV, DD_USED_HEAD, tx);
+	} else {
+		dprintf_bp(bp, "putting on dead list: %s", "");
+		if (async) {
+			/*
+			 * We are here as part of zio's write done callback,
+			 * which means we're a zio interrupt thread.  We can't
+			 * call dsl_deadlist_insert() now because it may block
+			 * waiting for I/O.  Instead, put bp on the deferred
+			 * queue and let dsl_pool_sync() finish the job.
+			 */
+			bplist_append(&ds->ds_pending_deadlist, bp);
+		} else {
+			dsl_deadlist_insert(&ds->ds_deadlist, bp, tx);
+		}
+		ASSERT3U(ds->ds_prev->ds_object, ==,
+		    dsl_dataset_phys(ds)->ds_prev_snap_obj);
+		ASSERT(dsl_dataset_phys(ds->ds_prev)->ds_num_children > 0);
+		/* if (bp->blk_birth > prev prev snap txg) prev unique += bs */
+		if (dsl_dataset_phys(ds->ds_prev)->ds_next_snap_obj ==
+		    ds->ds_object && bp->blk_birth >
+		    dsl_dataset_phys(ds->ds_prev)->ds_prev_snap_txg) {
+			dmu_buf_will_dirty(ds->ds_prev->ds_dbuf, tx);
+			mutex_enter(&ds->ds_prev->ds_lock);
+			dsl_dataset_phys(ds->ds_prev)->ds_unique_bytes += used;
+			mutex_exit(&ds->ds_prev->ds_lock);
+		}
+		if (bp->blk_birth > ds->ds_dir->dd_origin_txg) {
+			dsl_dir_transfer_space(ds->ds_dir, used,
+			    DD_USED_HEAD, DD_USED_SNAP, tx);
+		}
+	}
+	mutex_enter(&ds->ds_lock);
+	ASSERT3U(dsl_dataset_phys(ds)->ds_referenced_bytes, >=, used);
+	dsl_dataset_phys(ds)->ds_referenced_bytes -= used;
+	ASSERT3U(dsl_dataset_phys(ds)->ds_compressed_bytes, >=, compressed);
+	dsl_dataset_phys(ds)->ds_compressed_bytes -= compressed;
+	ASSERT3U(dsl_dataset_phys(ds)->ds_uncompressed_bytes, >=, uncompressed);
+	dsl_dataset_phys(ds)->ds_uncompressed_bytes -= uncompressed;
+	mutex_exit(&ds->ds_lock);
+
+	return (used);
+}
+
+uint64_t
+dsl_dataset_prev_snap_txg(dsl_dataset_t *ds)
+{
+	uint64_t trysnap = 0;
+
+	if (ds == NULL)
+		return (0);
+	/*
+	 * The snapshot creation could fail, but that would cause an
+	 * incorrect FALSE return, which would only result in an
+	 * overestimation of the amount of space that an operation would
+	 * consume, which is OK.
+	 *
+	 * There's also a small window where we could miss a pending
+	 * snapshot, because we could set the sync task in the quiescing
+	 * phase.  So this should only be used as a guess.
+	 */
+	if (ds->ds_trysnap_txg >
+	    spa_last_synced_txg(ds->ds_dir->dd_pool->dp_spa))
+		trysnap = ds->ds_trysnap_txg;
+	return (MAX(dsl_dataset_phys(ds)->ds_prev_snap_txg, trysnap));
+}
+
+boolean_t
+dsl_dataset_block_freeable(dsl_dataset_t *ds, const blkptr_t *bp,
+    uint64_t blk_birth)
+{
+	if (blk_birth <= dsl_dataset_prev_snap_txg(ds) ||
+	    (bp != NULL && BP_IS_HOLE(bp)))
+		return (B_FALSE);
+
+	ddt_prefetch(dsl_dataset_get_spa(ds), bp);
+
+	return (B_TRUE);
+}
+
+static void
+dsl_dataset_evict(void *dbu)
+{
+	dsl_dataset_t *ds = dbu;
+
+	ASSERT(ds->ds_owner == NULL);
+
+	ds->ds_dbuf = NULL;
+
+	unique_remove(ds->ds_fsid_guid);
+
+	if (ds->ds_objset != NULL)
+		dmu_objset_evict(ds->ds_objset);
+
+	if (ds->ds_prev) {
+		dsl_dataset_rele(ds->ds_prev, ds);
+		ds->ds_prev = NULL;
+	}
+
+	bplist_destroy(&ds->ds_pending_deadlist);
+	if (ds->ds_deadlist.dl_os != NULL)
+		dsl_deadlist_close(&ds->ds_deadlist);
+	if (ds->ds_dir)
+		dsl_dir_async_rele(ds->ds_dir, ds);
+
+	ASSERT(!list_link_active(&ds->ds_synced_link));
+
+	mutex_destroy(&ds->ds_lock);
+	mutex_destroy(&ds->ds_opening_lock);
+	mutex_destroy(&ds->ds_sendstream_lock);
+	refcount_destroy(&ds->ds_longholds);
+
+	kmem_free(ds, sizeof (dsl_dataset_t));
+}
+
+int
+dsl_dataset_get_snapname(dsl_dataset_t *ds)
+{
+	dsl_dataset_phys_t *headphys;
+	int err;
+	dmu_buf_t *headdbuf;
+	dsl_pool_t *dp = ds->ds_dir->dd_pool;
+	objset_t *mos = dp->dp_meta_objset;
+
+	if (ds->ds_snapname[0])
+		return (0);
+	if (dsl_dataset_phys(ds)->ds_next_snap_obj == 0)
+		return (0);
+
+	err = dmu_bonus_hold(mos, dsl_dir_phys(ds->ds_dir)->dd_head_dataset_obj,
+	    FTAG, &headdbuf);
+	if (err != 0)
+		return (err);
+	headphys = headdbuf->db_data;
+	err = zap_value_search(dp->dp_meta_objset,
+	    headphys->ds_snapnames_zapobj, ds->ds_object, 0, ds->ds_snapname);
+	if (err != 0 && zfs_recover == B_TRUE) {
+		err = 0;
+		(void) snprintf(ds->ds_snapname, sizeof (ds->ds_snapname),
+		    "SNAPOBJ=%llu-ERR=%d",
+		    (unsigned long long)ds->ds_object, err);
+	}
+	dmu_buf_rele(headdbuf, FTAG);
+	return (err);
+}
+
+int
+dsl_dataset_snap_lookup(dsl_dataset_t *ds, const char *name, uint64_t *value)
+{
+	objset_t *mos = ds->ds_dir->dd_pool->dp_meta_objset;
+	uint64_t snapobj = dsl_dataset_phys(ds)->ds_snapnames_zapobj;
+	matchtype_t mt;
+	int err;
+
+	if (dsl_dataset_phys(ds)->ds_flags & DS_FLAG_CI_DATASET)
+		mt = MT_FIRST;
+	else
+		mt = MT_EXACT;
+
+	err = zap_lookup_norm(mos, snapobj, name, 8, 1,
+	    value, mt, NULL, 0, NULL);
+	if (err == ENOTSUP && mt == MT_FIRST)
+		err = zap_lookup(mos, snapobj, name, 8, 1, value);
+	return (err);
+}
+
+int
+dsl_dataset_snap_remove(dsl_dataset_t *ds, const char *name, dmu_tx_t *tx,
+    boolean_t adj_cnt)
+{
+	objset_t *mos = ds->ds_dir->dd_pool->dp_meta_objset;
+	uint64_t snapobj = dsl_dataset_phys(ds)->ds_snapnames_zapobj;
+	matchtype_t mt;
+	int err;
+
+	dsl_dir_snap_cmtime_update(ds->ds_dir);
+
+	if (dsl_dataset_phys(ds)->ds_flags & DS_FLAG_CI_DATASET)
+		mt = MT_FIRST;
+	else
+		mt = MT_EXACT;
+
+	err = zap_remove_norm(mos, snapobj, name, mt, tx);
+	if (err == ENOTSUP && mt == MT_FIRST)
+		err = zap_remove(mos, snapobj, name, tx);
+
+	if (err == 0 && adj_cnt)
+		dsl_fs_ss_count_adjust(ds->ds_dir, -1,
+		    DD_FIELD_SNAPSHOT_COUNT, tx);
+
+	return (err);
+}
+
+boolean_t
+dsl_dataset_try_add_ref(dsl_pool_t *dp, dsl_dataset_t *ds, void *tag)
+{
+	dmu_buf_t *dbuf = ds->ds_dbuf;
+	boolean_t result = B_FALSE;
+
+	if (dbuf != NULL && dmu_buf_try_add_ref(dbuf, dp->dp_meta_objset,
+	    ds->ds_object, DMU_BONUS_BLKID, tag)) {
+
+		if (ds == dmu_buf_get_user(dbuf))
+			result = B_TRUE;
+		else
+			dmu_buf_rele(dbuf, tag);
+	}
+
+	return (result);
+}
+
+int
+dsl_dataset_hold_obj(dsl_pool_t *dp, uint64_t dsobj, void *tag,
+    dsl_dataset_t **dsp)
+{
+	objset_t *mos = dp->dp_meta_objset;
+	dmu_buf_t *dbuf;
+	dsl_dataset_t *ds;
+	int err;
+	dmu_object_info_t doi;
+
+	ASSERT(dsl_pool_config_held(dp));
+
+	err = dmu_bonus_hold(mos, dsobj, tag, &dbuf);
+	if (err != 0)
+		return (err);
+
+	/* Make sure dsobj has the correct object type. */
+	dmu_object_info_from_db(dbuf, &doi);
+	if (doi.doi_bonus_type != DMU_OT_DSL_DATASET) {
+		dmu_buf_rele(dbuf, tag);
+		return (SET_ERROR(EINVAL));
+	}
+
+	ds = dmu_buf_get_user(dbuf);
+	if (ds == NULL) {
+		dsl_dataset_t *winner = NULL;
+
+		ds = kmem_zalloc(sizeof (dsl_dataset_t), KM_SLEEP);
+		ds->ds_dbuf = dbuf;
+		ds->ds_object = dsobj;
+		ds->ds_is_snapshot = dsl_dataset_phys(ds)->ds_num_children != 0;
+		list_link_init(&ds->ds_synced_link);
+
+		mutex_init(&ds->ds_lock, NULL, MUTEX_DEFAULT, NULL);
+		mutex_init(&ds->ds_opening_lock, NULL, MUTEX_DEFAULT, NULL);
+		mutex_init(&ds->ds_sendstream_lock, NULL, MUTEX_DEFAULT, NULL);
+		refcount_create(&ds->ds_longholds);
+
+		bplist_create(&ds->ds_pending_deadlist);
+		dsl_deadlist_open(&ds->ds_deadlist,
+		    mos, dsl_dataset_phys(ds)->ds_deadlist_obj);
+
+		list_create(&ds->ds_sendstreams, sizeof (dmu_sendarg_t),
+		    offsetof(dmu_sendarg_t, dsa_link));
+
+		if (doi.doi_type == DMU_OTN_ZAP_METADATA) {
+			int zaperr = zap_contains(mos, dsobj,
+			    DS_FIELD_LARGE_BLOCKS);
+			if (zaperr != ENOENT) {
+				VERIFY0(zaperr);
+				ds->ds_large_blocks = B_TRUE;
+			}
+		}
+
+		if (err == 0) {
+			err = dsl_dir_hold_obj(dp,
+			    dsl_dataset_phys(ds)->ds_dir_obj, NULL, ds,
+			    &ds->ds_dir);
+		}
+		if (err != 0) {
+			mutex_destroy(&ds->ds_lock);
+			mutex_destroy(&ds->ds_opening_lock);
+			mutex_destroy(&ds->ds_sendstream_lock);
+			refcount_destroy(&ds->ds_longholds);
+			bplist_destroy(&ds->ds_pending_deadlist);
+			dsl_deadlist_close(&ds->ds_deadlist);
+			kmem_free(ds, sizeof (dsl_dataset_t));
+			dmu_buf_rele(dbuf, tag);
+			return (err);
+		}
+
+		if (!ds->ds_is_snapshot) {
+			ds->ds_snapname[0] = '\0';
+			if (dsl_dataset_phys(ds)->ds_prev_snap_obj != 0) {
+				err = dsl_dataset_hold_obj(dp,
+				    dsl_dataset_phys(ds)->ds_prev_snap_obj,
+				    ds, &ds->ds_prev);
+			}
+			if (doi.doi_type == DMU_OTN_ZAP_METADATA) {
+				int zaperr = zap_lookup(mos, ds->ds_object,
+				    DS_FIELD_BOOKMARK_NAMES,
+				    sizeof (ds->ds_bookmarks), 1,
+				    &ds->ds_bookmarks);
+				if (zaperr != ENOENT)
+					VERIFY0(zaperr);
+			}
+		} else {
+			if (zfs_flags & ZFS_DEBUG_SNAPNAMES)
+				err = dsl_dataset_get_snapname(ds);
+			if (err == 0 &&
+			    dsl_dataset_phys(ds)->ds_userrefs_obj != 0) {
+				err = zap_count(
+				    ds->ds_dir->dd_pool->dp_meta_objset,
+				    dsl_dataset_phys(ds)->ds_userrefs_obj,
+				    &ds->ds_userrefs);
+			}
+		}
+
+		if (err == 0 && !ds->ds_is_snapshot) {
+			err = dsl_prop_get_int_ds(ds,
+			    zfs_prop_to_name(ZFS_PROP_REFRESERVATION),
+			    &ds->ds_reserved);
+			if (err == 0) {
+				err = dsl_prop_get_int_ds(ds,
+				    zfs_prop_to_name(ZFS_PROP_REFQUOTA),
+				    &ds->ds_quota);
+			}
+		} else {
+			ds->ds_reserved = ds->ds_quota = 0;
+		}
+
+		dmu_buf_init_user(&ds->ds_dbu, dsl_dataset_evict, &ds->ds_dbuf);
+		if (err == 0)
+			winner = dmu_buf_set_user_ie(dbuf, &ds->ds_dbu);
+
+		if (err != 0 || winner != NULL) {
+			bplist_destroy(&ds->ds_pending_deadlist);
+			dsl_deadlist_close(&ds->ds_deadlist);
+			if (ds->ds_prev)
+				dsl_dataset_rele(ds->ds_prev, ds);
+			dsl_dir_rele(ds->ds_dir, ds);
+			mutex_destroy(&ds->ds_lock);
+			mutex_destroy(&ds->ds_opening_lock);
+			mutex_destroy(&ds->ds_sendstream_lock);
+			refcount_destroy(&ds->ds_longholds);
+			kmem_free(ds, sizeof (dsl_dataset_t));
+			if (err != 0) {
+				dmu_buf_rele(dbuf, tag);
+				return (err);
+			}
+			ds = winner;
+		} else {
+			ds->ds_fsid_guid =
+			    unique_insert(dsl_dataset_phys(ds)->ds_fsid_guid);
+		}
+	}
+	ASSERT3P(ds->ds_dbuf, ==, dbuf);
+	ASSERT3P(dsl_dataset_phys(ds), ==, dbuf->db_data);
+	ASSERT(dsl_dataset_phys(ds)->ds_prev_snap_obj != 0 ||
+	    spa_version(dp->dp_spa) < SPA_VERSION_ORIGIN ||
+	    dp->dp_origin_snap == NULL || ds == dp->dp_origin_snap);
+	*dsp = ds;
+	return (0);
+}
+
+int
+dsl_dataset_hold(dsl_pool_t *dp, const char *name,
+    void *tag, dsl_dataset_t **dsp)
+{
+	dsl_dir_t *dd;
+	const char *snapname;
+	uint64_t obj;
+	int err = 0;
+
+	err = dsl_dir_hold(dp, name, FTAG, &dd, &snapname);
+	if (err != 0)
+		return (err);
+
+	ASSERT(dsl_pool_config_held(dp));
+	obj = dsl_dir_phys(dd)->dd_head_dataset_obj;
+	if (obj != 0)
+		err = dsl_dataset_hold_obj(dp, obj, tag, dsp);
+	else
+		err = SET_ERROR(ENOENT);
+
+	/* we may be looking for a snapshot */
+	if (err == 0 && snapname != NULL) {
+		dsl_dataset_t *ds;
+
+		if (*snapname++ != '@') {
+			dsl_dataset_rele(*dsp, tag);
+			dsl_dir_rele(dd, FTAG);
+			return (SET_ERROR(ENOENT));
+		}
+
+		dprintf("looking for snapshot '%s'\n", snapname);
+		err = dsl_dataset_snap_lookup(*dsp, snapname, &obj);
+		if (err == 0)
+			err = dsl_dataset_hold_obj(dp, obj, tag, &ds);
+		dsl_dataset_rele(*dsp, tag);
+
+		if (err == 0) {
+			mutex_enter(&ds->ds_lock);
+			if (ds->ds_snapname[0] == 0)
+				(void) strlcpy(ds->ds_snapname, snapname,
+				    sizeof (ds->ds_snapname));
+			mutex_exit(&ds->ds_lock);
+			*dsp = ds;
+		}
+	}
+
+	dsl_dir_rele(dd, FTAG);
+	return (err);
+}
+
+int
+dsl_dataset_own_obj(dsl_pool_t *dp, uint64_t dsobj,
+    void *tag, dsl_dataset_t **dsp)
+{
+	int err = dsl_dataset_hold_obj(dp, dsobj, tag, dsp);
+	if (err != 0)
+		return (err);
+	if (!dsl_dataset_tryown(*dsp, tag)) {
+		dsl_dataset_rele(*dsp, tag);
+		*dsp = NULL;
+		return (SET_ERROR(EBUSY));
+	}
+	return (0);
+}
+
+int
+dsl_dataset_own(dsl_pool_t *dp, const char *name,
+    void *tag, dsl_dataset_t **dsp)
+{
+	int err = dsl_dataset_hold(dp, name, tag, dsp);
+	if (err != 0)
+		return (err);
+	if (!dsl_dataset_tryown(*dsp, tag)) {
+		dsl_dataset_rele(*dsp, tag);
+		return (SET_ERROR(EBUSY));
+	}
+	return (0);
+}
+
+/*
+ * See the comment above dsl_pool_hold() for details.  In summary, a long
+ * hold is used to prevent destruction of a dataset while the pool hold
+ * is dropped, allowing other concurrent operations (e.g. spa_sync()).
+ *
+ * The dataset and pool must be held when this function is called.  After it
+ * is called, the pool hold may be released while the dataset is still held
+ * and accessed.
+ */
+void
+dsl_dataset_long_hold(dsl_dataset_t *ds, void *tag)
+{
+	ASSERT(dsl_pool_config_held(ds->ds_dir->dd_pool));
+	(void) refcount_add(&ds->ds_longholds, tag);
+}
+
+void
+dsl_dataset_long_rele(dsl_dataset_t *ds, void *tag)
+{
+	(void) refcount_remove(&ds->ds_longholds, tag);
+}
+
+/* Return B_TRUE if there are any long holds on this dataset. */
+boolean_t
+dsl_dataset_long_held(dsl_dataset_t *ds)
+{
+	return (!refcount_is_zero(&ds->ds_longholds));
+}
+
+void
+dsl_dataset_name(dsl_dataset_t *ds, char *name)
+{
+	if (ds == NULL) {
+		(void) strcpy(name, "mos");
+	} else {
+		dsl_dir_name(ds->ds_dir, name);
+		VERIFY0(dsl_dataset_get_snapname(ds));
+		if (ds->ds_snapname[0]) {
+			(void) strcat(name, "@");
+			/*
+			 * We use a "recursive" mutex so that we
+			 * can call dprintf_ds() with ds_lock held.
+			 */
+			if (!MUTEX_HELD(&ds->ds_lock)) {
+				mutex_enter(&ds->ds_lock);
+				(void) strcat(name, ds->ds_snapname);
+				mutex_exit(&ds->ds_lock);
+			} else {
+				(void) strcat(name, ds->ds_snapname);
+			}
+		}
+	}
+}
+
+void
+dsl_dataset_rele(dsl_dataset_t *ds, void *tag)
+{
+	dmu_buf_rele(ds->ds_dbuf, tag);
+}
+
+void
+dsl_dataset_disown(dsl_dataset_t *ds, void *tag)
+{
+	ASSERT3P(ds->ds_owner, ==, tag);
+	ASSERT(ds->ds_dbuf != NULL);
+
+	mutex_enter(&ds->ds_lock);
+	ds->ds_owner = NULL;
+	mutex_exit(&ds->ds_lock);
+	dsl_dataset_long_rele(ds, tag);
+	dsl_dataset_rele(ds, tag);
+}
+
+boolean_t
+dsl_dataset_tryown(dsl_dataset_t *ds, void *tag)
+{
+	boolean_t gotit = FALSE;
+
+	mutex_enter(&ds->ds_lock);
+	if (ds->ds_owner == NULL && !DS_IS_INCONSISTENT(ds)) {
+		ds->ds_owner = tag;
+		dsl_dataset_long_hold(ds, tag);
+		gotit = TRUE;
+	}
+	mutex_exit(&ds->ds_lock);
+	return (gotit);
+}
+
+uint64_t
+dsl_dataset_create_sync_dd(dsl_dir_t *dd, dsl_dataset_t *origin,
+    uint64_t flags, dmu_tx_t *tx)
+{
+	dsl_pool_t *dp = dd->dd_pool;
+	dmu_buf_t *dbuf;
+	dsl_dataset_phys_t *dsphys;
+	uint64_t dsobj;
+	objset_t *mos = dp->dp_meta_objset;
+
+	if (origin == NULL)
+		origin = dp->dp_origin_snap;
+
+	ASSERT(origin == NULL || origin->ds_dir->dd_pool == dp);
+	ASSERT(origin == NULL || dsl_dataset_phys(origin)->ds_num_children > 0);
+	ASSERT(dmu_tx_is_syncing(tx));
+	ASSERT(dsl_dir_phys(dd)->dd_head_dataset_obj == 0);
+
+	dsobj = dmu_object_alloc(mos, DMU_OT_DSL_DATASET, 0,
+	    DMU_OT_DSL_DATASET, sizeof (dsl_dataset_phys_t), tx);
+	VERIFY0(dmu_bonus_hold(mos, dsobj, FTAG, &dbuf));
+	dmu_buf_will_dirty(dbuf, tx);
+	dsphys = dbuf->db_data;
+	bzero(dsphys, sizeof (dsl_dataset_phys_t));
+	dsphys->ds_dir_obj = dd->dd_object;
+	dsphys->ds_flags = flags;
+	dsphys->ds_fsid_guid = unique_create();
+	(void) random_get_pseudo_bytes((void*)&dsphys->ds_guid,
+	    sizeof (dsphys->ds_guid));
+	dsphys->ds_snapnames_zapobj =
+	    zap_create_norm(mos, U8_TEXTPREP_TOUPPER, DMU_OT_DSL_DS_SNAP_MAP,
+	    DMU_OT_NONE, 0, tx);
+	dsphys->ds_creation_time = gethrestime_sec();
+	dsphys->ds_creation_txg = tx->tx_txg == TXG_INITIAL ? 1 : tx->tx_txg;
+
+	if (origin == NULL) {
+		dsphys->ds_deadlist_obj = dsl_deadlist_alloc(mos, tx);
+	} else {
+		dsl_dataset_t *ohds; /* head of the origin snapshot */
+
+		dsphys->ds_prev_snap_obj = origin->ds_object;
+		dsphys->ds_prev_snap_txg =
+		    dsl_dataset_phys(origin)->ds_creation_txg;
+		dsphys->ds_referenced_bytes =
+		    dsl_dataset_phys(origin)->ds_referenced_bytes;
+		dsphys->ds_compressed_bytes =
+		    dsl_dataset_phys(origin)->ds_compressed_bytes;
+		dsphys->ds_uncompressed_bytes =
+		    dsl_dataset_phys(origin)->ds_uncompressed_bytes;
+		dsphys->ds_bp = dsl_dataset_phys(origin)->ds_bp;
+
+		/*
+		 * Inherit flags that describe the dataset's contents
+		 * (INCONSISTENT) or properties (Case Insensitive).
+		 */
+		dsphys->ds_flags |= dsl_dataset_phys(origin)->ds_flags &
+		    (DS_FLAG_INCONSISTENT | DS_FLAG_CI_DATASET);
+
+		if (origin->ds_large_blocks)
+			dsl_dataset_activate_large_blocks_sync_impl(dsobj, tx);
+
+		dmu_buf_will_dirty(origin->ds_dbuf, tx);
+		dsl_dataset_phys(origin)->ds_num_children++;
+
+		VERIFY0(dsl_dataset_hold_obj(dp,
+		    dsl_dir_phys(origin->ds_dir)->dd_head_dataset_obj,
+		    FTAG, &ohds));
+		dsphys->ds_deadlist_obj = dsl_deadlist_clone(&ohds->ds_deadlist,
+		    dsphys->ds_prev_snap_txg, dsphys->ds_prev_snap_obj, tx);
+		dsl_dataset_rele(ohds, FTAG);
+
+		if (spa_version(dp->dp_spa) >= SPA_VERSION_NEXT_CLONES) {
+			if (dsl_dataset_phys(origin)->ds_next_clones_obj == 0) {
+				dsl_dataset_phys(origin)->ds_next_clones_obj =
+				    zap_create(mos,
+				    DMU_OT_NEXT_CLONES, DMU_OT_NONE, 0, tx);
+			}
+			VERIFY0(zap_add_int(mos,
+			    dsl_dataset_phys(origin)->ds_next_clones_obj,
+			    dsobj, tx));
+		}
+
+		dmu_buf_will_dirty(dd->dd_dbuf, tx);
+		dsl_dir_phys(dd)->dd_origin_obj = origin->ds_object;
+		if (spa_version(dp->dp_spa) >= SPA_VERSION_DIR_CLONES) {
+			if (dsl_dir_phys(origin->ds_dir)->dd_clones == 0) {
+				dmu_buf_will_dirty(origin->ds_dir->dd_dbuf, tx);
+				dsl_dir_phys(origin->ds_dir)->dd_clones =
+				    zap_create(mos,
+				    DMU_OT_DSL_CLONES, DMU_OT_NONE, 0, tx);
+			}
+			VERIFY0(zap_add_int(mos,
+			    dsl_dir_phys(origin->ds_dir)->dd_clones,
+			    dsobj, tx));
+		}
+	}
+
+	if (spa_version(dp->dp_spa) >= SPA_VERSION_UNIQUE_ACCURATE)
+		dsphys->ds_flags |= DS_FLAG_UNIQUE_ACCURATE;
+
+	dmu_buf_rele(dbuf, FTAG);
+
+	dmu_buf_will_dirty(dd->dd_dbuf, tx);
+	dsl_dir_phys(dd)->dd_head_dataset_obj = dsobj;
+
+	return (dsobj);
+}
+
+static void
+dsl_dataset_zero_zil(dsl_dataset_t *ds, dmu_tx_t *tx)
+{
+	objset_t *os;
+
+	VERIFY0(dmu_objset_from_ds(ds, &os));
+	bzero(&os->os_zil_header, sizeof (os->os_zil_header));
+	dsl_dataset_dirty(ds, tx);
+}
+
+uint64_t
+dsl_dataset_create_sync(dsl_dir_t *pdd, const char *lastname,
+    dsl_dataset_t *origin, uint64_t flags, cred_t *cr, dmu_tx_t *tx)
+{
+	dsl_pool_t *dp = pdd->dd_pool;
+	uint64_t dsobj, ddobj;
+	dsl_dir_t *dd;
+
+	ASSERT(dmu_tx_is_syncing(tx));
+	ASSERT(lastname[0] != '@');
+
+	ddobj = dsl_dir_create_sync(dp, pdd, lastname, tx);
+	VERIFY0(dsl_dir_hold_obj(dp, ddobj, lastname, FTAG, &dd));
+
+	dsobj = dsl_dataset_create_sync_dd(dd, origin,
+	    flags & ~DS_CREATE_FLAG_NODIRTY, tx);
+
+	dsl_deleg_set_create_perms(dd, tx, cr);
+
+	/*
+	 * Since we're creating a new node we know it's a leaf, so we can
+	 * initialize the counts if the limit feature is active.
+	 */
+	if (spa_feature_is_active(dp->dp_spa, SPA_FEATURE_FS_SS_LIMIT)) {
+		uint64_t cnt = 0;
+		objset_t *os = dd->dd_pool->dp_meta_objset;
+
+		dsl_dir_zapify(dd, tx);
+		VERIFY0(zap_add(os, dd->dd_object, DD_FIELD_FILESYSTEM_COUNT,
+		    sizeof (cnt), 1, &cnt, tx));
+		VERIFY0(zap_add(os, dd->dd_object, DD_FIELD_SNAPSHOT_COUNT,
+		    sizeof (cnt), 1, &cnt, tx));
+	}
+
+	dsl_dir_rele(dd, FTAG);
+
+	/*
+	 * If we are creating a clone, make sure we zero out any stale
+	 * data from the origin snapshots zil header.
+	 */
+	if (origin != NULL && !(flags & DS_CREATE_FLAG_NODIRTY)) {
+		dsl_dataset_t *ds;
+
+		VERIFY0(dsl_dataset_hold_obj(dp, dsobj, FTAG, &ds));
+		dsl_dataset_zero_zil(ds, tx);
+		dsl_dataset_rele(ds, FTAG);
+	}
+
+	return (dsobj);
+}
+
+/*
+ * The unique space in the head dataset can be calculated by subtracting
+ * the space used in the most recent snapshot, that is still being used
+ * in this file system, from the space currently in use.  To figure out
+ * the space in the most recent snapshot still in use, we need to take
+ * the total space used in the snapshot and subtract out the space that
+ * has been freed up since the snapshot was taken.
+ */
+void
+dsl_dataset_recalc_head_uniq(dsl_dataset_t *ds)
+{
+	uint64_t mrs_used;
+	uint64_t dlused, dlcomp, dluncomp;
+
+	ASSERT(!ds->ds_is_snapshot);
+
+	if (dsl_dataset_phys(ds)->ds_prev_snap_obj != 0)
+		mrs_used = dsl_dataset_phys(ds->ds_prev)->ds_referenced_bytes;
+	else
+		mrs_used = 0;
+
+	dsl_deadlist_space(&ds->ds_deadlist, &dlused, &dlcomp, &dluncomp);
+
+	ASSERT3U(dlused, <=, mrs_used);
+	dsl_dataset_phys(ds)->ds_unique_bytes =
+	    dsl_dataset_phys(ds)->ds_referenced_bytes - (mrs_used - dlused);
+
+	if (spa_version(ds->ds_dir->dd_pool->dp_spa) >=
+	    SPA_VERSION_UNIQUE_ACCURATE)
+		dsl_dataset_phys(ds)->ds_flags |= DS_FLAG_UNIQUE_ACCURATE;
+}
+
+void
+dsl_dataset_remove_from_next_clones(dsl_dataset_t *ds, uint64_t obj,
+    dmu_tx_t *tx)
+{
+	objset_t *mos = ds->ds_dir->dd_pool->dp_meta_objset;
+	int err;
+	ASSERTV(uint64_t count);
+
+	ASSERT(dsl_dataset_phys(ds)->ds_num_children >= 2);
+	err = zap_remove_int(mos, dsl_dataset_phys(ds)->ds_next_clones_obj,
+	    obj, tx);
+	/*
+	 * The err should not be ENOENT, but a bug in a previous version
+	 * of the code could cause upgrade_clones_cb() to not set
+	 * ds_next_snap_obj when it should, leading to a missing entry.
+	 * If we knew that the pool was created after
+	 * SPA_VERSION_NEXT_CLONES, we could assert that it isn't
+	 * ENOENT.  However, at least we can check that we don't have
+	 * too many entries in the next_clones_obj even after failing to
+	 * remove this one.
+	 */
+	if (err != ENOENT)
+		VERIFY0(err);
+	ASSERT0(zap_count(mos, dsl_dataset_phys(ds)->ds_next_clones_obj,
+	    &count));
+	ASSERT3U(count, <=, dsl_dataset_phys(ds)->ds_num_children - 2);
+}
+
+
+blkptr_t *
+dsl_dataset_get_blkptr(dsl_dataset_t *ds)
+{
+	return (&dsl_dataset_phys(ds)->ds_bp);
+}
+
+void
+dsl_dataset_set_blkptr(dsl_dataset_t *ds, blkptr_t *bp, dmu_tx_t *tx)
+{
+	ASSERT(dmu_tx_is_syncing(tx));
+	/* If it's the meta-objset, set dp_meta_rootbp */
+	if (ds == NULL) {
+		tx->tx_pool->dp_meta_rootbp = *bp;
+	} else {
+		dmu_buf_will_dirty(ds->ds_dbuf, tx);
+		dsl_dataset_phys(ds)->ds_bp = *bp;
+	}
+}
+
+spa_t *
+dsl_dataset_get_spa(dsl_dataset_t *ds)
+{
+	return (ds->ds_dir->dd_pool->dp_spa);
+}
+
+void
+dsl_dataset_dirty(dsl_dataset_t *ds, dmu_tx_t *tx)
+{
+	dsl_pool_t *dp;
+
+	if (ds == NULL) /* this is the meta-objset */
+		return;
+
+	ASSERT(ds->ds_objset != NULL);
+
+	if (dsl_dataset_phys(ds)->ds_next_snap_obj != 0)
+		panic("dirtying snapshot!");
+
+	dp = ds->ds_dir->dd_pool;
+
+	if (txg_list_add(&dp->dp_dirty_datasets, ds, tx->tx_txg)) {
+		/* up the hold count until we can be written out */
+		dmu_buf_add_ref(ds->ds_dbuf, ds);
+	}
+}
+
+boolean_t
+dsl_dataset_is_dirty(dsl_dataset_t *ds)
+{
+	int t;
+
+	for (t = 0; t < TXG_SIZE; t++) {
+		if (txg_list_member(&ds->ds_dir->dd_pool->dp_dirty_datasets,
+		    ds, t))
+			return (B_TRUE);
+	}
+	return (B_FALSE);
+}
+
+static int
+dsl_dataset_snapshot_reserve_space(dsl_dataset_t *ds, dmu_tx_t *tx)
+{
+	uint64_t asize;
+
+	if (!dmu_tx_is_syncing(tx))
+		return (0);
+
+	/*
+	 * If there's an fs-only reservation, any blocks that might become
+	 * owned by the snapshot dataset must be accommodated by space
+	 * outside of the reservation.
+	 */
+	ASSERT(ds->ds_reserved == 0 || DS_UNIQUE_IS_ACCURATE(ds));
+	asize = MIN(dsl_dataset_phys(ds)->ds_unique_bytes, ds->ds_reserved);
+	if (asize > dsl_dir_space_available(ds->ds_dir, NULL, 0, TRUE))
+		return (SET_ERROR(ENOSPC));
+
+	/*
+	 * Propagate any reserved space for this snapshot to other
+	 * snapshot checks in this sync group.
+	 */
+	if (asize > 0)
+		dsl_dir_willuse_space(ds->ds_dir, asize, tx);
+
+	return (0);
+}
+
+typedef struct dsl_dataset_snapshot_arg {
+	nvlist_t *ddsa_snaps;
+	nvlist_t *ddsa_props;
+	nvlist_t *ddsa_errors;
+	cred_t *ddsa_cr;
+} dsl_dataset_snapshot_arg_t;
+
+int
+dsl_dataset_snapshot_check_impl(dsl_dataset_t *ds, const char *snapname,
+    dmu_tx_t *tx, boolean_t recv, uint64_t cnt, cred_t *cr)
+{
+	int error;
+	uint64_t value;
+
+	ds->ds_trysnap_txg = tx->tx_txg;
+
+	if (!dmu_tx_is_syncing(tx))
+		return (0);
+
+	/*
+	 * We don't allow multiple snapshots of the same txg.  If there
+	 * is already one, try again.
+	 */
+	if (dsl_dataset_phys(ds)->ds_prev_snap_txg >= tx->tx_txg)
+		return (SET_ERROR(EAGAIN));
+
+	/*
+	 * Check for conflicting snapshot name.
+	 */
+	error = dsl_dataset_snap_lookup(ds, snapname, &value);
+	if (error == 0)
+		return (SET_ERROR(EEXIST));
+	if (error != ENOENT)
+		return (error);
+
+	/*
+	 * We don't allow taking snapshots of inconsistent datasets, such as
+	 * those into which we are currently receiving.  However, if we are
+	 * creating this snapshot as part of a receive, this check will be
+	 * executed atomically with respect to the completion of the receive
+	 * itself but prior to the clearing of DS_FLAG_INCONSISTENT; in this
+	 * case we ignore this, knowing it will be fixed up for us shortly in
+	 * dmu_recv_end_sync().
+	 */
+	if (!recv && DS_IS_INCONSISTENT(ds))
+		return (SET_ERROR(EBUSY));
+
+	/*
+	 * Skip the check for temporary snapshots or if we have already checked
+	 * the counts in dsl_dataset_snapshot_check. This means we really only
+	 * check the count here when we're receiving a stream.
+	 */
+	if (cnt != 0 && cr != NULL) {
+		error = dsl_fs_ss_limit_check(ds->ds_dir, cnt,
+		    ZFS_PROP_SNAPSHOT_LIMIT, NULL, cr);
+		if (error != 0)
+			return (error);
+	}
+
+	error = dsl_dataset_snapshot_reserve_space(ds, tx);
+	if (error != 0)
+		return (error);
+
+	return (0);
+}
+
+static int
+dsl_dataset_snapshot_check(void *arg, dmu_tx_t *tx)
+{
+	dsl_dataset_snapshot_arg_t *ddsa = arg;
+	dsl_pool_t *dp = dmu_tx_pool(tx);
+	nvpair_t *pair;
+	int rv = 0;
+
+	/*
+	 * Pre-compute how many total new snapshots will be created for each
+	 * level in the tree and below. This is needed for validating the
+	 * snapshot limit when either taking a recursive snapshot or when
+	 * taking multiple snapshots.
+	 *
+	 * The problem is that the counts are not actually adjusted when
+	 * we are checking, only when we finally sync. For a single snapshot,
+	 * this is easy, the count will increase by 1 at each node up the tree,
+	 * but its more complicated for the recursive/multiple snapshot case.
+	 *
+	 * The dsl_fs_ss_limit_check function does recursively check the count
+	 * at each level up the tree but since it is validating each snapshot
+	 * independently we need to be sure that we are validating the complete
+	 * count for the entire set of snapshots. We do this by rolling up the
+	 * counts for each component of the name into an nvlist and then
+	 * checking each of those cases with the aggregated count.
+	 *
+	 * This approach properly handles not only the recursive snapshot
+	 * case (where we get all of those on the ddsa_snaps list) but also
+	 * the sibling case (e.g. snapshot a/b and a/c so that we will also
+	 * validate the limit on 'a' using a count of 2).
+	 *
+	 * We validate the snapshot names in the third loop and only report
+	 * name errors once.
+	 */
+	if (dmu_tx_is_syncing(tx)) {
+		char *nm;
+		nvlist_t *cnt_track = NULL;
+		cnt_track = fnvlist_alloc();
+
+		nm = kmem_alloc(MAXPATHLEN, KM_SLEEP);
+
+		/* Rollup aggregated counts into the cnt_track list */
+		for (pair = nvlist_next_nvpair(ddsa->ddsa_snaps, NULL);
+		    pair != NULL;
+		    pair = nvlist_next_nvpair(ddsa->ddsa_snaps, pair)) {
+			char *pdelim;
+			uint64_t val;
+
+			(void) strlcpy(nm, nvpair_name(pair), MAXPATHLEN);
+			pdelim = strchr(nm, '@');
+			if (pdelim == NULL)
+				continue;
+			*pdelim = '\0';
+
+			do {
+				if (nvlist_lookup_uint64(cnt_track, nm,
+				    &val) == 0) {
+					/* update existing entry */
+					fnvlist_add_uint64(cnt_track, nm,
+					    val + 1);
+				} else {
+					/* add to list */
+					fnvlist_add_uint64(cnt_track, nm, 1);
+				}
+
+				pdelim = strrchr(nm, '/');
+				if (pdelim != NULL)
+					*pdelim = '\0';
+			} while (pdelim != NULL);
+		}
+
+		kmem_free(nm, MAXPATHLEN);
+
+		/* Check aggregated counts at each level */
+		for (pair = nvlist_next_nvpair(cnt_track, NULL);
+		    pair != NULL; pair = nvlist_next_nvpair(cnt_track, pair)) {
+			int error = 0;
+			char *name;
+			uint64_t cnt = 0;
+			dsl_dataset_t *ds;
+
+			name = nvpair_name(pair);
+			cnt = fnvpair_value_uint64(pair);
+			ASSERT(cnt > 0);
+
+			error = dsl_dataset_hold(dp, name, FTAG, &ds);
+			if (error == 0) {
+				error = dsl_fs_ss_limit_check(ds->ds_dir, cnt,
+				    ZFS_PROP_SNAPSHOT_LIMIT, NULL,
+				    ddsa->ddsa_cr);
+				dsl_dataset_rele(ds, FTAG);
+			}
+
+			if (error != 0) {
+				if (ddsa->ddsa_errors != NULL)
+					fnvlist_add_int32(ddsa->ddsa_errors,
+					    name, error);
+				rv = error;
+				/* only report one error for this check */
+				break;
+			}
+		}
+		nvlist_free(cnt_track);
+	}
+
+	for (pair = nvlist_next_nvpair(ddsa->ddsa_snaps, NULL);
+	    pair != NULL; pair = nvlist_next_nvpair(ddsa->ddsa_snaps, pair)) {
+		int error = 0;
+		dsl_dataset_t *ds;
+		char *name, *atp;
+		char dsname[MAXNAMELEN];
+
+		name = nvpair_name(pair);
+		if (strlen(name) >= MAXNAMELEN)
+			error = SET_ERROR(ENAMETOOLONG);
+		if (error == 0) {
+			atp = strchr(name, '@');
+			if (atp == NULL)
+				error = SET_ERROR(EINVAL);
+			if (error == 0)
+				(void) strlcpy(dsname, name, atp - name + 1);
+		}
+		if (error == 0)
+			error = dsl_dataset_hold(dp, dsname, FTAG, &ds);
+		if (error == 0) {
+			/* passing 0/NULL skips dsl_fs_ss_limit_check */
+			error = dsl_dataset_snapshot_check_impl(ds,
+			    atp + 1, tx, B_FALSE, 0, NULL);
+			dsl_dataset_rele(ds, FTAG);
+		}
+
+		if (error != 0) {
+			if (ddsa->ddsa_errors != NULL) {
+				fnvlist_add_int32(ddsa->ddsa_errors,
+				    name, error);
+			}
+			rv = error;
+		}
+	}
+
+	return (rv);
+}
+
+void
+dsl_dataset_snapshot_sync_impl(dsl_dataset_t *ds, const char *snapname,
+    dmu_tx_t *tx)
+{
+	dsl_pool_t *dp = ds->ds_dir->dd_pool;
+	dmu_buf_t *dbuf;
+	dsl_dataset_phys_t *dsphys;
+	uint64_t dsobj, crtxg;
+	objset_t *mos = dp->dp_meta_objset;
+	ASSERTV(static zil_header_t zero_zil);
+	ASSERTV(objset_t *os);
+
+	ASSERT(RRW_WRITE_HELD(&dp->dp_config_rwlock));
+
+	/*
+	 * If we are on an old pool, the zil must not be active, in which
+	 * case it will be zeroed.  Usually zil_suspend() accomplishes this.
+	 */
+	ASSERT(spa_version(dmu_tx_pool(tx)->dp_spa) >= SPA_VERSION_FAST_SNAP ||
+	    dmu_objset_from_ds(ds, &os) != 0 ||
+	    bcmp(&os->os_phys->os_zil_header, &zero_zil,
+	    sizeof (zero_zil)) == 0);
+
+	dsl_fs_ss_count_adjust(ds->ds_dir, 1, DD_FIELD_SNAPSHOT_COUNT, tx);
+
+	/*
+	 * The origin's ds_creation_txg has to be < TXG_INITIAL
+	 */
+	if (strcmp(snapname, ORIGIN_DIR_NAME) == 0)
+		crtxg = 1;
+	else
+		crtxg = tx->tx_txg;
+
+	dsobj = dmu_object_alloc(mos, DMU_OT_DSL_DATASET, 0,
+	    DMU_OT_DSL_DATASET, sizeof (dsl_dataset_phys_t), tx);
+	VERIFY0(dmu_bonus_hold(mos, dsobj, FTAG, &dbuf));
+	dmu_buf_will_dirty(dbuf, tx);
+	dsphys = dbuf->db_data;
+	bzero(dsphys, sizeof (dsl_dataset_phys_t));
+	dsphys->ds_dir_obj = ds->ds_dir->dd_object;
+	dsphys->ds_fsid_guid = unique_create();
+	(void) random_get_pseudo_bytes((void*)&dsphys->ds_guid,
+	    sizeof (dsphys->ds_guid));
+	dsphys->ds_prev_snap_obj = dsl_dataset_phys(ds)->ds_prev_snap_obj;
+	dsphys->ds_prev_snap_txg = dsl_dataset_phys(ds)->ds_prev_snap_txg;
+	dsphys->ds_next_snap_obj = ds->ds_object;
+	dsphys->ds_num_children = 1;
+	dsphys->ds_creation_time = gethrestime_sec();
+	dsphys->ds_creation_txg = crtxg;
+	dsphys->ds_deadlist_obj = dsl_dataset_phys(ds)->ds_deadlist_obj;
+	dsphys->ds_referenced_bytes = dsl_dataset_phys(ds)->ds_referenced_bytes;
+	dsphys->ds_compressed_bytes = dsl_dataset_phys(ds)->ds_compressed_bytes;
+	dsphys->ds_uncompressed_bytes =
+	    dsl_dataset_phys(ds)->ds_uncompressed_bytes;
+	dsphys->ds_flags = dsl_dataset_phys(ds)->ds_flags;
+	dsphys->ds_bp = dsl_dataset_phys(ds)->ds_bp;
+	dmu_buf_rele(dbuf, FTAG);
+
+	if (ds->ds_large_blocks)
+		dsl_dataset_activate_large_blocks_sync_impl(dsobj, tx);
+
+	ASSERT3U(ds->ds_prev != 0, ==,
+	    dsl_dataset_phys(ds)->ds_prev_snap_obj != 0);
+	if (ds->ds_prev) {
+		uint64_t next_clones_obj =
+		    dsl_dataset_phys(ds->ds_prev)->ds_next_clones_obj;
+		ASSERT(dsl_dataset_phys(ds->ds_prev)->ds_next_snap_obj ==
+		    ds->ds_object ||
+		    dsl_dataset_phys(ds->ds_prev)->ds_num_children > 1);
+		if (dsl_dataset_phys(ds->ds_prev)->ds_next_snap_obj ==
+		    ds->ds_object) {
+			dmu_buf_will_dirty(ds->ds_prev->ds_dbuf, tx);
+			ASSERT3U(dsl_dataset_phys(ds)->ds_prev_snap_txg, ==,
+			    dsl_dataset_phys(ds->ds_prev)->ds_creation_txg);
+			dsl_dataset_phys(ds->ds_prev)->ds_next_snap_obj = dsobj;
+		} else if (next_clones_obj != 0) {
+			dsl_dataset_remove_from_next_clones(ds->ds_prev,
+			    dsphys->ds_next_snap_obj, tx);
+			VERIFY0(zap_add_int(mos,
+			    next_clones_obj, dsobj, tx));
+		}
+	}
+
+	/*
+	 * If we have a reference-reservation on this dataset, we will
+	 * need to increase the amount of refreservation being charged
+	 * since our unique space is going to zero.
+	 */
+	if (ds->ds_reserved) {
+		int64_t delta;
+		ASSERT(DS_UNIQUE_IS_ACCURATE(ds));
+		delta = MIN(dsl_dataset_phys(ds)->ds_unique_bytes,
+		    ds->ds_reserved);
+		dsl_dir_diduse_space(ds->ds_dir, DD_USED_REFRSRV,
+		    delta, 0, 0, tx);
+	}
+
+	dmu_buf_will_dirty(ds->ds_dbuf, tx);
+	dsl_dataset_phys(ds)->ds_deadlist_obj =
+	    dsl_deadlist_clone(&ds->ds_deadlist, UINT64_MAX,
+	    dsl_dataset_phys(ds)->ds_prev_snap_obj, tx);
+	dsl_deadlist_close(&ds->ds_deadlist);
+	dsl_deadlist_open(&ds->ds_deadlist, mos,
+	    dsl_dataset_phys(ds)->ds_deadlist_obj);
+	dsl_deadlist_add_key(&ds->ds_deadlist,
+	    dsl_dataset_phys(ds)->ds_prev_snap_txg, tx);
+
+	ASSERT3U(dsl_dataset_phys(ds)->ds_prev_snap_txg, <, tx->tx_txg);
+	dsl_dataset_phys(ds)->ds_prev_snap_obj = dsobj;
+	dsl_dataset_phys(ds)->ds_prev_snap_txg = crtxg;
+	dsl_dataset_phys(ds)->ds_unique_bytes = 0;
+	if (spa_version(dp->dp_spa) >= SPA_VERSION_UNIQUE_ACCURATE)
+		dsl_dataset_phys(ds)->ds_flags |= DS_FLAG_UNIQUE_ACCURATE;
+
+	VERIFY0(zap_add(mos, dsl_dataset_phys(ds)->ds_snapnames_zapobj,
+	    snapname, 8, 1, &dsobj, tx));
+
+	if (ds->ds_prev)
+		dsl_dataset_rele(ds->ds_prev, ds);
+	VERIFY0(dsl_dataset_hold_obj(dp,
+	    dsl_dataset_phys(ds)->ds_prev_snap_obj, ds, &ds->ds_prev));
+
+	dsl_scan_ds_snapshotted(ds, tx);
+
+	dsl_dir_snap_cmtime_update(ds->ds_dir);
+
+	spa_history_log_internal_ds(ds->ds_prev, "snapshot", tx, "");
+}
+
+static void
+dsl_dataset_snapshot_sync(void *arg, dmu_tx_t *tx)
+{
+	dsl_dataset_snapshot_arg_t *ddsa = arg;
+	dsl_pool_t *dp = dmu_tx_pool(tx);
+	nvpair_t *pair;
+
+	for (pair = nvlist_next_nvpair(ddsa->ddsa_snaps, NULL);
+	    pair != NULL; pair = nvlist_next_nvpair(ddsa->ddsa_snaps, pair)) {
+		dsl_dataset_t *ds;
+		char *name, *atp;
+		char dsname[MAXNAMELEN];
+
+		name = nvpair_name(pair);
+		atp = strchr(name, '@');
+		(void) strlcpy(dsname, name, atp - name + 1);
+		VERIFY0(dsl_dataset_hold(dp, dsname, FTAG, &ds));
+
+		dsl_dataset_snapshot_sync_impl(ds, atp + 1, tx);
+		if (ddsa->ddsa_props != NULL) {
+			dsl_props_set_sync_impl(ds->ds_prev,
+			    ZPROP_SRC_LOCAL, ddsa->ddsa_props, tx);
+		}
+		zvol_create_minors(dp->dp_spa, nvpair_name(pair), B_TRUE);
+		dsl_dataset_rele(ds, FTAG);
+	}
+}
+
+/*
+ * The snapshots must all be in the same pool.
+ * All-or-nothing: if there are any failures, nothing will be modified.
+ */
+int
+dsl_dataset_snapshot(nvlist_t *snaps, nvlist_t *props, nvlist_t *errors)
+{
+	dsl_dataset_snapshot_arg_t ddsa;
+	nvpair_t *pair;
+	boolean_t needsuspend;
+	int error;
+	spa_t *spa;
+	char *firstname;
+	nvlist_t *suspended = NULL;
+
+	pair = nvlist_next_nvpair(snaps, NULL);
+	if (pair == NULL)
+		return (0);
+	firstname = nvpair_name(pair);
+
+	error = spa_open(firstname, &spa, FTAG);
+	if (error != 0)
+		return (error);
+	needsuspend = (spa_version(spa) < SPA_VERSION_FAST_SNAP);
+	spa_close(spa, FTAG);
+
+	if (needsuspend) {
+		suspended = fnvlist_alloc();
+		for (pair = nvlist_next_nvpair(snaps, NULL); pair != NULL;
+		    pair = nvlist_next_nvpair(snaps, pair)) {
+			char fsname[MAXNAMELEN];
+			char *snapname = nvpair_name(pair);
+			char *atp;
+			void *cookie;
+
+			atp = strchr(snapname, '@');
+			if (atp == NULL) {
+				error = SET_ERROR(EINVAL);
+				break;
+			}
+			(void) strlcpy(fsname, snapname, atp - snapname + 1);
+
+			error = zil_suspend(fsname, &cookie);
+			if (error != 0)
+				break;
+			fnvlist_add_uint64(suspended, fsname,
+			    (uintptr_t)cookie);
+		}
+	}
+
+	ddsa.ddsa_snaps = snaps;
+	ddsa.ddsa_props = props;
+	ddsa.ddsa_errors = errors;
+	ddsa.ddsa_cr = CRED();
+
+	if (error == 0) {
+		error = dsl_sync_task(firstname, dsl_dataset_snapshot_check,
+		    dsl_dataset_snapshot_sync, &ddsa,
+		    fnvlist_num_pairs(snaps) * 3, ZFS_SPACE_CHECK_NORMAL);
+	}
+
+	if (suspended != NULL) {
+		for (pair = nvlist_next_nvpair(suspended, NULL); pair != NULL;
+		    pair = nvlist_next_nvpair(suspended, pair)) {
+			zil_resume((void *)(uintptr_t)
+			    fnvpair_value_uint64(pair));
+		}
+		fnvlist_free(suspended);
+	}
+
+	return (error);
+}
+
+typedef struct dsl_dataset_snapshot_tmp_arg {
+	const char *ddsta_fsname;
+	const char *ddsta_snapname;
+	minor_t ddsta_cleanup_minor;
+	const char *ddsta_htag;
+} dsl_dataset_snapshot_tmp_arg_t;
+
+static int
+dsl_dataset_snapshot_tmp_check(void *arg, dmu_tx_t *tx)
+{
+	dsl_dataset_snapshot_tmp_arg_t *ddsta = arg;
+	dsl_pool_t *dp = dmu_tx_pool(tx);
+	dsl_dataset_t *ds;
+	int error;
+
+	error = dsl_dataset_hold(dp, ddsta->ddsta_fsname, FTAG, &ds);
+	if (error != 0)
+		return (error);
+
+	/* NULL cred means no limit check for tmp snapshot */
+	error = dsl_dataset_snapshot_check_impl(ds, ddsta->ddsta_snapname,
+	    tx, B_FALSE, 0, NULL);
+	if (error != 0) {
+		dsl_dataset_rele(ds, FTAG);
+		return (error);
+	}
+
+	if (spa_version(dp->dp_spa) < SPA_VERSION_USERREFS) {
+		dsl_dataset_rele(ds, FTAG);
+		return (SET_ERROR(ENOTSUP));
+	}
+	error = dsl_dataset_user_hold_check_one(NULL, ddsta->ddsta_htag,
+	    B_TRUE, tx);
+	if (error != 0) {
+		dsl_dataset_rele(ds, FTAG);
+		return (error);
+	}
+
+	dsl_dataset_rele(ds, FTAG);
+	return (0);
+}
+
+static void
+dsl_dataset_snapshot_tmp_sync(void *arg, dmu_tx_t *tx)
+{
+	dsl_dataset_snapshot_tmp_arg_t *ddsta = arg;
+	dsl_pool_t *dp = dmu_tx_pool(tx);
+	dsl_dataset_t *ds;
+
+	VERIFY0(dsl_dataset_hold(dp, ddsta->ddsta_fsname, FTAG, &ds));
+
+	dsl_dataset_snapshot_sync_impl(ds, ddsta->ddsta_snapname, tx);
+	dsl_dataset_user_hold_sync_one(ds->ds_prev, ddsta->ddsta_htag,
+	    ddsta->ddsta_cleanup_minor, gethrestime_sec(), tx);
+	dsl_destroy_snapshot_sync_impl(ds->ds_prev, B_TRUE, tx);
+
+	dsl_dataset_rele(ds, FTAG);
+}
+
+int
+dsl_dataset_snapshot_tmp(const char *fsname, const char *snapname,
+    minor_t cleanup_minor, const char *htag)
+{
+	dsl_dataset_snapshot_tmp_arg_t ddsta;
+	int error;
+	spa_t *spa;
+	boolean_t needsuspend;
+	void *cookie;
+
+	ddsta.ddsta_fsname = fsname;
+	ddsta.ddsta_snapname = snapname;
+	ddsta.ddsta_cleanup_minor = cleanup_minor;
+	ddsta.ddsta_htag = htag;
+
+	error = spa_open(fsname, &spa, FTAG);
+	if (error != 0)
+		return (error);
+	needsuspend = (spa_version(spa) < SPA_VERSION_FAST_SNAP);
+	spa_close(spa, FTAG);
+
+	if (needsuspend) {
+		error = zil_suspend(fsname, &cookie);
+		if (error != 0)
+			return (error);
+	}
+
+	error = dsl_sync_task(fsname, dsl_dataset_snapshot_tmp_check,
+	    dsl_dataset_snapshot_tmp_sync, &ddsta, 3, ZFS_SPACE_CHECK_RESERVED);
+
+	if (needsuspend)
+		zil_resume(cookie);
+	return (error);
+}
+
+
+void
+dsl_dataset_sync(dsl_dataset_t *ds, zio_t *zio, dmu_tx_t *tx)
+{
+	ASSERT(dmu_tx_is_syncing(tx));
+	ASSERT(ds->ds_objset != NULL);
+	ASSERT(dsl_dataset_phys(ds)->ds_next_snap_obj == 0);
+
+	/*
+	 * in case we had to change ds_fsid_guid when we opened it,
+	 * sync it out now.
+	 */
+	dmu_buf_will_dirty(ds->ds_dbuf, tx);
+	dsl_dataset_phys(ds)->ds_fsid_guid = ds->ds_fsid_guid;
+
+	dmu_objset_sync(ds->ds_objset, zio, tx);
+
+	if (ds->ds_need_large_blocks && !ds->ds_large_blocks) {
+		dsl_dataset_activate_large_blocks_sync_impl(ds->ds_object, tx);
+		ds->ds_large_blocks = B_TRUE;
+	}
+}
+
+static void
+get_clones_stat(dsl_dataset_t *ds, nvlist_t *nv)
+{
+	uint64_t count = 0;
+	objset_t *mos = ds->ds_dir->dd_pool->dp_meta_objset;
+	zap_cursor_t zc;
+	zap_attribute_t za;
+	nvlist_t *propval = fnvlist_alloc();
+	nvlist_t *val = fnvlist_alloc();
+
+	ASSERT(dsl_pool_config_held(ds->ds_dir->dd_pool));
+
+	/*
+	 * There may be missing entries in ds_next_clones_obj
+	 * due to a bug in a previous version of the code.
+	 * Only trust it if it has the right number of entries.
+	 */
+	if (dsl_dataset_phys(ds)->ds_next_clones_obj != 0) {
+		VERIFY0(zap_count(mos, dsl_dataset_phys(ds)->ds_next_clones_obj,
+		    &count));
+	}
+	if (count != dsl_dataset_phys(ds)->ds_num_children - 1)
+		goto fail;
+	for (zap_cursor_init(&zc, mos,
+	    dsl_dataset_phys(ds)->ds_next_clones_obj);
+	    zap_cursor_retrieve(&zc, &za) == 0;
+	    zap_cursor_advance(&zc)) {
+		dsl_dataset_t *clone;
+		char buf[ZFS_MAXNAMELEN];
+		VERIFY0(dsl_dataset_hold_obj(ds->ds_dir->dd_pool,
+		    za.za_first_integer, FTAG, &clone));
+		dsl_dir_name(clone->ds_dir, buf);
+		fnvlist_add_boolean(val, buf);
+		dsl_dataset_rele(clone, FTAG);
+	}
+	zap_cursor_fini(&zc);
+	fnvlist_add_nvlist(propval, ZPROP_VALUE, val);
+	fnvlist_add_nvlist(nv, zfs_prop_to_name(ZFS_PROP_CLONES), propval);
+fail:
+	nvlist_free(val);
+	nvlist_free(propval);
+}
+
+void
+dsl_dataset_stats(dsl_dataset_t *ds, nvlist_t *nv)
+{
+	uint64_t refd, avail, uobjs, aobjs, ratio;
+	ASSERTV(dsl_pool_t *dp = ds->ds_dir->dd_pool);
+
+	ASSERT(dsl_pool_config_held(dp));
+
+	ratio = dsl_dataset_phys(ds)->ds_compressed_bytes == 0 ? 100 :
+	    (dsl_dataset_phys(ds)->ds_uncompressed_bytes * 100 /
+	    dsl_dataset_phys(ds)->ds_compressed_bytes);
+
+	dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_REFRATIO, ratio);
+	dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_LOGICALREFERENCED,
+	    dsl_dataset_phys(ds)->ds_uncompressed_bytes);
+
+	if (ds->ds_is_snapshot) {
+		dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_COMPRESSRATIO, ratio);
+		dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_USED,
+		    dsl_dataset_phys(ds)->ds_unique_bytes);
+		get_clones_stat(ds, nv);
+	} else {
+		dsl_dir_stats(ds->ds_dir, nv);
+	}
+
+	dsl_dataset_space(ds, &refd, &avail, &uobjs, &aobjs);
+	dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_AVAILABLE, avail);
+	dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_REFERENCED, refd);
+
+	dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_CREATION,
+	    dsl_dataset_phys(ds)->ds_creation_time);
+	dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_CREATETXG,
+	    dsl_dataset_phys(ds)->ds_creation_txg);
+	dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_REFQUOTA,
+	    ds->ds_quota);
+	dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_REFRESERVATION,
+	    ds->ds_reserved);
+	dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_GUID,
+	    dsl_dataset_phys(ds)->ds_guid);
+	dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_UNIQUE,
+	    dsl_dataset_phys(ds)->ds_unique_bytes);
+	dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_OBJSETID,
+	    ds->ds_object);
+	dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_USERREFS,
+	    ds->ds_userrefs);
+	dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_DEFER_DESTROY,
+	    DS_IS_DEFER_DESTROY(ds) ? 1 : 0);
+
+	if (dsl_dataset_phys(ds)->ds_prev_snap_obj != 0) {
+		uint64_t written, comp, uncomp;
+		dsl_pool_t *dp = ds->ds_dir->dd_pool;
+		dsl_dataset_t *prev;
+		int err;
+
+		err = dsl_dataset_hold_obj(dp,
+		    dsl_dataset_phys(ds)->ds_prev_snap_obj, FTAG, &prev);
+		if (err == 0) {
+			err = dsl_dataset_space_written(prev, ds, &written,
+			    &comp, &uncomp);
+			dsl_dataset_rele(prev, FTAG);
+			if (err == 0) {
+				dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_WRITTEN,
+				    written);
+			}
+		}
+	}
+
+}
+
+void
+dsl_dataset_fast_stat(dsl_dataset_t *ds, dmu_objset_stats_t *stat)
+{
+	dsl_pool_t *dp = ds->ds_dir->dd_pool;
+	ASSERT(dsl_pool_config_held(dp));
+
+	stat->dds_creation_txg = dsl_dataset_phys(ds)->ds_creation_txg;
+	stat->dds_inconsistent =
+	    dsl_dataset_phys(ds)->ds_flags & DS_FLAG_INCONSISTENT;
+	stat->dds_guid = dsl_dataset_phys(ds)->ds_guid;
+	stat->dds_origin[0] = '\0';
+	if (ds->ds_is_snapshot) {
+		stat->dds_is_snapshot = B_TRUE;
+		stat->dds_num_clones =
+		    dsl_dataset_phys(ds)->ds_num_children - 1;
+	} else {
+		stat->dds_is_snapshot = B_FALSE;
+		stat->dds_num_clones = 0;
+
+		if (dsl_dir_is_clone(ds->ds_dir)) {
+			dsl_dataset_t *ods;
+
+			VERIFY0(dsl_dataset_hold_obj(dp,
+			    dsl_dir_phys(ds->ds_dir)->dd_origin_obj,
+			    FTAG, &ods));
+			dsl_dataset_name(ods, stat->dds_origin);
+			dsl_dataset_rele(ods, FTAG);
+		}
+	}
+}
+
+uint64_t
+dsl_dataset_fsid_guid(dsl_dataset_t *ds)
+{
+	return (ds->ds_fsid_guid);
+}
+
+void
+dsl_dataset_space(dsl_dataset_t *ds,
+    uint64_t *refdbytesp, uint64_t *availbytesp,
+    uint64_t *usedobjsp, uint64_t *availobjsp)
+{
+	*refdbytesp = dsl_dataset_phys(ds)->ds_referenced_bytes;
+	*availbytesp = dsl_dir_space_available(ds->ds_dir, NULL, 0, TRUE);
+	if (ds->ds_reserved > dsl_dataset_phys(ds)->ds_unique_bytes)
+		*availbytesp +=
+		    ds->ds_reserved - dsl_dataset_phys(ds)->ds_unique_bytes;
+	if (ds->ds_quota != 0) {
+		/*
+		 * Adjust available bytes according to refquota
+		 */
+		if (*refdbytesp < ds->ds_quota)
+			*availbytesp = MIN(*availbytesp,
+			    ds->ds_quota - *refdbytesp);
+		else
+			*availbytesp = 0;
+	}
+	*usedobjsp = BP_GET_FILL(&dsl_dataset_phys(ds)->ds_bp);
+	*availobjsp = DN_MAX_OBJECT - *usedobjsp;
+}
+
+boolean_t
+dsl_dataset_modified_since_snap(dsl_dataset_t *ds, dsl_dataset_t *snap)
+{
+	ASSERT(dsl_pool_config_held(ds->ds_dir->dd_pool));
+	if (snap == NULL)
+		return (B_FALSE);
+	if (dsl_dataset_phys(ds)->ds_bp.blk_birth >
+	    dsl_dataset_phys(snap)->ds_creation_txg) {
+		objset_t *os, *os_snap;
+		/*
+		 * It may be that only the ZIL differs, because it was
+		 * reset in the head.  Don't count that as being
+		 * modified.
+		 */
+		if (dmu_objset_from_ds(ds, &os) != 0)
+			return (B_TRUE);
+		if (dmu_objset_from_ds(snap, &os_snap) != 0)
+			return (B_TRUE);
+		return (bcmp(&os->os_phys->os_meta_dnode,
+		    &os_snap->os_phys->os_meta_dnode,
+		    sizeof (os->os_phys->os_meta_dnode)) != 0);
+	}
+	return (B_FALSE);
+}
+
+typedef struct dsl_dataset_rename_snapshot_arg {
+	const char *ddrsa_fsname;
+	const char *ddrsa_oldsnapname;
+	const char *ddrsa_newsnapname;
+	boolean_t ddrsa_recursive;
+	dmu_tx_t *ddrsa_tx;
+} dsl_dataset_rename_snapshot_arg_t;
+
+/* ARGSUSED */
+static int
+dsl_dataset_rename_snapshot_check_impl(dsl_pool_t *dp,
+    dsl_dataset_t *hds, void *arg)
+{
+	dsl_dataset_rename_snapshot_arg_t *ddrsa = arg;
+	int error;
+	uint64_t val;
+
+	error = dsl_dataset_snap_lookup(hds, ddrsa->ddrsa_oldsnapname, &val);
+	if (error != 0) {
+		/* ignore nonexistent snapshots */
+		return (error == ENOENT ? 0 : error);
+	}
+
+	/* new name should not exist */
+	error = dsl_dataset_snap_lookup(hds, ddrsa->ddrsa_newsnapname, &val);
+	if (error == 0)
+		error = SET_ERROR(EEXIST);
+	else if (error == ENOENT)
+		error = 0;
+
+	/* dataset name + 1 for the "@" + the new snapshot name must fit */
+	if (dsl_dir_namelen(hds->ds_dir) + 1 +
+	    strlen(ddrsa->ddrsa_newsnapname) >= MAXNAMELEN)
+		error = SET_ERROR(ENAMETOOLONG);
+
+	return (error);
+}
+
+static int
+dsl_dataset_rename_snapshot_check(void *arg, dmu_tx_t *tx)
+{
+	dsl_dataset_rename_snapshot_arg_t *ddrsa = arg;
+	dsl_pool_t *dp = dmu_tx_pool(tx);
+	dsl_dataset_t *hds;
+	int error;
+
+	error = dsl_dataset_hold(dp, ddrsa->ddrsa_fsname, FTAG, &hds);
+	if (error != 0)
+		return (error);
+
+	if (ddrsa->ddrsa_recursive) {
+		error = dmu_objset_find_dp(dp, hds->ds_dir->dd_object,
+		    dsl_dataset_rename_snapshot_check_impl, ddrsa,
+		    DS_FIND_CHILDREN);
+	} else {
+		error = dsl_dataset_rename_snapshot_check_impl(dp, hds, ddrsa);
+	}
+	dsl_dataset_rele(hds, FTAG);
+	return (error);
+}
+
+static int
+dsl_dataset_rename_snapshot_sync_impl(dsl_pool_t *dp,
+    dsl_dataset_t *hds, void *arg)
+{
+	dsl_dataset_rename_snapshot_arg_t *ddrsa = arg;
+	dsl_dataset_t *ds;
+	uint64_t val;
+	dmu_tx_t *tx = ddrsa->ddrsa_tx;
+	int error;
+
+	error = dsl_dataset_snap_lookup(hds, ddrsa->ddrsa_oldsnapname, &val);
+	ASSERT(error == 0 || error == ENOENT);
+	if (error == ENOENT) {
+		/* ignore nonexistent snapshots */
+		return (0);
+	}
+
+	VERIFY0(dsl_dataset_hold_obj(dp, val, FTAG, &ds));
+
+	/* log before we change the name */
+	spa_history_log_internal_ds(ds, "rename", tx,
+	    "-> @%s", ddrsa->ddrsa_newsnapname);
+
+	VERIFY0(dsl_dataset_snap_remove(hds, ddrsa->ddrsa_oldsnapname, tx,
+	    B_FALSE));
+	mutex_enter(&ds->ds_lock);
+	(void) strcpy(ds->ds_snapname, ddrsa->ddrsa_newsnapname);
+	mutex_exit(&ds->ds_lock);
+	VERIFY0(zap_add(dp->dp_meta_objset,
+	    dsl_dataset_phys(hds)->ds_snapnames_zapobj,
+	    ds->ds_snapname, 8, 1, &ds->ds_object, tx));
+	zvol_rename_minors(dp->dp_spa, ddrsa->ddrsa_oldsnapname,
+	    ddrsa->ddrsa_newsnapname, B_TRUE);
+
+	dsl_dataset_rele(ds, FTAG);
+	return (0);
+}
+
+static void
+dsl_dataset_rename_snapshot_sync(void *arg, dmu_tx_t *tx)
+{
+	dsl_dataset_rename_snapshot_arg_t *ddrsa = arg;
+	dsl_pool_t *dp = dmu_tx_pool(tx);
+	dsl_dataset_t *hds;
+
+	VERIFY0(dsl_dataset_hold(dp, ddrsa->ddrsa_fsname, FTAG, &hds));
+	ddrsa->ddrsa_tx = tx;
+	if (ddrsa->ddrsa_recursive) {
+		VERIFY0(dmu_objset_find_dp(dp, hds->ds_dir->dd_object,
+		    dsl_dataset_rename_snapshot_sync_impl, ddrsa,
+		    DS_FIND_CHILDREN));
+	} else {
+		VERIFY0(dsl_dataset_rename_snapshot_sync_impl(dp, hds, ddrsa));
+	}
+	dsl_dataset_rele(hds, FTAG);
+}
+
+int
+dsl_dataset_rename_snapshot(const char *fsname,
+    const char *oldsnapname, const char *newsnapname, boolean_t recursive)
+{
+	dsl_dataset_rename_snapshot_arg_t ddrsa;
+
+	ddrsa.ddrsa_fsname = fsname;
+	ddrsa.ddrsa_oldsnapname = oldsnapname;
+	ddrsa.ddrsa_newsnapname = newsnapname;
+	ddrsa.ddrsa_recursive = recursive;
+
+	return (dsl_sync_task(fsname, dsl_dataset_rename_snapshot_check,
+	    dsl_dataset_rename_snapshot_sync, &ddrsa,
+	    1, ZFS_SPACE_CHECK_RESERVED));
+}
+
+/*
+ * If we're doing an ownership handoff, we need to make sure that there is
+ * only one long hold on the dataset.  We're not allowed to change anything here
+ * so we don't permanently release the long hold or regular hold here.  We want
+ * to do this only when syncing to avoid the dataset unexpectedly going away
+ * when we release the long hold.
+ */
+static int
+dsl_dataset_handoff_check(dsl_dataset_t *ds, void *owner, dmu_tx_t *tx)
+{
+	boolean_t held;
+
+	if (!dmu_tx_is_syncing(tx))
+		return (0);
+
+	if (owner != NULL) {
+		VERIFY3P(ds->ds_owner, ==, owner);
+		dsl_dataset_long_rele(ds, owner);
+	}
+
+	held = dsl_dataset_long_held(ds);
+
+	if (owner != NULL)
+		dsl_dataset_long_hold(ds, owner);
+
+	if (held)
+		return (SET_ERROR(EBUSY));
+
+	return (0);
+}
+
+typedef struct dsl_dataset_rollback_arg {
+	const char *ddra_fsname;
+	void *ddra_owner;
+	nvlist_t *ddra_result;
+} dsl_dataset_rollback_arg_t;
+
+static int
+dsl_dataset_rollback_check(void *arg, dmu_tx_t *tx)
+{
+	dsl_dataset_rollback_arg_t *ddra = arg;
+	dsl_pool_t *dp = dmu_tx_pool(tx);
+	dsl_dataset_t *ds;
+	int64_t unused_refres_delta;
+	int error;
+	nvpair_t *pair;
+	nvlist_t *proprequest, *bookmarks;
+
+	error = dsl_dataset_hold(dp, ddra->ddra_fsname, FTAG, &ds);
+	if (error != 0)
+		return (error);
+
+	/* must not be a snapshot */
+	if (ds->ds_is_snapshot) {
+		dsl_dataset_rele(ds, FTAG);
+		return (SET_ERROR(EINVAL));
+	}
+
+	/* must have a most recent snapshot */
+	if (dsl_dataset_phys(ds)->ds_prev_snap_txg < TXG_INITIAL) {
+		dsl_dataset_rele(ds, FTAG);
+		return (SET_ERROR(EINVAL));
+	}
+
+	/* must not have any bookmarks after the most recent snapshot */
+	proprequest = fnvlist_alloc();
+	fnvlist_add_boolean(proprequest, zfs_prop_to_name(ZFS_PROP_CREATETXG));
+	bookmarks = fnvlist_alloc();
+	error = dsl_get_bookmarks_impl(ds, proprequest, bookmarks);
+	fnvlist_free(proprequest);
+	if (error != 0)
+		return (error);
+	for (pair = nvlist_next_nvpair(bookmarks, NULL);
+	    pair != NULL; pair = nvlist_next_nvpair(bookmarks, pair)) {
+		nvlist_t *valuenv =
+		    fnvlist_lookup_nvlist(fnvpair_value_nvlist(pair),
+		    zfs_prop_to_name(ZFS_PROP_CREATETXG));
+		uint64_t createtxg = fnvlist_lookup_uint64(valuenv, "value");
+		if (createtxg > dsl_dataset_phys(ds)->ds_prev_snap_txg) {
+			fnvlist_free(bookmarks);
+			dsl_dataset_rele(ds, FTAG);
+			return (SET_ERROR(EEXIST));
+		}
+	}
+	fnvlist_free(bookmarks);
+
+	error = dsl_dataset_handoff_check(ds, ddra->ddra_owner, tx);
+	if (error != 0) {
+		dsl_dataset_rele(ds, FTAG);
+		return (error);
+	}
+
+	/*
+	 * Check if the snap we are rolling back to uses more than
+	 * the refquota.
+	 */
+	if (ds->ds_quota != 0 &&
+	    dsl_dataset_phys(ds->ds_prev)->ds_referenced_bytes > ds->ds_quota) {
+		dsl_dataset_rele(ds, FTAG);
+		return (SET_ERROR(EDQUOT));
+	}
+
+	/*
+	 * When we do the clone swap, we will temporarily use more space
+	 * due to the refreservation (the head will no longer have any
+	 * unique space, so the entire amount of the refreservation will need
+	 * to be free).  We will immediately destroy the clone, freeing
+	 * this space, but the freeing happens over many txg's.
+	 */
+	unused_refres_delta = (int64_t)MIN(ds->ds_reserved,
+	    dsl_dataset_phys(ds)->ds_unique_bytes);
+
+	if (unused_refres_delta > 0 &&
+	    unused_refres_delta >
+	    dsl_dir_space_available(ds->ds_dir, NULL, 0, TRUE)) {
+		dsl_dataset_rele(ds, FTAG);
+		return (SET_ERROR(ENOSPC));
+	}
+
+	dsl_dataset_rele(ds, FTAG);
+	return (0);
+}
+
+static void
+dsl_dataset_rollback_sync(void *arg, dmu_tx_t *tx)
+{
+	dsl_dataset_rollback_arg_t *ddra = arg;
+	dsl_pool_t *dp = dmu_tx_pool(tx);
+	dsl_dataset_t *ds, *clone;
+	uint64_t cloneobj;
+	char namebuf[ZFS_MAXNAMELEN];
+
+	VERIFY0(dsl_dataset_hold(dp, ddra->ddra_fsname, FTAG, &ds));
+
+	dsl_dataset_name(ds->ds_prev, namebuf);
+	fnvlist_add_string(ddra->ddra_result, "target", namebuf);
+
+	cloneobj = dsl_dataset_create_sync(ds->ds_dir, "%rollback",
+	    ds->ds_prev, DS_CREATE_FLAG_NODIRTY, kcred, tx);
+
+	VERIFY0(dsl_dataset_hold_obj(dp, cloneobj, FTAG, &clone));
+
+	dsl_dataset_clone_swap_sync_impl(clone, ds, tx);
+	dsl_dataset_zero_zil(ds, tx);
+
+	dsl_destroy_head_sync_impl(clone, tx);
+
+	dsl_dataset_rele(clone, FTAG);
+	dsl_dataset_rele(ds, FTAG);
+}
+
+/*
+ * Rolls back the given filesystem or volume to the most recent snapshot.
+ * The name of the most recent snapshot will be returned under key "target"
+ * in the result nvlist.
+ *
+ * If owner != NULL:
+ * - The existing dataset MUST be owned by the specified owner at entry
+ * - Upon return, dataset will still be held by the same owner, whether we
+ *   succeed or not.
+ *
+ * This mode is required any time the existing filesystem is mounted.  See
+ * notes above zfs_suspend_fs() for further details.
+ */
+int
+dsl_dataset_rollback(const char *fsname, void *owner, nvlist_t *result)
+{
+	dsl_dataset_rollback_arg_t ddra;
+
+	ddra.ddra_fsname = fsname;
+	ddra.ddra_owner = owner;
+	ddra.ddra_result = result;
+
+	return (dsl_sync_task(fsname, dsl_dataset_rollback_check,
+	    dsl_dataset_rollback_sync, &ddra,
+	    1, ZFS_SPACE_CHECK_RESERVED));
+}
+
+struct promotenode {
+	list_node_t link;
+	dsl_dataset_t *ds;
+};
+
+typedef struct dsl_dataset_promote_arg {
+	const char *ddpa_clonename;
+	dsl_dataset_t *ddpa_clone;
+	list_t shared_snaps, origin_snaps, clone_snaps;
+	dsl_dataset_t *origin_origin; /* origin of the origin */
+	uint64_t used, comp, uncomp, unique, cloneusedsnap, originusedsnap;
+	char *err_ds;
+	cred_t *cr;
+} dsl_dataset_promote_arg_t;
+
+static int snaplist_space(list_t *l, uint64_t mintxg, uint64_t *spacep);
+static int promote_hold(dsl_dataset_promote_arg_t *ddpa, dsl_pool_t *dp,
+    void *tag);
+static void promote_rele(dsl_dataset_promote_arg_t *ddpa, void *tag);
+
+static int
+dsl_dataset_promote_check(void *arg, dmu_tx_t *tx)
+{
+	dsl_dataset_promote_arg_t *ddpa = arg;
+	dsl_pool_t *dp = dmu_tx_pool(tx);
+	dsl_dataset_t *hds;
+	struct promotenode *snap;
+	dsl_dataset_t *origin_ds;
+	int err;
+	uint64_t unused;
+	uint64_t ss_mv_cnt;
+	size_t max_snap_len;
+
+	err = promote_hold(ddpa, dp, FTAG);
+	if (err != 0)
+		return (err);
+
+	hds = ddpa->ddpa_clone;
+	max_snap_len = MAXNAMELEN - strlen(ddpa->ddpa_clonename) - 1;
+
+	if (dsl_dataset_phys(hds)->ds_flags & DS_FLAG_NOPROMOTE) {
+		promote_rele(ddpa, FTAG);
+		return (SET_ERROR(EXDEV));
+	}
+
+	/*
+	 * Compute and check the amount of space to transfer.  Since this is
+	 * so expensive, don't do the preliminary check.
+	 */
+	if (!dmu_tx_is_syncing(tx)) {
+		promote_rele(ddpa, FTAG);
+		return (0);
+	}
+
+	snap = list_head(&ddpa->shared_snaps);
+	origin_ds = snap->ds;
+
+	/* compute origin's new unique space */
+	snap = list_tail(&ddpa->clone_snaps);
+	ASSERT3U(dsl_dataset_phys(snap->ds)->ds_prev_snap_obj, ==,
+	    origin_ds->ds_object);
+	dsl_deadlist_space_range(&snap->ds->ds_deadlist,
+	    dsl_dataset_phys(origin_ds)->ds_prev_snap_txg, UINT64_MAX,
+	    &ddpa->unique, &unused, &unused);
+
+	/*
+	 * Walk the snapshots that we are moving
+	 *
+	 * Compute space to transfer.  Consider the incremental changes
+	 * to used by each snapshot:
+	 * (my used) = (prev's used) + (blocks born) - (blocks killed)
+	 * So each snapshot gave birth to:
+	 * (blocks born) = (my used) - (prev's used) + (blocks killed)
+	 * So a sequence would look like:
+	 * (uN - u(N-1) + kN) + ... + (u1 - u0 + k1) + (u0 - 0 + k0)
+	 * Which simplifies to:
+	 * uN + kN + kN-1 + ... + k1 + k0
+	 * Note however, if we stop before we reach the ORIGIN we get:
+	 * uN + kN + kN-1 + ... + kM - uM-1
+	 */
+	ss_mv_cnt = 0;
+	ddpa->used = dsl_dataset_phys(origin_ds)->ds_referenced_bytes;
+	ddpa->comp = dsl_dataset_phys(origin_ds)->ds_compressed_bytes;
+	ddpa->uncomp = dsl_dataset_phys(origin_ds)->ds_uncompressed_bytes;
+	for (snap = list_head(&ddpa->shared_snaps); snap;
+	    snap = list_next(&ddpa->shared_snaps, snap)) {
+		uint64_t val, dlused, dlcomp, dluncomp;
+		dsl_dataset_t *ds = snap->ds;
+
+		ss_mv_cnt++;
+
+		/*
+		 * If there are long holds, we won't be able to evict
+		 * the objset.
+		 */
+		if (dsl_dataset_long_held(ds)) {
+			err = SET_ERROR(EBUSY);
+			goto out;
+		}
+
+		/* Check that the snapshot name does not conflict */
+		VERIFY0(dsl_dataset_get_snapname(ds));
+		if (strlen(ds->ds_snapname) >= max_snap_len) {
+			err = SET_ERROR(ENAMETOOLONG);
+			goto out;
+		}
+		err = dsl_dataset_snap_lookup(hds, ds->ds_snapname, &val);
+		if (err == 0) {
+			(void) strcpy(ddpa->err_ds, snap->ds->ds_snapname);
+			err = SET_ERROR(EEXIST);
+			goto out;
+		}
+		if (err != ENOENT)
+			goto out;
+
+		/* The very first snapshot does not have a deadlist */
+		if (dsl_dataset_phys(ds)->ds_prev_snap_obj == 0)
+			continue;
+
+		dsl_deadlist_space(&ds->ds_deadlist,
+		    &dlused, &dlcomp, &dluncomp);
+		ddpa->used += dlused;
+		ddpa->comp += dlcomp;
+		ddpa->uncomp += dluncomp;
+	}
+
+	/*
+	 * If we are a clone of a clone then we never reached ORIGIN,
+	 * so we need to subtract out the clone origin's used space.
+	 */
+	if (ddpa->origin_origin) {
+		ddpa->used -=
+		    dsl_dataset_phys(ddpa->origin_origin)->ds_referenced_bytes;
+		ddpa->comp -=
+		    dsl_dataset_phys(ddpa->origin_origin)->ds_compressed_bytes;
+		ddpa->uncomp -=
+		    dsl_dataset_phys(ddpa->origin_origin)->
+		    ds_uncompressed_bytes;
+	}
+
+	/* Check that there is enough space and limit headroom here */
+	err = dsl_dir_transfer_possible(origin_ds->ds_dir, hds->ds_dir,
+	    0, ss_mv_cnt, ddpa->used, ddpa->cr);
+	if (err != 0)
+		goto out;
+
+	/*
+	 * Compute the amounts of space that will be used by snapshots
+	 * after the promotion (for both origin and clone).  For each,
+	 * it is the amount of space that will be on all of their
+	 * deadlists (that was not born before their new origin).
+	 */
+	if (dsl_dir_phys(hds->ds_dir)->dd_flags & DD_FLAG_USED_BREAKDOWN) {
+		uint64_t space;
+
+		/*
+		 * Note, typically this will not be a clone of a clone,
+		 * so dd_origin_txg will be < TXG_INITIAL, so
+		 * these snaplist_space() -> dsl_deadlist_space_range()
+		 * calls will be fast because they do not have to
+		 * iterate over all bps.
+		 */
+		snap = list_head(&ddpa->origin_snaps);
+		err = snaplist_space(&ddpa->shared_snaps,
+		    snap->ds->ds_dir->dd_origin_txg, &ddpa->cloneusedsnap);
+		if (err != 0)
+			goto out;
+
+		err = snaplist_space(&ddpa->clone_snaps,
+		    snap->ds->ds_dir->dd_origin_txg, &space);
+		if (err != 0)
+			goto out;
+		ddpa->cloneusedsnap += space;
+	}
+	if (dsl_dir_phys(origin_ds->ds_dir)->dd_flags &
+	    DD_FLAG_USED_BREAKDOWN) {
+		err = snaplist_space(&ddpa->origin_snaps,
+		    dsl_dataset_phys(origin_ds)->ds_creation_txg,
+		    &ddpa->originusedsnap);
+		if (err != 0)
+			goto out;
+	}
+
+out:
+	promote_rele(ddpa, FTAG);
+	return (err);
+}
+
+static void
+dsl_dataset_promote_sync(void *arg, dmu_tx_t *tx)
+{
+	dsl_dataset_promote_arg_t *ddpa = arg;
+	dsl_pool_t *dp = dmu_tx_pool(tx);
+	dsl_dataset_t *hds;
+	struct promotenode *snap;
+	dsl_dataset_t *origin_ds;
+	dsl_dataset_t *origin_head;
+	dsl_dir_t *dd;
+	dsl_dir_t *odd = NULL;
+	uint64_t oldnext_obj;
+	int64_t delta;
+
+	VERIFY0(promote_hold(ddpa, dp, FTAG));
+	hds = ddpa->ddpa_clone;
+
+	ASSERT0(dsl_dataset_phys(hds)->ds_flags & DS_FLAG_NOPROMOTE);
+
+	snap = list_head(&ddpa->shared_snaps);
+	origin_ds = snap->ds;
+	dd = hds->ds_dir;
+
+	snap = list_head(&ddpa->origin_snaps);
+	origin_head = snap->ds;
+
+	/*
+	 * We need to explicitly open odd, since origin_ds's dd will be
+	 * changing.
+	 */
+	VERIFY0(dsl_dir_hold_obj(dp, origin_ds->ds_dir->dd_object,
+	    NULL, FTAG, &odd));
+
+	/* change origin's next snap */
+	dmu_buf_will_dirty(origin_ds->ds_dbuf, tx);
+	oldnext_obj = dsl_dataset_phys(origin_ds)->ds_next_snap_obj;
+	snap = list_tail(&ddpa->clone_snaps);
+	ASSERT3U(dsl_dataset_phys(snap->ds)->ds_prev_snap_obj, ==,
+	    origin_ds->ds_object);
+	dsl_dataset_phys(origin_ds)->ds_next_snap_obj = snap->ds->ds_object;
+
+	/* change the origin's next clone */
+	if (dsl_dataset_phys(origin_ds)->ds_next_clones_obj) {
+		dsl_dataset_remove_from_next_clones(origin_ds,
+		    snap->ds->ds_object, tx);
+		VERIFY0(zap_add_int(dp->dp_meta_objset,
+		    dsl_dataset_phys(origin_ds)->ds_next_clones_obj,
+		    oldnext_obj, tx));
+	}
+
+	/* change origin */
+	dmu_buf_will_dirty(dd->dd_dbuf, tx);
+	ASSERT3U(dsl_dir_phys(dd)->dd_origin_obj, ==, origin_ds->ds_object);
+	dsl_dir_phys(dd)->dd_origin_obj = dsl_dir_phys(odd)->dd_origin_obj;
+	dd->dd_origin_txg = origin_head->ds_dir->dd_origin_txg;
+	dmu_buf_will_dirty(odd->dd_dbuf, tx);
+	dsl_dir_phys(odd)->dd_origin_obj = origin_ds->ds_object;
+	origin_head->ds_dir->dd_origin_txg =
+	    dsl_dataset_phys(origin_ds)->ds_creation_txg;
+
+	/* change dd_clone entries */
+	if (spa_version(dp->dp_spa) >= SPA_VERSION_DIR_CLONES) {
+		VERIFY0(zap_remove_int(dp->dp_meta_objset,
+		    dsl_dir_phys(odd)->dd_clones, hds->ds_object, tx));
+		VERIFY0(zap_add_int(dp->dp_meta_objset,
+		    dsl_dir_phys(ddpa->origin_origin->ds_dir)->dd_clones,
+		    hds->ds_object, tx));
+
+		VERIFY0(zap_remove_int(dp->dp_meta_objset,
+		    dsl_dir_phys(ddpa->origin_origin->ds_dir)->dd_clones,
+		    origin_head->ds_object, tx));
+		if (dsl_dir_phys(dd)->dd_clones == 0) {
+			dsl_dir_phys(dd)->dd_clones =
+			    zap_create(dp->dp_meta_objset, DMU_OT_DSL_CLONES,
+			    DMU_OT_NONE, 0, tx);
+		}
+		VERIFY0(zap_add_int(dp->dp_meta_objset,
+		    dsl_dir_phys(dd)->dd_clones, origin_head->ds_object, tx));
+	}
+
+	/* move snapshots to this dir */
+	for (snap = list_head(&ddpa->shared_snaps); snap;
+	    snap = list_next(&ddpa->shared_snaps, snap)) {
+		dsl_dataset_t *ds = snap->ds;
+
+		/*
+		 * Property callbacks are registered to a particular
+		 * dsl_dir.  Since ours is changing, evict the objset
+		 * so that they will be unregistered from the old dsl_dir.
+		 */
+		if (ds->ds_objset) {
+			dmu_objset_evict(ds->ds_objset);
+			ds->ds_objset = NULL;
+		}
+
+		/* move snap name entry */
+		VERIFY0(dsl_dataset_get_snapname(ds));
+		VERIFY0(dsl_dataset_snap_remove(origin_head,
+		    ds->ds_snapname, tx, B_TRUE));
+		VERIFY0(zap_add(dp->dp_meta_objset,
+		    dsl_dataset_phys(hds)->ds_snapnames_zapobj, ds->ds_snapname,
+		    8, 1, &ds->ds_object, tx));
+		dsl_fs_ss_count_adjust(hds->ds_dir, 1,
+		    DD_FIELD_SNAPSHOT_COUNT, tx);
+
+		/* change containing dsl_dir */
+		dmu_buf_will_dirty(ds->ds_dbuf, tx);
+		ASSERT3U(dsl_dataset_phys(ds)->ds_dir_obj, ==, odd->dd_object);
+		dsl_dataset_phys(ds)->ds_dir_obj = dd->dd_object;
+		ASSERT3P(ds->ds_dir, ==, odd);
+		dsl_dir_rele(ds->ds_dir, ds);
+		VERIFY0(dsl_dir_hold_obj(dp, dd->dd_object,
+		    NULL, ds, &ds->ds_dir));
+
+		/* move any clone references */
+		if (dsl_dataset_phys(ds)->ds_next_clones_obj &&
+		    spa_version(dp->dp_spa) >= SPA_VERSION_DIR_CLONES) {
+			zap_cursor_t zc;
+			zap_attribute_t za;
+
+			for (zap_cursor_init(&zc, dp->dp_meta_objset,
+			    dsl_dataset_phys(ds)->ds_next_clones_obj);
+			    zap_cursor_retrieve(&zc, &za) == 0;
+			    zap_cursor_advance(&zc)) {
+				dsl_dataset_t *cnds;
+				uint64_t o;
+
+				if (za.za_first_integer == oldnext_obj) {
+					/*
+					 * We've already moved the
+					 * origin's reference.
+					 */
+					continue;
+				}
+
+				VERIFY0(dsl_dataset_hold_obj(dp,
+				    za.za_first_integer, FTAG, &cnds));
+				o = dsl_dir_phys(cnds->ds_dir)->
+				    dd_head_dataset_obj;
+
+				VERIFY0(zap_remove_int(dp->dp_meta_objset,
+				    dsl_dir_phys(odd)->dd_clones, o, tx));
+				VERIFY0(zap_add_int(dp->dp_meta_objset,
+				    dsl_dir_phys(dd)->dd_clones, o, tx));
+				dsl_dataset_rele(cnds, FTAG);
+			}
+			zap_cursor_fini(&zc);
+		}
+
+		ASSERT(!dsl_prop_hascb(ds));
+	}
+
+	/*
+	 * Change space accounting.
+	 * Note, pa->*usedsnap and dd_used_breakdown[SNAP] will either
+	 * both be valid, or both be 0 (resulting in delta == 0).  This
+	 * is true for each of {clone,origin} independently.
+	 */
+
+	delta = ddpa->cloneusedsnap -
+	    dsl_dir_phys(dd)->dd_used_breakdown[DD_USED_SNAP];
+	ASSERT3S(delta, >=, 0);
+	ASSERT3U(ddpa->used, >=, delta);
+	dsl_dir_diduse_space(dd, DD_USED_SNAP, delta, 0, 0, tx);
+	dsl_dir_diduse_space(dd, DD_USED_HEAD,
+	    ddpa->used - delta, ddpa->comp, ddpa->uncomp, tx);
+
+	delta = ddpa->originusedsnap -
+	    dsl_dir_phys(odd)->dd_used_breakdown[DD_USED_SNAP];
+	ASSERT3S(delta, <=, 0);
+	ASSERT3U(ddpa->used, >=, -delta);
+	dsl_dir_diduse_space(odd, DD_USED_SNAP, delta, 0, 0, tx);
+	dsl_dir_diduse_space(odd, DD_USED_HEAD,
+	    -ddpa->used - delta, -ddpa->comp, -ddpa->uncomp, tx);
+
+	dsl_dataset_phys(origin_ds)->ds_unique_bytes = ddpa->unique;
+
+	/* log history record */
+	spa_history_log_internal_ds(hds, "promote", tx, "");
+
+	dsl_dir_rele(odd, FTAG);
+	promote_rele(ddpa, FTAG);
+}
+
+/*
+ * Make a list of dsl_dataset_t's for the snapshots between first_obj
+ * (exclusive) and last_obj (inclusive).  The list will be in reverse
+ * order (last_obj will be the list_head()).  If first_obj == 0, do all
+ * snapshots back to this dataset's origin.
+ */
+static int
+snaplist_make(dsl_pool_t *dp,
+    uint64_t first_obj, uint64_t last_obj, list_t *l, void *tag)
+{
+	uint64_t obj = last_obj;
+
+	list_create(l, sizeof (struct promotenode),
+	    offsetof(struct promotenode, link));
+
+	while (obj != first_obj) {
+		dsl_dataset_t *ds;
+		struct promotenode *snap;
+		int err;
+
+		err = dsl_dataset_hold_obj(dp, obj, tag, &ds);
+		ASSERT(err != ENOENT);
+		if (err != 0)
+			return (err);
+
+		if (first_obj == 0)
+			first_obj = dsl_dir_phys(ds->ds_dir)->dd_origin_obj;
+
+		snap = kmem_alloc(sizeof (*snap), KM_SLEEP);
+		snap->ds = ds;
+		list_insert_tail(l, snap);
+		obj = dsl_dataset_phys(ds)->ds_prev_snap_obj;
+	}
+
+	return (0);
+}
+
+static int
+snaplist_space(list_t *l, uint64_t mintxg, uint64_t *spacep)
+{
+	struct promotenode *snap;
+
+	*spacep = 0;
+	for (snap = list_head(l); snap; snap = list_next(l, snap)) {
+		uint64_t used, comp, uncomp;
+		dsl_deadlist_space_range(&snap->ds->ds_deadlist,
+		    mintxg, UINT64_MAX, &used, &comp, &uncomp);
+		*spacep += used;
+	}
+	return (0);
+}
+
+static void
+snaplist_destroy(list_t *l, void *tag)
+{
+	struct promotenode *snap;
+
+	if (l == NULL || !list_link_active(&l->list_head))
+		return;
+
+	while ((snap = list_tail(l)) != NULL) {
+		list_remove(l, snap);
+		dsl_dataset_rele(snap->ds, tag);
+		kmem_free(snap, sizeof (*snap));
+	}
+	list_destroy(l);
+}
+
+static int
+promote_hold(dsl_dataset_promote_arg_t *ddpa, dsl_pool_t *dp, void *tag)
+{
+	int error;
+	dsl_dir_t *dd;
+	struct promotenode *snap;
+
+	error = dsl_dataset_hold(dp, ddpa->ddpa_clonename, tag,
+	    &ddpa->ddpa_clone);
+	if (error != 0)
+		return (error);
+	dd = ddpa->ddpa_clone->ds_dir;
+
+	if (ddpa->ddpa_clone->ds_is_snapshot ||
+	    !dsl_dir_is_clone(dd)) {
+		dsl_dataset_rele(ddpa->ddpa_clone, tag);
+		return (SET_ERROR(EINVAL));
+	}
+
+	error = snaplist_make(dp, 0, dsl_dir_phys(dd)->dd_origin_obj,
+	    &ddpa->shared_snaps, tag);
+	if (error != 0)
+		goto out;
+
+	error = snaplist_make(dp, 0, ddpa->ddpa_clone->ds_object,
+	    &ddpa->clone_snaps, tag);
+	if (error != 0)
+		goto out;
+
+	snap = list_head(&ddpa->shared_snaps);
+	ASSERT3U(snap->ds->ds_object, ==, dsl_dir_phys(dd)->dd_origin_obj);
+	error = snaplist_make(dp, dsl_dir_phys(dd)->dd_origin_obj,
+	    dsl_dir_phys(snap->ds->ds_dir)->dd_head_dataset_obj,
+	    &ddpa->origin_snaps, tag);
+	if (error != 0)
+		goto out;
+
+	if (dsl_dir_phys(snap->ds->ds_dir)->dd_origin_obj != 0) {
+		error = dsl_dataset_hold_obj(dp,
+		    dsl_dir_phys(snap->ds->ds_dir)->dd_origin_obj,
+		    tag, &ddpa->origin_origin);
+		if (error != 0)
+			goto out;
+	}
+out:
+	if (error != 0)
+		promote_rele(ddpa, tag);
+	return (error);
+}
+
+static void
+promote_rele(dsl_dataset_promote_arg_t *ddpa, void *tag)
+{
+	snaplist_destroy(&ddpa->shared_snaps, tag);
+	snaplist_destroy(&ddpa->clone_snaps, tag);
+	snaplist_destroy(&ddpa->origin_snaps, tag);
+	if (ddpa->origin_origin != NULL)
+		dsl_dataset_rele(ddpa->origin_origin, tag);
+	dsl_dataset_rele(ddpa->ddpa_clone, tag);
+}
+
+/*
+ * Promote a clone.
+ *
+ * If it fails due to a conflicting snapshot name, "conflsnap" will be filled
+ * in with the name.  (It must be at least MAXNAMELEN bytes long.)
+ */
+int
+dsl_dataset_promote(const char *name, char *conflsnap)
+{
+	dsl_dataset_promote_arg_t ddpa = { 0 };
+	uint64_t numsnaps;
+	int error;
+	objset_t *os;
+
+	/*
+	 * We will modify space proportional to the number of
+	 * snapshots.  Compute numsnaps.
+	 */
+	error = dmu_objset_hold(name, FTAG, &os);
+	if (error != 0)
+		return (error);
+	error = zap_count(dmu_objset_pool(os)->dp_meta_objset,
+	    dsl_dataset_phys(dmu_objset_ds(os))->ds_snapnames_zapobj,
+	    &numsnaps);
+	dmu_objset_rele(os, FTAG);
+	if (error != 0)
+		return (error);
+
+	ddpa.ddpa_clonename = name;
+	ddpa.err_ds = conflsnap;
+	ddpa.cr = CRED();
+
+	return (dsl_sync_task(name, dsl_dataset_promote_check,
+	    dsl_dataset_promote_sync, &ddpa,
+	    2 + numsnaps, ZFS_SPACE_CHECK_RESERVED));
+}
+
+int
+dsl_dataset_clone_swap_check_impl(dsl_dataset_t *clone,
+    dsl_dataset_t *origin_head, boolean_t force, void *owner, dmu_tx_t *tx)
+{
+	int64_t unused_refres_delta;
+
+	/* they should both be heads */
+	if (clone->ds_is_snapshot ||
+	    origin_head->ds_is_snapshot)
+		return (SET_ERROR(EINVAL));
+
+	/* if we are not forcing, the branch point should be just before them */
+	if (!force && clone->ds_prev != origin_head->ds_prev)
+		return (SET_ERROR(EINVAL));
+
+	/* clone should be the clone (unless they are unrelated) */
+	if (clone->ds_prev != NULL &&
+	    clone->ds_prev != clone->ds_dir->dd_pool->dp_origin_snap &&
+	    origin_head->ds_dir != clone->ds_prev->ds_dir)
+		return (SET_ERROR(EINVAL));
+
+	/* the clone should be a child of the origin */
+	if (clone->ds_dir->dd_parent != origin_head->ds_dir)
+		return (SET_ERROR(EINVAL));
+
+	/* origin_head shouldn't be modified unless 'force' */
+	if (!force &&
+	    dsl_dataset_modified_since_snap(origin_head, origin_head->ds_prev))
+		return (SET_ERROR(ETXTBSY));
+
+	/* origin_head should have no long holds (e.g. is not mounted) */
+	if (dsl_dataset_handoff_check(origin_head, owner, tx))
+		return (SET_ERROR(EBUSY));
+
+	/* check amount of any unconsumed refreservation */
+	unused_refres_delta =
+	    (int64_t)MIN(origin_head->ds_reserved,
+	    dsl_dataset_phys(origin_head)->ds_unique_bytes) -
+	    (int64_t)MIN(origin_head->ds_reserved,
+	    dsl_dataset_phys(clone)->ds_unique_bytes);
+
+	if (unused_refres_delta > 0 &&
+	    unused_refres_delta >
+	    dsl_dir_space_available(origin_head->ds_dir, NULL, 0, TRUE))
+		return (SET_ERROR(ENOSPC));
+
+	/* clone can't be over the head's refquota */
+	if (origin_head->ds_quota != 0 &&
+	    dsl_dataset_phys(clone)->ds_referenced_bytes >
+	    origin_head->ds_quota)
+		return (SET_ERROR(EDQUOT));
+
+	return (0);
+}
+
+void
+dsl_dataset_clone_swap_sync_impl(dsl_dataset_t *clone,
+    dsl_dataset_t *origin_head, dmu_tx_t *tx)
+{
+	dsl_pool_t *dp = dmu_tx_pool(tx);
+	int64_t unused_refres_delta;
+
+	ASSERT(clone->ds_reserved == 0);
+	ASSERT(origin_head->ds_quota == 0 ||
+	    dsl_dataset_phys(clone)->ds_unique_bytes <= origin_head->ds_quota);
+	ASSERT3P(clone->ds_prev, ==, origin_head->ds_prev);
+
+	dmu_buf_will_dirty(clone->ds_dbuf, tx);
+	dmu_buf_will_dirty(origin_head->ds_dbuf, tx);
+
+	if (clone->ds_objset != NULL) {
+		dmu_objset_evict(clone->ds_objset);
+		clone->ds_objset = NULL;
+	}
+
+	if (origin_head->ds_objset != NULL) {
+		dmu_objset_evict(origin_head->ds_objset);
+		origin_head->ds_objset = NULL;
+	}
+
+	unused_refres_delta =
+	    (int64_t)MIN(origin_head->ds_reserved,
+	    dsl_dataset_phys(origin_head)->ds_unique_bytes) -
+	    (int64_t)MIN(origin_head->ds_reserved,
+	    dsl_dataset_phys(clone)->ds_unique_bytes);
+
+	/*
+	 * Reset origin's unique bytes, if it exists.
+	 */
+	if (clone->ds_prev) {
+		dsl_dataset_t *origin = clone->ds_prev;
+		uint64_t comp, uncomp;
+
+		dmu_buf_will_dirty(origin->ds_dbuf, tx);
+		dsl_deadlist_space_range(&clone->ds_deadlist,
+		    dsl_dataset_phys(origin)->ds_prev_snap_txg, UINT64_MAX,
+		    &dsl_dataset_phys(origin)->ds_unique_bytes, &comp, &uncomp);
+	}
+
+	/* swap blkptrs */
+	{
+		blkptr_t tmp;
+		tmp = dsl_dataset_phys(origin_head)->ds_bp;
+		dsl_dataset_phys(origin_head)->ds_bp =
+		    dsl_dataset_phys(clone)->ds_bp;
+		dsl_dataset_phys(clone)->ds_bp = tmp;
+	}
+
+	/* set dd_*_bytes */
+	{
+		int64_t dused, dcomp, duncomp;
+		uint64_t cdl_used, cdl_comp, cdl_uncomp;
+		uint64_t odl_used, odl_comp, odl_uncomp;
+
+		ASSERT3U(dsl_dir_phys(clone->ds_dir)->
+		    dd_used_breakdown[DD_USED_SNAP], ==, 0);
+
+		dsl_deadlist_space(&clone->ds_deadlist,
+		    &cdl_used, &cdl_comp, &cdl_uncomp);
+		dsl_deadlist_space(&origin_head->ds_deadlist,
+		    &odl_used, &odl_comp, &odl_uncomp);
+
+		dused = dsl_dataset_phys(clone)->ds_referenced_bytes +
+		    cdl_used -
+		    (dsl_dataset_phys(origin_head)->ds_referenced_bytes +
+		    odl_used);
+		dcomp = dsl_dataset_phys(clone)->ds_compressed_bytes +
+		    cdl_comp -
+		    (dsl_dataset_phys(origin_head)->ds_compressed_bytes +
+		    odl_comp);
+		duncomp = dsl_dataset_phys(clone)->ds_uncompressed_bytes +
+		    cdl_uncomp -
+		    (dsl_dataset_phys(origin_head)->ds_uncompressed_bytes +
+		    odl_uncomp);
+
+		dsl_dir_diduse_space(origin_head->ds_dir, DD_USED_HEAD,
+		    dused, dcomp, duncomp, tx);
+		dsl_dir_diduse_space(clone->ds_dir, DD_USED_HEAD,
+		    -dused, -dcomp, -duncomp, tx);
+
+		/*
+		 * The difference in the space used by snapshots is the
+		 * difference in snapshot space due to the head's
+		 * deadlist (since that's the only thing that's
+		 * changing that affects the snapused).
+		 */
+		dsl_deadlist_space_range(&clone->ds_deadlist,
+		    origin_head->ds_dir->dd_origin_txg, UINT64_MAX,
+		    &cdl_used, &cdl_comp, &cdl_uncomp);
+		dsl_deadlist_space_range(&origin_head->ds_deadlist,
+		    origin_head->ds_dir->dd_origin_txg, UINT64_MAX,
+		    &odl_used, &odl_comp, &odl_uncomp);
+		dsl_dir_transfer_space(origin_head->ds_dir, cdl_used - odl_used,
+		    DD_USED_HEAD, DD_USED_SNAP, tx);
+	}
+
+	/* swap ds_*_bytes */
+	SWITCH64(dsl_dataset_phys(origin_head)->ds_referenced_bytes,
+	    dsl_dataset_phys(clone)->ds_referenced_bytes);
+	SWITCH64(dsl_dataset_phys(origin_head)->ds_compressed_bytes,
+	    dsl_dataset_phys(clone)->ds_compressed_bytes);
+	SWITCH64(dsl_dataset_phys(origin_head)->ds_uncompressed_bytes,
+	    dsl_dataset_phys(clone)->ds_uncompressed_bytes);
+	SWITCH64(dsl_dataset_phys(origin_head)->ds_unique_bytes,
+	    dsl_dataset_phys(clone)->ds_unique_bytes);
+
+	/* apply any parent delta for change in unconsumed refreservation */
+	dsl_dir_diduse_space(origin_head->ds_dir, DD_USED_REFRSRV,
+	    unused_refres_delta, 0, 0, tx);
+
+	/*
+	 * Swap deadlists.
+	 */
+	dsl_deadlist_close(&clone->ds_deadlist);
+	dsl_deadlist_close(&origin_head->ds_deadlist);
+	SWITCH64(dsl_dataset_phys(origin_head)->ds_deadlist_obj,
+	    dsl_dataset_phys(clone)->ds_deadlist_obj);
+	dsl_deadlist_open(&clone->ds_deadlist, dp->dp_meta_objset,
+	    dsl_dataset_phys(clone)->ds_deadlist_obj);
+	dsl_deadlist_open(&origin_head->ds_deadlist, dp->dp_meta_objset,
+	    dsl_dataset_phys(origin_head)->ds_deadlist_obj);
+
+	dsl_scan_ds_clone_swapped(origin_head, clone, tx);
+
+	spa_history_log_internal_ds(clone, "clone swap", tx,
+	    "parent=%s", origin_head->ds_dir->dd_myname);
+}
+
+/*
+ * Given a pool name and a dataset object number in that pool,
+ * return the name of that dataset.
+ */
+int
+dsl_dsobj_to_dsname(char *pname, uint64_t obj, char *buf)
+{
+	dsl_pool_t *dp;
+	dsl_dataset_t *ds;
+	int error;
+
+	error = dsl_pool_hold(pname, FTAG, &dp);
+	if (error != 0)
+		return (error);
+
+	error = dsl_dataset_hold_obj(dp, obj, FTAG, &ds);
+	if (error == 0) {
+		dsl_dataset_name(ds, buf);
+		dsl_dataset_rele(ds, FTAG);
+	}
+	dsl_pool_rele(dp, FTAG);
+
+	return (error);
+}
+
+int
+dsl_dataset_check_quota(dsl_dataset_t *ds, boolean_t check_quota,
+    uint64_t asize, uint64_t inflight, uint64_t *used, uint64_t *ref_rsrv)
+{
+	int error = 0;
+
+	ASSERT3S(asize, >, 0);
+
+	/*
+	 * *ref_rsrv is the portion of asize that will come from any
+	 * unconsumed refreservation space.
+	 */
+	*ref_rsrv = 0;
+
+	mutex_enter(&ds->ds_lock);
+	/*
+	 * Make a space adjustment for reserved bytes.
+	 */
+	if (ds->ds_reserved > dsl_dataset_phys(ds)->ds_unique_bytes) {
+		ASSERT3U(*used, >=,
+		    ds->ds_reserved - dsl_dataset_phys(ds)->ds_unique_bytes);
+		*used -=
+		    (ds->ds_reserved - dsl_dataset_phys(ds)->ds_unique_bytes);
+		*ref_rsrv =
+		    asize - MIN(asize, parent_delta(ds, asize + inflight));
+	}
+
+	if (!check_quota || ds->ds_quota == 0) {
+		mutex_exit(&ds->ds_lock);
+		return (0);
+	}
+	/*
+	 * If they are requesting more space, and our current estimate
+	 * is over quota, they get to try again unless the actual
+	 * on-disk is over quota and there are no pending changes (which
+	 * may free up space for us).
+	 */
+	if (dsl_dataset_phys(ds)->ds_referenced_bytes + inflight >=
+	    ds->ds_quota) {
+		if (inflight > 0 ||
+		    dsl_dataset_phys(ds)->ds_referenced_bytes < ds->ds_quota)
+			error = SET_ERROR(ERESTART);
+		else
+			error = SET_ERROR(EDQUOT);
+	}
+	mutex_exit(&ds->ds_lock);
+
+	return (error);
+}
+
+typedef struct dsl_dataset_set_qr_arg {
+	const char *ddsqra_name;
+	zprop_source_t ddsqra_source;
+	uint64_t ddsqra_value;
+} dsl_dataset_set_qr_arg_t;
+
+
+/* ARGSUSED */
+static int
+dsl_dataset_set_refquota_check(void *arg, dmu_tx_t *tx)
+{
+	dsl_dataset_set_qr_arg_t *ddsqra = arg;
+	dsl_pool_t *dp = dmu_tx_pool(tx);
+	dsl_dataset_t *ds;
+	int error;
+	uint64_t newval;
+
+	if (spa_version(dp->dp_spa) < SPA_VERSION_REFQUOTA)
+		return (SET_ERROR(ENOTSUP));
+
+	error = dsl_dataset_hold(dp, ddsqra->ddsqra_name, FTAG, &ds);
+	if (error != 0)
+		return (error);
+
+	if (ds->ds_is_snapshot) {
+		dsl_dataset_rele(ds, FTAG);
+		return (SET_ERROR(EINVAL));
+	}
+
+	error = dsl_prop_predict(ds->ds_dir,
+	    zfs_prop_to_name(ZFS_PROP_REFQUOTA),
+	    ddsqra->ddsqra_source, ddsqra->ddsqra_value, &newval);
+	if (error != 0) {
+		dsl_dataset_rele(ds, FTAG);
+		return (error);
+	}
+
+	if (newval == 0) {
+		dsl_dataset_rele(ds, FTAG);
+		return (0);
+	}
+
+	if (newval < dsl_dataset_phys(ds)->ds_referenced_bytes ||
+	    newval < ds->ds_reserved) {
+		dsl_dataset_rele(ds, FTAG);
+		return (SET_ERROR(ENOSPC));
+	}
+
+	dsl_dataset_rele(ds, FTAG);
+	return (0);
+}
+
+static void
+dsl_dataset_set_refquota_sync(void *arg, dmu_tx_t *tx)
+{
+	dsl_dataset_set_qr_arg_t *ddsqra = arg;
+	dsl_pool_t *dp = dmu_tx_pool(tx);
+	dsl_dataset_t *ds;
+	uint64_t newval;
+
+	VERIFY0(dsl_dataset_hold(dp, ddsqra->ddsqra_name, FTAG, &ds));
+
+	dsl_prop_set_sync_impl(ds,
+	    zfs_prop_to_name(ZFS_PROP_REFQUOTA),
+	    ddsqra->ddsqra_source, sizeof (ddsqra->ddsqra_value), 1,
+	    &ddsqra->ddsqra_value, tx);
+
+	VERIFY0(dsl_prop_get_int_ds(ds,
+	    zfs_prop_to_name(ZFS_PROP_REFQUOTA), &newval));
+
+	if (ds->ds_quota != newval) {
+		dmu_buf_will_dirty(ds->ds_dbuf, tx);
+		ds->ds_quota = newval;
+	}
+	dsl_dataset_rele(ds, FTAG);
+}
+
+int
+dsl_dataset_set_refquota(const char *dsname, zprop_source_t source,
+    uint64_t refquota)
+{
+	dsl_dataset_set_qr_arg_t ddsqra;
+
+	ddsqra.ddsqra_name = dsname;
+	ddsqra.ddsqra_source = source;
+	ddsqra.ddsqra_value = refquota;
+
+	return (dsl_sync_task(dsname, dsl_dataset_set_refquota_check,
+	    dsl_dataset_set_refquota_sync, &ddsqra, 0, ZFS_SPACE_CHECK_NONE));
+}
+
+static int
+dsl_dataset_set_refreservation_check(void *arg, dmu_tx_t *tx)
+{
+	dsl_dataset_set_qr_arg_t *ddsqra = arg;
+	dsl_pool_t *dp = dmu_tx_pool(tx);
+	dsl_dataset_t *ds;
+	int error;
+	uint64_t newval, unique;
+
+	if (spa_version(dp->dp_spa) < SPA_VERSION_REFRESERVATION)
+		return (SET_ERROR(ENOTSUP));
+
+	error = dsl_dataset_hold(dp, ddsqra->ddsqra_name, FTAG, &ds);
+	if (error != 0)
+		return (error);
+
+	if (ds->ds_is_snapshot) {
+		dsl_dataset_rele(ds, FTAG);
+		return (SET_ERROR(EINVAL));
+	}
+
+	error = dsl_prop_predict(ds->ds_dir,
+	    zfs_prop_to_name(ZFS_PROP_REFRESERVATION),
+	    ddsqra->ddsqra_source, ddsqra->ddsqra_value, &newval);
+	if (error != 0) {
+		dsl_dataset_rele(ds, FTAG);
+		return (error);
+	}
+
+	/*
+	 * If we are doing the preliminary check in open context, the
+	 * space estimates may be inaccurate.
+	 */
+	if (!dmu_tx_is_syncing(tx)) {
+		dsl_dataset_rele(ds, FTAG);
+		return (0);
+	}
+
+	mutex_enter(&ds->ds_lock);
+	if (!DS_UNIQUE_IS_ACCURATE(ds))
+		dsl_dataset_recalc_head_uniq(ds);
+	unique = dsl_dataset_phys(ds)->ds_unique_bytes;
+	mutex_exit(&ds->ds_lock);
+
+	if (MAX(unique, newval) > MAX(unique, ds->ds_reserved)) {
+		uint64_t delta = MAX(unique, newval) -
+		    MAX(unique, ds->ds_reserved);
+
+		if (delta >
+		    dsl_dir_space_available(ds->ds_dir, NULL, 0, B_TRUE) ||
+		    (ds->ds_quota > 0 && newval > ds->ds_quota)) {
+			dsl_dataset_rele(ds, FTAG);
+			return (SET_ERROR(ENOSPC));
+		}
+	}
+
+	dsl_dataset_rele(ds, FTAG);
+	return (0);
+}
+
+void
+dsl_dataset_set_refreservation_sync_impl(dsl_dataset_t *ds,
+    zprop_source_t source, uint64_t value, dmu_tx_t *tx)
+{
+	uint64_t newval;
+	uint64_t unique;
+	int64_t delta;
+
+	dsl_prop_set_sync_impl(ds, zfs_prop_to_name(ZFS_PROP_REFRESERVATION),
+	    source, sizeof (value), 1, &value, tx);
+
+	VERIFY0(dsl_prop_get_int_ds(ds,
+	    zfs_prop_to_name(ZFS_PROP_REFRESERVATION), &newval));
+
+	dmu_buf_will_dirty(ds->ds_dbuf, tx);
+	mutex_enter(&ds->ds_dir->dd_lock);
+	mutex_enter(&ds->ds_lock);
+	ASSERT(DS_UNIQUE_IS_ACCURATE(ds));
+	unique = dsl_dataset_phys(ds)->ds_unique_bytes;
+	delta = MAX(0, (int64_t)(newval - unique)) -
+	    MAX(0, (int64_t)(ds->ds_reserved - unique));
+	ds->ds_reserved = newval;
+	mutex_exit(&ds->ds_lock);
+
+	dsl_dir_diduse_space(ds->ds_dir, DD_USED_REFRSRV, delta, 0, 0, tx);
+	mutex_exit(&ds->ds_dir->dd_lock);
+}
+
+static void
+dsl_dataset_set_refreservation_sync(void *arg, dmu_tx_t *tx)
+{
+	dsl_dataset_set_qr_arg_t *ddsqra = arg;
+	dsl_pool_t *dp = dmu_tx_pool(tx);
+	dsl_dataset_t *ds;
+
+	VERIFY0(dsl_dataset_hold(dp, ddsqra->ddsqra_name, FTAG, &ds));
+	dsl_dataset_set_refreservation_sync_impl(ds,
+	    ddsqra->ddsqra_source, ddsqra->ddsqra_value, tx);
+	dsl_dataset_rele(ds, FTAG);
+}
+
+int
+dsl_dataset_set_refreservation(const char *dsname, zprop_source_t source,
+    uint64_t refreservation)
+{
+	dsl_dataset_set_qr_arg_t ddsqra;
+
+	ddsqra.ddsqra_name = dsname;
+	ddsqra.ddsqra_source = source;
+	ddsqra.ddsqra_value = refreservation;
+
+	return (dsl_sync_task(dsname, dsl_dataset_set_refreservation_check,
+	    dsl_dataset_set_refreservation_sync, &ddsqra,
+	    0, ZFS_SPACE_CHECK_NONE));
+}
+
+/*
+ * Return (in *usedp) the amount of space written in new that is not
+ * present in oldsnap.  New may be a snapshot or the head.  Old must be
+ * a snapshot before new, in new's filesystem (or its origin).  If not then
+ * fail and return EINVAL.
+ *
+ * The written space is calculated by considering two components:  First, we
+ * ignore any freed space, and calculate the written as new's used space
+ * minus old's used space.  Next, we add in the amount of space that was freed
+ * between the two snapshots, thus reducing new's used space relative to old's.
+ * Specifically, this is the space that was born before old->ds_creation_txg,
+ * and freed before new (ie. on new's deadlist or a previous deadlist).
+ *
+ * space freed                         [---------------------]
+ * snapshots                       ---O-------O--------O-------O------
+ *                                         oldsnap            new
+ */
+int
+dsl_dataset_space_written(dsl_dataset_t *oldsnap, dsl_dataset_t *new,
+    uint64_t *usedp, uint64_t *compp, uint64_t *uncompp)
+{
+	int err = 0;
+	uint64_t snapobj;
+	dsl_pool_t *dp = new->ds_dir->dd_pool;
+
+	ASSERT(dsl_pool_config_held(dp));
+
+	*usedp = 0;
+	*usedp += dsl_dataset_phys(new)->ds_referenced_bytes;
+	*usedp -= dsl_dataset_phys(oldsnap)->ds_referenced_bytes;
+
+	*compp = 0;
+	*compp += dsl_dataset_phys(new)->ds_compressed_bytes;
+	*compp -= dsl_dataset_phys(oldsnap)->ds_compressed_bytes;
+
+	*uncompp = 0;
+	*uncompp += dsl_dataset_phys(new)->ds_uncompressed_bytes;
+	*uncompp -= dsl_dataset_phys(oldsnap)->ds_uncompressed_bytes;
+
+	snapobj = new->ds_object;
+	while (snapobj != oldsnap->ds_object) {
+		dsl_dataset_t *snap;
+		uint64_t used, comp, uncomp;
+
+		if (snapobj == new->ds_object) {
+			snap = new;
+		} else {
+			err = dsl_dataset_hold_obj(dp, snapobj, FTAG, &snap);
+			if (err != 0)
+				break;
+		}
+
+		if (dsl_dataset_phys(snap)->ds_prev_snap_txg ==
+		    dsl_dataset_phys(oldsnap)->ds_creation_txg) {
+			/*
+			 * The blocks in the deadlist can not be born after
+			 * ds_prev_snap_txg, so get the whole deadlist space,
+			 * which is more efficient (especially for old-format
+			 * deadlists).  Unfortunately the deadlist code
+			 * doesn't have enough information to make this
+			 * optimization itself.
+			 */
+			dsl_deadlist_space(&snap->ds_deadlist,
+			    &used, &comp, &uncomp);
+		} else {
+			dsl_deadlist_space_range(&snap->ds_deadlist,
+			    0, dsl_dataset_phys(oldsnap)->ds_creation_txg,
+			    &used, &comp, &uncomp);
+		}
+		*usedp += used;
+		*compp += comp;
+		*uncompp += uncomp;
+
+		/*
+		 * If we get to the beginning of the chain of snapshots
+		 * (ds_prev_snap_obj == 0) before oldsnap, then oldsnap
+		 * was not a snapshot of/before new.
+		 */
+		snapobj = dsl_dataset_phys(snap)->ds_prev_snap_obj;
+		if (snap != new)
+			dsl_dataset_rele(snap, FTAG);
+		if (snapobj == 0) {
+			err = SET_ERROR(EINVAL);
+			break;
+		}
+
+	}
+	return (err);
+}
+
+/*
+ * Return (in *usedp) the amount of space that will be reclaimed if firstsnap,
+ * lastsnap, and all snapshots in between are deleted.
+ *
+ * blocks that would be freed            [---------------------------]
+ * snapshots                       ---O-------O--------O-------O--------O
+ *                                        firstsnap        lastsnap
+ *
+ * This is the set of blocks that were born after the snap before firstsnap,
+ * (birth > firstsnap->prev_snap_txg) and died before the snap after the
+ * last snap (ie, is on lastsnap->ds_next->ds_deadlist or an earlier deadlist).
+ * We calculate this by iterating over the relevant deadlists (from the snap
+ * after lastsnap, backward to the snap after firstsnap), summing up the
+ * space on the deadlist that was born after the snap before firstsnap.
+ */
+int
+dsl_dataset_space_wouldfree(dsl_dataset_t *firstsnap,
+    dsl_dataset_t *lastsnap,
+    uint64_t *usedp, uint64_t *compp, uint64_t *uncompp)
+{
+	int err = 0;
+	uint64_t snapobj;
+	dsl_pool_t *dp = firstsnap->ds_dir->dd_pool;
+
+	ASSERT(firstsnap->ds_is_snapshot);
+	ASSERT(lastsnap->ds_is_snapshot);
+
+	/*
+	 * Check that the snapshots are in the same dsl_dir, and firstsnap
+	 * is before lastsnap.
+	 */
+	if (firstsnap->ds_dir != lastsnap->ds_dir ||
+	    dsl_dataset_phys(firstsnap)->ds_creation_txg >
+	    dsl_dataset_phys(lastsnap)->ds_creation_txg)
+		return (SET_ERROR(EINVAL));
+
+	*usedp = *compp = *uncompp = 0;
+
+	snapobj = dsl_dataset_phys(lastsnap)->ds_next_snap_obj;
+	while (snapobj != firstsnap->ds_object) {
+		dsl_dataset_t *ds;
+		uint64_t used, comp, uncomp;
+
+		err = dsl_dataset_hold_obj(dp, snapobj, FTAG, &ds);
+		if (err != 0)
+			break;
+
+		dsl_deadlist_space_range(&ds->ds_deadlist,
+		    dsl_dataset_phys(firstsnap)->ds_prev_snap_txg, UINT64_MAX,
+		    &used, &comp, &uncomp);
+		*usedp += used;
+		*compp += comp;
+		*uncompp += uncomp;
+
+		snapobj = dsl_dataset_phys(ds)->ds_prev_snap_obj;
+		ASSERT3U(snapobj, !=, 0);
+		dsl_dataset_rele(ds, FTAG);
+	}
+	return (err);
+}
+
+static int
+dsl_dataset_activate_large_blocks_check(void *arg, dmu_tx_t *tx)
+{
+	const char *dsname = arg;
+	dsl_dataset_t *ds;
+	dsl_pool_t *dp = dmu_tx_pool(tx);
+	int error = 0;
+
+	if (!spa_feature_is_enabled(dp->dp_spa, SPA_FEATURE_LARGE_BLOCKS))
+		return (SET_ERROR(ENOTSUP));
+
+	ASSERT(spa_feature_is_enabled(dp->dp_spa,
+	    SPA_FEATURE_EXTENSIBLE_DATASET));
+
+	error = dsl_dataset_hold(dp, dsname, FTAG, &ds);
+	if (error != 0)
+		return (error);
+
+	if (ds->ds_large_blocks)
+		error = EALREADY;
+	dsl_dataset_rele(ds, FTAG);
+
+	return (error);
+}
+
+void
+dsl_dataset_activate_large_blocks_sync_impl(uint64_t dsobj, dmu_tx_t *tx)
+{
+	spa_t *spa = dmu_tx_pool(tx)->dp_spa;
+	objset_t *mos = dmu_tx_pool(tx)->dp_meta_objset;
+	uint64_t zero = 0;
+
+	spa_feature_incr(spa, SPA_FEATURE_LARGE_BLOCKS, tx);
+	dmu_object_zapify(mos, dsobj, DMU_OT_DSL_DATASET, tx);
+
+	VERIFY0(zap_add(mos, dsobj, DS_FIELD_LARGE_BLOCKS,
+	    sizeof (zero), 1, &zero, tx));
+}
+
+static void
+dsl_dataset_activate_large_blocks_sync(void *arg, dmu_tx_t *tx)
+{
+	const char *dsname = arg;
+	dsl_dataset_t *ds;
+
+	VERIFY0(dsl_dataset_hold(dmu_tx_pool(tx), dsname, FTAG, &ds));
+
+	dsl_dataset_activate_large_blocks_sync_impl(ds->ds_object, tx);
+	ASSERT(!ds->ds_large_blocks);
+	ds->ds_large_blocks = B_TRUE;
+	dsl_dataset_rele(ds, FTAG);
+}
+
+int
+dsl_dataset_activate_large_blocks(const char *dsname)
+{
+	int error;
+
+	error = dsl_sync_task(dsname,
+	    dsl_dataset_activate_large_blocks_check,
+	    dsl_dataset_activate_large_blocks_sync, (void *)dsname,
+	    1, ZFS_SPACE_CHECK_RESERVED);
+
+	/*
+	 * EALREADY indicates that this dataset already supports large blocks.
+	 */
+	if (error == EALREADY)
+		error = 0;
+	return (error);
+}
+
+/*
+ * Return TRUE if 'earlier' is an earlier snapshot in 'later's timeline.
+ * For example, they could both be snapshots of the same filesystem, and
+ * 'earlier' is before 'later'.  Or 'earlier' could be the origin of
+ * 'later's filesystem.  Or 'earlier' could be an older snapshot in the origin's
+ * filesystem.  Or 'earlier' could be the origin's origin.
+ *
+ * If non-zero, earlier_txg is used instead of earlier's ds_creation_txg.
+ */
+boolean_t
+dsl_dataset_is_before(dsl_dataset_t *later, dsl_dataset_t *earlier,
+	uint64_t earlier_txg)
+{
+	dsl_pool_t *dp = later->ds_dir->dd_pool;
+	int error;
+	boolean_t ret;
+	dsl_dataset_t *origin;
+
+	ASSERT(dsl_pool_config_held(dp));
+	ASSERT(earlier->ds_is_snapshot || earlier_txg != 0);
+
+	if (earlier_txg == 0)
+		earlier_txg = dsl_dataset_phys(earlier)->ds_creation_txg;
+
+	if (later->ds_is_snapshot &&
+	    earlier_txg >= dsl_dataset_phys(later)->ds_creation_txg)
+		return (B_FALSE);
+
+	if (later->ds_dir == earlier->ds_dir)
+		return (B_TRUE);
+	if (!dsl_dir_is_clone(later->ds_dir))
+		return (B_FALSE);
+
+	if (dsl_dir_phys(later->ds_dir)->dd_origin_obj == earlier->ds_object)
+		return (B_TRUE);
+	error = dsl_dataset_hold_obj(dp,
+	    dsl_dir_phys(later->ds_dir)->dd_origin_obj, FTAG, &origin);
+	if (error != 0)
+		return (B_FALSE);
+	ret = dsl_dataset_is_before(origin, earlier, earlier_txg);
+	dsl_dataset_rele(origin, FTAG);
+	return (ret);
+}
+
+
+void
+dsl_dataset_zapify(dsl_dataset_t *ds, dmu_tx_t *tx)
+{
+	objset_t *mos = ds->ds_dir->dd_pool->dp_meta_objset;
+	dmu_object_zapify(mos, ds->ds_object, DMU_OT_DSL_DATASET, tx);
+}
+
+#if defined(_KERNEL) && defined(HAVE_SPL)
+#if defined(_LP64)
+module_param(zfs_max_recordsize, int, 0644);
+MODULE_PARM_DESC(zfs_max_recordsize, "Max allowed record size");
+#else
+/* Limited to 1M on 32-bit platforms due to lack of virtual address space */
+module_param(zfs_max_recordsize, int, 0444);
+MODULE_PARM_DESC(zfs_max_recordsize, "Max allowed record size");
+#endif
+
+EXPORT_SYMBOL(dsl_dataset_hold);
+EXPORT_SYMBOL(dsl_dataset_hold_obj);
+EXPORT_SYMBOL(dsl_dataset_own);
+EXPORT_SYMBOL(dsl_dataset_own_obj);
+EXPORT_SYMBOL(dsl_dataset_name);
+EXPORT_SYMBOL(dsl_dataset_rele);
+EXPORT_SYMBOL(dsl_dataset_disown);
+EXPORT_SYMBOL(dsl_dataset_tryown);
+EXPORT_SYMBOL(dsl_dataset_create_sync);
+EXPORT_SYMBOL(dsl_dataset_create_sync_dd);
+EXPORT_SYMBOL(dsl_dataset_snapshot_check);
+EXPORT_SYMBOL(dsl_dataset_snapshot_sync);
+EXPORT_SYMBOL(dsl_dataset_promote);
+EXPORT_SYMBOL(dsl_dataset_user_hold);
+EXPORT_SYMBOL(dsl_dataset_user_release);
+EXPORT_SYMBOL(dsl_dataset_get_holds);
+EXPORT_SYMBOL(dsl_dataset_get_blkptr);
+EXPORT_SYMBOL(dsl_dataset_set_blkptr);
+EXPORT_SYMBOL(dsl_dataset_get_spa);
+EXPORT_SYMBOL(dsl_dataset_modified_since_snap);
+EXPORT_SYMBOL(dsl_dataset_space_written);
+EXPORT_SYMBOL(dsl_dataset_space_wouldfree);
+EXPORT_SYMBOL(dsl_dataset_sync);
+EXPORT_SYMBOL(dsl_dataset_block_born);
+EXPORT_SYMBOL(dsl_dataset_block_kill);
+EXPORT_SYMBOL(dsl_dataset_block_freeable);
+EXPORT_SYMBOL(dsl_dataset_prev_snap_txg);
+EXPORT_SYMBOL(dsl_dataset_dirty);
+EXPORT_SYMBOL(dsl_dataset_stats);
+EXPORT_SYMBOL(dsl_dataset_fast_stat);
+EXPORT_SYMBOL(dsl_dataset_space);
+EXPORT_SYMBOL(dsl_dataset_fsid_guid);
+EXPORT_SYMBOL(dsl_dsobj_to_dsname);
+EXPORT_SYMBOL(dsl_dataset_check_quota);
+EXPORT_SYMBOL(dsl_dataset_clone_swap_check_impl);
+EXPORT_SYMBOL(dsl_dataset_clone_swap_sync_impl);
+#endif
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/module/zfs/dsl_deadlist.c
@@ -0,0 +1,540 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012 by Delphix. All rights reserved.
+ * Copyright (c) 2014 Spectra Logic Corporation, All rights reserved.
+ */
+
+#include <sys/dsl_dataset.h>
+#include <sys/dmu.h>
+#include <sys/refcount.h>
+#include <sys/zap.h>
+#include <sys/zfs_context.h>
+#include <sys/dsl_pool.h>
+
+/*
+ * Deadlist concurrency:
+ *
+ * Deadlists can only be modified from the syncing thread.
+ *
+ * Except for dsl_deadlist_insert(), it can only be modified with the
+ * dp_config_rwlock held with RW_WRITER.
+ *
+ * The accessors (dsl_deadlist_space() and dsl_deadlist_space_range()) can
+ * be called concurrently, from open context, with the dl_config_rwlock held
+ * with RW_READER.
+ *
+ * Therefore, we only need to provide locking between dsl_deadlist_insert() and
+ * the accessors, protecting:
+ *     dl_phys->dl_used,comp,uncomp
+ *     and protecting the dl_tree from being loaded.
+ * The locking is provided by dl_lock.  Note that locking on the bpobj_t
+ * provides its own locking, and dl_oldfmt is immutable.
+ */
+
+static int
+dsl_deadlist_compare(const void *arg1, const void *arg2)
+{
+	const dsl_deadlist_entry_t *dle1 = arg1;
+	const dsl_deadlist_entry_t *dle2 = arg2;
+
+	if (dle1->dle_mintxg < dle2->dle_mintxg)
+		return (-1);
+	else if (dle1->dle_mintxg > dle2->dle_mintxg)
+		return (+1);
+	else
+		return (0);
+}
+
+static void
+dsl_deadlist_load_tree(dsl_deadlist_t *dl)
+{
+	zap_cursor_t zc;
+	zap_attribute_t za;
+
+	ASSERT(!dl->dl_oldfmt);
+	if (dl->dl_havetree)
+		return;
+
+	avl_create(&dl->dl_tree, dsl_deadlist_compare,
+	    sizeof (dsl_deadlist_entry_t),
+	    offsetof(dsl_deadlist_entry_t, dle_node));
+	for (zap_cursor_init(&zc, dl->dl_os, dl->dl_object);
+	    zap_cursor_retrieve(&zc, &za) == 0;
+	    zap_cursor_advance(&zc)) {
+		dsl_deadlist_entry_t *dle;
+
+		dle = kmem_alloc(sizeof (*dle), KM_SLEEP);
+		dle->dle_mintxg = strtonum(za.za_name, NULL);
+		VERIFY3U(0, ==, bpobj_open(&dle->dle_bpobj, dl->dl_os,
+		    za.za_first_integer));
+		avl_add(&dl->dl_tree, dle);
+	}
+	zap_cursor_fini(&zc);
+	dl->dl_havetree = B_TRUE;
+}
+
+void
+dsl_deadlist_open(dsl_deadlist_t *dl, objset_t *os, uint64_t object)
+{
+	dmu_object_info_t doi;
+
+	mutex_init(&dl->dl_lock, NULL, MUTEX_DEFAULT, NULL);
+	dl->dl_os = os;
+	dl->dl_object = object;
+	VERIFY3U(0, ==, dmu_bonus_hold(os, object, dl, &dl->dl_dbuf));
+	dmu_object_info_from_db(dl->dl_dbuf, &doi);
+	if (doi.doi_type == DMU_OT_BPOBJ) {
+		dmu_buf_rele(dl->dl_dbuf, dl);
+		dl->dl_dbuf = NULL;
+		dl->dl_oldfmt = B_TRUE;
+		VERIFY3U(0, ==, bpobj_open(&dl->dl_bpobj, os, object));
+		return;
+	}
+
+	dl->dl_oldfmt = B_FALSE;
+	dl->dl_phys = dl->dl_dbuf->db_data;
+	dl->dl_havetree = B_FALSE;
+}
+
+void
+dsl_deadlist_close(dsl_deadlist_t *dl)
+{
+	void *cookie = NULL;
+	dsl_deadlist_entry_t *dle;
+
+	dl->dl_os = NULL;
+
+	if (dl->dl_oldfmt) {
+		dl->dl_oldfmt = B_FALSE;
+		bpobj_close(&dl->dl_bpobj);
+		return;
+	}
+
+	if (dl->dl_havetree) {
+		while ((dle = avl_destroy_nodes(&dl->dl_tree, &cookie))
+		    != NULL) {
+			bpobj_close(&dle->dle_bpobj);
+			kmem_free(dle, sizeof (*dle));
+		}
+		avl_destroy(&dl->dl_tree);
+	}
+	dmu_buf_rele(dl->dl_dbuf, dl);
+	mutex_destroy(&dl->dl_lock);
+	dl->dl_dbuf = NULL;
+	dl->dl_phys = NULL;
+}
+
+uint64_t
+dsl_deadlist_alloc(objset_t *os, dmu_tx_t *tx)
+{
+	if (spa_version(dmu_objset_spa(os)) < SPA_VERSION_DEADLISTS)
+		return (bpobj_alloc(os, SPA_OLD_MAXBLOCKSIZE, tx));
+	return (zap_create(os, DMU_OT_DEADLIST, DMU_OT_DEADLIST_HDR,
+	    sizeof (dsl_deadlist_phys_t), tx));
+}
+
+void
+dsl_deadlist_free(objset_t *os, uint64_t dlobj, dmu_tx_t *tx)
+{
+	dmu_object_info_t doi;
+	zap_cursor_t zc;
+	zap_attribute_t za;
+
+	VERIFY3U(0, ==, dmu_object_info(os, dlobj, &doi));
+	if (doi.doi_type == DMU_OT_BPOBJ) {
+		bpobj_free(os, dlobj, tx);
+		return;
+	}
+
+	for (zap_cursor_init(&zc, os, dlobj);
+	    zap_cursor_retrieve(&zc, &za) == 0;
+	    zap_cursor_advance(&zc)) {
+		uint64_t obj = za.za_first_integer;
+		if (obj == dmu_objset_pool(os)->dp_empty_bpobj)
+			bpobj_decr_empty(os, tx);
+		else
+			bpobj_free(os, obj, tx);
+	}
+	zap_cursor_fini(&zc);
+	VERIFY3U(0, ==, dmu_object_free(os, dlobj, tx));
+}
+
+static void
+dle_enqueue(dsl_deadlist_t *dl, dsl_deadlist_entry_t *dle,
+    const blkptr_t *bp, dmu_tx_t *tx)
+{
+	if (dle->dle_bpobj.bpo_object ==
+	    dmu_objset_pool(dl->dl_os)->dp_empty_bpobj) {
+		uint64_t obj = bpobj_alloc(dl->dl_os, SPA_OLD_MAXBLOCKSIZE, tx);
+		bpobj_close(&dle->dle_bpobj);
+		bpobj_decr_empty(dl->dl_os, tx);
+		VERIFY3U(0, ==, bpobj_open(&dle->dle_bpobj, dl->dl_os, obj));
+		VERIFY3U(0, ==, zap_update_int_key(dl->dl_os, dl->dl_object,
+		    dle->dle_mintxg, obj, tx));
+	}
+	bpobj_enqueue(&dle->dle_bpobj, bp, tx);
+}
+
+static void
+dle_enqueue_subobj(dsl_deadlist_t *dl, dsl_deadlist_entry_t *dle,
+    uint64_t obj, dmu_tx_t *tx)
+{
+	if (dle->dle_bpobj.bpo_object !=
+	    dmu_objset_pool(dl->dl_os)->dp_empty_bpobj) {
+		bpobj_enqueue_subobj(&dle->dle_bpobj, obj, tx);
+	} else {
+		bpobj_close(&dle->dle_bpobj);
+		bpobj_decr_empty(dl->dl_os, tx);
+		VERIFY3U(0, ==, bpobj_open(&dle->dle_bpobj, dl->dl_os, obj));
+		VERIFY3U(0, ==, zap_update_int_key(dl->dl_os, dl->dl_object,
+		    dle->dle_mintxg, obj, tx));
+	}
+}
+
+void
+dsl_deadlist_insert(dsl_deadlist_t *dl, const blkptr_t *bp, dmu_tx_t *tx)
+{
+	dsl_deadlist_entry_t dle_tofind;
+	dsl_deadlist_entry_t *dle;
+	avl_index_t where;
+
+	if (dl->dl_oldfmt) {
+		bpobj_enqueue(&dl->dl_bpobj, bp, tx);
+		return;
+	}
+
+	dsl_deadlist_load_tree(dl);
+
+	dmu_buf_will_dirty(dl->dl_dbuf, tx);
+	mutex_enter(&dl->dl_lock);
+	dl->dl_phys->dl_used +=
+	    bp_get_dsize_sync(dmu_objset_spa(dl->dl_os), bp);
+	dl->dl_phys->dl_comp += BP_GET_PSIZE(bp);
+	dl->dl_phys->dl_uncomp += BP_GET_UCSIZE(bp);
+	mutex_exit(&dl->dl_lock);
+
+	dle_tofind.dle_mintxg = bp->blk_birth;
+	dle = avl_find(&dl->dl_tree, &dle_tofind, &where);
+	if (dle == NULL)
+		dle = avl_nearest(&dl->dl_tree, where, AVL_BEFORE);
+	else
+		dle = AVL_PREV(&dl->dl_tree, dle);
+	dle_enqueue(dl, dle, bp, tx);
+}
+
+/*
+ * Insert new key in deadlist, which must be > all current entries.
+ * mintxg is not inclusive.
+ */
+void
+dsl_deadlist_add_key(dsl_deadlist_t *dl, uint64_t mintxg, dmu_tx_t *tx)
+{
+	uint64_t obj;
+	dsl_deadlist_entry_t *dle;
+
+	if (dl->dl_oldfmt)
+		return;
+
+	dsl_deadlist_load_tree(dl);
+
+	dle = kmem_alloc(sizeof (*dle), KM_SLEEP);
+	dle->dle_mintxg = mintxg;
+	obj = bpobj_alloc_empty(dl->dl_os, SPA_OLD_MAXBLOCKSIZE, tx);
+	VERIFY3U(0, ==, bpobj_open(&dle->dle_bpobj, dl->dl_os, obj));
+	avl_add(&dl->dl_tree, dle);
+
+	VERIFY3U(0, ==, zap_add_int_key(dl->dl_os, dl->dl_object,
+	    mintxg, obj, tx));
+}
+
+/*
+ * Remove this key, merging its entries into the previous key.
+ */
+void
+dsl_deadlist_remove_key(dsl_deadlist_t *dl, uint64_t mintxg, dmu_tx_t *tx)
+{
+	dsl_deadlist_entry_t dle_tofind;
+	dsl_deadlist_entry_t *dle, *dle_prev;
+
+	if (dl->dl_oldfmt)
+		return;
+
+	dsl_deadlist_load_tree(dl);
+
+	dle_tofind.dle_mintxg = mintxg;
+	dle = avl_find(&dl->dl_tree, &dle_tofind, NULL);
+	dle_prev = AVL_PREV(&dl->dl_tree, dle);
+
+	dle_enqueue_subobj(dl, dle_prev, dle->dle_bpobj.bpo_object, tx);
+
+	avl_remove(&dl->dl_tree, dle);
+	bpobj_close(&dle->dle_bpobj);
+	kmem_free(dle, sizeof (*dle));
+
+	VERIFY3U(0, ==, zap_remove_int(dl->dl_os, dl->dl_object, mintxg, tx));
+}
+
+/*
+ * Walk ds's snapshots to regenerate generate ZAP & AVL.
+ */
+static void
+dsl_deadlist_regenerate(objset_t *os, uint64_t dlobj,
+    uint64_t mrs_obj, dmu_tx_t *tx)
+{
+	dsl_deadlist_t dl;
+	dsl_pool_t *dp = dmu_objset_pool(os);
+
+	dsl_deadlist_open(&dl, os, dlobj);
+	if (dl.dl_oldfmt) {
+		dsl_deadlist_close(&dl);
+		return;
+	}
+
+	while (mrs_obj != 0) {
+		dsl_dataset_t *ds;
+		VERIFY3U(0, ==, dsl_dataset_hold_obj(dp, mrs_obj, FTAG, &ds));
+		dsl_deadlist_add_key(&dl,
+		    dsl_dataset_phys(ds)->ds_prev_snap_txg, tx);
+		mrs_obj = dsl_dataset_phys(ds)->ds_prev_snap_obj;
+		dsl_dataset_rele(ds, FTAG);
+	}
+	dsl_deadlist_close(&dl);
+}
+
+uint64_t
+dsl_deadlist_clone(dsl_deadlist_t *dl, uint64_t maxtxg,
+    uint64_t mrs_obj, dmu_tx_t *tx)
+{
+	dsl_deadlist_entry_t *dle;
+	uint64_t newobj;
+
+	newobj = dsl_deadlist_alloc(dl->dl_os, tx);
+
+	if (dl->dl_oldfmt) {
+		dsl_deadlist_regenerate(dl->dl_os, newobj, mrs_obj, tx);
+		return (newobj);
+	}
+
+	dsl_deadlist_load_tree(dl);
+
+	for (dle = avl_first(&dl->dl_tree); dle;
+	    dle = AVL_NEXT(&dl->dl_tree, dle)) {
+		uint64_t obj;
+
+		if (dle->dle_mintxg >= maxtxg)
+			break;
+
+		obj = bpobj_alloc_empty(dl->dl_os, SPA_OLD_MAXBLOCKSIZE, tx);
+		VERIFY3U(0, ==, zap_add_int_key(dl->dl_os, newobj,
+		    dle->dle_mintxg, obj, tx));
+	}
+	return (newobj);
+}
+
+void
+dsl_deadlist_space(dsl_deadlist_t *dl,
+    uint64_t *usedp, uint64_t *compp, uint64_t *uncompp)
+{
+	if (dl->dl_oldfmt) {
+		VERIFY3U(0, ==, bpobj_space(&dl->dl_bpobj,
+		    usedp, compp, uncompp));
+		return;
+	}
+
+	mutex_enter(&dl->dl_lock);
+	*usedp = dl->dl_phys->dl_used;
+	*compp = dl->dl_phys->dl_comp;
+	*uncompp = dl->dl_phys->dl_uncomp;
+	mutex_exit(&dl->dl_lock);
+}
+
+/*
+ * return space used in the range (mintxg, maxtxg].
+ * Includes maxtxg, does not include mintxg.
+ * mintxg and maxtxg must both be keys in the deadlist (unless maxtxg is
+ * larger than any bp in the deadlist (eg. UINT64_MAX)).
+ */
+void
+dsl_deadlist_space_range(dsl_deadlist_t *dl, uint64_t mintxg, uint64_t maxtxg,
+    uint64_t *usedp, uint64_t *compp, uint64_t *uncompp)
+{
+	dsl_deadlist_entry_t *dle;
+	dsl_deadlist_entry_t dle_tofind;
+	avl_index_t where;
+
+	if (dl->dl_oldfmt) {
+		VERIFY3U(0, ==, bpobj_space_range(&dl->dl_bpobj,
+		    mintxg, maxtxg, usedp, compp, uncompp));
+		return;
+	}
+
+	*usedp = *compp = *uncompp = 0;
+
+	mutex_enter(&dl->dl_lock);
+	dsl_deadlist_load_tree(dl);
+	dle_tofind.dle_mintxg = mintxg;
+	dle = avl_find(&dl->dl_tree, &dle_tofind, &where);
+	/*
+	 * If we don't find this mintxg, there shouldn't be anything
+	 * after it either.
+	 */
+	ASSERT(dle != NULL ||
+	    avl_nearest(&dl->dl_tree, where, AVL_AFTER) == NULL);
+
+	for (; dle && dle->dle_mintxg < maxtxg;
+	    dle = AVL_NEXT(&dl->dl_tree, dle)) {
+		uint64_t used, comp, uncomp;
+
+		VERIFY3U(0, ==, bpobj_space(&dle->dle_bpobj,
+		    &used, &comp, &uncomp));
+
+		*usedp += used;
+		*compp += comp;
+		*uncompp += uncomp;
+	}
+	mutex_exit(&dl->dl_lock);
+}
+
+static void
+dsl_deadlist_insert_bpobj(dsl_deadlist_t *dl, uint64_t obj, uint64_t birth,
+    dmu_tx_t *tx)
+{
+	dsl_deadlist_entry_t dle_tofind;
+	dsl_deadlist_entry_t *dle;
+	avl_index_t where;
+	uint64_t used, comp, uncomp;
+	bpobj_t bpo;
+
+	VERIFY3U(0, ==, bpobj_open(&bpo, dl->dl_os, obj));
+	VERIFY3U(0, ==, bpobj_space(&bpo, &used, &comp, &uncomp));
+	bpobj_close(&bpo);
+
+	dsl_deadlist_load_tree(dl);
+
+	dmu_buf_will_dirty(dl->dl_dbuf, tx);
+	mutex_enter(&dl->dl_lock);
+	dl->dl_phys->dl_used += used;
+	dl->dl_phys->dl_comp += comp;
+	dl->dl_phys->dl_uncomp += uncomp;
+	mutex_exit(&dl->dl_lock);
+
+	dle_tofind.dle_mintxg = birth;
+	dle = avl_find(&dl->dl_tree, &dle_tofind, &where);
+	if (dle == NULL)
+		dle = avl_nearest(&dl->dl_tree, where, AVL_BEFORE);
+	dle_enqueue_subobj(dl, dle, obj, tx);
+}
+
+static int
+dsl_deadlist_insert_cb(void *arg, const blkptr_t *bp, dmu_tx_t *tx)
+{
+	dsl_deadlist_t *dl = arg;
+	dsl_deadlist_insert(dl, bp, tx);
+	return (0);
+}
+
+/*
+ * Merge the deadlist pointed to by 'obj' into dl.  obj will be left as
+ * an empty deadlist.
+ */
+void
+dsl_deadlist_merge(dsl_deadlist_t *dl, uint64_t obj, dmu_tx_t *tx)
+{
+	zap_cursor_t zc;
+	zap_attribute_t za;
+	dmu_buf_t *bonus;
+	dsl_deadlist_phys_t *dlp;
+	dmu_object_info_t doi;
+
+	VERIFY3U(0, ==, dmu_object_info(dl->dl_os, obj, &doi));
+	if (doi.doi_type == DMU_OT_BPOBJ) {
+		bpobj_t bpo;
+		VERIFY3U(0, ==, bpobj_open(&bpo, dl->dl_os, obj));
+		VERIFY3U(0, ==, bpobj_iterate(&bpo,
+		    dsl_deadlist_insert_cb, dl, tx));
+		bpobj_close(&bpo);
+		return;
+	}
+
+	for (zap_cursor_init(&zc, dl->dl_os, obj);
+	    zap_cursor_retrieve(&zc, &za) == 0;
+	    zap_cursor_advance(&zc)) {
+		uint64_t mintxg = strtonum(za.za_name, NULL);
+		dsl_deadlist_insert_bpobj(dl, za.za_first_integer, mintxg, tx);
+		VERIFY3U(0, ==, zap_remove_int(dl->dl_os, obj, mintxg, tx));
+	}
+	zap_cursor_fini(&zc);
+
+	VERIFY3U(0, ==, dmu_bonus_hold(dl->dl_os, obj, FTAG, &bonus));
+	dlp = bonus->db_data;
+	dmu_buf_will_dirty(bonus, tx);
+	bzero(dlp, sizeof (*dlp));
+	dmu_buf_rele(bonus, FTAG);
+}
+
+/*
+ * Remove entries on dl that are >= mintxg, and put them on the bpobj.
+ */
+void
+dsl_deadlist_move_bpobj(dsl_deadlist_t *dl, bpobj_t *bpo, uint64_t mintxg,
+    dmu_tx_t *tx)
+{
+	dsl_deadlist_entry_t dle_tofind;
+	dsl_deadlist_entry_t *dle;
+	avl_index_t where;
+
+	ASSERT(!dl->dl_oldfmt);
+	dmu_buf_will_dirty(dl->dl_dbuf, tx);
+	dsl_deadlist_load_tree(dl);
+
+	dle_tofind.dle_mintxg = mintxg;
+	dle = avl_find(&dl->dl_tree, &dle_tofind, &where);
+	if (dle == NULL)
+		dle = avl_nearest(&dl->dl_tree, where, AVL_AFTER);
+	while (dle) {
+		uint64_t used, comp, uncomp;
+		dsl_deadlist_entry_t *dle_next;
+
+		bpobj_enqueue_subobj(bpo, dle->dle_bpobj.bpo_object, tx);
+
+		VERIFY3U(0, ==, bpobj_space(&dle->dle_bpobj,
+		    &used, &comp, &uncomp));
+		mutex_enter(&dl->dl_lock);
+		ASSERT3U(dl->dl_phys->dl_used, >=, used);
+		ASSERT3U(dl->dl_phys->dl_comp, >=, comp);
+		ASSERT3U(dl->dl_phys->dl_uncomp, >=, uncomp);
+		dl->dl_phys->dl_used -= used;
+		dl->dl_phys->dl_comp -= comp;
+		dl->dl_phys->dl_uncomp -= uncomp;
+		mutex_exit(&dl->dl_lock);
+
+		VERIFY3U(0, ==, zap_remove_int(dl->dl_os, dl->dl_object,
+		    dle->dle_mintxg, tx));
+
+		dle_next = AVL_NEXT(&dl->dl_tree, dle);
+		avl_remove(&dl->dl_tree, dle);
+		bpobj_close(&dle->dle_bpobj);
+		kmem_free(dle, sizeof (*dle));
+		dle = dle_next;
+	}
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/module/zfs/dsl_deleg.c
@@ -0,0 +1,775 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2014 by Delphix. All rights reserved.
+ */
+
+/*
+ * DSL permissions are stored in a two level zap attribute
+ * mechanism.   The first level identifies the "class" of
+ * entry.  The class is identified by the first 2 letters of
+ * the attribute.  The second letter "l" or "d" identifies whether
+ * it is a local or descendent permission.  The first letter
+ * identifies the type of entry.
+ *
+ * ul$<id>    identifies permissions granted locally for this userid.
+ * ud$<id>    identifies permissions granted on descendent datasets for
+ *            this userid.
+ * Ul$<id>    identifies permission sets granted locally for this userid.
+ * Ud$<id>    identifies permission sets granted on descendent datasets for
+ *            this userid.
+ * gl$<id>    identifies permissions granted locally for this groupid.
+ * gd$<id>    identifies permissions granted on descendent datasets for
+ *            this groupid.
+ * Gl$<id>    identifies permission sets granted locally for this groupid.
+ * Gd$<id>    identifies permission sets granted on descendent datasets for
+ *            this groupid.
+ * el$        identifies permissions granted locally for everyone.
+ * ed$        identifies permissions granted on descendent datasets
+ *            for everyone.
+ * El$        identifies permission sets granted locally for everyone.
+ * Ed$        identifies permission sets granted to descendent datasets for
+ *            everyone.
+ * c-$        identifies permission to create at dataset creation time.
+ * C-$        identifies permission sets to grant locally at dataset creation
+ *            time.
+ * s-$@<name> permissions defined in specified set @<name>
+ * S-$@<name> Sets defined in named set @<name>
+ *
+ * Each of the above entities points to another zap attribute that contains one
+ * attribute for each allowed permission, such as create, destroy,...
+ * All of the "upper" case class types will specify permission set names
+ * rather than permissions.
+ *
+ * Basically it looks something like this:
+ * ul$12 -> ZAP OBJ -> permissions...
+ *
+ * The ZAP OBJ is referred to as the jump object.
+ */
+
+#include <sys/dmu.h>
+#include <sys/dmu_objset.h>
+#include <sys/dmu_tx.h>
+#include <sys/dsl_dataset.h>
+#include <sys/dsl_dir.h>
+#include <sys/dsl_prop.h>
+#include <sys/dsl_synctask.h>
+#include <sys/dsl_deleg.h>
+#include <sys/spa.h>
+#include <sys/zap.h>
+#include <sys/fs/zfs.h>
+#include <sys/cred.h>
+#include <sys/sunddi.h>
+
+#include "zfs_deleg.h"
+
+/*
+ * Validate that user is allowed to delegate specified permissions.
+ *
+ * In order to delegate "create" you must have "create"
+ * and "allow".
+ */
+int
+dsl_deleg_can_allow(char *ddname, nvlist_t *nvp, cred_t *cr)
+{
+	nvpair_t *whopair = NULL;
+	int error;
+
+	if ((error = dsl_deleg_access(ddname, ZFS_DELEG_PERM_ALLOW, cr)) != 0)
+		return (error);
+
+	while ((whopair = nvlist_next_nvpair(nvp, whopair))) {
+		nvlist_t *perms;
+		nvpair_t *permpair = NULL;
+
+		VERIFY(nvpair_value_nvlist(whopair, &perms) == 0);
+
+		while ((permpair = nvlist_next_nvpair(perms, permpair))) {
+			const char *perm = nvpair_name(permpair);
+
+			if (strcmp(perm, ZFS_DELEG_PERM_ALLOW) == 0)
+				return (SET_ERROR(EPERM));
+
+			if ((error = dsl_deleg_access(ddname, perm, cr)) != 0)
+				return (error);
+		}
+	}
+	return (0);
+}
+
+/*
+ * Validate that user is allowed to unallow specified permissions.  They
+ * must have the 'allow' permission, and even then can only unallow
+ * perms for their uid.
+ */
+int
+dsl_deleg_can_unallow(char *ddname, nvlist_t *nvp, cred_t *cr)
+{
+	nvpair_t *whopair = NULL;
+	int error;
+	char idstr[32];
+
+	if ((error = dsl_deleg_access(ddname, ZFS_DELEG_PERM_ALLOW, cr)) != 0)
+		return (error);
+
+	(void) snprintf(idstr, sizeof (idstr), "%lld",
+	    (longlong_t)crgetuid(cr));
+
+	while ((whopair = nvlist_next_nvpair(nvp, whopair))) {
+		zfs_deleg_who_type_t type = nvpair_name(whopair)[0];
+
+		if (type != ZFS_DELEG_USER &&
+		    type != ZFS_DELEG_USER_SETS)
+			return (SET_ERROR(EPERM));
+
+		if (strcmp(idstr, &nvpair_name(whopair)[3]) != 0)
+			return (SET_ERROR(EPERM));
+	}
+	return (0);
+}
+
+typedef struct dsl_deleg_arg {
+	const char *dda_name;
+	nvlist_t *dda_nvlist;
+} dsl_deleg_arg_t;
+
+static void
+dsl_deleg_set_sync(void *arg, dmu_tx_t *tx)
+{
+	dsl_deleg_arg_t *dda = arg;
+	dsl_dir_t *dd;
+	dsl_pool_t *dp = dmu_tx_pool(tx);
+	objset_t *mos = dp->dp_meta_objset;
+	nvpair_t *whopair = NULL;
+	uint64_t zapobj;
+
+	VERIFY0(dsl_dir_hold(dp, dda->dda_name, FTAG, &dd, NULL));
+
+	zapobj = dsl_dir_phys(dd)->dd_deleg_zapobj;
+	if (zapobj == 0) {
+		dmu_buf_will_dirty(dd->dd_dbuf, tx);
+		zapobj = dsl_dir_phys(dd)->dd_deleg_zapobj = zap_create(mos,
+		    DMU_OT_DSL_PERMS, DMU_OT_NONE, 0, tx);
+	}
+
+	while ((whopair = nvlist_next_nvpair(dda->dda_nvlist, whopair))) {
+		const char *whokey = nvpair_name(whopair);
+		nvlist_t *perms;
+		nvpair_t *permpair = NULL;
+		uint64_t jumpobj;
+
+		perms = fnvpair_value_nvlist(whopair);
+
+		if (zap_lookup(mos, zapobj, whokey, 8, 1, &jumpobj) != 0) {
+			jumpobj = zap_create_link(mos, DMU_OT_DSL_PERMS,
+			    zapobj, whokey, tx);
+		}
+
+		while ((permpair = nvlist_next_nvpair(perms, permpair))) {
+			const char *perm = nvpair_name(permpair);
+			uint64_t n = 0;
+
+			VERIFY(zap_update(mos, jumpobj,
+			    perm, 8, 1, &n, tx) == 0);
+			spa_history_log_internal_dd(dd, "permission update", tx,
+			    "%s %s", whokey, perm);
+		}
+	}
+	dsl_dir_rele(dd, FTAG);
+}
+
+static void
+dsl_deleg_unset_sync(void *arg, dmu_tx_t *tx)
+{
+	dsl_deleg_arg_t *dda = arg;
+	dsl_dir_t *dd;
+	dsl_pool_t *dp = dmu_tx_pool(tx);
+	objset_t *mos = dp->dp_meta_objset;
+	nvpair_t *whopair = NULL;
+	uint64_t zapobj;
+
+	VERIFY0(dsl_dir_hold(dp, dda->dda_name, FTAG, &dd, NULL));
+	zapobj = dsl_dir_phys(dd)->dd_deleg_zapobj;
+	if (zapobj == 0) {
+		dsl_dir_rele(dd, FTAG);
+		return;
+	}
+
+	while ((whopair = nvlist_next_nvpair(dda->dda_nvlist, whopair))) {
+		const char *whokey = nvpair_name(whopair);
+		nvlist_t *perms;
+		nvpair_t *permpair = NULL;
+		uint64_t jumpobj;
+
+		if (nvpair_value_nvlist(whopair, &perms) != 0) {
+			if (zap_lookup(mos, zapobj, whokey, 8,
+			    1, &jumpobj) == 0) {
+				(void) zap_remove(mos, zapobj, whokey, tx);
+				VERIFY(0 == zap_destroy(mos, jumpobj, tx));
+			}
+			spa_history_log_internal_dd(dd, "permission who remove",
+			    tx, "%s", whokey);
+			continue;
+		}
+
+		if (zap_lookup(mos, zapobj, whokey, 8, 1, &jumpobj) != 0)
+			continue;
+
+		while ((permpair = nvlist_next_nvpair(perms, permpair))) {
+			const char *perm = nvpair_name(permpair);
+			uint64_t n = 0;
+
+			(void) zap_remove(mos, jumpobj, perm, tx);
+			if (zap_count(mos, jumpobj, &n) == 0 && n == 0) {
+				(void) zap_remove(mos, zapobj,
+				    whokey, tx);
+				VERIFY(0 == zap_destroy(mos,
+				    jumpobj, tx));
+			}
+			spa_history_log_internal_dd(dd, "permission remove", tx,
+			    "%s %s", whokey, perm);
+		}
+	}
+	dsl_dir_rele(dd, FTAG);
+}
+
+static int
+dsl_deleg_check(void *arg, dmu_tx_t *tx)
+{
+	dsl_deleg_arg_t *dda = arg;
+	dsl_dir_t *dd;
+	int error;
+
+	if (spa_version(dmu_tx_pool(tx)->dp_spa) <
+	    SPA_VERSION_DELEGATED_PERMS) {
+		return (SET_ERROR(ENOTSUP));
+	}
+
+	error = dsl_dir_hold(dmu_tx_pool(tx), dda->dda_name, FTAG, &dd, NULL);
+	if (error == 0)
+		dsl_dir_rele(dd, FTAG);
+	return (error);
+}
+
+int
+dsl_deleg_set(const char *ddname, nvlist_t *nvp, boolean_t unset)
+{
+	dsl_deleg_arg_t dda;
+
+	/* nvp must already have been verified to be valid */
+
+	dda.dda_name = ddname;
+	dda.dda_nvlist = nvp;
+
+	return (dsl_sync_task(ddname, dsl_deleg_check,
+	    unset ? dsl_deleg_unset_sync : dsl_deleg_set_sync,
+	    &dda, fnvlist_num_pairs(nvp), ZFS_SPACE_CHECK_RESERVED));
+}
+
+/*
+ * Find all 'allow' permissions from a given point and then continue
+ * traversing up to the root.
+ *
+ * This function constructs an nvlist of nvlists.
+ * each setpoint is an nvlist composed of an nvlist of an nvlist
+ * of the individual * users/groups/everyone/create
+ * permissions.
+ *
+ * The nvlist will look like this.
+ *
+ * { source fsname -> { whokeys { permissions,...}, ...}}
+ *
+ * The fsname nvpairs will be arranged in a bottom up order.  For example,
+ * if we have the following structure a/b/c then the nvpairs for the fsnames
+ * will be ordered a/b/c, a/b, a.
+ */
+int
+dsl_deleg_get(const char *ddname, nvlist_t **nvp)
+{
+	dsl_dir_t *dd, *startdd;
+	dsl_pool_t *dp;
+	int error;
+	objset_t *mos;
+	zap_cursor_t *basezc, *zc;
+	zap_attribute_t *baseza, *za;
+	char *source;
+
+	error = dsl_pool_hold(ddname, FTAG, &dp);
+	if (error != 0)
+		return (error);
+
+	error = dsl_dir_hold(dp, ddname, FTAG, &startdd, NULL);
+	if (error != 0) {
+		dsl_pool_rele(dp, FTAG);
+		return (error);
+	}
+
+	dp = startdd->dd_pool;
+	mos = dp->dp_meta_objset;
+
+	zc = kmem_alloc(sizeof (zap_cursor_t), KM_SLEEP);
+	za = kmem_alloc(sizeof (zap_attribute_t), KM_SLEEP);
+	basezc = kmem_alloc(sizeof (zap_cursor_t), KM_SLEEP);
+	baseza = kmem_alloc(sizeof (zap_attribute_t), KM_SLEEP);
+	source = kmem_alloc(MAXNAMELEN + strlen(MOS_DIR_NAME) + 1, KM_SLEEP);
+	VERIFY(nvlist_alloc(nvp, NV_UNIQUE_NAME, KM_SLEEP) == 0);
+
+	for (dd = startdd; dd != NULL; dd = dd->dd_parent) {
+		nvlist_t *sp_nvp;
+		uint64_t n;
+
+		if (dsl_dir_phys(dd)->dd_deleg_zapobj == 0 ||
+		    zap_count(mos,
+		    dsl_dir_phys(dd)->dd_deleg_zapobj, &n) != 0 || n == 0)
+			continue;
+
+		sp_nvp = fnvlist_alloc();
+		for (zap_cursor_init(basezc, mos,
+		    dsl_dir_phys(dd)->dd_deleg_zapobj);
+		    zap_cursor_retrieve(basezc, baseza) == 0;
+		    zap_cursor_advance(basezc)) {
+			nvlist_t *perms_nvp;
+
+			ASSERT(baseza->za_integer_length == 8);
+			ASSERT(baseza->za_num_integers == 1);
+
+			perms_nvp = fnvlist_alloc();
+			for (zap_cursor_init(zc, mos, baseza->za_first_integer);
+			    zap_cursor_retrieve(zc, za) == 0;
+			    zap_cursor_advance(zc)) {
+				fnvlist_add_boolean(perms_nvp, za->za_name);
+			}
+			zap_cursor_fini(zc);
+			fnvlist_add_nvlist(sp_nvp, baseza->za_name, perms_nvp);
+			fnvlist_free(perms_nvp);
+		}
+
+		zap_cursor_fini(basezc);
+
+		dsl_dir_name(dd, source);
+		fnvlist_add_nvlist(*nvp, source, sp_nvp);
+		nvlist_free(sp_nvp);
+	}
+
+	kmem_free(source, MAXNAMELEN + strlen(MOS_DIR_NAME) + 1);
+	kmem_free(baseza, sizeof (zap_attribute_t));
+	kmem_free(basezc, sizeof (zap_cursor_t));
+	kmem_free(za, sizeof (zap_attribute_t));
+	kmem_free(zc, sizeof (zap_cursor_t));
+
+	dsl_dir_rele(startdd, FTAG);
+	dsl_pool_rele(dp, FTAG);
+	return (0);
+}
+
+/*
+ * Routines for dsl_deleg_access() -- access checking.
+ */
+typedef struct perm_set {
+	avl_node_t	p_node;
+	boolean_t	p_matched;
+	char		p_setname[ZFS_MAX_DELEG_NAME];
+} perm_set_t;
+
+static int
+perm_set_compare(const void *arg1, const void *arg2)
+{
+	const perm_set_t *node1 = arg1;
+	const perm_set_t *node2 = arg2;
+	int val;
+
+	val = strcmp(node1->p_setname, node2->p_setname);
+	if (val == 0)
+		return (0);
+	return (val > 0 ? 1 : -1);
+}
+
+/*
+ * Determine whether a specified permission exists.
+ *
+ * First the base attribute has to be retrieved.  i.e. ul$12
+ * Once the base object has been retrieved the actual permission
+ * is lookup up in the zap object the base object points to.
+ *
+ * Return 0 if permission exists, ENOENT if there is no whokey, EPERM if
+ * there is no perm in that jumpobj.
+ */
+static int
+dsl_check_access(objset_t *mos, uint64_t zapobj,
+    char type, char checkflag, void *valp, const char *perm)
+{
+	int error;
+	uint64_t jumpobj, zero;
+	char whokey[ZFS_MAX_DELEG_NAME];
+
+	zfs_deleg_whokey(whokey, type, checkflag, valp);
+	error = zap_lookup(mos, zapobj, whokey, 8, 1, &jumpobj);
+	if (error == 0) {
+		error = zap_lookup(mos, jumpobj, perm, 8, 1, &zero);
+		if (error == ENOENT)
+			error = SET_ERROR(EPERM);
+	}
+	return (error);
+}
+
+/*
+ * check a specified user/group for a requested permission
+ */
+static int
+dsl_check_user_access(objset_t *mos, uint64_t zapobj, const char *perm,
+    int checkflag, cred_t *cr)
+{
+	const	gid_t *gids;
+	int	ngids;
+	int	i;
+	uint64_t id;
+
+	/* check for user */
+	id = crgetuid(cr);
+	if (dsl_check_access(mos, zapobj,
+	    ZFS_DELEG_USER, checkflag, &id, perm) == 0)
+		return (0);
+
+	/* check for users primary group */
+	id = crgetgid(cr);
+	if (dsl_check_access(mos, zapobj,
+	    ZFS_DELEG_GROUP, checkflag, &id, perm) == 0)
+		return (0);
+
+	/* check for everyone entry */
+	id = -1;
+	if (dsl_check_access(mos, zapobj,
+	    ZFS_DELEG_EVERYONE, checkflag, &id, perm) == 0)
+		return (0);
+
+	/* check each supplemental group user is a member of */
+	ngids = crgetngroups(cr);
+	gids = crgetgroups(cr);
+	for (i = 0; i != ngids; i++) {
+		id = gids[i];
+		if (dsl_check_access(mos, zapobj,
+		    ZFS_DELEG_GROUP, checkflag, &id, perm) == 0)
+			return (0);
+	}
+
+	return (SET_ERROR(EPERM));
+}
+
+/*
+ * Iterate over the sets specified in the specified zapobj
+ * and load them into the permsets avl tree.
+ */
+static int
+dsl_load_sets(objset_t *mos, uint64_t zapobj,
+    char type, char checkflag, void *valp, avl_tree_t *avl)
+{
+	zap_cursor_t zc;
+	zap_attribute_t za;
+	perm_set_t *permnode;
+	avl_index_t idx;
+	uint64_t jumpobj;
+	int error;
+	char whokey[ZFS_MAX_DELEG_NAME];
+
+	zfs_deleg_whokey(whokey, type, checkflag, valp);
+
+	error = zap_lookup(mos, zapobj, whokey, 8, 1, &jumpobj);
+	if (error != 0)
+		return (error);
+
+	for (zap_cursor_init(&zc, mos, jumpobj);
+	    zap_cursor_retrieve(&zc, &za) == 0;
+	    zap_cursor_advance(&zc)) {
+		permnode = kmem_alloc(sizeof (perm_set_t), KM_SLEEP);
+		(void) strlcpy(permnode->p_setname, za.za_name,
+		    sizeof (permnode->p_setname));
+		permnode->p_matched = B_FALSE;
+
+		if (avl_find(avl, permnode, &idx) == NULL) {
+			avl_insert(avl, permnode, idx);
+		} else {
+			kmem_free(permnode, sizeof (perm_set_t));
+		}
+	}
+	zap_cursor_fini(&zc);
+	return (0);
+}
+
+/*
+ * Load all permissions user based on cred belongs to.
+ */
+static void
+dsl_load_user_sets(objset_t *mos, uint64_t zapobj, avl_tree_t *avl,
+    char checkflag, cred_t *cr)
+{
+	const	gid_t *gids;
+	int	ngids, i;
+	uint64_t id;
+
+	id = crgetuid(cr);
+	(void) dsl_load_sets(mos, zapobj,
+	    ZFS_DELEG_USER_SETS, checkflag, &id, avl);
+
+	id = crgetgid(cr);
+	(void) dsl_load_sets(mos, zapobj,
+	    ZFS_DELEG_GROUP_SETS, checkflag, &id, avl);
+
+	(void) dsl_load_sets(mos, zapobj,
+	    ZFS_DELEG_EVERYONE_SETS, checkflag, NULL, avl);
+
+	ngids = crgetngroups(cr);
+	gids = crgetgroups(cr);
+	for (i = 0; i != ngids; i++) {
+		id = gids[i];
+		(void) dsl_load_sets(mos, zapobj,
+		    ZFS_DELEG_GROUP_SETS, checkflag, &id, avl);
+	}
+}
+
+/*
+ * Check if user has requested permission.
+ */
+int
+dsl_deleg_access_impl(dsl_dataset_t *ds, const char *perm, cred_t *cr)
+{
+	dsl_dir_t *dd;
+	dsl_pool_t *dp;
+	void *cookie;
+	int	error;
+	char	checkflag;
+	objset_t *mos;
+	avl_tree_t permsets;
+	perm_set_t *setnode;
+
+	dp = ds->ds_dir->dd_pool;
+	mos = dp->dp_meta_objset;
+
+	if (dsl_delegation_on(mos) == B_FALSE)
+		return (SET_ERROR(ECANCELED));
+
+	if (spa_version(dmu_objset_spa(dp->dp_meta_objset)) <
+	    SPA_VERSION_DELEGATED_PERMS)
+		return (SET_ERROR(EPERM));
+
+	if (ds->ds_is_snapshot) {
+		/*
+		 * Snapshots are treated as descendents only,
+		 * local permissions do not apply.
+		 */
+		checkflag = ZFS_DELEG_DESCENDENT;
+	} else {
+		checkflag = ZFS_DELEG_LOCAL;
+	}
+
+	avl_create(&permsets, perm_set_compare, sizeof (perm_set_t),
+	    offsetof(perm_set_t, p_node));
+
+	ASSERT(dsl_pool_config_held(dp));
+	for (dd = ds->ds_dir; dd != NULL; dd = dd->dd_parent,
+	    checkflag = ZFS_DELEG_DESCENDENT) {
+		uint64_t zapobj;
+		boolean_t expanded;
+
+		/*
+		 * If not in global zone then make sure
+		 * the zoned property is set
+		 */
+		if (!INGLOBALZONE(curproc)) {
+			uint64_t zoned;
+
+			if (dsl_prop_get_dd(dd,
+			    zfs_prop_to_name(ZFS_PROP_ZONED),
+			    8, 1, &zoned, NULL, B_FALSE) != 0)
+				break;
+			if (!zoned)
+				break;
+		}
+		zapobj = dsl_dir_phys(dd)->dd_deleg_zapobj;
+
+		if (zapobj == 0)
+			continue;
+
+		dsl_load_user_sets(mos, zapobj, &permsets, checkflag, cr);
+again:
+		expanded = B_FALSE;
+		for (setnode = avl_first(&permsets); setnode;
+		    setnode = AVL_NEXT(&permsets, setnode)) {
+			if (setnode->p_matched == B_TRUE)
+				continue;
+
+			/* See if this set directly grants this permission */
+			error = dsl_check_access(mos, zapobj,
+			    ZFS_DELEG_NAMED_SET, 0, setnode->p_setname, perm);
+			if (error == 0)
+				goto success;
+			if (error == EPERM)
+				setnode->p_matched = B_TRUE;
+
+			/* See if this set includes other sets */
+			error = dsl_load_sets(mos, zapobj,
+			    ZFS_DELEG_NAMED_SET_SETS, 0,
+			    setnode->p_setname, &permsets);
+			if (error == 0)
+				setnode->p_matched = expanded = B_TRUE;
+		}
+		/*
+		 * If we expanded any sets, that will define more sets,
+		 * which we need to check.
+		 */
+		if (expanded)
+			goto again;
+
+		error = dsl_check_user_access(mos, zapobj, perm, checkflag, cr);
+		if (error == 0)
+			goto success;
+	}
+	error = SET_ERROR(EPERM);
+success:
+
+	cookie = NULL;
+	while ((setnode = avl_destroy_nodes(&permsets, &cookie)) != NULL)
+		kmem_free(setnode, sizeof (perm_set_t));
+
+	return (error);
+}
+
+int
+dsl_deleg_access(const char *dsname, const char *perm, cred_t *cr)
+{
+	dsl_pool_t *dp;
+	dsl_dataset_t *ds;
+	int error;
+
+	error = dsl_pool_hold(dsname, FTAG, &dp);
+	if (error != 0)
+		return (error);
+	error = dsl_dataset_hold(dp, dsname, FTAG, &ds);
+	if (error == 0) {
+		error = dsl_deleg_access_impl(ds, perm, cr);
+		dsl_dataset_rele(ds, FTAG);
+	}
+	dsl_pool_rele(dp, FTAG);
+
+	return (error);
+}
+
+/*
+ * Other routines.
+ */
+
+static void
+copy_create_perms(dsl_dir_t *dd, uint64_t pzapobj,
+    boolean_t dosets, uint64_t uid, dmu_tx_t *tx)
+{
+	objset_t *mos = dd->dd_pool->dp_meta_objset;
+	uint64_t jumpobj, pjumpobj;
+	uint64_t zapobj = dsl_dir_phys(dd)->dd_deleg_zapobj;
+	zap_cursor_t zc;
+	zap_attribute_t za;
+	char whokey[ZFS_MAX_DELEG_NAME];
+
+	zfs_deleg_whokey(whokey,
+	    dosets ? ZFS_DELEG_CREATE_SETS : ZFS_DELEG_CREATE,
+	    ZFS_DELEG_LOCAL, NULL);
+	if (zap_lookup(mos, pzapobj, whokey, 8, 1, &pjumpobj) != 0)
+		return;
+
+	if (zapobj == 0) {
+		dmu_buf_will_dirty(dd->dd_dbuf, tx);
+		zapobj = dsl_dir_phys(dd)->dd_deleg_zapobj = zap_create(mos,
+		    DMU_OT_DSL_PERMS, DMU_OT_NONE, 0, tx);
+	}
+
+	zfs_deleg_whokey(whokey,
+	    dosets ? ZFS_DELEG_USER_SETS : ZFS_DELEG_USER,
+	    ZFS_DELEG_LOCAL, &uid);
+	if (zap_lookup(mos, zapobj, whokey, 8, 1, &jumpobj) == ENOENT) {
+		jumpobj = zap_create(mos, DMU_OT_DSL_PERMS, DMU_OT_NONE, 0, tx);
+		VERIFY(zap_add(mos, zapobj, whokey, 8, 1, &jumpobj, tx) == 0);
+	}
+
+	for (zap_cursor_init(&zc, mos, pjumpobj);
+	    zap_cursor_retrieve(&zc, &za) == 0;
+	    zap_cursor_advance(&zc)) {
+		uint64_t zero = 0;
+		ASSERT(za.za_integer_length == 8 && za.za_num_integers == 1);
+
+		VERIFY(zap_update(mos, jumpobj, za.za_name,
+		    8, 1, &zero, tx) == 0);
+	}
+	zap_cursor_fini(&zc);
+}
+
+/*
+ * set all create time permission on new dataset.
+ */
+void
+dsl_deleg_set_create_perms(dsl_dir_t *sdd, dmu_tx_t *tx, cred_t *cr)
+{
+	dsl_dir_t *dd;
+	uint64_t uid = crgetuid(cr);
+
+	if (spa_version(dmu_objset_spa(sdd->dd_pool->dp_meta_objset)) <
+	    SPA_VERSION_DELEGATED_PERMS)
+		return;
+
+	for (dd = sdd->dd_parent; dd != NULL; dd = dd->dd_parent) {
+		uint64_t pzapobj = dsl_dir_phys(dd)->dd_deleg_zapobj;
+
+		if (pzapobj == 0)
+			continue;
+
+		copy_create_perms(sdd, pzapobj, B_FALSE, uid, tx);
+		copy_create_perms(sdd, pzapobj, B_TRUE, uid, tx);
+	}
+}
+
+int
+dsl_deleg_destroy(objset_t *mos, uint64_t zapobj, dmu_tx_t *tx)
+{
+	zap_cursor_t zc;
+	zap_attribute_t za;
+
+	if (zapobj == 0)
+		return (0);
+
+	for (zap_cursor_init(&zc, mos, zapobj);
+	    zap_cursor_retrieve(&zc, &za) == 0;
+	    zap_cursor_advance(&zc)) {
+		ASSERT(za.za_integer_length == 8 && za.za_num_integers == 1);
+		VERIFY(0 == zap_destroy(mos, za.za_first_integer, tx));
+	}
+	zap_cursor_fini(&zc);
+	VERIFY(0 == zap_destroy(mos, zapobj, tx));
+	return (0);
+}
+
+boolean_t
+dsl_delegation_on(objset_t *os)
+{
+	return (!!spa_delegation(os->os_spa));
+}
+
+#if defined(_KERNEL) && defined(HAVE_SPL)
+EXPORT_SYMBOL(dsl_deleg_get);
+EXPORT_SYMBOL(dsl_deleg_set);
+#endif
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/module/zfs/dsl_destroy.c
@@ -0,0 +1,990 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2014 by Delphix. All rights reserved.
+ * Copyright (c) 2013 Steven Hartland. All rights reserved.
+ * Copyright (c) 2013 by Joyent, Inc. All rights reserved.
+ * Copyright (c) 2016 Actifio, Inc. All rights reserved.
+ */
+
+#include <sys/zfs_context.h>
+#include <sys/dsl_userhold.h>
+#include <sys/dsl_dataset.h>
+#include <sys/dsl_synctask.h>
+#include <sys/dmu_tx.h>
+#include <sys/dsl_pool.h>
+#include <sys/dsl_dir.h>
+#include <sys/dmu_traverse.h>
+#include <sys/dsl_scan.h>
+#include <sys/dmu_objset.h>
+#include <sys/zap.h>
+#include <sys/zfeature.h>
+#include <sys/zfs_ioctl.h>
+#include <sys/dsl_deleg.h>
+#include <sys/dmu_impl.h>
+#include <sys/zvol.h>
+
+typedef struct dmu_snapshots_destroy_arg {
+	nvlist_t *dsda_snaps;
+	nvlist_t *dsda_successful_snaps;
+	boolean_t dsda_defer;
+	nvlist_t *dsda_errlist;
+} dmu_snapshots_destroy_arg_t;
+
+int
+dsl_destroy_snapshot_check_impl(dsl_dataset_t *ds, boolean_t defer)
+{
+	if (!ds->ds_is_snapshot)
+		return (SET_ERROR(EINVAL));
+
+	if (dsl_dataset_long_held(ds))
+		return (SET_ERROR(EBUSY));
+
+	/*
+	 * Only allow deferred destroy on pools that support it.
+	 * NOTE: deferred destroy is only supported on snapshots.
+	 */
+	if (defer) {
+		if (spa_version(ds->ds_dir->dd_pool->dp_spa) <
+		    SPA_VERSION_USERREFS)
+			return (SET_ERROR(ENOTSUP));
+		return (0);
+	}
+
+	/*
+	 * If this snapshot has an elevated user reference count,
+	 * we can't destroy it yet.
+	 */
+	if (ds->ds_userrefs > 0)
+		return (SET_ERROR(EBUSY));
+
+	/*
+	 * Can't delete a branch point.
+	 */
+	if (dsl_dataset_phys(ds)->ds_num_children > 1)
+		return (SET_ERROR(EEXIST));
+
+	return (0);
+}
+
+static int
+dsl_destroy_snapshot_check(void *arg, dmu_tx_t *tx)
+{
+	dmu_snapshots_destroy_arg_t *dsda = arg;
+	dsl_pool_t *dp = dmu_tx_pool(tx);
+	nvpair_t *pair;
+	int error = 0;
+
+	if (!dmu_tx_is_syncing(tx))
+		return (0);
+
+	for (pair = nvlist_next_nvpair(dsda->dsda_snaps, NULL);
+	    pair != NULL; pair = nvlist_next_nvpair(dsda->dsda_snaps, pair)) {
+		dsl_dataset_t *ds;
+
+		error = dsl_dataset_hold(dp, nvpair_name(pair),
+		    FTAG, &ds);
+
+		/*
+		 * If the snapshot does not exist, silently ignore it
+		 * (it's "already destroyed").
+		 */
+		if (error == ENOENT)
+			continue;
+
+		if (error == 0) {
+			error = dsl_destroy_snapshot_check_impl(ds,
+			    dsda->dsda_defer);
+			dsl_dataset_rele(ds, FTAG);
+		}
+
+		if (error == 0) {
+			fnvlist_add_boolean(dsda->dsda_successful_snaps,
+			    nvpair_name(pair));
+		} else {
+			fnvlist_add_int32(dsda->dsda_errlist,
+			    nvpair_name(pair), error);
+		}
+	}
+
+	pair = nvlist_next_nvpair(dsda->dsda_errlist, NULL);
+	if (pair != NULL)
+		return (fnvpair_value_int32(pair));
+
+	return (0);
+}
+
+struct process_old_arg {
+	dsl_dataset_t *ds;
+	dsl_dataset_t *ds_prev;
+	boolean_t after_branch_point;
+	zio_t *pio;
+	uint64_t used, comp, uncomp;
+};
+
+static int
+process_old_cb(void *arg, const blkptr_t *bp, dmu_tx_t *tx)
+{
+	struct process_old_arg *poa = arg;
+	dsl_pool_t *dp = poa->ds->ds_dir->dd_pool;
+
+	ASSERT(!BP_IS_HOLE(bp));
+
+	if (bp->blk_birth <= dsl_dataset_phys(poa->ds)->ds_prev_snap_txg) {
+		dsl_deadlist_insert(&poa->ds->ds_deadlist, bp, tx);
+		if (poa->ds_prev && !poa->after_branch_point &&
+		    bp->blk_birth >
+		    dsl_dataset_phys(poa->ds_prev)->ds_prev_snap_txg) {
+			dsl_dataset_phys(poa->ds_prev)->ds_unique_bytes +=
+			    bp_get_dsize_sync(dp->dp_spa, bp);
+		}
+	} else {
+		poa->used += bp_get_dsize_sync(dp->dp_spa, bp);
+		poa->comp += BP_GET_PSIZE(bp);
+		poa->uncomp += BP_GET_UCSIZE(bp);
+		dsl_free_sync(poa->pio, dp, tx->tx_txg, bp);
+	}
+	return (0);
+}
+
+static void
+process_old_deadlist(dsl_dataset_t *ds, dsl_dataset_t *ds_prev,
+    dsl_dataset_t *ds_next, boolean_t after_branch_point, dmu_tx_t *tx)
+{
+	struct process_old_arg poa = { 0 };
+	dsl_pool_t *dp = ds->ds_dir->dd_pool;
+	objset_t *mos = dp->dp_meta_objset;
+	uint64_t deadlist_obj;
+
+	ASSERT(ds->ds_deadlist.dl_oldfmt);
+	ASSERT(ds_next->ds_deadlist.dl_oldfmt);
+
+	poa.ds = ds;
+	poa.ds_prev = ds_prev;
+	poa.after_branch_point = after_branch_point;
+	poa.pio = zio_root(dp->dp_spa, NULL, NULL, ZIO_FLAG_MUSTSUCCEED);
+	VERIFY0(bpobj_iterate(&ds_next->ds_deadlist.dl_bpobj,
+	    process_old_cb, &poa, tx));
+	VERIFY0(zio_wait(poa.pio));
+	ASSERT3U(poa.used, ==, dsl_dataset_phys(ds)->ds_unique_bytes);
+
+	/* change snapused */
+	dsl_dir_diduse_space(ds->ds_dir, DD_USED_SNAP,
+	    -poa.used, -poa.comp, -poa.uncomp, tx);
+
+	/* swap next's deadlist to our deadlist */
+	dsl_deadlist_close(&ds->ds_deadlist);
+	dsl_deadlist_close(&ds_next->ds_deadlist);
+	deadlist_obj = dsl_dataset_phys(ds)->ds_deadlist_obj;
+	dsl_dataset_phys(ds)->ds_deadlist_obj =
+	    dsl_dataset_phys(ds_next)->ds_deadlist_obj;
+	dsl_dataset_phys(ds_next)->ds_deadlist_obj = deadlist_obj;
+	dsl_deadlist_open(&ds->ds_deadlist, mos,
+	    dsl_dataset_phys(ds)->ds_deadlist_obj);
+	dsl_deadlist_open(&ds_next->ds_deadlist, mos,
+	    dsl_dataset_phys(ds_next)->ds_deadlist_obj);
+}
+
+static void
+dsl_dataset_remove_clones_key(dsl_dataset_t *ds, uint64_t mintxg, dmu_tx_t *tx)
+{
+	objset_t *mos = ds->ds_dir->dd_pool->dp_meta_objset;
+	zap_cursor_t *zc;
+	zap_attribute_t *za;
+
+	/*
+	 * If it is the old version, dd_clones doesn't exist so we can't
+	 * find the clones, but dsl_deadlist_remove_key() is a no-op so it
+	 * doesn't matter.
+	 */
+	if (dsl_dir_phys(ds->ds_dir)->dd_clones == 0)
+		return;
+
+	zc = kmem_alloc(sizeof (zap_cursor_t), KM_SLEEP);
+	za = kmem_alloc(sizeof (zap_attribute_t), KM_SLEEP);
+
+	for (zap_cursor_init(zc, mos, dsl_dir_phys(ds->ds_dir)->dd_clones);
+	    zap_cursor_retrieve(zc, za) == 0;
+	    zap_cursor_advance(zc)) {
+		dsl_dataset_t *clone;
+
+		VERIFY0(dsl_dataset_hold_obj(ds->ds_dir->dd_pool,
+		    za->za_first_integer, FTAG, &clone));
+		if (clone->ds_dir->dd_origin_txg > mintxg) {
+			dsl_deadlist_remove_key(&clone->ds_deadlist,
+			    mintxg, tx);
+			dsl_dataset_remove_clones_key(clone, mintxg, tx);
+		}
+		dsl_dataset_rele(clone, FTAG);
+	}
+	zap_cursor_fini(zc);
+
+	kmem_free(za, sizeof (zap_attribute_t));
+	kmem_free(zc, sizeof (zap_cursor_t));
+}
+
+void
+dsl_destroy_snapshot_sync_impl(dsl_dataset_t *ds, boolean_t defer, dmu_tx_t *tx)
+{
+	int after_branch_point = FALSE;
+	dsl_pool_t *dp = ds->ds_dir->dd_pool;
+	objset_t *mos = dp->dp_meta_objset;
+	dsl_dataset_t *ds_prev = NULL;
+	uint64_t obj, old_unique, used = 0, comp = 0, uncomp = 0;
+	dsl_dataset_t *ds_next, *ds_head, *hds;
+
+
+	ASSERT(RRW_WRITE_HELD(&dp->dp_config_rwlock));
+	ASSERT3U(dsl_dataset_phys(ds)->ds_bp.blk_birth, <=, tx->tx_txg);
+	ASSERT(refcount_is_zero(&ds->ds_longholds));
+
+	if (defer &&
+	    (ds->ds_userrefs > 0 ||
+	    dsl_dataset_phys(ds)->ds_num_children > 1)) {
+		ASSERT(spa_version(dp->dp_spa) >= SPA_VERSION_USERREFS);
+		dmu_buf_will_dirty(ds->ds_dbuf, tx);
+		dsl_dataset_phys(ds)->ds_flags |= DS_FLAG_DEFER_DESTROY;
+		spa_history_log_internal_ds(ds, "defer_destroy", tx, "");
+		return;
+	}
+
+	ASSERT3U(dsl_dataset_phys(ds)->ds_num_children, <=, 1);
+
+	/* We need to log before removing it from the namespace. */
+	spa_history_log_internal_ds(ds, "destroy", tx, "");
+
+	dsl_scan_ds_destroyed(ds, tx);
+
+	obj = ds->ds_object;
+
+	if (ds->ds_large_blocks) {
+		ASSERT0(zap_contains(mos, obj, DS_FIELD_LARGE_BLOCKS));
+		spa_feature_decr(dp->dp_spa, SPA_FEATURE_LARGE_BLOCKS, tx);
+	}
+	if (dsl_dataset_phys(ds)->ds_prev_snap_obj != 0) {
+		ASSERT3P(ds->ds_prev, ==, NULL);
+		VERIFY0(dsl_dataset_hold_obj(dp,
+		    dsl_dataset_phys(ds)->ds_prev_snap_obj, FTAG, &ds_prev));
+		after_branch_point =
+		    (dsl_dataset_phys(ds_prev)->ds_next_snap_obj != obj);
+
+		dmu_buf_will_dirty(ds_prev->ds_dbuf, tx);
+		if (after_branch_point &&
+		    dsl_dataset_phys(ds_prev)->ds_next_clones_obj != 0) {
+			dsl_dataset_remove_from_next_clones(ds_prev, obj, tx);
+			if (dsl_dataset_phys(ds)->ds_next_snap_obj != 0) {
+				VERIFY0(zap_add_int(mos,
+				    dsl_dataset_phys(ds_prev)->
+				    ds_next_clones_obj,
+				    dsl_dataset_phys(ds)->ds_next_snap_obj,
+				    tx));
+			}
+		}
+		if (!after_branch_point) {
+			dsl_dataset_phys(ds_prev)->ds_next_snap_obj =
+			    dsl_dataset_phys(ds)->ds_next_snap_obj;
+		}
+	}
+
+	VERIFY0(dsl_dataset_hold_obj(dp,
+	    dsl_dataset_phys(ds)->ds_next_snap_obj, FTAG, &ds_next));
+	ASSERT3U(dsl_dataset_phys(ds_next)->ds_prev_snap_obj, ==, obj);
+
+	old_unique = dsl_dataset_phys(ds_next)->ds_unique_bytes;
+
+	dmu_buf_will_dirty(ds_next->ds_dbuf, tx);
+	dsl_dataset_phys(ds_next)->ds_prev_snap_obj =
+	    dsl_dataset_phys(ds)->ds_prev_snap_obj;
+	dsl_dataset_phys(ds_next)->ds_prev_snap_txg =
+	    dsl_dataset_phys(ds)->ds_prev_snap_txg;
+	ASSERT3U(dsl_dataset_phys(ds)->ds_prev_snap_txg, ==,
+	    ds_prev ? dsl_dataset_phys(ds_prev)->ds_creation_txg : 0);
+
+	if (ds_next->ds_deadlist.dl_oldfmt) {
+		process_old_deadlist(ds, ds_prev, ds_next,
+		    after_branch_point, tx);
+	} else {
+		/* Adjust prev's unique space. */
+		if (ds_prev && !after_branch_point) {
+			dsl_deadlist_space_range(&ds_next->ds_deadlist,
+			    dsl_dataset_phys(ds_prev)->ds_prev_snap_txg,
+			    dsl_dataset_phys(ds)->ds_prev_snap_txg,
+			    &used, &comp, &uncomp);
+			dsl_dataset_phys(ds_prev)->ds_unique_bytes += used;
+		}
+
+		/* Adjust snapused. */
+		dsl_deadlist_space_range(&ds_next->ds_deadlist,
+		    dsl_dataset_phys(ds)->ds_prev_snap_txg, UINT64_MAX,
+		    &used, &comp, &uncomp);
+		dsl_dir_diduse_space(ds->ds_dir, DD_USED_SNAP,
+		    -used, -comp, -uncomp, tx);
+
+		/* Move blocks to be freed to pool's free list. */
+		dsl_deadlist_move_bpobj(&ds_next->ds_deadlist,
+		    &dp->dp_free_bpobj, dsl_dataset_phys(ds)->ds_prev_snap_txg,
+		    tx);
+		dsl_dir_diduse_space(tx->tx_pool->dp_free_dir,
+		    DD_USED_HEAD, used, comp, uncomp, tx);
+
+		/* Merge our deadlist into next's and free it. */
+		dsl_deadlist_merge(&ds_next->ds_deadlist,
+		    dsl_dataset_phys(ds)->ds_deadlist_obj, tx);
+	}
+	dsl_deadlist_close(&ds->ds_deadlist);
+	dsl_deadlist_free(mos, dsl_dataset_phys(ds)->ds_deadlist_obj, tx);
+	dmu_buf_will_dirty(ds->ds_dbuf, tx);
+	dsl_dataset_phys(ds)->ds_deadlist_obj = 0;
+
+	/* Collapse range in clone heads */
+	dsl_dataset_remove_clones_key(ds,
+	    dsl_dataset_phys(ds)->ds_creation_txg, tx);
+
+	if (ds_next->ds_is_snapshot) {
+		dsl_dataset_t *ds_nextnext;
+
+		/*
+		 * Update next's unique to include blocks which
+		 * were previously shared by only this snapshot
+		 * and it.  Those blocks will be born after the
+		 * prev snap and before this snap, and will have
+		 * died after the next snap and before the one
+		 * after that (ie. be on the snap after next's
+		 * deadlist).
+		 */
+		VERIFY0(dsl_dataset_hold_obj(dp,
+		    dsl_dataset_phys(ds_next)->ds_next_snap_obj,
+		    FTAG, &ds_nextnext));
+		dsl_deadlist_space_range(&ds_nextnext->ds_deadlist,
+		    dsl_dataset_phys(ds)->ds_prev_snap_txg,
+		    dsl_dataset_phys(ds)->ds_creation_txg,
+		    &used, &comp, &uncomp);
+		dsl_dataset_phys(ds_next)->ds_unique_bytes += used;
+		dsl_dataset_rele(ds_nextnext, FTAG);
+		ASSERT3P(ds_next->ds_prev, ==, NULL);
+
+		/* Collapse range in this head. */
+		VERIFY0(dsl_dataset_hold_obj(dp,
+		    dsl_dir_phys(ds->ds_dir)->dd_head_dataset_obj, FTAG, &hds));
+		dsl_deadlist_remove_key(&hds->ds_deadlist,
+		    dsl_dataset_phys(ds)->ds_creation_txg, tx);
+		dsl_dataset_rele(hds, FTAG);
+
+	} else {
+		ASSERT3P(ds_next->ds_prev, ==, ds);
+		dsl_dataset_rele(ds_next->ds_prev, ds_next);
+		ds_next->ds_prev = NULL;
+		if (ds_prev) {
+			VERIFY0(dsl_dataset_hold_obj(dp,
+			    dsl_dataset_phys(ds)->ds_prev_snap_obj,
+			    ds_next, &ds_next->ds_prev));
+		}
+
+		dsl_dataset_recalc_head_uniq(ds_next);
+
+		/*
+		 * Reduce the amount of our unconsumed refreservation
+		 * being charged to our parent by the amount of
+		 * new unique data we have gained.
+		 */
+		if (old_unique < ds_next->ds_reserved) {
+			int64_t mrsdelta;
+			uint64_t new_unique =
+			    dsl_dataset_phys(ds_next)->ds_unique_bytes;
+
+			ASSERT(old_unique <= new_unique);
+			mrsdelta = MIN(new_unique - old_unique,
+			    ds_next->ds_reserved - old_unique);
+			dsl_dir_diduse_space(ds->ds_dir,
+			    DD_USED_REFRSRV, -mrsdelta, 0, 0, tx);
+		}
+	}
+	dsl_dataset_rele(ds_next, FTAG);
+
+	/*
+	 * This must be done after the dsl_traverse(), because it will
+	 * re-open the objset.
+	 */
+	if (ds->ds_objset) {
+		dmu_objset_evict(ds->ds_objset);
+		ds->ds_objset = NULL;
+	}
+
+	/* remove from snapshot namespace */
+	ASSERT(dsl_dataset_phys(ds)->ds_snapnames_zapobj == 0);
+	VERIFY0(dsl_dataset_hold_obj(dp,
+	    dsl_dir_phys(ds->ds_dir)->dd_head_dataset_obj, FTAG, &ds_head));
+	VERIFY0(dsl_dataset_get_snapname(ds));
+#ifdef ZFS_DEBUG
+	{
+		uint64_t val;
+		int err;
+
+		err = dsl_dataset_snap_lookup(ds_head,
+		    ds->ds_snapname, &val);
+		ASSERT0(err);
+		ASSERT3U(val, ==, obj);
+	}
+#endif
+	VERIFY0(dsl_dataset_snap_remove(ds_head, ds->ds_snapname, tx, B_TRUE));
+	dsl_dataset_rele(ds_head, FTAG);
+
+	if (ds_prev != NULL)
+		dsl_dataset_rele(ds_prev, FTAG);
+
+	spa_prop_clear_bootfs(dp->dp_spa, ds->ds_object, tx);
+
+	if (dsl_dataset_phys(ds)->ds_next_clones_obj != 0) {
+		ASSERTV(uint64_t count);
+		ASSERT0(zap_count(mos,
+		    dsl_dataset_phys(ds)->ds_next_clones_obj, &count) &&
+		    count == 0);
+		VERIFY0(dmu_object_free(mos,
+		    dsl_dataset_phys(ds)->ds_next_clones_obj, tx));
+	}
+	if (dsl_dataset_phys(ds)->ds_props_obj != 0)
+		VERIFY0(zap_destroy(mos, dsl_dataset_phys(ds)->ds_props_obj,
+		    tx));
+	if (dsl_dataset_phys(ds)->ds_userrefs_obj != 0)
+		VERIFY0(zap_destroy(mos, dsl_dataset_phys(ds)->ds_userrefs_obj,
+		    tx));
+	dsl_dir_rele(ds->ds_dir, ds);
+	ds->ds_dir = NULL;
+	dmu_object_free_zapified(mos, obj, tx);
+}
+
+static void
+dsl_destroy_snapshot_sync(void *arg, dmu_tx_t *tx)
+{
+	dmu_snapshots_destroy_arg_t *dsda = arg;
+	dsl_pool_t *dp = dmu_tx_pool(tx);
+	nvpair_t *pair;
+
+	for (pair = nvlist_next_nvpair(dsda->dsda_successful_snaps, NULL);
+	    pair != NULL;
+	    pair = nvlist_next_nvpair(dsda->dsda_successful_snaps, pair)) {
+		dsl_dataset_t *ds;
+
+		VERIFY0(dsl_dataset_hold(dp, nvpair_name(pair), FTAG, &ds));
+
+		dsl_destroy_snapshot_sync_impl(ds, dsda->dsda_defer, tx);
+		zvol_remove_minors(dp->dp_spa, nvpair_name(pair), B_TRUE);
+		dsl_dataset_rele(ds, FTAG);
+	}
+}
+
+/*
+ * The semantics of this function are described in the comment above
+ * lzc_destroy_snaps().  To summarize:
+ *
+ * The snapshots must all be in the same pool.
+ *
+ * Snapshots that don't exist will be silently ignored (considered to be
+ * "already deleted").
+ *
+ * On success, all snaps will be destroyed and this will return 0.
+ * On failure, no snaps will be destroyed, the errlist will be filled in,
+ * and this will return an errno.
+ */
+int
+dsl_destroy_snapshots_nvl(nvlist_t *snaps, boolean_t defer,
+    nvlist_t *errlist)
+{
+	dmu_snapshots_destroy_arg_t dsda;
+	int error;
+	nvpair_t *pair;
+
+	pair = nvlist_next_nvpair(snaps, NULL);
+	if (pair == NULL)
+		return (0);
+
+	dsda.dsda_snaps = snaps;
+	VERIFY0(nvlist_alloc(&dsda.dsda_successful_snaps,
+	    NV_UNIQUE_NAME, KM_SLEEP));
+	dsda.dsda_defer = defer;
+	dsda.dsda_errlist = errlist;
+
+	error = dsl_sync_task(nvpair_name(pair),
+	    dsl_destroy_snapshot_check, dsl_destroy_snapshot_sync,
+	    &dsda, 0, ZFS_SPACE_CHECK_NONE);
+	fnvlist_free(dsda.dsda_successful_snaps);
+
+	return (error);
+}
+
+int
+dsl_destroy_snapshot(const char *name, boolean_t defer)
+{
+	int error;
+	nvlist_t *nvl = fnvlist_alloc();
+	nvlist_t *errlist = fnvlist_alloc();
+
+	fnvlist_add_boolean(nvl, name);
+	error = dsl_destroy_snapshots_nvl(nvl, defer, errlist);
+	fnvlist_free(errlist);
+	fnvlist_free(nvl);
+	return (error);
+}
+
+struct killarg {
+	dsl_dataset_t *ds;
+	dmu_tx_t *tx;
+};
+
+/* ARGSUSED */
+static int
+kill_blkptr(spa_t *spa, zilog_t *zilog, const blkptr_t *bp,
+    const zbookmark_phys_t *zb, const dnode_phys_t *dnp, void *arg)
+{
+	struct killarg *ka = arg;
+	dmu_tx_t *tx = ka->tx;
+
+	if (BP_IS_HOLE(bp) || BP_IS_EMBEDDED(bp))
+		return (0);
+
+	if (zb->zb_level == ZB_ZIL_LEVEL) {
+		ASSERT(zilog != NULL);
+		/*
+		 * It's a block in the intent log.  It has no
+		 * accounting, so just free it.
+		 */
+		dsl_free(ka->tx->tx_pool, ka->tx->tx_txg, bp);
+	} else {
+		ASSERT(zilog == NULL);
+		ASSERT3U(bp->blk_birth, >,
+		    dsl_dataset_phys(ka->ds)->ds_prev_snap_txg);
+		(void) dsl_dataset_block_kill(ka->ds, bp, tx, B_FALSE);
+	}
+
+	return (0);
+}
+
+static void
+old_synchronous_dataset_destroy(dsl_dataset_t *ds, dmu_tx_t *tx)
+{
+	struct killarg ka;
+
+	/*
+	 * Free everything that we point to (that's born after
+	 * the previous snapshot, if we are a clone)
+	 *
+	 * NB: this should be very quick, because we already
+	 * freed all the objects in open context.
+	 */
+	ka.ds = ds;
+	ka.tx = tx;
+	VERIFY0(traverse_dataset(ds,
+	    dsl_dataset_phys(ds)->ds_prev_snap_txg, TRAVERSE_POST,
+	    kill_blkptr, &ka));
+	ASSERT(!DS_UNIQUE_IS_ACCURATE(ds) ||
+	    dsl_dataset_phys(ds)->ds_unique_bytes == 0);
+}
+
+typedef struct dsl_destroy_head_arg {
+	const char *ddha_name;
+} dsl_destroy_head_arg_t;
+
+int
+dsl_destroy_head_check_impl(dsl_dataset_t *ds, int expected_holds)
+{
+	int error;
+	uint64_t count;
+	objset_t *mos;
+
+	ASSERT(!ds->ds_is_snapshot);
+	if (ds->ds_is_snapshot)
+		return (SET_ERROR(EINVAL));
+
+	if (refcount_count(&ds->ds_longholds) != expected_holds)
+		return (SET_ERROR(EBUSY));
+
+	mos = ds->ds_dir->dd_pool->dp_meta_objset;
+
+	/*
+	 * Can't delete a head dataset if there are snapshots of it.
+	 * (Except if the only snapshots are from the branch we cloned
+	 * from.)
+	 */
+	if (ds->ds_prev != NULL &&
+	    dsl_dataset_phys(ds->ds_prev)->ds_next_snap_obj == ds->ds_object)
+		return (SET_ERROR(EBUSY));
+
+	/*
+	 * Can't delete if there are children of this fs.
+	 */
+	error = zap_count(mos,
+	    dsl_dir_phys(ds->ds_dir)->dd_child_dir_zapobj, &count);
+	if (error != 0)
+		return (error);
+	if (count != 0)
+		return (SET_ERROR(EEXIST));
+
+	if (dsl_dir_is_clone(ds->ds_dir) && DS_IS_DEFER_DESTROY(ds->ds_prev) &&
+	    dsl_dataset_phys(ds->ds_prev)->ds_num_children == 2 &&
+	    ds->ds_prev->ds_userrefs == 0) {
+		/* We need to remove the origin snapshot as well. */
+		if (!refcount_is_zero(&ds->ds_prev->ds_longholds))
+			return (SET_ERROR(EBUSY));
+	}
+	return (0);
+}
+
+static int
+dsl_destroy_head_check(void *arg, dmu_tx_t *tx)
+{
+	dsl_destroy_head_arg_t *ddha = arg;
+	dsl_pool_t *dp = dmu_tx_pool(tx);
+	dsl_dataset_t *ds;
+	int error;
+
+	error = dsl_dataset_hold(dp, ddha->ddha_name, FTAG, &ds);
+	if (error != 0)
+		return (error);
+
+	error = dsl_destroy_head_check_impl(ds, 0);
+	dsl_dataset_rele(ds, FTAG);
+	return (error);
+}
+
+static void
+dsl_dir_destroy_sync(uint64_t ddobj, dmu_tx_t *tx)
+{
+	dsl_dir_t *dd;
+	dsl_pool_t *dp = dmu_tx_pool(tx);
+	objset_t *mos = dp->dp_meta_objset;
+	dd_used_t t;
+
+	ASSERT(RRW_WRITE_HELD(&dmu_tx_pool(tx)->dp_config_rwlock));
+
+	VERIFY0(dsl_dir_hold_obj(dp, ddobj, NULL, FTAG, &dd));
+
+	ASSERT0(dsl_dir_phys(dd)->dd_head_dataset_obj);
+
+	/*
+	 * Decrement the filesystem count for all parent filesystems.
+	 *
+	 * When we receive an incremental stream into a filesystem that already
+	 * exists, a temporary clone is created.  We never count this temporary
+	 * clone, whose name begins with a '%'.
+	 */
+	if (dd->dd_myname[0] != '%' && dd->dd_parent != NULL)
+		dsl_fs_ss_count_adjust(dd->dd_parent, -1,
+		    DD_FIELD_FILESYSTEM_COUNT, tx);
+
+	/*
+	 * Remove our reservation. The impl() routine avoids setting the
+	 * actual property, which would require the (already destroyed) ds.
+	 */
+	dsl_dir_set_reservation_sync_impl(dd, 0, tx);
+
+	ASSERT0(dsl_dir_phys(dd)->dd_used_bytes);
+	ASSERT0(dsl_dir_phys(dd)->dd_reserved);
+	for (t = 0; t < DD_USED_NUM; t++)
+		ASSERT0(dsl_dir_phys(dd)->dd_used_breakdown[t]);
+
+	VERIFY0(zap_destroy(mos, dsl_dir_phys(dd)->dd_child_dir_zapobj, tx));
+	VERIFY0(zap_destroy(mos, dsl_dir_phys(dd)->dd_props_zapobj, tx));
+	VERIFY0(dsl_deleg_destroy(mos, dsl_dir_phys(dd)->dd_deleg_zapobj, tx));
+	VERIFY0(zap_remove(mos,
+	    dsl_dir_phys(dd->dd_parent)->dd_child_dir_zapobj,
+	    dd->dd_myname, tx));
+
+	dsl_dir_rele(dd, FTAG);
+	dmu_object_free_zapified(mos, ddobj, tx);
+}
+
+void
+dsl_destroy_head_sync_impl(dsl_dataset_t *ds, dmu_tx_t *tx)
+{
+	dsl_pool_t *dp = dmu_tx_pool(tx);
+	objset_t *mos = dp->dp_meta_objset;
+	uint64_t obj, ddobj, prevobj = 0;
+	boolean_t rmorigin;
+	objset_t *os;
+
+	ASSERT3U(dsl_dataset_phys(ds)->ds_num_children, <=, 1);
+	ASSERT(ds->ds_prev == NULL ||
+	    dsl_dataset_phys(ds->ds_prev)->ds_next_snap_obj != ds->ds_object);
+	ASSERT3U(dsl_dataset_phys(ds)->ds_bp.blk_birth, <=, tx->tx_txg);
+	ASSERT(RRW_WRITE_HELD(&dp->dp_config_rwlock));
+
+	/* We need to log before removing it from the namespace. */
+	spa_history_log_internal_ds(ds, "destroy", tx, "");
+
+	rmorigin = (dsl_dir_is_clone(ds->ds_dir) &&
+	    DS_IS_DEFER_DESTROY(ds->ds_prev) &&
+	    dsl_dataset_phys(ds->ds_prev)->ds_num_children == 2 &&
+	    ds->ds_prev->ds_userrefs == 0);
+
+	/* Remove our reservation. */
+	if (ds->ds_reserved != 0) {
+		dsl_dataset_set_refreservation_sync_impl(ds,
+		    (ZPROP_SRC_NONE | ZPROP_SRC_LOCAL | ZPROP_SRC_RECEIVED),
+		    0, tx);
+		ASSERT0(ds->ds_reserved);
+	}
+
+	if (ds->ds_large_blocks)
+		spa_feature_decr(dp->dp_spa, SPA_FEATURE_LARGE_BLOCKS, tx);
+
+	dsl_scan_ds_destroyed(ds, tx);
+
+	obj = ds->ds_object;
+
+	if (dsl_dataset_phys(ds)->ds_prev_snap_obj != 0) {
+		/* This is a clone */
+		ASSERT(ds->ds_prev != NULL);
+		ASSERT3U(dsl_dataset_phys(ds->ds_prev)->ds_next_snap_obj, !=,
+		    obj);
+		ASSERT0(dsl_dataset_phys(ds)->ds_next_snap_obj);
+
+		dmu_buf_will_dirty(ds->ds_prev->ds_dbuf, tx);
+		if (dsl_dataset_phys(ds->ds_prev)->ds_next_clones_obj != 0) {
+			dsl_dataset_remove_from_next_clones(ds->ds_prev,
+			    obj, tx);
+		}
+
+		ASSERT3U(dsl_dataset_phys(ds->ds_prev)->ds_num_children, >, 1);
+		dsl_dataset_phys(ds->ds_prev)->ds_num_children--;
+	}
+
+	/*
+	 * Destroy the deadlist.  Unless it's a clone, the
+	 * deadlist should be empty.  (If it's a clone, it's
+	 * safe to ignore the deadlist contents.)
+	 */
+	dsl_deadlist_close(&ds->ds_deadlist);
+	dsl_deadlist_free(mos, dsl_dataset_phys(ds)->ds_deadlist_obj, tx);
+	dmu_buf_will_dirty(ds->ds_dbuf, tx);
+	dsl_dataset_phys(ds)->ds_deadlist_obj = 0;
+
+	VERIFY0(dmu_objset_from_ds(ds, &os));
+
+	if (!spa_feature_is_enabled(dp->dp_spa, SPA_FEATURE_ASYNC_DESTROY)) {
+		old_synchronous_dataset_destroy(ds, tx);
+	} else {
+		/*
+		 * Move the bptree into the pool's list of trees to
+		 * clean up and update space accounting information.
+		 */
+		uint64_t used, comp, uncomp;
+
+		zil_destroy_sync(dmu_objset_zil(os), tx);
+
+		if (!spa_feature_is_active(dp->dp_spa,
+		    SPA_FEATURE_ASYNC_DESTROY)) {
+			dsl_scan_t *scn = dp->dp_scan;
+			spa_feature_incr(dp->dp_spa, SPA_FEATURE_ASYNC_DESTROY,
+			    tx);
+			dp->dp_bptree_obj = bptree_alloc(mos, tx);
+			VERIFY0(zap_add(mos,
+			    DMU_POOL_DIRECTORY_OBJECT,
+			    DMU_POOL_BPTREE_OBJ, sizeof (uint64_t), 1,
+			    &dp->dp_bptree_obj, tx));
+			ASSERT(!scn->scn_async_destroying);
+			scn->scn_async_destroying = B_TRUE;
+		}
+
+		used = dsl_dir_phys(ds->ds_dir)->dd_used_bytes;
+		comp = dsl_dir_phys(ds->ds_dir)->dd_compressed_bytes;
+		uncomp = dsl_dir_phys(ds->ds_dir)->dd_uncompressed_bytes;
+
+		ASSERT(!DS_UNIQUE_IS_ACCURATE(ds) ||
+		    dsl_dataset_phys(ds)->ds_unique_bytes == used);
+
+		bptree_add(mos, dp->dp_bptree_obj,
+		    &dsl_dataset_phys(ds)->ds_bp,
+		    dsl_dataset_phys(ds)->ds_prev_snap_txg,
+		    used, comp, uncomp, tx);
+		dsl_dir_diduse_space(ds->ds_dir, DD_USED_HEAD,
+		    -used, -comp, -uncomp, tx);
+		dsl_dir_diduse_space(dp->dp_free_dir, DD_USED_HEAD,
+		    used, comp, uncomp, tx);
+	}
+
+	if (ds->ds_prev != NULL) {
+		if (spa_version(dp->dp_spa) >= SPA_VERSION_DIR_CLONES) {
+			VERIFY0(zap_remove_int(mos,
+			    dsl_dir_phys(ds->ds_prev->ds_dir)->dd_clones,
+			    ds->ds_object, tx));
+		}
+		prevobj = ds->ds_prev->ds_object;
+		dsl_dataset_rele(ds->ds_prev, ds);
+		ds->ds_prev = NULL;
+	}
+
+	/*
+	 * This must be done after the dsl_traverse(), because it will
+	 * re-open the objset.
+	 */
+	if (ds->ds_objset) {
+		dmu_objset_evict(ds->ds_objset);
+		ds->ds_objset = NULL;
+	}
+
+	/* Erase the link in the dir */
+	dmu_buf_will_dirty(ds->ds_dir->dd_dbuf, tx);
+	dsl_dir_phys(ds->ds_dir)->dd_head_dataset_obj = 0;
+	ddobj = ds->ds_dir->dd_object;
+	ASSERT(dsl_dataset_phys(ds)->ds_snapnames_zapobj != 0);
+	VERIFY0(zap_destroy(mos,
+	    dsl_dataset_phys(ds)->ds_snapnames_zapobj, tx));
+
+	if (ds->ds_bookmarks != 0) {
+		VERIFY0(zap_destroy(mos, ds->ds_bookmarks, tx));
+		spa_feature_decr(dp->dp_spa, SPA_FEATURE_BOOKMARKS, tx);
+	}
+
+	spa_prop_clear_bootfs(dp->dp_spa, ds->ds_object, tx);
+
+	ASSERT0(dsl_dataset_phys(ds)->ds_next_clones_obj);
+	ASSERT0(dsl_dataset_phys(ds)->ds_props_obj);
+	ASSERT0(dsl_dataset_phys(ds)->ds_userrefs_obj);
+	dsl_dir_rele(ds->ds_dir, ds);
+	ds->ds_dir = NULL;
+	dmu_object_free_zapified(mos, obj, tx);
+
+	dsl_dir_destroy_sync(ddobj, tx);
+
+	if (rmorigin) {
+		dsl_dataset_t *prev;
+		VERIFY0(dsl_dataset_hold_obj(dp, prevobj, FTAG, &prev));
+		dsl_destroy_snapshot_sync_impl(prev, B_FALSE, tx);
+		dsl_dataset_rele(prev, FTAG);
+	}
+}
+
+static void
+dsl_destroy_head_sync(void *arg, dmu_tx_t *tx)
+{
+	dsl_destroy_head_arg_t *ddha = arg;
+	dsl_pool_t *dp = dmu_tx_pool(tx);
+	dsl_dataset_t *ds;
+
+	VERIFY0(dsl_dataset_hold(dp, ddha->ddha_name, FTAG, &ds));
+	dsl_destroy_head_sync_impl(ds, tx);
+	zvol_remove_minors(dp->dp_spa, ddha->ddha_name, B_TRUE);
+	dsl_dataset_rele(ds, FTAG);
+}
+
+static void
+dsl_destroy_head_begin_sync(void *arg, dmu_tx_t *tx)
+{
+	dsl_destroy_head_arg_t *ddha = arg;
+	dsl_pool_t *dp = dmu_tx_pool(tx);
+	dsl_dataset_t *ds;
+
+	VERIFY0(dsl_dataset_hold(dp, ddha->ddha_name, FTAG, &ds));
+
+	/* Mark it as inconsistent on-disk, in case we crash */
+	dmu_buf_will_dirty(ds->ds_dbuf, tx);
+	dsl_dataset_phys(ds)->ds_flags |= DS_FLAG_INCONSISTENT;
+
+	spa_history_log_internal_ds(ds, "destroy begin", tx, "");
+	dsl_dataset_rele(ds, FTAG);
+}
+
+int
+dsl_destroy_head(const char *name)
+{
+	dsl_destroy_head_arg_t ddha;
+	int error;
+	spa_t *spa;
+	boolean_t isenabled;
+
+#ifdef _KERNEL
+	zfs_destroy_unmount_origin(name);
+#endif
+
+	error = spa_open(name, &spa, FTAG);
+	if (error != 0)
+		return (error);
+	isenabled = spa_feature_is_enabled(spa, SPA_FEATURE_ASYNC_DESTROY);
+	spa_close(spa, FTAG);
+
+	ddha.ddha_name = name;
+
+	if (!isenabled) {
+		objset_t *os;
+
+		error = dsl_sync_task(name, dsl_destroy_head_check,
+		    dsl_destroy_head_begin_sync, &ddha,
+		    0, ZFS_SPACE_CHECK_NONE);
+		if (error != 0)
+			return (error);
+
+		/*
+		 * Head deletion is processed in one txg on old pools;
+		 * remove the objects from open context so that the txg sync
+		 * is not too long.
+		 */
+		error = dmu_objset_own(name, DMU_OST_ANY, B_FALSE, FTAG, &os);
+		if (error == 0) {
+			uint64_t obj;
+			uint64_t prev_snap_txg =
+			    dsl_dataset_phys(dmu_objset_ds(os))->
+			    ds_prev_snap_txg;
+			for (obj = 0; error == 0;
+			    error = dmu_object_next(os, &obj, FALSE,
+			    prev_snap_txg))
+				(void) dmu_free_long_object(os, obj);
+			/* sync out all frees */
+			txg_wait_synced(dmu_objset_pool(os), 0);
+			dmu_objset_disown(os, FTAG);
+		}
+	}
+
+	return (dsl_sync_task(name, dsl_destroy_head_check,
+	    dsl_destroy_head_sync, &ddha, 0, ZFS_SPACE_CHECK_NONE));
+}
+
+/*
+ * Note, this function is used as the callback for dmu_objset_find().  We
+ * always return 0 so that we will continue to find and process
+ * inconsistent datasets, even if we encounter an error trying to
+ * process one of them.
+ */
+/* ARGSUSED */
+int
+dsl_destroy_inconsistent(const char *dsname, void *arg)
+{
+	objset_t *os;
+
+	if (dmu_objset_hold(dsname, FTAG, &os) == 0) {
+		boolean_t inconsistent = DS_IS_INCONSISTENT(dmu_objset_ds(os));
+		dmu_objset_rele(os, FTAG);
+		if (inconsistent)
+			(void) dsl_destroy_head(dsname);
+	}
+	return (0);
+}
+
+
+#if defined(_KERNEL) && defined(HAVE_SPL)
+EXPORT_SYMBOL(dsl_destroy_head);
+EXPORT_SYMBOL(dsl_destroy_head_sync_impl);
+EXPORT_SYMBOL(dsl_dataset_user_hold_check_one);
+EXPORT_SYMBOL(dsl_destroy_snapshot_sync_impl);
+EXPORT_SYMBOL(dsl_destroy_inconsistent);
+EXPORT_SYMBOL(dsl_dataset_user_release_tmp);
+EXPORT_SYMBOL(dsl_destroy_head_check_impl);
+#endif
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/module/zfs/dsl_dir.c
@@ -0,0 +1,2009 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2014 by Delphix. All rights reserved.
+ * Copyright (c) 2013 Martin Matuska. All rights reserved.
+ * Copyright (c) 2014 Joyent, Inc. All rights reserved.
+ * Copyright (c) 2014 Spectra Logic Corporation, All rights reserved.
+ * Copyright (c) 2016 Actifio, Inc. All rights reserved.
+ */
+
+#include <sys/dmu.h>
+#include <sys/dmu_objset.h>
+#include <sys/dmu_tx.h>
+#include <sys/dsl_dataset.h>
+#include <sys/dsl_dir.h>
+#include <sys/dsl_prop.h>
+#include <sys/dsl_synctask.h>
+#include <sys/dsl_deleg.h>
+#include <sys/dmu_impl.h>
+#include <sys/spa.h>
+#include <sys/metaslab.h>
+#include <sys/zap.h>
+#include <sys/zio.h>
+#include <sys/arc.h>
+#include <sys/sunddi.h>
+#include <sys/zfeature.h>
+#include <sys/policy.h>
+#include <sys/zfs_znode.h>
+#include <sys/zvol.h>
+#include "zfs_namecheck.h"
+#include "zfs_prop.h"
+
+/*
+ * Filesystem and Snapshot Limits
+ * ------------------------------
+ *
+ * These limits are used to restrict the number of filesystems and/or snapshots
+ * that can be created at a given level in the tree or below. A typical
+ * use-case is with a delegated dataset where the administrator wants to ensure
+ * that a user within the zone is not creating too many additional filesystems
+ * or snapshots, even though they're not exceeding their space quota.
+ *
+ * The filesystem and snapshot counts are stored as extensible properties. This
+ * capability is controlled by a feature flag and must be enabled to be used.
+ * Once enabled, the feature is not active until the first limit is set. At
+ * that point, future operations to create/destroy filesystems or snapshots
+ * will validate and update the counts.
+ *
+ * Because the count properties will not exist before the feature is active,
+ * the counts are updated when a limit is first set on an uninitialized
+ * dsl_dir node in the tree (The filesystem/snapshot count on a node includes
+ * all of the nested filesystems/snapshots. Thus, a new leaf node has a
+ * filesystem count of 0 and a snapshot count of 0. Non-existent filesystem and
+ * snapshot count properties on a node indicate uninitialized counts on that
+ * node.) When first setting a limit on an uninitialized node, the code starts
+ * at the filesystem with the new limit and descends into all sub-filesystems
+ * to add the count properties.
+ *
+ * In practice this is lightweight since a limit is typically set when the
+ * filesystem is created and thus has no children. Once valid, changing the
+ * limit value won't require a re-traversal since the counts are already valid.
+ * When recursively fixing the counts, if a node with a limit is encountered
+ * during the descent, the counts are known to be valid and there is no need to
+ * descend into that filesystem's children. The counts on filesystems above the
+ * one with the new limit will still be uninitialized, unless a limit is
+ * eventually set on one of those filesystems. The counts are always recursively
+ * updated when a limit is set on a dataset, unless there is already a limit.
+ * When a new limit value is set on a filesystem with an existing limit, it is
+ * possible for the new limit to be less than the current count at that level
+ * since a user who can change the limit is also allowed to exceed the limit.
+ *
+ * Once the feature is active, then whenever a filesystem or snapshot is
+ * created, the code recurses up the tree, validating the new count against the
+ * limit at each initialized level. In practice, most levels will not have a
+ * limit set. If there is a limit at any initialized level up the tree, the
+ * check must pass or the creation will fail. Likewise, when a filesystem or
+ * snapshot is destroyed, the counts are recursively adjusted all the way up
+ * the initizized nodes in the tree. Renaming a filesystem into different point
+ * in the tree will first validate, then update the counts on each branch up to
+ * the common ancestor. A receive will also validate the counts and then update
+ * them.
+ *
+ * An exception to the above behavior is that the limit is not enforced if the
+ * user has permission to modify the limit. This is primarily so that
+ * recursive snapshots in the global zone always work. We want to prevent a
+ * denial-of-service in which a lower level delegated dataset could max out its
+ * limit and thus block recursive snapshots from being taken in the global zone.
+ * Because of this, it is possible for the snapshot count to be over the limit
+ * and snapshots taken in the global zone could cause a lower level dataset to
+ * hit or exceed its limit. The administrator taking the global zone recursive
+ * snapshot should be aware of this side-effect and behave accordingly.
+ * For consistency, the filesystem limit is also not enforced if the user can
+ * modify the limit.
+ *
+ * The filesystem and snapshot limits are validated by dsl_fs_ss_limit_check()
+ * and updated by dsl_fs_ss_count_adjust(). A new limit value is setup in
+ * dsl_dir_activate_fs_ss_limit() and the counts are adjusted, if necessary, by
+ * dsl_dir_init_fs_ss_count().
+ *
+ * There is a special case when we receive a filesystem that already exists. In
+ * this case a temporary clone name of %X is created (see dmu_recv_begin). We
+ * never update the filesystem counts for temporary clones.
+ *
+ * Likewise, we do not update the snapshot counts for temporary snapshots,
+ * such as those created by zfs diff.
+ */
+
+extern inline dsl_dir_phys_t *dsl_dir_phys(dsl_dir_t *dd);
+
+static uint64_t dsl_dir_space_towrite(dsl_dir_t *dd);
+
+static void
+dsl_dir_evict(void *dbu)
+{
+	dsl_dir_t *dd = dbu;
+	int t;
+	ASSERTV(dsl_pool_t *dp = dd->dd_pool);
+
+	dd->dd_dbuf = NULL;
+
+	for (t = 0; t < TXG_SIZE; t++) {
+		ASSERT(!txg_list_member(&dp->dp_dirty_dirs, dd, t));
+		ASSERT(dd->dd_tempreserved[t] == 0);
+		ASSERT(dd->dd_space_towrite[t] == 0);
+	}
+
+	if (dd->dd_parent)
+		dsl_dir_async_rele(dd->dd_parent, dd);
+
+	spa_async_close(dd->dd_pool->dp_spa, dd);
+
+	/*
+	 * The props callback list should have been cleaned up by
+	 * objset_evict().
+	 */
+	list_destroy(&dd->dd_prop_cbs);
+	mutex_destroy(&dd->dd_lock);
+	kmem_free(dd, sizeof (dsl_dir_t));
+}
+
+int
+dsl_dir_hold_obj(dsl_pool_t *dp, uint64_t ddobj,
+    const char *tail, void *tag, dsl_dir_t **ddp)
+{
+	dmu_buf_t *dbuf;
+	dsl_dir_t *dd;
+	int err;
+
+	ASSERT(dsl_pool_config_held(dp));
+
+	err = dmu_bonus_hold(dp->dp_meta_objset, ddobj, tag, &dbuf);
+	if (err != 0)
+		return (err);
+	dd = dmu_buf_get_user(dbuf);
+#ifdef ZFS_DEBUG
+	{
+		dmu_object_info_t doi;
+		dmu_object_info_from_db(dbuf, &doi);
+		ASSERT3U(doi.doi_bonus_type, ==, DMU_OT_DSL_DIR);
+		ASSERT3U(doi.doi_bonus_size, >=, sizeof (dsl_dir_phys_t));
+	}
+#endif
+	if (dd == NULL) {
+		dsl_dir_t *winner;
+
+		dd = kmem_zalloc(sizeof (dsl_dir_t), KM_SLEEP);
+		dd->dd_object = ddobj;
+		dd->dd_dbuf = dbuf;
+		dd->dd_pool = dp;
+		mutex_init(&dd->dd_lock, NULL, MUTEX_DEFAULT, NULL);
+
+		list_create(&dd->dd_prop_cbs, sizeof (dsl_prop_cb_record_t),
+		    offsetof(dsl_prop_cb_record_t, cbr_node));
+
+		dsl_dir_snap_cmtime_update(dd);
+
+		if (dsl_dir_phys(dd)->dd_parent_obj) {
+			err = dsl_dir_hold_obj(dp,
+			    dsl_dir_phys(dd)->dd_parent_obj, NULL, dd,
+			    &dd->dd_parent);
+			if (err != 0)
+				goto errout;
+			if (tail) {
+#ifdef ZFS_DEBUG
+				uint64_t foundobj;
+
+				err = zap_lookup(dp->dp_meta_objset,
+				    dsl_dir_phys(dd->dd_parent)->
+				    dd_child_dir_zapobj, tail,
+				    sizeof (foundobj), 1, &foundobj);
+				ASSERT(err || foundobj == ddobj);
+#endif
+				(void) strcpy(dd->dd_myname, tail);
+			} else {
+				err = zap_value_search(dp->dp_meta_objset,
+				    dsl_dir_phys(dd->dd_parent)->
+				    dd_child_dir_zapobj,
+				    ddobj, 0, dd->dd_myname);
+			}
+			if (err != 0)
+				goto errout;
+		} else {
+			(void) strcpy(dd->dd_myname, spa_name(dp->dp_spa));
+		}
+
+		if (dsl_dir_is_clone(dd)) {
+			dmu_buf_t *origin_bonus;
+			dsl_dataset_phys_t *origin_phys;
+
+			/*
+			 * We can't open the origin dataset, because
+			 * that would require opening this dsl_dir.
+			 * Just look at its phys directly instead.
+			 */
+			err = dmu_bonus_hold(dp->dp_meta_objset,
+			    dsl_dir_phys(dd)->dd_origin_obj, FTAG,
+			    &origin_bonus);
+			if (err != 0)
+				goto errout;
+			origin_phys = origin_bonus->db_data;
+			dd->dd_origin_txg =
+			    origin_phys->ds_creation_txg;
+			dmu_buf_rele(origin_bonus, FTAG);
+		}
+
+		dmu_buf_init_user(&dd->dd_dbu, dsl_dir_evict, &dd->dd_dbuf);
+		winner = dmu_buf_set_user_ie(dbuf, &dd->dd_dbu);
+		if (winner != NULL) {
+			if (dd->dd_parent)
+				dsl_dir_rele(dd->dd_parent, dd);
+			mutex_destroy(&dd->dd_lock);
+			kmem_free(dd, sizeof (dsl_dir_t));
+			dd = winner;
+		} else {
+			spa_open_ref(dp->dp_spa, dd);
+		}
+	}
+
+	/*
+	 * The dsl_dir_t has both open-to-close and instantiate-to-evict
+	 * holds on the spa.  We need the open-to-close holds because
+	 * otherwise the spa_refcnt wouldn't change when we open a
+	 * dir which the spa also has open, so we could incorrectly
+	 * think it was OK to unload/export/destroy the pool.  We need
+	 * the instantiate-to-evict hold because the dsl_dir_t has a
+	 * pointer to the dd_pool, which has a pointer to the spa_t.
+	 */
+	spa_open_ref(dp->dp_spa, tag);
+	ASSERT3P(dd->dd_pool, ==, dp);
+	ASSERT3U(dd->dd_object, ==, ddobj);
+	ASSERT3P(dd->dd_dbuf, ==, dbuf);
+	*ddp = dd;
+	return (0);
+
+errout:
+	if (dd->dd_parent)
+		dsl_dir_rele(dd->dd_parent, dd);
+	mutex_destroy(&dd->dd_lock);
+	kmem_free(dd, sizeof (dsl_dir_t));
+	dmu_buf_rele(dbuf, tag);
+	return (err);
+}
+
+void
+dsl_dir_rele(dsl_dir_t *dd, void *tag)
+{
+	dprintf_dd(dd, "%s\n", "");
+	spa_close(dd->dd_pool->dp_spa, tag);
+	dmu_buf_rele(dd->dd_dbuf, tag);
+}
+
+/*
+ * Remove a reference to the given dsl dir that is being asynchronously
+ * released.  Async releases occur from a taskq performing eviction of
+ * dsl datasets and dirs.  This process is identical to a normal release
+ * with the exception of using the async API for releasing the reference on
+ * the spa.
+ */
+void
+dsl_dir_async_rele(dsl_dir_t *dd, void *tag)
+{
+	dprintf_dd(dd, "%s\n", "");
+	spa_async_close(dd->dd_pool->dp_spa, tag);
+	dmu_buf_rele(dd->dd_dbuf, tag);
+}
+
+/* buf must be long enough (MAXNAMELEN + strlen(MOS_DIR_NAME) + 1 should do) */
+void
+dsl_dir_name(dsl_dir_t *dd, char *buf)
+{
+	if (dd->dd_parent) {
+		dsl_dir_name(dd->dd_parent, buf);
+		(void) strcat(buf, "/");
+	} else {
+		buf[0] = '\0';
+	}
+	if (!MUTEX_HELD(&dd->dd_lock)) {
+		/*
+		 * recursive mutex so that we can use
+		 * dprintf_dd() with dd_lock held
+		 */
+		mutex_enter(&dd->dd_lock);
+		(void) strcat(buf, dd->dd_myname);
+		mutex_exit(&dd->dd_lock);
+	} else {
+		(void) strcat(buf, dd->dd_myname);
+	}
+}
+
+/* Calculate name length, avoiding all the strcat calls of dsl_dir_name */
+int
+dsl_dir_namelen(dsl_dir_t *dd)
+{
+	int result = 0;
+
+	if (dd->dd_parent) {
+		/* parent's name + 1 for the "/" */
+		result = dsl_dir_namelen(dd->dd_parent) + 1;
+	}
+
+	if (!MUTEX_HELD(&dd->dd_lock)) {
+		/* see dsl_dir_name */
+		mutex_enter(&dd->dd_lock);
+		result += strlen(dd->dd_myname);
+		mutex_exit(&dd->dd_lock);
+	} else {
+		result += strlen(dd->dd_myname);
+	}
+
+	return (result);
+}
+
+static int
+getcomponent(const char *path, char *component, const char **nextp)
+{
+	char *p;
+
+	if ((path == NULL) || (path[0] == '\0'))
+		return (SET_ERROR(ENOENT));
+	/* This would be a good place to reserve some namespace... */
+	p = strpbrk(path, "/@");
+	if (p && (p[1] == '/' || p[1] == '@')) {
+		/* two separators in a row */
+		return (SET_ERROR(EINVAL));
+	}
+	if (p == NULL || p == path) {
+		/*
+		 * if the first thing is an @ or /, it had better be an
+		 * @ and it had better not have any more ats or slashes,
+		 * and it had better have something after the @.
+		 */
+		if (p != NULL &&
+		    (p[0] != '@' || strpbrk(path+1, "/@") || p[1] == '\0'))
+			return (SET_ERROR(EINVAL));
+		if (strlen(path) >= MAXNAMELEN)
+			return (SET_ERROR(ENAMETOOLONG));
+		(void) strcpy(component, path);
+		p = NULL;
+	} else if (p[0] == '/') {
+		if (p - path >= MAXNAMELEN)
+			return (SET_ERROR(ENAMETOOLONG));
+		(void) strncpy(component, path, p - path);
+		component[p - path] = '\0';
+		p++;
+	} else if (p[0] == '@') {
+		/*
+		 * if the next separator is an @, there better not be
+		 * any more slashes.
+		 */
+		if (strchr(path, '/'))
+			return (SET_ERROR(EINVAL));
+		if (p - path >= MAXNAMELEN)
+			return (SET_ERROR(ENAMETOOLONG));
+		(void) strncpy(component, path, p - path);
+		component[p - path] = '\0';
+	} else {
+		panic("invalid p=%p", (void *)p);
+	}
+	*nextp = p;
+	return (0);
+}
+
+/*
+ * Return the dsl_dir_t, and possibly the last component which couldn't
+ * be found in *tail.  The name must be in the specified dsl_pool_t.  This
+ * thread must hold the dp_config_rwlock for the pool.  Returns NULL if the
+ * path is bogus, or if tail==NULL and we couldn't parse the whole name.
+ * (*tail)[0] == '@' means that the last component is a snapshot.
+ */
+int
+dsl_dir_hold(dsl_pool_t *dp, const char *name, void *tag,
+    dsl_dir_t **ddp, const char **tailp)
+{
+	char *buf;
+	const char *spaname, *next, *nextnext = NULL;
+	int err;
+	dsl_dir_t *dd;
+	uint64_t ddobj;
+
+	buf = kmem_alloc(MAXNAMELEN, KM_SLEEP);
+	err = getcomponent(name, buf, &next);
+	if (err != 0)
+		goto error;
+
+	/* Make sure the name is in the specified pool. */
+	spaname = spa_name(dp->dp_spa);
+	if (strcmp(buf, spaname) != 0) {
+		err = SET_ERROR(EXDEV);
+		goto error;
+	}
+
+	ASSERT(dsl_pool_config_held(dp));
+
+	err = dsl_dir_hold_obj(dp, dp->dp_root_dir_obj, NULL, tag, &dd);
+	if (err != 0) {
+		goto error;
+	}
+
+	while (next != NULL) {
+		dsl_dir_t *child_dd;
+		err = getcomponent(next, buf, &nextnext);
+		if (err != 0)
+			break;
+		ASSERT(next[0] != '\0');
+		if (next[0] == '@')
+			break;
+		dprintf("looking up %s in obj%lld\n",
+		    buf, dsl_dir_phys(dd)->dd_child_dir_zapobj);
+
+		err = zap_lookup(dp->dp_meta_objset,
+		    dsl_dir_phys(dd)->dd_child_dir_zapobj,
+		    buf, sizeof (ddobj), 1, &ddobj);
+		if (err != 0) {
+			if (err == ENOENT)
+				err = 0;
+			break;
+		}
+
+		err = dsl_dir_hold_obj(dp, ddobj, buf, tag, &child_dd);
+		if (err != 0)
+			break;
+		dsl_dir_rele(dd, tag);
+		dd = child_dd;
+		next = nextnext;
+	}
+
+	if (err != 0) {
+		dsl_dir_rele(dd, tag);
+		goto error;
+	}
+
+	/*
+	 * It's an error if there's more than one component left, or
+	 * tailp==NULL and there's any component left.
+	 */
+	if (next != NULL &&
+	    (tailp == NULL || (nextnext && nextnext[0] != '\0'))) {
+		/* bad path name */
+		dsl_dir_rele(dd, tag);
+		dprintf("next=%p (%s) tail=%p\n", next, next?next:"", tailp);
+		err = SET_ERROR(ENOENT);
+	}
+	if (tailp != NULL)
+		*tailp = next;
+	*ddp = dd;
+error:
+	kmem_free(buf, MAXNAMELEN);
+	return (err);
+}
+
+/*
+ * If the counts are already initialized for this filesystem and its
+ * descendants then do nothing, otherwise initialize the counts.
+ *
+ * The counts on this filesystem, and those below, may be uninitialized due to
+ * either the use of a pre-existing pool which did not support the
+ * filesystem/snapshot limit feature, or one in which the feature had not yet
+ * been enabled.
+ *
+ * Recursively descend the filesystem tree and update the filesystem/snapshot
+ * counts on each filesystem below, then update the cumulative count on the
+ * current filesystem. If the filesystem already has a count set on it,
+ * then we know that its counts, and the counts on the filesystems below it,
+ * are already correct, so we don't have to update this filesystem.
+ */
+static void
+dsl_dir_init_fs_ss_count(dsl_dir_t *dd, dmu_tx_t *tx)
+{
+	uint64_t my_fs_cnt = 0;
+	uint64_t my_ss_cnt = 0;
+	dsl_pool_t *dp = dd->dd_pool;
+	objset_t *os = dp->dp_meta_objset;
+	zap_cursor_t *zc;
+	zap_attribute_t *za;
+	dsl_dataset_t *ds;
+
+	ASSERT(spa_feature_is_active(dp->dp_spa, SPA_FEATURE_FS_SS_LIMIT));
+	ASSERT(dsl_pool_config_held(dp));
+	ASSERT(dmu_tx_is_syncing(tx));
+
+	dsl_dir_zapify(dd, tx);
+
+	/*
+	 * If the filesystem count has already been initialized then we
+	 * don't need to recurse down any further.
+	 */
+	if (zap_contains(os, dd->dd_object, DD_FIELD_FILESYSTEM_COUNT) == 0)
+		return;
+
+	zc = kmem_alloc(sizeof (zap_cursor_t), KM_SLEEP);
+	za = kmem_alloc(sizeof (zap_attribute_t), KM_SLEEP);
+
+	/* Iterate my child dirs */
+	for (zap_cursor_init(zc, os, dsl_dir_phys(dd)->dd_child_dir_zapobj);
+	    zap_cursor_retrieve(zc, za) == 0; zap_cursor_advance(zc)) {
+		dsl_dir_t *chld_dd;
+		uint64_t count;
+
+		VERIFY0(dsl_dir_hold_obj(dp, za->za_first_integer, NULL, FTAG,
+		    &chld_dd));
+
+		/*
+		 * Ignore hidden ($FREE, $MOS & $ORIGIN) objsets and
+		 * temporary datasets.
+		 */
+		if (chld_dd->dd_myname[0] == '$' ||
+		    chld_dd->dd_myname[0] == '%') {
+			dsl_dir_rele(chld_dd, FTAG);
+			continue;
+		}
+
+		my_fs_cnt++;	/* count this child */
+
+		dsl_dir_init_fs_ss_count(chld_dd, tx);
+
+		VERIFY0(zap_lookup(os, chld_dd->dd_object,
+		    DD_FIELD_FILESYSTEM_COUNT, sizeof (count), 1, &count));
+		my_fs_cnt += count;
+		VERIFY0(zap_lookup(os, chld_dd->dd_object,
+		    DD_FIELD_SNAPSHOT_COUNT, sizeof (count), 1, &count));
+		my_ss_cnt += count;
+
+		dsl_dir_rele(chld_dd, FTAG);
+	}
+	zap_cursor_fini(zc);
+	/* Count my snapshots (we counted children's snapshots above) */
+	VERIFY0(dsl_dataset_hold_obj(dd->dd_pool,
+	    dsl_dir_phys(dd)->dd_head_dataset_obj, FTAG, &ds));
+
+	for (zap_cursor_init(zc, os, dsl_dataset_phys(ds)->ds_snapnames_zapobj);
+	    zap_cursor_retrieve(zc, za) == 0;
+	    zap_cursor_advance(zc)) {
+		/* Don't count temporary snapshots */
+		if (za->za_name[0] != '%')
+			my_ss_cnt++;
+	}
+	zap_cursor_fini(zc);
+
+	dsl_dataset_rele(ds, FTAG);
+
+	kmem_free(zc, sizeof (zap_cursor_t));
+	kmem_free(za, sizeof (zap_attribute_t));
+
+	/* we're in a sync task, update counts */
+	dmu_buf_will_dirty(dd->dd_dbuf, tx);
+	VERIFY0(zap_add(os, dd->dd_object, DD_FIELD_FILESYSTEM_COUNT,
+	    sizeof (my_fs_cnt), 1, &my_fs_cnt, tx));
+	VERIFY0(zap_add(os, dd->dd_object, DD_FIELD_SNAPSHOT_COUNT,
+	    sizeof (my_ss_cnt), 1, &my_ss_cnt, tx));
+}
+
+static int
+dsl_dir_actv_fs_ss_limit_check(void *arg, dmu_tx_t *tx)
+{
+	char *ddname = (char *)arg;
+	dsl_pool_t *dp = dmu_tx_pool(tx);
+	dsl_dataset_t *ds;
+	dsl_dir_t *dd;
+	int error;
+
+	error = dsl_dataset_hold(dp, ddname, FTAG, &ds);
+	if (error != 0)
+		return (error);
+
+	if (!spa_feature_is_enabled(dp->dp_spa, SPA_FEATURE_FS_SS_LIMIT)) {
+		dsl_dataset_rele(ds, FTAG);
+		return (SET_ERROR(ENOTSUP));
+	}
+
+	dd = ds->ds_dir;
+	if (spa_feature_is_active(dp->dp_spa, SPA_FEATURE_FS_SS_LIMIT) &&
+	    dsl_dir_is_zapified(dd) &&
+	    zap_contains(dp->dp_meta_objset, dd->dd_object,
+	    DD_FIELD_FILESYSTEM_COUNT) == 0) {
+		dsl_dataset_rele(ds, FTAG);
+		return (SET_ERROR(EALREADY));
+	}
+
+	dsl_dataset_rele(ds, FTAG);
+	return (0);
+}
+
+static void
+dsl_dir_actv_fs_ss_limit_sync(void *arg, dmu_tx_t *tx)
+{
+	char *ddname = (char *)arg;
+	dsl_pool_t *dp = dmu_tx_pool(tx);
+	dsl_dataset_t *ds;
+	spa_t *spa;
+
+	VERIFY0(dsl_dataset_hold(dp, ddname, FTAG, &ds));
+
+	spa = dsl_dataset_get_spa(ds);
+
+	if (!spa_feature_is_active(spa, SPA_FEATURE_FS_SS_LIMIT)) {
+		/*
+		 * Since the feature was not active and we're now setting a
+		 * limit, increment the feature-active counter so that the
+		 * feature becomes active for the first time.
+		 *
+		 * We are already in a sync task so we can update the MOS.
+		 */
+		spa_feature_incr(spa, SPA_FEATURE_FS_SS_LIMIT, tx);
+	}
+
+	/*
+	 * Since we are now setting a non-UINT64_MAX limit on the filesystem,
+	 * we need to ensure the counts are correct. Descend down the tree from
+	 * this point and update all of the counts to be accurate.
+	 */
+	dsl_dir_init_fs_ss_count(ds->ds_dir, tx);
+
+	dsl_dataset_rele(ds, FTAG);
+}
+
+/*
+ * Make sure the feature is enabled and activate it if necessary.
+ * Since we're setting a limit, ensure the on-disk counts are valid.
+ * This is only called by the ioctl path when setting a limit value.
+ *
+ * We do not need to validate the new limit, since users who can change the
+ * limit are also allowed to exceed the limit.
+ */
+int
+dsl_dir_activate_fs_ss_limit(const char *ddname)
+{
+	int error;
+
+	error = dsl_sync_task(ddname, dsl_dir_actv_fs_ss_limit_check,
+	    dsl_dir_actv_fs_ss_limit_sync, (void *)ddname, 0,
+	    ZFS_SPACE_CHECK_RESERVED);
+
+	if (error == EALREADY)
+		error = 0;
+
+	return (error);
+}
+
+/*
+ * Used to determine if the filesystem_limit or snapshot_limit should be
+ * enforced. We allow the limit to be exceeded if the user has permission to
+ * write the property value. We pass in the creds that we got in the open
+ * context since we will always be the GZ root in syncing context. We also have
+ * to handle the case where we are allowed to change the limit on the current
+ * dataset, but there may be another limit in the tree above.
+ *
+ * We can never modify these two properties within a non-global zone. In
+ * addition, the other checks are modeled on zfs_secpolicy_write_perms. We
+ * can't use that function since we are already holding the dp_config_rwlock.
+ * In addition, we already have the dd and dealing with snapshots is simplified
+ * in this code.
+ */
+
+typedef enum {
+	ENFORCE_ALWAYS,
+	ENFORCE_NEVER,
+	ENFORCE_ABOVE
+} enforce_res_t;
+
+static enforce_res_t
+dsl_enforce_ds_ss_limits(dsl_dir_t *dd, zfs_prop_t prop, cred_t *cr)
+{
+	enforce_res_t enforce = ENFORCE_ALWAYS;
+	uint64_t obj;
+	dsl_dataset_t *ds;
+	uint64_t zoned;
+
+	ASSERT(prop == ZFS_PROP_FILESYSTEM_LIMIT ||
+	    prop == ZFS_PROP_SNAPSHOT_LIMIT);
+
+#ifdef _KERNEL
+	if (crgetzoneid(cr) != GLOBAL_ZONEID)
+		return (ENFORCE_ALWAYS);
+
+	if (secpolicy_zfs(cr) == 0)
+		return (ENFORCE_NEVER);
+#endif
+
+	if ((obj = dsl_dir_phys(dd)->dd_head_dataset_obj) == 0)
+		return (ENFORCE_ALWAYS);
+
+	ASSERT(dsl_pool_config_held(dd->dd_pool));
+
+	if (dsl_dataset_hold_obj(dd->dd_pool, obj, FTAG, &ds) != 0)
+		return (ENFORCE_ALWAYS);
+
+	if (dsl_prop_get_ds(ds, "zoned", 8, 1, &zoned, NULL) || zoned) {
+		/* Only root can access zoned fs's from the GZ */
+		enforce = ENFORCE_ALWAYS;
+	} else {
+		if (dsl_deleg_access_impl(ds, zfs_prop_to_name(prop), cr) == 0)
+			enforce = ENFORCE_ABOVE;
+	}
+
+	dsl_dataset_rele(ds, FTAG);
+	return (enforce);
+}
+
+/*
+ * Check if adding additional child filesystem(s) would exceed any filesystem
+ * limits or adding additional snapshot(s) would exceed any snapshot limits.
+ * The prop argument indicates which limit to check.
+ *
+ * Note that all filesystem limits up to the root (or the highest
+ * initialized) filesystem or the given ancestor must be satisfied.
+ */
+int
+dsl_fs_ss_limit_check(dsl_dir_t *dd, uint64_t delta, zfs_prop_t prop,
+    dsl_dir_t *ancestor, cred_t *cr)
+{
+	objset_t *os = dd->dd_pool->dp_meta_objset;
+	uint64_t limit, count;
+	char *count_prop;
+	enforce_res_t enforce;
+	int err = 0;
+
+	ASSERT(dsl_pool_config_held(dd->dd_pool));
+	ASSERT(prop == ZFS_PROP_FILESYSTEM_LIMIT ||
+	    prop == ZFS_PROP_SNAPSHOT_LIMIT);
+
+	/*
+	 * If we're allowed to change the limit, don't enforce the limit
+	 * e.g. this can happen if a snapshot is taken by an administrative
+	 * user in the global zone (i.e. a recursive snapshot by root).
+	 * However, we must handle the case of delegated permissions where we
+	 * are allowed to change the limit on the current dataset, but there
+	 * is another limit in the tree above.
+	 */
+	enforce = dsl_enforce_ds_ss_limits(dd, prop, cr);
+	if (enforce == ENFORCE_NEVER)
+		return (0);
+
+	/*
+	 * e.g. if renaming a dataset with no snapshots, count adjustment
+	 * is 0.
+	 */
+	if (delta == 0)
+		return (0);
+
+	if (prop == ZFS_PROP_SNAPSHOT_LIMIT) {
+		/*
+		 * We don't enforce the limit for temporary snapshots. This is
+		 * indicated by a NULL cred_t argument.
+		 */
+		if (cr == NULL)
+			return (0);
+
+		count_prop = DD_FIELD_SNAPSHOT_COUNT;
+	} else {
+		count_prop = DD_FIELD_FILESYSTEM_COUNT;
+	}
+
+	/*
+	 * If an ancestor has been provided, stop checking the limit once we
+	 * hit that dir. We need this during rename so that we don't overcount
+	 * the check once we recurse up to the common ancestor.
+	 */
+	if (ancestor == dd)
+		return (0);
+
+	/*
+	 * If we hit an uninitialized node while recursing up the tree, we can
+	 * stop since we know there is no limit here (or above). The counts are
+	 * not valid on this node and we know we won't touch this node's counts.
+	 */
+	if (!dsl_dir_is_zapified(dd) || zap_lookup(os, dd->dd_object,
+	    count_prop, sizeof (count), 1, &count) == ENOENT)
+		return (0);
+
+	err = dsl_prop_get_dd(dd, zfs_prop_to_name(prop), 8, 1, &limit, NULL,
+	    B_FALSE);
+	if (err != 0)
+		return (err);
+
+	/* Is there a limit which we've hit? */
+	if (enforce == ENFORCE_ALWAYS && (count + delta) > limit)
+		return (SET_ERROR(EDQUOT));
+
+	if (dd->dd_parent != NULL)
+		err = dsl_fs_ss_limit_check(dd->dd_parent, delta, prop,
+		    ancestor, cr);
+
+	return (err);
+}
+
+/*
+ * Adjust the filesystem or snapshot count for the specified dsl_dir_t and all
+ * parents. When a new filesystem/snapshot is created, increment the count on
+ * all parents, and when a filesystem/snapshot is destroyed, decrement the
+ * count.
+ */
+void
+dsl_fs_ss_count_adjust(dsl_dir_t *dd, int64_t delta, const char *prop,
+    dmu_tx_t *tx)
+{
+	int err;
+	objset_t *os = dd->dd_pool->dp_meta_objset;
+	uint64_t count;
+
+	ASSERT(dsl_pool_config_held(dd->dd_pool));
+	ASSERT(dmu_tx_is_syncing(tx));
+	ASSERT(strcmp(prop, DD_FIELD_FILESYSTEM_COUNT) == 0 ||
+	    strcmp(prop, DD_FIELD_SNAPSHOT_COUNT) == 0);
+
+	/*
+	 * When we receive an incremental stream into a filesystem that already
+	 * exists, a temporary clone is created.  We don't count this temporary
+	 * clone, whose name begins with a '%'. We also ignore hidden ($FREE,
+	 * $MOS & $ORIGIN) objsets.
+	 */
+	if ((dd->dd_myname[0] == '%' || dd->dd_myname[0] == '$') &&
+	    strcmp(prop, DD_FIELD_FILESYSTEM_COUNT) == 0)
+		return;
+
+	/*
+	 * e.g. if renaming a dataset with no snapshots, count adjustment is 0
+	 */
+	if (delta == 0)
+		return;
+
+	/*
+	 * If we hit an uninitialized node while recursing up the tree, we can
+	 * stop since we know the counts are not valid on this node and we
+	 * know we shouldn't touch this node's counts. An uninitialized count
+	 * on the node indicates that either the feature has not yet been
+	 * activated or there are no limits on this part of the tree.
+	 */
+	if (!dsl_dir_is_zapified(dd) || (err = zap_lookup(os, dd->dd_object,
+	    prop, sizeof (count), 1, &count)) == ENOENT)
+		return;
+	VERIFY0(err);
+
+	count += delta;
+	/* Use a signed verify to make sure we're not neg. */
+	VERIFY3S(count, >=, 0);
+
+	VERIFY0(zap_update(os, dd->dd_object, prop, sizeof (count), 1, &count,
+	    tx));
+
+	/* Roll up this additional count into our ancestors */
+	if (dd->dd_parent != NULL)
+		dsl_fs_ss_count_adjust(dd->dd_parent, delta, prop, tx);
+}
+
+uint64_t
+dsl_dir_create_sync(dsl_pool_t *dp, dsl_dir_t *pds, const char *name,
+    dmu_tx_t *tx)
+{
+	objset_t *mos = dp->dp_meta_objset;
+	uint64_t ddobj;
+	dsl_dir_phys_t *ddphys;
+	dmu_buf_t *dbuf;
+
+	ddobj = dmu_object_alloc(mos, DMU_OT_DSL_DIR, 0,
+	    DMU_OT_DSL_DIR, sizeof (dsl_dir_phys_t), tx);
+	if (pds) {
+		VERIFY(0 == zap_add(mos, dsl_dir_phys(pds)->dd_child_dir_zapobj,
+		    name, sizeof (uint64_t), 1, &ddobj, tx));
+	} else {
+		/* it's the root dir */
+		VERIFY(0 == zap_add(mos, DMU_POOL_DIRECTORY_OBJECT,
+		    DMU_POOL_ROOT_DATASET, sizeof (uint64_t), 1, &ddobj, tx));
+	}
+	VERIFY(0 == dmu_bonus_hold(mos, ddobj, FTAG, &dbuf));
+	dmu_buf_will_dirty(dbuf, tx);
+	ddphys = dbuf->db_data;
+
+	ddphys->dd_creation_time = gethrestime_sec();
+	if (pds) {
+		ddphys->dd_parent_obj = pds->dd_object;
+
+		/* update the filesystem counts */
+		dsl_fs_ss_count_adjust(pds, 1, DD_FIELD_FILESYSTEM_COUNT, tx);
+	}
+	ddphys->dd_props_zapobj = zap_create(mos,
+	    DMU_OT_DSL_PROPS, DMU_OT_NONE, 0, tx);
+	ddphys->dd_child_dir_zapobj = zap_create(mos,
+	    DMU_OT_DSL_DIR_CHILD_MAP, DMU_OT_NONE, 0, tx);
+	if (spa_version(dp->dp_spa) >= SPA_VERSION_USED_BREAKDOWN)
+		ddphys->dd_flags |= DD_FLAG_USED_BREAKDOWN;
+	dmu_buf_rele(dbuf, FTAG);
+
+	return (ddobj);
+}
+
+boolean_t
+dsl_dir_is_clone(dsl_dir_t *dd)
+{
+	return (dsl_dir_phys(dd)->dd_origin_obj &&
+	    (dd->dd_pool->dp_origin_snap == NULL ||
+	    dsl_dir_phys(dd)->dd_origin_obj !=
+	    dd->dd_pool->dp_origin_snap->ds_object));
+}
+
+void
+dsl_dir_stats(dsl_dir_t *dd, nvlist_t *nv)
+{
+	mutex_enter(&dd->dd_lock);
+	dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_USED,
+	    dsl_dir_phys(dd)->dd_used_bytes);
+	dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_QUOTA,
+	    dsl_dir_phys(dd)->dd_quota);
+	dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_RESERVATION,
+	    dsl_dir_phys(dd)->dd_reserved);
+	dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_COMPRESSRATIO,
+	    dsl_dir_phys(dd)->dd_compressed_bytes == 0 ? 100 :
+	    (dsl_dir_phys(dd)->dd_uncompressed_bytes * 100 /
+	    dsl_dir_phys(dd)->dd_compressed_bytes));
+	dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_LOGICALUSED,
+	    dsl_dir_phys(dd)->dd_uncompressed_bytes);
+	if (dsl_dir_phys(dd)->dd_flags & DD_FLAG_USED_BREAKDOWN) {
+		dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_USEDSNAP,
+		    dsl_dir_phys(dd)->dd_used_breakdown[DD_USED_SNAP]);
+		dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_USEDDS,
+		    dsl_dir_phys(dd)->dd_used_breakdown[DD_USED_HEAD]);
+		dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_USEDREFRESERV,
+		    dsl_dir_phys(dd)->dd_used_breakdown[DD_USED_REFRSRV]);
+		dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_USEDCHILD,
+		    dsl_dir_phys(dd)->dd_used_breakdown[DD_USED_CHILD] +
+		    dsl_dir_phys(dd)->dd_used_breakdown[DD_USED_CHILD_RSRV]);
+	}
+	mutex_exit(&dd->dd_lock);
+
+	if (dsl_dir_is_zapified(dd)) {
+		uint64_t count;
+		objset_t *os = dd->dd_pool->dp_meta_objset;
+
+		if (zap_lookup(os, dd->dd_object, DD_FIELD_FILESYSTEM_COUNT,
+		    sizeof (count), 1, &count) == 0) {
+			dsl_prop_nvlist_add_uint64(nv,
+			    ZFS_PROP_FILESYSTEM_COUNT, count);
+		}
+		if (zap_lookup(os, dd->dd_object, DD_FIELD_SNAPSHOT_COUNT,
+		    sizeof (count), 1, &count) == 0) {
+			dsl_prop_nvlist_add_uint64(nv,
+			    ZFS_PROP_SNAPSHOT_COUNT, count);
+		}
+	}
+
+	if (dsl_dir_is_clone(dd)) {
+		dsl_dataset_t *ds;
+		char buf[MAXNAMELEN];
+
+		VERIFY0(dsl_dataset_hold_obj(dd->dd_pool,
+		    dsl_dir_phys(dd)->dd_origin_obj, FTAG, &ds));
+		dsl_dataset_name(ds, buf);
+		dsl_dataset_rele(ds, FTAG);
+		dsl_prop_nvlist_add_string(nv, ZFS_PROP_ORIGIN, buf);
+	}
+}
+
+void
+dsl_dir_dirty(dsl_dir_t *dd, dmu_tx_t *tx)
+{
+	dsl_pool_t *dp = dd->dd_pool;
+
+	ASSERT(dsl_dir_phys(dd));
+
+	if (txg_list_add(&dp->dp_dirty_dirs, dd, tx->tx_txg)) {
+		/* up the hold count until we can be written out */
+		dmu_buf_add_ref(dd->dd_dbuf, dd);
+	}
+}
+
+static int64_t
+parent_delta(dsl_dir_t *dd, uint64_t used, int64_t delta)
+{
+	uint64_t old_accounted = MAX(used, dsl_dir_phys(dd)->dd_reserved);
+	uint64_t new_accounted =
+	    MAX(used + delta, dsl_dir_phys(dd)->dd_reserved);
+	return (new_accounted - old_accounted);
+}
+
+void
+dsl_dir_sync(dsl_dir_t *dd, dmu_tx_t *tx)
+{
+	ASSERT(dmu_tx_is_syncing(tx));
+
+	mutex_enter(&dd->dd_lock);
+	ASSERT0(dd->dd_tempreserved[tx->tx_txg&TXG_MASK]);
+	dprintf_dd(dd, "txg=%llu towrite=%lluK\n", tx->tx_txg,
+	    dd->dd_space_towrite[tx->tx_txg&TXG_MASK] / 1024);
+	dd->dd_space_towrite[tx->tx_txg&TXG_MASK] = 0;
+	mutex_exit(&dd->dd_lock);
+
+	/* release the hold from dsl_dir_dirty */
+	dmu_buf_rele(dd->dd_dbuf, dd);
+}
+
+static uint64_t
+dsl_dir_space_towrite(dsl_dir_t *dd)
+{
+	uint64_t space = 0;
+	int i;
+
+	ASSERT(MUTEX_HELD(&dd->dd_lock));
+
+	for (i = 0; i < TXG_SIZE; i++) {
+		space += dd->dd_space_towrite[i&TXG_MASK];
+		ASSERT3U(dd->dd_space_towrite[i&TXG_MASK], >=, 0);
+	}
+	return (space);
+}
+
+/*
+ * How much space would dd have available if ancestor had delta applied
+ * to it?  If ondiskonly is set, we're only interested in what's
+ * on-disk, not estimated pending changes.
+ */
+uint64_t
+dsl_dir_space_available(dsl_dir_t *dd,
+    dsl_dir_t *ancestor, int64_t delta, int ondiskonly)
+{
+	uint64_t parentspace, myspace, quota, used;
+
+	/*
+	 * If there are no restrictions otherwise, assume we have
+	 * unlimited space available.
+	 */
+	quota = UINT64_MAX;
+	parentspace = UINT64_MAX;
+
+	if (dd->dd_parent != NULL) {
+		parentspace = dsl_dir_space_available(dd->dd_parent,
+		    ancestor, delta, ondiskonly);
+	}
+
+	mutex_enter(&dd->dd_lock);
+	if (dsl_dir_phys(dd)->dd_quota != 0)
+		quota = dsl_dir_phys(dd)->dd_quota;
+	used = dsl_dir_phys(dd)->dd_used_bytes;
+	if (!ondiskonly)
+		used += dsl_dir_space_towrite(dd);
+
+	if (dd->dd_parent == NULL) {
+		uint64_t poolsize = dsl_pool_adjustedsize(dd->dd_pool, FALSE);
+		quota = MIN(quota, poolsize);
+	}
+
+	if (dsl_dir_phys(dd)->dd_reserved > used && parentspace != UINT64_MAX) {
+		/*
+		 * We have some space reserved, in addition to what our
+		 * parent gave us.
+		 */
+		parentspace += dsl_dir_phys(dd)->dd_reserved - used;
+	}
+
+	if (dd == ancestor) {
+		ASSERT(delta <= 0);
+		ASSERT(used >= -delta);
+		used += delta;
+		if (parentspace != UINT64_MAX)
+			parentspace -= delta;
+	}
+
+	if (used > quota) {
+		/* over quota */
+		myspace = 0;
+	} else {
+		/*
+		 * the lesser of the space provided by our parent and
+		 * the space left in our quota
+		 */
+		myspace = MIN(parentspace, quota - used);
+	}
+
+	mutex_exit(&dd->dd_lock);
+
+	return (myspace);
+}
+
+struct tempreserve {
+	list_node_t tr_node;
+	dsl_dir_t *tr_ds;
+	uint64_t tr_size;
+};
+
+static int
+dsl_dir_tempreserve_impl(dsl_dir_t *dd, uint64_t asize, boolean_t netfree,
+    boolean_t ignorequota, boolean_t checkrefquota, list_t *tr_list,
+    dmu_tx_t *tx, boolean_t first)
+{
+	uint64_t txg = tx->tx_txg;
+	uint64_t est_inflight, used_on_disk, quota, parent_rsrv;
+	uint64_t deferred = 0;
+	struct tempreserve *tr;
+	int retval = EDQUOT;
+	int txgidx = txg & TXG_MASK;
+	int i;
+	uint64_t ref_rsrv = 0;
+
+	ASSERT3U(txg, !=, 0);
+	ASSERT3S(asize, >, 0);
+
+	mutex_enter(&dd->dd_lock);
+
+	/*
+	 * Check against the dsl_dir's quota.  We don't add in the delta
+	 * when checking for over-quota because they get one free hit.
+	 */
+	est_inflight = dsl_dir_space_towrite(dd);
+	for (i = 0; i < TXG_SIZE; i++)
+		est_inflight += dd->dd_tempreserved[i];
+	used_on_disk = dsl_dir_phys(dd)->dd_used_bytes;
+
+	/*
+	 * On the first iteration, fetch the dataset's used-on-disk and
+	 * refreservation values. Also, if checkrefquota is set, test if
+	 * allocating this space would exceed the dataset's refquota.
+	 */
+	if (first && tx->tx_objset) {
+		int error;
+		dsl_dataset_t *ds = tx->tx_objset->os_dsl_dataset;
+
+		error = dsl_dataset_check_quota(ds, checkrefquota,
+		    asize, est_inflight, &used_on_disk, &ref_rsrv);
+		if (error) {
+			mutex_exit(&dd->dd_lock);
+			DMU_TX_STAT_BUMP(dmu_tx_quota);
+			return (error);
+		}
+	}
+
+	/*
+	 * If this transaction will result in a net free of space,
+	 * we want to let it through.
+	 */
+	if (ignorequota || netfree || dsl_dir_phys(dd)->dd_quota == 0)
+		quota = UINT64_MAX;
+	else
+		quota = dsl_dir_phys(dd)->dd_quota;
+
+	/*
+	 * Adjust the quota against the actual pool size at the root
+	 * minus any outstanding deferred frees.
+	 * To ensure that it's possible to remove files from a full
+	 * pool without inducing transient overcommits, we throttle
+	 * netfree transactions against a quota that is slightly larger,
+	 * but still within the pool's allocation slop.  In cases where
+	 * we're very close to full, this will allow a steady trickle of
+	 * removes to get through.
+	 */
+	if (dd->dd_parent == NULL) {
+		spa_t *spa = dd->dd_pool->dp_spa;
+		uint64_t poolsize = dsl_pool_adjustedsize(dd->dd_pool, netfree);
+		deferred = metaslab_class_get_deferred(spa_normal_class(spa));
+		if (poolsize - deferred < quota) {
+			quota = poolsize - deferred;
+			retval = ENOSPC;
+		}
+	}
+
+	/*
+	 * If they are requesting more space, and our current estimate
+	 * is over quota, they get to try again unless the actual
+	 * on-disk is over quota and there are no pending changes (which
+	 * may free up space for us).
+	 */
+	if (used_on_disk + est_inflight >= quota) {
+		if (est_inflight > 0 || used_on_disk < quota ||
+		    (retval == ENOSPC && used_on_disk < quota + deferred))
+			retval = ERESTART;
+		dprintf_dd(dd, "failing: used=%lluK inflight = %lluK "
+		    "quota=%lluK tr=%lluK err=%d\n",
+		    used_on_disk>>10, est_inflight>>10,
+		    quota>>10, asize>>10, retval);
+		mutex_exit(&dd->dd_lock);
+		DMU_TX_STAT_BUMP(dmu_tx_quota);
+		return (SET_ERROR(retval));
+	}
+
+	/* We need to up our estimated delta before dropping dd_lock */
+	dd->dd_tempreserved[txgidx] += asize;
+
+	parent_rsrv = parent_delta(dd, used_on_disk + est_inflight,
+	    asize - ref_rsrv);
+	mutex_exit(&dd->dd_lock);
+
+	tr = kmem_zalloc(sizeof (struct tempreserve), KM_SLEEP);
+	tr->tr_ds = dd;
+	tr->tr_size = asize;
+	list_insert_tail(tr_list, tr);
+
+	/* see if it's OK with our parent */
+	if (dd->dd_parent && parent_rsrv) {
+		boolean_t ismos = (dsl_dir_phys(dd)->dd_head_dataset_obj == 0);
+
+		return (dsl_dir_tempreserve_impl(dd->dd_parent,
+		    parent_rsrv, netfree, ismos, TRUE, tr_list, tx, FALSE));
+	} else {
+		return (0);
+	}
+}
+
+/*
+ * Reserve space in this dsl_dir, to be used in this tx's txg.
+ * After the space has been dirtied (and dsl_dir_willuse_space()
+ * has been called), the reservation should be canceled, using
+ * dsl_dir_tempreserve_clear().
+ */
+int
+dsl_dir_tempreserve_space(dsl_dir_t *dd, uint64_t lsize, uint64_t asize,
+    uint64_t fsize, uint64_t usize, void **tr_cookiep, dmu_tx_t *tx)
+{
+	int err;
+	list_t *tr_list;
+
+	if (asize == 0) {
+		*tr_cookiep = NULL;
+		return (0);
+	}
+
+	tr_list = kmem_alloc(sizeof (list_t), KM_SLEEP);
+	list_create(tr_list, sizeof (struct tempreserve),
+	    offsetof(struct tempreserve, tr_node));
+	ASSERT3S(asize, >, 0);
+	ASSERT3S(fsize, >=, 0);
+
+	err = arc_tempreserve_space(lsize, tx->tx_txg);
+	if (err == 0) {
+		struct tempreserve *tr;
+
+		tr = kmem_zalloc(sizeof (struct tempreserve), KM_SLEEP);
+		tr->tr_size = lsize;
+		list_insert_tail(tr_list, tr);
+	} else {
+		if (err == EAGAIN) {
+			/*
+			 * If arc_memory_throttle() detected that pageout
+			 * is running and we are low on memory, we delay new
+			 * non-pageout transactions to give pageout an
+			 * advantage.
+			 *
+			 * It is unfortunate to be delaying while the caller's
+			 * locks are held.
+			 */
+			txg_delay(dd->dd_pool, tx->tx_txg,
+			    MSEC2NSEC(10), MSEC2NSEC(10));
+			err = SET_ERROR(ERESTART);
+		}
+	}
+
+	if (err == 0) {
+		err = dsl_dir_tempreserve_impl(dd, asize, fsize >= asize,
+		    FALSE, asize > usize, tr_list, tx, TRUE);
+	}
+
+	if (err != 0)
+		dsl_dir_tempreserve_clear(tr_list, tx);
+	else
+		*tr_cookiep = tr_list;
+
+	return (err);
+}
+
+/*
+ * Clear a temporary reservation that we previously made with
+ * dsl_dir_tempreserve_space().
+ */
+void
+dsl_dir_tempreserve_clear(void *tr_cookie, dmu_tx_t *tx)
+{
+	int txgidx = tx->tx_txg & TXG_MASK;
+	list_t *tr_list = tr_cookie;
+	struct tempreserve *tr;
+
+	ASSERT3U(tx->tx_txg, !=, 0);
+
+	if (tr_cookie == NULL)
+		return;
+
+	while ((tr = list_head(tr_list)) != NULL) {
+		if (tr->tr_ds) {
+			mutex_enter(&tr->tr_ds->dd_lock);
+			ASSERT3U(tr->tr_ds->dd_tempreserved[txgidx], >=,
+			    tr->tr_size);
+			tr->tr_ds->dd_tempreserved[txgidx] -= tr->tr_size;
+			mutex_exit(&tr->tr_ds->dd_lock);
+		} else {
+			arc_tempreserve_clear(tr->tr_size);
+		}
+		list_remove(tr_list, tr);
+		kmem_free(tr, sizeof (struct tempreserve));
+	}
+
+	kmem_free(tr_list, sizeof (list_t));
+}
+
+/*
+ * This should be called from open context when we think we're going to write
+ * or free space, for example when dirtying data. Be conservative; it's okay
+ * to write less space or free more, but we don't want to write more or free
+ * less than the amount specified.
+ *
+ * NOTE: The behavior of this function is identical to the Illumos / FreeBSD
+ * version however it has been adjusted to use an iterative rather then
+ * recursive algorithm to minimize stack usage.
+ */
+void
+dsl_dir_willuse_space(dsl_dir_t *dd, int64_t space, dmu_tx_t *tx)
+{
+	int64_t parent_space;
+	uint64_t est_used;
+
+	do {
+		mutex_enter(&dd->dd_lock);
+		if (space > 0)
+			dd->dd_space_towrite[tx->tx_txg & TXG_MASK] += space;
+
+		est_used = dsl_dir_space_towrite(dd) +
+		    dsl_dir_phys(dd)->dd_used_bytes;
+		parent_space = parent_delta(dd, est_used, space);
+		mutex_exit(&dd->dd_lock);
+
+		/* Make sure that we clean up dd_space_to* */
+		dsl_dir_dirty(dd, tx);
+
+		dd = dd->dd_parent;
+		space = parent_space;
+	} while (space && dd);
+}
+
+/* call from syncing context when we actually write/free space for this dd */
+void
+dsl_dir_diduse_space(dsl_dir_t *dd, dd_used_t type,
+    int64_t used, int64_t compressed, int64_t uncompressed, dmu_tx_t *tx)
+{
+	int64_t accounted_delta;
+
+	/*
+	 * dsl_dataset_set_refreservation_sync_impl() calls this with
+	 * dd_lock held, so that it can atomically update
+	 * ds->ds_reserved and the dsl_dir accounting, so that
+	 * dsl_dataset_check_quota() can see dataset and dir accounting
+	 * consistently.
+	 */
+	boolean_t needlock = !MUTEX_HELD(&dd->dd_lock);
+
+	ASSERT(dmu_tx_is_syncing(tx));
+	ASSERT(type < DD_USED_NUM);
+
+	dmu_buf_will_dirty(dd->dd_dbuf, tx);
+
+	if (needlock)
+		mutex_enter(&dd->dd_lock);
+	accounted_delta =
+	    parent_delta(dd, dsl_dir_phys(dd)->dd_used_bytes, used);
+	ASSERT(used >= 0 || dsl_dir_phys(dd)->dd_used_bytes >= -used);
+	ASSERT(compressed >= 0 ||
+	    dsl_dir_phys(dd)->dd_compressed_bytes >= -compressed);
+	ASSERT(uncompressed >= 0 ||
+	    dsl_dir_phys(dd)->dd_uncompressed_bytes >= -uncompressed);
+	dsl_dir_phys(dd)->dd_used_bytes += used;
+	dsl_dir_phys(dd)->dd_uncompressed_bytes += uncompressed;
+	dsl_dir_phys(dd)->dd_compressed_bytes += compressed;
+
+	if (dsl_dir_phys(dd)->dd_flags & DD_FLAG_USED_BREAKDOWN) {
+		ASSERT(used > 0 ||
+		    dsl_dir_phys(dd)->dd_used_breakdown[type] >= -used);
+		dsl_dir_phys(dd)->dd_used_breakdown[type] += used;
+#ifdef DEBUG
+		{
+			dd_used_t t;
+			uint64_t u = 0;
+			for (t = 0; t < DD_USED_NUM; t++)
+				u += dsl_dir_phys(dd)->dd_used_breakdown[t];
+			ASSERT3U(u, ==, dsl_dir_phys(dd)->dd_used_bytes);
+		}
+#endif
+	}
+	if (needlock)
+		mutex_exit(&dd->dd_lock);
+
+	if (dd->dd_parent != NULL) {
+		dsl_dir_diduse_space(dd->dd_parent, DD_USED_CHILD,
+		    accounted_delta, compressed, uncompressed, tx);
+		dsl_dir_transfer_space(dd->dd_parent,
+		    used - accounted_delta,
+		    DD_USED_CHILD_RSRV, DD_USED_CHILD, tx);
+	}
+}
+
+void
+dsl_dir_transfer_space(dsl_dir_t *dd, int64_t delta,
+    dd_used_t oldtype, dd_used_t newtype, dmu_tx_t *tx)
+{
+	ASSERT(dmu_tx_is_syncing(tx));
+	ASSERT(oldtype < DD_USED_NUM);
+	ASSERT(newtype < DD_USED_NUM);
+
+	if (delta == 0 ||
+	    !(dsl_dir_phys(dd)->dd_flags & DD_FLAG_USED_BREAKDOWN))
+		return;
+
+	dmu_buf_will_dirty(dd->dd_dbuf, tx);
+	mutex_enter(&dd->dd_lock);
+	ASSERT(delta > 0 ?
+	    dsl_dir_phys(dd)->dd_used_breakdown[oldtype] >= delta :
+	    dsl_dir_phys(dd)->dd_used_breakdown[newtype] >= -delta);
+	ASSERT(dsl_dir_phys(dd)->dd_used_bytes >= ABS(delta));
+	dsl_dir_phys(dd)->dd_used_breakdown[oldtype] -= delta;
+	dsl_dir_phys(dd)->dd_used_breakdown[newtype] += delta;
+	mutex_exit(&dd->dd_lock);
+}
+
+typedef struct dsl_dir_set_qr_arg {
+	const char *ddsqra_name;
+	zprop_source_t ddsqra_source;
+	uint64_t ddsqra_value;
+} dsl_dir_set_qr_arg_t;
+
+static int
+dsl_dir_set_quota_check(void *arg, dmu_tx_t *tx)
+{
+	dsl_dir_set_qr_arg_t *ddsqra = arg;
+	dsl_pool_t *dp = dmu_tx_pool(tx);
+	dsl_dataset_t *ds;
+	int error;
+	uint64_t towrite, newval;
+
+	error = dsl_dataset_hold(dp, ddsqra->ddsqra_name, FTAG, &ds);
+	if (error != 0)
+		return (error);
+
+	error = dsl_prop_predict(ds->ds_dir, "quota",
+	    ddsqra->ddsqra_source, ddsqra->ddsqra_value, &newval);
+	if (error != 0) {
+		dsl_dataset_rele(ds, FTAG);
+		return (error);
+	}
+
+	if (newval == 0) {
+		dsl_dataset_rele(ds, FTAG);
+		return (0);
+	}
+
+	mutex_enter(&ds->ds_dir->dd_lock);
+	/*
+	 * If we are doing the preliminary check in open context, and
+	 * there are pending changes, then don't fail it, since the
+	 * pending changes could under-estimate the amount of space to be
+	 * freed up.
+	 */
+	towrite = dsl_dir_space_towrite(ds->ds_dir);
+	if ((dmu_tx_is_syncing(tx) || towrite == 0) &&
+	    (newval < dsl_dir_phys(ds->ds_dir)->dd_reserved ||
+	    newval < dsl_dir_phys(ds->ds_dir)->dd_used_bytes + towrite)) {
+		error = SET_ERROR(ENOSPC);
+	}
+	mutex_exit(&ds->ds_dir->dd_lock);
+	dsl_dataset_rele(ds, FTAG);
+	return (error);
+}
+
+static void
+dsl_dir_set_quota_sync(void *arg, dmu_tx_t *tx)
+{
+	dsl_dir_set_qr_arg_t *ddsqra = arg;
+	dsl_pool_t *dp = dmu_tx_pool(tx);
+	dsl_dataset_t *ds;
+	uint64_t newval;
+
+	VERIFY0(dsl_dataset_hold(dp, ddsqra->ddsqra_name, FTAG, &ds));
+
+	if (spa_version(dp->dp_spa) >= SPA_VERSION_RECVD_PROPS) {
+		dsl_prop_set_sync_impl(ds, zfs_prop_to_name(ZFS_PROP_QUOTA),
+		    ddsqra->ddsqra_source, sizeof (ddsqra->ddsqra_value), 1,
+		    &ddsqra->ddsqra_value, tx);
+
+		VERIFY0(dsl_prop_get_int_ds(ds,
+		    zfs_prop_to_name(ZFS_PROP_QUOTA), &newval));
+	} else {
+		newval = ddsqra->ddsqra_value;
+		spa_history_log_internal_ds(ds, "set", tx, "%s=%lld",
+		    zfs_prop_to_name(ZFS_PROP_QUOTA), (longlong_t)newval);
+	}
+
+	dmu_buf_will_dirty(ds->ds_dir->dd_dbuf, tx);
+	mutex_enter(&ds->ds_dir->dd_lock);
+	dsl_dir_phys(ds->ds_dir)->dd_quota = newval;
+	mutex_exit(&ds->ds_dir->dd_lock);
+	dsl_dataset_rele(ds, FTAG);
+}
+
+int
+dsl_dir_set_quota(const char *ddname, zprop_source_t source, uint64_t quota)
+{
+	dsl_dir_set_qr_arg_t ddsqra;
+
+	ddsqra.ddsqra_name = ddname;
+	ddsqra.ddsqra_source = source;
+	ddsqra.ddsqra_value = quota;
+
+	return (dsl_sync_task(ddname, dsl_dir_set_quota_check,
+	    dsl_dir_set_quota_sync, &ddsqra, 0, ZFS_SPACE_CHECK_NONE));
+}
+
+int
+dsl_dir_set_reservation_check(void *arg, dmu_tx_t *tx)
+{
+	dsl_dir_set_qr_arg_t *ddsqra = arg;
+	dsl_pool_t *dp = dmu_tx_pool(tx);
+	dsl_dataset_t *ds;
+	dsl_dir_t *dd;
+	uint64_t newval, used, avail;
+	int error;
+
+	error = dsl_dataset_hold(dp, ddsqra->ddsqra_name, FTAG, &ds);
+	if (error != 0)
+		return (error);
+	dd = ds->ds_dir;
+
+	/*
+	 * If we are doing the preliminary check in open context, the
+	 * space estimates may be inaccurate.
+	 */
+	if (!dmu_tx_is_syncing(tx)) {
+		dsl_dataset_rele(ds, FTAG);
+		return (0);
+	}
+
+	error = dsl_prop_predict(ds->ds_dir,
+	    zfs_prop_to_name(ZFS_PROP_RESERVATION),
+	    ddsqra->ddsqra_source, ddsqra->ddsqra_value, &newval);
+	if (error != 0) {
+		dsl_dataset_rele(ds, FTAG);
+		return (error);
+	}
+
+	mutex_enter(&dd->dd_lock);
+	used = dsl_dir_phys(dd)->dd_used_bytes;
+	mutex_exit(&dd->dd_lock);
+
+	if (dd->dd_parent) {
+		avail = dsl_dir_space_available(dd->dd_parent,
+		    NULL, 0, FALSE);
+	} else {
+		avail = dsl_pool_adjustedsize(dd->dd_pool, B_FALSE) - used;
+	}
+
+	if (MAX(used, newval) > MAX(used, dsl_dir_phys(dd)->dd_reserved)) {
+		uint64_t delta = MAX(used, newval) -
+		    MAX(used, dsl_dir_phys(dd)->dd_reserved);
+
+		if (delta > avail ||
+		    (dsl_dir_phys(dd)->dd_quota > 0 &&
+		    newval > dsl_dir_phys(dd)->dd_quota))
+			error = SET_ERROR(ENOSPC);
+	}
+
+	dsl_dataset_rele(ds, FTAG);
+	return (error);
+}
+
+void
+dsl_dir_set_reservation_sync_impl(dsl_dir_t *dd, uint64_t value, dmu_tx_t *tx)
+{
+	uint64_t used;
+	int64_t delta;
+
+	dmu_buf_will_dirty(dd->dd_dbuf, tx);
+
+	mutex_enter(&dd->dd_lock);
+	used = dsl_dir_phys(dd)->dd_used_bytes;
+	delta = MAX(used, value) - MAX(used, dsl_dir_phys(dd)->dd_reserved);
+	dsl_dir_phys(dd)->dd_reserved = value;
+
+	if (dd->dd_parent != NULL) {
+		/* Roll up this additional usage into our ancestors */
+		dsl_dir_diduse_space(dd->dd_parent, DD_USED_CHILD_RSRV,
+		    delta, 0, 0, tx);
+	}
+	mutex_exit(&dd->dd_lock);
+}
+
+static void
+dsl_dir_set_reservation_sync(void *arg, dmu_tx_t *tx)
+{
+	dsl_dir_set_qr_arg_t *ddsqra = arg;
+	dsl_pool_t *dp = dmu_tx_pool(tx);
+	dsl_dataset_t *ds;
+	uint64_t newval;
+
+	VERIFY0(dsl_dataset_hold(dp, ddsqra->ddsqra_name, FTAG, &ds));
+
+	if (spa_version(dp->dp_spa) >= SPA_VERSION_RECVD_PROPS) {
+		dsl_prop_set_sync_impl(ds,
+		    zfs_prop_to_name(ZFS_PROP_RESERVATION),
+		    ddsqra->ddsqra_source, sizeof (ddsqra->ddsqra_value), 1,
+		    &ddsqra->ddsqra_value, tx);
+
+		VERIFY0(dsl_prop_get_int_ds(ds,
+		    zfs_prop_to_name(ZFS_PROP_RESERVATION), &newval));
+	} else {
+		newval = ddsqra->ddsqra_value;
+		spa_history_log_internal_ds(ds, "set", tx, "%s=%lld",
+		    zfs_prop_to_name(ZFS_PROP_RESERVATION),
+		    (longlong_t)newval);
+	}
+
+	dsl_dir_set_reservation_sync_impl(ds->ds_dir, newval, tx);
+	dsl_dataset_rele(ds, FTAG);
+}
+
+int
+dsl_dir_set_reservation(const char *ddname, zprop_source_t source,
+    uint64_t reservation)
+{
+	dsl_dir_set_qr_arg_t ddsqra;
+
+	ddsqra.ddsqra_name = ddname;
+	ddsqra.ddsqra_source = source;
+	ddsqra.ddsqra_value = reservation;
+
+	return (dsl_sync_task(ddname, dsl_dir_set_reservation_check,
+	    dsl_dir_set_reservation_sync, &ddsqra, 0, ZFS_SPACE_CHECK_NONE));
+}
+
+static dsl_dir_t *
+closest_common_ancestor(dsl_dir_t *ds1, dsl_dir_t *ds2)
+{
+	for (; ds1; ds1 = ds1->dd_parent) {
+		dsl_dir_t *dd;
+		for (dd = ds2; dd; dd = dd->dd_parent) {
+			if (ds1 == dd)
+				return (dd);
+		}
+	}
+	return (NULL);
+}
+
+/*
+ * If delta is applied to dd, how much of that delta would be applied to
+ * ancestor?  Syncing context only.
+ */
+static int64_t
+would_change(dsl_dir_t *dd, int64_t delta, dsl_dir_t *ancestor)
+{
+	if (dd == ancestor)
+		return (delta);
+
+	mutex_enter(&dd->dd_lock);
+	delta = parent_delta(dd, dsl_dir_phys(dd)->dd_used_bytes, delta);
+	mutex_exit(&dd->dd_lock);
+	return (would_change(dd->dd_parent, delta, ancestor));
+}
+
+typedef struct dsl_dir_rename_arg {
+	const char *ddra_oldname;
+	const char *ddra_newname;
+	cred_t *ddra_cred;
+} dsl_dir_rename_arg_t;
+
+/* ARGSUSED */
+static int
+dsl_valid_rename(dsl_pool_t *dp, dsl_dataset_t *ds, void *arg)
+{
+	int *deltap = arg;
+	char namebuf[MAXNAMELEN];
+
+	dsl_dataset_name(ds, namebuf);
+
+	if (strlen(namebuf) + *deltap >= MAXNAMELEN)
+		return (SET_ERROR(ENAMETOOLONG));
+	return (0);
+}
+
+static int
+dsl_dir_rename_check(void *arg, dmu_tx_t *tx)
+{
+	dsl_dir_rename_arg_t *ddra = arg;
+	dsl_pool_t *dp = dmu_tx_pool(tx);
+	dsl_dir_t *dd, *newparent;
+	const char *mynewname;
+	int error;
+	int delta = strlen(ddra->ddra_newname) - strlen(ddra->ddra_oldname);
+
+	/* target dir should exist */
+	error = dsl_dir_hold(dp, ddra->ddra_oldname, FTAG, &dd, NULL);
+	if (error != 0)
+		return (error);
+
+	/* new parent should exist */
+	error = dsl_dir_hold(dp, ddra->ddra_newname, FTAG,
+	    &newparent, &mynewname);
+	if (error != 0) {
+		dsl_dir_rele(dd, FTAG);
+		return (error);
+	}
+
+	/* can't rename to different pool */
+	if (dd->dd_pool != newparent->dd_pool) {
+		dsl_dir_rele(newparent, FTAG);
+		dsl_dir_rele(dd, FTAG);
+		return (SET_ERROR(EXDEV));
+	}
+
+	/* new name should not already exist */
+	if (mynewname == NULL) {
+		dsl_dir_rele(newparent, FTAG);
+		dsl_dir_rele(dd, FTAG);
+		return (SET_ERROR(EEXIST));
+	}
+
+	/* if the name length is growing, validate child name lengths */
+	if (delta > 0) {
+		error = dmu_objset_find_dp(dp, dd->dd_object, dsl_valid_rename,
+		    &delta, DS_FIND_CHILDREN | DS_FIND_SNAPSHOTS);
+		if (error != 0) {
+			dsl_dir_rele(newparent, FTAG);
+			dsl_dir_rele(dd, FTAG);
+			return (error);
+		}
+	}
+
+	if (dmu_tx_is_syncing(tx)) {
+		if (spa_feature_is_active(dp->dp_spa,
+		    SPA_FEATURE_FS_SS_LIMIT)) {
+			/*
+			 * Although this is the check function and we don't
+			 * normally make on-disk changes in check functions,
+			 * we need to do that here.
+			 *
+			 * Ensure this portion of the tree's counts have been
+			 * initialized in case the new parent has limits set.
+			 */
+			dsl_dir_init_fs_ss_count(dd, tx);
+		}
+	}
+
+	if (newparent != dd->dd_parent) {
+		/* is there enough space? */
+		uint64_t myspace =
+		    MAX(dsl_dir_phys(dd)->dd_used_bytes,
+		    dsl_dir_phys(dd)->dd_reserved);
+		objset_t *os = dd->dd_pool->dp_meta_objset;
+		uint64_t fs_cnt = 0;
+		uint64_t ss_cnt = 0;
+
+		if (dsl_dir_is_zapified(dd)) {
+			int err;
+
+			err = zap_lookup(os, dd->dd_object,
+			    DD_FIELD_FILESYSTEM_COUNT, sizeof (fs_cnt), 1,
+			    &fs_cnt);
+			if (err != ENOENT && err != 0) {
+				dsl_dir_rele(newparent, FTAG);
+				dsl_dir_rele(dd, FTAG);
+				return (err);
+			}
+
+			/*
+			 * have to add 1 for the filesystem itself that we're
+			 * moving
+			 */
+			fs_cnt++;
+
+			err = zap_lookup(os, dd->dd_object,
+			    DD_FIELD_SNAPSHOT_COUNT, sizeof (ss_cnt), 1,
+			    &ss_cnt);
+			if (err != ENOENT && err != 0) {
+				dsl_dir_rele(newparent, FTAG);
+				dsl_dir_rele(dd, FTAG);
+				return (err);
+			}
+		}
+
+		/* no rename into our descendant */
+		if (closest_common_ancestor(dd, newparent) == dd) {
+			dsl_dir_rele(newparent, FTAG);
+			dsl_dir_rele(dd, FTAG);
+			return (SET_ERROR(EINVAL));
+		}
+
+		error = dsl_dir_transfer_possible(dd->dd_parent,
+		    newparent, fs_cnt, ss_cnt, myspace, ddra->ddra_cred);
+		if (error != 0) {
+			dsl_dir_rele(newparent, FTAG);
+			dsl_dir_rele(dd, FTAG);
+			return (error);
+		}
+	}
+
+	dsl_dir_rele(newparent, FTAG);
+	dsl_dir_rele(dd, FTAG);
+	return (0);
+}
+
+static void
+dsl_dir_rename_sync(void *arg, dmu_tx_t *tx)
+{
+	dsl_dir_rename_arg_t *ddra = arg;
+	dsl_pool_t *dp = dmu_tx_pool(tx);
+	dsl_dir_t *dd, *newparent;
+	const char *mynewname;
+	int error;
+	objset_t *mos = dp->dp_meta_objset;
+
+	VERIFY0(dsl_dir_hold(dp, ddra->ddra_oldname, FTAG, &dd, NULL));
+	VERIFY0(dsl_dir_hold(dp, ddra->ddra_newname, FTAG, &newparent,
+	    &mynewname));
+
+	/* Log this before we change the name. */
+	spa_history_log_internal_dd(dd, "rename", tx,
+	    "-> %s", ddra->ddra_newname);
+
+	if (newparent != dd->dd_parent) {
+		objset_t *os = dd->dd_pool->dp_meta_objset;
+		uint64_t fs_cnt = 0;
+		uint64_t ss_cnt = 0;
+
+		/*
+		 * We already made sure the dd counts were initialized in the
+		 * check function.
+		 */
+		if (spa_feature_is_active(dp->dp_spa,
+		    SPA_FEATURE_FS_SS_LIMIT)) {
+			VERIFY0(zap_lookup(os, dd->dd_object,
+			    DD_FIELD_FILESYSTEM_COUNT, sizeof (fs_cnt), 1,
+			    &fs_cnt));
+			/* add 1 for the filesystem itself that we're moving */
+			fs_cnt++;
+
+			VERIFY0(zap_lookup(os, dd->dd_object,
+			    DD_FIELD_SNAPSHOT_COUNT, sizeof (ss_cnt), 1,
+			    &ss_cnt));
+		}
+
+		dsl_fs_ss_count_adjust(dd->dd_parent, -fs_cnt,
+		    DD_FIELD_FILESYSTEM_COUNT, tx);
+		dsl_fs_ss_count_adjust(newparent, fs_cnt,
+		    DD_FIELD_FILESYSTEM_COUNT, tx);
+
+		dsl_fs_ss_count_adjust(dd->dd_parent, -ss_cnt,
+		    DD_FIELD_SNAPSHOT_COUNT, tx);
+		dsl_fs_ss_count_adjust(newparent, ss_cnt,
+		    DD_FIELD_SNAPSHOT_COUNT, tx);
+
+		dsl_dir_diduse_space(dd->dd_parent, DD_USED_CHILD,
+		    -dsl_dir_phys(dd)->dd_used_bytes,
+		    -dsl_dir_phys(dd)->dd_compressed_bytes,
+		    -dsl_dir_phys(dd)->dd_uncompressed_bytes, tx);
+		dsl_dir_diduse_space(newparent, DD_USED_CHILD,
+		    dsl_dir_phys(dd)->dd_used_bytes,
+		    dsl_dir_phys(dd)->dd_compressed_bytes,
+		    dsl_dir_phys(dd)->dd_uncompressed_bytes, tx);
+
+		if (dsl_dir_phys(dd)->dd_reserved >
+		    dsl_dir_phys(dd)->dd_used_bytes) {
+			uint64_t unused_rsrv = dsl_dir_phys(dd)->dd_reserved -
+			    dsl_dir_phys(dd)->dd_used_bytes;
+
+			dsl_dir_diduse_space(dd->dd_parent, DD_USED_CHILD_RSRV,
+			    -unused_rsrv, 0, 0, tx);
+			dsl_dir_diduse_space(newparent, DD_USED_CHILD_RSRV,
+			    unused_rsrv, 0, 0, tx);
+		}
+	}
+
+	dmu_buf_will_dirty(dd->dd_dbuf, tx);
+
+	/* remove from old parent zapobj */
+	error = zap_remove(mos,
+	    dsl_dir_phys(dd->dd_parent)->dd_child_dir_zapobj,
+	    dd->dd_myname, tx);
+	ASSERT0(error);
+
+	(void) strcpy(dd->dd_myname, mynewname);
+	dsl_dir_rele(dd->dd_parent, dd);
+	dsl_dir_phys(dd)->dd_parent_obj = newparent->dd_object;
+	VERIFY0(dsl_dir_hold_obj(dp,
+	    newparent->dd_object, NULL, dd, &dd->dd_parent));
+
+	/* add to new parent zapobj */
+	VERIFY0(zap_add(mos, dsl_dir_phys(newparent)->dd_child_dir_zapobj,
+	    dd->dd_myname, 8, 1, &dd->dd_object, tx));
+
+	zvol_rename_minors(dp->dp_spa, ddra->ddra_oldname,
+	    ddra->ddra_newname, B_TRUE);
+
+	dsl_prop_notify_all(dd);
+
+	dsl_dir_rele(newparent, FTAG);
+	dsl_dir_rele(dd, FTAG);
+}
+
+int
+dsl_dir_rename(const char *oldname, const char *newname)
+{
+	dsl_dir_rename_arg_t ddra;
+
+	ddra.ddra_oldname = oldname;
+	ddra.ddra_newname = newname;
+	ddra.ddra_cred = CRED();
+
+	return (dsl_sync_task(oldname,
+	    dsl_dir_rename_check, dsl_dir_rename_sync, &ddra,
+	    3, ZFS_SPACE_CHECK_RESERVED));
+}
+
+int
+dsl_dir_transfer_possible(dsl_dir_t *sdd, dsl_dir_t *tdd,
+    uint64_t fs_cnt, uint64_t ss_cnt, uint64_t space, cred_t *cr)
+{
+	dsl_dir_t *ancestor;
+	int64_t adelta;
+	uint64_t avail;
+	int err;
+
+	ancestor = closest_common_ancestor(sdd, tdd);
+	adelta = would_change(sdd, -space, ancestor);
+	avail = dsl_dir_space_available(tdd, ancestor, adelta, FALSE);
+	if (avail < space)
+		return (SET_ERROR(ENOSPC));
+
+	err = dsl_fs_ss_limit_check(tdd, fs_cnt, ZFS_PROP_FILESYSTEM_LIMIT,
+	    ancestor, cr);
+	if (err != 0)
+		return (err);
+	err = dsl_fs_ss_limit_check(tdd, ss_cnt, ZFS_PROP_SNAPSHOT_LIMIT,
+	    ancestor, cr);
+	if (err != 0)
+		return (err);
+
+	return (0);
+}
+
+timestruc_t
+dsl_dir_snap_cmtime(dsl_dir_t *dd)
+{
+	timestruc_t t;
+
+	mutex_enter(&dd->dd_lock);
+	t = dd->dd_snap_cmtime;
+	mutex_exit(&dd->dd_lock);
+
+	return (t);
+}
+
+void
+dsl_dir_snap_cmtime_update(dsl_dir_t *dd)
+{
+	timestruc_t t;
+
+	gethrestime(&t);
+	mutex_enter(&dd->dd_lock);
+	dd->dd_snap_cmtime = t;
+	mutex_exit(&dd->dd_lock);
+}
+
+void
+dsl_dir_zapify(dsl_dir_t *dd, dmu_tx_t *tx)
+{
+	objset_t *mos = dd->dd_pool->dp_meta_objset;
+	dmu_object_zapify(mos, dd->dd_object, DMU_OT_DSL_DIR, tx);
+}
+
+boolean_t
+dsl_dir_is_zapified(dsl_dir_t *dd)
+{
+	dmu_object_info_t doi;
+
+	dmu_object_info_from_db(dd->dd_dbuf, &doi);
+	return (doi.doi_type == DMU_OTN_ZAP_METADATA);
+}
+
+#if defined(_KERNEL) && defined(HAVE_SPL)
+EXPORT_SYMBOL(dsl_dir_set_quota);
+EXPORT_SYMBOL(dsl_dir_set_reservation);
+#endif
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/module/zfs/dsl_pool.c
@@ -0,0 +1,1107 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2014 by Delphix. All rights reserved.
+ * Copyright (c) 2013 Steven Hartland. All rights reserved.
+ * Copyright (c) 2014 Spectra Logic Corporation, All rights reserved.
+ */
+
+#include <sys/dsl_pool.h>
+#include <sys/dsl_dataset.h>
+#include <sys/dsl_prop.h>
+#include <sys/dsl_dir.h>
+#include <sys/dsl_synctask.h>
+#include <sys/dsl_scan.h>
+#include <sys/dnode.h>
+#include <sys/dmu_tx.h>
+#include <sys/dmu_objset.h>
+#include <sys/arc.h>
+#include <sys/zap.h>
+#include <sys/zio.h>
+#include <sys/zfs_context.h>
+#include <sys/fs/zfs.h>
+#include <sys/zfs_znode.h>
+#include <sys/spa_impl.h>
+#include <sys/dsl_deadlist.h>
+#include <sys/bptree.h>
+#include <sys/zfeature.h>
+#include <sys/zil_impl.h>
+#include <sys/dsl_userhold.h>
+#include <sys/trace_txg.h>
+
+/*
+ * ZFS Write Throttle
+ * ------------------
+ *
+ * ZFS must limit the rate of incoming writes to the rate at which it is able
+ * to sync data modifications to the backend storage. Throttling by too much
+ * creates an artificial limit; throttling by too little can only be sustained
+ * for short periods and would lead to highly lumpy performance. On a per-pool
+ * basis, ZFS tracks the amount of modified (dirty) data. As operations change
+ * data, the amount of dirty data increases; as ZFS syncs out data, the amount
+ * of dirty data decreases. When the amount of dirty data exceeds a
+ * predetermined threshold further modifications are blocked until the amount
+ * of dirty data decreases (as data is synced out).
+ *
+ * The limit on dirty data is tunable, and should be adjusted according to
+ * both the IO capacity and available memory of the system. The larger the
+ * window, the more ZFS is able to aggregate and amortize metadata (and data)
+ * changes. However, memory is a limited resource, and allowing for more dirty
+ * data comes at the cost of keeping other useful data in memory (for example
+ * ZFS data cached by the ARC).
+ *
+ * Implementation
+ *
+ * As buffers are modified dsl_pool_willuse_space() increments both the per-
+ * txg (dp_dirty_pertxg[]) and poolwide (dp_dirty_total) accounting of
+ * dirty space used; dsl_pool_dirty_space() decrements those values as data
+ * is synced out from dsl_pool_sync(). While only the poolwide value is
+ * relevant, the per-txg value is useful for debugging. The tunable
+ * zfs_dirty_data_max determines the dirty space limit. Once that value is
+ * exceeded, new writes are halted until space frees up.
+ *
+ * The zfs_dirty_data_sync tunable dictates the threshold at which we
+ * ensure that there is a txg syncing (see the comment in txg.c for a full
+ * description of transaction group stages).
+ *
+ * The IO scheduler uses both the dirty space limit and current amount of
+ * dirty data as inputs. Those values affect the number of concurrent IOs ZFS
+ * issues. See the comment in vdev_queue.c for details of the IO scheduler.
+ *
+ * The delay is also calculated based on the amount of dirty data.  See the
+ * comment above dmu_tx_delay() for details.
+ */
+
+/*
+ * zfs_dirty_data_max will be set to zfs_dirty_data_max_percent% of all memory,
+ * capped at zfs_dirty_data_max_max.  It can also be overridden with a module
+ * parameter.
+ */
+unsigned long zfs_dirty_data_max = 0;
+unsigned long zfs_dirty_data_max_max = 0;
+int zfs_dirty_data_max_percent = 10;
+int zfs_dirty_data_max_max_percent = 25;
+
+/*
+ * If there is at least this much dirty data, push out a txg.
+ */
+unsigned long zfs_dirty_data_sync = 64 * 1024 * 1024;
+
+/*
+ * Once there is this amount of dirty data, the dmu_tx_delay() will kick in
+ * and delay each transaction.
+ * This value should be >= zfs_vdev_async_write_active_max_dirty_percent.
+ */
+int zfs_delay_min_dirty_percent = 60;
+
+/*
+ * This controls how quickly the delay approaches infinity.
+ * Larger values cause it to delay more for a given amount of dirty data.
+ * Therefore larger values will cause there to be less dirty data for a
+ * given throughput.
+ *
+ * For the smoothest delay, this value should be about 1 billion divided
+ * by the maximum number of operations per second.  This will smoothly
+ * handle between 10x and 1/10th this number.
+ *
+ * Note: zfs_delay_scale * zfs_dirty_data_max must be < 2^64, due to the
+ * multiply in dmu_tx_delay().
+ */
+unsigned long zfs_delay_scale = 1000 * 1000 * 1000 / 2000;
+
+hrtime_t zfs_throttle_delay = MSEC2NSEC(10);
+hrtime_t zfs_throttle_resolution = MSEC2NSEC(10);
+
+int
+dsl_pool_open_special_dir(dsl_pool_t *dp, const char *name, dsl_dir_t **ddp)
+{
+	uint64_t obj;
+	int err;
+
+	err = zap_lookup(dp->dp_meta_objset,
+	    dsl_dir_phys(dp->dp_root_dir)->dd_child_dir_zapobj,
+	    name, sizeof (obj), 1, &obj);
+	if (err)
+		return (err);
+
+	return (dsl_dir_hold_obj(dp, obj, name, dp, ddp));
+}
+
+static dsl_pool_t *
+dsl_pool_open_impl(spa_t *spa, uint64_t txg)
+{
+	dsl_pool_t *dp;
+	blkptr_t *bp = spa_get_rootblkptr(spa);
+
+	dp = kmem_zalloc(sizeof (dsl_pool_t), KM_SLEEP);
+	dp->dp_spa = spa;
+	dp->dp_meta_rootbp = *bp;
+	rrw_init(&dp->dp_config_rwlock, B_TRUE);
+	txg_init(dp, txg);
+
+	txg_list_create(&dp->dp_dirty_datasets,
+	    offsetof(dsl_dataset_t, ds_dirty_link));
+	txg_list_create(&dp->dp_dirty_zilogs,
+	    offsetof(zilog_t, zl_dirty_link));
+	txg_list_create(&dp->dp_dirty_dirs,
+	    offsetof(dsl_dir_t, dd_dirty_link));
+	txg_list_create(&dp->dp_sync_tasks,
+	    offsetof(dsl_sync_task_t, dst_node));
+
+	mutex_init(&dp->dp_lock, NULL, MUTEX_DEFAULT, NULL);
+	cv_init(&dp->dp_spaceavail_cv, NULL, CV_DEFAULT, NULL);
+
+	dp->dp_iput_taskq = taskq_create("z_iput", max_ncpus, defclsyspri,
+	    max_ncpus * 8, INT_MAX, TASKQ_PREPOPULATE | TASKQ_DYNAMIC);
+
+	return (dp);
+}
+
+int
+dsl_pool_init(spa_t *spa, uint64_t txg, dsl_pool_t **dpp)
+{
+	int err;
+	dsl_pool_t *dp = dsl_pool_open_impl(spa, txg);
+
+	err = dmu_objset_open_impl(spa, NULL, &dp->dp_meta_rootbp,
+	    &dp->dp_meta_objset);
+	if (err != 0)
+		dsl_pool_close(dp);
+	else
+		*dpp = dp;
+
+	return (err);
+}
+
+int
+dsl_pool_open(dsl_pool_t *dp)
+{
+	int err;
+	dsl_dir_t *dd;
+	dsl_dataset_t *ds;
+	uint64_t obj;
+
+	rrw_enter(&dp->dp_config_rwlock, RW_WRITER, FTAG);
+	err = zap_lookup(dp->dp_meta_objset, DMU_POOL_DIRECTORY_OBJECT,
+	    DMU_POOL_ROOT_DATASET, sizeof (uint64_t), 1,
+	    &dp->dp_root_dir_obj);
+	if (err)
+		goto out;
+
+	err = dsl_dir_hold_obj(dp, dp->dp_root_dir_obj,
+	    NULL, dp, &dp->dp_root_dir);
+	if (err)
+		goto out;
+
+	err = dsl_pool_open_special_dir(dp, MOS_DIR_NAME, &dp->dp_mos_dir);
+	if (err)
+		goto out;
+
+	if (spa_version(dp->dp_spa) >= SPA_VERSION_ORIGIN) {
+		err = dsl_pool_open_special_dir(dp, ORIGIN_DIR_NAME, &dd);
+		if (err)
+			goto out;
+		err = dsl_dataset_hold_obj(dp,
+		    dsl_dir_phys(dd)->dd_head_dataset_obj, FTAG, &ds);
+		if (err == 0) {
+			err = dsl_dataset_hold_obj(dp,
+			    dsl_dataset_phys(ds)->ds_prev_snap_obj, dp,
+			    &dp->dp_origin_snap);
+			dsl_dataset_rele(ds, FTAG);
+		}
+		dsl_dir_rele(dd, dp);
+		if (err)
+			goto out;
+	}
+
+	if (spa_version(dp->dp_spa) >= SPA_VERSION_DEADLISTS) {
+		err = dsl_pool_open_special_dir(dp, FREE_DIR_NAME,
+		    &dp->dp_free_dir);
+		if (err)
+			goto out;
+
+		err = zap_lookup(dp->dp_meta_objset, DMU_POOL_DIRECTORY_OBJECT,
+		    DMU_POOL_FREE_BPOBJ, sizeof (uint64_t), 1, &obj);
+		if (err)
+			goto out;
+		VERIFY0(bpobj_open(&dp->dp_free_bpobj,
+		    dp->dp_meta_objset, obj));
+	}
+
+	/*
+	 * Note: errors ignored, because the leak dir will not exist if we
+	 * have not encountered a leak yet.
+	 */
+	(void) dsl_pool_open_special_dir(dp, LEAK_DIR_NAME,
+	    &dp->dp_leak_dir);
+
+	if (spa_feature_is_active(dp->dp_spa, SPA_FEATURE_ASYNC_DESTROY)) {
+		err = zap_lookup(dp->dp_meta_objset, DMU_POOL_DIRECTORY_OBJECT,
+		    DMU_POOL_BPTREE_OBJ, sizeof (uint64_t), 1,
+		    &dp->dp_bptree_obj);
+		if (err != 0)
+			goto out;
+	}
+
+	if (spa_feature_is_active(dp->dp_spa, SPA_FEATURE_EMPTY_BPOBJ)) {
+		err = zap_lookup(dp->dp_meta_objset, DMU_POOL_DIRECTORY_OBJECT,
+		    DMU_POOL_EMPTY_BPOBJ, sizeof (uint64_t), 1,
+		    &dp->dp_empty_bpobj);
+		if (err != 0)
+			goto out;
+	}
+
+	err = zap_lookup(dp->dp_meta_objset, DMU_POOL_DIRECTORY_OBJECT,
+	    DMU_POOL_TMP_USERREFS, sizeof (uint64_t), 1,
+	    &dp->dp_tmp_userrefs_obj);
+	if (err == ENOENT)
+		err = 0;
+	if (err)
+		goto out;
+
+	err = dsl_scan_init(dp, dp->dp_tx.tx_open_txg);
+
+out:
+	rrw_exit(&dp->dp_config_rwlock, FTAG);
+	return (err);
+}
+
+void
+dsl_pool_close(dsl_pool_t *dp)
+{
+	/*
+	 * Drop our references from dsl_pool_open().
+	 *
+	 * Since we held the origin_snap from "syncing" context (which
+	 * includes pool-opening context), it actually only got a "ref"
+	 * and not a hold, so just drop that here.
+	 */
+	if (dp->dp_origin_snap)
+		dsl_dataset_rele(dp->dp_origin_snap, dp);
+	if (dp->dp_mos_dir)
+		dsl_dir_rele(dp->dp_mos_dir, dp);
+	if (dp->dp_free_dir)
+		dsl_dir_rele(dp->dp_free_dir, dp);
+	if (dp->dp_leak_dir)
+		dsl_dir_rele(dp->dp_leak_dir, dp);
+	if (dp->dp_root_dir)
+		dsl_dir_rele(dp->dp_root_dir, dp);
+
+	bpobj_close(&dp->dp_free_bpobj);
+
+	/* undo the dmu_objset_open_impl(mos) from dsl_pool_open() */
+	if (dp->dp_meta_objset)
+		dmu_objset_evict(dp->dp_meta_objset);
+
+	txg_list_destroy(&dp->dp_dirty_datasets);
+	txg_list_destroy(&dp->dp_dirty_zilogs);
+	txg_list_destroy(&dp->dp_sync_tasks);
+	txg_list_destroy(&dp->dp_dirty_dirs);
+
+	/*
+	 * We can't set retry to TRUE since we're explicitly specifying
+	 * a spa to flush. This is good enough; any missed buffers for
+	 * this spa won't cause trouble, and they'll eventually fall
+	 * out of the ARC just like any other unused buffer.
+	 */
+	arc_flush(dp->dp_spa, FALSE);
+
+	txg_fini(dp);
+	dsl_scan_fini(dp);
+	dmu_buf_user_evict_wait();
+
+	rrw_destroy(&dp->dp_config_rwlock);
+	mutex_destroy(&dp->dp_lock);
+	taskq_destroy(dp->dp_iput_taskq);
+	if (dp->dp_blkstats)
+		vmem_free(dp->dp_blkstats, sizeof (zfs_all_blkstats_t));
+	kmem_free(dp, sizeof (dsl_pool_t));
+}
+
+dsl_pool_t *
+dsl_pool_create(spa_t *spa, nvlist_t *zplprops, uint64_t txg)
+{
+	int err;
+	dsl_pool_t *dp = dsl_pool_open_impl(spa, txg);
+	dmu_tx_t *tx = dmu_tx_create_assigned(dp, txg);
+	objset_t *os;
+	dsl_dataset_t *ds;
+	uint64_t obj;
+
+	rrw_enter(&dp->dp_config_rwlock, RW_WRITER, FTAG);
+
+	/* create and open the MOS (meta-objset) */
+	dp->dp_meta_objset = dmu_objset_create_impl(spa,
+	    NULL, &dp->dp_meta_rootbp, DMU_OST_META, tx);
+
+	/* create the pool directory */
+	err = zap_create_claim(dp->dp_meta_objset, DMU_POOL_DIRECTORY_OBJECT,
+	    DMU_OT_OBJECT_DIRECTORY, DMU_OT_NONE, 0, tx);
+	ASSERT0(err);
+
+	/* Initialize scan structures */
+	VERIFY0(dsl_scan_init(dp, txg));
+
+	/* create and open the root dir */
+	dp->dp_root_dir_obj = dsl_dir_create_sync(dp, NULL, NULL, tx);
+	VERIFY0(dsl_dir_hold_obj(dp, dp->dp_root_dir_obj,
+	    NULL, dp, &dp->dp_root_dir));
+
+	/* create and open the meta-objset dir */
+	(void) dsl_dir_create_sync(dp, dp->dp_root_dir, MOS_DIR_NAME, tx);
+	VERIFY0(dsl_pool_open_special_dir(dp,
+	    MOS_DIR_NAME, &dp->dp_mos_dir));
+
+	if (spa_version(spa) >= SPA_VERSION_DEADLISTS) {
+		/* create and open the free dir */
+		(void) dsl_dir_create_sync(dp, dp->dp_root_dir,
+		    FREE_DIR_NAME, tx);
+		VERIFY0(dsl_pool_open_special_dir(dp,
+		    FREE_DIR_NAME, &dp->dp_free_dir));
+
+		/* create and open the free_bplist */
+		obj = bpobj_alloc(dp->dp_meta_objset, SPA_OLD_MAXBLOCKSIZE, tx);
+		VERIFY(zap_add(dp->dp_meta_objset, DMU_POOL_DIRECTORY_OBJECT,
+		    DMU_POOL_FREE_BPOBJ, sizeof (uint64_t), 1, &obj, tx) == 0);
+		VERIFY0(bpobj_open(&dp->dp_free_bpobj,
+		    dp->dp_meta_objset, obj));
+	}
+
+	if (spa_version(spa) >= SPA_VERSION_DSL_SCRUB)
+		dsl_pool_create_origin(dp, tx);
+
+	/* create the root dataset */
+	obj = dsl_dataset_create_sync_dd(dp->dp_root_dir, NULL, 0, tx);
+
+	/* create the root objset */
+	VERIFY0(dsl_dataset_hold_obj(dp, obj, FTAG, &ds));
+	VERIFY(NULL != (os = dmu_objset_create_impl(dp->dp_spa, ds,
+	    dsl_dataset_get_blkptr(ds), DMU_OST_ZFS, tx)));
+#ifdef _KERNEL
+	zfs_create_fs(os, kcred, zplprops, tx);
+#endif
+	dsl_dataset_rele(ds, FTAG);
+
+	dmu_tx_commit(tx);
+
+	rrw_exit(&dp->dp_config_rwlock, FTAG);
+
+	return (dp);
+}
+
+/*
+ * Account for the meta-objset space in its placeholder dsl_dir.
+ */
+void
+dsl_pool_mos_diduse_space(dsl_pool_t *dp,
+    int64_t used, int64_t comp, int64_t uncomp)
+{
+	ASSERT3U(comp, ==, uncomp); /* it's all metadata */
+	mutex_enter(&dp->dp_lock);
+	dp->dp_mos_used_delta += used;
+	dp->dp_mos_compressed_delta += comp;
+	dp->dp_mos_uncompressed_delta += uncomp;
+	mutex_exit(&dp->dp_lock);
+}
+
+static int
+deadlist_enqueue_cb(void *arg, const blkptr_t *bp, dmu_tx_t *tx)
+{
+	dsl_deadlist_t *dl = arg;
+	dsl_deadlist_insert(dl, bp, tx);
+	return (0);
+}
+
+static void
+dsl_pool_sync_mos(dsl_pool_t *dp, dmu_tx_t *tx)
+{
+	zio_t *zio = zio_root(dp->dp_spa, NULL, NULL, ZIO_FLAG_MUSTSUCCEED);
+	dmu_objset_sync(dp->dp_meta_objset, zio, tx);
+	VERIFY0(zio_wait(zio));
+	dprintf_bp(&dp->dp_meta_rootbp, "meta objset rootbp is %s", "");
+	spa_set_rootblkptr(dp->dp_spa, &dp->dp_meta_rootbp);
+}
+
+static void
+dsl_pool_dirty_delta(dsl_pool_t *dp, int64_t delta)
+{
+	ASSERT(MUTEX_HELD(&dp->dp_lock));
+
+	if (delta < 0)
+		ASSERT3U(-delta, <=, dp->dp_dirty_total);
+
+	dp->dp_dirty_total += delta;
+
+	/*
+	 * Note: we signal even when increasing dp_dirty_total.
+	 * This ensures forward progress -- each thread wakes the next waiter.
+	 */
+	if (dp->dp_dirty_total <= zfs_dirty_data_max)
+		cv_signal(&dp->dp_spaceavail_cv);
+}
+
+void
+dsl_pool_sync(dsl_pool_t *dp, uint64_t txg)
+{
+	zio_t *zio;
+	dmu_tx_t *tx;
+	dsl_dir_t *dd;
+	dsl_dataset_t *ds;
+	objset_t *mos = dp->dp_meta_objset;
+	list_t synced_datasets;
+
+	list_create(&synced_datasets, sizeof (dsl_dataset_t),
+	    offsetof(dsl_dataset_t, ds_synced_link));
+
+	tx = dmu_tx_create_assigned(dp, txg);
+
+	/*
+	 * Write out all dirty blocks of dirty datasets.
+	 */
+	zio = zio_root(dp->dp_spa, NULL, NULL, ZIO_FLAG_MUSTSUCCEED);
+	while ((ds = txg_list_remove(&dp->dp_dirty_datasets, txg)) != NULL) {
+		/*
+		 * We must not sync any non-MOS datasets twice, because
+		 * we may have taken a snapshot of them.  However, we
+		 * may sync newly-created datasets on pass 2.
+		 */
+		ASSERT(!list_link_active(&ds->ds_synced_link));
+		list_insert_tail(&synced_datasets, ds);
+		dsl_dataset_sync(ds, zio, tx);
+	}
+	VERIFY0(zio_wait(zio));
+
+	/*
+	 * We have written all of the accounted dirty data, so our
+	 * dp_space_towrite should now be zero.  However, some seldom-used
+	 * code paths do not adhere to this (e.g. dbuf_undirty(), also
+	 * rounding error in dbuf_write_physdone).
+	 * Shore up the accounting of any dirtied space now.
+	 */
+	dsl_pool_undirty_space(dp, dp->dp_dirty_pertxg[txg & TXG_MASK], txg);
+
+	/*
+	 * After the data blocks have been written (ensured by the zio_wait()
+	 * above), update the user/group space accounting.
+	 */
+	for (ds = list_head(&synced_datasets); ds != NULL;
+	    ds = list_next(&synced_datasets, ds)) {
+		dmu_objset_do_userquota_updates(ds->ds_objset, tx);
+	}
+
+	/*
+	 * Sync the datasets again to push out the changes due to
+	 * userspace updates.  This must be done before we process the
+	 * sync tasks, so that any snapshots will have the correct
+	 * user accounting information (and we won't get confused
+	 * about which blocks are part of the snapshot).
+	 */
+	zio = zio_root(dp->dp_spa, NULL, NULL, ZIO_FLAG_MUSTSUCCEED);
+	while ((ds = txg_list_remove(&dp->dp_dirty_datasets, txg)) != NULL) {
+		ASSERT(list_link_active(&ds->ds_synced_link));
+		dmu_buf_rele(ds->ds_dbuf, ds);
+		dsl_dataset_sync(ds, zio, tx);
+	}
+	VERIFY0(zio_wait(zio));
+
+	/*
+	 * Now that the datasets have been completely synced, we can
+	 * clean up our in-memory structures accumulated while syncing:
+	 *
+	 *  - move dead blocks from the pending deadlist to the on-disk deadlist
+	 *  - release hold from dsl_dataset_dirty()
+	 */
+	while ((ds = list_remove_head(&synced_datasets)) != NULL) {
+		ASSERTV(objset_t *os = ds->ds_objset);
+		bplist_iterate(&ds->ds_pending_deadlist,
+		    deadlist_enqueue_cb, &ds->ds_deadlist, tx);
+		ASSERT(!dmu_objset_is_dirty(os, txg));
+		dmu_buf_rele(ds->ds_dbuf, ds);
+	}
+
+	while ((dd = txg_list_remove(&dp->dp_dirty_dirs, txg)) != NULL) {
+		dsl_dir_sync(dd, tx);
+	}
+
+	/*
+	 * The MOS's space is accounted for in the pool/$MOS
+	 * (dp_mos_dir).  We can't modify the mos while we're syncing
+	 * it, so we remember the deltas and apply them here.
+	 */
+	if (dp->dp_mos_used_delta != 0 || dp->dp_mos_compressed_delta != 0 ||
+	    dp->dp_mos_uncompressed_delta != 0) {
+		dsl_dir_diduse_space(dp->dp_mos_dir, DD_USED_HEAD,
+		    dp->dp_mos_used_delta,
+		    dp->dp_mos_compressed_delta,
+		    dp->dp_mos_uncompressed_delta, tx);
+		dp->dp_mos_used_delta = 0;
+		dp->dp_mos_compressed_delta = 0;
+		dp->dp_mos_uncompressed_delta = 0;
+	}
+
+	if (list_head(&mos->os_dirty_dnodes[txg & TXG_MASK]) != NULL ||
+	    list_head(&mos->os_free_dnodes[txg & TXG_MASK]) != NULL) {
+		dsl_pool_sync_mos(dp, tx);
+	}
+
+	/*
+	 * If we modify a dataset in the same txg that we want to destroy it,
+	 * its dsl_dir's dd_dbuf will be dirty, and thus have a hold on it.
+	 * dsl_dir_destroy_check() will fail if there are unexpected holds.
+	 * Therefore, we want to sync the MOS (thus syncing the dd_dbuf
+	 * and clearing the hold on it) before we process the sync_tasks.
+	 * The MOS data dirtied by the sync_tasks will be synced on the next
+	 * pass.
+	 */
+	if (!txg_list_empty(&dp->dp_sync_tasks, txg)) {
+		dsl_sync_task_t *dst;
+		/*
+		 * No more sync tasks should have been added while we
+		 * were syncing.
+		 */
+		ASSERT3U(spa_sync_pass(dp->dp_spa), ==, 1);
+		while ((dst = txg_list_remove(&dp->dp_sync_tasks, txg)) != NULL)
+			dsl_sync_task_sync(dst, tx);
+	}
+
+	dmu_tx_commit(tx);
+
+	DTRACE_PROBE2(dsl_pool_sync__done, dsl_pool_t *dp, dp, uint64_t, txg);
+}
+
+void
+dsl_pool_sync_done(dsl_pool_t *dp, uint64_t txg)
+{
+	zilog_t *zilog;
+
+	while ((zilog = txg_list_remove(&dp->dp_dirty_zilogs, txg))) {
+		dsl_dataset_t *ds = dmu_objset_ds(zilog->zl_os);
+		zil_clean(zilog, txg);
+		ASSERT(!dmu_objset_is_dirty(zilog->zl_os, txg));
+		dmu_buf_rele(ds->ds_dbuf, zilog);
+	}
+	ASSERT(!dmu_objset_is_dirty(dp->dp_meta_objset, txg));
+}
+
+/*
+ * TRUE if the current thread is the tx_sync_thread or if we
+ * are being called from SPA context during pool initialization.
+ */
+int
+dsl_pool_sync_context(dsl_pool_t *dp)
+{
+	return (curthread == dp->dp_tx.tx_sync_thread ||
+	    spa_is_initializing(dp->dp_spa));
+}
+
+uint64_t
+dsl_pool_adjustedsize(dsl_pool_t *dp, boolean_t netfree)
+{
+	uint64_t space, resv;
+
+	/*
+	 * If we're trying to assess whether it's OK to do a free,
+	 * cut the reservation in half to allow forward progress
+	 * (e.g. make it possible to rm(1) files from a full pool).
+	 */
+	space = spa_get_dspace(dp->dp_spa);
+	resv = spa_get_slop_space(dp->dp_spa);
+	if (netfree)
+		resv >>= 1;
+
+	return (space - resv);
+}
+
+boolean_t
+dsl_pool_need_dirty_delay(dsl_pool_t *dp)
+{
+	uint64_t delay_min_bytes =
+	    zfs_dirty_data_max * zfs_delay_min_dirty_percent / 100;
+	boolean_t rv;
+
+	mutex_enter(&dp->dp_lock);
+	if (dp->dp_dirty_total > zfs_dirty_data_sync)
+		txg_kick(dp);
+	rv = (dp->dp_dirty_total > delay_min_bytes);
+	mutex_exit(&dp->dp_lock);
+	return (rv);
+}
+
+void
+dsl_pool_dirty_space(dsl_pool_t *dp, int64_t space, dmu_tx_t *tx)
+{
+	if (space > 0) {
+		mutex_enter(&dp->dp_lock);
+		dp->dp_dirty_pertxg[tx->tx_txg & TXG_MASK] += space;
+		dsl_pool_dirty_delta(dp, space);
+		mutex_exit(&dp->dp_lock);
+	}
+}
+
+void
+dsl_pool_undirty_space(dsl_pool_t *dp, int64_t space, uint64_t txg)
+{
+	ASSERT3S(space, >=, 0);
+	if (space == 0)
+		return;
+
+	mutex_enter(&dp->dp_lock);
+	if (dp->dp_dirty_pertxg[txg & TXG_MASK] < space) {
+		/* XXX writing something we didn't dirty? */
+		space = dp->dp_dirty_pertxg[txg & TXG_MASK];
+	}
+	ASSERT3U(dp->dp_dirty_pertxg[txg & TXG_MASK], >=, space);
+	dp->dp_dirty_pertxg[txg & TXG_MASK] -= space;
+	ASSERT3U(dp->dp_dirty_total, >=, space);
+	dsl_pool_dirty_delta(dp, -space);
+	mutex_exit(&dp->dp_lock);
+}
+
+/* ARGSUSED */
+static int
+upgrade_clones_cb(dsl_pool_t *dp, dsl_dataset_t *hds, void *arg)
+{
+	dmu_tx_t *tx = arg;
+	dsl_dataset_t *ds, *prev = NULL;
+	int err;
+
+	err = dsl_dataset_hold_obj(dp, hds->ds_object, FTAG, &ds);
+	if (err)
+		return (err);
+
+	while (dsl_dataset_phys(ds)->ds_prev_snap_obj != 0) {
+		err = dsl_dataset_hold_obj(dp,
+		    dsl_dataset_phys(ds)->ds_prev_snap_obj, FTAG, &prev);
+		if (err) {
+			dsl_dataset_rele(ds, FTAG);
+			return (err);
+		}
+
+		if (dsl_dataset_phys(prev)->ds_next_snap_obj != ds->ds_object)
+			break;
+		dsl_dataset_rele(ds, FTAG);
+		ds = prev;
+		prev = NULL;
+	}
+
+	if (prev == NULL) {
+		prev = dp->dp_origin_snap;
+
+		/*
+		 * The $ORIGIN can't have any data, or the accounting
+		 * will be wrong.
+		 */
+		ASSERT0(dsl_dataset_phys(prev)->ds_bp.blk_birth);
+
+		/* The origin doesn't get attached to itself */
+		if (ds->ds_object == prev->ds_object) {
+			dsl_dataset_rele(ds, FTAG);
+			return (0);
+		}
+
+		dmu_buf_will_dirty(ds->ds_dbuf, tx);
+		dsl_dataset_phys(ds)->ds_prev_snap_obj = prev->ds_object;
+		dsl_dataset_phys(ds)->ds_prev_snap_txg =
+		    dsl_dataset_phys(prev)->ds_creation_txg;
+
+		dmu_buf_will_dirty(ds->ds_dir->dd_dbuf, tx);
+		dsl_dir_phys(ds->ds_dir)->dd_origin_obj = prev->ds_object;
+
+		dmu_buf_will_dirty(prev->ds_dbuf, tx);
+		dsl_dataset_phys(prev)->ds_num_children++;
+
+		if (dsl_dataset_phys(ds)->ds_next_snap_obj == 0) {
+			ASSERT(ds->ds_prev == NULL);
+			VERIFY0(dsl_dataset_hold_obj(dp,
+			    dsl_dataset_phys(ds)->ds_prev_snap_obj,
+			    ds, &ds->ds_prev));
+		}
+	}
+
+	ASSERT3U(dsl_dir_phys(ds->ds_dir)->dd_origin_obj, ==, prev->ds_object);
+	ASSERT3U(dsl_dataset_phys(ds)->ds_prev_snap_obj, ==, prev->ds_object);
+
+	if (dsl_dataset_phys(prev)->ds_next_clones_obj == 0) {
+		dmu_buf_will_dirty(prev->ds_dbuf, tx);
+		dsl_dataset_phys(prev)->ds_next_clones_obj =
+		    zap_create(dp->dp_meta_objset,
+		    DMU_OT_NEXT_CLONES, DMU_OT_NONE, 0, tx);
+	}
+	VERIFY0(zap_add_int(dp->dp_meta_objset,
+	    dsl_dataset_phys(prev)->ds_next_clones_obj, ds->ds_object, tx));
+
+	dsl_dataset_rele(ds, FTAG);
+	if (prev != dp->dp_origin_snap)
+		dsl_dataset_rele(prev, FTAG);
+	return (0);
+}
+
+void
+dsl_pool_upgrade_clones(dsl_pool_t *dp, dmu_tx_t *tx)
+{
+	ASSERT(dmu_tx_is_syncing(tx));
+	ASSERT(dp->dp_origin_snap != NULL);
+
+	VERIFY0(dmu_objset_find_dp(dp, dp->dp_root_dir_obj, upgrade_clones_cb,
+	    tx, DS_FIND_CHILDREN | DS_FIND_SERIALIZE));
+}
+
+/* ARGSUSED */
+static int
+upgrade_dir_clones_cb(dsl_pool_t *dp, dsl_dataset_t *ds, void *arg)
+{
+	dmu_tx_t *tx = arg;
+	objset_t *mos = dp->dp_meta_objset;
+
+	if (dsl_dir_phys(ds->ds_dir)->dd_origin_obj != 0) {
+		dsl_dataset_t *origin;
+
+		VERIFY0(dsl_dataset_hold_obj(dp,
+		    dsl_dir_phys(ds->ds_dir)->dd_origin_obj, FTAG, &origin));
+
+		if (dsl_dir_phys(origin->ds_dir)->dd_clones == 0) {
+			dmu_buf_will_dirty(origin->ds_dir->dd_dbuf, tx);
+			dsl_dir_phys(origin->ds_dir)->dd_clones =
+			    zap_create(mos, DMU_OT_DSL_CLONES, DMU_OT_NONE,
+			    0, tx);
+		}
+
+		VERIFY0(zap_add_int(dp->dp_meta_objset,
+		    dsl_dir_phys(origin->ds_dir)->dd_clones,
+		    ds->ds_object, tx));
+
+		dsl_dataset_rele(origin, FTAG);
+	}
+	return (0);
+}
+
+void
+dsl_pool_upgrade_dir_clones(dsl_pool_t *dp, dmu_tx_t *tx)
+{
+	uint64_t obj;
+
+	ASSERT(dmu_tx_is_syncing(tx));
+
+	(void) dsl_dir_create_sync(dp, dp->dp_root_dir, FREE_DIR_NAME, tx);
+	VERIFY0(dsl_pool_open_special_dir(dp,
+	    FREE_DIR_NAME, &dp->dp_free_dir));
+
+	/*
+	 * We can't use bpobj_alloc(), because spa_version() still
+	 * returns the old version, and we need a new-version bpobj with
+	 * subobj support.  So call dmu_object_alloc() directly.
+	 */
+	obj = dmu_object_alloc(dp->dp_meta_objset, DMU_OT_BPOBJ,
+	    SPA_OLD_MAXBLOCKSIZE, DMU_OT_BPOBJ_HDR, sizeof (bpobj_phys_t), tx);
+	VERIFY0(zap_add(dp->dp_meta_objset, DMU_POOL_DIRECTORY_OBJECT,
+	    DMU_POOL_FREE_BPOBJ, sizeof (uint64_t), 1, &obj, tx));
+	VERIFY0(bpobj_open(&dp->dp_free_bpobj, dp->dp_meta_objset, obj));
+
+	VERIFY0(dmu_objset_find_dp(dp, dp->dp_root_dir_obj,
+	    upgrade_dir_clones_cb, tx, DS_FIND_CHILDREN | DS_FIND_SERIALIZE));
+}
+
+void
+dsl_pool_create_origin(dsl_pool_t *dp, dmu_tx_t *tx)
+{
+	uint64_t dsobj;
+	dsl_dataset_t *ds;
+
+	ASSERT(dmu_tx_is_syncing(tx));
+	ASSERT(dp->dp_origin_snap == NULL);
+	ASSERT(rrw_held(&dp->dp_config_rwlock, RW_WRITER));
+
+	/* create the origin dir, ds, & snap-ds */
+	dsobj = dsl_dataset_create_sync(dp->dp_root_dir, ORIGIN_DIR_NAME,
+	    NULL, 0, kcred, tx);
+	VERIFY0(dsl_dataset_hold_obj(dp, dsobj, FTAG, &ds));
+	dsl_dataset_snapshot_sync_impl(ds, ORIGIN_DIR_NAME, tx);
+	VERIFY0(dsl_dataset_hold_obj(dp, dsl_dataset_phys(ds)->ds_prev_snap_obj,
+	    dp, &dp->dp_origin_snap));
+	dsl_dataset_rele(ds, FTAG);
+}
+
+taskq_t *
+dsl_pool_iput_taskq(dsl_pool_t *dp)
+{
+	return (dp->dp_iput_taskq);
+}
+
+/*
+ * Walk through the pool-wide zap object of temporary snapshot user holds
+ * and release them.
+ */
+void
+dsl_pool_clean_tmp_userrefs(dsl_pool_t *dp)
+{
+	zap_attribute_t za;
+	zap_cursor_t zc;
+	objset_t *mos = dp->dp_meta_objset;
+	uint64_t zapobj = dp->dp_tmp_userrefs_obj;
+	nvlist_t *holds;
+
+	if (zapobj == 0)
+		return;
+	ASSERT(spa_version(dp->dp_spa) >= SPA_VERSION_USERREFS);
+
+	holds = fnvlist_alloc();
+
+	for (zap_cursor_init(&zc, mos, zapobj);
+	    zap_cursor_retrieve(&zc, &za) == 0;
+	    zap_cursor_advance(&zc)) {
+		char *htag;
+		nvlist_t *tags;
+
+		htag = strchr(za.za_name, '-');
+		*htag = '\0';
+		++htag;
+		if (nvlist_lookup_nvlist(holds, za.za_name, &tags) != 0) {
+			tags = fnvlist_alloc();
+			fnvlist_add_boolean(tags, htag);
+			fnvlist_add_nvlist(holds, za.za_name, tags);
+			fnvlist_free(tags);
+		} else {
+			fnvlist_add_boolean(tags, htag);
+		}
+	}
+	dsl_dataset_user_release_tmp(dp, holds);
+	fnvlist_free(holds);
+	zap_cursor_fini(&zc);
+}
+
+/*
+ * Create the pool-wide zap object for storing temporary snapshot holds.
+ */
+void
+dsl_pool_user_hold_create_obj(dsl_pool_t *dp, dmu_tx_t *tx)
+{
+	objset_t *mos = dp->dp_meta_objset;
+
+	ASSERT(dp->dp_tmp_userrefs_obj == 0);
+	ASSERT(dmu_tx_is_syncing(tx));
+
+	dp->dp_tmp_userrefs_obj = zap_create_link(mos, DMU_OT_USERREFS,
+	    DMU_POOL_DIRECTORY_OBJECT, DMU_POOL_TMP_USERREFS, tx);
+}
+
+static int
+dsl_pool_user_hold_rele_impl(dsl_pool_t *dp, uint64_t dsobj,
+    const char *tag, uint64_t now, dmu_tx_t *tx, boolean_t holding)
+{
+	objset_t *mos = dp->dp_meta_objset;
+	uint64_t zapobj = dp->dp_tmp_userrefs_obj;
+	char *name;
+	int error;
+
+	ASSERT(spa_version(dp->dp_spa) >= SPA_VERSION_USERREFS);
+	ASSERT(dmu_tx_is_syncing(tx));
+
+	/*
+	 * If the pool was created prior to SPA_VERSION_USERREFS, the
+	 * zap object for temporary holds might not exist yet.
+	 */
+	if (zapobj == 0) {
+		if (holding) {
+			dsl_pool_user_hold_create_obj(dp, tx);
+			zapobj = dp->dp_tmp_userrefs_obj;
+		} else {
+			return (SET_ERROR(ENOENT));
+		}
+	}
+
+	name = kmem_asprintf("%llx-%s", (u_longlong_t)dsobj, tag);
+	if (holding)
+		error = zap_add(mos, zapobj, name, 8, 1, &now, tx);
+	else
+		error = zap_remove(mos, zapobj, name, tx);
+	strfree(name);
+
+	return (error);
+}
+
+/*
+ * Add a temporary hold for the given dataset object and tag.
+ */
+int
+dsl_pool_user_hold(dsl_pool_t *dp, uint64_t dsobj, const char *tag,
+    uint64_t now, dmu_tx_t *tx)
+{
+	return (dsl_pool_user_hold_rele_impl(dp, dsobj, tag, now, tx, B_TRUE));
+}
+
+/*
+ * Release a temporary hold for the given dataset object and tag.
+ */
+int
+dsl_pool_user_release(dsl_pool_t *dp, uint64_t dsobj, const char *tag,
+    dmu_tx_t *tx)
+{
+	return (dsl_pool_user_hold_rele_impl(dp, dsobj, tag, 0,
+	    tx, B_FALSE));
+}
+
+/*
+ * DSL Pool Configuration Lock
+ *
+ * The dp_config_rwlock protects against changes to DSL state (e.g. dataset
+ * creation / destruction / rename / property setting).  It must be held for
+ * read to hold a dataset or dsl_dir.  I.e. you must call
+ * dsl_pool_config_enter() or dsl_pool_hold() before calling
+ * dsl_{dataset,dir}_hold{_obj}.  In most circumstances, the dp_config_rwlock
+ * must be held continuously until all datasets and dsl_dirs are released.
+ *
+ * The only exception to this rule is that if a "long hold" is placed on
+ * a dataset, then the dp_config_rwlock may be dropped while the dataset
+ * is still held.  The long hold will prevent the dataset from being
+ * destroyed -- the destroy will fail with EBUSY.  A long hold can be
+ * obtained by calling dsl_dataset_long_hold(), or by "owning" a dataset
+ * (by calling dsl_{dataset,objset}_{try}own{_obj}).
+ *
+ * Legitimate long-holders (including owners) should be long-running, cancelable
+ * tasks that should cause "zfs destroy" to fail.  This includes DMU
+ * consumers (i.e. a ZPL filesystem being mounted or ZVOL being open),
+ * "zfs send", and "zfs diff".  There are several other long-holders whose
+ * uses are suboptimal (e.g. "zfs promote", and zil_suspend()).
+ *
+ * The usual formula for long-holding would be:
+ * dsl_pool_hold()
+ * dsl_dataset_hold()
+ * ... perform checks ...
+ * dsl_dataset_long_hold()
+ * dsl_pool_rele()
+ * ... perform long-running task ...
+ * dsl_dataset_long_rele()
+ * dsl_dataset_rele()
+ *
+ * Note that when the long hold is released, the dataset is still held but
+ * the pool is not held.  The dataset may change arbitrarily during this time
+ * (e.g. it could be destroyed).  Therefore you shouldn't do anything to the
+ * dataset except release it.
+ *
+ * User-initiated operations (e.g. ioctls, zfs_ioc_*()) are either read-only
+ * or modifying operations.
+ *
+ * Modifying operations should generally use dsl_sync_task().  The synctask
+ * infrastructure enforces proper locking strategy with respect to the
+ * dp_config_rwlock.  See the comment above dsl_sync_task() for details.
+ *
+ * Read-only operations will manually hold the pool, then the dataset, obtain
+ * information from the dataset, then release the pool and dataset.
+ * dmu_objset_{hold,rele}() are convenience routines that also do the pool
+ * hold/rele.
+ */
+
+int
+dsl_pool_hold(const char *name, void *tag, dsl_pool_t **dp)
+{
+	spa_t *spa;
+	int error;
+
+	error = spa_open(name, &spa, tag);
+	if (error == 0) {
+		*dp = spa_get_dsl(spa);
+		dsl_pool_config_enter(*dp, tag);
+	}
+	return (error);
+}
+
+void
+dsl_pool_rele(dsl_pool_t *dp, void *tag)
+{
+	dsl_pool_config_exit(dp, tag);
+	spa_close(dp->dp_spa, tag);
+}
+
+void
+dsl_pool_config_enter(dsl_pool_t *dp, void *tag)
+{
+	/*
+	 * We use a "reentrant" reader-writer lock, but not reentrantly.
+	 *
+	 * The rrwlock can (with the track_all flag) track all reading threads,
+	 * which is very useful for debugging which code path failed to release
+	 * the lock, and for verifying that the *current* thread does hold
+	 * the lock.
+	 *
+	 * (Unlike a rwlock, which knows that N threads hold it for
+	 * read, but not *which* threads, so rw_held(RW_READER) returns TRUE
+	 * if any thread holds it for read, even if this thread doesn't).
+	 */
+	ASSERT(!rrw_held(&dp->dp_config_rwlock, RW_READER));
+	rrw_enter(&dp->dp_config_rwlock, RW_READER, tag);
+}
+
+void
+dsl_pool_config_enter_prio(dsl_pool_t *dp, void *tag)
+{
+	ASSERT(!rrw_held(&dp->dp_config_rwlock, RW_READER));
+	rrw_enter_read_prio(&dp->dp_config_rwlock, tag);
+}
+
+void
+dsl_pool_config_exit(dsl_pool_t *dp, void *tag)
+{
+	rrw_exit(&dp->dp_config_rwlock, tag);
+}
+
+boolean_t
+dsl_pool_config_held(dsl_pool_t *dp)
+{
+	return (RRW_LOCK_HELD(&dp->dp_config_rwlock));
+}
+
+boolean_t
+dsl_pool_config_held_writer(dsl_pool_t *dp)
+{
+	return (RRW_WRITE_HELD(&dp->dp_config_rwlock));
+}
+
+#if defined(_KERNEL) && defined(HAVE_SPL)
+EXPORT_SYMBOL(dsl_pool_config_enter);
+EXPORT_SYMBOL(dsl_pool_config_exit);
+
+/* zfs_dirty_data_max_percent only applied at module load in arc_init(). */
+module_param(zfs_dirty_data_max_percent, int, 0444);
+MODULE_PARM_DESC(zfs_dirty_data_max_percent, "percent of ram can be dirty");
+
+/* zfs_dirty_data_max_max_percent only applied at module load in arc_init(). */
+module_param(zfs_dirty_data_max_max_percent, int, 0444);
+MODULE_PARM_DESC(zfs_dirty_data_max_max_percent,
+	"zfs_dirty_data_max upper bound as % of RAM");
+
+module_param(zfs_delay_min_dirty_percent, int, 0644);
+MODULE_PARM_DESC(zfs_delay_min_dirty_percent, "transaction delay threshold");
+
+module_param(zfs_dirty_data_max, ulong, 0644);
+MODULE_PARM_DESC(zfs_dirty_data_max, "determines the dirty space limit");
+
+/* zfs_dirty_data_max_max only applied at module load in arc_init(). */
+module_param(zfs_dirty_data_max_max, ulong, 0444);
+MODULE_PARM_DESC(zfs_dirty_data_max_max,
+	"zfs_dirty_data_max upper bound in bytes");
+
+module_param(zfs_dirty_data_sync, ulong, 0644);
+MODULE_PARM_DESC(zfs_dirty_data_sync, "sync txg when this much dirty data");
+
+module_param(zfs_delay_scale, ulong, 0644);
+MODULE_PARM_DESC(zfs_delay_scale, "how quickly delay approaches infinity");
+#endif
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/module/zfs/dsl_prop.c
@@ -0,0 +1,1175 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2014 by Delphix. All rights reserved.
+ * Copyright (c) 2013 Martin Matuska. All rights reserved.
+ */
+
+#include <sys/zfs_context.h>
+#include <sys/dmu.h>
+#include <sys/dmu_objset.h>
+#include <sys/dmu_tx.h>
+#include <sys/dsl_dataset.h>
+#include <sys/dsl_dir.h>
+#include <sys/dsl_prop.h>
+#include <sys/dsl_synctask.h>
+#include <sys/spa.h>
+#include <sys/zap.h>
+#include <sys/fs/zfs.h>
+
+#include "zfs_prop.h"
+
+#define	ZPROP_INHERIT_SUFFIX "$inherit"
+#define	ZPROP_RECVD_SUFFIX "$recvd"
+
+static int
+dodefault(const char *propname, int intsz, int numints, void *buf)
+{
+	zfs_prop_t prop;
+
+	/*
+	 * The setonce properties are read-only, BUT they still
+	 * have a default value that can be used as the initial
+	 * value.
+	 */
+	if ((prop = zfs_name_to_prop(propname)) == ZPROP_INVAL ||
+	    (zfs_prop_readonly(prop) && !zfs_prop_setonce(prop)))
+		return (SET_ERROR(ENOENT));
+
+	if (zfs_prop_get_type(prop) == PROP_TYPE_STRING) {
+		if (intsz != 1)
+			return (SET_ERROR(EOVERFLOW));
+		(void) strncpy(buf, zfs_prop_default_string(prop),
+		    numints);
+	} else {
+		if (intsz != 8 || numints < 1)
+			return (SET_ERROR(EOVERFLOW));
+
+		*(uint64_t *)buf = zfs_prop_default_numeric(prop);
+	}
+
+	return (0);
+}
+
+int
+dsl_prop_get_dd(dsl_dir_t *dd, const char *propname,
+    int intsz, int numints, void *buf, char *setpoint, boolean_t snapshot)
+{
+	int err = ENOENT;
+	dsl_dir_t *target = dd;
+	objset_t *mos = dd->dd_pool->dp_meta_objset;
+	zfs_prop_t prop;
+	boolean_t inheritable;
+	boolean_t inheriting = B_FALSE;
+	char *inheritstr;
+	char *recvdstr;
+
+	ASSERT(dsl_pool_config_held(dd->dd_pool));
+
+	if (setpoint)
+		setpoint[0] = '\0';
+
+	prop = zfs_name_to_prop(propname);
+	inheritable = (prop == ZPROP_INVAL || zfs_prop_inheritable(prop));
+	inheritstr = kmem_asprintf("%s%s", propname, ZPROP_INHERIT_SUFFIX);
+	recvdstr = kmem_asprintf("%s%s", propname, ZPROP_RECVD_SUFFIX);
+
+	/*
+	 * Note: dd may become NULL, therefore we shouldn't dereference it
+	 * after this loop.
+	 */
+	for (; dd != NULL; dd = dd->dd_parent) {
+		if (dd != target || snapshot) {
+			if (!inheritable)
+				break;
+			inheriting = B_TRUE;
+		}
+
+		/* Check for a local value. */
+		err = zap_lookup(mos, dsl_dir_phys(dd)->dd_props_zapobj,
+		    propname, intsz, numints, buf);
+		if (err != ENOENT) {
+			if (setpoint != NULL && err == 0)
+				dsl_dir_name(dd, setpoint);
+			break;
+		}
+
+		/*
+		 * Skip the check for a received value if there is an explicit
+		 * inheritance entry.
+		 */
+		err = zap_contains(mos, dsl_dir_phys(dd)->dd_props_zapobj,
+		    inheritstr);
+		if (err != 0 && err != ENOENT)
+			break;
+
+		if (err == ENOENT) {
+			/* Check for a received value. */
+			err = zap_lookup(mos, dsl_dir_phys(dd)->dd_props_zapobj,
+			    recvdstr, intsz, numints, buf);
+			if (err != ENOENT) {
+				if (setpoint != NULL && err == 0) {
+					if (inheriting) {
+						dsl_dir_name(dd, setpoint);
+					} else {
+						(void) strcpy(setpoint,
+						    ZPROP_SOURCE_VAL_RECVD);
+					}
+				}
+				break;
+			}
+		}
+
+		/*
+		 * If we found an explicit inheritance entry, err is zero even
+		 * though we haven't yet found the value, so reinitializing err
+		 * at the end of the loop (instead of at the beginning) ensures
+		 * that err has a valid post-loop value.
+		 */
+		err = SET_ERROR(ENOENT);
+	}
+
+	if (err == ENOENT)
+		err = dodefault(propname, intsz, numints, buf);
+
+	strfree(inheritstr);
+	strfree(recvdstr);
+
+	return (err);
+}
+
+int
+dsl_prop_get_ds(dsl_dataset_t *ds, const char *propname,
+    int intsz, int numints, void *buf, char *setpoint)
+{
+	zfs_prop_t prop = zfs_name_to_prop(propname);
+	boolean_t inheritable;
+	uint64_t zapobj;
+
+	ASSERT(dsl_pool_config_held(ds->ds_dir->dd_pool));
+	inheritable = (prop == ZPROP_INVAL || zfs_prop_inheritable(prop));
+	zapobj = dsl_dataset_phys(ds)->ds_props_obj;
+
+	if (zapobj != 0) {
+		objset_t *mos = ds->ds_dir->dd_pool->dp_meta_objset;
+		int err;
+
+		ASSERT(ds->ds_is_snapshot);
+
+		/* Check for a local value. */
+		err = zap_lookup(mos, zapobj, propname, intsz, numints, buf);
+		if (err != ENOENT) {
+			if (setpoint != NULL && err == 0)
+				dsl_dataset_name(ds, setpoint);
+			return (err);
+		}
+
+		/*
+		 * Skip the check for a received value if there is an explicit
+		 * inheritance entry.
+		 */
+		if (inheritable) {
+			char *inheritstr = kmem_asprintf("%s%s", propname,
+			    ZPROP_INHERIT_SUFFIX);
+			err = zap_contains(mos, zapobj, inheritstr);
+			strfree(inheritstr);
+			if (err != 0 && err != ENOENT)
+				return (err);
+		}
+
+		if (err == ENOENT) {
+			/* Check for a received value. */
+			char *recvdstr = kmem_asprintf("%s%s", propname,
+			    ZPROP_RECVD_SUFFIX);
+			err = zap_lookup(mos, zapobj, recvdstr,
+			    intsz, numints, buf);
+			strfree(recvdstr);
+			if (err != ENOENT) {
+				if (setpoint != NULL && err == 0)
+					(void) strcpy(setpoint,
+					    ZPROP_SOURCE_VAL_RECVD);
+				return (err);
+			}
+		}
+	}
+
+	return (dsl_prop_get_dd(ds->ds_dir, propname,
+	    intsz, numints, buf, setpoint, ds->ds_is_snapshot));
+}
+
+/*
+ * Register interest in the named property.  We'll call the callback
+ * once to notify it of the current property value, and again each time
+ * the property changes, until this callback is unregistered.
+ *
+ * Return 0 on success, errno if the prop is not an integer value.
+ */
+int
+dsl_prop_register(dsl_dataset_t *ds, const char *propname,
+    dsl_prop_changed_cb_t *callback, void *cbarg)
+{
+	dsl_dir_t *dd = ds->ds_dir;
+	uint64_t value;
+	dsl_prop_cb_record_t *cbr;
+	int err;
+	ASSERTV(dsl_pool_t *dp = dd->dd_pool);
+
+	ASSERT(dsl_pool_config_held(dp));
+
+	err = dsl_prop_get_int_ds(ds, propname, &value);
+	if (err != 0)
+		return (err);
+
+	cbr = kmem_alloc(sizeof (dsl_prop_cb_record_t), KM_SLEEP);
+	cbr->cbr_ds = ds;
+	cbr->cbr_propname = kmem_alloc(strlen(propname)+1, KM_SLEEP);
+	(void) strcpy((char *)cbr->cbr_propname, propname);
+	cbr->cbr_func = callback;
+	cbr->cbr_arg = cbarg;
+	mutex_enter(&dd->dd_lock);
+	list_insert_head(&dd->dd_prop_cbs, cbr);
+	mutex_exit(&dd->dd_lock);
+
+	cbr->cbr_func(cbr->cbr_arg, value);
+	return (0);
+}
+
+int
+dsl_prop_get(const char *dsname, const char *propname,
+    int intsz, int numints, void *buf, char *setpoint)
+{
+	objset_t *os;
+	int error;
+
+	error = dmu_objset_hold(dsname, FTAG, &os);
+	if (error != 0)
+		return (error);
+
+	error = dsl_prop_get_ds(dmu_objset_ds(os), propname,
+	    intsz, numints, buf, setpoint);
+
+	dmu_objset_rele(os, FTAG);
+	return (error);
+}
+
+/*
+ * Get the current property value.  It may have changed by the time this
+ * function returns, so it is NOT safe to follow up with
+ * dsl_prop_register() and assume that the value has not changed in
+ * between.
+ *
+ * Return 0 on success, ENOENT if ddname is invalid.
+ */
+int
+dsl_prop_get_integer(const char *ddname, const char *propname,
+    uint64_t *valuep, char *setpoint)
+{
+	return (dsl_prop_get(ddname, propname, 8, 1, valuep, setpoint));
+}
+
+int
+dsl_prop_get_int_ds(dsl_dataset_t *ds, const char *propname,
+    uint64_t *valuep)
+{
+	return (dsl_prop_get_ds(ds, propname, 8, 1, valuep, NULL));
+}
+
+/*
+ * Predict the effective value of the given special property if it were set with
+ * the given value and source. This is not a general purpose function. It exists
+ * only to handle the special requirements of the quota and reservation
+ * properties. The fact that these properties are non-inheritable greatly
+ * simplifies the prediction logic.
+ *
+ * Returns 0 on success, a positive error code on failure, or -1 if called with
+ * a property not handled by this function.
+ */
+int
+dsl_prop_predict(dsl_dir_t *dd, const char *propname,
+    zprop_source_t source, uint64_t value, uint64_t *newvalp)
+{
+	zfs_prop_t prop = zfs_name_to_prop(propname);
+	objset_t *mos;
+	uint64_t zapobj;
+	uint64_t version;
+	char *recvdstr;
+	int err = 0;
+
+	switch (prop) {
+	case ZFS_PROP_QUOTA:
+	case ZFS_PROP_RESERVATION:
+	case ZFS_PROP_REFQUOTA:
+	case ZFS_PROP_REFRESERVATION:
+		break;
+	default:
+		return (-1);
+	}
+
+	mos = dd->dd_pool->dp_meta_objset;
+	zapobj = dsl_dir_phys(dd)->dd_props_zapobj;
+	recvdstr = kmem_asprintf("%s%s", propname, ZPROP_RECVD_SUFFIX);
+
+	version = spa_version(dd->dd_pool->dp_spa);
+	if (version < SPA_VERSION_RECVD_PROPS) {
+		if (source & ZPROP_SRC_NONE)
+			source = ZPROP_SRC_NONE;
+		else if (source & ZPROP_SRC_RECEIVED)
+			source = ZPROP_SRC_LOCAL;
+	}
+
+	switch ((int)source) {
+	case ZPROP_SRC_NONE:
+		/* Revert to the received value, if any. */
+		err = zap_lookup(mos, zapobj, recvdstr, 8, 1, newvalp);
+		if (err == ENOENT)
+			*newvalp = 0;
+		break;
+	case ZPROP_SRC_LOCAL:
+		*newvalp = value;
+		break;
+	case ZPROP_SRC_RECEIVED:
+		/*
+		 * If there's no local setting, then the new received value will
+		 * be the effective value.
+		 */
+		err = zap_lookup(mos, zapobj, propname, 8, 1, newvalp);
+		if (err == ENOENT)
+			*newvalp = value;
+		break;
+	case (ZPROP_SRC_NONE | ZPROP_SRC_RECEIVED):
+		/*
+		 * We're clearing the received value, so the local setting (if
+		 * it exists) remains the effective value.
+		 */
+		err = zap_lookup(mos, zapobj, propname, 8, 1, newvalp);
+		if (err == ENOENT)
+			*newvalp = 0;
+		break;
+	default:
+		panic("unexpected property source: %d", source);
+	}
+
+	strfree(recvdstr);
+
+	if (err == ENOENT)
+		return (0);
+
+	return (err);
+}
+
+/*
+ * Unregister this callback.  Return 0 on success, ENOENT if ddname is
+ * invalid, or ENOMSG if no matching callback registered.
+ */
+int
+dsl_prop_unregister(dsl_dataset_t *ds, const char *propname,
+    dsl_prop_changed_cb_t *callback, void *cbarg)
+{
+	dsl_dir_t *dd = ds->ds_dir;
+	dsl_prop_cb_record_t *cbr;
+
+	mutex_enter(&dd->dd_lock);
+	for (cbr = list_head(&dd->dd_prop_cbs);
+	    cbr; cbr = list_next(&dd->dd_prop_cbs, cbr)) {
+		if (cbr->cbr_ds == ds &&
+		    cbr->cbr_func == callback &&
+		    cbr->cbr_arg == cbarg &&
+		    strcmp(cbr->cbr_propname, propname) == 0)
+			break;
+	}
+
+	if (cbr == NULL) {
+		mutex_exit(&dd->dd_lock);
+		return (SET_ERROR(ENOMSG));
+	}
+
+	list_remove(&dd->dd_prop_cbs, cbr);
+	mutex_exit(&dd->dd_lock);
+	kmem_free((void*)cbr->cbr_propname, strlen(cbr->cbr_propname)+1);
+	kmem_free(cbr, sizeof (dsl_prop_cb_record_t));
+
+	return (0);
+}
+
+boolean_t
+dsl_prop_hascb(dsl_dataset_t *ds)
+{
+	dsl_dir_t *dd = ds->ds_dir;
+	boolean_t rv = B_FALSE;
+	dsl_prop_cb_record_t *cbr;
+
+	mutex_enter(&dd->dd_lock);
+	for (cbr = list_head(&dd->dd_prop_cbs); cbr;
+	    cbr = list_next(&dd->dd_prop_cbs, cbr)) {
+		if (cbr->cbr_ds == ds) {
+			rv = B_TRUE;
+			break;
+		}
+	}
+	mutex_exit(&dd->dd_lock);
+	return (rv);
+}
+
+/* ARGSUSED */
+static int
+dsl_prop_notify_all_cb(dsl_pool_t *dp, dsl_dataset_t *ds, void *arg)
+{
+	dsl_dir_t *dd = ds->ds_dir;
+	dsl_prop_cb_record_t *cbr;
+
+	mutex_enter(&dd->dd_lock);
+	for (cbr = list_head(&dd->dd_prop_cbs); cbr;
+	    cbr = list_next(&dd->dd_prop_cbs, cbr)) {
+		uint64_t value;
+
+		/*
+		 * Callback entries do not have holds on their datasets
+		 * so that datasets with registered callbacks are still
+		 * eligible for eviction.  Unlike operations on callbacks
+		 * for a single dataset, we are performing a recursive
+		 * descent of related datasets and the calling context
+		 * for this iteration only has a dataset hold on the root.
+		 * Without a hold, the callback's pointer to the dataset
+		 * could be invalidated by eviction at any time.
+		 *
+		 * Use dsl_dataset_try_add_ref() to verify that the
+		 * dataset has not begun eviction processing and to
+		 * prevent eviction from occurring for the duration
+		 * of the callback.  If the hold attempt fails, this
+		 * object is already being evicted and the callback can
+		 * be safely ignored.
+		 */
+		if (!dsl_dataset_try_add_ref(dp, cbr->cbr_ds, FTAG))
+			continue;
+
+		if (dsl_prop_get_ds(cbr->cbr_ds, cbr->cbr_propname,
+		    sizeof (value), 1, &value, NULL) == 0)
+			cbr->cbr_func(cbr->cbr_arg, value);
+
+		dsl_dataset_rele(cbr->cbr_ds, FTAG);
+	}
+	mutex_exit(&dd->dd_lock);
+
+	return (0);
+}
+
+/*
+ * Update all property values for ddobj & its descendants.  This is used
+ * when renaming the dir.
+ */
+void
+dsl_prop_notify_all(dsl_dir_t *dd)
+{
+	dsl_pool_t *dp = dd->dd_pool;
+	ASSERT(RRW_WRITE_HELD(&dp->dp_config_rwlock));
+	(void) dmu_objset_find_dp(dp, dd->dd_object, dsl_prop_notify_all_cb,
+	    NULL, DS_FIND_CHILDREN);
+}
+
+static void
+dsl_prop_changed_notify(dsl_pool_t *dp, uint64_t ddobj,
+    const char *propname, uint64_t value, int first)
+{
+	dsl_dir_t *dd;
+	dsl_prop_cb_record_t *cbr;
+	objset_t *mos = dp->dp_meta_objset;
+	zap_cursor_t zc;
+	zap_attribute_t *za;
+	int err;
+
+	ASSERT(RRW_WRITE_HELD(&dp->dp_config_rwlock));
+	err = dsl_dir_hold_obj(dp, ddobj, NULL, FTAG, &dd);
+	if (err)
+		return;
+
+	if (!first) {
+		/*
+		 * If the prop is set here, then this change is not
+		 * being inherited here or below; stop the recursion.
+		 */
+		err = zap_contains(mos, dsl_dir_phys(dd)->dd_props_zapobj,
+		    propname);
+		if (err == 0) {
+			dsl_dir_rele(dd, FTAG);
+			return;
+		}
+		ASSERT3U(err, ==, ENOENT);
+	}
+
+	mutex_enter(&dd->dd_lock);
+	for (cbr = list_head(&dd->dd_prop_cbs); cbr;
+	    cbr = list_next(&dd->dd_prop_cbs, cbr)) {
+		uint64_t propobj;
+
+		/*
+		 * cbr->cbf_ds may be invalidated due to eviction,
+		 * requiring the use of dsl_dataset_try_add_ref().
+		 * See comment block in dsl_prop_notify_all_cb()
+		 * for details.
+		 */
+		if (strcmp(cbr->cbr_propname, propname) != 0 ||
+		    !dsl_dataset_try_add_ref(dp, cbr->cbr_ds, FTAG))
+			continue;
+
+		propobj = dsl_dataset_phys(cbr->cbr_ds)->ds_props_obj;
+
+		/*
+		 * If the property is not set on this ds, then it is
+		 * inherited here; call the callback.
+		 */
+		if (propobj == 0 || zap_contains(mos, propobj, propname) != 0)
+			cbr->cbr_func(cbr->cbr_arg, value);
+
+		dsl_dataset_rele(cbr->cbr_ds, FTAG);
+	}
+	mutex_exit(&dd->dd_lock);
+
+	za = kmem_alloc(sizeof (zap_attribute_t), KM_SLEEP);
+	for (zap_cursor_init(&zc, mos,
+	    dsl_dir_phys(dd)->dd_child_dir_zapobj);
+	    zap_cursor_retrieve(&zc, za) == 0;
+	    zap_cursor_advance(&zc)) {
+		dsl_prop_changed_notify(dp, za->za_first_integer,
+		    propname, value, FALSE);
+	}
+	kmem_free(za, sizeof (zap_attribute_t));
+	zap_cursor_fini(&zc);
+	dsl_dir_rele(dd, FTAG);
+}
+
+void
+dsl_prop_set_sync_impl(dsl_dataset_t *ds, const char *propname,
+    zprop_source_t source, int intsz, int numints, const void *value,
+    dmu_tx_t *tx)
+{
+	objset_t *mos = ds->ds_dir->dd_pool->dp_meta_objset;
+	uint64_t zapobj, intval, dummy;
+	int isint;
+	char valbuf[32];
+	const char *valstr = NULL;
+	char *inheritstr;
+	char *recvdstr;
+	char *tbuf = NULL;
+	int err;
+	uint64_t version = spa_version(ds->ds_dir->dd_pool->dp_spa);
+
+	isint = (dodefault(propname, 8, 1, &intval) == 0);
+
+	if (ds->ds_is_snapshot) {
+		ASSERT(version >= SPA_VERSION_SNAP_PROPS);
+		if (dsl_dataset_phys(ds)->ds_props_obj == 0) {
+			dmu_buf_will_dirty(ds->ds_dbuf, tx);
+			dsl_dataset_phys(ds)->ds_props_obj =
+			    zap_create(mos,
+			    DMU_OT_DSL_PROPS, DMU_OT_NONE, 0, tx);
+		}
+		zapobj = dsl_dataset_phys(ds)->ds_props_obj;
+	} else {
+		zapobj = dsl_dir_phys(ds->ds_dir)->dd_props_zapobj;
+	}
+
+	if (version < SPA_VERSION_RECVD_PROPS) {
+		if (source & ZPROP_SRC_NONE)
+			source = ZPROP_SRC_NONE;
+		else if (source & ZPROP_SRC_RECEIVED)
+			source = ZPROP_SRC_LOCAL;
+	}
+
+	inheritstr = kmem_asprintf("%s%s", propname, ZPROP_INHERIT_SUFFIX);
+	recvdstr = kmem_asprintf("%s%s", propname, ZPROP_RECVD_SUFFIX);
+
+	switch ((int)source) {
+	case ZPROP_SRC_NONE:
+		/*
+		 * revert to received value, if any (inherit -S)
+		 * - remove propname
+		 * - remove propname$inherit
+		 */
+		err = zap_remove(mos, zapobj, propname, tx);
+		ASSERT(err == 0 || err == ENOENT);
+		err = zap_remove(mos, zapobj, inheritstr, tx);
+		ASSERT(err == 0 || err == ENOENT);
+		break;
+	case ZPROP_SRC_LOCAL:
+		/*
+		 * remove propname$inherit
+		 * set propname -> value
+		 */
+		err = zap_remove(mos, zapobj, inheritstr, tx);
+		ASSERT(err == 0 || err == ENOENT);
+		VERIFY0(zap_update(mos, zapobj, propname,
+		    intsz, numints, value, tx));
+		break;
+	case ZPROP_SRC_INHERITED:
+		/*
+		 * explicitly inherit
+		 * - remove propname
+		 * - set propname$inherit
+		 */
+		err = zap_remove(mos, zapobj, propname, tx);
+		ASSERT(err == 0 || err == ENOENT);
+		if (version >= SPA_VERSION_RECVD_PROPS &&
+		    dsl_prop_get_int_ds(ds, ZPROP_HAS_RECVD, &dummy) == 0) {
+			dummy = 0;
+			VERIFY0(zap_update(mos, zapobj, inheritstr,
+			    8, 1, &dummy, tx));
+		}
+		break;
+	case ZPROP_SRC_RECEIVED:
+		/*
+		 * set propname$recvd -> value
+		 */
+		err = zap_update(mos, zapobj, recvdstr,
+		    intsz, numints, value, tx);
+		ASSERT(err == 0);
+		break;
+	case (ZPROP_SRC_NONE | ZPROP_SRC_LOCAL | ZPROP_SRC_RECEIVED):
+		/*
+		 * clear local and received settings
+		 * - remove propname
+		 * - remove propname$inherit
+		 * - remove propname$recvd
+		 */
+		err = zap_remove(mos, zapobj, propname, tx);
+		ASSERT(err == 0 || err == ENOENT);
+		err = zap_remove(mos, zapobj, inheritstr, tx);
+		ASSERT(err == 0 || err == ENOENT);
+		/* FALLTHRU */
+	case (ZPROP_SRC_NONE | ZPROP_SRC_RECEIVED):
+		/*
+		 * remove propname$recvd
+		 */
+		err = zap_remove(mos, zapobj, recvdstr, tx);
+		ASSERT(err == 0 || err == ENOENT);
+		break;
+	default:
+		cmn_err(CE_PANIC, "unexpected property source: %d", source);
+	}
+
+	strfree(inheritstr);
+	strfree(recvdstr);
+
+	if (isint) {
+		VERIFY0(dsl_prop_get_int_ds(ds, propname, &intval));
+
+		if (ds->ds_is_snapshot) {
+			dsl_prop_cb_record_t *cbr;
+			/*
+			 * It's a snapshot; nothing can inherit this
+			 * property, so just look for callbacks on this
+			 * ds here.
+			 */
+			mutex_enter(&ds->ds_dir->dd_lock);
+			for (cbr = list_head(&ds->ds_dir->dd_prop_cbs); cbr;
+			    cbr = list_next(&ds->ds_dir->dd_prop_cbs, cbr)) {
+				if (cbr->cbr_ds == ds &&
+				    strcmp(cbr->cbr_propname, propname) == 0)
+					cbr->cbr_func(cbr->cbr_arg, intval);
+			}
+			mutex_exit(&ds->ds_dir->dd_lock);
+		} else {
+			dsl_prop_changed_notify(ds->ds_dir->dd_pool,
+			    ds->ds_dir->dd_object, propname, intval, TRUE);
+		}
+
+		(void) snprintf(valbuf, sizeof (valbuf),
+		    "%lld", (longlong_t)intval);
+		valstr = valbuf;
+	} else {
+		if (source == ZPROP_SRC_LOCAL) {
+			valstr = value;
+		} else {
+			tbuf = kmem_alloc(ZAP_MAXVALUELEN, KM_SLEEP);
+			if (dsl_prop_get_ds(ds, propname, 1,
+			    ZAP_MAXVALUELEN, tbuf, NULL) == 0)
+				valstr = tbuf;
+		}
+	}
+
+	spa_history_log_internal_ds(ds, (source == ZPROP_SRC_NONE ||
+	    source == ZPROP_SRC_INHERITED) ? "inherit" : "set", tx,
+	    "%s=%s", propname, (valstr == NULL ? "" : valstr));
+
+	if (tbuf != NULL)
+		kmem_free(tbuf, ZAP_MAXVALUELEN);
+}
+
+int
+dsl_prop_set_int(const char *dsname, const char *propname,
+    zprop_source_t source, uint64_t value)
+{
+	nvlist_t *nvl = fnvlist_alloc();
+	int error;
+
+	fnvlist_add_uint64(nvl, propname, value);
+	error = dsl_props_set(dsname, source, nvl);
+	fnvlist_free(nvl);
+	return (error);
+}
+
+int
+dsl_prop_set_string(const char *dsname, const char *propname,
+    zprop_source_t source, const char *value)
+{
+	nvlist_t *nvl = fnvlist_alloc();
+	int error;
+
+	fnvlist_add_string(nvl, propname, value);
+	error = dsl_props_set(dsname, source, nvl);
+	fnvlist_free(nvl);
+	return (error);
+}
+
+int
+dsl_prop_inherit(const char *dsname, const char *propname,
+    zprop_source_t source)
+{
+	nvlist_t *nvl = fnvlist_alloc();
+	int error;
+
+	fnvlist_add_boolean(nvl, propname);
+	error = dsl_props_set(dsname, source, nvl);
+	fnvlist_free(nvl);
+	return (error);
+}
+
+typedef struct dsl_props_set_arg {
+	const char *dpsa_dsname;
+	zprop_source_t dpsa_source;
+	nvlist_t *dpsa_props;
+} dsl_props_set_arg_t;
+
+static int
+dsl_props_set_check(void *arg, dmu_tx_t *tx)
+{
+	dsl_props_set_arg_t *dpsa = arg;
+	dsl_pool_t *dp = dmu_tx_pool(tx);
+	dsl_dataset_t *ds;
+	uint64_t version;
+	nvpair_t *elem = NULL;
+	int err;
+
+	err = dsl_dataset_hold(dp, dpsa->dpsa_dsname, FTAG, &ds);
+	if (err != 0)
+		return (err);
+
+	version = spa_version(ds->ds_dir->dd_pool->dp_spa);
+	while ((elem = nvlist_next_nvpair(dpsa->dpsa_props, elem)) != NULL) {
+		if (strlen(nvpair_name(elem)) >= ZAP_MAXNAMELEN) {
+			dsl_dataset_rele(ds, FTAG);
+			return (SET_ERROR(ENAMETOOLONG));
+		}
+		if (nvpair_type(elem) == DATA_TYPE_STRING) {
+			char *valstr = fnvpair_value_string(elem);
+			if (strlen(valstr) >= (version <
+			    SPA_VERSION_STMF_PROP ?
+			    ZAP_OLDMAXVALUELEN : ZAP_MAXVALUELEN)) {
+				dsl_dataset_rele(ds, FTAG);
+				return (E2BIG);
+			}
+		}
+	}
+
+	if (ds->ds_is_snapshot && version < SPA_VERSION_SNAP_PROPS) {
+		dsl_dataset_rele(ds, FTAG);
+		return (SET_ERROR(ENOTSUP));
+	}
+	dsl_dataset_rele(ds, FTAG);
+	return (0);
+}
+
+void
+dsl_props_set_sync_impl(dsl_dataset_t *ds, zprop_source_t source,
+    nvlist_t *props, dmu_tx_t *tx)
+{
+	nvpair_t *elem = NULL;
+
+	while ((elem = nvlist_next_nvpair(props, elem)) != NULL) {
+		nvpair_t *pair = elem;
+
+		if (nvpair_type(pair) == DATA_TYPE_NVLIST) {
+			/*
+			 * dsl_prop_get_all_impl() returns properties in this
+			 * format.
+			 */
+			nvlist_t *attrs = fnvpair_value_nvlist(pair);
+			pair = fnvlist_lookup_nvpair(attrs, ZPROP_VALUE);
+		}
+
+		if (nvpair_type(pair) == DATA_TYPE_STRING) {
+			const char *value = fnvpair_value_string(pair);
+			dsl_prop_set_sync_impl(ds, nvpair_name(pair),
+			    source, 1, strlen(value) + 1, value, tx);
+		} else if (nvpair_type(pair) == DATA_TYPE_UINT64) {
+			uint64_t intval = fnvpair_value_uint64(pair);
+			dsl_prop_set_sync_impl(ds, nvpair_name(pair),
+			    source, sizeof (intval), 1, &intval, tx);
+		} else if (nvpair_type(pair) == DATA_TYPE_BOOLEAN) {
+			dsl_prop_set_sync_impl(ds, nvpair_name(pair),
+			    source, 0, 0, NULL, tx);
+		} else {
+			panic("invalid nvpair type");
+		}
+	}
+}
+
+static void
+dsl_props_set_sync(void *arg, dmu_tx_t *tx)
+{
+	dsl_props_set_arg_t *dpsa = arg;
+	dsl_pool_t *dp = dmu_tx_pool(tx);
+	dsl_dataset_t *ds;
+
+	VERIFY0(dsl_dataset_hold(dp, dpsa->dpsa_dsname, FTAG, &ds));
+	dsl_props_set_sync_impl(ds, dpsa->dpsa_source, dpsa->dpsa_props, tx);
+	dsl_dataset_rele(ds, FTAG);
+}
+
+/*
+ * All-or-nothing; if any prop can't be set, nothing will be modified.
+ */
+int
+dsl_props_set(const char *dsname, zprop_source_t source, nvlist_t *props)
+{
+	dsl_props_set_arg_t dpsa;
+	int nblks = 0;
+
+	dpsa.dpsa_dsname = dsname;
+	dpsa.dpsa_source = source;
+	dpsa.dpsa_props = props;
+
+	/*
+	 * If the source includes NONE, then we will only be removing entries
+	 * from the ZAP object.  In that case don't check for ENOSPC.
+	 */
+	if ((source & ZPROP_SRC_NONE) == 0)
+		nblks = 2 * fnvlist_num_pairs(props);
+
+	return (dsl_sync_task(dsname, dsl_props_set_check, dsl_props_set_sync,
+	    &dpsa, nblks, ZFS_SPACE_CHECK_RESERVED));
+}
+
+typedef enum dsl_prop_getflags {
+	DSL_PROP_GET_INHERITING = 0x1,	/* searching parent of target ds */
+	DSL_PROP_GET_SNAPSHOT = 0x2,	/* snapshot dataset */
+	DSL_PROP_GET_LOCAL = 0x4,	/* local properties */
+	DSL_PROP_GET_RECEIVED = 0x8	/* received properties */
+} dsl_prop_getflags_t;
+
+static int
+dsl_prop_get_all_impl(objset_t *mos, uint64_t propobj,
+    const char *setpoint, dsl_prop_getflags_t flags, nvlist_t *nv)
+{
+	zap_cursor_t zc;
+	zap_attribute_t za;
+	int err = 0;
+
+	for (zap_cursor_init(&zc, mos, propobj);
+	    (err = zap_cursor_retrieve(&zc, &za)) == 0;
+	    zap_cursor_advance(&zc)) {
+		nvlist_t *propval;
+		zfs_prop_t prop;
+		char buf[ZAP_MAXNAMELEN];
+		char *valstr;
+		const char *suffix;
+		const char *propname;
+		const char *source;
+
+		suffix = strchr(za.za_name, '$');
+
+		if (suffix == NULL) {
+			/*
+			 * Skip local properties if we only want received
+			 * properties.
+			 */
+			if (flags & DSL_PROP_GET_RECEIVED)
+				continue;
+
+			propname = za.za_name;
+			source = setpoint;
+		} else if (strcmp(suffix, ZPROP_INHERIT_SUFFIX) == 0) {
+			/* Skip explicitly inherited entries. */
+			continue;
+		} else if (strcmp(suffix, ZPROP_RECVD_SUFFIX) == 0) {
+			if (flags & DSL_PROP_GET_LOCAL)
+				continue;
+
+			(void) strncpy(buf, za.za_name, (suffix - za.za_name));
+			buf[suffix - za.za_name] = '\0';
+			propname = buf;
+
+			if (!(flags & DSL_PROP_GET_RECEIVED)) {
+				/* Skip if locally overridden. */
+				err = zap_contains(mos, propobj, propname);
+				if (err == 0)
+					continue;
+				if (err != ENOENT)
+					break;
+
+				/* Skip if explicitly inherited. */
+				valstr = kmem_asprintf("%s%s", propname,
+				    ZPROP_INHERIT_SUFFIX);
+				err = zap_contains(mos, propobj, valstr);
+				strfree(valstr);
+				if (err == 0)
+					continue;
+				if (err != ENOENT)
+					break;
+			}
+
+			source = ((flags & DSL_PROP_GET_INHERITING) ?
+			    setpoint : ZPROP_SOURCE_VAL_RECVD);
+		} else {
+			/*
+			 * For backward compatibility, skip suffixes we don't
+			 * recognize.
+			 */
+			continue;
+		}
+
+		prop = zfs_name_to_prop(propname);
+
+		/* Skip non-inheritable properties. */
+		if ((flags & DSL_PROP_GET_INHERITING) && prop != ZPROP_INVAL &&
+		    !zfs_prop_inheritable(prop))
+			continue;
+
+		/* Skip properties not valid for this type. */
+		if ((flags & DSL_PROP_GET_SNAPSHOT) && prop != ZPROP_INVAL &&
+		    !zfs_prop_valid_for_type(prop, ZFS_TYPE_SNAPSHOT, B_FALSE))
+			continue;
+
+		/* Skip properties already defined. */
+		if (nvlist_exists(nv, propname))
+			continue;
+
+		VERIFY(nvlist_alloc(&propval, NV_UNIQUE_NAME, KM_SLEEP) == 0);
+		if (za.za_integer_length == 1) {
+			/*
+			 * String property
+			 */
+			char *tmp = kmem_alloc(za.za_num_integers,
+			    KM_SLEEP);
+			err = zap_lookup(mos, propobj,
+			    za.za_name, 1, za.za_num_integers, tmp);
+			if (err != 0) {
+				kmem_free(tmp, za.za_num_integers);
+				break;
+			}
+			VERIFY(nvlist_add_string(propval, ZPROP_VALUE,
+			    tmp) == 0);
+			kmem_free(tmp, za.za_num_integers);
+		} else {
+			/*
+			 * Integer property
+			 */
+			ASSERT(za.za_integer_length == 8);
+			(void) nvlist_add_uint64(propval, ZPROP_VALUE,
+			    za.za_first_integer);
+		}
+
+		VERIFY(nvlist_add_string(propval, ZPROP_SOURCE, source) == 0);
+		VERIFY(nvlist_add_nvlist(nv, propname, propval) == 0);
+		nvlist_free(propval);
+	}
+	zap_cursor_fini(&zc);
+	if (err == ENOENT)
+		err = 0;
+	return (err);
+}
+
+/*
+ * Iterate over all properties for this dataset and return them in an nvlist.
+ */
+static int
+dsl_prop_get_all_ds(dsl_dataset_t *ds, nvlist_t **nvp,
+    dsl_prop_getflags_t flags)
+{
+	dsl_dir_t *dd = ds->ds_dir;
+	dsl_pool_t *dp = dd->dd_pool;
+	objset_t *mos = dp->dp_meta_objset;
+	int err = 0;
+	char setpoint[MAXNAMELEN];
+
+	VERIFY(nvlist_alloc(nvp, NV_UNIQUE_NAME, KM_SLEEP) == 0);
+
+	if (ds->ds_is_snapshot)
+		flags |= DSL_PROP_GET_SNAPSHOT;
+
+	ASSERT(dsl_pool_config_held(dp));
+
+	if (dsl_dataset_phys(ds)->ds_props_obj != 0) {
+		ASSERT(flags & DSL_PROP_GET_SNAPSHOT);
+		dsl_dataset_name(ds, setpoint);
+		err = dsl_prop_get_all_impl(mos,
+		    dsl_dataset_phys(ds)->ds_props_obj, setpoint, flags, *nvp);
+		if (err)
+			goto out;
+	}
+
+	for (; dd != NULL; dd = dd->dd_parent) {
+		if (dd != ds->ds_dir || (flags & DSL_PROP_GET_SNAPSHOT)) {
+			if (flags & (DSL_PROP_GET_LOCAL |
+			    DSL_PROP_GET_RECEIVED))
+				break;
+			flags |= DSL_PROP_GET_INHERITING;
+		}
+		dsl_dir_name(dd, setpoint);
+		err = dsl_prop_get_all_impl(mos,
+		    dsl_dir_phys(dd)->dd_props_zapobj, setpoint, flags, *nvp);
+		if (err)
+			break;
+	}
+out:
+	return (err);
+}
+
+boolean_t
+dsl_prop_get_hasrecvd(const char *dsname)
+{
+	uint64_t dummy;
+
+	return (0 ==
+	    dsl_prop_get_integer(dsname, ZPROP_HAS_RECVD, &dummy, NULL));
+}
+
+static int
+dsl_prop_set_hasrecvd_impl(const char *dsname, zprop_source_t source)
+{
+	uint64_t version;
+	spa_t *spa;
+	int error = 0;
+
+	VERIFY0(spa_open(dsname, &spa, FTAG));
+	version = spa_version(spa);
+	spa_close(spa, FTAG);
+
+	if (version >= SPA_VERSION_RECVD_PROPS)
+		error = dsl_prop_set_int(dsname, ZPROP_HAS_RECVD, source, 0);
+	return (error);
+}
+
+/*
+ * Call after successfully receiving properties to ensure that only the first
+ * receive on or after SPA_VERSION_RECVD_PROPS blows away local properties.
+ */
+int
+dsl_prop_set_hasrecvd(const char *dsname)
+{
+	int error = 0;
+	if (!dsl_prop_get_hasrecvd(dsname))
+		error = dsl_prop_set_hasrecvd_impl(dsname, ZPROP_SRC_LOCAL);
+	return (error);
+}
+
+void
+dsl_prop_unset_hasrecvd(const char *dsname)
+{
+	VERIFY0(dsl_prop_set_hasrecvd_impl(dsname, ZPROP_SRC_NONE));
+}
+
+int
+dsl_prop_get_all(objset_t *os, nvlist_t **nvp)
+{
+	return (dsl_prop_get_all_ds(os->os_dsl_dataset, nvp, 0));
+}
+
+int
+dsl_prop_get_received(const char *dsname, nvlist_t **nvp)
+{
+	objset_t *os;
+	int error;
+
+	/*
+	 * Received properties are not distinguishable from local properties
+	 * until the dataset has received properties on or after
+	 * SPA_VERSION_RECVD_PROPS.
+	 */
+	dsl_prop_getflags_t flags = (dsl_prop_get_hasrecvd(dsname) ?
+	    DSL_PROP_GET_RECEIVED : DSL_PROP_GET_LOCAL);
+
+	error = dmu_objset_hold(dsname, FTAG, &os);
+	if (error != 0)
+		return (error);
+	error = dsl_prop_get_all_ds(os->os_dsl_dataset, nvp, flags);
+	dmu_objset_rele(os, FTAG);
+	return (error);
+}
+
+void
+dsl_prop_nvlist_add_uint64(nvlist_t *nv, zfs_prop_t prop, uint64_t value)
+{
+	nvlist_t *propval;
+	const char *propname = zfs_prop_to_name(prop);
+	uint64_t default_value;
+
+	if (nvlist_lookup_nvlist(nv, propname, &propval) == 0) {
+		VERIFY(nvlist_add_uint64(propval, ZPROP_VALUE, value) == 0);
+		return;
+	}
+
+	VERIFY(nvlist_alloc(&propval, NV_UNIQUE_NAME, KM_SLEEP) == 0);
+	VERIFY(nvlist_add_uint64(propval, ZPROP_VALUE, value) == 0);
+	/* Indicate the default source if we can. */
+	if (dodefault(propname, 8, 1, &default_value) == 0 &&
+	    value == default_value) {
+		VERIFY(nvlist_add_string(propval, ZPROP_SOURCE, "") == 0);
+	}
+	VERIFY(nvlist_add_nvlist(nv, propname, propval) == 0);
+	nvlist_free(propval);
+}
+
+void
+dsl_prop_nvlist_add_string(nvlist_t *nv, zfs_prop_t prop, const char *value)
+{
+	nvlist_t *propval;
+	const char *propname = zfs_prop_to_name(prop);
+
+	if (nvlist_lookup_nvlist(nv, propname, &propval) == 0) {
+		VERIFY(nvlist_add_string(propval, ZPROP_VALUE, value) == 0);
+		return;
+	}
+
+	VERIFY(nvlist_alloc(&propval, NV_UNIQUE_NAME, KM_SLEEP) == 0);
+	VERIFY(nvlist_add_string(propval, ZPROP_VALUE, value) == 0);
+	VERIFY(nvlist_add_nvlist(nv, propname, propval) == 0);
+	nvlist_free(propval);
+}
+
+#if defined(_KERNEL) && defined(HAVE_SPL)
+EXPORT_SYMBOL(dsl_prop_register);
+EXPORT_SYMBOL(dsl_prop_unregister);
+EXPORT_SYMBOL(dsl_prop_get);
+EXPORT_SYMBOL(dsl_prop_get_integer);
+EXPORT_SYMBOL(dsl_prop_get_all);
+EXPORT_SYMBOL(dsl_prop_get_received);
+EXPORT_SYMBOL(dsl_prop_get_ds);
+EXPORT_SYMBOL(dsl_prop_get_int_ds);
+EXPORT_SYMBOL(dsl_prop_get_dd);
+EXPORT_SYMBOL(dsl_props_set);
+EXPORT_SYMBOL(dsl_prop_set_int);
+EXPORT_SYMBOL(dsl_prop_set_string);
+EXPORT_SYMBOL(dsl_prop_inherit);
+EXPORT_SYMBOL(dsl_prop_predict);
+EXPORT_SYMBOL(dsl_prop_nvlist_add_uint64);
+EXPORT_SYMBOL(dsl_prop_nvlist_add_string);
+#endif
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/module/zfs/dsl_scan.c
@@ -0,0 +1,1907 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2014 by Delphix. All rights reserved.
+ */
+
+#include <sys/dsl_scan.h>
+#include <sys/dsl_pool.h>
+#include <sys/dsl_dataset.h>
+#include <sys/dsl_prop.h>
+#include <sys/dsl_dir.h>
+#include <sys/dsl_synctask.h>
+#include <sys/dnode.h>
+#include <sys/dmu_tx.h>
+#include <sys/dmu_objset.h>
+#include <sys/arc.h>
+#include <sys/zap.h>
+#include <sys/zio.h>
+#include <sys/zfs_context.h>
+#include <sys/fs/zfs.h>
+#include <sys/zfs_znode.h>
+#include <sys/spa_impl.h>
+#include <sys/vdev_impl.h>
+#include <sys/zil_impl.h>
+#include <sys/zio_checksum.h>
+#include <sys/ddt.h>
+#include <sys/sa.h>
+#include <sys/sa_impl.h>
+#include <sys/zfeature.h>
+#ifdef _KERNEL
+#include <sys/zfs_vfsops.h>
+#endif
+
+typedef int (scan_cb_t)(dsl_pool_t *, const blkptr_t *,
+    const zbookmark_phys_t *);
+
+static scan_cb_t dsl_scan_scrub_cb;
+static void dsl_scan_cancel_sync(void *, dmu_tx_t *);
+static void dsl_scan_sync_state(dsl_scan_t *, dmu_tx_t *tx);
+
+int zfs_top_maxinflight = 32;		/* maximum I/Os per top-level */
+int zfs_resilver_delay = 2;		/* number of ticks to delay resilver */
+int zfs_scrub_delay = 4;		/* number of ticks to delay scrub */
+int zfs_scan_idle = 50;			/* idle window in clock ticks */
+
+int zfs_scan_min_time_ms = 1000; /* min millisecs to scrub per txg */
+int zfs_free_min_time_ms = 1000; /* min millisecs to free per txg */
+int zfs_resilver_min_time_ms = 3000; /* min millisecs to resilver per txg */
+int zfs_no_scrub_io = B_FALSE; /* set to disable scrub i/o */
+int zfs_no_scrub_prefetch = B_FALSE; /* set to disable scrub prefetch */
+enum ddt_class zfs_scrub_ddt_class_max = DDT_CLASS_DUPLICATE;
+int dsl_scan_delay_completion = B_FALSE; /* set to delay scan completion */
+/* max number of blocks to free in a single TXG */
+ulong zfs_free_max_blocks = 100000;
+
+#define	DSL_SCAN_IS_SCRUB_RESILVER(scn) \
+	((scn)->scn_phys.scn_func == POOL_SCAN_SCRUB || \
+	(scn)->scn_phys.scn_func == POOL_SCAN_RESILVER)
+
+/* the order has to match pool_scan_type */
+static scan_cb_t *scan_funcs[POOL_SCAN_FUNCS] = {
+	NULL,
+	dsl_scan_scrub_cb,	/* POOL_SCAN_SCRUB */
+	dsl_scan_scrub_cb,	/* POOL_SCAN_RESILVER */
+};
+
+int
+dsl_scan_init(dsl_pool_t *dp, uint64_t txg)
+{
+	int err;
+	dsl_scan_t *scn;
+	spa_t *spa = dp->dp_spa;
+	uint64_t f;
+
+	scn = dp->dp_scan = kmem_zalloc(sizeof (dsl_scan_t), KM_SLEEP);
+	scn->scn_dp = dp;
+
+	/*
+	 * It's possible that we're resuming a scan after a reboot so
+	 * make sure that the scan_async_destroying flag is initialized
+	 * appropriately.
+	 */
+	ASSERT(!scn->scn_async_destroying);
+	scn->scn_async_destroying = spa_feature_is_active(dp->dp_spa,
+	    SPA_FEATURE_ASYNC_DESTROY);
+
+	err = zap_lookup(dp->dp_meta_objset, DMU_POOL_DIRECTORY_OBJECT,
+	    "scrub_func", sizeof (uint64_t), 1, &f);
+	if (err == 0) {
+		/*
+		 * There was an old-style scrub in progress.  Restart a
+		 * new-style scrub from the beginning.
+		 */
+		scn->scn_restart_txg = txg;
+		zfs_dbgmsg("old-style scrub was in progress; "
+		    "restarting new-style scrub in txg %llu",
+		    scn->scn_restart_txg);
+
+		/*
+		 * Load the queue obj from the old location so that it
+		 * can be freed by dsl_scan_done().
+		 */
+		(void) zap_lookup(dp->dp_meta_objset, DMU_POOL_DIRECTORY_OBJECT,
+		    "scrub_queue", sizeof (uint64_t), 1,
+		    &scn->scn_phys.scn_queue_obj);
+	} else {
+		err = zap_lookup(dp->dp_meta_objset, DMU_POOL_DIRECTORY_OBJECT,
+		    DMU_POOL_SCAN, sizeof (uint64_t), SCAN_PHYS_NUMINTS,
+		    &scn->scn_phys);
+		/*
+		 * Detect if the pool contains the signature of #2094.  If it
+		 * does properly update the scn->scn_phys structure and notify
+		 * the administrator by setting an errata for the pool.
+		 */
+		if (err == EOVERFLOW) {
+			uint64_t zaptmp[SCAN_PHYS_NUMINTS + 1];
+			VERIFY3S(SCAN_PHYS_NUMINTS, ==, 24);
+			VERIFY3S(offsetof(dsl_scan_phys_t, scn_flags), ==,
+			    (23 * sizeof (uint64_t)));
+
+			err = zap_lookup(dp->dp_meta_objset,
+			    DMU_POOL_DIRECTORY_OBJECT, DMU_POOL_SCAN,
+			    sizeof (uint64_t), SCAN_PHYS_NUMINTS + 1, &zaptmp);
+			if (err == 0) {
+				uint64_t overflow = zaptmp[SCAN_PHYS_NUMINTS];
+
+				if (overflow & ~DSL_SCAN_FLAGS_MASK ||
+				    scn->scn_async_destroying) {
+					spa->spa_errata =
+					    ZPOOL_ERRATA_ZOL_2094_ASYNC_DESTROY;
+					return (EOVERFLOW);
+				}
+
+				bcopy(zaptmp, &scn->scn_phys,
+				    SCAN_PHYS_NUMINTS * sizeof (uint64_t));
+				scn->scn_phys.scn_flags = overflow;
+
+				/* Required scrub already in progress. */
+				if (scn->scn_phys.scn_state == DSS_FINISHED ||
+				    scn->scn_phys.scn_state == DSS_CANCELED)
+					spa->spa_errata =
+					    ZPOOL_ERRATA_ZOL_2094_SCRUB;
+			}
+		}
+
+		if (err == ENOENT)
+			return (0);
+		else if (err)
+			return (err);
+
+		if (scn->scn_phys.scn_state == DSS_SCANNING &&
+		    spa_prev_software_version(dp->dp_spa) < SPA_VERSION_SCAN) {
+			/*
+			 * A new-type scrub was in progress on an old
+			 * pool, and the pool was accessed by old
+			 * software.  Restart from the beginning, since
+			 * the old software may have changed the pool in
+			 * the meantime.
+			 */
+			scn->scn_restart_txg = txg;
+			zfs_dbgmsg("new-style scrub was modified "
+			    "by old software; restarting in txg %llu",
+			    scn->scn_restart_txg);
+		}
+	}
+
+	spa_scan_stat_init(spa);
+	return (0);
+}
+
+void
+dsl_scan_fini(dsl_pool_t *dp)
+{
+	if (dp->dp_scan) {
+		kmem_free(dp->dp_scan, sizeof (dsl_scan_t));
+		dp->dp_scan = NULL;
+	}
+}
+
+/* ARGSUSED */
+static int
+dsl_scan_setup_check(void *arg, dmu_tx_t *tx)
+{
+	dsl_scan_t *scn = dmu_tx_pool(tx)->dp_scan;
+
+	if (scn->scn_phys.scn_state == DSS_SCANNING)
+		return (SET_ERROR(EBUSY));
+
+	return (0);
+}
+
+static void
+dsl_scan_setup_sync(void *arg, dmu_tx_t *tx)
+{
+	dsl_scan_t *scn = dmu_tx_pool(tx)->dp_scan;
+	pool_scan_func_t *funcp = arg;
+	dmu_object_type_t ot = 0;
+	dsl_pool_t *dp = scn->scn_dp;
+	spa_t *spa = dp->dp_spa;
+
+	ASSERT(scn->scn_phys.scn_state != DSS_SCANNING);
+	ASSERT(*funcp > POOL_SCAN_NONE && *funcp < POOL_SCAN_FUNCS);
+	bzero(&scn->scn_phys, sizeof (scn->scn_phys));
+	scn->scn_phys.scn_func = *funcp;
+	scn->scn_phys.scn_state = DSS_SCANNING;
+	scn->scn_phys.scn_min_txg = 0;
+	scn->scn_phys.scn_max_txg = tx->tx_txg;
+	scn->scn_phys.scn_ddt_class_max = DDT_CLASSES - 1; /* the entire DDT */
+	scn->scn_phys.scn_start_time = gethrestime_sec();
+	scn->scn_phys.scn_errors = 0;
+	scn->scn_phys.scn_to_examine = spa->spa_root_vdev->vdev_stat.vs_alloc;
+	scn->scn_restart_txg = 0;
+	scn->scn_done_txg = 0;
+	spa_scan_stat_init(spa);
+
+	if (DSL_SCAN_IS_SCRUB_RESILVER(scn)) {
+		scn->scn_phys.scn_ddt_class_max = zfs_scrub_ddt_class_max;
+
+		/* rewrite all disk labels */
+		vdev_config_dirty(spa->spa_root_vdev);
+
+		if (vdev_resilver_needed(spa->spa_root_vdev,
+		    &scn->scn_phys.scn_min_txg, &scn->scn_phys.scn_max_txg)) {
+			spa_event_notify(spa, NULL,
+			    FM_EREPORT_ZFS_RESILVER_START);
+		} else {
+			spa_event_notify(spa, NULL,
+			    FM_EREPORT_ZFS_SCRUB_START);
+		}
+
+		spa->spa_scrub_started = B_TRUE;
+		/*
+		 * If this is an incremental scrub, limit the DDT scrub phase
+		 * to just the auto-ditto class (for correctness); the rest
+		 * of the scrub should go faster using top-down pruning.
+		 */
+		if (scn->scn_phys.scn_min_txg > TXG_INITIAL)
+			scn->scn_phys.scn_ddt_class_max = DDT_CLASS_DITTO;
+
+	}
+
+	/* back to the generic stuff */
+
+	if (dp->dp_blkstats == NULL) {
+		dp->dp_blkstats =
+		    vmem_alloc(sizeof (zfs_all_blkstats_t), KM_SLEEP);
+	}
+	bzero(dp->dp_blkstats, sizeof (zfs_all_blkstats_t));
+
+	if (spa_version(spa) < SPA_VERSION_DSL_SCRUB)
+		ot = DMU_OT_ZAP_OTHER;
+
+	scn->scn_phys.scn_queue_obj = zap_create(dp->dp_meta_objset,
+	    ot ? ot : DMU_OT_SCAN_QUEUE, DMU_OT_NONE, 0, tx);
+
+	dsl_scan_sync_state(scn, tx);
+
+	spa_history_log_internal(spa, "scan setup", tx,
+	    "func=%u mintxg=%llu maxtxg=%llu",
+	    *funcp, scn->scn_phys.scn_min_txg, scn->scn_phys.scn_max_txg);
+}
+
+/* ARGSUSED */
+static void
+dsl_scan_done(dsl_scan_t *scn, boolean_t complete, dmu_tx_t *tx)
+{
+	static const char *old_names[] = {
+		"scrub_bookmark",
+		"scrub_ddt_bookmark",
+		"scrub_ddt_class_max",
+		"scrub_queue",
+		"scrub_min_txg",
+		"scrub_max_txg",
+		"scrub_func",
+		"scrub_errors",
+		NULL
+	};
+
+	dsl_pool_t *dp = scn->scn_dp;
+	spa_t *spa = dp->dp_spa;
+	int i;
+
+	/* Remove any remnants of an old-style scrub. */
+	for (i = 0; old_names[i]; i++) {
+		(void) zap_remove(dp->dp_meta_objset,
+		    DMU_POOL_DIRECTORY_OBJECT, old_names[i], tx);
+	}
+
+	if (scn->scn_phys.scn_queue_obj != 0) {
+		VERIFY(0 == dmu_object_free(dp->dp_meta_objset,
+		    scn->scn_phys.scn_queue_obj, tx));
+		scn->scn_phys.scn_queue_obj = 0;
+	}
+
+	/*
+	 * If we were "restarted" from a stopped state, don't bother
+	 * with anything else.
+	 */
+	if (scn->scn_phys.scn_state != DSS_SCANNING)
+		return;
+
+	if (complete)
+		scn->scn_phys.scn_state = DSS_FINISHED;
+	else
+		scn->scn_phys.scn_state = DSS_CANCELED;
+
+	spa_history_log_internal(spa, "scan done", tx,
+	    "complete=%u", complete);
+
+	if (DSL_SCAN_IS_SCRUB_RESILVER(scn)) {
+		mutex_enter(&spa->spa_scrub_lock);
+		while (spa->spa_scrub_inflight > 0) {
+			cv_wait(&spa->spa_scrub_io_cv,
+			    &spa->spa_scrub_lock);
+		}
+		mutex_exit(&spa->spa_scrub_lock);
+		spa->spa_scrub_started = B_FALSE;
+		spa->spa_scrub_active = B_FALSE;
+
+		/*
+		 * If the scrub/resilver completed, update all DTLs to
+		 * reflect this.  Whether it succeeded or not, vacate
+		 * all temporary scrub DTLs.
+		 */
+		vdev_dtl_reassess(spa->spa_root_vdev, tx->tx_txg,
+		    complete ? scn->scn_phys.scn_max_txg : 0, B_TRUE);
+		if (complete) {
+			spa_event_notify(spa, NULL, scn->scn_phys.scn_min_txg ?
+			    FM_EREPORT_ZFS_RESILVER_FINISH :
+			    FM_EREPORT_ZFS_SCRUB_FINISH);
+		}
+		spa_errlog_rotate(spa);
+
+		/*
+		 * We may have finished replacing a device.
+		 * Let the async thread assess this and handle the detach.
+		 */
+		spa_async_request(spa, SPA_ASYNC_RESILVER_DONE);
+	}
+
+	scn->scn_phys.scn_end_time = gethrestime_sec();
+
+	if (spa->spa_errata == ZPOOL_ERRATA_ZOL_2094_SCRUB)
+		spa->spa_errata = 0;
+}
+
+/* ARGSUSED */
+static int
+dsl_scan_cancel_check(void *arg, dmu_tx_t *tx)
+{
+	dsl_scan_t *scn = dmu_tx_pool(tx)->dp_scan;
+
+	if (scn->scn_phys.scn_state != DSS_SCANNING)
+		return (SET_ERROR(ENOENT));
+	return (0);
+}
+
+/* ARGSUSED */
+static void
+dsl_scan_cancel_sync(void *arg, dmu_tx_t *tx)
+{
+	dsl_scan_t *scn = dmu_tx_pool(tx)->dp_scan;
+
+	dsl_scan_done(scn, B_FALSE, tx);
+	dsl_scan_sync_state(scn, tx);
+}
+
+int
+dsl_scan_cancel(dsl_pool_t *dp)
+{
+	return (dsl_sync_task(spa_name(dp->dp_spa), dsl_scan_cancel_check,
+	    dsl_scan_cancel_sync, NULL, 3, ZFS_SPACE_CHECK_RESERVED));
+}
+
+static void dsl_scan_visitbp(blkptr_t *bp, const zbookmark_phys_t *zb,
+    dnode_phys_t *dnp, dsl_dataset_t *ds, dsl_scan_t *scn,
+    dmu_objset_type_t ostype, dmu_tx_t *tx);
+inline __attribute__((always_inline)) static void dsl_scan_visitdnode(
+    dsl_scan_t *, dsl_dataset_t *ds, dmu_objset_type_t ostype,
+    dnode_phys_t *dnp, uint64_t object, dmu_tx_t *tx);
+
+void
+dsl_free(dsl_pool_t *dp, uint64_t txg, const blkptr_t *bp)
+{
+	zio_free(dp->dp_spa, txg, bp);
+}
+
+void
+dsl_free_sync(zio_t *pio, dsl_pool_t *dp, uint64_t txg, const blkptr_t *bpp)
+{
+	ASSERT(dsl_pool_sync_context(dp));
+	zio_nowait(zio_free_sync(pio, dp->dp_spa, txg, bpp, pio->io_flags));
+}
+
+static uint64_t
+dsl_scan_ds_maxtxg(dsl_dataset_t *ds)
+{
+	uint64_t smt = ds->ds_dir->dd_pool->dp_scan->scn_phys.scn_max_txg;
+	if (ds->ds_is_snapshot)
+		return (MIN(smt, dsl_dataset_phys(ds)->ds_creation_txg));
+	return (smt);
+}
+
+static void
+dsl_scan_sync_state(dsl_scan_t *scn, dmu_tx_t *tx)
+{
+	VERIFY0(zap_update(scn->scn_dp->dp_meta_objset,
+	    DMU_POOL_DIRECTORY_OBJECT,
+	    DMU_POOL_SCAN, sizeof (uint64_t), SCAN_PHYS_NUMINTS,
+	    &scn->scn_phys, tx));
+}
+
+extern int zfs_vdev_async_write_active_min_dirty_percent;
+
+static boolean_t
+dsl_scan_check_pause(dsl_scan_t *scn, const zbookmark_phys_t *zb)
+{
+	uint64_t elapsed_nanosecs;
+	int mintime;
+	int dirty_pct;
+
+	/* we never skip user/group accounting objects */
+	if (zb && (int64_t)zb->zb_object < 0)
+		return (B_FALSE);
+
+	if (scn->scn_pausing)
+		return (B_TRUE); /* we're already pausing */
+
+	if (!ZB_IS_ZERO(&scn->scn_phys.scn_bookmark))
+		return (B_FALSE); /* we're resuming */
+
+	/* We only know how to resume from level-0 blocks. */
+	if (zb && zb->zb_level != 0)
+		return (B_FALSE);
+
+	/*
+	 * We pause if:
+	 *  - we have scanned for the maximum time: an entire txg
+	 *    timeout (default 5 sec)
+	 *  or
+	 *  - we have scanned for at least the minimum time (default 1 sec
+	 *    for scrub, 3 sec for resilver), and either we have sufficient
+	 *    dirty data that we are starting to write more quickly
+	 *    (default 30%), or someone is explicitly waiting for this txg
+	 *    to complete.
+	 *  or
+	 *  - the spa is shutting down because this pool is being exported
+	 *    or the machine is rebooting.
+	 */
+	mintime = (scn->scn_phys.scn_func == POOL_SCAN_RESILVER) ?
+	    zfs_resilver_min_time_ms : zfs_scan_min_time_ms;
+	elapsed_nanosecs = gethrtime() - scn->scn_sync_start_time;
+	dirty_pct = scn->scn_dp->dp_dirty_total * 100 / zfs_dirty_data_max;
+	if (elapsed_nanosecs / NANOSEC >= zfs_txg_timeout ||
+	    (NSEC2MSEC(elapsed_nanosecs) > mintime &&
+	    (txg_sync_waiting(scn->scn_dp) ||
+	    dirty_pct >= zfs_vdev_async_write_active_min_dirty_percent)) ||
+	    spa_shutting_down(scn->scn_dp->dp_spa)) {
+		if (zb) {
+			dprintf("pausing at bookmark %llx/%llx/%llx/%llx\n",
+			    (longlong_t)zb->zb_objset,
+			    (longlong_t)zb->zb_object,
+			    (longlong_t)zb->zb_level,
+			    (longlong_t)zb->zb_blkid);
+			scn->scn_phys.scn_bookmark = *zb;
+		}
+		dprintf("pausing at DDT bookmark %llx/%llx/%llx/%llx\n",
+		    (longlong_t)scn->scn_phys.scn_ddt_bookmark.ddb_class,
+		    (longlong_t)scn->scn_phys.scn_ddt_bookmark.ddb_type,
+		    (longlong_t)scn->scn_phys.scn_ddt_bookmark.ddb_checksum,
+		    (longlong_t)scn->scn_phys.scn_ddt_bookmark.ddb_cursor);
+		scn->scn_pausing = B_TRUE;
+		return (B_TRUE);
+	}
+	return (B_FALSE);
+}
+
+typedef struct zil_scan_arg {
+	dsl_pool_t	*zsa_dp;
+	zil_header_t	*zsa_zh;
+} zil_scan_arg_t;
+
+/* ARGSUSED */
+static int
+dsl_scan_zil_block(zilog_t *zilog, blkptr_t *bp, void *arg, uint64_t claim_txg)
+{
+	zil_scan_arg_t *zsa = arg;
+	dsl_pool_t *dp = zsa->zsa_dp;
+	dsl_scan_t *scn = dp->dp_scan;
+	zil_header_t *zh = zsa->zsa_zh;
+	zbookmark_phys_t zb;
+
+	if (BP_IS_HOLE(bp) || bp->blk_birth <= scn->scn_phys.scn_cur_min_txg)
+		return (0);
+
+	/*
+	 * One block ("stubby") can be allocated a long time ago; we
+	 * want to visit that one because it has been allocated
+	 * (on-disk) even if it hasn't been claimed (even though for
+	 * scrub there's nothing to do to it).
+	 */
+	if (claim_txg == 0 && bp->blk_birth >= spa_first_txg(dp->dp_spa))
+		return (0);
+
+	SET_BOOKMARK(&zb, zh->zh_log.blk_cksum.zc_word[ZIL_ZC_OBJSET],
+	    ZB_ZIL_OBJECT, ZB_ZIL_LEVEL, bp->blk_cksum.zc_word[ZIL_ZC_SEQ]);
+
+	VERIFY(0 == scan_funcs[scn->scn_phys.scn_func](dp, bp, &zb));
+	return (0);
+}
+
+/* ARGSUSED */
+static int
+dsl_scan_zil_record(zilog_t *zilog, lr_t *lrc, void *arg, uint64_t claim_txg)
+{
+	if (lrc->lrc_txtype == TX_WRITE) {
+		zil_scan_arg_t *zsa = arg;
+		dsl_pool_t *dp = zsa->zsa_dp;
+		dsl_scan_t *scn = dp->dp_scan;
+		zil_header_t *zh = zsa->zsa_zh;
+		lr_write_t *lr = (lr_write_t *)lrc;
+		blkptr_t *bp = &lr->lr_blkptr;
+		zbookmark_phys_t zb;
+
+		if (BP_IS_HOLE(bp) ||
+		    bp->blk_birth <= scn->scn_phys.scn_cur_min_txg)
+			return (0);
+
+		/*
+		 * birth can be < claim_txg if this record's txg is
+		 * already txg sync'ed (but this log block contains
+		 * other records that are not synced)
+		 */
+		if (claim_txg == 0 || bp->blk_birth < claim_txg)
+			return (0);
+
+		SET_BOOKMARK(&zb, zh->zh_log.blk_cksum.zc_word[ZIL_ZC_OBJSET],
+		    lr->lr_foid, ZB_ZIL_LEVEL,
+		    lr->lr_offset / BP_GET_LSIZE(bp));
+
+		VERIFY(0 == scan_funcs[scn->scn_phys.scn_func](dp, bp, &zb));
+	}
+	return (0);
+}
+
+static void
+dsl_scan_zil(dsl_pool_t *dp, zil_header_t *zh)
+{
+	uint64_t claim_txg = zh->zh_claim_txg;
+	zil_scan_arg_t zsa = { dp, zh };
+	zilog_t *zilog;
+
+	/*
+	 * We only want to visit blocks that have been claimed but not yet
+	 * replayed (or, in read-only mode, blocks that *would* be claimed).
+	 */
+	if (claim_txg == 0 && spa_writeable(dp->dp_spa))
+		return;
+
+	zilog = zil_alloc(dp->dp_meta_objset, zh);
+
+	(void) zil_parse(zilog, dsl_scan_zil_block, dsl_scan_zil_record, &zsa,
+	    claim_txg);
+
+	zil_free(zilog);
+}
+
+/* ARGSUSED */
+static void
+dsl_scan_prefetch(dsl_scan_t *scn, arc_buf_t *buf, blkptr_t *bp,
+    uint64_t objset, uint64_t object, uint64_t blkid)
+{
+	zbookmark_phys_t czb;
+	arc_flags_t flags = ARC_FLAG_NOWAIT | ARC_FLAG_PREFETCH;
+
+	if (zfs_no_scrub_prefetch)
+		return;
+
+	if (BP_IS_HOLE(bp) || bp->blk_birth <= scn->scn_phys.scn_min_txg ||
+	    (BP_GET_LEVEL(bp) == 0 && BP_GET_TYPE(bp) != DMU_OT_DNODE))
+		return;
+
+	SET_BOOKMARK(&czb, objset, object, BP_GET_LEVEL(bp), blkid);
+
+	(void) arc_read(scn->scn_zio_root, scn->scn_dp->dp_spa, bp,
+	    NULL, NULL, ZIO_PRIORITY_ASYNC_READ,
+	    ZIO_FLAG_CANFAIL | ZIO_FLAG_SCAN_THREAD, &flags, &czb);
+}
+
+static boolean_t
+dsl_scan_check_resume(dsl_scan_t *scn, const dnode_phys_t *dnp,
+    const zbookmark_phys_t *zb)
+{
+	/*
+	 * We never skip over user/group accounting objects (obj<0)
+	 */
+	if (!ZB_IS_ZERO(&scn->scn_phys.scn_bookmark) &&
+	    (int64_t)zb->zb_object >= 0) {
+		/*
+		 * If we already visited this bp & everything below (in
+		 * a prior txg sync), don't bother doing it again.
+		 */
+		if (zbookmark_is_before(dnp, zb, &scn->scn_phys.scn_bookmark))
+			return (B_TRUE);
+
+		/*
+		 * If we found the block we're trying to resume from, or
+		 * we went past it to a different object, zero it out to
+		 * indicate that it's OK to start checking for pausing
+		 * again.
+		 */
+		if (bcmp(zb, &scn->scn_phys.scn_bookmark, sizeof (*zb)) == 0 ||
+		    zb->zb_object > scn->scn_phys.scn_bookmark.zb_object) {
+			dprintf("resuming at %llx/%llx/%llx/%llx\n",
+			    (longlong_t)zb->zb_objset,
+			    (longlong_t)zb->zb_object,
+			    (longlong_t)zb->zb_level,
+			    (longlong_t)zb->zb_blkid);
+			bzero(&scn->scn_phys.scn_bookmark, sizeof (*zb));
+		}
+	}
+	return (B_FALSE);
+}
+
+/*
+ * Return nonzero on i/o error.
+ * Return new buf to write out in *bufp.
+ */
+inline __attribute__((always_inline)) static int
+dsl_scan_recurse(dsl_scan_t *scn, dsl_dataset_t *ds, dmu_objset_type_t ostype,
+    dnode_phys_t *dnp, const blkptr_t *bp,
+    const zbookmark_phys_t *zb, dmu_tx_t *tx)
+{
+	dsl_pool_t *dp = scn->scn_dp;
+	int zio_flags = ZIO_FLAG_CANFAIL | ZIO_FLAG_SCAN_THREAD;
+	int err;
+
+	if (BP_GET_LEVEL(bp) > 0) {
+		arc_flags_t flags = ARC_FLAG_WAIT;
+		int i;
+		blkptr_t *cbp;
+		int epb = BP_GET_LSIZE(bp) >> SPA_BLKPTRSHIFT;
+		arc_buf_t *buf;
+
+		err = arc_read(NULL, dp->dp_spa, bp, arc_getbuf_func, &buf,
+		    ZIO_PRIORITY_ASYNC_READ, zio_flags, &flags, zb);
+		if (err) {
+			scn->scn_phys.scn_errors++;
+			return (err);
+		}
+		for (i = 0, cbp = buf->b_data; i < epb; i++, cbp++) {
+			dsl_scan_prefetch(scn, buf, cbp, zb->zb_objset,
+			    zb->zb_object, zb->zb_blkid * epb + i);
+		}
+		for (i = 0, cbp = buf->b_data; i < epb; i++, cbp++) {
+			zbookmark_phys_t czb;
+
+			SET_BOOKMARK(&czb, zb->zb_objset, zb->zb_object,
+			    zb->zb_level - 1,
+			    zb->zb_blkid * epb + i);
+			dsl_scan_visitbp(cbp, &czb, dnp,
+			    ds, scn, ostype, tx);
+		}
+		(void) arc_buf_remove_ref(buf, &buf);
+	} else if (BP_GET_TYPE(bp) == DMU_OT_DNODE) {
+		arc_flags_t flags = ARC_FLAG_WAIT;
+		dnode_phys_t *cdnp;
+		int i, j;
+		int epb = BP_GET_LSIZE(bp) >> DNODE_SHIFT;
+		arc_buf_t *buf;
+
+		err = arc_read(NULL, dp->dp_spa, bp, arc_getbuf_func, &buf,
+		    ZIO_PRIORITY_ASYNC_READ, zio_flags, &flags, zb);
+		if (err) {
+			scn->scn_phys.scn_errors++;
+			return (err);
+		}
+		for (i = 0, cdnp = buf->b_data; i < epb; i++, cdnp++) {
+			for (j = 0; j < cdnp->dn_nblkptr; j++) {
+				blkptr_t *cbp = &cdnp->dn_blkptr[j];
+				dsl_scan_prefetch(scn, buf, cbp,
+				    zb->zb_objset, zb->zb_blkid * epb + i, j);
+			}
+		}
+		for (i = 0, cdnp = buf->b_data; i < epb; i++, cdnp++) {
+			dsl_scan_visitdnode(scn, ds, ostype,
+			    cdnp, zb->zb_blkid * epb + i, tx);
+		}
+
+		(void) arc_buf_remove_ref(buf, &buf);
+	} else if (BP_GET_TYPE(bp) == DMU_OT_OBJSET) {
+		arc_flags_t flags = ARC_FLAG_WAIT;
+		objset_phys_t *osp;
+		arc_buf_t *buf;
+
+		err = arc_read(NULL, dp->dp_spa, bp, arc_getbuf_func, &buf,
+		    ZIO_PRIORITY_ASYNC_READ, zio_flags, &flags, zb);
+		if (err) {
+			scn->scn_phys.scn_errors++;
+			return (err);
+		}
+
+		osp = buf->b_data;
+
+		dsl_scan_visitdnode(scn, ds, osp->os_type,
+		    &osp->os_meta_dnode, DMU_META_DNODE_OBJECT, tx);
+
+		if (OBJSET_BUF_HAS_USERUSED(buf)) {
+			/*
+			 * We also always visit user/group accounting
+			 * objects, and never skip them, even if we are
+			 * pausing.  This is necessary so that the space
+			 * deltas from this txg get integrated.
+			 */
+			dsl_scan_visitdnode(scn, ds, osp->os_type,
+			    &osp->os_groupused_dnode,
+			    DMU_GROUPUSED_OBJECT, tx);
+			dsl_scan_visitdnode(scn, ds, osp->os_type,
+			    &osp->os_userused_dnode,
+			    DMU_USERUSED_OBJECT, tx);
+		}
+		(void) arc_buf_remove_ref(buf, &buf);
+	}
+
+	return (0);
+}
+
+inline __attribute__((always_inline)) static void
+dsl_scan_visitdnode(dsl_scan_t *scn, dsl_dataset_t *ds,
+    dmu_objset_type_t ostype, dnode_phys_t *dnp,
+    uint64_t object, dmu_tx_t *tx)
+{
+	int j;
+
+	for (j = 0; j < dnp->dn_nblkptr; j++) {
+		zbookmark_phys_t czb;
+
+		SET_BOOKMARK(&czb, ds ? ds->ds_object : 0, object,
+		    dnp->dn_nlevels - 1, j);
+		dsl_scan_visitbp(&dnp->dn_blkptr[j],
+		    &czb, dnp, ds, scn, ostype, tx);
+	}
+
+	if (dnp->dn_flags & DNODE_FLAG_SPILL_BLKPTR) {
+		zbookmark_phys_t czb;
+		SET_BOOKMARK(&czb, ds ? ds->ds_object : 0, object,
+		    0, DMU_SPILL_BLKID);
+		dsl_scan_visitbp(&dnp->dn_spill,
+		    &czb, dnp, ds, scn, ostype, tx);
+	}
+}
+
+/*
+ * The arguments are in this order because mdb can only print the
+ * first 5; we want them to be useful.
+ */
+static void
+dsl_scan_visitbp(blkptr_t *bp, const zbookmark_phys_t *zb,
+    dnode_phys_t *dnp, dsl_dataset_t *ds, dsl_scan_t *scn,
+    dmu_objset_type_t ostype, dmu_tx_t *tx)
+{
+	dsl_pool_t *dp = scn->scn_dp;
+	blkptr_t *bp_toread;
+
+	bp_toread = kmem_alloc(sizeof (blkptr_t), KM_SLEEP);
+	*bp_toread = *bp;
+
+	/* ASSERT(pbuf == NULL || arc_released(pbuf)); */
+
+	if (dsl_scan_check_pause(scn, zb))
+		goto out;
+
+	if (dsl_scan_check_resume(scn, dnp, zb))
+		goto out;
+
+	if (BP_IS_HOLE(bp))
+		goto out;
+
+	scn->scn_visited_this_txg++;
+
+	/*
+	 * This debugging is commented out to conserve stack space.  This
+	 * function is called recursively and the debugging addes several
+	 * bytes to the stack for each call.  It can be commented back in
+	 * if required to debug an issue in dsl_scan_visitbp().
+	 *
+	 * dprintf_bp(bp,
+	 *    "visiting ds=%p/%llu zb=%llx/%llx/%llx/%llx bp=%p",
+	 *    ds, ds ? ds->ds_object : 0,
+	 *    zb->zb_objset, zb->zb_object, zb->zb_level, zb->zb_blkid,
+	 *    bp);
+	 */
+
+	if (bp->blk_birth <= scn->scn_phys.scn_cur_min_txg)
+		goto out;
+
+	if (dsl_scan_recurse(scn, ds, ostype, dnp, bp_toread, zb, tx) != 0)
+		goto out;
+
+	/*
+	 * If dsl_scan_ddt() has aready visited this block, it will have
+	 * already done any translations or scrubbing, so don't call the
+	 * callback again.
+	 */
+	if (ddt_class_contains(dp->dp_spa,
+	    scn->scn_phys.scn_ddt_class_max, bp)) {
+		goto out;
+	}
+
+	/*
+	 * If this block is from the future (after cur_max_txg), then we
+	 * are doing this on behalf of a deleted snapshot, and we will
+	 * revisit the future block on the next pass of this dataset.
+	 * Don't scan it now unless we need to because something
+	 * under it was modified.
+	 */
+	if (BP_PHYSICAL_BIRTH(bp) <= scn->scn_phys.scn_cur_max_txg) {
+		scan_funcs[scn->scn_phys.scn_func](dp, bp, zb);
+	}
+out:
+	kmem_free(bp_toread, sizeof (blkptr_t));
+}
+
+static void
+dsl_scan_visit_rootbp(dsl_scan_t *scn, dsl_dataset_t *ds, blkptr_t *bp,
+    dmu_tx_t *tx)
+{
+	zbookmark_phys_t zb;
+
+	SET_BOOKMARK(&zb, ds ? ds->ds_object : DMU_META_OBJSET,
+	    ZB_ROOT_OBJECT, ZB_ROOT_LEVEL, ZB_ROOT_BLKID);
+	dsl_scan_visitbp(bp, &zb, NULL,
+	    ds, scn, DMU_OST_NONE, tx);
+
+	dprintf_ds(ds, "finished scan%s", "");
+}
+
+void
+dsl_scan_ds_destroyed(dsl_dataset_t *ds, dmu_tx_t *tx)
+{
+	dsl_pool_t *dp = ds->ds_dir->dd_pool;
+	dsl_scan_t *scn = dp->dp_scan;
+	uint64_t mintxg;
+
+	if (scn->scn_phys.scn_state != DSS_SCANNING)
+		return;
+
+	if (scn->scn_phys.scn_bookmark.zb_objset == ds->ds_object) {
+		if (ds->ds_is_snapshot) {
+			/* Note, scn_cur_{min,max}_txg stays the same. */
+			scn->scn_phys.scn_bookmark.zb_objset =
+			    dsl_dataset_phys(ds)->ds_next_snap_obj;
+			zfs_dbgmsg("destroying ds %llu; currently traversing; "
+			    "reset zb_objset to %llu",
+			    (u_longlong_t)ds->ds_object,
+			    (u_longlong_t)dsl_dataset_phys(ds)->
+			    ds_next_snap_obj);
+			scn->scn_phys.scn_flags |= DSF_VISIT_DS_AGAIN;
+		} else {
+			SET_BOOKMARK(&scn->scn_phys.scn_bookmark,
+			    ZB_DESTROYED_OBJSET, 0, 0, 0);
+			zfs_dbgmsg("destroying ds %llu; currently traversing; "
+			    "reset bookmark to -1,0,0,0",
+			    (u_longlong_t)ds->ds_object);
+		}
+	} else if (zap_lookup_int_key(dp->dp_meta_objset,
+	    scn->scn_phys.scn_queue_obj, ds->ds_object, &mintxg) == 0) {
+		ASSERT3U(dsl_dataset_phys(ds)->ds_num_children, <=, 1);
+		VERIFY3U(0, ==, zap_remove_int(dp->dp_meta_objset,
+		    scn->scn_phys.scn_queue_obj, ds->ds_object, tx));
+		if (ds->ds_is_snapshot) {
+			/*
+			 * We keep the same mintxg; it could be >
+			 * ds_creation_txg if the previous snapshot was
+			 * deleted too.
+			 */
+			VERIFY(zap_add_int_key(dp->dp_meta_objset,
+			    scn->scn_phys.scn_queue_obj,
+			    dsl_dataset_phys(ds)->ds_next_snap_obj,
+			    mintxg, tx) == 0);
+			zfs_dbgmsg("destroying ds %llu; in queue; "
+			    "replacing with %llu",
+			    (u_longlong_t)ds->ds_object,
+			    (u_longlong_t)dsl_dataset_phys(ds)->
+			    ds_next_snap_obj);
+		} else {
+			zfs_dbgmsg("destroying ds %llu; in queue; removing",
+			    (u_longlong_t)ds->ds_object);
+		}
+	} else {
+		zfs_dbgmsg("destroying ds %llu; ignoring",
+		    (u_longlong_t)ds->ds_object);
+	}
+
+	/*
+	 * dsl_scan_sync() should be called after this, and should sync
+	 * out our changed state, but just to be safe, do it here.
+	 */
+	dsl_scan_sync_state(scn, tx);
+}
+
+void
+dsl_scan_ds_snapshotted(dsl_dataset_t *ds, dmu_tx_t *tx)
+{
+	dsl_pool_t *dp = ds->ds_dir->dd_pool;
+	dsl_scan_t *scn = dp->dp_scan;
+	uint64_t mintxg;
+
+	if (scn->scn_phys.scn_state != DSS_SCANNING)
+		return;
+
+	ASSERT(dsl_dataset_phys(ds)->ds_prev_snap_obj != 0);
+
+	if (scn->scn_phys.scn_bookmark.zb_objset == ds->ds_object) {
+		scn->scn_phys.scn_bookmark.zb_objset =
+		    dsl_dataset_phys(ds)->ds_prev_snap_obj;
+		zfs_dbgmsg("snapshotting ds %llu; currently traversing; "
+		    "reset zb_objset to %llu",
+		    (u_longlong_t)ds->ds_object,
+		    (u_longlong_t)dsl_dataset_phys(ds)->ds_prev_snap_obj);
+	} else if (zap_lookup_int_key(dp->dp_meta_objset,
+	    scn->scn_phys.scn_queue_obj, ds->ds_object, &mintxg) == 0) {
+		VERIFY3U(0, ==, zap_remove_int(dp->dp_meta_objset,
+		    scn->scn_phys.scn_queue_obj, ds->ds_object, tx));
+		VERIFY(zap_add_int_key(dp->dp_meta_objset,
+		    scn->scn_phys.scn_queue_obj,
+		    dsl_dataset_phys(ds)->ds_prev_snap_obj, mintxg, tx) == 0);
+		zfs_dbgmsg("snapshotting ds %llu; in queue; "
+		    "replacing with %llu",
+		    (u_longlong_t)ds->ds_object,
+		    (u_longlong_t)dsl_dataset_phys(ds)->ds_prev_snap_obj);
+	}
+	dsl_scan_sync_state(scn, tx);
+}
+
+void
+dsl_scan_ds_clone_swapped(dsl_dataset_t *ds1, dsl_dataset_t *ds2, dmu_tx_t *tx)
+{
+	dsl_pool_t *dp = ds1->ds_dir->dd_pool;
+	dsl_scan_t *scn = dp->dp_scan;
+	uint64_t mintxg;
+
+	if (scn->scn_phys.scn_state != DSS_SCANNING)
+		return;
+
+	if (scn->scn_phys.scn_bookmark.zb_objset == ds1->ds_object) {
+		scn->scn_phys.scn_bookmark.zb_objset = ds2->ds_object;
+		zfs_dbgmsg("clone_swap ds %llu; currently traversing; "
+		    "reset zb_objset to %llu",
+		    (u_longlong_t)ds1->ds_object,
+		    (u_longlong_t)ds2->ds_object);
+	} else if (scn->scn_phys.scn_bookmark.zb_objset == ds2->ds_object) {
+		scn->scn_phys.scn_bookmark.zb_objset = ds1->ds_object;
+		zfs_dbgmsg("clone_swap ds %llu; currently traversing; "
+		    "reset zb_objset to %llu",
+		    (u_longlong_t)ds2->ds_object,
+		    (u_longlong_t)ds1->ds_object);
+	}
+
+	if (zap_lookup_int_key(dp->dp_meta_objset, scn->scn_phys.scn_queue_obj,
+	    ds1->ds_object, &mintxg) == 0) {
+		int err;
+
+		ASSERT3U(mintxg, ==, dsl_dataset_phys(ds1)->ds_prev_snap_txg);
+		ASSERT3U(mintxg, ==, dsl_dataset_phys(ds2)->ds_prev_snap_txg);
+		VERIFY3U(0, ==, zap_remove_int(dp->dp_meta_objset,
+		    scn->scn_phys.scn_queue_obj, ds1->ds_object, tx));
+		err = zap_add_int_key(dp->dp_meta_objset,
+		    scn->scn_phys.scn_queue_obj, ds2->ds_object, mintxg, tx);
+		VERIFY(err == 0 || err == EEXIST);
+		if (err == EEXIST) {
+			/* Both were there to begin with */
+			VERIFY(0 == zap_add_int_key(dp->dp_meta_objset,
+			    scn->scn_phys.scn_queue_obj,
+			    ds1->ds_object, mintxg, tx));
+		}
+		zfs_dbgmsg("clone_swap ds %llu; in queue; "
+		    "replacing with %llu",
+		    (u_longlong_t)ds1->ds_object,
+		    (u_longlong_t)ds2->ds_object);
+	} else if (zap_lookup_int_key(dp->dp_meta_objset,
+	    scn->scn_phys.scn_queue_obj, ds2->ds_object, &mintxg) == 0) {
+		ASSERT3U(mintxg, ==, dsl_dataset_phys(ds1)->ds_prev_snap_txg);
+		ASSERT3U(mintxg, ==, dsl_dataset_phys(ds2)->ds_prev_snap_txg);
+		VERIFY3U(0, ==, zap_remove_int(dp->dp_meta_objset,
+		    scn->scn_phys.scn_queue_obj, ds2->ds_object, tx));
+		VERIFY(0 == zap_add_int_key(dp->dp_meta_objset,
+		    scn->scn_phys.scn_queue_obj, ds1->ds_object, mintxg, tx));
+		zfs_dbgmsg("clone_swap ds %llu; in queue; "
+		    "replacing with %llu",
+		    (u_longlong_t)ds2->ds_object,
+		    (u_longlong_t)ds1->ds_object);
+	}
+
+	dsl_scan_sync_state(scn, tx);
+}
+
+struct enqueue_clones_arg {
+	dmu_tx_t *tx;
+	uint64_t originobj;
+};
+
+/* ARGSUSED */
+static int
+enqueue_clones_cb(dsl_pool_t *dp, dsl_dataset_t *hds, void *arg)
+{
+	struct enqueue_clones_arg *eca = arg;
+	dsl_dataset_t *ds;
+	int err;
+	dsl_scan_t *scn = dp->dp_scan;
+
+	if (dsl_dir_phys(hds->ds_dir)->dd_origin_obj != eca->originobj)
+		return (0);
+
+	err = dsl_dataset_hold_obj(dp, hds->ds_object, FTAG, &ds);
+	if (err)
+		return (err);
+
+	while (dsl_dataset_phys(ds)->ds_prev_snap_obj != eca->originobj) {
+		dsl_dataset_t *prev;
+		err = dsl_dataset_hold_obj(dp,
+		    dsl_dataset_phys(ds)->ds_prev_snap_obj, FTAG, &prev);
+
+		dsl_dataset_rele(ds, FTAG);
+		if (err)
+			return (err);
+		ds = prev;
+	}
+	VERIFY(zap_add_int_key(dp->dp_meta_objset,
+	    scn->scn_phys.scn_queue_obj, ds->ds_object,
+	    dsl_dataset_phys(ds)->ds_prev_snap_txg, eca->tx) == 0);
+	dsl_dataset_rele(ds, FTAG);
+	return (0);
+}
+
+static void
+dsl_scan_visitds(dsl_scan_t *scn, uint64_t dsobj, dmu_tx_t *tx)
+{
+	dsl_pool_t *dp = scn->scn_dp;
+	dsl_dataset_t *ds;
+	objset_t *os;
+	char *dsname;
+
+	VERIFY3U(0, ==, dsl_dataset_hold_obj(dp, dsobj, FTAG, &ds));
+
+	if (dmu_objset_from_ds(ds, &os))
+		goto out;
+
+	/*
+	 * Only the ZIL in the head (non-snapshot) is valid.  Even though
+	 * snapshots can have ZIL block pointers (which may be the same
+	 * BP as in the head), they must be ignored.  So we traverse the
+	 * ZIL here, rather than in scan_recurse(), because the regular
+	 * snapshot block-sharing rules don't apply to it.
+	 */
+	if (DSL_SCAN_IS_SCRUB_RESILVER(scn) && !ds->ds_is_snapshot)
+		dsl_scan_zil(dp, &os->os_zil_header);
+
+	/*
+	 * Iterate over the bps in this ds.
+	 */
+	dmu_buf_will_dirty(ds->ds_dbuf, tx);
+	dsl_scan_visit_rootbp(scn, ds, &dsl_dataset_phys(ds)->ds_bp, tx);
+
+	dsname = kmem_alloc(ZFS_MAXNAMELEN, KM_SLEEP);
+	dsl_dataset_name(ds, dsname);
+	zfs_dbgmsg("scanned dataset %llu (%s) with min=%llu max=%llu; "
+	    "pausing=%u",
+	    (longlong_t)dsobj, dsname,
+	    (longlong_t)scn->scn_phys.scn_cur_min_txg,
+	    (longlong_t)scn->scn_phys.scn_cur_max_txg,
+	    (int)scn->scn_pausing);
+	kmem_free(dsname, ZFS_MAXNAMELEN);
+
+	if (scn->scn_pausing)
+		goto out;
+
+	/*
+	 * We've finished this pass over this dataset.
+	 */
+
+	/*
+	 * If we did not completely visit this dataset, do another pass.
+	 */
+	if (scn->scn_phys.scn_flags & DSF_VISIT_DS_AGAIN) {
+		zfs_dbgmsg("incomplete pass; visiting again");
+		scn->scn_phys.scn_flags &= ~DSF_VISIT_DS_AGAIN;
+		VERIFY(zap_add_int_key(dp->dp_meta_objset,
+		    scn->scn_phys.scn_queue_obj, ds->ds_object,
+		    scn->scn_phys.scn_cur_max_txg, tx) == 0);
+		goto out;
+	}
+
+	/*
+	 * Add descendent datasets to work queue.
+	 */
+	if (dsl_dataset_phys(ds)->ds_next_snap_obj != 0) {
+		VERIFY(zap_add_int_key(dp->dp_meta_objset,
+		    scn->scn_phys.scn_queue_obj,
+		    dsl_dataset_phys(ds)->ds_next_snap_obj,
+		    dsl_dataset_phys(ds)->ds_creation_txg, tx) == 0);
+	}
+	if (dsl_dataset_phys(ds)->ds_num_children > 1) {
+		boolean_t usenext = B_FALSE;
+		if (dsl_dataset_phys(ds)->ds_next_clones_obj != 0) {
+			uint64_t count;
+			/*
+			 * A bug in a previous version of the code could
+			 * cause upgrade_clones_cb() to not set
+			 * ds_next_snap_obj when it should, leading to a
+			 * missing entry.  Therefore we can only use the
+			 * next_clones_obj when its count is correct.
+			 */
+			int err = zap_count(dp->dp_meta_objset,
+			    dsl_dataset_phys(ds)->ds_next_clones_obj, &count);
+			if (err == 0 &&
+			    count == dsl_dataset_phys(ds)->ds_num_children - 1)
+				usenext = B_TRUE;
+		}
+
+		if (usenext) {
+			VERIFY0(zap_join_key(dp->dp_meta_objset,
+			    dsl_dataset_phys(ds)->ds_next_clones_obj,
+			    scn->scn_phys.scn_queue_obj,
+			    dsl_dataset_phys(ds)->ds_creation_txg, tx));
+		} else {
+			struct enqueue_clones_arg eca;
+			eca.tx = tx;
+			eca.originobj = ds->ds_object;
+
+			VERIFY0(dmu_objset_find_dp(dp, dp->dp_root_dir_obj,
+			    enqueue_clones_cb, &eca, DS_FIND_CHILDREN));
+		}
+	}
+
+out:
+	dsl_dataset_rele(ds, FTAG);
+}
+
+/* ARGSUSED */
+static int
+enqueue_cb(dsl_pool_t *dp, dsl_dataset_t *hds, void *arg)
+{
+	dmu_tx_t *tx = arg;
+	dsl_dataset_t *ds;
+	int err;
+	dsl_scan_t *scn = dp->dp_scan;
+
+	err = dsl_dataset_hold_obj(dp, hds->ds_object, FTAG, &ds);
+	if (err)
+		return (err);
+
+	while (dsl_dataset_phys(ds)->ds_prev_snap_obj != 0) {
+		dsl_dataset_t *prev;
+		err = dsl_dataset_hold_obj(dp,
+		    dsl_dataset_phys(ds)->ds_prev_snap_obj, FTAG, &prev);
+		if (err) {
+			dsl_dataset_rele(ds, FTAG);
+			return (err);
+		}
+
+		/*
+		 * If this is a clone, we don't need to worry about it for now.
+		 */
+		if (dsl_dataset_phys(prev)->ds_next_snap_obj != ds->ds_object) {
+			dsl_dataset_rele(ds, FTAG);
+			dsl_dataset_rele(prev, FTAG);
+			return (0);
+		}
+		dsl_dataset_rele(ds, FTAG);
+		ds = prev;
+	}
+
+	VERIFY(zap_add_int_key(dp->dp_meta_objset, scn->scn_phys.scn_queue_obj,
+	    ds->ds_object, dsl_dataset_phys(ds)->ds_prev_snap_txg, tx) == 0);
+	dsl_dataset_rele(ds, FTAG);
+	return (0);
+}
+
+/*
+ * Scrub/dedup interaction.
+ *
+ * If there are N references to a deduped block, we don't want to scrub it
+ * N times -- ideally, we should scrub it exactly once.
+ *
+ * We leverage the fact that the dde's replication class (enum ddt_class)
+ * is ordered from highest replication class (DDT_CLASS_DITTO) to lowest
+ * (DDT_CLASS_UNIQUE) so that we may walk the DDT in that order.
+ *
+ * To prevent excess scrubbing, the scrub begins by walking the DDT
+ * to find all blocks with refcnt > 1, and scrubs each of these once.
+ * Since there are two replication classes which contain blocks with
+ * refcnt > 1, we scrub the highest replication class (DDT_CLASS_DITTO) first.
+ * Finally the top-down scrub begins, only visiting blocks with refcnt == 1.
+ *
+ * There would be nothing more to say if a block's refcnt couldn't change
+ * during a scrub, but of course it can so we must account for changes
+ * in a block's replication class.
+ *
+ * Here's an example of what can occur:
+ *
+ * If a block has refcnt > 1 during the DDT scrub phase, but has refcnt == 1
+ * when visited during the top-down scrub phase, it will be scrubbed twice.
+ * This negates our scrub optimization, but is otherwise harmless.
+ *
+ * If a block has refcnt == 1 during the DDT scrub phase, but has refcnt > 1
+ * on each visit during the top-down scrub phase, it will never be scrubbed.
+ * To catch this, ddt_sync_entry() notifies the scrub code whenever a block's
+ * reference class transitions to a higher level (i.e DDT_CLASS_UNIQUE to
+ * DDT_CLASS_DUPLICATE); if it transitions from refcnt == 1 to refcnt > 1
+ * while a scrub is in progress, it scrubs the block right then.
+ */
+static void
+dsl_scan_ddt(dsl_scan_t *scn, dmu_tx_t *tx)
+{
+	ddt_bookmark_t *ddb = &scn->scn_phys.scn_ddt_bookmark;
+	ddt_entry_t dde;
+	int error;
+	uint64_t n = 0;
+
+	bzero(&dde, sizeof (ddt_entry_t));
+
+	while ((error = ddt_walk(scn->scn_dp->dp_spa, ddb, &dde)) == 0) {
+		ddt_t *ddt;
+
+		if (ddb->ddb_class > scn->scn_phys.scn_ddt_class_max)
+			break;
+		dprintf("visiting ddb=%llu/%llu/%llu/%llx\n",
+		    (longlong_t)ddb->ddb_class,
+		    (longlong_t)ddb->ddb_type,
+		    (longlong_t)ddb->ddb_checksum,
+		    (longlong_t)ddb->ddb_cursor);
+
+		/* There should be no pending changes to the dedup table */
+		ddt = scn->scn_dp->dp_spa->spa_ddt[ddb->ddb_checksum];
+		ASSERT(avl_first(&ddt->ddt_tree) == NULL);
+
+		dsl_scan_ddt_entry(scn, ddb->ddb_checksum, &dde, tx);
+		n++;
+
+		if (dsl_scan_check_pause(scn, NULL))
+			break;
+	}
+
+	zfs_dbgmsg("scanned %llu ddt entries with class_max = %u; pausing=%u",
+	    (longlong_t)n, (int)scn->scn_phys.scn_ddt_class_max,
+	    (int)scn->scn_pausing);
+
+	ASSERT(error == 0 || error == ENOENT);
+	ASSERT(error != ENOENT ||
+	    ddb->ddb_class > scn->scn_phys.scn_ddt_class_max);
+}
+
+/* ARGSUSED */
+void
+dsl_scan_ddt_entry(dsl_scan_t *scn, enum zio_checksum checksum,
+    ddt_entry_t *dde, dmu_tx_t *tx)
+{
+	const ddt_key_t *ddk = &dde->dde_key;
+	ddt_phys_t *ddp = dde->dde_phys;
+	blkptr_t bp;
+	zbookmark_phys_t zb = { 0 };
+	int p;
+
+	if (scn->scn_phys.scn_state != DSS_SCANNING)
+		return;
+
+	for (p = 0; p < DDT_PHYS_TYPES; p++, ddp++) {
+		if (ddp->ddp_phys_birth == 0 ||
+		    ddp->ddp_phys_birth > scn->scn_phys.scn_max_txg)
+			continue;
+		ddt_bp_create(checksum, ddk, ddp, &bp);
+
+		scn->scn_visited_this_txg++;
+		scan_funcs[scn->scn_phys.scn_func](scn->scn_dp, &bp, &zb);
+	}
+}
+
+static void
+dsl_scan_visit(dsl_scan_t *scn, dmu_tx_t *tx)
+{
+	dsl_pool_t *dp = scn->scn_dp;
+	zap_cursor_t *zc;
+	zap_attribute_t *za;
+
+	if (scn->scn_phys.scn_ddt_bookmark.ddb_class <=
+	    scn->scn_phys.scn_ddt_class_max) {
+		scn->scn_phys.scn_cur_min_txg = scn->scn_phys.scn_min_txg;
+		scn->scn_phys.scn_cur_max_txg = scn->scn_phys.scn_max_txg;
+		dsl_scan_ddt(scn, tx);
+		if (scn->scn_pausing)
+			return;
+	}
+
+	if (scn->scn_phys.scn_bookmark.zb_objset == DMU_META_OBJSET) {
+		/* First do the MOS & ORIGIN */
+
+		scn->scn_phys.scn_cur_min_txg = scn->scn_phys.scn_min_txg;
+		scn->scn_phys.scn_cur_max_txg = scn->scn_phys.scn_max_txg;
+		dsl_scan_visit_rootbp(scn, NULL,
+		    &dp->dp_meta_rootbp, tx);
+		spa_set_rootblkptr(dp->dp_spa, &dp->dp_meta_rootbp);
+		if (scn->scn_pausing)
+			return;
+
+		if (spa_version(dp->dp_spa) < SPA_VERSION_DSL_SCRUB) {
+			VERIFY0(dmu_objset_find_dp(dp, dp->dp_root_dir_obj,
+			    enqueue_cb, tx, DS_FIND_CHILDREN));
+		} else {
+			dsl_scan_visitds(scn,
+			    dp->dp_origin_snap->ds_object, tx);
+		}
+		ASSERT(!scn->scn_pausing);
+	} else if (scn->scn_phys.scn_bookmark.zb_objset !=
+	    ZB_DESTROYED_OBJSET) {
+		/*
+		 * If we were paused, continue from here.  Note if the
+		 * ds we were paused on was deleted, the zb_objset may
+		 * be -1, so we will skip this and find a new objset
+		 * below.
+		 */
+		dsl_scan_visitds(scn, scn->scn_phys.scn_bookmark.zb_objset, tx);
+		if (scn->scn_pausing)
+			return;
+	}
+
+	/*
+	 * In case we were paused right at the end of the ds, zero the
+	 * bookmark so we don't think that we're still trying to resume.
+	 */
+	bzero(&scn->scn_phys.scn_bookmark, sizeof (zbookmark_phys_t));
+	zc = kmem_alloc(sizeof (zap_cursor_t), KM_SLEEP);
+	za = kmem_alloc(sizeof (zap_attribute_t), KM_SLEEP);
+
+	/* keep pulling things out of the zap-object-as-queue */
+	while (zap_cursor_init(zc, dp->dp_meta_objset,
+	    scn->scn_phys.scn_queue_obj),
+	    zap_cursor_retrieve(zc, za) == 0) {
+		dsl_dataset_t *ds;
+		uint64_t dsobj;
+
+		dsobj = strtonum(za->za_name, NULL);
+		VERIFY3U(0, ==, zap_remove_int(dp->dp_meta_objset,
+		    scn->scn_phys.scn_queue_obj, dsobj, tx));
+
+		/* Set up min/max txg */
+		VERIFY3U(0, ==, dsl_dataset_hold_obj(dp, dsobj, FTAG, &ds));
+		if (za->za_first_integer != 0) {
+			scn->scn_phys.scn_cur_min_txg =
+			    MAX(scn->scn_phys.scn_min_txg,
+			    za->za_first_integer);
+		} else {
+			scn->scn_phys.scn_cur_min_txg =
+			    MAX(scn->scn_phys.scn_min_txg,
+			    dsl_dataset_phys(ds)->ds_prev_snap_txg);
+		}
+		scn->scn_phys.scn_cur_max_txg = dsl_scan_ds_maxtxg(ds);
+		dsl_dataset_rele(ds, FTAG);
+
+		dsl_scan_visitds(scn, dsobj, tx);
+		zap_cursor_fini(zc);
+		if (scn->scn_pausing)
+			goto out;
+	}
+	zap_cursor_fini(zc);
+out:
+	kmem_free(za, sizeof (zap_attribute_t));
+	kmem_free(zc, sizeof (zap_cursor_t));
+}
+
+static boolean_t
+dsl_scan_free_should_pause(dsl_scan_t *scn)
+{
+	uint64_t elapsed_nanosecs;
+
+	if (zfs_recover)
+		return (B_FALSE);
+
+	if (scn->scn_visited_this_txg >= zfs_free_max_blocks)
+		return (B_TRUE);
+
+	elapsed_nanosecs = gethrtime() - scn->scn_sync_start_time;
+	return (elapsed_nanosecs / NANOSEC > zfs_txg_timeout ||
+	    (NSEC2MSEC(elapsed_nanosecs) > zfs_free_min_time_ms &&
+	    txg_sync_waiting(scn->scn_dp)) ||
+	    spa_shutting_down(scn->scn_dp->dp_spa));
+}
+
+static int
+dsl_scan_free_block_cb(void *arg, const blkptr_t *bp, dmu_tx_t *tx)
+{
+	dsl_scan_t *scn = arg;
+
+	if (!scn->scn_is_bptree ||
+	    (BP_GET_LEVEL(bp) == 0 && BP_GET_TYPE(bp) != DMU_OT_OBJSET)) {
+		if (dsl_scan_free_should_pause(scn))
+			return (SET_ERROR(ERESTART));
+	}
+
+	zio_nowait(zio_free_sync(scn->scn_zio_root, scn->scn_dp->dp_spa,
+	    dmu_tx_get_txg(tx), bp, 0));
+	dsl_dir_diduse_space(tx->tx_pool->dp_free_dir, DD_USED_HEAD,
+	    -bp_get_dsize_sync(scn->scn_dp->dp_spa, bp),
+	    -BP_GET_PSIZE(bp), -BP_GET_UCSIZE(bp), tx);
+	scn->scn_visited_this_txg++;
+	return (0);
+}
+
+boolean_t
+dsl_scan_active(dsl_scan_t *scn)
+{
+	spa_t *spa = scn->scn_dp->dp_spa;
+	uint64_t used = 0, comp, uncomp;
+
+	if (spa->spa_load_state != SPA_LOAD_NONE)
+		return (B_FALSE);
+	if (spa_shutting_down(spa))
+		return (B_FALSE);
+	if (scn->scn_phys.scn_state == DSS_SCANNING ||
+	    (scn->scn_async_destroying && !scn->scn_async_stalled))
+		return (B_TRUE);
+
+	if (spa_version(scn->scn_dp->dp_spa) >= SPA_VERSION_DEADLISTS) {
+		(void) bpobj_space(&scn->scn_dp->dp_free_bpobj,
+		    &used, &comp, &uncomp);
+	}
+	return (used != 0);
+}
+
+void
+dsl_scan_sync(dsl_pool_t *dp, dmu_tx_t *tx)
+{
+	dsl_scan_t *scn = dp->dp_scan;
+	spa_t *spa = dp->dp_spa;
+	int err = 0;
+
+	/*
+	 * Check for scn_restart_txg before checking spa_load_state, so
+	 * that we can restart an old-style scan while the pool is being
+	 * imported (see dsl_scan_init).
+	 */
+	if (scn->scn_restart_txg != 0 &&
+	    scn->scn_restart_txg <= tx->tx_txg) {
+		pool_scan_func_t func = POOL_SCAN_SCRUB;
+		dsl_scan_done(scn, B_FALSE, tx);
+		if (vdev_resilver_needed(spa->spa_root_vdev, NULL, NULL))
+			func = POOL_SCAN_RESILVER;
+		zfs_dbgmsg("restarting scan func=%u txg=%llu",
+		    func, tx->tx_txg);
+		dsl_scan_setup_sync(&func, tx);
+	}
+
+	/*
+	 * If the scan is inactive due to a stalled async destroy, try again.
+	 */
+	if ((!scn->scn_async_stalled && !dsl_scan_active(scn)) ||
+	    spa_sync_pass(dp->dp_spa) > 1)
+		return;
+
+	scn->scn_visited_this_txg = 0;
+	scn->scn_pausing = B_FALSE;
+	scn->scn_sync_start_time = gethrtime();
+	spa->spa_scrub_active = B_TRUE;
+
+	/*
+	 * First process the async destroys.  If we pause, don't do
+	 * any scrubbing or resilvering.  This ensures that there are no
+	 * async destroys while we are scanning, so the scan code doesn't
+	 * have to worry about traversing it.  It is also faster to free the
+	 * blocks than to scrub them.
+	 */
+	if (spa_version(dp->dp_spa) >= SPA_VERSION_DEADLISTS) {
+		scn->scn_is_bptree = B_FALSE;
+		scn->scn_zio_root = zio_root(dp->dp_spa, NULL,
+		    NULL, ZIO_FLAG_MUSTSUCCEED);
+		err = bpobj_iterate(&dp->dp_free_bpobj,
+		    dsl_scan_free_block_cb, scn, tx);
+		VERIFY3U(0, ==, zio_wait(scn->scn_zio_root));
+
+		if (err != 0 && err != ERESTART)
+			zfs_panic_recover("error %u from bpobj_iterate()", err);
+	}
+
+	if (err == 0 && spa_feature_is_active(spa, SPA_FEATURE_ASYNC_DESTROY)) {
+		ASSERT(scn->scn_async_destroying);
+		scn->scn_is_bptree = B_TRUE;
+		scn->scn_zio_root = zio_root(dp->dp_spa, NULL,
+		    NULL, ZIO_FLAG_MUSTSUCCEED);
+		err = bptree_iterate(dp->dp_meta_objset,
+		    dp->dp_bptree_obj, B_TRUE, dsl_scan_free_block_cb, scn, tx);
+		VERIFY0(zio_wait(scn->scn_zio_root));
+
+		if (err == EIO || err == ECKSUM) {
+			err = 0;
+		} else if (err != 0 && err != ERESTART) {
+			zfs_panic_recover("error %u from "
+			    "traverse_dataset_destroyed()", err);
+		}
+
+		if (bptree_is_empty(dp->dp_meta_objset, dp->dp_bptree_obj)) {
+			/* finished; deactivate async destroy feature */
+			spa_feature_decr(spa, SPA_FEATURE_ASYNC_DESTROY, tx);
+			ASSERT(!spa_feature_is_active(spa,
+			    SPA_FEATURE_ASYNC_DESTROY));
+			VERIFY0(zap_remove(dp->dp_meta_objset,
+			    DMU_POOL_DIRECTORY_OBJECT,
+			    DMU_POOL_BPTREE_OBJ, tx));
+			VERIFY0(bptree_free(dp->dp_meta_objset,
+			    dp->dp_bptree_obj, tx));
+			dp->dp_bptree_obj = 0;
+			scn->scn_async_destroying = B_FALSE;
+			scn->scn_async_stalled = B_FALSE;
+		} else {
+			/*
+			 * If we didn't make progress, mark the async
+			 * destroy as stalled, so that we will not initiate
+			 * a spa_sync() on its behalf.  Note that we only
+			 * check this if we are not finished, because if the
+			 * bptree had no blocks for us to visit, we can
+			 * finish without "making progress".
+			 */
+			scn->scn_async_stalled =
+			    (scn->scn_visited_this_txg == 0);
+		}
+	}
+	if (scn->scn_visited_this_txg) {
+		zfs_dbgmsg("freed %llu blocks in %llums from "
+		    "free_bpobj/bptree txg %llu; err=%u",
+		    (longlong_t)scn->scn_visited_this_txg,
+		    (longlong_t)
+		    NSEC2MSEC(gethrtime() - scn->scn_sync_start_time),
+		    (longlong_t)tx->tx_txg, err);
+		scn->scn_visited_this_txg = 0;
+
+		/*
+		 * Write out changes to the DDT that may be required as a
+		 * result of the blocks freed.  This ensures that the DDT
+		 * is clean when a scrub/resilver runs.
+		 */
+		ddt_sync(spa, tx->tx_txg);
+	}
+	if (err != 0)
+		return;
+	if (!scn->scn_async_destroying && zfs_free_leak_on_eio &&
+	    (dsl_dir_phys(dp->dp_free_dir)->dd_used_bytes != 0 ||
+	    dsl_dir_phys(dp->dp_free_dir)->dd_compressed_bytes != 0 ||
+	    dsl_dir_phys(dp->dp_free_dir)->dd_uncompressed_bytes != 0)) {
+		/*
+		 * We have finished background destroying, but there is still
+		 * some space left in the dp_free_dir. Transfer this leaked
+		 * space to the dp_leak_dir.
+		 */
+		if (dp->dp_leak_dir == NULL) {
+			rrw_enter(&dp->dp_config_rwlock, RW_WRITER, FTAG);
+			(void) dsl_dir_create_sync(dp, dp->dp_root_dir,
+			    LEAK_DIR_NAME, tx);
+			VERIFY0(dsl_pool_open_special_dir(dp,
+			    LEAK_DIR_NAME, &dp->dp_leak_dir));
+			rrw_exit(&dp->dp_config_rwlock, FTAG);
+		}
+		dsl_dir_diduse_space(dp->dp_leak_dir, DD_USED_HEAD,
+		    dsl_dir_phys(dp->dp_free_dir)->dd_used_bytes,
+		    dsl_dir_phys(dp->dp_free_dir)->dd_compressed_bytes,
+		    dsl_dir_phys(dp->dp_free_dir)->dd_uncompressed_bytes, tx);
+		dsl_dir_diduse_space(dp->dp_free_dir, DD_USED_HEAD,
+		    -dsl_dir_phys(dp->dp_free_dir)->dd_used_bytes,
+		    -dsl_dir_phys(dp->dp_free_dir)->dd_compressed_bytes,
+		    -dsl_dir_phys(dp->dp_free_dir)->dd_uncompressed_bytes, tx);
+	}
+	if (!scn->scn_async_destroying) {
+		/* finished; verify that space accounting went to zero */
+		ASSERT0(dsl_dir_phys(dp->dp_free_dir)->dd_used_bytes);
+		ASSERT0(dsl_dir_phys(dp->dp_free_dir)->dd_compressed_bytes);
+		ASSERT0(dsl_dir_phys(dp->dp_free_dir)->dd_uncompressed_bytes);
+	}
+
+	if (scn->scn_phys.scn_state != DSS_SCANNING)
+		return;
+
+	if (scn->scn_done_txg == tx->tx_txg) {
+		ASSERT(!scn->scn_pausing);
+		/* finished with scan. */
+		zfs_dbgmsg("txg %llu scan complete", tx->tx_txg);
+		dsl_scan_done(scn, B_TRUE, tx);
+		ASSERT3U(spa->spa_scrub_inflight, ==, 0);
+		dsl_scan_sync_state(scn, tx);
+		return;
+	}
+
+	if (scn->scn_phys.scn_ddt_bookmark.ddb_class <=
+	    scn->scn_phys.scn_ddt_class_max) {
+		zfs_dbgmsg("doing scan sync txg %llu; "
+		    "ddt bm=%llu/%llu/%llu/%llx",
+		    (longlong_t)tx->tx_txg,
+		    (longlong_t)scn->scn_phys.scn_ddt_bookmark.ddb_class,
+		    (longlong_t)scn->scn_phys.scn_ddt_bookmark.ddb_type,
+		    (longlong_t)scn->scn_phys.scn_ddt_bookmark.ddb_checksum,
+		    (longlong_t)scn->scn_phys.scn_ddt_bookmark.ddb_cursor);
+		ASSERT(scn->scn_phys.scn_bookmark.zb_objset == 0);
+		ASSERT(scn->scn_phys.scn_bookmark.zb_object == 0);
+		ASSERT(scn->scn_phys.scn_bookmark.zb_level == 0);
+		ASSERT(scn->scn_phys.scn_bookmark.zb_blkid == 0);
+	} else {
+		zfs_dbgmsg("doing scan sync txg %llu; bm=%llu/%llu/%llu/%llu",
+		    (longlong_t)tx->tx_txg,
+		    (longlong_t)scn->scn_phys.scn_bookmark.zb_objset,
+		    (longlong_t)scn->scn_phys.scn_bookmark.zb_object,
+		    (longlong_t)scn->scn_phys.scn_bookmark.zb_level,
+		    (longlong_t)scn->scn_phys.scn_bookmark.zb_blkid);
+	}
+
+	scn->scn_zio_root = zio_root(dp->dp_spa, NULL,
+	    NULL, ZIO_FLAG_CANFAIL);
+	dsl_pool_config_enter(dp, FTAG);
+	dsl_scan_visit(scn, tx);
+	dsl_pool_config_exit(dp, FTAG);
+	(void) zio_wait(scn->scn_zio_root);
+	scn->scn_zio_root = NULL;
+
+	zfs_dbgmsg("visited %llu blocks in %llums",
+	    (longlong_t)scn->scn_visited_this_txg,
+	    (longlong_t)NSEC2MSEC(gethrtime() - scn->scn_sync_start_time));
+
+	if (!scn->scn_pausing) {
+		scn->scn_done_txg = tx->tx_txg + 1;
+		zfs_dbgmsg("txg %llu traversal complete, waiting till txg %llu",
+		    tx->tx_txg, scn->scn_done_txg);
+	}
+
+	if (DSL_SCAN_IS_SCRUB_RESILVER(scn)) {
+		mutex_enter(&spa->spa_scrub_lock);
+		while (spa->spa_scrub_inflight > 0) {
+			cv_wait(&spa->spa_scrub_io_cv,
+			    &spa->spa_scrub_lock);
+		}
+		mutex_exit(&spa->spa_scrub_lock);
+	}
+
+	dsl_scan_sync_state(scn, tx);
+}
+
+/*
+ * This will start a new scan, or restart an existing one.
+ */
+void
+dsl_resilver_restart(dsl_pool_t *dp, uint64_t txg)
+{
+	if (txg == 0) {
+		dmu_tx_t *tx;
+		tx = dmu_tx_create_dd(dp->dp_mos_dir);
+		VERIFY(0 == dmu_tx_assign(tx, TXG_WAIT));
+
+		txg = dmu_tx_get_txg(tx);
+		dp->dp_scan->scn_restart_txg = txg;
+		dmu_tx_commit(tx);
+	} else {
+		dp->dp_scan->scn_restart_txg = txg;
+	}
+	zfs_dbgmsg("restarting resilver txg=%llu", txg);
+}
+
+boolean_t
+dsl_scan_resilvering(dsl_pool_t *dp)
+{
+	return (dp->dp_scan->scn_phys.scn_state == DSS_SCANNING &&
+	    dp->dp_scan->scn_phys.scn_func == POOL_SCAN_RESILVER);
+}
+
+/*
+ * scrub consumers
+ */
+
+static void
+count_block(zfs_all_blkstats_t *zab, const blkptr_t *bp)
+{
+	int i;
+
+	/*
+	 * If we resume after a reboot, zab will be NULL; don't record
+	 * incomplete stats in that case.
+	 */
+	if (zab == NULL)
+		return;
+
+	for (i = 0; i < 4; i++) {
+		int l = (i < 2) ? BP_GET_LEVEL(bp) : DN_MAX_LEVELS;
+		int t = (i & 1) ? BP_GET_TYPE(bp) : DMU_OT_TOTAL;
+		int equal;
+		zfs_blkstat_t *zb;
+
+		if (t & DMU_OT_NEWTYPE)
+			t = DMU_OT_OTHER;
+
+		zb = &zab->zab_type[l][t];
+		zb->zb_count++;
+		zb->zb_asize += BP_GET_ASIZE(bp);
+		zb->zb_lsize += BP_GET_LSIZE(bp);
+		zb->zb_psize += BP_GET_PSIZE(bp);
+		zb->zb_gangs += BP_COUNT_GANG(bp);
+
+		switch (BP_GET_NDVAS(bp)) {
+		case 2:
+			if (DVA_GET_VDEV(&bp->blk_dva[0]) ==
+			    DVA_GET_VDEV(&bp->blk_dva[1]))
+				zb->zb_ditto_2_of_2_samevdev++;
+			break;
+		case 3:
+			equal = (DVA_GET_VDEV(&bp->blk_dva[0]) ==
+			    DVA_GET_VDEV(&bp->blk_dva[1])) +
+			    (DVA_GET_VDEV(&bp->blk_dva[0]) ==
+			    DVA_GET_VDEV(&bp->blk_dva[2])) +
+			    (DVA_GET_VDEV(&bp->blk_dva[1]) ==
+			    DVA_GET_VDEV(&bp->blk_dva[2]));
+			if (equal == 1)
+				zb->zb_ditto_2_of_3_samevdev++;
+			else if (equal == 3)
+				zb->zb_ditto_3_of_3_samevdev++;
+			break;
+		}
+	}
+}
+
+static void
+dsl_scan_scrub_done(zio_t *zio)
+{
+	spa_t *spa = zio->io_spa;
+
+	zio_data_buf_free(zio->io_data, zio->io_size);
+
+	mutex_enter(&spa->spa_scrub_lock);
+	spa->spa_scrub_inflight--;
+	cv_broadcast(&spa->spa_scrub_io_cv);
+
+	if (zio->io_error && (zio->io_error != ECKSUM ||
+	    !(zio->io_flags & ZIO_FLAG_SPECULATIVE))) {
+		spa->spa_dsl_pool->dp_scan->scn_phys.scn_errors++;
+	}
+	mutex_exit(&spa->spa_scrub_lock);
+}
+
+static int
+dsl_scan_scrub_cb(dsl_pool_t *dp,
+    const blkptr_t *bp, const zbookmark_phys_t *zb)
+{
+	dsl_scan_t *scn = dp->dp_scan;
+	size_t size = BP_GET_PSIZE(bp);
+	spa_t *spa = dp->dp_spa;
+	uint64_t phys_birth = BP_PHYSICAL_BIRTH(bp);
+	boolean_t needs_io = B_FALSE;
+	int zio_flags = ZIO_FLAG_SCAN_THREAD | ZIO_FLAG_RAW | ZIO_FLAG_CANFAIL;
+	int scan_delay = 0;
+	int d;
+
+	if (phys_birth <= scn->scn_phys.scn_min_txg ||
+	    phys_birth >= scn->scn_phys.scn_max_txg)
+		return (0);
+
+	count_block(dp->dp_blkstats, bp);
+
+	if (BP_IS_EMBEDDED(bp))
+		return (0);
+
+	ASSERT(DSL_SCAN_IS_SCRUB_RESILVER(scn));
+	if (scn->scn_phys.scn_func == POOL_SCAN_SCRUB) {
+		zio_flags |= ZIO_FLAG_SCRUB;
+		needs_io = B_TRUE;
+		scan_delay = zfs_scrub_delay;
+	} else {
+		ASSERT3U(scn->scn_phys.scn_func, ==, POOL_SCAN_RESILVER);
+		zio_flags |= ZIO_FLAG_RESILVER;
+		needs_io = B_FALSE;
+		scan_delay = zfs_resilver_delay;
+	}
+
+	/* If it's an intent log block, failure is expected. */
+	if (zb->zb_level == ZB_ZIL_LEVEL)
+		zio_flags |= ZIO_FLAG_SPECULATIVE;
+
+	for (d = 0; d < BP_GET_NDVAS(bp); d++) {
+		vdev_t *vd = vdev_lookup_top(spa,
+		    DVA_GET_VDEV(&bp->blk_dva[d]));
+
+		/*
+		 * Keep track of how much data we've examined so that
+		 * zpool(1M) status can make useful progress reports.
+		 */
+		scn->scn_phys.scn_examined += DVA_GET_ASIZE(&bp->blk_dva[d]);
+		spa->spa_scan_pass_exam += DVA_GET_ASIZE(&bp->blk_dva[d]);
+
+		/* if it's a resilver, this may not be in the target range */
+		if (!needs_io) {
+			if (DVA_GET_GANG(&bp->blk_dva[d])) {
+				/*
+				 * Gang members may be spread across multiple
+				 * vdevs, so the best estimate we have is the
+				 * scrub range, which has already been checked.
+				 * XXX -- it would be better to change our
+				 * allocation policy to ensure that all
+				 * gang members reside on the same vdev.
+				 */
+				needs_io = B_TRUE;
+			} else {
+				needs_io = vdev_dtl_contains(vd, DTL_PARTIAL,
+				    phys_birth, 1);
+			}
+		}
+	}
+
+	if (needs_io && !zfs_no_scrub_io) {
+		vdev_t *rvd = spa->spa_root_vdev;
+		uint64_t maxinflight = rvd->vdev_children * zfs_top_maxinflight;
+		void *data = zio_data_buf_alloc(size);
+
+		mutex_enter(&spa->spa_scrub_lock);
+		while (spa->spa_scrub_inflight >= maxinflight)
+			cv_wait(&spa->spa_scrub_io_cv, &spa->spa_scrub_lock);
+		spa->spa_scrub_inflight++;
+		mutex_exit(&spa->spa_scrub_lock);
+
+		/*
+		 * If we're seeing recent (zfs_scan_idle) "important" I/Os
+		 * then throttle our workload to limit the impact of a scan.
+		 */
+		if (ddi_get_lbolt64() - spa->spa_last_io <= zfs_scan_idle)
+			delay(scan_delay);
+
+		zio_nowait(zio_read(NULL, spa, bp, data, size,
+		    dsl_scan_scrub_done, NULL, ZIO_PRIORITY_SCRUB,
+		    zio_flags, zb));
+	}
+
+	/* do not relocate this block */
+	return (0);
+}
+
+int
+dsl_scan(dsl_pool_t *dp, pool_scan_func_t func)
+{
+	spa_t *spa = dp->dp_spa;
+
+	/*
+	 * Purge all vdev caches and probe all devices.  We do this here
+	 * rather than in sync context because this requires a writer lock
+	 * on the spa_config lock, which we can't do from sync context.  The
+	 * spa_scrub_reopen flag indicates that vdev_open() should not
+	 * attempt to start another scrub.
+	 */
+	spa_vdev_state_enter(spa, SCL_NONE);
+	spa->spa_scrub_reopen = B_TRUE;
+	vdev_reopen(spa->spa_root_vdev);
+	spa->spa_scrub_reopen = B_FALSE;
+	(void) spa_vdev_state_exit(spa, NULL, 0);
+
+	return (dsl_sync_task(spa_name(spa), dsl_scan_setup_check,
+	    dsl_scan_setup_sync, &func, 0, ZFS_SPACE_CHECK_NONE));
+}
+
+#if defined(_KERNEL) && defined(HAVE_SPL)
+module_param(zfs_top_maxinflight, int, 0644);
+MODULE_PARM_DESC(zfs_top_maxinflight, "Max I/Os per top-level");
+
+module_param(zfs_resilver_delay, int, 0644);
+MODULE_PARM_DESC(zfs_resilver_delay, "Number of ticks to delay resilver");
+
+module_param(zfs_scrub_delay, int, 0644);
+MODULE_PARM_DESC(zfs_scrub_delay, "Number of ticks to delay scrub");
+
+module_param(zfs_scan_idle, int, 0644);
+MODULE_PARM_DESC(zfs_scan_idle, "Idle window in clock ticks");
+
+module_param(zfs_scan_min_time_ms, int, 0644);
+MODULE_PARM_DESC(zfs_scan_min_time_ms, "Min millisecs to scrub per txg");
+
+module_param(zfs_free_min_time_ms, int, 0644);
+MODULE_PARM_DESC(zfs_free_min_time_ms, "Min millisecs to free per txg");
+
+module_param(zfs_resilver_min_time_ms, int, 0644);
+MODULE_PARM_DESC(zfs_resilver_min_time_ms, "Min millisecs to resilver per txg");
+
+module_param(zfs_no_scrub_io, int, 0644);
+MODULE_PARM_DESC(zfs_no_scrub_io, "Set to disable scrub I/O");
+
+module_param(zfs_no_scrub_prefetch, int, 0644);
+MODULE_PARM_DESC(zfs_no_scrub_prefetch, "Set to disable scrub prefetching");
+
+module_param(zfs_free_max_blocks, ulong, 0644);
+MODULE_PARM_DESC(zfs_free_max_blocks, "Max number of blocks freed in one txg");
+#endif
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/module/zfs/dsl_synctask.c
@@ -0,0 +1,191 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2014 by Delphix. All rights reserved.
+ */
+
+#include <sys/dmu.h>
+#include <sys/dmu_tx.h>
+#include <sys/dsl_pool.h>
+#include <sys/dsl_dir.h>
+#include <sys/dsl_synctask.h>
+#include <sys/metaslab.h>
+
+#define	DST_AVG_BLKSHIFT 14
+
+/* ARGSUSED */
+static int
+dsl_null_checkfunc(void *arg, dmu_tx_t *tx)
+{
+	return (0);
+}
+
+/*
+ * Called from open context to perform a callback in syncing context.  Waits
+ * for the operation to complete.
+ *
+ * The checkfunc will be called from open context as a preliminary check
+ * which can quickly fail.  If it succeeds, it will be called again from
+ * syncing context.  The checkfunc should generally be designed to work
+ * properly in either context, but if necessary it can check
+ * dmu_tx_is_syncing(tx).
+ *
+ * The synctask infrastructure enforces proper locking strategy with respect
+ * to the dp_config_rwlock -- the lock will always be held when the callbacks
+ * are called.  It will be held for read during the open-context (preliminary)
+ * call to the checkfunc, and then held for write from syncing context during
+ * the calls to the check and sync funcs.
+ *
+ * A dataset or pool name can be passed as the first argument.  Typically,
+ * the check func will hold, check the return value of the hold, and then
+ * release the dataset.  The sync func will VERIFYO(hold()) the dataset.
+ * This is safe because no changes can be made between the check and sync funcs,
+ * and the sync func will only be called if the check func successfully opened
+ * the dataset.
+ */
+int
+dsl_sync_task(const char *pool, dsl_checkfunc_t *checkfunc,
+    dsl_syncfunc_t *syncfunc, void *arg,
+    int blocks_modified, zfs_space_check_t space_check)
+{
+	spa_t *spa;
+	dmu_tx_t *tx;
+	int err;
+	dsl_sync_task_t dst = { { { NULL } } };
+	dsl_pool_t *dp;
+
+	err = spa_open(pool, &spa, FTAG);
+	if (err != 0)
+		return (err);
+	dp = spa_get_dsl(spa);
+
+top:
+	tx = dmu_tx_create_dd(dp->dp_mos_dir);
+	VERIFY0(dmu_tx_assign(tx, TXG_WAIT));
+
+	dst.dst_pool = dp;
+	dst.dst_txg = dmu_tx_get_txg(tx);
+	dst.dst_space = blocks_modified << DST_AVG_BLKSHIFT;
+	dst.dst_space_check = space_check;
+	dst.dst_checkfunc = checkfunc != NULL ? checkfunc : dsl_null_checkfunc;
+	dst.dst_syncfunc = syncfunc;
+	dst.dst_arg = arg;
+	dst.dst_error = 0;
+	dst.dst_nowaiter = B_FALSE;
+
+	dsl_pool_config_enter(dp, FTAG);
+	err = dst.dst_checkfunc(arg, tx);
+	dsl_pool_config_exit(dp, FTAG);
+
+	if (err != 0) {
+		dmu_tx_commit(tx);
+		spa_close(spa, FTAG);
+		return (err);
+	}
+
+	VERIFY(txg_list_add_tail(&dp->dp_sync_tasks, &dst, dst.dst_txg));
+
+	dmu_tx_commit(tx);
+
+	txg_wait_synced(dp, dst.dst_txg);
+
+	if (dst.dst_error == EAGAIN) {
+		txg_wait_synced(dp, dst.dst_txg + TXG_DEFER_SIZE);
+		goto top;
+	}
+
+	spa_close(spa, FTAG);
+	return (dst.dst_error);
+}
+
+void
+dsl_sync_task_nowait(dsl_pool_t *dp, dsl_syncfunc_t *syncfunc, void *arg,
+    int blocks_modified, zfs_space_check_t space_check, dmu_tx_t *tx)
+{
+	dsl_sync_task_t *dst = kmem_zalloc(sizeof (*dst), KM_SLEEP);
+
+	dst->dst_pool = dp;
+	dst->dst_txg = dmu_tx_get_txg(tx);
+	dst->dst_space = blocks_modified << DST_AVG_BLKSHIFT;
+	dst->dst_space_check = space_check;
+	dst->dst_checkfunc = dsl_null_checkfunc;
+	dst->dst_syncfunc = syncfunc;
+	dst->dst_arg = arg;
+	dst->dst_error = 0;
+	dst->dst_nowaiter = B_TRUE;
+
+	VERIFY(txg_list_add_tail(&dp->dp_sync_tasks, dst, dst->dst_txg));
+}
+
+/*
+ * Called in syncing context to execute the synctask.
+ */
+void
+dsl_sync_task_sync(dsl_sync_task_t *dst, dmu_tx_t *tx)
+{
+	dsl_pool_t *dp = dst->dst_pool;
+
+	ASSERT0(dst->dst_error);
+
+	/*
+	 * Check for sufficient space.
+	 *
+	 * When the sync task was created, the caller specified the
+	 * type of space checking required.  See the comment in
+	 * zfs_space_check_t for details on the semantics of each
+	 * type of space checking.
+	 *
+	 * We just check against what's on-disk; we don't want any
+	 * in-flight accounting to get in our way, because open context
+	 * may have already used up various in-core limits
+	 * (arc_tempreserve, dsl_pool_tempreserve).
+	 */
+	if (dst->dst_space_check != ZFS_SPACE_CHECK_NONE) {
+		uint64_t quota = dsl_pool_adjustedsize(dp,
+		    dst->dst_space_check == ZFS_SPACE_CHECK_RESERVED) -
+		    metaslab_class_get_deferred(spa_normal_class(dp->dp_spa));
+		uint64_t used = dsl_dir_phys(dp->dp_root_dir)->dd_used_bytes;
+		/* MOS space is triple-dittoed, so we multiply by 3. */
+		if (dst->dst_space > 0 && used + dst->dst_space * 3 > quota) {
+			dst->dst_error = SET_ERROR(ENOSPC);
+			if (dst->dst_nowaiter)
+				kmem_free(dst, sizeof (*dst));
+			return;
+		}
+	}
+
+	/*
+	 * Check for errors by calling checkfunc.
+	 */
+	rrw_enter(&dp->dp_config_rwlock, RW_WRITER, FTAG);
+	dst->dst_error = dst->dst_checkfunc(dst->dst_arg, tx);
+	if (dst->dst_error == 0)
+		dst->dst_syncfunc(dst->dst_arg, tx);
+	rrw_exit(&dp->dp_config_rwlock, FTAG);
+	if (dst->dst_nowaiter)
+		kmem_free(dst, sizeof (*dst));
+}
+
+#if defined(_KERNEL) && defined(HAVE_SPL)
+EXPORT_SYMBOL(dsl_sync_task);
+EXPORT_SYMBOL(dsl_sync_task_nowait);
+#endif
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/module/zfs/dsl_userhold.c
@@ -0,0 +1,674 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2014 by Delphix. All rights reserved.
+ * Copyright (c) 2013 Steven Hartland. All rights reserved.
+ */
+
+#include <sys/zfs_context.h>
+#include <sys/dsl_userhold.h>
+#include <sys/dsl_dataset.h>
+#include <sys/dsl_destroy.h>
+#include <sys/dsl_synctask.h>
+#include <sys/dmu_tx.h>
+#include <sys/zfs_onexit.h>
+#include <sys/dsl_pool.h>
+#include <sys/dsl_dir.h>
+#include <sys/zfs_ioctl.h>
+#include <sys/zap.h>
+
+typedef struct dsl_dataset_user_hold_arg {
+	nvlist_t *dduha_holds;
+	nvlist_t *dduha_chkholds;
+	nvlist_t *dduha_errlist;
+	minor_t dduha_minor;
+} dsl_dataset_user_hold_arg_t;
+
+/*
+ * If you add new checks here, you may need to add additional checks to the
+ * "temporary" case in snapshot_check() in dmu_objset.c.
+ */
+int
+dsl_dataset_user_hold_check_one(dsl_dataset_t *ds, const char *htag,
+    boolean_t temphold, dmu_tx_t *tx)
+{
+	dsl_pool_t *dp = dmu_tx_pool(tx);
+	objset_t *mos = dp->dp_meta_objset;
+	int error = 0;
+
+	ASSERT(dsl_pool_config_held(dp));
+
+	if (strlen(htag) > MAXNAMELEN)
+		return (SET_ERROR(E2BIG));
+	/* Tempholds have a more restricted length */
+	if (temphold && strlen(htag) + MAX_TAG_PREFIX_LEN >= MAXNAMELEN)
+		return (SET_ERROR(E2BIG));
+
+	/* tags must be unique (if ds already exists) */
+	if (ds != NULL && dsl_dataset_phys(ds)->ds_userrefs_obj != 0) {
+		uint64_t value;
+
+		error = zap_lookup(mos, dsl_dataset_phys(ds)->ds_userrefs_obj,
+		    htag, 8, 1, &value);
+		if (error == 0)
+			error = SET_ERROR(EEXIST);
+		else if (error == ENOENT)
+			error = 0;
+	}
+
+	return (error);
+}
+
+static int
+dsl_dataset_user_hold_check(void *arg, dmu_tx_t *tx)
+{
+	dsl_dataset_user_hold_arg_t *dduha = arg;
+	dsl_pool_t *dp = dmu_tx_pool(tx);
+	nvpair_t *pair;
+
+	if (spa_version(dp->dp_spa) < SPA_VERSION_USERREFS)
+		return (SET_ERROR(ENOTSUP));
+
+	if (!dmu_tx_is_syncing(tx))
+		return (0);
+
+	for (pair = nvlist_next_nvpair(dduha->dduha_holds, NULL);
+	    pair != NULL; pair = nvlist_next_nvpair(dduha->dduha_holds, pair)) {
+		dsl_dataset_t *ds;
+		int error = 0;
+		char *htag, *name;
+
+		/* must be a snapshot */
+		name = nvpair_name(pair);
+		if (strchr(name, '@') == NULL)
+			error = SET_ERROR(EINVAL);
+
+		if (error == 0)
+			error = nvpair_value_string(pair, &htag);
+
+		if (error == 0)
+			error = dsl_dataset_hold(dp, name, FTAG, &ds);
+
+		if (error == 0) {
+			error = dsl_dataset_user_hold_check_one(ds, htag,
+			    dduha->dduha_minor != 0, tx);
+			dsl_dataset_rele(ds, FTAG);
+		}
+
+		if (error == 0) {
+			fnvlist_add_string(dduha->dduha_chkholds, name, htag);
+		} else {
+			/*
+			 * We register ENOENT errors so they can be correctly
+			 * reported if needed, such as when all holds fail.
+			 */
+			fnvlist_add_int32(dduha->dduha_errlist, name, error);
+			if (error != ENOENT)
+				return (error);
+		}
+	}
+
+	return (0);
+}
+
+
+static void
+dsl_dataset_user_hold_sync_one_impl(nvlist_t *tmpholds, dsl_dataset_t *ds,
+    const char *htag, minor_t minor, uint64_t now, dmu_tx_t *tx)
+{
+	dsl_pool_t *dp = ds->ds_dir->dd_pool;
+	objset_t *mos = dp->dp_meta_objset;
+	uint64_t zapobj;
+
+	ASSERT(RRW_WRITE_HELD(&dp->dp_config_rwlock));
+
+	if (dsl_dataset_phys(ds)->ds_userrefs_obj == 0) {
+		/*
+		 * This is the first user hold for this dataset.  Create
+		 * the userrefs zap object.
+		 */
+		dmu_buf_will_dirty(ds->ds_dbuf, tx);
+		zapobj = dsl_dataset_phys(ds)->ds_userrefs_obj =
+		    zap_create(mos, DMU_OT_USERREFS, DMU_OT_NONE, 0, tx);
+	} else {
+		zapobj = dsl_dataset_phys(ds)->ds_userrefs_obj;
+	}
+	ds->ds_userrefs++;
+
+	VERIFY0(zap_add(mos, zapobj, htag, 8, 1, &now, tx));
+
+	if (minor != 0) {
+		char name[MAXNAMELEN];
+		nvlist_t *tags;
+
+		VERIFY0(dsl_pool_user_hold(dp, ds->ds_object,
+		    htag, now, tx));
+		(void) snprintf(name, sizeof (name), "%llx",
+		    (u_longlong_t)ds->ds_object);
+
+		if (nvlist_lookup_nvlist(tmpholds, name, &tags) != 0) {
+			tags = fnvlist_alloc();
+			fnvlist_add_boolean(tags, htag);
+			fnvlist_add_nvlist(tmpholds, name, tags);
+			fnvlist_free(tags);
+		} else {
+			fnvlist_add_boolean(tags, htag);
+		}
+	}
+
+	spa_history_log_internal_ds(ds, "hold", tx,
+	    "tag=%s temp=%d refs=%llu",
+	    htag, minor != 0, ds->ds_userrefs);
+}
+
+typedef struct zfs_hold_cleanup_arg {
+	char zhca_spaname[MAXNAMELEN];
+	uint64_t zhca_spa_load_guid;
+	nvlist_t *zhca_holds;
+} zfs_hold_cleanup_arg_t;
+
+static void
+dsl_dataset_user_release_onexit(void *arg)
+{
+	zfs_hold_cleanup_arg_t *ca = arg;
+	spa_t *spa;
+	int error;
+
+	error = spa_open(ca->zhca_spaname, &spa, FTAG);
+	if (error != 0) {
+		zfs_dbgmsg("couldn't release holds on pool=%s "
+		    "because pool is no longer loaded",
+		    ca->zhca_spaname);
+		return;
+	}
+	if (spa_load_guid(spa) != ca->zhca_spa_load_guid) {
+		zfs_dbgmsg("couldn't release holds on pool=%s "
+		    "because pool is no longer loaded (guid doesn't match)",
+		    ca->zhca_spaname);
+		spa_close(spa, FTAG);
+		return;
+	}
+
+	(void) dsl_dataset_user_release_tmp(spa_get_dsl(spa), ca->zhca_holds);
+	fnvlist_free(ca->zhca_holds);
+	kmem_free(ca, sizeof (zfs_hold_cleanup_arg_t));
+	spa_close(spa, FTAG);
+}
+
+static void
+dsl_onexit_hold_cleanup(spa_t *spa, nvlist_t *holds, minor_t minor)
+{
+	zfs_hold_cleanup_arg_t *ca;
+
+	if (minor == 0 || nvlist_empty(holds)) {
+		fnvlist_free(holds);
+		return;
+	}
+
+	ASSERT(spa != NULL);
+	ca = kmem_alloc(sizeof (*ca), KM_SLEEP);
+
+	(void) strlcpy(ca->zhca_spaname, spa_name(spa),
+	    sizeof (ca->zhca_spaname));
+	ca->zhca_spa_load_guid = spa_load_guid(spa);
+	ca->zhca_holds = holds;
+	VERIFY0(zfs_onexit_add_cb(minor,
+	    dsl_dataset_user_release_onexit, ca, NULL));
+}
+
+void
+dsl_dataset_user_hold_sync_one(dsl_dataset_t *ds, const char *htag,
+    minor_t minor, uint64_t now, dmu_tx_t *tx)
+{
+	nvlist_t *tmpholds;
+
+	if (minor != 0)
+		tmpholds = fnvlist_alloc();
+	else
+		tmpholds = NULL;
+	dsl_dataset_user_hold_sync_one_impl(tmpholds, ds, htag, minor, now, tx);
+	dsl_onexit_hold_cleanup(dsl_dataset_get_spa(ds), tmpholds, minor);
+}
+
+static void
+dsl_dataset_user_hold_sync(void *arg, dmu_tx_t *tx)
+{
+	dsl_dataset_user_hold_arg_t *dduha = arg;
+	dsl_pool_t *dp = dmu_tx_pool(tx);
+	nvlist_t *tmpholds;
+	nvpair_t *pair;
+	uint64_t now = gethrestime_sec();
+
+	if (dduha->dduha_minor != 0)
+		tmpholds = fnvlist_alloc();
+	else
+		tmpholds = NULL;
+	for (pair = nvlist_next_nvpair(dduha->dduha_chkholds, NULL);
+	    pair != NULL;
+	    pair = nvlist_next_nvpair(dduha->dduha_chkholds, pair)) {
+		dsl_dataset_t *ds;
+
+		VERIFY0(dsl_dataset_hold(dp, nvpair_name(pair), FTAG, &ds));
+		dsl_dataset_user_hold_sync_one_impl(tmpholds, ds,
+		    fnvpair_value_string(pair), dduha->dduha_minor, now, tx);
+		dsl_dataset_rele(ds, FTAG);
+	}
+	dsl_onexit_hold_cleanup(dp->dp_spa, tmpholds, dduha->dduha_minor);
+}
+
+/*
+ * The full semantics of this function are described in the comment above
+ * lzc_hold().
+ *
+ * To summarize:
+ * holds is nvl of snapname -> holdname
+ * errlist will be filled in with snapname -> error
+ *
+ * The snaphosts must all be in the same pool.
+ *
+ * Holds for snapshots that don't exist will be skipped.
+ *
+ * If none of the snapshots for requested holds exist then ENOENT will be
+ * returned.
+ *
+ * If cleanup_minor is not 0, the holds will be temporary, which will be cleaned
+ * up when the process exits.
+ *
+ * On success all the holds, for snapshots that existed, will be created and 0
+ * will be returned.
+ *
+ * On failure no holds will be created, the errlist will be filled in,
+ * and an errno will returned.
+ *
+ * In all cases the errlist will contain entries for holds where the snapshot
+ * didn't exist.
+ */
+int
+dsl_dataset_user_hold(nvlist_t *holds, minor_t cleanup_minor, nvlist_t *errlist)
+{
+	dsl_dataset_user_hold_arg_t dduha;
+	nvpair_t *pair;
+	int ret;
+
+	pair = nvlist_next_nvpair(holds, NULL);
+	if (pair == NULL)
+		return (0);
+
+	dduha.dduha_holds = holds;
+	dduha.dduha_chkholds = fnvlist_alloc();
+	dduha.dduha_errlist = errlist;
+	dduha.dduha_minor = cleanup_minor;
+
+	ret = dsl_sync_task(nvpair_name(pair), dsl_dataset_user_hold_check,
+	    dsl_dataset_user_hold_sync, &dduha,
+	    fnvlist_num_pairs(holds), ZFS_SPACE_CHECK_RESERVED);
+	fnvlist_free(dduha.dduha_chkholds);
+
+	return (ret);
+}
+
+typedef int (dsl_holdfunc_t)(dsl_pool_t *dp, const char *name, void *tag,
+    dsl_dataset_t **dsp);
+
+typedef struct dsl_dataset_user_release_arg {
+	dsl_holdfunc_t *ddura_holdfunc;
+	nvlist_t *ddura_holds;
+	nvlist_t *ddura_todelete;
+	nvlist_t *ddura_errlist;
+	nvlist_t *ddura_chkholds;
+} dsl_dataset_user_release_arg_t;
+
+/* Place a dataset hold on the snapshot identified by passed dsobj string */
+static int
+dsl_dataset_hold_obj_string(dsl_pool_t *dp, const char *dsobj, void *tag,
+    dsl_dataset_t **dsp)
+{
+	return (dsl_dataset_hold_obj(dp, strtonum(dsobj, NULL), tag, dsp));
+}
+
+static int
+dsl_dataset_user_release_check_one(dsl_dataset_user_release_arg_t *ddura,
+    dsl_dataset_t *ds, nvlist_t *holds, const char *snapname)
+{
+	uint64_t zapobj;
+	nvlist_t *holds_found;
+	nvpair_t *pair;
+	objset_t *mos;
+	int numholds;
+
+	if (!ds->ds_is_snapshot)
+		return (SET_ERROR(EINVAL));
+
+	if (nvlist_empty(holds))
+		return (0);
+
+	numholds = 0;
+	mos = ds->ds_dir->dd_pool->dp_meta_objset;
+	zapobj = dsl_dataset_phys(ds)->ds_userrefs_obj;
+	VERIFY0(nvlist_alloc(&holds_found, NV_UNIQUE_NAME, KM_SLEEP));
+
+	for (pair = nvlist_next_nvpair(holds, NULL); pair != NULL;
+	    pair = nvlist_next_nvpair(holds, pair)) {
+		uint64_t tmp;
+		int error;
+		const char *holdname = nvpair_name(pair);
+
+		if (zapobj != 0)
+			error = zap_lookup(mos, zapobj, holdname, 8, 1, &tmp);
+		else
+			error = SET_ERROR(ENOENT);
+
+		/*
+		 * Non-existent holds are put on the errlist, but don't
+		 * cause an overall failure.
+		 */
+		if (error == ENOENT) {
+			if (ddura->ddura_errlist != NULL) {
+				char *errtag = kmem_asprintf("%s#%s",
+				    snapname, holdname);
+				fnvlist_add_int32(ddura->ddura_errlist, errtag,
+				    ENOENT);
+				strfree(errtag);
+			}
+			continue;
+		}
+
+		if (error != 0) {
+			fnvlist_free(holds_found);
+			return (error);
+		}
+
+		fnvlist_add_boolean(holds_found, holdname);
+		numholds++;
+	}
+
+	if (DS_IS_DEFER_DESTROY(ds) &&
+	    dsl_dataset_phys(ds)->ds_num_children == 1 &&
+	    ds->ds_userrefs == numholds) {
+		/* we need to destroy the snapshot as well */
+		if (dsl_dataset_long_held(ds)) {
+			fnvlist_free(holds_found);
+			return (SET_ERROR(EBUSY));
+		}
+		fnvlist_add_boolean(ddura->ddura_todelete, snapname);
+	}
+
+	if (numholds != 0) {
+		fnvlist_add_nvlist(ddura->ddura_chkholds, snapname,
+		    holds_found);
+	}
+	fnvlist_free(holds_found);
+
+	return (0);
+}
+
+static int
+dsl_dataset_user_release_check(void *arg, dmu_tx_t *tx)
+{
+	dsl_dataset_user_release_arg_t *ddura;
+	dsl_holdfunc_t *holdfunc;
+	dsl_pool_t *dp;
+	nvpair_t *pair;
+
+	if (!dmu_tx_is_syncing(tx))
+		return (0);
+
+	dp = dmu_tx_pool(tx);
+
+	ASSERT(RRW_WRITE_HELD(&dp->dp_config_rwlock));
+
+	ddura = arg;
+	holdfunc = ddura->ddura_holdfunc;
+
+	for (pair = nvlist_next_nvpair(ddura->ddura_holds, NULL);
+	    pair != NULL; pair = nvlist_next_nvpair(ddura->ddura_holds, pair)) {
+		int error;
+		dsl_dataset_t *ds;
+		nvlist_t *holds;
+		const char *snapname = nvpair_name(pair);
+
+		error = nvpair_value_nvlist(pair, &holds);
+		if (error != 0)
+			error = (SET_ERROR(EINVAL));
+		else
+			error = holdfunc(dp, snapname, FTAG, &ds);
+		if (error == 0) {
+			error = dsl_dataset_user_release_check_one(ddura, ds,
+			    holds, snapname);
+			dsl_dataset_rele(ds, FTAG);
+		}
+		if (error != 0) {
+			if (ddura->ddura_errlist != NULL) {
+				fnvlist_add_int32(ddura->ddura_errlist,
+				    snapname, error);
+			}
+			/*
+			 * Non-existent snapshots are put on the errlist,
+			 * but don't cause an overall failure.
+			 */
+			if (error != ENOENT)
+				return (error);
+		}
+	}
+
+	return (0);
+}
+
+static void
+dsl_dataset_user_release_sync_one(dsl_dataset_t *ds, nvlist_t *holds,
+    dmu_tx_t *tx)
+{
+	dsl_pool_t *dp = ds->ds_dir->dd_pool;
+	objset_t *mos = dp->dp_meta_objset;
+	nvpair_t *pair;
+
+	for (pair = nvlist_next_nvpair(holds, NULL); pair != NULL;
+	    pair = nvlist_next_nvpair(holds, pair)) {
+		int error;
+		const char *holdname = nvpair_name(pair);
+
+		/* Remove temporary hold if one exists. */
+		error = dsl_pool_user_release(dp, ds->ds_object, holdname, tx);
+		VERIFY(error == 0 || error == ENOENT);
+
+		VERIFY0(zap_remove(mos, dsl_dataset_phys(ds)->ds_userrefs_obj,
+		    holdname, tx));
+		ds->ds_userrefs--;
+
+		spa_history_log_internal_ds(ds, "release", tx,
+		    "tag=%s refs=%lld", holdname, (longlong_t)ds->ds_userrefs);
+	}
+}
+
+static void
+dsl_dataset_user_release_sync(void *arg, dmu_tx_t *tx)
+{
+	dsl_dataset_user_release_arg_t *ddura = arg;
+	dsl_holdfunc_t *holdfunc = ddura->ddura_holdfunc;
+	dsl_pool_t *dp = dmu_tx_pool(tx);
+	nvpair_t *pair;
+
+	ASSERT(RRW_WRITE_HELD(&dp->dp_config_rwlock));
+
+	for (pair = nvlist_next_nvpair(ddura->ddura_chkholds, NULL);
+	    pair != NULL; pair = nvlist_next_nvpair(ddura->ddura_chkholds,
+	    pair)) {
+		dsl_dataset_t *ds;
+		const char *name = nvpair_name(pair);
+
+		VERIFY0(holdfunc(dp, name, FTAG, &ds));
+
+		dsl_dataset_user_release_sync_one(ds,
+		    fnvpair_value_nvlist(pair), tx);
+		if (nvlist_exists(ddura->ddura_todelete, name)) {
+			ASSERT(ds->ds_userrefs == 0 &&
+			    dsl_dataset_phys(ds)->ds_num_children == 1 &&
+			    DS_IS_DEFER_DESTROY(ds));
+			dsl_destroy_snapshot_sync_impl(ds, B_FALSE, tx);
+		}
+		dsl_dataset_rele(ds, FTAG);
+	}
+}
+
+/*
+ * The full semantics of this function are described in the comment above
+ * lzc_release().
+ *
+ * To summarize:
+ * Releases holds specified in the nvl holds.
+ *
+ * holds is nvl of snapname -> { holdname, ... }
+ * errlist will be filled in with snapname -> error
+ *
+ * If tmpdp is not NULL the names for holds should be the dsobj's of snapshots,
+ * otherwise they should be the names of shapshots.
+ *
+ * As a release may cause snapshots to be destroyed this trys to ensure they
+ * aren't mounted.
+ *
+ * The release of non-existent holds are skipped.
+ *
+ * At least one hold must have been released for the this function to succeed
+ * and return 0.
+ */
+static int
+dsl_dataset_user_release_impl(nvlist_t *holds, nvlist_t *errlist,
+    dsl_pool_t *tmpdp)
+{
+	dsl_dataset_user_release_arg_t ddura;
+	nvpair_t *pair;
+	char *pool;
+	int error;
+
+	pair = nvlist_next_nvpair(holds, NULL);
+	if (pair == NULL)
+		return (0);
+
+	/*
+	 * The release may cause snapshots to be destroyed; make sure they
+	 * are not mounted.
+	 */
+	if (tmpdp != NULL) {
+		/* Temporary holds are specified by dsobj string. */
+		ddura.ddura_holdfunc = dsl_dataset_hold_obj_string;
+		pool = spa_name(tmpdp->dp_spa);
+#ifdef _KERNEL
+		for (pair = nvlist_next_nvpair(holds, NULL); pair != NULL;
+		    pair = nvlist_next_nvpair(holds, pair)) {
+			dsl_dataset_t *ds;
+
+			dsl_pool_config_enter(tmpdp, FTAG);
+			error = dsl_dataset_hold_obj_string(tmpdp,
+			    nvpair_name(pair), FTAG, &ds);
+			if (error == 0) {
+				char name[MAXNAMELEN];
+				dsl_dataset_name(ds, name);
+				dsl_pool_config_exit(tmpdp, FTAG);
+				dsl_dataset_rele(ds, FTAG);
+				(void) zfs_unmount_snap(name);
+			} else {
+				dsl_pool_config_exit(tmpdp, FTAG);
+			}
+		}
+#endif
+	} else {
+		/* Non-temporary holds are specified by name. */
+		ddura.ddura_holdfunc = dsl_dataset_hold;
+		pool = nvpair_name(pair);
+#ifdef _KERNEL
+		for (pair = nvlist_next_nvpair(holds, NULL); pair != NULL;
+		    pair = nvlist_next_nvpair(holds, pair)) {
+			(void) zfs_unmount_snap(nvpair_name(pair));
+		}
+#endif
+	}
+
+	ddura.ddura_holds = holds;
+	ddura.ddura_errlist = errlist;
+	VERIFY0(nvlist_alloc(&ddura.ddura_todelete, NV_UNIQUE_NAME,
+	    KM_SLEEP));
+	VERIFY0(nvlist_alloc(&ddura.ddura_chkholds, NV_UNIQUE_NAME,
+	    KM_SLEEP));
+
+	error = dsl_sync_task(pool, dsl_dataset_user_release_check,
+	    dsl_dataset_user_release_sync, &ddura, 0, ZFS_SPACE_CHECK_NONE);
+	fnvlist_free(ddura.ddura_todelete);
+	fnvlist_free(ddura.ddura_chkholds);
+
+	return (error);
+}
+
+/*
+ * holds is nvl of snapname -> { holdname, ... }
+ * errlist will be filled in with snapname -> error
+ */
+int
+dsl_dataset_user_release(nvlist_t *holds, nvlist_t *errlist)
+{
+	return (dsl_dataset_user_release_impl(holds, errlist, NULL));
+}
+
+/*
+ * holds is nvl of snapdsobj -> { holdname, ... }
+ */
+void
+dsl_dataset_user_release_tmp(struct dsl_pool *dp, nvlist_t *holds)
+{
+	ASSERT(dp != NULL);
+	(void) dsl_dataset_user_release_impl(holds, NULL, dp);
+}
+
+int
+dsl_dataset_get_holds(const char *dsname, nvlist_t *nvl)
+{
+	dsl_pool_t *dp;
+	dsl_dataset_t *ds;
+	int err;
+
+	err = dsl_pool_hold(dsname, FTAG, &dp);
+	if (err != 0)
+		return (err);
+	err = dsl_dataset_hold(dp, dsname, FTAG, &ds);
+	if (err != 0) {
+		dsl_pool_rele(dp, FTAG);
+		return (err);
+	}
+
+	if (dsl_dataset_phys(ds)->ds_userrefs_obj != 0) {
+		zap_attribute_t *za;
+		zap_cursor_t zc;
+
+		za = kmem_alloc(sizeof (zap_attribute_t), KM_SLEEP);
+		for (zap_cursor_init(&zc, ds->ds_dir->dd_pool->dp_meta_objset,
+		    dsl_dataset_phys(ds)->ds_userrefs_obj);
+		    zap_cursor_retrieve(&zc, za) == 0;
+		    zap_cursor_advance(&zc)) {
+			fnvlist_add_uint64(nvl, za->za_name,
+			    za->za_first_integer);
+		}
+		zap_cursor_fini(&zc);
+		kmem_free(za, sizeof (zap_attribute_t));
+	}
+	dsl_dataset_rele(ds, FTAG);
+	dsl_pool_rele(dp, FTAG);
+	return (0);
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/module/zfs/fm.c
@@ -0,0 +1,1660 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
+ */
+
+/*
+ * Fault Management Architecture (FMA) Resource and Protocol Support
+ *
+ * The routines contained herein provide services to support kernel subsystems
+ * in publishing fault management telemetry (see PSARC 2002/412 and 2003/089).
+ *
+ * Name-Value Pair Lists
+ *
+ * The embodiment of an FMA protocol element (event, fmri or authority) is a
+ * name-value pair list (nvlist_t).  FMA-specific nvlist construtor and
+ * destructor functions, fm_nvlist_create() and fm_nvlist_destroy(), are used
+ * to create an nvpair list using custom allocators.  Callers may choose to
+ * allocate either from the kernel memory allocator, or from a preallocated
+ * buffer, useful in constrained contexts like high-level interrupt routines.
+ *
+ * Protocol Event and FMRI Construction
+ *
+ * Convenience routines are provided to construct nvlist events according to
+ * the FMA Event Protocol and Naming Schema specification for ereports and
+ * FMRIs for the dev, cpu, hc, mem, legacy hc and de schemes.
+ *
+ * ENA Manipulation
+ *
+ * Routines to generate ENA formats 0, 1 and 2 are available as well as
+ * routines to increment formats 1 and 2.  Individual fields within the
+ * ENA are extractable via fm_ena_time_get(), fm_ena_id_get(),
+ * fm_ena_format_get() and fm_ena_gen_get().
+ */
+
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/list.h>
+#include <sys/nvpair.h>
+#include <sys/cmn_err.h>
+#include <sys/sysmacros.h>
+#include <sys/compress.h>
+#include <sys/sunddi.h>
+#include <sys/systeminfo.h>
+#include <sys/fm/util.h>
+#include <sys/fm/protocol.h>
+#include <sys/kstat.h>
+#include <sys/zfs_context.h>
+#ifdef _KERNEL
+#include <sys/atomic.h>
+#include <sys/condvar.h>
+#include <sys/cpuvar.h>
+#include <sys/systm.h>
+#include <sys/dumphdr.h>
+#include <sys/cpuvar.h>
+#include <sys/console.h>
+#include <sys/kobj.h>
+#include <sys/time.h>
+#include <sys/zfs_ioctl.h>
+
+int zfs_zevent_len_max = 0;
+int zfs_zevent_cols = 80;
+int zfs_zevent_console = 0;
+
+static int zevent_len_cur = 0;
+static int zevent_waiters = 0;
+static int zevent_flags = 0;
+
+/*
+ * The EID (Event IDentifier) is used to uniquely tag a zevent when it is
+ * posted.  The posted EIDs are monotonically increasing but not persistent.
+ * They will be reset to the initial value (1) each time the kernel module is
+ * loaded.
+ */
+static uint64_t zevent_eid = 0;
+
+static kmutex_t zevent_lock;
+static list_t zevent_list;
+static kcondvar_t zevent_cv;
+#endif /* _KERNEL */
+
+extern void fastreboot_disable_highpil(void);
+
+/*
+ * Common fault management kstats to record event generation failures
+ */
+
+struct erpt_kstat {
+	kstat_named_t	erpt_dropped;		/* num erpts dropped on post */
+	kstat_named_t	erpt_set_failed;	/* num erpt set failures */
+	kstat_named_t	fmri_set_failed;	/* num fmri set failures */
+	kstat_named_t	payload_set_failed;	/* num payload set failures */
+};
+
+static struct erpt_kstat erpt_kstat_data = {
+	{ "erpt-dropped", KSTAT_DATA_UINT64 },
+	{ "erpt-set-failed", KSTAT_DATA_UINT64 },
+	{ "fmri-set-failed", KSTAT_DATA_UINT64 },
+	{ "payload-set-failed", KSTAT_DATA_UINT64 }
+};
+
+kstat_t *fm_ksp;
+
+#ifdef _KERNEL
+
+/*
+ * Formatting utility function for fm_nvprintr.  We attempt to wrap chunks of
+ * output so they aren't split across console lines, and return the end column.
+ */
+/*PRINTFLIKE4*/
+static int
+fm_printf(int depth, int c, int cols, const char *format, ...)
+{
+	va_list ap;
+	int width;
+	char c1;
+
+	va_start(ap, format);
+	width = vsnprintf(&c1, sizeof (c1), format, ap);
+	va_end(ap);
+
+	if (c + width >= cols) {
+		console_printf("\n");
+		c = 0;
+		if (format[0] != ' ' && depth > 0) {
+			console_printf(" ");
+			c++;
+		}
+	}
+
+	va_start(ap, format);
+	console_vprintf(format, ap);
+	va_end(ap);
+
+	return ((c + width) % cols);
+}
+
+/*
+ * Recursively print a nvlist in the specified column width and return the
+ * column we end up in.  This function is called recursively by fm_nvprint(),
+ * below.  We generically format the entire nvpair using hexadecimal
+ * integers and strings, and elide any integer arrays.  Arrays are basically
+ * used for cache dumps right now, so we suppress them so as not to overwhelm
+ * the amount of console output we produce at panic time.  This can be further
+ * enhanced as FMA technology grows based upon the needs of consumers.  All
+ * FMA telemetry is logged using the dump device transport, so the console
+ * output serves only as a fallback in case this procedure is unsuccessful.
+ */
+static int
+fm_nvprintr(nvlist_t *nvl, int d, int c, int cols)
+{
+	nvpair_t *nvp;
+
+	for (nvp = nvlist_next_nvpair(nvl, NULL);
+	    nvp != NULL; nvp = nvlist_next_nvpair(nvl, nvp)) {
+
+		data_type_t type = nvpair_type(nvp);
+		const char *name = nvpair_name(nvp);
+
+		boolean_t b;
+		uint8_t i8;
+		uint16_t i16;
+		uint32_t i32;
+		uint64_t i64;
+		char *str;
+		nvlist_t *cnv;
+
+		if (strcmp(name, FM_CLASS) == 0)
+			continue; /* already printed by caller */
+
+		c = fm_printf(d, c, cols, " %s=", name);
+
+		switch (type) {
+		case DATA_TYPE_BOOLEAN:
+			c = fm_printf(d + 1, c, cols, " 1");
+			break;
+
+		case DATA_TYPE_BOOLEAN_VALUE:
+			(void) nvpair_value_boolean_value(nvp, &b);
+			c = fm_printf(d + 1, c, cols, b ? "1" : "0");
+			break;
+
+		case DATA_TYPE_BYTE:
+			(void) nvpair_value_byte(nvp, &i8);
+			c = fm_printf(d + 1, c, cols, "0x%x", i8);
+			break;
+
+		case DATA_TYPE_INT8:
+			(void) nvpair_value_int8(nvp, (void *)&i8);
+			c = fm_printf(d + 1, c, cols, "0x%x", i8);
+			break;
+
+		case DATA_TYPE_UINT8:
+			(void) nvpair_value_uint8(nvp, &i8);
+			c = fm_printf(d + 1, c, cols, "0x%x", i8);
+			break;
+
+		case DATA_TYPE_INT16:
+			(void) nvpair_value_int16(nvp, (void *)&i16);
+			c = fm_printf(d + 1, c, cols, "0x%x", i16);
+			break;
+
+		case DATA_TYPE_UINT16:
+			(void) nvpair_value_uint16(nvp, &i16);
+			c = fm_printf(d + 1, c, cols, "0x%x", i16);
+			break;
+
+		case DATA_TYPE_INT32:
+			(void) nvpair_value_int32(nvp, (void *)&i32);
+			c = fm_printf(d + 1, c, cols, "0x%x", i32);
+			break;
+
+		case DATA_TYPE_UINT32:
+			(void) nvpair_value_uint32(nvp, &i32);
+			c = fm_printf(d + 1, c, cols, "0x%x", i32);
+			break;
+
+		case DATA_TYPE_INT64:
+			(void) nvpair_value_int64(nvp, (void *)&i64);
+			c = fm_printf(d + 1, c, cols, "0x%llx",
+			    (u_longlong_t)i64);
+			break;
+
+		case DATA_TYPE_UINT64:
+			(void) nvpair_value_uint64(nvp, &i64);
+			c = fm_printf(d + 1, c, cols, "0x%llx",
+			    (u_longlong_t)i64);
+			break;
+
+		case DATA_TYPE_HRTIME:
+			(void) nvpair_value_hrtime(nvp, (void *)&i64);
+			c = fm_printf(d + 1, c, cols, "0x%llx",
+			    (u_longlong_t)i64);
+			break;
+
+		case DATA_TYPE_STRING:
+			(void) nvpair_value_string(nvp, &str);
+			c = fm_printf(d + 1, c, cols, "\"%s\"",
+			    str ? str : "<NULL>");
+			break;
+
+		case DATA_TYPE_NVLIST:
+			c = fm_printf(d + 1, c, cols, "[");
+			(void) nvpair_value_nvlist(nvp, &cnv);
+			c = fm_nvprintr(cnv, d + 1, c, cols);
+			c = fm_printf(d + 1, c, cols, " ]");
+			break;
+
+		case DATA_TYPE_NVLIST_ARRAY: {
+			nvlist_t **val;
+			uint_t i, nelem;
+
+			c = fm_printf(d + 1, c, cols, "[");
+			(void) nvpair_value_nvlist_array(nvp, &val, &nelem);
+			for (i = 0; i < nelem; i++) {
+				c = fm_nvprintr(val[i], d + 1, c, cols);
+			}
+			c = fm_printf(d + 1, c, cols, " ]");
+			}
+			break;
+
+		case DATA_TYPE_INT8_ARRAY: {
+			int8_t *val;
+			uint_t i, nelem;
+
+			c = fm_printf(d + 1, c, cols, "[ ");
+			(void) nvpair_value_int8_array(nvp, &val, &nelem);
+			for (i = 0; i < nelem; i++)
+				c = fm_printf(d + 1, c, cols, "0x%llx ",
+				    (u_longlong_t)val[i]);
+
+			c = fm_printf(d + 1, c, cols, "]");
+			break;
+			}
+
+		case DATA_TYPE_UINT8_ARRAY: {
+			uint8_t *val;
+			uint_t i, nelem;
+
+			c = fm_printf(d + 1, c, cols, "[ ");
+			(void) nvpair_value_uint8_array(nvp, &val, &nelem);
+			for (i = 0; i < nelem; i++)
+				c = fm_printf(d + 1, c, cols, "0x%llx ",
+				    (u_longlong_t)val[i]);
+
+			c = fm_printf(d + 1, c, cols, "]");
+			break;
+			}
+
+		case DATA_TYPE_INT16_ARRAY: {
+			int16_t *val;
+			uint_t i, nelem;
+
+			c = fm_printf(d + 1, c, cols, "[ ");
+			(void) nvpair_value_int16_array(nvp, &val, &nelem);
+			for (i = 0; i < nelem; i++)
+				c = fm_printf(d + 1, c, cols, "0x%llx ",
+				    (u_longlong_t)val[i]);
+
+			c = fm_printf(d + 1, c, cols, "]");
+			break;
+			}
+
+		case DATA_TYPE_UINT16_ARRAY: {
+			uint16_t *val;
+			uint_t i, nelem;
+
+			c = fm_printf(d + 1, c, cols, "[ ");
+			(void) nvpair_value_uint16_array(nvp, &val, &nelem);
+			for (i = 0; i < nelem; i++)
+				c = fm_printf(d + 1, c, cols, "0x%llx ",
+				    (u_longlong_t)val[i]);
+
+			c = fm_printf(d + 1, c, cols, "]");
+			break;
+			}
+
+		case DATA_TYPE_INT32_ARRAY: {
+			int32_t *val;
+			uint_t i, nelem;
+
+			c = fm_printf(d + 1, c, cols, "[ ");
+			(void) nvpair_value_int32_array(nvp, &val, &nelem);
+			for (i = 0; i < nelem; i++)
+			c = fm_printf(d + 1, c, cols, "0x%llx ",
+			    (u_longlong_t)val[i]);
+
+			c = fm_printf(d + 1, c, cols, "]");
+			break;
+			}
+
+		case DATA_TYPE_UINT32_ARRAY: {
+			uint32_t *val;
+			uint_t i, nelem;
+
+			c = fm_printf(d + 1, c, cols, "[ ");
+			(void) nvpair_value_uint32_array(nvp, &val, &nelem);
+			for (i = 0; i < nelem; i++)
+				c = fm_printf(d + 1, c, cols, "0x%llx ",
+				    (u_longlong_t)val[i]);
+
+			c = fm_printf(d + 1, c, cols, "]");
+			break;
+			}
+
+		case DATA_TYPE_INT64_ARRAY: {
+			int64_t *val;
+			uint_t i, nelem;
+
+			c = fm_printf(d + 1, c, cols, "[ ");
+			(void) nvpair_value_int64_array(nvp, &val, &nelem);
+			for (i = 0; i < nelem; i++)
+				c = fm_printf(d + 1, c, cols, "0x%llx ",
+				    (u_longlong_t)val[i]);
+
+			c = fm_printf(d + 1, c, cols, "]");
+			break;
+			}
+
+		case DATA_TYPE_UINT64_ARRAY: {
+			uint64_t *val;
+			uint_t i, nelem;
+
+			c = fm_printf(d + 1, c, cols, "[ ");
+			(void) nvpair_value_uint64_array(nvp, &val, &nelem);
+			for (i = 0; i < nelem; i++)
+				c = fm_printf(d + 1, c, cols, "0x%llx ",
+				    (u_longlong_t)val[i]);
+
+			c = fm_printf(d + 1, c, cols, "]");
+			break;
+			}
+
+		case DATA_TYPE_STRING_ARRAY:
+		case DATA_TYPE_BOOLEAN_ARRAY:
+		case DATA_TYPE_BYTE_ARRAY:
+			c = fm_printf(d + 1, c, cols, "[...]");
+			break;
+
+		case DATA_TYPE_UNKNOWN:
+			c = fm_printf(d + 1, c, cols, "<unknown>");
+			break;
+		}
+	}
+
+	return (c);
+}
+
+void
+fm_nvprint(nvlist_t *nvl)
+{
+	char *class;
+	int c = 0;
+
+	console_printf("\n");
+
+	if (nvlist_lookup_string(nvl, FM_CLASS, &class) == 0)
+		c = fm_printf(0, c, zfs_zevent_cols, "%s", class);
+
+	if (fm_nvprintr(nvl, 0, c, zfs_zevent_cols) != 0)
+		console_printf("\n");
+
+	console_printf("\n");
+}
+
+static zevent_t *
+zfs_zevent_alloc(void)
+{
+	zevent_t *ev;
+
+	ev = kmem_zalloc(sizeof (zevent_t), KM_SLEEP);
+	if (ev == NULL)
+		return (NULL);
+
+	list_create(&ev->ev_ze_list, sizeof (zfs_zevent_t),
+		    offsetof(zfs_zevent_t, ze_node));
+	list_link_init(&ev->ev_node);
+
+	return (ev);
+}
+
+static void
+zfs_zevent_free(zevent_t *ev)
+{
+	/* Run provided cleanup callback */
+	ev->ev_cb(ev->ev_nvl, ev->ev_detector);
+
+	list_destroy(&ev->ev_ze_list);
+	kmem_free(ev, sizeof (zevent_t));
+}
+
+static void
+zfs_zevent_drain(zevent_t *ev)
+{
+	zfs_zevent_t *ze;
+
+	ASSERT(MUTEX_HELD(&zevent_lock));
+	list_remove(&zevent_list, ev);
+
+	/* Remove references to this event in all private file data */
+	while ((ze = list_head(&ev->ev_ze_list)) != NULL) {
+		list_remove(&ev->ev_ze_list, ze);
+		ze->ze_zevent = NULL;
+		ze->ze_dropped++;
+	}
+
+	zfs_zevent_free(ev);
+}
+
+void
+zfs_zevent_drain_all(int *count)
+{
+	zevent_t *ev;
+
+	mutex_enter(&zevent_lock);
+	while ((ev = list_head(&zevent_list)) != NULL)
+		zfs_zevent_drain(ev);
+
+	*count = zevent_len_cur;
+	zevent_len_cur = 0;
+	mutex_exit(&zevent_lock);
+}
+
+/*
+ * New zevents are inserted at the head.  If the maximum queue
+ * length is exceeded a zevent will be drained from the tail.
+ * As part of this any user space processes which currently have
+ * a reference to this zevent_t in their private data will have
+ * this reference set to NULL.
+ */
+static void
+zfs_zevent_insert(zevent_t *ev)
+{
+	ASSERT(MUTEX_HELD(&zevent_lock));
+	list_insert_head(&zevent_list, ev);
+
+	if (zevent_len_cur >= zfs_zevent_len_max)
+		zfs_zevent_drain(list_tail(&zevent_list));
+	else
+		zevent_len_cur++;
+}
+
+/*
+ * Post a zevent. The cb will be called when nvl and detector are no longer
+ * needed, i.e.:
+ * - An error happened and a zevent can't be posted. In this case, cb is called
+ *   before zfs_zevent_post() returns.
+ * - The event is being drained and freed.
+ */
+int
+zfs_zevent_post(nvlist_t *nvl, nvlist_t *detector, zevent_cb_t *cb)
+{
+	int64_t tv_array[2];
+	timestruc_t tv;
+	uint64_t eid;
+	size_t nvl_size = 0;
+	zevent_t *ev;
+	int error;
+
+	ASSERT(cb != NULL);
+
+	gethrestime(&tv);
+	tv_array[0] = tv.tv_sec;
+	tv_array[1] = tv.tv_nsec;
+
+	error = nvlist_add_int64_array(nvl, FM_EREPORT_TIME, tv_array, 2);
+	if (error) {
+		atomic_add_64(&erpt_kstat_data.erpt_set_failed.value.ui64, 1);
+		goto out;
+	}
+
+	eid = atomic_inc_64_nv(&zevent_eid);
+	error = nvlist_add_uint64(nvl, FM_EREPORT_EID, eid);
+	if (error) {
+		atomic_add_64(&erpt_kstat_data.erpt_set_failed.value.ui64, 1);
+		goto out;
+	}
+
+	error = nvlist_size(nvl, &nvl_size, NV_ENCODE_NATIVE);
+	if (error) {
+		atomic_add_64(&erpt_kstat_data.erpt_dropped.value.ui64, 1);
+		goto out;
+	}
+
+	if (nvl_size > ERPT_DATA_SZ || nvl_size == 0) {
+		atomic_add_64(&erpt_kstat_data.erpt_dropped.value.ui64, 1);
+		error = EOVERFLOW;
+		goto out;
+	}
+
+	if (zfs_zevent_console)
+		fm_nvprint(nvl);
+
+	ev = zfs_zevent_alloc();
+	if (ev == NULL) {
+		atomic_add_64(&erpt_kstat_data.erpt_dropped.value.ui64, 1);
+		error = ENOMEM;
+		goto out;
+	}
+
+	ev->ev_nvl = nvl;
+	ev->ev_detector = detector;
+	ev->ev_cb = cb;
+	ev->ev_eid = eid;
+
+	mutex_enter(&zevent_lock);
+	zfs_zevent_insert(ev);
+	cv_broadcast(&zevent_cv);
+	mutex_exit(&zevent_lock);
+
+out:
+	if (error)
+		cb(nvl, detector);
+
+	return (error);
+}
+
+static int
+zfs_zevent_minor_to_state(minor_t minor, zfs_zevent_t **ze)
+{
+	*ze = zfsdev_get_state(minor, ZST_ZEVENT);
+	if (*ze == NULL)
+		return (EBADF);
+
+	return (0);
+}
+
+int
+zfs_zevent_fd_hold(int fd, minor_t *minorp, zfs_zevent_t **ze)
+{
+	file_t *fp;
+	int error;
+
+	fp = getf(fd);
+	if (fp == NULL)
+		return (EBADF);
+
+	error = zfsdev_getminor(fp->f_file, minorp);
+	if (error == 0)
+		error = zfs_zevent_minor_to_state(*minorp, ze);
+
+	if (error)
+		zfs_zevent_fd_rele(fd);
+
+	return (error);
+}
+
+void
+zfs_zevent_fd_rele(int fd)
+{
+	releasef(fd);
+}
+
+/*
+ * Get the next zevent in the stream and place a copy in 'event'.  This
+ * may fail with ENOMEM if the encoded nvlist size exceeds the passed
+ * 'event_size'.  In this case the stream pointer is not advanced and
+ * and 'event_size' is set to the minimum required buffer size.
+ */
+int
+zfs_zevent_next(zfs_zevent_t *ze, nvlist_t **event, uint64_t *event_size,
+    uint64_t *dropped)
+{
+	zevent_t *ev;
+	size_t size;
+	int error = 0;
+
+	mutex_enter(&zevent_lock);
+	if (ze->ze_zevent == NULL) {
+		/* New stream start at the beginning/tail */
+		ev = list_tail(&zevent_list);
+		if (ev == NULL) {
+			error = ENOENT;
+			goto out;
+		}
+	} else {
+		/*
+		 * Existing stream continue with the next element and remove
+		 * ourselves from the wait queue for the previous element
+		 */
+		ev = list_prev(&zevent_list, ze->ze_zevent);
+		if (ev == NULL) {
+			error = ENOENT;
+			goto out;
+		}
+	}
+
+	VERIFY(nvlist_size(ev->ev_nvl, &size, NV_ENCODE_NATIVE) == 0);
+	if (size > *event_size) {
+		*event_size = size;
+		error = ENOMEM;
+		goto out;
+	}
+
+	if (ze->ze_zevent)
+		list_remove(&ze->ze_zevent->ev_ze_list, ze);
+
+	ze->ze_zevent = ev;
+	list_insert_head(&ev->ev_ze_list, ze);
+	nvlist_dup(ev->ev_nvl, event, KM_SLEEP);
+	*dropped = ze->ze_dropped;
+	ze->ze_dropped = 0;
+out:
+	mutex_exit(&zevent_lock);
+
+	return (error);
+}
+
+int
+zfs_zevent_wait(zfs_zevent_t *ze)
+{
+	int error = 0;
+
+	mutex_enter(&zevent_lock);
+
+	if (zevent_flags & ZEVENT_SHUTDOWN) {
+		error = ESHUTDOWN;
+		goto out;
+	}
+
+	zevent_waiters++;
+	cv_wait_sig(&zevent_cv, &zevent_lock);
+	if (issig(JUSTLOOKING))
+		error = EINTR;
+
+	zevent_waiters--;
+out:
+	mutex_exit(&zevent_lock);
+
+	return (error);
+}
+
+/*
+ * The caller may seek to a specific EID by passing that EID.  If the EID
+ * is still available in the posted list of events the cursor is positioned
+ * there.  Otherwise ENOENT is returned and the cursor is not moved.
+ *
+ * There are two reserved EIDs which may be passed and will never fail.
+ * ZEVENT_SEEK_START positions the cursor at the start of the list, and
+ * ZEVENT_SEEK_END positions the cursor at the end of the list.
+ */
+int
+zfs_zevent_seek(zfs_zevent_t *ze, uint64_t eid)
+{
+	zevent_t *ev;
+	int error = 0;
+
+	mutex_enter(&zevent_lock);
+
+	if (eid == ZEVENT_SEEK_START) {
+		if (ze->ze_zevent)
+			list_remove(&ze->ze_zevent->ev_ze_list, ze);
+
+		ze->ze_zevent = NULL;
+		goto out;
+	}
+
+	if (eid == ZEVENT_SEEK_END) {
+		if (ze->ze_zevent)
+			list_remove(&ze->ze_zevent->ev_ze_list, ze);
+
+		ev = list_head(&zevent_list);
+		if (ev) {
+			ze->ze_zevent = ev;
+			list_insert_head(&ev->ev_ze_list, ze);
+		} else {
+			ze->ze_zevent = NULL;
+		}
+
+		goto out;
+	}
+
+	for (ev = list_tail(&zevent_list); ev != NULL;
+	    ev = list_prev(&zevent_list, ev)) {
+		if (ev->ev_eid == eid) {
+			if (ze->ze_zevent)
+				list_remove(&ze->ze_zevent->ev_ze_list, ze);
+
+			ze->ze_zevent = ev;
+			list_insert_head(&ev->ev_ze_list, ze);
+			break;
+		}
+	}
+
+	if (ev == NULL)
+		error = ENOENT;
+
+out:
+	mutex_exit(&zevent_lock);
+
+	return (error);
+}
+
+void
+zfs_zevent_init(zfs_zevent_t **zep)
+{
+	zfs_zevent_t *ze;
+
+	ze = *zep = kmem_zalloc(sizeof (zfs_zevent_t), KM_SLEEP);
+	list_link_init(&ze->ze_node);
+}
+
+void
+zfs_zevent_destroy(zfs_zevent_t *ze)
+{
+	mutex_enter(&zevent_lock);
+	if (ze->ze_zevent)
+		list_remove(&ze->ze_zevent->ev_ze_list, ze);
+	mutex_exit(&zevent_lock);
+
+	kmem_free(ze, sizeof (zfs_zevent_t));
+}
+#endif /* _KERNEL */
+
+/*
+ * Wrapppers for FM nvlist allocators
+ */
+/* ARGSUSED */
+static void *
+i_fm_alloc(nv_alloc_t *nva, size_t size)
+{
+	return (kmem_zalloc(size, KM_SLEEP));
+}
+
+/* ARGSUSED */
+static void
+i_fm_free(nv_alloc_t *nva, void *buf, size_t size)
+{
+	kmem_free(buf, size);
+}
+
+const nv_alloc_ops_t fm_mem_alloc_ops = {
+	NULL,
+	NULL,
+	i_fm_alloc,
+	i_fm_free,
+	NULL
+};
+
+/*
+ * Create and initialize a new nv_alloc_t for a fixed buffer, buf.  A pointer
+ * to the newly allocated nv_alloc_t structure is returned upon success or NULL
+ * is returned to indicate that the nv_alloc structure could not be created.
+ */
+nv_alloc_t *
+fm_nva_xcreate(char *buf, size_t bufsz)
+{
+	nv_alloc_t *nvhdl = kmem_zalloc(sizeof (nv_alloc_t), KM_SLEEP);
+
+	if (bufsz == 0 || nv_alloc_init(nvhdl, nv_fixed_ops, buf, bufsz) != 0) {
+		kmem_free(nvhdl, sizeof (nv_alloc_t));
+		return (NULL);
+	}
+
+	return (nvhdl);
+}
+
+/*
+ * Destroy a previously allocated nv_alloc structure.  The fixed buffer
+ * associated with nva must be freed by the caller.
+ */
+void
+fm_nva_xdestroy(nv_alloc_t *nva)
+{
+	nv_alloc_fini(nva);
+	kmem_free(nva, sizeof (nv_alloc_t));
+}
+
+/*
+ * Create a new nv list.  A pointer to a new nv list structure is returned
+ * upon success or NULL is returned to indicate that the structure could
+ * not be created.  The newly created nv list is created and managed by the
+ * operations installed in nva.   If nva is NULL, the default FMA nva
+ * operations are installed and used.
+ *
+ * When called from the kernel and nva == NULL, this function must be called
+ * from passive kernel context with no locks held that can prevent a
+ * sleeping memory allocation from occurring.  Otherwise, this function may
+ * be called from other kernel contexts as long a valid nva created via
+ * fm_nva_create() is supplied.
+ */
+nvlist_t *
+fm_nvlist_create(nv_alloc_t *nva)
+{
+	int hdl_alloced = 0;
+	nvlist_t *nvl;
+	nv_alloc_t *nvhdl;
+
+	if (nva == NULL) {
+		nvhdl = kmem_zalloc(sizeof (nv_alloc_t), KM_SLEEP);
+
+		if (nv_alloc_init(nvhdl, &fm_mem_alloc_ops, NULL, 0) != 0) {
+			kmem_free(nvhdl, sizeof (nv_alloc_t));
+			return (NULL);
+		}
+		hdl_alloced = 1;
+	} else {
+		nvhdl = nva;
+	}
+
+	if (nvlist_xalloc(&nvl, NV_UNIQUE_NAME, nvhdl) != 0) {
+		if (hdl_alloced) {
+			nv_alloc_fini(nvhdl);
+			kmem_free(nvhdl, sizeof (nv_alloc_t));
+		}
+		return (NULL);
+	}
+
+	return (nvl);
+}
+
+/*
+ * Destroy a previously allocated nvlist structure.  flag indicates whether
+ * or not the associated nva structure should be freed (FM_NVA_FREE) or
+ * retained (FM_NVA_RETAIN).  Retaining the nv alloc structure allows
+ * it to be re-used for future nvlist creation operations.
+ */
+void
+fm_nvlist_destroy(nvlist_t *nvl, int flag)
+{
+	nv_alloc_t *nva = nvlist_lookup_nv_alloc(nvl);
+
+	nvlist_free(nvl);
+
+	if (nva != NULL) {
+		if (flag == FM_NVA_FREE)
+			fm_nva_xdestroy(nva);
+	}
+}
+
+int
+i_fm_payload_set(nvlist_t *payload, const char *name, va_list ap)
+{
+	int nelem, ret = 0;
+	data_type_t type;
+
+	while (ret == 0 && name != NULL) {
+		type = va_arg(ap, data_type_t);
+		switch (type) {
+		case DATA_TYPE_BYTE:
+			ret = nvlist_add_byte(payload, name,
+			    va_arg(ap, uint_t));
+			break;
+		case DATA_TYPE_BYTE_ARRAY:
+			nelem = va_arg(ap, int);
+			ret = nvlist_add_byte_array(payload, name,
+			    va_arg(ap, uchar_t *), nelem);
+			break;
+		case DATA_TYPE_BOOLEAN_VALUE:
+			ret = nvlist_add_boolean_value(payload, name,
+			    va_arg(ap, boolean_t));
+			break;
+		case DATA_TYPE_BOOLEAN_ARRAY:
+			nelem = va_arg(ap, int);
+			ret = nvlist_add_boolean_array(payload, name,
+			    va_arg(ap, boolean_t *), nelem);
+			break;
+		case DATA_TYPE_INT8:
+			ret = nvlist_add_int8(payload, name,
+			    va_arg(ap, int));
+			break;
+		case DATA_TYPE_INT8_ARRAY:
+			nelem = va_arg(ap, int);
+			ret = nvlist_add_int8_array(payload, name,
+			    va_arg(ap, int8_t *), nelem);
+			break;
+		case DATA_TYPE_UINT8:
+			ret = nvlist_add_uint8(payload, name,
+			    va_arg(ap, uint_t));
+			break;
+		case DATA_TYPE_UINT8_ARRAY:
+			nelem = va_arg(ap, int);
+			ret = nvlist_add_uint8_array(payload, name,
+			    va_arg(ap, uint8_t *), nelem);
+			break;
+		case DATA_TYPE_INT16:
+			ret = nvlist_add_int16(payload, name,
+			    va_arg(ap, int));
+			break;
+		case DATA_TYPE_INT16_ARRAY:
+			nelem = va_arg(ap, int);
+			ret = nvlist_add_int16_array(payload, name,
+			    va_arg(ap, int16_t *), nelem);
+			break;
+		case DATA_TYPE_UINT16:
+			ret = nvlist_add_uint16(payload, name,
+			    va_arg(ap, uint_t));
+			break;
+		case DATA_TYPE_UINT16_ARRAY:
+			nelem = va_arg(ap, int);
+			ret = nvlist_add_uint16_array(payload, name,
+			    va_arg(ap, uint16_t *), nelem);
+			break;
+		case DATA_TYPE_INT32:
+			ret = nvlist_add_int32(payload, name,
+			    va_arg(ap, int32_t));
+			break;
+		case DATA_TYPE_INT32_ARRAY:
+			nelem = va_arg(ap, int);
+			ret = nvlist_add_int32_array(payload, name,
+			    va_arg(ap, int32_t *), nelem);
+			break;
+		case DATA_TYPE_UINT32:
+			ret = nvlist_add_uint32(payload, name,
+			    va_arg(ap, uint32_t));
+			break;
+		case DATA_TYPE_UINT32_ARRAY:
+			nelem = va_arg(ap, int);
+			ret = nvlist_add_uint32_array(payload, name,
+			    va_arg(ap, uint32_t *), nelem);
+			break;
+		case DATA_TYPE_INT64:
+			ret = nvlist_add_int64(payload, name,
+			    va_arg(ap, int64_t));
+			break;
+		case DATA_TYPE_INT64_ARRAY:
+			nelem = va_arg(ap, int);
+			ret = nvlist_add_int64_array(payload, name,
+			    va_arg(ap, int64_t *), nelem);
+			break;
+		case DATA_TYPE_UINT64:
+			ret = nvlist_add_uint64(payload, name,
+			    va_arg(ap, uint64_t));
+			break;
+		case DATA_TYPE_UINT64_ARRAY:
+			nelem = va_arg(ap, int);
+			ret = nvlist_add_uint64_array(payload, name,
+			    va_arg(ap, uint64_t *), nelem);
+			break;
+		case DATA_TYPE_STRING:
+			ret = nvlist_add_string(payload, name,
+			    va_arg(ap, char *));
+			break;
+		case DATA_TYPE_STRING_ARRAY:
+			nelem = va_arg(ap, int);
+			ret = nvlist_add_string_array(payload, name,
+			    va_arg(ap, char **), nelem);
+			break;
+		case DATA_TYPE_NVLIST:
+			ret = nvlist_add_nvlist(payload, name,
+			    va_arg(ap, nvlist_t *));
+			break;
+		case DATA_TYPE_NVLIST_ARRAY:
+			nelem = va_arg(ap, int);
+			ret = nvlist_add_nvlist_array(payload, name,
+			    va_arg(ap, nvlist_t **), nelem);
+			break;
+		default:
+			ret = EINVAL;
+		}
+
+		name = va_arg(ap, char *);
+	}
+	return (ret);
+}
+
+void
+fm_payload_set(nvlist_t *payload, ...)
+{
+	int ret;
+	const char *name;
+	va_list ap;
+
+	va_start(ap, payload);
+	name = va_arg(ap, char *);
+	ret = i_fm_payload_set(payload, name, ap);
+	va_end(ap);
+
+	if (ret)
+		atomic_add_64(
+		    &erpt_kstat_data.payload_set_failed.value.ui64, 1);
+}
+
+/*
+ * Set-up and validate the members of an ereport event according to:
+ *
+ *	Member name		Type		Value
+ *	====================================================
+ *	class			string		ereport
+ *	version			uint8_t		0
+ *	ena			uint64_t	<ena>
+ *	detector		nvlist_t	<detector>
+ *	ereport-payload		nvlist_t	<var args>
+ *
+ * We don't actually add a 'version' member to the payload.  Really,
+ * the version quoted to us by our caller is that of the category 1
+ * "ereport" event class (and we require FM_EREPORT_VERS0) but
+ * the payload version of the actual leaf class event under construction
+ * may be something else.  Callers should supply a version in the varargs,
+ * or (better) we could take two version arguments - one for the
+ * ereport category 1 classification (expect FM_EREPORT_VERS0) and one
+ * for the leaf class.
+ */
+void
+fm_ereport_set(nvlist_t *ereport, int version, const char *erpt_class,
+    uint64_t ena, const nvlist_t *detector, ...)
+{
+	char ereport_class[FM_MAX_CLASS];
+	const char *name;
+	va_list ap;
+	int ret;
+
+	if (version != FM_EREPORT_VERS0) {
+		atomic_add_64(&erpt_kstat_data.erpt_set_failed.value.ui64, 1);
+		return;
+	}
+
+	(void) snprintf(ereport_class, FM_MAX_CLASS, "%s.%s",
+	    FM_EREPORT_CLASS, erpt_class);
+	if (nvlist_add_string(ereport, FM_CLASS, ereport_class) != 0) {
+		atomic_add_64(&erpt_kstat_data.erpt_set_failed.value.ui64, 1);
+		return;
+	}
+
+	if (nvlist_add_uint64(ereport, FM_EREPORT_ENA, ena)) {
+		atomic_add_64(&erpt_kstat_data.erpt_set_failed.value.ui64, 1);
+	}
+
+	if (nvlist_add_nvlist(ereport, FM_EREPORT_DETECTOR,
+	    (nvlist_t *)detector) != 0) {
+		atomic_add_64(&erpt_kstat_data.erpt_set_failed.value.ui64, 1);
+	}
+
+	va_start(ap, detector);
+	name = va_arg(ap, const char *);
+	ret = i_fm_payload_set(ereport, name, ap);
+	va_end(ap);
+
+	if (ret)
+		atomic_add_64(&erpt_kstat_data.erpt_set_failed.value.ui64, 1);
+}
+
+/*
+ * Set-up and validate the members of an hc fmri according to;
+ *
+ *	Member name		Type		Value
+ *	===================================================
+ *	version			uint8_t		0
+ *	auth			nvlist_t	<auth>
+ *	hc-name			string		<name>
+ *	hc-id			string		<id>
+ *
+ * Note that auth and hc-id are optional members.
+ */
+
+#define	HC_MAXPAIRS	20
+#define	HC_MAXNAMELEN	50
+
+static int
+fm_fmri_hc_set_common(nvlist_t *fmri, int version, const nvlist_t *auth)
+{
+	if (version != FM_HC_SCHEME_VERSION) {
+		atomic_add_64(&erpt_kstat_data.fmri_set_failed.value.ui64, 1);
+		return (0);
+	}
+
+	if (nvlist_add_uint8(fmri, FM_VERSION, version) != 0 ||
+	    nvlist_add_string(fmri, FM_FMRI_SCHEME, FM_FMRI_SCHEME_HC) != 0) {
+		atomic_add_64(&erpt_kstat_data.fmri_set_failed.value.ui64, 1);
+		return (0);
+	}
+
+	if (auth != NULL && nvlist_add_nvlist(fmri, FM_FMRI_AUTHORITY,
+	    (nvlist_t *)auth) != 0) {
+		atomic_add_64(&erpt_kstat_data.fmri_set_failed.value.ui64, 1);
+		return (0);
+	}
+
+	return (1);
+}
+
+void
+fm_fmri_hc_set(nvlist_t *fmri, int version, const nvlist_t *auth,
+    nvlist_t *snvl, int npairs, ...)
+{
+	nv_alloc_t *nva = nvlist_lookup_nv_alloc(fmri);
+	nvlist_t *pairs[HC_MAXPAIRS];
+	va_list ap;
+	int i;
+
+	if (!fm_fmri_hc_set_common(fmri, version, auth))
+		return;
+
+	npairs = MIN(npairs, HC_MAXPAIRS);
+
+	va_start(ap, npairs);
+	for (i = 0; i < npairs; i++) {
+		const char *name = va_arg(ap, const char *);
+		uint32_t id = va_arg(ap, uint32_t);
+		char idstr[11];
+
+		(void) snprintf(idstr, sizeof (idstr), "%u", id);
+
+		pairs[i] = fm_nvlist_create(nva);
+		if (nvlist_add_string(pairs[i], FM_FMRI_HC_NAME, name) != 0 ||
+		    nvlist_add_string(pairs[i], FM_FMRI_HC_ID, idstr) != 0) {
+			atomic_add_64(
+			    &erpt_kstat_data.fmri_set_failed.value.ui64, 1);
+		}
+	}
+	va_end(ap);
+
+	if (nvlist_add_nvlist_array(fmri, FM_FMRI_HC_LIST, pairs, npairs) != 0)
+		atomic_add_64(&erpt_kstat_data.fmri_set_failed.value.ui64, 1);
+
+	for (i = 0; i < npairs; i++)
+		fm_nvlist_destroy(pairs[i], FM_NVA_RETAIN);
+
+	if (snvl != NULL) {
+		if (nvlist_add_nvlist(fmri, FM_FMRI_HC_SPECIFIC, snvl) != 0) {
+			atomic_add_64(
+			    &erpt_kstat_data.fmri_set_failed.value.ui64, 1);
+		}
+	}
+}
+
+void
+fm_fmri_hc_create(nvlist_t *fmri, int version, const nvlist_t *auth,
+    nvlist_t *snvl, nvlist_t *bboard, int npairs, ...)
+{
+	nv_alloc_t *nva = nvlist_lookup_nv_alloc(fmri);
+	nvlist_t *pairs[HC_MAXPAIRS];
+	nvlist_t **hcl;
+	uint_t n;
+	int i, j;
+	va_list ap;
+	char *hcname, *hcid;
+
+	if (!fm_fmri_hc_set_common(fmri, version, auth))
+		return;
+
+	/*
+	 * copy the bboard nvpairs to the pairs array
+	 */
+	if (nvlist_lookup_nvlist_array(bboard, FM_FMRI_HC_LIST, &hcl, &n)
+	    != 0) {
+		atomic_add_64(&erpt_kstat_data.fmri_set_failed.value.ui64, 1);
+		return;
+	}
+
+	for (i = 0; i < n; i++) {
+		if (nvlist_lookup_string(hcl[i], FM_FMRI_HC_NAME,
+		    &hcname) != 0) {
+			atomic_add_64(
+			    &erpt_kstat_data.fmri_set_failed.value.ui64, 1);
+			return;
+		}
+		if (nvlist_lookup_string(hcl[i], FM_FMRI_HC_ID, &hcid) != 0) {
+			atomic_add_64(
+			    &erpt_kstat_data.fmri_set_failed.value.ui64, 1);
+			return;
+		}
+
+		pairs[i] = fm_nvlist_create(nva);
+		if (nvlist_add_string(pairs[i], FM_FMRI_HC_NAME, hcname) != 0 ||
+		    nvlist_add_string(pairs[i], FM_FMRI_HC_ID, hcid) != 0) {
+			for (j = 0; j <= i; j++) {
+				if (pairs[j] != NULL)
+					fm_nvlist_destroy(pairs[j],
+					    FM_NVA_RETAIN);
+			}
+			atomic_add_64(
+			    &erpt_kstat_data.fmri_set_failed.value.ui64, 1);
+			return;
+		}
+	}
+
+	/*
+	 * create the pairs from passed in pairs
+	 */
+	npairs = MIN(npairs, HC_MAXPAIRS);
+
+	va_start(ap, npairs);
+	for (i = n; i < npairs + n; i++) {
+		const char *name = va_arg(ap, const char *);
+		uint32_t id = va_arg(ap, uint32_t);
+		char idstr[11];
+		(void) snprintf(idstr, sizeof (idstr), "%u", id);
+		pairs[i] = fm_nvlist_create(nva);
+		if (nvlist_add_string(pairs[i], FM_FMRI_HC_NAME, name) != 0 ||
+		    nvlist_add_string(pairs[i], FM_FMRI_HC_ID, idstr) != 0) {
+			for (j = 0; j <= i; j++) {
+				if (pairs[j] != NULL)
+					fm_nvlist_destroy(pairs[j],
+					    FM_NVA_RETAIN);
+			}
+			atomic_add_64(
+			    &erpt_kstat_data.fmri_set_failed.value.ui64, 1);
+			return;
+		}
+	}
+	va_end(ap);
+
+	/*
+	 * Create the fmri hc list
+	 */
+	if (nvlist_add_nvlist_array(fmri, FM_FMRI_HC_LIST, pairs,
+	    npairs + n) != 0) {
+		atomic_add_64(&erpt_kstat_data.fmri_set_failed.value.ui64, 1);
+		return;
+	}
+
+	for (i = 0; i < npairs + n; i++) {
+			fm_nvlist_destroy(pairs[i], FM_NVA_RETAIN);
+	}
+
+	if (snvl != NULL) {
+		if (nvlist_add_nvlist(fmri, FM_FMRI_HC_SPECIFIC, snvl) != 0) {
+			atomic_add_64(
+			    &erpt_kstat_data.fmri_set_failed.value.ui64, 1);
+			return;
+		}
+	}
+}
+
+/*
+ * Set-up and validate the members of an dev fmri according to:
+ *
+ *	Member name		Type		Value
+ *	====================================================
+ *	version			uint8_t		0
+ *	auth			nvlist_t	<auth>
+ *	devpath			string		<devpath>
+ *	[devid]			string		<devid>
+ *	[target-port-l0id]	string		<target-port-lun0-id>
+ *
+ * Note that auth and devid are optional members.
+ */
+void
+fm_fmri_dev_set(nvlist_t *fmri_dev, int version, const nvlist_t *auth,
+    const char *devpath, const char *devid, const char *tpl0)
+{
+	int err = 0;
+
+	if (version != DEV_SCHEME_VERSION0) {
+		atomic_add_64(&erpt_kstat_data.fmri_set_failed.value.ui64, 1);
+		return;
+	}
+
+	err |= nvlist_add_uint8(fmri_dev, FM_VERSION, version);
+	err |= nvlist_add_string(fmri_dev, FM_FMRI_SCHEME, FM_FMRI_SCHEME_DEV);
+
+	if (auth != NULL) {
+		err |= nvlist_add_nvlist(fmri_dev, FM_FMRI_AUTHORITY,
+		    (nvlist_t *)auth);
+	}
+
+	err |= nvlist_add_string(fmri_dev, FM_FMRI_DEV_PATH, devpath);
+
+	if (devid != NULL)
+		err |= nvlist_add_string(fmri_dev, FM_FMRI_DEV_ID, devid);
+
+	if (tpl0 != NULL)
+		err |= nvlist_add_string(fmri_dev, FM_FMRI_DEV_TGTPTLUN0, tpl0);
+
+	if (err)
+		atomic_add_64(&erpt_kstat_data.fmri_set_failed.value.ui64, 1);
+
+}
+
+/*
+ * Set-up and validate the members of an cpu fmri according to:
+ *
+ *	Member name		Type		Value
+ *	====================================================
+ *	version			uint8_t		0
+ *	auth			nvlist_t	<auth>
+ *	cpuid			uint32_t	<cpu_id>
+ *	cpumask			uint8_t		<cpu_mask>
+ *	serial			uint64_t	<serial_id>
+ *
+ * Note that auth, cpumask, serial are optional members.
+ *
+ */
+void
+fm_fmri_cpu_set(nvlist_t *fmri_cpu, int version, const nvlist_t *auth,
+    uint32_t cpu_id, uint8_t *cpu_maskp, const char *serial_idp)
+{
+	uint64_t *failedp = &erpt_kstat_data.fmri_set_failed.value.ui64;
+
+	if (version < CPU_SCHEME_VERSION1) {
+		atomic_add_64(failedp, 1);
+		return;
+	}
+
+	if (nvlist_add_uint8(fmri_cpu, FM_VERSION, version) != 0) {
+		atomic_add_64(failedp, 1);
+		return;
+	}
+
+	if (nvlist_add_string(fmri_cpu, FM_FMRI_SCHEME,
+	    FM_FMRI_SCHEME_CPU) != 0) {
+		atomic_add_64(failedp, 1);
+		return;
+	}
+
+	if (auth != NULL && nvlist_add_nvlist(fmri_cpu, FM_FMRI_AUTHORITY,
+	    (nvlist_t *)auth) != 0)
+		atomic_add_64(failedp, 1);
+
+	if (nvlist_add_uint32(fmri_cpu, FM_FMRI_CPU_ID, cpu_id) != 0)
+		atomic_add_64(failedp, 1);
+
+	if (cpu_maskp != NULL && nvlist_add_uint8(fmri_cpu, FM_FMRI_CPU_MASK,
+	    *cpu_maskp) != 0)
+		atomic_add_64(failedp, 1);
+
+	if (serial_idp == NULL || nvlist_add_string(fmri_cpu,
+	    FM_FMRI_CPU_SERIAL_ID, (char *)serial_idp) != 0)
+			atomic_add_64(failedp, 1);
+}
+
+/*
+ * Set-up and validate the members of a mem according to:
+ *
+ *	Member name		Type		Value
+ *	====================================================
+ *	version			uint8_t		0
+ *	auth			nvlist_t	<auth>		[optional]
+ *	unum			string		<unum>
+ *	serial			string		<serial>	[optional*]
+ *	offset			uint64_t	<offset>	[optional]
+ *
+ *	* serial is required if offset is present
+ */
+void
+fm_fmri_mem_set(nvlist_t *fmri, int version, const nvlist_t *auth,
+    const char *unum, const char *serial, uint64_t offset)
+{
+	if (version != MEM_SCHEME_VERSION0) {
+		atomic_add_64(&erpt_kstat_data.fmri_set_failed.value.ui64, 1);
+		return;
+	}
+
+	if (!serial && (offset != (uint64_t)-1)) {
+		atomic_add_64(&erpt_kstat_data.fmri_set_failed.value.ui64, 1);
+		return;
+	}
+
+	if (nvlist_add_uint8(fmri, FM_VERSION, version) != 0) {
+		atomic_add_64(&erpt_kstat_data.fmri_set_failed.value.ui64, 1);
+		return;
+	}
+
+	if (nvlist_add_string(fmri, FM_FMRI_SCHEME, FM_FMRI_SCHEME_MEM) != 0) {
+		atomic_add_64(&erpt_kstat_data.fmri_set_failed.value.ui64, 1);
+		return;
+	}
+
+	if (auth != NULL) {
+		if (nvlist_add_nvlist(fmri, FM_FMRI_AUTHORITY,
+		    (nvlist_t *)auth) != 0) {
+			atomic_add_64(
+			    &erpt_kstat_data.fmri_set_failed.value.ui64, 1);
+		}
+	}
+
+	if (nvlist_add_string(fmri, FM_FMRI_MEM_UNUM, unum) != 0) {
+		atomic_add_64(&erpt_kstat_data.fmri_set_failed.value.ui64, 1);
+	}
+
+	if (serial != NULL) {
+		if (nvlist_add_string_array(fmri, FM_FMRI_MEM_SERIAL_ID,
+		    (char **)&serial, 1) != 0) {
+			atomic_add_64(
+			    &erpt_kstat_data.fmri_set_failed.value.ui64, 1);
+		}
+		if (offset != (uint64_t)-1) {
+			if (nvlist_add_uint64(fmri, FM_FMRI_MEM_OFFSET,
+			    offset) != 0) {
+				atomic_add_64(&erpt_kstat_data.
+				    fmri_set_failed.value.ui64, 1);
+			}
+		}
+	}
+}
+
+void
+fm_fmri_zfs_set(nvlist_t *fmri, int version, uint64_t pool_guid,
+    uint64_t vdev_guid)
+{
+	if (version != ZFS_SCHEME_VERSION0) {
+		atomic_add_64(&erpt_kstat_data.fmri_set_failed.value.ui64, 1);
+		return;
+	}
+
+	if (nvlist_add_uint8(fmri, FM_VERSION, version) != 0) {
+		atomic_add_64(&erpt_kstat_data.fmri_set_failed.value.ui64, 1);
+		return;
+	}
+
+	if (nvlist_add_string(fmri, FM_FMRI_SCHEME, FM_FMRI_SCHEME_ZFS) != 0) {
+		atomic_add_64(&erpt_kstat_data.fmri_set_failed.value.ui64, 1);
+		return;
+	}
+
+	if (nvlist_add_uint64(fmri, FM_FMRI_ZFS_POOL, pool_guid) != 0) {
+		atomic_add_64(&erpt_kstat_data.fmri_set_failed.value.ui64, 1);
+	}
+
+	if (vdev_guid != 0) {
+		if (nvlist_add_uint64(fmri, FM_FMRI_ZFS_VDEV, vdev_guid) != 0) {
+			atomic_add_64(
+			    &erpt_kstat_data.fmri_set_failed.value.ui64, 1);
+		}
+	}
+}
+
+uint64_t
+fm_ena_increment(uint64_t ena)
+{
+	uint64_t new_ena;
+
+	switch (ENA_FORMAT(ena)) {
+	case FM_ENA_FMT1:
+		new_ena = ena + (1 << ENA_FMT1_GEN_SHFT);
+		break;
+	case FM_ENA_FMT2:
+		new_ena = ena + (1 << ENA_FMT2_GEN_SHFT);
+		break;
+	default:
+		new_ena = 0;
+	}
+
+	return (new_ena);
+}
+
+uint64_t
+fm_ena_generate_cpu(uint64_t timestamp, processorid_t cpuid, uchar_t format)
+{
+	uint64_t ena = 0;
+
+	switch (format) {
+	case FM_ENA_FMT1:
+		if (timestamp) {
+			ena = (uint64_t)((format & ENA_FORMAT_MASK) |
+			    ((cpuid << ENA_FMT1_CPUID_SHFT) &
+			    ENA_FMT1_CPUID_MASK) |
+			    ((timestamp << ENA_FMT1_TIME_SHFT) &
+			    ENA_FMT1_TIME_MASK));
+		} else {
+			ena = (uint64_t)((format & ENA_FORMAT_MASK) |
+			    ((cpuid << ENA_FMT1_CPUID_SHFT) &
+			    ENA_FMT1_CPUID_MASK) |
+			    ((gethrtime() << ENA_FMT1_TIME_SHFT) &
+			    ENA_FMT1_TIME_MASK));
+		}
+		break;
+	case FM_ENA_FMT2:
+		ena = (uint64_t)((format & ENA_FORMAT_MASK) |
+		    ((timestamp << ENA_FMT2_TIME_SHFT) & ENA_FMT2_TIME_MASK));
+		break;
+	default:
+		break;
+	}
+
+	return (ena);
+}
+
+uint64_t
+fm_ena_generate(uint64_t timestamp, uchar_t format)
+{
+	uint64_t ena;
+
+	kpreempt_disable();
+	ena = fm_ena_generate_cpu(timestamp, getcpuid(), format);
+	kpreempt_enable();
+
+	return (ena);
+}
+
+uint64_t
+fm_ena_generation_get(uint64_t ena)
+{
+	uint64_t gen;
+
+	switch (ENA_FORMAT(ena)) {
+	case FM_ENA_FMT1:
+		gen = (ena & ENA_FMT1_GEN_MASK) >> ENA_FMT1_GEN_SHFT;
+		break;
+	case FM_ENA_FMT2:
+		gen = (ena & ENA_FMT2_GEN_MASK) >> ENA_FMT2_GEN_SHFT;
+		break;
+	default:
+		gen = 0;
+		break;
+	}
+
+	return (gen);
+}
+
+uchar_t
+fm_ena_format_get(uint64_t ena)
+{
+
+	return (ENA_FORMAT(ena));
+}
+
+uint64_t
+fm_ena_id_get(uint64_t ena)
+{
+	uint64_t id;
+
+	switch (ENA_FORMAT(ena)) {
+	case FM_ENA_FMT1:
+		id = (ena & ENA_FMT1_ID_MASK) >> ENA_FMT1_ID_SHFT;
+		break;
+	case FM_ENA_FMT2:
+		id = (ena & ENA_FMT2_ID_MASK) >> ENA_FMT2_ID_SHFT;
+		break;
+	default:
+		id = 0;
+	}
+
+	return (id);
+}
+
+uint64_t
+fm_ena_time_get(uint64_t ena)
+{
+	uint64_t time;
+
+	switch (ENA_FORMAT(ena)) {
+	case FM_ENA_FMT1:
+		time = (ena & ENA_FMT1_TIME_MASK) >> ENA_FMT1_TIME_SHFT;
+		break;
+	case FM_ENA_FMT2:
+		time = (ena & ENA_FMT2_TIME_MASK) >> ENA_FMT2_TIME_SHFT;
+		break;
+	default:
+		time = 0;
+	}
+
+	return (time);
+}
+
+#ifdef _KERNEL
+void
+fm_init(void)
+{
+	zevent_len_cur = 0;
+	zevent_flags = 0;
+
+	if (zfs_zevent_len_max == 0)
+		zfs_zevent_len_max = ERPT_MAX_ERRS * MAX(max_ncpus, 4);
+
+	/* Initialize zevent allocation and generation kstats */
+	fm_ksp = kstat_create("zfs", 0, "fm", "misc", KSTAT_TYPE_NAMED,
+	    sizeof (struct erpt_kstat) / sizeof (kstat_named_t),
+	    KSTAT_FLAG_VIRTUAL);
+
+	if (fm_ksp != NULL) {
+		fm_ksp->ks_data = &erpt_kstat_data;
+		kstat_install(fm_ksp);
+	} else {
+		cmn_err(CE_NOTE, "failed to create fm/misc kstat\n");
+	}
+
+	mutex_init(&zevent_lock, NULL, MUTEX_DEFAULT, NULL);
+	list_create(&zevent_list, sizeof (zevent_t),
+	    offsetof(zevent_t, ev_node));
+	cv_init(&zevent_cv, NULL, CV_DEFAULT, NULL);
+}
+
+void
+fm_fini(void)
+{
+	int count;
+
+	zfs_zevent_drain_all(&count);
+
+	mutex_enter(&zevent_lock);
+	cv_broadcast(&zevent_cv);
+
+	zevent_flags |= ZEVENT_SHUTDOWN;
+	while (zevent_waiters > 0) {
+		mutex_exit(&zevent_lock);
+		schedule();
+		mutex_enter(&zevent_lock);
+	}
+	mutex_exit(&zevent_lock);
+
+	cv_destroy(&zevent_cv);
+	list_destroy(&zevent_list);
+	mutex_destroy(&zevent_lock);
+
+	if (fm_ksp != NULL) {
+		kstat_delete(fm_ksp);
+		fm_ksp = NULL;
+	}
+}
+
+module_param(zfs_zevent_len_max, int, 0644);
+MODULE_PARM_DESC(zfs_zevent_len_max, "Max event queue length");
+
+module_param(zfs_zevent_cols, int, 0644);
+MODULE_PARM_DESC(zfs_zevent_cols, "Max event column width");
+
+module_param(zfs_zevent_console, int, 0644);
+MODULE_PARM_DESC(zfs_zevent_console, "Log events to the console");
+
+#endif /* _KERNEL */
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/module/zfs/gzip.c
@@ -0,0 +1,82 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+
+#include <sys/debug.h>
+#include <sys/types.h>
+
+#ifdef _KERNEL
+
+#include <sys/systm.h>
+#include <sys/zmod.h>
+
+typedef size_t zlen_t;
+#define	compress_func	z_compress_level
+#define	uncompress_func	z_uncompress
+
+#else /* _KERNEL */
+
+#include <strings.h>
+#include <zlib.h>
+
+typedef uLongf zlen_t;
+#define	compress_func	compress2
+#define	uncompress_func	uncompress
+
+#endif
+
+size_t
+gzip_compress(void *s_start, void *d_start, size_t s_len, size_t d_len, int n)
+{
+	zlen_t dstlen = d_len;
+
+	ASSERT(d_len <= s_len);
+
+	if (compress_func(d_start, &dstlen, s_start, s_len, n) != Z_OK) {
+		if (d_len != s_len)
+			return (s_len);
+
+		bcopy(s_start, d_start, s_len);
+		return (s_len);
+	}
+
+	return ((size_t) dstlen);
+}
+
+/*ARGSUSED*/
+int
+gzip_decompress(void *s_start, void *d_start, size_t s_len, size_t d_len, int n)
+{
+	zlen_t dstlen = d_len;
+
+	ASSERT(d_len >= s_len);
+
+	if (uncompress_func(d_start, &dstlen, s_start, s_len) != Z_OK)
+		return (-1);
+
+	return (0);
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/module/zfs/lz4.c
@@ -0,0 +1,1019 @@
+/*
+ * LZ4 - Fast LZ compression algorithm
+ * Header File
+ * Copyright (C) 2011-2013, Yann Collet.
+ * BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You can contact the author at :
+ * - LZ4 homepage : http://fastcompression.blogspot.com/p/lz4.html
+ * - LZ4 source repository : http://code.google.com/p/lz4/
+ */
+
+#include <sys/zfs_context.h>
+
+static int real_LZ4_compress(const char *source, char *dest, int isize,
+    int osize);
+static int LZ4_uncompress_unknownOutputSize(const char *source, char *dest,
+    int isize, int maxOutputSize);
+static int LZ4_compressCtx(void *ctx, const char *source, char *dest,
+    int isize, int osize);
+static int LZ4_compress64kCtx(void *ctx, const char *source, char *dest,
+    int isize, int osize);
+
+static kmem_cache_t *lz4_cache;
+
+/*ARGSUSED*/
+size_t
+lz4_compress_zfs(void *s_start, void *d_start, size_t s_len,
+    size_t d_len, int n)
+{
+	uint32_t bufsiz;
+	char *dest = d_start;
+
+	ASSERT(d_len >= sizeof (bufsiz));
+
+	bufsiz = real_LZ4_compress(s_start, &dest[sizeof (bufsiz)], s_len,
+	    d_len - sizeof (bufsiz));
+
+	/* Signal an error if the compression routine returned zero. */
+	if (bufsiz == 0)
+		return (s_len);
+
+	/*
+	 * Encode the compresed buffer size at the start. We'll need this in
+	 * decompression to counter the effects of padding which might be
+	 * added to the compressed buffer and which, if unhandled, would
+	 * confuse the hell out of our decompression function.
+	 */
+	*(uint32_t *)dest = BE_32(bufsiz);
+
+	return (bufsiz + sizeof (bufsiz));
+}
+
+/*ARGSUSED*/
+int
+lz4_decompress_zfs(void *s_start, void *d_start, size_t s_len,
+    size_t d_len, int n)
+{
+	const char *src = s_start;
+	uint32_t bufsiz = BE_IN32(src);
+
+	/* invalid compressed buffer size encoded at start */
+	if (bufsiz + sizeof (bufsiz) > s_len)
+		return (1);
+
+	/*
+	 * Returns 0 on success (decompression function returned non-negative)
+	 * and non-zero on failure (decompression function returned negative.
+	 */
+	return (LZ4_uncompress_unknownOutputSize(&src[sizeof (bufsiz)],
+	    d_start, bufsiz, d_len) < 0);
+}
+
+/*
+ * LZ4 API Description:
+ *
+ * Simple Functions:
+ * real_LZ4_compress() :
+ * 	isize  : is the input size. Max supported value is ~1.9GB
+ * 	return : the number of bytes written in buffer dest
+ *		 or 0 if the compression fails (if LZ4_COMPRESSMIN is set).
+ * 	note : destination buffer must be already allocated.
+ * 		destination buffer must be sized to handle worst cases
+ * 		situations (input data not compressible) worst case size
+ * 		evaluation is provided by function LZ4_compressBound().
+ *
+ * real_LZ4_uncompress() :
+ * 	osize  : is the output size, therefore the original size
+ * 	return : the number of bytes read in the source buffer.
+ * 		If the source stream is malformed, the function will stop
+ * 		decoding and return a negative result, indicating the byte
+ * 		position of the faulty instruction. This function never
+ * 		writes beyond dest + osize, and is therefore protected
+ * 		against malicious data packets.
+ * 	note : destination buffer must be already allocated
+ *	note : real_LZ4_uncompress() is not used in ZFS so its code
+ *	       is not present here.
+ *
+ * Advanced Functions
+ *
+ * LZ4_compressBound() :
+ * 	Provides the maximum size that LZ4 may output in a "worst case"
+ * 	scenario (input data not compressible) primarily useful for memory
+ * 	allocation of output buffer.
+ *
+ * 	isize  : is the input size. Max supported value is ~1.9GB
+ * 	return : maximum output size in a "worst case" scenario
+ * 	note : this function is limited by "int" range (2^31-1)
+ *
+ * LZ4_uncompress_unknownOutputSize() :
+ * 	isize  : is the input size, therefore the compressed size
+ * 	maxOutputSize : is the size of the destination buffer (which must be
+ * 		already allocated)
+ * 	return : the number of bytes decoded in the destination buffer
+ * 		(necessarily <= maxOutputSize). If the source stream is
+ * 		malformed, the function will stop decoding and return a
+ * 		negative result, indicating the byte position of the faulty
+ * 		instruction. This function never writes beyond dest +
+ * 		maxOutputSize, and is therefore protected against malicious
+ * 		data packets.
+ * 	note   : Destination buffer must be already allocated.
+ *		This version is slightly slower than real_LZ4_uncompress()
+ *
+ * LZ4_compressCtx() :
+ * 	This function explicitly handles the CTX memory structure.
+ *
+ * 	ILLUMOS CHANGES: the CTX memory structure must be explicitly allocated
+ * 	by the caller (either on the stack or using kmem_cache_alloc). Passing
+ * 	NULL isn't valid.
+ *
+ * LZ4_compress64kCtx() :
+ * 	Same as LZ4_compressCtx(), but specific to small inputs (<64KB).
+ * 	isize *Must* be <64KB, otherwise the output will be corrupted.
+ *
+ * 	ILLUMOS CHANGES: the CTX memory structure must be explicitly allocated
+ * 	by the caller (either on the stack or using kmem_cache_alloc). Passing
+ * 	NULL isn't valid.
+ */
+
+/*
+ * Tuning parameters
+ */
+
+/*
+ * COMPRESSIONLEVEL: Increasing this value improves compression ratio
+ *	 Lowering this value reduces memory usage. Reduced memory usage
+ *	typically improves speed, due to cache effect (ex: L1 32KB for Intel,
+ *	L1 64KB for AMD). Memory usage formula : N->2^(N+2) Bytes
+ *	(examples : 12 -> 16KB ; 17 -> 512KB)
+ */
+#define	COMPRESSIONLEVEL 12
+
+/*
+ * NOTCOMPRESSIBLE_CONFIRMATION: Decreasing this value will make the
+ *	algorithm skip faster data segments considered "incompressible".
+ *	This may decrease compression ratio dramatically, but will be
+ *	faster on incompressible data. Increasing this value will make
+ *	the algorithm search more before declaring a segment "incompressible".
+ *	This could improve compression a bit, but will be slower on
+ *	incompressible data. The default value (6) is recommended.
+ */
+#define	NOTCOMPRESSIBLE_CONFIRMATION 6
+
+/*
+ * BIG_ENDIAN_NATIVE_BUT_INCOMPATIBLE: This will provide a boost to
+ * performance for big endian cpu, but the resulting compressed stream
+ * will be incompatible with little-endian CPU. You can set this option
+ * to 1 in situations where data will stay within closed environment.
+ * This option is useless on Little_Endian CPU (such as x86).
+ */
+/* #define	BIG_ENDIAN_NATIVE_BUT_INCOMPATIBLE 1 */
+
+/*
+ * CPU Feature Detection
+ */
+
+/* 32 or 64 bits ? */
+#if defined(_LP64)
+#define	LZ4_ARCH64 1
+#else
+#define	LZ4_ARCH64 0
+#endif
+
+/*
+ * Little Endian or Big Endian?
+ * Note: overwrite the below #define if you know your architecture endianess.
+ */
+#if defined(_BIG_ENDIAN)
+#define	LZ4_BIG_ENDIAN 1
+#else
+/*
+ * Little Endian assumed. PDP Endian and other very rare endian format
+ * are unsupported.
+ */
+#undef LZ4_BIG_ENDIAN
+#endif
+
+/*
+ * Unaligned memory access is automatically enabled for "common" CPU,
+ * such as x86. For others CPU, the compiler will be more cautious, and
+ * insert extra code to ensure aligned access is respected. If you know
+ * your target CPU supports unaligned memory access, you may want to
+ * force this option manually to improve performance
+ */
+#if defined(__ARM_FEATURE_UNALIGNED)
+#define	LZ4_FORCE_UNALIGNED_ACCESS 1
+#endif
+
+/*
+ * Illumos : we can't use GCC's __builtin_ctz family of builtins in the
+ * kernel
+ * Linux : we can use GCC's __builtin_ctz family of builtins in the
+ * kernel
+ */
+#undef	LZ4_FORCE_SW_BITCOUNT
+#if defined(__sparc)
+#define	LZ4_FORCE_SW_BITCOUNT
+#endif
+
+/*
+ * Compiler Options
+ */
+/* Disable restrict */
+#define	restrict
+
+/*
+ * Linux : GCC_VERSION is defined as of 3.9-rc1, so undefine it.
+ * torvalds/linux@3f3f8d2f48acfd8ed3b8e6b7377935da57b27b16
+ */
+#ifdef GCC_VERSION
+#undef GCC_VERSION
+#endif
+
+#define	GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)
+
+#if (GCC_VERSION >= 302) || (__INTEL_COMPILER >= 800) || defined(__clang__)
+#define	expect(expr, value)    (__builtin_expect((expr), (value)))
+#else
+#define	expect(expr, value)    (expr)
+#endif
+
+#ifndef likely
+#define	likely(expr)	expect((expr) != 0, 1)
+#endif
+
+#ifndef unlikely
+#define	unlikely(expr)	expect((expr) != 0, 0)
+#endif
+
+#define	lz4_bswap16(x) ((unsigned short int) ((((x) >> 8) & 0xffu) | \
+	(((x) & 0xffu) << 8)))
+
+/* Basic types */
+#define	BYTE	uint8_t
+#define	U16	uint16_t
+#define	U32	uint32_t
+#define	S32	int32_t
+#define	U64	uint64_t
+
+#ifndef LZ4_FORCE_UNALIGNED_ACCESS
+#pragma pack(1)
+#endif
+
+typedef struct _U16_S {
+	U16 v;
+} U16_S;
+typedef struct _U32_S {
+	U32 v;
+} U32_S;
+typedef struct _U64_S {
+	U64 v;
+} U64_S;
+
+#ifndef LZ4_FORCE_UNALIGNED_ACCESS
+#pragma pack()
+#endif
+
+#define	A64(x) (((U64_S *)(x))->v)
+#define	A32(x) (((U32_S *)(x))->v)
+#define	A16(x) (((U16_S *)(x))->v)
+
+/*
+ * Constants
+ */
+#define	MINMATCH 4
+
+#define	HASH_LOG COMPRESSIONLEVEL
+#define	HASHTABLESIZE (1 << HASH_LOG)
+#define	HASH_MASK (HASHTABLESIZE - 1)
+
+#define	SKIPSTRENGTH (NOTCOMPRESSIBLE_CONFIRMATION > 2 ? \
+	NOTCOMPRESSIBLE_CONFIRMATION : 2)
+
+#define	COPYLENGTH 8
+#define	LASTLITERALS 5
+#define	MFLIMIT (COPYLENGTH + MINMATCH)
+#define	MINLENGTH (MFLIMIT + 1)
+
+#define	MAXD_LOG 16
+#define	MAX_DISTANCE ((1 << MAXD_LOG) - 1)
+
+#define	ML_BITS 4
+#define	ML_MASK ((1U<<ML_BITS)-1)
+#define	RUN_BITS (8-ML_BITS)
+#define	RUN_MASK ((1U<<RUN_BITS)-1)
+
+
+/*
+ * Architecture-specific macros
+ */
+#if LZ4_ARCH64
+#define	STEPSIZE 8
+#define	UARCH U64
+#define	AARCH A64
+#define	LZ4_COPYSTEP(s, d)	A64(d) = A64(s); d += 8; s += 8;
+#define	LZ4_COPYPACKET(s, d)	LZ4_COPYSTEP(s, d)
+#define	LZ4_SECURECOPY(s, d, e)	if (d < e) LZ4_WILDCOPY(s, d, e)
+#define	HTYPE U32
+#define	INITBASE(base)		const BYTE* const base = ip
+#else /* !LZ4_ARCH64 */
+#define	STEPSIZE 4
+#define	UARCH U32
+#define	AARCH A32
+#define	LZ4_COPYSTEP(s, d)	A32(d) = A32(s); d += 4; s += 4;
+#define	LZ4_COPYPACKET(s, d)	LZ4_COPYSTEP(s, d); LZ4_COPYSTEP(s, d);
+#define	LZ4_SECURECOPY		LZ4_WILDCOPY
+#define	HTYPE const BYTE *
+#define	INITBASE(base)		const int base = 0
+#endif /* !LZ4_ARCH64 */
+
+#if (defined(LZ4_BIG_ENDIAN) && !defined(BIG_ENDIAN_NATIVE_BUT_INCOMPATIBLE))
+#define	LZ4_READ_LITTLEENDIAN_16(d, s, p) \
+	{ U16 v = A16(p); v = lz4_bswap16(v); d = (s) - v; }
+#define	LZ4_WRITE_LITTLEENDIAN_16(p, i) \
+	{ U16 v = (U16)(i); v = lz4_bswap16(v); A16(p) = v; p += 2; }
+#else
+#define	LZ4_READ_LITTLEENDIAN_16(d, s, p) { d = (s) - A16(p); }
+#define	LZ4_WRITE_LITTLEENDIAN_16(p, v)  { A16(p) = v; p += 2; }
+#endif
+
+
+/* Local structures */
+struct refTables {
+	HTYPE hashTable[HASHTABLESIZE];
+};
+
+
+/* Macros */
+#define	LZ4_HASH_FUNCTION(i) (((i) * 2654435761U) >> ((MINMATCH * 8) - \
+	HASH_LOG))
+#define	LZ4_HASH_VALUE(p) LZ4_HASH_FUNCTION(A32(p))
+#define	LZ4_WILDCOPY(s, d, e) do { LZ4_COPYPACKET(s, d) } while (d < e);
+#define	LZ4_BLINDCOPY(s, d, l) { BYTE* e = (d) + l; LZ4_WILDCOPY(s, d, e); \
+	d = e; }
+
+
+/* Private functions */
+#if LZ4_ARCH64
+
+static inline int
+LZ4_NbCommonBytes(register U64 val)
+{
+#if defined(LZ4_BIG_ENDIAN)
+#if defined(__GNUC__) && (GCC_VERSION >= 304) && \
+	!defined(LZ4_FORCE_SW_BITCOUNT)
+	return (__builtin_clzll(val) >> 3);
+#else
+	int r;
+	if (!(val >> 32)) {
+		r = 4;
+	} else {
+		r = 0;
+		val >>= 32;
+	}
+	if (!(val >> 16)) {
+		r += 2;
+		val >>= 8;
+	} else {
+		val >>= 24;
+	}
+	r += (!val);
+	return (r);
+#endif
+#else
+#if defined(__GNUC__) && (GCC_VERSION >= 304) && \
+	!defined(LZ4_FORCE_SW_BITCOUNT)
+	return (__builtin_ctzll(val) >> 3);
+#else
+	static const int DeBruijnBytePos[64] =
+	    { 0, 0, 0, 0, 0, 1, 1, 2, 0, 3, 1, 3, 1, 4, 2, 7, 0, 2, 3, 6, 1, 5,
+		3, 5, 1, 3, 4, 4, 2, 5, 6, 7, 7, 0, 1, 2, 3, 3, 4, 6, 2, 6, 5,
+		5, 3, 4, 5, 6, 7, 1, 2, 4, 6, 4,
+		4, 5, 7, 2, 6, 5, 7, 6, 7, 7
+	};
+	return DeBruijnBytePos[((U64) ((val & -val) * 0x0218A392CDABBD3F)) >>
+	    58];
+#endif
+#endif
+}
+
+#else
+
+static inline int
+LZ4_NbCommonBytes(register U32 val)
+{
+#if defined(LZ4_BIG_ENDIAN)
+#if defined(__GNUC__) && (GCC_VERSION >= 304) && \
+	!defined(LZ4_FORCE_SW_BITCOUNT)
+	return (__builtin_clz(val) >> 3);
+#else
+	int r;
+	if (!(val >> 16)) {
+		r = 2;
+		val >>= 8;
+	} else {
+		r = 0;
+		val >>= 24;
+	}
+	r += (!val);
+	return (r);
+#endif
+#else
+#if defined(__GNUC__) && (GCC_VERSION >= 304) && \
+	!defined(LZ4_FORCE_SW_BITCOUNT)
+	return (__builtin_ctz(val) >> 3);
+#else
+	static const int DeBruijnBytePos[32] = {
+		0, 0, 3, 0, 3, 1, 3, 0,
+		3, 2, 2, 1, 3, 2, 0, 1,
+		3, 3, 1, 2, 2, 2, 2, 0,
+		3, 1, 2, 0, 1, 0, 1, 1
+	};
+	return DeBruijnBytePos[((U32) ((val & -(S32) val) * 0x077CB531U)) >>
+	    27];
+#endif
+#endif
+}
+
+#endif
+
+/* Compression functions */
+
+/*ARGSUSED*/
+static int
+LZ4_compressCtx(void *ctx, const char *source, char *dest, int isize,
+    int osize)
+{
+	struct refTables *srt = (struct refTables *)ctx;
+	HTYPE *HashTable = (HTYPE *) (srt->hashTable);
+
+	const BYTE *ip = (BYTE *) source;
+	INITBASE(base);
+	const BYTE *anchor = ip;
+	const BYTE *const iend = ip + isize;
+	const BYTE *const oend = (BYTE *) dest + osize;
+	const BYTE *const mflimit = iend - MFLIMIT;
+#define	matchlimit (iend - LASTLITERALS)
+
+	BYTE *op = (BYTE *) dest;
+
+	int len, length;
+	const int skipStrength = SKIPSTRENGTH;
+	U32 forwardH;
+
+
+	/* Init */
+	if (isize < MINLENGTH)
+		goto _last_literals;
+
+	/* First Byte */
+	HashTable[LZ4_HASH_VALUE(ip)] = ip - base;
+	ip++;
+	forwardH = LZ4_HASH_VALUE(ip);
+
+	/* Main Loop */
+	for (;;) {
+		int findMatchAttempts = (1U << skipStrength) + 3;
+		const BYTE *forwardIp = ip;
+		const BYTE *ref;
+		BYTE *token;
+
+		/* Find a match */
+		do {
+			U32 h = forwardH;
+			int step = findMatchAttempts++ >> skipStrength;
+			ip = forwardIp;
+			forwardIp = ip + step;
+
+			if (unlikely(forwardIp > mflimit)) {
+				goto _last_literals;
+			}
+
+			forwardH = LZ4_HASH_VALUE(forwardIp);
+			ref = base + HashTable[h];
+			HashTable[h] = ip - base;
+
+		} while ((ref < ip - MAX_DISTANCE) || (A32(ref) != A32(ip)));
+
+		/* Catch up */
+		while ((ip > anchor) && (ref > (BYTE *) source) &&
+		    unlikely(ip[-1] == ref[-1])) {
+			ip--;
+			ref--;
+		}
+
+		/* Encode Literal length */
+		length = ip - anchor;
+		token = op++;
+
+		/* Check output limit */
+		if (unlikely(op + length + (2 + 1 + LASTLITERALS) +
+		    (length >> 8) > oend))
+			return (0);
+
+		if (length >= (int)RUN_MASK) {
+			*token = (RUN_MASK << ML_BITS);
+			len = length - RUN_MASK;
+			for (; len > 254; len -= 255)
+				*op++ = 255;
+			*op++ = (BYTE)len;
+		} else
+			*token = (length << ML_BITS);
+
+		/* Copy Literals */
+		LZ4_BLINDCOPY(anchor, op, length);
+
+		_next_match:
+		/* Encode Offset */
+		LZ4_WRITE_LITTLEENDIAN_16(op, ip - ref);
+
+		/* Start Counting */
+		ip += MINMATCH;
+		ref += MINMATCH;	/* MinMatch verified */
+		anchor = ip;
+		while (likely(ip < matchlimit - (STEPSIZE - 1))) {
+			UARCH diff = AARCH(ref) ^ AARCH(ip);
+			if (!diff) {
+				ip += STEPSIZE;
+				ref += STEPSIZE;
+				continue;
+			}
+			ip += LZ4_NbCommonBytes(diff);
+			goto _endCount;
+		}
+#if LZ4_ARCH64
+		if ((ip < (matchlimit - 3)) && (A32(ref) == A32(ip))) {
+			ip += 4;
+			ref += 4;
+		}
+#endif
+		if ((ip < (matchlimit - 1)) && (A16(ref) == A16(ip))) {
+			ip += 2;
+			ref += 2;
+		}
+		if ((ip < matchlimit) && (*ref == *ip))
+			ip++;
+		_endCount:
+
+		/* Encode MatchLength */
+		len = (ip - anchor);
+		/* Check output limit */
+		if (unlikely(op + (1 + LASTLITERALS) + (len >> 8) > oend))
+			return (0);
+		if (len >= (int)ML_MASK) {
+			*token += ML_MASK;
+			len -= ML_MASK;
+			for (; len > 509; len -= 510) {
+				*op++ = 255;
+				*op++ = 255;
+			}
+			if (len > 254) {
+				len -= 255;
+				*op++ = 255;
+			}
+			*op++ = (BYTE)len;
+		} else
+			*token += len;
+
+		/* Test end of chunk */
+		if (ip > mflimit) {
+			anchor = ip;
+			break;
+		}
+		/* Fill table */
+		HashTable[LZ4_HASH_VALUE(ip - 2)] = ip - 2 - base;
+
+		/* Test next position */
+		ref = base + HashTable[LZ4_HASH_VALUE(ip)];
+		HashTable[LZ4_HASH_VALUE(ip)] = ip - base;
+		if ((ref > ip - (MAX_DISTANCE + 1)) && (A32(ref) == A32(ip))) {
+			token = op++;
+			*token = 0;
+			goto _next_match;
+		}
+		/* Prepare next loop */
+		anchor = ip++;
+		forwardH = LZ4_HASH_VALUE(ip);
+	}
+
+	_last_literals:
+	/* Encode Last Literals */
+	{
+		int lastRun = iend - anchor;
+		if (op + lastRun + 1 + ((lastRun + 255 - RUN_MASK) / 255) >
+		    oend)
+			return (0);
+		if (lastRun >= (int)RUN_MASK) {
+			*op++ = (RUN_MASK << ML_BITS);
+			lastRun -= RUN_MASK;
+			for (; lastRun > 254; lastRun -= 255) {
+				*op++ = 255;
+			}
+			*op++ = (BYTE)lastRun;
+		} else
+			*op++ = (lastRun << ML_BITS);
+		(void) memcpy(op, anchor, iend - anchor);
+		op += iend - anchor;
+	}
+
+	/* End */
+	return (int)(((char *)op) - dest);
+}
+
+
+
+/* Note : this function is valid only if isize < LZ4_64KLIMIT */
+#define	LZ4_64KLIMIT ((1 << 16) + (MFLIMIT - 1))
+#define	HASHLOG64K (HASH_LOG + 1)
+#define	HASH64KTABLESIZE (1U << HASHLOG64K)
+#define	LZ4_HASH64K_FUNCTION(i)	(((i) * 2654435761U) >> ((MINMATCH*8) - \
+	HASHLOG64K))
+#define	LZ4_HASH64K_VALUE(p)	LZ4_HASH64K_FUNCTION(A32(p))
+
+/*ARGSUSED*/
+static int
+LZ4_compress64kCtx(void *ctx, const char *source, char *dest, int isize,
+    int osize)
+{
+	struct refTables *srt = (struct refTables *)ctx;
+	U16 *HashTable = (U16 *) (srt->hashTable);
+
+	const BYTE *ip = (BYTE *) source;
+	const BYTE *anchor = ip;
+	const BYTE *const base = ip;
+	const BYTE *const iend = ip + isize;
+	const BYTE *const oend = (BYTE *) dest + osize;
+	const BYTE *const mflimit = iend - MFLIMIT;
+#define	matchlimit (iend - LASTLITERALS)
+
+	BYTE *op = (BYTE *) dest;
+
+	int len, length;
+	const int skipStrength = SKIPSTRENGTH;
+	U32 forwardH;
+
+	/* Init */
+	if (isize < MINLENGTH)
+		goto _last_literals;
+
+	/* First Byte */
+	ip++;
+	forwardH = LZ4_HASH64K_VALUE(ip);
+
+	/* Main Loop */
+	for (;;) {
+		int findMatchAttempts = (1U << skipStrength) + 3;
+		const BYTE *forwardIp = ip;
+		const BYTE *ref;
+		BYTE *token;
+
+		/* Find a match */
+		do {
+			U32 h = forwardH;
+			int step = findMatchAttempts++ >> skipStrength;
+			ip = forwardIp;
+			forwardIp = ip + step;
+
+			if (forwardIp > mflimit) {
+				goto _last_literals;
+			}
+
+			forwardH = LZ4_HASH64K_VALUE(forwardIp);
+			ref = base + HashTable[h];
+			HashTable[h] = ip - base;
+
+		} while (A32(ref) != A32(ip));
+
+		/* Catch up */
+		while ((ip > anchor) && (ref > (BYTE *) source) &&
+		    (ip[-1] == ref[-1])) {
+			ip--;
+			ref--;
+		}
+
+		/* Encode Literal length */
+		length = ip - anchor;
+		token = op++;
+
+		/* Check output limit */
+		if (unlikely(op + length + (2 + 1 + LASTLITERALS) +
+		    (length >> 8) > oend))
+			return (0);
+
+		if (length >= (int)RUN_MASK) {
+			*token = (RUN_MASK << ML_BITS);
+			len = length - RUN_MASK;
+			for (; len > 254; len -= 255)
+				*op++ = 255;
+			*op++ = (BYTE)len;
+		} else
+			*token = (length << ML_BITS);
+
+		/* Copy Literals */
+		LZ4_BLINDCOPY(anchor, op, length);
+
+		_next_match:
+		/* Encode Offset */
+		LZ4_WRITE_LITTLEENDIAN_16(op, ip - ref);
+
+		/* Start Counting */
+		ip += MINMATCH;
+		ref += MINMATCH;	/* MinMatch verified */
+		anchor = ip;
+		while (ip < matchlimit - (STEPSIZE - 1)) {
+			UARCH diff = AARCH(ref) ^ AARCH(ip);
+			if (!diff) {
+				ip += STEPSIZE;
+				ref += STEPSIZE;
+				continue;
+			}
+			ip += LZ4_NbCommonBytes(diff);
+			goto _endCount;
+		}
+#if LZ4_ARCH64
+		if ((ip < (matchlimit - 3)) && (A32(ref) == A32(ip))) {
+			ip += 4;
+			ref += 4;
+		}
+#endif
+		if ((ip < (matchlimit - 1)) && (A16(ref) == A16(ip))) {
+			ip += 2;
+			ref += 2;
+		}
+		if ((ip < matchlimit) && (*ref == *ip))
+			ip++;
+		_endCount:
+
+		/* Encode MatchLength */
+		len = (ip - anchor);
+		/* Check output limit */
+		if (unlikely(op + (1 + LASTLITERALS) + (len >> 8) > oend))
+			return (0);
+		if (len >= (int)ML_MASK) {
+			*token += ML_MASK;
+			len -= ML_MASK;
+			for (; len > 509; len -= 510) {
+				*op++ = 255;
+				*op++ = 255;
+			}
+			if (len > 254) {
+				len -= 255;
+				*op++ = 255;
+			}
+			*op++ = (BYTE)len;
+		} else
+			*token += len;
+
+		/* Test end of chunk */
+		if (ip > mflimit) {
+			anchor = ip;
+			break;
+		}
+		/* Fill table */
+		HashTable[LZ4_HASH64K_VALUE(ip - 2)] = ip - 2 - base;
+
+		/* Test next position */
+		ref = base + HashTable[LZ4_HASH64K_VALUE(ip)];
+		HashTable[LZ4_HASH64K_VALUE(ip)] = ip - base;
+		if (A32(ref) == A32(ip)) {
+			token = op++;
+			*token = 0;
+			goto _next_match;
+		}
+		/* Prepare next loop */
+		anchor = ip++;
+		forwardH = LZ4_HASH64K_VALUE(ip);
+	}
+
+	_last_literals:
+	/* Encode Last Literals */
+	{
+		int lastRun = iend - anchor;
+		if (op + lastRun + 1 + ((lastRun + 255 - RUN_MASK) / 255) >
+		    oend)
+			return (0);
+		if (lastRun >= (int)RUN_MASK) {
+			*op++ = (RUN_MASK << ML_BITS);
+			lastRun -= RUN_MASK;
+			for (; lastRun > 254; lastRun -= 255)
+				*op++ = 255;
+			*op++ = (BYTE)lastRun;
+		} else
+			*op++ = (lastRun << ML_BITS);
+		(void) memcpy(op, anchor, iend - anchor);
+		op += iend - anchor;
+	}
+
+	/* End */
+	return (int)(((char *)op) - dest);
+}
+
+static int
+real_LZ4_compress(const char *source, char *dest, int isize, int osize)
+{
+	void *ctx;
+	int result;
+
+	ASSERT(lz4_cache != NULL);
+	ctx = kmem_cache_alloc(lz4_cache, KM_SLEEP);
+
+	/*
+	 * out of kernel memory, gently fall through - this will disable
+	 * compression in zio_compress_data
+	 */
+	if (ctx == NULL)
+		return (0);
+
+	memset(ctx, 0, sizeof (struct refTables));
+
+	if (isize < LZ4_64KLIMIT)
+		result = LZ4_compress64kCtx(ctx, source, dest, isize, osize);
+	else
+		result = LZ4_compressCtx(ctx, source, dest, isize, osize);
+
+	kmem_cache_free(lz4_cache, ctx);
+	return (result);
+}
+
+/* Decompression functions */
+
+/*
+ * Note: The decoding functions real_LZ4_uncompress() and
+ *	LZ4_uncompress_unknownOutputSize() are safe against "buffer overflow"
+ *	attack type. They will never write nor read outside of the provided
+ *	output buffers. LZ4_uncompress_unknownOutputSize() also insures that
+ *	it will never read outside of the input buffer. A corrupted input
+ *	will produce an error result, a negative int, indicating the position
+ *	of the error within input stream.
+ *
+ * Note[2]: real_LZ4_uncompress(), referred to above, is not used in ZFS so
+ *	its code is not present here.
+ */
+
+static int
+LZ4_uncompress_unknownOutputSize(const char *source, char *dest, int isize,
+    int maxOutputSize)
+{
+	/* Local Variables */
+	const BYTE *restrict ip = (const BYTE *) source;
+	const BYTE *const iend = ip + isize;
+	const BYTE *ref;
+
+	BYTE *op = (BYTE *) dest;
+	BYTE *const oend = op + maxOutputSize;
+	BYTE *cpy;
+
+	size_t dec32table[] = {0, 3, 2, 3, 0, 0, 0, 0};
+#if LZ4_ARCH64
+	size_t dec64table[] = {0, 0, 0, (size_t)-1, 0, 1, 2, 3};
+#endif
+
+	/* Main Loop */
+	while (ip < iend) {
+		unsigned token;
+		size_t length;
+
+		/* get runlength */
+		token = *ip++;
+		if ((length = (token >> ML_BITS)) == RUN_MASK) {
+			int s = 255;
+			while ((ip < iend) && (s == 255)) {
+				s = *ip++;
+				length += s;
+			}
+		}
+		/* copy literals */
+		cpy = op + length;
+		/* CORNER-CASE: cpy might overflow. */
+		if (cpy < op)
+			goto _output_error;	/* cpy was overflowed, bail! */
+		if ((cpy > oend - COPYLENGTH) ||
+		    (ip + length > iend - COPYLENGTH)) {
+			if (cpy > oend)
+				/* Error: writes beyond output buffer */
+				goto _output_error;
+			if (ip + length != iend)
+				/*
+				 * Error: LZ4 format requires to consume all
+				 * input at this stage
+				 */
+				goto _output_error;
+			(void) memcpy(op, ip, length);
+			op += length;
+			/* Necessarily EOF, due to parsing restrictions */
+			break;
+		}
+		LZ4_WILDCOPY(ip, op, cpy);
+		ip -= (op - cpy);
+		op = cpy;
+
+		/* get offset */
+		LZ4_READ_LITTLEENDIAN_16(ref, cpy, ip);
+		ip += 2;
+		if (ref < (BYTE * const) dest)
+			/*
+			 * Error: offset creates reference outside of
+			 * destination buffer
+			 */
+			goto _output_error;
+
+		/* get matchlength */
+		if ((length = (token & ML_MASK)) == ML_MASK) {
+			while (ip < iend) {
+				int s = *ip++;
+				length += s;
+				if (s == 255)
+					continue;
+				break;
+			}
+		}
+		/* copy repeated sequence */
+		if (unlikely(op - ref < STEPSIZE)) {
+#if LZ4_ARCH64
+			size_t dec64 = dec64table[op-ref];
+#else
+			const int dec64 = 0;
+#endif
+			op[0] = ref[0];
+			op[1] = ref[1];
+			op[2] = ref[2];
+			op[3] = ref[3];
+			op += 4;
+			ref += 4;
+			ref -= dec32table[op-ref];
+			A32(op) = A32(ref);
+			op += STEPSIZE - 4;
+			ref -= dec64;
+		} else {
+			LZ4_COPYSTEP(ref, op);
+		}
+		cpy = op + length - (STEPSIZE - 4);
+		if (cpy > oend - COPYLENGTH) {
+			if (cpy > oend)
+				/*
+				 * Error: request to write outside of
+				 * destination buffer
+				 */
+				goto _output_error;
+			LZ4_SECURECOPY(ref, op, (oend - COPYLENGTH));
+			while (op < cpy)
+				*op++ = *ref++;
+			op = cpy;
+			if (op == oend)
+				/*
+				 * Check EOF (should never happen, since
+				 * last 5 bytes are supposed to be literals)
+				 */
+				goto _output_error;
+			continue;
+		}
+		LZ4_SECURECOPY(ref, op, cpy);
+		op = cpy;	/* correction */
+	}
+
+	/* end of decoding */
+	return (int)(((char *)op) - dest);
+
+	/* write overflow error detected */
+	_output_error:
+	return (int)(-(((char *)ip) - source));
+}
+
+void
+lz4_init(void)
+{
+	lz4_cache = kmem_cache_create("lz4_cache",
+		sizeof (struct refTables), 0, NULL, NULL, NULL, NULL, NULL, 0);
+}
+
+void
+lz4_fini(void)
+{
+	if (lz4_cache) {
+		kmem_cache_destroy(lz4_cache);
+		lz4_cache = NULL;
+	}
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/module/zfs/lzjb.c
@@ -0,0 +1,131 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ */
+
+/*
+ * We keep our own copy of this algorithm for 3 main reasons:
+ *	1. If we didn't, anyone modifying common/os/compress.c would
+ *         directly break our on disk format
+ *	2. Our version of lzjb does not have a number of checks that the
+ *         common/os version needs and uses
+ *	3. We initialize the lempel to ensure deterministic results,
+ *	   so that identical blocks can always be deduplicated.
+ * In particular, we are adding the "feature" that compress() can
+ * take a destination buffer size and returns the compressed length, or the
+ * source length if compression would overflow the destination buffer.
+ */
+
+#include <sys/zfs_context.h>
+
+#define	MATCH_BITS	6
+#define	MATCH_MIN	3
+#define	MATCH_MAX	((1 << MATCH_BITS) + (MATCH_MIN - 1))
+#define	OFFSET_MASK	((1 << (16 - MATCH_BITS)) - 1)
+#define	LEMPEL_SIZE	1024
+
+/*ARGSUSED*/
+size_t
+lzjb_compress(void *s_start, void *d_start, size_t s_len, size_t d_len, int n)
+{
+	uchar_t *src = s_start;
+	uchar_t *dst = d_start;
+	uchar_t *cpy;
+	uchar_t *copymap = NULL;
+	int copymask = 1 << (NBBY - 1);
+	int mlen, offset, hash;
+	uint16_t *hp;
+	uint16_t *lempel;
+
+	lempel = kmem_zalloc(LEMPEL_SIZE * sizeof (uint16_t), KM_SLEEP);
+	while (src < (uchar_t *)s_start + s_len) {
+		if ((copymask <<= 1) == (1 << NBBY)) {
+			if (dst >= (uchar_t *)d_start + d_len - 1 - 2 * NBBY) {
+				kmem_free(lempel,
+				    LEMPEL_SIZE*sizeof (uint16_t));
+				return (s_len);
+			}
+			copymask = 1;
+			copymap = dst;
+			*dst++ = 0;
+		}
+		if (src > (uchar_t *)s_start + s_len - MATCH_MAX) {
+			*dst++ = *src++;
+			continue;
+		}
+		hash = (src[0] << 16) + (src[1] << 8) + src[2];
+		hash += hash >> 9;
+		hash += hash >> 5;
+		hp = &lempel[hash & (LEMPEL_SIZE - 1)];
+		offset = (intptr_t)(src - *hp) & OFFSET_MASK;
+		*hp = (uint16_t)(uintptr_t)src;
+		cpy = src - offset;
+		if (cpy >= (uchar_t *)s_start && cpy != src &&
+		    src[0] == cpy[0] && src[1] == cpy[1] && src[2] == cpy[2]) {
+			*copymap |= copymask;
+			for (mlen = MATCH_MIN; mlen < MATCH_MAX; mlen++)
+				if (src[mlen] != cpy[mlen])
+					break;
+			*dst++ = ((mlen - MATCH_MIN) << (NBBY - MATCH_BITS)) |
+			    (offset >> NBBY);
+			*dst++ = (uchar_t)offset;
+			src += mlen;
+		} else {
+			*dst++ = *src++;
+		}
+	}
+
+	kmem_free(lempel, LEMPEL_SIZE * sizeof (uint16_t));
+	return (dst - (uchar_t *)d_start);
+}
+
+/*ARGSUSED*/
+int
+lzjb_decompress(void *s_start, void *d_start, size_t s_len, size_t d_len, int n)
+{
+	uchar_t *src = s_start;
+	uchar_t *dst = d_start;
+	uchar_t *d_end = (uchar_t *)d_start + d_len;
+	uchar_t *cpy;
+	uchar_t copymap = 0;
+	int copymask = 1 << (NBBY - 1);
+
+	while (dst < d_end) {
+		if ((copymask <<= 1) == (1 << NBBY)) {
+			copymask = 1;
+			copymap = *src++;
+		}
+		if (copymap & copymask) {
+			int mlen = (src[0] >> (NBBY - MATCH_BITS)) + MATCH_MIN;
+			int offset = ((src[0] << NBBY) | src[1]) & OFFSET_MASK;
+			src += 2;
+			if ((cpy = dst - offset) < (uchar_t *)d_start)
+				return (-1);
+			while (--mlen >= 0 && dst < d_end)
+				*dst++ = *cpy++;
+		} else {
+			*dst++ = *src++;
+		}
+	}
+	return (0);
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/module/zfs/metaslab.c
@@ -0,0 +1,2745 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2014 by Delphix. All rights reserved.
+ * Copyright (c) 2013 by Saso Kiselkov. All rights reserved.
+ */
+
+#include <sys/zfs_context.h>
+#include <sys/dmu.h>
+#include <sys/dmu_tx.h>
+#include <sys/space_map.h>
+#include <sys/metaslab_impl.h>
+#include <sys/vdev_impl.h>
+#include <sys/zio.h>
+#include <sys/spa_impl.h>
+#include <sys/zfeature.h>
+
+#define	WITH_DF_BLOCK_ALLOCATOR
+
+/*
+ * Allow allocations to switch to gang blocks quickly. We do this to
+ * avoid having to load lots of space_maps in a given txg. There are,
+ * however, some cases where we want to avoid "fast" ganging and instead
+ * we want to do an exhaustive search of all metaslabs on this device.
+ * Currently we don't allow any gang, slog, or dump device related allocations
+ * to "fast" gang.
+ */
+#define	CAN_FASTGANG(flags) \
+	(!((flags) & (METASLAB_GANG_CHILD | METASLAB_GANG_HEADER | \
+	METASLAB_GANG_AVOID)))
+
+#define	METASLAB_WEIGHT_PRIMARY		(1ULL << 63)
+#define	METASLAB_WEIGHT_SECONDARY	(1ULL << 62)
+#define	METASLAB_ACTIVE_MASK		\
+	(METASLAB_WEIGHT_PRIMARY | METASLAB_WEIGHT_SECONDARY)
+
+/*
+ * Metaslab granularity, in bytes. This is roughly similar to what would be
+ * referred to as the "stripe size" in traditional RAID arrays. In normal
+ * operation, we will try to write this amount of data to a top-level vdev
+ * before moving on to the next one.
+ */
+unsigned long metaslab_aliquot = 512 << 10;
+
+uint64_t metaslab_gang_bang = SPA_MAXBLOCKSIZE + 1;	/* force gang blocks */
+
+/*
+ * The in-core space map representation is more compact than its on-disk form.
+ * The zfs_condense_pct determines how much more compact the in-core
+ * space_map representation must be before we compact it on-disk.
+ * Values should be greater than or equal to 100.
+ */
+int zfs_condense_pct = 200;
+
+/*
+ * Condensing a metaslab is not guaranteed to actually reduce the amount of
+ * space used on disk. In particular, a space map uses data in increments of
+ * MAX(1 << ashift, space_map_blksz), so a metaslab might use the
+ * same number of blocks after condensing. Since the goal of condensing is to
+ * reduce the number of IOPs required to read the space map, we only want to
+ * condense when we can be sure we will reduce the number of blocks used by the
+ * space map. Unfortunately, we cannot precisely compute whether or not this is
+ * the case in metaslab_should_condense since we are holding ms_lock. Instead,
+ * we apply the following heuristic: do not condense a spacemap unless the
+ * uncondensed size consumes greater than zfs_metaslab_condense_block_threshold
+ * blocks.
+ */
+int zfs_metaslab_condense_block_threshold = 4;
+
+/*
+ * The zfs_mg_noalloc_threshold defines which metaslab groups should
+ * be eligible for allocation. The value is defined as a percentage of
+ * free space. Metaslab groups that have more free space than
+ * zfs_mg_noalloc_threshold are always eligible for allocations. Once
+ * a metaslab group's free space is less than or equal to the
+ * zfs_mg_noalloc_threshold the allocator will avoid allocating to that
+ * group unless all groups in the pool have reached zfs_mg_noalloc_threshold.
+ * Once all groups in the pool reach zfs_mg_noalloc_threshold then all
+ * groups are allowed to accept allocations. Gang blocks are always
+ * eligible to allocate on any metaslab group. The default value of 0 means
+ * no metaslab group will be excluded based on this criterion.
+ */
+int zfs_mg_noalloc_threshold = 0;
+
+/*
+ * Metaslab groups are considered eligible for allocations if their
+ * fragmenation metric (measured as a percentage) is less than or equal to
+ * zfs_mg_fragmentation_threshold. If a metaslab group exceeds this threshold
+ * then it will be skipped unless all metaslab groups within the metaslab
+ * class have also crossed this threshold.
+ */
+int zfs_mg_fragmentation_threshold = 85;
+
+/*
+ * Allow metaslabs to keep their active state as long as their fragmentation
+ * percentage is less than or equal to zfs_metaslab_fragmentation_threshold. An
+ * active metaslab that exceeds this threshold will no longer keep its active
+ * status allowing better metaslabs to be selected.
+ */
+int zfs_metaslab_fragmentation_threshold = 70;
+
+/*
+ * When set will load all metaslabs when pool is first opened.
+ */
+int metaslab_debug_load = 0;
+
+/*
+ * When set will prevent metaslabs from being unloaded.
+ */
+int metaslab_debug_unload = 0;
+
+/*
+ * Minimum size which forces the dynamic allocator to change
+ * it's allocation strategy.  Once the space map cannot satisfy
+ * an allocation of this size then it switches to using more
+ * aggressive strategy (i.e search by size rather than offset).
+ */
+uint64_t metaslab_df_alloc_threshold = SPA_MAXBLOCKSIZE;
+
+/*
+ * The minimum free space, in percent, which must be available
+ * in a space map to continue allocations in a first-fit fashion.
+ * Once the space_map's free space drops below this level we dynamically
+ * switch to using best-fit allocations.
+ */
+int metaslab_df_free_pct = 4;
+
+/*
+ * Percentage of all cpus that can be used by the metaslab taskq.
+ */
+int metaslab_load_pct = 50;
+
+/*
+ * Determines how many txgs a metaslab may remain loaded without having any
+ * allocations from it. As long as a metaslab continues to be used we will
+ * keep it loaded.
+ */
+int metaslab_unload_delay = TXG_SIZE * 2;
+
+/*
+ * Max number of metaslabs per group to preload.
+ */
+int metaslab_preload_limit = SPA_DVAS_PER_BP;
+
+/*
+ * Enable/disable preloading of metaslab.
+ */
+int metaslab_preload_enabled = B_TRUE;
+
+/*
+ * Enable/disable fragmentation weighting on metaslabs.
+ */
+int metaslab_fragmentation_factor_enabled = B_TRUE;
+
+/*
+ * Enable/disable lba weighting (i.e. outer tracks are given preference).
+ */
+int metaslab_lba_weighting_enabled = B_TRUE;
+
+/*
+ * Enable/disable metaslab group biasing.
+ */
+int metaslab_bias_enabled = B_TRUE;
+
+static uint64_t metaslab_fragmentation(metaslab_t *);
+
+/*
+ * ==========================================================================
+ * Metaslab classes
+ * ==========================================================================
+ */
+metaslab_class_t *
+metaslab_class_create(spa_t *spa, metaslab_ops_t *ops)
+{
+	metaslab_class_t *mc;
+
+	mc = kmem_zalloc(sizeof (metaslab_class_t), KM_SLEEP);
+
+	mc->mc_spa = spa;
+	mc->mc_rotor = NULL;
+	mc->mc_ops = ops;
+	mutex_init(&mc->mc_fastwrite_lock, NULL, MUTEX_DEFAULT, NULL);
+
+	return (mc);
+}
+
+void
+metaslab_class_destroy(metaslab_class_t *mc)
+{
+	ASSERT(mc->mc_rotor == NULL);
+	ASSERT(mc->mc_alloc == 0);
+	ASSERT(mc->mc_deferred == 0);
+	ASSERT(mc->mc_space == 0);
+	ASSERT(mc->mc_dspace == 0);
+
+	mutex_destroy(&mc->mc_fastwrite_lock);
+	kmem_free(mc, sizeof (metaslab_class_t));
+}
+
+int
+metaslab_class_validate(metaslab_class_t *mc)
+{
+	metaslab_group_t *mg;
+	vdev_t *vd;
+
+	/*
+	 * Must hold one of the spa_config locks.
+	 */
+	ASSERT(spa_config_held(mc->mc_spa, SCL_ALL, RW_READER) ||
+	    spa_config_held(mc->mc_spa, SCL_ALL, RW_WRITER));
+
+	if ((mg = mc->mc_rotor) == NULL)
+		return (0);
+
+	do {
+		vd = mg->mg_vd;
+		ASSERT(vd->vdev_mg != NULL);
+		ASSERT3P(vd->vdev_top, ==, vd);
+		ASSERT3P(mg->mg_class, ==, mc);
+		ASSERT3P(vd->vdev_ops, !=, &vdev_hole_ops);
+	} while ((mg = mg->mg_next) != mc->mc_rotor);
+
+	return (0);
+}
+
+void
+metaslab_class_space_update(metaslab_class_t *mc, int64_t alloc_delta,
+    int64_t defer_delta, int64_t space_delta, int64_t dspace_delta)
+{
+	atomic_add_64(&mc->mc_alloc, alloc_delta);
+	atomic_add_64(&mc->mc_deferred, defer_delta);
+	atomic_add_64(&mc->mc_space, space_delta);
+	atomic_add_64(&mc->mc_dspace, dspace_delta);
+}
+
+uint64_t
+metaslab_class_get_alloc(metaslab_class_t *mc)
+{
+	return (mc->mc_alloc);
+}
+
+uint64_t
+metaslab_class_get_deferred(metaslab_class_t *mc)
+{
+	return (mc->mc_deferred);
+}
+
+uint64_t
+metaslab_class_get_space(metaslab_class_t *mc)
+{
+	return (mc->mc_space);
+}
+
+uint64_t
+metaslab_class_get_dspace(metaslab_class_t *mc)
+{
+	return (spa_deflate(mc->mc_spa) ? mc->mc_dspace : mc->mc_space);
+}
+
+void
+metaslab_class_histogram_verify(metaslab_class_t *mc)
+{
+	vdev_t *rvd = mc->mc_spa->spa_root_vdev;
+	uint64_t *mc_hist;
+	int i, c;
+
+	if ((zfs_flags & ZFS_DEBUG_HISTOGRAM_VERIFY) == 0)
+		return;
+
+	mc_hist = kmem_zalloc(sizeof (uint64_t) * RANGE_TREE_HISTOGRAM_SIZE,
+	    KM_SLEEP);
+
+	for (c = 0; c < rvd->vdev_children; c++) {
+		vdev_t *tvd = rvd->vdev_child[c];
+		metaslab_group_t *mg = tvd->vdev_mg;
+
+		/*
+		 * Skip any holes, uninitialized top-levels, or
+		 * vdevs that are not in this metalab class.
+		 */
+		if (tvd->vdev_ishole || tvd->vdev_ms_shift == 0 ||
+		    mg->mg_class != mc) {
+			continue;
+		}
+
+		for (i = 0; i < RANGE_TREE_HISTOGRAM_SIZE; i++)
+			mc_hist[i] += mg->mg_histogram[i];
+	}
+
+	for (i = 0; i < RANGE_TREE_HISTOGRAM_SIZE; i++)
+		VERIFY3U(mc_hist[i], ==, mc->mc_histogram[i]);
+
+	kmem_free(mc_hist, sizeof (uint64_t) * RANGE_TREE_HISTOGRAM_SIZE);
+}
+
+/*
+ * Calculate the metaslab class's fragmentation metric. The metric
+ * is weighted based on the space contribution of each metaslab group.
+ * The return value will be a number between 0 and 100 (inclusive), or
+ * ZFS_FRAG_INVALID if the metric has not been set. See comment above the
+ * zfs_frag_table for more information about the metric.
+ */
+uint64_t
+metaslab_class_fragmentation(metaslab_class_t *mc)
+{
+	vdev_t *rvd = mc->mc_spa->spa_root_vdev;
+	uint64_t fragmentation = 0;
+	int c;
+
+	spa_config_enter(mc->mc_spa, SCL_VDEV, FTAG, RW_READER);
+
+	for (c = 0; c < rvd->vdev_children; c++) {
+		vdev_t *tvd = rvd->vdev_child[c];
+		metaslab_group_t *mg = tvd->vdev_mg;
+
+		/*
+		 * Skip any holes, uninitialized top-levels, or
+		 * vdevs that are not in this metalab class.
+		 */
+		if (tvd->vdev_ishole || tvd->vdev_ms_shift == 0 ||
+		    mg->mg_class != mc) {
+			continue;
+		}
+
+		/*
+		 * If a metaslab group does not contain a fragmentation
+		 * metric then just bail out.
+		 */
+		if (mg->mg_fragmentation == ZFS_FRAG_INVALID) {
+			spa_config_exit(mc->mc_spa, SCL_VDEV, FTAG);
+			return (ZFS_FRAG_INVALID);
+		}
+
+		/*
+		 * Determine how much this metaslab_group is contributing
+		 * to the overall pool fragmentation metric.
+		 */
+		fragmentation += mg->mg_fragmentation *
+		    metaslab_group_get_space(mg);
+	}
+	fragmentation /= metaslab_class_get_space(mc);
+
+	ASSERT3U(fragmentation, <=, 100);
+	spa_config_exit(mc->mc_spa, SCL_VDEV, FTAG);
+	return (fragmentation);
+}
+
+/*
+ * Calculate the amount of expandable space that is available in
+ * this metaslab class. If a device is expanded then its expandable
+ * space will be the amount of allocatable space that is currently not
+ * part of this metaslab class.
+ */
+uint64_t
+metaslab_class_expandable_space(metaslab_class_t *mc)
+{
+	vdev_t *rvd = mc->mc_spa->spa_root_vdev;
+	uint64_t space = 0;
+	int c;
+
+	spa_config_enter(mc->mc_spa, SCL_VDEV, FTAG, RW_READER);
+	for (c = 0; c < rvd->vdev_children; c++) {
+		vdev_t *tvd = rvd->vdev_child[c];
+		metaslab_group_t *mg = tvd->vdev_mg;
+
+		if (tvd->vdev_ishole || tvd->vdev_ms_shift == 0 ||
+		    mg->mg_class != mc) {
+			continue;
+		}
+
+		space += tvd->vdev_max_asize - tvd->vdev_asize;
+	}
+	spa_config_exit(mc->mc_spa, SCL_VDEV, FTAG);
+	return (space);
+}
+
+/*
+ * ==========================================================================
+ * Metaslab groups
+ * ==========================================================================
+ */
+static int
+metaslab_compare(const void *x1, const void *x2)
+{
+	const metaslab_t *m1 = x1;
+	const metaslab_t *m2 = x2;
+
+	if (m1->ms_weight < m2->ms_weight)
+		return (1);
+	if (m1->ms_weight > m2->ms_weight)
+		return (-1);
+
+	/*
+	 * If the weights are identical, use the offset to force uniqueness.
+	 */
+	if (m1->ms_start < m2->ms_start)
+		return (-1);
+	if (m1->ms_start > m2->ms_start)
+		return (1);
+
+	ASSERT3P(m1, ==, m2);
+
+	return (0);
+}
+
+/*
+ * Update the allocatable flag and the metaslab group's capacity.
+ * The allocatable flag is set to true if the capacity is below
+ * the zfs_mg_noalloc_threshold. If a metaslab group transitions
+ * from allocatable to non-allocatable or vice versa then the metaslab
+ * group's class is updated to reflect the transition.
+ */
+static void
+metaslab_group_alloc_update(metaslab_group_t *mg)
+{
+	vdev_t *vd = mg->mg_vd;
+	metaslab_class_t *mc = mg->mg_class;
+	vdev_stat_t *vs = &vd->vdev_stat;
+	boolean_t was_allocatable;
+
+	ASSERT(vd == vd->vdev_top);
+
+	mutex_enter(&mg->mg_lock);
+	was_allocatable = mg->mg_allocatable;
+
+	mg->mg_free_capacity = ((vs->vs_space - vs->vs_alloc) * 100) /
+	    (vs->vs_space + 1);
+
+	/*
+	 * A metaslab group is considered allocatable if it has plenty
+	 * of free space or is not heavily fragmented. We only take
+	 * fragmentation into account if the metaslab group has a valid
+	 * fragmentation metric (i.e. a value between 0 and 100).
+	 */
+	mg->mg_allocatable = (mg->mg_free_capacity > zfs_mg_noalloc_threshold &&
+	    (mg->mg_fragmentation == ZFS_FRAG_INVALID ||
+	    mg->mg_fragmentation <= zfs_mg_fragmentation_threshold));
+
+	/*
+	 * The mc_alloc_groups maintains a count of the number of
+	 * groups in this metaslab class that are still above the
+	 * zfs_mg_noalloc_threshold. This is used by the allocating
+	 * threads to determine if they should avoid allocations to
+	 * a given group. The allocator will avoid allocations to a group
+	 * if that group has reached or is below the zfs_mg_noalloc_threshold
+	 * and there are still other groups that are above the threshold.
+	 * When a group transitions from allocatable to non-allocatable or
+	 * vice versa we update the metaslab class to reflect that change.
+	 * When the mc_alloc_groups value drops to 0 that means that all
+	 * groups have reached the zfs_mg_noalloc_threshold making all groups
+	 * eligible for allocations. This effectively means that all devices
+	 * are balanced again.
+	 */
+	if (was_allocatable && !mg->mg_allocatable)
+		mc->mc_alloc_groups--;
+	else if (!was_allocatable && mg->mg_allocatable)
+		mc->mc_alloc_groups++;
+
+	mutex_exit(&mg->mg_lock);
+}
+
+metaslab_group_t *
+metaslab_group_create(metaslab_class_t *mc, vdev_t *vd)
+{
+	metaslab_group_t *mg;
+
+	mg = kmem_zalloc(sizeof (metaslab_group_t), KM_SLEEP);
+	mutex_init(&mg->mg_lock, NULL, MUTEX_DEFAULT, NULL);
+	avl_create(&mg->mg_metaslab_tree, metaslab_compare,
+	    sizeof (metaslab_t), offsetof(struct metaslab, ms_group_node));
+	mg->mg_vd = vd;
+	mg->mg_class = mc;
+	mg->mg_activation_count = 0;
+
+	mg->mg_taskq = taskq_create("metaslab_group_taskq", metaslab_load_pct,
+	    maxclsyspri, 10, INT_MAX, TASKQ_THREADS_CPU_PCT | TASKQ_DYNAMIC);
+
+	return (mg);
+}
+
+void
+metaslab_group_destroy(metaslab_group_t *mg)
+{
+	ASSERT(mg->mg_prev == NULL);
+	ASSERT(mg->mg_next == NULL);
+	/*
+	 * We may have gone below zero with the activation count
+	 * either because we never activated in the first place or
+	 * because we're done, and possibly removing the vdev.
+	 */
+	ASSERT(mg->mg_activation_count <= 0);
+
+	taskq_destroy(mg->mg_taskq);
+	avl_destroy(&mg->mg_metaslab_tree);
+	mutex_destroy(&mg->mg_lock);
+	kmem_free(mg, sizeof (metaslab_group_t));
+}
+
+void
+metaslab_group_activate(metaslab_group_t *mg)
+{
+	metaslab_class_t *mc = mg->mg_class;
+	metaslab_group_t *mgprev, *mgnext;
+
+	ASSERT(spa_config_held(mc->mc_spa, SCL_ALLOC, RW_WRITER));
+
+	ASSERT(mc->mc_rotor != mg);
+	ASSERT(mg->mg_prev == NULL);
+	ASSERT(mg->mg_next == NULL);
+	ASSERT(mg->mg_activation_count <= 0);
+
+	if (++mg->mg_activation_count <= 0)
+		return;
+
+	mg->mg_aliquot = metaslab_aliquot * MAX(1, mg->mg_vd->vdev_children);
+	metaslab_group_alloc_update(mg);
+
+	if ((mgprev = mc->mc_rotor) == NULL) {
+		mg->mg_prev = mg;
+		mg->mg_next = mg;
+	} else {
+		mgnext = mgprev->mg_next;
+		mg->mg_prev = mgprev;
+		mg->mg_next = mgnext;
+		mgprev->mg_next = mg;
+		mgnext->mg_prev = mg;
+	}
+	mc->mc_rotor = mg;
+}
+
+void
+metaslab_group_passivate(metaslab_group_t *mg)
+{
+	metaslab_class_t *mc = mg->mg_class;
+	metaslab_group_t *mgprev, *mgnext;
+
+	ASSERT(spa_config_held(mc->mc_spa, SCL_ALLOC, RW_WRITER));
+
+	if (--mg->mg_activation_count != 0) {
+		ASSERT(mc->mc_rotor != mg);
+		ASSERT(mg->mg_prev == NULL);
+		ASSERT(mg->mg_next == NULL);
+		ASSERT(mg->mg_activation_count < 0);
+		return;
+	}
+
+	taskq_wait_outstanding(mg->mg_taskq, 0);
+	metaslab_group_alloc_update(mg);
+
+	mgprev = mg->mg_prev;
+	mgnext = mg->mg_next;
+
+	if (mg == mgnext) {
+		mc->mc_rotor = NULL;
+	} else {
+		mc->mc_rotor = mgnext;
+		mgprev->mg_next = mgnext;
+		mgnext->mg_prev = mgprev;
+	}
+
+	mg->mg_prev = NULL;
+	mg->mg_next = NULL;
+}
+
+uint64_t
+metaslab_group_get_space(metaslab_group_t *mg)
+{
+	return ((1ULL << mg->mg_vd->vdev_ms_shift) * mg->mg_vd->vdev_ms_count);
+}
+
+void
+metaslab_group_histogram_verify(metaslab_group_t *mg)
+{
+	uint64_t *mg_hist;
+	vdev_t *vd = mg->mg_vd;
+	uint64_t ashift = vd->vdev_ashift;
+	int i, m;
+
+	if ((zfs_flags & ZFS_DEBUG_HISTOGRAM_VERIFY) == 0)
+		return;
+
+	mg_hist = kmem_zalloc(sizeof (uint64_t) * RANGE_TREE_HISTOGRAM_SIZE,
+	    KM_SLEEP);
+
+	ASSERT3U(RANGE_TREE_HISTOGRAM_SIZE, >=,
+	    SPACE_MAP_HISTOGRAM_SIZE + ashift);
+
+	for (m = 0; m < vd->vdev_ms_count; m++) {
+		metaslab_t *msp = vd->vdev_ms[m];
+
+		if (msp->ms_sm == NULL)
+			continue;
+
+		for (i = 0; i < SPACE_MAP_HISTOGRAM_SIZE; i++)
+			mg_hist[i + ashift] +=
+			    msp->ms_sm->sm_phys->smp_histogram[i];
+	}
+
+	for (i = 0; i < RANGE_TREE_HISTOGRAM_SIZE; i ++)
+		VERIFY3U(mg_hist[i], ==, mg->mg_histogram[i]);
+
+	kmem_free(mg_hist, sizeof (uint64_t) * RANGE_TREE_HISTOGRAM_SIZE);
+}
+
+static void
+metaslab_group_histogram_add(metaslab_group_t *mg, metaslab_t *msp)
+{
+	metaslab_class_t *mc = mg->mg_class;
+	uint64_t ashift = mg->mg_vd->vdev_ashift;
+	int i;
+
+	ASSERT(MUTEX_HELD(&msp->ms_lock));
+	if (msp->ms_sm == NULL)
+		return;
+
+	mutex_enter(&mg->mg_lock);
+	for (i = 0; i < SPACE_MAP_HISTOGRAM_SIZE; i++) {
+		mg->mg_histogram[i + ashift] +=
+		    msp->ms_sm->sm_phys->smp_histogram[i];
+		mc->mc_histogram[i + ashift] +=
+		    msp->ms_sm->sm_phys->smp_histogram[i];
+	}
+	mutex_exit(&mg->mg_lock);
+}
+
+void
+metaslab_group_histogram_remove(metaslab_group_t *mg, metaslab_t *msp)
+{
+	metaslab_class_t *mc = mg->mg_class;
+	uint64_t ashift = mg->mg_vd->vdev_ashift;
+	int i;
+
+	ASSERT(MUTEX_HELD(&msp->ms_lock));
+	if (msp->ms_sm == NULL)
+		return;
+
+	mutex_enter(&mg->mg_lock);
+	for (i = 0; i < SPACE_MAP_HISTOGRAM_SIZE; i++) {
+		ASSERT3U(mg->mg_histogram[i + ashift], >=,
+		    msp->ms_sm->sm_phys->smp_histogram[i]);
+		ASSERT3U(mc->mc_histogram[i + ashift], >=,
+		    msp->ms_sm->sm_phys->smp_histogram[i]);
+
+		mg->mg_histogram[i + ashift] -=
+		    msp->ms_sm->sm_phys->smp_histogram[i];
+		mc->mc_histogram[i + ashift] -=
+		    msp->ms_sm->sm_phys->smp_histogram[i];
+	}
+	mutex_exit(&mg->mg_lock);
+}
+
+static void
+metaslab_group_add(metaslab_group_t *mg, metaslab_t *msp)
+{
+	ASSERT(msp->ms_group == NULL);
+	mutex_enter(&mg->mg_lock);
+	msp->ms_group = mg;
+	msp->ms_weight = 0;
+	avl_add(&mg->mg_metaslab_tree, msp);
+	mutex_exit(&mg->mg_lock);
+
+	mutex_enter(&msp->ms_lock);
+	metaslab_group_histogram_add(mg, msp);
+	mutex_exit(&msp->ms_lock);
+}
+
+static void
+metaslab_group_remove(metaslab_group_t *mg, metaslab_t *msp)
+{
+	mutex_enter(&msp->ms_lock);
+	metaslab_group_histogram_remove(mg, msp);
+	mutex_exit(&msp->ms_lock);
+
+	mutex_enter(&mg->mg_lock);
+	ASSERT(msp->ms_group == mg);
+	avl_remove(&mg->mg_metaslab_tree, msp);
+	msp->ms_group = NULL;
+	mutex_exit(&mg->mg_lock);
+}
+
+static void
+metaslab_group_sort(metaslab_group_t *mg, metaslab_t *msp, uint64_t weight)
+{
+	/*
+	 * Although in principle the weight can be any value, in
+	 * practice we do not use values in the range [1, 511].
+	 */
+	ASSERT(weight >= SPA_MINBLOCKSIZE || weight == 0);
+	ASSERT(MUTEX_HELD(&msp->ms_lock));
+
+	mutex_enter(&mg->mg_lock);
+	ASSERT(msp->ms_group == mg);
+	avl_remove(&mg->mg_metaslab_tree, msp);
+	msp->ms_weight = weight;
+	avl_add(&mg->mg_metaslab_tree, msp);
+	mutex_exit(&mg->mg_lock);
+}
+
+/*
+ * Calculate the fragmentation for a given metaslab group. We can use
+ * a simple average here since all metaslabs within the group must have
+ * the same size. The return value will be a value between 0 and 100
+ * (inclusive), or ZFS_FRAG_INVALID if less than half of the metaslab in this
+ * group have a fragmentation metric.
+ */
+uint64_t
+metaslab_group_fragmentation(metaslab_group_t *mg)
+{
+	vdev_t *vd = mg->mg_vd;
+	uint64_t fragmentation = 0;
+	uint64_t valid_ms = 0;
+	int m;
+
+	for (m = 0; m < vd->vdev_ms_count; m++) {
+		metaslab_t *msp = vd->vdev_ms[m];
+
+		if (msp->ms_fragmentation == ZFS_FRAG_INVALID)
+			continue;
+
+		valid_ms++;
+		fragmentation += msp->ms_fragmentation;
+	}
+
+	if (valid_ms <= vd->vdev_ms_count / 2)
+		return (ZFS_FRAG_INVALID);
+
+	fragmentation /= valid_ms;
+	ASSERT3U(fragmentation, <=, 100);
+	return (fragmentation);
+}
+
+/*
+ * Determine if a given metaslab group should skip allocations. A metaslab
+ * group should avoid allocations if its free capacity is less than the
+ * zfs_mg_noalloc_threshold or its fragmentation metric is greater than
+ * zfs_mg_fragmentation_threshold and there is at least one metaslab group
+ * that can still handle allocations.
+ */
+static boolean_t
+metaslab_group_allocatable(metaslab_group_t *mg)
+{
+	vdev_t *vd = mg->mg_vd;
+	spa_t *spa = vd->vdev_spa;
+	metaslab_class_t *mc = mg->mg_class;
+
+	/*
+	 * We use two key metrics to determine if a metaslab group is
+	 * considered allocatable -- free space and fragmentation. If
+	 * the free space is greater than the free space threshold and
+	 * the fragmentation is less than the fragmentation threshold then
+	 * consider the group allocatable. There are two case when we will
+	 * not consider these key metrics. The first is if the group is
+	 * associated with a slog device and the second is if all groups
+	 * in this metaslab class have already been consider ineligible
+	 * for allocations.
+	 */
+	return ((mg->mg_free_capacity > zfs_mg_noalloc_threshold &&
+	    (mg->mg_fragmentation == ZFS_FRAG_INVALID ||
+	    mg->mg_fragmentation <= zfs_mg_fragmentation_threshold)) ||
+	    mc != spa_normal_class(spa) || mc->mc_alloc_groups == 0);
+}
+
+/*
+ * ==========================================================================
+ * Range tree callbacks
+ * ==========================================================================
+ */
+
+/*
+ * Comparison function for the private size-ordered tree. Tree is sorted
+ * by size, larger sizes at the end of the tree.
+ */
+static int
+metaslab_rangesize_compare(const void *x1, const void *x2)
+{
+	const range_seg_t *r1 = x1;
+	const range_seg_t *r2 = x2;
+	uint64_t rs_size1 = r1->rs_end - r1->rs_start;
+	uint64_t rs_size2 = r2->rs_end - r2->rs_start;
+
+	if (rs_size1 < rs_size2)
+		return (-1);
+	if (rs_size1 > rs_size2)
+		return (1);
+
+	if (r1->rs_start < r2->rs_start)
+		return (-1);
+
+	if (r1->rs_start > r2->rs_start)
+		return (1);
+
+	return (0);
+}
+
+/*
+ * Create any block allocator specific components. The current allocators
+ * rely on using both a size-ordered range_tree_t and an array of uint64_t's.
+ */
+static void
+metaslab_rt_create(range_tree_t *rt, void *arg)
+{
+	metaslab_t *msp = arg;
+
+	ASSERT3P(rt->rt_arg, ==, msp);
+	ASSERT(msp->ms_tree == NULL);
+
+	avl_create(&msp->ms_size_tree, metaslab_rangesize_compare,
+	    sizeof (range_seg_t), offsetof(range_seg_t, rs_pp_node));
+}
+
+/*
+ * Destroy the block allocator specific components.
+ */
+static void
+metaslab_rt_destroy(range_tree_t *rt, void *arg)
+{
+	metaslab_t *msp = arg;
+
+	ASSERT3P(rt->rt_arg, ==, msp);
+	ASSERT3P(msp->ms_tree, ==, rt);
+	ASSERT0(avl_numnodes(&msp->ms_size_tree));
+
+	avl_destroy(&msp->ms_size_tree);
+}
+
+static void
+metaslab_rt_add(range_tree_t *rt, range_seg_t *rs, void *arg)
+{
+	metaslab_t *msp = arg;
+
+	ASSERT3P(rt->rt_arg, ==, msp);
+	ASSERT3P(msp->ms_tree, ==, rt);
+	VERIFY(!msp->ms_condensing);
+	avl_add(&msp->ms_size_tree, rs);
+}
+
+static void
+metaslab_rt_remove(range_tree_t *rt, range_seg_t *rs, void *arg)
+{
+	metaslab_t *msp = arg;
+
+	ASSERT3P(rt->rt_arg, ==, msp);
+	ASSERT3P(msp->ms_tree, ==, rt);
+	VERIFY(!msp->ms_condensing);
+	avl_remove(&msp->ms_size_tree, rs);
+}
+
+static void
+metaslab_rt_vacate(range_tree_t *rt, void *arg)
+{
+	metaslab_t *msp = arg;
+
+	ASSERT3P(rt->rt_arg, ==, msp);
+	ASSERT3P(msp->ms_tree, ==, rt);
+
+	/*
+	 * Normally one would walk the tree freeing nodes along the way.
+	 * Since the nodes are shared with the range trees we can avoid
+	 * walking all nodes and just reinitialize the avl tree. The nodes
+	 * will be freed by the range tree, so we don't want to free them here.
+	 */
+	avl_create(&msp->ms_size_tree, metaslab_rangesize_compare,
+	    sizeof (range_seg_t), offsetof(range_seg_t, rs_pp_node));
+}
+
+static range_tree_ops_t metaslab_rt_ops = {
+	metaslab_rt_create,
+	metaslab_rt_destroy,
+	metaslab_rt_add,
+	metaslab_rt_remove,
+	metaslab_rt_vacate
+};
+
+/*
+ * ==========================================================================
+ * Metaslab block operations
+ * ==========================================================================
+ */
+
+/*
+ * Return the maximum contiguous segment within the metaslab.
+ */
+uint64_t
+metaslab_block_maxsize(metaslab_t *msp)
+{
+	avl_tree_t *t = &msp->ms_size_tree;
+	range_seg_t *rs;
+
+	if (t == NULL || (rs = avl_last(t)) == NULL)
+		return (0ULL);
+
+	return (rs->rs_end - rs->rs_start);
+}
+
+uint64_t
+metaslab_block_alloc(metaslab_t *msp, uint64_t size)
+{
+	uint64_t start;
+	range_tree_t *rt = msp->ms_tree;
+
+	VERIFY(!msp->ms_condensing);
+
+	start = msp->ms_ops->msop_alloc(msp, size);
+	if (start != -1ULL) {
+		vdev_t *vd = msp->ms_group->mg_vd;
+
+		VERIFY0(P2PHASE(start, 1ULL << vd->vdev_ashift));
+		VERIFY0(P2PHASE(size, 1ULL << vd->vdev_ashift));
+		VERIFY3U(range_tree_space(rt) - size, <=, msp->ms_size);
+		range_tree_remove(rt, start, size);
+	}
+	return (start);
+}
+
+/*
+ * ==========================================================================
+ * Common allocator routines
+ * ==========================================================================
+ */
+
+#if defined(WITH_FF_BLOCK_ALLOCATOR) || \
+    defined(WITH_DF_BLOCK_ALLOCATOR) || \
+    defined(WITH_CF_BLOCK_ALLOCATOR)
+/*
+ * This is a helper function that can be used by the allocator to find
+ * a suitable block to allocate. This will search the specified AVL
+ * tree looking for a block that matches the specified criteria.
+ */
+static uint64_t
+metaslab_block_picker(avl_tree_t *t, uint64_t *cursor, uint64_t size,
+    uint64_t align)
+{
+	range_seg_t *rs, rsearch;
+	avl_index_t where;
+
+	rsearch.rs_start = *cursor;
+	rsearch.rs_end = *cursor + size;
+
+	rs = avl_find(t, &rsearch, &where);
+	if (rs == NULL)
+		rs = avl_nearest(t, where, AVL_AFTER);
+
+	while (rs != NULL) {
+		uint64_t offset = P2ROUNDUP(rs->rs_start, align);
+
+		if (offset + size <= rs->rs_end) {
+			*cursor = offset + size;
+			return (offset);
+		}
+		rs = AVL_NEXT(t, rs);
+	}
+
+	/*
+	 * If we know we've searched the whole map (*cursor == 0), give up.
+	 * Otherwise, reset the cursor to the beginning and try again.
+	 */
+	if (*cursor == 0)
+		return (-1ULL);
+
+	*cursor = 0;
+	return (metaslab_block_picker(t, cursor, size, align));
+}
+#endif /* WITH_FF/DF/CF_BLOCK_ALLOCATOR */
+
+#if defined(WITH_FF_BLOCK_ALLOCATOR)
+/*
+ * ==========================================================================
+ * The first-fit block allocator
+ * ==========================================================================
+ */
+static uint64_t
+metaslab_ff_alloc(metaslab_t *msp, uint64_t size)
+{
+	/*
+	 * Find the largest power of 2 block size that evenly divides the
+	 * requested size. This is used to try to allocate blocks with similar
+	 * alignment from the same area of the metaslab (i.e. same cursor
+	 * bucket) but it does not guarantee that other allocations sizes
+	 * may exist in the same region.
+	 */
+	uint64_t align = size & -size;
+	uint64_t *cursor = &msp->ms_lbas[highbit64(align) - 1];
+	avl_tree_t *t = &msp->ms_tree->rt_root;
+
+	return (metaslab_block_picker(t, cursor, size, align));
+}
+
+static metaslab_ops_t metaslab_ff_ops = {
+	metaslab_ff_alloc
+};
+
+metaslab_ops_t *zfs_metaslab_ops = &metaslab_ff_ops;
+#endif /* WITH_FF_BLOCK_ALLOCATOR */
+
+#if defined(WITH_DF_BLOCK_ALLOCATOR)
+/*
+ * ==========================================================================
+ * Dynamic block allocator -
+ * Uses the first fit allocation scheme until space get low and then
+ * adjusts to a best fit allocation method. Uses metaslab_df_alloc_threshold
+ * and metaslab_df_free_pct to determine when to switch the allocation scheme.
+ * ==========================================================================
+ */
+static uint64_t
+metaslab_df_alloc(metaslab_t *msp, uint64_t size)
+{
+	/*
+	 * Find the largest power of 2 block size that evenly divides the
+	 * requested size. This is used to try to allocate blocks with similar
+	 * alignment from the same area of the metaslab (i.e. same cursor
+	 * bucket) but it does not guarantee that other allocations sizes
+	 * may exist in the same region.
+	 */
+	uint64_t align = size & -size;
+	uint64_t *cursor = &msp->ms_lbas[highbit64(align) - 1];
+	range_tree_t *rt = msp->ms_tree;
+	avl_tree_t *t = &rt->rt_root;
+	uint64_t max_size = metaslab_block_maxsize(msp);
+	int free_pct = range_tree_space(rt) * 100 / msp->ms_size;
+
+	ASSERT(MUTEX_HELD(&msp->ms_lock));
+	ASSERT3U(avl_numnodes(t), ==, avl_numnodes(&msp->ms_size_tree));
+
+	if (max_size < size)
+		return (-1ULL);
+
+	/*
+	 * If we're running low on space switch to using the size
+	 * sorted AVL tree (best-fit).
+	 */
+	if (max_size < metaslab_df_alloc_threshold ||
+	    free_pct < metaslab_df_free_pct) {
+		t = &msp->ms_size_tree;
+		*cursor = 0;
+	}
+
+	return (metaslab_block_picker(t, cursor, size, 1ULL));
+}
+
+static metaslab_ops_t metaslab_df_ops = {
+	metaslab_df_alloc
+};
+
+metaslab_ops_t *zfs_metaslab_ops = &metaslab_df_ops;
+#endif /* WITH_DF_BLOCK_ALLOCATOR */
+
+#if defined(WITH_CF_BLOCK_ALLOCATOR)
+/*
+ * ==========================================================================
+ * Cursor fit block allocator -
+ * Select the largest region in the metaslab, set the cursor to the beginning
+ * of the range and the cursor_end to the end of the range. As allocations
+ * are made advance the cursor. Continue allocating from the cursor until
+ * the range is exhausted and then find a new range.
+ * ==========================================================================
+ */
+static uint64_t
+metaslab_cf_alloc(metaslab_t *msp, uint64_t size)
+{
+	range_tree_t *rt = msp->ms_tree;
+	avl_tree_t *t = &msp->ms_size_tree;
+	uint64_t *cursor = &msp->ms_lbas[0];
+	uint64_t *cursor_end = &msp->ms_lbas[1];
+	uint64_t offset = 0;
+
+	ASSERT(MUTEX_HELD(&msp->ms_lock));
+	ASSERT3U(avl_numnodes(t), ==, avl_numnodes(&rt->rt_root));
+
+	ASSERT3U(*cursor_end, >=, *cursor);
+
+	if ((*cursor + size) > *cursor_end) {
+		range_seg_t *rs;
+
+		rs = avl_last(&msp->ms_size_tree);
+		if (rs == NULL || (rs->rs_end - rs->rs_start) < size)
+			return (-1ULL);
+
+		*cursor = rs->rs_start;
+		*cursor_end = rs->rs_end;
+	}
+
+	offset = *cursor;
+	*cursor += size;
+
+	return (offset);
+}
+
+static metaslab_ops_t metaslab_cf_ops = {
+	metaslab_cf_alloc
+};
+
+metaslab_ops_t *zfs_metaslab_ops = &metaslab_cf_ops;
+#endif /* WITH_CF_BLOCK_ALLOCATOR */
+
+#if defined(WITH_NDF_BLOCK_ALLOCATOR)
+/*
+ * ==========================================================================
+ * New dynamic fit allocator -
+ * Select a region that is large enough to allocate 2^metaslab_ndf_clump_shift
+ * contiguous blocks. If no region is found then just use the largest segment
+ * that remains.
+ * ==========================================================================
+ */
+
+/*
+ * Determines desired number of contiguous blocks (2^metaslab_ndf_clump_shift)
+ * to request from the allocator.
+ */
+uint64_t metaslab_ndf_clump_shift = 4;
+
+static uint64_t
+metaslab_ndf_alloc(metaslab_t *msp, uint64_t size)
+{
+	avl_tree_t *t = &msp->ms_tree->rt_root;
+	avl_index_t where;
+	range_seg_t *rs, rsearch;
+	uint64_t hbit = highbit64(size);
+	uint64_t *cursor = &msp->ms_lbas[hbit - 1];
+	uint64_t max_size = metaslab_block_maxsize(msp);
+
+	ASSERT(MUTEX_HELD(&msp->ms_lock));
+	ASSERT3U(avl_numnodes(t), ==, avl_numnodes(&msp->ms_size_tree));
+
+	if (max_size < size)
+		return (-1ULL);
+
+	rsearch.rs_start = *cursor;
+	rsearch.rs_end = *cursor + size;
+
+	rs = avl_find(t, &rsearch, &where);
+	if (rs == NULL || (rs->rs_end - rs->rs_start) < size) {
+		t = &msp->ms_size_tree;
+
+		rsearch.rs_start = 0;
+		rsearch.rs_end = MIN(max_size,
+		    1ULL << (hbit + metaslab_ndf_clump_shift));
+		rs = avl_find(t, &rsearch, &where);
+		if (rs == NULL)
+			rs = avl_nearest(t, where, AVL_AFTER);
+		ASSERT(rs != NULL);
+	}
+
+	if ((rs->rs_end - rs->rs_start) >= size) {
+		*cursor = rs->rs_start + size;
+		return (rs->rs_start);
+	}
+	return (-1ULL);
+}
+
+static metaslab_ops_t metaslab_ndf_ops = {
+	metaslab_ndf_alloc
+};
+
+metaslab_ops_t *zfs_metaslab_ops = &metaslab_ndf_ops;
+#endif /* WITH_NDF_BLOCK_ALLOCATOR */
+
+
+/*
+ * ==========================================================================
+ * Metaslabs
+ * ==========================================================================
+ */
+
+/*
+ * Wait for any in-progress metaslab loads to complete.
+ */
+void
+metaslab_load_wait(metaslab_t *msp)
+{
+	ASSERT(MUTEX_HELD(&msp->ms_lock));
+
+	while (msp->ms_loading) {
+		ASSERT(!msp->ms_loaded);
+		cv_wait(&msp->ms_load_cv, &msp->ms_lock);
+	}
+}
+
+int
+metaslab_load(metaslab_t *msp)
+{
+	int error = 0;
+	int t;
+
+	ASSERT(MUTEX_HELD(&msp->ms_lock));
+	ASSERT(!msp->ms_loaded);
+	ASSERT(!msp->ms_loading);
+
+	msp->ms_loading = B_TRUE;
+
+	/*
+	 * If the space map has not been allocated yet, then treat
+	 * all the space in the metaslab as free and add it to the
+	 * ms_tree.
+	 */
+	if (msp->ms_sm != NULL)
+		error = space_map_load(msp->ms_sm, msp->ms_tree, SM_FREE);
+	else
+		range_tree_add(msp->ms_tree, msp->ms_start, msp->ms_size);
+
+	msp->ms_loaded = (error == 0);
+	msp->ms_loading = B_FALSE;
+
+	if (msp->ms_loaded) {
+		for (t = 0; t < TXG_DEFER_SIZE; t++) {
+			range_tree_walk(msp->ms_defertree[t],
+			    range_tree_remove, msp->ms_tree);
+		}
+	}
+	cv_broadcast(&msp->ms_load_cv);
+	return (error);
+}
+
+void
+metaslab_unload(metaslab_t *msp)
+{
+	ASSERT(MUTEX_HELD(&msp->ms_lock));
+	range_tree_vacate(msp->ms_tree, NULL, NULL);
+	msp->ms_loaded = B_FALSE;
+	msp->ms_weight &= ~METASLAB_ACTIVE_MASK;
+}
+
+int
+metaslab_init(metaslab_group_t *mg, uint64_t id, uint64_t object, uint64_t txg,
+    metaslab_t **msp)
+{
+	vdev_t *vd = mg->mg_vd;
+	objset_t *mos = vd->vdev_spa->spa_meta_objset;
+	metaslab_t *ms;
+	int error;
+
+	ms = kmem_zalloc(sizeof (metaslab_t), KM_SLEEP);
+	mutex_init(&ms->ms_lock, NULL, MUTEX_DEFAULT, NULL);
+	cv_init(&ms->ms_load_cv, NULL, CV_DEFAULT, NULL);
+	ms->ms_id = id;
+	ms->ms_start = id << vd->vdev_ms_shift;
+	ms->ms_size = 1ULL << vd->vdev_ms_shift;
+
+	/*
+	 * We only open space map objects that already exist. All others
+	 * will be opened when we finally allocate an object for it.
+	 */
+	if (object != 0) {
+		error = space_map_open(&ms->ms_sm, mos, object, ms->ms_start,
+		    ms->ms_size, vd->vdev_ashift, &ms->ms_lock);
+
+		if (error != 0) {
+			kmem_free(ms, sizeof (metaslab_t));
+			return (error);
+		}
+
+		ASSERT(ms->ms_sm != NULL);
+	}
+
+	/*
+	 * We create the main range tree here, but we don't create the
+	 * alloctree and freetree until metaslab_sync_done().  This serves
+	 * two purposes: it allows metaslab_sync_done() to detect the
+	 * addition of new space; and for debugging, it ensures that we'd
+	 * data fault on any attempt to use this metaslab before it's ready.
+	 */
+	ms->ms_tree = range_tree_create(&metaslab_rt_ops, ms, &ms->ms_lock);
+	metaslab_group_add(mg, ms);
+
+	ms->ms_fragmentation = metaslab_fragmentation(ms);
+	ms->ms_ops = mg->mg_class->mc_ops;
+
+	/*
+	 * If we're opening an existing pool (txg == 0) or creating
+	 * a new one (txg == TXG_INITIAL), all space is available now.
+	 * If we're adding space to an existing pool, the new space
+	 * does not become available until after this txg has synced.
+	 */
+	if (txg <= TXG_INITIAL)
+		metaslab_sync_done(ms, 0);
+
+	/*
+	 * If metaslab_debug_load is set and we're initializing a metaslab
+	 * that has an allocated space_map object then load the its space
+	 * map so that can verify frees.
+	 */
+	if (metaslab_debug_load && ms->ms_sm != NULL) {
+		mutex_enter(&ms->ms_lock);
+		VERIFY0(metaslab_load(ms));
+		mutex_exit(&ms->ms_lock);
+	}
+
+	if (txg != 0) {
+		vdev_dirty(vd, 0, NULL, txg);
+		vdev_dirty(vd, VDD_METASLAB, ms, txg);
+	}
+
+	*msp = ms;
+
+	return (0);
+}
+
+void
+metaslab_fini(metaslab_t *msp)
+{
+	int t;
+
+	metaslab_group_t *mg = msp->ms_group;
+
+	metaslab_group_remove(mg, msp);
+
+	mutex_enter(&msp->ms_lock);
+
+	VERIFY(msp->ms_group == NULL);
+	vdev_space_update(mg->mg_vd, -space_map_allocated(msp->ms_sm),
+	    0, -msp->ms_size);
+	space_map_close(msp->ms_sm);
+
+	metaslab_unload(msp);
+	range_tree_destroy(msp->ms_tree);
+
+	for (t = 0; t < TXG_SIZE; t++) {
+		range_tree_destroy(msp->ms_alloctree[t]);
+		range_tree_destroy(msp->ms_freetree[t]);
+	}
+
+	for (t = 0; t < TXG_DEFER_SIZE; t++) {
+		range_tree_destroy(msp->ms_defertree[t]);
+	}
+
+	ASSERT0(msp->ms_deferspace);
+
+	mutex_exit(&msp->ms_lock);
+	cv_destroy(&msp->ms_load_cv);
+	mutex_destroy(&msp->ms_lock);
+
+	kmem_free(msp, sizeof (metaslab_t));
+}
+
+#define	FRAGMENTATION_TABLE_SIZE	17
+
+/*
+ * This table defines a segment size based fragmentation metric that will
+ * allow each metaslab to derive its own fragmentation value. This is done
+ * by calculating the space in each bucket of the spacemap histogram and
+ * multiplying that by the fragmetation metric in this table. Doing
+ * this for all buckets and dividing it by the total amount of free
+ * space in this metaslab (i.e. the total free space in all buckets) gives
+ * us the fragmentation metric. This means that a high fragmentation metric
+ * equates to most of the free space being comprised of small segments.
+ * Conversely, if the metric is low, then most of the free space is in
+ * large segments. A 10% change in fragmentation equates to approximately
+ * double the number of segments.
+ *
+ * This table defines 0% fragmented space using 16MB segments. Testing has
+ * shown that segments that are greater than or equal to 16MB do not suffer
+ * from drastic performance problems. Using this value, we derive the rest
+ * of the table. Since the fragmentation value is never stored on disk, it
+ * is possible to change these calculations in the future.
+ */
+int zfs_frag_table[FRAGMENTATION_TABLE_SIZE] = {
+	100,	/* 512B	*/
+	100,	/* 1K	*/
+	98,	/* 2K	*/
+	95,	/* 4K	*/
+	90,	/* 8K	*/
+	80,	/* 16K	*/
+	70,	/* 32K	*/
+	60,	/* 64K	*/
+	50,	/* 128K	*/
+	40,	/* 256K	*/
+	30,	/* 512K	*/
+	20,	/* 1M	*/
+	15,	/* 2M	*/
+	10,	/* 4M	*/
+	5,	/* 8M	*/
+	0	/* 16M	*/
+};
+
+/*
+ * Calclate the metaslab's fragmentation metric. A return value
+ * of ZFS_FRAG_INVALID means that the metaslab has not been upgraded and does
+ * not support this metric. Otherwise, the return value should be in the
+ * range [0, 100].
+ */
+static uint64_t
+metaslab_fragmentation(metaslab_t *msp)
+{
+	spa_t *spa = msp->ms_group->mg_vd->vdev_spa;
+	uint64_t fragmentation = 0;
+	uint64_t total = 0;
+	boolean_t feature_enabled = spa_feature_is_enabled(spa,
+	    SPA_FEATURE_SPACEMAP_HISTOGRAM);
+	int i;
+
+	if (!feature_enabled)
+		return (ZFS_FRAG_INVALID);
+
+	/*
+	 * A null space map means that the entire metaslab is free
+	 * and thus is not fragmented.
+	 */
+	if (msp->ms_sm == NULL)
+		return (0);
+
+	/*
+	 * If this metaslab's space_map has not been upgraded, flag it
+	 * so that we upgrade next time we encounter it.
+	 */
+	if (msp->ms_sm->sm_dbuf->db_size != sizeof (space_map_phys_t)) {
+		vdev_t *vd = msp->ms_group->mg_vd;
+
+		if (spa_writeable(vd->vdev_spa)) {
+			uint64_t txg = spa_syncing_txg(spa);
+
+			msp->ms_condense_wanted = B_TRUE;
+			vdev_dirty(vd, VDD_METASLAB, msp, txg + 1);
+			spa_dbgmsg(spa, "txg %llu, requesting force condense: "
+			    "msp %p, vd %p", txg, msp, vd);
+		}
+		return (ZFS_FRAG_INVALID);
+	}
+
+	for (i = 0; i < SPACE_MAP_HISTOGRAM_SIZE; i++) {
+		uint64_t space = 0;
+		uint8_t shift = msp->ms_sm->sm_shift;
+		int idx = MIN(shift - SPA_MINBLOCKSHIFT + i,
+		    FRAGMENTATION_TABLE_SIZE - 1);
+
+		if (msp->ms_sm->sm_phys->smp_histogram[i] == 0)
+			continue;
+
+		space = msp->ms_sm->sm_phys->smp_histogram[i] << (i + shift);
+		total += space;
+
+		ASSERT3U(idx, <, FRAGMENTATION_TABLE_SIZE);
+		fragmentation += space * zfs_frag_table[idx];
+	}
+
+	if (total > 0)
+		fragmentation /= total;
+	ASSERT3U(fragmentation, <=, 100);
+	return (fragmentation);
+}
+
+/*
+ * Compute a weight -- a selection preference value -- for the given metaslab.
+ * This is based on the amount of free space, the level of fragmentation,
+ * the LBA range, and whether the metaslab is loaded.
+ */
+static uint64_t
+metaslab_weight(metaslab_t *msp)
+{
+	metaslab_group_t *mg = msp->ms_group;
+	vdev_t *vd = mg->mg_vd;
+	uint64_t weight, space;
+
+	ASSERT(MUTEX_HELD(&msp->ms_lock));
+
+	/*
+	 * This vdev is in the process of being removed so there is nothing
+	 * for us to do here.
+	 */
+	if (vd->vdev_removing) {
+		ASSERT0(space_map_allocated(msp->ms_sm));
+		ASSERT0(vd->vdev_ms_shift);
+		return (0);
+	}
+
+	/*
+	 * The baseline weight is the metaslab's free space.
+	 */
+	space = msp->ms_size - space_map_allocated(msp->ms_sm);
+
+	msp->ms_fragmentation = metaslab_fragmentation(msp);
+	if (metaslab_fragmentation_factor_enabled &&
+	    msp->ms_fragmentation != ZFS_FRAG_INVALID) {
+		/*
+		 * Use the fragmentation information to inversely scale
+		 * down the baseline weight. We need to ensure that we
+		 * don't exclude this metaslab completely when it's 100%
+		 * fragmented. To avoid this we reduce the fragmented value
+		 * by 1.
+		 */
+		space = (space * (100 - (msp->ms_fragmentation - 1))) / 100;
+
+		/*
+		 * If space < SPA_MINBLOCKSIZE, then we will not allocate from
+		 * this metaslab again. The fragmentation metric may have
+		 * decreased the space to something smaller than
+		 * SPA_MINBLOCKSIZE, so reset the space to SPA_MINBLOCKSIZE
+		 * so that we can consume any remaining space.
+		 */
+		if (space > 0 && space < SPA_MINBLOCKSIZE)
+			space = SPA_MINBLOCKSIZE;
+	}
+	weight = space;
+
+	/*
+	 * Modern disks have uniform bit density and constant angular velocity.
+	 * Therefore, the outer recording zones are faster (higher bandwidth)
+	 * than the inner zones by the ratio of outer to inner track diameter,
+	 * which is typically around 2:1.  We account for this by assigning
+	 * higher weight to lower metaslabs (multiplier ranging from 2x to 1x).
+	 * In effect, this means that we'll select the metaslab with the most
+	 * free bandwidth rather than simply the one with the most free space.
+	 */
+	if (!vd->vdev_nonrot && metaslab_lba_weighting_enabled) {
+		weight = 2 * weight - (msp->ms_id * weight) / vd->vdev_ms_count;
+		ASSERT(weight >= space && weight <= 2 * space);
+	}
+
+	/*
+	 * If this metaslab is one we're actively using, adjust its
+	 * weight to make it preferable to any inactive metaslab so
+	 * we'll polish it off. If the fragmentation on this metaslab
+	 * has exceed our threshold, then don't mark it active.
+	 */
+	if (msp->ms_loaded && msp->ms_fragmentation != ZFS_FRAG_INVALID &&
+	    msp->ms_fragmentation <= zfs_metaslab_fragmentation_threshold) {
+		weight |= (msp->ms_weight & METASLAB_ACTIVE_MASK);
+	}
+
+	return (weight);
+}
+
+static int
+metaslab_activate(metaslab_t *msp, uint64_t activation_weight)
+{
+	ASSERT(MUTEX_HELD(&msp->ms_lock));
+
+	if ((msp->ms_weight & METASLAB_ACTIVE_MASK) == 0) {
+		metaslab_load_wait(msp);
+		if (!msp->ms_loaded) {
+			int error = metaslab_load(msp);
+			if (error) {
+				metaslab_group_sort(msp->ms_group, msp, 0);
+				return (error);
+			}
+		}
+
+		metaslab_group_sort(msp->ms_group, msp,
+		    msp->ms_weight | activation_weight);
+	}
+	ASSERT(msp->ms_loaded);
+	ASSERT(msp->ms_weight & METASLAB_ACTIVE_MASK);
+
+	return (0);
+}
+
+static void
+metaslab_passivate(metaslab_t *msp, uint64_t size)
+{
+	/*
+	 * If size < SPA_MINBLOCKSIZE, then we will not allocate from
+	 * this metaslab again.  In that case, it had better be empty,
+	 * or we would be leaving space on the table.
+	 */
+	ASSERT(size >= SPA_MINBLOCKSIZE || range_tree_space(msp->ms_tree) == 0);
+	metaslab_group_sort(msp->ms_group, msp, MIN(msp->ms_weight, size));
+	ASSERT((msp->ms_weight & METASLAB_ACTIVE_MASK) == 0);
+}
+
+static void
+metaslab_preload(void *arg)
+{
+	metaslab_t *msp = arg;
+	spa_t *spa = msp->ms_group->mg_vd->vdev_spa;
+	fstrans_cookie_t cookie = spl_fstrans_mark();
+
+	ASSERT(!MUTEX_HELD(&msp->ms_group->mg_lock));
+
+	mutex_enter(&msp->ms_lock);
+	metaslab_load_wait(msp);
+	if (!msp->ms_loaded)
+		(void) metaslab_load(msp);
+
+	/*
+	 * Set the ms_access_txg value so that we don't unload it right away.
+	 */
+	msp->ms_access_txg = spa_syncing_txg(spa) + metaslab_unload_delay + 1;
+	mutex_exit(&msp->ms_lock);
+	spl_fstrans_unmark(cookie);
+}
+
+static void
+metaslab_group_preload(metaslab_group_t *mg)
+{
+	spa_t *spa = mg->mg_vd->vdev_spa;
+	metaslab_t *msp;
+	avl_tree_t *t = &mg->mg_metaslab_tree;
+	int m = 0;
+
+	if (spa_shutting_down(spa) || !metaslab_preload_enabled) {
+		taskq_wait_outstanding(mg->mg_taskq, 0);
+		return;
+	}
+
+	mutex_enter(&mg->mg_lock);
+	/*
+	 * Load the next potential metaslabs
+	 */
+	msp = avl_first(t);
+	while (msp != NULL) {
+		metaslab_t *msp_next = AVL_NEXT(t, msp);
+
+		/*
+		 * We preload only the maximum number of metaslabs specified
+		 * by metaslab_preload_limit. If a metaslab is being forced
+		 * to condense then we preload it too. This will ensure
+		 * that force condensing happens in the next txg.
+		 */
+		if (++m > metaslab_preload_limit && !msp->ms_condense_wanted) {
+			msp = msp_next;
+			continue;
+		}
+
+		/*
+		 * We must drop the metaslab group lock here to preserve
+		 * lock ordering with the ms_lock (when grabbing both
+		 * the mg_lock and the ms_lock, the ms_lock must be taken
+		 * first).  As a result, it is possible that the ordering
+		 * of the metaslabs within the avl tree may change before
+		 * we reacquire the lock. The metaslab cannot be removed from
+		 * the tree while we're in syncing context so it is safe to
+		 * drop the mg_lock here. If the metaslabs are reordered
+		 * nothing will break -- we just may end up loading a
+		 * less than optimal one.
+		 */
+		mutex_exit(&mg->mg_lock);
+		VERIFY(taskq_dispatch(mg->mg_taskq, metaslab_preload,
+		    msp, TQ_SLEEP) != 0);
+		mutex_enter(&mg->mg_lock);
+		msp = msp_next;
+	}
+	mutex_exit(&mg->mg_lock);
+}
+
+/*
+ * Determine if the space map's on-disk footprint is past our tolerance
+ * for inefficiency. We would like to use the following criteria to make
+ * our decision:
+ *
+ * 1. The size of the space map object should not dramatically increase as a
+ * result of writing out the free space range tree.
+ *
+ * 2. The minimal on-disk space map representation is zfs_condense_pct/100
+ * times the size than the free space range tree representation
+ * (i.e. zfs_condense_pct = 110 and in-core = 1MB, minimal = 1.1.MB).
+ *
+ * 3. The on-disk size of the space map should actually decrease.
+ *
+ * Checking the first condition is tricky since we don't want to walk
+ * the entire AVL tree calculating the estimated on-disk size. Instead we
+ * use the size-ordered range tree in the metaslab and calculate the
+ * size required to write out the largest segment in our free tree. If the
+ * size required to represent that segment on disk is larger than the space
+ * map object then we avoid condensing this map.
+ *
+ * To determine the second criterion we use a best-case estimate and assume
+ * each segment can be represented on-disk as a single 64-bit entry. We refer
+ * to this best-case estimate as the space map's minimal form.
+ *
+ * Unfortunately, we cannot compute the on-disk size of the space map in this
+ * context because we cannot accurately compute the effects of compression, etc.
+ * Instead, we apply the heuristic described in the block comment for
+ * zfs_metaslab_condense_block_threshold - we only condense if the space used
+ * is greater than a threshold number of blocks.
+ */
+static boolean_t
+metaslab_should_condense(metaslab_t *msp)
+{
+	space_map_t *sm = msp->ms_sm;
+	range_seg_t *rs;
+	uint64_t size, entries, segsz, object_size, optimal_size, record_size;
+	dmu_object_info_t doi;
+	uint64_t vdev_blocksize = 1 << msp->ms_group->mg_vd->vdev_ashift;
+
+	ASSERT(MUTEX_HELD(&msp->ms_lock));
+	ASSERT(msp->ms_loaded);
+
+	/*
+	 * Use the ms_size_tree range tree, which is ordered by size, to
+	 * obtain the largest segment in the free tree. We always condense
+	 * metaslabs that are empty and metaslabs for which a condense
+	 * request has been made.
+	 */
+	rs = avl_last(&msp->ms_size_tree);
+	if (rs == NULL || msp->ms_condense_wanted)
+		return (B_TRUE);
+
+	/*
+	 * Calculate the number of 64-bit entries this segment would
+	 * require when written to disk. If this single segment would be
+	 * larger on-disk than the entire current on-disk structure, then
+	 * clearly condensing will increase the on-disk structure size.
+	 */
+	size = (rs->rs_end - rs->rs_start) >> sm->sm_shift;
+	entries = size / (MIN(size, SM_RUN_MAX));
+	segsz = entries * sizeof (uint64_t);
+
+	optimal_size = sizeof (uint64_t) * avl_numnodes(&msp->ms_tree->rt_root);
+	object_size = space_map_length(msp->ms_sm);
+
+	dmu_object_info_from_db(sm->sm_dbuf, &doi);
+	record_size = MAX(doi.doi_data_block_size, vdev_blocksize);
+
+	return (segsz <= object_size &&
+	    object_size >= (optimal_size * zfs_condense_pct / 100) &&
+	    object_size > zfs_metaslab_condense_block_threshold * record_size);
+}
+
+/*
+ * Condense the on-disk space map representation to its minimized form.
+ * The minimized form consists of a small number of allocations followed by
+ * the entries of the free range tree.
+ */
+static void
+metaslab_condense(metaslab_t *msp, uint64_t txg, dmu_tx_t *tx)
+{
+	spa_t *spa = msp->ms_group->mg_vd->vdev_spa;
+	range_tree_t *freetree = msp->ms_freetree[txg & TXG_MASK];
+	range_tree_t *condense_tree;
+	space_map_t *sm = msp->ms_sm;
+	int t;
+
+	ASSERT(MUTEX_HELD(&msp->ms_lock));
+	ASSERT3U(spa_sync_pass(spa), ==, 1);
+	ASSERT(msp->ms_loaded);
+
+
+	spa_dbgmsg(spa, "condensing: txg %llu, msp[%llu] %p, "
+	    "smp size %llu, segments %lu, forcing condense=%s", txg,
+	    msp->ms_id, msp, space_map_length(msp->ms_sm),
+	    avl_numnodes(&msp->ms_tree->rt_root),
+	    msp->ms_condense_wanted ? "TRUE" : "FALSE");
+
+	msp->ms_condense_wanted = B_FALSE;
+
+	/*
+	 * Create an range tree that is 100% allocated. We remove segments
+	 * that have been freed in this txg, any deferred frees that exist,
+	 * and any allocation in the future. Removing segments should be
+	 * a relatively inexpensive operation since we expect these trees to
+	 * have a small number of nodes.
+	 */
+	condense_tree = range_tree_create(NULL, NULL, &msp->ms_lock);
+	range_tree_add(condense_tree, msp->ms_start, msp->ms_size);
+
+	/*
+	 * Remove what's been freed in this txg from the condense_tree.
+	 * Since we're in sync_pass 1, we know that all the frees from
+	 * this txg are in the freetree.
+	 */
+	range_tree_walk(freetree, range_tree_remove, condense_tree);
+
+	for (t = 0; t < TXG_DEFER_SIZE; t++) {
+		range_tree_walk(msp->ms_defertree[t],
+		    range_tree_remove, condense_tree);
+	}
+
+	for (t = 1; t < TXG_CONCURRENT_STATES; t++) {
+		range_tree_walk(msp->ms_alloctree[(txg + t) & TXG_MASK],
+		    range_tree_remove, condense_tree);
+	}
+
+	/*
+	 * We're about to drop the metaslab's lock thus allowing
+	 * other consumers to change it's content. Set the
+	 * metaslab's ms_condensing flag to ensure that
+	 * allocations on this metaslab do not occur while we're
+	 * in the middle of committing it to disk. This is only critical
+	 * for the ms_tree as all other range trees use per txg
+	 * views of their content.
+	 */
+	msp->ms_condensing = B_TRUE;
+
+	mutex_exit(&msp->ms_lock);
+	space_map_truncate(sm, tx);
+	mutex_enter(&msp->ms_lock);
+
+	/*
+	 * While we would ideally like to create a space_map representation
+	 * that consists only of allocation records, doing so can be
+	 * prohibitively expensive because the in-core free tree can be
+	 * large, and therefore computationally expensive to subtract
+	 * from the condense_tree. Instead we sync out two trees, a cheap
+	 * allocation only tree followed by the in-core free tree. While not
+	 * optimal, this is typically close to optimal, and much cheaper to
+	 * compute.
+	 */
+	space_map_write(sm, condense_tree, SM_ALLOC, tx);
+	range_tree_vacate(condense_tree, NULL, NULL);
+	range_tree_destroy(condense_tree);
+
+	space_map_write(sm, msp->ms_tree, SM_FREE, tx);
+	msp->ms_condensing = B_FALSE;
+}
+
+/*
+ * Write a metaslab to disk in the context of the specified transaction group.
+ */
+void
+metaslab_sync(metaslab_t *msp, uint64_t txg)
+{
+	metaslab_group_t *mg = msp->ms_group;
+	vdev_t *vd = mg->mg_vd;
+	spa_t *spa = vd->vdev_spa;
+	objset_t *mos = spa_meta_objset(spa);
+	range_tree_t *alloctree = msp->ms_alloctree[txg & TXG_MASK];
+	range_tree_t **freetree = &msp->ms_freetree[txg & TXG_MASK];
+	range_tree_t **freed_tree =
+	    &msp->ms_freetree[TXG_CLEAN(txg) & TXG_MASK];
+	dmu_tx_t *tx;
+	uint64_t object = space_map_object(msp->ms_sm);
+
+	ASSERT(!vd->vdev_ishole);
+
+	/*
+	 * This metaslab has just been added so there's no work to do now.
+	 */
+	if (*freetree == NULL) {
+		ASSERT3P(alloctree, ==, NULL);
+		return;
+	}
+
+	ASSERT3P(alloctree, !=, NULL);
+	ASSERT3P(*freetree, !=, NULL);
+	ASSERT3P(*freed_tree, !=, NULL);
+
+	/*
+	 * Normally, we don't want to process a metaslab if there
+	 * are no allocations or frees to perform. However, if the metaslab
+	 * is being forced to condense we need to let it through.
+	 */
+	if (range_tree_space(alloctree) == 0 &&
+	    range_tree_space(*freetree) == 0 &&
+	    !msp->ms_condense_wanted)
+		return;
+
+	/*
+	 * The only state that can actually be changing concurrently with
+	 * metaslab_sync() is the metaslab's ms_tree.  No other thread can
+	 * be modifying this txg's alloctree, freetree, freed_tree, or
+	 * space_map_phys_t. Therefore, we only hold ms_lock to satify
+	 * space_map ASSERTs. We drop it whenever we call into the DMU,
+	 * because the DMU can call down to us (e.g. via zio_free()) at
+	 * any time.
+	 */
+
+	tx = dmu_tx_create_assigned(spa_get_dsl(spa), txg);
+
+	if (msp->ms_sm == NULL) {
+		uint64_t new_object;
+
+		new_object = space_map_alloc(mos, tx);
+		VERIFY3U(new_object, !=, 0);
+
+		VERIFY0(space_map_open(&msp->ms_sm, mos, new_object,
+		    msp->ms_start, msp->ms_size, vd->vdev_ashift,
+		    &msp->ms_lock));
+		ASSERT(msp->ms_sm != NULL);
+	}
+
+	mutex_enter(&msp->ms_lock);
+
+	/*
+	 * Note: metaslab_condense() clears the space_map's histogram.
+	 * Therefore we muse verify and remove this histogram before
+	 * condensing.
+	 */
+	metaslab_group_histogram_verify(mg);
+	metaslab_class_histogram_verify(mg->mg_class);
+	metaslab_group_histogram_remove(mg, msp);
+
+	if (msp->ms_loaded && spa_sync_pass(spa) == 1 &&
+	    metaslab_should_condense(msp)) {
+		metaslab_condense(msp, txg, tx);
+	} else {
+		space_map_write(msp->ms_sm, alloctree, SM_ALLOC, tx);
+		space_map_write(msp->ms_sm, *freetree, SM_FREE, tx);
+	}
+
+	if (msp->ms_loaded) {
+		/*
+		 * When the space map is loaded, we have an accruate
+		 * histogram in the range tree. This gives us an opportunity
+		 * to bring the space map's histogram up-to-date so we clear
+		 * it first before updating it.
+		 */
+		space_map_histogram_clear(msp->ms_sm);
+		space_map_histogram_add(msp->ms_sm, msp->ms_tree, tx);
+	} else {
+		/*
+		 * Since the space map is not loaded we simply update the
+		 * exisiting histogram with what was freed in this txg. This
+		 * means that the on-disk histogram may not have an accurate
+		 * view of the free space but it's close enough to allow
+		 * us to make allocation decisions.
+		 */
+		space_map_histogram_add(msp->ms_sm, *freetree, tx);
+	}
+	metaslab_group_histogram_add(mg, msp);
+	metaslab_group_histogram_verify(mg);
+	metaslab_class_histogram_verify(mg->mg_class);
+
+	/*
+	 * For sync pass 1, we avoid traversing this txg's free range tree
+	 * and instead will just swap the pointers for freetree and
+	 * freed_tree. We can safely do this since the freed_tree is
+	 * guaranteed to be empty on the initial pass.
+	 */
+	if (spa_sync_pass(spa) == 1) {
+		range_tree_swap(freetree, freed_tree);
+	} else {
+		range_tree_vacate(*freetree, range_tree_add, *freed_tree);
+	}
+	range_tree_vacate(alloctree, NULL, NULL);
+
+	ASSERT0(range_tree_space(msp->ms_alloctree[txg & TXG_MASK]));
+	ASSERT0(range_tree_space(msp->ms_freetree[txg & TXG_MASK]));
+
+	mutex_exit(&msp->ms_lock);
+
+	if (object != space_map_object(msp->ms_sm)) {
+		object = space_map_object(msp->ms_sm);
+		dmu_write(mos, vd->vdev_ms_array, sizeof (uint64_t) *
+		    msp->ms_id, sizeof (uint64_t), &object, tx);
+	}
+	dmu_tx_commit(tx);
+}
+
+/*
+ * Called after a transaction group has completely synced to mark
+ * all of the metaslab's free space as usable.
+ */
+void
+metaslab_sync_done(metaslab_t *msp, uint64_t txg)
+{
+	metaslab_group_t *mg = msp->ms_group;
+	vdev_t *vd = mg->mg_vd;
+	range_tree_t **freed_tree;
+	range_tree_t **defer_tree;
+	int64_t alloc_delta, defer_delta;
+	int t;
+
+	ASSERT(!vd->vdev_ishole);
+
+	mutex_enter(&msp->ms_lock);
+
+	/*
+	 * If this metaslab is just becoming available, initialize its
+	 * alloctrees, freetrees, and defertree and add its capacity to
+	 * the vdev.
+	 */
+	if (msp->ms_freetree[TXG_CLEAN(txg) & TXG_MASK] == NULL) {
+		for (t = 0; t < TXG_SIZE; t++) {
+			ASSERT(msp->ms_alloctree[t] == NULL);
+			ASSERT(msp->ms_freetree[t] == NULL);
+
+			msp->ms_alloctree[t] = range_tree_create(NULL, msp,
+			    &msp->ms_lock);
+			msp->ms_freetree[t] = range_tree_create(NULL, msp,
+			    &msp->ms_lock);
+		}
+
+		for (t = 0; t < TXG_DEFER_SIZE; t++) {
+			ASSERT(msp->ms_defertree[t] == NULL);
+
+			msp->ms_defertree[t] = range_tree_create(NULL, msp,
+			    &msp->ms_lock);
+		}
+
+		vdev_space_update(vd, 0, 0, msp->ms_size);
+	}
+
+	freed_tree = &msp->ms_freetree[TXG_CLEAN(txg) & TXG_MASK];
+	defer_tree = &msp->ms_defertree[txg % TXG_DEFER_SIZE];
+
+	alloc_delta = space_map_alloc_delta(msp->ms_sm);
+	defer_delta = range_tree_space(*freed_tree) -
+	    range_tree_space(*defer_tree);
+
+	vdev_space_update(vd, alloc_delta + defer_delta, defer_delta, 0);
+
+	ASSERT0(range_tree_space(msp->ms_alloctree[txg & TXG_MASK]));
+	ASSERT0(range_tree_space(msp->ms_freetree[txg & TXG_MASK]));
+
+	/*
+	 * If there's a metaslab_load() in progress, wait for it to complete
+	 * so that we have a consistent view of the in-core space map.
+	 */
+	metaslab_load_wait(msp);
+
+	/*
+	 * Move the frees from the defer_tree back to the free
+	 * range tree (if it's loaded). Swap the freed_tree and the
+	 * defer_tree -- this is safe to do because we've just emptied out
+	 * the defer_tree.
+	 */
+	range_tree_vacate(*defer_tree,
+	    msp->ms_loaded ? range_tree_add : NULL, msp->ms_tree);
+	range_tree_swap(freed_tree, defer_tree);
+
+	space_map_update(msp->ms_sm);
+
+	msp->ms_deferspace += defer_delta;
+	ASSERT3S(msp->ms_deferspace, >=, 0);
+	ASSERT3S(msp->ms_deferspace, <=, msp->ms_size);
+	if (msp->ms_deferspace != 0) {
+		/*
+		 * Keep syncing this metaslab until all deferred frees
+		 * are back in circulation.
+		 */
+		vdev_dirty(vd, VDD_METASLAB, msp, txg + 1);
+	}
+
+	if (msp->ms_loaded && msp->ms_access_txg < txg) {
+		for (t = 1; t < TXG_CONCURRENT_STATES; t++) {
+			VERIFY0(range_tree_space(
+			    msp->ms_alloctree[(txg + t) & TXG_MASK]));
+		}
+
+		if (!metaslab_debug_unload)
+			metaslab_unload(msp);
+	}
+
+	metaslab_group_sort(mg, msp, metaslab_weight(msp));
+	mutex_exit(&msp->ms_lock);
+}
+
+void
+metaslab_sync_reassess(metaslab_group_t *mg)
+{
+	metaslab_group_alloc_update(mg);
+	mg->mg_fragmentation = metaslab_group_fragmentation(mg);
+
+	/*
+	 * Preload the next potential metaslabs
+	 */
+	metaslab_group_preload(mg);
+}
+
+static uint64_t
+metaslab_distance(metaslab_t *msp, dva_t *dva)
+{
+	uint64_t ms_shift = msp->ms_group->mg_vd->vdev_ms_shift;
+	uint64_t offset = DVA_GET_OFFSET(dva) >> ms_shift;
+	uint64_t start = msp->ms_id;
+
+	if (msp->ms_group->mg_vd->vdev_id != DVA_GET_VDEV(dva))
+		return (1ULL << 63);
+
+	if (offset < start)
+		return ((start - offset) << ms_shift);
+	if (offset > start)
+		return ((offset - start) << ms_shift);
+	return (0);
+}
+
+static uint64_t
+metaslab_group_alloc(metaslab_group_t *mg, uint64_t psize, uint64_t asize,
+    uint64_t txg, uint64_t min_distance, dva_t *dva, int d)
+{
+	spa_t *spa = mg->mg_vd->vdev_spa;
+	metaslab_t *msp = NULL;
+	uint64_t offset = -1ULL;
+	avl_tree_t *t = &mg->mg_metaslab_tree;
+	uint64_t activation_weight;
+	uint64_t target_distance;
+	int i;
+
+	activation_weight = METASLAB_WEIGHT_PRIMARY;
+	for (i = 0; i < d; i++) {
+		if (DVA_GET_VDEV(&dva[i]) == mg->mg_vd->vdev_id) {
+			activation_weight = METASLAB_WEIGHT_SECONDARY;
+			break;
+		}
+	}
+
+	for (;;) {
+		boolean_t was_active;
+
+		mutex_enter(&mg->mg_lock);
+		for (msp = avl_first(t); msp; msp = AVL_NEXT(t, msp)) {
+			if (msp->ms_weight < asize) {
+				spa_dbgmsg(spa, "%s: failed to meet weight "
+				    "requirement: vdev %llu, txg %llu, mg %p, "
+				    "msp %p, psize %llu, asize %llu, "
+				    "weight %llu", spa_name(spa),
+				    mg->mg_vd->vdev_id, txg,
+				    mg, msp, psize, asize, msp->ms_weight);
+				mutex_exit(&mg->mg_lock);
+				return (-1ULL);
+			}
+
+			/*
+			 * If the selected metaslab is condensing, skip it.
+			 */
+			if (msp->ms_condensing)
+				continue;
+
+			was_active = msp->ms_weight & METASLAB_ACTIVE_MASK;
+			if (activation_weight == METASLAB_WEIGHT_PRIMARY)
+				break;
+
+			target_distance = min_distance +
+			    (space_map_allocated(msp->ms_sm) != 0 ? 0 :
+			    min_distance >> 1);
+
+			for (i = 0; i < d; i++)
+				if (metaslab_distance(msp, &dva[i]) <
+				    target_distance)
+					break;
+			if (i == d)
+				break;
+		}
+		mutex_exit(&mg->mg_lock);
+		if (msp == NULL)
+			return (-1ULL);
+
+		mutex_enter(&msp->ms_lock);
+
+		/*
+		 * Ensure that the metaslab we have selected is still
+		 * capable of handling our request. It's possible that
+		 * another thread may have changed the weight while we
+		 * were blocked on the metaslab lock.
+		 */
+		if (msp->ms_weight < asize || (was_active &&
+		    !(msp->ms_weight & METASLAB_ACTIVE_MASK) &&
+		    activation_weight == METASLAB_WEIGHT_PRIMARY)) {
+			mutex_exit(&msp->ms_lock);
+			continue;
+		}
+
+		if ((msp->ms_weight & METASLAB_WEIGHT_SECONDARY) &&
+		    activation_weight == METASLAB_WEIGHT_PRIMARY) {
+			metaslab_passivate(msp,
+			    msp->ms_weight & ~METASLAB_ACTIVE_MASK);
+			mutex_exit(&msp->ms_lock);
+			continue;
+		}
+
+		if (metaslab_activate(msp, activation_weight) != 0) {
+			mutex_exit(&msp->ms_lock);
+			continue;
+		}
+
+		/*
+		 * If this metaslab is currently condensing then pick again as
+		 * we can't manipulate this metaslab until it's committed
+		 * to disk.
+		 */
+		if (msp->ms_condensing) {
+			mutex_exit(&msp->ms_lock);
+			continue;
+		}
+
+		if ((offset = metaslab_block_alloc(msp, asize)) != -1ULL)
+			break;
+
+		metaslab_passivate(msp, metaslab_block_maxsize(msp));
+		mutex_exit(&msp->ms_lock);
+	}
+
+	if (range_tree_space(msp->ms_alloctree[txg & TXG_MASK]) == 0)
+		vdev_dirty(mg->mg_vd, VDD_METASLAB, msp, txg);
+
+	range_tree_add(msp->ms_alloctree[txg & TXG_MASK], offset, asize);
+	msp->ms_access_txg = txg + metaslab_unload_delay;
+
+	mutex_exit(&msp->ms_lock);
+
+	return (offset);
+}
+
+/*
+ * Allocate a block for the specified i/o.
+ */
+static int
+metaslab_alloc_dva(spa_t *spa, metaslab_class_t *mc, uint64_t psize,
+    dva_t *dva, int d, dva_t *hintdva, uint64_t txg, int flags)
+{
+	metaslab_group_t *mg, *fast_mg, *rotor;
+	vdev_t *vd;
+	int dshift = 3;
+	int all_zero;
+	int zio_lock = B_FALSE;
+	boolean_t allocatable;
+	uint64_t offset = -1ULL;
+	uint64_t asize;
+	uint64_t distance;
+
+	ASSERT(!DVA_IS_VALID(&dva[d]));
+
+	/*
+	 * For testing, make some blocks above a certain size be gang blocks.
+	 */
+	if (psize >= metaslab_gang_bang && (ddi_get_lbolt() & 3) == 0)
+		return (SET_ERROR(ENOSPC));
+
+	if (flags & METASLAB_FASTWRITE)
+		mutex_enter(&mc->mc_fastwrite_lock);
+
+	/*
+	 * Start at the rotor and loop through all mgs until we find something.
+	 * Note that there's no locking on mc_rotor or mc_aliquot because
+	 * nothing actually breaks if we miss a few updates -- we just won't
+	 * allocate quite as evenly.  It all balances out over time.
+	 *
+	 * If we are doing ditto or log blocks, try to spread them across
+	 * consecutive vdevs.  If we're forced to reuse a vdev before we've
+	 * allocated all of our ditto blocks, then try and spread them out on
+	 * that vdev as much as possible.  If it turns out to not be possible,
+	 * gradually lower our standards until anything becomes acceptable.
+	 * Also, allocating on consecutive vdevs (as opposed to random vdevs)
+	 * gives us hope of containing our fault domains to something we're
+	 * able to reason about.  Otherwise, any two top-level vdev failures
+	 * will guarantee the loss of data.  With consecutive allocation,
+	 * only two adjacent top-level vdev failures will result in data loss.
+	 *
+	 * If we are doing gang blocks (hintdva is non-NULL), try to keep
+	 * ourselves on the same vdev as our gang block header.  That
+	 * way, we can hope for locality in vdev_cache, plus it makes our
+	 * fault domains something tractable.
+	 */
+	if (hintdva) {
+		vd = vdev_lookup_top(spa, DVA_GET_VDEV(&hintdva[d]));
+
+		/*
+		 * It's possible the vdev we're using as the hint no
+		 * longer exists (i.e. removed). Consult the rotor when
+		 * all else fails.
+		 */
+		if (vd != NULL) {
+			mg = vd->vdev_mg;
+
+			if (flags & METASLAB_HINTBP_AVOID &&
+			    mg->mg_next != NULL)
+				mg = mg->mg_next;
+		} else {
+			mg = mc->mc_rotor;
+		}
+	} else if (d != 0) {
+		vd = vdev_lookup_top(spa, DVA_GET_VDEV(&dva[d - 1]));
+		mg = vd->vdev_mg->mg_next;
+	} else if (flags & METASLAB_FASTWRITE) {
+		mg = fast_mg = mc->mc_rotor;
+
+		do {
+			if (fast_mg->mg_vd->vdev_pending_fastwrite <
+			    mg->mg_vd->vdev_pending_fastwrite)
+				mg = fast_mg;
+		} while ((fast_mg = fast_mg->mg_next) != mc->mc_rotor);
+
+	} else {
+		mg = mc->mc_rotor;
+	}
+
+	/*
+	 * If the hint put us into the wrong metaslab class, or into a
+	 * metaslab group that has been passivated, just follow the rotor.
+	 */
+	if (mg->mg_class != mc || mg->mg_activation_count <= 0)
+		mg = mc->mc_rotor;
+
+	rotor = mg;
+top:
+	all_zero = B_TRUE;
+	do {
+		ASSERT(mg->mg_activation_count == 1);
+
+		vd = mg->mg_vd;
+
+		/*
+		 * Don't allocate from faulted devices.
+		 */
+		if (zio_lock) {
+			spa_config_enter(spa, SCL_ZIO, FTAG, RW_READER);
+			allocatable = vdev_allocatable(vd);
+			spa_config_exit(spa, SCL_ZIO, FTAG);
+		} else {
+			allocatable = vdev_allocatable(vd);
+		}
+
+		/*
+		 * Determine if the selected metaslab group is eligible
+		 * for allocations. If we're ganging or have requested
+		 * an allocation for the smallest gang block size
+		 * then we don't want to avoid allocating to the this
+		 * metaslab group. If we're in this condition we should
+		 * try to allocate from any device possible so that we
+		 * don't inadvertently return ENOSPC and suspend the pool
+		 * even though space is still available.
+		 */
+		if (allocatable && CAN_FASTGANG(flags) &&
+		    psize > SPA_GANGBLOCKSIZE)
+			allocatable = metaslab_group_allocatable(mg);
+
+		if (!allocatable)
+			goto next;
+
+		/*
+		 * Avoid writing single-copy data to a failing vdev
+		 * unless the user instructs us that it is okay.
+		 */
+		if ((vd->vdev_stat.vs_write_errors > 0 ||
+		    vd->vdev_state < VDEV_STATE_HEALTHY) &&
+		    d == 0 && dshift == 3 && vd->vdev_children == 0) {
+			all_zero = B_FALSE;
+			goto next;
+		}
+
+		ASSERT(mg->mg_class == mc);
+
+		distance = vd->vdev_asize >> dshift;
+		if (distance <= (1ULL << vd->vdev_ms_shift))
+			distance = 0;
+		else
+			all_zero = B_FALSE;
+
+		asize = vdev_psize_to_asize(vd, psize);
+		ASSERT(P2PHASE(asize, 1ULL << vd->vdev_ashift) == 0);
+
+		offset = metaslab_group_alloc(mg, psize, asize, txg, distance,
+		    dva, d);
+		if (offset != -1ULL) {
+			/*
+			 * If we've just selected this metaslab group,
+			 * figure out whether the corresponding vdev is
+			 * over- or under-used relative to the pool,
+			 * and set an allocation bias to even it out.
+			 *
+			 * Bias is also used to compensate for unequally
+			 * sized vdevs so that space is allocated fairly.
+			 */
+			if (mc->mc_aliquot == 0 && metaslab_bias_enabled) {
+				vdev_stat_t *vs = &vd->vdev_stat;
+				int64_t vs_free = vs->vs_space - vs->vs_alloc;
+				int64_t mc_free = mc->mc_space - mc->mc_alloc;
+				int64_t ratio;
+
+				/*
+				 * Calculate how much more or less we should
+				 * try to allocate from this device during
+				 * this iteration around the rotor.
+				 *
+				 * This basically introduces a zero-centered
+				 * bias towards the devices with the most
+				 * free space, while compensating for vdev
+				 * size differences.
+				 *
+				 * Examples:
+				 *  vdev V1 = 16M/128M
+				 *  vdev V2 = 16M/128M
+				 *  ratio(V1) = 100% ratio(V2) = 100%
+				 *
+				 *  vdev V1 = 16M/128M
+				 *  vdev V2 = 64M/128M
+				 *  ratio(V1) = 127% ratio(V2) =  72%
+				 *
+				 *  vdev V1 = 16M/128M
+				 *  vdev V2 = 64M/512M
+				 *  ratio(V1) =  40% ratio(V2) = 160%
+				 */
+				ratio = (vs_free * mc->mc_alloc_groups * 100) /
+				    (mc_free + 1);
+				mg->mg_bias = ((ratio - 100) *
+				    (int64_t)mg->mg_aliquot) / 100;
+			} else if (!metaslab_bias_enabled) {
+				mg->mg_bias = 0;
+			}
+
+			if ((flags & METASLAB_FASTWRITE) ||
+			    atomic_add_64_nv(&mc->mc_aliquot, asize) >=
+			    mg->mg_aliquot + mg->mg_bias) {
+				mc->mc_rotor = mg->mg_next;
+				mc->mc_aliquot = 0;
+			}
+
+			DVA_SET_VDEV(&dva[d], vd->vdev_id);
+			DVA_SET_OFFSET(&dva[d], offset);
+			DVA_SET_GANG(&dva[d], !!(flags & METASLAB_GANG_HEADER));
+			DVA_SET_ASIZE(&dva[d], asize);
+
+			if (flags & METASLAB_FASTWRITE) {
+				atomic_add_64(&vd->vdev_pending_fastwrite,
+				    psize);
+				mutex_exit(&mc->mc_fastwrite_lock);
+			}
+
+			return (0);
+		}
+next:
+		mc->mc_rotor = mg->mg_next;
+		mc->mc_aliquot = 0;
+	} while ((mg = mg->mg_next) != rotor);
+
+	if (!all_zero) {
+		dshift++;
+		ASSERT(dshift < 64);
+		goto top;
+	}
+
+	if (!allocatable && !zio_lock) {
+		dshift = 3;
+		zio_lock = B_TRUE;
+		goto top;
+	}
+
+	bzero(&dva[d], sizeof (dva_t));
+
+	if (flags & METASLAB_FASTWRITE)
+		mutex_exit(&mc->mc_fastwrite_lock);
+
+	return (SET_ERROR(ENOSPC));
+}
+
+/*
+ * Free the block represented by DVA in the context of the specified
+ * transaction group.
+ */
+static void
+metaslab_free_dva(spa_t *spa, const dva_t *dva, uint64_t txg, boolean_t now)
+{
+	uint64_t vdev = DVA_GET_VDEV(dva);
+	uint64_t offset = DVA_GET_OFFSET(dva);
+	uint64_t size = DVA_GET_ASIZE(dva);
+	vdev_t *vd;
+	metaslab_t *msp;
+
+	if (txg > spa_freeze_txg(spa))
+		return;
+
+	if ((vd = vdev_lookup_top(spa, vdev)) == NULL || !DVA_IS_VALID(dva) ||
+	    (offset >> vd->vdev_ms_shift) >= vd->vdev_ms_count) {
+		zfs_panic_recover("metaslab_free_dva(): bad DVA %llu:%llu:%llu",
+		    (u_longlong_t)vdev, (u_longlong_t)offset,
+		    (u_longlong_t)size);
+		return;
+	}
+
+	msp = vd->vdev_ms[offset >> vd->vdev_ms_shift];
+
+	if (DVA_GET_GANG(dva))
+		size = vdev_psize_to_asize(vd, SPA_GANGBLOCKSIZE);
+
+	mutex_enter(&msp->ms_lock);
+
+	if (now) {
+		range_tree_remove(msp->ms_alloctree[txg & TXG_MASK],
+		    offset, size);
+
+		VERIFY(!msp->ms_condensing);
+		VERIFY3U(offset, >=, msp->ms_start);
+		VERIFY3U(offset + size, <=, msp->ms_start + msp->ms_size);
+		VERIFY3U(range_tree_space(msp->ms_tree) + size, <=,
+		    msp->ms_size);
+		VERIFY0(P2PHASE(offset, 1ULL << vd->vdev_ashift));
+		VERIFY0(P2PHASE(size, 1ULL << vd->vdev_ashift));
+		range_tree_add(msp->ms_tree, offset, size);
+	} else {
+		if (range_tree_space(msp->ms_freetree[txg & TXG_MASK]) == 0)
+			vdev_dirty(vd, VDD_METASLAB, msp, txg);
+		range_tree_add(msp->ms_freetree[txg & TXG_MASK],
+		    offset, size);
+	}
+
+	mutex_exit(&msp->ms_lock);
+}
+
+/*
+ * Intent log support: upon opening the pool after a crash, notify the SPA
+ * of blocks that the intent log has allocated for immediate write, but
+ * which are still considered free by the SPA because the last transaction
+ * group didn't commit yet.
+ */
+static int
+metaslab_claim_dva(spa_t *spa, const dva_t *dva, uint64_t txg)
+{
+	uint64_t vdev = DVA_GET_VDEV(dva);
+	uint64_t offset = DVA_GET_OFFSET(dva);
+	uint64_t size = DVA_GET_ASIZE(dva);
+	vdev_t *vd;
+	metaslab_t *msp;
+	int error = 0;
+
+	ASSERT(DVA_IS_VALID(dva));
+
+	if ((vd = vdev_lookup_top(spa, vdev)) == NULL ||
+	    (offset >> vd->vdev_ms_shift) >= vd->vdev_ms_count)
+		return (SET_ERROR(ENXIO));
+
+	msp = vd->vdev_ms[offset >> vd->vdev_ms_shift];
+
+	if (DVA_GET_GANG(dva))
+		size = vdev_psize_to_asize(vd, SPA_GANGBLOCKSIZE);
+
+	mutex_enter(&msp->ms_lock);
+
+	if ((txg != 0 && spa_writeable(spa)) || !msp->ms_loaded)
+		error = metaslab_activate(msp, METASLAB_WEIGHT_SECONDARY);
+
+	if (error == 0 && !range_tree_contains(msp->ms_tree, offset, size))
+		error = SET_ERROR(ENOENT);
+
+	if (error || txg == 0) {	/* txg == 0 indicates dry run */
+		mutex_exit(&msp->ms_lock);
+		return (error);
+	}
+
+	VERIFY(!msp->ms_condensing);
+	VERIFY0(P2PHASE(offset, 1ULL << vd->vdev_ashift));
+	VERIFY0(P2PHASE(size, 1ULL << vd->vdev_ashift));
+	VERIFY3U(range_tree_space(msp->ms_tree) - size, <=, msp->ms_size);
+	range_tree_remove(msp->ms_tree, offset, size);
+
+	if (spa_writeable(spa)) {	/* don't dirty if we're zdb(1M) */
+		if (range_tree_space(msp->ms_alloctree[txg & TXG_MASK]) == 0)
+			vdev_dirty(vd, VDD_METASLAB, msp, txg);
+		range_tree_add(msp->ms_alloctree[txg & TXG_MASK], offset, size);
+	}
+
+	mutex_exit(&msp->ms_lock);
+
+	return (0);
+}
+
+int
+metaslab_alloc(spa_t *spa, metaslab_class_t *mc, uint64_t psize, blkptr_t *bp,
+    int ndvas, uint64_t txg, blkptr_t *hintbp, int flags)
+{
+	dva_t *dva = bp->blk_dva;
+	dva_t *hintdva = hintbp->blk_dva;
+	int d, error = 0;
+
+	ASSERT(bp->blk_birth == 0);
+	ASSERT(BP_PHYSICAL_BIRTH(bp) == 0);
+
+	spa_config_enter(spa, SCL_ALLOC, FTAG, RW_READER);
+
+	if (mc->mc_rotor == NULL) {	/* no vdevs in this class */
+		spa_config_exit(spa, SCL_ALLOC, FTAG);
+		return (SET_ERROR(ENOSPC));
+	}
+
+	ASSERT(ndvas > 0 && ndvas <= spa_max_replication(spa));
+	ASSERT(BP_GET_NDVAS(bp) == 0);
+	ASSERT(hintbp == NULL || ndvas <= BP_GET_NDVAS(hintbp));
+
+	for (d = 0; d < ndvas; d++) {
+		error = metaslab_alloc_dva(spa, mc, psize, dva, d, hintdva,
+		    txg, flags);
+		if (error != 0) {
+			for (d--; d >= 0; d--) {
+				metaslab_free_dva(spa, &dva[d], txg, B_TRUE);
+				bzero(&dva[d], sizeof (dva_t));
+			}
+			spa_config_exit(spa, SCL_ALLOC, FTAG);
+			return (error);
+		}
+	}
+	ASSERT(error == 0);
+	ASSERT(BP_GET_NDVAS(bp) == ndvas);
+
+	spa_config_exit(spa, SCL_ALLOC, FTAG);
+
+	BP_SET_BIRTH(bp, txg, txg);
+
+	return (0);
+}
+
+void
+metaslab_free(spa_t *spa, const blkptr_t *bp, uint64_t txg, boolean_t now)
+{
+	const dva_t *dva = bp->blk_dva;
+	int d, ndvas = BP_GET_NDVAS(bp);
+
+	ASSERT(!BP_IS_HOLE(bp));
+	ASSERT(!now || bp->blk_birth >= spa_syncing_txg(spa));
+
+	spa_config_enter(spa, SCL_FREE, FTAG, RW_READER);
+
+	for (d = 0; d < ndvas; d++)
+		metaslab_free_dva(spa, &dva[d], txg, now);
+
+	spa_config_exit(spa, SCL_FREE, FTAG);
+}
+
+int
+metaslab_claim(spa_t *spa, const blkptr_t *bp, uint64_t txg)
+{
+	const dva_t *dva = bp->blk_dva;
+	int ndvas = BP_GET_NDVAS(bp);
+	int d, error = 0;
+
+	ASSERT(!BP_IS_HOLE(bp));
+
+	if (txg != 0) {
+		/*
+		 * First do a dry run to make sure all DVAs are claimable,
+		 * so we don't have to unwind from partial failures below.
+		 */
+		if ((error = metaslab_claim(spa, bp, 0)) != 0)
+			return (error);
+	}
+
+	spa_config_enter(spa, SCL_ALLOC, FTAG, RW_READER);
+
+	for (d = 0; d < ndvas; d++)
+		if ((error = metaslab_claim_dva(spa, &dva[d], txg)) != 0)
+			break;
+
+	spa_config_exit(spa, SCL_ALLOC, FTAG);
+
+	ASSERT(error == 0 || txg == 0);
+
+	return (error);
+}
+
+void
+metaslab_fastwrite_mark(spa_t *spa, const blkptr_t *bp)
+{
+	const dva_t *dva = bp->blk_dva;
+	int ndvas = BP_GET_NDVAS(bp);
+	uint64_t psize = BP_GET_PSIZE(bp);
+	int d;
+	vdev_t *vd;
+
+	ASSERT(!BP_IS_HOLE(bp));
+	ASSERT(!BP_IS_EMBEDDED(bp));
+	ASSERT(psize > 0);
+
+	spa_config_enter(spa, SCL_VDEV, FTAG, RW_READER);
+
+	for (d = 0; d < ndvas; d++) {
+		if ((vd = vdev_lookup_top(spa, DVA_GET_VDEV(&dva[d]))) == NULL)
+			continue;
+		atomic_add_64(&vd->vdev_pending_fastwrite, psize);
+	}
+
+	spa_config_exit(spa, SCL_VDEV, FTAG);
+}
+
+void
+metaslab_fastwrite_unmark(spa_t *spa, const blkptr_t *bp)
+{
+	const dva_t *dva = bp->blk_dva;
+	int ndvas = BP_GET_NDVAS(bp);
+	uint64_t psize = BP_GET_PSIZE(bp);
+	int d;
+	vdev_t *vd;
+
+	ASSERT(!BP_IS_HOLE(bp));
+	ASSERT(!BP_IS_EMBEDDED(bp));
+	ASSERT(psize > 0);
+
+	spa_config_enter(spa, SCL_VDEV, FTAG, RW_READER);
+
+	for (d = 0; d < ndvas; d++) {
+		if ((vd = vdev_lookup_top(spa, DVA_GET_VDEV(&dva[d]))) == NULL)
+			continue;
+		ASSERT3U(vd->vdev_pending_fastwrite, >=, psize);
+		atomic_sub_64(&vd->vdev_pending_fastwrite, psize);
+	}
+
+	spa_config_exit(spa, SCL_VDEV, FTAG);
+}
+
+void
+metaslab_check_free(spa_t *spa, const blkptr_t *bp)
+{
+	int i, j;
+
+	if ((zfs_flags & ZFS_DEBUG_ZIO_FREE) == 0)
+		return;
+
+	spa_config_enter(spa, SCL_VDEV, FTAG, RW_READER);
+	for (i = 0; i < BP_GET_NDVAS(bp); i++) {
+		uint64_t vdev = DVA_GET_VDEV(&bp->blk_dva[i]);
+		vdev_t *vd = vdev_lookup_top(spa, vdev);
+		uint64_t offset = DVA_GET_OFFSET(&bp->blk_dva[i]);
+		uint64_t size = DVA_GET_ASIZE(&bp->blk_dva[i]);
+		metaslab_t *msp = vd->vdev_ms[offset >> vd->vdev_ms_shift];
+
+		if (msp->ms_loaded)
+			range_tree_verify(msp->ms_tree, offset, size);
+
+		for (j = 0; j < TXG_SIZE; j++)
+			range_tree_verify(msp->ms_freetree[j], offset, size);
+		for (j = 0; j < TXG_DEFER_SIZE; j++)
+			range_tree_verify(msp->ms_defertree[j], offset, size);
+	}
+	spa_config_exit(spa, SCL_VDEV, FTAG);
+}
+
+#if defined(_KERNEL) && defined(HAVE_SPL)
+module_param(metaslab_aliquot, ulong, 0644);
+module_param(metaslab_debug_load, int, 0644);
+module_param(metaslab_debug_unload, int, 0644);
+module_param(metaslab_preload_enabled, int, 0644);
+module_param(zfs_mg_noalloc_threshold, int, 0644);
+module_param(zfs_mg_fragmentation_threshold, int, 0644);
+module_param(zfs_metaslab_fragmentation_threshold, int, 0644);
+module_param(metaslab_fragmentation_factor_enabled, int, 0644);
+module_param(metaslab_lba_weighting_enabled, int, 0644);
+module_param(metaslab_bias_enabled, int, 0644);
+
+MODULE_PARM_DESC(metaslab_aliquot,
+	"allocation granularity (a.k.a. stripe size)");
+MODULE_PARM_DESC(metaslab_debug_load,
+	"load all metaslabs when pool is first opened");
+MODULE_PARM_DESC(metaslab_debug_unload,
+	"prevent metaslabs from being unloaded");
+MODULE_PARM_DESC(metaslab_preload_enabled,
+	"preload potential metaslabs during reassessment");
+
+MODULE_PARM_DESC(zfs_mg_noalloc_threshold,
+	"percentage of free space for metaslab group to allow allocation");
+MODULE_PARM_DESC(zfs_mg_fragmentation_threshold,
+	"fragmentation for metaslab group to allow allocation");
+
+MODULE_PARM_DESC(zfs_metaslab_fragmentation_threshold,
+	"fragmentation for metaslab to allow allocation");
+MODULE_PARM_DESC(metaslab_fragmentation_factor_enabled,
+	"use the fragmentation metric to prefer less fragmented metaslabs");
+MODULE_PARM_DESC(metaslab_lba_weighting_enabled,
+	"prefer metaslabs with lower LBAs");
+MODULE_PARM_DESC(metaslab_bias_enabled,
+	"enable metaslab group biasing");
+#endif /* _KERNEL && HAVE_SPL */
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/module/zfs/multilist.c
@@ -0,0 +1,375 @@
+/*
+ * CDDL HEADER START
+ *
+ * This file and its contents are supplied under the terms of the
+ * Common Development and Distribution License ("CDDL"), version 1.0.
+ * You may only use this file in accordance with the terms of version
+ * 1.0 of the CDDL.
+ *
+ * A full copy of the text of the CDDL should have accompanied this
+ * source.  A copy of the CDDL is also available via the Internet at
+ * http://www.illumos.org/license/CDDL.
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2013, 2014 by Delphix. All rights reserved.
+ */
+
+#include <sys/zfs_context.h>
+#include <sys/multilist.h>
+#include <sys/trace_multilist.h>
+
+/* needed for spa_get_random() */
+#include <sys/spa.h>
+
+/*
+ * Given the object contained on the list, return a pointer to the
+ * object's multilist_node_t structure it contains.
+ */
+#ifdef DEBUG
+static multilist_node_t *
+multilist_d2l(multilist_t *ml, void *obj)
+{
+	return ((multilist_node_t *)((char *)obj + ml->ml_offset));
+}
+#endif
+
+/*
+ * Initialize a new mutlilist using the parameters specified.
+ *
+ *  - 'size' denotes the size of the structure containing the
+ *     multilist_node_t.
+ *  - 'offset' denotes the byte offset of the mutlilist_node_t within
+ *     the structure that contains it.
+ *  - 'num' specifies the number of internal sublists to create.
+ *  - 'index_func' is used to determine which sublist to insert into
+ *     when the multilist_insert() function is called; as well as which
+ *     sublist to remove from when multilist_remove() is called. The
+ *     requirements this function must meet, are the following:
+ *
+ *      - It must always return the same value when called on the same
+ *        object (to ensure the object is removed from the list it was
+ *        inserted into).
+ *
+ *      - It must return a value in the range [0, number of sublists).
+ *        The multilist_get_num_sublists() function may be used to
+ *        determine the number of sublists in the multilist.
+ *
+ *     Also, in order to reduce internal contention between the sublists
+ *     during insertion and removal, this function should choose evenly
+ *     between all available sublists when inserting. This isn't a hard
+ *     requirement, but a general rule of thumb in order to garner the
+ *     best multi-threaded performance out of the data structure.
+ */
+void
+multilist_create(multilist_t *ml, size_t size, size_t offset, unsigned int num,
+    multilist_sublist_index_func_t *index_func)
+{
+	int i;
+
+	ASSERT3P(ml, !=, NULL);
+	ASSERT3U(size, >, 0);
+	ASSERT3U(size, >=, offset + sizeof (multilist_node_t));
+	ASSERT3U(num, >, 0);
+	ASSERT3P(index_func, !=, NULL);
+
+	ml->ml_offset = offset;
+	ml->ml_num_sublists = num;
+	ml->ml_index_func = index_func;
+
+	ml->ml_sublists = kmem_zalloc(sizeof (multilist_sublist_t) *
+	    ml->ml_num_sublists, KM_SLEEP);
+
+	ASSERT3P(ml->ml_sublists, !=, NULL);
+
+	for (i = 0; i < ml->ml_num_sublists; i++) {
+		multilist_sublist_t *mls = &ml->ml_sublists[i];
+		mutex_init(&mls->mls_lock, NULL, MUTEX_DEFAULT, NULL);
+		list_create(&mls->mls_list, size, offset);
+	}
+}
+
+/*
+ * Destroy the given multilist object, and free up any memory it holds.
+ */
+void
+multilist_destroy(multilist_t *ml)
+{
+	int i;
+
+	ASSERT(multilist_is_empty(ml));
+
+	for (i = 0; i < ml->ml_num_sublists; i++) {
+		multilist_sublist_t *mls = &ml->ml_sublists[i];
+
+		ASSERT(list_is_empty(&mls->mls_list));
+
+		list_destroy(&mls->mls_list);
+		mutex_destroy(&mls->mls_lock);
+	}
+
+	ASSERT3P(ml->ml_sublists, !=, NULL);
+	kmem_free(ml->ml_sublists,
+	    sizeof (multilist_sublist_t) * ml->ml_num_sublists);
+
+	ml->ml_num_sublists = 0;
+	ml->ml_offset = 0;
+}
+
+/*
+ * Insert the given object into the multilist.
+ *
+ * This function will insert the object specified into the sublist
+ * determined using the function given at multilist creation time.
+ *
+ * The sublist locks are automatically acquired if not already held, to
+ * ensure consistency when inserting and removing from multiple threads.
+ */
+void
+multilist_insert(multilist_t *ml, void *obj)
+{
+	unsigned int sublist_idx = ml->ml_index_func(ml, obj);
+	multilist_sublist_t *mls;
+	boolean_t need_lock;
+
+	DTRACE_PROBE3(multilist__insert, multilist_t *, ml,
+	    unsigned int, sublist_idx, void *, obj);
+
+	ASSERT3U(sublist_idx, <, ml->ml_num_sublists);
+
+	mls = &ml->ml_sublists[sublist_idx];
+
+	/*
+	 * Note: Callers may already hold the sublist lock by calling
+	 * multilist_sublist_lock().  Here we rely on MUTEX_HELD()
+	 * returning TRUE if and only if the current thread holds the
+	 * lock.  While it's a little ugly to make the lock recursive in
+	 * this way, it works and allows the calling code to be much
+	 * simpler -- otherwise it would have to pass around a flag
+	 * indicating that it already has the lock.
+	 */
+	need_lock = !MUTEX_HELD(&mls->mls_lock);
+
+	if (need_lock)
+		mutex_enter(&mls->mls_lock);
+
+	ASSERT(!multilist_link_active(multilist_d2l(ml, obj)));
+
+	multilist_sublist_insert_head(mls, obj);
+
+	if (need_lock)
+		mutex_exit(&mls->mls_lock);
+}
+
+/*
+ * Remove the given object from the multilist.
+ *
+ * This function will remove the object specified from the sublist
+ * determined using the function given at multilist creation time.
+ *
+ * The necessary sublist locks are automatically acquired, to ensure
+ * consistency when inserting and removing from multiple threads.
+ */
+void
+multilist_remove(multilist_t *ml, void *obj)
+{
+	unsigned int sublist_idx = ml->ml_index_func(ml, obj);
+	multilist_sublist_t *mls;
+	boolean_t need_lock;
+
+	DTRACE_PROBE3(multilist__remove, multilist_t *, ml,
+	    unsigned int, sublist_idx, void *, obj);
+
+	ASSERT3U(sublist_idx, <, ml->ml_num_sublists);
+
+	mls = &ml->ml_sublists[sublist_idx];
+	/* See comment in multilist_insert(). */
+	need_lock = !MUTEX_HELD(&mls->mls_lock);
+
+	if (need_lock)
+		mutex_enter(&mls->mls_lock);
+
+	ASSERT(multilist_link_active(multilist_d2l(ml, obj)));
+
+	multilist_sublist_remove(mls, obj);
+
+	if (need_lock)
+		mutex_exit(&mls->mls_lock);
+}
+
+/*
+ * Check to see if this multilist object is empty.
+ *
+ * This will return TRUE if it finds all of the sublists of this
+ * multilist to be empty, and FALSE otherwise. Each sublist lock will be
+ * automatically acquired as necessary.
+ *
+ * If concurrent insertions and removals are occurring, the semantics
+ * of this function become a little fuzzy. Instead of locking all
+ * sublists for the entire call time of the function, each sublist is
+ * only locked as it is individually checked for emptiness. Thus, it's
+ * possible for this function to return TRUE with non-empty sublists at
+ * the time the function returns. This would be due to another thread
+ * inserting into a given sublist, after that specific sublist was check
+ * and deemed empty, but before all sublists have been checked.
+ */
+int
+multilist_is_empty(multilist_t *ml)
+{
+	int i;
+
+	for (i = 0; i < ml->ml_num_sublists; i++) {
+		multilist_sublist_t *mls = &ml->ml_sublists[i];
+		/* See comment in multilist_insert(). */
+		boolean_t need_lock = !MUTEX_HELD(&mls->mls_lock);
+
+		if (need_lock)
+			mutex_enter(&mls->mls_lock);
+
+		if (!list_is_empty(&mls->mls_list)) {
+			if (need_lock)
+				mutex_exit(&mls->mls_lock);
+
+			return (FALSE);
+		}
+
+		if (need_lock)
+			mutex_exit(&mls->mls_lock);
+	}
+
+	return (TRUE);
+}
+
+/* Return the number of sublists composing this multilist */
+unsigned int
+multilist_get_num_sublists(multilist_t *ml)
+{
+	return (ml->ml_num_sublists);
+}
+
+/* Return a randomly selected, valid sublist index for this multilist */
+unsigned int
+multilist_get_random_index(multilist_t *ml)
+{
+	return (spa_get_random(ml->ml_num_sublists));
+}
+
+/* Lock and return the sublist specified at the given index */
+multilist_sublist_t *
+multilist_sublist_lock(multilist_t *ml, unsigned int sublist_idx)
+{
+	multilist_sublist_t *mls;
+
+	ASSERT3U(sublist_idx, <, ml->ml_num_sublists);
+	mls = &ml->ml_sublists[sublist_idx];
+	mutex_enter(&mls->mls_lock);
+
+	return (mls);
+}
+
+void
+multilist_sublist_unlock(multilist_sublist_t *mls)
+{
+	mutex_exit(&mls->mls_lock);
+}
+
+/*
+ * We're allowing any object to be inserted into this specific sublist,
+ * but this can lead to trouble if multilist_remove() is called to
+ * remove this object. Specifically, if calling ml_index_func on this
+ * object returns an index for sublist different than what is passed as
+ * a parameter here, any call to multilist_remove() with this newly
+ * inserted object is undefined! (the call to multilist_remove() will
+ * remove the object from a list that it isn't contained in)
+ */
+void
+multilist_sublist_insert_head(multilist_sublist_t *mls, void *obj)
+{
+	ASSERT(MUTEX_HELD(&mls->mls_lock));
+	list_insert_head(&mls->mls_list, obj);
+}
+
+/* please see comment above multilist_sublist_insert_head */
+void
+multilist_sublist_insert_tail(multilist_sublist_t *mls, void *obj)
+{
+	ASSERT(MUTEX_HELD(&mls->mls_lock));
+	list_insert_tail(&mls->mls_list, obj);
+}
+
+/*
+ * Move the object one element forward in the list.
+ *
+ * This function will move the given object forward in the list (towards
+ * the head) by one object. So, in essence, it will swap its position in
+ * the list with its "prev" pointer. If the given object is already at the
+ * head of the list, it cannot be moved forward any more than it already
+ * is, so no action is taken.
+ *
+ * NOTE: This function **must not** remove any object from the list other
+ *       than the object given as the parameter. This is relied upon in
+ *       arc_evict_state_impl().
+ */
+void
+multilist_sublist_move_forward(multilist_sublist_t *mls, void *obj)
+{
+	void *prev = list_prev(&mls->mls_list, obj);
+
+	ASSERT(MUTEX_HELD(&mls->mls_lock));
+	ASSERT(!list_is_empty(&mls->mls_list));
+
+	/* 'obj' must be at the head of the list, nothing to do */
+	if (prev == NULL)
+		return;
+
+	list_remove(&mls->mls_list, obj);
+	list_insert_before(&mls->mls_list, prev, obj);
+}
+
+void
+multilist_sublist_remove(multilist_sublist_t *mls, void *obj)
+{
+	ASSERT(MUTEX_HELD(&mls->mls_lock));
+	list_remove(&mls->mls_list, obj);
+}
+
+void *
+multilist_sublist_head(multilist_sublist_t *mls)
+{
+	ASSERT(MUTEX_HELD(&mls->mls_lock));
+	return (list_head(&mls->mls_list));
+}
+
+void *
+multilist_sublist_tail(multilist_sublist_t *mls)
+{
+	ASSERT(MUTEX_HELD(&mls->mls_lock));
+	return (list_tail(&mls->mls_list));
+}
+
+void *
+multilist_sublist_next(multilist_sublist_t *mls, void *obj)
+{
+	ASSERT(MUTEX_HELD(&mls->mls_lock));
+	return (list_next(&mls->mls_list, obj));
+}
+
+void *
+multilist_sublist_prev(multilist_sublist_t *mls, void *obj)
+{
+	ASSERT(MUTEX_HELD(&mls->mls_lock));
+	return (list_prev(&mls->mls_list, obj));
+}
+
+void
+multilist_link_init(multilist_node_t *link)
+{
+	list_link_init(link);
+}
+
+int
+multilist_link_active(multilist_node_t *link)
+{
+	return (list_link_active(link));
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/module/zfs/range_tree.c
@@ -0,0 +1,411 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * Copyright (c) 2013, 2014 by Delphix. All rights reserved.
+ */
+
+#include <sys/zfs_context.h>
+#include <sys/spa.h>
+#include <sys/dmu.h>
+#include <sys/dnode.h>
+#include <sys/zio.h>
+#include <sys/range_tree.h>
+
+kmem_cache_t *range_seg_cache;
+
+void
+range_tree_init(void)
+{
+	ASSERT(range_seg_cache == NULL);
+	range_seg_cache = kmem_cache_create("range_seg_cache",
+	    sizeof (range_seg_t), 0, NULL, NULL, NULL, NULL, NULL, 0);
+}
+
+void
+range_tree_fini(void)
+{
+	kmem_cache_destroy(range_seg_cache);
+	range_seg_cache = NULL;
+}
+
+void
+range_tree_stat_verify(range_tree_t *rt)
+{
+	range_seg_t *rs;
+	uint64_t hist[RANGE_TREE_HISTOGRAM_SIZE] = { 0 };
+	int i;
+
+	for (rs = avl_first(&rt->rt_root); rs != NULL;
+	    rs = AVL_NEXT(&rt->rt_root, rs)) {
+		uint64_t size = rs->rs_end - rs->rs_start;
+		int idx	= highbit64(size) - 1;
+
+		hist[idx]++;
+		ASSERT3U(hist[idx], !=, 0);
+	}
+
+	for (i = 0; i < RANGE_TREE_HISTOGRAM_SIZE; i++) {
+		if (hist[i] != rt->rt_histogram[i]) {
+			zfs_dbgmsg("i=%d, hist=%p, hist=%llu, rt_hist=%llu",
+			    i, hist, hist[i], rt->rt_histogram[i]);
+		}
+		VERIFY3U(hist[i], ==, rt->rt_histogram[i]);
+	}
+}
+
+static void
+range_tree_stat_incr(range_tree_t *rt, range_seg_t *rs)
+{
+	uint64_t size = rs->rs_end - rs->rs_start;
+	int idx = highbit64(size) - 1;
+
+	ASSERT(size != 0);
+	ASSERT3U(idx, <,
+	    sizeof (rt->rt_histogram) / sizeof (*rt->rt_histogram));
+
+	ASSERT(MUTEX_HELD(rt->rt_lock));
+	rt->rt_histogram[idx]++;
+	ASSERT3U(rt->rt_histogram[idx], !=, 0);
+}
+
+static void
+range_tree_stat_decr(range_tree_t *rt, range_seg_t *rs)
+{
+	uint64_t size = rs->rs_end - rs->rs_start;
+	int idx = highbit64(size) - 1;
+
+	ASSERT(size != 0);
+	ASSERT3U(idx, <,
+	    sizeof (rt->rt_histogram) / sizeof (*rt->rt_histogram));
+
+	ASSERT(MUTEX_HELD(rt->rt_lock));
+	ASSERT3U(rt->rt_histogram[idx], !=, 0);
+	rt->rt_histogram[idx]--;
+}
+
+/*
+ * NOTE: caller is responsible for all locking.
+ */
+static int
+range_tree_seg_compare(const void *x1, const void *x2)
+{
+	const range_seg_t *r1 = x1;
+	const range_seg_t *r2 = x2;
+
+	if (r1->rs_start < r2->rs_start) {
+		if (r1->rs_end > r2->rs_start)
+			return (0);
+		return (-1);
+	}
+	if (r1->rs_start > r2->rs_start) {
+		if (r1->rs_start < r2->rs_end)
+			return (0);
+		return (1);
+	}
+	return (0);
+}
+
+range_tree_t *
+range_tree_create(range_tree_ops_t *ops, void *arg, kmutex_t *lp)
+{
+	range_tree_t *rt;
+
+	rt = kmem_zalloc(sizeof (range_tree_t), KM_SLEEP);
+
+	avl_create(&rt->rt_root, range_tree_seg_compare,
+	    sizeof (range_seg_t), offsetof(range_seg_t, rs_node));
+
+	rt->rt_lock = lp;
+	rt->rt_ops = ops;
+	rt->rt_arg = arg;
+
+	if (rt->rt_ops != NULL)
+		rt->rt_ops->rtop_create(rt, rt->rt_arg);
+
+	return (rt);
+}
+
+void
+range_tree_destroy(range_tree_t *rt)
+{
+	VERIFY0(rt->rt_space);
+
+	if (rt->rt_ops != NULL)
+		rt->rt_ops->rtop_destroy(rt, rt->rt_arg);
+
+	avl_destroy(&rt->rt_root);
+	kmem_free(rt, sizeof (*rt));
+}
+
+void
+range_tree_add(void *arg, uint64_t start, uint64_t size)
+{
+	range_tree_t *rt = arg;
+	avl_index_t where;
+	range_seg_t rsearch, *rs_before, *rs_after, *rs;
+	uint64_t end = start + size;
+	boolean_t merge_before, merge_after;
+
+	ASSERT(MUTEX_HELD(rt->rt_lock));
+	VERIFY(size != 0);
+
+	rsearch.rs_start = start;
+	rsearch.rs_end = end;
+	rs = avl_find(&rt->rt_root, &rsearch, &where);
+
+	if (rs != NULL && rs->rs_start <= start && rs->rs_end >= end) {
+		zfs_panic_recover("zfs: allocating allocated segment"
+		    "(offset=%llu size=%llu)\n",
+		    (longlong_t)start, (longlong_t)size);
+		return;
+	}
+
+	/* Make sure we don't overlap with either of our neighbors */
+	VERIFY(rs == NULL);
+
+	rs_before = avl_nearest(&rt->rt_root, where, AVL_BEFORE);
+	rs_after = avl_nearest(&rt->rt_root, where, AVL_AFTER);
+
+	merge_before = (rs_before != NULL && rs_before->rs_end == start);
+	merge_after = (rs_after != NULL && rs_after->rs_start == end);
+
+	if (merge_before && merge_after) {
+		avl_remove(&rt->rt_root, rs_before);
+		if (rt->rt_ops != NULL) {
+			rt->rt_ops->rtop_remove(rt, rs_before, rt->rt_arg);
+			rt->rt_ops->rtop_remove(rt, rs_after, rt->rt_arg);
+		}
+
+		range_tree_stat_decr(rt, rs_before);
+		range_tree_stat_decr(rt, rs_after);
+
+		rs_after->rs_start = rs_before->rs_start;
+		kmem_cache_free(range_seg_cache, rs_before);
+		rs = rs_after;
+	} else if (merge_before) {
+		if (rt->rt_ops != NULL)
+			rt->rt_ops->rtop_remove(rt, rs_before, rt->rt_arg);
+
+		range_tree_stat_decr(rt, rs_before);
+
+		rs_before->rs_end = end;
+		rs = rs_before;
+	} else if (merge_after) {
+		if (rt->rt_ops != NULL)
+			rt->rt_ops->rtop_remove(rt, rs_after, rt->rt_arg);
+
+		range_tree_stat_decr(rt, rs_after);
+
+		rs_after->rs_start = start;
+		rs = rs_after;
+	} else {
+		rs = kmem_cache_alloc(range_seg_cache, KM_SLEEP);
+		rs->rs_start = start;
+		rs->rs_end = end;
+		avl_insert(&rt->rt_root, rs, where);
+	}
+
+	if (rt->rt_ops != NULL)
+		rt->rt_ops->rtop_add(rt, rs, rt->rt_arg);
+
+	range_tree_stat_incr(rt, rs);
+	rt->rt_space += size;
+}
+
+void
+range_tree_remove(void *arg, uint64_t start, uint64_t size)
+{
+	range_tree_t *rt = arg;
+	avl_index_t where;
+	range_seg_t rsearch, *rs, *newseg;
+	uint64_t end = start + size;
+	boolean_t left_over, right_over;
+
+	ASSERT(MUTEX_HELD(rt->rt_lock));
+	VERIFY3U(size, !=, 0);
+	VERIFY3U(size, <=, rt->rt_space);
+
+	rsearch.rs_start = start;
+	rsearch.rs_end = end;
+	rs = avl_find(&rt->rt_root, &rsearch, &where);
+
+	/* Make sure we completely overlap with someone */
+	if (rs == NULL) {
+		zfs_panic_recover("zfs: freeing free segment "
+		    "(offset=%llu size=%llu)",
+		    (longlong_t)start, (longlong_t)size);
+		return;
+	}
+	VERIFY3U(rs->rs_start, <=, start);
+	VERIFY3U(rs->rs_end, >=, end);
+
+	left_over = (rs->rs_start != start);
+	right_over = (rs->rs_end != end);
+
+	range_tree_stat_decr(rt, rs);
+
+	if (rt->rt_ops != NULL)
+		rt->rt_ops->rtop_remove(rt, rs, rt->rt_arg);
+
+	if (left_over && right_over) {
+		newseg = kmem_cache_alloc(range_seg_cache, KM_SLEEP);
+		newseg->rs_start = end;
+		newseg->rs_end = rs->rs_end;
+		range_tree_stat_incr(rt, newseg);
+
+		rs->rs_end = start;
+
+		avl_insert_here(&rt->rt_root, newseg, rs, AVL_AFTER);
+		if (rt->rt_ops != NULL)
+			rt->rt_ops->rtop_add(rt, newseg, rt->rt_arg);
+	} else if (left_over) {
+		rs->rs_end = start;
+	} else if (right_over) {
+		rs->rs_start = end;
+	} else {
+		avl_remove(&rt->rt_root, rs);
+		kmem_cache_free(range_seg_cache, rs);
+		rs = NULL;
+	}
+
+	if (rs != NULL) {
+		range_tree_stat_incr(rt, rs);
+
+		if (rt->rt_ops != NULL)
+			rt->rt_ops->rtop_add(rt, rs, rt->rt_arg);
+	}
+
+	rt->rt_space -= size;
+}
+
+static range_seg_t *
+range_tree_find_impl(range_tree_t *rt, uint64_t start, uint64_t size)
+{
+	avl_index_t where;
+	range_seg_t rsearch;
+	uint64_t end = start + size;
+
+	ASSERT(MUTEX_HELD(rt->rt_lock));
+	VERIFY(size != 0);
+
+	rsearch.rs_start = start;
+	rsearch.rs_end = end;
+	return (avl_find(&rt->rt_root, &rsearch, &where));
+}
+
+static range_seg_t *
+range_tree_find(range_tree_t *rt, uint64_t start, uint64_t size)
+{
+	range_seg_t *rs = range_tree_find_impl(rt, start, size);
+	if (rs != NULL && rs->rs_start <= start && rs->rs_end >= start + size)
+		return (rs);
+	return (NULL);
+}
+
+void
+range_tree_verify(range_tree_t *rt, uint64_t off, uint64_t size)
+{
+	range_seg_t *rs;
+
+	mutex_enter(rt->rt_lock);
+	rs = range_tree_find(rt, off, size);
+	if (rs != NULL)
+		panic("freeing free block; rs=%p", (void *)rs);
+	mutex_exit(rt->rt_lock);
+}
+
+boolean_t
+range_tree_contains(range_tree_t *rt, uint64_t start, uint64_t size)
+{
+	return (range_tree_find(rt, start, size) != NULL);
+}
+
+/*
+ * Ensure that this range is not in the tree, regardless of whether
+ * it is currently in the tree.
+ */
+void
+range_tree_clear(range_tree_t *rt, uint64_t start, uint64_t size)
+{
+	range_seg_t *rs;
+
+	while ((rs = range_tree_find_impl(rt, start, size)) != NULL) {
+		uint64_t free_start = MAX(rs->rs_start, start);
+		uint64_t free_end = MIN(rs->rs_end, start + size);
+		range_tree_remove(rt, free_start, free_end - free_start);
+	}
+}
+
+void
+range_tree_swap(range_tree_t **rtsrc, range_tree_t **rtdst)
+{
+	range_tree_t *rt;
+
+	ASSERT(MUTEX_HELD((*rtsrc)->rt_lock));
+	ASSERT0(range_tree_space(*rtdst));
+	ASSERT0(avl_numnodes(&(*rtdst)->rt_root));
+
+	rt = *rtsrc;
+	*rtsrc = *rtdst;
+	*rtdst = rt;
+}
+
+void
+range_tree_vacate(range_tree_t *rt, range_tree_func_t *func, void *arg)
+{
+	range_seg_t *rs;
+	void *cookie = NULL;
+
+	ASSERT(MUTEX_HELD(rt->rt_lock));
+
+	if (rt->rt_ops != NULL)
+		rt->rt_ops->rtop_vacate(rt, rt->rt_arg);
+
+	while ((rs = avl_destroy_nodes(&rt->rt_root, &cookie)) != NULL) {
+		if (func != NULL)
+			func(arg, rs->rs_start, rs->rs_end - rs->rs_start);
+		kmem_cache_free(range_seg_cache, rs);
+	}
+
+	bzero(rt->rt_histogram, sizeof (rt->rt_histogram));
+	rt->rt_space = 0;
+}
+
+void
+range_tree_walk(range_tree_t *rt, range_tree_func_t *func, void *arg)
+{
+	range_seg_t *rs;
+
+	ASSERT(MUTEX_HELD(rt->rt_lock));
+
+	for (rs = avl_first(&rt->rt_root); rs; rs = AVL_NEXT(&rt->rt_root, rs))
+		func(arg, rs->rs_start, rs->rs_end - rs->rs_start);
+}
+
+uint64_t
+range_tree_space(range_tree_t *rt)
+{
+	return (rt->rt_space);
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/module/zfs/refcount.c
@@ -0,0 +1,230 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012 by Delphix. All rights reserved.
+ */
+
+#include <sys/zfs_context.h>
+#include <sys/refcount.h>
+
+#ifdef	ZFS_DEBUG
+
+#ifdef _KERNEL
+int reference_tracking_enable = FALSE; /* runs out of memory too easily */
+#else
+int reference_tracking_enable = TRUE;
+#endif
+int reference_history = 3; /* tunable */
+
+static kmem_cache_t *reference_cache;
+static kmem_cache_t *reference_history_cache;
+
+void
+refcount_init(void)
+{
+	reference_cache = kmem_cache_create("reference_cache",
+	    sizeof (reference_t), 0, NULL, NULL, NULL, NULL, NULL, 0);
+
+	reference_history_cache = kmem_cache_create("reference_history_cache",
+	    sizeof (uint64_t), 0, NULL, NULL, NULL, NULL, NULL, 0);
+}
+
+void
+refcount_fini(void)
+{
+	kmem_cache_destroy(reference_cache);
+	kmem_cache_destroy(reference_history_cache);
+}
+
+void
+refcount_create(refcount_t *rc)
+{
+	mutex_init(&rc->rc_mtx, NULL, MUTEX_DEFAULT, NULL);
+	list_create(&rc->rc_list, sizeof (reference_t),
+	    offsetof(reference_t, ref_link));
+	list_create(&rc->rc_removed, sizeof (reference_t),
+	    offsetof(reference_t, ref_link));
+	rc->rc_count = 0;
+	rc->rc_removed_count = 0;
+	rc->rc_tracked = reference_tracking_enable;
+}
+
+void
+refcount_create_untracked(refcount_t *rc)
+{
+	refcount_create(rc);
+	rc->rc_tracked = B_FALSE;
+}
+
+void
+refcount_destroy_many(refcount_t *rc, uint64_t number)
+{
+	reference_t *ref;
+
+	ASSERT(rc->rc_count == number);
+	while ((ref = list_head(&rc->rc_list))) {
+		list_remove(&rc->rc_list, ref);
+		kmem_cache_free(reference_cache, ref);
+	}
+	list_destroy(&rc->rc_list);
+
+	while ((ref = list_head(&rc->rc_removed))) {
+		list_remove(&rc->rc_removed, ref);
+		kmem_cache_free(reference_history_cache, ref->ref_removed);
+		kmem_cache_free(reference_cache, ref);
+	}
+	list_destroy(&rc->rc_removed);
+	mutex_destroy(&rc->rc_mtx);
+}
+
+void
+refcount_destroy(refcount_t *rc)
+{
+	refcount_destroy_many(rc, 0);
+}
+
+int
+refcount_is_zero(refcount_t *rc)
+{
+	return (rc->rc_count == 0);
+}
+
+int64_t
+refcount_count(refcount_t *rc)
+{
+	return (rc->rc_count);
+}
+
+int64_t
+refcount_add_many(refcount_t *rc, uint64_t number, void *holder)
+{
+	reference_t *ref = NULL;
+	int64_t count;
+
+	if (rc->rc_tracked) {
+		ref = kmem_cache_alloc(reference_cache, KM_SLEEP);
+		ref->ref_holder = holder;
+		ref->ref_number = number;
+	}
+	mutex_enter(&rc->rc_mtx);
+	ASSERT(rc->rc_count >= 0);
+	if (rc->rc_tracked)
+		list_insert_head(&rc->rc_list, ref);
+	rc->rc_count += number;
+	count = rc->rc_count;
+	mutex_exit(&rc->rc_mtx);
+
+	return (count);
+}
+
+int64_t
+refcount_add(refcount_t *rc, void *holder)
+{
+	return (refcount_add_many(rc, 1, holder));
+}
+
+int64_t
+refcount_remove_many(refcount_t *rc, uint64_t number, void *holder)
+{
+	reference_t *ref;
+	int64_t count;
+
+	mutex_enter(&rc->rc_mtx);
+	ASSERT(rc->rc_count >= number);
+
+	if (!rc->rc_tracked) {
+		rc->rc_count -= number;
+		count = rc->rc_count;
+		mutex_exit(&rc->rc_mtx);
+		return (count);
+	}
+
+	for (ref = list_head(&rc->rc_list); ref;
+	    ref = list_next(&rc->rc_list, ref)) {
+		if (ref->ref_holder == holder && ref->ref_number == number) {
+			list_remove(&rc->rc_list, ref);
+			if (reference_history > 0) {
+				ref->ref_removed =
+				    kmem_cache_alloc(reference_history_cache,
+				    KM_SLEEP);
+				list_insert_head(&rc->rc_removed, ref);
+				rc->rc_removed_count++;
+				if (rc->rc_removed_count > reference_history) {
+					ref = list_tail(&rc->rc_removed);
+					list_remove(&rc->rc_removed, ref);
+					kmem_cache_free(reference_history_cache,
+					    ref->ref_removed);
+					kmem_cache_free(reference_cache, ref);
+					rc->rc_removed_count--;
+				}
+			} else {
+				kmem_cache_free(reference_cache, ref);
+			}
+			rc->rc_count -= number;
+			count = rc->rc_count;
+			mutex_exit(&rc->rc_mtx);
+			return (count);
+		}
+	}
+	panic("No such hold %p on refcount %llx", holder,
+	    (u_longlong_t)(uintptr_t)rc);
+	return (-1);
+}
+
+int64_t
+refcount_remove(refcount_t *rc, void *holder)
+{
+	return (refcount_remove_many(rc, 1, holder));
+}
+
+void
+refcount_transfer(refcount_t *dst, refcount_t *src)
+{
+	int64_t count, removed_count;
+	list_t list, removed;
+
+	list_create(&list, sizeof (reference_t),
+	    offsetof(reference_t, ref_link));
+	list_create(&removed, sizeof (reference_t),
+	    offsetof(reference_t, ref_link));
+
+	mutex_enter(&src->rc_mtx);
+	count = src->rc_count;
+	removed_count = src->rc_removed_count;
+	src->rc_count = 0;
+	src->rc_removed_count = 0;
+	list_move_tail(&list, &src->rc_list);
+	list_move_tail(&removed, &src->rc_removed);
+	mutex_exit(&src->rc_mtx);
+
+	mutex_enter(&dst->rc_mtx);
+	dst->rc_count += count;
+	dst->rc_removed_count += removed_count;
+	list_move_tail(&dst->rc_list, &list);
+	list_move_tail(&dst->rc_removed, &removed);
+	mutex_exit(&dst->rc_mtx);
+
+	list_destroy(&list);
+	list_destroy(&removed);
+}
+
+#endif	/* ZFS_DEBUG */
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/module/zfs/rrwlock.c
@@ -0,0 +1,395 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * Copyright (c) 2012 by Delphix. All rights reserved.
+ */
+
+#include <sys/refcount.h>
+#include <sys/rrwlock.h>
+
+/*
+ * This file contains the implementation of a re-entrant read
+ * reader/writer lock (aka "rrwlock").
+ *
+ * This is a normal reader/writer lock with the additional feature
+ * of allowing threads who have already obtained a read lock to
+ * re-enter another read lock (re-entrant read) - even if there are
+ * waiting writers.
+ *
+ * Callers who have not obtained a read lock give waiting writers priority.
+ *
+ * The rrwlock_t lock does not allow re-entrant writers, nor does it
+ * allow a re-entrant mix of reads and writes (that is, it does not
+ * allow a caller who has already obtained a read lock to be able to
+ * then grab a write lock without first dropping all read locks, and
+ * vice versa).
+ *
+ * The rrwlock_t uses tsd (thread specific data) to keep a list of
+ * nodes (rrw_node_t), where each node keeps track of which specific
+ * lock (rrw_node_t::rn_rrl) the thread has grabbed.  Since re-entering
+ * should be rare, a thread that grabs multiple reads on the same rrwlock_t
+ * will store multiple rrw_node_ts of the same 'rrn_rrl'. Nodes on the
+ * tsd list can represent a different rrwlock_t.  This allows a thread
+ * to enter multiple and unique rrwlock_ts for read locks at the same time.
+ *
+ * Since using tsd exposes some overhead, the rrwlock_t only needs to
+ * keep tsd data when writers are waiting.  If no writers are waiting, then
+ * a reader just bumps the anonymous read count (rr_anon_rcount) - no tsd
+ * is needed.  Once a writer attempts to grab the lock, readers then
+ * keep tsd data and bump the linked readers count (rr_linked_rcount).
+ *
+ * If there are waiting writers and there are anonymous readers, then a
+ * reader doesn't know if it is a re-entrant lock. But since it may be one,
+ * we allow the read to proceed (otherwise it could deadlock).  Since once
+ * waiting writers are active, readers no longer bump the anonymous count,
+ * the anonymous readers will eventually flush themselves out.  At this point,
+ * readers will be able to tell if they are a re-entrant lock (have a
+ * rrw_node_t entry for the lock) or not. If they are a re-entrant lock, then
+ * we must let the proceed.  If they are not, then the reader blocks for the
+ * waiting writers.  Hence, we do not starve writers.
+ */
+
+/* global key for TSD */
+uint_t rrw_tsd_key;
+
+typedef struct rrw_node {
+	struct rrw_node *rn_next;
+	rrwlock_t *rn_rrl;
+	void *rn_tag;
+} rrw_node_t;
+
+static rrw_node_t *
+rrn_find(rrwlock_t *rrl)
+{
+	rrw_node_t *rn;
+
+	if (refcount_count(&rrl->rr_linked_rcount) == 0)
+		return (NULL);
+
+	for (rn = tsd_get(rrw_tsd_key); rn != NULL; rn = rn->rn_next) {
+		if (rn->rn_rrl == rrl)
+			return (rn);
+	}
+	return (NULL);
+}
+
+/*
+ * Add a node to the head of the singly linked list.
+ */
+static void
+rrn_add(rrwlock_t *rrl, void *tag)
+{
+	rrw_node_t *rn;
+
+	rn = kmem_alloc(sizeof (*rn), KM_SLEEP);
+	rn->rn_rrl = rrl;
+	rn->rn_next = tsd_get(rrw_tsd_key);
+	rn->rn_tag = tag;
+	VERIFY(tsd_set(rrw_tsd_key, rn) == 0);
+}
+
+/*
+ * If a node is found for 'rrl', then remove the node from this
+ * thread's list and return TRUE; otherwise return FALSE.
+ */
+static boolean_t
+rrn_find_and_remove(rrwlock_t *rrl, void *tag)
+{
+	rrw_node_t *rn;
+	rrw_node_t *prev = NULL;
+
+	if (refcount_count(&rrl->rr_linked_rcount) == 0)
+		return (B_FALSE);
+
+	for (rn = tsd_get(rrw_tsd_key); rn != NULL; rn = rn->rn_next) {
+		if (rn->rn_rrl == rrl && rn->rn_tag == tag) {
+			if (prev)
+				prev->rn_next = rn->rn_next;
+			else
+				VERIFY(tsd_set(rrw_tsd_key, rn->rn_next) == 0);
+			kmem_free(rn, sizeof (*rn));
+			return (B_TRUE);
+		}
+		prev = rn;
+	}
+	return (B_FALSE);
+}
+
+void
+rrw_init(rrwlock_t *rrl, boolean_t track_all)
+{
+	mutex_init(&rrl->rr_lock, NULL, MUTEX_DEFAULT, NULL);
+	cv_init(&rrl->rr_cv, NULL, CV_DEFAULT, NULL);
+	rrl->rr_writer = NULL;
+	refcount_create(&rrl->rr_anon_rcount);
+	refcount_create(&rrl->rr_linked_rcount);
+	rrl->rr_writer_wanted = B_FALSE;
+	rrl->rr_track_all = track_all;
+}
+
+void
+rrw_destroy(rrwlock_t *rrl)
+{
+	mutex_destroy(&rrl->rr_lock);
+	cv_destroy(&rrl->rr_cv);
+	ASSERT(rrl->rr_writer == NULL);
+	refcount_destroy(&rrl->rr_anon_rcount);
+	refcount_destroy(&rrl->rr_linked_rcount);
+}
+
+static void
+rrw_enter_read_impl(rrwlock_t *rrl, boolean_t prio, void *tag)
+{
+	mutex_enter(&rrl->rr_lock);
+#if !defined(DEBUG) && defined(_KERNEL)
+	if (rrl->rr_writer == NULL && !rrl->rr_writer_wanted &&
+	    !rrl->rr_track_all) {
+		rrl->rr_anon_rcount.rc_count++;
+		mutex_exit(&rrl->rr_lock);
+		return;
+	}
+	DTRACE_PROBE(zfs__rrwfastpath__rdmiss);
+#endif
+	ASSERT(rrl->rr_writer != curthread);
+	ASSERT(refcount_count(&rrl->rr_anon_rcount) >= 0);
+
+	while (rrl->rr_writer != NULL || (rrl->rr_writer_wanted &&
+	    refcount_is_zero(&rrl->rr_anon_rcount) && !prio &&
+	    rrn_find(rrl) == NULL))
+		cv_wait(&rrl->rr_cv, &rrl->rr_lock);
+
+	if (rrl->rr_writer_wanted || rrl->rr_track_all) {
+		/* may or may not be a re-entrant enter */
+		rrn_add(rrl, tag);
+		(void) refcount_add(&rrl->rr_linked_rcount, tag);
+	} else {
+		(void) refcount_add(&rrl->rr_anon_rcount, tag);
+	}
+	ASSERT(rrl->rr_writer == NULL);
+	mutex_exit(&rrl->rr_lock);
+}
+
+void
+rrw_enter_read(rrwlock_t *rrl, void *tag)
+{
+	rrw_enter_read_impl(rrl, B_FALSE, tag);
+}
+
+/*
+ * take a read lock even if there are pending write lock requests. if we want
+ * to take a lock reentrantly, but from different threads (that have a
+ * relationship to each other), the normal detection mechanism to overrule
+ * the pending writer does not work, so we have to give an explicit hint here.
+ */
+void
+rrw_enter_read_prio(rrwlock_t *rrl, void *tag)
+{
+	rrw_enter_read_impl(rrl, B_TRUE, tag);
+}
+
+
+void
+rrw_enter_write(rrwlock_t *rrl)
+{
+	mutex_enter(&rrl->rr_lock);
+	ASSERT(rrl->rr_writer != curthread);
+
+	while (refcount_count(&rrl->rr_anon_rcount) > 0 ||
+	    refcount_count(&rrl->rr_linked_rcount) > 0 ||
+	    rrl->rr_writer != NULL) {
+		rrl->rr_writer_wanted = B_TRUE;
+		cv_wait(&rrl->rr_cv, &rrl->rr_lock);
+	}
+	rrl->rr_writer_wanted = B_FALSE;
+	rrl->rr_writer = curthread;
+	mutex_exit(&rrl->rr_lock);
+}
+
+void
+rrw_enter(rrwlock_t *rrl, krw_t rw, void *tag)
+{
+	if (rw == RW_READER)
+		rrw_enter_read(rrl, tag);
+	else
+		rrw_enter_write(rrl);
+}
+
+void
+rrw_exit(rrwlock_t *rrl, void *tag)
+{
+	mutex_enter(&rrl->rr_lock);
+#if !defined(DEBUG) && defined(_KERNEL)
+	if (!rrl->rr_writer && rrl->rr_linked_rcount.rc_count == 0) {
+		rrl->rr_anon_rcount.rc_count--;
+		if (rrl->rr_anon_rcount.rc_count == 0)
+			cv_broadcast(&rrl->rr_cv);
+		mutex_exit(&rrl->rr_lock);
+		return;
+	}
+	DTRACE_PROBE(zfs__rrwfastpath__exitmiss);
+#endif
+	ASSERT(!refcount_is_zero(&rrl->rr_anon_rcount) ||
+	    !refcount_is_zero(&rrl->rr_linked_rcount) ||
+	    rrl->rr_writer != NULL);
+
+	if (rrl->rr_writer == NULL) {
+		int64_t count;
+		if (rrn_find_and_remove(rrl, tag)) {
+			count = refcount_remove(&rrl->rr_linked_rcount, tag);
+		} else {
+			ASSERT(!rrl->rr_track_all);
+			count = refcount_remove(&rrl->rr_anon_rcount, tag);
+		}
+		if (count == 0)
+			cv_broadcast(&rrl->rr_cv);
+	} else {
+		ASSERT(rrl->rr_writer == curthread);
+		ASSERT(refcount_is_zero(&rrl->rr_anon_rcount) &&
+		    refcount_is_zero(&rrl->rr_linked_rcount));
+		rrl->rr_writer = NULL;
+		cv_broadcast(&rrl->rr_cv);
+	}
+	mutex_exit(&rrl->rr_lock);
+}
+
+/*
+ * If the lock was created with track_all, rrw_held(RW_READER) will return
+ * B_TRUE iff the current thread has the lock for reader.  Otherwise it may
+ * return B_TRUE if any thread has the lock for reader.
+ */
+boolean_t
+rrw_held(rrwlock_t *rrl, krw_t rw)
+{
+	boolean_t held;
+
+	mutex_enter(&rrl->rr_lock);
+	if (rw == RW_WRITER) {
+		held = (rrl->rr_writer == curthread);
+	} else {
+		held = (!refcount_is_zero(&rrl->rr_anon_rcount) ||
+		    rrn_find(rrl) != NULL);
+	}
+	mutex_exit(&rrl->rr_lock);
+
+	return (held);
+}
+
+void
+rrw_tsd_destroy(void *arg)
+{
+	rrw_node_t *rn = arg;
+	if (rn != NULL) {
+		panic("thread %p terminating with rrw lock %p held",
+		    (void *)curthread, (void *)rn->rn_rrl);
+	}
+}
+
+/*
+ * A reader-mostly lock implementation, tuning above reader-writer locks
+ * for hightly parallel read acquisitions, while pessimizing writes.
+ *
+ * The idea is to split single busy lock into array of locks, so that
+ * each reader can lock only one of them for read, depending on result
+ * of simple hash function.  That proportionally reduces lock congestion.
+ * Writer same time has to sequentially aquire write on all the locks.
+ * That makes write aquisition proportionally slower, but in places where
+ * it is used (filesystem unmount) performance is not critical.
+ *
+ * All the functions below are direct wrappers around functions above.
+ */
+void
+rrm_init(rrmlock_t *rrl, boolean_t track_all)
+{
+	int i;
+
+	for (i = 0; i < RRM_NUM_LOCKS; i++)
+		rrw_init(&rrl->locks[i], track_all);
+}
+
+void
+rrm_destroy(rrmlock_t *rrl)
+{
+	int i;
+
+	for (i = 0; i < RRM_NUM_LOCKS; i++)
+		rrw_destroy(&rrl->locks[i]);
+}
+
+void
+rrm_enter(rrmlock_t *rrl, krw_t rw, void *tag)
+{
+	if (rw == RW_READER)
+		rrm_enter_read(rrl, tag);
+	else
+		rrm_enter_write(rrl);
+}
+
+/*
+ * This maps the current thread to a specific lock.  Note that the lock
+ * must be released by the same thread that acquired it.  We do this
+ * mapping by taking the thread pointer mod a prime number.  We examine
+ * only the low 32 bits of the thread pointer, because 32-bit division
+ * is faster than 64-bit division, and the high 32 bits have little
+ * entropy anyway.
+ */
+#define	RRM_TD_LOCK()	(((uint32_t)(uintptr_t)(curthread)) % RRM_NUM_LOCKS)
+
+void
+rrm_enter_read(rrmlock_t *rrl, void *tag)
+{
+	rrw_enter_read(&rrl->locks[RRM_TD_LOCK()], tag);
+}
+
+void
+rrm_enter_write(rrmlock_t *rrl)
+{
+	int i;
+
+	for (i = 0; i < RRM_NUM_LOCKS; i++)
+		rrw_enter_write(&rrl->locks[i]);
+}
+
+void
+rrm_exit(rrmlock_t *rrl, void *tag)
+{
+	int i;
+
+	if (rrl->locks[0].rr_writer == curthread) {
+		for (i = 0; i < RRM_NUM_LOCKS; i++)
+			rrw_exit(&rrl->locks[i], tag);
+	} else {
+		rrw_exit(&rrl->locks[RRM_TD_LOCK()], tag);
+	}
+}
+
+boolean_t
+rrm_held(rrmlock_t *rrl, krw_t rw)
+{
+	if (rw == RW_WRITER) {
+		return (rrw_held(&rrl->locks[0], rw));
+	} else {
+		return (rrw_held(&rrl->locks[RRM_TD_LOCK()], rw));
+	}
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/module/zfs/sa.c
@@ -0,0 +1,2071 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013 by Delphix. All rights reserved.
+ * Copyright (c) 2014 Spectra Logic Corporation, All rights reserved.
+ */
+
+#include <sys/zfs_context.h>
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/sysmacros.h>
+#include <sys/dmu.h>
+#include <sys/dmu_impl.h>
+#include <sys/dmu_objset.h>
+#include <sys/dbuf.h>
+#include <sys/dnode.h>
+#include <sys/zap.h>
+#include <sys/sa.h>
+#include <sys/sunddi.h>
+#include <sys/sa_impl.h>
+#include <sys/dnode.h>
+#include <sys/errno.h>
+#include <sys/zfs_context.h>
+
+/*
+ * ZFS System attributes:
+ *
+ * A generic mechanism to allow for arbitrary attributes
+ * to be stored in a dnode.  The data will be stored in the bonus buffer of
+ * the dnode and if necessary a special "spill" block will be used to handle
+ * overflow situations.  The spill block will be sized to fit the data
+ * from 512 - 128K.  When a spill block is used the BP (blkptr_t) for the
+ * spill block is stored at the end of the current bonus buffer.  Any
+ * attributes that would be in the way of the blkptr_t will be relocated
+ * into the spill block.
+ *
+ * Attribute registration:
+ *
+ * Stored persistently on a per dataset basis
+ * a mapping between attribute "string" names and their actual attribute
+ * numeric values, length, and byteswap function.  The names are only used
+ * during registration.  All  attributes are known by their unique attribute
+ * id value.  If an attribute can have a variable size then the value
+ * 0 will be used to indicate this.
+ *
+ * Attribute Layout:
+ *
+ * Attribute layouts are a way to compactly store multiple attributes, but
+ * without taking the overhead associated with managing each attribute
+ * individually.  Since you will typically have the same set of attributes
+ * stored in the same order a single table will be used to represent that
+ * layout.  The ZPL for example will usually have only about 10 different
+ * layouts (regular files, device files, symlinks,
+ * regular files + scanstamp, files/dir with extended attributes, and then
+ * you have the possibility of all of those minus ACL, because it would
+ * be kicked out into the spill block)
+ *
+ * Layouts are simply an array of the attributes and their
+ * ordering i.e. [0, 1, 4, 5, 2]
+ *
+ * Each distinct layout is given a unique layout number and that is whats
+ * stored in the header at the beginning of the SA data buffer.
+ *
+ * A layout only covers a single dbuf (bonus or spill).  If a set of
+ * attributes is split up between the bonus buffer and a spill buffer then
+ * two different layouts will be used.  This allows us to byteswap the
+ * spill without looking at the bonus buffer and keeps the on disk format of
+ * the bonus and spill buffer the same.
+ *
+ * Adding a single attribute will cause the entire set of attributes to
+ * be rewritten and could result in a new layout number being constructed
+ * as part of the rewrite if no such layout exists for the new set of
+ * attribues.  The new attribute will be appended to the end of the already
+ * existing attributes.
+ *
+ * Both the attribute registration and attribute layout information are
+ * stored in normal ZAP attributes.  Their should be a small number of
+ * known layouts and the set of attributes is assumed to typically be quite
+ * small.
+ *
+ * The registered attributes and layout "table" information is maintained
+ * in core and a special "sa_os_t" is attached to the objset_t.
+ *
+ * A special interface is provided to allow for quickly applying
+ * a large set of attributes at once.  sa_replace_all_by_template() is
+ * used to set an array of attributes.  This is used by the ZPL when
+ * creating a brand new file.  The template that is passed into the function
+ * specifies the attribute, size for variable length attributes, location of
+ * data and special "data locator" function if the data isn't in a contiguous
+ * location.
+ *
+ * Byteswap implications:
+ *
+ * Since the SA attributes are not entirely self describing we can't do
+ * the normal byteswap processing.  The special ZAP layout attribute and
+ * attribute registration attributes define the byteswap function and the
+ * size of the attributes, unless it is variable sized.
+ * The normal ZFS byteswapping infrastructure assumes you don't need
+ * to read any objects in order to do the necessary byteswapping.  Whereas
+ * SA attributes can only be properly byteswapped if the dataset is opened
+ * and the layout/attribute ZAP attributes are available.  Because of this
+ * the SA attributes will be byteswapped when they are first accessed by
+ * the SA code that will read the SA data.
+ */
+
+typedef void (sa_iterfunc_t)(void *hdr, void *addr, sa_attr_type_t,
+    uint16_t length, int length_idx, boolean_t, void *userp);
+
+static int sa_build_index(sa_handle_t *hdl, sa_buf_type_t buftype);
+static void sa_idx_tab_hold(objset_t *os, sa_idx_tab_t *idx_tab);
+static void *sa_find_idx_tab(objset_t *os, dmu_object_type_t bonustype,
+    void *data);
+static void sa_idx_tab_rele(objset_t *os, void *arg);
+static void sa_copy_data(sa_data_locator_t *func, void *start, void *target,
+    int buflen);
+static int sa_modify_attrs(sa_handle_t *hdl, sa_attr_type_t newattr,
+    sa_data_op_t action, sa_data_locator_t *locator, void *datastart,
+    uint16_t buflen, dmu_tx_t *tx);
+
+arc_byteswap_func_t sa_bswap_table[] = {
+	byteswap_uint64_array,
+	byteswap_uint32_array,
+	byteswap_uint16_array,
+	byteswap_uint8_array,
+	zfs_acl_byteswap,
+};
+
+#define	SA_COPY_DATA(f, s, t, l) \
+	{ \
+		if (f == NULL) { \
+			if (l == 8) { \
+				*(uint64_t *)t = *(uint64_t *)s; \
+			} else if (l == 16) { \
+				*(uint64_t *)t = *(uint64_t *)s; \
+				*(uint64_t *)((uintptr_t)t + 8) = \
+				    *(uint64_t *)((uintptr_t)s + 8); \
+			} else { \
+				bcopy(s, t, l); \
+			} \
+		} else \
+			sa_copy_data(f, s, t, l); \
+	}
+
+/*
+ * This table is fixed and cannot be changed.  Its purpose is to
+ * allow the SA code to work with both old/new ZPL file systems.
+ * It contains the list of legacy attributes.  These attributes aren't
+ * stored in the "attribute" registry zap objects, since older ZPL file systems
+ * won't have the registry.  Only objsets of type ZFS_TYPE_FILESYSTEM will
+ * use this static table.
+ */
+sa_attr_reg_t sa_legacy_attrs[] = {
+	{"ZPL_ATIME", sizeof (uint64_t) * 2, SA_UINT64_ARRAY, 0},
+	{"ZPL_MTIME", sizeof (uint64_t) * 2, SA_UINT64_ARRAY, 1},
+	{"ZPL_CTIME", sizeof (uint64_t) * 2, SA_UINT64_ARRAY, 2},
+	{"ZPL_CRTIME", sizeof (uint64_t) * 2, SA_UINT64_ARRAY, 3},
+	{"ZPL_GEN", sizeof (uint64_t), SA_UINT64_ARRAY, 4},
+	{"ZPL_MODE", sizeof (uint64_t), SA_UINT64_ARRAY, 5},
+	{"ZPL_SIZE", sizeof (uint64_t), SA_UINT64_ARRAY, 6},
+	{"ZPL_PARENT", sizeof (uint64_t), SA_UINT64_ARRAY, 7},
+	{"ZPL_LINKS", sizeof (uint64_t), SA_UINT64_ARRAY, 8},
+	{"ZPL_XATTR", sizeof (uint64_t), SA_UINT64_ARRAY, 9},
+	{"ZPL_RDEV", sizeof (uint64_t), SA_UINT64_ARRAY, 10},
+	{"ZPL_FLAGS", sizeof (uint64_t), SA_UINT64_ARRAY, 11},
+	{"ZPL_UID", sizeof (uint64_t), SA_UINT64_ARRAY, 12},
+	{"ZPL_GID", sizeof (uint64_t), SA_UINT64_ARRAY, 13},
+	{"ZPL_PAD", sizeof (uint64_t) * 4, SA_UINT64_ARRAY, 14},
+	{"ZPL_ZNODE_ACL", 88, SA_UINT8_ARRAY, 15},
+};
+
+/*
+ * This is only used for objects of type DMU_OT_ZNODE
+ */
+sa_attr_type_t sa_legacy_zpl_layout[] = {
+    0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
+};
+
+/*
+ * Special dummy layout used for buffers with no attributes.
+ */
+sa_attr_type_t sa_dummy_zpl_layout[] = { 0 };
+
+static int sa_legacy_attr_count = 16;
+static kmem_cache_t *sa_cache = NULL;
+
+/*ARGSUSED*/
+static int
+sa_cache_constructor(void *buf, void *unused, int kmflag)
+{
+	sa_handle_t *hdl = buf;
+
+	mutex_init(&hdl->sa_lock, NULL, MUTEX_DEFAULT, NULL);
+	return (0);
+}
+
+/*ARGSUSED*/
+static void
+sa_cache_destructor(void *buf, void *unused)
+{
+	sa_handle_t *hdl = buf;
+	mutex_destroy(&hdl->sa_lock);
+}
+
+void
+sa_cache_init(void)
+{
+	sa_cache = kmem_cache_create("sa_cache",
+	    sizeof (sa_handle_t), 0, sa_cache_constructor,
+	    sa_cache_destructor, NULL, NULL, NULL, 0);
+}
+
+void
+sa_cache_fini(void)
+{
+	if (sa_cache)
+		kmem_cache_destroy(sa_cache);
+}
+
+static int
+layout_num_compare(const void *arg1, const void *arg2)
+{
+	const sa_lot_t *node1 = arg1;
+	const sa_lot_t *node2 = arg2;
+
+	if (node1->lot_num > node2->lot_num)
+		return (1);
+	else if (node1->lot_num < node2->lot_num)
+		return (-1);
+	return (0);
+}
+
+static int
+layout_hash_compare(const void *arg1, const void *arg2)
+{
+	const sa_lot_t *node1 = arg1;
+	const sa_lot_t *node2 = arg2;
+
+	if (node1->lot_hash > node2->lot_hash)
+		return (1);
+	if (node1->lot_hash < node2->lot_hash)
+		return (-1);
+	if (node1->lot_instance > node2->lot_instance)
+		return (1);
+	if (node1->lot_instance < node2->lot_instance)
+		return (-1);
+	return (0);
+}
+
+boolean_t
+sa_layout_equal(sa_lot_t *tbf, sa_attr_type_t *attrs, int count)
+{
+	int i;
+
+	if (count != tbf->lot_attr_count)
+		return (1);
+
+	for (i = 0; i != count; i++) {
+		if (attrs[i] != tbf->lot_attrs[i])
+			return (1);
+	}
+	return (0);
+}
+
+#define	SA_ATTR_HASH(attr) (zfs_crc64_table[(-1ULL ^ attr) & 0xFF])
+
+static uint64_t
+sa_layout_info_hash(sa_attr_type_t *attrs, int attr_count)
+{
+	int i;
+	uint64_t crc = -1ULL;
+
+	for (i = 0; i != attr_count; i++)
+		crc ^= SA_ATTR_HASH(attrs[i]);
+
+	return (crc);
+}
+
+static int
+sa_get_spill(sa_handle_t *hdl)
+{
+	int rc;
+	if (hdl->sa_spill == NULL) {
+		if ((rc = dmu_spill_hold_existing(hdl->sa_bonus, NULL,
+		    &hdl->sa_spill)) == 0)
+			VERIFY(0 == sa_build_index(hdl, SA_SPILL));
+	} else {
+		rc = 0;
+	}
+
+	return (rc);
+}
+
+/*
+ * Main attribute lookup/update function
+ * returns 0 for success or non zero for failures
+ *
+ * Operates on bulk array, first failure will abort further processing
+ */
+int
+sa_attr_op(sa_handle_t *hdl, sa_bulk_attr_t *bulk, int count,
+    sa_data_op_t data_op, dmu_tx_t *tx)
+{
+	sa_os_t *sa = hdl->sa_os->os_sa;
+	int i;
+	int error = 0;
+	sa_buf_type_t buftypes;
+
+	buftypes = 0;
+
+	ASSERT(count > 0);
+	for (i = 0; i != count; i++) {
+		ASSERT(bulk[i].sa_attr <= hdl->sa_os->os_sa->sa_num_attrs);
+
+		bulk[i].sa_addr = NULL;
+		/* First check the bonus buffer */
+
+		if (hdl->sa_bonus_tab && TOC_ATTR_PRESENT(
+		    hdl->sa_bonus_tab->sa_idx_tab[bulk[i].sa_attr])) {
+			SA_ATTR_INFO(sa, hdl->sa_bonus_tab,
+			    SA_GET_HDR(hdl, SA_BONUS),
+			    bulk[i].sa_attr, bulk[i], SA_BONUS, hdl);
+			if (tx && !(buftypes & SA_BONUS)) {
+				dmu_buf_will_dirty(hdl->sa_bonus, tx);
+				buftypes |= SA_BONUS;
+			}
+		}
+		if (bulk[i].sa_addr == NULL &&
+		    ((error = sa_get_spill(hdl)) == 0)) {
+			if (TOC_ATTR_PRESENT(
+			    hdl->sa_spill_tab->sa_idx_tab[bulk[i].sa_attr])) {
+				SA_ATTR_INFO(sa, hdl->sa_spill_tab,
+				    SA_GET_HDR(hdl, SA_SPILL),
+				    bulk[i].sa_attr, bulk[i], SA_SPILL, hdl);
+				if (tx && !(buftypes & SA_SPILL) &&
+				    bulk[i].sa_size == bulk[i].sa_length) {
+					dmu_buf_will_dirty(hdl->sa_spill, tx);
+					buftypes |= SA_SPILL;
+				}
+			}
+		}
+		if (error && error != ENOENT) {
+			return ((error == ECKSUM) ? EIO : error);
+		}
+
+		switch (data_op) {
+		case SA_LOOKUP:
+			if (bulk[i].sa_addr == NULL)
+				return (SET_ERROR(ENOENT));
+			if (bulk[i].sa_data) {
+				SA_COPY_DATA(bulk[i].sa_data_func,
+				    bulk[i].sa_addr, bulk[i].sa_data,
+				    bulk[i].sa_size);
+			}
+			continue;
+
+		case SA_UPDATE:
+			/* existing rewrite of attr */
+			if (bulk[i].sa_addr &&
+			    bulk[i].sa_size == bulk[i].sa_length) {
+				SA_COPY_DATA(bulk[i].sa_data_func,
+				    bulk[i].sa_data, bulk[i].sa_addr,
+				    bulk[i].sa_length);
+				continue;
+			} else if (bulk[i].sa_addr) { /* attr size change */
+				error = sa_modify_attrs(hdl, bulk[i].sa_attr,
+				    SA_REPLACE, bulk[i].sa_data_func,
+				    bulk[i].sa_data, bulk[i].sa_length, tx);
+			} else { /* adding new attribute */
+				error = sa_modify_attrs(hdl, bulk[i].sa_attr,
+				    SA_ADD, bulk[i].sa_data_func,
+				    bulk[i].sa_data, bulk[i].sa_length, tx);
+			}
+			if (error)
+				return (error);
+			break;
+		default:
+			break;
+		}
+	}
+	return (error);
+}
+
+static sa_lot_t *
+sa_add_layout_entry(objset_t *os, sa_attr_type_t *attrs, int attr_count,
+    uint64_t lot_num, uint64_t hash, boolean_t zapadd, dmu_tx_t *tx)
+{
+	sa_os_t *sa = os->os_sa;
+	sa_lot_t *tb, *findtb;
+	int i;
+	avl_index_t loc;
+
+	ASSERT(MUTEX_HELD(&sa->sa_lock));
+	tb = kmem_zalloc(sizeof (sa_lot_t), KM_SLEEP);
+	tb->lot_attr_count = attr_count;
+	tb->lot_attrs = kmem_alloc(sizeof (sa_attr_type_t) * attr_count,
+	    KM_SLEEP);
+	bcopy(attrs, tb->lot_attrs, sizeof (sa_attr_type_t) * attr_count);
+	tb->lot_num = lot_num;
+	tb->lot_hash = hash;
+	tb->lot_instance = 0;
+
+	if (zapadd) {
+		char attr_name[8];
+
+		if (sa->sa_layout_attr_obj == 0) {
+			sa->sa_layout_attr_obj = zap_create_link(os,
+			    DMU_OT_SA_ATTR_LAYOUTS,
+			    sa->sa_master_obj, SA_LAYOUTS, tx);
+		}
+
+		(void) snprintf(attr_name, sizeof (attr_name),
+		    "%d", (int)lot_num);
+		VERIFY(0 == zap_update(os, os->os_sa->sa_layout_attr_obj,
+		    attr_name, 2, attr_count, attrs, tx));
+	}
+
+	list_create(&tb->lot_idx_tab, sizeof (sa_idx_tab_t),
+	    offsetof(sa_idx_tab_t, sa_next));
+
+	for (i = 0; i != attr_count; i++) {
+		if (sa->sa_attr_table[tb->lot_attrs[i]].sa_length == 0)
+			tb->lot_var_sizes++;
+	}
+
+	avl_add(&sa->sa_layout_num_tree, tb);
+
+	/* verify we don't have a hash collision */
+	if ((findtb = avl_find(&sa->sa_layout_hash_tree, tb, &loc)) != NULL) {
+		for (; findtb && findtb->lot_hash == hash;
+		    findtb = AVL_NEXT(&sa->sa_layout_hash_tree, findtb)) {
+			if (findtb->lot_instance != tb->lot_instance)
+				break;
+			tb->lot_instance++;
+		}
+	}
+	avl_add(&sa->sa_layout_hash_tree, tb);
+	return (tb);
+}
+
+static void
+sa_find_layout(objset_t *os, uint64_t hash, sa_attr_type_t *attrs,
+    int count, dmu_tx_t *tx, sa_lot_t **lot)
+{
+	sa_lot_t *tb, tbsearch;
+	avl_index_t loc;
+	sa_os_t *sa = os->os_sa;
+	boolean_t found = B_FALSE;
+
+	mutex_enter(&sa->sa_lock);
+	tbsearch.lot_hash = hash;
+	tbsearch.lot_instance = 0;
+	tb = avl_find(&sa->sa_layout_hash_tree, &tbsearch, &loc);
+	if (tb) {
+		for (; tb && tb->lot_hash == hash;
+		    tb = AVL_NEXT(&sa->sa_layout_hash_tree, tb)) {
+			if (sa_layout_equal(tb, attrs, count) == 0) {
+				found = B_TRUE;
+				break;
+			}
+		}
+	}
+	if (!found) {
+		tb = sa_add_layout_entry(os, attrs, count,
+		    avl_numnodes(&sa->sa_layout_num_tree), hash, B_TRUE, tx);
+	}
+	mutex_exit(&sa->sa_lock);
+	*lot = tb;
+}
+
+static int
+sa_resize_spill(sa_handle_t *hdl, uint32_t size, dmu_tx_t *tx)
+{
+	int error;
+	uint32_t blocksize;
+
+	if (size == 0) {
+		blocksize = SPA_MINBLOCKSIZE;
+	} else if (size > SPA_OLD_MAXBLOCKSIZE) {
+		ASSERT(0);
+		return (SET_ERROR(EFBIG));
+	} else {
+		blocksize = P2ROUNDUP_TYPED(size, SPA_MINBLOCKSIZE, uint32_t);
+	}
+
+	error = dbuf_spill_set_blksz(hdl->sa_spill, blocksize, tx);
+	ASSERT(error == 0);
+	return (error);
+}
+
+static void
+sa_copy_data(sa_data_locator_t *func, void *datastart, void *target, int buflen)
+{
+	if (func == NULL) {
+		bcopy(datastart, target, buflen);
+	} else {
+		boolean_t start;
+		int bytes;
+		void *dataptr;
+		void *saptr = target;
+		uint32_t length;
+
+		start = B_TRUE;
+		bytes = 0;
+		while (bytes < buflen) {
+			func(&dataptr, &length, buflen, start, datastart);
+			bcopy(dataptr, saptr, length);
+			saptr = (void *)((caddr_t)saptr + length);
+			bytes += length;
+			start = B_FALSE;
+		}
+	}
+}
+
+/*
+ * Determine several different values pertaining to system attribute
+ * buffers.
+ *
+ * Return the size of the sa_hdr_phys_t header for the buffer. Each
+ * variable length attribute except the first contributes two bytes to
+ * the header size, which is then rounded up to an 8-byte boundary.
+ *
+ * The following output parameters are also computed.
+ *
+ *  index - The index of the first attribute in attr_desc that will
+ *  spill over. Only valid if will_spill is set.
+ *
+ *  total - The total number of bytes of all system attributes described
+ *  in attr_desc.
+ *
+ *  will_spill - Set when spilling is necessary. It is only set when
+ *  the buftype is SA_BONUS.
+ */
+static int
+sa_find_sizes(sa_os_t *sa, sa_bulk_attr_t *attr_desc, int attr_count,
+    dmu_buf_t *db, sa_buf_type_t buftype, int *index, int *total,
+    boolean_t *will_spill)
+{
+	int var_size_count = 0;
+	int i;
+	int full_space;
+	int hdrsize;
+	int extra_hdrsize;
+
+	if (buftype == SA_BONUS && sa->sa_force_spill) {
+		*total = 0;
+		*index = 0;
+		*will_spill = B_TRUE;
+		return (0);
+	}
+
+	*index = -1;
+	*total = 0;
+	*will_spill = B_FALSE;
+
+	extra_hdrsize = 0;
+	hdrsize = (SA_BONUSTYPE_FROM_DB(db) == DMU_OT_ZNODE) ? 0 :
+	    sizeof (sa_hdr_phys_t);
+
+	full_space = (buftype == SA_BONUS) ? DN_MAX_BONUSLEN : db->db_size;
+	ASSERT(IS_P2ALIGNED(full_space, 8));
+
+	for (i = 0; i != attr_count; i++) {
+		boolean_t is_var_sz, might_spill_here;
+		int tmp_hdrsize;
+
+		*total = P2ROUNDUP(*total, 8);
+		*total += attr_desc[i].sa_length;
+		if (*will_spill)
+			continue;
+
+		is_var_sz = (SA_REGISTERED_LEN(sa, attr_desc[i].sa_attr) == 0);
+		if (is_var_sz)
+			var_size_count++;
+
+		/*
+		 * Calculate what the SA header size would be if this
+		 * attribute doesn't spill.
+		 */
+		tmp_hdrsize = hdrsize + ((is_var_sz && var_size_count > 1) ?
+		    sizeof (uint16_t) : 0);
+
+		/*
+		 * Check whether this attribute spans into the space
+		 * that would be used by the spill block pointer should
+		 * a spill block be needed.
+		 */
+		might_spill_here =
+		    buftype == SA_BONUS && *index == -1 &&
+		    (*total + P2ROUNDUP(tmp_hdrsize, 8)) >
+		    (full_space - sizeof (blkptr_t));
+
+		if (is_var_sz && var_size_count > 1) {
+			if (buftype == SA_SPILL ||
+			    tmp_hdrsize + *total < full_space) {
+				/*
+				 * Record the extra header size in case this
+				 * increase needs to be reversed due to
+				 * spill-over.
+				 */
+				hdrsize = tmp_hdrsize;
+				if (*index != -1 || might_spill_here)
+					extra_hdrsize += sizeof (uint16_t);
+			} else {
+				ASSERT(buftype == SA_BONUS);
+				if (*index == -1)
+					*index = i;
+				*will_spill = B_TRUE;
+				continue;
+			}
+		}
+
+		/*
+		 * Store index of where spill *could* occur. Then
+		 * continue to count the remaining attribute sizes. The
+		 * sum is used later for sizing bonus and spill buffer.
+		 */
+		if (might_spill_here)
+			*index = i;
+
+		if ((*total + P2ROUNDUP(hdrsize, 8)) > full_space &&
+		    buftype == SA_BONUS)
+			*will_spill = B_TRUE;
+	}
+
+	if (*will_spill)
+		hdrsize -= extra_hdrsize;
+
+	hdrsize = P2ROUNDUP(hdrsize, 8);
+	return (hdrsize);
+}
+
+#define	BUF_SPACE_NEEDED(total, header) (total + header)
+
+/*
+ * Find layout that corresponds to ordering of attributes
+ * If not found a new layout number is created and added to
+ * persistent layout tables.
+ */
+static int
+sa_build_layouts(sa_handle_t *hdl, sa_bulk_attr_t *attr_desc, int attr_count,
+    dmu_tx_t *tx)
+{
+	sa_os_t *sa = hdl->sa_os->os_sa;
+	uint64_t hash;
+	sa_buf_type_t buftype;
+	sa_hdr_phys_t *sahdr;
+	void *data_start;
+	sa_attr_type_t *attrs, *attrs_start;
+	int i, lot_count;
+	int spill_idx;
+	int hdrsize;
+	int spillhdrsize = 0;
+	int used;
+	dmu_object_type_t bonustype;
+	sa_lot_t *lot;
+	int len_idx;
+	int spill_used;
+	boolean_t spilling;
+
+	dmu_buf_will_dirty(hdl->sa_bonus, tx);
+	bonustype = SA_BONUSTYPE_FROM_DB(hdl->sa_bonus);
+
+	/* first determine bonus header size and sum of all attributes */
+	hdrsize = sa_find_sizes(sa, attr_desc, attr_count, hdl->sa_bonus,
+	    SA_BONUS, &spill_idx, &used, &spilling);
+
+	if (used > SPA_OLD_MAXBLOCKSIZE)
+		return (SET_ERROR(EFBIG));
+
+	VERIFY(0 == dmu_set_bonus(hdl->sa_bonus, spilling ?
+	    MIN(DN_MAX_BONUSLEN - sizeof (blkptr_t), used + hdrsize) :
+	    used + hdrsize, tx));
+
+	ASSERT((bonustype == DMU_OT_ZNODE && spilling == 0) ||
+	    bonustype == DMU_OT_SA);
+
+	/* setup and size spill buffer when needed */
+	if (spilling) {
+		boolean_t dummy;
+
+		if (hdl->sa_spill == NULL) {
+			VERIFY(dmu_spill_hold_by_bonus(hdl->sa_bonus, NULL,
+			    &hdl->sa_spill) == 0);
+		}
+		dmu_buf_will_dirty(hdl->sa_spill, tx);
+
+		spillhdrsize = sa_find_sizes(sa, &attr_desc[spill_idx],
+		    attr_count - spill_idx, hdl->sa_spill, SA_SPILL, &i,
+		    &spill_used, &dummy);
+
+		if (spill_used > SPA_OLD_MAXBLOCKSIZE)
+			return (SET_ERROR(EFBIG));
+
+		if (BUF_SPACE_NEEDED(spill_used, spillhdrsize) >
+		    hdl->sa_spill->db_size)
+			VERIFY(0 == sa_resize_spill(hdl,
+			    BUF_SPACE_NEEDED(spill_used, spillhdrsize), tx));
+	}
+
+	/* setup starting pointers to lay down data */
+	data_start = (void *)((uintptr_t)hdl->sa_bonus->db_data + hdrsize);
+	sahdr = (sa_hdr_phys_t *)hdl->sa_bonus->db_data;
+	buftype = SA_BONUS;
+
+	attrs_start = attrs = kmem_alloc(sizeof (sa_attr_type_t) * attr_count,
+	    KM_SLEEP);
+	lot_count = 0;
+
+	for (i = 0, len_idx = 0, hash = -1ULL; i != attr_count; i++) {
+		uint16_t length;
+
+		ASSERT(IS_P2ALIGNED(data_start, 8));
+		attrs[i] = attr_desc[i].sa_attr;
+		length = SA_REGISTERED_LEN(sa, attrs[i]);
+		if (length == 0)
+			length = attr_desc[i].sa_length;
+
+		if (spilling && i == spill_idx) { /* switch to spill buffer */
+			VERIFY(bonustype == DMU_OT_SA);
+			if (buftype == SA_BONUS && !sa->sa_force_spill) {
+				sa_find_layout(hdl->sa_os, hash, attrs_start,
+				    lot_count, tx, &lot);
+				SA_SET_HDR(sahdr, lot->lot_num, hdrsize);
+			}
+
+			buftype = SA_SPILL;
+			hash = -1ULL;
+			len_idx = 0;
+
+			sahdr = (sa_hdr_phys_t *)hdl->sa_spill->db_data;
+			sahdr->sa_magic = SA_MAGIC;
+			data_start = (void *)((uintptr_t)sahdr +
+			    spillhdrsize);
+			attrs_start = &attrs[i];
+			lot_count = 0;
+		}
+		hash ^= SA_ATTR_HASH(attrs[i]);
+		attr_desc[i].sa_addr = data_start;
+		attr_desc[i].sa_size = length;
+		SA_COPY_DATA(attr_desc[i].sa_data_func, attr_desc[i].sa_data,
+		    data_start, length);
+		if (sa->sa_attr_table[attrs[i]].sa_length == 0) {
+			sahdr->sa_lengths[len_idx++] = length;
+		}
+		data_start = (void *)P2ROUNDUP(((uintptr_t)data_start +
+		    length), 8);
+		lot_count++;
+	}
+
+	sa_find_layout(hdl->sa_os, hash, attrs_start, lot_count, tx, &lot);
+
+	/*
+	 * Verify that old znodes always have layout number 0.
+	 * Must be DMU_OT_SA for arbitrary layouts
+	 */
+	VERIFY((bonustype == DMU_OT_ZNODE && lot->lot_num == 0) ||
+	    (bonustype == DMU_OT_SA && lot->lot_num > 1));
+
+	if (bonustype == DMU_OT_SA) {
+		SA_SET_HDR(sahdr, lot->lot_num,
+		    buftype == SA_BONUS ? hdrsize : spillhdrsize);
+	}
+
+	kmem_free(attrs, sizeof (sa_attr_type_t) * attr_count);
+	if (hdl->sa_bonus_tab) {
+		sa_idx_tab_rele(hdl->sa_os, hdl->sa_bonus_tab);
+		hdl->sa_bonus_tab = NULL;
+	}
+	if (!sa->sa_force_spill)
+		VERIFY(0 == sa_build_index(hdl, SA_BONUS));
+	if (hdl->sa_spill) {
+		sa_idx_tab_rele(hdl->sa_os, hdl->sa_spill_tab);
+		if (!spilling) {
+			/*
+			 * remove spill block that is no longer needed.
+			 */
+			dmu_buf_rele(hdl->sa_spill, NULL);
+			hdl->sa_spill = NULL;
+			hdl->sa_spill_tab = NULL;
+			VERIFY(0 == dmu_rm_spill(hdl->sa_os,
+			    sa_handle_object(hdl), tx));
+		} else {
+			VERIFY(0 == sa_build_index(hdl, SA_SPILL));
+		}
+	}
+
+	return (0);
+}
+
+static void
+sa_free_attr_table(sa_os_t *sa)
+{
+	int i;
+
+	if (sa->sa_attr_table == NULL)
+		return;
+
+	for (i = 0; i != sa->sa_num_attrs; i++) {
+		if (sa->sa_attr_table[i].sa_name)
+			kmem_free(sa->sa_attr_table[i].sa_name,
+			    strlen(sa->sa_attr_table[i].sa_name) + 1);
+	}
+
+	kmem_free(sa->sa_attr_table,
+	    sizeof (sa_attr_table_t) * sa->sa_num_attrs);
+
+	sa->sa_attr_table = NULL;
+}
+
+static int
+sa_attr_table_setup(objset_t *os, sa_attr_reg_t *reg_attrs, int count)
+{
+	sa_os_t *sa = os->os_sa;
+	uint64_t sa_attr_count = 0;
+	uint64_t sa_reg_count = 0;
+	int error = 0;
+	uint64_t attr_value;
+	sa_attr_table_t *tb;
+	zap_cursor_t zc;
+	zap_attribute_t za;
+	int registered_count = 0;
+	int i;
+	dmu_objset_type_t ostype = dmu_objset_type(os);
+
+	sa->sa_user_table =
+	    kmem_zalloc(count * sizeof (sa_attr_type_t), KM_SLEEP);
+	sa->sa_user_table_sz = count * sizeof (sa_attr_type_t);
+
+	if (sa->sa_reg_attr_obj != 0) {
+		error = zap_count(os, sa->sa_reg_attr_obj,
+		    &sa_attr_count);
+
+		/*
+		 * Make sure we retrieved a count and that it isn't zero
+		 */
+		if (error || (error == 0 && sa_attr_count == 0)) {
+			if (error == 0)
+				error = SET_ERROR(EINVAL);
+			goto bail;
+		}
+		sa_reg_count = sa_attr_count;
+	}
+
+	if (ostype == DMU_OST_ZFS && sa_attr_count == 0)
+		sa_attr_count += sa_legacy_attr_count;
+
+	/* Allocate attribute numbers for attributes that aren't registered */
+	for (i = 0; i != count; i++) {
+		boolean_t found = B_FALSE;
+		int j;
+
+		if (ostype == DMU_OST_ZFS) {
+			for (j = 0; j != sa_legacy_attr_count; j++) {
+				if (strcmp(reg_attrs[i].sa_name,
+				    sa_legacy_attrs[j].sa_name) == 0) {
+					sa->sa_user_table[i] =
+					    sa_legacy_attrs[j].sa_attr;
+					found = B_TRUE;
+				}
+			}
+		}
+		if (found)
+			continue;
+
+		if (sa->sa_reg_attr_obj)
+			error = zap_lookup(os, sa->sa_reg_attr_obj,
+			    reg_attrs[i].sa_name, 8, 1, &attr_value);
+		else
+			error = SET_ERROR(ENOENT);
+		switch (error) {
+		case ENOENT:
+			sa->sa_user_table[i] = (sa_attr_type_t)sa_attr_count;
+			sa_attr_count++;
+			break;
+		case 0:
+			sa->sa_user_table[i] = ATTR_NUM(attr_value);
+			break;
+		default:
+			goto bail;
+		}
+	}
+
+	sa->sa_num_attrs = sa_attr_count;
+	tb = sa->sa_attr_table =
+	    kmem_zalloc(sizeof (sa_attr_table_t) * sa_attr_count, KM_SLEEP);
+
+	/*
+	 * Attribute table is constructed from requested attribute list,
+	 * previously foreign registered attributes, and also the legacy
+	 * ZPL set of attributes.
+	 */
+
+	if (sa->sa_reg_attr_obj) {
+		for (zap_cursor_init(&zc, os, sa->sa_reg_attr_obj);
+		    (error = zap_cursor_retrieve(&zc, &za)) == 0;
+		    zap_cursor_advance(&zc)) {
+			uint64_t value;
+			value  = za.za_first_integer;
+
+			registered_count++;
+			tb[ATTR_NUM(value)].sa_attr = ATTR_NUM(value);
+			tb[ATTR_NUM(value)].sa_length = ATTR_LENGTH(value);
+			tb[ATTR_NUM(value)].sa_byteswap = ATTR_BSWAP(value);
+			tb[ATTR_NUM(value)].sa_registered = B_TRUE;
+
+			if (tb[ATTR_NUM(value)].sa_name) {
+				continue;
+			}
+			tb[ATTR_NUM(value)].sa_name =
+			    kmem_zalloc(strlen(za.za_name) +1, KM_SLEEP);
+			(void) strlcpy(tb[ATTR_NUM(value)].sa_name, za.za_name,
+			    strlen(za.za_name) +1);
+		}
+		zap_cursor_fini(&zc);
+		/*
+		 * Make sure we processed the correct number of registered
+		 * attributes
+		 */
+		if (registered_count != sa_reg_count) {
+			ASSERT(error != 0);
+			goto bail;
+		}
+
+	}
+
+	if (ostype == DMU_OST_ZFS) {
+		for (i = 0; i != sa_legacy_attr_count; i++) {
+			if (tb[i].sa_name)
+				continue;
+			tb[i].sa_attr = sa_legacy_attrs[i].sa_attr;
+			tb[i].sa_length = sa_legacy_attrs[i].sa_length;
+			tb[i].sa_byteswap = sa_legacy_attrs[i].sa_byteswap;
+			tb[i].sa_registered = B_FALSE;
+			tb[i].sa_name =
+			    kmem_zalloc(strlen(sa_legacy_attrs[i].sa_name) +1,
+			    KM_SLEEP);
+			(void) strlcpy(tb[i].sa_name,
+			    sa_legacy_attrs[i].sa_name,
+			    strlen(sa_legacy_attrs[i].sa_name) + 1);
+		}
+	}
+
+	for (i = 0; i != count; i++) {
+		sa_attr_type_t attr_id;
+
+		attr_id = sa->sa_user_table[i];
+		if (tb[attr_id].sa_name)
+			continue;
+
+		tb[attr_id].sa_length = reg_attrs[i].sa_length;
+		tb[attr_id].sa_byteswap = reg_attrs[i].sa_byteswap;
+		tb[attr_id].sa_attr = attr_id;
+		tb[attr_id].sa_name =
+		    kmem_zalloc(strlen(reg_attrs[i].sa_name) + 1, KM_SLEEP);
+		(void) strlcpy(tb[attr_id].sa_name, reg_attrs[i].sa_name,
+		    strlen(reg_attrs[i].sa_name) + 1);
+	}
+
+	sa->sa_need_attr_registration =
+	    (sa_attr_count != registered_count);
+
+	return (0);
+bail:
+	kmem_free(sa->sa_user_table, count * sizeof (sa_attr_type_t));
+	sa->sa_user_table = NULL;
+	sa_free_attr_table(sa);
+	return ((error != 0) ? error : EINVAL);
+}
+
+int
+sa_setup(objset_t *os, uint64_t sa_obj, sa_attr_reg_t *reg_attrs, int count,
+    sa_attr_type_t **user_table)
+{
+	zap_cursor_t zc;
+	zap_attribute_t za;
+	sa_os_t *sa;
+	dmu_objset_type_t ostype = dmu_objset_type(os);
+	sa_attr_type_t *tb;
+	int error;
+
+	mutex_enter(&os->os_user_ptr_lock);
+	if (os->os_sa) {
+		mutex_enter(&os->os_sa->sa_lock);
+		mutex_exit(&os->os_user_ptr_lock);
+		tb = os->os_sa->sa_user_table;
+		mutex_exit(&os->os_sa->sa_lock);
+		*user_table = tb;
+		return (0);
+	}
+
+	sa = kmem_zalloc(sizeof (sa_os_t), KM_SLEEP);
+	mutex_init(&sa->sa_lock, NULL, MUTEX_DEFAULT, NULL);
+	sa->sa_master_obj = sa_obj;
+
+	os->os_sa = sa;
+	mutex_enter(&sa->sa_lock);
+	mutex_exit(&os->os_user_ptr_lock);
+	avl_create(&sa->sa_layout_num_tree, layout_num_compare,
+	    sizeof (sa_lot_t), offsetof(sa_lot_t, lot_num_node));
+	avl_create(&sa->sa_layout_hash_tree, layout_hash_compare,
+	    sizeof (sa_lot_t), offsetof(sa_lot_t, lot_hash_node));
+
+	if (sa_obj) {
+		error = zap_lookup(os, sa_obj, SA_LAYOUTS,
+		    8, 1, &sa->sa_layout_attr_obj);
+		if (error != 0 && error != ENOENT)
+			goto fail;
+		error = zap_lookup(os, sa_obj, SA_REGISTRY,
+		    8, 1, &sa->sa_reg_attr_obj);
+		if (error != 0 && error != ENOENT)
+			goto fail;
+	}
+
+	if ((error = sa_attr_table_setup(os, reg_attrs, count)) != 0)
+		goto fail;
+
+	if (sa->sa_layout_attr_obj != 0) {
+		uint64_t layout_count;
+
+		error = zap_count(os, sa->sa_layout_attr_obj,
+		    &layout_count);
+
+		/*
+		 * Layout number count should be > 0
+		 */
+		if (error || (error == 0 && layout_count == 0)) {
+			if (error == 0)
+				error = SET_ERROR(EINVAL);
+			goto fail;
+		}
+
+		for (zap_cursor_init(&zc, os, sa->sa_layout_attr_obj);
+		    (error = zap_cursor_retrieve(&zc, &za)) == 0;
+		    zap_cursor_advance(&zc)) {
+			sa_attr_type_t *lot_attrs;
+			uint64_t lot_num;
+
+			lot_attrs = kmem_zalloc(sizeof (sa_attr_type_t) *
+			    za.za_num_integers, KM_SLEEP);
+
+			if ((error = (zap_lookup(os, sa->sa_layout_attr_obj,
+			    za.za_name, 2, za.za_num_integers,
+			    lot_attrs))) != 0) {
+				kmem_free(lot_attrs, sizeof (sa_attr_type_t) *
+				    za.za_num_integers);
+				break;
+			}
+			VERIFY(ddi_strtoull(za.za_name, NULL, 10,
+			    (unsigned long long *)&lot_num) == 0);
+
+			(void) sa_add_layout_entry(os, lot_attrs,
+			    za.za_num_integers, lot_num,
+			    sa_layout_info_hash(lot_attrs,
+			    za.za_num_integers), B_FALSE, NULL);
+			kmem_free(lot_attrs, sizeof (sa_attr_type_t) *
+			    za.za_num_integers);
+		}
+		zap_cursor_fini(&zc);
+
+		/*
+		 * Make sure layout count matches number of entries added
+		 * to AVL tree
+		 */
+		if (avl_numnodes(&sa->sa_layout_num_tree) != layout_count) {
+			ASSERT(error != 0);
+			goto fail;
+		}
+	}
+
+	/* Add special layout number for old ZNODES */
+	if (ostype == DMU_OST_ZFS) {
+		(void) sa_add_layout_entry(os, sa_legacy_zpl_layout,
+		    sa_legacy_attr_count, 0,
+		    sa_layout_info_hash(sa_legacy_zpl_layout,
+		    sa_legacy_attr_count), B_FALSE, NULL);
+
+		(void) sa_add_layout_entry(os, sa_dummy_zpl_layout, 0, 1,
+		    0, B_FALSE, NULL);
+	}
+	*user_table = os->os_sa->sa_user_table;
+	mutex_exit(&sa->sa_lock);
+	return (0);
+fail:
+	os->os_sa = NULL;
+	sa_free_attr_table(sa);
+	if (sa->sa_user_table)
+		kmem_free(sa->sa_user_table, sa->sa_user_table_sz);
+	mutex_exit(&sa->sa_lock);
+	avl_destroy(&sa->sa_layout_hash_tree);
+	avl_destroy(&sa->sa_layout_num_tree);
+	mutex_destroy(&sa->sa_lock);
+	kmem_free(sa, sizeof (sa_os_t));
+	return ((error == ECKSUM) ? EIO : error);
+}
+
+void
+sa_tear_down(objset_t *os)
+{
+	sa_os_t *sa = os->os_sa;
+	sa_lot_t *layout;
+	void *cookie;
+
+	kmem_free(sa->sa_user_table, sa->sa_user_table_sz);
+
+	/* Free up attr table */
+
+	sa_free_attr_table(sa);
+
+	cookie = NULL;
+	while ((layout =
+	    avl_destroy_nodes(&sa->sa_layout_hash_tree, &cookie))) {
+		sa_idx_tab_t *tab;
+		while ((tab = list_head(&layout->lot_idx_tab))) {
+			ASSERT(refcount_count(&tab->sa_refcount));
+			sa_idx_tab_rele(os, tab);
+		}
+	}
+
+	cookie = NULL;
+	while ((layout = avl_destroy_nodes(&sa->sa_layout_num_tree, &cookie))) {
+		kmem_free(layout->lot_attrs,
+		    sizeof (sa_attr_type_t) * layout->lot_attr_count);
+		kmem_free(layout, sizeof (sa_lot_t));
+	}
+
+	avl_destroy(&sa->sa_layout_hash_tree);
+	avl_destroy(&sa->sa_layout_num_tree);
+	mutex_destroy(&sa->sa_lock);
+
+	kmem_free(sa, sizeof (sa_os_t));
+	os->os_sa = NULL;
+}
+
+void
+sa_build_idx_tab(void *hdr, void *attr_addr, sa_attr_type_t attr,
+    uint16_t length, int length_idx, boolean_t var_length, void *userp)
+{
+	sa_idx_tab_t *idx_tab = userp;
+
+	if (var_length) {
+		ASSERT(idx_tab->sa_variable_lengths);
+		idx_tab->sa_variable_lengths[length_idx] = length;
+	}
+	TOC_ATTR_ENCODE(idx_tab->sa_idx_tab[attr], length_idx,
+	    (uint32_t)((uintptr_t)attr_addr - (uintptr_t)hdr));
+}
+
+static void
+sa_attr_iter(objset_t *os, sa_hdr_phys_t *hdr, dmu_object_type_t type,
+    sa_iterfunc_t func, sa_lot_t *tab, void *userp)
+{
+	void *data_start;
+	sa_lot_t *tb = tab;
+	sa_lot_t search;
+	avl_index_t loc;
+	sa_os_t *sa = os->os_sa;
+	int i;
+	uint16_t *length_start = NULL;
+	uint8_t length_idx = 0;
+
+	if (tab == NULL) {
+		search.lot_num = SA_LAYOUT_NUM(hdr, type);
+		tb = avl_find(&sa->sa_layout_num_tree, &search, &loc);
+		ASSERT(tb);
+	}
+
+	if (IS_SA_BONUSTYPE(type)) {
+		data_start = (void *)P2ROUNDUP(((uintptr_t)hdr +
+		    offsetof(sa_hdr_phys_t, sa_lengths) +
+		    (sizeof (uint16_t) * tb->lot_var_sizes)), 8);
+		length_start = hdr->sa_lengths;
+	} else {
+		data_start = hdr;
+	}
+
+	for (i = 0; i != tb->lot_attr_count; i++) {
+		int attr_length, reg_length;
+		uint8_t idx_len;
+
+		reg_length = sa->sa_attr_table[tb->lot_attrs[i]].sa_length;
+		if (reg_length) {
+			attr_length = reg_length;
+			idx_len = 0;
+		} else {
+			attr_length = length_start[length_idx];
+			idx_len = length_idx++;
+		}
+
+		func(hdr, data_start, tb->lot_attrs[i], attr_length,
+		    idx_len, reg_length == 0 ? B_TRUE : B_FALSE, userp);
+
+		data_start = (void *)P2ROUNDUP(((uintptr_t)data_start +
+		    attr_length), 8);
+	}
+}
+
+/*ARGSUSED*/
+void
+sa_byteswap_cb(void *hdr, void *attr_addr, sa_attr_type_t attr,
+    uint16_t length, int length_idx, boolean_t variable_length, void *userp)
+{
+	sa_handle_t *hdl = userp;
+	sa_os_t *sa = hdl->sa_os->os_sa;
+
+	sa_bswap_table[sa->sa_attr_table[attr].sa_byteswap](attr_addr, length);
+}
+
+void
+sa_byteswap(sa_handle_t *hdl, sa_buf_type_t buftype)
+{
+	sa_hdr_phys_t *sa_hdr_phys = SA_GET_HDR(hdl, buftype);
+	dmu_buf_impl_t *db;
+	int num_lengths = 1;
+	int i;
+	ASSERTV(sa_os_t *sa = hdl->sa_os->os_sa);
+
+	ASSERT(MUTEX_HELD(&sa->sa_lock));
+	if (sa_hdr_phys->sa_magic == SA_MAGIC)
+		return;
+
+	db = SA_GET_DB(hdl, buftype);
+
+	if (buftype == SA_SPILL) {
+		arc_release(db->db_buf, NULL);
+		arc_buf_thaw(db->db_buf);
+	}
+
+	sa_hdr_phys->sa_magic = BSWAP_32(sa_hdr_phys->sa_magic);
+	sa_hdr_phys->sa_layout_info = BSWAP_16(sa_hdr_phys->sa_layout_info);
+
+	/*
+	 * Determine number of variable lenghts in header
+	 * The standard 8 byte header has one for free and a
+	 * 16 byte header would have 4 + 1;
+	 */
+	if (SA_HDR_SIZE(sa_hdr_phys) > 8)
+		num_lengths += (SA_HDR_SIZE(sa_hdr_phys) - 8) >> 1;
+	for (i = 0; i != num_lengths; i++)
+		sa_hdr_phys->sa_lengths[i] =
+		    BSWAP_16(sa_hdr_phys->sa_lengths[i]);
+
+	sa_attr_iter(hdl->sa_os, sa_hdr_phys, DMU_OT_SA,
+	    sa_byteswap_cb, NULL, hdl);
+
+	if (buftype == SA_SPILL)
+		arc_buf_freeze(((dmu_buf_impl_t *)hdl->sa_spill)->db_buf);
+}
+
+static int
+sa_build_index(sa_handle_t *hdl, sa_buf_type_t buftype)
+{
+	sa_hdr_phys_t *sa_hdr_phys;
+	dmu_buf_impl_t *db = SA_GET_DB(hdl, buftype);
+	dmu_object_type_t bonustype = SA_BONUSTYPE_FROM_DB(db);
+	sa_os_t *sa = hdl->sa_os->os_sa;
+	sa_idx_tab_t *idx_tab;
+
+	sa_hdr_phys = SA_GET_HDR(hdl, buftype);
+
+	mutex_enter(&sa->sa_lock);
+
+	/* Do we need to byteswap? */
+
+	/* only check if not old znode */
+	if (IS_SA_BONUSTYPE(bonustype) && sa_hdr_phys->sa_magic != SA_MAGIC &&
+	    sa_hdr_phys->sa_magic != 0) {
+		VERIFY(BSWAP_32(sa_hdr_phys->sa_magic) == SA_MAGIC);
+		sa_byteswap(hdl, buftype);
+	}
+
+	idx_tab = sa_find_idx_tab(hdl->sa_os, bonustype, sa_hdr_phys);
+
+	if (buftype == SA_BONUS)
+		hdl->sa_bonus_tab = idx_tab;
+	else
+		hdl->sa_spill_tab = idx_tab;
+
+	mutex_exit(&sa->sa_lock);
+	return (0);
+}
+
+/*ARGSUSED*/
+static void
+sa_evict(void *dbu)
+{
+	panic("evicting sa dbuf\n");
+}
+
+static void
+sa_idx_tab_rele(objset_t *os, void *arg)
+{
+	sa_os_t *sa = os->os_sa;
+	sa_idx_tab_t *idx_tab = arg;
+
+	if (idx_tab == NULL)
+		return;
+
+	mutex_enter(&sa->sa_lock);
+	if (refcount_remove(&idx_tab->sa_refcount, NULL) == 0) {
+		list_remove(&idx_tab->sa_layout->lot_idx_tab, idx_tab);
+		if (idx_tab->sa_variable_lengths)
+			kmem_free(idx_tab->sa_variable_lengths,
+			    sizeof (uint16_t) *
+			    idx_tab->sa_layout->lot_var_sizes);
+		refcount_destroy(&idx_tab->sa_refcount);
+		kmem_free(idx_tab->sa_idx_tab,
+		    sizeof (uint32_t) * sa->sa_num_attrs);
+		kmem_free(idx_tab, sizeof (sa_idx_tab_t));
+	}
+	mutex_exit(&sa->sa_lock);
+}
+
+static void
+sa_idx_tab_hold(objset_t *os, sa_idx_tab_t *idx_tab)
+{
+	ASSERTV(sa_os_t *sa = os->os_sa);
+
+	ASSERT(MUTEX_HELD(&sa->sa_lock));
+	(void) refcount_add(&idx_tab->sa_refcount, NULL);
+}
+
+void
+sa_spill_rele(sa_handle_t *hdl)
+{
+	mutex_enter(&hdl->sa_lock);
+	if (hdl->sa_spill) {
+		sa_idx_tab_rele(hdl->sa_os, hdl->sa_spill_tab);
+		dmu_buf_rele(hdl->sa_spill, NULL);
+		hdl->sa_spill = NULL;
+		hdl->sa_spill_tab = NULL;
+	}
+	mutex_exit(&hdl->sa_lock);
+}
+
+void
+sa_handle_destroy(sa_handle_t *hdl)
+{
+	dmu_buf_t *db = hdl->sa_bonus;
+
+	mutex_enter(&hdl->sa_lock);
+	(void) dmu_buf_remove_user(db, &hdl->sa_dbu);
+
+	if (hdl->sa_bonus_tab)
+		sa_idx_tab_rele(hdl->sa_os, hdl->sa_bonus_tab);
+
+	if (hdl->sa_spill_tab)
+		sa_idx_tab_rele(hdl->sa_os, hdl->sa_spill_tab);
+
+	dmu_buf_rele(hdl->sa_bonus, NULL);
+
+	if (hdl->sa_spill)
+		dmu_buf_rele((dmu_buf_t *)hdl->sa_spill, NULL);
+	mutex_exit(&hdl->sa_lock);
+
+	kmem_cache_free(sa_cache, hdl);
+}
+
+int
+sa_handle_get_from_db(objset_t *os, dmu_buf_t *db, void *userp,
+    sa_handle_type_t hdl_type, sa_handle_t **handlepp)
+{
+	int error = 0;
+	sa_handle_t *handle = NULL;
+#ifdef ZFS_DEBUG
+	dmu_object_info_t doi;
+
+	dmu_object_info_from_db(db, &doi);
+	ASSERT(doi.doi_bonus_type == DMU_OT_SA ||
+	    doi.doi_bonus_type == DMU_OT_ZNODE);
+#endif
+	/* find handle, if it exists */
+	/* if one doesn't exist then create a new one, and initialize it */
+
+	if (hdl_type == SA_HDL_SHARED)
+		handle = dmu_buf_get_user(db);
+
+	if (handle == NULL) {
+		sa_handle_t *winner = NULL;
+
+		handle = kmem_cache_alloc(sa_cache, KM_SLEEP);
+		handle->sa_dbu.dbu_evict_func = NULL;
+		handle->sa_userp = userp;
+		handle->sa_bonus = db;
+		handle->sa_os = os;
+		handle->sa_spill = NULL;
+		handle->sa_bonus_tab = NULL;
+		handle->sa_spill_tab = NULL;
+
+		error = sa_build_index(handle, SA_BONUS);
+
+		if (hdl_type == SA_HDL_SHARED) {
+			dmu_buf_init_user(&handle->sa_dbu, sa_evict, NULL);
+			winner = dmu_buf_set_user_ie(db, &handle->sa_dbu);
+		}
+
+		if (winner != NULL) {
+			kmem_cache_free(sa_cache, handle);
+			handle = winner;
+		}
+	}
+	*handlepp = handle;
+
+	return (error);
+}
+
+int
+sa_handle_get(objset_t *objset, uint64_t objid, void *userp,
+    sa_handle_type_t hdl_type, sa_handle_t **handlepp)
+{
+	dmu_buf_t *db;
+	int error;
+
+	if ((error = dmu_bonus_hold(objset, objid, NULL, &db)))
+		return (error);
+
+	return (sa_handle_get_from_db(objset, db, userp, hdl_type,
+	    handlepp));
+}
+
+int
+sa_buf_hold(objset_t *objset, uint64_t obj_num, void *tag, dmu_buf_t **db)
+{
+	return (dmu_bonus_hold(objset, obj_num, tag, db));
+}
+
+void
+sa_buf_rele(dmu_buf_t *db, void *tag)
+{
+	dmu_buf_rele(db, tag);
+}
+
+int
+sa_lookup_impl(sa_handle_t *hdl, sa_bulk_attr_t *bulk, int count)
+{
+	ASSERT(hdl);
+	ASSERT(MUTEX_HELD(&hdl->sa_lock));
+	return (sa_attr_op(hdl, bulk, count, SA_LOOKUP, NULL));
+}
+
+int
+sa_lookup(sa_handle_t *hdl, sa_attr_type_t attr, void *buf, uint32_t buflen)
+{
+	int error;
+	sa_bulk_attr_t bulk;
+
+	VERIFY3U(buflen, <=, SA_ATTR_MAX_LEN);
+
+	bulk.sa_attr = attr;
+	bulk.sa_data = buf;
+	bulk.sa_length = buflen;
+	bulk.sa_data_func = NULL;
+
+	ASSERT(hdl);
+	mutex_enter(&hdl->sa_lock);
+	error = sa_lookup_impl(hdl, &bulk, 1);
+	mutex_exit(&hdl->sa_lock);
+	return (error);
+}
+
+#ifdef _KERNEL
+int
+sa_lookup_uio(sa_handle_t *hdl, sa_attr_type_t attr, uio_t *uio)
+{
+	int error;
+	sa_bulk_attr_t bulk;
+
+	bulk.sa_data = NULL;
+	bulk.sa_attr = attr;
+	bulk.sa_data_func = NULL;
+
+	ASSERT(hdl);
+
+	mutex_enter(&hdl->sa_lock);
+	if ((error = sa_attr_op(hdl, &bulk, 1, SA_LOOKUP, NULL)) == 0) {
+		error = uiomove((void *)bulk.sa_addr, MIN(bulk.sa_size,
+		    uio->uio_resid), UIO_READ, uio);
+	}
+	mutex_exit(&hdl->sa_lock);
+	return (error);
+}
+#endif
+
+void *
+sa_find_idx_tab(objset_t *os, dmu_object_type_t bonustype, void *data)
+{
+	sa_idx_tab_t *idx_tab;
+	sa_hdr_phys_t *hdr = (sa_hdr_phys_t *)data;
+	sa_os_t *sa = os->os_sa;
+	sa_lot_t *tb, search;
+	avl_index_t loc;
+
+	/*
+	 * Deterimine layout number.  If SA node and header == 0 then
+	 * force the index table to the dummy "1" empty layout.
+	 *
+	 * The layout number would only be zero for a newly created file
+	 * that has not added any attributes yet, or with crypto enabled which
+	 * doesn't write any attributes to the bonus buffer.
+	 */
+
+	search.lot_num = SA_LAYOUT_NUM(hdr, bonustype);
+
+	tb = avl_find(&sa->sa_layout_num_tree, &search, &loc);
+
+	/* Verify header size is consistent with layout information */
+	ASSERT(tb);
+	ASSERT((IS_SA_BONUSTYPE(bonustype) &&
+	    SA_HDR_SIZE_MATCH_LAYOUT(hdr, tb)) || !IS_SA_BONUSTYPE(bonustype) ||
+	    (IS_SA_BONUSTYPE(bonustype) && hdr->sa_layout_info == 0));
+
+	/*
+	 * See if any of the already existing TOC entries can be reused?
+	 */
+
+	for (idx_tab = list_head(&tb->lot_idx_tab); idx_tab;
+	    idx_tab = list_next(&tb->lot_idx_tab, idx_tab)) {
+		boolean_t valid_idx = B_TRUE;
+		int i;
+
+		if (tb->lot_var_sizes != 0 &&
+		    idx_tab->sa_variable_lengths != NULL) {
+			for (i = 0; i != tb->lot_var_sizes; i++) {
+				if (hdr->sa_lengths[i] !=
+				    idx_tab->sa_variable_lengths[i]) {
+					valid_idx = B_FALSE;
+					break;
+				}
+			}
+		}
+		if (valid_idx) {
+			sa_idx_tab_hold(os, idx_tab);
+			return (idx_tab);
+		}
+	}
+
+	/* No such luck, create a new entry */
+	idx_tab = kmem_zalloc(sizeof (sa_idx_tab_t), KM_SLEEP);
+	idx_tab->sa_idx_tab =
+	    kmem_zalloc(sizeof (uint32_t) * sa->sa_num_attrs, KM_SLEEP);
+	idx_tab->sa_layout = tb;
+	refcount_create(&idx_tab->sa_refcount);
+	if (tb->lot_var_sizes)
+		idx_tab->sa_variable_lengths = kmem_alloc(sizeof (uint16_t) *
+		    tb->lot_var_sizes, KM_SLEEP);
+
+	sa_attr_iter(os, hdr, bonustype, sa_build_idx_tab,
+	    tb, idx_tab);
+	sa_idx_tab_hold(os, idx_tab);   /* one hold for consumer */
+	sa_idx_tab_hold(os, idx_tab);	/* one for layout */
+	list_insert_tail(&tb->lot_idx_tab, idx_tab);
+	return (idx_tab);
+}
+
+void
+sa_default_locator(void **dataptr, uint32_t *len, uint32_t total_len,
+    boolean_t start, void *userdata)
+{
+	ASSERT(start);
+
+	*dataptr = userdata;
+	*len = total_len;
+}
+
+static void
+sa_attr_register_sync(sa_handle_t *hdl, dmu_tx_t *tx)
+{
+	uint64_t attr_value = 0;
+	sa_os_t *sa = hdl->sa_os->os_sa;
+	sa_attr_table_t *tb = sa->sa_attr_table;
+	int i;
+
+	mutex_enter(&sa->sa_lock);
+
+	if (!sa->sa_need_attr_registration || sa->sa_master_obj == 0) {
+		mutex_exit(&sa->sa_lock);
+		return;
+	}
+
+	if (sa->sa_reg_attr_obj == 0) {
+		sa->sa_reg_attr_obj = zap_create_link(hdl->sa_os,
+		    DMU_OT_SA_ATTR_REGISTRATION,
+		    sa->sa_master_obj, SA_REGISTRY, tx);
+	}
+	for (i = 0; i != sa->sa_num_attrs; i++) {
+		if (sa->sa_attr_table[i].sa_registered)
+			continue;
+		ATTR_ENCODE(attr_value, tb[i].sa_attr, tb[i].sa_length,
+		    tb[i].sa_byteswap);
+		VERIFY(0 == zap_update(hdl->sa_os, sa->sa_reg_attr_obj,
+		    tb[i].sa_name, 8, 1, &attr_value, tx));
+		tb[i].sa_registered = B_TRUE;
+	}
+	sa->sa_need_attr_registration = B_FALSE;
+	mutex_exit(&sa->sa_lock);
+}
+
+/*
+ * Replace all attributes with attributes specified in template.
+ * If dnode had a spill buffer then those attributes will be
+ * also be replaced, possibly with just an empty spill block
+ *
+ * This interface is intended to only be used for bulk adding of
+ * attributes for a new file.  It will also be used by the ZPL
+ * when converting and old formatted znode to native SA support.
+ */
+int
+sa_replace_all_by_template_locked(sa_handle_t *hdl, sa_bulk_attr_t *attr_desc,
+    int attr_count, dmu_tx_t *tx)
+{
+	sa_os_t *sa = hdl->sa_os->os_sa;
+
+	if (sa->sa_need_attr_registration)
+		sa_attr_register_sync(hdl, tx);
+	return (sa_build_layouts(hdl, attr_desc, attr_count, tx));
+}
+
+int
+sa_replace_all_by_template(sa_handle_t *hdl, sa_bulk_attr_t *attr_desc,
+    int attr_count, dmu_tx_t *tx)
+{
+	int error;
+
+	mutex_enter(&hdl->sa_lock);
+	error = sa_replace_all_by_template_locked(hdl, attr_desc,
+	    attr_count, tx);
+	mutex_exit(&hdl->sa_lock);
+	return (error);
+}
+
+/*
+ * add/remove/replace a single attribute and then rewrite the entire set
+ * of attributes.
+ */
+static int
+sa_modify_attrs(sa_handle_t *hdl, sa_attr_type_t newattr,
+    sa_data_op_t action, sa_data_locator_t *locator, void *datastart,
+    uint16_t buflen, dmu_tx_t *tx)
+{
+	sa_os_t *sa = hdl->sa_os->os_sa;
+	dmu_buf_impl_t *db = (dmu_buf_impl_t *)hdl->sa_bonus;
+	dnode_t *dn;
+	sa_bulk_attr_t *attr_desc;
+	void *old_data[2];
+	int bonus_attr_count = 0;
+	int bonus_data_size = 0;
+	int spill_data_size = 0;
+	int spill_attr_count = 0;
+	int error;
+	uint16_t length;
+	int i, j, k, length_idx;
+	sa_hdr_phys_t *hdr;
+	sa_idx_tab_t *idx_tab;
+	int attr_count;
+	int count;
+
+	ASSERT(MUTEX_HELD(&hdl->sa_lock));
+
+	/* First make of copy of the old data */
+
+	DB_DNODE_ENTER(db);
+	dn = DB_DNODE(db);
+	if (dn->dn_bonuslen != 0) {
+		bonus_data_size = hdl->sa_bonus->db_size;
+		old_data[0] = kmem_alloc(bonus_data_size, KM_SLEEP);
+		bcopy(hdl->sa_bonus->db_data, old_data[0],
+		    hdl->sa_bonus->db_size);
+		bonus_attr_count = hdl->sa_bonus_tab->sa_layout->lot_attr_count;
+	} else {
+		old_data[0] = NULL;
+	}
+	DB_DNODE_EXIT(db);
+
+	/* Bring spill buffer online if it isn't currently */
+
+	if ((error = sa_get_spill(hdl)) == 0) {
+		spill_data_size = hdl->sa_spill->db_size;
+		old_data[1] = zio_buf_alloc(spill_data_size);
+		bcopy(hdl->sa_spill->db_data, old_data[1],
+		    hdl->sa_spill->db_size);
+		spill_attr_count =
+		    hdl->sa_spill_tab->sa_layout->lot_attr_count;
+	} else if (error && error != ENOENT) {
+		if (old_data[0])
+			kmem_free(old_data[0], bonus_data_size);
+		return (error);
+	} else {
+		old_data[1] = NULL;
+	}
+
+	/* build descriptor of all attributes */
+
+	attr_count = bonus_attr_count + spill_attr_count;
+	if (action == SA_ADD)
+		attr_count++;
+	else if (action == SA_REMOVE)
+		attr_count--;
+
+	attr_desc = kmem_zalloc(sizeof (sa_bulk_attr_t) * attr_count, KM_SLEEP);
+
+	/*
+	 * loop through bonus and spill buffer if it exists, and
+	 * build up new attr_descriptor to reset the attributes
+	 */
+	k = j = 0;
+	count = bonus_attr_count;
+	hdr = SA_GET_HDR(hdl, SA_BONUS);
+	idx_tab = SA_IDX_TAB_GET(hdl, SA_BONUS);
+	for (; k != 2; k++) {
+		/*
+		 * Iterate over each attribute in layout.  Fetch the
+		 * size of variable-length attributes needing rewrite
+		 * from sa_lengths[].
+		 */
+		for (i = 0, length_idx = 0; i != count; i++) {
+			sa_attr_type_t attr;
+
+			attr = idx_tab->sa_layout->lot_attrs[i];
+			length = SA_REGISTERED_LEN(sa, attr);
+			if (attr == newattr) {
+				if (length == 0)
+					++length_idx;
+				if (action == SA_REMOVE)
+					continue;
+				ASSERT(length == 0);
+				ASSERT(action == SA_REPLACE);
+				SA_ADD_BULK_ATTR(attr_desc, j, attr,
+				    locator, datastart, buflen);
+			} else {
+				if (length == 0)
+					length = hdr->sa_lengths[length_idx++];
+
+				SA_ADD_BULK_ATTR(attr_desc, j, attr,
+				    NULL, (void *)
+				    (TOC_OFF(idx_tab->sa_idx_tab[attr]) +
+				    (uintptr_t)old_data[k]), length);
+			}
+		}
+		if (k == 0 && hdl->sa_spill) {
+			hdr = SA_GET_HDR(hdl, SA_SPILL);
+			idx_tab = SA_IDX_TAB_GET(hdl, SA_SPILL);
+			count = spill_attr_count;
+		} else {
+			break;
+		}
+	}
+	if (action == SA_ADD) {
+		length = SA_REGISTERED_LEN(sa, newattr);
+		if (length == 0) {
+			length = buflen;
+		}
+		SA_ADD_BULK_ATTR(attr_desc, j, newattr, locator,
+		    datastart, length);
+	}
+
+	error = sa_build_layouts(hdl, attr_desc, attr_count, tx);
+
+	if (old_data[0])
+		kmem_free(old_data[0], bonus_data_size);
+	if (old_data[1])
+		zio_buf_free(old_data[1], spill_data_size);
+	kmem_free(attr_desc, sizeof (sa_bulk_attr_t) * attr_count);
+
+	return (error);
+}
+
+static int
+sa_bulk_update_impl(sa_handle_t *hdl, sa_bulk_attr_t *bulk, int count,
+    dmu_tx_t *tx)
+{
+	int error;
+	sa_os_t *sa = hdl->sa_os->os_sa;
+	dmu_object_type_t bonustype;
+	dmu_buf_t *saved_spill;
+
+	ASSERT(hdl);
+	ASSERT(MUTEX_HELD(&hdl->sa_lock));
+
+	bonustype = SA_BONUSTYPE_FROM_DB(SA_GET_DB(hdl, SA_BONUS));
+	saved_spill = hdl->sa_spill;
+
+	/* sync out registration table if necessary */
+	if (sa->sa_need_attr_registration)
+		sa_attr_register_sync(hdl, tx);
+
+	error = sa_attr_op(hdl, bulk, count, SA_UPDATE, tx);
+	if (error == 0 && !IS_SA_BONUSTYPE(bonustype) && sa->sa_update_cb)
+		sa->sa_update_cb(hdl, tx);
+
+	/*
+	 * If saved_spill is NULL and current sa_spill is not NULL that
+	 * means we increased the refcount of the spill buffer through
+	 * sa_get_spill() or dmu_spill_hold_by_dnode().  Therefore we
+	 * must release the hold before calling dmu_tx_commit() to avoid
+	 * making a copy of this buffer in dbuf_sync_leaf() due to the
+	 * reference count now being greater than 1.
+	 */
+	if (!saved_spill && hdl->sa_spill) {
+		if (hdl->sa_spill_tab) {
+			sa_idx_tab_rele(hdl->sa_os, hdl->sa_spill_tab);
+			hdl->sa_spill_tab = NULL;
+		}
+
+		dmu_buf_rele((dmu_buf_t *)hdl->sa_spill, NULL);
+		hdl->sa_spill = NULL;
+	}
+
+	return (error);
+}
+
+/*
+ * update or add new attribute
+ */
+int
+sa_update(sa_handle_t *hdl, sa_attr_type_t type,
+    void *buf, uint32_t buflen, dmu_tx_t *tx)
+{
+	int error;
+	sa_bulk_attr_t bulk;
+
+	VERIFY3U(buflen, <=, SA_ATTR_MAX_LEN);
+
+	bulk.sa_attr = type;
+	bulk.sa_data_func = NULL;
+	bulk.sa_length = buflen;
+	bulk.sa_data = buf;
+
+	mutex_enter(&hdl->sa_lock);
+	error = sa_bulk_update_impl(hdl, &bulk, 1, tx);
+	mutex_exit(&hdl->sa_lock);
+	return (error);
+}
+
+int
+sa_update_from_cb(sa_handle_t *hdl, sa_attr_type_t attr,
+    uint32_t buflen, sa_data_locator_t *locator, void *userdata, dmu_tx_t *tx)
+{
+	int error;
+	sa_bulk_attr_t bulk;
+
+	VERIFY3U(buflen, <=, SA_ATTR_MAX_LEN);
+
+	bulk.sa_attr = attr;
+	bulk.sa_data = userdata;
+	bulk.sa_data_func = locator;
+	bulk.sa_length = buflen;
+
+	mutex_enter(&hdl->sa_lock);
+	error = sa_bulk_update_impl(hdl, &bulk, 1, tx);
+	mutex_exit(&hdl->sa_lock);
+	return (error);
+}
+
+/*
+ * Return size of an attribute
+ */
+
+int
+sa_size(sa_handle_t *hdl, sa_attr_type_t attr, int *size)
+{
+	sa_bulk_attr_t bulk;
+	int error;
+
+	bulk.sa_data = NULL;
+	bulk.sa_attr = attr;
+	bulk.sa_data_func = NULL;
+
+	ASSERT(hdl);
+	mutex_enter(&hdl->sa_lock);
+	if ((error = sa_attr_op(hdl, &bulk, 1, SA_LOOKUP, NULL)) != 0) {
+		mutex_exit(&hdl->sa_lock);
+		return (error);
+	}
+	*size = bulk.sa_size;
+
+	mutex_exit(&hdl->sa_lock);
+	return (0);
+}
+
+int
+sa_bulk_lookup_locked(sa_handle_t *hdl, sa_bulk_attr_t *attrs, int count)
+{
+	ASSERT(hdl);
+	ASSERT(MUTEX_HELD(&hdl->sa_lock));
+	return (sa_lookup_impl(hdl, attrs, count));
+}
+
+int
+sa_bulk_lookup(sa_handle_t *hdl, sa_bulk_attr_t *attrs, int count)
+{
+	int error;
+
+	ASSERT(hdl);
+	mutex_enter(&hdl->sa_lock);
+	error = sa_bulk_lookup_locked(hdl, attrs, count);
+	mutex_exit(&hdl->sa_lock);
+	return (error);
+}
+
+int
+sa_bulk_update(sa_handle_t *hdl, sa_bulk_attr_t *attrs, int count, dmu_tx_t *tx)
+{
+	int error;
+
+	ASSERT(hdl);
+	mutex_enter(&hdl->sa_lock);
+	error = sa_bulk_update_impl(hdl, attrs, count, tx);
+	mutex_exit(&hdl->sa_lock);
+	return (error);
+}
+
+int
+sa_remove(sa_handle_t *hdl, sa_attr_type_t attr, dmu_tx_t *tx)
+{
+	int error;
+
+	mutex_enter(&hdl->sa_lock);
+	error = sa_modify_attrs(hdl, attr, SA_REMOVE, NULL,
+	    NULL, 0, tx);
+	mutex_exit(&hdl->sa_lock);
+	return (error);
+}
+
+void
+sa_object_info(sa_handle_t *hdl, dmu_object_info_t *doi)
+{
+	dmu_object_info_from_db((dmu_buf_t *)hdl->sa_bonus, doi);
+}
+
+void
+sa_object_size(sa_handle_t *hdl, uint32_t *blksize, u_longlong_t *nblocks)
+{
+	dmu_object_size_from_db((dmu_buf_t *)hdl->sa_bonus,
+	    blksize, nblocks);
+}
+
+void
+sa_set_userp(sa_handle_t *hdl, void *ptr)
+{
+	hdl->sa_userp = ptr;
+}
+
+dmu_buf_t *
+sa_get_db(sa_handle_t *hdl)
+{
+	return ((dmu_buf_t *)hdl->sa_bonus);
+}
+
+void *
+sa_get_userdata(sa_handle_t *hdl)
+{
+	return (hdl->sa_userp);
+}
+
+void
+sa_register_update_callback_locked(objset_t *os, sa_update_cb_t *func)
+{
+	ASSERT(MUTEX_HELD(&os->os_sa->sa_lock));
+	os->os_sa->sa_update_cb = func;
+}
+
+void
+sa_register_update_callback(objset_t *os, sa_update_cb_t *func)
+{
+
+	mutex_enter(&os->os_sa->sa_lock);
+	sa_register_update_callback_locked(os, func);
+	mutex_exit(&os->os_sa->sa_lock);
+}
+
+uint64_t
+sa_handle_object(sa_handle_t *hdl)
+{
+	return (hdl->sa_bonus->db_object);
+}
+
+boolean_t
+sa_enabled(objset_t *os)
+{
+	return (os->os_sa == NULL);
+}
+
+int
+sa_set_sa_object(objset_t *os, uint64_t sa_object)
+{
+	sa_os_t *sa = os->os_sa;
+
+	if (sa->sa_master_obj)
+		return (1);
+
+	sa->sa_master_obj = sa_object;
+
+	return (0);
+}
+
+int
+sa_hdrsize(void *arg)
+{
+	sa_hdr_phys_t *hdr = arg;
+
+	return (SA_HDR_SIZE(hdr));
+}
+
+void
+sa_handle_lock(sa_handle_t *hdl)
+{
+	ASSERT(hdl);
+	mutex_enter(&hdl->sa_lock);
+}
+
+void
+sa_handle_unlock(sa_handle_t *hdl)
+{
+	ASSERT(hdl);
+	mutex_exit(&hdl->sa_lock);
+}
+
+#ifdef _KERNEL
+EXPORT_SYMBOL(sa_handle_get);
+EXPORT_SYMBOL(sa_handle_get_from_db);
+EXPORT_SYMBOL(sa_handle_destroy);
+EXPORT_SYMBOL(sa_buf_hold);
+EXPORT_SYMBOL(sa_buf_rele);
+EXPORT_SYMBOL(sa_spill_rele);
+EXPORT_SYMBOL(sa_lookup);
+EXPORT_SYMBOL(sa_update);
+EXPORT_SYMBOL(sa_remove);
+EXPORT_SYMBOL(sa_bulk_lookup);
+EXPORT_SYMBOL(sa_bulk_lookup_locked);
+EXPORT_SYMBOL(sa_bulk_update);
+EXPORT_SYMBOL(sa_size);
+EXPORT_SYMBOL(sa_update_from_cb);
+EXPORT_SYMBOL(sa_object_info);
+EXPORT_SYMBOL(sa_object_size);
+EXPORT_SYMBOL(sa_get_userdata);
+EXPORT_SYMBOL(sa_set_userp);
+EXPORT_SYMBOL(sa_get_db);
+EXPORT_SYMBOL(sa_handle_object);
+EXPORT_SYMBOL(sa_register_update_callback);
+EXPORT_SYMBOL(sa_setup);
+EXPORT_SYMBOL(sa_replace_all_by_template);
+EXPORT_SYMBOL(sa_replace_all_by_template_locked);
+EXPORT_SYMBOL(sa_enabled);
+EXPORT_SYMBOL(sa_cache_init);
+EXPORT_SYMBOL(sa_cache_fini);
+EXPORT_SYMBOL(sa_set_sa_object);
+EXPORT_SYMBOL(sa_hdrsize);
+EXPORT_SYMBOL(sa_handle_lock);
+EXPORT_SYMBOL(sa_handle_unlock);
+EXPORT_SYMBOL(sa_lookup_uio);
+#endif /* _KERNEL */
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/module/zfs/sha256.c
@@ -0,0 +1,127 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#include <sys/zfs_context.h>
+#include <sys/zio.h>
+#include <sys/zio_checksum.h>
+
+/*
+ * SHA-256 checksum, as specified in FIPS 180-3, available at:
+ * http://csrc.nist.gov/publications/PubsFIPS.html
+ *
+ * This is a very compact implementation of SHA-256.
+ * It is designed to be simple and portable, not to be fast.
+ */
+
+/*
+ * The literal definitions of Ch() and Maj() according to FIPS 180-3 are:
+ *
+ * 	Ch(x, y, z)     (x & y) ^ (~x & z)
+ * 	Maj(x, y, z)    (x & y) ^ (x & z) ^ (y & z)
+ *
+ * We use equivalent logical reductions here that require one less op.
+ */
+#define	Ch(x, y, z)	((z) ^ ((x) & ((y) ^ (z))))
+#define	Maj(x, y, z)	(((x) & (y)) ^ ((z) & ((x) ^ (y))))
+#define	Rot32(x, s)	(((x) >> s) | ((x) << (32 - s)))
+#define	SIGMA0(x)	(Rot32(x, 2) ^ Rot32(x, 13) ^ Rot32(x, 22))
+#define	SIGMA1(x)	(Rot32(x, 6) ^ Rot32(x, 11) ^ Rot32(x, 25))
+#define	sigma0(x)	(Rot32(x, 7) ^ Rot32(x, 18) ^ ((x) >> 3))
+#define	sigma1(x)	(Rot32(x, 17) ^ Rot32(x, 19) ^ ((x) >> 10))
+
+static const uint32_t SHA256_K[64] = {
+	0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
+	0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
+	0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
+	0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
+	0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
+	0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
+	0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
+	0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
+	0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
+	0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
+	0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
+	0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
+	0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
+	0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
+	0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
+	0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
+};
+
+static void
+SHA256Transform(uint32_t *H, const uint8_t *cp)
+{
+	uint32_t a, b, c, d, e, f, g, h, t, T1, T2, W[64];
+
+	for (t = 0; t < 16; t++, cp += 4)
+		W[t] = (cp[0] << 24) | (cp[1] << 16) | (cp[2] << 8) | cp[3];
+
+	for (t = 16; t < 64; t++)
+		W[t] = sigma1(W[t - 2]) + W[t - 7] +
+		    sigma0(W[t - 15]) + W[t - 16];
+
+	a = H[0]; b = H[1]; c = H[2]; d = H[3];
+	e = H[4]; f = H[5]; g = H[6]; h = H[7];
+
+	for (t = 0; t < 64; t++) {
+		T1 = h + SIGMA1(e) + Ch(e, f, g) + SHA256_K[t] + W[t];
+		T2 = SIGMA0(a) + Maj(a, b, c);
+		h = g; g = f; f = e; e = d + T1;
+		d = c; c = b; b = a; a = T1 + T2;
+	}
+
+	H[0] += a; H[1] += b; H[2] += c; H[3] += d;
+	H[4] += e; H[5] += f; H[6] += g; H[7] += h;
+}
+
+void
+zio_checksum_SHA256(const void *buf, uint64_t size, zio_cksum_t *zcp)
+{
+	uint32_t H[8] = { 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
+	    0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19 };
+	uint8_t pad[128];
+	int i, padsize;
+
+	for (i = 0; i < (size & ~63ULL); i += 64)
+		SHA256Transform(H, (uint8_t *)buf + i);
+
+	for (padsize = 0; i < size; i++)
+		pad[padsize++] = *((uint8_t *)buf + i);
+
+	for (pad[padsize++] = 0x80; (padsize & 63) != 56; padsize++)
+		pad[padsize] = 0;
+
+	for (i = 56; i >= 0; i -= 8)
+		pad[padsize++] = (size << 3) >> i;
+
+	for (i = 0; i < padsize; i += 64)
+		SHA256Transform(H, pad + i);
+
+	ZIO_SET_CHECKSUM(zcp,
+	    (uint64_t)H[0] << 32 | H[1],
+	    (uint64_t)H[2] << 32 | H[3],
+	    (uint64_t)H[4] << 32 | H[5],
+	    (uint64_t)H[6] << 32 | H[7]);
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/module/zfs/spa.c
@@ -0,0 +1,6835 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013 by Delphix. All rights reserved.
+ * Copyright (c) 2013, 2014, Nexenta Systems, Inc.  All rights reserved.
+ * Copyright (c) 2014 Spectra Logic Corporation, All rights reserved.
+ * Copyright (c) 2016 Actifio, Inc. All rights reserved.
+ */
+
+/*
+ * SPA: Storage Pool Allocator
+ *
+ * This file contains all the routines used when modifying on-disk SPA state.
+ * This includes opening, importing, destroying, exporting a pool, and syncing a
+ * pool.
+ */
+
+#include <sys/zfs_context.h>
+#include <sys/fm/fs/zfs.h>
+#include <sys/spa_impl.h>
+#include <sys/zio.h>
+#include <sys/zio_checksum.h>
+#include <sys/dmu.h>
+#include <sys/dmu_tx.h>
+#include <sys/zap.h>
+#include <sys/zil.h>
+#include <sys/ddt.h>
+#include <sys/vdev_impl.h>
+#include <sys/vdev_disk.h>
+#include <sys/metaslab.h>
+#include <sys/metaslab_impl.h>
+#include <sys/uberblock_impl.h>
+#include <sys/txg.h>
+#include <sys/avl.h>
+#include <sys/dmu_traverse.h>
+#include <sys/dmu_objset.h>
+#include <sys/unique.h>
+#include <sys/dsl_pool.h>
+#include <sys/dsl_dataset.h>
+#include <sys/dsl_dir.h>
+#include <sys/dsl_prop.h>
+#include <sys/dsl_synctask.h>
+#include <sys/fs/zfs.h>
+#include <sys/arc.h>
+#include <sys/callb.h>
+#include <sys/systeminfo.h>
+#include <sys/spa_boot.h>
+#include <sys/zfs_ioctl.h>
+#include <sys/dsl_scan.h>
+#include <sys/zfeature.h>
+#include <sys/dsl_destroy.h>
+#include <sys/zvol.h>
+
+#ifdef	_KERNEL
+#include <sys/bootprops.h>
+#include <sys/callb.h>
+#include <sys/cpupart.h>
+#include <sys/pool.h>
+#include <sys/sysdc.h>
+#include <sys/zone.h>
+#endif	/* _KERNEL */
+
+#include "zfs_prop.h"
+#include "zfs_comutil.h"
+
+typedef enum zti_modes {
+	ZTI_MODE_FIXED,			/* value is # of threads (min 1) */
+	ZTI_MODE_BATCH,			/* cpu-intensive; value is ignored */
+	ZTI_MODE_NULL,			/* don't create a taskq */
+	ZTI_NMODES
+} zti_modes_t;
+
+#define	ZTI_P(n, q)	{ ZTI_MODE_FIXED, (n), (q) }
+#define	ZTI_PCT(n)	{ ZTI_MODE_ONLINE_PERCENT, (n), 1 }
+#define	ZTI_BATCH	{ ZTI_MODE_BATCH, 0, 1 }
+#define	ZTI_NULL	{ ZTI_MODE_NULL, 0, 0 }
+
+#define	ZTI_N(n)	ZTI_P(n, 1)
+#define	ZTI_ONE		ZTI_N(1)
+
+typedef struct zio_taskq_info {
+	zti_modes_t zti_mode;
+	uint_t zti_value;
+	uint_t zti_count;
+} zio_taskq_info_t;
+
+static const char *const zio_taskq_types[ZIO_TASKQ_TYPES] = {
+	"iss", "iss_h", "int", "int_h"
+};
+
+/*
+ * This table defines the taskq settings for each ZFS I/O type. When
+ * initializing a pool, we use this table to create an appropriately sized
+ * taskq. Some operations are low volume and therefore have a small, static
+ * number of threads assigned to their taskqs using the ZTI_N(#) or ZTI_ONE
+ * macros. Other operations process a large amount of data; the ZTI_BATCH
+ * macro causes us to create a taskq oriented for throughput. Some operations
+ * are so high frequency and short-lived that the taskq itself can become a a
+ * point of lock contention. The ZTI_P(#, #) macro indicates that we need an
+ * additional degree of parallelism specified by the number of threads per-
+ * taskq and the number of taskqs; when dispatching an event in this case, the
+ * particular taskq is chosen at random.
+ *
+ * The different taskq priorities are to handle the different contexts (issue
+ * and interrupt) and then to reserve threads for ZIO_PRIORITY_NOW I/Os that
+ * need to be handled with minimum delay.
+ */
+const zio_taskq_info_t zio_taskqs[ZIO_TYPES][ZIO_TASKQ_TYPES] = {
+	/* ISSUE	ISSUE_HIGH	INTR		INTR_HIGH */
+	{ ZTI_ONE,	ZTI_NULL,	ZTI_ONE,	ZTI_NULL }, /* NULL */
+	{ ZTI_N(8),	ZTI_NULL,	ZTI_P(12, 8),	ZTI_NULL }, /* READ */
+	{ ZTI_BATCH,	ZTI_N(5),	ZTI_P(12, 8),	ZTI_N(5) }, /* WRITE */
+	{ ZTI_P(12, 8),	ZTI_NULL,	ZTI_ONE,	ZTI_NULL }, /* FREE */
+	{ ZTI_ONE,	ZTI_NULL,	ZTI_ONE,	ZTI_NULL }, /* CLAIM */
+	{ ZTI_ONE,	ZTI_NULL,	ZTI_ONE,	ZTI_NULL }, /* IOCTL */
+};
+
+static void spa_sync_version(void *arg, dmu_tx_t *tx);
+static void spa_sync_props(void *arg, dmu_tx_t *tx);
+static boolean_t spa_has_active_shared_spare(spa_t *spa);
+static inline int spa_load_impl(spa_t *spa, uint64_t, nvlist_t *config,
+    spa_load_state_t state, spa_import_type_t type, boolean_t mosconfig,
+    char **ereport);
+static void spa_vdev_resilver_done(spa_t *spa);
+
+uint_t		zio_taskq_batch_pct = 75;	/* 1 thread per cpu in pset */
+id_t		zio_taskq_psrset_bind = PS_NONE;
+boolean_t	zio_taskq_sysdc = B_TRUE;	/* use SDC scheduling class */
+uint_t		zio_taskq_basedc = 80;		/* base duty cycle */
+
+boolean_t	spa_create_process = B_TRUE;	/* no process ==> no sysdc */
+
+/*
+ * This (illegal) pool name is used when temporarily importing a spa_t in order
+ * to get the vdev stats associated with the imported devices.
+ */
+#define	TRYIMPORT_NAME	"$import"
+
+/*
+ * ==========================================================================
+ * SPA properties routines
+ * ==========================================================================
+ */
+
+/*
+ * Add a (source=src, propname=propval) list to an nvlist.
+ */
+static void
+spa_prop_add_list(nvlist_t *nvl, zpool_prop_t prop, char *strval,
+    uint64_t intval, zprop_source_t src)
+{
+	const char *propname = zpool_prop_to_name(prop);
+	nvlist_t *propval;
+
+	VERIFY(nvlist_alloc(&propval, NV_UNIQUE_NAME, KM_SLEEP) == 0);
+	VERIFY(nvlist_add_uint64(propval, ZPROP_SOURCE, src) == 0);
+
+	if (strval != NULL)
+		VERIFY(nvlist_add_string(propval, ZPROP_VALUE, strval) == 0);
+	else
+		VERIFY(nvlist_add_uint64(propval, ZPROP_VALUE, intval) == 0);
+
+	VERIFY(nvlist_add_nvlist(nvl, propname, propval) == 0);
+	nvlist_free(propval);
+}
+
+/*
+ * Get property values from the spa configuration.
+ */
+static void
+spa_prop_get_config(spa_t *spa, nvlist_t **nvp)
+{
+	vdev_t *rvd = spa->spa_root_vdev;
+	dsl_pool_t *pool = spa->spa_dsl_pool;
+	uint64_t size, alloc, cap, version;
+	zprop_source_t src = ZPROP_SRC_NONE;
+	spa_config_dirent_t *dp;
+	metaslab_class_t *mc = spa_normal_class(spa);
+
+	ASSERT(MUTEX_HELD(&spa->spa_props_lock));
+
+	if (rvd != NULL) {
+		alloc = metaslab_class_get_alloc(spa_normal_class(spa));
+		size = metaslab_class_get_space(spa_normal_class(spa));
+		spa_prop_add_list(*nvp, ZPOOL_PROP_NAME, spa_name(spa), 0, src);
+		spa_prop_add_list(*nvp, ZPOOL_PROP_SIZE, NULL, size, src);
+		spa_prop_add_list(*nvp, ZPOOL_PROP_ALLOCATED, NULL, alloc, src);
+		spa_prop_add_list(*nvp, ZPOOL_PROP_FREE, NULL,
+		    size - alloc, src);
+
+		spa_prop_add_list(*nvp, ZPOOL_PROP_FRAGMENTATION, NULL,
+		    metaslab_class_fragmentation(mc), src);
+		spa_prop_add_list(*nvp, ZPOOL_PROP_EXPANDSZ, NULL,
+		    metaslab_class_expandable_space(mc), src);
+		spa_prop_add_list(*nvp, ZPOOL_PROP_READONLY, NULL,
+		    (spa_mode(spa) == FREAD), src);
+
+		cap = (size == 0) ? 0 : (alloc * 100 / size);
+		spa_prop_add_list(*nvp, ZPOOL_PROP_CAPACITY, NULL, cap, src);
+
+		spa_prop_add_list(*nvp, ZPOOL_PROP_DEDUPRATIO, NULL,
+		    ddt_get_pool_dedup_ratio(spa), src);
+
+		spa_prop_add_list(*nvp, ZPOOL_PROP_HEALTH, NULL,
+		    rvd->vdev_state, src);
+
+		version = spa_version(spa);
+		if (version == zpool_prop_default_numeric(ZPOOL_PROP_VERSION))
+			src = ZPROP_SRC_DEFAULT;
+		else
+			src = ZPROP_SRC_LOCAL;
+		spa_prop_add_list(*nvp, ZPOOL_PROP_VERSION, NULL, version, src);
+	}
+
+	if (pool != NULL) {
+		/*
+		 * The $FREE directory was introduced in SPA_VERSION_DEADLISTS,
+		 * when opening pools before this version freedir will be NULL.
+		 */
+		if (pool->dp_free_dir != NULL) {
+			spa_prop_add_list(*nvp, ZPOOL_PROP_FREEING, NULL,
+			    dsl_dir_phys(pool->dp_free_dir)->dd_used_bytes,
+			    src);
+		} else {
+			spa_prop_add_list(*nvp, ZPOOL_PROP_FREEING,
+			    NULL, 0, src);
+		}
+
+		if (pool->dp_leak_dir != NULL) {
+			spa_prop_add_list(*nvp, ZPOOL_PROP_LEAKED, NULL,
+			    dsl_dir_phys(pool->dp_leak_dir)->dd_used_bytes,
+			    src);
+		} else {
+			spa_prop_add_list(*nvp, ZPOOL_PROP_LEAKED,
+			    NULL, 0, src);
+		}
+	}
+
+	spa_prop_add_list(*nvp, ZPOOL_PROP_GUID, NULL, spa_guid(spa), src);
+
+	if (spa->spa_comment != NULL) {
+		spa_prop_add_list(*nvp, ZPOOL_PROP_COMMENT, spa->spa_comment,
+		    0, ZPROP_SRC_LOCAL);
+	}
+
+	if (spa->spa_root != NULL)
+		spa_prop_add_list(*nvp, ZPOOL_PROP_ALTROOT, spa->spa_root,
+		    0, ZPROP_SRC_LOCAL);
+
+	if (spa_feature_is_enabled(spa, SPA_FEATURE_LARGE_BLOCKS)) {
+		spa_prop_add_list(*nvp, ZPOOL_PROP_MAXBLOCKSIZE, NULL,
+		    MIN(zfs_max_recordsize, SPA_MAXBLOCKSIZE), ZPROP_SRC_NONE);
+	} else {
+		spa_prop_add_list(*nvp, ZPOOL_PROP_MAXBLOCKSIZE, NULL,
+		    SPA_OLD_MAXBLOCKSIZE, ZPROP_SRC_NONE);
+	}
+
+	if ((dp = list_head(&spa->spa_config_list)) != NULL) {
+		if (dp->scd_path == NULL) {
+			spa_prop_add_list(*nvp, ZPOOL_PROP_CACHEFILE,
+			    "none", 0, ZPROP_SRC_LOCAL);
+		} else if (strcmp(dp->scd_path, spa_config_path) != 0) {
+			spa_prop_add_list(*nvp, ZPOOL_PROP_CACHEFILE,
+			    dp->scd_path, 0, ZPROP_SRC_LOCAL);
+		}
+	}
+}
+
+/*
+ * Get zpool property values.
+ */
+int
+spa_prop_get(spa_t *spa, nvlist_t **nvp)
+{
+	objset_t *mos = spa->spa_meta_objset;
+	zap_cursor_t zc;
+	zap_attribute_t za;
+	int err;
+
+	err = nvlist_alloc(nvp, NV_UNIQUE_NAME, KM_SLEEP);
+	if (err)
+		return (err);
+
+	mutex_enter(&spa->spa_props_lock);
+
+	/*
+	 * Get properties from the spa config.
+	 */
+	spa_prop_get_config(spa, nvp);
+
+	/* If no pool property object, no more prop to get. */
+	if (mos == NULL || spa->spa_pool_props_object == 0) {
+		mutex_exit(&spa->spa_props_lock);
+		goto out;
+	}
+
+	/*
+	 * Get properties from the MOS pool property object.
+	 */
+	for (zap_cursor_init(&zc, mos, spa->spa_pool_props_object);
+	    (err = zap_cursor_retrieve(&zc, &za)) == 0;
+	    zap_cursor_advance(&zc)) {
+		uint64_t intval = 0;
+		char *strval = NULL;
+		zprop_source_t src = ZPROP_SRC_DEFAULT;
+		zpool_prop_t prop;
+
+		if ((prop = zpool_name_to_prop(za.za_name)) == ZPROP_INVAL)
+			continue;
+
+		switch (za.za_integer_length) {
+		case 8:
+			/* integer property */
+			if (za.za_first_integer !=
+			    zpool_prop_default_numeric(prop))
+				src = ZPROP_SRC_LOCAL;
+
+			if (prop == ZPOOL_PROP_BOOTFS) {
+				dsl_pool_t *dp;
+				dsl_dataset_t *ds = NULL;
+
+				dp = spa_get_dsl(spa);
+				dsl_pool_config_enter(dp, FTAG);
+				if ((err = dsl_dataset_hold_obj(dp,
+				    za.za_first_integer, FTAG, &ds))) {
+					dsl_pool_config_exit(dp, FTAG);
+					break;
+				}
+
+				strval = kmem_alloc(
+				    MAXNAMELEN + strlen(MOS_DIR_NAME) + 1,
+				    KM_SLEEP);
+				dsl_dataset_name(ds, strval);
+				dsl_dataset_rele(ds, FTAG);
+				dsl_pool_config_exit(dp, FTAG);
+			} else {
+				strval = NULL;
+				intval = za.za_first_integer;
+			}
+
+			spa_prop_add_list(*nvp, prop, strval, intval, src);
+
+			if (strval != NULL)
+				kmem_free(strval,
+				    MAXNAMELEN + strlen(MOS_DIR_NAME) + 1);
+
+			break;
+
+		case 1:
+			/* string property */
+			strval = kmem_alloc(za.za_num_integers, KM_SLEEP);
+			err = zap_lookup(mos, spa->spa_pool_props_object,
+			    za.za_name, 1, za.za_num_integers, strval);
+			if (err) {
+				kmem_free(strval, za.za_num_integers);
+				break;
+			}
+			spa_prop_add_list(*nvp, prop, strval, 0, src);
+			kmem_free(strval, za.za_num_integers);
+			break;
+
+		default:
+			break;
+		}
+	}
+	zap_cursor_fini(&zc);
+	mutex_exit(&spa->spa_props_lock);
+out:
+	if (err && err != ENOENT) {
+		nvlist_free(*nvp);
+		*nvp = NULL;
+		return (err);
+	}
+
+	return (0);
+}
+
+/*
+ * Validate the given pool properties nvlist and modify the list
+ * for the property values to be set.
+ */
+static int
+spa_prop_validate(spa_t *spa, nvlist_t *props)
+{
+	nvpair_t *elem;
+	int error = 0, reset_bootfs = 0;
+	uint64_t objnum = 0;
+	boolean_t has_feature = B_FALSE;
+
+	elem = NULL;
+	while ((elem = nvlist_next_nvpair(props, elem)) != NULL) {
+		uint64_t intval;
+		char *strval, *slash, *check, *fname;
+		const char *propname = nvpair_name(elem);
+		zpool_prop_t prop = zpool_name_to_prop(propname);
+
+		switch ((int)prop) {
+		case ZPROP_INVAL:
+			if (!zpool_prop_feature(propname)) {
+				error = SET_ERROR(EINVAL);
+				break;
+			}
+
+			/*
+			 * Sanitize the input.
+			 */
+			if (nvpair_type(elem) != DATA_TYPE_UINT64) {
+				error = SET_ERROR(EINVAL);
+				break;
+			}
+
+			if (nvpair_value_uint64(elem, &intval) != 0) {
+				error = SET_ERROR(EINVAL);
+				break;
+			}
+
+			if (intval != 0) {
+				error = SET_ERROR(EINVAL);
+				break;
+			}
+
+			fname = strchr(propname, '@') + 1;
+			if (zfeature_lookup_name(fname, NULL) != 0) {
+				error = SET_ERROR(EINVAL);
+				break;
+			}
+
+			has_feature = B_TRUE;
+			break;
+
+		case ZPOOL_PROP_VERSION:
+			error = nvpair_value_uint64(elem, &intval);
+			if (!error &&
+			    (intval < spa_version(spa) ||
+			    intval > SPA_VERSION_BEFORE_FEATURES ||
+			    has_feature))
+				error = SET_ERROR(EINVAL);
+			break;
+
+		case ZPOOL_PROP_DELEGATION:
+		case ZPOOL_PROP_AUTOREPLACE:
+		case ZPOOL_PROP_LISTSNAPS:
+		case ZPOOL_PROP_AUTOEXPAND:
+			error = nvpair_value_uint64(elem, &intval);
+			if (!error && intval > 1)
+				error = SET_ERROR(EINVAL);
+			break;
+
+		case ZPOOL_PROP_BOOTFS:
+			/*
+			 * If the pool version is less than SPA_VERSION_BOOTFS,
+			 * or the pool is still being created (version == 0),
+			 * the bootfs property cannot be set.
+			 */
+			if (spa_version(spa) < SPA_VERSION_BOOTFS) {
+				error = SET_ERROR(ENOTSUP);
+				break;
+			}
+
+			/*
+			 * Make sure the vdev config is bootable
+			 */
+			if (!vdev_is_bootable(spa->spa_root_vdev)) {
+				error = SET_ERROR(ENOTSUP);
+				break;
+			}
+
+			reset_bootfs = 1;
+
+			error = nvpair_value_string(elem, &strval);
+
+			if (!error) {
+				objset_t *os;
+				uint64_t propval;
+
+				if (strval == NULL || strval[0] == '\0') {
+					objnum = zpool_prop_default_numeric(
+					    ZPOOL_PROP_BOOTFS);
+					break;
+				}
+
+				error = dmu_objset_hold(strval, FTAG, &os);
+				if (error)
+					break;
+
+				/*
+				 * Must be ZPL, and its property settings
+				 * must be supported by GRUB (compression
+				 * is not gzip, and large blocks are not used).
+				 */
+
+				if (dmu_objset_type(os) != DMU_OST_ZFS) {
+					error = SET_ERROR(ENOTSUP);
+				} else if ((error =
+				    dsl_prop_get_int_ds(dmu_objset_ds(os),
+				    zfs_prop_to_name(ZFS_PROP_COMPRESSION),
+				    &propval)) == 0 &&
+				    !BOOTFS_COMPRESS_VALID(propval)) {
+					error = SET_ERROR(ENOTSUP);
+				} else if ((error =
+				    dsl_prop_get_int_ds(dmu_objset_ds(os),
+				    zfs_prop_to_name(ZFS_PROP_RECORDSIZE),
+				    &propval)) == 0 &&
+				    propval > SPA_OLD_MAXBLOCKSIZE) {
+					error = SET_ERROR(ENOTSUP);
+				} else {
+					objnum = dmu_objset_id(os);
+				}
+				dmu_objset_rele(os, FTAG);
+			}
+			break;
+
+		case ZPOOL_PROP_FAILUREMODE:
+			error = nvpair_value_uint64(elem, &intval);
+			if (!error && (intval < ZIO_FAILURE_MODE_WAIT ||
+			    intval > ZIO_FAILURE_MODE_PANIC))
+				error = SET_ERROR(EINVAL);
+
+			/*
+			 * This is a special case which only occurs when
+			 * the pool has completely failed. This allows
+			 * the user to change the in-core failmode property
+			 * without syncing it out to disk (I/Os might
+			 * currently be blocked). We do this by returning
+			 * EIO to the caller (spa_prop_set) to trick it
+			 * into thinking we encountered a property validation
+			 * error.
+			 */
+			if (!error && spa_suspended(spa)) {
+				spa->spa_failmode = intval;
+				error = SET_ERROR(EIO);
+			}
+			break;
+
+		case ZPOOL_PROP_CACHEFILE:
+			if ((error = nvpair_value_string(elem, &strval)) != 0)
+				break;
+
+			if (strval[0] == '\0')
+				break;
+
+			if (strcmp(strval, "none") == 0)
+				break;
+
+			if (strval[0] != '/') {
+				error = SET_ERROR(EINVAL);
+				break;
+			}
+
+			slash = strrchr(strval, '/');
+			ASSERT(slash != NULL);
+
+			if (slash[1] == '\0' || strcmp(slash, "/.") == 0 ||
+			    strcmp(slash, "/..") == 0)
+				error = SET_ERROR(EINVAL);
+			break;
+
+		case ZPOOL_PROP_COMMENT:
+			if ((error = nvpair_value_string(elem, &strval)) != 0)
+				break;
+			for (check = strval; *check != '\0'; check++) {
+				if (!isprint(*check)) {
+					error = SET_ERROR(EINVAL);
+					break;
+				}
+				check++;
+			}
+			if (strlen(strval) > ZPROP_MAX_COMMENT)
+				error = SET_ERROR(E2BIG);
+			break;
+
+		case ZPOOL_PROP_DEDUPDITTO:
+			if (spa_version(spa) < SPA_VERSION_DEDUP)
+				error = SET_ERROR(ENOTSUP);
+			else
+				error = nvpair_value_uint64(elem, &intval);
+			if (error == 0 &&
+			    intval != 0 && intval < ZIO_DEDUPDITTO_MIN)
+				error = SET_ERROR(EINVAL);
+			break;
+
+		default:
+			break;
+		}
+
+		if (error)
+			break;
+	}
+
+	if (!error && reset_bootfs) {
+		error = nvlist_remove(props,
+		    zpool_prop_to_name(ZPOOL_PROP_BOOTFS), DATA_TYPE_STRING);
+
+		if (!error) {
+			error = nvlist_add_uint64(props,
+			    zpool_prop_to_name(ZPOOL_PROP_BOOTFS), objnum);
+		}
+	}
+
+	return (error);
+}
+
+void
+spa_configfile_set(spa_t *spa, nvlist_t *nvp, boolean_t need_sync)
+{
+	char *cachefile;
+	spa_config_dirent_t *dp;
+
+	if (nvlist_lookup_string(nvp, zpool_prop_to_name(ZPOOL_PROP_CACHEFILE),
+	    &cachefile) != 0)
+		return;
+
+	dp = kmem_alloc(sizeof (spa_config_dirent_t),
+	    KM_SLEEP);
+
+	if (cachefile[0] == '\0')
+		dp->scd_path = spa_strdup(spa_config_path);
+	else if (strcmp(cachefile, "none") == 0)
+		dp->scd_path = NULL;
+	else
+		dp->scd_path = spa_strdup(cachefile);
+
+	list_insert_head(&spa->spa_config_list, dp);
+	if (need_sync)
+		spa_async_request(spa, SPA_ASYNC_CONFIG_UPDATE);
+}
+
+int
+spa_prop_set(spa_t *spa, nvlist_t *nvp)
+{
+	int error;
+	nvpair_t *elem = NULL;
+	boolean_t need_sync = B_FALSE;
+
+	if ((error = spa_prop_validate(spa, nvp)) != 0)
+		return (error);
+
+	while ((elem = nvlist_next_nvpair(nvp, elem)) != NULL) {
+		zpool_prop_t prop = zpool_name_to_prop(nvpair_name(elem));
+
+		if (prop == ZPOOL_PROP_CACHEFILE ||
+		    prop == ZPOOL_PROP_ALTROOT ||
+		    prop == ZPOOL_PROP_READONLY)
+			continue;
+
+		if (prop == ZPOOL_PROP_VERSION || prop == ZPROP_INVAL) {
+			uint64_t ver;
+
+			if (prop == ZPOOL_PROP_VERSION) {
+				VERIFY(nvpair_value_uint64(elem, &ver) == 0);
+			} else {
+				ASSERT(zpool_prop_feature(nvpair_name(elem)));
+				ver = SPA_VERSION_FEATURES;
+				need_sync = B_TRUE;
+			}
+
+			/* Save time if the version is already set. */
+			if (ver == spa_version(spa))
+				continue;
+
+			/*
+			 * In addition to the pool directory object, we might
+			 * create the pool properties object, the features for
+			 * read object, the features for write object, or the
+			 * feature descriptions object.
+			 */
+			error = dsl_sync_task(spa->spa_name, NULL,
+			    spa_sync_version, &ver,
+			    6, ZFS_SPACE_CHECK_RESERVED);
+			if (error)
+				return (error);
+			continue;
+		}
+
+		need_sync = B_TRUE;
+		break;
+	}
+
+	if (need_sync) {
+		return (dsl_sync_task(spa->spa_name, NULL, spa_sync_props,
+		    nvp, 6, ZFS_SPACE_CHECK_RESERVED));
+	}
+
+	return (0);
+}
+
+/*
+ * If the bootfs property value is dsobj, clear it.
+ */
+void
+spa_prop_clear_bootfs(spa_t *spa, uint64_t dsobj, dmu_tx_t *tx)
+{
+	if (spa->spa_bootfs == dsobj && spa->spa_pool_props_object != 0) {
+		VERIFY(zap_remove(spa->spa_meta_objset,
+		    spa->spa_pool_props_object,
+		    zpool_prop_to_name(ZPOOL_PROP_BOOTFS), tx) == 0);
+		spa->spa_bootfs = 0;
+	}
+}
+
+/*ARGSUSED*/
+static int
+spa_change_guid_check(void *arg, dmu_tx_t *tx)
+{
+	spa_t *spa = dmu_tx_pool(tx)->dp_spa;
+	vdev_t *rvd = spa->spa_root_vdev;
+	uint64_t vdev_state;
+	ASSERTV(uint64_t *newguid = arg);
+
+	spa_config_enter(spa, SCL_STATE, FTAG, RW_READER);
+	vdev_state = rvd->vdev_state;
+	spa_config_exit(spa, SCL_STATE, FTAG);
+
+	if (vdev_state != VDEV_STATE_HEALTHY)
+		return (SET_ERROR(ENXIO));
+
+	ASSERT3U(spa_guid(spa), !=, *newguid);
+
+	return (0);
+}
+
+static void
+spa_change_guid_sync(void *arg, dmu_tx_t *tx)
+{
+	uint64_t *newguid = arg;
+	spa_t *spa = dmu_tx_pool(tx)->dp_spa;
+	uint64_t oldguid;
+	vdev_t *rvd = spa->spa_root_vdev;
+
+	oldguid = spa_guid(spa);
+
+	spa_config_enter(spa, SCL_STATE, FTAG, RW_READER);
+	rvd->vdev_guid = *newguid;
+	rvd->vdev_guid_sum += (*newguid - oldguid);
+	vdev_config_dirty(rvd);
+	spa_config_exit(spa, SCL_STATE, FTAG);
+
+	spa_history_log_internal(spa, "guid change", tx, "old=%llu new=%llu",
+	    oldguid, *newguid);
+}
+
+/*
+ * Change the GUID for the pool.  This is done so that we can later
+ * re-import a pool built from a clone of our own vdevs.  We will modify
+ * the root vdev's guid, our own pool guid, and then mark all of our
+ * vdevs dirty.  Note that we must make sure that all our vdevs are
+ * online when we do this, or else any vdevs that weren't present
+ * would be orphaned from our pool.  We are also going to issue a
+ * sysevent to update any watchers.
+ */
+int
+spa_change_guid(spa_t *spa)
+{
+	int error;
+	uint64_t guid;
+
+	mutex_enter(&spa->spa_vdev_top_lock);
+	mutex_enter(&spa_namespace_lock);
+	guid = spa_generate_guid(NULL);
+
+	error = dsl_sync_task(spa->spa_name, spa_change_guid_check,
+	    spa_change_guid_sync, &guid, 5, ZFS_SPACE_CHECK_RESERVED);
+
+	if (error == 0) {
+		spa_config_sync(spa, B_FALSE, B_TRUE);
+		spa_event_notify(spa, NULL, FM_EREPORT_ZFS_POOL_REGUID);
+	}
+
+	mutex_exit(&spa_namespace_lock);
+	mutex_exit(&spa->spa_vdev_top_lock);
+
+	return (error);
+}
+
+/*
+ * ==========================================================================
+ * SPA state manipulation (open/create/destroy/import/export)
+ * ==========================================================================
+ */
+
+static int
+spa_error_entry_compare(const void *a, const void *b)
+{
+	spa_error_entry_t *sa = (spa_error_entry_t *)a;
+	spa_error_entry_t *sb = (spa_error_entry_t *)b;
+	int ret;
+
+	ret = bcmp(&sa->se_bookmark, &sb->se_bookmark,
+	    sizeof (zbookmark_phys_t));
+
+	if (ret < 0)
+		return (-1);
+	else if (ret > 0)
+		return (1);
+	else
+		return (0);
+}
+
+/*
+ * Utility function which retrieves copies of the current logs and
+ * re-initializes them in the process.
+ */
+void
+spa_get_errlists(spa_t *spa, avl_tree_t *last, avl_tree_t *scrub)
+{
+	ASSERT(MUTEX_HELD(&spa->spa_errlist_lock));
+
+	bcopy(&spa->spa_errlist_last, last, sizeof (avl_tree_t));
+	bcopy(&spa->spa_errlist_scrub, scrub, sizeof (avl_tree_t));
+
+	avl_create(&spa->spa_errlist_scrub,
+	    spa_error_entry_compare, sizeof (spa_error_entry_t),
+	    offsetof(spa_error_entry_t, se_avl));
+	avl_create(&spa->spa_errlist_last,
+	    spa_error_entry_compare, sizeof (spa_error_entry_t),
+	    offsetof(spa_error_entry_t, se_avl));
+}
+
+static void
+spa_taskqs_init(spa_t *spa, zio_type_t t, zio_taskq_type_t q)
+{
+	const zio_taskq_info_t *ztip = &zio_taskqs[t][q];
+	enum zti_modes mode = ztip->zti_mode;
+	uint_t value = ztip->zti_value;
+	uint_t count = ztip->zti_count;
+	spa_taskqs_t *tqs = &spa->spa_zio_taskq[t][q];
+	char name[32];
+	uint_t i, flags = TASKQ_DYNAMIC;
+	boolean_t batch = B_FALSE;
+
+	if (mode == ZTI_MODE_NULL) {
+		tqs->stqs_count = 0;
+		tqs->stqs_taskq = NULL;
+		return;
+	}
+
+	ASSERT3U(count, >, 0);
+
+	tqs->stqs_count = count;
+	tqs->stqs_taskq = kmem_alloc(count * sizeof (taskq_t *), KM_SLEEP);
+
+	switch (mode) {
+	case ZTI_MODE_FIXED:
+		ASSERT3U(value, >=, 1);
+		value = MAX(value, 1);
+		break;
+
+	case ZTI_MODE_BATCH:
+		batch = B_TRUE;
+		flags |= TASKQ_THREADS_CPU_PCT;
+		value = MIN(zio_taskq_batch_pct, 100);
+		break;
+
+	default:
+		panic("unrecognized mode for %s_%s taskq (%u:%u) in "
+		    "spa_activate()",
+		    zio_type_name[t], zio_taskq_types[q], mode, value);
+		break;
+	}
+
+	for (i = 0; i < count; i++) {
+		taskq_t *tq;
+
+		if (count > 1) {
+			(void) snprintf(name, sizeof (name), "%s_%s_%u",
+			    zio_type_name[t], zio_taskq_types[q], i);
+		} else {
+			(void) snprintf(name, sizeof (name), "%s_%s",
+			    zio_type_name[t], zio_taskq_types[q]);
+		}
+
+		if (zio_taskq_sysdc && spa->spa_proc != &p0) {
+			if (batch)
+				flags |= TASKQ_DC_BATCH;
+
+			tq = taskq_create_sysdc(name, value, 50, INT_MAX,
+			    spa->spa_proc, zio_taskq_basedc, flags);
+		} else {
+			pri_t pri = maxclsyspri;
+			/*
+			 * The write issue taskq can be extremely CPU
+			 * intensive.  Run it at slightly less important
+			 * priority than the other taskqs.  Under Linux this
+			 * means incrementing the priority value on platforms
+			 * like illumos it should be decremented.
+			 */
+			if (t == ZIO_TYPE_WRITE && q == ZIO_TASKQ_ISSUE)
+				pri++;
+
+			tq = taskq_create_proc(name, value, pri, 50,
+			    INT_MAX, spa->spa_proc, flags);
+		}
+
+		tqs->stqs_taskq[i] = tq;
+	}
+}
+
+static void
+spa_taskqs_fini(spa_t *spa, zio_type_t t, zio_taskq_type_t q)
+{
+	spa_taskqs_t *tqs = &spa->spa_zio_taskq[t][q];
+	uint_t i;
+
+	if (tqs->stqs_taskq == NULL) {
+		ASSERT3U(tqs->stqs_count, ==, 0);
+		return;
+	}
+
+	for (i = 0; i < tqs->stqs_count; i++) {
+		ASSERT3P(tqs->stqs_taskq[i], !=, NULL);
+		taskq_destroy(tqs->stqs_taskq[i]);
+	}
+
+	kmem_free(tqs->stqs_taskq, tqs->stqs_count * sizeof (taskq_t *));
+	tqs->stqs_taskq = NULL;
+}
+
+/*
+ * Dispatch a task to the appropriate taskq for the ZFS I/O type and priority.
+ * Note that a type may have multiple discrete taskqs to avoid lock contention
+ * on the taskq itself. In that case we choose which taskq at random by using
+ * the low bits of gethrtime().
+ */
+void
+spa_taskq_dispatch_ent(spa_t *spa, zio_type_t t, zio_taskq_type_t q,
+    task_func_t *func, void *arg, uint_t flags, taskq_ent_t *ent)
+{
+	spa_taskqs_t *tqs = &spa->spa_zio_taskq[t][q];
+	taskq_t *tq;
+
+	ASSERT3P(tqs->stqs_taskq, !=, NULL);
+	ASSERT3U(tqs->stqs_count, !=, 0);
+
+	if (tqs->stqs_count == 1) {
+		tq = tqs->stqs_taskq[0];
+	} else {
+		tq = tqs->stqs_taskq[((uint64_t)gethrtime()) % tqs->stqs_count];
+	}
+
+	taskq_dispatch_ent(tq, func, arg, flags, ent);
+}
+
+/*
+ * Same as spa_taskq_dispatch_ent() but block on the task until completion.
+ */
+void
+spa_taskq_dispatch_sync(spa_t *spa, zio_type_t t, zio_taskq_type_t q,
+    task_func_t *func, void *arg, uint_t flags)
+{
+	spa_taskqs_t *tqs = &spa->spa_zio_taskq[t][q];
+	taskq_t *tq;
+	taskqid_t id;
+
+	ASSERT3P(tqs->stqs_taskq, !=, NULL);
+	ASSERT3U(tqs->stqs_count, !=, 0);
+
+	if (tqs->stqs_count == 1) {
+		tq = tqs->stqs_taskq[0];
+	} else {
+		tq = tqs->stqs_taskq[((uint64_t)gethrtime()) % tqs->stqs_count];
+	}
+
+	id = taskq_dispatch(tq, func, arg, flags);
+	if (id)
+		taskq_wait_id(tq, id);
+}
+
+static void
+spa_create_zio_taskqs(spa_t *spa)
+{
+	int t, q;
+
+	for (t = 0; t < ZIO_TYPES; t++) {
+		for (q = 0; q < ZIO_TASKQ_TYPES; q++) {
+			spa_taskqs_init(spa, t, q);
+		}
+	}
+}
+
+#if defined(_KERNEL) && defined(HAVE_SPA_THREAD)
+static void
+spa_thread(void *arg)
+{
+	callb_cpr_t cprinfo;
+
+	spa_t *spa = arg;
+	user_t *pu = PTOU(curproc);
+
+	CALLB_CPR_INIT(&cprinfo, &spa->spa_proc_lock, callb_generic_cpr,
+	    spa->spa_name);
+
+	ASSERT(curproc != &p0);
+	(void) snprintf(pu->u_psargs, sizeof (pu->u_psargs),
+	    "zpool-%s", spa->spa_name);
+	(void) strlcpy(pu->u_comm, pu->u_psargs, sizeof (pu->u_comm));
+
+	/* bind this thread to the requested psrset */
+	if (zio_taskq_psrset_bind != PS_NONE) {
+		pool_lock();
+		mutex_enter(&cpu_lock);
+		mutex_enter(&pidlock);
+		mutex_enter(&curproc->p_lock);
+
+		if (cpupart_bind_thread(curthread, zio_taskq_psrset_bind,
+		    0, NULL, NULL) == 0)  {
+			curthread->t_bind_pset = zio_taskq_psrset_bind;
+		} else {
+			cmn_err(CE_WARN,
+			    "Couldn't bind process for zfs pool \"%s\" to "
+			    "pset %d\n", spa->spa_name, zio_taskq_psrset_bind);
+		}
+
+		mutex_exit(&curproc->p_lock);
+		mutex_exit(&pidlock);
+		mutex_exit(&cpu_lock);
+		pool_unlock();
+	}
+
+	if (zio_taskq_sysdc) {
+		sysdc_thread_enter(curthread, 100, 0);
+	}
+
+	spa->spa_proc = curproc;
+	spa->spa_did = curthread->t_did;
+
+	spa_create_zio_taskqs(spa);
+
+	mutex_enter(&spa->spa_proc_lock);
+	ASSERT(spa->spa_proc_state == SPA_PROC_CREATED);
+
+	spa->spa_proc_state = SPA_PROC_ACTIVE;
+	cv_broadcast(&spa->spa_proc_cv);
+
+	CALLB_CPR_SAFE_BEGIN(&cprinfo);
+	while (spa->spa_proc_state == SPA_PROC_ACTIVE)
+		cv_wait(&spa->spa_proc_cv, &spa->spa_proc_lock);
+	CALLB_CPR_SAFE_END(&cprinfo, &spa->spa_proc_lock);
+
+	ASSERT(spa->spa_proc_state == SPA_PROC_DEACTIVATE);
+	spa->spa_proc_state = SPA_PROC_GONE;
+	spa->spa_proc = &p0;
+	cv_broadcast(&spa->spa_proc_cv);
+	CALLB_CPR_EXIT(&cprinfo);	/* drops spa_proc_lock */
+
+	mutex_enter(&curproc->p_lock);
+	lwp_exit();
+}
+#endif
+
+/*
+ * Activate an uninitialized pool.
+ */
+static void
+spa_activate(spa_t *spa, int mode)
+{
+	ASSERT(spa->spa_state == POOL_STATE_UNINITIALIZED);
+
+	spa->spa_state = POOL_STATE_ACTIVE;
+	spa->spa_mode = mode;
+
+	spa->spa_normal_class = metaslab_class_create(spa, zfs_metaslab_ops);
+	spa->spa_log_class = metaslab_class_create(spa, zfs_metaslab_ops);
+
+	/* Try to create a covering process */
+	mutex_enter(&spa->spa_proc_lock);
+	ASSERT(spa->spa_proc_state == SPA_PROC_NONE);
+	ASSERT(spa->spa_proc == &p0);
+	spa->spa_did = 0;
+
+#ifdef HAVE_SPA_THREAD
+	/* Only create a process if we're going to be around a while. */
+	if (spa_create_process && strcmp(spa->spa_name, TRYIMPORT_NAME) != 0) {
+		if (newproc(spa_thread, (caddr_t)spa, syscid, maxclsyspri,
+		    NULL, 0) == 0) {
+			spa->spa_proc_state = SPA_PROC_CREATED;
+			while (spa->spa_proc_state == SPA_PROC_CREATED) {
+				cv_wait(&spa->spa_proc_cv,
+				    &spa->spa_proc_lock);
+			}
+			ASSERT(spa->spa_proc_state == SPA_PROC_ACTIVE);
+			ASSERT(spa->spa_proc != &p0);
+			ASSERT(spa->spa_did != 0);
+		} else {
+#ifdef _KERNEL
+			cmn_err(CE_WARN,
+			    "Couldn't create process for zfs pool \"%s\"\n",
+			    spa->spa_name);
+#endif
+		}
+	}
+#endif /* HAVE_SPA_THREAD */
+	mutex_exit(&spa->spa_proc_lock);
+
+	/* If we didn't create a process, we need to create our taskqs. */
+	if (spa->spa_proc == &p0) {
+		spa_create_zio_taskqs(spa);
+	}
+
+	list_create(&spa->spa_config_dirty_list, sizeof (vdev_t),
+	    offsetof(vdev_t, vdev_config_dirty_node));
+	list_create(&spa->spa_evicting_os_list, sizeof (objset_t),
+	    offsetof(objset_t, os_evicting_node));
+	list_create(&spa->spa_state_dirty_list, sizeof (vdev_t),
+	    offsetof(vdev_t, vdev_state_dirty_node));
+
+	txg_list_create(&spa->spa_vdev_txg_list,
+	    offsetof(struct vdev, vdev_txg_node));
+
+	avl_create(&spa->spa_errlist_scrub,
+	    spa_error_entry_compare, sizeof (spa_error_entry_t),
+	    offsetof(spa_error_entry_t, se_avl));
+	avl_create(&spa->spa_errlist_last,
+	    spa_error_entry_compare, sizeof (spa_error_entry_t),
+	    offsetof(spa_error_entry_t, se_avl));
+
+	/*
+	 * This taskq is used to perform zvol-minor-related tasks
+	 * asynchronously. This has several advantages, including easy
+	 * resolution of various deadlocks (zfsonlinux bug #3681).
+	 *
+	 * The taskq must be single threaded to ensure tasks are always
+	 * processed in the order in which they were dispatched.
+	 *
+	 * A taskq per pool allows one to keep the pools independent.
+	 * This way if one pool is suspended, it will not impact another.
+	 *
+	 * The preferred location to dispatch a zvol minor task is a sync
+	 * task. In this context, there is easy access to the spa_t and minimal
+	 * error handling is required because the sync task must succeed.
+	 */
+	spa->spa_zvol_taskq = taskq_create("z_zvol", 1, defclsyspri,
+	    1, INT_MAX, 0);
+}
+
+/*
+ * Opposite of spa_activate().
+ */
+static void
+spa_deactivate(spa_t *spa)
+{
+	int t, q;
+
+	ASSERT(spa->spa_sync_on == B_FALSE);
+	ASSERT(spa->spa_dsl_pool == NULL);
+	ASSERT(spa->spa_root_vdev == NULL);
+	ASSERT(spa->spa_async_zio_root == NULL);
+	ASSERT(spa->spa_state != POOL_STATE_UNINITIALIZED);
+
+	spa_evicting_os_wait(spa);
+
+	if (spa->spa_zvol_taskq) {
+		taskq_destroy(spa->spa_zvol_taskq);
+		spa->spa_zvol_taskq = NULL;
+	}
+
+	txg_list_destroy(&spa->spa_vdev_txg_list);
+
+	list_destroy(&spa->spa_config_dirty_list);
+	list_destroy(&spa->spa_evicting_os_list);
+	list_destroy(&spa->spa_state_dirty_list);
+
+	taskq_cancel_id(system_taskq, spa->spa_deadman_tqid);
+
+	for (t = 0; t < ZIO_TYPES; t++) {
+		for (q = 0; q < ZIO_TASKQ_TYPES; q++) {
+			spa_taskqs_fini(spa, t, q);
+		}
+	}
+
+	metaslab_class_destroy(spa->spa_normal_class);
+	spa->spa_normal_class = NULL;
+
+	metaslab_class_destroy(spa->spa_log_class);
+	spa->spa_log_class = NULL;
+
+	/*
+	 * If this was part of an import or the open otherwise failed, we may
+	 * still have errors left in the queues.  Empty them just in case.
+	 */
+	spa_errlog_drain(spa);
+
+	avl_destroy(&spa->spa_errlist_scrub);
+	avl_destroy(&spa->spa_errlist_last);
+
+	spa->spa_state = POOL_STATE_UNINITIALIZED;
+
+	mutex_enter(&spa->spa_proc_lock);
+	if (spa->spa_proc_state != SPA_PROC_NONE) {
+		ASSERT(spa->spa_proc_state == SPA_PROC_ACTIVE);
+		spa->spa_proc_state = SPA_PROC_DEACTIVATE;
+		cv_broadcast(&spa->spa_proc_cv);
+		while (spa->spa_proc_state == SPA_PROC_DEACTIVATE) {
+			ASSERT(spa->spa_proc != &p0);
+			cv_wait(&spa->spa_proc_cv, &spa->spa_proc_lock);
+		}
+		ASSERT(spa->spa_proc_state == SPA_PROC_GONE);
+		spa->spa_proc_state = SPA_PROC_NONE;
+	}
+	ASSERT(spa->spa_proc == &p0);
+	mutex_exit(&spa->spa_proc_lock);
+
+	/*
+	 * We want to make sure spa_thread() has actually exited the ZFS
+	 * module, so that the module can't be unloaded out from underneath
+	 * it.
+	 */
+	if (spa->spa_did != 0) {
+		thread_join(spa->spa_did);
+		spa->spa_did = 0;
+	}
+}
+
+/*
+ * Verify a pool configuration, and construct the vdev tree appropriately.  This
+ * will create all the necessary vdevs in the appropriate layout, with each vdev
+ * in the CLOSED state.  This will prep the pool before open/creation/import.
+ * All vdev validation is done by the vdev_alloc() routine.
+ */
+static int
+spa_config_parse(spa_t *spa, vdev_t **vdp, nvlist_t *nv, vdev_t *parent,
+    uint_t id, int atype)
+{
+	nvlist_t **child;
+	uint_t children;
+	int error;
+	int c;
+
+	if ((error = vdev_alloc(spa, vdp, nv, parent, id, atype)) != 0)
+		return (error);
+
+	if ((*vdp)->vdev_ops->vdev_op_leaf)
+		return (0);
+
+	error = nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
+	    &child, &children);
+
+	if (error == ENOENT)
+		return (0);
+
+	if (error) {
+		vdev_free(*vdp);
+		*vdp = NULL;
+		return (SET_ERROR(EINVAL));
+	}
+
+	for (c = 0; c < children; c++) {
+		vdev_t *vd;
+		if ((error = spa_config_parse(spa, &vd, child[c], *vdp, c,
+		    atype)) != 0) {
+			vdev_free(*vdp);
+			*vdp = NULL;
+			return (error);
+		}
+	}
+
+	ASSERT(*vdp != NULL);
+
+	return (0);
+}
+
+/*
+ * Opposite of spa_load().
+ */
+static void
+spa_unload(spa_t *spa)
+{
+	int i;
+
+	ASSERT(MUTEX_HELD(&spa_namespace_lock));
+
+	/*
+	 * Stop async tasks.
+	 */
+	spa_async_suspend(spa);
+
+	/*
+	 * Stop syncing.
+	 */
+	if (spa->spa_sync_on) {
+		txg_sync_stop(spa->spa_dsl_pool);
+		spa->spa_sync_on = B_FALSE;
+	}
+
+	/*
+	 * Wait for any outstanding async I/O to complete.
+	 */
+	if (spa->spa_async_zio_root != NULL) {
+		for (i = 0; i < max_ncpus; i++)
+			(void) zio_wait(spa->spa_async_zio_root[i]);
+		kmem_free(spa->spa_async_zio_root, max_ncpus * sizeof (void *));
+		spa->spa_async_zio_root = NULL;
+	}
+
+	bpobj_close(&spa->spa_deferred_bpobj);
+
+	spa_config_enter(spa, SCL_ALL, FTAG, RW_WRITER);
+
+	/*
+	 * Close all vdevs.
+	 */
+	if (spa->spa_root_vdev)
+		vdev_free(spa->spa_root_vdev);
+	ASSERT(spa->spa_root_vdev == NULL);
+
+	/*
+	 * Close the dsl pool.
+	 */
+	if (spa->spa_dsl_pool) {
+		dsl_pool_close(spa->spa_dsl_pool);
+		spa->spa_dsl_pool = NULL;
+		spa->spa_meta_objset = NULL;
+	}
+
+	ddt_unload(spa);
+
+
+	/*
+	 * Drop and purge level 2 cache
+	 */
+	spa_l2cache_drop(spa);
+
+	for (i = 0; i < spa->spa_spares.sav_count; i++)
+		vdev_free(spa->spa_spares.sav_vdevs[i]);
+	if (spa->spa_spares.sav_vdevs) {
+		kmem_free(spa->spa_spares.sav_vdevs,
+		    spa->spa_spares.sav_count * sizeof (void *));
+		spa->spa_spares.sav_vdevs = NULL;
+	}
+	if (spa->spa_spares.sav_config) {
+		nvlist_free(spa->spa_spares.sav_config);
+		spa->spa_spares.sav_config = NULL;
+	}
+	spa->spa_spares.sav_count = 0;
+
+	for (i = 0; i < spa->spa_l2cache.sav_count; i++) {
+		vdev_clear_stats(spa->spa_l2cache.sav_vdevs[i]);
+		vdev_free(spa->spa_l2cache.sav_vdevs[i]);
+	}
+	if (spa->spa_l2cache.sav_vdevs) {
+		kmem_free(spa->spa_l2cache.sav_vdevs,
+		    spa->spa_l2cache.sav_count * sizeof (void *));
+		spa->spa_l2cache.sav_vdevs = NULL;
+	}
+	if (spa->spa_l2cache.sav_config) {
+		nvlist_free(spa->spa_l2cache.sav_config);
+		spa->spa_l2cache.sav_config = NULL;
+	}
+	spa->spa_l2cache.sav_count = 0;
+
+	spa->spa_async_suspended = 0;
+
+	if (spa->spa_comment != NULL) {
+		spa_strfree(spa->spa_comment);
+		spa->spa_comment = NULL;
+	}
+
+	spa_config_exit(spa, SCL_ALL, FTAG);
+}
+
+/*
+ * Load (or re-load) the current list of vdevs describing the active spares for
+ * this pool.  When this is called, we have some form of basic information in
+ * 'spa_spares.sav_config'.  We parse this into vdevs, try to open them, and
+ * then re-generate a more complete list including status information.
+ */
+static void
+spa_load_spares(spa_t *spa)
+{
+	nvlist_t **spares;
+	uint_t nspares;
+	int i;
+	vdev_t *vd, *tvd;
+
+	ASSERT(spa_config_held(spa, SCL_ALL, RW_WRITER) == SCL_ALL);
+
+	/*
+	 * First, close and free any existing spare vdevs.
+	 */
+	for (i = 0; i < spa->spa_spares.sav_count; i++) {
+		vd = spa->spa_spares.sav_vdevs[i];
+
+		/* Undo the call to spa_activate() below */
+		if ((tvd = spa_lookup_by_guid(spa, vd->vdev_guid,
+		    B_FALSE)) != NULL && tvd->vdev_isspare)
+			spa_spare_remove(tvd);
+		vdev_close(vd);
+		vdev_free(vd);
+	}
+
+	if (spa->spa_spares.sav_vdevs)
+		kmem_free(spa->spa_spares.sav_vdevs,
+		    spa->spa_spares.sav_count * sizeof (void *));
+
+	if (spa->spa_spares.sav_config == NULL)
+		nspares = 0;
+	else
+		VERIFY(nvlist_lookup_nvlist_array(spa->spa_spares.sav_config,
+		    ZPOOL_CONFIG_SPARES, &spares, &nspares) == 0);
+
+	spa->spa_spares.sav_count = (int)nspares;
+	spa->spa_spares.sav_vdevs = NULL;
+
+	if (nspares == 0)
+		return;
+
+	/*
+	 * Construct the array of vdevs, opening them to get status in the
+	 * process.   For each spare, there is potentially two different vdev_t
+	 * structures associated with it: one in the list of spares (used only
+	 * for basic validation purposes) and one in the active vdev
+	 * configuration (if it's spared in).  During this phase we open and
+	 * validate each vdev on the spare list.  If the vdev also exists in the
+	 * active configuration, then we also mark this vdev as an active spare.
+	 */
+	spa->spa_spares.sav_vdevs = kmem_zalloc(nspares * sizeof (void *),
+	    KM_SLEEP);
+	for (i = 0; i < spa->spa_spares.sav_count; i++) {
+		VERIFY(spa_config_parse(spa, &vd, spares[i], NULL, 0,
+		    VDEV_ALLOC_SPARE) == 0);
+		ASSERT(vd != NULL);
+
+		spa->spa_spares.sav_vdevs[i] = vd;
+
+		if ((tvd = spa_lookup_by_guid(spa, vd->vdev_guid,
+		    B_FALSE)) != NULL) {
+			if (!tvd->vdev_isspare)
+				spa_spare_add(tvd);
+
+			/*
+			 * We only mark the spare active if we were successfully
+			 * able to load the vdev.  Otherwise, importing a pool
+			 * with a bad active spare would result in strange
+			 * behavior, because multiple pool would think the spare
+			 * is actively in use.
+			 *
+			 * There is a vulnerability here to an equally bizarre
+			 * circumstance, where a dead active spare is later
+			 * brought back to life (onlined or otherwise).  Given
+			 * the rarity of this scenario, and the extra complexity
+			 * it adds, we ignore the possibility.
+			 */
+			if (!vdev_is_dead(tvd))
+				spa_spare_activate(tvd);
+		}
+
+		vd->vdev_top = vd;
+		vd->vdev_aux = &spa->spa_spares;
+
+		if (vdev_open(vd) != 0)
+			continue;
+
+		if (vdev_validate_aux(vd) == 0)
+			spa_spare_add(vd);
+	}
+
+	/*
+	 * Recompute the stashed list of spares, with status information
+	 * this time.
+	 */
+	VERIFY(nvlist_remove(spa->spa_spares.sav_config, ZPOOL_CONFIG_SPARES,
+	    DATA_TYPE_NVLIST_ARRAY) == 0);
+
+	spares = kmem_alloc(spa->spa_spares.sav_count * sizeof (void *),
+	    KM_SLEEP);
+	for (i = 0; i < spa->spa_spares.sav_count; i++)
+		spares[i] = vdev_config_generate(spa,
+		    spa->spa_spares.sav_vdevs[i], B_TRUE, VDEV_CONFIG_SPARE);
+	VERIFY(nvlist_add_nvlist_array(spa->spa_spares.sav_config,
+	    ZPOOL_CONFIG_SPARES, spares, spa->spa_spares.sav_count) == 0);
+	for (i = 0; i < spa->spa_spares.sav_count; i++)
+		nvlist_free(spares[i]);
+	kmem_free(spares, spa->spa_spares.sav_count * sizeof (void *));
+}
+
+/*
+ * Load (or re-load) the current list of vdevs describing the active l2cache for
+ * this pool.  When this is called, we have some form of basic information in
+ * 'spa_l2cache.sav_config'.  We parse this into vdevs, try to open them, and
+ * then re-generate a more complete list including status information.
+ * Devices which are already active have their details maintained, and are
+ * not re-opened.
+ */
+static void
+spa_load_l2cache(spa_t *spa)
+{
+	nvlist_t **l2cache;
+	uint_t nl2cache;
+	int i, j, oldnvdevs;
+	uint64_t guid;
+	vdev_t *vd, **oldvdevs, **newvdevs;
+	spa_aux_vdev_t *sav = &spa->spa_l2cache;
+
+	ASSERT(spa_config_held(spa, SCL_ALL, RW_WRITER) == SCL_ALL);
+
+	if (sav->sav_config != NULL) {
+		VERIFY(nvlist_lookup_nvlist_array(sav->sav_config,
+		    ZPOOL_CONFIG_L2CACHE, &l2cache, &nl2cache) == 0);
+		newvdevs = kmem_alloc(nl2cache * sizeof (void *), KM_SLEEP);
+	} else {
+		nl2cache = 0;
+		newvdevs = NULL;
+	}
+
+	oldvdevs = sav->sav_vdevs;
+	oldnvdevs = sav->sav_count;
+	sav->sav_vdevs = NULL;
+	sav->sav_count = 0;
+
+	/*
+	 * Process new nvlist of vdevs.
+	 */
+	for (i = 0; i < nl2cache; i++) {
+		VERIFY(nvlist_lookup_uint64(l2cache[i], ZPOOL_CONFIG_GUID,
+		    &guid) == 0);
+
+		newvdevs[i] = NULL;
+		for (j = 0; j < oldnvdevs; j++) {
+			vd = oldvdevs[j];
+			if (vd != NULL && guid == vd->vdev_guid) {
+				/*
+				 * Retain previous vdev for add/remove ops.
+				 */
+				newvdevs[i] = vd;
+				oldvdevs[j] = NULL;
+				break;
+			}
+		}
+
+		if (newvdevs[i] == NULL) {
+			/*
+			 * Create new vdev
+			 */
+			VERIFY(spa_config_parse(spa, &vd, l2cache[i], NULL, 0,
+			    VDEV_ALLOC_L2CACHE) == 0);
+			ASSERT(vd != NULL);
+			newvdevs[i] = vd;
+
+			/*
+			 * Commit this vdev as an l2cache device,
+			 * even if it fails to open.
+			 */
+			spa_l2cache_add(vd);
+
+			vd->vdev_top = vd;
+			vd->vdev_aux = sav;
+
+			spa_l2cache_activate(vd);
+
+			if (vdev_open(vd) != 0)
+				continue;
+
+			(void) vdev_validate_aux(vd);
+
+			if (!vdev_is_dead(vd))
+				l2arc_add_vdev(spa, vd);
+		}
+	}
+
+	/*
+	 * Purge vdevs that were dropped
+	 */
+	for (i = 0; i < oldnvdevs; i++) {
+		uint64_t pool;
+
+		vd = oldvdevs[i];
+		if (vd != NULL) {
+			ASSERT(vd->vdev_isl2cache);
+
+			if (spa_l2cache_exists(vd->vdev_guid, &pool) &&
+			    pool != 0ULL && l2arc_vdev_present(vd))
+				l2arc_remove_vdev(vd);
+			vdev_clear_stats(vd);
+			vdev_free(vd);
+		}
+	}
+
+	if (oldvdevs)
+		kmem_free(oldvdevs, oldnvdevs * sizeof (void *));
+
+	if (sav->sav_config == NULL)
+		goto out;
+
+	sav->sav_vdevs = newvdevs;
+	sav->sav_count = (int)nl2cache;
+
+	/*
+	 * Recompute the stashed list of l2cache devices, with status
+	 * information this time.
+	 */
+	VERIFY(nvlist_remove(sav->sav_config, ZPOOL_CONFIG_L2CACHE,
+	    DATA_TYPE_NVLIST_ARRAY) == 0);
+
+	l2cache = kmem_alloc(sav->sav_count * sizeof (void *), KM_SLEEP);
+	for (i = 0; i < sav->sav_count; i++)
+		l2cache[i] = vdev_config_generate(spa,
+		    sav->sav_vdevs[i], B_TRUE, VDEV_CONFIG_L2CACHE);
+	VERIFY(nvlist_add_nvlist_array(sav->sav_config,
+	    ZPOOL_CONFIG_L2CACHE, l2cache, sav->sav_count) == 0);
+out:
+	for (i = 0; i < sav->sav_count; i++)
+		nvlist_free(l2cache[i]);
+	if (sav->sav_count)
+		kmem_free(l2cache, sav->sav_count * sizeof (void *));
+}
+
+static int
+load_nvlist(spa_t *spa, uint64_t obj, nvlist_t **value)
+{
+	dmu_buf_t *db;
+	char *packed = NULL;
+	size_t nvsize = 0;
+	int error;
+	*value = NULL;
+
+	error = dmu_bonus_hold(spa->spa_meta_objset, obj, FTAG, &db);
+	if (error)
+		return (error);
+
+	nvsize = *(uint64_t *)db->db_data;
+	dmu_buf_rele(db, FTAG);
+
+	packed = vmem_alloc(nvsize, KM_SLEEP);
+	error = dmu_read(spa->spa_meta_objset, obj, 0, nvsize, packed,
+	    DMU_READ_PREFETCH);
+	if (error == 0)
+		error = nvlist_unpack(packed, nvsize, value, 0);
+	vmem_free(packed, nvsize);
+
+	return (error);
+}
+
+/*
+ * Checks to see if the given vdev could not be opened, in which case we post a
+ * sysevent to notify the autoreplace code that the device has been removed.
+ */
+static void
+spa_check_removed(vdev_t *vd)
+{
+	int c;
+
+	for (c = 0; c < vd->vdev_children; c++)
+		spa_check_removed(vd->vdev_child[c]);
+
+	if (vd->vdev_ops->vdev_op_leaf && vdev_is_dead(vd) &&
+	    !vd->vdev_ishole) {
+		zfs_ereport_post(FM_EREPORT_RESOURCE_AUTOREPLACE,
+		    vd->vdev_spa, vd, NULL, 0, 0);
+		spa_event_notify(vd->vdev_spa, vd, FM_EREPORT_ZFS_DEVICE_CHECK);
+	}
+}
+
+/*
+ * Validate the current config against the MOS config
+ */
+static boolean_t
+spa_config_valid(spa_t *spa, nvlist_t *config)
+{
+	vdev_t *mrvd, *rvd = spa->spa_root_vdev;
+	nvlist_t *nv;
+	int c, i;
+
+	VERIFY(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE, &nv) == 0);
+
+	spa_config_enter(spa, SCL_ALL, FTAG, RW_WRITER);
+	VERIFY(spa_config_parse(spa, &mrvd, nv, NULL, 0, VDEV_ALLOC_LOAD) == 0);
+
+	ASSERT3U(rvd->vdev_children, ==, mrvd->vdev_children);
+
+	/*
+	 * If we're doing a normal import, then build up any additional
+	 * diagnostic information about missing devices in this config.
+	 * We'll pass this up to the user for further processing.
+	 */
+	if (!(spa->spa_import_flags & ZFS_IMPORT_MISSING_LOG)) {
+		nvlist_t **child, *nv;
+		uint64_t idx = 0;
+
+		child = kmem_alloc(rvd->vdev_children * sizeof (nvlist_t **),
+		    KM_SLEEP);
+		VERIFY(nvlist_alloc(&nv, NV_UNIQUE_NAME, KM_SLEEP) == 0);
+
+		for (c = 0; c < rvd->vdev_children; c++) {
+			vdev_t *tvd = rvd->vdev_child[c];
+			vdev_t *mtvd  = mrvd->vdev_child[c];
+
+			if (tvd->vdev_ops == &vdev_missing_ops &&
+			    mtvd->vdev_ops != &vdev_missing_ops &&
+			    mtvd->vdev_islog)
+				child[idx++] = vdev_config_generate(spa, mtvd,
+				    B_FALSE, 0);
+		}
+
+		if (idx) {
+			VERIFY(nvlist_add_nvlist_array(nv,
+			    ZPOOL_CONFIG_CHILDREN, child, idx) == 0);
+			VERIFY(nvlist_add_nvlist(spa->spa_load_info,
+			    ZPOOL_CONFIG_MISSING_DEVICES, nv) == 0);
+
+			for (i = 0; i < idx; i++)
+				nvlist_free(child[i]);
+		}
+		nvlist_free(nv);
+		kmem_free(child, rvd->vdev_children * sizeof (char **));
+	}
+
+	/*
+	 * Compare the root vdev tree with the information we have
+	 * from the MOS config (mrvd). Check each top-level vdev
+	 * with the corresponding MOS config top-level (mtvd).
+	 */
+	for (c = 0; c < rvd->vdev_children; c++) {
+		vdev_t *tvd = rvd->vdev_child[c];
+		vdev_t *mtvd  = mrvd->vdev_child[c];
+
+		/*
+		 * Resolve any "missing" vdevs in the current configuration.
+		 * If we find that the MOS config has more accurate information
+		 * about the top-level vdev then use that vdev instead.
+		 */
+		if (tvd->vdev_ops == &vdev_missing_ops &&
+		    mtvd->vdev_ops != &vdev_missing_ops) {
+
+			if (!(spa->spa_import_flags & ZFS_IMPORT_MISSING_LOG))
+				continue;
+
+			/*
+			 * Device specific actions.
+			 */
+			if (mtvd->vdev_islog) {
+				spa_set_log_state(spa, SPA_LOG_CLEAR);
+			} else {
+				/*
+				 * XXX - once we have 'readonly' pool
+				 * support we should be able to handle
+				 * missing data devices by transitioning
+				 * the pool to readonly.
+				 */
+				continue;
+			}
+
+			/*
+			 * Swap the missing vdev with the data we were
+			 * able to obtain from the MOS config.
+			 */
+			vdev_remove_child(rvd, tvd);
+			vdev_remove_child(mrvd, mtvd);
+
+			vdev_add_child(rvd, mtvd);
+			vdev_add_child(mrvd, tvd);
+
+			spa_config_exit(spa, SCL_ALL, FTAG);
+			vdev_load(mtvd);
+			spa_config_enter(spa, SCL_ALL, FTAG, RW_WRITER);
+
+			vdev_reopen(rvd);
+		} else if (mtvd->vdev_islog) {
+			/*
+			 * Load the slog device's state from the MOS config
+			 * since it's possible that the label does not
+			 * contain the most up-to-date information.
+			 */
+			vdev_load_log_state(tvd, mtvd);
+			vdev_reopen(tvd);
+		}
+	}
+	vdev_free(mrvd);
+	spa_config_exit(spa, SCL_ALL, FTAG);
+
+	/*
+	 * Ensure we were able to validate the config.
+	 */
+	return (rvd->vdev_guid_sum == spa->spa_uberblock.ub_guid_sum);
+}
+
+/*
+ * Check for missing log devices
+ */
+static boolean_t
+spa_check_logs(spa_t *spa)
+{
+	boolean_t rv = B_FALSE;
+	dsl_pool_t *dp = spa_get_dsl(spa);
+
+	switch (spa->spa_log_state) {
+	default:
+		break;
+	case SPA_LOG_MISSING:
+		/* need to recheck in case slog has been restored */
+	case SPA_LOG_UNKNOWN:
+		rv = (dmu_objset_find_dp(dp, dp->dp_root_dir_obj,
+		    zil_check_log_chain, NULL, DS_FIND_CHILDREN) != 0);
+		if (rv)
+			spa_set_log_state(spa, SPA_LOG_MISSING);
+		break;
+	}
+	return (rv);
+}
+
+static boolean_t
+spa_passivate_log(spa_t *spa)
+{
+	vdev_t *rvd = spa->spa_root_vdev;
+	boolean_t slog_found = B_FALSE;
+	int c;
+
+	ASSERT(spa_config_held(spa, SCL_ALLOC, RW_WRITER));
+
+	if (!spa_has_slogs(spa))
+		return (B_FALSE);
+
+	for (c = 0; c < rvd->vdev_children; c++) {
+		vdev_t *tvd = rvd->vdev_child[c];
+		metaslab_group_t *mg = tvd->vdev_mg;
+
+		if (tvd->vdev_islog) {
+			metaslab_group_passivate(mg);
+			slog_found = B_TRUE;
+		}
+	}
+
+	return (slog_found);
+}
+
+static void
+spa_activate_log(spa_t *spa)
+{
+	vdev_t *rvd = spa->spa_root_vdev;
+	int c;
+
+	ASSERT(spa_config_held(spa, SCL_ALLOC, RW_WRITER));
+
+	for (c = 0; c < rvd->vdev_children; c++) {
+		vdev_t *tvd = rvd->vdev_child[c];
+		metaslab_group_t *mg = tvd->vdev_mg;
+
+		if (tvd->vdev_islog)
+			metaslab_group_activate(mg);
+	}
+}
+
+int
+spa_offline_log(spa_t *spa)
+{
+	int error;
+
+	error = dmu_objset_find(spa_name(spa), zil_vdev_offline,
+	    NULL, DS_FIND_CHILDREN);
+	if (error == 0) {
+		/*
+		 * We successfully offlined the log device, sync out the
+		 * current txg so that the "stubby" block can be removed
+		 * by zil_sync().
+		 */
+		txg_wait_synced(spa->spa_dsl_pool, 0);
+	}
+	return (error);
+}
+
+static void
+spa_aux_check_removed(spa_aux_vdev_t *sav)
+{
+	int i;
+
+	for (i = 0; i < sav->sav_count; i++)
+		spa_check_removed(sav->sav_vdevs[i]);
+}
+
+void
+spa_claim_notify(zio_t *zio)
+{
+	spa_t *spa = zio->io_spa;
+
+	if (zio->io_error)
+		return;
+
+	mutex_enter(&spa->spa_props_lock);	/* any mutex will do */
+	if (spa->spa_claim_max_txg < zio->io_bp->blk_birth)
+		spa->spa_claim_max_txg = zio->io_bp->blk_birth;
+	mutex_exit(&spa->spa_props_lock);
+}
+
+typedef struct spa_load_error {
+	uint64_t	sle_meta_count;
+	uint64_t	sle_data_count;
+} spa_load_error_t;
+
+static void
+spa_load_verify_done(zio_t *zio)
+{
+	blkptr_t *bp = zio->io_bp;
+	spa_load_error_t *sle = zio->io_private;
+	dmu_object_type_t type = BP_GET_TYPE(bp);
+	int error = zio->io_error;
+	spa_t *spa = zio->io_spa;
+
+	if (error) {
+		if ((BP_GET_LEVEL(bp) != 0 || DMU_OT_IS_METADATA(type)) &&
+		    type != DMU_OT_INTENT_LOG)
+			atomic_add_64(&sle->sle_meta_count, 1);
+		else
+			atomic_add_64(&sle->sle_data_count, 1);
+	}
+	zio_data_buf_free(zio->io_data, zio->io_size);
+
+	mutex_enter(&spa->spa_scrub_lock);
+	spa->spa_scrub_inflight--;
+	cv_broadcast(&spa->spa_scrub_io_cv);
+	mutex_exit(&spa->spa_scrub_lock);
+}
+
+/*
+ * Maximum number of concurrent scrub i/os to create while verifying
+ * a pool while importing it.
+ */
+int spa_load_verify_maxinflight = 10000;
+int spa_load_verify_metadata = B_TRUE;
+int spa_load_verify_data = B_TRUE;
+
+/*ARGSUSED*/
+static int
+spa_load_verify_cb(spa_t *spa, zilog_t *zilog, const blkptr_t *bp,
+    const zbookmark_phys_t *zb, const dnode_phys_t *dnp, void *arg)
+{
+	zio_t *rio;
+	size_t size;
+	void *data;
+
+	if (BP_IS_HOLE(bp) || BP_IS_EMBEDDED(bp))
+		return (0);
+	/*
+	 * Note: normally this routine will not be called if
+	 * spa_load_verify_metadata is not set.  However, it may be useful
+	 * to manually set the flag after the traversal has begun.
+	 */
+	if (!spa_load_verify_metadata)
+		return (0);
+	if (BP_GET_BUFC_TYPE(bp) == ARC_BUFC_DATA && !spa_load_verify_data)
+		return (0);
+
+	rio = arg;
+	size = BP_GET_PSIZE(bp);
+	data = zio_data_buf_alloc(size);
+
+	mutex_enter(&spa->spa_scrub_lock);
+	while (spa->spa_scrub_inflight >= spa_load_verify_maxinflight)
+		cv_wait(&spa->spa_scrub_io_cv, &spa->spa_scrub_lock);
+	spa->spa_scrub_inflight++;
+	mutex_exit(&spa->spa_scrub_lock);
+
+	zio_nowait(zio_read(rio, spa, bp, data, size,
+	    spa_load_verify_done, rio->io_private, ZIO_PRIORITY_SCRUB,
+	    ZIO_FLAG_SPECULATIVE | ZIO_FLAG_CANFAIL |
+	    ZIO_FLAG_SCRUB | ZIO_FLAG_RAW, zb));
+	return (0);
+}
+
+static int
+spa_load_verify(spa_t *spa)
+{
+	zio_t *rio;
+	spa_load_error_t sle = { 0 };
+	zpool_rewind_policy_t policy;
+	boolean_t verify_ok = B_FALSE;
+	int error = 0;
+
+	zpool_get_rewind_policy(spa->spa_config, &policy);
+
+	if (policy.zrp_request & ZPOOL_NEVER_REWIND)
+		return (0);
+
+	rio = zio_root(spa, NULL, &sle,
+	    ZIO_FLAG_CANFAIL | ZIO_FLAG_SPECULATIVE);
+
+	if (spa_load_verify_metadata) {
+		error = traverse_pool(spa, spa->spa_verify_min_txg,
+		    TRAVERSE_PRE | TRAVERSE_PREFETCH_METADATA,
+		    spa_load_verify_cb, rio);
+	}
+
+	(void) zio_wait(rio);
+
+	spa->spa_load_meta_errors = sle.sle_meta_count;
+	spa->spa_load_data_errors = sle.sle_data_count;
+
+	if (!error && sle.sle_meta_count <= policy.zrp_maxmeta &&
+	    sle.sle_data_count <= policy.zrp_maxdata) {
+		int64_t loss = 0;
+
+		verify_ok = B_TRUE;
+		spa->spa_load_txg = spa->spa_uberblock.ub_txg;
+		spa->spa_load_txg_ts = spa->spa_uberblock.ub_timestamp;
+
+		loss = spa->spa_last_ubsync_txg_ts - spa->spa_load_txg_ts;
+		VERIFY(nvlist_add_uint64(spa->spa_load_info,
+		    ZPOOL_CONFIG_LOAD_TIME, spa->spa_load_txg_ts) == 0);
+		VERIFY(nvlist_add_int64(spa->spa_load_info,
+		    ZPOOL_CONFIG_REWIND_TIME, loss) == 0);
+		VERIFY(nvlist_add_uint64(spa->spa_load_info,
+		    ZPOOL_CONFIG_LOAD_DATA_ERRORS, sle.sle_data_count) == 0);
+	} else {
+		spa->spa_load_max_txg = spa->spa_uberblock.ub_txg;
+	}
+
+	if (error) {
+		if (error != ENXIO && error != EIO)
+			error = SET_ERROR(EIO);
+		return (error);
+	}
+
+	return (verify_ok ? 0 : EIO);
+}
+
+/*
+ * Find a value in the pool props object.
+ */
+static void
+spa_prop_find(spa_t *spa, zpool_prop_t prop, uint64_t *val)
+{
+	(void) zap_lookup(spa->spa_meta_objset, spa->spa_pool_props_object,
+	    zpool_prop_to_name(prop), sizeof (uint64_t), 1, val);
+}
+
+/*
+ * Find a value in the pool directory object.
+ */
+static int
+spa_dir_prop(spa_t *spa, const char *name, uint64_t *val)
+{
+	return (zap_lookup(spa->spa_meta_objset, DMU_POOL_DIRECTORY_OBJECT,
+	    name, sizeof (uint64_t), 1, val));
+}
+
+static int
+spa_vdev_err(vdev_t *vdev, vdev_aux_t aux, int err)
+{
+	vdev_set_state(vdev, B_TRUE, VDEV_STATE_CANT_OPEN, aux);
+	return (err);
+}
+
+/*
+ * Fix up config after a partly-completed split.  This is done with the
+ * ZPOOL_CONFIG_SPLIT nvlist.  Both the splitting pool and the split-off
+ * pool have that entry in their config, but only the splitting one contains
+ * a list of all the guids of the vdevs that are being split off.
+ *
+ * This function determines what to do with that list: either rejoin
+ * all the disks to the pool, or complete the splitting process.  To attempt
+ * the rejoin, each disk that is offlined is marked online again, and
+ * we do a reopen() call.  If the vdev label for every disk that was
+ * marked online indicates it was successfully split off (VDEV_AUX_SPLIT_POOL)
+ * then we call vdev_split() on each disk, and complete the split.
+ *
+ * Otherwise we leave the config alone, with all the vdevs in place in
+ * the original pool.
+ */
+static void
+spa_try_repair(spa_t *spa, nvlist_t *config)
+{
+	uint_t extracted;
+	uint64_t *glist;
+	uint_t i, gcount;
+	nvlist_t *nvl;
+	vdev_t **vd;
+	boolean_t attempt_reopen;
+
+	if (nvlist_lookup_nvlist(config, ZPOOL_CONFIG_SPLIT, &nvl) != 0)
+		return;
+
+	/* check that the config is complete */
+	if (nvlist_lookup_uint64_array(nvl, ZPOOL_CONFIG_SPLIT_LIST,
+	    &glist, &gcount) != 0)
+		return;
+
+	vd = kmem_zalloc(gcount * sizeof (vdev_t *), KM_SLEEP);
+
+	/* attempt to online all the vdevs & validate */
+	attempt_reopen = B_TRUE;
+	for (i = 0; i < gcount; i++) {
+		if (glist[i] == 0)	/* vdev is hole */
+			continue;
+
+		vd[i] = spa_lookup_by_guid(spa, glist[i], B_FALSE);
+		if (vd[i] == NULL) {
+			/*
+			 * Don't bother attempting to reopen the disks;
+			 * just do the split.
+			 */
+			attempt_reopen = B_FALSE;
+		} else {
+			/* attempt to re-online it */
+			vd[i]->vdev_offline = B_FALSE;
+		}
+	}
+
+	if (attempt_reopen) {
+		vdev_reopen(spa->spa_root_vdev);
+
+		/* check each device to see what state it's in */
+		for (extracted = 0, i = 0; i < gcount; i++) {
+			if (vd[i] != NULL &&
+			    vd[i]->vdev_stat.vs_aux != VDEV_AUX_SPLIT_POOL)
+				break;
+			++extracted;
+		}
+	}
+
+	/*
+	 * If every disk has been moved to the new pool, or if we never
+	 * even attempted to look at them, then we split them off for
+	 * good.
+	 */
+	if (!attempt_reopen || gcount == extracted) {
+		for (i = 0; i < gcount; i++)
+			if (vd[i] != NULL)
+				vdev_split(vd[i]);
+		vdev_reopen(spa->spa_root_vdev);
+	}
+
+	kmem_free(vd, gcount * sizeof (vdev_t *));
+}
+
+static int
+spa_load(spa_t *spa, spa_load_state_t state, spa_import_type_t type,
+    boolean_t mosconfig)
+{
+	nvlist_t *config = spa->spa_config;
+	char *ereport = FM_EREPORT_ZFS_POOL;
+	char *comment;
+	int error;
+	uint64_t pool_guid;
+	nvlist_t *nvl;
+
+	if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_GUID, &pool_guid))
+		return (SET_ERROR(EINVAL));
+
+	ASSERT(spa->spa_comment == NULL);
+	if (nvlist_lookup_string(config, ZPOOL_CONFIG_COMMENT, &comment) == 0)
+		spa->spa_comment = spa_strdup(comment);
+
+	/*
+	 * Versioning wasn't explicitly added to the label until later, so if
+	 * it's not present treat it as the initial version.
+	 */
+	if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION,
+	    &spa->spa_ubsync.ub_version) != 0)
+		spa->spa_ubsync.ub_version = SPA_VERSION_INITIAL;
+
+	(void) nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_TXG,
+	    &spa->spa_config_txg);
+
+	if ((state == SPA_LOAD_IMPORT || state == SPA_LOAD_TRYIMPORT) &&
+	    spa_guid_exists(pool_guid, 0)) {
+		error = SET_ERROR(EEXIST);
+	} else {
+		spa->spa_config_guid = pool_guid;
+
+		if (nvlist_lookup_nvlist(config, ZPOOL_CONFIG_SPLIT,
+		    &nvl) == 0) {
+			VERIFY(nvlist_dup(nvl, &spa->spa_config_splitting,
+			    KM_SLEEP) == 0);
+		}
+
+		nvlist_free(spa->spa_load_info);
+		spa->spa_load_info = fnvlist_alloc();
+
+		gethrestime(&spa->spa_loaded_ts);
+		error = spa_load_impl(spa, pool_guid, config, state, type,
+		    mosconfig, &ereport);
+	}
+
+	/*
+	 * Don't count references from objsets that are already closed
+	 * and are making their way through the eviction process.
+	 */
+	spa_evicting_os_wait(spa);
+	spa->spa_minref = refcount_count(&spa->spa_refcount);
+	if (error) {
+		if (error != EEXIST) {
+			spa->spa_loaded_ts.tv_sec = 0;
+			spa->spa_loaded_ts.tv_nsec = 0;
+		}
+		if (error != EBADF) {
+			zfs_ereport_post(ereport, spa, NULL, NULL, 0, 0);
+		}
+	}
+	spa->spa_load_state = error ? SPA_LOAD_ERROR : SPA_LOAD_NONE;
+	spa->spa_ena = 0;
+
+	return (error);
+}
+
+/*
+ * Load an existing storage pool, using the pool's builtin spa_config as a
+ * source of configuration information.
+ */
+__attribute__((always_inline))
+static inline int
+spa_load_impl(spa_t *spa, uint64_t pool_guid, nvlist_t *config,
+    spa_load_state_t state, spa_import_type_t type, boolean_t mosconfig,
+    char **ereport)
+{
+	int error = 0;
+	nvlist_t *nvroot = NULL;
+	nvlist_t *label;
+	vdev_t *rvd;
+	uberblock_t *ub = &spa->spa_uberblock;
+	uint64_t children, config_cache_txg = spa->spa_config_txg;
+	int orig_mode = spa->spa_mode;
+	int parse, i;
+	uint64_t obj;
+	boolean_t missing_feat_write = B_FALSE;
+
+	/*
+	 * If this is an untrusted config, access the pool in read-only mode.
+	 * This prevents things like resilvering recently removed devices.
+	 */
+	if (!mosconfig)
+		spa->spa_mode = FREAD;
+
+	ASSERT(MUTEX_HELD(&spa_namespace_lock));
+
+	spa->spa_load_state = state;
+
+	if (nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE, &nvroot))
+		return (SET_ERROR(EINVAL));
+
+	parse = (type == SPA_IMPORT_EXISTING ?
+	    VDEV_ALLOC_LOAD : VDEV_ALLOC_SPLIT);
+
+	/*
+	 * Create "The Godfather" zio to hold all async IOs
+	 */
+	spa->spa_async_zio_root = kmem_alloc(max_ncpus * sizeof (void *),
+	    KM_SLEEP);
+	for (i = 0; i < max_ncpus; i++) {
+		spa->spa_async_zio_root[i] = zio_root(spa, NULL, NULL,
+		    ZIO_FLAG_CANFAIL | ZIO_FLAG_SPECULATIVE |
+		    ZIO_FLAG_GODFATHER);
+	}
+
+	/*
+	 * Parse the configuration into a vdev tree.  We explicitly set the
+	 * value that will be returned by spa_version() since parsing the
+	 * configuration requires knowing the version number.
+	 */
+	spa_config_enter(spa, SCL_ALL, FTAG, RW_WRITER);
+	error = spa_config_parse(spa, &rvd, nvroot, NULL, 0, parse);
+	spa_config_exit(spa, SCL_ALL, FTAG);
+
+	if (error != 0)
+		return (error);
+
+	ASSERT(spa->spa_root_vdev == rvd);
+	ASSERT3U(spa->spa_min_ashift, >=, SPA_MINBLOCKSHIFT);
+	ASSERT3U(spa->spa_max_ashift, <=, SPA_MAXBLOCKSHIFT);
+
+	if (type != SPA_IMPORT_ASSEMBLE) {
+		ASSERT(spa_guid(spa) == pool_guid);
+	}
+
+	/*
+	 * Try to open all vdevs, loading each label in the process.
+	 */
+	spa_config_enter(spa, SCL_ALL, FTAG, RW_WRITER);
+	error = vdev_open(rvd);
+	spa_config_exit(spa, SCL_ALL, FTAG);
+	if (error != 0)
+		return (error);
+
+	/*
+	 * We need to validate the vdev labels against the configuration that
+	 * we have in hand, which is dependent on the setting of mosconfig. If
+	 * mosconfig is true then we're validating the vdev labels based on
+	 * that config.  Otherwise, we're validating against the cached config
+	 * (zpool.cache) that was read when we loaded the zfs module, and then
+	 * later we will recursively call spa_load() and validate against
+	 * the vdev config.
+	 *
+	 * If we're assembling a new pool that's been split off from an
+	 * existing pool, the labels haven't yet been updated so we skip
+	 * validation for now.
+	 */
+	if (type != SPA_IMPORT_ASSEMBLE) {
+		spa_config_enter(spa, SCL_ALL, FTAG, RW_WRITER);
+		error = vdev_validate(rvd, mosconfig);
+		spa_config_exit(spa, SCL_ALL, FTAG);
+
+		if (error != 0)
+			return (error);
+
+		if (rvd->vdev_state <= VDEV_STATE_CANT_OPEN)
+			return (SET_ERROR(ENXIO));
+	}
+
+	/*
+	 * Find the best uberblock.
+	 */
+	vdev_uberblock_load(rvd, ub, &label);
+
+	/*
+	 * If we weren't able to find a single valid uberblock, return failure.
+	 */
+	if (ub->ub_txg == 0) {
+		nvlist_free(label);
+		return (spa_vdev_err(rvd, VDEV_AUX_CORRUPT_DATA, ENXIO));
+	}
+
+	/*
+	 * If the pool has an unsupported version we can't open it.
+	 */
+	if (!SPA_VERSION_IS_SUPPORTED(ub->ub_version)) {
+		nvlist_free(label);
+		return (spa_vdev_err(rvd, VDEV_AUX_VERSION_NEWER, ENOTSUP));
+	}
+
+	if (ub->ub_version >= SPA_VERSION_FEATURES) {
+		nvlist_t *features;
+
+		/*
+		 * If we weren't able to find what's necessary for reading the
+		 * MOS in the label, return failure.
+		 */
+		if (label == NULL || nvlist_lookup_nvlist(label,
+		    ZPOOL_CONFIG_FEATURES_FOR_READ, &features) != 0) {
+			nvlist_free(label);
+			return (spa_vdev_err(rvd, VDEV_AUX_CORRUPT_DATA,
+			    ENXIO));
+		}
+
+		/*
+		 * Update our in-core representation with the definitive values
+		 * from the label.
+		 */
+		nvlist_free(spa->spa_label_features);
+		VERIFY(nvlist_dup(features, &spa->spa_label_features, 0) == 0);
+	}
+
+	nvlist_free(label);
+
+	/*
+	 * Look through entries in the label nvlist's features_for_read. If
+	 * there is a feature listed there which we don't understand then we
+	 * cannot open a pool.
+	 */
+	if (ub->ub_version >= SPA_VERSION_FEATURES) {
+		nvlist_t *unsup_feat;
+		nvpair_t *nvp;
+
+		VERIFY(nvlist_alloc(&unsup_feat, NV_UNIQUE_NAME, KM_SLEEP) ==
+		    0);
+
+		for (nvp = nvlist_next_nvpair(spa->spa_label_features, NULL);
+		    nvp != NULL;
+		    nvp = nvlist_next_nvpair(spa->spa_label_features, nvp)) {
+			if (!zfeature_is_supported(nvpair_name(nvp))) {
+				VERIFY(nvlist_add_string(unsup_feat,
+				    nvpair_name(nvp), "") == 0);
+			}
+		}
+
+		if (!nvlist_empty(unsup_feat)) {
+			VERIFY(nvlist_add_nvlist(spa->spa_load_info,
+			    ZPOOL_CONFIG_UNSUP_FEAT, unsup_feat) == 0);
+			nvlist_free(unsup_feat);
+			return (spa_vdev_err(rvd, VDEV_AUX_UNSUP_FEAT,
+			    ENOTSUP));
+		}
+
+		nvlist_free(unsup_feat);
+	}
+
+	/*
+	 * If the vdev guid sum doesn't match the uberblock, we have an
+	 * incomplete configuration.  We first check to see if the pool
+	 * is aware of the complete config (i.e ZPOOL_CONFIG_VDEV_CHILDREN).
+	 * If it is, defer the vdev_guid_sum check till later so we
+	 * can handle missing vdevs.
+	 */
+	if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_VDEV_CHILDREN,
+	    &children) != 0 && mosconfig && type != SPA_IMPORT_ASSEMBLE &&
+	    rvd->vdev_guid_sum != ub->ub_guid_sum)
+		return (spa_vdev_err(rvd, VDEV_AUX_BAD_GUID_SUM, ENXIO));
+
+	if (type != SPA_IMPORT_ASSEMBLE && spa->spa_config_splitting) {
+		spa_config_enter(spa, SCL_ALL, FTAG, RW_WRITER);
+		spa_try_repair(spa, config);
+		spa_config_exit(spa, SCL_ALL, FTAG);
+		nvlist_free(spa->spa_config_splitting);
+		spa->spa_config_splitting = NULL;
+	}
+
+	/*
+	 * Initialize internal SPA structures.
+	 */
+	spa->spa_state = POOL_STATE_ACTIVE;
+	spa->spa_ubsync = spa->spa_uberblock;
+	spa->spa_verify_min_txg = spa->spa_extreme_rewind ?
+	    TXG_INITIAL - 1 : spa_last_synced_txg(spa) - TXG_DEFER_SIZE - 1;
+	spa->spa_first_txg = spa->spa_last_ubsync_txg ?
+	    spa->spa_last_ubsync_txg : spa_last_synced_txg(spa) + 1;
+	spa->spa_claim_max_txg = spa->spa_first_txg;
+	spa->spa_prev_software_version = ub->ub_software_version;
+
+	error = dsl_pool_init(spa, spa->spa_first_txg, &spa->spa_dsl_pool);
+	if (error)
+		return (spa_vdev_err(rvd, VDEV_AUX_CORRUPT_DATA, EIO));
+	spa->spa_meta_objset = spa->spa_dsl_pool->dp_meta_objset;
+
+	if (spa_dir_prop(spa, DMU_POOL_CONFIG, &spa->spa_config_object) != 0)
+		return (spa_vdev_err(rvd, VDEV_AUX_CORRUPT_DATA, EIO));
+
+	if (spa_version(spa) >= SPA_VERSION_FEATURES) {
+		boolean_t missing_feat_read = B_FALSE;
+		nvlist_t *unsup_feat, *enabled_feat;
+		spa_feature_t i;
+
+		if (spa_dir_prop(spa, DMU_POOL_FEATURES_FOR_READ,
+		    &spa->spa_feat_for_read_obj) != 0) {
+			return (spa_vdev_err(rvd, VDEV_AUX_CORRUPT_DATA, EIO));
+		}
+
+		if (spa_dir_prop(spa, DMU_POOL_FEATURES_FOR_WRITE,
+		    &spa->spa_feat_for_write_obj) != 0) {
+			return (spa_vdev_err(rvd, VDEV_AUX_CORRUPT_DATA, EIO));
+		}
+
+		if (spa_dir_prop(spa, DMU_POOL_FEATURE_DESCRIPTIONS,
+		    &spa->spa_feat_desc_obj) != 0) {
+			return (spa_vdev_err(rvd, VDEV_AUX_CORRUPT_DATA, EIO));
+		}
+
+		enabled_feat = fnvlist_alloc();
+		unsup_feat = fnvlist_alloc();
+
+		if (!spa_features_check(spa, B_FALSE,
+		    unsup_feat, enabled_feat))
+			missing_feat_read = B_TRUE;
+
+		if (spa_writeable(spa) || state == SPA_LOAD_TRYIMPORT) {
+			if (!spa_features_check(spa, B_TRUE,
+			    unsup_feat, enabled_feat)) {
+				missing_feat_write = B_TRUE;
+			}
+		}
+
+		fnvlist_add_nvlist(spa->spa_load_info,
+		    ZPOOL_CONFIG_ENABLED_FEAT, enabled_feat);
+
+		if (!nvlist_empty(unsup_feat)) {
+			fnvlist_add_nvlist(spa->spa_load_info,
+			    ZPOOL_CONFIG_UNSUP_FEAT, unsup_feat);
+		}
+
+		fnvlist_free(enabled_feat);
+		fnvlist_free(unsup_feat);
+
+		if (!missing_feat_read) {
+			fnvlist_add_boolean(spa->spa_load_info,
+			    ZPOOL_CONFIG_CAN_RDONLY);
+		}
+
+		/*
+		 * If the state is SPA_LOAD_TRYIMPORT, our objective is
+		 * twofold: to determine whether the pool is available for
+		 * import in read-write mode and (if it is not) whether the
+		 * pool is available for import in read-only mode. If the pool
+		 * is available for import in read-write mode, it is displayed
+		 * as available in userland; if it is not available for import
+		 * in read-only mode, it is displayed as unavailable in
+		 * userland. If the pool is available for import in read-only
+		 * mode but not read-write mode, it is displayed as unavailable
+		 * in userland with a special note that the pool is actually
+		 * available for open in read-only mode.
+		 *
+		 * As a result, if the state is SPA_LOAD_TRYIMPORT and we are
+		 * missing a feature for write, we must first determine whether
+		 * the pool can be opened read-only before returning to
+		 * userland in order to know whether to display the
+		 * abovementioned note.
+		 */
+		if (missing_feat_read || (missing_feat_write &&
+		    spa_writeable(spa))) {
+			return (spa_vdev_err(rvd, VDEV_AUX_UNSUP_FEAT,
+			    ENOTSUP));
+		}
+
+		/*
+		 * Load refcounts for ZFS features from disk into an in-memory
+		 * cache during SPA initialization.
+		 */
+		for (i = 0; i < SPA_FEATURES; i++) {
+			uint64_t refcount;
+
+			error = feature_get_refcount_from_disk(spa,
+			    &spa_feature_table[i], &refcount);
+			if (error == 0) {
+				spa->spa_feat_refcount_cache[i] = refcount;
+			} else if (error == ENOTSUP) {
+				spa->spa_feat_refcount_cache[i] =
+				    SPA_FEATURE_DISABLED;
+			} else {
+				return (spa_vdev_err(rvd,
+				    VDEV_AUX_CORRUPT_DATA, EIO));
+			}
+		}
+	}
+
+	if (spa_feature_is_active(spa, SPA_FEATURE_ENABLED_TXG)) {
+		if (spa_dir_prop(spa, DMU_POOL_FEATURE_ENABLED_TXG,
+		    &spa->spa_feat_enabled_txg_obj) != 0)
+			return (spa_vdev_err(rvd, VDEV_AUX_CORRUPT_DATA, EIO));
+	}
+
+	spa->spa_is_initializing = B_TRUE;
+	error = dsl_pool_open(spa->spa_dsl_pool);
+	spa->spa_is_initializing = B_FALSE;
+	if (error != 0)
+		return (spa_vdev_err(rvd, VDEV_AUX_CORRUPT_DATA, EIO));
+
+	if (!mosconfig) {
+		uint64_t hostid;
+		nvlist_t *policy = NULL, *nvconfig;
+
+		if (load_nvlist(spa, spa->spa_config_object, &nvconfig) != 0)
+			return (spa_vdev_err(rvd, VDEV_AUX_CORRUPT_DATA, EIO));
+
+		if (!spa_is_root(spa) && nvlist_lookup_uint64(nvconfig,
+		    ZPOOL_CONFIG_HOSTID, &hostid) == 0) {
+			char *hostname;
+			unsigned long myhostid = 0;
+
+			VERIFY(nvlist_lookup_string(nvconfig,
+			    ZPOOL_CONFIG_HOSTNAME, &hostname) == 0);
+
+#ifdef	_KERNEL
+			myhostid = zone_get_hostid(NULL);
+#else	/* _KERNEL */
+			/*
+			 * We're emulating the system's hostid in userland, so
+			 * we can't use zone_get_hostid().
+			 */
+			(void) ddi_strtoul(hw_serial, NULL, 10, &myhostid);
+#endif	/* _KERNEL */
+			if (hostid != 0 && myhostid != 0 &&
+			    hostid != myhostid) {
+				nvlist_free(nvconfig);
+				cmn_err(CE_WARN, "pool '%s' could not be "
+				    "loaded as it was last accessed by another "
+				    "system (host: %s hostid: 0x%lx). See: "
+				    "http://zfsonlinux.org/msg/ZFS-8000-EY",
+				    spa_name(spa), hostname,
+				    (unsigned long)hostid);
+				return (SET_ERROR(EBADF));
+			}
+		}
+		if (nvlist_lookup_nvlist(spa->spa_config,
+		    ZPOOL_REWIND_POLICY, &policy) == 0)
+			VERIFY(nvlist_add_nvlist(nvconfig,
+			    ZPOOL_REWIND_POLICY, policy) == 0);
+
+		spa_config_set(spa, nvconfig);
+		spa_unload(spa);
+		spa_deactivate(spa);
+		spa_activate(spa, orig_mode);
+
+		return (spa_load(spa, state, SPA_IMPORT_EXISTING, B_TRUE));
+	}
+
+	if (spa_dir_prop(spa, DMU_POOL_SYNC_BPOBJ, &obj) != 0)
+		return (spa_vdev_err(rvd, VDEV_AUX_CORRUPT_DATA, EIO));
+	error = bpobj_open(&spa->spa_deferred_bpobj, spa->spa_meta_objset, obj);
+	if (error != 0)
+		return (spa_vdev_err(rvd, VDEV_AUX_CORRUPT_DATA, EIO));
+
+	/*
+	 * Load the bit that tells us to use the new accounting function
+	 * (raid-z deflation).  If we have an older pool, this will not
+	 * be present.
+	 */
+	error = spa_dir_prop(spa, DMU_POOL_DEFLATE, &spa->spa_deflate);
+	if (error != 0 && error != ENOENT)
+		return (spa_vdev_err(rvd, VDEV_AUX_CORRUPT_DATA, EIO));
+
+	error = spa_dir_prop(spa, DMU_POOL_CREATION_VERSION,
+	    &spa->spa_creation_version);
+	if (error != 0 && error != ENOENT)
+		return (spa_vdev_err(rvd, VDEV_AUX_CORRUPT_DATA, EIO));
+
+	/*
+	 * Load the persistent error log.  If we have an older pool, this will
+	 * not be present.
+	 */
+	error = spa_dir_prop(spa, DMU_POOL_ERRLOG_LAST, &spa->spa_errlog_last);
+	if (error != 0 && error != ENOENT)
+		return (spa_vdev_err(rvd, VDEV_AUX_CORRUPT_DATA, EIO));
+
+	error = spa_dir_prop(spa, DMU_POOL_ERRLOG_SCRUB,
+	    &spa->spa_errlog_scrub);
+	if (error != 0 && error != ENOENT)
+		return (spa_vdev_err(rvd, VDEV_AUX_CORRUPT_DATA, EIO));
+
+	/*
+	 * Load the history object.  If we have an older pool, this
+	 * will not be present.
+	 */
+	error = spa_dir_prop(spa, DMU_POOL_HISTORY, &spa->spa_history);
+	if (error != 0 && error != ENOENT)
+		return (spa_vdev_err(rvd, VDEV_AUX_CORRUPT_DATA, EIO));
+
+	/*
+	 * If we're assembling the pool from the split-off vdevs of
+	 * an existing pool, we don't want to attach the spares & cache
+	 * devices.
+	 */
+
+	/*
+	 * Load any hot spares for this pool.
+	 */
+	error = spa_dir_prop(spa, DMU_POOL_SPARES, &spa->spa_spares.sav_object);
+	if (error != 0 && error != ENOENT)
+		return (spa_vdev_err(rvd, VDEV_AUX_CORRUPT_DATA, EIO));
+	if (error == 0 && type != SPA_IMPORT_ASSEMBLE) {
+		ASSERT(spa_version(spa) >= SPA_VERSION_SPARES);
+		if (load_nvlist(spa, spa->spa_spares.sav_object,
+		    &spa->spa_spares.sav_config) != 0)
+			return (spa_vdev_err(rvd, VDEV_AUX_CORRUPT_DATA, EIO));
+
+		spa_config_enter(spa, SCL_ALL, FTAG, RW_WRITER);
+		spa_load_spares(spa);
+		spa_config_exit(spa, SCL_ALL, FTAG);
+	} else if (error == 0) {
+		spa->spa_spares.sav_sync = B_TRUE;
+	}
+
+	/*
+	 * Load any level 2 ARC devices for this pool.
+	 */
+	error = spa_dir_prop(spa, DMU_POOL_L2CACHE,
+	    &spa->spa_l2cache.sav_object);
+	if (error != 0 && error != ENOENT)
+		return (spa_vdev_err(rvd, VDEV_AUX_CORRUPT_DATA, EIO));
+	if (error == 0 && type != SPA_IMPORT_ASSEMBLE) {
+		ASSERT(spa_version(spa) >= SPA_VERSION_L2CACHE);
+		if (load_nvlist(spa, spa->spa_l2cache.sav_object,
+		    &spa->spa_l2cache.sav_config) != 0)
+			return (spa_vdev_err(rvd, VDEV_AUX_CORRUPT_DATA, EIO));
+
+		spa_config_enter(spa, SCL_ALL, FTAG, RW_WRITER);
+		spa_load_l2cache(spa);
+		spa_config_exit(spa, SCL_ALL, FTAG);
+	} else if (error == 0) {
+		spa->spa_l2cache.sav_sync = B_TRUE;
+	}
+
+	spa->spa_delegation = zpool_prop_default_numeric(ZPOOL_PROP_DELEGATION);
+
+	error = spa_dir_prop(spa, DMU_POOL_PROPS, &spa->spa_pool_props_object);
+	if (error && error != ENOENT)
+		return (spa_vdev_err(rvd, VDEV_AUX_CORRUPT_DATA, EIO));
+
+	if (error == 0) {
+		uint64_t autoreplace = 0;
+
+		spa_prop_find(spa, ZPOOL_PROP_BOOTFS, &spa->spa_bootfs);
+		spa_prop_find(spa, ZPOOL_PROP_AUTOREPLACE, &autoreplace);
+		spa_prop_find(spa, ZPOOL_PROP_DELEGATION, &spa->spa_delegation);
+		spa_prop_find(spa, ZPOOL_PROP_FAILUREMODE, &spa->spa_failmode);
+		spa_prop_find(spa, ZPOOL_PROP_AUTOEXPAND, &spa->spa_autoexpand);
+		spa_prop_find(spa, ZPOOL_PROP_DEDUPDITTO,
+		    &spa->spa_dedup_ditto);
+
+		spa->spa_autoreplace = (autoreplace != 0);
+	}
+
+	/*
+	 * If the 'autoreplace' property is set, then post a resource notifying
+	 * the ZFS DE that it should not issue any faults for unopenable
+	 * devices.  We also iterate over the vdevs, and post a sysevent for any
+	 * unopenable vdevs so that the normal autoreplace handler can take
+	 * over.
+	 */
+	if (spa->spa_autoreplace && state != SPA_LOAD_TRYIMPORT) {
+		spa_check_removed(spa->spa_root_vdev);
+		/*
+		 * For the import case, this is done in spa_import(), because
+		 * at this point we're using the spare definitions from
+		 * the MOS config, not necessarily from the userland config.
+		 */
+		if (state != SPA_LOAD_IMPORT) {
+			spa_aux_check_removed(&spa->spa_spares);
+			spa_aux_check_removed(&spa->spa_l2cache);
+		}
+	}
+
+	/*
+	 * Load the vdev state for all toplevel vdevs.
+	 */
+	vdev_load(rvd);
+
+	/*
+	 * Propagate the leaf DTLs we just loaded all the way up the tree.
+	 */
+	spa_config_enter(spa, SCL_ALL, FTAG, RW_WRITER);
+	vdev_dtl_reassess(rvd, 0, 0, B_FALSE);
+	spa_config_exit(spa, SCL_ALL, FTAG);
+
+	/*
+	 * Load the DDTs (dedup tables).
+	 */
+	error = ddt_load(spa);
+	if (error != 0)
+		return (spa_vdev_err(rvd, VDEV_AUX_CORRUPT_DATA, EIO));
+
+	spa_update_dspace(spa);
+
+	/*
+	 * Validate the config, using the MOS config to fill in any
+	 * information which might be missing.  If we fail to validate
+	 * the config then declare the pool unfit for use. If we're
+	 * assembling a pool from a split, the log is not transferred
+	 * over.
+	 */
+	if (type != SPA_IMPORT_ASSEMBLE) {
+		nvlist_t *nvconfig;
+
+		if (load_nvlist(spa, spa->spa_config_object, &nvconfig) != 0)
+			return (spa_vdev_err(rvd, VDEV_AUX_CORRUPT_DATA, EIO));
+
+		if (!spa_config_valid(spa, nvconfig)) {
+			nvlist_free(nvconfig);
+			return (spa_vdev_err(rvd, VDEV_AUX_BAD_GUID_SUM,
+			    ENXIO));
+		}
+		nvlist_free(nvconfig);
+
+		/*
+		 * Now that we've validated the config, check the state of the
+		 * root vdev.  If it can't be opened, it indicates one or
+		 * more toplevel vdevs are faulted.
+		 */
+		if (rvd->vdev_state <= VDEV_STATE_CANT_OPEN)
+			return (SET_ERROR(ENXIO));
+
+		if (spa_writeable(spa) && spa_check_logs(spa)) {
+			*ereport = FM_EREPORT_ZFS_LOG_REPLAY;
+			return (spa_vdev_err(rvd, VDEV_AUX_BAD_LOG, ENXIO));
+		}
+	}
+
+	if (missing_feat_write) {
+		ASSERT(state == SPA_LOAD_TRYIMPORT);
+
+		/*
+		 * At this point, we know that we can open the pool in
+		 * read-only mode but not read-write mode. We now have enough
+		 * information and can return to userland.
+		 */
+		return (spa_vdev_err(rvd, VDEV_AUX_UNSUP_FEAT, ENOTSUP));
+	}
+
+	/*
+	 * We've successfully opened the pool, verify that we're ready
+	 * to start pushing transactions.
+	 */
+	if (state != SPA_LOAD_TRYIMPORT) {
+		if ((error = spa_load_verify(spa)))
+			return (spa_vdev_err(rvd, VDEV_AUX_CORRUPT_DATA,
+			    error));
+	}
+
+	if (spa_writeable(spa) && (state == SPA_LOAD_RECOVER ||
+	    spa->spa_load_max_txg == UINT64_MAX)) {
+		dmu_tx_t *tx;
+		int need_update = B_FALSE;
+		dsl_pool_t *dp = spa_get_dsl(spa);
+		int c;
+
+		ASSERT(state != SPA_LOAD_TRYIMPORT);
+
+		/*
+		 * Claim log blocks that haven't been committed yet.
+		 * This must all happen in a single txg.
+		 * Note: spa_claim_max_txg is updated by spa_claim_notify(),
+		 * invoked from zil_claim_log_block()'s i/o done callback.
+		 * Price of rollback is that we abandon the log.
+		 */
+		spa->spa_claiming = B_TRUE;
+
+		tx = dmu_tx_create_assigned(dp, spa_first_txg(spa));
+		(void) dmu_objset_find_dp(dp, dp->dp_root_dir_obj,
+		    zil_claim, tx, DS_FIND_CHILDREN);
+		dmu_tx_commit(tx);
+
+		spa->spa_claiming = B_FALSE;
+
+		spa_set_log_state(spa, SPA_LOG_GOOD);
+		spa->spa_sync_on = B_TRUE;
+		txg_sync_start(spa->spa_dsl_pool);
+
+		/*
+		 * Wait for all claims to sync.  We sync up to the highest
+		 * claimed log block birth time so that claimed log blocks
+		 * don't appear to be from the future.  spa_claim_max_txg
+		 * will have been set for us by either zil_check_log_chain()
+		 * (invoked from spa_check_logs()) or zil_claim() above.
+		 */
+		txg_wait_synced(spa->spa_dsl_pool, spa->spa_claim_max_txg);
+
+		/*
+		 * If the config cache is stale, or we have uninitialized
+		 * metaslabs (see spa_vdev_add()), then update the config.
+		 *
+		 * If this is a verbatim import, trust the current
+		 * in-core spa_config and update the disk labels.
+		 */
+		if (config_cache_txg != spa->spa_config_txg ||
+		    state == SPA_LOAD_IMPORT ||
+		    state == SPA_LOAD_RECOVER ||
+		    (spa->spa_import_flags & ZFS_IMPORT_VERBATIM))
+			need_update = B_TRUE;
+
+		for (c = 0; c < rvd->vdev_children; c++)
+			if (rvd->vdev_child[c]->vdev_ms_array == 0)
+				need_update = B_TRUE;
+
+		/*
+		 * Update the config cache asychronously in case we're the
+		 * root pool, in which case the config cache isn't writable yet.
+		 */
+		if (need_update)
+			spa_async_request(spa, SPA_ASYNC_CONFIG_UPDATE);
+
+		/*
+		 * Check all DTLs to see if anything needs resilvering.
+		 */
+		if (!dsl_scan_resilvering(spa->spa_dsl_pool) &&
+		    vdev_resilver_needed(rvd, NULL, NULL))
+			spa_async_request(spa, SPA_ASYNC_RESILVER);
+
+		/*
+		 * Log the fact that we booted up (so that we can detect if
+		 * we rebooted in the middle of an operation).
+		 */
+		spa_history_log_version(spa, "open");
+
+		/*
+		 * Delete any inconsistent datasets.
+		 */
+		(void) dmu_objset_find(spa_name(spa),
+		    dsl_destroy_inconsistent, NULL, DS_FIND_CHILDREN);
+
+		/*
+		 * Clean up any stale temporary dataset userrefs.
+		 */
+		dsl_pool_clean_tmp_userrefs(spa->spa_dsl_pool);
+	}
+
+	return (0);
+}
+
+static int
+spa_load_retry(spa_t *spa, spa_load_state_t state, int mosconfig)
+{
+	int mode = spa->spa_mode;
+
+	spa_unload(spa);
+	spa_deactivate(spa);
+
+	spa->spa_load_max_txg = spa->spa_uberblock.ub_txg - 1;
+
+	spa_activate(spa, mode);
+	spa_async_suspend(spa);
+
+	return (spa_load(spa, state, SPA_IMPORT_EXISTING, mosconfig));
+}
+
+/*
+ * If spa_load() fails this function will try loading prior txg's. If
+ * 'state' is SPA_LOAD_RECOVER and one of these loads succeeds the pool
+ * will be rewound to that txg. If 'state' is not SPA_LOAD_RECOVER this
+ * function will not rewind the pool and will return the same error as
+ * spa_load().
+ */
+static int
+spa_load_best(spa_t *spa, spa_load_state_t state, int mosconfig,
+    uint64_t max_request, int rewind_flags)
+{
+	nvlist_t *loadinfo = NULL;
+	nvlist_t *config = NULL;
+	int load_error, rewind_error;
+	uint64_t safe_rewind_txg;
+	uint64_t min_txg;
+
+	if (spa->spa_load_txg && state == SPA_LOAD_RECOVER) {
+		spa->spa_load_max_txg = spa->spa_load_txg;
+		spa_set_log_state(spa, SPA_LOG_CLEAR);
+	} else {
+		spa->spa_load_max_txg = max_request;
+		if (max_request != UINT64_MAX)
+			spa->spa_extreme_rewind = B_TRUE;
+	}
+
+	load_error = rewind_error = spa_load(spa, state, SPA_IMPORT_EXISTING,
+	    mosconfig);
+	if (load_error == 0)
+		return (0);
+
+	if (spa->spa_root_vdev != NULL)
+		config = spa_config_generate(spa, NULL, -1ULL, B_TRUE);
+
+	spa->spa_last_ubsync_txg = spa->spa_uberblock.ub_txg;
+	spa->spa_last_ubsync_txg_ts = spa->spa_uberblock.ub_timestamp;
+
+	if (rewind_flags & ZPOOL_NEVER_REWIND) {
+		nvlist_free(config);
+		return (load_error);
+	}
+
+	if (state == SPA_LOAD_RECOVER) {
+		/* Price of rolling back is discarding txgs, including log */
+		spa_set_log_state(spa, SPA_LOG_CLEAR);
+	} else {
+		/*
+		 * If we aren't rolling back save the load info from our first
+		 * import attempt so that we can restore it after attempting
+		 * to rewind.
+		 */
+		loadinfo = spa->spa_load_info;
+		spa->spa_load_info = fnvlist_alloc();
+	}
+
+	spa->spa_load_max_txg = spa->spa_last_ubsync_txg;
+	safe_rewind_txg = spa->spa_last_ubsync_txg - TXG_DEFER_SIZE;
+	min_txg = (rewind_flags & ZPOOL_EXTREME_REWIND) ?
+	    TXG_INITIAL : safe_rewind_txg;
+
+	/*
+	 * Continue as long as we're finding errors, we're still within
+	 * the acceptable rewind range, and we're still finding uberblocks
+	 */
+	while (rewind_error && spa->spa_uberblock.ub_txg >= min_txg &&
+	    spa->spa_uberblock.ub_txg <= spa->spa_load_max_txg) {
+		if (spa->spa_load_max_txg < safe_rewind_txg)
+			spa->spa_extreme_rewind = B_TRUE;
+		rewind_error = spa_load_retry(spa, state, mosconfig);
+	}
+
+	spa->spa_extreme_rewind = B_FALSE;
+	spa->spa_load_max_txg = UINT64_MAX;
+
+	if (config && (rewind_error || state != SPA_LOAD_RECOVER))
+		spa_config_set(spa, config);
+
+	if (state == SPA_LOAD_RECOVER) {
+		ASSERT3P(loadinfo, ==, NULL);
+		return (rewind_error);
+	} else {
+		/* Store the rewind info as part of the initial load info */
+		fnvlist_add_nvlist(loadinfo, ZPOOL_CONFIG_REWIND_INFO,
+		    spa->spa_load_info);
+
+		/* Restore the initial load info */
+		fnvlist_free(spa->spa_load_info);
+		spa->spa_load_info = loadinfo;
+
+		return (load_error);
+	}
+}
+
+/*
+ * Pool Open/Import
+ *
+ * The import case is identical to an open except that the configuration is sent
+ * down from userland, instead of grabbed from the configuration cache.  For the
+ * case of an open, the pool configuration will exist in the
+ * POOL_STATE_UNINITIALIZED state.
+ *
+ * The stats information (gen/count/ustats) is used to gather vdev statistics at
+ * the same time open the pool, without having to keep around the spa_t in some
+ * ambiguous state.
+ */
+static int
+spa_open_common(const char *pool, spa_t **spapp, void *tag, nvlist_t *nvpolicy,
+    nvlist_t **config)
+{
+	spa_t *spa;
+	spa_load_state_t state = SPA_LOAD_OPEN;
+	int error;
+	int locked = B_FALSE;
+	int firstopen = B_FALSE;
+
+	*spapp = NULL;
+
+	/*
+	 * As disgusting as this is, we need to support recursive calls to this
+	 * function because dsl_dir_open() is called during spa_load(), and ends
+	 * up calling spa_open() again.  The real fix is to figure out how to
+	 * avoid dsl_dir_open() calling this in the first place.
+	 */
+	if (mutex_owner(&spa_namespace_lock) != curthread) {
+		mutex_enter(&spa_namespace_lock);
+		locked = B_TRUE;
+	}
+
+	if ((spa = spa_lookup(pool)) == NULL) {
+		if (locked)
+			mutex_exit(&spa_namespace_lock);
+		return (SET_ERROR(ENOENT));
+	}
+
+	if (spa->spa_state == POOL_STATE_UNINITIALIZED) {
+		zpool_rewind_policy_t policy;
+
+		firstopen = B_TRUE;
+
+		zpool_get_rewind_policy(nvpolicy ? nvpolicy : spa->spa_config,
+		    &policy);
+		if (policy.zrp_request & ZPOOL_DO_REWIND)
+			state = SPA_LOAD_RECOVER;
+
+		spa_activate(spa, spa_mode_global);
+
+		if (state != SPA_LOAD_RECOVER)
+			spa->spa_last_ubsync_txg = spa->spa_load_txg = 0;
+
+		error = spa_load_best(spa, state, B_FALSE, policy.zrp_txg,
+		    policy.zrp_request);
+
+		if (error == EBADF) {
+			/*
+			 * If vdev_validate() returns failure (indicated by
+			 * EBADF), it indicates that one of the vdevs indicates
+			 * that the pool has been exported or destroyed.  If
+			 * this is the case, the config cache is out of sync and
+			 * we should remove the pool from the namespace.
+			 */
+			spa_unload(spa);
+			spa_deactivate(spa);
+			spa_config_sync(spa, B_TRUE, B_TRUE);
+			spa_remove(spa);
+			if (locked)
+				mutex_exit(&spa_namespace_lock);
+			return (SET_ERROR(ENOENT));
+		}
+
+		if (error) {
+			/*
+			 * We can't open the pool, but we still have useful
+			 * information: the state of each vdev after the
+			 * attempted vdev_open().  Return this to the user.
+			 */
+			if (config != NULL && spa->spa_config) {
+				VERIFY(nvlist_dup(spa->spa_config, config,
+				    KM_SLEEP) == 0);
+				VERIFY(nvlist_add_nvlist(*config,
+				    ZPOOL_CONFIG_LOAD_INFO,
+				    spa->spa_load_info) == 0);
+			}
+			spa_unload(spa);
+			spa_deactivate(spa);
+			spa->spa_last_open_failed = error;
+			if (locked)
+				mutex_exit(&spa_namespace_lock);
+			*spapp = NULL;
+			return (error);
+		}
+	}
+
+	spa_open_ref(spa, tag);
+
+	if (config != NULL)
+		*config = spa_config_generate(spa, NULL, -1ULL, B_TRUE);
+
+	/*
+	 * If we've recovered the pool, pass back any information we
+	 * gathered while doing the load.
+	 */
+	if (state == SPA_LOAD_RECOVER) {
+		VERIFY(nvlist_add_nvlist(*config, ZPOOL_CONFIG_LOAD_INFO,
+		    spa->spa_load_info) == 0);
+	}
+
+	if (locked) {
+		spa->spa_last_open_failed = 0;
+		spa->spa_last_ubsync_txg = 0;
+		spa->spa_load_txg = 0;
+		mutex_exit(&spa_namespace_lock);
+	}
+
+	if (firstopen)
+		zvol_create_minors(spa, spa_name(spa), B_TRUE);
+
+	*spapp = spa;
+
+	return (0);
+}
+
+int
+spa_open_rewind(const char *name, spa_t **spapp, void *tag, nvlist_t *policy,
+    nvlist_t **config)
+{
+	return (spa_open_common(name, spapp, tag, policy, config));
+}
+
+int
+spa_open(const char *name, spa_t **spapp, void *tag)
+{
+	return (spa_open_common(name, spapp, tag, NULL, NULL));
+}
+
+/*
+ * Lookup the given spa_t, incrementing the inject count in the process,
+ * preventing it from being exported or destroyed.
+ */
+spa_t *
+spa_inject_addref(char *name)
+{
+	spa_t *spa;
+
+	mutex_enter(&spa_namespace_lock);
+	if ((spa = spa_lookup(name)) == NULL) {
+		mutex_exit(&spa_namespace_lock);
+		return (NULL);
+	}
+	spa->spa_inject_ref++;
+	mutex_exit(&spa_namespace_lock);
+
+	return (spa);
+}
+
+void
+spa_inject_delref(spa_t *spa)
+{
+	mutex_enter(&spa_namespace_lock);
+	spa->spa_inject_ref--;
+	mutex_exit(&spa_namespace_lock);
+}
+
+/*
+ * Add spares device information to the nvlist.
+ */
+static void
+spa_add_spares(spa_t *spa, nvlist_t *config)
+{
+	nvlist_t **spares;
+	uint_t i, nspares;
+	nvlist_t *nvroot;
+	uint64_t guid;
+	vdev_stat_t *vs;
+	uint_t vsc;
+	uint64_t pool;
+
+	ASSERT(spa_config_held(spa, SCL_CONFIG, RW_READER));
+
+	if (spa->spa_spares.sav_count == 0)
+		return;
+
+	VERIFY(nvlist_lookup_nvlist(config,
+	    ZPOOL_CONFIG_VDEV_TREE, &nvroot) == 0);
+	VERIFY(nvlist_lookup_nvlist_array(spa->spa_spares.sav_config,
+	    ZPOOL_CONFIG_SPARES, &spares, &nspares) == 0);
+	if (nspares != 0) {
+		VERIFY(nvlist_add_nvlist_array(nvroot,
+		    ZPOOL_CONFIG_SPARES, spares, nspares) == 0);
+		VERIFY(nvlist_lookup_nvlist_array(nvroot,
+		    ZPOOL_CONFIG_SPARES, &spares, &nspares) == 0);
+
+		/*
+		 * Go through and find any spares which have since been
+		 * repurposed as an active spare.  If this is the case, update
+		 * their status appropriately.
+		 */
+		for (i = 0; i < nspares; i++) {
+			VERIFY(nvlist_lookup_uint64(spares[i],
+			    ZPOOL_CONFIG_GUID, &guid) == 0);
+			if (spa_spare_exists(guid, &pool, NULL) &&
+			    pool != 0ULL) {
+				VERIFY(nvlist_lookup_uint64_array(
+				    spares[i], ZPOOL_CONFIG_VDEV_STATS,
+				    (uint64_t **)&vs, &vsc) == 0);
+				vs->vs_state = VDEV_STATE_CANT_OPEN;
+				vs->vs_aux = VDEV_AUX_SPARED;
+			}
+		}
+	}
+}
+
+/*
+ * Add l2cache device information to the nvlist, including vdev stats.
+ */
+static void
+spa_add_l2cache(spa_t *spa, nvlist_t *config)
+{
+	nvlist_t **l2cache;
+	uint_t i, j, nl2cache;
+	nvlist_t *nvroot;
+	uint64_t guid;
+	vdev_t *vd;
+	vdev_stat_t *vs;
+	uint_t vsc;
+
+	ASSERT(spa_config_held(spa, SCL_CONFIG, RW_READER));
+
+	if (spa->spa_l2cache.sav_count == 0)
+		return;
+
+	VERIFY(nvlist_lookup_nvlist(config,
+	    ZPOOL_CONFIG_VDEV_TREE, &nvroot) == 0);
+	VERIFY(nvlist_lookup_nvlist_array(spa->spa_l2cache.sav_config,
+	    ZPOOL_CONFIG_L2CACHE, &l2cache, &nl2cache) == 0);
+	if (nl2cache != 0) {
+		VERIFY(nvlist_add_nvlist_array(nvroot,
+		    ZPOOL_CONFIG_L2CACHE, l2cache, nl2cache) == 0);
+		VERIFY(nvlist_lookup_nvlist_array(nvroot,
+		    ZPOOL_CONFIG_L2CACHE, &l2cache, &nl2cache) == 0);
+
+		/*
+		 * Update level 2 cache device stats.
+		 */
+
+		for (i = 0; i < nl2cache; i++) {
+			VERIFY(nvlist_lookup_uint64(l2cache[i],
+			    ZPOOL_CONFIG_GUID, &guid) == 0);
+
+			vd = NULL;
+			for (j = 0; j < spa->spa_l2cache.sav_count; j++) {
+				if (guid ==
+				    spa->spa_l2cache.sav_vdevs[j]->vdev_guid) {
+					vd = spa->spa_l2cache.sav_vdevs[j];
+					break;
+				}
+			}
+			ASSERT(vd != NULL);
+
+			VERIFY(nvlist_lookup_uint64_array(l2cache[i],
+			    ZPOOL_CONFIG_VDEV_STATS, (uint64_t **)&vs, &vsc)
+			    == 0);
+			vdev_get_stats(vd, vs);
+		}
+	}
+}
+
+static void
+spa_feature_stats_from_disk(spa_t *spa, nvlist_t *features)
+{
+	zap_cursor_t zc;
+	zap_attribute_t za;
+
+	if (spa->spa_feat_for_read_obj != 0) {
+		for (zap_cursor_init(&zc, spa->spa_meta_objset,
+		    spa->spa_feat_for_read_obj);
+		    zap_cursor_retrieve(&zc, &za) == 0;
+		    zap_cursor_advance(&zc)) {
+			ASSERT(za.za_integer_length == sizeof (uint64_t) &&
+			    za.za_num_integers == 1);
+			VERIFY0(nvlist_add_uint64(features, za.za_name,
+			    za.za_first_integer));
+		}
+		zap_cursor_fini(&zc);
+	}
+
+	if (spa->spa_feat_for_write_obj != 0) {
+		for (zap_cursor_init(&zc, spa->spa_meta_objset,
+		    spa->spa_feat_for_write_obj);
+		    zap_cursor_retrieve(&zc, &za) == 0;
+		    zap_cursor_advance(&zc)) {
+			ASSERT(za.za_integer_length == sizeof (uint64_t) &&
+			    za.za_num_integers == 1);
+			VERIFY0(nvlist_add_uint64(features, za.za_name,
+			    za.za_first_integer));
+		}
+		zap_cursor_fini(&zc);
+	}
+}
+
+static void
+spa_feature_stats_from_cache(spa_t *spa, nvlist_t *features)
+{
+	int i;
+
+	for (i = 0; i < SPA_FEATURES; i++) {
+		zfeature_info_t feature = spa_feature_table[i];
+		uint64_t refcount;
+
+		if (feature_get_refcount(spa, &feature, &refcount) != 0)
+			continue;
+
+		VERIFY0(nvlist_add_uint64(features, feature.fi_guid, refcount));
+	}
+}
+
+/*
+ * Store a list of pool features and their reference counts in the
+ * config.
+ *
+ * The first time this is called on a spa, allocate a new nvlist, fetch
+ * the pool features and reference counts from disk, then save the list
+ * in the spa. In subsequent calls on the same spa use the saved nvlist
+ * and refresh its values from the cached reference counts.  This
+ * ensures we don't block here on I/O on a suspended pool so 'zpool
+ * clear' can resume the pool.
+ */
+static void
+spa_add_feature_stats(spa_t *spa, nvlist_t *config)
+{
+	nvlist_t *features;
+
+	ASSERT(spa_config_held(spa, SCL_CONFIG, RW_READER));
+
+	mutex_enter(&spa->spa_feat_stats_lock);
+	features = spa->spa_feat_stats;
+
+	if (features != NULL) {
+		spa_feature_stats_from_cache(spa, features);
+	} else {
+		VERIFY0(nvlist_alloc(&features, NV_UNIQUE_NAME, KM_SLEEP));
+		spa->spa_feat_stats = features;
+		spa_feature_stats_from_disk(spa, features);
+	}
+
+	VERIFY0(nvlist_add_nvlist(config, ZPOOL_CONFIG_FEATURE_STATS,
+	    features));
+
+	mutex_exit(&spa->spa_feat_stats_lock);
+}
+
+int
+spa_get_stats(const char *name, nvlist_t **config,
+    char *altroot, size_t buflen)
+{
+	int error;
+	spa_t *spa;
+
+	*config = NULL;
+	error = spa_open_common(name, &spa, FTAG, NULL, config);
+
+	if (spa != NULL) {
+		/*
+		 * This still leaves a window of inconsistency where the spares
+		 * or l2cache devices could change and the config would be
+		 * self-inconsistent.
+		 */
+		spa_config_enter(spa, SCL_CONFIG, FTAG, RW_READER);
+
+		if (*config != NULL) {
+			uint64_t loadtimes[2];
+
+			loadtimes[0] = spa->spa_loaded_ts.tv_sec;
+			loadtimes[1] = spa->spa_loaded_ts.tv_nsec;
+			VERIFY(nvlist_add_uint64_array(*config,
+			    ZPOOL_CONFIG_LOADED_TIME, loadtimes, 2) == 0);
+
+			VERIFY(nvlist_add_uint64(*config,
+			    ZPOOL_CONFIG_ERRCOUNT,
+			    spa_get_errlog_size(spa)) == 0);
+
+			if (spa_suspended(spa))
+				VERIFY(nvlist_add_uint64(*config,
+				    ZPOOL_CONFIG_SUSPENDED,
+				    spa->spa_failmode) == 0);
+
+			spa_add_spares(spa, *config);
+			spa_add_l2cache(spa, *config);
+			spa_add_feature_stats(spa, *config);
+		}
+	}
+
+	/*
+	 * We want to get the alternate root even for faulted pools, so we cheat
+	 * and call spa_lookup() directly.
+	 */
+	if (altroot) {
+		if (spa == NULL) {
+			mutex_enter(&spa_namespace_lock);
+			spa = spa_lookup(name);
+			if (spa)
+				spa_altroot(spa, altroot, buflen);
+			else
+				altroot[0] = '\0';
+			spa = NULL;
+			mutex_exit(&spa_namespace_lock);
+		} else {
+			spa_altroot(spa, altroot, buflen);
+		}
+	}
+
+	if (spa != NULL) {
+		spa_config_exit(spa, SCL_CONFIG, FTAG);
+		spa_close(spa, FTAG);
+	}
+
+	return (error);
+}
+
+/*
+ * Validate that the auxiliary device array is well formed.  We must have an
+ * array of nvlists, each which describes a valid leaf vdev.  If this is an
+ * import (mode is VDEV_ALLOC_SPARE), then we allow corrupted spares to be
+ * specified, as long as they are well-formed.
+ */
+static int
+spa_validate_aux_devs(spa_t *spa, nvlist_t *nvroot, uint64_t crtxg, int mode,
+    spa_aux_vdev_t *sav, const char *config, uint64_t version,
+    vdev_labeltype_t label)
+{
+	nvlist_t **dev;
+	uint_t i, ndev;
+	vdev_t *vd;
+	int error;
+
+	ASSERT(spa_config_held(spa, SCL_ALL, RW_WRITER) == SCL_ALL);
+
+	/*
+	 * It's acceptable to have no devs specified.
+	 */
+	if (nvlist_lookup_nvlist_array(nvroot, config, &dev, &ndev) != 0)
+		return (0);
+
+	if (ndev == 0)
+		return (SET_ERROR(EINVAL));
+
+	/*
+	 * Make sure the pool is formatted with a version that supports this
+	 * device type.
+	 */
+	if (spa_version(spa) < version)
+		return (SET_ERROR(ENOTSUP));
+
+	/*
+	 * Set the pending device list so we correctly handle device in-use
+	 * checking.
+	 */
+	sav->sav_pending = dev;
+	sav->sav_npending = ndev;
+
+	for (i = 0; i < ndev; i++) {
+		if ((error = spa_config_parse(spa, &vd, dev[i], NULL, 0,
+		    mode)) != 0)
+			goto out;
+
+		if (!vd->vdev_ops->vdev_op_leaf) {
+			vdev_free(vd);
+			error = SET_ERROR(EINVAL);
+			goto out;
+		}
+
+		/*
+		 * The L2ARC currently only supports disk devices in
+		 * kernel context.  For user-level testing, we allow it.
+		 */
+#ifdef _KERNEL
+		if ((strcmp(config, ZPOOL_CONFIG_L2CACHE) == 0) &&
+		    strcmp(vd->vdev_ops->vdev_op_type, VDEV_TYPE_DISK) != 0) {
+			error = SET_ERROR(ENOTBLK);
+			vdev_free(vd);
+			goto out;
+		}
+#endif
+		vd->vdev_top = vd;
+
+		if ((error = vdev_open(vd)) == 0 &&
+		    (error = vdev_label_init(vd, crtxg, label)) == 0) {
+			VERIFY(nvlist_add_uint64(dev[i], ZPOOL_CONFIG_GUID,
+			    vd->vdev_guid) == 0);
+		}
+
+		vdev_free(vd);
+
+		if (error &&
+		    (mode != VDEV_ALLOC_SPARE && mode != VDEV_ALLOC_L2CACHE))
+			goto out;
+		else
+			error = 0;
+	}
+
+out:
+	sav->sav_pending = NULL;
+	sav->sav_npending = 0;
+	return (error);
+}
+
+static int
+spa_validate_aux(spa_t *spa, nvlist_t *nvroot, uint64_t crtxg, int mode)
+{
+	int error;
+
+	ASSERT(spa_config_held(spa, SCL_ALL, RW_WRITER) == SCL_ALL);
+
+	if ((error = spa_validate_aux_devs(spa, nvroot, crtxg, mode,
+	    &spa->spa_spares, ZPOOL_CONFIG_SPARES, SPA_VERSION_SPARES,
+	    VDEV_LABEL_SPARE)) != 0) {
+		return (error);
+	}
+
+	return (spa_validate_aux_devs(spa, nvroot, crtxg, mode,
+	    &spa->spa_l2cache, ZPOOL_CONFIG_L2CACHE, SPA_VERSION_L2CACHE,
+	    VDEV_LABEL_L2CACHE));
+}
+
+static void
+spa_set_aux_vdevs(spa_aux_vdev_t *sav, nvlist_t **devs, int ndevs,
+    const char *config)
+{
+	int i;
+
+	if (sav->sav_config != NULL) {
+		nvlist_t **olddevs;
+		uint_t oldndevs;
+		nvlist_t **newdevs;
+
+		/*
+		 * Generate new dev list by concatentating with the
+		 * current dev list.
+		 */
+		VERIFY(nvlist_lookup_nvlist_array(sav->sav_config, config,
+		    &olddevs, &oldndevs) == 0);
+
+		newdevs = kmem_alloc(sizeof (void *) *
+		    (ndevs + oldndevs), KM_SLEEP);
+		for (i = 0; i < oldndevs; i++)
+			VERIFY(nvlist_dup(olddevs[i], &newdevs[i],
+			    KM_SLEEP) == 0);
+		for (i = 0; i < ndevs; i++)
+			VERIFY(nvlist_dup(devs[i], &newdevs[i + oldndevs],
+			    KM_SLEEP) == 0);
+
+		VERIFY(nvlist_remove(sav->sav_config, config,
+		    DATA_TYPE_NVLIST_ARRAY) == 0);
+
+		VERIFY(nvlist_add_nvlist_array(sav->sav_config,
+		    config, newdevs, ndevs + oldndevs) == 0);
+		for (i = 0; i < oldndevs + ndevs; i++)
+			nvlist_free(newdevs[i]);
+		kmem_free(newdevs, (oldndevs + ndevs) * sizeof (void *));
+	} else {
+		/*
+		 * Generate a new dev list.
+		 */
+		VERIFY(nvlist_alloc(&sav->sav_config, NV_UNIQUE_NAME,
+		    KM_SLEEP) == 0);
+		VERIFY(nvlist_add_nvlist_array(sav->sav_config, config,
+		    devs, ndevs) == 0);
+	}
+}
+
+/*
+ * Stop and drop level 2 ARC devices
+ */
+void
+spa_l2cache_drop(spa_t *spa)
+{
+	vdev_t *vd;
+	int i;
+	spa_aux_vdev_t *sav = &spa->spa_l2cache;
+
+	for (i = 0; i < sav->sav_count; i++) {
+		uint64_t pool;
+
+		vd = sav->sav_vdevs[i];
+		ASSERT(vd != NULL);
+
+		if (spa_l2cache_exists(vd->vdev_guid, &pool) &&
+		    pool != 0ULL && l2arc_vdev_present(vd))
+			l2arc_remove_vdev(vd);
+	}
+}
+
+/*
+ * Pool Creation
+ */
+int
+spa_create(const char *pool, nvlist_t *nvroot, nvlist_t *props,
+    nvlist_t *zplprops)
+{
+	spa_t *spa;
+	char *altroot = NULL;
+	vdev_t *rvd;
+	dsl_pool_t *dp;
+	dmu_tx_t *tx;
+	int error = 0;
+	uint64_t txg = TXG_INITIAL;
+	nvlist_t **spares, **l2cache;
+	uint_t nspares, nl2cache;
+	uint64_t version, obj;
+	boolean_t has_features;
+	nvpair_t *elem;
+	int c, i;
+	char *poolname;
+	nvlist_t *nvl;
+
+	if (nvlist_lookup_string(props, "tname", &poolname) != 0)
+		poolname = (char *)pool;
+
+	/*
+	 * If this pool already exists, return failure.
+	 */
+	mutex_enter(&spa_namespace_lock);
+	if (spa_lookup(poolname) != NULL) {
+		mutex_exit(&spa_namespace_lock);
+		return (SET_ERROR(EEXIST));
+	}
+
+	/*
+	 * Allocate a new spa_t structure.
+	 */
+	nvl = fnvlist_alloc();
+	fnvlist_add_string(nvl, ZPOOL_CONFIG_POOL_NAME, pool);
+	(void) nvlist_lookup_string(props,
+	    zpool_prop_to_name(ZPOOL_PROP_ALTROOT), &altroot);
+	spa = spa_add(poolname, nvl, altroot);
+	fnvlist_free(nvl);
+	spa_activate(spa, spa_mode_global);
+
+	if (props && (error = spa_prop_validate(spa, props))) {
+		spa_deactivate(spa);
+		spa_remove(spa);
+		mutex_exit(&spa_namespace_lock);
+		return (error);
+	}
+
+	/*
+	 * Temporary pool names should never be written to disk.
+	 */
+	if (poolname != pool)
+		spa->spa_import_flags |= ZFS_IMPORT_TEMP_NAME;
+
+	has_features = B_FALSE;
+	for (elem = nvlist_next_nvpair(props, NULL);
+	    elem != NULL; elem = nvlist_next_nvpair(props, elem)) {
+		if (zpool_prop_feature(nvpair_name(elem)))
+			has_features = B_TRUE;
+	}
+
+	if (has_features || nvlist_lookup_uint64(props,
+	    zpool_prop_to_name(ZPOOL_PROP_VERSION), &version) != 0) {
+		version = SPA_VERSION;
+	}
+	ASSERT(SPA_VERSION_IS_SUPPORTED(version));
+
+	spa->spa_first_txg = txg;
+	spa->spa_uberblock.ub_txg = txg - 1;
+	spa->spa_uberblock.ub_version = version;
+	spa->spa_ubsync = spa->spa_uberblock;
+
+	/*
+	 * Create "The Godfather" zio to hold all async IOs
+	 */
+	spa->spa_async_zio_root = kmem_alloc(max_ncpus * sizeof (void *),
+	    KM_SLEEP);
+	for (i = 0; i < max_ncpus; i++) {
+		spa->spa_async_zio_root[i] = zio_root(spa, NULL, NULL,
+		    ZIO_FLAG_CANFAIL | ZIO_FLAG_SPECULATIVE |
+		    ZIO_FLAG_GODFATHER);
+	}
+
+	/*
+	 * Create the root vdev.
+	 */
+	spa_config_enter(spa, SCL_ALL, FTAG, RW_WRITER);
+
+	error = spa_config_parse(spa, &rvd, nvroot, NULL, 0, VDEV_ALLOC_ADD);
+
+	ASSERT(error != 0 || rvd != NULL);
+	ASSERT(error != 0 || spa->spa_root_vdev == rvd);
+
+	if (error == 0 && !zfs_allocatable_devs(nvroot))
+		error = SET_ERROR(EINVAL);
+
+	if (error == 0 &&
+	    (error = vdev_create(rvd, txg, B_FALSE)) == 0 &&
+	    (error = spa_validate_aux(spa, nvroot, txg,
+	    VDEV_ALLOC_ADD)) == 0) {
+		for (c = 0; c < rvd->vdev_children; c++) {
+			vdev_metaslab_set_size(rvd->vdev_child[c]);
+			vdev_expand(rvd->vdev_child[c], txg);
+		}
+	}
+
+	spa_config_exit(spa, SCL_ALL, FTAG);
+
+	if (error != 0) {
+		spa_unload(spa);
+		spa_deactivate(spa);
+		spa_remove(spa);
+		mutex_exit(&spa_namespace_lock);
+		return (error);
+	}
+
+	/*
+	 * Get the list of spares, if specified.
+	 */
+	if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_SPARES,
+	    &spares, &nspares) == 0) {
+		VERIFY(nvlist_alloc(&spa->spa_spares.sav_config, NV_UNIQUE_NAME,
+		    KM_SLEEP) == 0);
+		VERIFY(nvlist_add_nvlist_array(spa->spa_spares.sav_config,
+		    ZPOOL_CONFIG_SPARES, spares, nspares) == 0);
+		spa_config_enter(spa, SCL_ALL, FTAG, RW_WRITER);
+		spa_load_spares(spa);
+		spa_config_exit(spa, SCL_ALL, FTAG);
+		spa->spa_spares.sav_sync = B_TRUE;
+	}
+
+	/*
+	 * Get the list of level 2 cache devices, if specified.
+	 */
+	if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_L2CACHE,
+	    &l2cache, &nl2cache) == 0) {
+		VERIFY(nvlist_alloc(&spa->spa_l2cache.sav_config,
+		    NV_UNIQUE_NAME, KM_SLEEP) == 0);
+		VERIFY(nvlist_add_nvlist_array(spa->spa_l2cache.sav_config,
+		    ZPOOL_CONFIG_L2CACHE, l2cache, nl2cache) == 0);
+		spa_config_enter(spa, SCL_ALL, FTAG, RW_WRITER);
+		spa_load_l2cache(spa);
+		spa_config_exit(spa, SCL_ALL, FTAG);
+		spa->spa_l2cache.sav_sync = B_TRUE;
+	}
+
+	spa->spa_is_initializing = B_TRUE;
+	spa->spa_dsl_pool = dp = dsl_pool_create(spa, zplprops, txg);
+	spa->spa_meta_objset = dp->dp_meta_objset;
+	spa->spa_is_initializing = B_FALSE;
+
+	/*
+	 * Create DDTs (dedup tables).
+	 */
+	ddt_create(spa);
+
+	spa_update_dspace(spa);
+
+	tx = dmu_tx_create_assigned(dp, txg);
+
+	/*
+	 * Create the pool config object.
+	 */
+	spa->spa_config_object = dmu_object_alloc(spa->spa_meta_objset,
+	    DMU_OT_PACKED_NVLIST, SPA_CONFIG_BLOCKSIZE,
+	    DMU_OT_PACKED_NVLIST_SIZE, sizeof (uint64_t), tx);
+
+	if (zap_add(spa->spa_meta_objset,
+	    DMU_POOL_DIRECTORY_OBJECT, DMU_POOL_CONFIG,
+	    sizeof (uint64_t), 1, &spa->spa_config_object, tx) != 0) {
+		cmn_err(CE_PANIC, "failed to add pool config");
+	}
+
+	if (spa_version(spa) >= SPA_VERSION_FEATURES)
+		spa_feature_create_zap_objects(spa, tx);
+
+	if (zap_add(spa->spa_meta_objset,
+	    DMU_POOL_DIRECTORY_OBJECT, DMU_POOL_CREATION_VERSION,
+	    sizeof (uint64_t), 1, &version, tx) != 0) {
+		cmn_err(CE_PANIC, "failed to add pool version");
+	}
+
+	/* Newly created pools with the right version are always deflated. */
+	if (version >= SPA_VERSION_RAIDZ_DEFLATE) {
+		spa->spa_deflate = TRUE;
+		if (zap_add(spa->spa_meta_objset,
+		    DMU_POOL_DIRECTORY_OBJECT, DMU_POOL_DEFLATE,
+		    sizeof (uint64_t), 1, &spa->spa_deflate, tx) != 0) {
+			cmn_err(CE_PANIC, "failed to add deflate");
+		}
+	}
+
+	/*
+	 * Create the deferred-free bpobj.  Turn off compression
+	 * because sync-to-convergence takes longer if the blocksize
+	 * keeps changing.
+	 */
+	obj = bpobj_alloc(spa->spa_meta_objset, 1 << 14, tx);
+	dmu_object_set_compress(spa->spa_meta_objset, obj,
+	    ZIO_COMPRESS_OFF, tx);
+	if (zap_add(spa->spa_meta_objset,
+	    DMU_POOL_DIRECTORY_OBJECT, DMU_POOL_SYNC_BPOBJ,
+	    sizeof (uint64_t), 1, &obj, tx) != 0) {
+		cmn_err(CE_PANIC, "failed to add bpobj");
+	}
+	VERIFY3U(0, ==, bpobj_open(&spa->spa_deferred_bpobj,
+	    spa->spa_meta_objset, obj));
+
+	/*
+	 * Create the pool's history object.
+	 */
+	if (version >= SPA_VERSION_ZPOOL_HISTORY)
+		spa_history_create_obj(spa, tx);
+
+	/*
+	 * Set pool properties.
+	 */
+	spa->spa_bootfs = zpool_prop_default_numeric(ZPOOL_PROP_BOOTFS);
+	spa->spa_delegation = zpool_prop_default_numeric(ZPOOL_PROP_DELEGATION);
+	spa->spa_failmode = zpool_prop_default_numeric(ZPOOL_PROP_FAILUREMODE);
+	spa->spa_autoexpand = zpool_prop_default_numeric(ZPOOL_PROP_AUTOEXPAND);
+
+	if (props != NULL) {
+		spa_configfile_set(spa, props, B_FALSE);
+		spa_sync_props(props, tx);
+	}
+
+	dmu_tx_commit(tx);
+
+	spa->spa_sync_on = B_TRUE;
+	txg_sync_start(spa->spa_dsl_pool);
+
+	/*
+	 * We explicitly wait for the first transaction to complete so that our
+	 * bean counters are appropriately updated.
+	 */
+	txg_wait_synced(spa->spa_dsl_pool, txg);
+
+	spa_config_sync(spa, B_FALSE, B_TRUE);
+
+	spa_history_log_version(spa, "create");
+
+	/*
+	 * Don't count references from objsets that are already closed
+	 * and are making their way through the eviction process.
+	 */
+	spa_evicting_os_wait(spa);
+	spa->spa_minref = refcount_count(&spa->spa_refcount);
+
+	mutex_exit(&spa_namespace_lock);
+
+	return (0);
+}
+
+#ifdef _KERNEL
+/*
+ * Get the root pool information from the root disk, then import the root pool
+ * during the system boot up time.
+ */
+extern int vdev_disk_read_rootlabel(char *, char *, nvlist_t **);
+
+static nvlist_t *
+spa_generate_rootconf(char *devpath, char *devid, uint64_t *guid)
+{
+	nvlist_t *config;
+	nvlist_t *nvtop, *nvroot;
+	uint64_t pgid;
+
+	if (vdev_disk_read_rootlabel(devpath, devid, &config) != 0)
+		return (NULL);
+
+	/*
+	 * Add this top-level vdev to the child array.
+	 */
+	VERIFY(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
+	    &nvtop) == 0);
+	VERIFY(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_GUID,
+	    &pgid) == 0);
+	VERIFY(nvlist_lookup_uint64(config, ZPOOL_CONFIG_GUID, guid) == 0);
+
+	/*
+	 * Put this pool's top-level vdevs into a root vdev.
+	 */
+	VERIFY(nvlist_alloc(&nvroot, NV_UNIQUE_NAME, KM_SLEEP) == 0);
+	VERIFY(nvlist_add_string(nvroot, ZPOOL_CONFIG_TYPE,
+	    VDEV_TYPE_ROOT) == 0);
+	VERIFY(nvlist_add_uint64(nvroot, ZPOOL_CONFIG_ID, 0ULL) == 0);
+	VERIFY(nvlist_add_uint64(nvroot, ZPOOL_CONFIG_GUID, pgid) == 0);
+	VERIFY(nvlist_add_nvlist_array(nvroot, ZPOOL_CONFIG_CHILDREN,
+	    &nvtop, 1) == 0);
+
+	/*
+	 * Replace the existing vdev_tree with the new root vdev in
+	 * this pool's configuration (remove the old, add the new).
+	 */
+	VERIFY(nvlist_add_nvlist(config, ZPOOL_CONFIG_VDEV_TREE, nvroot) == 0);
+	nvlist_free(nvroot);
+	return (config);
+}
+
+/*
+ * Walk the vdev tree and see if we can find a device with "better"
+ * configuration. A configuration is "better" if the label on that
+ * device has a more recent txg.
+ */
+static void
+spa_alt_rootvdev(vdev_t *vd, vdev_t **avd, uint64_t *txg)
+{
+	int c;
+
+	for (c = 0; c < vd->vdev_children; c++)
+		spa_alt_rootvdev(vd->vdev_child[c], avd, txg);
+
+	if (vd->vdev_ops->vdev_op_leaf) {
+		nvlist_t *label;
+		uint64_t label_txg;
+
+		if (vdev_disk_read_rootlabel(vd->vdev_physpath, vd->vdev_devid,
+		    &label) != 0)
+			return;
+
+		VERIFY(nvlist_lookup_uint64(label, ZPOOL_CONFIG_POOL_TXG,
+		    &label_txg) == 0);
+
+		/*
+		 * Do we have a better boot device?
+		 */
+		if (label_txg > *txg) {
+			*txg = label_txg;
+			*avd = vd;
+		}
+		nvlist_free(label);
+	}
+}
+
+/*
+ * Import a root pool.
+ *
+ * For x86. devpath_list will consist of devid and/or physpath name of
+ * the vdev (e.g. "id1,sd@SSEAGATE..." or "/pci@1f,0/ide@d/disk@0,0:a").
+ * The GRUB "findroot" command will return the vdev we should boot.
+ *
+ * For Sparc, devpath_list consists the physpath name of the booting device
+ * no matter the rootpool is a single device pool or a mirrored pool.
+ * e.g.
+ *	"/pci@1f,0/ide@d/disk@0,0:a"
+ */
+int
+spa_import_rootpool(char *devpath, char *devid)
+{
+	spa_t *spa;
+	vdev_t *rvd, *bvd, *avd = NULL;
+	nvlist_t *config, *nvtop;
+	uint64_t guid, txg;
+	char *pname;
+	int error;
+
+	/*
+	 * Read the label from the boot device and generate a configuration.
+	 */
+	config = spa_generate_rootconf(devpath, devid, &guid);
+#if defined(_OBP) && defined(_KERNEL)
+	if (config == NULL) {
+		if (strstr(devpath, "/iscsi/ssd") != NULL) {
+			/* iscsi boot */
+			get_iscsi_bootpath_phy(devpath);
+			config = spa_generate_rootconf(devpath, devid, &guid);
+		}
+	}
+#endif
+	if (config == NULL) {
+		cmn_err(CE_NOTE, "Cannot read the pool label from '%s'",
+		    devpath);
+		return (SET_ERROR(EIO));
+	}
+
+	VERIFY(nvlist_lookup_string(config, ZPOOL_CONFIG_POOL_NAME,
+	    &pname) == 0);
+	VERIFY(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_TXG, &txg) == 0);
+
+	mutex_enter(&spa_namespace_lock);
+	if ((spa = spa_lookup(pname)) != NULL) {
+		/*
+		 * Remove the existing root pool from the namespace so that we
+		 * can replace it with the correct config we just read in.
+		 */
+		spa_remove(spa);
+	}
+
+	spa = spa_add(pname, config, NULL);
+	spa->spa_is_root = B_TRUE;
+	spa->spa_import_flags = ZFS_IMPORT_VERBATIM;
+
+	/*
+	 * Build up a vdev tree based on the boot device's label config.
+	 */
+	VERIFY(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
+	    &nvtop) == 0);
+	spa_config_enter(spa, SCL_ALL, FTAG, RW_WRITER);
+	error = spa_config_parse(spa, &rvd, nvtop, NULL, 0,
+	    VDEV_ALLOC_ROOTPOOL);
+	spa_config_exit(spa, SCL_ALL, FTAG);
+	if (error) {
+		mutex_exit(&spa_namespace_lock);
+		nvlist_free(config);
+		cmn_err(CE_NOTE, "Can not parse the config for pool '%s'",
+		    pname);
+		return (error);
+	}
+
+	/*
+	 * Get the boot vdev.
+	 */
+	if ((bvd = vdev_lookup_by_guid(rvd, guid)) == NULL) {
+		cmn_err(CE_NOTE, "Can not find the boot vdev for guid %llu",
+		    (u_longlong_t)guid);
+		error = SET_ERROR(ENOENT);
+		goto out;
+	}
+
+	/*
+	 * Determine if there is a better boot device.
+	 */
+	avd = bvd;
+	spa_alt_rootvdev(rvd, &avd, &txg);
+	if (avd != bvd) {
+		cmn_err(CE_NOTE, "The boot device is 'degraded'. Please "
+		    "try booting from '%s'", avd->vdev_path);
+		error = SET_ERROR(EINVAL);
+		goto out;
+	}
+
+	/*
+	 * If the boot device is part of a spare vdev then ensure that
+	 * we're booting off the active spare.
+	 */
+	if (bvd->vdev_parent->vdev_ops == &vdev_spare_ops &&
+	    !bvd->vdev_isspare) {
+		cmn_err(CE_NOTE, "The boot device is currently spared. Please "
+		    "try booting from '%s'",
+		    bvd->vdev_parent->
+		    vdev_child[bvd->vdev_parent->vdev_children - 1]->vdev_path);
+		error = SET_ERROR(EINVAL);
+		goto out;
+	}
+
+	error = 0;
+out:
+	spa_config_enter(spa, SCL_ALL, FTAG, RW_WRITER);
+	vdev_free(rvd);
+	spa_config_exit(spa, SCL_ALL, FTAG);
+	mutex_exit(&spa_namespace_lock);
+
+	nvlist_free(config);
+	return (error);
+}
+
+#endif
+
+/*
+ * Import a non-root pool into the system.
+ */
+int
+spa_import(char *pool, nvlist_t *config, nvlist_t *props, uint64_t flags)
+{
+	spa_t *spa;
+	char *altroot = NULL;
+	spa_load_state_t state = SPA_LOAD_IMPORT;
+	zpool_rewind_policy_t policy;
+	uint64_t mode = spa_mode_global;
+	uint64_t readonly = B_FALSE;
+	int error;
+	nvlist_t *nvroot;
+	nvlist_t **spares, **l2cache;
+	uint_t nspares, nl2cache;
+
+	/*
+	 * If a pool with this name exists, return failure.
+	 */
+	mutex_enter(&spa_namespace_lock);
+	if (spa_lookup(pool) != NULL) {
+		mutex_exit(&spa_namespace_lock);
+		return (SET_ERROR(EEXIST));
+	}
+
+	/*
+	 * Create and initialize the spa structure.
+	 */
+	(void) nvlist_lookup_string(props,
+	    zpool_prop_to_name(ZPOOL_PROP_ALTROOT), &altroot);
+	(void) nvlist_lookup_uint64(props,
+	    zpool_prop_to_name(ZPOOL_PROP_READONLY), &readonly);
+	if (readonly)
+		mode = FREAD;
+	spa = spa_add(pool, config, altroot);
+	spa->spa_import_flags = flags;
+
+	/*
+	 * Verbatim import - Take a pool and insert it into the namespace
+	 * as if it had been loaded at boot.
+	 */
+	if (spa->spa_import_flags & ZFS_IMPORT_VERBATIM) {
+		if (props != NULL)
+			spa_configfile_set(spa, props, B_FALSE);
+
+		spa_config_sync(spa, B_FALSE, B_TRUE);
+
+		mutex_exit(&spa_namespace_lock);
+		return (0);
+	}
+
+	spa_activate(spa, mode);
+
+	/*
+	 * Don't start async tasks until we know everything is healthy.
+	 */
+	spa_async_suspend(spa);
+
+	zpool_get_rewind_policy(config, &policy);
+	if (policy.zrp_request & ZPOOL_DO_REWIND)
+		state = SPA_LOAD_RECOVER;
+
+	/*
+	 * Pass off the heavy lifting to spa_load().  Pass TRUE for mosconfig
+	 * because the user-supplied config is actually the one to trust when
+	 * doing an import.
+	 */
+	if (state != SPA_LOAD_RECOVER)
+		spa->spa_last_ubsync_txg = spa->spa_load_txg = 0;
+
+	error = spa_load_best(spa, state, B_TRUE, policy.zrp_txg,
+	    policy.zrp_request);
+
+	/*
+	 * Propagate anything learned while loading the pool and pass it
+	 * back to caller (i.e. rewind info, missing devices, etc).
+	 */
+	VERIFY(nvlist_add_nvlist(config, ZPOOL_CONFIG_LOAD_INFO,
+	    spa->spa_load_info) == 0);
+
+	spa_config_enter(spa, SCL_ALL, FTAG, RW_WRITER);
+	/*
+	 * Toss any existing sparelist, as it doesn't have any validity
+	 * anymore, and conflicts with spa_has_spare().
+	 */
+	if (spa->spa_spares.sav_config) {
+		nvlist_free(spa->spa_spares.sav_config);
+		spa->spa_spares.sav_config = NULL;
+		spa_load_spares(spa);
+	}
+	if (spa->spa_l2cache.sav_config) {
+		nvlist_free(spa->spa_l2cache.sav_config);
+		spa->spa_l2cache.sav_config = NULL;
+		spa_load_l2cache(spa);
+	}
+
+	VERIFY(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
+	    &nvroot) == 0);
+	if (error == 0)
+		error = spa_validate_aux(spa, nvroot, -1ULL,
+		    VDEV_ALLOC_SPARE);
+	if (error == 0)
+		error = spa_validate_aux(spa, nvroot, -1ULL,
+		    VDEV_ALLOC_L2CACHE);
+	spa_config_exit(spa, SCL_ALL, FTAG);
+
+	if (props != NULL)
+		spa_configfile_set(spa, props, B_FALSE);
+
+	if (error != 0 || (props && spa_writeable(spa) &&
+	    (error = spa_prop_set(spa, props)))) {
+		spa_unload(spa);
+		spa_deactivate(spa);
+		spa_remove(spa);
+		mutex_exit(&spa_namespace_lock);
+		return (error);
+	}
+
+	spa_async_resume(spa);
+
+	/*
+	 * Override any spares and level 2 cache devices as specified by
+	 * the user, as these may have correct device names/devids, etc.
+	 */
+	if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_SPARES,
+	    &spares, &nspares) == 0) {
+		if (spa->spa_spares.sav_config)
+			VERIFY(nvlist_remove(spa->spa_spares.sav_config,
+			    ZPOOL_CONFIG_SPARES, DATA_TYPE_NVLIST_ARRAY) == 0);
+		else
+			VERIFY(nvlist_alloc(&spa->spa_spares.sav_config,
+			    NV_UNIQUE_NAME, KM_SLEEP) == 0);
+		VERIFY(nvlist_add_nvlist_array(spa->spa_spares.sav_config,
+		    ZPOOL_CONFIG_SPARES, spares, nspares) == 0);
+		spa_config_enter(spa, SCL_ALL, FTAG, RW_WRITER);
+		spa_load_spares(spa);
+		spa_config_exit(spa, SCL_ALL, FTAG);
+		spa->spa_spares.sav_sync = B_TRUE;
+	}
+	if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_L2CACHE,
+	    &l2cache, &nl2cache) == 0) {
+		if (spa->spa_l2cache.sav_config)
+			VERIFY(nvlist_remove(spa->spa_l2cache.sav_config,
+			    ZPOOL_CONFIG_L2CACHE, DATA_TYPE_NVLIST_ARRAY) == 0);
+		else
+			VERIFY(nvlist_alloc(&spa->spa_l2cache.sav_config,
+			    NV_UNIQUE_NAME, KM_SLEEP) == 0);
+		VERIFY(nvlist_add_nvlist_array(spa->spa_l2cache.sav_config,
+		    ZPOOL_CONFIG_L2CACHE, l2cache, nl2cache) == 0);
+		spa_config_enter(spa, SCL_ALL, FTAG, RW_WRITER);
+		spa_load_l2cache(spa);
+		spa_config_exit(spa, SCL_ALL, FTAG);
+		spa->spa_l2cache.sav_sync = B_TRUE;
+	}
+
+	/*
+	 * Check for any removed devices.
+	 */
+	if (spa->spa_autoreplace) {
+		spa_aux_check_removed(&spa->spa_spares);
+		spa_aux_check_removed(&spa->spa_l2cache);
+	}
+
+	if (spa_writeable(spa)) {
+		/*
+		 * Update the config cache to include the newly-imported pool.
+		 */
+		spa_config_update(spa, SPA_CONFIG_UPDATE_POOL);
+	}
+
+	/*
+	 * It's possible that the pool was expanded while it was exported.
+	 * We kick off an async task to handle this for us.
+	 */
+	spa_async_request(spa, SPA_ASYNC_AUTOEXPAND);
+
+	mutex_exit(&spa_namespace_lock);
+	spa_history_log_version(spa, "import");
+	zvol_create_minors(spa, pool, B_TRUE);
+
+	return (0);
+}
+
+nvlist_t *
+spa_tryimport(nvlist_t *tryconfig)
+{
+	nvlist_t *config = NULL;
+	char *poolname;
+	spa_t *spa;
+	uint64_t state;
+	int error;
+
+	if (nvlist_lookup_string(tryconfig, ZPOOL_CONFIG_POOL_NAME, &poolname))
+		return (NULL);
+
+	if (nvlist_lookup_uint64(tryconfig, ZPOOL_CONFIG_POOL_STATE, &state))
+		return (NULL);
+
+	/*
+	 * Create and initialize the spa structure.
+	 */
+	mutex_enter(&spa_namespace_lock);
+	spa = spa_add(TRYIMPORT_NAME, tryconfig, NULL);
+	spa_activate(spa, FREAD);
+
+	/*
+	 * Pass off the heavy lifting to spa_load().
+	 * Pass TRUE for mosconfig because the user-supplied config
+	 * is actually the one to trust when doing an import.
+	 */
+	error = spa_load(spa, SPA_LOAD_TRYIMPORT, SPA_IMPORT_EXISTING, B_TRUE);
+
+	/*
+	 * If 'tryconfig' was at least parsable, return the current config.
+	 */
+	if (spa->spa_root_vdev != NULL) {
+		config = spa_config_generate(spa, NULL, -1ULL, B_TRUE);
+		VERIFY(nvlist_add_string(config, ZPOOL_CONFIG_POOL_NAME,
+		    poolname) == 0);
+		VERIFY(nvlist_add_uint64(config, ZPOOL_CONFIG_POOL_STATE,
+		    state) == 0);
+		VERIFY(nvlist_add_uint64(config, ZPOOL_CONFIG_TIMESTAMP,
+		    spa->spa_uberblock.ub_timestamp) == 0);
+		VERIFY(nvlist_add_nvlist(config, ZPOOL_CONFIG_LOAD_INFO,
+		    spa->spa_load_info) == 0);
+		VERIFY(nvlist_add_uint64(config, ZPOOL_CONFIG_ERRATA,
+		    spa->spa_errata) == 0);
+
+		/*
+		 * If the bootfs property exists on this pool then we
+		 * copy it out so that external consumers can tell which
+		 * pools are bootable.
+		 */
+		if ((!error || error == EEXIST) && spa->spa_bootfs) {
+			char *tmpname = kmem_alloc(MAXPATHLEN, KM_SLEEP);
+
+			/*
+			 * We have to play games with the name since the
+			 * pool was opened as TRYIMPORT_NAME.
+			 */
+			if (dsl_dsobj_to_dsname(spa_name(spa),
+			    spa->spa_bootfs, tmpname) == 0) {
+				char *cp;
+				char *dsname;
+
+				dsname = kmem_alloc(MAXPATHLEN, KM_SLEEP);
+
+				cp = strchr(tmpname, '/');
+				if (cp == NULL) {
+					(void) strlcpy(dsname, tmpname,
+					    MAXPATHLEN);
+				} else {
+					(void) snprintf(dsname, MAXPATHLEN,
+					    "%s/%s", poolname, ++cp);
+				}
+				VERIFY(nvlist_add_string(config,
+				    ZPOOL_CONFIG_BOOTFS, dsname) == 0);
+				kmem_free(dsname, MAXPATHLEN);
+			}
+			kmem_free(tmpname, MAXPATHLEN);
+		}
+
+		/*
+		 * Add the list of hot spares and level 2 cache devices.
+		 */
+		spa_config_enter(spa, SCL_CONFIG, FTAG, RW_READER);
+		spa_add_spares(spa, config);
+		spa_add_l2cache(spa, config);
+		spa_config_exit(spa, SCL_CONFIG, FTAG);
+	}
+
+	spa_unload(spa);
+	spa_deactivate(spa);
+	spa_remove(spa);
+	mutex_exit(&spa_namespace_lock);
+
+	return (config);
+}
+
+/*
+ * Pool export/destroy
+ *
+ * The act of destroying or exporting a pool is very simple.  We make sure there
+ * is no more pending I/O and any references to the pool are gone.  Then, we
+ * update the pool state and sync all the labels to disk, removing the
+ * configuration from the cache afterwards. If the 'hardforce' flag is set, then
+ * we don't sync the labels or remove the configuration cache.
+ */
+static int
+spa_export_common(char *pool, int new_state, nvlist_t **oldconfig,
+    boolean_t force, boolean_t hardforce)
+{
+	spa_t *spa;
+
+	if (oldconfig)
+		*oldconfig = NULL;
+
+	if (!(spa_mode_global & FWRITE))
+		return (SET_ERROR(EROFS));
+
+	mutex_enter(&spa_namespace_lock);
+	if ((spa = spa_lookup(pool)) == NULL) {
+		mutex_exit(&spa_namespace_lock);
+		return (SET_ERROR(ENOENT));
+	}
+
+	/*
+	 * Put a hold on the pool, drop the namespace lock, stop async tasks,
+	 * reacquire the namespace lock, and see if we can export.
+	 */
+	spa_open_ref(spa, FTAG);
+	mutex_exit(&spa_namespace_lock);
+	spa_async_suspend(spa);
+	if (spa->spa_zvol_taskq) {
+		zvol_remove_minors(spa, spa_name(spa), B_TRUE);
+		taskq_wait(spa->spa_zvol_taskq);
+	}
+	mutex_enter(&spa_namespace_lock);
+	spa_close(spa, FTAG);
+
+	if (spa->spa_state == POOL_STATE_UNINITIALIZED)
+		goto export_spa;
+	/*
+	 * The pool will be in core if it's openable, in which case we can
+	 * modify its state.  Objsets may be open only because they're dirty,
+	 * so we have to force it to sync before checking spa_refcnt.
+	 */
+	if (spa->spa_sync_on) {
+		txg_wait_synced(spa->spa_dsl_pool, 0);
+		spa_evicting_os_wait(spa);
+	}
+
+	/*
+	 * A pool cannot be exported or destroyed if there are active
+	 * references.  If we are resetting a pool, allow references by
+	 * fault injection handlers.
+	 */
+	if (!spa_refcount_zero(spa) ||
+	    (spa->spa_inject_ref != 0 &&
+	    new_state != POOL_STATE_UNINITIALIZED)) {
+		spa_async_resume(spa);
+		mutex_exit(&spa_namespace_lock);
+		return (SET_ERROR(EBUSY));
+	}
+
+	if (spa->spa_sync_on) {
+		/*
+		 * A pool cannot be exported if it has an active shared spare.
+		 * This is to prevent other pools stealing the active spare
+		 * from an exported pool. At user's own will, such pool can
+		 * be forcedly exported.
+		 */
+		if (!force && new_state == POOL_STATE_EXPORTED &&
+		    spa_has_active_shared_spare(spa)) {
+			spa_async_resume(spa);
+			mutex_exit(&spa_namespace_lock);
+			return (SET_ERROR(EXDEV));
+		}
+
+		/*
+		 * We want this to be reflected on every label,
+		 * so mark them all dirty.  spa_unload() will do the
+		 * final sync that pushes these changes out.
+		 */
+		if (new_state != POOL_STATE_UNINITIALIZED && !hardforce) {
+			spa_config_enter(spa, SCL_ALL, FTAG, RW_WRITER);
+			spa->spa_state = new_state;
+			spa->spa_final_txg = spa_last_synced_txg(spa) +
+			    TXG_DEFER_SIZE + 1;
+			vdev_config_dirty(spa->spa_root_vdev);
+			spa_config_exit(spa, SCL_ALL, FTAG);
+		}
+	}
+
+export_spa:
+	spa_event_notify(spa, NULL, FM_EREPORT_ZFS_POOL_DESTROY);
+
+	if (spa->spa_state != POOL_STATE_UNINITIALIZED) {
+		spa_unload(spa);
+		spa_deactivate(spa);
+	}
+
+	if (oldconfig && spa->spa_config)
+		VERIFY(nvlist_dup(spa->spa_config, oldconfig, 0) == 0);
+
+	if (new_state != POOL_STATE_UNINITIALIZED) {
+		if (!hardforce)
+			spa_config_sync(spa, B_TRUE, B_TRUE);
+		spa_remove(spa);
+	}
+	mutex_exit(&spa_namespace_lock);
+
+	return (0);
+}
+
+/*
+ * Destroy a storage pool.
+ */
+int
+spa_destroy(char *pool)
+{
+	return (spa_export_common(pool, POOL_STATE_DESTROYED, NULL,
+	    B_FALSE, B_FALSE));
+}
+
+/*
+ * Export a storage pool.
+ */
+int
+spa_export(char *pool, nvlist_t **oldconfig, boolean_t force,
+    boolean_t hardforce)
+{
+	return (spa_export_common(pool, POOL_STATE_EXPORTED, oldconfig,
+	    force, hardforce));
+}
+
+/*
+ * Similar to spa_export(), this unloads the spa_t without actually removing it
+ * from the namespace in any way.
+ */
+int
+spa_reset(char *pool)
+{
+	return (spa_export_common(pool, POOL_STATE_UNINITIALIZED, NULL,
+	    B_FALSE, B_FALSE));
+}
+
+/*
+ * ==========================================================================
+ * Device manipulation
+ * ==========================================================================
+ */
+
+/*
+ * Add a device to a storage pool.
+ */
+int
+spa_vdev_add(spa_t *spa, nvlist_t *nvroot)
+{
+	uint64_t txg, id;
+	int error;
+	vdev_t *rvd = spa->spa_root_vdev;
+	vdev_t *vd, *tvd;
+	nvlist_t **spares, **l2cache;
+	uint_t nspares, nl2cache;
+	int c;
+
+	ASSERT(spa_writeable(spa));
+
+	txg = spa_vdev_enter(spa);
+
+	if ((error = spa_config_parse(spa, &vd, nvroot, NULL, 0,
+	    VDEV_ALLOC_ADD)) != 0)
+		return (spa_vdev_exit(spa, NULL, txg, error));
+
+	spa->spa_pending_vdev = vd;	/* spa_vdev_exit() will clear this */
+
+	if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_SPARES, &spares,
+	    &nspares) != 0)
+		nspares = 0;
+
+	if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_L2CACHE, &l2cache,
+	    &nl2cache) != 0)
+		nl2cache = 0;
+
+	if (vd->vdev_children == 0 && nspares == 0 && nl2cache == 0)
+		return (spa_vdev_exit(spa, vd, txg, EINVAL));
+
+	if (vd->vdev_children != 0 &&
+	    (error = vdev_create(vd, txg, B_FALSE)) != 0)
+		return (spa_vdev_exit(spa, vd, txg, error));
+
+	/*
+	 * We must validate the spares and l2cache devices after checking the
+	 * children.  Otherwise, vdev_inuse() will blindly overwrite the spare.
+	 */
+	if ((error = spa_validate_aux(spa, nvroot, txg, VDEV_ALLOC_ADD)) != 0)
+		return (spa_vdev_exit(spa, vd, txg, error));
+
+	/*
+	 * Transfer each new top-level vdev from vd to rvd.
+	 */
+	for (c = 0; c < vd->vdev_children; c++) {
+
+		/*
+		 * Set the vdev id to the first hole, if one exists.
+		 */
+		for (id = 0; id < rvd->vdev_children; id++) {
+			if (rvd->vdev_child[id]->vdev_ishole) {
+				vdev_free(rvd->vdev_child[id]);
+				break;
+			}
+		}
+		tvd = vd->vdev_child[c];
+		vdev_remove_child(vd, tvd);
+		tvd->vdev_id = id;
+		vdev_add_child(rvd, tvd);
+		vdev_config_dirty(tvd);
+	}
+
+	if (nspares != 0) {
+		spa_set_aux_vdevs(&spa->spa_spares, spares, nspares,
+		    ZPOOL_CONFIG_SPARES);
+		spa_load_spares(spa);
+		spa->spa_spares.sav_sync = B_TRUE;
+	}
+
+	if (nl2cache != 0) {
+		spa_set_aux_vdevs(&spa->spa_l2cache, l2cache, nl2cache,
+		    ZPOOL_CONFIG_L2CACHE);
+		spa_load_l2cache(spa);
+		spa->spa_l2cache.sav_sync = B_TRUE;
+	}
+
+	/*
+	 * We have to be careful when adding new vdevs to an existing pool.
+	 * If other threads start allocating from these vdevs before we
+	 * sync the config cache, and we lose power, then upon reboot we may
+	 * fail to open the pool because there are DVAs that the config cache
+	 * can't translate.  Therefore, we first add the vdevs without
+	 * initializing metaslabs; sync the config cache (via spa_vdev_exit());
+	 * and then let spa_config_update() initialize the new metaslabs.
+	 *
+	 * spa_load() checks for added-but-not-initialized vdevs, so that
+	 * if we lose power at any point in this sequence, the remaining
+	 * steps will be completed the next time we load the pool.
+	 */
+	(void) spa_vdev_exit(spa, vd, txg, 0);
+
+	mutex_enter(&spa_namespace_lock);
+	spa_config_update(spa, SPA_CONFIG_UPDATE_POOL);
+	mutex_exit(&spa_namespace_lock);
+
+	return (0);
+}
+
+/*
+ * Attach a device to a mirror.  The arguments are the path to any device
+ * in the mirror, and the nvroot for the new device.  If the path specifies
+ * a device that is not mirrored, we automatically insert the mirror vdev.
+ *
+ * If 'replacing' is specified, the new device is intended to replace the
+ * existing device; in this case the two devices are made into their own
+ * mirror using the 'replacing' vdev, which is functionally identical to
+ * the mirror vdev (it actually reuses all the same ops) but has a few
+ * extra rules: you can't attach to it after it's been created, and upon
+ * completion of resilvering, the first disk (the one being replaced)
+ * is automatically detached.
+ */
+int
+spa_vdev_attach(spa_t *spa, uint64_t guid, nvlist_t *nvroot, int replacing)
+{
+	uint64_t txg, dtl_max_txg;
+	vdev_t *oldvd, *newvd, *newrootvd, *pvd, *tvd;
+	vdev_ops_t *pvops;
+	char *oldvdpath, *newvdpath;
+	int newvd_isspare;
+	int error;
+	ASSERTV(vdev_t *rvd = spa->spa_root_vdev);
+
+	ASSERT(spa_writeable(spa));
+
+	txg = spa_vdev_enter(spa);
+
+	oldvd = spa_lookup_by_guid(spa, guid, B_FALSE);
+
+	if (oldvd == NULL)
+		return (spa_vdev_exit(spa, NULL, txg, ENODEV));
+
+	if (!oldvd->vdev_ops->vdev_op_leaf)
+		return (spa_vdev_exit(spa, NULL, txg, ENOTSUP));
+
+	pvd = oldvd->vdev_parent;
+
+	if ((error = spa_config_parse(spa, &newrootvd, nvroot, NULL, 0,
+	    VDEV_ALLOC_ATTACH)) != 0)
+		return (spa_vdev_exit(spa, NULL, txg, EINVAL));
+
+	if (newrootvd->vdev_children != 1)
+		return (spa_vdev_exit(spa, newrootvd, txg, EINVAL));
+
+	newvd = newrootvd->vdev_child[0];
+
+	if (!newvd->vdev_ops->vdev_op_leaf)
+		return (spa_vdev_exit(spa, newrootvd, txg, EINVAL));
+
+	if ((error = vdev_create(newrootvd, txg, replacing)) != 0)
+		return (spa_vdev_exit(spa, newrootvd, txg, error));
+
+	/*
+	 * Spares can't replace logs
+	 */
+	if (oldvd->vdev_top->vdev_islog && newvd->vdev_isspare)
+		return (spa_vdev_exit(spa, newrootvd, txg, ENOTSUP));
+
+	if (!replacing) {
+		/*
+		 * For attach, the only allowable parent is a mirror or the root
+		 * vdev.
+		 */
+		if (pvd->vdev_ops != &vdev_mirror_ops &&
+		    pvd->vdev_ops != &vdev_root_ops)
+			return (spa_vdev_exit(spa, newrootvd, txg, ENOTSUP));
+
+		pvops = &vdev_mirror_ops;
+	} else {
+		/*
+		 * Active hot spares can only be replaced by inactive hot
+		 * spares.
+		 */
+		if (pvd->vdev_ops == &vdev_spare_ops &&
+		    oldvd->vdev_isspare &&
+		    !spa_has_spare(spa, newvd->vdev_guid))
+			return (spa_vdev_exit(spa, newrootvd, txg, ENOTSUP));
+
+		/*
+		 * If the source is a hot spare, and the parent isn't already a
+		 * spare, then we want to create a new hot spare.  Otherwise, we
+		 * want to create a replacing vdev.  The user is not allowed to
+		 * attach to a spared vdev child unless the 'isspare' state is
+		 * the same (spare replaces spare, non-spare replaces
+		 * non-spare).
+		 */
+		if (pvd->vdev_ops == &vdev_replacing_ops &&
+		    spa_version(spa) < SPA_VERSION_MULTI_REPLACE) {
+			return (spa_vdev_exit(spa, newrootvd, txg, ENOTSUP));
+		} else if (pvd->vdev_ops == &vdev_spare_ops &&
+		    newvd->vdev_isspare != oldvd->vdev_isspare) {
+			return (spa_vdev_exit(spa, newrootvd, txg, ENOTSUP));
+		}
+
+		if (newvd->vdev_isspare)
+			pvops = &vdev_spare_ops;
+		else
+			pvops = &vdev_replacing_ops;
+	}
+
+	/*
+	 * Make sure the new device is big enough.
+	 */
+	if (newvd->vdev_asize < vdev_get_min_asize(oldvd))
+		return (spa_vdev_exit(spa, newrootvd, txg, EOVERFLOW));
+
+	/*
+	 * The new device cannot have a higher alignment requirement
+	 * than the top-level vdev.
+	 */
+	if (newvd->vdev_ashift > oldvd->vdev_top->vdev_ashift)
+		return (spa_vdev_exit(spa, newrootvd, txg, EDOM));
+
+	/*
+	 * If this is an in-place replacement, update oldvd's path and devid
+	 * to make it distinguishable from newvd, and unopenable from now on.
+	 */
+	if (strcmp(oldvd->vdev_path, newvd->vdev_path) == 0) {
+		spa_strfree(oldvd->vdev_path);
+		oldvd->vdev_path = kmem_alloc(strlen(newvd->vdev_path) + 5,
+		    KM_SLEEP);
+		(void) sprintf(oldvd->vdev_path, "%s/%s",
+		    newvd->vdev_path, "old");
+		if (oldvd->vdev_devid != NULL) {
+			spa_strfree(oldvd->vdev_devid);
+			oldvd->vdev_devid = NULL;
+		}
+	}
+
+	/* mark the device being resilvered */
+	newvd->vdev_resilver_txg = txg;
+
+	/*
+	 * If the parent is not a mirror, or if we're replacing, insert the new
+	 * mirror/replacing/spare vdev above oldvd.
+	 */
+	if (pvd->vdev_ops != pvops)
+		pvd = vdev_add_parent(oldvd, pvops);
+
+	ASSERT(pvd->vdev_top->vdev_parent == rvd);
+	ASSERT(pvd->vdev_ops == pvops);
+	ASSERT(oldvd->vdev_parent == pvd);
+
+	/*
+	 * Extract the new device from its root and add it to pvd.
+	 */
+	vdev_remove_child(newrootvd, newvd);
+	newvd->vdev_id = pvd->vdev_children;
+	newvd->vdev_crtxg = oldvd->vdev_crtxg;
+	vdev_add_child(pvd, newvd);
+
+	tvd = newvd->vdev_top;
+	ASSERT(pvd->vdev_top == tvd);
+	ASSERT(tvd->vdev_parent == rvd);
+
+	vdev_config_dirty(tvd);
+
+	/*
+	 * Set newvd's DTL to [TXG_INITIAL, dtl_max_txg) so that we account
+	 * for any dmu_sync-ed blocks.  It will propagate upward when
+	 * spa_vdev_exit() calls vdev_dtl_reassess().
+	 */
+	dtl_max_txg = txg + TXG_CONCURRENT_STATES;
+
+	vdev_dtl_dirty(newvd, DTL_MISSING, TXG_INITIAL,
+	    dtl_max_txg - TXG_INITIAL);
+
+	if (newvd->vdev_isspare) {
+		spa_spare_activate(newvd);
+		spa_event_notify(spa, newvd, FM_EREPORT_ZFS_DEVICE_SPARE);
+	}
+
+	oldvdpath = spa_strdup(oldvd->vdev_path);
+	newvdpath = spa_strdup(newvd->vdev_path);
+	newvd_isspare = newvd->vdev_isspare;
+
+	/*
+	 * Mark newvd's DTL dirty in this txg.
+	 */
+	vdev_dirty(tvd, VDD_DTL, newvd, txg);
+
+	/*
+	 * Schedule the resilver to restart in the future. We do this to
+	 * ensure that dmu_sync-ed blocks have been stitched into the
+	 * respective datasets.
+	 */
+	dsl_resilver_restart(spa->spa_dsl_pool, dtl_max_txg);
+
+	/*
+	 * Commit the config
+	 */
+	(void) spa_vdev_exit(spa, newrootvd, dtl_max_txg, 0);
+
+	spa_history_log_internal(spa, "vdev attach", NULL,
+	    "%s vdev=%s %s vdev=%s",
+	    replacing && newvd_isspare ? "spare in" :
+	    replacing ? "replace" : "attach", newvdpath,
+	    replacing ? "for" : "to", oldvdpath);
+
+	spa_strfree(oldvdpath);
+	spa_strfree(newvdpath);
+
+	if (spa->spa_bootfs)
+		spa_event_notify(spa, newvd, FM_EREPORT_ZFS_BOOTFS_VDEV_ATTACH);
+
+	return (0);
+}
+
+/*
+ * Detach a device from a mirror or replacing vdev.
+ *
+ * If 'replace_done' is specified, only detach if the parent
+ * is a replacing vdev.
+ */
+int
+spa_vdev_detach(spa_t *spa, uint64_t guid, uint64_t pguid, int replace_done)
+{
+	uint64_t txg;
+	int error;
+	vdev_t *vd, *pvd, *cvd, *tvd;
+	boolean_t unspare = B_FALSE;
+	uint64_t unspare_guid = 0;
+	char *vdpath;
+	int c, t;
+	ASSERTV(vdev_t *rvd = spa->spa_root_vdev);
+	ASSERT(spa_writeable(spa));
+
+	txg = spa_vdev_enter(spa);
+
+	vd = spa_lookup_by_guid(spa, guid, B_FALSE);
+
+	if (vd == NULL)
+		return (spa_vdev_exit(spa, NULL, txg, ENODEV));
+
+	if (!vd->vdev_ops->vdev_op_leaf)
+		return (spa_vdev_exit(spa, NULL, txg, ENOTSUP));
+
+	pvd = vd->vdev_parent;
+
+	/*
+	 * If the parent/child relationship is not as expected, don't do it.
+	 * Consider M(A,R(B,C)) -- that is, a mirror of A with a replacing
+	 * vdev that's replacing B with C.  The user's intent in replacing
+	 * is to go from M(A,B) to M(A,C).  If the user decides to cancel
+	 * the replace by detaching C, the expected behavior is to end up
+	 * M(A,B).  But suppose that right after deciding to detach C,
+	 * the replacement of B completes.  We would have M(A,C), and then
+	 * ask to detach C, which would leave us with just A -- not what
+	 * the user wanted.  To prevent this, we make sure that the
+	 * parent/child relationship hasn't changed -- in this example,
+	 * that C's parent is still the replacing vdev R.
+	 */
+	if (pvd->vdev_guid != pguid && pguid != 0)
+		return (spa_vdev_exit(spa, NULL, txg, EBUSY));
+
+	/*
+	 * Only 'replacing' or 'spare' vdevs can be replaced.
+	 */
+	if (replace_done && pvd->vdev_ops != &vdev_replacing_ops &&
+	    pvd->vdev_ops != &vdev_spare_ops)
+		return (spa_vdev_exit(spa, NULL, txg, ENOTSUP));
+
+	ASSERT(pvd->vdev_ops != &vdev_spare_ops ||
+	    spa_version(spa) >= SPA_VERSION_SPARES);
+
+	/*
+	 * Only mirror, replacing, and spare vdevs support detach.
+	 */
+	if (pvd->vdev_ops != &vdev_replacing_ops &&
+	    pvd->vdev_ops != &vdev_mirror_ops &&
+	    pvd->vdev_ops != &vdev_spare_ops)
+		return (spa_vdev_exit(spa, NULL, txg, ENOTSUP));
+
+	/*
+	 * If this device has the only valid copy of some data,
+	 * we cannot safely detach it.
+	 */
+	if (vdev_dtl_required(vd))
+		return (spa_vdev_exit(spa, NULL, txg, EBUSY));
+
+	ASSERT(pvd->vdev_children >= 2);
+
+	/*
+	 * If we are detaching the second disk from a replacing vdev, then
+	 * check to see if we changed the original vdev's path to have "/old"
+	 * at the end in spa_vdev_attach().  If so, undo that change now.
+	 */
+	if (pvd->vdev_ops == &vdev_replacing_ops && vd->vdev_id > 0 &&
+	    vd->vdev_path != NULL) {
+		size_t len = strlen(vd->vdev_path);
+
+		for (c = 0; c < pvd->vdev_children; c++) {
+			cvd = pvd->vdev_child[c];
+
+			if (cvd == vd || cvd->vdev_path == NULL)
+				continue;
+
+			if (strncmp(cvd->vdev_path, vd->vdev_path, len) == 0 &&
+			    strcmp(cvd->vdev_path + len, "/old") == 0) {
+				spa_strfree(cvd->vdev_path);
+				cvd->vdev_path = spa_strdup(vd->vdev_path);
+				break;
+			}
+		}
+	}
+
+	/*
+	 * If we are detaching the original disk from a spare, then it implies
+	 * that the spare should become a real disk, and be removed from the
+	 * active spare list for the pool.
+	 */
+	if (pvd->vdev_ops == &vdev_spare_ops &&
+	    vd->vdev_id == 0 &&
+	    pvd->vdev_child[pvd->vdev_children - 1]->vdev_isspare)
+		unspare = B_TRUE;
+
+	/*
+	 * Erase the disk labels so the disk can be used for other things.
+	 * This must be done after all other error cases are handled,
+	 * but before we disembowel vd (so we can still do I/O to it).
+	 * But if we can't do it, don't treat the error as fatal --
+	 * it may be that the unwritability of the disk is the reason
+	 * it's being detached!
+	 */
+	error = vdev_label_init(vd, 0, VDEV_LABEL_REMOVE);
+
+	/*
+	 * Remove vd from its parent and compact the parent's children.
+	 */
+	vdev_remove_child(pvd, vd);
+	vdev_compact_children(pvd);
+
+	/*
+	 * Remember one of the remaining children so we can get tvd below.
+	 */
+	cvd = pvd->vdev_child[pvd->vdev_children - 1];
+
+	/*
+	 * If we need to remove the remaining child from the list of hot spares,
+	 * do it now, marking the vdev as no longer a spare in the process.
+	 * We must do this before vdev_remove_parent(), because that can
+	 * change the GUID if it creates a new toplevel GUID.  For a similar
+	 * reason, we must remove the spare now, in the same txg as the detach;
+	 * otherwise someone could attach a new sibling, change the GUID, and
+	 * the subsequent attempt to spa_vdev_remove(unspare_guid) would fail.
+	 */
+	if (unspare) {
+		ASSERT(cvd->vdev_isspare);
+		spa_spare_remove(cvd);
+		unspare_guid = cvd->vdev_guid;
+		(void) spa_vdev_remove(spa, unspare_guid, B_TRUE);
+		cvd->vdev_unspare = B_TRUE;
+	}
+
+	/*
+	 * If the parent mirror/replacing vdev only has one child,
+	 * the parent is no longer needed.  Remove it from the tree.
+	 */
+	if (pvd->vdev_children == 1) {
+		if (pvd->vdev_ops == &vdev_spare_ops)
+			cvd->vdev_unspare = B_FALSE;
+		vdev_remove_parent(cvd);
+	}
+
+
+	/*
+	 * We don't set tvd until now because the parent we just removed
+	 * may have been the previous top-level vdev.
+	 */
+	tvd = cvd->vdev_top;
+	ASSERT(tvd->vdev_parent == rvd);
+
+	/*
+	 * Reevaluate the parent vdev state.
+	 */
+	vdev_propagate_state(cvd);
+
+	/*
+	 * If the 'autoexpand' property is set on the pool then automatically
+	 * try to expand the size of the pool. For example if the device we
+	 * just detached was smaller than the others, it may be possible to
+	 * add metaslabs (i.e. grow the pool). We need to reopen the vdev
+	 * first so that we can obtain the updated sizes of the leaf vdevs.
+	 */
+	if (spa->spa_autoexpand) {
+		vdev_reopen(tvd);
+		vdev_expand(tvd, txg);
+	}
+
+	vdev_config_dirty(tvd);
+
+	/*
+	 * Mark vd's DTL as dirty in this txg.  vdev_dtl_sync() will see that
+	 * vd->vdev_detached is set and free vd's DTL object in syncing context.
+	 * But first make sure we're not on any *other* txg's DTL list, to
+	 * prevent vd from being accessed after it's freed.
+	 */
+	vdpath = spa_strdup(vd->vdev_path);
+	for (t = 0; t < TXG_SIZE; t++)
+		(void) txg_list_remove_this(&tvd->vdev_dtl_list, vd, t);
+	vd->vdev_detached = B_TRUE;
+	vdev_dirty(tvd, VDD_DTL, vd, txg);
+
+	spa_event_notify(spa, vd, FM_EREPORT_ZFS_DEVICE_REMOVE);
+
+	/* hang on to the spa before we release the lock */
+	spa_open_ref(spa, FTAG);
+
+	error = spa_vdev_exit(spa, vd, txg, 0);
+
+	spa_history_log_internal(spa, "detach", NULL,
+	    "vdev=%s", vdpath);
+	spa_strfree(vdpath);
+
+	/*
+	 * If this was the removal of the original device in a hot spare vdev,
+	 * then we want to go through and remove the device from the hot spare
+	 * list of every other pool.
+	 */
+	if (unspare) {
+		spa_t *altspa = NULL;
+
+		mutex_enter(&spa_namespace_lock);
+		while ((altspa = spa_next(altspa)) != NULL) {
+			if (altspa->spa_state != POOL_STATE_ACTIVE ||
+			    altspa == spa)
+				continue;
+
+			spa_open_ref(altspa, FTAG);
+			mutex_exit(&spa_namespace_lock);
+			(void) spa_vdev_remove(altspa, unspare_guid, B_TRUE);
+			mutex_enter(&spa_namespace_lock);
+			spa_close(altspa, FTAG);
+		}
+		mutex_exit(&spa_namespace_lock);
+
+		/* search the rest of the vdevs for spares to remove */
+		spa_vdev_resilver_done(spa);
+	}
+
+	/* all done with the spa; OK to release */
+	mutex_enter(&spa_namespace_lock);
+	spa_close(spa, FTAG);
+	mutex_exit(&spa_namespace_lock);
+
+	return (error);
+}
+
+/*
+ * Split a set of devices from their mirrors, and create a new pool from them.
+ */
+int
+spa_vdev_split_mirror(spa_t *spa, char *newname, nvlist_t *config,
+    nvlist_t *props, boolean_t exp)
+{
+	int error = 0;
+	uint64_t txg, *glist;
+	spa_t *newspa;
+	uint_t c, children, lastlog;
+	nvlist_t **child, *nvl, *tmp;
+	dmu_tx_t *tx;
+	char *altroot = NULL;
+	vdev_t *rvd, **vml = NULL;			/* vdev modify list */
+	boolean_t activate_slog;
+
+	ASSERT(spa_writeable(spa));
+
+	txg = spa_vdev_enter(spa);
+
+	/* clear the log and flush everything up to now */
+	activate_slog = spa_passivate_log(spa);
+	(void) spa_vdev_config_exit(spa, NULL, txg, 0, FTAG);
+	error = spa_offline_log(spa);
+	txg = spa_vdev_config_enter(spa);
+
+	if (activate_slog)
+		spa_activate_log(spa);
+
+	if (error != 0)
+		return (spa_vdev_exit(spa, NULL, txg, error));
+
+	/* check new spa name before going any further */
+	if (spa_lookup(newname) != NULL)
+		return (spa_vdev_exit(spa, NULL, txg, EEXIST));
+
+	/*
+	 * scan through all the children to ensure they're all mirrors
+	 */
+	if (nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE, &nvl) != 0 ||
+	    nvlist_lookup_nvlist_array(nvl, ZPOOL_CONFIG_CHILDREN, &child,
+	    &children) != 0)
+		return (spa_vdev_exit(spa, NULL, txg, EINVAL));
+
+	/* first, check to ensure we've got the right child count */
+	rvd = spa->spa_root_vdev;
+	lastlog = 0;
+	for (c = 0; c < rvd->vdev_children; c++) {
+		vdev_t *vd = rvd->vdev_child[c];
+
+		/* don't count the holes & logs as children */
+		if (vd->vdev_islog || vd->vdev_ishole) {
+			if (lastlog == 0)
+				lastlog = c;
+			continue;
+		}
+
+		lastlog = 0;
+	}
+	if (children != (lastlog != 0 ? lastlog : rvd->vdev_children))
+		return (spa_vdev_exit(spa, NULL, txg, EINVAL));
+
+	/* next, ensure no spare or cache devices are part of the split */
+	if (nvlist_lookup_nvlist(nvl, ZPOOL_CONFIG_SPARES, &tmp) == 0 ||
+	    nvlist_lookup_nvlist(nvl, ZPOOL_CONFIG_L2CACHE, &tmp) == 0)
+		return (spa_vdev_exit(spa, NULL, txg, EINVAL));
+
+	vml = kmem_zalloc(children * sizeof (vdev_t *), KM_SLEEP);
+	glist = kmem_zalloc(children * sizeof (uint64_t), KM_SLEEP);
+
+	/* then, loop over each vdev and validate it */
+	for (c = 0; c < children; c++) {
+		uint64_t is_hole = 0;
+
+		(void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_HOLE,
+		    &is_hole);
+
+		if (is_hole != 0) {
+			if (spa->spa_root_vdev->vdev_child[c]->vdev_ishole ||
+			    spa->spa_root_vdev->vdev_child[c]->vdev_islog) {
+				continue;
+			} else {
+				error = SET_ERROR(EINVAL);
+				break;
+			}
+		}
+
+		/* which disk is going to be split? */
+		if (nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_GUID,
+		    &glist[c]) != 0) {
+			error = SET_ERROR(EINVAL);
+			break;
+		}
+
+		/* look it up in the spa */
+		vml[c] = spa_lookup_by_guid(spa, glist[c], B_FALSE);
+		if (vml[c] == NULL) {
+			error = SET_ERROR(ENODEV);
+			break;
+		}
+
+		/* make sure there's nothing stopping the split */
+		if (vml[c]->vdev_parent->vdev_ops != &vdev_mirror_ops ||
+		    vml[c]->vdev_islog ||
+		    vml[c]->vdev_ishole ||
+		    vml[c]->vdev_isspare ||
+		    vml[c]->vdev_isl2cache ||
+		    !vdev_writeable(vml[c]) ||
+		    vml[c]->vdev_children != 0 ||
+		    vml[c]->vdev_state != VDEV_STATE_HEALTHY ||
+		    c != spa->spa_root_vdev->vdev_child[c]->vdev_id) {
+			error = SET_ERROR(EINVAL);
+			break;
+		}
+
+		if (vdev_dtl_required(vml[c])) {
+			error = SET_ERROR(EBUSY);
+			break;
+		}
+
+		/* we need certain info from the top level */
+		VERIFY(nvlist_add_uint64(child[c], ZPOOL_CONFIG_METASLAB_ARRAY,
+		    vml[c]->vdev_top->vdev_ms_array) == 0);
+		VERIFY(nvlist_add_uint64(child[c], ZPOOL_CONFIG_METASLAB_SHIFT,
+		    vml[c]->vdev_top->vdev_ms_shift) == 0);
+		VERIFY(nvlist_add_uint64(child[c], ZPOOL_CONFIG_ASIZE,
+		    vml[c]->vdev_top->vdev_asize) == 0);
+		VERIFY(nvlist_add_uint64(child[c], ZPOOL_CONFIG_ASHIFT,
+		    vml[c]->vdev_top->vdev_ashift) == 0);
+	}
+
+	if (error != 0) {
+		kmem_free(vml, children * sizeof (vdev_t *));
+		kmem_free(glist, children * sizeof (uint64_t));
+		return (spa_vdev_exit(spa, NULL, txg, error));
+	}
+
+	/* stop writers from using the disks */
+	for (c = 0; c < children; c++) {
+		if (vml[c] != NULL)
+			vml[c]->vdev_offline = B_TRUE;
+	}
+	vdev_reopen(spa->spa_root_vdev);
+
+	/*
+	 * Temporarily record the splitting vdevs in the spa config.  This
+	 * will disappear once the config is regenerated.
+	 */
+	VERIFY(nvlist_alloc(&nvl, NV_UNIQUE_NAME, KM_SLEEP) == 0);
+	VERIFY(nvlist_add_uint64_array(nvl, ZPOOL_CONFIG_SPLIT_LIST,
+	    glist, children) == 0);
+	kmem_free(glist, children * sizeof (uint64_t));
+
+	mutex_enter(&spa->spa_props_lock);
+	VERIFY(nvlist_add_nvlist(spa->spa_config, ZPOOL_CONFIG_SPLIT,
+	    nvl) == 0);
+	mutex_exit(&spa->spa_props_lock);
+	spa->spa_config_splitting = nvl;
+	vdev_config_dirty(spa->spa_root_vdev);
+
+	/* configure and create the new pool */
+	VERIFY(nvlist_add_string(config, ZPOOL_CONFIG_POOL_NAME, newname) == 0);
+	VERIFY(nvlist_add_uint64(config, ZPOOL_CONFIG_POOL_STATE,
+	    exp ? POOL_STATE_EXPORTED : POOL_STATE_ACTIVE) == 0);
+	VERIFY(nvlist_add_uint64(config, ZPOOL_CONFIG_VERSION,
+	    spa_version(spa)) == 0);
+	VERIFY(nvlist_add_uint64(config, ZPOOL_CONFIG_POOL_TXG,
+	    spa->spa_config_txg) == 0);
+	VERIFY(nvlist_add_uint64(config, ZPOOL_CONFIG_POOL_GUID,
+	    spa_generate_guid(NULL)) == 0);
+	(void) nvlist_lookup_string(props,
+	    zpool_prop_to_name(ZPOOL_PROP_ALTROOT), &altroot);
+
+	/* add the new pool to the namespace */
+	newspa = spa_add(newname, config, altroot);
+	newspa->spa_config_txg = spa->spa_config_txg;
+	spa_set_log_state(newspa, SPA_LOG_CLEAR);
+
+	/* release the spa config lock, retaining the namespace lock */
+	spa_vdev_config_exit(spa, NULL, txg, 0, FTAG);
+
+	if (zio_injection_enabled)
+		zio_handle_panic_injection(spa, FTAG, 1);
+
+	spa_activate(newspa, spa_mode_global);
+	spa_async_suspend(newspa);
+
+	/* create the new pool from the disks of the original pool */
+	error = spa_load(newspa, SPA_LOAD_IMPORT, SPA_IMPORT_ASSEMBLE, B_TRUE);
+	if (error)
+		goto out;
+
+	/* if that worked, generate a real config for the new pool */
+	if (newspa->spa_root_vdev != NULL) {
+		VERIFY(nvlist_alloc(&newspa->spa_config_splitting,
+		    NV_UNIQUE_NAME, KM_SLEEP) == 0);
+		VERIFY(nvlist_add_uint64(newspa->spa_config_splitting,
+		    ZPOOL_CONFIG_SPLIT_GUID, spa_guid(spa)) == 0);
+		spa_config_set(newspa, spa_config_generate(newspa, NULL, -1ULL,
+		    B_TRUE));
+	}
+
+	/* set the props */
+	if (props != NULL) {
+		spa_configfile_set(newspa, props, B_FALSE);
+		error = spa_prop_set(newspa, props);
+		if (error)
+			goto out;
+	}
+
+	/* flush everything */
+	txg = spa_vdev_config_enter(newspa);
+	vdev_config_dirty(newspa->spa_root_vdev);
+	(void) spa_vdev_config_exit(newspa, NULL, txg, 0, FTAG);
+
+	if (zio_injection_enabled)
+		zio_handle_panic_injection(spa, FTAG, 2);
+
+	spa_async_resume(newspa);
+
+	/* finally, update the original pool's config */
+	txg = spa_vdev_config_enter(spa);
+	tx = dmu_tx_create_dd(spa_get_dsl(spa)->dp_mos_dir);
+	error = dmu_tx_assign(tx, TXG_WAIT);
+	if (error != 0)
+		dmu_tx_abort(tx);
+	for (c = 0; c < children; c++) {
+		if (vml[c] != NULL) {
+			vdev_split(vml[c]);
+			if (error == 0)
+				spa_history_log_internal(spa, "detach", tx,
+				    "vdev=%s", vml[c]->vdev_path);
+			vdev_free(vml[c]);
+		}
+	}
+	vdev_config_dirty(spa->spa_root_vdev);
+	spa->spa_config_splitting = NULL;
+	nvlist_free(nvl);
+	if (error == 0)
+		dmu_tx_commit(tx);
+	(void) spa_vdev_exit(spa, NULL, txg, 0);
+
+	if (zio_injection_enabled)
+		zio_handle_panic_injection(spa, FTAG, 3);
+
+	/* split is complete; log a history record */
+	spa_history_log_internal(newspa, "split", NULL,
+	    "from pool %s", spa_name(spa));
+
+	kmem_free(vml, children * sizeof (vdev_t *));
+
+	/* if we're not going to mount the filesystems in userland, export */
+	if (exp)
+		error = spa_export_common(newname, POOL_STATE_EXPORTED, NULL,
+		    B_FALSE, B_FALSE);
+
+	return (error);
+
+out:
+	spa_unload(newspa);
+	spa_deactivate(newspa);
+	spa_remove(newspa);
+
+	txg = spa_vdev_config_enter(spa);
+
+	/* re-online all offlined disks */
+	for (c = 0; c < children; c++) {
+		if (vml[c] != NULL)
+			vml[c]->vdev_offline = B_FALSE;
+	}
+	vdev_reopen(spa->spa_root_vdev);
+
+	nvlist_free(spa->spa_config_splitting);
+	spa->spa_config_splitting = NULL;
+	(void) spa_vdev_exit(spa, NULL, txg, error);
+
+	kmem_free(vml, children * sizeof (vdev_t *));
+	return (error);
+}
+
+static nvlist_t *
+spa_nvlist_lookup_by_guid(nvlist_t **nvpp, int count, uint64_t target_guid)
+{
+	int i;
+
+	for (i = 0; i < count; i++) {
+		uint64_t guid;
+
+		VERIFY(nvlist_lookup_uint64(nvpp[i], ZPOOL_CONFIG_GUID,
+		    &guid) == 0);
+
+		if (guid == target_guid)
+			return (nvpp[i]);
+	}
+
+	return (NULL);
+}
+
+static void
+spa_vdev_remove_aux(nvlist_t *config, char *name, nvlist_t **dev, int count,
+	nvlist_t *dev_to_remove)
+{
+	nvlist_t **newdev = NULL;
+	int i, j;
+
+	if (count > 1)
+		newdev = kmem_alloc((count - 1) * sizeof (void *), KM_SLEEP);
+
+	for (i = 0, j = 0; i < count; i++) {
+		if (dev[i] == dev_to_remove)
+			continue;
+		VERIFY(nvlist_dup(dev[i], &newdev[j++], KM_SLEEP) == 0);
+	}
+
+	VERIFY(nvlist_remove(config, name, DATA_TYPE_NVLIST_ARRAY) == 0);
+	VERIFY(nvlist_add_nvlist_array(config, name, newdev, count - 1) == 0);
+
+	for (i = 0; i < count - 1; i++)
+		nvlist_free(newdev[i]);
+
+	if (count > 1)
+		kmem_free(newdev, (count - 1) * sizeof (void *));
+}
+
+/*
+ * Evacuate the device.
+ */
+static int
+spa_vdev_remove_evacuate(spa_t *spa, vdev_t *vd)
+{
+	uint64_t txg;
+	int error = 0;
+
+	ASSERT(MUTEX_HELD(&spa_namespace_lock));
+	ASSERT(spa_config_held(spa, SCL_ALL, RW_WRITER) == 0);
+	ASSERT(vd == vd->vdev_top);
+
+	/*
+	 * Evacuate the device.  We don't hold the config lock as writer
+	 * since we need to do I/O but we do keep the
+	 * spa_namespace_lock held.  Once this completes the device
+	 * should no longer have any blocks allocated on it.
+	 */
+	if (vd->vdev_islog) {
+		if (vd->vdev_stat.vs_alloc != 0)
+			error = spa_offline_log(spa);
+	} else {
+		error = SET_ERROR(ENOTSUP);
+	}
+
+	if (error)
+		return (error);
+
+	/*
+	 * The evacuation succeeded.  Remove any remaining MOS metadata
+	 * associated with this vdev, and wait for these changes to sync.
+	 */
+	ASSERT0(vd->vdev_stat.vs_alloc);
+	txg = spa_vdev_config_enter(spa);
+	vd->vdev_removing = B_TRUE;
+	vdev_dirty_leaves(vd, VDD_DTL, txg);
+	vdev_config_dirty(vd);
+	spa_vdev_config_exit(spa, NULL, txg, 0, FTAG);
+
+	return (0);
+}
+
+/*
+ * Complete the removal by cleaning up the namespace.
+ */
+static void
+spa_vdev_remove_from_namespace(spa_t *spa, vdev_t *vd)
+{
+	vdev_t *rvd = spa->spa_root_vdev;
+	uint64_t id = vd->vdev_id;
+	boolean_t last_vdev = (id == (rvd->vdev_children - 1));
+
+	ASSERT(MUTEX_HELD(&spa_namespace_lock));
+	ASSERT(spa_config_held(spa, SCL_ALL, RW_WRITER) == SCL_ALL);
+	ASSERT(vd == vd->vdev_top);
+
+	/*
+	 * Only remove any devices which are empty.
+	 */
+	if (vd->vdev_stat.vs_alloc != 0)
+		return;
+
+	(void) vdev_label_init(vd, 0, VDEV_LABEL_REMOVE);
+
+	if (list_link_active(&vd->vdev_state_dirty_node))
+		vdev_state_clean(vd);
+	if (list_link_active(&vd->vdev_config_dirty_node))
+		vdev_config_clean(vd);
+
+	vdev_free(vd);
+
+	if (last_vdev) {
+		vdev_compact_children(rvd);
+	} else {
+		vd = vdev_alloc_common(spa, id, 0, &vdev_hole_ops);
+		vdev_add_child(rvd, vd);
+	}
+	vdev_config_dirty(rvd);
+
+	/*
+	 * Reassess the health of our root vdev.
+	 */
+	vdev_reopen(rvd);
+}
+
+/*
+ * Remove a device from the pool -
+ *
+ * Removing a device from the vdev namespace requires several steps
+ * and can take a significant amount of time.  As a result we use
+ * the spa_vdev_config_[enter/exit] functions which allow us to
+ * grab and release the spa_config_lock while still holding the namespace
+ * lock.  During each step the configuration is synced out.
+ *
+ * Currently, this supports removing only hot spares, slogs, and level 2 ARC
+ * devices.
+ */
+int
+spa_vdev_remove(spa_t *spa, uint64_t guid, boolean_t unspare)
+{
+	vdev_t *vd;
+	metaslab_group_t *mg;
+	nvlist_t **spares, **l2cache, *nv;
+	uint64_t txg = 0;
+	uint_t nspares, nl2cache;
+	int error = 0;
+	boolean_t locked = MUTEX_HELD(&spa_namespace_lock);
+
+	ASSERT(spa_writeable(spa));
+
+	if (!locked)
+		txg = spa_vdev_enter(spa);
+
+	vd = spa_lookup_by_guid(spa, guid, B_FALSE);
+
+	if (spa->spa_spares.sav_vdevs != NULL &&
+	    nvlist_lookup_nvlist_array(spa->spa_spares.sav_config,
+	    ZPOOL_CONFIG_SPARES, &spares, &nspares) == 0 &&
+	    (nv = spa_nvlist_lookup_by_guid(spares, nspares, guid)) != NULL) {
+		/*
+		 * Only remove the hot spare if it's not currently in use
+		 * in this pool.
+		 */
+		if (vd == NULL || unspare) {
+			spa_vdev_remove_aux(spa->spa_spares.sav_config,
+			    ZPOOL_CONFIG_SPARES, spares, nspares, nv);
+			spa_load_spares(spa);
+			spa->spa_spares.sav_sync = B_TRUE;
+		} else {
+			error = SET_ERROR(EBUSY);
+		}
+	} else if (spa->spa_l2cache.sav_vdevs != NULL &&
+	    nvlist_lookup_nvlist_array(spa->spa_l2cache.sav_config,
+	    ZPOOL_CONFIG_L2CACHE, &l2cache, &nl2cache) == 0 &&
+	    (nv = spa_nvlist_lookup_by_guid(l2cache, nl2cache, guid)) != NULL) {
+		/*
+		 * Cache devices can always be removed.
+		 */
+		spa_vdev_remove_aux(spa->spa_l2cache.sav_config,
+		    ZPOOL_CONFIG_L2CACHE, l2cache, nl2cache, nv);
+		spa_load_l2cache(spa);
+		spa->spa_l2cache.sav_sync = B_TRUE;
+	} else if (vd != NULL && vd->vdev_islog) {
+		ASSERT(!locked);
+		ASSERT(vd == vd->vdev_top);
+
+		mg = vd->vdev_mg;
+
+		/*
+		 * Stop allocating from this vdev.
+		 */
+		metaslab_group_passivate(mg);
+
+		/*
+		 * Wait for the youngest allocations and frees to sync,
+		 * and then wait for the deferral of those frees to finish.
+		 */
+		spa_vdev_config_exit(spa, NULL,
+		    txg + TXG_CONCURRENT_STATES + TXG_DEFER_SIZE, 0, FTAG);
+
+		/*
+		 * Attempt to evacuate the vdev.
+		 */
+		error = spa_vdev_remove_evacuate(spa, vd);
+
+		txg = spa_vdev_config_enter(spa);
+
+		/*
+		 * If we couldn't evacuate the vdev, unwind.
+		 */
+		if (error) {
+			metaslab_group_activate(mg);
+			return (spa_vdev_exit(spa, NULL, txg, error));
+		}
+
+		/*
+		 * Clean up the vdev namespace.
+		 */
+		spa_vdev_remove_from_namespace(spa, vd);
+
+	} else if (vd != NULL) {
+		/*
+		 * Normal vdevs cannot be removed (yet).
+		 */
+		error = SET_ERROR(ENOTSUP);
+	} else {
+		/*
+		 * There is no vdev of any kind with the specified guid.
+		 */
+		error = SET_ERROR(ENOENT);
+	}
+
+	if (!locked)
+		return (spa_vdev_exit(spa, NULL, txg, error));
+
+	return (error);
+}
+
+/*
+ * Find any device that's done replacing, or a vdev marked 'unspare' that's
+ * currently spared, so we can detach it.
+ */
+static vdev_t *
+spa_vdev_resilver_done_hunt(vdev_t *vd)
+{
+	vdev_t *newvd, *oldvd;
+	int c;
+
+	for (c = 0; c < vd->vdev_children; c++) {
+		oldvd = spa_vdev_resilver_done_hunt(vd->vdev_child[c]);
+		if (oldvd != NULL)
+			return (oldvd);
+	}
+
+	/*
+	 * Check for a completed replacement.  We always consider the first
+	 * vdev in the list to be the oldest vdev, and the last one to be
+	 * the newest (see spa_vdev_attach() for how that works).  In
+	 * the case where the newest vdev is faulted, we will not automatically
+	 * remove it after a resilver completes.  This is OK as it will require
+	 * user intervention to determine which disk the admin wishes to keep.
+	 */
+	if (vd->vdev_ops == &vdev_replacing_ops) {
+		ASSERT(vd->vdev_children > 1);
+
+		newvd = vd->vdev_child[vd->vdev_children - 1];
+		oldvd = vd->vdev_child[0];
+
+		if (vdev_dtl_empty(newvd, DTL_MISSING) &&
+		    vdev_dtl_empty(newvd, DTL_OUTAGE) &&
+		    !vdev_dtl_required(oldvd))
+			return (oldvd);
+	}
+
+	/*
+	 * Check for a completed resilver with the 'unspare' flag set.
+	 */
+	if (vd->vdev_ops == &vdev_spare_ops) {
+		vdev_t *first = vd->vdev_child[0];
+		vdev_t *last = vd->vdev_child[vd->vdev_children - 1];
+
+		if (last->vdev_unspare) {
+			oldvd = first;
+			newvd = last;
+		} else if (first->vdev_unspare) {
+			oldvd = last;
+			newvd = first;
+		} else {
+			oldvd = NULL;
+		}
+
+		if (oldvd != NULL &&
+		    vdev_dtl_empty(newvd, DTL_MISSING) &&
+		    vdev_dtl_empty(newvd, DTL_OUTAGE) &&
+		    !vdev_dtl_required(oldvd))
+			return (oldvd);
+
+		/*
+		 * If there are more than two spares attached to a disk,
+		 * and those spares are not required, then we want to
+		 * attempt to free them up now so that they can be used
+		 * by other pools.  Once we're back down to a single
+		 * disk+spare, we stop removing them.
+		 */
+		if (vd->vdev_children > 2) {
+			newvd = vd->vdev_child[1];
+
+			if (newvd->vdev_isspare && last->vdev_isspare &&
+			    vdev_dtl_empty(last, DTL_MISSING) &&
+			    vdev_dtl_empty(last, DTL_OUTAGE) &&
+			    !vdev_dtl_required(newvd))
+				return (newvd);
+		}
+	}
+
+	return (NULL);
+}
+
+static void
+spa_vdev_resilver_done(spa_t *spa)
+{
+	vdev_t *vd, *pvd, *ppvd;
+	uint64_t guid, sguid, pguid, ppguid;
+
+	spa_config_enter(spa, SCL_ALL, FTAG, RW_WRITER);
+
+	while ((vd = spa_vdev_resilver_done_hunt(spa->spa_root_vdev)) != NULL) {
+		pvd = vd->vdev_parent;
+		ppvd = pvd->vdev_parent;
+		guid = vd->vdev_guid;
+		pguid = pvd->vdev_guid;
+		ppguid = ppvd->vdev_guid;
+		sguid = 0;
+		/*
+		 * If we have just finished replacing a hot spared device, then
+		 * we need to detach the parent's first child (the original hot
+		 * spare) as well.
+		 */
+		if (ppvd->vdev_ops == &vdev_spare_ops && pvd->vdev_id == 0 &&
+		    ppvd->vdev_children == 2) {
+			ASSERT(pvd->vdev_ops == &vdev_replacing_ops);
+			sguid = ppvd->vdev_child[1]->vdev_guid;
+		}
+		ASSERT(vd->vdev_resilver_txg == 0 || !vdev_dtl_required(vd));
+
+		spa_config_exit(spa, SCL_ALL, FTAG);
+		if (spa_vdev_detach(spa, guid, pguid, B_TRUE) != 0)
+			return;
+		if (sguid && spa_vdev_detach(spa, sguid, ppguid, B_TRUE) != 0)
+			return;
+		spa_config_enter(spa, SCL_ALL, FTAG, RW_WRITER);
+	}
+
+	spa_config_exit(spa, SCL_ALL, FTAG);
+}
+
+/*
+ * Update the stored path or FRU for this vdev.
+ */
+int
+spa_vdev_set_common(spa_t *spa, uint64_t guid, const char *value,
+    boolean_t ispath)
+{
+	vdev_t *vd;
+	boolean_t sync = B_FALSE;
+
+	ASSERT(spa_writeable(spa));
+
+	spa_vdev_state_enter(spa, SCL_ALL);
+
+	if ((vd = spa_lookup_by_guid(spa, guid, B_TRUE)) == NULL)
+		return (spa_vdev_state_exit(spa, NULL, ENOENT));
+
+	if (!vd->vdev_ops->vdev_op_leaf)
+		return (spa_vdev_state_exit(spa, NULL, ENOTSUP));
+
+	if (ispath) {
+		if (strcmp(value, vd->vdev_path) != 0) {
+			spa_strfree(vd->vdev_path);
+			vd->vdev_path = spa_strdup(value);
+			sync = B_TRUE;
+		}
+	} else {
+		if (vd->vdev_fru == NULL) {
+			vd->vdev_fru = spa_strdup(value);
+			sync = B_TRUE;
+		} else if (strcmp(value, vd->vdev_fru) != 0) {
+			spa_strfree(vd->vdev_fru);
+			vd->vdev_fru = spa_strdup(value);
+			sync = B_TRUE;
+		}
+	}
+
+	return (spa_vdev_state_exit(spa, sync ? vd : NULL, 0));
+}
+
+int
+spa_vdev_setpath(spa_t *spa, uint64_t guid, const char *newpath)
+{
+	return (spa_vdev_set_common(spa, guid, newpath, B_TRUE));
+}
+
+int
+spa_vdev_setfru(spa_t *spa, uint64_t guid, const char *newfru)
+{
+	return (spa_vdev_set_common(spa, guid, newfru, B_FALSE));
+}
+
+/*
+ * ==========================================================================
+ * SPA Scanning
+ * ==========================================================================
+ */
+
+int
+spa_scan_stop(spa_t *spa)
+{
+	ASSERT(spa_config_held(spa, SCL_ALL, RW_WRITER) == 0);
+	if (dsl_scan_resilvering(spa->spa_dsl_pool))
+		return (SET_ERROR(EBUSY));
+	return (dsl_scan_cancel(spa->spa_dsl_pool));
+}
+
+int
+spa_scan(spa_t *spa, pool_scan_func_t func)
+{
+	ASSERT(spa_config_held(spa, SCL_ALL, RW_WRITER) == 0);
+
+	if (func >= POOL_SCAN_FUNCS || func == POOL_SCAN_NONE)
+		return (SET_ERROR(ENOTSUP));
+
+	/*
+	 * If a resilver was requested, but there is no DTL on a
+	 * writeable leaf device, we have nothing to do.
+	 */
+	if (func == POOL_SCAN_RESILVER &&
+	    !vdev_resilver_needed(spa->spa_root_vdev, NULL, NULL)) {
+		spa_async_request(spa, SPA_ASYNC_RESILVER_DONE);
+		return (0);
+	}
+
+	return (dsl_scan(spa->spa_dsl_pool, func));
+}
+
+/*
+ * ==========================================================================
+ * SPA async task processing
+ * ==========================================================================
+ */
+
+static void
+spa_async_remove(spa_t *spa, vdev_t *vd)
+{
+	int c;
+
+	if (vd->vdev_remove_wanted) {
+		vd->vdev_remove_wanted = B_FALSE;
+		vd->vdev_delayed_close = B_FALSE;
+		vdev_set_state(vd, B_FALSE, VDEV_STATE_REMOVED, VDEV_AUX_NONE);
+
+		/*
+		 * We want to clear the stats, but we don't want to do a full
+		 * vdev_clear() as that will cause us to throw away
+		 * degraded/faulted state as well as attempt to reopen the
+		 * device, all of which is a waste.
+		 */
+		vd->vdev_stat.vs_read_errors = 0;
+		vd->vdev_stat.vs_write_errors = 0;
+		vd->vdev_stat.vs_checksum_errors = 0;
+
+		vdev_state_dirty(vd->vdev_top);
+	}
+
+	for (c = 0; c < vd->vdev_children; c++)
+		spa_async_remove(spa, vd->vdev_child[c]);
+}
+
+static void
+spa_async_probe(spa_t *spa, vdev_t *vd)
+{
+	int c;
+
+	if (vd->vdev_probe_wanted) {
+		vd->vdev_probe_wanted = B_FALSE;
+		vdev_reopen(vd);	/* vdev_open() does the actual probe */
+	}
+
+	for (c = 0; c < vd->vdev_children; c++)
+		spa_async_probe(spa, vd->vdev_child[c]);
+}
+
+static void
+spa_async_autoexpand(spa_t *spa, vdev_t *vd)
+{
+	int c;
+
+	if (!spa->spa_autoexpand)
+		return;
+
+	for (c = 0; c < vd->vdev_children; c++) {
+		vdev_t *cvd = vd->vdev_child[c];
+		spa_async_autoexpand(spa, cvd);
+	}
+
+	if (!vd->vdev_ops->vdev_op_leaf || vd->vdev_physpath == NULL)
+		return;
+
+	spa_event_notify(vd->vdev_spa, vd, FM_EREPORT_ZFS_DEVICE_AUTOEXPAND);
+}
+
+static void
+spa_async_thread(spa_t *spa)
+{
+	int tasks, i;
+
+	ASSERT(spa->spa_sync_on);
+
+	mutex_enter(&spa->spa_async_lock);
+	tasks = spa->spa_async_tasks;
+	spa->spa_async_tasks = 0;
+	mutex_exit(&spa->spa_async_lock);
+
+	/*
+	 * See if the config needs to be updated.
+	 */
+	if (tasks & SPA_ASYNC_CONFIG_UPDATE) {
+		uint64_t old_space, new_space;
+
+		mutex_enter(&spa_namespace_lock);
+		old_space = metaslab_class_get_space(spa_normal_class(spa));
+		spa_config_update(spa, SPA_CONFIG_UPDATE_POOL);
+		new_space = metaslab_class_get_space(spa_normal_class(spa));
+		mutex_exit(&spa_namespace_lock);
+
+		/*
+		 * If the pool grew as a result of the config update,
+		 * then log an internal history event.
+		 */
+		if (new_space != old_space) {
+			spa_history_log_internal(spa, "vdev online", NULL,
+			    "pool '%s' size: %llu(+%llu)",
+			    spa_name(spa), new_space, new_space - old_space);
+		}
+	}
+
+	/*
+	 * See if any devices need to be marked REMOVED.
+	 */
+	if (tasks & SPA_ASYNC_REMOVE) {
+		spa_vdev_state_enter(spa, SCL_NONE);
+		spa_async_remove(spa, spa->spa_root_vdev);
+		for (i = 0; i < spa->spa_l2cache.sav_count; i++)
+			spa_async_remove(spa, spa->spa_l2cache.sav_vdevs[i]);
+		for (i = 0; i < spa->spa_spares.sav_count; i++)
+			spa_async_remove(spa, spa->spa_spares.sav_vdevs[i]);
+		(void) spa_vdev_state_exit(spa, NULL, 0);
+	}
+
+	if ((tasks & SPA_ASYNC_AUTOEXPAND) && !spa_suspended(spa)) {
+		spa_config_enter(spa, SCL_CONFIG, FTAG, RW_READER);
+		spa_async_autoexpand(spa, spa->spa_root_vdev);
+		spa_config_exit(spa, SCL_CONFIG, FTAG);
+	}
+
+	/*
+	 * See if any devices need to be probed.
+	 */
+	if (tasks & SPA_ASYNC_PROBE) {
+		spa_vdev_state_enter(spa, SCL_NONE);
+		spa_async_probe(spa, spa->spa_root_vdev);
+		(void) spa_vdev_state_exit(spa, NULL, 0);
+	}
+
+	/*
+	 * If any devices are done replacing, detach them.
+	 */
+	if (tasks & SPA_ASYNC_RESILVER_DONE)
+		spa_vdev_resilver_done(spa);
+
+	/*
+	 * Kick off a resilver.
+	 */
+	if (tasks & SPA_ASYNC_RESILVER)
+		dsl_resilver_restart(spa->spa_dsl_pool, 0);
+
+	/*
+	 * Let the world know that we're done.
+	 */
+	mutex_enter(&spa->spa_async_lock);
+	spa->spa_async_thread = NULL;
+	cv_broadcast(&spa->spa_async_cv);
+	mutex_exit(&spa->spa_async_lock);
+	thread_exit();
+}
+
+void
+spa_async_suspend(spa_t *spa)
+{
+	mutex_enter(&spa->spa_async_lock);
+	spa->spa_async_suspended++;
+	while (spa->spa_async_thread != NULL)
+		cv_wait(&spa->spa_async_cv, &spa->spa_async_lock);
+	mutex_exit(&spa->spa_async_lock);
+}
+
+void
+spa_async_resume(spa_t *spa)
+{
+	mutex_enter(&spa->spa_async_lock);
+	ASSERT(spa->spa_async_suspended != 0);
+	spa->spa_async_suspended--;
+	mutex_exit(&spa->spa_async_lock);
+}
+
+static void
+spa_async_dispatch(spa_t *spa)
+{
+	mutex_enter(&spa->spa_async_lock);
+	if (spa->spa_async_tasks && !spa->spa_async_suspended &&
+	    spa->spa_async_thread == NULL &&
+	    rootdir != NULL && !vn_is_readonly(rootdir))
+		spa->spa_async_thread = thread_create(NULL, 0,
+		    spa_async_thread, spa, 0, &p0, TS_RUN, maxclsyspri);
+	mutex_exit(&spa->spa_async_lock);
+}
+
+void
+spa_async_request(spa_t *spa, int task)
+{
+	zfs_dbgmsg("spa=%s async request task=%u", spa->spa_name, task);
+	mutex_enter(&spa->spa_async_lock);
+	spa->spa_async_tasks |= task;
+	mutex_exit(&spa->spa_async_lock);
+}
+
+/*
+ * ==========================================================================
+ * SPA syncing routines
+ * ==========================================================================
+ */
+
+static int
+bpobj_enqueue_cb(void *arg, const blkptr_t *bp, dmu_tx_t *tx)
+{
+	bpobj_t *bpo = arg;
+	bpobj_enqueue(bpo, bp, tx);
+	return (0);
+}
+
+static int
+spa_free_sync_cb(void *arg, const blkptr_t *bp, dmu_tx_t *tx)
+{
+	zio_t *zio = arg;
+
+	zio_nowait(zio_free_sync(zio, zio->io_spa, dmu_tx_get_txg(tx), bp,
+	    zio->io_flags));
+	return (0);
+}
+
+/*
+ * Note: this simple function is not inlined to make it easier to dtrace the
+ * amount of time spent syncing frees.
+ */
+static void
+spa_sync_frees(spa_t *spa, bplist_t *bpl, dmu_tx_t *tx)
+{
+	zio_t *zio = zio_root(spa, NULL, NULL, 0);
+	bplist_iterate(bpl, spa_free_sync_cb, zio, tx);
+	VERIFY(zio_wait(zio) == 0);
+}
+
+/*
+ * Note: this simple function is not inlined to make it easier to dtrace the
+ * amount of time spent syncing deferred frees.
+ */
+static void
+spa_sync_deferred_frees(spa_t *spa, dmu_tx_t *tx)
+{
+	zio_t *zio = zio_root(spa, NULL, NULL, 0);
+	VERIFY3U(bpobj_iterate(&spa->spa_deferred_bpobj,
+	    spa_free_sync_cb, zio, tx), ==, 0);
+	VERIFY0(zio_wait(zio));
+}
+
+static void
+spa_sync_nvlist(spa_t *spa, uint64_t obj, nvlist_t *nv, dmu_tx_t *tx)
+{
+	char *packed = NULL;
+	size_t bufsize;
+	size_t nvsize = 0;
+	dmu_buf_t *db;
+
+	VERIFY(nvlist_size(nv, &nvsize, NV_ENCODE_XDR) == 0);
+
+	/*
+	 * Write full (SPA_CONFIG_BLOCKSIZE) blocks of configuration
+	 * information.  This avoids the dmu_buf_will_dirty() path and
+	 * saves us a pre-read to get data we don't actually care about.
+	 */
+	bufsize = P2ROUNDUP((uint64_t)nvsize, SPA_CONFIG_BLOCKSIZE);
+	packed = vmem_alloc(bufsize, KM_SLEEP);
+
+	VERIFY(nvlist_pack(nv, &packed, &nvsize, NV_ENCODE_XDR,
+	    KM_SLEEP) == 0);
+	bzero(packed + nvsize, bufsize - nvsize);
+
+	dmu_write(spa->spa_meta_objset, obj, 0, bufsize, packed, tx);
+
+	vmem_free(packed, bufsize);
+
+	VERIFY(0 == dmu_bonus_hold(spa->spa_meta_objset, obj, FTAG, &db));
+	dmu_buf_will_dirty(db, tx);
+	*(uint64_t *)db->db_data = nvsize;
+	dmu_buf_rele(db, FTAG);
+}
+
+static void
+spa_sync_aux_dev(spa_t *spa, spa_aux_vdev_t *sav, dmu_tx_t *tx,
+    const char *config, const char *entry)
+{
+	nvlist_t *nvroot;
+	nvlist_t **list;
+	int i;
+
+	if (!sav->sav_sync)
+		return;
+
+	/*
+	 * Update the MOS nvlist describing the list of available devices.
+	 * spa_validate_aux() will have already made sure this nvlist is
+	 * valid and the vdevs are labeled appropriately.
+	 */
+	if (sav->sav_object == 0) {
+		sav->sav_object = dmu_object_alloc(spa->spa_meta_objset,
+		    DMU_OT_PACKED_NVLIST, 1 << 14, DMU_OT_PACKED_NVLIST_SIZE,
+		    sizeof (uint64_t), tx);
+		VERIFY(zap_update(spa->spa_meta_objset,
+		    DMU_POOL_DIRECTORY_OBJECT, entry, sizeof (uint64_t), 1,
+		    &sav->sav_object, tx) == 0);
+	}
+
+	VERIFY(nvlist_alloc(&nvroot, NV_UNIQUE_NAME, KM_SLEEP) == 0);
+	if (sav->sav_count == 0) {
+		VERIFY(nvlist_add_nvlist_array(nvroot, config, NULL, 0) == 0);
+	} else {
+		list = kmem_alloc(sav->sav_count*sizeof (void *), KM_SLEEP);
+		for (i = 0; i < sav->sav_count; i++)
+			list[i] = vdev_config_generate(spa, sav->sav_vdevs[i],
+			    B_FALSE, VDEV_CONFIG_L2CACHE);
+		VERIFY(nvlist_add_nvlist_array(nvroot, config, list,
+		    sav->sav_count) == 0);
+		for (i = 0; i < sav->sav_count; i++)
+			nvlist_free(list[i]);
+		kmem_free(list, sav->sav_count * sizeof (void *));
+	}
+
+	spa_sync_nvlist(spa, sav->sav_object, nvroot, tx);
+	nvlist_free(nvroot);
+
+	sav->sav_sync = B_FALSE;
+}
+
+static void
+spa_sync_config_object(spa_t *spa, dmu_tx_t *tx)
+{
+	nvlist_t *config;
+
+	if (list_is_empty(&spa->spa_config_dirty_list))
+		return;
+
+	spa_config_enter(spa, SCL_STATE, FTAG, RW_READER);
+
+	config = spa_config_generate(spa, spa->spa_root_vdev,
+	    dmu_tx_get_txg(tx), B_FALSE);
+
+	/*
+	 * If we're upgrading the spa version then make sure that
+	 * the config object gets updated with the correct version.
+	 */
+	if (spa->spa_ubsync.ub_version < spa->spa_uberblock.ub_version)
+		fnvlist_add_uint64(config, ZPOOL_CONFIG_VERSION,
+		    spa->spa_uberblock.ub_version);
+
+	spa_config_exit(spa, SCL_STATE, FTAG);
+
+	if (spa->spa_config_syncing)
+		nvlist_free(spa->spa_config_syncing);
+	spa->spa_config_syncing = config;
+
+	spa_sync_nvlist(spa, spa->spa_config_object, config, tx);
+}
+
+static void
+spa_sync_version(void *arg, dmu_tx_t *tx)
+{
+	uint64_t *versionp = arg;
+	uint64_t version = *versionp;
+	spa_t *spa = dmu_tx_pool(tx)->dp_spa;
+
+	/*
+	 * Setting the version is special cased when first creating the pool.
+	 */
+	ASSERT(tx->tx_txg != TXG_INITIAL);
+
+	ASSERT(SPA_VERSION_IS_SUPPORTED(version));
+	ASSERT(version >= spa_version(spa));
+
+	spa->spa_uberblock.ub_version = version;
+	vdev_config_dirty(spa->spa_root_vdev);
+	spa_history_log_internal(spa, "set", tx, "version=%lld", version);
+}
+
+/*
+ * Set zpool properties.
+ */
+static void
+spa_sync_props(void *arg, dmu_tx_t *tx)
+{
+	nvlist_t *nvp = arg;
+	spa_t *spa = dmu_tx_pool(tx)->dp_spa;
+	objset_t *mos = spa->spa_meta_objset;
+	nvpair_t *elem = NULL;
+
+	mutex_enter(&spa->spa_props_lock);
+
+	while ((elem = nvlist_next_nvpair(nvp, elem))) {
+		uint64_t intval;
+		char *strval, *fname;
+		zpool_prop_t prop;
+		const char *propname;
+		zprop_type_t proptype;
+		spa_feature_t fid;
+
+		prop = zpool_name_to_prop(nvpair_name(elem));
+		switch ((int)prop) {
+		case ZPROP_INVAL:
+			/*
+			 * We checked this earlier in spa_prop_validate().
+			 */
+			ASSERT(zpool_prop_feature(nvpair_name(elem)));
+
+			fname = strchr(nvpair_name(elem), '@') + 1;
+			VERIFY0(zfeature_lookup_name(fname, &fid));
+
+			spa_feature_enable(spa, fid, tx);
+			spa_history_log_internal(spa, "set", tx,
+			    "%s=enabled", nvpair_name(elem));
+			break;
+
+		case ZPOOL_PROP_VERSION:
+			intval = fnvpair_value_uint64(elem);
+			/*
+			 * The version is synced seperatly before other
+			 * properties and should be correct by now.
+			 */
+			ASSERT3U(spa_version(spa), >=, intval);
+			break;
+
+		case ZPOOL_PROP_ALTROOT:
+			/*
+			 * 'altroot' is a non-persistent property. It should
+			 * have been set temporarily at creation or import time.
+			 */
+			ASSERT(spa->spa_root != NULL);
+			break;
+
+		case ZPOOL_PROP_READONLY:
+		case ZPOOL_PROP_CACHEFILE:
+			/*
+			 * 'readonly' and 'cachefile' are also non-persisitent
+			 * properties.
+			 */
+			break;
+		case ZPOOL_PROP_COMMENT:
+			strval = fnvpair_value_string(elem);
+			if (spa->spa_comment != NULL)
+				spa_strfree(spa->spa_comment);
+			spa->spa_comment = spa_strdup(strval);
+			/*
+			 * We need to dirty the configuration on all the vdevs
+			 * so that their labels get updated.  It's unnecessary
+			 * to do this for pool creation since the vdev's
+			 * configuratoin has already been dirtied.
+			 */
+			if (tx->tx_txg != TXG_INITIAL)
+				vdev_config_dirty(spa->spa_root_vdev);
+			spa_history_log_internal(spa, "set", tx,
+			    "%s=%s", nvpair_name(elem), strval);
+			break;
+		default:
+			/*
+			 * Set pool property values in the poolprops mos object.
+			 */
+			if (spa->spa_pool_props_object == 0) {
+				spa->spa_pool_props_object =
+				    zap_create_link(mos, DMU_OT_POOL_PROPS,
+				    DMU_POOL_DIRECTORY_OBJECT, DMU_POOL_PROPS,
+				    tx);
+			}
+
+			/* normalize the property name */
+			propname = zpool_prop_to_name(prop);
+			proptype = zpool_prop_get_type(prop);
+
+			if (nvpair_type(elem) == DATA_TYPE_STRING) {
+				ASSERT(proptype == PROP_TYPE_STRING);
+				strval = fnvpair_value_string(elem);
+				VERIFY0(zap_update(mos,
+				    spa->spa_pool_props_object, propname,
+				    1, strlen(strval) + 1, strval, tx));
+				spa_history_log_internal(spa, "set", tx,
+				    "%s=%s", nvpair_name(elem), strval);
+			} else if (nvpair_type(elem) == DATA_TYPE_UINT64) {
+				intval = fnvpair_value_uint64(elem);
+
+				if (proptype == PROP_TYPE_INDEX) {
+					const char *unused;
+					VERIFY0(zpool_prop_index_to_string(
+					    prop, intval, &unused));
+				}
+				VERIFY0(zap_update(mos,
+				    spa->spa_pool_props_object, propname,
+				    8, 1, &intval, tx));
+				spa_history_log_internal(spa, "set", tx,
+				    "%s=%lld", nvpair_name(elem), intval);
+			} else {
+				ASSERT(0); /* not allowed */
+			}
+
+			switch (prop) {
+			case ZPOOL_PROP_DELEGATION:
+				spa->spa_delegation = intval;
+				break;
+			case ZPOOL_PROP_BOOTFS:
+				spa->spa_bootfs = intval;
+				break;
+			case ZPOOL_PROP_FAILUREMODE:
+				spa->spa_failmode = intval;
+				break;
+			case ZPOOL_PROP_AUTOEXPAND:
+				spa->spa_autoexpand = intval;
+				if (tx->tx_txg != TXG_INITIAL)
+					spa_async_request(spa,
+					    SPA_ASYNC_AUTOEXPAND);
+				break;
+			case ZPOOL_PROP_DEDUPDITTO:
+				spa->spa_dedup_ditto = intval;
+				break;
+			default:
+				break;
+			}
+		}
+
+	}
+
+	mutex_exit(&spa->spa_props_lock);
+}
+
+/*
+ * Perform one-time upgrade on-disk changes.  spa_version() does not
+ * reflect the new version this txg, so there must be no changes this
+ * txg to anything that the upgrade code depends on after it executes.
+ * Therefore this must be called after dsl_pool_sync() does the sync
+ * tasks.
+ */
+static void
+spa_sync_upgrades(spa_t *spa, dmu_tx_t *tx)
+{
+	dsl_pool_t *dp = spa->spa_dsl_pool;
+
+	ASSERT(spa->spa_sync_pass == 1);
+
+	rrw_enter(&dp->dp_config_rwlock, RW_WRITER, FTAG);
+
+	if (spa->spa_ubsync.ub_version < SPA_VERSION_ORIGIN &&
+	    spa->spa_uberblock.ub_version >= SPA_VERSION_ORIGIN) {
+		dsl_pool_create_origin(dp, tx);
+
+		/* Keeping the origin open increases spa_minref */
+		spa->spa_minref += 3;
+	}
+
+	if (spa->spa_ubsync.ub_version < SPA_VERSION_NEXT_CLONES &&
+	    spa->spa_uberblock.ub_version >= SPA_VERSION_NEXT_CLONES) {
+		dsl_pool_upgrade_clones(dp, tx);
+	}
+
+	if (spa->spa_ubsync.ub_version < SPA_VERSION_DIR_CLONES &&
+	    spa->spa_uberblock.ub_version >= SPA_VERSION_DIR_CLONES) {
+		dsl_pool_upgrade_dir_clones(dp, tx);
+
+		/* Keeping the freedir open increases spa_minref */
+		spa->spa_minref += 3;
+	}
+
+	if (spa->spa_ubsync.ub_version < SPA_VERSION_FEATURES &&
+	    spa->spa_uberblock.ub_version >= SPA_VERSION_FEATURES) {
+		spa_feature_create_zap_objects(spa, tx);
+	}
+
+	/*
+	 * LZ4_COMPRESS feature's behaviour was changed to activate_on_enable
+	 * when possibility to use lz4 compression for metadata was added
+	 * Old pools that have this feature enabled must be upgraded to have
+	 * this feature active
+	 */
+	if (spa->spa_uberblock.ub_version >= SPA_VERSION_FEATURES) {
+		boolean_t lz4_en = spa_feature_is_enabled(spa,
+		    SPA_FEATURE_LZ4_COMPRESS);
+		boolean_t lz4_ac = spa_feature_is_active(spa,
+		    SPA_FEATURE_LZ4_COMPRESS);
+
+		if (lz4_en && !lz4_ac)
+			spa_feature_incr(spa, SPA_FEATURE_LZ4_COMPRESS, tx);
+	}
+	rrw_exit(&dp->dp_config_rwlock, FTAG);
+}
+
+/*
+ * Sync the specified transaction group.  New blocks may be dirtied as
+ * part of the process, so we iterate until it converges.
+ */
+void
+spa_sync(spa_t *spa, uint64_t txg)
+{
+	dsl_pool_t *dp = spa->spa_dsl_pool;
+	objset_t *mos = spa->spa_meta_objset;
+	bplist_t *free_bpl = &spa->spa_free_bplist[txg & TXG_MASK];
+	vdev_t *rvd = spa->spa_root_vdev;
+	vdev_t *vd;
+	dmu_tx_t *tx;
+	int error;
+	int c;
+
+	VERIFY(spa_writeable(spa));
+
+	/*
+	 * Lock out configuration changes.
+	 */
+	spa_config_enter(spa, SCL_CONFIG, FTAG, RW_READER);
+
+	spa->spa_syncing_txg = txg;
+	spa->spa_sync_pass = 0;
+
+	/*
+	 * If there are any pending vdev state changes, convert them
+	 * into config changes that go out with this transaction group.
+	 */
+	spa_config_enter(spa, SCL_STATE, FTAG, RW_READER);
+	while (list_head(&spa->spa_state_dirty_list) != NULL) {
+		/*
+		 * We need the write lock here because, for aux vdevs,
+		 * calling vdev_config_dirty() modifies sav_config.
+		 * This is ugly and will become unnecessary when we
+		 * eliminate the aux vdev wart by integrating all vdevs
+		 * into the root vdev tree.
+		 */
+		spa_config_exit(spa, SCL_CONFIG | SCL_STATE, FTAG);
+		spa_config_enter(spa, SCL_CONFIG | SCL_STATE, FTAG, RW_WRITER);
+		while ((vd = list_head(&spa->spa_state_dirty_list)) != NULL) {
+			vdev_state_clean(vd);
+			vdev_config_dirty(vd);
+		}
+		spa_config_exit(spa, SCL_CONFIG | SCL_STATE, FTAG);
+		spa_config_enter(spa, SCL_CONFIG | SCL_STATE, FTAG, RW_READER);
+	}
+	spa_config_exit(spa, SCL_STATE, FTAG);
+
+	tx = dmu_tx_create_assigned(dp, txg);
+
+	spa->spa_sync_starttime = gethrtime();
+	taskq_cancel_id(system_taskq, spa->spa_deadman_tqid);
+	spa->spa_deadman_tqid = taskq_dispatch_delay(system_taskq,
+	    spa_deadman, spa, TQ_SLEEP, ddi_get_lbolt() +
+	    NSEC_TO_TICK(spa->spa_deadman_synctime));
+
+	/*
+	 * If we are upgrading to SPA_VERSION_RAIDZ_DEFLATE this txg,
+	 * set spa_deflate if we have no raid-z vdevs.
+	 */
+	if (spa->spa_ubsync.ub_version < SPA_VERSION_RAIDZ_DEFLATE &&
+	    spa->spa_uberblock.ub_version >= SPA_VERSION_RAIDZ_DEFLATE) {
+		int i;
+
+		for (i = 0; i < rvd->vdev_children; i++) {
+			vd = rvd->vdev_child[i];
+			if (vd->vdev_deflate_ratio != SPA_MINBLOCKSIZE)
+				break;
+		}
+		if (i == rvd->vdev_children) {
+			spa->spa_deflate = TRUE;
+			VERIFY(0 == zap_add(spa->spa_meta_objset,
+			    DMU_POOL_DIRECTORY_OBJECT, DMU_POOL_DEFLATE,
+			    sizeof (uint64_t), 1, &spa->spa_deflate, tx));
+		}
+	}
+
+	/*
+	 * Iterate to convergence.
+	 */
+	do {
+		int pass = ++spa->spa_sync_pass;
+
+		spa_sync_config_object(spa, tx);
+		spa_sync_aux_dev(spa, &spa->spa_spares, tx,
+		    ZPOOL_CONFIG_SPARES, DMU_POOL_SPARES);
+		spa_sync_aux_dev(spa, &spa->spa_l2cache, tx,
+		    ZPOOL_CONFIG_L2CACHE, DMU_POOL_L2CACHE);
+		spa_errlog_sync(spa, txg);
+		dsl_pool_sync(dp, txg);
+
+		if (pass < zfs_sync_pass_deferred_free) {
+			spa_sync_frees(spa, free_bpl, tx);
+		} else {
+			/*
+			 * We can not defer frees in pass 1, because
+			 * we sync the deferred frees later in pass 1.
+			 */
+			ASSERT3U(pass, >, 1);
+			bplist_iterate(free_bpl, bpobj_enqueue_cb,
+			    &spa->spa_deferred_bpobj, tx);
+		}
+
+		ddt_sync(spa, txg);
+		dsl_scan_sync(dp, tx);
+
+		while ((vd = txg_list_remove(&spa->spa_vdev_txg_list, txg)))
+			vdev_sync(vd, txg);
+
+		if (pass == 1) {
+			spa_sync_upgrades(spa, tx);
+			ASSERT3U(txg, >=,
+			    spa->spa_uberblock.ub_rootbp.blk_birth);
+			/*
+			 * Note: We need to check if the MOS is dirty
+			 * because we could have marked the MOS dirty
+			 * without updating the uberblock (e.g. if we
+			 * have sync tasks but no dirty user data).  We
+			 * need to check the uberblock's rootbp because
+			 * it is updated if we have synced out dirty
+			 * data (though in this case the MOS will most
+			 * likely also be dirty due to second order
+			 * effects, we don't want to rely on that here).
+			 */
+			if (spa->spa_uberblock.ub_rootbp.blk_birth < txg &&
+			    !dmu_objset_is_dirty(mos, txg)) {
+				/*
+				 * Nothing changed on the first pass,
+				 * therefore this TXG is a no-op.  Avoid
+				 * syncing deferred frees, so that we
+				 * can keep this TXG as a no-op.
+				 */
+				ASSERT(txg_list_empty(&dp->dp_dirty_datasets,
+				    txg));
+				ASSERT(txg_list_empty(&dp->dp_dirty_dirs, txg));
+				ASSERT(txg_list_empty(&dp->dp_sync_tasks, txg));
+				break;
+			}
+			spa_sync_deferred_frees(spa, tx);
+		}
+
+	} while (dmu_objset_is_dirty(mos, txg));
+
+	/*
+	 * Rewrite the vdev configuration (which includes the uberblock)
+	 * to commit the transaction group.
+	 *
+	 * If there are no dirty vdevs, we sync the uberblock to a few
+	 * random top-level vdevs that are known to be visible in the
+	 * config cache (see spa_vdev_add() for a complete description).
+	 * If there *are* dirty vdevs, sync the uberblock to all vdevs.
+	 */
+	for (;;) {
+		/*
+		 * We hold SCL_STATE to prevent vdev open/close/etc.
+		 * while we're attempting to write the vdev labels.
+		 */
+		spa_config_enter(spa, SCL_STATE, FTAG, RW_READER);
+
+		if (list_is_empty(&spa->spa_config_dirty_list)) {
+			vdev_t *svd[SPA_DVAS_PER_BP];
+			int svdcount = 0;
+			int children = rvd->vdev_children;
+			int c0 = spa_get_random(children);
+
+			for (c = 0; c < children; c++) {
+				vd = rvd->vdev_child[(c0 + c) % children];
+				if (vd->vdev_ms_array == 0 || vd->vdev_islog)
+					continue;
+				svd[svdcount++] = vd;
+				if (svdcount == SPA_DVAS_PER_BP)
+					break;
+			}
+			error = vdev_config_sync(svd, svdcount, txg, B_FALSE);
+			if (error != 0)
+				error = vdev_config_sync(svd, svdcount, txg,
+				    B_TRUE);
+		} else {
+			error = vdev_config_sync(rvd->vdev_child,
+			    rvd->vdev_children, txg, B_FALSE);
+			if (error != 0)
+				error = vdev_config_sync(rvd->vdev_child,
+				    rvd->vdev_children, txg, B_TRUE);
+		}
+
+		if (error == 0)
+			spa->spa_last_synced_guid = rvd->vdev_guid;
+
+		spa_config_exit(spa, SCL_STATE, FTAG);
+
+		if (error == 0)
+			break;
+		zio_suspend(spa, NULL);
+		zio_resume_wait(spa);
+	}
+	dmu_tx_commit(tx);
+
+	taskq_cancel_id(system_taskq, spa->spa_deadman_tqid);
+	spa->spa_deadman_tqid = 0;
+
+	/*
+	 * Clear the dirty config list.
+	 */
+	while ((vd = list_head(&spa->spa_config_dirty_list)) != NULL)
+		vdev_config_clean(vd);
+
+	/*
+	 * Now that the new config has synced transactionally,
+	 * let it become visible to the config cache.
+	 */
+	if (spa->spa_config_syncing != NULL) {
+		spa_config_set(spa, spa->spa_config_syncing);
+		spa->spa_config_txg = txg;
+		spa->spa_config_syncing = NULL;
+	}
+
+	spa->spa_ubsync = spa->spa_uberblock;
+
+	dsl_pool_sync_done(dp, txg);
+
+	/*
+	 * Update usable space statistics.
+	 */
+	while ((vd = txg_list_remove(&spa->spa_vdev_txg_list, TXG_CLEAN(txg))))
+		vdev_sync_done(vd, txg);
+
+	spa_update_dspace(spa);
+
+	/*
+	 * It had better be the case that we didn't dirty anything
+	 * since vdev_config_sync().
+	 */
+	ASSERT(txg_list_empty(&dp->dp_dirty_datasets, txg));
+	ASSERT(txg_list_empty(&dp->dp_dirty_dirs, txg));
+	ASSERT(txg_list_empty(&spa->spa_vdev_txg_list, txg));
+
+	spa->spa_sync_pass = 0;
+
+	spa_config_exit(spa, SCL_CONFIG, FTAG);
+
+	spa_handle_ignored_writes(spa);
+
+	/*
+	 * If any async tasks have been requested, kick them off.
+	 */
+	spa_async_dispatch(spa);
+}
+
+/*
+ * Sync all pools.  We don't want to hold the namespace lock across these
+ * operations, so we take a reference on the spa_t and drop the lock during the
+ * sync.
+ */
+void
+spa_sync_allpools(void)
+{
+	spa_t *spa = NULL;
+	mutex_enter(&spa_namespace_lock);
+	while ((spa = spa_next(spa)) != NULL) {
+		if (spa_state(spa) != POOL_STATE_ACTIVE ||
+		    !spa_writeable(spa) || spa_suspended(spa))
+			continue;
+		spa_open_ref(spa, FTAG);
+		mutex_exit(&spa_namespace_lock);
+		txg_wait_synced(spa_get_dsl(spa), 0);
+		mutex_enter(&spa_namespace_lock);
+		spa_close(spa, FTAG);
+	}
+	mutex_exit(&spa_namespace_lock);
+}
+
+/*
+ * ==========================================================================
+ * Miscellaneous routines
+ * ==========================================================================
+ */
+
+/*
+ * Remove all pools in the system.
+ */
+void
+spa_evict_all(void)
+{
+	spa_t *spa;
+
+	/*
+	 * Remove all cached state.  All pools should be closed now,
+	 * so every spa in the AVL tree should be unreferenced.
+	 */
+	mutex_enter(&spa_namespace_lock);
+	while ((spa = spa_next(NULL)) != NULL) {
+		/*
+		 * Stop async tasks.  The async thread may need to detach
+		 * a device that's been replaced, which requires grabbing
+		 * spa_namespace_lock, so we must drop it here.
+		 */
+		spa_open_ref(spa, FTAG);
+		mutex_exit(&spa_namespace_lock);
+		spa_async_suspend(spa);
+		mutex_enter(&spa_namespace_lock);
+		spa_close(spa, FTAG);
+
+		if (spa->spa_state != POOL_STATE_UNINITIALIZED) {
+			spa_unload(spa);
+			spa_deactivate(spa);
+		}
+		spa_remove(spa);
+	}
+	mutex_exit(&spa_namespace_lock);
+}
+
+vdev_t *
+spa_lookup_by_guid(spa_t *spa, uint64_t guid, boolean_t aux)
+{
+	vdev_t *vd;
+	int i;
+
+	if ((vd = vdev_lookup_by_guid(spa->spa_root_vdev, guid)) != NULL)
+		return (vd);
+
+	if (aux) {
+		for (i = 0; i < spa->spa_l2cache.sav_count; i++) {
+			vd = spa->spa_l2cache.sav_vdevs[i];
+			if (vd->vdev_guid == guid)
+				return (vd);
+		}
+
+		for (i = 0; i < spa->spa_spares.sav_count; i++) {
+			vd = spa->spa_spares.sav_vdevs[i];
+			if (vd->vdev_guid == guid)
+				return (vd);
+		}
+	}
+
+	return (NULL);
+}
+
+void
+spa_upgrade(spa_t *spa, uint64_t version)
+{
+	ASSERT(spa_writeable(spa));
+
+	spa_config_enter(spa, SCL_ALL, FTAG, RW_WRITER);
+
+	/*
+	 * This should only be called for a non-faulted pool, and since a
+	 * future version would result in an unopenable pool, this shouldn't be
+	 * possible.
+	 */
+	ASSERT(SPA_VERSION_IS_SUPPORTED(spa->spa_uberblock.ub_version));
+	ASSERT3U(version, >=, spa->spa_uberblock.ub_version);
+
+	spa->spa_uberblock.ub_version = version;
+	vdev_config_dirty(spa->spa_root_vdev);
+
+	spa_config_exit(spa, SCL_ALL, FTAG);
+
+	txg_wait_synced(spa_get_dsl(spa), 0);
+}
+
+boolean_t
+spa_has_spare(spa_t *spa, uint64_t guid)
+{
+	int i;
+	uint64_t spareguid;
+	spa_aux_vdev_t *sav = &spa->spa_spares;
+
+	for (i = 0; i < sav->sav_count; i++)
+		if (sav->sav_vdevs[i]->vdev_guid == guid)
+			return (B_TRUE);
+
+	for (i = 0; i < sav->sav_npending; i++) {
+		if (nvlist_lookup_uint64(sav->sav_pending[i], ZPOOL_CONFIG_GUID,
+		    &spareguid) == 0 && spareguid == guid)
+			return (B_TRUE);
+	}
+
+	return (B_FALSE);
+}
+
+/*
+ * Check if a pool has an active shared spare device.
+ * Note: reference count of an active spare is 2, as a spare and as a replace
+ */
+static boolean_t
+spa_has_active_shared_spare(spa_t *spa)
+{
+	int i, refcnt;
+	uint64_t pool;
+	spa_aux_vdev_t *sav = &spa->spa_spares;
+
+	for (i = 0; i < sav->sav_count; i++) {
+		if (spa_spare_exists(sav->sav_vdevs[i]->vdev_guid, &pool,
+		    &refcnt) && pool != 0ULL && pool == spa_guid(spa) &&
+		    refcnt > 2)
+			return (B_TRUE);
+	}
+
+	return (B_FALSE);
+}
+
+/*
+ * Post a FM_EREPORT_ZFS_* event from sys/fm/fs/zfs.h.  The payload will be
+ * filled in from the spa and (optionally) the vdev.  This doesn't do anything
+ * in the userland libzpool, as we don't want consumers to misinterpret ztest
+ * or zdb as real changes.
+ */
+void
+spa_event_notify(spa_t *spa, vdev_t *vd, const char *name)
+{
+#ifdef _KERNEL
+	zfs_ereport_post(name, spa, vd, NULL, 0, 0);
+#endif
+}
+
+#if defined(_KERNEL) && defined(HAVE_SPL)
+/* state manipulation functions */
+EXPORT_SYMBOL(spa_open);
+EXPORT_SYMBOL(spa_open_rewind);
+EXPORT_SYMBOL(spa_get_stats);
+EXPORT_SYMBOL(spa_create);
+EXPORT_SYMBOL(spa_import_rootpool);
+EXPORT_SYMBOL(spa_import);
+EXPORT_SYMBOL(spa_tryimport);
+EXPORT_SYMBOL(spa_destroy);
+EXPORT_SYMBOL(spa_export);
+EXPORT_SYMBOL(spa_reset);
+EXPORT_SYMBOL(spa_async_request);
+EXPORT_SYMBOL(spa_async_suspend);
+EXPORT_SYMBOL(spa_async_resume);
+EXPORT_SYMBOL(spa_inject_addref);
+EXPORT_SYMBOL(spa_inject_delref);
+EXPORT_SYMBOL(spa_scan_stat_init);
+EXPORT_SYMBOL(spa_scan_get_stats);
+
+/* device maniion */
+EXPORT_SYMBOL(spa_vdev_add);
+EXPORT_SYMBOL(spa_vdev_attach);
+EXPORT_SYMBOL(spa_vdev_detach);
+EXPORT_SYMBOL(spa_vdev_remove);
+EXPORT_SYMBOL(spa_vdev_setpath);
+EXPORT_SYMBOL(spa_vdev_setfru);
+EXPORT_SYMBOL(spa_vdev_split_mirror);
+
+/* spare statech is global across all pools) */
+EXPORT_SYMBOL(spa_spare_add);
+EXPORT_SYMBOL(spa_spare_remove);
+EXPORT_SYMBOL(spa_spare_exists);
+EXPORT_SYMBOL(spa_spare_activate);
+
+/* L2ARC statech is global across all pools) */
+EXPORT_SYMBOL(spa_l2cache_add);
+EXPORT_SYMBOL(spa_l2cache_remove);
+EXPORT_SYMBOL(spa_l2cache_exists);
+EXPORT_SYMBOL(spa_l2cache_activate);
+EXPORT_SYMBOL(spa_l2cache_drop);
+
+/* scanning */
+EXPORT_SYMBOL(spa_scan);
+EXPORT_SYMBOL(spa_scan_stop);
+
+/* spa syncing */
+EXPORT_SYMBOL(spa_sync); /* only for DMU use */
+EXPORT_SYMBOL(spa_sync_allpools);
+
+/* properties */
+EXPORT_SYMBOL(spa_prop_set);
+EXPORT_SYMBOL(spa_prop_get);
+EXPORT_SYMBOL(spa_prop_clear_bootfs);
+
+/* asynchronous event notification */
+EXPORT_SYMBOL(spa_event_notify);
+#endif
+
+#if defined(_KERNEL) && defined(HAVE_SPL)
+module_param(spa_load_verify_maxinflight, int, 0644);
+MODULE_PARM_DESC(spa_load_verify_maxinflight,
+	"Max concurrent traversal I/Os while verifying pool during import -X");
+
+module_param(spa_load_verify_metadata, int, 0644);
+MODULE_PARM_DESC(spa_load_verify_metadata,
+	"Set to traverse metadata on pool import");
+
+module_param(spa_load_verify_data, int, 0644);
+MODULE_PARM_DESC(spa_load_verify_data,
+	"Set to traverse data on pool import");
+
+module_param(zio_taskq_batch_pct, uint, 0444);
+MODULE_PARM_DESC(zio_taskq_batch_pct,
+	"Percentage of CPUs to run an IO worker thread");
+
+#endif
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/module/zfs/spa_boot.c
@@ -0,0 +1,50 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifdef _KERNEL
+
+#include <sys/zio.h>
+#include <sys/spa.h>
+#include <sys/sunddi.h>
+
+char *
+spa_get_bootprop(char *propname)
+{
+	char *value;
+
+	if (ddi_prop_lookup_string(DDI_DEV_T_ANY, ddi_root_node(),
+	    DDI_PROP_DONTPASS, propname, &value) != DDI_SUCCESS)
+		return (NULL);
+	return (value);
+}
+
+void
+spa_free_bootprop(char *value)
+{
+	ddi_prop_free(value);
+}
+
+#endif /* _KERNEL */
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/module/zfs/spa_config.c
@@ -0,0 +1,583 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
+ * Copyright (c) 2013 by Delphix. All rights reserved.
+ */
+
+#include <sys/spa.h>
+#include <sys/spa_impl.h>
+#include <sys/nvpair.h>
+#include <sys/uio.h>
+#include <sys/fs/zfs.h>
+#include <sys/vdev_impl.h>
+#include <sys/zfs_ioctl.h>
+#include <sys/systeminfo.h>
+#include <sys/sunddi.h>
+#include <sys/zfeature.h>
+#ifdef _KERNEL
+#include <sys/kobj.h>
+#include <sys/zone.h>
+#endif
+
+/*
+ * Pool configuration repository.
+ *
+ * Pool configuration is stored as a packed nvlist on the filesystem.  By
+ * default, all pools are stored in /etc/zfs/zpool.cache and loaded on boot
+ * (when the ZFS module is loaded).  Pools can also have the 'cachefile'
+ * property set that allows them to be stored in an alternate location until
+ * the control of external software.
+ *
+ * For each cache file, we have a single nvlist which holds all the
+ * configuration information.  When the module loads, we read this information
+ * from /etc/zfs/zpool.cache and populate the SPA namespace.  This namespace is
+ * maintained independently in spa.c.  Whenever the namespace is modified, or
+ * the configuration of a pool is changed, we call spa_config_sync(), which
+ * walks through all the active pools and writes the configuration to disk.
+ */
+
+static uint64_t spa_config_generation = 1;
+
+/*
+ * This can be overridden in userland to preserve an alternate namespace for
+ * userland pools when doing testing.
+ */
+char *spa_config_path = ZPOOL_CACHE;
+int zfs_autoimport_disable = 1;
+
+/*
+ * Called when the module is first loaded, this routine loads the configuration
+ * file into the SPA namespace.  It does not actually open or load the pools; it
+ * only populates the namespace.
+ */
+void
+spa_config_load(void)
+{
+	void *buf = NULL;
+	nvlist_t *nvlist, *child;
+	nvpair_t *nvpair;
+	char *pathname;
+	struct _buf *file;
+	uint64_t fsize;
+
+#ifdef _KERNEL
+	if (zfs_autoimport_disable)
+		return;
+#endif
+
+	/*
+	 * Open the configuration file.
+	 */
+	pathname = kmem_alloc(MAXPATHLEN, KM_SLEEP);
+
+	(void) snprintf(pathname, MAXPATHLEN, "%s%s",
+	    (rootdir != NULL) ? "./" : "", spa_config_path);
+
+	file = kobj_open_file(pathname);
+
+	kmem_free(pathname, MAXPATHLEN);
+
+	if (file == (struct _buf *)-1)
+		return;
+
+	if (kobj_get_filesize(file, &fsize) != 0)
+		goto out;
+
+	buf = kmem_alloc(fsize, KM_SLEEP);
+
+	/*
+	 * Read the nvlist from the file.
+	 */
+	if (kobj_read_file(file, buf, fsize, 0) < 0)
+		goto out;
+
+	/*
+	 * Unpack the nvlist.
+	 */
+	if (nvlist_unpack(buf, fsize, &nvlist, KM_SLEEP) != 0)
+		goto out;
+
+	/*
+	 * Iterate over all elements in the nvlist, creating a new spa_t for
+	 * each one with the specified configuration.
+	 */
+	mutex_enter(&spa_namespace_lock);
+	nvpair = NULL;
+	while ((nvpair = nvlist_next_nvpair(nvlist, nvpair)) != NULL) {
+		if (nvpair_type(nvpair) != DATA_TYPE_NVLIST)
+			continue;
+
+		VERIFY(nvpair_value_nvlist(nvpair, &child) == 0);
+
+		if (spa_lookup(nvpair_name(nvpair)) != NULL)
+			continue;
+		(void) spa_add(nvpair_name(nvpair), child, NULL);
+	}
+	mutex_exit(&spa_namespace_lock);
+
+	nvlist_free(nvlist);
+
+out:
+	if (buf != NULL)
+		kmem_free(buf, fsize);
+
+	kobj_close_file(file);
+}
+
+static void
+spa_config_write(spa_config_dirent_t *dp, nvlist_t *nvl)
+{
+	size_t buflen;
+	char *buf;
+	vnode_t *vp;
+	int oflags = FWRITE | FTRUNC | FCREAT | FOFFMAX;
+	int error;
+	char *temp;
+
+	/*
+	 * If the nvlist is empty (NULL), then remove the old cachefile.
+	 */
+	if (nvl == NULL) {
+		(void) vn_remove(dp->scd_path, UIO_SYSSPACE, RMFILE);
+		return;
+	}
+
+	/*
+	 * Pack the configuration into a buffer.
+	 */
+	VERIFY(nvlist_size(nvl, &buflen, NV_ENCODE_XDR) == 0);
+
+	buf = vmem_alloc(buflen, KM_SLEEP);
+	temp = kmem_zalloc(MAXPATHLEN, KM_SLEEP);
+
+	VERIFY(nvlist_pack(nvl, &buf, &buflen, NV_ENCODE_XDR,
+	    KM_SLEEP) == 0);
+
+#if defined(__linux__) && defined(_KERNEL)
+	/*
+	 * Write the configuration to disk.  Due to the complexity involved
+	 * in performing a rename from within the kernel the file is truncated
+	 * and overwritten in place.  In the event of an error the file is
+	 * unlinked to make sure we always have a consistent view of the data.
+	 */
+	error = vn_open(dp->scd_path, UIO_SYSSPACE, oflags, 0644, &vp, 0, 0);
+	if (error == 0) {
+		error = vn_rdwr(UIO_WRITE, vp, buf, buflen, 0,
+		    UIO_SYSSPACE, 0, RLIM64_INFINITY, kcred, NULL);
+		if (error == 0)
+			error = VOP_FSYNC(vp, FSYNC, kcred, NULL);
+
+		(void) VOP_CLOSE(vp, oflags, 1, 0, kcred, NULL);
+
+		if (error)
+			(void) vn_remove(dp->scd_path, UIO_SYSSPACE, RMFILE);
+	}
+#else
+	/*
+	 * Write the configuration to disk.  We need to do the traditional
+	 * 'write to temporary file, sync, move over original' to make sure we
+	 * always have a consistent view of the data.
+	 */
+	(void) snprintf(temp, MAXPATHLEN, "%s.tmp", dp->scd_path);
+
+	error = vn_open(temp, UIO_SYSSPACE, oflags, 0644, &vp, CRCREAT, 0);
+	if (error == 0) {
+		if (vn_rdwr(UIO_WRITE, vp, buf, buflen, 0, UIO_SYSSPACE,
+		    0, RLIM64_INFINITY, kcred, NULL) == 0 &&
+		    VOP_FSYNC(vp, FSYNC, kcred, NULL) == 0) {
+			(void) vn_rename(temp, dp->scd_path, UIO_SYSSPACE);
+		}
+		(void) VOP_CLOSE(vp, oflags, 1, 0, kcred, NULL);
+	}
+
+	(void) vn_remove(temp, UIO_SYSSPACE, RMFILE);
+#endif
+
+	vmem_free(buf, buflen);
+	kmem_free(temp, MAXPATHLEN);
+}
+
+/*
+ * Synchronize pool configuration to disk.  This must be called with the
+ * namespace lock held. Synchronizing the pool cache is typically done after
+ * the configuration has been synced to the MOS. This exposes a window where
+ * the MOS config will have been updated but the cache file has not. If
+ * the system were to crash at that instant then the cached config may not
+ * contain the correct information to open the pool and an explicity import
+ * would be required.
+ */
+void
+spa_config_sync(spa_t *target, boolean_t removing, boolean_t postsysevent)
+{
+	spa_config_dirent_t *dp, *tdp;
+	nvlist_t *nvl;
+	char *pool_name;
+
+	ASSERT(MUTEX_HELD(&spa_namespace_lock));
+
+	if (rootdir == NULL || !(spa_mode_global & FWRITE))
+		return;
+
+	/*
+	 * Iterate over all cachefiles for the pool, past or present.  When the
+	 * cachefile is changed, the new one is pushed onto this list, allowing
+	 * us to update previous cachefiles that no longer contain this pool.
+	 */
+	for (dp = list_head(&target->spa_config_list); dp != NULL;
+	    dp = list_next(&target->spa_config_list, dp)) {
+		spa_t *spa = NULL;
+		if (dp->scd_path == NULL)
+			continue;
+
+		/*
+		 * Iterate over all pools, adding any matching pools to 'nvl'.
+		 */
+		nvl = NULL;
+		while ((spa = spa_next(spa)) != NULL) {
+			/*
+			 * Skip over our own pool if we're about to remove
+			 * ourselves from the spa namespace or any pool that
+			 * is readonly. Since we cannot guarantee that a
+			 * readonly pool would successfully import upon reboot,
+			 * we don't allow them to be written to the cache file.
+			 */
+			if ((spa == target && removing) ||
+			    !spa_writeable(spa))
+				continue;
+
+			mutex_enter(&spa->spa_props_lock);
+			tdp = list_head(&spa->spa_config_list);
+			if (spa->spa_config == NULL ||
+			    tdp->scd_path == NULL ||
+			    strcmp(tdp->scd_path, dp->scd_path) != 0) {
+				mutex_exit(&spa->spa_props_lock);
+				continue;
+			}
+
+			if (nvl == NULL)
+				VERIFY(nvlist_alloc(&nvl, NV_UNIQUE_NAME,
+				    KM_SLEEP) == 0);
+
+			if (spa->spa_import_flags & ZFS_IMPORT_TEMP_NAME) {
+				VERIFY0(nvlist_lookup_string(spa->spa_config,
+					ZPOOL_CONFIG_POOL_NAME, &pool_name));
+			} else
+				pool_name = spa_name(spa);
+
+			VERIFY(nvlist_add_nvlist(nvl, pool_name,
+			    spa->spa_config) == 0);
+			mutex_exit(&spa->spa_props_lock);
+		}
+
+		spa_config_write(dp, nvl);
+		nvlist_free(nvl);
+	}
+
+	/*
+	 * Remove any config entries older than the current one.
+	 */
+	dp = list_head(&target->spa_config_list);
+	while ((tdp = list_next(&target->spa_config_list, dp)) != NULL) {
+		list_remove(&target->spa_config_list, tdp);
+		if (tdp->scd_path != NULL)
+			spa_strfree(tdp->scd_path);
+		kmem_free(tdp, sizeof (spa_config_dirent_t));
+	}
+
+	spa_config_generation++;
+
+	if (postsysevent)
+		spa_event_notify(target, NULL, FM_EREPORT_ZFS_CONFIG_SYNC);
+}
+
+/*
+ * Sigh.  Inside a local zone, we don't have access to /etc/zfs/zpool.cache,
+ * and we don't want to allow the local zone to see all the pools anyway.
+ * So we have to invent the ZFS_IOC_CONFIG ioctl to grab the configuration
+ * information for all pool visible within the zone.
+ */
+nvlist_t *
+spa_all_configs(uint64_t *generation)
+{
+	nvlist_t *pools;
+	spa_t *spa = NULL;
+
+	if (*generation == spa_config_generation)
+		return (NULL);
+
+	VERIFY(nvlist_alloc(&pools, NV_UNIQUE_NAME, KM_SLEEP) == 0);
+
+	mutex_enter(&spa_namespace_lock);
+	while ((spa = spa_next(spa)) != NULL) {
+		if (INGLOBALZONE(curproc) ||
+		    zone_dataset_visible(spa_name(spa), NULL)) {
+			mutex_enter(&spa->spa_props_lock);
+			VERIFY(nvlist_add_nvlist(pools, spa_name(spa),
+			    spa->spa_config) == 0);
+			mutex_exit(&spa->spa_props_lock);
+		}
+	}
+	*generation = spa_config_generation;
+	mutex_exit(&spa_namespace_lock);
+
+	return (pools);
+}
+
+void
+spa_config_set(spa_t *spa, nvlist_t *config)
+{
+	mutex_enter(&spa->spa_props_lock);
+	if (spa->spa_config != NULL)
+		nvlist_free(spa->spa_config);
+	spa->spa_config = config;
+	mutex_exit(&spa->spa_props_lock);
+}
+
+/*
+ * Generate the pool's configuration based on the current in-core state.
+ *
+ * We infer whether to generate a complete config or just one top-level config
+ * based on whether vd is the root vdev.
+ */
+nvlist_t *
+spa_config_generate(spa_t *spa, vdev_t *vd, uint64_t txg, int getstats)
+{
+	nvlist_t *config, *nvroot;
+	vdev_t *rvd = spa->spa_root_vdev;
+	unsigned long hostid = 0;
+	boolean_t locked = B_FALSE;
+	uint64_t split_guid;
+	char *pool_name;
+
+	if (vd == NULL) {
+		vd = rvd;
+		locked = B_TRUE;
+		spa_config_enter(spa, SCL_CONFIG | SCL_STATE, FTAG, RW_READER);
+	}
+
+	ASSERT(spa_config_held(spa, SCL_CONFIG | SCL_STATE, RW_READER) ==
+	    (SCL_CONFIG | SCL_STATE));
+
+	/*
+	 * If txg is -1, report the current value of spa->spa_config_txg.
+	 */
+	if (txg == -1ULL)
+		txg = spa->spa_config_txg;
+
+	/*
+	 * Originally, users had to handle spa namespace collisions by either
+	 * exporting the already imported pool or by specifying a new name for
+	 * the pool with a conflicting name. In the case of root pools from
+	 * virtual guests, neither approach to collision resolution is
+	 * reasonable. This is addressed by extending the new name syntax with
+	 * an option to specify that the new name is temporary. When specified,
+	 * ZFS_IMPORT_TEMP_NAME will be set in spa->spa_import_flags to tell us
+	 * to use the previous name, which we do below.
+	 */
+	if (spa->spa_import_flags & ZFS_IMPORT_TEMP_NAME) {
+		VERIFY0(nvlist_lookup_string(spa->spa_config,
+			ZPOOL_CONFIG_POOL_NAME, &pool_name));
+	} else
+		pool_name = spa_name(spa);
+
+	VERIFY(nvlist_alloc(&config, NV_UNIQUE_NAME, KM_SLEEP) == 0);
+
+	VERIFY(nvlist_add_uint64(config, ZPOOL_CONFIG_VERSION,
+	    spa_version(spa)) == 0);
+	VERIFY(nvlist_add_string(config, ZPOOL_CONFIG_POOL_NAME,
+	    pool_name) == 0);
+	VERIFY(nvlist_add_uint64(config, ZPOOL_CONFIG_POOL_STATE,
+	    spa_state(spa)) == 0);
+	VERIFY(nvlist_add_uint64(config, ZPOOL_CONFIG_POOL_TXG,
+	    txg) == 0);
+	VERIFY(nvlist_add_uint64(config, ZPOOL_CONFIG_POOL_GUID,
+	    spa_guid(spa)) == 0);
+	VERIFY(nvlist_add_uint64(config, ZPOOL_CONFIG_ERRATA,
+	    spa->spa_errata) == 0);
+	VERIFY(spa->spa_comment == NULL || nvlist_add_string(config,
+	    ZPOOL_CONFIG_COMMENT, spa->spa_comment) == 0);
+
+
+#ifdef	_KERNEL
+	hostid = zone_get_hostid(NULL);
+#else	/* _KERNEL */
+	/*
+	 * We're emulating the system's hostid in userland, so we can't use
+	 * zone_get_hostid().
+	 */
+	(void) ddi_strtoul(hw_serial, NULL, 10, &hostid);
+#endif	/* _KERNEL */
+	if (hostid != 0) {
+		VERIFY(nvlist_add_uint64(config, ZPOOL_CONFIG_HOSTID,
+		    hostid) == 0);
+	}
+	VERIFY0(nvlist_add_string(config, ZPOOL_CONFIG_HOSTNAME,
+	    utsname()->nodename));
+
+	if (vd != rvd) {
+		VERIFY(nvlist_add_uint64(config, ZPOOL_CONFIG_TOP_GUID,
+		    vd->vdev_top->vdev_guid) == 0);
+		VERIFY(nvlist_add_uint64(config, ZPOOL_CONFIG_GUID,
+		    vd->vdev_guid) == 0);
+		if (vd->vdev_isspare)
+			VERIFY(nvlist_add_uint64(config, ZPOOL_CONFIG_IS_SPARE,
+			    1ULL) == 0);
+		if (vd->vdev_islog)
+			VERIFY(nvlist_add_uint64(config, ZPOOL_CONFIG_IS_LOG,
+			    1ULL) == 0);
+		vd = vd->vdev_top;		/* label contains top config */
+	} else {
+		/*
+		 * Only add the (potentially large) split information
+		 * in the mos config, and not in the vdev labels
+		 */
+		if (spa->spa_config_splitting != NULL)
+			VERIFY(nvlist_add_nvlist(config, ZPOOL_CONFIG_SPLIT,
+			    spa->spa_config_splitting) == 0);
+	}
+
+	/*
+	 * Add the top-level config.  We even add this on pools which
+	 * don't support holes in the namespace.
+	 */
+	vdev_top_config_generate(spa, config);
+
+	/*
+	 * If we're splitting, record the original pool's guid.
+	 */
+	if (spa->spa_config_splitting != NULL &&
+	    nvlist_lookup_uint64(spa->spa_config_splitting,
+	    ZPOOL_CONFIG_SPLIT_GUID, &split_guid) == 0) {
+		VERIFY(nvlist_add_uint64(config, ZPOOL_CONFIG_SPLIT_GUID,
+		    split_guid) == 0);
+	}
+
+	nvroot = vdev_config_generate(spa, vd, getstats, 0);
+	VERIFY(nvlist_add_nvlist(config, ZPOOL_CONFIG_VDEV_TREE, nvroot) == 0);
+	nvlist_free(nvroot);
+
+	/*
+	 * Store what's necessary for reading the MOS in the label.
+	 */
+	VERIFY(nvlist_add_nvlist(config, ZPOOL_CONFIG_FEATURES_FOR_READ,
+	    spa->spa_label_features) == 0);
+
+	if (getstats && spa_load_state(spa) == SPA_LOAD_NONE) {
+		ddt_histogram_t *ddh;
+		ddt_stat_t *dds;
+		ddt_object_t *ddo;
+
+		ddh = kmem_zalloc(sizeof (ddt_histogram_t), KM_SLEEP);
+		ddt_get_dedup_histogram(spa, ddh);
+		VERIFY(nvlist_add_uint64_array(config,
+		    ZPOOL_CONFIG_DDT_HISTOGRAM,
+		    (uint64_t *)ddh, sizeof (*ddh) / sizeof (uint64_t)) == 0);
+		kmem_free(ddh, sizeof (ddt_histogram_t));
+
+		ddo = kmem_zalloc(sizeof (ddt_object_t), KM_SLEEP);
+		ddt_get_dedup_object_stats(spa, ddo);
+		VERIFY(nvlist_add_uint64_array(config,
+		    ZPOOL_CONFIG_DDT_OBJ_STATS,
+		    (uint64_t *)ddo, sizeof (*ddo) / sizeof (uint64_t)) == 0);
+		kmem_free(ddo, sizeof (ddt_object_t));
+
+		dds = kmem_zalloc(sizeof (ddt_stat_t), KM_SLEEP);
+		ddt_get_dedup_stats(spa, dds);
+		VERIFY(nvlist_add_uint64_array(config,
+		    ZPOOL_CONFIG_DDT_STATS,
+		    (uint64_t *)dds, sizeof (*dds) / sizeof (uint64_t)) == 0);
+		kmem_free(dds, sizeof (ddt_stat_t));
+	}
+
+	if (locked)
+		spa_config_exit(spa, SCL_CONFIG | SCL_STATE, FTAG);
+
+	return (config);
+}
+
+/*
+ * Update all disk labels, generate a fresh config based on the current
+ * in-core state, and sync the global config cache (do not sync the config
+ * cache if this is a booting rootpool).
+ */
+void
+spa_config_update(spa_t *spa, int what)
+{
+	vdev_t *rvd = spa->spa_root_vdev;
+	uint64_t txg;
+	int c;
+
+	ASSERT(MUTEX_HELD(&spa_namespace_lock));
+
+	spa_config_enter(spa, SCL_ALL, FTAG, RW_WRITER);
+	txg = spa_last_synced_txg(spa) + 1;
+	if (what == SPA_CONFIG_UPDATE_POOL) {
+		vdev_config_dirty(rvd);
+	} else {
+		/*
+		 * If we have top-level vdevs that were added but have
+		 * not yet been prepared for allocation, do that now.
+		 * (It's safe now because the config cache is up to date,
+		 * so it will be able to translate the new DVAs.)
+		 * See comments in spa_vdev_add() for full details.
+		 */
+		for (c = 0; c < rvd->vdev_children; c++) {
+			vdev_t *tvd = rvd->vdev_child[c];
+			if (tvd->vdev_ms_array == 0)
+				vdev_metaslab_set_size(tvd);
+			vdev_expand(tvd, txg);
+		}
+	}
+	spa_config_exit(spa, SCL_ALL, FTAG);
+
+	/*
+	 * Wait for the mosconfig to be regenerated and synced.
+	 */
+	txg_wait_synced(spa->spa_dsl_pool, txg);
+
+	/*
+	 * Update the global config cache to reflect the new mosconfig.
+	 */
+	if (!spa->spa_is_root)
+		spa_config_sync(spa, B_FALSE, what != SPA_CONFIG_UPDATE_POOL);
+
+	if (what == SPA_CONFIG_UPDATE_POOL)
+		spa_config_update(spa, SPA_CONFIG_UPDATE_VDEVS);
+}
+
+#if defined(_KERNEL) && defined(HAVE_SPL)
+EXPORT_SYMBOL(spa_config_sync);
+EXPORT_SYMBOL(spa_config_load);
+EXPORT_SYMBOL(spa_all_configs);
+EXPORT_SYMBOL(spa_config_set);
+EXPORT_SYMBOL(spa_config_generate);
+EXPORT_SYMBOL(spa_config_update);
+
+module_param(spa_config_path, charp, 0444);
+MODULE_PARM_DESC(spa_config_path, "SPA config file (/etc/zfs/zpool.cache)");
+
+module_param(zfs_autoimport_disable, int, 0644);
+MODULE_PARM_DESC(zfs_autoimport_disable, "Disable pool import at module load");
+
+#endif
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/module/zfs/spa_errlog.c
@@ -0,0 +1,417 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014 by Delphix. All rights reserved.
+ */
+
+/*
+ * Routines to manage the on-disk persistent error log.
+ *
+ * Each pool stores a log of all logical data errors seen during normal
+ * operation.  This is actually the union of two distinct logs: the last log,
+ * and the current log.  All errors seen are logged to the current log.  When a
+ * scrub completes, the current log becomes the last log, the last log is thrown
+ * out, and the current log is reinitialized.  This way, if an error is somehow
+ * corrected, a new scrub will show that that it no longer exists, and will be
+ * deleted from the log when the scrub completes.
+ *
+ * The log is stored using a ZAP object whose key is a string form of the
+ * zbookmark_phys tuple (objset, object, level, blkid), and whose contents is an
+ * optional 'objset:object' human-readable string describing the data.  When an
+ * error is first logged, this string will be empty, indicating that no name is
+ * known.  This prevents us from having to issue a potentially large amount of
+ * I/O to discover the object name during an error path.  Instead, we do the
+ * calculation when the data is requested, storing the result so future queries
+ * will be faster.
+ *
+ * This log is then shipped into an nvlist where the key is the dataset name and
+ * the value is the object name.  Userland is then responsible for uniquifying
+ * this list and displaying it to the user.
+ */
+
+#include <sys/dmu_tx.h>
+#include <sys/spa.h>
+#include <sys/spa_impl.h>
+#include <sys/zap.h>
+#include <sys/zio.h>
+
+
+/*
+ * Convert a bookmark to a string.
+ */
+static void
+bookmark_to_name(zbookmark_phys_t *zb, char *buf, size_t len)
+{
+	(void) snprintf(buf, len, "%llx:%llx:%llx:%llx",
+	    (u_longlong_t)zb->zb_objset, (u_longlong_t)zb->zb_object,
+	    (u_longlong_t)zb->zb_level, (u_longlong_t)zb->zb_blkid);
+}
+
+/*
+ * Convert a string to a bookmark
+ */
+#ifdef _KERNEL
+static void
+name_to_bookmark(char *buf, zbookmark_phys_t *zb)
+{
+	zb->zb_objset = strtonum(buf, &buf);
+	ASSERT(*buf == ':');
+	zb->zb_object = strtonum(buf + 1, &buf);
+	ASSERT(*buf == ':');
+	zb->zb_level = (int)strtonum(buf + 1, &buf);
+	ASSERT(*buf == ':');
+	zb->zb_blkid = strtonum(buf + 1, &buf);
+	ASSERT(*buf == '\0');
+}
+#endif
+
+/*
+ * Log an uncorrectable error to the persistent error log.  We add it to the
+ * spa's list of pending errors.  The changes are actually synced out to disk
+ * during spa_errlog_sync().
+ */
+void
+spa_log_error(spa_t *spa, zio_t *zio)
+{
+	zbookmark_phys_t *zb = &zio->io_logical->io_bookmark;
+	spa_error_entry_t search;
+	spa_error_entry_t *new;
+	avl_tree_t *tree;
+	avl_index_t where;
+
+	/*
+	 * If we are trying to import a pool, ignore any errors, as we won't be
+	 * writing to the pool any time soon.
+	 */
+	if (spa_load_state(spa) == SPA_LOAD_TRYIMPORT)
+		return;
+
+	mutex_enter(&spa->spa_errlist_lock);
+
+	/*
+	 * If we have had a request to rotate the log, log it to the next list
+	 * instead of the current one.
+	 */
+	if (spa->spa_scrub_active || spa->spa_scrub_finished)
+		tree = &spa->spa_errlist_scrub;
+	else
+		tree = &spa->spa_errlist_last;
+
+	search.se_bookmark = *zb;
+	if (avl_find(tree, &search, &where) != NULL) {
+		mutex_exit(&spa->spa_errlist_lock);
+		return;
+	}
+
+	new = kmem_zalloc(sizeof (spa_error_entry_t), KM_SLEEP);
+	new->se_bookmark = *zb;
+	avl_insert(tree, new, where);
+
+	mutex_exit(&spa->spa_errlist_lock);
+}
+
+/*
+ * Return the number of errors currently in the error log.  This is actually the
+ * sum of both the last log and the current log, since we don't know the union
+ * of these logs until we reach userland.
+ */
+uint64_t
+spa_get_errlog_size(spa_t *spa)
+{
+	uint64_t total = 0, count;
+
+	mutex_enter(&spa->spa_errlog_lock);
+	if (spa->spa_errlog_scrub != 0 &&
+	    zap_count(spa->spa_meta_objset, spa->spa_errlog_scrub,
+	    &count) == 0)
+		total += count;
+
+	if (spa->spa_errlog_last != 0 && !spa->spa_scrub_finished &&
+	    zap_count(spa->spa_meta_objset, spa->spa_errlog_last,
+	    &count) == 0)
+		total += count;
+	mutex_exit(&spa->spa_errlog_lock);
+
+	mutex_enter(&spa->spa_errlist_lock);
+	total += avl_numnodes(&spa->spa_errlist_last);
+	total += avl_numnodes(&spa->spa_errlist_scrub);
+	mutex_exit(&spa->spa_errlist_lock);
+
+	return (total);
+}
+
+#ifdef _KERNEL
+static int
+process_error_log(spa_t *spa, uint64_t obj, void *addr, size_t *count)
+{
+	zap_cursor_t zc;
+	zap_attribute_t za;
+	zbookmark_phys_t zb;
+
+	if (obj == 0)
+		return (0);
+
+	for (zap_cursor_init(&zc, spa->spa_meta_objset, obj);
+	    zap_cursor_retrieve(&zc, &za) == 0;
+	    zap_cursor_advance(&zc)) {
+
+		if (*count == 0) {
+			zap_cursor_fini(&zc);
+			return (SET_ERROR(ENOMEM));
+		}
+
+		name_to_bookmark(za.za_name, &zb);
+
+		if (copyout(&zb, (char *)addr +
+		    (*count - 1) * sizeof (zbookmark_phys_t),
+		    sizeof (zbookmark_phys_t)) != 0) {
+			zap_cursor_fini(&zc);
+			return (SET_ERROR(EFAULT));
+		}
+
+		*count -= 1;
+	}
+
+	zap_cursor_fini(&zc);
+
+	return (0);
+}
+
+static int
+process_error_list(avl_tree_t *list, void *addr, size_t *count)
+{
+	spa_error_entry_t *se;
+
+	for (se = avl_first(list); se != NULL; se = AVL_NEXT(list, se)) {
+
+		if (*count == 0)
+			return (SET_ERROR(ENOMEM));
+
+		if (copyout(&se->se_bookmark, (char *)addr +
+		    (*count - 1) * sizeof (zbookmark_phys_t),
+		    sizeof (zbookmark_phys_t)) != 0)
+			return (SET_ERROR(EFAULT));
+
+		*count -= 1;
+	}
+
+	return (0);
+}
+#endif
+
+/*
+ * Copy all known errors to userland as an array of bookmarks.  This is
+ * actually a union of the on-disk last log and current log, as well as any
+ * pending error requests.
+ *
+ * Because the act of reading the on-disk log could cause errors to be
+ * generated, we have two separate locks: one for the error log and one for the
+ * in-core error lists.  We only need the error list lock to log and error, so
+ * we grab the error log lock while we read the on-disk logs, and only pick up
+ * the error list lock when we are finished.
+ */
+int
+spa_get_errlog(spa_t *spa, void *uaddr, size_t *count)
+{
+	int ret = 0;
+
+#ifdef _KERNEL
+	mutex_enter(&spa->spa_errlog_lock);
+
+	ret = process_error_log(spa, spa->spa_errlog_scrub, uaddr, count);
+
+	if (!ret && !spa->spa_scrub_finished)
+		ret = process_error_log(spa, spa->spa_errlog_last, uaddr,
+		    count);
+
+	mutex_enter(&spa->spa_errlist_lock);
+	if (!ret)
+		ret = process_error_list(&spa->spa_errlist_scrub, uaddr,
+		    count);
+	if (!ret)
+		ret = process_error_list(&spa->spa_errlist_last, uaddr,
+		    count);
+	mutex_exit(&spa->spa_errlist_lock);
+
+	mutex_exit(&spa->spa_errlog_lock);
+#endif
+
+	return (ret);
+}
+
+/*
+ * Called when a scrub completes.  This simply set a bit which tells which AVL
+ * tree to add new errors.  spa_errlog_sync() is responsible for actually
+ * syncing the changes to the underlying objects.
+ */
+void
+spa_errlog_rotate(spa_t *spa)
+{
+	mutex_enter(&spa->spa_errlist_lock);
+	spa->spa_scrub_finished = B_TRUE;
+	mutex_exit(&spa->spa_errlist_lock);
+}
+
+/*
+ * Discard any pending errors from the spa_t.  Called when unloading a faulted
+ * pool, as the errors encountered during the open cannot be synced to disk.
+ */
+void
+spa_errlog_drain(spa_t *spa)
+{
+	spa_error_entry_t *se;
+	void *cookie;
+
+	mutex_enter(&spa->spa_errlist_lock);
+
+	cookie = NULL;
+	while ((se = avl_destroy_nodes(&spa->spa_errlist_last,
+	    &cookie)) != NULL)
+		kmem_free(se, sizeof (spa_error_entry_t));
+	cookie = NULL;
+	while ((se = avl_destroy_nodes(&spa->spa_errlist_scrub,
+	    &cookie)) != NULL)
+		kmem_free(se, sizeof (spa_error_entry_t));
+
+	mutex_exit(&spa->spa_errlist_lock);
+}
+
+/*
+ * Process a list of errors into the current on-disk log.
+ */
+static void
+sync_error_list(spa_t *spa, avl_tree_t *t, uint64_t *obj, dmu_tx_t *tx)
+{
+	spa_error_entry_t *se;
+	char buf[64];
+	void *cookie;
+
+	if (avl_numnodes(t) != 0) {
+		/* create log if necessary */
+		if (*obj == 0)
+			*obj = zap_create(spa->spa_meta_objset,
+			    DMU_OT_ERROR_LOG, DMU_OT_NONE,
+			    0, tx);
+
+		/* add errors to the current log */
+		for (se = avl_first(t); se != NULL; se = AVL_NEXT(t, se)) {
+			char *name = se->se_name ? se->se_name : "";
+
+			bookmark_to_name(&se->se_bookmark, buf, sizeof (buf));
+
+			(void) zap_update(spa->spa_meta_objset,
+			    *obj, buf, 1, strlen(name) + 1, name, tx);
+		}
+
+		/* purge the error list */
+		cookie = NULL;
+		while ((se = avl_destroy_nodes(t, &cookie)) != NULL)
+			kmem_free(se, sizeof (spa_error_entry_t));
+	}
+}
+
+/*
+ * Sync the error log out to disk.  This is a little tricky because the act of
+ * writing the error log requires the spa_errlist_lock.  So, we need to lock the
+ * error lists, take a copy of the lists, and then reinitialize them.  Then, we
+ * drop the error list lock and take the error log lock, at which point we
+ * do the errlog processing.  Then, if we encounter an I/O error during this
+ * process, we can successfully add the error to the list.  Note that this will
+ * result in the perpetual recycling of errors, but it is an unlikely situation
+ * and not a performance critical operation.
+ */
+void
+spa_errlog_sync(spa_t *spa, uint64_t txg)
+{
+	dmu_tx_t *tx;
+	avl_tree_t scrub, last;
+	int scrub_finished;
+
+	mutex_enter(&spa->spa_errlist_lock);
+
+	/*
+	 * Bail out early under normal circumstances.
+	 */
+	if (avl_numnodes(&spa->spa_errlist_scrub) == 0 &&
+	    avl_numnodes(&spa->spa_errlist_last) == 0 &&
+	    !spa->spa_scrub_finished) {
+		mutex_exit(&spa->spa_errlist_lock);
+		return;
+	}
+
+	spa_get_errlists(spa, &last, &scrub);
+	scrub_finished = spa->spa_scrub_finished;
+	spa->spa_scrub_finished = B_FALSE;
+
+	mutex_exit(&spa->spa_errlist_lock);
+	mutex_enter(&spa->spa_errlog_lock);
+
+	tx = dmu_tx_create_assigned(spa->spa_dsl_pool, txg);
+
+	/*
+	 * Sync out the current list of errors.
+	 */
+	sync_error_list(spa, &last, &spa->spa_errlog_last, tx);
+
+	/*
+	 * Rotate the log if necessary.
+	 */
+	if (scrub_finished) {
+		if (spa->spa_errlog_last != 0)
+			VERIFY(dmu_object_free(spa->spa_meta_objset,
+			    spa->spa_errlog_last, tx) == 0);
+		spa->spa_errlog_last = spa->spa_errlog_scrub;
+		spa->spa_errlog_scrub = 0;
+
+		sync_error_list(spa, &scrub, &spa->spa_errlog_last, tx);
+	}
+
+	/*
+	 * Sync out any pending scrub errors.
+	 */
+	sync_error_list(spa, &scrub, &spa->spa_errlog_scrub, tx);
+
+	/*
+	 * Update the MOS to reflect the new values.
+	 */
+	(void) zap_update(spa->spa_meta_objset, DMU_POOL_DIRECTORY_OBJECT,
+	    DMU_POOL_ERRLOG_LAST, sizeof (uint64_t), 1,
+	    &spa->spa_errlog_last, tx);
+	(void) zap_update(spa->spa_meta_objset, DMU_POOL_DIRECTORY_OBJECT,
+	    DMU_POOL_ERRLOG_SCRUB, sizeof (uint64_t), 1,
+	    &spa->spa_errlog_scrub, tx);
+
+	dmu_tx_commit(tx);
+
+	mutex_exit(&spa->spa_errlog_lock);
+}
+
+#if defined(_KERNEL) && defined(HAVE_SPL)
+/* error handling */
+EXPORT_SYMBOL(spa_log_error);
+EXPORT_SYMBOL(spa_get_errlog_size);
+EXPORT_SYMBOL(spa_get_errlog);
+EXPORT_SYMBOL(spa_errlog_rotate);
+EXPORT_SYMBOL(spa_errlog_drain);
+EXPORT_SYMBOL(spa_errlog_sync);
+EXPORT_SYMBOL(spa_get_errlists);
+#endif
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/module/zfs/spa_history.c
@@ -0,0 +1,547 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2014 by Delphix. All rights reserved.
+ */
+
+#include <sys/spa.h>
+#include <sys/spa_impl.h>
+#include <sys/zap.h>
+#include <sys/dsl_synctask.h>
+#include <sys/dmu_tx.h>
+#include <sys/dmu_objset.h>
+#include <sys/dsl_dataset.h>
+#include <sys/dsl_dir.h>
+#include <sys/cmn_err.h>
+#include <sys/sunddi.h>
+#include <sys/cred.h>
+#include "zfs_comutil.h"
+#ifdef _KERNEL
+#include <sys/zone.h>
+#endif
+
+/*
+ * Routines to manage the on-disk history log.
+ *
+ * The history log is stored as a dmu object containing
+ * <packed record length, record nvlist> tuples.
+ *
+ * Where "record nvlist" is a nvlist containing uint64_ts and strings, and
+ * "packed record length" is the packed length of the "record nvlist" stored
+ * as a little endian uint64_t.
+ *
+ * The log is implemented as a ring buffer, though the original creation
+ * of the pool ('zpool create') is never overwritten.
+ *
+ * The history log is tracked as object 'spa_t::spa_history'.  The bonus buffer
+ * of 'spa_history' stores the offsets for logging/retrieving history as
+ * 'spa_history_phys_t'.  'sh_pool_create_len' is the ending offset in bytes of
+ * where the 'zpool create' record is stored.  This allows us to never
+ * overwrite the original creation of the pool.  'sh_phys_max_off' is the
+ * physical ending offset in bytes of the log.  This tells you the length of
+ * the buffer. 'sh_eof' is the logical EOF (in bytes).  Whenever a record
+ * is added, 'sh_eof' is incremented by the the size of the record.
+ * 'sh_eof' is never decremented.  'sh_bof' is the logical BOF (in bytes).
+ * This is where the consumer should start reading from after reading in
+ * the 'zpool create' portion of the log.
+ *
+ * 'sh_records_lost' keeps track of how many records have been overwritten
+ * and permanently lost.
+ */
+
+/* convert a logical offset to physical */
+static uint64_t
+spa_history_log_to_phys(uint64_t log_off, spa_history_phys_t *shpp)
+{
+	uint64_t phys_len;
+
+	phys_len = shpp->sh_phys_max_off - shpp->sh_pool_create_len;
+	return ((log_off - shpp->sh_pool_create_len) % phys_len
+	    + shpp->sh_pool_create_len);
+}
+
+void
+spa_history_create_obj(spa_t *spa, dmu_tx_t *tx)
+{
+	dmu_buf_t *dbp;
+	spa_history_phys_t *shpp;
+	objset_t *mos = spa->spa_meta_objset;
+
+	ASSERT(spa->spa_history == 0);
+	spa->spa_history = dmu_object_alloc(mos, DMU_OT_SPA_HISTORY,
+	    SPA_OLD_MAXBLOCKSIZE, DMU_OT_SPA_HISTORY_OFFSETS,
+	    sizeof (spa_history_phys_t), tx);
+
+	VERIFY(zap_add(mos, DMU_POOL_DIRECTORY_OBJECT,
+	    DMU_POOL_HISTORY, sizeof (uint64_t), 1,
+	    &spa->spa_history, tx) == 0);
+
+	VERIFY(0 == dmu_bonus_hold(mos, spa->spa_history, FTAG, &dbp));
+	ASSERT(dbp->db_size >= sizeof (spa_history_phys_t));
+
+	shpp = dbp->db_data;
+	dmu_buf_will_dirty(dbp, tx);
+
+	/*
+	 * Figure out maximum size of history log.  We set it at
+	 * 0.1% of pool size, with a max of 1G and min of 128KB.
+	 */
+	shpp->sh_phys_max_off =
+	    metaslab_class_get_dspace(spa_normal_class(spa)) / 1000;
+	shpp->sh_phys_max_off = MIN(shpp->sh_phys_max_off, 1<<30);
+	shpp->sh_phys_max_off = MAX(shpp->sh_phys_max_off, 128<<10);
+
+	dmu_buf_rele(dbp, FTAG);
+}
+
+/*
+ * Change 'sh_bof' to the beginning of the next record.
+ */
+static int
+spa_history_advance_bof(spa_t *spa, spa_history_phys_t *shpp)
+{
+	objset_t *mos = spa->spa_meta_objset;
+	uint64_t firstread, reclen, phys_bof;
+	char buf[sizeof (reclen)];
+	int err;
+
+	phys_bof = spa_history_log_to_phys(shpp->sh_bof, shpp);
+	firstread = MIN(sizeof (reclen), shpp->sh_phys_max_off - phys_bof);
+
+	if ((err = dmu_read(mos, spa->spa_history, phys_bof, firstread,
+	    buf, DMU_READ_PREFETCH)) != 0)
+		return (err);
+	if (firstread != sizeof (reclen)) {
+		if ((err = dmu_read(mos, spa->spa_history,
+		    shpp->sh_pool_create_len, sizeof (reclen) - firstread,
+		    buf + firstread, DMU_READ_PREFETCH)) != 0)
+			return (err);
+	}
+
+	reclen = LE_64(*((uint64_t *)buf));
+	shpp->sh_bof += reclen + sizeof (reclen);
+	shpp->sh_records_lost++;
+	return (0);
+}
+
+static int
+spa_history_write(spa_t *spa, void *buf, uint64_t len, spa_history_phys_t *shpp,
+    dmu_tx_t *tx)
+{
+	uint64_t firstwrite, phys_eof;
+	objset_t *mos = spa->spa_meta_objset;
+	int err;
+
+	ASSERT(MUTEX_HELD(&spa->spa_history_lock));
+
+	/* see if we need to reset logical BOF */
+	while (shpp->sh_phys_max_off - shpp->sh_pool_create_len -
+	    (shpp->sh_eof - shpp->sh_bof) <= len) {
+		if ((err = spa_history_advance_bof(spa, shpp)) != 0) {
+			return (err);
+		}
+	}
+
+	phys_eof = spa_history_log_to_phys(shpp->sh_eof, shpp);
+	firstwrite = MIN(len, shpp->sh_phys_max_off - phys_eof);
+	shpp->sh_eof += len;
+	dmu_write(mos, spa->spa_history, phys_eof, firstwrite, buf, tx);
+
+	len -= firstwrite;
+	if (len > 0) {
+		/* write out the rest at the beginning of physical file */
+		dmu_write(mos, spa->spa_history, shpp->sh_pool_create_len,
+		    len, (char *)buf + firstwrite, tx);
+	}
+
+	return (0);
+}
+
+static char *
+spa_history_zone(void)
+{
+#ifdef _KERNEL
+#ifdef HAVE_SPL
+	return ("linux");
+#else
+	return (curproc->p_zone->zone_name);
+#endif
+#else
+	return (NULL);
+#endif
+}
+
+/*
+ * Write out a history event.
+ */
+/*ARGSUSED*/
+static void
+spa_history_log_sync(void *arg, dmu_tx_t *tx)
+{
+	nvlist_t	*nvl = arg;
+	spa_t		*spa = dmu_tx_pool(tx)->dp_spa;
+	objset_t	*mos = spa->spa_meta_objset;
+	dmu_buf_t	*dbp;
+	spa_history_phys_t *shpp;
+	size_t		reclen;
+	uint64_t	le_len;
+	char		*record_packed = NULL;
+	int		ret;
+
+	/*
+	 * If we have an older pool that doesn't have a command
+	 * history object, create it now.
+	 */
+	mutex_enter(&spa->spa_history_lock);
+	if (!spa->spa_history)
+		spa_history_create_obj(spa, tx);
+	mutex_exit(&spa->spa_history_lock);
+
+	/*
+	 * Get the offset of where we need to write via the bonus buffer.
+	 * Update the offset when the write completes.
+	 */
+	VERIFY0(dmu_bonus_hold(mos, spa->spa_history, FTAG, &dbp));
+	shpp = dbp->db_data;
+
+	dmu_buf_will_dirty(dbp, tx);
+
+#ifdef ZFS_DEBUG
+	{
+		dmu_object_info_t doi;
+		dmu_object_info_from_db(dbp, &doi);
+		ASSERT3U(doi.doi_bonus_type, ==, DMU_OT_SPA_HISTORY_OFFSETS);
+	}
+#endif
+
+	fnvlist_add_uint64(nvl, ZPOOL_HIST_TIME, gethrestime_sec());
+	fnvlist_add_string(nvl, ZPOOL_HIST_HOST, utsname()->nodename);
+
+	if (nvlist_exists(nvl, ZPOOL_HIST_CMD)) {
+		zfs_dbgmsg("command: %s",
+		    fnvlist_lookup_string(nvl, ZPOOL_HIST_CMD));
+	} else if (nvlist_exists(nvl, ZPOOL_HIST_INT_NAME)) {
+		if (nvlist_exists(nvl, ZPOOL_HIST_DSNAME)) {
+			zfs_dbgmsg("txg %lld %s %s (id %llu) %s",
+			    fnvlist_lookup_uint64(nvl, ZPOOL_HIST_TXG),
+			    fnvlist_lookup_string(nvl, ZPOOL_HIST_INT_NAME),
+			    fnvlist_lookup_string(nvl, ZPOOL_HIST_DSNAME),
+			    fnvlist_lookup_uint64(nvl, ZPOOL_HIST_DSID),
+			    fnvlist_lookup_string(nvl, ZPOOL_HIST_INT_STR));
+		} else {
+			zfs_dbgmsg("txg %lld %s %s",
+			    fnvlist_lookup_uint64(nvl, ZPOOL_HIST_TXG),
+			    fnvlist_lookup_string(nvl, ZPOOL_HIST_INT_NAME),
+			    fnvlist_lookup_string(nvl, ZPOOL_HIST_INT_STR));
+		}
+	} else if (nvlist_exists(nvl, ZPOOL_HIST_IOCTL)) {
+		zfs_dbgmsg("ioctl %s",
+		    fnvlist_lookup_string(nvl, ZPOOL_HIST_IOCTL));
+	}
+
+	VERIFY3U(nvlist_pack(nvl, &record_packed, &reclen, NV_ENCODE_NATIVE,
+	    KM_SLEEP), ==, 0);
+
+	mutex_enter(&spa->spa_history_lock);
+
+	/* write out the packed length as little endian */
+	le_len = LE_64((uint64_t)reclen);
+	ret = spa_history_write(spa, &le_len, sizeof (le_len), shpp, tx);
+	if (!ret)
+		ret = spa_history_write(spa, record_packed, reclen, shpp, tx);
+
+	/* The first command is the create, which we keep forever */
+	if (ret == 0 && shpp->sh_pool_create_len == 0 &&
+	    nvlist_exists(nvl, ZPOOL_HIST_CMD)) {
+		shpp->sh_pool_create_len = shpp->sh_bof = shpp->sh_eof;
+	}
+
+	mutex_exit(&spa->spa_history_lock);
+	fnvlist_pack_free(record_packed, reclen);
+	dmu_buf_rele(dbp, FTAG);
+	fnvlist_free(nvl);
+}
+
+/*
+ * Write out a history event.
+ */
+int
+spa_history_log(spa_t *spa, const char *msg)
+{
+	int err;
+	nvlist_t *nvl = fnvlist_alloc();
+
+	fnvlist_add_string(nvl, ZPOOL_HIST_CMD, msg);
+	err = spa_history_log_nvl(spa, nvl);
+	fnvlist_free(nvl);
+	return (err);
+}
+
+int
+spa_history_log_nvl(spa_t *spa, nvlist_t *nvl)
+{
+	int err = 0;
+	dmu_tx_t *tx;
+	nvlist_t *nvarg;
+
+	if (spa_version(spa) < SPA_VERSION_ZPOOL_HISTORY || !spa_writeable(spa))
+		return (SET_ERROR(EINVAL));
+
+	tx = dmu_tx_create_dd(spa_get_dsl(spa)->dp_mos_dir);
+	err = dmu_tx_assign(tx, TXG_WAIT);
+	if (err) {
+		dmu_tx_abort(tx);
+		return (err);
+	}
+
+	VERIFY0(nvlist_dup(nvl, &nvarg, KM_SLEEP));
+	if (spa_history_zone() != NULL) {
+		fnvlist_add_string(nvarg, ZPOOL_HIST_ZONE,
+		    spa_history_zone());
+	}
+	fnvlist_add_uint64(nvarg, ZPOOL_HIST_WHO, crgetruid(CRED()));
+
+	/* Kick this off asynchronously; errors are ignored. */
+	dsl_sync_task_nowait(spa_get_dsl(spa), spa_history_log_sync,
+	    nvarg, 0, ZFS_SPACE_CHECK_NONE, tx);
+	dmu_tx_commit(tx);
+
+	/* spa_history_log_sync will free nvl */
+	return (err);
+
+}
+
+/*
+ * Read out the command history.
+ */
+int
+spa_history_get(spa_t *spa, uint64_t *offp, uint64_t *len, char *buf)
+{
+	objset_t *mos = spa->spa_meta_objset;
+	dmu_buf_t *dbp;
+	uint64_t read_len, phys_read_off, phys_eof;
+	uint64_t leftover = 0;
+	spa_history_phys_t *shpp;
+	int err;
+
+	/*
+	 * If the command history doesn't exist (older pool),
+	 * that's ok, just return ENOENT.
+	 */
+	if (!spa->spa_history)
+		return (SET_ERROR(ENOENT));
+
+	/*
+	 * The history is logged asynchronously, so when they request
+	 * the first chunk of history, make sure everything has been
+	 * synced to disk so that we get it.
+	 */
+	if (*offp == 0 && spa_writeable(spa))
+		txg_wait_synced(spa_get_dsl(spa), 0);
+
+	if ((err = dmu_bonus_hold(mos, spa->spa_history, FTAG, &dbp)) != 0)
+		return (err);
+	shpp = dbp->db_data;
+
+#ifdef ZFS_DEBUG
+	{
+		dmu_object_info_t doi;
+		dmu_object_info_from_db(dbp, &doi);
+		ASSERT3U(doi.doi_bonus_type, ==, DMU_OT_SPA_HISTORY_OFFSETS);
+	}
+#endif
+
+	mutex_enter(&spa->spa_history_lock);
+	phys_eof = spa_history_log_to_phys(shpp->sh_eof, shpp);
+
+	if (*offp < shpp->sh_pool_create_len) {
+		/* read in just the zpool create history */
+		phys_read_off = *offp;
+		read_len = MIN(*len, shpp->sh_pool_create_len -
+		    phys_read_off);
+	} else {
+		/*
+		 * Need to reset passed in offset to BOF if the passed in
+		 * offset has since been overwritten.
+		 */
+		*offp = MAX(*offp, shpp->sh_bof);
+		phys_read_off = spa_history_log_to_phys(*offp, shpp);
+
+		/*
+		 * Read up to the minimum of what the user passed down or
+		 * the EOF (physical or logical).  If we hit physical EOF,
+		 * use 'leftover' to read from the physical BOF.
+		 */
+		if (phys_read_off <= phys_eof) {
+			read_len = MIN(*len, phys_eof - phys_read_off);
+		} else {
+			read_len = MIN(*len,
+			    shpp->sh_phys_max_off - phys_read_off);
+			if (phys_read_off + *len > shpp->sh_phys_max_off) {
+				leftover = MIN(*len - read_len,
+				    phys_eof - shpp->sh_pool_create_len);
+			}
+		}
+	}
+
+	/* offset for consumer to use next */
+	*offp += read_len + leftover;
+
+	/* tell the consumer how much you actually read */
+	*len = read_len + leftover;
+
+	if (read_len == 0) {
+		mutex_exit(&spa->spa_history_lock);
+		dmu_buf_rele(dbp, FTAG);
+		return (0);
+	}
+
+	err = dmu_read(mos, spa->spa_history, phys_read_off, read_len, buf,
+	    DMU_READ_PREFETCH);
+	if (leftover && err == 0) {
+		err = dmu_read(mos, spa->spa_history, shpp->sh_pool_create_len,
+		    leftover, buf + read_len, DMU_READ_PREFETCH);
+	}
+	mutex_exit(&spa->spa_history_lock);
+
+	dmu_buf_rele(dbp, FTAG);
+	return (err);
+}
+
+/*
+ * The nvlist will be consumed by this call.
+ */
+static void
+log_internal(nvlist_t *nvl, const char *operation, spa_t *spa,
+    dmu_tx_t *tx, const char *fmt, va_list adx)
+{
+	char *msg;
+
+	/*
+	 * If this is part of creating a pool, not everything is
+	 * initialized yet, so don't bother logging the internal events.
+	 * Likewise if the pool is not writeable.
+	 */
+	if (tx->tx_txg == TXG_INITIAL || !spa_writeable(spa)) {
+		fnvlist_free(nvl);
+		return;
+	}
+
+	msg = kmem_vasprintf(fmt, adx);
+	fnvlist_add_string(nvl, ZPOOL_HIST_INT_STR, msg);
+	strfree(msg);
+
+	fnvlist_add_string(nvl, ZPOOL_HIST_INT_NAME, operation);
+	fnvlist_add_uint64(nvl, ZPOOL_HIST_TXG, tx->tx_txg);
+
+	if (dmu_tx_is_syncing(tx)) {
+		spa_history_log_sync(nvl, tx);
+	} else {
+		dsl_sync_task_nowait(spa_get_dsl(spa),
+		    spa_history_log_sync, nvl, 0, ZFS_SPACE_CHECK_NONE, tx);
+	}
+	/* spa_history_log_sync() will free nvl */
+}
+
+void
+spa_history_log_internal(spa_t *spa, const char *operation,
+    dmu_tx_t *tx, const char *fmt, ...)
+{
+	dmu_tx_t *htx = tx;
+	va_list adx;
+
+	/* create a tx if we didn't get one */
+	if (tx == NULL) {
+		htx = dmu_tx_create_dd(spa_get_dsl(spa)->dp_mos_dir);
+		if (dmu_tx_assign(htx, TXG_WAIT) != 0) {
+			dmu_tx_abort(htx);
+			return;
+		}
+	}
+
+	va_start(adx, fmt);
+	log_internal(fnvlist_alloc(), operation, spa, htx, fmt, adx);
+	va_end(adx);
+
+	/* if we didn't get a tx from the caller, commit the one we made */
+	if (tx == NULL)
+		dmu_tx_commit(htx);
+}
+
+void
+spa_history_log_internal_ds(dsl_dataset_t *ds, const char *operation,
+    dmu_tx_t *tx, const char *fmt, ...)
+{
+	va_list adx;
+	char namebuf[MAXNAMELEN];
+	nvlist_t *nvl = fnvlist_alloc();
+
+	ASSERT(tx != NULL);
+
+	dsl_dataset_name(ds, namebuf);
+	fnvlist_add_string(nvl, ZPOOL_HIST_DSNAME, namebuf);
+	fnvlist_add_uint64(nvl, ZPOOL_HIST_DSID, ds->ds_object);
+
+	va_start(adx, fmt);
+	log_internal(nvl, operation, dsl_dataset_get_spa(ds), tx, fmt, adx);
+	va_end(adx);
+}
+
+void
+spa_history_log_internal_dd(dsl_dir_t *dd, const char *operation,
+    dmu_tx_t *tx, const char *fmt, ...)
+{
+	va_list adx;
+	char namebuf[MAXNAMELEN];
+	nvlist_t *nvl = fnvlist_alloc();
+
+	ASSERT(tx != NULL);
+
+	dsl_dir_name(dd, namebuf);
+	fnvlist_add_string(nvl, ZPOOL_HIST_DSNAME, namebuf);
+	fnvlist_add_uint64(nvl, ZPOOL_HIST_DSID,
+	    dsl_dir_phys(dd)->dd_head_dataset_obj);
+
+	va_start(adx, fmt);
+	log_internal(nvl, operation, dd->dd_pool->dp_spa, tx, fmt, adx);
+	va_end(adx);
+}
+
+void
+spa_history_log_version(spa_t *spa, const char *operation)
+{
+	utsname_t *u = utsname();
+
+	spa_history_log_internal(spa, operation, NULL,
+	    "pool version %llu; software version %llu/%d; uts %s %s %s %s",
+	    (u_longlong_t)spa_version(spa), SPA_VERSION, ZPL_VERSION,
+	    u->nodename, u->release, u->version, u->machine);
+}
+
+#if defined(_KERNEL) && defined(HAVE_SPL)
+EXPORT_SYMBOL(spa_history_create_obj);
+EXPORT_SYMBOL(spa_history_get);
+EXPORT_SYMBOL(spa_history_log);
+EXPORT_SYMBOL(spa_history_log_internal);
+EXPORT_SYMBOL(spa_history_log_version);
+#endif
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/module/zfs/spa_misc.c
@@ -0,0 +1,2100 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2015 by Delphix. All rights reserved.
+ * Copyright 2011 Nexenta Systems, Inc.  All rights reserved.
+ * Copyright (c) 2014 Spectra Logic Corporation, All rights reserved.
+ */
+
+#include <sys/zfs_context.h>
+#include <sys/spa_impl.h>
+#include <sys/zio.h>
+#include <sys/zio_checksum.h>
+#include <sys/zio_compress.h>
+#include <sys/dmu.h>
+#include <sys/dmu_tx.h>
+#include <sys/zap.h>
+#include <sys/zil.h>
+#include <sys/vdev_impl.h>
+#include <sys/vdev_file.h>
+#include <sys/metaslab.h>
+#include <sys/uberblock_impl.h>
+#include <sys/txg.h>
+#include <sys/avl.h>
+#include <sys/unique.h>
+#include <sys/dsl_pool.h>
+#include <sys/dsl_dir.h>
+#include <sys/dsl_prop.h>
+#include <sys/fm/util.h>
+#include <sys/dsl_scan.h>
+#include <sys/fs/zfs.h>
+#include <sys/metaslab_impl.h>
+#include <sys/arc.h>
+#include <sys/ddt.h>
+#include <sys/kstat.h>
+#include "zfs_prop.h"
+#include "zfeature_common.h"
+
+/*
+ * SPA locking
+ *
+ * There are four basic locks for managing spa_t structures:
+ *
+ * spa_namespace_lock (global mutex)
+ *
+ *	This lock must be acquired to do any of the following:
+ *
+ *		- Lookup a spa_t by name
+ *		- Add or remove a spa_t from the namespace
+ *		- Increase spa_refcount from non-zero
+ *		- Check if spa_refcount is zero
+ *		- Rename a spa_t
+ *		- add/remove/attach/detach devices
+ *		- Held for the duration of create/destroy/import/export
+ *
+ *	It does not need to handle recursion.  A create or destroy may
+ *	reference objects (files or zvols) in other pools, but by
+ *	definition they must have an existing reference, and will never need
+ *	to lookup a spa_t by name.
+ *
+ * spa_refcount (per-spa refcount_t protected by mutex)
+ *
+ *	This reference count keep track of any active users of the spa_t.  The
+ *	spa_t cannot be destroyed or freed while this is non-zero.  Internally,
+ *	the refcount is never really 'zero' - opening a pool implicitly keeps
+ *	some references in the DMU.  Internally we check against spa_minref, but
+ *	present the image of a zero/non-zero value to consumers.
+ *
+ * spa_config_lock[] (per-spa array of rwlocks)
+ *
+ *	This protects the spa_t from config changes, and must be held in
+ *	the following circumstances:
+ *
+ *		- RW_READER to perform I/O to the spa
+ *		- RW_WRITER to change the vdev config
+ *
+ * The locking order is fairly straightforward:
+ *
+ *		spa_namespace_lock	->	spa_refcount
+ *
+ *	The namespace lock must be acquired to increase the refcount from 0
+ *	or to check if it is zero.
+ *
+ *		spa_refcount		->	spa_config_lock[]
+ *
+ *	There must be at least one valid reference on the spa_t to acquire
+ *	the config lock.
+ *
+ *		spa_namespace_lock	->	spa_config_lock[]
+ *
+ *	The namespace lock must always be taken before the config lock.
+ *
+ *
+ * The spa_namespace_lock can be acquired directly and is globally visible.
+ *
+ * The namespace is manipulated using the following functions, all of which
+ * require the spa_namespace_lock to be held.
+ *
+ *	spa_lookup()		Lookup a spa_t by name.
+ *
+ *	spa_add()		Create a new spa_t in the namespace.
+ *
+ *	spa_remove()		Remove a spa_t from the namespace.  This also
+ *				frees up any memory associated with the spa_t.
+ *
+ *	spa_next()		Returns the next spa_t in the system, or the
+ *				first if NULL is passed.
+ *
+ *	spa_evict_all()		Shutdown and remove all spa_t structures in
+ *				the system.
+ *
+ *	spa_guid_exists()	Determine whether a pool/device guid exists.
+ *
+ * The spa_refcount is manipulated using the following functions:
+ *
+ *	spa_open_ref()		Adds a reference to the given spa_t.  Must be
+ *				called with spa_namespace_lock held if the
+ *				refcount is currently zero.
+ *
+ *	spa_close()		Remove a reference from the spa_t.  This will
+ *				not free the spa_t or remove it from the
+ *				namespace.  No locking is required.
+ *
+ *	spa_refcount_zero()	Returns true if the refcount is currently
+ *				zero.  Must be called with spa_namespace_lock
+ *				held.
+ *
+ * The spa_config_lock[] is an array of rwlocks, ordered as follows:
+ * SCL_CONFIG > SCL_STATE > SCL_ALLOC > SCL_ZIO > SCL_FREE > SCL_VDEV.
+ * spa_config_lock[] is manipulated with spa_config_{enter,exit,held}().
+ *
+ * To read the configuration, it suffices to hold one of these locks as reader.
+ * To modify the configuration, you must hold all locks as writer.  To modify
+ * vdev state without altering the vdev tree's topology (e.g. online/offline),
+ * you must hold SCL_STATE and SCL_ZIO as writer.
+ *
+ * We use these distinct config locks to avoid recursive lock entry.
+ * For example, spa_sync() (which holds SCL_CONFIG as reader) induces
+ * block allocations (SCL_ALLOC), which may require reading space maps
+ * from disk (dmu_read() -> zio_read() -> SCL_ZIO).
+ *
+ * The spa config locks cannot be normal rwlocks because we need the
+ * ability to hand off ownership.  For example, SCL_ZIO is acquired
+ * by the issuing thread and later released by an interrupt thread.
+ * They do, however, obey the usual write-wanted semantics to prevent
+ * writer (i.e. system administrator) starvation.
+ *
+ * The lock acquisition rules are as follows:
+ *
+ * SCL_CONFIG
+ *	Protects changes to the vdev tree topology, such as vdev
+ *	add/remove/attach/detach.  Protects the dirty config list
+ *	(spa_config_dirty_list) and the set of spares and l2arc devices.
+ *
+ * SCL_STATE
+ *	Protects changes to pool state and vdev state, such as vdev
+ *	online/offline/fault/degrade/clear.  Protects the dirty state list
+ *	(spa_state_dirty_list) and global pool state (spa_state).
+ *
+ * SCL_ALLOC
+ *	Protects changes to metaslab groups and classes.
+ *	Held as reader by metaslab_alloc() and metaslab_claim().
+ *
+ * SCL_ZIO
+ *	Held by bp-level zios (those which have no io_vd upon entry)
+ *	to prevent changes to the vdev tree.  The bp-level zio implicitly
+ *	protects all of its vdev child zios, which do not hold SCL_ZIO.
+ *
+ * SCL_FREE
+ *	Protects changes to metaslab groups and classes.
+ *	Held as reader by metaslab_free().  SCL_FREE is distinct from
+ *	SCL_ALLOC, and lower than SCL_ZIO, so that we can safely free
+ *	blocks in zio_done() while another i/o that holds either
+ *	SCL_ALLOC or SCL_ZIO is waiting for this i/o to complete.
+ *
+ * SCL_VDEV
+ *	Held as reader to prevent changes to the vdev tree during trivial
+ *	inquiries such as bp_get_dsize().  SCL_VDEV is distinct from the
+ *	other locks, and lower than all of them, to ensure that it's safe
+ *	to acquire regardless of caller context.
+ *
+ * In addition, the following rules apply:
+ *
+ * (a)	spa_props_lock protects pool properties, spa_config and spa_config_list.
+ *	The lock ordering is SCL_CONFIG > spa_props_lock.
+ *
+ * (b)	I/O operations on leaf vdevs.  For any zio operation that takes
+ *	an explicit vdev_t argument -- such as zio_ioctl(), zio_read_phys(),
+ *	or zio_write_phys() -- the caller must ensure that the config cannot
+ *	cannot change in the interim, and that the vdev cannot be reopened.
+ *	SCL_STATE as reader suffices for both.
+ *
+ * The vdev configuration is protected by spa_vdev_enter() / spa_vdev_exit().
+ *
+ *	spa_vdev_enter()	Acquire the namespace lock and the config lock
+ *				for writing.
+ *
+ *	spa_vdev_exit()		Release the config lock, wait for all I/O
+ *				to complete, sync the updated configs to the
+ *				cache, and release the namespace lock.
+ *
+ * vdev state is protected by spa_vdev_state_enter() / spa_vdev_state_exit().
+ * Like spa_vdev_enter/exit, these are convenience wrappers -- the actual
+ * locking is, always, based on spa_namespace_lock and spa_config_lock[].
+ *
+ * spa_rename() is also implemented within this file since it requires
+ * manipulation of the namespace.
+ */
+
+static avl_tree_t spa_namespace_avl;
+kmutex_t spa_namespace_lock;
+static kcondvar_t spa_namespace_cv;
+int spa_max_replication_override = SPA_DVAS_PER_BP;
+
+static kmutex_t spa_spare_lock;
+static avl_tree_t spa_spare_avl;
+static kmutex_t spa_l2cache_lock;
+static avl_tree_t spa_l2cache_avl;
+
+kmem_cache_t *spa_buffer_pool;
+int spa_mode_global;
+
+#ifdef ZFS_DEBUG
+/* Everything except dprintf and spa is on by default in debug builds */
+int zfs_flags = ~(ZFS_DEBUG_DPRINTF | ZFS_DEBUG_SPA);
+#else
+int zfs_flags = 0;
+#endif
+
+/*
+ * zfs_recover can be set to nonzero to attempt to recover from
+ * otherwise-fatal errors, typically caused by on-disk corruption.  When
+ * set, calls to zfs_panic_recover() will turn into warning messages.
+ * This should only be used as a last resort, as it typically results
+ * in leaked space, or worse.
+ */
+int zfs_recover = B_FALSE;
+
+/*
+ * If destroy encounters an EIO while reading metadata (e.g. indirect
+ * blocks), space referenced by the missing metadata can not be freed.
+ * Normally this causes the background destroy to become "stalled", as
+ * it is unable to make forward progress.  While in this stalled state,
+ * all remaining space to free from the error-encountering filesystem is
+ * "temporarily leaked".  Set this flag to cause it to ignore the EIO,
+ * permanently leak the space from indirect blocks that can not be read,
+ * and continue to free everything else that it can.
+ *
+ * The default, "stalling" behavior is useful if the storage partially
+ * fails (i.e. some but not all i/os fail), and then later recovers.  In
+ * this case, we will be able to continue pool operations while it is
+ * partially failed, and when it recovers, we can continue to free the
+ * space, with no leaks.  However, note that this case is actually
+ * fairly rare.
+ *
+ * Typically pools either (a) fail completely (but perhaps temporarily,
+ * e.g. a top-level vdev going offline), or (b) have localized,
+ * permanent errors (e.g. disk returns the wrong data due to bit flip or
+ * firmware bug).  In case (a), this setting does not matter because the
+ * pool will be suspended and the sync thread will not be able to make
+ * forward progress regardless.  In case (b), because the error is
+ * permanent, the best we can do is leak the minimum amount of space,
+ * which is what setting this flag will do.  Therefore, it is reasonable
+ * for this flag to normally be set, but we chose the more conservative
+ * approach of not setting it, so that there is no possibility of
+ * leaking space in the "partial temporary" failure case.
+ */
+int zfs_free_leak_on_eio = B_FALSE;
+
+/*
+ * Expiration time in milliseconds. This value has two meanings. First it is
+ * used to determine when the spa_deadman() logic should fire. By default the
+ * spa_deadman() will fire if spa_sync() has not completed in 1000 seconds.
+ * Secondly, the value determines if an I/O is considered "hung". Any I/O that
+ * has not completed in zfs_deadman_synctime_ms is considered "hung" resulting
+ * in a system panic.
+ */
+unsigned long zfs_deadman_synctime_ms = 1000000ULL;
+
+/*
+ * By default the deadman is enabled.
+ */
+int zfs_deadman_enabled = 1;
+
+/*
+ * The worst case is single-sector max-parity RAID-Z blocks, in which
+ * case the space requirement is exactly (VDEV_RAIDZ_MAXPARITY + 1)
+ * times the size; so just assume that.  Add to this the fact that
+ * we can have up to 3 DVAs per bp, and one more factor of 2 because
+ * the block may be dittoed with up to 3 DVAs by ddt_sync().  All together,
+ * the worst case is:
+ *     (VDEV_RAIDZ_MAXPARITY + 1) * SPA_DVAS_PER_BP * 2 == 24
+ */
+int spa_asize_inflation = 24;
+
+/*
+ * Normally, we don't allow the last 3.2% (1/(2^spa_slop_shift)) of space in
+ * the pool to be consumed.  This ensures that we don't run the pool
+ * completely out of space, due to unaccounted changes (e.g. to the MOS).
+ * It also limits the worst-case time to allocate space.  If we have
+ * less than this amount of free space, most ZPL operations (e.g. write,
+ * create) will return ENOSPC.
+ *
+ * Certain operations (e.g. file removal, most administrative actions) can
+ * use half the slop space.  They will only return ENOSPC if less than half
+ * the slop space is free.  Typically, once the pool has less than the slop
+ * space free, the user will use these operations to free up space in the pool.
+ * These are the operations that call dsl_pool_adjustedsize() with the netfree
+ * argument set to TRUE.
+ *
+ * A very restricted set of operations are always permitted, regardless of
+ * the amount of free space.  These are the operations that call
+ * dsl_sync_task(ZFS_SPACE_CHECK_NONE), e.g. "zfs destroy".  If these
+ * operations result in a net increase in the amount of space used,
+ * it is possible to run the pool completely out of space, causing it to
+ * be permanently read-only.
+ *
+ * See also the comments in zfs_space_check_t.
+ */
+int spa_slop_shift = 5;
+
+/*
+ * ==========================================================================
+ * SPA config locking
+ * ==========================================================================
+ */
+static void
+spa_config_lock_init(spa_t *spa)
+{
+	int i;
+
+	for (i = 0; i < SCL_LOCKS; i++) {
+		spa_config_lock_t *scl = &spa->spa_config_lock[i];
+		mutex_init(&scl->scl_lock, NULL, MUTEX_DEFAULT, NULL);
+		cv_init(&scl->scl_cv, NULL, CV_DEFAULT, NULL);
+		refcount_create_untracked(&scl->scl_count);
+		scl->scl_writer = NULL;
+		scl->scl_write_wanted = 0;
+	}
+}
+
+static void
+spa_config_lock_destroy(spa_t *spa)
+{
+	int i;
+
+	for (i = 0; i < SCL_LOCKS; i++) {
+		spa_config_lock_t *scl = &spa->spa_config_lock[i];
+		mutex_destroy(&scl->scl_lock);
+		cv_destroy(&scl->scl_cv);
+		refcount_destroy(&scl->scl_count);
+		ASSERT(scl->scl_writer == NULL);
+		ASSERT(scl->scl_write_wanted == 0);
+	}
+}
+
+int
+spa_config_tryenter(spa_t *spa, int locks, void *tag, krw_t rw)
+{
+	int i;
+
+	for (i = 0; i < SCL_LOCKS; i++) {
+		spa_config_lock_t *scl = &spa->spa_config_lock[i];
+		if (!(locks & (1 << i)))
+			continue;
+		mutex_enter(&scl->scl_lock);
+		if (rw == RW_READER) {
+			if (scl->scl_writer || scl->scl_write_wanted) {
+				mutex_exit(&scl->scl_lock);
+				spa_config_exit(spa, locks ^ (1 << i), tag);
+				return (0);
+			}
+		} else {
+			ASSERT(scl->scl_writer != curthread);
+			if (!refcount_is_zero(&scl->scl_count)) {
+				mutex_exit(&scl->scl_lock);
+				spa_config_exit(spa, locks ^ (1 << i), tag);
+				return (0);
+			}
+			scl->scl_writer = curthread;
+		}
+		(void) refcount_add(&scl->scl_count, tag);
+		mutex_exit(&scl->scl_lock);
+	}
+	return (1);
+}
+
+void
+spa_config_enter(spa_t *spa, int locks, void *tag, krw_t rw)
+{
+	int wlocks_held = 0;
+	int i;
+
+	ASSERT3U(SCL_LOCKS, <, sizeof (wlocks_held) * NBBY);
+
+	for (i = 0; i < SCL_LOCKS; i++) {
+		spa_config_lock_t *scl = &spa->spa_config_lock[i];
+		if (scl->scl_writer == curthread)
+			wlocks_held |= (1 << i);
+		if (!(locks & (1 << i)))
+			continue;
+		mutex_enter(&scl->scl_lock);
+		if (rw == RW_READER) {
+			while (scl->scl_writer || scl->scl_write_wanted) {
+				cv_wait(&scl->scl_cv, &scl->scl_lock);
+			}
+		} else {
+			ASSERT(scl->scl_writer != curthread);
+			while (!refcount_is_zero(&scl->scl_count)) {
+				scl->scl_write_wanted++;
+				cv_wait(&scl->scl_cv, &scl->scl_lock);
+				scl->scl_write_wanted--;
+			}
+			scl->scl_writer = curthread;
+		}
+		(void) refcount_add(&scl->scl_count, tag);
+		mutex_exit(&scl->scl_lock);
+	}
+	ASSERT(wlocks_held <= locks);
+}
+
+void
+spa_config_exit(spa_t *spa, int locks, void *tag)
+{
+	int i;
+
+	for (i = SCL_LOCKS - 1; i >= 0; i--) {
+		spa_config_lock_t *scl = &spa->spa_config_lock[i];
+		if (!(locks & (1 << i)))
+			continue;
+		mutex_enter(&scl->scl_lock);
+		ASSERT(!refcount_is_zero(&scl->scl_count));
+		if (refcount_remove(&scl->scl_count, tag) == 0) {
+			ASSERT(scl->scl_writer == NULL ||
+			    scl->scl_writer == curthread);
+			scl->scl_writer = NULL;	/* OK in either case */
+			cv_broadcast(&scl->scl_cv);
+		}
+		mutex_exit(&scl->scl_lock);
+	}
+}
+
+int
+spa_config_held(spa_t *spa, int locks, krw_t rw)
+{
+	int i, locks_held = 0;
+
+	for (i = 0; i < SCL_LOCKS; i++) {
+		spa_config_lock_t *scl = &spa->spa_config_lock[i];
+		if (!(locks & (1 << i)))
+			continue;
+		if ((rw == RW_READER && !refcount_is_zero(&scl->scl_count)) ||
+		    (rw == RW_WRITER && scl->scl_writer == curthread))
+			locks_held |= 1 << i;
+	}
+
+	return (locks_held);
+}
+
+/*
+ * ==========================================================================
+ * SPA namespace functions
+ * ==========================================================================
+ */
+
+/*
+ * Lookup the named spa_t in the AVL tree.  The spa_namespace_lock must be held.
+ * Returns NULL if no matching spa_t is found.
+ */
+spa_t *
+spa_lookup(const char *name)
+{
+	static spa_t search;	/* spa_t is large; don't allocate on stack */
+	spa_t *spa;
+	avl_index_t where;
+	char *cp;
+
+	ASSERT(MUTEX_HELD(&spa_namespace_lock));
+
+	(void) strlcpy(search.spa_name, name, sizeof (search.spa_name));
+
+	/*
+	 * If it's a full dataset name, figure out the pool name and
+	 * just use that.
+	 */
+	cp = strpbrk(search.spa_name, "/@#");
+	if (cp != NULL)
+		*cp = '\0';
+
+	spa = avl_find(&spa_namespace_avl, &search, &where);
+
+	return (spa);
+}
+
+/*
+ * Fires when spa_sync has not completed within zfs_deadman_synctime_ms.
+ * If the zfs_deadman_enabled flag is set then it inspects all vdev queues
+ * looking for potentially hung I/Os.
+ */
+void
+spa_deadman(void *arg)
+{
+	spa_t *spa = arg;
+
+	zfs_dbgmsg("slow spa_sync: started %llu seconds ago, calls %llu",
+	    (gethrtime() - spa->spa_sync_starttime) / NANOSEC,
+	    ++spa->spa_deadman_calls);
+	if (zfs_deadman_enabled)
+		vdev_deadman(spa->spa_root_vdev);
+
+	spa->spa_deadman_tqid = taskq_dispatch_delay(system_taskq,
+	    spa_deadman, spa, KM_SLEEP, ddi_get_lbolt() +
+	    NSEC_TO_TICK(spa->spa_deadman_synctime));
+}
+
+/*
+ * Create an uninitialized spa_t with the given name.  Requires
+ * spa_namespace_lock.  The caller must ensure that the spa_t doesn't already
+ * exist by calling spa_lookup() first.
+ */
+spa_t *
+spa_add(const char *name, nvlist_t *config, const char *altroot)
+{
+	spa_t *spa;
+	spa_config_dirent_t *dp;
+	int t;
+	int i;
+
+	ASSERT(MUTEX_HELD(&spa_namespace_lock));
+
+	spa = kmem_zalloc(sizeof (spa_t), KM_SLEEP);
+
+	mutex_init(&spa->spa_async_lock, NULL, MUTEX_DEFAULT, NULL);
+	mutex_init(&spa->spa_errlist_lock, NULL, MUTEX_DEFAULT, NULL);
+	mutex_init(&spa->spa_errlog_lock, NULL, MUTEX_DEFAULT, NULL);
+	mutex_init(&spa->spa_evicting_os_lock, NULL, MUTEX_DEFAULT, NULL);
+	mutex_init(&spa->spa_history_lock, NULL, MUTEX_DEFAULT, NULL);
+	mutex_init(&spa->spa_proc_lock, NULL, MUTEX_DEFAULT, NULL);
+	mutex_init(&spa->spa_props_lock, NULL, MUTEX_DEFAULT, NULL);
+	mutex_init(&spa->spa_scrub_lock, NULL, MUTEX_DEFAULT, NULL);
+	mutex_init(&spa->spa_suspend_lock, NULL, MUTEX_DEFAULT, NULL);
+	mutex_init(&spa->spa_vdev_top_lock, NULL, MUTEX_DEFAULT, NULL);
+	mutex_init(&spa->spa_feat_stats_lock, NULL, MUTEX_DEFAULT, NULL);
+
+	cv_init(&spa->spa_async_cv, NULL, CV_DEFAULT, NULL);
+	cv_init(&spa->spa_evicting_os_cv, NULL, CV_DEFAULT, NULL);
+	cv_init(&spa->spa_proc_cv, NULL, CV_DEFAULT, NULL);
+	cv_init(&spa->spa_scrub_io_cv, NULL, CV_DEFAULT, NULL);
+	cv_init(&spa->spa_suspend_cv, NULL, CV_DEFAULT, NULL);
+
+	for (t = 0; t < TXG_SIZE; t++)
+		bplist_create(&spa->spa_free_bplist[t]);
+
+	(void) strlcpy(spa->spa_name, name, sizeof (spa->spa_name));
+	spa->spa_state = POOL_STATE_UNINITIALIZED;
+	spa->spa_freeze_txg = UINT64_MAX;
+	spa->spa_final_txg = UINT64_MAX;
+	spa->spa_load_max_txg = UINT64_MAX;
+	spa->spa_proc = &p0;
+	spa->spa_proc_state = SPA_PROC_NONE;
+
+	spa->spa_deadman_synctime = MSEC2NSEC(zfs_deadman_synctime_ms);
+
+	refcount_create(&spa->spa_refcount);
+	spa_config_lock_init(spa);
+	spa_stats_init(spa);
+
+	avl_add(&spa_namespace_avl, spa);
+
+	/*
+	 * Set the alternate root, if there is one.
+	 */
+	if (altroot)
+		spa->spa_root = spa_strdup(altroot);
+
+	/*
+	 * Every pool starts with the default cachefile
+	 */
+	list_create(&spa->spa_config_list, sizeof (spa_config_dirent_t),
+	    offsetof(spa_config_dirent_t, scd_link));
+
+	dp = kmem_zalloc(sizeof (spa_config_dirent_t), KM_SLEEP);
+	dp->scd_path = altroot ? NULL : spa_strdup(spa_config_path);
+	list_insert_head(&spa->spa_config_list, dp);
+
+	VERIFY(nvlist_alloc(&spa->spa_load_info, NV_UNIQUE_NAME,
+	    KM_SLEEP) == 0);
+
+	if (config != NULL) {
+		nvlist_t *features;
+
+		if (nvlist_lookup_nvlist(config, ZPOOL_CONFIG_FEATURES_FOR_READ,
+		    &features) == 0) {
+			VERIFY(nvlist_dup(features, &spa->spa_label_features,
+			    0) == 0);
+		}
+
+		VERIFY(nvlist_dup(config, &spa->spa_config, 0) == 0);
+	}
+
+	if (spa->spa_label_features == NULL) {
+		VERIFY(nvlist_alloc(&spa->spa_label_features, NV_UNIQUE_NAME,
+		    KM_SLEEP) == 0);
+	}
+
+	spa->spa_debug = ((zfs_flags & ZFS_DEBUG_SPA) != 0);
+
+	spa->spa_min_ashift = INT_MAX;
+	spa->spa_max_ashift = 0;
+
+	/*
+	 * As a pool is being created, treat all features as disabled by
+	 * setting SPA_FEATURE_DISABLED for all entries in the feature
+	 * refcount cache.
+	 */
+	for (i = 0; i < SPA_FEATURES; i++) {
+		spa->spa_feat_refcount_cache[i] = SPA_FEATURE_DISABLED;
+	}
+
+	return (spa);
+}
+
+/*
+ * Removes a spa_t from the namespace, freeing up any memory used.  Requires
+ * spa_namespace_lock.  This is called only after the spa_t has been closed and
+ * deactivated.
+ */
+void
+spa_remove(spa_t *spa)
+{
+	spa_config_dirent_t *dp;
+	int t;
+
+	ASSERT(MUTEX_HELD(&spa_namespace_lock));
+	ASSERT(spa->spa_state == POOL_STATE_UNINITIALIZED);
+	ASSERT3U(refcount_count(&spa->spa_refcount), ==, 0);
+
+	nvlist_free(spa->spa_config_splitting);
+
+	avl_remove(&spa_namespace_avl, spa);
+	cv_broadcast(&spa_namespace_cv);
+
+	if (spa->spa_root)
+		spa_strfree(spa->spa_root);
+
+	while ((dp = list_head(&spa->spa_config_list)) != NULL) {
+		list_remove(&spa->spa_config_list, dp);
+		if (dp->scd_path != NULL)
+			spa_strfree(dp->scd_path);
+		kmem_free(dp, sizeof (spa_config_dirent_t));
+	}
+
+	list_destroy(&spa->spa_config_list);
+
+	nvlist_free(spa->spa_label_features);
+	nvlist_free(spa->spa_load_info);
+	nvlist_free(spa->spa_feat_stats);
+	spa_config_set(spa, NULL);
+
+	refcount_destroy(&spa->spa_refcount);
+
+	spa_stats_destroy(spa);
+	spa_config_lock_destroy(spa);
+
+	for (t = 0; t < TXG_SIZE; t++)
+		bplist_destroy(&spa->spa_free_bplist[t]);
+
+	cv_destroy(&spa->spa_async_cv);
+	cv_destroy(&spa->spa_evicting_os_cv);
+	cv_destroy(&spa->spa_proc_cv);
+	cv_destroy(&spa->spa_scrub_io_cv);
+	cv_destroy(&spa->spa_suspend_cv);
+
+	mutex_destroy(&spa->spa_async_lock);
+	mutex_destroy(&spa->spa_errlist_lock);
+	mutex_destroy(&spa->spa_errlog_lock);
+	mutex_destroy(&spa->spa_evicting_os_lock);
+	mutex_destroy(&spa->spa_history_lock);
+	mutex_destroy(&spa->spa_proc_lock);
+	mutex_destroy(&spa->spa_props_lock);
+	mutex_destroy(&spa->spa_scrub_lock);
+	mutex_destroy(&spa->spa_suspend_lock);
+	mutex_destroy(&spa->spa_vdev_top_lock);
+	mutex_destroy(&spa->spa_feat_stats_lock);
+
+	kmem_free(spa, sizeof (spa_t));
+}
+
+/*
+ * Given a pool, return the next pool in the namespace, or NULL if there is
+ * none.  If 'prev' is NULL, return the first pool.
+ */
+spa_t *
+spa_next(spa_t *prev)
+{
+	ASSERT(MUTEX_HELD(&spa_namespace_lock));
+
+	if (prev)
+		return (AVL_NEXT(&spa_namespace_avl, prev));
+	else
+		return (avl_first(&spa_namespace_avl));
+}
+
+/*
+ * ==========================================================================
+ * SPA refcount functions
+ * ==========================================================================
+ */
+
+/*
+ * Add a reference to the given spa_t.  Must have at least one reference, or
+ * have the namespace lock held.
+ */
+void
+spa_open_ref(spa_t *spa, void *tag)
+{
+	ASSERT(refcount_count(&spa->spa_refcount) >= spa->spa_minref ||
+	    MUTEX_HELD(&spa_namespace_lock));
+	(void) refcount_add(&spa->spa_refcount, tag);
+}
+
+/*
+ * Remove a reference to the given spa_t.  Must have at least one reference, or
+ * have the namespace lock held.
+ */
+void
+spa_close(spa_t *spa, void *tag)
+{
+	ASSERT(refcount_count(&spa->spa_refcount) > spa->spa_minref ||
+	    MUTEX_HELD(&spa_namespace_lock));
+	(void) refcount_remove(&spa->spa_refcount, tag);
+}
+
+/*
+ * Remove a reference to the given spa_t held by a dsl dir that is
+ * being asynchronously released.  Async releases occur from a taskq
+ * performing eviction of dsl datasets and dirs.  The namespace lock
+ * isn't held and the hold by the object being evicted may contribute to
+ * spa_minref (e.g. dataset or directory released during pool export),
+ * so the asserts in spa_close() do not apply.
+ */
+void
+spa_async_close(spa_t *spa, void *tag)
+{
+	(void) refcount_remove(&spa->spa_refcount, tag);
+}
+
+/*
+ * Check to see if the spa refcount is zero.  Must be called with
+ * spa_namespace_lock held.  We really compare against spa_minref, which is the
+ * number of references acquired when opening a pool
+ */
+boolean_t
+spa_refcount_zero(spa_t *spa)
+{
+	ASSERT(MUTEX_HELD(&spa_namespace_lock));
+
+	return (refcount_count(&spa->spa_refcount) == spa->spa_minref);
+}
+
+/*
+ * ==========================================================================
+ * SPA spare and l2cache tracking
+ * ==========================================================================
+ */
+
+/*
+ * Hot spares and cache devices are tracked using the same code below,
+ * for 'auxiliary' devices.
+ */
+
+typedef struct spa_aux {
+	uint64_t	aux_guid;
+	uint64_t	aux_pool;
+	avl_node_t	aux_avl;
+	int		aux_count;
+} spa_aux_t;
+
+static int
+spa_aux_compare(const void *a, const void *b)
+{
+	const spa_aux_t *sa = a;
+	const spa_aux_t *sb = b;
+
+	if (sa->aux_guid < sb->aux_guid)
+		return (-1);
+	else if (sa->aux_guid > sb->aux_guid)
+		return (1);
+	else
+		return (0);
+}
+
+void
+spa_aux_add(vdev_t *vd, avl_tree_t *avl)
+{
+	avl_index_t where;
+	spa_aux_t search;
+	spa_aux_t *aux;
+
+	search.aux_guid = vd->vdev_guid;
+	if ((aux = avl_find(avl, &search, &where)) != NULL) {
+		aux->aux_count++;
+	} else {
+		aux = kmem_zalloc(sizeof (spa_aux_t), KM_SLEEP);
+		aux->aux_guid = vd->vdev_guid;
+		aux->aux_count = 1;
+		avl_insert(avl, aux, where);
+	}
+}
+
+void
+spa_aux_remove(vdev_t *vd, avl_tree_t *avl)
+{
+	spa_aux_t search;
+	spa_aux_t *aux;
+	avl_index_t where;
+
+	search.aux_guid = vd->vdev_guid;
+	aux = avl_find(avl, &search, &where);
+
+	ASSERT(aux != NULL);
+
+	if (--aux->aux_count == 0) {
+		avl_remove(avl, aux);
+		kmem_free(aux, sizeof (spa_aux_t));
+	} else if (aux->aux_pool == spa_guid(vd->vdev_spa)) {
+		aux->aux_pool = 0ULL;
+	}
+}
+
+boolean_t
+spa_aux_exists(uint64_t guid, uint64_t *pool, int *refcnt, avl_tree_t *avl)
+{
+	spa_aux_t search, *found;
+
+	search.aux_guid = guid;
+	found = avl_find(avl, &search, NULL);
+
+	if (pool) {
+		if (found)
+			*pool = found->aux_pool;
+		else
+			*pool = 0ULL;
+	}
+
+	if (refcnt) {
+		if (found)
+			*refcnt = found->aux_count;
+		else
+			*refcnt = 0;
+	}
+
+	return (found != NULL);
+}
+
+void
+spa_aux_activate(vdev_t *vd, avl_tree_t *avl)
+{
+	spa_aux_t search, *found;
+	avl_index_t where;
+
+	search.aux_guid = vd->vdev_guid;
+	found = avl_find(avl, &search, &where);
+	ASSERT(found != NULL);
+	ASSERT(found->aux_pool == 0ULL);
+
+	found->aux_pool = spa_guid(vd->vdev_spa);
+}
+
+/*
+ * Spares are tracked globally due to the following constraints:
+ *
+ * 	- A spare may be part of multiple pools.
+ * 	- A spare may be added to a pool even if it's actively in use within
+ *	  another pool.
+ * 	- A spare in use in any pool can only be the source of a replacement if
+ *	  the target is a spare in the same pool.
+ *
+ * We keep track of all spares on the system through the use of a reference
+ * counted AVL tree.  When a vdev is added as a spare, or used as a replacement
+ * spare, then we bump the reference count in the AVL tree.  In addition, we set
+ * the 'vdev_isspare' member to indicate that the device is a spare (active or
+ * inactive).  When a spare is made active (used to replace a device in the
+ * pool), we also keep track of which pool its been made a part of.
+ *
+ * The 'spa_spare_lock' protects the AVL tree.  These functions are normally
+ * called under the spa_namespace lock as part of vdev reconfiguration.  The
+ * separate spare lock exists for the status query path, which does not need to
+ * be completely consistent with respect to other vdev configuration changes.
+ */
+
+static int
+spa_spare_compare(const void *a, const void *b)
+{
+	return (spa_aux_compare(a, b));
+}
+
+void
+spa_spare_add(vdev_t *vd)
+{
+	mutex_enter(&spa_spare_lock);
+	ASSERT(!vd->vdev_isspare);
+	spa_aux_add(vd, &spa_spare_avl);
+	vd->vdev_isspare = B_TRUE;
+	mutex_exit(&spa_spare_lock);
+}
+
+void
+spa_spare_remove(vdev_t *vd)
+{
+	mutex_enter(&spa_spare_lock);
+	ASSERT(vd->vdev_isspare);
+	spa_aux_remove(vd, &spa_spare_avl);
+	vd->vdev_isspare = B_FALSE;
+	mutex_exit(&spa_spare_lock);
+}
+
+boolean_t
+spa_spare_exists(uint64_t guid, uint64_t *pool, int *refcnt)
+{
+	boolean_t found;
+
+	mutex_enter(&spa_spare_lock);
+	found = spa_aux_exists(guid, pool, refcnt, &spa_spare_avl);
+	mutex_exit(&spa_spare_lock);
+
+	return (found);
+}
+
+void
+spa_spare_activate(vdev_t *vd)
+{
+	mutex_enter(&spa_spare_lock);
+	ASSERT(vd->vdev_isspare);
+	spa_aux_activate(vd, &spa_spare_avl);
+	mutex_exit(&spa_spare_lock);
+}
+
+/*
+ * Level 2 ARC devices are tracked globally for the same reasons as spares.
+ * Cache devices currently only support one pool per cache device, and so
+ * for these devices the aux reference count is currently unused beyond 1.
+ */
+
+static int
+spa_l2cache_compare(const void *a, const void *b)
+{
+	return (spa_aux_compare(a, b));
+}
+
+void
+spa_l2cache_add(vdev_t *vd)
+{
+	mutex_enter(&spa_l2cache_lock);
+	ASSERT(!vd->vdev_isl2cache);
+	spa_aux_add(vd, &spa_l2cache_avl);
+	vd->vdev_isl2cache = B_TRUE;
+	mutex_exit(&spa_l2cache_lock);
+}
+
+void
+spa_l2cache_remove(vdev_t *vd)
+{
+	mutex_enter(&spa_l2cache_lock);
+	ASSERT(vd->vdev_isl2cache);
+	spa_aux_remove(vd, &spa_l2cache_avl);
+	vd->vdev_isl2cache = B_FALSE;
+	mutex_exit(&spa_l2cache_lock);
+}
+
+boolean_t
+spa_l2cache_exists(uint64_t guid, uint64_t *pool)
+{
+	boolean_t found;
+
+	mutex_enter(&spa_l2cache_lock);
+	found = spa_aux_exists(guid, pool, NULL, &spa_l2cache_avl);
+	mutex_exit(&spa_l2cache_lock);
+
+	return (found);
+}
+
+void
+spa_l2cache_activate(vdev_t *vd)
+{
+	mutex_enter(&spa_l2cache_lock);
+	ASSERT(vd->vdev_isl2cache);
+	spa_aux_activate(vd, &spa_l2cache_avl);
+	mutex_exit(&spa_l2cache_lock);
+}
+
+/*
+ * ==========================================================================
+ * SPA vdev locking
+ * ==========================================================================
+ */
+
+/*
+ * Lock the given spa_t for the purpose of adding or removing a vdev.
+ * Grabs the global spa_namespace_lock plus the spa config lock for writing.
+ * It returns the next transaction group for the spa_t.
+ */
+uint64_t
+spa_vdev_enter(spa_t *spa)
+{
+	mutex_enter(&spa->spa_vdev_top_lock);
+	mutex_enter(&spa_namespace_lock);
+	return (spa_vdev_config_enter(spa));
+}
+
+/*
+ * Internal implementation for spa_vdev_enter().  Used when a vdev
+ * operation requires multiple syncs (i.e. removing a device) while
+ * keeping the spa_namespace_lock held.
+ */
+uint64_t
+spa_vdev_config_enter(spa_t *spa)
+{
+	ASSERT(MUTEX_HELD(&spa_namespace_lock));
+
+	spa_config_enter(spa, SCL_ALL, spa, RW_WRITER);
+
+	return (spa_last_synced_txg(spa) + 1);
+}
+
+/*
+ * Used in combination with spa_vdev_config_enter() to allow the syncing
+ * of multiple transactions without releasing the spa_namespace_lock.
+ */
+void
+spa_vdev_config_exit(spa_t *spa, vdev_t *vd, uint64_t txg, int error, char *tag)
+{
+	int config_changed = B_FALSE;
+
+	ASSERT(MUTEX_HELD(&spa_namespace_lock));
+	ASSERT(txg > spa_last_synced_txg(spa));
+
+	spa->spa_pending_vdev = NULL;
+
+	/*
+	 * Reassess the DTLs.
+	 */
+	vdev_dtl_reassess(spa->spa_root_vdev, 0, 0, B_FALSE);
+
+	if (error == 0 && !list_is_empty(&spa->spa_config_dirty_list)) {
+		config_changed = B_TRUE;
+		spa->spa_config_generation++;
+	}
+
+	/*
+	 * Verify the metaslab classes.
+	 */
+	ASSERT(metaslab_class_validate(spa_normal_class(spa)) == 0);
+	ASSERT(metaslab_class_validate(spa_log_class(spa)) == 0);
+
+	spa_config_exit(spa, SCL_ALL, spa);
+
+	/*
+	 * Panic the system if the specified tag requires it.  This
+	 * is useful for ensuring that configurations are updated
+	 * transactionally.
+	 */
+	if (zio_injection_enabled)
+		zio_handle_panic_injection(spa, tag, 0);
+
+	/*
+	 * Note: this txg_wait_synced() is important because it ensures
+	 * that there won't be more than one config change per txg.
+	 * This allows us to use the txg as the generation number.
+	 */
+	if (error == 0)
+		txg_wait_synced(spa->spa_dsl_pool, txg);
+
+	if (vd != NULL) {
+		ASSERT(!vd->vdev_detached || vd->vdev_dtl_sm == NULL);
+		spa_config_enter(spa, SCL_ALL, spa, RW_WRITER);
+		vdev_free(vd);
+		spa_config_exit(spa, SCL_ALL, spa);
+	}
+
+	/*
+	 * If the config changed, update the config cache.
+	 */
+	if (config_changed)
+		spa_config_sync(spa, B_FALSE, B_TRUE);
+}
+
+/*
+ * Unlock the spa_t after adding or removing a vdev.  Besides undoing the
+ * locking of spa_vdev_enter(), we also want make sure the transactions have
+ * synced to disk, and then update the global configuration cache with the new
+ * information.
+ */
+int
+spa_vdev_exit(spa_t *spa, vdev_t *vd, uint64_t txg, int error)
+{
+	spa_vdev_config_exit(spa, vd, txg, error, FTAG);
+	mutex_exit(&spa_namespace_lock);
+	mutex_exit(&spa->spa_vdev_top_lock);
+
+	return (error);
+}
+
+/*
+ * Lock the given spa_t for the purpose of changing vdev state.
+ */
+void
+spa_vdev_state_enter(spa_t *spa, int oplocks)
+{
+	int locks = SCL_STATE_ALL | oplocks;
+
+	/*
+	 * Root pools may need to read of the underlying devfs filesystem
+	 * when opening up a vdev.  Unfortunately if we're holding the
+	 * SCL_ZIO lock it will result in a deadlock when we try to issue
+	 * the read from the root filesystem.  Instead we "prefetch"
+	 * the associated vnodes that we need prior to opening the
+	 * underlying devices and cache them so that we can prevent
+	 * any I/O when we are doing the actual open.
+	 */
+	if (spa_is_root(spa)) {
+		int low = locks & ~(SCL_ZIO - 1);
+		int high = locks & ~low;
+
+		spa_config_enter(spa, high, spa, RW_WRITER);
+		vdev_hold(spa->spa_root_vdev);
+		spa_config_enter(spa, low, spa, RW_WRITER);
+	} else {
+		spa_config_enter(spa, locks, spa, RW_WRITER);
+	}
+	spa->spa_vdev_locks = locks;
+}
+
+int
+spa_vdev_state_exit(spa_t *spa, vdev_t *vd, int error)
+{
+	boolean_t config_changed = B_FALSE;
+
+	if (vd != NULL || error == 0)
+		vdev_dtl_reassess(vd ? vd->vdev_top : spa->spa_root_vdev,
+		    0, 0, B_FALSE);
+
+	if (vd != NULL) {
+		vdev_state_dirty(vd->vdev_top);
+		config_changed = B_TRUE;
+		spa->spa_config_generation++;
+	}
+
+	if (spa_is_root(spa))
+		vdev_rele(spa->spa_root_vdev);
+
+	ASSERT3U(spa->spa_vdev_locks, >=, SCL_STATE_ALL);
+	spa_config_exit(spa, spa->spa_vdev_locks, spa);
+
+	/*
+	 * If anything changed, wait for it to sync.  This ensures that,
+	 * from the system administrator's perspective, zpool(1M) commands
+	 * are synchronous.  This is important for things like zpool offline:
+	 * when the command completes, you expect no further I/O from ZFS.
+	 */
+	if (vd != NULL)
+		txg_wait_synced(spa->spa_dsl_pool, 0);
+
+	/*
+	 * If the config changed, update the config cache.
+	 */
+	if (config_changed) {
+		mutex_enter(&spa_namespace_lock);
+		spa_config_sync(spa, B_FALSE, B_TRUE);
+		mutex_exit(&spa_namespace_lock);
+	}
+
+	return (error);
+}
+
+/*
+ * ==========================================================================
+ * Miscellaneous functions
+ * ==========================================================================
+ */
+
+void
+spa_activate_mos_feature(spa_t *spa, const char *feature, dmu_tx_t *tx)
+{
+	if (!nvlist_exists(spa->spa_label_features, feature)) {
+		fnvlist_add_boolean(spa->spa_label_features, feature);
+		/*
+		 * When we are creating the pool (tx_txg==TXG_INITIAL), we can't
+		 * dirty the vdev config because lock SCL_CONFIG is not held.
+		 * Thankfully, in this case we don't need to dirty the config
+		 * because it will be written out anyway when we finish
+		 * creating the pool.
+		 */
+		if (tx->tx_txg != TXG_INITIAL)
+			vdev_config_dirty(spa->spa_root_vdev);
+	}
+}
+
+void
+spa_deactivate_mos_feature(spa_t *spa, const char *feature)
+{
+	if (nvlist_remove_all(spa->spa_label_features, feature) == 0)
+		vdev_config_dirty(spa->spa_root_vdev);
+}
+
+/*
+ * Rename a spa_t.
+ */
+int
+spa_rename(const char *name, const char *newname)
+{
+	spa_t *spa;
+	int err;
+
+	/*
+	 * Lookup the spa_t and grab the config lock for writing.  We need to
+	 * actually open the pool so that we can sync out the necessary labels.
+	 * It's OK to call spa_open() with the namespace lock held because we
+	 * allow recursive calls for other reasons.
+	 */
+	mutex_enter(&spa_namespace_lock);
+	if ((err = spa_open(name, &spa, FTAG)) != 0) {
+		mutex_exit(&spa_namespace_lock);
+		return (err);
+	}
+
+	spa_config_enter(spa, SCL_ALL, FTAG, RW_WRITER);
+
+	avl_remove(&spa_namespace_avl, spa);
+	(void) strlcpy(spa->spa_name, newname, sizeof (spa->spa_name));
+	avl_add(&spa_namespace_avl, spa);
+
+	/*
+	 * Sync all labels to disk with the new names by marking the root vdev
+	 * dirty and waiting for it to sync.  It will pick up the new pool name
+	 * during the sync.
+	 */
+	vdev_config_dirty(spa->spa_root_vdev);
+
+	spa_config_exit(spa, SCL_ALL, FTAG);
+
+	txg_wait_synced(spa->spa_dsl_pool, 0);
+
+	/*
+	 * Sync the updated config cache.
+	 */
+	spa_config_sync(spa, B_FALSE, B_TRUE);
+
+	spa_close(spa, FTAG);
+
+	mutex_exit(&spa_namespace_lock);
+
+	return (0);
+}
+
+/*
+ * Return the spa_t associated with given pool_guid, if it exists.  If
+ * device_guid is non-zero, determine whether the pool exists *and* contains
+ * a device with the specified device_guid.
+ */
+spa_t *
+spa_by_guid(uint64_t pool_guid, uint64_t device_guid)
+{
+	spa_t *spa;
+	avl_tree_t *t = &spa_namespace_avl;
+
+	ASSERT(MUTEX_HELD(&spa_namespace_lock));
+
+	for (spa = avl_first(t); spa != NULL; spa = AVL_NEXT(t, spa)) {
+		if (spa->spa_state == POOL_STATE_UNINITIALIZED)
+			continue;
+		if (spa->spa_root_vdev == NULL)
+			continue;
+		if (spa_guid(spa) == pool_guid) {
+			if (device_guid == 0)
+				break;
+
+			if (vdev_lookup_by_guid(spa->spa_root_vdev,
+			    device_guid) != NULL)
+				break;
+
+			/*
+			 * Check any devices we may be in the process of adding.
+			 */
+			if (spa->spa_pending_vdev) {
+				if (vdev_lookup_by_guid(spa->spa_pending_vdev,
+				    device_guid) != NULL)
+					break;
+			}
+		}
+	}
+
+	return (spa);
+}
+
+/*
+ * Determine whether a pool with the given pool_guid exists.
+ */
+boolean_t
+spa_guid_exists(uint64_t pool_guid, uint64_t device_guid)
+{
+	return (spa_by_guid(pool_guid, device_guid) != NULL);
+}
+
+char *
+spa_strdup(const char *s)
+{
+	size_t len;
+	char *new;
+
+	len = strlen(s);
+	new = kmem_alloc(len + 1, KM_SLEEP);
+	bcopy(s, new, len);
+	new[len] = '\0';
+
+	return (new);
+}
+
+void
+spa_strfree(char *s)
+{
+	kmem_free(s, strlen(s) + 1);
+}
+
+uint64_t
+spa_get_random(uint64_t range)
+{
+	uint64_t r;
+
+	ASSERT(range != 0);
+
+	(void) random_get_pseudo_bytes((void *)&r, sizeof (uint64_t));
+
+	return (r % range);
+}
+
+uint64_t
+spa_generate_guid(spa_t *spa)
+{
+	uint64_t guid = spa_get_random(-1ULL);
+
+	if (spa != NULL) {
+		while (guid == 0 || spa_guid_exists(spa_guid(spa), guid))
+			guid = spa_get_random(-1ULL);
+	} else {
+		while (guid == 0 || spa_guid_exists(guid, 0))
+			guid = spa_get_random(-1ULL);
+	}
+
+	return (guid);
+}
+
+void
+snprintf_blkptr(char *buf, size_t buflen, const blkptr_t *bp)
+{
+	char type[256];
+	char *checksum = NULL;
+	char *compress = NULL;
+
+	if (bp != NULL) {
+		if (BP_GET_TYPE(bp) & DMU_OT_NEWTYPE) {
+			dmu_object_byteswap_t bswap =
+			    DMU_OT_BYTESWAP(BP_GET_TYPE(bp));
+			(void) snprintf(type, sizeof (type), "bswap %s %s",
+			    DMU_OT_IS_METADATA(BP_GET_TYPE(bp)) ?
+			    "metadata" : "data",
+			    dmu_ot_byteswap[bswap].ob_name);
+		} else {
+			(void) strlcpy(type, dmu_ot[BP_GET_TYPE(bp)].ot_name,
+			    sizeof (type));
+		}
+		if (!BP_IS_EMBEDDED(bp)) {
+			checksum =
+			    zio_checksum_table[BP_GET_CHECKSUM(bp)].ci_name;
+		}
+		compress = zio_compress_table[BP_GET_COMPRESS(bp)].ci_name;
+	}
+
+	SNPRINTF_BLKPTR(snprintf, ' ', buf, buflen, bp, type, checksum,
+	    compress);
+}
+
+void
+spa_freeze(spa_t *spa)
+{
+	uint64_t freeze_txg = 0;
+
+	spa_config_enter(spa, SCL_ALL, FTAG, RW_WRITER);
+	if (spa->spa_freeze_txg == UINT64_MAX) {
+		freeze_txg = spa_last_synced_txg(spa) + TXG_SIZE;
+		spa->spa_freeze_txg = freeze_txg;
+	}
+	spa_config_exit(spa, SCL_ALL, FTAG);
+	if (freeze_txg != 0)
+		txg_wait_synced(spa_get_dsl(spa), freeze_txg);
+}
+
+void
+zfs_panic_recover(const char *fmt, ...)
+{
+	va_list adx;
+
+	va_start(adx, fmt);
+	vcmn_err(zfs_recover ? CE_WARN : CE_PANIC, fmt, adx);
+	va_end(adx);
+}
+
+/*
+ * This is a stripped-down version of strtoull, suitable only for converting
+ * lowercase hexadecimal numbers that don't overflow.
+ */
+uint64_t
+strtonum(const char *str, char **nptr)
+{
+	uint64_t val = 0;
+	char c;
+	int digit;
+
+	while ((c = *str) != '\0') {
+		if (c >= '0' && c <= '9')
+			digit = c - '0';
+		else if (c >= 'a' && c <= 'f')
+			digit = 10 + c - 'a';
+		else
+			break;
+
+		val *= 16;
+		val += digit;
+
+		str++;
+	}
+
+	if (nptr)
+		*nptr = (char *)str;
+
+	return (val);
+}
+
+/*
+ * ==========================================================================
+ * Accessor functions
+ * ==========================================================================
+ */
+
+boolean_t
+spa_shutting_down(spa_t *spa)
+{
+	return (spa->spa_async_suspended);
+}
+
+dsl_pool_t *
+spa_get_dsl(spa_t *spa)
+{
+	return (spa->spa_dsl_pool);
+}
+
+boolean_t
+spa_is_initializing(spa_t *spa)
+{
+	return (spa->spa_is_initializing);
+}
+
+blkptr_t *
+spa_get_rootblkptr(spa_t *spa)
+{
+	return (&spa->spa_ubsync.ub_rootbp);
+}
+
+void
+spa_set_rootblkptr(spa_t *spa, const blkptr_t *bp)
+{
+	spa->spa_uberblock.ub_rootbp = *bp;
+}
+
+void
+spa_altroot(spa_t *spa, char *buf, size_t buflen)
+{
+	if (spa->spa_root == NULL)
+		buf[0] = '\0';
+	else
+		(void) strncpy(buf, spa->spa_root, buflen);
+}
+
+int
+spa_sync_pass(spa_t *spa)
+{
+	return (spa->spa_sync_pass);
+}
+
+char *
+spa_name(spa_t *spa)
+{
+	return (spa->spa_name);
+}
+
+uint64_t
+spa_guid(spa_t *spa)
+{
+	dsl_pool_t *dp = spa_get_dsl(spa);
+	uint64_t guid;
+
+	/*
+	 * If we fail to parse the config during spa_load(), we can go through
+	 * the error path (which posts an ereport) and end up here with no root
+	 * vdev.  We stash the original pool guid in 'spa_config_guid' to handle
+	 * this case.
+	 */
+	if (spa->spa_root_vdev == NULL)
+		return (spa->spa_config_guid);
+
+	guid = spa->spa_last_synced_guid != 0 ?
+	    spa->spa_last_synced_guid : spa->spa_root_vdev->vdev_guid;
+
+	/*
+	 * Return the most recently synced out guid unless we're
+	 * in syncing context.
+	 */
+	if (dp && dsl_pool_sync_context(dp))
+		return (spa->spa_root_vdev->vdev_guid);
+	else
+		return (guid);
+}
+
+uint64_t
+spa_load_guid(spa_t *spa)
+{
+	/*
+	 * This is a GUID that exists solely as a reference for the
+	 * purposes of the arc.  It is generated at load time, and
+	 * is never written to persistent storage.
+	 */
+	return (spa->spa_load_guid);
+}
+
+uint64_t
+spa_last_synced_txg(spa_t *spa)
+{
+	return (spa->spa_ubsync.ub_txg);
+}
+
+uint64_t
+spa_first_txg(spa_t *spa)
+{
+	return (spa->spa_first_txg);
+}
+
+uint64_t
+spa_syncing_txg(spa_t *spa)
+{
+	return (spa->spa_syncing_txg);
+}
+
+pool_state_t
+spa_state(spa_t *spa)
+{
+	return (spa->spa_state);
+}
+
+spa_load_state_t
+spa_load_state(spa_t *spa)
+{
+	return (spa->spa_load_state);
+}
+
+uint64_t
+spa_freeze_txg(spa_t *spa)
+{
+	return (spa->spa_freeze_txg);
+}
+
+/* ARGSUSED */
+uint64_t
+spa_get_asize(spa_t *spa, uint64_t lsize)
+{
+	return (lsize * spa_asize_inflation);
+}
+
+/*
+ * Return the amount of slop space in bytes.  It is 1/32 of the pool (3.2%),
+ * or at least 32MB.
+ *
+ * See the comment above spa_slop_shift for details.
+ */
+uint64_t
+spa_get_slop_space(spa_t *spa) {
+	uint64_t space = spa_get_dspace(spa);
+	return (MAX(space >> spa_slop_shift, SPA_MINDEVSIZE >> 1));
+}
+
+uint64_t
+spa_get_dspace(spa_t *spa)
+{
+	return (spa->spa_dspace);
+}
+
+void
+spa_update_dspace(spa_t *spa)
+{
+	spa->spa_dspace = metaslab_class_get_dspace(spa_normal_class(spa)) +
+	    ddt_get_dedup_dspace(spa);
+}
+
+/*
+ * Return the failure mode that has been set to this pool. The default
+ * behavior will be to block all I/Os when a complete failure occurs.
+ */
+uint8_t
+spa_get_failmode(spa_t *spa)
+{
+	return (spa->spa_failmode);
+}
+
+boolean_t
+spa_suspended(spa_t *spa)
+{
+	return (spa->spa_suspended);
+}
+
+uint64_t
+spa_version(spa_t *spa)
+{
+	return (spa->spa_ubsync.ub_version);
+}
+
+boolean_t
+spa_deflate(spa_t *spa)
+{
+	return (spa->spa_deflate);
+}
+
+metaslab_class_t *
+spa_normal_class(spa_t *spa)
+{
+	return (spa->spa_normal_class);
+}
+
+metaslab_class_t *
+spa_log_class(spa_t *spa)
+{
+	return (spa->spa_log_class);
+}
+
+void
+spa_evicting_os_register(spa_t *spa, objset_t *os)
+{
+	mutex_enter(&spa->spa_evicting_os_lock);
+	list_insert_head(&spa->spa_evicting_os_list, os);
+	mutex_exit(&spa->spa_evicting_os_lock);
+}
+
+void
+spa_evicting_os_deregister(spa_t *spa, objset_t *os)
+{
+	mutex_enter(&spa->spa_evicting_os_lock);
+	list_remove(&spa->spa_evicting_os_list, os);
+	cv_broadcast(&spa->spa_evicting_os_cv);
+	mutex_exit(&spa->spa_evicting_os_lock);
+}
+
+void
+spa_evicting_os_wait(spa_t *spa)
+{
+	mutex_enter(&spa->spa_evicting_os_lock);
+	while (!list_is_empty(&spa->spa_evicting_os_list))
+		cv_wait(&spa->spa_evicting_os_cv, &spa->spa_evicting_os_lock);
+	mutex_exit(&spa->spa_evicting_os_lock);
+
+	dmu_buf_user_evict_wait();
+}
+
+int
+spa_max_replication(spa_t *spa)
+{
+	/*
+	 * As of SPA_VERSION == SPA_VERSION_DITTO_BLOCKS, we are able to
+	 * handle BPs with more than one DVA allocated.  Set our max
+	 * replication level accordingly.
+	 */
+	if (spa_version(spa) < SPA_VERSION_DITTO_BLOCKS)
+		return (1);
+	return (MIN(SPA_DVAS_PER_BP, spa_max_replication_override));
+}
+
+int
+spa_prev_software_version(spa_t *spa)
+{
+	return (spa->spa_prev_software_version);
+}
+
+uint64_t
+spa_deadman_synctime(spa_t *spa)
+{
+	return (spa->spa_deadman_synctime);
+}
+
+uint64_t
+dva_get_dsize_sync(spa_t *spa, const dva_t *dva)
+{
+	uint64_t asize = DVA_GET_ASIZE(dva);
+	uint64_t dsize = asize;
+
+	ASSERT(spa_config_held(spa, SCL_ALL, RW_READER) != 0);
+
+	if (asize != 0 && spa->spa_deflate) {
+		vdev_t *vd = vdev_lookup_top(spa, DVA_GET_VDEV(dva));
+		if (vd != NULL)
+			dsize = (asize >> SPA_MINBLOCKSHIFT) *
+			    vd->vdev_deflate_ratio;
+	}
+
+	return (dsize);
+}
+
+uint64_t
+bp_get_dsize_sync(spa_t *spa, const blkptr_t *bp)
+{
+	uint64_t dsize = 0;
+	int d;
+
+	for (d = 0; d < BP_GET_NDVAS(bp); d++)
+		dsize += dva_get_dsize_sync(spa, &bp->blk_dva[d]);
+
+	return (dsize);
+}
+
+uint64_t
+bp_get_dsize(spa_t *spa, const blkptr_t *bp)
+{
+	uint64_t dsize = 0;
+	int d;
+
+	spa_config_enter(spa, SCL_VDEV, FTAG, RW_READER);
+
+	for (d = 0; d < BP_GET_NDVAS(bp); d++)
+		dsize += dva_get_dsize_sync(spa, &bp->blk_dva[d]);
+
+	spa_config_exit(spa, SCL_VDEV, FTAG);
+
+	return (dsize);
+}
+
+/*
+ * ==========================================================================
+ * Initialization and Termination
+ * ==========================================================================
+ */
+
+static int
+spa_name_compare(const void *a1, const void *a2)
+{
+	const spa_t *s1 = a1;
+	const spa_t *s2 = a2;
+	int s;
+
+	s = strcmp(s1->spa_name, s2->spa_name);
+	if (s > 0)
+		return (1);
+	if (s < 0)
+		return (-1);
+	return (0);
+}
+
+void
+spa_boot_init(void)
+{
+	spa_config_load();
+}
+
+void
+spa_init(int mode)
+{
+	mutex_init(&spa_namespace_lock, NULL, MUTEX_DEFAULT, NULL);
+	mutex_init(&spa_spare_lock, NULL, MUTEX_DEFAULT, NULL);
+	mutex_init(&spa_l2cache_lock, NULL, MUTEX_DEFAULT, NULL);
+	cv_init(&spa_namespace_cv, NULL, CV_DEFAULT, NULL);
+
+	avl_create(&spa_namespace_avl, spa_name_compare, sizeof (spa_t),
+	    offsetof(spa_t, spa_avl));
+
+	avl_create(&spa_spare_avl, spa_spare_compare, sizeof (spa_aux_t),
+	    offsetof(spa_aux_t, aux_avl));
+
+	avl_create(&spa_l2cache_avl, spa_l2cache_compare, sizeof (spa_aux_t),
+	    offsetof(spa_aux_t, aux_avl));
+
+	spa_mode_global = mode;
+
+#ifndef _KERNEL
+	if (spa_mode_global != FREAD && dprintf_find_string("watch")) {
+		struct sigaction sa;
+
+		sa.sa_flags = SA_SIGINFO;
+		sigemptyset(&sa.sa_mask);
+		sa.sa_sigaction = arc_buf_sigsegv;
+
+		if (sigaction(SIGSEGV, &sa, NULL) == -1) {
+			perror("could not enable watchpoints: "
+			    "sigaction(SIGSEGV, ...) = ");
+		} else {
+			arc_watch = B_TRUE;
+		}
+	}
+#endif
+
+	fm_init();
+	refcount_init();
+	unique_init();
+	range_tree_init();
+	ddt_init();
+	zio_init();
+	dmu_init();
+	zil_init();
+	vdev_cache_stat_init();
+	zfs_prop_init();
+	zpool_prop_init();
+	zpool_feature_init();
+	spa_config_load();
+	l2arc_start();
+}
+
+void
+spa_fini(void)
+{
+	l2arc_stop();
+
+	spa_evict_all();
+
+	vdev_cache_stat_fini();
+	zil_fini();
+	dmu_fini();
+	zio_fini();
+	ddt_fini();
+	range_tree_fini();
+	unique_fini();
+	refcount_fini();
+	fm_fini();
+
+	avl_destroy(&spa_namespace_avl);
+	avl_destroy(&spa_spare_avl);
+	avl_destroy(&spa_l2cache_avl);
+
+	cv_destroy(&spa_namespace_cv);
+	mutex_destroy(&spa_namespace_lock);
+	mutex_destroy(&spa_spare_lock);
+	mutex_destroy(&spa_l2cache_lock);
+}
+
+/*
+ * Return whether this pool has slogs. No locking needed.
+ * It's not a problem if the wrong answer is returned as it's only for
+ * performance and not correctness
+ */
+boolean_t
+spa_has_slogs(spa_t *spa)
+{
+	return (spa->spa_log_class->mc_rotor != NULL);
+}
+
+spa_log_state_t
+spa_get_log_state(spa_t *spa)
+{
+	return (spa->spa_log_state);
+}
+
+void
+spa_set_log_state(spa_t *spa, spa_log_state_t state)
+{
+	spa->spa_log_state = state;
+}
+
+boolean_t
+spa_is_root(spa_t *spa)
+{
+	return (spa->spa_is_root);
+}
+
+boolean_t
+spa_writeable(spa_t *spa)
+{
+	return (!!(spa->spa_mode & FWRITE));
+}
+
+/*
+ * Returns true if there is a pending sync task in any of the current
+ * syncing txg, the current quiescing txg, or the current open txg.
+ */
+boolean_t
+spa_has_pending_synctask(spa_t *spa)
+{
+	return (!txg_all_lists_empty(&spa->spa_dsl_pool->dp_sync_tasks));
+}
+
+int
+spa_mode(spa_t *spa)
+{
+	return (spa->spa_mode);
+}
+
+uint64_t
+spa_bootfs(spa_t *spa)
+{
+	return (spa->spa_bootfs);
+}
+
+uint64_t
+spa_delegation(spa_t *spa)
+{
+	return (spa->spa_delegation);
+}
+
+objset_t *
+spa_meta_objset(spa_t *spa)
+{
+	return (spa->spa_meta_objset);
+}
+
+enum zio_checksum
+spa_dedup_checksum(spa_t *spa)
+{
+	return (spa->spa_dedup_checksum);
+}
+
+/*
+ * Reset pool scan stat per scan pass (or reboot).
+ */
+void
+spa_scan_stat_init(spa_t *spa)
+{
+	/* data not stored on disk */
+	spa->spa_scan_pass_start = gethrestime_sec();
+	spa->spa_scan_pass_exam = 0;
+	vdev_scan_stat_init(spa->spa_root_vdev);
+}
+
+/*
+ * Get scan stats for zpool status reports
+ */
+int
+spa_scan_get_stats(spa_t *spa, pool_scan_stat_t *ps)
+{
+	dsl_scan_t *scn = spa->spa_dsl_pool ? spa->spa_dsl_pool->dp_scan : NULL;
+
+	if (scn == NULL || scn->scn_phys.scn_func == POOL_SCAN_NONE)
+		return (SET_ERROR(ENOENT));
+	bzero(ps, sizeof (pool_scan_stat_t));
+
+	/* data stored on disk */
+	ps->pss_func = scn->scn_phys.scn_func;
+	ps->pss_start_time = scn->scn_phys.scn_start_time;
+	ps->pss_end_time = scn->scn_phys.scn_end_time;
+	ps->pss_to_examine = scn->scn_phys.scn_to_examine;
+	ps->pss_examined = scn->scn_phys.scn_examined;
+	ps->pss_to_process = scn->scn_phys.scn_to_process;
+	ps->pss_processed = scn->scn_phys.scn_processed;
+	ps->pss_errors = scn->scn_phys.scn_errors;
+	ps->pss_state = scn->scn_phys.scn_state;
+
+	/* data not stored on disk */
+	ps->pss_pass_start = spa->spa_scan_pass_start;
+	ps->pss_pass_exam = spa->spa_scan_pass_exam;
+
+	return (0);
+}
+
+boolean_t
+spa_debug_enabled(spa_t *spa)
+{
+	return (spa->spa_debug);
+}
+
+int
+spa_maxblocksize(spa_t *spa)
+{
+	if (spa_feature_is_enabled(spa, SPA_FEATURE_LARGE_BLOCKS))
+		return (SPA_MAXBLOCKSIZE);
+	else
+		return (SPA_OLD_MAXBLOCKSIZE);
+}
+
+#if defined(_KERNEL) && defined(HAVE_SPL)
+/* Namespace manipulation */
+EXPORT_SYMBOL(spa_lookup);
+EXPORT_SYMBOL(spa_add);
+EXPORT_SYMBOL(spa_remove);
+EXPORT_SYMBOL(spa_next);
+
+/* Refcount functions */
+EXPORT_SYMBOL(spa_open_ref);
+EXPORT_SYMBOL(spa_close);
+EXPORT_SYMBOL(spa_refcount_zero);
+
+/* Pool configuration lock */
+EXPORT_SYMBOL(spa_config_tryenter);
+EXPORT_SYMBOL(spa_config_enter);
+EXPORT_SYMBOL(spa_config_exit);
+EXPORT_SYMBOL(spa_config_held);
+
+/* Pool vdev add/remove lock */
+EXPORT_SYMBOL(spa_vdev_enter);
+EXPORT_SYMBOL(spa_vdev_exit);
+
+/* Pool vdev state change lock */
+EXPORT_SYMBOL(spa_vdev_state_enter);
+EXPORT_SYMBOL(spa_vdev_state_exit);
+
+/* Accessor functions */
+EXPORT_SYMBOL(spa_shutting_down);
+EXPORT_SYMBOL(spa_get_dsl);
+EXPORT_SYMBOL(spa_get_rootblkptr);
+EXPORT_SYMBOL(spa_set_rootblkptr);
+EXPORT_SYMBOL(spa_altroot);
+EXPORT_SYMBOL(spa_sync_pass);
+EXPORT_SYMBOL(spa_name);
+EXPORT_SYMBOL(spa_guid);
+EXPORT_SYMBOL(spa_last_synced_txg);
+EXPORT_SYMBOL(spa_first_txg);
+EXPORT_SYMBOL(spa_syncing_txg);
+EXPORT_SYMBOL(spa_version);
+EXPORT_SYMBOL(spa_state);
+EXPORT_SYMBOL(spa_load_state);
+EXPORT_SYMBOL(spa_freeze_txg);
+EXPORT_SYMBOL(spa_get_asize);
+EXPORT_SYMBOL(spa_get_dspace);
+EXPORT_SYMBOL(spa_update_dspace);
+EXPORT_SYMBOL(spa_deflate);
+EXPORT_SYMBOL(spa_normal_class);
+EXPORT_SYMBOL(spa_log_class);
+EXPORT_SYMBOL(spa_max_replication);
+EXPORT_SYMBOL(spa_prev_software_version);
+EXPORT_SYMBOL(spa_get_failmode);
+EXPORT_SYMBOL(spa_suspended);
+EXPORT_SYMBOL(spa_bootfs);
+EXPORT_SYMBOL(spa_delegation);
+EXPORT_SYMBOL(spa_meta_objset);
+EXPORT_SYMBOL(spa_maxblocksize);
+
+/* Miscellaneous support routines */
+EXPORT_SYMBOL(spa_rename);
+EXPORT_SYMBOL(spa_guid_exists);
+EXPORT_SYMBOL(spa_strdup);
+EXPORT_SYMBOL(spa_strfree);
+EXPORT_SYMBOL(spa_get_random);
+EXPORT_SYMBOL(spa_generate_guid);
+EXPORT_SYMBOL(snprintf_blkptr);
+EXPORT_SYMBOL(spa_freeze);
+EXPORT_SYMBOL(spa_upgrade);
+EXPORT_SYMBOL(spa_evict_all);
+EXPORT_SYMBOL(spa_lookup_by_guid);
+EXPORT_SYMBOL(spa_has_spare);
+EXPORT_SYMBOL(dva_get_dsize_sync);
+EXPORT_SYMBOL(bp_get_dsize_sync);
+EXPORT_SYMBOL(bp_get_dsize);
+EXPORT_SYMBOL(spa_has_slogs);
+EXPORT_SYMBOL(spa_is_root);
+EXPORT_SYMBOL(spa_writeable);
+EXPORT_SYMBOL(spa_mode);
+
+EXPORT_SYMBOL(spa_namespace_lock);
+
+module_param(zfs_flags, uint, 0644);
+MODULE_PARM_DESC(zfs_flags, "Set additional debugging flags");
+
+module_param(zfs_recover, int, 0644);
+MODULE_PARM_DESC(zfs_recover, "Set to attempt to recover from fatal errors");
+
+module_param(zfs_free_leak_on_eio, int, 0644);
+MODULE_PARM_DESC(zfs_free_leak_on_eio,
+	"Set to ignore IO errors during free and permanently leak the space");
+
+module_param(zfs_deadman_synctime_ms, ulong, 0644);
+MODULE_PARM_DESC(zfs_deadman_synctime_ms, "Expiration time in milliseconds");
+
+module_param(zfs_deadman_enabled, int, 0644);
+MODULE_PARM_DESC(zfs_deadman_enabled, "Enable deadman timer");
+
+module_param(spa_asize_inflation, int, 0644);
+MODULE_PARM_DESC(spa_asize_inflation,
+	"SPA size estimate multiplication factor");
+
+module_param(spa_slop_shift, int, 0644);
+MODULE_PARM_DESC(spa_slop_shift, "Reserved free space in pool");
+#endif
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/module/zfs/spa_stats.c
@@ -0,0 +1,683 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+#include <sys/zfs_context.h>
+#include <sys/spa_impl.h>
+
+/*
+ * Keeps stats on last N reads per spa_t, disabled by default.
+ */
+int zfs_read_history = 0;
+
+/*
+ * Include cache hits in history, disabled by default.
+ */
+int zfs_read_history_hits = 0;
+
+/*
+ * Keeps stats on the last N txgs, disabled by default.
+ */
+int zfs_txg_history = 0;
+
+/*
+ * ==========================================================================
+ * SPA Read History Routines
+ * ==========================================================================
+ */
+
+/*
+ * Read statistics - Information exported regarding each arc_read call
+ */
+typedef struct spa_read_history {
+	uint64_t	uid;		/* unique identifier */
+	hrtime_t	start;		/* time read completed */
+	uint64_t	objset;		/* read from this objset */
+	uint64_t	object;		/* read of this object number */
+	uint64_t	level;		/* block's indirection level */
+	uint64_t	blkid;		/* read of this block id */
+	char		origin[24];	/* read originated from here */
+	uint32_t	aflags;		/* ARC flags (cached, prefetch, etc.) */
+	pid_t		pid;		/* PID of task doing read */
+	char		comm[16];	/* process name of task doing read */
+	list_node_t	srh_link;
+} spa_read_history_t;
+
+static int
+spa_read_history_headers(char *buf, size_t size)
+{
+	(void) snprintf(buf, size, "%-8s %-16s %-8s %-8s %-8s %-8s %-8s "
+	    "%-24s %-8s %-16s\n", "UID", "start", "objset", "object",
+	    "level", "blkid", "aflags", "origin", "pid", "process");
+
+	return (0);
+}
+
+static int
+spa_read_history_data(char *buf, size_t size, void *data)
+{
+	spa_read_history_t *srh = (spa_read_history_t *)data;
+
+	(void) snprintf(buf, size, "%-8llu %-16llu 0x%-6llx "
+	    "%-8lli %-8lli %-8lli 0x%-6x %-24s %-8i %-16s\n",
+	    (u_longlong_t)srh->uid, srh->start,
+	    (longlong_t)srh->objset, (longlong_t)srh->object,
+	    (longlong_t)srh->level, (longlong_t)srh->blkid,
+	    srh->aflags, srh->origin, srh->pid, srh->comm);
+
+	return (0);
+}
+
+/*
+ * Calculate the address for the next spa_stats_history_t entry.  The
+ * ssh->lock will be held until ksp->ks_ndata entries are processed.
+ */
+static void *
+spa_read_history_addr(kstat_t *ksp, loff_t n)
+{
+	spa_t *spa = ksp->ks_private;
+	spa_stats_history_t *ssh = &spa->spa_stats.read_history;
+
+	ASSERT(MUTEX_HELD(&ssh->lock));
+
+	if (n == 0)
+		ssh->private = list_tail(&ssh->list);
+	else if (ssh->private)
+		ssh->private = list_prev(&ssh->list, ssh->private);
+
+	return (ssh->private);
+}
+
+/*
+ * When the kstat is written discard all spa_read_history_t entires.  The
+ * ssh->lock will be held until ksp->ks_ndata entries are processed.
+ */
+static int
+spa_read_history_update(kstat_t *ksp, int rw)
+{
+	spa_t *spa = ksp->ks_private;
+	spa_stats_history_t *ssh = &spa->spa_stats.read_history;
+
+	if (rw == KSTAT_WRITE) {
+		spa_read_history_t *srh;
+
+		while ((srh = list_remove_head(&ssh->list))) {
+			ssh->size--;
+			kmem_free(srh, sizeof (spa_read_history_t));
+		}
+
+		ASSERT3U(ssh->size, ==, 0);
+	}
+
+	ksp->ks_ndata = ssh->size;
+	ksp->ks_data_size = ssh->size * sizeof (spa_read_history_t);
+
+	return (0);
+}
+
+static void
+spa_read_history_init(spa_t *spa)
+{
+	spa_stats_history_t *ssh = &spa->spa_stats.read_history;
+	char name[KSTAT_STRLEN];
+	kstat_t *ksp;
+
+	mutex_init(&ssh->lock, NULL, MUTEX_DEFAULT, NULL);
+	list_create(&ssh->list, sizeof (spa_read_history_t),
+	    offsetof(spa_read_history_t, srh_link));
+
+	ssh->count = 0;
+	ssh->size = 0;
+	ssh->private = NULL;
+
+	(void) snprintf(name, KSTAT_STRLEN, "zfs/%s", spa_name(spa));
+
+	ksp = kstat_create(name, 0, "reads", "misc",
+	    KSTAT_TYPE_RAW, 0, KSTAT_FLAG_VIRTUAL);
+	ssh->kstat = ksp;
+
+	if (ksp) {
+		ksp->ks_lock = &ssh->lock;
+		ksp->ks_data = NULL;
+		ksp->ks_private = spa;
+		ksp->ks_update = spa_read_history_update;
+		kstat_set_raw_ops(ksp, spa_read_history_headers,
+		    spa_read_history_data, spa_read_history_addr);
+		kstat_install(ksp);
+	}
+}
+
+static void
+spa_read_history_destroy(spa_t *spa)
+{
+	spa_stats_history_t *ssh = &spa->spa_stats.read_history;
+	spa_read_history_t *srh;
+	kstat_t *ksp;
+
+	ksp = ssh->kstat;
+	if (ksp)
+		kstat_delete(ksp);
+
+	mutex_enter(&ssh->lock);
+	while ((srh = list_remove_head(&ssh->list))) {
+		ssh->size--;
+		kmem_free(srh, sizeof (spa_read_history_t));
+	}
+
+	ASSERT3U(ssh->size, ==, 0);
+	list_destroy(&ssh->list);
+	mutex_exit(&ssh->lock);
+
+	mutex_destroy(&ssh->lock);
+}
+
+void
+spa_read_history_add(spa_t *spa, const zbookmark_phys_t *zb, uint32_t aflags)
+{
+	spa_stats_history_t *ssh = &spa->spa_stats.read_history;
+	spa_read_history_t *srh, *rm;
+
+	ASSERT3P(spa, !=, NULL);
+	ASSERT3P(zb,  !=, NULL);
+
+	if (zfs_read_history == 0 && ssh->size == 0)
+		return;
+
+	if (zfs_read_history_hits == 0 && (aflags & ARC_FLAG_CACHED))
+		return;
+
+	srh = kmem_zalloc(sizeof (spa_read_history_t), KM_SLEEP);
+	strlcpy(srh->comm, getcomm(), sizeof (srh->comm));
+	srh->start  = gethrtime();
+	srh->objset = zb->zb_objset;
+	srh->object = zb->zb_object;
+	srh->level  = zb->zb_level;
+	srh->blkid  = zb->zb_blkid;
+	srh->aflags = aflags;
+	srh->pid    = getpid();
+
+	mutex_enter(&ssh->lock);
+
+	srh->uid = ssh->count++;
+	list_insert_head(&ssh->list, srh);
+	ssh->size++;
+
+	while (ssh->size > zfs_read_history) {
+		ssh->size--;
+		rm = list_remove_tail(&ssh->list);
+		kmem_free(rm, sizeof (spa_read_history_t));
+	}
+
+	mutex_exit(&ssh->lock);
+}
+
+/*
+ * ==========================================================================
+ * SPA TXG History Routines
+ * ==========================================================================
+ */
+
+/*
+ * Txg statistics - Information exported regarding each txg sync
+ */
+
+typedef struct spa_txg_history {
+	uint64_t	txg;		/* txg id */
+	txg_state_t	state;		/* active txg state */
+	uint64_t	nread;		/* number of bytes read */
+	uint64_t	nwritten;	/* number of bytes written */
+	uint64_t	reads;		/* number of read operations */
+	uint64_t	writes;		/* number of write operations */
+	uint64_t	ndirty;		/* number of dirty bytes */
+	hrtime_t	times[TXG_STATE_COMMITTED]; /* completion times */
+	list_node_t	sth_link;
+} spa_txg_history_t;
+
+static int
+spa_txg_history_headers(char *buf, size_t size)
+{
+	(void) snprintf(buf, size, "%-8s %-16s %-5s %-12s %-12s %-12s "
+	    "%-8s %-8s %-12s %-12s %-12s %-12s\n", "txg", "birth", "state",
+	    "ndirty", "nread", "nwritten", "reads", "writes",
+	    "otime", "qtime", "wtime", "stime");
+
+	return (0);
+}
+
+static int
+spa_txg_history_data(char *buf, size_t size, void *data)
+{
+	spa_txg_history_t *sth = (spa_txg_history_t *)data;
+	uint64_t open = 0, quiesce = 0, wait = 0, sync = 0;
+	char state;
+
+	switch (sth->state) {
+		case TXG_STATE_BIRTH:		state = 'B';	break;
+		case TXG_STATE_OPEN:		state = 'O';	break;
+		case TXG_STATE_QUIESCED:	state = 'Q';	break;
+		case TXG_STATE_WAIT_FOR_SYNC:	state = 'W';	break;
+		case TXG_STATE_SYNCED:		state = 'S';	break;
+		case TXG_STATE_COMMITTED:	state = 'C';	break;
+		default:			state = '?';	break;
+	}
+
+	if (sth->times[TXG_STATE_OPEN])
+		open = sth->times[TXG_STATE_OPEN] -
+		    sth->times[TXG_STATE_BIRTH];
+
+	if (sth->times[TXG_STATE_QUIESCED])
+		quiesce = sth->times[TXG_STATE_QUIESCED] -
+		    sth->times[TXG_STATE_OPEN];
+
+	if (sth->times[TXG_STATE_WAIT_FOR_SYNC])
+		wait = sth->times[TXG_STATE_WAIT_FOR_SYNC] -
+		    sth->times[TXG_STATE_QUIESCED];
+
+	if (sth->times[TXG_STATE_SYNCED])
+		sync = sth->times[TXG_STATE_SYNCED] -
+		    sth->times[TXG_STATE_WAIT_FOR_SYNC];
+
+	(void) snprintf(buf, size, "%-8llu %-16llu %-5c %-12llu "
+	    "%-12llu %-12llu %-8llu %-8llu %-12llu %-12llu %-12llu %-12llu\n",
+	    (longlong_t)sth->txg, sth->times[TXG_STATE_BIRTH], state,
+	    (u_longlong_t)sth->ndirty,
+	    (u_longlong_t)sth->nread, (u_longlong_t)sth->nwritten,
+	    (u_longlong_t)sth->reads, (u_longlong_t)sth->writes,
+	    (u_longlong_t)open, (u_longlong_t)quiesce, (u_longlong_t)wait,
+	    (u_longlong_t)sync);
+
+	return (0);
+}
+
+/*
+ * Calculate the address for the next spa_stats_history_t entry.  The
+ * ssh->lock will be held until ksp->ks_ndata entries are processed.
+ */
+static void *
+spa_txg_history_addr(kstat_t *ksp, loff_t n)
+{
+	spa_t *spa = ksp->ks_private;
+	spa_stats_history_t *ssh = &spa->spa_stats.txg_history;
+
+	ASSERT(MUTEX_HELD(&ssh->lock));
+
+	if (n == 0)
+		ssh->private = list_tail(&ssh->list);
+	else if (ssh->private)
+		ssh->private = list_prev(&ssh->list, ssh->private);
+
+	return (ssh->private);
+}
+
+/*
+ * When the kstat is written discard all spa_txg_history_t entires.  The
+ * ssh->lock will be held until ksp->ks_ndata entries are processed.
+ */
+static int
+spa_txg_history_update(kstat_t *ksp, int rw)
+{
+	spa_t *spa = ksp->ks_private;
+	spa_stats_history_t *ssh = &spa->spa_stats.txg_history;
+
+	ASSERT(MUTEX_HELD(&ssh->lock));
+
+	if (rw == KSTAT_WRITE) {
+		spa_txg_history_t *sth;
+
+		while ((sth = list_remove_head(&ssh->list))) {
+			ssh->size--;
+			kmem_free(sth, sizeof (spa_txg_history_t));
+		}
+
+		ASSERT3U(ssh->size, ==, 0);
+	}
+
+	ksp->ks_ndata = ssh->size;
+	ksp->ks_data_size = ssh->size * sizeof (spa_txg_history_t);
+
+	return (0);
+}
+
+static void
+spa_txg_history_init(spa_t *spa)
+{
+	spa_stats_history_t *ssh = &spa->spa_stats.txg_history;
+	char name[KSTAT_STRLEN];
+	kstat_t *ksp;
+
+	mutex_init(&ssh->lock, NULL, MUTEX_DEFAULT, NULL);
+	list_create(&ssh->list, sizeof (spa_txg_history_t),
+	    offsetof(spa_txg_history_t, sth_link));
+
+	ssh->count = 0;
+	ssh->size = 0;
+	ssh->private = NULL;
+
+	(void) snprintf(name, KSTAT_STRLEN, "zfs/%s", spa_name(spa));
+
+	ksp = kstat_create(name, 0, "txgs", "misc",
+	    KSTAT_TYPE_RAW, 0, KSTAT_FLAG_VIRTUAL);
+	ssh->kstat = ksp;
+
+	if (ksp) {
+		ksp->ks_lock = &ssh->lock;
+		ksp->ks_data = NULL;
+		ksp->ks_private = spa;
+		ksp->ks_update = spa_txg_history_update;
+		kstat_set_raw_ops(ksp, spa_txg_history_headers,
+		    spa_txg_history_data, spa_txg_history_addr);
+		kstat_install(ksp);
+	}
+}
+
+static void
+spa_txg_history_destroy(spa_t *spa)
+{
+	spa_stats_history_t *ssh = &spa->spa_stats.txg_history;
+	spa_txg_history_t *sth;
+	kstat_t *ksp;
+
+	ksp = ssh->kstat;
+	if (ksp)
+		kstat_delete(ksp);
+
+	mutex_enter(&ssh->lock);
+	while ((sth = list_remove_head(&ssh->list))) {
+		ssh->size--;
+		kmem_free(sth, sizeof (spa_txg_history_t));
+	}
+
+	ASSERT3U(ssh->size, ==, 0);
+	list_destroy(&ssh->list);
+	mutex_exit(&ssh->lock);
+
+	mutex_destroy(&ssh->lock);
+}
+
+/*
+ * Add a new txg to historical record.
+ */
+void
+spa_txg_history_add(spa_t *spa, uint64_t txg, hrtime_t birth_time)
+{
+	spa_stats_history_t *ssh = &spa->spa_stats.txg_history;
+	spa_txg_history_t *sth, *rm;
+
+	if (zfs_txg_history == 0 && ssh->size == 0)
+		return;
+
+	sth = kmem_zalloc(sizeof (spa_txg_history_t), KM_SLEEP);
+	sth->txg = txg;
+	sth->state = TXG_STATE_OPEN;
+	sth->times[TXG_STATE_BIRTH] = birth_time;
+
+	mutex_enter(&ssh->lock);
+
+	list_insert_head(&ssh->list, sth);
+	ssh->size++;
+
+	while (ssh->size > zfs_txg_history) {
+		ssh->size--;
+		rm = list_remove_tail(&ssh->list);
+		kmem_free(rm, sizeof (spa_txg_history_t));
+	}
+
+	mutex_exit(&ssh->lock);
+}
+
+/*
+ * Set txg state completion time and increment current state.
+ */
+int
+spa_txg_history_set(spa_t *spa, uint64_t txg, txg_state_t completed_state,
+    hrtime_t completed_time)
+{
+	spa_stats_history_t *ssh = &spa->spa_stats.txg_history;
+	spa_txg_history_t *sth;
+	int error = ENOENT;
+
+	if (zfs_txg_history == 0)
+		return (0);
+
+	mutex_enter(&ssh->lock);
+	for (sth = list_head(&ssh->list); sth != NULL;
+	    sth = list_next(&ssh->list, sth)) {
+		if (sth->txg == txg) {
+			sth->times[completed_state] = completed_time;
+			sth->state++;
+			error = 0;
+			break;
+		}
+	}
+	mutex_exit(&ssh->lock);
+
+	return (error);
+}
+
+/*
+ * Set txg IO stats.
+ */
+int
+spa_txg_history_set_io(spa_t *spa, uint64_t txg, uint64_t nread,
+    uint64_t nwritten, uint64_t reads, uint64_t writes, uint64_t ndirty)
+{
+	spa_stats_history_t *ssh = &spa->spa_stats.txg_history;
+	spa_txg_history_t *sth;
+	int error = ENOENT;
+
+	if (zfs_txg_history == 0)
+		return (0);
+
+	mutex_enter(&ssh->lock);
+	for (sth = list_head(&ssh->list); sth != NULL;
+	    sth = list_next(&ssh->list, sth)) {
+		if (sth->txg == txg) {
+			sth->nread = nread;
+			sth->nwritten = nwritten;
+			sth->reads = reads;
+			sth->writes = writes;
+			sth->ndirty = ndirty;
+			error = 0;
+			break;
+		}
+	}
+	mutex_exit(&ssh->lock);
+
+	return (error);
+}
+
+/*
+ * ==========================================================================
+ * SPA TX Assign Histogram Routines
+ * ==========================================================================
+ */
+
+/*
+ * Tx statistics - Information exported regarding dmu_tx_assign time.
+ */
+
+/*
+ * When the kstat is written zero all buckets.  When the kstat is read
+ * count the number of trailing buckets set to zero and update ks_ndata
+ * such that they are not output.
+ */
+static int
+spa_tx_assign_update(kstat_t *ksp, int rw)
+{
+	spa_t *spa = ksp->ks_private;
+	spa_stats_history_t *ssh = &spa->spa_stats.tx_assign_histogram;
+	int i;
+
+	if (rw == KSTAT_WRITE) {
+		for (i = 0; i < ssh->count; i++)
+			((kstat_named_t *)ssh->private)[i].value.ui64 = 0;
+	}
+
+	for (i = ssh->count; i > 0; i--)
+		if (((kstat_named_t *)ssh->private)[i-1].value.ui64 != 0)
+			break;
+
+	ksp->ks_ndata = i;
+	ksp->ks_data_size = i * sizeof (kstat_named_t);
+
+	return (0);
+}
+
+static void
+spa_tx_assign_init(spa_t *spa)
+{
+	spa_stats_history_t *ssh = &spa->spa_stats.tx_assign_histogram;
+	char name[KSTAT_STRLEN];
+	kstat_named_t *ks;
+	kstat_t *ksp;
+	int i;
+
+	mutex_init(&ssh->lock, NULL, MUTEX_DEFAULT, NULL);
+
+	ssh->count = 42; /* power of two buckets for 1ns to 2,199s */
+	ssh->size = ssh->count * sizeof (kstat_named_t);
+	ssh->private = kmem_alloc(ssh->size, KM_SLEEP);
+
+	(void) snprintf(name, KSTAT_STRLEN, "zfs/%s", spa_name(spa));
+
+	for (i = 0; i < ssh->count; i++) {
+		ks = &((kstat_named_t *)ssh->private)[i];
+		ks->data_type = KSTAT_DATA_UINT64;
+		ks->value.ui64 = 0;
+		(void) snprintf(ks->name, KSTAT_STRLEN, "%llu ns",
+		    (u_longlong_t)1 << i);
+	}
+
+	ksp = kstat_create(name, 0, "dmu_tx_assign", "misc",
+	    KSTAT_TYPE_NAMED, 0, KSTAT_FLAG_VIRTUAL);
+	ssh->kstat = ksp;
+
+	if (ksp) {
+		ksp->ks_lock = &ssh->lock;
+		ksp->ks_data = ssh->private;
+		ksp->ks_ndata = ssh->count;
+		ksp->ks_data_size = ssh->size;
+		ksp->ks_private = spa;
+		ksp->ks_update = spa_tx_assign_update;
+		kstat_install(ksp);
+	}
+}
+
+static void
+spa_tx_assign_destroy(spa_t *spa)
+{
+	spa_stats_history_t *ssh = &spa->spa_stats.tx_assign_histogram;
+	kstat_t *ksp;
+
+	ksp = ssh->kstat;
+	if (ksp)
+		kstat_delete(ksp);
+
+	kmem_free(ssh->private, ssh->size);
+	mutex_destroy(&ssh->lock);
+}
+
+void
+spa_tx_assign_add_nsecs(spa_t *spa, uint64_t nsecs)
+{
+	spa_stats_history_t *ssh = &spa->spa_stats.tx_assign_histogram;
+	uint64_t idx = 0;
+
+	while (((1 << idx) < nsecs) && (idx < ssh->size - 1))
+		idx++;
+
+	atomic_inc_64(&((kstat_named_t *)ssh->private)[idx].value.ui64);
+}
+
+/*
+ * ==========================================================================
+ * SPA IO History Routines
+ * ==========================================================================
+ */
+static int
+spa_io_history_update(kstat_t *ksp, int rw)
+{
+	if (rw == KSTAT_WRITE)
+		memset(ksp->ks_data, 0, ksp->ks_data_size);
+
+	return (0);
+}
+
+static void
+spa_io_history_init(spa_t *spa)
+{
+	spa_stats_history_t *ssh = &spa->spa_stats.io_history;
+	char name[KSTAT_STRLEN];
+	kstat_t *ksp;
+
+	mutex_init(&ssh->lock, NULL, MUTEX_DEFAULT, NULL);
+
+	(void) snprintf(name, KSTAT_STRLEN, "zfs/%s", spa_name(spa));
+
+	ksp = kstat_create(name, 0, "io", "disk", KSTAT_TYPE_IO, 1, 0);
+	ssh->kstat = ksp;
+
+	if (ksp) {
+		ksp->ks_lock = &ssh->lock;
+		ksp->ks_private = spa;
+		ksp->ks_update = spa_io_history_update;
+		kstat_install(ksp);
+	}
+}
+
+static void
+spa_io_history_destroy(spa_t *spa)
+{
+	spa_stats_history_t *ssh = &spa->spa_stats.io_history;
+
+	if (ssh->kstat)
+		kstat_delete(ssh->kstat);
+
+	mutex_destroy(&ssh->lock);
+}
+
+void
+spa_stats_init(spa_t *spa)
+{
+	spa_read_history_init(spa);
+	spa_txg_history_init(spa);
+	spa_tx_assign_init(spa);
+	spa_io_history_init(spa);
+}
+
+void
+spa_stats_destroy(spa_t *spa)
+{
+	spa_tx_assign_destroy(spa);
+	spa_txg_history_destroy(spa);
+	spa_read_history_destroy(spa);
+	spa_io_history_destroy(spa);
+}
+
+#if defined(_KERNEL) && defined(HAVE_SPL)
+module_param(zfs_read_history, int, 0644);
+MODULE_PARM_DESC(zfs_read_history, "Historic statistics for the last N reads");
+
+module_param(zfs_read_history_hits, int, 0644);
+MODULE_PARM_DESC(zfs_read_history_hits, "Include cache hits in read history");
+
+module_param(zfs_txg_history, int, 0644);
+MODULE_PARM_DESC(zfs_txg_history, "Historic statistics for the last N txgs");
+#endif
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/module/zfs/space_map.c
@@ -0,0 +1,551 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * Copyright (c) 2012, 2014 by Delphix. All rights reserved.
+ */
+
+#include <sys/zfs_context.h>
+#include <sys/spa.h>
+#include <sys/dmu.h>
+#include <sys/dmu_tx.h>
+#include <sys/dnode.h>
+#include <sys/dsl_pool.h>
+#include <sys/zio.h>
+#include <sys/space_map.h>
+#include <sys/refcount.h>
+#include <sys/zfeature.h>
+
+/*
+ * The data for a given space map can be kept on blocks of any size.
+ * Larger blocks entail fewer i/o operations, but they also cause the
+ * DMU to keep more data in-core, and also to waste more i/o bandwidth
+ * when only a few blocks have changed since the last transaction group.
+ */
+int space_map_blksz = (1 << 12);
+
+/*
+ * Load the space map disk into the specified range tree. Segments of maptype
+ * are added to the range tree, other segment types are removed.
+ *
+ * Note: space_map_load() will drop sm_lock across dmu_read() calls.
+ * The caller must be OK with this.
+ */
+int
+space_map_load(space_map_t *sm, range_tree_t *rt, maptype_t maptype)
+{
+	uint64_t *entry, *entry_map, *entry_map_end;
+	uint64_t bufsize, size, offset, end, space;
+	int error = 0;
+
+	ASSERT(MUTEX_HELD(sm->sm_lock));
+
+	end = space_map_length(sm);
+	space = space_map_allocated(sm);
+
+	VERIFY0(range_tree_space(rt));
+
+	if (maptype == SM_FREE) {
+		range_tree_add(rt, sm->sm_start, sm->sm_size);
+		space = sm->sm_size - space;
+	}
+
+	bufsize = MAX(sm->sm_blksz, SPA_MINBLOCKSIZE);
+	entry_map = zio_buf_alloc(bufsize);
+
+	mutex_exit(sm->sm_lock);
+	if (end > bufsize) {
+		dmu_prefetch(sm->sm_os, space_map_object(sm), bufsize,
+		    end - bufsize);
+	}
+	mutex_enter(sm->sm_lock);
+
+	for (offset = 0; offset < end; offset += bufsize) {
+		size = MIN(end - offset, bufsize);
+		VERIFY(P2PHASE(size, sizeof (uint64_t)) == 0);
+		VERIFY(size != 0);
+		ASSERT3U(sm->sm_blksz, !=, 0);
+
+		dprintf("object=%llu  offset=%llx  size=%llx\n",
+		    space_map_object(sm), offset, size);
+
+		mutex_exit(sm->sm_lock);
+		error = dmu_read(sm->sm_os, space_map_object(sm), offset, size,
+		    entry_map, DMU_READ_PREFETCH);
+		mutex_enter(sm->sm_lock);
+		if (error != 0)
+			break;
+
+		entry_map_end = entry_map + (size / sizeof (uint64_t));
+		for (entry = entry_map; entry < entry_map_end; entry++) {
+			uint64_t e = *entry;
+			uint64_t offset, size;
+
+			if (SM_DEBUG_DECODE(e))		/* Skip debug entries */
+				continue;
+
+			offset = (SM_OFFSET_DECODE(e) << sm->sm_shift) +
+			    sm->sm_start;
+			size = SM_RUN_DECODE(e) << sm->sm_shift;
+
+			VERIFY0(P2PHASE(offset, 1ULL << sm->sm_shift));
+			VERIFY0(P2PHASE(size, 1ULL << sm->sm_shift));
+			VERIFY3U(offset, >=, sm->sm_start);
+			VERIFY3U(offset + size, <=, sm->sm_start + sm->sm_size);
+			if (SM_TYPE_DECODE(e) == maptype) {
+				VERIFY3U(range_tree_space(rt) + size, <=,
+				    sm->sm_size);
+				range_tree_add(rt, offset, size);
+			} else {
+				range_tree_remove(rt, offset, size);
+			}
+		}
+	}
+
+	if (error == 0)
+		VERIFY3U(range_tree_space(rt), ==, space);
+	else
+		range_tree_vacate(rt, NULL, NULL);
+
+	zio_buf_free(entry_map, bufsize);
+	return (error);
+}
+
+void
+space_map_histogram_clear(space_map_t *sm)
+{
+	if (sm->sm_dbuf->db_size != sizeof (space_map_phys_t))
+		return;
+
+	bzero(sm->sm_phys->smp_histogram, sizeof (sm->sm_phys->smp_histogram));
+}
+
+boolean_t
+space_map_histogram_verify(space_map_t *sm, range_tree_t *rt)
+{
+	int i;
+
+	/*
+	 * Verify that the in-core range tree does not have any
+	 * ranges smaller than our sm_shift size.
+	 */
+	for (i = 0; i < sm->sm_shift; i++) {
+		if (rt->rt_histogram[i] != 0)
+			return (B_FALSE);
+	}
+	return (B_TRUE);
+}
+
+void
+space_map_histogram_add(space_map_t *sm, range_tree_t *rt, dmu_tx_t *tx)
+{
+	int idx = 0;
+	int i;
+
+	ASSERT(MUTEX_HELD(rt->rt_lock));
+	ASSERT(dmu_tx_is_syncing(tx));
+	VERIFY3U(space_map_object(sm), !=, 0);
+
+	if (sm->sm_dbuf->db_size != sizeof (space_map_phys_t))
+		return;
+
+	dmu_buf_will_dirty(sm->sm_dbuf, tx);
+
+	ASSERT(space_map_histogram_verify(sm, rt));
+
+	/*
+	 * Transfer the content of the range tree histogram to the space
+	 * map histogram. The space map histogram contains 32 buckets ranging
+	 * between 2^sm_shift to 2^(32+sm_shift-1). The range tree,
+	 * however, can represent ranges from 2^0 to 2^63. Since the space
+	 * map only cares about allocatable blocks (minimum of sm_shift) we
+	 * can safely ignore all ranges in the range tree smaller than sm_shift.
+	 */
+	for (i = sm->sm_shift; i < RANGE_TREE_HISTOGRAM_SIZE; i++) {
+
+		/*
+		 * Since the largest histogram bucket in the space map is
+		 * 2^(32+sm_shift-1), we need to normalize the values in
+		 * the range tree for any bucket larger than that size. For
+		 * example given an sm_shift of 9, ranges larger than 2^40
+		 * would get normalized as if they were 1TB ranges. Assume
+		 * the range tree had a count of 5 in the 2^44 (16TB) bucket,
+		 * the calculation below would normalize this to 5 * 2^4 (16).
+		 */
+		ASSERT3U(i, >=, idx + sm->sm_shift);
+		sm->sm_phys->smp_histogram[idx] +=
+		    rt->rt_histogram[i] << (i - idx - sm->sm_shift);
+
+		/*
+		 * Increment the space map's index as long as we haven't
+		 * reached the maximum bucket size. Accumulate all ranges
+		 * larger than the max bucket size into the last bucket.
+		 */
+		if (idx < SPACE_MAP_HISTOGRAM_SIZE - 1) {
+			ASSERT3U(idx + sm->sm_shift, ==, i);
+			idx++;
+			ASSERT3U(idx, <, SPACE_MAP_HISTOGRAM_SIZE);
+		}
+	}
+}
+
+uint64_t
+space_map_entries(space_map_t *sm, range_tree_t *rt)
+{
+	avl_tree_t *t = &rt->rt_root;
+	range_seg_t *rs;
+	uint64_t size, entries;
+
+	/*
+	 * All space_maps always have a debug entry so account for it here.
+	 */
+	entries = 1;
+
+	/*
+	 * Traverse the range tree and calculate the number of space map
+	 * entries that would be required to write out the range tree.
+	 */
+	for (rs = avl_first(t); rs != NULL; rs = AVL_NEXT(t, rs)) {
+		size = (rs->rs_end - rs->rs_start) >> sm->sm_shift;
+		entries += howmany(size, SM_RUN_MAX);
+	}
+	return (entries);
+}
+
+/*
+ * Note: space_map_write() will drop sm_lock across dmu_write() calls.
+ */
+void
+space_map_write(space_map_t *sm, range_tree_t *rt, maptype_t maptype,
+    dmu_tx_t *tx)
+{
+	objset_t *os = sm->sm_os;
+	spa_t *spa = dmu_objset_spa(os);
+	avl_tree_t *t = &rt->rt_root;
+	range_seg_t *rs;
+	uint64_t size, total, rt_space, nodes;
+	uint64_t *entry, *entry_map, *entry_map_end;
+	uint64_t expected_entries, actual_entries = 1;
+
+	ASSERT(MUTEX_HELD(rt->rt_lock));
+	ASSERT(dsl_pool_sync_context(dmu_objset_pool(os)));
+	VERIFY3U(space_map_object(sm), !=, 0);
+	dmu_buf_will_dirty(sm->sm_dbuf, tx);
+
+	/*
+	 * This field is no longer necessary since the in-core space map
+	 * now contains the object number but is maintained for backwards
+	 * compatibility.
+	 */
+	sm->sm_phys->smp_object = sm->sm_object;
+
+	if (range_tree_space(rt) == 0) {
+		VERIFY3U(sm->sm_object, ==, sm->sm_phys->smp_object);
+		return;
+	}
+
+	if (maptype == SM_ALLOC)
+		sm->sm_phys->smp_alloc += range_tree_space(rt);
+	else
+		sm->sm_phys->smp_alloc -= range_tree_space(rt);
+
+	expected_entries = space_map_entries(sm, rt);
+
+	entry_map = zio_buf_alloc(sm->sm_blksz);
+	entry_map_end = entry_map + (sm->sm_blksz / sizeof (uint64_t));
+	entry = entry_map;
+
+	*entry++ = SM_DEBUG_ENCODE(1) |
+	    SM_DEBUG_ACTION_ENCODE(maptype) |
+	    SM_DEBUG_SYNCPASS_ENCODE(spa_sync_pass(spa)) |
+	    SM_DEBUG_TXG_ENCODE(dmu_tx_get_txg(tx));
+
+	total = 0;
+	nodes = avl_numnodes(&rt->rt_root);
+	rt_space = range_tree_space(rt);
+	for (rs = avl_first(t); rs != NULL; rs = AVL_NEXT(t, rs)) {
+		uint64_t start;
+
+		size = (rs->rs_end - rs->rs_start) >> sm->sm_shift;
+		start = (rs->rs_start - sm->sm_start) >> sm->sm_shift;
+
+		total += size << sm->sm_shift;
+
+		while (size != 0) {
+			uint64_t run_len;
+
+			run_len = MIN(size, SM_RUN_MAX);
+
+			if (entry == entry_map_end) {
+				mutex_exit(rt->rt_lock);
+				dmu_write(os, space_map_object(sm),
+				    sm->sm_phys->smp_objsize, sm->sm_blksz,
+				    entry_map, tx);
+				mutex_enter(rt->rt_lock);
+				sm->sm_phys->smp_objsize += sm->sm_blksz;
+				entry = entry_map;
+			}
+
+			*entry++ = SM_OFFSET_ENCODE(start) |
+			    SM_TYPE_ENCODE(maptype) |
+			    SM_RUN_ENCODE(run_len);
+
+			start += run_len;
+			size -= run_len;
+			actual_entries++;
+		}
+	}
+
+	if (entry != entry_map) {
+		size = (entry - entry_map) * sizeof (uint64_t);
+		mutex_exit(rt->rt_lock);
+		dmu_write(os, space_map_object(sm), sm->sm_phys->smp_objsize,
+		    size, entry_map, tx);
+		mutex_enter(rt->rt_lock);
+		sm->sm_phys->smp_objsize += size;
+	}
+	ASSERT3U(expected_entries, ==, actual_entries);
+
+	/*
+	 * Ensure that the space_map's accounting wasn't changed
+	 * while we were in the middle of writing it out.
+	 */
+	VERIFY3U(nodes, ==, avl_numnodes(&rt->rt_root));
+	VERIFY3U(range_tree_space(rt), ==, rt_space);
+	VERIFY3U(range_tree_space(rt), ==, total);
+
+	zio_buf_free(entry_map, sm->sm_blksz);
+}
+
+static int
+space_map_open_impl(space_map_t *sm)
+{
+	int error;
+	u_longlong_t blocks;
+
+	error = dmu_bonus_hold(sm->sm_os, sm->sm_object, sm, &sm->sm_dbuf);
+	if (error)
+		return (error);
+
+	dmu_object_size_from_db(sm->sm_dbuf, &sm->sm_blksz, &blocks);
+	sm->sm_phys = sm->sm_dbuf->db_data;
+	return (0);
+}
+
+int
+space_map_open(space_map_t **smp, objset_t *os, uint64_t object,
+    uint64_t start, uint64_t size, uint8_t shift, kmutex_t *lp)
+{
+	space_map_t *sm;
+	int error;
+
+	ASSERT(*smp == NULL);
+	ASSERT(os != NULL);
+	ASSERT(object != 0);
+
+	sm = kmem_alloc(sizeof (space_map_t), KM_SLEEP);
+
+	sm->sm_start = start;
+	sm->sm_size = size;
+	sm->sm_shift = shift;
+	sm->sm_lock = lp;
+	sm->sm_os = os;
+	sm->sm_object = object;
+	sm->sm_length = 0;
+	sm->sm_alloc = 0;
+	sm->sm_blksz = 0;
+	sm->sm_dbuf = NULL;
+	sm->sm_phys = NULL;
+
+	error = space_map_open_impl(sm);
+	if (error != 0) {
+		space_map_close(sm);
+		return (error);
+	}
+
+	*smp = sm;
+
+	return (0);
+}
+
+void
+space_map_close(space_map_t *sm)
+{
+	if (sm == NULL)
+		return;
+
+	if (sm->sm_dbuf != NULL)
+		dmu_buf_rele(sm->sm_dbuf, sm);
+	sm->sm_dbuf = NULL;
+	sm->sm_phys = NULL;
+
+	kmem_free(sm, sizeof (*sm));
+}
+
+void
+space_map_truncate(space_map_t *sm, dmu_tx_t *tx)
+{
+	objset_t *os = sm->sm_os;
+	spa_t *spa = dmu_objset_spa(os);
+	dmu_object_info_t doi;
+
+	ASSERT(dsl_pool_sync_context(dmu_objset_pool(os)));
+	ASSERT(dmu_tx_is_syncing(tx));
+
+	dmu_object_info_from_db(sm->sm_dbuf, &doi);
+
+	/*
+	 * If the space map has the wrong bonus size (because
+	 * SPA_FEATURE_SPACEMAP_HISTOGRAM has recently been enabled), or
+	 * the wrong block size (because space_map_blksz has changed),
+	 * free and re-allocate its object with the updated sizes.
+	 *
+	 * Otherwise, just truncate the current object.
+	 */
+	if ((spa_feature_is_enabled(spa, SPA_FEATURE_SPACEMAP_HISTOGRAM) &&
+	    doi.doi_bonus_size != sizeof (space_map_phys_t)) ||
+	    doi.doi_data_block_size != space_map_blksz) {
+		zfs_dbgmsg("txg %llu, spa %s, reallocating: "
+		    "old bonus %llu, old blocksz %u", dmu_tx_get_txg(tx),
+		    spa_name(spa), doi.doi_bonus_size, doi.doi_data_block_size);
+
+		space_map_free(sm, tx);
+		dmu_buf_rele(sm->sm_dbuf, sm);
+
+		sm->sm_object = space_map_alloc(sm->sm_os, tx);
+		VERIFY0(space_map_open_impl(sm));
+	} else {
+		VERIFY0(dmu_free_range(os, space_map_object(sm), 0, -1ULL, tx));
+
+		/*
+		 * If the spacemap is reallocated, its histogram
+		 * will be reset.  Do the same in the common case so that
+		 * bugs related to the uncommon case do not go unnoticed.
+		 */
+		bzero(sm->sm_phys->smp_histogram,
+		    sizeof (sm->sm_phys->smp_histogram));
+	}
+
+	dmu_buf_will_dirty(sm->sm_dbuf, tx);
+	sm->sm_phys->smp_objsize = 0;
+	sm->sm_phys->smp_alloc = 0;
+}
+
+/*
+ * Update the in-core space_map allocation and length values.
+ */
+void
+space_map_update(space_map_t *sm)
+{
+	if (sm == NULL)
+		return;
+
+	ASSERT(MUTEX_HELD(sm->sm_lock));
+
+	sm->sm_alloc = sm->sm_phys->smp_alloc;
+	sm->sm_length = sm->sm_phys->smp_objsize;
+}
+
+uint64_t
+space_map_alloc(objset_t *os, dmu_tx_t *tx)
+{
+	spa_t *spa = dmu_objset_spa(os);
+	uint64_t object;
+	int bonuslen;
+
+	if (spa_feature_is_enabled(spa, SPA_FEATURE_SPACEMAP_HISTOGRAM)) {
+		spa_feature_incr(spa, SPA_FEATURE_SPACEMAP_HISTOGRAM, tx);
+		bonuslen = sizeof (space_map_phys_t);
+		ASSERT3U(bonuslen, <=, dmu_bonus_max());
+	} else {
+		bonuslen = SPACE_MAP_SIZE_V0;
+	}
+
+	object = dmu_object_alloc(os,
+	    DMU_OT_SPACE_MAP, space_map_blksz,
+	    DMU_OT_SPACE_MAP_HEADER, bonuslen, tx);
+
+	return (object);
+}
+
+void
+space_map_free(space_map_t *sm, dmu_tx_t *tx)
+{
+	spa_t *spa;
+
+	if (sm == NULL)
+		return;
+
+	spa = dmu_objset_spa(sm->sm_os);
+	if (spa_feature_is_enabled(spa, SPA_FEATURE_SPACEMAP_HISTOGRAM)) {
+		dmu_object_info_t doi;
+
+		dmu_object_info_from_db(sm->sm_dbuf, &doi);
+		if (doi.doi_bonus_size != SPACE_MAP_SIZE_V0) {
+			VERIFY(spa_feature_is_active(spa,
+			    SPA_FEATURE_SPACEMAP_HISTOGRAM));
+			spa_feature_decr(spa,
+			    SPA_FEATURE_SPACEMAP_HISTOGRAM, tx);
+		}
+	}
+
+	VERIFY3U(dmu_object_free(sm->sm_os, space_map_object(sm), tx), ==, 0);
+	sm->sm_object = 0;
+}
+
+uint64_t
+space_map_object(space_map_t *sm)
+{
+	return (sm != NULL ? sm->sm_object : 0);
+}
+
+/*
+ * Returns the already synced, on-disk allocated space.
+ */
+uint64_t
+space_map_allocated(space_map_t *sm)
+{
+	return (sm != NULL ? sm->sm_alloc : 0);
+}
+
+/*
+ * Returns the already synced, on-disk length;
+ */
+uint64_t
+space_map_length(space_map_t *sm)
+{
+	return (sm != NULL ? sm->sm_length : 0);
+}
+
+/*
+ * Returns the allocated space that is currently syncing.
+ */
+int64_t
+space_map_alloc_delta(space_map_t *sm)
+{
+	if (sm == NULL)
+		return (0);
+	ASSERT(sm->sm_dbuf != NULL);
+	return (sm->sm_phys->smp_alloc - space_map_allocated(sm));
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/module/zfs/space_reftree.c
@@ -0,0 +1,159 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * Copyright (c) 2013 by Delphix. All rights reserved.
+ */
+
+#include <sys/zfs_context.h>
+#include <sys/range_tree.h>
+#include <sys/space_reftree.h>
+
+/*
+ * Space reference trees.
+ *
+ * A range tree is a collection of integers.  Every integer is either
+ * in the tree, or it's not.  A space reference tree generalizes
+ * the idea: it allows its members to have arbitrary reference counts,
+ * as opposed to the implicit reference count of 0 or 1 in a range tree.
+ * This representation comes in handy when computing the union or
+ * intersection of multiple space maps.  For example, the union of
+ * N range trees is the subset of the reference tree with refcnt >= 1.
+ * The intersection of N range trees is the subset with refcnt >= N.
+ *
+ * [It's very much like a Fourier transform.  Unions and intersections
+ * are hard to perform in the 'range tree domain', so we convert the trees
+ * into the 'reference count domain', where it's trivial, then invert.]
+ *
+ * vdev_dtl_reassess() uses computations of this form to determine
+ * DTL_MISSING and DTL_OUTAGE for interior vdevs -- e.g. a RAID-Z vdev
+ * has an outage wherever refcnt >= vdev_nparity + 1, and a mirror vdev
+ * has an outage wherever refcnt >= vdev_children.
+ */
+static int
+space_reftree_compare(const void *x1, const void *x2)
+{
+	const space_ref_t *sr1 = x1;
+	const space_ref_t *sr2 = x2;
+
+	if (sr1->sr_offset < sr2->sr_offset)
+		return (-1);
+	if (sr1->sr_offset > sr2->sr_offset)
+		return (1);
+
+	if (sr1 < sr2)
+		return (-1);
+	if (sr1 > sr2)
+		return (1);
+
+	return (0);
+}
+
+void
+space_reftree_create(avl_tree_t *t)
+{
+	avl_create(t, space_reftree_compare,
+	    sizeof (space_ref_t), offsetof(space_ref_t, sr_node));
+}
+
+void
+space_reftree_destroy(avl_tree_t *t)
+{
+	space_ref_t *sr;
+	void *cookie = NULL;
+
+	while ((sr = avl_destroy_nodes(t, &cookie)) != NULL)
+		kmem_free(sr, sizeof (*sr));
+
+	avl_destroy(t);
+}
+
+static void
+space_reftree_add_node(avl_tree_t *t, uint64_t offset, int64_t refcnt)
+{
+	space_ref_t *sr;
+
+	sr = kmem_alloc(sizeof (*sr), KM_SLEEP);
+	sr->sr_offset = offset;
+	sr->sr_refcnt = refcnt;
+
+	avl_add(t, sr);
+}
+
+void
+space_reftree_add_seg(avl_tree_t *t, uint64_t start, uint64_t end,
+	int64_t refcnt)
+{
+	space_reftree_add_node(t, start, refcnt);
+	space_reftree_add_node(t, end, -refcnt);
+}
+
+/*
+ * Convert (or add) a range tree into a reference tree.
+ */
+void
+space_reftree_add_map(avl_tree_t *t, range_tree_t *rt, int64_t refcnt)
+{
+	range_seg_t *rs;
+
+	ASSERT(MUTEX_HELD(rt->rt_lock));
+
+	for (rs = avl_first(&rt->rt_root); rs; rs = AVL_NEXT(&rt->rt_root, rs))
+		space_reftree_add_seg(t, rs->rs_start, rs->rs_end, refcnt);
+}
+
+/*
+ * Convert a reference tree into a range tree.  The range tree will contain
+ * all members of the reference tree for which refcnt >= minref.
+ */
+void
+space_reftree_generate_map(avl_tree_t *t, range_tree_t *rt, int64_t minref)
+{
+	uint64_t start = -1ULL;
+	int64_t refcnt = 0;
+	space_ref_t *sr;
+
+	ASSERT(MUTEX_HELD(rt->rt_lock));
+
+	range_tree_vacate(rt, NULL, NULL);
+
+	for (sr = avl_first(t); sr != NULL; sr = AVL_NEXT(t, sr)) {
+		refcnt += sr->sr_refcnt;
+		if (refcnt >= minref) {
+			if (start == -1ULL) {
+				start = sr->sr_offset;
+			}
+		} else {
+			if (start != -1ULL) {
+				uint64_t end = sr->sr_offset;
+				ASSERT(start <= end);
+				if (end > start)
+					range_tree_add(rt, start, end - start);
+				start = -1ULL;
+			}
+		}
+	}
+	ASSERT(refcnt == 0);
+	ASSERT(start == -1ULL);
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/module/zfs/trace.c
@@ -0,0 +1,50 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Each Linux tracepoints subsystem must define CREATE_TRACE_POINTS in one
+ * (and only one) C file, so this dummy file exists for that purpose.
+ */
+
+#include <sys/multilist.h>
+#include <sys/arc_impl.h>
+#include <sys/vdev_impl.h>
+#include <sys/zio.h>
+#include <sys/dbuf.h>
+#include <sys/dmu_objset.h>
+#include <sys/dsl_dataset.h>
+#include <sys/dmu_tx.h>
+#include <sys/dnode.h>
+#include <sys/multilist.h>
+#include <sys/zfs_znode.h>
+#include <sys/zil_impl.h>
+#include <sys/zrlock.h>
+
+#define	CREATE_TRACE_POINTS
+#include <sys/trace.h>
+#include <sys/trace_acl.h>
+#include <sys/trace_arc.h>
+#include <sys/trace_dbuf.h>
+#include <sys/trace_dmu.h>
+#include <sys/trace_dnode.h>
+#include <sys/trace_multilist.h>
+#include <sys/trace_txg.h>
+#include <sys/trace_zil.h>
+#include <sys/trace_zrlock.h>
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/module/zfs/txg.c
@@ -0,0 +1,952 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Portions Copyright 2011 Martin Matuska
+ * Copyright (c) 2012, 2014 by Delphix. All rights reserved.
+ */
+
+#include <sys/zfs_context.h>
+#include <sys/txg_impl.h>
+#include <sys/dmu_impl.h>
+#include <sys/spa_impl.h>
+#include <sys/dmu_tx.h>
+#include <sys/dsl_pool.h>
+#include <sys/dsl_scan.h>
+#include <sys/callb.h>
+#include <sys/trace_txg.h>
+
+/*
+ * ZFS Transaction Groups
+ * ----------------------
+ *
+ * ZFS transaction groups are, as the name implies, groups of transactions
+ * that act on persistent state. ZFS asserts consistency at the granularity of
+ * these transaction groups. Each successive transaction group (txg) is
+ * assigned a 64-bit consecutive identifier. There are three active
+ * transaction group states: open, quiescing, or syncing. At any given time,
+ * there may be an active txg associated with each state; each active txg may
+ * either be processing, or blocked waiting to enter the next state. There may
+ * be up to three active txgs, and there is always a txg in the open state
+ * (though it may be blocked waiting to enter the quiescing state). In broad
+ * strokes, transactions -- operations that change in-memory structures -- are
+ * accepted into the txg in the open state, and are completed while the txg is
+ * in the open or quiescing states. The accumulated changes are written to
+ * disk in the syncing state.
+ *
+ * Open
+ *
+ * When a new txg becomes active, it first enters the open state. New
+ * transactions -- updates to in-memory structures -- are assigned to the
+ * currently open txg. There is always a txg in the open state so that ZFS can
+ * accept new changes (though the txg may refuse new changes if it has hit
+ * some limit). ZFS advances the open txg to the next state for a variety of
+ * reasons such as it hitting a time or size threshold, or the execution of an
+ * administrative action that must be completed in the syncing state.
+ *
+ * Quiescing
+ *
+ * After a txg exits the open state, it enters the quiescing state. The
+ * quiescing state is intended to provide a buffer between accepting new
+ * transactions in the open state and writing them out to stable storage in
+ * the syncing state. While quiescing, transactions can continue their
+ * operation without delaying either of the other states. Typically, a txg is
+ * in the quiescing state very briefly since the operations are bounded by
+ * software latencies rather than, say, slower I/O latencies. After all
+ * transactions complete, the txg is ready to enter the next state.
+ *
+ * Syncing
+ *
+ * In the syncing state, the in-memory state built up during the open and (to
+ * a lesser degree) the quiescing states is written to stable storage. The
+ * process of writing out modified data can, in turn modify more data. For
+ * example when we write new blocks, we need to allocate space for them; those
+ * allocations modify metadata (space maps)... which themselves must be
+ * written to stable storage. During the sync state, ZFS iterates, writing out
+ * data until it converges and all in-memory changes have been written out.
+ * The first such pass is the largest as it encompasses all the modified user
+ * data (as opposed to filesystem metadata). Subsequent passes typically have
+ * far less data to write as they consist exclusively of filesystem metadata.
+ *
+ * To ensure convergence, after a certain number of passes ZFS begins
+ * overwriting locations on stable storage that had been allocated earlier in
+ * the syncing state (and subsequently freed). ZFS usually allocates new
+ * blocks to optimize for large, continuous, writes. For the syncing state to
+ * converge however it must complete a pass where no new blocks are allocated
+ * since each allocation requires a modification of persistent metadata.
+ * Further, to hasten convergence, after a prescribed number of passes, ZFS
+ * also defers frees, and stops compressing.
+ *
+ * In addition to writing out user data, we must also execute synctasks during
+ * the syncing context. A synctask is the mechanism by which some
+ * administrative activities work such as creating and destroying snapshots or
+ * datasets. Note that when a synctask is initiated it enters the open txg,
+ * and ZFS then pushes that txg as quickly as possible to completion of the
+ * syncing state in order to reduce the latency of the administrative
+ * activity. To complete the syncing state, ZFS writes out a new uberblock,
+ * the root of the tree of blocks that comprise all state stored on the ZFS
+ * pool. Finally, if there is a quiesced txg waiting, we signal that it can
+ * now transition to the syncing state.
+ */
+
+static void txg_sync_thread(dsl_pool_t *dp);
+static void txg_quiesce_thread(dsl_pool_t *dp);
+
+int zfs_txg_timeout = 5;	/* max seconds worth of delta per txg */
+
+/*
+ * Prepare the txg subsystem.
+ */
+void
+txg_init(dsl_pool_t *dp, uint64_t txg)
+{
+	tx_state_t *tx = &dp->dp_tx;
+	int c;
+	bzero(tx, sizeof (tx_state_t));
+
+	tx->tx_cpu = vmem_zalloc(max_ncpus * sizeof (tx_cpu_t), KM_SLEEP);
+
+	for (c = 0; c < max_ncpus; c++) {
+		int i;
+
+		mutex_init(&tx->tx_cpu[c].tc_lock, NULL, MUTEX_DEFAULT, NULL);
+		mutex_init(&tx->tx_cpu[c].tc_open_lock, NULL, MUTEX_DEFAULT,
+		    NULL);
+		for (i = 0; i < TXG_SIZE; i++) {
+			cv_init(&tx->tx_cpu[c].tc_cv[i], NULL, CV_DEFAULT,
+			    NULL);
+			list_create(&tx->tx_cpu[c].tc_callbacks[i],
+			    sizeof (dmu_tx_callback_t),
+			    offsetof(dmu_tx_callback_t, dcb_node));
+		}
+	}
+
+	mutex_init(&tx->tx_sync_lock, NULL, MUTEX_DEFAULT, NULL);
+
+	cv_init(&tx->tx_sync_more_cv, NULL, CV_DEFAULT, NULL);
+	cv_init(&tx->tx_sync_done_cv, NULL, CV_DEFAULT, NULL);
+	cv_init(&tx->tx_quiesce_more_cv, NULL, CV_DEFAULT, NULL);
+	cv_init(&tx->tx_quiesce_done_cv, NULL, CV_DEFAULT, NULL);
+	cv_init(&tx->tx_exit_cv, NULL, CV_DEFAULT, NULL);
+
+	tx->tx_open_txg = txg;
+}
+
+/*
+ * Close down the txg subsystem.
+ */
+void
+txg_fini(dsl_pool_t *dp)
+{
+	tx_state_t *tx = &dp->dp_tx;
+	int c;
+
+	ASSERT(tx->tx_threads == 0);
+
+	mutex_destroy(&tx->tx_sync_lock);
+
+	cv_destroy(&tx->tx_sync_more_cv);
+	cv_destroy(&tx->tx_sync_done_cv);
+	cv_destroy(&tx->tx_quiesce_more_cv);
+	cv_destroy(&tx->tx_quiesce_done_cv);
+	cv_destroy(&tx->tx_exit_cv);
+
+	for (c = 0; c < max_ncpus; c++) {
+		int i;
+
+		mutex_destroy(&tx->tx_cpu[c].tc_open_lock);
+		mutex_destroy(&tx->tx_cpu[c].tc_lock);
+		for (i = 0; i < TXG_SIZE; i++) {
+			cv_destroy(&tx->tx_cpu[c].tc_cv[i]);
+			list_destroy(&tx->tx_cpu[c].tc_callbacks[i]);
+		}
+	}
+
+	if (tx->tx_commit_cb_taskq != NULL)
+		taskq_destroy(tx->tx_commit_cb_taskq);
+
+	vmem_free(tx->tx_cpu, max_ncpus * sizeof (tx_cpu_t));
+
+	bzero(tx, sizeof (tx_state_t));
+}
+
+/*
+ * Start syncing transaction groups.
+ */
+void
+txg_sync_start(dsl_pool_t *dp)
+{
+	tx_state_t *tx = &dp->dp_tx;
+
+	mutex_enter(&tx->tx_sync_lock);
+
+	dprintf("pool %p\n", dp);
+
+	ASSERT(tx->tx_threads == 0);
+
+	tx->tx_threads = 2;
+
+	tx->tx_quiesce_thread = thread_create(NULL, 0, txg_quiesce_thread,
+	    dp, 0, &p0, TS_RUN, defclsyspri);
+
+	/*
+	 * The sync thread can need a larger-than-default stack size on
+	 * 32-bit x86.  This is due in part to nested pools and
+	 * scrub_visitbp() recursion.
+	 */
+	tx->tx_sync_thread = thread_create(NULL, 32<<10, txg_sync_thread,
+	    dp, 0, &p0, TS_RUN, defclsyspri);
+
+	mutex_exit(&tx->tx_sync_lock);
+}
+
+static void
+txg_thread_enter(tx_state_t *tx, callb_cpr_t *cpr)
+{
+	CALLB_CPR_INIT(cpr, &tx->tx_sync_lock, callb_generic_cpr, FTAG);
+	mutex_enter(&tx->tx_sync_lock);
+}
+
+static void
+txg_thread_exit(tx_state_t *tx, callb_cpr_t *cpr, kthread_t **tpp)
+{
+	ASSERT(*tpp != NULL);
+	*tpp = NULL;
+	tx->tx_threads--;
+	cv_broadcast(&tx->tx_exit_cv);
+	CALLB_CPR_EXIT(cpr);		/* drops &tx->tx_sync_lock */
+	thread_exit();
+}
+
+static void
+txg_thread_wait(tx_state_t *tx, callb_cpr_t *cpr, kcondvar_t *cv, clock_t time)
+{
+	CALLB_CPR_SAFE_BEGIN(cpr);
+
+	if (time)
+		(void) cv_timedwait_sig(cv, &tx->tx_sync_lock,
+		    ddi_get_lbolt() + time);
+	else
+		cv_wait_sig(cv, &tx->tx_sync_lock);
+
+	CALLB_CPR_SAFE_END(cpr, &tx->tx_sync_lock);
+}
+
+/*
+ * Stop syncing transaction groups.
+ */
+void
+txg_sync_stop(dsl_pool_t *dp)
+{
+	tx_state_t *tx = &dp->dp_tx;
+
+	dprintf("pool %p\n", dp);
+	/*
+	 * Finish off any work in progress.
+	 */
+	ASSERT(tx->tx_threads == 2);
+
+	/*
+	 * We need to ensure that we've vacated the deferred space_maps.
+	 */
+	txg_wait_synced(dp, tx->tx_open_txg + TXG_DEFER_SIZE);
+
+	/*
+	 * Wake all sync threads and wait for them to die.
+	 */
+	mutex_enter(&tx->tx_sync_lock);
+
+	ASSERT(tx->tx_threads == 2);
+
+	tx->tx_exiting = 1;
+
+	cv_broadcast(&tx->tx_quiesce_more_cv);
+	cv_broadcast(&tx->tx_quiesce_done_cv);
+	cv_broadcast(&tx->tx_sync_more_cv);
+
+	while (tx->tx_threads != 0)
+		cv_wait(&tx->tx_exit_cv, &tx->tx_sync_lock);
+
+	tx->tx_exiting = 0;
+
+	mutex_exit(&tx->tx_sync_lock);
+}
+
+uint64_t
+txg_hold_open(dsl_pool_t *dp, txg_handle_t *th)
+{
+	tx_state_t *tx = &dp->dp_tx;
+	tx_cpu_t *tc;
+	uint64_t txg;
+
+	/*
+	 * It appears the processor id is simply used as a "random"
+	 * number to index into the array, and there isn't any other
+	 * significance to the chosen tx_cpu. Because.. Why not use
+	 * the current cpu to index into the array?
+	 */
+	kpreempt_disable();
+	tc = &tx->tx_cpu[CPU_SEQID];
+	kpreempt_enable();
+
+	mutex_enter(&tc->tc_open_lock);
+	txg = tx->tx_open_txg;
+
+	mutex_enter(&tc->tc_lock);
+	tc->tc_count[txg & TXG_MASK]++;
+	mutex_exit(&tc->tc_lock);
+
+	th->th_cpu = tc;
+	th->th_txg = txg;
+
+	return (txg);
+}
+
+void
+txg_rele_to_quiesce(txg_handle_t *th)
+{
+	tx_cpu_t *tc = th->th_cpu;
+
+	ASSERT(!MUTEX_HELD(&tc->tc_lock));
+	mutex_exit(&tc->tc_open_lock);
+}
+
+void
+txg_register_callbacks(txg_handle_t *th, list_t *tx_callbacks)
+{
+	tx_cpu_t *tc = th->th_cpu;
+	int g = th->th_txg & TXG_MASK;
+
+	mutex_enter(&tc->tc_lock);
+	list_move_tail(&tc->tc_callbacks[g], tx_callbacks);
+	mutex_exit(&tc->tc_lock);
+}
+
+void
+txg_rele_to_sync(txg_handle_t *th)
+{
+	tx_cpu_t *tc = th->th_cpu;
+	int g = th->th_txg & TXG_MASK;
+
+	mutex_enter(&tc->tc_lock);
+	ASSERT(tc->tc_count[g] != 0);
+	if (--tc->tc_count[g] == 0)
+		cv_broadcast(&tc->tc_cv[g]);
+	mutex_exit(&tc->tc_lock);
+
+	th->th_cpu = NULL;	/* defensive */
+}
+
+/*
+ * Blocks until all transactions in the group are committed.
+ *
+ * On return, the transaction group has reached a stable state in which it can
+ * then be passed off to the syncing context.
+ */
+static void
+txg_quiesce(dsl_pool_t *dp, uint64_t txg)
+{
+	tx_state_t *tx = &dp->dp_tx;
+	int g = txg & TXG_MASK;
+	int c;
+
+	/*
+	 * Grab all tc_open_locks so nobody else can get into this txg.
+	 */
+	for (c = 0; c < max_ncpus; c++)
+		mutex_enter(&tx->tx_cpu[c].tc_open_lock);
+
+	ASSERT(txg == tx->tx_open_txg);
+	tx->tx_open_txg++;
+	tx->tx_open_time = gethrtime();
+
+	spa_txg_history_set(dp->dp_spa, txg, TXG_STATE_OPEN, tx->tx_open_time);
+	spa_txg_history_add(dp->dp_spa, tx->tx_open_txg, tx->tx_open_time);
+
+	DTRACE_PROBE2(txg__quiescing, dsl_pool_t *, dp, uint64_t, txg);
+	DTRACE_PROBE2(txg__opened, dsl_pool_t *, dp, uint64_t, tx->tx_open_txg);
+
+	/*
+	 * Now that we've incremented tx_open_txg, we can let threads
+	 * enter the next transaction group.
+	 */
+	for (c = 0; c < max_ncpus; c++)
+		mutex_exit(&tx->tx_cpu[c].tc_open_lock);
+
+	/*
+	 * Quiesce the transaction group by waiting for everyone to txg_exit().
+	 */
+	for (c = 0; c < max_ncpus; c++) {
+		tx_cpu_t *tc = &tx->tx_cpu[c];
+		mutex_enter(&tc->tc_lock);
+		while (tc->tc_count[g] != 0)
+			cv_wait(&tc->tc_cv[g], &tc->tc_lock);
+		mutex_exit(&tc->tc_lock);
+	}
+
+	spa_txg_history_set(dp->dp_spa, txg, TXG_STATE_QUIESCED, gethrtime());
+}
+
+static void
+txg_do_callbacks(list_t *cb_list)
+{
+	dmu_tx_do_callbacks(cb_list, 0);
+
+	list_destroy(cb_list);
+
+	kmem_free(cb_list, sizeof (list_t));
+}
+
+/*
+ * Dispatch the commit callbacks registered on this txg to worker threads.
+ *
+ * If no callbacks are registered for a given TXG, nothing happens.
+ * This function creates a taskq for the associated pool, if needed.
+ */
+static void
+txg_dispatch_callbacks(dsl_pool_t *dp, uint64_t txg)
+{
+	int c;
+	tx_state_t *tx = &dp->dp_tx;
+	list_t *cb_list;
+
+	for (c = 0; c < max_ncpus; c++) {
+		tx_cpu_t *tc = &tx->tx_cpu[c];
+		/*
+		 * No need to lock tx_cpu_t at this point, since this can
+		 * only be called once a txg has been synced.
+		 */
+
+		int g = txg & TXG_MASK;
+
+		if (list_is_empty(&tc->tc_callbacks[g]))
+			continue;
+
+		if (tx->tx_commit_cb_taskq == NULL) {
+			/*
+			 * Commit callback taskq hasn't been created yet.
+			 */
+			tx->tx_commit_cb_taskq = taskq_create("tx_commit_cb",
+			    max_ncpus, defclsyspri, max_ncpus, max_ncpus * 2,
+			    TASKQ_PREPOPULATE | TASKQ_DYNAMIC);
+		}
+
+		cb_list = kmem_alloc(sizeof (list_t), KM_SLEEP);
+		list_create(cb_list, sizeof (dmu_tx_callback_t),
+		    offsetof(dmu_tx_callback_t, dcb_node));
+
+		list_move_tail(cb_list, &tc->tc_callbacks[g]);
+
+		(void) taskq_dispatch(tx->tx_commit_cb_taskq, (task_func_t *)
+		    txg_do_callbacks, cb_list, TQ_SLEEP);
+	}
+}
+
+/*
+ * Wait for pending commit callbacks of already-synced transactions to finish
+ * processing.
+ * Calling this function from within a commit callback will deadlock.
+ */
+void
+txg_wait_callbacks(dsl_pool_t *dp)
+{
+	tx_state_t *tx = &dp->dp_tx;
+
+	if (tx->tx_commit_cb_taskq != NULL)
+		taskq_wait_outstanding(tx->tx_commit_cb_taskq, 0);
+}
+
+static void
+txg_sync_thread(dsl_pool_t *dp)
+{
+	spa_t *spa = dp->dp_spa;
+	tx_state_t *tx = &dp->dp_tx;
+	callb_cpr_t cpr;
+	vdev_stat_t *vs1, *vs2;
+	clock_t start, delta;
+
+	(void) spl_fstrans_mark();
+	txg_thread_enter(tx, &cpr);
+
+	vs1 = kmem_alloc(sizeof (vdev_stat_t), KM_SLEEP);
+	vs2 = kmem_alloc(sizeof (vdev_stat_t), KM_SLEEP);
+
+	start = delta = 0;
+	for (;;) {
+		clock_t timer, timeout;
+		uint64_t txg;
+		uint64_t ndirty;
+
+		timeout = zfs_txg_timeout * hz;
+
+		/*
+		 * We sync when we're scanning, there's someone waiting
+		 * on us, or the quiesce thread has handed off a txg to
+		 * us, or we have reached our timeout.
+		 */
+		timer = (delta >= timeout ? 0 : timeout - delta);
+		while (!dsl_scan_active(dp->dp_scan) &&
+		    !tx->tx_exiting && timer > 0 &&
+		    tx->tx_synced_txg >= tx->tx_sync_txg_waiting &&
+		    tx->tx_quiesced_txg == 0 &&
+		    dp->dp_dirty_total < zfs_dirty_data_sync) {
+			dprintf("waiting; tx_synced=%llu waiting=%llu dp=%p\n",
+			    tx->tx_synced_txg, tx->tx_sync_txg_waiting, dp);
+			txg_thread_wait(tx, &cpr, &tx->tx_sync_more_cv, timer);
+			delta = ddi_get_lbolt() - start;
+			timer = (delta > timeout ? 0 : timeout - delta);
+		}
+
+		/*
+		 * Wait until the quiesce thread hands off a txg to us,
+		 * prompting it to do so if necessary.
+		 */
+		while (!tx->tx_exiting && tx->tx_quiesced_txg == 0) {
+			if (tx->tx_quiesce_txg_waiting < tx->tx_open_txg+1)
+				tx->tx_quiesce_txg_waiting = tx->tx_open_txg+1;
+			cv_broadcast(&tx->tx_quiesce_more_cv);
+			txg_thread_wait(tx, &cpr, &tx->tx_quiesce_done_cv, 0);
+		}
+
+		if (tx->tx_exiting) {
+			kmem_free(vs2, sizeof (vdev_stat_t));
+			kmem_free(vs1, sizeof (vdev_stat_t));
+			txg_thread_exit(tx, &cpr, &tx->tx_sync_thread);
+		}
+
+		spa_config_enter(spa, SCL_ALL, FTAG, RW_READER);
+		vdev_get_stats(spa->spa_root_vdev, vs1);
+		spa_config_exit(spa, SCL_ALL, FTAG);
+
+		/*
+		 * Consume the quiesced txg which has been handed off to
+		 * us.  This may cause the quiescing thread to now be
+		 * able to quiesce another txg, so we must signal it.
+		 */
+		txg = tx->tx_quiesced_txg;
+		tx->tx_quiesced_txg = 0;
+		tx->tx_syncing_txg = txg;
+		DTRACE_PROBE2(txg__syncing, dsl_pool_t *, dp, uint64_t, txg);
+		cv_broadcast(&tx->tx_quiesce_more_cv);
+
+		dprintf("txg=%llu quiesce_txg=%llu sync_txg=%llu\n",
+		    txg, tx->tx_quiesce_txg_waiting, tx->tx_sync_txg_waiting);
+		mutex_exit(&tx->tx_sync_lock);
+
+		spa_txg_history_set(spa, txg, TXG_STATE_WAIT_FOR_SYNC,
+		    gethrtime());
+		ndirty = dp->dp_dirty_pertxg[txg & TXG_MASK];
+
+		start = ddi_get_lbolt();
+		spa_sync(spa, txg);
+		delta = ddi_get_lbolt() - start;
+
+		mutex_enter(&tx->tx_sync_lock);
+		tx->tx_synced_txg = txg;
+		tx->tx_syncing_txg = 0;
+		DTRACE_PROBE2(txg__synced, dsl_pool_t *, dp, uint64_t, txg);
+		cv_broadcast(&tx->tx_sync_done_cv);
+
+		/*
+		 * Dispatch commit callbacks to worker threads.
+		 */
+		txg_dispatch_callbacks(dp, txg);
+
+		spa_config_enter(spa, SCL_ALL, FTAG, RW_READER);
+		vdev_get_stats(spa->spa_root_vdev, vs2);
+		spa_config_exit(spa, SCL_ALL, FTAG);
+		spa_txg_history_set_io(spa, txg,
+		    vs2->vs_bytes[ZIO_TYPE_READ]-vs1->vs_bytes[ZIO_TYPE_READ],
+		    vs2->vs_bytes[ZIO_TYPE_WRITE]-vs1->vs_bytes[ZIO_TYPE_WRITE],
+		    vs2->vs_ops[ZIO_TYPE_READ]-vs1->vs_ops[ZIO_TYPE_READ],
+		    vs2->vs_ops[ZIO_TYPE_WRITE]-vs1->vs_ops[ZIO_TYPE_WRITE],
+		    ndirty);
+		spa_txg_history_set(spa, txg, TXG_STATE_SYNCED, gethrtime());
+	}
+}
+
+static void
+txg_quiesce_thread(dsl_pool_t *dp)
+{
+	tx_state_t *tx = &dp->dp_tx;
+	callb_cpr_t cpr;
+
+	txg_thread_enter(tx, &cpr);
+
+	for (;;) {
+		uint64_t txg;
+
+		/*
+		 * We quiesce when there's someone waiting on us.
+		 * However, we can only have one txg in "quiescing" or
+		 * "quiesced, waiting to sync" state.  So we wait until
+		 * the "quiesced, waiting to sync" txg has been consumed
+		 * by the sync thread.
+		 */
+		while (!tx->tx_exiting &&
+		    (tx->tx_open_txg >= tx->tx_quiesce_txg_waiting ||
+		    tx->tx_quiesced_txg != 0))
+			txg_thread_wait(tx, &cpr, &tx->tx_quiesce_more_cv, 0);
+
+		if (tx->tx_exiting)
+			txg_thread_exit(tx, &cpr, &tx->tx_quiesce_thread);
+
+		txg = tx->tx_open_txg;
+		dprintf("txg=%llu quiesce_txg=%llu sync_txg=%llu\n",
+		    txg, tx->tx_quiesce_txg_waiting,
+		    tx->tx_sync_txg_waiting);
+		mutex_exit(&tx->tx_sync_lock);
+		txg_quiesce(dp, txg);
+		mutex_enter(&tx->tx_sync_lock);
+
+		/*
+		 * Hand this txg off to the sync thread.
+		 */
+		dprintf("quiesce done, handing off txg %llu\n", txg);
+		tx->tx_quiesced_txg = txg;
+		DTRACE_PROBE2(txg__quiesced, dsl_pool_t *, dp, uint64_t, txg);
+		cv_broadcast(&tx->tx_sync_more_cv);
+		cv_broadcast(&tx->tx_quiesce_done_cv);
+	}
+}
+
+/*
+ * Delay this thread by delay nanoseconds if we are still in the open
+ * transaction group and there is already a waiting txg quiesing or quiesced.
+ * Abort the delay if this txg stalls or enters the quiesing state.
+ */
+void
+txg_delay(dsl_pool_t *dp, uint64_t txg, hrtime_t delay, hrtime_t resolution)
+{
+	tx_state_t *tx = &dp->dp_tx;
+	hrtime_t start = gethrtime();
+
+	/* don't delay if this txg could transition to quiescing immediately */
+	if (tx->tx_open_txg > txg ||
+	    tx->tx_syncing_txg == txg-1 || tx->tx_synced_txg == txg-1)
+		return;
+
+	mutex_enter(&tx->tx_sync_lock);
+	if (tx->tx_open_txg > txg || tx->tx_synced_txg == txg-1) {
+		mutex_exit(&tx->tx_sync_lock);
+		return;
+	}
+
+	while (gethrtime() - start < delay &&
+	    tx->tx_syncing_txg < txg-1 && !txg_stalled(dp)) {
+		(void) cv_timedwait_hires(&tx->tx_quiesce_more_cv,
+		    &tx->tx_sync_lock, delay, resolution, 0);
+	}
+
+	DMU_TX_STAT_BUMP(dmu_tx_delay);
+
+	mutex_exit(&tx->tx_sync_lock);
+}
+
+void
+txg_wait_synced(dsl_pool_t *dp, uint64_t txg)
+{
+	tx_state_t *tx = &dp->dp_tx;
+
+	ASSERT(!dsl_pool_config_held(dp));
+
+	mutex_enter(&tx->tx_sync_lock);
+	ASSERT(tx->tx_threads == 2);
+	if (txg == 0)
+		txg = tx->tx_open_txg + TXG_DEFER_SIZE;
+	if (tx->tx_sync_txg_waiting < txg)
+		tx->tx_sync_txg_waiting = txg;
+	dprintf("txg=%llu quiesce_txg=%llu sync_txg=%llu\n",
+	    txg, tx->tx_quiesce_txg_waiting, tx->tx_sync_txg_waiting);
+	while (tx->tx_synced_txg < txg) {
+		dprintf("broadcasting sync more "
+		    "tx_synced=%llu waiting=%llu dp=%p\n",
+		    tx->tx_synced_txg, tx->tx_sync_txg_waiting, dp);
+		cv_broadcast(&tx->tx_sync_more_cv);
+		cv_wait(&tx->tx_sync_done_cv, &tx->tx_sync_lock);
+	}
+	mutex_exit(&tx->tx_sync_lock);
+}
+
+void
+txg_wait_open(dsl_pool_t *dp, uint64_t txg)
+{
+	tx_state_t *tx = &dp->dp_tx;
+
+	ASSERT(!dsl_pool_config_held(dp));
+
+	mutex_enter(&tx->tx_sync_lock);
+	ASSERT(tx->tx_threads == 2);
+	if (txg == 0)
+		txg = tx->tx_open_txg + 1;
+	if (tx->tx_quiesce_txg_waiting < txg)
+		tx->tx_quiesce_txg_waiting = txg;
+	dprintf("txg=%llu quiesce_txg=%llu sync_txg=%llu\n",
+	    txg, tx->tx_quiesce_txg_waiting, tx->tx_sync_txg_waiting);
+	while (tx->tx_open_txg < txg) {
+		cv_broadcast(&tx->tx_quiesce_more_cv);
+		cv_wait(&tx->tx_quiesce_done_cv, &tx->tx_sync_lock);
+	}
+	mutex_exit(&tx->tx_sync_lock);
+}
+
+/*
+ * If there isn't a txg syncing or in the pipeline, push another txg through
+ * the pipeline by queiscing the open txg.
+ */
+void
+txg_kick(dsl_pool_t *dp)
+{
+	tx_state_t *tx = &dp->dp_tx;
+
+	ASSERT(!dsl_pool_config_held(dp));
+
+	mutex_enter(&tx->tx_sync_lock);
+	if (tx->tx_syncing_txg == 0 &&
+	    tx->tx_quiesce_txg_waiting <= tx->tx_open_txg &&
+	    tx->tx_sync_txg_waiting <= tx->tx_synced_txg &&
+	    tx->tx_quiesced_txg <= tx->tx_synced_txg) {
+		tx->tx_quiesce_txg_waiting = tx->tx_open_txg + 1;
+		cv_broadcast(&tx->tx_quiesce_more_cv);
+	}
+	mutex_exit(&tx->tx_sync_lock);
+}
+
+boolean_t
+txg_stalled(dsl_pool_t *dp)
+{
+	tx_state_t *tx = &dp->dp_tx;
+	return (tx->tx_quiesce_txg_waiting > tx->tx_open_txg);
+}
+
+boolean_t
+txg_sync_waiting(dsl_pool_t *dp)
+{
+	tx_state_t *tx = &dp->dp_tx;
+
+	return (tx->tx_syncing_txg <= tx->tx_sync_txg_waiting ||
+	    tx->tx_quiesced_txg != 0);
+}
+
+/*
+ * Per-txg object lists.
+ */
+void
+txg_list_create(txg_list_t *tl, size_t offset)
+{
+	int t;
+
+	mutex_init(&tl->tl_lock, NULL, MUTEX_DEFAULT, NULL);
+
+	tl->tl_offset = offset;
+
+	for (t = 0; t < TXG_SIZE; t++)
+		tl->tl_head[t] = NULL;
+}
+
+void
+txg_list_destroy(txg_list_t *tl)
+{
+	int t;
+
+	for (t = 0; t < TXG_SIZE; t++)
+		ASSERT(txg_list_empty(tl, t));
+
+	mutex_destroy(&tl->tl_lock);
+}
+
+boolean_t
+txg_list_empty(txg_list_t *tl, uint64_t txg)
+{
+	return (tl->tl_head[txg & TXG_MASK] == NULL);
+}
+
+/*
+ * Returns true if all txg lists are empty.
+ *
+ * Warning: this is inherently racy (an item could be added immediately
+ * after this function returns). We don't bother with the lock because
+ * it wouldn't change the semantics.
+ */
+boolean_t
+txg_all_lists_empty(txg_list_t *tl)
+{
+	int i;
+
+	for (i = 0; i < TXG_SIZE; i++) {
+		if (!txg_list_empty(tl, i)) {
+			return (B_FALSE);
+		}
+	}
+	return (B_TRUE);
+}
+
+/*
+ * Add an entry to the list (unless it's already on the list).
+ * Returns B_TRUE if it was actually added.
+ */
+boolean_t
+txg_list_add(txg_list_t *tl, void *p, uint64_t txg)
+{
+	int t = txg & TXG_MASK;
+	txg_node_t *tn = (txg_node_t *)((char *)p + tl->tl_offset);
+	boolean_t add;
+
+	mutex_enter(&tl->tl_lock);
+	add = (tn->tn_member[t] == 0);
+	if (add) {
+		tn->tn_member[t] = 1;
+		tn->tn_next[t] = tl->tl_head[t];
+		tl->tl_head[t] = tn;
+	}
+	mutex_exit(&tl->tl_lock);
+
+	return (add);
+}
+
+/*
+ * Add an entry to the end of the list, unless it's already on the list.
+ * (walks list to find end)
+ * Returns B_TRUE if it was actually added.
+ */
+boolean_t
+txg_list_add_tail(txg_list_t *tl, void *p, uint64_t txg)
+{
+	int t = txg & TXG_MASK;
+	txg_node_t *tn = (txg_node_t *)((char *)p + tl->tl_offset);
+	boolean_t add;
+
+	mutex_enter(&tl->tl_lock);
+	add = (tn->tn_member[t] == 0);
+	if (add) {
+		txg_node_t **tp;
+
+		for (tp = &tl->tl_head[t]; *tp != NULL; tp = &(*tp)->tn_next[t])
+			continue;
+
+		tn->tn_member[t] = 1;
+		tn->tn_next[t] = NULL;
+		*tp = tn;
+	}
+	mutex_exit(&tl->tl_lock);
+
+	return (add);
+}
+
+/*
+ * Remove the head of the list and return it.
+ */
+void *
+txg_list_remove(txg_list_t *tl, uint64_t txg)
+{
+	int t = txg & TXG_MASK;
+	txg_node_t *tn;
+	void *p = NULL;
+
+	mutex_enter(&tl->tl_lock);
+	if ((tn = tl->tl_head[t]) != NULL) {
+		p = (char *)tn - tl->tl_offset;
+		tl->tl_head[t] = tn->tn_next[t];
+		tn->tn_next[t] = NULL;
+		tn->tn_member[t] = 0;
+	}
+	mutex_exit(&tl->tl_lock);
+
+	return (p);
+}
+
+/*
+ * Remove a specific item from the list and return it.
+ */
+void *
+txg_list_remove_this(txg_list_t *tl, void *p, uint64_t txg)
+{
+	int t = txg & TXG_MASK;
+	txg_node_t *tn, **tp;
+
+	mutex_enter(&tl->tl_lock);
+
+	for (tp = &tl->tl_head[t]; (tn = *tp) != NULL; tp = &tn->tn_next[t]) {
+		if ((char *)tn - tl->tl_offset == p) {
+			*tp = tn->tn_next[t];
+			tn->tn_next[t] = NULL;
+			tn->tn_member[t] = 0;
+			mutex_exit(&tl->tl_lock);
+			return (p);
+		}
+	}
+
+	mutex_exit(&tl->tl_lock);
+
+	return (NULL);
+}
+
+boolean_t
+txg_list_member(txg_list_t *tl, void *p, uint64_t txg)
+{
+	int t = txg & TXG_MASK;
+	txg_node_t *tn = (txg_node_t *)((char *)p + tl->tl_offset);
+
+	return (tn->tn_member[t] != 0);
+}
+
+/*
+ * Walk a txg list -- only safe if you know it's not changing.
+ */
+void *
+txg_list_head(txg_list_t *tl, uint64_t txg)
+{
+	int t = txg & TXG_MASK;
+	txg_node_t *tn = tl->tl_head[t];
+
+	return (tn == NULL ? NULL : (char *)tn - tl->tl_offset);
+}
+
+void *
+txg_list_next(txg_list_t *tl, void *p, uint64_t txg)
+{
+	int t = txg & TXG_MASK;
+	txg_node_t *tn = (txg_node_t *)((char *)p + tl->tl_offset);
+
+	tn = tn->tn_next[t];
+
+	return (tn == NULL ? NULL : (char *)tn - tl->tl_offset);
+}
+
+#if defined(_KERNEL) && defined(HAVE_SPL)
+EXPORT_SYMBOL(txg_init);
+EXPORT_SYMBOL(txg_fini);
+EXPORT_SYMBOL(txg_sync_start);
+EXPORT_SYMBOL(txg_sync_stop);
+EXPORT_SYMBOL(txg_hold_open);
+EXPORT_SYMBOL(txg_rele_to_quiesce);
+EXPORT_SYMBOL(txg_rele_to_sync);
+EXPORT_SYMBOL(txg_register_callbacks);
+EXPORT_SYMBOL(txg_delay);
+EXPORT_SYMBOL(txg_wait_synced);
+EXPORT_SYMBOL(txg_wait_open);
+EXPORT_SYMBOL(txg_wait_callbacks);
+EXPORT_SYMBOL(txg_stalled);
+EXPORT_SYMBOL(txg_sync_waiting);
+
+module_param(zfs_txg_timeout, int, 0644);
+MODULE_PARM_DESC(zfs_txg_timeout, "Max seconds worth of delta per txg");
+#endif
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/module/zfs/uberblock.c
@@ -0,0 +1,62 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014 by Delphix. All rights reserved.
+ */
+
+#include <sys/zfs_context.h>
+#include <sys/uberblock_impl.h>
+#include <sys/vdev_impl.h>
+
+int
+uberblock_verify(uberblock_t *ub)
+{
+	if (ub->ub_magic == BSWAP_64((uint64_t)UBERBLOCK_MAGIC))
+		byteswap_uint64_array(ub, sizeof (uberblock_t));
+
+	if (ub->ub_magic != UBERBLOCK_MAGIC)
+		return (SET_ERROR(EINVAL));
+
+	return (0);
+}
+
+/*
+ * Update the uberblock and return TRUE if anything changed in this
+ * transaction group.
+ */
+boolean_t
+uberblock_update(uberblock_t *ub, vdev_t *rvd, uint64_t txg)
+{
+	ASSERT(ub->ub_txg < txg);
+
+	/*
+	 * We explicitly do not set ub_version here, so that older versions
+	 * continue to be written with the previous uberblock version.
+	 */
+	ub->ub_magic = UBERBLOCK_MAGIC;
+	ub->ub_txg = txg;
+	ub->ub_guid_sum = rvd->vdev_guid_sum;
+	ub->ub_timestamp = gethrestime_sec();
+	ub->ub_software_version = SPA_VERSION;
+
+	return (ub->ub_rootbp.blk_birth == txg);
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/module/zfs/unique.c
@@ -0,0 +1,116 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+
+#include <sys/zfs_context.h>
+#include <sys/avl.h>
+#include <sys/unique.h>
+
+static avl_tree_t unique_avl;
+static kmutex_t unique_mtx;
+
+typedef struct unique {
+	avl_node_t un_link;
+	uint64_t un_value;
+} unique_t;
+
+#define	UNIQUE_MASK ((1ULL << UNIQUE_BITS) - 1)
+
+static int
+unique_compare(const void *a, const void *b)
+{
+	const unique_t *una = a;
+	const unique_t *unb = b;
+
+	if (una->un_value < unb->un_value)
+		return (-1);
+	if (una->un_value > unb->un_value)
+		return (+1);
+	return (0);
+}
+
+void
+unique_init(void)
+{
+	avl_create(&unique_avl, unique_compare,
+	    sizeof (unique_t), offsetof(unique_t, un_link));
+	mutex_init(&unique_mtx, NULL, MUTEX_DEFAULT, NULL);
+}
+
+void
+unique_fini(void)
+{
+	avl_destroy(&unique_avl);
+	mutex_destroy(&unique_mtx);
+}
+
+uint64_t
+unique_create(void)
+{
+	uint64_t value = unique_insert(0);
+	unique_remove(value);
+	return (value);
+}
+
+uint64_t
+unique_insert(uint64_t value)
+{
+	avl_index_t idx;
+	unique_t *un = kmem_alloc(sizeof (unique_t), KM_SLEEP);
+
+	un->un_value = value;
+
+	mutex_enter(&unique_mtx);
+	while (un->un_value == 0 || un->un_value & ~UNIQUE_MASK ||
+	    avl_find(&unique_avl, un, &idx)) {
+		mutex_exit(&unique_mtx);
+		(void) random_get_pseudo_bytes((void*)&un->un_value,
+		    sizeof (un->un_value));
+		un->un_value &= UNIQUE_MASK;
+		mutex_enter(&unique_mtx);
+	}
+
+	avl_insert(&unique_avl, un, idx);
+	mutex_exit(&unique_mtx);
+
+	return (un->un_value);
+}
+
+void
+unique_remove(uint64_t value)
+{
+	unique_t un_tofind;
+	unique_t *un;
+
+	un_tofind.un_value = value;
+	mutex_enter(&unique_mtx);
+	un = avl_find(&unique_avl, &un_tofind, NULL);
+	if (un != NULL) {
+		avl_remove(&unique_avl, un);
+		kmem_free(un, sizeof (unique_t));
+	}
+	mutex_exit(&unique_mtx);
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/module/zfs/vdev.c
@@ -0,0 +1,3445 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2011 Nexenta Systems, Inc.  All rights reserved.
+ * Copyright (c) 2011, 2015 by Delphix. All rights reserved.
+ */
+
+#include <sys/zfs_context.h>
+#include <sys/fm/fs/zfs.h>
+#include <sys/spa.h>
+#include <sys/spa_impl.h>
+#include <sys/dmu.h>
+#include <sys/dmu_tx.h>
+#include <sys/vdev_impl.h>
+#include <sys/uberblock_impl.h>
+#include <sys/metaslab.h>
+#include <sys/metaslab_impl.h>
+#include <sys/space_map.h>
+#include <sys/space_reftree.h>
+#include <sys/zio.h>
+#include <sys/zap.h>
+#include <sys/fs/zfs.h>
+#include <sys/arc.h>
+#include <sys/zil.h>
+#include <sys/dsl_scan.h>
+#include <sys/zvol.h>
+
+/*
+ * When a vdev is added, it will be divided into approximately (but no
+ * more than) this number of metaslabs.
+ */
+int metaslabs_per_vdev = 200;
+
+/*
+ * Virtual device management.
+ */
+
+static vdev_ops_t *vdev_ops_table[] = {
+	&vdev_root_ops,
+	&vdev_raidz_ops,
+	&vdev_mirror_ops,
+	&vdev_replacing_ops,
+	&vdev_spare_ops,
+	&vdev_disk_ops,
+	&vdev_file_ops,
+	&vdev_missing_ops,
+	&vdev_hole_ops,
+	NULL
+};
+
+/*
+ * Given a vdev type, return the appropriate ops vector.
+ */
+static vdev_ops_t *
+vdev_getops(const char *type)
+{
+	vdev_ops_t *ops, **opspp;
+
+	for (opspp = vdev_ops_table; (ops = *opspp) != NULL; opspp++)
+		if (strcmp(ops->vdev_op_type, type) == 0)
+			break;
+
+	return (ops);
+}
+
+/*
+ * Default asize function: return the MAX of psize with the asize of
+ * all children.  This is what's used by anything other than RAID-Z.
+ */
+uint64_t
+vdev_default_asize(vdev_t *vd, uint64_t psize)
+{
+	uint64_t asize = P2ROUNDUP(psize, 1ULL << vd->vdev_top->vdev_ashift);
+	uint64_t csize;
+	int c;
+
+	for (c = 0; c < vd->vdev_children; c++) {
+		csize = vdev_psize_to_asize(vd->vdev_child[c], psize);
+		asize = MAX(asize, csize);
+	}
+
+	return (asize);
+}
+
+/*
+ * Get the minimum allocatable size. We define the allocatable size as
+ * the vdev's asize rounded to the nearest metaslab. This allows us to
+ * replace or attach devices which don't have the same physical size but
+ * can still satisfy the same number of allocations.
+ */
+uint64_t
+vdev_get_min_asize(vdev_t *vd)
+{
+	vdev_t *pvd = vd->vdev_parent;
+
+	/*
+	 * If our parent is NULL (inactive spare or cache) or is the root,
+	 * just return our own asize.
+	 */
+	if (pvd == NULL)
+		return (vd->vdev_asize);
+
+	/*
+	 * The top-level vdev just returns the allocatable size rounded
+	 * to the nearest metaslab.
+	 */
+	if (vd == vd->vdev_top)
+		return (P2ALIGN(vd->vdev_asize, 1ULL << vd->vdev_ms_shift));
+
+	/*
+	 * The allocatable space for a raidz vdev is N * sizeof(smallest child),
+	 * so each child must provide at least 1/Nth of its asize.
+	 */
+	if (pvd->vdev_ops == &vdev_raidz_ops)
+		return (pvd->vdev_min_asize / pvd->vdev_children);
+
+	return (pvd->vdev_min_asize);
+}
+
+void
+vdev_set_min_asize(vdev_t *vd)
+{
+	int c;
+	vd->vdev_min_asize = vdev_get_min_asize(vd);
+
+	for (c = 0; c < vd->vdev_children; c++)
+		vdev_set_min_asize(vd->vdev_child[c]);
+}
+
+vdev_t *
+vdev_lookup_top(spa_t *spa, uint64_t vdev)
+{
+	vdev_t *rvd = spa->spa_root_vdev;
+
+	ASSERT(spa_config_held(spa, SCL_ALL, RW_READER) != 0);
+
+	if (vdev < rvd->vdev_children) {
+		ASSERT(rvd->vdev_child[vdev] != NULL);
+		return (rvd->vdev_child[vdev]);
+	}
+
+	return (NULL);
+}
+
+vdev_t *
+vdev_lookup_by_guid(vdev_t *vd, uint64_t guid)
+{
+	vdev_t *mvd;
+	int c;
+
+	if (vd->vdev_guid == guid)
+		return (vd);
+
+	for (c = 0; c < vd->vdev_children; c++)
+		if ((mvd = vdev_lookup_by_guid(vd->vdev_child[c], guid)) !=
+		    NULL)
+			return (mvd);
+
+	return (NULL);
+}
+
+static int
+vdev_count_leaves_impl(vdev_t *vd)
+{
+	int n = 0;
+	int c;
+
+	if (vd->vdev_ops->vdev_op_leaf)
+		return (1);
+
+	for (c = 0; c < vd->vdev_children; c++)
+		n += vdev_count_leaves_impl(vd->vdev_child[c]);
+
+	return (n);
+}
+
+int
+vdev_count_leaves(spa_t *spa)
+{
+	return (vdev_count_leaves_impl(spa->spa_root_vdev));
+}
+
+void
+vdev_add_child(vdev_t *pvd, vdev_t *cvd)
+{
+	size_t oldsize, newsize;
+	uint64_t id = cvd->vdev_id;
+	vdev_t **newchild;
+
+	ASSERT(spa_config_held(cvd->vdev_spa, SCL_ALL, RW_WRITER) == SCL_ALL);
+	ASSERT(cvd->vdev_parent == NULL);
+
+	cvd->vdev_parent = pvd;
+
+	if (pvd == NULL)
+		return;
+
+	ASSERT(id >= pvd->vdev_children || pvd->vdev_child[id] == NULL);
+
+	oldsize = pvd->vdev_children * sizeof (vdev_t *);
+	pvd->vdev_children = MAX(pvd->vdev_children, id + 1);
+	newsize = pvd->vdev_children * sizeof (vdev_t *);
+
+	newchild = kmem_alloc(newsize, KM_SLEEP);
+	if (pvd->vdev_child != NULL) {
+		bcopy(pvd->vdev_child, newchild, oldsize);
+		kmem_free(pvd->vdev_child, oldsize);
+	}
+
+	pvd->vdev_child = newchild;
+	pvd->vdev_child[id] = cvd;
+
+	cvd->vdev_top = (pvd->vdev_top ? pvd->vdev_top: cvd);
+	ASSERT(cvd->vdev_top->vdev_parent->vdev_parent == NULL);
+
+	/*
+	 * Walk up all ancestors to update guid sum.
+	 */
+	for (; pvd != NULL; pvd = pvd->vdev_parent)
+		pvd->vdev_guid_sum += cvd->vdev_guid_sum;
+}
+
+void
+vdev_remove_child(vdev_t *pvd, vdev_t *cvd)
+{
+	int c;
+	uint_t id = cvd->vdev_id;
+
+	ASSERT(cvd->vdev_parent == pvd);
+
+	if (pvd == NULL)
+		return;
+
+	ASSERT(id < pvd->vdev_children);
+	ASSERT(pvd->vdev_child[id] == cvd);
+
+	pvd->vdev_child[id] = NULL;
+	cvd->vdev_parent = NULL;
+
+	for (c = 0; c < pvd->vdev_children; c++)
+		if (pvd->vdev_child[c])
+			break;
+
+	if (c == pvd->vdev_children) {
+		kmem_free(pvd->vdev_child, c * sizeof (vdev_t *));
+		pvd->vdev_child = NULL;
+		pvd->vdev_children = 0;
+	}
+
+	/*
+	 * Walk up all ancestors to update guid sum.
+	 */
+	for (; pvd != NULL; pvd = pvd->vdev_parent)
+		pvd->vdev_guid_sum -= cvd->vdev_guid_sum;
+}
+
+/*
+ * Remove any holes in the child array.
+ */
+void
+vdev_compact_children(vdev_t *pvd)
+{
+	vdev_t **newchild, *cvd;
+	int oldc = pvd->vdev_children;
+	int newc;
+	int c;
+
+	ASSERT(spa_config_held(pvd->vdev_spa, SCL_ALL, RW_WRITER) == SCL_ALL);
+
+	for (c = newc = 0; c < oldc; c++)
+		if (pvd->vdev_child[c])
+			newc++;
+
+	newchild = kmem_zalloc(newc * sizeof (vdev_t *), KM_SLEEP);
+
+	for (c = newc = 0; c < oldc; c++) {
+		if ((cvd = pvd->vdev_child[c]) != NULL) {
+			newchild[newc] = cvd;
+			cvd->vdev_id = newc++;
+		}
+	}
+
+	kmem_free(pvd->vdev_child, oldc * sizeof (vdev_t *));
+	pvd->vdev_child = newchild;
+	pvd->vdev_children = newc;
+}
+
+/*
+ * Allocate and minimally initialize a vdev_t.
+ */
+vdev_t *
+vdev_alloc_common(spa_t *spa, uint_t id, uint64_t guid, vdev_ops_t *ops)
+{
+	vdev_t *vd;
+	int t;
+
+	vd = kmem_zalloc(sizeof (vdev_t), KM_SLEEP);
+
+	if (spa->spa_root_vdev == NULL) {
+		ASSERT(ops == &vdev_root_ops);
+		spa->spa_root_vdev = vd;
+		spa->spa_load_guid = spa_generate_guid(NULL);
+	}
+
+	if (guid == 0 && ops != &vdev_hole_ops) {
+		if (spa->spa_root_vdev == vd) {
+			/*
+			 * The root vdev's guid will also be the pool guid,
+			 * which must be unique among all pools.
+			 */
+			guid = spa_generate_guid(NULL);
+		} else {
+			/*
+			 * Any other vdev's guid must be unique within the pool.
+			 */
+			guid = spa_generate_guid(spa);
+		}
+		ASSERT(!spa_guid_exists(spa_guid(spa), guid));
+	}
+
+	vd->vdev_spa = spa;
+	vd->vdev_id = id;
+	vd->vdev_guid = guid;
+	vd->vdev_guid_sum = guid;
+	vd->vdev_ops = ops;
+	vd->vdev_state = VDEV_STATE_CLOSED;
+	vd->vdev_ishole = (ops == &vdev_hole_ops);
+
+	list_link_init(&vd->vdev_config_dirty_node);
+	list_link_init(&vd->vdev_state_dirty_node);
+	mutex_init(&vd->vdev_dtl_lock, NULL, MUTEX_DEFAULT, NULL);
+	mutex_init(&vd->vdev_stat_lock, NULL, MUTEX_DEFAULT, NULL);
+	mutex_init(&vd->vdev_probe_lock, NULL, MUTEX_DEFAULT, NULL);
+	for (t = 0; t < DTL_TYPES; t++) {
+		vd->vdev_dtl[t] = range_tree_create(NULL, NULL,
+		    &vd->vdev_dtl_lock);
+	}
+	txg_list_create(&vd->vdev_ms_list,
+	    offsetof(struct metaslab, ms_txg_node));
+	txg_list_create(&vd->vdev_dtl_list,
+	    offsetof(struct vdev, vdev_dtl_node));
+	vd->vdev_stat.vs_timestamp = gethrtime();
+	vdev_queue_init(vd);
+	vdev_cache_init(vd);
+
+	return (vd);
+}
+
+/*
+ * Allocate a new vdev.  The 'alloctype' is used to control whether we are
+ * creating a new vdev or loading an existing one - the behavior is slightly
+ * different for each case.
+ */
+int
+vdev_alloc(spa_t *spa, vdev_t **vdp, nvlist_t *nv, vdev_t *parent, uint_t id,
+    int alloctype)
+{
+	vdev_ops_t *ops;
+	char *type;
+	uint64_t guid = 0, islog, nparity;
+	vdev_t *vd;
+
+	ASSERT(spa_config_held(spa, SCL_ALL, RW_WRITER) == SCL_ALL);
+
+	if (nvlist_lookup_string(nv, ZPOOL_CONFIG_TYPE, &type) != 0)
+		return (SET_ERROR(EINVAL));
+
+	if ((ops = vdev_getops(type)) == NULL)
+		return (SET_ERROR(EINVAL));
+
+	/*
+	 * If this is a load, get the vdev guid from the nvlist.
+	 * Otherwise, vdev_alloc_common() will generate one for us.
+	 */
+	if (alloctype == VDEV_ALLOC_LOAD) {
+		uint64_t label_id;
+
+		if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_ID, &label_id) ||
+		    label_id != id)
+			return (SET_ERROR(EINVAL));
+
+		if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID, &guid) != 0)
+			return (SET_ERROR(EINVAL));
+	} else if (alloctype == VDEV_ALLOC_SPARE) {
+		if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID, &guid) != 0)
+			return (SET_ERROR(EINVAL));
+	} else if (alloctype == VDEV_ALLOC_L2CACHE) {
+		if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID, &guid) != 0)
+			return (SET_ERROR(EINVAL));
+	} else if (alloctype == VDEV_ALLOC_ROOTPOOL) {
+		if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID, &guid) != 0)
+			return (SET_ERROR(EINVAL));
+	}
+
+	/*
+	 * The first allocated vdev must be of type 'root'.
+	 */
+	if (ops != &vdev_root_ops && spa->spa_root_vdev == NULL)
+		return (SET_ERROR(EINVAL));
+
+	/*
+	 * Determine whether we're a log vdev.
+	 */
+	islog = 0;
+	(void) nvlist_lookup_uint64(nv, ZPOOL_CONFIG_IS_LOG, &islog);
+	if (islog && spa_version(spa) < SPA_VERSION_SLOGS)
+		return (SET_ERROR(ENOTSUP));
+
+	if (ops == &vdev_hole_ops && spa_version(spa) < SPA_VERSION_HOLES)
+		return (SET_ERROR(ENOTSUP));
+
+	/*
+	 * Set the nparity property for RAID-Z vdevs.
+	 */
+	nparity = -1ULL;
+	if (ops == &vdev_raidz_ops) {
+		if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_NPARITY,
+		    &nparity) == 0) {
+			if (nparity == 0 || nparity > VDEV_RAIDZ_MAXPARITY)
+				return (SET_ERROR(EINVAL));
+			/*
+			 * Previous versions could only support 1 or 2 parity
+			 * device.
+			 */
+			if (nparity > 1 &&
+			    spa_version(spa) < SPA_VERSION_RAIDZ2)
+				return (SET_ERROR(ENOTSUP));
+			if (nparity > 2 &&
+			    spa_version(spa) < SPA_VERSION_RAIDZ3)
+				return (SET_ERROR(ENOTSUP));
+		} else {
+			/*
+			 * We require the parity to be specified for SPAs that
+			 * support multiple parity levels.
+			 */
+			if (spa_version(spa) >= SPA_VERSION_RAIDZ2)
+				return (SET_ERROR(EINVAL));
+			/*
+			 * Otherwise, we default to 1 parity device for RAID-Z.
+			 */
+			nparity = 1;
+		}
+	} else {
+		nparity = 0;
+	}
+	ASSERT(nparity != -1ULL);
+
+	vd = vdev_alloc_common(spa, id, guid, ops);
+
+	vd->vdev_islog = islog;
+	vd->vdev_nparity = nparity;
+
+	if (nvlist_lookup_string(nv, ZPOOL_CONFIG_PATH, &vd->vdev_path) == 0)
+		vd->vdev_path = spa_strdup(vd->vdev_path);
+	if (nvlist_lookup_string(nv, ZPOOL_CONFIG_DEVID, &vd->vdev_devid) == 0)
+		vd->vdev_devid = spa_strdup(vd->vdev_devid);
+	if (nvlist_lookup_string(nv, ZPOOL_CONFIG_PHYS_PATH,
+	    &vd->vdev_physpath) == 0)
+		vd->vdev_physpath = spa_strdup(vd->vdev_physpath);
+	if (nvlist_lookup_string(nv, ZPOOL_CONFIG_FRU, &vd->vdev_fru) == 0)
+		vd->vdev_fru = spa_strdup(vd->vdev_fru);
+
+	/*
+	 * Set the whole_disk property.  If it's not specified, leave the value
+	 * as -1.
+	 */
+	if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_WHOLE_DISK,
+	    &vd->vdev_wholedisk) != 0)
+		vd->vdev_wholedisk = -1ULL;
+
+	/*
+	 * Look for the 'not present' flag.  This will only be set if the device
+	 * was not present at the time of import.
+	 */
+	(void) nvlist_lookup_uint64(nv, ZPOOL_CONFIG_NOT_PRESENT,
+	    &vd->vdev_not_present);
+
+	/*
+	 * Get the alignment requirement.
+	 */
+	(void) nvlist_lookup_uint64(nv, ZPOOL_CONFIG_ASHIFT, &vd->vdev_ashift);
+
+	/*
+	 * Retrieve the vdev creation time.
+	 */
+	(void) nvlist_lookup_uint64(nv, ZPOOL_CONFIG_CREATE_TXG,
+	    &vd->vdev_crtxg);
+
+	/*
+	 * If we're a top-level vdev, try to load the allocation parameters.
+	 */
+	if (parent && !parent->vdev_parent &&
+	    (alloctype == VDEV_ALLOC_LOAD || alloctype == VDEV_ALLOC_SPLIT)) {
+		(void) nvlist_lookup_uint64(nv, ZPOOL_CONFIG_METASLAB_ARRAY,
+		    &vd->vdev_ms_array);
+		(void) nvlist_lookup_uint64(nv, ZPOOL_CONFIG_METASLAB_SHIFT,
+		    &vd->vdev_ms_shift);
+		(void) nvlist_lookup_uint64(nv, ZPOOL_CONFIG_ASIZE,
+		    &vd->vdev_asize);
+		(void) nvlist_lookup_uint64(nv, ZPOOL_CONFIG_REMOVING,
+		    &vd->vdev_removing);
+	}
+
+	if (parent && !parent->vdev_parent && alloctype != VDEV_ALLOC_ATTACH) {
+		ASSERT(alloctype == VDEV_ALLOC_LOAD ||
+		    alloctype == VDEV_ALLOC_ADD ||
+		    alloctype == VDEV_ALLOC_SPLIT ||
+		    alloctype == VDEV_ALLOC_ROOTPOOL);
+		vd->vdev_mg = metaslab_group_create(islog ?
+		    spa_log_class(spa) : spa_normal_class(spa), vd);
+	}
+
+	/*
+	 * If we're a leaf vdev, try to load the DTL object and other state.
+	 */
+	if (vd->vdev_ops->vdev_op_leaf &&
+	    (alloctype == VDEV_ALLOC_LOAD || alloctype == VDEV_ALLOC_L2CACHE ||
+	    alloctype == VDEV_ALLOC_ROOTPOOL)) {
+		if (alloctype == VDEV_ALLOC_LOAD) {
+			(void) nvlist_lookup_uint64(nv, ZPOOL_CONFIG_DTL,
+			    &vd->vdev_dtl_object);
+			(void) nvlist_lookup_uint64(nv, ZPOOL_CONFIG_UNSPARE,
+			    &vd->vdev_unspare);
+		}
+
+		if (alloctype == VDEV_ALLOC_ROOTPOOL) {
+			uint64_t spare = 0;
+
+			if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_IS_SPARE,
+			    &spare) == 0 && spare)
+				spa_spare_add(vd);
+		}
+
+		(void) nvlist_lookup_uint64(nv, ZPOOL_CONFIG_OFFLINE,
+		    &vd->vdev_offline);
+
+		(void) nvlist_lookup_uint64(nv, ZPOOL_CONFIG_RESILVER_TXG,
+		    &vd->vdev_resilver_txg);
+
+		/*
+		 * When importing a pool, we want to ignore the persistent fault
+		 * state, as the diagnosis made on another system may not be
+		 * valid in the current context.  Local vdevs will
+		 * remain in the faulted state.
+		 */
+		if (spa_load_state(spa) == SPA_LOAD_OPEN) {
+			(void) nvlist_lookup_uint64(nv, ZPOOL_CONFIG_FAULTED,
+			    &vd->vdev_faulted);
+			(void) nvlist_lookup_uint64(nv, ZPOOL_CONFIG_DEGRADED,
+			    &vd->vdev_degraded);
+			(void) nvlist_lookup_uint64(nv, ZPOOL_CONFIG_REMOVED,
+			    &vd->vdev_removed);
+
+			if (vd->vdev_faulted || vd->vdev_degraded) {
+				char *aux;
+
+				vd->vdev_label_aux =
+				    VDEV_AUX_ERR_EXCEEDED;
+				if (nvlist_lookup_string(nv,
+				    ZPOOL_CONFIG_AUX_STATE, &aux) == 0 &&
+				    strcmp(aux, "external") == 0)
+					vd->vdev_label_aux = VDEV_AUX_EXTERNAL;
+			}
+		}
+	}
+
+	/*
+	 * Add ourselves to the parent's list of children.
+	 */
+	vdev_add_child(parent, vd);
+
+	*vdp = vd;
+
+	return (0);
+}
+
+void
+vdev_free(vdev_t *vd)
+{
+	int c, t;
+	spa_t *spa = vd->vdev_spa;
+
+	/*
+	 * vdev_free() implies closing the vdev first.  This is simpler than
+	 * trying to ensure complicated semantics for all callers.
+	 */
+	vdev_close(vd);
+
+	ASSERT(!list_link_active(&vd->vdev_config_dirty_node));
+	ASSERT(!list_link_active(&vd->vdev_state_dirty_node));
+
+	/*
+	 * Free all children.
+	 */
+	for (c = 0; c < vd->vdev_children; c++)
+		vdev_free(vd->vdev_child[c]);
+
+	ASSERT(vd->vdev_child == NULL);
+	ASSERT(vd->vdev_guid_sum == vd->vdev_guid);
+
+	/*
+	 * Discard allocation state.
+	 */
+	if (vd->vdev_mg != NULL) {
+		vdev_metaslab_fini(vd);
+		metaslab_group_destroy(vd->vdev_mg);
+	}
+
+	ASSERT0(vd->vdev_stat.vs_space);
+	ASSERT0(vd->vdev_stat.vs_dspace);
+	ASSERT0(vd->vdev_stat.vs_alloc);
+
+	/*
+	 * Remove this vdev from its parent's child list.
+	 */
+	vdev_remove_child(vd->vdev_parent, vd);
+
+	ASSERT(vd->vdev_parent == NULL);
+
+	/*
+	 * Clean up vdev structure.
+	 */
+	vdev_queue_fini(vd);
+	vdev_cache_fini(vd);
+
+	if (vd->vdev_path)
+		spa_strfree(vd->vdev_path);
+	if (vd->vdev_devid)
+		spa_strfree(vd->vdev_devid);
+	if (vd->vdev_physpath)
+		spa_strfree(vd->vdev_physpath);
+	if (vd->vdev_fru)
+		spa_strfree(vd->vdev_fru);
+
+	if (vd->vdev_isspare)
+		spa_spare_remove(vd);
+	if (vd->vdev_isl2cache)
+		spa_l2cache_remove(vd);
+
+	txg_list_destroy(&vd->vdev_ms_list);
+	txg_list_destroy(&vd->vdev_dtl_list);
+
+	mutex_enter(&vd->vdev_dtl_lock);
+	space_map_close(vd->vdev_dtl_sm);
+	for (t = 0; t < DTL_TYPES; t++) {
+		range_tree_vacate(vd->vdev_dtl[t], NULL, NULL);
+		range_tree_destroy(vd->vdev_dtl[t]);
+	}
+	mutex_exit(&vd->vdev_dtl_lock);
+
+	mutex_destroy(&vd->vdev_dtl_lock);
+	mutex_destroy(&vd->vdev_stat_lock);
+	mutex_destroy(&vd->vdev_probe_lock);
+
+	if (vd == spa->spa_root_vdev)
+		spa->spa_root_vdev = NULL;
+
+	kmem_free(vd, sizeof (vdev_t));
+}
+
+/*
+ * Transfer top-level vdev state from svd to tvd.
+ */
+static void
+vdev_top_transfer(vdev_t *svd, vdev_t *tvd)
+{
+	spa_t *spa = svd->vdev_spa;
+	metaslab_t *msp;
+	vdev_t *vd;
+	int t;
+
+	ASSERT(tvd == tvd->vdev_top);
+
+	tvd->vdev_ms_array = svd->vdev_ms_array;
+	tvd->vdev_ms_shift = svd->vdev_ms_shift;
+	tvd->vdev_ms_count = svd->vdev_ms_count;
+
+	svd->vdev_ms_array = 0;
+	svd->vdev_ms_shift = 0;
+	svd->vdev_ms_count = 0;
+
+	if (tvd->vdev_mg)
+		ASSERT3P(tvd->vdev_mg, ==, svd->vdev_mg);
+	tvd->vdev_mg = svd->vdev_mg;
+	tvd->vdev_ms = svd->vdev_ms;
+
+	svd->vdev_mg = NULL;
+	svd->vdev_ms = NULL;
+
+	if (tvd->vdev_mg != NULL)
+		tvd->vdev_mg->mg_vd = tvd;
+
+	tvd->vdev_stat.vs_alloc = svd->vdev_stat.vs_alloc;
+	tvd->vdev_stat.vs_space = svd->vdev_stat.vs_space;
+	tvd->vdev_stat.vs_dspace = svd->vdev_stat.vs_dspace;
+
+	svd->vdev_stat.vs_alloc = 0;
+	svd->vdev_stat.vs_space = 0;
+	svd->vdev_stat.vs_dspace = 0;
+
+	for (t = 0; t < TXG_SIZE; t++) {
+		while ((msp = txg_list_remove(&svd->vdev_ms_list, t)) != NULL)
+			(void) txg_list_add(&tvd->vdev_ms_list, msp, t);
+		while ((vd = txg_list_remove(&svd->vdev_dtl_list, t)) != NULL)
+			(void) txg_list_add(&tvd->vdev_dtl_list, vd, t);
+		if (txg_list_remove_this(&spa->spa_vdev_txg_list, svd, t))
+			(void) txg_list_add(&spa->spa_vdev_txg_list, tvd, t);
+	}
+
+	if (list_link_active(&svd->vdev_config_dirty_node)) {
+		vdev_config_clean(svd);
+		vdev_config_dirty(tvd);
+	}
+
+	if (list_link_active(&svd->vdev_state_dirty_node)) {
+		vdev_state_clean(svd);
+		vdev_state_dirty(tvd);
+	}
+
+	tvd->vdev_deflate_ratio = svd->vdev_deflate_ratio;
+	svd->vdev_deflate_ratio = 0;
+
+	tvd->vdev_islog = svd->vdev_islog;
+	svd->vdev_islog = 0;
+}
+
+static void
+vdev_top_update(vdev_t *tvd, vdev_t *vd)
+{
+	int c;
+
+	if (vd == NULL)
+		return;
+
+	vd->vdev_top = tvd;
+
+	for (c = 0; c < vd->vdev_children; c++)
+		vdev_top_update(tvd, vd->vdev_child[c]);
+}
+
+/*
+ * Add a mirror/replacing vdev above an existing vdev.
+ */
+vdev_t *
+vdev_add_parent(vdev_t *cvd, vdev_ops_t *ops)
+{
+	spa_t *spa = cvd->vdev_spa;
+	vdev_t *pvd = cvd->vdev_parent;
+	vdev_t *mvd;
+
+	ASSERT(spa_config_held(spa, SCL_ALL, RW_WRITER) == SCL_ALL);
+
+	mvd = vdev_alloc_common(spa, cvd->vdev_id, 0, ops);
+
+	mvd->vdev_asize = cvd->vdev_asize;
+	mvd->vdev_min_asize = cvd->vdev_min_asize;
+	mvd->vdev_max_asize = cvd->vdev_max_asize;
+	mvd->vdev_ashift = cvd->vdev_ashift;
+	mvd->vdev_state = cvd->vdev_state;
+	mvd->vdev_crtxg = cvd->vdev_crtxg;
+
+	vdev_remove_child(pvd, cvd);
+	vdev_add_child(pvd, mvd);
+	cvd->vdev_id = mvd->vdev_children;
+	vdev_add_child(mvd, cvd);
+	vdev_top_update(cvd->vdev_top, cvd->vdev_top);
+
+	if (mvd == mvd->vdev_top)
+		vdev_top_transfer(cvd, mvd);
+
+	return (mvd);
+}
+
+/*
+ * Remove a 1-way mirror/replacing vdev from the tree.
+ */
+void
+vdev_remove_parent(vdev_t *cvd)
+{
+	vdev_t *mvd = cvd->vdev_parent;
+	vdev_t *pvd = mvd->vdev_parent;
+
+	ASSERT(spa_config_held(cvd->vdev_spa, SCL_ALL, RW_WRITER) == SCL_ALL);
+
+	ASSERT(mvd->vdev_children == 1);
+	ASSERT(mvd->vdev_ops == &vdev_mirror_ops ||
+	    mvd->vdev_ops == &vdev_replacing_ops ||
+	    mvd->vdev_ops == &vdev_spare_ops);
+	cvd->vdev_ashift = mvd->vdev_ashift;
+
+	vdev_remove_child(mvd, cvd);
+	vdev_remove_child(pvd, mvd);
+
+	/*
+	 * If cvd will replace mvd as a top-level vdev, preserve mvd's guid.
+	 * Otherwise, we could have detached an offline device, and when we
+	 * go to import the pool we'll think we have two top-level vdevs,
+	 * instead of a different version of the same top-level vdev.
+	 */
+	if (mvd->vdev_top == mvd) {
+		uint64_t guid_delta = mvd->vdev_guid - cvd->vdev_guid;
+		cvd->vdev_orig_guid = cvd->vdev_guid;
+		cvd->vdev_guid += guid_delta;
+		cvd->vdev_guid_sum += guid_delta;
+
+		/*
+		 * If pool not set for autoexpand, we need to also preserve
+		 * mvd's asize to prevent automatic expansion of cvd.
+		 * Otherwise if we are adjusting the mirror by attaching and
+		 * detaching children of non-uniform sizes, the mirror could
+		 * autoexpand, unexpectedly requiring larger devices to
+		 * re-establish the mirror.
+		 */
+		if (!cvd->vdev_spa->spa_autoexpand)
+			cvd->vdev_asize = mvd->vdev_asize;
+	}
+	cvd->vdev_id = mvd->vdev_id;
+	vdev_add_child(pvd, cvd);
+	vdev_top_update(cvd->vdev_top, cvd->vdev_top);
+
+	if (cvd == cvd->vdev_top)
+		vdev_top_transfer(mvd, cvd);
+
+	ASSERT(mvd->vdev_children == 0);
+	vdev_free(mvd);
+}
+
+int
+vdev_metaslab_init(vdev_t *vd, uint64_t txg)
+{
+	spa_t *spa = vd->vdev_spa;
+	objset_t *mos = spa->spa_meta_objset;
+	uint64_t m;
+	uint64_t oldc = vd->vdev_ms_count;
+	uint64_t newc = vd->vdev_asize >> vd->vdev_ms_shift;
+	metaslab_t **mspp;
+	int error;
+
+	ASSERT(txg == 0 || spa_config_held(spa, SCL_ALLOC, RW_WRITER));
+
+	/*
+	 * This vdev is not being allocated from yet or is a hole.
+	 */
+	if (vd->vdev_ms_shift == 0)
+		return (0);
+
+	ASSERT(!vd->vdev_ishole);
+
+	/*
+	 * Compute the raidz-deflation ratio.  Note, we hard-code
+	 * in 128k (1 << 17) because it is the "typical" blocksize.
+	 * Even though SPA_MAXBLOCKSIZE changed, this algorithm can not change,
+	 * otherwise it would inconsistently account for existing bp's.
+	 */
+	vd->vdev_deflate_ratio = (1 << 17) /
+	    (vdev_psize_to_asize(vd, 1 << 17) >> SPA_MINBLOCKSHIFT);
+
+	ASSERT(oldc <= newc);
+
+	mspp = kmem_zalloc(newc * sizeof (*mspp), KM_SLEEP);
+
+	if (oldc != 0) {
+		bcopy(vd->vdev_ms, mspp, oldc * sizeof (*mspp));
+		kmem_free(vd->vdev_ms, oldc * sizeof (*mspp));
+	}
+
+	vd->vdev_ms = mspp;
+	vd->vdev_ms_count = newc;
+
+	for (m = oldc; m < newc; m++) {
+		uint64_t object = 0;
+
+		if (txg == 0) {
+			error = dmu_read(mos, vd->vdev_ms_array,
+			    m * sizeof (uint64_t), sizeof (uint64_t), &object,
+			    DMU_READ_PREFETCH);
+			if (error)
+				return (error);
+		}
+
+		error = metaslab_init(vd->vdev_mg, m, object, txg,
+		    &(vd->vdev_ms[m]));
+		if (error)
+			return (error);
+	}
+
+	if (txg == 0)
+		spa_config_enter(spa, SCL_ALLOC, FTAG, RW_WRITER);
+
+	/*
+	 * If the vdev is being removed we don't activate
+	 * the metaslabs since we want to ensure that no new
+	 * allocations are performed on this device.
+	 */
+	if (oldc == 0 && !vd->vdev_removing)
+		metaslab_group_activate(vd->vdev_mg);
+
+	if (txg == 0)
+		spa_config_exit(spa, SCL_ALLOC, FTAG);
+
+	return (0);
+}
+
+void
+vdev_metaslab_fini(vdev_t *vd)
+{
+	uint64_t m;
+	uint64_t count = vd->vdev_ms_count;
+
+	if (vd->vdev_ms != NULL) {
+		metaslab_group_passivate(vd->vdev_mg);
+		for (m = 0; m < count; m++) {
+			metaslab_t *msp = vd->vdev_ms[m];
+
+			if (msp != NULL)
+				metaslab_fini(msp);
+		}
+		kmem_free(vd->vdev_ms, count * sizeof (metaslab_t *));
+		vd->vdev_ms = NULL;
+	}
+
+	ASSERT3U(vd->vdev_pending_fastwrite, ==, 0);
+}
+
+typedef struct vdev_probe_stats {
+	boolean_t	vps_readable;
+	boolean_t	vps_writeable;
+	int		vps_flags;
+} vdev_probe_stats_t;
+
+static void
+vdev_probe_done(zio_t *zio)
+{
+	spa_t *spa = zio->io_spa;
+	vdev_t *vd = zio->io_vd;
+	vdev_probe_stats_t *vps = zio->io_private;
+
+	ASSERT(vd->vdev_probe_zio != NULL);
+
+	if (zio->io_type == ZIO_TYPE_READ) {
+		if (zio->io_error == 0)
+			vps->vps_readable = 1;
+		if (zio->io_error == 0 && spa_writeable(spa)) {
+			zio_nowait(zio_write_phys(vd->vdev_probe_zio, vd,
+			    zio->io_offset, zio->io_size, zio->io_data,
+			    ZIO_CHECKSUM_OFF, vdev_probe_done, vps,
+			    ZIO_PRIORITY_SYNC_WRITE, vps->vps_flags, B_TRUE));
+		} else {
+			zio_buf_free(zio->io_data, zio->io_size);
+		}
+	} else if (zio->io_type == ZIO_TYPE_WRITE) {
+		if (zio->io_error == 0)
+			vps->vps_writeable = 1;
+		zio_buf_free(zio->io_data, zio->io_size);
+	} else if (zio->io_type == ZIO_TYPE_NULL) {
+		zio_t *pio;
+
+		vd->vdev_cant_read |= !vps->vps_readable;
+		vd->vdev_cant_write |= !vps->vps_writeable;
+
+		if (vdev_readable(vd) &&
+		    (vdev_writeable(vd) || !spa_writeable(spa))) {
+			zio->io_error = 0;
+		} else {
+			ASSERT(zio->io_error != 0);
+			zfs_ereport_post(FM_EREPORT_ZFS_PROBE_FAILURE,
+			    spa, vd, NULL, 0, 0);
+			zio->io_error = SET_ERROR(ENXIO);
+		}
+
+		mutex_enter(&vd->vdev_probe_lock);
+		ASSERT(vd->vdev_probe_zio == zio);
+		vd->vdev_probe_zio = NULL;
+		mutex_exit(&vd->vdev_probe_lock);
+
+		while ((pio = zio_walk_parents(zio)) != NULL)
+			if (!vdev_accessible(vd, pio))
+				pio->io_error = SET_ERROR(ENXIO);
+
+		kmem_free(vps, sizeof (*vps));
+	}
+}
+
+/*
+ * Determine whether this device is accessible.
+ *
+ * Read and write to several known locations: the pad regions of each
+ * vdev label but the first, which we leave alone in case it contains
+ * a VTOC.
+ */
+zio_t *
+vdev_probe(vdev_t *vd, zio_t *zio)
+{
+	spa_t *spa = vd->vdev_spa;
+	vdev_probe_stats_t *vps = NULL;
+	zio_t *pio;
+	int l;
+
+	ASSERT(vd->vdev_ops->vdev_op_leaf);
+
+	/*
+	 * Don't probe the probe.
+	 */
+	if (zio && (zio->io_flags & ZIO_FLAG_PROBE))
+		return (NULL);
+
+	/*
+	 * To prevent 'probe storms' when a device fails, we create
+	 * just one probe i/o at a time.  All zios that want to probe
+	 * this vdev will become parents of the probe io.
+	 */
+	mutex_enter(&vd->vdev_probe_lock);
+
+	if ((pio = vd->vdev_probe_zio) == NULL) {
+		vps = kmem_zalloc(sizeof (*vps), KM_SLEEP);
+
+		vps->vps_flags = ZIO_FLAG_CANFAIL | ZIO_FLAG_PROBE |
+		    ZIO_FLAG_DONT_CACHE | ZIO_FLAG_DONT_AGGREGATE |
+		    ZIO_FLAG_TRYHARD;
+
+		if (spa_config_held(spa, SCL_ZIO, RW_WRITER)) {
+			/*
+			 * vdev_cant_read and vdev_cant_write can only
+			 * transition from TRUE to FALSE when we have the
+			 * SCL_ZIO lock as writer; otherwise they can only
+			 * transition from FALSE to TRUE.  This ensures that
+			 * any zio looking at these values can assume that
+			 * failures persist for the life of the I/O.  That's
+			 * important because when a device has intermittent
+			 * connectivity problems, we want to ensure that
+			 * they're ascribed to the device (ENXIO) and not
+			 * the zio (EIO).
+			 *
+			 * Since we hold SCL_ZIO as writer here, clear both
+			 * values so the probe can reevaluate from first
+			 * principles.
+			 */
+			vps->vps_flags |= ZIO_FLAG_CONFIG_WRITER;
+			vd->vdev_cant_read = B_FALSE;
+			vd->vdev_cant_write = B_FALSE;
+		}
+
+		vd->vdev_probe_zio = pio = zio_null(NULL, spa, vd,
+		    vdev_probe_done, vps,
+		    vps->vps_flags | ZIO_FLAG_DONT_PROPAGATE);
+
+		/*
+		 * We can't change the vdev state in this context, so we
+		 * kick off an async task to do it on our behalf.
+		 */
+		if (zio != NULL) {
+			vd->vdev_probe_wanted = B_TRUE;
+			spa_async_request(spa, SPA_ASYNC_PROBE);
+		}
+	}
+
+	if (zio != NULL)
+		zio_add_child(zio, pio);
+
+	mutex_exit(&vd->vdev_probe_lock);
+
+	if (vps == NULL) {
+		ASSERT(zio != NULL);
+		return (NULL);
+	}
+
+	for (l = 1; l < VDEV_LABELS; l++) {
+		zio_nowait(zio_read_phys(pio, vd,
+		    vdev_label_offset(vd->vdev_psize, l,
+		    offsetof(vdev_label_t, vl_pad2)),
+		    VDEV_PAD_SIZE, zio_buf_alloc(VDEV_PAD_SIZE),
+		    ZIO_CHECKSUM_OFF, vdev_probe_done, vps,
+		    ZIO_PRIORITY_SYNC_READ, vps->vps_flags, B_TRUE));
+	}
+
+	if (zio == NULL)
+		return (pio);
+
+	zio_nowait(pio);
+	return (NULL);
+}
+
+static void
+vdev_open_child(void *arg)
+{
+	vdev_t *vd = arg;
+
+	vd->vdev_open_thread = curthread;
+	vd->vdev_open_error = vdev_open(vd);
+	vd->vdev_open_thread = NULL;
+	vd->vdev_parent->vdev_nonrot &= vd->vdev_nonrot;
+}
+
+static boolean_t
+vdev_uses_zvols(vdev_t *vd)
+{
+	int c;
+
+#ifdef _KERNEL
+	if (zvol_is_zvol(vd->vdev_path))
+		return (B_TRUE);
+#endif
+
+	for (c = 0; c < vd->vdev_children; c++)
+		if (vdev_uses_zvols(vd->vdev_child[c]))
+			return (B_TRUE);
+
+	return (B_FALSE);
+}
+
+void
+vdev_open_children(vdev_t *vd)
+{
+	taskq_t *tq;
+	int children = vd->vdev_children;
+	int c;
+
+	vd->vdev_nonrot = B_TRUE;
+
+	/*
+	 * in order to handle pools on top of zvols, do the opens
+	 * in a single thread so that the same thread holds the
+	 * spa_namespace_lock
+	 */
+	if (vdev_uses_zvols(vd)) {
+		for (c = 0; c < children; c++) {
+			vd->vdev_child[c]->vdev_open_error =
+			    vdev_open(vd->vdev_child[c]);
+			vd->vdev_nonrot &= vd->vdev_child[c]->vdev_nonrot;
+		}
+		return;
+	}
+	tq = taskq_create("vdev_open", children, minclsyspri,
+	    children, children, TASKQ_PREPOPULATE);
+
+	for (c = 0; c < children; c++)
+		VERIFY(taskq_dispatch(tq, vdev_open_child, vd->vdev_child[c],
+		    TQ_SLEEP) != 0);
+
+	taskq_destroy(tq);
+
+	for (c = 0; c < children; c++)
+		vd->vdev_nonrot &= vd->vdev_child[c]->vdev_nonrot;
+}
+
+/*
+ * Prepare a virtual device for access.
+ */
+int
+vdev_open(vdev_t *vd)
+{
+	spa_t *spa = vd->vdev_spa;
+	int error;
+	uint64_t osize = 0;
+	uint64_t max_osize = 0;
+	uint64_t asize, max_asize, psize;
+	uint64_t ashift = 0;
+	int c;
+
+	ASSERT(vd->vdev_open_thread == curthread ||
+	    spa_config_held(spa, SCL_STATE_ALL, RW_WRITER) == SCL_STATE_ALL);
+	ASSERT(vd->vdev_state == VDEV_STATE_CLOSED ||
+	    vd->vdev_state == VDEV_STATE_CANT_OPEN ||
+	    vd->vdev_state == VDEV_STATE_OFFLINE);
+
+	vd->vdev_stat.vs_aux = VDEV_AUX_NONE;
+	vd->vdev_cant_read = B_FALSE;
+	vd->vdev_cant_write = B_FALSE;
+	vd->vdev_min_asize = vdev_get_min_asize(vd);
+
+	/*
+	 * If this vdev is not removed, check its fault status.  If it's
+	 * faulted, bail out of the open.
+	 */
+	if (!vd->vdev_removed && vd->vdev_faulted) {
+		ASSERT(vd->vdev_children == 0);
+		ASSERT(vd->vdev_label_aux == VDEV_AUX_ERR_EXCEEDED ||
+		    vd->vdev_label_aux == VDEV_AUX_EXTERNAL);
+		vdev_set_state(vd, B_TRUE, VDEV_STATE_FAULTED,
+		    vd->vdev_label_aux);
+		return (SET_ERROR(ENXIO));
+	} else if (vd->vdev_offline) {
+		ASSERT(vd->vdev_children == 0);
+		vdev_set_state(vd, B_TRUE, VDEV_STATE_OFFLINE, VDEV_AUX_NONE);
+		return (SET_ERROR(ENXIO));
+	}
+
+	error = vd->vdev_ops->vdev_op_open(vd, &osize, &max_osize, &ashift);
+
+	/*
+	 * Reset the vdev_reopening flag so that we actually close
+	 * the vdev on error.
+	 */
+	vd->vdev_reopening = B_FALSE;
+	if (zio_injection_enabled && error == 0)
+		error = zio_handle_device_injection(vd, NULL, ENXIO);
+
+	if (error) {
+		if (vd->vdev_removed &&
+		    vd->vdev_stat.vs_aux != VDEV_AUX_OPEN_FAILED)
+			vd->vdev_removed = B_FALSE;
+
+		vdev_set_state(vd, B_TRUE, VDEV_STATE_CANT_OPEN,
+		    vd->vdev_stat.vs_aux);
+		return (error);
+	}
+
+	vd->vdev_removed = B_FALSE;
+
+	/*
+	 * Recheck the faulted flag now that we have confirmed that
+	 * the vdev is accessible.  If we're faulted, bail.
+	 */
+	if (vd->vdev_faulted) {
+		ASSERT(vd->vdev_children == 0);
+		ASSERT(vd->vdev_label_aux == VDEV_AUX_ERR_EXCEEDED ||
+		    vd->vdev_label_aux == VDEV_AUX_EXTERNAL);
+		vdev_set_state(vd, B_TRUE, VDEV_STATE_FAULTED,
+		    vd->vdev_label_aux);
+		return (SET_ERROR(ENXIO));
+	}
+
+	if (vd->vdev_degraded) {
+		ASSERT(vd->vdev_children == 0);
+		vdev_set_state(vd, B_TRUE, VDEV_STATE_DEGRADED,
+		    VDEV_AUX_ERR_EXCEEDED);
+	} else {
+		vdev_set_state(vd, B_TRUE, VDEV_STATE_HEALTHY, 0);
+	}
+
+	/*
+	 * For hole or missing vdevs we just return success.
+	 */
+	if (vd->vdev_ishole || vd->vdev_ops == &vdev_missing_ops)
+		return (0);
+
+	for (c = 0; c < vd->vdev_children; c++) {
+		if (vd->vdev_child[c]->vdev_state != VDEV_STATE_HEALTHY) {
+			vdev_set_state(vd, B_TRUE, VDEV_STATE_DEGRADED,
+			    VDEV_AUX_NONE);
+			break;
+		}
+	}
+
+	osize = P2ALIGN(osize, (uint64_t)sizeof (vdev_label_t));
+	max_osize = P2ALIGN(max_osize, (uint64_t)sizeof (vdev_label_t));
+
+	if (vd->vdev_children == 0) {
+		if (osize < SPA_MINDEVSIZE) {
+			vdev_set_state(vd, B_TRUE, VDEV_STATE_CANT_OPEN,
+			    VDEV_AUX_TOO_SMALL);
+			return (SET_ERROR(EOVERFLOW));
+		}
+		psize = osize;
+		asize = osize - (VDEV_LABEL_START_SIZE + VDEV_LABEL_END_SIZE);
+		max_asize = max_osize - (VDEV_LABEL_START_SIZE +
+		    VDEV_LABEL_END_SIZE);
+	} else {
+		if (vd->vdev_parent != NULL && osize < SPA_MINDEVSIZE -
+		    (VDEV_LABEL_START_SIZE + VDEV_LABEL_END_SIZE)) {
+			vdev_set_state(vd, B_TRUE, VDEV_STATE_CANT_OPEN,
+			    VDEV_AUX_TOO_SMALL);
+			return (SET_ERROR(EOVERFLOW));
+		}
+		psize = 0;
+		asize = osize;
+		max_asize = max_osize;
+	}
+
+	vd->vdev_psize = psize;
+
+	/*
+	 * Make sure the allocatable size hasn't shrunk.
+	 */
+	if (asize < vd->vdev_min_asize) {
+		vdev_set_state(vd, B_TRUE, VDEV_STATE_CANT_OPEN,
+		    VDEV_AUX_BAD_LABEL);
+		return (SET_ERROR(EINVAL));
+	}
+
+	if (vd->vdev_asize == 0) {
+		/*
+		 * This is the first-ever open, so use the computed values.
+		 * For compatibility, a different ashift can be requested.
+		 */
+		vd->vdev_asize = asize;
+		vd->vdev_max_asize = max_asize;
+		if (vd->vdev_ashift == 0)
+			vd->vdev_ashift = ashift;
+	} else {
+		/*
+		 * Detect if the alignment requirement has increased.
+		 * We don't want to make the pool unavailable, just
+		 * post an event instead.
+		 */
+		if (ashift > vd->vdev_top->vdev_ashift &&
+		    vd->vdev_ops->vdev_op_leaf) {
+			zfs_ereport_post(FM_EREPORT_ZFS_DEVICE_BAD_ASHIFT,
+			    spa, vd, NULL, 0, 0);
+		}
+
+		vd->vdev_max_asize = max_asize;
+	}
+
+	/*
+	 * If all children are healthy and the asize has increased,
+	 * then we've experienced dynamic LUN growth.  If automatic
+	 * expansion is enabled then use the additional space.
+	 */
+	if (vd->vdev_state == VDEV_STATE_HEALTHY && asize > vd->vdev_asize &&
+	    (vd->vdev_expanding || spa->spa_autoexpand))
+		vd->vdev_asize = asize;
+
+	vdev_set_min_asize(vd);
+
+	/*
+	 * Ensure we can issue some IO before declaring the
+	 * vdev open for business.
+	 */
+	if (vd->vdev_ops->vdev_op_leaf &&
+	    (error = zio_wait(vdev_probe(vd, NULL))) != 0) {
+		vdev_set_state(vd, B_TRUE, VDEV_STATE_FAULTED,
+		    VDEV_AUX_ERR_EXCEEDED);
+		return (error);
+	}
+
+	/*
+	 * Track the min and max ashift values for normal data devices.
+	 */
+	if (vd->vdev_top == vd && vd->vdev_ashift != 0 &&
+	    !vd->vdev_islog && vd->vdev_aux == NULL) {
+		if (vd->vdev_ashift > spa->spa_max_ashift)
+			spa->spa_max_ashift = vd->vdev_ashift;
+		if (vd->vdev_ashift < spa->spa_min_ashift)
+			spa->spa_min_ashift = vd->vdev_ashift;
+	}
+
+	/*
+	 * If a leaf vdev has a DTL, and seems healthy, then kick off a
+	 * resilver.  But don't do this if we are doing a reopen for a scrub,
+	 * since this would just restart the scrub we are already doing.
+	 */
+	if (vd->vdev_ops->vdev_op_leaf && !spa->spa_scrub_reopen &&
+	    vdev_resilver_needed(vd, NULL, NULL))
+		spa_async_request(spa, SPA_ASYNC_RESILVER);
+
+	return (0);
+}
+
+/*
+ * Called once the vdevs are all opened, this routine validates the label
+ * contents.  This needs to be done before vdev_load() so that we don't
+ * inadvertently do repair I/Os to the wrong device.
+ *
+ * If 'strict' is false ignore the spa guid check. This is necessary because
+ * if the machine crashed during a re-guid the new guid might have been written
+ * to all of the vdev labels, but not the cached config. The strict check
+ * will be performed when the pool is opened again using the mos config.
+ *
+ * This function will only return failure if one of the vdevs indicates that it
+ * has since been destroyed or exported.  This is only possible if
+ * /etc/zfs/zpool.cache was readonly at the time.  Otherwise, the vdev state
+ * will be updated but the function will return 0.
+ */
+int
+vdev_validate(vdev_t *vd, boolean_t strict)
+{
+	spa_t *spa = vd->vdev_spa;
+	nvlist_t *label;
+	uint64_t guid = 0, top_guid;
+	uint64_t state;
+	int c;
+
+	for (c = 0; c < vd->vdev_children; c++)
+		if (vdev_validate(vd->vdev_child[c], strict) != 0)
+			return (SET_ERROR(EBADF));
+
+	/*
+	 * If the device has already failed, or was marked offline, don't do
+	 * any further validation.  Otherwise, label I/O will fail and we will
+	 * overwrite the previous state.
+	 */
+	if (vd->vdev_ops->vdev_op_leaf && vdev_readable(vd)) {
+		uint64_t aux_guid = 0;
+		nvlist_t *nvl;
+		uint64_t txg = spa_last_synced_txg(spa) != 0 ?
+		    spa_last_synced_txg(spa) : -1ULL;
+
+		if ((label = vdev_label_read_config(vd, txg)) == NULL) {
+			vdev_set_state(vd, B_TRUE, VDEV_STATE_CANT_OPEN,
+			    VDEV_AUX_BAD_LABEL);
+			return (0);
+		}
+
+		/*
+		 * Determine if this vdev has been split off into another
+		 * pool.  If so, then refuse to open it.
+		 */
+		if (nvlist_lookup_uint64(label, ZPOOL_CONFIG_SPLIT_GUID,
+		    &aux_guid) == 0 && aux_guid == spa_guid(spa)) {
+			vdev_set_state(vd, B_FALSE, VDEV_STATE_CANT_OPEN,
+			    VDEV_AUX_SPLIT_POOL);
+			nvlist_free(label);
+			return (0);
+		}
+
+		if (strict && (nvlist_lookup_uint64(label,
+		    ZPOOL_CONFIG_POOL_GUID, &guid) != 0 ||
+		    guid != spa_guid(spa))) {
+			vdev_set_state(vd, B_FALSE, VDEV_STATE_CANT_OPEN,
+			    VDEV_AUX_CORRUPT_DATA);
+			nvlist_free(label);
+			return (0);
+		}
+
+		if (nvlist_lookup_nvlist(label, ZPOOL_CONFIG_VDEV_TREE, &nvl)
+		    != 0 || nvlist_lookup_uint64(nvl, ZPOOL_CONFIG_ORIG_GUID,
+		    &aux_guid) != 0)
+			aux_guid = 0;
+
+		/*
+		 * If this vdev just became a top-level vdev because its
+		 * sibling was detached, it will have adopted the parent's
+		 * vdev guid -- but the label may or may not be on disk yet.
+		 * Fortunately, either version of the label will have the
+		 * same top guid, so if we're a top-level vdev, we can
+		 * safely compare to that instead.
+		 *
+		 * If we split this vdev off instead, then we also check the
+		 * original pool's guid.  We don't want to consider the vdev
+		 * corrupt if it is partway through a split operation.
+		 */
+		if (nvlist_lookup_uint64(label, ZPOOL_CONFIG_GUID,
+		    &guid) != 0 ||
+		    nvlist_lookup_uint64(label, ZPOOL_CONFIG_TOP_GUID,
+		    &top_guid) != 0 ||
+		    ((vd->vdev_guid != guid && vd->vdev_guid != aux_guid) &&
+		    (vd->vdev_guid != top_guid || vd != vd->vdev_top))) {
+			vdev_set_state(vd, B_FALSE, VDEV_STATE_CANT_OPEN,
+			    VDEV_AUX_CORRUPT_DATA);
+			nvlist_free(label);
+			return (0);
+		}
+
+		if (nvlist_lookup_uint64(label, ZPOOL_CONFIG_POOL_STATE,
+		    &state) != 0) {
+			vdev_set_state(vd, B_FALSE, VDEV_STATE_CANT_OPEN,
+			    VDEV_AUX_CORRUPT_DATA);
+			nvlist_free(label);
+			return (0);
+		}
+
+		nvlist_free(label);
+
+		/*
+		 * If this is a verbatim import, no need to check the
+		 * state of the pool.
+		 */
+		if (!(spa->spa_import_flags & ZFS_IMPORT_VERBATIM) &&
+		    spa_load_state(spa) == SPA_LOAD_OPEN &&
+		    state != POOL_STATE_ACTIVE)
+			return (SET_ERROR(EBADF));
+
+		/*
+		 * If we were able to open and validate a vdev that was
+		 * previously marked permanently unavailable, clear that state
+		 * now.
+		 */
+		if (vd->vdev_not_present)
+			vd->vdev_not_present = 0;
+	}
+
+	return (0);
+}
+
+/*
+ * Close a virtual device.
+ */
+void
+vdev_close(vdev_t *vd)
+{
+	vdev_t *pvd = vd->vdev_parent;
+	ASSERTV(spa_t *spa = vd->vdev_spa);
+
+	ASSERT(spa_config_held(spa, SCL_STATE_ALL, RW_WRITER) == SCL_STATE_ALL);
+
+	/*
+	 * If our parent is reopening, then we are as well, unless we are
+	 * going offline.
+	 */
+	if (pvd != NULL && pvd->vdev_reopening)
+		vd->vdev_reopening = (pvd->vdev_reopening && !vd->vdev_offline);
+
+	vd->vdev_ops->vdev_op_close(vd);
+
+	vdev_cache_purge(vd);
+
+	/*
+	 * We record the previous state before we close it, so that if we are
+	 * doing a reopen(), we don't generate FMA ereports if we notice that
+	 * it's still faulted.
+	 */
+	vd->vdev_prevstate = vd->vdev_state;
+
+	if (vd->vdev_offline)
+		vd->vdev_state = VDEV_STATE_OFFLINE;
+	else
+		vd->vdev_state = VDEV_STATE_CLOSED;
+	vd->vdev_stat.vs_aux = VDEV_AUX_NONE;
+}
+
+void
+vdev_hold(vdev_t *vd)
+{
+	spa_t *spa = vd->vdev_spa;
+	int c;
+
+	ASSERT(spa_is_root(spa));
+	if (spa->spa_state == POOL_STATE_UNINITIALIZED)
+		return;
+
+	for (c = 0; c < vd->vdev_children; c++)
+		vdev_hold(vd->vdev_child[c]);
+
+	if (vd->vdev_ops->vdev_op_leaf)
+		vd->vdev_ops->vdev_op_hold(vd);
+}
+
+void
+vdev_rele(vdev_t *vd)
+{
+	int c;
+
+	ASSERT(spa_is_root(vd->vdev_spa));
+	for (c = 0; c < vd->vdev_children; c++)
+		vdev_rele(vd->vdev_child[c]);
+
+	if (vd->vdev_ops->vdev_op_leaf)
+		vd->vdev_ops->vdev_op_rele(vd);
+}
+
+/*
+ * Reopen all interior vdevs and any unopened leaves.  We don't actually
+ * reopen leaf vdevs which had previously been opened as they might deadlock
+ * on the spa_config_lock.  Instead we only obtain the leaf's physical size.
+ * If the leaf has never been opened then open it, as usual.
+ */
+void
+vdev_reopen(vdev_t *vd)
+{
+	spa_t *spa = vd->vdev_spa;
+
+	ASSERT(spa_config_held(spa, SCL_STATE_ALL, RW_WRITER) == SCL_STATE_ALL);
+
+	/* set the reopening flag unless we're taking the vdev offline */
+	vd->vdev_reopening = !vd->vdev_offline;
+	vdev_close(vd);
+	(void) vdev_open(vd);
+
+	/*
+	 * Call vdev_validate() here to make sure we have the same device.
+	 * Otherwise, a device with an invalid label could be successfully
+	 * opened in response to vdev_reopen().
+	 */
+	if (vd->vdev_aux) {
+		(void) vdev_validate_aux(vd);
+		if (vdev_readable(vd) && vdev_writeable(vd) &&
+		    vd->vdev_aux == &spa->spa_l2cache &&
+		    !l2arc_vdev_present(vd))
+			l2arc_add_vdev(spa, vd);
+	} else {
+		(void) vdev_validate(vd, B_TRUE);
+	}
+
+	/*
+	 * Reassess parent vdev's health.
+	 */
+	vdev_propagate_state(vd);
+}
+
+int
+vdev_create(vdev_t *vd, uint64_t txg, boolean_t isreplacing)
+{
+	int error;
+
+	/*
+	 * Normally, partial opens (e.g. of a mirror) are allowed.
+	 * For a create, however, we want to fail the request if
+	 * there are any components we can't open.
+	 */
+	error = vdev_open(vd);
+
+	if (error || vd->vdev_state != VDEV_STATE_HEALTHY) {
+		vdev_close(vd);
+		return (error ? error : ENXIO);
+	}
+
+	/*
+	 * Recursively load DTLs and initialize all labels.
+	 */
+	if ((error = vdev_dtl_load(vd)) != 0 ||
+	    (error = vdev_label_init(vd, txg, isreplacing ?
+	    VDEV_LABEL_REPLACE : VDEV_LABEL_CREATE)) != 0) {
+		vdev_close(vd);
+		return (error);
+	}
+
+	return (0);
+}
+
+void
+vdev_metaslab_set_size(vdev_t *vd)
+{
+	/*
+	 * Aim for roughly metaslabs_per_vdev (default 200) metaslabs per vdev.
+	 */
+	vd->vdev_ms_shift = highbit64(vd->vdev_asize / metaslabs_per_vdev);
+	vd->vdev_ms_shift = MAX(vd->vdev_ms_shift, SPA_MAXBLOCKSHIFT);
+}
+
+void
+vdev_dirty(vdev_t *vd, int flags, void *arg, uint64_t txg)
+{
+	ASSERT(vd == vd->vdev_top);
+	ASSERT(!vd->vdev_ishole);
+	ASSERT(ISP2(flags));
+	ASSERT(spa_writeable(vd->vdev_spa));
+
+	if (flags & VDD_METASLAB)
+		(void) txg_list_add(&vd->vdev_ms_list, arg, txg);
+
+	if (flags & VDD_DTL)
+		(void) txg_list_add(&vd->vdev_dtl_list, arg, txg);
+
+	(void) txg_list_add(&vd->vdev_spa->spa_vdev_txg_list, vd, txg);
+}
+
+void
+vdev_dirty_leaves(vdev_t *vd, int flags, uint64_t txg)
+{
+	int c;
+
+	for (c = 0; c < vd->vdev_children; c++)
+		vdev_dirty_leaves(vd->vdev_child[c], flags, txg);
+
+	if (vd->vdev_ops->vdev_op_leaf)
+		vdev_dirty(vd->vdev_top, flags, vd, txg);
+}
+
+/*
+ * DTLs.
+ *
+ * A vdev's DTL (dirty time log) is the set of transaction groups for which
+ * the vdev has less than perfect replication.  There are four kinds of DTL:
+ *
+ * DTL_MISSING: txgs for which the vdev has no valid copies of the data
+ *
+ * DTL_PARTIAL: txgs for which data is available, but not fully replicated
+ *
+ * DTL_SCRUB: the txgs that could not be repaired by the last scrub; upon
+ *	scrub completion, DTL_SCRUB replaces DTL_MISSING in the range of
+ *	txgs that was scrubbed.
+ *
+ * DTL_OUTAGE: txgs which cannot currently be read, whether due to
+ *	persistent errors or just some device being offline.
+ *	Unlike the other three, the DTL_OUTAGE map is not generally
+ *	maintained; it's only computed when needed, typically to
+ *	determine whether a device can be detached.
+ *
+ * For leaf vdevs, DTL_MISSING and DTL_PARTIAL are identical: the device
+ * either has the data or it doesn't.
+ *
+ * For interior vdevs such as mirror and RAID-Z the picture is more complex.
+ * A vdev's DTL_PARTIAL is the union of its children's DTL_PARTIALs, because
+ * if any child is less than fully replicated, then so is its parent.
+ * A vdev's DTL_MISSING is a modified union of its children's DTL_MISSINGs,
+ * comprising only those txgs which appear in 'maxfaults' or more children;
+ * those are the txgs we don't have enough replication to read.  For example,
+ * double-parity RAID-Z can tolerate up to two missing devices (maxfaults == 2);
+ * thus, its DTL_MISSING consists of the set of txgs that appear in more than
+ * two child DTL_MISSING maps.
+ *
+ * It should be clear from the above that to compute the DTLs and outage maps
+ * for all vdevs, it suffices to know just the leaf vdevs' DTL_MISSING maps.
+ * Therefore, that is all we keep on disk.  When loading the pool, or after
+ * a configuration change, we generate all other DTLs from first principles.
+ */
+void
+vdev_dtl_dirty(vdev_t *vd, vdev_dtl_type_t t, uint64_t txg, uint64_t size)
+{
+	range_tree_t *rt = vd->vdev_dtl[t];
+
+	ASSERT(t < DTL_TYPES);
+	ASSERT(vd != vd->vdev_spa->spa_root_vdev);
+	ASSERT(spa_writeable(vd->vdev_spa));
+
+	mutex_enter(rt->rt_lock);
+	if (!range_tree_contains(rt, txg, size))
+		range_tree_add(rt, txg, size);
+	mutex_exit(rt->rt_lock);
+}
+
+boolean_t
+vdev_dtl_contains(vdev_t *vd, vdev_dtl_type_t t, uint64_t txg, uint64_t size)
+{
+	range_tree_t *rt = vd->vdev_dtl[t];
+	boolean_t dirty = B_FALSE;
+
+	ASSERT(t < DTL_TYPES);
+	ASSERT(vd != vd->vdev_spa->spa_root_vdev);
+
+	mutex_enter(rt->rt_lock);
+	if (range_tree_space(rt) != 0)
+		dirty = range_tree_contains(rt, txg, size);
+	mutex_exit(rt->rt_lock);
+
+	return (dirty);
+}
+
+boolean_t
+vdev_dtl_empty(vdev_t *vd, vdev_dtl_type_t t)
+{
+	range_tree_t *rt = vd->vdev_dtl[t];
+	boolean_t empty;
+
+	mutex_enter(rt->rt_lock);
+	empty = (range_tree_space(rt) == 0);
+	mutex_exit(rt->rt_lock);
+
+	return (empty);
+}
+
+/*
+ * Returns the lowest txg in the DTL range.
+ */
+static uint64_t
+vdev_dtl_min(vdev_t *vd)
+{
+	range_seg_t *rs;
+
+	ASSERT(MUTEX_HELD(&vd->vdev_dtl_lock));
+	ASSERT3U(range_tree_space(vd->vdev_dtl[DTL_MISSING]), !=, 0);
+	ASSERT0(vd->vdev_children);
+
+	rs = avl_first(&vd->vdev_dtl[DTL_MISSING]->rt_root);
+	return (rs->rs_start - 1);
+}
+
+/*
+ * Returns the highest txg in the DTL.
+ */
+static uint64_t
+vdev_dtl_max(vdev_t *vd)
+{
+	range_seg_t *rs;
+
+	ASSERT(MUTEX_HELD(&vd->vdev_dtl_lock));
+	ASSERT3U(range_tree_space(vd->vdev_dtl[DTL_MISSING]), !=, 0);
+	ASSERT0(vd->vdev_children);
+
+	rs = avl_last(&vd->vdev_dtl[DTL_MISSING]->rt_root);
+	return (rs->rs_end);
+}
+
+/*
+ * Determine if a resilvering vdev should remove any DTL entries from
+ * its range. If the vdev was resilvering for the entire duration of the
+ * scan then it should excise that range from its DTLs. Otherwise, this
+ * vdev is considered partially resilvered and should leave its DTL
+ * entries intact. The comment in vdev_dtl_reassess() describes how we
+ * excise the DTLs.
+ */
+static boolean_t
+vdev_dtl_should_excise(vdev_t *vd)
+{
+	spa_t *spa = vd->vdev_spa;
+	dsl_scan_t *scn = spa->spa_dsl_pool->dp_scan;
+
+	ASSERT0(scn->scn_phys.scn_errors);
+	ASSERT0(vd->vdev_children);
+
+	if (vd->vdev_resilver_txg == 0 ||
+	    range_tree_space(vd->vdev_dtl[DTL_MISSING]) == 0)
+		return (B_TRUE);
+
+	/*
+	 * When a resilver is initiated the scan will assign the scn_max_txg
+	 * value to the highest txg value that exists in all DTLs. If this
+	 * device's max DTL is not part of this scan (i.e. it is not in
+	 * the range (scn_min_txg, scn_max_txg] then it is not eligible
+	 * for excision.
+	 */
+	if (vdev_dtl_max(vd) <= scn->scn_phys.scn_max_txg) {
+		ASSERT3U(scn->scn_phys.scn_min_txg, <=, vdev_dtl_min(vd));
+		ASSERT3U(scn->scn_phys.scn_min_txg, <, vd->vdev_resilver_txg);
+		ASSERT3U(vd->vdev_resilver_txg, <=, scn->scn_phys.scn_max_txg);
+		return (B_TRUE);
+	}
+	return (B_FALSE);
+}
+
+/*
+ * Reassess DTLs after a config change or scrub completion.
+ */
+void
+vdev_dtl_reassess(vdev_t *vd, uint64_t txg, uint64_t scrub_txg, int scrub_done)
+{
+	spa_t *spa = vd->vdev_spa;
+	avl_tree_t reftree;
+	int c, t, minref;
+
+	ASSERT(spa_config_held(spa, SCL_ALL, RW_READER) != 0);
+
+	for (c = 0; c < vd->vdev_children; c++)
+		vdev_dtl_reassess(vd->vdev_child[c], txg,
+		    scrub_txg, scrub_done);
+
+	if (vd == spa->spa_root_vdev || vd->vdev_ishole || vd->vdev_aux)
+		return;
+
+	if (vd->vdev_ops->vdev_op_leaf) {
+		dsl_scan_t *scn = spa->spa_dsl_pool->dp_scan;
+
+		mutex_enter(&vd->vdev_dtl_lock);
+
+		/*
+		 * If we've completed a scan cleanly then determine
+		 * if this vdev should remove any DTLs. We only want to
+		 * excise regions on vdevs that were available during
+		 * the entire duration of this scan.
+		 */
+		if (scrub_txg != 0 &&
+		    (spa->spa_scrub_started ||
+		    (scn != NULL && scn->scn_phys.scn_errors == 0)) &&
+		    vdev_dtl_should_excise(vd)) {
+			/*
+			 * We completed a scrub up to scrub_txg.  If we
+			 * did it without rebooting, then the scrub dtl
+			 * will be valid, so excise the old region and
+			 * fold in the scrub dtl.  Otherwise, leave the
+			 * dtl as-is if there was an error.
+			 *
+			 * There's little trick here: to excise the beginning
+			 * of the DTL_MISSING map, we put it into a reference
+			 * tree and then add a segment with refcnt -1 that
+			 * covers the range [0, scrub_txg).  This means
+			 * that each txg in that range has refcnt -1 or 0.
+			 * We then add DTL_SCRUB with a refcnt of 2, so that
+			 * entries in the range [0, scrub_txg) will have a
+			 * positive refcnt -- either 1 or 2.  We then convert
+			 * the reference tree into the new DTL_MISSING map.
+			 */
+			space_reftree_create(&reftree);
+			space_reftree_add_map(&reftree,
+			    vd->vdev_dtl[DTL_MISSING], 1);
+			space_reftree_add_seg(&reftree, 0, scrub_txg, -1);
+			space_reftree_add_map(&reftree,
+			    vd->vdev_dtl[DTL_SCRUB], 2);
+			space_reftree_generate_map(&reftree,
+			    vd->vdev_dtl[DTL_MISSING], 1);
+			space_reftree_destroy(&reftree);
+		}
+		range_tree_vacate(vd->vdev_dtl[DTL_PARTIAL], NULL, NULL);
+		range_tree_walk(vd->vdev_dtl[DTL_MISSING],
+		    range_tree_add, vd->vdev_dtl[DTL_PARTIAL]);
+		if (scrub_done)
+			range_tree_vacate(vd->vdev_dtl[DTL_SCRUB], NULL, NULL);
+		range_tree_vacate(vd->vdev_dtl[DTL_OUTAGE], NULL, NULL);
+		if (!vdev_readable(vd))
+			range_tree_add(vd->vdev_dtl[DTL_OUTAGE], 0, -1ULL);
+		else
+			range_tree_walk(vd->vdev_dtl[DTL_MISSING],
+			    range_tree_add, vd->vdev_dtl[DTL_OUTAGE]);
+
+		/*
+		 * If the vdev was resilvering and no longer has any
+		 * DTLs then reset its resilvering flag.
+		 */
+		if (vd->vdev_resilver_txg != 0 &&
+		    range_tree_space(vd->vdev_dtl[DTL_MISSING]) == 0 &&
+		    range_tree_space(vd->vdev_dtl[DTL_OUTAGE]) == 0)
+			vd->vdev_resilver_txg = 0;
+
+		mutex_exit(&vd->vdev_dtl_lock);
+
+		if (txg != 0)
+			vdev_dirty(vd->vdev_top, VDD_DTL, vd, txg);
+		return;
+	}
+
+	mutex_enter(&vd->vdev_dtl_lock);
+	for (t = 0; t < DTL_TYPES; t++) {
+		int c;
+
+		/* account for child's outage in parent's missing map */
+		int s = (t == DTL_MISSING) ? DTL_OUTAGE: t;
+		if (t == DTL_SCRUB)
+			continue;			/* leaf vdevs only */
+		if (t == DTL_PARTIAL)
+			minref = 1;			/* i.e. non-zero */
+		else if (vd->vdev_nparity != 0)
+			minref = vd->vdev_nparity + 1;	/* RAID-Z */
+		else
+			minref = vd->vdev_children;	/* any kind of mirror */
+		space_reftree_create(&reftree);
+		for (c = 0; c < vd->vdev_children; c++) {
+			vdev_t *cvd = vd->vdev_child[c];
+			mutex_enter(&cvd->vdev_dtl_lock);
+			space_reftree_add_map(&reftree, cvd->vdev_dtl[s], 1);
+			mutex_exit(&cvd->vdev_dtl_lock);
+		}
+		space_reftree_generate_map(&reftree, vd->vdev_dtl[t], minref);
+		space_reftree_destroy(&reftree);
+	}
+	mutex_exit(&vd->vdev_dtl_lock);
+}
+
+int
+vdev_dtl_load(vdev_t *vd)
+{
+	spa_t *spa = vd->vdev_spa;
+	objset_t *mos = spa->spa_meta_objset;
+	int error = 0;
+	int c;
+
+	if (vd->vdev_ops->vdev_op_leaf && vd->vdev_dtl_object != 0) {
+		ASSERT(!vd->vdev_ishole);
+
+		error = space_map_open(&vd->vdev_dtl_sm, mos,
+		    vd->vdev_dtl_object, 0, -1ULL, 0, &vd->vdev_dtl_lock);
+		if (error)
+			return (error);
+		ASSERT(vd->vdev_dtl_sm != NULL);
+
+		mutex_enter(&vd->vdev_dtl_lock);
+
+		/*
+		 * Now that we've opened the space_map we need to update
+		 * the in-core DTL.
+		 */
+		space_map_update(vd->vdev_dtl_sm);
+
+		error = space_map_load(vd->vdev_dtl_sm,
+		    vd->vdev_dtl[DTL_MISSING], SM_ALLOC);
+		mutex_exit(&vd->vdev_dtl_lock);
+
+		return (error);
+	}
+
+	for (c = 0; c < vd->vdev_children; c++) {
+		error = vdev_dtl_load(vd->vdev_child[c]);
+		if (error != 0)
+			break;
+	}
+
+	return (error);
+}
+
+void
+vdev_dtl_sync(vdev_t *vd, uint64_t txg)
+{
+	spa_t *spa = vd->vdev_spa;
+	range_tree_t *rt = vd->vdev_dtl[DTL_MISSING];
+	objset_t *mos = spa->spa_meta_objset;
+	range_tree_t *rtsync;
+	kmutex_t rtlock;
+	dmu_tx_t *tx;
+	uint64_t object = space_map_object(vd->vdev_dtl_sm);
+
+	ASSERT(!vd->vdev_ishole);
+	ASSERT(vd->vdev_ops->vdev_op_leaf);
+
+	tx = dmu_tx_create_assigned(spa->spa_dsl_pool, txg);
+
+	if (vd->vdev_detached || vd->vdev_top->vdev_removing) {
+		mutex_enter(&vd->vdev_dtl_lock);
+		space_map_free(vd->vdev_dtl_sm, tx);
+		space_map_close(vd->vdev_dtl_sm);
+		vd->vdev_dtl_sm = NULL;
+		mutex_exit(&vd->vdev_dtl_lock);
+		dmu_tx_commit(tx);
+		return;
+	}
+
+	if (vd->vdev_dtl_sm == NULL) {
+		uint64_t new_object;
+
+		new_object = space_map_alloc(mos, tx);
+		VERIFY3U(new_object, !=, 0);
+
+		VERIFY0(space_map_open(&vd->vdev_dtl_sm, mos, new_object,
+		    0, -1ULL, 0, &vd->vdev_dtl_lock));
+		ASSERT(vd->vdev_dtl_sm != NULL);
+	}
+
+	mutex_init(&rtlock, NULL, MUTEX_DEFAULT, NULL);
+
+	rtsync = range_tree_create(NULL, NULL, &rtlock);
+
+	mutex_enter(&rtlock);
+
+	mutex_enter(&vd->vdev_dtl_lock);
+	range_tree_walk(rt, range_tree_add, rtsync);
+	mutex_exit(&vd->vdev_dtl_lock);
+
+	space_map_truncate(vd->vdev_dtl_sm, tx);
+	space_map_write(vd->vdev_dtl_sm, rtsync, SM_ALLOC, tx);
+	range_tree_vacate(rtsync, NULL, NULL);
+
+	range_tree_destroy(rtsync);
+
+	mutex_exit(&rtlock);
+	mutex_destroy(&rtlock);
+
+	/*
+	 * If the object for the space map has changed then dirty
+	 * the top level so that we update the config.
+	 */
+	if (object != space_map_object(vd->vdev_dtl_sm)) {
+		zfs_dbgmsg("txg %llu, spa %s, DTL old object %llu, "
+		    "new object %llu", txg, spa_name(spa), object,
+		    space_map_object(vd->vdev_dtl_sm));
+		vdev_config_dirty(vd->vdev_top);
+	}
+
+	dmu_tx_commit(tx);
+
+	mutex_enter(&vd->vdev_dtl_lock);
+	space_map_update(vd->vdev_dtl_sm);
+	mutex_exit(&vd->vdev_dtl_lock);
+}
+
+/*
+ * Determine whether the specified vdev can be offlined/detached/removed
+ * without losing data.
+ */
+boolean_t
+vdev_dtl_required(vdev_t *vd)
+{
+	spa_t *spa = vd->vdev_spa;
+	vdev_t *tvd = vd->vdev_top;
+	uint8_t cant_read = vd->vdev_cant_read;
+	boolean_t required;
+
+	ASSERT(spa_config_held(spa, SCL_STATE_ALL, RW_WRITER) == SCL_STATE_ALL);
+
+	if (vd == spa->spa_root_vdev || vd == tvd)
+		return (B_TRUE);
+
+	/*
+	 * Temporarily mark the device as unreadable, and then determine
+	 * whether this results in any DTL outages in the top-level vdev.
+	 * If not, we can safely offline/detach/remove the device.
+	 */
+	vd->vdev_cant_read = B_TRUE;
+	vdev_dtl_reassess(tvd, 0, 0, B_FALSE);
+	required = !vdev_dtl_empty(tvd, DTL_OUTAGE);
+	vd->vdev_cant_read = cant_read;
+	vdev_dtl_reassess(tvd, 0, 0, B_FALSE);
+
+	if (!required && zio_injection_enabled)
+		required = !!zio_handle_device_injection(vd, NULL, ECHILD);
+
+	return (required);
+}
+
+/*
+ * Determine if resilver is needed, and if so the txg range.
+ */
+boolean_t
+vdev_resilver_needed(vdev_t *vd, uint64_t *minp, uint64_t *maxp)
+{
+	boolean_t needed = B_FALSE;
+	uint64_t thismin = UINT64_MAX;
+	uint64_t thismax = 0;
+	int c;
+
+	if (vd->vdev_children == 0) {
+		mutex_enter(&vd->vdev_dtl_lock);
+		if (range_tree_space(vd->vdev_dtl[DTL_MISSING]) != 0 &&
+		    vdev_writeable(vd)) {
+
+			thismin = vdev_dtl_min(vd);
+			thismax = vdev_dtl_max(vd);
+			needed = B_TRUE;
+		}
+		mutex_exit(&vd->vdev_dtl_lock);
+	} else {
+		for (c = 0; c < vd->vdev_children; c++) {
+			vdev_t *cvd = vd->vdev_child[c];
+			uint64_t cmin, cmax;
+
+			if (vdev_resilver_needed(cvd, &cmin, &cmax)) {
+				thismin = MIN(thismin, cmin);
+				thismax = MAX(thismax, cmax);
+				needed = B_TRUE;
+			}
+		}
+	}
+
+	if (needed && minp) {
+		*minp = thismin;
+		*maxp = thismax;
+	}
+	return (needed);
+}
+
+void
+vdev_load(vdev_t *vd)
+{
+	int c;
+
+	/*
+	 * Recursively load all children.
+	 */
+	for (c = 0; c < vd->vdev_children; c++)
+		vdev_load(vd->vdev_child[c]);
+
+	/*
+	 * If this is a top-level vdev, initialize its metaslabs.
+	 */
+	if (vd == vd->vdev_top && !vd->vdev_ishole &&
+	    (vd->vdev_ashift == 0 || vd->vdev_asize == 0 ||
+	    vdev_metaslab_init(vd, 0) != 0))
+		vdev_set_state(vd, B_FALSE, VDEV_STATE_CANT_OPEN,
+		    VDEV_AUX_CORRUPT_DATA);
+
+	/*
+	 * If this is a leaf vdev, load its DTL.
+	 */
+	if (vd->vdev_ops->vdev_op_leaf && vdev_dtl_load(vd) != 0)
+		vdev_set_state(vd, B_FALSE, VDEV_STATE_CANT_OPEN,
+		    VDEV_AUX_CORRUPT_DATA);
+}
+
+/*
+ * The special vdev case is used for hot spares and l2cache devices.  Its
+ * sole purpose it to set the vdev state for the associated vdev.  To do this,
+ * we make sure that we can open the underlying device, then try to read the
+ * label, and make sure that the label is sane and that it hasn't been
+ * repurposed to another pool.
+ */
+int
+vdev_validate_aux(vdev_t *vd)
+{
+	nvlist_t *label;
+	uint64_t guid, version;
+	uint64_t state;
+
+	if (!vdev_readable(vd))
+		return (0);
+
+	if ((label = vdev_label_read_config(vd, -1ULL)) == NULL) {
+		vdev_set_state(vd, B_TRUE, VDEV_STATE_CANT_OPEN,
+		    VDEV_AUX_CORRUPT_DATA);
+		return (-1);
+	}
+
+	if (nvlist_lookup_uint64(label, ZPOOL_CONFIG_VERSION, &version) != 0 ||
+	    !SPA_VERSION_IS_SUPPORTED(version) ||
+	    nvlist_lookup_uint64(label, ZPOOL_CONFIG_GUID, &guid) != 0 ||
+	    guid != vd->vdev_guid ||
+	    nvlist_lookup_uint64(label, ZPOOL_CONFIG_POOL_STATE, &state) != 0) {
+		vdev_set_state(vd, B_TRUE, VDEV_STATE_CANT_OPEN,
+		    VDEV_AUX_CORRUPT_DATA);
+		nvlist_free(label);
+		return (-1);
+	}
+
+	/*
+	 * We don't actually check the pool state here.  If it's in fact in
+	 * use by another pool, we update this fact on the fly when requested.
+	 */
+	nvlist_free(label);
+	return (0);
+}
+
+void
+vdev_remove(vdev_t *vd, uint64_t txg)
+{
+	spa_t *spa = vd->vdev_spa;
+	objset_t *mos = spa->spa_meta_objset;
+	dmu_tx_t *tx;
+	int m, i;
+
+	tx = dmu_tx_create_assigned(spa_get_dsl(spa), txg);
+
+	if (vd->vdev_ms != NULL) {
+		metaslab_group_t *mg = vd->vdev_mg;
+
+		metaslab_group_histogram_verify(mg);
+		metaslab_class_histogram_verify(mg->mg_class);
+
+		for (m = 0; m < vd->vdev_ms_count; m++) {
+			metaslab_t *msp = vd->vdev_ms[m];
+
+			if (msp == NULL || msp->ms_sm == NULL)
+				continue;
+
+			mutex_enter(&msp->ms_lock);
+			/*
+			 * If the metaslab was not loaded when the vdev
+			 * was removed then the histogram accounting may
+			 * not be accurate. Update the histogram information
+			 * here so that we ensure that the metaslab group
+			 * and metaslab class are up-to-date.
+			 */
+			metaslab_group_histogram_remove(mg, msp);
+
+			VERIFY0(space_map_allocated(msp->ms_sm));
+			space_map_free(msp->ms_sm, tx);
+			space_map_close(msp->ms_sm);
+			msp->ms_sm = NULL;
+			mutex_exit(&msp->ms_lock);
+		}
+
+		metaslab_group_histogram_verify(mg);
+		metaslab_class_histogram_verify(mg->mg_class);
+		for (i = 0; i < RANGE_TREE_HISTOGRAM_SIZE; i++)
+			ASSERT0(mg->mg_histogram[i]);
+
+	}
+
+	if (vd->vdev_ms_array) {
+		(void) dmu_object_free(mos, vd->vdev_ms_array, tx);
+		vd->vdev_ms_array = 0;
+	}
+	dmu_tx_commit(tx);
+}
+
+void
+vdev_sync_done(vdev_t *vd, uint64_t txg)
+{
+	metaslab_t *msp;
+	boolean_t reassess = !txg_list_empty(&vd->vdev_ms_list, TXG_CLEAN(txg));
+
+	ASSERT(!vd->vdev_ishole);
+
+	while ((msp = txg_list_remove(&vd->vdev_ms_list, TXG_CLEAN(txg))))
+		metaslab_sync_done(msp, txg);
+
+	if (reassess)
+		metaslab_sync_reassess(vd->vdev_mg);
+}
+
+void
+vdev_sync(vdev_t *vd, uint64_t txg)
+{
+	spa_t *spa = vd->vdev_spa;
+	vdev_t *lvd;
+	metaslab_t *msp;
+	dmu_tx_t *tx;
+
+	ASSERT(!vd->vdev_ishole);
+
+	if (vd->vdev_ms_array == 0 && vd->vdev_ms_shift != 0) {
+		ASSERT(vd == vd->vdev_top);
+		tx = dmu_tx_create_assigned(spa->spa_dsl_pool, txg);
+		vd->vdev_ms_array = dmu_object_alloc(spa->spa_meta_objset,
+		    DMU_OT_OBJECT_ARRAY, 0, DMU_OT_NONE, 0, tx);
+		ASSERT(vd->vdev_ms_array != 0);
+		vdev_config_dirty(vd);
+		dmu_tx_commit(tx);
+	}
+
+	/*
+	 * Remove the metadata associated with this vdev once it's empty.
+	 */
+	if (vd->vdev_stat.vs_alloc == 0 && vd->vdev_removing)
+		vdev_remove(vd, txg);
+
+	while ((msp = txg_list_remove(&vd->vdev_ms_list, txg)) != NULL) {
+		metaslab_sync(msp, txg);
+		(void) txg_list_add(&vd->vdev_ms_list, msp, TXG_CLEAN(txg));
+	}
+
+	while ((lvd = txg_list_remove(&vd->vdev_dtl_list, txg)) != NULL)
+		vdev_dtl_sync(lvd, txg);
+
+	(void) txg_list_add(&spa->spa_vdev_txg_list, vd, TXG_CLEAN(txg));
+}
+
+uint64_t
+vdev_psize_to_asize(vdev_t *vd, uint64_t psize)
+{
+	return (vd->vdev_ops->vdev_op_asize(vd, psize));
+}
+
+/*
+ * Mark the given vdev faulted.  A faulted vdev behaves as if the device could
+ * not be opened, and no I/O is attempted.
+ */
+int
+vdev_fault(spa_t *spa, uint64_t guid, vdev_aux_t aux)
+{
+	vdev_t *vd, *tvd;
+
+	spa_vdev_state_enter(spa, SCL_NONE);
+
+	if ((vd = spa_lookup_by_guid(spa, guid, B_TRUE)) == NULL)
+		return (spa_vdev_state_exit(spa, NULL, ENODEV));
+
+	if (!vd->vdev_ops->vdev_op_leaf)
+		return (spa_vdev_state_exit(spa, NULL, ENOTSUP));
+
+	tvd = vd->vdev_top;
+
+	/*
+	 * We don't directly use the aux state here, but if we do a
+	 * vdev_reopen(), we need this value to be present to remember why we
+	 * were faulted.
+	 */
+	vd->vdev_label_aux = aux;
+
+	/*
+	 * Faulted state takes precedence over degraded.
+	 */
+	vd->vdev_delayed_close = B_FALSE;
+	vd->vdev_faulted = 1ULL;
+	vd->vdev_degraded = 0ULL;
+	vdev_set_state(vd, B_FALSE, VDEV_STATE_FAULTED, aux);
+
+	/*
+	 * If this device has the only valid copy of the data, then
+	 * back off and simply mark the vdev as degraded instead.
+	 */
+	if (!tvd->vdev_islog && vd->vdev_aux == NULL && vdev_dtl_required(vd)) {
+		vd->vdev_degraded = 1ULL;
+		vd->vdev_faulted = 0ULL;
+
+		/*
+		 * If we reopen the device and it's not dead, only then do we
+		 * mark it degraded.
+		 */
+		vdev_reopen(tvd);
+
+		if (vdev_readable(vd))
+			vdev_set_state(vd, B_FALSE, VDEV_STATE_DEGRADED, aux);
+	}
+
+	return (spa_vdev_state_exit(spa, vd, 0));
+}
+
+/*
+ * Mark the given vdev degraded.  A degraded vdev is purely an indication to the
+ * user that something is wrong.  The vdev continues to operate as normal as far
+ * as I/O is concerned.
+ */
+int
+vdev_degrade(spa_t *spa, uint64_t guid, vdev_aux_t aux)
+{
+	vdev_t *vd;
+
+	spa_vdev_state_enter(spa, SCL_NONE);
+
+	if ((vd = spa_lookup_by_guid(spa, guid, B_TRUE)) == NULL)
+		return (spa_vdev_state_exit(spa, NULL, ENODEV));
+
+	if (!vd->vdev_ops->vdev_op_leaf)
+		return (spa_vdev_state_exit(spa, NULL, ENOTSUP));
+
+	/*
+	 * If the vdev is already faulted, then don't do anything.
+	 */
+	if (vd->vdev_faulted || vd->vdev_degraded)
+		return (spa_vdev_state_exit(spa, NULL, 0));
+
+	vd->vdev_degraded = 1ULL;
+	if (!vdev_is_dead(vd))
+		vdev_set_state(vd, B_FALSE, VDEV_STATE_DEGRADED,
+		    aux);
+
+	return (spa_vdev_state_exit(spa, vd, 0));
+}
+
+/*
+ * Online the given vdev.
+ *
+ * If 'ZFS_ONLINE_UNSPARE' is set, it implies two things.  First, any attached
+ * spare device should be detached when the device finishes resilvering.
+ * Second, the online should be treated like a 'test' online case, so no FMA
+ * events are generated if the device fails to open.
+ */
+int
+vdev_online(spa_t *spa, uint64_t guid, uint64_t flags, vdev_state_t *newstate)
+{
+	vdev_t *vd, *tvd, *pvd, *rvd = spa->spa_root_vdev;
+
+	spa_vdev_state_enter(spa, SCL_NONE);
+
+	if ((vd = spa_lookup_by_guid(spa, guid, B_TRUE)) == NULL)
+		return (spa_vdev_state_exit(spa, NULL, ENODEV));
+
+	if (!vd->vdev_ops->vdev_op_leaf)
+		return (spa_vdev_state_exit(spa, NULL, ENOTSUP));
+
+	tvd = vd->vdev_top;
+	vd->vdev_offline = B_FALSE;
+	vd->vdev_tmpoffline = B_FALSE;
+	vd->vdev_checkremove = !!(flags & ZFS_ONLINE_CHECKREMOVE);
+	vd->vdev_forcefault = !!(flags & ZFS_ONLINE_FORCEFAULT);
+
+	/* XXX - L2ARC 1.0 does not support expansion */
+	if (!vd->vdev_aux) {
+		for (pvd = vd; pvd != rvd; pvd = pvd->vdev_parent)
+			pvd->vdev_expanding = !!(flags & ZFS_ONLINE_EXPAND);
+	}
+
+	vdev_reopen(tvd);
+	vd->vdev_checkremove = vd->vdev_forcefault = B_FALSE;
+
+	if (!vd->vdev_aux) {
+		for (pvd = vd; pvd != rvd; pvd = pvd->vdev_parent)
+			pvd->vdev_expanding = B_FALSE;
+	}
+
+	if (newstate)
+		*newstate = vd->vdev_state;
+	if ((flags & ZFS_ONLINE_UNSPARE) &&
+	    !vdev_is_dead(vd) && vd->vdev_parent &&
+	    vd->vdev_parent->vdev_ops == &vdev_spare_ops &&
+	    vd->vdev_parent->vdev_child[0] == vd)
+		vd->vdev_unspare = B_TRUE;
+
+	if ((flags & ZFS_ONLINE_EXPAND) || spa->spa_autoexpand) {
+
+		/* XXX - L2ARC 1.0 does not support expansion */
+		if (vd->vdev_aux)
+			return (spa_vdev_state_exit(spa, vd, ENOTSUP));
+		spa_async_request(spa, SPA_ASYNC_CONFIG_UPDATE);
+	}
+	return (spa_vdev_state_exit(spa, vd, 0));
+}
+
+static int
+vdev_offline_locked(spa_t *spa, uint64_t guid, uint64_t flags)
+{
+	vdev_t *vd, *tvd;
+	int error = 0;
+	uint64_t generation;
+	metaslab_group_t *mg;
+
+top:
+	spa_vdev_state_enter(spa, SCL_ALLOC);
+
+	if ((vd = spa_lookup_by_guid(spa, guid, B_TRUE)) == NULL)
+		return (spa_vdev_state_exit(spa, NULL, ENODEV));
+
+	if (!vd->vdev_ops->vdev_op_leaf)
+		return (spa_vdev_state_exit(spa, NULL, ENOTSUP));
+
+	tvd = vd->vdev_top;
+	mg = tvd->vdev_mg;
+	generation = spa->spa_config_generation + 1;
+
+	/*
+	 * If the device isn't already offline, try to offline it.
+	 */
+	if (!vd->vdev_offline) {
+		/*
+		 * If this device has the only valid copy of some data,
+		 * don't allow it to be offlined. Log devices are always
+		 * expendable.
+		 */
+		if (!tvd->vdev_islog && vd->vdev_aux == NULL &&
+		    vdev_dtl_required(vd))
+			return (spa_vdev_state_exit(spa, NULL, EBUSY));
+
+		/*
+		 * If the top-level is a slog and it has had allocations
+		 * then proceed.  We check that the vdev's metaslab group
+		 * is not NULL since it's possible that we may have just
+		 * added this vdev but not yet initialized its metaslabs.
+		 */
+		if (tvd->vdev_islog && mg != NULL) {
+			/*
+			 * Prevent any future allocations.
+			 */
+			metaslab_group_passivate(mg);
+			(void) spa_vdev_state_exit(spa, vd, 0);
+
+			error = spa_offline_log(spa);
+
+			spa_vdev_state_enter(spa, SCL_ALLOC);
+
+			/*
+			 * Check to see if the config has changed.
+			 */
+			if (error || generation != spa->spa_config_generation) {
+				metaslab_group_activate(mg);
+				if (error)
+					return (spa_vdev_state_exit(spa,
+					    vd, error));
+				(void) spa_vdev_state_exit(spa, vd, 0);
+				goto top;
+			}
+			ASSERT0(tvd->vdev_stat.vs_alloc);
+		}
+
+		/*
+		 * Offline this device and reopen its top-level vdev.
+		 * If the top-level vdev is a log device then just offline
+		 * it. Otherwise, if this action results in the top-level
+		 * vdev becoming unusable, undo it and fail the request.
+		 */
+		vd->vdev_offline = B_TRUE;
+		vdev_reopen(tvd);
+
+		if (!tvd->vdev_islog && vd->vdev_aux == NULL &&
+		    vdev_is_dead(tvd)) {
+			vd->vdev_offline = B_FALSE;
+			vdev_reopen(tvd);
+			return (spa_vdev_state_exit(spa, NULL, EBUSY));
+		}
+
+		/*
+		 * Add the device back into the metaslab rotor so that
+		 * once we online the device it's open for business.
+		 */
+		if (tvd->vdev_islog && mg != NULL)
+			metaslab_group_activate(mg);
+	}
+
+	vd->vdev_tmpoffline = !!(flags & ZFS_OFFLINE_TEMPORARY);
+
+	return (spa_vdev_state_exit(spa, vd, 0));
+}
+
+int
+vdev_offline(spa_t *spa, uint64_t guid, uint64_t flags)
+{
+	int error;
+
+	mutex_enter(&spa->spa_vdev_top_lock);
+	error = vdev_offline_locked(spa, guid, flags);
+	mutex_exit(&spa->spa_vdev_top_lock);
+
+	return (error);
+}
+
+/*
+ * Clear the error counts associated with this vdev.  Unlike vdev_online() and
+ * vdev_offline(), we assume the spa config is locked.  We also clear all
+ * children.  If 'vd' is NULL, then the user wants to clear all vdevs.
+ */
+void
+vdev_clear(spa_t *spa, vdev_t *vd)
+{
+	vdev_t *rvd = spa->spa_root_vdev;
+	int c;
+
+	ASSERT(spa_config_held(spa, SCL_STATE_ALL, RW_WRITER) == SCL_STATE_ALL);
+
+	if (vd == NULL)
+		vd = rvd;
+
+	vd->vdev_stat.vs_read_errors = 0;
+	vd->vdev_stat.vs_write_errors = 0;
+	vd->vdev_stat.vs_checksum_errors = 0;
+
+	for (c = 0; c < vd->vdev_children; c++)
+		vdev_clear(spa, vd->vdev_child[c]);
+
+	/*
+	 * If we're in the FAULTED state or have experienced failed I/O, then
+	 * clear the persistent state and attempt to reopen the device.  We
+	 * also mark the vdev config dirty, so that the new faulted state is
+	 * written out to disk.
+	 */
+	if (vd->vdev_faulted || vd->vdev_degraded ||
+	    !vdev_readable(vd) || !vdev_writeable(vd)) {
+
+		/*
+		 * When reopening in reponse to a clear event, it may be due to
+		 * a fmadm repair request.  In this case, if the device is
+		 * still broken, we want to still post the ereport again.
+		 */
+		vd->vdev_forcefault = B_TRUE;
+
+		vd->vdev_faulted = vd->vdev_degraded = 0ULL;
+		vd->vdev_cant_read = B_FALSE;
+		vd->vdev_cant_write = B_FALSE;
+
+		vdev_reopen(vd == rvd ? rvd : vd->vdev_top);
+
+		vd->vdev_forcefault = B_FALSE;
+
+		if (vd != rvd && vdev_writeable(vd->vdev_top))
+			vdev_state_dirty(vd->vdev_top);
+
+		if (vd->vdev_aux == NULL && !vdev_is_dead(vd))
+			spa_async_request(spa, SPA_ASYNC_RESILVER);
+
+		spa_event_notify(spa, vd, FM_EREPORT_ZFS_DEVICE_CLEAR);
+	}
+
+	/*
+	 * When clearing a FMA-diagnosed fault, we always want to
+	 * unspare the device, as we assume that the original spare was
+	 * done in response to the FMA fault.
+	 */
+	if (!vdev_is_dead(vd) && vd->vdev_parent != NULL &&
+	    vd->vdev_parent->vdev_ops == &vdev_spare_ops &&
+	    vd->vdev_parent->vdev_child[0] == vd)
+		vd->vdev_unspare = B_TRUE;
+}
+
+boolean_t
+vdev_is_dead(vdev_t *vd)
+{
+	/*
+	 * Holes and missing devices are always considered "dead".
+	 * This simplifies the code since we don't have to check for
+	 * these types of devices in the various code paths.
+	 * Instead we rely on the fact that we skip over dead devices
+	 * before issuing I/O to them.
+	 */
+	return (vd->vdev_state < VDEV_STATE_DEGRADED || vd->vdev_ishole ||
+	    vd->vdev_ops == &vdev_missing_ops);
+}
+
+boolean_t
+vdev_readable(vdev_t *vd)
+{
+	return (!vdev_is_dead(vd) && !vd->vdev_cant_read);
+}
+
+boolean_t
+vdev_writeable(vdev_t *vd)
+{
+	return (!vdev_is_dead(vd) && !vd->vdev_cant_write);
+}
+
+boolean_t
+vdev_allocatable(vdev_t *vd)
+{
+	uint64_t state = vd->vdev_state;
+
+	/*
+	 * We currently allow allocations from vdevs which may be in the
+	 * process of reopening (i.e. VDEV_STATE_CLOSED). If the device
+	 * fails to reopen then we'll catch it later when we're holding
+	 * the proper locks.  Note that we have to get the vdev state
+	 * in a local variable because although it changes atomically,
+	 * we're asking two separate questions about it.
+	 */
+	return (!(state < VDEV_STATE_DEGRADED && state != VDEV_STATE_CLOSED) &&
+	    !vd->vdev_cant_write && !vd->vdev_ishole);
+}
+
+boolean_t
+vdev_accessible(vdev_t *vd, zio_t *zio)
+{
+	ASSERT(zio->io_vd == vd);
+
+	if (vdev_is_dead(vd) || vd->vdev_remove_wanted)
+		return (B_FALSE);
+
+	if (zio->io_type == ZIO_TYPE_READ)
+		return (!vd->vdev_cant_read);
+
+	if (zio->io_type == ZIO_TYPE_WRITE)
+		return (!vd->vdev_cant_write);
+
+	return (B_TRUE);
+}
+
+/*
+ * Get statistics for the given vdev.
+ */
+void
+vdev_get_stats(vdev_t *vd, vdev_stat_t *vs)
+{
+	spa_t *spa = vd->vdev_spa;
+	vdev_t *rvd = spa->spa_root_vdev;
+	int c, t;
+
+	ASSERT(spa_config_held(spa, SCL_ALL, RW_READER) != 0);
+
+	mutex_enter(&vd->vdev_stat_lock);
+	bcopy(&vd->vdev_stat, vs, sizeof (*vs));
+	vs->vs_timestamp = gethrtime() - vs->vs_timestamp;
+	vs->vs_state = vd->vdev_state;
+	vs->vs_rsize = vdev_get_min_asize(vd);
+	if (vd->vdev_ops->vdev_op_leaf)
+		vs->vs_rsize += VDEV_LABEL_START_SIZE + VDEV_LABEL_END_SIZE;
+	vs->vs_esize = vd->vdev_max_asize - vd->vdev_asize;
+	if (vd->vdev_aux == NULL && vd == vd->vdev_top && !vd->vdev_ishole) {
+		vs->vs_fragmentation = vd->vdev_mg->mg_fragmentation;
+	}
+
+	/*
+	 * If we're getting stats on the root vdev, aggregate the I/O counts
+	 * over all top-level vdevs (i.e. the direct children of the root).
+	 */
+	if (vd == rvd) {
+		for (c = 0; c < rvd->vdev_children; c++) {
+			vdev_t *cvd = rvd->vdev_child[c];
+			vdev_stat_t *cvs = &cvd->vdev_stat;
+
+			for (t = 0; t < ZIO_TYPES; t++) {
+				vs->vs_ops[t] += cvs->vs_ops[t];
+				vs->vs_bytes[t] += cvs->vs_bytes[t];
+			}
+			cvs->vs_scan_removing = cvd->vdev_removing;
+		}
+	}
+	mutex_exit(&vd->vdev_stat_lock);
+}
+
+void
+vdev_clear_stats(vdev_t *vd)
+{
+	mutex_enter(&vd->vdev_stat_lock);
+	vd->vdev_stat.vs_space = 0;
+	vd->vdev_stat.vs_dspace = 0;
+	vd->vdev_stat.vs_alloc = 0;
+	mutex_exit(&vd->vdev_stat_lock);
+}
+
+void
+vdev_scan_stat_init(vdev_t *vd)
+{
+	vdev_stat_t *vs = &vd->vdev_stat;
+	int c;
+
+	for (c = 0; c < vd->vdev_children; c++)
+		vdev_scan_stat_init(vd->vdev_child[c]);
+
+	mutex_enter(&vd->vdev_stat_lock);
+	vs->vs_scan_processed = 0;
+	mutex_exit(&vd->vdev_stat_lock);
+}
+
+void
+vdev_stat_update(zio_t *zio, uint64_t psize)
+{
+	spa_t *spa = zio->io_spa;
+	vdev_t *rvd = spa->spa_root_vdev;
+	vdev_t *vd = zio->io_vd ? zio->io_vd : rvd;
+	vdev_t *pvd;
+	uint64_t txg = zio->io_txg;
+	vdev_stat_t *vs = &vd->vdev_stat;
+	zio_type_t type = zio->io_type;
+	int flags = zio->io_flags;
+
+	/*
+	 * If this i/o is a gang leader, it didn't do any actual work.
+	 */
+	if (zio->io_gang_tree)
+		return;
+
+	if (zio->io_error == 0) {
+		/*
+		 * If this is a root i/o, don't count it -- we've already
+		 * counted the top-level vdevs, and vdev_get_stats() will
+		 * aggregate them when asked.  This reduces contention on
+		 * the root vdev_stat_lock and implicitly handles blocks
+		 * that compress away to holes, for which there is no i/o.
+		 * (Holes never create vdev children, so all the counters
+		 * remain zero, which is what we want.)
+		 *
+		 * Note: this only applies to successful i/o (io_error == 0)
+		 * because unlike i/o counts, errors are not additive.
+		 * When reading a ditto block, for example, failure of
+		 * one top-level vdev does not imply a root-level error.
+		 */
+		if (vd == rvd)
+			return;
+
+		ASSERT(vd == zio->io_vd);
+
+		if (flags & ZIO_FLAG_IO_BYPASS)
+			return;
+
+		mutex_enter(&vd->vdev_stat_lock);
+
+		if (flags & ZIO_FLAG_IO_REPAIR) {
+			if (flags & ZIO_FLAG_SCAN_THREAD) {
+				dsl_scan_phys_t *scn_phys =
+				    &spa->spa_dsl_pool->dp_scan->scn_phys;
+				uint64_t *processed = &scn_phys->scn_processed;
+
+				/* XXX cleanup? */
+				if (vd->vdev_ops->vdev_op_leaf)
+					atomic_add_64(processed, psize);
+				vs->vs_scan_processed += psize;
+			}
+
+			if (flags & ZIO_FLAG_SELF_HEAL)
+				vs->vs_self_healed += psize;
+		}
+
+		vs->vs_ops[type]++;
+		vs->vs_bytes[type] += psize;
+
+		mutex_exit(&vd->vdev_stat_lock);
+		return;
+	}
+
+	if (flags & ZIO_FLAG_SPECULATIVE)
+		return;
+
+	/*
+	 * If this is an I/O error that is going to be retried, then ignore the
+	 * error.  Otherwise, the user may interpret B_FAILFAST I/O errors as
+	 * hard errors, when in reality they can happen for any number of
+	 * innocuous reasons (bus resets, MPxIO link failure, etc).
+	 */
+	if (zio->io_error == EIO &&
+	    !(zio->io_flags & ZIO_FLAG_IO_RETRY))
+		return;
+
+	/*
+	 * Intent logs writes won't propagate their error to the root
+	 * I/O so don't mark these types of failures as pool-level
+	 * errors.
+	 */
+	if (zio->io_vd == NULL && (zio->io_flags & ZIO_FLAG_DONT_PROPAGATE))
+		return;
+
+	mutex_enter(&vd->vdev_stat_lock);
+	if (type == ZIO_TYPE_READ && !vdev_is_dead(vd)) {
+		if (zio->io_error == ECKSUM)
+			vs->vs_checksum_errors++;
+		else
+			vs->vs_read_errors++;
+	}
+	if (type == ZIO_TYPE_WRITE && !vdev_is_dead(vd))
+		vs->vs_write_errors++;
+	mutex_exit(&vd->vdev_stat_lock);
+
+	if (type == ZIO_TYPE_WRITE && txg != 0 &&
+	    (!(flags & ZIO_FLAG_IO_REPAIR) ||
+	    (flags & ZIO_FLAG_SCAN_THREAD) ||
+	    spa->spa_claiming)) {
+		/*
+		 * This is either a normal write (not a repair), or it's
+		 * a repair induced by the scrub thread, or it's a repair
+		 * made by zil_claim() during spa_load() in the first txg.
+		 * In the normal case, we commit the DTL change in the same
+		 * txg as the block was born.  In the scrub-induced repair
+		 * case, we know that scrubs run in first-pass syncing context,
+		 * so we commit the DTL change in spa_syncing_txg(spa).
+		 * In the zil_claim() case, we commit in spa_first_txg(spa).
+		 *
+		 * We currently do not make DTL entries for failed spontaneous
+		 * self-healing writes triggered by normal (non-scrubbing)
+		 * reads, because we have no transactional context in which to
+		 * do so -- and it's not clear that it'd be desirable anyway.
+		 */
+		if (vd->vdev_ops->vdev_op_leaf) {
+			uint64_t commit_txg = txg;
+			if (flags & ZIO_FLAG_SCAN_THREAD) {
+				ASSERT(flags & ZIO_FLAG_IO_REPAIR);
+				ASSERT(spa_sync_pass(spa) == 1);
+				vdev_dtl_dirty(vd, DTL_SCRUB, txg, 1);
+				commit_txg = spa_syncing_txg(spa);
+			} else if (spa->spa_claiming) {
+				ASSERT(flags & ZIO_FLAG_IO_REPAIR);
+				commit_txg = spa_first_txg(spa);
+			}
+			ASSERT(commit_txg >= spa_syncing_txg(spa));
+			if (vdev_dtl_contains(vd, DTL_MISSING, txg, 1))
+				return;
+			for (pvd = vd; pvd != rvd; pvd = pvd->vdev_parent)
+				vdev_dtl_dirty(pvd, DTL_PARTIAL, txg, 1);
+			vdev_dirty(vd->vdev_top, VDD_DTL, vd, commit_txg);
+		}
+		if (vd != rvd)
+			vdev_dtl_dirty(vd, DTL_MISSING, txg, 1);
+	}
+}
+
+/*
+ * Update the in-core space usage stats for this vdev, its metaslab class,
+ * and the root vdev.
+ */
+void
+vdev_space_update(vdev_t *vd, int64_t alloc_delta, int64_t defer_delta,
+    int64_t space_delta)
+{
+	int64_t dspace_delta = space_delta;
+	spa_t *spa = vd->vdev_spa;
+	vdev_t *rvd = spa->spa_root_vdev;
+	metaslab_group_t *mg = vd->vdev_mg;
+	metaslab_class_t *mc = mg ? mg->mg_class : NULL;
+
+	ASSERT(vd == vd->vdev_top);
+
+	/*
+	 * Apply the inverse of the psize-to-asize (ie. RAID-Z) space-expansion
+	 * factor.  We must calculate this here and not at the root vdev
+	 * because the root vdev's psize-to-asize is simply the max of its
+	 * childrens', thus not accurate enough for us.
+	 */
+	ASSERT((dspace_delta & (SPA_MINBLOCKSIZE-1)) == 0);
+	ASSERT(vd->vdev_deflate_ratio != 0 || vd->vdev_isl2cache);
+	dspace_delta = (dspace_delta >> SPA_MINBLOCKSHIFT) *
+	    vd->vdev_deflate_ratio;
+
+	mutex_enter(&vd->vdev_stat_lock);
+	vd->vdev_stat.vs_alloc += alloc_delta;
+	vd->vdev_stat.vs_space += space_delta;
+	vd->vdev_stat.vs_dspace += dspace_delta;
+	mutex_exit(&vd->vdev_stat_lock);
+
+	if (mc == spa_normal_class(spa)) {
+		mutex_enter(&rvd->vdev_stat_lock);
+		rvd->vdev_stat.vs_alloc += alloc_delta;
+		rvd->vdev_stat.vs_space += space_delta;
+		rvd->vdev_stat.vs_dspace += dspace_delta;
+		mutex_exit(&rvd->vdev_stat_lock);
+	}
+
+	if (mc != NULL) {
+		ASSERT(rvd == vd->vdev_parent);
+		ASSERT(vd->vdev_ms_count != 0);
+
+		metaslab_class_space_update(mc,
+		    alloc_delta, defer_delta, space_delta, dspace_delta);
+	}
+}
+
+/*
+ * Mark a top-level vdev's config as dirty, placing it on the dirty list
+ * so that it will be written out next time the vdev configuration is synced.
+ * If the root vdev is specified (vdev_top == NULL), dirty all top-level vdevs.
+ */
+void
+vdev_config_dirty(vdev_t *vd)
+{
+	spa_t *spa = vd->vdev_spa;
+	vdev_t *rvd = spa->spa_root_vdev;
+	int c;
+
+	ASSERT(spa_writeable(spa));
+
+	/*
+	 * If this is an aux vdev (as with l2cache and spare devices), then we
+	 * update the vdev config manually and set the sync flag.
+	 */
+	if (vd->vdev_aux != NULL) {
+		spa_aux_vdev_t *sav = vd->vdev_aux;
+		nvlist_t **aux;
+		uint_t naux;
+
+		for (c = 0; c < sav->sav_count; c++) {
+			if (sav->sav_vdevs[c] == vd)
+				break;
+		}
+
+		if (c == sav->sav_count) {
+			/*
+			 * We're being removed.  There's nothing more to do.
+			 */
+			ASSERT(sav->sav_sync == B_TRUE);
+			return;
+		}
+
+		sav->sav_sync = B_TRUE;
+
+		if (nvlist_lookup_nvlist_array(sav->sav_config,
+		    ZPOOL_CONFIG_L2CACHE, &aux, &naux) != 0) {
+			VERIFY(nvlist_lookup_nvlist_array(sav->sav_config,
+			    ZPOOL_CONFIG_SPARES, &aux, &naux) == 0);
+		}
+
+		ASSERT(c < naux);
+
+		/*
+		 * Setting the nvlist in the middle if the array is a little
+		 * sketchy, but it will work.
+		 */
+		nvlist_free(aux[c]);
+		aux[c] = vdev_config_generate(spa, vd, B_TRUE, 0);
+
+		return;
+	}
+
+	/*
+	 * The dirty list is protected by the SCL_CONFIG lock.  The caller
+	 * must either hold SCL_CONFIG as writer, or must be the sync thread
+	 * (which holds SCL_CONFIG as reader).  There's only one sync thread,
+	 * so this is sufficient to ensure mutual exclusion.
+	 */
+	ASSERT(spa_config_held(spa, SCL_CONFIG, RW_WRITER) ||
+	    (dsl_pool_sync_context(spa_get_dsl(spa)) &&
+	    spa_config_held(spa, SCL_CONFIG, RW_READER)));
+
+	if (vd == rvd) {
+		for (c = 0; c < rvd->vdev_children; c++)
+			vdev_config_dirty(rvd->vdev_child[c]);
+	} else {
+		ASSERT(vd == vd->vdev_top);
+
+		if (!list_link_active(&vd->vdev_config_dirty_node) &&
+		    !vd->vdev_ishole)
+			list_insert_head(&spa->spa_config_dirty_list, vd);
+	}
+}
+
+void
+vdev_config_clean(vdev_t *vd)
+{
+	spa_t *spa = vd->vdev_spa;
+
+	ASSERT(spa_config_held(spa, SCL_CONFIG, RW_WRITER) ||
+	    (dsl_pool_sync_context(spa_get_dsl(spa)) &&
+	    spa_config_held(spa, SCL_CONFIG, RW_READER)));
+
+	ASSERT(list_link_active(&vd->vdev_config_dirty_node));
+	list_remove(&spa->spa_config_dirty_list, vd);
+}
+
+/*
+ * Mark a top-level vdev's state as dirty, so that the next pass of
+ * spa_sync() can convert this into vdev_config_dirty().  We distinguish
+ * the state changes from larger config changes because they require
+ * much less locking, and are often needed for administrative actions.
+ */
+void
+vdev_state_dirty(vdev_t *vd)
+{
+	spa_t *spa = vd->vdev_spa;
+
+	ASSERT(spa_writeable(spa));
+	ASSERT(vd == vd->vdev_top);
+
+	/*
+	 * The state list is protected by the SCL_STATE lock.  The caller
+	 * must either hold SCL_STATE as writer, or must be the sync thread
+	 * (which holds SCL_STATE as reader).  There's only one sync thread,
+	 * so this is sufficient to ensure mutual exclusion.
+	 */
+	ASSERT(spa_config_held(spa, SCL_STATE, RW_WRITER) ||
+	    (dsl_pool_sync_context(spa_get_dsl(spa)) &&
+	    spa_config_held(spa, SCL_STATE, RW_READER)));
+
+	if (!list_link_active(&vd->vdev_state_dirty_node) && !vd->vdev_ishole)
+		list_insert_head(&spa->spa_state_dirty_list, vd);
+}
+
+void
+vdev_state_clean(vdev_t *vd)
+{
+	spa_t *spa = vd->vdev_spa;
+
+	ASSERT(spa_config_held(spa, SCL_STATE, RW_WRITER) ||
+	    (dsl_pool_sync_context(spa_get_dsl(spa)) &&
+	    spa_config_held(spa, SCL_STATE, RW_READER)));
+
+	ASSERT(list_link_active(&vd->vdev_state_dirty_node));
+	list_remove(&spa->spa_state_dirty_list, vd);
+}
+
+/*
+ * Propagate vdev state up from children to parent.
+ */
+void
+vdev_propagate_state(vdev_t *vd)
+{
+	spa_t *spa = vd->vdev_spa;
+	vdev_t *rvd = spa->spa_root_vdev;
+	int degraded = 0, faulted = 0;
+	int corrupted = 0;
+	vdev_t *child;
+	int c;
+
+	if (vd->vdev_children > 0) {
+		for (c = 0; c < vd->vdev_children; c++) {
+			child = vd->vdev_child[c];
+
+			/*
+			 * Don't factor holes into the decision.
+			 */
+			if (child->vdev_ishole)
+				continue;
+
+			if (!vdev_readable(child) ||
+			    (!vdev_writeable(child) && spa_writeable(spa))) {
+				/*
+				 * Root special: if there is a top-level log
+				 * device, treat the root vdev as if it were
+				 * degraded.
+				 */
+				if (child->vdev_islog && vd == rvd)
+					degraded++;
+				else
+					faulted++;
+			} else if (child->vdev_state <= VDEV_STATE_DEGRADED) {
+				degraded++;
+			}
+
+			if (child->vdev_stat.vs_aux == VDEV_AUX_CORRUPT_DATA)
+				corrupted++;
+		}
+
+		vd->vdev_ops->vdev_op_state_change(vd, faulted, degraded);
+
+		/*
+		 * Root special: if there is a top-level vdev that cannot be
+		 * opened due to corrupted metadata, then propagate the root
+		 * vdev's aux state as 'corrupt' rather than 'insufficient
+		 * replicas'.
+		 */
+		if (corrupted && vd == rvd &&
+		    rvd->vdev_state == VDEV_STATE_CANT_OPEN)
+			vdev_set_state(rvd, B_FALSE, VDEV_STATE_CANT_OPEN,
+			    VDEV_AUX_CORRUPT_DATA);
+	}
+
+	if (vd->vdev_parent)
+		vdev_propagate_state(vd->vdev_parent);
+}
+
+/*
+ * Set a vdev's state.  If this is during an open, we don't update the parent
+ * state, because we're in the process of opening children depth-first.
+ * Otherwise, we propagate the change to the parent.
+ *
+ * If this routine places a device in a faulted state, an appropriate ereport is
+ * generated.
+ */
+void
+vdev_set_state(vdev_t *vd, boolean_t isopen, vdev_state_t state, vdev_aux_t aux)
+{
+	uint64_t save_state;
+	spa_t *spa = vd->vdev_spa;
+
+	if (state == vd->vdev_state) {
+		vd->vdev_stat.vs_aux = aux;
+		return;
+	}
+
+	save_state = vd->vdev_state;
+
+	vd->vdev_state = state;
+	vd->vdev_stat.vs_aux = aux;
+
+	/*
+	 * If we are setting the vdev state to anything but an open state, then
+	 * always close the underlying device unless the device has requested
+	 * a delayed close (i.e. we're about to remove or fault the device).
+	 * Otherwise, we keep accessible but invalid devices open forever.
+	 * We don't call vdev_close() itself, because that implies some extra
+	 * checks (offline, etc) that we don't want here.  This is limited to
+	 * leaf devices, because otherwise closing the device will affect other
+	 * children.
+	 */
+	if (!vd->vdev_delayed_close && vdev_is_dead(vd) &&
+	    vd->vdev_ops->vdev_op_leaf)
+		vd->vdev_ops->vdev_op_close(vd);
+
+	/*
+	 * If we have brought this vdev back into service, we need
+	 * to notify fmd so that it can gracefully repair any outstanding
+	 * cases due to a missing device.  We do this in all cases, even those
+	 * that probably don't correlate to a repaired fault.  This is sure to
+	 * catch all cases, and we let the zfs-retire agent sort it out.  If
+	 * this is a transient state it's OK, as the retire agent will
+	 * double-check the state of the vdev before repairing it.
+	 */
+	if (state == VDEV_STATE_HEALTHY && vd->vdev_ops->vdev_op_leaf &&
+	    vd->vdev_prevstate != state)
+		zfs_post_state_change(spa, vd);
+
+	if (vd->vdev_removed &&
+	    state == VDEV_STATE_CANT_OPEN &&
+	    (aux == VDEV_AUX_OPEN_FAILED || vd->vdev_checkremove)) {
+		/*
+		 * If the previous state is set to VDEV_STATE_REMOVED, then this
+		 * device was previously marked removed and someone attempted to
+		 * reopen it.  If this failed due to a nonexistent device, then
+		 * keep the device in the REMOVED state.  We also let this be if
+		 * it is one of our special test online cases, which is only
+		 * attempting to online the device and shouldn't generate an FMA
+		 * fault.
+		 */
+		vd->vdev_state = VDEV_STATE_REMOVED;
+		vd->vdev_stat.vs_aux = VDEV_AUX_NONE;
+	} else if (state == VDEV_STATE_REMOVED) {
+		vd->vdev_removed = B_TRUE;
+	} else if (state == VDEV_STATE_CANT_OPEN) {
+		/*
+		 * If we fail to open a vdev during an import or recovery, we
+		 * mark it as "not available", which signifies that it was
+		 * never there to begin with.  Failure to open such a device
+		 * is not considered an error.
+		 */
+		if ((spa_load_state(spa) == SPA_LOAD_IMPORT ||
+		    spa_load_state(spa) == SPA_LOAD_RECOVER) &&
+		    vd->vdev_ops->vdev_op_leaf)
+			vd->vdev_not_present = 1;
+
+		/*
+		 * Post the appropriate ereport.  If the 'prevstate' field is
+		 * set to something other than VDEV_STATE_UNKNOWN, it indicates
+		 * that this is part of a vdev_reopen().  In this case, we don't
+		 * want to post the ereport if the device was already in the
+		 * CANT_OPEN state beforehand.
+		 *
+		 * If the 'checkremove' flag is set, then this is an attempt to
+		 * online the device in response to an insertion event.  If we
+		 * hit this case, then we have detected an insertion event for a
+		 * faulted or offline device that wasn't in the removed state.
+		 * In this scenario, we don't post an ereport because we are
+		 * about to replace the device, or attempt an online with
+		 * vdev_forcefault, which will generate the fault for us.
+		 */
+		if ((vd->vdev_prevstate != state || vd->vdev_forcefault) &&
+		    !vd->vdev_not_present && !vd->vdev_checkremove &&
+		    vd != spa->spa_root_vdev) {
+			const char *class;
+
+			switch (aux) {
+			case VDEV_AUX_OPEN_FAILED:
+				class = FM_EREPORT_ZFS_DEVICE_OPEN_FAILED;
+				break;
+			case VDEV_AUX_CORRUPT_DATA:
+				class = FM_EREPORT_ZFS_DEVICE_CORRUPT_DATA;
+				break;
+			case VDEV_AUX_NO_REPLICAS:
+				class = FM_EREPORT_ZFS_DEVICE_NO_REPLICAS;
+				break;
+			case VDEV_AUX_BAD_GUID_SUM:
+				class = FM_EREPORT_ZFS_DEVICE_BAD_GUID_SUM;
+				break;
+			case VDEV_AUX_TOO_SMALL:
+				class = FM_EREPORT_ZFS_DEVICE_TOO_SMALL;
+				break;
+			case VDEV_AUX_BAD_LABEL:
+				class = FM_EREPORT_ZFS_DEVICE_BAD_LABEL;
+				break;
+			default:
+				class = FM_EREPORT_ZFS_DEVICE_UNKNOWN;
+			}
+
+			zfs_ereport_post(class, spa, vd, NULL, save_state, 0);
+		}
+
+		/* Erase any notion of persistent removed state */
+		vd->vdev_removed = B_FALSE;
+	} else {
+		vd->vdev_removed = B_FALSE;
+	}
+
+	if (!isopen && vd->vdev_parent)
+		vdev_propagate_state(vd->vdev_parent);
+}
+
+/*
+ * Check the vdev configuration to ensure that it's capable of supporting
+ * a root pool.
+ */
+boolean_t
+vdev_is_bootable(vdev_t *vd)
+{
+#if defined(__sun__) || defined(__sun)
+	/*
+	 * Currently, we do not support RAID-Z or partial configuration.
+	 * In addition, only a single top-level vdev is allowed and none of the
+	 * leaves can be wholedisks.
+	 */
+	int c;
+
+	if (!vd->vdev_ops->vdev_op_leaf) {
+		char *vdev_type = vd->vdev_ops->vdev_op_type;
+
+		if (strcmp(vdev_type, VDEV_TYPE_ROOT) == 0 &&
+		    vd->vdev_children > 1) {
+			return (B_FALSE);
+		} else if (strcmp(vdev_type, VDEV_TYPE_RAIDZ) == 0 ||
+		    strcmp(vdev_type, VDEV_TYPE_MISSING) == 0) {
+			return (B_FALSE);
+		}
+	} else if (vd->vdev_wholedisk == 1) {
+		return (B_FALSE);
+	}
+
+	for (c = 0; c < vd->vdev_children; c++) {
+		if (!vdev_is_bootable(vd->vdev_child[c]))
+			return (B_FALSE);
+	}
+#endif /* __sun__ || __sun */
+	return (B_TRUE);
+}
+
+/*
+ * Load the state from the original vdev tree (ovd) which
+ * we've retrieved from the MOS config object. If the original
+ * vdev was offline or faulted then we transfer that state to the
+ * device in the current vdev tree (nvd).
+ */
+void
+vdev_load_log_state(vdev_t *nvd, vdev_t *ovd)
+{
+	int c;
+
+	ASSERT(nvd->vdev_top->vdev_islog);
+	ASSERT(spa_config_held(nvd->vdev_spa,
+	    SCL_STATE_ALL, RW_WRITER) == SCL_STATE_ALL);
+	ASSERT3U(nvd->vdev_guid, ==, ovd->vdev_guid);
+
+	for (c = 0; c < nvd->vdev_children; c++)
+		vdev_load_log_state(nvd->vdev_child[c], ovd->vdev_child[c]);
+
+	if (nvd->vdev_ops->vdev_op_leaf) {
+		/*
+		 * Restore the persistent vdev state
+		 */
+		nvd->vdev_offline = ovd->vdev_offline;
+		nvd->vdev_faulted = ovd->vdev_faulted;
+		nvd->vdev_degraded = ovd->vdev_degraded;
+		nvd->vdev_removed = ovd->vdev_removed;
+	}
+}
+
+/*
+ * Determine if a log device has valid content.  If the vdev was
+ * removed or faulted in the MOS config then we know that
+ * the content on the log device has already been written to the pool.
+ */
+boolean_t
+vdev_log_state_valid(vdev_t *vd)
+{
+	int c;
+
+	if (vd->vdev_ops->vdev_op_leaf && !vd->vdev_faulted &&
+	    !vd->vdev_removed)
+		return (B_TRUE);
+
+	for (c = 0; c < vd->vdev_children; c++)
+		if (vdev_log_state_valid(vd->vdev_child[c]))
+			return (B_TRUE);
+
+	return (B_FALSE);
+}
+
+/*
+ * Expand a vdev if possible.
+ */
+void
+vdev_expand(vdev_t *vd, uint64_t txg)
+{
+	ASSERT(vd->vdev_top == vd);
+	ASSERT(spa_config_held(vd->vdev_spa, SCL_ALL, RW_WRITER) == SCL_ALL);
+
+	if ((vd->vdev_asize >> vd->vdev_ms_shift) > vd->vdev_ms_count) {
+		VERIFY(vdev_metaslab_init(vd, txg) == 0);
+		vdev_config_dirty(vd);
+	}
+}
+
+/*
+ * Split a vdev.
+ */
+void
+vdev_split(vdev_t *vd)
+{
+	vdev_t *cvd, *pvd = vd->vdev_parent;
+
+	vdev_remove_child(pvd, vd);
+	vdev_compact_children(pvd);
+
+	cvd = pvd->vdev_child[0];
+	if (pvd->vdev_children == 1) {
+		vdev_remove_parent(cvd);
+		cvd->vdev_splitting = B_TRUE;
+	}
+	vdev_propagate_state(cvd);
+}
+
+void
+vdev_deadman(vdev_t *vd)
+{
+	int c;
+
+	for (c = 0; c < vd->vdev_children; c++) {
+		vdev_t *cvd = vd->vdev_child[c];
+
+		vdev_deadman(cvd);
+	}
+
+	if (vd->vdev_ops->vdev_op_leaf) {
+		vdev_queue_t *vq = &vd->vdev_queue;
+
+		mutex_enter(&vq->vq_lock);
+		if (avl_numnodes(&vq->vq_active_tree) > 0) {
+			spa_t *spa = vd->vdev_spa;
+			zio_t *fio;
+			uint64_t delta;
+
+			/*
+			 * Look at the head of all the pending queues,
+			 * if any I/O has been outstanding for longer than
+			 * the spa_deadman_synctime we log a zevent.
+			 */
+			fio = avl_first(&vq->vq_active_tree);
+			delta = gethrtime() - fio->io_timestamp;
+			if (delta > spa_deadman_synctime(spa)) {
+				zfs_dbgmsg("SLOW IO: zio timestamp %lluns, "
+				    "delta %lluns, last io %lluns",
+				    fio->io_timestamp, delta,
+				    vq->vq_io_complete_ts);
+				zfs_ereport_post(FM_EREPORT_ZFS_DELAY,
+				    spa, vd, fio, 0, 0);
+			}
+		}
+		mutex_exit(&vq->vq_lock);
+	}
+}
+
+#if defined(_KERNEL) && defined(HAVE_SPL)
+EXPORT_SYMBOL(vdev_fault);
+EXPORT_SYMBOL(vdev_degrade);
+EXPORT_SYMBOL(vdev_online);
+EXPORT_SYMBOL(vdev_offline);
+EXPORT_SYMBOL(vdev_clear);
+
+module_param(metaslabs_per_vdev, int, 0644);
+MODULE_PARM_DESC(metaslabs_per_vdev,
+	"Divide added vdev into approximately (but no more than) this number "
+	"of metaslabs");
+#endif
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/module/zfs/vdev_cache.c
@@ -0,0 +1,439 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * Copyright (c) 2013 by Delphix. All rights reserved.
+ */
+
+#include <sys/zfs_context.h>
+#include <sys/spa.h>
+#include <sys/vdev_impl.h>
+#include <sys/zio.h>
+#include <sys/kstat.h>
+
+/*
+ * Virtual device read-ahead caching.
+ *
+ * This file implements a simple LRU read-ahead cache.  When the DMU reads
+ * a given block, it will often want other, nearby blocks soon thereafter.
+ * We take advantage of this by reading a larger disk region and caching
+ * the result.  In the best case, this can turn 128 back-to-back 512-byte
+ * reads into a single 64k read followed by 127 cache hits; this reduces
+ * latency dramatically.  In the worst case, it can turn an isolated 512-byte
+ * read into a 64k read, which doesn't affect latency all that much but is
+ * terribly wasteful of bandwidth.  A more intelligent version of the cache
+ * could keep track of access patterns and not do read-ahead unless it sees
+ * at least two temporally close I/Os to the same region.  Currently, only
+ * metadata I/O is inflated.  A futher enhancement could take advantage of
+ * more semantic information about the I/O.  And it could use something
+ * faster than an AVL tree; that was chosen solely for convenience.
+ *
+ * There are five cache operations: allocate, fill, read, write, evict.
+ *
+ * (1) Allocate.  This reserves a cache entry for the specified region.
+ *     We separate the allocate and fill operations so that multiple threads
+ *     don't generate I/O for the same cache miss.
+ *
+ * (2) Fill.  When the I/O for a cache miss completes, the fill routine
+ *     places the data in the previously allocated cache entry.
+ *
+ * (3) Read.  Read data from the cache.
+ *
+ * (4) Write.  Update cache contents after write completion.
+ *
+ * (5) Evict.  When allocating a new entry, we evict the oldest (LRU) entry
+ *     if the total cache size exceeds zfs_vdev_cache_size.
+ */
+
+/*
+ * These tunables are for performance analysis.
+ */
+/*
+ * All i/os smaller than zfs_vdev_cache_max will be turned into
+ * 1<<zfs_vdev_cache_bshift byte reads by the vdev_cache (aka software
+ * track buffer).  At most zfs_vdev_cache_size bytes will be kept in each
+ * vdev's vdev_cache.
+ *
+ * TODO: Note that with the current ZFS code, it turns out that the
+ * vdev cache is not helpful, and in some cases actually harmful.  It
+ * is better if we disable this.  Once some time has passed, we should
+ * actually remove this to simplify the code.  For now we just disable
+ * it by setting the zfs_vdev_cache_size to zero.  Note that Solaris 11
+ * has made these same changes.
+ */
+int zfs_vdev_cache_max = 1<<14;			/* 16KB */
+int zfs_vdev_cache_size = 0;
+int zfs_vdev_cache_bshift = 16;
+
+#define	VCBS (1 << zfs_vdev_cache_bshift)	/* 64KB */
+
+kstat_t	*vdc_ksp = NULL;
+
+typedef struct vdc_stats {
+	kstat_named_t vdc_stat_delegations;
+	kstat_named_t vdc_stat_hits;
+	kstat_named_t vdc_stat_misses;
+} vdc_stats_t;
+
+static vdc_stats_t vdc_stats = {
+	{ "delegations",	KSTAT_DATA_UINT64 },
+	{ "hits",		KSTAT_DATA_UINT64 },
+	{ "misses",		KSTAT_DATA_UINT64 }
+};
+
+#define	VDCSTAT_BUMP(stat)	atomic_add_64(&vdc_stats.stat.value.ui64, 1);
+
+static int
+vdev_cache_offset_compare(const void *a1, const void *a2)
+{
+	const vdev_cache_entry_t *ve1 = a1;
+	const vdev_cache_entry_t *ve2 = a2;
+
+	if (ve1->ve_offset < ve2->ve_offset)
+		return (-1);
+	if (ve1->ve_offset > ve2->ve_offset)
+		return (1);
+	return (0);
+}
+
+static int
+vdev_cache_lastused_compare(const void *a1, const void *a2)
+{
+	const vdev_cache_entry_t *ve1 = a1;
+	const vdev_cache_entry_t *ve2 = a2;
+
+	if (ddi_time_before(ve1->ve_lastused, ve2->ve_lastused))
+		return (-1);
+	if (ddi_time_after(ve1->ve_lastused, ve2->ve_lastused))
+		return (1);
+
+	/*
+	 * Among equally old entries, sort by offset to ensure uniqueness.
+	 */
+	return (vdev_cache_offset_compare(a1, a2));
+}
+
+/*
+ * Evict the specified entry from the cache.
+ */
+static void
+vdev_cache_evict(vdev_cache_t *vc, vdev_cache_entry_t *ve)
+{
+	ASSERT(MUTEX_HELD(&vc->vc_lock));
+	ASSERT(ve->ve_fill_io == NULL);
+	ASSERT(ve->ve_data != NULL);
+
+	avl_remove(&vc->vc_lastused_tree, ve);
+	avl_remove(&vc->vc_offset_tree, ve);
+	zio_buf_free(ve->ve_data, VCBS);
+	kmem_free(ve, sizeof (vdev_cache_entry_t));
+}
+
+/*
+ * Allocate an entry in the cache.  At the point we don't have the data,
+ * we're just creating a placeholder so that multiple threads don't all
+ * go off and read the same blocks.
+ */
+static vdev_cache_entry_t *
+vdev_cache_allocate(zio_t *zio)
+{
+	vdev_cache_t *vc = &zio->io_vd->vdev_cache;
+	uint64_t offset = P2ALIGN(zio->io_offset, VCBS);
+	vdev_cache_entry_t *ve;
+
+	ASSERT(MUTEX_HELD(&vc->vc_lock));
+
+	if (zfs_vdev_cache_size == 0)
+		return (NULL);
+
+	/*
+	 * If adding a new entry would exceed the cache size,
+	 * evict the oldest entry (LRU).
+	 */
+	if ((avl_numnodes(&vc->vc_lastused_tree) << zfs_vdev_cache_bshift) >
+	    zfs_vdev_cache_size) {
+		ve = avl_first(&vc->vc_lastused_tree);
+		if (ve->ve_fill_io != NULL)
+			return (NULL);
+		ASSERT(ve->ve_hits != 0);
+		vdev_cache_evict(vc, ve);
+	}
+
+	ve = kmem_zalloc(sizeof (vdev_cache_entry_t), KM_SLEEP);
+	ve->ve_offset = offset;
+	ve->ve_lastused = ddi_get_lbolt();
+	ve->ve_data = zio_buf_alloc(VCBS);
+
+	avl_add(&vc->vc_offset_tree, ve);
+	avl_add(&vc->vc_lastused_tree, ve);
+
+	return (ve);
+}
+
+static void
+vdev_cache_hit(vdev_cache_t *vc, vdev_cache_entry_t *ve, zio_t *zio)
+{
+	uint64_t cache_phase = P2PHASE(zio->io_offset, VCBS);
+
+	ASSERT(MUTEX_HELD(&vc->vc_lock));
+	ASSERT(ve->ve_fill_io == NULL);
+
+	if (ve->ve_lastused != ddi_get_lbolt()) {
+		avl_remove(&vc->vc_lastused_tree, ve);
+		ve->ve_lastused = ddi_get_lbolt();
+		avl_add(&vc->vc_lastused_tree, ve);
+	}
+
+	ve->ve_hits++;
+	bcopy(ve->ve_data + cache_phase, zio->io_data, zio->io_size);
+}
+
+/*
+ * Fill a previously allocated cache entry with data.
+ */
+static void
+vdev_cache_fill(zio_t *fio)
+{
+	vdev_t *vd = fio->io_vd;
+	vdev_cache_t *vc = &vd->vdev_cache;
+	vdev_cache_entry_t *ve = fio->io_private;
+	zio_t *pio;
+
+	ASSERT(fio->io_size == VCBS);
+
+	/*
+	 * Add data to the cache.
+	 */
+	mutex_enter(&vc->vc_lock);
+
+	ASSERT(ve->ve_fill_io == fio);
+	ASSERT(ve->ve_offset == fio->io_offset);
+	ASSERT(ve->ve_data == fio->io_data);
+
+	ve->ve_fill_io = NULL;
+
+	/*
+	 * Even if this cache line was invalidated by a missed write update,
+	 * any reads that were queued up before the missed update are still
+	 * valid, so we can satisfy them from this line before we evict it.
+	 */
+	while ((pio = zio_walk_parents(fio)) != NULL)
+		vdev_cache_hit(vc, ve, pio);
+
+	if (fio->io_error || ve->ve_missed_update)
+		vdev_cache_evict(vc, ve);
+
+	mutex_exit(&vc->vc_lock);
+}
+
+/*
+ * Read data from the cache.  Returns B_TRUE cache hit, B_FALSE on miss.
+ */
+boolean_t
+vdev_cache_read(zio_t *zio)
+{
+	vdev_cache_t *vc = &zio->io_vd->vdev_cache;
+	vdev_cache_entry_t *ve, *ve_search;
+	uint64_t cache_offset = P2ALIGN(zio->io_offset, VCBS);
+	zio_t *fio;
+	ASSERTV(uint64_t cache_phase = P2PHASE(zio->io_offset, VCBS));
+
+	ASSERT(zio->io_type == ZIO_TYPE_READ);
+
+	if (zio->io_flags & ZIO_FLAG_DONT_CACHE)
+		return (B_FALSE);
+
+	if (zio->io_size > zfs_vdev_cache_max)
+		return (B_FALSE);
+
+	/*
+	 * If the I/O straddles two or more cache blocks, don't cache it.
+	 */
+	if (P2BOUNDARY(zio->io_offset, zio->io_size, VCBS))
+		return (B_FALSE);
+
+	ASSERT(cache_phase + zio->io_size <= VCBS);
+
+	mutex_enter(&vc->vc_lock);
+
+	ve_search = kmem_alloc(sizeof (vdev_cache_entry_t), KM_SLEEP);
+	ve_search->ve_offset = cache_offset;
+	ve = avl_find(&vc->vc_offset_tree, ve_search, NULL);
+	kmem_free(ve_search, sizeof (vdev_cache_entry_t));
+
+	if (ve != NULL) {
+		if (ve->ve_missed_update) {
+			mutex_exit(&vc->vc_lock);
+			return (B_FALSE);
+		}
+
+		if ((fio = ve->ve_fill_io) != NULL) {
+			zio_vdev_io_bypass(zio);
+			zio_add_child(zio, fio);
+			mutex_exit(&vc->vc_lock);
+			VDCSTAT_BUMP(vdc_stat_delegations);
+			return (B_TRUE);
+		}
+
+		vdev_cache_hit(vc, ve, zio);
+		zio_vdev_io_bypass(zio);
+
+		mutex_exit(&vc->vc_lock);
+		VDCSTAT_BUMP(vdc_stat_hits);
+		return (B_TRUE);
+	}
+
+	ve = vdev_cache_allocate(zio);
+
+	if (ve == NULL) {
+		mutex_exit(&vc->vc_lock);
+		return (B_FALSE);
+	}
+
+	fio = zio_vdev_delegated_io(zio->io_vd, cache_offset,
+	    ve->ve_data, VCBS, ZIO_TYPE_READ, ZIO_PRIORITY_NOW,
+	    ZIO_FLAG_DONT_CACHE, vdev_cache_fill, ve);
+
+	ve->ve_fill_io = fio;
+	zio_vdev_io_bypass(zio);
+	zio_add_child(zio, fio);
+
+	mutex_exit(&vc->vc_lock);
+	zio_nowait(fio);
+	VDCSTAT_BUMP(vdc_stat_misses);
+
+	return (B_TRUE);
+}
+
+/*
+ * Update cache contents upon write completion.
+ */
+void
+vdev_cache_write(zio_t *zio)
+{
+	vdev_cache_t *vc = &zio->io_vd->vdev_cache;
+	vdev_cache_entry_t *ve, ve_search;
+	uint64_t io_start = zio->io_offset;
+	uint64_t io_end = io_start + zio->io_size;
+	uint64_t min_offset = P2ALIGN(io_start, VCBS);
+	uint64_t max_offset = P2ROUNDUP(io_end, VCBS);
+	avl_index_t where;
+
+	ASSERT(zio->io_type == ZIO_TYPE_WRITE);
+
+	mutex_enter(&vc->vc_lock);
+
+	ve_search.ve_offset = min_offset;
+	ve = avl_find(&vc->vc_offset_tree, &ve_search, &where);
+
+	if (ve == NULL)
+		ve = avl_nearest(&vc->vc_offset_tree, where, AVL_AFTER);
+
+	while (ve != NULL && ve->ve_offset < max_offset) {
+		uint64_t start = MAX(ve->ve_offset, io_start);
+		uint64_t end = MIN(ve->ve_offset + VCBS, io_end);
+
+		if (ve->ve_fill_io != NULL) {
+			ve->ve_missed_update = 1;
+		} else {
+			bcopy((char *)zio->io_data + start - io_start,
+			    ve->ve_data + start - ve->ve_offset, end - start);
+		}
+		ve = AVL_NEXT(&vc->vc_offset_tree, ve);
+	}
+	mutex_exit(&vc->vc_lock);
+}
+
+void
+vdev_cache_purge(vdev_t *vd)
+{
+	vdev_cache_t *vc = &vd->vdev_cache;
+	vdev_cache_entry_t *ve;
+
+	mutex_enter(&vc->vc_lock);
+	while ((ve = avl_first(&vc->vc_offset_tree)) != NULL)
+		vdev_cache_evict(vc, ve);
+	mutex_exit(&vc->vc_lock);
+}
+
+void
+vdev_cache_init(vdev_t *vd)
+{
+	vdev_cache_t *vc = &vd->vdev_cache;
+
+	mutex_init(&vc->vc_lock, NULL, MUTEX_DEFAULT, NULL);
+
+	avl_create(&vc->vc_offset_tree, vdev_cache_offset_compare,
+	    sizeof (vdev_cache_entry_t),
+	    offsetof(struct vdev_cache_entry, ve_offset_node));
+
+	avl_create(&vc->vc_lastused_tree, vdev_cache_lastused_compare,
+	    sizeof (vdev_cache_entry_t),
+	    offsetof(struct vdev_cache_entry, ve_lastused_node));
+}
+
+void
+vdev_cache_fini(vdev_t *vd)
+{
+	vdev_cache_t *vc = &vd->vdev_cache;
+
+	vdev_cache_purge(vd);
+
+	avl_destroy(&vc->vc_offset_tree);
+	avl_destroy(&vc->vc_lastused_tree);
+
+	mutex_destroy(&vc->vc_lock);
+}
+
+void
+vdev_cache_stat_init(void)
+{
+	vdc_ksp = kstat_create("zfs", 0, "vdev_cache_stats", "misc",
+	    KSTAT_TYPE_NAMED, sizeof (vdc_stats) / sizeof (kstat_named_t),
+	    KSTAT_FLAG_VIRTUAL);
+	if (vdc_ksp != NULL) {
+		vdc_ksp->ks_data = &vdc_stats;
+		kstat_install(vdc_ksp);
+	}
+}
+
+void
+vdev_cache_stat_fini(void)
+{
+	if (vdc_ksp != NULL) {
+		kstat_delete(vdc_ksp);
+		vdc_ksp = NULL;
+	}
+}
+
+#if defined(_KERNEL) && defined(HAVE_SPL)
+module_param(zfs_vdev_cache_max, int, 0644);
+MODULE_PARM_DESC(zfs_vdev_cache_max, "Inflate reads small than max");
+
+module_param(zfs_vdev_cache_size, int, 0444);
+MODULE_PARM_DESC(zfs_vdev_cache_size, "Total size of the per-disk cache");
+
+module_param(zfs_vdev_cache_bshift, int, 0644);
+MODULE_PARM_DESC(zfs_vdev_cache_bshift, "Shift size to inflate reads too");
+#endif
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/module/zfs/vdev_disk.c
@@ -0,0 +1,869 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (C) 2008-2010 Lawrence Livermore National Security, LLC.
+ * Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ * Rewritten for Linux by Brian Behlendorf <behlendorf1@llnl.gov>.
+ * LLNL-CODE-403049.
+ * Copyright (c) 2012, 2014 by Delphix. All rights reserved.
+ */
+
+#include <sys/zfs_context.h>
+#include <sys/spa.h>
+#include <sys/vdev_disk.h>
+#include <sys/vdev_impl.h>
+#include <sys/fs/zfs.h>
+#include <sys/zio.h>
+#include <sys/sunldi.h>
+
+char *zfs_vdev_scheduler = VDEV_SCHEDULER;
+static void *zfs_vdev_holder = VDEV_HOLDER;
+
+/*
+ * Virtual device vector for disks.
+ */
+typedef struct dio_request {
+	struct completion	dr_comp;	/* Completion for sync IO */
+	zio_t			*dr_zio;	/* Parent ZIO */
+	atomic_t		dr_ref;		/* References */
+	int			dr_wait;	/* Wait for IO */
+	int			dr_error;	/* Bio error */
+	int			dr_bio_count;	/* Count of bio's */
+	struct bio		*dr_bio[0];	/* Attached bio's */
+} dio_request_t;
+
+
+#ifdef HAVE_OPEN_BDEV_EXCLUSIVE
+static fmode_t
+vdev_bdev_mode(int smode)
+{
+	fmode_t mode = 0;
+
+	ASSERT3S(smode & (FREAD | FWRITE), !=, 0);
+
+	if (smode & FREAD)
+		mode |= FMODE_READ;
+
+	if (smode & FWRITE)
+		mode |= FMODE_WRITE;
+
+	return (mode);
+}
+#else
+static int
+vdev_bdev_mode(int smode)
+{
+	int mode = 0;
+
+	ASSERT3S(smode & (FREAD | FWRITE), !=, 0);
+
+	if ((smode & FREAD) && !(smode & FWRITE))
+		mode = MS_RDONLY;
+
+	return (mode);
+}
+#endif /* HAVE_OPEN_BDEV_EXCLUSIVE */
+
+static uint64_t
+bdev_capacity(struct block_device *bdev)
+{
+	struct hd_struct *part = bdev->bd_part;
+
+	/* The partition capacity referenced by the block device */
+	if (part)
+		return (part->nr_sects << 9);
+
+	/* Otherwise assume the full device capacity */
+	return (get_capacity(bdev->bd_disk) << 9);
+}
+
+static void
+vdev_disk_error(zio_t *zio)
+{
+#ifdef ZFS_DEBUG
+	printk("ZFS: zio error=%d type=%d offset=%llu size=%llu "
+	    "flags=%x delay=%llu\n", zio->io_error, zio->io_type,
+	    (u_longlong_t)zio->io_offset, (u_longlong_t)zio->io_size,
+	    zio->io_flags, (u_longlong_t)zio->io_delay);
+#endif
+}
+
+/*
+ * Use the Linux 'noop' elevator for zfs managed block devices.  This
+ * strikes the ideal balance by allowing the zfs elevator to do all
+ * request ordering and prioritization.  While allowing the Linux
+ * elevator to do the maximum front/back merging allowed by the
+ * physical device.  This yields the largest possible requests for
+ * the device with the lowest total overhead.
+ */
+static int
+vdev_elevator_switch(vdev_t *v, char *elevator)
+{
+	vdev_disk_t *vd = v->vdev_tsd;
+	struct block_device *bdev = vd->vd_bdev;
+	struct request_queue *q = bdev_get_queue(bdev);
+	char *device = bdev->bd_disk->disk_name;
+	int error;
+
+	/*
+	 * Skip devices which are not whole disks (partitions).
+	 * Device-mapper devices are excepted since they may be whole
+	 * disks despite the vdev_wholedisk flag, in which case we can
+	 * and should switch the elevator. If the device-mapper device
+	 * does not have an elevator (i.e. dm-raid, dm-crypt, etc.) the
+	 * "Skip devices without schedulers" check below will fail.
+	 */
+	if (!v->vdev_wholedisk && strncmp(device, "dm-", 3) != 0)
+		return (0);
+
+	/* Skip devices without schedulers (loop, ram, dm, etc) */
+	if (!q->elevator || !blk_queue_stackable(q))
+		return (0);
+
+	/* Leave existing scheduler when set to "none" */
+	if ((strncmp(elevator, "none", 4) == 0) && (strlen(elevator) == 4))
+		return (0);
+
+#ifdef HAVE_ELEVATOR_CHANGE
+	error = elevator_change(q, elevator);
+#else
+	/*
+	 * For pre-2.6.36 kernels elevator_change() is not available.
+	 * Therefore we fall back to using a usermodehelper to echo the
+	 * elevator into sysfs;  This requires /bin/echo and sysfs to be
+	 * mounted which may not be true early in the boot process.
+	 */
+#define	SET_SCHEDULER_CMD \
+	"exec 0</dev/null " \
+	"     1>/sys/block/%s/queue/scheduler " \
+	"     2>/dev/null; " \
+	"echo %s"
+
+	{
+		char *argv[] = { "/bin/sh", "-c", NULL, NULL };
+		char *envp[] = { NULL };
+
+		argv[2] = kmem_asprintf(SET_SCHEDULER_CMD, device, elevator);
+		error = call_usermodehelper(argv[0], argv, envp, UMH_WAIT_PROC);
+		strfree(argv[2]);
+	}
+#endif /* HAVE_ELEVATOR_CHANGE */
+	if (error)
+		printk("ZFS: Unable to set \"%s\" scheduler for %s (%s): %d\n",
+		    elevator, v->vdev_path, device, error);
+
+	return (error);
+}
+
+/*
+ * Expanding a whole disk vdev involves invoking BLKRRPART on the
+ * whole disk device. This poses a problem, because BLKRRPART will
+ * return EBUSY if one of the disk's partitions is open. That's why
+ * we have to do it here, just before opening the data partition.
+ * Unfortunately, BLKRRPART works by dropping all partitions and
+ * recreating them, which means that for a short time window, all
+ * /dev/sdxN device files disappear (until udev recreates them).
+ * This means two things:
+ *  - When we open the data partition just after a BLKRRPART, we
+ *    can't do it using the normal device file path because of the
+ *    obvious race condition with udev. Instead, we use reliable
+ *    kernel APIs to get a handle to the new partition device from
+ *    the whole disk device.
+ *  - Because vdev_disk_open() initially needs to find the device
+ *    using its path, multiple vdev_disk_open() invocations in
+ *    short succession on the same disk with BLKRRPARTs in the
+ *    middle have a high probability of failure (because of the
+ *    race condition with udev). A typical situation where this
+ *    might happen is when the zpool userspace tool does a
+ *    TRYIMPORT immediately followed by an IMPORT. For this
+ *    reason, we only invoke BLKRRPART in the module when strictly
+ *    necessary (zpool online -e case), and rely on userspace to
+ *    do it when possible.
+ */
+static struct block_device *
+vdev_disk_rrpart(const char *path, int mode, vdev_disk_t *vd)
+{
+#if defined(HAVE_3ARG_BLKDEV_GET) && defined(HAVE_GET_GENDISK)
+	struct block_device *bdev, *result = ERR_PTR(-ENXIO);
+	struct gendisk *disk;
+	int error, partno;
+
+	bdev = vdev_bdev_open(path, vdev_bdev_mode(mode), zfs_vdev_holder);
+	if (IS_ERR(bdev))
+		return (bdev);
+
+	disk = get_gendisk(bdev->bd_dev, &partno);
+	vdev_bdev_close(bdev, vdev_bdev_mode(mode));
+
+	if (disk) {
+		bdev = bdget(disk_devt(disk));
+		if (bdev) {
+			error = blkdev_get(bdev, vdev_bdev_mode(mode), vd);
+			if (error == 0)
+				error = ioctl_by_bdev(bdev, BLKRRPART, 0);
+			vdev_bdev_close(bdev, vdev_bdev_mode(mode));
+		}
+
+		bdev = bdget_disk(disk, partno);
+		if (bdev) {
+			error = blkdev_get(bdev,
+			    vdev_bdev_mode(mode) | FMODE_EXCL, vd);
+			if (error == 0)
+				result = bdev;
+		}
+		put_disk(disk);
+	}
+
+	return (result);
+#else
+	return (ERR_PTR(-EOPNOTSUPP));
+#endif /* defined(HAVE_3ARG_BLKDEV_GET) && defined(HAVE_GET_GENDISK) */
+}
+
+static int
+vdev_disk_open(vdev_t *v, uint64_t *psize, uint64_t *max_psize,
+    uint64_t *ashift)
+{
+	struct block_device *bdev = ERR_PTR(-ENXIO);
+	vdev_disk_t *vd;
+	int count = 0, mode, block_size;
+
+	/* Must have a pathname and it must be absolute. */
+	if (v->vdev_path == NULL || v->vdev_path[0] != '/') {
+		v->vdev_stat.vs_aux = VDEV_AUX_BAD_LABEL;
+		return (SET_ERROR(EINVAL));
+	}
+
+	/*
+	 * Reopen the device if it's not currently open. Otherwise,
+	 * just update the physical size of the device.
+	 */
+	if (v->vdev_tsd != NULL) {
+		ASSERT(v->vdev_reopening);
+		vd = v->vdev_tsd;
+		goto skip_open;
+	}
+
+	vd = kmem_zalloc(sizeof (vdev_disk_t), KM_SLEEP);
+	if (vd == NULL)
+		return (SET_ERROR(ENOMEM));
+
+	/*
+	 * Devices are always opened by the path provided at configuration
+	 * time.  This means that if the provided path is a udev by-id path
+	 * then drives may be recabled without an issue.  If the provided
+	 * path is a udev by-path path, then the physical location information
+	 * will be preserved.  This can be critical for more complicated
+	 * configurations where drives are located in specific physical
+	 * locations to maximize the systems tolerence to component failure.
+	 * Alternatively, you can provide your own udev rule to flexibly map
+	 * the drives as you see fit.  It is not advised that you use the
+	 * /dev/[hd]d devices which may be reordered due to probing order.
+	 * Devices in the wrong locations will be detected by the higher
+	 * level vdev validation.
+	 *
+	 * The specified paths may be briefly removed and recreated in
+	 * response to udev events.  This should be exceptionally unlikely
+	 * because the zpool command makes every effort to verify these paths
+	 * have already settled prior to reaching this point.  Therefore,
+	 * a ENOENT failure at this point is highly likely to be transient
+	 * and it is reasonable to sleep and retry before giving up.  In
+	 * practice delays have been observed to be on the order of 100ms.
+	 */
+	mode = spa_mode(v->vdev_spa);
+	if (v->vdev_wholedisk && v->vdev_expanding)
+		bdev = vdev_disk_rrpart(v->vdev_path, mode, vd);
+
+	while (IS_ERR(bdev) && count < 50) {
+		bdev = vdev_bdev_open(v->vdev_path,
+		    vdev_bdev_mode(mode), zfs_vdev_holder);
+		if (unlikely(PTR_ERR(bdev) == -ENOENT)) {
+			msleep(10);
+			count++;
+		} else if (IS_ERR(bdev)) {
+			break;
+		}
+	}
+
+	if (IS_ERR(bdev)) {
+		dprintf("failed open v->vdev_path=%s, error=%d count=%d\n",
+		    v->vdev_path, -PTR_ERR(bdev), count);
+		kmem_free(vd, sizeof (vdev_disk_t));
+		return (SET_ERROR(-PTR_ERR(bdev)));
+	}
+
+	v->vdev_tsd = vd;
+	vd->vd_bdev = bdev;
+
+skip_open:
+	/*  Determine the physical block size */
+	block_size = vdev_bdev_block_size(vd->vd_bdev);
+
+	/* Clear the nowritecache bit, causes vdev_reopen() to try again. */
+	v->vdev_nowritecache = B_FALSE;
+
+	/* Inform the ZIO pipeline that we are non-rotational */
+	v->vdev_nonrot = blk_queue_nonrot(bdev_get_queue(vd->vd_bdev));
+
+	/* Physical volume size in bytes */
+	*psize = bdev_capacity(vd->vd_bdev);
+
+	/* TODO: report possible expansion size */
+	*max_psize = *psize;
+
+	/* Based on the minimum sector size set the block size */
+	*ashift = highbit64(MAX(block_size, SPA_MINBLOCKSIZE)) - 1;
+
+	/* Try to set the io scheduler elevator algorithm */
+	(void) vdev_elevator_switch(v, zfs_vdev_scheduler);
+
+	return (0);
+}
+
+static void
+vdev_disk_close(vdev_t *v)
+{
+	vdev_disk_t *vd = v->vdev_tsd;
+
+	if (v->vdev_reopening || vd == NULL)
+		return;
+
+	if (vd->vd_bdev != NULL)
+		vdev_bdev_close(vd->vd_bdev,
+		    vdev_bdev_mode(spa_mode(v->vdev_spa)));
+
+	kmem_free(vd, sizeof (vdev_disk_t));
+	v->vdev_tsd = NULL;
+}
+
+static dio_request_t *
+vdev_disk_dio_alloc(int bio_count)
+{
+	dio_request_t *dr;
+	int i;
+
+	dr = kmem_zalloc(sizeof (dio_request_t) +
+	    sizeof (struct bio *) * bio_count, KM_SLEEP);
+	if (dr) {
+		init_completion(&dr->dr_comp);
+		atomic_set(&dr->dr_ref, 0);
+		dr->dr_bio_count = bio_count;
+		dr->dr_error = 0;
+
+		for (i = 0; i < dr->dr_bio_count; i++)
+			dr->dr_bio[i] = NULL;
+	}
+
+	return (dr);
+}
+
+static void
+vdev_disk_dio_free(dio_request_t *dr)
+{
+	int i;
+
+	for (i = 0; i < dr->dr_bio_count; i++)
+		if (dr->dr_bio[i])
+			bio_put(dr->dr_bio[i]);
+
+	kmem_free(dr, sizeof (dio_request_t) +
+	    sizeof (struct bio *) * dr->dr_bio_count);
+}
+
+static void
+vdev_disk_dio_get(dio_request_t *dr)
+{
+	atomic_inc(&dr->dr_ref);
+}
+
+static int
+vdev_disk_dio_put(dio_request_t *dr)
+{
+	int rc = atomic_dec_return(&dr->dr_ref);
+
+	/*
+	 * Free the dio_request when the last reference is dropped and
+	 * ensure zio_interpret is called only once with the correct zio
+	 */
+	if (rc == 0) {
+		zio_t *zio = dr->dr_zio;
+		int error = dr->dr_error;
+
+		vdev_disk_dio_free(dr);
+
+		if (zio) {
+			zio->io_delay = jiffies_64 - zio->io_delay;
+			zio->io_error = error;
+			ASSERT3S(zio->io_error, >=, 0);
+			if (zio->io_error)
+				vdev_disk_error(zio);
+			zio_interrupt(zio);
+		}
+	}
+
+	return (rc);
+}
+
+BIO_END_IO_PROTO(vdev_disk_physio_completion, bio, error)
+{
+	dio_request_t *dr = bio->bi_private;
+	int rc;
+	int wait;
+
+	if (dr->dr_error == 0) {
+#ifdef HAVE_1ARG_BIO_END_IO_T
+		dr->dr_error = -(bio->bi_error);
+#else
+		if (error)
+			dr->dr_error = -(error);
+		else if (!test_bit(BIO_UPTODATE, &bio->bi_flags))
+			dr->dr_error = EIO;
+#endif
+	}
+
+	wait = dr->dr_wait;
+	/* Drop reference aquired by __vdev_disk_physio */
+	rc = vdev_disk_dio_put(dr);
+
+	/* Wake up synchronous waiter this is the last outstanding bio */
+	if (wait && rc == 1)
+		complete(&dr->dr_comp);
+}
+
+static inline unsigned long
+bio_nr_pages(void *bio_ptr, unsigned int bio_size)
+{
+	return ((((unsigned long)bio_ptr + bio_size + PAGE_SIZE - 1) >>
+	    PAGE_SHIFT) - ((unsigned long)bio_ptr >> PAGE_SHIFT));
+}
+
+static unsigned int
+bio_map(struct bio *bio, void *bio_ptr, unsigned int bio_size)
+{
+	unsigned int offset, size, i;
+	struct page *page;
+
+	offset = offset_in_page(bio_ptr);
+	for (i = 0; i < bio->bi_max_vecs; i++) {
+		size = PAGE_SIZE - offset;
+
+		if (bio_size <= 0)
+			break;
+
+		if (size > bio_size)
+			size = bio_size;
+
+		if (is_vmalloc_addr(bio_ptr))
+			page = vmalloc_to_page(bio_ptr);
+		else
+			page = virt_to_page(bio_ptr);
+
+		/*
+		 * Some network related block device uses tcp_sendpage, which
+		 * doesn't behave well when using 0-count page, this is a
+		 * safety net to catch them.
+		 */
+		ASSERT3S(page_count(page), >, 0);
+
+		if (bio_add_page(bio, page, size, offset) != size)
+			break;
+
+		bio_ptr  += size;
+		bio_size -= size;
+		offset = 0;
+	}
+
+	return (bio_size);
+}
+
+static inline void
+vdev_submit_bio(int rw, struct bio *bio)
+{
+#ifdef HAVE_CURRENT_BIO_TAIL
+	struct bio **bio_tail = current->bio_tail;
+	current->bio_tail = NULL;
+	submit_bio(rw, bio);
+	current->bio_tail = bio_tail;
+#else
+	struct bio_list *bio_list = current->bio_list;
+	current->bio_list = NULL;
+	submit_bio(rw, bio);
+	current->bio_list = bio_list;
+#endif
+}
+
+static int
+__vdev_disk_physio(struct block_device *bdev, zio_t *zio, caddr_t kbuf_ptr,
+    size_t kbuf_size, uint64_t kbuf_offset, int flags, int wait)
+{
+	dio_request_t *dr;
+	caddr_t bio_ptr;
+	uint64_t bio_offset;
+	int rw, bio_size, bio_count = 16;
+	int i = 0, error = 0;
+
+	ASSERT3U(kbuf_offset + kbuf_size, <=, bdev->bd_inode->i_size);
+
+retry:
+	dr = vdev_disk_dio_alloc(bio_count);
+	if (dr == NULL)
+		return (ENOMEM);
+
+	if (zio && !(zio->io_flags & (ZIO_FLAG_IO_RETRY | ZIO_FLAG_TRYHARD)))
+		bio_set_flags_failfast(bdev, &flags);
+
+	rw = flags;
+	dr->dr_zio = zio;
+	dr->dr_wait = wait;
+
+	/*
+	 * When the IO size exceeds the maximum bio size for the request
+	 * queue we are forced to break the IO in multiple bio's and wait
+	 * for them all to complete.  Ideally, all pool users will set
+	 * their volume block size to match the maximum request size and
+	 * the common case will be one bio per vdev IO request.
+	 */
+	bio_ptr    = kbuf_ptr;
+	bio_offset = kbuf_offset;
+	bio_size   = kbuf_size;
+	for (i = 0; i <= dr->dr_bio_count; i++) {
+
+		/* Finished constructing bio's for given buffer */
+		if (bio_size <= 0)
+			break;
+
+		/*
+		 * By default only 'bio_count' bio's per dio are allowed.
+		 * However, if we find ourselves in a situation where more
+		 * are needed we allocate a larger dio and warn the user.
+		 */
+		if (dr->dr_bio_count == i) {
+			vdev_disk_dio_free(dr);
+			bio_count *= 2;
+			goto retry;
+		}
+
+		/* bio_alloc() with __GFP_WAIT never returns NULL */
+		dr->dr_bio[i] = bio_alloc(GFP_NOIO,
+		    MIN(bio_nr_pages(bio_ptr, bio_size), BIO_MAX_PAGES));
+		if (unlikely(dr->dr_bio[i] == NULL)) {
+			vdev_disk_dio_free(dr);
+			return (ENOMEM);
+		}
+
+		/* Matching put called by vdev_disk_physio_completion */
+		vdev_disk_dio_get(dr);
+
+		dr->dr_bio[i]->bi_bdev = bdev;
+		BIO_BI_SECTOR(dr->dr_bio[i]) = bio_offset >> 9;
+		dr->dr_bio[i]->bi_rw = rw;
+		dr->dr_bio[i]->bi_end_io = vdev_disk_physio_completion;
+		dr->dr_bio[i]->bi_private = dr;
+
+		/* Remaining size is returned to become the new size */
+		bio_size = bio_map(dr->dr_bio[i], bio_ptr, bio_size);
+
+		/* Advance in buffer and construct another bio if needed */
+		bio_ptr    += BIO_BI_SIZE(dr->dr_bio[i]);
+		bio_offset += BIO_BI_SIZE(dr->dr_bio[i]);
+	}
+
+	/* Extra reference to protect dio_request during vdev_submit_bio */
+	vdev_disk_dio_get(dr);
+	if (zio)
+		zio->io_delay = jiffies_64;
+
+	/* Submit all bio's associated with this dio */
+	for (i = 0; i < dr->dr_bio_count; i++)
+		if (dr->dr_bio[i])
+			vdev_submit_bio(rw, dr->dr_bio[i]);
+
+	/*
+	 * On synchronous blocking requests we wait for all bio the completion
+	 * callbacks to run.  We will be woken when the last callback runs
+	 * for this dio.  We are responsible for putting the last dio_request
+	 * reference will in turn put back the last bio references.  The
+	 * only synchronous consumer is vdev_disk_read_rootlabel() all other
+	 * IO originating from vdev_disk_io_start() is asynchronous.
+	 */
+	if (wait) {
+		wait_for_completion(&dr->dr_comp);
+		error = dr->dr_error;
+		ASSERT3S(atomic_read(&dr->dr_ref), ==, 1);
+	}
+
+	(void) vdev_disk_dio_put(dr);
+
+	return (error);
+}
+
+int
+vdev_disk_physio(struct block_device *bdev, caddr_t kbuf,
+    size_t size, uint64_t offset, int flags)
+{
+	bio_set_flags_failfast(bdev, &flags);
+	return (__vdev_disk_physio(bdev, NULL, kbuf, size, offset, flags, 1));
+}
+
+BIO_END_IO_PROTO(vdev_disk_io_flush_completion, bio, rc)
+{
+	zio_t *zio = bio->bi_private;
+#ifdef HAVE_1ARG_BIO_END_IO_T
+	int rc = bio->bi_error;
+#endif
+
+	zio->io_delay = jiffies_64 - zio->io_delay;
+	zio->io_error = -rc;
+	if (rc && (rc == -EOPNOTSUPP))
+		zio->io_vd->vdev_nowritecache = B_TRUE;
+
+	bio_put(bio);
+	ASSERT3S(zio->io_error, >=, 0);
+	if (zio->io_error)
+		vdev_disk_error(zio);
+	zio_interrupt(zio);
+}
+
+static int
+vdev_disk_io_flush(struct block_device *bdev, zio_t *zio)
+{
+	struct request_queue *q;
+	struct bio *bio;
+
+	q = bdev_get_queue(bdev);
+	if (!q)
+		return (ENXIO);
+
+	bio = bio_alloc(GFP_NOIO, 0);
+	/* bio_alloc() with __GFP_WAIT never returns NULL */
+	if (unlikely(bio == NULL))
+		return (ENOMEM);
+
+	bio->bi_end_io = vdev_disk_io_flush_completion;
+	bio->bi_private = zio;
+	bio->bi_bdev = bdev;
+	zio->io_delay = jiffies_64;
+	vdev_submit_bio(VDEV_WRITE_FLUSH_FUA, bio);
+	invalidate_bdev(bdev);
+
+	return (0);
+}
+
+static void
+vdev_disk_io_start(zio_t *zio)
+{
+	vdev_t *v = zio->io_vd;
+	vdev_disk_t *vd = v->vdev_tsd;
+	zio_priority_t pri = zio->io_priority;
+	int flags, error;
+
+	switch (zio->io_type) {
+	case ZIO_TYPE_IOCTL:
+
+		if (!vdev_readable(v)) {
+			zio->io_error = SET_ERROR(ENXIO);
+			zio_interrupt(zio);
+			return;
+		}
+
+		switch (zio->io_cmd) {
+		case DKIOCFLUSHWRITECACHE:
+
+			if (zfs_nocacheflush)
+				break;
+
+			if (v->vdev_nowritecache) {
+				zio->io_error = SET_ERROR(ENOTSUP);
+				break;
+			}
+
+			error = vdev_disk_io_flush(vd->vd_bdev, zio);
+			if (error == 0)
+				return;
+
+			zio->io_error = error;
+			if (error == ENOTSUP)
+				v->vdev_nowritecache = B_TRUE;
+
+			break;
+
+		default:
+			zio->io_error = SET_ERROR(ENOTSUP);
+		}
+
+		zio_execute(zio);
+		return;
+	case ZIO_TYPE_WRITE:
+		if ((pri == ZIO_PRIORITY_SYNC_WRITE) && (v->vdev_nonrot))
+			flags = WRITE_SYNC;
+		else
+			flags = WRITE;
+		break;
+
+	case ZIO_TYPE_READ:
+		if ((pri == ZIO_PRIORITY_SYNC_READ) && (v->vdev_nonrot))
+			flags = READ_SYNC;
+		else
+			flags = READ;
+		break;
+
+	default:
+		zio->io_error = SET_ERROR(ENOTSUP);
+		zio_interrupt(zio);
+		return;
+	}
+
+	error = __vdev_disk_physio(vd->vd_bdev, zio, zio->io_data,
+	    zio->io_size, zio->io_offset, flags, 0);
+	if (error) {
+		zio->io_error = error;
+		zio_interrupt(zio);
+		return;
+	}
+}
+
+static void
+vdev_disk_io_done(zio_t *zio)
+{
+	/*
+	 * If the device returned EIO, we revalidate the media.  If it is
+	 * determined the media has changed this triggers the asynchronous
+	 * removal of the device from the configuration.
+	 */
+	if (zio->io_error == EIO) {
+		vdev_t *v = zio->io_vd;
+		vdev_disk_t *vd = v->vdev_tsd;
+
+		if (check_disk_change(vd->vd_bdev)) {
+			vdev_bdev_invalidate(vd->vd_bdev);
+			v->vdev_remove_wanted = B_TRUE;
+			spa_async_request(zio->io_spa, SPA_ASYNC_REMOVE);
+		}
+	}
+}
+
+static void
+vdev_disk_hold(vdev_t *vd)
+{
+	ASSERT(spa_config_held(vd->vdev_spa, SCL_STATE, RW_WRITER));
+
+	/* We must have a pathname, and it must be absolute. */
+	if (vd->vdev_path == NULL || vd->vdev_path[0] != '/')
+		return;
+
+	/*
+	 * Only prefetch path and devid info if the device has
+	 * never been opened.
+	 */
+	if (vd->vdev_tsd != NULL)
+		return;
+
+	/* XXX: Implement me as a vnode lookup for the device */
+	vd->vdev_name_vp = NULL;
+	vd->vdev_devid_vp = NULL;
+}
+
+static void
+vdev_disk_rele(vdev_t *vd)
+{
+	ASSERT(spa_config_held(vd->vdev_spa, SCL_STATE, RW_WRITER));
+
+	/* XXX: Implement me as a vnode rele for the device */
+}
+
+vdev_ops_t vdev_disk_ops = {
+	vdev_disk_open,
+	vdev_disk_close,
+	vdev_default_asize,
+	vdev_disk_io_start,
+	vdev_disk_io_done,
+	NULL,
+	vdev_disk_hold,
+	vdev_disk_rele,
+	VDEV_TYPE_DISK,		/* name of this vdev type */
+	B_TRUE			/* leaf vdev */
+};
+
+/*
+ * Given the root disk device devid or pathname, read the label from
+ * the device, and construct a configuration nvlist.
+ */
+int
+vdev_disk_read_rootlabel(char *devpath, char *devid, nvlist_t **config)
+{
+	struct block_device *bdev;
+	vdev_label_t *label;
+	uint64_t s, size;
+	int i;
+
+	bdev = vdev_bdev_open(devpath, vdev_bdev_mode(FREAD), zfs_vdev_holder);
+	if (IS_ERR(bdev))
+		return (-PTR_ERR(bdev));
+
+	s = bdev_capacity(bdev);
+	if (s == 0) {
+		vdev_bdev_close(bdev, vdev_bdev_mode(FREAD));
+		return (EIO);
+	}
+
+	size = P2ALIGN_TYPED(s, sizeof (vdev_label_t), uint64_t);
+	label = vmem_alloc(sizeof (vdev_label_t), KM_SLEEP);
+
+	for (i = 0; i < VDEV_LABELS; i++) {
+		uint64_t offset, state, txg = 0;
+
+		/* read vdev label */
+		offset = vdev_label_offset(size, i, 0);
+		if (vdev_disk_physio(bdev, (caddr_t)label,
+		    VDEV_SKIP_SIZE + VDEV_PHYS_SIZE, offset, READ_SYNC) != 0)
+			continue;
+
+		if (nvlist_unpack(label->vl_vdev_phys.vp_nvlist,
+		    sizeof (label->vl_vdev_phys.vp_nvlist), config, 0) != 0) {
+			*config = NULL;
+			continue;
+		}
+
+		if (nvlist_lookup_uint64(*config, ZPOOL_CONFIG_POOL_STATE,
+		    &state) != 0 || state >= POOL_STATE_DESTROYED) {
+			nvlist_free(*config);
+			*config = NULL;
+			continue;
+		}
+
+		if (nvlist_lookup_uint64(*config, ZPOOL_CONFIG_POOL_TXG,
+		    &txg) != 0 || txg == 0) {
+			nvlist_free(*config);
+			*config = NULL;
+			continue;
+		}
+
+		break;
+	}
+
+	vmem_free(label, sizeof (vdev_label_t));
+	vdev_bdev_close(bdev, vdev_bdev_mode(FREAD));
+
+	return (0);
+}
+
+module_param(zfs_vdev_scheduler, charp, 0644);
+MODULE_PARM_DESC(zfs_vdev_scheduler, "I/O scheduler");
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/module/zfs/vdev_file.c
@@ -0,0 +1,261 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2014 by Delphix. All rights reserved.
+ */
+
+#include <sys/zfs_context.h>
+#include <sys/spa.h>
+#include <sys/spa_impl.h>
+#include <sys/vdev_file.h>
+#include <sys/vdev_impl.h>
+#include <sys/zio.h>
+#include <sys/fs/zfs.h>
+#include <sys/fm/fs/zfs.h>
+
+/*
+ * Virtual device vector for files.
+ */
+
+static void
+vdev_file_hold(vdev_t *vd)
+{
+	ASSERT(vd->vdev_path != NULL);
+}
+
+static void
+vdev_file_rele(vdev_t *vd)
+{
+	ASSERT(vd->vdev_path != NULL);
+}
+
+static int
+vdev_file_open(vdev_t *vd, uint64_t *psize, uint64_t *max_psize,
+    uint64_t *ashift)
+{
+	vdev_file_t *vf;
+	vnode_t *vp;
+	vattr_t vattr;
+	int error;
+
+	/* Rotational optimizations only make sense on block devices */
+	vd->vdev_nonrot = B_TRUE;
+
+	/*
+	 * We must have a pathname, and it must be absolute.
+	 */
+	if (vd->vdev_path == NULL || vd->vdev_path[0] != '/') {
+		vd->vdev_stat.vs_aux = VDEV_AUX_BAD_LABEL;
+		return (SET_ERROR(EINVAL));
+	}
+
+	/*
+	 * Reopen the device if it's not currently open.  Otherwise,
+	 * just update the physical size of the device.
+	 */
+	if (vd->vdev_tsd != NULL) {
+		ASSERT(vd->vdev_reopening);
+		vf = vd->vdev_tsd;
+		goto skip_open;
+	}
+
+	vf = vd->vdev_tsd = kmem_zalloc(sizeof (vdev_file_t), KM_SLEEP);
+
+	/*
+	 * We always open the files from the root of the global zone, even if
+	 * we're in a local zone.  If the user has gotten to this point, the
+	 * administrator has already decided that the pool should be available
+	 * to local zone users, so the underlying devices should be as well.
+	 */
+	ASSERT(vd->vdev_path != NULL && vd->vdev_path[0] == '/');
+	error = vn_openat(vd->vdev_path + 1, UIO_SYSSPACE,
+	    spa_mode(vd->vdev_spa) | FOFFMAX, 0, &vp, 0, 0, rootdir, -1);
+
+	if (error) {
+		vd->vdev_stat.vs_aux = VDEV_AUX_OPEN_FAILED;
+		return (error);
+	}
+
+	vf->vf_vnode = vp;
+
+#ifdef _KERNEL
+	/*
+	 * Make sure it's a regular file.
+	 */
+	if (vp->v_type != VREG) {
+		vd->vdev_stat.vs_aux = VDEV_AUX_OPEN_FAILED;
+		return (SET_ERROR(ENODEV));
+	}
+#endif
+
+skip_open:
+	/*
+	 * Determine the physical size of the file.
+	 */
+	vattr.va_mask = AT_SIZE;
+	error = VOP_GETATTR(vf->vf_vnode, &vattr, 0, kcred, NULL);
+	if (error) {
+		vd->vdev_stat.vs_aux = VDEV_AUX_OPEN_FAILED;
+		return (error);
+	}
+
+	*max_psize = *psize = vattr.va_size;
+	*ashift = SPA_MINBLOCKSHIFT;
+
+	return (0);
+}
+
+static void
+vdev_file_close(vdev_t *vd)
+{
+	vdev_file_t *vf = vd->vdev_tsd;
+
+	if (vd->vdev_reopening || vf == NULL)
+		return;
+
+	if (vf->vf_vnode != NULL) {
+		(void) VOP_PUTPAGE(vf->vf_vnode, 0, 0, B_INVAL, kcred, NULL);
+		(void) VOP_CLOSE(vf->vf_vnode, spa_mode(vd->vdev_spa), 1, 0,
+		    kcred, NULL);
+	}
+
+	vd->vdev_delayed_close = B_FALSE;
+	kmem_free(vf, sizeof (vdev_file_t));
+	vd->vdev_tsd = NULL;
+}
+
+static void
+vdev_file_io_strategy(void *arg)
+{
+	zio_t *zio = (zio_t *)arg;
+	vdev_t *vd = zio->io_vd;
+	vdev_file_t *vf = vd->vdev_tsd;
+	ssize_t resid;
+
+	zio->io_error = vn_rdwr(zio->io_type == ZIO_TYPE_READ ?
+	    UIO_READ : UIO_WRITE, vf->vf_vnode, zio->io_data,
+	    zio->io_size, zio->io_offset, UIO_SYSSPACE,
+	    0, RLIM64_INFINITY, kcred, &resid);
+
+	if (resid != 0 && zio->io_error == 0)
+		zio->io_error = SET_ERROR(ENOSPC);
+
+	zio_interrupt(zio);
+}
+
+static void
+vdev_file_io_fsync(void *arg)
+{
+	zio_t *zio = (zio_t *)arg;
+	vdev_file_t *vf = zio->io_vd->vdev_tsd;
+
+	zio->io_error = VOP_FSYNC(vf->vf_vnode, FSYNC | FDSYNC, kcred, NULL);
+
+	zio_interrupt(zio);
+}
+
+static void
+vdev_file_io_start(zio_t *zio)
+{
+	vdev_t *vd = zio->io_vd;
+	vdev_file_t *vf = vd->vdev_tsd;
+
+	if (zio->io_type == ZIO_TYPE_IOCTL) {
+		/* XXPOLICY */
+		if (!vdev_readable(vd)) {
+			zio->io_error = SET_ERROR(ENXIO);
+			zio_interrupt(zio);
+			return;
+		}
+
+		switch (zio->io_cmd) {
+		case DKIOCFLUSHWRITECACHE:
+
+			if (zfs_nocacheflush)
+				break;
+
+			/*
+			 * We cannot safely call vfs_fsync() when PF_FSTRANS
+			 * is set in the current context.  Filesystems like
+			 * XFS include sanity checks to verify it is not
+			 * already set, see xfs_vm_writepage().  Therefore
+			 * the sync must be dispatched to a different context.
+			 */
+			if (spl_fstrans_check()) {
+				VERIFY3U(taskq_dispatch(system_taskq,
+				    vdev_file_io_fsync, zio, TQ_SLEEP), !=, 0);
+				return;
+			}
+
+			zio->io_error = VOP_FSYNC(vf->vf_vnode, FSYNC | FDSYNC,
+			    kcred, NULL);
+			break;
+		default:
+			zio->io_error = SET_ERROR(ENOTSUP);
+		}
+
+		zio_execute(zio);
+		return;
+	}
+
+	VERIFY3U(taskq_dispatch(system_taskq, vdev_file_io_strategy, zio,
+	    TQ_SLEEP), !=, 0);
+}
+
+/* ARGSUSED */
+static void
+vdev_file_io_done(zio_t *zio)
+{
+}
+
+vdev_ops_t vdev_file_ops = {
+	vdev_file_open,
+	vdev_file_close,
+	vdev_default_asize,
+	vdev_file_io_start,
+	vdev_file_io_done,
+	NULL,
+	vdev_file_hold,
+	vdev_file_rele,
+	VDEV_TYPE_FILE,		/* name of this vdev type */
+	B_TRUE			/* leaf vdev */
+};
+
+/*
+ * From userland we access disks just like files.
+ */
+#ifndef _KERNEL
+
+vdev_ops_t vdev_disk_ops = {
+	vdev_file_open,
+	vdev_file_close,
+	vdev_default_asize,
+	vdev_file_io_start,
+	vdev_file_io_done,
+	NULL,
+	vdev_file_hold,
+	vdev_file_rele,
+	VDEV_TYPE_DISK,		/* name of this vdev type */
+	B_TRUE			/* leaf vdev */
+};
+
+#endif
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/module/zfs/vdev_label.c
@@ -0,0 +1,1282 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013 by Delphix. All rights reserved.
+ */
+
+/*
+ * Virtual Device Labels
+ * ---------------------
+ *
+ * The vdev label serves several distinct purposes:
+ *
+ *	1. Uniquely identify this device as part of a ZFS pool and confirm its
+ *	   identity within the pool.
+ *
+ * 	2. Verify that all the devices given in a configuration are present
+ *         within the pool.
+ *
+ * 	3. Determine the uberblock for the pool.
+ *
+ * 	4. In case of an import operation, determine the configuration of the
+ *         toplevel vdev of which it is a part.
+ *
+ * 	5. If an import operation cannot find all the devices in the pool,
+ *         provide enough information to the administrator to determine which
+ *         devices are missing.
+ *
+ * It is important to note that while the kernel is responsible for writing the
+ * label, it only consumes the information in the first three cases.  The
+ * latter information is only consumed in userland when determining the
+ * configuration to import a pool.
+ *
+ *
+ * Label Organization
+ * ------------------
+ *
+ * Before describing the contents of the label, it's important to understand how
+ * the labels are written and updated with respect to the uberblock.
+ *
+ * When the pool configuration is altered, either because it was newly created
+ * or a device was added, we want to update all the labels such that we can deal
+ * with fatal failure at any point.  To this end, each disk has two labels which
+ * are updated before and after the uberblock is synced.  Assuming we have
+ * labels and an uberblock with the following transaction groups:
+ *
+ *              L1          UB          L2
+ *           +------+    +------+    +------+
+ *           |      |    |      |    |      |
+ *           | t10  |    | t10  |    | t10  |
+ *           |      |    |      |    |      |
+ *           +------+    +------+    +------+
+ *
+ * In this stable state, the labels and the uberblock were all updated within
+ * the same transaction group (10).  Each label is mirrored and checksummed, so
+ * that we can detect when we fail partway through writing the label.
+ *
+ * In order to identify which labels are valid, the labels are written in the
+ * following manner:
+ *
+ * 	1. For each vdev, update 'L1' to the new label
+ * 	2. Update the uberblock
+ * 	3. For each vdev, update 'L2' to the new label
+ *
+ * Given arbitrary failure, we can determine the correct label to use based on
+ * the transaction group.  If we fail after updating L1 but before updating the
+ * UB, we will notice that L1's transaction group is greater than the uberblock,
+ * so L2 must be valid.  If we fail after writing the uberblock but before
+ * writing L2, we will notice that L2's transaction group is less than L1, and
+ * therefore L1 is valid.
+ *
+ * Another added complexity is that not every label is updated when the config
+ * is synced.  If we add a single device, we do not want to have to re-write
+ * every label for every device in the pool.  This means that both L1 and L2 may
+ * be older than the pool uberblock, because the necessary information is stored
+ * on another vdev.
+ *
+ *
+ * On-disk Format
+ * --------------
+ *
+ * The vdev label consists of two distinct parts, and is wrapped within the
+ * vdev_label_t structure.  The label includes 8k of padding to permit legacy
+ * VTOC disk labels, but is otherwise ignored.
+ *
+ * The first half of the label is a packed nvlist which contains pool wide
+ * properties, per-vdev properties, and configuration information.  It is
+ * described in more detail below.
+ *
+ * The latter half of the label consists of a redundant array of uberblocks.
+ * These uberblocks are updated whenever a transaction group is committed,
+ * or when the configuration is updated.  When a pool is loaded, we scan each
+ * vdev for the 'best' uberblock.
+ *
+ *
+ * Configuration Information
+ * -------------------------
+ *
+ * The nvlist describing the pool and vdev contains the following elements:
+ *
+ * 	version		ZFS on-disk version
+ * 	name		Pool name
+ * 	state		Pool state
+ * 	txg		Transaction group in which this label was written
+ * 	pool_guid	Unique identifier for this pool
+ * 	vdev_tree	An nvlist describing vdev tree.
+ *	features_for_read
+ *			An nvlist of the features necessary for reading the MOS.
+ *
+ * Each leaf device label also contains the following:
+ *
+ * 	top_guid	Unique ID for top-level vdev in which this is contained
+ * 	guid		Unique ID for the leaf vdev
+ *
+ * The 'vs' configuration follows the format described in 'spa_config.c'.
+ */
+
+#include <sys/zfs_context.h>
+#include <sys/spa.h>
+#include <sys/spa_impl.h>
+#include <sys/dmu.h>
+#include <sys/zap.h>
+#include <sys/vdev.h>
+#include <sys/vdev_impl.h>
+#include <sys/uberblock_impl.h>
+#include <sys/metaslab.h>
+#include <sys/zio.h>
+#include <sys/dsl_scan.h>
+#include <sys/fs/zfs.h>
+
+/*
+ * Basic routines to read and write from a vdev label.
+ * Used throughout the rest of this file.
+ */
+uint64_t
+vdev_label_offset(uint64_t psize, int l, uint64_t offset)
+{
+	ASSERT(offset < sizeof (vdev_label_t));
+	ASSERT(P2PHASE_TYPED(psize, sizeof (vdev_label_t), uint64_t) == 0);
+
+	return (offset + l * sizeof (vdev_label_t) + (l < VDEV_LABELS / 2 ?
+	    0 : psize - VDEV_LABELS * sizeof (vdev_label_t)));
+}
+
+/*
+ * Returns back the vdev label associated with the passed in offset.
+ */
+int
+vdev_label_number(uint64_t psize, uint64_t offset)
+{
+	int l;
+
+	if (offset >= psize - VDEV_LABEL_END_SIZE) {
+		offset -= psize - VDEV_LABEL_END_SIZE;
+		offset += (VDEV_LABELS / 2) * sizeof (vdev_label_t);
+	}
+	l = offset / sizeof (vdev_label_t);
+	return (l < VDEV_LABELS ? l : -1);
+}
+
+static void
+vdev_label_read(zio_t *zio, vdev_t *vd, int l, void *buf, uint64_t offset,
+	uint64_t size, zio_done_func_t *done, void *private, int flags)
+{
+	ASSERT(spa_config_held(zio->io_spa, SCL_STATE_ALL, RW_WRITER) ==
+	    SCL_STATE_ALL);
+	ASSERT(flags & ZIO_FLAG_CONFIG_WRITER);
+
+	zio_nowait(zio_read_phys(zio, vd,
+	    vdev_label_offset(vd->vdev_psize, l, offset),
+	    size, buf, ZIO_CHECKSUM_LABEL, done, private,
+	    ZIO_PRIORITY_SYNC_READ, flags, B_TRUE));
+}
+
+static void
+vdev_label_write(zio_t *zio, vdev_t *vd, int l, void *buf, uint64_t offset,
+	uint64_t size, zio_done_func_t *done, void *private, int flags)
+{
+	ASSERT(spa_config_held(zio->io_spa, SCL_ALL, RW_WRITER) == SCL_ALL ||
+	    (spa_config_held(zio->io_spa, SCL_CONFIG | SCL_STATE, RW_READER) ==
+	    (SCL_CONFIG | SCL_STATE) &&
+	    dsl_pool_sync_context(spa_get_dsl(zio->io_spa))));
+	ASSERT(flags & ZIO_FLAG_CONFIG_WRITER);
+
+	zio_nowait(zio_write_phys(zio, vd,
+	    vdev_label_offset(vd->vdev_psize, l, offset),
+	    size, buf, ZIO_CHECKSUM_LABEL, done, private,
+	    ZIO_PRIORITY_SYNC_WRITE, flags, B_TRUE));
+}
+
+/*
+ * Generate the nvlist representing this vdev's config.
+ */
+nvlist_t *
+vdev_config_generate(spa_t *spa, vdev_t *vd, boolean_t getstats,
+    vdev_config_flag_t flags)
+{
+	nvlist_t *nv = NULL;
+
+	nv = fnvlist_alloc();
+
+	fnvlist_add_string(nv, ZPOOL_CONFIG_TYPE, vd->vdev_ops->vdev_op_type);
+	if (!(flags & (VDEV_CONFIG_SPARE | VDEV_CONFIG_L2CACHE)))
+		fnvlist_add_uint64(nv, ZPOOL_CONFIG_ID, vd->vdev_id);
+	fnvlist_add_uint64(nv, ZPOOL_CONFIG_GUID, vd->vdev_guid);
+
+	if (vd->vdev_path != NULL)
+		fnvlist_add_string(nv, ZPOOL_CONFIG_PATH, vd->vdev_path);
+
+	if (vd->vdev_devid != NULL)
+		fnvlist_add_string(nv, ZPOOL_CONFIG_DEVID, vd->vdev_devid);
+
+	if (vd->vdev_physpath != NULL)
+		fnvlist_add_string(nv, ZPOOL_CONFIG_PHYS_PATH,
+		    vd->vdev_physpath);
+
+	if (vd->vdev_fru != NULL)
+		fnvlist_add_string(nv, ZPOOL_CONFIG_FRU, vd->vdev_fru);
+
+	if (vd->vdev_nparity != 0) {
+		ASSERT(strcmp(vd->vdev_ops->vdev_op_type,
+		    VDEV_TYPE_RAIDZ) == 0);
+
+		/*
+		 * Make sure someone hasn't managed to sneak a fancy new vdev
+		 * into a crufty old storage pool.
+		 */
+		ASSERT(vd->vdev_nparity == 1 ||
+		    (vd->vdev_nparity <= 2 &&
+		    spa_version(spa) >= SPA_VERSION_RAIDZ2) ||
+		    (vd->vdev_nparity <= 3 &&
+		    spa_version(spa) >= SPA_VERSION_RAIDZ3));
+
+		/*
+		 * Note that we'll add the nparity tag even on storage pools
+		 * that only support a single parity device -- older software
+		 * will just ignore it.
+		 */
+		fnvlist_add_uint64(nv, ZPOOL_CONFIG_NPARITY, vd->vdev_nparity);
+	}
+
+	if (vd->vdev_wholedisk != -1ULL)
+		fnvlist_add_uint64(nv, ZPOOL_CONFIG_WHOLE_DISK,
+		    vd->vdev_wholedisk);
+
+	if (vd->vdev_not_present)
+		fnvlist_add_uint64(nv, ZPOOL_CONFIG_NOT_PRESENT, 1);
+
+	if (vd->vdev_isspare)
+		fnvlist_add_uint64(nv, ZPOOL_CONFIG_IS_SPARE, 1);
+
+	if (!(flags & (VDEV_CONFIG_SPARE | VDEV_CONFIG_L2CACHE)) &&
+	    vd == vd->vdev_top) {
+		fnvlist_add_uint64(nv, ZPOOL_CONFIG_METASLAB_ARRAY,
+		    vd->vdev_ms_array);
+		fnvlist_add_uint64(nv, ZPOOL_CONFIG_METASLAB_SHIFT,
+		    vd->vdev_ms_shift);
+		fnvlist_add_uint64(nv, ZPOOL_CONFIG_ASHIFT, vd->vdev_ashift);
+		fnvlist_add_uint64(nv, ZPOOL_CONFIG_ASIZE,
+		    vd->vdev_asize);
+		fnvlist_add_uint64(nv, ZPOOL_CONFIG_IS_LOG, vd->vdev_islog);
+		if (vd->vdev_removing)
+			fnvlist_add_uint64(nv, ZPOOL_CONFIG_REMOVING,
+			    vd->vdev_removing);
+	}
+
+	if (vd->vdev_dtl_sm != NULL) {
+		fnvlist_add_uint64(nv, ZPOOL_CONFIG_DTL,
+		    space_map_object(vd->vdev_dtl_sm));
+	}
+
+	if (vd->vdev_crtxg)
+		fnvlist_add_uint64(nv, ZPOOL_CONFIG_CREATE_TXG, vd->vdev_crtxg);
+
+	if (getstats) {
+		vdev_stat_t vs;
+		pool_scan_stat_t ps;
+
+		vdev_get_stats(vd, &vs);
+		fnvlist_add_uint64_array(nv, ZPOOL_CONFIG_VDEV_STATS,
+		    (uint64_t *)&vs, sizeof (vs) / sizeof (uint64_t));
+
+		/* provide either current or previous scan information */
+		if (spa_scan_get_stats(spa, &ps) == 0) {
+			fnvlist_add_uint64_array(nv,
+			    ZPOOL_CONFIG_SCAN_STATS, (uint64_t *)&ps,
+			    sizeof (pool_scan_stat_t) / sizeof (uint64_t));
+		}
+	}
+
+	if (!vd->vdev_ops->vdev_op_leaf) {
+		nvlist_t **child;
+		int c, idx;
+
+		ASSERT(!vd->vdev_ishole);
+
+		child = kmem_alloc(vd->vdev_children * sizeof (nvlist_t *),
+		    KM_SLEEP);
+
+		for (c = 0, idx = 0; c < vd->vdev_children; c++) {
+			vdev_t *cvd = vd->vdev_child[c];
+
+			/*
+			 * If we're generating an nvlist of removing
+			 * vdevs then skip over any device which is
+			 * not being removed.
+			 */
+			if ((flags & VDEV_CONFIG_REMOVING) &&
+			    !cvd->vdev_removing)
+				continue;
+
+			child[idx++] = vdev_config_generate(spa, cvd,
+			    getstats, flags);
+		}
+
+		if (idx) {
+			fnvlist_add_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
+			    child, idx);
+		}
+
+		for (c = 0; c < idx; c++)
+			nvlist_free(child[c]);
+
+		kmem_free(child, vd->vdev_children * sizeof (nvlist_t *));
+
+	} else {
+		const char *aux = NULL;
+
+		if (vd->vdev_offline && !vd->vdev_tmpoffline)
+			fnvlist_add_uint64(nv, ZPOOL_CONFIG_OFFLINE, B_TRUE);
+		if (vd->vdev_resilver_txg != 0)
+			fnvlist_add_uint64(nv, ZPOOL_CONFIG_RESILVER_TXG,
+			    vd->vdev_resilver_txg);
+		if (vd->vdev_faulted)
+			fnvlist_add_uint64(nv, ZPOOL_CONFIG_FAULTED, B_TRUE);
+		if (vd->vdev_degraded)
+			fnvlist_add_uint64(nv, ZPOOL_CONFIG_DEGRADED, B_TRUE);
+		if (vd->vdev_removed)
+			fnvlist_add_uint64(nv, ZPOOL_CONFIG_REMOVED, B_TRUE);
+		if (vd->vdev_unspare)
+			fnvlist_add_uint64(nv, ZPOOL_CONFIG_UNSPARE, B_TRUE);
+		if (vd->vdev_ishole)
+			fnvlist_add_uint64(nv, ZPOOL_CONFIG_IS_HOLE, B_TRUE);
+
+		switch (vd->vdev_stat.vs_aux) {
+		case VDEV_AUX_ERR_EXCEEDED:
+			aux = "err_exceeded";
+			break;
+
+		case VDEV_AUX_EXTERNAL:
+			aux = "external";
+			break;
+		}
+
+		if (aux != NULL)
+			fnvlist_add_string(nv, ZPOOL_CONFIG_AUX_STATE, aux);
+
+		if (vd->vdev_splitting && vd->vdev_orig_guid != 0LL) {
+			fnvlist_add_uint64(nv, ZPOOL_CONFIG_ORIG_GUID,
+			    vd->vdev_orig_guid);
+		}
+	}
+
+	return (nv);
+}
+
+/*
+ * Generate a view of the top-level vdevs.  If we currently have holes
+ * in the namespace, then generate an array which contains a list of holey
+ * vdevs.  Additionally, add the number of top-level children that currently
+ * exist.
+ */
+void
+vdev_top_config_generate(spa_t *spa, nvlist_t *config)
+{
+	vdev_t *rvd = spa->spa_root_vdev;
+	uint64_t *array;
+	uint_t c, idx;
+
+	array = kmem_alloc(rvd->vdev_children * sizeof (uint64_t), KM_SLEEP);
+
+	for (c = 0, idx = 0; c < rvd->vdev_children; c++) {
+		vdev_t *tvd = rvd->vdev_child[c];
+
+		if (tvd->vdev_ishole)
+			array[idx++] = c;
+	}
+
+	if (idx) {
+		VERIFY(nvlist_add_uint64_array(config, ZPOOL_CONFIG_HOLE_ARRAY,
+		    array, idx) == 0);
+	}
+
+	VERIFY(nvlist_add_uint64(config, ZPOOL_CONFIG_VDEV_CHILDREN,
+	    rvd->vdev_children) == 0);
+
+	kmem_free(array, rvd->vdev_children * sizeof (uint64_t));
+}
+
+/*
+ * Returns the configuration from the label of the given vdev. For vdevs
+ * which don't have a txg value stored on their label (i.e. spares/cache)
+ * or have not been completely initialized (txg = 0) just return
+ * the configuration from the first valid label we find. Otherwise,
+ * find the most up-to-date label that does not exceed the specified
+ * 'txg' value.
+ */
+nvlist_t *
+vdev_label_read_config(vdev_t *vd, uint64_t txg)
+{
+	spa_t *spa = vd->vdev_spa;
+	nvlist_t *config = NULL;
+	vdev_phys_t *vp;
+	zio_t *zio;
+	uint64_t best_txg = 0;
+	int error = 0;
+	int flags = ZIO_FLAG_CONFIG_WRITER | ZIO_FLAG_CANFAIL |
+	    ZIO_FLAG_SPECULATIVE;
+	int l;
+
+	ASSERT(spa_config_held(spa, SCL_STATE_ALL, RW_WRITER) == SCL_STATE_ALL);
+
+	if (!vdev_readable(vd))
+		return (NULL);
+
+	vp = zio_buf_alloc(sizeof (vdev_phys_t));
+
+retry:
+	for (l = 0; l < VDEV_LABELS; l++) {
+		nvlist_t *label = NULL;
+
+		zio = zio_root(spa, NULL, NULL, flags);
+
+		vdev_label_read(zio, vd, l, vp,
+		    offsetof(vdev_label_t, vl_vdev_phys),
+		    sizeof (vdev_phys_t), NULL, NULL, flags);
+
+		if (zio_wait(zio) == 0 &&
+		    nvlist_unpack(vp->vp_nvlist, sizeof (vp->vp_nvlist),
+		    &label, 0) == 0) {
+			uint64_t label_txg = 0;
+
+			/*
+			 * Auxiliary vdevs won't have txg values in their
+			 * labels and newly added vdevs may not have been
+			 * completely initialized so just return the
+			 * configuration from the first valid label we
+			 * encounter.
+			 */
+			error = nvlist_lookup_uint64(label,
+			    ZPOOL_CONFIG_POOL_TXG, &label_txg);
+			if ((error || label_txg == 0) && !config) {
+				config = label;
+				break;
+			} else if (label_txg <= txg && label_txg > best_txg) {
+				best_txg = label_txg;
+				nvlist_free(config);
+				config = fnvlist_dup(label);
+			}
+		}
+
+		if (label != NULL) {
+			nvlist_free(label);
+			label = NULL;
+		}
+	}
+
+	if (config == NULL && !(flags & ZIO_FLAG_TRYHARD)) {
+		flags |= ZIO_FLAG_TRYHARD;
+		goto retry;
+	}
+
+	zio_buf_free(vp, sizeof (vdev_phys_t));
+
+	return (config);
+}
+
+/*
+ * Determine if a device is in use.  The 'spare_guid' parameter will be filled
+ * in with the device guid if this spare is active elsewhere on the system.
+ */
+static boolean_t
+vdev_inuse(vdev_t *vd, uint64_t crtxg, vdev_labeltype_t reason,
+    uint64_t *spare_guid, uint64_t *l2cache_guid)
+{
+	spa_t *spa = vd->vdev_spa;
+	uint64_t state, pool_guid, device_guid, txg, spare_pool;
+	uint64_t vdtxg = 0;
+	nvlist_t *label;
+
+	if (spare_guid)
+		*spare_guid = 0ULL;
+	if (l2cache_guid)
+		*l2cache_guid = 0ULL;
+
+	/*
+	 * Read the label, if any, and perform some basic sanity checks.
+	 */
+	if ((label = vdev_label_read_config(vd, -1ULL)) == NULL)
+		return (B_FALSE);
+
+	(void) nvlist_lookup_uint64(label, ZPOOL_CONFIG_CREATE_TXG,
+	    &vdtxg);
+
+	if (nvlist_lookup_uint64(label, ZPOOL_CONFIG_POOL_STATE,
+	    &state) != 0 ||
+	    nvlist_lookup_uint64(label, ZPOOL_CONFIG_GUID,
+	    &device_guid) != 0) {
+		nvlist_free(label);
+		return (B_FALSE);
+	}
+
+	if (state != POOL_STATE_SPARE && state != POOL_STATE_L2CACHE &&
+	    (nvlist_lookup_uint64(label, ZPOOL_CONFIG_POOL_GUID,
+	    &pool_guid) != 0 ||
+	    nvlist_lookup_uint64(label, ZPOOL_CONFIG_POOL_TXG,
+	    &txg) != 0)) {
+		nvlist_free(label);
+		return (B_FALSE);
+	}
+
+	nvlist_free(label);
+
+	/*
+	 * Check to see if this device indeed belongs to the pool it claims to
+	 * be a part of.  The only way this is allowed is if the device is a hot
+	 * spare (which we check for later on).
+	 */
+	if (state != POOL_STATE_SPARE && state != POOL_STATE_L2CACHE &&
+	    !spa_guid_exists(pool_guid, device_guid) &&
+	    !spa_spare_exists(device_guid, NULL, NULL) &&
+	    !spa_l2cache_exists(device_guid, NULL))
+		return (B_FALSE);
+
+	/*
+	 * If the transaction group is zero, then this an initialized (but
+	 * unused) label.  This is only an error if the create transaction
+	 * on-disk is the same as the one we're using now, in which case the
+	 * user has attempted to add the same vdev multiple times in the same
+	 * transaction.
+	 */
+	if (state != POOL_STATE_SPARE && state != POOL_STATE_L2CACHE &&
+	    txg == 0 && vdtxg == crtxg)
+		return (B_TRUE);
+
+	/*
+	 * Check to see if this is a spare device.  We do an explicit check for
+	 * spa_has_spare() here because it may be on our pending list of spares
+	 * to add.  We also check if it is an l2cache device.
+	 */
+	if (spa_spare_exists(device_guid, &spare_pool, NULL) ||
+	    spa_has_spare(spa, device_guid)) {
+		if (spare_guid)
+			*spare_guid = device_guid;
+
+		switch (reason) {
+		case VDEV_LABEL_CREATE:
+		case VDEV_LABEL_L2CACHE:
+			return (B_TRUE);
+
+		case VDEV_LABEL_REPLACE:
+			return (!spa_has_spare(spa, device_guid) ||
+			    spare_pool != 0ULL);
+
+		case VDEV_LABEL_SPARE:
+			return (spa_has_spare(spa, device_guid));
+		default:
+			break;
+		}
+	}
+
+	/*
+	 * Check to see if this is an l2cache device.
+	 */
+	if (spa_l2cache_exists(device_guid, NULL))
+		return (B_TRUE);
+
+	/*
+	 * We can't rely on a pool's state if it's been imported
+	 * read-only.  Instead we look to see if the pools is marked
+	 * read-only in the namespace and set the state to active.
+	 */
+	if (state != POOL_STATE_SPARE && state != POOL_STATE_L2CACHE &&
+	    (spa = spa_by_guid(pool_guid, device_guid)) != NULL &&
+	    spa_mode(spa) == FREAD)
+		state = POOL_STATE_ACTIVE;
+
+	/*
+	 * If the device is marked ACTIVE, then this device is in use by another
+	 * pool on the system.
+	 */
+	return (state == POOL_STATE_ACTIVE);
+}
+
+/*
+ * Initialize a vdev label.  We check to make sure each leaf device is not in
+ * use, and writable.  We put down an initial label which we will later
+ * overwrite with a complete label.  Note that it's important to do this
+ * sequentially, not in parallel, so that we catch cases of multiple use of the
+ * same leaf vdev in the vdev we're creating -- e.g. mirroring a disk with
+ * itself.
+ */
+int
+vdev_label_init(vdev_t *vd, uint64_t crtxg, vdev_labeltype_t reason)
+{
+	spa_t *spa = vd->vdev_spa;
+	nvlist_t *label;
+	vdev_phys_t *vp;
+	char *pad2;
+	uberblock_t *ub;
+	zio_t *zio;
+	char *buf;
+	size_t buflen;
+	int error;
+	uint64_t spare_guid = 0, l2cache_guid = 0;
+	int flags = ZIO_FLAG_CONFIG_WRITER | ZIO_FLAG_CANFAIL;
+	int c, l;
+	vdev_t *pvd;
+
+	ASSERT(spa_config_held(spa, SCL_ALL, RW_WRITER) == SCL_ALL);
+
+	for (c = 0; c < vd->vdev_children; c++)
+		if ((error = vdev_label_init(vd->vdev_child[c],
+		    crtxg, reason)) != 0)
+			return (error);
+
+	/* Track the creation time for this vdev */
+	vd->vdev_crtxg = crtxg;
+
+	if (!vd->vdev_ops->vdev_op_leaf || !spa_writeable(spa))
+		return (0);
+
+	/*
+	 * Dead vdevs cannot be initialized.
+	 */
+	if (vdev_is_dead(vd))
+		return (SET_ERROR(EIO));
+
+	/*
+	 * Determine if the vdev is in use.
+	 */
+	if (reason != VDEV_LABEL_REMOVE && reason != VDEV_LABEL_SPLIT &&
+	    vdev_inuse(vd, crtxg, reason, &spare_guid, &l2cache_guid))
+		return (SET_ERROR(EBUSY));
+
+	/*
+	 * If this is a request to add or replace a spare or l2cache device
+	 * that is in use elsewhere on the system, then we must update the
+	 * guid (which was initialized to a random value) to reflect the
+	 * actual GUID (which is shared between multiple pools).
+	 */
+	if (reason != VDEV_LABEL_REMOVE && reason != VDEV_LABEL_L2CACHE &&
+	    spare_guid != 0ULL) {
+		uint64_t guid_delta = spare_guid - vd->vdev_guid;
+
+		vd->vdev_guid += guid_delta;
+
+		for (pvd = vd; pvd != NULL; pvd = pvd->vdev_parent)
+			pvd->vdev_guid_sum += guid_delta;
+
+		/*
+		 * If this is a replacement, then we want to fallthrough to the
+		 * rest of the code.  If we're adding a spare, then it's already
+		 * labeled appropriately and we can just return.
+		 */
+		if (reason == VDEV_LABEL_SPARE)
+			return (0);
+		ASSERT(reason == VDEV_LABEL_REPLACE ||
+		    reason == VDEV_LABEL_SPLIT);
+	}
+
+	if (reason != VDEV_LABEL_REMOVE && reason != VDEV_LABEL_SPARE &&
+	    l2cache_guid != 0ULL) {
+		uint64_t guid_delta = l2cache_guid - vd->vdev_guid;
+
+		vd->vdev_guid += guid_delta;
+
+		for (pvd = vd; pvd != NULL; pvd = pvd->vdev_parent)
+			pvd->vdev_guid_sum += guid_delta;
+
+		/*
+		 * If this is a replacement, then we want to fallthrough to the
+		 * rest of the code.  If we're adding an l2cache, then it's
+		 * already labeled appropriately and we can just return.
+		 */
+		if (reason == VDEV_LABEL_L2CACHE)
+			return (0);
+		ASSERT(reason == VDEV_LABEL_REPLACE);
+	}
+
+	/*
+	 * Initialize its label.
+	 */
+	vp = zio_buf_alloc(sizeof (vdev_phys_t));
+	bzero(vp, sizeof (vdev_phys_t));
+
+	/*
+	 * Generate a label describing the pool and our top-level vdev.
+	 * We mark it as being from txg 0 to indicate that it's not
+	 * really part of an active pool just yet.  The labels will
+	 * be written again with a meaningful txg by spa_sync().
+	 */
+	if (reason == VDEV_LABEL_SPARE ||
+	    (reason == VDEV_LABEL_REMOVE && vd->vdev_isspare)) {
+		/*
+		 * For inactive hot spares, we generate a special label that
+		 * identifies as a mutually shared hot spare.  We write the
+		 * label if we are adding a hot spare, or if we are removing an
+		 * active hot spare (in which case we want to revert the
+		 * labels).
+		 */
+		VERIFY(nvlist_alloc(&label, NV_UNIQUE_NAME, KM_SLEEP) == 0);
+
+		VERIFY(nvlist_add_uint64(label, ZPOOL_CONFIG_VERSION,
+		    spa_version(spa)) == 0);
+		VERIFY(nvlist_add_uint64(label, ZPOOL_CONFIG_POOL_STATE,
+		    POOL_STATE_SPARE) == 0);
+		VERIFY(nvlist_add_uint64(label, ZPOOL_CONFIG_GUID,
+		    vd->vdev_guid) == 0);
+	} else if (reason == VDEV_LABEL_L2CACHE ||
+	    (reason == VDEV_LABEL_REMOVE && vd->vdev_isl2cache)) {
+		/*
+		 * For level 2 ARC devices, add a special label.
+		 */
+		VERIFY(nvlist_alloc(&label, NV_UNIQUE_NAME, KM_SLEEP) == 0);
+
+		VERIFY(nvlist_add_uint64(label, ZPOOL_CONFIG_VERSION,
+		    spa_version(spa)) == 0);
+		VERIFY(nvlist_add_uint64(label, ZPOOL_CONFIG_POOL_STATE,
+		    POOL_STATE_L2CACHE) == 0);
+		VERIFY(nvlist_add_uint64(label, ZPOOL_CONFIG_GUID,
+		    vd->vdev_guid) == 0);
+	} else {
+		uint64_t txg = 0ULL;
+
+		if (reason == VDEV_LABEL_SPLIT)
+			txg = spa->spa_uberblock.ub_txg;
+		label = spa_config_generate(spa, vd, txg, B_FALSE);
+
+		/*
+		 * Add our creation time.  This allows us to detect multiple
+		 * vdev uses as described above, and automatically expires if we
+		 * fail.
+		 */
+		VERIFY(nvlist_add_uint64(label, ZPOOL_CONFIG_CREATE_TXG,
+		    crtxg) == 0);
+	}
+
+	buf = vp->vp_nvlist;
+	buflen = sizeof (vp->vp_nvlist);
+
+	error = nvlist_pack(label, &buf, &buflen, NV_ENCODE_XDR, KM_SLEEP);
+	if (error != 0) {
+		nvlist_free(label);
+		zio_buf_free(vp, sizeof (vdev_phys_t));
+		/* EFAULT means nvlist_pack ran out of room */
+		return (error == EFAULT ? ENAMETOOLONG : EINVAL);
+	}
+
+	/*
+	 * Initialize uberblock template.
+	 */
+	ub = zio_buf_alloc(VDEV_UBERBLOCK_RING);
+	bzero(ub, VDEV_UBERBLOCK_RING);
+	*ub = spa->spa_uberblock;
+	ub->ub_txg = 0;
+
+	/* Initialize the 2nd padding area. */
+	pad2 = zio_buf_alloc(VDEV_PAD_SIZE);
+	bzero(pad2, VDEV_PAD_SIZE);
+
+	/*
+	 * Write everything in parallel.
+	 */
+retry:
+	zio = zio_root(spa, NULL, NULL, flags);
+
+	for (l = 0; l < VDEV_LABELS; l++) {
+
+		vdev_label_write(zio, vd, l, vp,
+		    offsetof(vdev_label_t, vl_vdev_phys),
+		    sizeof (vdev_phys_t), NULL, NULL, flags);
+
+		/*
+		 * Skip the 1st padding area.
+		 * Zero out the 2nd padding area where it might have
+		 * left over data from previous filesystem format.
+		 */
+		vdev_label_write(zio, vd, l, pad2,
+		    offsetof(vdev_label_t, vl_pad2),
+		    VDEV_PAD_SIZE, NULL, NULL, flags);
+
+		vdev_label_write(zio, vd, l, ub,
+		    offsetof(vdev_label_t, vl_uberblock),
+		    VDEV_UBERBLOCK_RING, NULL, NULL, flags);
+	}
+
+	error = zio_wait(zio);
+
+	if (error != 0 && !(flags & ZIO_FLAG_TRYHARD)) {
+		flags |= ZIO_FLAG_TRYHARD;
+		goto retry;
+	}
+
+	nvlist_free(label);
+	zio_buf_free(pad2, VDEV_PAD_SIZE);
+	zio_buf_free(ub, VDEV_UBERBLOCK_RING);
+	zio_buf_free(vp, sizeof (vdev_phys_t));
+
+	/*
+	 * If this vdev hasn't been previously identified as a spare, then we
+	 * mark it as such only if a) we are labeling it as a spare, or b) it
+	 * exists as a spare elsewhere in the system.  Do the same for
+	 * level 2 ARC devices.
+	 */
+	if (error == 0 && !vd->vdev_isspare &&
+	    (reason == VDEV_LABEL_SPARE ||
+	    spa_spare_exists(vd->vdev_guid, NULL, NULL)))
+		spa_spare_add(vd);
+
+	if (error == 0 && !vd->vdev_isl2cache &&
+	    (reason == VDEV_LABEL_L2CACHE ||
+	    spa_l2cache_exists(vd->vdev_guid, NULL)))
+		spa_l2cache_add(vd);
+
+	return (error);
+}
+
+/*
+ * ==========================================================================
+ * uberblock load/sync
+ * ==========================================================================
+ */
+
+/*
+ * Consider the following situation: txg is safely synced to disk.  We've
+ * written the first uberblock for txg + 1, and then we lose power.  When we
+ * come back up, we fail to see the uberblock for txg + 1 because, say,
+ * it was on a mirrored device and the replica to which we wrote txg + 1
+ * is now offline.  If we then make some changes and sync txg + 1, and then
+ * the missing replica comes back, then for a few seconds we'll have two
+ * conflicting uberblocks on disk with the same txg.  The solution is simple:
+ * among uberblocks with equal txg, choose the one with the latest timestamp.
+ */
+static int
+vdev_uberblock_compare(uberblock_t *ub1, uberblock_t *ub2)
+{
+	if (ub1->ub_txg < ub2->ub_txg)
+		return (-1);
+	if (ub1->ub_txg > ub2->ub_txg)
+		return (1);
+
+	if (ub1->ub_timestamp < ub2->ub_timestamp)
+		return (-1);
+	if (ub1->ub_timestamp > ub2->ub_timestamp)
+		return (1);
+
+	return (0);
+}
+
+struct ubl_cbdata {
+	uberblock_t	*ubl_ubbest;	/* Best uberblock */
+	vdev_t		*ubl_vd;	/* vdev associated with the above */
+};
+
+static void
+vdev_uberblock_load_done(zio_t *zio)
+{
+	vdev_t *vd = zio->io_vd;
+	spa_t *spa = zio->io_spa;
+	zio_t *rio = zio->io_private;
+	uberblock_t *ub = zio->io_data;
+	struct ubl_cbdata *cbp = rio->io_private;
+
+	ASSERT3U(zio->io_size, ==, VDEV_UBERBLOCK_SIZE(vd));
+
+	if (zio->io_error == 0 && uberblock_verify(ub) == 0) {
+		mutex_enter(&rio->io_lock);
+		if (ub->ub_txg <= spa->spa_load_max_txg &&
+		    vdev_uberblock_compare(ub, cbp->ubl_ubbest) > 0) {
+			/*
+			 * Keep track of the vdev in which this uberblock
+			 * was found. We will use this information later
+			 * to obtain the config nvlist associated with
+			 * this uberblock.
+			 */
+			*cbp->ubl_ubbest = *ub;
+			cbp->ubl_vd = vd;
+		}
+		mutex_exit(&rio->io_lock);
+	}
+
+	zio_buf_free(zio->io_data, zio->io_size);
+}
+
+static void
+vdev_uberblock_load_impl(zio_t *zio, vdev_t *vd, int flags,
+    struct ubl_cbdata *cbp)
+{
+	int c, l, n;
+
+	for (c = 0; c < vd->vdev_children; c++)
+		vdev_uberblock_load_impl(zio, vd->vdev_child[c], flags, cbp);
+
+	if (vd->vdev_ops->vdev_op_leaf && vdev_readable(vd)) {
+		for (l = 0; l < VDEV_LABELS; l++) {
+			for (n = 0; n < VDEV_UBERBLOCK_COUNT(vd); n++) {
+				vdev_label_read(zio, vd, l,
+				    zio_buf_alloc(VDEV_UBERBLOCK_SIZE(vd)),
+				    VDEV_UBERBLOCK_OFFSET(vd, n),
+				    VDEV_UBERBLOCK_SIZE(vd),
+				    vdev_uberblock_load_done, zio, flags);
+			}
+		}
+	}
+}
+
+/*
+ * Reads the 'best' uberblock from disk along with its associated
+ * configuration. First, we read the uberblock array of each label of each
+ * vdev, keeping track of the uberblock with the highest txg in each array.
+ * Then, we read the configuration from the same vdev as the best uberblock.
+ */
+void
+vdev_uberblock_load(vdev_t *rvd, uberblock_t *ub, nvlist_t **config)
+{
+	zio_t *zio;
+	spa_t *spa = rvd->vdev_spa;
+	struct ubl_cbdata cb;
+	int flags = ZIO_FLAG_CONFIG_WRITER | ZIO_FLAG_CANFAIL |
+	    ZIO_FLAG_SPECULATIVE | ZIO_FLAG_TRYHARD;
+
+	ASSERT(ub);
+	ASSERT(config);
+
+	bzero(ub, sizeof (uberblock_t));
+	*config = NULL;
+
+	cb.ubl_ubbest = ub;
+	cb.ubl_vd = NULL;
+
+	spa_config_enter(spa, SCL_ALL, FTAG, RW_WRITER);
+	zio = zio_root(spa, NULL, &cb, flags);
+	vdev_uberblock_load_impl(zio, rvd, flags, &cb);
+	(void) zio_wait(zio);
+
+	/*
+	 * It's possible that the best uberblock was discovered on a label
+	 * that has a configuration which was written in a future txg.
+	 * Search all labels on this vdev to find the configuration that
+	 * matches the txg for our uberblock.
+	 */
+	if (cb.ubl_vd != NULL)
+		*config = vdev_label_read_config(cb.ubl_vd, ub->ub_txg);
+	spa_config_exit(spa, SCL_ALL, FTAG);
+}
+
+/*
+ * On success, increment root zio's count of good writes.
+ * We only get credit for writes to known-visible vdevs; see spa_vdev_add().
+ */
+static void
+vdev_uberblock_sync_done(zio_t *zio)
+{
+	uint64_t *good_writes = zio->io_private;
+
+	if (zio->io_error == 0 && zio->io_vd->vdev_top->vdev_ms_array != 0)
+		atomic_add_64(good_writes, 1);
+}
+
+/*
+ * Write the uberblock to all labels of all leaves of the specified vdev.
+ */
+static void
+vdev_uberblock_sync(zio_t *zio, uberblock_t *ub, vdev_t *vd, int flags)
+{
+	uberblock_t *ubbuf;
+	int c, l, n;
+
+	for (c = 0; c < vd->vdev_children; c++)
+		vdev_uberblock_sync(zio, ub, vd->vdev_child[c], flags);
+
+	if (!vd->vdev_ops->vdev_op_leaf)
+		return;
+
+	if (!vdev_writeable(vd))
+		return;
+
+	n = ub->ub_txg & (VDEV_UBERBLOCK_COUNT(vd) - 1);
+
+	ubbuf = zio_buf_alloc(VDEV_UBERBLOCK_SIZE(vd));
+	bzero(ubbuf, VDEV_UBERBLOCK_SIZE(vd));
+	*ubbuf = *ub;
+
+	for (l = 0; l < VDEV_LABELS; l++)
+		vdev_label_write(zio, vd, l, ubbuf,
+		    VDEV_UBERBLOCK_OFFSET(vd, n), VDEV_UBERBLOCK_SIZE(vd),
+		    vdev_uberblock_sync_done, zio->io_private,
+		    flags | ZIO_FLAG_DONT_PROPAGATE);
+
+	zio_buf_free(ubbuf, VDEV_UBERBLOCK_SIZE(vd));
+}
+
+/* Sync the uberblocks to all vdevs in svd[] */
+int
+vdev_uberblock_sync_list(vdev_t **svd, int svdcount, uberblock_t *ub, int flags)
+{
+	spa_t *spa = svd[0]->vdev_spa;
+	zio_t *zio;
+	uint64_t good_writes = 0;
+	int v;
+
+	zio = zio_root(spa, NULL, &good_writes, flags);
+
+	for (v = 0; v < svdcount; v++)
+		vdev_uberblock_sync(zio, ub, svd[v], flags);
+
+	(void) zio_wait(zio);
+
+	/*
+	 * Flush the uberblocks to disk.  This ensures that the odd labels
+	 * are no longer needed (because the new uberblocks and the even
+	 * labels are safely on disk), so it is safe to overwrite them.
+	 */
+	zio = zio_root(spa, NULL, NULL, flags);
+
+	for (v = 0; v < svdcount; v++)
+		zio_flush(zio, svd[v]);
+
+	(void) zio_wait(zio);
+
+	return (good_writes >= 1 ? 0 : EIO);
+}
+
+/*
+ * On success, increment the count of good writes for our top-level vdev.
+ */
+static void
+vdev_label_sync_done(zio_t *zio)
+{
+	uint64_t *good_writes = zio->io_private;
+
+	if (zio->io_error == 0)
+		atomic_add_64(good_writes, 1);
+}
+
+/*
+ * If there weren't enough good writes, indicate failure to the parent.
+ */
+static void
+vdev_label_sync_top_done(zio_t *zio)
+{
+	uint64_t *good_writes = zio->io_private;
+
+	if (*good_writes == 0)
+		zio->io_error = SET_ERROR(EIO);
+
+	kmem_free(good_writes, sizeof (uint64_t));
+}
+
+/*
+ * We ignore errors for log and cache devices, simply free the private data.
+ */
+static void
+vdev_label_sync_ignore_done(zio_t *zio)
+{
+	kmem_free(zio->io_private, sizeof (uint64_t));
+}
+
+/*
+ * Write all even or odd labels to all leaves of the specified vdev.
+ */
+static void
+vdev_label_sync(zio_t *zio, vdev_t *vd, int l, uint64_t txg, int flags)
+{
+	nvlist_t *label;
+	vdev_phys_t *vp;
+	char *buf;
+	size_t buflen;
+	int c;
+
+	for (c = 0; c < vd->vdev_children; c++)
+		vdev_label_sync(zio, vd->vdev_child[c], l, txg, flags);
+
+	if (!vd->vdev_ops->vdev_op_leaf)
+		return;
+
+	if (!vdev_writeable(vd))
+		return;
+
+	/*
+	 * Generate a label describing the top-level config to which we belong.
+	 */
+	label = spa_config_generate(vd->vdev_spa, vd, txg, B_FALSE);
+
+	vp = zio_buf_alloc(sizeof (vdev_phys_t));
+	bzero(vp, sizeof (vdev_phys_t));
+
+	buf = vp->vp_nvlist;
+	buflen = sizeof (vp->vp_nvlist);
+
+	if (!nvlist_pack(label, &buf, &buflen, NV_ENCODE_XDR, KM_SLEEP)) {
+		for (; l < VDEV_LABELS; l += 2) {
+			vdev_label_write(zio, vd, l, vp,
+			    offsetof(vdev_label_t, vl_vdev_phys),
+			    sizeof (vdev_phys_t),
+			    vdev_label_sync_done, zio->io_private,
+			    flags | ZIO_FLAG_DONT_PROPAGATE);
+		}
+	}
+
+	zio_buf_free(vp, sizeof (vdev_phys_t));
+	nvlist_free(label);
+}
+
+int
+vdev_label_sync_list(spa_t *spa, int l, uint64_t txg, int flags)
+{
+	list_t *dl = &spa->spa_config_dirty_list;
+	vdev_t *vd;
+	zio_t *zio;
+	int error;
+
+	/*
+	 * Write the new labels to disk.
+	 */
+	zio = zio_root(spa, NULL, NULL, flags);
+
+	for (vd = list_head(dl); vd != NULL; vd = list_next(dl, vd)) {
+		uint64_t *good_writes;
+		zio_t *vio;
+
+		ASSERT(!vd->vdev_ishole);
+
+		good_writes = kmem_zalloc(sizeof (uint64_t), KM_SLEEP);
+		vio = zio_null(zio, spa, NULL,
+		    (vd->vdev_islog || vd->vdev_aux != NULL) ?
+		    vdev_label_sync_ignore_done : vdev_label_sync_top_done,
+		    good_writes, flags);
+		vdev_label_sync(vio, vd, l, txg, flags);
+		zio_nowait(vio);
+	}
+
+	error = zio_wait(zio);
+
+	/*
+	 * Flush the new labels to disk.
+	 */
+	zio = zio_root(spa, NULL, NULL, flags);
+
+	for (vd = list_head(dl); vd != NULL; vd = list_next(dl, vd))
+		zio_flush(zio, vd);
+
+	(void) zio_wait(zio);
+
+	return (error);
+}
+
+/*
+ * Sync the uberblock and any changes to the vdev configuration.
+ *
+ * The order of operations is carefully crafted to ensure that
+ * if the system panics or loses power at any time, the state on disk
+ * is still transactionally consistent.  The in-line comments below
+ * describe the failure semantics at each stage.
+ *
+ * Moreover, vdev_config_sync() is designed to be idempotent: if it fails
+ * at any time, you can just call it again, and it will resume its work.
+ */
+int
+vdev_config_sync(vdev_t **svd, int svdcount, uint64_t txg, boolean_t tryhard)
+{
+	spa_t *spa = svd[0]->vdev_spa;
+	uberblock_t *ub = &spa->spa_uberblock;
+	vdev_t *vd;
+	zio_t *zio;
+	int error;
+	int flags = ZIO_FLAG_CONFIG_WRITER | ZIO_FLAG_CANFAIL;
+
+	/*
+	 * Normally, we don't want to try too hard to write every label and
+	 * uberblock.  If there is a flaky disk, we don't want the rest of the
+	 * sync process to block while we retry.  But if we can't write a
+	 * single label out, we should retry with ZIO_FLAG_TRYHARD before
+	 * bailing out and declaring the pool faulted.
+	 */
+	if (tryhard)
+		flags |= ZIO_FLAG_TRYHARD;
+
+	ASSERT(ub->ub_txg <= txg);
+
+	/*
+	 * If this isn't a resync due to I/O errors,
+	 * and nothing changed in this transaction group,
+	 * and the vdev configuration hasn't changed,
+	 * then there's nothing to do.
+	 */
+	if (ub->ub_txg < txg &&
+	    uberblock_update(ub, spa->spa_root_vdev, txg) == B_FALSE &&
+	    list_is_empty(&spa->spa_config_dirty_list))
+		return (0);
+
+	if (txg > spa_freeze_txg(spa))
+		return (0);
+
+	ASSERT(txg <= spa->spa_final_txg);
+
+	/*
+	 * Flush the write cache of every disk that's been written to
+	 * in this transaction group.  This ensures that all blocks
+	 * written in this txg will be committed to stable storage
+	 * before any uberblock that references them.
+	 */
+	zio = zio_root(spa, NULL, NULL, flags);
+
+	for (vd = txg_list_head(&spa->spa_vdev_txg_list, TXG_CLEAN(txg)); vd;
+	    vd = txg_list_next(&spa->spa_vdev_txg_list, vd, TXG_CLEAN(txg)))
+		zio_flush(zio, vd);
+
+	(void) zio_wait(zio);
+
+	/*
+	 * Sync out the even labels (L0, L2) for every dirty vdev.  If the
+	 * system dies in the middle of this process, that's OK: all of the
+	 * even labels that made it to disk will be newer than any uberblock,
+	 * and will therefore be considered invalid.  The odd labels (L1, L3),
+	 * which have not yet been touched, will still be valid.  We flush
+	 * the new labels to disk to ensure that all even-label updates
+	 * are committed to stable storage before the uberblock update.
+	 */
+	if ((error = vdev_label_sync_list(spa, 0, txg, flags)) != 0)
+		return (error);
+
+	/*
+	 * Sync the uberblocks to all vdevs in svd[].
+	 * If the system dies in the middle of this step, there are two cases
+	 * to consider, and the on-disk state is consistent either way:
+	 *
+	 * (1)	If none of the new uberblocks made it to disk, then the
+	 *	previous uberblock will be the newest, and the odd labels
+	 *	(which had not yet been touched) will be valid with respect
+	 *	to that uberblock.
+	 *
+	 * (2)	If one or more new uberblocks made it to disk, then they
+	 *	will be the newest, and the even labels (which had all
+	 *	been successfully committed) will be valid with respect
+	 *	to the new uberblocks.
+	 */
+	if ((error = vdev_uberblock_sync_list(svd, svdcount, ub, flags)) != 0)
+		return (error);
+
+	/*
+	 * Sync out odd labels for every dirty vdev.  If the system dies
+	 * in the middle of this process, the even labels and the new
+	 * uberblocks will suffice to open the pool.  The next time
+	 * the pool is opened, the first thing we'll do -- before any
+	 * user data is modified -- is mark every vdev dirty so that
+	 * all labels will be brought up to date.  We flush the new labels
+	 * to disk to ensure that all odd-label updates are committed to
+	 * stable storage before the next transaction group begins.
+	 */
+	return (vdev_label_sync_list(spa, 1, txg, flags));
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/module/zfs/vdev_mirror.c
@@ -0,0 +1,564 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/*
+ * Copyright (c) 2012, 2014 by Delphix. All rights reserved.
+ */
+
+#include <sys/zfs_context.h>
+#include <sys/spa.h>
+#include <sys/vdev_impl.h>
+#include <sys/zio.h>
+#include <sys/fs/zfs.h>
+
+/*
+ * Virtual device vector for mirroring.
+ */
+
+typedef struct mirror_child {
+	vdev_t		*mc_vd;
+	uint64_t	mc_offset;
+	int		mc_error;
+	int		mc_pending;
+	uint8_t		mc_tried;
+	uint8_t		mc_skipped;
+	uint8_t		mc_speculative;
+} mirror_child_t;
+
+typedef struct mirror_map {
+	int		mm_children;
+	int		mm_replacing;
+	int		mm_preferred;
+	int		mm_root;
+	mirror_child_t	mm_child[1];
+} mirror_map_t;
+
+/*
+ * When the children are equally busy queue incoming requests to a single
+ * child for N microseconds.  This is done to maximize the likelihood that
+ * the Linux elevator will be able to merge requests while it is plugged.
+ * Otherwise, requests are queued to the least busy device.
+ *
+ * For rotational disks the Linux elevator will plug for 10ms which is
+ * why zfs_vdev_mirror_switch_us is set to 10ms by default.  For non-
+ * rotational disks the elevator will not plug, but 10ms is still a small
+ * enough value that the requests will get spread over all the children.
+ *
+ * For fast SSDs it may make sense to decrease zfs_vdev_mirror_switch_us
+ * significantly to bound the worst case latencies.  It would probably be
+ * ideal to calculate a decaying average of the last observed latencies and
+ * use that to dynamically adjust the zfs_vdev_mirror_switch_us time.
+ */
+int zfs_vdev_mirror_switch_us = 10000;
+
+static void
+vdev_mirror_map_free(zio_t *zio)
+{
+	mirror_map_t *mm = zio->io_vsd;
+
+	kmem_free(mm, offsetof(mirror_map_t, mm_child[mm->mm_children]));
+}
+
+static const zio_vsd_ops_t vdev_mirror_vsd_ops = {
+	vdev_mirror_map_free,
+	zio_vsd_default_cksum_report
+};
+
+static int
+vdev_mirror_pending(vdev_t *vd)
+{
+	return (avl_numnodes(&vd->vdev_queue.vq_active_tree));
+}
+
+/*
+ * Avoid inlining the function to keep vdev_mirror_io_start(), which
+ * is this functions only caller, as small as possible on the stack.
+ */
+noinline static mirror_map_t *
+vdev_mirror_map_alloc(zio_t *zio)
+{
+	mirror_map_t *mm = NULL;
+	mirror_child_t *mc;
+	vdev_t *vd = zio->io_vd;
+	int c, d;
+
+	if (vd == NULL) {
+		dva_t *dva = zio->io_bp->blk_dva;
+		spa_t *spa = zio->io_spa;
+
+		c = BP_GET_NDVAS(zio->io_bp);
+
+		mm = kmem_zalloc(offsetof(mirror_map_t, mm_child[c]),
+		    KM_SLEEP);
+		mm->mm_children = c;
+		mm->mm_replacing = B_FALSE;
+		mm->mm_preferred = spa_get_random(c);
+		mm->mm_root = B_TRUE;
+
+		/*
+		 * Check the other, lower-index DVAs to see if they're on
+		 * the same vdev as the child we picked.  If they are, use
+		 * them since they are likely to have been allocated from
+		 * the primary metaslab in use at the time, and hence are
+		 * more likely to have locality with single-copy data.
+		 */
+		for (c = mm->mm_preferred, d = c - 1; d >= 0; d--) {
+			if (DVA_GET_VDEV(&dva[d]) == DVA_GET_VDEV(&dva[c]))
+				mm->mm_preferred = d;
+		}
+
+		for (c = 0; c < mm->mm_children; c++) {
+			mc = &mm->mm_child[c];
+
+			mc->mc_vd = vdev_lookup_top(spa, DVA_GET_VDEV(&dva[c]));
+			mc->mc_offset = DVA_GET_OFFSET(&dva[c]);
+		}
+	} else {
+		int lowest_pending = INT_MAX;
+		int lowest_nr = 1;
+
+		c = vd->vdev_children;
+
+		mm = kmem_zalloc(offsetof(mirror_map_t, mm_child[c]),
+		    KM_SLEEP);
+		mm->mm_children = c;
+		mm->mm_replacing = (vd->vdev_ops == &vdev_replacing_ops ||
+		    vd->vdev_ops == &vdev_spare_ops);
+		mm->mm_preferred = 0;
+		mm->mm_root = B_FALSE;
+
+		for (c = 0; c < mm->mm_children; c++) {
+			mc = &mm->mm_child[c];
+			mc->mc_vd = vd->vdev_child[c];
+			mc->mc_offset = zio->io_offset;
+
+			if (mm->mm_replacing)
+				continue;
+
+			if (!vdev_readable(mc->mc_vd)) {
+				mc->mc_error = SET_ERROR(ENXIO);
+				mc->mc_tried = 1;
+				mc->mc_skipped = 1;
+				mc->mc_pending = INT_MAX;
+				continue;
+			}
+
+			mc->mc_pending = vdev_mirror_pending(mc->mc_vd);
+			if (mc->mc_pending < lowest_pending) {
+				lowest_pending = mc->mc_pending;
+				lowest_nr = 1;
+			} else if (mc->mc_pending == lowest_pending) {
+				lowest_nr++;
+			}
+		}
+
+		d = gethrtime() / (NSEC_PER_USEC * zfs_vdev_mirror_switch_us);
+		d = (d % lowest_nr) + 1;
+
+		for (c = 0; c < mm->mm_children; c++) {
+			mc = &mm->mm_child[c];
+
+			if (mm->mm_child[c].mc_pending == lowest_pending) {
+				if (--d == 0) {
+					mm->mm_preferred = c;
+					break;
+				}
+			}
+		}
+	}
+
+	zio->io_vsd = mm;
+	zio->io_vsd_ops = &vdev_mirror_vsd_ops;
+	return (mm);
+}
+
+static int
+vdev_mirror_open(vdev_t *vd, uint64_t *asize, uint64_t *max_asize,
+    uint64_t *ashift)
+{
+	int numerrors = 0;
+	int lasterror = 0;
+	int c;
+
+	if (vd->vdev_children == 0) {
+		vd->vdev_stat.vs_aux = VDEV_AUX_BAD_LABEL;
+		return (SET_ERROR(EINVAL));
+	}
+
+	vdev_open_children(vd);
+
+	for (c = 0; c < vd->vdev_children; c++) {
+		vdev_t *cvd = vd->vdev_child[c];
+
+		if (cvd->vdev_open_error) {
+			lasterror = cvd->vdev_open_error;
+			numerrors++;
+			continue;
+		}
+
+		*asize = MIN(*asize - 1, cvd->vdev_asize - 1) + 1;
+		*max_asize = MIN(*max_asize - 1, cvd->vdev_max_asize - 1) + 1;
+		*ashift = MAX(*ashift, cvd->vdev_ashift);
+	}
+
+	if (numerrors == vd->vdev_children) {
+		vd->vdev_stat.vs_aux = VDEV_AUX_NO_REPLICAS;
+		return (lasterror);
+	}
+
+	return (0);
+}
+
+static void
+vdev_mirror_close(vdev_t *vd)
+{
+	int c;
+
+	for (c = 0; c < vd->vdev_children; c++)
+		vdev_close(vd->vdev_child[c]);
+}
+
+static void
+vdev_mirror_child_done(zio_t *zio)
+{
+	mirror_child_t *mc = zio->io_private;
+
+	mc->mc_error = zio->io_error;
+	mc->mc_tried = 1;
+	mc->mc_skipped = 0;
+}
+
+static void
+vdev_mirror_scrub_done(zio_t *zio)
+{
+	mirror_child_t *mc = zio->io_private;
+
+	if (zio->io_error == 0) {
+		zio_t *pio;
+
+		mutex_enter(&zio->io_lock);
+		while ((pio = zio_walk_parents(zio)) != NULL) {
+			mutex_enter(&pio->io_lock);
+			ASSERT3U(zio->io_size, >=, pio->io_size);
+			bcopy(zio->io_data, pio->io_data, pio->io_size);
+			mutex_exit(&pio->io_lock);
+		}
+		mutex_exit(&zio->io_lock);
+	}
+
+	zio_buf_free(zio->io_data, zio->io_size);
+
+	mc->mc_error = zio->io_error;
+	mc->mc_tried = 1;
+	mc->mc_skipped = 0;
+}
+
+/*
+ * Try to find a child whose DTL doesn't contain the block we want to read.
+ * If we can't, try the read on any vdev we haven't already tried.
+ */
+static int
+vdev_mirror_child_select(zio_t *zio)
+{
+	mirror_map_t *mm = zio->io_vsd;
+	mirror_child_t *mc;
+	uint64_t txg = zio->io_txg;
+	int i, c;
+
+	ASSERT(zio->io_bp == NULL || BP_PHYSICAL_BIRTH(zio->io_bp) == txg);
+
+	/*
+	 * Try to find a child whose DTL doesn't contain the block to read.
+	 * If a child is known to be completely inaccessible (indicated by
+	 * vdev_readable() returning B_FALSE), don't even try.
+	 */
+	for (i = 0, c = mm->mm_preferred; i < mm->mm_children; i++, c++) {
+		if (c >= mm->mm_children)
+			c = 0;
+		mc = &mm->mm_child[c];
+		if (mc->mc_tried || mc->mc_skipped)
+			continue;
+		if (mc->mc_vd == NULL || !vdev_readable(mc->mc_vd)) {
+			mc->mc_error = SET_ERROR(ENXIO);
+			mc->mc_tried = 1;	/* don't even try */
+			mc->mc_skipped = 1;
+			continue;
+		}
+		if (!vdev_dtl_contains(mc->mc_vd, DTL_MISSING, txg, 1))
+			return (c);
+		mc->mc_error = SET_ERROR(ESTALE);
+		mc->mc_skipped = 1;
+		mc->mc_speculative = 1;
+	}
+
+	/*
+	 * Every device is either missing or has this txg in its DTL.
+	 * Look for any child we haven't already tried before giving up.
+	 */
+	for (c = 0; c < mm->mm_children; c++)
+		if (!mm->mm_child[c].mc_tried)
+			return (c);
+
+	/*
+	 * Every child failed.  There's no place left to look.
+	 */
+	return (-1);
+}
+
+static void
+vdev_mirror_io_start(zio_t *zio)
+{
+	mirror_map_t *mm;
+	mirror_child_t *mc;
+	int c, children;
+
+	mm = vdev_mirror_map_alloc(zio);
+
+	if (zio->io_type == ZIO_TYPE_READ) {
+		if ((zio->io_flags & ZIO_FLAG_SCRUB) && !mm->mm_replacing) {
+			/*
+			 * For scrubbing reads we need to allocate a read
+			 * buffer for each child and issue reads to all
+			 * children.  If any child succeeds, it will copy its
+			 * data into zio->io_data in vdev_mirror_scrub_done.
+			 */
+			for (c = 0; c < mm->mm_children; c++) {
+				mc = &mm->mm_child[c];
+				zio_nowait(zio_vdev_child_io(zio, zio->io_bp,
+				    mc->mc_vd, mc->mc_offset,
+				    zio_buf_alloc(zio->io_size), zio->io_size,
+				    zio->io_type, zio->io_priority, 0,
+				    vdev_mirror_scrub_done, mc));
+			}
+			zio_execute(zio);
+			return;
+		}
+		/*
+		 * For normal reads just pick one child.
+		 */
+		c = vdev_mirror_child_select(zio);
+		children = (c >= 0);
+	} else {
+		ASSERT(zio->io_type == ZIO_TYPE_WRITE);
+
+		/*
+		 * Writes go to all children.
+		 */
+		c = 0;
+		children = mm->mm_children;
+	}
+
+	while (children--) {
+		mc = &mm->mm_child[c];
+		zio_nowait(zio_vdev_child_io(zio, zio->io_bp,
+		    mc->mc_vd, mc->mc_offset, zio->io_data, zio->io_size,
+		    zio->io_type, zio->io_priority, 0,
+		    vdev_mirror_child_done, mc));
+		c++;
+	}
+
+	zio_execute(zio);
+}
+
+static int
+vdev_mirror_worst_error(mirror_map_t *mm)
+{
+	int c, error[2] = { 0, 0 };
+
+	for (c = 0; c < mm->mm_children; c++) {
+		mirror_child_t *mc = &mm->mm_child[c];
+		int s = mc->mc_speculative;
+		error[s] = zio_worst_error(error[s], mc->mc_error);
+	}
+
+	return (error[0] ? error[0] : error[1]);
+}
+
+static void
+vdev_mirror_io_done(zio_t *zio)
+{
+	mirror_map_t *mm = zio->io_vsd;
+	mirror_child_t *mc;
+	int c;
+	int good_copies = 0;
+	int unexpected_errors = 0;
+
+	for (c = 0; c < mm->mm_children; c++) {
+		mc = &mm->mm_child[c];
+
+		if (mc->mc_error) {
+			if (!mc->mc_skipped)
+				unexpected_errors++;
+		} else if (mc->mc_tried) {
+			good_copies++;
+		}
+	}
+
+	if (zio->io_type == ZIO_TYPE_WRITE) {
+		/*
+		 * XXX -- for now, treat partial writes as success.
+		 *
+		 * Now that we support write reallocation, it would be better
+		 * to treat partial failure as real failure unless there are
+		 * no non-degraded top-level vdevs left, and not update DTLs
+		 * if we intend to reallocate.
+		 */
+		/* XXPOLICY */
+		if (good_copies != mm->mm_children) {
+			/*
+			 * Always require at least one good copy.
+			 *
+			 * For ditto blocks (io_vd == NULL), require
+			 * all copies to be good.
+			 *
+			 * XXX -- for replacing vdevs, there's no great answer.
+			 * If the old device is really dead, we may not even
+			 * be able to access it -- so we only want to
+			 * require good writes to the new device.  But if
+			 * the new device turns out to be flaky, we want
+			 * to be able to detach it -- which requires all
+			 * writes to the old device to have succeeded.
+			 */
+			if (good_copies == 0 || zio->io_vd == NULL)
+				zio->io_error = vdev_mirror_worst_error(mm);
+		}
+		return;
+	}
+
+	ASSERT(zio->io_type == ZIO_TYPE_READ);
+
+	/*
+	 * If we don't have a good copy yet, keep trying other children.
+	 */
+	/* XXPOLICY */
+	if (good_copies == 0 && (c = vdev_mirror_child_select(zio)) != -1) {
+		ASSERT(c >= 0 && c < mm->mm_children);
+		mc = &mm->mm_child[c];
+		zio_vdev_io_redone(zio);
+		zio_nowait(zio_vdev_child_io(zio, zio->io_bp,
+		    mc->mc_vd, mc->mc_offset, zio->io_data, zio->io_size,
+		    ZIO_TYPE_READ, zio->io_priority, 0,
+		    vdev_mirror_child_done, mc));
+		return;
+	}
+
+	/* XXPOLICY */
+	if (good_copies == 0) {
+		zio->io_error = vdev_mirror_worst_error(mm);
+		ASSERT(zio->io_error != 0);
+	}
+
+	if (good_copies && spa_writeable(zio->io_spa) &&
+	    (unexpected_errors ||
+	    (zio->io_flags & ZIO_FLAG_RESILVER) ||
+	    ((zio->io_flags & ZIO_FLAG_SCRUB) && mm->mm_replacing))) {
+		/*
+		 * Use the good data we have in hand to repair damaged children.
+		 */
+		for (c = 0; c < mm->mm_children; c++) {
+			/*
+			 * Don't rewrite known good children.
+			 * Not only is it unnecessary, it could
+			 * actually be harmful: if the system lost
+			 * power while rewriting the only good copy,
+			 * there would be no good copies left!
+			 */
+			mc = &mm->mm_child[c];
+
+			if (mc->mc_error == 0) {
+				if (mc->mc_tried)
+					continue;
+				if (!(zio->io_flags & ZIO_FLAG_SCRUB) &&
+				    !vdev_dtl_contains(mc->mc_vd, DTL_PARTIAL,
+				    zio->io_txg, 1))
+					continue;
+				mc->mc_error = SET_ERROR(ESTALE);
+			}
+
+			zio_nowait(zio_vdev_child_io(zio, zio->io_bp,
+			    mc->mc_vd, mc->mc_offset,
+			    zio->io_data, zio->io_size,
+			    ZIO_TYPE_WRITE, ZIO_PRIORITY_ASYNC_WRITE,
+			    ZIO_FLAG_IO_REPAIR | (unexpected_errors ?
+			    ZIO_FLAG_SELF_HEAL : 0), NULL, NULL));
+		}
+	}
+}
+
+static void
+vdev_mirror_state_change(vdev_t *vd, int faulted, int degraded)
+{
+	if (faulted == vd->vdev_children)
+		vdev_set_state(vd, B_FALSE, VDEV_STATE_CANT_OPEN,
+		    VDEV_AUX_NO_REPLICAS);
+	else if (degraded + faulted != 0)
+		vdev_set_state(vd, B_FALSE, VDEV_STATE_DEGRADED, VDEV_AUX_NONE);
+	else
+		vdev_set_state(vd, B_FALSE, VDEV_STATE_HEALTHY, VDEV_AUX_NONE);
+}
+
+vdev_ops_t vdev_mirror_ops = {
+	vdev_mirror_open,
+	vdev_mirror_close,
+	vdev_default_asize,
+	vdev_mirror_io_start,
+	vdev_mirror_io_done,
+	vdev_mirror_state_change,
+	NULL,
+	NULL,
+	VDEV_TYPE_MIRROR,	/* name of this vdev type */
+	B_FALSE			/* not a leaf vdev */
+};
+
+vdev_ops_t vdev_replacing_ops = {
+	vdev_mirror_open,
+	vdev_mirror_close,
+	vdev_default_asize,
+	vdev_mirror_io_start,
+	vdev_mirror_io_done,
+	vdev_mirror_state_change,
+	NULL,
+	NULL,
+	VDEV_TYPE_REPLACING,	/* name of this vdev type */
+	B_FALSE			/* not a leaf vdev */
+};
+
+vdev_ops_t vdev_spare_ops = {
+	vdev_mirror_open,
+	vdev_mirror_close,
+	vdev_default_asize,
+	vdev_mirror_io_start,
+	vdev_mirror_io_done,
+	vdev_mirror_state_change,
+	NULL,
+	NULL,
+	VDEV_TYPE_SPARE,	/* name of this vdev type */
+	B_FALSE			/* not a leaf vdev */
+};
+
+#if defined(_KERNEL) && defined(HAVE_SPL)
+module_param(zfs_vdev_mirror_switch_us, int, 0644);
+MODULE_PARM_DESC(zfs_vdev_mirror_switch_us, "Switch mirrors every N usecs");
+#endif
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/module/zfs/vdev_missing.c
@@ -0,0 +1,106 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/*
+ * Copyright (c) 2012, 2014 by Delphix. All rights reserved.
+ */
+
+/*
+ * The 'missing' vdev is a special vdev type used only during import.  It
+ * signifies a placeholder in the root vdev for some vdev that we know is
+ * missing.  We pass it down to the kernel to allow the rest of the
+ * configuration to parsed and an attempt made to open all available devices.
+ * Because its GUID is always 0, we know that the guid sum will mismatch and we
+ * won't be able to open the pool anyway.
+ */
+
+#include <sys/zfs_context.h>
+#include <sys/spa.h>
+#include <sys/vdev_impl.h>
+#include <sys/fs/zfs.h>
+#include <sys/zio.h>
+
+/* ARGSUSED */
+static int
+vdev_missing_open(vdev_t *vd, uint64_t *psize, uint64_t *max_psize,
+    uint64_t *ashift)
+{
+	/*
+	 * Really this should just fail.  But then the root vdev will be in the
+	 * faulted state with VDEV_AUX_NO_REPLICAS, when what we really want is
+	 * VDEV_AUX_BAD_GUID_SUM.  So we pretend to succeed, knowing that we
+	 * will fail the GUID sum check before ever trying to open the pool.
+	 */
+	*psize = 0;
+	*max_psize = 0;
+	*ashift = 0;
+	return (0);
+}
+
+/* ARGSUSED */
+static void
+vdev_missing_close(vdev_t *vd)
+{
+}
+
+/* ARGSUSED */
+static void
+vdev_missing_io_start(zio_t *zio)
+{
+	zio->io_error = SET_ERROR(ENOTSUP);
+	zio_execute(zio);
+}
+
+/* ARGSUSED */
+static void
+vdev_missing_io_done(zio_t *zio)
+{
+}
+
+vdev_ops_t vdev_missing_ops = {
+	vdev_missing_open,
+	vdev_missing_close,
+	vdev_default_asize,
+	vdev_missing_io_start,
+	vdev_missing_io_done,
+	NULL,
+	NULL,
+	NULL,
+	VDEV_TYPE_MISSING,	/* name of this vdev type */
+	B_TRUE			/* leaf vdev */
+};
+
+vdev_ops_t vdev_hole_ops = {
+	vdev_missing_open,
+	vdev_missing_close,
+	vdev_default_asize,
+	vdev_missing_io_start,
+	vdev_missing_io_done,
+	NULL,
+	NULL,
+	NULL,
+	VDEV_TYPE_HOLE,		/* name of this vdev type */
+	B_TRUE			/* leaf vdev */
+};
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/module/zfs/vdev_queue.c
@@ -0,0 +1,840 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/*
+ * Copyright (c) 2012, 2014 by Delphix. All rights reserved.
+ */
+
+#include <sys/zfs_context.h>
+#include <sys/vdev_impl.h>
+#include <sys/spa_impl.h>
+#include <sys/zio.h>
+#include <sys/avl.h>
+#include <sys/dsl_pool.h>
+#include <sys/spa.h>
+#include <sys/spa_impl.h>
+#include <sys/kstat.h>
+
+/*
+ * ZFS I/O Scheduler
+ * ---------------
+ *
+ * ZFS issues I/O operations to leaf vdevs to satisfy and complete zios.  The
+ * I/O scheduler determines when and in what order those operations are
+ * issued.  The I/O scheduler divides operations into five I/O classes
+ * prioritized in the following order: sync read, sync write, async read,
+ * async write, and scrub/resilver.  Each queue defines the minimum and
+ * maximum number of concurrent operations that may be issued to the device.
+ * In addition, the device has an aggregate maximum. Note that the sum of the
+ * per-queue minimums must not exceed the aggregate maximum. If the
+ * sum of the per-queue maximums exceeds the aggregate maximum, then the
+ * number of active i/os may reach zfs_vdev_max_active, in which case no
+ * further i/os will be issued regardless of whether all per-queue
+ * minimums have been met.
+ *
+ * For many physical devices, throughput increases with the number of
+ * concurrent operations, but latency typically suffers. Further, physical
+ * devices typically have a limit at which more concurrent operations have no
+ * effect on throughput or can actually cause it to decrease.
+ *
+ * The scheduler selects the next operation to issue by first looking for an
+ * I/O class whose minimum has not been satisfied. Once all are satisfied and
+ * the aggregate maximum has not been hit, the scheduler looks for classes
+ * whose maximum has not been satisfied. Iteration through the I/O classes is
+ * done in the order specified above. No further operations are issued if the
+ * aggregate maximum number of concurrent operations has been hit or if there
+ * are no operations queued for an I/O class that has not hit its maximum.
+ * Every time an i/o is queued or an operation completes, the I/O scheduler
+ * looks for new operations to issue.
+ *
+ * All I/O classes have a fixed maximum number of outstanding operations
+ * except for the async write class. Asynchronous writes represent the data
+ * that is committed to stable storage during the syncing stage for
+ * transaction groups (see txg.c). Transaction groups enter the syncing state
+ * periodically so the number of queued async writes will quickly burst up and
+ * then bleed down to zero. Rather than servicing them as quickly as possible,
+ * the I/O scheduler changes the maximum number of active async write i/os
+ * according to the amount of dirty data in the pool (see dsl_pool.c). Since
+ * both throughput and latency typically increase with the number of
+ * concurrent operations issued to physical devices, reducing the burstiness
+ * in the number of concurrent operations also stabilizes the response time of
+ * operations from other -- and in particular synchronous -- queues. In broad
+ * strokes, the I/O scheduler will issue more concurrent operations from the
+ * async write queue as there's more dirty data in the pool.
+ *
+ * Async Writes
+ *
+ * The number of concurrent operations issued for the async write I/O class
+ * follows a piece-wise linear function defined by a few adjustable points.
+ *
+ *        |                   o---------| <-- zfs_vdev_async_write_max_active
+ *   ^    |                  /^         |
+ *   |    |                 / |         |
+ * active |                /  |         |
+ *  I/O   |               /   |         |
+ * count  |              /    |         |
+ *        |             /     |         |
+ *        |------------o      |         | <-- zfs_vdev_async_write_min_active
+ *       0|____________^______|_________|
+ *        0%           |      |       100% of zfs_dirty_data_max
+ *                     |      |
+ *                     |      `-- zfs_vdev_async_write_active_max_dirty_percent
+ *                     `--------- zfs_vdev_async_write_active_min_dirty_percent
+ *
+ * Until the amount of dirty data exceeds a minimum percentage of the dirty
+ * data allowed in the pool, the I/O scheduler will limit the number of
+ * concurrent operations to the minimum. As that threshold is crossed, the
+ * number of concurrent operations issued increases linearly to the maximum at
+ * the specified maximum percentage of the dirty data allowed in the pool.
+ *
+ * Ideally, the amount of dirty data on a busy pool will stay in the sloped
+ * part of the function between zfs_vdev_async_write_active_min_dirty_percent
+ * and zfs_vdev_async_write_active_max_dirty_percent. If it exceeds the
+ * maximum percentage, this indicates that the rate of incoming data is
+ * greater than the rate that the backend storage can handle. In this case, we
+ * must further throttle incoming writes (see dmu_tx_delay() for details).
+ */
+
+/*
+ * The maximum number of i/os active to each device.  Ideally, this will be >=
+ * the sum of each queue's max_active.  It must be at least the sum of each
+ * queue's min_active.
+ */
+uint32_t zfs_vdev_max_active = 1000;
+
+/*
+ * Per-queue limits on the number of i/os active to each device.  If the
+ * number of active i/os is < zfs_vdev_max_active, then the min_active comes
+ * into play. We will send min_active from each queue, and then select from
+ * queues in the order defined by zio_priority_t.
+ *
+ * In general, smaller max_active's will lead to lower latency of synchronous
+ * operations.  Larger max_active's may lead to higher overall throughput,
+ * depending on underlying storage.
+ *
+ * The ratio of the queues' max_actives determines the balance of performance
+ * between reads, writes, and scrubs.  E.g., increasing
+ * zfs_vdev_scrub_max_active will cause the scrub or resilver to complete
+ * more quickly, but reads and writes to have higher latency and lower
+ * throughput.
+ */
+uint32_t zfs_vdev_sync_read_min_active = 10;
+uint32_t zfs_vdev_sync_read_max_active = 10;
+uint32_t zfs_vdev_sync_write_min_active = 10;
+uint32_t zfs_vdev_sync_write_max_active = 10;
+uint32_t zfs_vdev_async_read_min_active = 1;
+uint32_t zfs_vdev_async_read_max_active = 3;
+uint32_t zfs_vdev_async_write_min_active = 1;
+uint32_t zfs_vdev_async_write_max_active = 10;
+uint32_t zfs_vdev_scrub_min_active = 1;
+uint32_t zfs_vdev_scrub_max_active = 2;
+
+/*
+ * When the pool has less than zfs_vdev_async_write_active_min_dirty_percent
+ * dirty data, use zfs_vdev_async_write_min_active.  When it has more than
+ * zfs_vdev_async_write_active_max_dirty_percent, use
+ * zfs_vdev_async_write_max_active. The value is linearly interpolated
+ * between min and max.
+ */
+int zfs_vdev_async_write_active_min_dirty_percent = 30;
+int zfs_vdev_async_write_active_max_dirty_percent = 60;
+
+/*
+ * To reduce IOPs, we aggregate small adjacent I/Os into one large I/O.
+ * For read I/Os, we also aggregate across small adjacency gaps; for writes
+ * we include spans of optional I/Os to aid aggregation at the disk even when
+ * they aren't able to help us aggregate at this level.
+ */
+int zfs_vdev_aggregation_limit = SPA_OLD_MAXBLOCKSIZE;
+int zfs_vdev_read_gap_limit = 32 << 10;
+int zfs_vdev_write_gap_limit = 4 << 10;
+
+int
+vdev_queue_offset_compare(const void *x1, const void *x2)
+{
+	const zio_t *z1 = x1;
+	const zio_t *z2 = x2;
+
+	if (z1->io_offset < z2->io_offset)
+		return (-1);
+	if (z1->io_offset > z2->io_offset)
+		return (1);
+
+	if (z1 < z2)
+		return (-1);
+	if (z1 > z2)
+		return (1);
+
+	return (0);
+}
+
+static inline avl_tree_t *
+vdev_queue_class_tree(vdev_queue_t *vq, zio_priority_t p)
+{
+	return (&vq->vq_class[p].vqc_queued_tree);
+}
+
+static inline avl_tree_t *
+vdev_queue_type_tree(vdev_queue_t *vq, zio_type_t t)
+{
+	ASSERT(t == ZIO_TYPE_READ || t == ZIO_TYPE_WRITE);
+	if (t == ZIO_TYPE_READ)
+		return (&vq->vq_read_offset_tree);
+	else
+		return (&vq->vq_write_offset_tree);
+}
+
+int
+vdev_queue_timestamp_compare(const void *x1, const void *x2)
+{
+	const zio_t *z1 = x1;
+	const zio_t *z2 = x2;
+
+	if (z1->io_timestamp < z2->io_timestamp)
+		return (-1);
+	if (z1->io_timestamp > z2->io_timestamp)
+		return (1);
+
+	if (z1 < z2)
+		return (-1);
+	if (z1 > z2)
+		return (1);
+
+	return (0);
+}
+
+static int
+vdev_queue_class_min_active(zio_priority_t p)
+{
+	switch (p) {
+	case ZIO_PRIORITY_SYNC_READ:
+		return (zfs_vdev_sync_read_min_active);
+	case ZIO_PRIORITY_SYNC_WRITE:
+		return (zfs_vdev_sync_write_min_active);
+	case ZIO_PRIORITY_ASYNC_READ:
+		return (zfs_vdev_async_read_min_active);
+	case ZIO_PRIORITY_ASYNC_WRITE:
+		return (zfs_vdev_async_write_min_active);
+	case ZIO_PRIORITY_SCRUB:
+		return (zfs_vdev_scrub_min_active);
+	default:
+		panic("invalid priority %u", p);
+		return (0);
+	}
+}
+
+static int
+vdev_queue_max_async_writes(spa_t *spa)
+{
+	int writes;
+	uint64_t dirty = spa->spa_dsl_pool->dp_dirty_total;
+	uint64_t min_bytes = zfs_dirty_data_max *
+	    zfs_vdev_async_write_active_min_dirty_percent / 100;
+	uint64_t max_bytes = zfs_dirty_data_max *
+	    zfs_vdev_async_write_active_max_dirty_percent / 100;
+
+	/*
+	 * Sync tasks correspond to interactive user actions. To reduce the
+	 * execution time of those actions we push data out as fast as possible.
+	 */
+	if (spa_has_pending_synctask(spa)) {
+		return (zfs_vdev_async_write_max_active);
+	}
+
+	if (dirty < min_bytes)
+		return (zfs_vdev_async_write_min_active);
+	if (dirty > max_bytes)
+		return (zfs_vdev_async_write_max_active);
+
+	/*
+	 * linear interpolation:
+	 * slope = (max_writes - min_writes) / (max_bytes - min_bytes)
+	 * move right by min_bytes
+	 * move up by min_writes
+	 */
+	writes = (dirty - min_bytes) *
+	    (zfs_vdev_async_write_max_active -
+	    zfs_vdev_async_write_min_active) /
+	    (max_bytes - min_bytes) +
+	    zfs_vdev_async_write_min_active;
+	ASSERT3U(writes, >=, zfs_vdev_async_write_min_active);
+	ASSERT3U(writes, <=, zfs_vdev_async_write_max_active);
+	return (writes);
+}
+
+static int
+vdev_queue_class_max_active(spa_t *spa, zio_priority_t p)
+{
+	switch (p) {
+	case ZIO_PRIORITY_SYNC_READ:
+		return (zfs_vdev_sync_read_max_active);
+	case ZIO_PRIORITY_SYNC_WRITE:
+		return (zfs_vdev_sync_write_max_active);
+	case ZIO_PRIORITY_ASYNC_READ:
+		return (zfs_vdev_async_read_max_active);
+	case ZIO_PRIORITY_ASYNC_WRITE:
+		return (vdev_queue_max_async_writes(spa));
+	case ZIO_PRIORITY_SCRUB:
+		return (zfs_vdev_scrub_max_active);
+	default:
+		panic("invalid priority %u", p);
+		return (0);
+	}
+}
+
+/*
+ * Return the i/o class to issue from, or ZIO_PRIORITY_MAX_QUEUEABLE if
+ * there is no eligible class.
+ */
+static zio_priority_t
+vdev_queue_class_to_issue(vdev_queue_t *vq)
+{
+	spa_t *spa = vq->vq_vdev->vdev_spa;
+	zio_priority_t p;
+
+	if (avl_numnodes(&vq->vq_active_tree) >= zfs_vdev_max_active)
+		return (ZIO_PRIORITY_NUM_QUEUEABLE);
+
+	/* find a queue that has not reached its minimum # outstanding i/os */
+	for (p = 0; p < ZIO_PRIORITY_NUM_QUEUEABLE; p++) {
+		if (avl_numnodes(vdev_queue_class_tree(vq, p)) > 0 &&
+		    vq->vq_class[p].vqc_active <
+		    vdev_queue_class_min_active(p))
+			return (p);
+	}
+
+	/*
+	 * If we haven't found a queue, look for one that hasn't reached its
+	 * maximum # outstanding i/os.
+	 */
+	for (p = 0; p < ZIO_PRIORITY_NUM_QUEUEABLE; p++) {
+		if (avl_numnodes(vdev_queue_class_tree(vq, p)) > 0 &&
+		    vq->vq_class[p].vqc_active <
+		    vdev_queue_class_max_active(spa, p))
+			return (p);
+	}
+
+	/* No eligible queued i/os */
+	return (ZIO_PRIORITY_NUM_QUEUEABLE);
+}
+
+void
+vdev_queue_init(vdev_t *vd)
+{
+	vdev_queue_t *vq = &vd->vdev_queue;
+	zio_priority_t p;
+
+	mutex_init(&vq->vq_lock, NULL, MUTEX_DEFAULT, NULL);
+	vq->vq_vdev = vd;
+	taskq_init_ent(&vd->vdev_queue.vq_io_search.io_tqent);
+
+	avl_create(&vq->vq_active_tree, vdev_queue_offset_compare,
+	    sizeof (zio_t), offsetof(struct zio, io_queue_node));
+	avl_create(vdev_queue_type_tree(vq, ZIO_TYPE_READ),
+		vdev_queue_offset_compare, sizeof (zio_t),
+		offsetof(struct zio, io_offset_node));
+	avl_create(vdev_queue_type_tree(vq, ZIO_TYPE_WRITE),
+		vdev_queue_offset_compare, sizeof (zio_t),
+		offsetof(struct zio, io_offset_node));
+
+	for (p = 0; p < ZIO_PRIORITY_NUM_QUEUEABLE; p++) {
+		int (*compfn) (const void *, const void *);
+
+		/*
+		 * The synchronous i/o queues are dispatched in FIFO rather
+		 * than LBA order. This provides more consistent latency for
+		 * these i/os.
+		 */
+		if (p == ZIO_PRIORITY_SYNC_READ || p == ZIO_PRIORITY_SYNC_WRITE)
+			compfn = vdev_queue_timestamp_compare;
+		else
+			compfn = vdev_queue_offset_compare;
+		avl_create(vdev_queue_class_tree(vq, p), compfn,
+			sizeof (zio_t), offsetof(struct zio, io_queue_node));
+	}
+}
+
+void
+vdev_queue_fini(vdev_t *vd)
+{
+	vdev_queue_t *vq = &vd->vdev_queue;
+	zio_priority_t p;
+
+	for (p = 0; p < ZIO_PRIORITY_NUM_QUEUEABLE; p++)
+		avl_destroy(vdev_queue_class_tree(vq, p));
+	avl_destroy(&vq->vq_active_tree);
+	avl_destroy(vdev_queue_type_tree(vq, ZIO_TYPE_READ));
+	avl_destroy(vdev_queue_type_tree(vq, ZIO_TYPE_WRITE));
+
+	mutex_destroy(&vq->vq_lock);
+}
+
+static void
+vdev_queue_io_add(vdev_queue_t *vq, zio_t *zio)
+{
+	spa_t *spa = zio->io_spa;
+	spa_stats_history_t *ssh = &spa->spa_stats.io_history;
+
+	ASSERT3U(zio->io_priority, <, ZIO_PRIORITY_NUM_QUEUEABLE);
+	avl_add(vdev_queue_class_tree(vq, zio->io_priority), zio);
+	avl_add(vdev_queue_type_tree(vq, zio->io_type), zio);
+
+	if (ssh->kstat != NULL) {
+		mutex_enter(&ssh->lock);
+		kstat_waitq_enter(ssh->kstat->ks_data);
+		mutex_exit(&ssh->lock);
+	}
+}
+
+static void
+vdev_queue_io_remove(vdev_queue_t *vq, zio_t *zio)
+{
+	spa_t *spa = zio->io_spa;
+	spa_stats_history_t *ssh = &spa->spa_stats.io_history;
+
+	ASSERT3U(zio->io_priority, <, ZIO_PRIORITY_NUM_QUEUEABLE);
+	avl_remove(vdev_queue_class_tree(vq, zio->io_priority), zio);
+	avl_remove(vdev_queue_type_tree(vq, zio->io_type), zio);
+
+	if (ssh->kstat != NULL) {
+		mutex_enter(&ssh->lock);
+		kstat_waitq_exit(ssh->kstat->ks_data);
+		mutex_exit(&ssh->lock);
+	}
+}
+
+static void
+vdev_queue_pending_add(vdev_queue_t *vq, zio_t *zio)
+{
+	spa_t *spa = zio->io_spa;
+	spa_stats_history_t *ssh = &spa->spa_stats.io_history;
+
+	ASSERT(MUTEX_HELD(&vq->vq_lock));
+	ASSERT3U(zio->io_priority, <, ZIO_PRIORITY_NUM_QUEUEABLE);
+	vq->vq_class[zio->io_priority].vqc_active++;
+	avl_add(&vq->vq_active_tree, zio);
+
+	if (ssh->kstat != NULL) {
+		mutex_enter(&ssh->lock);
+		kstat_runq_enter(ssh->kstat->ks_data);
+		mutex_exit(&ssh->lock);
+	}
+}
+
+static void
+vdev_queue_pending_remove(vdev_queue_t *vq, zio_t *zio)
+{
+	spa_t *spa = zio->io_spa;
+	spa_stats_history_t *ssh = &spa->spa_stats.io_history;
+
+	ASSERT(MUTEX_HELD(&vq->vq_lock));
+	ASSERT3U(zio->io_priority, <, ZIO_PRIORITY_NUM_QUEUEABLE);
+	vq->vq_class[zio->io_priority].vqc_active--;
+	avl_remove(&vq->vq_active_tree, zio);
+
+	if (ssh->kstat != NULL) {
+		kstat_io_t *ksio = ssh->kstat->ks_data;
+
+		mutex_enter(&ssh->lock);
+		kstat_runq_exit(ksio);
+		if (zio->io_type == ZIO_TYPE_READ) {
+			ksio->reads++;
+			ksio->nread += zio->io_size;
+		} else if (zio->io_type == ZIO_TYPE_WRITE) {
+			ksio->writes++;
+			ksio->nwritten += zio->io_size;
+		}
+		mutex_exit(&ssh->lock);
+	}
+}
+
+static void
+vdev_queue_agg_io_done(zio_t *aio)
+{
+	if (aio->io_type == ZIO_TYPE_READ) {
+		zio_t *pio;
+		while ((pio = zio_walk_parents(aio)) != NULL) {
+			bcopy((char *)aio->io_data + (pio->io_offset -
+			    aio->io_offset), pio->io_data, pio->io_size);
+		}
+	}
+
+	zio_buf_free(aio->io_data, aio->io_size);
+}
+
+/*
+ * Compute the range spanned by two i/os, which is the endpoint of the last
+ * (lio->io_offset + lio->io_size) minus start of the first (fio->io_offset).
+ * Conveniently, the gap between fio and lio is given by -IO_SPAN(lio, fio);
+ * thus fio and lio are adjacent if and only if IO_SPAN(lio, fio) == 0.
+ */
+#define	IO_SPAN(fio, lio) ((lio)->io_offset + (lio)->io_size - (fio)->io_offset)
+#define	IO_GAP(fio, lio) (-IO_SPAN(lio, fio))
+
+static zio_t *
+vdev_queue_aggregate(vdev_queue_t *vq, zio_t *zio)
+{
+	zio_t *first, *last, *aio, *dio, *mandatory, *nio;
+	uint64_t maxgap = 0;
+	uint64_t size;
+	boolean_t stretch = B_FALSE;
+	avl_tree_t *t = vdev_queue_type_tree(vq, zio->io_type);
+	enum zio_flag flags = zio->io_flags & ZIO_FLAG_AGG_INHERIT;
+	void *buf;
+
+	if (zio->io_flags & ZIO_FLAG_DONT_AGGREGATE)
+		return (NULL);
+
+	/*
+	 * Prevent users from setting the zfs_vdev_aggregation_limit
+	 * tuning larger than SPA_MAXBLOCKSIZE.
+	 */
+	zfs_vdev_aggregation_limit =
+	    MIN(zfs_vdev_aggregation_limit, SPA_MAXBLOCKSIZE);
+
+	first = last = zio;
+
+	if (zio->io_type == ZIO_TYPE_READ)
+		maxgap = zfs_vdev_read_gap_limit;
+
+	/*
+	 * We can aggregate I/Os that are sufficiently adjacent and of
+	 * the same flavor, as expressed by the AGG_INHERIT flags.
+	 * The latter requirement is necessary so that certain
+	 * attributes of the I/O, such as whether it's a normal I/O
+	 * or a scrub/resilver, can be preserved in the aggregate.
+	 * We can include optional I/Os, but don't allow them
+	 * to begin a range as they add no benefit in that situation.
+	 */
+
+	/*
+	 * We keep track of the last non-optional I/O.
+	 */
+	mandatory = (first->io_flags & ZIO_FLAG_OPTIONAL) ? NULL : first;
+
+	/*
+	 * Walk backwards through sufficiently contiguous I/Os
+	 * recording the last non-option I/O.
+	 */
+	while ((dio = AVL_PREV(t, first)) != NULL &&
+	    (dio->io_flags & ZIO_FLAG_AGG_INHERIT) == flags &&
+	    IO_SPAN(dio, last) <= zfs_vdev_aggregation_limit &&
+	    IO_GAP(dio, first) <= maxgap) {
+		first = dio;
+		if (mandatory == NULL && !(first->io_flags & ZIO_FLAG_OPTIONAL))
+			mandatory = first;
+	}
+
+	/*
+	 * Skip any initial optional I/Os.
+	 */
+	while ((first->io_flags & ZIO_FLAG_OPTIONAL) && first != last) {
+		first = AVL_NEXT(t, first);
+		ASSERT(first != NULL);
+	}
+
+
+	/*
+	 * Walk forward through sufficiently contiguous I/Os.
+	 */
+	while ((dio = AVL_NEXT(t, last)) != NULL &&
+	    (dio->io_flags & ZIO_FLAG_AGG_INHERIT) == flags &&
+	    IO_SPAN(first, dio) <= zfs_vdev_aggregation_limit &&
+	    IO_GAP(last, dio) <= maxgap) {
+		last = dio;
+		if (!(last->io_flags & ZIO_FLAG_OPTIONAL))
+			mandatory = last;
+	}
+
+	/*
+	 * Now that we've established the range of the I/O aggregation
+	 * we must decide what to do with trailing optional I/Os.
+	 * For reads, there's nothing to do. While we are unable to
+	 * aggregate further, it's possible that a trailing optional
+	 * I/O would allow the underlying device to aggregate with
+	 * subsequent I/Os. We must therefore determine if the next
+	 * non-optional I/O is close enough to make aggregation
+	 * worthwhile.
+	 */
+	if (zio->io_type == ZIO_TYPE_WRITE && mandatory != NULL) {
+		zio_t *nio = last;
+		while ((dio = AVL_NEXT(t, nio)) != NULL &&
+		    IO_GAP(nio, dio) == 0 &&
+		    IO_GAP(mandatory, dio) <= zfs_vdev_write_gap_limit) {
+			nio = dio;
+			if (!(nio->io_flags & ZIO_FLAG_OPTIONAL)) {
+				stretch = B_TRUE;
+				break;
+			}
+		}
+	}
+
+	if (stretch) {
+		/* This may be a no-op. */
+		dio = AVL_NEXT(t, last);
+		dio->io_flags &= ~ZIO_FLAG_OPTIONAL;
+	} else {
+		while (last != mandatory && last != first) {
+			ASSERT(last->io_flags & ZIO_FLAG_OPTIONAL);
+			last = AVL_PREV(t, last);
+			ASSERT(last != NULL);
+		}
+	}
+
+	if (first == last)
+		return (NULL);
+
+	size = IO_SPAN(first, last);
+	ASSERT3U(size, <=, zfs_vdev_aggregation_limit);
+
+	buf = zio_buf_alloc_flags(size, KM_NOSLEEP);
+	if (buf == NULL)
+		return (NULL);
+
+	aio = zio_vdev_delegated_io(first->io_vd, first->io_offset,
+	    buf, size, first->io_type, zio->io_priority,
+	    flags | ZIO_FLAG_DONT_CACHE | ZIO_FLAG_DONT_QUEUE,
+	    vdev_queue_agg_io_done, NULL);
+	aio->io_timestamp = first->io_timestamp;
+
+	nio = first;
+	do {
+		dio = nio;
+		nio = AVL_NEXT(t, dio);
+		ASSERT3U(dio->io_type, ==, aio->io_type);
+
+		if (dio->io_flags & ZIO_FLAG_NODATA) {
+			ASSERT3U(dio->io_type, ==, ZIO_TYPE_WRITE);
+			bzero((char *)aio->io_data + (dio->io_offset -
+			    aio->io_offset), dio->io_size);
+		} else if (dio->io_type == ZIO_TYPE_WRITE) {
+			bcopy(dio->io_data, (char *)aio->io_data +
+			    (dio->io_offset - aio->io_offset),
+			    dio->io_size);
+		}
+
+		zio_add_child(dio, aio);
+		vdev_queue_io_remove(vq, dio);
+		zio_vdev_io_bypass(dio);
+		zio_execute(dio);
+	} while (dio != last);
+
+	return (aio);
+}
+
+static zio_t *
+vdev_queue_io_to_issue(vdev_queue_t *vq)
+{
+	zio_t *zio, *aio;
+	zio_priority_t p;
+	avl_index_t idx;
+	avl_tree_t *tree;
+
+again:
+	ASSERT(MUTEX_HELD(&vq->vq_lock));
+
+	p = vdev_queue_class_to_issue(vq);
+
+	if (p == ZIO_PRIORITY_NUM_QUEUEABLE) {
+		/* No eligible queued i/os */
+		return (NULL);
+	}
+
+	/*
+	 * For LBA-ordered queues (async / scrub), issue the i/o which follows
+	 * the most recently issued i/o in LBA (offset) order.
+	 *
+	 * For FIFO queues (sync), issue the i/o with the lowest timestamp.
+	 */
+	tree = vdev_queue_class_tree(vq, p);
+	vq->vq_io_search.io_timestamp = 0;
+	vq->vq_io_search.io_offset = vq->vq_last_offset + 1;
+	VERIFY3P(avl_find(tree, &vq->vq_io_search,
+	    &idx), ==, NULL);
+	zio = avl_nearest(tree, idx, AVL_AFTER);
+	if (zio == NULL)
+		zio = avl_first(tree);
+	ASSERT3U(zio->io_priority, ==, p);
+
+	aio = vdev_queue_aggregate(vq, zio);
+	if (aio != NULL)
+		zio = aio;
+	else
+		vdev_queue_io_remove(vq, zio);
+
+	/*
+	 * If the I/O is or was optional and therefore has no data, we need to
+	 * simply discard it. We need to drop the vdev queue's lock to avoid a
+	 * deadlock that we could encounter since this I/O will complete
+	 * immediately.
+	 */
+	if (zio->io_flags & ZIO_FLAG_NODATA) {
+		mutex_exit(&vq->vq_lock);
+		zio_vdev_io_bypass(zio);
+		zio_execute(zio);
+		mutex_enter(&vq->vq_lock);
+		goto again;
+	}
+
+	vdev_queue_pending_add(vq, zio);
+	vq->vq_last_offset = zio->io_offset;
+
+	return (zio);
+}
+
+zio_t *
+vdev_queue_io(zio_t *zio)
+{
+	vdev_queue_t *vq = &zio->io_vd->vdev_queue;
+	zio_t *nio;
+
+	if (zio->io_flags & ZIO_FLAG_DONT_QUEUE)
+		return (zio);
+
+	/*
+	 * Children i/os inherent their parent's priority, which might
+	 * not match the child's i/o type.  Fix it up here.
+	 */
+	if (zio->io_type == ZIO_TYPE_READ) {
+		if (zio->io_priority != ZIO_PRIORITY_SYNC_READ &&
+		    zio->io_priority != ZIO_PRIORITY_ASYNC_READ &&
+		    zio->io_priority != ZIO_PRIORITY_SCRUB)
+			zio->io_priority = ZIO_PRIORITY_ASYNC_READ;
+	} else {
+		ASSERT(zio->io_type == ZIO_TYPE_WRITE);
+		if (zio->io_priority != ZIO_PRIORITY_SYNC_WRITE &&
+		    zio->io_priority != ZIO_PRIORITY_ASYNC_WRITE)
+			zio->io_priority = ZIO_PRIORITY_ASYNC_WRITE;
+	}
+
+	zio->io_flags |= ZIO_FLAG_DONT_CACHE | ZIO_FLAG_DONT_QUEUE;
+
+	mutex_enter(&vq->vq_lock);
+	zio->io_timestamp = gethrtime();
+	vdev_queue_io_add(vq, zio);
+	nio = vdev_queue_io_to_issue(vq);
+	mutex_exit(&vq->vq_lock);
+
+	if (nio == NULL)
+		return (NULL);
+
+	if (nio->io_done == vdev_queue_agg_io_done) {
+		zio_nowait(nio);
+		return (NULL);
+	}
+
+	return (nio);
+}
+
+void
+vdev_queue_io_done(zio_t *zio)
+{
+	vdev_queue_t *vq = &zio->io_vd->vdev_queue;
+	zio_t *nio;
+
+	if (zio_injection_enabled)
+		delay(SEC_TO_TICK(zio_handle_io_delay(zio)));
+
+	mutex_enter(&vq->vq_lock);
+
+	vdev_queue_pending_remove(vq, zio);
+
+	zio->io_delta = gethrtime() - zio->io_timestamp;
+	vq->vq_io_complete_ts = gethrtime();
+	vq->vq_io_delta_ts = vq->vq_io_complete_ts - zio->io_timestamp;
+
+	while ((nio = vdev_queue_io_to_issue(vq)) != NULL) {
+		mutex_exit(&vq->vq_lock);
+		if (nio->io_done == vdev_queue_agg_io_done) {
+			zio_nowait(nio);
+		} else {
+			zio_vdev_io_reissue(nio);
+			zio_execute(nio);
+		}
+		mutex_enter(&vq->vq_lock);
+	}
+
+	mutex_exit(&vq->vq_lock);
+}
+
+#if defined(_KERNEL) && defined(HAVE_SPL)
+module_param(zfs_vdev_aggregation_limit, int, 0644);
+MODULE_PARM_DESC(zfs_vdev_aggregation_limit, "Max vdev I/O aggregation size");
+
+module_param(zfs_vdev_read_gap_limit, int, 0644);
+MODULE_PARM_DESC(zfs_vdev_read_gap_limit, "Aggregate read I/O over gap");
+
+module_param(zfs_vdev_write_gap_limit, int, 0644);
+MODULE_PARM_DESC(zfs_vdev_write_gap_limit, "Aggregate write I/O over gap");
+
+module_param(zfs_vdev_max_active, int, 0644);
+MODULE_PARM_DESC(zfs_vdev_max_active, "Maximum number of active I/Os per vdev");
+
+module_param(zfs_vdev_async_write_active_max_dirty_percent, int, 0644);
+MODULE_PARM_DESC(zfs_vdev_async_write_active_max_dirty_percent,
+	"Async write concurrency max threshold");
+
+module_param(zfs_vdev_async_write_active_min_dirty_percent, int, 0644);
+MODULE_PARM_DESC(zfs_vdev_async_write_active_min_dirty_percent,
+	"Async write concurrency min threshold");
+
+module_param(zfs_vdev_async_read_max_active, int, 0644);
+MODULE_PARM_DESC(zfs_vdev_async_read_max_active,
+	"Max active async read I/Os per vdev");
+
+module_param(zfs_vdev_async_read_min_active, int, 0644);
+MODULE_PARM_DESC(zfs_vdev_async_read_min_active,
+	"Min active async read I/Os per vdev");
+
+module_param(zfs_vdev_async_write_max_active, int, 0644);
+MODULE_PARM_DESC(zfs_vdev_async_write_max_active,
+	"Max active async write I/Os per vdev");
+
+module_param(zfs_vdev_async_write_min_active, int, 0644);
+MODULE_PARM_DESC(zfs_vdev_async_write_min_active,
+	"Min active async write I/Os per vdev");
+
+module_param(zfs_vdev_scrub_max_active, int, 0644);
+MODULE_PARM_DESC(zfs_vdev_scrub_max_active, "Max active scrub I/Os per vdev");
+
+module_param(zfs_vdev_scrub_min_active, int, 0644);
+MODULE_PARM_DESC(zfs_vdev_scrub_min_active, "Min active scrub I/Os per vdev");
+
+module_param(zfs_vdev_sync_read_max_active, int, 0644);
+MODULE_PARM_DESC(zfs_vdev_sync_read_max_active,
+	"Max active sync read I/Os per vdev");
+
+module_param(zfs_vdev_sync_read_min_active, int, 0644);
+MODULE_PARM_DESC(zfs_vdev_sync_read_min_active,
+	"Min active sync read I/Os per vdev");
+
+module_param(zfs_vdev_sync_write_max_active, int, 0644);
+MODULE_PARM_DESC(zfs_vdev_sync_write_max_active,
+	"Max active sync write I/Os per vdev");
+
+module_param(zfs_vdev_sync_write_min_active, int, 0644);
+MODULE_PARM_DESC(zfs_vdev_sync_write_min_active,
+	"Min active sync write I/Os per vdev");
+#endif
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/module/zfs/vdev_raidz.c
@@ -0,0 +1,2222 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2014 by Delphix. All rights reserved.
+ */
+
+#include <sys/zfs_context.h>
+#include <sys/spa.h>
+#include <sys/vdev_impl.h>
+#include <sys/zio.h>
+#include <sys/zio_checksum.h>
+#include <sys/fs/zfs.h>
+#include <sys/fm/fs/zfs.h>
+
+/*
+ * Virtual device vector for RAID-Z.
+ *
+ * This vdev supports single, double, and triple parity. For single parity,
+ * we use a simple XOR of all the data columns. For double or triple parity,
+ * we use a special case of Reed-Solomon coding. This extends the
+ * technique described in "The mathematics of RAID-6" by H. Peter Anvin by
+ * drawing on the system described in "A Tutorial on Reed-Solomon Coding for
+ * Fault-Tolerance in RAID-like Systems" by James S. Plank on which the
+ * former is also based. The latter is designed to provide higher performance
+ * for writes.
+ *
+ * Note that the Plank paper claimed to support arbitrary N+M, but was then
+ * amended six years later identifying a critical flaw that invalidates its
+ * claims. Nevertheless, the technique can be adapted to work for up to
+ * triple parity. For additional parity, the amendment "Note: Correction to
+ * the 1997 Tutorial on Reed-Solomon Coding" by James S. Plank and Ying Ding
+ * is viable, but the additional complexity means that write performance will
+ * suffer.
+ *
+ * All of the methods above operate on a Galois field, defined over the
+ * integers mod 2^N. In our case we choose N=8 for GF(8) so that all elements
+ * can be expressed with a single byte. Briefly, the operations on the
+ * field are defined as follows:
+ *
+ *   o addition (+) is represented by a bitwise XOR
+ *   o subtraction (-) is therefore identical to addition: A + B = A - B
+ *   o multiplication of A by 2 is defined by the following bitwise expression:
+ *
+ *	(A * 2)_7 = A_6
+ *	(A * 2)_6 = A_5
+ *	(A * 2)_5 = A_4
+ *	(A * 2)_4 = A_3 + A_7
+ *	(A * 2)_3 = A_2 + A_7
+ *	(A * 2)_2 = A_1 + A_7
+ *	(A * 2)_1 = A_0
+ *	(A * 2)_0 = A_7
+ *
+ * In C, multiplying by 2 is therefore ((a << 1) ^ ((a & 0x80) ? 0x1d : 0)).
+ * As an aside, this multiplication is derived from the error correcting
+ * primitive polynomial x^8 + x^4 + x^3 + x^2 + 1.
+ *
+ * Observe that any number in the field (except for 0) can be expressed as a
+ * power of 2 -- a generator for the field. We store a table of the powers of
+ * 2 and logs base 2 for quick look ups, and exploit the fact that A * B can
+ * be rewritten as 2^(log_2(A) + log_2(B)) (where '+' is normal addition rather
+ * than field addition). The inverse of a field element A (A^-1) is therefore
+ * A ^ (255 - 1) = A^254.
+ *
+ * The up-to-three parity columns, P, Q, R over several data columns,
+ * D_0, ... D_n-1, can be expressed by field operations:
+ *
+ *	P = D_0 + D_1 + ... + D_n-2 + D_n-1
+ *	Q = 2^n-1 * D_0 + 2^n-2 * D_1 + ... + 2^1 * D_n-2 + 2^0 * D_n-1
+ *	  = ((...((D_0) * 2 + D_1) * 2 + ...) * 2 + D_n-2) * 2 + D_n-1
+ *	R = 4^n-1 * D_0 + 4^n-2 * D_1 + ... + 4^1 * D_n-2 + 4^0 * D_n-1
+ *	  = ((...((D_0) * 4 + D_1) * 4 + ...) * 4 + D_n-2) * 4 + D_n-1
+ *
+ * We chose 1, 2, and 4 as our generators because 1 corresponds to the trival
+ * XOR operation, and 2 and 4 can be computed quickly and generate linearly-
+ * independent coefficients. (There are no additional coefficients that have
+ * this property which is why the uncorrected Plank method breaks down.)
+ *
+ * See the reconstruction code below for how P, Q and R can used individually
+ * or in concert to recover missing data columns.
+ */
+
+typedef struct raidz_col {
+	uint64_t rc_devidx;		/* child device index for I/O */
+	uint64_t rc_offset;		/* device offset */
+	uint64_t rc_size;		/* I/O size */
+	void *rc_data;			/* I/O data */
+	void *rc_gdata;			/* used to store the "good" version */
+	int rc_error;			/* I/O error for this device */
+	uint8_t rc_tried;		/* Did we attempt this I/O column? */
+	uint8_t rc_skipped;		/* Did we skip this I/O column? */
+} raidz_col_t;
+
+typedef struct raidz_map {
+	uint64_t rm_cols;		/* Regular column count */
+	uint64_t rm_scols;		/* Count including skipped columns */
+	uint64_t rm_bigcols;		/* Number of oversized columns */
+	uint64_t rm_asize;		/* Actual total I/O size */
+	uint64_t rm_missingdata;	/* Count of missing data devices */
+	uint64_t rm_missingparity;	/* Count of missing parity devices */
+	uint64_t rm_firstdatacol;	/* First data column/parity count */
+	uint64_t rm_nskip;		/* Skipped sectors for padding */
+	uint64_t rm_skipstart;		/* Column index of padding start */
+	void *rm_datacopy;		/* rm_asize-buffer of copied data */
+	uintptr_t rm_reports;		/* # of referencing checksum reports */
+	uint8_t	rm_freed;		/* map no longer has referencing ZIO */
+	uint8_t	rm_ecksuminjected;	/* checksum error was injected */
+	raidz_col_t rm_col[1];		/* Flexible array of I/O columns */
+} raidz_map_t;
+
+#define	VDEV_RAIDZ_P		0
+#define	VDEV_RAIDZ_Q		1
+#define	VDEV_RAIDZ_R		2
+
+#define	VDEV_RAIDZ_MUL_2(x)	(((x) << 1) ^ (((x) & 0x80) ? 0x1d : 0))
+#define	VDEV_RAIDZ_MUL_4(x)	(VDEV_RAIDZ_MUL_2(VDEV_RAIDZ_MUL_2(x)))
+
+/*
+ * We provide a mechanism to perform the field multiplication operation on a
+ * 64-bit value all at once rather than a byte at a time. This works by
+ * creating a mask from the top bit in each byte and using that to
+ * conditionally apply the XOR of 0x1d.
+ */
+#define	VDEV_RAIDZ_64MUL_2(x, mask) \
+{ \
+	(mask) = (x) & 0x8080808080808080ULL; \
+	(mask) = ((mask) << 1) - ((mask) >> 7); \
+	(x) = (((x) << 1) & 0xfefefefefefefefeULL) ^ \
+	    ((mask) & 0x1d1d1d1d1d1d1d1dULL); \
+}
+
+#define	VDEV_RAIDZ_64MUL_4(x, mask) \
+{ \
+	VDEV_RAIDZ_64MUL_2((x), mask); \
+	VDEV_RAIDZ_64MUL_2((x), mask); \
+}
+
+/*
+ * Force reconstruction to use the general purpose method.
+ */
+int vdev_raidz_default_to_general;
+
+/* Powers of 2 in the Galois field defined above. */
+static const uint8_t vdev_raidz_pow2[256] = {
+	0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80,
+	0x1d, 0x3a, 0x74, 0xe8, 0xcd, 0x87, 0x13, 0x26,
+	0x4c, 0x98, 0x2d, 0x5a, 0xb4, 0x75, 0xea, 0xc9,
+	0x8f, 0x03, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0,
+	0x9d, 0x27, 0x4e, 0x9c, 0x25, 0x4a, 0x94, 0x35,
+	0x6a, 0xd4, 0xb5, 0x77, 0xee, 0xc1, 0x9f, 0x23,
+	0x46, 0x8c, 0x05, 0x0a, 0x14, 0x28, 0x50, 0xa0,
+	0x5d, 0xba, 0x69, 0xd2, 0xb9, 0x6f, 0xde, 0xa1,
+	0x5f, 0xbe, 0x61, 0xc2, 0x99, 0x2f, 0x5e, 0xbc,
+	0x65, 0xca, 0x89, 0x0f, 0x1e, 0x3c, 0x78, 0xf0,
+	0xfd, 0xe7, 0xd3, 0xbb, 0x6b, 0xd6, 0xb1, 0x7f,
+	0xfe, 0xe1, 0xdf, 0xa3, 0x5b, 0xb6, 0x71, 0xe2,
+	0xd9, 0xaf, 0x43, 0x86, 0x11, 0x22, 0x44, 0x88,
+	0x0d, 0x1a, 0x34, 0x68, 0xd0, 0xbd, 0x67, 0xce,
+	0x81, 0x1f, 0x3e, 0x7c, 0xf8, 0xed, 0xc7, 0x93,
+	0x3b, 0x76, 0xec, 0xc5, 0x97, 0x33, 0x66, 0xcc,
+	0x85, 0x17, 0x2e, 0x5c, 0xb8, 0x6d, 0xda, 0xa9,
+	0x4f, 0x9e, 0x21, 0x42, 0x84, 0x15, 0x2a, 0x54,
+	0xa8, 0x4d, 0x9a, 0x29, 0x52, 0xa4, 0x55, 0xaa,
+	0x49, 0x92, 0x39, 0x72, 0xe4, 0xd5, 0xb7, 0x73,
+	0xe6, 0xd1, 0xbf, 0x63, 0xc6, 0x91, 0x3f, 0x7e,
+	0xfc, 0xe5, 0xd7, 0xb3, 0x7b, 0xf6, 0xf1, 0xff,
+	0xe3, 0xdb, 0xab, 0x4b, 0x96, 0x31, 0x62, 0xc4,
+	0x95, 0x37, 0x6e, 0xdc, 0xa5, 0x57, 0xae, 0x41,
+	0x82, 0x19, 0x32, 0x64, 0xc8, 0x8d, 0x07, 0x0e,
+	0x1c, 0x38, 0x70, 0xe0, 0xdd, 0xa7, 0x53, 0xa6,
+	0x51, 0xa2, 0x59, 0xb2, 0x79, 0xf2, 0xf9, 0xef,
+	0xc3, 0x9b, 0x2b, 0x56, 0xac, 0x45, 0x8a, 0x09,
+	0x12, 0x24, 0x48, 0x90, 0x3d, 0x7a, 0xf4, 0xf5,
+	0xf7, 0xf3, 0xfb, 0xeb, 0xcb, 0x8b, 0x0b, 0x16,
+	0x2c, 0x58, 0xb0, 0x7d, 0xfa, 0xe9, 0xcf, 0x83,
+	0x1b, 0x36, 0x6c, 0xd8, 0xad, 0x47, 0x8e, 0x01
+};
+/* Logs of 2 in the Galois field defined above. */
+static const uint8_t vdev_raidz_log2[256] = {
+	0x00, 0x00, 0x01, 0x19, 0x02, 0x32, 0x1a, 0xc6,
+	0x03, 0xdf, 0x33, 0xee, 0x1b, 0x68, 0xc7, 0x4b,
+	0x04, 0x64, 0xe0, 0x0e, 0x34, 0x8d, 0xef, 0x81,
+	0x1c, 0xc1, 0x69, 0xf8, 0xc8, 0x08, 0x4c, 0x71,
+	0x05, 0x8a, 0x65, 0x2f, 0xe1, 0x24, 0x0f, 0x21,
+	0x35, 0x93, 0x8e, 0xda, 0xf0, 0x12, 0x82, 0x45,
+	0x1d, 0xb5, 0xc2, 0x7d, 0x6a, 0x27, 0xf9, 0xb9,
+	0xc9, 0x9a, 0x09, 0x78, 0x4d, 0xe4, 0x72, 0xa6,
+	0x06, 0xbf, 0x8b, 0x62, 0x66, 0xdd, 0x30, 0xfd,
+	0xe2, 0x98, 0x25, 0xb3, 0x10, 0x91, 0x22, 0x88,
+	0x36, 0xd0, 0x94, 0xce, 0x8f, 0x96, 0xdb, 0xbd,
+	0xf1, 0xd2, 0x13, 0x5c, 0x83, 0x38, 0x46, 0x40,
+	0x1e, 0x42, 0xb6, 0xa3, 0xc3, 0x48, 0x7e, 0x6e,
+	0x6b, 0x3a, 0x28, 0x54, 0xfa, 0x85, 0xba, 0x3d,
+	0xca, 0x5e, 0x9b, 0x9f, 0x0a, 0x15, 0x79, 0x2b,
+	0x4e, 0xd4, 0xe5, 0xac, 0x73, 0xf3, 0xa7, 0x57,
+	0x07, 0x70, 0xc0, 0xf7, 0x8c, 0x80, 0x63, 0x0d,
+	0x67, 0x4a, 0xde, 0xed, 0x31, 0xc5, 0xfe, 0x18,
+	0xe3, 0xa5, 0x99, 0x77, 0x26, 0xb8, 0xb4, 0x7c,
+	0x11, 0x44, 0x92, 0xd9, 0x23, 0x20, 0x89, 0x2e,
+	0x37, 0x3f, 0xd1, 0x5b, 0x95, 0xbc, 0xcf, 0xcd,
+	0x90, 0x87, 0x97, 0xb2, 0xdc, 0xfc, 0xbe, 0x61,
+	0xf2, 0x56, 0xd3, 0xab, 0x14, 0x2a, 0x5d, 0x9e,
+	0x84, 0x3c, 0x39, 0x53, 0x47, 0x6d, 0x41, 0xa2,
+	0x1f, 0x2d, 0x43, 0xd8, 0xb7, 0x7b, 0xa4, 0x76,
+	0xc4, 0x17, 0x49, 0xec, 0x7f, 0x0c, 0x6f, 0xf6,
+	0x6c, 0xa1, 0x3b, 0x52, 0x29, 0x9d, 0x55, 0xaa,
+	0xfb, 0x60, 0x86, 0xb1, 0xbb, 0xcc, 0x3e, 0x5a,
+	0xcb, 0x59, 0x5f, 0xb0, 0x9c, 0xa9, 0xa0, 0x51,
+	0x0b, 0xf5, 0x16, 0xeb, 0x7a, 0x75, 0x2c, 0xd7,
+	0x4f, 0xae, 0xd5, 0xe9, 0xe6, 0xe7, 0xad, 0xe8,
+	0x74, 0xd6, 0xf4, 0xea, 0xa8, 0x50, 0x58, 0xaf,
+};
+
+static void vdev_raidz_generate_parity(raidz_map_t *rm);
+
+/*
+ * Multiply a given number by 2 raised to the given power.
+ */
+static uint8_t
+vdev_raidz_exp2(uint_t a, int exp)
+{
+	if (a == 0)
+		return (0);
+
+	ASSERT(exp >= 0);
+	ASSERT(vdev_raidz_log2[a] > 0 || a == 1);
+
+	exp += vdev_raidz_log2[a];
+	if (exp > 255)
+		exp -= 255;
+
+	return (vdev_raidz_pow2[exp]);
+}
+
+static void
+vdev_raidz_map_free(raidz_map_t *rm)
+{
+	int c;
+	size_t size;
+
+	for (c = 0; c < rm->rm_firstdatacol; c++) {
+		zio_buf_free(rm->rm_col[c].rc_data, rm->rm_col[c].rc_size);
+
+		if (rm->rm_col[c].rc_gdata != NULL)
+			zio_buf_free(rm->rm_col[c].rc_gdata,
+			    rm->rm_col[c].rc_size);
+	}
+
+	size = 0;
+	for (c = rm->rm_firstdatacol; c < rm->rm_cols; c++)
+		size += rm->rm_col[c].rc_size;
+
+	if (rm->rm_datacopy != NULL)
+		zio_buf_free(rm->rm_datacopy, size);
+
+	kmem_free(rm, offsetof(raidz_map_t, rm_col[rm->rm_scols]));
+}
+
+static void
+vdev_raidz_map_free_vsd(zio_t *zio)
+{
+	raidz_map_t *rm = zio->io_vsd;
+
+	ASSERT0(rm->rm_freed);
+	rm->rm_freed = 1;
+
+	if (rm->rm_reports == 0)
+		vdev_raidz_map_free(rm);
+}
+
+/*ARGSUSED*/
+static void
+vdev_raidz_cksum_free(void *arg, size_t ignored)
+{
+	raidz_map_t *rm = arg;
+
+	ASSERT3U(rm->rm_reports, >, 0);
+
+	if (--rm->rm_reports == 0 && rm->rm_freed != 0)
+		vdev_raidz_map_free(rm);
+}
+
+static void
+vdev_raidz_cksum_finish(zio_cksum_report_t *zcr, const void *good_data)
+{
+	raidz_map_t *rm = zcr->zcr_cbdata;
+	size_t c = zcr->zcr_cbinfo;
+	size_t x;
+
+	const char *good = NULL;
+	const char *bad = rm->rm_col[c].rc_data;
+
+	if (good_data == NULL) {
+		zfs_ereport_finish_checksum(zcr, NULL, NULL, B_FALSE);
+		return;
+	}
+
+	if (c < rm->rm_firstdatacol) {
+		/*
+		 * The first time through, calculate the parity blocks for
+		 * the good data (this relies on the fact that the good
+		 * data never changes for a given logical ZIO)
+		 */
+		if (rm->rm_col[0].rc_gdata == NULL) {
+			char *bad_parity[VDEV_RAIDZ_MAXPARITY];
+			char *buf;
+
+			/*
+			 * Set up the rm_col[]s to generate the parity for
+			 * good_data, first saving the parity bufs and
+			 * replacing them with buffers to hold the result.
+			 */
+			for (x = 0; x < rm->rm_firstdatacol; x++) {
+				bad_parity[x] = rm->rm_col[x].rc_data;
+				rm->rm_col[x].rc_data = rm->rm_col[x].rc_gdata =
+				    zio_buf_alloc(rm->rm_col[x].rc_size);
+			}
+
+			/* fill in the data columns from good_data */
+			buf = (char *)good_data;
+			for (; x < rm->rm_cols; x++) {
+				rm->rm_col[x].rc_data = buf;
+				buf += rm->rm_col[x].rc_size;
+			}
+
+			/*
+			 * Construct the parity from the good data.
+			 */
+			vdev_raidz_generate_parity(rm);
+
+			/* restore everything back to its original state */
+			for (x = 0; x < rm->rm_firstdatacol; x++)
+				rm->rm_col[x].rc_data = bad_parity[x];
+
+			buf = rm->rm_datacopy;
+			for (x = rm->rm_firstdatacol; x < rm->rm_cols; x++) {
+				rm->rm_col[x].rc_data = buf;
+				buf += rm->rm_col[x].rc_size;
+			}
+		}
+
+		ASSERT3P(rm->rm_col[c].rc_gdata, !=, NULL);
+		good = rm->rm_col[c].rc_gdata;
+	} else {
+		/* adjust good_data to point at the start of our column */
+		good = good_data;
+
+		for (x = rm->rm_firstdatacol; x < c; x++)
+			good += rm->rm_col[x].rc_size;
+	}
+
+	/* we drop the ereport if it ends up that the data was good */
+	zfs_ereport_finish_checksum(zcr, good, bad, B_TRUE);
+}
+
+/*
+ * Invoked indirectly by zfs_ereport_start_checksum(), called
+ * below when our read operation fails completely.  The main point
+ * is to keep a copy of everything we read from disk, so that at
+ * vdev_raidz_cksum_finish() time we can compare it with the good data.
+ */
+static void
+vdev_raidz_cksum_report(zio_t *zio, zio_cksum_report_t *zcr, void *arg)
+{
+	size_t c = (size_t)(uintptr_t)arg;
+	caddr_t buf;
+
+	raidz_map_t *rm = zio->io_vsd;
+	size_t size;
+
+	/* set up the report and bump the refcount  */
+	zcr->zcr_cbdata = rm;
+	zcr->zcr_cbinfo = c;
+	zcr->zcr_finish = vdev_raidz_cksum_finish;
+	zcr->zcr_free = vdev_raidz_cksum_free;
+
+	rm->rm_reports++;
+	ASSERT3U(rm->rm_reports, >, 0);
+
+	if (rm->rm_datacopy != NULL)
+		return;
+
+	/*
+	 * It's the first time we're called for this raidz_map_t, so we need
+	 * to copy the data aside; there's no guarantee that our zio's buffer
+	 * won't be re-used for something else.
+	 *
+	 * Our parity data is already in separate buffers, so there's no need
+	 * to copy them.
+	 */
+
+	size = 0;
+	for (c = rm->rm_firstdatacol; c < rm->rm_cols; c++)
+		size += rm->rm_col[c].rc_size;
+
+	buf = rm->rm_datacopy = zio_buf_alloc(size);
+
+	for (c = rm->rm_firstdatacol; c < rm->rm_cols; c++) {
+		raidz_col_t *col = &rm->rm_col[c];
+
+		bcopy(col->rc_data, buf, col->rc_size);
+		col->rc_data = buf;
+
+		buf += col->rc_size;
+	}
+	ASSERT3P(buf - (caddr_t)rm->rm_datacopy, ==, size);
+}
+
+static const zio_vsd_ops_t vdev_raidz_vsd_ops = {
+	vdev_raidz_map_free_vsd,
+	vdev_raidz_cksum_report
+};
+
+/*
+ * Divides the IO evenly across all child vdevs; usually, dcols is
+ * the number of children in the target vdev.
+ *
+ * Avoid inlining the function to keep vdev_raidz_io_start(), which
+ * is this functions only caller, as small as possible on the stack.
+ */
+noinline static raidz_map_t *
+vdev_raidz_map_alloc(zio_t *zio, uint64_t unit_shift, uint64_t dcols,
+    uint64_t nparity)
+{
+	raidz_map_t *rm;
+	/* The starting RAIDZ (parent) vdev sector of the block. */
+	uint64_t b = zio->io_offset >> unit_shift;
+	/* The zio's size in units of the vdev's minimum sector size. */
+	uint64_t s = zio->io_size >> unit_shift;
+	/* The first column for this stripe. */
+	uint64_t f = b % dcols;
+	/* The starting byte offset on each child vdev. */
+	uint64_t o = (b / dcols) << unit_shift;
+	uint64_t q, r, c, bc, col, acols, scols, coff, devidx, asize, tot;
+
+	/*
+	 * "Quotient": The number of data sectors for this stripe on all but
+	 * the "big column" child vdevs that also contain "remainder" data.
+	 */
+	q = s / (dcols - nparity);
+
+	/*
+	 * "Remainder": The number of partial stripe data sectors in this I/O.
+	 * This will add a sector to some, but not all, child vdevs.
+	 */
+	r = s - q * (dcols - nparity);
+
+	/* The number of "big columns" - those which contain remainder data. */
+	bc = (r == 0 ? 0 : r + nparity);
+
+	/*
+	 * The total number of data and parity sectors associated with
+	 * this I/O.
+	 */
+	tot = s + nparity * (q + (r == 0 ? 0 : 1));
+
+	/* acols: The columns that will be accessed. */
+	/* scols: The columns that will be accessed or skipped. */
+	if (q == 0) {
+		/* Our I/O request doesn't span all child vdevs. */
+		acols = bc;
+		scols = MIN(dcols, roundup(bc, nparity + 1));
+	} else {
+		acols = dcols;
+		scols = dcols;
+	}
+
+	ASSERT3U(acols, <=, scols);
+
+	rm = kmem_alloc(offsetof(raidz_map_t, rm_col[scols]), KM_SLEEP);
+
+	rm->rm_cols = acols;
+	rm->rm_scols = scols;
+	rm->rm_bigcols = bc;
+	rm->rm_skipstart = bc;
+	rm->rm_missingdata = 0;
+	rm->rm_missingparity = 0;
+	rm->rm_firstdatacol = nparity;
+	rm->rm_datacopy = NULL;
+	rm->rm_reports = 0;
+	rm->rm_freed = 0;
+	rm->rm_ecksuminjected = 0;
+
+	asize = 0;
+
+	for (c = 0; c < scols; c++) {
+		col = f + c;
+		coff = o;
+		if (col >= dcols) {
+			col -= dcols;
+			coff += 1ULL << unit_shift;
+		}
+		rm->rm_col[c].rc_devidx = col;
+		rm->rm_col[c].rc_offset = coff;
+		rm->rm_col[c].rc_data = NULL;
+		rm->rm_col[c].rc_gdata = NULL;
+		rm->rm_col[c].rc_error = 0;
+		rm->rm_col[c].rc_tried = 0;
+		rm->rm_col[c].rc_skipped = 0;
+
+		if (c >= acols)
+			rm->rm_col[c].rc_size = 0;
+		else if (c < bc)
+			rm->rm_col[c].rc_size = (q + 1) << unit_shift;
+		else
+			rm->rm_col[c].rc_size = q << unit_shift;
+
+		asize += rm->rm_col[c].rc_size;
+	}
+
+	ASSERT3U(asize, ==, tot << unit_shift);
+	rm->rm_asize = roundup(asize, (nparity + 1) << unit_shift);
+	rm->rm_nskip = roundup(tot, nparity + 1) - tot;
+	ASSERT3U(rm->rm_asize - asize, ==, rm->rm_nskip << unit_shift);
+	ASSERT3U(rm->rm_nskip, <=, nparity);
+
+	for (c = 0; c < rm->rm_firstdatacol; c++)
+		rm->rm_col[c].rc_data = zio_buf_alloc(rm->rm_col[c].rc_size);
+
+	rm->rm_col[c].rc_data = zio->io_data;
+
+	for (c = c + 1; c < acols; c++)
+		rm->rm_col[c].rc_data = (char *)rm->rm_col[c - 1].rc_data +
+		    rm->rm_col[c - 1].rc_size;
+
+	/*
+	 * If all data stored spans all columns, there's a danger that parity
+	 * will always be on the same device and, since parity isn't read
+	 * during normal operation, that that device's I/O bandwidth won't be
+	 * used effectively. We therefore switch the parity every 1MB.
+	 *
+	 * ... at least that was, ostensibly, the theory. As a practical
+	 * matter unless we juggle the parity between all devices evenly, we
+	 * won't see any benefit. Further, occasional writes that aren't a
+	 * multiple of the LCM of the number of children and the minimum
+	 * stripe width are sufficient to avoid pessimal behavior.
+	 * Unfortunately, this decision created an implicit on-disk format
+	 * requirement that we need to support for all eternity, but only
+	 * for single-parity RAID-Z.
+	 *
+	 * If we intend to skip a sector in the zeroth column for padding
+	 * we must make sure to note this swap. We will never intend to
+	 * skip the first column since at least one data and one parity
+	 * column must appear in each row.
+	 */
+	ASSERT(rm->rm_cols >= 2);
+	ASSERT(rm->rm_col[0].rc_size == rm->rm_col[1].rc_size);
+
+	if (rm->rm_firstdatacol == 1 && (zio->io_offset & (1ULL << 20))) {
+		devidx = rm->rm_col[0].rc_devidx;
+		o = rm->rm_col[0].rc_offset;
+		rm->rm_col[0].rc_devidx = rm->rm_col[1].rc_devidx;
+		rm->rm_col[0].rc_offset = rm->rm_col[1].rc_offset;
+		rm->rm_col[1].rc_devidx = devidx;
+		rm->rm_col[1].rc_offset = o;
+
+		if (rm->rm_skipstart == 0)
+			rm->rm_skipstart = 1;
+	}
+
+	zio->io_vsd = rm;
+	zio->io_vsd_ops = &vdev_raidz_vsd_ops;
+	return (rm);
+}
+
+static void
+vdev_raidz_generate_parity_p(raidz_map_t *rm)
+{
+	uint64_t *p, *src, pcount, ccount, i;
+	int c;
+
+	pcount = rm->rm_col[VDEV_RAIDZ_P].rc_size / sizeof (src[0]);
+
+	for (c = rm->rm_firstdatacol; c < rm->rm_cols; c++) {
+		src = rm->rm_col[c].rc_data;
+		p = rm->rm_col[VDEV_RAIDZ_P].rc_data;
+		ccount = rm->rm_col[c].rc_size / sizeof (src[0]);
+
+		if (c == rm->rm_firstdatacol) {
+			ASSERT(ccount == pcount);
+			for (i = 0; i < ccount; i++, src++, p++) {
+				*p = *src;
+			}
+		} else {
+			ASSERT(ccount <= pcount);
+			for (i = 0; i < ccount; i++, src++, p++) {
+				*p ^= *src;
+			}
+		}
+	}
+}
+
+static void
+vdev_raidz_generate_parity_pq(raidz_map_t *rm)
+{
+	uint64_t *p, *q, *src, pcnt, ccnt, mask, i;
+	int c;
+
+	pcnt = rm->rm_col[VDEV_RAIDZ_P].rc_size / sizeof (src[0]);
+	ASSERT(rm->rm_col[VDEV_RAIDZ_P].rc_size ==
+	    rm->rm_col[VDEV_RAIDZ_Q].rc_size);
+
+	for (c = rm->rm_firstdatacol; c < rm->rm_cols; c++) {
+		src = rm->rm_col[c].rc_data;
+		p = rm->rm_col[VDEV_RAIDZ_P].rc_data;
+		q = rm->rm_col[VDEV_RAIDZ_Q].rc_data;
+
+		ccnt = rm->rm_col[c].rc_size / sizeof (src[0]);
+
+		if (c == rm->rm_firstdatacol) {
+			ASSERT(ccnt == pcnt || ccnt == 0);
+			for (i = 0; i < ccnt; i++, src++, p++, q++) {
+				*p = *src;
+				*q = *src;
+			}
+			for (; i < pcnt; i++, src++, p++, q++) {
+				*p = 0;
+				*q = 0;
+			}
+		} else {
+			ASSERT(ccnt <= pcnt);
+
+			/*
+			 * Apply the algorithm described above by multiplying
+			 * the previous result and adding in the new value.
+			 */
+			for (i = 0; i < ccnt; i++, src++, p++, q++) {
+				*p ^= *src;
+
+				VDEV_RAIDZ_64MUL_2(*q, mask);
+				*q ^= *src;
+			}
+
+			/*
+			 * Treat short columns as though they are full of 0s.
+			 * Note that there's therefore nothing needed for P.
+			 */
+			for (; i < pcnt; i++, q++) {
+				VDEV_RAIDZ_64MUL_2(*q, mask);
+			}
+		}
+	}
+}
+
+static void
+vdev_raidz_generate_parity_pqr(raidz_map_t *rm)
+{
+	uint64_t *p, *q, *r, *src, pcnt, ccnt, mask, i;
+	int c;
+
+	pcnt = rm->rm_col[VDEV_RAIDZ_P].rc_size / sizeof (src[0]);
+	ASSERT(rm->rm_col[VDEV_RAIDZ_P].rc_size ==
+	    rm->rm_col[VDEV_RAIDZ_Q].rc_size);
+	ASSERT(rm->rm_col[VDEV_RAIDZ_P].rc_size ==
+	    rm->rm_col[VDEV_RAIDZ_R].rc_size);
+
+	for (c = rm->rm_firstdatacol; c < rm->rm_cols; c++) {
+		src = rm->rm_col[c].rc_data;
+		p = rm->rm_col[VDEV_RAIDZ_P].rc_data;
+		q = rm->rm_col[VDEV_RAIDZ_Q].rc_data;
+		r = rm->rm_col[VDEV_RAIDZ_R].rc_data;
+
+		ccnt = rm->rm_col[c].rc_size / sizeof (src[0]);
+
+		if (c == rm->rm_firstdatacol) {
+			ASSERT(ccnt == pcnt || ccnt == 0);
+			for (i = 0; i < ccnt; i++, src++, p++, q++, r++) {
+				*p = *src;
+				*q = *src;
+				*r = *src;
+			}
+			for (; i < pcnt; i++, src++, p++, q++, r++) {
+				*p = 0;
+				*q = 0;
+				*r = 0;
+			}
+		} else {
+			ASSERT(ccnt <= pcnt);
+
+			/*
+			 * Apply the algorithm described above by multiplying
+			 * the previous result and adding in the new value.
+			 */
+			for (i = 0; i < ccnt; i++, src++, p++, q++, r++) {
+				*p ^= *src;
+
+				VDEV_RAIDZ_64MUL_2(*q, mask);
+				*q ^= *src;
+
+				VDEV_RAIDZ_64MUL_4(*r, mask);
+				*r ^= *src;
+			}
+
+			/*
+			 * Treat short columns as though they are full of 0s.
+			 * Note that there's therefore nothing needed for P.
+			 */
+			for (; i < pcnt; i++, q++, r++) {
+				VDEV_RAIDZ_64MUL_2(*q, mask);
+				VDEV_RAIDZ_64MUL_4(*r, mask);
+			}
+		}
+	}
+}
+
+/*
+ * Generate RAID parity in the first virtual columns according to the number of
+ * parity columns available.
+ */
+static void
+vdev_raidz_generate_parity(raidz_map_t *rm)
+{
+	switch (rm->rm_firstdatacol) {
+	case 1:
+		vdev_raidz_generate_parity_p(rm);
+		break;
+	case 2:
+		vdev_raidz_generate_parity_pq(rm);
+		break;
+	case 3:
+		vdev_raidz_generate_parity_pqr(rm);
+		break;
+	default:
+		cmn_err(CE_PANIC, "invalid RAID-Z configuration");
+	}
+}
+
+static int
+vdev_raidz_reconstruct_p(raidz_map_t *rm, int *tgts, int ntgts)
+{
+	uint64_t *dst, *src, xcount, ccount, count, i;
+	int x = tgts[0];
+	int c;
+
+	ASSERT(ntgts == 1);
+	ASSERT(x >= rm->rm_firstdatacol);
+	ASSERT(x < rm->rm_cols);
+
+	xcount = rm->rm_col[x].rc_size / sizeof (src[0]);
+	ASSERT(xcount <= rm->rm_col[VDEV_RAIDZ_P].rc_size / sizeof (src[0]));
+	ASSERT(xcount > 0);
+
+	src = rm->rm_col[VDEV_RAIDZ_P].rc_data;
+	dst = rm->rm_col[x].rc_data;
+	for (i = 0; i < xcount; i++, dst++, src++) {
+		*dst = *src;
+	}
+
+	for (c = rm->rm_firstdatacol; c < rm->rm_cols; c++) {
+		src = rm->rm_col[c].rc_data;
+		dst = rm->rm_col[x].rc_data;
+
+		if (c == x)
+			continue;
+
+		ccount = rm->rm_col[c].rc_size / sizeof (src[0]);
+		count = MIN(ccount, xcount);
+
+		for (i = 0; i < count; i++, dst++, src++) {
+			*dst ^= *src;
+		}
+	}
+
+	return (1 << VDEV_RAIDZ_P);
+}
+
+static int
+vdev_raidz_reconstruct_q(raidz_map_t *rm, int *tgts, int ntgts)
+{
+	uint64_t *dst, *src, xcount, ccount, count, mask, i;
+	uint8_t *b;
+	int x = tgts[0];
+	int c, j, exp;
+
+	ASSERT(ntgts == 1);
+
+	xcount = rm->rm_col[x].rc_size / sizeof (src[0]);
+	ASSERT(xcount <= rm->rm_col[VDEV_RAIDZ_Q].rc_size / sizeof (src[0]));
+
+	for (c = rm->rm_firstdatacol; c < rm->rm_cols; c++) {
+		src = rm->rm_col[c].rc_data;
+		dst = rm->rm_col[x].rc_data;
+
+		if (c == x)
+			ccount = 0;
+		else
+			ccount = rm->rm_col[c].rc_size / sizeof (src[0]);
+
+		count = MIN(ccount, xcount);
+
+		if (c == rm->rm_firstdatacol) {
+			for (i = 0; i < count; i++, dst++, src++) {
+				*dst = *src;
+			}
+			for (; i < xcount; i++, dst++) {
+				*dst = 0;
+			}
+
+		} else {
+			for (i = 0; i < count; i++, dst++, src++) {
+				VDEV_RAIDZ_64MUL_2(*dst, mask);
+				*dst ^= *src;
+			}
+
+			for (; i < xcount; i++, dst++) {
+				VDEV_RAIDZ_64MUL_2(*dst, mask);
+			}
+		}
+	}
+
+	src = rm->rm_col[VDEV_RAIDZ_Q].rc_data;
+	dst = rm->rm_col[x].rc_data;
+	exp = 255 - (rm->rm_cols - 1 - x);
+
+	for (i = 0; i < xcount; i++, dst++, src++) {
+		*dst ^= *src;
+		for (j = 0, b = (uint8_t *)dst; j < 8; j++, b++) {
+			*b = vdev_raidz_exp2(*b, exp);
+		}
+	}
+
+	return (1 << VDEV_RAIDZ_Q);
+}
+
+static int
+vdev_raidz_reconstruct_pq(raidz_map_t *rm, int *tgts, int ntgts)
+{
+	uint8_t *p, *q, *pxy, *qxy, *xd, *yd, tmp, a, b, aexp, bexp;
+	void *pdata, *qdata;
+	uint64_t xsize, ysize, i;
+	int x = tgts[0];
+	int y = tgts[1];
+
+	ASSERT(ntgts == 2);
+	ASSERT(x < y);
+	ASSERT(x >= rm->rm_firstdatacol);
+	ASSERT(y < rm->rm_cols);
+
+	ASSERT(rm->rm_col[x].rc_size >= rm->rm_col[y].rc_size);
+
+	/*
+	 * Move the parity data aside -- we're going to compute parity as
+	 * though columns x and y were full of zeros -- Pxy and Qxy. We want to
+	 * reuse the parity generation mechanism without trashing the actual
+	 * parity so we make those columns appear to be full of zeros by
+	 * setting their lengths to zero.
+	 */
+	pdata = rm->rm_col[VDEV_RAIDZ_P].rc_data;
+	qdata = rm->rm_col[VDEV_RAIDZ_Q].rc_data;
+	xsize = rm->rm_col[x].rc_size;
+	ysize = rm->rm_col[y].rc_size;
+
+	rm->rm_col[VDEV_RAIDZ_P].rc_data =
+	    zio_buf_alloc(rm->rm_col[VDEV_RAIDZ_P].rc_size);
+	rm->rm_col[VDEV_RAIDZ_Q].rc_data =
+	    zio_buf_alloc(rm->rm_col[VDEV_RAIDZ_Q].rc_size);
+	rm->rm_col[x].rc_size = 0;
+	rm->rm_col[y].rc_size = 0;
+
+	vdev_raidz_generate_parity_pq(rm);
+
+	rm->rm_col[x].rc_size = xsize;
+	rm->rm_col[y].rc_size = ysize;
+
+	p = pdata;
+	q = qdata;
+	pxy = rm->rm_col[VDEV_RAIDZ_P].rc_data;
+	qxy = rm->rm_col[VDEV_RAIDZ_Q].rc_data;
+	xd = rm->rm_col[x].rc_data;
+	yd = rm->rm_col[y].rc_data;
+
+	/*
+	 * We now have:
+	 *	Pxy = P + D_x + D_y
+	 *	Qxy = Q + 2^(ndevs - 1 - x) * D_x + 2^(ndevs - 1 - y) * D_y
+	 *
+	 * We can then solve for D_x:
+	 *	D_x = A * (P + Pxy) + B * (Q + Qxy)
+	 * where
+	 *	A = 2^(x - y) * (2^(x - y) + 1)^-1
+	 *	B = 2^(ndevs - 1 - x) * (2^(x - y) + 1)^-1
+	 *
+	 * With D_x in hand, we can easily solve for D_y:
+	 *	D_y = P + Pxy + D_x
+	 */
+
+	a = vdev_raidz_pow2[255 + x - y];
+	b = vdev_raidz_pow2[255 - (rm->rm_cols - 1 - x)];
+	tmp = 255 - vdev_raidz_log2[a ^ 1];
+
+	aexp = vdev_raidz_log2[vdev_raidz_exp2(a, tmp)];
+	bexp = vdev_raidz_log2[vdev_raidz_exp2(b, tmp)];
+
+	for (i = 0; i < xsize; i++, p++, q++, pxy++, qxy++, xd++, yd++) {
+		*xd = vdev_raidz_exp2(*p ^ *pxy, aexp) ^
+		    vdev_raidz_exp2(*q ^ *qxy, bexp);
+
+		if (i < ysize)
+			*yd = *p ^ *pxy ^ *xd;
+	}
+
+	zio_buf_free(rm->rm_col[VDEV_RAIDZ_P].rc_data,
+	    rm->rm_col[VDEV_RAIDZ_P].rc_size);
+	zio_buf_free(rm->rm_col[VDEV_RAIDZ_Q].rc_data,
+	    rm->rm_col[VDEV_RAIDZ_Q].rc_size);
+
+	/*
+	 * Restore the saved parity data.
+	 */
+	rm->rm_col[VDEV_RAIDZ_P].rc_data = pdata;
+	rm->rm_col[VDEV_RAIDZ_Q].rc_data = qdata;
+
+	return ((1 << VDEV_RAIDZ_P) | (1 << VDEV_RAIDZ_Q));
+}
+
+/* BEGIN CSTYLED */
+/*
+ * In the general case of reconstruction, we must solve the system of linear
+ * equations defined by the coeffecients used to generate parity as well as
+ * the contents of the data and parity disks. This can be expressed with
+ * vectors for the original data (D) and the actual data (d) and parity (p)
+ * and a matrix composed of the identity matrix (I) and a dispersal matrix (V):
+ *
+ *            __   __                     __     __
+ *            |     |         __     __   |  p_0  |
+ *            |  V  |         |  D_0  |   | p_m-1 |
+ *            |     |    x    |   :   | = |  d_0  |
+ *            |  I  |         | D_n-1 |   |   :   |
+ *            |     |         ~~     ~~   | d_n-1 |
+ *            ~~   ~~                     ~~     ~~
+ *
+ * I is simply a square identity matrix of size n, and V is a vandermonde
+ * matrix defined by the coeffecients we chose for the various parity columns
+ * (1, 2, 4). Note that these values were chosen both for simplicity, speedy
+ * computation as well as linear separability.
+ *
+ *      __               __               __     __
+ *      |   1   ..  1 1 1 |               |  p_0  |
+ *      | 2^n-1 ..  4 2 1 |   __     __   |   :   |
+ *      | 4^n-1 .. 16 4 1 |   |  D_0  |   | p_m-1 |
+ *      |   1   ..  0 0 0 |   |  D_1  |   |  d_0  |
+ *      |   0   ..  0 0 0 | x |  D_2  | = |  d_1  |
+ *      |   :       : : : |   |   :   |   |  d_2  |
+ *      |   0   ..  1 0 0 |   | D_n-1 |   |   :   |
+ *      |   0   ..  0 1 0 |   ~~     ~~   |   :   |
+ *      |   0   ..  0 0 1 |               | d_n-1 |
+ *      ~~               ~~               ~~     ~~
+ *
+ * Note that I, V, d, and p are known. To compute D, we must invert the
+ * matrix and use the known data and parity values to reconstruct the unknown
+ * data values. We begin by removing the rows in V|I and d|p that correspond
+ * to failed or missing columns; we then make V|I square (n x n) and d|p
+ * sized n by removing rows corresponding to unused parity from the bottom up
+ * to generate (V|I)' and (d|p)'. We can then generate the inverse of (V|I)'
+ * using Gauss-Jordan elimination. In the example below we use m=3 parity
+ * columns, n=8 data columns, with errors in d_1, d_2, and p_1:
+ *           __                               __
+ *           |  1   1   1   1   1   1   1   1  |
+ *           | 128  64  32  16  8   4   2   1  | <-----+-+-- missing disks
+ *           |  19 205 116  29  64  16  4   1  |      / /
+ *           |  1   0   0   0   0   0   0   0  |     / /
+ *           |  0   1   0   0   0   0   0   0  | <--' /
+ *  (V|I)  = |  0   0   1   0   0   0   0   0  | <---'
+ *           |  0   0   0   1   0   0   0   0  |
+ *           |  0   0   0   0   1   0   0   0  |
+ *           |  0   0   0   0   0   1   0   0  |
+ *           |  0   0   0   0   0   0   1   0  |
+ *           |  0   0   0   0   0   0   0   1  |
+ *           ~~                               ~~
+ *           __                               __
+ *           |  1   1   1   1   1   1   1   1  |
+ *           | 128  64  32  16  8   4   2   1  |
+ *           |  19 205 116  29  64  16  4   1  |
+ *           |  1   0   0   0   0   0   0   0  |
+ *           |  0   1   0   0   0   0   0   0  |
+ *  (V|I)' = |  0   0   1   0   0   0   0   0  |
+ *           |  0   0   0   1   0   0   0   0  |
+ *           |  0   0   0   0   1   0   0   0  |
+ *           |  0   0   0   0   0   1   0   0  |
+ *           |  0   0   0   0   0   0   1   0  |
+ *           |  0   0   0   0   0   0   0   1  |
+ *           ~~                               ~~
+ *
+ * Here we employ Gauss-Jordan elimination to find the inverse of (V|I)'. We
+ * have carefully chosen the seed values 1, 2, and 4 to ensure that this
+ * matrix is not singular.
+ * __                                                                 __
+ * |  1   1   1   1   1   1   1   1     1   0   0   0   0   0   0   0  |
+ * |  19 205 116  29  64  16  4   1     0   1   0   0   0   0   0   0  |
+ * |  1   0   0   0   0   0   0   0     0   0   1   0   0   0   0   0  |
+ * |  0   0   0   1   0   0   0   0     0   0   0   1   0   0   0   0  |
+ * |  0   0   0   0   1   0   0   0     0   0   0   0   1   0   0   0  |
+ * |  0   0   0   0   0   1   0   0     0   0   0   0   0   1   0   0  |
+ * |  0   0   0   0   0   0   1   0     0   0   0   0   0   0   1   0  |
+ * |  0   0   0   0   0   0   0   1     0   0   0   0   0   0   0   1  |
+ * ~~                                                                 ~~
+ * __                                                                 __
+ * |  1   0   0   0   0   0   0   0     0   0   1   0   0   0   0   0  |
+ * |  1   1   1   1   1   1   1   1     1   0   0   0   0   0   0   0  |
+ * |  19 205 116  29  64  16  4   1     0   1   0   0   0   0   0   0  |
+ * |  0   0   0   1   0   0   0   0     0   0   0   1   0   0   0   0  |
+ * |  0   0   0   0   1   0   0   0     0   0   0   0   1   0   0   0  |
+ * |  0   0   0   0   0   1   0   0     0   0   0   0   0   1   0   0  |
+ * |  0   0   0   0   0   0   1   0     0   0   0   0   0   0   1   0  |
+ * |  0   0   0   0   0   0   0   1     0   0   0   0   0   0   0   1  |
+ * ~~                                                                 ~~
+ * __                                                                 __
+ * |  1   0   0   0   0   0   0   0     0   0   1   0   0   0   0   0  |
+ * |  0   1   1   0   0   0   0   0     1   0   1   1   1   1   1   1  |
+ * |  0  205 116  0   0   0   0   0     0   1   19  29  64  16  4   1  |
+ * |  0   0   0   1   0   0   0   0     0   0   0   1   0   0   0   0  |
+ * |  0   0   0   0   1   0   0   0     0   0   0   0   1   0   0   0  |
+ * |  0   0   0   0   0   1   0   0     0   0   0   0   0   1   0   0  |
+ * |  0   0   0   0   0   0   1   0     0   0   0   0   0   0   1   0  |
+ * |  0   0   0   0   0   0   0   1     0   0   0   0   0   0   0   1  |
+ * ~~                                                                 ~~
+ * __                                                                 __
+ * |  1   0   0   0   0   0   0   0     0   0   1   0   0   0   0   0  |
+ * |  0   1   1   0   0   0   0   0     1   0   1   1   1   1   1   1  |
+ * |  0   0  185  0   0   0   0   0    205  1  222 208 141 221 201 204 |
+ * |  0   0   0   1   0   0   0   0     0   0   0   1   0   0   0   0  |
+ * |  0   0   0   0   1   0   0   0     0   0   0   0   1   0   0   0  |
+ * |  0   0   0   0   0   1   0   0     0   0   0   0   0   1   0   0  |
+ * |  0   0   0   0   0   0   1   0     0   0   0   0   0   0   1   0  |
+ * |  0   0   0   0   0   0   0   1     0   0   0   0   0   0   0   1  |
+ * ~~                                                                 ~~
+ * __                                                                 __
+ * |  1   0   0   0   0   0   0   0     0   0   1   0   0   0   0   0  |
+ * |  0   1   1   0   0   0   0   0     1   0   1   1   1   1   1   1  |
+ * |  0   0   1   0   0   0   0   0    166 100  4   40 158 168 216 209 |
+ * |  0   0   0   1   0   0   0   0     0   0   0   1   0   0   0   0  |
+ * |  0   0   0   0   1   0   0   0     0   0   0   0   1   0   0   0  |
+ * |  0   0   0   0   0   1   0   0     0   0   0   0   0   1   0   0  |
+ * |  0   0   0   0   0   0   1   0     0   0   0   0   0   0   1   0  |
+ * |  0   0   0   0   0   0   0   1     0   0   0   0   0   0   0   1  |
+ * ~~                                                                 ~~
+ * __                                                                 __
+ * |  1   0   0   0   0   0   0   0     0   0   1   0   0   0   0   0  |
+ * |  0   1   0   0   0   0   0   0    167 100  5   41 159 169 217 208 |
+ * |  0   0   1   0   0   0   0   0    166 100  4   40 158 168 216 209 |
+ * |  0   0   0   1   0   0   0   0     0   0   0   1   0   0   0   0  |
+ * |  0   0   0   0   1   0   0   0     0   0   0   0   1   0   0   0  |
+ * |  0   0   0   0   0   1   0   0     0   0   0   0   0   1   0   0  |
+ * |  0   0   0   0   0   0   1   0     0   0   0   0   0   0   1   0  |
+ * |  0   0   0   0   0   0   0   1     0   0   0   0   0   0   0   1  |
+ * ~~                                                                 ~~
+ *                   __                               __
+ *                   |  0   0   1   0   0   0   0   0  |
+ *                   | 167 100  5   41 159 169 217 208 |
+ *                   | 166 100  4   40 158 168 216 209 |
+ *       (V|I)'^-1 = |  0   0   0   1   0   0   0   0  |
+ *                   |  0   0   0   0   1   0   0   0  |
+ *                   |  0   0   0   0   0   1   0   0  |
+ *                   |  0   0   0   0   0   0   1   0  |
+ *                   |  0   0   0   0   0   0   0   1  |
+ *                   ~~                               ~~
+ *
+ * We can then simply compute D = (V|I)'^-1 x (d|p)' to discover the values
+ * of the missing data.
+ *
+ * As is apparent from the example above, the only non-trivial rows in the
+ * inverse matrix correspond to the data disks that we're trying to
+ * reconstruct. Indeed, those are the only rows we need as the others would
+ * only be useful for reconstructing data known or assumed to be valid. For
+ * that reason, we only build the coefficients in the rows that correspond to
+ * targeted columns.
+ */
+/* END CSTYLED */
+
+static void
+vdev_raidz_matrix_init(raidz_map_t *rm, int n, int nmap, int *map,
+    uint8_t **rows)
+{
+	int i, j;
+	int pow;
+
+	ASSERT(n == rm->rm_cols - rm->rm_firstdatacol);
+
+	/*
+	 * Fill in the missing rows of interest.
+	 */
+	for (i = 0; i < nmap; i++) {
+		ASSERT3S(0, <=, map[i]);
+		ASSERT3S(map[i], <=, 2);
+
+		pow = map[i] * n;
+		if (pow > 255)
+			pow -= 255;
+		ASSERT(pow <= 255);
+
+		for (j = 0; j < n; j++) {
+			pow -= map[i];
+			if (pow < 0)
+				pow += 255;
+			rows[i][j] = vdev_raidz_pow2[pow];
+		}
+	}
+}
+
+static void
+vdev_raidz_matrix_invert(raidz_map_t *rm, int n, int nmissing, int *missing,
+    uint8_t **rows, uint8_t **invrows, const uint8_t *used)
+{
+	int i, j, ii, jj;
+	uint8_t log;
+
+	/*
+	 * Assert that the first nmissing entries from the array of used
+	 * columns correspond to parity columns and that subsequent entries
+	 * correspond to data columns.
+	 */
+	for (i = 0; i < nmissing; i++) {
+		ASSERT3S(used[i], <, rm->rm_firstdatacol);
+	}
+	for (; i < n; i++) {
+		ASSERT3S(used[i], >=, rm->rm_firstdatacol);
+	}
+
+	/*
+	 * First initialize the storage where we'll compute the inverse rows.
+	 */
+	for (i = 0; i < nmissing; i++) {
+		for (j = 0; j < n; j++) {
+			invrows[i][j] = (i == j) ? 1 : 0;
+		}
+	}
+
+	/*
+	 * Subtract all trivial rows from the rows of consequence.
+	 */
+	for (i = 0; i < nmissing; i++) {
+		for (j = nmissing; j < n; j++) {
+			ASSERT3U(used[j], >=, rm->rm_firstdatacol);
+			jj = used[j] - rm->rm_firstdatacol;
+			ASSERT3S(jj, <, n);
+			invrows[i][j] = rows[i][jj];
+			rows[i][jj] = 0;
+		}
+	}
+
+	/*
+	 * For each of the rows of interest, we must normalize it and subtract
+	 * a multiple of it from the other rows.
+	 */
+	for (i = 0; i < nmissing; i++) {
+		for (j = 0; j < missing[i]; j++) {
+			ASSERT0(rows[i][j]);
+		}
+		ASSERT3U(rows[i][missing[i]], !=, 0);
+
+		/*
+		 * Compute the inverse of the first element and multiply each
+		 * element in the row by that value.
+		 */
+		log = 255 - vdev_raidz_log2[rows[i][missing[i]]];
+
+		for (j = 0; j < n; j++) {
+			rows[i][j] = vdev_raidz_exp2(rows[i][j], log);
+			invrows[i][j] = vdev_raidz_exp2(invrows[i][j], log);
+		}
+
+		for (ii = 0; ii < nmissing; ii++) {
+			if (i == ii)
+				continue;
+
+			ASSERT3U(rows[ii][missing[i]], !=, 0);
+
+			log = vdev_raidz_log2[rows[ii][missing[i]]];
+
+			for (j = 0; j < n; j++) {
+				rows[ii][j] ^=
+				    vdev_raidz_exp2(rows[i][j], log);
+				invrows[ii][j] ^=
+				    vdev_raidz_exp2(invrows[i][j], log);
+			}
+		}
+	}
+
+	/*
+	 * Verify that the data that is left in the rows are properly part of
+	 * an identity matrix.
+	 */
+	for (i = 0; i < nmissing; i++) {
+		for (j = 0; j < n; j++) {
+			if (j == missing[i]) {
+				ASSERT3U(rows[i][j], ==, 1);
+			} else {
+				ASSERT0(rows[i][j]);
+			}
+		}
+	}
+}
+
+static void
+vdev_raidz_matrix_reconstruct(raidz_map_t *rm, int n, int nmissing,
+    int *missing, uint8_t **invrows, const uint8_t *used)
+{
+	int i, j, x, cc, c;
+	uint8_t *src;
+	uint64_t ccount;
+	uint8_t *dst[VDEV_RAIDZ_MAXPARITY];
+	uint64_t dcount[VDEV_RAIDZ_MAXPARITY];
+	uint8_t log = 0;
+	uint8_t val;
+	int ll;
+	uint8_t *invlog[VDEV_RAIDZ_MAXPARITY];
+	uint8_t *p, *pp;
+	size_t psize;
+
+	psize = sizeof (invlog[0][0]) * n * nmissing;
+	p = kmem_alloc(psize, KM_SLEEP);
+
+	for (pp = p, i = 0; i < nmissing; i++) {
+		invlog[i] = pp;
+		pp += n;
+	}
+
+	for (i = 0; i < nmissing; i++) {
+		for (j = 0; j < n; j++) {
+			ASSERT3U(invrows[i][j], !=, 0);
+			invlog[i][j] = vdev_raidz_log2[invrows[i][j]];
+		}
+	}
+
+	for (i = 0; i < n; i++) {
+		c = used[i];
+		ASSERT3U(c, <, rm->rm_cols);
+
+		src = rm->rm_col[c].rc_data;
+		ccount = rm->rm_col[c].rc_size;
+		for (j = 0; j < nmissing; j++) {
+			cc = missing[j] + rm->rm_firstdatacol;
+			ASSERT3U(cc, >=, rm->rm_firstdatacol);
+			ASSERT3U(cc, <, rm->rm_cols);
+			ASSERT3U(cc, !=, c);
+
+			dst[j] = rm->rm_col[cc].rc_data;
+			dcount[j] = rm->rm_col[cc].rc_size;
+		}
+
+		ASSERT(ccount >= rm->rm_col[missing[0]].rc_size || i > 0);
+
+		for (x = 0; x < ccount; x++, src++) {
+			if (*src != 0)
+				log = vdev_raidz_log2[*src];
+
+			for (cc = 0; cc < nmissing; cc++) {
+				if (x >= dcount[cc])
+					continue;
+
+				if (*src == 0) {
+					val = 0;
+				} else {
+					if ((ll = log + invlog[cc][i]) >= 255)
+						ll -= 255;
+					val = vdev_raidz_pow2[ll];
+				}
+
+				if (i == 0)
+					dst[cc][x] = val;
+				else
+					dst[cc][x] ^= val;
+			}
+		}
+	}
+
+	kmem_free(p, psize);
+}
+
+static int
+vdev_raidz_reconstruct_general(raidz_map_t *rm, int *tgts, int ntgts)
+{
+	int n, i, c, t, tt;
+	int nmissing_rows;
+	int missing_rows[VDEV_RAIDZ_MAXPARITY];
+	int parity_map[VDEV_RAIDZ_MAXPARITY];
+
+	uint8_t *p, *pp;
+	size_t psize;
+
+	uint8_t *rows[VDEV_RAIDZ_MAXPARITY];
+	uint8_t *invrows[VDEV_RAIDZ_MAXPARITY];
+	uint8_t *used;
+
+	int code = 0;
+
+
+	n = rm->rm_cols - rm->rm_firstdatacol;
+
+	/*
+	 * Figure out which data columns are missing.
+	 */
+	nmissing_rows = 0;
+	for (t = 0; t < ntgts; t++) {
+		if (tgts[t] >= rm->rm_firstdatacol) {
+			missing_rows[nmissing_rows++] =
+			    tgts[t] - rm->rm_firstdatacol;
+		}
+	}
+
+	/*
+	 * Figure out which parity columns to use to help generate the missing
+	 * data columns.
+	 */
+	for (tt = 0, c = 0, i = 0; i < nmissing_rows; c++) {
+		ASSERT(tt < ntgts);
+		ASSERT(c < rm->rm_firstdatacol);
+
+		/*
+		 * Skip any targeted parity columns.
+		 */
+		if (c == tgts[tt]) {
+			tt++;
+			continue;
+		}
+
+		code |= 1 << c;
+
+		parity_map[i] = c;
+		i++;
+	}
+
+	ASSERT(code != 0);
+	ASSERT3U(code, <, 1 << VDEV_RAIDZ_MAXPARITY);
+
+	psize = (sizeof (rows[0][0]) + sizeof (invrows[0][0])) *
+	    nmissing_rows * n + sizeof (used[0]) * n;
+	p = kmem_alloc(psize, KM_SLEEP);
+
+	for (pp = p, i = 0; i < nmissing_rows; i++) {
+		rows[i] = pp;
+		pp += n;
+		invrows[i] = pp;
+		pp += n;
+	}
+	used = pp;
+
+	for (i = 0; i < nmissing_rows; i++) {
+		used[i] = parity_map[i];
+	}
+
+	for (tt = 0, c = rm->rm_firstdatacol; c < rm->rm_cols; c++) {
+		if (tt < nmissing_rows &&
+		    c == missing_rows[tt] + rm->rm_firstdatacol) {
+			tt++;
+			continue;
+		}
+
+		ASSERT3S(i, <, n);
+		used[i] = c;
+		i++;
+	}
+
+	/*
+	 * Initialize the interesting rows of the matrix.
+	 */
+	vdev_raidz_matrix_init(rm, n, nmissing_rows, parity_map, rows);
+
+	/*
+	 * Invert the matrix.
+	 */
+	vdev_raidz_matrix_invert(rm, n, nmissing_rows, missing_rows, rows,
+	    invrows, used);
+
+	/*
+	 * Reconstruct the missing data using the generated matrix.
+	 */
+	vdev_raidz_matrix_reconstruct(rm, n, nmissing_rows, missing_rows,
+	    invrows, used);
+
+	kmem_free(p, psize);
+
+	return (code);
+}
+
+static int
+vdev_raidz_reconstruct(raidz_map_t *rm, int *t, int nt)
+{
+	int tgts[VDEV_RAIDZ_MAXPARITY], *dt;
+	int ntgts;
+	int i, c;
+	int code;
+	int nbadparity, nbaddata;
+	int parity_valid[VDEV_RAIDZ_MAXPARITY];
+
+	/*
+	 * The tgts list must already be sorted.
+	 */
+	for (i = 1; i < nt; i++) {
+		ASSERT(t[i] > t[i - 1]);
+	}
+
+	nbadparity = rm->rm_firstdatacol;
+	nbaddata = rm->rm_cols - nbadparity;
+	ntgts = 0;
+	for (i = 0, c = 0; c < rm->rm_cols; c++) {
+		if (c < rm->rm_firstdatacol)
+			parity_valid[c] = B_FALSE;
+
+		if (i < nt && c == t[i]) {
+			tgts[ntgts++] = c;
+			i++;
+		} else if (rm->rm_col[c].rc_error != 0) {
+			tgts[ntgts++] = c;
+		} else if (c >= rm->rm_firstdatacol) {
+			nbaddata--;
+		} else {
+			parity_valid[c] = B_TRUE;
+			nbadparity--;
+		}
+	}
+
+	ASSERT(ntgts >= nt);
+	ASSERT(nbaddata >= 0);
+	ASSERT(nbaddata + nbadparity == ntgts);
+
+	dt = &tgts[nbadparity];
+
+	/*
+	 * See if we can use any of our optimized reconstruction routines.
+	 */
+	if (!vdev_raidz_default_to_general) {
+		switch (nbaddata) {
+		case 1:
+			if (parity_valid[VDEV_RAIDZ_P])
+				return (vdev_raidz_reconstruct_p(rm, dt, 1));
+
+			ASSERT(rm->rm_firstdatacol > 1);
+
+			if (parity_valid[VDEV_RAIDZ_Q])
+				return (vdev_raidz_reconstruct_q(rm, dt, 1));
+
+			ASSERT(rm->rm_firstdatacol > 2);
+			break;
+
+		case 2:
+			ASSERT(rm->rm_firstdatacol > 1);
+
+			if (parity_valid[VDEV_RAIDZ_P] &&
+			    parity_valid[VDEV_RAIDZ_Q])
+				return (vdev_raidz_reconstruct_pq(rm, dt, 2));
+
+			ASSERT(rm->rm_firstdatacol > 2);
+
+			break;
+		}
+	}
+
+	code = vdev_raidz_reconstruct_general(rm, tgts, ntgts);
+	ASSERT(code < (1 << VDEV_RAIDZ_MAXPARITY));
+	ASSERT(code > 0);
+	return (code);
+}
+
+static int
+vdev_raidz_open(vdev_t *vd, uint64_t *asize, uint64_t *max_asize,
+    uint64_t *ashift)
+{
+	vdev_t *cvd;
+	uint64_t nparity = vd->vdev_nparity;
+	int c;
+	int lasterror = 0;
+	int numerrors = 0;
+
+	ASSERT(nparity > 0);
+
+	if (nparity > VDEV_RAIDZ_MAXPARITY ||
+	    vd->vdev_children < nparity + 1) {
+		vd->vdev_stat.vs_aux = VDEV_AUX_BAD_LABEL;
+		return (SET_ERROR(EINVAL));
+	}
+
+	vdev_open_children(vd);
+
+	for (c = 0; c < vd->vdev_children; c++) {
+		cvd = vd->vdev_child[c];
+
+		if (cvd->vdev_open_error != 0) {
+			lasterror = cvd->vdev_open_error;
+			numerrors++;
+			continue;
+		}
+
+		*asize = MIN(*asize - 1, cvd->vdev_asize - 1) + 1;
+		*max_asize = MIN(*max_asize - 1, cvd->vdev_max_asize - 1) + 1;
+		*ashift = MAX(*ashift, cvd->vdev_ashift);
+	}
+
+	*asize *= vd->vdev_children;
+	*max_asize *= vd->vdev_children;
+
+	if (numerrors > nparity) {
+		vd->vdev_stat.vs_aux = VDEV_AUX_NO_REPLICAS;
+		return (lasterror);
+	}
+
+	return (0);
+}
+
+static void
+vdev_raidz_close(vdev_t *vd)
+{
+	int c;
+
+	for (c = 0; c < vd->vdev_children; c++)
+		vdev_close(vd->vdev_child[c]);
+}
+
+static uint64_t
+vdev_raidz_asize(vdev_t *vd, uint64_t psize)
+{
+	uint64_t asize;
+	uint64_t ashift = vd->vdev_top->vdev_ashift;
+	uint64_t cols = vd->vdev_children;
+	uint64_t nparity = vd->vdev_nparity;
+
+	asize = ((psize - 1) >> ashift) + 1;
+	asize += nparity * ((asize + cols - nparity - 1) / (cols - nparity));
+	asize = roundup(asize, nparity + 1) << ashift;
+
+	return (asize);
+}
+
+static void
+vdev_raidz_child_done(zio_t *zio)
+{
+	raidz_col_t *rc = zio->io_private;
+
+	rc->rc_error = zio->io_error;
+	rc->rc_tried = 1;
+	rc->rc_skipped = 0;
+}
+
+/*
+ * Start an IO operation on a RAIDZ VDev
+ *
+ * Outline:
+ * - For write operations:
+ *   1. Generate the parity data
+ *   2. Create child zio write operations to each column's vdev, for both
+ *      data and parity.
+ *   3. If the column skips any sectors for padding, create optional dummy
+ *      write zio children for those areas to improve aggregation continuity.
+ * - For read operations:
+ *   1. Create child zio read operations to each data column's vdev to read
+ *      the range of data required for zio.
+ *   2. If this is a scrub or resilver operation, or if any of the data
+ *      vdevs have had errors, then create zio read operations to the parity
+ *      columns' VDevs as well.
+ */
+static void
+vdev_raidz_io_start(zio_t *zio)
+{
+	vdev_t *vd = zio->io_vd;
+	vdev_t *tvd = vd->vdev_top;
+	vdev_t *cvd;
+	raidz_map_t *rm;
+	raidz_col_t *rc;
+	int c, i;
+
+	rm = vdev_raidz_map_alloc(zio, tvd->vdev_ashift, vd->vdev_children,
+	    vd->vdev_nparity);
+
+	ASSERT3U(rm->rm_asize, ==, vdev_psize_to_asize(vd, zio->io_size));
+
+	if (zio->io_type == ZIO_TYPE_WRITE) {
+		vdev_raidz_generate_parity(rm);
+
+		for (c = 0; c < rm->rm_cols; c++) {
+			rc = &rm->rm_col[c];
+			cvd = vd->vdev_child[rc->rc_devidx];
+			zio_nowait(zio_vdev_child_io(zio, NULL, cvd,
+			    rc->rc_offset, rc->rc_data, rc->rc_size,
+			    zio->io_type, zio->io_priority, 0,
+			    vdev_raidz_child_done, rc));
+		}
+
+		/*
+		 * Generate optional I/Os for any skipped sectors to improve
+		 * aggregation contiguity.
+		 */
+		for (c = rm->rm_skipstart, i = 0; i < rm->rm_nskip; c++, i++) {
+			ASSERT(c <= rm->rm_scols);
+			if (c == rm->rm_scols)
+				c = 0;
+			rc = &rm->rm_col[c];
+			cvd = vd->vdev_child[rc->rc_devidx];
+			zio_nowait(zio_vdev_child_io(zio, NULL, cvd,
+			    rc->rc_offset + rc->rc_size, NULL,
+			    1 << tvd->vdev_ashift,
+			    zio->io_type, zio->io_priority,
+			    ZIO_FLAG_NODATA | ZIO_FLAG_OPTIONAL, NULL, NULL));
+		}
+
+		zio_execute(zio);
+		return;
+	}
+
+	ASSERT(zio->io_type == ZIO_TYPE_READ);
+
+	/*
+	 * Iterate over the columns in reverse order so that we hit the parity
+	 * last -- any errors along the way will force us to read the parity.
+	 */
+	for (c = rm->rm_cols - 1; c >= 0; c--) {
+		rc = &rm->rm_col[c];
+		cvd = vd->vdev_child[rc->rc_devidx];
+		if (!vdev_readable(cvd)) {
+			if (c >= rm->rm_firstdatacol)
+				rm->rm_missingdata++;
+			else
+				rm->rm_missingparity++;
+			rc->rc_error = SET_ERROR(ENXIO);
+			rc->rc_tried = 1;	/* don't even try */
+			rc->rc_skipped = 1;
+			continue;
+		}
+		if (vdev_dtl_contains(cvd, DTL_MISSING, zio->io_txg, 1)) {
+			if (c >= rm->rm_firstdatacol)
+				rm->rm_missingdata++;
+			else
+				rm->rm_missingparity++;
+			rc->rc_error = SET_ERROR(ESTALE);
+			rc->rc_skipped = 1;
+			continue;
+		}
+		if (c >= rm->rm_firstdatacol || rm->rm_missingdata > 0 ||
+		    (zio->io_flags & (ZIO_FLAG_SCRUB | ZIO_FLAG_RESILVER))) {
+			zio_nowait(zio_vdev_child_io(zio, NULL, cvd,
+			    rc->rc_offset, rc->rc_data, rc->rc_size,
+			    zio->io_type, zio->io_priority, 0,
+			    vdev_raidz_child_done, rc));
+		}
+	}
+
+	zio_execute(zio);
+}
+
+
+/*
+ * Report a checksum error for a child of a RAID-Z device.
+ */
+static void
+raidz_checksum_error(zio_t *zio, raidz_col_t *rc, void *bad_data)
+{
+	vdev_t *vd = zio->io_vd->vdev_child[rc->rc_devidx];
+
+	if (!(zio->io_flags & ZIO_FLAG_SPECULATIVE)) {
+		zio_bad_cksum_t zbc;
+		raidz_map_t *rm = zio->io_vsd;
+
+		mutex_enter(&vd->vdev_stat_lock);
+		vd->vdev_stat.vs_checksum_errors++;
+		mutex_exit(&vd->vdev_stat_lock);
+
+		zbc.zbc_has_cksum = 0;
+		zbc.zbc_injected = rm->rm_ecksuminjected;
+
+		zfs_ereport_post_checksum(zio->io_spa, vd, zio,
+		    rc->rc_offset, rc->rc_size, rc->rc_data, bad_data,
+		    &zbc);
+	}
+}
+
+/*
+ * We keep track of whether or not there were any injected errors, so that
+ * any ereports we generate can note it.
+ */
+static int
+raidz_checksum_verify(zio_t *zio)
+{
+	zio_bad_cksum_t zbc;
+	raidz_map_t *rm = zio->io_vsd;
+	int ret;
+
+	bzero(&zbc, sizeof (zio_bad_cksum_t));
+
+	ret = zio_checksum_error(zio, &zbc);
+	if (ret != 0 && zbc.zbc_injected != 0)
+		rm->rm_ecksuminjected = 1;
+
+	return (ret);
+}
+
+/*
+ * Generate the parity from the data columns. If we tried and were able to
+ * read the parity without error, verify that the generated parity matches the
+ * data we read. If it doesn't, we fire off a checksum error. Return the
+ * number such failures.
+ */
+static int
+raidz_parity_verify(zio_t *zio, raidz_map_t *rm)
+{
+	void *orig[VDEV_RAIDZ_MAXPARITY];
+	int c, ret = 0;
+	raidz_col_t *rc;
+
+	for (c = 0; c < rm->rm_firstdatacol; c++) {
+		rc = &rm->rm_col[c];
+		if (!rc->rc_tried || rc->rc_error != 0)
+			continue;
+		orig[c] = zio_buf_alloc(rc->rc_size);
+		bcopy(rc->rc_data, orig[c], rc->rc_size);
+	}
+
+	vdev_raidz_generate_parity(rm);
+
+	for (c = 0; c < rm->rm_firstdatacol; c++) {
+		rc = &rm->rm_col[c];
+		if (!rc->rc_tried || rc->rc_error != 0)
+			continue;
+		if (bcmp(orig[c], rc->rc_data, rc->rc_size) != 0) {
+			raidz_checksum_error(zio, rc, orig[c]);
+			rc->rc_error = SET_ERROR(ECKSUM);
+			ret++;
+		}
+		zio_buf_free(orig[c], rc->rc_size);
+	}
+
+	return (ret);
+}
+
+/*
+ * Keep statistics on all the ways that we used parity to correct data.
+ */
+static uint64_t raidz_corrected[1 << VDEV_RAIDZ_MAXPARITY];
+
+static int
+vdev_raidz_worst_error(raidz_map_t *rm)
+{
+	int c, error = 0;
+
+	for (c = 0; c < rm->rm_cols; c++)
+		error = zio_worst_error(error, rm->rm_col[c].rc_error);
+
+	return (error);
+}
+
+/*
+ * Iterate over all combinations of bad data and attempt a reconstruction.
+ * Note that the algorithm below is non-optimal because it doesn't take into
+ * account how reconstruction is actually performed. For example, with
+ * triple-parity RAID-Z the reconstruction procedure is the same if column 4
+ * is targeted as invalid as if columns 1 and 4 are targeted since in both
+ * cases we'd only use parity information in column 0.
+ */
+static int
+vdev_raidz_combrec(zio_t *zio, int total_errors, int data_errors)
+{
+	raidz_map_t *rm = zio->io_vsd;
+	raidz_col_t *rc;
+	void *orig[VDEV_RAIDZ_MAXPARITY];
+	int tstore[VDEV_RAIDZ_MAXPARITY + 2];
+	int *tgts = &tstore[1];
+	int curr, next, i, c, n;
+	int code, ret = 0;
+
+	ASSERT(total_errors < rm->rm_firstdatacol);
+
+	/*
+	 * This simplifies one edge condition.
+	 */
+	tgts[-1] = -1;
+
+	for (n = 1; n <= rm->rm_firstdatacol - total_errors; n++) {
+		/*
+		 * Initialize the targets array by finding the first n columns
+		 * that contain no error.
+		 *
+		 * If there were no data errors, we need to ensure that we're
+		 * always explicitly attempting to reconstruct at least one
+		 * data column. To do this, we simply push the highest target
+		 * up into the data columns.
+		 */
+		for (c = 0, i = 0; i < n; i++) {
+			if (i == n - 1 && data_errors == 0 &&
+			    c < rm->rm_firstdatacol) {
+				c = rm->rm_firstdatacol;
+			}
+
+			while (rm->rm_col[c].rc_error != 0) {
+				c++;
+				ASSERT3S(c, <, rm->rm_cols);
+			}
+
+			tgts[i] = c++;
+		}
+
+		/*
+		 * Setting tgts[n] simplifies the other edge condition.
+		 */
+		tgts[n] = rm->rm_cols;
+
+		/*
+		 * These buffers were allocated in previous iterations.
+		 */
+		for (i = 0; i < n - 1; i++) {
+			ASSERT(orig[i] != NULL);
+		}
+
+		orig[n - 1] = zio_buf_alloc(rm->rm_col[0].rc_size);
+
+		curr = 0;
+		next = tgts[curr];
+
+		while (curr != n) {
+			tgts[curr] = next;
+			curr = 0;
+
+			/*
+			 * Save off the original data that we're going to
+			 * attempt to reconstruct.
+			 */
+			for (i = 0; i < n; i++) {
+				ASSERT(orig[i] != NULL);
+				c = tgts[i];
+				ASSERT3S(c, >=, 0);
+				ASSERT3S(c, <, rm->rm_cols);
+				rc = &rm->rm_col[c];
+				bcopy(rc->rc_data, orig[i], rc->rc_size);
+			}
+
+			/*
+			 * Attempt a reconstruction and exit the outer loop on
+			 * success.
+			 */
+			code = vdev_raidz_reconstruct(rm, tgts, n);
+			if (raidz_checksum_verify(zio) == 0) {
+				atomic_inc_64(&raidz_corrected[code]);
+
+				for (i = 0; i < n; i++) {
+					c = tgts[i];
+					rc = &rm->rm_col[c];
+					ASSERT(rc->rc_error == 0);
+					if (rc->rc_tried)
+						raidz_checksum_error(zio, rc,
+						    orig[i]);
+					rc->rc_error = SET_ERROR(ECKSUM);
+				}
+
+				ret = code;
+				goto done;
+			}
+
+			/*
+			 * Restore the original data.
+			 */
+			for (i = 0; i < n; i++) {
+				c = tgts[i];
+				rc = &rm->rm_col[c];
+				bcopy(orig[i], rc->rc_data, rc->rc_size);
+			}
+
+			do {
+				/*
+				 * Find the next valid column after the curr
+				 * position..
+				 */
+				for (next = tgts[curr] + 1;
+				    next < rm->rm_cols &&
+				    rm->rm_col[next].rc_error != 0; next++)
+					continue;
+
+				ASSERT(next <= tgts[curr + 1]);
+
+				/*
+				 * If that spot is available, we're done here.
+				 */
+				if (next != tgts[curr + 1])
+					break;
+
+				/*
+				 * Otherwise, find the next valid column after
+				 * the previous position.
+				 */
+				for (c = tgts[curr - 1] + 1;
+				    rm->rm_col[c].rc_error != 0; c++)
+					continue;
+
+				tgts[curr] = c;
+				curr++;
+
+			} while (curr != n);
+		}
+	}
+	n--;
+done:
+	for (i = 0; i < n; i++) {
+		zio_buf_free(orig[i], rm->rm_col[0].rc_size);
+	}
+
+	return (ret);
+}
+
+/*
+ * Complete an IO operation on a RAIDZ VDev
+ *
+ * Outline:
+ * - For write operations:
+ *   1. Check for errors on the child IOs.
+ *   2. Return, setting an error code if too few child VDevs were written
+ *      to reconstruct the data later.  Note that partial writes are
+ *      considered successful if they can be reconstructed at all.
+ * - For read operations:
+ *   1. Check for errors on the child IOs.
+ *   2. If data errors occurred:
+ *      a. Try to reassemble the data from the parity available.
+ *      b. If we haven't yet read the parity drives, read them now.
+ *      c. If all parity drives have been read but the data still doesn't
+ *         reassemble with a correct checksum, then try combinatorial
+ *         reconstruction.
+ *      d. If that doesn't work, return an error.
+ *   3. If there were unexpected errors or this is a resilver operation,
+ *      rewrite the vdevs that had errors.
+ */
+static void
+vdev_raidz_io_done(zio_t *zio)
+{
+	vdev_t *vd = zio->io_vd;
+	vdev_t *cvd;
+	raidz_map_t *rm = zio->io_vsd;
+	raidz_col_t *rc = NULL;
+	int unexpected_errors = 0;
+	int parity_errors = 0;
+	int parity_untried = 0;
+	int data_errors = 0;
+	int total_errors = 0;
+	int n, c;
+	int tgts[VDEV_RAIDZ_MAXPARITY];
+	int code;
+
+	ASSERT(zio->io_bp != NULL);  /* XXX need to add code to enforce this */
+
+	ASSERT(rm->rm_missingparity <= rm->rm_firstdatacol);
+	ASSERT(rm->rm_missingdata <= rm->rm_cols - rm->rm_firstdatacol);
+
+	for (c = 0; c < rm->rm_cols; c++) {
+		rc = &rm->rm_col[c];
+
+		if (rc->rc_error) {
+			ASSERT(rc->rc_error != ECKSUM);	/* child has no bp */
+
+			if (c < rm->rm_firstdatacol)
+				parity_errors++;
+			else
+				data_errors++;
+
+			if (!rc->rc_skipped)
+				unexpected_errors++;
+
+			total_errors++;
+		} else if (c < rm->rm_firstdatacol && !rc->rc_tried) {
+			parity_untried++;
+		}
+	}
+
+	if (zio->io_type == ZIO_TYPE_WRITE) {
+		/*
+		 * XXX -- for now, treat partial writes as a success.
+		 * (If we couldn't write enough columns to reconstruct
+		 * the data, the I/O failed.  Otherwise, good enough.)
+		 *
+		 * Now that we support write reallocation, it would be better
+		 * to treat partial failure as real failure unless there are
+		 * no non-degraded top-level vdevs left, and not update DTLs
+		 * if we intend to reallocate.
+		 */
+		/* XXPOLICY */
+		if (total_errors > rm->rm_firstdatacol)
+			zio->io_error = vdev_raidz_worst_error(rm);
+
+		return;
+	}
+
+	ASSERT(zio->io_type == ZIO_TYPE_READ);
+	/*
+	 * There are three potential phases for a read:
+	 *	1. produce valid data from the columns read
+	 *	2. read all disks and try again
+	 *	3. perform combinatorial reconstruction
+	 *
+	 * Each phase is progressively both more expensive and less likely to
+	 * occur. If we encounter more errors than we can repair or all phases
+	 * fail, we have no choice but to return an error.
+	 */
+
+	/*
+	 * If the number of errors we saw was correctable -- less than or equal
+	 * to the number of parity disks read -- attempt to produce data that
+	 * has a valid checksum. Naturally, this case applies in the absence of
+	 * any errors.
+	 */
+	if (total_errors <= rm->rm_firstdatacol - parity_untried) {
+		if (data_errors == 0) {
+			if (raidz_checksum_verify(zio) == 0) {
+				/*
+				 * If we read parity information (unnecessarily
+				 * as it happens since no reconstruction was
+				 * needed) regenerate and verify the parity.
+				 * We also regenerate parity when resilvering
+				 * so we can write it out to the failed device
+				 * later.
+				 */
+				if (parity_errors + parity_untried <
+				    rm->rm_firstdatacol ||
+				    (zio->io_flags & ZIO_FLAG_RESILVER)) {
+					n = raidz_parity_verify(zio, rm);
+					unexpected_errors += n;
+					ASSERT(parity_errors + n <=
+					    rm->rm_firstdatacol);
+				}
+				goto done;
+			}
+		} else {
+			/*
+			 * We either attempt to read all the parity columns or
+			 * none of them. If we didn't try to read parity, we
+			 * wouldn't be here in the correctable case. There must
+			 * also have been fewer parity errors than parity
+			 * columns or, again, we wouldn't be in this code path.
+			 */
+			ASSERT(parity_untried == 0);
+			ASSERT(parity_errors < rm->rm_firstdatacol);
+
+			/*
+			 * Identify the data columns that reported an error.
+			 */
+			n = 0;
+			for (c = rm->rm_firstdatacol; c < rm->rm_cols; c++) {
+				rc = &rm->rm_col[c];
+				if (rc->rc_error != 0) {
+					ASSERT(n < VDEV_RAIDZ_MAXPARITY);
+					tgts[n++] = c;
+				}
+			}
+
+			ASSERT(rm->rm_firstdatacol >= n);
+
+			code = vdev_raidz_reconstruct(rm, tgts, n);
+
+			if (raidz_checksum_verify(zio) == 0) {
+				atomic_inc_64(&raidz_corrected[code]);
+
+				/*
+				 * If we read more parity disks than were used
+				 * for reconstruction, confirm that the other
+				 * parity disks produced correct data. This
+				 * routine is suboptimal in that it regenerates
+				 * the parity that we already used in addition
+				 * to the parity that we're attempting to
+				 * verify, but this should be a relatively
+				 * uncommon case, and can be optimized if it
+				 * becomes a problem. Note that we regenerate
+				 * parity when resilvering so we can write it
+				 * out to failed devices later.
+				 */
+				if (parity_errors < rm->rm_firstdatacol - n ||
+				    (zio->io_flags & ZIO_FLAG_RESILVER)) {
+					n = raidz_parity_verify(zio, rm);
+					unexpected_errors += n;
+					ASSERT(parity_errors + n <=
+					    rm->rm_firstdatacol);
+				}
+
+				goto done;
+			}
+		}
+	}
+
+	/*
+	 * This isn't a typical situation -- either we got a read error or
+	 * a child silently returned bad data. Read every block so we can
+	 * try again with as much data and parity as we can track down. If
+	 * we've already been through once before, all children will be marked
+	 * as tried so we'll proceed to combinatorial reconstruction.
+	 */
+	unexpected_errors = 1;
+	rm->rm_missingdata = 0;
+	rm->rm_missingparity = 0;
+
+	for (c = 0; c < rm->rm_cols; c++) {
+		if (rm->rm_col[c].rc_tried)
+			continue;
+
+		zio_vdev_io_redone(zio);
+		do {
+			rc = &rm->rm_col[c];
+			if (rc->rc_tried)
+				continue;
+			zio_nowait(zio_vdev_child_io(zio, NULL,
+			    vd->vdev_child[rc->rc_devidx],
+			    rc->rc_offset, rc->rc_data, rc->rc_size,
+			    zio->io_type, zio->io_priority, 0,
+			    vdev_raidz_child_done, rc));
+		} while (++c < rm->rm_cols);
+
+		return;
+	}
+
+	/*
+	 * At this point we've attempted to reconstruct the data given the
+	 * errors we detected, and we've attempted to read all columns. There
+	 * must, therefore, be one or more additional problems -- silent errors
+	 * resulting in invalid data rather than explicit I/O errors resulting
+	 * in absent data. We check if there is enough additional data to
+	 * possibly reconstruct the data and then perform combinatorial
+	 * reconstruction over all possible combinations. If that fails,
+	 * we're cooked.
+	 */
+	if (total_errors > rm->rm_firstdatacol) {
+		zio->io_error = vdev_raidz_worst_error(rm);
+
+	} else if (total_errors < rm->rm_firstdatacol &&
+	    (code = vdev_raidz_combrec(zio, total_errors, data_errors)) != 0) {
+		/*
+		 * If we didn't use all the available parity for the
+		 * combinatorial reconstruction, verify that the remaining
+		 * parity is correct.
+		 */
+		if (code != (1 << rm->rm_firstdatacol) - 1)
+			(void) raidz_parity_verify(zio, rm);
+	} else {
+		/*
+		 * We're here because either:
+		 *
+		 *	total_errors == rm_first_datacol, or
+		 *	vdev_raidz_combrec() failed
+		 *
+		 * In either case, there is enough bad data to prevent
+		 * reconstruction.
+		 *
+		 * Start checksum ereports for all children which haven't
+		 * failed, and the IO wasn't speculative.
+		 */
+		zio->io_error = SET_ERROR(ECKSUM);
+
+		if (!(zio->io_flags & ZIO_FLAG_SPECULATIVE)) {
+			for (c = 0; c < rm->rm_cols; c++) {
+				rc = &rm->rm_col[c];
+				if (rc->rc_error == 0) {
+					zio_bad_cksum_t zbc;
+					zbc.zbc_has_cksum = 0;
+					zbc.zbc_injected =
+					    rm->rm_ecksuminjected;
+
+					zfs_ereport_start_checksum(
+					    zio->io_spa,
+					    vd->vdev_child[rc->rc_devidx],
+					    zio, rc->rc_offset, rc->rc_size,
+					    (void *)(uintptr_t)c, &zbc);
+				}
+			}
+		}
+	}
+
+done:
+	zio_checksum_verified(zio);
+
+	if (zio->io_error == 0 && spa_writeable(zio->io_spa) &&
+	    (unexpected_errors || (zio->io_flags & ZIO_FLAG_RESILVER))) {
+		/*
+		 * Use the good data we have in hand to repair damaged children.
+		 */
+		for (c = 0; c < rm->rm_cols; c++) {
+			rc = &rm->rm_col[c];
+			cvd = vd->vdev_child[rc->rc_devidx];
+
+			if (rc->rc_error == 0)
+				continue;
+
+			zio_nowait(zio_vdev_child_io(zio, NULL, cvd,
+			    rc->rc_offset, rc->rc_data, rc->rc_size,
+			    ZIO_TYPE_WRITE, ZIO_PRIORITY_ASYNC_WRITE,
+			    ZIO_FLAG_IO_REPAIR | (unexpected_errors ?
+			    ZIO_FLAG_SELF_HEAL : 0), NULL, NULL));
+		}
+	}
+}
+
+static void
+vdev_raidz_state_change(vdev_t *vd, int faulted, int degraded)
+{
+	if (faulted > vd->vdev_nparity)
+		vdev_set_state(vd, B_FALSE, VDEV_STATE_CANT_OPEN,
+		    VDEV_AUX_NO_REPLICAS);
+	else if (degraded + faulted != 0)
+		vdev_set_state(vd, B_FALSE, VDEV_STATE_DEGRADED, VDEV_AUX_NONE);
+	else
+		vdev_set_state(vd, B_FALSE, VDEV_STATE_HEALTHY, VDEV_AUX_NONE);
+}
+
+vdev_ops_t vdev_raidz_ops = {
+	vdev_raidz_open,
+	vdev_raidz_close,
+	vdev_raidz_asize,
+	vdev_raidz_io_start,
+	vdev_raidz_io_done,
+	vdev_raidz_state_change,
+	NULL,
+	NULL,
+	VDEV_TYPE_RAIDZ,	/* name of this vdev type */
+	B_FALSE			/* not a leaf vdev */
+};
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/module/zfs/vdev_root.c
@@ -0,0 +1,125 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/*
+ * Copyright (c) 2013 by Delphix. All rights reserved.
+ */
+
+#include <sys/zfs_context.h>
+#include <sys/spa.h>
+#include <sys/vdev_impl.h>
+#include <sys/zio.h>
+#include <sys/fs/zfs.h>
+
+/*
+ * Virtual device vector for the pool's root vdev.
+ */
+
+/*
+ * We should be able to tolerate one failure with absolutely no damage
+ * to our metadata.  Two failures will take out space maps, a bunch of
+ * indirect block trees, meta dnodes, dnodes, etc.  Probably not a happy
+ * place to live.  When we get smarter, we can liberalize this policy.
+ * e.g. If we haven't lost two consecutive top-level vdevs, then we are
+ * probably fine.  Adding bean counters during alloc/free can make this
+ * future guesswork more accurate.
+ */
+static int
+too_many_errors(vdev_t *vd, int numerrors)
+{
+	ASSERT3U(numerrors, <=, vd->vdev_children);
+	return (numerrors > 0);
+}
+
+static int
+vdev_root_open(vdev_t *vd, uint64_t *asize, uint64_t *max_asize,
+    uint64_t *ashift)
+{
+	int lasterror = 0;
+	int numerrors = 0;
+	int c;
+
+	if (vd->vdev_children == 0) {
+		vd->vdev_stat.vs_aux = VDEV_AUX_BAD_LABEL;
+		return (SET_ERROR(EINVAL));
+	}
+
+	vdev_open_children(vd);
+
+	for (c = 0; c < vd->vdev_children; c++) {
+		vdev_t *cvd = vd->vdev_child[c];
+
+		if (cvd->vdev_open_error && !cvd->vdev_islog) {
+			lasterror = cvd->vdev_open_error;
+			numerrors++;
+		}
+	}
+
+	if (too_many_errors(vd, numerrors)) {
+		vd->vdev_stat.vs_aux = VDEV_AUX_NO_REPLICAS;
+		return (lasterror);
+	}
+
+	*asize = 0;
+	*max_asize = 0;
+	*ashift = 0;
+
+	return (0);
+}
+
+static void
+vdev_root_close(vdev_t *vd)
+{
+	int c;
+
+	for (c = 0; c < vd->vdev_children; c++)
+		vdev_close(vd->vdev_child[c]);
+}
+
+static void
+vdev_root_state_change(vdev_t *vd, int faulted, int degraded)
+{
+	if (too_many_errors(vd, faulted)) {
+		vdev_set_state(vd, B_FALSE, VDEV_STATE_CANT_OPEN,
+		    VDEV_AUX_NO_REPLICAS);
+	} else if (degraded) {
+		vdev_set_state(vd, B_FALSE, VDEV_STATE_DEGRADED, VDEV_AUX_NONE);
+	} else {
+		vdev_set_state(vd, B_FALSE, VDEV_STATE_HEALTHY, VDEV_AUX_NONE);
+	}
+}
+
+vdev_ops_t vdev_root_ops = {
+	vdev_root_open,
+	vdev_root_close,
+	vdev_default_asize,
+	NULL,			/* io_start - not applicable to the root */
+	NULL,			/* io_done - not applicable to the root */
+	vdev_root_state_change,
+	NULL,
+	NULL,
+	VDEV_TYPE_ROOT,		/* name of this vdev type */
+	B_FALSE			/* not a leaf vdev */
+};
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/module/zfs/zap.c
@@ -0,0 +1,1372 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2014 by Delphix. All rights reserved.
+ * Copyright (c) 2014 Spectra Logic Corporation, All rights reserved.
+ */
+
+/*
+ * This file contains the top half of the zfs directory structure
+ * implementation. The bottom half is in zap_leaf.c.
+ *
+ * The zdir is an extendable hash data structure. There is a table of
+ * pointers to buckets (zap_t->zd_data->zd_leafs). The buckets are
+ * each a constant size and hold a variable number of directory entries.
+ * The buckets (aka "leaf nodes") are implemented in zap_leaf.c.
+ *
+ * The pointer table holds a power of 2 number of pointers.
+ * (1<<zap_t->zd_data->zd_phys->zd_prefix_len).  The bucket pointed to
+ * by the pointer at index i in the table holds entries whose hash value
+ * has a zd_prefix_len - bit prefix
+ */
+
+#include <sys/spa.h>
+#include <sys/dmu.h>
+#include <sys/zfs_context.h>
+#include <sys/zfs_znode.h>
+#include <sys/fs/zfs.h>
+#include <sys/zap.h>
+#include <sys/refcount.h>
+#include <sys/zap_impl.h>
+#include <sys/zap_leaf.h>
+
+int fzap_default_block_shift = 14; /* 16k blocksize */
+
+extern inline zap_phys_t *zap_f_phys(zap_t *zap);
+
+static uint64_t zap_allocate_blocks(zap_t *zap, int nblocks);
+
+void
+fzap_byteswap(void *vbuf, size_t size)
+{
+	uint64_t block_type;
+
+	block_type = *(uint64_t *)vbuf;
+
+	if (block_type == ZBT_LEAF || block_type == BSWAP_64(ZBT_LEAF))
+		zap_leaf_byteswap(vbuf, size);
+	else {
+		/* it's a ptrtbl block */
+		byteswap_uint64_array(vbuf, size);
+	}
+}
+
+void
+fzap_upgrade(zap_t *zap, dmu_tx_t *tx, zap_flags_t flags)
+{
+	dmu_buf_t *db;
+	zap_leaf_t *l;
+	int i;
+	zap_phys_t *zp;
+
+	ASSERT(RW_WRITE_HELD(&zap->zap_rwlock));
+	zap->zap_ismicro = FALSE;
+
+	zap->zap_dbu.dbu_evict_func = zap_evict;
+
+	mutex_init(&zap->zap_f.zap_num_entries_mtx, 0, 0, 0);
+	zap->zap_f.zap_block_shift = highbit64(zap->zap_dbuf->db_size) - 1;
+
+	zp = zap_f_phys(zap);
+	/*
+	 * explicitly zero it since it might be coming from an
+	 * initialized microzap
+	 */
+	bzero(zap->zap_dbuf->db_data, zap->zap_dbuf->db_size);
+	zp->zap_block_type = ZBT_HEADER;
+	zp->zap_magic = ZAP_MAGIC;
+
+	zp->zap_ptrtbl.zt_shift = ZAP_EMBEDDED_PTRTBL_SHIFT(zap);
+
+	zp->zap_freeblk = 2;		/* block 1 will be the first leaf */
+	zp->zap_num_leafs = 1;
+	zp->zap_num_entries = 0;
+	zp->zap_salt = zap->zap_salt;
+	zp->zap_normflags = zap->zap_normflags;
+	zp->zap_flags = flags;
+
+	/* block 1 will be the first leaf */
+	for (i = 0; i < (1<<zp->zap_ptrtbl.zt_shift); i++)
+		ZAP_EMBEDDED_PTRTBL_ENT(zap, i) = 1;
+
+	/*
+	 * set up block 1 - the first leaf
+	 */
+	VERIFY(0 == dmu_buf_hold(zap->zap_objset, zap->zap_object,
+	    1<<FZAP_BLOCK_SHIFT(zap), FTAG, &db, DMU_READ_NO_PREFETCH));
+	dmu_buf_will_dirty(db, tx);
+
+	l = kmem_zalloc(sizeof (zap_leaf_t), KM_SLEEP);
+	l->l_dbuf = db;
+
+	zap_leaf_init(l, zp->zap_normflags != 0);
+
+	kmem_free(l, sizeof (zap_leaf_t));
+	dmu_buf_rele(db, FTAG);
+}
+
+static int
+zap_tryupgradedir(zap_t *zap, dmu_tx_t *tx)
+{
+	if (RW_WRITE_HELD(&zap->zap_rwlock))
+		return (1);
+	if (rw_tryupgrade(&zap->zap_rwlock)) {
+		dmu_buf_will_dirty(zap->zap_dbuf, tx);
+		return (1);
+	}
+	return (0);
+}
+
+/*
+ * Generic routines for dealing with the pointer & cookie tables.
+ */
+
+static int
+zap_table_grow(zap_t *zap, zap_table_phys_t *tbl,
+    void (*transfer_func)(const uint64_t *src, uint64_t *dst, int n),
+    dmu_tx_t *tx)
+{
+	uint64_t b, newblk;
+	dmu_buf_t *db_old, *db_new;
+	int err;
+	int bs = FZAP_BLOCK_SHIFT(zap);
+	int hepb = 1<<(bs-4);
+	/* hepb = half the number of entries in a block */
+
+	ASSERT(RW_WRITE_HELD(&zap->zap_rwlock));
+	ASSERT(tbl->zt_blk != 0);
+	ASSERT(tbl->zt_numblks > 0);
+
+	if (tbl->zt_nextblk != 0) {
+		newblk = tbl->zt_nextblk;
+	} else {
+		newblk = zap_allocate_blocks(zap, tbl->zt_numblks * 2);
+		tbl->zt_nextblk = newblk;
+		ASSERT0(tbl->zt_blks_copied);
+		dmu_prefetch(zap->zap_objset, zap->zap_object,
+		    tbl->zt_blk << bs, tbl->zt_numblks << bs);
+	}
+
+	/*
+	 * Copy the ptrtbl from the old to new location.
+	 */
+
+	b = tbl->zt_blks_copied;
+	err = dmu_buf_hold(zap->zap_objset, zap->zap_object,
+	    (tbl->zt_blk + b) << bs, FTAG, &db_old, DMU_READ_NO_PREFETCH);
+	if (err)
+		return (err);
+
+	/* first half of entries in old[b] go to new[2*b+0] */
+	VERIFY(0 == dmu_buf_hold(zap->zap_objset, zap->zap_object,
+	    (newblk + 2*b+0) << bs, FTAG, &db_new, DMU_READ_NO_PREFETCH));
+	dmu_buf_will_dirty(db_new, tx);
+	transfer_func(db_old->db_data, db_new->db_data, hepb);
+	dmu_buf_rele(db_new, FTAG);
+
+	/* second half of entries in old[b] go to new[2*b+1] */
+	VERIFY(0 == dmu_buf_hold(zap->zap_objset, zap->zap_object,
+	    (newblk + 2*b+1) << bs, FTAG, &db_new, DMU_READ_NO_PREFETCH));
+	dmu_buf_will_dirty(db_new, tx);
+	transfer_func((uint64_t *)db_old->db_data + hepb,
+	    db_new->db_data, hepb);
+	dmu_buf_rele(db_new, FTAG);
+
+	dmu_buf_rele(db_old, FTAG);
+
+	tbl->zt_blks_copied++;
+
+	dprintf("copied block %llu of %llu\n",
+	    tbl->zt_blks_copied, tbl->zt_numblks);
+
+	if (tbl->zt_blks_copied == tbl->zt_numblks) {
+		(void) dmu_free_range(zap->zap_objset, zap->zap_object,
+		    tbl->zt_blk << bs, tbl->zt_numblks << bs, tx);
+
+		tbl->zt_blk = newblk;
+		tbl->zt_numblks *= 2;
+		tbl->zt_shift++;
+		tbl->zt_nextblk = 0;
+		tbl->zt_blks_copied = 0;
+
+		dprintf("finished; numblocks now %llu (%uk entries)\n",
+		    tbl->zt_numblks, 1<<(tbl->zt_shift-10));
+	}
+
+	return (0);
+}
+
+static int
+zap_table_store(zap_t *zap, zap_table_phys_t *tbl, uint64_t idx, uint64_t val,
+    dmu_tx_t *tx)
+{
+	int err;
+	uint64_t blk, off;
+	int bs = FZAP_BLOCK_SHIFT(zap);
+	dmu_buf_t *db;
+
+	ASSERT(RW_LOCK_HELD(&zap->zap_rwlock));
+	ASSERT(tbl->zt_blk != 0);
+
+	dprintf("storing %llx at index %llx\n", val, idx);
+
+	blk = idx >> (bs-3);
+	off = idx & ((1<<(bs-3))-1);
+
+	err = dmu_buf_hold(zap->zap_objset, zap->zap_object,
+	    (tbl->zt_blk + blk) << bs, FTAG, &db, DMU_READ_NO_PREFETCH);
+	if (err)
+		return (err);
+	dmu_buf_will_dirty(db, tx);
+
+	if (tbl->zt_nextblk != 0) {
+		uint64_t idx2 = idx * 2;
+		uint64_t blk2 = idx2 >> (bs-3);
+		uint64_t off2 = idx2 & ((1<<(bs-3))-1);
+		dmu_buf_t *db2;
+
+		err = dmu_buf_hold(zap->zap_objset, zap->zap_object,
+		    (tbl->zt_nextblk + blk2) << bs, FTAG, &db2,
+		    DMU_READ_NO_PREFETCH);
+		if (err) {
+			dmu_buf_rele(db, FTAG);
+			return (err);
+		}
+		dmu_buf_will_dirty(db2, tx);
+		((uint64_t *)db2->db_data)[off2] = val;
+		((uint64_t *)db2->db_data)[off2+1] = val;
+		dmu_buf_rele(db2, FTAG);
+	}
+
+	((uint64_t *)db->db_data)[off] = val;
+	dmu_buf_rele(db, FTAG);
+
+	return (0);
+}
+
+static int
+zap_table_load(zap_t *zap, zap_table_phys_t *tbl, uint64_t idx, uint64_t *valp)
+{
+	uint64_t blk, off;
+	int err;
+	dmu_buf_t *db;
+	int bs = FZAP_BLOCK_SHIFT(zap);
+
+	ASSERT(RW_LOCK_HELD(&zap->zap_rwlock));
+
+	blk = idx >> (bs-3);
+	off = idx & ((1<<(bs-3))-1);
+
+	err = dmu_buf_hold(zap->zap_objset, zap->zap_object,
+	    (tbl->zt_blk + blk) << bs, FTAG, &db, DMU_READ_NO_PREFETCH);
+	if (err)
+		return (err);
+	*valp = ((uint64_t *)db->db_data)[off];
+	dmu_buf_rele(db, FTAG);
+
+	if (tbl->zt_nextblk != 0) {
+		/*
+		 * read the nextblk for the sake of i/o error checking,
+		 * so that zap_table_load() will catch errors for
+		 * zap_table_store.
+		 */
+		blk = (idx*2) >> (bs-3);
+
+		err = dmu_buf_hold(zap->zap_objset, zap->zap_object,
+		    (tbl->zt_nextblk + blk) << bs, FTAG, &db,
+		    DMU_READ_NO_PREFETCH);
+		if (err == 0)
+			dmu_buf_rele(db, FTAG);
+	}
+	return (err);
+}
+
+/*
+ * Routines for growing the ptrtbl.
+ */
+
+static void
+zap_ptrtbl_transfer(const uint64_t *src, uint64_t *dst, int n)
+{
+	int i;
+	for (i = 0; i < n; i++) {
+		uint64_t lb = src[i];
+		dst[2*i+0] = lb;
+		dst[2*i+1] = lb;
+	}
+}
+
+static int
+zap_grow_ptrtbl(zap_t *zap, dmu_tx_t *tx)
+{
+	/*
+	 * The pointer table should never use more hash bits than we
+	 * have (otherwise we'd be using useless zero bits to index it).
+	 * If we are within 2 bits of running out, stop growing, since
+	 * this is already an aberrant condition.
+	 */
+	if (zap_f_phys(zap)->zap_ptrtbl.zt_shift >= zap_hashbits(zap) - 2)
+		return (SET_ERROR(ENOSPC));
+
+	if (zap_f_phys(zap)->zap_ptrtbl.zt_numblks == 0) {
+		/*
+		 * We are outgrowing the "embedded" ptrtbl (the one
+		 * stored in the header block).  Give it its own entire
+		 * block, which will double the size of the ptrtbl.
+		 */
+		uint64_t newblk;
+		dmu_buf_t *db_new;
+		int err;
+
+		ASSERT3U(zap_f_phys(zap)->zap_ptrtbl.zt_shift, ==,
+		    ZAP_EMBEDDED_PTRTBL_SHIFT(zap));
+		ASSERT0(zap_f_phys(zap)->zap_ptrtbl.zt_blk);
+
+		newblk = zap_allocate_blocks(zap, 1);
+		err = dmu_buf_hold(zap->zap_objset, zap->zap_object,
+		    newblk << FZAP_BLOCK_SHIFT(zap), FTAG, &db_new,
+		    DMU_READ_NO_PREFETCH);
+		if (err)
+			return (err);
+		dmu_buf_will_dirty(db_new, tx);
+		zap_ptrtbl_transfer(&ZAP_EMBEDDED_PTRTBL_ENT(zap, 0),
+		    db_new->db_data, 1 << ZAP_EMBEDDED_PTRTBL_SHIFT(zap));
+		dmu_buf_rele(db_new, FTAG);
+
+		zap_f_phys(zap)->zap_ptrtbl.zt_blk = newblk;
+		zap_f_phys(zap)->zap_ptrtbl.zt_numblks = 1;
+		zap_f_phys(zap)->zap_ptrtbl.zt_shift++;
+
+		ASSERT3U(1ULL << zap_f_phys(zap)->zap_ptrtbl.zt_shift, ==,
+		    zap_f_phys(zap)->zap_ptrtbl.zt_numblks <<
+		    (FZAP_BLOCK_SHIFT(zap)-3));
+
+		return (0);
+	} else {
+		return (zap_table_grow(zap, &zap_f_phys(zap)->zap_ptrtbl,
+		    zap_ptrtbl_transfer, tx));
+	}
+}
+
+static void
+zap_increment_num_entries(zap_t *zap, int delta, dmu_tx_t *tx)
+{
+	dmu_buf_will_dirty(zap->zap_dbuf, tx);
+	mutex_enter(&zap->zap_f.zap_num_entries_mtx);
+	ASSERT(delta > 0 || zap_f_phys(zap)->zap_num_entries >= -delta);
+	zap_f_phys(zap)->zap_num_entries += delta;
+	mutex_exit(&zap->zap_f.zap_num_entries_mtx);
+}
+
+static uint64_t
+zap_allocate_blocks(zap_t *zap, int nblocks)
+{
+	uint64_t newblk;
+	ASSERT(RW_WRITE_HELD(&zap->zap_rwlock));
+	newblk = zap_f_phys(zap)->zap_freeblk;
+	zap_f_phys(zap)->zap_freeblk += nblocks;
+	return (newblk);
+}
+
+static void
+zap_leaf_pageout(void *dbu)
+{
+	zap_leaf_t *l = dbu;
+
+	rw_destroy(&l->l_rwlock);
+	kmem_free(l, sizeof (zap_leaf_t));
+}
+
+static zap_leaf_t *
+zap_create_leaf(zap_t *zap, dmu_tx_t *tx)
+{
+	void *winner;
+	zap_leaf_t *l = kmem_zalloc(sizeof (zap_leaf_t), KM_SLEEP);
+
+	ASSERT(RW_WRITE_HELD(&zap->zap_rwlock));
+
+	rw_init(&l->l_rwlock, NULL, RW_DEFAULT, NULL);
+	rw_enter(&l->l_rwlock, RW_WRITER);
+	l->l_blkid = zap_allocate_blocks(zap, 1);
+	l->l_dbuf = NULL;
+
+	VERIFY(0 == dmu_buf_hold(zap->zap_objset, zap->zap_object,
+	    l->l_blkid << FZAP_BLOCK_SHIFT(zap), NULL, &l->l_dbuf,
+	    DMU_READ_NO_PREFETCH));
+	dmu_buf_init_user(&l->l_dbu, zap_leaf_pageout, &l->l_dbuf);
+	winner = dmu_buf_set_user(l->l_dbuf, &l->l_dbu);
+	ASSERT(winner == NULL);
+	dmu_buf_will_dirty(l->l_dbuf, tx);
+
+	zap_leaf_init(l, zap->zap_normflags != 0);
+
+	zap_f_phys(zap)->zap_num_leafs++;
+
+	return (l);
+}
+
+int
+fzap_count(zap_t *zap, uint64_t *count)
+{
+	ASSERT(!zap->zap_ismicro);
+	mutex_enter(&zap->zap_f.zap_num_entries_mtx); /* unnecessary */
+	*count = zap_f_phys(zap)->zap_num_entries;
+	mutex_exit(&zap->zap_f.zap_num_entries_mtx);
+	return (0);
+}
+
+/*
+ * Routines for obtaining zap_leaf_t's
+ */
+
+void
+zap_put_leaf(zap_leaf_t *l)
+{
+	rw_exit(&l->l_rwlock);
+	dmu_buf_rele(l->l_dbuf, NULL);
+}
+
+static zap_leaf_t *
+zap_open_leaf(uint64_t blkid, dmu_buf_t *db)
+{
+	zap_leaf_t *l, *winner;
+
+	ASSERT(blkid != 0);
+
+	l = kmem_zalloc(sizeof (zap_leaf_t), KM_SLEEP);
+	rw_init(&l->l_rwlock, NULL, RW_DEFAULT, NULL);
+	rw_enter(&l->l_rwlock, RW_WRITER);
+	l->l_blkid = blkid;
+	l->l_bs = highbit64(db->db_size) - 1;
+	l->l_dbuf = db;
+
+	dmu_buf_init_user(&l->l_dbu, zap_leaf_pageout, &l->l_dbuf);
+	winner = dmu_buf_set_user(db, &l->l_dbu);
+
+	rw_exit(&l->l_rwlock);
+	if (winner != NULL) {
+		/* someone else set it first */
+		zap_leaf_pageout(&l->l_dbu);
+		l = winner;
+	}
+
+	/*
+	 * lhr_pad was previously used for the next leaf in the leaf
+	 * chain.  There should be no chained leafs (as we have removed
+	 * support for them).
+	 */
+	ASSERT0(zap_leaf_phys(l)->l_hdr.lh_pad1);
+
+	/*
+	 * There should be more hash entries than there can be
+	 * chunks to put in the hash table
+	 */
+	ASSERT3U(ZAP_LEAF_HASH_NUMENTRIES(l), >, ZAP_LEAF_NUMCHUNKS(l) / 3);
+
+	/* The chunks should begin at the end of the hash table */
+	ASSERT3P(&ZAP_LEAF_CHUNK(l, 0), ==, (zap_leaf_chunk_t *)
+	    &zap_leaf_phys(l)->l_hash[ZAP_LEAF_HASH_NUMENTRIES(l)]);
+
+	/* The chunks should end at the end of the block */
+	ASSERT3U((uintptr_t)&ZAP_LEAF_CHUNK(l, ZAP_LEAF_NUMCHUNKS(l)) -
+	    (uintptr_t)zap_leaf_phys(l), ==, l->l_dbuf->db_size);
+
+	return (l);
+}
+
+static int
+zap_get_leaf_byblk(zap_t *zap, uint64_t blkid, dmu_tx_t *tx, krw_t lt,
+    zap_leaf_t **lp)
+{
+	dmu_buf_t *db;
+	zap_leaf_t *l;
+	int bs = FZAP_BLOCK_SHIFT(zap);
+	int err;
+
+	ASSERT(RW_LOCK_HELD(&zap->zap_rwlock));
+
+	/*
+	 * If system crashed just after dmu_free_long_range in zfs_rmnode, we
+	 * would be left with an empty xattr dir in delete queue. blkid=0
+	 * would be passed in when doing zfs_purgedir. If that's the case we
+	 * should just return immediately. The underlying objects should
+	 * already be freed, so this should be perfectly fine.
+	 */
+	if (blkid == 0)
+		return (ENOENT);
+
+	err = dmu_buf_hold(zap->zap_objset, zap->zap_object,
+	    blkid << bs, NULL, &db, DMU_READ_NO_PREFETCH);
+	if (err)
+		return (err);
+
+	ASSERT3U(db->db_object, ==, zap->zap_object);
+	ASSERT3U(db->db_offset, ==, blkid << bs);
+	ASSERT3U(db->db_size, ==, 1 << bs);
+	ASSERT(blkid != 0);
+
+	l = dmu_buf_get_user(db);
+
+	if (l == NULL)
+		l = zap_open_leaf(blkid, db);
+
+	rw_enter(&l->l_rwlock, lt);
+	/*
+	 * Must lock before dirtying, otherwise zap_leaf_phys(l) could change,
+	 * causing ASSERT below to fail.
+	 */
+	if (lt == RW_WRITER)
+		dmu_buf_will_dirty(db, tx);
+	ASSERT3U(l->l_blkid, ==, blkid);
+	ASSERT3P(l->l_dbuf, ==, db);
+	ASSERT3U(zap_leaf_phys(l)->l_hdr.lh_block_type, ==, ZBT_LEAF);
+	ASSERT3U(zap_leaf_phys(l)->l_hdr.lh_magic, ==, ZAP_LEAF_MAGIC);
+
+	*lp = l;
+	return (0);
+}
+
+static int
+zap_idx_to_blk(zap_t *zap, uint64_t idx, uint64_t *valp)
+{
+	ASSERT(RW_LOCK_HELD(&zap->zap_rwlock));
+
+	if (zap_f_phys(zap)->zap_ptrtbl.zt_numblks == 0) {
+		ASSERT3U(idx, <,
+		    (1ULL << zap_f_phys(zap)->zap_ptrtbl.zt_shift));
+		*valp = ZAP_EMBEDDED_PTRTBL_ENT(zap, idx);
+		return (0);
+	} else {
+		return (zap_table_load(zap, &zap_f_phys(zap)->zap_ptrtbl,
+		    idx, valp));
+	}
+}
+
+static int
+zap_set_idx_to_blk(zap_t *zap, uint64_t idx, uint64_t blk, dmu_tx_t *tx)
+{
+	ASSERT(tx != NULL);
+	ASSERT(RW_WRITE_HELD(&zap->zap_rwlock));
+
+	if (zap_f_phys(zap)->zap_ptrtbl.zt_blk == 0) {
+		ZAP_EMBEDDED_PTRTBL_ENT(zap, idx) = blk;
+		return (0);
+	} else {
+		return (zap_table_store(zap, &zap_f_phys(zap)->zap_ptrtbl,
+		    idx, blk, tx));
+	}
+}
+
+static int
+zap_deref_leaf(zap_t *zap, uint64_t h, dmu_tx_t *tx, krw_t lt, zap_leaf_t **lp)
+{
+	uint64_t idx, blk;
+	int err;
+
+	ASSERT(zap->zap_dbuf == NULL ||
+	    zap_f_phys(zap) == zap->zap_dbuf->db_data);
+	ASSERT3U(zap_f_phys(zap)->zap_magic, ==, ZAP_MAGIC);
+	idx = ZAP_HASH_IDX(h, zap_f_phys(zap)->zap_ptrtbl.zt_shift);
+	err = zap_idx_to_blk(zap, idx, &blk);
+	if (err != 0)
+		return (err);
+	err = zap_get_leaf_byblk(zap, blk, tx, lt, lp);
+
+	ASSERT(err ||
+	    ZAP_HASH_IDX(h, zap_leaf_phys(*lp)->l_hdr.lh_prefix_len) ==
+	    zap_leaf_phys(*lp)->l_hdr.lh_prefix);
+	return (err);
+}
+
+static int
+zap_expand_leaf(zap_name_t *zn, zap_leaf_t *l, dmu_tx_t *tx, zap_leaf_t **lp)
+{
+	zap_t *zap = zn->zn_zap;
+	uint64_t hash = zn->zn_hash;
+	zap_leaf_t *nl;
+	int prefix_diff, i, err;
+	uint64_t sibling;
+	int old_prefix_len = zap_leaf_phys(l)->l_hdr.lh_prefix_len;
+
+	ASSERT3U(old_prefix_len, <=, zap_f_phys(zap)->zap_ptrtbl.zt_shift);
+	ASSERT(RW_LOCK_HELD(&zap->zap_rwlock));
+
+	ASSERT3U(ZAP_HASH_IDX(hash, old_prefix_len), ==,
+	    zap_leaf_phys(l)->l_hdr.lh_prefix);
+
+	if (zap_tryupgradedir(zap, tx) == 0 ||
+	    old_prefix_len == zap_f_phys(zap)->zap_ptrtbl.zt_shift) {
+		/* We failed to upgrade, or need to grow the pointer table */
+		objset_t *os = zap->zap_objset;
+		uint64_t object = zap->zap_object;
+
+		zap_put_leaf(l);
+		zap_unlockdir(zap);
+		err = zap_lockdir(os, object, tx, RW_WRITER,
+		    FALSE, FALSE, &zn->zn_zap);
+		zap = zn->zn_zap;
+		if (err)
+			return (err);
+		ASSERT(!zap->zap_ismicro);
+
+		while (old_prefix_len ==
+		    zap_f_phys(zap)->zap_ptrtbl.zt_shift) {
+			err = zap_grow_ptrtbl(zap, tx);
+			if (err)
+				return (err);
+		}
+
+		err = zap_deref_leaf(zap, hash, tx, RW_WRITER, &l);
+		if (err)
+			return (err);
+
+		if (zap_leaf_phys(l)->l_hdr.lh_prefix_len != old_prefix_len) {
+			/* it split while our locks were down */
+			*lp = l;
+			return (0);
+		}
+	}
+	ASSERT(RW_WRITE_HELD(&zap->zap_rwlock));
+	ASSERT3U(old_prefix_len, <, zap_f_phys(zap)->zap_ptrtbl.zt_shift);
+	ASSERT3U(ZAP_HASH_IDX(hash, old_prefix_len), ==,
+	    zap_leaf_phys(l)->l_hdr.lh_prefix);
+
+	prefix_diff = zap_f_phys(zap)->zap_ptrtbl.zt_shift -
+	    (old_prefix_len + 1);
+	sibling = (ZAP_HASH_IDX(hash, old_prefix_len + 1) | 1) << prefix_diff;
+
+	/* check for i/o errors before doing zap_leaf_split */
+	for (i = 0; i < (1ULL<<prefix_diff); i++) {
+		uint64_t blk;
+		err = zap_idx_to_blk(zap, sibling+i, &blk);
+		if (err)
+			return (err);
+		ASSERT3U(blk, ==, l->l_blkid);
+	}
+
+	nl = zap_create_leaf(zap, tx);
+	zap_leaf_split(l, nl, zap->zap_normflags != 0);
+
+	/* set sibling pointers */
+	for (i = 0; i < (1ULL << prefix_diff); i++) {
+		err = zap_set_idx_to_blk(zap, sibling+i, nl->l_blkid, tx);
+		ASSERT0(err); /* we checked for i/o errors above */
+	}
+
+	if (hash & (1ULL << (64 - zap_leaf_phys(l)->l_hdr.lh_prefix_len))) {
+		/* we want the sibling */
+		zap_put_leaf(l);
+		*lp = nl;
+	} else {
+		zap_put_leaf(nl);
+		*lp = l;
+	}
+
+	return (0);
+}
+
+static void
+zap_put_leaf_maybe_grow_ptrtbl(zap_name_t *zn, zap_leaf_t *l, dmu_tx_t *tx)
+{
+	zap_t *zap = zn->zn_zap;
+	int shift = zap_f_phys(zap)->zap_ptrtbl.zt_shift;
+	int leaffull = (zap_leaf_phys(l)->l_hdr.lh_prefix_len == shift &&
+	    zap_leaf_phys(l)->l_hdr.lh_nfree < ZAP_LEAF_LOW_WATER);
+
+	zap_put_leaf(l);
+
+	if (leaffull || zap_f_phys(zap)->zap_ptrtbl.zt_nextblk) {
+		int err;
+
+		/*
+		 * We are in the middle of growing the pointer table, or
+		 * this leaf will soon make us grow it.
+		 */
+		if (zap_tryupgradedir(zap, tx) == 0) {
+			objset_t *os = zap->zap_objset;
+			uint64_t zapobj = zap->zap_object;
+
+			zap_unlockdir(zap);
+			err = zap_lockdir(os, zapobj, tx,
+			    RW_WRITER, FALSE, FALSE, &zn->zn_zap);
+			zap = zn->zn_zap;
+			if (err)
+				return;
+		}
+
+		/* could have finished growing while our locks were down */
+		if (zap_f_phys(zap)->zap_ptrtbl.zt_shift == shift)
+			(void) zap_grow_ptrtbl(zap, tx);
+	}
+}
+
+static int
+fzap_checkname(zap_name_t *zn)
+{
+	if (zn->zn_key_orig_numints * zn->zn_key_intlen > ZAP_MAXNAMELEN)
+		return (SET_ERROR(ENAMETOOLONG));
+	return (0);
+}
+
+static int
+fzap_checksize(uint64_t integer_size, uint64_t num_integers)
+{
+	/* Only integer sizes supported by C */
+	switch (integer_size) {
+	case 1:
+	case 2:
+	case 4:
+	case 8:
+		break;
+	default:
+		return (SET_ERROR(EINVAL));
+	}
+
+	if (integer_size * num_integers > ZAP_MAXVALUELEN)
+		return (E2BIG);
+
+	return (0);
+}
+
+static int
+fzap_check(zap_name_t *zn, uint64_t integer_size, uint64_t num_integers)
+{
+	int err;
+
+	if ((err = fzap_checkname(zn)) != 0)
+		return (err);
+	return (fzap_checksize(integer_size, num_integers));
+}
+
+/*
+ * Routines for manipulating attributes.
+ */
+int
+fzap_lookup(zap_name_t *zn,
+    uint64_t integer_size, uint64_t num_integers, void *buf,
+    char *realname, int rn_len, boolean_t *ncp)
+{
+	zap_leaf_t *l;
+	int err;
+	zap_entry_handle_t zeh;
+
+	if ((err = fzap_checkname(zn)) != 0)
+		return (err);
+
+	err = zap_deref_leaf(zn->zn_zap, zn->zn_hash, NULL, RW_READER, &l);
+	if (err != 0)
+		return (err);
+	err = zap_leaf_lookup(l, zn, &zeh);
+	if (err == 0) {
+		if ((err = fzap_checksize(integer_size, num_integers)) != 0) {
+			zap_put_leaf(l);
+			return (err);
+		}
+
+		err = zap_entry_read(&zeh, integer_size, num_integers, buf);
+		(void) zap_entry_read_name(zn->zn_zap, &zeh, rn_len, realname);
+		if (ncp) {
+			*ncp = zap_entry_normalization_conflict(&zeh,
+			    zn, NULL, zn->zn_zap);
+		}
+	}
+
+	zap_put_leaf(l);
+	return (err);
+}
+
+int
+fzap_add_cd(zap_name_t *zn,
+    uint64_t integer_size, uint64_t num_integers,
+    const void *val, uint32_t cd, dmu_tx_t *tx)
+{
+	zap_leaf_t *l;
+	int err;
+	zap_entry_handle_t zeh;
+	zap_t *zap = zn->zn_zap;
+
+	ASSERT(RW_LOCK_HELD(&zap->zap_rwlock));
+	ASSERT(!zap->zap_ismicro);
+	ASSERT(fzap_check(zn, integer_size, num_integers) == 0);
+
+	err = zap_deref_leaf(zap, zn->zn_hash, tx, RW_WRITER, &l);
+	if (err != 0)
+		return (err);
+retry:
+	err = zap_leaf_lookup(l, zn, &zeh);
+	if (err == 0) {
+		err = SET_ERROR(EEXIST);
+		goto out;
+	}
+	if (err != ENOENT)
+		goto out;
+
+	err = zap_entry_create(l, zn, cd,
+	    integer_size, num_integers, val, &zeh);
+
+	if (err == 0) {
+		zap_increment_num_entries(zap, 1, tx);
+	} else if (err == EAGAIN) {
+		err = zap_expand_leaf(zn, l, tx, &l);
+		zap = zn->zn_zap;	/* zap_expand_leaf() may change zap */
+		if (err == 0)
+			goto retry;
+	}
+
+out:
+	if (zap != NULL)
+		zap_put_leaf_maybe_grow_ptrtbl(zn, l, tx);
+	return (err);
+}
+
+int
+fzap_add(zap_name_t *zn,
+    uint64_t integer_size, uint64_t num_integers,
+    const void *val, dmu_tx_t *tx)
+{
+	int err = fzap_check(zn, integer_size, num_integers);
+	if (err != 0)
+		return (err);
+
+	return (fzap_add_cd(zn, integer_size, num_integers,
+	    val, ZAP_NEED_CD, tx));
+}
+
+int
+fzap_update(zap_name_t *zn,
+    int integer_size, uint64_t num_integers, const void *val, dmu_tx_t *tx)
+{
+	zap_leaf_t *l;
+	int err, create;
+	zap_entry_handle_t zeh;
+	zap_t *zap = zn->zn_zap;
+
+	ASSERT(RW_LOCK_HELD(&zap->zap_rwlock));
+	err = fzap_check(zn, integer_size, num_integers);
+	if (err != 0)
+		return (err);
+
+	err = zap_deref_leaf(zap, zn->zn_hash, tx, RW_WRITER, &l);
+	if (err != 0)
+		return (err);
+retry:
+	err = zap_leaf_lookup(l, zn, &zeh);
+	create = (err == ENOENT);
+	ASSERT(err == 0 || err == ENOENT);
+
+	if (create) {
+		err = zap_entry_create(l, zn, ZAP_NEED_CD,
+		    integer_size, num_integers, val, &zeh);
+		if (err == 0)
+			zap_increment_num_entries(zap, 1, tx);
+	} else {
+		err = zap_entry_update(&zeh, integer_size, num_integers, val);
+	}
+
+	if (err == EAGAIN) {
+		err = zap_expand_leaf(zn, l, tx, &l);
+		zap = zn->zn_zap;	/* zap_expand_leaf() may change zap */
+		if (err == 0)
+			goto retry;
+	}
+
+	if (zap != NULL)
+		zap_put_leaf_maybe_grow_ptrtbl(zn, l, tx);
+	return (err);
+}
+
+int
+fzap_length(zap_name_t *zn,
+    uint64_t *integer_size, uint64_t *num_integers)
+{
+	zap_leaf_t *l;
+	int err;
+	zap_entry_handle_t zeh;
+
+	err = zap_deref_leaf(zn->zn_zap, zn->zn_hash, NULL, RW_READER, &l);
+	if (err != 0)
+		return (err);
+	err = zap_leaf_lookup(l, zn, &zeh);
+	if (err != 0)
+		goto out;
+
+	if (integer_size)
+		*integer_size = zeh.zeh_integer_size;
+	if (num_integers)
+		*num_integers = zeh.zeh_num_integers;
+out:
+	zap_put_leaf(l);
+	return (err);
+}
+
+int
+fzap_remove(zap_name_t *zn, dmu_tx_t *tx)
+{
+	zap_leaf_t *l;
+	int err;
+	zap_entry_handle_t zeh;
+
+	err = zap_deref_leaf(zn->zn_zap, zn->zn_hash, tx, RW_WRITER, &l);
+	if (err != 0)
+		return (err);
+	err = zap_leaf_lookup(l, zn, &zeh);
+	if (err == 0) {
+		zap_entry_remove(&zeh);
+		zap_increment_num_entries(zn->zn_zap, -1, tx);
+	}
+	zap_put_leaf(l);
+	return (err);
+}
+
+void
+fzap_prefetch(zap_name_t *zn)
+{
+	uint64_t idx, blk;
+	zap_t *zap = zn->zn_zap;
+	int bs;
+
+	idx = ZAP_HASH_IDX(zn->zn_hash,
+	    zap_f_phys(zap)->zap_ptrtbl.zt_shift);
+	if (zap_idx_to_blk(zap, idx, &blk) != 0)
+		return;
+	bs = FZAP_BLOCK_SHIFT(zap);
+	dmu_prefetch(zap->zap_objset, zap->zap_object, blk << bs, 1 << bs);
+}
+
+/*
+ * Helper functions for consumers.
+ */
+
+uint64_t
+zap_create_link(objset_t *os, dmu_object_type_t ot, uint64_t parent_obj,
+    const char *name, dmu_tx_t *tx)
+{
+	uint64_t new_obj;
+
+	VERIFY((new_obj = zap_create(os, ot, DMU_OT_NONE, 0, tx)) > 0);
+	VERIFY(zap_add(os, parent_obj, name, sizeof (uint64_t), 1, &new_obj,
+	    tx) == 0);
+
+	return (new_obj);
+}
+
+int
+zap_value_search(objset_t *os, uint64_t zapobj, uint64_t value, uint64_t mask,
+    char *name)
+{
+	zap_cursor_t zc;
+	zap_attribute_t *za;
+	int err;
+
+	if (mask == 0)
+		mask = -1ULL;
+
+	za = kmem_alloc(sizeof (zap_attribute_t), KM_SLEEP);
+	for (zap_cursor_init(&zc, os, zapobj);
+	    (err = zap_cursor_retrieve(&zc, za)) == 0;
+	    zap_cursor_advance(&zc)) {
+		if ((za->za_first_integer & mask) == (value & mask)) {
+			(void) strcpy(name, za->za_name);
+			break;
+		}
+	}
+	zap_cursor_fini(&zc);
+	kmem_free(za, sizeof (zap_attribute_t));
+	return (err);
+}
+
+int
+zap_join(objset_t *os, uint64_t fromobj, uint64_t intoobj, dmu_tx_t *tx)
+{
+	zap_cursor_t zc;
+	zap_attribute_t za;
+	int err;
+
+	err = 0;
+	for (zap_cursor_init(&zc, os, fromobj);
+	    zap_cursor_retrieve(&zc, &za) == 0;
+	    (void) zap_cursor_advance(&zc)) {
+		if (za.za_integer_length != 8 || za.za_num_integers != 1) {
+			err = SET_ERROR(EINVAL);
+			break;
+		}
+		err = zap_add(os, intoobj, za.za_name,
+		    8, 1, &za.za_first_integer, tx);
+		if (err)
+			break;
+	}
+	zap_cursor_fini(&zc);
+	return (err);
+}
+
+int
+zap_join_key(objset_t *os, uint64_t fromobj, uint64_t intoobj,
+    uint64_t value, dmu_tx_t *tx)
+{
+	zap_cursor_t zc;
+	zap_attribute_t za;
+	int err;
+
+	err = 0;
+	for (zap_cursor_init(&zc, os, fromobj);
+	    zap_cursor_retrieve(&zc, &za) == 0;
+	    (void) zap_cursor_advance(&zc)) {
+		if (za.za_integer_length != 8 || za.za_num_integers != 1) {
+			err = SET_ERROR(EINVAL);
+			break;
+		}
+		err = zap_add(os, intoobj, za.za_name,
+		    8, 1, &value, tx);
+		if (err)
+			break;
+	}
+	zap_cursor_fini(&zc);
+	return (err);
+}
+
+int
+zap_join_increment(objset_t *os, uint64_t fromobj, uint64_t intoobj,
+    dmu_tx_t *tx)
+{
+	zap_cursor_t zc;
+	zap_attribute_t za;
+	int err;
+
+	err = 0;
+	for (zap_cursor_init(&zc, os, fromobj);
+	    zap_cursor_retrieve(&zc, &za) == 0;
+	    (void) zap_cursor_advance(&zc)) {
+		uint64_t delta = 0;
+
+		if (za.za_integer_length != 8 || za.za_num_integers != 1) {
+			err = SET_ERROR(EINVAL);
+			break;
+		}
+
+		err = zap_lookup(os, intoobj, za.za_name, 8, 1, &delta);
+		if (err != 0 && err != ENOENT)
+			break;
+		delta += za.za_first_integer;
+		err = zap_update(os, intoobj, za.za_name, 8, 1, &delta, tx);
+		if (err)
+			break;
+	}
+	zap_cursor_fini(&zc);
+	return (err);
+}
+
+int
+zap_add_int(objset_t *os, uint64_t obj, uint64_t value, dmu_tx_t *tx)
+{
+	char name[20];
+
+	(void) snprintf(name, sizeof (name), "%llx", (longlong_t)value);
+	return (zap_add(os, obj, name, 8, 1, &value, tx));
+}
+
+int
+zap_remove_int(objset_t *os, uint64_t obj, uint64_t value, dmu_tx_t *tx)
+{
+	char name[20];
+
+	(void) snprintf(name, sizeof (name), "%llx", (longlong_t)value);
+	return (zap_remove(os, obj, name, tx));
+}
+
+int
+zap_lookup_int(objset_t *os, uint64_t obj, uint64_t value)
+{
+	char name[20];
+
+	(void) snprintf(name, sizeof (name), "%llx", (longlong_t)value);
+	return (zap_lookup(os, obj, name, 8, 1, &value));
+}
+
+int
+zap_add_int_key(objset_t *os, uint64_t obj,
+    uint64_t key, uint64_t value, dmu_tx_t *tx)
+{
+	char name[20];
+
+	(void) snprintf(name, sizeof (name), "%llx", (longlong_t)key);
+	return (zap_add(os, obj, name, 8, 1, &value, tx));
+}
+
+int
+zap_update_int_key(objset_t *os, uint64_t obj,
+    uint64_t key, uint64_t value, dmu_tx_t *tx)
+{
+	char name[20];
+
+	(void) snprintf(name, sizeof (name), "%llx", (longlong_t)key);
+	return (zap_update(os, obj, name, 8, 1, &value, tx));
+}
+
+int
+zap_lookup_int_key(objset_t *os, uint64_t obj, uint64_t key, uint64_t *valuep)
+{
+	char name[20];
+
+	(void) snprintf(name, sizeof (name), "%llx", (longlong_t)key);
+	return (zap_lookup(os, obj, name, 8, 1, valuep));
+}
+
+int
+zap_increment(objset_t *os, uint64_t obj, const char *name, int64_t delta,
+    dmu_tx_t *tx)
+{
+	uint64_t value = 0;
+	int err;
+
+	if (delta == 0)
+		return (0);
+
+	err = zap_lookup(os, obj, name, 8, 1, &value);
+	if (err != 0 && err != ENOENT)
+		return (err);
+	value += delta;
+	if (value == 0)
+		err = zap_remove(os, obj, name, tx);
+	else
+		err = zap_update(os, obj, name, 8, 1, &value, tx);
+	return (err);
+}
+
+int
+zap_increment_int(objset_t *os, uint64_t obj, uint64_t key, int64_t delta,
+    dmu_tx_t *tx)
+{
+	char name[20];
+
+	(void) snprintf(name, sizeof (name), "%llx", (longlong_t)key);
+	return (zap_increment(os, obj, name, delta, tx));
+}
+
+/*
+ * Routines for iterating over the attributes.
+ */
+
+int
+fzap_cursor_retrieve(zap_t *zap, zap_cursor_t *zc, zap_attribute_t *za)
+{
+	int err = ENOENT;
+	zap_entry_handle_t zeh;
+	zap_leaf_t *l;
+
+	/* retrieve the next entry at or after zc_hash/zc_cd */
+	/* if no entry, return ENOENT */
+
+	if (zc->zc_leaf &&
+	    (ZAP_HASH_IDX(zc->zc_hash,
+	    zap_leaf_phys(zc->zc_leaf)->l_hdr.lh_prefix_len) !=
+	    zap_leaf_phys(zc->zc_leaf)->l_hdr.lh_prefix)) {
+		rw_enter(&zc->zc_leaf->l_rwlock, RW_READER);
+		zap_put_leaf(zc->zc_leaf);
+		zc->zc_leaf = NULL;
+	}
+
+again:
+	if (zc->zc_leaf == NULL) {
+		err = zap_deref_leaf(zap, zc->zc_hash, NULL, RW_READER,
+		    &zc->zc_leaf);
+		if (err != 0)
+			return (err);
+	} else {
+		rw_enter(&zc->zc_leaf->l_rwlock, RW_READER);
+	}
+	l = zc->zc_leaf;
+
+	err = zap_leaf_lookup_closest(l, zc->zc_hash, zc->zc_cd, &zeh);
+
+	if (err == ENOENT) {
+		uint64_t nocare =
+		    (1ULL << (64 - zap_leaf_phys(l)->l_hdr.lh_prefix_len)) - 1;
+		zc->zc_hash = (zc->zc_hash & ~nocare) + nocare + 1;
+		zc->zc_cd = 0;
+		if (zap_leaf_phys(l)->l_hdr.lh_prefix_len == 0 ||
+		    zc->zc_hash == 0) {
+			zc->zc_hash = -1ULL;
+		} else {
+			zap_put_leaf(zc->zc_leaf);
+			zc->zc_leaf = NULL;
+			goto again;
+		}
+	}
+
+	if (err == 0) {
+		zc->zc_hash = zeh.zeh_hash;
+		zc->zc_cd = zeh.zeh_cd;
+		za->za_integer_length = zeh.zeh_integer_size;
+		za->za_num_integers = zeh.zeh_num_integers;
+		if (zeh.zeh_num_integers == 0) {
+			za->za_first_integer = 0;
+		} else {
+			err = zap_entry_read(&zeh, 8, 1, &za->za_first_integer);
+			ASSERT(err == 0 || err == EOVERFLOW);
+		}
+		err = zap_entry_read_name(zap, &zeh,
+		    sizeof (za->za_name), za->za_name);
+		ASSERT(err == 0);
+
+		za->za_normalization_conflict =
+		    zap_entry_normalization_conflict(&zeh,
+		    NULL, za->za_name, zap);
+	}
+	rw_exit(&zc->zc_leaf->l_rwlock);
+	return (err);
+}
+
+static void
+zap_stats_ptrtbl(zap_t *zap, uint64_t *tbl, int len, zap_stats_t *zs)
+{
+	int i, err;
+	uint64_t lastblk = 0;
+
+	/*
+	 * NB: if a leaf has more pointers than an entire ptrtbl block
+	 * can hold, then it'll be accounted for more than once, since
+	 * we won't have lastblk.
+	 */
+	for (i = 0; i < len; i++) {
+		zap_leaf_t *l;
+
+		if (tbl[i] == lastblk)
+			continue;
+		lastblk = tbl[i];
+
+		err = zap_get_leaf_byblk(zap, tbl[i], NULL, RW_READER, &l);
+		if (err == 0) {
+			zap_leaf_stats(zap, l, zs);
+			zap_put_leaf(l);
+		}
+	}
+}
+
+void
+fzap_get_stats(zap_t *zap, zap_stats_t *zs)
+{
+	int bs = FZAP_BLOCK_SHIFT(zap);
+	zs->zs_blocksize = 1ULL << bs;
+
+	/*
+	 * Set zap_phys_t fields
+	 */
+	zs->zs_num_leafs = zap_f_phys(zap)->zap_num_leafs;
+	zs->zs_num_entries = zap_f_phys(zap)->zap_num_entries;
+	zs->zs_num_blocks = zap_f_phys(zap)->zap_freeblk;
+	zs->zs_block_type = zap_f_phys(zap)->zap_block_type;
+	zs->zs_magic = zap_f_phys(zap)->zap_magic;
+	zs->zs_salt = zap_f_phys(zap)->zap_salt;
+
+	/*
+	 * Set zap_ptrtbl fields
+	 */
+	zs->zs_ptrtbl_len = 1ULL << zap_f_phys(zap)->zap_ptrtbl.zt_shift;
+	zs->zs_ptrtbl_nextblk = zap_f_phys(zap)->zap_ptrtbl.zt_nextblk;
+	zs->zs_ptrtbl_blks_copied =
+	    zap_f_phys(zap)->zap_ptrtbl.zt_blks_copied;
+	zs->zs_ptrtbl_zt_blk = zap_f_phys(zap)->zap_ptrtbl.zt_blk;
+	zs->zs_ptrtbl_zt_numblks = zap_f_phys(zap)->zap_ptrtbl.zt_numblks;
+	zs->zs_ptrtbl_zt_shift = zap_f_phys(zap)->zap_ptrtbl.zt_shift;
+
+	if (zap_f_phys(zap)->zap_ptrtbl.zt_numblks == 0) {
+		/* the ptrtbl is entirely in the header block. */
+		zap_stats_ptrtbl(zap, &ZAP_EMBEDDED_PTRTBL_ENT(zap, 0),
+		    1 << ZAP_EMBEDDED_PTRTBL_SHIFT(zap), zs);
+	} else {
+		int b;
+
+		dmu_prefetch(zap->zap_objset, zap->zap_object,
+		    zap_f_phys(zap)->zap_ptrtbl.zt_blk << bs,
+		    zap_f_phys(zap)->zap_ptrtbl.zt_numblks << bs);
+
+		for (b = 0; b < zap_f_phys(zap)->zap_ptrtbl.zt_numblks;
+		    b++) {
+			dmu_buf_t *db;
+			int err;
+
+			err = dmu_buf_hold(zap->zap_objset, zap->zap_object,
+			    (zap_f_phys(zap)->zap_ptrtbl.zt_blk + b) << bs,
+			    FTAG, &db, DMU_READ_NO_PREFETCH);
+			if (err == 0) {
+				zap_stats_ptrtbl(zap, db->db_data,
+				    1<<(bs-3), zs);
+				dmu_buf_rele(db, FTAG);
+			}
+		}
+	}
+}
+
+int
+fzap_count_write(zap_name_t *zn, int add, uint64_t *towrite,
+    uint64_t *tooverwrite)
+{
+	zap_t *zap = zn->zn_zap;
+	zap_leaf_t *l;
+	int err;
+
+	/*
+	 * Account for the header block of the fatzap.
+	 */
+	if (!add && dmu_buf_freeable(zap->zap_dbuf)) {
+		*tooverwrite += zap->zap_dbuf->db_size;
+	} else {
+		*towrite += zap->zap_dbuf->db_size;
+	}
+
+	/*
+	 * Account for the pointer table blocks.
+	 * If we are adding we need to account for the following cases :
+	 * - If the pointer table is embedded, this operation could force an
+	 *   external pointer table.
+	 * - If this already has an external pointer table this operation
+	 *   could extend the table.
+	 */
+	if (add) {
+		if (zap_f_phys(zap)->zap_ptrtbl.zt_blk == 0)
+			*towrite += zap->zap_dbuf->db_size;
+		else
+			*towrite += (zap->zap_dbuf->db_size * 3);
+	}
+
+	/*
+	 * Now, check if the block containing leaf is freeable
+	 * and account accordingly.
+	 */
+	err = zap_deref_leaf(zap, zn->zn_hash, NULL, RW_READER, &l);
+	if (err != 0) {
+		return (err);
+	}
+
+	if (!add && dmu_buf_freeable(l->l_dbuf)) {
+		*tooverwrite += l->l_dbuf->db_size;
+	} else {
+		/*
+		 * If this an add operation, the leaf block could split.
+		 * Hence, we need to account for an additional leaf block.
+		 */
+		*towrite += (add ? 2 : 1) * l->l_dbuf->db_size;
+	}
+
+	zap_put_leaf(l);
+	return (0);
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/module/zfs/zap_leaf.c
@@ -0,0 +1,887 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014 by Delphix. All rights reserved.
+ */
+
+/*
+ * The 512-byte leaf is broken into 32 16-byte chunks.
+ * chunk number n means l_chunk[n], even though the header precedes it.
+ * the names are stored null-terminated.
+ */
+
+#include <sys/zio.h>
+#include <sys/spa.h>
+#include <sys/dmu.h>
+#include <sys/zfs_context.h>
+#include <sys/fs/zfs.h>
+#include <sys/zap.h>
+#include <sys/zap_impl.h>
+#include <sys/zap_leaf.h>
+#include <sys/arc.h>
+
+static uint16_t *zap_leaf_rehash_entry(zap_leaf_t *l, uint16_t entry);
+
+#define	CHAIN_END 0xffff /* end of the chunk chain */
+
+/* half the (current) minimum block size */
+#define	MAX_ARRAY_BYTES (8<<10)
+
+#define	LEAF_HASH(l, h) \
+	((ZAP_LEAF_HASH_NUMENTRIES(l)-1) & \
+	((h) >> \
+	(64 - ZAP_LEAF_HASH_SHIFT(l) - zap_leaf_phys(l)->l_hdr.lh_prefix_len)))
+
+#define	LEAF_HASH_ENTPTR(l, h) (&zap_leaf_phys(l)->l_hash[LEAF_HASH(l, h)])
+
+extern inline zap_leaf_phys_t *zap_leaf_phys(zap_leaf_t *l);
+
+static void
+zap_memset(void *a, int c, size_t n)
+{
+	char *cp = a;
+	char *cpend = cp + n;
+
+	while (cp < cpend)
+		*cp++ = c;
+}
+
+static void
+stv(int len, void *addr, uint64_t value)
+{
+	switch (len) {
+	case 1:
+		*(uint8_t *)addr = value;
+		return;
+	case 2:
+		*(uint16_t *)addr = value;
+		return;
+	case 4:
+		*(uint32_t *)addr = value;
+		return;
+	case 8:
+		*(uint64_t *)addr = value;
+		return;
+	default:
+		cmn_err(CE_PANIC, "bad int len %d", len);
+	}
+}
+
+static uint64_t
+ldv(int len, const void *addr)
+{
+	switch (len) {
+	case 1:
+		return (*(uint8_t *)addr);
+	case 2:
+		return (*(uint16_t *)addr);
+	case 4:
+		return (*(uint32_t *)addr);
+	case 8:
+		return (*(uint64_t *)addr);
+	default:
+		cmn_err(CE_PANIC, "bad int len %d", len);
+	}
+	return (0xFEEDFACEDEADBEEFULL);
+}
+
+void
+zap_leaf_byteswap(zap_leaf_phys_t *buf, int size)
+{
+	int i;
+	zap_leaf_t l;
+	dmu_buf_t l_dbuf;
+
+	l_dbuf.db_data = buf;
+	l.l_bs = highbit64(size) - 1;
+	l.l_dbuf = &l_dbuf;
+
+	buf->l_hdr.lh_block_type =	BSWAP_64(buf->l_hdr.lh_block_type);
+	buf->l_hdr.lh_prefix =		BSWAP_64(buf->l_hdr.lh_prefix);
+	buf->l_hdr.lh_magic =		BSWAP_32(buf->l_hdr.lh_magic);
+	buf->l_hdr.lh_nfree =		BSWAP_16(buf->l_hdr.lh_nfree);
+	buf->l_hdr.lh_nentries =	BSWAP_16(buf->l_hdr.lh_nentries);
+	buf->l_hdr.lh_prefix_len =	BSWAP_16(buf->l_hdr.lh_prefix_len);
+	buf->l_hdr.lh_freelist =	BSWAP_16(buf->l_hdr.lh_freelist);
+
+	for (i = 0; i < ZAP_LEAF_HASH_NUMENTRIES(&l); i++)
+		buf->l_hash[i] = BSWAP_16(buf->l_hash[i]);
+
+	for (i = 0; i < ZAP_LEAF_NUMCHUNKS(&l); i++) {
+		zap_leaf_chunk_t *lc = &ZAP_LEAF_CHUNK(&l, i);
+		struct zap_leaf_entry *le;
+
+		switch (lc->l_free.lf_type) {
+		case ZAP_CHUNK_ENTRY:
+			le = &lc->l_entry;
+
+			le->le_type =		BSWAP_8(le->le_type);
+			le->le_value_intlen =	BSWAP_8(le->le_value_intlen);
+			le->le_next =		BSWAP_16(le->le_next);
+			le->le_name_chunk =	BSWAP_16(le->le_name_chunk);
+			le->le_name_numints =	BSWAP_16(le->le_name_numints);
+			le->le_value_chunk =	BSWAP_16(le->le_value_chunk);
+			le->le_value_numints =	BSWAP_16(le->le_value_numints);
+			le->le_cd =		BSWAP_32(le->le_cd);
+			le->le_hash =		BSWAP_64(le->le_hash);
+			break;
+		case ZAP_CHUNK_FREE:
+			lc->l_free.lf_type =	BSWAP_8(lc->l_free.lf_type);
+			lc->l_free.lf_next =	BSWAP_16(lc->l_free.lf_next);
+			break;
+		case ZAP_CHUNK_ARRAY:
+			lc->l_array.la_type =	BSWAP_8(lc->l_array.la_type);
+			lc->l_array.la_next =	BSWAP_16(lc->l_array.la_next);
+			/* la_array doesn't need swapping */
+			break;
+		default:
+			cmn_err(CE_PANIC, "bad leaf type %d",
+			    lc->l_free.lf_type);
+		}
+	}
+}
+
+void
+zap_leaf_init(zap_leaf_t *l, boolean_t sort)
+{
+	int i;
+
+	l->l_bs = highbit64(l->l_dbuf->db_size) - 1;
+	zap_memset(&zap_leaf_phys(l)->l_hdr, 0,
+	    sizeof (struct zap_leaf_header));
+	zap_memset(zap_leaf_phys(l)->l_hash, CHAIN_END,
+	    2*ZAP_LEAF_HASH_NUMENTRIES(l));
+	for (i = 0; i < ZAP_LEAF_NUMCHUNKS(l); i++) {
+		ZAP_LEAF_CHUNK(l, i).l_free.lf_type = ZAP_CHUNK_FREE;
+		ZAP_LEAF_CHUNK(l, i).l_free.lf_next = i+1;
+	}
+	ZAP_LEAF_CHUNK(l, ZAP_LEAF_NUMCHUNKS(l)-1).l_free.lf_next = CHAIN_END;
+	zap_leaf_phys(l)->l_hdr.lh_block_type = ZBT_LEAF;
+	zap_leaf_phys(l)->l_hdr.lh_magic = ZAP_LEAF_MAGIC;
+	zap_leaf_phys(l)->l_hdr.lh_nfree = ZAP_LEAF_NUMCHUNKS(l);
+	if (sort)
+		zap_leaf_phys(l)->l_hdr.lh_flags |= ZLF_ENTRIES_CDSORTED;
+}
+
+/*
+ * Routines which manipulate leaf chunks (l_chunk[]).
+ */
+
+static uint16_t
+zap_leaf_chunk_alloc(zap_leaf_t *l)
+{
+	int chunk;
+
+	ASSERT(zap_leaf_phys(l)->l_hdr.lh_nfree > 0);
+
+	chunk = zap_leaf_phys(l)->l_hdr.lh_freelist;
+	ASSERT3U(chunk, <, ZAP_LEAF_NUMCHUNKS(l));
+	ASSERT3U(ZAP_LEAF_CHUNK(l, chunk).l_free.lf_type, ==, ZAP_CHUNK_FREE);
+
+	zap_leaf_phys(l)->l_hdr.lh_freelist =
+	    ZAP_LEAF_CHUNK(l, chunk).l_free.lf_next;
+
+	zap_leaf_phys(l)->l_hdr.lh_nfree--;
+
+	return (chunk);
+}
+
+static void
+zap_leaf_chunk_free(zap_leaf_t *l, uint16_t chunk)
+{
+	struct zap_leaf_free *zlf = &ZAP_LEAF_CHUNK(l, chunk).l_free;
+	ASSERT3U(zap_leaf_phys(l)->l_hdr.lh_nfree, <, ZAP_LEAF_NUMCHUNKS(l));
+	ASSERT3U(chunk, <, ZAP_LEAF_NUMCHUNKS(l));
+	ASSERT(zlf->lf_type != ZAP_CHUNK_FREE);
+
+	zlf->lf_type = ZAP_CHUNK_FREE;
+	zlf->lf_next = zap_leaf_phys(l)->l_hdr.lh_freelist;
+	bzero(zlf->lf_pad, sizeof (zlf->lf_pad)); /* help it to compress */
+	zap_leaf_phys(l)->l_hdr.lh_freelist = chunk;
+
+	zap_leaf_phys(l)->l_hdr.lh_nfree++;
+}
+
+/*
+ * Routines which manipulate leaf arrays (zap_leaf_array type chunks).
+ */
+
+static uint16_t
+zap_leaf_array_create(zap_leaf_t *l, const char *buf,
+    int integer_size, int num_integers)
+{
+	uint16_t chunk_head;
+	uint16_t *chunkp = &chunk_head;
+	int byten = 0;
+	uint64_t value = 0;
+	int shift = (integer_size-1)*8;
+	int len = num_integers;
+
+	ASSERT3U(num_integers * integer_size, <, MAX_ARRAY_BYTES);
+
+	while (len > 0) {
+		uint16_t chunk = zap_leaf_chunk_alloc(l);
+		struct zap_leaf_array *la = &ZAP_LEAF_CHUNK(l, chunk).l_array;
+		int i;
+
+		la->la_type = ZAP_CHUNK_ARRAY;
+		for (i = 0; i < ZAP_LEAF_ARRAY_BYTES; i++) {
+			if (byten == 0)
+				value = ldv(integer_size, buf);
+			la->la_array[i] = value >> shift;
+			value <<= 8;
+			if (++byten == integer_size) {
+				byten = 0;
+				buf += integer_size;
+				if (--len == 0)
+					break;
+			}
+		}
+
+		*chunkp = chunk;
+		chunkp = &la->la_next;
+	}
+	*chunkp = CHAIN_END;
+
+	return (chunk_head);
+}
+
+static void
+zap_leaf_array_free(zap_leaf_t *l, uint16_t *chunkp)
+{
+	uint16_t chunk = *chunkp;
+
+	*chunkp = CHAIN_END;
+
+	while (chunk != CHAIN_END) {
+		int nextchunk = ZAP_LEAF_CHUNK(l, chunk).l_array.la_next;
+		ASSERT3U(ZAP_LEAF_CHUNK(l, chunk).l_array.la_type, ==,
+		    ZAP_CHUNK_ARRAY);
+		zap_leaf_chunk_free(l, chunk);
+		chunk = nextchunk;
+	}
+}
+
+/* array_len and buf_len are in integers, not bytes */
+static void
+zap_leaf_array_read(zap_leaf_t *l, uint16_t chunk,
+    int array_int_len, int array_len, int buf_int_len, uint64_t buf_len,
+    void *buf)
+{
+	int len = MIN(array_len, buf_len);
+	int byten = 0;
+	uint64_t value = 0;
+	char *p = buf;
+
+	ASSERT3U(array_int_len, <=, buf_int_len);
+
+	/* Fast path for one 8-byte integer */
+	if (array_int_len == 8 && buf_int_len == 8 && len == 1) {
+		struct zap_leaf_array *la = &ZAP_LEAF_CHUNK(l, chunk).l_array;
+		uint8_t *ip = la->la_array;
+		uint64_t *buf64 = buf;
+
+		*buf64 = (uint64_t)ip[0] << 56 | (uint64_t)ip[1] << 48 |
+		    (uint64_t)ip[2] << 40 | (uint64_t)ip[3] << 32 |
+		    (uint64_t)ip[4] << 24 | (uint64_t)ip[5] << 16 |
+		    (uint64_t)ip[6] << 8 | (uint64_t)ip[7];
+		return;
+	}
+
+	/* Fast path for an array of 1-byte integers (eg. the entry name) */
+	if (array_int_len == 1 && buf_int_len == 1 &&
+	    buf_len > array_len + ZAP_LEAF_ARRAY_BYTES) {
+		while (chunk != CHAIN_END) {
+			struct zap_leaf_array *la =
+			    &ZAP_LEAF_CHUNK(l, chunk).l_array;
+			bcopy(la->la_array, p, ZAP_LEAF_ARRAY_BYTES);
+			p += ZAP_LEAF_ARRAY_BYTES;
+			chunk = la->la_next;
+		}
+		return;
+	}
+
+	while (len > 0) {
+		struct zap_leaf_array *la = &ZAP_LEAF_CHUNK(l, chunk).l_array;
+		int i;
+
+		ASSERT3U(chunk, <, ZAP_LEAF_NUMCHUNKS(l));
+		for (i = 0; i < ZAP_LEAF_ARRAY_BYTES && len > 0; i++) {
+			value = (value << 8) | la->la_array[i];
+			byten++;
+			if (byten == array_int_len) {
+				stv(buf_int_len, p, value);
+				byten = 0;
+				len--;
+				if (len == 0)
+					return;
+				p += buf_int_len;
+			}
+		}
+		chunk = la->la_next;
+	}
+}
+
+static boolean_t
+zap_leaf_array_match(zap_leaf_t *l, zap_name_t *zn,
+    int chunk, int array_numints)
+{
+	int bseen = 0;
+
+	if (zap_getflags(zn->zn_zap) & ZAP_FLAG_UINT64_KEY) {
+		uint64_t *thiskey;
+		boolean_t match;
+
+		ASSERT(zn->zn_key_intlen == sizeof (*thiskey));
+		thiskey = kmem_alloc(array_numints * sizeof (*thiskey),
+		    KM_SLEEP);
+
+		zap_leaf_array_read(l, chunk, sizeof (*thiskey), array_numints,
+		    sizeof (*thiskey), array_numints, thiskey);
+		match = bcmp(thiskey, zn->zn_key_orig,
+		    array_numints * sizeof (*thiskey)) == 0;
+		kmem_free(thiskey, array_numints * sizeof (*thiskey));
+		return (match);
+	}
+
+	ASSERT(zn->zn_key_intlen == 1);
+	if (zn->zn_matchtype == MT_FIRST) {
+		char *thisname = kmem_alloc(array_numints, KM_SLEEP);
+		boolean_t match;
+
+		zap_leaf_array_read(l, chunk, sizeof (char), array_numints,
+		    sizeof (char), array_numints, thisname);
+		match = zap_match(zn, thisname);
+		kmem_free(thisname, array_numints);
+		return (match);
+	}
+
+	/*
+	 * Fast path for exact matching.
+	 * First check that the lengths match, so that we don't read
+	 * past the end of the zn_key_orig array.
+	 */
+	if (array_numints != zn->zn_key_orig_numints)
+		return (B_FALSE);
+	while (bseen < array_numints) {
+		struct zap_leaf_array *la = &ZAP_LEAF_CHUNK(l, chunk).l_array;
+		int toread = MIN(array_numints - bseen, ZAP_LEAF_ARRAY_BYTES);
+		ASSERT3U(chunk, <, ZAP_LEAF_NUMCHUNKS(l));
+		if (bcmp(la->la_array, (char *)zn->zn_key_orig + bseen, toread))
+			break;
+		chunk = la->la_next;
+		bseen += toread;
+	}
+	return (bseen == array_numints);
+}
+
+/*
+ * Routines which manipulate leaf entries.
+ */
+
+int
+zap_leaf_lookup(zap_leaf_t *l, zap_name_t *zn, zap_entry_handle_t *zeh)
+{
+	uint16_t *chunkp;
+	struct zap_leaf_entry *le;
+
+	ASSERT3U(zap_leaf_phys(l)->l_hdr.lh_magic, ==, ZAP_LEAF_MAGIC);
+
+again:
+	for (chunkp = LEAF_HASH_ENTPTR(l, zn->zn_hash);
+	    *chunkp != CHAIN_END; chunkp = &le->le_next) {
+		uint16_t chunk = *chunkp;
+		le = ZAP_LEAF_ENTRY(l, chunk);
+
+		ASSERT3U(chunk, <, ZAP_LEAF_NUMCHUNKS(l));
+		ASSERT3U(le->le_type, ==, ZAP_CHUNK_ENTRY);
+
+		if (le->le_hash != zn->zn_hash)
+			continue;
+
+		/*
+		 * NB: the entry chain is always sorted by cd on
+		 * normalized zap objects, so this will find the
+		 * lowest-cd match for MT_FIRST.
+		 */
+		ASSERT(zn->zn_matchtype == MT_EXACT ||
+		    (zap_leaf_phys(l)->l_hdr.lh_flags & ZLF_ENTRIES_CDSORTED));
+		if (zap_leaf_array_match(l, zn, le->le_name_chunk,
+		    le->le_name_numints)) {
+			zeh->zeh_num_integers = le->le_value_numints;
+			zeh->zeh_integer_size = le->le_value_intlen;
+			zeh->zeh_cd = le->le_cd;
+			zeh->zeh_hash = le->le_hash;
+			zeh->zeh_chunkp = chunkp;
+			zeh->zeh_leaf = l;
+			return (0);
+		}
+	}
+
+	/*
+	 * NB: we could of course do this in one pass, but that would be
+	 * a pain.  We'll see if MT_BEST is even used much.
+	 */
+	if (zn->zn_matchtype == MT_BEST) {
+		zn->zn_matchtype = MT_FIRST;
+		goto again;
+	}
+
+	return (SET_ERROR(ENOENT));
+}
+
+/* Return (h1,cd1 >= h2,cd2) */
+#define	HCD_GTEQ(h1, cd1, h2, cd2) \
+	((h1 > h2) ? TRUE : ((h1 == h2 && cd1 >= cd2) ? TRUE : FALSE))
+
+int
+zap_leaf_lookup_closest(zap_leaf_t *l,
+    uint64_t h, uint32_t cd, zap_entry_handle_t *zeh)
+{
+	uint16_t chunk;
+	uint64_t besth = -1ULL;
+	uint32_t bestcd = -1U;
+	uint16_t bestlh = ZAP_LEAF_HASH_NUMENTRIES(l)-1;
+	uint16_t lh;
+	struct zap_leaf_entry *le;
+
+	ASSERT3U(zap_leaf_phys(l)->l_hdr.lh_magic, ==, ZAP_LEAF_MAGIC);
+
+	for (lh = LEAF_HASH(l, h); lh <= bestlh; lh++) {
+		for (chunk = zap_leaf_phys(l)->l_hash[lh];
+		    chunk != CHAIN_END; chunk = le->le_next) {
+			le = ZAP_LEAF_ENTRY(l, chunk);
+
+			ASSERT3U(chunk, <, ZAP_LEAF_NUMCHUNKS(l));
+			ASSERT3U(le->le_type, ==, ZAP_CHUNK_ENTRY);
+
+			if (HCD_GTEQ(le->le_hash, le->le_cd, h, cd) &&
+			    HCD_GTEQ(besth, bestcd, le->le_hash, le->le_cd)) {
+				ASSERT3U(bestlh, >=, lh);
+				bestlh = lh;
+				besth = le->le_hash;
+				bestcd = le->le_cd;
+
+				zeh->zeh_num_integers = le->le_value_numints;
+				zeh->zeh_integer_size = le->le_value_intlen;
+				zeh->zeh_cd = le->le_cd;
+				zeh->zeh_hash = le->le_hash;
+				zeh->zeh_fakechunk = chunk;
+				zeh->zeh_chunkp = &zeh->zeh_fakechunk;
+				zeh->zeh_leaf = l;
+			}
+		}
+	}
+
+	return (bestcd == -1U ? ENOENT : 0);
+}
+
+int
+zap_entry_read(const zap_entry_handle_t *zeh,
+    uint8_t integer_size, uint64_t num_integers, void *buf)
+{
+	struct zap_leaf_entry *le =
+	    ZAP_LEAF_ENTRY(zeh->zeh_leaf, *zeh->zeh_chunkp);
+	ASSERT3U(le->le_type, ==, ZAP_CHUNK_ENTRY);
+
+	if (le->le_value_intlen > integer_size)
+		return (SET_ERROR(EINVAL));
+
+	zap_leaf_array_read(zeh->zeh_leaf, le->le_value_chunk,
+	    le->le_value_intlen, le->le_value_numints,
+	    integer_size, num_integers, buf);
+
+	if (zeh->zeh_num_integers > num_integers)
+		return (SET_ERROR(EOVERFLOW));
+	return (0);
+
+}
+
+int
+zap_entry_read_name(zap_t *zap, const zap_entry_handle_t *zeh, uint16_t buflen,
+    char *buf)
+{
+	struct zap_leaf_entry *le =
+	    ZAP_LEAF_ENTRY(zeh->zeh_leaf, *zeh->zeh_chunkp);
+	ASSERT3U(le->le_type, ==, ZAP_CHUNK_ENTRY);
+
+	if (zap_getflags(zap) & ZAP_FLAG_UINT64_KEY) {
+		zap_leaf_array_read(zeh->zeh_leaf, le->le_name_chunk, 8,
+		    le->le_name_numints, 8, buflen / 8, buf);
+	} else {
+		zap_leaf_array_read(zeh->zeh_leaf, le->le_name_chunk, 1,
+		    le->le_name_numints, 1, buflen, buf);
+	}
+	if (le->le_name_numints > buflen)
+		return (SET_ERROR(EOVERFLOW));
+	return (0);
+}
+
+int
+zap_entry_update(zap_entry_handle_t *zeh,
+	uint8_t integer_size, uint64_t num_integers, const void *buf)
+{
+	int delta_chunks;
+	zap_leaf_t *l = zeh->zeh_leaf;
+	struct zap_leaf_entry *le = ZAP_LEAF_ENTRY(l, *zeh->zeh_chunkp);
+
+	delta_chunks = ZAP_LEAF_ARRAY_NCHUNKS(num_integers * integer_size) -
+	    ZAP_LEAF_ARRAY_NCHUNKS(le->le_value_numints * le->le_value_intlen);
+
+	if ((int)zap_leaf_phys(l)->l_hdr.lh_nfree < delta_chunks)
+		return (SET_ERROR(EAGAIN));
+
+	zap_leaf_array_free(l, &le->le_value_chunk);
+	le->le_value_chunk =
+	    zap_leaf_array_create(l, buf, integer_size, num_integers);
+	le->le_value_numints = num_integers;
+	le->le_value_intlen = integer_size;
+	return (0);
+}
+
+void
+zap_entry_remove(zap_entry_handle_t *zeh)
+{
+	uint16_t entry_chunk;
+	struct zap_leaf_entry *le;
+	zap_leaf_t *l = zeh->zeh_leaf;
+
+	ASSERT3P(zeh->zeh_chunkp, !=, &zeh->zeh_fakechunk);
+
+	entry_chunk = *zeh->zeh_chunkp;
+	le = ZAP_LEAF_ENTRY(l, entry_chunk);
+	ASSERT3U(le->le_type, ==, ZAP_CHUNK_ENTRY);
+
+	zap_leaf_array_free(l, &le->le_name_chunk);
+	zap_leaf_array_free(l, &le->le_value_chunk);
+
+	*zeh->zeh_chunkp = le->le_next;
+	zap_leaf_chunk_free(l, entry_chunk);
+
+	zap_leaf_phys(l)->l_hdr.lh_nentries--;
+}
+
+int
+zap_entry_create(zap_leaf_t *l, zap_name_t *zn, uint32_t cd,
+    uint8_t integer_size, uint64_t num_integers, const void *buf,
+    zap_entry_handle_t *zeh)
+{
+	uint16_t chunk;
+	uint16_t *chunkp;
+	struct zap_leaf_entry *le;
+	uint64_t valuelen;
+	int numchunks;
+	uint64_t h = zn->zn_hash;
+
+	valuelen = integer_size * num_integers;
+
+	numchunks = 1 + ZAP_LEAF_ARRAY_NCHUNKS(zn->zn_key_orig_numints *
+	    zn->zn_key_intlen) + ZAP_LEAF_ARRAY_NCHUNKS(valuelen);
+	if (numchunks > ZAP_LEAF_NUMCHUNKS(l))
+		return (E2BIG);
+
+	if (cd == ZAP_NEED_CD) {
+		/* find the lowest unused cd */
+		if (zap_leaf_phys(l)->l_hdr.lh_flags & ZLF_ENTRIES_CDSORTED) {
+			cd = 0;
+
+			for (chunk = *LEAF_HASH_ENTPTR(l, h);
+			    chunk != CHAIN_END; chunk = le->le_next) {
+				le = ZAP_LEAF_ENTRY(l, chunk);
+				if (le->le_cd > cd)
+					break;
+				if (le->le_hash == h) {
+					ASSERT3U(cd, ==, le->le_cd);
+					cd++;
+				}
+			}
+		} else {
+			/* old unsorted format; do it the O(n^2) way */
+			for (cd = 0; ; cd++) {
+				for (chunk = *LEAF_HASH_ENTPTR(l, h);
+				    chunk != CHAIN_END; chunk = le->le_next) {
+					le = ZAP_LEAF_ENTRY(l, chunk);
+					if (le->le_hash == h &&
+					    le->le_cd == cd) {
+						break;
+					}
+				}
+				/* If this cd is not in use, we are good. */
+				if (chunk == CHAIN_END)
+					break;
+			}
+		}
+		/*
+		 * We would run out of space in a block before we could
+		 * store enough entries to run out of CD values.
+		 */
+		ASSERT3U(cd, <, zap_maxcd(zn->zn_zap));
+	}
+
+	if (zap_leaf_phys(l)->l_hdr.lh_nfree < numchunks)
+		return (SET_ERROR(EAGAIN));
+
+	/* make the entry */
+	chunk = zap_leaf_chunk_alloc(l);
+	le = ZAP_LEAF_ENTRY(l, chunk);
+	le->le_type = ZAP_CHUNK_ENTRY;
+	le->le_name_chunk = zap_leaf_array_create(l, zn->zn_key_orig,
+	    zn->zn_key_intlen, zn->zn_key_orig_numints);
+	le->le_name_numints = zn->zn_key_orig_numints;
+	le->le_value_chunk =
+	    zap_leaf_array_create(l, buf, integer_size, num_integers);
+	le->le_value_numints = num_integers;
+	le->le_value_intlen = integer_size;
+	le->le_hash = h;
+	le->le_cd = cd;
+
+	/* link it into the hash chain */
+	/* XXX if we did the search above, we could just use that */
+	chunkp = zap_leaf_rehash_entry(l, chunk);
+
+	zap_leaf_phys(l)->l_hdr.lh_nentries++;
+
+	zeh->zeh_leaf = l;
+	zeh->zeh_num_integers = num_integers;
+	zeh->zeh_integer_size = le->le_value_intlen;
+	zeh->zeh_cd = le->le_cd;
+	zeh->zeh_hash = le->le_hash;
+	zeh->zeh_chunkp = chunkp;
+
+	return (0);
+}
+
+/*
+ * Determine if there is another entry with the same normalized form.
+ * For performance purposes, either zn or name must be provided (the
+ * other can be NULL).  Note, there usually won't be any hash
+ * conflicts, in which case we don't need the concatenated/normalized
+ * form of the name.  But all callers have one of these on hand anyway,
+ * so might as well take advantage.  A cleaner but slower interface
+ * would accept neither argument, and compute the normalized name as
+ * needed (using zap_name_alloc(zap_entry_read_name(zeh))).
+ */
+boolean_t
+zap_entry_normalization_conflict(zap_entry_handle_t *zeh, zap_name_t *zn,
+    const char *name, zap_t *zap)
+{
+	uint64_t chunk;
+	struct zap_leaf_entry *le;
+	boolean_t allocdzn = B_FALSE;
+
+	if (zap->zap_normflags == 0)
+		return (B_FALSE);
+
+	for (chunk = *LEAF_HASH_ENTPTR(zeh->zeh_leaf, zeh->zeh_hash);
+	    chunk != CHAIN_END; chunk = le->le_next) {
+		le = ZAP_LEAF_ENTRY(zeh->zeh_leaf, chunk);
+		if (le->le_hash != zeh->zeh_hash)
+			continue;
+		if (le->le_cd == zeh->zeh_cd)
+			continue;
+
+		if (zn == NULL) {
+			zn = zap_name_alloc(zap, name, MT_FIRST);
+			allocdzn = B_TRUE;
+		}
+		if (zap_leaf_array_match(zeh->zeh_leaf, zn,
+		    le->le_name_chunk, le->le_name_numints)) {
+			if (allocdzn)
+				zap_name_free(zn);
+			return (B_TRUE);
+		}
+	}
+	if (allocdzn)
+		zap_name_free(zn);
+	return (B_FALSE);
+}
+
+/*
+ * Routines for transferring entries between leafs.
+ */
+
+static uint16_t *
+zap_leaf_rehash_entry(zap_leaf_t *l, uint16_t entry)
+{
+	struct zap_leaf_entry *le = ZAP_LEAF_ENTRY(l, entry);
+	struct zap_leaf_entry *le2;
+	uint16_t *chunkp;
+
+	/*
+	 * keep the entry chain sorted by cd
+	 * NB: this will not cause problems for unsorted leafs, though
+	 * it is unnecessary there.
+	 */
+	for (chunkp = LEAF_HASH_ENTPTR(l, le->le_hash);
+	    *chunkp != CHAIN_END; chunkp = &le2->le_next) {
+		le2 = ZAP_LEAF_ENTRY(l, *chunkp);
+		if (le2->le_cd > le->le_cd)
+			break;
+	}
+
+	le->le_next = *chunkp;
+	*chunkp = entry;
+	return (chunkp);
+}
+
+static uint16_t
+zap_leaf_transfer_array(zap_leaf_t *l, uint16_t chunk, zap_leaf_t *nl)
+{
+	uint16_t new_chunk;
+	uint16_t *nchunkp = &new_chunk;
+
+	while (chunk != CHAIN_END) {
+		uint16_t nchunk = zap_leaf_chunk_alloc(nl);
+		struct zap_leaf_array *nla =
+		    &ZAP_LEAF_CHUNK(nl, nchunk).l_array;
+		struct zap_leaf_array *la =
+		    &ZAP_LEAF_CHUNK(l, chunk).l_array;
+		int nextchunk = la->la_next;
+
+		ASSERT3U(chunk, <, ZAP_LEAF_NUMCHUNKS(l));
+		ASSERT3U(nchunk, <, ZAP_LEAF_NUMCHUNKS(l));
+
+		*nla = *la; /* structure assignment */
+
+		zap_leaf_chunk_free(l, chunk);
+		chunk = nextchunk;
+		*nchunkp = nchunk;
+		nchunkp = &nla->la_next;
+	}
+	*nchunkp = CHAIN_END;
+	return (new_chunk);
+}
+
+static void
+zap_leaf_transfer_entry(zap_leaf_t *l, int entry, zap_leaf_t *nl)
+{
+	struct zap_leaf_entry *le, *nle;
+	uint16_t chunk;
+
+	le = ZAP_LEAF_ENTRY(l, entry);
+	ASSERT3U(le->le_type, ==, ZAP_CHUNK_ENTRY);
+
+	chunk = zap_leaf_chunk_alloc(nl);
+	nle = ZAP_LEAF_ENTRY(nl, chunk);
+	*nle = *le; /* structure assignment */
+
+	(void) zap_leaf_rehash_entry(nl, chunk);
+
+	nle->le_name_chunk = zap_leaf_transfer_array(l, le->le_name_chunk, nl);
+	nle->le_value_chunk =
+	    zap_leaf_transfer_array(l, le->le_value_chunk, nl);
+
+	zap_leaf_chunk_free(l, entry);
+
+	zap_leaf_phys(l)->l_hdr.lh_nentries--;
+	zap_leaf_phys(nl)->l_hdr.lh_nentries++;
+}
+
+/*
+ * Transfer the entries whose hash prefix ends in 1 to the new leaf.
+ */
+void
+zap_leaf_split(zap_leaf_t *l, zap_leaf_t *nl, boolean_t sort)
+{
+	int i;
+	int bit = 64 - 1 - zap_leaf_phys(l)->l_hdr.lh_prefix_len;
+
+	/* set new prefix and prefix_len */
+	zap_leaf_phys(l)->l_hdr.lh_prefix <<= 1;
+	zap_leaf_phys(l)->l_hdr.lh_prefix_len++;
+	zap_leaf_phys(nl)->l_hdr.lh_prefix =
+	    zap_leaf_phys(l)->l_hdr.lh_prefix | 1;
+	zap_leaf_phys(nl)->l_hdr.lh_prefix_len =
+	    zap_leaf_phys(l)->l_hdr.lh_prefix_len;
+
+	/* break existing hash chains */
+	zap_memset(zap_leaf_phys(l)->l_hash, CHAIN_END,
+	    2*ZAP_LEAF_HASH_NUMENTRIES(l));
+
+	if (sort)
+		zap_leaf_phys(l)->l_hdr.lh_flags |= ZLF_ENTRIES_CDSORTED;
+
+	/*
+	 * Transfer entries whose hash bit 'bit' is set to nl; rehash
+	 * the remaining entries
+	 *
+	 * NB: We could find entries via the hashtable instead. That
+	 * would be O(hashents+numents) rather than O(numblks+numents),
+	 * but this accesses memory more sequentially, and when we're
+	 * called, the block is usually pretty full.
+	 */
+	for (i = 0; i < ZAP_LEAF_NUMCHUNKS(l); i++) {
+		struct zap_leaf_entry *le = ZAP_LEAF_ENTRY(l, i);
+		if (le->le_type != ZAP_CHUNK_ENTRY)
+			continue;
+
+		if (le->le_hash & (1ULL << bit))
+			zap_leaf_transfer_entry(l, i, nl);
+		else
+			(void) zap_leaf_rehash_entry(l, i);
+	}
+}
+
+void
+zap_leaf_stats(zap_t *zap, zap_leaf_t *l, zap_stats_t *zs)
+{
+	int i, n;
+
+	n = zap_f_phys(zap)->zap_ptrtbl.zt_shift -
+	    zap_leaf_phys(l)->l_hdr.lh_prefix_len;
+	n = MIN(n, ZAP_HISTOGRAM_SIZE-1);
+	zs->zs_leafs_with_2n_pointers[n]++;
+
+
+	n = zap_leaf_phys(l)->l_hdr.lh_nentries/5;
+	n = MIN(n, ZAP_HISTOGRAM_SIZE-1);
+	zs->zs_blocks_with_n5_entries[n]++;
+
+	n = ((1<<FZAP_BLOCK_SHIFT(zap)) -
+	    zap_leaf_phys(l)->l_hdr.lh_nfree * (ZAP_LEAF_ARRAY_BYTES+1))*10 /
+	    (1<<FZAP_BLOCK_SHIFT(zap));
+	n = MIN(n, ZAP_HISTOGRAM_SIZE-1);
+	zs->zs_blocks_n_tenths_full[n]++;
+
+	for (i = 0; i < ZAP_LEAF_HASH_NUMENTRIES(l); i++) {
+		int nentries = 0;
+		int chunk = zap_leaf_phys(l)->l_hash[i];
+
+		while (chunk != CHAIN_END) {
+			struct zap_leaf_entry *le =
+			    ZAP_LEAF_ENTRY(l, chunk);
+
+			n = 1 + ZAP_LEAF_ARRAY_NCHUNKS(le->le_name_numints) +
+			    ZAP_LEAF_ARRAY_NCHUNKS(le->le_value_numints *
+			    le->le_value_intlen);
+			n = MIN(n, ZAP_HISTOGRAM_SIZE-1);
+			zs->zs_entries_using_n_chunks[n]++;
+
+			chunk = le->le_next;
+			nentries++;
+		}
+
+		n = nentries;
+		n = MIN(n, ZAP_HISTOGRAM_SIZE-1);
+		zs->zs_buckets_with_n_entries[n]++;
+	}
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/module/zfs/zap_micro.c
@@ -0,0 +1,1482 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2014 by Delphix. All rights reserved.
+ * Copyright (c) 2014 Spectra Logic Corporation, All rights reserved.
+ */
+
+#include <sys/zio.h>
+#include <sys/spa.h>
+#include <sys/dmu.h>
+#include <sys/zfs_context.h>
+#include <sys/zap.h>
+#include <sys/refcount.h>
+#include <sys/zap_impl.h>
+#include <sys/zap_leaf.h>
+#include <sys/avl.h>
+#include <sys/arc.h>
+#include <sys/dmu_objset.h>
+
+#ifdef _KERNEL
+#include <sys/sunddi.h>
+#endif
+
+extern inline mzap_phys_t *zap_m_phys(zap_t *zap);
+
+static int mzap_upgrade(zap_t **zapp, dmu_tx_t *tx, zap_flags_t flags);
+
+uint64_t
+zap_getflags(zap_t *zap)
+{
+	if (zap->zap_ismicro)
+		return (0);
+	return (zap_f_phys(zap)->zap_flags);
+}
+
+int
+zap_hashbits(zap_t *zap)
+{
+	if (zap_getflags(zap) & ZAP_FLAG_HASH64)
+		return (48);
+	else
+		return (28);
+}
+
+uint32_t
+zap_maxcd(zap_t *zap)
+{
+	if (zap_getflags(zap) & ZAP_FLAG_HASH64)
+		return ((1<<16)-1);
+	else
+		return (-1U);
+}
+
+static uint64_t
+zap_hash(zap_name_t *zn)
+{
+	zap_t *zap = zn->zn_zap;
+	uint64_t h = 0;
+
+	if (zap_getflags(zap) & ZAP_FLAG_PRE_HASHED_KEY) {
+		ASSERT(zap_getflags(zap) & ZAP_FLAG_UINT64_KEY);
+		h = *(uint64_t *)zn->zn_key_orig;
+	} else {
+		h = zap->zap_salt;
+		ASSERT(h != 0);
+		ASSERT(zfs_crc64_table[128] == ZFS_CRC64_POLY);
+
+		if (zap_getflags(zap) & ZAP_FLAG_UINT64_KEY) {
+			int i;
+			const uint64_t *wp = zn->zn_key_norm;
+
+			ASSERT(zn->zn_key_intlen == 8);
+			for (i = 0; i < zn->zn_key_norm_numints; wp++, i++) {
+				int j;
+				uint64_t word = *wp;
+
+				for (j = 0; j < zn->zn_key_intlen; j++) {
+					h = (h >> 8) ^
+					    zfs_crc64_table[(h ^ word) & 0xFF];
+					word >>= NBBY;
+				}
+			}
+		} else {
+			int i, len;
+			const uint8_t *cp = zn->zn_key_norm;
+
+			/*
+			 * We previously stored the terminating null on
+			 * disk, but didn't hash it, so we need to
+			 * continue to not hash it.  (The
+			 * zn_key_*_numints includes the terminating
+			 * null for non-binary keys.)
+			 */
+			len = zn->zn_key_norm_numints - 1;
+
+			ASSERT(zn->zn_key_intlen == 1);
+			for (i = 0; i < len; cp++, i++) {
+				h = (h >> 8) ^
+				    zfs_crc64_table[(h ^ *cp) & 0xFF];
+			}
+		}
+	}
+	/*
+	 * Don't use all 64 bits, since we need some in the cookie for
+	 * the collision differentiator.  We MUST use the high bits,
+	 * since those are the ones that we first pay attention to when
+	 * chosing the bucket.
+	 */
+	h &= ~((1ULL << (64 - zap_hashbits(zap))) - 1);
+
+	return (h);
+}
+
+static int
+zap_normalize(zap_t *zap, const char *name, char *namenorm)
+{
+	size_t inlen, outlen;
+	int err;
+
+	ASSERT(!(zap_getflags(zap) & ZAP_FLAG_UINT64_KEY));
+
+	inlen = strlen(name) + 1;
+	outlen = ZAP_MAXNAMELEN;
+
+	err = 0;
+	(void) u8_textprep_str((char *)name, &inlen, namenorm, &outlen,
+	    zap->zap_normflags | U8_TEXTPREP_IGNORE_NULL |
+	    U8_TEXTPREP_IGNORE_INVALID, U8_UNICODE_LATEST, &err);
+
+	return (err);
+}
+
+boolean_t
+zap_match(zap_name_t *zn, const char *matchname)
+{
+	ASSERT(!(zap_getflags(zn->zn_zap) & ZAP_FLAG_UINT64_KEY));
+
+	if (zn->zn_matchtype == MT_FIRST) {
+		char norm[ZAP_MAXNAMELEN];
+
+		if (zap_normalize(zn->zn_zap, matchname, norm) != 0)
+			return (B_FALSE);
+
+		return (strcmp(zn->zn_key_norm, norm) == 0);
+	} else {
+		/* MT_BEST or MT_EXACT */
+		return (strcmp(zn->zn_key_orig, matchname) == 0);
+	}
+}
+
+void
+zap_name_free(zap_name_t *zn)
+{
+	kmem_free(zn, sizeof (zap_name_t));
+}
+
+zap_name_t *
+zap_name_alloc(zap_t *zap, const char *key, matchtype_t mt)
+{
+	zap_name_t *zn = kmem_alloc(sizeof (zap_name_t), KM_SLEEP);
+
+	zn->zn_zap = zap;
+	zn->zn_key_intlen = sizeof (*key);
+	zn->zn_key_orig = key;
+	zn->zn_key_orig_numints = strlen(zn->zn_key_orig) + 1;
+	zn->zn_matchtype = mt;
+	if (zap->zap_normflags) {
+		if (zap_normalize(zap, key, zn->zn_normbuf) != 0) {
+			zap_name_free(zn);
+			return (NULL);
+		}
+		zn->zn_key_norm = zn->zn_normbuf;
+		zn->zn_key_norm_numints = strlen(zn->zn_key_norm) + 1;
+	} else {
+		if (mt != MT_EXACT) {
+			zap_name_free(zn);
+			return (NULL);
+		}
+		zn->zn_key_norm = zn->zn_key_orig;
+		zn->zn_key_norm_numints = zn->zn_key_orig_numints;
+	}
+
+	zn->zn_hash = zap_hash(zn);
+	return (zn);
+}
+
+zap_name_t *
+zap_name_alloc_uint64(zap_t *zap, const uint64_t *key, int numints)
+{
+	zap_name_t *zn = kmem_alloc(sizeof (zap_name_t), KM_SLEEP);
+
+	ASSERT(zap->zap_normflags == 0);
+	zn->zn_zap = zap;
+	zn->zn_key_intlen = sizeof (*key);
+	zn->zn_key_orig = zn->zn_key_norm = key;
+	zn->zn_key_orig_numints = zn->zn_key_norm_numints = numints;
+	zn->zn_matchtype = MT_EXACT;
+
+	zn->zn_hash = zap_hash(zn);
+	return (zn);
+}
+
+static void
+mzap_byteswap(mzap_phys_t *buf, size_t size)
+{
+	int i, max;
+	buf->mz_block_type = BSWAP_64(buf->mz_block_type);
+	buf->mz_salt = BSWAP_64(buf->mz_salt);
+	buf->mz_normflags = BSWAP_64(buf->mz_normflags);
+	max = (size / MZAP_ENT_LEN) - 1;
+	for (i = 0; i < max; i++) {
+		buf->mz_chunk[i].mze_value =
+		    BSWAP_64(buf->mz_chunk[i].mze_value);
+		buf->mz_chunk[i].mze_cd =
+		    BSWAP_32(buf->mz_chunk[i].mze_cd);
+	}
+}
+
+void
+zap_byteswap(void *buf, size_t size)
+{
+	uint64_t block_type;
+
+	block_type = *(uint64_t *)buf;
+
+	if (block_type == ZBT_MICRO || block_type == BSWAP_64(ZBT_MICRO)) {
+		/* ASSERT(magic == ZAP_LEAF_MAGIC); */
+		mzap_byteswap(buf, size);
+	} else {
+		fzap_byteswap(buf, size);
+	}
+}
+
+static int
+mze_compare(const void *arg1, const void *arg2)
+{
+	const mzap_ent_t *mze1 = arg1;
+	const mzap_ent_t *mze2 = arg2;
+
+	if (mze1->mze_hash > mze2->mze_hash)
+		return (+1);
+	if (mze1->mze_hash < mze2->mze_hash)
+		return (-1);
+	if (mze1->mze_cd > mze2->mze_cd)
+		return (+1);
+	if (mze1->mze_cd < mze2->mze_cd)
+		return (-1);
+	return (0);
+}
+
+static void
+mze_insert(zap_t *zap, int chunkid, uint64_t hash)
+{
+	mzap_ent_t *mze;
+
+	ASSERT(zap->zap_ismicro);
+	ASSERT(RW_WRITE_HELD(&zap->zap_rwlock));
+
+	mze = kmem_alloc(sizeof (mzap_ent_t), KM_SLEEP);
+	mze->mze_chunkid = chunkid;
+	mze->mze_hash = hash;
+	mze->mze_cd = MZE_PHYS(zap, mze)->mze_cd;
+	ASSERT(MZE_PHYS(zap, mze)->mze_name[0] != 0);
+	avl_add(&zap->zap_m.zap_avl, mze);
+}
+
+static mzap_ent_t *
+mze_find(zap_name_t *zn)
+{
+	mzap_ent_t mze_tofind;
+	mzap_ent_t *mze;
+	avl_index_t idx;
+	avl_tree_t *avl = &zn->zn_zap->zap_m.zap_avl;
+
+	ASSERT(zn->zn_zap->zap_ismicro);
+	ASSERT(RW_LOCK_HELD(&zn->zn_zap->zap_rwlock));
+
+	mze_tofind.mze_hash = zn->zn_hash;
+	mze_tofind.mze_cd = 0;
+
+again:
+	mze = avl_find(avl, &mze_tofind, &idx);
+	if (mze == NULL)
+		mze = avl_nearest(avl, idx, AVL_AFTER);
+	for (; mze && mze->mze_hash == zn->zn_hash; mze = AVL_NEXT(avl, mze)) {
+		ASSERT3U(mze->mze_cd, ==, MZE_PHYS(zn->zn_zap, mze)->mze_cd);
+		if (zap_match(zn, MZE_PHYS(zn->zn_zap, mze)->mze_name))
+			return (mze);
+	}
+	if (zn->zn_matchtype == MT_BEST) {
+		zn->zn_matchtype = MT_FIRST;
+		goto again;
+	}
+	return (NULL);
+}
+
+static uint32_t
+mze_find_unused_cd(zap_t *zap, uint64_t hash)
+{
+	mzap_ent_t mze_tofind;
+	mzap_ent_t *mze;
+	avl_index_t idx;
+	avl_tree_t *avl = &zap->zap_m.zap_avl;
+	uint32_t cd;
+
+	ASSERT(zap->zap_ismicro);
+	ASSERT(RW_LOCK_HELD(&zap->zap_rwlock));
+
+	mze_tofind.mze_hash = hash;
+	mze_tofind.mze_cd = 0;
+
+	cd = 0;
+	for (mze = avl_find(avl, &mze_tofind, &idx);
+	    mze && mze->mze_hash == hash; mze = AVL_NEXT(avl, mze)) {
+		if (mze->mze_cd != cd)
+			break;
+		cd++;
+	}
+
+	return (cd);
+}
+
+static void
+mze_remove(zap_t *zap, mzap_ent_t *mze)
+{
+	ASSERT(zap->zap_ismicro);
+	ASSERT(RW_WRITE_HELD(&zap->zap_rwlock));
+
+	avl_remove(&zap->zap_m.zap_avl, mze);
+	kmem_free(mze, sizeof (mzap_ent_t));
+}
+
+static void
+mze_destroy(zap_t *zap)
+{
+	mzap_ent_t *mze;
+	void *avlcookie = NULL;
+
+	while ((mze = avl_destroy_nodes(&zap->zap_m.zap_avl, &avlcookie)))
+		kmem_free(mze, sizeof (mzap_ent_t));
+	avl_destroy(&zap->zap_m.zap_avl);
+}
+
+static zap_t *
+mzap_open(objset_t *os, uint64_t obj, dmu_buf_t *db)
+{
+	zap_t *winner;
+	zap_t *zap;
+	int i;
+
+	ASSERT3U(MZAP_ENT_LEN, ==, sizeof (mzap_ent_phys_t));
+
+	zap = kmem_zalloc(sizeof (zap_t), KM_SLEEP);
+	rw_init(&zap->zap_rwlock, NULL, RW_DEFAULT, NULL);
+	rw_enter(&zap->zap_rwlock, RW_WRITER);
+	zap->zap_objset = os;
+	zap->zap_object = obj;
+	zap->zap_dbuf = db;
+
+	if (*(uint64_t *)db->db_data != ZBT_MICRO) {
+		mutex_init(&zap->zap_f.zap_num_entries_mtx, 0, 0, 0);
+		zap->zap_f.zap_block_shift = highbit64(db->db_size) - 1;
+	} else {
+		zap->zap_ismicro = TRUE;
+	}
+
+	/*
+	 * Make sure that zap_ismicro is set before we let others see
+	 * it, because zap_lockdir() checks zap_ismicro without the lock
+	 * held.
+	 */
+	dmu_buf_init_user(&zap->zap_dbu, zap_evict, &zap->zap_dbuf);
+	winner = dmu_buf_set_user(db, &zap->zap_dbu);
+
+	if (winner != NULL) {
+		rw_exit(&zap->zap_rwlock);
+		rw_destroy(&zap->zap_rwlock);
+		if (!zap->zap_ismicro)
+			mutex_destroy(&zap->zap_f.zap_num_entries_mtx);
+		kmem_free(zap, sizeof (zap_t));
+		return (winner);
+	}
+
+	if (zap->zap_ismicro) {
+		zap->zap_salt = zap_m_phys(zap)->mz_salt;
+		zap->zap_normflags = zap_m_phys(zap)->mz_normflags;
+		zap->zap_m.zap_num_chunks = db->db_size / MZAP_ENT_LEN - 1;
+		avl_create(&zap->zap_m.zap_avl, mze_compare,
+		    sizeof (mzap_ent_t), offsetof(mzap_ent_t, mze_node));
+
+		for (i = 0; i < zap->zap_m.zap_num_chunks; i++) {
+			mzap_ent_phys_t *mze =
+			    &zap_m_phys(zap)->mz_chunk[i];
+			if (mze->mze_name[0]) {
+				zap_name_t *zn;
+
+				zap->zap_m.zap_num_entries++;
+				zn = zap_name_alloc(zap, mze->mze_name,
+				    MT_EXACT);
+				mze_insert(zap, i, zn->zn_hash);
+				zap_name_free(zn);
+			}
+		}
+	} else {
+		zap->zap_salt = zap_f_phys(zap)->zap_salt;
+		zap->zap_normflags = zap_f_phys(zap)->zap_normflags;
+
+		ASSERT3U(sizeof (struct zap_leaf_header), ==,
+		    2*ZAP_LEAF_CHUNKSIZE);
+
+		/*
+		 * The embedded pointer table should not overlap the
+		 * other members.
+		 */
+		ASSERT3P(&ZAP_EMBEDDED_PTRTBL_ENT(zap, 0), >,
+		    &zap_f_phys(zap)->zap_salt);
+
+		/*
+		 * The embedded pointer table should end at the end of
+		 * the block
+		 */
+		ASSERT3U((uintptr_t)&ZAP_EMBEDDED_PTRTBL_ENT(zap,
+		    1<<ZAP_EMBEDDED_PTRTBL_SHIFT(zap)) -
+		    (uintptr_t)zap_f_phys(zap), ==,
+		    zap->zap_dbuf->db_size);
+	}
+	rw_exit(&zap->zap_rwlock);
+	return (zap);
+}
+
+int
+zap_lockdir(objset_t *os, uint64_t obj, dmu_tx_t *tx,
+    krw_t lti, boolean_t fatreader, boolean_t adding, zap_t **zapp)
+{
+	dmu_object_info_t doi;
+	zap_t *zap;
+	dmu_buf_t *db;
+	krw_t lt;
+	int err;
+
+	*zapp = NULL;
+
+	err = dmu_buf_hold(os, obj, 0, NULL, &db, DMU_READ_NO_PREFETCH);
+	if (err)
+		return (err);
+
+	dmu_object_info_from_db(db, &doi);
+	if (DMU_OT_BYTESWAP(doi.doi_type) != DMU_BSWAP_ZAP)
+		return (SET_ERROR(EINVAL));
+
+	zap = dmu_buf_get_user(db);
+	if (zap == NULL)
+		zap = mzap_open(os, obj, db);
+
+	/*
+	 * We're checking zap_ismicro without the lock held, in order to
+	 * tell what type of lock we want.  Once we have some sort of
+	 * lock, see if it really is the right type.  In practice this
+	 * can only be different if it was upgraded from micro to fat,
+	 * and micro wanted WRITER but fat only needs READER.
+	 */
+	lt = (!zap->zap_ismicro && fatreader) ? RW_READER : lti;
+	rw_enter(&zap->zap_rwlock, lt);
+	if (lt != ((!zap->zap_ismicro && fatreader) ? RW_READER : lti)) {
+		/* it was upgraded, now we only need reader */
+		ASSERT(lt == RW_WRITER);
+		ASSERT(RW_READER ==
+		    ((!zap->zap_ismicro && fatreader) ? RW_READER : lti));
+		rw_downgrade(&zap->zap_rwlock);
+		lt = RW_READER;
+	}
+
+	zap->zap_objset = os;
+
+	if (lt == RW_WRITER)
+		dmu_buf_will_dirty(db, tx);
+
+	ASSERT3P(zap->zap_dbuf, ==, db);
+
+	ASSERT(!zap->zap_ismicro ||
+	    zap->zap_m.zap_num_entries <= zap->zap_m.zap_num_chunks);
+	if (zap->zap_ismicro && tx && adding &&
+	    zap->zap_m.zap_num_entries == zap->zap_m.zap_num_chunks) {
+		uint64_t newsz = db->db_size + SPA_MINBLOCKSIZE;
+		if (newsz > MZAP_MAX_BLKSZ) {
+			dprintf("upgrading obj %llu: num_entries=%u\n",
+			    obj, zap->zap_m.zap_num_entries);
+			*zapp = zap;
+			return (mzap_upgrade(zapp, tx, 0));
+		}
+		err = dmu_object_set_blocksize(os, obj, newsz, 0, tx);
+		ASSERT0(err);
+		zap->zap_m.zap_num_chunks =
+		    db->db_size / MZAP_ENT_LEN - 1;
+	}
+
+	*zapp = zap;
+	return (0);
+}
+
+void
+zap_unlockdir(zap_t *zap)
+{
+	rw_exit(&zap->zap_rwlock);
+	dmu_buf_rele(zap->zap_dbuf, NULL);
+}
+
+static int
+mzap_upgrade(zap_t **zapp, dmu_tx_t *tx, zap_flags_t flags)
+{
+	mzap_phys_t *mzp;
+	int i, sz, nchunks;
+	int err = 0;
+	zap_t *zap = *zapp;
+
+	ASSERT(RW_WRITE_HELD(&zap->zap_rwlock));
+
+	sz = zap->zap_dbuf->db_size;
+	mzp = zio_buf_alloc(sz);
+	bcopy(zap->zap_dbuf->db_data, mzp, sz);
+	nchunks = zap->zap_m.zap_num_chunks;
+
+	if (!flags) {
+		err = dmu_object_set_blocksize(zap->zap_objset, zap->zap_object,
+		    1ULL << fzap_default_block_shift, 0, tx);
+		if (err) {
+			zio_buf_free(mzp, sz);
+			return (err);
+		}
+	}
+
+	dprintf("upgrading obj=%llu with %u chunks\n",
+	    zap->zap_object, nchunks);
+	/* XXX destroy the avl later, so we can use the stored hash value */
+	mze_destroy(zap);
+
+	fzap_upgrade(zap, tx, flags);
+
+	for (i = 0; i < nchunks; i++) {
+		mzap_ent_phys_t *mze = &mzp->mz_chunk[i];
+		zap_name_t *zn;
+		if (mze->mze_name[0] == 0)
+			continue;
+		dprintf("adding %s=%llu\n",
+		    mze->mze_name, mze->mze_value);
+		zn = zap_name_alloc(zap, mze->mze_name, MT_EXACT);
+		err = fzap_add_cd(zn, 8, 1, &mze->mze_value, mze->mze_cd, tx);
+		zap = zn->zn_zap;	/* fzap_add_cd() may change zap */
+		zap_name_free(zn);
+		if (err)
+			break;
+	}
+	zio_buf_free(mzp, sz);
+	*zapp = zap;
+	return (err);
+}
+
+void
+mzap_create_impl(objset_t *os, uint64_t obj, int normflags, zap_flags_t flags,
+    dmu_tx_t *tx)
+{
+	dmu_buf_t *db;
+	mzap_phys_t *zp;
+
+	VERIFY(0 == dmu_buf_hold(os, obj, 0, FTAG, &db, DMU_READ_NO_PREFETCH));
+
+#ifdef ZFS_DEBUG
+	{
+		dmu_object_info_t doi;
+		dmu_object_info_from_db(db, &doi);
+		ASSERT3U(DMU_OT_BYTESWAP(doi.doi_type), ==, DMU_BSWAP_ZAP);
+	}
+#endif
+
+	dmu_buf_will_dirty(db, tx);
+	zp = db->db_data;
+	zp->mz_block_type = ZBT_MICRO;
+	zp->mz_salt = ((uintptr_t)db ^ (uintptr_t)tx ^ (obj << 1)) | 1ULL;
+	zp->mz_normflags = normflags;
+	dmu_buf_rele(db, FTAG);
+
+	if (flags != 0) {
+		zap_t *zap;
+		/* Only fat zap supports flags; upgrade immediately. */
+		VERIFY(0 == zap_lockdir(os, obj, tx, RW_WRITER,
+		    B_FALSE, B_FALSE, &zap));
+		VERIFY3U(0, ==, mzap_upgrade(&zap, tx, flags));
+		zap_unlockdir(zap);
+	}
+}
+
+int
+zap_create_claim(objset_t *os, uint64_t obj, dmu_object_type_t ot,
+    dmu_object_type_t bonustype, int bonuslen, dmu_tx_t *tx)
+{
+	return (zap_create_claim_norm(os, obj,
+	    0, ot, bonustype, bonuslen, tx));
+}
+
+int
+zap_create_claim_norm(objset_t *os, uint64_t obj, int normflags,
+    dmu_object_type_t ot,
+    dmu_object_type_t bonustype, int bonuslen, dmu_tx_t *tx)
+{
+	int err;
+
+	err = dmu_object_claim(os, obj, ot, 0, bonustype, bonuslen, tx);
+	if (err != 0)
+		return (err);
+	mzap_create_impl(os, obj, normflags, 0, tx);
+	return (0);
+}
+
+uint64_t
+zap_create(objset_t *os, dmu_object_type_t ot,
+    dmu_object_type_t bonustype, int bonuslen, dmu_tx_t *tx)
+{
+	return (zap_create_norm(os, 0, ot, bonustype, bonuslen, tx));
+}
+
+uint64_t
+zap_create_norm(objset_t *os, int normflags, dmu_object_type_t ot,
+    dmu_object_type_t bonustype, int bonuslen, dmu_tx_t *tx)
+{
+	uint64_t obj = dmu_object_alloc(os, ot, 0, bonustype, bonuslen, tx);
+
+	mzap_create_impl(os, obj, normflags, 0, tx);
+	return (obj);
+}
+
+uint64_t
+zap_create_flags(objset_t *os, int normflags, zap_flags_t flags,
+    dmu_object_type_t ot, int leaf_blockshift, int indirect_blockshift,
+    dmu_object_type_t bonustype, int bonuslen, dmu_tx_t *tx)
+{
+	uint64_t obj = dmu_object_alloc(os, ot, 0, bonustype, bonuslen, tx);
+
+	ASSERT(leaf_blockshift >= SPA_MINBLOCKSHIFT &&
+	    leaf_blockshift <= SPA_OLD_MAXBLOCKSHIFT &&
+	    indirect_blockshift >= SPA_MINBLOCKSHIFT &&
+	    indirect_blockshift <= SPA_OLD_MAXBLOCKSHIFT);
+
+	VERIFY(dmu_object_set_blocksize(os, obj,
+	    1ULL << leaf_blockshift, indirect_blockshift, tx) == 0);
+
+	mzap_create_impl(os, obj, normflags, flags, tx);
+	return (obj);
+}
+
+int
+zap_destroy(objset_t *os, uint64_t zapobj, dmu_tx_t *tx)
+{
+	/*
+	 * dmu_object_free will free the object number and free the
+	 * data.  Freeing the data will cause our pageout function to be
+	 * called, which will destroy our data (zap_leaf_t's and zap_t).
+	 */
+
+	return (dmu_object_free(os, zapobj, tx));
+}
+
+void
+zap_evict(void *dbu)
+{
+	zap_t *zap = dbu;
+
+	rw_destroy(&zap->zap_rwlock);
+
+	if (zap->zap_ismicro)
+		mze_destroy(zap);
+	else
+		mutex_destroy(&zap->zap_f.zap_num_entries_mtx);
+
+	kmem_free(zap, sizeof (zap_t));
+}
+
+int
+zap_count(objset_t *os, uint64_t zapobj, uint64_t *count)
+{
+	zap_t *zap;
+	int err;
+
+	err = zap_lockdir(os, zapobj, NULL, RW_READER, TRUE, FALSE, &zap);
+	if (err)
+		return (err);
+	if (!zap->zap_ismicro) {
+		err = fzap_count(zap, count);
+	} else {
+		*count = zap->zap_m.zap_num_entries;
+	}
+	zap_unlockdir(zap);
+	return (err);
+}
+
+/*
+ * zn may be NULL; if not specified, it will be computed if needed.
+ * See also the comment above zap_entry_normalization_conflict().
+ */
+static boolean_t
+mzap_normalization_conflict(zap_t *zap, zap_name_t *zn, mzap_ent_t *mze)
+{
+	mzap_ent_t *other;
+	int direction = AVL_BEFORE;
+	boolean_t allocdzn = B_FALSE;
+
+	if (zap->zap_normflags == 0)
+		return (B_FALSE);
+
+again:
+	for (other = avl_walk(&zap->zap_m.zap_avl, mze, direction);
+	    other && other->mze_hash == mze->mze_hash;
+	    other = avl_walk(&zap->zap_m.zap_avl, other, direction)) {
+
+		if (zn == NULL) {
+			zn = zap_name_alloc(zap, MZE_PHYS(zap, mze)->mze_name,
+			    MT_FIRST);
+			allocdzn = B_TRUE;
+		}
+		if (zap_match(zn, MZE_PHYS(zap, other)->mze_name)) {
+			if (allocdzn)
+				zap_name_free(zn);
+			return (B_TRUE);
+		}
+	}
+
+	if (direction == AVL_BEFORE) {
+		direction = AVL_AFTER;
+		goto again;
+	}
+
+	if (allocdzn)
+		zap_name_free(zn);
+	return (B_FALSE);
+}
+
+/*
+ * Routines for manipulating attributes.
+ */
+
+int
+zap_lookup(objset_t *os, uint64_t zapobj, const char *name,
+    uint64_t integer_size, uint64_t num_integers, void *buf)
+{
+	return (zap_lookup_norm(os, zapobj, name, integer_size,
+	    num_integers, buf, MT_EXACT, NULL, 0, NULL));
+}
+
+int
+zap_lookup_norm(objset_t *os, uint64_t zapobj, const char *name,
+    uint64_t integer_size, uint64_t num_integers, void *buf,
+    matchtype_t mt, char *realname, int rn_len,
+    boolean_t *ncp)
+{
+	zap_t *zap;
+	int err;
+	mzap_ent_t *mze;
+	zap_name_t *zn;
+
+	err = zap_lockdir(os, zapobj, NULL, RW_READER, TRUE, FALSE, &zap);
+	if (err)
+		return (err);
+	zn = zap_name_alloc(zap, name, mt);
+	if (zn == NULL) {
+		zap_unlockdir(zap);
+		return (SET_ERROR(ENOTSUP));
+	}
+
+	if (!zap->zap_ismicro) {
+		err = fzap_lookup(zn, integer_size, num_integers, buf,
+		    realname, rn_len, ncp);
+	} else {
+		mze = mze_find(zn);
+		if (mze == NULL) {
+			err = SET_ERROR(ENOENT);
+		} else {
+			if (num_integers < 1) {
+				err = SET_ERROR(EOVERFLOW);
+			} else if (integer_size != 8) {
+				err = SET_ERROR(EINVAL);
+			} else {
+				*(uint64_t *)buf =
+				    MZE_PHYS(zap, mze)->mze_value;
+				(void) strlcpy(realname,
+				    MZE_PHYS(zap, mze)->mze_name, rn_len);
+				if (ncp) {
+					*ncp = mzap_normalization_conflict(zap,
+					    zn, mze);
+				}
+			}
+		}
+	}
+	zap_name_free(zn);
+	zap_unlockdir(zap);
+	return (err);
+}
+
+int
+zap_prefetch(objset_t *os, uint64_t zapobj, const char *name)
+{
+	zap_t *zap;
+	int err;
+	zap_name_t *zn;
+
+	err = zap_lockdir(os, zapobj, NULL, RW_READER, TRUE, FALSE, &zap);
+	if (err)
+		return (err);
+	zn = zap_name_alloc(zap, name, MT_EXACT);
+	if (zn == NULL) {
+		zap_unlockdir(zap);
+		return (SET_ERROR(ENOTSUP));
+	}
+
+	fzap_prefetch(zn);
+	zap_name_free(zn);
+	zap_unlockdir(zap);
+	return (err);
+}
+
+int
+zap_prefetch_uint64(objset_t *os, uint64_t zapobj, const uint64_t *key,
+    int key_numints)
+{
+	zap_t *zap;
+	int err;
+	zap_name_t *zn;
+
+	err = zap_lockdir(os, zapobj, NULL, RW_READER, TRUE, FALSE, &zap);
+	if (err)
+		return (err);
+	zn = zap_name_alloc_uint64(zap, key, key_numints);
+	if (zn == NULL) {
+		zap_unlockdir(zap);
+		return (SET_ERROR(ENOTSUP));
+	}
+
+	fzap_prefetch(zn);
+	zap_name_free(zn);
+	zap_unlockdir(zap);
+	return (err);
+}
+
+int
+zap_lookup_uint64(objset_t *os, uint64_t zapobj, const uint64_t *key,
+    int key_numints, uint64_t integer_size, uint64_t num_integers, void *buf)
+{
+	zap_t *zap;
+	int err;
+	zap_name_t *zn;
+
+	err = zap_lockdir(os, zapobj, NULL, RW_READER, TRUE, FALSE, &zap);
+	if (err)
+		return (err);
+	zn = zap_name_alloc_uint64(zap, key, key_numints);
+	if (zn == NULL) {
+		zap_unlockdir(zap);
+		return (SET_ERROR(ENOTSUP));
+	}
+
+	err = fzap_lookup(zn, integer_size, num_integers, buf,
+	    NULL, 0, NULL);
+	zap_name_free(zn);
+	zap_unlockdir(zap);
+	return (err);
+}
+
+int
+zap_contains(objset_t *os, uint64_t zapobj, const char *name)
+{
+	int err = zap_lookup_norm(os, zapobj, name, 0,
+	    0, NULL, MT_EXACT, NULL, 0, NULL);
+	if (err == EOVERFLOW || err == EINVAL)
+		err = 0; /* found, but skipped reading the value */
+	return (err);
+}
+
+int
+zap_length(objset_t *os, uint64_t zapobj, const char *name,
+    uint64_t *integer_size, uint64_t *num_integers)
+{
+	zap_t *zap;
+	int err;
+	mzap_ent_t *mze;
+	zap_name_t *zn;
+
+	err = zap_lockdir(os, zapobj, NULL, RW_READER, TRUE, FALSE, &zap);
+	if (err)
+		return (err);
+	zn = zap_name_alloc(zap, name, MT_EXACT);
+	if (zn == NULL) {
+		zap_unlockdir(zap);
+		return (SET_ERROR(ENOTSUP));
+	}
+	if (!zap->zap_ismicro) {
+		err = fzap_length(zn, integer_size, num_integers);
+	} else {
+		mze = mze_find(zn);
+		if (mze == NULL) {
+			err = SET_ERROR(ENOENT);
+		} else {
+			if (integer_size)
+				*integer_size = 8;
+			if (num_integers)
+				*num_integers = 1;
+		}
+	}
+	zap_name_free(zn);
+	zap_unlockdir(zap);
+	return (err);
+}
+
+int
+zap_length_uint64(objset_t *os, uint64_t zapobj, const uint64_t *key,
+    int key_numints, uint64_t *integer_size, uint64_t *num_integers)
+{
+	zap_t *zap;
+	int err;
+	zap_name_t *zn;
+
+	err = zap_lockdir(os, zapobj, NULL, RW_READER, TRUE, FALSE, &zap);
+	if (err)
+		return (err);
+	zn = zap_name_alloc_uint64(zap, key, key_numints);
+	if (zn == NULL) {
+		zap_unlockdir(zap);
+		return (SET_ERROR(ENOTSUP));
+	}
+	err = fzap_length(zn, integer_size, num_integers);
+	zap_name_free(zn);
+	zap_unlockdir(zap);
+	return (err);
+}
+
+static void
+mzap_addent(zap_name_t *zn, uint64_t value)
+{
+	int i;
+	zap_t *zap = zn->zn_zap;
+	int start = zap->zap_m.zap_alloc_next;
+	uint32_t cd;
+
+	ASSERT(RW_WRITE_HELD(&zap->zap_rwlock));
+
+#ifdef ZFS_DEBUG
+	for (i = 0; i < zap->zap_m.zap_num_chunks; i++) {
+		ASSERTV(mzap_ent_phys_t *mze);
+		ASSERT(mze = &zap_m_phys(zap)->mz_chunk[i]);
+		ASSERT(strcmp(zn->zn_key_orig, mze->mze_name) != 0);
+	}
+#endif
+
+	cd = mze_find_unused_cd(zap, zn->zn_hash);
+	/* given the limited size of the microzap, this can't happen */
+	ASSERT(cd < zap_maxcd(zap));
+
+again:
+	for (i = start; i < zap->zap_m.zap_num_chunks; i++) {
+		mzap_ent_phys_t *mze = &zap_m_phys(zap)->mz_chunk[i];
+		if (mze->mze_name[0] == 0) {
+			mze->mze_value = value;
+			mze->mze_cd = cd;
+			(void) strcpy(mze->mze_name, zn->zn_key_orig);
+			zap->zap_m.zap_num_entries++;
+			zap->zap_m.zap_alloc_next = i+1;
+			if (zap->zap_m.zap_alloc_next ==
+			    zap->zap_m.zap_num_chunks)
+				zap->zap_m.zap_alloc_next = 0;
+			mze_insert(zap, i, zn->zn_hash);
+			return;
+		}
+	}
+	if (start != 0) {
+		start = 0;
+		goto again;
+	}
+	cmn_err(CE_PANIC, "out of entries!");
+}
+
+int
+zap_add(objset_t *os, uint64_t zapobj, const char *key,
+    int integer_size, uint64_t num_integers,
+    const void *val, dmu_tx_t *tx)
+{
+	zap_t *zap;
+	int err;
+	mzap_ent_t *mze;
+	const uint64_t *intval = val;
+	zap_name_t *zn;
+
+	err = zap_lockdir(os, zapobj, tx, RW_WRITER, TRUE, TRUE, &zap);
+	if (err)
+		return (err);
+	zn = zap_name_alloc(zap, key, MT_EXACT);
+	if (zn == NULL) {
+		zap_unlockdir(zap);
+		return (SET_ERROR(ENOTSUP));
+	}
+	if (!zap->zap_ismicro) {
+		err = fzap_add(zn, integer_size, num_integers, val, tx);
+		zap = zn->zn_zap;	/* fzap_add() may change zap */
+	} else if (integer_size != 8 || num_integers != 1 ||
+	    strlen(key) >= MZAP_NAME_LEN) {
+		err = mzap_upgrade(&zn->zn_zap, tx, 0);
+		if (err == 0)
+			err = fzap_add(zn, integer_size, num_integers, val, tx);
+		zap = zn->zn_zap;	/* fzap_add() may change zap */
+	} else {
+		mze = mze_find(zn);
+		if (mze != NULL) {
+			err = SET_ERROR(EEXIST);
+		} else {
+			mzap_addent(zn, *intval);
+		}
+	}
+	ASSERT(zap == zn->zn_zap);
+	zap_name_free(zn);
+	if (zap != NULL)	/* may be NULL if fzap_add() failed */
+		zap_unlockdir(zap);
+	return (err);
+}
+
+int
+zap_add_uint64(objset_t *os, uint64_t zapobj, const uint64_t *key,
+    int key_numints, int integer_size, uint64_t num_integers,
+    const void *val, dmu_tx_t *tx)
+{
+	zap_t *zap;
+	int err;
+	zap_name_t *zn;
+
+	err = zap_lockdir(os, zapobj, tx, RW_WRITER, TRUE, TRUE, &zap);
+	if (err)
+		return (err);
+	zn = zap_name_alloc_uint64(zap, key, key_numints);
+	if (zn == NULL) {
+		zap_unlockdir(zap);
+		return (SET_ERROR(ENOTSUP));
+	}
+	err = fzap_add(zn, integer_size, num_integers, val, tx);
+	zap = zn->zn_zap;	/* fzap_add() may change zap */
+	zap_name_free(zn);
+	if (zap != NULL)	/* may be NULL if fzap_add() failed */
+		zap_unlockdir(zap);
+	return (err);
+}
+
+int
+zap_update(objset_t *os, uint64_t zapobj, const char *name,
+    int integer_size, uint64_t num_integers, const void *val, dmu_tx_t *tx)
+{
+	zap_t *zap;
+	mzap_ent_t *mze;
+	const uint64_t *intval = val;
+	zap_name_t *zn;
+	int err;
+
+#ifdef ZFS_DEBUG
+	uint64_t oldval;
+
+	/*
+	 * If there is an old value, it shouldn't change across the
+	 * lockdir (eg, due to bprewrite's xlation).
+	 */
+	if (integer_size == 8 && num_integers == 1)
+		(void) zap_lookup(os, zapobj, name, 8, 1, &oldval);
+#endif
+
+	err = zap_lockdir(os, zapobj, tx, RW_WRITER, TRUE, TRUE, &zap);
+	if (err)
+		return (err);
+	zn = zap_name_alloc(zap, name, MT_EXACT);
+	if (zn == NULL) {
+		zap_unlockdir(zap);
+		return (SET_ERROR(ENOTSUP));
+	}
+	if (!zap->zap_ismicro) {
+		err = fzap_update(zn, integer_size, num_integers, val, tx);
+		zap = zn->zn_zap;	/* fzap_update() may change zap */
+	} else if (integer_size != 8 || num_integers != 1 ||
+	    strlen(name) >= MZAP_NAME_LEN) {
+		dprintf("upgrading obj %llu: intsz=%u numint=%llu name=%s\n",
+		    zapobj, integer_size, num_integers, name);
+		err = mzap_upgrade(&zn->zn_zap, tx, 0);
+		if (err == 0)
+			err = fzap_update(zn, integer_size, num_integers,
+			    val, tx);
+		zap = zn->zn_zap;	/* fzap_update() may change zap */
+	} else {
+		mze = mze_find(zn);
+		if (mze != NULL) {
+			ASSERT3U(MZE_PHYS(zap, mze)->mze_value, ==, oldval);
+			MZE_PHYS(zap, mze)->mze_value = *intval;
+		} else {
+			mzap_addent(zn, *intval);
+		}
+	}
+	ASSERT(zap == zn->zn_zap);
+	zap_name_free(zn);
+	if (zap != NULL)	/* may be NULL if fzap_upgrade() failed */
+		zap_unlockdir(zap);
+	return (err);
+}
+
+int
+zap_update_uint64(objset_t *os, uint64_t zapobj, const uint64_t *key,
+    int key_numints,
+    int integer_size, uint64_t num_integers, const void *val, dmu_tx_t *tx)
+{
+	zap_t *zap;
+	zap_name_t *zn;
+	int err;
+
+	err = zap_lockdir(os, zapobj, tx, RW_WRITER, TRUE, TRUE, &zap);
+	if (err)
+		return (err);
+	zn = zap_name_alloc_uint64(zap, key, key_numints);
+	if (zn == NULL) {
+		zap_unlockdir(zap);
+		return (SET_ERROR(ENOTSUP));
+	}
+	err = fzap_update(zn, integer_size, num_integers, val, tx);
+	zap = zn->zn_zap;	/* fzap_update() may change zap */
+	zap_name_free(zn);
+	if (zap != NULL)	/* may be NULL if fzap_upgrade() failed */
+		zap_unlockdir(zap);
+	return (err);
+}
+
+int
+zap_remove(objset_t *os, uint64_t zapobj, const char *name, dmu_tx_t *tx)
+{
+	return (zap_remove_norm(os, zapobj, name, MT_EXACT, tx));
+}
+
+int
+zap_remove_norm(objset_t *os, uint64_t zapobj, const char *name,
+    matchtype_t mt, dmu_tx_t *tx)
+{
+	zap_t *zap;
+	int err;
+	mzap_ent_t *mze;
+	zap_name_t *zn;
+
+	err = zap_lockdir(os, zapobj, tx, RW_WRITER, TRUE, FALSE, &zap);
+	if (err)
+		return (err);
+	zn = zap_name_alloc(zap, name, mt);
+	if (zn == NULL) {
+		zap_unlockdir(zap);
+		return (SET_ERROR(ENOTSUP));
+	}
+	if (!zap->zap_ismicro) {
+		err = fzap_remove(zn, tx);
+	} else {
+		mze = mze_find(zn);
+		if (mze == NULL) {
+			err = SET_ERROR(ENOENT);
+		} else {
+			zap->zap_m.zap_num_entries--;
+			bzero(&zap_m_phys(zap)->mz_chunk[mze->mze_chunkid],
+			    sizeof (mzap_ent_phys_t));
+			mze_remove(zap, mze);
+		}
+	}
+	zap_name_free(zn);
+	zap_unlockdir(zap);
+	return (err);
+}
+
+int
+zap_remove_uint64(objset_t *os, uint64_t zapobj, const uint64_t *key,
+    int key_numints, dmu_tx_t *tx)
+{
+	zap_t *zap;
+	int err;
+	zap_name_t *zn;
+
+	err = zap_lockdir(os, zapobj, tx, RW_WRITER, TRUE, FALSE, &zap);
+	if (err)
+		return (err);
+	zn = zap_name_alloc_uint64(zap, key, key_numints);
+	if (zn == NULL) {
+		zap_unlockdir(zap);
+		return (SET_ERROR(ENOTSUP));
+	}
+	err = fzap_remove(zn, tx);
+	zap_name_free(zn);
+	zap_unlockdir(zap);
+	return (err);
+}
+
+/*
+ * Routines for iterating over the attributes.
+ */
+
+void
+zap_cursor_init_serialized(zap_cursor_t *zc, objset_t *os, uint64_t zapobj,
+    uint64_t serialized)
+{
+	zc->zc_objset = os;
+	zc->zc_zap = NULL;
+	zc->zc_leaf = NULL;
+	zc->zc_zapobj = zapobj;
+	zc->zc_serialized = serialized;
+	zc->zc_hash = 0;
+	zc->zc_cd = 0;
+}
+
+void
+zap_cursor_init(zap_cursor_t *zc, objset_t *os, uint64_t zapobj)
+{
+	zap_cursor_init_serialized(zc, os, zapobj, 0);
+}
+
+void
+zap_cursor_fini(zap_cursor_t *zc)
+{
+	if (zc->zc_zap) {
+		rw_enter(&zc->zc_zap->zap_rwlock, RW_READER);
+		zap_unlockdir(zc->zc_zap);
+		zc->zc_zap = NULL;
+	}
+	if (zc->zc_leaf) {
+		rw_enter(&zc->zc_leaf->l_rwlock, RW_READER);
+		zap_put_leaf(zc->zc_leaf);
+		zc->zc_leaf = NULL;
+	}
+	zc->zc_objset = NULL;
+}
+
+uint64_t
+zap_cursor_serialize(zap_cursor_t *zc)
+{
+	if (zc->zc_hash == -1ULL)
+		return (-1ULL);
+	if (zc->zc_zap == NULL)
+		return (zc->zc_serialized);
+	ASSERT((zc->zc_hash & zap_maxcd(zc->zc_zap)) == 0);
+	ASSERT(zc->zc_cd < zap_maxcd(zc->zc_zap));
+
+	/*
+	 * We want to keep the high 32 bits of the cursor zero if we can, so
+	 * that 32-bit programs can access this.  So usually use a small
+	 * (28-bit) hash value so we can fit 4 bits of cd into the low 32-bits
+	 * of the cursor.
+	 *
+	 * [ collision differentiator | zap_hashbits()-bit hash value ]
+	 */
+	return ((zc->zc_hash >> (64 - zap_hashbits(zc->zc_zap))) |
+	    ((uint64_t)zc->zc_cd << zap_hashbits(zc->zc_zap)));
+}
+
+int
+zap_cursor_retrieve(zap_cursor_t *zc, zap_attribute_t *za)
+{
+	int err;
+	avl_index_t idx;
+	mzap_ent_t mze_tofind;
+	mzap_ent_t *mze;
+
+	if (zc->zc_hash == -1ULL)
+		return (SET_ERROR(ENOENT));
+
+	if (zc->zc_zap == NULL) {
+		int hb;
+		err = zap_lockdir(zc->zc_objset, zc->zc_zapobj, NULL,
+		    RW_READER, TRUE, FALSE, &zc->zc_zap);
+		if (err)
+			return (err);
+
+		/*
+		 * To support zap_cursor_init_serialized, advance, retrieve,
+		 * we must add to the existing zc_cd, which may already
+		 * be 1 due to the zap_cursor_advance.
+		 */
+		ASSERT(zc->zc_hash == 0);
+		hb = zap_hashbits(zc->zc_zap);
+		zc->zc_hash = zc->zc_serialized << (64 - hb);
+		zc->zc_cd += zc->zc_serialized >> hb;
+		if (zc->zc_cd >= zap_maxcd(zc->zc_zap)) /* corrupt serialized */
+			zc->zc_cd = 0;
+	} else {
+		rw_enter(&zc->zc_zap->zap_rwlock, RW_READER);
+	}
+	if (!zc->zc_zap->zap_ismicro) {
+		err = fzap_cursor_retrieve(zc->zc_zap, zc, za);
+	} else {
+		mze_tofind.mze_hash = zc->zc_hash;
+		mze_tofind.mze_cd = zc->zc_cd;
+
+		mze = avl_find(&zc->zc_zap->zap_m.zap_avl, &mze_tofind, &idx);
+		if (mze == NULL) {
+			mze = avl_nearest(&zc->zc_zap->zap_m.zap_avl,
+			    idx, AVL_AFTER);
+		}
+		if (mze) {
+			mzap_ent_phys_t *mzep = MZE_PHYS(zc->zc_zap, mze);
+			ASSERT3U(mze->mze_cd, ==, mzep->mze_cd);
+			za->za_normalization_conflict =
+			    mzap_normalization_conflict(zc->zc_zap, NULL, mze);
+			za->za_integer_length = 8;
+			za->za_num_integers = 1;
+			za->za_first_integer = mzep->mze_value;
+			(void) strcpy(za->za_name, mzep->mze_name);
+			zc->zc_hash = mze->mze_hash;
+			zc->zc_cd = mze->mze_cd;
+			err = 0;
+		} else {
+			zc->zc_hash = -1ULL;
+			err = SET_ERROR(ENOENT);
+		}
+	}
+	rw_exit(&zc->zc_zap->zap_rwlock);
+	return (err);
+}
+
+void
+zap_cursor_advance(zap_cursor_t *zc)
+{
+	if (zc->zc_hash == -1ULL)
+		return;
+	zc->zc_cd++;
+}
+
+int
+zap_get_stats(objset_t *os, uint64_t zapobj, zap_stats_t *zs)
+{
+	int err;
+	zap_t *zap;
+
+	err = zap_lockdir(os, zapobj, NULL, RW_READER, TRUE, FALSE, &zap);
+	if (err)
+		return (err);
+
+	bzero(zs, sizeof (zap_stats_t));
+
+	if (zap->zap_ismicro) {
+		zs->zs_blocksize = zap->zap_dbuf->db_size;
+		zs->zs_num_entries = zap->zap_m.zap_num_entries;
+		zs->zs_num_blocks = 1;
+	} else {
+		fzap_get_stats(zap, zs);
+	}
+	zap_unlockdir(zap);
+	return (0);
+}
+
+int
+zap_count_write(objset_t *os, uint64_t zapobj, const char *name, int add,
+    uint64_t *towrite, uint64_t *tooverwrite)
+{
+	zap_t *zap;
+	int err = 0;
+
+	/*
+	 * Since, we don't have a name, we cannot figure out which blocks will
+	 * be affected in this operation. So, account for the worst case :
+	 * - 3 blocks overwritten: target leaf, ptrtbl block, header block
+	 * - 4 new blocks written if adding:
+	 * 	- 2 blocks for possibly split leaves,
+	 * 	- 2 grown ptrtbl blocks
+	 *
+	 * This also accomodates the case where an add operation to a fairly
+	 * large microzap results in a promotion to fatzap.
+	 */
+	if (name == NULL) {
+		*towrite += (3 + (add ? 4 : 0)) * SPA_OLD_MAXBLOCKSIZE;
+		return (err);
+	}
+
+	/*
+	 * We lock the zap with adding == FALSE. Because, if we pass
+	 * the actual value of add, it could trigger a mzap_upgrade().
+	 * At present we are just evaluating the possibility of this operation
+	 * and hence we donot want to trigger an upgrade.
+	 */
+	err = zap_lockdir(os, zapobj, NULL, RW_READER, TRUE, FALSE, &zap);
+	if (err)
+		return (err);
+
+	if (!zap->zap_ismicro) {
+		zap_name_t *zn = zap_name_alloc(zap, name, MT_EXACT);
+		if (zn) {
+			err = fzap_count_write(zn, add, towrite,
+			    tooverwrite);
+			zap_name_free(zn);
+		} else {
+			/*
+			 * We treat this case as similar to (name == NULL)
+			 */
+			*towrite += (3 + (add ? 4 : 0)) * SPA_OLD_MAXBLOCKSIZE;
+		}
+	} else {
+		/*
+		 * We are here if (name != NULL) and this is a micro-zap.
+		 * We account for the header block depending on whether it
+		 * is freeable.
+		 *
+		 * Incase of an add-operation it is hard to find out
+		 * if this add will promote this microzap to fatzap.
+		 * Hence, we consider the worst case and account for the
+		 * blocks assuming this microzap would be promoted to a
+		 * fatzap.
+		 *
+		 * 1 block overwritten  : header block
+		 * 4 new blocks written : 2 new split leaf, 2 grown
+		 *			ptrtbl blocks
+		 */
+		if (dmu_buf_freeable(zap->zap_dbuf))
+			*tooverwrite += MZAP_MAX_BLKSZ;
+		else
+			*towrite += MZAP_MAX_BLKSZ;
+
+		if (add) {
+			*towrite += 4 * MZAP_MAX_BLKSZ;
+		}
+	}
+
+	zap_unlockdir(zap);
+	return (err);
+}
+
+#if defined(_KERNEL) && defined(HAVE_SPL)
+EXPORT_SYMBOL(zap_create);
+EXPORT_SYMBOL(zap_create_norm);
+EXPORT_SYMBOL(zap_create_flags);
+EXPORT_SYMBOL(zap_create_claim);
+EXPORT_SYMBOL(zap_create_claim_norm);
+EXPORT_SYMBOL(zap_destroy);
+EXPORT_SYMBOL(zap_lookup);
+EXPORT_SYMBOL(zap_lookup_norm);
+EXPORT_SYMBOL(zap_lookup_uint64);
+EXPORT_SYMBOL(zap_contains);
+EXPORT_SYMBOL(zap_prefetch);
+EXPORT_SYMBOL(zap_prefetch_uint64);
+EXPORT_SYMBOL(zap_count_write);
+EXPORT_SYMBOL(zap_add);
+EXPORT_SYMBOL(zap_add_uint64);
+EXPORT_SYMBOL(zap_update);
+EXPORT_SYMBOL(zap_update_uint64);
+EXPORT_SYMBOL(zap_length);
+EXPORT_SYMBOL(zap_length_uint64);
+EXPORT_SYMBOL(zap_remove);
+EXPORT_SYMBOL(zap_remove_norm);
+EXPORT_SYMBOL(zap_remove_uint64);
+EXPORT_SYMBOL(zap_count);
+EXPORT_SYMBOL(zap_value_search);
+EXPORT_SYMBOL(zap_join);
+EXPORT_SYMBOL(zap_join_increment);
+EXPORT_SYMBOL(zap_add_int);
+EXPORT_SYMBOL(zap_remove_int);
+EXPORT_SYMBOL(zap_lookup_int);
+EXPORT_SYMBOL(zap_increment_int);
+EXPORT_SYMBOL(zap_add_int_key);
+EXPORT_SYMBOL(zap_lookup_int_key);
+EXPORT_SYMBOL(zap_increment);
+EXPORT_SYMBOL(zap_cursor_init);
+EXPORT_SYMBOL(zap_cursor_fini);
+EXPORT_SYMBOL(zap_cursor_retrieve);
+EXPORT_SYMBOL(zap_cursor_advance);
+EXPORT_SYMBOL(zap_cursor_serialize);
+EXPORT_SYMBOL(zap_cursor_init_serialized);
+EXPORT_SYMBOL(zap_get_stats);
+#endif
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/module/zfs/zfeature.c
@@ -0,0 +1,512 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2013 by Delphix. All rights reserved.
+ */
+
+#include <sys/zfs_context.h>
+#include <sys/zfeature.h>
+#include <sys/dmu.h>
+#include <sys/nvpair.h>
+#include <sys/zap.h>
+#include <sys/dmu_tx.h>
+#include "zfeature_common.h"
+#include <sys/spa_impl.h>
+
+/*
+ * ZFS Feature Flags
+ * -----------------
+ *
+ * ZFS feature flags are used to provide fine-grained versioning to the ZFS
+ * on-disk format. Once enabled on a pool feature flags replace the old
+ * spa_version() number.
+ *
+ * Each new on-disk format change will be given a uniquely identifying string
+ * guid rather than a version number. This avoids the problem of different
+ * organizations creating new on-disk formats with the same version number. To
+ * keep feature guids unique they should consist of the reverse dns name of the
+ * organization which implemented the feature and a short name for the feature,
+ * separated by a colon (e.g. com.delphix:async_destroy).
+ *
+ * Reference Counts
+ * ----------------
+ *
+ * Within each pool features can be in one of three states: disabled, enabled,
+ * or active. These states are differentiated by a reference count stored on
+ * disk for each feature:
+ *
+ *   1) If there is no reference count stored on disk the feature is disabled.
+ *   2) If the reference count is 0 a system administrator has enabled the
+ *      feature, but the feature has not been used yet, so no on-disk
+ *      format changes have been made.
+ *   3) If the reference count is greater than 0 the feature is active.
+ *      The format changes required by the feature are currently on disk.
+ *      Note that if the feature's format changes are reversed the feature
+ *      may choose to set its reference count back to 0.
+ *
+ * Feature flags makes no differentiation between non-zero reference counts
+ * for an active feature (e.g. a reference count of 1 means the same thing as a
+ * reference count of 27834721), but feature implementations may choose to use
+ * the reference count to store meaningful information. For example, a new RAID
+ * implementation might set the reference count to the number of vdevs using
+ * it. If all those disks are removed from the pool the feature goes back to
+ * having a reference count of 0.
+ *
+ * It is the responsibility of the individual features to maintain a non-zero
+ * reference count as long as the feature's format changes are present on disk.
+ *
+ * Dependencies
+ * ------------
+ *
+ * Each feature may depend on other features. The only effect of this
+ * relationship is that when a feature is enabled all of its dependencies are
+ * automatically enabled as well. Any future work to support disabling of
+ * features would need to ensure that features cannot be disabled if other
+ * enabled features depend on them.
+ *
+ * On-disk Format
+ * --------------
+ *
+ * When feature flags are enabled spa_version() is set to SPA_VERSION_FEATURES
+ * (5000). In order for this to work the pool is automatically upgraded to
+ * SPA_VERSION_BEFORE_FEATURES (28) first, so all pre-feature flags on disk
+ * format changes will be in use.
+ *
+ * Information about features is stored in 3 ZAP objects in the pool's MOS.
+ * These objects are linked to by the following names in the pool directory
+ * object:
+ *
+ * 1) features_for_read: feature guid -> reference count
+ *    Features needed to open the pool for reading.
+ * 2) features_for_write: feature guid -> reference count
+ *    Features needed to open the pool for writing.
+ * 3) feature_descriptions: feature guid -> descriptive string
+ *    A human readable string.
+ *
+ * All enabled features appear in either features_for_read or
+ * features_for_write, but not both.
+ *
+ * To open a pool in read-only mode only the features listed in
+ * features_for_read need to be supported.
+ *
+ * To open the pool in read-write mode features in both features_for_read and
+ * features_for_write need to be supported.
+ *
+ * Some features may be required to read the ZAP objects containing feature
+ * information. To allow software to check for compatibility with these features
+ * before the pool is opened their names must be stored in the label in a
+ * new "features_for_read" entry (note that features that are only required
+ * to write to a pool never need to be stored in the label since the
+ * features_for_write ZAP object can be read before the pool is written to).
+ * To save space in the label features must be explicitly marked as needing to
+ * be written to the label. Also, reference counts are not stored in the label,
+ * instead any feature whose reference count drops to 0 is removed from the
+ * label.
+ *
+ * Adding New Features
+ * -------------------
+ *
+ * Features must be registered in zpool_feature_init() function in
+ * zfeature_common.c using the zfeature_register() function. This function
+ * has arguments to specify if the feature should be stored in the
+ * features_for_read or features_for_write ZAP object and if it needs to be
+ * written to the label when active.
+ *
+ * Once a feature is registered it will appear as a "feature@<feature name>"
+ * property which can be set by an administrator. Feature implementors should
+ * use the spa_feature_is_enabled() and spa_feature_is_active() functions to
+ * query the state of a feature and the spa_feature_incr() and
+ * spa_feature_decr() functions to change an enabled feature's reference count.
+ * Reference counts may only be updated in the syncing context.
+ *
+ * Features may not perform enable-time initialization. Instead, any such
+ * initialization should occur when the feature is first used. This design
+ * enforces that on-disk changes be made only when features are used. Code
+ * should only check if a feature is enabled using spa_feature_is_enabled(),
+ * not by relying on any feature specific metadata existing. If a feature is
+ * enabled, but the feature's metadata is not on disk yet then it should be
+ * created as needed.
+ *
+ * As an example, consider the com.delphix:async_destroy feature. This feature
+ * relies on the existence of a bptree in the MOS that store blocks for
+ * asynchronous freeing. This bptree is not created when async_destroy is
+ * enabled. Instead, when a dataset is destroyed spa_feature_is_enabled() is
+ * called to check if async_destroy is enabled. If it is and the bptree object
+ * does not exist yet, the bptree object is created as part of the dataset
+ * destroy and async_destroy's reference count is incremented to indicate it
+ * has made an on-disk format change. Later, after the destroyed dataset's
+ * blocks have all been asynchronously freed there is no longer any use for the
+ * bptree object, so it is destroyed and async_destroy's reference count is
+ * decremented back to 0 to indicate that it has undone its on-disk format
+ * changes.
+ */
+
+typedef enum {
+	FEATURE_ACTION_INCR,
+	FEATURE_ACTION_DECR,
+} feature_action_t;
+
+/*
+ * Checks that the active features in the pool are supported by
+ * this software.  Adds each unsupported feature (name -> description) to
+ * the supplied nvlist.
+ */
+boolean_t
+spa_features_check(spa_t *spa, boolean_t for_write,
+    nvlist_t *unsup_feat, nvlist_t *enabled_feat)
+{
+	objset_t *os = spa->spa_meta_objset;
+	boolean_t supported;
+	zap_cursor_t *zc;
+	zap_attribute_t *za;
+	uint64_t obj = for_write ?
+	    spa->spa_feat_for_write_obj : spa->spa_feat_for_read_obj;
+	char *buf;
+
+	zc = kmem_alloc(sizeof (zap_cursor_t), KM_SLEEP);
+	za = kmem_alloc(sizeof (zap_attribute_t), KM_SLEEP);
+	buf = kmem_alloc(MAXPATHLEN, KM_SLEEP);
+
+	supported = B_TRUE;
+	for (zap_cursor_init(zc, os, obj);
+	    zap_cursor_retrieve(zc, za) == 0;
+	    zap_cursor_advance(zc)) {
+		ASSERT(za->za_integer_length == sizeof (uint64_t) &&
+		    za->za_num_integers == 1);
+
+		if (NULL != enabled_feat) {
+			fnvlist_add_uint64(enabled_feat, za->za_name,
+			    za->za_first_integer);
+		}
+
+		if (za->za_first_integer != 0 &&
+		    !zfeature_is_supported(za->za_name)) {
+			supported = B_FALSE;
+
+			if (NULL != unsup_feat) {
+				char *desc = "";
+
+				if (zap_lookup(os, spa->spa_feat_desc_obj,
+				    za->za_name, 1, MAXPATHLEN, buf) == 0)
+					desc = buf;
+
+				VERIFY(nvlist_add_string(unsup_feat,
+				    za->za_name, desc) == 0);
+			}
+		}
+	}
+	zap_cursor_fini(zc);
+
+	kmem_free(buf, MAXPATHLEN);
+	kmem_free(za, sizeof (zap_attribute_t));
+	kmem_free(zc, sizeof (zap_cursor_t));
+
+	return (supported);
+}
+
+/*
+ * Use an in-memory cache of feature refcounts for quick retrieval.
+ *
+ * Note: well-designed features will not need to use this; they should
+ * use spa_feature_is_enabled() and spa_feature_is_active() instead.
+ * However, this is non-static for zdb, zhack, and spa_add_feature_stats().
+ */
+int
+feature_get_refcount(spa_t *spa, zfeature_info_t *feature, uint64_t *res)
+{
+	ASSERT(VALID_FEATURE_FID(feature->fi_feature));
+	if (spa->spa_feat_refcount_cache[feature->fi_feature] ==
+	    SPA_FEATURE_DISABLED) {
+		return (SET_ERROR(ENOTSUP));
+	}
+	*res = spa->spa_feat_refcount_cache[feature->fi_feature];
+	return (0);
+}
+
+/*
+ * Note: well-designed features will not need to use this; they should
+ * use spa_feature_is_enabled() and spa_feature_is_active() instead.
+ * However, this is non-static for zdb and zhack.
+ */
+int
+feature_get_refcount_from_disk(spa_t *spa, zfeature_info_t *feature,
+    uint64_t *res)
+{
+	int err;
+	uint64_t refcount;
+	uint64_t zapobj = feature->fi_can_readonly ?
+	    spa->spa_feat_for_write_obj : spa->spa_feat_for_read_obj;
+
+	/*
+	 * If the pool is currently being created, the feature objects may not
+	 * have been allocated yet.  Act as though all features are disabled.
+	 */
+	if (zapobj == 0)
+		return (SET_ERROR(ENOTSUP));
+
+	err = zap_lookup(spa->spa_meta_objset, zapobj,
+	    feature->fi_guid, sizeof (uint64_t), 1, &refcount);
+	if (err != 0) {
+		if (err == ENOENT)
+			return (SET_ERROR(ENOTSUP));
+		else
+			return (err);
+	}
+	*res = refcount;
+	return (0);
+}
+
+
+static int
+feature_get_enabled_txg(spa_t *spa, zfeature_info_t *feature, uint64_t *res) {
+	ASSERTV(uint64_t enabled_txg_obj = spa->spa_feat_enabled_txg_obj);
+
+	ASSERT(zfeature_depends_on(feature->fi_feature,
+	    SPA_FEATURE_ENABLED_TXG));
+
+	if (!spa_feature_is_enabled(spa, feature->fi_feature)) {
+		return (SET_ERROR(ENOTSUP));
+	}
+
+	ASSERT(enabled_txg_obj != 0);
+
+	VERIFY0(zap_lookup(spa->spa_meta_objset, spa->spa_feat_enabled_txg_obj,
+	    feature->fi_guid, sizeof (uint64_t), 1, res));
+
+	return (0);
+}
+
+/*
+ * This function is non-static for zhack; it should otherwise not be used
+ * outside this file.
+ */
+void
+feature_sync(spa_t *spa, zfeature_info_t *feature, uint64_t refcount,
+    dmu_tx_t *tx)
+{
+	uint64_t zapobj;
+
+	ASSERT(VALID_FEATURE_OR_NONE(feature->fi_feature));
+	zapobj = feature->fi_can_readonly ?
+	    spa->spa_feat_for_write_obj : spa->spa_feat_for_read_obj;
+	VERIFY0(zap_update(spa->spa_meta_objset, zapobj, feature->fi_guid,
+	    sizeof (uint64_t), 1, &refcount, tx));
+
+	/*
+	 * feature_sync is called directly from zhack, allowing the
+	 * creation of arbitrary features whose fi_feature field may
+	 * be greater than SPA_FEATURES. When called from zhack, the
+	 * zfeature_info_t object's fi_feature field will be set to
+	 * SPA_FEATURE_NONE.
+	 */
+	if (feature->fi_feature != SPA_FEATURE_NONE) {
+		uint64_t *refcount_cache =
+		    &spa->spa_feat_refcount_cache[feature->fi_feature];
+		VERIFY3U(*refcount_cache, ==,
+		    atomic_swap_64(refcount_cache, refcount));
+	}
+
+	if (refcount == 0)
+		spa_deactivate_mos_feature(spa, feature->fi_guid);
+	else if (feature->fi_mos)
+		spa_activate_mos_feature(spa, feature->fi_guid, tx);
+}
+
+/*
+ * This function is non-static for zhack; it should otherwise not be used
+ * outside this file.
+ */
+void
+feature_enable_sync(spa_t *spa, zfeature_info_t *feature, dmu_tx_t *tx)
+{
+	uint64_t initial_refcount = feature->fi_activate_on_enable ? 1 : 0;
+	uint64_t zapobj = feature->fi_can_readonly ?
+	    spa->spa_feat_for_write_obj : spa->spa_feat_for_read_obj;
+	int i;
+
+	ASSERT(0 != zapobj);
+	ASSERT(zfeature_is_valid_guid(feature->fi_guid));
+	ASSERT3U(spa_version(spa), >=, SPA_VERSION_FEATURES);
+
+	/*
+	 * If the feature is already enabled, ignore the request.
+	 */
+	if (zap_contains(spa->spa_meta_objset, zapobj, feature->fi_guid) == 0)
+		return;
+
+	for (i = 0; feature->fi_depends[i] != SPA_FEATURE_NONE; i++)
+		spa_feature_enable(spa, feature->fi_depends[i], tx);
+
+	VERIFY0(zap_update(spa->spa_meta_objset, spa->spa_feat_desc_obj,
+	    feature->fi_guid, 1, strlen(feature->fi_desc) + 1,
+	    feature->fi_desc, tx));
+
+	feature_sync(spa, feature, initial_refcount, tx);
+
+	if (spa_feature_is_enabled(spa, SPA_FEATURE_ENABLED_TXG)) {
+		uint64_t enabling_txg = dmu_tx_get_txg(tx);
+
+		if (spa->spa_feat_enabled_txg_obj == 0ULL) {
+			spa->spa_feat_enabled_txg_obj =
+			    zap_create_link(spa->spa_meta_objset,
+			    DMU_OTN_ZAP_METADATA, DMU_POOL_DIRECTORY_OBJECT,
+			    DMU_POOL_FEATURE_ENABLED_TXG, tx);
+		}
+		spa_feature_incr(spa, SPA_FEATURE_ENABLED_TXG, tx);
+
+		VERIFY0(zap_add(spa->spa_meta_objset,
+		    spa->spa_feat_enabled_txg_obj, feature->fi_guid,
+		    sizeof (uint64_t), 1, &enabling_txg, tx));
+	}
+}
+
+static void
+feature_do_action(spa_t *spa, spa_feature_t fid, feature_action_t action,
+    dmu_tx_t *tx)
+{
+	uint64_t refcount = 0;
+	zfeature_info_t *feature = &spa_feature_table[fid];
+	ASSERTV(uint64_t zapobj = feature->fi_can_readonly ?
+	    spa->spa_feat_for_write_obj : spa->spa_feat_for_read_obj);
+
+	ASSERT(VALID_FEATURE_FID(fid));
+	ASSERT(0 != zapobj);
+	ASSERT(zfeature_is_valid_guid(feature->fi_guid));
+
+	ASSERT(dmu_tx_is_syncing(tx));
+	ASSERT3U(spa_version(spa), >=, SPA_VERSION_FEATURES);
+
+	VERIFY3U(feature_get_refcount(spa, feature, &refcount), !=, ENOTSUP);
+
+	switch (action) {
+	case FEATURE_ACTION_INCR:
+		VERIFY3U(refcount, !=, UINT64_MAX);
+		refcount++;
+		break;
+	case FEATURE_ACTION_DECR:
+		VERIFY3U(refcount, !=, 0);
+		refcount--;
+		break;
+	default:
+		ASSERT(0);
+		break;
+	}
+
+	feature_sync(spa, feature, refcount, tx);
+}
+
+void
+spa_feature_create_zap_objects(spa_t *spa, dmu_tx_t *tx)
+{
+	/*
+	 * We create feature flags ZAP objects in two instances: during pool
+	 * creation and during pool upgrade.
+	 */
+	ASSERT(dsl_pool_sync_context(spa_get_dsl(spa)) || (!spa->spa_sync_on &&
+	    tx->tx_txg == TXG_INITIAL));
+
+	spa->spa_feat_for_read_obj = zap_create_link(spa->spa_meta_objset,
+	    DMU_OTN_ZAP_METADATA, DMU_POOL_DIRECTORY_OBJECT,
+	    DMU_POOL_FEATURES_FOR_READ, tx);
+	spa->spa_feat_for_write_obj = zap_create_link(spa->spa_meta_objset,
+	    DMU_OTN_ZAP_METADATA, DMU_POOL_DIRECTORY_OBJECT,
+	    DMU_POOL_FEATURES_FOR_WRITE, tx);
+	spa->spa_feat_desc_obj = zap_create_link(spa->spa_meta_objset,
+	    DMU_OTN_ZAP_METADATA, DMU_POOL_DIRECTORY_OBJECT,
+	    DMU_POOL_FEATURE_DESCRIPTIONS, tx);
+}
+
+/*
+ * Enable any required dependencies, then enable the requested feature.
+ */
+void
+spa_feature_enable(spa_t *spa, spa_feature_t fid, dmu_tx_t *tx)
+{
+	ASSERT3U(spa_version(spa), >=, SPA_VERSION_FEATURES);
+	ASSERT(VALID_FEATURE_FID(fid));
+	feature_enable_sync(spa, &spa_feature_table[fid], tx);
+}
+
+void
+spa_feature_incr(spa_t *spa, spa_feature_t fid, dmu_tx_t *tx)
+{
+	feature_do_action(spa, fid, FEATURE_ACTION_INCR, tx);
+}
+
+void
+spa_feature_decr(spa_t *spa, spa_feature_t fid, dmu_tx_t *tx)
+{
+	feature_do_action(spa, fid, FEATURE_ACTION_DECR, tx);
+}
+
+boolean_t
+spa_feature_is_enabled(spa_t *spa, spa_feature_t fid)
+{
+	int err;
+	uint64_t refcount = 0;
+
+	ASSERT(VALID_FEATURE_FID(fid));
+	if (spa_version(spa) < SPA_VERSION_FEATURES)
+		return (B_FALSE);
+
+	err = feature_get_refcount(spa, &spa_feature_table[fid], &refcount);
+	ASSERT(err == 0 || err == ENOTSUP);
+	return (err == 0);
+}
+
+boolean_t
+spa_feature_is_active(spa_t *spa, spa_feature_t fid)
+{
+	int err;
+	uint64_t refcount = 0;
+
+	ASSERT(VALID_FEATURE_FID(fid));
+	if (spa_version(spa) < SPA_VERSION_FEATURES)
+		return (B_FALSE);
+
+	err = feature_get_refcount(spa, &spa_feature_table[fid], &refcount);
+	ASSERT(err == 0 || err == ENOTSUP);
+	return (err == 0 && refcount > 0);
+}
+
+/*
+ * For the feature specified by fid (which must depend on
+ * SPA_FEATURE_ENABLED_TXG), return the TXG at which it was enabled in the
+ * OUT txg argument.
+ *
+ * Returns B_TRUE if the feature is enabled, in which case txg will be filled
+ * with the transaction group in which the specified feature was enabled.
+ * Returns B_FALSE otherwise (i.e. if the feature is not enabled).
+ */
+boolean_t
+spa_feature_enabled_txg(spa_t *spa, spa_feature_t fid, uint64_t *txg) {
+	int err;
+
+	ASSERT(VALID_FEATURE_FID(fid));
+	if (spa_version(spa) < SPA_VERSION_FEATURES)
+		return (B_FALSE);
+
+	err = feature_get_enabled_txg(spa, &spa_feature_table[fid], txg);
+	ASSERT(err == 0 || err == ENOTSUP);
+
+	return (err == 0);
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/module/zfs/zfeature_common.c
@@ -0,0 +1,245 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2013 by Delphix. All rights reserved.
+ * Copyright (c) 2013 by Saso Kiselkov. All rights reserved.
+ * Copyright (c) 2014, Nexenta Systems, Inc. All rights reserved.
+ */
+
+#ifdef _KERNEL
+#include <sys/systm.h>
+#else
+#include <errno.h>
+#include <string.h>
+#endif
+#include <sys/debug.h>
+#include <sys/fs/zfs.h>
+#include <sys/inttypes.h>
+#include <sys/types.h>
+#include "zfeature_common.h"
+
+/*
+ * Set to disable all feature checks while opening pools, allowing pools with
+ * unsupported features to be opened. Set for testing only.
+ */
+boolean_t zfeature_checks_disable = B_FALSE;
+
+zfeature_info_t spa_feature_table[SPA_FEATURES];
+
+/*
+ * Valid characters for feature guids. This list is mainly for aesthetic
+ * purposes and could be expanded in the future. There are different allowed
+ * characters in the guids reverse dns portion (before the colon) and its
+ * short name (after the colon).
+ */
+static int
+valid_char(char c, boolean_t after_colon)
+{
+	return ((c >= 'a' && c <= 'z') ||
+	    (c >= '0' && c <= '9') ||
+	    (after_colon && c == '_') ||
+	    (!after_colon && (c == '.' || c == '-')));
+}
+
+/*
+ * Every feature guid must contain exactly one colon which separates a reverse
+ * dns organization name from the feature's "short" name (e.g.
+ * "com.company:feature_name").
+ */
+boolean_t
+zfeature_is_valid_guid(const char *name)
+{
+	int i;
+	boolean_t has_colon = B_FALSE;
+
+	i = 0;
+	while (name[i] != '\0') {
+		char c = name[i++];
+		if (c == ':') {
+			if (has_colon)
+				return (B_FALSE);
+			has_colon = B_TRUE;
+			continue;
+		}
+		if (!valid_char(c, has_colon))
+			return (B_FALSE);
+	}
+
+	return (has_colon);
+}
+
+boolean_t
+zfeature_is_supported(const char *guid)
+{
+	spa_feature_t i;
+
+	if (zfeature_checks_disable)
+		return (B_TRUE);
+
+	for (i = 0; i < SPA_FEATURES; i++) {
+		zfeature_info_t *feature = &spa_feature_table[i];
+		if (strcmp(guid, feature->fi_guid) == 0)
+			return (B_TRUE);
+	}
+
+	return (B_FALSE);
+}
+
+int
+zfeature_lookup_name(const char *name, spa_feature_t *res)
+{
+	spa_feature_t i;
+
+	for (i = 0; i < SPA_FEATURES; i++) {
+		zfeature_info_t *feature = &spa_feature_table[i];
+		if (strcmp(name, feature->fi_uname) == 0) {
+			if (res != NULL)
+				*res = i;
+			return (0);
+		}
+	}
+
+	return (ENOENT);
+}
+
+boolean_t
+zfeature_depends_on(spa_feature_t fid, spa_feature_t check) {
+	zfeature_info_t *feature = &spa_feature_table[fid];
+	int i;
+
+	for (i = 0; feature->fi_depends[i] != SPA_FEATURE_NONE; i++) {
+		if (feature->fi_depends[i] == check)
+			return (B_TRUE);
+	}
+	return (B_FALSE);
+}
+
+static void
+zfeature_register(spa_feature_t fid, const char *guid, const char *name,
+    const char *desc, boolean_t readonly, boolean_t mos,
+    boolean_t activate_on_enable, const spa_feature_t *deps)
+{
+	zfeature_info_t *feature = &spa_feature_table[fid];
+	static spa_feature_t nodeps[] = { SPA_FEATURE_NONE };
+
+	ASSERT(name != NULL);
+	ASSERT(desc != NULL);
+	ASSERT(!readonly || !mos);
+	ASSERT3U(fid, <, SPA_FEATURES);
+	ASSERT(zfeature_is_valid_guid(guid));
+
+	if (deps == NULL)
+		deps = nodeps;
+
+	feature->fi_feature = fid;
+	feature->fi_guid = guid;
+	feature->fi_uname = name;
+	feature->fi_desc = desc;
+	feature->fi_can_readonly = readonly;
+	feature->fi_mos = mos;
+	feature->fi_activate_on_enable = activate_on_enable;
+	feature->fi_depends = deps;
+}
+
+void
+zpool_feature_init(void)
+{
+	zfeature_register(SPA_FEATURE_ASYNC_DESTROY,
+	    "com.delphix:async_destroy", "async_destroy",
+	    "Destroy filesystems asynchronously.", B_TRUE, B_FALSE,
+	    B_FALSE, NULL);
+
+	zfeature_register(SPA_FEATURE_EMPTY_BPOBJ,
+	    "com.delphix:empty_bpobj", "empty_bpobj",
+	    "Snapshots use less space.", B_TRUE, B_FALSE,
+	    B_FALSE, NULL);
+
+	zfeature_register(SPA_FEATURE_LZ4_COMPRESS,
+	    "org.illumos:lz4_compress", "lz4_compress",
+	    "LZ4 compression algorithm support.", B_FALSE, B_FALSE,
+	    B_TRUE, NULL);
+
+	zfeature_register(SPA_FEATURE_SPACEMAP_HISTOGRAM,
+	    "com.delphix:spacemap_histogram", "spacemap_histogram",
+	    "Spacemaps maintain space histograms.", B_TRUE, B_FALSE,
+	    B_FALSE, NULL);
+
+	zfeature_register(SPA_FEATURE_ENABLED_TXG,
+	    "com.delphix:enabled_txg", "enabled_txg",
+	    "Record txg at which a feature is enabled", B_TRUE, B_FALSE,
+	    B_FALSE, NULL);
+
+	{
+	static const spa_feature_t hole_birth_deps[] = {
+		SPA_FEATURE_ENABLED_TXG,
+		SPA_FEATURE_NONE
+	};
+	zfeature_register(SPA_FEATURE_HOLE_BIRTH,
+	    "com.delphix:hole_birth", "hole_birth",
+	    "Retain hole birth txg for more precise zfs send",
+	    B_FALSE, B_TRUE, B_TRUE, hole_birth_deps);
+	}
+
+	zfeature_register(SPA_FEATURE_EXTENSIBLE_DATASET,
+	    "com.delphix:extensible_dataset", "extensible_dataset",
+	    "Enhanced dataset functionality, used by other features.",
+	    B_FALSE, B_FALSE, B_FALSE, NULL);
+
+	{
+	static const spa_feature_t bookmarks_deps[] = {
+		SPA_FEATURE_EXTENSIBLE_DATASET,
+		SPA_FEATURE_NONE
+	};
+
+	zfeature_register(SPA_FEATURE_BOOKMARKS,
+	    "com.delphix:bookmarks", "bookmarks",
+	    "\"zfs bookmark\" command",
+	    B_TRUE, B_FALSE, B_FALSE, bookmarks_deps);
+	}
+
+	{
+	static const spa_feature_t filesystem_limits_deps[] = {
+	    SPA_FEATURE_EXTENSIBLE_DATASET,
+	    SPA_FEATURE_NONE
+	};
+	zfeature_register(SPA_FEATURE_FS_SS_LIMIT,
+	    "com.joyent:filesystem_limits", "filesystem_limits",
+	    "Filesystem and snapshot limits.", B_TRUE, B_FALSE, B_FALSE,
+	    filesystem_limits_deps);
+	}
+
+	zfeature_register(SPA_FEATURE_EMBEDDED_DATA,
+	    "com.delphix:embedded_data", "embedded_data",
+	    "Blocks which compress very well use even less space.",
+	    B_FALSE, B_TRUE, B_TRUE, NULL);
+
+	{
+	static const spa_feature_t large_blocks_deps[] = {
+		SPA_FEATURE_EXTENSIBLE_DATASET,
+		SPA_FEATURE_NONE
+	};
+	zfeature_register(SPA_FEATURE_LARGE_BLOCKS,
+	    "org.open-zfs:large_blocks", "large_blocks",
+	    "Support for blocks larger than 128KB.", B_FALSE, B_FALSE, B_FALSE,
+	    large_blocks_deps);
+	}
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/module/zfs/zfs_acl.c
@@ -0,0 +1,2830 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013 by Delphix. All rights reserved.
+ */
+
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/time.h>
+#include <sys/systm.h>
+#include <sys/sysmacros.h>
+#include <sys/resource.h>
+#include <sys/vfs.h>
+#include <sys/vnode.h>
+#include <sys/sid.h>
+#include <sys/file.h>
+#include <sys/stat.h>
+#include <sys/kmem.h>
+#include <sys/cmn_err.h>
+#include <sys/errno.h>
+#include <sys/unistd.h>
+#include <sys/sdt.h>
+#include <sys/fs/zfs.h>
+#include <sys/mode.h>
+#include <sys/policy.h>
+#include <sys/zfs_znode.h>
+#include <sys/zfs_fuid.h>
+#include <sys/zfs_acl.h>
+#include <sys/zfs_dir.h>
+#include <sys/zfs_vfsops.h>
+#include <sys/dmu.h>
+#include <sys/dnode.h>
+#include <sys/zap.h>
+#include <sys/sa.h>
+#include <sys/trace_acl.h>
+#include "fs/fs_subr.h"
+
+#define	ALLOW	ACE_ACCESS_ALLOWED_ACE_TYPE
+#define	DENY	ACE_ACCESS_DENIED_ACE_TYPE
+#define	MAX_ACE_TYPE	ACE_SYSTEM_ALARM_CALLBACK_OBJECT_ACE_TYPE
+#define	MIN_ACE_TYPE	ALLOW
+
+#define	OWNING_GROUP		(ACE_GROUP|ACE_IDENTIFIER_GROUP)
+#define	EVERYONE_ALLOW_MASK (ACE_READ_ACL|ACE_READ_ATTRIBUTES | \
+    ACE_READ_NAMED_ATTRS|ACE_SYNCHRONIZE)
+#define	EVERYONE_DENY_MASK (ACE_WRITE_ACL|ACE_WRITE_OWNER | \
+    ACE_WRITE_ATTRIBUTES|ACE_WRITE_NAMED_ATTRS)
+#define	OWNER_ALLOW_MASK (ACE_WRITE_ACL | ACE_WRITE_OWNER | \
+    ACE_WRITE_ATTRIBUTES|ACE_WRITE_NAMED_ATTRS)
+
+#define	ZFS_CHECKED_MASKS (ACE_READ_ACL|ACE_READ_ATTRIBUTES|ACE_READ_DATA| \
+    ACE_READ_NAMED_ATTRS|ACE_WRITE_DATA|ACE_WRITE_ATTRIBUTES| \
+    ACE_WRITE_NAMED_ATTRS|ACE_APPEND_DATA|ACE_EXECUTE|ACE_WRITE_OWNER| \
+    ACE_WRITE_ACL|ACE_DELETE|ACE_DELETE_CHILD|ACE_SYNCHRONIZE)
+
+#define	WRITE_MASK_DATA (ACE_WRITE_DATA|ACE_APPEND_DATA|ACE_WRITE_NAMED_ATTRS)
+#define	WRITE_MASK_ATTRS (ACE_WRITE_ACL|ACE_WRITE_OWNER|ACE_WRITE_ATTRIBUTES| \
+    ACE_DELETE|ACE_DELETE_CHILD)
+#define	WRITE_MASK (WRITE_MASK_DATA|WRITE_MASK_ATTRS)
+
+#define	OGE_CLEAR	(ACE_READ_DATA|ACE_LIST_DIRECTORY|ACE_WRITE_DATA| \
+    ACE_ADD_FILE|ACE_APPEND_DATA|ACE_ADD_SUBDIRECTORY|ACE_EXECUTE)
+
+#define	OKAY_MASK_BITS (ACE_READ_DATA|ACE_LIST_DIRECTORY|ACE_WRITE_DATA| \
+    ACE_ADD_FILE|ACE_APPEND_DATA|ACE_ADD_SUBDIRECTORY|ACE_EXECUTE)
+
+#define	ALL_INHERIT	(ACE_FILE_INHERIT_ACE|ACE_DIRECTORY_INHERIT_ACE | \
+    ACE_NO_PROPAGATE_INHERIT_ACE|ACE_INHERIT_ONLY_ACE|ACE_INHERITED_ACE)
+
+#define	RESTRICTED_CLEAR	(ACE_WRITE_ACL|ACE_WRITE_OWNER)
+
+#define	V4_ACL_WIDE_FLAGS (ZFS_ACL_AUTO_INHERIT|ZFS_ACL_DEFAULTED|\
+    ZFS_ACL_PROTECTED)
+
+#define	ZFS_ACL_WIDE_FLAGS (V4_ACL_WIDE_FLAGS|ZFS_ACL_TRIVIAL|ZFS_INHERIT_ACE|\
+    ZFS_ACL_OBJ_ACE)
+
+#define	ALL_MODE_EXECS (S_IXUSR | S_IXGRP | S_IXOTH)
+
+static uint16_t
+zfs_ace_v0_get_type(void *acep)
+{
+	return (((zfs_oldace_t *)acep)->z_type);
+}
+
+static uint16_t
+zfs_ace_v0_get_flags(void *acep)
+{
+	return (((zfs_oldace_t *)acep)->z_flags);
+}
+
+static uint32_t
+zfs_ace_v0_get_mask(void *acep)
+{
+	return (((zfs_oldace_t *)acep)->z_access_mask);
+}
+
+static uint64_t
+zfs_ace_v0_get_who(void *acep)
+{
+	return (((zfs_oldace_t *)acep)->z_fuid);
+}
+
+static void
+zfs_ace_v0_set_type(void *acep, uint16_t type)
+{
+	((zfs_oldace_t *)acep)->z_type = type;
+}
+
+static void
+zfs_ace_v0_set_flags(void *acep, uint16_t flags)
+{
+	((zfs_oldace_t *)acep)->z_flags = flags;
+}
+
+static void
+zfs_ace_v0_set_mask(void *acep, uint32_t mask)
+{
+	((zfs_oldace_t *)acep)->z_access_mask = mask;
+}
+
+static void
+zfs_ace_v0_set_who(void *acep, uint64_t who)
+{
+	((zfs_oldace_t *)acep)->z_fuid = who;
+}
+
+/*ARGSUSED*/
+static size_t
+zfs_ace_v0_size(void *acep)
+{
+	return (sizeof (zfs_oldace_t));
+}
+
+static size_t
+zfs_ace_v0_abstract_size(void)
+{
+	return (sizeof (zfs_oldace_t));
+}
+
+static int
+zfs_ace_v0_mask_off(void)
+{
+	return (offsetof(zfs_oldace_t, z_access_mask));
+}
+
+/*ARGSUSED*/
+static int
+zfs_ace_v0_data(void *acep, void **datap)
+{
+	*datap = NULL;
+	return (0);
+}
+
+static acl_ops_t zfs_acl_v0_ops = {
+	zfs_ace_v0_get_mask,
+	zfs_ace_v0_set_mask,
+	zfs_ace_v0_get_flags,
+	zfs_ace_v0_set_flags,
+	zfs_ace_v0_get_type,
+	zfs_ace_v0_set_type,
+	zfs_ace_v0_get_who,
+	zfs_ace_v0_set_who,
+	zfs_ace_v0_size,
+	zfs_ace_v0_abstract_size,
+	zfs_ace_v0_mask_off,
+	zfs_ace_v0_data
+};
+
+static uint16_t
+zfs_ace_fuid_get_type(void *acep)
+{
+	return (((zfs_ace_hdr_t *)acep)->z_type);
+}
+
+static uint16_t
+zfs_ace_fuid_get_flags(void *acep)
+{
+	return (((zfs_ace_hdr_t *)acep)->z_flags);
+}
+
+static uint32_t
+zfs_ace_fuid_get_mask(void *acep)
+{
+	return (((zfs_ace_hdr_t *)acep)->z_access_mask);
+}
+
+static uint64_t
+zfs_ace_fuid_get_who(void *args)
+{
+	uint16_t entry_type;
+	zfs_ace_t *acep = args;
+
+	entry_type = acep->z_hdr.z_flags & ACE_TYPE_FLAGS;
+
+	if (entry_type == ACE_OWNER || entry_type == OWNING_GROUP ||
+	    entry_type == ACE_EVERYONE)
+		return (-1);
+	return (((zfs_ace_t *)acep)->z_fuid);
+}
+
+static void
+zfs_ace_fuid_set_type(void *acep, uint16_t type)
+{
+	((zfs_ace_hdr_t *)acep)->z_type = type;
+}
+
+static void
+zfs_ace_fuid_set_flags(void *acep, uint16_t flags)
+{
+	((zfs_ace_hdr_t *)acep)->z_flags = flags;
+}
+
+static void
+zfs_ace_fuid_set_mask(void *acep, uint32_t mask)
+{
+	((zfs_ace_hdr_t *)acep)->z_access_mask = mask;
+}
+
+static void
+zfs_ace_fuid_set_who(void *arg, uint64_t who)
+{
+	zfs_ace_t *acep = arg;
+
+	uint16_t entry_type = acep->z_hdr.z_flags & ACE_TYPE_FLAGS;
+
+	if (entry_type == ACE_OWNER || entry_type == OWNING_GROUP ||
+	    entry_type == ACE_EVERYONE)
+		return;
+	acep->z_fuid = who;
+}
+
+static size_t
+zfs_ace_fuid_size(void *acep)
+{
+	zfs_ace_hdr_t *zacep = acep;
+	uint16_t entry_type;
+
+	switch (zacep->z_type) {
+	case ACE_ACCESS_ALLOWED_OBJECT_ACE_TYPE:
+	case ACE_ACCESS_DENIED_OBJECT_ACE_TYPE:
+	case ACE_SYSTEM_AUDIT_OBJECT_ACE_TYPE:
+	case ACE_SYSTEM_ALARM_OBJECT_ACE_TYPE:
+		return (sizeof (zfs_object_ace_t));
+	case ALLOW:
+	case DENY:
+		entry_type =
+		    (((zfs_ace_hdr_t *)acep)->z_flags & ACE_TYPE_FLAGS);
+		if (entry_type == ACE_OWNER ||
+		    entry_type == OWNING_GROUP ||
+		    entry_type == ACE_EVERYONE)
+			return (sizeof (zfs_ace_hdr_t));
+		/*FALLTHROUGH*/
+	default:
+		return (sizeof (zfs_ace_t));
+	}
+}
+
+static size_t
+zfs_ace_fuid_abstract_size(void)
+{
+	return (sizeof (zfs_ace_hdr_t));
+}
+
+static int
+zfs_ace_fuid_mask_off(void)
+{
+	return (offsetof(zfs_ace_hdr_t, z_access_mask));
+}
+
+static int
+zfs_ace_fuid_data(void *acep, void **datap)
+{
+	zfs_ace_t *zacep = acep;
+	zfs_object_ace_t *zobjp;
+
+	switch (zacep->z_hdr.z_type) {
+	case ACE_ACCESS_ALLOWED_OBJECT_ACE_TYPE:
+	case ACE_ACCESS_DENIED_OBJECT_ACE_TYPE:
+	case ACE_SYSTEM_AUDIT_OBJECT_ACE_TYPE:
+	case ACE_SYSTEM_ALARM_OBJECT_ACE_TYPE:
+		zobjp = acep;
+		*datap = (caddr_t)zobjp + sizeof (zfs_ace_t);
+		return (sizeof (zfs_object_ace_t) - sizeof (zfs_ace_t));
+	default:
+		*datap = NULL;
+		return (0);
+	}
+}
+
+static acl_ops_t zfs_acl_fuid_ops = {
+	zfs_ace_fuid_get_mask,
+	zfs_ace_fuid_set_mask,
+	zfs_ace_fuid_get_flags,
+	zfs_ace_fuid_set_flags,
+	zfs_ace_fuid_get_type,
+	zfs_ace_fuid_set_type,
+	zfs_ace_fuid_get_who,
+	zfs_ace_fuid_set_who,
+	zfs_ace_fuid_size,
+	zfs_ace_fuid_abstract_size,
+	zfs_ace_fuid_mask_off,
+	zfs_ace_fuid_data
+};
+
+/*
+ * The following three functions are provided for compatibility with
+ * older ZPL version in order to determine if the file use to have
+ * an external ACL and what version of ACL previously existed on the
+ * file.  Would really be nice to not need this, sigh.
+ */
+uint64_t
+zfs_external_acl(znode_t *zp)
+{
+	zfs_acl_phys_t acl_phys;
+	int error;
+
+	if (zp->z_is_sa)
+		return (0);
+
+	/*
+	 * Need to deal with a potential
+	 * race where zfs_sa_upgrade could cause
+	 * z_isa_sa to change.
+	 *
+	 * If the lookup fails then the state of z_is_sa should have
+	 * changed.
+	 */
+
+	if ((error = sa_lookup(zp->z_sa_hdl, SA_ZPL_ZNODE_ACL(ZTOZSB(zp)),
+	    &acl_phys, sizeof (acl_phys))) == 0)
+		return (acl_phys.z_acl_extern_obj);
+	else {
+		/*
+		 * after upgrade the SA_ZPL_ZNODE_ACL should have been
+		 * removed
+		 */
+		VERIFY(zp->z_is_sa && error == ENOENT);
+		return (0);
+	}
+}
+
+/*
+ * Determine size of ACL in bytes
+ *
+ * This is more complicated than it should be since we have to deal
+ * with old external ACLs.
+ */
+static int
+zfs_acl_znode_info(znode_t *zp, int *aclsize, int *aclcount,
+    zfs_acl_phys_t *aclphys)
+{
+	zfs_sb_t *zsb = ZTOZSB(zp);
+	uint64_t acl_count;
+	int size;
+	int error;
+
+	ASSERT(MUTEX_HELD(&zp->z_acl_lock));
+	if (zp->z_is_sa) {
+		if ((error = sa_size(zp->z_sa_hdl, SA_ZPL_DACL_ACES(zsb),
+		    &size)) != 0)
+			return (error);
+		*aclsize = size;
+		if ((error = sa_lookup(zp->z_sa_hdl, SA_ZPL_DACL_COUNT(zsb),
+		    &acl_count, sizeof (acl_count))) != 0)
+			return (error);
+		*aclcount = acl_count;
+	} else {
+		if ((error = sa_lookup(zp->z_sa_hdl, SA_ZPL_ZNODE_ACL(zsb),
+		    aclphys, sizeof (*aclphys))) != 0)
+			return (error);
+
+		if (aclphys->z_acl_version == ZFS_ACL_VERSION_INITIAL) {
+			*aclsize = ZFS_ACL_SIZE(aclphys->z_acl_size);
+			*aclcount = aclphys->z_acl_size;
+		} else {
+			*aclsize = aclphys->z_acl_size;
+			*aclcount = aclphys->z_acl_count;
+		}
+	}
+	return (0);
+}
+
+int
+zfs_znode_acl_version(znode_t *zp)
+{
+	zfs_acl_phys_t acl_phys;
+
+	if (zp->z_is_sa)
+		return (ZFS_ACL_VERSION_FUID);
+	else {
+		int error;
+
+		/*
+		 * Need to deal with a potential
+		 * race where zfs_sa_upgrade could cause
+		 * z_isa_sa to change.
+		 *
+		 * If the lookup fails then the state of z_is_sa should have
+		 * changed.
+		 */
+		if ((error = sa_lookup(zp->z_sa_hdl,
+		    SA_ZPL_ZNODE_ACL(ZTOZSB(zp)),
+		    &acl_phys, sizeof (acl_phys))) == 0)
+			return (acl_phys.z_acl_version);
+		else {
+			/*
+			 * After upgrade SA_ZPL_ZNODE_ACL should have
+			 * been removed.
+			 */
+			VERIFY(zp->z_is_sa && error == ENOENT);
+			return (ZFS_ACL_VERSION_FUID);
+		}
+	}
+}
+
+static int
+zfs_acl_version(int version)
+{
+	if (version < ZPL_VERSION_FUID)
+		return (ZFS_ACL_VERSION_INITIAL);
+	else
+		return (ZFS_ACL_VERSION_FUID);
+}
+
+static int
+zfs_acl_version_zp(znode_t *zp)
+{
+	return (zfs_acl_version(ZTOZSB(zp)->z_version));
+}
+
+zfs_acl_t *
+zfs_acl_alloc(int vers)
+{
+	zfs_acl_t *aclp;
+
+	aclp = kmem_zalloc(sizeof (zfs_acl_t), KM_SLEEP);
+	list_create(&aclp->z_acl, sizeof (zfs_acl_node_t),
+	    offsetof(zfs_acl_node_t, z_next));
+	aclp->z_version = vers;
+	if (vers == ZFS_ACL_VERSION_FUID)
+		aclp->z_ops = &zfs_acl_fuid_ops;
+	else
+		aclp->z_ops = &zfs_acl_v0_ops;
+	return (aclp);
+}
+
+zfs_acl_node_t *
+zfs_acl_node_alloc(size_t bytes)
+{
+	zfs_acl_node_t *aclnode;
+
+	aclnode = kmem_zalloc(sizeof (zfs_acl_node_t), KM_SLEEP);
+	if (bytes) {
+		aclnode->z_acldata = kmem_alloc(bytes, KM_SLEEP);
+		aclnode->z_allocdata = aclnode->z_acldata;
+		aclnode->z_allocsize = bytes;
+		aclnode->z_size = bytes;
+	}
+
+	return (aclnode);
+}
+
+static void
+zfs_acl_node_free(zfs_acl_node_t *aclnode)
+{
+	if (aclnode->z_allocsize)
+		kmem_free(aclnode->z_allocdata, aclnode->z_allocsize);
+	kmem_free(aclnode, sizeof (zfs_acl_node_t));
+}
+
+static void
+zfs_acl_release_nodes(zfs_acl_t *aclp)
+{
+	zfs_acl_node_t *aclnode;
+
+	while ((aclnode = list_head(&aclp->z_acl))) {
+		list_remove(&aclp->z_acl, aclnode);
+		zfs_acl_node_free(aclnode);
+	}
+	aclp->z_acl_count = 0;
+	aclp->z_acl_bytes = 0;
+}
+
+void
+zfs_acl_free(zfs_acl_t *aclp)
+{
+	zfs_acl_release_nodes(aclp);
+	list_destroy(&aclp->z_acl);
+	kmem_free(aclp, sizeof (zfs_acl_t));
+}
+
+static boolean_t
+zfs_acl_valid_ace_type(uint_t type, uint_t flags)
+{
+	uint16_t entry_type;
+
+	switch (type) {
+	case ALLOW:
+	case DENY:
+	case ACE_SYSTEM_AUDIT_ACE_TYPE:
+	case ACE_SYSTEM_ALARM_ACE_TYPE:
+		entry_type = flags & ACE_TYPE_FLAGS;
+		return (entry_type == ACE_OWNER ||
+		    entry_type == OWNING_GROUP ||
+		    entry_type == ACE_EVERYONE || entry_type == 0 ||
+		    entry_type == ACE_IDENTIFIER_GROUP);
+	default:
+		if (type >= MIN_ACE_TYPE && type <= MAX_ACE_TYPE)
+			return (B_TRUE);
+	}
+	return (B_FALSE);
+}
+
+static boolean_t
+zfs_ace_valid(umode_t obj_mode, zfs_acl_t *aclp, uint16_t type, uint16_t iflags)
+{
+	/*
+	 * first check type of entry
+	 */
+
+	if (!zfs_acl_valid_ace_type(type, iflags))
+		return (B_FALSE);
+
+	switch (type) {
+	case ACE_ACCESS_ALLOWED_OBJECT_ACE_TYPE:
+	case ACE_ACCESS_DENIED_OBJECT_ACE_TYPE:
+	case ACE_SYSTEM_AUDIT_OBJECT_ACE_TYPE:
+	case ACE_SYSTEM_ALARM_OBJECT_ACE_TYPE:
+		if (aclp->z_version < ZFS_ACL_VERSION_FUID)
+			return (B_FALSE);
+		aclp->z_hints |= ZFS_ACL_OBJ_ACE;
+	}
+
+	/*
+	 * next check inheritance level flags
+	 */
+
+	if (S_ISDIR(obj_mode) &&
+	    (iflags & (ACE_FILE_INHERIT_ACE|ACE_DIRECTORY_INHERIT_ACE)))
+		aclp->z_hints |= ZFS_INHERIT_ACE;
+
+	if (iflags & (ACE_INHERIT_ONLY_ACE|ACE_NO_PROPAGATE_INHERIT_ACE)) {
+		if ((iflags & (ACE_FILE_INHERIT_ACE|
+		    ACE_DIRECTORY_INHERIT_ACE)) == 0) {
+			return (B_FALSE);
+		}
+	}
+
+	return (B_TRUE);
+}
+
+static void *
+zfs_acl_next_ace(zfs_acl_t *aclp, void *start, uint64_t *who,
+    uint32_t *access_mask, uint16_t *iflags, uint16_t *type)
+{
+	zfs_acl_node_t *aclnode;
+
+	ASSERT(aclp);
+
+	if (start == NULL) {
+		aclnode = list_head(&aclp->z_acl);
+		if (aclnode == NULL)
+			return (NULL);
+
+		aclp->z_next_ace = aclnode->z_acldata;
+		aclp->z_curr_node = aclnode;
+		aclnode->z_ace_idx = 0;
+	}
+
+	aclnode = aclp->z_curr_node;
+
+	if (aclnode == NULL)
+		return (NULL);
+
+	if (aclnode->z_ace_idx >= aclnode->z_ace_count) {
+		aclnode = list_next(&aclp->z_acl, aclnode);
+		if (aclnode == NULL)
+			return (NULL);
+		else {
+			aclp->z_curr_node = aclnode;
+			aclnode->z_ace_idx = 0;
+			aclp->z_next_ace = aclnode->z_acldata;
+		}
+	}
+
+	if (aclnode->z_ace_idx < aclnode->z_ace_count) {
+		void *acep = aclp->z_next_ace;
+		size_t ace_size;
+
+		/*
+		 * Make sure we don't overstep our bounds
+		 */
+		ace_size = aclp->z_ops->ace_size(acep);
+
+		if (((caddr_t)acep + ace_size) >
+		    ((caddr_t)aclnode->z_acldata + aclnode->z_size)) {
+			return (NULL);
+		}
+
+		*iflags = aclp->z_ops->ace_flags_get(acep);
+		*type = aclp->z_ops->ace_type_get(acep);
+		*access_mask = aclp->z_ops->ace_mask_get(acep);
+		*who = aclp->z_ops->ace_who_get(acep);
+		aclp->z_next_ace = (caddr_t)aclp->z_next_ace + ace_size;
+		aclnode->z_ace_idx++;
+
+		return ((void *)acep);
+	}
+	return (NULL);
+}
+
+/*ARGSUSED*/
+static uint64_t
+zfs_ace_walk(void *datap, uint64_t cookie, int aclcnt,
+    uint16_t *flags, uint16_t *type, uint32_t *mask)
+{
+	zfs_acl_t *aclp = datap;
+	zfs_ace_hdr_t *acep = (zfs_ace_hdr_t *)(uintptr_t)cookie;
+	uint64_t who;
+
+	acep = zfs_acl_next_ace(aclp, acep, &who, mask,
+	    flags, type);
+	return ((uint64_t)(uintptr_t)acep);
+}
+
+/*
+ * Copy ACE to internal ZFS format.
+ * While processing the ACL each ACE will be validated for correctness.
+ * ACE FUIDs will be created later.
+ */
+int
+zfs_copy_ace_2_fuid(zfs_sb_t *zsb, umode_t obj_mode, zfs_acl_t *aclp,
+    void *datap, zfs_ace_t *z_acl, uint64_t aclcnt, size_t *size,
+    zfs_fuid_info_t **fuidp, cred_t *cr)
+{
+	int i;
+	uint16_t entry_type;
+	zfs_ace_t *aceptr = z_acl;
+	ace_t *acep = datap;
+	zfs_object_ace_t *zobjacep;
+	ace_object_t *aceobjp;
+
+	for (i = 0; i != aclcnt; i++) {
+		aceptr->z_hdr.z_access_mask = acep->a_access_mask;
+		aceptr->z_hdr.z_flags = acep->a_flags;
+		aceptr->z_hdr.z_type = acep->a_type;
+		entry_type = aceptr->z_hdr.z_flags & ACE_TYPE_FLAGS;
+		if (entry_type != ACE_OWNER && entry_type != OWNING_GROUP &&
+		    entry_type != ACE_EVERYONE) {
+			aceptr->z_fuid = zfs_fuid_create(zsb, acep->a_who,
+			    cr, (entry_type == 0) ?
+			    ZFS_ACE_USER : ZFS_ACE_GROUP, fuidp);
+		}
+
+		/*
+		 * Make sure ACE is valid
+		 */
+		if (zfs_ace_valid(obj_mode, aclp, aceptr->z_hdr.z_type,
+		    aceptr->z_hdr.z_flags) != B_TRUE)
+			return (SET_ERROR(EINVAL));
+
+		switch (acep->a_type) {
+		case ACE_ACCESS_ALLOWED_OBJECT_ACE_TYPE:
+		case ACE_ACCESS_DENIED_OBJECT_ACE_TYPE:
+		case ACE_SYSTEM_AUDIT_OBJECT_ACE_TYPE:
+		case ACE_SYSTEM_ALARM_OBJECT_ACE_TYPE:
+			zobjacep = (zfs_object_ace_t *)aceptr;
+			aceobjp = (ace_object_t *)acep;
+
+			bcopy(aceobjp->a_obj_type, zobjacep->z_object_type,
+			    sizeof (aceobjp->a_obj_type));
+			bcopy(aceobjp->a_inherit_obj_type,
+			    zobjacep->z_inherit_type,
+			    sizeof (aceobjp->a_inherit_obj_type));
+			acep = (ace_t *)((caddr_t)acep + sizeof (ace_object_t));
+			break;
+		default:
+			acep = (ace_t *)((caddr_t)acep + sizeof (ace_t));
+		}
+
+		aceptr = (zfs_ace_t *)((caddr_t)aceptr +
+		    aclp->z_ops->ace_size(aceptr));
+	}
+
+	*size = (caddr_t)aceptr - (caddr_t)z_acl;
+
+	return (0);
+}
+
+/*
+ * Copy ZFS ACEs to fixed size ace_t layout
+ */
+static void
+zfs_copy_fuid_2_ace(zfs_sb_t *zsb, zfs_acl_t *aclp, cred_t *cr,
+    void *datap, int filter)
+{
+	uint64_t who;
+	uint32_t access_mask;
+	uint16_t iflags, type;
+	zfs_ace_hdr_t *zacep = NULL;
+	ace_t *acep = datap;
+	ace_object_t *objacep;
+	zfs_object_ace_t *zobjacep;
+	size_t ace_size;
+	uint16_t entry_type;
+
+	while ((zacep = zfs_acl_next_ace(aclp, zacep,
+	    &who, &access_mask, &iflags, &type))) {
+
+		switch (type) {
+		case ACE_ACCESS_ALLOWED_OBJECT_ACE_TYPE:
+		case ACE_ACCESS_DENIED_OBJECT_ACE_TYPE:
+		case ACE_SYSTEM_AUDIT_OBJECT_ACE_TYPE:
+		case ACE_SYSTEM_ALARM_OBJECT_ACE_TYPE:
+			if (filter) {
+				continue;
+			}
+			zobjacep = (zfs_object_ace_t *)zacep;
+			objacep = (ace_object_t *)acep;
+			bcopy(zobjacep->z_object_type,
+			    objacep->a_obj_type,
+			    sizeof (zobjacep->z_object_type));
+			bcopy(zobjacep->z_inherit_type,
+			    objacep->a_inherit_obj_type,
+			    sizeof (zobjacep->z_inherit_type));
+			ace_size = sizeof (ace_object_t);
+			break;
+		default:
+			ace_size = sizeof (ace_t);
+			break;
+		}
+
+		entry_type = (iflags & ACE_TYPE_FLAGS);
+		if ((entry_type != ACE_OWNER &&
+		    entry_type != OWNING_GROUP &&
+		    entry_type != ACE_EVERYONE)) {
+			acep->a_who = zfs_fuid_map_id(zsb, who,
+			    cr, (entry_type & ACE_IDENTIFIER_GROUP) ?
+			    ZFS_ACE_GROUP : ZFS_ACE_USER);
+		} else {
+			acep->a_who = (uid_t)(int64_t)who;
+		}
+		acep->a_access_mask = access_mask;
+		acep->a_flags = iflags;
+		acep->a_type = type;
+		acep = (ace_t *)((caddr_t)acep + ace_size);
+	}
+}
+
+static int
+zfs_copy_ace_2_oldace(umode_t obj_mode, zfs_acl_t *aclp, ace_t *acep,
+    zfs_oldace_t *z_acl, int aclcnt, size_t *size)
+{
+	int i;
+	zfs_oldace_t *aceptr = z_acl;
+
+	for (i = 0; i != aclcnt; i++, aceptr++) {
+		aceptr->z_access_mask = acep[i].a_access_mask;
+		aceptr->z_type = acep[i].a_type;
+		aceptr->z_flags = acep[i].a_flags;
+		aceptr->z_fuid = acep[i].a_who;
+		/*
+		 * Make sure ACE is valid
+		 */
+		if (zfs_ace_valid(obj_mode, aclp, aceptr->z_type,
+		    aceptr->z_flags) != B_TRUE)
+			return (SET_ERROR(EINVAL));
+	}
+	*size = (caddr_t)aceptr - (caddr_t)z_acl;
+	return (0);
+}
+
+/*
+ * convert old ACL format to new
+ */
+void
+zfs_acl_xform(znode_t *zp, zfs_acl_t *aclp, cred_t *cr)
+{
+	zfs_oldace_t *oldaclp;
+	int i;
+	uint16_t type, iflags;
+	uint32_t access_mask;
+	uint64_t who;
+	void *cookie = NULL;
+	zfs_acl_node_t *newaclnode;
+
+	ASSERT(aclp->z_version == ZFS_ACL_VERSION_INITIAL);
+	/*
+	 * First create the ACE in a contiguous piece of memory
+	 * for zfs_copy_ace_2_fuid().
+	 *
+	 * We only convert an ACL once, so this won't happen
+	 * everytime.
+	 */
+	oldaclp = kmem_alloc(sizeof (zfs_oldace_t) * aclp->z_acl_count,
+	    KM_SLEEP);
+	i = 0;
+	while ((cookie = zfs_acl_next_ace(aclp, cookie, &who,
+	    &access_mask, &iflags, &type))) {
+		oldaclp[i].z_flags = iflags;
+		oldaclp[i].z_type = type;
+		oldaclp[i].z_fuid = who;
+		oldaclp[i++].z_access_mask = access_mask;
+	}
+
+	newaclnode = zfs_acl_node_alloc(aclp->z_acl_count *
+	    sizeof (zfs_object_ace_t));
+	aclp->z_ops = &zfs_acl_fuid_ops;
+	VERIFY(zfs_copy_ace_2_fuid(ZTOZSB(zp), ZTOI(zp)->i_mode,
+	    aclp, oldaclp, newaclnode->z_acldata, aclp->z_acl_count,
+	    &newaclnode->z_size, NULL, cr) == 0);
+	newaclnode->z_ace_count = aclp->z_acl_count;
+	aclp->z_version = ZFS_ACL_VERSION;
+	kmem_free(oldaclp, aclp->z_acl_count * sizeof (zfs_oldace_t));
+
+	/*
+	 * Release all previous ACL nodes
+	 */
+
+	zfs_acl_release_nodes(aclp);
+
+	list_insert_head(&aclp->z_acl, newaclnode);
+
+	aclp->z_acl_bytes = newaclnode->z_size;
+	aclp->z_acl_count = newaclnode->z_ace_count;
+
+}
+
+/*
+ * Convert unix access mask to v4 access mask
+ */
+static uint32_t
+zfs_unix_to_v4(uint32_t access_mask)
+{
+	uint32_t new_mask = 0;
+
+	if (access_mask & S_IXOTH)
+		new_mask |= ACE_EXECUTE;
+	if (access_mask & S_IWOTH)
+		new_mask |= ACE_WRITE_DATA;
+	if (access_mask & S_IROTH)
+		new_mask |= ACE_READ_DATA;
+	return (new_mask);
+}
+
+static void
+zfs_set_ace(zfs_acl_t *aclp, void *acep, uint32_t access_mask,
+    uint16_t access_type, uint64_t fuid, uint16_t entry_type)
+{
+	uint16_t type = entry_type & ACE_TYPE_FLAGS;
+
+	aclp->z_ops->ace_mask_set(acep, access_mask);
+	aclp->z_ops->ace_type_set(acep, access_type);
+	aclp->z_ops->ace_flags_set(acep, entry_type);
+	if ((type != ACE_OWNER && type != OWNING_GROUP &&
+	    type != ACE_EVERYONE))
+		aclp->z_ops->ace_who_set(acep, fuid);
+}
+
+/*
+ * Determine mode of file based on ACL.
+ * Also, create FUIDs for any User/Group ACEs
+ */
+uint64_t
+zfs_mode_compute(uint64_t fmode, zfs_acl_t *aclp,
+    uint64_t *pflags, uint64_t fuid, uint64_t fgid)
+{
+	int		entry_type;
+	mode_t		mode;
+	mode_t		seen = 0;
+	zfs_ace_hdr_t 	*acep = NULL;
+	uint64_t	who;
+	uint16_t	iflags, type;
+	uint32_t	access_mask;
+	boolean_t	an_exec_denied = B_FALSE;
+
+	mode = (fmode & (S_IFMT | S_ISUID | S_ISGID | S_ISVTX));
+
+	while ((acep = zfs_acl_next_ace(aclp, acep, &who,
+	    &access_mask, &iflags, &type))) {
+
+		if (!zfs_acl_valid_ace_type(type, iflags))
+			continue;
+
+		entry_type = (iflags & ACE_TYPE_FLAGS);
+
+		/*
+		 * Skip over owner@, group@ or everyone@ inherit only ACEs
+		 */
+		if ((iflags & ACE_INHERIT_ONLY_ACE) &&
+		    (entry_type == ACE_OWNER || entry_type == ACE_EVERYONE ||
+		    entry_type == OWNING_GROUP))
+			continue;
+
+		if (entry_type == ACE_OWNER || (entry_type == 0 &&
+		    who == fuid)) {
+			if ((access_mask & ACE_READ_DATA) &&
+			    (!(seen & S_IRUSR))) {
+				seen |= S_IRUSR;
+				if (type == ALLOW) {
+					mode |= S_IRUSR;
+				}
+			}
+			if ((access_mask & ACE_WRITE_DATA) &&
+			    (!(seen & S_IWUSR))) {
+				seen |= S_IWUSR;
+				if (type == ALLOW) {
+					mode |= S_IWUSR;
+				}
+			}
+			if ((access_mask & ACE_EXECUTE) &&
+			    (!(seen & S_IXUSR))) {
+				seen |= S_IXUSR;
+				if (type == ALLOW) {
+					mode |= S_IXUSR;
+				}
+			}
+		} else if (entry_type == OWNING_GROUP ||
+		    (entry_type == ACE_IDENTIFIER_GROUP && who == fgid)) {
+			if ((access_mask & ACE_READ_DATA) &&
+			    (!(seen & S_IRGRP))) {
+				seen |= S_IRGRP;
+				if (type == ALLOW) {
+					mode |= S_IRGRP;
+				}
+			}
+			if ((access_mask & ACE_WRITE_DATA) &&
+			    (!(seen & S_IWGRP))) {
+				seen |= S_IWGRP;
+				if (type == ALLOW) {
+					mode |= S_IWGRP;
+				}
+			}
+			if ((access_mask & ACE_EXECUTE) &&
+			    (!(seen & S_IXGRP))) {
+				seen |= S_IXGRP;
+				if (type == ALLOW) {
+					mode |= S_IXGRP;
+				}
+			}
+		} else if (entry_type == ACE_EVERYONE) {
+			if ((access_mask & ACE_READ_DATA)) {
+				if (!(seen & S_IRUSR)) {
+					seen |= S_IRUSR;
+					if (type == ALLOW) {
+						mode |= S_IRUSR;
+					}
+				}
+				if (!(seen & S_IRGRP)) {
+					seen |= S_IRGRP;
+					if (type == ALLOW) {
+						mode |= S_IRGRP;
+					}
+				}
+				if (!(seen & S_IROTH)) {
+					seen |= S_IROTH;
+					if (type == ALLOW) {
+						mode |= S_IROTH;
+					}
+				}
+			}
+			if ((access_mask & ACE_WRITE_DATA)) {
+				if (!(seen & S_IWUSR)) {
+					seen |= S_IWUSR;
+					if (type == ALLOW) {
+						mode |= S_IWUSR;
+					}
+				}
+				if (!(seen & S_IWGRP)) {
+					seen |= S_IWGRP;
+					if (type == ALLOW) {
+						mode |= S_IWGRP;
+					}
+				}
+				if (!(seen & S_IWOTH)) {
+					seen |= S_IWOTH;
+					if (type == ALLOW) {
+						mode |= S_IWOTH;
+					}
+				}
+			}
+			if ((access_mask & ACE_EXECUTE)) {
+				if (!(seen & S_IXUSR)) {
+					seen |= S_IXUSR;
+					if (type == ALLOW) {
+						mode |= S_IXUSR;
+					}
+				}
+				if (!(seen & S_IXGRP)) {
+					seen |= S_IXGRP;
+					if (type == ALLOW) {
+						mode |= S_IXGRP;
+					}
+				}
+				if (!(seen & S_IXOTH)) {
+					seen |= S_IXOTH;
+					if (type == ALLOW) {
+						mode |= S_IXOTH;
+					}
+				}
+			}
+		} else {
+			/*
+			 * Only care if this IDENTIFIER_GROUP or
+			 * USER ACE denies execute access to someone,
+			 * mode is not affected
+			 */
+			if ((access_mask & ACE_EXECUTE) && type == DENY)
+				an_exec_denied = B_TRUE;
+		}
+	}
+
+	/*
+	 * Failure to allow is effectively a deny, so execute permission
+	 * is denied if it was never mentioned or if we explicitly
+	 * weren't allowed it.
+	 */
+	if (!an_exec_denied &&
+	    ((seen & ALL_MODE_EXECS) != ALL_MODE_EXECS ||
+	    (mode & ALL_MODE_EXECS) != ALL_MODE_EXECS))
+		an_exec_denied = B_TRUE;
+
+	if (an_exec_denied)
+		*pflags &= ~ZFS_NO_EXECS_DENIED;
+	else
+		*pflags |= ZFS_NO_EXECS_DENIED;
+
+	return (mode);
+}
+
+/*
+ * Read an external acl object.  If the intent is to modify, always
+ * create a new acl and leave any cached acl in place.
+ */
+static int
+zfs_acl_node_read(znode_t *zp, boolean_t have_lock, zfs_acl_t **aclpp,
+    boolean_t will_modify)
+{
+	zfs_acl_t	*aclp;
+	int		aclsize = 0;
+	int		acl_count = 0;
+	zfs_acl_node_t	*aclnode;
+	zfs_acl_phys_t	znode_acl;
+	int		version;
+	int		error;
+	boolean_t	drop_lock = B_FALSE;
+
+	ASSERT(MUTEX_HELD(&zp->z_acl_lock));
+
+	if (zp->z_acl_cached && !will_modify) {
+		*aclpp = zp->z_acl_cached;
+		return (0);
+	}
+
+	/*
+	 * close race where znode could be upgrade while trying to
+	 * read the znode attributes.
+	 *
+	 * But this could only happen if the file isn't already an SA
+	 * znode
+	 */
+	if (!zp->z_is_sa && !have_lock) {
+		mutex_enter(&zp->z_lock);
+		drop_lock = B_TRUE;
+	}
+	version = zfs_znode_acl_version(zp);
+
+	if ((error = zfs_acl_znode_info(zp, &aclsize,
+	    &acl_count, &znode_acl)) != 0) {
+		goto done;
+	}
+
+	aclp = zfs_acl_alloc(version);
+
+	aclp->z_acl_count = acl_count;
+	aclp->z_acl_bytes = aclsize;
+
+	aclnode = zfs_acl_node_alloc(aclsize);
+	aclnode->z_ace_count = aclp->z_acl_count;
+	aclnode->z_size = aclsize;
+
+	if (!zp->z_is_sa) {
+		if (znode_acl.z_acl_extern_obj) {
+			error = dmu_read(ZTOZSB(zp)->z_os,
+			    znode_acl.z_acl_extern_obj, 0, aclnode->z_size,
+			    aclnode->z_acldata, DMU_READ_PREFETCH);
+		} else {
+			bcopy(znode_acl.z_ace_data, aclnode->z_acldata,
+			    aclnode->z_size);
+		}
+	} else {
+		error = sa_lookup(zp->z_sa_hdl, SA_ZPL_DACL_ACES(ZTOZSB(zp)),
+		    aclnode->z_acldata, aclnode->z_size);
+	}
+
+	if (error != 0) {
+		zfs_acl_free(aclp);
+		zfs_acl_node_free(aclnode);
+		/* convert checksum errors into IO errors */
+		if (error == ECKSUM)
+			error = SET_ERROR(EIO);
+		goto done;
+	}
+
+	list_insert_head(&aclp->z_acl, aclnode);
+
+	*aclpp = aclp;
+	if (!will_modify)
+		zp->z_acl_cached = aclp;
+done:
+	if (drop_lock)
+		mutex_exit(&zp->z_lock);
+	return (error);
+}
+
+/*ARGSUSED*/
+void
+zfs_acl_data_locator(void **dataptr, uint32_t *length, uint32_t buflen,
+    boolean_t start, void *userdata)
+{
+	zfs_acl_locator_cb_t *cb = (zfs_acl_locator_cb_t *)userdata;
+
+	if (start) {
+		cb->cb_acl_node = list_head(&cb->cb_aclp->z_acl);
+	} else {
+		cb->cb_acl_node = list_next(&cb->cb_aclp->z_acl,
+		    cb->cb_acl_node);
+	}
+	*dataptr = cb->cb_acl_node->z_acldata;
+	*length = cb->cb_acl_node->z_size;
+}
+
+int
+zfs_acl_chown_setattr(znode_t *zp)
+{
+	int error;
+	zfs_acl_t *aclp;
+
+	if (ZTOZSB(zp)->z_acl_type == ZFS_ACLTYPE_POSIXACL)
+		return (0);
+
+	ASSERT(MUTEX_HELD(&zp->z_lock));
+	ASSERT(MUTEX_HELD(&zp->z_acl_lock));
+
+	error = zfs_acl_node_read(zp, B_TRUE, &aclp, B_FALSE);
+	if (error == 0 && aclp->z_acl_count > 0)
+		zp->z_mode = zfs_mode_compute(zp->z_mode, aclp,
+		    &zp->z_pflags, zp->z_uid, zp->z_gid);
+
+	/*
+	 * Some ZFS implementations (ZEVO) create neither a ZNODE_ACL
+	 * nor a DACL_ACES SA in which case ENOENT is returned from
+	 * zfs_acl_node_read() when the SA can't be located.
+	 * Allow chown/chgrp to succeed in these cases rather than
+	 * returning an error that makes no sense in the context of
+	 * the caller.
+	 */
+	if (error == ENOENT)
+		return (0);
+
+	return (error);
+}
+
+static void
+acl_trivial_access_masks(mode_t mode, uint32_t *allow0, uint32_t *deny1,
+    uint32_t *deny2, uint32_t *owner, uint32_t *group, uint32_t *everyone)
+{
+	*deny1 = *deny2 = *allow0 = *group = 0;
+
+	if (!(mode & S_IRUSR) && (mode & (S_IRGRP|S_IROTH)))
+		*deny1 |= ACE_READ_DATA;
+	if (!(mode & S_IWUSR) && (mode & (S_IWGRP|S_IWOTH)))
+		*deny1 |= ACE_WRITE_DATA;
+	if (!(mode & S_IXUSR) && (mode & (S_IXGRP|S_IXOTH)))
+		*deny1 |= ACE_EXECUTE;
+
+	if (!(mode & S_IRGRP) && (mode & S_IROTH))
+		*deny2 = ACE_READ_DATA;
+	if (!(mode & S_IWGRP) && (mode & S_IWOTH))
+		*deny2 |= ACE_WRITE_DATA;
+	if (!(mode & S_IXGRP) && (mode & S_IXOTH))
+		*deny2 |= ACE_EXECUTE;
+
+	if ((mode & S_IRUSR) && (!(mode & S_IRGRP) && (mode & S_IROTH)))
+		*allow0 |= ACE_READ_DATA;
+	if ((mode & S_IWUSR) && (!(mode & S_IWGRP) && (mode & S_IWOTH)))
+		*allow0 |= ACE_WRITE_DATA;
+	if ((mode & S_IXUSR) && (!(mode & S_IXGRP) && (mode & S_IXOTH)))
+		*allow0 |= ACE_EXECUTE;
+
+	*owner = ACE_WRITE_ATTRIBUTES|ACE_WRITE_OWNER|ACE_WRITE_ACL|
+	    ACE_WRITE_NAMED_ATTRS|ACE_READ_ACL|ACE_READ_ATTRIBUTES|
+	    ACE_READ_NAMED_ATTRS|ACE_SYNCHRONIZE;
+	if (mode & S_IRUSR)
+		*owner |= ACE_READ_DATA;
+	if (mode & S_IWUSR)
+		*owner |= ACE_WRITE_DATA|ACE_APPEND_DATA;
+	if (mode & S_IXUSR)
+		*owner |= ACE_EXECUTE;
+
+	*group = ACE_READ_ACL|ACE_READ_ATTRIBUTES| ACE_READ_NAMED_ATTRS|
+	    ACE_SYNCHRONIZE;
+	if (mode & S_IRGRP)
+		*group |= ACE_READ_DATA;
+	if (mode & S_IWGRP)
+		*group |= ACE_WRITE_DATA|ACE_APPEND_DATA;
+	if (mode & S_IXGRP)
+		*group |= ACE_EXECUTE;
+
+	*everyone = ACE_READ_ACL|ACE_READ_ATTRIBUTES| ACE_READ_NAMED_ATTRS|
+	    ACE_SYNCHRONIZE;
+	if (mode & S_IROTH)
+		*everyone |= ACE_READ_DATA;
+	if (mode & S_IWOTH)
+		*everyone |= ACE_WRITE_DATA|ACE_APPEND_DATA;
+	if (mode & S_IXOTH)
+		*everyone |= ACE_EXECUTE;
+}
+
+/*
+ * ace_trivial:
+ * determine whether an ace_t acl is trivial
+ *
+ * Trivialness implies that the acl is composed of only
+ * owner, group, everyone entries.  ACL can't
+ * have read_acl denied, and write_owner/write_acl/write_attributes
+ * can only be owner@ entry.
+ */
+static int
+ace_trivial_common(void *acep, int aclcnt,
+    uint64_t (*walk)(void *, uint64_t, int aclcnt,
+    uint16_t *, uint16_t *, uint32_t *))
+{
+	uint16_t flags;
+	uint32_t mask;
+	uint16_t type;
+	uint64_t cookie = 0;
+
+	while ((cookie = walk(acep, cookie, aclcnt, &flags, &type, &mask))) {
+		switch (flags & ACE_TYPE_FLAGS) {
+		case ACE_OWNER:
+		case ACE_GROUP|ACE_IDENTIFIER_GROUP:
+		case ACE_EVERYONE:
+			break;
+		default:
+			return (1);
+		}
+
+		if (flags & (ACE_FILE_INHERIT_ACE|
+		    ACE_DIRECTORY_INHERIT_ACE|ACE_NO_PROPAGATE_INHERIT_ACE|
+		    ACE_INHERIT_ONLY_ACE))
+			return (1);
+
+		/*
+		 * Special check for some special bits
+		 *
+		 * Don't allow anybody to deny reading basic
+		 * attributes or a files ACL.
+		 */
+		if ((mask & (ACE_READ_ACL|ACE_READ_ATTRIBUTES)) &&
+		    (type == ACE_ACCESS_DENIED_ACE_TYPE))
+			return (1);
+
+		/*
+		 * Delete permissions are never set by default
+		 */
+		if (mask & (ACE_DELETE|ACE_DELETE_CHILD))
+			return (1);
+		/*
+		 * only allow owner@ to have
+		 * write_acl/write_owner/write_attributes/write_xattr/
+		 */
+		if (type == ACE_ACCESS_ALLOWED_ACE_TYPE &&
+		    (!(flags & ACE_OWNER) && (mask &
+		    (ACE_WRITE_OWNER|ACE_WRITE_ACL| ACE_WRITE_ATTRIBUTES|
+		    ACE_WRITE_NAMED_ATTRS))))
+			return (1);
+
+	}
+
+	return (0);
+}
+
+/*
+ * common code for setting ACLs.
+ *
+ * This function is called from zfs_mode_update, zfs_perm_init, and zfs_setacl.
+ * zfs_setacl passes a non-NULL inherit pointer (ihp) to indicate that it's
+ * already checked the acl and knows whether to inherit.
+ */
+int
+zfs_aclset_common(znode_t *zp, zfs_acl_t *aclp, cred_t *cr, dmu_tx_t *tx)
+{
+	int			error;
+	zfs_sb_t		*zsb = ZTOZSB(zp);
+	dmu_object_type_t	otype;
+	zfs_acl_locator_cb_t	locate = { 0 };
+	uint64_t		mode;
+	sa_bulk_attr_t		bulk[5];
+	uint64_t		ctime[2];
+	int			count = 0;
+
+	mode = zp->z_mode;
+
+	mode = zfs_mode_compute(mode, aclp, &zp->z_pflags,
+	    zp->z_uid, zp->z_gid);
+
+	zp->z_mode = mode;
+	SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_MODE(zsb), NULL,
+	    &mode, sizeof (mode));
+	SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_FLAGS(zsb), NULL,
+	    &zp->z_pflags, sizeof (zp->z_pflags));
+	SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_CTIME(zsb), NULL,
+	    &ctime, sizeof (ctime));
+
+	if (zp->z_acl_cached) {
+		zfs_acl_free(zp->z_acl_cached);
+		zp->z_acl_cached = NULL;
+	}
+
+	/*
+	 * Upgrade needed?
+	 */
+	if (!zsb->z_use_fuids) {
+		otype = DMU_OT_OLDACL;
+	} else {
+		if ((aclp->z_version == ZFS_ACL_VERSION_INITIAL) &&
+		    (zsb->z_version >= ZPL_VERSION_FUID))
+			zfs_acl_xform(zp, aclp, cr);
+		ASSERT(aclp->z_version >= ZFS_ACL_VERSION_FUID);
+		otype = DMU_OT_ACL;
+	}
+
+	/*
+	 * Arrgh, we have to handle old on disk format
+	 * as well as newer (preferred) SA format.
+	 */
+
+	if (zp->z_is_sa) { /* the easy case, just update the ACL attribute */
+		locate.cb_aclp = aclp;
+		SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_DACL_ACES(zsb),
+		    zfs_acl_data_locator, &locate, aclp->z_acl_bytes);
+		SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_DACL_COUNT(zsb),
+		    NULL, &aclp->z_acl_count, sizeof (uint64_t));
+	} else { /* Painful legacy way */
+		zfs_acl_node_t *aclnode;
+		uint64_t off = 0;
+		zfs_acl_phys_t acl_phys;
+		uint64_t aoid;
+
+		if ((error = sa_lookup(zp->z_sa_hdl, SA_ZPL_ZNODE_ACL(zsb),
+		    &acl_phys, sizeof (acl_phys))) != 0)
+			return (error);
+
+		aoid = acl_phys.z_acl_extern_obj;
+
+		if (aclp->z_acl_bytes > ZFS_ACE_SPACE) {
+			/*
+			 * If ACL was previously external and we are now
+			 * converting to new ACL format then release old
+			 * ACL object and create a new one.
+			 */
+			if (aoid &&
+			    aclp->z_version != acl_phys.z_acl_version) {
+				error = dmu_object_free(zsb->z_os, aoid, tx);
+				if (error)
+					return (error);
+				aoid = 0;
+			}
+			if (aoid == 0) {
+				aoid = dmu_object_alloc(zsb->z_os,
+				    otype, aclp->z_acl_bytes,
+				    otype == DMU_OT_ACL ?
+				    DMU_OT_SYSACL : DMU_OT_NONE,
+				    otype == DMU_OT_ACL ?
+				    DN_MAX_BONUSLEN : 0, tx);
+			} else {
+				(void) dmu_object_set_blocksize(zsb->z_os,
+				    aoid, aclp->z_acl_bytes, 0, tx);
+			}
+			acl_phys.z_acl_extern_obj = aoid;
+			for (aclnode = list_head(&aclp->z_acl); aclnode;
+			    aclnode = list_next(&aclp->z_acl, aclnode)) {
+				if (aclnode->z_ace_count == 0)
+					continue;
+				dmu_write(zsb->z_os, aoid, off,
+				    aclnode->z_size, aclnode->z_acldata, tx);
+				off += aclnode->z_size;
+			}
+		} else {
+			void *start = acl_phys.z_ace_data;
+			/*
+			 * Migrating back embedded?
+			 */
+			if (acl_phys.z_acl_extern_obj) {
+				error = dmu_object_free(zsb->z_os,
+				    acl_phys.z_acl_extern_obj, tx);
+				if (error)
+					return (error);
+				acl_phys.z_acl_extern_obj = 0;
+			}
+
+			for (aclnode = list_head(&aclp->z_acl); aclnode;
+			    aclnode = list_next(&aclp->z_acl, aclnode)) {
+				if (aclnode->z_ace_count == 0)
+					continue;
+				bcopy(aclnode->z_acldata, start,
+				    aclnode->z_size);
+				start = (caddr_t)start + aclnode->z_size;
+			}
+		}
+		/*
+		 * If Old version then swap count/bytes to match old
+		 * layout of znode_acl_phys_t.
+		 */
+		if (aclp->z_version == ZFS_ACL_VERSION_INITIAL) {
+			acl_phys.z_acl_size = aclp->z_acl_count;
+			acl_phys.z_acl_count = aclp->z_acl_bytes;
+		} else {
+			acl_phys.z_acl_size = aclp->z_acl_bytes;
+			acl_phys.z_acl_count = aclp->z_acl_count;
+		}
+		acl_phys.z_acl_version = aclp->z_version;
+
+		SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_ZNODE_ACL(zsb), NULL,
+		    &acl_phys, sizeof (acl_phys));
+	}
+
+	/*
+	 * Replace ACL wide bits, but first clear them.
+	 */
+	zp->z_pflags &= ~ZFS_ACL_WIDE_FLAGS;
+
+	zp->z_pflags |= aclp->z_hints;
+
+	if (ace_trivial_common(aclp, 0, zfs_ace_walk) == 0)
+		zp->z_pflags |= ZFS_ACL_TRIVIAL;
+
+	zfs_tstamp_update_setup(zp, STATE_CHANGED, NULL, ctime, B_TRUE);
+	return (sa_bulk_update(zp->z_sa_hdl, bulk, count, tx));
+}
+
+static void
+zfs_acl_chmod(zfs_sb_t *zsb, uint64_t mode, zfs_acl_t *aclp)
+{
+	void		*acep = NULL;
+	uint64_t	who;
+	int		new_count, new_bytes;
+	int		ace_size;
+	int		entry_type;
+	uint16_t	iflags, type;
+	uint32_t	access_mask;
+	zfs_acl_node_t	*newnode;
+	size_t		abstract_size = aclp->z_ops->ace_abstract_size();
+	void		*zacep;
+	uint32_t	owner, group, everyone;
+	uint32_t	deny1, deny2, allow0;
+
+	new_count = new_bytes = 0;
+
+	acl_trivial_access_masks((mode_t)mode, &allow0, &deny1, &deny2,
+	    &owner, &group, &everyone);
+
+	newnode = zfs_acl_node_alloc((abstract_size * 6) + aclp->z_acl_bytes);
+
+	zacep = newnode->z_acldata;
+	if (allow0) {
+		zfs_set_ace(aclp, zacep, allow0, ALLOW, -1, ACE_OWNER);
+		zacep = (void *)((uintptr_t)zacep + abstract_size);
+		new_count++;
+		new_bytes += abstract_size;
+	}
+	if (deny1) {
+		zfs_set_ace(aclp, zacep, deny1, DENY, -1, ACE_OWNER);
+		zacep = (void *)((uintptr_t)zacep + abstract_size);
+		new_count++;
+		new_bytes += abstract_size;
+	}
+	if (deny2) {
+		zfs_set_ace(aclp, zacep, deny2, DENY, -1, OWNING_GROUP);
+		zacep = (void *)((uintptr_t)zacep + abstract_size);
+		new_count++;
+		new_bytes += abstract_size;
+	}
+
+	while ((acep = zfs_acl_next_ace(aclp, acep, &who, &access_mask,
+	    &iflags, &type))) {
+		uint16_t inherit_flags;
+
+		entry_type = (iflags & ACE_TYPE_FLAGS);
+		inherit_flags = (iflags & ALL_INHERIT);
+
+		if ((entry_type == ACE_OWNER || entry_type == ACE_EVERYONE ||
+		    (entry_type == OWNING_GROUP)) &&
+		    ((inherit_flags & ACE_INHERIT_ONLY_ACE) == 0)) {
+			continue;
+		}
+
+		if ((type != ALLOW && type != DENY) ||
+		    (inherit_flags & ACE_INHERIT_ONLY_ACE)) {
+			if (inherit_flags)
+				aclp->z_hints |= ZFS_INHERIT_ACE;
+			switch (type) {
+			case ACE_ACCESS_ALLOWED_OBJECT_ACE_TYPE:
+			case ACE_ACCESS_DENIED_OBJECT_ACE_TYPE:
+			case ACE_SYSTEM_AUDIT_OBJECT_ACE_TYPE:
+			case ACE_SYSTEM_ALARM_OBJECT_ACE_TYPE:
+				aclp->z_hints |= ZFS_ACL_OBJ_ACE;
+				break;
+			}
+		} else {
+
+			/*
+			 * Limit permissions to be no greater than
+			 * group permissions
+			 */
+			if (zsb->z_acl_inherit == ZFS_ACL_RESTRICTED) {
+				if (!(mode & S_IRGRP))
+					access_mask &= ~ACE_READ_DATA;
+				if (!(mode & S_IWGRP))
+					access_mask &=
+					    ~(ACE_WRITE_DATA|ACE_APPEND_DATA);
+				if (!(mode & S_IXGRP))
+					access_mask &= ~ACE_EXECUTE;
+				access_mask &=
+				    ~(ACE_WRITE_OWNER|ACE_WRITE_ACL|
+				    ACE_WRITE_ATTRIBUTES|ACE_WRITE_NAMED_ATTRS);
+			}
+		}
+		zfs_set_ace(aclp, zacep, access_mask, type, who, iflags);
+		ace_size = aclp->z_ops->ace_size(acep);
+		zacep = (void *)((uintptr_t)zacep + ace_size);
+		new_count++;
+		new_bytes += ace_size;
+	}
+	zfs_set_ace(aclp, zacep, owner, 0, -1, ACE_OWNER);
+	zacep = (void *)((uintptr_t)zacep + abstract_size);
+	zfs_set_ace(aclp, zacep, group, 0, -1, OWNING_GROUP);
+	zacep = (void *)((uintptr_t)zacep + abstract_size);
+	zfs_set_ace(aclp, zacep, everyone, 0, -1, ACE_EVERYONE);
+
+	new_count += 3;
+	new_bytes += abstract_size * 3;
+	zfs_acl_release_nodes(aclp);
+	aclp->z_acl_count = new_count;
+	aclp->z_acl_bytes = new_bytes;
+	newnode->z_ace_count = new_count;
+	newnode->z_size = new_bytes;
+	list_insert_tail(&aclp->z_acl, newnode);
+}
+
+void
+zfs_acl_chmod_setattr(znode_t *zp, zfs_acl_t **aclp, uint64_t mode)
+{
+	mutex_enter(&zp->z_acl_lock);
+	mutex_enter(&zp->z_lock);
+	*aclp = zfs_acl_alloc(zfs_acl_version_zp(zp));
+	(*aclp)->z_hints = zp->z_pflags & V4_ACL_WIDE_FLAGS;
+	zfs_acl_chmod(ZTOZSB(zp), mode, *aclp);
+	mutex_exit(&zp->z_lock);
+	mutex_exit(&zp->z_acl_lock);
+	ASSERT(*aclp);
+}
+
+/*
+ * strip off write_owner and write_acl
+ */
+static void
+zfs_restricted_update(zfs_sb_t *zsb, zfs_acl_t *aclp, void *acep)
+{
+	uint32_t mask = aclp->z_ops->ace_mask_get(acep);
+
+	if ((zsb->z_acl_inherit == ZFS_ACL_RESTRICTED) &&
+	    (aclp->z_ops->ace_type_get(acep) == ALLOW)) {
+		mask &= ~RESTRICTED_CLEAR;
+		aclp->z_ops->ace_mask_set(acep, mask);
+	}
+}
+
+/*
+ * Should ACE be inherited?
+ */
+static int
+zfs_ace_can_use(umode_t obj_mode, uint16_t acep_flags)
+{
+	int	iflags = (acep_flags & 0xf);
+
+	if (S_ISDIR(obj_mode) && (iflags & ACE_DIRECTORY_INHERIT_ACE))
+		return (1);
+	else if (iflags & ACE_FILE_INHERIT_ACE)
+		return (!(S_ISDIR(obj_mode) &&
+		    (iflags & ACE_NO_PROPAGATE_INHERIT_ACE)));
+	return (0);
+}
+
+/*
+ * inherit inheritable ACEs from parent
+ */
+static zfs_acl_t *
+zfs_acl_inherit(zfs_sb_t *zsb, umode_t obj_mode, zfs_acl_t *paclp,
+    uint64_t mode, boolean_t *need_chmod)
+{
+	void		*pacep;
+	void		*acep;
+	zfs_acl_node_t  *aclnode;
+	zfs_acl_t	*aclp = NULL;
+	uint64_t	who;
+	uint32_t	access_mask;
+	uint16_t	iflags, newflags, type;
+	size_t		ace_size;
+	void		*data1, *data2;
+	size_t		data1sz, data2sz;
+	boolean_t	vdir = S_ISDIR(obj_mode);
+	boolean_t	vreg = S_ISREG(obj_mode);
+	boolean_t	passthrough, passthrough_x, noallow;
+
+	passthrough_x =
+	    zsb->z_acl_inherit == ZFS_ACL_PASSTHROUGH_X;
+	passthrough = passthrough_x ||
+	    zsb->z_acl_inherit == ZFS_ACL_PASSTHROUGH;
+	noallow =
+	    zsb->z_acl_inherit == ZFS_ACL_NOALLOW;
+
+	*need_chmod = B_TRUE;
+	pacep = NULL;
+	aclp = zfs_acl_alloc(paclp->z_version);
+	if (zsb->z_acl_inherit == ZFS_ACL_DISCARD || S_ISLNK(obj_mode))
+		return (aclp);
+	while ((pacep = zfs_acl_next_ace(paclp, pacep, &who,
+	    &access_mask, &iflags, &type))) {
+
+		/*
+		 * don't inherit bogus ACEs
+		 */
+		if (!zfs_acl_valid_ace_type(type, iflags))
+			continue;
+
+		if (noallow && type == ALLOW)
+			continue;
+
+		ace_size = aclp->z_ops->ace_size(pacep);
+
+		if (!zfs_ace_can_use(obj_mode, iflags))
+			continue;
+
+		/*
+		 * If owner@, group@, or everyone@ inheritable
+		 * then zfs_acl_chmod() isn't needed.
+		 */
+		if (passthrough &&
+		    ((iflags & (ACE_OWNER|ACE_EVERYONE)) ||
+		    ((iflags & OWNING_GROUP) ==
+		    OWNING_GROUP)) && (vreg || (vdir && (iflags &
+		    ACE_DIRECTORY_INHERIT_ACE)))) {
+			*need_chmod = B_FALSE;
+		}
+
+		if (!vdir && passthrough_x &&
+		    ((mode & (S_IXUSR | S_IXGRP | S_IXOTH)) == 0)) {
+			access_mask &= ~ACE_EXECUTE;
+		}
+
+		aclnode = zfs_acl_node_alloc(ace_size);
+		list_insert_tail(&aclp->z_acl, aclnode);
+		acep = aclnode->z_acldata;
+
+		zfs_set_ace(aclp, acep, access_mask, type,
+		    who, iflags|ACE_INHERITED_ACE);
+
+		/*
+		 * Copy special opaque data if any
+		 */
+		if ((data1sz = paclp->z_ops->ace_data(pacep, &data1)) != 0) {
+			VERIFY((data2sz = aclp->z_ops->ace_data(acep,
+			    &data2)) == data1sz);
+			bcopy(data1, data2, data2sz);
+		}
+
+		aclp->z_acl_count++;
+		aclnode->z_ace_count++;
+		aclp->z_acl_bytes += aclnode->z_size;
+		newflags = aclp->z_ops->ace_flags_get(acep);
+
+		if (vdir)
+			aclp->z_hints |= ZFS_INHERIT_ACE;
+
+		if ((iflags & ACE_NO_PROPAGATE_INHERIT_ACE) || !vdir) {
+			newflags &= ~ALL_INHERIT;
+			aclp->z_ops->ace_flags_set(acep,
+			    newflags|ACE_INHERITED_ACE);
+			zfs_restricted_update(zsb, aclp, acep);
+			continue;
+		}
+
+		ASSERT(vdir);
+
+		/*
+		 * If only FILE_INHERIT is set then turn on
+		 * inherit_only
+		 */
+		if ((iflags & (ACE_FILE_INHERIT_ACE |
+		    ACE_DIRECTORY_INHERIT_ACE)) == ACE_FILE_INHERIT_ACE) {
+			newflags |= ACE_INHERIT_ONLY_ACE;
+			aclp->z_ops->ace_flags_set(acep,
+			    newflags|ACE_INHERITED_ACE);
+		} else {
+			newflags &= ~ACE_INHERIT_ONLY_ACE;
+			aclp->z_ops->ace_flags_set(acep,
+			    newflags|ACE_INHERITED_ACE);
+		}
+	}
+	return (aclp);
+}
+
+/*
+ * Create file system object initial permissions
+ * including inheritable ACEs.
+ */
+int
+zfs_acl_ids_create(znode_t *dzp, int flag, vattr_t *vap, cred_t *cr,
+    vsecattr_t *vsecp, zfs_acl_ids_t *acl_ids)
+{
+	int		error;
+	zfs_sb_t	*zsb = ZTOZSB(dzp);
+	zfs_acl_t	*paclp;
+#ifdef HAVE_KSID
+	gid_t		gid;
+#endif /* HAVE_KSID */
+	boolean_t	need_chmod = B_TRUE;
+	boolean_t	inherited = B_FALSE;
+
+	bzero(acl_ids, sizeof (zfs_acl_ids_t));
+	acl_ids->z_mode = vap->va_mode;
+
+	if (vsecp)
+		if ((error = zfs_vsec_2_aclp(zsb, vap->va_mode, vsecp,
+		    cr, &acl_ids->z_fuidp, &acl_ids->z_aclp)) != 0)
+			return (error);
+
+	acl_ids->z_fuid = vap->va_uid;
+	acl_ids->z_fgid = vap->va_gid;
+#ifdef HAVE_KSID
+	/*
+	 * Determine uid and gid.
+	 */
+	if ((flag & IS_ROOT_NODE) || zsb->z_replay ||
+	    ((flag & IS_XATTR) && (S_ISDIR(vap->va_mode)))) {
+		acl_ids->z_fuid = zfs_fuid_create(zsb, (uint64_t)vap->va_uid,
+		    cr, ZFS_OWNER, &acl_ids->z_fuidp);
+		acl_ids->z_fgid = zfs_fuid_create(zsb, (uint64_t)vap->va_gid,
+		    cr, ZFS_GROUP, &acl_ids->z_fuidp);
+		gid = vap->va_gid;
+	} else {
+		acl_ids->z_fuid = zfs_fuid_create_cred(zsb, ZFS_OWNER,
+		    cr, &acl_ids->z_fuidp);
+		acl_ids->z_fgid = 0;
+		if (vap->va_mask & AT_GID)  {
+			acl_ids->z_fgid = zfs_fuid_create(zsb,
+			    (uint64_t)vap->va_gid,
+			    cr, ZFS_GROUP, &acl_ids->z_fuidp);
+			gid = vap->va_gid;
+			if (acl_ids->z_fgid != dzp->z_gid &&
+			    !groupmember(vap->va_gid, cr) &&
+			    secpolicy_vnode_create_gid(cr) != 0)
+				acl_ids->z_fgid = 0;
+		}
+		if (acl_ids->z_fgid == 0) {
+			if (dzp->z_mode & S_ISGID) {
+				char		*domain;
+				uint32_t	rid;
+
+				acl_ids->z_fgid = dzp->z_gid;
+				gid = zfs_fuid_map_id(zsb, acl_ids->z_fgid,
+				    cr, ZFS_GROUP);
+
+				if (zsb->z_use_fuids &&
+				    IS_EPHEMERAL(acl_ids->z_fgid)) {
+					domain = zfs_fuid_idx_domain(
+					    &zsb->z_fuid_idx,
+					    FUID_INDEX(acl_ids->z_fgid));
+					rid = FUID_RID(acl_ids->z_fgid);
+					zfs_fuid_node_add(&acl_ids->z_fuidp,
+					    domain, rid,
+					    FUID_INDEX(acl_ids->z_fgid),
+					    acl_ids->z_fgid, ZFS_GROUP);
+				}
+			} else {
+				acl_ids->z_fgid = zfs_fuid_create_cred(zsb,
+				    ZFS_GROUP, cr, &acl_ids->z_fuidp);
+				gid = crgetgid(cr);
+			}
+		}
+	}
+#endif /* HAVE_KSID */
+
+	/*
+	 * If we're creating a directory, and the parent directory has the
+	 * set-GID bit set, set in on the new directory.
+	 * Otherwise, if the user is neither privileged nor a member of the
+	 * file's new group, clear the file's set-GID bit.
+	 */
+
+	if (!(flag & IS_ROOT_NODE) && (dzp->z_mode & S_ISGID) &&
+	    (S_ISDIR(vap->va_mode))) {
+		acl_ids->z_mode |= S_ISGID;
+	} else {
+		if ((acl_ids->z_mode & S_ISGID) &&
+		    secpolicy_vnode_setids_setgids(cr, gid) != 0)
+			acl_ids->z_mode &= ~S_ISGID;
+	}
+
+	if (acl_ids->z_aclp == NULL) {
+		mutex_enter(&dzp->z_acl_lock);
+		mutex_enter(&dzp->z_lock);
+		if (!(flag & IS_ROOT_NODE) && (S_ISDIR(ZTOI(dzp)->i_mode) &&
+		    (dzp->z_pflags & ZFS_INHERIT_ACE)) &&
+		    !(dzp->z_pflags & ZFS_XATTR)) {
+			VERIFY(0 == zfs_acl_node_read(dzp, B_TRUE,
+			    &paclp, B_FALSE));
+			acl_ids->z_aclp = zfs_acl_inherit(zsb,
+			    vap->va_mode, paclp, acl_ids->z_mode, &need_chmod);
+			inherited = B_TRUE;
+		} else {
+			acl_ids->z_aclp =
+			    zfs_acl_alloc(zfs_acl_version_zp(dzp));
+			acl_ids->z_aclp->z_hints |= ZFS_ACL_TRIVIAL;
+		}
+		mutex_exit(&dzp->z_lock);
+		mutex_exit(&dzp->z_acl_lock);
+		if (need_chmod) {
+			acl_ids->z_aclp->z_hints |= S_ISDIR(vap->va_mode) ?
+			    ZFS_ACL_AUTO_INHERIT : 0;
+			zfs_acl_chmod(zsb, acl_ids->z_mode, acl_ids->z_aclp);
+		}
+	}
+
+	if (inherited || vsecp) {
+		acl_ids->z_mode = zfs_mode_compute(acl_ids->z_mode,
+		    acl_ids->z_aclp, &acl_ids->z_aclp->z_hints,
+		    acl_ids->z_fuid, acl_ids->z_fgid);
+		if (ace_trivial_common(acl_ids->z_aclp, 0, zfs_ace_walk) == 0)
+			acl_ids->z_aclp->z_hints |= ZFS_ACL_TRIVIAL;
+	}
+
+	return (0);
+}
+
+/*
+ * Free ACL and fuid_infop, but not the acl_ids structure
+ */
+void
+zfs_acl_ids_free(zfs_acl_ids_t *acl_ids)
+{
+	if (acl_ids->z_aclp)
+		zfs_acl_free(acl_ids->z_aclp);
+	if (acl_ids->z_fuidp)
+		zfs_fuid_info_free(acl_ids->z_fuidp);
+	acl_ids->z_aclp = NULL;
+	acl_ids->z_fuidp = NULL;
+}
+
+boolean_t
+zfs_acl_ids_overquota(zfs_sb_t *zsb, zfs_acl_ids_t *acl_ids)
+{
+	return (zfs_fuid_overquota(zsb, B_FALSE, acl_ids->z_fuid) ||
+	    zfs_fuid_overquota(zsb, B_TRUE, acl_ids->z_fgid));
+}
+
+/*
+ * Retrieve a file's ACL
+ */
+int
+zfs_getacl(znode_t *zp, vsecattr_t *vsecp, boolean_t skipaclchk, cred_t *cr)
+{
+	zfs_acl_t	*aclp;
+	ulong_t		mask;
+	int		error;
+	int 		count = 0;
+	int		largeace = 0;
+
+	mask = vsecp->vsa_mask & (VSA_ACE | VSA_ACECNT |
+	    VSA_ACE_ACLFLAGS | VSA_ACE_ALLTYPES);
+
+	if (mask == 0)
+		return (SET_ERROR(ENOSYS));
+
+	if ((error = zfs_zaccess(zp, ACE_READ_ACL, 0, skipaclchk, cr)))
+		return (error);
+
+	mutex_enter(&zp->z_acl_lock);
+
+	error = zfs_acl_node_read(zp, B_FALSE, &aclp, B_FALSE);
+	if (error != 0) {
+		mutex_exit(&zp->z_acl_lock);
+		return (error);
+	}
+
+	/*
+	 * Scan ACL to determine number of ACEs
+	 */
+	if ((zp->z_pflags & ZFS_ACL_OBJ_ACE) && !(mask & VSA_ACE_ALLTYPES)) {
+		void *zacep = NULL;
+		uint64_t who;
+		uint32_t access_mask;
+		uint16_t type, iflags;
+
+		while ((zacep = zfs_acl_next_ace(aclp, zacep,
+		    &who, &access_mask, &iflags, &type))) {
+			switch (type) {
+			case ACE_ACCESS_ALLOWED_OBJECT_ACE_TYPE:
+			case ACE_ACCESS_DENIED_OBJECT_ACE_TYPE:
+			case ACE_SYSTEM_AUDIT_OBJECT_ACE_TYPE:
+			case ACE_SYSTEM_ALARM_OBJECT_ACE_TYPE:
+				largeace++;
+				continue;
+			default:
+				count++;
+			}
+		}
+		vsecp->vsa_aclcnt = count;
+	} else
+		count = (int)aclp->z_acl_count;
+
+	if (mask & VSA_ACECNT) {
+		vsecp->vsa_aclcnt = count;
+	}
+
+	if (mask & VSA_ACE) {
+		size_t aclsz;
+
+		aclsz = count * sizeof (ace_t) +
+		    sizeof (ace_object_t) * largeace;
+
+		vsecp->vsa_aclentp = kmem_alloc(aclsz, KM_SLEEP);
+		vsecp->vsa_aclentsz = aclsz;
+
+		if (aclp->z_version == ZFS_ACL_VERSION_FUID)
+			zfs_copy_fuid_2_ace(ZTOZSB(zp), aclp, cr,
+			    vsecp->vsa_aclentp, !(mask & VSA_ACE_ALLTYPES));
+		else {
+			zfs_acl_node_t *aclnode;
+			void *start = vsecp->vsa_aclentp;
+
+			for (aclnode = list_head(&aclp->z_acl); aclnode;
+			    aclnode = list_next(&aclp->z_acl, aclnode)) {
+				bcopy(aclnode->z_acldata, start,
+				    aclnode->z_size);
+				start = (caddr_t)start + aclnode->z_size;
+			}
+			ASSERT((caddr_t)start - (caddr_t)vsecp->vsa_aclentp ==
+			    aclp->z_acl_bytes);
+		}
+	}
+	if (mask & VSA_ACE_ACLFLAGS) {
+		vsecp->vsa_aclflags = 0;
+		if (zp->z_pflags & ZFS_ACL_DEFAULTED)
+			vsecp->vsa_aclflags |= ACL_DEFAULTED;
+		if (zp->z_pflags & ZFS_ACL_PROTECTED)
+			vsecp->vsa_aclflags |= ACL_PROTECTED;
+		if (zp->z_pflags & ZFS_ACL_AUTO_INHERIT)
+			vsecp->vsa_aclflags |= ACL_AUTO_INHERIT;
+	}
+
+	mutex_exit(&zp->z_acl_lock);
+
+	return (0);
+}
+
+int
+zfs_vsec_2_aclp(zfs_sb_t *zsb, umode_t obj_mode,
+    vsecattr_t *vsecp, cred_t *cr, zfs_fuid_info_t **fuidp, zfs_acl_t **zaclp)
+{
+	zfs_acl_t *aclp;
+	zfs_acl_node_t *aclnode;
+	int aclcnt = vsecp->vsa_aclcnt;
+	int error;
+
+	if (vsecp->vsa_aclcnt > MAX_ACL_ENTRIES || vsecp->vsa_aclcnt <= 0)
+		return (SET_ERROR(EINVAL));
+
+	aclp = zfs_acl_alloc(zfs_acl_version(zsb->z_version));
+
+	aclp->z_hints = 0;
+	aclnode = zfs_acl_node_alloc(aclcnt * sizeof (zfs_object_ace_t));
+	if (aclp->z_version == ZFS_ACL_VERSION_INITIAL) {
+		if ((error = zfs_copy_ace_2_oldace(obj_mode, aclp,
+		    (ace_t *)vsecp->vsa_aclentp, aclnode->z_acldata,
+		    aclcnt, &aclnode->z_size)) != 0) {
+			zfs_acl_free(aclp);
+			zfs_acl_node_free(aclnode);
+			return (error);
+		}
+	} else {
+		if ((error = zfs_copy_ace_2_fuid(zsb, obj_mode, aclp,
+		    vsecp->vsa_aclentp, aclnode->z_acldata, aclcnt,
+		    &aclnode->z_size, fuidp, cr)) != 0) {
+			zfs_acl_free(aclp);
+			zfs_acl_node_free(aclnode);
+			return (error);
+		}
+	}
+	aclp->z_acl_bytes = aclnode->z_size;
+	aclnode->z_ace_count = aclcnt;
+	aclp->z_acl_count = aclcnt;
+	list_insert_head(&aclp->z_acl, aclnode);
+
+	/*
+	 * If flags are being set then add them to z_hints
+	 */
+	if (vsecp->vsa_mask & VSA_ACE_ACLFLAGS) {
+		if (vsecp->vsa_aclflags & ACL_PROTECTED)
+			aclp->z_hints |= ZFS_ACL_PROTECTED;
+		if (vsecp->vsa_aclflags & ACL_DEFAULTED)
+			aclp->z_hints |= ZFS_ACL_DEFAULTED;
+		if (vsecp->vsa_aclflags & ACL_AUTO_INHERIT)
+			aclp->z_hints |= ZFS_ACL_AUTO_INHERIT;
+	}
+
+	*zaclp = aclp;
+
+	return (0);
+}
+
+/*
+ * Set a file's ACL
+ */
+int
+zfs_setacl(znode_t *zp, vsecattr_t *vsecp, boolean_t skipaclchk, cred_t *cr)
+{
+	zfs_sb_t	*zsb = ZTOZSB(zp);
+	zilog_t		*zilog = zsb->z_log;
+	ulong_t		mask = vsecp->vsa_mask & (VSA_ACE | VSA_ACECNT);
+	dmu_tx_t	*tx;
+	int		error;
+	zfs_acl_t	*aclp;
+	zfs_fuid_info_t	*fuidp = NULL;
+	boolean_t	fuid_dirtied;
+	uint64_t	acl_obj;
+
+	if (mask == 0)
+		return (SET_ERROR(ENOSYS));
+
+	if (zp->z_pflags & ZFS_IMMUTABLE)
+		return (SET_ERROR(EPERM));
+
+	if ((error = zfs_zaccess(zp, ACE_WRITE_ACL, 0, skipaclchk, cr)))
+		return (error);
+
+	error = zfs_vsec_2_aclp(zsb, ZTOI(zp)->i_mode, vsecp, cr, &fuidp,
+	    &aclp);
+	if (error)
+		return (error);
+
+	/*
+	 * If ACL wide flags aren't being set then preserve any
+	 * existing flags.
+	 */
+	if (!(vsecp->vsa_mask & VSA_ACE_ACLFLAGS)) {
+		aclp->z_hints |=
+		    (zp->z_pflags & V4_ACL_WIDE_FLAGS);
+	}
+top:
+	mutex_enter(&zp->z_acl_lock);
+	mutex_enter(&zp->z_lock);
+
+	tx = dmu_tx_create(zsb->z_os);
+
+	dmu_tx_hold_sa(tx, zp->z_sa_hdl, B_TRUE);
+
+	fuid_dirtied = zsb->z_fuid_dirty;
+	if (fuid_dirtied)
+		zfs_fuid_txhold(zsb, tx);
+
+	/*
+	 * If old version and ACL won't fit in bonus and we aren't
+	 * upgrading then take out necessary DMU holds
+	 */
+
+	if ((acl_obj = zfs_external_acl(zp)) != 0) {
+		if (zsb->z_version >= ZPL_VERSION_FUID &&
+		    zfs_znode_acl_version(zp) <= ZFS_ACL_VERSION_INITIAL) {
+			dmu_tx_hold_free(tx, acl_obj, 0,
+			    DMU_OBJECT_END);
+			dmu_tx_hold_write(tx, DMU_NEW_OBJECT, 0,
+			    aclp->z_acl_bytes);
+		} else {
+			dmu_tx_hold_write(tx, acl_obj, 0, aclp->z_acl_bytes);
+		}
+	} else if (!zp->z_is_sa && aclp->z_acl_bytes > ZFS_ACE_SPACE) {
+		dmu_tx_hold_write(tx, DMU_NEW_OBJECT, 0, aclp->z_acl_bytes);
+	}
+
+	zfs_sa_upgrade_txholds(tx, zp);
+	error = dmu_tx_assign(tx, TXG_NOWAIT);
+	if (error) {
+		mutex_exit(&zp->z_acl_lock);
+		mutex_exit(&zp->z_lock);
+
+		if (error == ERESTART) {
+			dmu_tx_wait(tx);
+			dmu_tx_abort(tx);
+			goto top;
+		}
+		dmu_tx_abort(tx);
+		zfs_acl_free(aclp);
+		return (error);
+	}
+
+	error = zfs_aclset_common(zp, aclp, cr, tx);
+	ASSERT(error == 0);
+	ASSERT(zp->z_acl_cached == NULL);
+	zp->z_acl_cached = aclp;
+
+	if (fuid_dirtied)
+		zfs_fuid_sync(zsb, tx);
+
+	zfs_log_acl(zilog, tx, zp, vsecp, fuidp);
+
+	if (fuidp)
+		zfs_fuid_info_free(fuidp);
+	dmu_tx_commit(tx);
+
+	mutex_exit(&zp->z_lock);
+	mutex_exit(&zp->z_acl_lock);
+
+	return (error);
+}
+
+/*
+ * Check accesses of interest (AoI) against attributes of the dataset
+ * such as read-only.  Returns zero if no AoI conflict with dataset
+ * attributes, otherwise an appropriate errno is returned.
+ */
+static int
+zfs_zaccess_dataset_check(znode_t *zp, uint32_t v4_mode)
+{
+	if ((v4_mode & WRITE_MASK) && (zfs_is_readonly(ZTOZSB(zp))) &&
+	    (!S_ISDEV(ZTOI(zp)->i_mode) ||
+	    (S_ISDEV(ZTOI(zp)->i_mode) && (v4_mode & WRITE_MASK_ATTRS)))) {
+		return (SET_ERROR(EROFS));
+	}
+
+	/*
+	 * Only check for READONLY on non-directories.
+	 */
+	if ((v4_mode & WRITE_MASK_DATA) &&
+	    ((!S_ISDIR(ZTOI(zp)->i_mode) &&
+	    (zp->z_pflags & (ZFS_READONLY | ZFS_IMMUTABLE))) ||
+	    (S_ISDIR(ZTOI(zp)->i_mode) &&
+	    (zp->z_pflags & ZFS_IMMUTABLE)))) {
+		return (SET_ERROR(EPERM));
+	}
+
+	if ((v4_mode & (ACE_DELETE | ACE_DELETE_CHILD)) &&
+	    (zp->z_pflags & ZFS_NOUNLINK)) {
+		return (SET_ERROR(EPERM));
+	}
+
+	if (((v4_mode & (ACE_READ_DATA|ACE_EXECUTE)) &&
+	    (zp->z_pflags & ZFS_AV_QUARANTINED))) {
+		return (SET_ERROR(EACCES));
+	}
+
+	return (0);
+}
+
+/*
+ * The primary usage of this function is to loop through all of the
+ * ACEs in the znode, determining what accesses of interest (AoI) to
+ * the caller are allowed or denied.  The AoI are expressed as bits in
+ * the working_mode parameter.  As each ACE is processed, bits covered
+ * by that ACE are removed from the working_mode.  This removal
+ * facilitates two things.  The first is that when the working mode is
+ * empty (= 0), we know we've looked at all the AoI. The second is
+ * that the ACE interpretation rules don't allow a later ACE to undo
+ * something granted or denied by an earlier ACE.  Removing the
+ * discovered access or denial enforces this rule.  At the end of
+ * processing the ACEs, all AoI that were found to be denied are
+ * placed into the working_mode, giving the caller a mask of denied
+ * accesses.  Returns:
+ *	0		if all AoI granted
+ *	EACCESS 	if the denied mask is non-zero
+ *	other error	if abnormal failure (e.g., IO error)
+ *
+ * A secondary usage of the function is to determine if any of the
+ * AoI are granted.  If an ACE grants any access in
+ * the working_mode, we immediately short circuit out of the function.
+ * This mode is chosen by setting anyaccess to B_TRUE.  The
+ * working_mode is not a denied access mask upon exit if the function
+ * is used in this manner.
+ */
+static int
+zfs_zaccess_aces_check(znode_t *zp, uint32_t *working_mode,
+    boolean_t anyaccess, cred_t *cr)
+{
+	zfs_sb_t	*zsb = ZTOZSB(zp);
+	zfs_acl_t	*aclp;
+	int		error;
+	uid_t		uid = crgetuid(cr);
+	uint64_t	who;
+	uint16_t	type, iflags;
+	uint16_t	entry_type;
+	uint32_t	access_mask;
+	uint32_t	deny_mask = 0;
+	zfs_ace_hdr_t	*acep = NULL;
+	boolean_t	checkit;
+	uid_t		gowner;
+	uid_t		fowner;
+
+	zfs_fuid_map_ids(zp, cr, &fowner, &gowner);
+
+	mutex_enter(&zp->z_acl_lock);
+
+	error = zfs_acl_node_read(zp, B_FALSE, &aclp, B_FALSE);
+	if (error != 0) {
+		mutex_exit(&zp->z_acl_lock);
+		return (error);
+	}
+
+	ASSERT(zp->z_acl_cached);
+
+	while ((acep = zfs_acl_next_ace(aclp, acep, &who, &access_mask,
+	    &iflags, &type))) {
+		uint32_t mask_matched;
+
+		if (!zfs_acl_valid_ace_type(type, iflags))
+			continue;
+
+		if (S_ISDIR(ZTOI(zp)->i_mode) &&
+		    (iflags & ACE_INHERIT_ONLY_ACE))
+			continue;
+
+		/* Skip ACE if it does not affect any AoI */
+		mask_matched = (access_mask & *working_mode);
+		if (!mask_matched)
+			continue;
+
+		entry_type = (iflags & ACE_TYPE_FLAGS);
+
+		checkit = B_FALSE;
+
+		switch (entry_type) {
+		case ACE_OWNER:
+			if (uid == fowner)
+				checkit = B_TRUE;
+			break;
+		case OWNING_GROUP:
+			who = gowner;
+			/*FALLTHROUGH*/
+		case ACE_IDENTIFIER_GROUP:
+			checkit = zfs_groupmember(zsb, who, cr);
+			break;
+		case ACE_EVERYONE:
+			checkit = B_TRUE;
+			break;
+
+		/* USER Entry */
+		default:
+			if (entry_type == 0) {
+				uid_t newid;
+
+				newid = zfs_fuid_map_id(zsb, who, cr,
+				    ZFS_ACE_USER);
+				if (newid != IDMAP_WK_CREATOR_OWNER_UID &&
+				    uid == newid)
+					checkit = B_TRUE;
+				break;
+			} else {
+				mutex_exit(&zp->z_acl_lock);
+				return (SET_ERROR(EIO));
+			}
+		}
+
+		if (checkit) {
+			if (type == DENY) {
+				DTRACE_PROBE3(zfs__ace__denies,
+				    znode_t *, zp,
+				    zfs_ace_hdr_t *, acep,
+				    uint32_t, mask_matched);
+				deny_mask |= mask_matched;
+			} else {
+				DTRACE_PROBE3(zfs__ace__allows,
+				    znode_t *, zp,
+				    zfs_ace_hdr_t *, acep,
+				    uint32_t, mask_matched);
+				if (anyaccess) {
+					mutex_exit(&zp->z_acl_lock);
+					return (0);
+				}
+			}
+			*working_mode &= ~mask_matched;
+		}
+
+		/* Are we done? */
+		if (*working_mode == 0)
+			break;
+	}
+
+	mutex_exit(&zp->z_acl_lock);
+
+	/* Put the found 'denies' back on the working mode */
+	if (deny_mask) {
+		*working_mode |= deny_mask;
+		return (SET_ERROR(EACCES));
+	} else if (*working_mode) {
+		return (-1);
+	}
+
+	return (0);
+}
+
+/*
+ * Return true if any access whatsoever granted, we don't actually
+ * care what access is granted.
+ */
+boolean_t
+zfs_has_access(znode_t *zp, cred_t *cr)
+{
+	uint32_t have = ACE_ALL_PERMS;
+
+	if (zfs_zaccess_aces_check(zp, &have, B_TRUE, cr) != 0) {
+		uid_t owner;
+
+		owner = zfs_fuid_map_id(ZTOZSB(zp), zp->z_uid, cr, ZFS_OWNER);
+		return (secpolicy_vnode_any_access(cr, ZTOI(zp), owner) == 0);
+	}
+	return (B_TRUE);
+}
+
+static int
+zfs_zaccess_common(znode_t *zp, uint32_t v4_mode, uint32_t *working_mode,
+    boolean_t *check_privs, boolean_t skipaclchk, cred_t *cr)
+{
+	zfs_sb_t *zsb = ZTOZSB(zp);
+	int err;
+
+	*working_mode = v4_mode;
+	*check_privs = B_TRUE;
+
+	/*
+	 * Short circuit empty requests
+	 */
+	if (v4_mode == 0 || zsb->z_replay) {
+		*working_mode = 0;
+		return (0);
+	}
+
+	if ((err = zfs_zaccess_dataset_check(zp, v4_mode)) != 0) {
+		*check_privs = B_FALSE;
+		return (err);
+	}
+
+	/*
+	 * The caller requested that the ACL check be skipped.  This
+	 * would only happen if the caller checked VOP_ACCESS() with a
+	 * 32 bit ACE mask and already had the appropriate permissions.
+	 */
+	if (skipaclchk) {
+		*working_mode = 0;
+		return (0);
+	}
+
+	return (zfs_zaccess_aces_check(zp, working_mode, B_FALSE, cr));
+}
+
+static int
+zfs_zaccess_append(znode_t *zp, uint32_t *working_mode, boolean_t *check_privs,
+    cred_t *cr)
+{
+	if (*working_mode != ACE_WRITE_DATA)
+		return (SET_ERROR(EACCES));
+
+	return (zfs_zaccess_common(zp, ACE_APPEND_DATA, working_mode,
+	    check_privs, B_FALSE, cr));
+}
+
+int
+zfs_fastaccesschk_execute(znode_t *zdp, cred_t *cr)
+{
+	boolean_t owner = B_FALSE;
+	boolean_t groupmbr = B_FALSE;
+	boolean_t is_attr;
+	uid_t uid = crgetuid(cr);
+	int error;
+
+	if (zdp->z_pflags & ZFS_AV_QUARANTINED)
+		return (SET_ERROR(EACCES));
+
+	is_attr = ((zdp->z_pflags & ZFS_XATTR) &&
+	    (S_ISDIR(ZTOI(zdp)->i_mode)));
+	if (is_attr)
+		goto slow;
+
+
+	mutex_enter(&zdp->z_acl_lock);
+
+	if (zdp->z_pflags & ZFS_NO_EXECS_DENIED) {
+		mutex_exit(&zdp->z_acl_lock);
+		return (0);
+	}
+
+	if (FUID_INDEX(zdp->z_uid) != 0 || FUID_INDEX(zdp->z_gid) != 0) {
+		mutex_exit(&zdp->z_acl_lock);
+		goto slow;
+	}
+
+	if (uid == zdp->z_uid) {
+		owner = B_TRUE;
+		if (zdp->z_mode & S_IXUSR) {
+			mutex_exit(&zdp->z_acl_lock);
+			return (0);
+		} else {
+			mutex_exit(&zdp->z_acl_lock);
+			goto slow;
+		}
+	}
+	if (groupmember(zdp->z_gid, cr)) {
+		groupmbr = B_TRUE;
+		if (zdp->z_mode & S_IXGRP) {
+			mutex_exit(&zdp->z_acl_lock);
+			return (0);
+		} else {
+			mutex_exit(&zdp->z_acl_lock);
+			goto slow;
+		}
+	}
+	if (!owner && !groupmbr) {
+		if (zdp->z_mode & S_IXOTH) {
+			mutex_exit(&zdp->z_acl_lock);
+			return (0);
+		}
+	}
+
+	mutex_exit(&zdp->z_acl_lock);
+
+slow:
+	DTRACE_PROBE(zfs__fastpath__execute__access__miss);
+	ZFS_ENTER(ZTOZSB(zdp));
+	error = zfs_zaccess(zdp, ACE_EXECUTE, 0, B_FALSE, cr);
+	ZFS_EXIT(ZTOZSB(zdp));
+	return (error);
+}
+
+/*
+ * Determine whether Access should be granted/denied.
+ *
+ * The least priv subsytem is always consulted as a basic privilege
+ * can define any form of access.
+ */
+int
+zfs_zaccess(znode_t *zp, int mode, int flags, boolean_t skipaclchk, cred_t *cr)
+{
+	uint32_t	working_mode;
+	int		error;
+	boolean_t	check_privs;
+	znode_t		*check_zp = zp;
+	mode_t		needed_bits;
+	uid_t		owner;
+
+	/*
+	 * If attribute then validate against base file
+	 */
+	if ((zp->z_pflags & ZFS_XATTR) && S_ISDIR(ZTOI(zp)->i_mode)) {
+		uint64_t	parent;
+
+		rw_enter(&zp->z_xattr_lock, RW_READER);
+		if (zp->z_xattr_parent) {
+			check_zp = zp->z_xattr_parent;
+			rw_exit(&zp->z_xattr_lock);
+
+			/*
+			 * Verify a lookup yields the same znode.
+			 */
+			ASSERT3S(sa_lookup(zp->z_sa_hdl, SA_ZPL_PARENT(
+			    ZTOZSB(zp)), &parent, sizeof (parent)), ==, 0);
+			ASSERT3U(check_zp->z_id, ==, parent);
+		} else {
+			rw_exit(&zp->z_xattr_lock);
+
+			error = sa_lookup(zp->z_sa_hdl, SA_ZPL_PARENT(
+			    ZTOZSB(zp)), &parent, sizeof (parent));
+			if (error)
+				return (error);
+
+			/*
+			 * Cache the lookup on the parent file znode as
+			 * zp->z_xattr_parent and hold a reference.  This
+			 * effectively pins the parent in memory until all
+			 * child xattr znodes have been destroyed and
+			 * release their references in zfs_inode_destroy().
+			 */
+			error = zfs_zget(ZTOZSB(zp), parent, &check_zp);
+			if (error)
+				return (error);
+
+			rw_enter(&zp->z_xattr_lock, RW_WRITER);
+			if (zp->z_xattr_parent == NULL)
+				zp->z_xattr_parent = check_zp;
+			rw_exit(&zp->z_xattr_lock);
+		}
+
+		/*
+		 * fixup mode to map to xattr perms
+		 */
+
+		if (mode & (ACE_WRITE_DATA|ACE_APPEND_DATA)) {
+			mode &= ~(ACE_WRITE_DATA|ACE_APPEND_DATA);
+			mode |= ACE_WRITE_NAMED_ATTRS;
+		}
+
+		if (mode & (ACE_READ_DATA|ACE_EXECUTE)) {
+			mode &= ~(ACE_READ_DATA|ACE_EXECUTE);
+			mode |= ACE_READ_NAMED_ATTRS;
+		}
+	}
+
+	owner = zfs_fuid_map_id(ZTOZSB(zp), zp->z_uid, cr, ZFS_OWNER);
+	/*
+	 * Map the bits required to the standard inode flags
+	 * S_IRUSR|S_IWUSR|S_IXUSR in the needed_bits.  Map the bits
+	 * mapped by working_mode (currently missing) in missing_bits.
+	 * Call secpolicy_vnode_access2() with (needed_bits & ~checkmode),
+	 * needed_bits.
+	 */
+	needed_bits = 0;
+
+	working_mode = mode;
+	if ((working_mode & (ACE_READ_ACL|ACE_READ_ATTRIBUTES)) &&
+	    owner == crgetuid(cr))
+		working_mode &= ~(ACE_READ_ACL|ACE_READ_ATTRIBUTES);
+
+	if (working_mode & (ACE_READ_DATA|ACE_READ_NAMED_ATTRS|
+	    ACE_READ_ACL|ACE_READ_ATTRIBUTES|ACE_SYNCHRONIZE))
+		needed_bits |= S_IRUSR;
+	if (working_mode & (ACE_WRITE_DATA|ACE_WRITE_NAMED_ATTRS|
+	    ACE_APPEND_DATA|ACE_WRITE_ATTRIBUTES|ACE_SYNCHRONIZE))
+		needed_bits |= S_IWUSR;
+	if (working_mode & ACE_EXECUTE)
+		needed_bits |= S_IXUSR;
+
+	if ((error = zfs_zaccess_common(check_zp, mode, &working_mode,
+	    &check_privs, skipaclchk, cr)) == 0) {
+		return (secpolicy_vnode_access2(cr, ZTOI(zp), owner,
+		    needed_bits, needed_bits));
+	}
+
+	if (error && !check_privs) {
+		return (error);
+	}
+
+	if (error && (flags & V_APPEND)) {
+		error = zfs_zaccess_append(zp, &working_mode, &check_privs, cr);
+	}
+
+	if (error && check_privs) {
+		mode_t		checkmode = 0;
+
+		/*
+		 * First check for implicit owner permission on
+		 * read_acl/read_attributes
+		 */
+
+		error = 0;
+		ASSERT(working_mode != 0);
+
+		if ((working_mode & (ACE_READ_ACL|ACE_READ_ATTRIBUTES) &&
+		    owner == crgetuid(cr)))
+			working_mode &= ~(ACE_READ_ACL|ACE_READ_ATTRIBUTES);
+
+		if (working_mode & (ACE_READ_DATA|ACE_READ_NAMED_ATTRS|
+		    ACE_READ_ACL|ACE_READ_ATTRIBUTES|ACE_SYNCHRONIZE))
+			checkmode |= S_IRUSR;
+		if (working_mode & (ACE_WRITE_DATA|ACE_WRITE_NAMED_ATTRS|
+		    ACE_APPEND_DATA|ACE_WRITE_ATTRIBUTES|ACE_SYNCHRONIZE))
+			checkmode |= S_IWUSR;
+		if (working_mode & ACE_EXECUTE)
+			checkmode |= S_IXUSR;
+
+		error = secpolicy_vnode_access2(cr, ZTOI(check_zp), owner,
+		    needed_bits & ~checkmode, needed_bits);
+
+		if (error == 0 && (working_mode & ACE_WRITE_OWNER))
+			error = secpolicy_vnode_chown(cr, owner);
+		if (error == 0 && (working_mode & ACE_WRITE_ACL))
+			error = secpolicy_vnode_setdac(cr, owner);
+
+		if (error == 0 && (working_mode &
+		    (ACE_DELETE|ACE_DELETE_CHILD)))
+			error = secpolicy_vnode_remove(cr);
+
+		if (error == 0 && (working_mode & ACE_SYNCHRONIZE)) {
+			error = secpolicy_vnode_chown(cr, owner);
+		}
+		if (error == 0) {
+			/*
+			 * See if any bits other than those already checked
+			 * for are still present.  If so then return EACCES
+			 */
+			if (working_mode & ~(ZFS_CHECKED_MASKS)) {
+				error = SET_ERROR(EACCES);
+			}
+		}
+	} else if (error == 0) {
+		error = secpolicy_vnode_access2(cr, ZTOI(zp), owner,
+		    needed_bits, needed_bits);
+	}
+
+	return (error);
+}
+
+/*
+ * Translate traditional unix S_IRUSR/S_IWUSR/S_IXUSR mode into
+ * native ACL format and call zfs_zaccess()
+ */
+int
+zfs_zaccess_rwx(znode_t *zp, mode_t mode, int flags, cred_t *cr)
+{
+	return (zfs_zaccess(zp, zfs_unix_to_v4(mode >> 6), flags, B_FALSE, cr));
+}
+
+/*
+ * Access function for secpolicy_vnode_setattr
+ */
+int
+zfs_zaccess_unix(znode_t *zp, mode_t mode, cred_t *cr)
+{
+	int v4_mode = zfs_unix_to_v4(mode >> 6);
+
+	return (zfs_zaccess(zp, v4_mode, 0, B_FALSE, cr));
+}
+
+static int
+zfs_delete_final_check(znode_t *zp, znode_t *dzp,
+    mode_t available_perms, cred_t *cr)
+{
+	int error;
+	uid_t downer;
+
+	downer = zfs_fuid_map_id(ZTOZSB(dzp), dzp->z_uid, cr, ZFS_OWNER);
+
+	error = secpolicy_vnode_access2(cr, ZTOI(dzp),
+	    downer, available_perms, S_IWUSR|S_IXUSR);
+
+	if (error == 0)
+		error = zfs_sticky_remove_access(dzp, zp, cr);
+
+	return (error);
+}
+
+/*
+ * Determine whether Access should be granted/deny, without
+ * consulting least priv subsystem.
+ *
+ * The following chart is the recommended NFSv4 enforcement for
+ * ability to delete an object.
+ *
+ *      -------------------------------------------------------
+ *      |   Parent Dir  |           Target Object Permissions |
+ *      |  permissions  |                                     |
+ *      -------------------------------------------------------
+ *      |               | ACL Allows | ACL Denies| Delete     |
+ *      |               |  Delete    |  Delete   | unspecified|
+ *      -------------------------------------------------------
+ *      |  ACL Allows   | Permit     | Permit    | Permit     |
+ *      |  DELETE_CHILD |                                     |
+ *      -------------------------------------------------------
+ *      |  ACL Denies   | Permit     | Deny      | Deny       |
+ *      |  DELETE_CHILD |            |           |            |
+ *      -------------------------------------------------------
+ *      | ACL specifies |            |           |            |
+ *      | only allow    | Permit     | Permit    | Permit     |
+ *      | write and     |            |           |            |
+ *      | execute       |            |           |            |
+ *      -------------------------------------------------------
+ *      | ACL denies    |            |           |            |
+ *      | write and     | Permit     | Deny      | Deny       |
+ *      | execute       |            |           |            |
+ *      -------------------------------------------------------
+ *         ^
+ *         |
+ *         No search privilege, can't even look up file?
+ *
+ */
+int
+zfs_zaccess_delete(znode_t *dzp, znode_t *zp, cred_t *cr)
+{
+	uint32_t dzp_working_mode = 0;
+	uint32_t zp_working_mode = 0;
+	int dzp_error, zp_error;
+	mode_t available_perms;
+	boolean_t dzpcheck_privs = B_TRUE;
+	boolean_t zpcheck_privs = B_TRUE;
+
+	/*
+	 * We want specific DELETE permissions to
+	 * take precedence over WRITE/EXECUTE.  We don't
+	 * want an ACL such as this to mess us up.
+	 * user:joe:write_data:deny,user:joe:delete:allow
+	 *
+	 * However, deny permissions may ultimately be overridden
+	 * by secpolicy_vnode_access().
+	 *
+	 * We will ask for all of the necessary permissions and then
+	 * look at the working modes from the directory and target object
+	 * to determine what was found.
+	 */
+
+	if (zp->z_pflags & (ZFS_IMMUTABLE | ZFS_NOUNLINK))
+		return (SET_ERROR(EPERM));
+
+	/*
+	 * First row
+	 * If the directory permissions allow the delete, we are done.
+	 */
+	if ((dzp_error = zfs_zaccess_common(dzp, ACE_DELETE_CHILD,
+	    &dzp_working_mode, &dzpcheck_privs, B_FALSE, cr)) == 0)
+		return (0);
+
+	/*
+	 * If target object has delete permission then we are done
+	 */
+	if ((zp_error = zfs_zaccess_common(zp, ACE_DELETE, &zp_working_mode,
+	    &zpcheck_privs, B_FALSE, cr)) == 0)
+		return (0);
+
+	ASSERT(dzp_error && zp_error);
+
+	if (!dzpcheck_privs)
+		return (dzp_error);
+	if (!zpcheck_privs)
+		return (zp_error);
+
+	/*
+	 * Second row
+	 *
+	 * If directory returns EACCES then delete_child was denied
+	 * due to deny delete_child.  In this case send the request through
+	 * secpolicy_vnode_remove().  We don't use zfs_delete_final_check()
+	 * since that *could* allow the delete based on write/execute permission
+	 * and we want delete permissions to override write/execute.
+	 */
+
+	if (dzp_error == EACCES)
+		return (secpolicy_vnode_remove(cr));
+
+	/*
+	 * Third Row
+	 * only need to see if we have write/execute on directory.
+	 */
+
+	dzp_error = zfs_zaccess_common(dzp, ACE_EXECUTE|ACE_WRITE_DATA,
+	    &dzp_working_mode, &dzpcheck_privs, B_FALSE, cr);
+
+	if (dzp_error != 0 && !dzpcheck_privs)
+		return (dzp_error);
+
+	/*
+	 * Fourth row
+	 */
+
+	available_perms = (dzp_working_mode & ACE_WRITE_DATA) ? 0 : S_IWUSR;
+	available_perms |= (dzp_working_mode & ACE_EXECUTE) ? 0 : S_IXUSR;
+
+	return (zfs_delete_final_check(zp, dzp, available_perms, cr));
+
+}
+
+int
+zfs_zaccess_rename(znode_t *sdzp, znode_t *szp, znode_t *tdzp,
+    znode_t *tzp, cred_t *cr)
+{
+	int add_perm;
+	int error;
+
+	if (szp->z_pflags & ZFS_AV_QUARANTINED)
+		return (SET_ERROR(EACCES));
+
+	add_perm = S_ISDIR(ZTOI(szp)->i_mode) ?
+	    ACE_ADD_SUBDIRECTORY : ACE_ADD_FILE;
+
+	/*
+	 * Rename permissions are combination of delete permission +
+	 * add file/subdir permission.
+	 */
+
+	/*
+	 * first make sure we do the delete portion.
+	 *
+	 * If that succeeds then check for add_file/add_subdir permissions
+	 */
+
+	if ((error = zfs_zaccess_delete(sdzp, szp, cr)))
+		return (error);
+
+	/*
+	 * If we have a tzp, see if we can delete it?
+	 */
+	if (tzp) {
+		if ((error = zfs_zaccess_delete(tdzp, tzp, cr)))
+			return (error);
+	}
+
+	/*
+	 * Now check for add permissions
+	 */
+	error = zfs_zaccess(tdzp, add_perm, 0, B_FALSE, cr);
+
+	return (error);
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/module/zfs/zfs_byteswap.c
@@ -0,0 +1,205 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#include <sys/zfs_context.h>
+#include <sys/vfs.h>
+#include <sys/fs/zfs.h>
+#include <sys/zfs_znode.h>
+#include <sys/zfs_sa.h>
+#include <sys/zfs_acl.h>
+
+void
+zfs_oldace_byteswap(ace_t *ace, int ace_cnt)
+{
+	int i;
+
+	for (i = 0; i != ace_cnt; i++, ace++) {
+		ace->a_who = BSWAP_32(ace->a_who);
+		ace->a_access_mask = BSWAP_32(ace->a_access_mask);
+		ace->a_flags = BSWAP_16(ace->a_flags);
+		ace->a_type = BSWAP_16(ace->a_type);
+	}
+}
+
+/*
+ * swap ace_t and ace_oject_t
+ */
+void
+zfs_ace_byteswap(void *buf, size_t size, boolean_t zfs_layout)
+{
+	caddr_t end;
+	caddr_t ptr;
+	zfs_ace_t *zacep = NULL;
+	ace_t *acep;
+	uint16_t entry_type;
+	size_t entry_size;
+	int ace_type;
+
+	end = (caddr_t)buf + size;
+	ptr = buf;
+
+	while (ptr < end) {
+		if (zfs_layout) {
+			/*
+			 * Avoid overrun.  Embedded aces can have one
+			 * of several sizes.  We don't know exactly
+			 * how many our present, only the size of the
+			 * buffer containing them.  That size may be
+			 * larger than needed to hold the aces
+			 * present.  As long as we do not do any
+			 * swapping beyond the end of our block we are
+			 * okay.  It it safe to swap any non-ace data
+			 * within the block since it is just zeros.
+			 */
+			if (ptr + sizeof (zfs_ace_hdr_t) > end) {
+				break;
+			}
+			zacep = (zfs_ace_t *)ptr;
+			zacep->z_hdr.z_access_mask =
+			    BSWAP_32(zacep->z_hdr.z_access_mask);
+			zacep->z_hdr.z_flags = BSWAP_16(zacep->z_hdr.z_flags);
+			ace_type = zacep->z_hdr.z_type =
+			    BSWAP_16(zacep->z_hdr.z_type);
+			entry_type = zacep->z_hdr.z_flags & ACE_TYPE_FLAGS;
+		} else {
+			/* Overrun avoidance */
+			if (ptr + sizeof (ace_t) > end) {
+				break;
+			}
+			acep = (ace_t *)ptr;
+			acep->a_access_mask = BSWAP_32(acep->a_access_mask);
+			acep->a_flags = BSWAP_16(acep->a_flags);
+			ace_type = acep->a_type = BSWAP_16(acep->a_type);
+			acep->a_who = BSWAP_32(acep->a_who);
+			entry_type = acep->a_flags & ACE_TYPE_FLAGS;
+		}
+		switch (entry_type) {
+		case ACE_OWNER:
+		case ACE_EVERYONE:
+		case (ACE_IDENTIFIER_GROUP | ACE_GROUP):
+			entry_size = zfs_layout ?
+			    sizeof (zfs_ace_hdr_t) : sizeof (ace_t);
+			break;
+		case ACE_IDENTIFIER_GROUP:
+		default:
+			/* Overrun avoidance */
+			if (zfs_layout) {
+				if (ptr + sizeof (zfs_ace_t) <= end) {
+					zacep->z_fuid = BSWAP_64(zacep->z_fuid);
+				} else {
+					entry_size = sizeof (zfs_ace_t);
+					break;
+				}
+			}
+			switch (ace_type) {
+			case ACE_ACCESS_ALLOWED_OBJECT_ACE_TYPE:
+			case ACE_ACCESS_DENIED_OBJECT_ACE_TYPE:
+			case ACE_SYSTEM_AUDIT_OBJECT_ACE_TYPE:
+			case ACE_SYSTEM_ALARM_OBJECT_ACE_TYPE:
+				entry_size = zfs_layout ?
+				    sizeof (zfs_object_ace_t) :
+				    sizeof (ace_object_t);
+				break;
+			default:
+				entry_size = zfs_layout ? sizeof (zfs_ace_t) :
+				    sizeof (ace_t);
+				break;
+			}
+		}
+		ptr = ptr + entry_size;
+	}
+}
+
+/* ARGSUSED */
+void
+zfs_oldacl_byteswap(void *buf, size_t size)
+{
+	int cnt;
+
+	/*
+	 * Arggh, since we don't know how many ACEs are in
+	 * the array, we have to swap the entire block
+	 */
+
+	cnt = size / sizeof (ace_t);
+
+	zfs_oldace_byteswap((ace_t *)buf, cnt);
+}
+
+/* ARGSUSED */
+void
+zfs_acl_byteswap(void *buf, size_t size)
+{
+	zfs_ace_byteswap(buf, size, B_TRUE);
+}
+
+void
+zfs_znode_byteswap(void *buf, size_t size)
+{
+	znode_phys_t *zp = buf;
+
+	ASSERT(size >= sizeof (znode_phys_t));
+
+	zp->zp_crtime[0] = BSWAP_64(zp->zp_crtime[0]);
+	zp->zp_crtime[1] = BSWAP_64(zp->zp_crtime[1]);
+	zp->zp_atime[0] = BSWAP_64(zp->zp_atime[0]);
+	zp->zp_atime[1] = BSWAP_64(zp->zp_atime[1]);
+	zp->zp_mtime[0] = BSWAP_64(zp->zp_mtime[0]);
+	zp->zp_mtime[1] = BSWAP_64(zp->zp_mtime[1]);
+	zp->zp_ctime[0] = BSWAP_64(zp->zp_ctime[0]);
+	zp->zp_ctime[1] = BSWAP_64(zp->zp_ctime[1]);
+	zp->zp_gen = BSWAP_64(zp->zp_gen);
+	zp->zp_mode = BSWAP_64(zp->zp_mode);
+	zp->zp_size = BSWAP_64(zp->zp_size);
+	zp->zp_parent = BSWAP_64(zp->zp_parent);
+	zp->zp_links = BSWAP_64(zp->zp_links);
+	zp->zp_xattr = BSWAP_64(zp->zp_xattr);
+	zp->zp_rdev = BSWAP_64(zp->zp_rdev);
+	zp->zp_flags = BSWAP_64(zp->zp_flags);
+	zp->zp_uid = BSWAP_64(zp->zp_uid);
+	zp->zp_gid = BSWAP_64(zp->zp_gid);
+	zp->zp_zap = BSWAP_64(zp->zp_zap);
+	zp->zp_pad[0] = BSWAP_64(zp->zp_pad[0]);
+	zp->zp_pad[1] = BSWAP_64(zp->zp_pad[1]);
+	zp->zp_pad[2] = BSWAP_64(zp->zp_pad[2]);
+
+	zp->zp_acl.z_acl_extern_obj = BSWAP_64(zp->zp_acl.z_acl_extern_obj);
+	zp->zp_acl.z_acl_size = BSWAP_32(zp->zp_acl.z_acl_size);
+	zp->zp_acl.z_acl_version = BSWAP_16(zp->zp_acl.z_acl_version);
+	zp->zp_acl.z_acl_count = BSWAP_16(zp->zp_acl.z_acl_count);
+	if (zp->zp_acl.z_acl_version == ZFS_ACL_VERSION) {
+		zfs_acl_byteswap((void *)&zp->zp_acl.z_ace_data[0],
+		    ZFS_ACE_SPACE);
+	} else {
+		zfs_oldace_byteswap((ace_t *)&zp->zp_acl.z_ace_data[0],
+		    ACE_SLOT_CNT);
+	}
+}
+
+#if defined(_KERNEL) && defined(HAVE_SPL)
+EXPORT_SYMBOL(zfs_oldacl_byteswap);
+EXPORT_SYMBOL(zfs_acl_byteswap);
+EXPORT_SYMBOL(zfs_znode_byteswap);
+#endif
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/module/zfs/zfs_ctldir.c
@@ -0,0 +1,1302 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ *
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (C) 2011 Lawrence Livermore National Security, LLC.
+ * Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ * LLNL-CODE-403049.
+ * Rewritten for Linux by:
+ *   Rohan Puri <rohan.puri15@gmail.com>
+ *   Brian Behlendorf <behlendorf1@llnl.gov>
+ * Copyright (c) 2013 by Delphix. All rights reserved.
+ */
+
+/*
+ * ZFS control directory (a.k.a. ".zfs")
+ *
+ * This directory provides a common location for all ZFS meta-objects.
+ * Currently, this is only the 'snapshot' and 'shares' directory, but this may
+ * expand in the future.  The elements are built dynamically, as the hierarchy
+ * does not actually exist on disk.
+ *
+ * For 'snapshot', we don't want to have all snapshots always mounted, because
+ * this would take up a huge amount of space in /etc/mnttab.  We have three
+ * types of objects:
+ *
+ *	ctldir ------> snapshotdir -------> snapshot
+ *                                             |
+ *                                             |
+ *                                             V
+ *                                         mounted fs
+ *
+ * The 'snapshot' node contains just enough information to lookup '..' and act
+ * as a mountpoint for the snapshot.  Whenever we lookup a specific snapshot, we
+ * perform an automount of the underlying filesystem and return the
+ * corresponding inode.
+ *
+ * All mounts are handled automatically by an user mode helper which invokes
+ * the mount mount procedure.  Unmounts are handled by allowing the mount
+ * point to expire so the kernel may automatically unmount it.
+ *
+ * The '.zfs', '.zfs/snapshot', and all directories created under
+ * '.zfs/snapshot' (ie: '.zfs/snapshot/<snapname>') all share the same
+ * share the same zfs_sb_t as the head filesystem (what '.zfs' lives under).
+ *
+ * File systems mounted on top of the '.zfs/snapshot/<snapname>' paths
+ * (ie: snapshots) are complete ZFS filesystems and have their own unique
+ * zfs_sb_t.  However, the fsid reported by these mounts will be the same
+ * as that used by the parent zfs_sb_t to make NFS happy.
+ */
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/time.h>
+#include <sys/systm.h>
+#include <sys/sysmacros.h>
+#include <sys/pathname.h>
+#include <sys/vfs.h>
+#include <sys/vfs_opreg.h>
+#include <sys/zfs_ctldir.h>
+#include <sys/zfs_ioctl.h>
+#include <sys/zfs_vfsops.h>
+#include <sys/zfs_vnops.h>
+#include <sys/stat.h>
+#include <sys/dmu.h>
+#include <sys/dmu_objset.h>
+#include <sys/dsl_destroy.h>
+#include <sys/dsl_deleg.h>
+#include <sys/mount.h>
+#include <sys/zpl.h>
+#include "zfs_namecheck.h"
+
+/*
+ * Two AVL trees are maintained which contain all currently automounted
+ * snapshots.  Every automounted snapshots maps to a single zfs_snapentry_t
+ * entry which MUST:
+ *
+ *   - be attached to both trees, and
+ *   - be unique, no duplicate entries are allowed.
+ *
+ * The zfs_snapshots_by_name tree is indexed by the full dataset name
+ * while the zfs_snapshots_by_objsetid tree is indexed by the unique
+ * objsetid.  This allows for fast lookups either by name or objsetid.
+ */
+static avl_tree_t zfs_snapshots_by_name;
+static avl_tree_t zfs_snapshots_by_objsetid;
+static krwlock_t zfs_snapshot_lock;
+
+/*
+ * Control Directory Tunables (.zfs)
+ */
+int zfs_expire_snapshot = ZFSCTL_EXPIRE_SNAPSHOT;
+int zfs_admin_snapshot = 0;
+
+/*
+ * Dedicated task queue for unmounting snapshots.
+ */
+static taskq_t *zfs_expire_taskq;
+
+typedef struct {
+	char		*se_name;	/* full snapshot name */
+	char		*se_path;	/* full mount path */
+	spa_t		*se_spa;	/* pool spa */
+	uint64_t	se_objsetid;	/* snapshot objset id */
+	struct dentry   *se_root_dentry; /* snapshot root dentry */
+	taskqid_t	se_taskqid;	/* scheduled unmount taskqid */
+	avl_node_t	se_node_name;	/* zfs_snapshots_by_name link */
+	avl_node_t	se_node_objsetid; /* zfs_snapshots_by_objsetid link */
+	refcount_t	se_refcount;	/* reference count */
+} zfs_snapentry_t;
+
+static void zfsctl_snapshot_unmount_delay_impl(zfs_snapentry_t *se, int delay);
+
+/*
+ * Allocate a new zfs_snapentry_t being careful to make a copy of the
+ * the snapshot name and provided mount point.  No reference is taken.
+ */
+static zfs_snapentry_t *
+zfsctl_snapshot_alloc(char *full_name, char *full_path, spa_t *spa,
+    uint64_t objsetid, struct dentry *root_dentry)
+{
+	zfs_snapentry_t *se;
+
+	se = kmem_zalloc(sizeof (zfs_snapentry_t), KM_SLEEP);
+
+	se->se_name = strdup(full_name);
+	se->se_path = strdup(full_path);
+	se->se_spa = spa;
+	se->se_objsetid = objsetid;
+	se->se_root_dentry = root_dentry;
+	se->se_taskqid = -1;
+
+	refcount_create(&se->se_refcount);
+
+	return (se);
+}
+
+/*
+ * Free a zfs_snapentry_t the called must ensure there are no active
+ * references.
+ */
+static void
+zfsctl_snapshot_free(zfs_snapentry_t *se)
+{
+	refcount_destroy(&se->se_refcount);
+	strfree(se->se_name);
+	strfree(se->se_path);
+
+	kmem_free(se, sizeof (zfs_snapentry_t));
+}
+
+/*
+ * Hold a reference on the zfs_snapentry_t.
+ */
+static void
+zfsctl_snapshot_hold(zfs_snapentry_t *se)
+{
+	refcount_add(&se->se_refcount, NULL);
+}
+
+/*
+ * Release a reference on the zfs_snapentry_t.  When the number of
+ * references drops to zero the structure will be freed.
+ */
+static void
+zfsctl_snapshot_rele(zfs_snapentry_t *se)
+{
+	if (refcount_remove(&se->se_refcount, NULL) == 0)
+		zfsctl_snapshot_free(se);
+}
+
+/*
+ * Add a zfs_snapentry_t to both the zfs_snapshots_by_name and
+ * zfs_snapshots_by_objsetid trees.  While the zfs_snapentry_t is part
+ * of the trees a reference is held.
+ */
+static void
+zfsctl_snapshot_add(zfs_snapentry_t *se)
+{
+	ASSERT(RW_WRITE_HELD(&zfs_snapshot_lock));
+	refcount_add(&se->se_refcount, NULL);
+	avl_add(&zfs_snapshots_by_name, se);
+	avl_add(&zfs_snapshots_by_objsetid, se);
+}
+
+/*
+ * Remove a zfs_snapentry_t from both the zfs_snapshots_by_name and
+ * zfs_snapshots_by_objsetid trees.  Upon removal a reference is dropped,
+ * this can result in the structure being freed if that was the last
+ * remaining reference.
+ */
+static void
+zfsctl_snapshot_remove(zfs_snapentry_t *se)
+{
+	ASSERT(RW_WRITE_HELD(&zfs_snapshot_lock));
+	avl_remove(&zfs_snapshots_by_name, se);
+	avl_remove(&zfs_snapshots_by_objsetid, se);
+	zfsctl_snapshot_rele(se);
+}
+
+/*
+ * Snapshot name comparison function for the zfs_snapshots_by_name.
+ */
+static int
+snapentry_compare_by_name(const void *a, const void *b)
+{
+	const zfs_snapentry_t *se_a = a;
+	const zfs_snapentry_t *se_b = b;
+	int ret;
+
+	ret = strcmp(se_a->se_name, se_b->se_name);
+
+	if (ret < 0)
+		return (-1);
+	else if (ret > 0)
+		return (1);
+	else
+		return (0);
+}
+
+/*
+ * Snapshot name comparison function for the zfs_snapshots_by_objsetid.
+ */
+static int
+snapentry_compare_by_objsetid(const void *a, const void *b)
+{
+	const zfs_snapentry_t *se_a = a;
+	const zfs_snapentry_t *se_b = b;
+
+	if (se_a->se_spa != se_b->se_spa)
+		return ((ulong_t)se_a->se_spa < (ulong_t)se_b->se_spa ? -1 : 1);
+
+	if (se_a->se_objsetid < se_b->se_objsetid)
+		return (-1);
+	else if (se_a->se_objsetid > se_b->se_objsetid)
+		return (1);
+	else
+		return (0);
+}
+
+/*
+ * Find a zfs_snapentry_t in zfs_snapshots_by_name.  If the snapname
+ * is found a pointer to the zfs_snapentry_t is returned and a reference
+ * taken on the structure.  The caller is responsible for dropping the
+ * reference with zfsctl_snapshot_rele().  If the snapname is not found
+ * NULL will be returned.
+ */
+static zfs_snapentry_t *
+zfsctl_snapshot_find_by_name(char *snapname)
+{
+	zfs_snapentry_t *se, search;
+
+	ASSERT(RW_LOCK_HELD(&zfs_snapshot_lock));
+
+	search.se_name = snapname;
+	se = avl_find(&zfs_snapshots_by_name, &search, NULL);
+	if (se)
+		refcount_add(&se->se_refcount, NULL);
+
+	return (se);
+}
+
+/*
+ * Find a zfs_snapentry_t in zfs_snapshots_by_objsetid given the objset id
+ * rather than the snapname.  In all other respects it behaves the same
+ * as zfsctl_snapshot_find_by_name().
+ */
+static zfs_snapentry_t *
+zfsctl_snapshot_find_by_objsetid(spa_t *spa, uint64_t objsetid)
+{
+	zfs_snapentry_t *se, search;
+
+	ASSERT(RW_LOCK_HELD(&zfs_snapshot_lock));
+
+	search.se_spa = spa;
+	search.se_objsetid = objsetid;
+	se = avl_find(&zfs_snapshots_by_objsetid, &search, NULL);
+	if (se)
+		refcount_add(&se->se_refcount, NULL);
+
+	return (se);
+}
+
+/*
+ * Rename a zfs_snapentry_t in the zfs_snapshots_by_name.  The structure is
+ * removed, renamed, and added back to the new correct location in the tree.
+ */
+static int
+zfsctl_snapshot_rename(char *old_snapname, char *new_snapname)
+{
+	zfs_snapentry_t *se;
+
+	ASSERT(RW_WRITE_HELD(&zfs_snapshot_lock));
+
+	se = zfsctl_snapshot_find_by_name(old_snapname);
+	if (se == NULL)
+		return (ENOENT);
+
+	zfsctl_snapshot_remove(se);
+	strfree(se->se_name);
+	se->se_name = strdup(new_snapname);
+	zfsctl_snapshot_add(se);
+	zfsctl_snapshot_rele(se);
+
+	return (0);
+}
+
+/*
+ * Delayed task responsible for unmounting an expired automounted snapshot.
+ */
+static void
+snapentry_expire(void *data)
+{
+	zfs_snapentry_t *se = (zfs_snapentry_t *)data;
+	spa_t *spa = se->se_spa;
+	uint64_t objsetid = se->se_objsetid;
+
+	if (zfs_expire_snapshot <= 0) {
+		zfsctl_snapshot_rele(se);
+		return;
+	}
+
+	se->se_taskqid = -1;
+	(void) zfsctl_snapshot_unmount(se->se_name, MNT_EXPIRE);
+	zfsctl_snapshot_rele(se);
+
+	/*
+	 * Reschedule the unmount if the zfs_snapentry_t wasn't removed.
+	 * This can occur when the snapshot is busy.
+	 */
+	rw_enter(&zfs_snapshot_lock, RW_READER);
+	if ((se = zfsctl_snapshot_find_by_objsetid(spa, objsetid)) != NULL) {
+		zfsctl_snapshot_unmount_delay_impl(se, zfs_expire_snapshot);
+		zfsctl_snapshot_rele(se);
+	}
+	rw_exit(&zfs_snapshot_lock);
+}
+
+/*
+ * Cancel an automatic unmount of a snapname.  This callback is responsible
+ * for dropping the reference on the zfs_snapentry_t which was taken when
+ * during dispatch.
+ */
+static void
+zfsctl_snapshot_unmount_cancel(zfs_snapentry_t *se)
+{
+	ASSERT(RW_LOCK_HELD(&zfs_snapshot_lock));
+
+	if (taskq_cancel_id(zfs_expire_taskq, se->se_taskqid) == 0) {
+		se->se_taskqid = -1;
+		zfsctl_snapshot_rele(se);
+	}
+}
+
+/*
+ * Dispatch the unmount task for delayed handling with a hold protecting it.
+ */
+static void
+zfsctl_snapshot_unmount_delay_impl(zfs_snapentry_t *se, int delay)
+{
+	ASSERT3S(se->se_taskqid, ==, -1);
+
+	if (delay <= 0)
+		return;
+
+	zfsctl_snapshot_hold(se);
+	se->se_taskqid = taskq_dispatch_delay(zfs_expire_taskq,
+	    snapentry_expire, se, TQ_SLEEP, ddi_get_lbolt() + delay * HZ);
+}
+
+/*
+ * Schedule an automatic unmount of objset id to occur in delay seconds from
+ * now.  Any previous delayed unmount will be cancelled in favor of the
+ * updated deadline.  A reference is taken by zfsctl_snapshot_find_by_name()
+ * and held until the outstanding task is handled or cancelled.
+ */
+int
+zfsctl_snapshot_unmount_delay(spa_t *spa, uint64_t objsetid, int delay)
+{
+	zfs_snapentry_t *se;
+	int error = ENOENT;
+
+	rw_enter(&zfs_snapshot_lock, RW_READER);
+	if ((se = zfsctl_snapshot_find_by_objsetid(spa, objsetid)) != NULL) {
+		zfsctl_snapshot_unmount_cancel(se);
+		zfsctl_snapshot_unmount_delay_impl(se, delay);
+		zfsctl_snapshot_rele(se);
+		error = 0;
+	}
+	rw_exit(&zfs_snapshot_lock);
+
+	return (error);
+}
+
+/*
+ * Check if snapname is currently mounted.  Returned non-zero when mounted
+ * and zero when unmounted.
+ */
+static boolean_t
+zfsctl_snapshot_ismounted(char *snapname)
+{
+	zfs_snapentry_t *se;
+	boolean_t ismounted = B_FALSE;
+
+	rw_enter(&zfs_snapshot_lock, RW_READER);
+	if ((se = zfsctl_snapshot_find_by_name(snapname)) != NULL) {
+		zfsctl_snapshot_rele(se);
+		ismounted = B_TRUE;
+	}
+	rw_exit(&zfs_snapshot_lock);
+
+	return (ismounted);
+}
+
+/*
+ * Check if the given inode is a part of the virtual .zfs directory.
+ */
+boolean_t
+zfsctl_is_node(struct inode *ip)
+{
+	return (ITOZ(ip)->z_is_ctldir);
+}
+
+/*
+ * Check if the given inode is a .zfs/snapshots/snapname directory.
+ */
+boolean_t
+zfsctl_is_snapdir(struct inode *ip)
+{
+	return (zfsctl_is_node(ip) && (ip->i_ino <= ZFSCTL_INO_SNAPDIRS));
+}
+
+/*
+ * Allocate a new inode with the passed id and ops.
+ */
+static struct inode *
+zfsctl_inode_alloc(zfs_sb_t *zsb, uint64_t id,
+    const struct file_operations *fops, const struct inode_operations *ops)
+{
+	struct timespec now = current_fs_time(zsb->z_sb);
+	struct inode *ip;
+	znode_t *zp;
+
+	ip = new_inode(zsb->z_sb);
+	if (ip == NULL)
+		return (NULL);
+
+	zp = ITOZ(ip);
+	ASSERT3P(zp->z_dirlocks, ==, NULL);
+	ASSERT3P(zp->z_acl_cached, ==, NULL);
+	ASSERT3P(zp->z_xattr_cached, ==, NULL);
+	zp->z_id = id;
+	zp->z_unlinked = 0;
+	zp->z_atime_dirty = 0;
+	zp->z_zn_prefetch = 0;
+	zp->z_moved = 0;
+	zp->z_sa_hdl = NULL;
+	zp->z_blksz = 0;
+	zp->z_seq = 0;
+	zp->z_mapcnt = 0;
+	zp->z_gen = 0;
+	zp->z_size = 0;
+	zp->z_atime[0] = 0;
+	zp->z_atime[1] = 0;
+	zp->z_links = 0;
+	zp->z_pflags = 0;
+	zp->z_uid = 0;
+	zp->z_gid = 0;
+	zp->z_mode = 0;
+	zp->z_sync_cnt = 0;
+	zp->z_is_zvol = B_FALSE;
+	zp->z_is_mapped = B_FALSE;
+	zp->z_is_ctldir = B_TRUE;
+	zp->z_is_sa = B_FALSE;
+	zp->z_is_stale = B_FALSE;
+	ip->i_ino = id;
+	ip->i_mode = (S_IFDIR | S_IRUGO | S_IXUGO);
+	ip->i_uid = SUID_TO_KUID(0);
+	ip->i_gid = SGID_TO_KGID(0);
+	ip->i_blkbits = SPA_MINBLOCKSHIFT;
+	ip->i_atime = now;
+	ip->i_mtime = now;
+	ip->i_ctime = now;
+	ip->i_fop = fops;
+	ip->i_op = ops;
+
+	if (insert_inode_locked(ip)) {
+		unlock_new_inode(ip);
+		iput(ip);
+		return (NULL);
+	}
+
+	mutex_enter(&zsb->z_znodes_lock);
+	list_insert_tail(&zsb->z_all_znodes, zp);
+	zsb->z_nr_znodes++;
+	membar_producer();
+	mutex_exit(&zsb->z_znodes_lock);
+
+	unlock_new_inode(ip);
+
+	return (ip);
+}
+
+/*
+ * Lookup the inode with given id, it will be allocated if needed.
+ */
+static struct inode *
+zfsctl_inode_lookup(zfs_sb_t *zsb, uint64_t id,
+    const struct file_operations *fops, const struct inode_operations *ops)
+{
+	struct inode *ip = NULL;
+
+	while (ip == NULL) {
+		ip = ilookup(zsb->z_sb, (unsigned long)id);
+		if (ip)
+			break;
+
+		/* May fail due to concurrent zfsctl_inode_alloc() */
+		ip = zfsctl_inode_alloc(zsb, id, fops, ops);
+	}
+
+	return (ip);
+}
+
+/*
+ * Create the '.zfs' directory.  This directory is cached as part of the VFS
+ * structure.  This results in a hold on the zfs_sb_t.  The code in zfs_umount()
+ * therefore checks against a vfs_count of 2 instead of 1.  This reference
+ * is removed when the ctldir is destroyed in the unmount.  All other entities
+ * under the '.zfs' directory are created dynamically as needed.
+ *
+ * Because the dynamically created '.zfs' directory entries assume the use
+ * of 64-bit inode numbers this support must be disabled on 32-bit systems.
+ */
+int
+zfsctl_create(zfs_sb_t *zsb)
+{
+#if defined(CONFIG_64BIT)
+	ASSERT(zsb->z_ctldir == NULL);
+
+	zsb->z_ctldir = zfsctl_inode_alloc(zsb, ZFSCTL_INO_ROOT,
+	    &zpl_fops_root, &zpl_ops_root);
+	if (zsb->z_ctldir == NULL)
+		return (SET_ERROR(ENOENT));
+
+	return (0);
+#else
+	return (SET_ERROR(EOPNOTSUPP));
+#endif /* CONFIG_64BIT */
+}
+
+/*
+ * Destroy the '.zfs' directory or remove a snapshot from zfs_snapshots_by_name.
+ * Only called when the filesystem is unmounted.
+ */
+void
+zfsctl_destroy(zfs_sb_t *zsb)
+{
+	if (zsb->z_issnap) {
+		zfs_snapentry_t *se;
+		spa_t *spa = zsb->z_os->os_spa;
+		uint64_t objsetid = dmu_objset_id(zsb->z_os);
+
+		rw_enter(&zfs_snapshot_lock, RW_WRITER);
+		if ((se = zfsctl_snapshot_find_by_objsetid(spa, objsetid))
+		    != NULL) {
+			zfsctl_snapshot_unmount_cancel(se);
+			zfsctl_snapshot_remove(se);
+			zfsctl_snapshot_rele(se);
+		}
+		rw_exit(&zfs_snapshot_lock);
+	} else if (zsb->z_ctldir) {
+		iput(zsb->z_ctldir);
+		zsb->z_ctldir = NULL;
+	}
+}
+
+/*
+ * Given a root znode, retrieve the associated .zfs directory.
+ * Add a hold to the vnode and return it.
+ */
+struct inode *
+zfsctl_root(znode_t *zp)
+{
+	ASSERT(zfs_has_ctldir(zp));
+	igrab(ZTOZSB(zp)->z_ctldir);
+	return (ZTOZSB(zp)->z_ctldir);
+}
+/*
+ * Generate a long fid which includes the root object and objset of a
+ * snapshot but not the generation number.  For the root object the
+ * generation number is ignored when zero to avoid needing to open
+ * the dataset when generating fids for the snapshot names.
+ */
+static int
+zfsctl_snapdir_fid(struct inode *ip, fid_t *fidp)
+{
+	zfs_sb_t *zsb = ITOZSB(ip);
+	zfid_short_t *zfid = (zfid_short_t *)fidp;
+	zfid_long_t *zlfid = (zfid_long_t *)fidp;
+	uint32_t gen = 0;
+	uint64_t object;
+	uint64_t objsetid;
+	int i;
+
+	object = zsb->z_root;
+	objsetid = ZFSCTL_INO_SNAPDIRS - ip->i_ino;
+	zfid->zf_len = LONG_FID_LEN;
+
+	for (i = 0; i < sizeof (zfid->zf_object); i++)
+		zfid->zf_object[i] = (uint8_t)(object >> (8 * i));
+
+	for (i = 0; i < sizeof (zfid->zf_gen); i++)
+		zfid->zf_gen[i] = (uint8_t)(gen >> (8 * i));
+
+	for (i = 0; i < sizeof (zlfid->zf_setid); i++)
+		zlfid->zf_setid[i] = (uint8_t)(objsetid >> (8 * i));
+
+	for (i = 0; i < sizeof (zlfid->zf_setgen); i++)
+		zlfid->zf_setgen[i] = 0;
+
+	return (0);
+}
+
+/*
+ * Generate an appropriate fid for an entry in the .zfs directory.
+ */
+int
+zfsctl_fid(struct inode *ip, fid_t *fidp)
+{
+	znode_t		*zp = ITOZ(ip);
+	zfs_sb_t	*zsb = ITOZSB(ip);
+	uint64_t	object = zp->z_id;
+	zfid_short_t	*zfid;
+	int		i;
+
+	ZFS_ENTER(zsb);
+
+	if (fidp->fid_len < SHORT_FID_LEN) {
+		fidp->fid_len = SHORT_FID_LEN;
+		ZFS_EXIT(zsb);
+		return (SET_ERROR(ENOSPC));
+	}
+
+	if (zfsctl_is_snapdir(ip)) {
+		ZFS_EXIT(zsb);
+		return (zfsctl_snapdir_fid(ip, fidp));
+	}
+
+	zfid = (zfid_short_t *)fidp;
+
+	zfid->zf_len = SHORT_FID_LEN;
+
+	for (i = 0; i < sizeof (zfid->zf_object); i++)
+		zfid->zf_object[i] = (uint8_t)(object >> (8 * i));
+
+	/* .zfs znodes always have a generation number of 0 */
+	for (i = 0; i < sizeof (zfid->zf_gen); i++)
+		zfid->zf_gen[i] = 0;
+
+	ZFS_EXIT(zsb);
+	return (0);
+}
+
+/*
+ * Construct a full dataset name in full_name: "pool/dataset@snap_name"
+ */
+static int
+zfsctl_snapshot_name(zfs_sb_t *zsb, const char *snap_name, int len,
+    char *full_name)
+{
+	objset_t *os = zsb->z_os;
+
+	if (zfs_component_namecheck(snap_name, NULL, NULL) != 0)
+		return (SET_ERROR(EILSEQ));
+
+	dmu_objset_name(os, full_name);
+	if ((strlen(full_name) + 1 + strlen(snap_name)) >= len)
+		return (SET_ERROR(ENAMETOOLONG));
+
+	(void) strcat(full_name, "@");
+	(void) strcat(full_name, snap_name);
+
+	return (0);
+}
+
+/*
+ * Returns full path in full_path: "/pool/dataset/.zfs/snapshot/snap_name/"
+ */
+static int
+zfsctl_snapshot_path(struct path *path, int len, char *full_path)
+{
+	char *path_buffer, *path_ptr;
+	int path_len, error = 0;
+
+	path_buffer = kmem_alloc(len, KM_SLEEP);
+
+	path_ptr = d_path(path, path_buffer, len);
+	if (IS_ERR(path_ptr)) {
+		error = -PTR_ERR(path_ptr);
+		goto out;
+	}
+
+	path_len = path_buffer + len - 1 - path_ptr;
+	if (path_len > len) {
+		error = SET_ERROR(EFAULT);
+		goto out;
+	}
+
+	memcpy(full_path, path_ptr, path_len);
+	full_path[path_len] = '\0';
+out:
+	kmem_free(path_buffer, len);
+
+	return (error);
+}
+
+/*
+ * Returns full path in full_path: "/pool/dataset/.zfs/snapshot/snap_name/"
+ */
+static int
+zfsctl_snapshot_path_objset(zfs_sb_t *zsb, uint64_t objsetid,
+    int path_len, char *full_path)
+{
+	objset_t *os = zsb->z_os;
+	fstrans_cookie_t cookie;
+	char *snapname;
+	boolean_t case_conflict;
+	uint64_t id, pos = 0;
+	int error = 0;
+
+	if (zsb->z_mntopts->z_mntpoint == NULL)
+		return (ENOENT);
+
+	cookie = spl_fstrans_mark();
+	snapname = kmem_alloc(MAXNAMELEN, KM_SLEEP);
+
+	while (error == 0) {
+		dsl_pool_config_enter(dmu_objset_pool(os), FTAG);
+		error = dmu_snapshot_list_next(zsb->z_os, MAXNAMELEN,
+		    snapname, &id, &pos, &case_conflict);
+		dsl_pool_config_exit(dmu_objset_pool(os), FTAG);
+		if (error)
+			goto out;
+
+		if (id == objsetid)
+			break;
+	}
+
+	memset(full_path, 0, path_len);
+	snprintf(full_path, path_len - 1, "%s/.zfs/snapshot/%s",
+	    zsb->z_mntopts->z_mntpoint, snapname);
+out:
+	kmem_free(snapname, MAXNAMELEN);
+	spl_fstrans_unmark(cookie);
+
+	return (error);
+}
+
+/*
+ * Special case the handling of "..".
+ */
+int
+zfsctl_root_lookup(struct inode *dip, char *name, struct inode **ipp,
+    int flags, cred_t *cr, int *direntflags, pathname_t *realpnp)
+{
+	zfs_sb_t *zsb = ITOZSB(dip);
+	int error = 0;
+
+	ZFS_ENTER(zsb);
+
+	if (strcmp(name, "..") == 0) {
+		*ipp = dip->i_sb->s_root->d_inode;
+	} else if (strcmp(name, ZFS_SNAPDIR_NAME) == 0) {
+		*ipp = zfsctl_inode_lookup(zsb, ZFSCTL_INO_SNAPDIR,
+		    &zpl_fops_snapdir, &zpl_ops_snapdir);
+	} else if (strcmp(name, ZFS_SHAREDIR_NAME) == 0) {
+		*ipp = zfsctl_inode_lookup(zsb, ZFSCTL_INO_SHARES,
+		    &zpl_fops_shares, &zpl_ops_shares);
+	} else {
+		*ipp = NULL;
+	}
+
+	if (*ipp == NULL)
+		error = SET_ERROR(ENOENT);
+
+	ZFS_EXIT(zsb);
+
+	return (error);
+}
+
+/*
+ * Lookup entry point for the 'snapshot' directory.  Try to open the
+ * snapshot if it exist, creating the pseudo filesystem inode as necessary.
+ * Perform a mount of the associated dataset on top of the inode.
+ */
+int
+zfsctl_snapdir_lookup(struct inode *dip, char *name, struct inode **ipp,
+    int flags, cred_t *cr, int *direntflags, pathname_t *realpnp)
+{
+	zfs_sb_t *zsb = ITOZSB(dip);
+	uint64_t id;
+	int error;
+
+	ZFS_ENTER(zsb);
+
+	error = dmu_snapshot_lookup(zsb->z_os, name, &id);
+	if (error) {
+		ZFS_EXIT(zsb);
+		return (error);
+	}
+
+	*ipp = zfsctl_inode_lookup(zsb, ZFSCTL_INO_SNAPDIRS - id,
+	    &simple_dir_operations, &simple_dir_inode_operations);
+	if (*ipp == NULL)
+		error = SET_ERROR(ENOENT);
+
+	ZFS_EXIT(zsb);
+
+	return (error);
+}
+
+/*
+ * Renaming a directory under '.zfs/snapshot' will automatically trigger
+ * a rename of the snapshot to the new given name.  The rename is confined
+ * to the '.zfs/snapshot' directory snapshots cannot be moved elsewhere.
+ */
+int
+zfsctl_snapdir_rename(struct inode *sdip, char *snm,
+    struct inode *tdip, char *tnm, cred_t *cr, int flags)
+{
+	zfs_sb_t *zsb = ITOZSB(sdip);
+	char *to, *from, *real, *fsname;
+	int error;
+
+	if (!zfs_admin_snapshot)
+		return (EACCES);
+
+	ZFS_ENTER(zsb);
+
+	to = kmem_alloc(MAXNAMELEN, KM_SLEEP);
+	from = kmem_alloc(MAXNAMELEN, KM_SLEEP);
+	real = kmem_alloc(MAXNAMELEN, KM_SLEEP);
+	fsname = kmem_alloc(MAXNAMELEN, KM_SLEEP);
+
+	if (zsb->z_case == ZFS_CASE_INSENSITIVE) {
+		error = dmu_snapshot_realname(zsb->z_os, snm, real,
+		    MAXNAMELEN, NULL);
+		if (error == 0) {
+			snm = real;
+		} else if (error != ENOTSUP) {
+			goto out;
+		}
+	}
+
+	dmu_objset_name(zsb->z_os, fsname);
+
+	error = zfsctl_snapshot_name(ITOZSB(sdip), snm, MAXNAMELEN, from);
+	if (error == 0)
+		error = zfsctl_snapshot_name(ITOZSB(tdip), tnm, MAXNAMELEN, to);
+	if (error == 0)
+		error = zfs_secpolicy_rename_perms(from, to, cr);
+	if (error != 0)
+		goto out;
+
+	/*
+	 * Cannot move snapshots out of the snapdir.
+	 */
+	if (sdip != tdip) {
+		error = SET_ERROR(EINVAL);
+		goto out;
+	}
+
+	/*
+	 * No-op when names are identical.
+	 */
+	if (strcmp(snm, tnm) == 0) {
+		error = 0;
+		goto out;
+	}
+
+	rw_enter(&zfs_snapshot_lock, RW_WRITER);
+
+	error = dsl_dataset_rename_snapshot(fsname, snm, tnm, B_FALSE);
+	if (error == 0)
+		(void) zfsctl_snapshot_rename(snm, tnm);
+
+	rw_exit(&zfs_snapshot_lock);
+out:
+	kmem_free(from, MAXNAMELEN);
+	kmem_free(to, MAXNAMELEN);
+	kmem_free(real, MAXNAMELEN);
+	kmem_free(fsname, MAXNAMELEN);
+
+	ZFS_EXIT(zsb);
+
+	return (error);
+}
+
+/*
+ * Removing a directory under '.zfs/snapshot' will automatically trigger
+ * the removal of the snapshot with the given name.
+ */
+int
+zfsctl_snapdir_remove(struct inode *dip, char *name, cred_t *cr, int flags)
+{
+	zfs_sb_t *zsb = ITOZSB(dip);
+	char *snapname, *real;
+	int error;
+
+	if (!zfs_admin_snapshot)
+		return (EACCES);
+
+	ZFS_ENTER(zsb);
+
+	snapname = kmem_alloc(MAXNAMELEN, KM_SLEEP);
+	real = kmem_alloc(MAXNAMELEN, KM_SLEEP);
+
+	if (zsb->z_case == ZFS_CASE_INSENSITIVE) {
+		error = dmu_snapshot_realname(zsb->z_os, name, real,
+		    MAXNAMELEN, NULL);
+		if (error == 0) {
+			name = real;
+		} else if (error != ENOTSUP) {
+			goto out;
+		}
+	}
+
+	error = zfsctl_snapshot_name(ITOZSB(dip), name, MAXNAMELEN, snapname);
+	if (error == 0)
+		error = zfs_secpolicy_destroy_perms(snapname, cr);
+	if (error != 0)
+		goto out;
+
+	error = zfsctl_snapshot_unmount(snapname, MNT_FORCE);
+	if ((error == 0) || (error == ENOENT))
+		error = dsl_destroy_snapshot(snapname, B_FALSE);
+out:
+	kmem_free(snapname, MAXNAMELEN);
+	kmem_free(real, MAXNAMELEN);
+
+	ZFS_EXIT(zsb);
+
+	return (error);
+}
+
+/*
+ * Creating a directory under '.zfs/snapshot' will automatically trigger
+ * the creation of a new snapshot with the given name.
+ */
+int
+zfsctl_snapdir_mkdir(struct inode *dip, char *dirname, vattr_t *vap,
+	struct inode **ipp, cred_t *cr, int flags)
+{
+	zfs_sb_t *zsb = ITOZSB(dip);
+	char *dsname;
+	int error;
+
+	if (!zfs_admin_snapshot)
+		return (EACCES);
+
+	dsname = kmem_alloc(MAXNAMELEN, KM_SLEEP);
+
+	if (zfs_component_namecheck(dirname, NULL, NULL) != 0) {
+		error = SET_ERROR(EILSEQ);
+		goto out;
+	}
+
+	dmu_objset_name(zsb->z_os, dsname);
+
+	error = zfs_secpolicy_snapshot_perms(dsname, cr);
+	if (error != 0)
+		goto out;
+
+	if (error == 0) {
+		error = dmu_objset_snapshot_one(dsname, dirname);
+		if (error != 0)
+			goto out;
+
+		error = zfsctl_snapdir_lookup(dip, dirname, ipp,
+		    0, cr, NULL, NULL);
+	}
+out:
+	kmem_free(dsname, MAXNAMELEN);
+
+	return (error);
+}
+
+/*
+ * Attempt to unmount a snapshot by making a call to user space.
+ * There is no assurance that this can or will succeed, is just a
+ * best effort.  In the case where it does fail, perhaps because
+ * it's in use, the unmount will fail harmlessly.
+ */
+#define	SET_UNMOUNT_CMD \
+	"exec 0</dev/null " \
+	"     1>/dev/null " \
+	"     2>/dev/null; " \
+	"umount -t zfs -n %s'%s'"
+
+int
+zfsctl_snapshot_unmount(char *snapname, int flags)
+{
+	char *argv[] = { "/bin/sh", "-c", NULL, NULL };
+	char *envp[] = { NULL };
+	zfs_snapentry_t *se;
+	int error;
+
+	rw_enter(&zfs_snapshot_lock, RW_READER);
+	if ((se = zfsctl_snapshot_find_by_name(snapname)) == NULL) {
+		rw_exit(&zfs_snapshot_lock);
+		return (ENOENT);
+	}
+	rw_exit(&zfs_snapshot_lock);
+
+	argv[2] = kmem_asprintf(SET_UNMOUNT_CMD,
+	    flags & MNT_FORCE ? "-f " : "", se->se_path);
+	zfsctl_snapshot_rele(se);
+	dprintf("unmount; path=%s\n", se->se_path);
+	error = call_usermodehelper(argv[0], argv, envp, UMH_WAIT_PROC);
+	strfree(argv[2]);
+
+
+	/*
+	 * The umount system utility will return 256 on error.  We must
+	 * assume this error is because the file system is busy so it is
+	 * converted to the more sensible EBUSY.
+	 */
+	if (error)
+		error = SET_ERROR(EBUSY);
+
+	return (error);
+}
+
+#define	MOUNT_BUSY 0x80		/* Mount failed due to EBUSY (from mntent.h) */
+#define	SET_MOUNT_CMD \
+	"exec 0</dev/null " \
+	"     1>/dev/null " \
+	"     2>/dev/null; " \
+	"mount -t zfs -n '%s' '%s'"
+
+int
+zfsctl_snapshot_mount(struct path *path, int flags)
+{
+	struct dentry *dentry = path->dentry;
+	struct inode *ip = dentry->d_inode;
+	zfs_sb_t *zsb;
+	zfs_sb_t *snap_zsb;
+	zfs_snapentry_t *se;
+	char *full_name, *full_path;
+	char *argv[] = { "/bin/sh", "-c", NULL, NULL };
+	char *envp[] = { NULL };
+	int error;
+	struct path spath;
+
+	if (ip == NULL)
+		return (EISDIR);
+
+	zsb = ITOZSB(ip);
+	ZFS_ENTER(zsb);
+
+	full_name = kmem_zalloc(MAXNAMELEN, KM_SLEEP);
+	full_path = kmem_zalloc(MAXPATHLEN, KM_SLEEP);
+
+	error = zfsctl_snapshot_name(zsb, dname(dentry),
+	    MAXNAMELEN, full_name);
+	if (error)
+		goto error;
+
+	error = zfsctl_snapshot_path(path, MAXPATHLEN, full_path);
+	if (error)
+		goto error;
+
+	/*
+	 * Multiple concurrent automounts of a snapshot are never allowed.
+	 * The snapshot may be manually mounted as many times as desired.
+	 */
+	if (zfsctl_snapshot_ismounted(full_name)) {
+		error = 0;
+		goto error;
+	}
+
+	/*
+	 * Attempt to mount the snapshot from user space.  Normally this
+	 * would be done using the vfs_kern_mount() function, however that
+	 * function is marked GPL-only and cannot be used.  On error we
+	 * careful to log the real error to the console and return EISDIR
+	 * to safely abort the automount.  This should be very rare.
+	 *
+	 * If the user mode helper happens to return EBUSY, a concurrent
+	 * mount is already in progress in which case the error is ignored.
+	 * Take note that if the program was executed successfully the return
+	 * value from call_usermodehelper() will be (exitcode << 8 + signal).
+	 */
+	dprintf("mount; name=%s path=%s\n", full_name, full_path);
+	argv[2] = kmem_asprintf(SET_MOUNT_CMD, full_name, full_path);
+	error = call_usermodehelper(argv[0], argv, envp, UMH_WAIT_PROC);
+	strfree(argv[2]);
+	if (error) {
+		if (!(error & MOUNT_BUSY << 8)) {
+			cmn_err(CE_WARN, "Unable to automount %s/%s: %d",
+			    full_path, full_name, error);
+			error = SET_ERROR(EISDIR);
+		} else {
+			/*
+			 * EBUSY, this could mean a concurrent mount, or the
+			 * snapshot has already been mounted at completely
+			 * different place. We return 0 so VFS will retry. For
+			 * the latter case the VFS will retry several times
+			 * and return ELOOP, which is probably not a very good
+			 * behavior.
+			 */
+			error = 0;
+		}
+		goto error;
+	}
+
+	/*
+	 * Follow down in to the mounted snapshot and set MNT_SHRINKABLE
+	 * to identify this as an automounted filesystem.
+	 */
+	spath = *path;
+	path_get(&spath);
+	if (zpl_follow_down_one(&spath)) {
+		snap_zsb = ITOZSB(spath.dentry->d_inode);
+		snap_zsb->z_parent = zsb;
+		dentry = spath.dentry;
+		spath.mnt->mnt_flags |= MNT_SHRINKABLE;
+
+		rw_enter(&zfs_snapshot_lock, RW_WRITER);
+		se = zfsctl_snapshot_alloc(full_name, full_path,
+		    snap_zsb->z_os->os_spa, dmu_objset_id(snap_zsb->z_os),
+		    dentry);
+		zfsctl_snapshot_add(se);
+		zfsctl_snapshot_unmount_delay_impl(se, zfs_expire_snapshot);
+		rw_exit(&zfs_snapshot_lock);
+	}
+	path_put(&spath);
+error:
+	kmem_free(full_name, MAXNAMELEN);
+	kmem_free(full_path, MAXPATHLEN);
+
+	ZFS_EXIT(zsb);
+
+	return (error);
+}
+
+/*
+ * Given the objset id of the snapshot return its zfs_sb_t as zsbp.
+ */
+int
+zfsctl_lookup_objset(struct super_block *sb, uint64_t objsetid, zfs_sb_t **zsbp)
+{
+	zfs_snapentry_t *se;
+	int error;
+	spa_t *spa = ((zfs_sb_t *)(sb->s_fs_info))->z_os->os_spa;
+
+	/*
+	 * Verify that the snapshot is mounted then lookup the mounted root
+	 * rather than the covered mount point.  This may fail if the
+	 * snapshot has just been unmounted by an unrelated user space
+	 * process.  This race cannot occur to an expired mount point
+	 * because we hold the zfs_snapshot_lock to prevent the race.
+	 */
+	rw_enter(&zfs_snapshot_lock, RW_READER);
+	if ((se = zfsctl_snapshot_find_by_objsetid(spa, objsetid)) != NULL) {
+		zfs_sb_t *zsb;
+
+		zsb = ITOZSB(se->se_root_dentry->d_inode);
+		ASSERT3U(dmu_objset_id(zsb->z_os), ==, objsetid);
+
+		if (time_after(jiffies, zsb->z_snap_defer_time +
+		    MAX(zfs_expire_snapshot * HZ / 2, HZ))) {
+			zsb->z_snap_defer_time = jiffies;
+			zfsctl_snapshot_unmount_cancel(se);
+			zfsctl_snapshot_unmount_delay_impl(se,
+			    zfs_expire_snapshot);
+		}
+
+		*zsbp = zsb;
+		zfsctl_snapshot_rele(se);
+		error = SET_ERROR(0);
+	} else {
+		error = SET_ERROR(ENOENT);
+	}
+	rw_exit(&zfs_snapshot_lock);
+
+	/*
+	 * Automount the snapshot given the objset id by constructing the
+	 * full mount point and performing a traversal.
+	 */
+	if (error == ENOENT) {
+		struct path path;
+		char *mnt;
+
+		mnt = kmem_alloc(MAXPATHLEN, KM_SLEEP);
+		error = zfsctl_snapshot_path_objset(sb->s_fs_info, objsetid,
+		    MAXPATHLEN, mnt);
+		if (error) {
+			kmem_free(mnt, MAXPATHLEN);
+			return (SET_ERROR(error));
+		}
+
+		error = kern_path(mnt, LOOKUP_FOLLOW|LOOKUP_DIRECTORY, &path);
+		if (error == 0) {
+			*zsbp = ITOZSB(path.dentry->d_inode);
+			path_put(&path);
+		}
+
+		kmem_free(mnt, MAXPATHLEN);
+	}
+
+	return (error);
+}
+
+int
+zfsctl_shares_lookup(struct inode *dip, char *name, struct inode **ipp,
+    int flags, cred_t *cr, int *direntflags, pathname_t *realpnp)
+{
+	zfs_sb_t *zsb = ITOZSB(dip);
+	struct inode *ip;
+	znode_t *dzp;
+	int error;
+
+	ZFS_ENTER(zsb);
+
+	if (zsb->z_shares_dir == 0) {
+		ZFS_EXIT(zsb);
+		return (SET_ERROR(ENOTSUP));
+	}
+
+	error = zfs_zget(zsb, zsb->z_shares_dir, &dzp);
+	if (error) {
+		ZFS_EXIT(zsb);
+		return (error);
+	}
+
+	error = zfs_lookup(ZTOI(dzp), name, &ip, 0, cr, NULL, NULL);
+
+	iput(ZTOI(dzp));
+	ZFS_EXIT(zsb);
+
+	return (error);
+}
+
+
+/*
+ * Initialize the various pieces we'll need to create and manipulate .zfs
+ * directories.  Currently this is unused but available.
+ */
+void
+zfsctl_init(void)
+{
+	avl_create(&zfs_snapshots_by_name, snapentry_compare_by_name,
+	    sizeof (zfs_snapentry_t), offsetof(zfs_snapentry_t,
+	    se_node_name));
+	avl_create(&zfs_snapshots_by_objsetid, snapentry_compare_by_objsetid,
+	    sizeof (zfs_snapentry_t), offsetof(zfs_snapentry_t,
+	    se_node_objsetid));
+	rw_init(&zfs_snapshot_lock, NULL, RW_DEFAULT, NULL);
+
+	zfs_expire_taskq = taskq_create("z_unmount", 1, defclsyspri,
+	    1, 8, TASKQ_PREPOPULATE);
+}
+
+/*
+ * Cleanup the various pieces we needed for .zfs directories.  In particular
+ * ensure the expiry timer is canceled safely.
+ */
+void
+zfsctl_fini(void)
+{
+	taskq_destroy(zfs_expire_taskq);
+
+	avl_destroy(&zfs_snapshots_by_name);
+	avl_destroy(&zfs_snapshots_by_objsetid);
+	rw_destroy(&zfs_snapshot_lock);
+}
+
+module_param(zfs_admin_snapshot, int, 0644);
+MODULE_PARM_DESC(zfs_admin_snapshot, "Enable mkdir/rmdir/mv in .zfs/snapshot");
+
+module_param(zfs_expire_snapshot, int, 0644);
+MODULE_PARM_DESC(zfs_expire_snapshot, "Seconds to expire .zfs/snapshot");
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/module/zfs/zfs_debug.c
@@ -0,0 +1,239 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2014 by Delphix. All rights reserved.
+ */
+
+#include <sys/zfs_context.h>
+#include <sys/kstat.h>
+
+list_t zfs_dbgmsgs;
+int zfs_dbgmsg_size = 0;
+kmutex_t zfs_dbgmsgs_lock;
+int zfs_dbgmsg_maxsize = 4<<20; /* 4MB */
+kstat_t *zfs_dbgmsg_kstat;
+
+/*
+ * By default only enable the internal ZFS debug messages when running
+ * in userspace (ztest).  The kernel log must be manually enabled.
+ *
+ * # Enable the kernel debug message log.
+ * echo 1 > /sys/module/zfs/parameters/zfs_dbgmsg_enable
+ *
+ * # Clear the kernel debug message log.
+ * echo 0 >/proc/spl/kstat/zfs/dbgmsg
+ */
+#if defined(_KERNEL)
+int zfs_dbgmsg_enable = 0;
+#else
+int zfs_dbgmsg_enable = 1;
+#endif
+
+static int
+zfs_dbgmsg_headers(char *buf, size_t size)
+{
+	(void) snprintf(buf, size, "%-12s %-8s\n", "timestamp", "message");
+
+	return (0);
+}
+
+static int
+zfs_dbgmsg_data(char *buf, size_t size, void *data)
+{
+	zfs_dbgmsg_t *zdm = (zfs_dbgmsg_t *)data;
+
+	(void) snprintf(buf, size, "%-12llu %-s\n",
+	    (u_longlong_t) zdm->zdm_timestamp, zdm->zdm_msg);
+
+	return (0);
+}
+
+static void *
+zfs_dbgmsg_addr(kstat_t *ksp, loff_t n)
+{
+	zfs_dbgmsg_t *zdm = (zfs_dbgmsg_t *)ksp->ks_private;
+
+	ASSERT(MUTEX_HELD(&zfs_dbgmsgs_lock));
+
+	if (n == 0)
+		ksp->ks_private = list_head(&zfs_dbgmsgs);
+	else if (zdm)
+		ksp->ks_private = list_next(&zfs_dbgmsgs, zdm);
+
+	return (ksp->ks_private);
+}
+
+static void
+zfs_dbgmsg_purge(int max_size)
+{
+	zfs_dbgmsg_t *zdm;
+	int size;
+
+	ASSERT(MUTEX_HELD(&zfs_dbgmsgs_lock));
+
+	while (zfs_dbgmsg_size > max_size) {
+		zdm = list_remove_head(&zfs_dbgmsgs);
+		if (zdm == NULL)
+			return;
+
+		size = zdm->zdm_size;
+		kmem_free(zdm, size);
+		zfs_dbgmsg_size -= size;
+	}
+}
+
+static int
+zfs_dbgmsg_update(kstat_t *ksp, int rw)
+{
+	if (rw == KSTAT_WRITE)
+		zfs_dbgmsg_purge(0);
+
+	return (0);
+}
+
+void
+zfs_dbgmsg_init(void)
+{
+	list_create(&zfs_dbgmsgs, sizeof (zfs_dbgmsg_t),
+	    offsetof(zfs_dbgmsg_t, zdm_node));
+	mutex_init(&zfs_dbgmsgs_lock, NULL, MUTEX_DEFAULT, NULL);
+
+	zfs_dbgmsg_kstat = kstat_create("zfs", 0, "dbgmsg", "misc",
+	    KSTAT_TYPE_RAW, 0, KSTAT_FLAG_VIRTUAL);
+	if (zfs_dbgmsg_kstat) {
+		zfs_dbgmsg_kstat->ks_lock = &zfs_dbgmsgs_lock;
+		zfs_dbgmsg_kstat->ks_ndata = UINT32_MAX;
+		zfs_dbgmsg_kstat->ks_private = NULL;
+		zfs_dbgmsg_kstat->ks_update = zfs_dbgmsg_update;
+		kstat_set_raw_ops(zfs_dbgmsg_kstat, zfs_dbgmsg_headers,
+		    zfs_dbgmsg_data, zfs_dbgmsg_addr);
+		kstat_install(zfs_dbgmsg_kstat);
+	}
+}
+
+void
+zfs_dbgmsg_fini(void)
+{
+	if (zfs_dbgmsg_kstat)
+		kstat_delete(zfs_dbgmsg_kstat);
+
+	mutex_enter(&zfs_dbgmsgs_lock);
+	zfs_dbgmsg_purge(0);
+	mutex_exit(&zfs_dbgmsgs_lock);
+	mutex_destroy(&zfs_dbgmsgs_lock);
+}
+
+void
+__zfs_dbgmsg(char *buf)
+{
+	zfs_dbgmsg_t *zdm;
+	int size;
+
+	size = sizeof (zfs_dbgmsg_t) + strlen(buf);
+	zdm = kmem_zalloc(size, KM_SLEEP);
+	zdm->zdm_size = size;
+	zdm->zdm_timestamp = gethrestime_sec();
+	strcpy(zdm->zdm_msg, buf);
+
+	mutex_enter(&zfs_dbgmsgs_lock);
+	list_insert_tail(&zfs_dbgmsgs, zdm);
+	zfs_dbgmsg_size += size;
+	zfs_dbgmsg_purge(MAX(zfs_dbgmsg_maxsize, 0));
+	mutex_exit(&zfs_dbgmsgs_lock);
+}
+
+#ifdef _KERNEL
+void
+__dprintf(const char *file, const char *func, int line, const char *fmt, ...)
+{
+	const char *newfile;
+	va_list adx;
+	size_t size;
+	char *buf;
+	char *nl;
+
+	if (!zfs_dbgmsg_enable && !(zfs_flags & ZFS_DEBUG_DPRINTF))
+		return;
+
+	size = 1024;
+	buf = kmem_alloc(size, KM_SLEEP);
+
+	/*
+	 * Get rid of annoying prefix to filename.
+	 */
+	newfile = strrchr(file, '/');
+	if (newfile != NULL) {
+		newfile = newfile + 1; /* Get rid of leading / */
+	} else {
+		newfile = file;
+	}
+
+	va_start(adx, fmt);
+	(void) vsnprintf(buf, size, fmt, adx);
+	va_end(adx);
+
+	/*
+	 * Get rid of trailing newline.
+	 */
+	nl = strrchr(buf, '\n');
+	if (nl != NULL)
+		*nl = '\0';
+
+	/*
+	 * To get this data enable the zfs__dprintf trace point as shown:
+	 *
+	 * # Enable zfs__dprintf tracepoint, clear the tracepoint ring buffer
+	 * $ echo 1 > /sys/module/zfs/parameters/zfs_flags
+	 * $ echo 1 > /sys/kernel/debug/tracing/events/zfs/enable
+	 * $ echo 0 > /sys/kernel/debug/tracing/trace
+	 *
+	 * # Dump the ring buffer.
+	 * $ cat /sys/kernel/debug/tracing/trace
+	 */
+	if (zfs_flags & ZFS_DEBUG_DPRINTF)
+		DTRACE_PROBE4(zfs__dprintf,
+		    char *, newfile, char *, func, int, line, char *, buf);
+
+	/*
+	 * To get this data enable the zfs debug log as shown:
+	 *
+	 * # Set zfs_dbgmsg enable, clear the log buffer
+	 * $ echo 1 > /sys/module/zfs/parameters/zfs_dbgmsg_enable
+	 * $ echo 0 > /proc/spl/kstat/zfs/dbgmsg
+	 *
+	 * # Dump the log buffer.
+	 * $ cat /proc/spl/kstat/zfs/dbgmsg
+	 */
+	if (zfs_dbgmsg_enable)
+		__zfs_dbgmsg(buf);
+
+	kmem_free(buf, size);
+}
+#endif /* _KERNEL */
+
+#ifdef _KERNEL
+module_param(zfs_dbgmsg_enable, int, 0644);
+MODULE_PARM_DESC(zfs_dbgmsg_enable, "Enable ZFS debug message log");
+
+module_param(zfs_dbgmsg_maxsize, int, 0644);
+MODULE_PARM_DESC(zfs_dbgmsg_maxsize, "Maximum ZFS debug log size");
+#endif
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/module/zfs/zfs_dir.c
@@ -0,0 +1,1099 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013 by Delphix. All rights reserved.
+ */
+
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/time.h>
+#include <sys/systm.h>
+#include <sys/sysmacros.h>
+#include <sys/resource.h>
+#include <sys/vfs.h>
+#include <sys/vnode.h>
+#include <sys/file.h>
+#include <sys/mode.h>
+#include <sys/kmem.h>
+#include <sys/uio.h>
+#include <sys/pathname.h>
+#include <sys/cmn_err.h>
+#include <sys/errno.h>
+#include <sys/stat.h>
+#include <sys/unistd.h>
+#include <sys/sunddi.h>
+#include <sys/random.h>
+#include <sys/policy.h>
+#include <sys/zfs_dir.h>
+#include <sys/zfs_acl.h>
+#include <sys/zfs_vnops.h>
+#include <sys/fs/zfs.h>
+#include "fs/fs_subr.h"
+#include <sys/zap.h>
+#include <sys/dmu.h>
+#include <sys/atomic.h>
+#include <sys/zfs_ctldir.h>
+#include <sys/zfs_fuid.h>
+#include <sys/sa.h>
+#include <sys/zfs_sa.h>
+#include <sys/dnlc.h>
+#include <sys/extdirent.h>
+
+/*
+ * zfs_match_find() is used by zfs_dirent_lock() to peform zap lookups
+ * of names after deciding which is the appropriate lookup interface.
+ */
+static int
+zfs_match_find(zfs_sb_t *zsb, znode_t *dzp, char *name, boolean_t exact,
+    boolean_t update, int *deflags, pathname_t *rpnp, uint64_t *zoid)
+{
+	boolean_t conflict = B_FALSE;
+	int error;
+
+	if (zsb->z_norm) {
+		matchtype_t mt = MT_FIRST;
+		size_t bufsz = 0;
+		char *buf = NULL;
+
+		if (rpnp) {
+			buf = rpnp->pn_buf;
+			bufsz = rpnp->pn_bufsize;
+		}
+		if (exact)
+			mt = MT_EXACT;
+		/*
+		 * In the non-mixed case we only expect there would ever
+		 * be one match, but we need to use the normalizing lookup.
+		 */
+		error = zap_lookup_norm(zsb->z_os, dzp->z_id, name, 8, 1,
+		    zoid, mt, buf, bufsz, &conflict);
+	} else {
+		error = zap_lookup(zsb->z_os, dzp->z_id, name, 8, 1, zoid);
+	}
+
+	/*
+	 * Allow multiple entries provided the first entry is
+	 * the object id.  Non-zpl consumers may safely make
+	 * use of the additional space.
+	 *
+	 * XXX: This should be a feature flag for compatibility
+	 */
+	if (error == EOVERFLOW)
+		error = 0;
+
+	if (zsb->z_norm && !error && deflags)
+		*deflags = conflict ? ED_CASE_CONFLICT : 0;
+
+	*zoid = ZFS_DIRENT_OBJ(*zoid);
+
+#ifdef HAVE_DNLC
+	if (error == ENOENT && update)
+		dnlc_update(ZTOI(dzp), name, DNLC_NO_VNODE);
+#endif /* HAVE_DNLC */
+
+	return (error);
+}
+
+/*
+ * Lock a directory entry.  A dirlock on <dzp, name> protects that name
+ * in dzp's directory zap object.  As long as you hold a dirlock, you can
+ * assume two things: (1) dzp cannot be reaped, and (2) no other thread
+ * can change the zap entry for (i.e. link or unlink) this name.
+ *
+ * Input arguments:
+ *	dzp	- znode for directory
+ *	name	- name of entry to lock
+ *	flag	- ZNEW: if the entry already exists, fail with EEXIST.
+ *		  ZEXISTS: if the entry does not exist, fail with ENOENT.
+ *		  ZSHARED: allow concurrent access with other ZSHARED callers.
+ *		  ZXATTR: we want dzp's xattr directory
+ *		  ZCILOOK: On a mixed sensitivity file system,
+ *			   this lookup should be case-insensitive.
+ *		  ZCIEXACT: On a purely case-insensitive file system,
+ *			    this lookup should be case-sensitive.
+ *		  ZRENAMING: we are locking for renaming, force narrow locks
+ *		  ZHAVELOCK: Don't grab the z_name_lock for this call. The
+ *			     current thread already holds it.
+ *
+ * Output arguments:
+ *	zpp	- pointer to the znode for the entry (NULL if there isn't one)
+ *	dlpp	- pointer to the dirlock for this entry (NULL on error)
+ *      direntflags - (case-insensitive lookup only)
+ *		flags if multiple case-sensitive matches exist in directory
+ *      realpnp     - (case-insensitive lookup only)
+ *		actual name matched within the directory
+ *
+ * Return value: 0 on success or errno on failure.
+ *
+ * NOTE: Always checks for, and rejects, '.' and '..'.
+ * NOTE: For case-insensitive file systems we take wide locks (see below),
+ *	 but return znode pointers to a single match.
+ */
+int
+zfs_dirent_lock(zfs_dirlock_t **dlpp, znode_t *dzp, char *name, znode_t **zpp,
+    int flag, int *direntflags, pathname_t *realpnp)
+{
+	zfs_sb_t	*zsb = ZTOZSB(dzp);
+	zfs_dirlock_t	*dl;
+	boolean_t	update;
+	boolean_t	exact;
+	uint64_t	zoid;
+#ifdef HAVE_DNLC
+	vnode_t		*vp = NULL;
+#endif /* HAVE_DNLC */
+	int		error = 0;
+	int		cmpflags;
+
+	*zpp = NULL;
+	*dlpp = NULL;
+
+	/*
+	 * Verify that we are not trying to lock '.', '..', or '.zfs'
+	 */
+	if ((name[0] == '.' &&
+	    (name[1] == '\0' || (name[1] == '.' && name[2] == '\0'))) ||
+	    (zfs_has_ctldir(dzp) && strcmp(name, ZFS_CTLDIR_NAME) == 0))
+		return (SET_ERROR(EEXIST));
+
+	/*
+	 * Case sensitivity and normalization preferences are set when
+	 * the file system is created.  These are stored in the
+	 * zsb->z_case and zsb->z_norm fields.  These choices
+	 * affect what vnodes can be cached in the DNLC, how we
+	 * perform zap lookups, and the "width" of our dirlocks.
+	 *
+	 * A normal dirlock locks a single name.  Note that with
+	 * normalization a name can be composed multiple ways, but
+	 * when normalized, these names all compare equal.  A wide
+	 * dirlock locks multiple names.  We need these when the file
+	 * system is supporting mixed-mode access.  It is sometimes
+	 * necessary to lock all case permutations of file name at
+	 * once so that simultaneous case-insensitive/case-sensitive
+	 * behaves as rationally as possible.
+	 */
+
+	/*
+	 * Decide if exact matches should be requested when performing
+	 * a zap lookup on file systems supporting case-insensitive
+	 * access.
+	 */
+	exact =
+	    ((zsb->z_case == ZFS_CASE_INSENSITIVE) && (flag & ZCIEXACT)) ||
+	    ((zsb->z_case == ZFS_CASE_MIXED) && !(flag & ZCILOOK));
+
+	/*
+	 * Only look in or update the DNLC if we are looking for the
+	 * name on a file system that does not require normalization
+	 * or case folding.  We can also look there if we happen to be
+	 * on a non-normalizing, mixed sensitivity file system IF we
+	 * are looking for the exact name.
+	 *
+	 * Maybe can add TO-UPPERed version of name to dnlc in ci-only
+	 * case for performance improvement?
+	 */
+	update = !zsb->z_norm ||
+	    ((zsb->z_case == ZFS_CASE_MIXED) &&
+	    !(zsb->z_norm & ~U8_TEXTPREP_TOUPPER) && !(flag & ZCILOOK));
+
+	/*
+	 * ZRENAMING indicates we are in a situation where we should
+	 * take narrow locks regardless of the file system's
+	 * preferences for normalizing and case folding.  This will
+	 * prevent us deadlocking trying to grab the same wide lock
+	 * twice if the two names happen to be case-insensitive
+	 * matches.
+	 */
+	if (flag & ZRENAMING)
+		cmpflags = 0;
+	else
+		cmpflags = zsb->z_norm;
+
+	/*
+	 * Wait until there are no locks on this name.
+	 *
+	 * Don't grab the the lock if it is already held. However, cannot
+	 * have both ZSHARED and ZHAVELOCK together.
+	 */
+	ASSERT(!(flag & ZSHARED) || !(flag & ZHAVELOCK));
+	if (!(flag & ZHAVELOCK))
+		rw_enter(&dzp->z_name_lock, RW_READER);
+
+	mutex_enter(&dzp->z_lock);
+	for (;;) {
+		if (dzp->z_unlinked) {
+			mutex_exit(&dzp->z_lock);
+			if (!(flag & ZHAVELOCK))
+				rw_exit(&dzp->z_name_lock);
+			return (SET_ERROR(ENOENT));
+		}
+		for (dl = dzp->z_dirlocks; dl != NULL; dl = dl->dl_next) {
+			if ((u8_strcmp(name, dl->dl_name, 0, cmpflags,
+			    U8_UNICODE_LATEST, &error) == 0) || error != 0)
+				break;
+		}
+		if (error != 0) {
+			mutex_exit(&dzp->z_lock);
+			if (!(flag & ZHAVELOCK))
+				rw_exit(&dzp->z_name_lock);
+			return (SET_ERROR(ENOENT));
+		}
+		if (dl == NULL)	{
+			/*
+			 * Allocate a new dirlock and add it to the list.
+			 */
+			dl = kmem_alloc(sizeof (zfs_dirlock_t), KM_SLEEP);
+			cv_init(&dl->dl_cv, NULL, CV_DEFAULT, NULL);
+			dl->dl_name = name;
+			dl->dl_sharecnt = 0;
+			dl->dl_namelock = 0;
+			dl->dl_namesize = 0;
+			dl->dl_dzp = dzp;
+			dl->dl_next = dzp->z_dirlocks;
+			dzp->z_dirlocks = dl;
+			break;
+		}
+		if ((flag & ZSHARED) && dl->dl_sharecnt != 0)
+			break;
+		cv_wait(&dl->dl_cv, &dzp->z_lock);
+	}
+
+	/*
+	 * If the z_name_lock was NOT held for this dirlock record it.
+	 */
+	if (flag & ZHAVELOCK)
+		dl->dl_namelock = 1;
+
+	if ((flag & ZSHARED) && ++dl->dl_sharecnt > 1 && dl->dl_namesize == 0) {
+		/*
+		 * We're the second shared reference to dl.  Make a copy of
+		 * dl_name in case the first thread goes away before we do.
+		 * Note that we initialize the new name before storing its
+		 * pointer into dl_name, because the first thread may load
+		 * dl->dl_name at any time.  He'll either see the old value,
+		 * which is his, or the new shared copy; either is OK.
+		 */
+		dl->dl_namesize = strlen(dl->dl_name) + 1;
+		name = kmem_alloc(dl->dl_namesize, KM_SLEEP);
+		bcopy(dl->dl_name, name, dl->dl_namesize);
+		dl->dl_name = name;
+	}
+
+	mutex_exit(&dzp->z_lock);
+
+	/*
+	 * We have a dirlock on the name.  (Note that it is the dirlock,
+	 * not the dzp's z_lock, that protects the name in the zap object.)
+	 * See if there's an object by this name; if so, put a hold on it.
+	 */
+	if (flag & ZXATTR) {
+		error = sa_lookup(dzp->z_sa_hdl, SA_ZPL_XATTR(zsb), &zoid,
+		    sizeof (zoid));
+		if (error == 0)
+			error = (zoid == 0 ? SET_ERROR(ENOENT) : 0);
+	} else {
+#ifdef HAVE_DNLC
+		if (update)
+			vp = dnlc_lookup(ZTOI(dzp), name);
+		if (vp == DNLC_NO_VNODE) {
+			iput(vp);
+			error = SET_ERROR(ENOENT);
+		} else if (vp) {
+			if (flag & ZNEW) {
+				zfs_dirent_unlock(dl);
+				iput(vp);
+				return (SET_ERROR(EEXIST));
+			}
+			*dlpp = dl;
+			*zpp = VTOZ(vp);
+			return (0);
+		} else {
+			error = zfs_match_find(zsb, dzp, name, exact,
+			    update, direntflags, realpnp, &zoid);
+		}
+#else
+		error = zfs_match_find(zsb, dzp, name, exact,
+		    update, direntflags, realpnp, &zoid);
+#endif /* HAVE_DNLC */
+	}
+	if (error) {
+		if (error != ENOENT || (flag & ZEXISTS)) {
+			zfs_dirent_unlock(dl);
+			return (error);
+		}
+	} else {
+		if (flag & ZNEW) {
+			zfs_dirent_unlock(dl);
+			return (SET_ERROR(EEXIST));
+		}
+		error = zfs_zget(zsb, zoid, zpp);
+		if (error) {
+			zfs_dirent_unlock(dl);
+			return (error);
+		}
+#ifdef HAVE_DNLC
+		if (!(flag & ZXATTR) && update)
+			dnlc_update(ZTOI(dzp), name, ZTOI(*zpp));
+#endif /* HAVE_DNLC */
+	}
+
+	*dlpp = dl;
+
+	return (0);
+}
+
+/*
+ * Unlock this directory entry and wake anyone who was waiting for it.
+ */
+void
+zfs_dirent_unlock(zfs_dirlock_t *dl)
+{
+	znode_t *dzp = dl->dl_dzp;
+	zfs_dirlock_t **prev_dl, *cur_dl;
+
+	mutex_enter(&dzp->z_lock);
+
+	if (!dl->dl_namelock)
+		rw_exit(&dzp->z_name_lock);
+
+	if (dl->dl_sharecnt > 1) {
+		dl->dl_sharecnt--;
+		mutex_exit(&dzp->z_lock);
+		return;
+	}
+	prev_dl = &dzp->z_dirlocks;
+	while ((cur_dl = *prev_dl) != dl)
+		prev_dl = &cur_dl->dl_next;
+	*prev_dl = dl->dl_next;
+	cv_broadcast(&dl->dl_cv);
+	mutex_exit(&dzp->z_lock);
+
+	if (dl->dl_namesize != 0)
+		kmem_free(dl->dl_name, dl->dl_namesize);
+	cv_destroy(&dl->dl_cv);
+	kmem_free(dl, sizeof (*dl));
+}
+
+/*
+ * Look up an entry in a directory.
+ *
+ * NOTE: '.' and '..' are handled as special cases because
+ *	no directory entries are actually stored for them.  If this is
+ *	the root of a filesystem, then '.zfs' is also treated as a
+ *	special pseudo-directory.
+ */
+int
+zfs_dirlook(znode_t *dzp, char *name, struct inode **ipp, int flags,
+    int *deflg, pathname_t *rpnp)
+{
+	zfs_dirlock_t *dl;
+	znode_t *zp;
+	int error = 0;
+	uint64_t parent;
+
+	if (name[0] == 0 || (name[0] == '.' && name[1] == 0)) {
+		*ipp = ZTOI(dzp);
+		igrab(*ipp);
+	} else if (name[0] == '.' && name[1] == '.' && name[2] == 0) {
+		zfs_sb_t *zsb = ZTOZSB(dzp);
+
+		/*
+		 * If we are a snapshot mounted under .zfs, return
+		 * the inode pointer for the snapshot directory.
+		 */
+		if ((error = sa_lookup(dzp->z_sa_hdl,
+		    SA_ZPL_PARENT(zsb), &parent, sizeof (parent))) != 0)
+			return (error);
+
+		if (parent == dzp->z_id && zsb->z_parent != zsb) {
+			error = zfsctl_root_lookup(zsb->z_parent->z_ctldir,
+			    "snapshot", ipp, 0, kcred, NULL, NULL);
+			return (error);
+		}
+		rw_enter(&dzp->z_parent_lock, RW_READER);
+		error = zfs_zget(zsb, parent, &zp);
+		if (error == 0)
+			*ipp = ZTOI(zp);
+		rw_exit(&dzp->z_parent_lock);
+	} else if (zfs_has_ctldir(dzp) && strcmp(name, ZFS_CTLDIR_NAME) == 0) {
+		*ipp = zfsctl_root(dzp);
+	} else {
+		int zf;
+
+		zf = ZEXISTS | ZSHARED;
+		if (flags & FIGNORECASE)
+			zf |= ZCILOOK;
+
+		error = zfs_dirent_lock(&dl, dzp, name, &zp, zf, deflg, rpnp);
+		if (error == 0) {
+			*ipp = ZTOI(zp);
+			zfs_dirent_unlock(dl);
+			dzp->z_zn_prefetch = B_TRUE; /* enable prefetching */
+		}
+		rpnp = NULL;
+	}
+
+	if ((flags & FIGNORECASE) && rpnp && !error)
+		(void) strlcpy(rpnp->pn_buf, name, rpnp->pn_bufsize);
+
+	return (error);
+}
+
+/*
+ * unlinked Set (formerly known as the "delete queue") Error Handling
+ *
+ * When dealing with the unlinked set, we dmu_tx_hold_zap(), but we
+ * don't specify the name of the entry that we will be manipulating.  We
+ * also fib and say that we won't be adding any new entries to the
+ * unlinked set, even though we might (this is to lower the minimum file
+ * size that can be deleted in a full filesystem).  So on the small
+ * chance that the nlink list is using a fat zap (ie. has more than
+ * 2000 entries), we *may* not pre-read a block that's needed.
+ * Therefore it is remotely possible for some of the assertions
+ * regarding the unlinked set below to fail due to i/o error.  On a
+ * nondebug system, this will result in the space being leaked.
+ */
+void
+zfs_unlinked_add(znode_t *zp, dmu_tx_t *tx)
+{
+	zfs_sb_t *zsb = ZTOZSB(zp);
+
+	ASSERT(zp->z_unlinked);
+	ASSERT(zp->z_links == 0);
+
+	VERIFY3U(0, ==,
+	    zap_add_int(zsb->z_os, zsb->z_unlinkedobj, zp->z_id, tx));
+}
+
+/*
+ * Clean up any znodes that had no links when we either crashed or
+ * (force) umounted the file system.
+ */
+void
+zfs_unlinked_drain(zfs_sb_t *zsb)
+{
+	zap_cursor_t	zc;
+	zap_attribute_t zap;
+	dmu_object_info_t doi;
+	znode_t		*zp;
+	int		error;
+
+	/*
+	 * Iterate over the contents of the unlinked set.
+	 */
+	for (zap_cursor_init(&zc, zsb->z_os, zsb->z_unlinkedobj);
+	    zap_cursor_retrieve(&zc, &zap) == 0;
+	    zap_cursor_advance(&zc)) {
+
+		/*
+		 * See what kind of object we have in list
+		 */
+
+		error = dmu_object_info(zsb->z_os, zap.za_first_integer, &doi);
+		if (error != 0)
+			continue;
+
+		ASSERT((doi.doi_type == DMU_OT_PLAIN_FILE_CONTENTS) ||
+		    (doi.doi_type == DMU_OT_DIRECTORY_CONTENTS));
+		/*
+		 * We need to re-mark these list entries for deletion,
+		 * so we pull them back into core and set zp->z_unlinked.
+		 */
+		error = zfs_zget(zsb, zap.za_first_integer, &zp);
+
+		/*
+		 * We may pick up znodes that are already marked for deletion.
+		 * This could happen during the purge of an extended attribute
+		 * directory.  All we need to do is skip over them, since they
+		 * are already in the system marked z_unlinked.
+		 */
+		if (error != 0)
+			continue;
+
+		zp->z_unlinked = B_TRUE;
+		iput(ZTOI(zp));
+	}
+	zap_cursor_fini(&zc);
+}
+
+/*
+ * Delete the entire contents of a directory.  Return a count
+ * of the number of entries that could not be deleted. If we encounter
+ * an error, return a count of at least one so that the directory stays
+ * in the unlinked set.
+ *
+ * NOTE: this function assumes that the directory is inactive,
+ *	so there is no need to lock its entries before deletion.
+ *	Also, it assumes the directory contents is *only* regular
+ *	files.
+ */
+static int
+zfs_purgedir(znode_t *dzp)
+{
+	zap_cursor_t	zc;
+	zap_attribute_t	zap;
+	znode_t		*xzp;
+	dmu_tx_t	*tx;
+	zfs_sb_t	*zsb = ZTOZSB(dzp);
+	zfs_dirlock_t	dl;
+	int skipped = 0;
+	int error;
+
+	for (zap_cursor_init(&zc, zsb->z_os, dzp->z_id);
+	    (error = zap_cursor_retrieve(&zc, &zap)) == 0;
+	    zap_cursor_advance(&zc)) {
+		error = zfs_zget(zsb,
+		    ZFS_DIRENT_OBJ(zap.za_first_integer), &xzp);
+		if (error) {
+			skipped += 1;
+			continue;
+		}
+
+		ASSERT(S_ISREG(ZTOI(xzp)->i_mode) ||
+		    S_ISLNK(ZTOI(xzp)->i_mode));
+
+		tx = dmu_tx_create(zsb->z_os);
+		dmu_tx_hold_sa(tx, dzp->z_sa_hdl, B_FALSE);
+		dmu_tx_hold_zap(tx, dzp->z_id, FALSE, zap.za_name);
+		dmu_tx_hold_sa(tx, xzp->z_sa_hdl, B_FALSE);
+		dmu_tx_hold_zap(tx, zsb->z_unlinkedobj, FALSE, NULL);
+		/* Is this really needed ? */
+		zfs_sa_upgrade_txholds(tx, xzp);
+		error = dmu_tx_assign(tx, TXG_WAIT);
+		if (error) {
+			dmu_tx_abort(tx);
+			zfs_iput_async(ZTOI(xzp));
+			skipped += 1;
+			continue;
+		}
+		bzero(&dl, sizeof (dl));
+		dl.dl_dzp = dzp;
+		dl.dl_name = zap.za_name;
+
+		error = zfs_link_destroy(&dl, xzp, tx, 0, NULL);
+		if (error)
+			skipped += 1;
+		dmu_tx_commit(tx);
+
+		zfs_iput_async(ZTOI(xzp));
+	}
+	zap_cursor_fini(&zc);
+	if (error != ENOENT)
+		skipped += 1;
+	return (skipped);
+}
+
+void
+zfs_rmnode(znode_t *zp)
+{
+	zfs_sb_t	*zsb = ZTOZSB(zp);
+	objset_t	*os = zsb->z_os;
+	znode_t		*xzp = NULL;
+	dmu_tx_t	*tx;
+	uint64_t	acl_obj;
+	uint64_t	xattr_obj;
+	int		error;
+
+	ASSERT(zp->z_links == 0);
+	ASSERT(atomic_read(&ZTOI(zp)->i_count) == 0);
+
+	/*
+	 * If this is an attribute directory, purge its contents.
+	 */
+	if (S_ISDIR(ZTOI(zp)->i_mode) && (zp->z_pflags & ZFS_XATTR)) {
+		if (zfs_purgedir(zp) != 0) {
+			/*
+			 * Not enough space to delete some xattrs.
+			 * Leave it in the unlinked set.
+			 */
+			zfs_znode_dmu_fini(zp);
+
+			return;
+		}
+	}
+
+	/*
+	 * Free up all the data in the file.  We don't do this for directories
+	 * because we need truncate and remove to be in the same tx, like in
+	 * zfs_znode_delete(). Otherwise, if we crash here we'll end up with
+	 * an inconsistent truncated zap object in the delete queue.  Note a
+	 * truncated file is harmless since it only contains user data.
+	 */
+	if (S_ISREG(ZTOI(zp)->i_mode)) {
+		error = dmu_free_long_range(os, zp->z_id, 0, DMU_OBJECT_END);
+		if (error) {
+			/*
+			 * Not enough space.  Leave the file in the unlinked
+			 * set.
+			 */
+			zfs_znode_dmu_fini(zp);
+			return;
+		}
+	}
+
+	/*
+	 * If the file has extended attributes, we're going to unlink
+	 * the xattr dir.
+	 */
+	error = sa_lookup(zp->z_sa_hdl, SA_ZPL_XATTR(zsb),
+	    &xattr_obj, sizeof (xattr_obj));
+	if (error == 0 && xattr_obj) {
+		error = zfs_zget(zsb, xattr_obj, &xzp);
+		ASSERT(error == 0);
+	}
+
+	acl_obj = zfs_external_acl(zp);
+
+	/*
+	 * Set up the final transaction.
+	 */
+	tx = dmu_tx_create(os);
+	dmu_tx_hold_free(tx, zp->z_id, 0, DMU_OBJECT_END);
+	dmu_tx_hold_zap(tx, zsb->z_unlinkedobj, FALSE, NULL);
+	if (xzp) {
+		dmu_tx_hold_zap(tx, zsb->z_unlinkedobj, TRUE, NULL);
+		dmu_tx_hold_sa(tx, xzp->z_sa_hdl, B_FALSE);
+	}
+	if (acl_obj)
+		dmu_tx_hold_free(tx, acl_obj, 0, DMU_OBJECT_END);
+
+	zfs_sa_upgrade_txholds(tx, zp);
+	error = dmu_tx_assign(tx, TXG_WAIT);
+	if (error) {
+		/*
+		 * Not enough space to delete the file.  Leave it in the
+		 * unlinked set, leaking it until the fs is remounted (at
+		 * which point we'll call zfs_unlinked_drain() to process it).
+		 */
+		dmu_tx_abort(tx);
+		zfs_znode_dmu_fini(zp);
+		goto out;
+	}
+
+	if (xzp) {
+		ASSERT(error == 0);
+		mutex_enter(&xzp->z_lock);
+		xzp->z_unlinked = B_TRUE;	/* mark xzp for deletion */
+		xzp->z_links = 0;	/* no more links to it */
+		VERIFY(0 == sa_update(xzp->z_sa_hdl, SA_ZPL_LINKS(zsb),
+		    &xzp->z_links, sizeof (xzp->z_links), tx));
+		mutex_exit(&xzp->z_lock);
+		zfs_unlinked_add(xzp, tx);
+	}
+
+	/* Remove this znode from the unlinked set */
+	VERIFY3U(0, ==,
+	    zap_remove_int(zsb->z_os, zsb->z_unlinkedobj, zp->z_id, tx));
+
+	zfs_znode_delete(zp, tx);
+
+	dmu_tx_commit(tx);
+out:
+	if (xzp)
+		zfs_iput_async(ZTOI(xzp));
+}
+
+static uint64_t
+zfs_dirent(znode_t *zp, uint64_t mode)
+{
+	uint64_t de = zp->z_id;
+
+	if (ZTOZSB(zp)->z_version >= ZPL_VERSION_DIRENT_TYPE)
+		de |= IFTODT(mode) << 60;
+	return (de);
+}
+
+/*
+ * Link zp into dl.  Can only fail if zp has been unlinked.
+ */
+int
+zfs_link_create(zfs_dirlock_t *dl, znode_t *zp, dmu_tx_t *tx, int flag)
+{
+	znode_t *dzp = dl->dl_dzp;
+	zfs_sb_t *zsb = ZTOZSB(zp);
+	uint64_t value;
+	int zp_is_dir = S_ISDIR(ZTOI(zp)->i_mode);
+	sa_bulk_attr_t bulk[5];
+	uint64_t mtime[2], ctime[2];
+	int count = 0;
+	int error;
+
+	mutex_enter(&zp->z_lock);
+
+	if (!(flag & ZRENAMING)) {
+		if (zp->z_unlinked) {	/* no new links to unlinked zp */
+			ASSERT(!(flag & (ZNEW | ZEXISTS)));
+			mutex_exit(&zp->z_lock);
+			return (SET_ERROR(ENOENT));
+		}
+		zp->z_links++;
+		SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_LINKS(zsb), NULL,
+		    &zp->z_links, sizeof (zp->z_links));
+
+	}
+	SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_PARENT(zsb), NULL,
+	    &dzp->z_id, sizeof (dzp->z_id));
+	SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_FLAGS(zsb), NULL,
+	    &zp->z_pflags, sizeof (zp->z_pflags));
+
+	if (!(flag & ZNEW)) {
+		SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_CTIME(zsb), NULL,
+		    ctime, sizeof (ctime));
+		zfs_tstamp_update_setup(zp, STATE_CHANGED, mtime,
+		    ctime, B_TRUE);
+	}
+	error = sa_bulk_update(zp->z_sa_hdl, bulk, count, tx);
+	ASSERT(error == 0);
+
+	mutex_exit(&zp->z_lock);
+
+	mutex_enter(&dzp->z_lock);
+	dzp->z_size++;
+	dzp->z_links += zp_is_dir;
+	count = 0;
+	SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_SIZE(zsb), NULL,
+	    &dzp->z_size, sizeof (dzp->z_size));
+	SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_LINKS(zsb), NULL,
+	    &dzp->z_links, sizeof (dzp->z_links));
+	SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_MTIME(zsb), NULL,
+	    mtime, sizeof (mtime));
+	SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_CTIME(zsb), NULL,
+	    ctime, sizeof (ctime));
+	SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_FLAGS(zsb), NULL,
+	    &dzp->z_pflags, sizeof (dzp->z_pflags));
+	zfs_tstamp_update_setup(dzp, CONTENT_MODIFIED, mtime, ctime, B_TRUE);
+	error = sa_bulk_update(dzp->z_sa_hdl, bulk, count, tx);
+	ASSERT(error == 0);
+	mutex_exit(&dzp->z_lock);
+
+	value = zfs_dirent(zp, zp->z_mode);
+	error = zap_add(ZTOZSB(zp)->z_os, dzp->z_id, dl->dl_name,
+	    8, 1, &value, tx);
+	ASSERT(error == 0);
+
+	return (0);
+}
+
+static int
+zfs_dropname(zfs_dirlock_t *dl, znode_t *zp, znode_t *dzp, dmu_tx_t *tx,
+    int flag)
+{
+	int error;
+
+	if (ZTOZSB(zp)->z_norm) {
+		if (((ZTOZSB(zp)->z_case == ZFS_CASE_INSENSITIVE) &&
+		    (flag & ZCIEXACT)) ||
+		    ((ZTOZSB(zp)->z_case == ZFS_CASE_MIXED) &&
+		    !(flag & ZCILOOK)))
+			error = zap_remove_norm(ZTOZSB(zp)->z_os,
+			    dzp->z_id, dl->dl_name, MT_EXACT, tx);
+		else
+			error = zap_remove_norm(ZTOZSB(zp)->z_os,
+			    dzp->z_id, dl->dl_name, MT_FIRST, tx);
+	} else {
+		error = zap_remove(ZTOZSB(zp)->z_os,
+		    dzp->z_id, dl->dl_name, tx);
+	}
+
+	return (error);
+}
+
+/*
+ * Unlink zp from dl, and mark zp for deletion if this was the last link. Can
+ * fail if zp is a mount point (EBUSY) or a non-empty directory (ENOTEMPTY).
+ * If 'unlinkedp' is NULL, we put unlinked znodes on the unlinked list.
+ * If it's non-NULL, we use it to indicate whether the znode needs deletion,
+ * and it's the caller's job to do it.
+ */
+int
+zfs_link_destroy(zfs_dirlock_t *dl, znode_t *zp, dmu_tx_t *tx, int flag,
+	boolean_t *unlinkedp)
+{
+	znode_t *dzp = dl->dl_dzp;
+	zfs_sb_t *zsb = ZTOZSB(dzp);
+	int zp_is_dir = S_ISDIR(ZTOI(zp)->i_mode);
+	boolean_t unlinked = B_FALSE;
+	sa_bulk_attr_t bulk[5];
+	uint64_t mtime[2], ctime[2];
+	int count = 0;
+	int error;
+
+#ifdef HAVE_DNLC
+	dnlc_remove(ZTOI(dzp), dl->dl_name);
+#endif /* HAVE_DNLC */
+
+	if (!(flag & ZRENAMING)) {
+		mutex_enter(&zp->z_lock);
+
+		if (zp_is_dir && !zfs_dirempty(zp)) {
+			mutex_exit(&zp->z_lock);
+			return (SET_ERROR(ENOTEMPTY));
+		}
+
+		/*
+		 * If we get here, we are going to try to remove the object.
+		 * First try removing the name from the directory; if that
+		 * fails, return the error.
+		 */
+		error = zfs_dropname(dl, zp, dzp, tx, flag);
+		if (error != 0) {
+			mutex_exit(&zp->z_lock);
+			return (error);
+		}
+
+		if (zp->z_links <= zp_is_dir) {
+			zfs_panic_recover("zfs: link count on %lu is %u, "
+			    "should be at least %u", zp->z_id,
+			    (int)zp->z_links, zp_is_dir + 1);
+			zp->z_links = zp_is_dir + 1;
+		}
+		if (--zp->z_links == zp_is_dir) {
+			zp->z_unlinked = B_TRUE;
+			zp->z_links = 0;
+			unlinked = B_TRUE;
+		} else {
+			SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_CTIME(zsb),
+			    NULL, &ctime, sizeof (ctime));
+			SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_FLAGS(zsb),
+			    NULL, &zp->z_pflags, sizeof (zp->z_pflags));
+			zfs_tstamp_update_setup(zp, STATE_CHANGED, mtime, ctime,
+			    B_TRUE);
+		}
+		SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_LINKS(zsb),
+		    NULL, &zp->z_links, sizeof (zp->z_links));
+		error = sa_bulk_update(zp->z_sa_hdl, bulk, count, tx);
+		count = 0;
+		ASSERT(error == 0);
+		mutex_exit(&zp->z_lock);
+	} else {
+		error = zfs_dropname(dl, zp, dzp, tx, flag);
+		if (error != 0)
+			return (error);
+	}
+
+	mutex_enter(&dzp->z_lock);
+	dzp->z_size--;		/* one dirent removed */
+	dzp->z_links -= zp_is_dir;	/* ".." link from zp */
+	SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_LINKS(zsb),
+	    NULL, &dzp->z_links, sizeof (dzp->z_links));
+	SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_SIZE(zsb),
+	    NULL, &dzp->z_size, sizeof (dzp->z_size));
+	SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_CTIME(zsb),
+	    NULL, ctime, sizeof (ctime));
+	SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_MTIME(zsb),
+	    NULL, mtime, sizeof (mtime));
+	SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_FLAGS(zsb),
+	    NULL, &dzp->z_pflags, sizeof (dzp->z_pflags));
+	zfs_tstamp_update_setup(dzp, CONTENT_MODIFIED, mtime, ctime, B_TRUE);
+	error = sa_bulk_update(dzp->z_sa_hdl, bulk, count, tx);
+	ASSERT(error == 0);
+	mutex_exit(&dzp->z_lock);
+
+	if (unlinkedp != NULL)
+		*unlinkedp = unlinked;
+	else if (unlinked)
+		zfs_unlinked_add(zp, tx);
+
+	return (0);
+}
+
+/*
+ * Indicate whether the directory is empty.  Works with or without z_lock
+ * held, but can only be consider a hint in the latter case.  Returns true
+ * if only "." and ".." remain and there's no work in progress.
+ */
+boolean_t
+zfs_dirempty(znode_t *dzp)
+{
+	return (dzp->z_size == 2 && dzp->z_dirlocks == 0);
+}
+
+int
+zfs_make_xattrdir(znode_t *zp, vattr_t *vap, struct inode **xipp, cred_t *cr)
+{
+	zfs_sb_t *zsb = ZTOZSB(zp);
+	znode_t *xzp;
+	dmu_tx_t *tx;
+	int error;
+	zfs_acl_ids_t acl_ids;
+	boolean_t fuid_dirtied;
+#ifdef DEBUG
+	uint64_t parent;
+#endif
+
+	*xipp = NULL;
+
+	if ((error = zfs_zaccess(zp, ACE_WRITE_NAMED_ATTRS, 0, B_FALSE, cr)))
+		return (error);
+
+	if ((error = zfs_acl_ids_create(zp, IS_XATTR, vap, cr, NULL,
+	    &acl_ids)) != 0)
+		return (error);
+	if (zfs_acl_ids_overquota(zsb, &acl_ids)) {
+		zfs_acl_ids_free(&acl_ids);
+		return (SET_ERROR(EDQUOT));
+	}
+
+	tx = dmu_tx_create(zsb->z_os);
+	dmu_tx_hold_sa_create(tx, acl_ids.z_aclp->z_acl_bytes +
+	    ZFS_SA_BASE_ATTR_SIZE);
+	dmu_tx_hold_sa(tx, zp->z_sa_hdl, B_TRUE);
+	dmu_tx_hold_zap(tx, DMU_NEW_OBJECT, FALSE, NULL);
+	fuid_dirtied = zsb->z_fuid_dirty;
+	if (fuid_dirtied)
+		zfs_fuid_txhold(zsb, tx);
+	error = dmu_tx_assign(tx, TXG_WAIT);
+	if (error) {
+		zfs_acl_ids_free(&acl_ids);
+		dmu_tx_abort(tx);
+		return (error);
+	}
+	zfs_mknode(zp, vap, tx, cr, IS_XATTR, &xzp, &acl_ids);
+
+	if (fuid_dirtied)
+		zfs_fuid_sync(zsb, tx);
+
+#ifdef DEBUG
+	error = sa_lookup(xzp->z_sa_hdl, SA_ZPL_PARENT(zsb),
+	    &parent, sizeof (parent));
+	ASSERT(error == 0 && parent == zp->z_id);
+#endif
+
+	VERIFY(0 == sa_update(zp->z_sa_hdl, SA_ZPL_XATTR(zsb), &xzp->z_id,
+	    sizeof (xzp->z_id), tx));
+
+	(void) zfs_log_create(zsb->z_log, tx, TX_MKXATTR, zp,
+	    xzp, "", NULL, acl_ids.z_fuidp, vap);
+
+	zfs_acl_ids_free(&acl_ids);
+	dmu_tx_commit(tx);
+
+	*xipp = ZTOI(xzp);
+
+	return (0);
+}
+
+/*
+ * Return a znode for the extended attribute directory for zp.
+ * ** If the directory does not already exist, it is created **
+ *
+ *	IN:	zp	- znode to obtain attribute directory from
+ *		cr	- credentials of caller
+ *		flags	- flags from the VOP_LOOKUP call
+ *
+ *	OUT:	xipp	- pointer to extended attribute znode
+ *
+ *	RETURN:	0 on success
+ *		error number on failure
+ */
+int
+zfs_get_xattrdir(znode_t *zp, struct inode **xipp, cred_t *cr, int flags)
+{
+	zfs_sb_t	*zsb = ZTOZSB(zp);
+	znode_t		*xzp;
+	zfs_dirlock_t	*dl;
+	vattr_t		va;
+	int		error;
+top:
+	error = zfs_dirent_lock(&dl, zp, "", &xzp, ZXATTR, NULL, NULL);
+	if (error)
+		return (error);
+
+	if (xzp != NULL) {
+		*xipp = ZTOI(xzp);
+		zfs_dirent_unlock(dl);
+		return (0);
+	}
+
+	if (!(flags & CREATE_XATTR_DIR)) {
+		zfs_dirent_unlock(dl);
+		return (SET_ERROR(ENOENT));
+	}
+
+	if (zfs_is_readonly(zsb)) {
+		zfs_dirent_unlock(dl);
+		return (SET_ERROR(EROFS));
+	}
+
+	/*
+	 * The ability to 'create' files in an attribute
+	 * directory comes from the write_xattr permission on the base file.
+	 *
+	 * The ability to 'search' an attribute directory requires
+	 * read_xattr permission on the base file.
+	 *
+	 * Once in a directory the ability to read/write attributes
+	 * is controlled by the permissions on the attribute file.
+	 */
+	va.va_mask = ATTR_MODE | ATTR_UID | ATTR_GID;
+	va.va_mode = S_IFDIR | S_ISVTX | 0777;
+	zfs_fuid_map_ids(zp, cr, &va.va_uid, &va.va_gid);
+
+	va.va_dentry = NULL;
+	error = zfs_make_xattrdir(zp, &va, xipp, cr);
+	zfs_dirent_unlock(dl);
+
+	if (error == ERESTART) {
+		/* NB: we already did dmu_tx_wait() if necessary */
+		goto top;
+	}
+
+	return (error);
+}
+
+/*
+ * Decide whether it is okay to remove within a sticky directory.
+ *
+ * In sticky directories, write access is not sufficient;
+ * you can remove entries from a directory only if:
+ *
+ *	you own the directory,
+ *	you own the entry,
+ *	the entry is a plain file and you have write access,
+ *	or you are privileged (checked in secpolicy...).
+ *
+ * The function returns 0 if remove access is granted.
+ */
+int
+zfs_sticky_remove_access(znode_t *zdp, znode_t *zp, cred_t *cr)
+{
+	uid_t		uid;
+	uid_t		downer;
+	uid_t		fowner;
+	zfs_sb_t	*zsb = ZTOZSB(zdp);
+
+	if (zsb->z_replay)
+		return (0);
+
+	if ((zdp->z_mode & S_ISVTX) == 0)
+		return (0);
+
+	downer = zfs_fuid_map_id(zsb, zdp->z_uid, cr, ZFS_OWNER);
+	fowner = zfs_fuid_map_id(zsb, zp->z_uid, cr, ZFS_OWNER);
+
+	if ((uid = crgetuid(cr)) == downer || uid == fowner ||
+	    (S_ISDIR(ZTOI(zp)->i_mode) &&
+	    zfs_zaccess(zp, ACE_WRITE_DATA, 0, B_FALSE, cr) == 0))
+		return (0);
+	else
+		return (secpolicy_vnode_remove(cr));
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/module/zfs/zfs_fm.c
@@ -0,0 +1,936 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/*
+ * Copyright (c) 2012 by Delphix. All rights reserved.
+ */
+
+#include <sys/spa.h>
+#include <sys/spa_impl.h>
+#include <sys/vdev.h>
+#include <sys/vdev_impl.h>
+#include <sys/zio.h>
+#include <sys/zio_checksum.h>
+
+#include <sys/fm/fs/zfs.h>
+#include <sys/fm/protocol.h>
+#include <sys/fm/util.h>
+#include <sys/sysevent.h>
+
+/*
+ * This general routine is responsible for generating all the different ZFS
+ * ereports.  The payload is dependent on the class, and which arguments are
+ * supplied to the function:
+ *
+ * 	EREPORT			POOL	VDEV	IO
+ * 	block			X	X	X
+ * 	data			X		X
+ * 	device			X	X
+ * 	pool			X
+ *
+ * If we are in a loading state, all errors are chained together by the same
+ * SPA-wide ENA (Error Numeric Association).
+ *
+ * For isolated I/O requests, we get the ENA from the zio_t. The propagation
+ * gets very complicated due to RAID-Z, gang blocks, and vdev caching.  We want
+ * to chain together all ereports associated with a logical piece of data.  For
+ * read I/Os, there  are basically three 'types' of I/O, which form a roughly
+ * layered diagram:
+ *
+ *      +---------------+
+ * 	| Aggregate I/O |	No associated logical data or device
+ * 	+---------------+
+ *              |
+ *              V
+ * 	+---------------+	Reads associated with a piece of logical data.
+ * 	|   Read I/O    |	This includes reads on behalf of RAID-Z,
+ * 	+---------------+       mirrors, gang blocks, retries, etc.
+ *              |
+ *              V
+ * 	+---------------+	Reads associated with a particular device, but
+ * 	| Physical I/O  |	no logical data.  Issued as part of vdev caching
+ * 	+---------------+	and I/O aggregation.
+ *
+ * Note that 'physical I/O' here is not the same terminology as used in the rest
+ * of ZIO.  Typically, 'physical I/O' simply means that there is no attached
+ * blockpointer.  But I/O with no associated block pointer can still be related
+ * to a logical piece of data (i.e. RAID-Z requests).
+ *
+ * Purely physical I/O always have unique ENAs.  They are not related to a
+ * particular piece of logical data, and therefore cannot be chained together.
+ * We still generate an ereport, but the DE doesn't correlate it with any
+ * logical piece of data.  When such an I/O fails, the delegated I/O requests
+ * will issue a retry, which will trigger the 'real' ereport with the correct
+ * ENA.
+ *
+ * We keep track of the ENA for a ZIO chain through the 'io_logical' member.
+ * When a new logical I/O is issued, we set this to point to itself.  Child I/Os
+ * then inherit this pointer, so that when it is first set subsequent failures
+ * will use the same ENA.  For vdev cache fill and queue aggregation I/O,
+ * this pointer is set to NULL, and no ereport will be generated (since it
+ * doesn't actually correspond to any particular device or piece of data,
+ * and the caller will always retry without caching or queueing anyway).
+ *
+ * For checksum errors, we want to include more information about the actual
+ * error which occurs.  Accordingly, we build an ereport when the error is
+ * noticed, but instead of sending it in immediately, we hang it off of the
+ * io_cksum_report field of the logical IO.  When the logical IO completes
+ * (successfully or not), zfs_ereport_finish_checksum() is called with the
+ * good and bad versions of the buffer (if available), and we annotate the
+ * ereport with information about the differences.
+ */
+#ifdef _KERNEL
+static void
+zfs_zevent_post_cb(nvlist_t *nvl, nvlist_t *detector)
+{
+	if (nvl)
+		fm_nvlist_destroy(nvl, FM_NVA_FREE);
+
+	if (detector)
+		fm_nvlist_destroy(detector, FM_NVA_FREE);
+}
+
+static void
+zfs_zevent_post_cb_noop(nvlist_t *nvl, nvlist_t *detector)
+{
+}
+
+static void
+zfs_ereport_start(nvlist_t **ereport_out, nvlist_t **detector_out,
+    const char *subclass, spa_t *spa, vdev_t *vd, zio_t *zio,
+    uint64_t stateoroffset, uint64_t size)
+{
+	nvlist_t *ereport, *detector;
+
+	uint64_t ena;
+	char class[64];
+
+	/*
+	 * If we are doing a spa_tryimport() or in recovery mode,
+	 * ignore errors.
+	 */
+	if (spa_load_state(spa) == SPA_LOAD_TRYIMPORT ||
+	    spa_load_state(spa) == SPA_LOAD_RECOVER)
+		return;
+
+	/*
+	 * If we are in the middle of opening a pool, and the previous attempt
+	 * failed, don't bother logging any new ereports - we're just going to
+	 * get the same diagnosis anyway.
+	 */
+	if (spa_load_state(spa) != SPA_LOAD_NONE &&
+	    spa->spa_last_open_failed)
+		return;
+
+	if (zio != NULL) {
+		/*
+		 * If this is not a read or write zio, ignore the error.  This
+		 * can occur if the DKIOCFLUSHWRITECACHE ioctl fails.
+		 */
+		if (zio->io_type != ZIO_TYPE_READ &&
+		    zio->io_type != ZIO_TYPE_WRITE)
+			return;
+
+		if (vd != NULL) {
+			/*
+			 * If the vdev has already been marked as failing due
+			 * to a failed probe, then ignore any subsequent I/O
+			 * errors, as the DE will automatically fault the vdev
+			 * on the first such failure.  This also catches cases
+			 * where vdev_remove_wanted is set and the device has
+			 * not yet been asynchronously placed into the REMOVED
+			 * state.
+			 */
+			if (zio->io_vd == vd && !vdev_accessible(vd, zio))
+				return;
+
+			/*
+			 * Ignore checksum errors for reads from DTL regions of
+			 * leaf vdevs.
+			 */
+			if (zio->io_type == ZIO_TYPE_READ &&
+			    zio->io_error == ECKSUM &&
+			    vd->vdev_ops->vdev_op_leaf &&
+			    vdev_dtl_contains(vd, DTL_MISSING, zio->io_txg, 1))
+				return;
+		}
+	}
+
+	/*
+	 * For probe failure, we want to avoid posting ereports if we've
+	 * already removed the device in the meantime.
+	 */
+	if (vd != NULL &&
+	    strcmp(subclass, FM_EREPORT_ZFS_PROBE_FAILURE) == 0 &&
+	    (vd->vdev_remove_wanted || vd->vdev_state == VDEV_STATE_REMOVED))
+		return;
+
+	if ((ereport = fm_nvlist_create(NULL)) == NULL)
+		return;
+
+	if ((detector = fm_nvlist_create(NULL)) == NULL) {
+		fm_nvlist_destroy(ereport, FM_NVA_FREE);
+		return;
+	}
+
+	/*
+	 * Serialize ereport generation
+	 */
+	mutex_enter(&spa->spa_errlist_lock);
+
+	/*
+	 * Determine the ENA to use for this event.  If we are in a loading
+	 * state, use a SPA-wide ENA.  Otherwise, if we are in an I/O state, use
+	 * a root zio-wide ENA.  Otherwise, simply use a unique ENA.
+	 */
+	if (spa_load_state(spa) != SPA_LOAD_NONE) {
+		if (spa->spa_ena == 0)
+			spa->spa_ena = fm_ena_generate(0, FM_ENA_FMT1);
+		ena = spa->spa_ena;
+	} else if (zio != NULL && zio->io_logical != NULL) {
+		if (zio->io_logical->io_ena == 0)
+			zio->io_logical->io_ena =
+			    fm_ena_generate(0, FM_ENA_FMT1);
+		ena = zio->io_logical->io_ena;
+	} else {
+		ena = fm_ena_generate(0, FM_ENA_FMT1);
+	}
+
+	/*
+	 * Construct the full class, detector, and other standard FMA fields.
+	 */
+	(void) snprintf(class, sizeof (class), "%s.%s",
+	    ZFS_ERROR_CLASS, subclass);
+
+	fm_fmri_zfs_set(detector, FM_ZFS_SCHEME_VERSION, spa_guid(spa),
+	    vd != NULL ? vd->vdev_guid : 0);
+
+	fm_ereport_set(ereport, FM_EREPORT_VERSION, class, ena, detector, NULL);
+
+	/*
+	 * Construct the per-ereport payload, depending on which parameters are
+	 * passed in.
+	 */
+
+	/*
+	 * Generic payload members common to all ereports.
+	 */
+	fm_payload_set(ereport, FM_EREPORT_PAYLOAD_ZFS_POOL,
+	    DATA_TYPE_STRING, spa_name(spa), FM_EREPORT_PAYLOAD_ZFS_POOL_GUID,
+	    DATA_TYPE_UINT64, spa_guid(spa),
+	    FM_EREPORT_PAYLOAD_ZFS_POOL_CONTEXT, DATA_TYPE_INT32,
+	    spa_load_state(spa), NULL);
+
+	if (spa != NULL) {
+		fm_payload_set(ereport, FM_EREPORT_PAYLOAD_ZFS_POOL_FAILMODE,
+		    DATA_TYPE_STRING,
+		    spa_get_failmode(spa) == ZIO_FAILURE_MODE_WAIT ?
+		    FM_EREPORT_FAILMODE_WAIT :
+		    spa_get_failmode(spa) == ZIO_FAILURE_MODE_CONTINUE ?
+		    FM_EREPORT_FAILMODE_CONTINUE : FM_EREPORT_FAILMODE_PANIC,
+		    NULL);
+	}
+
+	if (vd != NULL) {
+		vdev_t *pvd = vd->vdev_parent;
+		vdev_queue_t *vq = &vd->vdev_queue;
+		vdev_stat_t *vs = &vd->vdev_stat;
+		vdev_t *spare_vd;
+		uint64_t *spare_guids;
+		char **spare_paths;
+		int i, spare_count;
+
+		fm_payload_set(ereport, FM_EREPORT_PAYLOAD_ZFS_VDEV_GUID,
+		    DATA_TYPE_UINT64, vd->vdev_guid,
+		    FM_EREPORT_PAYLOAD_ZFS_VDEV_TYPE,
+		    DATA_TYPE_STRING, vd->vdev_ops->vdev_op_type, NULL);
+		if (vd->vdev_path != NULL)
+			fm_payload_set(ereport,
+			    FM_EREPORT_PAYLOAD_ZFS_VDEV_PATH,
+			    DATA_TYPE_STRING, vd->vdev_path, NULL);
+		if (vd->vdev_devid != NULL)
+			fm_payload_set(ereport,
+			    FM_EREPORT_PAYLOAD_ZFS_VDEV_DEVID,
+			    DATA_TYPE_STRING, vd->vdev_devid, NULL);
+		if (vd->vdev_fru != NULL)
+			fm_payload_set(ereport,
+			    FM_EREPORT_PAYLOAD_ZFS_VDEV_FRU,
+			    DATA_TYPE_STRING, vd->vdev_fru, NULL);
+		if (vd->vdev_ashift)
+			fm_payload_set(ereport,
+			    FM_EREPORT_PAYLOAD_ZFS_VDEV_ASHIFT,
+			    DATA_TYPE_UINT64, vd->vdev_ashift, NULL);
+
+		if (vq != NULL) {
+			fm_payload_set(ereport,
+			    FM_EREPORT_PAYLOAD_ZFS_VDEV_COMP_TS,
+			    DATA_TYPE_UINT64, vq->vq_io_complete_ts, NULL);
+			fm_payload_set(ereport,
+			    FM_EREPORT_PAYLOAD_ZFS_VDEV_DELTA_TS,
+			    DATA_TYPE_UINT64, vq->vq_io_delta_ts, NULL);
+		}
+
+		if (vs != NULL) {
+			fm_payload_set(ereport,
+			    FM_EREPORT_PAYLOAD_ZFS_VDEV_READ_ERRORS,
+			    DATA_TYPE_UINT64, vs->vs_read_errors,
+			    FM_EREPORT_PAYLOAD_ZFS_VDEV_WRITE_ERRORS,
+			    DATA_TYPE_UINT64, vs->vs_write_errors,
+			    FM_EREPORT_PAYLOAD_ZFS_VDEV_CKSUM_ERRORS,
+			    DATA_TYPE_UINT64, vs->vs_checksum_errors, NULL);
+		}
+
+		if (pvd != NULL) {
+			fm_payload_set(ereport,
+			    FM_EREPORT_PAYLOAD_ZFS_PARENT_GUID,
+			    DATA_TYPE_UINT64, pvd->vdev_guid,
+			    FM_EREPORT_PAYLOAD_ZFS_PARENT_TYPE,
+			    DATA_TYPE_STRING, pvd->vdev_ops->vdev_op_type,
+			    NULL);
+			if (pvd->vdev_path)
+				fm_payload_set(ereport,
+				    FM_EREPORT_PAYLOAD_ZFS_PARENT_PATH,
+				    DATA_TYPE_STRING, pvd->vdev_path, NULL);
+			if (pvd->vdev_devid)
+				fm_payload_set(ereport,
+				    FM_EREPORT_PAYLOAD_ZFS_PARENT_DEVID,
+				    DATA_TYPE_STRING, pvd->vdev_devid, NULL);
+		}
+
+		spare_count = spa->spa_spares.sav_count;
+		spare_paths = kmem_zalloc(sizeof (char *) * spare_count,
+		    KM_SLEEP);
+		spare_guids = kmem_zalloc(sizeof (uint64_t) * spare_count,
+		    KM_SLEEP);
+
+		for (i = 0; i < spare_count; i++) {
+			spare_vd = spa->spa_spares.sav_vdevs[i];
+			if (spare_vd) {
+				spare_paths[i] = spare_vd->vdev_path;
+				spare_guids[i] = spare_vd->vdev_guid;
+			}
+		}
+
+		fm_payload_set(ereport, FM_EREPORT_PAYLOAD_ZFS_VDEV_SPARE_PATHS,
+		    DATA_TYPE_STRING_ARRAY, spare_count, spare_paths,
+		    FM_EREPORT_PAYLOAD_ZFS_VDEV_SPARE_GUIDS,
+		    DATA_TYPE_UINT64_ARRAY, spare_count, spare_guids, NULL);
+
+		kmem_free(spare_guids, sizeof (uint64_t) * spare_count);
+		kmem_free(spare_paths, sizeof (char *) * spare_count);
+	}
+
+	if (zio != NULL) {
+		/*
+		 * Payload common to all I/Os.
+		 */
+		fm_payload_set(ereport, FM_EREPORT_PAYLOAD_ZFS_ZIO_ERR,
+		    DATA_TYPE_INT32, zio->io_error, NULL);
+		fm_payload_set(ereport, FM_EREPORT_PAYLOAD_ZFS_ZIO_FLAGS,
+		    DATA_TYPE_INT32, zio->io_flags, NULL);
+		fm_payload_set(ereport, FM_EREPORT_PAYLOAD_ZFS_ZIO_STAGE,
+		    DATA_TYPE_UINT32, zio->io_stage, NULL);
+		fm_payload_set(ereport, FM_EREPORT_PAYLOAD_ZFS_ZIO_PIPELINE,
+		    DATA_TYPE_UINT32, zio->io_pipeline, NULL);
+		fm_payload_set(ereport, FM_EREPORT_PAYLOAD_ZFS_ZIO_DELAY,
+		    DATA_TYPE_UINT64, zio->io_delay, NULL);
+		fm_payload_set(ereport, FM_EREPORT_PAYLOAD_ZFS_ZIO_TIMESTAMP,
+		    DATA_TYPE_UINT64, zio->io_timestamp, NULL);
+		fm_payload_set(ereport, FM_EREPORT_PAYLOAD_ZFS_ZIO_DELTA,
+		    DATA_TYPE_UINT64, zio->io_delta, NULL);
+
+		/*
+		 * If the 'size' parameter is non-zero, it indicates this is a
+		 * RAID-Z or other I/O where the physical offset and length are
+		 * provided for us, instead of within the zio_t.
+		 */
+		if (vd != NULL) {
+			if (size)
+				fm_payload_set(ereport,
+				    FM_EREPORT_PAYLOAD_ZFS_ZIO_OFFSET,
+				    DATA_TYPE_UINT64, stateoroffset,
+				    FM_EREPORT_PAYLOAD_ZFS_ZIO_SIZE,
+				    DATA_TYPE_UINT64, size, NULL);
+			else
+				fm_payload_set(ereport,
+				    FM_EREPORT_PAYLOAD_ZFS_ZIO_OFFSET,
+				    DATA_TYPE_UINT64, zio->io_offset,
+				    FM_EREPORT_PAYLOAD_ZFS_ZIO_SIZE,
+				    DATA_TYPE_UINT64, zio->io_size, NULL);
+		}
+
+		/*
+		 * Payload for I/Os with corresponding logical information.
+		 */
+		if (zio->io_logical != NULL)
+			fm_payload_set(ereport,
+			    FM_EREPORT_PAYLOAD_ZFS_ZIO_OBJSET,
+			    DATA_TYPE_UINT64,
+			    zio->io_logical->io_bookmark.zb_objset,
+			    FM_EREPORT_PAYLOAD_ZFS_ZIO_OBJECT,
+			    DATA_TYPE_UINT64,
+			    zio->io_logical->io_bookmark.zb_object,
+			    FM_EREPORT_PAYLOAD_ZFS_ZIO_LEVEL,
+			    DATA_TYPE_INT64,
+			    zio->io_logical->io_bookmark.zb_level,
+			    FM_EREPORT_PAYLOAD_ZFS_ZIO_BLKID,
+			    DATA_TYPE_UINT64,
+			    zio->io_logical->io_bookmark.zb_blkid, NULL);
+	} else if (vd != NULL) {
+		/*
+		 * If we have a vdev but no zio, this is a device fault, and the
+		 * 'stateoroffset' parameter indicates the previous state of the
+		 * vdev.
+		 */
+		fm_payload_set(ereport,
+		    FM_EREPORT_PAYLOAD_ZFS_PREV_STATE,
+		    DATA_TYPE_UINT64, stateoroffset, NULL);
+	}
+
+	mutex_exit(&spa->spa_errlist_lock);
+
+	*ereport_out = ereport;
+	*detector_out = detector;
+}
+
+/* if it's <= 128 bytes, save the corruption directly */
+#define	ZFM_MAX_INLINE		(128 / sizeof (uint64_t))
+
+#define	MAX_RANGES		16
+
+typedef struct zfs_ecksum_info {
+	/* histograms of set and cleared bits by bit number in a 64-bit word */
+	uint16_t zei_histogram_set[sizeof (uint64_t) * NBBY];
+	uint16_t zei_histogram_cleared[sizeof (uint64_t) * NBBY];
+
+	/* inline arrays of bits set and cleared. */
+	uint64_t zei_bits_set[ZFM_MAX_INLINE];
+	uint64_t zei_bits_cleared[ZFM_MAX_INLINE];
+
+	/*
+	 * for each range, the number of bits set and cleared.  The Hamming
+	 * distance between the good and bad buffers is the sum of them all.
+	 */
+	uint32_t zei_range_sets[MAX_RANGES];
+	uint32_t zei_range_clears[MAX_RANGES];
+
+	struct zei_ranges {
+		uint32_t	zr_start;
+		uint32_t	zr_end;
+	} zei_ranges[MAX_RANGES];
+
+	size_t	zei_range_count;
+	uint32_t zei_mingap;
+	uint32_t zei_allowed_mingap;
+
+} zfs_ecksum_info_t;
+
+static void
+update_histogram(uint64_t value_arg, uint16_t *hist, uint32_t *count)
+{
+	size_t i;
+	size_t bits = 0;
+	uint64_t value = BE_64(value_arg);
+
+	/* We store the bits in big-endian (largest-first) order */
+	for (i = 0; i < 64; i++) {
+		if (value & (1ull << i)) {
+			if (hist[63 - i] < UINT16_MAX)
+				hist[63 - i]++;
+			++bits;
+		}
+	}
+	/* update the count of bits changed */
+	*count += bits;
+}
+
+/*
+ * We've now filled up the range array, and need to increase "mingap" and
+ * shrink the range list accordingly.  zei_mingap is always the smallest
+ * distance between array entries, so we set the new_allowed_gap to be
+ * one greater than that.  We then go through the list, joining together
+ * any ranges which are closer than the new_allowed_gap.
+ *
+ * By construction, there will be at least one.  We also update zei_mingap
+ * to the new smallest gap, to prepare for our next invocation.
+ */
+static void
+zei_shrink_ranges(zfs_ecksum_info_t *eip)
+{
+	uint32_t mingap = UINT32_MAX;
+	uint32_t new_allowed_gap = eip->zei_mingap + 1;
+
+	size_t idx, output;
+	size_t max = eip->zei_range_count;
+
+	struct zei_ranges *r = eip->zei_ranges;
+
+	ASSERT3U(eip->zei_range_count, >, 0);
+	ASSERT3U(eip->zei_range_count, <=, MAX_RANGES);
+
+	output = idx = 0;
+	while (idx < max - 1) {
+		uint32_t start = r[idx].zr_start;
+		uint32_t end = r[idx].zr_end;
+
+		while (idx < max - 1) {
+			uint32_t nstart, nend, gap;
+
+			idx++;
+			nstart = r[idx].zr_start;
+			nend = r[idx].zr_end;
+
+			gap = nstart - end;
+			if (gap < new_allowed_gap) {
+				end = nend;
+				continue;
+			}
+			if (gap < mingap)
+				mingap = gap;
+			break;
+		}
+		r[output].zr_start = start;
+		r[output].zr_end = end;
+		output++;
+	}
+	ASSERT3U(output, <, eip->zei_range_count);
+	eip->zei_range_count = output;
+	eip->zei_mingap = mingap;
+	eip->zei_allowed_mingap = new_allowed_gap;
+}
+
+static void
+zei_add_range(zfs_ecksum_info_t *eip, int start, int end)
+{
+	struct zei_ranges *r = eip->zei_ranges;
+	size_t count = eip->zei_range_count;
+
+	if (count >= MAX_RANGES) {
+		zei_shrink_ranges(eip);
+		count = eip->zei_range_count;
+	}
+	if (count == 0) {
+		eip->zei_mingap = UINT32_MAX;
+		eip->zei_allowed_mingap = 1;
+	} else {
+		int gap = start - r[count - 1].zr_end;
+
+		if (gap < eip->zei_allowed_mingap) {
+			r[count - 1].zr_end = end;
+			return;
+		}
+		if (gap < eip->zei_mingap)
+			eip->zei_mingap = gap;
+	}
+	r[count].zr_start = start;
+	r[count].zr_end = end;
+	eip->zei_range_count++;
+}
+
+static size_t
+zei_range_total_size(zfs_ecksum_info_t *eip)
+{
+	struct zei_ranges *r = eip->zei_ranges;
+	size_t count = eip->zei_range_count;
+	size_t result = 0;
+	size_t idx;
+
+	for (idx = 0; idx < count; idx++)
+		result += (r[idx].zr_end - r[idx].zr_start);
+
+	return (result);
+}
+
+static zfs_ecksum_info_t *
+annotate_ecksum(nvlist_t *ereport, zio_bad_cksum_t *info,
+    const uint8_t *goodbuf, const uint8_t *badbuf, size_t size,
+    boolean_t drop_if_identical)
+{
+	const uint64_t *good = (const uint64_t *)goodbuf;
+	const uint64_t *bad = (const uint64_t *)badbuf;
+
+	uint64_t allset = 0;
+	uint64_t allcleared = 0;
+
+	size_t nui64s = size / sizeof (uint64_t);
+
+	size_t inline_size;
+	int no_inline = 0;
+	size_t idx;
+	size_t range;
+
+	size_t offset = 0;
+	ssize_t start = -1;
+
+	zfs_ecksum_info_t *eip = kmem_zalloc(sizeof (*eip), KM_SLEEP);
+
+	/* don't do any annotation for injected checksum errors */
+	if (info != NULL && info->zbc_injected)
+		return (eip);
+
+	if (info != NULL && info->zbc_has_cksum) {
+		fm_payload_set(ereport,
+		    FM_EREPORT_PAYLOAD_ZFS_CKSUM_EXPECTED,
+		    DATA_TYPE_UINT64_ARRAY,
+		    sizeof (info->zbc_expected) / sizeof (uint64_t),
+		    (uint64_t *)&info->zbc_expected,
+		    FM_EREPORT_PAYLOAD_ZFS_CKSUM_ACTUAL,
+		    DATA_TYPE_UINT64_ARRAY,
+		    sizeof (info->zbc_actual) / sizeof (uint64_t),
+		    (uint64_t *)&info->zbc_actual,
+		    FM_EREPORT_PAYLOAD_ZFS_CKSUM_ALGO,
+		    DATA_TYPE_STRING,
+		    info->zbc_checksum_name,
+		    NULL);
+
+		if (info->zbc_byteswapped) {
+			fm_payload_set(ereport,
+			    FM_EREPORT_PAYLOAD_ZFS_CKSUM_BYTESWAP,
+			    DATA_TYPE_BOOLEAN, 1,
+			    NULL);
+		}
+	}
+
+	if (badbuf == NULL || goodbuf == NULL)
+		return (eip);
+
+	ASSERT3U(size, ==, nui64s * sizeof (uint64_t));
+	ASSERT3U(size, <=, SPA_MAXBLOCKSIZE);
+	ASSERT3U(size, <=, UINT32_MAX);
+
+	/* build up the range list by comparing the two buffers. */
+	for (idx = 0; idx < nui64s; idx++) {
+		if (good[idx] == bad[idx]) {
+			if (start == -1)
+				continue;
+
+			zei_add_range(eip, start, idx);
+			start = -1;
+		} else {
+			if (start != -1)
+				continue;
+
+			start = idx;
+		}
+	}
+	if (start != -1)
+		zei_add_range(eip, start, idx);
+
+	/* See if it will fit in our inline buffers */
+	inline_size = zei_range_total_size(eip);
+	if (inline_size > ZFM_MAX_INLINE)
+		no_inline = 1;
+
+	/*
+	 * If there is no change and we want to drop if the buffers are
+	 * identical, do so.
+	 */
+	if (inline_size == 0 && drop_if_identical) {
+		kmem_free(eip, sizeof (*eip));
+		return (NULL);
+	}
+
+	/*
+	 * Now walk through the ranges, filling in the details of the
+	 * differences.  Also convert our uint64_t-array offsets to byte
+	 * offsets.
+	 */
+	for (range = 0; range < eip->zei_range_count; range++) {
+		size_t start = eip->zei_ranges[range].zr_start;
+		size_t end = eip->zei_ranges[range].zr_end;
+
+		for (idx = start; idx < end; idx++) {
+			uint64_t set, cleared;
+
+			// bits set in bad, but not in good
+			set = ((~good[idx]) & bad[idx]);
+			// bits set in good, but not in bad
+			cleared = (good[idx] & (~bad[idx]));
+
+			allset |= set;
+			allcleared |= cleared;
+
+			if (!no_inline) {
+				ASSERT3U(offset, <, inline_size);
+				eip->zei_bits_set[offset] = set;
+				eip->zei_bits_cleared[offset] = cleared;
+				offset++;
+			}
+
+			update_histogram(set, eip->zei_histogram_set,
+			    &eip->zei_range_sets[range]);
+			update_histogram(cleared, eip->zei_histogram_cleared,
+			    &eip->zei_range_clears[range]);
+		}
+
+		/* convert to byte offsets */
+		eip->zei_ranges[range].zr_start	*= sizeof (uint64_t);
+		eip->zei_ranges[range].zr_end	*= sizeof (uint64_t);
+	}
+	eip->zei_allowed_mingap	*= sizeof (uint64_t);
+	inline_size		*= sizeof (uint64_t);
+
+	/* fill in ereport */
+	fm_payload_set(ereport,
+	    FM_EREPORT_PAYLOAD_ZFS_BAD_OFFSET_RANGES,
+	    DATA_TYPE_UINT32_ARRAY, 2 * eip->zei_range_count,
+	    (uint32_t *)eip->zei_ranges,
+	    FM_EREPORT_PAYLOAD_ZFS_BAD_RANGE_MIN_GAP,
+	    DATA_TYPE_UINT32, eip->zei_allowed_mingap,
+	    FM_EREPORT_PAYLOAD_ZFS_BAD_RANGE_SETS,
+	    DATA_TYPE_UINT32_ARRAY, eip->zei_range_count, eip->zei_range_sets,
+	    FM_EREPORT_PAYLOAD_ZFS_BAD_RANGE_CLEARS,
+	    DATA_TYPE_UINT32_ARRAY, eip->zei_range_count, eip->zei_range_clears,
+	    NULL);
+
+	if (!no_inline) {
+		fm_payload_set(ereport,
+		    FM_EREPORT_PAYLOAD_ZFS_BAD_SET_BITS,
+		    DATA_TYPE_UINT8_ARRAY,
+		    inline_size, (uint8_t *)eip->zei_bits_set,
+		    FM_EREPORT_PAYLOAD_ZFS_BAD_CLEARED_BITS,
+		    DATA_TYPE_UINT8_ARRAY,
+		    inline_size, (uint8_t *)eip->zei_bits_cleared,
+		    NULL);
+	} else {
+		fm_payload_set(ereport,
+		    FM_EREPORT_PAYLOAD_ZFS_BAD_SET_HISTOGRAM,
+		    DATA_TYPE_UINT16_ARRAY,
+		    NBBY * sizeof (uint64_t), eip->zei_histogram_set,
+		    FM_EREPORT_PAYLOAD_ZFS_BAD_CLEARED_HISTOGRAM,
+		    DATA_TYPE_UINT16_ARRAY,
+		    NBBY * sizeof (uint64_t), eip->zei_histogram_cleared,
+		    NULL);
+	}
+	return (eip);
+}
+#endif
+
+void
+zfs_ereport_post(const char *subclass, spa_t *spa, vdev_t *vd, zio_t *zio,
+    uint64_t stateoroffset, uint64_t size)
+{
+#ifdef _KERNEL
+	nvlist_t *ereport = NULL;
+	nvlist_t *detector = NULL;
+
+	zfs_ereport_start(&ereport, &detector,
+	    subclass, spa, vd, zio, stateoroffset, size);
+
+	if (ereport == NULL)
+		return;
+
+	/* Cleanup is handled by the callback function */
+	zfs_zevent_post(ereport, detector, zfs_zevent_post_cb);
+#endif
+}
+
+void
+zfs_ereport_start_checksum(spa_t *spa, vdev_t *vd,
+    struct zio *zio, uint64_t offset, uint64_t length, void *arg,
+    zio_bad_cksum_t *info)
+{
+	zio_cksum_report_t *report = kmem_zalloc(sizeof (*report), KM_SLEEP);
+
+	if (zio->io_vsd != NULL)
+		zio->io_vsd_ops->vsd_cksum_report(zio, report, arg);
+	else
+		zio_vsd_default_cksum_report(zio, report, arg);
+
+	/* copy the checksum failure information if it was provided */
+	if (info != NULL) {
+		report->zcr_ckinfo = kmem_zalloc(sizeof (*info), KM_SLEEP);
+		bcopy(info, report->zcr_ckinfo, sizeof (*info));
+	}
+
+	report->zcr_align = 1ULL << vd->vdev_top->vdev_ashift;
+	report->zcr_length = length;
+
+#ifdef _KERNEL
+	zfs_ereport_start(&report->zcr_ereport, &report->zcr_detector,
+	    FM_EREPORT_ZFS_CHECKSUM, spa, vd, zio, offset, length);
+
+	if (report->zcr_ereport == NULL) {
+		zfs_ereport_free_checksum(report);
+		return;
+	}
+#endif
+
+	mutex_enter(&spa->spa_errlist_lock);
+	report->zcr_next = zio->io_logical->io_cksum_report;
+	zio->io_logical->io_cksum_report = report;
+	mutex_exit(&spa->spa_errlist_lock);
+}
+
+void
+zfs_ereport_finish_checksum(zio_cksum_report_t *report,
+    const void *good_data, const void *bad_data, boolean_t drop_if_identical)
+{
+#ifdef _KERNEL
+	zfs_ecksum_info_t *info;
+
+	info = annotate_ecksum(report->zcr_ereport, report->zcr_ckinfo,
+	    good_data, bad_data, report->zcr_length, drop_if_identical);
+	if (info != NULL)
+		zfs_zevent_post(report->zcr_ereport,
+		    report->zcr_detector, zfs_zevent_post_cb);
+	else
+		zfs_zevent_post_cb(report->zcr_ereport, report->zcr_detector);
+
+	report->zcr_ereport = report->zcr_detector = NULL;
+	if (info != NULL)
+		kmem_free(info, sizeof (*info));
+#endif
+}
+
+void
+zfs_ereport_free_checksum(zio_cksum_report_t *rpt)
+{
+#ifdef _KERNEL
+	if (rpt->zcr_ereport != NULL) {
+		fm_nvlist_destroy(rpt->zcr_ereport,
+		    FM_NVA_FREE);
+		fm_nvlist_destroy(rpt->zcr_detector,
+		    FM_NVA_FREE);
+	}
+#endif
+	rpt->zcr_free(rpt->zcr_cbdata, rpt->zcr_cbinfo);
+
+	if (rpt->zcr_ckinfo != NULL)
+		kmem_free(rpt->zcr_ckinfo, sizeof (*rpt->zcr_ckinfo));
+
+	kmem_free(rpt, sizeof (*rpt));
+}
+
+void
+zfs_ereport_send_interim_checksum(zio_cksum_report_t *report)
+{
+#ifdef _KERNEL
+	zfs_zevent_post(report->zcr_ereport, report->zcr_detector,
+	    zfs_zevent_post_cb_noop);
+#endif
+}
+
+void
+zfs_ereport_post_checksum(spa_t *spa, vdev_t *vd,
+    struct zio *zio, uint64_t offset, uint64_t length,
+    const void *good_data, const void *bad_data, zio_bad_cksum_t *zbc)
+{
+#ifdef _KERNEL
+	nvlist_t *ereport = NULL;
+	nvlist_t *detector = NULL;
+	zfs_ecksum_info_t *info;
+
+	zfs_ereport_start(&ereport, &detector,
+	    FM_EREPORT_ZFS_CHECKSUM, spa, vd, zio, offset, length);
+
+	if (ereport == NULL)
+		return;
+
+	info = annotate_ecksum(ereport, zbc, good_data, bad_data, length,
+	    B_FALSE);
+
+	if (info != NULL) {
+		zfs_zevent_post(ereport, detector, zfs_zevent_post_cb);
+		kmem_free(info, sizeof (*info));
+	}
+#endif
+}
+
+static void
+zfs_post_common(spa_t *spa, vdev_t *vd, const char *name)
+{
+#ifdef _KERNEL
+	nvlist_t *resource;
+	char class[64];
+
+	if (spa_load_state(spa) == SPA_LOAD_TRYIMPORT)
+		return;
+
+	if ((resource = fm_nvlist_create(NULL)) == NULL)
+		return;
+
+	(void) snprintf(class, sizeof (class), "%s.%s.%s", FM_RSRC_RESOURCE,
+	    ZFS_ERROR_CLASS, name);
+	VERIFY0(nvlist_add_uint8(resource, FM_VERSION, FM_RSRC_VERSION));
+	VERIFY0(nvlist_add_string(resource, FM_CLASS, class));
+	VERIFY0(nvlist_add_uint64(resource,
+	    FM_EREPORT_PAYLOAD_ZFS_POOL_GUID, spa_guid(spa)));
+	VERIFY0(nvlist_add_int32(resource,
+	    FM_EREPORT_PAYLOAD_ZFS_POOL_CONTEXT, spa_load_state(spa)));
+
+	if (vd) {
+		VERIFY0(nvlist_add_uint64(resource,
+		    FM_EREPORT_PAYLOAD_ZFS_VDEV_GUID, vd->vdev_guid));
+		VERIFY0(nvlist_add_uint64(resource,
+		    FM_EREPORT_PAYLOAD_ZFS_VDEV_STATE, vd->vdev_state));
+	}
+
+	zfs_zevent_post(resource, NULL, zfs_zevent_post_cb);
+#endif
+}
+
+/*
+ * The 'resource.fs.zfs.removed' event is an internal signal that the given vdev
+ * has been removed from the system.  This will cause the DE to ignore any
+ * recent I/O errors, inferring that they are due to the asynchronous device
+ * removal.
+ */
+void
+zfs_post_remove(spa_t *spa, vdev_t *vd)
+{
+	zfs_post_common(spa, vd, FM_EREPORT_RESOURCE_REMOVED);
+}
+
+/*
+ * The 'resource.fs.zfs.autoreplace' event is an internal signal that the pool
+ * has the 'autoreplace' property set, and therefore any broken vdevs will be
+ * handled by higher level logic, and no vdev fault should be generated.
+ */
+void
+zfs_post_autoreplace(spa_t *spa, vdev_t *vd)
+{
+	zfs_post_common(spa, vd, FM_EREPORT_RESOURCE_AUTOREPLACE);
+}
+
+/*
+ * The 'resource.fs.zfs.statechange' event is an internal signal that the
+ * given vdev has transitioned its state to DEGRADED or HEALTHY.  This will
+ * cause the retire agent to repair any outstanding fault management cases
+ * open because the device was not found (fault.fs.zfs.device).
+ */
+void
+zfs_post_state_change(spa_t *spa, vdev_t *vd)
+{
+	zfs_post_common(spa, vd, FM_EREPORT_RESOURCE_STATECHANGE);
+}
+
+#if defined(_KERNEL) && defined(HAVE_SPL)
+EXPORT_SYMBOL(zfs_ereport_post);
+EXPORT_SYMBOL(zfs_ereport_post_checksum);
+EXPORT_SYMBOL(zfs_post_remove);
+EXPORT_SYMBOL(zfs_post_autoreplace);
+EXPORT_SYMBOL(zfs_post_state_change);
+#endif /* _KERNEL */
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/module/zfs/zfs_fuid.c
@@ -0,0 +1,778 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+ */
+
+#include <sys/zfs_context.h>
+#include <sys/dmu.h>
+#include <sys/avl.h>
+#include <sys/zap.h>
+#include <sys/refcount.h>
+#include <sys/nvpair.h>
+#ifdef _KERNEL
+#include <sys/kidmap.h>
+#include <sys/sid.h>
+#include <sys/zfs_vfsops.h>
+#include <sys/zfs_znode.h>
+#endif
+#include <sys/zfs_fuid.h>
+
+/*
+ * FUID Domain table(s).
+ *
+ * The FUID table is stored as a packed nvlist of an array
+ * of nvlists which contain an index, domain string and offset
+ *
+ * During file system initialization the nvlist(s) are read and
+ * two AVL trees are created.  One tree is keyed by the index number
+ * and the other by the domain string.  Nodes are never removed from
+ * trees, but new entries may be added.  If a new entry is added then
+ * the zsb->z_fuid_dirty flag is set to true and the caller will then
+ * be responsible for calling zfs_fuid_sync() to sync the changes to disk.
+ *
+ */
+
+#define	FUID_IDX	"fuid_idx"
+#define	FUID_DOMAIN	"fuid_domain"
+#define	FUID_OFFSET	"fuid_offset"
+#define	FUID_NVP_ARRAY	"fuid_nvlist"
+
+typedef struct fuid_domain {
+	avl_node_t	f_domnode;
+	avl_node_t	f_idxnode;
+	ksiddomain_t	*f_ksid;
+	uint64_t	f_idx;
+} fuid_domain_t;
+
+static char *nulldomain = "";
+
+/*
+ * Compare two indexes.
+ */
+static int
+idx_compare(const void *arg1, const void *arg2)
+{
+	const fuid_domain_t *node1 = arg1;
+	const fuid_domain_t *node2 = arg2;
+
+	if (node1->f_idx < node2->f_idx)
+		return (-1);
+	else if (node1->f_idx > node2->f_idx)
+		return (1);
+	return (0);
+}
+
+/*
+ * Compare two domain strings.
+ */
+static int
+domain_compare(const void *arg1, const void *arg2)
+{
+	const fuid_domain_t *node1 = arg1;
+	const fuid_domain_t *node2 = arg2;
+	int val;
+
+	val = strcmp(node1->f_ksid->kd_name, node2->f_ksid->kd_name);
+	if (val == 0)
+		return (0);
+	return (val > 0 ? 1 : -1);
+}
+
+void
+zfs_fuid_avl_tree_create(avl_tree_t *idx_tree, avl_tree_t *domain_tree)
+{
+	avl_create(idx_tree, idx_compare,
+	    sizeof (fuid_domain_t), offsetof(fuid_domain_t, f_idxnode));
+	avl_create(domain_tree, domain_compare,
+	    sizeof (fuid_domain_t), offsetof(fuid_domain_t, f_domnode));
+}
+
+/*
+ * load initial fuid domain and idx trees.  This function is used by
+ * both the kernel and zdb.
+ */
+uint64_t
+zfs_fuid_table_load(objset_t *os, uint64_t fuid_obj, avl_tree_t *idx_tree,
+    avl_tree_t *domain_tree)
+{
+	dmu_buf_t *db;
+	uint64_t fuid_size;
+
+	ASSERT(fuid_obj != 0);
+	VERIFY(0 == dmu_bonus_hold(os, fuid_obj,
+	    FTAG, &db));
+	fuid_size = *(uint64_t *)db->db_data;
+	dmu_buf_rele(db, FTAG);
+
+	if (fuid_size)  {
+		nvlist_t **fuidnvp;
+		nvlist_t *nvp = NULL;
+		uint_t count;
+		char *packed;
+		int i;
+
+		packed = kmem_alloc(fuid_size, KM_SLEEP);
+		VERIFY(dmu_read(os, fuid_obj, 0,
+		    fuid_size, packed, DMU_READ_PREFETCH) == 0);
+		VERIFY(nvlist_unpack(packed, fuid_size,
+		    &nvp, 0) == 0);
+		VERIFY(nvlist_lookup_nvlist_array(nvp, FUID_NVP_ARRAY,
+		    &fuidnvp, &count) == 0);
+
+		for (i = 0; i != count; i++) {
+			fuid_domain_t *domnode;
+			char *domain;
+			uint64_t idx;
+
+			VERIFY(nvlist_lookup_string(fuidnvp[i], FUID_DOMAIN,
+			    &domain) == 0);
+			VERIFY(nvlist_lookup_uint64(fuidnvp[i], FUID_IDX,
+			    &idx) == 0);
+
+			domnode = kmem_alloc(sizeof (fuid_domain_t), KM_SLEEP);
+
+			domnode->f_idx = idx;
+			domnode->f_ksid = ksid_lookupdomain(domain);
+			avl_add(idx_tree, domnode);
+			avl_add(domain_tree, domnode);
+		}
+		nvlist_free(nvp);
+		kmem_free(packed, fuid_size);
+	}
+	return (fuid_size);
+}
+
+void
+zfs_fuid_table_destroy(avl_tree_t *idx_tree, avl_tree_t *domain_tree)
+{
+	fuid_domain_t *domnode;
+	void *cookie;
+
+	cookie = NULL;
+	while ((domnode = avl_destroy_nodes(domain_tree, &cookie)))
+		ksiddomain_rele(domnode->f_ksid);
+
+	avl_destroy(domain_tree);
+	cookie = NULL;
+	while ((domnode = avl_destroy_nodes(idx_tree, &cookie)))
+		kmem_free(domnode, sizeof (fuid_domain_t));
+	avl_destroy(idx_tree);
+}
+
+char *
+zfs_fuid_idx_domain(avl_tree_t *idx_tree, uint32_t idx)
+{
+	fuid_domain_t searchnode, *findnode;
+	avl_index_t loc;
+
+	searchnode.f_idx = idx;
+
+	findnode = avl_find(idx_tree, &searchnode, &loc);
+
+	return (findnode ? findnode->f_ksid->kd_name : nulldomain);
+}
+
+#ifdef _KERNEL
+/*
+ * Load the fuid table(s) into memory.
+ */
+static void
+zfs_fuid_init(zfs_sb_t *zsb)
+{
+	rw_enter(&zsb->z_fuid_lock, RW_WRITER);
+
+	if (zsb->z_fuid_loaded) {
+		rw_exit(&zsb->z_fuid_lock);
+		return;
+	}
+
+	zfs_fuid_avl_tree_create(&zsb->z_fuid_idx, &zsb->z_fuid_domain);
+
+	(void) zap_lookup(zsb->z_os, MASTER_NODE_OBJ,
+	    ZFS_FUID_TABLES, 8, 1, &zsb->z_fuid_obj);
+	if (zsb->z_fuid_obj != 0) {
+		zsb->z_fuid_size = zfs_fuid_table_load(zsb->z_os,
+		    zsb->z_fuid_obj, &zsb->z_fuid_idx,
+		    &zsb->z_fuid_domain);
+	}
+
+	zsb->z_fuid_loaded = B_TRUE;
+	rw_exit(&zsb->z_fuid_lock);
+}
+
+/*
+ * sync out AVL trees to persistent storage.
+ */
+void
+zfs_fuid_sync(zfs_sb_t *zsb, dmu_tx_t *tx)
+{
+	nvlist_t *nvp;
+	nvlist_t **fuids;
+	size_t nvsize = 0;
+	char *packed;
+	dmu_buf_t *db;
+	fuid_domain_t *domnode;
+	int numnodes;
+	int i;
+
+	if (!zsb->z_fuid_dirty) {
+		return;
+	}
+
+	rw_enter(&zsb->z_fuid_lock, RW_WRITER);
+
+	/*
+	 * First see if table needs to be created?
+	 */
+	if (zsb->z_fuid_obj == 0) {
+		zsb->z_fuid_obj = dmu_object_alloc(zsb->z_os,
+		    DMU_OT_FUID, 1 << 14, DMU_OT_FUID_SIZE,
+		    sizeof (uint64_t), tx);
+		VERIFY(zap_add(zsb->z_os, MASTER_NODE_OBJ,
+		    ZFS_FUID_TABLES, sizeof (uint64_t), 1,
+		    &zsb->z_fuid_obj, tx) == 0);
+	}
+
+	VERIFY(nvlist_alloc(&nvp, NV_UNIQUE_NAME, KM_SLEEP) == 0);
+
+	numnodes = avl_numnodes(&zsb->z_fuid_idx);
+	fuids = kmem_alloc(numnodes * sizeof (void *), KM_SLEEP);
+	for (i = 0, domnode = avl_first(&zsb->z_fuid_domain); domnode; i++,
+	    domnode = AVL_NEXT(&zsb->z_fuid_domain, domnode)) {
+		VERIFY(nvlist_alloc(&fuids[i], NV_UNIQUE_NAME, KM_SLEEP) == 0);
+		VERIFY(nvlist_add_uint64(fuids[i], FUID_IDX,
+		    domnode->f_idx) == 0);
+		VERIFY(nvlist_add_uint64(fuids[i], FUID_OFFSET, 0) == 0);
+		VERIFY(nvlist_add_string(fuids[i], FUID_DOMAIN,
+		    domnode->f_ksid->kd_name) == 0);
+	}
+	VERIFY(nvlist_add_nvlist_array(nvp, FUID_NVP_ARRAY,
+	    fuids, numnodes) == 0);
+	for (i = 0; i != numnodes; i++)
+		nvlist_free(fuids[i]);
+	kmem_free(fuids, numnodes * sizeof (void *));
+	VERIFY(nvlist_size(nvp, &nvsize, NV_ENCODE_XDR) == 0);
+	packed = kmem_alloc(nvsize, KM_SLEEP);
+	VERIFY(nvlist_pack(nvp, &packed, &nvsize,
+	    NV_ENCODE_XDR, KM_SLEEP) == 0);
+	nvlist_free(nvp);
+	zsb->z_fuid_size = nvsize;
+	dmu_write(zsb->z_os, zsb->z_fuid_obj, 0, zsb->z_fuid_size, packed, tx);
+	kmem_free(packed, zsb->z_fuid_size);
+	VERIFY(0 == dmu_bonus_hold(zsb->z_os, zsb->z_fuid_obj,
+	    FTAG, &db));
+	dmu_buf_will_dirty(db, tx);
+	*(uint64_t *)db->db_data = zsb->z_fuid_size;
+	dmu_buf_rele(db, FTAG);
+
+	zsb->z_fuid_dirty = B_FALSE;
+	rw_exit(&zsb->z_fuid_lock);
+}
+
+/*
+ * Query domain table for a given domain.
+ *
+ * If domain isn't found and addok is set, it is added to AVL trees and
+ * the zsb->z_fuid_dirty flag will be set to TRUE.  It will then be
+ * necessary for the caller or another thread to detect the dirty table
+ * and sync out the changes.
+ */
+int
+zfs_fuid_find_by_domain(zfs_sb_t *zsb, const char *domain,
+    char **retdomain, boolean_t addok)
+{
+	fuid_domain_t searchnode, *findnode;
+	avl_index_t loc;
+	krw_t rw = RW_READER;
+
+	/*
+	 * If the dummy "nobody" domain then return an index of 0
+	 * to cause the created FUID to be a standard POSIX id
+	 * for the user nobody.
+	 */
+	if (domain[0] == '\0') {
+		if (retdomain)
+			*retdomain = nulldomain;
+		return (0);
+	}
+
+	searchnode.f_ksid = ksid_lookupdomain(domain);
+	if (retdomain)
+		*retdomain = searchnode.f_ksid->kd_name;
+	if (!zsb->z_fuid_loaded)
+		zfs_fuid_init(zsb);
+
+retry:
+	rw_enter(&zsb->z_fuid_lock, rw);
+	findnode = avl_find(&zsb->z_fuid_domain, &searchnode, &loc);
+
+	if (findnode) {
+		rw_exit(&zsb->z_fuid_lock);
+		ksiddomain_rele(searchnode.f_ksid);
+		return (findnode->f_idx);
+	} else if (addok) {
+		fuid_domain_t *domnode;
+		uint64_t retidx;
+
+		if (rw == RW_READER && !rw_tryupgrade(&zsb->z_fuid_lock)) {
+			rw_exit(&zsb->z_fuid_lock);
+			rw = RW_WRITER;
+			goto retry;
+		}
+
+		domnode = kmem_alloc(sizeof (fuid_domain_t), KM_SLEEP);
+		domnode->f_ksid = searchnode.f_ksid;
+
+		retidx = domnode->f_idx = avl_numnodes(&zsb->z_fuid_idx) + 1;
+
+		avl_add(&zsb->z_fuid_domain, domnode);
+		avl_add(&zsb->z_fuid_idx, domnode);
+		zsb->z_fuid_dirty = B_TRUE;
+		rw_exit(&zsb->z_fuid_lock);
+		return (retidx);
+	} else {
+		rw_exit(&zsb->z_fuid_lock);
+		return (-1);
+	}
+}
+
+/*
+ * Query domain table by index, returning domain string
+ *
+ * Returns a pointer from an avl node of the domain string.
+ *
+ */
+const char *
+zfs_fuid_find_by_idx(zfs_sb_t *zsb, uint32_t idx)
+{
+	char *domain;
+
+	if (idx == 0 || !zsb->z_use_fuids)
+		return (NULL);
+
+	if (!zsb->z_fuid_loaded)
+		zfs_fuid_init(zsb);
+
+	rw_enter(&zsb->z_fuid_lock, RW_READER);
+
+	if (zsb->z_fuid_obj || zsb->z_fuid_dirty)
+		domain = zfs_fuid_idx_domain(&zsb->z_fuid_idx, idx);
+	else
+		domain = nulldomain;
+	rw_exit(&zsb->z_fuid_lock);
+
+	ASSERT(domain);
+	return (domain);
+}
+
+void
+zfs_fuid_map_ids(znode_t *zp, cred_t *cr, uid_t *uidp, uid_t *gidp)
+{
+	*uidp = zfs_fuid_map_id(ZTOZSB(zp), zp->z_uid, cr, ZFS_OWNER);
+	*gidp = zfs_fuid_map_id(ZTOZSB(zp), zp->z_gid, cr, ZFS_GROUP);
+}
+
+uid_t
+zfs_fuid_map_id(zfs_sb_t *zsb, uint64_t fuid,
+    cred_t *cr, zfs_fuid_type_t type)
+{
+#ifdef HAVE_KSID
+	uint32_t index = FUID_INDEX(fuid);
+	const char *domain;
+	uid_t id;
+
+	if (index == 0)
+		return (fuid);
+
+	domain = zfs_fuid_find_by_idx(zsb, index);
+	ASSERT(domain != NULL);
+
+	if (type == ZFS_OWNER || type == ZFS_ACE_USER) {
+		(void) kidmap_getuidbysid(crgetzone(cr), domain,
+		    FUID_RID(fuid), &id);
+	} else {
+		(void) kidmap_getgidbysid(crgetzone(cr), domain,
+		    FUID_RID(fuid), &id);
+	}
+	return (id);
+#else
+	/*
+	 * The Linux port only supports POSIX IDs, use the passed id.
+	 */
+	return (fuid);
+#endif /* HAVE_KSID */
+}
+
+/*
+ * Add a FUID node to the list of fuid's being created for this
+ * ACL
+ *
+ * If ACL has multiple domains, then keep only one copy of each unique
+ * domain.
+ */
+void
+zfs_fuid_node_add(zfs_fuid_info_t **fuidpp, const char *domain, uint32_t rid,
+    uint64_t idx, uint64_t id, zfs_fuid_type_t type)
+{
+	zfs_fuid_t *fuid;
+	zfs_fuid_domain_t *fuid_domain;
+	zfs_fuid_info_t *fuidp;
+	uint64_t fuididx;
+	boolean_t found = B_FALSE;
+
+	if (*fuidpp == NULL)
+		*fuidpp = zfs_fuid_info_alloc();
+
+	fuidp = *fuidpp;
+	/*
+	 * First find fuid domain index in linked list
+	 *
+	 * If one isn't found then create an entry.
+	 */
+
+	for (fuididx = 1, fuid_domain = list_head(&fuidp->z_domains);
+	    fuid_domain; fuid_domain = list_next(&fuidp->z_domains,
+	    fuid_domain), fuididx++) {
+		if (idx == fuid_domain->z_domidx) {
+			found = B_TRUE;
+			break;
+		}
+	}
+
+	if (!found) {
+		fuid_domain = kmem_alloc(sizeof (zfs_fuid_domain_t), KM_SLEEP);
+		fuid_domain->z_domain = domain;
+		fuid_domain->z_domidx = idx;
+		list_insert_tail(&fuidp->z_domains, fuid_domain);
+		fuidp->z_domain_str_sz += strlen(domain) + 1;
+		fuidp->z_domain_cnt++;
+	}
+
+	if (type == ZFS_ACE_USER || type == ZFS_ACE_GROUP) {
+
+		/*
+		 * Now allocate fuid entry and add it on the end of the list
+		 */
+
+		fuid = kmem_alloc(sizeof (zfs_fuid_t), KM_SLEEP);
+		fuid->z_id = id;
+		fuid->z_domidx = idx;
+		fuid->z_logfuid = FUID_ENCODE(fuididx, rid);
+
+		list_insert_tail(&fuidp->z_fuids, fuid);
+		fuidp->z_fuid_cnt++;
+	} else {
+		if (type == ZFS_OWNER)
+			fuidp->z_fuid_owner = FUID_ENCODE(fuididx, rid);
+		else
+			fuidp->z_fuid_group = FUID_ENCODE(fuididx, rid);
+	}
+}
+
+#ifdef HAVE_KSID
+/*
+ * Create a file system FUID, based on information in the users cred
+ *
+ * If cred contains KSID_OWNER then it should be used to determine
+ * the uid otherwise cred's uid will be used. By default cred's gid
+ * is used unless it's an ephemeral ID in which case KSID_GROUP will
+ * be used if it exists.
+ */
+uint64_t
+zfs_fuid_create_cred(zfs_sb_t *zsb, zfs_fuid_type_t type,
+    cred_t *cr, zfs_fuid_info_t **fuidp)
+{
+	uint64_t	idx;
+	ksid_t		*ksid;
+	uint32_t	rid;
+	char		*kdomain;
+	const char	*domain;
+	uid_t		id;
+
+	VERIFY(type == ZFS_OWNER || type == ZFS_GROUP);
+
+	ksid = crgetsid(cr, (type == ZFS_OWNER) ? KSID_OWNER : KSID_GROUP);
+
+	if (!zsb->z_use_fuids || (ksid == NULL)) {
+		id = (type == ZFS_OWNER) ? crgetuid(cr) : crgetgid(cr);
+
+		if (IS_EPHEMERAL(id))
+			return ((type == ZFS_OWNER) ? UID_NOBODY : GID_NOBODY);
+
+		return ((uint64_t)id);
+	}
+
+	/*
+	 * ksid is present and FUID is supported
+	 */
+	id = (type == ZFS_OWNER) ? ksid_getid(ksid) : crgetgid(cr);
+
+	if (!IS_EPHEMERAL(id))
+		return ((uint64_t)id);
+
+	if (type == ZFS_GROUP)
+		id = ksid_getid(ksid);
+
+	rid = ksid_getrid(ksid);
+	domain = ksid_getdomain(ksid);
+
+	idx = zfs_fuid_find_by_domain(zsb, domain, &kdomain, B_TRUE);
+
+	zfs_fuid_node_add(fuidp, kdomain, rid, idx, id, type);
+
+	return (FUID_ENCODE(idx, rid));
+}
+#endif /* HAVE_KSID */
+
+/*
+ * Create a file system FUID for an ACL ace
+ * or a chown/chgrp of the file.
+ * This is similar to zfs_fuid_create_cred, except that
+ * we can't find the domain + rid information in the
+ * cred.  Instead we have to query Winchester for the
+ * domain and rid.
+ *
+ * During replay operations the domain+rid information is
+ * found in the zfs_fuid_info_t that the replay code has
+ * attached to the zsb of the file system.
+ */
+uint64_t
+zfs_fuid_create(zfs_sb_t *zsb, uint64_t id, cred_t *cr,
+    zfs_fuid_type_t type, zfs_fuid_info_t **fuidpp)
+{
+#ifdef HAVE_KSID
+	const char *domain;
+	char *kdomain;
+	uint32_t fuid_idx = FUID_INDEX(id);
+	uint32_t rid;
+	idmap_stat status;
+	uint64_t idx = 0;
+	zfs_fuid_t *zfuid = NULL;
+	zfs_fuid_info_t *fuidp = NULL;
+
+	/*
+	 * If POSIX ID, or entry is already a FUID then
+	 * just return the id
+	 *
+	 * We may also be handed an already FUID'ized id via
+	 * chmod.
+	 */
+
+	if (!zsb->z_use_fuids || !IS_EPHEMERAL(id) || fuid_idx != 0)
+		return (id);
+
+	if (zsb->z_replay) {
+		fuidp = zsb->z_fuid_replay;
+
+		/*
+		 * If we are passed an ephemeral id, but no
+		 * fuid_info was logged then return NOBODY.
+		 * This is most likely a result of idmap service
+		 * not being available.
+		 */
+		if (fuidp == NULL)
+			return (UID_NOBODY);
+
+		VERIFY3U(type, >=, ZFS_OWNER);
+		VERIFY3U(type, <=, ZFS_ACE_GROUP);
+
+		switch (type) {
+		case ZFS_ACE_USER:
+		case ZFS_ACE_GROUP:
+			zfuid = list_head(&fuidp->z_fuids);
+			rid = FUID_RID(zfuid->z_logfuid);
+			idx = FUID_INDEX(zfuid->z_logfuid);
+			break;
+		case ZFS_OWNER:
+			rid = FUID_RID(fuidp->z_fuid_owner);
+			idx = FUID_INDEX(fuidp->z_fuid_owner);
+			break;
+		case ZFS_GROUP:
+			rid = FUID_RID(fuidp->z_fuid_group);
+			idx = FUID_INDEX(fuidp->z_fuid_group);
+			break;
+		};
+		domain = fuidp->z_domain_table[idx - 1];
+	} else {
+		if (type == ZFS_OWNER || type == ZFS_ACE_USER)
+			status = kidmap_getsidbyuid(crgetzone(cr), id,
+			    &domain, &rid);
+		else
+			status = kidmap_getsidbygid(crgetzone(cr), id,
+			    &domain, &rid);
+
+		if (status != 0) {
+			/*
+			 * When returning nobody we will need to
+			 * make a dummy fuid table entry for logging
+			 * purposes.
+			 */
+			rid = UID_NOBODY;
+			domain = nulldomain;
+		}
+	}
+
+	idx = zfs_fuid_find_by_domain(zsb, domain, &kdomain, B_TRUE);
+
+	if (!zsb->z_replay)
+		zfs_fuid_node_add(fuidpp, kdomain,
+		    rid, idx, id, type);
+	else if (zfuid != NULL) {
+		list_remove(&fuidp->z_fuids, zfuid);
+		kmem_free(zfuid, sizeof (zfs_fuid_t));
+	}
+	return (FUID_ENCODE(idx, rid));
+#else
+	/*
+	 * The Linux port only supports POSIX IDs, use the passed id.
+	 */
+	return (id);
+#endif
+}
+
+void
+zfs_fuid_destroy(zfs_sb_t *zsb)
+{
+	rw_enter(&zsb->z_fuid_lock, RW_WRITER);
+	if (!zsb->z_fuid_loaded) {
+		rw_exit(&zsb->z_fuid_lock);
+		return;
+	}
+	zfs_fuid_table_destroy(&zsb->z_fuid_idx, &zsb->z_fuid_domain);
+	rw_exit(&zsb->z_fuid_lock);
+}
+
+/*
+ * Allocate zfs_fuid_info for tracking FUIDs created during
+ * zfs_mknode, VOP_SETATTR() or VOP_SETSECATTR()
+ */
+zfs_fuid_info_t *
+zfs_fuid_info_alloc(void)
+{
+	zfs_fuid_info_t *fuidp;
+
+	fuidp = kmem_zalloc(sizeof (zfs_fuid_info_t), KM_SLEEP);
+	list_create(&fuidp->z_domains, sizeof (zfs_fuid_domain_t),
+	    offsetof(zfs_fuid_domain_t, z_next));
+	list_create(&fuidp->z_fuids, sizeof (zfs_fuid_t),
+	    offsetof(zfs_fuid_t, z_next));
+	return (fuidp);
+}
+
+/*
+ * Release all memory associated with zfs_fuid_info_t
+ */
+void
+zfs_fuid_info_free(zfs_fuid_info_t *fuidp)
+{
+	zfs_fuid_t *zfuid;
+	zfs_fuid_domain_t *zdomain;
+
+	while ((zfuid = list_head(&fuidp->z_fuids)) != NULL) {
+		list_remove(&fuidp->z_fuids, zfuid);
+		kmem_free(zfuid, sizeof (zfs_fuid_t));
+	}
+
+	if (fuidp->z_domain_table != NULL)
+		kmem_free(fuidp->z_domain_table,
+		    (sizeof (char **)) * fuidp->z_domain_cnt);
+
+	while ((zdomain = list_head(&fuidp->z_domains)) != NULL) {
+		list_remove(&fuidp->z_domains, zdomain);
+		kmem_free(zdomain, sizeof (zfs_fuid_domain_t));
+	}
+
+	kmem_free(fuidp, sizeof (zfs_fuid_info_t));
+}
+
+/*
+ * Check to see if id is a groupmember.  If cred
+ * has ksid info then sidlist is checked first
+ * and if still not found then POSIX groups are checked
+ *
+ * Will use a straight FUID compare when possible.
+ */
+boolean_t
+zfs_groupmember(zfs_sb_t *zsb, uint64_t id, cred_t *cr)
+{
+#ifdef HAVE_KSID
+	ksid_t		*ksid = crgetsid(cr, KSID_GROUP);
+	ksidlist_t	*ksidlist = crgetsidlist(cr);
+	uid_t		gid;
+
+	if (ksid && ksidlist) {
+		int		i;
+		ksid_t		*ksid_groups;
+		uint32_t	idx = FUID_INDEX(id);
+		uint32_t	rid = FUID_RID(id);
+
+		ksid_groups = ksidlist->ksl_sids;
+
+		for (i = 0; i != ksidlist->ksl_nsid; i++) {
+			if (idx == 0) {
+				if (id != IDMAP_WK_CREATOR_GROUP_GID &&
+				    id == ksid_groups[i].ks_id) {
+					return (B_TRUE);
+				}
+			} else {
+				const char *domain;
+
+				domain = zfs_fuid_find_by_idx(zsb, idx);
+				ASSERT(domain != NULL);
+
+				if (strcmp(domain,
+				    IDMAP_WK_CREATOR_SID_AUTHORITY) == 0)
+					return (B_FALSE);
+
+				if ((strcmp(domain,
+				    ksid_groups[i].ks_domain->kd_name) == 0) &&
+				    rid == ksid_groups[i].ks_rid)
+					return (B_TRUE);
+			}
+		}
+	}
+
+	/*
+	 * Not found in ksidlist, check posix groups
+	 */
+	gid = zfs_fuid_map_id(zsb, id, cr, ZFS_GROUP);
+	return (groupmember(gid, cr));
+#else
+	return (B_TRUE);
+#endif
+}
+
+void
+zfs_fuid_txhold(zfs_sb_t *zsb, dmu_tx_t *tx)
+{
+	if (zsb->z_fuid_obj == 0) {
+		dmu_tx_hold_bonus(tx, DMU_NEW_OBJECT);
+		dmu_tx_hold_write(tx, DMU_NEW_OBJECT, 0,
+		    FUID_SIZE_ESTIMATE(zsb));
+		dmu_tx_hold_zap(tx, MASTER_NODE_OBJ, FALSE, NULL);
+	} else {
+		dmu_tx_hold_bonus(tx, zsb->z_fuid_obj);
+		dmu_tx_hold_write(tx, zsb->z_fuid_obj, 0,
+		    FUID_SIZE_ESTIMATE(zsb));
+	}
+}
+#endif
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/module/zfs/zfs_ioctl.c
@@ -0,0 +1,6059 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Portions Copyright 2011 Martin Matuska
+ * Portions Copyright 2012 Pawel Jakub Dawidek <pawel@dawidek.net>
+ * Copyright (c) 2012, Joyent, Inc. All rights reserved.
+ * Copyright 2011 Nexenta Systems, Inc.  All rights reserved.
+ * Copyright (c) 2014, Joyent, Inc. All rights reserved.
+ * Copyright (c) 2011, 2014 by Delphix. All rights reserved.
+ * Copyright (c) 2013 by Saso Kiselkov. All rights reserved.
+ * Copyright (c) 2013 Steven Hartland. All rights reserved.
+ * Copyright (c) 2014, Nexenta Systems, Inc. All rights reserved.
+ * Copyright (c) 2016 Actifio, Inc. All rights reserved.
+ */
+
+/*
+ * ZFS ioctls.
+ *
+ * This file handles the ioctls to /dev/zfs, used for configuring ZFS storage
+ * pools and filesystems, e.g. with /sbin/zfs and /sbin/zpool.
+ *
+ * There are two ways that we handle ioctls: the legacy way where almost
+ * all of the logic is in the ioctl callback, and the new way where most
+ * of the marshalling is handled in the common entry point, zfsdev_ioctl().
+ *
+ * Non-legacy ioctls should be registered by calling
+ * zfs_ioctl_register() from zfs_ioctl_init().  The ioctl is invoked
+ * from userland by lzc_ioctl().
+ *
+ * The registration arguments are as follows:
+ *
+ * const char *name
+ *   The name of the ioctl.  This is used for history logging.  If the
+ *   ioctl returns successfully (the callback returns 0), and allow_log
+ *   is true, then a history log entry will be recorded with the input &
+ *   output nvlists.  The log entry can be printed with "zpool history -i".
+ *
+ * zfs_ioc_t ioc
+ *   The ioctl request number, which userland will pass to ioctl(2).
+ *   The ioctl numbers can change from release to release, because
+ *   the caller (libzfs) must be matched to the kernel.
+ *
+ * zfs_secpolicy_func_t *secpolicy
+ *   This function will be called before the zfs_ioc_func_t, to
+ *   determine if this operation is permitted.  It should return EPERM
+ *   on failure, and 0 on success.  Checks include determining if the
+ *   dataset is visible in this zone, and if the user has either all
+ *   zfs privileges in the zone (SYS_MOUNT), or has been granted permission
+ *   to do this operation on this dataset with "zfs allow".
+ *
+ * zfs_ioc_namecheck_t namecheck
+ *   This specifies what to expect in the zfs_cmd_t:zc_name -- a pool
+ *   name, a dataset name, or nothing.  If the name is not well-formed,
+ *   the ioctl will fail and the callback will not be called.
+ *   Therefore, the callback can assume that the name is well-formed
+ *   (e.g. is null-terminated, doesn't have more than one '@' character,
+ *   doesn't have invalid characters).
+ *
+ * zfs_ioc_poolcheck_t pool_check
+ *   This specifies requirements on the pool state.  If the pool does
+ *   not meet them (is suspended or is readonly), the ioctl will fail
+ *   and the callback will not be called.  If any checks are specified
+ *   (i.e. it is not POOL_CHECK_NONE), namecheck must not be NO_NAME.
+ *   Multiple checks can be or-ed together (e.g. POOL_CHECK_SUSPENDED |
+ *   POOL_CHECK_READONLY).
+ *
+ * boolean_t smush_outnvlist
+ *   If smush_outnvlist is true, then the output is presumed to be a
+ *   list of errors, and it will be "smushed" down to fit into the
+ *   caller's buffer, by removing some entries and replacing them with a
+ *   single "N_MORE_ERRORS" entry indicating how many were removed.  See
+ *   nvlist_smush() for details.  If smush_outnvlist is false, and the
+ *   outnvlist does not fit into the userland-provided buffer, then the
+ *   ioctl will fail with ENOMEM.
+ *
+ * zfs_ioc_func_t *func
+ *   The callback function that will perform the operation.
+ *
+ *   The callback should return 0 on success, or an error number on
+ *   failure.  If the function fails, the userland ioctl will return -1,
+ *   and errno will be set to the callback's return value.  The callback
+ *   will be called with the following arguments:
+ *
+ *   const char *name
+ *     The name of the pool or dataset to operate on, from
+ *     zfs_cmd_t:zc_name.  The 'namecheck' argument specifies the
+ *     expected type (pool, dataset, or none).
+ *
+ *   nvlist_t *innvl
+ *     The input nvlist, deserialized from zfs_cmd_t:zc_nvlist_src.  Or
+ *     NULL if no input nvlist was provided.  Changes to this nvlist are
+ *     ignored.  If the input nvlist could not be deserialized, the
+ *     ioctl will fail and the callback will not be called.
+ *
+ *   nvlist_t *outnvl
+ *     The output nvlist, initially empty.  The callback can fill it in,
+ *     and it will be returned to userland by serializing it into
+ *     zfs_cmd_t:zc_nvlist_dst.  If it is non-empty, and serialization
+ *     fails (e.g. because the caller didn't supply a large enough
+ *     buffer), then the overall ioctl will fail.  See the
+ *     'smush_nvlist' argument above for additional behaviors.
+ *
+ *     There are two typical uses of the output nvlist:
+ *       - To return state, e.g. property values.  In this case,
+ *         smush_outnvlist should be false.  If the buffer was not large
+ *         enough, the caller will reallocate a larger buffer and try
+ *         the ioctl again.
+ *
+ *       - To return multiple errors from an ioctl which makes on-disk
+ *         changes.  In this case, smush_outnvlist should be true.
+ *         Ioctls which make on-disk modifications should generally not
+ *         use the outnvl if they succeed, because the caller can not
+ *         distinguish between the operation failing, and
+ *         deserialization failing.
+ */
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/errno.h>
+#include <sys/uio.h>
+#include <sys/buf.h>
+#include <sys/modctl.h>
+#include <sys/open.h>
+#include <sys/file.h>
+#include <sys/kmem.h>
+#include <sys/conf.h>
+#include <sys/cmn_err.h>
+#include <sys/stat.h>
+#include <sys/zfs_ioctl.h>
+#include <sys/zfs_vfsops.h>
+#include <sys/zfs_znode.h>
+#include <sys/zap.h>
+#include <sys/spa.h>
+#include <sys/spa_impl.h>
+#include <sys/vdev.h>
+#include <sys/priv_impl.h>
+#include <sys/dmu.h>
+#include <sys/dsl_dir.h>
+#include <sys/dsl_dataset.h>
+#include <sys/dsl_prop.h>
+#include <sys/dsl_deleg.h>
+#include <sys/dmu_objset.h>
+#include <sys/dmu_impl.h>
+#include <sys/dmu_tx.h>
+#include <sys/ddi.h>
+#include <sys/sunddi.h>
+#include <sys/sunldi.h>
+#include <sys/policy.h>
+#include <sys/zone.h>
+#include <sys/nvpair.h>
+#include <sys/pathname.h>
+#include <sys/mount.h>
+#include <sys/sdt.h>
+#include <sys/fs/zfs.h>
+#include <sys/zfs_ctldir.h>
+#include <sys/zfs_dir.h>
+#include <sys/zfs_onexit.h>
+#include <sys/zvol.h>
+#include <sys/dsl_scan.h>
+#include <sharefs/share.h>
+#include <sys/fm/util.h>
+
+#include <sys/dmu_send.h>
+#include <sys/dsl_destroy.h>
+#include <sys/dsl_bookmark.h>
+#include <sys/dsl_userhold.h>
+#include <sys/zfeature.h>
+
+#include <linux/miscdevice.h>
+
+#include "zfs_namecheck.h"
+#include "zfs_prop.h"
+#include "zfs_deleg.h"
+#include "zfs_comutil.h"
+
+kmutex_t zfsdev_state_lock;
+zfsdev_state_t *zfsdev_state_list;
+
+extern void zfs_init(void);
+extern void zfs_fini(void);
+
+uint_t zfs_fsyncer_key;
+extern uint_t rrw_tsd_key;
+static uint_t zfs_allow_log_key;
+
+typedef int zfs_ioc_legacy_func_t(zfs_cmd_t *);
+typedef int zfs_ioc_func_t(const char *, nvlist_t *, nvlist_t *);
+typedef int zfs_secpolicy_func_t(zfs_cmd_t *, nvlist_t *, cred_t *);
+
+typedef enum {
+	NO_NAME,
+	POOL_NAME,
+	DATASET_NAME
+} zfs_ioc_namecheck_t;
+
+typedef enum {
+	POOL_CHECK_NONE		= 1 << 0,
+	POOL_CHECK_SUSPENDED	= 1 << 1,
+	POOL_CHECK_READONLY	= 1 << 2,
+} zfs_ioc_poolcheck_t;
+
+typedef struct zfs_ioc_vec {
+	zfs_ioc_legacy_func_t	*zvec_legacy_func;
+	zfs_ioc_func_t		*zvec_func;
+	zfs_secpolicy_func_t	*zvec_secpolicy;
+	zfs_ioc_namecheck_t	zvec_namecheck;
+	boolean_t		zvec_allow_log;
+	zfs_ioc_poolcheck_t	zvec_pool_check;
+	boolean_t		zvec_smush_outnvlist;
+	const char		*zvec_name;
+} zfs_ioc_vec_t;
+
+/* This array is indexed by zfs_userquota_prop_t */
+static const char *userquota_perms[] = {
+	ZFS_DELEG_PERM_USERUSED,
+	ZFS_DELEG_PERM_USERQUOTA,
+	ZFS_DELEG_PERM_GROUPUSED,
+	ZFS_DELEG_PERM_GROUPQUOTA,
+};
+
+static int zfs_ioc_userspace_upgrade(zfs_cmd_t *zc);
+static int zfs_check_settable(const char *name, nvpair_t *property,
+    cred_t *cr);
+static int zfs_check_clearable(char *dataset, nvlist_t *props,
+    nvlist_t **errors);
+static int zfs_fill_zplprops_root(uint64_t, nvlist_t *, nvlist_t *,
+    boolean_t *);
+int zfs_set_prop_nvlist(const char *, zprop_source_t, nvlist_t *, nvlist_t *);
+static int get_nvlist(uint64_t nvl, uint64_t size, int iflag, nvlist_t **nvp);
+
+static void
+history_str_free(char *buf)
+{
+	kmem_free(buf, HIS_MAX_RECORD_LEN);
+}
+
+static char *
+history_str_get(zfs_cmd_t *zc)
+{
+	char *buf;
+
+	if (zc->zc_history == 0)
+		return (NULL);
+
+	buf = kmem_alloc(HIS_MAX_RECORD_LEN, KM_SLEEP);
+	if (copyinstr((void *)(uintptr_t)zc->zc_history,
+	    buf, HIS_MAX_RECORD_LEN, NULL) != 0) {
+		history_str_free(buf);
+		return (NULL);
+	}
+
+	buf[HIS_MAX_RECORD_LEN -1] = '\0';
+
+	return (buf);
+}
+
+/*
+ * Check to see if the named dataset is currently defined as bootable
+ */
+static boolean_t
+zfs_is_bootfs(const char *name)
+{
+	objset_t *os;
+
+	if (dmu_objset_hold(name, FTAG, &os) == 0) {
+		boolean_t ret;
+		ret = (dmu_objset_id(os) == spa_bootfs(dmu_objset_spa(os)));
+		dmu_objset_rele(os, FTAG);
+		return (ret);
+	}
+	return (B_FALSE);
+}
+
+/*
+ * Return non-zero if the spa version is less than requested version.
+ */
+static int
+zfs_earlier_version(const char *name, int version)
+{
+	spa_t *spa;
+
+	if (spa_open(name, &spa, FTAG) == 0) {
+		if (spa_version(spa) < version) {
+			spa_close(spa, FTAG);
+			return (1);
+		}
+		spa_close(spa, FTAG);
+	}
+	return (0);
+}
+
+/*
+ * Return TRUE if the ZPL version is less than requested version.
+ */
+static boolean_t
+zpl_earlier_version(const char *name, int version)
+{
+	objset_t *os;
+	boolean_t rc = B_TRUE;
+
+	if (dmu_objset_hold(name, FTAG, &os) == 0) {
+		uint64_t zplversion;
+
+		if (dmu_objset_type(os) != DMU_OST_ZFS) {
+			dmu_objset_rele(os, FTAG);
+			return (B_TRUE);
+		}
+		/* XXX reading from non-owned objset */
+		if (zfs_get_zplprop(os, ZFS_PROP_VERSION, &zplversion) == 0)
+			rc = zplversion < version;
+		dmu_objset_rele(os, FTAG);
+	}
+	return (rc);
+}
+
+static void
+zfs_log_history(zfs_cmd_t *zc)
+{
+	spa_t *spa;
+	char *buf;
+
+	if ((buf = history_str_get(zc)) == NULL)
+		return;
+
+	if (spa_open(zc->zc_name, &spa, FTAG) == 0) {
+		if (spa_version(spa) >= SPA_VERSION_ZPOOL_HISTORY)
+			(void) spa_history_log(spa, buf);
+		spa_close(spa, FTAG);
+	}
+	history_str_free(buf);
+}
+
+/*
+ * Policy for top-level read operations (list pools).  Requires no privileges,
+ * and can be used in the local zone, as there is no associated dataset.
+ */
+/* ARGSUSED */
+static int
+zfs_secpolicy_none(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr)
+{
+	return (0);
+}
+
+/*
+ * Policy for dataset read operations (list children, get statistics).  Requires
+ * no privileges, but must be visible in the local zone.
+ */
+/* ARGSUSED */
+static int
+zfs_secpolicy_read(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr)
+{
+	if (INGLOBALZONE(curproc) ||
+	    zone_dataset_visible(zc->zc_name, NULL))
+		return (0);
+
+	return (SET_ERROR(ENOENT));
+}
+
+static int
+zfs_dozonecheck_impl(const char *dataset, uint64_t zoned, cred_t *cr)
+{
+	int writable = 1;
+
+	/*
+	 * The dataset must be visible by this zone -- check this first
+	 * so they don't see EPERM on something they shouldn't know about.
+	 */
+	if (!INGLOBALZONE(curproc) &&
+	    !zone_dataset_visible(dataset, &writable))
+		return (SET_ERROR(ENOENT));
+
+	if (INGLOBALZONE(curproc)) {
+		/*
+		 * If the fs is zoned, only root can access it from the
+		 * global zone.
+		 */
+		if (secpolicy_zfs(cr) && zoned)
+			return (SET_ERROR(EPERM));
+	} else {
+		/*
+		 * If we are in a local zone, the 'zoned' property must be set.
+		 */
+		if (!zoned)
+			return (SET_ERROR(EPERM));
+
+		/* must be writable by this zone */
+		if (!writable)
+			return (SET_ERROR(EPERM));
+	}
+	return (0);
+}
+
+static int
+zfs_dozonecheck(const char *dataset, cred_t *cr)
+{
+	uint64_t zoned;
+
+	if (dsl_prop_get_integer(dataset, "zoned", &zoned, NULL))
+		return (SET_ERROR(ENOENT));
+
+	return (zfs_dozonecheck_impl(dataset, zoned, cr));
+}
+
+static int
+zfs_dozonecheck_ds(const char *dataset, dsl_dataset_t *ds, cred_t *cr)
+{
+	uint64_t zoned;
+
+	if (dsl_prop_get_int_ds(ds, "zoned", &zoned))
+		return (SET_ERROR(ENOENT));
+
+	return (zfs_dozonecheck_impl(dataset, zoned, cr));
+}
+
+static int
+zfs_secpolicy_write_perms_ds(const char *name, dsl_dataset_t *ds,
+    const char *perm, cred_t *cr)
+{
+	int error;
+
+	error = zfs_dozonecheck_ds(name, ds, cr);
+	if (error == 0) {
+		error = secpolicy_zfs(cr);
+		if (error != 0)
+			error = dsl_deleg_access_impl(ds, perm, cr);
+	}
+	return (error);
+}
+
+static int
+zfs_secpolicy_write_perms(const char *name, const char *perm, cred_t *cr)
+{
+	int error;
+	dsl_dataset_t *ds;
+	dsl_pool_t *dp;
+
+	error = dsl_pool_hold(name, FTAG, &dp);
+	if (error != 0)
+		return (error);
+
+	error = dsl_dataset_hold(dp, name, FTAG, &ds);
+	if (error != 0) {
+		dsl_pool_rele(dp, FTAG);
+		return (error);
+	}
+
+	error = zfs_secpolicy_write_perms_ds(name, ds, perm, cr);
+
+	dsl_dataset_rele(ds, FTAG);
+	dsl_pool_rele(dp, FTAG);
+	return (error);
+}
+
+/*
+ * Policy for setting the security label property.
+ *
+ * Returns 0 for success, non-zero for access and other errors.
+ */
+static int
+zfs_set_slabel_policy(const char *name, char *strval, cred_t *cr)
+{
+#ifdef HAVE_MLSLABEL
+	char		ds_hexsl[MAXNAMELEN];
+	bslabel_t	ds_sl, new_sl;
+	boolean_t	new_default = FALSE;
+	uint64_t	zoned;
+	int		needed_priv = -1;
+	int		error;
+
+	/* First get the existing dataset label. */
+	error = dsl_prop_get(name, zfs_prop_to_name(ZFS_PROP_MLSLABEL),
+	    1, sizeof (ds_hexsl), &ds_hexsl, NULL);
+	if (error != 0)
+		return (SET_ERROR(EPERM));
+
+	if (strcasecmp(strval, ZFS_MLSLABEL_DEFAULT) == 0)
+		new_default = TRUE;
+
+	/* The label must be translatable */
+	if (!new_default && (hexstr_to_label(strval, &new_sl) != 0))
+		return (SET_ERROR(EINVAL));
+
+	/*
+	 * In a non-global zone, disallow attempts to set a label that
+	 * doesn't match that of the zone; otherwise no other checks
+	 * are needed.
+	 */
+	if (!INGLOBALZONE(curproc)) {
+		if (new_default || !blequal(&new_sl, CR_SL(CRED())))
+			return (SET_ERROR(EPERM));
+		return (0);
+	}
+
+	/*
+	 * For global-zone datasets (i.e., those whose zoned property is
+	 * "off", verify that the specified new label is valid for the
+	 * global zone.
+	 */
+	if (dsl_prop_get_integer(name,
+	    zfs_prop_to_name(ZFS_PROP_ZONED), &zoned, NULL))
+		return (SET_ERROR(EPERM));
+	if (!zoned) {
+		if (zfs_check_global_label(name, strval) != 0)
+			return (SET_ERROR(EPERM));
+	}
+
+	/*
+	 * If the existing dataset label is nondefault, check if the
+	 * dataset is mounted (label cannot be changed while mounted).
+	 * Get the zfs_sb_t; if there isn't one, then the dataset isn't
+	 * mounted (or isn't a dataset, doesn't exist, ...).
+	 */
+	if (strcasecmp(ds_hexsl, ZFS_MLSLABEL_DEFAULT) != 0) {
+		objset_t *os;
+		static char *setsl_tag = "setsl_tag";
+
+		/*
+		 * Try to own the dataset; abort if there is any error,
+		 * (e.g., already mounted, in use, or other error).
+		 */
+		error = dmu_objset_own(name, DMU_OST_ZFS, B_TRUE,
+		    setsl_tag, &os);
+		if (error != 0)
+			return (SET_ERROR(EPERM));
+
+		dmu_objset_disown(os, setsl_tag);
+
+		if (new_default) {
+			needed_priv = PRIV_FILE_DOWNGRADE_SL;
+			goto out_check;
+		}
+
+		if (hexstr_to_label(strval, &new_sl) != 0)
+			return (SET_ERROR(EPERM));
+
+		if (blstrictdom(&ds_sl, &new_sl))
+			needed_priv = PRIV_FILE_DOWNGRADE_SL;
+		else if (blstrictdom(&new_sl, &ds_sl))
+			needed_priv = PRIV_FILE_UPGRADE_SL;
+	} else {
+		/* dataset currently has a default label */
+		if (!new_default)
+			needed_priv = PRIV_FILE_UPGRADE_SL;
+	}
+
+out_check:
+	if (needed_priv != -1)
+		return (PRIV_POLICY(cr, needed_priv, B_FALSE, EPERM, NULL));
+	return (0);
+#else
+	return (ENOTSUP);
+#endif /* HAVE_MLSLABEL */
+}
+
+static int
+zfs_secpolicy_setprop(const char *dsname, zfs_prop_t prop, nvpair_t *propval,
+    cred_t *cr)
+{
+	char *strval;
+
+	/*
+	 * Check permissions for special properties.
+	 */
+	switch (prop) {
+	default:
+		break;
+	case ZFS_PROP_ZONED:
+		/*
+		 * Disallow setting of 'zoned' from within a local zone.
+		 */
+		if (!INGLOBALZONE(curproc))
+			return (SET_ERROR(EPERM));
+		break;
+
+	case ZFS_PROP_QUOTA:
+	case ZFS_PROP_FILESYSTEM_LIMIT:
+	case ZFS_PROP_SNAPSHOT_LIMIT:
+		if (!INGLOBALZONE(curproc)) {
+			uint64_t zoned;
+			char setpoint[MAXNAMELEN];
+			/*
+			 * Unprivileged users are allowed to modify the
+			 * limit on things *under* (ie. contained by)
+			 * the thing they own.
+			 */
+			if (dsl_prop_get_integer(dsname, "zoned", &zoned,
+			    setpoint))
+				return (SET_ERROR(EPERM));
+			if (!zoned || strlen(dsname) <= strlen(setpoint))
+				return (SET_ERROR(EPERM));
+		}
+		break;
+
+	case ZFS_PROP_MLSLABEL:
+		if (!is_system_labeled())
+			return (SET_ERROR(EPERM));
+
+		if (nvpair_value_string(propval, &strval) == 0) {
+			int err;
+
+			err = zfs_set_slabel_policy(dsname, strval, CRED());
+			if (err != 0)
+				return (err);
+		}
+		break;
+	}
+
+	return (zfs_secpolicy_write_perms(dsname, zfs_prop_to_name(prop), cr));
+}
+
+/* ARGSUSED */
+static int
+zfs_secpolicy_set_fsacl(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr)
+{
+	int error;
+
+	error = zfs_dozonecheck(zc->zc_name, cr);
+	if (error != 0)
+		return (error);
+
+	/*
+	 * permission to set permissions will be evaluated later in
+	 * dsl_deleg_can_allow()
+	 */
+	return (0);
+}
+
+/* ARGSUSED */
+static int
+zfs_secpolicy_rollback(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr)
+{
+	return (zfs_secpolicy_write_perms(zc->zc_name,
+	    ZFS_DELEG_PERM_ROLLBACK, cr));
+}
+
+/* ARGSUSED */
+static int
+zfs_secpolicy_send(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr)
+{
+	dsl_pool_t *dp;
+	dsl_dataset_t *ds;
+	char *cp;
+	int error;
+
+	/*
+	 * Generate the current snapshot name from the given objsetid, then
+	 * use that name for the secpolicy/zone checks.
+	 */
+	cp = strchr(zc->zc_name, '@');
+	if (cp == NULL)
+		return (SET_ERROR(EINVAL));
+	error = dsl_pool_hold(zc->zc_name, FTAG, &dp);
+	if (error != 0)
+		return (error);
+
+	error = dsl_dataset_hold_obj(dp, zc->zc_sendobj, FTAG, &ds);
+	if (error != 0) {
+		dsl_pool_rele(dp, FTAG);
+		return (error);
+	}
+
+	dsl_dataset_name(ds, zc->zc_name);
+
+	error = zfs_secpolicy_write_perms_ds(zc->zc_name, ds,
+	    ZFS_DELEG_PERM_SEND, cr);
+	dsl_dataset_rele(ds, FTAG);
+	dsl_pool_rele(dp, FTAG);
+
+	return (error);
+}
+
+/* ARGSUSED */
+static int
+zfs_secpolicy_send_new(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr)
+{
+	return (zfs_secpolicy_write_perms(zc->zc_name,
+	    ZFS_DELEG_PERM_SEND, cr));
+}
+
+#ifdef HAVE_SMB_SHARE
+/* ARGSUSED */
+static int
+zfs_secpolicy_deleg_share(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr)
+{
+	vnode_t *vp;
+	int error;
+
+	if ((error = lookupname(zc->zc_value, UIO_SYSSPACE,
+	    NO_FOLLOW, NULL, &vp)) != 0)
+		return (error);
+
+	/* Now make sure mntpnt and dataset are ZFS */
+
+	if (vp->v_vfsp->vfs_fstype != zfsfstype ||
+	    (strcmp((char *)refstr_value(vp->v_vfsp->vfs_resource),
+	    zc->zc_name) != 0)) {
+		VN_RELE(vp);
+		return (SET_ERROR(EPERM));
+	}
+
+	VN_RELE(vp);
+	return (dsl_deleg_access(zc->zc_name,
+	    ZFS_DELEG_PERM_SHARE, cr));
+}
+#endif /* HAVE_SMB_SHARE */
+
+int
+zfs_secpolicy_share(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr)
+{
+#ifdef HAVE_SMB_SHARE
+	if (!INGLOBALZONE(curproc))
+		return (SET_ERROR(EPERM));
+
+	if (secpolicy_nfs(cr) == 0) {
+		return (0);
+	} else {
+		return (zfs_secpolicy_deleg_share(zc, innvl, cr));
+	}
+#else
+	return (SET_ERROR(ENOTSUP));
+#endif /* HAVE_SMB_SHARE */
+}
+
+int
+zfs_secpolicy_smb_acl(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr)
+{
+#ifdef HAVE_SMB_SHARE
+	if (!INGLOBALZONE(curproc))
+		return (SET_ERROR(EPERM));
+
+	if (secpolicy_smb(cr) == 0) {
+		return (0);
+	} else {
+		return (zfs_secpolicy_deleg_share(zc, innvl, cr));
+	}
+#else
+	return (SET_ERROR(ENOTSUP));
+#endif /* HAVE_SMB_SHARE */
+}
+
+static int
+zfs_get_parent(const char *datasetname, char *parent, int parentsize)
+{
+	char *cp;
+
+	/*
+	 * Remove the @bla or /bla from the end of the name to get the parent.
+	 */
+	(void) strncpy(parent, datasetname, parentsize);
+	cp = strrchr(parent, '@');
+	if (cp != NULL) {
+		cp[0] = '\0';
+	} else {
+		cp = strrchr(parent, '/');
+		if (cp == NULL)
+			return (SET_ERROR(ENOENT));
+		cp[0] = '\0';
+	}
+
+	return (0);
+}
+
+int
+zfs_secpolicy_destroy_perms(const char *name, cred_t *cr)
+{
+	int error;
+
+	if ((error = zfs_secpolicy_write_perms(name,
+	    ZFS_DELEG_PERM_MOUNT, cr)) != 0)
+		return (error);
+
+	return (zfs_secpolicy_write_perms(name, ZFS_DELEG_PERM_DESTROY, cr));
+}
+
+/* ARGSUSED */
+static int
+zfs_secpolicy_destroy(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr)
+{
+	return (zfs_secpolicy_destroy_perms(zc->zc_name, cr));
+}
+
+/*
+ * Destroying snapshots with delegated permissions requires
+ * descendant mount and destroy permissions.
+ */
+/* ARGSUSED */
+static int
+zfs_secpolicy_destroy_snaps(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr)
+{
+	nvlist_t *snaps;
+	nvpair_t *pair, *nextpair;
+	int error = 0;
+
+	if (nvlist_lookup_nvlist(innvl, "snaps", &snaps) != 0)
+		return (SET_ERROR(EINVAL));
+	for (pair = nvlist_next_nvpair(snaps, NULL); pair != NULL;
+	    pair = nextpair) {
+		nextpair = nvlist_next_nvpair(snaps, pair);
+		error = zfs_secpolicy_destroy_perms(nvpair_name(pair), cr);
+		if (error == ENOENT) {
+			/*
+			 * Ignore any snapshots that don't exist (we consider
+			 * them "already destroyed").  Remove the name from the
+			 * nvl here in case the snapshot is created between
+			 * now and when we try to destroy it (in which case
+			 * we don't want to destroy it since we haven't
+			 * checked for permission).
+			 */
+			fnvlist_remove_nvpair(snaps, pair);
+			error = 0;
+		}
+		if (error != 0)
+			break;
+	}
+
+	return (error);
+}
+
+int
+zfs_secpolicy_rename_perms(const char *from, const char *to, cred_t *cr)
+{
+	char	parentname[MAXNAMELEN];
+	int	error;
+
+	if ((error = zfs_secpolicy_write_perms(from,
+	    ZFS_DELEG_PERM_RENAME, cr)) != 0)
+		return (error);
+
+	if ((error = zfs_secpolicy_write_perms(from,
+	    ZFS_DELEG_PERM_MOUNT, cr)) != 0)
+		return (error);
+
+	if ((error = zfs_get_parent(to, parentname,
+	    sizeof (parentname))) != 0)
+		return (error);
+
+	if ((error = zfs_secpolicy_write_perms(parentname,
+	    ZFS_DELEG_PERM_CREATE, cr)) != 0)
+		return (error);
+
+	if ((error = zfs_secpolicy_write_perms(parentname,
+	    ZFS_DELEG_PERM_MOUNT, cr)) != 0)
+		return (error);
+
+	return (error);
+}
+
+/* ARGSUSED */
+static int
+zfs_secpolicy_rename(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr)
+{
+	return (zfs_secpolicy_rename_perms(zc->zc_name, zc->zc_value, cr));
+}
+
+/* ARGSUSED */
+static int
+zfs_secpolicy_promote(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr)
+{
+	dsl_pool_t *dp;
+	dsl_dataset_t *clone;
+	int error;
+
+	error = zfs_secpolicy_write_perms(zc->zc_name,
+	    ZFS_DELEG_PERM_PROMOTE, cr);
+	if (error != 0)
+		return (error);
+
+	error = dsl_pool_hold(zc->zc_name, FTAG, &dp);
+	if (error != 0)
+		return (error);
+
+	error = dsl_dataset_hold(dp, zc->zc_name, FTAG, &clone);
+
+	if (error == 0) {
+		char parentname[MAXNAMELEN];
+		dsl_dataset_t *origin = NULL;
+		dsl_dir_t *dd;
+		dd = clone->ds_dir;
+
+		error = dsl_dataset_hold_obj(dd->dd_pool,
+		    dsl_dir_phys(dd)->dd_origin_obj, FTAG, &origin);
+		if (error != 0) {
+			dsl_dataset_rele(clone, FTAG);
+			dsl_pool_rele(dp, FTAG);
+			return (error);
+		}
+
+		error = zfs_secpolicy_write_perms_ds(zc->zc_name, clone,
+		    ZFS_DELEG_PERM_MOUNT, cr);
+
+		dsl_dataset_name(origin, parentname);
+		if (error == 0) {
+			error = zfs_secpolicy_write_perms_ds(parentname, origin,
+			    ZFS_DELEG_PERM_PROMOTE, cr);
+		}
+		dsl_dataset_rele(clone, FTAG);
+		dsl_dataset_rele(origin, FTAG);
+	}
+	dsl_pool_rele(dp, FTAG);
+	return (error);
+}
+
+/* ARGSUSED */
+static int
+zfs_secpolicy_recv(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr)
+{
+	int error;
+
+	if ((error = zfs_secpolicy_write_perms(zc->zc_name,
+	    ZFS_DELEG_PERM_RECEIVE, cr)) != 0)
+		return (error);
+
+	if ((error = zfs_secpolicy_write_perms(zc->zc_name,
+	    ZFS_DELEG_PERM_MOUNT, cr)) != 0)
+		return (error);
+
+	return (zfs_secpolicy_write_perms(zc->zc_name,
+	    ZFS_DELEG_PERM_CREATE, cr));
+}
+
+int
+zfs_secpolicy_snapshot_perms(const char *name, cred_t *cr)
+{
+	return (zfs_secpolicy_write_perms(name,
+	    ZFS_DELEG_PERM_SNAPSHOT, cr));
+}
+
+/*
+ * Check for permission to create each snapshot in the nvlist.
+ */
+/* ARGSUSED */
+static int
+zfs_secpolicy_snapshot(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr)
+{
+	nvlist_t *snaps;
+	int error = 0;
+	nvpair_t *pair;
+
+	if (nvlist_lookup_nvlist(innvl, "snaps", &snaps) != 0)
+		return (SET_ERROR(EINVAL));
+	for (pair = nvlist_next_nvpair(snaps, NULL); pair != NULL;
+	    pair = nvlist_next_nvpair(snaps, pair)) {
+		char *name = nvpair_name(pair);
+		char *atp = strchr(name, '@');
+
+		if (atp == NULL) {
+			error = SET_ERROR(EINVAL);
+			break;
+		}
+		*atp = '\0';
+		error = zfs_secpolicy_snapshot_perms(name, cr);
+		*atp = '@';
+		if (error != 0)
+			break;
+	}
+	return (error);
+}
+
+/*
+ * Check for permission to create each snapshot in the nvlist.
+ */
+/* ARGSUSED */
+static int
+zfs_secpolicy_bookmark(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr)
+{
+	int error = 0;
+	nvpair_t *pair;
+
+	for (pair = nvlist_next_nvpair(innvl, NULL);
+	    pair != NULL; pair = nvlist_next_nvpair(innvl, pair)) {
+		char *name = nvpair_name(pair);
+		char *hashp = strchr(name, '#');
+
+		if (hashp == NULL) {
+			error = SET_ERROR(EINVAL);
+			break;
+		}
+		*hashp = '\0';
+		error = zfs_secpolicy_write_perms(name,
+		    ZFS_DELEG_PERM_BOOKMARK, cr);
+		*hashp = '#';
+		if (error != 0)
+			break;
+	}
+	return (error);
+}
+
+/* ARGSUSED */
+static int
+zfs_secpolicy_destroy_bookmarks(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr)
+{
+	nvpair_t *pair, *nextpair;
+	int error = 0;
+
+	for (pair = nvlist_next_nvpair(innvl, NULL); pair != NULL;
+	    pair = nextpair) {
+		char *name = nvpair_name(pair);
+		char *hashp = strchr(name, '#');
+		nextpair = nvlist_next_nvpair(innvl, pair);
+
+		if (hashp == NULL) {
+			error = SET_ERROR(EINVAL);
+			break;
+		}
+
+		*hashp = '\0';
+		error = zfs_secpolicy_write_perms(name,
+		    ZFS_DELEG_PERM_DESTROY, cr);
+		*hashp = '#';
+		if (error == ENOENT) {
+			/*
+			 * Ignore any filesystems that don't exist (we consider
+			 * their bookmarks "already destroyed").  Remove
+			 * the name from the nvl here in case the filesystem
+			 * is created between now and when we try to destroy
+			 * the bookmark (in which case we don't want to
+			 * destroy it since we haven't checked for permission).
+			 */
+			fnvlist_remove_nvpair(innvl, pair);
+			error = 0;
+		}
+		if (error != 0)
+			break;
+	}
+
+	return (error);
+}
+
+/* ARGSUSED */
+static int
+zfs_secpolicy_log_history(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr)
+{
+	/*
+	 * Even root must have a proper TSD so that we know what pool
+	 * to log to.
+	 */
+	if (tsd_get(zfs_allow_log_key) == NULL)
+		return (SET_ERROR(EPERM));
+	return (0);
+}
+
+static int
+zfs_secpolicy_create_clone(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr)
+{
+	char	parentname[MAXNAMELEN];
+	int	error;
+	char	*origin;
+
+	if ((error = zfs_get_parent(zc->zc_name, parentname,
+	    sizeof (parentname))) != 0)
+		return (error);
+
+	if (nvlist_lookup_string(innvl, "origin", &origin) == 0 &&
+	    (error = zfs_secpolicy_write_perms(origin,
+	    ZFS_DELEG_PERM_CLONE, cr)) != 0)
+		return (error);
+
+	if ((error = zfs_secpolicy_write_perms(parentname,
+	    ZFS_DELEG_PERM_CREATE, cr)) != 0)
+		return (error);
+
+	return (zfs_secpolicy_write_perms(parentname,
+	    ZFS_DELEG_PERM_MOUNT, cr));
+}
+
+/*
+ * Policy for pool operations - create/destroy pools, add vdevs, etc.  Requires
+ * SYS_CONFIG privilege, which is not available in a local zone.
+ */
+/* ARGSUSED */
+static int
+zfs_secpolicy_config(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr)
+{
+	if (secpolicy_sys_config(cr, B_FALSE) != 0)
+		return (SET_ERROR(EPERM));
+
+	return (0);
+}
+
+/*
+ * Policy for object to name lookups.
+ */
+/* ARGSUSED */
+static int
+zfs_secpolicy_diff(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr)
+{
+	int error;
+
+	if ((error = secpolicy_sys_config(cr, B_FALSE)) == 0)
+		return (0);
+
+	error = zfs_secpolicy_write_perms(zc->zc_name, ZFS_DELEG_PERM_DIFF, cr);
+	return (error);
+}
+
+/*
+ * Policy for fault injection.  Requires all privileges.
+ */
+/* ARGSUSED */
+static int
+zfs_secpolicy_inject(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr)
+{
+	return (secpolicy_zinject(cr));
+}
+
+/* ARGSUSED */
+static int
+zfs_secpolicy_inherit_prop(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr)
+{
+	zfs_prop_t prop = zfs_name_to_prop(zc->zc_value);
+
+	if (prop == ZPROP_INVAL) {
+		if (!zfs_prop_user(zc->zc_value))
+			return (SET_ERROR(EINVAL));
+		return (zfs_secpolicy_write_perms(zc->zc_name,
+		    ZFS_DELEG_PERM_USERPROP, cr));
+	} else {
+		return (zfs_secpolicy_setprop(zc->zc_name, prop,
+		    NULL, cr));
+	}
+}
+
+static int
+zfs_secpolicy_userspace_one(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr)
+{
+	int err = zfs_secpolicy_read(zc, innvl, cr);
+	if (err)
+		return (err);
+
+	if (zc->zc_objset_type >= ZFS_NUM_USERQUOTA_PROPS)
+		return (SET_ERROR(EINVAL));
+
+	if (zc->zc_value[0] == 0) {
+		/*
+		 * They are asking about a posix uid/gid.  If it's
+		 * themself, allow it.
+		 */
+		if (zc->zc_objset_type == ZFS_PROP_USERUSED ||
+		    zc->zc_objset_type == ZFS_PROP_USERQUOTA) {
+			if (zc->zc_guid == crgetuid(cr))
+				return (0);
+		} else {
+			if (groupmember(zc->zc_guid, cr))
+				return (0);
+		}
+	}
+
+	return (zfs_secpolicy_write_perms(zc->zc_name,
+	    userquota_perms[zc->zc_objset_type], cr));
+}
+
+static int
+zfs_secpolicy_userspace_many(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr)
+{
+	int err = zfs_secpolicy_read(zc, innvl, cr);
+	if (err)
+		return (err);
+
+	if (zc->zc_objset_type >= ZFS_NUM_USERQUOTA_PROPS)
+		return (SET_ERROR(EINVAL));
+
+	return (zfs_secpolicy_write_perms(zc->zc_name,
+	    userquota_perms[zc->zc_objset_type], cr));
+}
+
+/* ARGSUSED */
+static int
+zfs_secpolicy_userspace_upgrade(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr)
+{
+	return (zfs_secpolicy_setprop(zc->zc_name, ZFS_PROP_VERSION,
+	    NULL, cr));
+}
+
+/* ARGSUSED */
+static int
+zfs_secpolicy_hold(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr)
+{
+	nvpair_t *pair;
+	nvlist_t *holds;
+	int error;
+
+	error = nvlist_lookup_nvlist(innvl, "holds", &holds);
+	if (error != 0)
+		return (SET_ERROR(EINVAL));
+
+	for (pair = nvlist_next_nvpair(holds, NULL); pair != NULL;
+	    pair = nvlist_next_nvpair(holds, pair)) {
+		char fsname[MAXNAMELEN];
+		error = dmu_fsname(nvpair_name(pair), fsname);
+		if (error != 0)
+			return (error);
+		error = zfs_secpolicy_write_perms(fsname,
+		    ZFS_DELEG_PERM_HOLD, cr);
+		if (error != 0)
+			return (error);
+	}
+	return (0);
+}
+
+/* ARGSUSED */
+static int
+zfs_secpolicy_release(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr)
+{
+	nvpair_t *pair;
+	int error;
+
+	for (pair = nvlist_next_nvpair(innvl, NULL); pair != NULL;
+	    pair = nvlist_next_nvpair(innvl, pair)) {
+		char fsname[MAXNAMELEN];
+		error = dmu_fsname(nvpair_name(pair), fsname);
+		if (error != 0)
+			return (error);
+		error = zfs_secpolicy_write_perms(fsname,
+		    ZFS_DELEG_PERM_RELEASE, cr);
+		if (error != 0)
+			return (error);
+	}
+	return (0);
+}
+
+/*
+ * Policy for allowing temporary snapshots to be taken or released
+ */
+static int
+zfs_secpolicy_tmp_snapshot(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr)
+{
+	/*
+	 * A temporary snapshot is the same as a snapshot,
+	 * hold, destroy and release all rolled into one.
+	 * Delegated diff alone is sufficient that we allow this.
+	 */
+	int error;
+
+	if ((error = zfs_secpolicy_write_perms(zc->zc_name,
+	    ZFS_DELEG_PERM_DIFF, cr)) == 0)
+		return (0);
+
+	error = zfs_secpolicy_snapshot_perms(zc->zc_name, cr);
+	if (error == 0)
+		error = zfs_secpolicy_hold(zc, innvl, cr);
+	if (error == 0)
+		error = zfs_secpolicy_release(zc, innvl, cr);
+	if (error == 0)
+		error = zfs_secpolicy_destroy(zc, innvl, cr);
+	return (error);
+}
+
+/*
+ * Returns the nvlist as specified by the user in the zfs_cmd_t.
+ */
+static int
+get_nvlist(uint64_t nvl, uint64_t size, int iflag, nvlist_t **nvp)
+{
+	char *packed;
+	int error;
+	nvlist_t *list = NULL;
+
+	/*
+	 * Read in and unpack the user-supplied nvlist.
+	 */
+	if (size == 0)
+		return (SET_ERROR(EINVAL));
+
+	packed = vmem_alloc(size, KM_SLEEP);
+
+	if ((error = ddi_copyin((void *)(uintptr_t)nvl, packed, size,
+	    iflag)) != 0) {
+		vmem_free(packed, size);
+		return (SET_ERROR(EFAULT));
+	}
+
+	if ((error = nvlist_unpack(packed, size, &list, 0)) != 0) {
+		vmem_free(packed, size);
+		return (error);
+	}
+
+	vmem_free(packed, size);
+
+	*nvp = list;
+	return (0);
+}
+
+/*
+ * Reduce the size of this nvlist until it can be serialized in 'max' bytes.
+ * Entries will be removed from the end of the nvlist, and one int32 entry
+ * named "N_MORE_ERRORS" will be added indicating how many entries were
+ * removed.
+ */
+static int
+nvlist_smush(nvlist_t *errors, size_t max)
+{
+	size_t size;
+
+	size = fnvlist_size(errors);
+
+	if (size > max) {
+		nvpair_t *more_errors;
+		int n = 0;
+
+		if (max < 1024)
+			return (SET_ERROR(ENOMEM));
+
+		fnvlist_add_int32(errors, ZPROP_N_MORE_ERRORS, 0);
+		more_errors = nvlist_prev_nvpair(errors, NULL);
+
+		do {
+			nvpair_t *pair = nvlist_prev_nvpair(errors,
+			    more_errors);
+			fnvlist_remove_nvpair(errors, pair);
+			n++;
+			size = fnvlist_size(errors);
+		} while (size > max);
+
+		fnvlist_remove_nvpair(errors, more_errors);
+		fnvlist_add_int32(errors, ZPROP_N_MORE_ERRORS, n);
+		ASSERT3U(fnvlist_size(errors), <=, max);
+	}
+
+	return (0);
+}
+
+static int
+put_nvlist(zfs_cmd_t *zc, nvlist_t *nvl)
+{
+	char *packed = NULL;
+	int error = 0;
+	size_t size;
+
+	size = fnvlist_size(nvl);
+
+	if (size > zc->zc_nvlist_dst_size) {
+		error = SET_ERROR(ENOMEM);
+	} else {
+		packed = fnvlist_pack(nvl, &size);
+		if (ddi_copyout(packed, (void *)(uintptr_t)zc->zc_nvlist_dst,
+		    size, zc->zc_iflags) != 0)
+			error = SET_ERROR(EFAULT);
+		fnvlist_pack_free(packed, size);
+	}
+
+	zc->zc_nvlist_dst_size = size;
+	zc->zc_nvlist_dst_filled = B_TRUE;
+	return (error);
+}
+
+static int
+get_zfs_sb(const char *dsname, zfs_sb_t **zsbp)
+{
+	objset_t *os;
+	int error;
+
+	error = dmu_objset_hold(dsname, FTAG, &os);
+	if (error != 0)
+		return (error);
+	if (dmu_objset_type(os) != DMU_OST_ZFS) {
+		dmu_objset_rele(os, FTAG);
+		return (SET_ERROR(EINVAL));
+	}
+
+	mutex_enter(&os->os_user_ptr_lock);
+	*zsbp = dmu_objset_get_user(os);
+	if (*zsbp && (*zsbp)->z_sb) {
+		atomic_inc(&((*zsbp)->z_sb->s_active));
+	} else {
+		error = SET_ERROR(ESRCH);
+	}
+	mutex_exit(&os->os_user_ptr_lock);
+	dmu_objset_rele(os, FTAG);
+	return (error);
+}
+
+/*
+ * Find a zfs_sb_t for a mounted filesystem, or create our own, in which
+ * case its z_sb will be NULL, and it will be opened as the owner.
+ * If 'writer' is set, the z_teardown_lock will be held for RW_WRITER,
+ * which prevents all inode ops from running.
+ */
+static int
+zfs_sb_hold(const char *name, void *tag, zfs_sb_t **zsbp, boolean_t writer)
+{
+	int error = 0;
+
+	if (get_zfs_sb(name, zsbp) != 0)
+		error = zfs_sb_create(name, NULL, zsbp);
+	if (error == 0) {
+		rrm_enter(&(*zsbp)->z_teardown_lock, (writer) ? RW_WRITER :
+		    RW_READER, tag);
+		if ((*zsbp)->z_unmounted) {
+			/*
+			 * XXX we could probably try again, since the unmounting
+			 * thread should be just about to disassociate the
+			 * objset from the zsb.
+			 */
+			rrm_exit(&(*zsbp)->z_teardown_lock, tag);
+			return (SET_ERROR(EBUSY));
+		}
+	}
+	return (error);
+}
+
+static void
+zfs_sb_rele(zfs_sb_t *zsb, void *tag)
+{
+	rrm_exit(&zsb->z_teardown_lock, tag);
+
+	if (zsb->z_sb) {
+		deactivate_super(zsb->z_sb);
+	} else {
+		dmu_objset_disown(zsb->z_os, zsb);
+		zfs_sb_free(zsb);
+	}
+}
+
+static int
+zfs_ioc_pool_create(zfs_cmd_t *zc)
+{
+	int error;
+	nvlist_t *config, *props = NULL;
+	nvlist_t *rootprops = NULL;
+	nvlist_t *zplprops = NULL;
+
+	if ((error = get_nvlist(zc->zc_nvlist_conf, zc->zc_nvlist_conf_size,
+	    zc->zc_iflags, &config)))
+		return (error);
+
+	if (zc->zc_nvlist_src_size != 0 && (error =
+	    get_nvlist(zc->zc_nvlist_src, zc->zc_nvlist_src_size,
+	    zc->zc_iflags, &props))) {
+		nvlist_free(config);
+		return (error);
+	}
+
+	if (props) {
+		nvlist_t *nvl = NULL;
+		uint64_t version = SPA_VERSION;
+
+		(void) nvlist_lookup_uint64(props,
+		    zpool_prop_to_name(ZPOOL_PROP_VERSION), &version);
+		if (!SPA_VERSION_IS_SUPPORTED(version)) {
+			error = SET_ERROR(EINVAL);
+			goto pool_props_bad;
+		}
+		(void) nvlist_lookup_nvlist(props, ZPOOL_ROOTFS_PROPS, &nvl);
+		if (nvl) {
+			error = nvlist_dup(nvl, &rootprops, KM_SLEEP);
+			if (error != 0) {
+				nvlist_free(config);
+				nvlist_free(props);
+				return (error);
+			}
+			(void) nvlist_remove_all(props, ZPOOL_ROOTFS_PROPS);
+		}
+		VERIFY(nvlist_alloc(&zplprops, NV_UNIQUE_NAME, KM_SLEEP) == 0);
+		error = zfs_fill_zplprops_root(version, rootprops,
+		    zplprops, NULL);
+		if (error != 0)
+			goto pool_props_bad;
+	}
+
+	error = spa_create(zc->zc_name, config, props, zplprops);
+
+	/*
+	 * Set the remaining root properties
+	 */
+	if (!error && (error = zfs_set_prop_nvlist(zc->zc_name,
+	    ZPROP_SRC_LOCAL, rootprops, NULL)) != 0)
+		(void) spa_destroy(zc->zc_name);
+
+pool_props_bad:
+	nvlist_free(rootprops);
+	nvlist_free(zplprops);
+	nvlist_free(config);
+	nvlist_free(props);
+
+	return (error);
+}
+
+static int
+zfs_ioc_pool_destroy(zfs_cmd_t *zc)
+{
+	int error;
+	zfs_log_history(zc);
+	error = spa_destroy(zc->zc_name);
+
+	return (error);
+}
+
+static int
+zfs_ioc_pool_import(zfs_cmd_t *zc)
+{
+	nvlist_t *config, *props = NULL;
+	uint64_t guid;
+	int error;
+
+	if ((error = get_nvlist(zc->zc_nvlist_conf, zc->zc_nvlist_conf_size,
+	    zc->zc_iflags, &config)) != 0)
+		return (error);
+
+	if (zc->zc_nvlist_src_size != 0 && (error =
+	    get_nvlist(zc->zc_nvlist_src, zc->zc_nvlist_src_size,
+	    zc->zc_iflags, &props))) {
+		nvlist_free(config);
+		return (error);
+	}
+
+	if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_GUID, &guid) != 0 ||
+	    guid != zc->zc_guid)
+		error = SET_ERROR(EINVAL);
+	else
+		error = spa_import(zc->zc_name, config, props, zc->zc_cookie);
+
+	if (zc->zc_nvlist_dst != 0) {
+		int err;
+
+		if ((err = put_nvlist(zc, config)) != 0)
+			error = err;
+	}
+
+	nvlist_free(config);
+
+	if (props)
+		nvlist_free(props);
+
+	return (error);
+}
+
+static int
+zfs_ioc_pool_export(zfs_cmd_t *zc)
+{
+	int error;
+	boolean_t force = (boolean_t)zc->zc_cookie;
+	boolean_t hardforce = (boolean_t)zc->zc_guid;
+
+	zfs_log_history(zc);
+	error = spa_export(zc->zc_name, NULL, force, hardforce);
+
+	return (error);
+}
+
+static int
+zfs_ioc_pool_configs(zfs_cmd_t *zc)
+{
+	nvlist_t *configs;
+	int error;
+
+	if ((configs = spa_all_configs(&zc->zc_cookie)) == NULL)
+		return (SET_ERROR(EEXIST));
+
+	error = put_nvlist(zc, configs);
+
+	nvlist_free(configs);
+
+	return (error);
+}
+
+/*
+ * inputs:
+ * zc_name		name of the pool
+ *
+ * outputs:
+ * zc_cookie		real errno
+ * zc_nvlist_dst	config nvlist
+ * zc_nvlist_dst_size	size of config nvlist
+ */
+static int
+zfs_ioc_pool_stats(zfs_cmd_t *zc)
+{
+	nvlist_t *config;
+	int error;
+	int ret = 0;
+
+	error = spa_get_stats(zc->zc_name, &config, zc->zc_value,
+	    sizeof (zc->zc_value));
+
+	if (config != NULL) {
+		ret = put_nvlist(zc, config);
+		nvlist_free(config);
+
+		/*
+		 * The config may be present even if 'error' is non-zero.
+		 * In this case we return success, and preserve the real errno
+		 * in 'zc_cookie'.
+		 */
+		zc->zc_cookie = error;
+	} else {
+		ret = error;
+	}
+
+	return (ret);
+}
+
+/*
+ * Try to import the given pool, returning pool stats as appropriate so that
+ * user land knows which devices are available and overall pool health.
+ */
+static int
+zfs_ioc_pool_tryimport(zfs_cmd_t *zc)
+{
+	nvlist_t *tryconfig, *config;
+	int error;
+
+	if ((error = get_nvlist(zc->zc_nvlist_conf, zc->zc_nvlist_conf_size,
+	    zc->zc_iflags, &tryconfig)) != 0)
+		return (error);
+
+	config = spa_tryimport(tryconfig);
+
+	nvlist_free(tryconfig);
+
+	if (config == NULL)
+		return (SET_ERROR(EINVAL));
+
+	error = put_nvlist(zc, config);
+	nvlist_free(config);
+
+	return (error);
+}
+
+/*
+ * inputs:
+ * zc_name              name of the pool
+ * zc_cookie            scan func (pool_scan_func_t)
+ */
+static int
+zfs_ioc_pool_scan(zfs_cmd_t *zc)
+{
+	spa_t *spa;
+	int error;
+
+	if ((error = spa_open(zc->zc_name, &spa, FTAG)) != 0)
+		return (error);
+
+	if (zc->zc_cookie == POOL_SCAN_NONE)
+		error = spa_scan_stop(spa);
+	else
+		error = spa_scan(spa, zc->zc_cookie);
+
+	spa_close(spa, FTAG);
+
+	return (error);
+}
+
+static int
+zfs_ioc_pool_freeze(zfs_cmd_t *zc)
+{
+	spa_t *spa;
+	int error;
+
+	error = spa_open(zc->zc_name, &spa, FTAG);
+	if (error == 0) {
+		spa_freeze(spa);
+		spa_close(spa, FTAG);
+	}
+	return (error);
+}
+
+static int
+zfs_ioc_pool_upgrade(zfs_cmd_t *zc)
+{
+	spa_t *spa;
+	int error;
+
+	if ((error = spa_open(zc->zc_name, &spa, FTAG)) != 0)
+		return (error);
+
+	if (zc->zc_cookie < spa_version(spa) ||
+	    !SPA_VERSION_IS_SUPPORTED(zc->zc_cookie)) {
+		spa_close(spa, FTAG);
+		return (SET_ERROR(EINVAL));
+	}
+
+	spa_upgrade(spa, zc->zc_cookie);
+	spa_close(spa, FTAG);
+
+	return (error);
+}
+
+static int
+zfs_ioc_pool_get_history(zfs_cmd_t *zc)
+{
+	spa_t *spa;
+	char *hist_buf;
+	uint64_t size;
+	int error;
+
+	if ((size = zc->zc_history_len) == 0)
+		return (SET_ERROR(EINVAL));
+
+	if ((error = spa_open(zc->zc_name, &spa, FTAG)) != 0)
+		return (error);
+
+	if (spa_version(spa) < SPA_VERSION_ZPOOL_HISTORY) {
+		spa_close(spa, FTAG);
+		return (SET_ERROR(ENOTSUP));
+	}
+
+	hist_buf = vmem_alloc(size, KM_SLEEP);
+	if ((error = spa_history_get(spa, &zc->zc_history_offset,
+	    &zc->zc_history_len, hist_buf)) == 0) {
+		error = ddi_copyout(hist_buf,
+		    (void *)(uintptr_t)zc->zc_history,
+		    zc->zc_history_len, zc->zc_iflags);
+	}
+
+	spa_close(spa, FTAG);
+	vmem_free(hist_buf, size);
+	return (error);
+}
+
+static int
+zfs_ioc_pool_reguid(zfs_cmd_t *zc)
+{
+	spa_t *spa;
+	int error;
+
+	error = spa_open(zc->zc_name, &spa, FTAG);
+	if (error == 0) {
+		error = spa_change_guid(spa);
+		spa_close(spa, FTAG);
+	}
+	return (error);
+}
+
+static int
+zfs_ioc_dsobj_to_dsname(zfs_cmd_t *zc)
+{
+	return (dsl_dsobj_to_dsname(zc->zc_name, zc->zc_obj, zc->zc_value));
+}
+
+/*
+ * inputs:
+ * zc_name		name of filesystem
+ * zc_obj		object to find
+ *
+ * outputs:
+ * zc_value		name of object
+ */
+static int
+zfs_ioc_obj_to_path(zfs_cmd_t *zc)
+{
+	objset_t *os;
+	int error;
+
+	/* XXX reading from objset not owned */
+	if ((error = dmu_objset_hold(zc->zc_name, FTAG, &os)) != 0)
+		return (error);
+	if (dmu_objset_type(os) != DMU_OST_ZFS) {
+		dmu_objset_rele(os, FTAG);
+		return (SET_ERROR(EINVAL));
+	}
+	error = zfs_obj_to_path(os, zc->zc_obj, zc->zc_value,
+	    sizeof (zc->zc_value));
+	dmu_objset_rele(os, FTAG);
+
+	return (error);
+}
+
+/*
+ * inputs:
+ * zc_name		name of filesystem
+ * zc_obj		object to find
+ *
+ * outputs:
+ * zc_stat		stats on object
+ * zc_value		path to object
+ */
+static int
+zfs_ioc_obj_to_stats(zfs_cmd_t *zc)
+{
+	objset_t *os;
+	int error;
+
+	/* XXX reading from objset not owned */
+	if ((error = dmu_objset_hold(zc->zc_name, FTAG, &os)) != 0)
+		return (error);
+	if (dmu_objset_type(os) != DMU_OST_ZFS) {
+		dmu_objset_rele(os, FTAG);
+		return (SET_ERROR(EINVAL));
+	}
+	error = zfs_obj_to_stats(os, zc->zc_obj, &zc->zc_stat, zc->zc_value,
+	    sizeof (zc->zc_value));
+	dmu_objset_rele(os, FTAG);
+
+	return (error);
+}
+
+static int
+zfs_ioc_vdev_add(zfs_cmd_t *zc)
+{
+	spa_t *spa;
+	int error;
+	nvlist_t *config;
+
+	error = spa_open(zc->zc_name, &spa, FTAG);
+	if (error != 0)
+		return (error);
+
+	error = get_nvlist(zc->zc_nvlist_conf, zc->zc_nvlist_conf_size,
+	    zc->zc_iflags, &config);
+	if (error == 0) {
+		error = spa_vdev_add(spa, config);
+		nvlist_free(config);
+	}
+	spa_close(spa, FTAG);
+	return (error);
+}
+
+/*
+ * inputs:
+ * zc_name		name of the pool
+ * zc_nvlist_conf	nvlist of devices to remove
+ * zc_cookie		to stop the remove?
+ */
+static int
+zfs_ioc_vdev_remove(zfs_cmd_t *zc)
+{
+	spa_t *spa;
+	int error;
+
+	error = spa_open(zc->zc_name, &spa, FTAG);
+	if (error != 0)
+		return (error);
+	error = spa_vdev_remove(spa, zc->zc_guid, B_FALSE);
+	spa_close(spa, FTAG);
+	return (error);
+}
+
+static int
+zfs_ioc_vdev_set_state(zfs_cmd_t *zc)
+{
+	spa_t *spa;
+	int error;
+	vdev_state_t newstate = VDEV_STATE_UNKNOWN;
+
+	if ((error = spa_open(zc->zc_name, &spa, FTAG)) != 0)
+		return (error);
+	switch (zc->zc_cookie) {
+	case VDEV_STATE_ONLINE:
+		error = vdev_online(spa, zc->zc_guid, zc->zc_obj, &newstate);
+		break;
+
+	case VDEV_STATE_OFFLINE:
+		error = vdev_offline(spa, zc->zc_guid, zc->zc_obj);
+		break;
+
+	case VDEV_STATE_FAULTED:
+		if (zc->zc_obj != VDEV_AUX_ERR_EXCEEDED &&
+		    zc->zc_obj != VDEV_AUX_EXTERNAL)
+			zc->zc_obj = VDEV_AUX_ERR_EXCEEDED;
+
+		error = vdev_fault(spa, zc->zc_guid, zc->zc_obj);
+		break;
+
+	case VDEV_STATE_DEGRADED:
+		if (zc->zc_obj != VDEV_AUX_ERR_EXCEEDED &&
+		    zc->zc_obj != VDEV_AUX_EXTERNAL)
+			zc->zc_obj = VDEV_AUX_ERR_EXCEEDED;
+
+		error = vdev_degrade(spa, zc->zc_guid, zc->zc_obj);
+		break;
+
+	default:
+		error = SET_ERROR(EINVAL);
+	}
+	zc->zc_cookie = newstate;
+	spa_close(spa, FTAG);
+	return (error);
+}
+
+static int
+zfs_ioc_vdev_attach(zfs_cmd_t *zc)
+{
+	spa_t *spa;
+	int replacing = zc->zc_cookie;
+	nvlist_t *config;
+	int error;
+
+	if ((error = spa_open(zc->zc_name, &spa, FTAG)) != 0)
+		return (error);
+
+	if ((error = get_nvlist(zc->zc_nvlist_conf, zc->zc_nvlist_conf_size,
+	    zc->zc_iflags, &config)) == 0) {
+		error = spa_vdev_attach(spa, zc->zc_guid, config, replacing);
+		nvlist_free(config);
+	}
+
+	spa_close(spa, FTAG);
+	return (error);
+}
+
+static int
+zfs_ioc_vdev_detach(zfs_cmd_t *zc)
+{
+	spa_t *spa;
+	int error;
+
+	if ((error = spa_open(zc->zc_name, &spa, FTAG)) != 0)
+		return (error);
+
+	error = spa_vdev_detach(spa, zc->zc_guid, 0, B_FALSE);
+
+	spa_close(spa, FTAG);
+	return (error);
+}
+
+static int
+zfs_ioc_vdev_split(zfs_cmd_t *zc)
+{
+	spa_t *spa;
+	nvlist_t *config, *props = NULL;
+	int error;
+	boolean_t exp = !!(zc->zc_cookie & ZPOOL_EXPORT_AFTER_SPLIT);
+
+	if ((error = spa_open(zc->zc_name, &spa, FTAG)) != 0)
+		return (error);
+
+	if ((error = get_nvlist(zc->zc_nvlist_conf, zc->zc_nvlist_conf_size,
+	    zc->zc_iflags, &config))) {
+		spa_close(spa, FTAG);
+		return (error);
+	}
+
+	if (zc->zc_nvlist_src_size != 0 && (error =
+	    get_nvlist(zc->zc_nvlist_src, zc->zc_nvlist_src_size,
+	    zc->zc_iflags, &props))) {
+		spa_close(spa, FTAG);
+		nvlist_free(config);
+		return (error);
+	}
+
+	error = spa_vdev_split_mirror(spa, zc->zc_string, config, props, exp);
+
+	spa_close(spa, FTAG);
+
+	nvlist_free(config);
+	nvlist_free(props);
+
+	return (error);
+}
+
+static int
+zfs_ioc_vdev_setpath(zfs_cmd_t *zc)
+{
+	spa_t *spa;
+	char *path = zc->zc_value;
+	uint64_t guid = zc->zc_guid;
+	int error;
+
+	error = spa_open(zc->zc_name, &spa, FTAG);
+	if (error != 0)
+		return (error);
+
+	error = spa_vdev_setpath(spa, guid, path);
+	spa_close(spa, FTAG);
+	return (error);
+}
+
+static int
+zfs_ioc_vdev_setfru(zfs_cmd_t *zc)
+{
+	spa_t *spa;
+	char *fru = zc->zc_value;
+	uint64_t guid = zc->zc_guid;
+	int error;
+
+	error = spa_open(zc->zc_name, &spa, FTAG);
+	if (error != 0)
+		return (error);
+
+	error = spa_vdev_setfru(spa, guid, fru);
+	spa_close(spa, FTAG);
+	return (error);
+}
+
+static int
+zfs_ioc_objset_stats_impl(zfs_cmd_t *zc, objset_t *os)
+{
+	int error = 0;
+	nvlist_t *nv;
+
+	dmu_objset_fast_stat(os, &zc->zc_objset_stats);
+
+	if (zc->zc_nvlist_dst != 0 &&
+	    (error = dsl_prop_get_all(os, &nv)) == 0) {
+		dmu_objset_stats(os, nv);
+		/*
+		 * NB: zvol_get_stats() will read the objset contents,
+		 * which we aren't supposed to do with a
+		 * DS_MODE_USER hold, because it could be
+		 * inconsistent.  So this is a bit of a workaround...
+		 * XXX reading with out owning
+		 */
+		if (!zc->zc_objset_stats.dds_inconsistent &&
+		    dmu_objset_type(os) == DMU_OST_ZVOL) {
+			error = zvol_get_stats(os, nv);
+			if (error == EIO)
+				return (error);
+			VERIFY0(error);
+		}
+		if (error == 0)
+			error = put_nvlist(zc, nv);
+		nvlist_free(nv);
+	}
+
+	return (error);
+}
+
+/*
+ * inputs:
+ * zc_name		name of filesystem
+ * zc_nvlist_dst_size	size of buffer for property nvlist
+ *
+ * outputs:
+ * zc_objset_stats	stats
+ * zc_nvlist_dst	property nvlist
+ * zc_nvlist_dst_size	size of property nvlist
+ */
+static int
+zfs_ioc_objset_stats(zfs_cmd_t *zc)
+{
+	objset_t *os;
+	int error;
+
+	error = dmu_objset_hold(zc->zc_name, FTAG, &os);
+	if (error == 0) {
+		error = zfs_ioc_objset_stats_impl(zc, os);
+		dmu_objset_rele(os, FTAG);
+	}
+
+	return (error);
+}
+
+/*
+ * inputs:
+ * zc_name		name of filesystem
+ * zc_nvlist_dst_size	size of buffer for property nvlist
+ *
+ * outputs:
+ * zc_nvlist_dst	received property nvlist
+ * zc_nvlist_dst_size	size of received property nvlist
+ *
+ * Gets received properties (distinct from local properties on or after
+ * SPA_VERSION_RECVD_PROPS) for callers who want to differentiate received from
+ * local property values.
+ */
+static int
+zfs_ioc_objset_recvd_props(zfs_cmd_t *zc)
+{
+	int error = 0;
+	nvlist_t *nv;
+
+	/*
+	 * Without this check, we would return local property values if the
+	 * caller has not already received properties on or after
+	 * SPA_VERSION_RECVD_PROPS.
+	 */
+	if (!dsl_prop_get_hasrecvd(zc->zc_name))
+		return (SET_ERROR(ENOTSUP));
+
+	if (zc->zc_nvlist_dst != 0 &&
+	    (error = dsl_prop_get_received(zc->zc_name, &nv)) == 0) {
+		error = put_nvlist(zc, nv);
+		nvlist_free(nv);
+	}
+
+	return (error);
+}
+
+static int
+nvl_add_zplprop(objset_t *os, nvlist_t *props, zfs_prop_t prop)
+{
+	uint64_t value;
+	int error;
+
+	/*
+	 * zfs_get_zplprop() will either find a value or give us
+	 * the default value (if there is one).
+	 */
+	if ((error = zfs_get_zplprop(os, prop, &value)) != 0)
+		return (error);
+	VERIFY(nvlist_add_uint64(props, zfs_prop_to_name(prop), value) == 0);
+	return (0);
+}
+
+/*
+ * inputs:
+ * zc_name		name of filesystem
+ * zc_nvlist_dst_size	size of buffer for zpl property nvlist
+ *
+ * outputs:
+ * zc_nvlist_dst	zpl property nvlist
+ * zc_nvlist_dst_size	size of zpl property nvlist
+ */
+static int
+zfs_ioc_objset_zplprops(zfs_cmd_t *zc)
+{
+	objset_t *os;
+	int err;
+
+	/* XXX reading without owning */
+	if ((err = dmu_objset_hold(zc->zc_name, FTAG, &os)))
+		return (err);
+
+	dmu_objset_fast_stat(os, &zc->zc_objset_stats);
+
+	/*
+	 * NB: nvl_add_zplprop() will read the objset contents,
+	 * which we aren't supposed to do with a DS_MODE_USER
+	 * hold, because it could be inconsistent.
+	 */
+	if (zc->zc_nvlist_dst != 0 &&
+	    !zc->zc_objset_stats.dds_inconsistent &&
+	    dmu_objset_type(os) == DMU_OST_ZFS) {
+		nvlist_t *nv;
+
+		VERIFY(nvlist_alloc(&nv, NV_UNIQUE_NAME, KM_SLEEP) == 0);
+		if ((err = nvl_add_zplprop(os, nv, ZFS_PROP_VERSION)) == 0 &&
+		    (err = nvl_add_zplprop(os, nv, ZFS_PROP_NORMALIZE)) == 0 &&
+		    (err = nvl_add_zplprop(os, nv, ZFS_PROP_UTF8ONLY)) == 0 &&
+		    (err = nvl_add_zplprop(os, nv, ZFS_PROP_CASE)) == 0)
+			err = put_nvlist(zc, nv);
+		nvlist_free(nv);
+	} else {
+		err = SET_ERROR(ENOENT);
+	}
+	dmu_objset_rele(os, FTAG);
+	return (err);
+}
+
+boolean_t
+dataset_name_hidden(const char *name)
+{
+	/*
+	 * Skip over datasets that are not visible in this zone,
+	 * internal datasets (which have a $ in their name), and
+	 * temporary datasets (which have a % in their name).
+	 */
+	if (strchr(name, '$') != NULL)
+		return (B_TRUE);
+	if (strchr(name, '%') != NULL)
+		return (B_TRUE);
+	if (!INGLOBALZONE(curproc) && !zone_dataset_visible(name, NULL))
+		return (B_TRUE);
+	return (B_FALSE);
+}
+
+/*
+ * inputs:
+ * zc_name		name of filesystem
+ * zc_cookie		zap cursor
+ * zc_nvlist_dst_size	size of buffer for property nvlist
+ *
+ * outputs:
+ * zc_name		name of next filesystem
+ * zc_cookie		zap cursor
+ * zc_objset_stats	stats
+ * zc_nvlist_dst	property nvlist
+ * zc_nvlist_dst_size	size of property nvlist
+ */
+static int
+zfs_ioc_dataset_list_next(zfs_cmd_t *zc)
+{
+	objset_t *os;
+	int error;
+	char *p;
+	size_t orig_len = strlen(zc->zc_name);
+
+top:
+	if ((error = dmu_objset_hold(zc->zc_name, FTAG, &os))) {
+		if (error == ENOENT)
+			error = SET_ERROR(ESRCH);
+		return (error);
+	}
+
+	p = strrchr(zc->zc_name, '/');
+	if (p == NULL || p[1] != '\0')
+		(void) strlcat(zc->zc_name, "/", sizeof (zc->zc_name));
+	p = zc->zc_name + strlen(zc->zc_name);
+
+	do {
+		error = dmu_dir_list_next(os,
+		    sizeof (zc->zc_name) - (p - zc->zc_name), p,
+		    NULL, &zc->zc_cookie);
+		if (error == ENOENT)
+			error = SET_ERROR(ESRCH);
+	} while (error == 0 && dataset_name_hidden(zc->zc_name));
+	dmu_objset_rele(os, FTAG);
+
+	/*
+	 * If it's an internal dataset (ie. with a '$' in its name),
+	 * don't try to get stats for it, otherwise we'll return ENOENT.
+	 */
+	if (error == 0 && strchr(zc->zc_name, '$') == NULL) {
+		error = zfs_ioc_objset_stats(zc); /* fill in the stats */
+		if (error == ENOENT) {
+			/* We lost a race with destroy, get the next one. */
+			zc->zc_name[orig_len] = '\0';
+			goto top;
+		}
+	}
+	return (error);
+}
+
+/*
+ * inputs:
+ * zc_name		name of filesystem
+ * zc_cookie		zap cursor
+ * zc_nvlist_dst_size	size of buffer for property nvlist
+ *
+ * outputs:
+ * zc_name		name of next snapshot
+ * zc_objset_stats	stats
+ * zc_nvlist_dst	property nvlist
+ * zc_nvlist_dst_size	size of property nvlist
+ */
+static int
+zfs_ioc_snapshot_list_next(zfs_cmd_t *zc)
+{
+	objset_t *os;
+	int error;
+
+	error = dmu_objset_hold(zc->zc_name, FTAG, &os);
+	if (error != 0) {
+		return (error == ENOENT ? ESRCH : error);
+	}
+
+	/*
+	 * A dataset name of maximum length cannot have any snapshots,
+	 * so exit immediately.
+	 */
+	if (strlcat(zc->zc_name, "@", sizeof (zc->zc_name)) >= MAXNAMELEN) {
+		dmu_objset_rele(os, FTAG);
+		return (SET_ERROR(ESRCH));
+	}
+
+	error = dmu_snapshot_list_next(os,
+	    sizeof (zc->zc_name) - strlen(zc->zc_name),
+	    zc->zc_name + strlen(zc->zc_name), &zc->zc_obj, &zc->zc_cookie,
+	    NULL);
+
+	if (error == 0 && !zc->zc_simple) {
+		dsl_dataset_t *ds;
+		dsl_pool_t *dp = os->os_dsl_dataset->ds_dir->dd_pool;
+
+		error = dsl_dataset_hold_obj(dp, zc->zc_obj, FTAG, &ds);
+		if (error == 0) {
+			objset_t *ossnap;
+
+			error = dmu_objset_from_ds(ds, &ossnap);
+			if (error == 0)
+				error = zfs_ioc_objset_stats_impl(zc, ossnap);
+			dsl_dataset_rele(ds, FTAG);
+		}
+	} else if (error == ENOENT) {
+		error = SET_ERROR(ESRCH);
+	}
+
+	dmu_objset_rele(os, FTAG);
+	/* if we failed, undo the @ that we tacked on to zc_name */
+	if (error != 0)
+		*strchr(zc->zc_name, '@') = '\0';
+	return (error);
+}
+
+static int
+zfs_prop_set_userquota(const char *dsname, nvpair_t *pair)
+{
+	const char *propname = nvpair_name(pair);
+	uint64_t *valary;
+	unsigned int vallen;
+	const char *domain;
+	char *dash;
+	zfs_userquota_prop_t type;
+	uint64_t rid;
+	uint64_t quota;
+	zfs_sb_t *zsb;
+	int err;
+
+	if (nvpair_type(pair) == DATA_TYPE_NVLIST) {
+		nvlist_t *attrs;
+		VERIFY(nvpair_value_nvlist(pair, &attrs) == 0);
+		if (nvlist_lookup_nvpair(attrs, ZPROP_VALUE,
+		    &pair) != 0)
+			return (SET_ERROR(EINVAL));
+	}
+
+	/*
+	 * A correctly constructed propname is encoded as
+	 * userquota@<rid>-<domain>.
+	 */
+	if ((dash = strchr(propname, '-')) == NULL ||
+	    nvpair_value_uint64_array(pair, &valary, &vallen) != 0 ||
+	    vallen != 3)
+		return (SET_ERROR(EINVAL));
+
+	domain = dash + 1;
+	type = valary[0];
+	rid = valary[1];
+	quota = valary[2];
+
+	err = zfs_sb_hold(dsname, FTAG, &zsb, B_FALSE);
+	if (err == 0) {
+		err = zfs_set_userquota(zsb, type, domain, rid, quota);
+		zfs_sb_rele(zsb, FTAG);
+	}
+
+	return (err);
+}
+
+/*
+ * If the named property is one that has a special function to set its value,
+ * return 0 on success and a positive error code on failure; otherwise if it is
+ * not one of the special properties handled by this function, return -1.
+ *
+ * XXX: It would be better for callers of the property interface if we handled
+ * these special cases in dsl_prop.c (in the dsl layer).
+ */
+static int
+zfs_prop_set_special(const char *dsname, zprop_source_t source,
+    nvpair_t *pair)
+{
+	const char *propname = nvpair_name(pair);
+	zfs_prop_t prop = zfs_name_to_prop(propname);
+	uint64_t intval;
+	int err = -1;
+
+	if (prop == ZPROP_INVAL) {
+		if (zfs_prop_userquota(propname))
+			return (zfs_prop_set_userquota(dsname, pair));
+		return (-1);
+	}
+
+	if (nvpair_type(pair) == DATA_TYPE_NVLIST) {
+		nvlist_t *attrs;
+		VERIFY(nvpair_value_nvlist(pair, &attrs) == 0);
+		VERIFY(nvlist_lookup_nvpair(attrs, ZPROP_VALUE,
+		    &pair) == 0);
+	}
+
+	if (zfs_prop_get_type(prop) == PROP_TYPE_STRING)
+		return (-1);
+
+	VERIFY(0 == nvpair_value_uint64(pair, &intval));
+
+	switch (prop) {
+	case ZFS_PROP_QUOTA:
+		err = dsl_dir_set_quota(dsname, source, intval);
+		break;
+	case ZFS_PROP_REFQUOTA:
+		err = dsl_dataset_set_refquota(dsname, source, intval);
+		break;
+	case ZFS_PROP_FILESYSTEM_LIMIT:
+	case ZFS_PROP_SNAPSHOT_LIMIT:
+		if (intval == UINT64_MAX) {
+			/* clearing the limit, just do it */
+			err = 0;
+		} else {
+			err = dsl_dir_activate_fs_ss_limit(dsname);
+		}
+		/*
+		 * Set err to -1 to force the zfs_set_prop_nvlist code down the
+		 * default path to set the value in the nvlist.
+		 */
+		if (err == 0)
+			err = -1;
+		break;
+	case ZFS_PROP_RESERVATION:
+		err = dsl_dir_set_reservation(dsname, source, intval);
+		break;
+	case ZFS_PROP_REFRESERVATION:
+		err = dsl_dataset_set_refreservation(dsname, source, intval);
+		break;
+	case ZFS_PROP_VOLSIZE:
+		err = zvol_set_volsize(dsname, intval);
+		break;
+	case ZFS_PROP_SNAPDEV:
+		err = zvol_set_snapdev(dsname, source, intval);
+		break;
+	case ZFS_PROP_VERSION:
+	{
+		zfs_sb_t *zsb;
+
+		if ((err = zfs_sb_hold(dsname, FTAG, &zsb, B_TRUE)) != 0)
+			break;
+
+		err = zfs_set_version(zsb, intval);
+		zfs_sb_rele(zsb, FTAG);
+
+		if (err == 0 && intval >= ZPL_VERSION_USERSPACE) {
+			zfs_cmd_t *zc;
+
+			zc = kmem_zalloc(sizeof (zfs_cmd_t), KM_SLEEP);
+			(void) strcpy(zc->zc_name, dsname);
+			(void) zfs_ioc_userspace_upgrade(zc);
+			kmem_free(zc, sizeof (zfs_cmd_t));
+		}
+		break;
+	}
+	default:
+		err = -1;
+	}
+
+	return (err);
+}
+
+/*
+ * This function is best effort. If it fails to set any of the given properties,
+ * it continues to set as many as it can and returns the last error
+ * encountered. If the caller provides a non-NULL errlist, it will be filled in
+ * with the list of names of all the properties that failed along with the
+ * corresponding error numbers.
+ *
+ * If every property is set successfully, zero is returned and errlist is not
+ * modified.
+ */
+int
+zfs_set_prop_nvlist(const char *dsname, zprop_source_t source, nvlist_t *nvl,
+    nvlist_t *errlist)
+{
+	nvpair_t *pair;
+	nvpair_t *propval;
+	int rv = 0;
+	uint64_t intval;
+	char *strval;
+
+	nvlist_t *genericnvl = fnvlist_alloc();
+	nvlist_t *retrynvl = fnvlist_alloc();
+retry:
+	pair = NULL;
+	while ((pair = nvlist_next_nvpair(nvl, pair)) != NULL) {
+		const char *propname = nvpair_name(pair);
+		zfs_prop_t prop = zfs_name_to_prop(propname);
+		int err = 0;
+
+		/* decode the property value */
+		propval = pair;
+		if (nvpair_type(pair) == DATA_TYPE_NVLIST) {
+			nvlist_t *attrs;
+			attrs = fnvpair_value_nvlist(pair);
+			if (nvlist_lookup_nvpair(attrs, ZPROP_VALUE,
+			    &propval) != 0)
+				err = SET_ERROR(EINVAL);
+		}
+
+		/* Validate value type */
+		if (err == 0 && prop == ZPROP_INVAL) {
+			if (zfs_prop_user(propname)) {
+				if (nvpair_type(propval) != DATA_TYPE_STRING)
+					err = SET_ERROR(EINVAL);
+			} else if (zfs_prop_userquota(propname)) {
+				if (nvpair_type(propval) !=
+				    DATA_TYPE_UINT64_ARRAY)
+					err = SET_ERROR(EINVAL);
+			} else {
+				err = SET_ERROR(EINVAL);
+			}
+		} else if (err == 0) {
+			if (nvpair_type(propval) == DATA_TYPE_STRING) {
+				if (zfs_prop_get_type(prop) != PROP_TYPE_STRING)
+					err = SET_ERROR(EINVAL);
+			} else if (nvpair_type(propval) == DATA_TYPE_UINT64) {
+				const char *unused;
+
+				intval = fnvpair_value_uint64(propval);
+
+				switch (zfs_prop_get_type(prop)) {
+				case PROP_TYPE_NUMBER:
+					break;
+				case PROP_TYPE_STRING:
+					err = SET_ERROR(EINVAL);
+					break;
+				case PROP_TYPE_INDEX:
+					if (zfs_prop_index_to_string(prop,
+					    intval, &unused) != 0)
+						err = SET_ERROR(EINVAL);
+					break;
+				default:
+					cmn_err(CE_PANIC,
+					    "unknown property type");
+				}
+			} else {
+				err = SET_ERROR(EINVAL);
+			}
+		}
+
+		/* Validate permissions */
+		if (err == 0)
+			err = zfs_check_settable(dsname, pair, CRED());
+
+		if (err == 0) {
+			err = zfs_prop_set_special(dsname, source, pair);
+			if (err == -1) {
+				/*
+				 * For better performance we build up a list of
+				 * properties to set in a single transaction.
+				 */
+				err = nvlist_add_nvpair(genericnvl, pair);
+			} else if (err != 0 && nvl != retrynvl) {
+				/*
+				 * This may be a spurious error caused by
+				 * receiving quota and reservation out of order.
+				 * Try again in a second pass.
+				 */
+				err = nvlist_add_nvpair(retrynvl, pair);
+			}
+		}
+
+		if (err != 0) {
+			if (errlist != NULL)
+				fnvlist_add_int32(errlist, propname, err);
+			rv = err;
+		}
+	}
+
+	if (nvl != retrynvl && !nvlist_empty(retrynvl)) {
+		nvl = retrynvl;
+		goto retry;
+	}
+
+	if (!nvlist_empty(genericnvl) &&
+	    dsl_props_set(dsname, source, genericnvl) != 0) {
+		/*
+		 * If this fails, we still want to set as many properties as we
+		 * can, so try setting them individually.
+		 */
+		pair = NULL;
+		while ((pair = nvlist_next_nvpair(genericnvl, pair)) != NULL) {
+			const char *propname = nvpair_name(pair);
+			int err = 0;
+
+			propval = pair;
+			if (nvpair_type(pair) == DATA_TYPE_NVLIST) {
+				nvlist_t *attrs;
+				attrs = fnvpair_value_nvlist(pair);
+				propval = fnvlist_lookup_nvpair(attrs,
+				    ZPROP_VALUE);
+			}
+
+			if (nvpair_type(propval) == DATA_TYPE_STRING) {
+				strval = fnvpair_value_string(propval);
+				err = dsl_prop_set_string(dsname, propname,
+				    source, strval);
+			} else {
+				intval = fnvpair_value_uint64(propval);
+				err = dsl_prop_set_int(dsname, propname, source,
+				    intval);
+			}
+
+			if (err != 0) {
+				if (errlist != NULL) {
+					fnvlist_add_int32(errlist, propname,
+					    err);
+				}
+				rv = err;
+			}
+		}
+	}
+	nvlist_free(genericnvl);
+	nvlist_free(retrynvl);
+
+	return (rv);
+}
+
+/*
+ * Check that all the properties are valid user properties.
+ */
+static int
+zfs_check_userprops(const char *fsname, nvlist_t *nvl)
+{
+	nvpair_t *pair = NULL;
+	int error = 0;
+
+	while ((pair = nvlist_next_nvpair(nvl, pair)) != NULL) {
+		const char *propname = nvpair_name(pair);
+
+		if (!zfs_prop_user(propname) ||
+		    nvpair_type(pair) != DATA_TYPE_STRING)
+			return (SET_ERROR(EINVAL));
+
+		if ((error = zfs_secpolicy_write_perms(fsname,
+		    ZFS_DELEG_PERM_USERPROP, CRED())))
+			return (error);
+
+		if (strlen(propname) >= ZAP_MAXNAMELEN)
+			return (SET_ERROR(ENAMETOOLONG));
+
+		if (strlen(fnvpair_value_string(pair)) >= ZAP_MAXVALUELEN)
+			return (SET_ERROR(E2BIG));
+	}
+	return (0);
+}
+
+static void
+props_skip(nvlist_t *props, nvlist_t *skipped, nvlist_t **newprops)
+{
+	nvpair_t *pair;
+
+	VERIFY(nvlist_alloc(newprops, NV_UNIQUE_NAME, KM_SLEEP) == 0);
+
+	pair = NULL;
+	while ((pair = nvlist_next_nvpair(props, pair)) != NULL) {
+		if (nvlist_exists(skipped, nvpair_name(pair)))
+			continue;
+
+		VERIFY(nvlist_add_nvpair(*newprops, pair) == 0);
+	}
+}
+
+static int
+clear_received_props(const char *dsname, nvlist_t *props,
+    nvlist_t *skipped)
+{
+	int err = 0;
+	nvlist_t *cleared_props = NULL;
+	props_skip(props, skipped, &cleared_props);
+	if (!nvlist_empty(cleared_props)) {
+		/*
+		 * Acts on local properties until the dataset has received
+		 * properties at least once on or after SPA_VERSION_RECVD_PROPS.
+		 */
+		zprop_source_t flags = (ZPROP_SRC_NONE |
+		    (dsl_prop_get_hasrecvd(dsname) ? ZPROP_SRC_RECEIVED : 0));
+		err = zfs_set_prop_nvlist(dsname, flags, cleared_props, NULL);
+	}
+	nvlist_free(cleared_props);
+	return (err);
+}
+
+/*
+ * inputs:
+ * zc_name		name of filesystem
+ * zc_value		name of property to set
+ * zc_nvlist_src{_size}	nvlist of properties to apply
+ * zc_cookie		received properties flag
+ *
+ * outputs:
+ * zc_nvlist_dst{_size} error for each unapplied received property
+ */
+static int
+zfs_ioc_set_prop(zfs_cmd_t *zc)
+{
+	nvlist_t *nvl;
+	boolean_t received = zc->zc_cookie;
+	zprop_source_t source = (received ? ZPROP_SRC_RECEIVED :
+	    ZPROP_SRC_LOCAL);
+	nvlist_t *errors;
+	int error;
+
+	if ((error = get_nvlist(zc->zc_nvlist_src, zc->zc_nvlist_src_size,
+	    zc->zc_iflags, &nvl)) != 0)
+		return (error);
+
+	if (received) {
+		nvlist_t *origprops;
+
+		if (dsl_prop_get_received(zc->zc_name, &origprops) == 0) {
+			(void) clear_received_props(zc->zc_name,
+			    origprops, nvl);
+			nvlist_free(origprops);
+		}
+
+		error = dsl_prop_set_hasrecvd(zc->zc_name);
+	}
+
+	errors = fnvlist_alloc();
+	if (error == 0)
+		error = zfs_set_prop_nvlist(zc->zc_name, source, nvl, errors);
+
+	if (zc->zc_nvlist_dst != 0 && errors != NULL) {
+		(void) put_nvlist(zc, errors);
+	}
+
+	nvlist_free(errors);
+	nvlist_free(nvl);
+	return (error);
+}
+
+/*
+ * inputs:
+ * zc_name		name of filesystem
+ * zc_value		name of property to inherit
+ * zc_cookie		revert to received value if TRUE
+ *
+ * outputs:		none
+ */
+static int
+zfs_ioc_inherit_prop(zfs_cmd_t *zc)
+{
+	const char *propname = zc->zc_value;
+	zfs_prop_t prop = zfs_name_to_prop(propname);
+	boolean_t received = zc->zc_cookie;
+	zprop_source_t source = (received
+	    ? ZPROP_SRC_NONE		/* revert to received value, if any */
+	    : ZPROP_SRC_INHERITED);	/* explicitly inherit */
+
+	if (received) {
+		nvlist_t *dummy;
+		nvpair_t *pair;
+		zprop_type_t type;
+		int err;
+
+		/*
+		 * zfs_prop_set_special() expects properties in the form of an
+		 * nvpair with type info.
+		 */
+		if (prop == ZPROP_INVAL) {
+			if (!zfs_prop_user(propname))
+				return (SET_ERROR(EINVAL));
+
+			type = PROP_TYPE_STRING;
+		} else if (prop == ZFS_PROP_VOLSIZE ||
+		    prop == ZFS_PROP_VERSION) {
+			return (SET_ERROR(EINVAL));
+		} else {
+			type = zfs_prop_get_type(prop);
+		}
+
+		VERIFY(nvlist_alloc(&dummy, NV_UNIQUE_NAME, KM_SLEEP) == 0);
+
+		switch (type) {
+		case PROP_TYPE_STRING:
+			VERIFY(0 == nvlist_add_string(dummy, propname, ""));
+			break;
+		case PROP_TYPE_NUMBER:
+		case PROP_TYPE_INDEX:
+			VERIFY(0 == nvlist_add_uint64(dummy, propname, 0));
+			break;
+		default:
+			nvlist_free(dummy);
+			return (SET_ERROR(EINVAL));
+		}
+
+		pair = nvlist_next_nvpair(dummy, NULL);
+		err = zfs_prop_set_special(zc->zc_name, source, pair);
+		nvlist_free(dummy);
+		if (err != -1)
+			return (err); /* special property already handled */
+	} else {
+		/*
+		 * Only check this in the non-received case. We want to allow
+		 * 'inherit -S' to revert non-inheritable properties like quota
+		 * and reservation to the received or default values even though
+		 * they are not considered inheritable.
+		 */
+		if (prop != ZPROP_INVAL && !zfs_prop_inheritable(prop))
+			return (SET_ERROR(EINVAL));
+	}
+
+	/* property name has been validated by zfs_secpolicy_inherit_prop() */
+	return (dsl_prop_inherit(zc->zc_name, zc->zc_value, source));
+}
+
+static int
+zfs_ioc_pool_set_props(zfs_cmd_t *zc)
+{
+	nvlist_t *props;
+	spa_t *spa;
+	int error;
+	nvpair_t *pair;
+
+	if ((error = get_nvlist(zc->zc_nvlist_src, zc->zc_nvlist_src_size,
+	    zc->zc_iflags, &props)))
+		return (error);
+
+	/*
+	 * If the only property is the configfile, then just do a spa_lookup()
+	 * to handle the faulted case.
+	 */
+	pair = nvlist_next_nvpair(props, NULL);
+	if (pair != NULL && strcmp(nvpair_name(pair),
+	    zpool_prop_to_name(ZPOOL_PROP_CACHEFILE)) == 0 &&
+	    nvlist_next_nvpair(props, pair) == NULL) {
+		mutex_enter(&spa_namespace_lock);
+		if ((spa = spa_lookup(zc->zc_name)) != NULL) {
+			spa_configfile_set(spa, props, B_FALSE);
+			spa_config_sync(spa, B_FALSE, B_TRUE);
+		}
+		mutex_exit(&spa_namespace_lock);
+		if (spa != NULL) {
+			nvlist_free(props);
+			return (0);
+		}
+	}
+
+	if ((error = spa_open(zc->zc_name, &spa, FTAG)) != 0) {
+		nvlist_free(props);
+		return (error);
+	}
+
+	error = spa_prop_set(spa, props);
+
+	nvlist_free(props);
+	spa_close(spa, FTAG);
+
+	return (error);
+}
+
+static int
+zfs_ioc_pool_get_props(zfs_cmd_t *zc)
+{
+	spa_t *spa;
+	int error;
+	nvlist_t *nvp = NULL;
+
+	if ((error = spa_open(zc->zc_name, &spa, FTAG)) != 0) {
+		/*
+		 * If the pool is faulted, there may be properties we can still
+		 * get (such as altroot and cachefile), so attempt to get them
+		 * anyway.
+		 */
+		mutex_enter(&spa_namespace_lock);
+		if ((spa = spa_lookup(zc->zc_name)) != NULL)
+			error = spa_prop_get(spa, &nvp);
+		mutex_exit(&spa_namespace_lock);
+	} else {
+		error = spa_prop_get(spa, &nvp);
+		spa_close(spa, FTAG);
+	}
+
+	if (error == 0 && zc->zc_nvlist_dst != 0)
+		error = put_nvlist(zc, nvp);
+	else
+		error = SET_ERROR(EFAULT);
+
+	nvlist_free(nvp);
+	return (error);
+}
+
+/*
+ * inputs:
+ * zc_name		name of filesystem
+ * zc_nvlist_src{_size}	nvlist of delegated permissions
+ * zc_perm_action	allow/unallow flag
+ *
+ * outputs:		none
+ */
+static int
+zfs_ioc_set_fsacl(zfs_cmd_t *zc)
+{
+	int error;
+	nvlist_t *fsaclnv = NULL;
+
+	if ((error = get_nvlist(zc->zc_nvlist_src, zc->zc_nvlist_src_size,
+	    zc->zc_iflags, &fsaclnv)) != 0)
+		return (error);
+
+	/*
+	 * Verify nvlist is constructed correctly
+	 */
+	if ((error = zfs_deleg_verify_nvlist(fsaclnv)) != 0) {
+		nvlist_free(fsaclnv);
+		return (SET_ERROR(EINVAL));
+	}
+
+	/*
+	 * If we don't have PRIV_SYS_MOUNT, then validate
+	 * that user is allowed to hand out each permission in
+	 * the nvlist(s)
+	 */
+
+	error = secpolicy_zfs(CRED());
+	if (error != 0) {
+		if (zc->zc_perm_action == B_FALSE) {
+			error = dsl_deleg_can_allow(zc->zc_name,
+			    fsaclnv, CRED());
+		} else {
+			error = dsl_deleg_can_unallow(zc->zc_name,
+			    fsaclnv, CRED());
+		}
+	}
+
+	if (error == 0)
+		error = dsl_deleg_set(zc->zc_name, fsaclnv, zc->zc_perm_action);
+
+	nvlist_free(fsaclnv);
+	return (error);
+}
+
+/*
+ * inputs:
+ * zc_name		name of filesystem
+ *
+ * outputs:
+ * zc_nvlist_src{_size}	nvlist of delegated permissions
+ */
+static int
+zfs_ioc_get_fsacl(zfs_cmd_t *zc)
+{
+	nvlist_t *nvp;
+	int error;
+
+	if ((error = dsl_deleg_get(zc->zc_name, &nvp)) == 0) {
+		error = put_nvlist(zc, nvp);
+		nvlist_free(nvp);
+	}
+
+	return (error);
+}
+
+/* ARGSUSED */
+static void
+zfs_create_cb(objset_t *os, void *arg, cred_t *cr, dmu_tx_t *tx)
+{
+	zfs_creat_t *zct = arg;
+
+	zfs_create_fs(os, cr, zct->zct_zplprops, tx);
+}
+
+#define	ZFS_PROP_UNDEFINED	((uint64_t)-1)
+
+/*
+ * inputs:
+ * os			parent objset pointer (NULL if root fs)
+ * fuids_ok		fuids allowed in this version of the spa?
+ * sa_ok		SAs allowed in this version of the spa?
+ * createprops		list of properties requested by creator
+ *
+ * outputs:
+ * zplprops	values for the zplprops we attach to the master node object
+ * is_ci	true if requested file system will be purely case-insensitive
+ *
+ * Determine the settings for utf8only, normalization and
+ * casesensitivity.  Specific values may have been requested by the
+ * creator and/or we can inherit values from the parent dataset.  If
+ * the file system is of too early a vintage, a creator can not
+ * request settings for these properties, even if the requested
+ * setting is the default value.  We don't actually want to create dsl
+ * properties for these, so remove them from the source nvlist after
+ * processing.
+ */
+static int
+zfs_fill_zplprops_impl(objset_t *os, uint64_t zplver,
+    boolean_t fuids_ok, boolean_t sa_ok, nvlist_t *createprops,
+    nvlist_t *zplprops, boolean_t *is_ci)
+{
+	uint64_t sense = ZFS_PROP_UNDEFINED;
+	uint64_t norm = ZFS_PROP_UNDEFINED;
+	uint64_t u8 = ZFS_PROP_UNDEFINED;
+	int error;
+
+	ASSERT(zplprops != NULL);
+
+	/*
+	 * Pull out creator prop choices, if any.
+	 */
+	if (createprops) {
+		(void) nvlist_lookup_uint64(createprops,
+		    zfs_prop_to_name(ZFS_PROP_VERSION), &zplver);
+		(void) nvlist_lookup_uint64(createprops,
+		    zfs_prop_to_name(ZFS_PROP_NORMALIZE), &norm);
+		(void) nvlist_remove_all(createprops,
+		    zfs_prop_to_name(ZFS_PROP_NORMALIZE));
+		(void) nvlist_lookup_uint64(createprops,
+		    zfs_prop_to_name(ZFS_PROP_UTF8ONLY), &u8);
+		(void) nvlist_remove_all(createprops,
+		    zfs_prop_to_name(ZFS_PROP_UTF8ONLY));
+		(void) nvlist_lookup_uint64(createprops,
+		    zfs_prop_to_name(ZFS_PROP_CASE), &sense);
+		(void) nvlist_remove_all(createprops,
+		    zfs_prop_to_name(ZFS_PROP_CASE));
+	}
+
+	/*
+	 * If the zpl version requested is whacky or the file system
+	 * or pool is version is too "young" to support normalization
+	 * and the creator tried to set a value for one of the props,
+	 * error out.
+	 */
+	if ((zplver < ZPL_VERSION_INITIAL || zplver > ZPL_VERSION) ||
+	    (zplver >= ZPL_VERSION_FUID && !fuids_ok) ||
+	    (zplver >= ZPL_VERSION_SA && !sa_ok) ||
+	    (zplver < ZPL_VERSION_NORMALIZATION &&
+	    (norm != ZFS_PROP_UNDEFINED || u8 != ZFS_PROP_UNDEFINED ||
+	    sense != ZFS_PROP_UNDEFINED)))
+		return (SET_ERROR(ENOTSUP));
+
+	/*
+	 * Put the version in the zplprops
+	 */
+	VERIFY(nvlist_add_uint64(zplprops,
+	    zfs_prop_to_name(ZFS_PROP_VERSION), zplver) == 0);
+
+	if (norm == ZFS_PROP_UNDEFINED &&
+	    (error = zfs_get_zplprop(os, ZFS_PROP_NORMALIZE, &norm)) != 0)
+		return (error);
+	VERIFY(nvlist_add_uint64(zplprops,
+	    zfs_prop_to_name(ZFS_PROP_NORMALIZE), norm) == 0);
+
+	/*
+	 * If we're normalizing, names must always be valid UTF-8 strings.
+	 */
+	if (norm)
+		u8 = 1;
+	if (u8 == ZFS_PROP_UNDEFINED &&
+	    (error = zfs_get_zplprop(os, ZFS_PROP_UTF8ONLY, &u8)) != 0)
+		return (error);
+	VERIFY(nvlist_add_uint64(zplprops,
+	    zfs_prop_to_name(ZFS_PROP_UTF8ONLY), u8) == 0);
+
+	if (sense == ZFS_PROP_UNDEFINED &&
+	    (error = zfs_get_zplprop(os, ZFS_PROP_CASE, &sense)) != 0)
+		return (error);
+	VERIFY(nvlist_add_uint64(zplprops,
+	    zfs_prop_to_name(ZFS_PROP_CASE), sense) == 0);
+
+	if (is_ci)
+		*is_ci = (sense == ZFS_CASE_INSENSITIVE);
+
+	return (0);
+}
+
+static int
+zfs_fill_zplprops(const char *dataset, nvlist_t *createprops,
+    nvlist_t *zplprops, boolean_t *is_ci)
+{
+	boolean_t fuids_ok, sa_ok;
+	uint64_t zplver = ZPL_VERSION;
+	objset_t *os = NULL;
+	char parentname[MAXNAMELEN];
+	char *cp;
+	spa_t *spa;
+	uint64_t spa_vers;
+	int error;
+
+	(void) strlcpy(parentname, dataset, sizeof (parentname));
+	cp = strrchr(parentname, '/');
+	ASSERT(cp != NULL);
+	cp[0] = '\0';
+
+	if ((error = spa_open(dataset, &spa, FTAG)) != 0)
+		return (error);
+
+	spa_vers = spa_version(spa);
+	spa_close(spa, FTAG);
+
+	zplver = zfs_zpl_version_map(spa_vers);
+	fuids_ok = (zplver >= ZPL_VERSION_FUID);
+	sa_ok = (zplver >= ZPL_VERSION_SA);
+
+	/*
+	 * Open parent object set so we can inherit zplprop values.
+	 */
+	if ((error = dmu_objset_hold(parentname, FTAG, &os)) != 0)
+		return (error);
+
+	error = zfs_fill_zplprops_impl(os, zplver, fuids_ok, sa_ok, createprops,
+	    zplprops, is_ci);
+	dmu_objset_rele(os, FTAG);
+	return (error);
+}
+
+static int
+zfs_fill_zplprops_root(uint64_t spa_vers, nvlist_t *createprops,
+    nvlist_t *zplprops, boolean_t *is_ci)
+{
+	boolean_t fuids_ok;
+	boolean_t sa_ok;
+	uint64_t zplver = ZPL_VERSION;
+	int error;
+
+	zplver = zfs_zpl_version_map(spa_vers);
+	fuids_ok = (zplver >= ZPL_VERSION_FUID);
+	sa_ok = (zplver >= ZPL_VERSION_SA);
+
+	error = zfs_fill_zplprops_impl(NULL, zplver, fuids_ok, sa_ok,
+	    createprops, zplprops, is_ci);
+	return (error);
+}
+
+/*
+ * innvl: {
+ *     "type" -> dmu_objset_type_t (int32)
+ *     (optional) "props" -> { prop -> value }
+ * }
+ *
+ * outnvl: propname -> error code (int32)
+ */
+static int
+zfs_ioc_create(const char *fsname, nvlist_t *innvl, nvlist_t *outnvl)
+{
+	int error = 0;
+	zfs_creat_t zct = { 0 };
+	nvlist_t *nvprops = NULL;
+	void (*cbfunc)(objset_t *os, void *arg, cred_t *cr, dmu_tx_t *tx);
+	int32_t type32;
+	dmu_objset_type_t type;
+	boolean_t is_insensitive = B_FALSE;
+
+	if (nvlist_lookup_int32(innvl, "type", &type32) != 0)
+		return (SET_ERROR(EINVAL));
+	type = type32;
+	(void) nvlist_lookup_nvlist(innvl, "props", &nvprops);
+
+	switch (type) {
+	case DMU_OST_ZFS:
+		cbfunc = zfs_create_cb;
+		break;
+
+	case DMU_OST_ZVOL:
+		cbfunc = zvol_create_cb;
+		break;
+
+	default:
+		cbfunc = NULL;
+		break;
+	}
+	if (strchr(fsname, '@') ||
+	    strchr(fsname, '%'))
+		return (SET_ERROR(EINVAL));
+
+	zct.zct_props = nvprops;
+
+	if (cbfunc == NULL)
+		return (SET_ERROR(EINVAL));
+
+	if (type == DMU_OST_ZVOL) {
+		uint64_t volsize, volblocksize;
+
+		if (nvprops == NULL)
+			return (SET_ERROR(EINVAL));
+		if (nvlist_lookup_uint64(nvprops,
+		    zfs_prop_to_name(ZFS_PROP_VOLSIZE), &volsize) != 0)
+			return (SET_ERROR(EINVAL));
+
+		if ((error = nvlist_lookup_uint64(nvprops,
+		    zfs_prop_to_name(ZFS_PROP_VOLBLOCKSIZE),
+		    &volblocksize)) != 0 && error != ENOENT)
+			return (SET_ERROR(EINVAL));
+
+		if (error != 0)
+			volblocksize = zfs_prop_default_numeric(
+			    ZFS_PROP_VOLBLOCKSIZE);
+
+		if ((error = zvol_check_volblocksize(fsname,
+		    volblocksize)) != 0 ||
+		    (error = zvol_check_volsize(volsize,
+		    volblocksize)) != 0)
+			return (error);
+	} else if (type == DMU_OST_ZFS) {
+		int error;
+
+		/*
+		 * We have to have normalization and
+		 * case-folding flags correct when we do the
+		 * file system creation, so go figure them out
+		 * now.
+		 */
+		VERIFY(nvlist_alloc(&zct.zct_zplprops,
+		    NV_UNIQUE_NAME, KM_SLEEP) == 0);
+		error = zfs_fill_zplprops(fsname, nvprops,
+		    zct.zct_zplprops, &is_insensitive);
+		if (error != 0) {
+			nvlist_free(zct.zct_zplprops);
+			return (error);
+		}
+	}
+
+	error = dmu_objset_create(fsname, type,
+	    is_insensitive ? DS_FLAG_CI_DATASET : 0, cbfunc, &zct);
+	nvlist_free(zct.zct_zplprops);
+
+	/*
+	 * It would be nice to do this atomically.
+	 */
+	if (error == 0) {
+		error = zfs_set_prop_nvlist(fsname, ZPROP_SRC_LOCAL,
+		    nvprops, outnvl);
+		if (error != 0)
+			(void) dsl_destroy_head(fsname);
+	}
+	return (error);
+}
+
+/*
+ * innvl: {
+ *     "origin" -> name of origin snapshot
+ *     (optional) "props" -> { prop -> value }
+ * }
+ *
+ * outputs:
+ * outnvl: propname -> error code (int32)
+ */
+static int
+zfs_ioc_clone(const char *fsname, nvlist_t *innvl, nvlist_t *outnvl)
+{
+	int error = 0;
+	nvlist_t *nvprops = NULL;
+	char *origin_name;
+
+	if (nvlist_lookup_string(innvl, "origin", &origin_name) != 0)
+		return (SET_ERROR(EINVAL));
+	(void) nvlist_lookup_nvlist(innvl, "props", &nvprops);
+
+	if (strchr(fsname, '@') ||
+	    strchr(fsname, '%'))
+		return (SET_ERROR(EINVAL));
+
+	if (dataset_namecheck(origin_name, NULL, NULL) != 0)
+		return (SET_ERROR(EINVAL));
+	error = dmu_objset_clone(fsname, origin_name);
+	if (error != 0)
+		return (error);
+
+	/*
+	 * It would be nice to do this atomically.
+	 */
+	if (error == 0) {
+		error = zfs_set_prop_nvlist(fsname, ZPROP_SRC_LOCAL,
+		    nvprops, outnvl);
+		if (error != 0)
+			(void) dsl_destroy_head(fsname);
+	}
+	return (error);
+}
+
+/*
+ * innvl: {
+ *     "snaps" -> { snapshot1, snapshot2 }
+ *     (optional) "props" -> { prop -> value (string) }
+ * }
+ *
+ * outnvl: snapshot -> error code (int32)
+ */
+static int
+zfs_ioc_snapshot(const char *poolname, nvlist_t *innvl, nvlist_t *outnvl)
+{
+	nvlist_t *snaps;
+	nvlist_t *props = NULL;
+	int error, poollen;
+	nvpair_t *pair, *pair2;
+
+	(void) nvlist_lookup_nvlist(innvl, "props", &props);
+	if ((error = zfs_check_userprops(poolname, props)) != 0)
+		return (error);
+
+	if (!nvlist_empty(props) &&
+	    zfs_earlier_version(poolname, SPA_VERSION_SNAP_PROPS))
+		return (SET_ERROR(ENOTSUP));
+
+	if (nvlist_lookup_nvlist(innvl, "snaps", &snaps) != 0)
+		return (SET_ERROR(EINVAL));
+	poollen = strlen(poolname);
+	for (pair = nvlist_next_nvpair(snaps, NULL); pair != NULL;
+	    pair = nvlist_next_nvpair(snaps, pair)) {
+		const char *name = nvpair_name(pair);
+		const char *cp = strchr(name, '@');
+
+		/*
+		 * The snap name must contain an @, and the part after it must
+		 * contain only valid characters.
+		 */
+		if (cp == NULL ||
+		    zfs_component_namecheck(cp + 1, NULL, NULL) != 0)
+			return (SET_ERROR(EINVAL));
+
+		/*
+		 * The snap must be in the specified pool.
+		 */
+		if (strncmp(name, poolname, poollen) != 0 ||
+		    (name[poollen] != '/' && name[poollen] != '@'))
+			return (SET_ERROR(EXDEV));
+
+		/* This must be the only snap of this fs. */
+		for (pair2 = nvlist_next_nvpair(snaps, pair);
+		    pair2 != NULL; pair2 = nvlist_next_nvpair(snaps, pair2)) {
+			if (strncmp(name, nvpair_name(pair2), cp - name + 1)
+			    == 0) {
+				return (SET_ERROR(EXDEV));
+			}
+		}
+	}
+
+	error = dsl_dataset_snapshot(snaps, props, outnvl);
+
+	return (error);
+}
+
+/*
+ * innvl: "message" -> string
+ */
+/* ARGSUSED */
+static int
+zfs_ioc_log_history(const char *unused, nvlist_t *innvl, nvlist_t *outnvl)
+{
+	char *message;
+	spa_t *spa;
+	int error;
+	char *poolname;
+
+	/*
+	 * The poolname in the ioctl is not set, we get it from the TSD,
+	 * which was set at the end of the last successful ioctl that allows
+	 * logging.  The secpolicy func already checked that it is set.
+	 * Only one log ioctl is allowed after each successful ioctl, so
+	 * we clear the TSD here.
+	 */
+	poolname = tsd_get(zfs_allow_log_key);
+	(void) tsd_set(zfs_allow_log_key, NULL);
+	error = spa_open(poolname, &spa, FTAG);
+	strfree(poolname);
+	if (error != 0)
+		return (error);
+
+	if (nvlist_lookup_string(innvl, "message", &message) != 0)  {
+		spa_close(spa, FTAG);
+		return (SET_ERROR(EINVAL));
+	}
+
+	if (spa_version(spa) < SPA_VERSION_ZPOOL_HISTORY) {
+		spa_close(spa, FTAG);
+		return (SET_ERROR(ENOTSUP));
+	}
+
+	error = spa_history_log(spa, message);
+	spa_close(spa, FTAG);
+	return (error);
+}
+
+/*
+ * The dp_config_rwlock must not be held when calling this, because the
+ * unmount may need to write out data.
+ *
+ * This function is best-effort.  Callers must deal gracefully if it
+ * remains mounted (or is remounted after this call).
+ *
+ * Returns 0 if the argument is not a snapshot, or it is not currently a
+ * filesystem, or we were able to unmount it.  Returns error code otherwise.
+ */
+int
+zfs_unmount_snap(const char *snapname)
+{
+	int err;
+
+	if (strchr(snapname, '@') == NULL)
+		return (0);
+
+	err = zfsctl_snapshot_unmount((char *)snapname, MNT_FORCE);
+	if (err != 0 && err != ENOENT)
+		return (SET_ERROR(err));
+
+	return (0);
+}
+
+/* ARGSUSED */
+static int
+zfs_unmount_snap_cb(const char *snapname, void *arg)
+{
+	return (zfs_unmount_snap(snapname));
+}
+
+/*
+ * When a clone is destroyed, its origin may also need to be destroyed,
+ * in which case it must be unmounted.  This routine will do that unmount
+ * if necessary.
+ */
+void
+zfs_destroy_unmount_origin(const char *fsname)
+{
+	int error;
+	objset_t *os;
+	dsl_dataset_t *ds;
+
+	error = dmu_objset_hold(fsname, FTAG, &os);
+	if (error != 0)
+		return;
+	ds = dmu_objset_ds(os);
+	if (dsl_dir_is_clone(ds->ds_dir) && DS_IS_DEFER_DESTROY(ds->ds_prev)) {
+		char originname[MAXNAMELEN];
+		dsl_dataset_name(ds->ds_prev, originname);
+		dmu_objset_rele(os, FTAG);
+		(void) zfs_unmount_snap(originname);
+	} else {
+		dmu_objset_rele(os, FTAG);
+	}
+}
+
+/*
+ * innvl: {
+ *     "snaps" -> { snapshot1, snapshot2 }
+ *     (optional boolean) "defer"
+ * }
+ *
+ * outnvl: snapshot -> error code (int32)
+ */
+/* ARGSUSED */
+static int
+zfs_ioc_destroy_snaps(const char *poolname, nvlist_t *innvl, nvlist_t *outnvl)
+{
+	nvlist_t *snaps;
+	nvpair_t *pair;
+	boolean_t defer;
+
+	if (nvlist_lookup_nvlist(innvl, "snaps", &snaps) != 0)
+		return (SET_ERROR(EINVAL));
+	defer = nvlist_exists(innvl, "defer");
+
+	for (pair = nvlist_next_nvpair(snaps, NULL); pair != NULL;
+	    pair = nvlist_next_nvpair(snaps, pair)) {
+		(void) zfs_unmount_snap(nvpair_name(pair));
+	}
+
+	return (dsl_destroy_snapshots_nvl(snaps, defer, outnvl));
+}
+
+/*
+ * Create bookmarks.  Bookmark names are of the form <fs>#<bmark>.
+ * All bookmarks must be in the same pool.
+ *
+ * innvl: {
+ *     bookmark1 -> snapshot1, bookmark2 -> snapshot2
+ * }
+ *
+ * outnvl: bookmark -> error code (int32)
+ *
+ */
+/* ARGSUSED */
+static int
+zfs_ioc_bookmark(const char *poolname, nvlist_t *innvl, nvlist_t *outnvl)
+{
+	nvpair_t *pair, *pair2;
+
+	for (pair = nvlist_next_nvpair(innvl, NULL);
+	    pair != NULL; pair = nvlist_next_nvpair(innvl, pair)) {
+		char *snap_name;
+
+		/*
+		 * Verify the snapshot argument.
+		 */
+		if (nvpair_value_string(pair, &snap_name) != 0)
+			return (SET_ERROR(EINVAL));
+
+
+		/* Verify that the keys (bookmarks) are unique */
+		for (pair2 = nvlist_next_nvpair(innvl, pair);
+		    pair2 != NULL; pair2 = nvlist_next_nvpair(innvl, pair2)) {
+			if (strcmp(nvpair_name(pair), nvpair_name(pair2)) == 0)
+				return (SET_ERROR(EINVAL));
+		}
+	}
+
+	return (dsl_bookmark_create(innvl, outnvl));
+}
+
+/*
+ * innvl: {
+ *     property 1, property 2, ...
+ * }
+ *
+ * outnvl: {
+ *     bookmark name 1 -> { property 1, property 2, ... },
+ *     bookmark name 2 -> { property 1, property 2, ... }
+ * }
+ *
+ */
+static int
+zfs_ioc_get_bookmarks(const char *fsname, nvlist_t *innvl, nvlist_t *outnvl)
+{
+	return (dsl_get_bookmarks(fsname, innvl, outnvl));
+}
+
+/*
+ * innvl: {
+ *     bookmark name 1, bookmark name 2
+ * }
+ *
+ * outnvl: bookmark -> error code (int32)
+ *
+ */
+static int
+zfs_ioc_destroy_bookmarks(const char *poolname, nvlist_t *innvl,
+    nvlist_t *outnvl)
+{
+	int error, poollen;
+	nvpair_t *pair;
+
+	poollen = strlen(poolname);
+	for (pair = nvlist_next_nvpair(innvl, NULL);
+	    pair != NULL; pair = nvlist_next_nvpair(innvl, pair)) {
+		const char *name = nvpair_name(pair);
+		const char *cp = strchr(name, '#');
+
+		/*
+		 * The bookmark name must contain an #, and the part after it
+		 * must contain only valid characters.
+		 */
+		if (cp == NULL ||
+		    zfs_component_namecheck(cp + 1, NULL, NULL) != 0)
+			return (SET_ERROR(EINVAL));
+
+		/*
+		 * The bookmark must be in the specified pool.
+		 */
+		if (strncmp(name, poolname, poollen) != 0 ||
+		    (name[poollen] != '/' && name[poollen] != '#'))
+			return (SET_ERROR(EXDEV));
+	}
+
+	error = dsl_bookmark_destroy(innvl, outnvl);
+	return (error);
+}
+
+/*
+ * inputs:
+ * zc_name		name of dataset to destroy
+ * zc_objset_type	type of objset
+ * zc_defer_destroy	mark for deferred destroy
+ *
+ * outputs:		none
+ */
+static int
+zfs_ioc_destroy(zfs_cmd_t *zc)
+{
+	int err;
+
+	if (zc->zc_objset_type == DMU_OST_ZFS) {
+		err = zfs_unmount_snap(zc->zc_name);
+		if (err != 0)
+			return (err);
+	}
+
+	if (strchr(zc->zc_name, '@'))
+		err = dsl_destroy_snapshot(zc->zc_name, zc->zc_defer_destroy);
+	else
+		err = dsl_destroy_head(zc->zc_name);
+
+	return (err);
+}
+
+/*
+ * fsname is name of dataset to rollback (to most recent snapshot)
+ *
+ * innvl is not used.
+ *
+ * outnvl: "target" -> name of most recent snapshot
+ * }
+ */
+/* ARGSUSED */
+static int
+zfs_ioc_rollback(const char *fsname, nvlist_t *args, nvlist_t *outnvl)
+{
+	zfs_sb_t *zsb;
+	int error;
+
+	if (get_zfs_sb(fsname, &zsb) == 0) {
+		error = zfs_suspend_fs(zsb);
+		if (error == 0) {
+			int resume_err;
+
+			error = dsl_dataset_rollback(fsname, zsb, outnvl);
+			resume_err = zfs_resume_fs(zsb, fsname);
+			error = error ? error : resume_err;
+		}
+		deactivate_super(zsb->z_sb);
+	} else {
+		error = dsl_dataset_rollback(fsname, NULL, outnvl);
+	}
+	return (error);
+}
+
+static int
+recursive_unmount(const char *fsname, void *arg)
+{
+	const char *snapname = arg;
+	char *fullname;
+	int error;
+
+	fullname = kmem_asprintf("%s@%s", fsname, snapname);
+	error = zfs_unmount_snap(fullname);
+	strfree(fullname);
+
+	return (error);
+}
+
+/*
+ * inputs:
+ * zc_name	old name of dataset
+ * zc_value	new name of dataset
+ * zc_cookie	recursive flag (only valid for snapshots)
+ *
+ * outputs:	none
+ */
+static int
+zfs_ioc_rename(zfs_cmd_t *zc)
+{
+	boolean_t recursive = zc->zc_cookie & 1;
+	char *at;
+
+	zc->zc_value[sizeof (zc->zc_value) - 1] = '\0';
+	if (dataset_namecheck(zc->zc_value, NULL, NULL) != 0 ||
+	    strchr(zc->zc_value, '%'))
+		return (SET_ERROR(EINVAL));
+
+	at = strchr(zc->zc_name, '@');
+	if (at != NULL) {
+		/* snaps must be in same fs */
+		int error;
+
+		if (strncmp(zc->zc_name, zc->zc_value, at - zc->zc_name + 1))
+			return (SET_ERROR(EXDEV));
+		*at = '\0';
+		if (zc->zc_objset_type == DMU_OST_ZFS) {
+			error = dmu_objset_find(zc->zc_name,
+			    recursive_unmount, at + 1,
+			    recursive ? DS_FIND_CHILDREN : 0);
+			if (error != 0) {
+				*at = '@';
+				return (error);
+			}
+		}
+		error = dsl_dataset_rename_snapshot(zc->zc_name,
+		    at + 1, strchr(zc->zc_value, '@') + 1, recursive);
+		*at = '@';
+
+		return (error);
+	} else {
+		return (dsl_dir_rename(zc->zc_name, zc->zc_value));
+	}
+}
+
+static int
+zfs_check_settable(const char *dsname, nvpair_t *pair, cred_t *cr)
+{
+	const char *propname = nvpair_name(pair);
+	boolean_t issnap = (strchr(dsname, '@') != NULL);
+	zfs_prop_t prop = zfs_name_to_prop(propname);
+	uint64_t intval;
+	int err;
+
+	if (prop == ZPROP_INVAL) {
+		if (zfs_prop_user(propname)) {
+			if ((err = zfs_secpolicy_write_perms(dsname,
+			    ZFS_DELEG_PERM_USERPROP, cr)))
+				return (err);
+			return (0);
+		}
+
+		if (!issnap && zfs_prop_userquota(propname)) {
+			const char *perm = NULL;
+			const char *uq_prefix =
+			    zfs_userquota_prop_prefixes[ZFS_PROP_USERQUOTA];
+			const char *gq_prefix =
+			    zfs_userquota_prop_prefixes[ZFS_PROP_GROUPQUOTA];
+
+			if (strncmp(propname, uq_prefix,
+			    strlen(uq_prefix)) == 0) {
+				perm = ZFS_DELEG_PERM_USERQUOTA;
+			} else if (strncmp(propname, gq_prefix,
+			    strlen(gq_prefix)) == 0) {
+				perm = ZFS_DELEG_PERM_GROUPQUOTA;
+			} else {
+				/* USERUSED and GROUPUSED are read-only */
+				return (SET_ERROR(EINVAL));
+			}
+
+			if ((err = zfs_secpolicy_write_perms(dsname, perm, cr)))
+				return (err);
+			return (0);
+		}
+
+		return (SET_ERROR(EINVAL));
+	}
+
+	if (issnap)
+		return (SET_ERROR(EINVAL));
+
+	if (nvpair_type(pair) == DATA_TYPE_NVLIST) {
+		/*
+		 * dsl_prop_get_all_impl() returns properties in this
+		 * format.
+		 */
+		nvlist_t *attrs;
+		VERIFY(nvpair_value_nvlist(pair, &attrs) == 0);
+		VERIFY(nvlist_lookup_nvpair(attrs, ZPROP_VALUE,
+		    &pair) == 0);
+	}
+
+	/*
+	 * Check that this value is valid for this pool version
+	 */
+	switch (prop) {
+	case ZFS_PROP_COMPRESSION:
+		/*
+		 * If the user specified gzip compression, make sure
+		 * the SPA supports it. We ignore any errors here since
+		 * we'll catch them later.
+		 */
+		if (nvpair_value_uint64(pair, &intval) == 0) {
+			if (intval >= ZIO_COMPRESS_GZIP_1 &&
+			    intval <= ZIO_COMPRESS_GZIP_9 &&
+			    zfs_earlier_version(dsname,
+			    SPA_VERSION_GZIP_COMPRESSION)) {
+				return (SET_ERROR(ENOTSUP));
+			}
+
+			if (intval == ZIO_COMPRESS_ZLE &&
+			    zfs_earlier_version(dsname,
+			    SPA_VERSION_ZLE_COMPRESSION))
+				return (SET_ERROR(ENOTSUP));
+
+			if (intval == ZIO_COMPRESS_LZ4) {
+				spa_t *spa;
+
+				if ((err = spa_open(dsname, &spa, FTAG)) != 0)
+					return (err);
+
+				if (!spa_feature_is_enabled(spa,
+				    SPA_FEATURE_LZ4_COMPRESS)) {
+					spa_close(spa, FTAG);
+					return (SET_ERROR(ENOTSUP));
+				}
+				spa_close(spa, FTAG);
+			}
+
+			/*
+			 * If this is a bootable dataset then
+			 * verify that the compression algorithm
+			 * is supported for booting. We must return
+			 * something other than ENOTSUP since it
+			 * implies a downrev pool version.
+			 */
+			if (zfs_is_bootfs(dsname) &&
+			    !BOOTFS_COMPRESS_VALID(intval)) {
+				return (SET_ERROR(ERANGE));
+			}
+		}
+		break;
+
+	case ZFS_PROP_COPIES:
+		if (zfs_earlier_version(dsname, SPA_VERSION_DITTO_BLOCKS))
+			return (SET_ERROR(ENOTSUP));
+		break;
+
+	case ZFS_PROP_DEDUP:
+		if (zfs_earlier_version(dsname, SPA_VERSION_DEDUP))
+			return (SET_ERROR(ENOTSUP));
+		break;
+
+	case ZFS_PROP_VOLBLOCKSIZE:
+	case ZFS_PROP_RECORDSIZE:
+		/* Record sizes above 128k need the feature to be enabled */
+		if (nvpair_value_uint64(pair, &intval) == 0 &&
+		    intval > SPA_OLD_MAXBLOCKSIZE) {
+			spa_t *spa;
+
+			/*
+			 * If this is a bootable dataset then
+			 * the we don't allow large (>128K) blocks,
+			 * because GRUB doesn't support them.
+			 */
+			if (zfs_is_bootfs(dsname) &&
+			    intval > SPA_OLD_MAXBLOCKSIZE) {
+				return (SET_ERROR(EDOM));
+			}
+
+			/*
+			 * We don't allow setting the property above 1MB,
+			 * unless the tunable has been changed.
+			 */
+			if (intval > zfs_max_recordsize ||
+			    intval > SPA_MAXBLOCKSIZE)
+				return (SET_ERROR(EDOM));
+
+			if ((err = spa_open(dsname, &spa, FTAG)) != 0)
+				return (err);
+
+			if (!spa_feature_is_enabled(spa,
+			    SPA_FEATURE_LARGE_BLOCKS)) {
+				spa_close(spa, FTAG);
+				return (SET_ERROR(ENOTSUP));
+			}
+			spa_close(spa, FTAG);
+		}
+		break;
+
+	case ZFS_PROP_SHARESMB:
+		if (zpl_earlier_version(dsname, ZPL_VERSION_FUID))
+			return (SET_ERROR(ENOTSUP));
+		break;
+
+	case ZFS_PROP_ACLINHERIT:
+		if (nvpair_type(pair) == DATA_TYPE_UINT64 &&
+		    nvpair_value_uint64(pair, &intval) == 0) {
+			if (intval == ZFS_ACL_PASSTHROUGH_X &&
+			    zfs_earlier_version(dsname,
+			    SPA_VERSION_PASSTHROUGH_X))
+				return (SET_ERROR(ENOTSUP));
+		}
+		break;
+	default:
+		break;
+	}
+
+	return (zfs_secpolicy_setprop(dsname, prop, pair, CRED()));
+}
+
+/*
+ * Removes properties from the given props list that fail permission checks
+ * needed to clear them and to restore them in case of a receive error. For each
+ * property, make sure we have both set and inherit permissions.
+ *
+ * Returns the first error encountered if any permission checks fail. If the
+ * caller provides a non-NULL errlist, it also gives the complete list of names
+ * of all the properties that failed a permission check along with the
+ * corresponding error numbers. The caller is responsible for freeing the
+ * returned errlist.
+ *
+ * If every property checks out successfully, zero is returned and the list
+ * pointed at by errlist is NULL.
+ */
+static int
+zfs_check_clearable(char *dataset, nvlist_t *props, nvlist_t **errlist)
+{
+	zfs_cmd_t *zc;
+	nvpair_t *pair, *next_pair;
+	nvlist_t *errors;
+	int err, rv = 0;
+
+	if (props == NULL)
+		return (0);
+
+	VERIFY(nvlist_alloc(&errors, NV_UNIQUE_NAME, KM_SLEEP) == 0);
+
+	zc = kmem_alloc(sizeof (zfs_cmd_t), KM_SLEEP);
+	(void) strcpy(zc->zc_name, dataset);
+	pair = nvlist_next_nvpair(props, NULL);
+	while (pair != NULL) {
+		next_pair = nvlist_next_nvpair(props, pair);
+
+		(void) strcpy(zc->zc_value, nvpair_name(pair));
+		if ((err = zfs_check_settable(dataset, pair, CRED())) != 0 ||
+		    (err = zfs_secpolicy_inherit_prop(zc, NULL, CRED())) != 0) {
+			VERIFY(nvlist_remove_nvpair(props, pair) == 0);
+			VERIFY(nvlist_add_int32(errors,
+			    zc->zc_value, err) == 0);
+		}
+		pair = next_pair;
+	}
+	kmem_free(zc, sizeof (zfs_cmd_t));
+
+	if ((pair = nvlist_next_nvpair(errors, NULL)) == NULL) {
+		nvlist_free(errors);
+		errors = NULL;
+	} else {
+		VERIFY(nvpair_value_int32(pair, &rv) == 0);
+	}
+
+	if (errlist == NULL)
+		nvlist_free(errors);
+	else
+		*errlist = errors;
+
+	return (rv);
+}
+
+static boolean_t
+propval_equals(nvpair_t *p1, nvpair_t *p2)
+{
+	if (nvpair_type(p1) == DATA_TYPE_NVLIST) {
+		/* dsl_prop_get_all_impl() format */
+		nvlist_t *attrs;
+		VERIFY(nvpair_value_nvlist(p1, &attrs) == 0);
+		VERIFY(nvlist_lookup_nvpair(attrs, ZPROP_VALUE,
+		    &p1) == 0);
+	}
+
+	if (nvpair_type(p2) == DATA_TYPE_NVLIST) {
+		nvlist_t *attrs;
+		VERIFY(nvpair_value_nvlist(p2, &attrs) == 0);
+		VERIFY(nvlist_lookup_nvpair(attrs, ZPROP_VALUE,
+		    &p2) == 0);
+	}
+
+	if (nvpair_type(p1) != nvpair_type(p2))
+		return (B_FALSE);
+
+	if (nvpair_type(p1) == DATA_TYPE_STRING) {
+		char *valstr1, *valstr2;
+
+		VERIFY(nvpair_value_string(p1, (char **)&valstr1) == 0);
+		VERIFY(nvpair_value_string(p2, (char **)&valstr2) == 0);
+		return (strcmp(valstr1, valstr2) == 0);
+	} else {
+		uint64_t intval1, intval2;
+
+		VERIFY(nvpair_value_uint64(p1, &intval1) == 0);
+		VERIFY(nvpair_value_uint64(p2, &intval2) == 0);
+		return (intval1 == intval2);
+	}
+}
+
+/*
+ * Remove properties from props if they are not going to change (as determined
+ * by comparison with origprops). Remove them from origprops as well, since we
+ * do not need to clear or restore properties that won't change.
+ */
+static void
+props_reduce(nvlist_t *props, nvlist_t *origprops)
+{
+	nvpair_t *pair, *next_pair;
+
+	if (origprops == NULL)
+		return; /* all props need to be received */
+
+	pair = nvlist_next_nvpair(props, NULL);
+	while (pair != NULL) {
+		const char *propname = nvpair_name(pair);
+		nvpair_t *match;
+
+		next_pair = nvlist_next_nvpair(props, pair);
+
+		if ((nvlist_lookup_nvpair(origprops, propname,
+		    &match) != 0) || !propval_equals(pair, match))
+			goto next; /* need to set received value */
+
+		/* don't clear the existing received value */
+		(void) nvlist_remove_nvpair(origprops, match);
+		/* don't bother receiving the property */
+		(void) nvlist_remove_nvpair(props, pair);
+next:
+		pair = next_pair;
+	}
+}
+
+#ifdef	DEBUG
+static boolean_t zfs_ioc_recv_inject_err;
+#endif
+
+/*
+ * inputs:
+ * zc_name		name of containing filesystem
+ * zc_nvlist_src{_size}	nvlist of properties to apply
+ * zc_value		name of snapshot to create
+ * zc_string		name of clone origin (if DRR_FLAG_CLONE)
+ * zc_cookie		file descriptor to recv from
+ * zc_begin_record	the BEGIN record of the stream (not byteswapped)
+ * zc_guid		force flag
+ * zc_cleanup_fd	cleanup-on-exit file descriptor
+ * zc_action_handle	handle for this guid/ds mapping (or zero on first call)
+ *
+ * outputs:
+ * zc_cookie		number of bytes read
+ * zc_nvlist_dst{_size} error for each unapplied received property
+ * zc_obj		zprop_errflags_t
+ * zc_action_handle	handle for this guid/ds mapping
+ */
+static int
+zfs_ioc_recv(zfs_cmd_t *zc)
+{
+	file_t *fp;
+	dmu_recv_cookie_t drc;
+	boolean_t force = (boolean_t)zc->zc_guid;
+	int fd;
+	int error = 0;
+	int props_error = 0;
+	nvlist_t *errors;
+	offset_t off;
+	nvlist_t *props = NULL; /* sent properties */
+	nvlist_t *origprops = NULL; /* existing properties */
+	char *origin = NULL;
+	char *tosnap;
+	char tofs[ZFS_MAXNAMELEN];
+	boolean_t first_recvd_props = B_FALSE;
+
+	if (dataset_namecheck(zc->zc_value, NULL, NULL) != 0 ||
+	    strchr(zc->zc_value, '@') == NULL ||
+	    strchr(zc->zc_value, '%'))
+		return (SET_ERROR(EINVAL));
+
+	(void) strcpy(tofs, zc->zc_value);
+	tosnap = strchr(tofs, '@');
+	*tosnap++ = '\0';
+
+	if (zc->zc_nvlist_src != 0 &&
+	    (error = get_nvlist(zc->zc_nvlist_src, zc->zc_nvlist_src_size,
+	    zc->zc_iflags, &props)) != 0)
+		return (error);
+
+	fd = zc->zc_cookie;
+	fp = getf(fd);
+	if (fp == NULL) {
+		nvlist_free(props);
+		return (SET_ERROR(EBADF));
+	}
+
+	VERIFY(nvlist_alloc(&errors, NV_UNIQUE_NAME, KM_SLEEP) == 0);
+
+	if (zc->zc_string[0])
+		origin = zc->zc_string;
+
+	error = dmu_recv_begin(tofs, tosnap,
+	    &zc->zc_begin_record, force, origin, &drc);
+	if (error != 0)
+		goto out;
+
+	/*
+	 * Set properties before we receive the stream so that they are applied
+	 * to the new data. Note that we must call dmu_recv_stream() if
+	 * dmu_recv_begin() succeeds.
+	 */
+	if (props != NULL && !drc.drc_newfs) {
+		if (spa_version(dsl_dataset_get_spa(drc.drc_ds)) >=
+		    SPA_VERSION_RECVD_PROPS &&
+		    !dsl_prop_get_hasrecvd(tofs))
+			first_recvd_props = B_TRUE;
+
+		/*
+		 * If new received properties are supplied, they are to
+		 * completely replace the existing received properties, so stash
+		 * away the existing ones.
+		 */
+		if (dsl_prop_get_received(tofs, &origprops) == 0) {
+			nvlist_t *errlist = NULL;
+			/*
+			 * Don't bother writing a property if its value won't
+			 * change (and avoid the unnecessary security checks).
+			 *
+			 * The first receive after SPA_VERSION_RECVD_PROPS is a
+			 * special case where we blow away all local properties
+			 * regardless.
+			 */
+			if (!first_recvd_props)
+				props_reduce(props, origprops);
+			if (zfs_check_clearable(tofs, origprops, &errlist) != 0)
+				(void) nvlist_merge(errors, errlist, 0);
+			nvlist_free(errlist);
+
+			if (clear_received_props(tofs, origprops,
+			    first_recvd_props ? NULL : props) != 0)
+				zc->zc_obj |= ZPROP_ERR_NOCLEAR;
+		} else {
+			zc->zc_obj |= ZPROP_ERR_NOCLEAR;
+		}
+	}
+
+	if (props != NULL) {
+		props_error = dsl_prop_set_hasrecvd(tofs);
+
+		if (props_error == 0) {
+			(void) zfs_set_prop_nvlist(tofs, ZPROP_SRC_RECEIVED,
+			    props, errors);
+		}
+	}
+
+	if (zc->zc_nvlist_dst_size != 0 &&
+	    (nvlist_smush(errors, zc->zc_nvlist_dst_size) != 0 ||
+	    put_nvlist(zc, errors) != 0)) {
+		/*
+		 * Caller made zc->zc_nvlist_dst less than the minimum expected
+		 * size or supplied an invalid address.
+		 */
+		props_error = SET_ERROR(EINVAL);
+	}
+
+	off = fp->f_offset;
+	error = dmu_recv_stream(&drc, fp->f_vnode, &off, zc->zc_cleanup_fd,
+	    &zc->zc_action_handle);
+
+	if (error == 0) {
+		zfs_sb_t *zsb = NULL;
+
+		if (get_zfs_sb(tofs, &zsb) == 0) {
+			/* online recv */
+			int end_err;
+
+			error = zfs_suspend_fs(zsb);
+			/*
+			 * If the suspend fails, then the recv_end will
+			 * likely also fail, and clean up after itself.
+			 */
+			end_err = dmu_recv_end(&drc, zsb);
+			if (error == 0)
+				error = zfs_resume_fs(zsb, tofs);
+			error = error ? error : end_err;
+			deactivate_super(zsb->z_sb);
+		} else {
+			error = dmu_recv_end(&drc, NULL);
+		}
+	}
+
+	zc->zc_cookie = off - fp->f_offset;
+	if (VOP_SEEK(fp->f_vnode, fp->f_offset, &off, NULL) == 0)
+		fp->f_offset = off;
+
+#ifdef	DEBUG
+	if (zfs_ioc_recv_inject_err) {
+		zfs_ioc_recv_inject_err = B_FALSE;
+		error = 1;
+	}
+#endif
+
+	/*
+	 * On error, restore the original props.
+	 */
+	if (error != 0 && props != NULL && !drc.drc_newfs) {
+		if (clear_received_props(tofs, props, NULL) != 0) {
+			/*
+			 * We failed to clear the received properties.
+			 * Since we may have left a $recvd value on the
+			 * system, we can't clear the $hasrecvd flag.
+			 */
+			zc->zc_obj |= ZPROP_ERR_NORESTORE;
+		} else if (first_recvd_props) {
+			dsl_prop_unset_hasrecvd(tofs);
+		}
+
+		if (origprops == NULL && !drc.drc_newfs) {
+			/* We failed to stash the original properties. */
+			zc->zc_obj |= ZPROP_ERR_NORESTORE;
+		}
+
+		/*
+		 * dsl_props_set() will not convert RECEIVED to LOCAL on or
+		 * after SPA_VERSION_RECVD_PROPS, so we need to specify LOCAL
+		 * explictly if we're restoring local properties cleared in the
+		 * first new-style receive.
+		 */
+		if (origprops != NULL &&
+		    zfs_set_prop_nvlist(tofs, (first_recvd_props ?
+		    ZPROP_SRC_LOCAL : ZPROP_SRC_RECEIVED),
+		    origprops, NULL) != 0) {
+			/*
+			 * We stashed the original properties but failed to
+			 * restore them.
+			 */
+			zc->zc_obj |= ZPROP_ERR_NORESTORE;
+		}
+	}
+out:
+	nvlist_free(props);
+	nvlist_free(origprops);
+	nvlist_free(errors);
+	releasef(fd);
+
+	if (error == 0)
+		error = props_error;
+
+	return (error);
+}
+
+/*
+ * inputs:
+ * zc_name	name of snapshot to send
+ * zc_cookie	file descriptor to send stream to
+ * zc_obj	fromorigin flag (mutually exclusive with zc_fromobj)
+ * zc_sendobj	objsetid of snapshot to send
+ * zc_fromobj	objsetid of incremental fromsnap (may be zero)
+ * zc_guid	if set, estimate size of stream only.  zc_cookie is ignored.
+ *		output size in zc_objset_type.
+ * zc_flags	lzc_send_flags
+ *
+ * outputs:
+ * zc_objset_type	estimated size, if zc_guid is set
+ */
+static int
+zfs_ioc_send(zfs_cmd_t *zc)
+{
+	int error;
+	offset_t off;
+	boolean_t estimate = (zc->zc_guid != 0);
+	boolean_t embedok = (zc->zc_flags & 0x1);
+	boolean_t large_block_ok = (zc->zc_flags & 0x2);
+
+	if (zc->zc_obj != 0) {
+		dsl_pool_t *dp;
+		dsl_dataset_t *tosnap;
+
+		error = dsl_pool_hold(zc->zc_name, FTAG, &dp);
+		if (error != 0)
+			return (error);
+
+		error = dsl_dataset_hold_obj(dp, zc->zc_sendobj, FTAG, &tosnap);
+		if (error != 0) {
+			dsl_pool_rele(dp, FTAG);
+			return (error);
+		}
+
+		if (dsl_dir_is_clone(tosnap->ds_dir))
+			zc->zc_fromobj =
+			    dsl_dir_phys(tosnap->ds_dir)->dd_origin_obj;
+		dsl_dataset_rele(tosnap, FTAG);
+		dsl_pool_rele(dp, FTAG);
+	}
+
+	if (estimate) {
+		dsl_pool_t *dp;
+		dsl_dataset_t *tosnap;
+		dsl_dataset_t *fromsnap = NULL;
+
+		error = dsl_pool_hold(zc->zc_name, FTAG, &dp);
+		if (error != 0)
+			return (error);
+
+		error = dsl_dataset_hold_obj(dp, zc->zc_sendobj, FTAG, &tosnap);
+		if (error != 0) {
+			dsl_pool_rele(dp, FTAG);
+			return (error);
+		}
+
+		if (zc->zc_fromobj != 0) {
+			error = dsl_dataset_hold_obj(dp, zc->zc_fromobj,
+			    FTAG, &fromsnap);
+			if (error != 0) {
+				dsl_dataset_rele(tosnap, FTAG);
+				dsl_pool_rele(dp, FTAG);
+				return (error);
+			}
+		}
+
+		error = dmu_send_estimate(tosnap, fromsnap,
+		    &zc->zc_objset_type);
+
+		if (fromsnap != NULL)
+			dsl_dataset_rele(fromsnap, FTAG);
+		dsl_dataset_rele(tosnap, FTAG);
+		dsl_pool_rele(dp, FTAG);
+	} else {
+		file_t *fp = getf(zc->zc_cookie);
+		if (fp == NULL)
+			return (SET_ERROR(EBADF));
+
+		off = fp->f_offset;
+		error = dmu_send_obj(zc->zc_name, zc->zc_sendobj,
+		    zc->zc_fromobj, embedok, large_block_ok,
+		    zc->zc_cookie, fp->f_vnode, &off);
+
+		if (VOP_SEEK(fp->f_vnode, fp->f_offset, &off, NULL) == 0)
+			fp->f_offset = off;
+		releasef(zc->zc_cookie);
+	}
+	return (error);
+}
+
+/*
+ * inputs:
+ * zc_name	name of snapshot on which to report progress
+ * zc_cookie	file descriptor of send stream
+ *
+ * outputs:
+ * zc_cookie	number of bytes written in send stream thus far
+ */
+static int
+zfs_ioc_send_progress(zfs_cmd_t *zc)
+{
+	dsl_pool_t *dp;
+	dsl_dataset_t *ds;
+	dmu_sendarg_t *dsp = NULL;
+	int error;
+
+	error = dsl_pool_hold(zc->zc_name, FTAG, &dp);
+	if (error != 0)
+		return (error);
+
+	error = dsl_dataset_hold(dp, zc->zc_name, FTAG, &ds);
+	if (error != 0) {
+		dsl_pool_rele(dp, FTAG);
+		return (error);
+	}
+
+	mutex_enter(&ds->ds_sendstream_lock);
+
+	/*
+	 * Iterate over all the send streams currently active on this dataset.
+	 * If there's one which matches the specified file descriptor _and_ the
+	 * stream was started by the current process, return the progress of
+	 * that stream.
+	 */
+
+	for (dsp = list_head(&ds->ds_sendstreams); dsp != NULL;
+	    dsp = list_next(&ds->ds_sendstreams, dsp)) {
+		if (dsp->dsa_outfd == zc->zc_cookie &&
+		    dsp->dsa_proc->group_leader == curproc->group_leader)
+			break;
+	}
+
+	if (dsp != NULL)
+		zc->zc_cookie = *(dsp->dsa_off);
+	else
+		error = SET_ERROR(ENOENT);
+
+	mutex_exit(&ds->ds_sendstream_lock);
+	dsl_dataset_rele(ds, FTAG);
+	dsl_pool_rele(dp, FTAG);
+	return (error);
+}
+
+static int
+zfs_ioc_inject_fault(zfs_cmd_t *zc)
+{
+	int id, error;
+
+	error = zio_inject_fault(zc->zc_name, (int)zc->zc_guid, &id,
+	    &zc->zc_inject_record);
+
+	if (error == 0)
+		zc->zc_guid = (uint64_t)id;
+
+	return (error);
+}
+
+static int
+zfs_ioc_clear_fault(zfs_cmd_t *zc)
+{
+	return (zio_clear_fault((int)zc->zc_guid));
+}
+
+static int
+zfs_ioc_inject_list_next(zfs_cmd_t *zc)
+{
+	int id = (int)zc->zc_guid;
+	int error;
+
+	error = zio_inject_list_next(&id, zc->zc_name, sizeof (zc->zc_name),
+	    &zc->zc_inject_record);
+
+	zc->zc_guid = id;
+
+	return (error);
+}
+
+static int
+zfs_ioc_error_log(zfs_cmd_t *zc)
+{
+	spa_t *spa;
+	int error;
+	size_t count = (size_t)zc->zc_nvlist_dst_size;
+
+	if ((error = spa_open(zc->zc_name, &spa, FTAG)) != 0)
+		return (error);
+
+	error = spa_get_errlog(spa, (void *)(uintptr_t)zc->zc_nvlist_dst,
+	    &count);
+	if (error == 0)
+		zc->zc_nvlist_dst_size = count;
+	else
+		zc->zc_nvlist_dst_size = spa_get_errlog_size(spa);
+
+	spa_close(spa, FTAG);
+
+	return (error);
+}
+
+static int
+zfs_ioc_clear(zfs_cmd_t *zc)
+{
+	spa_t *spa;
+	vdev_t *vd;
+	int error;
+
+	/*
+	 * On zpool clear we also fix up missing slogs
+	 */
+	mutex_enter(&spa_namespace_lock);
+	spa = spa_lookup(zc->zc_name);
+	if (spa == NULL) {
+		mutex_exit(&spa_namespace_lock);
+		return (SET_ERROR(EIO));
+	}
+	if (spa_get_log_state(spa) == SPA_LOG_MISSING) {
+		/* we need to let spa_open/spa_load clear the chains */
+		spa_set_log_state(spa, SPA_LOG_CLEAR);
+	}
+	spa->spa_last_open_failed = 0;
+	mutex_exit(&spa_namespace_lock);
+
+	if (zc->zc_cookie & ZPOOL_NO_REWIND) {
+		error = spa_open(zc->zc_name, &spa, FTAG);
+	} else {
+		nvlist_t *policy;
+		nvlist_t *config = NULL;
+
+		if (zc->zc_nvlist_src == 0)
+			return (SET_ERROR(EINVAL));
+
+		if ((error = get_nvlist(zc->zc_nvlist_src,
+		    zc->zc_nvlist_src_size, zc->zc_iflags, &policy)) == 0) {
+			error = spa_open_rewind(zc->zc_name, &spa, FTAG,
+			    policy, &config);
+			if (config != NULL) {
+				int err;
+
+				if ((err = put_nvlist(zc, config)) != 0)
+					error = err;
+				nvlist_free(config);
+			}
+			nvlist_free(policy);
+		}
+	}
+
+	if (error != 0)
+		return (error);
+
+	spa_vdev_state_enter(spa, SCL_NONE);
+
+	if (zc->zc_guid == 0) {
+		vd = NULL;
+	} else {
+		vd = spa_lookup_by_guid(spa, zc->zc_guid, B_TRUE);
+		if (vd == NULL) {
+			(void) spa_vdev_state_exit(spa, NULL, ENODEV);
+			spa_close(spa, FTAG);
+			return (SET_ERROR(ENODEV));
+		}
+	}
+
+	vdev_clear(spa, vd);
+
+	(void) spa_vdev_state_exit(spa, NULL, 0);
+
+	/*
+	 * Resume any suspended I/Os.
+	 */
+	if (zio_resume(spa) != 0)
+		error = SET_ERROR(EIO);
+
+	spa_close(spa, FTAG);
+
+	return (error);
+}
+
+static int
+zfs_ioc_pool_reopen(zfs_cmd_t *zc)
+{
+	spa_t *spa;
+	int error;
+
+	error = spa_open(zc->zc_name, &spa, FTAG);
+	if (error != 0)
+		return (error);
+
+	spa_vdev_state_enter(spa, SCL_NONE);
+
+	/*
+	 * If a resilver is already in progress then set the
+	 * spa_scrub_reopen flag to B_TRUE so that we don't restart
+	 * the scan as a side effect of the reopen. Otherwise, let
+	 * vdev_open() decided if a resilver is required.
+	 */
+	spa->spa_scrub_reopen = dsl_scan_resilvering(spa->spa_dsl_pool);
+	vdev_reopen(spa->spa_root_vdev);
+	spa->spa_scrub_reopen = B_FALSE;
+
+	(void) spa_vdev_state_exit(spa, NULL, 0);
+	spa_close(spa, FTAG);
+	return (0);
+}
+/*
+ * inputs:
+ * zc_name	name of filesystem
+ * zc_value	name of origin snapshot
+ *
+ * outputs:
+ * zc_string	name of conflicting snapshot, if there is one
+ */
+static int
+zfs_ioc_promote(zfs_cmd_t *zc)
+{
+	char *cp;
+
+	/*
+	 * We don't need to unmount *all* the origin fs's snapshots, but
+	 * it's easier.
+	 */
+	cp = strchr(zc->zc_value, '@');
+	if (cp)
+		*cp = '\0';
+	(void) dmu_objset_find(zc->zc_value,
+	    zfs_unmount_snap_cb, NULL, DS_FIND_SNAPSHOTS);
+	return (dsl_dataset_promote(zc->zc_name, zc->zc_string));
+}
+
+/*
+ * Retrieve a single {user|group}{used|quota}@... property.
+ *
+ * inputs:
+ * zc_name	name of filesystem
+ * zc_objset_type zfs_userquota_prop_t
+ * zc_value	domain name (eg. "S-1-234-567-89")
+ * zc_guid	RID/UID/GID
+ *
+ * outputs:
+ * zc_cookie	property value
+ */
+static int
+zfs_ioc_userspace_one(zfs_cmd_t *zc)
+{
+	zfs_sb_t *zsb;
+	int error;
+
+	if (zc->zc_objset_type >= ZFS_NUM_USERQUOTA_PROPS)
+		return (SET_ERROR(EINVAL));
+
+	error = zfs_sb_hold(zc->zc_name, FTAG, &zsb, B_FALSE);
+	if (error != 0)
+		return (error);
+
+	error = zfs_userspace_one(zsb,
+	    zc->zc_objset_type, zc->zc_value, zc->zc_guid, &zc->zc_cookie);
+	zfs_sb_rele(zsb, FTAG);
+
+	return (error);
+}
+
+/*
+ * inputs:
+ * zc_name		name of filesystem
+ * zc_cookie		zap cursor
+ * zc_objset_type	zfs_userquota_prop_t
+ * zc_nvlist_dst[_size] buffer to fill (not really an nvlist)
+ *
+ * outputs:
+ * zc_nvlist_dst[_size]	data buffer (array of zfs_useracct_t)
+ * zc_cookie	zap cursor
+ */
+static int
+zfs_ioc_userspace_many(zfs_cmd_t *zc)
+{
+	zfs_sb_t *zsb;
+	int bufsize = zc->zc_nvlist_dst_size;
+	int error;
+	void *buf;
+
+	if (bufsize <= 0)
+		return (SET_ERROR(ENOMEM));
+
+	error = zfs_sb_hold(zc->zc_name, FTAG, &zsb, B_FALSE);
+	if (error != 0)
+		return (error);
+
+	buf = vmem_alloc(bufsize, KM_SLEEP);
+
+	error = zfs_userspace_many(zsb, zc->zc_objset_type, &zc->zc_cookie,
+	    buf, &zc->zc_nvlist_dst_size);
+
+	if (error == 0) {
+		error = xcopyout(buf,
+		    (void *)(uintptr_t)zc->zc_nvlist_dst,
+		    zc->zc_nvlist_dst_size);
+	}
+	vmem_free(buf, bufsize);
+	zfs_sb_rele(zsb, FTAG);
+
+	return (error);
+}
+
+/*
+ * inputs:
+ * zc_name		name of filesystem
+ *
+ * outputs:
+ * none
+ */
+static int
+zfs_ioc_userspace_upgrade(zfs_cmd_t *zc)
+{
+	objset_t *os;
+	int error = 0;
+	zfs_sb_t *zsb;
+
+	if (get_zfs_sb(zc->zc_name, &zsb) == 0) {
+		if (!dmu_objset_userused_enabled(zsb->z_os)) {
+			/*
+			 * If userused is not enabled, it may be because the
+			 * objset needs to be closed & reopened (to grow the
+			 * objset_phys_t).  Suspend/resume the fs will do that.
+			 */
+			error = zfs_suspend_fs(zsb);
+			if (error == 0) {
+				dmu_objset_refresh_ownership(zsb->z_os,
+				    zsb);
+				error = zfs_resume_fs(zsb, zc->zc_name);
+			}
+		}
+		if (error == 0)
+			error = dmu_objset_userspace_upgrade(zsb->z_os);
+		deactivate_super(zsb->z_sb);
+	} else {
+		/* XXX kind of reading contents without owning */
+		error = dmu_objset_hold(zc->zc_name, FTAG, &os);
+		if (error != 0)
+			return (error);
+
+		error = dmu_objset_userspace_upgrade(os);
+		dmu_objset_rele(os, FTAG);
+	}
+
+	return (error);
+}
+
+static int
+zfs_ioc_share(zfs_cmd_t *zc)
+{
+	return (SET_ERROR(ENOSYS));
+}
+
+ace_t full_access[] = {
+	{(uid_t)-1, ACE_ALL_PERMS, ACE_EVERYONE, 0}
+};
+
+/*
+ * inputs:
+ * zc_name		name of containing filesystem
+ * zc_obj		object # beyond which we want next in-use object #
+ *
+ * outputs:
+ * zc_obj		next in-use object #
+ */
+static int
+zfs_ioc_next_obj(zfs_cmd_t *zc)
+{
+	objset_t *os = NULL;
+	int error;
+
+	error = dmu_objset_hold(zc->zc_name, FTAG, &os);
+	if (error != 0)
+		return (error);
+
+	error = dmu_object_next(os, &zc->zc_obj, B_FALSE, 0);
+
+	dmu_objset_rele(os, FTAG);
+	return (error);
+}
+
+/*
+ * inputs:
+ * zc_name		name of filesystem
+ * zc_value		prefix name for snapshot
+ * zc_cleanup_fd	cleanup-on-exit file descriptor for calling process
+ *
+ * outputs:
+ * zc_value		short name of new snapshot
+ */
+static int
+zfs_ioc_tmp_snapshot(zfs_cmd_t *zc)
+{
+	char *snap_name;
+	char *hold_name;
+	int error;
+	minor_t minor;
+
+	error = zfs_onexit_fd_hold(zc->zc_cleanup_fd, &minor);
+	if (error != 0)
+		return (error);
+
+	snap_name = kmem_asprintf("%s-%016llx", zc->zc_value,
+	    (u_longlong_t)ddi_get_lbolt64());
+	hold_name = kmem_asprintf("%%%s", zc->zc_value);
+
+	error = dsl_dataset_snapshot_tmp(zc->zc_name, snap_name, minor,
+	    hold_name);
+	if (error == 0)
+		(void) strcpy(zc->zc_value, snap_name);
+	strfree(snap_name);
+	strfree(hold_name);
+	zfs_onexit_fd_rele(zc->zc_cleanup_fd);
+	return (error);
+}
+
+/*
+ * inputs:
+ * zc_name		name of "to" snapshot
+ * zc_value		name of "from" snapshot
+ * zc_cookie		file descriptor to write diff data on
+ *
+ * outputs:
+ * dmu_diff_record_t's to the file descriptor
+ */
+static int
+zfs_ioc_diff(zfs_cmd_t *zc)
+{
+	file_t *fp;
+	offset_t off;
+	int error;
+
+	fp = getf(zc->zc_cookie);
+	if (fp == NULL)
+		return (SET_ERROR(EBADF));
+
+	off = fp->f_offset;
+
+	error = dmu_diff(zc->zc_name, zc->zc_value, fp->f_vnode, &off);
+
+	if (VOP_SEEK(fp->f_vnode, fp->f_offset, &off, NULL) == 0)
+		fp->f_offset = off;
+	releasef(zc->zc_cookie);
+
+	return (error);
+}
+
+/*
+ * Remove all ACL files in shares dir
+ */
+#ifdef HAVE_SMB_SHARE
+static int
+zfs_smb_acl_purge(znode_t *dzp)
+{
+	zap_cursor_t	zc;
+	zap_attribute_t	zap;
+	zfs_sb_t *zsb = ZTOZSB(dzp);
+	int error;
+
+	for (zap_cursor_init(&zc, zsb->z_os, dzp->z_id);
+	    (error = zap_cursor_retrieve(&zc, &zap)) == 0;
+	    zap_cursor_advance(&zc)) {
+		if ((error = VOP_REMOVE(ZTOV(dzp), zap.za_name, kcred,
+		    NULL, 0)) != 0)
+			break;
+	}
+	zap_cursor_fini(&zc);
+	return (error);
+}
+#endif /* HAVE_SMB_SHARE */
+
+static int
+zfs_ioc_smb_acl(zfs_cmd_t *zc)
+{
+#ifdef HAVE_SMB_SHARE
+	vnode_t *vp;
+	znode_t *dzp;
+	vnode_t *resourcevp = NULL;
+	znode_t *sharedir;
+	zfs_sb_t *zsb;
+	nvlist_t *nvlist;
+	char *src, *target;
+	vattr_t vattr;
+	vsecattr_t vsec;
+	int error = 0;
+
+	if ((error = lookupname(zc->zc_value, UIO_SYSSPACE,
+	    NO_FOLLOW, NULL, &vp)) != 0)
+		return (error);
+
+	/* Now make sure mntpnt and dataset are ZFS */
+
+	if (vp->v_vfsp->vfs_fstype != zfsfstype ||
+	    (strcmp((char *)refstr_value(vp->v_vfsp->vfs_resource),
+	    zc->zc_name) != 0)) {
+		VN_RELE(vp);
+		return (SET_ERROR(EINVAL));
+	}
+
+	dzp = VTOZ(vp);
+	zsb = ZTOZSB(dzp);
+	ZFS_ENTER(zsb);
+
+	/*
+	 * Create share dir if its missing.
+	 */
+	mutex_enter(&zsb->z_lock);
+	if (zsb->z_shares_dir == 0) {
+		dmu_tx_t *tx;
+
+		tx = dmu_tx_create(zsb->z_os);
+		dmu_tx_hold_zap(tx, MASTER_NODE_OBJ, TRUE,
+		    ZFS_SHARES_DIR);
+		dmu_tx_hold_zap(tx, DMU_NEW_OBJECT, FALSE, NULL);
+		error = dmu_tx_assign(tx, TXG_WAIT);
+		if (error != 0) {
+			dmu_tx_abort(tx);
+		} else {
+			error = zfs_create_share_dir(zsb, tx);
+			dmu_tx_commit(tx);
+		}
+		if (error != 0) {
+			mutex_exit(&zsb->z_lock);
+			VN_RELE(vp);
+			ZFS_EXIT(zsb);
+			return (error);
+		}
+	}
+	mutex_exit(&zsb->z_lock);
+
+	ASSERT(zsb->z_shares_dir);
+	if ((error = zfs_zget(zsb, zsb->z_shares_dir, &sharedir)) != 0) {
+		VN_RELE(vp);
+		ZFS_EXIT(zsb);
+		return (error);
+	}
+
+	switch (zc->zc_cookie) {
+	case ZFS_SMB_ACL_ADD:
+		vattr.va_mask = AT_MODE|AT_UID|AT_GID|AT_TYPE;
+		vattr.va_mode = S_IFREG|0777;
+		vattr.va_uid = 0;
+		vattr.va_gid = 0;
+
+		vsec.vsa_mask = VSA_ACE;
+		vsec.vsa_aclentp = &full_access;
+		vsec.vsa_aclentsz = sizeof (full_access);
+		vsec.vsa_aclcnt = 1;
+
+		error = VOP_CREATE(ZTOV(sharedir), zc->zc_string,
+		    &vattr, EXCL, 0, &resourcevp, kcred, 0, NULL, &vsec);
+		if (resourcevp)
+			VN_RELE(resourcevp);
+		break;
+
+	case ZFS_SMB_ACL_REMOVE:
+		error = VOP_REMOVE(ZTOV(sharedir), zc->zc_string, kcred,
+		    NULL, 0);
+		break;
+
+	case ZFS_SMB_ACL_RENAME:
+		if ((error = get_nvlist(zc->zc_nvlist_src,
+		    zc->zc_nvlist_src_size, zc->zc_iflags, &nvlist)) != 0) {
+			VN_RELE(vp);
+			ZFS_EXIT(zsb);
+			return (error);
+		}
+		if (nvlist_lookup_string(nvlist, ZFS_SMB_ACL_SRC, &src) ||
+		    nvlist_lookup_string(nvlist, ZFS_SMB_ACL_TARGET,
+		    &target)) {
+			VN_RELE(vp);
+			VN_RELE(ZTOV(sharedir));
+			ZFS_EXIT(zsb);
+			nvlist_free(nvlist);
+			return (error);
+		}
+		error = VOP_RENAME(ZTOV(sharedir), src, ZTOV(sharedir), target,
+		    kcred, NULL, 0);
+		nvlist_free(nvlist);
+		break;
+
+	case ZFS_SMB_ACL_PURGE:
+		error = zfs_smb_acl_purge(sharedir);
+		break;
+
+	default:
+		error = SET_ERROR(EINVAL);
+		break;
+	}
+
+	VN_RELE(vp);
+	VN_RELE(ZTOV(sharedir));
+
+	ZFS_EXIT(zsb);
+
+	return (error);
+#else
+	return (SET_ERROR(ENOTSUP));
+#endif /* HAVE_SMB_SHARE */
+}
+
+/*
+ * innvl: {
+ *     "holds" -> { snapname -> holdname (string), ... }
+ *     (optional) "cleanup_fd" -> fd (int32)
+ * }
+ *
+ * outnvl: {
+ *     snapname -> error value (int32)
+ *     ...
+ * }
+ */
+/* ARGSUSED */
+static int
+zfs_ioc_hold(const char *pool, nvlist_t *args, nvlist_t *errlist)
+{
+	nvlist_t *holds;
+	int cleanup_fd = -1;
+	int error;
+	minor_t minor = 0;
+
+	error = nvlist_lookup_nvlist(args, "holds", &holds);
+	if (error != 0)
+		return (SET_ERROR(EINVAL));
+
+	if (nvlist_lookup_int32(args, "cleanup_fd", &cleanup_fd) == 0) {
+		error = zfs_onexit_fd_hold(cleanup_fd, &minor);
+		if (error != 0)
+			return (error);
+	}
+
+	error = dsl_dataset_user_hold(holds, minor, errlist);
+	if (minor != 0)
+		zfs_onexit_fd_rele(cleanup_fd);
+	return (error);
+}
+
+/*
+ * innvl is not used.
+ *
+ * outnvl: {
+ *    holdname -> time added (uint64 seconds since epoch)
+ *    ...
+ * }
+ */
+/* ARGSUSED */
+static int
+zfs_ioc_get_holds(const char *snapname, nvlist_t *args, nvlist_t *outnvl)
+{
+	return (dsl_dataset_get_holds(snapname, outnvl));
+}
+
+/*
+ * innvl: {
+ *     snapname -> { holdname, ... }
+ *     ...
+ * }
+ *
+ * outnvl: {
+ *     snapname -> error value (int32)
+ *     ...
+ * }
+ */
+/* ARGSUSED */
+static int
+zfs_ioc_release(const char *pool, nvlist_t *holds, nvlist_t *errlist)
+{
+	return (dsl_dataset_user_release(holds, errlist));
+}
+
+/*
+ * inputs:
+ * zc_guid		flags (ZEVENT_NONBLOCK)
+ * zc_cleanup_fd	zevent file descriptor
+ *
+ * outputs:
+ * zc_nvlist_dst	next nvlist event
+ * zc_cookie		dropped events since last get
+ */
+static int
+zfs_ioc_events_next(zfs_cmd_t *zc)
+{
+	zfs_zevent_t *ze;
+	nvlist_t *event = NULL;
+	minor_t minor;
+	uint64_t dropped = 0;
+	int error;
+
+	error = zfs_zevent_fd_hold(zc->zc_cleanup_fd, &minor, &ze);
+	if (error != 0)
+		return (error);
+
+	do {
+		error = zfs_zevent_next(ze, &event,
+			&zc->zc_nvlist_dst_size, &dropped);
+		if (event != NULL) {
+			zc->zc_cookie = dropped;
+			error = put_nvlist(zc, event);
+			nvlist_free(event);
+		}
+
+		if (zc->zc_guid & ZEVENT_NONBLOCK)
+			break;
+
+		if ((error == 0) || (error != ENOENT))
+			break;
+
+		error = zfs_zevent_wait(ze);
+		if (error != 0)
+			break;
+	} while (1);
+
+	zfs_zevent_fd_rele(zc->zc_cleanup_fd);
+
+	return (error);
+}
+
+/*
+ * outputs:
+ * zc_cookie		cleared events count
+ */
+static int
+zfs_ioc_events_clear(zfs_cmd_t *zc)
+{
+	int count;
+
+	zfs_zevent_drain_all(&count);
+	zc->zc_cookie = count;
+
+	return (0);
+}
+
+/*
+ * inputs:
+ * zc_guid		eid | ZEVENT_SEEK_START | ZEVENT_SEEK_END
+ * zc_cleanup		zevent file descriptor
+ */
+static int
+zfs_ioc_events_seek(zfs_cmd_t *zc)
+{
+	zfs_zevent_t *ze;
+	minor_t minor;
+	int error;
+
+	error = zfs_zevent_fd_hold(zc->zc_cleanup_fd, &minor, &ze);
+	if (error != 0)
+		return (error);
+
+	error = zfs_zevent_seek(ze, zc->zc_guid);
+	zfs_zevent_fd_rele(zc->zc_cleanup_fd);
+
+	return (error);
+}
+
+/*
+ * inputs:
+ * zc_name		name of new filesystem or snapshot
+ * zc_value		full name of old snapshot
+ *
+ * outputs:
+ * zc_cookie		space in bytes
+ * zc_objset_type	compressed space in bytes
+ * zc_perm_action	uncompressed space in bytes
+ */
+static int
+zfs_ioc_space_written(zfs_cmd_t *zc)
+{
+	int error;
+	dsl_pool_t *dp;
+	dsl_dataset_t *new, *old;
+
+	error = dsl_pool_hold(zc->zc_name, FTAG, &dp);
+	if (error != 0)
+		return (error);
+	error = dsl_dataset_hold(dp, zc->zc_name, FTAG, &new);
+	if (error != 0) {
+		dsl_pool_rele(dp, FTAG);
+		return (error);
+	}
+	error = dsl_dataset_hold(dp, zc->zc_value, FTAG, &old);
+	if (error != 0) {
+		dsl_dataset_rele(new, FTAG);
+		dsl_pool_rele(dp, FTAG);
+		return (error);
+	}
+
+	error = dsl_dataset_space_written(old, new, &zc->zc_cookie,
+	    &zc->zc_objset_type, &zc->zc_perm_action);
+	dsl_dataset_rele(old, FTAG);
+	dsl_dataset_rele(new, FTAG);
+	dsl_pool_rele(dp, FTAG);
+	return (error);
+}
+
+/*
+ * innvl: {
+ *     "firstsnap" -> snapshot name
+ * }
+ *
+ * outnvl: {
+ *     "used" -> space in bytes
+ *     "compressed" -> compressed space in bytes
+ *     "uncompressed" -> uncompressed space in bytes
+ * }
+ */
+static int
+zfs_ioc_space_snaps(const char *lastsnap, nvlist_t *innvl, nvlist_t *outnvl)
+{
+	int error;
+	dsl_pool_t *dp;
+	dsl_dataset_t *new, *old;
+	char *firstsnap;
+	uint64_t used, comp, uncomp;
+
+	if (nvlist_lookup_string(innvl, "firstsnap", &firstsnap) != 0)
+		return (SET_ERROR(EINVAL));
+
+	error = dsl_pool_hold(lastsnap, FTAG, &dp);
+	if (error != 0)
+		return (error);
+
+	error = dsl_dataset_hold(dp, lastsnap, FTAG, &new);
+	if (error == 0 && !new->ds_is_snapshot) {
+		dsl_dataset_rele(new, FTAG);
+		error = SET_ERROR(EINVAL);
+	}
+	if (error != 0) {
+		dsl_pool_rele(dp, FTAG);
+		return (error);
+	}
+	error = dsl_dataset_hold(dp, firstsnap, FTAG, &old);
+	if (error == 0 && !old->ds_is_snapshot) {
+		dsl_dataset_rele(old, FTAG);
+		error = SET_ERROR(EINVAL);
+	}
+	if (error != 0) {
+		dsl_dataset_rele(new, FTAG);
+		dsl_pool_rele(dp, FTAG);
+		return (error);
+	}
+
+	error = dsl_dataset_space_wouldfree(old, new, &used, &comp, &uncomp);
+	dsl_dataset_rele(old, FTAG);
+	dsl_dataset_rele(new, FTAG);
+	dsl_pool_rele(dp, FTAG);
+	fnvlist_add_uint64(outnvl, "used", used);
+	fnvlist_add_uint64(outnvl, "compressed", comp);
+	fnvlist_add_uint64(outnvl, "uncompressed", uncomp);
+	return (error);
+}
+
+/*
+ * innvl: {
+ *     "fd" -> file descriptor to write stream to (int32)
+ *     (optional) "fromsnap" -> full snap name to send an incremental from
+ *     (optional) "largeblockok" -> (value ignored)
+ *         indicates that blocks > 128KB are permitted
+ *     (optional) "embedok" -> (value ignored)
+ *         presence indicates DRR_WRITE_EMBEDDED records are permitted
+ * }
+ *
+ * outnvl is unused
+ */
+/* ARGSUSED */
+static int
+zfs_ioc_send_new(const char *snapname, nvlist_t *innvl, nvlist_t *outnvl)
+{
+	int error;
+	offset_t off;
+	char *fromname = NULL;
+	int fd;
+	file_t *fp;
+	boolean_t largeblockok;
+	boolean_t embedok;
+
+	error = nvlist_lookup_int32(innvl, "fd", &fd);
+	if (error != 0)
+		return (SET_ERROR(EINVAL));
+
+	(void) nvlist_lookup_string(innvl, "fromsnap", &fromname);
+
+	largeblockok = nvlist_exists(innvl, "largeblockok");
+	embedok = nvlist_exists(innvl, "embedok");
+
+	if ((fp = getf(fd)) == NULL)
+		return (SET_ERROR(EBADF));
+
+	off = fp->f_offset;
+	error = dmu_send(snapname, fromname, embedok, largeblockok,
+	    fd, fp->f_vnode, &off);
+
+	if (VOP_SEEK(fp->f_vnode, fp->f_offset, &off, NULL) == 0)
+		fp->f_offset = off;
+
+	releasef(fd);
+	return (error);
+}
+
+/*
+ * Determine approximately how large a zfs send stream will be -- the number
+ * of bytes that will be written to the fd supplied to zfs_ioc_send_new().
+ *
+ * innvl: {
+ *     (optional) "from" -> full snap or bookmark name to send an incremental
+ *                          from
+ * }
+ *
+ * outnvl: {
+ *     "space" -> bytes of space (uint64)
+ * }
+ */
+static int
+zfs_ioc_send_space(const char *snapname, nvlist_t *innvl, nvlist_t *outnvl)
+{
+	dsl_pool_t *dp;
+	dsl_dataset_t *tosnap;
+	int error;
+	char *fromname;
+	uint64_t space;
+
+	error = dsl_pool_hold(snapname, FTAG, &dp);
+	if (error != 0)
+		return (error);
+
+	error = dsl_dataset_hold(dp, snapname, FTAG, &tosnap);
+	if (error != 0) {
+		dsl_pool_rele(dp, FTAG);
+		return (error);
+	}
+
+	error = nvlist_lookup_string(innvl, "from", &fromname);
+	if (error == 0) {
+		if (strchr(fromname, '@') != NULL) {
+			/*
+			 * If from is a snapshot, hold it and use the more
+			 * efficient dmu_send_estimate to estimate send space
+			 * size using deadlists.
+			 */
+			dsl_dataset_t *fromsnap;
+			error = dsl_dataset_hold(dp, fromname, FTAG, &fromsnap);
+			if (error != 0)
+				goto out;
+			error = dmu_send_estimate(tosnap, fromsnap, &space);
+			dsl_dataset_rele(fromsnap, FTAG);
+		} else if (strchr(fromname, '#') != NULL) {
+			/*
+			 * If from is a bookmark, fetch the creation TXG of the
+			 * snapshot it was created from and use that to find
+			 * blocks that were born after it.
+			 */
+			zfs_bookmark_phys_t frombm;
+
+			error = dsl_bookmark_lookup(dp, fromname, tosnap,
+			    &frombm);
+			if (error != 0)
+				goto out;
+			error = dmu_send_estimate_from_txg(tosnap,
+			    frombm.zbm_creation_txg, &space);
+		} else {
+			/*
+			 * from is not properly formatted as a snapshot or
+			 * bookmark
+			 */
+			error = SET_ERROR(EINVAL);
+			goto out;
+		}
+	} else {
+		// If estimating the size of a full send, use dmu_send_estimate
+		error = dmu_send_estimate(tosnap, NULL, &space);
+	}
+
+	fnvlist_add_uint64(outnvl, "space", space);
+
+out:
+	dsl_dataset_rele(tosnap, FTAG);
+	dsl_pool_rele(dp, FTAG);
+	return (error);
+}
+
+static zfs_ioc_vec_t zfs_ioc_vec[ZFS_IOC_LAST - ZFS_IOC_FIRST];
+
+static void
+zfs_ioctl_register_legacy(zfs_ioc_t ioc, zfs_ioc_legacy_func_t *func,
+    zfs_secpolicy_func_t *secpolicy, zfs_ioc_namecheck_t namecheck,
+    boolean_t log_history, zfs_ioc_poolcheck_t pool_check)
+{
+	zfs_ioc_vec_t *vec = &zfs_ioc_vec[ioc - ZFS_IOC_FIRST];
+
+	ASSERT3U(ioc, >=, ZFS_IOC_FIRST);
+	ASSERT3U(ioc, <, ZFS_IOC_LAST);
+	ASSERT3P(vec->zvec_legacy_func, ==, NULL);
+	ASSERT3P(vec->zvec_func, ==, NULL);
+
+	vec->zvec_legacy_func = func;
+	vec->zvec_secpolicy = secpolicy;
+	vec->zvec_namecheck = namecheck;
+	vec->zvec_allow_log = log_history;
+	vec->zvec_pool_check = pool_check;
+}
+
+/*
+ * See the block comment at the beginning of this file for details on
+ * each argument to this function.
+ */
+static void
+zfs_ioctl_register(const char *name, zfs_ioc_t ioc, zfs_ioc_func_t *func,
+    zfs_secpolicy_func_t *secpolicy, zfs_ioc_namecheck_t namecheck,
+    zfs_ioc_poolcheck_t pool_check, boolean_t smush_outnvlist,
+    boolean_t allow_log)
+{
+	zfs_ioc_vec_t *vec = &zfs_ioc_vec[ioc - ZFS_IOC_FIRST];
+
+	ASSERT3U(ioc, >=, ZFS_IOC_FIRST);
+	ASSERT3U(ioc, <, ZFS_IOC_LAST);
+	ASSERT3P(vec->zvec_legacy_func, ==, NULL);
+	ASSERT3P(vec->zvec_func, ==, NULL);
+
+	/* if we are logging, the name must be valid */
+	ASSERT(!allow_log || namecheck != NO_NAME);
+
+	vec->zvec_name = name;
+	vec->zvec_func = func;
+	vec->zvec_secpolicy = secpolicy;
+	vec->zvec_namecheck = namecheck;
+	vec->zvec_pool_check = pool_check;
+	vec->zvec_smush_outnvlist = smush_outnvlist;
+	vec->zvec_allow_log = allow_log;
+}
+
+static void
+zfs_ioctl_register_pool(zfs_ioc_t ioc, zfs_ioc_legacy_func_t *func,
+    zfs_secpolicy_func_t *secpolicy, boolean_t log_history,
+    zfs_ioc_poolcheck_t pool_check)
+{
+	zfs_ioctl_register_legacy(ioc, func, secpolicy,
+	    POOL_NAME, log_history, pool_check);
+}
+
+static void
+zfs_ioctl_register_dataset_nolog(zfs_ioc_t ioc, zfs_ioc_legacy_func_t *func,
+    zfs_secpolicy_func_t *secpolicy, zfs_ioc_poolcheck_t pool_check)
+{
+	zfs_ioctl_register_legacy(ioc, func, secpolicy,
+	    DATASET_NAME, B_FALSE, pool_check);
+}
+
+static void
+zfs_ioctl_register_pool_modify(zfs_ioc_t ioc, zfs_ioc_legacy_func_t *func)
+{
+	zfs_ioctl_register_legacy(ioc, func, zfs_secpolicy_config,
+	    POOL_NAME, B_TRUE, POOL_CHECK_SUSPENDED | POOL_CHECK_READONLY);
+}
+
+static void
+zfs_ioctl_register_pool_meta(zfs_ioc_t ioc, zfs_ioc_legacy_func_t *func,
+    zfs_secpolicy_func_t *secpolicy)
+{
+	zfs_ioctl_register_legacy(ioc, func, secpolicy,
+	    NO_NAME, B_FALSE, POOL_CHECK_NONE);
+}
+
+static void
+zfs_ioctl_register_dataset_read_secpolicy(zfs_ioc_t ioc,
+    zfs_ioc_legacy_func_t *func, zfs_secpolicy_func_t *secpolicy)
+{
+	zfs_ioctl_register_legacy(ioc, func, secpolicy,
+	    DATASET_NAME, B_FALSE, POOL_CHECK_SUSPENDED);
+}
+
+static void
+zfs_ioctl_register_dataset_read(zfs_ioc_t ioc, zfs_ioc_legacy_func_t *func)
+{
+	zfs_ioctl_register_dataset_read_secpolicy(ioc, func,
+	    zfs_secpolicy_read);
+}
+
+static void
+zfs_ioctl_register_dataset_modify(zfs_ioc_t ioc, zfs_ioc_legacy_func_t *func,
+	zfs_secpolicy_func_t *secpolicy)
+{
+	zfs_ioctl_register_legacy(ioc, func, secpolicy,
+	    DATASET_NAME, B_TRUE, POOL_CHECK_SUSPENDED | POOL_CHECK_READONLY);
+}
+
+static void
+zfs_ioctl_init(void)
+{
+	zfs_ioctl_register("snapshot", ZFS_IOC_SNAPSHOT,
+	    zfs_ioc_snapshot, zfs_secpolicy_snapshot, POOL_NAME,
+	    POOL_CHECK_SUSPENDED | POOL_CHECK_READONLY, B_TRUE, B_TRUE);
+
+	zfs_ioctl_register("log_history", ZFS_IOC_LOG_HISTORY,
+	    zfs_ioc_log_history, zfs_secpolicy_log_history, NO_NAME,
+	    POOL_CHECK_SUSPENDED | POOL_CHECK_READONLY, B_FALSE, B_FALSE);
+
+	zfs_ioctl_register("space_snaps", ZFS_IOC_SPACE_SNAPS,
+	    zfs_ioc_space_snaps, zfs_secpolicy_read, DATASET_NAME,
+	    POOL_CHECK_SUSPENDED, B_FALSE, B_FALSE);
+
+	zfs_ioctl_register("send", ZFS_IOC_SEND_NEW,
+	    zfs_ioc_send_new, zfs_secpolicy_send_new, DATASET_NAME,
+	    POOL_CHECK_SUSPENDED, B_FALSE, B_FALSE);
+
+	zfs_ioctl_register("send_space", ZFS_IOC_SEND_SPACE,
+	    zfs_ioc_send_space, zfs_secpolicy_read, DATASET_NAME,
+	    POOL_CHECK_SUSPENDED, B_FALSE, B_FALSE);
+
+	zfs_ioctl_register("create", ZFS_IOC_CREATE,
+	    zfs_ioc_create, zfs_secpolicy_create_clone, DATASET_NAME,
+	    POOL_CHECK_SUSPENDED | POOL_CHECK_READONLY, B_TRUE, B_TRUE);
+
+	zfs_ioctl_register("clone", ZFS_IOC_CLONE,
+	    zfs_ioc_clone, zfs_secpolicy_create_clone, DATASET_NAME,
+	    POOL_CHECK_SUSPENDED | POOL_CHECK_READONLY, B_TRUE, B_TRUE);
+
+	zfs_ioctl_register("destroy_snaps", ZFS_IOC_DESTROY_SNAPS,
+	    zfs_ioc_destroy_snaps, zfs_secpolicy_destroy_snaps, POOL_NAME,
+	    POOL_CHECK_SUSPENDED | POOL_CHECK_READONLY, B_TRUE, B_TRUE);
+
+	zfs_ioctl_register("hold", ZFS_IOC_HOLD,
+	    zfs_ioc_hold, zfs_secpolicy_hold, POOL_NAME,
+	    POOL_CHECK_SUSPENDED | POOL_CHECK_READONLY, B_TRUE, B_TRUE);
+	zfs_ioctl_register("release", ZFS_IOC_RELEASE,
+	    zfs_ioc_release, zfs_secpolicy_release, POOL_NAME,
+	    POOL_CHECK_SUSPENDED | POOL_CHECK_READONLY, B_TRUE, B_TRUE);
+
+	zfs_ioctl_register("get_holds", ZFS_IOC_GET_HOLDS,
+	    zfs_ioc_get_holds, zfs_secpolicy_read, DATASET_NAME,
+	    POOL_CHECK_SUSPENDED, B_FALSE, B_FALSE);
+
+	zfs_ioctl_register("rollback", ZFS_IOC_ROLLBACK,
+	    zfs_ioc_rollback, zfs_secpolicy_rollback, DATASET_NAME,
+	    POOL_CHECK_SUSPENDED | POOL_CHECK_READONLY, B_FALSE, B_TRUE);
+
+	zfs_ioctl_register("bookmark", ZFS_IOC_BOOKMARK,
+	    zfs_ioc_bookmark, zfs_secpolicy_bookmark, POOL_NAME,
+	    POOL_CHECK_SUSPENDED | POOL_CHECK_READONLY, B_TRUE, B_TRUE);
+
+	zfs_ioctl_register("get_bookmarks", ZFS_IOC_GET_BOOKMARKS,
+	    zfs_ioc_get_bookmarks, zfs_secpolicy_read, DATASET_NAME,
+	    POOL_CHECK_SUSPENDED, B_FALSE, B_FALSE);
+
+	zfs_ioctl_register("destroy_bookmarks", ZFS_IOC_DESTROY_BOOKMARKS,
+	    zfs_ioc_destroy_bookmarks, zfs_secpolicy_destroy_bookmarks,
+	    POOL_NAME,
+	    POOL_CHECK_SUSPENDED | POOL_CHECK_READONLY, B_TRUE, B_TRUE);
+
+	/* IOCTLS that use the legacy function signature */
+
+	zfs_ioctl_register_legacy(ZFS_IOC_POOL_FREEZE, zfs_ioc_pool_freeze,
+	    zfs_secpolicy_config, NO_NAME, B_FALSE, POOL_CHECK_READONLY);
+
+	zfs_ioctl_register_pool(ZFS_IOC_POOL_CREATE, zfs_ioc_pool_create,
+	    zfs_secpolicy_config, B_TRUE, POOL_CHECK_NONE);
+	zfs_ioctl_register_pool_modify(ZFS_IOC_POOL_SCAN,
+	    zfs_ioc_pool_scan);
+	zfs_ioctl_register_pool_modify(ZFS_IOC_POOL_UPGRADE,
+	    zfs_ioc_pool_upgrade);
+	zfs_ioctl_register_pool_modify(ZFS_IOC_VDEV_ADD,
+	    zfs_ioc_vdev_add);
+	zfs_ioctl_register_pool_modify(ZFS_IOC_VDEV_REMOVE,
+	    zfs_ioc_vdev_remove);
+	zfs_ioctl_register_pool_modify(ZFS_IOC_VDEV_SET_STATE,
+	    zfs_ioc_vdev_set_state);
+	zfs_ioctl_register_pool_modify(ZFS_IOC_VDEV_ATTACH,
+	    zfs_ioc_vdev_attach);
+	zfs_ioctl_register_pool_modify(ZFS_IOC_VDEV_DETACH,
+	    zfs_ioc_vdev_detach);
+	zfs_ioctl_register_pool_modify(ZFS_IOC_VDEV_SETPATH,
+	    zfs_ioc_vdev_setpath);
+	zfs_ioctl_register_pool_modify(ZFS_IOC_VDEV_SETFRU,
+	    zfs_ioc_vdev_setfru);
+	zfs_ioctl_register_pool_modify(ZFS_IOC_POOL_SET_PROPS,
+	    zfs_ioc_pool_set_props);
+	zfs_ioctl_register_pool_modify(ZFS_IOC_VDEV_SPLIT,
+	    zfs_ioc_vdev_split);
+	zfs_ioctl_register_pool_modify(ZFS_IOC_POOL_REGUID,
+	    zfs_ioc_pool_reguid);
+
+	zfs_ioctl_register_pool_meta(ZFS_IOC_POOL_CONFIGS,
+	    zfs_ioc_pool_configs, zfs_secpolicy_none);
+	zfs_ioctl_register_pool_meta(ZFS_IOC_POOL_TRYIMPORT,
+	    zfs_ioc_pool_tryimport, zfs_secpolicy_config);
+	zfs_ioctl_register_pool_meta(ZFS_IOC_INJECT_FAULT,
+	    zfs_ioc_inject_fault, zfs_secpolicy_inject);
+	zfs_ioctl_register_pool_meta(ZFS_IOC_CLEAR_FAULT,
+	    zfs_ioc_clear_fault, zfs_secpolicy_inject);
+	zfs_ioctl_register_pool_meta(ZFS_IOC_INJECT_LIST_NEXT,
+	    zfs_ioc_inject_list_next, zfs_secpolicy_inject);
+
+	/*
+	 * pool destroy, and export don't log the history as part of
+	 * zfsdev_ioctl, but rather zfs_ioc_pool_export
+	 * does the logging of those commands.
+	 */
+	zfs_ioctl_register_pool(ZFS_IOC_POOL_DESTROY, zfs_ioc_pool_destroy,
+	    zfs_secpolicy_config, B_FALSE, POOL_CHECK_SUSPENDED);
+	zfs_ioctl_register_pool(ZFS_IOC_POOL_EXPORT, zfs_ioc_pool_export,
+	    zfs_secpolicy_config, B_FALSE, POOL_CHECK_SUSPENDED);
+
+	zfs_ioctl_register_pool(ZFS_IOC_POOL_STATS, zfs_ioc_pool_stats,
+	    zfs_secpolicy_read, B_FALSE, POOL_CHECK_NONE);
+	zfs_ioctl_register_pool(ZFS_IOC_POOL_GET_PROPS, zfs_ioc_pool_get_props,
+	    zfs_secpolicy_read, B_FALSE, POOL_CHECK_NONE);
+
+	zfs_ioctl_register_pool(ZFS_IOC_ERROR_LOG, zfs_ioc_error_log,
+	    zfs_secpolicy_inject, B_FALSE, POOL_CHECK_SUSPENDED);
+	zfs_ioctl_register_pool(ZFS_IOC_DSOBJ_TO_DSNAME,
+	    zfs_ioc_dsobj_to_dsname,
+	    zfs_secpolicy_diff, B_FALSE, POOL_CHECK_SUSPENDED);
+	zfs_ioctl_register_pool(ZFS_IOC_POOL_GET_HISTORY,
+	    zfs_ioc_pool_get_history,
+	    zfs_secpolicy_config, B_FALSE, POOL_CHECK_SUSPENDED);
+
+	zfs_ioctl_register_pool(ZFS_IOC_POOL_IMPORT, zfs_ioc_pool_import,
+	    zfs_secpolicy_config, B_TRUE, POOL_CHECK_NONE);
+
+	zfs_ioctl_register_pool(ZFS_IOC_CLEAR, zfs_ioc_clear,
+	    zfs_secpolicy_config, B_TRUE, POOL_CHECK_NONE);
+	zfs_ioctl_register_pool(ZFS_IOC_POOL_REOPEN, zfs_ioc_pool_reopen,
+	    zfs_secpolicy_config, B_TRUE, POOL_CHECK_SUSPENDED);
+
+	zfs_ioctl_register_dataset_read(ZFS_IOC_SPACE_WRITTEN,
+	    zfs_ioc_space_written);
+	zfs_ioctl_register_dataset_read(ZFS_IOC_OBJSET_RECVD_PROPS,
+	    zfs_ioc_objset_recvd_props);
+	zfs_ioctl_register_dataset_read(ZFS_IOC_NEXT_OBJ,
+	    zfs_ioc_next_obj);
+	zfs_ioctl_register_dataset_read(ZFS_IOC_GET_FSACL,
+	    zfs_ioc_get_fsacl);
+	zfs_ioctl_register_dataset_read(ZFS_IOC_OBJSET_STATS,
+	    zfs_ioc_objset_stats);
+	zfs_ioctl_register_dataset_read(ZFS_IOC_OBJSET_ZPLPROPS,
+	    zfs_ioc_objset_zplprops);
+	zfs_ioctl_register_dataset_read(ZFS_IOC_DATASET_LIST_NEXT,
+	    zfs_ioc_dataset_list_next);
+	zfs_ioctl_register_dataset_read(ZFS_IOC_SNAPSHOT_LIST_NEXT,
+	    zfs_ioc_snapshot_list_next);
+	zfs_ioctl_register_dataset_read(ZFS_IOC_SEND_PROGRESS,
+	    zfs_ioc_send_progress);
+
+	zfs_ioctl_register_dataset_read_secpolicy(ZFS_IOC_DIFF,
+	    zfs_ioc_diff, zfs_secpolicy_diff);
+	zfs_ioctl_register_dataset_read_secpolicy(ZFS_IOC_OBJ_TO_STATS,
+	    zfs_ioc_obj_to_stats, zfs_secpolicy_diff);
+	zfs_ioctl_register_dataset_read_secpolicy(ZFS_IOC_OBJ_TO_PATH,
+	    zfs_ioc_obj_to_path, zfs_secpolicy_diff);
+	zfs_ioctl_register_dataset_read_secpolicy(ZFS_IOC_USERSPACE_ONE,
+	    zfs_ioc_userspace_one, zfs_secpolicy_userspace_one);
+	zfs_ioctl_register_dataset_read_secpolicy(ZFS_IOC_USERSPACE_MANY,
+	    zfs_ioc_userspace_many, zfs_secpolicy_userspace_many);
+	zfs_ioctl_register_dataset_read_secpolicy(ZFS_IOC_SEND,
+	    zfs_ioc_send, zfs_secpolicy_send);
+
+	zfs_ioctl_register_dataset_modify(ZFS_IOC_SET_PROP, zfs_ioc_set_prop,
+	    zfs_secpolicy_none);
+	zfs_ioctl_register_dataset_modify(ZFS_IOC_DESTROY, zfs_ioc_destroy,
+	    zfs_secpolicy_destroy);
+	zfs_ioctl_register_dataset_modify(ZFS_IOC_RENAME, zfs_ioc_rename,
+	    zfs_secpolicy_rename);
+	zfs_ioctl_register_dataset_modify(ZFS_IOC_RECV, zfs_ioc_recv,
+	    zfs_secpolicy_recv);
+	zfs_ioctl_register_dataset_modify(ZFS_IOC_PROMOTE, zfs_ioc_promote,
+	    zfs_secpolicy_promote);
+	zfs_ioctl_register_dataset_modify(ZFS_IOC_INHERIT_PROP,
+	    zfs_ioc_inherit_prop, zfs_secpolicy_inherit_prop);
+	zfs_ioctl_register_dataset_modify(ZFS_IOC_SET_FSACL, zfs_ioc_set_fsacl,
+	    zfs_secpolicy_set_fsacl);
+
+	zfs_ioctl_register_dataset_nolog(ZFS_IOC_SHARE, zfs_ioc_share,
+	    zfs_secpolicy_share, POOL_CHECK_NONE);
+	zfs_ioctl_register_dataset_nolog(ZFS_IOC_SMB_ACL, zfs_ioc_smb_acl,
+	    zfs_secpolicy_smb_acl, POOL_CHECK_NONE);
+	zfs_ioctl_register_dataset_nolog(ZFS_IOC_USERSPACE_UPGRADE,
+	    zfs_ioc_userspace_upgrade, zfs_secpolicy_userspace_upgrade,
+	    POOL_CHECK_SUSPENDED | POOL_CHECK_READONLY);
+	zfs_ioctl_register_dataset_nolog(ZFS_IOC_TMP_SNAPSHOT,
+	    zfs_ioc_tmp_snapshot, zfs_secpolicy_tmp_snapshot,
+	    POOL_CHECK_SUSPENDED | POOL_CHECK_READONLY);
+
+	/*
+	 * ZoL functions
+	 */
+	zfs_ioctl_register_legacy(ZFS_IOC_EVENTS_NEXT, zfs_ioc_events_next,
+	    zfs_secpolicy_config, NO_NAME, B_FALSE, POOL_CHECK_NONE);
+	zfs_ioctl_register_legacy(ZFS_IOC_EVENTS_CLEAR, zfs_ioc_events_clear,
+	    zfs_secpolicy_config, NO_NAME, B_FALSE, POOL_CHECK_NONE);
+	zfs_ioctl_register_legacy(ZFS_IOC_EVENTS_SEEK, zfs_ioc_events_seek,
+	    zfs_secpolicy_config, NO_NAME, B_FALSE, POOL_CHECK_NONE);
+}
+
+int
+pool_status_check(const char *name, zfs_ioc_namecheck_t type,
+    zfs_ioc_poolcheck_t check)
+{
+	spa_t *spa;
+	int error;
+
+	ASSERT(type == POOL_NAME || type == DATASET_NAME);
+
+	if (check & POOL_CHECK_NONE)
+		return (0);
+
+	error = spa_open(name, &spa, FTAG);
+	if (error == 0) {
+		if ((check & POOL_CHECK_SUSPENDED) && spa_suspended(spa))
+			error = SET_ERROR(EAGAIN);
+		else if ((check & POOL_CHECK_READONLY) && !spa_writeable(spa))
+			error = SET_ERROR(EROFS);
+		spa_close(spa, FTAG);
+	}
+	return (error);
+}
+
+static void *
+zfsdev_get_state_impl(minor_t minor, enum zfsdev_state_type which)
+{
+	zfsdev_state_t *zs;
+
+	for (zs = zfsdev_state_list; zs != NULL; zs = zs->zs_next) {
+		if (zs->zs_minor == minor) {
+			smp_rmb();
+			switch (which) {
+			case ZST_ONEXIT:
+				return (zs->zs_onexit);
+			case ZST_ZEVENT:
+				return (zs->zs_zevent);
+			case ZST_ALL:
+				return (zs);
+			}
+		}
+	}
+
+	return (NULL);
+}
+
+void *
+zfsdev_get_state(minor_t minor, enum zfsdev_state_type which)
+{
+	void *ptr;
+
+	ptr = zfsdev_get_state_impl(minor, which);
+
+	return (ptr);
+}
+
+int
+zfsdev_getminor(struct file *filp, minor_t *minorp)
+{
+	zfsdev_state_t *zs, *fpd;
+
+	ASSERT(filp != NULL);
+	ASSERT(!MUTEX_HELD(&zfsdev_state_lock));
+
+	fpd = filp->private_data;
+	if (fpd == NULL)
+		return (EBADF);
+
+	mutex_enter(&zfsdev_state_lock);
+
+	for (zs = zfsdev_state_list; zs != NULL; zs = zs->zs_next) {
+
+		if (zs->zs_minor == -1)
+			continue;
+
+		if (fpd == zs) {
+			*minorp = fpd->zs_minor;
+			mutex_exit(&zfsdev_state_lock);
+			return (0);
+		}
+	}
+
+	mutex_exit(&zfsdev_state_lock);
+
+	return (EBADF);
+}
+
+/*
+ * Find a free minor number.  The zfsdev_state_list is expected to
+ * be short since it is only a list of currently open file handles.
+ */
+minor_t
+zfsdev_minor_alloc(void)
+{
+	static minor_t last_minor = 0;
+	minor_t m;
+
+	ASSERT(MUTEX_HELD(&zfsdev_state_lock));
+
+	for (m = last_minor + 1; m != last_minor; m++) {
+		if (m > ZFSDEV_MAX_MINOR)
+			m = 1;
+		if (zfsdev_get_state_impl(m, ZST_ALL) == NULL) {
+			last_minor = m;
+			return (m);
+		}
+	}
+
+	return (0);
+}
+
+static int
+zfsdev_state_init(struct file *filp)
+{
+	zfsdev_state_t *zs, *zsprev = NULL;
+	minor_t minor;
+	boolean_t newzs = B_FALSE;
+
+	ASSERT(MUTEX_HELD(&zfsdev_state_lock));
+
+	minor = zfsdev_minor_alloc();
+	if (minor == 0)
+		return (SET_ERROR(ENXIO));
+
+	for (zs = zfsdev_state_list; zs != NULL; zs = zs->zs_next) {
+		if (zs->zs_minor == -1)
+			break;
+		zsprev = zs;
+	}
+
+	if (!zs) {
+		zs = kmem_zalloc(sizeof (zfsdev_state_t), KM_SLEEP);
+		newzs = B_TRUE;
+	}
+
+	zs->zs_file = filp;
+	filp->private_data = zs;
+
+	zfs_onexit_init((zfs_onexit_t **)&zs->zs_onexit);
+	zfs_zevent_init((zfs_zevent_t **)&zs->zs_zevent);
+
+
+	/*
+	 * In order to provide for lock-free concurrent read access
+	 * to the minor list in zfsdev_get_state_impl(), new entries
+	 * must be completely written before linking them into the
+	 * list whereas existing entries are already linked; the last
+	 * operation must be updating zs_minor (from -1 to the new
+	 * value).
+	 */
+	if (newzs) {
+		zs->zs_minor = minor;
+		smp_wmb();
+		zsprev->zs_next = zs;
+	} else {
+		smp_wmb();
+		zs->zs_minor = minor;
+	}
+
+	return (0);
+}
+
+static int
+zfsdev_state_destroy(struct file *filp)
+{
+	zfsdev_state_t *zs;
+
+	ASSERT(MUTEX_HELD(&zfsdev_state_lock));
+	ASSERT(filp->private_data != NULL);
+
+	zs = filp->private_data;
+	zs->zs_minor = -1;
+	zfs_onexit_destroy(zs->zs_onexit);
+	zfs_zevent_destroy(zs->zs_zevent);
+
+	return (0);
+}
+
+static int
+zfsdev_open(struct inode *ino, struct file *filp)
+{
+	int error;
+
+	mutex_enter(&zfsdev_state_lock);
+	error = zfsdev_state_init(filp);
+	mutex_exit(&zfsdev_state_lock);
+
+	return (-error);
+}
+
+static int
+zfsdev_release(struct inode *ino, struct file *filp)
+{
+	int error;
+
+	mutex_enter(&zfsdev_state_lock);
+	error = zfsdev_state_destroy(filp);
+	mutex_exit(&zfsdev_state_lock);
+
+	return (-error);
+}
+
+static long
+zfsdev_ioctl(struct file *filp, unsigned cmd, unsigned long arg)
+{
+	zfs_cmd_t *zc;
+	uint_t vecnum;
+	int error, rc, flag = 0;
+	const zfs_ioc_vec_t *vec;
+	char *saved_poolname = NULL;
+	nvlist_t *innvl = NULL;
+	fstrans_cookie_t cookie;
+
+	vecnum = cmd - ZFS_IOC_FIRST;
+	if (vecnum >= sizeof (zfs_ioc_vec) / sizeof (zfs_ioc_vec[0]))
+		return (-SET_ERROR(EINVAL));
+	vec = &zfs_ioc_vec[vecnum];
+
+	/*
+	 * The registered ioctl list may be sparse, verify that either
+	 * a normal or legacy handler are registered.
+	 */
+	if (vec->zvec_func == NULL && vec->zvec_legacy_func == NULL)
+		return (-SET_ERROR(EINVAL));
+
+	zc = kmem_zalloc(sizeof (zfs_cmd_t), KM_SLEEP);
+
+	error = ddi_copyin((void *)arg, zc, sizeof (zfs_cmd_t), flag);
+	if (error != 0) {
+		error = SET_ERROR(EFAULT);
+		goto out;
+	}
+
+	zc->zc_iflags = flag & FKIOCTL;
+	if (zc->zc_nvlist_src_size != 0) {
+		error = get_nvlist(zc->zc_nvlist_src, zc->zc_nvlist_src_size,
+		    zc->zc_iflags, &innvl);
+		if (error != 0)
+			goto out;
+	}
+
+	/*
+	 * Ensure that all pool/dataset names are valid before we pass down to
+	 * the lower layers.
+	 */
+	zc->zc_name[sizeof (zc->zc_name) - 1] = '\0';
+	switch (vec->zvec_namecheck) {
+	case POOL_NAME:
+		if (pool_namecheck(zc->zc_name, NULL, NULL) != 0)
+			error = SET_ERROR(EINVAL);
+		else
+			error = pool_status_check(zc->zc_name,
+			    vec->zvec_namecheck, vec->zvec_pool_check);
+		break;
+
+	case DATASET_NAME:
+		if (dataset_namecheck(zc->zc_name, NULL, NULL) != 0)
+			error = SET_ERROR(EINVAL);
+		else
+			error = pool_status_check(zc->zc_name,
+			    vec->zvec_namecheck, vec->zvec_pool_check);
+		break;
+
+	case NO_NAME:
+		break;
+	}
+
+
+	if (error == 0 && !(flag & FKIOCTL)) {
+		cookie = spl_fstrans_mark();
+		error = vec->zvec_secpolicy(zc, innvl, CRED());
+		spl_fstrans_unmark(cookie);
+	}
+
+	if (error != 0)
+		goto out;
+
+	/* legacy ioctls can modify zc_name */
+	saved_poolname = strdup(zc->zc_name);
+	if (saved_poolname == NULL) {
+		error = SET_ERROR(ENOMEM);
+		goto out;
+	} else {
+		saved_poolname[strcspn(saved_poolname, "/@#")] = '\0';
+	}
+
+	if (vec->zvec_func != NULL) {
+		nvlist_t *outnvl;
+		int puterror = 0;
+		spa_t *spa;
+		nvlist_t *lognv = NULL;
+
+		ASSERT(vec->zvec_legacy_func == NULL);
+
+		/*
+		 * Add the innvl to the lognv before calling the func,
+		 * in case the func changes the innvl.
+		 */
+		if (vec->zvec_allow_log) {
+			lognv = fnvlist_alloc();
+			fnvlist_add_string(lognv, ZPOOL_HIST_IOCTL,
+			    vec->zvec_name);
+			if (!nvlist_empty(innvl)) {
+				fnvlist_add_nvlist(lognv, ZPOOL_HIST_INPUT_NVL,
+				    innvl);
+			}
+		}
+
+		outnvl = fnvlist_alloc();
+		cookie = spl_fstrans_mark();
+		error = vec->zvec_func(zc->zc_name, innvl, outnvl);
+		spl_fstrans_unmark(cookie);
+
+		if (error == 0 && vec->zvec_allow_log &&
+		    spa_open(zc->zc_name, &spa, FTAG) == 0) {
+			if (!nvlist_empty(outnvl)) {
+				fnvlist_add_nvlist(lognv, ZPOOL_HIST_OUTPUT_NVL,
+				    outnvl);
+			}
+			(void) spa_history_log_nvl(spa, lognv);
+			spa_close(spa, FTAG);
+		}
+		fnvlist_free(lognv);
+
+		if (!nvlist_empty(outnvl) || zc->zc_nvlist_dst_size != 0) {
+			int smusherror = 0;
+			if (vec->zvec_smush_outnvlist) {
+				smusherror = nvlist_smush(outnvl,
+				    zc->zc_nvlist_dst_size);
+			}
+			if (smusherror == 0)
+				puterror = put_nvlist(zc, outnvl);
+		}
+
+		if (puterror != 0)
+			error = puterror;
+
+		nvlist_free(outnvl);
+	} else {
+		cookie = spl_fstrans_mark();
+		error = vec->zvec_legacy_func(zc);
+		spl_fstrans_unmark(cookie);
+	}
+
+out:
+	nvlist_free(innvl);
+	rc = ddi_copyout(zc, (void *)arg, sizeof (zfs_cmd_t), flag);
+	if (error == 0 && rc != 0)
+		error = SET_ERROR(EFAULT);
+	if (error == 0 && vec->zvec_allow_log) {
+		char *s = tsd_get(zfs_allow_log_key);
+		if (s != NULL)
+			strfree(s);
+		(void) tsd_set(zfs_allow_log_key, saved_poolname);
+	} else {
+		if (saved_poolname != NULL)
+			strfree(saved_poolname);
+	}
+
+	kmem_free(zc, sizeof (zfs_cmd_t));
+	return (-error);
+}
+
+#ifdef CONFIG_COMPAT
+static long
+zfsdev_compat_ioctl(struct file *filp, unsigned cmd, unsigned long arg)
+{
+	return (zfsdev_ioctl(filp, cmd, arg));
+}
+#else
+#define	zfsdev_compat_ioctl	NULL
+#endif
+
+static const struct file_operations zfsdev_fops = {
+	.open		= zfsdev_open,
+	.release	= zfsdev_release,
+	.unlocked_ioctl	= zfsdev_ioctl,
+	.compat_ioctl	= zfsdev_compat_ioctl,
+	.owner		= THIS_MODULE,
+};
+
+static struct miscdevice zfs_misc = {
+	.minor		= MISC_DYNAMIC_MINOR,
+	.name		= ZFS_DRIVER,
+	.fops		= &zfsdev_fops,
+};
+
+static int
+zfs_attach(void)
+{
+	int error;
+
+	mutex_init(&zfsdev_state_lock, NULL, MUTEX_DEFAULT, NULL);
+	zfsdev_state_list = kmem_zalloc(sizeof (zfsdev_state_t), KM_SLEEP);
+	zfsdev_state_list->zs_minor = -1;
+
+	error = misc_register(&zfs_misc);
+	if (error != 0) {
+		printk(KERN_INFO "ZFS: misc_register() failed %d\n", error);
+		return (error);
+	}
+
+	return (0);
+}
+
+static void
+zfs_detach(void)
+{
+	zfsdev_state_t *zs, *zsprev = NULL;
+
+	misc_deregister(&zfs_misc);
+	mutex_destroy(&zfsdev_state_lock);
+
+	for (zs = zfsdev_state_list; zs != NULL; zs = zs->zs_next) {
+		if (zsprev)
+			kmem_free(zsprev, sizeof (zfsdev_state_t));
+		zsprev = zs;
+	}
+	if (zsprev)
+		kmem_free(zsprev, sizeof (zfsdev_state_t));
+}
+
+static void
+zfs_allow_log_destroy(void *arg)
+{
+	char *poolname = arg;
+	strfree(poolname);
+}
+
+#ifdef DEBUG
+#define	ZFS_DEBUG_STR	" (DEBUG mode)"
+#else
+#define	ZFS_DEBUG_STR	""
+#endif
+
+static int __init
+_init(void)
+{
+	int error;
+
+	error = -vn_set_pwd("/");
+	if (error) {
+		printk(KERN_NOTICE
+		    "ZFS: Warning unable to set pwd to '/': %d\n", error);
+		return (error);
+	}
+
+	if ((error = -zvol_init()) != 0)
+		return (error);
+
+	spa_init(FREAD | FWRITE);
+	zfs_init();
+
+	zfs_ioctl_init();
+
+	if ((error = zfs_attach()) != 0)
+		goto out;
+
+	tsd_create(&zfs_fsyncer_key, NULL);
+	tsd_create(&rrw_tsd_key, rrw_tsd_destroy);
+	tsd_create(&zfs_allow_log_key, zfs_allow_log_destroy);
+
+	printk(KERN_NOTICE "ZFS: Loaded module v%s-%s%s, "
+	    "ZFS pool version %s, ZFS filesystem version %s\n",
+	    ZFS_META_VERSION, ZFS_META_RELEASE, ZFS_DEBUG_STR,
+	    SPA_VERSION_STRING, ZPL_VERSION_STRING);
+#ifndef CONFIG_FS_POSIX_ACL
+	printk(KERN_NOTICE "ZFS: Posix ACLs disabled by kernel\n");
+#endif /* CONFIG_FS_POSIX_ACL */
+
+	return (0);
+
+out:
+	zfs_fini();
+	spa_fini();
+	(void) zvol_fini();
+	printk(KERN_NOTICE "ZFS: Failed to Load ZFS Filesystem v%s-%s%s"
+	    ", rc = %d\n", ZFS_META_VERSION, ZFS_META_RELEASE,
+	    ZFS_DEBUG_STR, error);
+
+	return (error);
+}
+
+static void __exit
+_fini(void)
+{
+	zfs_detach();
+	zfs_fini();
+	spa_fini();
+	zvol_fini();
+
+	tsd_destroy(&zfs_fsyncer_key);
+	tsd_destroy(&rrw_tsd_key);
+	tsd_destroy(&zfs_allow_log_key);
+
+	printk(KERN_NOTICE "ZFS: Unloaded module v%s-%s%s\n",
+	    ZFS_META_VERSION, ZFS_META_RELEASE, ZFS_DEBUG_STR);
+}
+
+#ifdef HAVE_SPL
+module_init(_init);
+module_exit(_fini);
+
+MODULE_DESCRIPTION("ZFS");
+MODULE_AUTHOR(ZFS_META_AUTHOR);
+MODULE_LICENSE(ZFS_META_LICENSE);
+MODULE_VERSION(ZFS_META_VERSION "-" ZFS_META_RELEASE);
+#endif /* HAVE_SPL */
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/module/zfs/zfs_log.c
@@ -0,0 +1,688 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ */
+
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/sysmacros.h>
+#include <sys/cmn_err.h>
+#include <sys/kmem.h>
+#include <sys/thread.h>
+#include <sys/file.h>
+#include <sys/vfs.h>
+#include <sys/zfs_znode.h>
+#include <sys/zfs_dir.h>
+#include <sys/zil.h>
+#include <sys/zil_impl.h>
+#include <sys/byteorder.h>
+#include <sys/policy.h>
+#include <sys/stat.h>
+#include <sys/mode.h>
+#include <sys/acl.h>
+#include <sys/dmu.h>
+#include <sys/spa.h>
+#include <sys/zfs_fuid.h>
+#include <sys/ddi.h>
+#include <sys/dsl_dataset.h>
+
+/*
+ * These zfs_log_* functions must be called within a dmu tx, in one
+ * of 2 contexts depending on zilog->z_replay:
+ *
+ * Non replay mode
+ * ---------------
+ * We need to record the transaction so that if it is committed to
+ * the Intent Log then it can be replayed.  An intent log transaction
+ * structure (itx_t) is allocated and all the information necessary to
+ * possibly replay the transaction is saved in it. The itx is then assigned
+ * a sequence number and inserted in the in-memory list anchored in the zilog.
+ *
+ * Replay mode
+ * -----------
+ * We need to mark the intent log record as replayed in the log header.
+ * This is done in the same transaction as the replay so that they
+ * commit atomically.
+ */
+
+int
+zfs_log_create_txtype(zil_create_t type, vsecattr_t *vsecp, vattr_t *vap)
+{
+	int isxvattr = (vap->va_mask & ATTR_XVATTR);
+	switch (type) {
+	case Z_FILE:
+		if (vsecp == NULL && !isxvattr)
+			return (TX_CREATE);
+		if (vsecp && isxvattr)
+			return (TX_CREATE_ACL_ATTR);
+		if (vsecp)
+			return (TX_CREATE_ACL);
+		else
+			return (TX_CREATE_ATTR);
+		/*NOTREACHED*/
+	case Z_DIR:
+		if (vsecp == NULL && !isxvattr)
+			return (TX_MKDIR);
+		if (vsecp && isxvattr)
+			return (TX_MKDIR_ACL_ATTR);
+		if (vsecp)
+			return (TX_MKDIR_ACL);
+		else
+			return (TX_MKDIR_ATTR);
+	case Z_XATTRDIR:
+		return (TX_MKXATTR);
+	}
+	ASSERT(0);
+	return (TX_MAX_TYPE);
+}
+
+/*
+ * build up the log data necessary for logging xvattr_t
+ * First lr_attr_t is initialized.  following the lr_attr_t
+ * is the mapsize and attribute bitmap copied from the xvattr_t.
+ * Following the bitmap and bitmapsize two 64 bit words are reserved
+ * for the create time which may be set.  Following the create time
+ * records a single 64 bit integer which has the bits to set on
+ * replay for the xvattr.
+ */
+static void
+zfs_log_xvattr(lr_attr_t *lrattr, xvattr_t *xvap)
+{
+	uint32_t	*bitmap;
+	uint64_t	*attrs;
+	uint64_t	*crtime;
+	xoptattr_t	*xoap;
+	void		*scanstamp;
+	int		i;
+
+	xoap = xva_getxoptattr(xvap);
+	ASSERT(xoap);
+
+	lrattr->lr_attr_masksize = xvap->xva_mapsize;
+	bitmap = &lrattr->lr_attr_bitmap;
+	for (i = 0; i != xvap->xva_mapsize; i++, bitmap++) {
+		*bitmap = xvap->xva_reqattrmap[i];
+	}
+
+	/* Now pack the attributes up in a single uint64_t */
+	attrs = (uint64_t *)bitmap;
+	crtime = attrs + 1;
+	scanstamp = (caddr_t)(crtime + 2);
+	*attrs = 0;
+	if (XVA_ISSET_REQ(xvap, XAT_READONLY))
+		*attrs |= (xoap->xoa_readonly == 0) ? 0 :
+		    XAT0_READONLY;
+	if (XVA_ISSET_REQ(xvap, XAT_HIDDEN))
+		*attrs |= (xoap->xoa_hidden == 0) ? 0 :
+		    XAT0_HIDDEN;
+	if (XVA_ISSET_REQ(xvap, XAT_SYSTEM))
+		*attrs |= (xoap->xoa_system == 0) ? 0 :
+		    XAT0_SYSTEM;
+	if (XVA_ISSET_REQ(xvap, XAT_ARCHIVE))
+		*attrs |= (xoap->xoa_archive == 0) ? 0 :
+		    XAT0_ARCHIVE;
+	if (XVA_ISSET_REQ(xvap, XAT_IMMUTABLE))
+		*attrs |= (xoap->xoa_immutable == 0) ? 0 :
+		    XAT0_IMMUTABLE;
+	if (XVA_ISSET_REQ(xvap, XAT_NOUNLINK))
+		*attrs |= (xoap->xoa_nounlink == 0) ? 0 :
+		    XAT0_NOUNLINK;
+	if (XVA_ISSET_REQ(xvap, XAT_APPENDONLY))
+		*attrs |= (xoap->xoa_appendonly == 0) ? 0 :
+		    XAT0_APPENDONLY;
+	if (XVA_ISSET_REQ(xvap, XAT_OPAQUE))
+		*attrs |= (xoap->xoa_opaque == 0) ? 0 :
+		    XAT0_APPENDONLY;
+	if (XVA_ISSET_REQ(xvap, XAT_NODUMP))
+		*attrs |= (xoap->xoa_nodump == 0) ? 0 :
+		    XAT0_NODUMP;
+	if (XVA_ISSET_REQ(xvap, XAT_AV_QUARANTINED))
+		*attrs |= (xoap->xoa_av_quarantined == 0) ? 0 :
+		    XAT0_AV_QUARANTINED;
+	if (XVA_ISSET_REQ(xvap, XAT_AV_MODIFIED))
+		*attrs |= (xoap->xoa_av_modified == 0) ? 0 :
+		    XAT0_AV_MODIFIED;
+	if (XVA_ISSET_REQ(xvap, XAT_CREATETIME))
+		ZFS_TIME_ENCODE(&xoap->xoa_createtime, crtime);
+	if (XVA_ISSET_REQ(xvap, XAT_AV_SCANSTAMP))
+		bcopy(xoap->xoa_av_scanstamp, scanstamp, AV_SCANSTAMP_SZ);
+	if (XVA_ISSET_REQ(xvap, XAT_REPARSE))
+		*attrs |= (xoap->xoa_reparse == 0) ? 0 :
+		    XAT0_REPARSE;
+	if (XVA_ISSET_REQ(xvap, XAT_OFFLINE))
+		*attrs |= (xoap->xoa_offline == 0) ? 0 :
+		    XAT0_OFFLINE;
+	if (XVA_ISSET_REQ(xvap, XAT_SPARSE))
+		*attrs |= (xoap->xoa_sparse == 0) ? 0 :
+		    XAT0_SPARSE;
+}
+
+static void *
+zfs_log_fuid_ids(zfs_fuid_info_t *fuidp, void *start)
+{
+	zfs_fuid_t *zfuid;
+	uint64_t *fuidloc = start;
+
+	/* First copy in the ACE FUIDs */
+	for (zfuid = list_head(&fuidp->z_fuids); zfuid;
+	    zfuid = list_next(&fuidp->z_fuids, zfuid)) {
+		*fuidloc++ = zfuid->z_logfuid;
+	}
+	return (fuidloc);
+}
+
+
+static void *
+zfs_log_fuid_domains(zfs_fuid_info_t *fuidp, void *start)
+{
+	zfs_fuid_domain_t *zdomain;
+
+	/* now copy in the domain info, if any */
+	if (fuidp->z_domain_str_sz != 0) {
+		for (zdomain = list_head(&fuidp->z_domains); zdomain;
+		    zdomain = list_next(&fuidp->z_domains, zdomain)) {
+			bcopy((void *)zdomain->z_domain, start,
+			    strlen(zdomain->z_domain) + 1);
+			start = (caddr_t)start +
+			    strlen(zdomain->z_domain) + 1;
+		}
+	}
+	return (start);
+}
+
+/*
+ * Handles TX_CREATE, TX_CREATE_ATTR, TX_MKDIR, TX_MKDIR_ATTR and
+ * TK_MKXATTR transactions.
+ *
+ * TX_CREATE and TX_MKDIR are standard creates, but they may have FUID
+ * domain information appended prior to the name.  In this case the
+ * uid/gid in the log record will be a log centric FUID.
+ *
+ * TX_CREATE_ACL_ATTR and TX_MKDIR_ACL_ATTR handle special creates that
+ * may contain attributes, ACL and optional fuid information.
+ *
+ * TX_CREATE_ACL and TX_MKDIR_ACL handle special creates that specify
+ * and ACL and normal users/groups in the ACEs.
+ *
+ * There may be an optional xvattr attribute information similar
+ * to zfs_log_setattr.
+ *
+ * Also, after the file name "domain" strings may be appended.
+ */
+void
+zfs_log_create(zilog_t *zilog, dmu_tx_t *tx, uint64_t txtype,
+    znode_t *dzp, znode_t *zp, char *name, vsecattr_t *vsecp,
+    zfs_fuid_info_t *fuidp, vattr_t *vap)
+{
+	itx_t *itx;
+	lr_create_t *lr;
+	lr_acl_create_t *lracl;
+	size_t aclsize = 0;
+	size_t xvatsize = 0;
+	size_t txsize;
+	xvattr_t *xvap = (xvattr_t *)vap;
+	void *end;
+	size_t lrsize;
+	size_t namesize = strlen(name) + 1;
+	size_t fuidsz = 0;
+
+	if (zil_replaying(zilog, tx))
+		return;
+
+	/*
+	 * If we have FUIDs present then add in space for
+	 * domains and ACE fuid's if any.
+	 */
+	if (fuidp) {
+		fuidsz += fuidp->z_domain_str_sz;
+		fuidsz += fuidp->z_fuid_cnt * sizeof (uint64_t);
+	}
+
+	if (vap->va_mask & ATTR_XVATTR)
+		xvatsize = ZIL_XVAT_SIZE(xvap->xva_mapsize);
+
+	if ((int)txtype == TX_CREATE_ATTR || (int)txtype == TX_MKDIR_ATTR ||
+	    (int)txtype == TX_CREATE || (int)txtype == TX_MKDIR ||
+	    (int)txtype == TX_MKXATTR) {
+		txsize = sizeof (*lr) + namesize + fuidsz + xvatsize;
+		lrsize = sizeof (*lr);
+	} else {
+		txsize =
+		    sizeof (lr_acl_create_t) + namesize + fuidsz +
+		    ZIL_ACE_LENGTH(aclsize) + xvatsize;
+		lrsize = sizeof (lr_acl_create_t);
+	}
+
+	itx = zil_itx_create(txtype, txsize);
+
+	lr = (lr_create_t *)&itx->itx_lr;
+	lr->lr_doid = dzp->z_id;
+	lr->lr_foid = zp->z_id;
+	lr->lr_mode = zp->z_mode;
+	if (!IS_EPHEMERAL(zp->z_uid)) {
+		lr->lr_uid = (uint64_t)zp->z_uid;
+	} else {
+		lr->lr_uid = fuidp->z_fuid_owner;
+	}
+	if (!IS_EPHEMERAL(zp->z_gid)) {
+		lr->lr_gid = (uint64_t)zp->z_gid;
+	} else {
+		lr->lr_gid = fuidp->z_fuid_group;
+	}
+	(void) sa_lookup(zp->z_sa_hdl, SA_ZPL_GEN(ZTOZSB(zp)), &lr->lr_gen,
+	    sizeof (uint64_t));
+	(void) sa_lookup(zp->z_sa_hdl, SA_ZPL_CRTIME(ZTOZSB(zp)),
+	    lr->lr_crtime, sizeof (uint64_t) * 2);
+
+	if (sa_lookup(zp->z_sa_hdl, SA_ZPL_RDEV(ZTOZSB(zp)), &lr->lr_rdev,
+	    sizeof (lr->lr_rdev)) != 0)
+		lr->lr_rdev = 0;
+
+	/*
+	 * Fill in xvattr info if any
+	 */
+	if (vap->va_mask & ATTR_XVATTR) {
+		zfs_log_xvattr((lr_attr_t *)((caddr_t)lr + lrsize), xvap);
+		end = (caddr_t)lr + lrsize + xvatsize;
+	} else {
+		end = (caddr_t)lr + lrsize;
+	}
+
+	/* Now fill in any ACL info */
+
+	if (vsecp) {
+		lracl = (lr_acl_create_t *)&itx->itx_lr;
+		lracl->lr_aclcnt = vsecp->vsa_aclcnt;
+		lracl->lr_acl_bytes = aclsize;
+		lracl->lr_domcnt = fuidp ? fuidp->z_domain_cnt : 0;
+		lracl->lr_fuidcnt  = fuidp ? fuidp->z_fuid_cnt : 0;
+		if (vsecp->vsa_aclflags & VSA_ACE_ACLFLAGS)
+			lracl->lr_acl_flags = (uint64_t)vsecp->vsa_aclflags;
+		else
+			lracl->lr_acl_flags = 0;
+
+		bcopy(vsecp->vsa_aclentp, end, aclsize);
+		end = (caddr_t)end + ZIL_ACE_LENGTH(aclsize);
+	}
+
+	/* drop in FUID info */
+	if (fuidp) {
+		end = zfs_log_fuid_ids(fuidp, end);
+		end = zfs_log_fuid_domains(fuidp, end);
+	}
+	/*
+	 * Now place file name in log record
+	 */
+	bcopy(name, end, namesize);
+
+	zil_itx_assign(zilog, itx, tx);
+}
+
+/*
+ * Handles both TX_REMOVE and TX_RMDIR transactions.
+ */
+void
+zfs_log_remove(zilog_t *zilog, dmu_tx_t *tx, uint64_t txtype,
+	znode_t *dzp, char *name, uint64_t foid)
+{
+	itx_t *itx;
+	lr_remove_t *lr;
+	size_t namesize = strlen(name) + 1;
+
+	if (zil_replaying(zilog, tx))
+		return;
+
+	itx = zil_itx_create(txtype, sizeof (*lr) + namesize);
+	lr = (lr_remove_t *)&itx->itx_lr;
+	lr->lr_doid = dzp->z_id;
+	bcopy(name, (char *)(lr + 1), namesize);
+
+	itx->itx_oid = foid;
+
+	zil_itx_assign(zilog, itx, tx);
+}
+
+/*
+ * Handles TX_LINK transactions.
+ */
+void
+zfs_log_link(zilog_t *zilog, dmu_tx_t *tx, uint64_t txtype,
+	znode_t *dzp, znode_t *zp, char *name)
+{
+	itx_t *itx;
+	lr_link_t *lr;
+	size_t namesize = strlen(name) + 1;
+
+	if (zil_replaying(zilog, tx))
+		return;
+
+	itx = zil_itx_create(txtype, sizeof (*lr) + namesize);
+	lr = (lr_link_t *)&itx->itx_lr;
+	lr->lr_doid = dzp->z_id;
+	lr->lr_link_obj = zp->z_id;
+	bcopy(name, (char *)(lr + 1), namesize);
+
+	zil_itx_assign(zilog, itx, tx);
+}
+
+/*
+ * Handles TX_SYMLINK transactions.
+ */
+void
+zfs_log_symlink(zilog_t *zilog, dmu_tx_t *tx, uint64_t txtype,
+    znode_t *dzp, znode_t *zp, char *name, char *link)
+{
+	itx_t *itx;
+	lr_create_t *lr;
+	size_t namesize = strlen(name) + 1;
+	size_t linksize = strlen(link) + 1;
+
+	if (zil_replaying(zilog, tx))
+		return;
+
+	itx = zil_itx_create(txtype, sizeof (*lr) + namesize + linksize);
+	lr = (lr_create_t *)&itx->itx_lr;
+	lr->lr_doid = dzp->z_id;
+	lr->lr_foid = zp->z_id;
+	lr->lr_uid = zp->z_uid;
+	lr->lr_gid = zp->z_gid;
+	lr->lr_mode = zp->z_mode;
+	(void) sa_lookup(zp->z_sa_hdl, SA_ZPL_GEN(ZTOZSB(zp)), &lr->lr_gen,
+	    sizeof (uint64_t));
+	(void) sa_lookup(zp->z_sa_hdl, SA_ZPL_CRTIME(ZTOZSB(zp)),
+	    lr->lr_crtime, sizeof (uint64_t) * 2);
+	bcopy(name, (char *)(lr + 1), namesize);
+	bcopy(link, (char *)(lr + 1) + namesize, linksize);
+
+	zil_itx_assign(zilog, itx, tx);
+}
+
+/*
+ * Handles TX_RENAME transactions.
+ */
+void
+zfs_log_rename(zilog_t *zilog, dmu_tx_t *tx, uint64_t txtype,
+	znode_t *sdzp, char *sname, znode_t *tdzp, char *dname, znode_t *szp)
+{
+	itx_t *itx;
+	lr_rename_t *lr;
+	size_t snamesize = strlen(sname) + 1;
+	size_t dnamesize = strlen(dname) + 1;
+
+	if (zil_replaying(zilog, tx))
+		return;
+
+	itx = zil_itx_create(txtype, sizeof (*lr) + snamesize + dnamesize);
+	lr = (lr_rename_t *)&itx->itx_lr;
+	lr->lr_sdoid = sdzp->z_id;
+	lr->lr_tdoid = tdzp->z_id;
+	bcopy(sname, (char *)(lr + 1), snamesize);
+	bcopy(dname, (char *)(lr + 1) + snamesize, dnamesize);
+	itx->itx_oid = szp->z_id;
+
+	zil_itx_assign(zilog, itx, tx);
+}
+
+/*
+ * zfs_log_write() handles TX_WRITE transactions. The specified callback is
+ * called as soon as the write is on stable storage (be it via a DMU sync or a
+ * ZIL commit).
+ */
+long zfs_immediate_write_sz = 32768;
+
+void
+zfs_log_write(zilog_t *zilog, dmu_tx_t *tx, int txtype,
+	znode_t *zp, offset_t off, ssize_t resid, int ioflag,
+	zil_callback_t callback, void *callback_data)
+{
+	itx_wr_state_t write_state;
+	boolean_t slogging;
+	uintptr_t fsync_cnt;
+	ssize_t immediate_write_sz;
+
+	if (zil_replaying(zilog, tx) || zp->z_unlinked) {
+		if (callback != NULL)
+			callback(callback_data);
+		return;
+	}
+
+	immediate_write_sz = (zilog->zl_logbias == ZFS_LOGBIAS_THROUGHPUT)
+	    ? 0 : (ssize_t)zfs_immediate_write_sz;
+
+	slogging = spa_has_slogs(zilog->zl_spa) &&
+	    (zilog->zl_logbias == ZFS_LOGBIAS_LATENCY);
+	if (resid > immediate_write_sz && !slogging && resid <= zp->z_blksz)
+		write_state = WR_INDIRECT;
+	else if (ioflag & (FSYNC | FDSYNC))
+		write_state = WR_COPIED;
+	else
+		write_state = WR_NEED_COPY;
+
+	if ((fsync_cnt = (uintptr_t)tsd_get(zfs_fsyncer_key)) != 0) {
+		(void) tsd_set(zfs_fsyncer_key, (void *)(fsync_cnt - 1));
+	}
+
+	while (resid) {
+		itx_t *itx;
+		lr_write_t *lr;
+		ssize_t len;
+
+		/*
+		 * If the write would overflow the largest block then split it.
+		 */
+		if (write_state != WR_INDIRECT && resid > ZIL_MAX_LOG_DATA)
+			len = SPA_OLD_MAXBLOCKSIZE >> 1;
+		else
+			len = resid;
+
+		itx = zil_itx_create(txtype, sizeof (*lr) +
+		    (write_state == WR_COPIED ? len : 0));
+		lr = (lr_write_t *)&itx->itx_lr;
+		if (write_state == WR_COPIED && dmu_read(ZTOZSB(zp)->z_os,
+		    zp->z_id, off, len, lr + 1, DMU_READ_NO_PREFETCH) != 0) {
+			zil_itx_destroy(itx);
+			itx = zil_itx_create(txtype, sizeof (*lr));
+			lr = (lr_write_t *)&itx->itx_lr;
+			write_state = WR_NEED_COPY;
+		}
+
+		itx->itx_wr_state = write_state;
+		if (write_state == WR_NEED_COPY)
+			itx->itx_sod += len;
+		lr->lr_foid = zp->z_id;
+		lr->lr_offset = off;
+		lr->lr_length = len;
+		lr->lr_blkoff = 0;
+		BP_ZERO(&lr->lr_blkptr);
+
+		itx->itx_private = ZTOZSB(zp);
+
+		if (!(ioflag & (FSYNC | FDSYNC)) && (zp->z_sync_cnt == 0) &&
+		    (fsync_cnt == 0))
+			itx->itx_sync = B_FALSE;
+
+		itx->itx_callback = callback;
+		itx->itx_callback_data = callback_data;
+		zil_itx_assign(zilog, itx, tx);
+
+		off += len;
+		resid -= len;
+	}
+}
+
+/*
+ * Handles TX_TRUNCATE transactions.
+ */
+void
+zfs_log_truncate(zilog_t *zilog, dmu_tx_t *tx, int txtype,
+	znode_t *zp, uint64_t off, uint64_t len)
+{
+	itx_t *itx;
+	lr_truncate_t *lr;
+
+	if (zil_replaying(zilog, tx) || zp->z_unlinked)
+		return;
+
+	itx = zil_itx_create(txtype, sizeof (*lr));
+	lr = (lr_truncate_t *)&itx->itx_lr;
+	lr->lr_foid = zp->z_id;
+	lr->lr_offset = off;
+	lr->lr_length = len;
+
+	itx->itx_sync = (zp->z_sync_cnt != 0);
+	zil_itx_assign(zilog, itx, tx);
+}
+
+/*
+ * Handles TX_SETATTR transactions.
+ */
+void
+zfs_log_setattr(zilog_t *zilog, dmu_tx_t *tx, int txtype,
+    znode_t *zp, vattr_t *vap, uint_t mask_applied, zfs_fuid_info_t *fuidp)
+{
+	itx_t		*itx;
+	lr_setattr_t	*lr;
+	xvattr_t	*xvap = (xvattr_t *)vap;
+	size_t		recsize = sizeof (lr_setattr_t);
+	void		*start;
+
+	if (zil_replaying(zilog, tx) || zp->z_unlinked)
+		return;
+
+	/*
+	 * If XVATTR set, then log record size needs to allow
+	 * for lr_attr_t + xvattr mask, mapsize and create time
+	 * plus actual attribute values
+	 */
+	if (vap->va_mask & ATTR_XVATTR)
+		recsize = sizeof (*lr) + ZIL_XVAT_SIZE(xvap->xva_mapsize);
+
+	if (fuidp)
+		recsize += fuidp->z_domain_str_sz;
+
+	itx = zil_itx_create(txtype, recsize);
+	lr = (lr_setattr_t *)&itx->itx_lr;
+	lr->lr_foid = zp->z_id;
+	lr->lr_mask = (uint64_t)mask_applied;
+	lr->lr_mode = (uint64_t)vap->va_mode;
+	if ((mask_applied & ATTR_UID) && IS_EPHEMERAL(vap->va_uid))
+		lr->lr_uid = fuidp->z_fuid_owner;
+	else
+		lr->lr_uid = (uint64_t)vap->va_uid;
+
+	if ((mask_applied & ATTR_GID) && IS_EPHEMERAL(vap->va_gid))
+		lr->lr_gid = fuidp->z_fuid_group;
+	else
+		lr->lr_gid = (uint64_t)vap->va_gid;
+
+	lr->lr_size = (uint64_t)vap->va_size;
+	ZFS_TIME_ENCODE(&vap->va_atime, lr->lr_atime);
+	ZFS_TIME_ENCODE(&vap->va_mtime, lr->lr_mtime);
+	start = (lr_setattr_t *)(lr + 1);
+	if (vap->va_mask & ATTR_XVATTR) {
+		zfs_log_xvattr((lr_attr_t *)start, xvap);
+		start = (caddr_t)start + ZIL_XVAT_SIZE(xvap->xva_mapsize);
+	}
+
+	/*
+	 * Now stick on domain information if any on end
+	 */
+
+	if (fuidp)
+		(void) zfs_log_fuid_domains(fuidp, start);
+
+	itx->itx_sync = (zp->z_sync_cnt != 0);
+	zil_itx_assign(zilog, itx, tx);
+}
+
+/*
+ * Handles TX_ACL transactions.
+ */
+void
+zfs_log_acl(zilog_t *zilog, dmu_tx_t *tx, znode_t *zp,
+    vsecattr_t *vsecp, zfs_fuid_info_t *fuidp)
+{
+	itx_t *itx;
+	lr_acl_v0_t *lrv0;
+	lr_acl_t *lr;
+	int txtype;
+	int lrsize;
+	size_t txsize;
+	size_t aclbytes = vsecp->vsa_aclentsz;
+
+	if (zil_replaying(zilog, tx) || zp->z_unlinked)
+		return;
+
+	txtype = (ZTOZSB(zp)->z_version < ZPL_VERSION_FUID) ?
+	    TX_ACL_V0 : TX_ACL;
+
+	if (txtype == TX_ACL)
+		lrsize = sizeof (*lr);
+	else
+		lrsize = sizeof (*lrv0);
+
+	txsize = lrsize +
+	    ((txtype == TX_ACL) ? ZIL_ACE_LENGTH(aclbytes) : aclbytes) +
+	    (fuidp ? fuidp->z_domain_str_sz : 0) +
+	    sizeof (uint64_t) * (fuidp ? fuidp->z_fuid_cnt : 0);
+
+	itx = zil_itx_create(txtype, txsize);
+
+	lr = (lr_acl_t *)&itx->itx_lr;
+	lr->lr_foid = zp->z_id;
+	if (txtype == TX_ACL) {
+		lr->lr_acl_bytes = aclbytes;
+		lr->lr_domcnt = fuidp ? fuidp->z_domain_cnt : 0;
+		lr->lr_fuidcnt = fuidp ? fuidp->z_fuid_cnt : 0;
+		if (vsecp->vsa_mask & VSA_ACE_ACLFLAGS)
+			lr->lr_acl_flags = (uint64_t)vsecp->vsa_aclflags;
+		else
+			lr->lr_acl_flags = 0;
+	}
+	lr->lr_aclcnt = (uint64_t)vsecp->vsa_aclcnt;
+
+	if (txtype == TX_ACL_V0) {
+		lrv0 = (lr_acl_v0_t *)lr;
+		bcopy(vsecp->vsa_aclentp, (ace_t *)(lrv0 + 1), aclbytes);
+	} else {
+		void *start = (ace_t *)(lr + 1);
+
+		bcopy(vsecp->vsa_aclentp, start, aclbytes);
+
+		start = (caddr_t)start + ZIL_ACE_LENGTH(aclbytes);
+
+		if (fuidp) {
+			start = zfs_log_fuid_ids(fuidp, start);
+			(void) zfs_log_fuid_domains(fuidp, start);
+		}
+	}
+
+	itx->itx_sync = (zp->z_sync_cnt != 0);
+	zil_itx_assign(zilog, itx, tx);
+}
+
+#if defined(_KERNEL) && defined(HAVE_SPL)
+module_param(zfs_immediate_write_sz, long, 0644);
+MODULE_PARM_DESC(zfs_immediate_write_sz, "Largest data block to write to zil");
+#endif
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/module/zfs/zfs_onexit.c
@@ -0,0 +1,255 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013 by Delphix. All rights reserved.
+ */
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/errno.h>
+#include <sys/open.h>
+#include <sys/kmem.h>
+#include <sys/conf.h>
+#include <sys/ddi.h>
+#include <sys/sunddi.h>
+#include <sys/zfs_ioctl.h>
+#include <sys/mkdev.h>
+#include <sys/zfs_onexit.h>
+#include <sys/zvol.h>
+
+/*
+ * ZFS kernel routines may add/delete callback routines to be invoked
+ * upon process exit (triggered via the close operation from the /dev/zfs
+ * driver).
+ *
+ * These cleanup callbacks are intended to allow for the accumulation
+ * of kernel state across multiple ioctls.  User processes participate
+ * simply by opening ZFS_DEV. This causes the ZFS driver to do create
+ * some private data for the file descriptor and generating a unique
+ * minor number. The process then passes along that file descriptor to
+ * each ioctl that might have a cleanup operation.
+ *
+ * Consumers of the onexit routines should call zfs_onexit_fd_hold() early
+ * on to validate the given fd and add a reference to its file table entry.
+ * This allows the consumer to do its work and then add a callback, knowing
+ * that zfs_onexit_add_cb() won't fail with EBADF.  When finished, consumers
+ * should call zfs_onexit_fd_rele().
+ *
+ * A simple example is zfs_ioc_recv(), where we might create an AVL tree
+ * with dataset/GUID mappings and then reuse that tree on subsequent
+ * zfs_ioc_recv() calls.
+ *
+ * On the first zfs_ioc_recv() call, dmu_recv_stream() will kmem_alloc()
+ * the AVL tree and pass it along with a callback function to
+ * zfs_onexit_add_cb(). The zfs_onexit_add_cb() routine will register the
+ * callback and return an action handle.
+ *
+ * The action handle is then passed from user space to subsequent
+ * zfs_ioc_recv() calls, so that dmu_recv_stream() can fetch its AVL tree
+ * by calling zfs_onexit_cb_data() with the device minor number and
+ * action handle.
+ *
+ * If the user process exits abnormally, the callback is invoked implicitly
+ * as part of the driver close operation.  Once the user space process is
+ * finished with the accumulated kernel state, it can also just call close(2)
+ * on the cleanup fd to trigger the cleanup callback.
+ */
+
+void
+zfs_onexit_init(zfs_onexit_t **zop)
+{
+	zfs_onexit_t *zo;
+
+	zo = *zop = kmem_zalloc(sizeof (zfs_onexit_t), KM_SLEEP);
+	mutex_init(&zo->zo_lock, NULL, MUTEX_DEFAULT, NULL);
+	list_create(&zo->zo_actions, sizeof (zfs_onexit_action_node_t),
+	    offsetof(zfs_onexit_action_node_t, za_link));
+}
+
+void
+zfs_onexit_destroy(zfs_onexit_t *zo)
+{
+	zfs_onexit_action_node_t *ap;
+
+	mutex_enter(&zo->zo_lock);
+	while ((ap = list_head(&zo->zo_actions)) != NULL) {
+		list_remove(&zo->zo_actions, ap);
+		mutex_exit(&zo->zo_lock);
+		ap->za_func(ap->za_data);
+		kmem_free(ap, sizeof (zfs_onexit_action_node_t));
+		mutex_enter(&zo->zo_lock);
+	}
+	mutex_exit(&zo->zo_lock);
+
+	list_destroy(&zo->zo_actions);
+	mutex_destroy(&zo->zo_lock);
+	kmem_free(zo, sizeof (zfs_onexit_t));
+}
+
+static int
+zfs_onexit_minor_to_state(minor_t minor, zfs_onexit_t **zo)
+{
+	*zo = zfsdev_get_state(minor, ZST_ONEXIT);
+	if (*zo == NULL)
+		return (SET_ERROR(EBADF));
+
+	return (0);
+}
+
+/*
+ * Consumers might need to operate by minor number instead of fd, since
+ * they might be running in another thread (e.g. txg_sync_thread). Callers
+ * of this function must call zfs_onexit_fd_rele() when they're finished
+ * using the minor number.
+ */
+int
+zfs_onexit_fd_hold(int fd, minor_t *minorp)
+{
+	file_t *fp;
+	zfs_onexit_t *zo;
+	int error;
+
+	fp = getf(fd);
+	if (fp == NULL)
+		return (SET_ERROR(EBADF));
+
+	error = zfsdev_getminor(fp->f_file, minorp);
+	if (error == 0)
+		error = zfs_onexit_minor_to_state(*minorp, &zo);
+
+	if (error)
+		zfs_onexit_fd_rele(fd);
+
+	return (error);
+}
+
+void
+zfs_onexit_fd_rele(int fd)
+{
+	releasef(fd);
+}
+
+/*
+ * Add a callback to be invoked when the calling process exits.
+ */
+int
+zfs_onexit_add_cb(minor_t minor, void (*func)(void *), void *data,
+    uint64_t *action_handle)
+{
+	zfs_onexit_t *zo;
+	zfs_onexit_action_node_t *ap;
+	int error;
+
+	error = zfs_onexit_minor_to_state(minor, &zo);
+	if (error)
+		return (error);
+
+	ap = kmem_alloc(sizeof (zfs_onexit_action_node_t), KM_SLEEP);
+	list_link_init(&ap->za_link);
+	ap->za_func = func;
+	ap->za_data = data;
+
+	mutex_enter(&zo->zo_lock);
+	list_insert_tail(&zo->zo_actions, ap);
+	mutex_exit(&zo->zo_lock);
+	if (action_handle)
+		*action_handle = (uint64_t)(uintptr_t)ap;
+
+	return (0);
+}
+
+static zfs_onexit_action_node_t *
+zfs_onexit_find_cb(zfs_onexit_t *zo, uint64_t action_handle)
+{
+	zfs_onexit_action_node_t *match;
+	zfs_onexit_action_node_t *ap;
+	list_t *l;
+
+	ASSERT(MUTEX_HELD(&zo->zo_lock));
+
+	match = (zfs_onexit_action_node_t *)(uintptr_t)action_handle;
+	l = &zo->zo_actions;
+	for (ap = list_head(l); ap != NULL; ap = list_next(l, ap)) {
+		if (match == ap)
+			break;
+	}
+	return (ap);
+}
+
+/*
+ * Delete the callback, triggering it first if 'fire' is set.
+ */
+int
+zfs_onexit_del_cb(minor_t minor, uint64_t action_handle, boolean_t fire)
+{
+	zfs_onexit_t *zo;
+	zfs_onexit_action_node_t *ap;
+	int error;
+
+	error = zfs_onexit_minor_to_state(minor, &zo);
+	if (error)
+		return (error);
+
+	mutex_enter(&zo->zo_lock);
+	ap = zfs_onexit_find_cb(zo, action_handle);
+	if (ap != NULL) {
+		list_remove(&zo->zo_actions, ap);
+		mutex_exit(&zo->zo_lock);
+		if (fire)
+			ap->za_func(ap->za_data);
+		kmem_free(ap, sizeof (zfs_onexit_action_node_t));
+	} else {
+		mutex_exit(&zo->zo_lock);
+		error = SET_ERROR(ENOENT);
+	}
+
+	return (error);
+}
+
+/*
+ * Return the data associated with this callback.  This allows consumers
+ * of the cleanup-on-exit interfaces to stash kernel data across system
+ * calls, knowing that it will be cleaned up if the calling process exits.
+ */
+int
+zfs_onexit_cb_data(minor_t minor, uint64_t action_handle, void **data)
+{
+	zfs_onexit_t *zo;
+	zfs_onexit_action_node_t *ap;
+	int error;
+
+	*data = NULL;
+
+	error = zfs_onexit_minor_to_state(minor, &zo);
+	if (error)
+		return (error);
+
+	mutex_enter(&zo->zo_lock);
+	ap = zfs_onexit_find_cb(zo, action_handle);
+	if (ap != NULL)
+		*data = ap->za_data;
+	else
+		error = SET_ERROR(ENOENT);
+	mutex_exit(&zo->zo_lock);
+
+	return (error);
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/module/zfs/zfs_replay.c
@@ -0,0 +1,936 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012 Cyril Plisko. All rights reserved.
+ * Copyright (c) 2013 by Delphix. All rights reserved.
+ */
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/sysmacros.h>
+#include <sys/cmn_err.h>
+#include <sys/kmem.h>
+#include <sys/thread.h>
+#include <sys/file.h>
+#include <sys/fcntl.h>
+#include <sys/vfs.h>
+#include <sys/fs/zfs.h>
+#include <sys/zfs_znode.h>
+#include <sys/zfs_dir.h>
+#include <sys/zfs_acl.h>
+#include <sys/zfs_fuid.h>
+#include <sys/zfs_vnops.h>
+#include <sys/spa.h>
+#include <sys/zil.h>
+#include <sys/byteorder.h>
+#include <sys/stat.h>
+#include <sys/mode.h>
+#include <sys/acl.h>
+#include <sys/atomic.h>
+#include <sys/cred.h>
+#include <sys/zpl.h>
+
+/*
+ * Functions to replay ZFS intent log (ZIL) records
+ * The functions are called through a function vector (zfs_replay_vector)
+ * which is indexed by the transaction type.
+ */
+
+static void
+zfs_init_vattr(vattr_t *vap, uint64_t mask, uint64_t mode,
+	uint64_t uid, uint64_t gid, uint64_t rdev, uint64_t nodeid)
+{
+	bzero(vap, sizeof (*vap));
+	vap->va_mask = (uint_t)mask;
+	vap->va_type = IFTOVT(mode);
+	vap->va_mode = mode;
+	vap->va_uid = (uid_t)(IS_EPHEMERAL(uid)) ? -1 : uid;
+	vap->va_gid = (gid_t)(IS_EPHEMERAL(gid)) ? -1 : gid;
+	vap->va_rdev = rdev;
+	vap->va_nodeid = nodeid;
+}
+
+/* ARGSUSED */
+static int
+zfs_replay_error(zfs_sb_t *zsb, lr_t *lr, boolean_t byteswap)
+{
+	return (SET_ERROR(ENOTSUP));
+}
+
+static void
+zfs_replay_xvattr(lr_attr_t *lrattr, xvattr_t *xvap)
+{
+	xoptattr_t *xoap = NULL;
+	uint64_t *attrs;
+	uint64_t *crtime;
+	uint32_t *bitmap;
+	void *scanstamp;
+	int i;
+
+	xvap->xva_vattr.va_mask |= ATTR_XVATTR;
+	if ((xoap = xva_getxoptattr(xvap)) == NULL) {
+		xvap->xva_vattr.va_mask &= ~ATTR_XVATTR; /* shouldn't happen */
+		return;
+	}
+
+	ASSERT(lrattr->lr_attr_masksize == xvap->xva_mapsize);
+
+	bitmap = &lrattr->lr_attr_bitmap;
+	for (i = 0; i != lrattr->lr_attr_masksize; i++, bitmap++)
+		xvap->xva_reqattrmap[i] = *bitmap;
+
+	attrs = (uint64_t *)(lrattr + lrattr->lr_attr_masksize - 1);
+	crtime = attrs + 1;
+	scanstamp = (caddr_t)(crtime + 2);
+
+	if (XVA_ISSET_REQ(xvap, XAT_HIDDEN))
+		xoap->xoa_hidden = ((*attrs & XAT0_HIDDEN) != 0);
+	if (XVA_ISSET_REQ(xvap, XAT_SYSTEM))
+		xoap->xoa_system = ((*attrs & XAT0_SYSTEM) != 0);
+	if (XVA_ISSET_REQ(xvap, XAT_ARCHIVE))
+		xoap->xoa_archive = ((*attrs & XAT0_ARCHIVE) != 0);
+	if (XVA_ISSET_REQ(xvap, XAT_READONLY))
+		xoap->xoa_readonly = ((*attrs & XAT0_READONLY) != 0);
+	if (XVA_ISSET_REQ(xvap, XAT_IMMUTABLE))
+		xoap->xoa_immutable = ((*attrs & XAT0_IMMUTABLE) != 0);
+	if (XVA_ISSET_REQ(xvap, XAT_NOUNLINK))
+		xoap->xoa_nounlink = ((*attrs & XAT0_NOUNLINK) != 0);
+	if (XVA_ISSET_REQ(xvap, XAT_APPENDONLY))
+		xoap->xoa_appendonly = ((*attrs & XAT0_APPENDONLY) != 0);
+	if (XVA_ISSET_REQ(xvap, XAT_NODUMP))
+		xoap->xoa_nodump = ((*attrs & XAT0_NODUMP) != 0);
+	if (XVA_ISSET_REQ(xvap, XAT_OPAQUE))
+		xoap->xoa_opaque = ((*attrs & XAT0_OPAQUE) != 0);
+	if (XVA_ISSET_REQ(xvap, XAT_AV_MODIFIED))
+		xoap->xoa_av_modified = ((*attrs & XAT0_AV_MODIFIED) != 0);
+	if (XVA_ISSET_REQ(xvap, XAT_AV_QUARANTINED))
+		xoap->xoa_av_quarantined =
+		    ((*attrs & XAT0_AV_QUARANTINED) != 0);
+	if (XVA_ISSET_REQ(xvap, XAT_CREATETIME))
+		ZFS_TIME_DECODE(&xoap->xoa_createtime, crtime);
+	if (XVA_ISSET_REQ(xvap, XAT_AV_SCANSTAMP))
+		bcopy(scanstamp, xoap->xoa_av_scanstamp, AV_SCANSTAMP_SZ);
+	if (XVA_ISSET_REQ(xvap, XAT_REPARSE))
+		xoap->xoa_reparse = ((*attrs & XAT0_REPARSE) != 0);
+	if (XVA_ISSET_REQ(xvap, XAT_OFFLINE))
+		xoap->xoa_offline = ((*attrs & XAT0_OFFLINE) != 0);
+	if (XVA_ISSET_REQ(xvap, XAT_SPARSE))
+		xoap->xoa_sparse = ((*attrs & XAT0_SPARSE) != 0);
+}
+
+static int
+zfs_replay_domain_cnt(uint64_t uid, uint64_t gid)
+{
+	uint64_t uid_idx;
+	uint64_t gid_idx;
+	int domcnt = 0;
+
+	uid_idx = FUID_INDEX(uid);
+	gid_idx = FUID_INDEX(gid);
+	if (uid_idx)
+		domcnt++;
+	if (gid_idx > 0 && gid_idx != uid_idx)
+		domcnt++;
+
+	return (domcnt);
+}
+
+static void *
+zfs_replay_fuid_domain_common(zfs_fuid_info_t *fuid_infop, void *start,
+    int domcnt)
+{
+	int i;
+
+	for (i = 0; i != domcnt; i++) {
+		fuid_infop->z_domain_table[i] = start;
+		start = (caddr_t)start + strlen(start) + 1;
+	}
+
+	return (start);
+}
+
+/*
+ * Set the uid/gid in the fuid_info structure.
+ */
+static void
+zfs_replay_fuid_ugid(zfs_fuid_info_t *fuid_infop, uint64_t uid, uint64_t gid)
+{
+	/*
+	 * If owner or group are log specific FUIDs then slurp up
+	 * domain information and build zfs_fuid_info_t
+	 */
+	if (IS_EPHEMERAL(uid))
+		fuid_infop->z_fuid_owner = uid;
+
+	if (IS_EPHEMERAL(gid))
+		fuid_infop->z_fuid_group = gid;
+}
+
+/*
+ * Load fuid domains into fuid_info_t
+ */
+static zfs_fuid_info_t *
+zfs_replay_fuid_domain(void *buf, void **end, uint64_t uid, uint64_t gid)
+{
+	int domcnt;
+
+	zfs_fuid_info_t *fuid_infop;
+
+	fuid_infop = zfs_fuid_info_alloc();
+
+	domcnt = zfs_replay_domain_cnt(uid, gid);
+
+	if (domcnt == 0)
+		return (fuid_infop);
+
+	fuid_infop->z_domain_table =
+	    kmem_zalloc(domcnt * sizeof (char **), KM_SLEEP);
+
+	zfs_replay_fuid_ugid(fuid_infop, uid, gid);
+
+	fuid_infop->z_domain_cnt = domcnt;
+	*end = zfs_replay_fuid_domain_common(fuid_infop, buf, domcnt);
+	return (fuid_infop);
+}
+
+/*
+ * load zfs_fuid_t's and fuid_domains into fuid_info_t
+ */
+static zfs_fuid_info_t *
+zfs_replay_fuids(void *start, void **end, int idcnt, int domcnt, uint64_t uid,
+    uint64_t gid)
+{
+	uint64_t *log_fuid = (uint64_t *)start;
+	zfs_fuid_info_t *fuid_infop;
+	int i;
+
+	fuid_infop = zfs_fuid_info_alloc();
+	fuid_infop->z_domain_cnt = domcnt;
+
+	fuid_infop->z_domain_table =
+	    kmem_zalloc(domcnt * sizeof (char **), KM_SLEEP);
+
+	for (i = 0; i != idcnt; i++) {
+		zfs_fuid_t *zfuid;
+
+		zfuid = kmem_alloc(sizeof (zfs_fuid_t), KM_SLEEP);
+		zfuid->z_logfuid = *log_fuid;
+		zfuid->z_id = -1;
+		zfuid->z_domidx = 0;
+		list_insert_tail(&fuid_infop->z_fuids, zfuid);
+		log_fuid++;
+	}
+
+	zfs_replay_fuid_ugid(fuid_infop, uid, gid);
+
+	*end = zfs_replay_fuid_domain_common(fuid_infop, log_fuid, domcnt);
+	return (fuid_infop);
+}
+
+static void
+zfs_replay_swap_attrs(lr_attr_t *lrattr)
+{
+	/* swap the lr_attr structure */
+	byteswap_uint32_array(lrattr, sizeof (*lrattr));
+	/* swap the bitmap */
+	byteswap_uint32_array(lrattr + 1, (lrattr->lr_attr_masksize - 1) *
+	    sizeof (uint32_t));
+	/* swap the attributes, create time + 64 bit word for attributes */
+	byteswap_uint64_array((caddr_t)(lrattr + 1) + (sizeof (uint32_t) *
+	    (lrattr->lr_attr_masksize - 1)), 3 * sizeof (uint64_t));
+}
+
+/*
+ * Replay file create with optional ACL, xvattr information as well
+ * as option FUID information.
+ */
+static int
+zfs_replay_create_acl(zfs_sb_t *zsb, lr_acl_create_t *lracl, boolean_t byteswap)
+{
+	char *name = NULL;		/* location determined later */
+	lr_create_t *lr = (lr_create_t *)lracl;
+	znode_t *dzp;
+	struct inode *ip = NULL;
+	xvattr_t xva;
+	int vflg = 0;
+	vsecattr_t vsec = { 0 };
+	lr_attr_t *lrattr;
+	void *aclstart;
+	void *fuidstart;
+	size_t xvatlen = 0;
+	uint64_t txtype;
+	int error;
+
+	txtype = (lr->lr_common.lrc_txtype & ~TX_CI);
+	if (byteswap) {
+		byteswap_uint64_array(lracl, sizeof (*lracl));
+		if (txtype == TX_CREATE_ACL_ATTR ||
+		    txtype == TX_MKDIR_ACL_ATTR) {
+			lrattr = (lr_attr_t *)(caddr_t)(lracl + 1);
+			zfs_replay_swap_attrs(lrattr);
+			xvatlen = ZIL_XVAT_SIZE(lrattr->lr_attr_masksize);
+		}
+
+		aclstart = (caddr_t)(lracl + 1) + xvatlen;
+		zfs_ace_byteswap(aclstart, lracl->lr_acl_bytes, B_FALSE);
+		/* swap fuids */
+		if (lracl->lr_fuidcnt) {
+			byteswap_uint64_array((caddr_t)aclstart +
+			    ZIL_ACE_LENGTH(lracl->lr_acl_bytes),
+			    lracl->lr_fuidcnt * sizeof (uint64_t));
+		}
+	}
+
+	if ((error = zfs_zget(zsb, lr->lr_doid, &dzp)) != 0)
+		return (error);
+
+	xva_init(&xva);
+	zfs_init_vattr(&xva.xva_vattr, ATTR_MODE | ATTR_UID | ATTR_GID,
+	    lr->lr_mode, lr->lr_uid, lr->lr_gid, lr->lr_rdev, lr->lr_foid);
+
+	/*
+	 * All forms of zfs create (create, mkdir, mkxattrdir, symlink)
+	 * eventually end up in zfs_mknode(), which assigns the object's
+	 * creation time and generation number.  The generic zfs_create()
+	 * doesn't have either concept, so we smuggle the values inside
+	 * the vattr's otherwise unused va_ctime and va_nblocks fields.
+	 */
+	ZFS_TIME_DECODE(&xva.xva_vattr.va_ctime, lr->lr_crtime);
+	xva.xva_vattr.va_nblocks = lr->lr_gen;
+
+	error = dmu_object_info(zsb->z_os, lr->lr_foid, NULL);
+	if (error != ENOENT)
+		goto bail;
+
+	if (lr->lr_common.lrc_txtype & TX_CI)
+		vflg |= FIGNORECASE;
+	switch (txtype) {
+	case TX_CREATE_ACL:
+		aclstart = (caddr_t)(lracl + 1);
+		fuidstart = (caddr_t)aclstart +
+		    ZIL_ACE_LENGTH(lracl->lr_acl_bytes);
+		zsb->z_fuid_replay = zfs_replay_fuids(fuidstart,
+		    (void *)&name, lracl->lr_fuidcnt, lracl->lr_domcnt,
+		    lr->lr_uid, lr->lr_gid);
+		/*FALLTHROUGH*/
+	case TX_CREATE_ACL_ATTR:
+		if (name == NULL) {
+			lrattr = (lr_attr_t *)(caddr_t)(lracl + 1);
+			xvatlen = ZIL_XVAT_SIZE(lrattr->lr_attr_masksize);
+			xva.xva_vattr.va_mask |= ATTR_XVATTR;
+			zfs_replay_xvattr(lrattr, &xva);
+		}
+		vsec.vsa_mask = VSA_ACE | VSA_ACE_ACLFLAGS;
+		vsec.vsa_aclentp = (caddr_t)(lracl + 1) + xvatlen;
+		vsec.vsa_aclcnt = lracl->lr_aclcnt;
+		vsec.vsa_aclentsz = lracl->lr_acl_bytes;
+		vsec.vsa_aclflags = lracl->lr_acl_flags;
+		if (zsb->z_fuid_replay == NULL) {
+			fuidstart = (caddr_t)(lracl + 1) + xvatlen +
+			    ZIL_ACE_LENGTH(lracl->lr_acl_bytes);
+			zsb->z_fuid_replay =
+			    zfs_replay_fuids(fuidstart,
+			    (void *)&name, lracl->lr_fuidcnt, lracl->lr_domcnt,
+			    lr->lr_uid, lr->lr_gid);
+		}
+
+		error = zfs_create(ZTOI(dzp), name, &xva.xva_vattr,
+		    0, 0, &ip, kcred, vflg, &vsec);
+		break;
+	case TX_MKDIR_ACL:
+		aclstart = (caddr_t)(lracl + 1);
+		fuidstart = (caddr_t)aclstart +
+		    ZIL_ACE_LENGTH(lracl->lr_acl_bytes);
+		zsb->z_fuid_replay = zfs_replay_fuids(fuidstart,
+		    (void *)&name, lracl->lr_fuidcnt, lracl->lr_domcnt,
+		    lr->lr_uid, lr->lr_gid);
+		/*FALLTHROUGH*/
+	case TX_MKDIR_ACL_ATTR:
+		if (name == NULL) {
+			lrattr = (lr_attr_t *)(caddr_t)(lracl + 1);
+			xvatlen = ZIL_XVAT_SIZE(lrattr->lr_attr_masksize);
+			zfs_replay_xvattr(lrattr, &xva);
+		}
+		vsec.vsa_mask = VSA_ACE | VSA_ACE_ACLFLAGS;
+		vsec.vsa_aclentp = (caddr_t)(lracl + 1) + xvatlen;
+		vsec.vsa_aclcnt = lracl->lr_aclcnt;
+		vsec.vsa_aclentsz = lracl->lr_acl_bytes;
+		vsec.vsa_aclflags = lracl->lr_acl_flags;
+		if (zsb->z_fuid_replay == NULL) {
+			fuidstart = (caddr_t)(lracl + 1) + xvatlen +
+			    ZIL_ACE_LENGTH(lracl->lr_acl_bytes);
+			zsb->z_fuid_replay =
+			    zfs_replay_fuids(fuidstart,
+			    (void *)&name, lracl->lr_fuidcnt, lracl->lr_domcnt,
+			    lr->lr_uid, lr->lr_gid);
+		}
+		error = zfs_mkdir(ZTOI(dzp), name, &xva.xva_vattr,
+		    &ip, kcred, vflg, &vsec);
+		break;
+	default:
+		error = SET_ERROR(ENOTSUP);
+	}
+
+bail:
+	if (error == 0 && ip != NULL)
+		iput(ip);
+
+	iput(ZTOI(dzp));
+
+	if (zsb->z_fuid_replay)
+		zfs_fuid_info_free(zsb->z_fuid_replay);
+	zsb->z_fuid_replay = NULL;
+
+	return (error);
+}
+
+static int
+zfs_replay_create(zfs_sb_t *zsb, lr_create_t *lr, boolean_t byteswap)
+{
+	char *name = NULL;		/* location determined later */
+	char *link;			/* symlink content follows name */
+	znode_t *dzp;
+	struct inode *ip = NULL;
+	xvattr_t xva;
+	int vflg = 0;
+	size_t lrsize = sizeof (lr_create_t);
+	lr_attr_t *lrattr;
+	void *start;
+	size_t xvatlen;
+	uint64_t txtype;
+	int error;
+
+	txtype = (lr->lr_common.lrc_txtype & ~TX_CI);
+	if (byteswap) {
+		byteswap_uint64_array(lr, sizeof (*lr));
+		if (txtype == TX_CREATE_ATTR || txtype == TX_MKDIR_ATTR)
+			zfs_replay_swap_attrs((lr_attr_t *)(lr + 1));
+	}
+
+
+	if ((error = zfs_zget(zsb, lr->lr_doid, &dzp)) != 0)
+		return (error);
+
+	xva_init(&xva);
+	zfs_init_vattr(&xva.xva_vattr, ATTR_MODE | ATTR_UID | ATTR_GID,
+	    lr->lr_mode, lr->lr_uid, lr->lr_gid, lr->lr_rdev, lr->lr_foid);
+
+	/*
+	 * All forms of zfs create (create, mkdir, mkxattrdir, symlink)
+	 * eventually end up in zfs_mknode(), which assigns the object's
+	 * creation time and generation number.  The generic zfs_create()
+	 * doesn't have either concept, so we smuggle the values inside
+	 * the vattr's otherwise unused va_ctime and va_nblocks fields.
+	 */
+	ZFS_TIME_DECODE(&xva.xva_vattr.va_ctime, lr->lr_crtime);
+	xva.xva_vattr.va_nblocks = lr->lr_gen;
+
+	error = dmu_object_info(zsb->z_os, lr->lr_foid, NULL);
+	if (error != ENOENT)
+		goto out;
+
+	if (lr->lr_common.lrc_txtype & TX_CI)
+		vflg |= FIGNORECASE;
+
+	/*
+	 * Symlinks don't have fuid info, and CIFS never creates
+	 * symlinks.
+	 *
+	 * The _ATTR versions will grab the fuid info in their subcases.
+	 */
+	if ((int)lr->lr_common.lrc_txtype != TX_SYMLINK &&
+	    (int)lr->lr_common.lrc_txtype != TX_MKDIR_ATTR &&
+	    (int)lr->lr_common.lrc_txtype != TX_CREATE_ATTR) {
+		start = (lr + 1);
+		zsb->z_fuid_replay =
+		    zfs_replay_fuid_domain(start, &start,
+		    lr->lr_uid, lr->lr_gid);
+	}
+
+	switch (txtype) {
+	case TX_CREATE_ATTR:
+		lrattr = (lr_attr_t *)(caddr_t)(lr + 1);
+		xvatlen = ZIL_XVAT_SIZE(lrattr->lr_attr_masksize);
+		zfs_replay_xvattr((lr_attr_t *)((caddr_t)lr + lrsize), &xva);
+		start = (caddr_t)(lr + 1) + xvatlen;
+		zsb->z_fuid_replay =
+		    zfs_replay_fuid_domain(start, &start,
+		    lr->lr_uid, lr->lr_gid);
+		name = (char *)start;
+
+		/*FALLTHROUGH*/
+	case TX_CREATE:
+		if (name == NULL)
+			name = (char *)start;
+
+		error = zfs_create(ZTOI(dzp), name, &xva.xva_vattr,
+		    0, 0, &ip, kcred, vflg, NULL);
+		break;
+	case TX_MKDIR_ATTR:
+		lrattr = (lr_attr_t *)(caddr_t)(lr + 1);
+		xvatlen = ZIL_XVAT_SIZE(lrattr->lr_attr_masksize);
+		zfs_replay_xvattr((lr_attr_t *)((caddr_t)lr + lrsize), &xva);
+		start = (caddr_t)(lr + 1) + xvatlen;
+		zsb->z_fuid_replay =
+		    zfs_replay_fuid_domain(start, &start,
+		    lr->lr_uid, lr->lr_gid);
+		name = (char *)start;
+
+		/*FALLTHROUGH*/
+	case TX_MKDIR:
+		if (name == NULL)
+			name = (char *)(lr + 1);
+
+		error = zfs_mkdir(ZTOI(dzp), name, &xva.xva_vattr,
+		    &ip, kcred, vflg, NULL);
+		break;
+	case TX_MKXATTR:
+		error = zfs_make_xattrdir(dzp, &xva.xva_vattr, &ip, kcred);
+		break;
+	case TX_SYMLINK:
+		name = (char *)(lr + 1);
+		link = name + strlen(name) + 1;
+		error = zfs_symlink(ZTOI(dzp), name, &xva.xva_vattr,
+		    link, &ip, kcred, vflg);
+		break;
+	default:
+		error = SET_ERROR(ENOTSUP);
+	}
+
+out:
+	if (error == 0 && ip != NULL)
+		iput(ip);
+
+	iput(ZTOI(dzp));
+
+	if (zsb->z_fuid_replay)
+		zfs_fuid_info_free(zsb->z_fuid_replay);
+	zsb->z_fuid_replay = NULL;
+	return (error);
+}
+
+static int
+zfs_replay_remove(zfs_sb_t *zsb, lr_remove_t *lr, boolean_t byteswap)
+{
+	char *name = (char *)(lr + 1);	/* name follows lr_remove_t */
+	znode_t *dzp;
+	int error;
+	int vflg = 0;
+
+	if (byteswap)
+		byteswap_uint64_array(lr, sizeof (*lr));
+
+	if ((error = zfs_zget(zsb, lr->lr_doid, &dzp)) != 0)
+		return (error);
+
+	if (lr->lr_common.lrc_txtype & TX_CI)
+		vflg |= FIGNORECASE;
+
+	switch ((int)lr->lr_common.lrc_txtype) {
+	case TX_REMOVE:
+		error = zfs_remove(ZTOI(dzp), name, kcred);
+		break;
+	case TX_RMDIR:
+		error = zfs_rmdir(ZTOI(dzp), name, NULL, kcred, vflg);
+		break;
+	default:
+		error = SET_ERROR(ENOTSUP);
+	}
+
+	iput(ZTOI(dzp));
+
+	return (error);
+}
+
+static int
+zfs_replay_link(zfs_sb_t *zsb, lr_link_t *lr, boolean_t byteswap)
+{
+	char *name = (char *)(lr + 1);	/* name follows lr_link_t */
+	znode_t *dzp, *zp;
+	int error;
+	int vflg = 0;
+
+	if (byteswap)
+		byteswap_uint64_array(lr, sizeof (*lr));
+
+	if ((error = zfs_zget(zsb, lr->lr_doid, &dzp)) != 0)
+		return (error);
+
+	if ((error = zfs_zget(zsb, lr->lr_link_obj, &zp)) != 0) {
+		iput(ZTOI(dzp));
+		return (error);
+	}
+
+	if (lr->lr_common.lrc_txtype & TX_CI)
+		vflg |= FIGNORECASE;
+
+	error = zfs_link(ZTOI(dzp), ZTOI(zp), name, kcred);
+
+	iput(ZTOI(zp));
+	iput(ZTOI(dzp));
+
+	return (error);
+}
+
+static int
+zfs_replay_rename(zfs_sb_t *zsb, lr_rename_t *lr, boolean_t byteswap)
+{
+	char *sname = (char *)(lr + 1);	/* sname and tname follow lr_rename_t */
+	char *tname = sname + strlen(sname) + 1;
+	znode_t *sdzp, *tdzp;
+	int error;
+	int vflg = 0;
+
+	if (byteswap)
+		byteswap_uint64_array(lr, sizeof (*lr));
+
+	if ((error = zfs_zget(zsb, lr->lr_sdoid, &sdzp)) != 0)
+		return (error);
+
+	if ((error = zfs_zget(zsb, lr->lr_tdoid, &tdzp)) != 0) {
+		iput(ZTOI(sdzp));
+		return (error);
+	}
+
+	if (lr->lr_common.lrc_txtype & TX_CI)
+		vflg |= FIGNORECASE;
+
+	error = zfs_rename(ZTOI(sdzp), sname, ZTOI(tdzp), tname, kcred, vflg);
+
+	iput(ZTOI(tdzp));
+	iput(ZTOI(sdzp));
+
+	return (error);
+}
+
+static int
+zfs_replay_write(zfs_sb_t *zsb, lr_write_t *lr, boolean_t byteswap)
+{
+	char *data = (char *)(lr + 1);	/* data follows lr_write_t */
+	znode_t	*zp;
+	int error, written;
+	uint64_t eod, offset, length;
+
+	if (byteswap)
+		byteswap_uint64_array(lr, sizeof (*lr));
+
+	if ((error = zfs_zget(zsb, lr->lr_foid, &zp)) != 0) {
+		/*
+		 * As we can log writes out of order, it's possible the
+		 * file has been removed. In this case just drop the write
+		 * and return success.
+		 */
+		if (error == ENOENT)
+			error = 0;
+		return (error);
+	}
+
+	offset = lr->lr_offset;
+	length = lr->lr_length;
+	eod = offset + length;	/* end of data for this write */
+
+	/*
+	 * This may be a write from a dmu_sync() for a whole block,
+	 * and may extend beyond the current end of the file.
+	 * We can't just replay what was written for this TX_WRITE as
+	 * a future TX_WRITE2 may extend the eof and the data for that
+	 * write needs to be there. So we write the whole block and
+	 * reduce the eof. This needs to be done within the single dmu
+	 * transaction created within vn_rdwr -> zfs_write. So a possible
+	 * new end of file is passed through in zsb->z_replay_eof
+	 */
+
+	zsb->z_replay_eof = 0; /* 0 means don't change end of file */
+
+	/* If it's a dmu_sync() block, write the whole block */
+	if (lr->lr_common.lrc_reclen == sizeof (lr_write_t)) {
+		uint64_t blocksize = BP_GET_LSIZE(&lr->lr_blkptr);
+		if (length < blocksize) {
+			offset -= offset % blocksize;
+			length = blocksize;
+		}
+		if (zp->z_size < eod)
+			zsb->z_replay_eof = eod;
+	}
+
+	written = zpl_write_common(ZTOI(zp), data, length, &offset,
+	    UIO_SYSSPACE, 0, kcred);
+	if (written < 0)
+		error = -written;
+	else if (written < length)
+		error = SET_ERROR(EIO); /* short write */
+
+	iput(ZTOI(zp));
+	zsb->z_replay_eof = 0;	/* safety */
+
+	return (error);
+}
+
+/*
+ * TX_WRITE2 are only generated when dmu_sync() returns EALREADY
+ * meaning the pool block is already being synced. So now that we always write
+ * out full blocks, all we have to do is expand the eof if
+ * the file is grown.
+ */
+static int
+zfs_replay_write2(zfs_sb_t *zsb, lr_write_t *lr, boolean_t byteswap)
+{
+	znode_t	*zp;
+	int error;
+	uint64_t end;
+
+	if (byteswap)
+		byteswap_uint64_array(lr, sizeof (*lr));
+
+	if ((error = zfs_zget(zsb, lr->lr_foid, &zp)) != 0)
+		return (error);
+
+top:
+	end = lr->lr_offset + lr->lr_length;
+	if (end > zp->z_size) {
+		dmu_tx_t *tx = dmu_tx_create(zsb->z_os);
+
+		zp->z_size = end;
+		dmu_tx_hold_sa(tx, zp->z_sa_hdl, B_FALSE);
+		error = dmu_tx_assign(tx, TXG_WAIT);
+		if (error) {
+			iput(ZTOI(zp));
+			if (error == ERESTART) {
+				dmu_tx_wait(tx);
+				dmu_tx_abort(tx);
+				goto top;
+			}
+			dmu_tx_abort(tx);
+			return (error);
+		}
+		(void) sa_update(zp->z_sa_hdl, SA_ZPL_SIZE(zsb),
+		    (void *)&zp->z_size, sizeof (uint64_t), tx);
+
+		/* Ensure the replayed seq is updated */
+		(void) zil_replaying(zsb->z_log, tx);
+
+		dmu_tx_commit(tx);
+	}
+
+	iput(ZTOI(zp));
+
+	return (error);
+}
+
+static int
+zfs_replay_truncate(zfs_sb_t *zsb, lr_truncate_t *lr, boolean_t byteswap)
+{
+	znode_t *zp;
+	flock64_t fl;
+	int error;
+
+	if (byteswap)
+		byteswap_uint64_array(lr, sizeof (*lr));
+
+	if ((error = zfs_zget(zsb, lr->lr_foid, &zp)) != 0)
+		return (error);
+
+	bzero(&fl, sizeof (fl));
+	fl.l_type = F_WRLCK;
+	fl.l_whence = 0;
+	fl.l_start = lr->lr_offset;
+	fl.l_len = lr->lr_length;
+
+	error = zfs_space(ZTOI(zp), F_FREESP, &fl, FWRITE | FOFFMAX,
+	    lr->lr_offset, kcred);
+
+	iput(ZTOI(zp));
+
+	return (error);
+}
+
+static int
+zfs_replay_setattr(zfs_sb_t *zsb, lr_setattr_t *lr, boolean_t byteswap)
+{
+	znode_t *zp;
+	xvattr_t xva;
+	vattr_t *vap = &xva.xva_vattr;
+	int error;
+	void *start;
+
+	xva_init(&xva);
+	if (byteswap) {
+		byteswap_uint64_array(lr, sizeof (*lr));
+
+		if ((lr->lr_mask & ATTR_XVATTR) &&
+		    zsb->z_version >= ZPL_VERSION_INITIAL)
+			zfs_replay_swap_attrs((lr_attr_t *)(lr + 1));
+	}
+
+	if ((error = zfs_zget(zsb, lr->lr_foid, &zp)) != 0)
+		return (error);
+
+	zfs_init_vattr(vap, lr->lr_mask, lr->lr_mode,
+	    lr->lr_uid, lr->lr_gid, 0, lr->lr_foid);
+
+	vap->va_size = lr->lr_size;
+	ZFS_TIME_DECODE(&vap->va_atime, lr->lr_atime);
+	ZFS_TIME_DECODE(&vap->va_mtime, lr->lr_mtime);
+
+	/*
+	 * Fill in xvattr_t portions if necessary.
+	 */
+
+	start = (lr_setattr_t *)(lr + 1);
+	if (vap->va_mask & ATTR_XVATTR) {
+		zfs_replay_xvattr((lr_attr_t *)start, &xva);
+		start = (caddr_t)start +
+		    ZIL_XVAT_SIZE(((lr_attr_t *)start)->lr_attr_masksize);
+	} else
+		xva.xva_vattr.va_mask &= ~ATTR_XVATTR;
+
+	zsb->z_fuid_replay = zfs_replay_fuid_domain(start, &start,
+	    lr->lr_uid, lr->lr_gid);
+
+	error = zfs_setattr(ZTOI(zp), vap, 0, kcred);
+
+	zfs_fuid_info_free(zsb->z_fuid_replay);
+	zsb->z_fuid_replay = NULL;
+	iput(ZTOI(zp));
+
+	return (error);
+}
+
+static int
+zfs_replay_acl_v0(zfs_sb_t *zsb, lr_acl_v0_t *lr, boolean_t byteswap)
+{
+	ace_t *ace = (ace_t *)(lr + 1);	/* ace array follows lr_acl_t */
+	vsecattr_t vsa;
+	znode_t *zp;
+	int error;
+
+	if (byteswap) {
+		byteswap_uint64_array(lr, sizeof (*lr));
+		zfs_oldace_byteswap(ace, lr->lr_aclcnt);
+	}
+
+	if ((error = zfs_zget(zsb, lr->lr_foid, &zp)) != 0)
+		return (error);
+
+	bzero(&vsa, sizeof (vsa));
+	vsa.vsa_mask = VSA_ACE | VSA_ACECNT;
+	vsa.vsa_aclcnt = lr->lr_aclcnt;
+	vsa.vsa_aclentsz = sizeof (ace_t) * vsa.vsa_aclcnt;
+	vsa.vsa_aclflags = 0;
+	vsa.vsa_aclentp = ace;
+
+	error = zfs_setsecattr(ZTOI(zp), &vsa, 0, kcred);
+
+	iput(ZTOI(zp));
+
+	return (error);
+}
+
+/*
+ * Replaying ACLs is complicated by FUID support.
+ * The log record may contain some optional data
+ * to be used for replaying FUID's.  These pieces
+ * are the actual FUIDs that were created initially.
+ * The FUID table index may no longer be valid and
+ * during zfs_create() a new index may be assigned.
+ * Because of this the log will contain the original
+ * doman+rid in order to create a new FUID.
+ *
+ * The individual ACEs may contain an ephemeral uid/gid which is no
+ * longer valid and will need to be replaced with an actual FUID.
+ *
+ */
+static int
+zfs_replay_acl(zfs_sb_t *zsb, lr_acl_t *lr, boolean_t byteswap)
+{
+	ace_t *ace = (ace_t *)(lr + 1);
+	vsecattr_t vsa;
+	znode_t *zp;
+	int error;
+
+	if (byteswap) {
+		byteswap_uint64_array(lr, sizeof (*lr));
+		zfs_ace_byteswap(ace, lr->lr_acl_bytes, B_FALSE);
+		if (lr->lr_fuidcnt) {
+			byteswap_uint64_array((caddr_t)ace +
+			    ZIL_ACE_LENGTH(lr->lr_acl_bytes),
+			    lr->lr_fuidcnt * sizeof (uint64_t));
+		}
+	}
+
+	if ((error = zfs_zget(zsb, lr->lr_foid, &zp)) != 0)
+		return (error);
+
+	bzero(&vsa, sizeof (vsa));
+	vsa.vsa_mask = VSA_ACE | VSA_ACECNT | VSA_ACE_ACLFLAGS;
+	vsa.vsa_aclcnt = lr->lr_aclcnt;
+	vsa.vsa_aclentp = ace;
+	vsa.vsa_aclentsz = lr->lr_acl_bytes;
+	vsa.vsa_aclflags = lr->lr_acl_flags;
+
+	if (lr->lr_fuidcnt) {
+		void *fuidstart = (caddr_t)ace +
+		    ZIL_ACE_LENGTH(lr->lr_acl_bytes);
+
+		zsb->z_fuid_replay =
+		    zfs_replay_fuids(fuidstart, &fuidstart,
+		    lr->lr_fuidcnt, lr->lr_domcnt, 0, 0);
+	}
+
+	error = zfs_setsecattr(ZTOI(zp), &vsa, 0, kcred);
+
+	if (zsb->z_fuid_replay)
+		zfs_fuid_info_free(zsb->z_fuid_replay);
+
+	zsb->z_fuid_replay = NULL;
+	iput(ZTOI(zp));
+
+	return (error);
+}
+
+/*
+ * Callback vectors for replaying records
+ */
+zil_replay_func_t zfs_replay_vector[TX_MAX_TYPE] = {
+	(zil_replay_func_t)zfs_replay_error,		/* no such type */
+	(zil_replay_func_t)zfs_replay_create,		/* TX_CREATE */
+	(zil_replay_func_t)zfs_replay_create,		/* TX_MKDIR */
+	(zil_replay_func_t)zfs_replay_create,		/* TX_MKXATTR */
+	(zil_replay_func_t)zfs_replay_create,		/* TX_SYMLINK */
+	(zil_replay_func_t)zfs_replay_remove,		/* TX_REMOVE */
+	(zil_replay_func_t)zfs_replay_remove,		/* TX_RMDIR */
+	(zil_replay_func_t)zfs_replay_link,		/* TX_LINK */
+	(zil_replay_func_t)zfs_replay_rename,		/* TX_RENAME */
+	(zil_replay_func_t)zfs_replay_write,		/* TX_WRITE */
+	(zil_replay_func_t)zfs_replay_truncate,		/* TX_TRUNCATE */
+	(zil_replay_func_t)zfs_replay_setattr,		/* TX_SETATTR */
+	(zil_replay_func_t)zfs_replay_acl_v0,		/* TX_ACL_V0 */
+	(zil_replay_func_t)zfs_replay_acl,		/* TX_ACL */
+	(zil_replay_func_t)zfs_replay_create_acl,	/* TX_CREATE_ACL */
+	(zil_replay_func_t)zfs_replay_create,		/* TX_CREATE_ATTR */
+	(zil_replay_func_t)zfs_replay_create_acl,	/* TX_CREATE_ACL_ATTR */
+	(zil_replay_func_t)zfs_replay_create_acl,	/* TX_MKDIR_ACL */
+	(zil_replay_func_t)zfs_replay_create,		/* TX_MKDIR_ATTR */
+	(zil_replay_func_t)zfs_replay_create_acl,	/* TX_MKDIR_ACL_ATTR */
+	(zil_replay_func_t)zfs_replay_write2,		/* TX_WRITE2 */
+};
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/module/zfs/zfs_rlock.c
@@ -0,0 +1,628 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * Copyright (c) 2012 by Delphix. All rights reserved.
+ */
+
+/*
+ * This file contains the code to implement file range locking in
+ * ZFS, although there isn't much specific to ZFS (all that comes to mind is
+ * support for growing the blocksize).
+ *
+ * Interface
+ * ---------
+ * Defined in zfs_rlock.h but essentially:
+ *	rl = zfs_range_lock(zp, off, len, lock_type);
+ *	zfs_range_unlock(rl);
+ *	zfs_range_reduce(rl, off, len);
+ *
+ * AVL tree
+ * --------
+ * An AVL tree is used to maintain the state of the existing ranges
+ * that are locked for exclusive (writer) or shared (reader) use.
+ * The starting range offset is used for searching and sorting the tree.
+ *
+ * Common case
+ * -----------
+ * The (hopefully) usual case is of no overlaps or contention for
+ * locks. On entry to zfs_lock_range() a rl_t is allocated; the tree
+ * searched that finds no overlap, and *this* rl_t is placed in the tree.
+ *
+ * Overlaps/Reference counting/Proxy locks
+ * ---------------------------------------
+ * The avl code only allows one node at a particular offset. Also it's very
+ * inefficient to search through all previous entries looking for overlaps
+ * (because the very 1st in the ordered list might be at offset 0 but
+ * cover the whole file).
+ * So this implementation uses reference counts and proxy range locks.
+ * Firstly, only reader locks use reference counts and proxy locks,
+ * because writer locks are exclusive.
+ * When a reader lock overlaps with another then a proxy lock is created
+ * for that range and replaces the original lock. If the overlap
+ * is exact then the reference count of the proxy is simply incremented.
+ * Otherwise, the proxy lock is split into smaller lock ranges and
+ * new proxy locks created for non overlapping ranges.
+ * The reference counts are adjusted accordingly.
+ * Meanwhile, the orginal lock is kept around (this is the callers handle)
+ * and its offset and length are used when releasing the lock.
+ *
+ * Thread coordination
+ * -------------------
+ * In order to make wakeups efficient and to ensure multiple continuous
+ * readers on a range don't starve a writer for the same range lock,
+ * two condition variables are allocated in each rl_t.
+ * If a writer (or reader) can't get a range it initialises the writer
+ * (or reader) cv; sets a flag saying there's a writer (or reader) waiting;
+ * and waits on that cv. When a thread unlocks that range it wakes up all
+ * writers then all readers before destroying the lock.
+ *
+ * Append mode writes
+ * ------------------
+ * Append mode writes need to lock a range at the end of a file.
+ * The offset of the end of the file is determined under the
+ * range locking mutex, and the lock type converted from RL_APPEND to
+ * RL_WRITER and the range locked.
+ *
+ * Grow block handling
+ * -------------------
+ * ZFS supports multiple block sizes currently upto 128K. The smallest
+ * block size is used for the file which is grown as needed. During this
+ * growth all other writers and readers must be excluded.
+ * So if the block size needs to be grown then the whole file is
+ * exclusively locked, then later the caller will reduce the lock
+ * range to just the range to be written using zfs_reduce_range.
+ */
+
+#include <sys/zfs_rlock.h>
+
+/*
+ * Check if a write lock can be grabbed, or wait and recheck until available.
+ */
+static void
+zfs_range_lock_writer(znode_t *zp, rl_t *new)
+{
+	avl_tree_t *tree = &zp->z_range_avl;
+	rl_t *rl;
+	avl_index_t where;
+	uint64_t end_size;
+	uint64_t off = new->r_off;
+	uint64_t len = new->r_len;
+
+	for (;;) {
+		/*
+		 * Range locking is also used by zvol and uses a
+		 * dummied up znode. However, for zvol, we don't need to
+		 * append or grow blocksize, and besides we don't have
+		 * a "sa" data or zfs_sb_t - so skip that processing.
+		 *
+		 * Yes, this is ugly, and would be solved by not handling
+		 * grow or append in range lock code. If that was done then
+		 * we could make the range locking code generically available
+		 * to other non-zfs consumers.
+		 */
+		if (!zp->z_is_zvol) { /* caller is ZPL */
+			/*
+			 * If in append mode pick up the current end of file.
+			 * This is done under z_range_lock to avoid races.
+			 */
+			if (new->r_type == RL_APPEND)
+				new->r_off = zp->z_size;
+
+			/*
+			 * If we need to grow the block size then grab the whole
+			 * file range. This is also done under z_range_lock to
+			 * avoid races.
+			 */
+			end_size = MAX(zp->z_size, new->r_off + len);
+			if (end_size > zp->z_blksz && (!ISP2(zp->z_blksz) ||
+			    zp->z_blksz < ZTOZSB(zp)->z_max_blksz)) {
+				new->r_off = 0;
+				new->r_len = UINT64_MAX;
+			}
+		}
+
+		/*
+		 * First check for the usual case of no locks
+		 */
+		if (avl_numnodes(tree) == 0) {
+			new->r_type = RL_WRITER; /* convert to writer */
+			avl_add(tree, new);
+			return;
+		}
+
+		/*
+		 * Look for any locks in the range.
+		 */
+		rl = avl_find(tree, new, &where);
+		if (rl)
+			goto wait; /* already locked at same offset */
+
+		rl = (rl_t *)avl_nearest(tree, where, AVL_AFTER);
+		if (rl && (rl->r_off < new->r_off + new->r_len))
+			goto wait;
+
+		rl = (rl_t *)avl_nearest(tree, where, AVL_BEFORE);
+		if (rl && rl->r_off + rl->r_len > new->r_off)
+			goto wait;
+
+		new->r_type = RL_WRITER; /* convert possible RL_APPEND */
+		avl_insert(tree, new, where);
+		return;
+wait:
+		if (!rl->r_write_wanted) {
+			cv_init(&rl->r_wr_cv, NULL, CV_DEFAULT, NULL);
+			rl->r_write_wanted = B_TRUE;
+		}
+		cv_wait(&rl->r_wr_cv, &zp->z_range_lock);
+
+		/* reset to original */
+		new->r_off = off;
+		new->r_len = len;
+	}
+}
+
+/*
+ * If this is an original (non-proxy) lock then replace it by
+ * a proxy and return the proxy.
+ */
+static rl_t *
+zfs_range_proxify(avl_tree_t *tree, rl_t *rl)
+{
+	rl_t *proxy;
+
+	if (rl->r_proxy)
+		return (rl); /* already a proxy */
+
+	ASSERT3U(rl->r_cnt, ==, 1);
+	ASSERT(rl->r_write_wanted == B_FALSE);
+	ASSERT(rl->r_read_wanted == B_FALSE);
+	avl_remove(tree, rl);
+	rl->r_cnt = 0;
+
+	/* create a proxy range lock */
+	proxy = kmem_alloc(sizeof (rl_t), KM_SLEEP);
+	proxy->r_off = rl->r_off;
+	proxy->r_len = rl->r_len;
+	proxy->r_cnt = 1;
+	proxy->r_type = RL_READER;
+	proxy->r_proxy = B_TRUE;
+	proxy->r_write_wanted = B_FALSE;
+	proxy->r_read_wanted = B_FALSE;
+	avl_add(tree, proxy);
+
+	return (proxy);
+}
+
+/*
+ * Split the range lock at the supplied offset
+ * returning the *front* proxy.
+ */
+static rl_t *
+zfs_range_split(avl_tree_t *tree, rl_t *rl, uint64_t off)
+{
+	rl_t *front, *rear;
+
+	ASSERT3U(rl->r_len, >, 1);
+	ASSERT3U(off, >, rl->r_off);
+	ASSERT3U(off, <, rl->r_off + rl->r_len);
+	ASSERT(rl->r_write_wanted == B_FALSE);
+	ASSERT(rl->r_read_wanted == B_FALSE);
+
+	/* create the rear proxy range lock */
+	rear = kmem_alloc(sizeof (rl_t), KM_SLEEP);
+	rear->r_off = off;
+	rear->r_len = rl->r_off + rl->r_len - off;
+	rear->r_cnt = rl->r_cnt;
+	rear->r_type = RL_READER;
+	rear->r_proxy = B_TRUE;
+	rear->r_write_wanted = B_FALSE;
+	rear->r_read_wanted = B_FALSE;
+
+	front = zfs_range_proxify(tree, rl);
+	front->r_len = off - rl->r_off;
+
+	avl_insert_here(tree, rear, front, AVL_AFTER);
+	return (front);
+}
+
+/*
+ * Create and add a new proxy range lock for the supplied range.
+ */
+static void
+zfs_range_new_proxy(avl_tree_t *tree, uint64_t off, uint64_t len)
+{
+	rl_t *rl;
+
+	ASSERT(len);
+	rl = kmem_alloc(sizeof (rl_t), KM_SLEEP);
+	rl->r_off = off;
+	rl->r_len = len;
+	rl->r_cnt = 1;
+	rl->r_type = RL_READER;
+	rl->r_proxy = B_TRUE;
+	rl->r_write_wanted = B_FALSE;
+	rl->r_read_wanted = B_FALSE;
+	avl_add(tree, rl);
+}
+
+static void
+zfs_range_add_reader(avl_tree_t *tree, rl_t *new, rl_t *prev, avl_index_t where)
+{
+	rl_t *next;
+	uint64_t off = new->r_off;
+	uint64_t len = new->r_len;
+
+	/*
+	 * prev arrives either:
+	 * - pointing to an entry at the same offset
+	 * - pointing to the entry with the closest previous offset whose
+	 *   range may overlap with the new range
+	 * - null, if there were no ranges starting before the new one
+	 */
+	if (prev) {
+		if (prev->r_off + prev->r_len <= off) {
+			prev = NULL;
+		} else if (prev->r_off != off) {
+			/*
+			 * convert to proxy if needed then
+			 * split this entry and bump ref count
+			 */
+			prev = zfs_range_split(tree, prev, off);
+			prev = AVL_NEXT(tree, prev); /* move to rear range */
+		}
+	}
+	ASSERT((prev == NULL) || (prev->r_off == off));
+
+	if (prev)
+		next = prev;
+	else
+		next = (rl_t *)avl_nearest(tree, where, AVL_AFTER);
+
+	if (next == NULL || off + len <= next->r_off) {
+		/* no overlaps, use the original new rl_t in the tree */
+		avl_insert(tree, new, where);
+		return;
+	}
+
+	if (off < next->r_off) {
+		/* Add a proxy for initial range before the overlap */
+		zfs_range_new_proxy(tree, off, next->r_off - off);
+	}
+
+	new->r_cnt = 0; /* will use proxies in tree */
+	/*
+	 * We now search forward through the ranges, until we go past the end
+	 * of the new range. For each entry we make it a proxy if it
+	 * isn't already, then bump its reference count. If there's any
+	 * gaps between the ranges then we create a new proxy range.
+	 */
+	for (prev = NULL; next; prev = next, next = AVL_NEXT(tree, next)) {
+		if (off + len <= next->r_off)
+			break;
+		if (prev && prev->r_off + prev->r_len < next->r_off) {
+			/* there's a gap */
+			ASSERT3U(next->r_off, >, prev->r_off + prev->r_len);
+			zfs_range_new_proxy(tree, prev->r_off + prev->r_len,
+			    next->r_off - (prev->r_off + prev->r_len));
+		}
+		if (off + len == next->r_off + next->r_len) {
+			/* exact overlap with end */
+			next = zfs_range_proxify(tree, next);
+			next->r_cnt++;
+			return;
+		}
+		if (off + len < next->r_off + next->r_len) {
+			/* new range ends in the middle of this block */
+			next = zfs_range_split(tree, next, off + len);
+			next->r_cnt++;
+			return;
+		}
+		ASSERT3U(off + len, >, next->r_off + next->r_len);
+		next = zfs_range_proxify(tree, next);
+		next->r_cnt++;
+	}
+
+	/* Add the remaining end range. */
+	zfs_range_new_proxy(tree, prev->r_off + prev->r_len,
+	    (off + len) - (prev->r_off + prev->r_len));
+}
+
+/*
+ * Check if a reader lock can be grabbed, or wait and recheck until available.
+ */
+static void
+zfs_range_lock_reader(znode_t *zp, rl_t *new)
+{
+	avl_tree_t *tree = &zp->z_range_avl;
+	rl_t *prev, *next;
+	avl_index_t where;
+	uint64_t off = new->r_off;
+	uint64_t len = new->r_len;
+
+	/*
+	 * Look for any writer locks in the range.
+	 */
+retry:
+	prev = avl_find(tree, new, &where);
+	if (prev == NULL)
+		prev = (rl_t *)avl_nearest(tree, where, AVL_BEFORE);
+
+	/*
+	 * Check the previous range for a writer lock overlap.
+	 */
+	if (prev && (off < prev->r_off + prev->r_len)) {
+		if ((prev->r_type == RL_WRITER) || (prev->r_write_wanted)) {
+			if (!prev->r_read_wanted) {
+				cv_init(&prev->r_rd_cv, NULL, CV_DEFAULT, NULL);
+				prev->r_read_wanted = B_TRUE;
+			}
+			cv_wait(&prev->r_rd_cv, &zp->z_range_lock);
+			goto retry;
+		}
+		if (off + len < prev->r_off + prev->r_len)
+			goto got_lock;
+	}
+
+	/*
+	 * Search through the following ranges to see if there's
+	 * write lock any overlap.
+	 */
+	if (prev)
+		next = AVL_NEXT(tree, prev);
+	else
+		next = (rl_t *)avl_nearest(tree, where, AVL_AFTER);
+	for (; next; next = AVL_NEXT(tree, next)) {
+		if (off + len <= next->r_off)
+			goto got_lock;
+		if ((next->r_type == RL_WRITER) || (next->r_write_wanted)) {
+			if (!next->r_read_wanted) {
+				cv_init(&next->r_rd_cv, NULL, CV_DEFAULT, NULL);
+				next->r_read_wanted = B_TRUE;
+			}
+			cv_wait(&next->r_rd_cv, &zp->z_range_lock);
+			goto retry;
+		}
+		if (off + len <= next->r_off + next->r_len)
+			goto got_lock;
+	}
+
+got_lock:
+	/*
+	 * Add the read lock, which may involve splitting existing
+	 * locks and bumping ref counts (r_cnt).
+	 */
+	zfs_range_add_reader(tree, new, prev, where);
+}
+
+/*
+ * Lock a range (offset, length) as either shared (RL_READER)
+ * or exclusive (RL_WRITER). Returns the range lock structure
+ * for later unlocking or reduce range (if entire file
+ * previously locked as RL_WRITER).
+ */
+rl_t *
+zfs_range_lock(znode_t *zp, uint64_t off, uint64_t len, rl_type_t type)
+{
+	rl_t *new;
+
+	ASSERT(type == RL_READER || type == RL_WRITER || type == RL_APPEND);
+
+	new = kmem_alloc(sizeof (rl_t), KM_SLEEP);
+	new->r_zp = zp;
+	new->r_off = off;
+	if (len + off < off)	/* overflow */
+		len = UINT64_MAX - off;
+	new->r_len = len;
+	new->r_cnt = 1; /* assume it's going to be in the tree */
+	new->r_type = type;
+	new->r_proxy = B_FALSE;
+	new->r_write_wanted = B_FALSE;
+	new->r_read_wanted = B_FALSE;
+
+	mutex_enter(&zp->z_range_lock);
+	if (type == RL_READER) {
+		/*
+		 * First check for the usual case of no locks
+		 */
+		if (avl_numnodes(&zp->z_range_avl) == 0)
+			avl_add(&zp->z_range_avl, new);
+		else
+			zfs_range_lock_reader(zp, new);
+	} else
+		zfs_range_lock_writer(zp, new); /* RL_WRITER or RL_APPEND */
+	mutex_exit(&zp->z_range_lock);
+	return (new);
+}
+
+static void
+zfs_range_free(void *arg)
+{
+	rl_t *rl = arg;
+
+	if (rl->r_write_wanted)
+		cv_destroy(&rl->r_wr_cv);
+
+	if (rl->r_read_wanted)
+		cv_destroy(&rl->r_rd_cv);
+
+	kmem_free(rl, sizeof (rl_t));
+}
+
+/*
+ * Unlock a reader lock
+ */
+static void
+zfs_range_unlock_reader(znode_t *zp, rl_t *remove, list_t *free_list)
+{
+	avl_tree_t *tree = &zp->z_range_avl;
+	rl_t *rl, *next = NULL;
+	uint64_t len;
+
+	/*
+	 * The common case is when the remove entry is in the tree
+	 * (cnt == 1) meaning there's been no other reader locks overlapping
+	 * with this one. Otherwise the remove entry will have been
+	 * removed from the tree and replaced by proxies (one or
+	 * more ranges mapping to the entire range).
+	 */
+	if (remove->r_cnt == 1) {
+		avl_remove(tree, remove);
+
+		if (remove->r_write_wanted)
+			cv_broadcast(&remove->r_wr_cv);
+
+		if (remove->r_read_wanted)
+			cv_broadcast(&remove->r_rd_cv);
+
+		list_insert_tail(free_list, remove);
+	} else {
+		ASSERT0(remove->r_cnt);
+		ASSERT0(remove->r_write_wanted);
+		ASSERT0(remove->r_read_wanted);
+		/*
+		 * Find start proxy representing this reader lock,
+		 * then decrement ref count on all proxies
+		 * that make up this range, freeing them as needed.
+		 */
+		rl = avl_find(tree, remove, NULL);
+		ASSERT(rl);
+		ASSERT(rl->r_cnt);
+		ASSERT(rl->r_type == RL_READER);
+		for (len = remove->r_len; len != 0; rl = next) {
+			len -= rl->r_len;
+			if (len) {
+				next = AVL_NEXT(tree, rl);
+				ASSERT(next);
+				ASSERT(rl->r_off + rl->r_len == next->r_off);
+				ASSERT(next->r_cnt);
+				ASSERT(next->r_type == RL_READER);
+			}
+			rl->r_cnt--;
+			if (rl->r_cnt == 0) {
+				avl_remove(tree, rl);
+
+				if (rl->r_write_wanted)
+					cv_broadcast(&rl->r_wr_cv);
+
+				if (rl->r_read_wanted)
+					cv_broadcast(&rl->r_rd_cv);
+
+				list_insert_tail(free_list, rl);
+			}
+		}
+
+		kmem_free(remove, sizeof (rl_t));
+	}
+}
+
+/*
+ * Unlock range and destroy range lock structure.
+ */
+void
+zfs_range_unlock(rl_t *rl)
+{
+	znode_t *zp = rl->r_zp;
+	list_t free_list;
+	rl_t *free_rl;
+
+	ASSERT(rl->r_type == RL_WRITER || rl->r_type == RL_READER);
+	ASSERT(rl->r_cnt == 1 || rl->r_cnt == 0);
+	ASSERT(!rl->r_proxy);
+	list_create(&free_list, sizeof (rl_t), offsetof(rl_t, rl_node));
+
+	mutex_enter(&zp->z_range_lock);
+	if (rl->r_type == RL_WRITER) {
+		/* writer locks can't be shared or split */
+		avl_remove(&zp->z_range_avl, rl);
+		if (rl->r_write_wanted)
+			cv_broadcast(&rl->r_wr_cv);
+
+		if (rl->r_read_wanted)
+			cv_broadcast(&rl->r_rd_cv);
+
+		list_insert_tail(&free_list, rl);
+	} else {
+		/*
+		 * lock may be shared, let zfs_range_unlock_reader()
+		 * release the zp->z_range_lock lock and free the rl_t
+		 */
+		zfs_range_unlock_reader(zp, rl, &free_list);
+	}
+	mutex_exit(&zp->z_range_lock);
+
+	while ((free_rl = list_head(&free_list)) != NULL) {
+		list_remove(&free_list, free_rl);
+		zfs_range_free(free_rl);
+	}
+
+	list_destroy(&free_list);
+}
+
+/*
+ * Reduce range locked as RL_WRITER from whole file to specified range.
+ * Asserts the whole file is exclusivly locked and so there's only one
+ * entry in the tree.
+ */
+void
+zfs_range_reduce(rl_t *rl, uint64_t off, uint64_t len)
+{
+	znode_t *zp = rl->r_zp;
+
+	/* Ensure there are no other locks */
+	ASSERT(avl_numnodes(&zp->z_range_avl) == 1);
+	ASSERT(rl->r_off == 0);
+	ASSERT(rl->r_type == RL_WRITER);
+	ASSERT(!rl->r_proxy);
+	ASSERT3U(rl->r_len, ==, UINT64_MAX);
+	ASSERT3U(rl->r_cnt, ==, 1);
+
+	mutex_enter(&zp->z_range_lock);
+	rl->r_off = off;
+	rl->r_len = len;
+
+	if (rl->r_write_wanted)
+		cv_broadcast(&rl->r_wr_cv);
+	if (rl->r_read_wanted)
+		cv_broadcast(&rl->r_rd_cv);
+
+	mutex_exit(&zp->z_range_lock);
+}
+
+/*
+ * AVL comparison function used to order range locks
+ * Locks are ordered on the start offset of the range.
+ */
+int
+zfs_range_compare(const void *arg1, const void *arg2)
+{
+	const rl_t *rl1 = arg1;
+	const rl_t *rl2 = arg2;
+
+	if (rl1->r_off > rl2->r_off)
+		return (1);
+	if (rl1->r_off < rl2->r_off)
+		return (-1);
+	return (0);
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/module/zfs/zfs_sa.c
@@ -0,0 +1,423 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ */
+
+#include <sys/zfs_context.h>
+#include <sys/vnode.h>
+#include <sys/sa.h>
+#include <sys/zfs_acl.h>
+#include <sys/zfs_sa.h>
+
+/*
+ * ZPL attribute registration table.
+ * Order of attributes doesn't matter
+ * a unique value will be assigned for each
+ * attribute that is file system specific
+ *
+ * This is just the set of ZPL attributes that this
+ * version of ZFS deals with natively.  The file system
+ * could have other attributes stored in files, but they will be
+ * ignored.  The SA framework will preserve them, just that
+ * this version of ZFS won't change or delete them.
+ */
+
+sa_attr_reg_t zfs_attr_table[ZPL_END+1] = {
+	{"ZPL_ATIME", sizeof (uint64_t) * 2, SA_UINT64_ARRAY, 0},
+	{"ZPL_MTIME", sizeof (uint64_t) * 2, SA_UINT64_ARRAY, 1},
+	{"ZPL_CTIME", sizeof (uint64_t) * 2, SA_UINT64_ARRAY, 2},
+	{"ZPL_CRTIME", sizeof (uint64_t) * 2, SA_UINT64_ARRAY, 3},
+	{"ZPL_GEN", sizeof (uint64_t), SA_UINT64_ARRAY, 4},
+	{"ZPL_MODE", sizeof (uint64_t), SA_UINT64_ARRAY, 5},
+	{"ZPL_SIZE", sizeof (uint64_t), SA_UINT64_ARRAY, 6},
+	{"ZPL_PARENT", sizeof (uint64_t), SA_UINT64_ARRAY, 7},
+	{"ZPL_LINKS", sizeof (uint64_t), SA_UINT64_ARRAY, 8},
+	{"ZPL_XATTR", sizeof (uint64_t), SA_UINT64_ARRAY, 9},
+	{"ZPL_RDEV", sizeof (uint64_t), SA_UINT64_ARRAY, 10},
+	{"ZPL_FLAGS", sizeof (uint64_t), SA_UINT64_ARRAY, 11},
+	{"ZPL_UID", sizeof (uint64_t), SA_UINT64_ARRAY, 12},
+	{"ZPL_GID", sizeof (uint64_t), SA_UINT64_ARRAY, 13},
+	{"ZPL_PAD", sizeof (uint64_t) * 4, SA_UINT64_ARRAY, 14},
+	{"ZPL_ZNODE_ACL", 88, SA_UINT8_ARRAY, 15},
+	{"ZPL_DACL_COUNT", sizeof (uint64_t), SA_UINT64_ARRAY, 0},
+	{"ZPL_SYMLINK", 0, SA_UINT8_ARRAY, 0},
+	{"ZPL_SCANSTAMP", 32, SA_UINT8_ARRAY, 0},
+	{"ZPL_DACL_ACES", 0, SA_ACL, 0},
+	{"ZPL_DXATTR", 0, SA_UINT8_ARRAY, 0},
+	{NULL, 0, 0, 0}
+};
+
+#ifdef _KERNEL
+int
+zfs_sa_readlink(znode_t *zp, uio_t *uio)
+{
+	dmu_buf_t *db = sa_get_db(zp->z_sa_hdl);
+	size_t bufsz;
+	int error;
+
+	bufsz = zp->z_size;
+	if (bufsz + ZFS_OLD_ZNODE_PHYS_SIZE <= db->db_size) {
+		error = uiomove((caddr_t)db->db_data +
+		    ZFS_OLD_ZNODE_PHYS_SIZE,
+		    MIN((size_t)bufsz, uio->uio_resid), UIO_READ, uio);
+	} else {
+		dmu_buf_t *dbp;
+		if ((error = dmu_buf_hold(ZTOZSB(zp)->z_os, zp->z_id,
+		    0, FTAG, &dbp, DMU_READ_NO_PREFETCH)) == 0) {
+			error = uiomove(dbp->db_data,
+			    MIN((size_t)bufsz, uio->uio_resid), UIO_READ, uio);
+			dmu_buf_rele(dbp, FTAG);
+		}
+	}
+	return (error);
+}
+
+void
+zfs_sa_symlink(znode_t *zp, char *link, int len, dmu_tx_t *tx)
+{
+	dmu_buf_t *db = sa_get_db(zp->z_sa_hdl);
+
+	if (ZFS_OLD_ZNODE_PHYS_SIZE + len <= dmu_bonus_max()) {
+		VERIFY(dmu_set_bonus(db,
+		    len + ZFS_OLD_ZNODE_PHYS_SIZE, tx) == 0);
+		if (len) {
+			bcopy(link, (caddr_t)db->db_data +
+			    ZFS_OLD_ZNODE_PHYS_SIZE, len);
+		}
+	} else {
+		dmu_buf_t *dbp;
+
+		zfs_grow_blocksize(zp, len, tx);
+		VERIFY(0 == dmu_buf_hold(ZTOZSB(zp)->z_os,
+		    zp->z_id, 0, FTAG, &dbp, DMU_READ_NO_PREFETCH));
+
+		dmu_buf_will_dirty(dbp, tx);
+
+		ASSERT3U(len, <=, dbp->db_size);
+		bcopy(link, dbp->db_data, len);
+		dmu_buf_rele(dbp, FTAG);
+	}
+}
+
+void
+zfs_sa_get_scanstamp(znode_t *zp, xvattr_t *xvap)
+{
+	zfs_sb_t *zsb = ZTOZSB(zp);
+	xoptattr_t *xoap;
+
+	ASSERT(MUTEX_HELD(&zp->z_lock));
+	VERIFY((xoap = xva_getxoptattr(xvap)) != NULL);
+	if (zp->z_is_sa) {
+		if (sa_lookup(zp->z_sa_hdl, SA_ZPL_SCANSTAMP(zsb),
+		    &xoap->xoa_av_scanstamp,
+		    sizeof (xoap->xoa_av_scanstamp)) != 0)
+			return;
+	} else {
+		dmu_object_info_t doi;
+		dmu_buf_t *db = sa_get_db(zp->z_sa_hdl);
+		int len;
+
+		if (!(zp->z_pflags & ZFS_BONUS_SCANSTAMP))
+			return;
+
+		sa_object_info(zp->z_sa_hdl, &doi);
+		len = sizeof (xoap->xoa_av_scanstamp) +
+		    ZFS_OLD_ZNODE_PHYS_SIZE;
+
+		if (len <= doi.doi_bonus_size) {
+			(void) memcpy(xoap->xoa_av_scanstamp,
+			    (caddr_t)db->db_data + ZFS_OLD_ZNODE_PHYS_SIZE,
+			    sizeof (xoap->xoa_av_scanstamp));
+		}
+	}
+	XVA_SET_RTN(xvap, XAT_AV_SCANSTAMP);
+}
+
+void
+zfs_sa_set_scanstamp(znode_t *zp, xvattr_t *xvap, dmu_tx_t *tx)
+{
+	zfs_sb_t *zsb = ZTOZSB(zp);
+	xoptattr_t *xoap;
+
+	ASSERT(MUTEX_HELD(&zp->z_lock));
+	VERIFY((xoap = xva_getxoptattr(xvap)) != NULL);
+	if (zp->z_is_sa)
+		VERIFY(0 == sa_update(zp->z_sa_hdl, SA_ZPL_SCANSTAMP(zsb),
+		    &xoap->xoa_av_scanstamp,
+		    sizeof (xoap->xoa_av_scanstamp), tx));
+	else {
+		dmu_object_info_t doi;
+		dmu_buf_t *db = sa_get_db(zp->z_sa_hdl);
+		int len;
+
+		sa_object_info(zp->z_sa_hdl, &doi);
+		len = sizeof (xoap->xoa_av_scanstamp) +
+		    ZFS_OLD_ZNODE_PHYS_SIZE;
+		if (len > doi.doi_bonus_size)
+			VERIFY(dmu_set_bonus(db, len, tx) == 0);
+		(void) memcpy((caddr_t)db->db_data + ZFS_OLD_ZNODE_PHYS_SIZE,
+		    xoap->xoa_av_scanstamp, sizeof (xoap->xoa_av_scanstamp));
+
+		zp->z_pflags |= ZFS_BONUS_SCANSTAMP;
+		VERIFY(0 == sa_update(zp->z_sa_hdl, SA_ZPL_FLAGS(zsb),
+		    &zp->z_pflags, sizeof (uint64_t), tx));
+	}
+}
+
+int
+zfs_sa_get_xattr(znode_t *zp)
+{
+	zfs_sb_t *zsb = ZTOZSB(zp);
+	char *obj;
+	int size;
+	int error;
+
+	ASSERT(RW_LOCK_HELD(&zp->z_xattr_lock));
+	ASSERT(!zp->z_xattr_cached);
+	ASSERT(zp->z_is_sa);
+
+	error = sa_size(zp->z_sa_hdl, SA_ZPL_DXATTR(zsb), &size);
+	if (error) {
+		if (error == ENOENT)
+			return nvlist_alloc(&zp->z_xattr_cached,
+			    NV_UNIQUE_NAME, KM_SLEEP);
+		else
+			return (error);
+	}
+
+	obj = zio_buf_alloc(size);
+
+	error = sa_lookup(zp->z_sa_hdl, SA_ZPL_DXATTR(zsb), obj, size);
+	if (error == 0)
+		error = nvlist_unpack(obj, size, &zp->z_xattr_cached, KM_SLEEP);
+
+	zio_buf_free(obj, size);
+
+	return (error);
+}
+
+int
+zfs_sa_set_xattr(znode_t *zp)
+{
+	zfs_sb_t *zsb = ZTOZSB(zp);
+	dmu_tx_t *tx;
+	char *obj;
+	size_t size;
+	int error;
+
+	ASSERT(RW_WRITE_HELD(&zp->z_xattr_lock));
+	ASSERT(zp->z_xattr_cached);
+	ASSERT(zp->z_is_sa);
+
+	error = nvlist_size(zp->z_xattr_cached, &size, NV_ENCODE_XDR);
+	if ((error == 0) && (size > SA_ATTR_MAX_LEN))
+		error = EFBIG;
+	if (error)
+		goto out;
+
+	obj = zio_buf_alloc(size);
+
+	error = nvlist_pack(zp->z_xattr_cached, &obj, &size,
+	    NV_ENCODE_XDR, KM_SLEEP);
+	if (error)
+		goto out_free;
+
+	tx = dmu_tx_create(zsb->z_os);
+	dmu_tx_hold_sa_create(tx, size);
+	dmu_tx_hold_sa(tx, zp->z_sa_hdl, B_TRUE);
+
+	error = dmu_tx_assign(tx, TXG_WAIT);
+	if (error) {
+		dmu_tx_abort(tx);
+	} else {
+		VERIFY0(sa_update(zp->z_sa_hdl, SA_ZPL_DXATTR(zsb),
+		    obj, size, tx));
+		dmu_tx_commit(tx);
+	}
+out_free:
+	zio_buf_free(obj, size);
+out:
+	return (error);
+}
+
+/*
+ * I'm not convinced we should do any of this upgrade.
+ * since the SA code can read both old/new znode formats
+ * with probably little to no performance difference.
+ *
+ * All new files will be created with the new format.
+ */
+
+void
+zfs_sa_upgrade(sa_handle_t *hdl, dmu_tx_t *tx)
+{
+	dmu_buf_t *db = sa_get_db(hdl);
+	znode_t *zp = sa_get_userdata(hdl);
+	zfs_sb_t *zsb = ZTOZSB(zp);
+	int count = 0;
+	sa_bulk_attr_t *bulk, *sa_attrs;
+	zfs_acl_locator_cb_t locate = { 0 };
+	uint64_t uid, gid, mode, rdev, xattr, parent;
+	uint64_t crtime[2], mtime[2], ctime[2];
+	zfs_acl_phys_t znode_acl;
+	char scanstamp[AV_SCANSTAMP_SZ];
+	boolean_t drop_lock = B_FALSE;
+
+	/*
+	 * No upgrade if ACL isn't cached
+	 * since we won't know which locks are held
+	 * and ready the ACL would require special "locked"
+	 * interfaces that would be messy
+	 */
+	if (zp->z_acl_cached == NULL || S_ISLNK(ZTOI(zp)->i_mode))
+		return;
+
+	/*
+	 * If the z_lock is held and we aren't the owner
+	 * the just return since we don't want to deadlock
+	 * trying to update the status of z_is_sa.  This
+	 * file can then be upgraded at a later time.
+	 *
+	 * Otherwise, we know we are doing the
+	 * sa_update() that caused us to enter this function.
+	 */
+	if (mutex_owner(&zp->z_lock) != curthread) {
+		if (mutex_tryenter(&zp->z_lock) == 0)
+			return;
+		else
+			drop_lock = B_TRUE;
+	}
+
+	/* First do a bulk query of the attributes that aren't cached */
+	bulk = kmem_alloc(sizeof (sa_bulk_attr_t) * 20, KM_SLEEP);
+	SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_MTIME(zsb), NULL, &mtime, 16);
+	SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_CTIME(zsb), NULL, &ctime, 16);
+	SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_CRTIME(zsb), NULL, &crtime, 16);
+	SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_MODE(zsb), NULL, &mode, 8);
+	SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_PARENT(zsb), NULL, &parent, 8);
+	SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_XATTR(zsb), NULL, &xattr, 8);
+	SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_RDEV(zsb), NULL, &rdev, 8);
+	SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_UID(zsb), NULL, &uid, 8);
+	SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_GID(zsb), NULL, &gid, 8);
+	SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_ZNODE_ACL(zsb), NULL,
+	    &znode_acl, 88);
+
+	if (sa_bulk_lookup_locked(hdl, bulk, count) != 0) {
+		kmem_free(bulk, sizeof (sa_bulk_attr_t) * 20);
+		goto done;
+	}
+
+	/*
+	 * While the order here doesn't matter its best to try and organize
+	 * it is such a way to pick up an already existing layout number
+	 */
+	count = 0;
+	sa_attrs = kmem_zalloc(sizeof (sa_bulk_attr_t) * 20, KM_SLEEP);
+	SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_MODE(zsb), NULL, &mode, 8);
+	SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_SIZE(zsb), NULL,
+	    &zp->z_size, 8);
+	SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_GEN(zsb),
+	    NULL, &zp->z_gen, 8);
+	SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_UID(zsb), NULL, &uid, 8);
+	SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_GID(zsb), NULL, &gid, 8);
+	SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_PARENT(zsb),
+	    NULL, &parent, 8);
+	SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_FLAGS(zsb), NULL,
+	    &zp->z_pflags, 8);
+	SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_ATIME(zsb), NULL,
+	    zp->z_atime, 16);
+	SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_MTIME(zsb), NULL,
+	    &mtime, 16);
+	SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_CTIME(zsb), NULL,
+	    &ctime, 16);
+	SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_CRTIME(zsb), NULL,
+	    &crtime, 16);
+	SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_LINKS(zsb), NULL,
+	    &zp->z_links, 8);
+	if (S_ISBLK(ZTOI(zp)->i_mode) || S_ISCHR(ZTOI(zp)->i_mode))
+		SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_RDEV(zsb), NULL,
+		    &rdev, 8);
+	SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_DACL_COUNT(zsb), NULL,
+	    &zp->z_acl_cached->z_acl_count, 8);
+
+	if (zp->z_acl_cached->z_version < ZFS_ACL_VERSION_FUID)
+		zfs_acl_xform(zp, zp->z_acl_cached, CRED());
+
+	locate.cb_aclp = zp->z_acl_cached;
+	SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_DACL_ACES(zsb),
+	    zfs_acl_data_locator, &locate, zp->z_acl_cached->z_acl_bytes);
+
+	if (xattr)
+		SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_XATTR(zsb),
+		    NULL, &xattr, 8);
+
+	/* if scanstamp then add scanstamp */
+
+	if (zp->z_pflags & ZFS_BONUS_SCANSTAMP) {
+		bcopy((caddr_t)db->db_data + ZFS_OLD_ZNODE_PHYS_SIZE,
+		    scanstamp, AV_SCANSTAMP_SZ);
+		SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_SCANSTAMP(zsb),
+		    NULL, scanstamp, AV_SCANSTAMP_SZ);
+		zp->z_pflags &= ~ZFS_BONUS_SCANSTAMP;
+	}
+
+	VERIFY(dmu_set_bonustype(db, DMU_OT_SA, tx) == 0);
+	VERIFY(sa_replace_all_by_template_locked(hdl, sa_attrs,
+	    count, tx) == 0);
+	if (znode_acl.z_acl_extern_obj)
+		VERIFY(0 == dmu_object_free(zsb->z_os,
+		    znode_acl.z_acl_extern_obj, tx));
+
+	zp->z_is_sa = B_TRUE;
+	kmem_free(sa_attrs, sizeof (sa_bulk_attr_t) * 20);
+	kmem_free(bulk, sizeof (sa_bulk_attr_t) * 20);
+done:
+	if (drop_lock)
+		mutex_exit(&zp->z_lock);
+}
+
+void
+zfs_sa_upgrade_txholds(dmu_tx_t *tx, znode_t *zp)
+{
+	if (!ZTOZSB(zp)->z_use_sa || zp->z_is_sa)
+		return;
+
+
+	dmu_tx_hold_sa(tx, zp->z_sa_hdl, B_TRUE);
+
+	if (zfs_external_acl(zp)) {
+		dmu_tx_hold_free(tx, zfs_external_acl(zp), 0,
+		    DMU_OBJECT_END);
+	}
+}
+
+EXPORT_SYMBOL(zfs_attr_table);
+EXPORT_SYMBOL(zfs_sa_readlink);
+EXPORT_SYMBOL(zfs_sa_symlink);
+EXPORT_SYMBOL(zfs_sa_get_scanstamp);
+EXPORT_SYMBOL(zfs_sa_set_scanstamp);
+EXPORT_SYMBOL(zfs_sa_get_xattr);
+EXPORT_SYMBOL(zfs_sa_set_xattr);
+EXPORT_SYMBOL(zfs_sa_upgrade);
+EXPORT_SYMBOL(zfs_sa_upgrade_txholds);
+
+#endif
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/module/zfs/zfs_vfsops.c
@@ -0,0 +1,1865 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013 by Delphix. All rights reserved.
+ */
+
+/* Portions Copyright 2010 Robert Milkowski */
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/sysmacros.h>
+#include <sys/kmem.h>
+#include <sys/pathname.h>
+#include <sys/vnode.h>
+#include <sys/vfs.h>
+#include <sys/vfs_opreg.h>
+#include <sys/mntent.h>
+#include <sys/mount.h>
+#include <sys/cmn_err.h>
+#include "fs/fs_subr.h"
+#include <sys/zfs_znode.h>
+#include <sys/zfs_vnops.h>
+#include <sys/zfs_dir.h>
+#include <sys/zil.h>
+#include <sys/fs/zfs.h>
+#include <sys/dmu.h>
+#include <sys/dsl_prop.h>
+#include <sys/dsl_dataset.h>
+#include <sys/dsl_deleg.h>
+#include <sys/spa.h>
+#include <sys/zap.h>
+#include <sys/sa.h>
+#include <sys/sa_impl.h>
+#include <sys/varargs.h>
+#include <sys/policy.h>
+#include <sys/atomic.h>
+#include <sys/mkdev.h>
+#include <sys/modctl.h>
+#include <sys/refstr.h>
+#include <sys/zfs_ioctl.h>
+#include <sys/zfs_ctldir.h>
+#include <sys/zfs_fuid.h>
+#include <sys/bootconf.h>
+#include <sys/sunddi.h>
+#include <sys/dnlc.h>
+#include <sys/dmu_objset.h>
+#include <sys/spa_boot.h>
+#include <sys/zpl.h>
+#include "zfs_comutil.h"
+
+/*ARGSUSED*/
+int
+zfs_sync(struct super_block *sb, int wait, cred_t *cr)
+{
+	zfs_sb_t *zsb = sb->s_fs_info;
+
+	/*
+	 * Data integrity is job one.  We don't want a compromised kernel
+	 * writing to the storage pool, so we never sync during panic.
+	 */
+	if (unlikely(oops_in_progress))
+		return (0);
+
+	/*
+	 * Semantically, the only requirement is that the sync be initiated.
+	 * The DMU syncs out txgs frequently, so there's nothing to do.
+	 */
+	if (!wait)
+		return (0);
+
+	if (zsb != NULL) {
+		/*
+		 * Sync a specific filesystem.
+		 */
+		dsl_pool_t *dp;
+
+		ZFS_ENTER(zsb);
+		dp = dmu_objset_pool(zsb->z_os);
+
+		/*
+		 * If the system is shutting down, then skip any
+		 * filesystems which may exist on a suspended pool.
+		 */
+		if (spa_suspended(dp->dp_spa)) {
+			ZFS_EXIT(zsb);
+			return (0);
+		}
+
+		if (zsb->z_log != NULL)
+			zil_commit(zsb->z_log, 0);
+
+		ZFS_EXIT(zsb);
+	} else {
+		/*
+		 * Sync all ZFS filesystems.  This is what happens when you
+		 * run sync(1M).  Unlike other filesystems, ZFS honors the
+		 * request by waiting for all pools to commit all dirty data.
+		 */
+		spa_sync_allpools();
+	}
+
+	return (0);
+}
+EXPORT_SYMBOL(zfs_sync);
+
+boolean_t
+zfs_is_readonly(zfs_sb_t *zsb)
+{
+	return (!!(zsb->z_sb->s_flags & MS_RDONLY));
+}
+EXPORT_SYMBOL(zfs_is_readonly);
+
+static void
+atime_changed_cb(void *arg, uint64_t newval)
+{
+	((zfs_sb_t *)arg)->z_atime = newval;
+}
+
+static void
+relatime_changed_cb(void *arg, uint64_t newval)
+{
+	((zfs_sb_t *)arg)->z_relatime = newval;
+}
+
+static void
+xattr_changed_cb(void *arg, uint64_t newval)
+{
+	zfs_sb_t *zsb = arg;
+
+	if (newval == ZFS_XATTR_OFF) {
+		zsb->z_flags &= ~ZSB_XATTR;
+	} else {
+		zsb->z_flags |= ZSB_XATTR;
+
+		if (newval == ZFS_XATTR_SA)
+			zsb->z_xattr_sa = B_TRUE;
+		else
+			zsb->z_xattr_sa = B_FALSE;
+	}
+}
+
+static void
+acltype_changed_cb(void *arg, uint64_t newval)
+{
+	zfs_sb_t *zsb = arg;
+
+	switch (newval) {
+	case ZFS_ACLTYPE_OFF:
+		zsb->z_acl_type = ZFS_ACLTYPE_OFF;
+		zsb->z_sb->s_flags &= ~MS_POSIXACL;
+		break;
+	case ZFS_ACLTYPE_POSIXACL:
+#ifdef CONFIG_FS_POSIX_ACL
+		zsb->z_acl_type = ZFS_ACLTYPE_POSIXACL;
+		zsb->z_sb->s_flags |= MS_POSIXACL;
+#else
+		zsb->z_acl_type = ZFS_ACLTYPE_OFF;
+		zsb->z_sb->s_flags &= ~MS_POSIXACL;
+#endif /* CONFIG_FS_POSIX_ACL */
+		break;
+	default:
+		break;
+	}
+}
+
+static void
+blksz_changed_cb(void *arg, uint64_t newval)
+{
+	zfs_sb_t *zsb = arg;
+	ASSERT3U(newval, <=, spa_maxblocksize(dmu_objset_spa(zsb->z_os)));
+	ASSERT3U(newval, >=, SPA_MINBLOCKSIZE);
+	ASSERT(ISP2(newval));
+
+	zsb->z_max_blksz = newval;
+}
+
+static void
+readonly_changed_cb(void *arg, uint64_t newval)
+{
+	zfs_sb_t *zsb = arg;
+	struct super_block *sb = zsb->z_sb;
+
+	if (sb == NULL)
+		return;
+
+	if (newval)
+		sb->s_flags |= MS_RDONLY;
+	else
+		sb->s_flags &= ~MS_RDONLY;
+}
+
+static void
+devices_changed_cb(void *arg, uint64_t newval)
+{
+}
+
+static void
+setuid_changed_cb(void *arg, uint64_t newval)
+{
+}
+
+static void
+exec_changed_cb(void *arg, uint64_t newval)
+{
+}
+
+static void
+nbmand_changed_cb(void *arg, uint64_t newval)
+{
+	zfs_sb_t *zsb = arg;
+	struct super_block *sb = zsb->z_sb;
+
+	if (sb == NULL)
+		return;
+
+	if (newval == TRUE)
+		sb->s_flags |= MS_MANDLOCK;
+	else
+		sb->s_flags &= ~MS_MANDLOCK;
+}
+
+static void
+snapdir_changed_cb(void *arg, uint64_t newval)
+{
+	((zfs_sb_t *)arg)->z_show_ctldir = newval;
+}
+
+static void
+vscan_changed_cb(void *arg, uint64_t newval)
+{
+	((zfs_sb_t *)arg)->z_vscan = newval;
+}
+
+static void
+acl_inherit_changed_cb(void *arg, uint64_t newval)
+{
+	((zfs_sb_t *)arg)->z_acl_inherit = newval;
+}
+
+int
+zfs_register_callbacks(zfs_sb_t *zsb)
+{
+	struct dsl_dataset *ds = NULL;
+	objset_t *os = zsb->z_os;
+	zfs_mntopts_t *zmo = zsb->z_mntopts;
+	int error = 0;
+
+	ASSERT(zsb);
+	ASSERT(zmo);
+
+	/*
+	 * The act of registering our callbacks will destroy any mount
+	 * options we may have.  In order to enable temporary overrides
+	 * of mount options, we stash away the current values and
+	 * restore them after we register the callbacks.
+	 */
+	if (zfs_is_readonly(zsb) || !spa_writeable(dmu_objset_spa(os))) {
+		zmo->z_do_readonly = B_TRUE;
+		zmo->z_readonly = B_TRUE;
+	}
+
+	/*
+	 * Register property callbacks.
+	 *
+	 * It would probably be fine to just check for i/o error from
+	 * the first prop_register(), but I guess I like to go
+	 * overboard...
+	 */
+	ds = dmu_objset_ds(os);
+	dsl_pool_config_enter(dmu_objset_pool(os), FTAG);
+	error = dsl_prop_register(ds,
+	    zfs_prop_to_name(ZFS_PROP_ATIME), atime_changed_cb, zsb);
+	error = error ? error : dsl_prop_register(ds,
+	    zfs_prop_to_name(ZFS_PROP_RELATIME), relatime_changed_cb, zsb);
+	error = error ? error : dsl_prop_register(ds,
+	    zfs_prop_to_name(ZFS_PROP_XATTR), xattr_changed_cb, zsb);
+	error = error ? error : dsl_prop_register(ds,
+	    zfs_prop_to_name(ZFS_PROP_RECORDSIZE), blksz_changed_cb, zsb);
+	error = error ? error : dsl_prop_register(ds,
+	    zfs_prop_to_name(ZFS_PROP_READONLY), readonly_changed_cb, zsb);
+	error = error ? error : dsl_prop_register(ds,
+	    zfs_prop_to_name(ZFS_PROP_DEVICES), devices_changed_cb, zsb);
+	error = error ? error : dsl_prop_register(ds,
+	    zfs_prop_to_name(ZFS_PROP_SETUID), setuid_changed_cb, zsb);
+	error = error ? error : dsl_prop_register(ds,
+	    zfs_prop_to_name(ZFS_PROP_EXEC), exec_changed_cb, zsb);
+	error = error ? error : dsl_prop_register(ds,
+	    zfs_prop_to_name(ZFS_PROP_SNAPDIR), snapdir_changed_cb, zsb);
+	error = error ? error : dsl_prop_register(ds,
+	    zfs_prop_to_name(ZFS_PROP_ACLTYPE), acltype_changed_cb, zsb);
+	error = error ? error : dsl_prop_register(ds,
+	    zfs_prop_to_name(ZFS_PROP_ACLINHERIT), acl_inherit_changed_cb, zsb);
+	error = error ? error : dsl_prop_register(ds,
+	    zfs_prop_to_name(ZFS_PROP_VSCAN), vscan_changed_cb, zsb);
+	error = error ? error : dsl_prop_register(ds,
+	    zfs_prop_to_name(ZFS_PROP_NBMAND), nbmand_changed_cb, zsb);
+	dsl_pool_config_exit(dmu_objset_pool(os), FTAG);
+	if (error)
+		goto unregister;
+
+	/*
+	 * Invoke our callbacks to restore temporary mount options.
+	 */
+	if (zmo->z_do_readonly)
+		readonly_changed_cb(zsb, zmo->z_readonly);
+	if (zmo->z_do_setuid)
+		setuid_changed_cb(zsb, zmo->z_setuid);
+	if (zmo->z_do_exec)
+		exec_changed_cb(zsb, zmo->z_exec);
+	if (zmo->z_do_devices)
+		devices_changed_cb(zsb, zmo->z_devices);
+	if (zmo->z_do_xattr)
+		xattr_changed_cb(zsb, zmo->z_xattr);
+	if (zmo->z_do_atime)
+		atime_changed_cb(zsb, zmo->z_atime);
+	if (zmo->z_do_relatime)
+		relatime_changed_cb(zsb, zmo->z_relatime);
+	if (zmo->z_do_nbmand)
+		nbmand_changed_cb(zsb, zmo->z_nbmand);
+
+	return (0);
+
+unregister:
+	/*
+	 * We may attempt to unregister some callbacks that are not
+	 * registered, but this is OK; it will simply return ENOMSG,
+	 * which we will ignore.
+	 */
+	(void) dsl_prop_unregister(ds, zfs_prop_to_name(ZFS_PROP_ATIME),
+	    atime_changed_cb, zsb);
+	(void) dsl_prop_unregister(ds, zfs_prop_to_name(ZFS_PROP_RELATIME),
+	    relatime_changed_cb, zsb);
+	(void) dsl_prop_unregister(ds, zfs_prop_to_name(ZFS_PROP_XATTR),
+	    xattr_changed_cb, zsb);
+	(void) dsl_prop_unregister(ds, zfs_prop_to_name(ZFS_PROP_RECORDSIZE),
+	    blksz_changed_cb, zsb);
+	(void) dsl_prop_unregister(ds, zfs_prop_to_name(ZFS_PROP_READONLY),
+	    readonly_changed_cb, zsb);
+	(void) dsl_prop_unregister(ds, zfs_prop_to_name(ZFS_PROP_DEVICES),
+	    devices_changed_cb, zsb);
+	(void) dsl_prop_unregister(ds, zfs_prop_to_name(ZFS_PROP_SETUID),
+	    setuid_changed_cb, zsb);
+	(void) dsl_prop_unregister(ds, zfs_prop_to_name(ZFS_PROP_EXEC),
+	    exec_changed_cb, zsb);
+	(void) dsl_prop_unregister(ds, zfs_prop_to_name(ZFS_PROP_SNAPDIR),
+	    snapdir_changed_cb, zsb);
+	(void) dsl_prop_unregister(ds, zfs_prop_to_name(ZFS_PROP_ACLTYPE),
+	    acltype_changed_cb, zsb);
+	(void) dsl_prop_unregister(ds, zfs_prop_to_name(ZFS_PROP_ACLINHERIT),
+	    acl_inherit_changed_cb, zsb);
+	(void) dsl_prop_unregister(ds, zfs_prop_to_name(ZFS_PROP_VSCAN),
+	    vscan_changed_cb, zsb);
+	(void) dsl_prop_unregister(ds, zfs_prop_to_name(ZFS_PROP_NBMAND),
+	    nbmand_changed_cb, zsb);
+
+	return (error);
+}
+EXPORT_SYMBOL(zfs_register_callbacks);
+
+static int
+zfs_space_delta_cb(dmu_object_type_t bonustype, void *data,
+    uint64_t *userp, uint64_t *groupp)
+{
+	/*
+	 * Is it a valid type of object to track?
+	 */
+	if (bonustype != DMU_OT_ZNODE && bonustype != DMU_OT_SA)
+		return (SET_ERROR(ENOENT));
+
+	/*
+	 * If we have a NULL data pointer
+	 * then assume the id's aren't changing and
+	 * return EEXIST to the dmu to let it know to
+	 * use the same ids
+	 */
+	if (data == NULL)
+		return (SET_ERROR(EEXIST));
+
+	if (bonustype == DMU_OT_ZNODE) {
+		znode_phys_t *znp = data;
+		*userp = znp->zp_uid;
+		*groupp = znp->zp_gid;
+	} else {
+		int hdrsize;
+		sa_hdr_phys_t *sap = data;
+		sa_hdr_phys_t sa = *sap;
+		boolean_t swap = B_FALSE;
+
+		ASSERT(bonustype == DMU_OT_SA);
+
+		if (sa.sa_magic == 0) {
+			/*
+			 * This should only happen for newly created
+			 * files that haven't had the znode data filled
+			 * in yet.
+			 */
+			*userp = 0;
+			*groupp = 0;
+			return (0);
+		}
+		if (sa.sa_magic == BSWAP_32(SA_MAGIC)) {
+			sa.sa_magic = SA_MAGIC;
+			sa.sa_layout_info = BSWAP_16(sa.sa_layout_info);
+			swap = B_TRUE;
+		} else {
+			VERIFY3U(sa.sa_magic, ==, SA_MAGIC);
+		}
+
+		hdrsize = sa_hdrsize(&sa);
+		VERIFY3U(hdrsize, >=, sizeof (sa_hdr_phys_t));
+		*userp = *((uint64_t *)((uintptr_t)data + hdrsize +
+		    SA_UID_OFFSET));
+		*groupp = *((uint64_t *)((uintptr_t)data + hdrsize +
+		    SA_GID_OFFSET));
+		if (swap) {
+			*userp = BSWAP_64(*userp);
+			*groupp = BSWAP_64(*groupp);
+		}
+	}
+	return (0);
+}
+
+static void
+fuidstr_to_sid(zfs_sb_t *zsb, const char *fuidstr,
+    char *domainbuf, int buflen, uid_t *ridp)
+{
+	uint64_t fuid;
+	const char *domain;
+
+	fuid = strtonum(fuidstr, NULL);
+
+	domain = zfs_fuid_find_by_idx(zsb, FUID_INDEX(fuid));
+	if (domain)
+		(void) strlcpy(domainbuf, domain, buflen);
+	else
+		domainbuf[0] = '\0';
+	*ridp = FUID_RID(fuid);
+}
+
+static uint64_t
+zfs_userquota_prop_to_obj(zfs_sb_t *zsb, zfs_userquota_prop_t type)
+{
+	switch (type) {
+	case ZFS_PROP_USERUSED:
+		return (DMU_USERUSED_OBJECT);
+	case ZFS_PROP_GROUPUSED:
+		return (DMU_GROUPUSED_OBJECT);
+	case ZFS_PROP_USERQUOTA:
+		return (zsb->z_userquota_obj);
+	case ZFS_PROP_GROUPQUOTA:
+		return (zsb->z_groupquota_obj);
+	default:
+		return (SET_ERROR(ENOTSUP));
+	}
+	return (0);
+}
+
+int
+zfs_userspace_many(zfs_sb_t *zsb, zfs_userquota_prop_t type,
+    uint64_t *cookiep, void *vbuf, uint64_t *bufsizep)
+{
+	int error;
+	zap_cursor_t zc;
+	zap_attribute_t za;
+	zfs_useracct_t *buf = vbuf;
+	uint64_t obj;
+
+	if (!dmu_objset_userspace_present(zsb->z_os))
+		return (SET_ERROR(ENOTSUP));
+
+	obj = zfs_userquota_prop_to_obj(zsb, type);
+	if (obj == 0) {
+		*bufsizep = 0;
+		return (0);
+	}
+
+	for (zap_cursor_init_serialized(&zc, zsb->z_os, obj, *cookiep);
+	    (error = zap_cursor_retrieve(&zc, &za)) == 0;
+	    zap_cursor_advance(&zc)) {
+		if ((uintptr_t)buf - (uintptr_t)vbuf + sizeof (zfs_useracct_t) >
+		    *bufsizep)
+			break;
+
+		fuidstr_to_sid(zsb, za.za_name,
+		    buf->zu_domain, sizeof (buf->zu_domain), &buf->zu_rid);
+
+		buf->zu_space = za.za_first_integer;
+		buf++;
+	}
+	if (error == ENOENT)
+		error = 0;
+
+	ASSERT3U((uintptr_t)buf - (uintptr_t)vbuf, <=, *bufsizep);
+	*bufsizep = (uintptr_t)buf - (uintptr_t)vbuf;
+	*cookiep = zap_cursor_serialize(&zc);
+	zap_cursor_fini(&zc);
+	return (error);
+}
+EXPORT_SYMBOL(zfs_userspace_many);
+
+/*
+ * buf must be big enough (eg, 32 bytes)
+ */
+static int
+id_to_fuidstr(zfs_sb_t *zsb, const char *domain, uid_t rid,
+    char *buf, boolean_t addok)
+{
+	uint64_t fuid;
+	int domainid = 0;
+
+	if (domain && domain[0]) {
+		domainid = zfs_fuid_find_by_domain(zsb, domain, NULL, addok);
+		if (domainid == -1)
+			return (SET_ERROR(ENOENT));
+	}
+	fuid = FUID_ENCODE(domainid, rid);
+	(void) sprintf(buf, "%llx", (longlong_t)fuid);
+	return (0);
+}
+
+int
+zfs_userspace_one(zfs_sb_t *zsb, zfs_userquota_prop_t type,
+    const char *domain, uint64_t rid, uint64_t *valp)
+{
+	char buf[32];
+	int err;
+	uint64_t obj;
+
+	*valp = 0;
+
+	if (!dmu_objset_userspace_present(zsb->z_os))
+		return (SET_ERROR(ENOTSUP));
+
+	obj = zfs_userquota_prop_to_obj(zsb, type);
+	if (obj == 0)
+		return (0);
+
+	err = id_to_fuidstr(zsb, domain, rid, buf, B_FALSE);
+	if (err)
+		return (err);
+
+	err = zap_lookup(zsb->z_os, obj, buf, 8, 1, valp);
+	if (err == ENOENT)
+		err = 0;
+	return (err);
+}
+EXPORT_SYMBOL(zfs_userspace_one);
+
+int
+zfs_set_userquota(zfs_sb_t *zsb, zfs_userquota_prop_t type,
+    const char *domain, uint64_t rid, uint64_t quota)
+{
+	char buf[32];
+	int err;
+	dmu_tx_t *tx;
+	uint64_t *objp;
+	boolean_t fuid_dirtied;
+
+	if (type != ZFS_PROP_USERQUOTA && type != ZFS_PROP_GROUPQUOTA)
+		return (SET_ERROR(EINVAL));
+
+	if (zsb->z_version < ZPL_VERSION_USERSPACE)
+		return (SET_ERROR(ENOTSUP));
+
+	objp = (type == ZFS_PROP_USERQUOTA) ? &zsb->z_userquota_obj :
+	    &zsb->z_groupquota_obj;
+
+	err = id_to_fuidstr(zsb, domain, rid, buf, B_TRUE);
+	if (err)
+		return (err);
+	fuid_dirtied = zsb->z_fuid_dirty;
+
+	tx = dmu_tx_create(zsb->z_os);
+	dmu_tx_hold_zap(tx, *objp ? *objp : DMU_NEW_OBJECT, B_TRUE, NULL);
+	if (*objp == 0) {
+		dmu_tx_hold_zap(tx, MASTER_NODE_OBJ, B_TRUE,
+		    zfs_userquota_prop_prefixes[type]);
+	}
+	if (fuid_dirtied)
+		zfs_fuid_txhold(zsb, tx);
+	err = dmu_tx_assign(tx, TXG_WAIT);
+	if (err) {
+		dmu_tx_abort(tx);
+		return (err);
+	}
+
+	mutex_enter(&zsb->z_lock);
+	if (*objp == 0) {
+		*objp = zap_create(zsb->z_os, DMU_OT_USERGROUP_QUOTA,
+		    DMU_OT_NONE, 0, tx);
+		VERIFY(0 == zap_add(zsb->z_os, MASTER_NODE_OBJ,
+		    zfs_userquota_prop_prefixes[type], 8, 1, objp, tx));
+	}
+	mutex_exit(&zsb->z_lock);
+
+	if (quota == 0) {
+		err = zap_remove(zsb->z_os, *objp, buf, tx);
+		if (err == ENOENT)
+			err = 0;
+	} else {
+		err = zap_update(zsb->z_os, *objp, buf, 8, 1, &quota, tx);
+	}
+	ASSERT(err == 0);
+	if (fuid_dirtied)
+		zfs_fuid_sync(zsb, tx);
+	dmu_tx_commit(tx);
+	return (err);
+}
+EXPORT_SYMBOL(zfs_set_userquota);
+
+boolean_t
+zfs_fuid_overquota(zfs_sb_t *zsb, boolean_t isgroup, uint64_t fuid)
+{
+	char buf[32];
+	uint64_t used, quota, usedobj, quotaobj;
+	int err;
+
+	usedobj = isgroup ? DMU_GROUPUSED_OBJECT : DMU_USERUSED_OBJECT;
+	quotaobj = isgroup ? zsb->z_groupquota_obj : zsb->z_userquota_obj;
+
+	if (quotaobj == 0 || zsb->z_replay)
+		return (B_FALSE);
+
+	(void) sprintf(buf, "%llx", (longlong_t)fuid);
+	err = zap_lookup(zsb->z_os, quotaobj, buf, 8, 1, &quota);
+	if (err != 0)
+		return (B_FALSE);
+
+	err = zap_lookup(zsb->z_os, usedobj, buf, 8, 1, &used);
+	if (err != 0)
+		return (B_FALSE);
+	return (used >= quota);
+}
+EXPORT_SYMBOL(zfs_fuid_overquota);
+
+boolean_t
+zfs_owner_overquota(zfs_sb_t *zsb, znode_t *zp, boolean_t isgroup)
+{
+	uint64_t fuid;
+	uint64_t quotaobj;
+
+	quotaobj = isgroup ? zsb->z_groupquota_obj : zsb->z_userquota_obj;
+
+	fuid = isgroup ? zp->z_gid : zp->z_uid;
+
+	if (quotaobj == 0 || zsb->z_replay)
+		return (B_FALSE);
+
+	return (zfs_fuid_overquota(zsb, isgroup, fuid));
+}
+EXPORT_SYMBOL(zfs_owner_overquota);
+
+zfs_mntopts_t *
+zfs_mntopts_alloc(void)
+{
+	return (kmem_zalloc(sizeof (zfs_mntopts_t), KM_SLEEP));
+}
+
+void
+zfs_mntopts_free(zfs_mntopts_t *zmo)
+{
+	if (zmo->z_osname)
+		strfree(zmo->z_osname);
+
+	if (zmo->z_mntpoint)
+		strfree(zmo->z_mntpoint);
+
+	kmem_free(zmo, sizeof (zfs_mntopts_t));
+}
+
+int
+zfs_sb_create(const char *osname, zfs_mntopts_t *zmo, zfs_sb_t **zsbp)
+{
+	objset_t *os;
+	zfs_sb_t *zsb;
+	uint64_t zval;
+	int i, size, error;
+	uint64_t sa_obj;
+
+	zsb = kmem_zalloc(sizeof (zfs_sb_t), KM_SLEEP);
+
+	/*
+	 * We claim to always be readonly so we can open snapshots;
+	 * other ZPL code will prevent us from writing to snapshots.
+	 */
+	error = dmu_objset_own(osname, DMU_OST_ZFS, B_TRUE, zsb, &os);
+	if (error) {
+		kmem_free(zsb, sizeof (zfs_sb_t));
+		return (error);
+	}
+
+	/*
+	 * Optional temporary mount options, free'd in zfs_sb_free().
+	 */
+	zsb->z_mntopts = (zmo ? zmo : zfs_mntopts_alloc());
+
+	/*
+	 * Initialize the zfs-specific filesystem structure.
+	 * Should probably make this a kmem cache, shuffle fields.
+	 */
+	zsb->z_sb = NULL;
+	zsb->z_parent = zsb;
+	zsb->z_max_blksz = SPA_OLD_MAXBLOCKSIZE;
+	zsb->z_show_ctldir = ZFS_SNAPDIR_VISIBLE;
+	zsb->z_os = os;
+
+	error = zfs_get_zplprop(os, ZFS_PROP_VERSION, &zsb->z_version);
+	if (error) {
+		goto out;
+	} else if (zsb->z_version > ZPL_VERSION) {
+		error = SET_ERROR(ENOTSUP);
+		goto out;
+	}
+	if ((error = zfs_get_zplprop(os, ZFS_PROP_NORMALIZE, &zval)) != 0)
+		goto out;
+	zsb->z_norm = (int)zval;
+
+	if ((error = zfs_get_zplprop(os, ZFS_PROP_UTF8ONLY, &zval)) != 0)
+		goto out;
+	zsb->z_utf8 = (zval != 0);
+
+	if ((error = zfs_get_zplprop(os, ZFS_PROP_CASE, &zval)) != 0)
+		goto out;
+	zsb->z_case = (uint_t)zval;
+
+	if ((error = zfs_get_zplprop(os, ZFS_PROP_ACLTYPE, &zval)) != 0)
+		goto out;
+	zsb->z_acl_type = (uint_t)zval;
+
+	/*
+	 * Fold case on file systems that are always or sometimes case
+	 * insensitive.
+	 */
+	if (zsb->z_case == ZFS_CASE_INSENSITIVE ||
+	    zsb->z_case == ZFS_CASE_MIXED)
+		zsb->z_norm |= U8_TEXTPREP_TOUPPER;
+
+	zsb->z_use_fuids = USE_FUIDS(zsb->z_version, zsb->z_os);
+	zsb->z_use_sa = USE_SA(zsb->z_version, zsb->z_os);
+
+	if (zsb->z_use_sa) {
+		/* should either have both of these objects or none */
+		error = zap_lookup(os, MASTER_NODE_OBJ, ZFS_SA_ATTRS, 8, 1,
+		    &sa_obj);
+		if (error)
+			goto out;
+
+		error = zfs_get_zplprop(os, ZFS_PROP_XATTR, &zval);
+		if ((error == 0) && (zval == ZFS_XATTR_SA))
+			zsb->z_xattr_sa = B_TRUE;
+	} else {
+		/*
+		 * Pre SA versions file systems should never touch
+		 * either the attribute registration or layout objects.
+		 */
+		sa_obj = 0;
+	}
+
+	error = sa_setup(os, sa_obj, zfs_attr_table, ZPL_END,
+	    &zsb->z_attr_table);
+	if (error)
+		goto out;
+
+	if (zsb->z_version >= ZPL_VERSION_SA)
+		sa_register_update_callback(os, zfs_sa_upgrade);
+
+	error = zap_lookup(os, MASTER_NODE_OBJ, ZFS_ROOT_OBJ, 8, 1,
+	    &zsb->z_root);
+	if (error)
+		goto out;
+	ASSERT(zsb->z_root != 0);
+
+	error = zap_lookup(os, MASTER_NODE_OBJ, ZFS_UNLINKED_SET, 8, 1,
+	    &zsb->z_unlinkedobj);
+	if (error)
+		goto out;
+
+	error = zap_lookup(os, MASTER_NODE_OBJ,
+	    zfs_userquota_prop_prefixes[ZFS_PROP_USERQUOTA],
+	    8, 1, &zsb->z_userquota_obj);
+	if (error && error != ENOENT)
+		goto out;
+
+	error = zap_lookup(os, MASTER_NODE_OBJ,
+	    zfs_userquota_prop_prefixes[ZFS_PROP_GROUPQUOTA],
+	    8, 1, &zsb->z_groupquota_obj);
+	if (error && error != ENOENT)
+		goto out;
+
+	error = zap_lookup(os, MASTER_NODE_OBJ, ZFS_FUID_TABLES, 8, 1,
+	    &zsb->z_fuid_obj);
+	if (error && error != ENOENT)
+		goto out;
+
+	error = zap_lookup(os, MASTER_NODE_OBJ, ZFS_SHARES_DIR, 8, 1,
+	    &zsb->z_shares_dir);
+	if (error && error != ENOENT)
+		goto out;
+
+	mutex_init(&zsb->z_znodes_lock, NULL, MUTEX_DEFAULT, NULL);
+	mutex_init(&zsb->z_lock, NULL, MUTEX_DEFAULT, NULL);
+	list_create(&zsb->z_all_znodes, sizeof (znode_t),
+	    offsetof(znode_t, z_link_node));
+	rrm_init(&zsb->z_teardown_lock, B_FALSE);
+	rw_init(&zsb->z_teardown_inactive_lock, NULL, RW_DEFAULT, NULL);
+	rw_init(&zsb->z_fuid_lock, NULL, RW_DEFAULT, NULL);
+
+	size = MIN(1 << (highbit64(zfs_object_mutex_size)-1), ZFS_OBJ_MTX_MAX);
+	zsb->z_hold_size = size;
+	zsb->z_hold_trees = vmem_zalloc(sizeof (avl_tree_t) * size, KM_SLEEP);
+	zsb->z_hold_locks = vmem_zalloc(sizeof (kmutex_t) * size, KM_SLEEP);
+	for (i = 0; i != size; i++) {
+		avl_create(&zsb->z_hold_trees[i], zfs_znode_hold_compare,
+		    sizeof (znode_hold_t), offsetof(znode_hold_t, zh_node));
+		mutex_init(&zsb->z_hold_locks[i], NULL, MUTEX_DEFAULT, NULL);
+	}
+
+	*zsbp = zsb;
+	return (0);
+
+out:
+	dmu_objset_disown(os, zsb);
+	*zsbp = NULL;
+
+	kmem_free(zsb, sizeof (zfs_sb_t));
+	return (error);
+}
+EXPORT_SYMBOL(zfs_sb_create);
+
+int
+zfs_sb_setup(zfs_sb_t *zsb, boolean_t mounting)
+{
+	int error;
+
+	error = zfs_register_callbacks(zsb);
+	if (error)
+		return (error);
+
+	/*
+	 * Set the objset user_ptr to track its zsb.
+	 */
+	mutex_enter(&zsb->z_os->os_user_ptr_lock);
+	dmu_objset_set_user(zsb->z_os, zsb);
+	mutex_exit(&zsb->z_os->os_user_ptr_lock);
+
+	zsb->z_log = zil_open(zsb->z_os, zfs_get_data);
+
+	/*
+	 * If we are not mounting (ie: online recv), then we don't
+	 * have to worry about replaying the log as we blocked all
+	 * operations out since we closed the ZIL.
+	 */
+	if (mounting) {
+		boolean_t readonly;
+
+		/*
+		 * During replay we remove the read only flag to
+		 * allow replays to succeed.
+		 */
+		readonly = zfs_is_readonly(zsb);
+		if (readonly != 0)
+			readonly_changed_cb(zsb, B_FALSE);
+		else
+			zfs_unlinked_drain(zsb);
+
+		/*
+		 * Parse and replay the intent log.
+		 *
+		 * Because of ziltest, this must be done after
+		 * zfs_unlinked_drain().  (Further note: ziltest
+		 * doesn't use readonly mounts, where
+		 * zfs_unlinked_drain() isn't called.)  This is because
+		 * ziltest causes spa_sync() to think it's committed,
+		 * but actually it is not, so the intent log contains
+		 * many txg's worth of changes.
+		 *
+		 * In particular, if object N is in the unlinked set in
+		 * the last txg to actually sync, then it could be
+		 * actually freed in a later txg and then reallocated
+		 * in a yet later txg.  This would write a "create
+		 * object N" record to the intent log.  Normally, this
+		 * would be fine because the spa_sync() would have
+		 * written out the fact that object N is free, before
+		 * we could write the "create object N" intent log
+		 * record.
+		 *
+		 * But when we are in ziltest mode, we advance the "open
+		 * txg" without actually spa_sync()-ing the changes to
+		 * disk.  So we would see that object N is still
+		 * allocated and in the unlinked set, and there is an
+		 * intent log record saying to allocate it.
+		 */
+		if (spa_writeable(dmu_objset_spa(zsb->z_os))) {
+			if (zil_replay_disable) {
+				zil_destroy(zsb->z_log, B_FALSE);
+			} else {
+				zsb->z_replay = B_TRUE;
+				zil_replay(zsb->z_os, zsb,
+				    zfs_replay_vector);
+				zsb->z_replay = B_FALSE;
+			}
+		}
+
+		/* restore readonly bit */
+		if (readonly != 0)
+			readonly_changed_cb(zsb, B_TRUE);
+	}
+
+	return (0);
+}
+EXPORT_SYMBOL(zfs_sb_setup);
+
+void
+zfs_sb_free(zfs_sb_t *zsb)
+{
+	int i, size = zsb->z_hold_size;
+
+	zfs_fuid_destroy(zsb);
+
+	mutex_destroy(&zsb->z_znodes_lock);
+	mutex_destroy(&zsb->z_lock);
+	list_destroy(&zsb->z_all_znodes);
+	rrm_destroy(&zsb->z_teardown_lock);
+	rw_destroy(&zsb->z_teardown_inactive_lock);
+	rw_destroy(&zsb->z_fuid_lock);
+	for (i = 0; i != size; i++) {
+		avl_destroy(&zsb->z_hold_trees[i]);
+		mutex_destroy(&zsb->z_hold_locks[i]);
+	}
+	vmem_free(zsb->z_hold_trees, sizeof (avl_tree_t) * size);
+	vmem_free(zsb->z_hold_locks, sizeof (kmutex_t) * size);
+	zfs_mntopts_free(zsb->z_mntopts);
+	kmem_free(zsb, sizeof (zfs_sb_t));
+}
+EXPORT_SYMBOL(zfs_sb_free);
+
+static void
+zfs_set_fuid_feature(zfs_sb_t *zsb)
+{
+	zsb->z_use_fuids = USE_FUIDS(zsb->z_version, zsb->z_os);
+	zsb->z_use_sa = USE_SA(zsb->z_version, zsb->z_os);
+}
+
+void
+zfs_unregister_callbacks(zfs_sb_t *zsb)
+{
+	objset_t *os = zsb->z_os;
+	struct dsl_dataset *ds;
+
+	/*
+	 * Unregister properties.
+	 */
+	if (!dmu_objset_is_snapshot(os)) {
+		ds = dmu_objset_ds(os);
+		VERIFY(dsl_prop_unregister(ds, "atime", atime_changed_cb,
+		    zsb) == 0);
+
+		VERIFY(dsl_prop_unregister(ds, "relatime", relatime_changed_cb,
+		    zsb) == 0);
+
+		VERIFY(dsl_prop_unregister(ds, "xattr", xattr_changed_cb,
+		    zsb) == 0);
+
+		VERIFY(dsl_prop_unregister(ds, "recordsize", blksz_changed_cb,
+		    zsb) == 0);
+
+		VERIFY(dsl_prop_unregister(ds, "readonly", readonly_changed_cb,
+		    zsb) == 0);
+
+		VERIFY(dsl_prop_unregister(ds, "devices", devices_changed_cb,
+		    zsb) == 0);
+
+		VERIFY(dsl_prop_unregister(ds, "setuid", setuid_changed_cb,
+		    zsb) == 0);
+
+		VERIFY(dsl_prop_unregister(ds, "exec", exec_changed_cb,
+		    zsb) == 0);
+
+		VERIFY(dsl_prop_unregister(ds, "snapdir", snapdir_changed_cb,
+		    zsb) == 0);
+
+		VERIFY(dsl_prop_unregister(ds, "acltype", acltype_changed_cb,
+		    zsb) == 0);
+
+		VERIFY(dsl_prop_unregister(ds, "aclinherit",
+		    acl_inherit_changed_cb, zsb) == 0);
+
+		VERIFY(dsl_prop_unregister(ds, "vscan",
+		    vscan_changed_cb, zsb) == 0);
+
+		VERIFY(dsl_prop_unregister(ds, "nbmand",
+		    nbmand_changed_cb, zsb) == 0);
+	}
+}
+EXPORT_SYMBOL(zfs_unregister_callbacks);
+
+#ifdef HAVE_MLSLABEL
+/*
+ * Check that the hex label string is appropriate for the dataset being
+ * mounted into the global_zone proper.
+ *
+ * Return an error if the hex label string is not default or
+ * admin_low/admin_high.  For admin_low labels, the corresponding
+ * dataset must be readonly.
+ */
+int
+zfs_check_global_label(const char *dsname, const char *hexsl)
+{
+	if (strcasecmp(hexsl, ZFS_MLSLABEL_DEFAULT) == 0)
+		return (0);
+	if (strcasecmp(hexsl, ADMIN_HIGH) == 0)
+		return (0);
+	if (strcasecmp(hexsl, ADMIN_LOW) == 0) {
+		/* must be readonly */
+		uint64_t rdonly;
+
+		if (dsl_prop_get_integer(dsname,
+		    zfs_prop_to_name(ZFS_PROP_READONLY), &rdonly, NULL))
+			return (SET_ERROR(EACCES));
+		return (rdonly ? 0 : EACCES);
+	}
+	return (SET_ERROR(EACCES));
+}
+EXPORT_SYMBOL(zfs_check_global_label);
+#endif /* HAVE_MLSLABEL */
+
+int
+zfs_statvfs(struct dentry *dentry, struct kstatfs *statp)
+{
+	zfs_sb_t *zsb = dentry->d_sb->s_fs_info;
+	uint64_t refdbytes, availbytes, usedobjs, availobjs;
+	uint64_t fsid;
+	uint32_t bshift;
+
+	ZFS_ENTER(zsb);
+
+	dmu_objset_space(zsb->z_os,
+	    &refdbytes, &availbytes, &usedobjs, &availobjs);
+
+	fsid = dmu_objset_fsid_guid(zsb->z_os);
+	/*
+	 * The underlying storage pool actually uses multiple block
+	 * size.  Under Solaris frsize (fragment size) is reported as
+	 * the smallest block size we support, and bsize (block size)
+	 * as the filesystem's maximum block size.  Unfortunately,
+	 * under Linux the fragment size and block size are often used
+	 * interchangeably.  Thus we are forced to report both of them
+	 * as the filesystem's maximum block size.
+	 */
+	statp->f_frsize = zsb->z_max_blksz;
+	statp->f_bsize = zsb->z_max_blksz;
+	bshift = fls(statp->f_bsize) - 1;
+
+	/*
+	 * The following report "total" blocks of various kinds in
+	 * the file system, but reported in terms of f_bsize - the
+	 * "preferred" size.
+	 */
+
+	statp->f_blocks = (refdbytes + availbytes) >> bshift;
+	statp->f_bfree = availbytes >> bshift;
+	statp->f_bavail = statp->f_bfree; /* no root reservation */
+
+	/*
+	 * statvfs() should really be called statufs(), because it assumes
+	 * static metadata.  ZFS doesn't preallocate files, so the best
+	 * we can do is report the max that could possibly fit in f_files,
+	 * and that minus the number actually used in f_ffree.
+	 * For f_ffree, report the smaller of the number of object available
+	 * and the number of blocks (each object will take at least a block).
+	 */
+	statp->f_ffree = MIN(availobjs, availbytes >> DNODE_SHIFT);
+	statp->f_files = statp->f_ffree + usedobjs;
+	statp->f_fsid.val[0] = (uint32_t)fsid;
+	statp->f_fsid.val[1] = (uint32_t)(fsid >> 32);
+	statp->f_type = ZFS_SUPER_MAGIC;
+	statp->f_namelen = ZFS_MAXNAMELEN;
+
+	/*
+	 * We have all of 40 characters to stuff a string here.
+	 * Is there anything useful we could/should provide?
+	 */
+	bzero(statp->f_spare, sizeof (statp->f_spare));
+
+	ZFS_EXIT(zsb);
+	return (0);
+}
+EXPORT_SYMBOL(zfs_statvfs);
+
+int
+zfs_root(zfs_sb_t *zsb, struct inode **ipp)
+{
+	znode_t *rootzp;
+	int error;
+
+	ZFS_ENTER(zsb);
+
+	error = zfs_zget(zsb, zsb->z_root, &rootzp);
+	if (error == 0)
+		*ipp = ZTOI(rootzp);
+
+	ZFS_EXIT(zsb);
+	return (error);
+}
+EXPORT_SYMBOL(zfs_root);
+
+#if !defined(HAVE_SPLIT_SHRINKER_CALLBACK) && !defined(HAVE_SHRINK) && \
+	defined(HAVE_D_PRUNE_ALIASES)
+/*
+ * Linux kernels older than 3.1 do not support a per-filesystem shrinker.
+ * To accommodate this we must improvise and manually walk the list of znodes
+ * attempting to prune dentries in order to be able to drop the inodes.
+ *
+ * To avoid scanning the same znodes multiple times they are always rotated
+ * to the end of the z_all_znodes list.  New znodes are inserted at the
+ * end of the list so we're always scanning the oldest znodes first.
+ */
+static int
+zfs_sb_prune_aliases(zfs_sb_t *zsb, unsigned long nr_to_scan)
+{
+	znode_t **zp_array, *zp;
+	int max_array = MIN(nr_to_scan, PAGE_SIZE * 8 / sizeof (znode_t *));
+	int objects = 0;
+	int i = 0, j = 0;
+
+	zp_array = kmem_zalloc(max_array * sizeof (znode_t *), KM_SLEEP);
+
+	mutex_enter(&zsb->z_znodes_lock);
+	while ((zp = list_head(&zsb->z_all_znodes)) != NULL) {
+
+		if ((i++ > nr_to_scan) || (j >= max_array))
+			break;
+
+		ASSERT(list_link_active(&zp->z_link_node));
+		list_remove(&zsb->z_all_znodes, zp);
+		list_insert_tail(&zsb->z_all_znodes, zp);
+
+		/* Skip active znodes and .zfs entries */
+		if (MUTEX_HELD(&zp->z_lock) || zp->z_is_ctldir)
+			continue;
+
+		if (igrab(ZTOI(zp)) == NULL)
+			continue;
+
+		zp_array[j] = zp;
+		j++;
+	}
+	mutex_exit(&zsb->z_znodes_lock);
+
+	for (i = 0; i < j; i++) {
+		zp = zp_array[i];
+
+		ASSERT3P(zp, !=, NULL);
+		d_prune_aliases(ZTOI(zp));
+
+		if (atomic_read(&ZTOI(zp)->i_count) == 1)
+			objects++;
+
+		iput(ZTOI(zp));
+	}
+
+	kmem_free(zp_array, max_array * sizeof (znode_t *));
+
+	return (objects);
+}
+#endif /* HAVE_D_PRUNE_ALIASES */
+
+/*
+ * The ARC has requested that the filesystem drop entries from the dentry
+ * and inode caches.  This can occur when the ARC needs to free meta data
+ * blocks but can't because they are all pinned by entries in these caches.
+ */
+int
+zfs_sb_prune(struct super_block *sb, unsigned long nr_to_scan, int *objects)
+{
+	zfs_sb_t *zsb = sb->s_fs_info;
+	int error = 0;
+#if defined(HAVE_SHRINK) || defined(HAVE_SPLIT_SHRINKER_CALLBACK)
+	struct shrinker *shrinker = &sb->s_shrink;
+	struct shrink_control sc = {
+		.nr_to_scan = nr_to_scan,
+		.gfp_mask = GFP_KERNEL,
+	};
+#endif
+
+	ZFS_ENTER(zsb);
+
+#if defined(HAVE_SPLIT_SHRINKER_CALLBACK) && \
+	defined(SHRINK_CONTROL_HAS_NID) && \
+	defined(SHRINKER_NUMA_AWARE)
+	if (sb->s_shrink.flags & SHRINKER_NUMA_AWARE) {
+		*objects = 0;
+		for_each_online_node(sc.nid)
+			*objects += (*shrinker->scan_objects)(shrinker, &sc);
+	} else {
+			*objects = (*shrinker->scan_objects)(shrinker, &sc);
+	}
+#elif defined(HAVE_SPLIT_SHRINKER_CALLBACK)
+	*objects = (*shrinker->scan_objects)(shrinker, &sc);
+#elif defined(HAVE_SHRINK)
+	*objects = (*shrinker->shrink)(shrinker, &sc);
+#elif defined(HAVE_D_PRUNE_ALIASES)
+	*objects = zfs_sb_prune_aliases(zsb, nr_to_scan);
+#else
+#error "No available dentry and inode cache pruning mechanism."
+#endif
+	ZFS_EXIT(zsb);
+
+	dprintf_ds(zsb->z_os->os_dsl_dataset,
+	    "pruning, nr_to_scan=%lu objects=%d error=%d\n",
+	    nr_to_scan, *objects, error);
+
+	return (error);
+}
+EXPORT_SYMBOL(zfs_sb_prune);
+
+/*
+ * Teardown the zfs_sb_t.
+ *
+ * Note, if 'unmounting' if FALSE, we return with the 'z_teardown_lock'
+ * and 'z_teardown_inactive_lock' held.
+ */
+int
+zfs_sb_teardown(zfs_sb_t *zsb, boolean_t unmounting)
+{
+	znode_t	*zp;
+
+	/*
+	 * If someone has not already unmounted this file system,
+	 * drain the iput_taskq to ensure all active references to the
+	 * zfs_sb_t have been handled only then can it be safely destroyed.
+	 */
+	if (zsb->z_os) {
+		/*
+		 * If we're unmounting we have to wait for the list to
+		 * drain completely.
+		 *
+		 * If we're not unmounting there's no guarantee the list
+		 * will drain completely, but iputs run from the taskq
+		 * may add the parents of dir-based xattrs to the taskq
+		 * so we want to wait for these.
+		 *
+		 * We can safely read z_nr_znodes without locking because the
+		 * VFS has already blocked operations which add to the
+		 * z_all_znodes list and thus increment z_nr_znodes.
+		 */
+		int round = 0;
+		while (zsb->z_nr_znodes > 0) {
+			taskq_wait_outstanding(dsl_pool_iput_taskq(
+			    dmu_objset_pool(zsb->z_os)), 0);
+			if (++round > 1 && !unmounting)
+				break;
+		}
+	}
+
+	rrm_enter(&zsb->z_teardown_lock, RW_WRITER, FTAG);
+
+	if (!unmounting) {
+		/*
+		 * We purge the parent filesystem's super block as the
+		 * parent filesystem and all of its snapshots have their
+		 * inode's super block set to the parent's filesystem's
+		 * super block.  Note,  'z_parent' is self referential
+		 * for non-snapshots.
+		 */
+		shrink_dcache_sb(zsb->z_parent->z_sb);
+	}
+
+	/*
+	 * Close the zil. NB: Can't close the zil while zfs_inactive
+	 * threads are blocked as zil_close can call zfs_inactive.
+	 */
+	if (zsb->z_log) {
+		zil_close(zsb->z_log);
+		zsb->z_log = NULL;
+	}
+
+	rw_enter(&zsb->z_teardown_inactive_lock, RW_WRITER);
+
+	/*
+	 * If we are not unmounting (ie: online recv) and someone already
+	 * unmounted this file system while we were doing the switcheroo,
+	 * or a reopen of z_os failed then just bail out now.
+	 */
+	if (!unmounting && (zsb->z_unmounted || zsb->z_os == NULL)) {
+		rw_exit(&zsb->z_teardown_inactive_lock);
+		rrm_exit(&zsb->z_teardown_lock, FTAG);
+		return (SET_ERROR(EIO));
+	}
+
+	/*
+	 * At this point there are no VFS ops active, and any new VFS ops
+	 * will fail with EIO since we have z_teardown_lock for writer (only
+	 * relevant for forced unmount).
+	 *
+	 * Release all holds on dbufs.
+	 */
+	if (!unmounting) {
+		mutex_enter(&zsb->z_znodes_lock);
+		for (zp = list_head(&zsb->z_all_znodes); zp != NULL;
+		zp = list_next(&zsb->z_all_znodes, zp)) {
+			if (zp->z_sa_hdl)
+				zfs_znode_dmu_fini(zp);
+		}
+		mutex_exit(&zsb->z_znodes_lock);
+	}
+
+	/*
+	 * If we are unmounting, set the unmounted flag and let new VFS ops
+	 * unblock.  zfs_inactive will have the unmounted behavior, and all
+	 * other VFS ops will fail with EIO.
+	 */
+	if (unmounting) {
+		zsb->z_unmounted = B_TRUE;
+		rrm_exit(&zsb->z_teardown_lock, FTAG);
+		rw_exit(&zsb->z_teardown_inactive_lock);
+	}
+
+	/*
+	 * z_os will be NULL if there was an error in attempting to reopen
+	 * zsb, so just return as the properties had already been
+	 *
+	 * unregistered and cached data had been evicted before.
+	 */
+	if (zsb->z_os == NULL)
+		return (0);
+
+	/*
+	 * Unregister properties.
+	 */
+	zfs_unregister_callbacks(zsb);
+
+	/*
+	 * Evict cached data
+	 */
+	if (dsl_dataset_is_dirty(dmu_objset_ds(zsb->z_os)) &&
+	    !zfs_is_readonly(zsb))
+		txg_wait_synced(dmu_objset_pool(zsb->z_os), 0);
+	dmu_objset_evict_dbufs(zsb->z_os);
+
+	return (0);
+}
+EXPORT_SYMBOL(zfs_sb_teardown);
+
+#if !defined(HAVE_2ARGS_BDI_SETUP_AND_REGISTER) && \
+	!defined(HAVE_3ARGS_BDI_SETUP_AND_REGISTER)
+atomic_long_t zfs_bdi_seq = ATOMIC_LONG_INIT(0);
+#endif
+
+int
+zfs_domount(struct super_block *sb, zfs_mntopts_t *zmo, int silent)
+{
+	const char *osname = zmo->z_osname;
+	zfs_sb_t *zsb;
+	struct inode *root_inode;
+	uint64_t recordsize;
+	int error;
+
+	error = zfs_sb_create(osname, zmo, &zsb);
+	if (error)
+		return (error);
+
+	if ((error = dsl_prop_get_integer(osname, "recordsize",
+	    &recordsize, NULL)))
+		goto out;
+
+	zsb->z_sb = sb;
+	sb->s_fs_info = zsb;
+	sb->s_magic = ZFS_SUPER_MAGIC;
+	sb->s_maxbytes = MAX_LFS_FILESIZE;
+	sb->s_time_gran = 1;
+	sb->s_blocksize = recordsize;
+	sb->s_blocksize_bits = ilog2(recordsize);
+	zsb->z_bdi.ra_pages = 0;
+	sb->s_bdi = &zsb->z_bdi;
+
+	error = -zpl_bdi_setup_and_register(&zsb->z_bdi, "zfs");
+	if (error)
+		goto out;
+
+	/* Set callback operations for the file system. */
+	sb->s_op = &zpl_super_operations;
+	sb->s_xattr = zpl_xattr_handlers;
+	sb->s_export_op = &zpl_export_operations;
+#ifdef HAVE_S_D_OP
+	sb->s_d_op = &zpl_dentry_operations;
+#endif /* HAVE_S_D_OP */
+
+	/* Set features for file system. */
+	zfs_set_fuid_feature(zsb);
+
+	if (dmu_objset_is_snapshot(zsb->z_os)) {
+		uint64_t pval;
+
+		atime_changed_cb(zsb, B_FALSE);
+		readonly_changed_cb(zsb, B_TRUE);
+		if ((error = dsl_prop_get_integer(osname,
+		    "xattr", &pval, NULL)))
+			goto out;
+		xattr_changed_cb(zsb, pval);
+		if ((error = dsl_prop_get_integer(osname,
+		    "acltype", &pval, NULL)))
+			goto out;
+		acltype_changed_cb(zsb, pval);
+		zsb->z_issnap = B_TRUE;
+		zsb->z_os->os_sync = ZFS_SYNC_DISABLED;
+		zsb->z_snap_defer_time = jiffies;
+
+		mutex_enter(&zsb->z_os->os_user_ptr_lock);
+		dmu_objset_set_user(zsb->z_os, zsb);
+		mutex_exit(&zsb->z_os->os_user_ptr_lock);
+	} else {
+		error = zfs_sb_setup(zsb, B_TRUE);
+	}
+
+	/* Allocate a root inode for the filesystem. */
+	error = zfs_root(zsb, &root_inode);
+	if (error) {
+		(void) zfs_umount(sb);
+		goto out;
+	}
+
+	/* Allocate a root dentry for the filesystem */
+	sb->s_root = d_make_root(root_inode);
+	if (sb->s_root == NULL) {
+		(void) zfs_umount(sb);
+		error = SET_ERROR(ENOMEM);
+		goto out;
+	}
+
+	if (!zsb->z_issnap)
+		zfsctl_create(zsb);
+
+	zsb->z_arc_prune = arc_add_prune_callback(zpl_prune_sb, sb);
+out:
+	if (error) {
+		dmu_objset_disown(zsb->z_os, zsb);
+		zfs_sb_free(zsb);
+	}
+
+	return (error);
+}
+EXPORT_SYMBOL(zfs_domount);
+
+/*
+ * Called when an unmount is requested and certain sanity checks have
+ * already passed.  At this point no dentries or inodes have been reclaimed
+ * from their respective caches.  We drop the extra reference on the .zfs
+ * control directory to allow everything to be reclaimed.  All snapshots
+ * must already have been unmounted to reach this point.
+ */
+void
+zfs_preumount(struct super_block *sb)
+{
+	zfs_sb_t *zsb = sb->s_fs_info;
+
+	if (zsb)
+		zfsctl_destroy(sb->s_fs_info);
+}
+EXPORT_SYMBOL(zfs_preumount);
+
+/*
+ * Called once all other unmount released tear down has occurred.
+ * It is our responsibility to release any remaining infrastructure.
+ */
+/*ARGSUSED*/
+int
+zfs_umount(struct super_block *sb)
+{
+	zfs_sb_t *zsb = sb->s_fs_info;
+	objset_t *os;
+
+	arc_remove_prune_callback(zsb->z_arc_prune);
+	VERIFY(zfs_sb_teardown(zsb, B_TRUE) == 0);
+	os = zsb->z_os;
+	bdi_destroy(sb->s_bdi);
+
+	/*
+	 * z_os will be NULL if there was an error in
+	 * attempting to reopen zsb.
+	 */
+	if (os != NULL) {
+		/*
+		 * Unset the objset user_ptr.
+		 */
+		mutex_enter(&os->os_user_ptr_lock);
+		dmu_objset_set_user(os, NULL);
+		mutex_exit(&os->os_user_ptr_lock);
+
+		/*
+		 * Finally release the objset
+		 */
+		dmu_objset_disown(os, zsb);
+	}
+
+	zfs_sb_free(zsb);
+	return (0);
+}
+EXPORT_SYMBOL(zfs_umount);
+
+int
+zfs_remount(struct super_block *sb, int *flags, zfs_mntopts_t *zmo)
+{
+	zfs_sb_t *zsb = sb->s_fs_info;
+	int error;
+
+	zfs_unregister_callbacks(zsb);
+	error = zfs_register_callbacks(zsb);
+
+	return (error);
+}
+EXPORT_SYMBOL(zfs_remount);
+
+int
+zfs_vget(struct super_block *sb, struct inode **ipp, fid_t *fidp)
+{
+	zfs_sb_t	*zsb = sb->s_fs_info;
+	znode_t		*zp;
+	uint64_t	object = 0;
+	uint64_t	fid_gen = 0;
+	uint64_t	gen_mask;
+	uint64_t	zp_gen;
+	int		i, err;
+
+	*ipp = NULL;
+
+	ZFS_ENTER(zsb);
+
+	if (fidp->fid_len == LONG_FID_LEN) {
+		zfid_long_t	*zlfid = (zfid_long_t *)fidp;
+		uint64_t	objsetid = 0;
+		uint64_t	setgen = 0;
+
+		for (i = 0; i < sizeof (zlfid->zf_setid); i++)
+			objsetid |= ((uint64_t)zlfid->zf_setid[i]) << (8 * i);
+
+		for (i = 0; i < sizeof (zlfid->zf_setgen); i++)
+			setgen |= ((uint64_t)zlfid->zf_setgen[i]) << (8 * i);
+
+		ZFS_EXIT(zsb);
+
+		err = zfsctl_lookup_objset(sb, objsetid, &zsb);
+		if (err)
+			return (SET_ERROR(EINVAL));
+
+		ZFS_ENTER(zsb);
+	}
+
+	if (fidp->fid_len == SHORT_FID_LEN || fidp->fid_len == LONG_FID_LEN) {
+		zfid_short_t	*zfid = (zfid_short_t *)fidp;
+
+		for (i = 0; i < sizeof (zfid->zf_object); i++)
+			object |= ((uint64_t)zfid->zf_object[i]) << (8 * i);
+
+		for (i = 0; i < sizeof (zfid->zf_gen); i++)
+			fid_gen |= ((uint64_t)zfid->zf_gen[i]) << (8 * i);
+	} else {
+		ZFS_EXIT(zsb);
+		return (SET_ERROR(EINVAL));
+	}
+
+	/* A zero fid_gen means we are in the .zfs control directories */
+	if (fid_gen == 0 &&
+	    (object == ZFSCTL_INO_ROOT || object == ZFSCTL_INO_SNAPDIR)) {
+		*ipp = zsb->z_ctldir;
+		ASSERT(*ipp != NULL);
+		if (object == ZFSCTL_INO_SNAPDIR) {
+			VERIFY(zfsctl_root_lookup(*ipp, "snapshot", ipp,
+			    0, kcred, NULL, NULL) == 0);
+		} else {
+			igrab(*ipp);
+		}
+		ZFS_EXIT(zsb);
+		return (0);
+	}
+
+	gen_mask = -1ULL >> (64 - 8 * i);
+
+	dprintf("getting %llu [%llu mask %llx]\n", object, fid_gen, gen_mask);
+	if ((err = zfs_zget(zsb, object, &zp))) {
+		ZFS_EXIT(zsb);
+		return (err);
+	}
+	(void) sa_lookup(zp->z_sa_hdl, SA_ZPL_GEN(zsb), &zp_gen,
+	    sizeof (uint64_t));
+	zp_gen = zp_gen & gen_mask;
+	if (zp_gen == 0)
+		zp_gen = 1;
+	if ((fid_gen == 0) && (zsb->z_root == object))
+		fid_gen = zp_gen;
+	if (zp->z_unlinked || zp_gen != fid_gen) {
+		dprintf("znode gen (%llu) != fid gen (%llu)\n", zp_gen,
+		    fid_gen);
+		iput(ZTOI(zp));
+		ZFS_EXIT(zsb);
+		return (SET_ERROR(EINVAL));
+	}
+
+	*ipp = ZTOI(zp);
+	if (*ipp)
+		zfs_inode_update(ITOZ(*ipp));
+
+	ZFS_EXIT(zsb);
+	return (0);
+}
+EXPORT_SYMBOL(zfs_vget);
+
+/*
+ * Block out VFS ops and close zfs_sb_t
+ *
+ * Note, if successful, then we return with the 'z_teardown_lock' and
+ * 'z_teardown_inactive_lock' write held.  We leave ownership of the underlying
+ * dataset and objset intact so that they can be atomically handed off during
+ * a subsequent rollback or recv operation and the resume thereafter.
+ */
+int
+zfs_suspend_fs(zfs_sb_t *zsb)
+{
+	int error;
+
+	if ((error = zfs_sb_teardown(zsb, B_FALSE)) != 0)
+		return (error);
+
+	return (0);
+}
+EXPORT_SYMBOL(zfs_suspend_fs);
+
+/*
+ * Reopen zfs_sb_t and release VFS ops.
+ */
+int
+zfs_resume_fs(zfs_sb_t *zsb, const char *osname)
+{
+	int err, err2;
+	znode_t *zp;
+	uint64_t sa_obj = 0;
+
+	ASSERT(RRM_WRITE_HELD(&zsb->z_teardown_lock));
+	ASSERT(RW_WRITE_HELD(&zsb->z_teardown_inactive_lock));
+
+	/*
+	 * We already own this, so just hold and rele it to update the
+	 * objset_t, as the one we had before may have been evicted.
+	 */
+	VERIFY0(dmu_objset_hold(osname, zsb, &zsb->z_os));
+	VERIFY3P(zsb->z_os->os_dsl_dataset->ds_owner, ==, zsb);
+	VERIFY(dsl_dataset_long_held(zsb->z_os->os_dsl_dataset));
+	dmu_objset_rele(zsb->z_os, zsb);
+
+	/*
+	 * Make sure version hasn't changed
+	 */
+
+	err = zfs_get_zplprop(zsb->z_os, ZFS_PROP_VERSION,
+	    &zsb->z_version);
+
+	if (err)
+		goto bail;
+
+	err = zap_lookup(zsb->z_os, MASTER_NODE_OBJ,
+	    ZFS_SA_ATTRS, 8, 1, &sa_obj);
+
+	if (err && zsb->z_version >= ZPL_VERSION_SA)
+		goto bail;
+
+	if ((err = sa_setup(zsb->z_os, sa_obj,
+	    zfs_attr_table,  ZPL_END, &zsb->z_attr_table)) != 0)
+		goto bail;
+
+	if (zsb->z_version >= ZPL_VERSION_SA)
+		sa_register_update_callback(zsb->z_os,
+		    zfs_sa_upgrade);
+
+	VERIFY(zfs_sb_setup(zsb, B_FALSE) == 0);
+
+	zfs_set_fuid_feature(zsb);
+	zsb->z_rollback_time = jiffies;
+
+	/*
+	 * Attempt to re-establish all the active inodes with their
+	 * dbufs.  If a zfs_rezget() fails, then we unhash the inode
+	 * and mark it stale.  This prevents a collision if a new
+	 * inode/object is created which must use the same inode
+	 * number.  The stale inode will be be released when the
+	 * VFS prunes the dentry holding the remaining references
+	 * on the stale inode.
+	 */
+	mutex_enter(&zsb->z_znodes_lock);
+	for (zp = list_head(&zsb->z_all_znodes); zp;
+	    zp = list_next(&zsb->z_all_znodes, zp)) {
+		err2 = zfs_rezget(zp);
+		if (err2) {
+			remove_inode_hash(ZTOI(zp));
+			zp->z_is_stale = B_TRUE;
+		}
+	}
+	mutex_exit(&zsb->z_znodes_lock);
+
+bail:
+	/* release the VFS ops */
+	rw_exit(&zsb->z_teardown_inactive_lock);
+	rrm_exit(&zsb->z_teardown_lock, FTAG);
+
+	if (err) {
+		/*
+		 * Since we couldn't setup the sa framework, try to force
+		 * unmount this file system.
+		 */
+		if (zsb->z_os)
+			(void) zfs_umount(zsb->z_sb);
+	}
+	return (err);
+}
+EXPORT_SYMBOL(zfs_resume_fs);
+
+int
+zfs_set_version(zfs_sb_t *zsb, uint64_t newvers)
+{
+	int error;
+	objset_t *os = zsb->z_os;
+	dmu_tx_t *tx;
+
+	if (newvers < ZPL_VERSION_INITIAL || newvers > ZPL_VERSION)
+		return (SET_ERROR(EINVAL));
+
+	if (newvers < zsb->z_version)
+		return (SET_ERROR(EINVAL));
+
+	if (zfs_spa_version_map(newvers) >
+	    spa_version(dmu_objset_spa(zsb->z_os)))
+		return (SET_ERROR(ENOTSUP));
+
+	tx = dmu_tx_create(os);
+	dmu_tx_hold_zap(tx, MASTER_NODE_OBJ, B_FALSE, ZPL_VERSION_STR);
+	if (newvers >= ZPL_VERSION_SA && !zsb->z_use_sa) {
+		dmu_tx_hold_zap(tx, MASTER_NODE_OBJ, B_TRUE,
+		    ZFS_SA_ATTRS);
+		dmu_tx_hold_zap(tx, DMU_NEW_OBJECT, FALSE, NULL);
+	}
+	error = dmu_tx_assign(tx, TXG_WAIT);
+	if (error) {
+		dmu_tx_abort(tx);
+		return (error);
+	}
+
+	error = zap_update(os, MASTER_NODE_OBJ, ZPL_VERSION_STR,
+	    8, 1, &newvers, tx);
+
+	if (error) {
+		dmu_tx_commit(tx);
+		return (error);
+	}
+
+	if (newvers >= ZPL_VERSION_SA && !zsb->z_use_sa) {
+		uint64_t sa_obj;
+
+		ASSERT3U(spa_version(dmu_objset_spa(zsb->z_os)), >=,
+		    SPA_VERSION_SA);
+		sa_obj = zap_create(os, DMU_OT_SA_MASTER_NODE,
+		    DMU_OT_NONE, 0, tx);
+
+		error = zap_add(os, MASTER_NODE_OBJ,
+		    ZFS_SA_ATTRS, 8, 1, &sa_obj, tx);
+		ASSERT0(error);
+
+		VERIFY(0 == sa_set_sa_object(os, sa_obj));
+		sa_register_update_callback(os, zfs_sa_upgrade);
+	}
+
+	spa_history_log_internal_ds(dmu_objset_ds(os), "upgrade", tx,
+	    "from %llu to %llu", zsb->z_version, newvers);
+
+	dmu_tx_commit(tx);
+
+	zsb->z_version = newvers;
+
+	zfs_set_fuid_feature(zsb);
+
+	return (0);
+}
+EXPORT_SYMBOL(zfs_set_version);
+
+/*
+ * Read a property stored within the master node.
+ */
+int
+zfs_get_zplprop(objset_t *os, zfs_prop_t prop, uint64_t *value)
+{
+	const char *pname;
+	int error = SET_ERROR(ENOENT);
+
+	/*
+	 * Look up the file system's value for the property.  For the
+	 * version property, we look up a slightly different string.
+	 */
+	if (prop == ZFS_PROP_VERSION)
+		pname = ZPL_VERSION_STR;
+	else
+		pname = zfs_prop_to_name(prop);
+
+	if (os != NULL)
+		error = zap_lookup(os, MASTER_NODE_OBJ, pname, 8, 1, value);
+
+	if (error == ENOENT) {
+		/* No value set, use the default value */
+		switch (prop) {
+		case ZFS_PROP_VERSION:
+			*value = ZPL_VERSION;
+			break;
+		case ZFS_PROP_NORMALIZE:
+		case ZFS_PROP_UTF8ONLY:
+			*value = 0;
+			break;
+		case ZFS_PROP_CASE:
+			*value = ZFS_CASE_SENSITIVE;
+			break;
+		case ZFS_PROP_ACLTYPE:
+			*value = ZFS_ACLTYPE_OFF;
+			break;
+		default:
+			return (error);
+		}
+		error = 0;
+	}
+	return (error);
+}
+EXPORT_SYMBOL(zfs_get_zplprop);
+
+void
+zfs_init(void)
+{
+	zfsctl_init();
+	zfs_znode_init();
+	dmu_objset_register_type(DMU_OST_ZFS, zfs_space_delta_cb);
+	register_filesystem(&zpl_fs_type);
+}
+
+void
+zfs_fini(void)
+{
+	taskq_wait_outstanding(system_taskq, 0);
+	unregister_filesystem(&zpl_fs_type);
+	zfs_znode_fini();
+	zfsctl_fini();
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/module/zfs/zfs_vnops.c
@@ -0,0 +1,4673 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013 by Delphix. All rights reserved.
+ * Copyright (c) 2015 by Chunwei Chen. All rights reserved.
+ */
+
+/* Portions Copyright 2007 Jeremy Teo */
+/* Portions Copyright 2010 Robert Milkowski */
+
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/time.h>
+#include <sys/systm.h>
+#include <sys/sysmacros.h>
+#include <sys/resource.h>
+#include <sys/vfs.h>
+#include <sys/vfs_opreg.h>
+#include <sys/file.h>
+#include <sys/stat.h>
+#include <sys/kmem.h>
+#include <sys/taskq.h>
+#include <sys/uio.h>
+#include <sys/vmsystm.h>
+#include <sys/atomic.h>
+#include <vm/pvn.h>
+#include <sys/pathname.h>
+#include <sys/cmn_err.h>
+#include <sys/errno.h>
+#include <sys/unistd.h>
+#include <sys/zfs_dir.h>
+#include <sys/zfs_acl.h>
+#include <sys/zfs_ioctl.h>
+#include <sys/fs/zfs.h>
+#include <sys/dmu.h>
+#include <sys/dmu_objset.h>
+#include <sys/spa.h>
+#include <sys/txg.h>
+#include <sys/dbuf.h>
+#include <sys/zap.h>
+#include <sys/sa.h>
+#include <sys/dirent.h>
+#include <sys/policy.h>
+#include <sys/sunddi.h>
+#include <sys/sid.h>
+#include <sys/mode.h>
+#include "fs/fs_subr.h"
+#include <sys/zfs_ctldir.h>
+#include <sys/zfs_fuid.h>
+#include <sys/zfs_sa.h>
+#include <sys/zfs_vnops.h>
+#include <sys/dnlc.h>
+#include <sys/zfs_rlock.h>
+#include <sys/extdirent.h>
+#include <sys/kidmap.h>
+#include <sys/cred.h>
+#include <sys/attr.h>
+#include <sys/zpl.h>
+
+/*
+ * Programming rules.
+ *
+ * Each vnode op performs some logical unit of work.  To do this, the ZPL must
+ * properly lock its in-core state, create a DMU transaction, do the work,
+ * record this work in the intent log (ZIL), commit the DMU transaction,
+ * and wait for the intent log to commit if it is a synchronous operation.
+ * Moreover, the vnode ops must work in both normal and log replay context.
+ * The ordering of events is important to avoid deadlocks and references
+ * to freed memory.  The example below illustrates the following Big Rules:
+ *
+ *  (1) A check must be made in each zfs thread for a mounted file system.
+ *	This is done avoiding races using ZFS_ENTER(zsb).
+ *      A ZFS_EXIT(zsb) is needed before all returns.  Any znodes
+ *      must be checked with ZFS_VERIFY_ZP(zp).  Both of these macros
+ *      can return EIO from the calling function.
+ *
+ *  (2)	iput() should always be the last thing except for zil_commit()
+ *	(if necessary) and ZFS_EXIT(). This is for 3 reasons:
+ *	First, if it's the last reference, the vnode/znode
+ *	can be freed, so the zp may point to freed memory.  Second, the last
+ *	reference will call zfs_zinactive(), which may induce a lot of work --
+ *	pushing cached pages (which acquires range locks) and syncing out
+ *	cached atime changes.  Third, zfs_zinactive() may require a new tx,
+ *	which could deadlock the system if you were already holding one.
+ *	If you must call iput() within a tx then use zfs_iput_async().
+ *
+ *  (3)	All range locks must be grabbed before calling dmu_tx_assign(),
+ *	as they can span dmu_tx_assign() calls.
+ *
+ *  (4) If ZPL locks are held, pass TXG_NOWAIT as the second argument to
+ *      dmu_tx_assign().  This is critical because we don't want to block
+ *      while holding locks.
+ *
+ *	If no ZPL locks are held (aside from ZFS_ENTER()), use TXG_WAIT.  This
+ *	reduces lock contention and CPU usage when we must wait (note that if
+ *	throughput is constrained by the storage, nearly every transaction
+ *	must wait).
+ *
+ *      Note, in particular, that if a lock is sometimes acquired before
+ *      the tx assigns, and sometimes after (e.g. z_lock), then failing
+ *      to use a non-blocking assign can deadlock the system.  The scenario:
+ *
+ *	Thread A has grabbed a lock before calling dmu_tx_assign().
+ *	Thread B is in an already-assigned tx, and blocks for this lock.
+ *	Thread A calls dmu_tx_assign(TXG_WAIT) and blocks in txg_wait_open()
+ *	forever, because the previous txg can't quiesce until B's tx commits.
+ *
+ *	If dmu_tx_assign() returns ERESTART and zsb->z_assign is TXG_NOWAIT,
+ *	then drop all locks, call dmu_tx_wait(), and try again.  On subsequent
+ *	calls to dmu_tx_assign(), pass TXG_WAITED rather than TXG_NOWAIT,
+ *	to indicate that this operation has already called dmu_tx_wait().
+ *	This will ensure that we don't retry forever, waiting a short bit
+ *	each time.
+ *
+ *  (5)	If the operation succeeded, generate the intent log entry for it
+ *	before dropping locks.  This ensures that the ordering of events
+ *	in the intent log matches the order in which they actually occurred.
+ *	During ZIL replay the zfs_log_* functions will update the sequence
+ *	number to indicate the zil transaction has replayed.
+ *
+ *  (6)	At the end of each vnode op, the DMU tx must always commit,
+ *	regardless of whether there were any errors.
+ *
+ *  (7)	After dropping all locks, invoke zil_commit(zilog, foid)
+ *	to ensure that synchronous semantics are provided when necessary.
+ *
+ * In general, this is how things should be ordered in each vnode op:
+ *
+ *	ZFS_ENTER(zsb);		// exit if unmounted
+ * top:
+ *	zfs_dirent_lock(&dl, ...)	// lock directory entry (may igrab())
+ *	rw_enter(...);			// grab any other locks you need
+ *	tx = dmu_tx_create(...);	// get DMU tx
+ *	dmu_tx_hold_*();		// hold each object you might modify
+ *	error = dmu_tx_assign(tx, waited ? TXG_WAITED : TXG_NOWAIT);
+ *	if (error) {
+ *		rw_exit(...);		// drop locks
+ *		zfs_dirent_unlock(dl);	// unlock directory entry
+ *		iput(...);		// release held vnodes
+ *		if (error == ERESTART) {
+ *			waited = B_TRUE;
+ *			dmu_tx_wait(tx);
+ *			dmu_tx_abort(tx);
+ *			goto top;
+ *		}
+ *		dmu_tx_abort(tx);	// abort DMU tx
+ *		ZFS_EXIT(zsb);	// finished in zfs
+ *		return (error);		// really out of space
+ *	}
+ *	error = do_real_work();		// do whatever this VOP does
+ *	if (error == 0)
+ *		zfs_log_*(...);		// on success, make ZIL entry
+ *	dmu_tx_commit(tx);		// commit DMU tx -- error or not
+ *	rw_exit(...);			// drop locks
+ *	zfs_dirent_unlock(dl);		// unlock directory entry
+ *	iput(...);			// release held vnodes
+ *	zil_commit(zilog, foid);	// synchronous when necessary
+ *	ZFS_EXIT(zsb);		// finished in zfs
+ *	return (error);			// done, report error
+ */
+
+/*
+ * Virus scanning is unsupported.  It would be possible to add a hook
+ * here to performance the required virus scan.  This could be done
+ * entirely in the kernel or potentially as an update to invoke a
+ * scanning utility.
+ */
+static int
+zfs_vscan(struct inode *ip, cred_t *cr, int async)
+{
+	return (0);
+}
+
+/* ARGSUSED */
+int
+zfs_open(struct inode *ip, int mode, int flag, cred_t *cr)
+{
+	znode_t	*zp = ITOZ(ip);
+	zfs_sb_t *zsb = ITOZSB(ip);
+
+	ZFS_ENTER(zsb);
+	ZFS_VERIFY_ZP(zp);
+
+	/* Honor ZFS_APPENDONLY file attribute */
+	if ((mode & FMODE_WRITE) && (zp->z_pflags & ZFS_APPENDONLY) &&
+	    ((flag & O_APPEND) == 0)) {
+		ZFS_EXIT(zsb);
+		return (SET_ERROR(EPERM));
+	}
+
+	/* Virus scan eligible files on open */
+	if (!zfs_has_ctldir(zp) && zsb->z_vscan && S_ISREG(ip->i_mode) &&
+	    !(zp->z_pflags & ZFS_AV_QUARANTINED) && zp->z_size > 0) {
+		if (zfs_vscan(ip, cr, 0) != 0) {
+			ZFS_EXIT(zsb);
+			return (SET_ERROR(EACCES));
+		}
+	}
+
+	/* Keep a count of the synchronous opens in the znode */
+	if (flag & O_SYNC)
+		atomic_inc_32(&zp->z_sync_cnt);
+
+	ZFS_EXIT(zsb);
+	return (0);
+}
+EXPORT_SYMBOL(zfs_open);
+
+/* ARGSUSED */
+int
+zfs_close(struct inode *ip, int flag, cred_t *cr)
+{
+	znode_t	*zp = ITOZ(ip);
+	zfs_sb_t *zsb = ITOZSB(ip);
+
+	ZFS_ENTER(zsb);
+	ZFS_VERIFY_ZP(zp);
+
+	/* Decrement the synchronous opens in the znode */
+	if (flag & O_SYNC)
+		atomic_dec_32(&zp->z_sync_cnt);
+
+	if (!zfs_has_ctldir(zp) && zsb->z_vscan && S_ISREG(ip->i_mode) &&
+	    !(zp->z_pflags & ZFS_AV_QUARANTINED) && zp->z_size > 0)
+		VERIFY(zfs_vscan(ip, cr, 1) == 0);
+
+	ZFS_EXIT(zsb);
+	return (0);
+}
+EXPORT_SYMBOL(zfs_close);
+
+#if defined(SEEK_HOLE) && defined(SEEK_DATA)
+/*
+ * Lseek support for finding holes (cmd == SEEK_HOLE) and
+ * data (cmd == SEEK_DATA). "off" is an in/out parameter.
+ */
+static int
+zfs_holey_common(struct inode *ip, int cmd, loff_t *off)
+{
+	znode_t	*zp = ITOZ(ip);
+	uint64_t noff = (uint64_t)*off; /* new offset */
+	uint64_t file_sz;
+	int error;
+	boolean_t hole;
+
+	file_sz = zp->z_size;
+	if (noff >= file_sz)  {
+		return (SET_ERROR(ENXIO));
+	}
+
+	if (cmd == SEEK_HOLE)
+		hole = B_TRUE;
+	else
+		hole = B_FALSE;
+
+	error = dmu_offset_next(ZTOZSB(zp)->z_os, zp->z_id, hole, &noff);
+
+	if (error == ESRCH)
+		return (SET_ERROR(ENXIO));
+
+	/*
+	 * We could find a hole that begins after the logical end-of-file,
+	 * because dmu_offset_next() only works on whole blocks.  If the
+	 * EOF falls mid-block, then indicate that the "virtual hole"
+	 * at the end of the file begins at the logical EOF, rather than
+	 * at the end of the last block.
+	 */
+	if (noff > file_sz) {
+		ASSERT(hole);
+		noff = file_sz;
+	}
+
+	if (noff < *off)
+		return (error);
+	*off = noff;
+	return (error);
+}
+
+int
+zfs_holey(struct inode *ip, int cmd, loff_t *off)
+{
+	znode_t	*zp = ITOZ(ip);
+	zfs_sb_t *zsb = ITOZSB(ip);
+	int error;
+
+	ZFS_ENTER(zsb);
+	ZFS_VERIFY_ZP(zp);
+
+	error = zfs_holey_common(ip, cmd, off);
+
+	ZFS_EXIT(zsb);
+	return (error);
+}
+EXPORT_SYMBOL(zfs_holey);
+#endif /* SEEK_HOLE && SEEK_DATA */
+
+#if defined(_KERNEL)
+/*
+ * When a file is memory mapped, we must keep the IO data synchronized
+ * between the DMU cache and the memory mapped pages.  What this means:
+ *
+ * On Write:	If we find a memory mapped page, we write to *both*
+ *		the page and the dmu buffer.
+ */
+static void
+update_pages(struct inode *ip, int64_t start, int len,
+    objset_t *os, uint64_t oid)
+{
+	struct address_space *mp = ip->i_mapping;
+	struct page *pp;
+	uint64_t nbytes;
+	int64_t	off;
+	void *pb;
+
+	off = start & (PAGE_CACHE_SIZE-1);
+	for (start &= PAGE_CACHE_MASK; len > 0; start += PAGE_CACHE_SIZE) {
+		nbytes = MIN(PAGE_CACHE_SIZE - off, len);
+
+		pp = find_lock_page(mp, start >> PAGE_CACHE_SHIFT);
+		if (pp) {
+			if (mapping_writably_mapped(mp))
+				flush_dcache_page(pp);
+
+			pb = kmap(pp);
+			(void) dmu_read(os, oid, start+off, nbytes, pb+off,
+			    DMU_READ_PREFETCH);
+			kunmap(pp);
+
+			if (mapping_writably_mapped(mp))
+				flush_dcache_page(pp);
+
+			mark_page_accessed(pp);
+			SetPageUptodate(pp);
+			ClearPageError(pp);
+			unlock_page(pp);
+			page_cache_release(pp);
+		}
+
+		len -= nbytes;
+		off = 0;
+	}
+}
+
+/*
+ * When a file is memory mapped, we must keep the IO data synchronized
+ * between the DMU cache and the memory mapped pages.  What this means:
+ *
+ * On Read:	We "read" preferentially from memory mapped pages,
+ *		else we default from the dmu buffer.
+ *
+ * NOTE: We will always "break up" the IO into PAGESIZE uiomoves when
+ *	 the file is memory mapped.
+ */
+static int
+mappedread(struct inode *ip, int nbytes, uio_t *uio)
+{
+	struct address_space *mp = ip->i_mapping;
+	struct page *pp;
+	znode_t *zp = ITOZ(ip);
+	int64_t	start, off;
+	uint64_t bytes;
+	int len = nbytes;
+	int error = 0;
+	void *pb;
+
+	start = uio->uio_loffset;
+	off = start & (PAGE_CACHE_SIZE-1);
+	for (start &= PAGE_CACHE_MASK; len > 0; start += PAGE_CACHE_SIZE) {
+		bytes = MIN(PAGE_CACHE_SIZE - off, len);
+
+		pp = find_lock_page(mp, start >> PAGE_CACHE_SHIFT);
+		if (pp) {
+			ASSERT(PageUptodate(pp));
+
+			pb = kmap(pp);
+			error = uiomove(pb + off, bytes, UIO_READ, uio);
+			kunmap(pp);
+
+			if (mapping_writably_mapped(mp))
+				flush_dcache_page(pp);
+
+			mark_page_accessed(pp);
+			unlock_page(pp);
+			page_cache_release(pp);
+		} else {
+			error = dmu_read_uio_dbuf(sa_get_db(zp->z_sa_hdl),
+			    uio, bytes);
+		}
+
+		len -= bytes;
+		off = 0;
+		if (error)
+			break;
+	}
+	return (error);
+}
+#endif /* _KERNEL */
+
+unsigned long zfs_read_chunk_size = 1024 * 1024; /* Tunable */
+
+/*
+ * Read bytes from specified file into supplied buffer.
+ *
+ *	IN:	ip	- inode of file to be read from.
+ *		uio	- structure supplying read location, range info,
+ *			  and return buffer.
+ *		ioflag	- FSYNC flags; used to provide FRSYNC semantics.
+ *			  O_DIRECT flag; used to bypass page cache.
+ *		cr	- credentials of caller.
+ *
+ *	OUT:	uio	- updated offset and range, buffer filled.
+ *
+ *	RETURN:	0 on success, error code on failure.
+ *
+ * Side Effects:
+ *	inode - atime updated if byte count > 0
+ */
+/* ARGSUSED */
+int
+zfs_read(struct inode *ip, uio_t *uio, int ioflag, cred_t *cr)
+{
+	znode_t		*zp = ITOZ(ip);
+	zfs_sb_t	*zsb = ITOZSB(ip);
+	ssize_t		n, nbytes;
+	int		error = 0;
+	rl_t		*rl;
+#ifdef HAVE_UIO_ZEROCOPY
+	xuio_t		*xuio = NULL;
+#endif /* HAVE_UIO_ZEROCOPY */
+
+	ZFS_ENTER(zsb);
+	ZFS_VERIFY_ZP(zp);
+
+	if (zp->z_pflags & ZFS_AV_QUARANTINED) {
+		ZFS_EXIT(zsb);
+		return (SET_ERROR(EACCES));
+	}
+
+	/*
+	 * Validate file offset
+	 */
+	if (uio->uio_loffset < (offset_t)0) {
+		ZFS_EXIT(zsb);
+		return (SET_ERROR(EINVAL));
+	}
+
+	/*
+	 * Fasttrack empty reads
+	 */
+	if (uio->uio_resid == 0) {
+		ZFS_EXIT(zsb);
+		return (0);
+	}
+
+	/*
+	 * If we're in FRSYNC mode, sync out this znode before reading it.
+	 */
+	if (ioflag & FRSYNC || zsb->z_os->os_sync == ZFS_SYNC_ALWAYS)
+		zil_commit(zsb->z_log, zp->z_id);
+
+	/*
+	 * Lock the range against changes.
+	 */
+	rl = zfs_range_lock(zp, uio->uio_loffset, uio->uio_resid, RL_READER);
+
+	/*
+	 * If we are reading past end-of-file we can skip
+	 * to the end; but we might still need to set atime.
+	 */
+	if (uio->uio_loffset >= zp->z_size) {
+		error = 0;
+		goto out;
+	}
+
+	ASSERT(uio->uio_loffset < zp->z_size);
+	n = MIN(uio->uio_resid, zp->z_size - uio->uio_loffset);
+
+#ifdef HAVE_UIO_ZEROCOPY
+	if ((uio->uio_extflg == UIO_XUIO) &&
+	    (((xuio_t *)uio)->xu_type == UIOTYPE_ZEROCOPY)) {
+		int nblk;
+		int blksz = zp->z_blksz;
+		uint64_t offset = uio->uio_loffset;
+
+		xuio = (xuio_t *)uio;
+		if ((ISP2(blksz))) {
+			nblk = (P2ROUNDUP(offset + n, blksz) - P2ALIGN(offset,
+			    blksz)) / blksz;
+		} else {
+			ASSERT(offset + n <= blksz);
+			nblk = 1;
+		}
+		(void) dmu_xuio_init(xuio, nblk);
+
+		if (vn_has_cached_data(ip)) {
+			/*
+			 * For simplicity, we always allocate a full buffer
+			 * even if we only expect to read a portion of a block.
+			 */
+			while (--nblk >= 0) {
+				(void) dmu_xuio_add(xuio,
+				    dmu_request_arcbuf(sa_get_db(zp->z_sa_hdl),
+				    blksz), 0, blksz);
+			}
+		}
+	}
+#endif /* HAVE_UIO_ZEROCOPY */
+
+	while (n > 0) {
+		nbytes = MIN(n, zfs_read_chunk_size -
+		    P2PHASE(uio->uio_loffset, zfs_read_chunk_size));
+
+		if (zp->z_is_mapped && !(ioflag & O_DIRECT)) {
+			error = mappedread(ip, nbytes, uio);
+		} else {
+			error = dmu_read_uio_dbuf(sa_get_db(zp->z_sa_hdl),
+			    uio, nbytes);
+		}
+
+		if (error) {
+			/* convert checksum errors into IO errors */
+			if (error == ECKSUM)
+				error = SET_ERROR(EIO);
+			break;
+		}
+
+		n -= nbytes;
+	}
+out:
+	zfs_range_unlock(rl);
+
+	ZFS_ACCESSTIME_STAMP(zsb, zp);
+	ZFS_EXIT(zsb);
+	return (error);
+}
+EXPORT_SYMBOL(zfs_read);
+
+/*
+ * Write the bytes to a file.
+ *
+ *	IN:	ip	- inode of file to be written to.
+ *		uio	- structure supplying write location, range info,
+ *			  and data buffer.
+ *		ioflag	- FAPPEND flag set if in append mode.
+ *			  O_DIRECT flag; used to bypass page cache.
+ *		cr	- credentials of caller.
+ *
+ *	OUT:	uio	- updated offset and range.
+ *
+ *	RETURN:	0 if success
+ *		error code if failure
+ *
+ * Timestamps:
+ *	ip - ctime|mtime updated if byte count > 0
+ */
+
+/* ARGSUSED */
+int
+zfs_write(struct inode *ip, uio_t *uio, int ioflag, cred_t *cr)
+{
+	znode_t		*zp = ITOZ(ip);
+	rlim64_t	limit = uio->uio_limit;
+	ssize_t		start_resid = uio->uio_resid;
+	ssize_t		tx_bytes;
+	uint64_t	end_size;
+	dmu_tx_t	*tx;
+	zfs_sb_t	*zsb = ZTOZSB(zp);
+	zilog_t		*zilog;
+	offset_t	woff;
+	ssize_t		n, nbytes;
+	rl_t		*rl;
+	int		max_blksz = zsb->z_max_blksz;
+	int		error = 0;
+	arc_buf_t	*abuf;
+	const iovec_t	*aiov = NULL;
+	xuio_t		*xuio = NULL;
+	int		i_iov = 0;
+	const iovec_t	*iovp = uio->uio_iov;
+	int		write_eof;
+	int		count = 0;
+	sa_bulk_attr_t	bulk[4];
+	uint64_t	mtime[2], ctime[2];
+	ASSERTV(int	iovcnt = uio->uio_iovcnt);
+
+	/*
+	 * Fasttrack empty write
+	 */
+	n = start_resid;
+	if (n == 0)
+		return (0);
+
+	if (limit == RLIM64_INFINITY || limit > MAXOFFSET_T)
+		limit = MAXOFFSET_T;
+
+	ZFS_ENTER(zsb);
+	ZFS_VERIFY_ZP(zp);
+
+	SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_MTIME(zsb), NULL, &mtime, 16);
+	SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_CTIME(zsb), NULL, &ctime, 16);
+	SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_SIZE(zsb), NULL, &zp->z_size, 8);
+	SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_FLAGS(zsb), NULL,
+	    &zp->z_pflags, 8);
+
+	/*
+	 * If immutable or not appending then return EPERM
+	 */
+	if ((zp->z_pflags & (ZFS_IMMUTABLE | ZFS_READONLY)) ||
+	    ((zp->z_pflags & ZFS_APPENDONLY) && !(ioflag & FAPPEND) &&
+	    (uio->uio_loffset < zp->z_size))) {
+		ZFS_EXIT(zsb);
+		return (SET_ERROR(EPERM));
+	}
+
+	zilog = zsb->z_log;
+
+	/*
+	 * Validate file offset
+	 */
+	woff = ioflag & FAPPEND ? zp->z_size : uio->uio_loffset;
+	if (woff < 0) {
+		ZFS_EXIT(zsb);
+		return (SET_ERROR(EINVAL));
+	}
+
+	/*
+	 * Pre-fault the pages to ensure slow (eg NFS) pages
+	 * don't hold up txg.
+	 * Skip this if uio contains loaned arc_buf.
+	 */
+#ifdef HAVE_UIO_ZEROCOPY
+	if ((uio->uio_extflg == UIO_XUIO) &&
+	    (((xuio_t *)uio)->xu_type == UIOTYPE_ZEROCOPY))
+		xuio = (xuio_t *)uio;
+	else
+#endif
+		uio_prefaultpages(MIN(n, max_blksz), uio);
+
+	/*
+	 * If in append mode, set the io offset pointer to eof.
+	 */
+	if (ioflag & FAPPEND) {
+		/*
+		 * Obtain an appending range lock to guarantee file append
+		 * semantics.  We reset the write offset once we have the lock.
+		 */
+		rl = zfs_range_lock(zp, 0, n, RL_APPEND);
+		woff = rl->r_off;
+		if (rl->r_len == UINT64_MAX) {
+			/*
+			 * We overlocked the file because this write will cause
+			 * the file block size to increase.
+			 * Note that zp_size cannot change with this lock held.
+			 */
+			woff = zp->z_size;
+		}
+		uio->uio_loffset = woff;
+	} else {
+		/*
+		 * Note that if the file block size will change as a result of
+		 * this write, then this range lock will lock the entire file
+		 * so that we can re-write the block safely.
+		 */
+		rl = zfs_range_lock(zp, woff, n, RL_WRITER);
+	}
+
+	if (woff >= limit) {
+		zfs_range_unlock(rl);
+		ZFS_EXIT(zsb);
+		return (SET_ERROR(EFBIG));
+	}
+
+	if ((woff + n) > limit || woff > (limit - n))
+		n = limit - woff;
+
+	/* Will this write extend the file length? */
+	write_eof = (woff + n > zp->z_size);
+
+	end_size = MAX(zp->z_size, woff + n);
+
+	/*
+	 * Write the file in reasonable size chunks.  Each chunk is written
+	 * in a separate transaction; this keeps the intent log records small
+	 * and allows us to do more fine-grained space accounting.
+	 */
+	while (n > 0) {
+		abuf = NULL;
+		woff = uio->uio_loffset;
+		if (zfs_owner_overquota(zsb, zp, B_FALSE) ||
+		    zfs_owner_overquota(zsb, zp, B_TRUE)) {
+			if (abuf != NULL)
+				dmu_return_arcbuf(abuf);
+			error = SET_ERROR(EDQUOT);
+			break;
+		}
+
+		if (xuio && abuf == NULL) {
+			ASSERT(i_iov < iovcnt);
+			ASSERT3U(uio->uio_segflg, !=, UIO_BVEC);
+			aiov = &iovp[i_iov];
+			abuf = dmu_xuio_arcbuf(xuio, i_iov);
+			dmu_xuio_clear(xuio, i_iov);
+			ASSERT((aiov->iov_base == abuf->b_data) ||
+			    ((char *)aiov->iov_base - (char *)abuf->b_data +
+			    aiov->iov_len == arc_buf_size(abuf)));
+			i_iov++;
+		} else if (abuf == NULL && n >= max_blksz &&
+		    woff >= zp->z_size &&
+		    P2PHASE(woff, max_blksz) == 0 &&
+		    zp->z_blksz == max_blksz) {
+			/*
+			 * This write covers a full block.  "Borrow" a buffer
+			 * from the dmu so that we can fill it before we enter
+			 * a transaction.  This avoids the possibility of
+			 * holding up the transaction if the data copy hangs
+			 * up on a pagefault (e.g., from an NFS server mapping).
+			 */
+			size_t cbytes;
+
+			abuf = dmu_request_arcbuf(sa_get_db(zp->z_sa_hdl),
+			    max_blksz);
+			ASSERT(abuf != NULL);
+			ASSERT(arc_buf_size(abuf) == max_blksz);
+			if ((error = uiocopy(abuf->b_data, max_blksz,
+			    UIO_WRITE, uio, &cbytes))) {
+				dmu_return_arcbuf(abuf);
+				break;
+			}
+			ASSERT(cbytes == max_blksz);
+		}
+
+		/*
+		 * Start a transaction.
+		 */
+		tx = dmu_tx_create(zsb->z_os);
+		dmu_tx_hold_sa(tx, zp->z_sa_hdl, B_FALSE);
+		dmu_tx_hold_write(tx, zp->z_id, woff, MIN(n, max_blksz));
+		zfs_sa_upgrade_txholds(tx, zp);
+		error = dmu_tx_assign(tx, TXG_WAIT);
+		if (error) {
+			dmu_tx_abort(tx);
+			if (abuf != NULL)
+				dmu_return_arcbuf(abuf);
+			break;
+		}
+
+		/*
+		 * If zfs_range_lock() over-locked we grow the blocksize
+		 * and then reduce the lock range.  This will only happen
+		 * on the first iteration since zfs_range_reduce() will
+		 * shrink down r_len to the appropriate size.
+		 */
+		if (rl->r_len == UINT64_MAX) {
+			uint64_t new_blksz;
+
+			if (zp->z_blksz > max_blksz) {
+				/*
+				 * File's blocksize is already larger than the
+				 * "recordsize" property.  Only let it grow to
+				 * the next power of 2.
+				 */
+				ASSERT(!ISP2(zp->z_blksz));
+				new_blksz = MIN(end_size,
+				    1 << highbit64(zp->z_blksz));
+			} else {
+				new_blksz = MIN(end_size, max_blksz);
+			}
+			zfs_grow_blocksize(zp, new_blksz, tx);
+			zfs_range_reduce(rl, woff, n);
+		}
+
+		/*
+		 * XXX - should we really limit each write to z_max_blksz?
+		 * Perhaps we should use SPA_MAXBLOCKSIZE chunks?
+		 */
+		nbytes = MIN(n, max_blksz - P2PHASE(woff, max_blksz));
+
+		if (abuf == NULL) {
+			tx_bytes = uio->uio_resid;
+			error = dmu_write_uio_dbuf(sa_get_db(zp->z_sa_hdl),
+			    uio, nbytes, tx);
+			tx_bytes -= uio->uio_resid;
+		} else {
+			tx_bytes = nbytes;
+			ASSERT(xuio == NULL || tx_bytes == aiov->iov_len);
+			/*
+			 * If this is not a full block write, but we are
+			 * extending the file past EOF and this data starts
+			 * block-aligned, use assign_arcbuf().  Otherwise,
+			 * write via dmu_write().
+			 */
+			if (tx_bytes < max_blksz && (!write_eof ||
+			    aiov->iov_base != abuf->b_data)) {
+				ASSERT(xuio);
+				dmu_write(zsb->z_os, zp->z_id, woff,
+				    aiov->iov_len, aiov->iov_base, tx);
+				dmu_return_arcbuf(abuf);
+				xuio_stat_wbuf_copied();
+			} else {
+				ASSERT(xuio || tx_bytes == max_blksz);
+				dmu_assign_arcbuf(sa_get_db(zp->z_sa_hdl),
+				    woff, abuf, tx);
+			}
+			ASSERT(tx_bytes <= uio->uio_resid);
+			uioskip(uio, tx_bytes);
+		}
+
+		if (tx_bytes && zp->z_is_mapped && !(ioflag & O_DIRECT))
+			update_pages(ip, woff, tx_bytes, zsb->z_os, zp->z_id);
+
+		/*
+		 * If we made no progress, we're done.  If we made even
+		 * partial progress, update the znode and ZIL accordingly.
+		 */
+		if (tx_bytes == 0) {
+			(void) sa_update(zp->z_sa_hdl, SA_ZPL_SIZE(zsb),
+			    (void *)&zp->z_size, sizeof (uint64_t), tx);
+			dmu_tx_commit(tx);
+			ASSERT(error != 0);
+			break;
+		}
+
+		/*
+		 * Clear Set-UID/Set-GID bits on successful write if not
+		 * privileged and at least one of the excute bits is set.
+		 *
+		 * It would be nice to to this after all writes have
+		 * been done, but that would still expose the ISUID/ISGID
+		 * to another app after the partial write is committed.
+		 *
+		 * Note: we don't call zfs_fuid_map_id() here because
+		 * user 0 is not an ephemeral uid.
+		 */
+		mutex_enter(&zp->z_acl_lock);
+		if ((zp->z_mode & (S_IXUSR | (S_IXUSR >> 3) |
+		    (S_IXUSR >> 6))) != 0 &&
+		    (zp->z_mode & (S_ISUID | S_ISGID)) != 0 &&
+		    secpolicy_vnode_setid_retain(cr,
+		    (zp->z_mode & S_ISUID) != 0 && zp->z_uid == 0) != 0) {
+			uint64_t newmode;
+			zp->z_mode &= ~(S_ISUID | S_ISGID);
+			newmode = zp->z_mode;
+			(void) sa_update(zp->z_sa_hdl, SA_ZPL_MODE(zsb),
+			    (void *)&newmode, sizeof (uint64_t), tx);
+		}
+		mutex_exit(&zp->z_acl_lock);
+
+		zfs_tstamp_update_setup(zp, CONTENT_MODIFIED, mtime, ctime,
+		    B_TRUE);
+
+		/*
+		 * Update the file size (zp_size) if it has changed;
+		 * account for possible concurrent updates.
+		 */
+		while ((end_size = zp->z_size) < uio->uio_loffset) {
+			(void) atomic_cas_64(&zp->z_size, end_size,
+			    uio->uio_loffset);
+			ASSERT(error == 0);
+		}
+		/*
+		 * If we are replaying and eof is non zero then force
+		 * the file size to the specified eof. Note, there's no
+		 * concurrency during replay.
+		 */
+		if (zsb->z_replay && zsb->z_replay_eof != 0)
+			zp->z_size = zsb->z_replay_eof;
+
+		error = sa_bulk_update(zp->z_sa_hdl, bulk, count, tx);
+
+		zfs_log_write(zilog, tx, TX_WRITE, zp, woff, tx_bytes, ioflag,
+		    NULL, NULL);
+		dmu_tx_commit(tx);
+
+		if (error != 0)
+			break;
+		ASSERT(tx_bytes == nbytes);
+		n -= nbytes;
+
+		if (!xuio && n > 0)
+			uio_prefaultpages(MIN(n, max_blksz), uio);
+	}
+
+	zfs_inode_update(zp);
+	zfs_range_unlock(rl);
+
+	/*
+	 * If we're in replay mode, or we made no progress, return error.
+	 * Otherwise, it's at least a partial write, so it's successful.
+	 */
+	if (zsb->z_replay || uio->uio_resid == start_resid) {
+		ZFS_EXIT(zsb);
+		return (error);
+	}
+
+	if (ioflag & (FSYNC | FDSYNC) ||
+	    zsb->z_os->os_sync == ZFS_SYNC_ALWAYS)
+		zil_commit(zilog, zp->z_id);
+
+	ZFS_EXIT(zsb);
+	return (0);
+}
+EXPORT_SYMBOL(zfs_write);
+
+void
+zfs_iput_async(struct inode *ip)
+{
+	objset_t *os = ITOZSB(ip)->z_os;
+
+	ASSERT(atomic_read(&ip->i_count) > 0);
+	ASSERT(os != NULL);
+
+	if (atomic_read(&ip->i_count) == 1)
+		taskq_dispatch(dsl_pool_iput_taskq(dmu_objset_pool(os)),
+		    (task_func_t *)iput, ip, TQ_SLEEP);
+	else
+		iput(ip);
+}
+
+void
+zfs_get_done(zgd_t *zgd, int error)
+{
+	znode_t *zp = zgd->zgd_private;
+
+	if (zgd->zgd_db)
+		dmu_buf_rele(zgd->zgd_db, zgd);
+
+	zfs_range_unlock(zgd->zgd_rl);
+
+	/*
+	 * Release the vnode asynchronously as we currently have the
+	 * txg stopped from syncing.
+	 */
+	zfs_iput_async(ZTOI(zp));
+
+	if (error == 0 && zgd->zgd_bp)
+		zil_add_block(zgd->zgd_zilog, zgd->zgd_bp);
+
+	kmem_free(zgd, sizeof (zgd_t));
+}
+
+#ifdef DEBUG
+static int zil_fault_io = 0;
+#endif
+
+/*
+ * Get data to generate a TX_WRITE intent log record.
+ */
+int
+zfs_get_data(void *arg, lr_write_t *lr, char *buf, zio_t *zio)
+{
+	zfs_sb_t *zsb = arg;
+	objset_t *os = zsb->z_os;
+	znode_t *zp;
+	uint64_t object = lr->lr_foid;
+	uint64_t offset = lr->lr_offset;
+	uint64_t size = lr->lr_length;
+	blkptr_t *bp = &lr->lr_blkptr;
+	dmu_buf_t *db;
+	zgd_t *zgd;
+	int error = 0;
+
+	ASSERT(zio != NULL);
+	ASSERT(size != 0);
+
+	/*
+	 * Nothing to do if the file has been removed
+	 */
+	if (zfs_zget(zsb, object, &zp) != 0)
+		return (SET_ERROR(ENOENT));
+	if (zp->z_unlinked) {
+		/*
+		 * Release the vnode asynchronously as we currently have the
+		 * txg stopped from syncing.
+		 */
+		zfs_iput_async(ZTOI(zp));
+		return (SET_ERROR(ENOENT));
+	}
+
+	zgd = (zgd_t *)kmem_zalloc(sizeof (zgd_t), KM_SLEEP);
+	zgd->zgd_zilog = zsb->z_log;
+	zgd->zgd_private = zp;
+
+	/*
+	 * Write records come in two flavors: immediate and indirect.
+	 * For small writes it's cheaper to store the data with the
+	 * log record (immediate); for large writes it's cheaper to
+	 * sync the data and get a pointer to it (indirect) so that
+	 * we don't have to write the data twice.
+	 */
+	if (buf != NULL) { /* immediate write */
+		zgd->zgd_rl = zfs_range_lock(zp, offset, size, RL_READER);
+		/* test for truncation needs to be done while range locked */
+		if (offset >= zp->z_size) {
+			error = SET_ERROR(ENOENT);
+		} else {
+			error = dmu_read(os, object, offset, size, buf,
+			    DMU_READ_NO_PREFETCH);
+		}
+		ASSERT(error == 0 || error == ENOENT);
+	} else { /* indirect write */
+		/*
+		 * Have to lock the whole block to ensure when it's
+		 * written out and it's checksum is being calculated
+		 * that no one can change the data. We need to re-check
+		 * blocksize after we get the lock in case it's changed!
+		 */
+		for (;;) {
+			uint64_t blkoff;
+			size = zp->z_blksz;
+			blkoff = ISP2(size) ? P2PHASE(offset, size) : offset;
+			offset -= blkoff;
+			zgd->zgd_rl = zfs_range_lock(zp, offset, size,
+			    RL_READER);
+			if (zp->z_blksz == size)
+				break;
+			offset += blkoff;
+			zfs_range_unlock(zgd->zgd_rl);
+		}
+		/* test for truncation needs to be done while range locked */
+		if (lr->lr_offset >= zp->z_size)
+			error = SET_ERROR(ENOENT);
+#ifdef DEBUG
+		if (zil_fault_io) {
+			error = SET_ERROR(EIO);
+			zil_fault_io = 0;
+		}
+#endif
+		if (error == 0)
+			error = dmu_buf_hold(os, object, offset, zgd, &db,
+			    DMU_READ_NO_PREFETCH);
+
+		if (error == 0) {
+			blkptr_t *obp = dmu_buf_get_blkptr(db);
+			if (obp) {
+				ASSERT(BP_IS_HOLE(bp));
+				*bp = *obp;
+			}
+
+			zgd->zgd_db = db;
+			zgd->zgd_bp = bp;
+
+			ASSERT(db->db_offset == offset);
+			ASSERT(db->db_size == size);
+
+			error = dmu_sync(zio, lr->lr_common.lrc_txg,
+			    zfs_get_done, zgd);
+			ASSERT(error || lr->lr_length <= zp->z_blksz);
+
+			/*
+			 * On success, we need to wait for the write I/O
+			 * initiated by dmu_sync() to complete before we can
+			 * release this dbuf.  We will finish everything up
+			 * in the zfs_get_done() callback.
+			 */
+			if (error == 0)
+				return (0);
+
+			if (error == EALREADY) {
+				lr->lr_common.lrc_txtype = TX_WRITE2;
+				error = 0;
+			}
+		}
+	}
+
+	zfs_get_done(zgd, error);
+
+	return (error);
+}
+
+/*ARGSUSED*/
+int
+zfs_access(struct inode *ip, int mode, int flag, cred_t *cr)
+{
+	znode_t *zp = ITOZ(ip);
+	zfs_sb_t *zsb = ITOZSB(ip);
+	int error;
+
+	ZFS_ENTER(zsb);
+	ZFS_VERIFY_ZP(zp);
+
+	if (flag & V_ACE_MASK)
+		error = zfs_zaccess(zp, mode, flag, B_FALSE, cr);
+	else
+		error = zfs_zaccess_rwx(zp, mode, flag, cr);
+
+	ZFS_EXIT(zsb);
+	return (error);
+}
+EXPORT_SYMBOL(zfs_access);
+
+/*
+ * Lookup an entry in a directory, or an extended attribute directory.
+ * If it exists, return a held inode reference for it.
+ *
+ *	IN:	dip	- inode of directory to search.
+ *		nm	- name of entry to lookup.
+ *		flags	- LOOKUP_XATTR set if looking for an attribute.
+ *		cr	- credentials of caller.
+ *		direntflags - directory lookup flags
+ *		realpnp - returned pathname.
+ *
+ *	OUT:	ipp	- inode of located entry, NULL if not found.
+ *
+ *	RETURN:	0 on success, error code on failure.
+ *
+ * Timestamps:
+ *	NA
+ */
+/* ARGSUSED */
+int
+zfs_lookup(struct inode *dip, char *nm, struct inode **ipp, int flags,
+    cred_t *cr, int *direntflags, pathname_t *realpnp)
+{
+	znode_t *zdp = ITOZ(dip);
+	zfs_sb_t *zsb = ITOZSB(dip);
+	int error = 0;
+
+	/* fast path */
+	if (!(flags & (LOOKUP_XATTR | FIGNORECASE))) {
+
+		if (!S_ISDIR(dip->i_mode)) {
+			return (SET_ERROR(ENOTDIR));
+		} else if (zdp->z_sa_hdl == NULL) {
+			return (SET_ERROR(EIO));
+		}
+
+		if (nm[0] == 0 || (nm[0] == '.' && nm[1] == '\0')) {
+			error = zfs_fastaccesschk_execute(zdp, cr);
+			if (!error) {
+				*ipp = dip;
+				igrab(*ipp);
+				return (0);
+			}
+			return (error);
+#ifdef HAVE_DNLC
+		} else {
+			vnode_t *tvp = dnlc_lookup(dvp, nm);
+
+			if (tvp) {
+				error = zfs_fastaccesschk_execute(zdp, cr);
+				if (error) {
+					iput(tvp);
+					return (error);
+				}
+				if (tvp == DNLC_NO_VNODE) {
+					iput(tvp);
+					return (SET_ERROR(ENOENT));
+				} else {
+					*vpp = tvp;
+					return (specvp_check(vpp, cr));
+				}
+			}
+#endif /* HAVE_DNLC */
+		}
+	}
+
+	ZFS_ENTER(zsb);
+	ZFS_VERIFY_ZP(zdp);
+
+	*ipp = NULL;
+
+	if (flags & LOOKUP_XATTR) {
+		/*
+		 * We don't allow recursive attributes..
+		 * Maybe someday we will.
+		 */
+		if (zdp->z_pflags & ZFS_XATTR) {
+			ZFS_EXIT(zsb);
+			return (SET_ERROR(EINVAL));
+		}
+
+		if ((error = zfs_get_xattrdir(zdp, ipp, cr, flags))) {
+			ZFS_EXIT(zsb);
+			return (error);
+		}
+
+		/*
+		 * Do we have permission to get into attribute directory?
+		 */
+
+		if ((error = zfs_zaccess(ITOZ(*ipp), ACE_EXECUTE, 0,
+		    B_FALSE, cr))) {
+			iput(*ipp);
+			*ipp = NULL;
+		}
+
+		ZFS_EXIT(zsb);
+		return (error);
+	}
+
+	if (!S_ISDIR(dip->i_mode)) {
+		ZFS_EXIT(zsb);
+		return (SET_ERROR(ENOTDIR));
+	}
+
+	/*
+	 * Check accessibility of directory.
+	 */
+
+	if ((error = zfs_zaccess(zdp, ACE_EXECUTE, 0, B_FALSE, cr))) {
+		ZFS_EXIT(zsb);
+		return (error);
+	}
+
+	if (zsb->z_utf8 && u8_validate(nm, strlen(nm),
+	    NULL, U8_VALIDATE_ENTIRE, &error) < 0) {
+		ZFS_EXIT(zsb);
+		return (SET_ERROR(EILSEQ));
+	}
+
+	error = zfs_dirlook(zdp, nm, ipp, flags, direntflags, realpnp);
+	if ((error == 0) && (*ipp))
+		zfs_inode_update(ITOZ(*ipp));
+
+	ZFS_EXIT(zsb);
+	return (error);
+}
+EXPORT_SYMBOL(zfs_lookup);
+
+/*
+ * Attempt to create a new entry in a directory.  If the entry
+ * already exists, truncate the file if permissible, else return
+ * an error.  Return the ip of the created or trunc'd file.
+ *
+ *	IN:	dip	- inode of directory to put new file entry in.
+ *		name	- name of new file entry.
+ *		vap	- attributes of new file.
+ *		excl	- flag indicating exclusive or non-exclusive mode.
+ *		mode	- mode to open file with.
+ *		cr	- credentials of caller.
+ *		flag	- large file flag [UNUSED].
+ *		vsecp	- ACL to be set
+ *
+ *	OUT:	ipp	- inode of created or trunc'd entry.
+ *
+ *	RETURN:	0 on success, error code on failure.
+ *
+ * Timestamps:
+ *	dip - ctime|mtime updated if new entry created
+ *	 ip - ctime|mtime always, atime if new
+ */
+
+/* ARGSUSED */
+int
+zfs_create(struct inode *dip, char *name, vattr_t *vap, int excl,
+    int mode, struct inode **ipp, cred_t *cr, int flag, vsecattr_t *vsecp)
+{
+	znode_t		*zp, *dzp = ITOZ(dip);
+	zfs_sb_t	*zsb = ITOZSB(dip);
+	zilog_t		*zilog;
+	objset_t	*os;
+	zfs_dirlock_t	*dl;
+	dmu_tx_t	*tx;
+	int		error;
+	uid_t		uid;
+	gid_t		gid;
+	zfs_acl_ids_t   acl_ids;
+	boolean_t	fuid_dirtied;
+	boolean_t	have_acl = B_FALSE;
+	boolean_t	waited = B_FALSE;
+
+	/*
+	 * If we have an ephemeral id, ACL, or XVATTR then
+	 * make sure file system is at proper version
+	 */
+
+	gid = crgetgid(cr);
+	uid = crgetuid(cr);
+
+	if (zsb->z_use_fuids == B_FALSE &&
+	    (vsecp || IS_EPHEMERAL(uid) || IS_EPHEMERAL(gid)))
+		return (SET_ERROR(EINVAL));
+
+	ZFS_ENTER(zsb);
+	ZFS_VERIFY_ZP(dzp);
+	os = zsb->z_os;
+	zilog = zsb->z_log;
+
+	if (zsb->z_utf8 && u8_validate(name, strlen(name),
+	    NULL, U8_VALIDATE_ENTIRE, &error) < 0) {
+		ZFS_EXIT(zsb);
+		return (SET_ERROR(EILSEQ));
+	}
+
+	if (vap->va_mask & ATTR_XVATTR) {
+		if ((error = secpolicy_xvattr((xvattr_t *)vap,
+		    crgetuid(cr), cr, vap->va_mode)) != 0) {
+			ZFS_EXIT(zsb);
+			return (error);
+		}
+	}
+
+top:
+	*ipp = NULL;
+	if (*name == '\0') {
+		/*
+		 * Null component name refers to the directory itself.
+		 */
+		igrab(dip);
+		zp = dzp;
+		dl = NULL;
+		error = 0;
+	} else {
+		/* possible igrab(zp) */
+		int zflg = 0;
+
+		if (flag & FIGNORECASE)
+			zflg |= ZCILOOK;
+
+		error = zfs_dirent_lock(&dl, dzp, name, &zp, zflg,
+		    NULL, NULL);
+		if (error) {
+			if (have_acl)
+				zfs_acl_ids_free(&acl_ids);
+			if (strcmp(name, "..") == 0)
+				error = SET_ERROR(EISDIR);
+			ZFS_EXIT(zsb);
+			return (error);
+		}
+	}
+
+	if (zp == NULL) {
+		uint64_t txtype;
+
+		/*
+		 * Create a new file object and update the directory
+		 * to reference it.
+		 */
+		if ((error = zfs_zaccess(dzp, ACE_ADD_FILE, 0, B_FALSE, cr))) {
+			if (have_acl)
+				zfs_acl_ids_free(&acl_ids);
+			goto out;
+		}
+
+		/*
+		 * We only support the creation of regular files in
+		 * extended attribute directories.
+		 */
+
+		if ((dzp->z_pflags & ZFS_XATTR) && !S_ISREG(vap->va_mode)) {
+			if (have_acl)
+				zfs_acl_ids_free(&acl_ids);
+			error = SET_ERROR(EINVAL);
+			goto out;
+		}
+
+		if (!have_acl && (error = zfs_acl_ids_create(dzp, 0, vap,
+		    cr, vsecp, &acl_ids)) != 0)
+			goto out;
+		have_acl = B_TRUE;
+
+		if (zfs_acl_ids_overquota(zsb, &acl_ids)) {
+			zfs_acl_ids_free(&acl_ids);
+			error = SET_ERROR(EDQUOT);
+			goto out;
+		}
+
+		tx = dmu_tx_create(os);
+
+		dmu_tx_hold_sa_create(tx, acl_ids.z_aclp->z_acl_bytes +
+		    ZFS_SA_BASE_ATTR_SIZE);
+
+		fuid_dirtied = zsb->z_fuid_dirty;
+		if (fuid_dirtied)
+			zfs_fuid_txhold(zsb, tx);
+		dmu_tx_hold_zap(tx, dzp->z_id, TRUE, name);
+		dmu_tx_hold_sa(tx, dzp->z_sa_hdl, B_FALSE);
+		if (!zsb->z_use_sa &&
+		    acl_ids.z_aclp->z_acl_bytes > ZFS_ACE_SPACE) {
+			dmu_tx_hold_write(tx, DMU_NEW_OBJECT,
+			    0, acl_ids.z_aclp->z_acl_bytes);
+		}
+		error = dmu_tx_assign(tx, waited ? TXG_WAITED : TXG_NOWAIT);
+		if (error) {
+			zfs_dirent_unlock(dl);
+			if (error == ERESTART) {
+				waited = B_TRUE;
+				dmu_tx_wait(tx);
+				dmu_tx_abort(tx);
+				goto top;
+			}
+			zfs_acl_ids_free(&acl_ids);
+			dmu_tx_abort(tx);
+			ZFS_EXIT(zsb);
+			return (error);
+		}
+		zfs_mknode(dzp, vap, tx, cr, 0, &zp, &acl_ids);
+
+		if (fuid_dirtied)
+			zfs_fuid_sync(zsb, tx);
+
+		(void) zfs_link_create(dl, zp, tx, ZNEW);
+		txtype = zfs_log_create_txtype(Z_FILE, vsecp, vap);
+		if (flag & FIGNORECASE)
+			txtype |= TX_CI;
+		zfs_log_create(zilog, tx, txtype, dzp, zp, name,
+		    vsecp, acl_ids.z_fuidp, vap);
+		zfs_acl_ids_free(&acl_ids);
+		dmu_tx_commit(tx);
+	} else {
+		int aflags = (flag & FAPPEND) ? V_APPEND : 0;
+
+		if (have_acl)
+			zfs_acl_ids_free(&acl_ids);
+		have_acl = B_FALSE;
+
+		/*
+		 * A directory entry already exists for this name.
+		 */
+		/*
+		 * Can't truncate an existing file if in exclusive mode.
+		 */
+		if (excl) {
+			error = SET_ERROR(EEXIST);
+			goto out;
+		}
+		/*
+		 * Can't open a directory for writing.
+		 */
+		if (S_ISDIR(ZTOI(zp)->i_mode)) {
+			error = SET_ERROR(EISDIR);
+			goto out;
+		}
+		/*
+		 * Verify requested access to file.
+		 */
+		if (mode && (error = zfs_zaccess_rwx(zp, mode, aflags, cr))) {
+			goto out;
+		}
+
+		mutex_enter(&dzp->z_lock);
+		dzp->z_seq++;
+		mutex_exit(&dzp->z_lock);
+
+		/*
+		 * Truncate regular files if requested.
+		 */
+		if (S_ISREG(ZTOI(zp)->i_mode) &&
+		    (vap->va_mask & ATTR_SIZE) && (vap->va_size == 0)) {
+			/* we can't hold any locks when calling zfs_freesp() */
+			zfs_dirent_unlock(dl);
+			dl = NULL;
+			error = zfs_freesp(zp, 0, 0, mode, TRUE);
+		}
+	}
+out:
+
+	if (dl)
+		zfs_dirent_unlock(dl);
+
+	if (error) {
+		if (zp)
+			iput(ZTOI(zp));
+	} else {
+		zfs_inode_update(dzp);
+		zfs_inode_update(zp);
+		*ipp = ZTOI(zp);
+	}
+
+	if (zsb->z_os->os_sync == ZFS_SYNC_ALWAYS)
+		zil_commit(zilog, 0);
+
+	ZFS_EXIT(zsb);
+	return (error);
+}
+EXPORT_SYMBOL(zfs_create);
+
+/*
+ * Remove an entry from a directory.
+ *
+ *	IN:	dip	- inode of directory to remove entry from.
+ *		name	- name of entry to remove.
+ *		cr	- credentials of caller.
+ *
+ *	RETURN:	0 if success
+ *		error code if failure
+ *
+ * Timestamps:
+ *	dip - ctime|mtime
+ *	 ip - ctime (if nlink > 0)
+ */
+
+uint64_t null_xattr = 0;
+
+/*ARGSUSED*/
+int
+zfs_remove(struct inode *dip, char *name, cred_t *cr)
+{
+	znode_t		*zp, *dzp = ITOZ(dip);
+	znode_t		*xzp;
+	struct inode	*ip;
+	zfs_sb_t	*zsb = ITOZSB(dip);
+	zilog_t		*zilog;
+	uint64_t	xattr_obj;
+	uint64_t	xattr_obj_unlinked = 0;
+	uint64_t	obj = 0;
+	zfs_dirlock_t	*dl;
+	dmu_tx_t	*tx;
+	boolean_t	unlinked;
+	uint64_t	txtype;
+	pathname_t	*realnmp = NULL;
+#ifdef HAVE_PN_UTILS
+	pathname_t	realnm;
+#endif /* HAVE_PN_UTILS */
+	int		error;
+	int		zflg = ZEXISTS;
+	boolean_t	waited = B_FALSE;
+
+	ZFS_ENTER(zsb);
+	ZFS_VERIFY_ZP(dzp);
+	zilog = zsb->z_log;
+
+#ifdef HAVE_PN_UTILS
+	if (flags & FIGNORECASE) {
+		zflg |= ZCILOOK;
+		pn_alloc(&realnm);
+		realnmp = &realnm;
+	}
+#endif /* HAVE_PN_UTILS */
+
+top:
+	xattr_obj = 0;
+	xzp = NULL;
+	/*
+	 * Attempt to lock directory; fail if entry doesn't exist.
+	 */
+	if ((error = zfs_dirent_lock(&dl, dzp, name, &zp, zflg,
+	    NULL, realnmp))) {
+#ifdef HAVE_PN_UTILS
+		if (realnmp)
+			pn_free(realnmp);
+#endif /* HAVE_PN_UTILS */
+		ZFS_EXIT(zsb);
+		return (error);
+	}
+
+	ip = ZTOI(zp);
+
+	if ((error = zfs_zaccess_delete(dzp, zp, cr))) {
+		goto out;
+	}
+
+	/*
+	 * Need to use rmdir for removing directories.
+	 */
+	if (S_ISDIR(ip->i_mode)) {
+		error = SET_ERROR(EPERM);
+		goto out;
+	}
+
+#ifdef HAVE_DNLC
+	if (realnmp)
+		dnlc_remove(dvp, realnmp->pn_buf);
+	else
+		dnlc_remove(dvp, name);
+#endif /* HAVE_DNLC */
+
+	/*
+	 * We never delete the znode and always place it in the unlinked
+	 * set.  The dentry cache will always hold the last reference and
+	 * is responsible for safely freeing the znode.
+	 */
+	obj = zp->z_id;
+	tx = dmu_tx_create(zsb->z_os);
+	dmu_tx_hold_zap(tx, dzp->z_id, FALSE, name);
+	dmu_tx_hold_sa(tx, zp->z_sa_hdl, B_FALSE);
+	zfs_sa_upgrade_txholds(tx, zp);
+	zfs_sa_upgrade_txholds(tx, dzp);
+
+	/* are there any extended attributes? */
+	error = sa_lookup(zp->z_sa_hdl, SA_ZPL_XATTR(zsb),
+	    &xattr_obj, sizeof (xattr_obj));
+	if (error == 0 && xattr_obj) {
+		error = zfs_zget(zsb, xattr_obj, &xzp);
+		ASSERT0(error);
+		dmu_tx_hold_sa(tx, zp->z_sa_hdl, B_TRUE);
+		dmu_tx_hold_sa(tx, xzp->z_sa_hdl, B_FALSE);
+	}
+
+	/* charge as an update -- would be nice not to charge at all */
+	dmu_tx_hold_zap(tx, zsb->z_unlinkedobj, FALSE, NULL);
+
+	error = dmu_tx_assign(tx, waited ? TXG_WAITED : TXG_NOWAIT);
+	if (error) {
+		zfs_dirent_unlock(dl);
+		iput(ip);
+		if (xzp)
+			iput(ZTOI(xzp));
+		if (error == ERESTART) {
+			waited = B_TRUE;
+			dmu_tx_wait(tx);
+			dmu_tx_abort(tx);
+			goto top;
+		}
+#ifdef HAVE_PN_UTILS
+		if (realnmp)
+			pn_free(realnmp);
+#endif /* HAVE_PN_UTILS */
+		dmu_tx_abort(tx);
+		ZFS_EXIT(zsb);
+		return (error);
+	}
+
+	/*
+	 * Remove the directory entry.
+	 */
+	error = zfs_link_destroy(dl, zp, tx, zflg, &unlinked);
+
+	if (error) {
+		dmu_tx_commit(tx);
+		goto out;
+	}
+
+	if (unlinked) {
+		/*
+		 * Hold z_lock so that we can make sure that the ACL obj
+		 * hasn't changed.  Could have been deleted due to
+		 * zfs_sa_upgrade().
+		 */
+		mutex_enter(&zp->z_lock);
+		(void) sa_lookup(zp->z_sa_hdl, SA_ZPL_XATTR(zsb),
+		    &xattr_obj_unlinked, sizeof (xattr_obj_unlinked));
+		mutex_exit(&zp->z_lock);
+		zfs_unlinked_add(zp, tx);
+	}
+
+	txtype = TX_REMOVE;
+#ifdef HAVE_PN_UTILS
+	if (flags & FIGNORECASE)
+		txtype |= TX_CI;
+#endif /* HAVE_PN_UTILS */
+	zfs_log_remove(zilog, tx, txtype, dzp, name, obj);
+
+	dmu_tx_commit(tx);
+out:
+#ifdef HAVE_PN_UTILS
+	if (realnmp)
+		pn_free(realnmp);
+#endif /* HAVE_PN_UTILS */
+
+	zfs_dirent_unlock(dl);
+	zfs_inode_update(dzp);
+	zfs_inode_update(zp);
+	if (xzp)
+		zfs_inode_update(xzp);
+
+	iput(ip);
+	if (xzp)
+		iput(ZTOI(xzp));
+
+	if (zsb->z_os->os_sync == ZFS_SYNC_ALWAYS)
+		zil_commit(zilog, 0);
+
+	ZFS_EXIT(zsb);
+	return (error);
+}
+EXPORT_SYMBOL(zfs_remove);
+
+/*
+ * Create a new directory and insert it into dip using the name
+ * provided.  Return a pointer to the inserted directory.
+ *
+ *	IN:	dip	- inode of directory to add subdir to.
+ *		dirname	- name of new directory.
+ *		vap	- attributes of new directory.
+ *		cr	- credentials of caller.
+ *		vsecp	- ACL to be set
+ *
+ *	OUT:	ipp	- inode of created directory.
+ *
+ *	RETURN:	0 if success
+ *		error code if failure
+ *
+ * Timestamps:
+ *	dip - ctime|mtime updated
+ *	ipp - ctime|mtime|atime updated
+ */
+/*ARGSUSED*/
+int
+zfs_mkdir(struct inode *dip, char *dirname, vattr_t *vap, struct inode **ipp,
+    cred_t *cr, int flags, vsecattr_t *vsecp)
+{
+	znode_t		*zp, *dzp = ITOZ(dip);
+	zfs_sb_t	*zsb = ITOZSB(dip);
+	zilog_t		*zilog;
+	zfs_dirlock_t	*dl;
+	uint64_t	txtype;
+	dmu_tx_t	*tx;
+	int		error;
+	int		zf = ZNEW;
+	uid_t		uid;
+	gid_t		gid = crgetgid(cr);
+	zfs_acl_ids_t   acl_ids;
+	boolean_t	fuid_dirtied;
+	boolean_t	waited = B_FALSE;
+
+	ASSERT(S_ISDIR(vap->va_mode));
+
+	/*
+	 * If we have an ephemeral id, ACL, or XVATTR then
+	 * make sure file system is at proper version
+	 */
+
+	uid = crgetuid(cr);
+	if (zsb->z_use_fuids == B_FALSE &&
+	    (vsecp || IS_EPHEMERAL(uid) || IS_EPHEMERAL(gid)))
+		return (SET_ERROR(EINVAL));
+
+	ZFS_ENTER(zsb);
+	ZFS_VERIFY_ZP(dzp);
+	zilog = zsb->z_log;
+
+	if (dzp->z_pflags & ZFS_XATTR) {
+		ZFS_EXIT(zsb);
+		return (SET_ERROR(EINVAL));
+	}
+
+	if (zsb->z_utf8 && u8_validate(dirname,
+	    strlen(dirname), NULL, U8_VALIDATE_ENTIRE, &error) < 0) {
+		ZFS_EXIT(zsb);
+		return (SET_ERROR(EILSEQ));
+	}
+	if (flags & FIGNORECASE)
+		zf |= ZCILOOK;
+
+	if (vap->va_mask & ATTR_XVATTR) {
+		if ((error = secpolicy_xvattr((xvattr_t *)vap,
+		    crgetuid(cr), cr, vap->va_mode)) != 0) {
+			ZFS_EXIT(zsb);
+			return (error);
+		}
+	}
+
+	if ((error = zfs_acl_ids_create(dzp, 0, vap, cr,
+	    vsecp, &acl_ids)) != 0) {
+		ZFS_EXIT(zsb);
+		return (error);
+	}
+	/*
+	 * First make sure the new directory doesn't exist.
+	 *
+	 * Existence is checked first to make sure we don't return
+	 * EACCES instead of EEXIST which can cause some applications
+	 * to fail.
+	 */
+top:
+	*ipp = NULL;
+
+	if ((error = zfs_dirent_lock(&dl, dzp, dirname, &zp, zf,
+	    NULL, NULL))) {
+		zfs_acl_ids_free(&acl_ids);
+		ZFS_EXIT(zsb);
+		return (error);
+	}
+
+	if ((error = zfs_zaccess(dzp, ACE_ADD_SUBDIRECTORY, 0, B_FALSE, cr))) {
+		zfs_acl_ids_free(&acl_ids);
+		zfs_dirent_unlock(dl);
+		ZFS_EXIT(zsb);
+		return (error);
+	}
+
+	if (zfs_acl_ids_overquota(zsb, &acl_ids)) {
+		zfs_acl_ids_free(&acl_ids);
+		zfs_dirent_unlock(dl);
+		ZFS_EXIT(zsb);
+		return (SET_ERROR(EDQUOT));
+	}
+
+	/*
+	 * Add a new entry to the directory.
+	 */
+	tx = dmu_tx_create(zsb->z_os);
+	dmu_tx_hold_zap(tx, dzp->z_id, TRUE, dirname);
+	dmu_tx_hold_zap(tx, DMU_NEW_OBJECT, FALSE, NULL);
+	fuid_dirtied = zsb->z_fuid_dirty;
+	if (fuid_dirtied)
+		zfs_fuid_txhold(zsb, tx);
+	if (!zsb->z_use_sa && acl_ids.z_aclp->z_acl_bytes > ZFS_ACE_SPACE) {
+		dmu_tx_hold_write(tx, DMU_NEW_OBJECT, 0,
+		    acl_ids.z_aclp->z_acl_bytes);
+	}
+
+	dmu_tx_hold_sa_create(tx, acl_ids.z_aclp->z_acl_bytes +
+	    ZFS_SA_BASE_ATTR_SIZE);
+
+	error = dmu_tx_assign(tx, waited ? TXG_WAITED : TXG_NOWAIT);
+	if (error) {
+		zfs_dirent_unlock(dl);
+		if (error == ERESTART) {
+			waited = B_TRUE;
+			dmu_tx_wait(tx);
+			dmu_tx_abort(tx);
+			goto top;
+		}
+		zfs_acl_ids_free(&acl_ids);
+		dmu_tx_abort(tx);
+		ZFS_EXIT(zsb);
+		return (error);
+	}
+
+	/*
+	 * Create new node.
+	 */
+	zfs_mknode(dzp, vap, tx, cr, 0, &zp, &acl_ids);
+
+	if (fuid_dirtied)
+		zfs_fuid_sync(zsb, tx);
+
+	/*
+	 * Now put new name in parent dir.
+	 */
+	(void) zfs_link_create(dl, zp, tx, ZNEW);
+
+	*ipp = ZTOI(zp);
+
+	txtype = zfs_log_create_txtype(Z_DIR, vsecp, vap);
+	if (flags & FIGNORECASE)
+		txtype |= TX_CI;
+	zfs_log_create(zilog, tx, txtype, dzp, zp, dirname, vsecp,
+	    acl_ids.z_fuidp, vap);
+
+	zfs_acl_ids_free(&acl_ids);
+
+	dmu_tx_commit(tx);
+
+	zfs_dirent_unlock(dl);
+
+	if (zsb->z_os->os_sync == ZFS_SYNC_ALWAYS)
+		zil_commit(zilog, 0);
+
+	zfs_inode_update(dzp);
+	zfs_inode_update(zp);
+	ZFS_EXIT(zsb);
+	return (0);
+}
+EXPORT_SYMBOL(zfs_mkdir);
+
+/*
+ * Remove a directory subdir entry.  If the current working
+ * directory is the same as the subdir to be removed, the
+ * remove will fail.
+ *
+ *	IN:	dip	- inode of directory to remove from.
+ *		name	- name of directory to be removed.
+ *		cwd	- inode of current working directory.
+ *		cr	- credentials of caller.
+ *		flags	- case flags
+ *
+ *	RETURN:	0 on success, error code on failure.
+ *
+ * Timestamps:
+ *	dip - ctime|mtime updated
+ */
+/*ARGSUSED*/
+int
+zfs_rmdir(struct inode *dip, char *name, struct inode *cwd, cred_t *cr,
+    int flags)
+{
+	znode_t		*dzp = ITOZ(dip);
+	znode_t		*zp;
+	struct inode	*ip;
+	zfs_sb_t	*zsb = ITOZSB(dip);
+	zilog_t		*zilog;
+	zfs_dirlock_t	*dl;
+	dmu_tx_t	*tx;
+	int		error;
+	int		zflg = ZEXISTS;
+	boolean_t	waited = B_FALSE;
+
+	ZFS_ENTER(zsb);
+	ZFS_VERIFY_ZP(dzp);
+	zilog = zsb->z_log;
+
+	if (flags & FIGNORECASE)
+		zflg |= ZCILOOK;
+top:
+	zp = NULL;
+
+	/*
+	 * Attempt to lock directory; fail if entry doesn't exist.
+	 */
+	if ((error = zfs_dirent_lock(&dl, dzp, name, &zp, zflg,
+	    NULL, NULL))) {
+		ZFS_EXIT(zsb);
+		return (error);
+	}
+
+	ip = ZTOI(zp);
+
+	if ((error = zfs_zaccess_delete(dzp, zp, cr))) {
+		goto out;
+	}
+
+	if (!S_ISDIR(ip->i_mode)) {
+		error = SET_ERROR(ENOTDIR);
+		goto out;
+	}
+
+	if (ip == cwd) {
+		error = SET_ERROR(EINVAL);
+		goto out;
+	}
+
+	/*
+	 * Grab a lock on the directory to make sure that noone is
+	 * trying to add (or lookup) entries while we are removing it.
+	 */
+	rw_enter(&zp->z_name_lock, RW_WRITER);
+
+	/*
+	 * Grab a lock on the parent pointer to make sure we play well
+	 * with the treewalk and directory rename code.
+	 */
+	rw_enter(&zp->z_parent_lock, RW_WRITER);
+
+	tx = dmu_tx_create(zsb->z_os);
+	dmu_tx_hold_zap(tx, dzp->z_id, FALSE, name);
+	dmu_tx_hold_sa(tx, zp->z_sa_hdl, B_FALSE);
+	dmu_tx_hold_zap(tx, zsb->z_unlinkedobj, FALSE, NULL);
+	zfs_sa_upgrade_txholds(tx, zp);
+	zfs_sa_upgrade_txholds(tx, dzp);
+	error = dmu_tx_assign(tx, waited ? TXG_WAITED : TXG_NOWAIT);
+	if (error) {
+		rw_exit(&zp->z_parent_lock);
+		rw_exit(&zp->z_name_lock);
+		zfs_dirent_unlock(dl);
+		iput(ip);
+		if (error == ERESTART) {
+			waited = B_TRUE;
+			dmu_tx_wait(tx);
+			dmu_tx_abort(tx);
+			goto top;
+		}
+		dmu_tx_abort(tx);
+		ZFS_EXIT(zsb);
+		return (error);
+	}
+
+	error = zfs_link_destroy(dl, zp, tx, zflg, NULL);
+
+	if (error == 0) {
+		uint64_t txtype = TX_RMDIR;
+		if (flags & FIGNORECASE)
+			txtype |= TX_CI;
+		zfs_log_remove(zilog, tx, txtype, dzp, name, ZFS_NO_OBJECT);
+	}
+
+	dmu_tx_commit(tx);
+
+	rw_exit(&zp->z_parent_lock);
+	rw_exit(&zp->z_name_lock);
+out:
+	zfs_dirent_unlock(dl);
+
+	zfs_inode_update(dzp);
+	zfs_inode_update(zp);
+	iput(ip);
+
+	if (zsb->z_os->os_sync == ZFS_SYNC_ALWAYS)
+		zil_commit(zilog, 0);
+
+	ZFS_EXIT(zsb);
+	return (error);
+}
+EXPORT_SYMBOL(zfs_rmdir);
+
+/*
+ * Read as many directory entries as will fit into the provided
+ * dirent buffer from the given directory cursor position.
+ *
+ *	IN:	ip	- inode of directory to read.
+ *		dirent	- buffer for directory entries.
+ *
+ *	OUT:	dirent	- filler buffer of directory entries.
+ *
+ *	RETURN:	0 if success
+ *		error code if failure
+ *
+ * Timestamps:
+ *	ip - atime updated
+ *
+ * Note that the low 4 bits of the cookie returned by zap is always zero.
+ * This allows us to use the low range for "special" directory entries:
+ * We use 0 for '.', and 1 for '..'.  If this is the root of the filesystem,
+ * we use the offset 2 for the '.zfs' directory.
+ */
+/* ARGSUSED */
+int
+zfs_readdir(struct inode *ip, struct dir_context *ctx, cred_t *cr)
+{
+	znode_t		*zp = ITOZ(ip);
+	zfs_sb_t	*zsb = ITOZSB(ip);
+	objset_t	*os;
+	zap_cursor_t	zc;
+	zap_attribute_t	zap;
+	int		error;
+	uint8_t		prefetch;
+	uint8_t		type;
+	int		done = 0;
+	uint64_t	parent;
+	uint64_t	offset; /* must be unsigned; checks for < 1 */
+
+	ZFS_ENTER(zsb);
+	ZFS_VERIFY_ZP(zp);
+
+	if ((error = sa_lookup(zp->z_sa_hdl, SA_ZPL_PARENT(zsb),
+	    &parent, sizeof (parent))) != 0)
+		goto out;
+
+	/*
+	 * Quit if directory has been removed (posix)
+	 */
+	if (zp->z_unlinked)
+		goto out;
+
+	error = 0;
+	os = zsb->z_os;
+	offset = ctx->pos;
+	prefetch = zp->z_zn_prefetch;
+
+	/*
+	 * Initialize the iterator cursor.
+	 */
+	if (offset <= 3) {
+		/*
+		 * Start iteration from the beginning of the directory.
+		 */
+		zap_cursor_init(&zc, os, zp->z_id);
+	} else {
+		/*
+		 * The offset is a serialized cursor.
+		 */
+		zap_cursor_init_serialized(&zc, os, zp->z_id, offset);
+	}
+
+	/*
+	 * Transform to file-system independent format
+	 */
+	while (!done) {
+		uint64_t objnum;
+		/*
+		 * Special case `.', `..', and `.zfs'.
+		 */
+		if (offset == 0) {
+			(void) strcpy(zap.za_name, ".");
+			zap.za_normalization_conflict = 0;
+			objnum = zp->z_id;
+			type = DT_DIR;
+		} else if (offset == 1) {
+			(void) strcpy(zap.za_name, "..");
+			zap.za_normalization_conflict = 0;
+			objnum = parent;
+			type = DT_DIR;
+		} else if (offset == 2 && zfs_show_ctldir(zp)) {
+			(void) strcpy(zap.za_name, ZFS_CTLDIR_NAME);
+			zap.za_normalization_conflict = 0;
+			objnum = ZFSCTL_INO_ROOT;
+			type = DT_DIR;
+		} else {
+			/*
+			 * Grab next entry.
+			 */
+			if ((error = zap_cursor_retrieve(&zc, &zap))) {
+				if (error == ENOENT)
+					break;
+				else
+					goto update;
+			}
+
+			/*
+			 * Allow multiple entries provided the first entry is
+			 * the object id.  Non-zpl consumers may safely make
+			 * use of the additional space.
+			 *
+			 * XXX: This should be a feature flag for compatibility
+			 */
+			if (zap.za_integer_length != 8 ||
+			    zap.za_num_integers == 0) {
+				cmn_err(CE_WARN, "zap_readdir: bad directory "
+				    "entry, obj = %lld, offset = %lld, "
+				    "length = %d, num = %lld\n",
+				    (u_longlong_t)zp->z_id,
+				    (u_longlong_t)offset,
+				    zap.za_integer_length,
+				    (u_longlong_t)zap.za_num_integers);
+				error = SET_ERROR(ENXIO);
+				goto update;
+			}
+
+			objnum = ZFS_DIRENT_OBJ(zap.za_first_integer);
+			type = ZFS_DIRENT_TYPE(zap.za_first_integer);
+		}
+
+		done = !dir_emit(ctx, zap.za_name, strlen(zap.za_name),
+		    objnum, type);
+		if (done)
+			break;
+
+		/* Prefetch znode */
+		if (prefetch) {
+			dmu_prefetch(os, objnum, 0, 0);
+		}
+
+		/*
+		 * Move to the next entry, fill in the previous offset.
+		 */
+		if (offset > 2 || (offset == 2 && !zfs_show_ctldir(zp))) {
+			zap_cursor_advance(&zc);
+			offset = zap_cursor_serialize(&zc);
+		} else {
+			offset += 1;
+		}
+		ctx->pos = offset;
+	}
+	zp->z_zn_prefetch = B_FALSE; /* a lookup will re-enable pre-fetching */
+
+update:
+	zap_cursor_fini(&zc);
+	if (error == ENOENT)
+		error = 0;
+
+	ZFS_ACCESSTIME_STAMP(zsb, zp);
+
+out:
+	ZFS_EXIT(zsb);
+
+	return (error);
+}
+EXPORT_SYMBOL(zfs_readdir);
+
+ulong_t zfs_fsync_sync_cnt = 4;
+
+int
+zfs_fsync(struct inode *ip, int syncflag, cred_t *cr)
+{
+	znode_t	*zp = ITOZ(ip);
+	zfs_sb_t *zsb = ITOZSB(ip);
+
+	(void) tsd_set(zfs_fsyncer_key, (void *)zfs_fsync_sync_cnt);
+
+	if (zsb->z_os->os_sync != ZFS_SYNC_DISABLED) {
+		ZFS_ENTER(zsb);
+		ZFS_VERIFY_ZP(zp);
+		zil_commit(zsb->z_log, zp->z_id);
+		ZFS_EXIT(zsb);
+	}
+	tsd_set(zfs_fsyncer_key, NULL);
+
+	return (0);
+}
+EXPORT_SYMBOL(zfs_fsync);
+
+
+/*
+ * Get the requested file attributes and place them in the provided
+ * vattr structure.
+ *
+ *	IN:	ip	- inode of file.
+ *		vap	- va_mask identifies requested attributes.
+ *			  If ATTR_XVATTR set, then optional attrs are requested
+ *		flags	- ATTR_NOACLCHECK (CIFS server context)
+ *		cr	- credentials of caller.
+ *
+ *	OUT:	vap	- attribute values.
+ *
+ *	RETURN:	0 (always succeeds)
+ */
+/* ARGSUSED */
+int
+zfs_getattr(struct inode *ip, vattr_t *vap, int flags, cred_t *cr)
+{
+	znode_t *zp = ITOZ(ip);
+	zfs_sb_t *zsb = ITOZSB(ip);
+	int	error = 0;
+	uint64_t links;
+	uint64_t mtime[2], ctime[2];
+	xvattr_t *xvap = (xvattr_t *)vap;	/* vap may be an xvattr_t * */
+	xoptattr_t *xoap = NULL;
+	boolean_t skipaclchk = (flags & ATTR_NOACLCHECK) ? B_TRUE : B_FALSE;
+	sa_bulk_attr_t bulk[2];
+	int count = 0;
+
+	ZFS_ENTER(zsb);
+	ZFS_VERIFY_ZP(zp);
+
+	zfs_fuid_map_ids(zp, cr, &vap->va_uid, &vap->va_gid);
+
+	SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_MTIME(zsb), NULL, &mtime, 16);
+	SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_CTIME(zsb), NULL, &ctime, 16);
+
+	if ((error = sa_bulk_lookup(zp->z_sa_hdl, bulk, count)) != 0) {
+		ZFS_EXIT(zsb);
+		return (error);
+	}
+
+	/*
+	 * If ACL is trivial don't bother looking for ACE_READ_ATTRIBUTES.
+	 * Also, if we are the owner don't bother, since owner should
+	 * always be allowed to read basic attributes of file.
+	 */
+	if (!(zp->z_pflags & ZFS_ACL_TRIVIAL) &&
+	    (vap->va_uid != crgetuid(cr))) {
+		if ((error = zfs_zaccess(zp, ACE_READ_ATTRIBUTES, 0,
+		    skipaclchk, cr))) {
+			ZFS_EXIT(zsb);
+			return (error);
+		}
+	}
+
+	/*
+	 * Return all attributes.  It's cheaper to provide the answer
+	 * than to determine whether we were asked the question.
+	 */
+
+	mutex_enter(&zp->z_lock);
+	vap->va_type = vn_mode_to_vtype(zp->z_mode);
+	vap->va_mode = zp->z_mode;
+	vap->va_fsid = ZTOI(zp)->i_sb->s_dev;
+	vap->va_nodeid = zp->z_id;
+	if ((zp->z_id == zsb->z_root) && zfs_show_ctldir(zp))
+		links = zp->z_links + 1;
+	else
+		links = zp->z_links;
+	vap->va_nlink = MIN(links, ZFS_LINK_MAX);
+	vap->va_size = i_size_read(ip);
+	vap->va_rdev = ip->i_rdev;
+	vap->va_seq = ip->i_generation;
+
+	/*
+	 * Add in any requested optional attributes and the create time.
+	 * Also set the corresponding bits in the returned attribute bitmap.
+	 */
+	if ((xoap = xva_getxoptattr(xvap)) != NULL && zsb->z_use_fuids) {
+		if (XVA_ISSET_REQ(xvap, XAT_ARCHIVE)) {
+			xoap->xoa_archive =
+			    ((zp->z_pflags & ZFS_ARCHIVE) != 0);
+			XVA_SET_RTN(xvap, XAT_ARCHIVE);
+		}
+
+		if (XVA_ISSET_REQ(xvap, XAT_READONLY)) {
+			xoap->xoa_readonly =
+			    ((zp->z_pflags & ZFS_READONLY) != 0);
+			XVA_SET_RTN(xvap, XAT_READONLY);
+		}
+
+		if (XVA_ISSET_REQ(xvap, XAT_SYSTEM)) {
+			xoap->xoa_system =
+			    ((zp->z_pflags & ZFS_SYSTEM) != 0);
+			XVA_SET_RTN(xvap, XAT_SYSTEM);
+		}
+
+		if (XVA_ISSET_REQ(xvap, XAT_HIDDEN)) {
+			xoap->xoa_hidden =
+			    ((zp->z_pflags & ZFS_HIDDEN) != 0);
+			XVA_SET_RTN(xvap, XAT_HIDDEN);
+		}
+
+		if (XVA_ISSET_REQ(xvap, XAT_NOUNLINK)) {
+			xoap->xoa_nounlink =
+			    ((zp->z_pflags & ZFS_NOUNLINK) != 0);
+			XVA_SET_RTN(xvap, XAT_NOUNLINK);
+		}
+
+		if (XVA_ISSET_REQ(xvap, XAT_IMMUTABLE)) {
+			xoap->xoa_immutable =
+			    ((zp->z_pflags & ZFS_IMMUTABLE) != 0);
+			XVA_SET_RTN(xvap, XAT_IMMUTABLE);
+		}
+
+		if (XVA_ISSET_REQ(xvap, XAT_APPENDONLY)) {
+			xoap->xoa_appendonly =
+			    ((zp->z_pflags & ZFS_APPENDONLY) != 0);
+			XVA_SET_RTN(xvap, XAT_APPENDONLY);
+		}
+
+		if (XVA_ISSET_REQ(xvap, XAT_NODUMP)) {
+			xoap->xoa_nodump =
+			    ((zp->z_pflags & ZFS_NODUMP) != 0);
+			XVA_SET_RTN(xvap, XAT_NODUMP);
+		}
+
+		if (XVA_ISSET_REQ(xvap, XAT_OPAQUE)) {
+			xoap->xoa_opaque =
+			    ((zp->z_pflags & ZFS_OPAQUE) != 0);
+			XVA_SET_RTN(xvap, XAT_OPAQUE);
+		}
+
+		if (XVA_ISSET_REQ(xvap, XAT_AV_QUARANTINED)) {
+			xoap->xoa_av_quarantined =
+			    ((zp->z_pflags & ZFS_AV_QUARANTINED) != 0);
+			XVA_SET_RTN(xvap, XAT_AV_QUARANTINED);
+		}
+
+		if (XVA_ISSET_REQ(xvap, XAT_AV_MODIFIED)) {
+			xoap->xoa_av_modified =
+			    ((zp->z_pflags & ZFS_AV_MODIFIED) != 0);
+			XVA_SET_RTN(xvap, XAT_AV_MODIFIED);
+		}
+
+		if (XVA_ISSET_REQ(xvap, XAT_AV_SCANSTAMP) &&
+		    S_ISREG(ip->i_mode)) {
+			zfs_sa_get_scanstamp(zp, xvap);
+		}
+
+		if (XVA_ISSET_REQ(xvap, XAT_CREATETIME)) {
+			uint64_t times[2];
+
+			(void) sa_lookup(zp->z_sa_hdl, SA_ZPL_CRTIME(zsb),
+			    times, sizeof (times));
+			ZFS_TIME_DECODE(&xoap->xoa_createtime, times);
+			XVA_SET_RTN(xvap, XAT_CREATETIME);
+		}
+
+		if (XVA_ISSET_REQ(xvap, XAT_REPARSE)) {
+			xoap->xoa_reparse = ((zp->z_pflags & ZFS_REPARSE) != 0);
+			XVA_SET_RTN(xvap, XAT_REPARSE);
+		}
+		if (XVA_ISSET_REQ(xvap, XAT_GEN)) {
+			xoap->xoa_generation = zp->z_gen;
+			XVA_SET_RTN(xvap, XAT_GEN);
+		}
+
+		if (XVA_ISSET_REQ(xvap, XAT_OFFLINE)) {
+			xoap->xoa_offline =
+			    ((zp->z_pflags & ZFS_OFFLINE) != 0);
+			XVA_SET_RTN(xvap, XAT_OFFLINE);
+		}
+
+		if (XVA_ISSET_REQ(xvap, XAT_SPARSE)) {
+			xoap->xoa_sparse =
+			    ((zp->z_pflags & ZFS_SPARSE) != 0);
+			XVA_SET_RTN(xvap, XAT_SPARSE);
+		}
+	}
+
+	ZFS_TIME_DECODE(&vap->va_atime, zp->z_atime);
+	ZFS_TIME_DECODE(&vap->va_mtime, mtime);
+	ZFS_TIME_DECODE(&vap->va_ctime, ctime);
+
+	mutex_exit(&zp->z_lock);
+
+	sa_object_size(zp->z_sa_hdl, &vap->va_blksize, &vap->va_nblocks);
+
+	if (zp->z_blksz == 0) {
+		/*
+		 * Block size hasn't been set; suggest maximal I/O transfers.
+		 */
+		vap->va_blksize = zsb->z_max_blksz;
+	}
+
+	ZFS_EXIT(zsb);
+	return (0);
+}
+EXPORT_SYMBOL(zfs_getattr);
+
+/*
+ * Get the basic file attributes and place them in the provided kstat
+ * structure.  The inode is assumed to be the authoritative source
+ * for most of the attributes.  However, the znode currently has the
+ * authoritative atime, blksize, and block count.
+ *
+ *	IN:	ip	- inode of file.
+ *
+ *	OUT:	sp	- kstat values.
+ *
+ *	RETURN:	0 (always succeeds)
+ */
+/* ARGSUSED */
+int
+zfs_getattr_fast(struct inode *ip, struct kstat *sp)
+{
+	znode_t *zp = ITOZ(ip);
+	zfs_sb_t *zsb = ITOZSB(ip);
+	uint32_t blksize;
+	u_longlong_t nblocks;
+
+	ZFS_ENTER(zsb);
+	ZFS_VERIFY_ZP(zp);
+
+	mutex_enter(&zp->z_lock);
+
+	generic_fillattr(ip, sp);
+	ZFS_TIME_DECODE(&sp->atime, zp->z_atime);
+
+	sa_object_size(zp->z_sa_hdl, &blksize, &nblocks);
+	sp->blksize = blksize;
+	sp->blocks = nblocks;
+
+	if (unlikely(zp->z_blksz == 0)) {
+		/*
+		 * Block size hasn't been set; suggest maximal I/O transfers.
+		 */
+		sp->blksize = zsb->z_max_blksz;
+	}
+
+	mutex_exit(&zp->z_lock);
+
+	/*
+	 * Required to prevent NFS client from detecting different inode
+	 * numbers of snapshot root dentry before and after snapshot mount.
+	 */
+	if (zsb->z_issnap) {
+		if (ip->i_sb->s_root->d_inode == ip)
+			sp->ino = ZFSCTL_INO_SNAPDIRS -
+				dmu_objset_id(zsb->z_os);
+	}
+
+	ZFS_EXIT(zsb);
+
+	return (0);
+}
+EXPORT_SYMBOL(zfs_getattr_fast);
+
+/*
+ * Set the file attributes to the values contained in the
+ * vattr structure.
+ *
+ *	IN:	ip	- inode of file to be modified.
+ *		vap	- new attribute values.
+ *			  If ATTR_XVATTR set, then optional attrs are being set
+ *		flags	- ATTR_UTIME set if non-default time values provided.
+ *			- ATTR_NOACLCHECK (CIFS context only).
+ *		cr	- credentials of caller.
+ *
+ *	RETURN:	0 if success
+ *		error code if failure
+ *
+ * Timestamps:
+ *	ip - ctime updated, mtime updated if size changed.
+ */
+/* ARGSUSED */
+int
+zfs_setattr(struct inode *ip, vattr_t *vap, int flags, cred_t *cr)
+{
+	znode_t		*zp = ITOZ(ip);
+	zfs_sb_t	*zsb = ITOZSB(ip);
+	zilog_t		*zilog;
+	dmu_tx_t	*tx;
+	vattr_t		oldva;
+	xvattr_t	*tmpxvattr;
+	uint_t		mask = vap->va_mask;
+	uint_t		saved_mask = 0;
+	int		trim_mask = 0;
+	uint64_t	new_mode;
+	uint64_t	new_uid, new_gid;
+	uint64_t	xattr_obj;
+	uint64_t	mtime[2], ctime[2];
+	znode_t		*attrzp;
+	int		need_policy = FALSE;
+	int		err, err2;
+	zfs_fuid_info_t *fuidp = NULL;
+	xvattr_t *xvap = (xvattr_t *)vap;	/* vap may be an xvattr_t * */
+	xoptattr_t	*xoap;
+	zfs_acl_t	*aclp;
+	boolean_t skipaclchk = (flags & ATTR_NOACLCHECK) ? B_TRUE : B_FALSE;
+	boolean_t	fuid_dirtied = B_FALSE;
+	sa_bulk_attr_t	*bulk, *xattr_bulk;
+	int		count = 0, xattr_count = 0;
+
+	if (mask == 0)
+		return (0);
+
+	ZFS_ENTER(zsb);
+	ZFS_VERIFY_ZP(zp);
+
+	zilog = zsb->z_log;
+
+	/*
+	 * Make sure that if we have ephemeral uid/gid or xvattr specified
+	 * that file system is at proper version level
+	 */
+
+	if (zsb->z_use_fuids == B_FALSE &&
+	    (((mask & ATTR_UID) && IS_EPHEMERAL(vap->va_uid)) ||
+	    ((mask & ATTR_GID) && IS_EPHEMERAL(vap->va_gid)) ||
+	    (mask & ATTR_XVATTR))) {
+		ZFS_EXIT(zsb);
+		return (SET_ERROR(EINVAL));
+	}
+
+	if (mask & ATTR_SIZE && S_ISDIR(ip->i_mode)) {
+		ZFS_EXIT(zsb);
+		return (SET_ERROR(EISDIR));
+	}
+
+	if (mask & ATTR_SIZE && !S_ISREG(ip->i_mode) && !S_ISFIFO(ip->i_mode)) {
+		ZFS_EXIT(zsb);
+		return (SET_ERROR(EINVAL));
+	}
+
+	/*
+	 * If this is an xvattr_t, then get a pointer to the structure of
+	 * optional attributes.  If this is NULL, then we have a vattr_t.
+	 */
+	xoap = xva_getxoptattr(xvap);
+
+	tmpxvattr = kmem_alloc(sizeof (xvattr_t), KM_SLEEP);
+	xva_init(tmpxvattr);
+
+	bulk = kmem_alloc(sizeof (sa_bulk_attr_t) * 7, KM_SLEEP);
+	xattr_bulk = kmem_alloc(sizeof (sa_bulk_attr_t) * 7, KM_SLEEP);
+
+	/*
+	 * Immutable files can only alter immutable bit and atime
+	 */
+	if ((zp->z_pflags & ZFS_IMMUTABLE) &&
+	    ((mask & (ATTR_SIZE|ATTR_UID|ATTR_GID|ATTR_MTIME|ATTR_MODE)) ||
+	    ((mask & ATTR_XVATTR) && XVA_ISSET_REQ(xvap, XAT_CREATETIME)))) {
+		err = EPERM;
+		goto out3;
+	}
+
+	if ((mask & ATTR_SIZE) && (zp->z_pflags & ZFS_READONLY)) {
+		err = EPERM;
+		goto out3;
+	}
+
+	/*
+	 * Verify timestamps doesn't overflow 32 bits.
+	 * ZFS can handle large timestamps, but 32bit syscalls can't
+	 * handle times greater than 2039.  This check should be removed
+	 * once large timestamps are fully supported.
+	 */
+	if (mask & (ATTR_ATIME | ATTR_MTIME)) {
+		if (((mask & ATTR_ATIME) &&
+		    TIMESPEC_OVERFLOW(&vap->va_atime)) ||
+		    ((mask & ATTR_MTIME) &&
+		    TIMESPEC_OVERFLOW(&vap->va_mtime))) {
+			err = EOVERFLOW;
+			goto out3;
+		}
+	}
+
+top:
+	attrzp = NULL;
+	aclp = NULL;
+
+	/* Can this be moved to before the top label? */
+	if (zfs_is_readonly(zsb)) {
+		err = EROFS;
+		goto out3;
+	}
+
+	/*
+	 * First validate permissions
+	 */
+
+	if (mask & ATTR_SIZE) {
+		err = zfs_zaccess(zp, ACE_WRITE_DATA, 0, skipaclchk, cr);
+		if (err)
+			goto out3;
+
+		/*
+		 * XXX - Note, we are not providing any open
+		 * mode flags here (like FNDELAY), so we may
+		 * block if there are locks present... this
+		 * should be addressed in openat().
+		 */
+		/* XXX - would it be OK to generate a log record here? */
+		err = zfs_freesp(zp, vap->va_size, 0, 0, FALSE);
+		if (err)
+			goto out3;
+	}
+
+	if (mask & (ATTR_ATIME|ATTR_MTIME) ||
+	    ((mask & ATTR_XVATTR) && (XVA_ISSET_REQ(xvap, XAT_HIDDEN) ||
+	    XVA_ISSET_REQ(xvap, XAT_READONLY) ||
+	    XVA_ISSET_REQ(xvap, XAT_ARCHIVE) ||
+	    XVA_ISSET_REQ(xvap, XAT_OFFLINE) ||
+	    XVA_ISSET_REQ(xvap, XAT_SPARSE) ||
+	    XVA_ISSET_REQ(xvap, XAT_CREATETIME) ||
+	    XVA_ISSET_REQ(xvap, XAT_SYSTEM)))) {
+		need_policy = zfs_zaccess(zp, ACE_WRITE_ATTRIBUTES, 0,
+		    skipaclchk, cr);
+	}
+
+	if (mask & (ATTR_UID|ATTR_GID)) {
+		int	idmask = (mask & (ATTR_UID|ATTR_GID));
+		int	take_owner;
+		int	take_group;
+
+		/*
+		 * NOTE: even if a new mode is being set,
+		 * we may clear S_ISUID/S_ISGID bits.
+		 */
+
+		if (!(mask & ATTR_MODE))
+			vap->va_mode = zp->z_mode;
+
+		/*
+		 * Take ownership or chgrp to group we are a member of
+		 */
+
+		take_owner = (mask & ATTR_UID) && (vap->va_uid == crgetuid(cr));
+		take_group = (mask & ATTR_GID) &&
+		    zfs_groupmember(zsb, vap->va_gid, cr);
+
+		/*
+		 * If both ATTR_UID and ATTR_GID are set then take_owner and
+		 * take_group must both be set in order to allow taking
+		 * ownership.
+		 *
+		 * Otherwise, send the check through secpolicy_vnode_setattr()
+		 *
+		 */
+
+		if (((idmask == (ATTR_UID|ATTR_GID)) &&
+		    take_owner && take_group) ||
+		    ((idmask == ATTR_UID) && take_owner) ||
+		    ((idmask == ATTR_GID) && take_group)) {
+			if (zfs_zaccess(zp, ACE_WRITE_OWNER, 0,
+			    skipaclchk, cr) == 0) {
+				/*
+				 * Remove setuid/setgid for non-privileged users
+				 */
+				(void) secpolicy_setid_clear(vap, cr);
+				trim_mask = (mask & (ATTR_UID|ATTR_GID));
+			} else {
+				need_policy =  TRUE;
+			}
+		} else {
+			need_policy =  TRUE;
+		}
+	}
+
+	mutex_enter(&zp->z_lock);
+	oldva.va_mode = zp->z_mode;
+	zfs_fuid_map_ids(zp, cr, &oldva.va_uid, &oldva.va_gid);
+	if (mask & ATTR_XVATTR) {
+		/*
+		 * Update xvattr mask to include only those attributes
+		 * that are actually changing.
+		 *
+		 * the bits will be restored prior to actually setting
+		 * the attributes so the caller thinks they were set.
+		 */
+		if (XVA_ISSET_REQ(xvap, XAT_APPENDONLY)) {
+			if (xoap->xoa_appendonly !=
+			    ((zp->z_pflags & ZFS_APPENDONLY) != 0)) {
+				need_policy = TRUE;
+			} else {
+				XVA_CLR_REQ(xvap, XAT_APPENDONLY);
+				XVA_SET_REQ(tmpxvattr, XAT_APPENDONLY);
+			}
+		}
+
+		if (XVA_ISSET_REQ(xvap, XAT_NOUNLINK)) {
+			if (xoap->xoa_nounlink !=
+			    ((zp->z_pflags & ZFS_NOUNLINK) != 0)) {
+				need_policy = TRUE;
+			} else {
+				XVA_CLR_REQ(xvap, XAT_NOUNLINK);
+				XVA_SET_REQ(tmpxvattr, XAT_NOUNLINK);
+			}
+		}
+
+		if (XVA_ISSET_REQ(xvap, XAT_IMMUTABLE)) {
+			if (xoap->xoa_immutable !=
+			    ((zp->z_pflags & ZFS_IMMUTABLE) != 0)) {
+				need_policy = TRUE;
+			} else {
+				XVA_CLR_REQ(xvap, XAT_IMMUTABLE);
+				XVA_SET_REQ(tmpxvattr, XAT_IMMUTABLE);
+			}
+		}
+
+		if (XVA_ISSET_REQ(xvap, XAT_NODUMP)) {
+			if (xoap->xoa_nodump !=
+			    ((zp->z_pflags & ZFS_NODUMP) != 0)) {
+				need_policy = TRUE;
+			} else {
+				XVA_CLR_REQ(xvap, XAT_NODUMP);
+				XVA_SET_REQ(tmpxvattr, XAT_NODUMP);
+			}
+		}
+
+		if (XVA_ISSET_REQ(xvap, XAT_AV_MODIFIED)) {
+			if (xoap->xoa_av_modified !=
+			    ((zp->z_pflags & ZFS_AV_MODIFIED) != 0)) {
+				need_policy = TRUE;
+			} else {
+				XVA_CLR_REQ(xvap, XAT_AV_MODIFIED);
+				XVA_SET_REQ(tmpxvattr, XAT_AV_MODIFIED);
+			}
+		}
+
+		if (XVA_ISSET_REQ(xvap, XAT_AV_QUARANTINED)) {
+			if ((!S_ISREG(ip->i_mode) &&
+			    xoap->xoa_av_quarantined) ||
+			    xoap->xoa_av_quarantined !=
+			    ((zp->z_pflags & ZFS_AV_QUARANTINED) != 0)) {
+				need_policy = TRUE;
+			} else {
+				XVA_CLR_REQ(xvap, XAT_AV_QUARANTINED);
+				XVA_SET_REQ(tmpxvattr, XAT_AV_QUARANTINED);
+			}
+		}
+
+		if (XVA_ISSET_REQ(xvap, XAT_REPARSE)) {
+			mutex_exit(&zp->z_lock);
+			err = EPERM;
+			goto out3;
+		}
+
+		if (need_policy == FALSE &&
+		    (XVA_ISSET_REQ(xvap, XAT_AV_SCANSTAMP) ||
+		    XVA_ISSET_REQ(xvap, XAT_OPAQUE))) {
+			need_policy = TRUE;
+		}
+	}
+
+	mutex_exit(&zp->z_lock);
+
+	if (mask & ATTR_MODE) {
+		if (zfs_zaccess(zp, ACE_WRITE_ACL, 0, skipaclchk, cr) == 0) {
+			err = secpolicy_setid_setsticky_clear(ip, vap,
+			    &oldva, cr);
+			if (err)
+				goto out3;
+
+			trim_mask |= ATTR_MODE;
+		} else {
+			need_policy = TRUE;
+		}
+	}
+
+	if (need_policy) {
+		/*
+		 * If trim_mask is set then take ownership
+		 * has been granted or write_acl is present and user
+		 * has the ability to modify mode.  In that case remove
+		 * UID|GID and or MODE from mask so that
+		 * secpolicy_vnode_setattr() doesn't revoke it.
+		 */
+
+		if (trim_mask) {
+			saved_mask = vap->va_mask;
+			vap->va_mask &= ~trim_mask;
+		}
+		err = secpolicy_vnode_setattr(cr, ip, vap, &oldva, flags,
+		    (int (*)(void *, int, cred_t *))zfs_zaccess_unix, zp);
+		if (err)
+			goto out3;
+
+		if (trim_mask)
+			vap->va_mask |= saved_mask;
+	}
+
+	/*
+	 * secpolicy_vnode_setattr, or take ownership may have
+	 * changed va_mask
+	 */
+	mask = vap->va_mask;
+
+	if ((mask & (ATTR_UID | ATTR_GID))) {
+		err = sa_lookup(zp->z_sa_hdl, SA_ZPL_XATTR(zsb),
+		    &xattr_obj, sizeof (xattr_obj));
+
+		if (err == 0 && xattr_obj) {
+			err = zfs_zget(ZTOZSB(zp), xattr_obj, &attrzp);
+			if (err)
+				goto out2;
+		}
+		if (mask & ATTR_UID) {
+			new_uid = zfs_fuid_create(zsb,
+			    (uint64_t)vap->va_uid, cr, ZFS_OWNER, &fuidp);
+			if (new_uid != zp->z_uid &&
+			    zfs_fuid_overquota(zsb, B_FALSE, new_uid)) {
+				if (attrzp)
+					iput(ZTOI(attrzp));
+				err = EDQUOT;
+				goto out2;
+			}
+		}
+
+		if (mask & ATTR_GID) {
+			new_gid = zfs_fuid_create(zsb, (uint64_t)vap->va_gid,
+			    cr, ZFS_GROUP, &fuidp);
+			if (new_gid != zp->z_gid &&
+			    zfs_fuid_overquota(zsb, B_TRUE, new_gid)) {
+				if (attrzp)
+					iput(ZTOI(attrzp));
+				err = EDQUOT;
+				goto out2;
+			}
+		}
+	}
+	tx = dmu_tx_create(zsb->z_os);
+
+	if (mask & ATTR_MODE) {
+		uint64_t pmode = zp->z_mode;
+		uint64_t acl_obj;
+		new_mode = (pmode & S_IFMT) | (vap->va_mode & ~S_IFMT);
+
+		zfs_acl_chmod_setattr(zp, &aclp, new_mode);
+
+		mutex_enter(&zp->z_lock);
+		if (!zp->z_is_sa && ((acl_obj = zfs_external_acl(zp)) != 0)) {
+			/*
+			 * Are we upgrading ACL from old V0 format
+			 * to V1 format?
+			 */
+			if (zsb->z_version >= ZPL_VERSION_FUID &&
+			    zfs_znode_acl_version(zp) ==
+			    ZFS_ACL_VERSION_INITIAL) {
+				dmu_tx_hold_free(tx, acl_obj, 0,
+				    DMU_OBJECT_END);
+				dmu_tx_hold_write(tx, DMU_NEW_OBJECT,
+				    0, aclp->z_acl_bytes);
+			} else {
+				dmu_tx_hold_write(tx, acl_obj, 0,
+				    aclp->z_acl_bytes);
+			}
+		} else if (!zp->z_is_sa && aclp->z_acl_bytes > ZFS_ACE_SPACE) {
+			dmu_tx_hold_write(tx, DMU_NEW_OBJECT,
+			    0, aclp->z_acl_bytes);
+		}
+		mutex_exit(&zp->z_lock);
+		dmu_tx_hold_sa(tx, zp->z_sa_hdl, B_TRUE);
+	} else {
+		if ((mask & ATTR_XVATTR) &&
+		    XVA_ISSET_REQ(xvap, XAT_AV_SCANSTAMP))
+			dmu_tx_hold_sa(tx, zp->z_sa_hdl, B_TRUE);
+		else
+			dmu_tx_hold_sa(tx, zp->z_sa_hdl, B_FALSE);
+	}
+
+	if (attrzp) {
+		dmu_tx_hold_sa(tx, attrzp->z_sa_hdl, B_FALSE);
+	}
+
+	fuid_dirtied = zsb->z_fuid_dirty;
+	if (fuid_dirtied)
+		zfs_fuid_txhold(zsb, tx);
+
+	zfs_sa_upgrade_txholds(tx, zp);
+
+	err = dmu_tx_assign(tx, TXG_WAIT);
+	if (err)
+		goto out;
+
+	count = 0;
+	/*
+	 * Set each attribute requested.
+	 * We group settings according to the locks they need to acquire.
+	 *
+	 * Note: you cannot set ctime directly, although it will be
+	 * updated as a side-effect of calling this function.
+	 */
+
+
+	if (mask & (ATTR_UID|ATTR_GID|ATTR_MODE))
+		mutex_enter(&zp->z_acl_lock);
+	mutex_enter(&zp->z_lock);
+
+	SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_FLAGS(zsb), NULL,
+	    &zp->z_pflags, sizeof (zp->z_pflags));
+
+	if (attrzp) {
+		if (mask & (ATTR_UID|ATTR_GID|ATTR_MODE))
+			mutex_enter(&attrzp->z_acl_lock);
+		mutex_enter(&attrzp->z_lock);
+		SA_ADD_BULK_ATTR(xattr_bulk, xattr_count,
+		    SA_ZPL_FLAGS(zsb), NULL, &attrzp->z_pflags,
+		    sizeof (attrzp->z_pflags));
+	}
+
+	if (mask & (ATTR_UID|ATTR_GID)) {
+
+		if (mask & ATTR_UID) {
+			SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_UID(zsb), NULL,
+			    &new_uid, sizeof (new_uid));
+			zp->z_uid = new_uid;
+			if (attrzp) {
+				SA_ADD_BULK_ATTR(xattr_bulk, xattr_count,
+				    SA_ZPL_UID(zsb), NULL, &new_uid,
+				    sizeof (new_uid));
+				attrzp->z_uid = new_uid;
+			}
+		}
+
+		if (mask & ATTR_GID) {
+			SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_GID(zsb),
+			    NULL, &new_gid, sizeof (new_gid));
+			zp->z_gid = new_gid;
+			if (attrzp) {
+				SA_ADD_BULK_ATTR(xattr_bulk, xattr_count,
+				    SA_ZPL_GID(zsb), NULL, &new_gid,
+				    sizeof (new_gid));
+				attrzp->z_gid = new_gid;
+			}
+		}
+		if (!(mask & ATTR_MODE)) {
+			SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_MODE(zsb),
+			    NULL, &new_mode, sizeof (new_mode));
+			new_mode = zp->z_mode;
+		}
+		err = zfs_acl_chown_setattr(zp);
+		ASSERT(err == 0);
+		if (attrzp) {
+			err = zfs_acl_chown_setattr(attrzp);
+			ASSERT(err == 0);
+		}
+	}
+
+	if (mask & ATTR_MODE) {
+		SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_MODE(zsb), NULL,
+		    &new_mode, sizeof (new_mode));
+		zp->z_mode = new_mode;
+		ASSERT3P(aclp, !=, NULL);
+		err = zfs_aclset_common(zp, aclp, cr, tx);
+		ASSERT0(err);
+		if (zp->z_acl_cached)
+			zfs_acl_free(zp->z_acl_cached);
+		zp->z_acl_cached = aclp;
+		aclp = NULL;
+	}
+
+
+	if (mask & ATTR_ATIME) {
+		ZFS_TIME_ENCODE(&vap->va_atime, zp->z_atime);
+		SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_ATIME(zsb), NULL,
+		    &zp->z_atime, sizeof (zp->z_atime));
+	}
+
+	if (mask & ATTR_MTIME) {
+		ZFS_TIME_ENCODE(&vap->va_mtime, mtime);
+		SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_MTIME(zsb), NULL,
+		    mtime, sizeof (mtime));
+	}
+
+	/* XXX - shouldn't this be done *before* the ATIME/MTIME checks? */
+	if (mask & ATTR_SIZE && !(mask & ATTR_MTIME)) {
+		SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_MTIME(zsb),
+		    NULL, mtime, sizeof (mtime));
+		SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_CTIME(zsb), NULL,
+		    &ctime, sizeof (ctime));
+		zfs_tstamp_update_setup(zp, CONTENT_MODIFIED, mtime, ctime,
+		    B_TRUE);
+	} else if (mask != 0) {
+		SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_CTIME(zsb), NULL,
+		    &ctime, sizeof (ctime));
+		zfs_tstamp_update_setup(zp, STATE_CHANGED, mtime, ctime,
+		    B_TRUE);
+		if (attrzp) {
+			SA_ADD_BULK_ATTR(xattr_bulk, xattr_count,
+			    SA_ZPL_CTIME(zsb), NULL,
+			    &ctime, sizeof (ctime));
+			zfs_tstamp_update_setup(attrzp, STATE_CHANGED,
+			    mtime, ctime, B_TRUE);
+		}
+	}
+	/*
+	 * Do this after setting timestamps to prevent timestamp
+	 * update from toggling bit
+	 */
+
+	if (xoap && (mask & ATTR_XVATTR)) {
+
+		/*
+		 * restore trimmed off masks
+		 * so that return masks can be set for caller.
+		 */
+
+		if (XVA_ISSET_REQ(tmpxvattr, XAT_APPENDONLY)) {
+			XVA_SET_REQ(xvap, XAT_APPENDONLY);
+		}
+		if (XVA_ISSET_REQ(tmpxvattr, XAT_NOUNLINK)) {
+			XVA_SET_REQ(xvap, XAT_NOUNLINK);
+		}
+		if (XVA_ISSET_REQ(tmpxvattr, XAT_IMMUTABLE)) {
+			XVA_SET_REQ(xvap, XAT_IMMUTABLE);
+		}
+		if (XVA_ISSET_REQ(tmpxvattr, XAT_NODUMP)) {
+			XVA_SET_REQ(xvap, XAT_NODUMP);
+		}
+		if (XVA_ISSET_REQ(tmpxvattr, XAT_AV_MODIFIED)) {
+			XVA_SET_REQ(xvap, XAT_AV_MODIFIED);
+		}
+		if (XVA_ISSET_REQ(tmpxvattr, XAT_AV_QUARANTINED)) {
+			XVA_SET_REQ(xvap, XAT_AV_QUARANTINED);
+		}
+
+		if (XVA_ISSET_REQ(xvap, XAT_AV_SCANSTAMP))
+			ASSERT(S_ISREG(ip->i_mode));
+
+		zfs_xvattr_set(zp, xvap, tx);
+	}
+
+	if (fuid_dirtied)
+		zfs_fuid_sync(zsb, tx);
+
+	if (mask != 0)
+		zfs_log_setattr(zilog, tx, TX_SETATTR, zp, vap, mask, fuidp);
+
+	mutex_exit(&zp->z_lock);
+	if (mask & (ATTR_UID|ATTR_GID|ATTR_MODE))
+		mutex_exit(&zp->z_acl_lock);
+
+	if (attrzp) {
+		if (mask & (ATTR_UID|ATTR_GID|ATTR_MODE))
+			mutex_exit(&attrzp->z_acl_lock);
+		mutex_exit(&attrzp->z_lock);
+	}
+out:
+	if (err == 0 && attrzp) {
+		err2 = sa_bulk_update(attrzp->z_sa_hdl, xattr_bulk,
+		    xattr_count, tx);
+		ASSERT(err2 == 0);
+	}
+
+	if (attrzp)
+		iput(ZTOI(attrzp));
+	if (aclp)
+		zfs_acl_free(aclp);
+
+	if (fuidp) {
+		zfs_fuid_info_free(fuidp);
+		fuidp = NULL;
+	}
+
+	if (err) {
+		dmu_tx_abort(tx);
+		if (err == ERESTART)
+			goto top;
+	} else {
+		err2 = sa_bulk_update(zp->z_sa_hdl, bulk, count, tx);
+		dmu_tx_commit(tx);
+		zfs_inode_update(zp);
+	}
+
+out2:
+	if (zsb->z_os->os_sync == ZFS_SYNC_ALWAYS)
+		zil_commit(zilog, 0);
+
+out3:
+	kmem_free(xattr_bulk, sizeof (sa_bulk_attr_t) * 7);
+	kmem_free(bulk, sizeof (sa_bulk_attr_t) * 7);
+	kmem_free(tmpxvattr, sizeof (xvattr_t));
+	ZFS_EXIT(zsb);
+	return (err);
+}
+EXPORT_SYMBOL(zfs_setattr);
+
+typedef struct zfs_zlock {
+	krwlock_t	*zl_rwlock;	/* lock we acquired */
+	znode_t		*zl_znode;	/* znode we held */
+	struct zfs_zlock *zl_next;	/* next in list */
+} zfs_zlock_t;
+
+/*
+ * Drop locks and release vnodes that were held by zfs_rename_lock().
+ */
+static void
+zfs_rename_unlock(zfs_zlock_t **zlpp)
+{
+	zfs_zlock_t *zl;
+
+	while ((zl = *zlpp) != NULL) {
+		if (zl->zl_znode != NULL)
+			iput(ZTOI(zl->zl_znode));
+		rw_exit(zl->zl_rwlock);
+		*zlpp = zl->zl_next;
+		kmem_free(zl, sizeof (*zl));
+	}
+}
+
+/*
+ * Search back through the directory tree, using the ".." entries.
+ * Lock each directory in the chain to prevent concurrent renames.
+ * Fail any attempt to move a directory into one of its own descendants.
+ * XXX - z_parent_lock can overlap with map or grow locks
+ */
+static int
+zfs_rename_lock(znode_t *szp, znode_t *tdzp, znode_t *sdzp, zfs_zlock_t **zlpp)
+{
+	zfs_zlock_t	*zl;
+	znode_t		*zp = tdzp;
+	uint64_t	rootid = ZTOZSB(zp)->z_root;
+	uint64_t	oidp = zp->z_id;
+	krwlock_t	*rwlp = &szp->z_parent_lock;
+	krw_t		rw = RW_WRITER;
+
+	/*
+	 * First pass write-locks szp and compares to zp->z_id.
+	 * Later passes read-lock zp and compare to zp->z_parent.
+	 */
+	do {
+		if (!rw_tryenter(rwlp, rw)) {
+			/*
+			 * Another thread is renaming in this path.
+			 * Note that if we are a WRITER, we don't have any
+			 * parent_locks held yet.
+			 */
+			if (rw == RW_READER && zp->z_id > szp->z_id) {
+				/*
+				 * Drop our locks and restart
+				 */
+				zfs_rename_unlock(&zl);
+				*zlpp = NULL;
+				zp = tdzp;
+				oidp = zp->z_id;
+				rwlp = &szp->z_parent_lock;
+				rw = RW_WRITER;
+				continue;
+			} else {
+				/*
+				 * Wait for other thread to drop its locks
+				 */
+				rw_enter(rwlp, rw);
+			}
+		}
+
+		zl = kmem_alloc(sizeof (*zl), KM_SLEEP);
+		zl->zl_rwlock = rwlp;
+		zl->zl_znode = NULL;
+		zl->zl_next = *zlpp;
+		*zlpp = zl;
+
+		if (oidp == szp->z_id)		/* We're a descendant of szp */
+			return (SET_ERROR(EINVAL));
+
+		if (oidp == rootid)		/* We've hit the top */
+			return (0);
+
+		if (rw == RW_READER) {		/* i.e. not the first pass */
+			int error = zfs_zget(ZTOZSB(zp), oidp, &zp);
+			if (error)
+				return (error);
+			zl->zl_znode = zp;
+		}
+		(void) sa_lookup(zp->z_sa_hdl, SA_ZPL_PARENT(ZTOZSB(zp)),
+		    &oidp, sizeof (oidp));
+		rwlp = &zp->z_parent_lock;
+		rw = RW_READER;
+
+	} while (zp->z_id != sdzp->z_id);
+
+	return (0);
+}
+
+/*
+ * Move an entry from the provided source directory to the target
+ * directory.  Change the entry name as indicated.
+ *
+ *	IN:	sdip	- Source directory containing the "old entry".
+ *		snm	- Old entry name.
+ *		tdip	- Target directory to contain the "new entry".
+ *		tnm	- New entry name.
+ *		cr	- credentials of caller.
+ *		flags	- case flags
+ *
+ *	RETURN:	0 on success, error code on failure.
+ *
+ * Timestamps:
+ *	sdip,tdip - ctime|mtime updated
+ */
+/*ARGSUSED*/
+int
+zfs_rename(struct inode *sdip, char *snm, struct inode *tdip, char *tnm,
+    cred_t *cr, int flags)
+{
+	znode_t		*tdzp, *szp, *tzp;
+	znode_t		*sdzp = ITOZ(sdip);
+	zfs_sb_t	*zsb = ITOZSB(sdip);
+	zilog_t		*zilog;
+	zfs_dirlock_t	*sdl, *tdl;
+	dmu_tx_t	*tx;
+	zfs_zlock_t	*zl;
+	int		cmp, serr, terr;
+	int		error = 0;
+	int		zflg = 0;
+	boolean_t	waited = B_FALSE;
+
+	ZFS_ENTER(zsb);
+	ZFS_VERIFY_ZP(sdzp);
+	zilog = zsb->z_log;
+
+	if (tdip->i_sb != sdip->i_sb || zfsctl_is_node(tdip)) {
+		ZFS_EXIT(zsb);
+		return (SET_ERROR(EXDEV));
+	}
+
+	tdzp = ITOZ(tdip);
+	ZFS_VERIFY_ZP(tdzp);
+	if (zsb->z_utf8 && u8_validate(tnm,
+	    strlen(tnm), NULL, U8_VALIDATE_ENTIRE, &error) < 0) {
+		ZFS_EXIT(zsb);
+		return (SET_ERROR(EILSEQ));
+	}
+
+	if (flags & FIGNORECASE)
+		zflg |= ZCILOOK;
+
+top:
+	szp = NULL;
+	tzp = NULL;
+	zl = NULL;
+
+	/*
+	 * This is to prevent the creation of links into attribute space
+	 * by renaming a linked file into/outof an attribute directory.
+	 * See the comment in zfs_link() for why this is considered bad.
+	 */
+	if ((tdzp->z_pflags & ZFS_XATTR) != (sdzp->z_pflags & ZFS_XATTR)) {
+		ZFS_EXIT(zsb);
+		return (SET_ERROR(EINVAL));
+	}
+
+	/*
+	 * Lock source and target directory entries.  To prevent deadlock,
+	 * a lock ordering must be defined.  We lock the directory with
+	 * the smallest object id first, or if it's a tie, the one with
+	 * the lexically first name.
+	 */
+	if (sdzp->z_id < tdzp->z_id) {
+		cmp = -1;
+	} else if (sdzp->z_id > tdzp->z_id) {
+		cmp = 1;
+	} else {
+		/*
+		 * First compare the two name arguments without
+		 * considering any case folding.
+		 */
+		int nofold = (zsb->z_norm & ~U8_TEXTPREP_TOUPPER);
+
+		cmp = u8_strcmp(snm, tnm, 0, nofold, U8_UNICODE_LATEST, &error);
+		ASSERT(error == 0 || !zsb->z_utf8);
+		if (cmp == 0) {
+			/*
+			 * POSIX: "If the old argument and the new argument
+			 * both refer to links to the same existing file,
+			 * the rename() function shall return successfully
+			 * and perform no other action."
+			 */
+			ZFS_EXIT(zsb);
+			return (0);
+		}
+		/*
+		 * If the file system is case-folding, then we may
+		 * have some more checking to do.  A case-folding file
+		 * system is either supporting mixed case sensitivity
+		 * access or is completely case-insensitive.  Note
+		 * that the file system is always case preserving.
+		 *
+		 * In mixed sensitivity mode case sensitive behavior
+		 * is the default.  FIGNORECASE must be used to
+		 * explicitly request case insensitive behavior.
+		 *
+		 * If the source and target names provided differ only
+		 * by case (e.g., a request to rename 'tim' to 'Tim'),
+		 * we will treat this as a special case in the
+		 * case-insensitive mode: as long as the source name
+		 * is an exact match, we will allow this to proceed as
+		 * a name-change request.
+		 */
+		if ((zsb->z_case == ZFS_CASE_INSENSITIVE ||
+		    (zsb->z_case == ZFS_CASE_MIXED &&
+		    flags & FIGNORECASE)) &&
+		    u8_strcmp(snm, tnm, 0, zsb->z_norm, U8_UNICODE_LATEST,
+		    &error) == 0) {
+			/*
+			 * case preserving rename request, require exact
+			 * name matches
+			 */
+			zflg |= ZCIEXACT;
+			zflg &= ~ZCILOOK;
+		}
+	}
+
+	/*
+	 * If the source and destination directories are the same, we should
+	 * grab the z_name_lock of that directory only once.
+	 */
+	if (sdzp == tdzp) {
+		zflg |= ZHAVELOCK;
+		rw_enter(&sdzp->z_name_lock, RW_READER);
+	}
+
+	if (cmp < 0) {
+		serr = zfs_dirent_lock(&sdl, sdzp, snm, &szp,
+		    ZEXISTS | zflg, NULL, NULL);
+		terr = zfs_dirent_lock(&tdl,
+		    tdzp, tnm, &tzp, ZRENAMING | zflg, NULL, NULL);
+	} else {
+		terr = zfs_dirent_lock(&tdl,
+		    tdzp, tnm, &tzp, zflg, NULL, NULL);
+		serr = zfs_dirent_lock(&sdl,
+		    sdzp, snm, &szp, ZEXISTS | ZRENAMING | zflg,
+		    NULL, NULL);
+	}
+
+	if (serr) {
+		/*
+		 * Source entry invalid or not there.
+		 */
+		if (!terr) {
+			zfs_dirent_unlock(tdl);
+			if (tzp)
+				iput(ZTOI(tzp));
+		}
+
+		if (sdzp == tdzp)
+			rw_exit(&sdzp->z_name_lock);
+
+		if (strcmp(snm, "..") == 0)
+			serr = EINVAL;
+		ZFS_EXIT(zsb);
+		return (serr);
+	}
+	if (terr) {
+		zfs_dirent_unlock(sdl);
+		iput(ZTOI(szp));
+
+		if (sdzp == tdzp)
+			rw_exit(&sdzp->z_name_lock);
+
+		if (strcmp(tnm, "..") == 0)
+			terr = EINVAL;
+		ZFS_EXIT(zsb);
+		return (terr);
+	}
+
+	/*
+	 * Must have write access at the source to remove the old entry
+	 * and write access at the target to create the new entry.
+	 * Note that if target and source are the same, this can be
+	 * done in a single check.
+	 */
+
+	if ((error = zfs_zaccess_rename(sdzp, szp, tdzp, tzp, cr)))
+		goto out;
+
+	if (S_ISDIR(ZTOI(szp)->i_mode)) {
+		/*
+		 * Check to make sure rename is valid.
+		 * Can't do a move like this: /usr/a/b to /usr/a/b/c/d
+		 */
+		if ((error = zfs_rename_lock(szp, tdzp, sdzp, &zl)))
+			goto out;
+	}
+
+	/*
+	 * Does target exist?
+	 */
+	if (tzp) {
+		/*
+		 * Source and target must be the same type.
+		 */
+		if (S_ISDIR(ZTOI(szp)->i_mode)) {
+			if (!S_ISDIR(ZTOI(tzp)->i_mode)) {
+				error = SET_ERROR(ENOTDIR);
+				goto out;
+			}
+		} else {
+			if (S_ISDIR(ZTOI(tzp)->i_mode)) {
+				error = SET_ERROR(EISDIR);
+				goto out;
+			}
+		}
+		/*
+		 * POSIX dictates that when the source and target
+		 * entries refer to the same file object, rename
+		 * must do nothing and exit without error.
+		 */
+		if (szp->z_id == tzp->z_id) {
+			error = 0;
+			goto out;
+		}
+	}
+
+	tx = dmu_tx_create(zsb->z_os);
+	dmu_tx_hold_sa(tx, szp->z_sa_hdl, B_FALSE);
+	dmu_tx_hold_sa(tx, sdzp->z_sa_hdl, B_FALSE);
+	dmu_tx_hold_zap(tx, sdzp->z_id, FALSE, snm);
+	dmu_tx_hold_zap(tx, tdzp->z_id, TRUE, tnm);
+	if (sdzp != tdzp) {
+		dmu_tx_hold_sa(tx, tdzp->z_sa_hdl, B_FALSE);
+		zfs_sa_upgrade_txholds(tx, tdzp);
+	}
+	if (tzp) {
+		dmu_tx_hold_sa(tx, tzp->z_sa_hdl, B_FALSE);
+		zfs_sa_upgrade_txholds(tx, tzp);
+	}
+
+	zfs_sa_upgrade_txholds(tx, szp);
+	dmu_tx_hold_zap(tx, zsb->z_unlinkedobj, FALSE, NULL);
+	error = dmu_tx_assign(tx, waited ? TXG_WAITED : TXG_NOWAIT);
+	if (error) {
+		if (zl != NULL)
+			zfs_rename_unlock(&zl);
+		zfs_dirent_unlock(sdl);
+		zfs_dirent_unlock(tdl);
+
+		if (sdzp == tdzp)
+			rw_exit(&sdzp->z_name_lock);
+
+		iput(ZTOI(szp));
+		if (tzp)
+			iput(ZTOI(tzp));
+		if (error == ERESTART) {
+			waited = B_TRUE;
+			dmu_tx_wait(tx);
+			dmu_tx_abort(tx);
+			goto top;
+		}
+		dmu_tx_abort(tx);
+		ZFS_EXIT(zsb);
+		return (error);
+	}
+
+	if (tzp)	/* Attempt to remove the existing target */
+		error = zfs_link_destroy(tdl, tzp, tx, zflg, NULL);
+
+	if (error == 0) {
+		error = zfs_link_create(tdl, szp, tx, ZRENAMING);
+		if (error == 0) {
+			szp->z_pflags |= ZFS_AV_MODIFIED;
+
+			error = sa_update(szp->z_sa_hdl, SA_ZPL_FLAGS(zsb),
+			    (void *)&szp->z_pflags, sizeof (uint64_t), tx);
+			ASSERT0(error);
+
+			error = zfs_link_destroy(sdl, szp, tx, ZRENAMING, NULL);
+			if (error == 0) {
+				zfs_log_rename(zilog, tx, TX_RENAME |
+				    (flags & FIGNORECASE ? TX_CI : 0), sdzp,
+				    sdl->dl_name, tdzp, tdl->dl_name, szp);
+			} else {
+				/*
+				 * At this point, we have successfully created
+				 * the target name, but have failed to remove
+				 * the source name.  Since the create was done
+				 * with the ZRENAMING flag, there are
+				 * complications; for one, the link count is
+				 * wrong.  The easiest way to deal with this
+				 * is to remove the newly created target, and
+				 * return the original error.  This must
+				 * succeed; fortunately, it is very unlikely to
+				 * fail, since we just created it.
+				 */
+				VERIFY3U(zfs_link_destroy(tdl, szp, tx,
+				    ZRENAMING, NULL), ==, 0);
+			}
+		}
+	}
+
+	dmu_tx_commit(tx);
+out:
+	if (zl != NULL)
+		zfs_rename_unlock(&zl);
+
+	zfs_dirent_unlock(sdl);
+	zfs_dirent_unlock(tdl);
+
+	zfs_inode_update(sdzp);
+	if (sdzp == tdzp)
+		rw_exit(&sdzp->z_name_lock);
+
+	if (sdzp != tdzp)
+		zfs_inode_update(tdzp);
+
+	zfs_inode_update(szp);
+	iput(ZTOI(szp));
+	if (tzp) {
+		zfs_inode_update(tzp);
+		iput(ZTOI(tzp));
+	}
+
+	if (zsb->z_os->os_sync == ZFS_SYNC_ALWAYS)
+		zil_commit(zilog, 0);
+
+	ZFS_EXIT(zsb);
+	return (error);
+}
+EXPORT_SYMBOL(zfs_rename);
+
+/*
+ * Insert the indicated symbolic reference entry into the directory.
+ *
+ *	IN:	dip	- Directory to contain new symbolic link.
+ *		link	- Name for new symlink entry.
+ *		vap	- Attributes of new entry.
+ *		target	- Target path of new symlink.
+ *
+ *		cr	- credentials of caller.
+ *		flags	- case flags
+ *
+ *	RETURN:	0 on success, error code on failure.
+ *
+ * Timestamps:
+ *	dip - ctime|mtime updated
+ */
+/*ARGSUSED*/
+int
+zfs_symlink(struct inode *dip, char *name, vattr_t *vap, char *link,
+    struct inode **ipp, cred_t *cr, int flags)
+{
+	znode_t		*zp, *dzp = ITOZ(dip);
+	zfs_dirlock_t	*dl;
+	dmu_tx_t	*tx;
+	zfs_sb_t	*zsb = ITOZSB(dip);
+	zilog_t		*zilog;
+	uint64_t	len = strlen(link);
+	int		error;
+	int		zflg = ZNEW;
+	zfs_acl_ids_t	acl_ids;
+	boolean_t	fuid_dirtied;
+	uint64_t	txtype = TX_SYMLINK;
+	boolean_t	waited = B_FALSE;
+
+	ASSERT(S_ISLNK(vap->va_mode));
+
+	ZFS_ENTER(zsb);
+	ZFS_VERIFY_ZP(dzp);
+	zilog = zsb->z_log;
+
+	if (zsb->z_utf8 && u8_validate(name, strlen(name),
+	    NULL, U8_VALIDATE_ENTIRE, &error) < 0) {
+		ZFS_EXIT(zsb);
+		return (SET_ERROR(EILSEQ));
+	}
+	if (flags & FIGNORECASE)
+		zflg |= ZCILOOK;
+
+	if (len > MAXPATHLEN) {
+		ZFS_EXIT(zsb);
+		return (SET_ERROR(ENAMETOOLONG));
+	}
+
+	if ((error = zfs_acl_ids_create(dzp, 0,
+	    vap, cr, NULL, &acl_ids)) != 0) {
+		ZFS_EXIT(zsb);
+		return (error);
+	}
+top:
+	*ipp = NULL;
+
+	/*
+	 * Attempt to lock directory; fail if entry already exists.
+	 */
+	error = zfs_dirent_lock(&dl, dzp, name, &zp, zflg, NULL, NULL);
+	if (error) {
+		zfs_acl_ids_free(&acl_ids);
+		ZFS_EXIT(zsb);
+		return (error);
+	}
+
+	if ((error = zfs_zaccess(dzp, ACE_ADD_FILE, 0, B_FALSE, cr))) {
+		zfs_acl_ids_free(&acl_ids);
+		zfs_dirent_unlock(dl);
+		ZFS_EXIT(zsb);
+		return (error);
+	}
+
+	if (zfs_acl_ids_overquota(zsb, &acl_ids)) {
+		zfs_acl_ids_free(&acl_ids);
+		zfs_dirent_unlock(dl);
+		ZFS_EXIT(zsb);
+		return (SET_ERROR(EDQUOT));
+	}
+	tx = dmu_tx_create(zsb->z_os);
+	fuid_dirtied = zsb->z_fuid_dirty;
+	dmu_tx_hold_write(tx, DMU_NEW_OBJECT, 0, MAX(1, len));
+	dmu_tx_hold_zap(tx, dzp->z_id, TRUE, name);
+	dmu_tx_hold_sa_create(tx, acl_ids.z_aclp->z_acl_bytes +
+	    ZFS_SA_BASE_ATTR_SIZE + len);
+	dmu_tx_hold_sa(tx, dzp->z_sa_hdl, B_FALSE);
+	if (!zsb->z_use_sa && acl_ids.z_aclp->z_acl_bytes > ZFS_ACE_SPACE) {
+		dmu_tx_hold_write(tx, DMU_NEW_OBJECT, 0,
+		    acl_ids.z_aclp->z_acl_bytes);
+	}
+	if (fuid_dirtied)
+		zfs_fuid_txhold(zsb, tx);
+	error = dmu_tx_assign(tx, waited ? TXG_WAITED : TXG_NOWAIT);
+	if (error) {
+		zfs_dirent_unlock(dl);
+		if (error == ERESTART) {
+			waited = B_TRUE;
+			dmu_tx_wait(tx);
+			dmu_tx_abort(tx);
+			goto top;
+		}
+		zfs_acl_ids_free(&acl_ids);
+		dmu_tx_abort(tx);
+		ZFS_EXIT(zsb);
+		return (error);
+	}
+
+	/*
+	 * Create a new object for the symlink.
+	 * for version 4 ZPL datsets the symlink will be an SA attribute
+	 */
+	zfs_mknode(dzp, vap, tx, cr, 0, &zp, &acl_ids);
+
+	if (fuid_dirtied)
+		zfs_fuid_sync(zsb, tx);
+
+	mutex_enter(&zp->z_lock);
+	if (zp->z_is_sa)
+		error = sa_update(zp->z_sa_hdl, SA_ZPL_SYMLINK(zsb),
+		    link, len, tx);
+	else
+		zfs_sa_symlink(zp, link, len, tx);
+	mutex_exit(&zp->z_lock);
+
+	zp->z_size = len;
+	(void) sa_update(zp->z_sa_hdl, SA_ZPL_SIZE(zsb),
+	    &zp->z_size, sizeof (zp->z_size), tx);
+	/*
+	 * Insert the new object into the directory.
+	 */
+	(void) zfs_link_create(dl, zp, tx, ZNEW);
+
+	if (flags & FIGNORECASE)
+		txtype |= TX_CI;
+	zfs_log_symlink(zilog, tx, txtype, dzp, zp, name, link);
+
+	zfs_inode_update(dzp);
+	zfs_inode_update(zp);
+
+	zfs_acl_ids_free(&acl_ids);
+
+	dmu_tx_commit(tx);
+
+	zfs_dirent_unlock(dl);
+
+	*ipp = ZTOI(zp);
+
+	if (zsb->z_os->os_sync == ZFS_SYNC_ALWAYS)
+		zil_commit(zilog, 0);
+
+	ZFS_EXIT(zsb);
+	return (error);
+}
+EXPORT_SYMBOL(zfs_symlink);
+
+/*
+ * Return, in the buffer contained in the provided uio structure,
+ * the symbolic path referred to by ip.
+ *
+ *	IN:	ip	- inode of symbolic link
+ *		uio	- structure to contain the link path.
+ *		cr	- credentials of caller.
+ *
+ *	RETURN:	0 if success
+ *		error code if failure
+ *
+ * Timestamps:
+ *	ip - atime updated
+ */
+/* ARGSUSED */
+int
+zfs_readlink(struct inode *ip, uio_t *uio, cred_t *cr)
+{
+	znode_t		*zp = ITOZ(ip);
+	zfs_sb_t	*zsb = ITOZSB(ip);
+	int		error;
+
+	ZFS_ENTER(zsb);
+	ZFS_VERIFY_ZP(zp);
+
+	mutex_enter(&zp->z_lock);
+	if (zp->z_is_sa)
+		error = sa_lookup_uio(zp->z_sa_hdl,
+		    SA_ZPL_SYMLINK(zsb), uio);
+	else
+		error = zfs_sa_readlink(zp, uio);
+	mutex_exit(&zp->z_lock);
+
+	ZFS_ACCESSTIME_STAMP(zsb, zp);
+	ZFS_EXIT(zsb);
+	return (error);
+}
+EXPORT_SYMBOL(zfs_readlink);
+
+/*
+ * Insert a new entry into directory tdip referencing sip.
+ *
+ *	IN:	tdip	- Directory to contain new entry.
+ *		sip	- inode of new entry.
+ *		name	- name of new entry.
+ *		cr	- credentials of caller.
+ *
+ *	RETURN:	0 if success
+ *		error code if failure
+ *
+ * Timestamps:
+ *	tdip - ctime|mtime updated
+ *	 sip - ctime updated
+ */
+/* ARGSUSED */
+int
+zfs_link(struct inode *tdip, struct inode *sip, char *name, cred_t *cr)
+{
+	znode_t		*dzp = ITOZ(tdip);
+	znode_t		*tzp, *szp;
+	zfs_sb_t	*zsb = ITOZSB(tdip);
+	zilog_t		*zilog;
+	zfs_dirlock_t	*dl;
+	dmu_tx_t	*tx;
+	int		error;
+	int		zf = ZNEW;
+	uint64_t	parent;
+	uid_t		owner;
+	boolean_t	waited = B_FALSE;
+
+	ASSERT(S_ISDIR(tdip->i_mode));
+
+	ZFS_ENTER(zsb);
+	ZFS_VERIFY_ZP(dzp);
+	zilog = zsb->z_log;
+
+	/*
+	 * POSIX dictates that we return EPERM here.
+	 * Better choices include ENOTSUP or EISDIR.
+	 */
+	if (S_ISDIR(sip->i_mode)) {
+		ZFS_EXIT(zsb);
+		return (SET_ERROR(EPERM));
+	}
+
+	if (sip->i_sb != tdip->i_sb || zfsctl_is_node(sip)) {
+		ZFS_EXIT(zsb);
+		return (SET_ERROR(EXDEV));
+	}
+
+	szp = ITOZ(sip);
+	ZFS_VERIFY_ZP(szp);
+
+	/* Prevent links to .zfs/shares files */
+
+	if ((error = sa_lookup(szp->z_sa_hdl, SA_ZPL_PARENT(zsb),
+	    &parent, sizeof (uint64_t))) != 0) {
+		ZFS_EXIT(zsb);
+		return (error);
+	}
+	if (parent == zsb->z_shares_dir) {
+		ZFS_EXIT(zsb);
+		return (SET_ERROR(EPERM));
+	}
+
+	if (zsb->z_utf8 && u8_validate(name,
+	    strlen(name), NULL, U8_VALIDATE_ENTIRE, &error) < 0) {
+		ZFS_EXIT(zsb);
+		return (SET_ERROR(EILSEQ));
+	}
+#ifdef HAVE_PN_UTILS
+	if (flags & FIGNORECASE)
+		zf |= ZCILOOK;
+#endif /* HAVE_PN_UTILS */
+
+	/*
+	 * We do not support links between attributes and non-attributes
+	 * because of the potential security risk of creating links
+	 * into "normal" file space in order to circumvent restrictions
+	 * imposed in attribute space.
+	 */
+	if ((szp->z_pflags & ZFS_XATTR) != (dzp->z_pflags & ZFS_XATTR)) {
+		ZFS_EXIT(zsb);
+		return (SET_ERROR(EINVAL));
+	}
+
+	owner = zfs_fuid_map_id(zsb, szp->z_uid, cr, ZFS_OWNER);
+	if (owner != crgetuid(cr) && secpolicy_basic_link(cr) != 0) {
+		ZFS_EXIT(zsb);
+		return (SET_ERROR(EPERM));
+	}
+
+	if ((error = zfs_zaccess(dzp, ACE_ADD_FILE, 0, B_FALSE, cr))) {
+		ZFS_EXIT(zsb);
+		return (error);
+	}
+
+top:
+	/*
+	 * Attempt to lock directory; fail if entry already exists.
+	 */
+	error = zfs_dirent_lock(&dl, dzp, name, &tzp, zf, NULL, NULL);
+	if (error) {
+		ZFS_EXIT(zsb);
+		return (error);
+	}
+
+	tx = dmu_tx_create(zsb->z_os);
+	dmu_tx_hold_sa(tx, szp->z_sa_hdl, B_FALSE);
+	dmu_tx_hold_zap(tx, dzp->z_id, TRUE, name);
+	zfs_sa_upgrade_txholds(tx, szp);
+	zfs_sa_upgrade_txholds(tx, dzp);
+	error = dmu_tx_assign(tx, waited ? TXG_WAITED : TXG_NOWAIT);
+	if (error) {
+		zfs_dirent_unlock(dl);
+		if (error == ERESTART) {
+			waited = B_TRUE;
+			dmu_tx_wait(tx);
+			dmu_tx_abort(tx);
+			goto top;
+		}
+		dmu_tx_abort(tx);
+		ZFS_EXIT(zsb);
+		return (error);
+	}
+
+	error = zfs_link_create(dl, szp, tx, 0);
+
+	if (error == 0) {
+		uint64_t txtype = TX_LINK;
+#ifdef HAVE_PN_UTILS
+		if (flags & FIGNORECASE)
+			txtype |= TX_CI;
+#endif /* HAVE_PN_UTILS */
+		zfs_log_link(zilog, tx, txtype, dzp, szp, name);
+	}
+
+	dmu_tx_commit(tx);
+
+	zfs_dirent_unlock(dl);
+
+	if (zsb->z_os->os_sync == ZFS_SYNC_ALWAYS)
+		zil_commit(zilog, 0);
+
+	zfs_inode_update(dzp);
+	zfs_inode_update(szp);
+	ZFS_EXIT(zsb);
+	return (error);
+}
+EXPORT_SYMBOL(zfs_link);
+
+static void
+zfs_putpage_commit_cb(void *arg)
+{
+	struct page *pp = arg;
+
+	ClearPageError(pp);
+	end_page_writeback(pp);
+}
+
+/*
+ * Push a page out to disk, once the page is on stable storage the
+ * registered commit callback will be run as notification of completion.
+ *
+ *	IN:	ip	- page mapped for inode.
+ *		pp	- page to push (page is locked)
+ *		wbc	- writeback control data
+ *
+ *	RETURN:	0 if success
+ *		error code if failure
+ *
+ * Timestamps:
+ *	ip - ctime|mtime updated
+ */
+/* ARGSUSED */
+int
+zfs_putpage(struct inode *ip, struct page *pp, struct writeback_control *wbc)
+{
+	znode_t		*zp = ITOZ(ip);
+	zfs_sb_t	*zsb = ITOZSB(ip);
+	loff_t		offset;
+	loff_t		pgoff;
+	unsigned int	pglen;
+	rl_t		*rl;
+	dmu_tx_t	*tx;
+	caddr_t		va;
+	int		err = 0;
+	uint64_t	mtime[2], ctime[2];
+	sa_bulk_attr_t	bulk[3];
+	int		cnt = 0;
+	struct address_space *mapping;
+
+	ZFS_ENTER(zsb);
+	ZFS_VERIFY_ZP(zp);
+
+	ASSERT(PageLocked(pp));
+
+	pgoff = page_offset(pp);	/* Page byte-offset in file */
+	offset = i_size_read(ip);	/* File length in bytes */
+	pglen = MIN(PAGE_CACHE_SIZE,	/* Page length in bytes */
+	    P2ROUNDUP(offset, PAGE_CACHE_SIZE)-pgoff);
+
+	/* Page is beyond end of file */
+	if (pgoff >= offset) {
+		unlock_page(pp);
+		ZFS_EXIT(zsb);
+		return (0);
+	}
+
+	/* Truncate page length to end of file */
+	if (pgoff + pglen > offset)
+		pglen = offset - pgoff;
+
+#if 0
+	/*
+	 * FIXME: Allow mmap writes past its quota.  The correct fix
+	 * is to register a page_mkwrite() handler to count the page
+	 * against its quota when it is about to be dirtied.
+	 */
+	if (zfs_owner_overquota(zsb, zp, B_FALSE) ||
+	    zfs_owner_overquota(zsb, zp, B_TRUE)) {
+		err = EDQUOT;
+	}
+#endif
+
+	/*
+	 * The ordering here is critical and must adhere to the following
+	 * rules in order to avoid deadlocking in either zfs_read() or
+	 * zfs_free_range() due to a lock inversion.
+	 *
+	 * 1) The page must be unlocked prior to acquiring the range lock.
+	 *    This is critical because zfs_read() calls find_lock_page()
+	 *    which may block on the page lock while holding the range lock.
+	 *
+	 * 2) Before setting or clearing write back on a page the range lock
+	 *    must be held in order to prevent a lock inversion with the
+	 *    zfs_free_range() function.
+	 *
+	 * This presents a problem because upon entering this function the
+	 * page lock is already held.  To safely acquire the range lock the
+	 * page lock must be dropped.  This creates a window where another
+	 * process could truncate, invalidate, dirty, or write out the page.
+	 *
+	 * Therefore, after successfully reacquiring the range and page locks
+	 * the current page state is checked.  In the common case everything
+	 * will be as is expected and it can be written out.  However, if
+	 * the page state has changed it must be handled accordingly.
+	 */
+	mapping = pp->mapping;
+	redirty_page_for_writepage(wbc, pp);
+	unlock_page(pp);
+
+	rl = zfs_range_lock(zp, pgoff, pglen, RL_WRITER);
+	lock_page(pp);
+
+	/* Page mapping changed or it was no longer dirty, we're done */
+	if (unlikely((mapping != pp->mapping) || !PageDirty(pp))) {
+		unlock_page(pp);
+		zfs_range_unlock(rl);
+		ZFS_EXIT(zsb);
+		return (0);
+	}
+
+	/* Another process started write block if required */
+	if (PageWriteback(pp)) {
+		unlock_page(pp);
+		zfs_range_unlock(rl);
+
+		if (wbc->sync_mode != WB_SYNC_NONE)
+			wait_on_page_writeback(pp);
+
+		ZFS_EXIT(zsb);
+		return (0);
+	}
+
+	/* Clear the dirty flag the required locks are held */
+	if (!clear_page_dirty_for_io(pp)) {
+		unlock_page(pp);
+		zfs_range_unlock(rl);
+		ZFS_EXIT(zsb);
+		return (0);
+	}
+
+	/*
+	 * Counterpart for redirty_page_for_writepage() above.  This page
+	 * was in fact not skipped and should not be counted as if it were.
+	 */
+	wbc->pages_skipped--;
+	set_page_writeback(pp);
+	unlock_page(pp);
+
+	tx = dmu_tx_create(zsb->z_os);
+	dmu_tx_hold_write(tx, zp->z_id, pgoff, pglen);
+	dmu_tx_hold_sa(tx, zp->z_sa_hdl, B_FALSE);
+	zfs_sa_upgrade_txholds(tx, zp);
+
+	err = dmu_tx_assign(tx, TXG_NOWAIT);
+	if (err != 0) {
+		if (err == ERESTART)
+			dmu_tx_wait(tx);
+
+		dmu_tx_abort(tx);
+		__set_page_dirty_nobuffers(pp);
+		ClearPageError(pp);
+		end_page_writeback(pp);
+		zfs_range_unlock(rl);
+		ZFS_EXIT(zsb);
+		return (err);
+	}
+
+	va = kmap(pp);
+	ASSERT3U(pglen, <=, PAGE_CACHE_SIZE);
+	dmu_write(zsb->z_os, zp->z_id, pgoff, pglen, va, tx);
+	kunmap(pp);
+
+	SA_ADD_BULK_ATTR(bulk, cnt, SA_ZPL_MTIME(zsb), NULL, &mtime, 16);
+	SA_ADD_BULK_ATTR(bulk, cnt, SA_ZPL_CTIME(zsb), NULL, &ctime, 16);
+	SA_ADD_BULK_ATTR(bulk, cnt, SA_ZPL_FLAGS(zsb), NULL, &zp->z_pflags, 8);
+
+	/* Preserve the mtime and ctime provided by the inode */
+	ZFS_TIME_ENCODE(&ip->i_mtime, mtime);
+	ZFS_TIME_ENCODE(&ip->i_ctime, ctime);
+	zp->z_atime_dirty = 0;
+	zp->z_seq++;
+
+	err = sa_bulk_update(zp->z_sa_hdl, bulk, cnt, tx);
+
+	zfs_log_write(zsb->z_log, tx, TX_WRITE, zp, pgoff, pglen, 0,
+	    zfs_putpage_commit_cb, pp);
+	dmu_tx_commit(tx);
+
+	zfs_range_unlock(rl);
+
+	if (wbc->sync_mode != WB_SYNC_NONE) {
+		/*
+		 * Note that this is rarely called under writepages(), because
+		 * writepages() normally handles the entire commit for
+		 * performance reasons.
+		 */
+		if (zsb->z_log != NULL)
+			zil_commit(zsb->z_log, zp->z_id);
+	}
+
+	ZFS_EXIT(zsb);
+	return (err);
+}
+
+/*
+ * Update the system attributes when the inode has been dirtied.  For the
+ * moment we only update the mode, atime, mtime, and ctime.
+ */
+int
+zfs_dirty_inode(struct inode *ip, int flags)
+{
+	znode_t		*zp = ITOZ(ip);
+	zfs_sb_t	*zsb = ITOZSB(ip);
+	dmu_tx_t	*tx;
+	uint64_t	mode, atime[2], mtime[2], ctime[2];
+	sa_bulk_attr_t	bulk[4];
+	int		error;
+	int		cnt = 0;
+
+	if (zfs_is_readonly(zsb) || dmu_objset_is_snapshot(zsb->z_os))
+		return (0);
+
+	ZFS_ENTER(zsb);
+	ZFS_VERIFY_ZP(zp);
+
+	tx = dmu_tx_create(zsb->z_os);
+
+	dmu_tx_hold_sa(tx, zp->z_sa_hdl, B_FALSE);
+	zfs_sa_upgrade_txholds(tx, zp);
+
+	error = dmu_tx_assign(tx, TXG_WAIT);
+	if (error) {
+		dmu_tx_abort(tx);
+		goto out;
+	}
+
+	mutex_enter(&zp->z_lock);
+	SA_ADD_BULK_ATTR(bulk, cnt, SA_ZPL_MODE(zsb), NULL, &mode, 8);
+	SA_ADD_BULK_ATTR(bulk, cnt, SA_ZPL_ATIME(zsb), NULL, &atime, 16);
+	SA_ADD_BULK_ATTR(bulk, cnt, SA_ZPL_MTIME(zsb), NULL, &mtime, 16);
+	SA_ADD_BULK_ATTR(bulk, cnt, SA_ZPL_CTIME(zsb), NULL, &ctime, 16);
+
+	/* Preserve the mode, mtime and ctime provided by the inode */
+	ZFS_TIME_ENCODE(&ip->i_atime, atime);
+	ZFS_TIME_ENCODE(&ip->i_mtime, mtime);
+	ZFS_TIME_ENCODE(&ip->i_ctime, ctime);
+	mode = ip->i_mode;
+
+	zp->z_mode = mode;
+	zp->z_atime_dirty = 0;
+
+	error = sa_bulk_update(zp->z_sa_hdl, bulk, cnt, tx);
+	mutex_exit(&zp->z_lock);
+
+	dmu_tx_commit(tx);
+out:
+	ZFS_EXIT(zsb);
+	return (error);
+}
+EXPORT_SYMBOL(zfs_dirty_inode);
+
+/*ARGSUSED*/
+void
+zfs_inactive(struct inode *ip)
+{
+	znode_t	*zp = ITOZ(ip);
+	zfs_sb_t *zsb = ITOZSB(ip);
+	int error;
+	int need_unlock = 0;
+
+	/* Only read lock if we haven't already write locked, e.g. rollback */
+	if (!RW_WRITE_HELD(&zsb->z_teardown_inactive_lock)) {
+		need_unlock = 1;
+		rw_enter(&zsb->z_teardown_inactive_lock, RW_READER);
+	}
+	if (zp->z_sa_hdl == NULL) {
+		if (need_unlock)
+			rw_exit(&zsb->z_teardown_inactive_lock);
+		return;
+	}
+
+	if (zp->z_atime_dirty && zp->z_unlinked == 0) {
+		dmu_tx_t *tx = dmu_tx_create(zsb->z_os);
+
+		dmu_tx_hold_sa(tx, zp->z_sa_hdl, B_FALSE);
+		zfs_sa_upgrade_txholds(tx, zp);
+		error = dmu_tx_assign(tx, TXG_WAIT);
+		if (error) {
+			dmu_tx_abort(tx);
+		} else {
+			mutex_enter(&zp->z_lock);
+			(void) sa_update(zp->z_sa_hdl, SA_ZPL_ATIME(zsb),
+			    (void *)&zp->z_atime, sizeof (zp->z_atime), tx);
+			zp->z_atime_dirty = 0;
+			mutex_exit(&zp->z_lock);
+			dmu_tx_commit(tx);
+		}
+	}
+
+	zfs_zinactive(zp);
+	if (need_unlock)
+		rw_exit(&zsb->z_teardown_inactive_lock);
+}
+EXPORT_SYMBOL(zfs_inactive);
+
+/*
+ * Bounds-check the seek operation.
+ *
+ *	IN:	ip	- inode seeking within
+ *		ooff	- old file offset
+ *		noffp	- pointer to new file offset
+ *		ct	- caller context
+ *
+ *	RETURN:	0 if success
+ *		EINVAL if new offset invalid
+ */
+/* ARGSUSED */
+int
+zfs_seek(struct inode *ip, offset_t ooff, offset_t *noffp)
+{
+	if (S_ISDIR(ip->i_mode))
+		return (0);
+	return ((*noffp < 0 || *noffp > MAXOFFSET_T) ? EINVAL : 0);
+}
+EXPORT_SYMBOL(zfs_seek);
+
+/*
+ * Fill pages with data from the disk.
+ */
+static int
+zfs_fillpage(struct inode *ip, struct page *pl[], int nr_pages)
+{
+	znode_t *zp = ITOZ(ip);
+	zfs_sb_t *zsb = ITOZSB(ip);
+	objset_t *os;
+	struct page *cur_pp;
+	u_offset_t io_off, total;
+	size_t io_len;
+	loff_t i_size;
+	unsigned page_idx;
+	int err;
+
+	os = zsb->z_os;
+	io_len = nr_pages << PAGE_CACHE_SHIFT;
+	i_size = i_size_read(ip);
+	io_off = page_offset(pl[0]);
+
+	if (io_off + io_len > i_size)
+		io_len = i_size - io_off;
+
+	/*
+	 * Iterate over list of pages and read each page individually.
+	 */
+	page_idx = 0;
+	cur_pp   = pl[0];
+	for (total = io_off + io_len; io_off < total; io_off += PAGESIZE) {
+		caddr_t va;
+
+		va = kmap(cur_pp);
+		err = dmu_read(os, zp->z_id, io_off, PAGESIZE, va,
+		    DMU_READ_PREFETCH);
+		kunmap(cur_pp);
+		if (err) {
+			/* convert checksum errors into IO errors */
+			if (err == ECKSUM)
+				err = SET_ERROR(EIO);
+			return (err);
+		}
+		cur_pp = pl[++page_idx];
+	}
+
+	return (0);
+}
+
+/*
+ * Uses zfs_fillpage to read data from the file and fill the pages.
+ *
+ *	IN:	ip	 - inode of file to get data from.
+ *		pl	 - list of pages to read
+ *		nr_pages - number of pages to read
+ *
+ *	RETURN:	0 on success, error code on failure.
+ *
+ * Timestamps:
+ *	vp - atime updated
+ */
+/* ARGSUSED */
+int
+zfs_getpage(struct inode *ip, struct page *pl[], int nr_pages)
+{
+	znode_t	 *zp  = ITOZ(ip);
+	zfs_sb_t *zsb = ITOZSB(ip);
+	int	 err;
+
+	if (pl == NULL)
+		return (0);
+
+	ZFS_ENTER(zsb);
+	ZFS_VERIFY_ZP(zp);
+
+	err = zfs_fillpage(ip, pl, nr_pages);
+
+	if (!err)
+		ZFS_ACCESSTIME_STAMP(zsb, zp);
+
+	ZFS_EXIT(zsb);
+	return (err);
+}
+EXPORT_SYMBOL(zfs_getpage);
+
+/*
+ * Check ZFS specific permissions to memory map a section of a file.
+ *
+ *	IN:	ip	- inode of the file to mmap
+ *		off	- file offset
+ *		addrp	- start address in memory region
+ *		len	- length of memory region
+ *		vm_flags- address flags
+ *
+ *	RETURN:	0 if success
+ *		error code if failure
+ */
+/*ARGSUSED*/
+int
+zfs_map(struct inode *ip, offset_t off, caddr_t *addrp, size_t len,
+    unsigned long vm_flags)
+{
+	znode_t  *zp = ITOZ(ip);
+	zfs_sb_t *zsb = ITOZSB(ip);
+
+	ZFS_ENTER(zsb);
+	ZFS_VERIFY_ZP(zp);
+
+	if ((vm_flags & VM_WRITE) && (zp->z_pflags &
+	    (ZFS_IMMUTABLE | ZFS_READONLY | ZFS_APPENDONLY))) {
+		ZFS_EXIT(zsb);
+		return (SET_ERROR(EPERM));
+	}
+
+	if ((vm_flags & (VM_READ | VM_EXEC)) &&
+	    (zp->z_pflags & ZFS_AV_QUARANTINED)) {
+		ZFS_EXIT(zsb);
+		return (SET_ERROR(EACCES));
+	}
+
+	if (off < 0 || len > MAXOFFSET_T - off) {
+		ZFS_EXIT(zsb);
+		return (SET_ERROR(ENXIO));
+	}
+
+	ZFS_EXIT(zsb);
+	return (0);
+}
+EXPORT_SYMBOL(zfs_map);
+
+/*
+ * convoff - converts the given data (start, whence) to the
+ * given whence.
+ */
+int
+convoff(struct inode *ip, flock64_t *lckdat, int  whence, offset_t offset)
+{
+	vattr_t vap;
+	int error;
+
+	if ((lckdat->l_whence == 2) || (whence == 2)) {
+		if ((error = zfs_getattr(ip, &vap, 0, CRED()) != 0))
+			return (error);
+	}
+
+	switch (lckdat->l_whence) {
+	case 1:
+		lckdat->l_start += offset;
+		break;
+	case 2:
+		lckdat->l_start += vap.va_size;
+		/* FALLTHRU */
+	case 0:
+		break;
+	default:
+		return (SET_ERROR(EINVAL));
+	}
+
+	if (lckdat->l_start < 0)
+		return (SET_ERROR(EINVAL));
+
+	switch (whence) {
+	case 1:
+		lckdat->l_start -= offset;
+		break;
+	case 2:
+		lckdat->l_start -= vap.va_size;
+		/* FALLTHRU */
+	case 0:
+		break;
+	default:
+		return (SET_ERROR(EINVAL));
+	}
+
+	lckdat->l_whence = (short)whence;
+	return (0);
+}
+
+/*
+ * Free or allocate space in a file.  Currently, this function only
+ * supports the `F_FREESP' command.  However, this command is somewhat
+ * misnamed, as its functionality includes the ability to allocate as
+ * well as free space.
+ *
+ *	IN:	ip	- inode of file to free data in.
+ *		cmd	- action to take (only F_FREESP supported).
+ *		bfp	- section of file to free/alloc.
+ *		flag	- current file open mode flags.
+ *		offset	- current file offset.
+ *		cr	- credentials of caller [UNUSED].
+ *
+ *	RETURN:	0 on success, error code on failure.
+ *
+ * Timestamps:
+ *	ip - ctime|mtime updated
+ */
+/* ARGSUSED */
+int
+zfs_space(struct inode *ip, int cmd, flock64_t *bfp, int flag,
+    offset_t offset, cred_t *cr)
+{
+	znode_t		*zp = ITOZ(ip);
+	zfs_sb_t	*zsb = ITOZSB(ip);
+	uint64_t	off, len;
+	int		error;
+
+	ZFS_ENTER(zsb);
+	ZFS_VERIFY_ZP(zp);
+
+	if (cmd != F_FREESP) {
+		ZFS_EXIT(zsb);
+		return (SET_ERROR(EINVAL));
+	}
+
+	if ((error = convoff(ip, bfp, 0, offset))) {
+		ZFS_EXIT(zsb);
+		return (error);
+	}
+
+	if (bfp->l_len < 0) {
+		ZFS_EXIT(zsb);
+		return (SET_ERROR(EINVAL));
+	}
+
+	/*
+	 * Permissions aren't checked on Solaris because on this OS
+	 * zfs_space() can only be called with an opened file handle.
+	 * On Linux we can get here through truncate_range() which
+	 * operates directly on inodes, so we need to check access rights.
+	 */
+	if ((error = zfs_zaccess(zp, ACE_WRITE_DATA, 0, B_FALSE, cr))) {
+		ZFS_EXIT(zsb);
+		return (error);
+	}
+
+	off = bfp->l_start;
+	len = bfp->l_len; /* 0 means from off to end of file */
+
+	error = zfs_freesp(zp, off, len, flag, TRUE);
+
+	ZFS_EXIT(zsb);
+	return (error);
+}
+EXPORT_SYMBOL(zfs_space);
+
+/*ARGSUSED*/
+int
+zfs_fid(struct inode *ip, fid_t *fidp)
+{
+	znode_t		*zp = ITOZ(ip);
+	zfs_sb_t	*zsb = ITOZSB(ip);
+	uint32_t	gen;
+	uint64_t	gen64;
+	uint64_t	object = zp->z_id;
+	zfid_short_t	*zfid;
+	int		size, i, error;
+
+	ZFS_ENTER(zsb);
+	ZFS_VERIFY_ZP(zp);
+
+	if ((error = sa_lookup(zp->z_sa_hdl, SA_ZPL_GEN(zsb),
+	    &gen64, sizeof (uint64_t))) != 0) {
+		ZFS_EXIT(zsb);
+		return (error);
+	}
+
+	gen = (uint32_t)gen64;
+
+	size = (zsb->z_parent != zsb) ? LONG_FID_LEN : SHORT_FID_LEN;
+	if (fidp->fid_len < size) {
+		fidp->fid_len = size;
+		ZFS_EXIT(zsb);
+		return (SET_ERROR(ENOSPC));
+	}
+
+	zfid = (zfid_short_t *)fidp;
+
+	zfid->zf_len = size;
+
+	for (i = 0; i < sizeof (zfid->zf_object); i++)
+		zfid->zf_object[i] = (uint8_t)(object >> (8 * i));
+
+	/* Must have a non-zero generation number to distinguish from .zfs */
+	if (gen == 0)
+		gen = 1;
+	for (i = 0; i < sizeof (zfid->zf_gen); i++)
+		zfid->zf_gen[i] = (uint8_t)(gen >> (8 * i));
+
+	if (size == LONG_FID_LEN) {
+		uint64_t	objsetid = dmu_objset_id(zsb->z_os);
+		zfid_long_t	*zlfid;
+
+		zlfid = (zfid_long_t *)fidp;
+
+		for (i = 0; i < sizeof (zlfid->zf_setid); i++)
+			zlfid->zf_setid[i] = (uint8_t)(objsetid >> (8 * i));
+
+		/* XXX - this should be the generation number for the objset */
+		for (i = 0; i < sizeof (zlfid->zf_setgen); i++)
+			zlfid->zf_setgen[i] = 0;
+	}
+
+	ZFS_EXIT(zsb);
+	return (0);
+}
+EXPORT_SYMBOL(zfs_fid);
+
+/*ARGSUSED*/
+int
+zfs_getsecattr(struct inode *ip, vsecattr_t *vsecp, int flag, cred_t *cr)
+{
+	znode_t *zp = ITOZ(ip);
+	zfs_sb_t *zsb = ITOZSB(ip);
+	int error;
+	boolean_t skipaclchk = (flag & ATTR_NOACLCHECK) ? B_TRUE : B_FALSE;
+
+	ZFS_ENTER(zsb);
+	ZFS_VERIFY_ZP(zp);
+	error = zfs_getacl(zp, vsecp, skipaclchk, cr);
+	ZFS_EXIT(zsb);
+
+	return (error);
+}
+EXPORT_SYMBOL(zfs_getsecattr);
+
+/*ARGSUSED*/
+int
+zfs_setsecattr(struct inode *ip, vsecattr_t *vsecp, int flag, cred_t *cr)
+{
+	znode_t *zp = ITOZ(ip);
+	zfs_sb_t *zsb = ITOZSB(ip);
+	int error;
+	boolean_t skipaclchk = (flag & ATTR_NOACLCHECK) ? B_TRUE : B_FALSE;
+	zilog_t	*zilog = zsb->z_log;
+
+	ZFS_ENTER(zsb);
+	ZFS_VERIFY_ZP(zp);
+
+	error = zfs_setacl(zp, vsecp, skipaclchk, cr);
+
+	if (zsb->z_os->os_sync == ZFS_SYNC_ALWAYS)
+		zil_commit(zilog, 0);
+
+	ZFS_EXIT(zsb);
+	return (error);
+}
+EXPORT_SYMBOL(zfs_setsecattr);
+
+#ifdef HAVE_UIO_ZEROCOPY
+/*
+ * Tunable, both must be a power of 2.
+ *
+ * zcr_blksz_min: the smallest read we may consider to loan out an arcbuf
+ * zcr_blksz_max: if set to less than the file block size, allow loaning out of
+ *		an arcbuf for a partial block read
+ */
+int zcr_blksz_min = (1 << 10);	/* 1K */
+int zcr_blksz_max = (1 << 17);	/* 128K */
+
+/*ARGSUSED*/
+static int
+zfs_reqzcbuf(struct inode *ip, enum uio_rw ioflag, xuio_t *xuio, cred_t *cr)
+{
+	znode_t	*zp = ITOZ(ip);
+	zfs_sb_t *zsb = ITOZSB(ip);
+	int max_blksz = zsb->z_max_blksz;
+	uio_t *uio = &xuio->xu_uio;
+	ssize_t size = uio->uio_resid;
+	offset_t offset = uio->uio_loffset;
+	int blksz;
+	int fullblk, i;
+	arc_buf_t *abuf;
+	ssize_t maxsize;
+	int preamble, postamble;
+
+	if (xuio->xu_type != UIOTYPE_ZEROCOPY)
+		return (SET_ERROR(EINVAL));
+
+	ZFS_ENTER(zsb);
+	ZFS_VERIFY_ZP(zp);
+	switch (ioflag) {
+	case UIO_WRITE:
+		/*
+		 * Loan out an arc_buf for write if write size is bigger than
+		 * max_blksz, and the file's block size is also max_blksz.
+		 */
+		blksz = max_blksz;
+		if (size < blksz || zp->z_blksz != blksz) {
+			ZFS_EXIT(zsb);
+			return (SET_ERROR(EINVAL));
+		}
+		/*
+		 * Caller requests buffers for write before knowing where the
+		 * write offset might be (e.g. NFS TCP write).
+		 */
+		if (offset == -1) {
+			preamble = 0;
+		} else {
+			preamble = P2PHASE(offset, blksz);
+			if (preamble) {
+				preamble = blksz - preamble;
+				size -= preamble;
+			}
+		}
+
+		postamble = P2PHASE(size, blksz);
+		size -= postamble;
+
+		fullblk = size / blksz;
+		(void) dmu_xuio_init(xuio,
+		    (preamble != 0) + fullblk + (postamble != 0));
+
+		/*
+		 * Have to fix iov base/len for partial buffers.  They
+		 * currently represent full arc_buf's.
+		 */
+		if (preamble) {
+			/* data begins in the middle of the arc_buf */
+			abuf = dmu_request_arcbuf(sa_get_db(zp->z_sa_hdl),
+			    blksz);
+			ASSERT(abuf);
+			(void) dmu_xuio_add(xuio, abuf,
+			    blksz - preamble, preamble);
+		}
+
+		for (i = 0; i < fullblk; i++) {
+			abuf = dmu_request_arcbuf(sa_get_db(zp->z_sa_hdl),
+			    blksz);
+			ASSERT(abuf);
+			(void) dmu_xuio_add(xuio, abuf, 0, blksz);
+		}
+
+		if (postamble) {
+			/* data ends in the middle of the arc_buf */
+			abuf = dmu_request_arcbuf(sa_get_db(zp->z_sa_hdl),
+			    blksz);
+			ASSERT(abuf);
+			(void) dmu_xuio_add(xuio, abuf, 0, postamble);
+		}
+		break;
+	case UIO_READ:
+		/*
+		 * Loan out an arc_buf for read if the read size is larger than
+		 * the current file block size.  Block alignment is not
+		 * considered.  Partial arc_buf will be loaned out for read.
+		 */
+		blksz = zp->z_blksz;
+		if (blksz < zcr_blksz_min)
+			blksz = zcr_blksz_min;
+		if (blksz > zcr_blksz_max)
+			blksz = zcr_blksz_max;
+		/* avoid potential complexity of dealing with it */
+		if (blksz > max_blksz) {
+			ZFS_EXIT(zsb);
+			return (SET_ERROR(EINVAL));
+		}
+
+		maxsize = zp->z_size - uio->uio_loffset;
+		if (size > maxsize)
+			size = maxsize;
+
+		if (size < blksz) {
+			ZFS_EXIT(zsb);
+			return (SET_ERROR(EINVAL));
+		}
+		break;
+	default:
+		ZFS_EXIT(zsb);
+		return (SET_ERROR(EINVAL));
+	}
+
+	uio->uio_extflg = UIO_XUIO;
+	XUIO_XUZC_RW(xuio) = ioflag;
+	ZFS_EXIT(zsb);
+	return (0);
+}
+
+/*ARGSUSED*/
+static int
+zfs_retzcbuf(struct inode *ip, xuio_t *xuio, cred_t *cr)
+{
+	int i;
+	arc_buf_t *abuf;
+	int ioflag = XUIO_XUZC_RW(xuio);
+
+	ASSERT(xuio->xu_type == UIOTYPE_ZEROCOPY);
+
+	i = dmu_xuio_cnt(xuio);
+	while (i-- > 0) {
+		abuf = dmu_xuio_arcbuf(xuio, i);
+		/*
+		 * if abuf == NULL, it must be a write buffer
+		 * that has been returned in zfs_write().
+		 */
+		if (abuf)
+			dmu_return_arcbuf(abuf);
+		ASSERT(abuf || ioflag == UIO_WRITE);
+	}
+
+	dmu_xuio_fini(xuio);
+	return (0);
+}
+#endif /* HAVE_UIO_ZEROCOPY */
+
+#if defined(_KERNEL) && defined(HAVE_SPL)
+module_param(zfs_read_chunk_size, long, 0644);
+MODULE_PARM_DESC(zfs_read_chunk_size, "Bytes to read per chunk");
+#endif
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/module/zfs/zfs_znode.c
@@ -0,0 +1,2157 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013 by Delphix. All rights reserved.
+ */
+
+/* Portions Copyright 2007 Jeremy Teo */
+
+#ifdef _KERNEL
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/time.h>
+#include <sys/systm.h>
+#include <sys/sysmacros.h>
+#include <sys/resource.h>
+#include <sys/mntent.h>
+#include <sys/mkdev.h>
+#include <sys/u8_textprep.h>
+#include <sys/dsl_dataset.h>
+#include <sys/vfs.h>
+#include <sys/vfs_opreg.h>
+#include <sys/vnode.h>
+#include <sys/file.h>
+#include <sys/kmem.h>
+#include <sys/errno.h>
+#include <sys/unistd.h>
+#include <sys/mode.h>
+#include <sys/atomic.h>
+#include <vm/pvn.h>
+#include "fs/fs_subr.h"
+#include <sys/zfs_dir.h>
+#include <sys/zfs_acl.h>
+#include <sys/zfs_ioctl.h>
+#include <sys/zfs_rlock.h>
+#include <sys/zfs_fuid.h>
+#include <sys/zfs_vnops.h>
+#include <sys/zfs_ctldir.h>
+#include <sys/dnode.h>
+#include <sys/fs/zfs.h>
+#include <sys/kidmap.h>
+#include <sys/zpl.h>
+#endif /* _KERNEL */
+
+#include <sys/dmu.h>
+#include <sys/dmu_objset.h>
+#include <sys/refcount.h>
+#include <sys/stat.h>
+#include <sys/zap.h>
+#include <sys/zfs_znode.h>
+#include <sys/sa.h>
+#include <sys/zfs_sa.h>
+#include <sys/zfs_stat.h>
+
+#include "zfs_prop.h"
+#include "zfs_comutil.h"
+
+/*
+ * Define ZNODE_STATS to turn on statistic gathering. By default, it is only
+ * turned on when DEBUG is also defined.
+ */
+#ifdef	DEBUG
+#define	ZNODE_STATS
+#endif	/* DEBUG */
+
+#ifdef	ZNODE_STATS
+#define	ZNODE_STAT_ADD(stat)			((stat)++)
+#else
+#define	ZNODE_STAT_ADD(stat)			/* nothing */
+#endif	/* ZNODE_STATS */
+
+/*
+ * Functions needed for userland (ie: libzpool) are not put under
+ * #ifdef_KERNEL; the rest of the functions have dependencies
+ * (such as VFS logic) that will not compile easily in userland.
+ */
+#ifdef _KERNEL
+
+static kmem_cache_t *znode_cache = NULL;
+static kmem_cache_t *znode_hold_cache = NULL;
+unsigned int zfs_object_mutex_size = ZFS_OBJ_MTX_SZ;
+
+/*ARGSUSED*/
+static int
+zfs_znode_cache_constructor(void *buf, void *arg, int kmflags)
+{
+	znode_t *zp = buf;
+
+	inode_init_once(ZTOI(zp));
+	list_link_init(&zp->z_link_node);
+
+	mutex_init(&zp->z_lock, NULL, MUTEX_DEFAULT, NULL);
+	rw_init(&zp->z_parent_lock, NULL, RW_DEFAULT, NULL);
+	rw_init(&zp->z_name_lock, NULL, RW_DEFAULT, NULL);
+	mutex_init(&zp->z_acl_lock, NULL, MUTEX_DEFAULT, NULL);
+	rw_init(&zp->z_xattr_lock, NULL, RW_DEFAULT, NULL);
+
+	mutex_init(&zp->z_range_lock, NULL, MUTEX_DEFAULT, NULL);
+	avl_create(&zp->z_range_avl, zfs_range_compare,
+	    sizeof (rl_t), offsetof(rl_t, r_node));
+
+	zp->z_dirlocks = NULL;
+	zp->z_acl_cached = NULL;
+	zp->z_xattr_cached = NULL;
+	zp->z_xattr_parent = NULL;
+	zp->z_moved = 0;
+	return (0);
+}
+
+/*ARGSUSED*/
+static void
+zfs_znode_cache_destructor(void *buf, void *arg)
+{
+	znode_t *zp = buf;
+
+	ASSERT(!list_link_active(&zp->z_link_node));
+	mutex_destroy(&zp->z_lock);
+	rw_destroy(&zp->z_parent_lock);
+	rw_destroy(&zp->z_name_lock);
+	mutex_destroy(&zp->z_acl_lock);
+	rw_destroy(&zp->z_xattr_lock);
+	avl_destroy(&zp->z_range_avl);
+	mutex_destroy(&zp->z_range_lock);
+
+	ASSERT(zp->z_dirlocks == NULL);
+	ASSERT(zp->z_acl_cached == NULL);
+	ASSERT(zp->z_xattr_cached == NULL);
+	ASSERT(zp->z_xattr_parent == NULL);
+}
+
+static int
+zfs_znode_hold_cache_constructor(void *buf, void *arg, int kmflags)
+{
+	znode_hold_t *zh = buf;
+
+	mutex_init(&zh->zh_lock, NULL, MUTEX_DEFAULT, NULL);
+	refcount_create(&zh->zh_refcount);
+	zh->zh_obj = ZFS_NO_OBJECT;
+
+	return (0);
+}
+
+static void
+zfs_znode_hold_cache_destructor(void *buf, void *arg)
+{
+	znode_hold_t *zh = buf;
+
+	mutex_destroy(&zh->zh_lock);
+	refcount_destroy(&zh->zh_refcount);
+}
+
+void
+zfs_znode_init(void)
+{
+	/*
+	 * Initialize zcache.  The KMC_SLAB hint is used in order that it be
+	 * backed by kmalloc() when on the Linux slab in order that any
+	 * wait_on_bit() operations on the related inode operate properly.
+	 */
+	ASSERT(znode_cache == NULL);
+	znode_cache = kmem_cache_create("zfs_znode_cache",
+	    sizeof (znode_t), 0, zfs_znode_cache_constructor,
+	    zfs_znode_cache_destructor, NULL, NULL, NULL, KMC_SLAB);
+
+	ASSERT(znode_hold_cache == NULL);
+	znode_hold_cache = kmem_cache_create("zfs_znode_hold_cache",
+	    sizeof (znode_hold_t), 0, zfs_znode_hold_cache_constructor,
+	    zfs_znode_hold_cache_destructor, NULL, NULL, NULL, 0);
+}
+
+void
+zfs_znode_fini(void)
+{
+	/*
+	 * Cleanup zcache
+	 */
+	if (znode_cache)
+		kmem_cache_destroy(znode_cache);
+	znode_cache = NULL;
+
+	if (znode_hold_cache)
+		kmem_cache_destroy(znode_hold_cache);
+	znode_hold_cache = NULL;
+}
+
+/*
+ * The zfs_znode_hold_enter() / zfs_znode_hold_exit() functions are used to
+ * serialize access to a znode and its SA buffer while the object is being
+ * created or destroyed.  This kind of locking would normally reside in the
+ * znode itself but in this case that's impossible because the znode and SA
+ * buffer may not yet exist.  Therefore the locking is handled externally
+ * with an array of mutexs and AVLs trees which contain per-object locks.
+ *
+ * In zfs_znode_hold_enter() a per-object lock is created as needed, inserted
+ * in to the correct AVL tree and finally the per-object lock is held.  In
+ * zfs_znode_hold_exit() the process is reversed.  The per-object lock is
+ * released, removed from the AVL tree and destroyed if there are no waiters.
+ *
+ * This scheme has two important properties:
+ *
+ * 1) No memory allocations are performed while holding one of the z_hold_locks.
+ *    This ensures evict(), which can be called from direct memory reclaim, will
+ *    never block waiting on a z_hold_locks which just happens to have hashed
+ *    to the same index.
+ *
+ * 2) All locks used to serialize access to an object are per-object and never
+ *    shared.  This minimizes lock contention without creating a large number
+ *    of dedicated locks.
+ *
+ * On the downside it does require znode_lock_t structures to be frequently
+ * allocated and freed.  However, because these are backed by a kmem cache
+ * and very short lived this cost is minimal.
+ */
+int
+zfs_znode_hold_compare(const void *a, const void *b)
+{
+	const znode_hold_t *zh_a = a;
+	const znode_hold_t *zh_b = b;
+
+	if (zh_a->zh_obj < zh_b->zh_obj)
+		return (-1);
+	else if (zh_a->zh_obj > zh_b->zh_obj)
+		return (1);
+	else
+		return (0);
+}
+
+boolean_t
+zfs_znode_held(zfs_sb_t *zsb, uint64_t obj)
+{
+	znode_hold_t *zh, search;
+	int i = ZFS_OBJ_HASH(zsb, obj);
+	boolean_t held;
+
+	search.zh_obj = obj;
+
+	mutex_enter(&zsb->z_hold_locks[i]);
+	zh = avl_find(&zsb->z_hold_trees[i], &search, NULL);
+	held = (zh && MUTEX_HELD(&zh->zh_lock)) ? B_TRUE : B_FALSE;
+	mutex_exit(&zsb->z_hold_locks[i]);
+
+	return (held);
+}
+
+static znode_hold_t *
+zfs_znode_hold_enter(zfs_sb_t *zsb, uint64_t obj)
+{
+	znode_hold_t *zh, *zh_new, search;
+	int i = ZFS_OBJ_HASH(zsb, obj);
+	boolean_t found = B_FALSE;
+
+	zh_new = kmem_cache_alloc(znode_hold_cache, KM_SLEEP);
+	zh_new->zh_obj = obj;
+	search.zh_obj = obj;
+
+	mutex_enter(&zsb->z_hold_locks[i]);
+	zh = avl_find(&zsb->z_hold_trees[i], &search, NULL);
+	if (likely(zh == NULL)) {
+		zh = zh_new;
+		avl_add(&zsb->z_hold_trees[i], zh);
+	} else {
+		ASSERT3U(zh->zh_obj, ==, obj);
+		found = B_TRUE;
+	}
+	refcount_add(&zh->zh_refcount, NULL);
+	mutex_exit(&zsb->z_hold_locks[i]);
+
+	if (found == B_TRUE)
+		kmem_cache_free(znode_hold_cache, zh_new);
+
+	ASSERT(MUTEX_NOT_HELD(&zh->zh_lock));
+	ASSERT3S(refcount_count(&zh->zh_refcount), >, 0);
+	mutex_enter(&zh->zh_lock);
+
+	return (zh);
+}
+
+static void
+zfs_znode_hold_exit(zfs_sb_t *zsb, znode_hold_t *zh)
+{
+	int i = ZFS_OBJ_HASH(zsb, zh->zh_obj);
+	boolean_t remove = B_FALSE;
+
+	ASSERT(zfs_znode_held(zsb, zh->zh_obj));
+	ASSERT3S(refcount_count(&zh->zh_refcount), >, 0);
+	mutex_exit(&zh->zh_lock);
+
+	mutex_enter(&zsb->z_hold_locks[i]);
+	if (refcount_remove(&zh->zh_refcount, NULL) == 0) {
+		avl_remove(&zsb->z_hold_trees[i], zh);
+		remove = B_TRUE;
+	}
+	mutex_exit(&zsb->z_hold_locks[i]);
+
+	if (remove == B_TRUE)
+		kmem_cache_free(znode_hold_cache, zh);
+}
+
+int
+zfs_create_share_dir(zfs_sb_t *zsb, dmu_tx_t *tx)
+{
+#ifdef HAVE_SMB_SHARE
+	zfs_acl_ids_t acl_ids;
+	vattr_t vattr;
+	znode_t *sharezp;
+	vnode_t *vp;
+	znode_t *zp;
+	int error;
+
+	vattr.va_mask = AT_MODE|AT_UID|AT_GID|AT_TYPE;
+	vattr.va_mode = S_IFDIR | 0555;
+	vattr.va_uid = crgetuid(kcred);
+	vattr.va_gid = crgetgid(kcred);
+
+	sharezp = kmem_cache_alloc(znode_cache, KM_SLEEP);
+	sharezp->z_moved = 0;
+	sharezp->z_unlinked = 0;
+	sharezp->z_atime_dirty = 0;
+	sharezp->z_zfsvfs = zfsvfs;
+	sharezp->z_is_sa = zfsvfs->z_use_sa;
+
+	vp = ZTOV(sharezp);
+	vn_reinit(vp);
+	vp->v_type = VDIR;
+
+	VERIFY(0 == zfs_acl_ids_create(sharezp, IS_ROOT_NODE, &vattr,
+	    kcred, NULL, &acl_ids));
+	zfs_mknode(sharezp, &vattr, tx, kcred, IS_ROOT_NODE, &zp, &acl_ids);
+	ASSERT3P(zp, ==, sharezp);
+	ASSERT(!vn_in_dnlc(ZTOV(sharezp))); /* not valid to move */
+	POINTER_INVALIDATE(&sharezp->z_zfsvfs);
+	error = zap_add(zfsvfs->z_os, MASTER_NODE_OBJ,
+	    ZFS_SHARES_DIR, 8, 1, &sharezp->z_id, tx);
+	zfsvfs->z_shares_dir = sharezp->z_id;
+
+	zfs_acl_ids_free(&acl_ids);
+	// ZTOV(sharezp)->v_count = 0;
+	sa_handle_destroy(sharezp->z_sa_hdl);
+	kmem_cache_free(znode_cache, sharezp);
+
+	return (error);
+#else
+	return (0);
+#endif /* HAVE_SMB_SHARE */
+}
+
+static void
+zfs_znode_sa_init(zfs_sb_t *zsb, znode_t *zp,
+    dmu_buf_t *db, dmu_object_type_t obj_type, sa_handle_t *sa_hdl)
+{
+	ASSERT(zfs_znode_held(zsb, zp->z_id));
+
+	mutex_enter(&zp->z_lock);
+
+	ASSERT(zp->z_sa_hdl == NULL);
+	ASSERT(zp->z_acl_cached == NULL);
+	if (sa_hdl == NULL) {
+		VERIFY(0 == sa_handle_get_from_db(zsb->z_os, db, zp,
+		    SA_HDL_SHARED, &zp->z_sa_hdl));
+	} else {
+		zp->z_sa_hdl = sa_hdl;
+		sa_set_userp(sa_hdl, zp);
+	}
+
+	zp->z_is_sa = (obj_type == DMU_OT_SA) ? B_TRUE : B_FALSE;
+
+	mutex_exit(&zp->z_lock);
+}
+
+void
+zfs_znode_dmu_fini(znode_t *zp)
+{
+	ASSERT(zfs_znode_held(ZTOZSB(zp), zp->z_id) || zp->z_unlinked ||
+	    RW_WRITE_HELD(&ZTOZSB(zp)->z_teardown_inactive_lock));
+
+	sa_handle_destroy(zp->z_sa_hdl);
+	zp->z_sa_hdl = NULL;
+}
+
+/*
+ * Called by new_inode() to allocate a new inode.
+ */
+int
+zfs_inode_alloc(struct super_block *sb, struct inode **ip)
+{
+	znode_t *zp;
+
+	zp = kmem_cache_alloc(znode_cache, KM_SLEEP);
+	*ip = ZTOI(zp);
+
+	return (0);
+}
+
+/*
+ * Called in multiple places when an inode should be destroyed.
+ */
+void
+zfs_inode_destroy(struct inode *ip)
+{
+	znode_t *zp = ITOZ(ip);
+	zfs_sb_t *zsb = ZTOZSB(zp);
+
+	mutex_enter(&zsb->z_znodes_lock);
+	if (list_link_active(&zp->z_link_node)) {
+		list_remove(&zsb->z_all_znodes, zp);
+		zsb->z_nr_znodes--;
+	}
+	mutex_exit(&zsb->z_znodes_lock);
+
+	if (zp->z_acl_cached) {
+		zfs_acl_free(zp->z_acl_cached);
+		zp->z_acl_cached = NULL;
+	}
+
+	if (zp->z_xattr_cached) {
+		nvlist_free(zp->z_xattr_cached);
+		zp->z_xattr_cached = NULL;
+	}
+
+	if (zp->z_xattr_parent) {
+		zfs_iput_async(ZTOI(zp->z_xattr_parent));
+		zp->z_xattr_parent = NULL;
+	}
+
+	kmem_cache_free(znode_cache, zp);
+}
+
+static void
+zfs_inode_set_ops(zfs_sb_t *zsb, struct inode *ip)
+{
+	uint64_t rdev = 0;
+
+	switch (ip->i_mode & S_IFMT) {
+	case S_IFREG:
+		ip->i_op = &zpl_inode_operations;
+		ip->i_fop = &zpl_file_operations;
+		ip->i_mapping->a_ops = &zpl_address_space_operations;
+		break;
+
+	case S_IFDIR:
+		ip->i_op = &zpl_dir_inode_operations;
+		ip->i_fop = &zpl_dir_file_operations;
+		ITOZ(ip)->z_zn_prefetch = B_TRUE;
+		break;
+
+	case S_IFLNK:
+		ip->i_op = &zpl_symlink_inode_operations;
+		break;
+
+	/*
+	 * rdev is only stored in a SA only for device files.
+	 */
+	case S_IFCHR:
+	case S_IFBLK:
+		sa_lookup(ITOZ(ip)->z_sa_hdl, SA_ZPL_RDEV(zsb), &rdev,
+		    sizeof (rdev));
+		/*FALLTHROUGH*/
+	case S_IFIFO:
+	case S_IFSOCK:
+		init_special_inode(ip, ip->i_mode, rdev);
+		ip->i_op = &zpl_special_inode_operations;
+		break;
+
+	default:
+		zfs_panic_recover("inode %llu has invalid mode: 0x%x\n",
+		    (u_longlong_t)ip->i_ino, ip->i_mode);
+
+		/* Assume the inode is a file and attempt to continue */
+		ip->i_mode = S_IFREG | 0644;
+		ip->i_op = &zpl_inode_operations;
+		ip->i_fop = &zpl_file_operations;
+		ip->i_mapping->a_ops = &zpl_address_space_operations;
+		break;
+	}
+}
+
+/*
+ * Construct a znode+inode and initialize.
+ *
+ * This does not do a call to dmu_set_user() that is
+ * up to the caller to do, in case you don't want to
+ * return the znode
+ */
+static znode_t *
+zfs_znode_alloc(zfs_sb_t *zsb, dmu_buf_t *db, int blksz,
+    dmu_object_type_t obj_type, uint64_t obj, sa_handle_t *hdl,
+    struct inode *dip)
+{
+	znode_t	*zp;
+	struct inode *ip;
+	uint64_t mode;
+	uint64_t parent;
+	sa_bulk_attr_t bulk[9];
+	int count = 0;
+
+	ASSERT(zsb != NULL);
+
+	ip = new_inode(zsb->z_sb);
+	if (ip == NULL)
+		return (NULL);
+
+	zp = ITOZ(ip);
+	ASSERT(zp->z_dirlocks == NULL);
+	ASSERT3P(zp->z_acl_cached, ==, NULL);
+	ASSERT3P(zp->z_xattr_cached, ==, NULL);
+	ASSERT3P(zp->z_xattr_parent, ==, NULL);
+	zp->z_moved = 0;
+	zp->z_sa_hdl = NULL;
+	zp->z_unlinked = 0;
+	zp->z_atime_dirty = 0;
+	zp->z_mapcnt = 0;
+	zp->z_id = db->db_object;
+	zp->z_blksz = blksz;
+	zp->z_seq = 0x7A4653;
+	zp->z_sync_cnt = 0;
+	zp->z_is_zvol = B_FALSE;
+	zp->z_is_mapped = B_FALSE;
+	zp->z_is_ctldir = B_FALSE;
+	zp->z_is_stale = B_FALSE;
+
+	zfs_znode_sa_init(zsb, zp, db, obj_type, hdl);
+
+	SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_MODE(zsb), NULL, &mode, 8);
+	SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_GEN(zsb), NULL, &zp->z_gen, 8);
+	SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_SIZE(zsb), NULL, &zp->z_size, 8);
+	SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_LINKS(zsb), NULL, &zp->z_links, 8);
+	SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_FLAGS(zsb), NULL,
+	    &zp->z_pflags, 8);
+	SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_PARENT(zsb), NULL,
+	    &parent, 8);
+	SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_ATIME(zsb), NULL,
+	    &zp->z_atime, 16);
+	SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_UID(zsb), NULL, &zp->z_uid, 8);
+	SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_GID(zsb), NULL, &zp->z_gid, 8);
+
+	if (sa_bulk_lookup(zp->z_sa_hdl, bulk, count) != 0 || zp->z_gen == 0) {
+		if (hdl == NULL)
+			sa_handle_destroy(zp->z_sa_hdl);
+		zp->z_sa_hdl = NULL;
+		goto error;
+	}
+
+	zp->z_mode = mode;
+
+	/*
+	 * xattr znodes hold a reference on their unique parent
+	 */
+	if (dip && zp->z_pflags & ZFS_XATTR) {
+		igrab(dip);
+		zp->z_xattr_parent = ITOZ(dip);
+	}
+
+	ip->i_ino = obj;
+	zfs_inode_update(zp);
+	zfs_inode_set_ops(zsb, ip);
+
+	/*
+	 * The only way insert_inode_locked() can fail is if the ip->i_ino
+	 * number is already hashed for this super block.  This can never
+	 * happen because the inode numbers map 1:1 with the object numbers.
+	 *
+	 * The one exception is rolling back a mounted file system, but in
+	 * this case all the active inode are unhashed during the rollback.
+	 */
+	VERIFY3S(insert_inode_locked(ip), ==, 0);
+
+	mutex_enter(&zsb->z_znodes_lock);
+	list_insert_tail(&zsb->z_all_znodes, zp);
+	zsb->z_nr_znodes++;
+	membar_producer();
+	mutex_exit(&zsb->z_znodes_lock);
+
+	unlock_new_inode(ip);
+	return (zp);
+
+error:
+	iput(ip);
+	return (NULL);
+}
+
+void
+zfs_set_inode_flags(znode_t *zp, struct inode *ip)
+{
+	/*
+	 * Linux and Solaris have different sets of file attributes, so we
+	 * restrict this conversion to the intersection of the two.
+	 */
+
+	if (zp->z_pflags & ZFS_IMMUTABLE)
+		ip->i_flags |= S_IMMUTABLE;
+	else
+		ip->i_flags &= ~S_IMMUTABLE;
+
+	if (zp->z_pflags & ZFS_APPENDONLY)
+		ip->i_flags |= S_APPEND;
+	else
+		ip->i_flags &= ~S_APPEND;
+}
+
+/*
+ * Update the embedded inode given the znode.  We should work toward
+ * eliminating this function as soon as possible by removing values
+ * which are duplicated between the znode and inode.  If the generic
+ * inode has the correct field it should be used, and the ZFS code
+ * updated to access the inode.  This can be done incrementally.
+ */
+void
+zfs_inode_update(znode_t *zp)
+{
+	zfs_sb_t	*zsb;
+	struct inode	*ip;
+	uint32_t	blksize;
+	uint64_t	atime[2], mtime[2], ctime[2];
+
+	ASSERT(zp != NULL);
+	zsb = ZTOZSB(zp);
+	ip = ZTOI(zp);
+
+	/* Skip .zfs control nodes which do not exist on disk. */
+	if (zfsctl_is_node(ip))
+		return;
+
+	sa_lookup(zp->z_sa_hdl, SA_ZPL_ATIME(zsb), &atime, 16);
+	sa_lookup(zp->z_sa_hdl, SA_ZPL_MTIME(zsb), &mtime, 16);
+	sa_lookup(zp->z_sa_hdl, SA_ZPL_CTIME(zsb), &ctime, 16);
+
+	spin_lock(&ip->i_lock);
+	ip->i_generation = zp->z_gen;
+	ip->i_uid = SUID_TO_KUID(zp->z_uid);
+	ip->i_gid = SGID_TO_KGID(zp->z_gid);
+	set_nlink(ip, zp->z_links);
+	ip->i_mode = zp->z_mode;
+	zfs_set_inode_flags(zp, ip);
+	ip->i_blkbits = SPA_MINBLOCKSHIFT;
+	dmu_object_size_from_db(sa_get_db(zp->z_sa_hdl), &blksize,
+	    (u_longlong_t *)&ip->i_blocks);
+
+	ZFS_TIME_DECODE(&ip->i_atime, atime);
+	ZFS_TIME_DECODE(&ip->i_mtime, mtime);
+	ZFS_TIME_DECODE(&ip->i_ctime, ctime);
+
+	i_size_write(ip, zp->z_size);
+	spin_unlock(&ip->i_lock);
+}
+
+/*
+ * Safely mark an inode dirty.  Inodes which are part of a read-only
+ * file system or snapshot may not be dirtied.
+ */
+void
+zfs_mark_inode_dirty(struct inode *ip)
+{
+	zfs_sb_t *zsb = ITOZSB(ip);
+
+	if (zfs_is_readonly(zsb) || dmu_objset_is_snapshot(zsb->z_os))
+		return;
+
+	mark_inode_dirty(ip);
+}
+
+static uint64_t empty_xattr;
+static uint64_t pad[4];
+static zfs_acl_phys_t acl_phys;
+/*
+ * Create a new DMU object to hold a zfs znode.
+ *
+ *	IN:	dzp	- parent directory for new znode
+ *		vap	- file attributes for new znode
+ *		tx	- dmu transaction id for zap operations
+ *		cr	- credentials of caller
+ *		flag	- flags:
+ *			  IS_ROOT_NODE	- new object will be root
+ *			  IS_XATTR	- new object is an attribute
+ *		bonuslen - length of bonus buffer
+ *		setaclp  - File/Dir initial ACL
+ *		fuidp	 - Tracks fuid allocation.
+ *
+ *	OUT:	zpp	- allocated znode
+ *
+ */
+void
+zfs_mknode(znode_t *dzp, vattr_t *vap, dmu_tx_t *tx, cred_t *cr,
+    uint_t flag, znode_t **zpp, zfs_acl_ids_t *acl_ids)
+{
+	uint64_t	crtime[2], atime[2], mtime[2], ctime[2];
+	uint64_t	mode, size, links, parent, pflags;
+	uint64_t	dzp_pflags = 0;
+	uint64_t	rdev = 0;
+	zfs_sb_t	*zsb = ZTOZSB(dzp);
+	dmu_buf_t	*db;
+	timestruc_t	now;
+	uint64_t	gen, obj;
+	int		bonuslen;
+	sa_handle_t	*sa_hdl;
+	dmu_object_type_t obj_type;
+	sa_bulk_attr_t	*sa_attrs;
+	int		cnt = 0;
+	zfs_acl_locator_cb_t locate = { 0 };
+	znode_hold_t	*zh;
+
+	if (zsb->z_replay) {
+		obj = vap->va_nodeid;
+		now = vap->va_ctime;		/* see zfs_replay_create() */
+		gen = vap->va_nblocks;		/* ditto */
+	} else {
+		obj = 0;
+		gethrestime(&now);
+		gen = dmu_tx_get_txg(tx);
+	}
+
+	obj_type = zsb->z_use_sa ? DMU_OT_SA : DMU_OT_ZNODE;
+	bonuslen = (obj_type == DMU_OT_SA) ?
+	    DN_MAX_BONUSLEN : ZFS_OLD_ZNODE_PHYS_SIZE;
+
+	/*
+	 * Create a new DMU object.
+	 */
+	/*
+	 * There's currently no mechanism for pre-reading the blocks that will
+	 * be needed to allocate a new object, so we accept the small chance
+	 * that there will be an i/o error and we will fail one of the
+	 * assertions below.
+	 */
+	if (S_ISDIR(vap->va_mode)) {
+		if (zsb->z_replay) {
+			VERIFY0(zap_create_claim_norm(zsb->z_os, obj,
+			    zsb->z_norm, DMU_OT_DIRECTORY_CONTENTS,
+			    obj_type, bonuslen, tx));
+		} else {
+			obj = zap_create_norm(zsb->z_os,
+			    zsb->z_norm, DMU_OT_DIRECTORY_CONTENTS,
+			    obj_type, bonuslen, tx);
+		}
+	} else {
+		if (zsb->z_replay) {
+			VERIFY0(dmu_object_claim(zsb->z_os, obj,
+			    DMU_OT_PLAIN_FILE_CONTENTS, 0,
+			    obj_type, bonuslen, tx));
+		} else {
+			obj = dmu_object_alloc(zsb->z_os,
+			    DMU_OT_PLAIN_FILE_CONTENTS, 0,
+			    obj_type, bonuslen, tx);
+		}
+	}
+
+	zh = zfs_znode_hold_enter(zsb, obj);
+	VERIFY(0 == sa_buf_hold(zsb->z_os, obj, NULL, &db));
+
+	/*
+	 * If this is the root, fix up the half-initialized parent pointer
+	 * to reference the just-allocated physical data area.
+	 */
+	if (flag & IS_ROOT_NODE) {
+		dzp->z_id = obj;
+	} else {
+		dzp_pflags = dzp->z_pflags;
+	}
+
+	/*
+	 * If parent is an xattr, so am I.
+	 */
+	if (dzp_pflags & ZFS_XATTR) {
+		flag |= IS_XATTR;
+	}
+
+	if (zsb->z_use_fuids)
+		pflags = ZFS_ARCHIVE | ZFS_AV_MODIFIED;
+	else
+		pflags = 0;
+
+	if (S_ISDIR(vap->va_mode)) {
+		size = 2;		/* contents ("." and "..") */
+		links = (flag & (IS_ROOT_NODE | IS_XATTR)) ? 2 : 1;
+	} else {
+		size = links = 0;
+	}
+
+	if (S_ISBLK(vap->va_mode) || S_ISCHR(vap->va_mode))
+		rdev = vap->va_rdev;
+
+	parent = dzp->z_id;
+	mode = acl_ids->z_mode;
+	if (flag & IS_XATTR)
+		pflags |= ZFS_XATTR;
+
+	/*
+	 * No execs denied will be deterimed when zfs_mode_compute() is called.
+	 */
+	pflags |= acl_ids->z_aclp->z_hints &
+	    (ZFS_ACL_TRIVIAL|ZFS_INHERIT_ACE|ZFS_ACL_AUTO_INHERIT|
+	    ZFS_ACL_DEFAULTED|ZFS_ACL_PROTECTED);
+
+	ZFS_TIME_ENCODE(&now, crtime);
+	ZFS_TIME_ENCODE(&now, ctime);
+
+	if (vap->va_mask & ATTR_ATIME) {
+		ZFS_TIME_ENCODE(&vap->va_atime, atime);
+	} else {
+		ZFS_TIME_ENCODE(&now, atime);
+	}
+
+	if (vap->va_mask & ATTR_MTIME) {
+		ZFS_TIME_ENCODE(&vap->va_mtime, mtime);
+	} else {
+		ZFS_TIME_ENCODE(&now, mtime);
+	}
+
+	/* Now add in all of the "SA" attributes */
+	VERIFY(0 == sa_handle_get_from_db(zsb->z_os, db, NULL, SA_HDL_SHARED,
+	    &sa_hdl));
+
+	/*
+	 * Setup the array of attributes to be replaced/set on the new file
+	 *
+	 * order for  DMU_OT_ZNODE is critical since it needs to be constructed
+	 * in the old znode_phys_t format.  Don't change this ordering
+	 */
+	sa_attrs = kmem_alloc(sizeof (sa_bulk_attr_t) * ZPL_END, KM_SLEEP);
+
+	if (obj_type == DMU_OT_ZNODE) {
+		SA_ADD_BULK_ATTR(sa_attrs, cnt, SA_ZPL_ATIME(zsb),
+		    NULL, &atime, 16);
+		SA_ADD_BULK_ATTR(sa_attrs, cnt, SA_ZPL_MTIME(zsb),
+		    NULL, &mtime, 16);
+		SA_ADD_BULK_ATTR(sa_attrs, cnt, SA_ZPL_CTIME(zsb),
+		    NULL, &ctime, 16);
+		SA_ADD_BULK_ATTR(sa_attrs, cnt, SA_ZPL_CRTIME(zsb),
+		    NULL, &crtime, 16);
+		SA_ADD_BULK_ATTR(sa_attrs, cnt, SA_ZPL_GEN(zsb),
+		    NULL, &gen, 8);
+		SA_ADD_BULK_ATTR(sa_attrs, cnt, SA_ZPL_MODE(zsb),
+		    NULL, &mode, 8);
+		SA_ADD_BULK_ATTR(sa_attrs, cnt, SA_ZPL_SIZE(zsb),
+		    NULL, &size, 8);
+		SA_ADD_BULK_ATTR(sa_attrs, cnt, SA_ZPL_PARENT(zsb),
+		    NULL, &parent, 8);
+	} else {
+		SA_ADD_BULK_ATTR(sa_attrs, cnt, SA_ZPL_MODE(zsb),
+		    NULL, &mode, 8);
+		SA_ADD_BULK_ATTR(sa_attrs, cnt, SA_ZPL_SIZE(zsb),
+		    NULL, &size, 8);
+		SA_ADD_BULK_ATTR(sa_attrs, cnt, SA_ZPL_GEN(zsb),
+		    NULL, &gen, 8);
+		SA_ADD_BULK_ATTR(sa_attrs, cnt, SA_ZPL_UID(zsb),
+		    NULL, &acl_ids->z_fuid, 8);
+		SA_ADD_BULK_ATTR(sa_attrs, cnt, SA_ZPL_GID(zsb),
+		    NULL, &acl_ids->z_fgid, 8);
+		SA_ADD_BULK_ATTR(sa_attrs, cnt, SA_ZPL_PARENT(zsb),
+		    NULL, &parent, 8);
+		SA_ADD_BULK_ATTR(sa_attrs, cnt, SA_ZPL_FLAGS(zsb),
+		    NULL, &pflags, 8);
+		SA_ADD_BULK_ATTR(sa_attrs, cnt, SA_ZPL_ATIME(zsb),
+		    NULL, &atime, 16);
+		SA_ADD_BULK_ATTR(sa_attrs, cnt, SA_ZPL_MTIME(zsb),
+		    NULL, &mtime, 16);
+		SA_ADD_BULK_ATTR(sa_attrs, cnt, SA_ZPL_CTIME(zsb),
+		    NULL, &ctime, 16);
+		SA_ADD_BULK_ATTR(sa_attrs, cnt, SA_ZPL_CRTIME(zsb),
+		    NULL, &crtime, 16);
+	}
+
+	SA_ADD_BULK_ATTR(sa_attrs, cnt, SA_ZPL_LINKS(zsb), NULL, &links, 8);
+
+	if (obj_type == DMU_OT_ZNODE) {
+		SA_ADD_BULK_ATTR(sa_attrs, cnt, SA_ZPL_XATTR(zsb), NULL,
+		    &empty_xattr, 8);
+	}
+	if (obj_type == DMU_OT_ZNODE ||
+	    (S_ISBLK(vap->va_mode) || S_ISCHR(vap->va_mode))) {
+		SA_ADD_BULK_ATTR(sa_attrs, cnt, SA_ZPL_RDEV(zsb),
+		    NULL, &rdev, 8);
+	}
+	if (obj_type == DMU_OT_ZNODE) {
+		SA_ADD_BULK_ATTR(sa_attrs, cnt, SA_ZPL_FLAGS(zsb),
+		    NULL, &pflags, 8);
+		SA_ADD_BULK_ATTR(sa_attrs, cnt, SA_ZPL_UID(zsb), NULL,
+		    &acl_ids->z_fuid, 8);
+		SA_ADD_BULK_ATTR(sa_attrs, cnt, SA_ZPL_GID(zsb), NULL,
+		    &acl_ids->z_fgid, 8);
+		SA_ADD_BULK_ATTR(sa_attrs, cnt, SA_ZPL_PAD(zsb), NULL, pad,
+		    sizeof (uint64_t) * 4);
+		SA_ADD_BULK_ATTR(sa_attrs, cnt, SA_ZPL_ZNODE_ACL(zsb), NULL,
+		    &acl_phys, sizeof (zfs_acl_phys_t));
+	} else if (acl_ids->z_aclp->z_version >= ZFS_ACL_VERSION_FUID) {
+		SA_ADD_BULK_ATTR(sa_attrs, cnt, SA_ZPL_DACL_COUNT(zsb), NULL,
+		    &acl_ids->z_aclp->z_acl_count, 8);
+		locate.cb_aclp = acl_ids->z_aclp;
+		SA_ADD_BULK_ATTR(sa_attrs, cnt, SA_ZPL_DACL_ACES(zsb),
+		    zfs_acl_data_locator, &locate,
+		    acl_ids->z_aclp->z_acl_bytes);
+		mode = zfs_mode_compute(mode, acl_ids->z_aclp, &pflags,
+		    acl_ids->z_fuid, acl_ids->z_fgid);
+	}
+
+	VERIFY(sa_replace_all_by_template(sa_hdl, sa_attrs, cnt, tx) == 0);
+
+	if (!(flag & IS_ROOT_NODE)) {
+		*zpp = zfs_znode_alloc(zsb, db, 0, obj_type, obj, sa_hdl,
+		    ZTOI(dzp));
+		VERIFY(*zpp != NULL);
+		VERIFY(dzp != NULL);
+	} else {
+		/*
+		 * If we are creating the root node, the "parent" we
+		 * passed in is the znode for the root.
+		 */
+		*zpp = dzp;
+
+		(*zpp)->z_sa_hdl = sa_hdl;
+	}
+
+	(*zpp)->z_pflags = pflags;
+	(*zpp)->z_mode = mode;
+
+	if (obj_type == DMU_OT_ZNODE ||
+	    acl_ids->z_aclp->z_version < ZFS_ACL_VERSION_FUID) {
+		VERIFY0(zfs_aclset_common(*zpp, acl_ids->z_aclp, cr, tx));
+	}
+	kmem_free(sa_attrs, sizeof (sa_bulk_attr_t) * ZPL_END);
+	zfs_znode_hold_exit(zsb, zh);
+}
+
+/*
+ * Update in-core attributes.  It is assumed the caller will be doing an
+ * sa_bulk_update to push the changes out.
+ */
+void
+zfs_xvattr_set(znode_t *zp, xvattr_t *xvap, dmu_tx_t *tx)
+{
+	xoptattr_t *xoap;
+
+	xoap = xva_getxoptattr(xvap);
+	ASSERT(xoap);
+
+	if (XVA_ISSET_REQ(xvap, XAT_CREATETIME)) {
+		uint64_t times[2];
+		ZFS_TIME_ENCODE(&xoap->xoa_createtime, times);
+		(void) sa_update(zp->z_sa_hdl, SA_ZPL_CRTIME(ZTOZSB(zp)),
+		    &times, sizeof (times), tx);
+		XVA_SET_RTN(xvap, XAT_CREATETIME);
+	}
+	if (XVA_ISSET_REQ(xvap, XAT_READONLY)) {
+		ZFS_ATTR_SET(zp, ZFS_READONLY, xoap->xoa_readonly,
+		    zp->z_pflags, tx);
+		XVA_SET_RTN(xvap, XAT_READONLY);
+	}
+	if (XVA_ISSET_REQ(xvap, XAT_HIDDEN)) {
+		ZFS_ATTR_SET(zp, ZFS_HIDDEN, xoap->xoa_hidden,
+		    zp->z_pflags, tx);
+		XVA_SET_RTN(xvap, XAT_HIDDEN);
+	}
+	if (XVA_ISSET_REQ(xvap, XAT_SYSTEM)) {
+		ZFS_ATTR_SET(zp, ZFS_SYSTEM, xoap->xoa_system,
+		    zp->z_pflags, tx);
+		XVA_SET_RTN(xvap, XAT_SYSTEM);
+	}
+	if (XVA_ISSET_REQ(xvap, XAT_ARCHIVE)) {
+		ZFS_ATTR_SET(zp, ZFS_ARCHIVE, xoap->xoa_archive,
+		    zp->z_pflags, tx);
+		XVA_SET_RTN(xvap, XAT_ARCHIVE);
+	}
+	if (XVA_ISSET_REQ(xvap, XAT_IMMUTABLE)) {
+		ZFS_ATTR_SET(zp, ZFS_IMMUTABLE, xoap->xoa_immutable,
+		    zp->z_pflags, tx);
+		XVA_SET_RTN(xvap, XAT_IMMUTABLE);
+	}
+	if (XVA_ISSET_REQ(xvap, XAT_NOUNLINK)) {
+		ZFS_ATTR_SET(zp, ZFS_NOUNLINK, xoap->xoa_nounlink,
+		    zp->z_pflags, tx);
+		XVA_SET_RTN(xvap, XAT_NOUNLINK);
+	}
+	if (XVA_ISSET_REQ(xvap, XAT_APPENDONLY)) {
+		ZFS_ATTR_SET(zp, ZFS_APPENDONLY, xoap->xoa_appendonly,
+		    zp->z_pflags, tx);
+		XVA_SET_RTN(xvap, XAT_APPENDONLY);
+	}
+	if (XVA_ISSET_REQ(xvap, XAT_NODUMP)) {
+		ZFS_ATTR_SET(zp, ZFS_NODUMP, xoap->xoa_nodump,
+		    zp->z_pflags, tx);
+		XVA_SET_RTN(xvap, XAT_NODUMP);
+	}
+	if (XVA_ISSET_REQ(xvap, XAT_OPAQUE)) {
+		ZFS_ATTR_SET(zp, ZFS_OPAQUE, xoap->xoa_opaque,
+		    zp->z_pflags, tx);
+		XVA_SET_RTN(xvap, XAT_OPAQUE);
+	}
+	if (XVA_ISSET_REQ(xvap, XAT_AV_QUARANTINED)) {
+		ZFS_ATTR_SET(zp, ZFS_AV_QUARANTINED,
+		    xoap->xoa_av_quarantined, zp->z_pflags, tx);
+		XVA_SET_RTN(xvap, XAT_AV_QUARANTINED);
+	}
+	if (XVA_ISSET_REQ(xvap, XAT_AV_MODIFIED)) {
+		ZFS_ATTR_SET(zp, ZFS_AV_MODIFIED, xoap->xoa_av_modified,
+		    zp->z_pflags, tx);
+		XVA_SET_RTN(xvap, XAT_AV_MODIFIED);
+	}
+	if (XVA_ISSET_REQ(xvap, XAT_AV_SCANSTAMP)) {
+		zfs_sa_set_scanstamp(zp, xvap, tx);
+		XVA_SET_RTN(xvap, XAT_AV_SCANSTAMP);
+	}
+	if (XVA_ISSET_REQ(xvap, XAT_REPARSE)) {
+		ZFS_ATTR_SET(zp, ZFS_REPARSE, xoap->xoa_reparse,
+		    zp->z_pflags, tx);
+		XVA_SET_RTN(xvap, XAT_REPARSE);
+	}
+	if (XVA_ISSET_REQ(xvap, XAT_OFFLINE)) {
+		ZFS_ATTR_SET(zp, ZFS_OFFLINE, xoap->xoa_offline,
+		    zp->z_pflags, tx);
+		XVA_SET_RTN(xvap, XAT_OFFLINE);
+	}
+	if (XVA_ISSET_REQ(xvap, XAT_SPARSE)) {
+		ZFS_ATTR_SET(zp, ZFS_SPARSE, xoap->xoa_sparse,
+		    zp->z_pflags, tx);
+		XVA_SET_RTN(xvap, XAT_SPARSE);
+	}
+}
+
+int
+zfs_zget(zfs_sb_t *zsb, uint64_t obj_num, znode_t **zpp)
+{
+	dmu_object_info_t doi;
+	dmu_buf_t	*db;
+	znode_t		*zp;
+	znode_hold_t	*zh;
+	int err;
+	sa_handle_t	*hdl;
+
+	*zpp = NULL;
+
+again:
+	zh = zfs_znode_hold_enter(zsb, obj_num);
+
+	err = sa_buf_hold(zsb->z_os, obj_num, NULL, &db);
+	if (err) {
+		zfs_znode_hold_exit(zsb, zh);
+		return (err);
+	}
+
+	dmu_object_info_from_db(db, &doi);
+	if (doi.doi_bonus_type != DMU_OT_SA &&
+	    (doi.doi_bonus_type != DMU_OT_ZNODE ||
+	    (doi.doi_bonus_type == DMU_OT_ZNODE &&
+	    doi.doi_bonus_size < sizeof (znode_phys_t)))) {
+		sa_buf_rele(db, NULL);
+		zfs_znode_hold_exit(zsb, zh);
+		return (SET_ERROR(EINVAL));
+	}
+
+	hdl = dmu_buf_get_user(db);
+	if (hdl != NULL) {
+		zp = sa_get_userdata(hdl);
+
+
+		/*
+		 * Since "SA" does immediate eviction we
+		 * should never find a sa handle that doesn't
+		 * know about the znode.
+		 */
+
+		ASSERT3P(zp, !=, NULL);
+
+		mutex_enter(&zp->z_lock);
+		ASSERT3U(zp->z_id, ==, obj_num);
+		if (zp->z_unlinked) {
+			err = SET_ERROR(ENOENT);
+		} else {
+			/*
+			 * If igrab() returns NULL the VFS has independently
+			 * determined the inode should be evicted and has
+			 * called iput_final() to start the eviction process.
+			 * The SA handle is still valid but because the VFS
+			 * requires that the eviction succeed we must drop
+			 * our locks and references to allow the eviction to
+			 * complete.  The zfs_zget() may then be retried.
+			 *
+			 * This unlikely case could be optimized by registering
+			 * a sops->drop_inode() callback.  The callback would
+			 * need to detect the active SA hold thereby informing
+			 * the VFS that this inode should not be evicted.
+			 */
+			if (igrab(ZTOI(zp)) == NULL) {
+				mutex_exit(&zp->z_lock);
+				sa_buf_rele(db, NULL);
+				zfs_znode_hold_exit(zsb, zh);
+				/* inode might need this to finish evict */
+				cond_resched();
+				goto again;
+			}
+			*zpp = zp;
+			err = 0;
+		}
+		mutex_exit(&zp->z_lock);
+		sa_buf_rele(db, NULL);
+		zfs_znode_hold_exit(zsb, zh);
+		return (err);
+	}
+
+	/*
+	 * Not found create new znode/vnode but only if file exists.
+	 *
+	 * There is a small window where zfs_vget() could
+	 * find this object while a file create is still in
+	 * progress.  This is checked for in zfs_znode_alloc()
+	 *
+	 * if zfs_znode_alloc() fails it will drop the hold on the
+	 * bonus buffer.
+	 */
+	zp = zfs_znode_alloc(zsb, db, doi.doi_data_block_size,
+	    doi.doi_bonus_type, obj_num, NULL, NULL);
+	if (zp == NULL) {
+		err = SET_ERROR(ENOENT);
+	} else {
+		*zpp = zp;
+	}
+	zfs_znode_hold_exit(zsb, zh);
+	return (err);
+}
+
+int
+zfs_rezget(znode_t *zp)
+{
+	zfs_sb_t *zsb = ZTOZSB(zp);
+	dmu_object_info_t doi;
+	dmu_buf_t *db;
+	uint64_t obj_num = zp->z_id;
+	uint64_t mode;
+	sa_bulk_attr_t bulk[8];
+	int err;
+	int count = 0;
+	uint64_t gen;
+	znode_hold_t *zh;
+
+	zh = zfs_znode_hold_enter(zsb, obj_num);
+
+	mutex_enter(&zp->z_acl_lock);
+	if (zp->z_acl_cached) {
+		zfs_acl_free(zp->z_acl_cached);
+		zp->z_acl_cached = NULL;
+	}
+	mutex_exit(&zp->z_acl_lock);
+
+	rw_enter(&zp->z_xattr_lock, RW_WRITER);
+	if (zp->z_xattr_cached) {
+		nvlist_free(zp->z_xattr_cached);
+		zp->z_xattr_cached = NULL;
+	}
+
+	if (zp->z_xattr_parent) {
+		zfs_iput_async(ZTOI(zp->z_xattr_parent));
+		zp->z_xattr_parent = NULL;
+	}
+	rw_exit(&zp->z_xattr_lock);
+
+	ASSERT(zp->z_sa_hdl == NULL);
+	err = sa_buf_hold(zsb->z_os, obj_num, NULL, &db);
+	if (err) {
+		zfs_znode_hold_exit(zsb, zh);
+		return (err);
+	}
+
+	dmu_object_info_from_db(db, &doi);
+	if (doi.doi_bonus_type != DMU_OT_SA &&
+	    (doi.doi_bonus_type != DMU_OT_ZNODE ||
+	    (doi.doi_bonus_type == DMU_OT_ZNODE &&
+	    doi.doi_bonus_size < sizeof (znode_phys_t)))) {
+		sa_buf_rele(db, NULL);
+		zfs_znode_hold_exit(zsb, zh);
+		return (SET_ERROR(EINVAL));
+	}
+
+	zfs_znode_sa_init(zsb, zp, db, doi.doi_bonus_type, NULL);
+
+	/* reload cached values */
+	SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_GEN(zsb), NULL,
+	    &gen, sizeof (gen));
+	SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_SIZE(zsb), NULL,
+	    &zp->z_size, sizeof (zp->z_size));
+	SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_LINKS(zsb), NULL,
+	    &zp->z_links, sizeof (zp->z_links));
+	SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_FLAGS(zsb), NULL,
+	    &zp->z_pflags, sizeof (zp->z_pflags));
+	SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_ATIME(zsb), NULL,
+	    &zp->z_atime, sizeof (zp->z_atime));
+	SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_UID(zsb), NULL,
+	    &zp->z_uid, sizeof (zp->z_uid));
+	SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_GID(zsb), NULL,
+	    &zp->z_gid, sizeof (zp->z_gid));
+	SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_MODE(zsb), NULL,
+	    &mode, sizeof (mode));
+
+	if (sa_bulk_lookup(zp->z_sa_hdl, bulk, count)) {
+		zfs_znode_dmu_fini(zp);
+		zfs_znode_hold_exit(zsb, zh);
+		return (SET_ERROR(EIO));
+	}
+
+	zp->z_mode = mode;
+
+	if (gen != zp->z_gen) {
+		zfs_znode_dmu_fini(zp);
+		zfs_znode_hold_exit(zsb, zh);
+		return (SET_ERROR(EIO));
+	}
+
+	zp->z_unlinked = (zp->z_links == 0);
+	zp->z_blksz = doi.doi_data_block_size;
+	zfs_inode_update(zp);
+
+	zfs_znode_hold_exit(zsb, zh);
+
+	return (0);
+}
+
+void
+zfs_znode_delete(znode_t *zp, dmu_tx_t *tx)
+{
+	zfs_sb_t *zsb = ZTOZSB(zp);
+	objset_t *os = zsb->z_os;
+	uint64_t obj = zp->z_id;
+	uint64_t acl_obj = zfs_external_acl(zp);
+	znode_hold_t *zh;
+
+	zh = zfs_znode_hold_enter(zsb, obj);
+	if (acl_obj) {
+		VERIFY(!zp->z_is_sa);
+		VERIFY(0 == dmu_object_free(os, acl_obj, tx));
+	}
+	VERIFY(0 == dmu_object_free(os, obj, tx));
+	zfs_znode_dmu_fini(zp);
+	zfs_znode_hold_exit(zsb, zh);
+}
+
+void
+zfs_zinactive(znode_t *zp)
+{
+	zfs_sb_t *zsb = ZTOZSB(zp);
+	uint64_t z_id = zp->z_id;
+	znode_hold_t *zh;
+
+	ASSERT(zp->z_sa_hdl);
+
+	/*
+	 * Don't allow a zfs_zget() while were trying to release this znode.
+	 */
+	zh = zfs_znode_hold_enter(zsb, z_id);
+
+	mutex_enter(&zp->z_lock);
+
+	/*
+	 * If this was the last reference to a file with no links,
+	 * remove the file from the file system.
+	 */
+	if (zp->z_unlinked) {
+		mutex_exit(&zp->z_lock);
+		zfs_znode_hold_exit(zsb, zh);
+		zfs_rmnode(zp);
+		return;
+	}
+
+	mutex_exit(&zp->z_lock);
+	zfs_znode_dmu_fini(zp);
+
+	zfs_znode_hold_exit(zsb, zh);
+}
+
+static inline int
+zfs_compare_timespec(struct timespec *t1, struct timespec *t2)
+{
+	if (t1->tv_sec < t2->tv_sec)
+		return (-1);
+
+	if (t1->tv_sec > t2->tv_sec)
+		return (1);
+
+	return (t1->tv_nsec - t2->tv_nsec);
+}
+
+/*
+ *  Determine whether the znode's atime must be updated.  The logic mostly
+ *  duplicates the Linux kernel's relatime_need_update() functionality.
+ *  This function is only called if the underlying filesystem actually has
+ *  atime updates enabled.
+ */
+static inline boolean_t
+zfs_atime_need_update(znode_t *zp, timestruc_t *now)
+{
+	if (!ZTOZSB(zp)->z_relatime)
+		return (B_TRUE);
+
+	/*
+	 * In relatime mode, only update the atime if the previous atime
+	 * is earlier than either the ctime or mtime or if at least a day
+	 * has passed since the last update of atime.
+	 */
+	if (zfs_compare_timespec(&ZTOI(zp)->i_mtime, &ZTOI(zp)->i_atime) >= 0)
+		return (B_TRUE);
+
+	if (zfs_compare_timespec(&ZTOI(zp)->i_ctime, &ZTOI(zp)->i_atime) >= 0)
+		return (B_TRUE);
+
+	if ((long)now->tv_sec - ZTOI(zp)->i_atime.tv_sec >= 24*60*60)
+		return (B_TRUE);
+
+	return (B_FALSE);
+}
+
+/*
+ * Prepare to update znode time stamps.
+ *
+ *	IN:	zp	- znode requiring timestamp update
+ *		flag	- ATTR_MTIME, ATTR_CTIME, ATTR_ATIME flags
+ *		have_tx	- true of caller is creating a new txg
+ *
+ *	OUT:	zp	- new atime (via underlying inode's i_atime)
+ *		mtime	- new mtime
+ *		ctime	- new ctime
+ *
+ * NOTE: The arguments are somewhat redundant.  The following condition
+ * is always true:
+ *
+ *		have_tx == !(flag & ATTR_ATIME)
+ */
+void
+zfs_tstamp_update_setup(znode_t *zp, uint_t flag, uint64_t mtime[2],
+    uint64_t ctime[2], boolean_t have_tx)
+{
+	timestruc_t	now;
+
+	ASSERT(have_tx == !(flag & ATTR_ATIME));
+	gethrestime(&now);
+
+	/*
+	 * NOTE: The following test intentionally does not update z_atime_dirty
+	 * in the case where an ATIME update has been requested but for which
+	 * the update is omitted due to relatime logic.  The rationale being
+	 * that if the flag was set somewhere else, we should leave it alone
+	 * here.
+	 */
+	if (flag & ATTR_ATIME) {
+		if (zfs_atime_need_update(zp, &now)) {
+			ZFS_TIME_ENCODE(&now, zp->z_atime);
+			ZTOI(zp)->i_atime.tv_sec = zp->z_atime[0];
+			ZTOI(zp)->i_atime.tv_nsec = zp->z_atime[1];
+			zp->z_atime_dirty = 1;
+		}
+	} else {
+		zp->z_atime_dirty = 0;
+		zp->z_seq++;
+	}
+
+	if (flag & ATTR_MTIME) {
+		ZFS_TIME_ENCODE(&now, mtime);
+		if (ZTOZSB(zp)->z_use_fuids) {
+			zp->z_pflags |= (ZFS_ARCHIVE |
+			    ZFS_AV_MODIFIED);
+		}
+	}
+
+	if (flag & ATTR_CTIME) {
+		ZFS_TIME_ENCODE(&now, ctime);
+		if (ZTOZSB(zp)->z_use_fuids)
+			zp->z_pflags |= ZFS_ARCHIVE;
+	}
+}
+
+/*
+ * Grow the block size for a file.
+ *
+ *	IN:	zp	- znode of file to free data in.
+ *		size	- requested block size
+ *		tx	- open transaction.
+ *
+ * NOTE: this function assumes that the znode is write locked.
+ */
+void
+zfs_grow_blocksize(znode_t *zp, uint64_t size, dmu_tx_t *tx)
+{
+	int		error;
+	u_longlong_t	dummy;
+
+	if (size <= zp->z_blksz)
+		return;
+	/*
+	 * If the file size is already greater than the current blocksize,
+	 * we will not grow.  If there is more than one block in a file,
+	 * the blocksize cannot change.
+	 */
+	if (zp->z_blksz && zp->z_size > zp->z_blksz)
+		return;
+
+	error = dmu_object_set_blocksize(ZTOZSB(zp)->z_os, zp->z_id,
+	    size, 0, tx);
+
+	if (error == ENOTSUP)
+		return;
+	ASSERT0(error);
+
+	/* What blocksize did we actually get? */
+	dmu_object_size_from_db(sa_get_db(zp->z_sa_hdl), &zp->z_blksz, &dummy);
+}
+
+/*
+ * Increase the file length
+ *
+ *	IN:	zp	- znode of file to free data in.
+ *		end	- new end-of-file
+ *
+ * 	RETURN:	0 on success, error code on failure
+ */
+static int
+zfs_extend(znode_t *zp, uint64_t end)
+{
+	zfs_sb_t *zsb = ZTOZSB(zp);
+	dmu_tx_t *tx;
+	rl_t *rl;
+	uint64_t newblksz;
+	int error;
+
+	/*
+	 * We will change zp_size, lock the whole file.
+	 */
+	rl = zfs_range_lock(zp, 0, UINT64_MAX, RL_WRITER);
+
+	/*
+	 * Nothing to do if file already at desired length.
+	 */
+	if (end <= zp->z_size) {
+		zfs_range_unlock(rl);
+		return (0);
+	}
+	tx = dmu_tx_create(zsb->z_os);
+	dmu_tx_hold_sa(tx, zp->z_sa_hdl, B_FALSE);
+	zfs_sa_upgrade_txholds(tx, zp);
+	if (end > zp->z_blksz &&
+	    (!ISP2(zp->z_blksz) || zp->z_blksz < zsb->z_max_blksz)) {
+		/*
+		 * We are growing the file past the current block size.
+		 */
+		if (zp->z_blksz > ZTOZSB(zp)->z_max_blksz) {
+			/*
+			 * File's blocksize is already larger than the
+			 * "recordsize" property.  Only let it grow to
+			 * the next power of 2.
+			 */
+			ASSERT(!ISP2(zp->z_blksz));
+			newblksz = MIN(end, 1 << highbit64(zp->z_blksz));
+		} else {
+			newblksz = MIN(end, ZTOZSB(zp)->z_max_blksz);
+		}
+		dmu_tx_hold_write(tx, zp->z_id, 0, newblksz);
+	} else {
+		newblksz = 0;
+	}
+
+	error = dmu_tx_assign(tx, TXG_WAIT);
+	if (error) {
+		dmu_tx_abort(tx);
+		zfs_range_unlock(rl);
+		return (error);
+	}
+
+	if (newblksz)
+		zfs_grow_blocksize(zp, newblksz, tx);
+
+	zp->z_size = end;
+
+	VERIFY(0 == sa_update(zp->z_sa_hdl, SA_ZPL_SIZE(ZTOZSB(zp)),
+	    &zp->z_size, sizeof (zp->z_size), tx));
+
+	zfs_range_unlock(rl);
+
+	dmu_tx_commit(tx);
+
+	return (0);
+}
+
+/*
+ * zfs_zero_partial_page - Modeled after update_pages() but
+ * with different arguments and semantics for use by zfs_freesp().
+ *
+ * Zeroes a piece of a single page cache entry for zp at offset
+ * start and length len.
+ *
+ * Caller must acquire a range lock on the file for the region
+ * being zeroed in order that the ARC and page cache stay in sync.
+ */
+static void
+zfs_zero_partial_page(znode_t *zp, uint64_t start, uint64_t len)
+{
+	struct address_space *mp = ZTOI(zp)->i_mapping;
+	struct page *pp;
+	int64_t	off;
+	void *pb;
+
+	ASSERT((start & PAGE_CACHE_MASK) ==
+	    ((start + len - 1) & PAGE_CACHE_MASK));
+
+	off = start & (PAGE_CACHE_SIZE - 1);
+	start &= PAGE_CACHE_MASK;
+
+	pp = find_lock_page(mp, start >> PAGE_CACHE_SHIFT);
+	if (pp) {
+		if (mapping_writably_mapped(mp))
+			flush_dcache_page(pp);
+
+		pb = kmap(pp);
+		bzero(pb + off, len);
+		kunmap(pp);
+
+		if (mapping_writably_mapped(mp))
+			flush_dcache_page(pp);
+
+		mark_page_accessed(pp);
+		SetPageUptodate(pp);
+		ClearPageError(pp);
+		unlock_page(pp);
+		page_cache_release(pp);
+	}
+}
+
+/*
+ * Free space in a file.
+ *
+ *	IN:	zp	- znode of file to free data in.
+ *		off	- start of section to free.
+ *		len	- length of section to free.
+ *
+ * 	RETURN:	0 on success, error code on failure
+ */
+static int
+zfs_free_range(znode_t *zp, uint64_t off, uint64_t len)
+{
+	zfs_sb_t *zsb = ZTOZSB(zp);
+	rl_t *rl;
+	int error;
+
+	/*
+	 * Lock the range being freed.
+	 */
+	rl = zfs_range_lock(zp, off, len, RL_WRITER);
+
+	/*
+	 * Nothing to do if file already at desired length.
+	 */
+	if (off >= zp->z_size) {
+		zfs_range_unlock(rl);
+		return (0);
+	}
+
+	if (off + len > zp->z_size)
+		len = zp->z_size - off;
+
+	error = dmu_free_long_range(zsb->z_os, zp->z_id, off, len);
+
+	/*
+	 * Zero partial page cache entries.  This must be done under a
+	 * range lock in order to keep the ARC and page cache in sync.
+	 */
+	if (zp->z_is_mapped) {
+		loff_t first_page, last_page, page_len;
+		loff_t first_page_offset, last_page_offset;
+
+		/* first possible full page in hole */
+		first_page = (off + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
+		/* last page of hole */
+		last_page = (off + len) >> PAGE_CACHE_SHIFT;
+
+		/* offset of first_page */
+		first_page_offset = first_page << PAGE_CACHE_SHIFT;
+		/* offset of last_page */
+		last_page_offset = last_page << PAGE_CACHE_SHIFT;
+
+		/* truncate whole pages */
+		if (last_page_offset > first_page_offset) {
+			truncate_inode_pages_range(ZTOI(zp)->i_mapping,
+			    first_page_offset, last_page_offset - 1);
+		}
+
+		/* truncate sub-page ranges */
+		if (first_page > last_page) {
+			/* entire punched area within a single page */
+			zfs_zero_partial_page(zp, off, len);
+		} else {
+			/* beginning of punched area at the end of a page */
+			page_len  = first_page_offset - off;
+			if (page_len > 0)
+				zfs_zero_partial_page(zp, off, page_len);
+
+			/* end of punched area at the beginning of a page */
+			page_len = off + len - last_page_offset;
+			if (page_len > 0)
+				zfs_zero_partial_page(zp, last_page_offset,
+				    page_len);
+		}
+	}
+	zfs_range_unlock(rl);
+
+	return (error);
+}
+
+/*
+ * Truncate a file
+ *
+ *	IN:	zp	- znode of file to free data in.
+ *		end	- new end-of-file.
+ *
+ * 	RETURN:	0 on success, error code on failure
+ */
+static int
+zfs_trunc(znode_t *zp, uint64_t end)
+{
+	zfs_sb_t *zsb = ZTOZSB(zp);
+	dmu_tx_t *tx;
+	rl_t *rl;
+	int error;
+	sa_bulk_attr_t bulk[2];
+	int count = 0;
+
+	/*
+	 * We will change zp_size, lock the whole file.
+	 */
+	rl = zfs_range_lock(zp, 0, UINT64_MAX, RL_WRITER);
+
+	/*
+	 * Nothing to do if file already at desired length.
+	 */
+	if (end >= zp->z_size) {
+		zfs_range_unlock(rl);
+		return (0);
+	}
+
+	error = dmu_free_long_range(zsb->z_os, zp->z_id, end,  -1);
+	if (error) {
+		zfs_range_unlock(rl);
+		return (error);
+	}
+	tx = dmu_tx_create(zsb->z_os);
+	dmu_tx_hold_sa(tx, zp->z_sa_hdl, B_FALSE);
+	zfs_sa_upgrade_txholds(tx, zp);
+	error = dmu_tx_assign(tx, TXG_WAIT);
+	if (error) {
+		dmu_tx_abort(tx);
+		zfs_range_unlock(rl);
+		return (error);
+	}
+
+	zp->z_size = end;
+	SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_SIZE(zsb),
+	    NULL, &zp->z_size, sizeof (zp->z_size));
+
+	if (end == 0) {
+		zp->z_pflags &= ~ZFS_SPARSE;
+		SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_FLAGS(zsb),
+		    NULL, &zp->z_pflags, 8);
+	}
+	VERIFY(sa_bulk_update(zp->z_sa_hdl, bulk, count, tx) == 0);
+
+	dmu_tx_commit(tx);
+
+	zfs_range_unlock(rl);
+
+	return (0);
+}
+
+/*
+ * Free space in a file
+ *
+ *	IN:	zp	- znode of file to free data in.
+ *		off	- start of range
+ *		len	- end of range (0 => EOF)
+ *		flag	- current file open mode flags.
+ *		log	- TRUE if this action should be logged
+ *
+ * 	RETURN:	0 on success, error code on failure
+ */
+int
+zfs_freesp(znode_t *zp, uint64_t off, uint64_t len, int flag, boolean_t log)
+{
+	dmu_tx_t *tx;
+	zfs_sb_t *zsb = ZTOZSB(zp);
+	zilog_t *zilog = zsb->z_log;
+	uint64_t mode;
+	uint64_t mtime[2], ctime[2];
+	sa_bulk_attr_t bulk[3];
+	int count = 0;
+	int error;
+
+	if ((error = sa_lookup(zp->z_sa_hdl, SA_ZPL_MODE(zsb), &mode,
+	    sizeof (mode))) != 0)
+		return (error);
+
+	if (off > zp->z_size) {
+		error =  zfs_extend(zp, off+len);
+		if (error == 0 && log)
+			goto log;
+		goto out;
+	}
+
+	if (len == 0) {
+		error = zfs_trunc(zp, off);
+	} else {
+		if ((error = zfs_free_range(zp, off, len)) == 0 &&
+		    off + len > zp->z_size)
+			error = zfs_extend(zp, off+len);
+	}
+	if (error || !log)
+		goto out;
+log:
+	tx = dmu_tx_create(zsb->z_os);
+	dmu_tx_hold_sa(tx, zp->z_sa_hdl, B_FALSE);
+	zfs_sa_upgrade_txholds(tx, zp);
+	error = dmu_tx_assign(tx, TXG_WAIT);
+	if (error) {
+		dmu_tx_abort(tx);
+		goto out;
+	}
+
+	SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_MTIME(zsb), NULL, mtime, 16);
+	SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_CTIME(zsb), NULL, ctime, 16);
+	SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_FLAGS(zsb),
+	    NULL, &zp->z_pflags, 8);
+	zfs_tstamp_update_setup(zp, CONTENT_MODIFIED, mtime, ctime, B_TRUE);
+	error = sa_bulk_update(zp->z_sa_hdl, bulk, count, tx);
+	ASSERT(error == 0);
+
+	zfs_log_truncate(zilog, tx, TX_TRUNCATE, zp, off, len);
+
+	dmu_tx_commit(tx);
+
+	zfs_inode_update(zp);
+	error = 0;
+
+out:
+	/*
+	 * Truncate the page cache - for file truncate operations, use
+	 * the purpose-built API for truncations.  For punching operations,
+	 * the truncation is handled under a range lock in zfs_free_range.
+	 */
+	if (len == 0)
+		truncate_setsize(ZTOI(zp), off);
+	return (error);
+}
+
+void
+zfs_create_fs(objset_t *os, cred_t *cr, nvlist_t *zplprops, dmu_tx_t *tx)
+{
+	struct super_block *sb;
+	zfs_sb_t	*zsb;
+	uint64_t	moid, obj, sa_obj, version;
+	uint64_t	sense = ZFS_CASE_SENSITIVE;
+	uint64_t	norm = 0;
+	nvpair_t	*elem;
+	int		size;
+	int		error;
+	int		i;
+	znode_t		*rootzp = NULL;
+	vattr_t		vattr;
+	znode_t		*zp;
+	zfs_acl_ids_t	acl_ids;
+
+	/*
+	 * First attempt to create master node.
+	 */
+	/*
+	 * In an empty objset, there are no blocks to read and thus
+	 * there can be no i/o errors (which we assert below).
+	 */
+	moid = MASTER_NODE_OBJ;
+	error = zap_create_claim(os, moid, DMU_OT_MASTER_NODE,
+	    DMU_OT_NONE, 0, tx);
+	ASSERT(error == 0);
+
+	/*
+	 * Set starting attributes.
+	 */
+	version = zfs_zpl_version_map(spa_version(dmu_objset_spa(os)));
+	elem = NULL;
+	while ((elem = nvlist_next_nvpair(zplprops, elem)) != NULL) {
+		/* For the moment we expect all zpl props to be uint64_ts */
+		uint64_t val;
+		char *name;
+
+		ASSERT(nvpair_type(elem) == DATA_TYPE_UINT64);
+		VERIFY(nvpair_value_uint64(elem, &val) == 0);
+		name = nvpair_name(elem);
+		if (strcmp(name, zfs_prop_to_name(ZFS_PROP_VERSION)) == 0) {
+			if (val < version)
+				version = val;
+		} else {
+			error = zap_update(os, moid, name, 8, 1, &val, tx);
+		}
+		ASSERT(error == 0);
+		if (strcmp(name, zfs_prop_to_name(ZFS_PROP_NORMALIZE)) == 0)
+			norm = val;
+		else if (strcmp(name, zfs_prop_to_name(ZFS_PROP_CASE)) == 0)
+			sense = val;
+	}
+	ASSERT(version != 0);
+	error = zap_update(os, moid, ZPL_VERSION_STR, 8, 1, &version, tx);
+
+	/*
+	 * Create zap object used for SA attribute registration
+	 */
+
+	if (version >= ZPL_VERSION_SA) {
+		sa_obj = zap_create(os, DMU_OT_SA_MASTER_NODE,
+		    DMU_OT_NONE, 0, tx);
+		error = zap_add(os, moid, ZFS_SA_ATTRS, 8, 1, &sa_obj, tx);
+		ASSERT(error == 0);
+	} else {
+		sa_obj = 0;
+	}
+	/*
+	 * Create a delete queue.
+	 */
+	obj = zap_create(os, DMU_OT_UNLINKED_SET, DMU_OT_NONE, 0, tx);
+
+	error = zap_add(os, moid, ZFS_UNLINKED_SET, 8, 1, &obj, tx);
+	ASSERT(error == 0);
+
+	/*
+	 * Create root znode.  Create minimal znode/inode/zsb/sb
+	 * to allow zfs_mknode to work.
+	 */
+	vattr.va_mask = ATTR_MODE|ATTR_UID|ATTR_GID;
+	vattr.va_mode = S_IFDIR|0755;
+	vattr.va_uid = crgetuid(cr);
+	vattr.va_gid = crgetgid(cr);
+
+	rootzp = kmem_cache_alloc(znode_cache, KM_SLEEP);
+	rootzp->z_moved = 0;
+	rootzp->z_unlinked = 0;
+	rootzp->z_atime_dirty = 0;
+	rootzp->z_is_sa = USE_SA(version, os);
+
+	zsb = kmem_zalloc(sizeof (zfs_sb_t), KM_SLEEP);
+	zsb->z_os = os;
+	zsb->z_parent = zsb;
+	zsb->z_version = version;
+	zsb->z_use_fuids = USE_FUIDS(version, os);
+	zsb->z_use_sa = USE_SA(version, os);
+	zsb->z_norm = norm;
+
+	sb = kmem_zalloc(sizeof (struct super_block), KM_SLEEP);
+	sb->s_fs_info = zsb;
+
+	ZTOI(rootzp)->i_sb = sb;
+
+	error = sa_setup(os, sa_obj, zfs_attr_table, ZPL_END,
+	    &zsb->z_attr_table);
+
+	ASSERT(error == 0);
+
+	/*
+	 * Fold case on file systems that are always or sometimes case
+	 * insensitive.
+	 */
+	if (sense == ZFS_CASE_INSENSITIVE || sense == ZFS_CASE_MIXED)
+		zsb->z_norm |= U8_TEXTPREP_TOUPPER;
+
+	mutex_init(&zsb->z_znodes_lock, NULL, MUTEX_DEFAULT, NULL);
+	list_create(&zsb->z_all_znodes, sizeof (znode_t),
+	    offsetof(znode_t, z_link_node));
+
+	size = MIN(1 << (highbit64(zfs_object_mutex_size)-1), ZFS_OBJ_MTX_MAX);
+	zsb->z_hold_size = size;
+	zsb->z_hold_trees = vmem_zalloc(sizeof (avl_tree_t) * size, KM_SLEEP);
+	zsb->z_hold_locks = vmem_zalloc(sizeof (kmutex_t) * size, KM_SLEEP);
+	for (i = 0; i != size; i++) {
+		avl_create(&zsb->z_hold_trees[i], zfs_znode_hold_compare,
+		    sizeof (znode_hold_t), offsetof(znode_hold_t, zh_node));
+		mutex_init(&zsb->z_hold_locks[i], NULL, MUTEX_DEFAULT, NULL);
+	}
+
+	VERIFY(0 == zfs_acl_ids_create(rootzp, IS_ROOT_NODE, &vattr,
+	    cr, NULL, &acl_ids));
+	zfs_mknode(rootzp, &vattr, tx, cr, IS_ROOT_NODE, &zp, &acl_ids);
+	ASSERT3P(zp, ==, rootzp);
+	error = zap_add(os, moid, ZFS_ROOT_OBJ, 8, 1, &rootzp->z_id, tx);
+	ASSERT(error == 0);
+	zfs_acl_ids_free(&acl_ids);
+
+	atomic_set(&ZTOI(rootzp)->i_count, 0);
+	sa_handle_destroy(rootzp->z_sa_hdl);
+	kmem_cache_free(znode_cache, rootzp);
+
+	/*
+	 * Create shares directory
+	 */
+	error = zfs_create_share_dir(zsb, tx);
+	ASSERT(error == 0);
+
+	for (i = 0; i != size; i++) {
+		avl_destroy(&zsb->z_hold_trees[i]);
+		mutex_destroy(&zsb->z_hold_locks[i]);
+	}
+
+	vmem_free(zsb->z_hold_trees, sizeof (avl_tree_t) * size);
+	vmem_free(zsb->z_hold_locks, sizeof (kmutex_t) * size);
+	kmem_free(sb, sizeof (struct super_block));
+	kmem_free(zsb, sizeof (zfs_sb_t));
+}
+#endif /* _KERNEL */
+
+static int
+zfs_sa_setup(objset_t *osp, sa_attr_type_t **sa_table)
+{
+	uint64_t sa_obj = 0;
+	int error;
+
+	error = zap_lookup(osp, MASTER_NODE_OBJ, ZFS_SA_ATTRS, 8, 1, &sa_obj);
+	if (error != 0 && error != ENOENT)
+		return (error);
+
+	error = sa_setup(osp, sa_obj, zfs_attr_table, ZPL_END, sa_table);
+	return (error);
+}
+
+static int
+zfs_grab_sa_handle(objset_t *osp, uint64_t obj, sa_handle_t **hdlp,
+    dmu_buf_t **db, void *tag)
+{
+	dmu_object_info_t doi;
+	int error;
+
+	if ((error = sa_buf_hold(osp, obj, tag, db)) != 0)
+		return (error);
+
+	dmu_object_info_from_db(*db, &doi);
+	if ((doi.doi_bonus_type != DMU_OT_SA &&
+	    doi.doi_bonus_type != DMU_OT_ZNODE) ||
+	    (doi.doi_bonus_type == DMU_OT_ZNODE &&
+	    doi.doi_bonus_size < sizeof (znode_phys_t))) {
+		sa_buf_rele(*db, tag);
+		return (SET_ERROR(ENOTSUP));
+	}
+
+	error = sa_handle_get(osp, obj, NULL, SA_HDL_PRIVATE, hdlp);
+	if (error != 0) {
+		sa_buf_rele(*db, tag);
+		return (error);
+	}
+
+	return (0);
+}
+
+void
+zfs_release_sa_handle(sa_handle_t *hdl, dmu_buf_t *db, void *tag)
+{
+	sa_handle_destroy(hdl);
+	sa_buf_rele(db, tag);
+}
+
+/*
+ * Given an object number, return its parent object number and whether
+ * or not the object is an extended attribute directory.
+ */
+static int
+zfs_obj_to_pobj(sa_handle_t *hdl, sa_attr_type_t *sa_table, uint64_t *pobjp,
+    int *is_xattrdir)
+{
+	uint64_t parent;
+	uint64_t pflags;
+	uint64_t mode;
+	sa_bulk_attr_t bulk[3];
+	int count = 0;
+	int error;
+
+	SA_ADD_BULK_ATTR(bulk, count, sa_table[ZPL_PARENT], NULL,
+	    &parent, sizeof (parent));
+	SA_ADD_BULK_ATTR(bulk, count, sa_table[ZPL_FLAGS], NULL,
+	    &pflags, sizeof (pflags));
+	SA_ADD_BULK_ATTR(bulk, count, sa_table[ZPL_MODE], NULL,
+	    &mode, sizeof (mode));
+
+	if ((error = sa_bulk_lookup(hdl, bulk, count)) != 0)
+		return (error);
+
+	*pobjp = parent;
+	*is_xattrdir = ((pflags & ZFS_XATTR) != 0) && S_ISDIR(mode);
+
+	return (0);
+}
+
+/*
+ * Given an object number, return some zpl level statistics
+ */
+static int
+zfs_obj_to_stats_impl(sa_handle_t *hdl, sa_attr_type_t *sa_table,
+    zfs_stat_t *sb)
+{
+	sa_bulk_attr_t bulk[4];
+	int count = 0;
+
+	SA_ADD_BULK_ATTR(bulk, count, sa_table[ZPL_MODE], NULL,
+	    &sb->zs_mode, sizeof (sb->zs_mode));
+	SA_ADD_BULK_ATTR(bulk, count, sa_table[ZPL_GEN], NULL,
+	    &sb->zs_gen, sizeof (sb->zs_gen));
+	SA_ADD_BULK_ATTR(bulk, count, sa_table[ZPL_LINKS], NULL,
+	    &sb->zs_links, sizeof (sb->zs_links));
+	SA_ADD_BULK_ATTR(bulk, count, sa_table[ZPL_CTIME], NULL,
+	    &sb->zs_ctime, sizeof (sb->zs_ctime));
+
+	return (sa_bulk_lookup(hdl, bulk, count));
+}
+
+static int
+zfs_obj_to_path_impl(objset_t *osp, uint64_t obj, sa_handle_t *hdl,
+    sa_attr_type_t *sa_table, char *buf, int len)
+{
+	sa_handle_t *sa_hdl;
+	sa_handle_t *prevhdl = NULL;
+	dmu_buf_t *prevdb = NULL;
+	dmu_buf_t *sa_db = NULL;
+	char *path = buf + len - 1;
+	int error;
+
+	*path = '\0';
+	sa_hdl = hdl;
+
+	for (;;) {
+		uint64_t pobj = 0;
+		char component[MAXNAMELEN + 2];
+		size_t complen;
+		int is_xattrdir = 0;
+
+		if (prevdb)
+			zfs_release_sa_handle(prevhdl, prevdb, FTAG);
+
+		if ((error = zfs_obj_to_pobj(sa_hdl, sa_table, &pobj,
+		    &is_xattrdir)) != 0)
+			break;
+
+		if (pobj == obj) {
+			if (path[0] != '/')
+				*--path = '/';
+			break;
+		}
+
+		component[0] = '/';
+		if (is_xattrdir) {
+			(void) sprintf(component + 1, "<xattrdir>");
+		} else {
+			error = zap_value_search(osp, pobj, obj,
+			    ZFS_DIRENT_OBJ(-1ULL), component + 1);
+			if (error != 0)
+				break;
+		}
+
+		complen = strlen(component);
+		path -= complen;
+		ASSERT(path >= buf);
+		bcopy(component, path, complen);
+		obj = pobj;
+
+		if (sa_hdl != hdl) {
+			prevhdl = sa_hdl;
+			prevdb = sa_db;
+		}
+		error = zfs_grab_sa_handle(osp, obj, &sa_hdl, &sa_db, FTAG);
+		if (error != 0) {
+			sa_hdl = prevhdl;
+			sa_db = prevdb;
+			break;
+		}
+	}
+
+	if (sa_hdl != NULL && sa_hdl != hdl) {
+		ASSERT(sa_db != NULL);
+		zfs_release_sa_handle(sa_hdl, sa_db, FTAG);
+	}
+
+	if (error == 0)
+		(void) memmove(buf, path, buf + len - path);
+
+	return (error);
+}
+
+int
+zfs_obj_to_path(objset_t *osp, uint64_t obj, char *buf, int len)
+{
+	sa_attr_type_t *sa_table;
+	sa_handle_t *hdl;
+	dmu_buf_t *db;
+	int error;
+
+	error = zfs_sa_setup(osp, &sa_table);
+	if (error != 0)
+		return (error);
+
+	error = zfs_grab_sa_handle(osp, obj, &hdl, &db, FTAG);
+	if (error != 0)
+		return (error);
+
+	error = zfs_obj_to_path_impl(osp, obj, hdl, sa_table, buf, len);
+
+	zfs_release_sa_handle(hdl, db, FTAG);
+	return (error);
+}
+
+int
+zfs_obj_to_stats(objset_t *osp, uint64_t obj, zfs_stat_t *sb,
+    char *buf, int len)
+{
+	char *path = buf + len - 1;
+	sa_attr_type_t *sa_table;
+	sa_handle_t *hdl;
+	dmu_buf_t *db;
+	int error;
+
+	*path = '\0';
+
+	error = zfs_sa_setup(osp, &sa_table);
+	if (error != 0)
+		return (error);
+
+	error = zfs_grab_sa_handle(osp, obj, &hdl, &db, FTAG);
+	if (error != 0)
+		return (error);
+
+	error = zfs_obj_to_stats_impl(hdl, sa_table, sb);
+	if (error != 0) {
+		zfs_release_sa_handle(hdl, db, FTAG);
+		return (error);
+	}
+
+	error = zfs_obj_to_path_impl(osp, obj, hdl, sa_table, buf, len);
+
+	zfs_release_sa_handle(hdl, db, FTAG);
+	return (error);
+}
+
+#if defined(_KERNEL) && defined(HAVE_SPL)
+EXPORT_SYMBOL(zfs_create_fs);
+EXPORT_SYMBOL(zfs_obj_to_path);
+
+module_param(zfs_object_mutex_size, uint, 0644);
+MODULE_PARM_DESC(zfs_object_mutex_size, "Size of znode hold array");
+#endif
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/module/zfs/zil.c
@@ -0,0 +1,2285 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2014 by Delphix. All rights reserved.
+ */
+
+/* Portions Copyright 2010 Robert Milkowski */
+
+#include <sys/zfs_context.h>
+#include <sys/spa.h>
+#include <sys/dmu.h>
+#include <sys/zap.h>
+#include <sys/arc.h>
+#include <sys/stat.h>
+#include <sys/resource.h>
+#include <sys/zil.h>
+#include <sys/zil_impl.h>
+#include <sys/dsl_dataset.h>
+#include <sys/vdev_impl.h>
+#include <sys/dmu_tx.h>
+#include <sys/dsl_pool.h>
+#include <sys/metaslab.h>
+#include <sys/trace_zil.h>
+
+/*
+ * The zfs intent log (ZIL) saves transaction records of system calls
+ * that change the file system in memory with enough information
+ * to be able to replay them. These are stored in memory until
+ * either the DMU transaction group (txg) commits them to the stable pool
+ * and they can be discarded, or they are flushed to the stable log
+ * (also in the pool) due to a fsync, O_DSYNC or other synchronous
+ * requirement. In the event of a panic or power fail then those log
+ * records (transactions) are replayed.
+ *
+ * There is one ZIL per file system. Its on-disk (pool) format consists
+ * of 3 parts:
+ *
+ * 	- ZIL header
+ * 	- ZIL blocks
+ * 	- ZIL records
+ *
+ * A log record holds a system call transaction. Log blocks can
+ * hold many log records and the blocks are chained together.
+ * Each ZIL block contains a block pointer (blkptr_t) to the next
+ * ZIL block in the chain. The ZIL header points to the first
+ * block in the chain. Note there is not a fixed place in the pool
+ * to hold blocks. They are dynamically allocated and freed as
+ * needed from the blocks available. Figure X shows the ZIL structure:
+ */
+
+/*
+ * See zil.h for more information about these fields.
+ */
+zil_stats_t zil_stats = {
+	{ "zil_commit_count",			KSTAT_DATA_UINT64 },
+	{ "zil_commit_writer_count",		KSTAT_DATA_UINT64 },
+	{ "zil_itx_count",			KSTAT_DATA_UINT64 },
+	{ "zil_itx_indirect_count",		KSTAT_DATA_UINT64 },
+	{ "zil_itx_indirect_bytes",		KSTAT_DATA_UINT64 },
+	{ "zil_itx_copied_count",		KSTAT_DATA_UINT64 },
+	{ "zil_itx_copied_bytes",		KSTAT_DATA_UINT64 },
+	{ "zil_itx_needcopy_count",		KSTAT_DATA_UINT64 },
+	{ "zil_itx_needcopy_bytes",		KSTAT_DATA_UINT64 },
+	{ "zil_itx_metaslab_normal_count",	KSTAT_DATA_UINT64 },
+	{ "zil_itx_metaslab_normal_bytes",	KSTAT_DATA_UINT64 },
+	{ "zil_itx_metaslab_slog_count",	KSTAT_DATA_UINT64 },
+	{ "zil_itx_metaslab_slog_bytes",	KSTAT_DATA_UINT64 },
+};
+
+static kstat_t *zil_ksp;
+
+/*
+ * Disable intent logging replay.  This global ZIL switch affects all pools.
+ */
+int zil_replay_disable = 0;
+
+/*
+ * Tunable parameter for debugging or performance analysis.  Setting
+ * zfs_nocacheflush will cause corruption on power loss if a volatile
+ * out-of-order write cache is enabled.
+ */
+int zfs_nocacheflush = 0;
+
+static kmem_cache_t *zil_lwb_cache;
+
+static void zil_async_to_sync(zilog_t *zilog, uint64_t foid);
+
+#define	LWB_EMPTY(lwb) ((BP_GET_LSIZE(&lwb->lwb_blk) - \
+    sizeof (zil_chain_t)) == (lwb->lwb_sz - lwb->lwb_nused))
+
+
+/*
+ * ziltest is by and large an ugly hack, but very useful in
+ * checking replay without tedious work.
+ * When running ziltest we want to keep all itx's and so maintain
+ * a single list in the zl_itxg[] that uses a high txg: ZILTEST_TXG
+ * We subtract TXG_CONCURRENT_STATES to allow for common code.
+ */
+#define	ZILTEST_TXG (UINT64_MAX - TXG_CONCURRENT_STATES)
+
+static int
+zil_bp_compare(const void *x1, const void *x2)
+{
+	const dva_t *dva1 = &((zil_bp_node_t *)x1)->zn_dva;
+	const dva_t *dva2 = &((zil_bp_node_t *)x2)->zn_dva;
+
+	if (DVA_GET_VDEV(dva1) < DVA_GET_VDEV(dva2))
+		return (-1);
+	if (DVA_GET_VDEV(dva1) > DVA_GET_VDEV(dva2))
+		return (1);
+
+	if (DVA_GET_OFFSET(dva1) < DVA_GET_OFFSET(dva2))
+		return (-1);
+	if (DVA_GET_OFFSET(dva1) > DVA_GET_OFFSET(dva2))
+		return (1);
+
+	return (0);
+}
+
+static void
+zil_bp_tree_init(zilog_t *zilog)
+{
+	avl_create(&zilog->zl_bp_tree, zil_bp_compare,
+	    sizeof (zil_bp_node_t), offsetof(zil_bp_node_t, zn_node));
+}
+
+static void
+zil_bp_tree_fini(zilog_t *zilog)
+{
+	avl_tree_t *t = &zilog->zl_bp_tree;
+	zil_bp_node_t *zn;
+	void *cookie = NULL;
+
+	while ((zn = avl_destroy_nodes(t, &cookie)) != NULL)
+		kmem_free(zn, sizeof (zil_bp_node_t));
+
+	avl_destroy(t);
+}
+
+int
+zil_bp_tree_add(zilog_t *zilog, const blkptr_t *bp)
+{
+	avl_tree_t *t = &zilog->zl_bp_tree;
+	const dva_t *dva;
+	zil_bp_node_t *zn;
+	avl_index_t where;
+
+	if (BP_IS_EMBEDDED(bp))
+		return (0);
+
+	dva = BP_IDENTITY(bp);
+
+	if (avl_find(t, dva, &where) != NULL)
+		return (SET_ERROR(EEXIST));
+
+	zn = kmem_alloc(sizeof (zil_bp_node_t), KM_SLEEP);
+	zn->zn_dva = *dva;
+	avl_insert(t, zn, where);
+
+	return (0);
+}
+
+static zil_header_t *
+zil_header_in_syncing_context(zilog_t *zilog)
+{
+	return ((zil_header_t *)zilog->zl_header);
+}
+
+static void
+zil_init_log_chain(zilog_t *zilog, blkptr_t *bp)
+{
+	zio_cksum_t *zc = &bp->blk_cksum;
+
+	zc->zc_word[ZIL_ZC_GUID_0] = spa_get_random(-1ULL);
+	zc->zc_word[ZIL_ZC_GUID_1] = spa_get_random(-1ULL);
+	zc->zc_word[ZIL_ZC_OBJSET] = dmu_objset_id(zilog->zl_os);
+	zc->zc_word[ZIL_ZC_SEQ] = 1ULL;
+}
+
+/*
+ * Read a log block and make sure it's valid.
+ */
+static int
+zil_read_log_block(zilog_t *zilog, const blkptr_t *bp, blkptr_t *nbp, void *dst,
+    char **end)
+{
+	enum zio_flag zio_flags = ZIO_FLAG_CANFAIL;
+	arc_flags_t aflags = ARC_FLAG_WAIT;
+	arc_buf_t *abuf = NULL;
+	zbookmark_phys_t zb;
+	int error;
+
+	if (zilog->zl_header->zh_claim_txg == 0)
+		zio_flags |= ZIO_FLAG_SPECULATIVE | ZIO_FLAG_SCRUB;
+
+	if (!(zilog->zl_header->zh_flags & ZIL_CLAIM_LR_SEQ_VALID))
+		zio_flags |= ZIO_FLAG_SPECULATIVE;
+
+	SET_BOOKMARK(&zb, bp->blk_cksum.zc_word[ZIL_ZC_OBJSET],
+	    ZB_ZIL_OBJECT, ZB_ZIL_LEVEL, bp->blk_cksum.zc_word[ZIL_ZC_SEQ]);
+
+	error = arc_read(NULL, zilog->zl_spa, bp, arc_getbuf_func, &abuf,
+	    ZIO_PRIORITY_SYNC_READ, zio_flags, &aflags, &zb);
+
+	if (error == 0) {
+		zio_cksum_t cksum = bp->blk_cksum;
+
+		/*
+		 * Validate the checksummed log block.
+		 *
+		 * Sequence numbers should be... sequential.  The checksum
+		 * verifier for the next block should be bp's checksum plus 1.
+		 *
+		 * Also check the log chain linkage and size used.
+		 */
+		cksum.zc_word[ZIL_ZC_SEQ]++;
+
+		if (BP_GET_CHECKSUM(bp) == ZIO_CHECKSUM_ZILOG2) {
+			zil_chain_t *zilc = abuf->b_data;
+			char *lr = (char *)(zilc + 1);
+			uint64_t len = zilc->zc_nused - sizeof (zil_chain_t);
+
+			if (bcmp(&cksum, &zilc->zc_next_blk.blk_cksum,
+			    sizeof (cksum)) || BP_IS_HOLE(&zilc->zc_next_blk)) {
+				error = SET_ERROR(ECKSUM);
+			} else {
+				ASSERT3U(len, <=, SPA_OLD_MAXBLOCKSIZE);
+				bcopy(lr, dst, len);
+				*end = (char *)dst + len;
+				*nbp = zilc->zc_next_blk;
+			}
+		} else {
+			char *lr = abuf->b_data;
+			uint64_t size = BP_GET_LSIZE(bp);
+			zil_chain_t *zilc = (zil_chain_t *)(lr + size) - 1;
+
+			if (bcmp(&cksum, &zilc->zc_next_blk.blk_cksum,
+			    sizeof (cksum)) || BP_IS_HOLE(&zilc->zc_next_blk) ||
+			    (zilc->zc_nused > (size - sizeof (*zilc)))) {
+				error = SET_ERROR(ECKSUM);
+			} else {
+				ASSERT3U(zilc->zc_nused, <=,
+				    SPA_OLD_MAXBLOCKSIZE);
+				bcopy(lr, dst, zilc->zc_nused);
+				*end = (char *)dst + zilc->zc_nused;
+				*nbp = zilc->zc_next_blk;
+			}
+		}
+
+		VERIFY(arc_buf_remove_ref(abuf, &abuf));
+	}
+
+	return (error);
+}
+
+/*
+ * Read a TX_WRITE log data block.
+ */
+static int
+zil_read_log_data(zilog_t *zilog, const lr_write_t *lr, void *wbuf)
+{
+	enum zio_flag zio_flags = ZIO_FLAG_CANFAIL;
+	const blkptr_t *bp = &lr->lr_blkptr;
+	arc_flags_t aflags = ARC_FLAG_WAIT;
+	arc_buf_t *abuf = NULL;
+	zbookmark_phys_t zb;
+	int error;
+
+	if (BP_IS_HOLE(bp)) {
+		if (wbuf != NULL)
+			bzero(wbuf, MAX(BP_GET_LSIZE(bp), lr->lr_length));
+		return (0);
+	}
+
+	if (zilog->zl_header->zh_claim_txg == 0)
+		zio_flags |= ZIO_FLAG_SPECULATIVE | ZIO_FLAG_SCRUB;
+
+	SET_BOOKMARK(&zb, dmu_objset_id(zilog->zl_os), lr->lr_foid,
+	    ZB_ZIL_LEVEL, lr->lr_offset / BP_GET_LSIZE(bp));
+
+	error = arc_read(NULL, zilog->zl_spa, bp, arc_getbuf_func, &abuf,
+	    ZIO_PRIORITY_SYNC_READ, zio_flags, &aflags, &zb);
+
+	if (error == 0) {
+		if (wbuf != NULL)
+			bcopy(abuf->b_data, wbuf, arc_buf_size(abuf));
+		(void) arc_buf_remove_ref(abuf, &abuf);
+	}
+
+	return (error);
+}
+
+/*
+ * Parse the intent log, and call parse_func for each valid record within.
+ */
+int
+zil_parse(zilog_t *zilog, zil_parse_blk_func_t *parse_blk_func,
+    zil_parse_lr_func_t *parse_lr_func, void *arg, uint64_t txg)
+{
+	const zil_header_t *zh = zilog->zl_header;
+	boolean_t claimed = !!zh->zh_claim_txg;
+	uint64_t claim_blk_seq = claimed ? zh->zh_claim_blk_seq : UINT64_MAX;
+	uint64_t claim_lr_seq = claimed ? zh->zh_claim_lr_seq : UINT64_MAX;
+	uint64_t max_blk_seq = 0;
+	uint64_t max_lr_seq = 0;
+	uint64_t blk_count = 0;
+	uint64_t lr_count = 0;
+	blkptr_t blk, next_blk;
+	char *lrbuf, *lrp;
+	int error = 0;
+
+	bzero(&next_blk, sizeof (blkptr_t));
+
+	/*
+	 * Old logs didn't record the maximum zh_claim_lr_seq.
+	 */
+	if (!(zh->zh_flags & ZIL_CLAIM_LR_SEQ_VALID))
+		claim_lr_seq = UINT64_MAX;
+
+	/*
+	 * Starting at the block pointed to by zh_log we read the log chain.
+	 * For each block in the chain we strongly check that block to
+	 * ensure its validity.  We stop when an invalid block is found.
+	 * For each block pointer in the chain we call parse_blk_func().
+	 * For each record in each valid block we call parse_lr_func().
+	 * If the log has been claimed, stop if we encounter a sequence
+	 * number greater than the highest claimed sequence number.
+	 */
+	lrbuf = zio_buf_alloc(SPA_OLD_MAXBLOCKSIZE);
+	zil_bp_tree_init(zilog);
+
+	for (blk = zh->zh_log; !BP_IS_HOLE(&blk); blk = next_blk) {
+		uint64_t blk_seq = blk.blk_cksum.zc_word[ZIL_ZC_SEQ];
+		int reclen;
+		char *end = NULL;
+
+		if (blk_seq > claim_blk_seq)
+			break;
+		if ((error = parse_blk_func(zilog, &blk, arg, txg)) != 0)
+			break;
+		ASSERT3U(max_blk_seq, <, blk_seq);
+		max_blk_seq = blk_seq;
+		blk_count++;
+
+		if (max_lr_seq == claim_lr_seq && max_blk_seq == claim_blk_seq)
+			break;
+
+		error = zil_read_log_block(zilog, &blk, &next_blk, lrbuf, &end);
+		if (error != 0)
+			break;
+
+		for (lrp = lrbuf; lrp < end; lrp += reclen) {
+			lr_t *lr = (lr_t *)lrp;
+			reclen = lr->lrc_reclen;
+			ASSERT3U(reclen, >=, sizeof (lr_t));
+			if (lr->lrc_seq > claim_lr_seq)
+				goto done;
+			if ((error = parse_lr_func(zilog, lr, arg, txg)) != 0)
+				goto done;
+			ASSERT3U(max_lr_seq, <, lr->lrc_seq);
+			max_lr_seq = lr->lrc_seq;
+			lr_count++;
+		}
+	}
+done:
+	zilog->zl_parse_error = error;
+	zilog->zl_parse_blk_seq = max_blk_seq;
+	zilog->zl_parse_lr_seq = max_lr_seq;
+	zilog->zl_parse_blk_count = blk_count;
+	zilog->zl_parse_lr_count = lr_count;
+
+	ASSERT(!claimed || !(zh->zh_flags & ZIL_CLAIM_LR_SEQ_VALID) ||
+	    (max_blk_seq == claim_blk_seq && max_lr_seq == claim_lr_seq));
+
+	zil_bp_tree_fini(zilog);
+	zio_buf_free(lrbuf, SPA_OLD_MAXBLOCKSIZE);
+
+	return (error);
+}
+
+static int
+zil_claim_log_block(zilog_t *zilog, blkptr_t *bp, void *tx, uint64_t first_txg)
+{
+	/*
+	 * Claim log block if not already committed and not already claimed.
+	 * If tx == NULL, just verify that the block is claimable.
+	 */
+	if (BP_IS_HOLE(bp) || bp->blk_birth < first_txg ||
+	    zil_bp_tree_add(zilog, bp) != 0)
+		return (0);
+
+	return (zio_wait(zio_claim(NULL, zilog->zl_spa,
+	    tx == NULL ? 0 : first_txg, bp, spa_claim_notify, NULL,
+	    ZIO_FLAG_CANFAIL | ZIO_FLAG_SPECULATIVE | ZIO_FLAG_SCRUB)));
+}
+
+static int
+zil_claim_log_record(zilog_t *zilog, lr_t *lrc, void *tx, uint64_t first_txg)
+{
+	lr_write_t *lr = (lr_write_t *)lrc;
+	int error;
+
+	if (lrc->lrc_txtype != TX_WRITE)
+		return (0);
+
+	/*
+	 * If the block is not readable, don't claim it.  This can happen
+	 * in normal operation when a log block is written to disk before
+	 * some of the dmu_sync() blocks it points to.  In this case, the
+	 * transaction cannot have been committed to anyone (we would have
+	 * waited for all writes to be stable first), so it is semantically
+	 * correct to declare this the end of the log.
+	 */
+	if (lr->lr_blkptr.blk_birth >= first_txg &&
+	    (error = zil_read_log_data(zilog, lr, NULL)) != 0)
+		return (error);
+	return (zil_claim_log_block(zilog, &lr->lr_blkptr, tx, first_txg));
+}
+
+/* ARGSUSED */
+static int
+zil_free_log_block(zilog_t *zilog, blkptr_t *bp, void *tx, uint64_t claim_txg)
+{
+	zio_free_zil(zilog->zl_spa, dmu_tx_get_txg(tx), bp);
+
+	return (0);
+}
+
+static int
+zil_free_log_record(zilog_t *zilog, lr_t *lrc, void *tx, uint64_t claim_txg)
+{
+	lr_write_t *lr = (lr_write_t *)lrc;
+	blkptr_t *bp = &lr->lr_blkptr;
+
+	/*
+	 * If we previously claimed it, we need to free it.
+	 */
+	if (claim_txg != 0 && lrc->lrc_txtype == TX_WRITE &&
+	    bp->blk_birth >= claim_txg && zil_bp_tree_add(zilog, bp) == 0 &&
+	    !BP_IS_HOLE(bp))
+		zio_free(zilog->zl_spa, dmu_tx_get_txg(tx), bp);
+
+	return (0);
+}
+
+static lwb_t *
+zil_alloc_lwb(zilog_t *zilog, blkptr_t *bp, uint64_t txg, boolean_t fastwrite)
+{
+	lwb_t *lwb;
+
+	lwb = kmem_cache_alloc(zil_lwb_cache, KM_SLEEP);
+	lwb->lwb_zilog = zilog;
+	lwb->lwb_blk = *bp;
+	lwb->lwb_fastwrite = fastwrite;
+	lwb->lwb_buf = zio_buf_alloc(BP_GET_LSIZE(bp));
+	lwb->lwb_max_txg = txg;
+	lwb->lwb_zio = NULL;
+	lwb->lwb_tx = NULL;
+	if (BP_GET_CHECKSUM(bp) == ZIO_CHECKSUM_ZILOG2) {
+		lwb->lwb_nused = sizeof (zil_chain_t);
+		lwb->lwb_sz = BP_GET_LSIZE(bp);
+	} else {
+		lwb->lwb_nused = 0;
+		lwb->lwb_sz = BP_GET_LSIZE(bp) - sizeof (zil_chain_t);
+	}
+
+	mutex_enter(&zilog->zl_lock);
+	list_insert_tail(&zilog->zl_lwb_list, lwb);
+	mutex_exit(&zilog->zl_lock);
+
+	return (lwb);
+}
+
+/*
+ * Called when we create in-memory log transactions so that we know
+ * to cleanup the itxs at the end of spa_sync().
+ */
+void
+zilog_dirty(zilog_t *zilog, uint64_t txg)
+{
+	dsl_pool_t *dp = zilog->zl_dmu_pool;
+	dsl_dataset_t *ds = dmu_objset_ds(zilog->zl_os);
+
+	if (ds->ds_is_snapshot)
+		panic("dirtying snapshot!");
+
+	if (txg_list_add(&dp->dp_dirty_zilogs, zilog, txg)) {
+		/* up the hold count until we can be written out */
+		dmu_buf_add_ref(ds->ds_dbuf, zilog);
+	}
+}
+
+boolean_t
+zilog_is_dirty(zilog_t *zilog)
+{
+	dsl_pool_t *dp = zilog->zl_dmu_pool;
+	int t;
+
+	for (t = 0; t < TXG_SIZE; t++) {
+		if (txg_list_member(&dp->dp_dirty_zilogs, zilog, t))
+			return (B_TRUE);
+	}
+	return (B_FALSE);
+}
+
+/*
+ * Create an on-disk intent log.
+ */
+static lwb_t *
+zil_create(zilog_t *zilog)
+{
+	const zil_header_t *zh = zilog->zl_header;
+	lwb_t *lwb = NULL;
+	uint64_t txg = 0;
+	dmu_tx_t *tx = NULL;
+	blkptr_t blk;
+	int error = 0;
+	boolean_t fastwrite = FALSE;
+
+	/*
+	 * Wait for any previous destroy to complete.
+	 */
+	txg_wait_synced(zilog->zl_dmu_pool, zilog->zl_destroy_txg);
+
+	ASSERT(zh->zh_claim_txg == 0);
+	ASSERT(zh->zh_replay_seq == 0);
+
+	blk = zh->zh_log;
+
+	/*
+	 * Allocate an initial log block if:
+	 *    - there isn't one already
+	 *    - the existing block is the wrong endianess
+	 */
+	if (BP_IS_HOLE(&blk) || BP_SHOULD_BYTESWAP(&blk)) {
+		tx = dmu_tx_create(zilog->zl_os);
+		VERIFY(dmu_tx_assign(tx, TXG_WAIT) == 0);
+		dsl_dataset_dirty(dmu_objset_ds(zilog->zl_os), tx);
+		txg = dmu_tx_get_txg(tx);
+
+		if (!BP_IS_HOLE(&blk)) {
+			zio_free_zil(zilog->zl_spa, txg, &blk);
+			BP_ZERO(&blk);
+		}
+
+		error = zio_alloc_zil(zilog->zl_spa, txg, &blk,
+		    ZIL_MIN_BLKSZ, B_TRUE);
+		fastwrite = TRUE;
+
+		if (error == 0)
+			zil_init_log_chain(zilog, &blk);
+	}
+
+	/*
+	 * Allocate a log write buffer (lwb) for the first log block.
+	 */
+	if (error == 0)
+		lwb = zil_alloc_lwb(zilog, &blk, txg, fastwrite);
+
+	/*
+	 * If we just allocated the first log block, commit our transaction
+	 * and wait for zil_sync() to stuff the block poiner into zh_log.
+	 * (zh is part of the MOS, so we cannot modify it in open context.)
+	 */
+	if (tx != NULL) {
+		dmu_tx_commit(tx);
+		txg_wait_synced(zilog->zl_dmu_pool, txg);
+	}
+
+	ASSERT(bcmp(&blk, &zh->zh_log, sizeof (blk)) == 0);
+
+	return (lwb);
+}
+
+/*
+ * In one tx, free all log blocks and clear the log header.
+ * If keep_first is set, then we're replaying a log with no content.
+ * We want to keep the first block, however, so that the first
+ * synchronous transaction doesn't require a txg_wait_synced()
+ * in zil_create().  We don't need to txg_wait_synced() here either
+ * when keep_first is set, because both zil_create() and zil_destroy()
+ * will wait for any in-progress destroys to complete.
+ */
+void
+zil_destroy(zilog_t *zilog, boolean_t keep_first)
+{
+	const zil_header_t *zh = zilog->zl_header;
+	lwb_t *lwb;
+	dmu_tx_t *tx;
+	uint64_t txg;
+
+	/*
+	 * Wait for any previous destroy to complete.
+	 */
+	txg_wait_synced(zilog->zl_dmu_pool, zilog->zl_destroy_txg);
+
+	zilog->zl_old_header = *zh;		/* debugging aid */
+
+	if (BP_IS_HOLE(&zh->zh_log))
+		return;
+
+	tx = dmu_tx_create(zilog->zl_os);
+	VERIFY(dmu_tx_assign(tx, TXG_WAIT) == 0);
+	dsl_dataset_dirty(dmu_objset_ds(zilog->zl_os), tx);
+	txg = dmu_tx_get_txg(tx);
+
+	mutex_enter(&zilog->zl_lock);
+
+	ASSERT3U(zilog->zl_destroy_txg, <, txg);
+	zilog->zl_destroy_txg = txg;
+	zilog->zl_keep_first = keep_first;
+
+	if (!list_is_empty(&zilog->zl_lwb_list)) {
+		ASSERT(zh->zh_claim_txg == 0);
+		VERIFY(!keep_first);
+		while ((lwb = list_head(&zilog->zl_lwb_list)) != NULL) {
+			ASSERT(lwb->lwb_zio == NULL);
+			if (lwb->lwb_fastwrite)
+				metaslab_fastwrite_unmark(zilog->zl_spa,
+				    &lwb->lwb_blk);
+			list_remove(&zilog->zl_lwb_list, lwb);
+			if (lwb->lwb_buf != NULL)
+				zio_buf_free(lwb->lwb_buf, lwb->lwb_sz);
+			zio_free_zil(zilog->zl_spa, txg, &lwb->lwb_blk);
+			kmem_cache_free(zil_lwb_cache, lwb);
+		}
+	} else if (!keep_first) {
+		zil_destroy_sync(zilog, tx);
+	}
+	mutex_exit(&zilog->zl_lock);
+
+	dmu_tx_commit(tx);
+}
+
+void
+zil_destroy_sync(zilog_t *zilog, dmu_tx_t *tx)
+{
+	ASSERT(list_is_empty(&zilog->zl_lwb_list));
+	(void) zil_parse(zilog, zil_free_log_block,
+	    zil_free_log_record, tx, zilog->zl_header->zh_claim_txg);
+}
+
+int
+zil_claim(dsl_pool_t *dp, dsl_dataset_t *ds, void *txarg)
+{
+	dmu_tx_t *tx = txarg;
+	uint64_t first_txg = dmu_tx_get_txg(tx);
+	zilog_t *zilog;
+	zil_header_t *zh;
+	objset_t *os;
+	int error;
+
+	error = dmu_objset_own_obj(dp, ds->ds_object,
+	    DMU_OST_ANY, B_FALSE, FTAG, &os);
+	if (error != 0) {
+		/*
+		 * EBUSY indicates that the objset is inconsistent, in which
+		 * case it can not have a ZIL.
+		 */
+		if (error != EBUSY) {
+			cmn_err(CE_WARN, "can't open objset for %llu, error %u",
+			    (unsigned long long)ds->ds_object, error);
+		}
+
+		return (0);
+	}
+
+	zilog = dmu_objset_zil(os);
+	zh = zil_header_in_syncing_context(zilog);
+
+	if (spa_get_log_state(zilog->zl_spa) == SPA_LOG_CLEAR) {
+		if (!BP_IS_HOLE(&zh->zh_log))
+			zio_free_zil(zilog->zl_spa, first_txg, &zh->zh_log);
+		BP_ZERO(&zh->zh_log);
+		dsl_dataset_dirty(dmu_objset_ds(os), tx);
+		dmu_objset_disown(os, FTAG);
+		return (0);
+	}
+
+	/*
+	 * Claim all log blocks if we haven't already done so, and remember
+	 * the highest claimed sequence number.  This ensures that if we can
+	 * read only part of the log now (e.g. due to a missing device),
+	 * but we can read the entire log later, we will not try to replay
+	 * or destroy beyond the last block we successfully claimed.
+	 */
+	ASSERT3U(zh->zh_claim_txg, <=, first_txg);
+	if (zh->zh_claim_txg == 0 && !BP_IS_HOLE(&zh->zh_log)) {
+		(void) zil_parse(zilog, zil_claim_log_block,
+		    zil_claim_log_record, tx, first_txg);
+		zh->zh_claim_txg = first_txg;
+		zh->zh_claim_blk_seq = zilog->zl_parse_blk_seq;
+		zh->zh_claim_lr_seq = zilog->zl_parse_lr_seq;
+		if (zilog->zl_parse_lr_count || zilog->zl_parse_blk_count > 1)
+			zh->zh_flags |= ZIL_REPLAY_NEEDED;
+		zh->zh_flags |= ZIL_CLAIM_LR_SEQ_VALID;
+		dsl_dataset_dirty(dmu_objset_ds(os), tx);
+	}
+
+	ASSERT3U(first_txg, ==, (spa_last_synced_txg(zilog->zl_spa) + 1));
+	dmu_objset_disown(os, FTAG);
+	return (0);
+}
+
+/*
+ * Check the log by walking the log chain.
+ * Checksum errors are ok as they indicate the end of the chain.
+ * Any other error (no device or read failure) returns an error.
+ */
+/* ARGSUSED */
+int
+zil_check_log_chain(dsl_pool_t *dp, dsl_dataset_t *ds, void *tx)
+{
+	zilog_t *zilog;
+	objset_t *os;
+	blkptr_t *bp;
+	int error;
+
+	ASSERT(tx == NULL);
+
+	error = dmu_objset_from_ds(ds, &os);
+	if (error != 0) {
+		cmn_err(CE_WARN, "can't open objset %llu, error %d",
+		    (unsigned long long)ds->ds_object, error);
+		return (0);
+	}
+
+	zilog = dmu_objset_zil(os);
+	bp = (blkptr_t *)&zilog->zl_header->zh_log;
+
+	/*
+	 * Check the first block and determine if it's on a log device
+	 * which may have been removed or faulted prior to loading this
+	 * pool.  If so, there's no point in checking the rest of the log
+	 * as its content should have already been synced to the pool.
+	 */
+	if (!BP_IS_HOLE(bp)) {
+		vdev_t *vd;
+		boolean_t valid = B_TRUE;
+
+		spa_config_enter(os->os_spa, SCL_STATE, FTAG, RW_READER);
+		vd = vdev_lookup_top(os->os_spa, DVA_GET_VDEV(&bp->blk_dva[0]));
+		if (vd->vdev_islog && vdev_is_dead(vd))
+			valid = vdev_log_state_valid(vd);
+		spa_config_exit(os->os_spa, SCL_STATE, FTAG);
+
+		if (!valid)
+			return (0);
+	}
+
+	/*
+	 * Because tx == NULL, zil_claim_log_block() will not actually claim
+	 * any blocks, but just determine whether it is possible to do so.
+	 * In addition to checking the log chain, zil_claim_log_block()
+	 * will invoke zio_claim() with a done func of spa_claim_notify(),
+	 * which will update spa_max_claim_txg.  See spa_load() for details.
+	 */
+	error = zil_parse(zilog, zil_claim_log_block, zil_claim_log_record, tx,
+	    zilog->zl_header->zh_claim_txg ? -1ULL : spa_first_txg(os->os_spa));
+
+	return ((error == ECKSUM || error == ENOENT) ? 0 : error);
+}
+
+static int
+zil_vdev_compare(const void *x1, const void *x2)
+{
+	const uint64_t v1 = ((zil_vdev_node_t *)x1)->zv_vdev;
+	const uint64_t v2 = ((zil_vdev_node_t *)x2)->zv_vdev;
+
+	if (v1 < v2)
+		return (-1);
+	if (v1 > v2)
+		return (1);
+
+	return (0);
+}
+
+void
+zil_add_block(zilog_t *zilog, const blkptr_t *bp)
+{
+	avl_tree_t *t = &zilog->zl_vdev_tree;
+	avl_index_t where;
+	zil_vdev_node_t *zv, zvsearch;
+	int ndvas = BP_GET_NDVAS(bp);
+	int i;
+
+	if (zfs_nocacheflush)
+		return;
+
+	ASSERT(zilog->zl_writer);
+
+	/*
+	 * Even though we're zl_writer, we still need a lock because the
+	 * zl_get_data() callbacks may have dmu_sync() done callbacks
+	 * that will run concurrently.
+	 */
+	mutex_enter(&zilog->zl_vdev_lock);
+	for (i = 0; i < ndvas; i++) {
+		zvsearch.zv_vdev = DVA_GET_VDEV(&bp->blk_dva[i]);
+		if (avl_find(t, &zvsearch, &where) == NULL) {
+			zv = kmem_alloc(sizeof (*zv), KM_SLEEP);
+			zv->zv_vdev = zvsearch.zv_vdev;
+			avl_insert(t, zv, where);
+		}
+	}
+	mutex_exit(&zilog->zl_vdev_lock);
+}
+
+static void
+zil_flush_vdevs(zilog_t *zilog)
+{
+	spa_t *spa = zilog->zl_spa;
+	avl_tree_t *t = &zilog->zl_vdev_tree;
+	void *cookie = NULL;
+	zil_vdev_node_t *zv;
+	zio_t *zio;
+
+	ASSERT(zilog->zl_writer);
+
+	/*
+	 * We don't need zl_vdev_lock here because we're the zl_writer,
+	 * and all zl_get_data() callbacks are done.
+	 */
+	if (avl_numnodes(t) == 0)
+		return;
+
+	spa_config_enter(spa, SCL_STATE, FTAG, RW_READER);
+
+	zio = zio_root(spa, NULL, NULL, ZIO_FLAG_CANFAIL);
+
+	while ((zv = avl_destroy_nodes(t, &cookie)) != NULL) {
+		vdev_t *vd = vdev_lookup_top(spa, zv->zv_vdev);
+		if (vd != NULL)
+			zio_flush(zio, vd);
+		kmem_free(zv, sizeof (*zv));
+	}
+
+	/*
+	 * Wait for all the flushes to complete.  Not all devices actually
+	 * support the DKIOCFLUSHWRITECACHE ioctl, so it's OK if it fails.
+	 */
+	(void) zio_wait(zio);
+
+	spa_config_exit(spa, SCL_STATE, FTAG);
+}
+
+/*
+ * Function called when a log block write completes
+ */
+static void
+zil_lwb_write_done(zio_t *zio)
+{
+	lwb_t *lwb = zio->io_private;
+	zilog_t *zilog = lwb->lwb_zilog;
+	dmu_tx_t *tx = lwb->lwb_tx;
+
+	ASSERT(BP_GET_COMPRESS(zio->io_bp) == ZIO_COMPRESS_OFF);
+	ASSERT(BP_GET_TYPE(zio->io_bp) == DMU_OT_INTENT_LOG);
+	ASSERT(BP_GET_LEVEL(zio->io_bp) == 0);
+	ASSERT(BP_GET_BYTEORDER(zio->io_bp) == ZFS_HOST_BYTEORDER);
+	ASSERT(!BP_IS_GANG(zio->io_bp));
+	ASSERT(!BP_IS_HOLE(zio->io_bp));
+	ASSERT(BP_GET_FILL(zio->io_bp) == 0);
+
+	/*
+	 * Ensure the lwb buffer pointer is cleared before releasing
+	 * the txg. If we have had an allocation failure and
+	 * the txg is waiting to sync then we want want zil_sync()
+	 * to remove the lwb so that it's not picked up as the next new
+	 * one in zil_commit_writer(). zil_sync() will only remove
+	 * the lwb if lwb_buf is null.
+	 */
+	zio_buf_free(lwb->lwb_buf, lwb->lwb_sz);
+	mutex_enter(&zilog->zl_lock);
+	lwb->lwb_zio = NULL;
+	lwb->lwb_fastwrite = FALSE;
+	lwb->lwb_buf = NULL;
+	lwb->lwb_tx = NULL;
+	mutex_exit(&zilog->zl_lock);
+
+	/*
+	 * Now that we've written this log block, we have a stable pointer
+	 * to the next block in the chain, so it's OK to let the txg in
+	 * which we allocated the next block sync.
+	 */
+	dmu_tx_commit(tx);
+}
+
+/*
+ * Initialize the io for a log block.
+ */
+static void
+zil_lwb_write_init(zilog_t *zilog, lwb_t *lwb)
+{
+	zbookmark_phys_t zb;
+
+	SET_BOOKMARK(&zb, lwb->lwb_blk.blk_cksum.zc_word[ZIL_ZC_OBJSET],
+	    ZB_ZIL_OBJECT, ZB_ZIL_LEVEL,
+	    lwb->lwb_blk.blk_cksum.zc_word[ZIL_ZC_SEQ]);
+
+	if (zilog->zl_root_zio == NULL) {
+		zilog->zl_root_zio = zio_root(zilog->zl_spa, NULL, NULL,
+		    ZIO_FLAG_CANFAIL);
+	}
+
+	/* Lock so zil_sync() doesn't fastwrite_unmark after zio is created */
+	mutex_enter(&zilog->zl_lock);
+	if (lwb->lwb_zio == NULL) {
+		if (!lwb->lwb_fastwrite) {
+			metaslab_fastwrite_mark(zilog->zl_spa, &lwb->lwb_blk);
+			lwb->lwb_fastwrite = 1;
+		}
+		lwb->lwb_zio = zio_rewrite(zilog->zl_root_zio, zilog->zl_spa,
+		    0, &lwb->lwb_blk, lwb->lwb_buf, BP_GET_LSIZE(&lwb->lwb_blk),
+		    zil_lwb_write_done, lwb, ZIO_PRIORITY_SYNC_WRITE,
+		    ZIO_FLAG_CANFAIL | ZIO_FLAG_DONT_PROPAGATE |
+		    ZIO_FLAG_FASTWRITE, &zb);
+	}
+	mutex_exit(&zilog->zl_lock);
+}
+
+/*
+ * Define a limited set of intent log block sizes.
+ *
+ * These must be a multiple of 4KB. Note only the amount used (again
+ * aligned to 4KB) actually gets written. However, we can't always just
+ * allocate SPA_OLD_MAXBLOCKSIZE as the slog space could be exhausted.
+ */
+uint64_t zil_block_buckets[] = {
+    4096,		/* non TX_WRITE */
+    8192+4096,		/* data base */
+    32*1024 + 4096, 	/* NFS writes */
+    UINT64_MAX
+};
+
+/*
+ * Use the slog as long as the current commit size is less than the
+ * limit or the total list size is less than 2X the limit.  Limit
+ * checking is disabled by setting zil_slog_limit to UINT64_MAX.
+ */
+unsigned long zil_slog_limit = 1024 * 1024;
+#define	USE_SLOG(zilog) (((zilog)->zl_cur_used < zil_slog_limit) || \
+	((zilog)->zl_itx_list_sz < (zil_slog_limit << 1)))
+
+/*
+ * Start a log block write and advance to the next log block.
+ * Calls are serialized.
+ */
+static lwb_t *
+zil_lwb_write_start(zilog_t *zilog, lwb_t *lwb)
+{
+	lwb_t *nlwb = NULL;
+	zil_chain_t *zilc;
+	spa_t *spa = zilog->zl_spa;
+	blkptr_t *bp;
+	dmu_tx_t *tx;
+	uint64_t txg;
+	uint64_t zil_blksz, wsz;
+	int i, error;
+	boolean_t use_slog;
+
+	if (BP_GET_CHECKSUM(&lwb->lwb_blk) == ZIO_CHECKSUM_ZILOG2) {
+		zilc = (zil_chain_t *)lwb->lwb_buf;
+		bp = &zilc->zc_next_blk;
+	} else {
+		zilc = (zil_chain_t *)(lwb->lwb_buf + lwb->lwb_sz);
+		bp = &zilc->zc_next_blk;
+	}
+
+	ASSERT(lwb->lwb_nused <= lwb->lwb_sz);
+
+	/*
+	 * Allocate the next block and save its address in this block
+	 * before writing it in order to establish the log chain.
+	 * Note that if the allocation of nlwb synced before we wrote
+	 * the block that points at it (lwb), we'd leak it if we crashed.
+	 * Therefore, we don't do dmu_tx_commit() until zil_lwb_write_done().
+	 * We dirty the dataset to ensure that zil_sync() will be called
+	 * to clean up in the event of allocation failure or I/O failure.
+	 */
+	tx = dmu_tx_create(zilog->zl_os);
+	VERIFY(dmu_tx_assign(tx, TXG_WAIT) == 0);
+	dsl_dataset_dirty(dmu_objset_ds(zilog->zl_os), tx);
+	txg = dmu_tx_get_txg(tx);
+
+	lwb->lwb_tx = tx;
+
+	/*
+	 * Log blocks are pre-allocated. Here we select the size of the next
+	 * block, based on size used in the last block.
+	 * - first find the smallest bucket that will fit the block from a
+	 *   limited set of block sizes. This is because it's faster to write
+	 *   blocks allocated from the same metaslab as they are adjacent or
+	 *   close.
+	 * - next find the maximum from the new suggested size and an array of
+	 *   previous sizes. This lessens a picket fence effect of wrongly
+	 *   guesssing the size if we have a stream of say 2k, 64k, 2k, 64k
+	 *   requests.
+	 *
+	 * Note we only write what is used, but we can't just allocate
+	 * the maximum block size because we can exhaust the available
+	 * pool log space.
+	 */
+	zil_blksz = zilog->zl_cur_used + sizeof (zil_chain_t);
+	for (i = 0; zil_blksz > zil_block_buckets[i]; i++)
+		continue;
+	zil_blksz = zil_block_buckets[i];
+	if (zil_blksz == UINT64_MAX)
+		zil_blksz = SPA_OLD_MAXBLOCKSIZE;
+	zilog->zl_prev_blks[zilog->zl_prev_rotor] = zil_blksz;
+	for (i = 0; i < ZIL_PREV_BLKS; i++)
+		zil_blksz = MAX(zil_blksz, zilog->zl_prev_blks[i]);
+	zilog->zl_prev_rotor = (zilog->zl_prev_rotor + 1) & (ZIL_PREV_BLKS - 1);
+
+	BP_ZERO(bp);
+	use_slog = USE_SLOG(zilog);
+	error = zio_alloc_zil(spa, txg, bp, zil_blksz,
+	    USE_SLOG(zilog));
+	if (use_slog) {
+		ZIL_STAT_BUMP(zil_itx_metaslab_slog_count);
+		ZIL_STAT_INCR(zil_itx_metaslab_slog_bytes, lwb->lwb_nused);
+	} else {
+		ZIL_STAT_BUMP(zil_itx_metaslab_normal_count);
+		ZIL_STAT_INCR(zil_itx_metaslab_normal_bytes, lwb->lwb_nused);
+	}
+	if (error == 0) {
+		ASSERT3U(bp->blk_birth, ==, txg);
+		bp->blk_cksum = lwb->lwb_blk.blk_cksum;
+		bp->blk_cksum.zc_word[ZIL_ZC_SEQ]++;
+
+		/*
+		 * Allocate a new log write buffer (lwb).
+		 */
+		nlwb = zil_alloc_lwb(zilog, bp, txg, TRUE);
+
+		/* Record the block for later vdev flushing */
+		zil_add_block(zilog, &lwb->lwb_blk);
+	}
+
+	if (BP_GET_CHECKSUM(&lwb->lwb_blk) == ZIO_CHECKSUM_ZILOG2) {
+		/* For Slim ZIL only write what is used. */
+		wsz = P2ROUNDUP_TYPED(lwb->lwb_nused, ZIL_MIN_BLKSZ, uint64_t);
+		ASSERT3U(wsz, <=, lwb->lwb_sz);
+		zio_shrink(lwb->lwb_zio, wsz);
+
+	} else {
+		wsz = lwb->lwb_sz;
+	}
+
+	zilc->zc_pad = 0;
+	zilc->zc_nused = lwb->lwb_nused;
+	zilc->zc_eck.zec_cksum = lwb->lwb_blk.blk_cksum;
+
+	/*
+	 * clear unused data for security
+	 */
+	bzero(lwb->lwb_buf + lwb->lwb_nused, wsz - lwb->lwb_nused);
+
+	zio_nowait(lwb->lwb_zio); /* Kick off the write for the old log block */
+
+	/*
+	 * If there was an allocation failure then nlwb will be null which
+	 * forces a txg_wait_synced().
+	 */
+	return (nlwb);
+}
+
+static lwb_t *
+zil_lwb_commit(zilog_t *zilog, itx_t *itx, lwb_t *lwb)
+{
+	lr_t *lrc = &itx->itx_lr; /* common log record */
+	lr_write_t *lrw = (lr_write_t *)lrc;
+	char *lr_buf;
+	uint64_t txg = lrc->lrc_txg;
+	uint64_t reclen = lrc->lrc_reclen;
+	uint64_t dlen = 0;
+
+	if (lwb == NULL)
+		return (NULL);
+
+	ASSERT(lwb->lwb_buf != NULL);
+	ASSERT(zilog_is_dirty(zilog) ||
+	    spa_freeze_txg(zilog->zl_spa) != UINT64_MAX);
+
+	if (lrc->lrc_txtype == TX_WRITE && itx->itx_wr_state == WR_NEED_COPY)
+		dlen = P2ROUNDUP_TYPED(
+		    lrw->lr_length, sizeof (uint64_t), uint64_t);
+
+	zilog->zl_cur_used += (reclen + dlen);
+
+	zil_lwb_write_init(zilog, lwb);
+
+	/*
+	 * If this record won't fit in the current log block, start a new one.
+	 */
+	if (lwb->lwb_nused + reclen + dlen > lwb->lwb_sz) {
+		lwb = zil_lwb_write_start(zilog, lwb);
+		if (lwb == NULL)
+			return (NULL);
+		zil_lwb_write_init(zilog, lwb);
+		ASSERT(LWB_EMPTY(lwb));
+		if (lwb->lwb_nused + reclen + dlen > lwb->lwb_sz) {
+			txg_wait_synced(zilog->zl_dmu_pool, txg);
+			return (lwb);
+		}
+	}
+
+	lr_buf = lwb->lwb_buf + lwb->lwb_nused;
+	bcopy(lrc, lr_buf, reclen);
+	lrc = (lr_t *)lr_buf;
+	lrw = (lr_write_t *)lrc;
+
+	ZIL_STAT_BUMP(zil_itx_count);
+
+	/*
+	 * If it's a write, fetch the data or get its blkptr as appropriate.
+	 */
+	if (lrc->lrc_txtype == TX_WRITE) {
+		if (txg > spa_freeze_txg(zilog->zl_spa))
+			txg_wait_synced(zilog->zl_dmu_pool, txg);
+		if (itx->itx_wr_state == WR_COPIED) {
+			ZIL_STAT_BUMP(zil_itx_copied_count);
+			ZIL_STAT_INCR(zil_itx_copied_bytes, lrw->lr_length);
+		} else {
+			char *dbuf;
+			int error;
+
+			if (dlen) {
+				ASSERT(itx->itx_wr_state == WR_NEED_COPY);
+				dbuf = lr_buf + reclen;
+				lrw->lr_common.lrc_reclen += dlen;
+				ZIL_STAT_BUMP(zil_itx_needcopy_count);
+				ZIL_STAT_INCR(zil_itx_needcopy_bytes,
+				    lrw->lr_length);
+			} else {
+				ASSERT(itx->itx_wr_state == WR_INDIRECT);
+				dbuf = NULL;
+				ZIL_STAT_BUMP(zil_itx_indirect_count);
+				ZIL_STAT_INCR(zil_itx_indirect_bytes,
+				    lrw->lr_length);
+			}
+			error = zilog->zl_get_data(
+			    itx->itx_private, lrw, dbuf, lwb->lwb_zio);
+			if (error == EIO) {
+				txg_wait_synced(zilog->zl_dmu_pool, txg);
+				return (lwb);
+			}
+			if (error != 0) {
+				ASSERT(error == ENOENT || error == EEXIST ||
+				    error == EALREADY);
+				return (lwb);
+			}
+		}
+	}
+
+	/*
+	 * We're actually making an entry, so update lrc_seq to be the
+	 * log record sequence number.  Note that this is generally not
+	 * equal to the itx sequence number because not all transactions
+	 * are synchronous, and sometimes spa_sync() gets there first.
+	 */
+	lrc->lrc_seq = ++zilog->zl_lr_seq; /* we are single threaded */
+	lwb->lwb_nused += reclen + dlen;
+	lwb->lwb_max_txg = MAX(lwb->lwb_max_txg, txg);
+	ASSERT3U(lwb->lwb_nused, <=, lwb->lwb_sz);
+	ASSERT0(P2PHASE(lwb->lwb_nused, sizeof (uint64_t)));
+
+	return (lwb);
+}
+
+itx_t *
+zil_itx_create(uint64_t txtype, size_t lrsize)
+{
+	itx_t *itx;
+
+	lrsize = P2ROUNDUP_TYPED(lrsize, sizeof (uint64_t), size_t);
+
+	itx = zio_data_buf_alloc(offsetof(itx_t, itx_lr) + lrsize);
+	itx->itx_lr.lrc_txtype = txtype;
+	itx->itx_lr.lrc_reclen = lrsize;
+	itx->itx_sod = lrsize; /* if write & WR_NEED_COPY will be increased */
+	itx->itx_lr.lrc_seq = 0;	/* defensive */
+	itx->itx_sync = B_TRUE;		/* default is synchronous */
+	itx->itx_callback = NULL;
+	itx->itx_callback_data = NULL;
+
+	return (itx);
+}
+
+void
+zil_itx_destroy(itx_t *itx)
+{
+	zio_data_buf_free(itx, offsetof(itx_t, itx_lr)+itx->itx_lr.lrc_reclen);
+}
+
+/*
+ * Free up the sync and async itxs. The itxs_t has already been detached
+ * so no locks are needed.
+ */
+static void
+zil_itxg_clean(itxs_t *itxs)
+{
+	itx_t *itx;
+	list_t *list;
+	avl_tree_t *t;
+	void *cookie;
+	itx_async_node_t *ian;
+
+	list = &itxs->i_sync_list;
+	while ((itx = list_head(list)) != NULL) {
+		if (itx->itx_callback != NULL)
+			itx->itx_callback(itx->itx_callback_data);
+		list_remove(list, itx);
+		zil_itx_destroy(itx);
+	}
+
+	cookie = NULL;
+	t = &itxs->i_async_tree;
+	while ((ian = avl_destroy_nodes(t, &cookie)) != NULL) {
+		list = &ian->ia_list;
+		while ((itx = list_head(list)) != NULL) {
+			if (itx->itx_callback != NULL)
+				itx->itx_callback(itx->itx_callback_data);
+			list_remove(list, itx);
+			zil_itx_destroy(itx);
+		}
+		list_destroy(list);
+		kmem_free(ian, sizeof (itx_async_node_t));
+	}
+	avl_destroy(t);
+
+	kmem_free(itxs, sizeof (itxs_t));
+}
+
+static int
+zil_aitx_compare(const void *x1, const void *x2)
+{
+	const uint64_t o1 = ((itx_async_node_t *)x1)->ia_foid;
+	const uint64_t o2 = ((itx_async_node_t *)x2)->ia_foid;
+
+	if (o1 < o2)
+		return (-1);
+	if (o1 > o2)
+		return (1);
+
+	return (0);
+}
+
+/*
+ * Remove all async itx with the given oid.
+ */
+static void
+zil_remove_async(zilog_t *zilog, uint64_t oid)
+{
+	uint64_t otxg, txg;
+	itx_async_node_t *ian;
+	avl_tree_t *t;
+	avl_index_t where;
+	list_t clean_list;
+	itx_t *itx;
+
+	ASSERT(oid != 0);
+	list_create(&clean_list, sizeof (itx_t), offsetof(itx_t, itx_node));
+
+	if (spa_freeze_txg(zilog->zl_spa) != UINT64_MAX) /* ziltest support */
+		otxg = ZILTEST_TXG;
+	else
+		otxg = spa_last_synced_txg(zilog->zl_spa) + 1;
+
+	for (txg = otxg; txg < (otxg + TXG_CONCURRENT_STATES); txg++) {
+		itxg_t *itxg = &zilog->zl_itxg[txg & TXG_MASK];
+
+		mutex_enter(&itxg->itxg_lock);
+		if (itxg->itxg_txg != txg) {
+			mutex_exit(&itxg->itxg_lock);
+			continue;
+		}
+
+		/*
+		 * Locate the object node and append its list.
+		 */
+		t = &itxg->itxg_itxs->i_async_tree;
+		ian = avl_find(t, &oid, &where);
+		if (ian != NULL)
+			list_move_tail(&clean_list, &ian->ia_list);
+		mutex_exit(&itxg->itxg_lock);
+	}
+	while ((itx = list_head(&clean_list)) != NULL) {
+		if (itx->itx_callback != NULL)
+			itx->itx_callback(itx->itx_callback_data);
+		list_remove(&clean_list, itx);
+		zil_itx_destroy(itx);
+	}
+	list_destroy(&clean_list);
+}
+
+void
+zil_itx_assign(zilog_t *zilog, itx_t *itx, dmu_tx_t *tx)
+{
+	uint64_t txg;
+	itxg_t *itxg;
+	itxs_t *itxs, *clean = NULL;
+
+	/*
+	 * Object ids can be re-instantiated in the next txg so
+	 * remove any async transactions to avoid future leaks.
+	 * This can happen if a fsync occurs on the re-instantiated
+	 * object for a WR_INDIRECT or WR_NEED_COPY write, which gets
+	 * the new file data and flushes a write record for the old object.
+	 */
+	if ((itx->itx_lr.lrc_txtype & ~TX_CI) == TX_REMOVE)
+		zil_remove_async(zilog, itx->itx_oid);
+
+	/*
+	 * Ensure the data of a renamed file is committed before the rename.
+	 */
+	if ((itx->itx_lr.lrc_txtype & ~TX_CI) == TX_RENAME)
+		zil_async_to_sync(zilog, itx->itx_oid);
+
+	if (spa_freeze_txg(zilog->zl_spa) != UINT64_MAX)
+		txg = ZILTEST_TXG;
+	else
+		txg = dmu_tx_get_txg(tx);
+
+	itxg = &zilog->zl_itxg[txg & TXG_MASK];
+	mutex_enter(&itxg->itxg_lock);
+	itxs = itxg->itxg_itxs;
+	if (itxg->itxg_txg != txg) {
+		if (itxs != NULL) {
+			/*
+			 * The zil_clean callback hasn't got around to cleaning
+			 * this itxg. Save the itxs for release below.
+			 * This should be rare.
+			 */
+			atomic_add_64(&zilog->zl_itx_list_sz, -itxg->itxg_sod);
+			itxg->itxg_sod = 0;
+			clean = itxg->itxg_itxs;
+		}
+		ASSERT(itxg->itxg_sod == 0);
+		itxg->itxg_txg = txg;
+		itxs = itxg->itxg_itxs = kmem_zalloc(sizeof (itxs_t),
+		    KM_SLEEP);
+
+		list_create(&itxs->i_sync_list, sizeof (itx_t),
+		    offsetof(itx_t, itx_node));
+		avl_create(&itxs->i_async_tree, zil_aitx_compare,
+		    sizeof (itx_async_node_t),
+		    offsetof(itx_async_node_t, ia_node));
+	}
+	if (itx->itx_sync) {
+		list_insert_tail(&itxs->i_sync_list, itx);
+		atomic_add_64(&zilog->zl_itx_list_sz, itx->itx_sod);
+		itxg->itxg_sod += itx->itx_sod;
+	} else {
+		avl_tree_t *t = &itxs->i_async_tree;
+		uint64_t foid = ((lr_ooo_t *)&itx->itx_lr)->lr_foid;
+		itx_async_node_t *ian;
+		avl_index_t where;
+
+		ian = avl_find(t, &foid, &where);
+		if (ian == NULL) {
+			ian = kmem_alloc(sizeof (itx_async_node_t),
+			    KM_SLEEP);
+			list_create(&ian->ia_list, sizeof (itx_t),
+			    offsetof(itx_t, itx_node));
+			ian->ia_foid = foid;
+			avl_insert(t, ian, where);
+		}
+		list_insert_tail(&ian->ia_list, itx);
+	}
+
+	itx->itx_lr.lrc_txg = dmu_tx_get_txg(tx);
+	zilog_dirty(zilog, txg);
+	mutex_exit(&itxg->itxg_lock);
+
+	/* Release the old itxs now we've dropped the lock */
+	if (clean != NULL)
+		zil_itxg_clean(clean);
+}
+
+/*
+ * If there are any in-memory intent log transactions which have now been
+ * synced then start up a taskq to free them. We should only do this after we
+ * have written out the uberblocks (i.e. txg has been comitted) so that
+ * don't inadvertently clean out in-memory log records that would be required
+ * by zil_commit().
+ */
+void
+zil_clean(zilog_t *zilog, uint64_t synced_txg)
+{
+	itxg_t *itxg = &zilog->zl_itxg[synced_txg & TXG_MASK];
+	itxs_t *clean_me;
+
+	mutex_enter(&itxg->itxg_lock);
+	if (itxg->itxg_itxs == NULL || itxg->itxg_txg == ZILTEST_TXG) {
+		mutex_exit(&itxg->itxg_lock);
+		return;
+	}
+	ASSERT3U(itxg->itxg_txg, <=, synced_txg);
+	ASSERT(itxg->itxg_txg != 0);
+	ASSERT(zilog->zl_clean_taskq != NULL);
+	atomic_add_64(&zilog->zl_itx_list_sz, -itxg->itxg_sod);
+	itxg->itxg_sod = 0;
+	clean_me = itxg->itxg_itxs;
+	itxg->itxg_itxs = NULL;
+	itxg->itxg_txg = 0;
+	mutex_exit(&itxg->itxg_lock);
+	/*
+	 * Preferably start a task queue to free up the old itxs but
+	 * if taskq_dispatch can't allocate resources to do that then
+	 * free it in-line. This should be rare. Note, using TQ_SLEEP
+	 * created a bad performance problem.
+	 */
+	if (taskq_dispatch(zilog->zl_clean_taskq,
+	    (void (*)(void *))zil_itxg_clean, clean_me, TQ_NOSLEEP) == 0)
+		zil_itxg_clean(clean_me);
+}
+
+/*
+ * Get the list of itxs to commit into zl_itx_commit_list.
+ */
+static void
+zil_get_commit_list(zilog_t *zilog)
+{
+	uint64_t otxg, txg;
+	list_t *commit_list = &zilog->zl_itx_commit_list;
+	uint64_t push_sod = 0;
+
+	if (spa_freeze_txg(zilog->zl_spa) != UINT64_MAX) /* ziltest support */
+		otxg = ZILTEST_TXG;
+	else
+		otxg = spa_last_synced_txg(zilog->zl_spa) + 1;
+
+	for (txg = otxg; txg < (otxg + TXG_CONCURRENT_STATES); txg++) {
+		itxg_t *itxg = &zilog->zl_itxg[txg & TXG_MASK];
+
+		mutex_enter(&itxg->itxg_lock);
+		if (itxg->itxg_txg != txg) {
+			mutex_exit(&itxg->itxg_lock);
+			continue;
+		}
+
+		list_move_tail(commit_list, &itxg->itxg_itxs->i_sync_list);
+		push_sod += itxg->itxg_sod;
+		itxg->itxg_sod = 0;
+
+		mutex_exit(&itxg->itxg_lock);
+	}
+	atomic_add_64(&zilog->zl_itx_list_sz, -push_sod);
+}
+
+/*
+ * Move the async itxs for a specified object to commit into sync lists.
+ */
+static void
+zil_async_to_sync(zilog_t *zilog, uint64_t foid)
+{
+	uint64_t otxg, txg;
+	itx_async_node_t *ian;
+	avl_tree_t *t;
+	avl_index_t where;
+
+	if (spa_freeze_txg(zilog->zl_spa) != UINT64_MAX) /* ziltest support */
+		otxg = ZILTEST_TXG;
+	else
+		otxg = spa_last_synced_txg(zilog->zl_spa) + 1;
+
+	for (txg = otxg; txg < (otxg + TXG_CONCURRENT_STATES); txg++) {
+		itxg_t *itxg = &zilog->zl_itxg[txg & TXG_MASK];
+
+		mutex_enter(&itxg->itxg_lock);
+		if (itxg->itxg_txg != txg) {
+			mutex_exit(&itxg->itxg_lock);
+			continue;
+		}
+
+		/*
+		 * If a foid is specified then find that node and append its
+		 * list. Otherwise walk the tree appending all the lists
+		 * to the sync list. We add to the end rather than the
+		 * beginning to ensure the create has happened.
+		 */
+		t = &itxg->itxg_itxs->i_async_tree;
+		if (foid != 0) {
+			ian = avl_find(t, &foid, &where);
+			if (ian != NULL) {
+				list_move_tail(&itxg->itxg_itxs->i_sync_list,
+				    &ian->ia_list);
+			}
+		} else {
+			void *cookie = NULL;
+
+			while ((ian = avl_destroy_nodes(t, &cookie)) != NULL) {
+				list_move_tail(&itxg->itxg_itxs->i_sync_list,
+				    &ian->ia_list);
+				list_destroy(&ian->ia_list);
+				kmem_free(ian, sizeof (itx_async_node_t));
+			}
+		}
+		mutex_exit(&itxg->itxg_lock);
+	}
+}
+
+static void
+zil_commit_writer(zilog_t *zilog)
+{
+	uint64_t txg;
+	itx_t *itx;
+	lwb_t *lwb;
+	spa_t *spa = zilog->zl_spa;
+	int error = 0;
+
+	ASSERT(zilog->zl_root_zio == NULL);
+
+	mutex_exit(&zilog->zl_lock);
+
+	zil_get_commit_list(zilog);
+
+	/*
+	 * Return if there's nothing to commit before we dirty the fs by
+	 * calling zil_create().
+	 */
+	if (list_head(&zilog->zl_itx_commit_list) == NULL) {
+		mutex_enter(&zilog->zl_lock);
+		return;
+	}
+
+	if (zilog->zl_suspend) {
+		lwb = NULL;
+	} else {
+		lwb = list_tail(&zilog->zl_lwb_list);
+		if (lwb == NULL)
+			lwb = zil_create(zilog);
+	}
+
+	DTRACE_PROBE1(zil__cw1, zilog_t *, zilog);
+	for (itx = list_head(&zilog->zl_itx_commit_list); itx != NULL;
+	    itx = list_next(&zilog->zl_itx_commit_list, itx)) {
+		txg = itx->itx_lr.lrc_txg;
+		ASSERT(txg);
+
+		if (txg > spa_last_synced_txg(spa) || txg > spa_freeze_txg(spa))
+			lwb = zil_lwb_commit(zilog, itx, lwb);
+	}
+	DTRACE_PROBE1(zil__cw2, zilog_t *, zilog);
+
+	/* write the last block out */
+	if (lwb != NULL && lwb->lwb_zio != NULL)
+		lwb = zil_lwb_write_start(zilog, lwb);
+
+	zilog->zl_cur_used = 0;
+
+	/*
+	 * Wait if necessary for the log blocks to be on stable storage.
+	 */
+	if (zilog->zl_root_zio) {
+		error = zio_wait(zilog->zl_root_zio);
+		zilog->zl_root_zio = NULL;
+		zil_flush_vdevs(zilog);
+	}
+
+	if (error || lwb == NULL)
+		txg_wait_synced(zilog->zl_dmu_pool, 0);
+
+	while ((itx = list_head(&zilog->zl_itx_commit_list))) {
+		txg = itx->itx_lr.lrc_txg;
+		ASSERT(txg);
+
+		if (itx->itx_callback != NULL)
+			itx->itx_callback(itx->itx_callback_data);
+		list_remove(&zilog->zl_itx_commit_list, itx);
+		zil_itx_destroy(itx);
+	}
+
+	mutex_enter(&zilog->zl_lock);
+
+	/*
+	 * Remember the highest committed log sequence number for ztest.
+	 * We only update this value when all the log writes succeeded,
+	 * because ztest wants to ASSERT that it got the whole log chain.
+	 */
+	if (error == 0 && lwb != NULL)
+		zilog->zl_commit_lr_seq = zilog->zl_lr_seq;
+}
+
+/*
+ * Commit zfs transactions to stable storage.
+ * If foid is 0 push out all transactions, otherwise push only those
+ * for that object or might reference that object.
+ *
+ * itxs are committed in batches. In a heavily stressed zil there will be
+ * a commit writer thread who is writing out a bunch of itxs to the log
+ * for a set of committing threads (cthreads) in the same batch as the writer.
+ * Those cthreads are all waiting on the same cv for that batch.
+ *
+ * There will also be a different and growing batch of threads that are
+ * waiting to commit (qthreads). When the committing batch completes
+ * a transition occurs such that the cthreads exit and the qthreads become
+ * cthreads. One of the new cthreads becomes the writer thread for the
+ * batch. Any new threads arriving become new qthreads.
+ *
+ * Only 2 condition variables are needed and there's no transition
+ * between the two cvs needed. They just flip-flop between qthreads
+ * and cthreads.
+ *
+ * Using this scheme we can efficiently wakeup up only those threads
+ * that have been committed.
+ */
+void
+zil_commit(zilog_t *zilog, uint64_t foid)
+{
+	uint64_t mybatch;
+
+	if (zilog->zl_sync == ZFS_SYNC_DISABLED)
+		return;
+
+	ZIL_STAT_BUMP(zil_commit_count);
+
+	/* move the async itxs for the foid to the sync queues */
+	zil_async_to_sync(zilog, foid);
+
+	mutex_enter(&zilog->zl_lock);
+	mybatch = zilog->zl_next_batch;
+	while (zilog->zl_writer) {
+		cv_wait(&zilog->zl_cv_batch[mybatch & 1], &zilog->zl_lock);
+		if (mybatch <= zilog->zl_com_batch) {
+			mutex_exit(&zilog->zl_lock);
+			return;
+		}
+	}
+
+	zilog->zl_next_batch++;
+	zilog->zl_writer = B_TRUE;
+	ZIL_STAT_BUMP(zil_commit_writer_count);
+	zil_commit_writer(zilog);
+	zilog->zl_com_batch = mybatch;
+	zilog->zl_writer = B_FALSE;
+
+	/* wake up one thread to become the next writer */
+	cv_signal(&zilog->zl_cv_batch[(mybatch+1) & 1]);
+
+	/* wake up all threads waiting for this batch to be committed */
+	cv_broadcast(&zilog->zl_cv_batch[mybatch & 1]);
+
+	mutex_exit(&zilog->zl_lock);
+}
+
+/*
+ * Called in syncing context to free committed log blocks and update log header.
+ */
+void
+zil_sync(zilog_t *zilog, dmu_tx_t *tx)
+{
+	zil_header_t *zh = zil_header_in_syncing_context(zilog);
+	uint64_t txg = dmu_tx_get_txg(tx);
+	spa_t *spa = zilog->zl_spa;
+	uint64_t *replayed_seq = &zilog->zl_replayed_seq[txg & TXG_MASK];
+	lwb_t *lwb;
+
+	/*
+	 * We don't zero out zl_destroy_txg, so make sure we don't try
+	 * to destroy it twice.
+	 */
+	if (spa_sync_pass(spa) != 1)
+		return;
+
+	mutex_enter(&zilog->zl_lock);
+
+	ASSERT(zilog->zl_stop_sync == 0);
+
+	if (*replayed_seq != 0) {
+		ASSERT(zh->zh_replay_seq < *replayed_seq);
+		zh->zh_replay_seq = *replayed_seq;
+		*replayed_seq = 0;
+	}
+
+	if (zilog->zl_destroy_txg == txg) {
+		blkptr_t blk = zh->zh_log;
+
+		ASSERT(list_head(&zilog->zl_lwb_list) == NULL);
+
+		bzero(zh, sizeof (zil_header_t));
+		bzero(zilog->zl_replayed_seq, sizeof (zilog->zl_replayed_seq));
+
+		if (zilog->zl_keep_first) {
+			/*
+			 * If this block was part of log chain that couldn't
+			 * be claimed because a device was missing during
+			 * zil_claim(), but that device later returns,
+			 * then this block could erroneously appear valid.
+			 * To guard against this, assign a new GUID to the new
+			 * log chain so it doesn't matter what blk points to.
+			 */
+			zil_init_log_chain(zilog, &blk);
+			zh->zh_log = blk;
+		}
+	}
+
+	while ((lwb = list_head(&zilog->zl_lwb_list)) != NULL) {
+		zh->zh_log = lwb->lwb_blk;
+		if (lwb->lwb_buf != NULL || lwb->lwb_max_txg > txg)
+			break;
+
+		ASSERT(lwb->lwb_zio == NULL);
+
+		list_remove(&zilog->zl_lwb_list, lwb);
+		zio_free_zil(spa, txg, &lwb->lwb_blk);
+		kmem_cache_free(zil_lwb_cache, lwb);
+
+		/*
+		 * If we don't have anything left in the lwb list then
+		 * we've had an allocation failure and we need to zero
+		 * out the zil_header blkptr so that we don't end
+		 * up freeing the same block twice.
+		 */
+		if (list_head(&zilog->zl_lwb_list) == NULL)
+			BP_ZERO(&zh->zh_log);
+	}
+
+	/*
+	 * Remove fastwrite on any blocks that have been pre-allocated for
+	 * the next commit. This prevents fastwrite counter pollution by
+	 * unused, long-lived LWBs.
+	 */
+	for (; lwb != NULL; lwb = list_next(&zilog->zl_lwb_list, lwb)) {
+		if (lwb->lwb_fastwrite && !lwb->lwb_zio) {
+			metaslab_fastwrite_unmark(zilog->zl_spa, &lwb->lwb_blk);
+			lwb->lwb_fastwrite = 0;
+		}
+	}
+
+	mutex_exit(&zilog->zl_lock);
+}
+
+void
+zil_init(void)
+{
+	zil_lwb_cache = kmem_cache_create("zil_lwb_cache",
+	    sizeof (struct lwb), 0, NULL, NULL, NULL, NULL, NULL, 0);
+
+	zil_ksp = kstat_create("zfs", 0, "zil", "misc",
+	    KSTAT_TYPE_NAMED, sizeof (zil_stats) / sizeof (kstat_named_t),
+	    KSTAT_FLAG_VIRTUAL);
+
+	if (zil_ksp != NULL) {
+		zil_ksp->ks_data = &zil_stats;
+		kstat_install(zil_ksp);
+	}
+}
+
+void
+zil_fini(void)
+{
+	kmem_cache_destroy(zil_lwb_cache);
+
+	if (zil_ksp != NULL) {
+		kstat_delete(zil_ksp);
+		zil_ksp = NULL;
+	}
+}
+
+void
+zil_set_sync(zilog_t *zilog, uint64_t sync)
+{
+	zilog->zl_sync = sync;
+}
+
+void
+zil_set_logbias(zilog_t *zilog, uint64_t logbias)
+{
+	zilog->zl_logbias = logbias;
+}
+
+zilog_t *
+zil_alloc(objset_t *os, zil_header_t *zh_phys)
+{
+	zilog_t *zilog;
+	int i;
+
+	zilog = kmem_zalloc(sizeof (zilog_t), KM_SLEEP);
+
+	zilog->zl_header = zh_phys;
+	zilog->zl_os = os;
+	zilog->zl_spa = dmu_objset_spa(os);
+	zilog->zl_dmu_pool = dmu_objset_pool(os);
+	zilog->zl_destroy_txg = TXG_INITIAL - 1;
+	zilog->zl_logbias = dmu_objset_logbias(os);
+	zilog->zl_sync = dmu_objset_syncprop(os);
+	zilog->zl_next_batch = 1;
+
+	mutex_init(&zilog->zl_lock, NULL, MUTEX_DEFAULT, NULL);
+
+	for (i = 0; i < TXG_SIZE; i++) {
+		mutex_init(&zilog->zl_itxg[i].itxg_lock, NULL,
+		    MUTEX_DEFAULT, NULL);
+	}
+
+	list_create(&zilog->zl_lwb_list, sizeof (lwb_t),
+	    offsetof(lwb_t, lwb_node));
+
+	list_create(&zilog->zl_itx_commit_list, sizeof (itx_t),
+	    offsetof(itx_t, itx_node));
+
+	mutex_init(&zilog->zl_vdev_lock, NULL, MUTEX_DEFAULT, NULL);
+
+	avl_create(&zilog->zl_vdev_tree, zil_vdev_compare,
+	    sizeof (zil_vdev_node_t), offsetof(zil_vdev_node_t, zv_node));
+
+	cv_init(&zilog->zl_cv_writer, NULL, CV_DEFAULT, NULL);
+	cv_init(&zilog->zl_cv_suspend, NULL, CV_DEFAULT, NULL);
+	cv_init(&zilog->zl_cv_batch[0], NULL, CV_DEFAULT, NULL);
+	cv_init(&zilog->zl_cv_batch[1], NULL, CV_DEFAULT, NULL);
+
+	return (zilog);
+}
+
+void
+zil_free(zilog_t *zilog)
+{
+	int i;
+
+	zilog->zl_stop_sync = 1;
+
+	ASSERT0(zilog->zl_suspend);
+	ASSERT0(zilog->zl_suspending);
+
+	ASSERT(list_is_empty(&zilog->zl_lwb_list));
+	list_destroy(&zilog->zl_lwb_list);
+
+	avl_destroy(&zilog->zl_vdev_tree);
+	mutex_destroy(&zilog->zl_vdev_lock);
+
+	ASSERT(list_is_empty(&zilog->zl_itx_commit_list));
+	list_destroy(&zilog->zl_itx_commit_list);
+
+	for (i = 0; i < TXG_SIZE; i++) {
+		/*
+		 * It's possible for an itx to be generated that doesn't dirty
+		 * a txg (e.g. ztest TX_TRUNCATE). So there's no zil_clean()
+		 * callback to remove the entry. We remove those here.
+		 *
+		 * Also free up the ziltest itxs.
+		 */
+		if (zilog->zl_itxg[i].itxg_itxs)
+			zil_itxg_clean(zilog->zl_itxg[i].itxg_itxs);
+		mutex_destroy(&zilog->zl_itxg[i].itxg_lock);
+	}
+
+	mutex_destroy(&zilog->zl_lock);
+
+	cv_destroy(&zilog->zl_cv_writer);
+	cv_destroy(&zilog->zl_cv_suspend);
+	cv_destroy(&zilog->zl_cv_batch[0]);
+	cv_destroy(&zilog->zl_cv_batch[1]);
+
+	kmem_free(zilog, sizeof (zilog_t));
+}
+
+/*
+ * Open an intent log.
+ */
+zilog_t *
+zil_open(objset_t *os, zil_get_data_t *get_data)
+{
+	zilog_t *zilog = dmu_objset_zil(os);
+
+	ASSERT(zilog->zl_clean_taskq == NULL);
+	ASSERT(zilog->zl_get_data == NULL);
+	ASSERT(list_is_empty(&zilog->zl_lwb_list));
+
+	zilog->zl_get_data = get_data;
+	zilog->zl_clean_taskq = taskq_create("zil_clean", 1, defclsyspri,
+	    2, 2, TASKQ_PREPOPULATE);
+
+	return (zilog);
+}
+
+/*
+ * Close an intent log.
+ */
+void
+zil_close(zilog_t *zilog)
+{
+	lwb_t *lwb;
+	uint64_t txg = 0;
+
+	zil_commit(zilog, 0); /* commit all itx */
+
+	/*
+	 * The lwb_max_txg for the stubby lwb will reflect the last activity
+	 * for the zil.  After a txg_wait_synced() on the txg we know all the
+	 * callbacks have occurred that may clean the zil.  Only then can we
+	 * destroy the zl_clean_taskq.
+	 */
+	mutex_enter(&zilog->zl_lock);
+	lwb = list_tail(&zilog->zl_lwb_list);
+	if (lwb != NULL)
+		txg = lwb->lwb_max_txg;
+	mutex_exit(&zilog->zl_lock);
+	if (txg)
+		txg_wait_synced(zilog->zl_dmu_pool, txg);
+	ASSERT(!zilog_is_dirty(zilog));
+
+	taskq_destroy(zilog->zl_clean_taskq);
+	zilog->zl_clean_taskq = NULL;
+	zilog->zl_get_data = NULL;
+
+	/*
+	 * We should have only one LWB left on the list; remove it now.
+	 */
+	mutex_enter(&zilog->zl_lock);
+	lwb = list_head(&zilog->zl_lwb_list);
+	if (lwb != NULL) {
+		ASSERT(lwb == list_tail(&zilog->zl_lwb_list));
+		ASSERT(lwb->lwb_zio == NULL);
+		if (lwb->lwb_fastwrite)
+			metaslab_fastwrite_unmark(zilog->zl_spa, &lwb->lwb_blk);
+		list_remove(&zilog->zl_lwb_list, lwb);
+		zio_buf_free(lwb->lwb_buf, lwb->lwb_sz);
+		kmem_cache_free(zil_lwb_cache, lwb);
+	}
+	mutex_exit(&zilog->zl_lock);
+}
+
+static char *suspend_tag = "zil suspending";
+
+/*
+ * Suspend an intent log.  While in suspended mode, we still honor
+ * synchronous semantics, but we rely on txg_wait_synced() to do it.
+ * On old version pools, we suspend the log briefly when taking a
+ * snapshot so that it will have an empty intent log.
+ *
+ * Long holds are not really intended to be used the way we do here --
+ * held for such a short time.  A concurrent caller of dsl_dataset_long_held()
+ * could fail.  Therefore we take pains to only put a long hold if it is
+ * actually necessary.  Fortunately, it will only be necessary if the
+ * objset is currently mounted (or the ZVOL equivalent).  In that case it
+ * will already have a long hold, so we are not really making things any worse.
+ *
+ * Ideally, we would locate the existing long-holder (i.e. the zfsvfs_t or
+ * zvol_state_t), and use their mechanism to prevent their hold from being
+ * dropped (e.g. VFS_HOLD()).  However, that would be even more pain for
+ * very little gain.
+ *
+ * if cookiep == NULL, this does both the suspend & resume.
+ * Otherwise, it returns with the dataset "long held", and the cookie
+ * should be passed into zil_resume().
+ */
+int
+zil_suspend(const char *osname, void **cookiep)
+{
+	objset_t *os;
+	zilog_t *zilog;
+	const zil_header_t *zh;
+	int error;
+
+	error = dmu_objset_hold(osname, suspend_tag, &os);
+	if (error != 0)
+		return (error);
+	zilog = dmu_objset_zil(os);
+
+	mutex_enter(&zilog->zl_lock);
+	zh = zilog->zl_header;
+
+	if (zh->zh_flags & ZIL_REPLAY_NEEDED) {		/* unplayed log */
+		mutex_exit(&zilog->zl_lock);
+		dmu_objset_rele(os, suspend_tag);
+		return (SET_ERROR(EBUSY));
+	}
+
+	/*
+	 * Don't put a long hold in the cases where we can avoid it.  This
+	 * is when there is no cookie so we are doing a suspend & resume
+	 * (i.e. called from zil_vdev_offline()), and there's nothing to do
+	 * for the suspend because it's already suspended, or there's no ZIL.
+	 */
+	if (cookiep == NULL && !zilog->zl_suspending &&
+	    (zilog->zl_suspend > 0 || BP_IS_HOLE(&zh->zh_log))) {
+		mutex_exit(&zilog->zl_lock);
+		dmu_objset_rele(os, suspend_tag);
+		return (0);
+	}
+
+	dsl_dataset_long_hold(dmu_objset_ds(os), suspend_tag);
+	dsl_pool_rele(dmu_objset_pool(os), suspend_tag);
+
+	zilog->zl_suspend++;
+
+	if (zilog->zl_suspend > 1) {
+		/*
+		 * Someone else is already suspending it.
+		 * Just wait for them to finish.
+		 */
+
+		while (zilog->zl_suspending)
+			cv_wait(&zilog->zl_cv_suspend, &zilog->zl_lock);
+		mutex_exit(&zilog->zl_lock);
+
+		if (cookiep == NULL)
+			zil_resume(os);
+		else
+			*cookiep = os;
+		return (0);
+	}
+
+	/*
+	 * If there is no pointer to an on-disk block, this ZIL must not
+	 * be active (e.g. filesystem not mounted), so there's nothing
+	 * to clean up.
+	 */
+	if (BP_IS_HOLE(&zh->zh_log)) {
+		ASSERT(cookiep != NULL); /* fast path already handled */
+
+		*cookiep = os;
+		mutex_exit(&zilog->zl_lock);
+		return (0);
+	}
+
+	zilog->zl_suspending = B_TRUE;
+	mutex_exit(&zilog->zl_lock);
+
+	zil_commit(zilog, 0);
+
+	zil_destroy(zilog, B_FALSE);
+
+	mutex_enter(&zilog->zl_lock);
+	zilog->zl_suspending = B_FALSE;
+	cv_broadcast(&zilog->zl_cv_suspend);
+	mutex_exit(&zilog->zl_lock);
+
+	if (cookiep == NULL)
+		zil_resume(os);
+	else
+		*cookiep = os;
+	return (0);
+}
+
+void
+zil_resume(void *cookie)
+{
+	objset_t *os = cookie;
+	zilog_t *zilog = dmu_objset_zil(os);
+
+	mutex_enter(&zilog->zl_lock);
+	ASSERT(zilog->zl_suspend != 0);
+	zilog->zl_suspend--;
+	mutex_exit(&zilog->zl_lock);
+	dsl_dataset_long_rele(dmu_objset_ds(os), suspend_tag);
+	dsl_dataset_rele(dmu_objset_ds(os), suspend_tag);
+}
+
+typedef struct zil_replay_arg {
+	zil_replay_func_t *zr_replay;
+	void		*zr_arg;
+	boolean_t	zr_byteswap;
+	char		*zr_lr;
+} zil_replay_arg_t;
+
+static int
+zil_replay_error(zilog_t *zilog, lr_t *lr, int error)
+{
+	char name[MAXNAMELEN];
+
+	zilog->zl_replaying_seq--;	/* didn't actually replay this one */
+
+	dmu_objset_name(zilog->zl_os, name);
+
+	cmn_err(CE_WARN, "ZFS replay transaction error %d, "
+	    "dataset %s, seq 0x%llx, txtype %llu %s\n", error, name,
+	    (u_longlong_t)lr->lrc_seq,
+	    (u_longlong_t)(lr->lrc_txtype & ~TX_CI),
+	    (lr->lrc_txtype & TX_CI) ? "CI" : "");
+
+	return (error);
+}
+
+static int
+zil_replay_log_record(zilog_t *zilog, lr_t *lr, void *zra, uint64_t claim_txg)
+{
+	zil_replay_arg_t *zr = zra;
+	const zil_header_t *zh = zilog->zl_header;
+	uint64_t reclen = lr->lrc_reclen;
+	uint64_t txtype = lr->lrc_txtype;
+	int error = 0;
+
+	zilog->zl_replaying_seq = lr->lrc_seq;
+
+	if (lr->lrc_seq <= zh->zh_replay_seq)	/* already replayed */
+		return (0);
+
+	if (lr->lrc_txg < claim_txg)		/* already committed */
+		return (0);
+
+	/* Strip case-insensitive bit, still present in log record */
+	txtype &= ~TX_CI;
+
+	if (txtype == 0 || txtype >= TX_MAX_TYPE)
+		return (zil_replay_error(zilog, lr, EINVAL));
+
+	/*
+	 * If this record type can be logged out of order, the object
+	 * (lr_foid) may no longer exist.  That's legitimate, not an error.
+	 */
+	if (TX_OOO(txtype)) {
+		error = dmu_object_info(zilog->zl_os,
+		    ((lr_ooo_t *)lr)->lr_foid, NULL);
+		if (error == ENOENT || error == EEXIST)
+			return (0);
+	}
+
+	/*
+	 * Make a copy of the data so we can revise and extend it.
+	 */
+	bcopy(lr, zr->zr_lr, reclen);
+
+	/*
+	 * If this is a TX_WRITE with a blkptr, suck in the data.
+	 */
+	if (txtype == TX_WRITE && reclen == sizeof (lr_write_t)) {
+		error = zil_read_log_data(zilog, (lr_write_t *)lr,
+		    zr->zr_lr + reclen);
+		if (error != 0)
+			return (zil_replay_error(zilog, lr, error));
+	}
+
+	/*
+	 * The log block containing this lr may have been byteswapped
+	 * so that we can easily examine common fields like lrc_txtype.
+	 * However, the log is a mix of different record types, and only the
+	 * replay vectors know how to byteswap their records.  Therefore, if
+	 * the lr was byteswapped, undo it before invoking the replay vector.
+	 */
+	if (zr->zr_byteswap)
+		byteswap_uint64_array(zr->zr_lr, reclen);
+
+	/*
+	 * We must now do two things atomically: replay this log record,
+	 * and update the log header sequence number to reflect the fact that
+	 * we did so. At the end of each replay function the sequence number
+	 * is updated if we are in replay mode.
+	 */
+	error = zr->zr_replay[txtype](zr->zr_arg, zr->zr_lr, zr->zr_byteswap);
+	if (error != 0) {
+		/*
+		 * The DMU's dnode layer doesn't see removes until the txg
+		 * commits, so a subsequent claim can spuriously fail with
+		 * EEXIST. So if we receive any error we try syncing out
+		 * any removes then retry the transaction.  Note that we
+		 * specify B_FALSE for byteswap now, so we don't do it twice.
+		 */
+		txg_wait_synced(spa_get_dsl(zilog->zl_spa), 0);
+		error = zr->zr_replay[txtype](zr->zr_arg, zr->zr_lr, B_FALSE);
+		if (error != 0)
+			return (zil_replay_error(zilog, lr, error));
+	}
+	return (0);
+}
+
+/* ARGSUSED */
+static int
+zil_incr_blks(zilog_t *zilog, blkptr_t *bp, void *arg, uint64_t claim_txg)
+{
+	zilog->zl_replay_blks++;
+
+	return (0);
+}
+
+/*
+ * If this dataset has a non-empty intent log, replay it and destroy it.
+ */
+void
+zil_replay(objset_t *os, void *arg, zil_replay_func_t replay_func[TX_MAX_TYPE])
+{
+	zilog_t *zilog = dmu_objset_zil(os);
+	const zil_header_t *zh = zilog->zl_header;
+	zil_replay_arg_t zr;
+
+	if ((zh->zh_flags & ZIL_REPLAY_NEEDED) == 0) {
+		zil_destroy(zilog, B_TRUE);
+		return;
+	}
+
+	zr.zr_replay = replay_func;
+	zr.zr_arg = arg;
+	zr.zr_byteswap = BP_SHOULD_BYTESWAP(&zh->zh_log);
+	zr.zr_lr = vmem_alloc(2 * SPA_MAXBLOCKSIZE, KM_SLEEP);
+
+	/*
+	 * Wait for in-progress removes to sync before starting replay.
+	 */
+	txg_wait_synced(zilog->zl_dmu_pool, 0);
+
+	zilog->zl_replay = B_TRUE;
+	zilog->zl_replay_time = ddi_get_lbolt();
+	ASSERT(zilog->zl_replay_blks == 0);
+	(void) zil_parse(zilog, zil_incr_blks, zil_replay_log_record, &zr,
+	    zh->zh_claim_txg);
+	vmem_free(zr.zr_lr, 2 * SPA_MAXBLOCKSIZE);
+
+	zil_destroy(zilog, B_FALSE);
+	txg_wait_synced(zilog->zl_dmu_pool, zilog->zl_destroy_txg);
+	zilog->zl_replay = B_FALSE;
+}
+
+boolean_t
+zil_replaying(zilog_t *zilog, dmu_tx_t *tx)
+{
+	if (zilog->zl_sync == ZFS_SYNC_DISABLED)
+		return (B_TRUE);
+
+	if (zilog->zl_replay) {
+		dsl_dataset_dirty(dmu_objset_ds(zilog->zl_os), tx);
+		zilog->zl_replayed_seq[dmu_tx_get_txg(tx) & TXG_MASK] =
+		    zilog->zl_replaying_seq;
+		return (B_TRUE);
+	}
+
+	return (B_FALSE);
+}
+
+/* ARGSUSED */
+int
+zil_vdev_offline(const char *osname, void *arg)
+{
+	int error;
+
+	error = zil_suspend(osname, NULL);
+	if (error != 0)
+		return (SET_ERROR(EEXIST));
+	return (0);
+}
+
+#if defined(_KERNEL) && defined(HAVE_SPL)
+EXPORT_SYMBOL(zil_alloc);
+EXPORT_SYMBOL(zil_free);
+EXPORT_SYMBOL(zil_open);
+EXPORT_SYMBOL(zil_close);
+EXPORT_SYMBOL(zil_replay);
+EXPORT_SYMBOL(zil_replaying);
+EXPORT_SYMBOL(zil_destroy);
+EXPORT_SYMBOL(zil_destroy_sync);
+EXPORT_SYMBOL(zil_itx_create);
+EXPORT_SYMBOL(zil_itx_destroy);
+EXPORT_SYMBOL(zil_itx_assign);
+EXPORT_SYMBOL(zil_commit);
+EXPORT_SYMBOL(zil_vdev_offline);
+EXPORT_SYMBOL(zil_claim);
+EXPORT_SYMBOL(zil_check_log_chain);
+EXPORT_SYMBOL(zil_sync);
+EXPORT_SYMBOL(zil_clean);
+EXPORT_SYMBOL(zil_suspend);
+EXPORT_SYMBOL(zil_resume);
+EXPORT_SYMBOL(zil_add_block);
+EXPORT_SYMBOL(zil_bp_tree_add);
+EXPORT_SYMBOL(zil_set_sync);
+EXPORT_SYMBOL(zil_set_logbias);
+
+module_param(zil_replay_disable, int, 0644);
+MODULE_PARM_DESC(zil_replay_disable, "Disable intent logging replay");
+
+module_param(zfs_nocacheflush, int, 0644);
+MODULE_PARM_DESC(zfs_nocacheflush, "Disable cache flushes");
+
+module_param(zil_slog_limit, ulong, 0644);
+MODULE_PARM_DESC(zil_slog_limit, "Max commit bytes to separate log device");
+#endif
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/module/zfs/zio.c
@@ -0,0 +1,3496 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2015 by Delphix. All rights reserved.
+ * Copyright (c) 2011 Nexenta Systems, Inc. All rights reserved.
+ */
+
+#include <sys/sysmacros.h>
+#include <sys/zfs_context.h>
+#include <sys/fm/fs/zfs.h>
+#include <sys/spa.h>
+#include <sys/txg.h>
+#include <sys/spa_impl.h>
+#include <sys/vdev_impl.h>
+#include <sys/zio_impl.h>
+#include <sys/zio_compress.h>
+#include <sys/zio_checksum.h>
+#include <sys/dmu_objset.h>
+#include <sys/arc.h>
+#include <sys/ddt.h>
+#include <sys/blkptr.h>
+#include <sys/zfeature.h>
+
+/*
+ * ==========================================================================
+ * I/O type descriptions
+ * ==========================================================================
+ */
+const char *zio_type_name[ZIO_TYPES] = {
+	"z_null", "z_rd", "z_wr", "z_fr", "z_cl", "z_ioctl"
+};
+
+/*
+ * ==========================================================================
+ * I/O kmem caches
+ * ==========================================================================
+ */
+kmem_cache_t *zio_cache;
+kmem_cache_t *zio_link_cache;
+kmem_cache_t *zio_buf_cache[SPA_MAXBLOCKSIZE >> SPA_MINBLOCKSHIFT];
+kmem_cache_t *zio_data_buf_cache[SPA_MAXBLOCKSIZE >> SPA_MINBLOCKSHIFT];
+int zio_delay_max = ZIO_DELAY_MAX;
+
+#define	ZIO_PIPELINE_CONTINUE		0x100
+#define	ZIO_PIPELINE_STOP		0x101
+
+/*
+ * The following actions directly effect the spa's sync-to-convergence logic.
+ * The values below define the sync pass when we start performing the action.
+ * Care should be taken when changing these values as they directly impact
+ * spa_sync() performance. Tuning these values may introduce subtle performance
+ * pathologies and should only be done in the context of performance analysis.
+ * These tunables will eventually be removed and replaced with #defines once
+ * enough analysis has been done to determine optimal values.
+ *
+ * The 'zfs_sync_pass_deferred_free' pass must be greater than 1 to ensure that
+ * regular blocks are not deferred.
+ */
+int zfs_sync_pass_deferred_free = 2; /* defer frees starting in this pass */
+int zfs_sync_pass_dont_compress = 5; /* don't compress starting in this pass */
+int zfs_sync_pass_rewrite = 2; /* rewrite new bps starting in this pass */
+
+/*
+ * An allocating zio is one that either currently has the DVA allocate
+ * stage set or will have it later in its lifetime.
+ */
+#define	IO_IS_ALLOCATING(zio) ((zio)->io_orig_pipeline & ZIO_STAGE_DVA_ALLOCATE)
+
+int zio_requeue_io_start_cut_in_line = 1;
+
+#ifdef ZFS_DEBUG
+int zio_buf_debug_limit = 16384;
+#else
+int zio_buf_debug_limit = 0;
+#endif
+
+static inline void __zio_execute(zio_t *zio);
+
+void
+zio_init(void)
+{
+	size_t c;
+	vmem_t *data_alloc_arena = NULL;
+
+	zio_cache = kmem_cache_create("zio_cache",
+	    sizeof (zio_t), 0, NULL, NULL, NULL, NULL, NULL, 0);
+	zio_link_cache = kmem_cache_create("zio_link_cache",
+	    sizeof (zio_link_t), 0, NULL, NULL, NULL, NULL, NULL, 0);
+
+	/*
+	 * For small buffers, we want a cache for each multiple of
+	 * SPA_MINBLOCKSIZE.  For larger buffers, we want a cache
+	 * for each quarter-power of 2.
+	 */
+	for (c = 0; c < SPA_MAXBLOCKSIZE >> SPA_MINBLOCKSHIFT; c++) {
+		size_t size = (c + 1) << SPA_MINBLOCKSHIFT;
+		size_t p2 = size;
+		size_t align = 0;
+		size_t cflags = (size > zio_buf_debug_limit) ? KMC_NODEBUG : 0;
+
+#ifdef _ILP32
+		/*
+		 * Cache size limited to 1M on 32-bit platforms until ARC
+		 * buffers no longer require virtual address space.
+		 */
+		if (size > zfs_max_recordsize)
+			break;
+#endif
+
+		while (!ISP2(p2))
+			p2 &= p2 - 1;
+
+#ifndef _KERNEL
+		/*
+		 * If we are using watchpoints, put each buffer on its own page,
+		 * to eliminate the performance overhead of trapping to the
+		 * kernel when modifying a non-watched buffer that shares the
+		 * page with a watched buffer.
+		 */
+		if (arc_watch && !IS_P2ALIGNED(size, PAGESIZE))
+			continue;
+#endif
+		if (size <= 4 * SPA_MINBLOCKSIZE) {
+			align = SPA_MINBLOCKSIZE;
+		} else if (IS_P2ALIGNED(size, p2 >> 2)) {
+			align = MIN(p2 >> 2, PAGESIZE);
+		}
+
+		if (align != 0) {
+			char name[36];
+			(void) sprintf(name, "zio_buf_%lu", (ulong_t)size);
+			zio_buf_cache[c] = kmem_cache_create(name, size,
+			    align, NULL, NULL, NULL, NULL, NULL, cflags);
+
+			(void) sprintf(name, "zio_data_buf_%lu", (ulong_t)size);
+			zio_data_buf_cache[c] = kmem_cache_create(name, size,
+			    align, NULL, NULL, NULL, NULL,
+			    data_alloc_arena, cflags);
+		}
+	}
+
+	while (--c != 0) {
+		ASSERT(zio_buf_cache[c] != NULL);
+		if (zio_buf_cache[c - 1] == NULL)
+			zio_buf_cache[c - 1] = zio_buf_cache[c];
+
+		ASSERT(zio_data_buf_cache[c] != NULL);
+		if (zio_data_buf_cache[c - 1] == NULL)
+			zio_data_buf_cache[c - 1] = zio_data_buf_cache[c];
+	}
+
+	zio_inject_init();
+
+	lz4_init();
+}
+
+void
+zio_fini(void)
+{
+	size_t c;
+	kmem_cache_t *last_cache = NULL;
+	kmem_cache_t *last_data_cache = NULL;
+
+	for (c = 0; c < SPA_MAXBLOCKSIZE >> SPA_MINBLOCKSHIFT; c++) {
+#ifdef _ILP32
+		/*
+		 * Cache size limited to 1M on 32-bit platforms until ARC
+		 * buffers no longer require virtual address space.
+		 */
+		if (((c + 1) << SPA_MINBLOCKSHIFT) > zfs_max_recordsize)
+			break;
+#endif
+		if (zio_buf_cache[c] != last_cache) {
+			last_cache = zio_buf_cache[c];
+			kmem_cache_destroy(zio_buf_cache[c]);
+		}
+		zio_buf_cache[c] = NULL;
+
+		if (zio_data_buf_cache[c] != last_data_cache) {
+			last_data_cache = zio_data_buf_cache[c];
+			kmem_cache_destroy(zio_data_buf_cache[c]);
+		}
+		zio_data_buf_cache[c] = NULL;
+	}
+
+	kmem_cache_destroy(zio_link_cache);
+	kmem_cache_destroy(zio_cache);
+
+	zio_inject_fini();
+
+	lz4_fini();
+}
+
+/*
+ * ==========================================================================
+ * Allocate and free I/O buffers
+ * ==========================================================================
+ */
+
+/*
+ * Use zio_buf_alloc to allocate ZFS metadata.  This data will appear in a
+ * crashdump if the kernel panics, so use it judiciously.  Obviously, it's
+ * useful to inspect ZFS metadata, but if possible, we should avoid keeping
+ * excess / transient data in-core during a crashdump.
+ */
+void *
+zio_buf_alloc(size_t size)
+{
+	size_t c = (size - 1) >> SPA_MINBLOCKSHIFT;
+
+	VERIFY3U(c, <, SPA_MAXBLOCKSIZE >> SPA_MINBLOCKSHIFT);
+
+	return (kmem_cache_alloc(zio_buf_cache[c], KM_PUSHPAGE));
+}
+
+/*
+ * Use zio_data_buf_alloc to allocate data.  The data will not appear in a
+ * crashdump if the kernel panics.  This exists so that we will limit the amount
+ * of ZFS data that shows up in a kernel crashdump.  (Thus reducing the amount
+ * of kernel heap dumped to disk when the kernel panics)
+ */
+void *
+zio_data_buf_alloc(size_t size)
+{
+	size_t c = (size - 1) >> SPA_MINBLOCKSHIFT;
+
+	VERIFY3U(c, <, SPA_MAXBLOCKSIZE >> SPA_MINBLOCKSHIFT);
+
+	return (kmem_cache_alloc(zio_data_buf_cache[c], KM_PUSHPAGE));
+}
+
+/*
+ * Use zio_buf_alloc_flags when specific allocation flags are needed.  e.g.
+ * passing KM_NOSLEEP when it is acceptable for an allocation to fail.
+ */
+void *
+zio_buf_alloc_flags(size_t size, int flags)
+{
+	size_t c = (size - 1) >> SPA_MINBLOCKSHIFT;
+
+	VERIFY3U(c, <, SPA_MAXBLOCKSIZE >> SPA_MINBLOCKSHIFT);
+
+	return (kmem_cache_alloc(zio_buf_cache[c], flags));
+}
+
+void
+zio_buf_free(void *buf, size_t size)
+{
+	size_t c = (size - 1) >> SPA_MINBLOCKSHIFT;
+
+	VERIFY3U(c, <, SPA_MAXBLOCKSIZE >> SPA_MINBLOCKSHIFT);
+
+	kmem_cache_free(zio_buf_cache[c], buf);
+}
+
+void
+zio_data_buf_free(void *buf, size_t size)
+{
+	size_t c = (size - 1) >> SPA_MINBLOCKSHIFT;
+
+	VERIFY3U(c, <, SPA_MAXBLOCKSIZE >> SPA_MINBLOCKSHIFT);
+
+	kmem_cache_free(zio_data_buf_cache[c], buf);
+}
+
+/*
+ * ==========================================================================
+ * Push and pop I/O transform buffers
+ * ==========================================================================
+ */
+static void
+zio_push_transform(zio_t *zio, void *data, uint64_t size, uint64_t bufsize,
+	zio_transform_func_t *transform)
+{
+	zio_transform_t *zt = kmem_alloc(sizeof (zio_transform_t), KM_SLEEP);
+
+	zt->zt_orig_data = zio->io_data;
+	zt->zt_orig_size = zio->io_size;
+	zt->zt_bufsize = bufsize;
+	zt->zt_transform = transform;
+
+	zt->zt_next = zio->io_transform_stack;
+	zio->io_transform_stack = zt;
+
+	zio->io_data = data;
+	zio->io_size = size;
+}
+
+static void
+zio_pop_transforms(zio_t *zio)
+{
+	zio_transform_t *zt;
+
+	while ((zt = zio->io_transform_stack) != NULL) {
+		if (zt->zt_transform != NULL)
+			zt->zt_transform(zio,
+			    zt->zt_orig_data, zt->zt_orig_size);
+
+		if (zt->zt_bufsize != 0)
+			zio_buf_free(zio->io_data, zt->zt_bufsize);
+
+		zio->io_data = zt->zt_orig_data;
+		zio->io_size = zt->zt_orig_size;
+		zio->io_transform_stack = zt->zt_next;
+
+		kmem_free(zt, sizeof (zio_transform_t));
+	}
+}
+
+/*
+ * ==========================================================================
+ * I/O transform callbacks for subblocks and decompression
+ * ==========================================================================
+ */
+static void
+zio_subblock(zio_t *zio, void *data, uint64_t size)
+{
+	ASSERT(zio->io_size > size);
+
+	if (zio->io_type == ZIO_TYPE_READ)
+		bcopy(zio->io_data, data, size);
+}
+
+static void
+zio_decompress(zio_t *zio, void *data, uint64_t size)
+{
+	if (zio->io_error == 0 &&
+	    zio_decompress_data(BP_GET_COMPRESS(zio->io_bp),
+	    zio->io_data, data, zio->io_size, size) != 0)
+		zio->io_error = SET_ERROR(EIO);
+}
+
+/*
+ * ==========================================================================
+ * I/O parent/child relationships and pipeline interlocks
+ * ==========================================================================
+ */
+/*
+ * NOTE - Callers to zio_walk_parents() and zio_walk_children must
+ *        continue calling these functions until they return NULL.
+ *        Otherwise, the next caller will pick up the list walk in
+ *        some indeterminate state.  (Otherwise every caller would
+ *        have to pass in a cookie to keep the state represented by
+ *        io_walk_link, which gets annoying.)
+ */
+zio_t *
+zio_walk_parents(zio_t *cio)
+{
+	zio_link_t *zl = cio->io_walk_link;
+	list_t *pl = &cio->io_parent_list;
+
+	zl = (zl == NULL) ? list_head(pl) : list_next(pl, zl);
+	cio->io_walk_link = zl;
+
+	if (zl == NULL)
+		return (NULL);
+
+	ASSERT(zl->zl_child == cio);
+	return (zl->zl_parent);
+}
+
+zio_t *
+zio_walk_children(zio_t *pio)
+{
+	zio_link_t *zl = pio->io_walk_link;
+	list_t *cl = &pio->io_child_list;
+
+	zl = (zl == NULL) ? list_head(cl) : list_next(cl, zl);
+	pio->io_walk_link = zl;
+
+	if (zl == NULL)
+		return (NULL);
+
+	ASSERT(zl->zl_parent == pio);
+	return (zl->zl_child);
+}
+
+zio_t *
+zio_unique_parent(zio_t *cio)
+{
+	zio_t *pio = zio_walk_parents(cio);
+
+	VERIFY(zio_walk_parents(cio) == NULL);
+	return (pio);
+}
+
+void
+zio_add_child(zio_t *pio, zio_t *cio)
+{
+	zio_link_t *zl = kmem_cache_alloc(zio_link_cache, KM_SLEEP);
+	int w;
+
+	/*
+	 * Logical I/Os can have logical, gang, or vdev children.
+	 * Gang I/Os can have gang or vdev children.
+	 * Vdev I/Os can only have vdev children.
+	 * The following ASSERT captures all of these constraints.
+	 */
+	ASSERT(cio->io_child_type <= pio->io_child_type);
+
+	zl->zl_parent = pio;
+	zl->zl_child = cio;
+
+	mutex_enter(&cio->io_lock);
+	mutex_enter(&pio->io_lock);
+
+	ASSERT(pio->io_state[ZIO_WAIT_DONE] == 0);
+
+	for (w = 0; w < ZIO_WAIT_TYPES; w++)
+		pio->io_children[cio->io_child_type][w] += !cio->io_state[w];
+
+	list_insert_head(&pio->io_child_list, zl);
+	list_insert_head(&cio->io_parent_list, zl);
+
+	pio->io_child_count++;
+	cio->io_parent_count++;
+
+	mutex_exit(&pio->io_lock);
+	mutex_exit(&cio->io_lock);
+}
+
+static void
+zio_remove_child(zio_t *pio, zio_t *cio, zio_link_t *zl)
+{
+	ASSERT(zl->zl_parent == pio);
+	ASSERT(zl->zl_child == cio);
+
+	mutex_enter(&cio->io_lock);
+	mutex_enter(&pio->io_lock);
+
+	list_remove(&pio->io_child_list, zl);
+	list_remove(&cio->io_parent_list, zl);
+
+	pio->io_child_count--;
+	cio->io_parent_count--;
+
+	mutex_exit(&pio->io_lock);
+	mutex_exit(&cio->io_lock);
+
+	kmem_cache_free(zio_link_cache, zl);
+}
+
+static boolean_t
+zio_wait_for_children(zio_t *zio, enum zio_child child, enum zio_wait_type wait)
+{
+	uint64_t *countp = &zio->io_children[child][wait];
+	boolean_t waiting = B_FALSE;
+
+	mutex_enter(&zio->io_lock);
+	ASSERT(zio->io_stall == NULL);
+	if (*countp != 0) {
+		zio->io_stage >>= 1;
+		zio->io_stall = countp;
+		waiting = B_TRUE;
+	}
+	mutex_exit(&zio->io_lock);
+
+	return (waiting);
+}
+
+__attribute__((always_inline))
+static inline void
+zio_notify_parent(zio_t *pio, zio_t *zio, enum zio_wait_type wait)
+{
+	uint64_t *countp = &pio->io_children[zio->io_child_type][wait];
+	int *errorp = &pio->io_child_error[zio->io_child_type];
+
+	mutex_enter(&pio->io_lock);
+	if (zio->io_error && !(zio->io_flags & ZIO_FLAG_DONT_PROPAGATE))
+		*errorp = zio_worst_error(*errorp, zio->io_error);
+	pio->io_reexecute |= zio->io_reexecute;
+	ASSERT3U(*countp, >, 0);
+
+	(*countp)--;
+
+	if (*countp == 0 && pio->io_stall == countp) {
+		pio->io_stall = NULL;
+		mutex_exit(&pio->io_lock);
+		__zio_execute(pio);
+	} else {
+		mutex_exit(&pio->io_lock);
+	}
+}
+
+static void
+zio_inherit_child_errors(zio_t *zio, enum zio_child c)
+{
+	if (zio->io_child_error[c] != 0 && zio->io_error == 0)
+		zio->io_error = zio->io_child_error[c];
+}
+
+/*
+ * ==========================================================================
+ * Create the various types of I/O (read, write, free, etc)
+ * ==========================================================================
+ */
+static zio_t *
+zio_create(zio_t *pio, spa_t *spa, uint64_t txg, const blkptr_t *bp,
+    void *data, uint64_t size, zio_done_func_t *done, void *private,
+    zio_type_t type, zio_priority_t priority, enum zio_flag flags,
+    vdev_t *vd, uint64_t offset, const zbookmark_phys_t *zb,
+    enum zio_stage stage, enum zio_stage pipeline)
+{
+	zio_t *zio;
+
+	ASSERT3U(size, <=, SPA_MAXBLOCKSIZE);
+	ASSERT(P2PHASE(size, SPA_MINBLOCKSIZE) == 0);
+	ASSERT(P2PHASE(offset, SPA_MINBLOCKSIZE) == 0);
+
+	ASSERT(!vd || spa_config_held(spa, SCL_STATE_ALL, RW_READER));
+	ASSERT(!bp || !(flags & ZIO_FLAG_CONFIG_WRITER));
+	ASSERT(vd || stage == ZIO_STAGE_OPEN);
+
+	zio = kmem_cache_alloc(zio_cache, KM_SLEEP);
+	bzero(zio, sizeof (zio_t));
+
+	mutex_init(&zio->io_lock, NULL, MUTEX_DEFAULT, NULL);
+	cv_init(&zio->io_cv, NULL, CV_DEFAULT, NULL);
+
+	list_create(&zio->io_parent_list, sizeof (zio_link_t),
+	    offsetof(zio_link_t, zl_parent_node));
+	list_create(&zio->io_child_list, sizeof (zio_link_t),
+	    offsetof(zio_link_t, zl_child_node));
+
+	if (vd != NULL)
+		zio->io_child_type = ZIO_CHILD_VDEV;
+	else if (flags & ZIO_FLAG_GANG_CHILD)
+		zio->io_child_type = ZIO_CHILD_GANG;
+	else if (flags & ZIO_FLAG_DDT_CHILD)
+		zio->io_child_type = ZIO_CHILD_DDT;
+	else
+		zio->io_child_type = ZIO_CHILD_LOGICAL;
+
+	if (bp != NULL) {
+		zio->io_bp = (blkptr_t *)bp;
+		zio->io_bp_copy = *bp;
+		zio->io_bp_orig = *bp;
+		if (type != ZIO_TYPE_WRITE ||
+		    zio->io_child_type == ZIO_CHILD_DDT)
+			zio->io_bp = &zio->io_bp_copy;	/* so caller can free */
+		if (zio->io_child_type == ZIO_CHILD_LOGICAL)
+			zio->io_logical = zio;
+		if (zio->io_child_type > ZIO_CHILD_GANG && BP_IS_GANG(bp))
+			pipeline |= ZIO_GANG_STAGES;
+	}
+
+	zio->io_spa = spa;
+	zio->io_txg = txg;
+	zio->io_done = done;
+	zio->io_private = private;
+	zio->io_type = type;
+	zio->io_priority = priority;
+	zio->io_vd = vd;
+	zio->io_offset = offset;
+	zio->io_orig_data = zio->io_data = data;
+	zio->io_orig_size = zio->io_size = size;
+	zio->io_orig_flags = zio->io_flags = flags;
+	zio->io_orig_stage = zio->io_stage = stage;
+	zio->io_orig_pipeline = zio->io_pipeline = pipeline;
+
+	zio->io_state[ZIO_WAIT_READY] = (stage >= ZIO_STAGE_READY);
+	zio->io_state[ZIO_WAIT_DONE] = (stage >= ZIO_STAGE_DONE);
+
+	if (zb != NULL)
+		zio->io_bookmark = *zb;
+
+	if (pio != NULL) {
+		if (zio->io_logical == NULL)
+			zio->io_logical = pio->io_logical;
+		if (zio->io_child_type == ZIO_CHILD_GANG)
+			zio->io_gang_leader = pio->io_gang_leader;
+		zio_add_child(pio, zio);
+	}
+
+	taskq_init_ent(&zio->io_tqent);
+
+	return (zio);
+}
+
+static void
+zio_destroy(zio_t *zio)
+{
+	list_destroy(&zio->io_parent_list);
+	list_destroy(&zio->io_child_list);
+	mutex_destroy(&zio->io_lock);
+	cv_destroy(&zio->io_cv);
+	kmem_cache_free(zio_cache, zio);
+}
+
+zio_t *
+zio_null(zio_t *pio, spa_t *spa, vdev_t *vd, zio_done_func_t *done,
+    void *private, enum zio_flag flags)
+{
+	zio_t *zio;
+
+	zio = zio_create(pio, spa, 0, NULL, NULL, 0, done, private,
+	    ZIO_TYPE_NULL, ZIO_PRIORITY_NOW, flags, vd, 0, NULL,
+	    ZIO_STAGE_OPEN, ZIO_INTERLOCK_PIPELINE);
+
+	return (zio);
+}
+
+zio_t *
+zio_root(spa_t *spa, zio_done_func_t *done, void *private, enum zio_flag flags)
+{
+	return (zio_null(NULL, spa, NULL, done, private, flags));
+}
+
+void
+zfs_blkptr_verify(spa_t *spa, const blkptr_t *bp)
+{
+	int i;
+
+	if (!DMU_OT_IS_VALID(BP_GET_TYPE(bp))) {
+		zfs_panic_recover("blkptr at %p has invalid TYPE %llu",
+		    bp, (longlong_t)BP_GET_TYPE(bp));
+	}
+	if (BP_GET_CHECKSUM(bp) >= ZIO_CHECKSUM_FUNCTIONS ||
+	    BP_GET_CHECKSUM(bp) <= ZIO_CHECKSUM_ON) {
+		zfs_panic_recover("blkptr at %p has invalid CHECKSUM %llu",
+		    bp, (longlong_t)BP_GET_CHECKSUM(bp));
+	}
+	if (BP_GET_COMPRESS(bp) >= ZIO_COMPRESS_FUNCTIONS ||
+	    BP_GET_COMPRESS(bp) <= ZIO_COMPRESS_ON) {
+		zfs_panic_recover("blkptr at %p has invalid COMPRESS %llu",
+		    bp, (longlong_t)BP_GET_COMPRESS(bp));
+	}
+	if (BP_GET_LSIZE(bp) > SPA_MAXBLOCKSIZE) {
+		zfs_panic_recover("blkptr at %p has invalid LSIZE %llu",
+		    bp, (longlong_t)BP_GET_LSIZE(bp));
+	}
+	if (BP_GET_PSIZE(bp) > SPA_MAXBLOCKSIZE) {
+		zfs_panic_recover("blkptr at %p has invalid PSIZE %llu",
+		    bp, (longlong_t)BP_GET_PSIZE(bp));
+	}
+
+	if (BP_IS_EMBEDDED(bp)) {
+		if (BPE_GET_ETYPE(bp) > NUM_BP_EMBEDDED_TYPES) {
+			zfs_panic_recover("blkptr at %p has invalid ETYPE %llu",
+			    bp, (longlong_t)BPE_GET_ETYPE(bp));
+		}
+	}
+
+	/*
+	 * Pool-specific checks.
+	 *
+	 * Note: it would be nice to verify that the blk_birth and
+	 * BP_PHYSICAL_BIRTH() are not too large.  However, spa_freeze()
+	 * allows the birth time of log blocks (and dmu_sync()-ed blocks
+	 * that are in the log) to be arbitrarily large.
+	 */
+	for (i = 0; i < BP_GET_NDVAS(bp); i++) {
+		uint64_t vdevid = DVA_GET_VDEV(&bp->blk_dva[i]);
+		vdev_t *vd;
+		uint64_t offset, asize;
+		if (vdevid >= spa->spa_root_vdev->vdev_children) {
+			zfs_panic_recover("blkptr at %p DVA %u has invalid "
+			    "VDEV %llu",
+			    bp, i, (longlong_t)vdevid);
+		}
+		vd = spa->spa_root_vdev->vdev_child[vdevid];
+		if (vd == NULL) {
+			zfs_panic_recover("blkptr at %p DVA %u has invalid "
+			    "VDEV %llu",
+			    bp, i, (longlong_t)vdevid);
+		}
+		if (vd->vdev_ops == &vdev_hole_ops) {
+			zfs_panic_recover("blkptr at %p DVA %u has hole "
+			    "VDEV %llu",
+			    bp, i, (longlong_t)vdevid);
+
+		}
+		if (vd->vdev_ops == &vdev_missing_ops) {
+			/*
+			 * "missing" vdevs are valid during import, but we
+			 * don't have their detailed info (e.g. asize), so
+			 * we can't perform any more checks on them.
+			 */
+			continue;
+		}
+		offset = DVA_GET_OFFSET(&bp->blk_dva[i]);
+		asize = DVA_GET_ASIZE(&bp->blk_dva[i]);
+		if (BP_IS_GANG(bp))
+			asize = vdev_psize_to_asize(vd, SPA_GANGBLOCKSIZE);
+		if (offset + asize > vd->vdev_asize) {
+			zfs_panic_recover("blkptr at %p DVA %u has invalid "
+			    "OFFSET %llu",
+			    bp, i, (longlong_t)offset);
+		}
+	}
+}
+
+zio_t *
+zio_read(zio_t *pio, spa_t *spa, const blkptr_t *bp,
+    void *data, uint64_t size, zio_done_func_t *done, void *private,
+    zio_priority_t priority, enum zio_flag flags, const zbookmark_phys_t *zb)
+{
+	zio_t *zio;
+
+	zfs_blkptr_verify(spa, bp);
+
+	zio = zio_create(pio, spa, BP_PHYSICAL_BIRTH(bp), bp,
+	    data, size, done, private,
+	    ZIO_TYPE_READ, priority, flags, NULL, 0, zb,
+	    ZIO_STAGE_OPEN, (flags & ZIO_FLAG_DDT_CHILD) ?
+	    ZIO_DDT_CHILD_READ_PIPELINE : ZIO_READ_PIPELINE);
+
+	return (zio);
+}
+
+zio_t *
+zio_write(zio_t *pio, spa_t *spa, uint64_t txg, blkptr_t *bp,
+    void *data, uint64_t size, const zio_prop_t *zp,
+    zio_done_func_t *ready, zio_done_func_t *physdone, zio_done_func_t *done,
+    void *private,
+    zio_priority_t priority, enum zio_flag flags, const zbookmark_phys_t *zb)
+{
+	zio_t *zio;
+
+	ASSERT(zp->zp_checksum >= ZIO_CHECKSUM_OFF &&
+	    zp->zp_checksum < ZIO_CHECKSUM_FUNCTIONS &&
+	    zp->zp_compress >= ZIO_COMPRESS_OFF &&
+	    zp->zp_compress < ZIO_COMPRESS_FUNCTIONS &&
+	    DMU_OT_IS_VALID(zp->zp_type) &&
+	    zp->zp_level < 32 &&
+	    zp->zp_copies > 0 &&
+	    zp->zp_copies <= spa_max_replication(spa));
+
+	zio = zio_create(pio, spa, txg, bp, data, size, done, private,
+	    ZIO_TYPE_WRITE, priority, flags, NULL, 0, zb,
+	    ZIO_STAGE_OPEN, (flags & ZIO_FLAG_DDT_CHILD) ?
+	    ZIO_DDT_CHILD_WRITE_PIPELINE : ZIO_WRITE_PIPELINE);
+
+	zio->io_ready = ready;
+	zio->io_physdone = physdone;
+	zio->io_prop = *zp;
+
+	/*
+	 * Data can be NULL if we are going to call zio_write_override() to
+	 * provide the already-allocated BP.  But we may need the data to
+	 * verify a dedup hit (if requested).  In this case, don't try to
+	 * dedup (just take the already-allocated BP verbatim).
+	 */
+	if (data == NULL && zio->io_prop.zp_dedup_verify) {
+		zio->io_prop.zp_dedup = zio->io_prop.zp_dedup_verify = B_FALSE;
+	}
+
+	return (zio);
+}
+
+zio_t *
+zio_rewrite(zio_t *pio, spa_t *spa, uint64_t txg, blkptr_t *bp, void *data,
+    uint64_t size, zio_done_func_t *done, void *private,
+    zio_priority_t priority, enum zio_flag flags, zbookmark_phys_t *zb)
+{
+	zio_t *zio;
+
+	zio = zio_create(pio, spa, txg, bp, data, size, done, private,
+	    ZIO_TYPE_WRITE, priority, flags, NULL, 0, zb,
+	    ZIO_STAGE_OPEN, ZIO_REWRITE_PIPELINE);
+
+	return (zio);
+}
+
+void
+zio_write_override(zio_t *zio, blkptr_t *bp, int copies, boolean_t nopwrite)
+{
+	ASSERT(zio->io_type == ZIO_TYPE_WRITE);
+	ASSERT(zio->io_child_type == ZIO_CHILD_LOGICAL);
+	ASSERT(zio->io_stage == ZIO_STAGE_OPEN);
+	ASSERT(zio->io_txg == spa_syncing_txg(zio->io_spa));
+
+	/*
+	 * We must reset the io_prop to match the values that existed
+	 * when the bp was first written by dmu_sync() keeping in mind
+	 * that nopwrite and dedup are mutually exclusive.
+	 */
+	zio->io_prop.zp_dedup = nopwrite ? B_FALSE : zio->io_prop.zp_dedup;
+	zio->io_prop.zp_nopwrite = nopwrite;
+	zio->io_prop.zp_copies = copies;
+	zio->io_bp_override = bp;
+}
+
+void
+zio_free(spa_t *spa, uint64_t txg, const blkptr_t *bp)
+{
+
+	/*
+	 * The check for EMBEDDED is a performance optimization.  We
+	 * process the free here (by ignoring it) rather than
+	 * putting it on the list and then processing it in zio_free_sync().
+	 */
+	if (BP_IS_EMBEDDED(bp))
+		return;
+	metaslab_check_free(spa, bp);
+
+	/*
+	 * Frees that are for the currently-syncing txg, are not going to be
+	 * deferred, and which will not need to do a read (i.e. not GANG or
+	 * DEDUP), can be processed immediately.  Otherwise, put them on the
+	 * in-memory list for later processing.
+	 */
+	if (BP_IS_GANG(bp) || BP_GET_DEDUP(bp) ||
+	    txg != spa->spa_syncing_txg ||
+	    spa_sync_pass(spa) >= zfs_sync_pass_deferred_free) {
+		bplist_append(&spa->spa_free_bplist[txg & TXG_MASK], bp);
+	} else {
+		VERIFY0(zio_wait(zio_free_sync(NULL, spa, txg, bp, 0)));
+	}
+}
+
+zio_t *
+zio_free_sync(zio_t *pio, spa_t *spa, uint64_t txg, const blkptr_t *bp,
+    enum zio_flag flags)
+{
+	zio_t *zio;
+	enum zio_stage stage = ZIO_FREE_PIPELINE;
+
+	ASSERT(!BP_IS_HOLE(bp));
+	ASSERT(spa_syncing_txg(spa) == txg);
+	ASSERT(spa_sync_pass(spa) < zfs_sync_pass_deferred_free);
+
+	if (BP_IS_EMBEDDED(bp))
+		return (zio_null(pio, spa, NULL, NULL, NULL, 0));
+
+	metaslab_check_free(spa, bp);
+	arc_freed(spa, bp);
+
+	/*
+	 * GANG and DEDUP blocks can induce a read (for the gang block header,
+	 * or the DDT), so issue them asynchronously so that this thread is
+	 * not tied up.
+	 */
+	if (BP_IS_GANG(bp) || BP_GET_DEDUP(bp))
+		stage |= ZIO_STAGE_ISSUE_ASYNC;
+
+	zio = zio_create(pio, spa, txg, bp, NULL, BP_GET_PSIZE(bp),
+	    NULL, NULL, ZIO_TYPE_FREE, ZIO_PRIORITY_NOW, flags,
+	    NULL, 0, NULL, ZIO_STAGE_OPEN, stage);
+
+	return (zio);
+}
+
+zio_t *
+zio_claim(zio_t *pio, spa_t *spa, uint64_t txg, const blkptr_t *bp,
+    zio_done_func_t *done, void *private, enum zio_flag flags)
+{
+	zio_t *zio;
+
+	dprintf_bp(bp, "claiming in txg %llu", txg);
+
+	if (BP_IS_EMBEDDED(bp))
+		return (zio_null(pio, spa, NULL, NULL, NULL, 0));
+
+	/*
+	 * A claim is an allocation of a specific block.  Claims are needed
+	 * to support immediate writes in the intent log.  The issue is that
+	 * immediate writes contain committed data, but in a txg that was
+	 * *not* committed.  Upon opening the pool after an unclean shutdown,
+	 * the intent log claims all blocks that contain immediate write data
+	 * so that the SPA knows they're in use.
+	 *
+	 * All claims *must* be resolved in the first txg -- before the SPA
+	 * starts allocating blocks -- so that nothing is allocated twice.
+	 * If txg == 0 we just verify that the block is claimable.
+	 */
+	ASSERT3U(spa->spa_uberblock.ub_rootbp.blk_birth, <, spa_first_txg(spa));
+	ASSERT(txg == spa_first_txg(spa) || txg == 0);
+	ASSERT(!BP_GET_DEDUP(bp) || !spa_writeable(spa));	/* zdb(1M) */
+
+	zio = zio_create(pio, spa, txg, bp, NULL, BP_GET_PSIZE(bp),
+	    done, private, ZIO_TYPE_CLAIM, ZIO_PRIORITY_NOW, flags,
+	    NULL, 0, NULL, ZIO_STAGE_OPEN, ZIO_CLAIM_PIPELINE);
+
+	return (zio);
+}
+
+zio_t *
+zio_ioctl(zio_t *pio, spa_t *spa, vdev_t *vd, int cmd,
+    zio_done_func_t *done, void *private, enum zio_flag flags)
+{
+	zio_t *zio;
+	int c;
+
+	if (vd->vdev_children == 0) {
+		zio = zio_create(pio, spa, 0, NULL, NULL, 0, done, private,
+		    ZIO_TYPE_IOCTL, ZIO_PRIORITY_NOW, flags, vd, 0, NULL,
+		    ZIO_STAGE_OPEN, ZIO_IOCTL_PIPELINE);
+
+		zio->io_cmd = cmd;
+	} else {
+		zio = zio_null(pio, spa, NULL, NULL, NULL, flags);
+
+		for (c = 0; c < vd->vdev_children; c++)
+			zio_nowait(zio_ioctl(zio, spa, vd->vdev_child[c], cmd,
+			    done, private, flags));
+	}
+
+	return (zio);
+}
+
+zio_t *
+zio_read_phys(zio_t *pio, vdev_t *vd, uint64_t offset, uint64_t size,
+    void *data, int checksum, zio_done_func_t *done, void *private,
+    zio_priority_t priority, enum zio_flag flags, boolean_t labels)
+{
+	zio_t *zio;
+
+	ASSERT(vd->vdev_children == 0);
+	ASSERT(!labels || offset + size <= VDEV_LABEL_START_SIZE ||
+	    offset >= vd->vdev_psize - VDEV_LABEL_END_SIZE);
+	ASSERT3U(offset + size, <=, vd->vdev_psize);
+
+	zio = zio_create(pio, vd->vdev_spa, 0, NULL, data, size, done, private,
+	    ZIO_TYPE_READ, priority, flags | ZIO_FLAG_PHYSICAL, vd, offset,
+	    NULL, ZIO_STAGE_OPEN, ZIO_READ_PHYS_PIPELINE);
+
+	zio->io_prop.zp_checksum = checksum;
+
+	return (zio);
+}
+
+zio_t *
+zio_write_phys(zio_t *pio, vdev_t *vd, uint64_t offset, uint64_t size,
+    void *data, int checksum, zio_done_func_t *done, void *private,
+    zio_priority_t priority, enum zio_flag flags, boolean_t labels)
+{
+	zio_t *zio;
+
+	ASSERT(vd->vdev_children == 0);
+	ASSERT(!labels || offset + size <= VDEV_LABEL_START_SIZE ||
+	    offset >= vd->vdev_psize - VDEV_LABEL_END_SIZE);
+	ASSERT3U(offset + size, <=, vd->vdev_psize);
+
+	zio = zio_create(pio, vd->vdev_spa, 0, NULL, data, size, done, private,
+	    ZIO_TYPE_WRITE, priority, flags | ZIO_FLAG_PHYSICAL, vd, offset,
+	    NULL, ZIO_STAGE_OPEN, ZIO_WRITE_PHYS_PIPELINE);
+
+	zio->io_prop.zp_checksum = checksum;
+
+	if (zio_checksum_table[checksum].ci_eck) {
+		/*
+		 * zec checksums are necessarily destructive -- they modify
+		 * the end of the write buffer to hold the verifier/checksum.
+		 * Therefore, we must make a local copy in case the data is
+		 * being written to multiple places in parallel.
+		 */
+		void *wbuf = zio_buf_alloc(size);
+		bcopy(data, wbuf, size);
+		zio_push_transform(zio, wbuf, size, size, NULL);
+	}
+
+	return (zio);
+}
+
+/*
+ * Create a child I/O to do some work for us.
+ */
+zio_t *
+zio_vdev_child_io(zio_t *pio, blkptr_t *bp, vdev_t *vd, uint64_t offset,
+	void *data, uint64_t size, int type, zio_priority_t priority,
+	enum zio_flag flags, zio_done_func_t *done, void *private)
+{
+	enum zio_stage pipeline = ZIO_VDEV_CHILD_PIPELINE;
+	zio_t *zio;
+
+	ASSERT(vd->vdev_parent ==
+	    (pio->io_vd ? pio->io_vd : pio->io_spa->spa_root_vdev));
+
+	if (type == ZIO_TYPE_READ && bp != NULL) {
+		/*
+		 * If we have the bp, then the child should perform the
+		 * checksum and the parent need not.  This pushes error
+		 * detection as close to the leaves as possible and
+		 * eliminates redundant checksums in the interior nodes.
+		 */
+		pipeline |= ZIO_STAGE_CHECKSUM_VERIFY;
+		pio->io_pipeline &= ~ZIO_STAGE_CHECKSUM_VERIFY;
+	}
+
+	if (vd->vdev_children == 0)
+		offset += VDEV_LABEL_START_SIZE;
+
+	flags |= ZIO_VDEV_CHILD_FLAGS(pio) | ZIO_FLAG_DONT_PROPAGATE;
+
+	/*
+	 * If we've decided to do a repair, the write is not speculative --
+	 * even if the original read was.
+	 */
+	if (flags & ZIO_FLAG_IO_REPAIR)
+		flags &= ~ZIO_FLAG_SPECULATIVE;
+
+	zio = zio_create(pio, pio->io_spa, pio->io_txg, bp, data, size,
+	    done, private, type, priority, flags, vd, offset, &pio->io_bookmark,
+	    ZIO_STAGE_VDEV_IO_START >> 1, pipeline);
+
+	zio->io_physdone = pio->io_physdone;
+	if (vd->vdev_ops->vdev_op_leaf && zio->io_logical != NULL)
+		zio->io_logical->io_phys_children++;
+
+	return (zio);
+}
+
+zio_t *
+zio_vdev_delegated_io(vdev_t *vd, uint64_t offset, void *data, uint64_t size,
+	int type, zio_priority_t priority, enum zio_flag flags,
+	zio_done_func_t *done, void *private)
+{
+	zio_t *zio;
+
+	ASSERT(vd->vdev_ops->vdev_op_leaf);
+
+	zio = zio_create(NULL, vd->vdev_spa, 0, NULL,
+	    data, size, done, private, type, priority,
+	    flags | ZIO_FLAG_CANFAIL | ZIO_FLAG_DONT_RETRY | ZIO_FLAG_DELEGATED,
+	    vd, offset, NULL,
+	    ZIO_STAGE_VDEV_IO_START >> 1, ZIO_VDEV_CHILD_PIPELINE);
+
+	return (zio);
+}
+
+void
+zio_flush(zio_t *zio, vdev_t *vd)
+{
+	zio_nowait(zio_ioctl(zio, zio->io_spa, vd, DKIOCFLUSHWRITECACHE,
+	    NULL, NULL,
+	    ZIO_FLAG_CANFAIL | ZIO_FLAG_DONT_PROPAGATE | ZIO_FLAG_DONT_RETRY));
+}
+
+void
+zio_shrink(zio_t *zio, uint64_t size)
+{
+	ASSERT(zio->io_executor == NULL);
+	ASSERT(zio->io_orig_size == zio->io_size);
+	ASSERT(size <= zio->io_size);
+
+	/*
+	 * We don't shrink for raidz because of problems with the
+	 * reconstruction when reading back less than the block size.
+	 * Note, BP_IS_RAIDZ() assumes no compression.
+	 */
+	ASSERT(BP_GET_COMPRESS(zio->io_bp) == ZIO_COMPRESS_OFF);
+	if (!BP_IS_RAIDZ(zio->io_bp))
+		zio->io_orig_size = zio->io_size = size;
+}
+
+/*
+ * ==========================================================================
+ * Prepare to read and write logical blocks
+ * ==========================================================================
+ */
+
+static int
+zio_read_bp_init(zio_t *zio)
+{
+	blkptr_t *bp = zio->io_bp;
+
+	if (BP_GET_COMPRESS(bp) != ZIO_COMPRESS_OFF &&
+	    zio->io_child_type == ZIO_CHILD_LOGICAL &&
+	    !(zio->io_flags & ZIO_FLAG_RAW)) {
+		uint64_t psize =
+		    BP_IS_EMBEDDED(bp) ? BPE_GET_PSIZE(bp) : BP_GET_PSIZE(bp);
+		void *cbuf = zio_buf_alloc(psize);
+
+		zio_push_transform(zio, cbuf, psize, psize, zio_decompress);
+	}
+
+	if (BP_IS_EMBEDDED(bp) && BPE_GET_ETYPE(bp) == BP_EMBEDDED_TYPE_DATA) {
+		zio->io_pipeline = ZIO_INTERLOCK_PIPELINE;
+		decode_embedded_bp_compressed(bp, zio->io_data);
+	} else {
+		ASSERT(!BP_IS_EMBEDDED(bp));
+	}
+
+	if (!DMU_OT_IS_METADATA(BP_GET_TYPE(bp)) && BP_GET_LEVEL(bp) == 0)
+		zio->io_flags |= ZIO_FLAG_DONT_CACHE;
+
+	if (BP_GET_TYPE(bp) == DMU_OT_DDT_ZAP)
+		zio->io_flags |= ZIO_FLAG_DONT_CACHE;
+
+	if (BP_GET_DEDUP(bp) && zio->io_child_type == ZIO_CHILD_LOGICAL)
+		zio->io_pipeline = ZIO_DDT_READ_PIPELINE;
+
+	return (ZIO_PIPELINE_CONTINUE);
+}
+
+static int
+zio_write_bp_init(zio_t *zio)
+{
+	spa_t *spa = zio->io_spa;
+	zio_prop_t *zp = &zio->io_prop;
+	enum zio_compress compress = zp->zp_compress;
+	blkptr_t *bp = zio->io_bp;
+	uint64_t lsize = zio->io_size;
+	uint64_t psize = lsize;
+	int pass = 1;
+
+	/*
+	 * If our children haven't all reached the ready stage,
+	 * wait for them and then repeat this pipeline stage.
+	 */
+	if (zio_wait_for_children(zio, ZIO_CHILD_GANG, ZIO_WAIT_READY) ||
+	    zio_wait_for_children(zio, ZIO_CHILD_LOGICAL, ZIO_WAIT_READY))
+		return (ZIO_PIPELINE_STOP);
+
+	if (!IO_IS_ALLOCATING(zio))
+		return (ZIO_PIPELINE_CONTINUE);
+
+	ASSERT(zio->io_child_type != ZIO_CHILD_DDT);
+
+	if (zio->io_bp_override) {
+		ASSERT(bp->blk_birth != zio->io_txg);
+		ASSERT(BP_GET_DEDUP(zio->io_bp_override) == 0);
+
+		*bp = *zio->io_bp_override;
+		zio->io_pipeline = ZIO_INTERLOCK_PIPELINE;
+
+		if (BP_IS_EMBEDDED(bp))
+			return (ZIO_PIPELINE_CONTINUE);
+
+		/*
+		 * If we've been overridden and nopwrite is set then
+		 * set the flag accordingly to indicate that a nopwrite
+		 * has already occurred.
+		 */
+		if (!BP_IS_HOLE(bp) && zp->zp_nopwrite) {
+			ASSERT(!zp->zp_dedup);
+			zio->io_flags |= ZIO_FLAG_NOPWRITE;
+			return (ZIO_PIPELINE_CONTINUE);
+		}
+
+		ASSERT(!zp->zp_nopwrite);
+
+		if (BP_IS_HOLE(bp) || !zp->zp_dedup)
+			return (ZIO_PIPELINE_CONTINUE);
+
+		ASSERT(zio_checksum_table[zp->zp_checksum].ci_dedup ||
+		    zp->zp_dedup_verify);
+
+		if (BP_GET_CHECKSUM(bp) == zp->zp_checksum) {
+			BP_SET_DEDUP(bp, 1);
+			zio->io_pipeline |= ZIO_STAGE_DDT_WRITE;
+			return (ZIO_PIPELINE_CONTINUE);
+		}
+	}
+
+	if (!BP_IS_HOLE(bp) && bp->blk_birth == zio->io_txg) {
+		/*
+		 * We're rewriting an existing block, which means we're
+		 * working on behalf of spa_sync().  For spa_sync() to
+		 * converge, it must eventually be the case that we don't
+		 * have to allocate new blocks.  But compression changes
+		 * the blocksize, which forces a reallocate, and makes
+		 * convergence take longer.  Therefore, after the first
+		 * few passes, stop compressing to ensure convergence.
+		 */
+		pass = spa_sync_pass(spa);
+
+		ASSERT(zio->io_txg == spa_syncing_txg(spa));
+		ASSERT(zio->io_child_type == ZIO_CHILD_LOGICAL);
+		ASSERT(!BP_GET_DEDUP(bp));
+
+		if (pass >= zfs_sync_pass_dont_compress)
+			compress = ZIO_COMPRESS_OFF;
+
+		/* Make sure someone doesn't change their mind on overwrites */
+		ASSERT(BP_IS_EMBEDDED(bp) || MIN(zp->zp_copies + BP_IS_GANG(bp),
+		    spa_max_replication(spa)) == BP_GET_NDVAS(bp));
+	}
+
+	if (compress != ZIO_COMPRESS_OFF) {
+		void *cbuf = zio_buf_alloc(lsize);
+		psize = zio_compress_data(compress, zio->io_data, cbuf, lsize);
+		if (psize == 0 || psize == lsize) {
+			compress = ZIO_COMPRESS_OFF;
+			zio_buf_free(cbuf, lsize);
+		} else if (!zp->zp_dedup && psize <= BPE_PAYLOAD_SIZE &&
+		    zp->zp_level == 0 && !DMU_OT_HAS_FILL(zp->zp_type) &&
+		    spa_feature_is_enabled(spa, SPA_FEATURE_EMBEDDED_DATA)) {
+			encode_embedded_bp_compressed(bp,
+			    cbuf, compress, lsize, psize);
+			BPE_SET_ETYPE(bp, BP_EMBEDDED_TYPE_DATA);
+			BP_SET_TYPE(bp, zio->io_prop.zp_type);
+			BP_SET_LEVEL(bp, zio->io_prop.zp_level);
+			zio_buf_free(cbuf, lsize);
+			bp->blk_birth = zio->io_txg;
+			zio->io_pipeline = ZIO_INTERLOCK_PIPELINE;
+			ASSERT(spa_feature_is_active(spa,
+			    SPA_FEATURE_EMBEDDED_DATA));
+			return (ZIO_PIPELINE_CONTINUE);
+		} else {
+			/*
+			 * Round up compressed size up to the ashift
+			 * of the smallest-ashift device, and zero the tail.
+			 * This ensures that the compressed size of the BP
+			 * (and thus compressratio property) are correct,
+			 * in that we charge for the padding used to fill out
+			 * the last sector.
+			 */
+			size_t rounded;
+
+			ASSERT3U(spa->spa_min_ashift, >=, SPA_MINBLOCKSHIFT);
+
+			rounded = (size_t)P2ROUNDUP(psize,
+			    1ULL << spa->spa_min_ashift);
+			if (rounded >= lsize) {
+				compress = ZIO_COMPRESS_OFF;
+				zio_buf_free(cbuf, lsize);
+				psize = lsize;
+			} else {
+				bzero((char *)cbuf + psize, rounded - psize);
+				psize = rounded;
+				zio_push_transform(zio, cbuf,
+				    psize, lsize, NULL);
+			}
+		}
+	}
+
+	/*
+	 * The final pass of spa_sync() must be all rewrites, but the first
+	 * few passes offer a trade-off: allocating blocks defers convergence,
+	 * but newly allocated blocks are sequential, so they can be written
+	 * to disk faster.  Therefore, we allow the first few passes of
+	 * spa_sync() to allocate new blocks, but force rewrites after that.
+	 * There should only be a handful of blocks after pass 1 in any case.
+	 */
+	if (!BP_IS_HOLE(bp) && bp->blk_birth == zio->io_txg &&
+	    BP_GET_PSIZE(bp) == psize &&
+	    pass >= zfs_sync_pass_rewrite) {
+		enum zio_stage gang_stages = zio->io_pipeline & ZIO_GANG_STAGES;
+		ASSERT(psize != 0);
+		zio->io_pipeline = ZIO_REWRITE_PIPELINE | gang_stages;
+		zio->io_flags |= ZIO_FLAG_IO_REWRITE;
+	} else {
+		BP_ZERO(bp);
+		zio->io_pipeline = ZIO_WRITE_PIPELINE;
+	}
+
+	if (psize == 0) {
+		if (zio->io_bp_orig.blk_birth != 0 &&
+		    spa_feature_is_active(spa, SPA_FEATURE_HOLE_BIRTH)) {
+			BP_SET_LSIZE(bp, lsize);
+			BP_SET_TYPE(bp, zp->zp_type);
+			BP_SET_LEVEL(bp, zp->zp_level);
+			BP_SET_BIRTH(bp, zio->io_txg, 0);
+		}
+		zio->io_pipeline = ZIO_INTERLOCK_PIPELINE;
+	} else {
+		ASSERT(zp->zp_checksum != ZIO_CHECKSUM_GANG_HEADER);
+		BP_SET_LSIZE(bp, lsize);
+		BP_SET_TYPE(bp, zp->zp_type);
+		BP_SET_LEVEL(bp, zp->zp_level);
+		BP_SET_PSIZE(bp, psize);
+		BP_SET_COMPRESS(bp, compress);
+		BP_SET_CHECKSUM(bp, zp->zp_checksum);
+		BP_SET_DEDUP(bp, zp->zp_dedup);
+		BP_SET_BYTEORDER(bp, ZFS_HOST_BYTEORDER);
+		if (zp->zp_dedup) {
+			ASSERT(zio->io_child_type == ZIO_CHILD_LOGICAL);
+			ASSERT(!(zio->io_flags & ZIO_FLAG_IO_REWRITE));
+			zio->io_pipeline = ZIO_DDT_WRITE_PIPELINE;
+		}
+		if (zp->zp_nopwrite) {
+			ASSERT(zio->io_child_type == ZIO_CHILD_LOGICAL);
+			ASSERT(!(zio->io_flags & ZIO_FLAG_IO_REWRITE));
+			zio->io_pipeline |= ZIO_STAGE_NOP_WRITE;
+		}
+	}
+
+	return (ZIO_PIPELINE_CONTINUE);
+}
+
+static int
+zio_free_bp_init(zio_t *zio)
+{
+	blkptr_t *bp = zio->io_bp;
+
+	if (zio->io_child_type == ZIO_CHILD_LOGICAL) {
+		if (BP_GET_DEDUP(bp))
+			zio->io_pipeline = ZIO_DDT_FREE_PIPELINE;
+	}
+
+	return (ZIO_PIPELINE_CONTINUE);
+}
+
+/*
+ * ==========================================================================
+ * Execute the I/O pipeline
+ * ==========================================================================
+ */
+
+static void
+zio_taskq_dispatch(zio_t *zio, zio_taskq_type_t q, boolean_t cutinline)
+{
+	spa_t *spa = zio->io_spa;
+	zio_type_t t = zio->io_type;
+	int flags = (cutinline ? TQ_FRONT : 0);
+
+	/*
+	 * If we're a config writer or a probe, the normal issue and
+	 * interrupt threads may all be blocked waiting for the config lock.
+	 * In this case, select the otherwise-unused taskq for ZIO_TYPE_NULL.
+	 */
+	if (zio->io_flags & (ZIO_FLAG_CONFIG_WRITER | ZIO_FLAG_PROBE))
+		t = ZIO_TYPE_NULL;
+
+	/*
+	 * A similar issue exists for the L2ARC write thread until L2ARC 2.0.
+	 */
+	if (t == ZIO_TYPE_WRITE && zio->io_vd && zio->io_vd->vdev_aux)
+		t = ZIO_TYPE_NULL;
+
+	/*
+	 * If this is a high priority I/O, then use the high priority taskq if
+	 * available.
+	 */
+	if (zio->io_priority == ZIO_PRIORITY_NOW &&
+	    spa->spa_zio_taskq[t][q + 1].stqs_count != 0)
+		q++;
+
+	ASSERT3U(q, <, ZIO_TASKQ_TYPES);
+
+	/*
+	 * NB: We are assuming that the zio can only be dispatched
+	 * to a single taskq at a time.  It would be a grievous error
+	 * to dispatch the zio to another taskq at the same time.
+	 */
+	ASSERT(taskq_empty_ent(&zio->io_tqent));
+	spa_taskq_dispatch_ent(spa, t, q, (task_func_t *)zio_execute, zio,
+	    flags, &zio->io_tqent);
+}
+
+static boolean_t
+zio_taskq_member(zio_t *zio, zio_taskq_type_t q)
+{
+	kthread_t *executor = zio->io_executor;
+	spa_t *spa = zio->io_spa;
+	zio_type_t t;
+
+	for (t = 0; t < ZIO_TYPES; t++) {
+		spa_taskqs_t *tqs = &spa->spa_zio_taskq[t][q];
+		uint_t i;
+		for (i = 0; i < tqs->stqs_count; i++) {
+			if (taskq_member(tqs->stqs_taskq[i], executor))
+				return (B_TRUE);
+		}
+	}
+
+	return (B_FALSE);
+}
+
+static int
+zio_issue_async(zio_t *zio)
+{
+	zio_taskq_dispatch(zio, ZIO_TASKQ_ISSUE, B_FALSE);
+
+	return (ZIO_PIPELINE_STOP);
+}
+
+void
+zio_interrupt(zio_t *zio)
+{
+	zio_taskq_dispatch(zio, ZIO_TASKQ_INTERRUPT, B_FALSE);
+}
+
+/*
+ * Execute the I/O pipeline until one of the following occurs:
+ * (1) the I/O completes; (2) the pipeline stalls waiting for
+ * dependent child I/Os; (3) the I/O issues, so we're waiting
+ * for an I/O completion interrupt; (4) the I/O is delegated by
+ * vdev-level caching or aggregation; (5) the I/O is deferred
+ * due to vdev-level queueing; (6) the I/O is handed off to
+ * another thread.  In all cases, the pipeline stops whenever
+ * there's no CPU work; it never burns a thread in cv_wait_io().
+ *
+ * There's no locking on io_stage because there's no legitimate way
+ * for multiple threads to be attempting to process the same I/O.
+ */
+static zio_pipe_stage_t *zio_pipeline[];
+
+/*
+ * zio_execute() is a wrapper around the static function
+ * __zio_execute() so that we can force  __zio_execute() to be
+ * inlined.  This reduces stack overhead which is important
+ * because __zio_execute() is called recursively in several zio
+ * code paths.  zio_execute() itself cannot be inlined because
+ * it is externally visible.
+ */
+void
+zio_execute(zio_t *zio)
+{
+	fstrans_cookie_t cookie;
+
+	cookie = spl_fstrans_mark();
+	__zio_execute(zio);
+	spl_fstrans_unmark(cookie);
+}
+
+__attribute__((always_inline))
+static inline void
+__zio_execute(zio_t *zio)
+{
+	zio->io_executor = curthread;
+
+	while (zio->io_stage < ZIO_STAGE_DONE) {
+		enum zio_stage pipeline = zio->io_pipeline;
+		enum zio_stage stage = zio->io_stage;
+		dsl_pool_t *dp;
+		boolean_t cut;
+		int rv;
+
+		ASSERT(!MUTEX_HELD(&zio->io_lock));
+		ASSERT(ISP2(stage));
+		ASSERT(zio->io_stall == NULL);
+
+		do {
+			stage <<= 1;
+		} while ((stage & pipeline) == 0);
+
+		ASSERT(stage <= ZIO_STAGE_DONE);
+
+		dp = spa_get_dsl(zio->io_spa);
+		cut = (stage == ZIO_STAGE_VDEV_IO_START) ?
+		    zio_requeue_io_start_cut_in_line : B_FALSE;
+
+		/*
+		 * If we are in interrupt context and this pipeline stage
+		 * will grab a config lock that is held across I/O,
+		 * or may wait for an I/O that needs an interrupt thread
+		 * to complete, issue async to avoid deadlock.
+		 *
+		 * For VDEV_IO_START, we cut in line so that the io will
+		 * be sent to disk promptly.
+		 */
+		if ((stage & ZIO_BLOCKING_STAGES) && zio->io_vd == NULL &&
+		    zio_taskq_member(zio, ZIO_TASKQ_INTERRUPT)) {
+			zio_taskq_dispatch(zio, ZIO_TASKQ_ISSUE, cut);
+			return;
+		}
+
+		/*
+		 * If we executing in the context of the tx_sync_thread,
+		 * or we are performing pool initialization outside of a
+		 * zio_taskq[ZIO_TASKQ_ISSUE|ZIO_TASKQ_ISSUE_HIGH] context.
+		 * Then issue the zio asynchronously to minimize stack usage
+		 * for these deep call paths.
+		 */
+		if ((dp && curthread == dp->dp_tx.tx_sync_thread) ||
+		    (dp && spa_is_initializing(dp->dp_spa) &&
+		    !zio_taskq_member(zio, ZIO_TASKQ_ISSUE) &&
+		    !zio_taskq_member(zio, ZIO_TASKQ_ISSUE_HIGH))) {
+			zio_taskq_dispatch(zio, ZIO_TASKQ_ISSUE, cut);
+			return;
+		}
+
+		zio->io_stage = stage;
+		rv = zio_pipeline[highbit64(stage) - 1](zio);
+
+		if (rv == ZIO_PIPELINE_STOP)
+			return;
+
+		ASSERT(rv == ZIO_PIPELINE_CONTINUE);
+	}
+}
+
+
+/*
+ * ==========================================================================
+ * Initiate I/O, either sync or async
+ * ==========================================================================
+ */
+int
+zio_wait(zio_t *zio)
+{
+	int error;
+
+	ASSERT(zio->io_stage == ZIO_STAGE_OPEN);
+	ASSERT(zio->io_executor == NULL);
+
+	zio->io_waiter = curthread;
+
+	__zio_execute(zio);
+
+	mutex_enter(&zio->io_lock);
+	while (zio->io_executor != NULL)
+		cv_wait_io(&zio->io_cv, &zio->io_lock);
+	mutex_exit(&zio->io_lock);
+
+	error = zio->io_error;
+	zio_destroy(zio);
+
+	return (error);
+}
+
+void
+zio_nowait(zio_t *zio)
+{
+	ASSERT(zio->io_executor == NULL);
+
+	if (zio->io_child_type == ZIO_CHILD_LOGICAL &&
+	    zio_unique_parent(zio) == NULL) {
+		zio_t *pio;
+
+		/*
+		 * This is a logical async I/O with no parent to wait for it.
+		 * We add it to the spa_async_root_zio "Godfather" I/O which
+		 * will ensure they complete prior to unloading the pool.
+		 */
+		spa_t *spa = zio->io_spa;
+		kpreempt_disable();
+		pio = spa->spa_async_zio_root[CPU_SEQID];
+		kpreempt_enable();
+
+		zio_add_child(pio, zio);
+	}
+
+	__zio_execute(zio);
+}
+
+/*
+ * ==========================================================================
+ * Reexecute or suspend/resume failed I/O
+ * ==========================================================================
+ */
+
+static void
+zio_reexecute(zio_t *pio)
+{
+	zio_t *cio, *cio_next;
+	int c, w;
+
+	ASSERT(pio->io_child_type == ZIO_CHILD_LOGICAL);
+	ASSERT(pio->io_orig_stage == ZIO_STAGE_OPEN);
+	ASSERT(pio->io_gang_leader == NULL);
+	ASSERT(pio->io_gang_tree == NULL);
+
+	pio->io_flags = pio->io_orig_flags;
+	pio->io_stage = pio->io_orig_stage;
+	pio->io_pipeline = pio->io_orig_pipeline;
+	pio->io_reexecute = 0;
+	pio->io_flags |= ZIO_FLAG_REEXECUTED;
+	pio->io_error = 0;
+	for (w = 0; w < ZIO_WAIT_TYPES; w++)
+		pio->io_state[w] = 0;
+	for (c = 0; c < ZIO_CHILD_TYPES; c++)
+		pio->io_child_error[c] = 0;
+
+	if (IO_IS_ALLOCATING(pio))
+		BP_ZERO(pio->io_bp);
+
+	/*
+	 * As we reexecute pio's children, new children could be created.
+	 * New children go to the head of pio's io_child_list, however,
+	 * so we will (correctly) not reexecute them.  The key is that
+	 * the remainder of pio's io_child_list, from 'cio_next' onward,
+	 * cannot be affected by any side effects of reexecuting 'cio'.
+	 */
+	for (cio = zio_walk_children(pio); cio != NULL; cio = cio_next) {
+		cio_next = zio_walk_children(pio);
+		mutex_enter(&pio->io_lock);
+		for (w = 0; w < ZIO_WAIT_TYPES; w++)
+			pio->io_children[cio->io_child_type][w]++;
+		mutex_exit(&pio->io_lock);
+		zio_reexecute(cio);
+	}
+
+	/*
+	 * Now that all children have been reexecuted, execute the parent.
+	 * We don't reexecute "The Godfather" I/O here as it's the
+	 * responsibility of the caller to wait on him.
+	 */
+	if (!(pio->io_flags & ZIO_FLAG_GODFATHER))
+		__zio_execute(pio);
+}
+
+void
+zio_suspend(spa_t *spa, zio_t *zio)
+{
+	if (spa_get_failmode(spa) == ZIO_FAILURE_MODE_PANIC)
+		fm_panic("Pool '%s' has encountered an uncorrectable I/O "
+		    "failure and the failure mode property for this pool "
+		    "is set to panic.", spa_name(spa));
+
+	cmn_err(CE_WARN, "Pool '%s' has encountered an uncorrectable I/O "
+	    "failure and has been suspended.\n", spa_name(spa));
+
+	zfs_ereport_post(FM_EREPORT_ZFS_IO_FAILURE, spa, NULL, NULL, 0, 0);
+
+	mutex_enter(&spa->spa_suspend_lock);
+
+	if (spa->spa_suspend_zio_root == NULL)
+		spa->spa_suspend_zio_root = zio_root(spa, NULL, NULL,
+		    ZIO_FLAG_CANFAIL | ZIO_FLAG_SPECULATIVE |
+		    ZIO_FLAG_GODFATHER);
+
+	spa->spa_suspended = B_TRUE;
+
+	if (zio != NULL) {
+		ASSERT(!(zio->io_flags & ZIO_FLAG_GODFATHER));
+		ASSERT(zio != spa->spa_suspend_zio_root);
+		ASSERT(zio->io_child_type == ZIO_CHILD_LOGICAL);
+		ASSERT(zio_unique_parent(zio) == NULL);
+		ASSERT(zio->io_stage == ZIO_STAGE_DONE);
+		zio_add_child(spa->spa_suspend_zio_root, zio);
+	}
+
+	mutex_exit(&spa->spa_suspend_lock);
+}
+
+int
+zio_resume(spa_t *spa)
+{
+	zio_t *pio;
+
+	/*
+	 * Reexecute all previously suspended i/o.
+	 */
+	mutex_enter(&spa->spa_suspend_lock);
+	spa->spa_suspended = B_FALSE;
+	cv_broadcast(&spa->spa_suspend_cv);
+	pio = spa->spa_suspend_zio_root;
+	spa->spa_suspend_zio_root = NULL;
+	mutex_exit(&spa->spa_suspend_lock);
+
+	if (pio == NULL)
+		return (0);
+
+	zio_reexecute(pio);
+	return (zio_wait(pio));
+}
+
+void
+zio_resume_wait(spa_t *spa)
+{
+	mutex_enter(&spa->spa_suspend_lock);
+	while (spa_suspended(spa))
+		cv_wait(&spa->spa_suspend_cv, &spa->spa_suspend_lock);
+	mutex_exit(&spa->spa_suspend_lock);
+}
+
+/*
+ * ==========================================================================
+ * Gang blocks.
+ *
+ * A gang block is a collection of small blocks that looks to the DMU
+ * like one large block.  When zio_dva_allocate() cannot find a block
+ * of the requested size, due to either severe fragmentation or the pool
+ * being nearly full, it calls zio_write_gang_block() to construct the
+ * block from smaller fragments.
+ *
+ * A gang block consists of a gang header (zio_gbh_phys_t) and up to
+ * three (SPA_GBH_NBLKPTRS) gang members.  The gang header is just like
+ * an indirect block: it's an array of block pointers.  It consumes
+ * only one sector and hence is allocatable regardless of fragmentation.
+ * The gang header's bps point to its gang members, which hold the data.
+ *
+ * Gang blocks are self-checksumming, using the bp's <vdev, offset, txg>
+ * as the verifier to ensure uniqueness of the SHA256 checksum.
+ * Critically, the gang block bp's blk_cksum is the checksum of the data,
+ * not the gang header.  This ensures that data block signatures (needed for
+ * deduplication) are independent of how the block is physically stored.
+ *
+ * Gang blocks can be nested: a gang member may itself be a gang block.
+ * Thus every gang block is a tree in which root and all interior nodes are
+ * gang headers, and the leaves are normal blocks that contain user data.
+ * The root of the gang tree is called the gang leader.
+ *
+ * To perform any operation (read, rewrite, free, claim) on a gang block,
+ * zio_gang_assemble() first assembles the gang tree (minus data leaves)
+ * in the io_gang_tree field of the original logical i/o by recursively
+ * reading the gang leader and all gang headers below it.  This yields
+ * an in-core tree containing the contents of every gang header and the
+ * bps for every constituent of the gang block.
+ *
+ * With the gang tree now assembled, zio_gang_issue() just walks the gang tree
+ * and invokes a callback on each bp.  To free a gang block, zio_gang_issue()
+ * calls zio_free_gang() -- a trivial wrapper around zio_free() -- for each bp.
+ * zio_claim_gang() provides a similarly trivial wrapper for zio_claim().
+ * zio_read_gang() is a wrapper around zio_read() that omits reading gang
+ * headers, since we already have those in io_gang_tree.  zio_rewrite_gang()
+ * performs a zio_rewrite() of the data or, for gang headers, a zio_rewrite()
+ * of the gang header plus zio_checksum_compute() of the data to update the
+ * gang header's blk_cksum as described above.
+ *
+ * The two-phase assemble/issue model solves the problem of partial failure --
+ * what if you'd freed part of a gang block but then couldn't read the
+ * gang header for another part?  Assembling the entire gang tree first
+ * ensures that all the necessary gang header I/O has succeeded before
+ * starting the actual work of free, claim, or write.  Once the gang tree
+ * is assembled, free and claim are in-memory operations that cannot fail.
+ *
+ * In the event that a gang write fails, zio_dva_unallocate() walks the
+ * gang tree to immediately free (i.e. insert back into the space map)
+ * everything we've allocated.  This ensures that we don't get ENOSPC
+ * errors during repeated suspend/resume cycles due to a flaky device.
+ *
+ * Gang rewrites only happen during sync-to-convergence.  If we can't assemble
+ * the gang tree, we won't modify the block, so we can safely defer the free
+ * (knowing that the block is still intact).  If we *can* assemble the gang
+ * tree, then even if some of the rewrites fail, zio_dva_unallocate() will free
+ * each constituent bp and we can allocate a new block on the next sync pass.
+ *
+ * In all cases, the gang tree allows complete recovery from partial failure.
+ * ==========================================================================
+ */
+
+static zio_t *
+zio_read_gang(zio_t *pio, blkptr_t *bp, zio_gang_node_t *gn, void *data)
+{
+	if (gn != NULL)
+		return (pio);
+
+	return (zio_read(pio, pio->io_spa, bp, data, BP_GET_PSIZE(bp),
+	    NULL, NULL, pio->io_priority, ZIO_GANG_CHILD_FLAGS(pio),
+	    &pio->io_bookmark));
+}
+
+zio_t *
+zio_rewrite_gang(zio_t *pio, blkptr_t *bp, zio_gang_node_t *gn, void *data)
+{
+	zio_t *zio;
+
+	if (gn != NULL) {
+		zio = zio_rewrite(pio, pio->io_spa, pio->io_txg, bp,
+		    gn->gn_gbh, SPA_GANGBLOCKSIZE, NULL, NULL, pio->io_priority,
+		    ZIO_GANG_CHILD_FLAGS(pio), &pio->io_bookmark);
+		/*
+		 * As we rewrite each gang header, the pipeline will compute
+		 * a new gang block header checksum for it; but no one will
+		 * compute a new data checksum, so we do that here.  The one
+		 * exception is the gang leader: the pipeline already computed
+		 * its data checksum because that stage precedes gang assembly.
+		 * (Presently, nothing actually uses interior data checksums;
+		 * this is just good hygiene.)
+		 */
+		if (gn != pio->io_gang_leader->io_gang_tree) {
+			zio_checksum_compute(zio, BP_GET_CHECKSUM(bp),
+			    data, BP_GET_PSIZE(bp));
+		}
+		/*
+		 * If we are here to damage data for testing purposes,
+		 * leave the GBH alone so that we can detect the damage.
+		 */
+		if (pio->io_gang_leader->io_flags & ZIO_FLAG_INDUCE_DAMAGE)
+			zio->io_pipeline &= ~ZIO_VDEV_IO_STAGES;
+	} else {
+		zio = zio_rewrite(pio, pio->io_spa, pio->io_txg, bp,
+		    data, BP_GET_PSIZE(bp), NULL, NULL, pio->io_priority,
+		    ZIO_GANG_CHILD_FLAGS(pio), &pio->io_bookmark);
+	}
+
+	return (zio);
+}
+
+/* ARGSUSED */
+zio_t *
+zio_free_gang(zio_t *pio, blkptr_t *bp, zio_gang_node_t *gn, void *data)
+{
+	return (zio_free_sync(pio, pio->io_spa, pio->io_txg, bp,
+	    ZIO_GANG_CHILD_FLAGS(pio)));
+}
+
+/* ARGSUSED */
+zio_t *
+zio_claim_gang(zio_t *pio, blkptr_t *bp, zio_gang_node_t *gn, void *data)
+{
+	return (zio_claim(pio, pio->io_spa, pio->io_txg, bp,
+	    NULL, NULL, ZIO_GANG_CHILD_FLAGS(pio)));
+}
+
+static zio_gang_issue_func_t *zio_gang_issue_func[ZIO_TYPES] = {
+	NULL,
+	zio_read_gang,
+	zio_rewrite_gang,
+	zio_free_gang,
+	zio_claim_gang,
+	NULL
+};
+
+static void zio_gang_tree_assemble_done(zio_t *zio);
+
+static zio_gang_node_t *
+zio_gang_node_alloc(zio_gang_node_t **gnpp)
+{
+	zio_gang_node_t *gn;
+
+	ASSERT(*gnpp == NULL);
+
+	gn = kmem_zalloc(sizeof (*gn), KM_SLEEP);
+	gn->gn_gbh = zio_buf_alloc(SPA_GANGBLOCKSIZE);
+	*gnpp = gn;
+
+	return (gn);
+}
+
+static void
+zio_gang_node_free(zio_gang_node_t **gnpp)
+{
+	zio_gang_node_t *gn = *gnpp;
+	int g;
+
+	for (g = 0; g < SPA_GBH_NBLKPTRS; g++)
+		ASSERT(gn->gn_child[g] == NULL);
+
+	zio_buf_free(gn->gn_gbh, SPA_GANGBLOCKSIZE);
+	kmem_free(gn, sizeof (*gn));
+	*gnpp = NULL;
+}
+
+static void
+zio_gang_tree_free(zio_gang_node_t **gnpp)
+{
+	zio_gang_node_t *gn = *gnpp;
+	int g;
+
+	if (gn == NULL)
+		return;
+
+	for (g = 0; g < SPA_GBH_NBLKPTRS; g++)
+		zio_gang_tree_free(&gn->gn_child[g]);
+
+	zio_gang_node_free(gnpp);
+}
+
+static void
+zio_gang_tree_assemble(zio_t *gio, blkptr_t *bp, zio_gang_node_t **gnpp)
+{
+	zio_gang_node_t *gn = zio_gang_node_alloc(gnpp);
+
+	ASSERT(gio->io_gang_leader == gio);
+	ASSERT(BP_IS_GANG(bp));
+
+	zio_nowait(zio_read(gio, gio->io_spa, bp, gn->gn_gbh,
+	    SPA_GANGBLOCKSIZE, zio_gang_tree_assemble_done, gn,
+	    gio->io_priority, ZIO_GANG_CHILD_FLAGS(gio), &gio->io_bookmark));
+}
+
+static void
+zio_gang_tree_assemble_done(zio_t *zio)
+{
+	zio_t *gio = zio->io_gang_leader;
+	zio_gang_node_t *gn = zio->io_private;
+	blkptr_t *bp = zio->io_bp;
+	int g;
+
+	ASSERT(gio == zio_unique_parent(zio));
+	ASSERT(zio->io_child_count == 0);
+
+	if (zio->io_error)
+		return;
+
+	if (BP_SHOULD_BYTESWAP(bp))
+		byteswap_uint64_array(zio->io_data, zio->io_size);
+
+	ASSERT(zio->io_data == gn->gn_gbh);
+	ASSERT(zio->io_size == SPA_GANGBLOCKSIZE);
+	ASSERT(gn->gn_gbh->zg_tail.zec_magic == ZEC_MAGIC);
+
+	for (g = 0; g < SPA_GBH_NBLKPTRS; g++) {
+		blkptr_t *gbp = &gn->gn_gbh->zg_blkptr[g];
+		if (!BP_IS_GANG(gbp))
+			continue;
+		zio_gang_tree_assemble(gio, gbp, &gn->gn_child[g]);
+	}
+}
+
+static void
+zio_gang_tree_issue(zio_t *pio, zio_gang_node_t *gn, blkptr_t *bp, void *data)
+{
+	zio_t *gio = pio->io_gang_leader;
+	zio_t *zio;
+	int g;
+
+	ASSERT(BP_IS_GANG(bp) == !!gn);
+	ASSERT(BP_GET_CHECKSUM(bp) == BP_GET_CHECKSUM(gio->io_bp));
+	ASSERT(BP_GET_LSIZE(bp) == BP_GET_PSIZE(bp) || gn == gio->io_gang_tree);
+
+	/*
+	 * If you're a gang header, your data is in gn->gn_gbh.
+	 * If you're a gang member, your data is in 'data' and gn == NULL.
+	 */
+	zio = zio_gang_issue_func[gio->io_type](pio, bp, gn, data);
+
+	if (gn != NULL) {
+		ASSERT(gn->gn_gbh->zg_tail.zec_magic == ZEC_MAGIC);
+
+		for (g = 0; g < SPA_GBH_NBLKPTRS; g++) {
+			blkptr_t *gbp = &gn->gn_gbh->zg_blkptr[g];
+			if (BP_IS_HOLE(gbp))
+				continue;
+			zio_gang_tree_issue(zio, gn->gn_child[g], gbp, data);
+			data = (char *)data + BP_GET_PSIZE(gbp);
+		}
+	}
+
+	if (gn == gio->io_gang_tree)
+		ASSERT3P((char *)gio->io_data + gio->io_size, ==, data);
+
+	if (zio != pio)
+		zio_nowait(zio);
+}
+
+static int
+zio_gang_assemble(zio_t *zio)
+{
+	blkptr_t *bp = zio->io_bp;
+
+	ASSERT(BP_IS_GANG(bp) && zio->io_gang_leader == NULL);
+	ASSERT(zio->io_child_type > ZIO_CHILD_GANG);
+
+	zio->io_gang_leader = zio;
+
+	zio_gang_tree_assemble(zio, bp, &zio->io_gang_tree);
+
+	return (ZIO_PIPELINE_CONTINUE);
+}
+
+static int
+zio_gang_issue(zio_t *zio)
+{
+	blkptr_t *bp = zio->io_bp;
+
+	if (zio_wait_for_children(zio, ZIO_CHILD_GANG, ZIO_WAIT_DONE))
+		return (ZIO_PIPELINE_STOP);
+
+	ASSERT(BP_IS_GANG(bp) && zio->io_gang_leader == zio);
+	ASSERT(zio->io_child_type > ZIO_CHILD_GANG);
+
+	if (zio->io_child_error[ZIO_CHILD_GANG] == 0)
+		zio_gang_tree_issue(zio, zio->io_gang_tree, bp, zio->io_data);
+	else
+		zio_gang_tree_free(&zio->io_gang_tree);
+
+	zio->io_pipeline = ZIO_INTERLOCK_PIPELINE;
+
+	return (ZIO_PIPELINE_CONTINUE);
+}
+
+static void
+zio_write_gang_member_ready(zio_t *zio)
+{
+	zio_t *pio = zio_unique_parent(zio);
+	dva_t *cdva = zio->io_bp->blk_dva;
+	dva_t *pdva = pio->io_bp->blk_dva;
+	uint64_t asize;
+	int d;
+	ASSERTV(zio_t *gio = zio->io_gang_leader);
+
+	if (BP_IS_HOLE(zio->io_bp))
+		return;
+
+	ASSERT(BP_IS_HOLE(&zio->io_bp_orig));
+
+	ASSERT(zio->io_child_type == ZIO_CHILD_GANG);
+	ASSERT3U(zio->io_prop.zp_copies, ==, gio->io_prop.zp_copies);
+	ASSERT3U(zio->io_prop.zp_copies, <=, BP_GET_NDVAS(zio->io_bp));
+	ASSERT3U(pio->io_prop.zp_copies, <=, BP_GET_NDVAS(pio->io_bp));
+	ASSERT3U(BP_GET_NDVAS(zio->io_bp), <=, BP_GET_NDVAS(pio->io_bp));
+
+	mutex_enter(&pio->io_lock);
+	for (d = 0; d < BP_GET_NDVAS(zio->io_bp); d++) {
+		ASSERT(DVA_GET_GANG(&pdva[d]));
+		asize = DVA_GET_ASIZE(&pdva[d]);
+		asize += DVA_GET_ASIZE(&cdva[d]);
+		DVA_SET_ASIZE(&pdva[d], asize);
+	}
+	mutex_exit(&pio->io_lock);
+}
+
+static int
+zio_write_gang_block(zio_t *pio)
+{
+	spa_t *spa = pio->io_spa;
+	blkptr_t *bp = pio->io_bp;
+	zio_t *gio = pio->io_gang_leader;
+	zio_t *zio;
+	zio_gang_node_t *gn, **gnpp;
+	zio_gbh_phys_t *gbh;
+	uint64_t txg = pio->io_txg;
+	uint64_t resid = pio->io_size;
+	uint64_t lsize;
+	int copies = gio->io_prop.zp_copies;
+	int gbh_copies = MIN(copies + 1, spa_max_replication(spa));
+	zio_prop_t zp;
+	int g, error;
+
+	error = metaslab_alloc(spa, spa_normal_class(spa), SPA_GANGBLOCKSIZE,
+	    bp, gbh_copies, txg, pio == gio ? NULL : gio->io_bp,
+	    METASLAB_HINTBP_FAVOR | METASLAB_GANG_HEADER);
+	if (error) {
+		pio->io_error = error;
+		return (ZIO_PIPELINE_CONTINUE);
+	}
+
+	if (pio == gio) {
+		gnpp = &gio->io_gang_tree;
+	} else {
+		gnpp = pio->io_private;
+		ASSERT(pio->io_ready == zio_write_gang_member_ready);
+	}
+
+	gn = zio_gang_node_alloc(gnpp);
+	gbh = gn->gn_gbh;
+	bzero(gbh, SPA_GANGBLOCKSIZE);
+
+	/*
+	 * Create the gang header.
+	 */
+	zio = zio_rewrite(pio, spa, txg, bp, gbh, SPA_GANGBLOCKSIZE, NULL, NULL,
+	    pio->io_priority, ZIO_GANG_CHILD_FLAGS(pio), &pio->io_bookmark);
+
+	/*
+	 * Create and nowait the gang children.
+	 */
+	for (g = 0; resid != 0; resid -= lsize, g++) {
+		lsize = P2ROUNDUP(resid / (SPA_GBH_NBLKPTRS - g),
+		    SPA_MINBLOCKSIZE);
+		ASSERT(lsize >= SPA_MINBLOCKSIZE && lsize <= resid);
+
+		zp.zp_checksum = gio->io_prop.zp_checksum;
+		zp.zp_compress = ZIO_COMPRESS_OFF;
+		zp.zp_type = DMU_OT_NONE;
+		zp.zp_level = 0;
+		zp.zp_copies = gio->io_prop.zp_copies;
+		zp.zp_dedup = B_FALSE;
+		zp.zp_dedup_verify = B_FALSE;
+		zp.zp_nopwrite = B_FALSE;
+
+		zio_nowait(zio_write(zio, spa, txg, &gbh->zg_blkptr[g],
+		    (char *)pio->io_data + (pio->io_size - resid), lsize, &zp,
+		    zio_write_gang_member_ready, NULL, NULL, &gn->gn_child[g],
+		    pio->io_priority, ZIO_GANG_CHILD_FLAGS(pio),
+		    &pio->io_bookmark));
+	}
+
+	/*
+	 * Set pio's pipeline to just wait for zio to finish.
+	 */
+	pio->io_pipeline = ZIO_INTERLOCK_PIPELINE;
+
+	/*
+	 * We didn't allocate this bp, so make sure it doesn't get unmarked.
+	 */
+	pio->io_flags &= ~ZIO_FLAG_FASTWRITE;
+
+	zio_nowait(zio);
+
+	return (ZIO_PIPELINE_CONTINUE);
+}
+
+/*
+ * The zio_nop_write stage in the pipeline determines if allocating
+ * a new bp is necessary.  By leveraging a cryptographically secure checksum,
+ * such as SHA256, we can compare the checksums of the new data and the old
+ * to determine if allocating a new block is required.  The nopwrite
+ * feature can handle writes in either syncing or open context (i.e. zil
+ * writes) and as a result is mutually exclusive with dedup.
+ */
+static int
+zio_nop_write(zio_t *zio)
+{
+	blkptr_t *bp = zio->io_bp;
+	blkptr_t *bp_orig = &zio->io_bp_orig;
+	zio_prop_t *zp = &zio->io_prop;
+
+	ASSERT(BP_GET_LEVEL(bp) == 0);
+	ASSERT(!(zio->io_flags & ZIO_FLAG_IO_REWRITE));
+	ASSERT(zp->zp_nopwrite);
+	ASSERT(!zp->zp_dedup);
+	ASSERT(zio->io_bp_override == NULL);
+	ASSERT(IO_IS_ALLOCATING(zio));
+
+	/*
+	 * Check to see if the original bp and the new bp have matching
+	 * characteristics (i.e. same checksum, compression algorithms, etc).
+	 * If they don't then just continue with the pipeline which will
+	 * allocate a new bp.
+	 */
+	if (BP_IS_HOLE(bp_orig) ||
+	    !zio_checksum_table[BP_GET_CHECKSUM(bp)].ci_dedup ||
+	    BP_GET_CHECKSUM(bp) != BP_GET_CHECKSUM(bp_orig) ||
+	    BP_GET_COMPRESS(bp) != BP_GET_COMPRESS(bp_orig) ||
+	    BP_GET_DEDUP(bp) != BP_GET_DEDUP(bp_orig) ||
+	    zp->zp_copies != BP_GET_NDVAS(bp_orig))
+		return (ZIO_PIPELINE_CONTINUE);
+
+	/*
+	 * If the checksums match then reset the pipeline so that we
+	 * avoid allocating a new bp and issuing any I/O.
+	 */
+	if (ZIO_CHECKSUM_EQUAL(bp->blk_cksum, bp_orig->blk_cksum)) {
+		ASSERT(zio_checksum_table[zp->zp_checksum].ci_dedup);
+		ASSERT3U(BP_GET_PSIZE(bp), ==, BP_GET_PSIZE(bp_orig));
+		ASSERT3U(BP_GET_LSIZE(bp), ==, BP_GET_LSIZE(bp_orig));
+		ASSERT(zp->zp_compress != ZIO_COMPRESS_OFF);
+		ASSERT(bcmp(&bp->blk_prop, &bp_orig->blk_prop,
+		    sizeof (uint64_t)) == 0);
+
+		*bp = *bp_orig;
+		zio->io_pipeline = ZIO_INTERLOCK_PIPELINE;
+		zio->io_flags |= ZIO_FLAG_NOPWRITE;
+	}
+
+	return (ZIO_PIPELINE_CONTINUE);
+}
+
+/*
+ * ==========================================================================
+ * Dedup
+ * ==========================================================================
+ */
+static void
+zio_ddt_child_read_done(zio_t *zio)
+{
+	blkptr_t *bp = zio->io_bp;
+	ddt_entry_t *dde = zio->io_private;
+	ddt_phys_t *ddp;
+	zio_t *pio = zio_unique_parent(zio);
+
+	mutex_enter(&pio->io_lock);
+	ddp = ddt_phys_select(dde, bp);
+	if (zio->io_error == 0)
+		ddt_phys_clear(ddp);	/* this ddp doesn't need repair */
+	if (zio->io_error == 0 && dde->dde_repair_data == NULL)
+		dde->dde_repair_data = zio->io_data;
+	else
+		zio_buf_free(zio->io_data, zio->io_size);
+	mutex_exit(&pio->io_lock);
+}
+
+static int
+zio_ddt_read_start(zio_t *zio)
+{
+	blkptr_t *bp = zio->io_bp;
+	int p;
+
+	ASSERT(BP_GET_DEDUP(bp));
+	ASSERT(BP_GET_PSIZE(bp) == zio->io_size);
+	ASSERT(zio->io_child_type == ZIO_CHILD_LOGICAL);
+
+	if (zio->io_child_error[ZIO_CHILD_DDT]) {
+		ddt_t *ddt = ddt_select(zio->io_spa, bp);
+		ddt_entry_t *dde = ddt_repair_start(ddt, bp);
+		ddt_phys_t *ddp = dde->dde_phys;
+		ddt_phys_t *ddp_self = ddt_phys_select(dde, bp);
+		blkptr_t blk;
+
+		ASSERT(zio->io_vsd == NULL);
+		zio->io_vsd = dde;
+
+		if (ddp_self == NULL)
+			return (ZIO_PIPELINE_CONTINUE);
+
+		for (p = 0; p < DDT_PHYS_TYPES; p++, ddp++) {
+			if (ddp->ddp_phys_birth == 0 || ddp == ddp_self)
+				continue;
+			ddt_bp_create(ddt->ddt_checksum, &dde->dde_key, ddp,
+			    &blk);
+			zio_nowait(zio_read(zio, zio->io_spa, &blk,
+			    zio_buf_alloc(zio->io_size), zio->io_size,
+			    zio_ddt_child_read_done, dde, zio->io_priority,
+			    ZIO_DDT_CHILD_FLAGS(zio) | ZIO_FLAG_DONT_PROPAGATE,
+			    &zio->io_bookmark));
+		}
+		return (ZIO_PIPELINE_CONTINUE);
+	}
+
+	zio_nowait(zio_read(zio, zio->io_spa, bp,
+	    zio->io_data, zio->io_size, NULL, NULL, zio->io_priority,
+	    ZIO_DDT_CHILD_FLAGS(zio), &zio->io_bookmark));
+
+	return (ZIO_PIPELINE_CONTINUE);
+}
+
+static int
+zio_ddt_read_done(zio_t *zio)
+{
+	blkptr_t *bp = zio->io_bp;
+
+	if (zio_wait_for_children(zio, ZIO_CHILD_DDT, ZIO_WAIT_DONE))
+		return (ZIO_PIPELINE_STOP);
+
+	ASSERT(BP_GET_DEDUP(bp));
+	ASSERT(BP_GET_PSIZE(bp) == zio->io_size);
+	ASSERT(zio->io_child_type == ZIO_CHILD_LOGICAL);
+
+	if (zio->io_child_error[ZIO_CHILD_DDT]) {
+		ddt_t *ddt = ddt_select(zio->io_spa, bp);
+		ddt_entry_t *dde = zio->io_vsd;
+		if (ddt == NULL) {
+			ASSERT(spa_load_state(zio->io_spa) != SPA_LOAD_NONE);
+			return (ZIO_PIPELINE_CONTINUE);
+		}
+		if (dde == NULL) {
+			zio->io_stage = ZIO_STAGE_DDT_READ_START >> 1;
+			zio_taskq_dispatch(zio, ZIO_TASKQ_ISSUE, B_FALSE);
+			return (ZIO_PIPELINE_STOP);
+		}
+		if (dde->dde_repair_data != NULL) {
+			bcopy(dde->dde_repair_data, zio->io_data, zio->io_size);
+			zio->io_child_error[ZIO_CHILD_DDT] = 0;
+		}
+		ddt_repair_done(ddt, dde);
+		zio->io_vsd = NULL;
+	}
+
+	ASSERT(zio->io_vsd == NULL);
+
+	return (ZIO_PIPELINE_CONTINUE);
+}
+
+static boolean_t
+zio_ddt_collision(zio_t *zio, ddt_t *ddt, ddt_entry_t *dde)
+{
+	spa_t *spa = zio->io_spa;
+	int p;
+
+	/*
+	 * Note: we compare the original data, not the transformed data,
+	 * because when zio->io_bp is an override bp, we will not have
+	 * pushed the I/O transforms.  That's an important optimization
+	 * because otherwise we'd compress/encrypt all dmu_sync() data twice.
+	 */
+	for (p = DDT_PHYS_SINGLE; p <= DDT_PHYS_TRIPLE; p++) {
+		zio_t *lio = dde->dde_lead_zio[p];
+
+		if (lio != NULL) {
+			return (lio->io_orig_size != zio->io_orig_size ||
+			    bcmp(zio->io_orig_data, lio->io_orig_data,
+			    zio->io_orig_size) != 0);
+		}
+	}
+
+	for (p = DDT_PHYS_SINGLE; p <= DDT_PHYS_TRIPLE; p++) {
+		ddt_phys_t *ddp = &dde->dde_phys[p];
+
+		if (ddp->ddp_phys_birth != 0) {
+			arc_buf_t *abuf = NULL;
+			arc_flags_t aflags = ARC_FLAG_WAIT;
+			blkptr_t blk = *zio->io_bp;
+			int error;
+
+			ddt_bp_fill(ddp, &blk, ddp->ddp_phys_birth);
+
+			ddt_exit(ddt);
+
+			error = arc_read(NULL, spa, &blk,
+			    arc_getbuf_func, &abuf, ZIO_PRIORITY_SYNC_READ,
+			    ZIO_FLAG_CANFAIL | ZIO_FLAG_SPECULATIVE,
+			    &aflags, &zio->io_bookmark);
+
+			if (error == 0) {
+				if (arc_buf_size(abuf) != zio->io_orig_size ||
+				    bcmp(abuf->b_data, zio->io_orig_data,
+				    zio->io_orig_size) != 0)
+					error = SET_ERROR(EEXIST);
+				VERIFY(arc_buf_remove_ref(abuf, &abuf));
+			}
+
+			ddt_enter(ddt);
+			return (error != 0);
+		}
+	}
+
+	return (B_FALSE);
+}
+
+static void
+zio_ddt_child_write_ready(zio_t *zio)
+{
+	int p = zio->io_prop.zp_copies;
+	ddt_t *ddt = ddt_select(zio->io_spa, zio->io_bp);
+	ddt_entry_t *dde = zio->io_private;
+	ddt_phys_t *ddp = &dde->dde_phys[p];
+	zio_t *pio;
+
+	if (zio->io_error)
+		return;
+
+	ddt_enter(ddt);
+
+	ASSERT(dde->dde_lead_zio[p] == zio);
+
+	ddt_phys_fill(ddp, zio->io_bp);
+
+	while ((pio = zio_walk_parents(zio)) != NULL)
+		ddt_bp_fill(ddp, pio->io_bp, zio->io_txg);
+
+	ddt_exit(ddt);
+}
+
+static void
+zio_ddt_child_write_done(zio_t *zio)
+{
+	int p = zio->io_prop.zp_copies;
+	ddt_t *ddt = ddt_select(zio->io_spa, zio->io_bp);
+	ddt_entry_t *dde = zio->io_private;
+	ddt_phys_t *ddp = &dde->dde_phys[p];
+
+	ddt_enter(ddt);
+
+	ASSERT(ddp->ddp_refcnt == 0);
+	ASSERT(dde->dde_lead_zio[p] == zio);
+	dde->dde_lead_zio[p] = NULL;
+
+	if (zio->io_error == 0) {
+		while (zio_walk_parents(zio) != NULL)
+			ddt_phys_addref(ddp);
+	} else {
+		ddt_phys_clear(ddp);
+	}
+
+	ddt_exit(ddt);
+}
+
+static void
+zio_ddt_ditto_write_done(zio_t *zio)
+{
+	int p = DDT_PHYS_DITTO;
+	blkptr_t *bp = zio->io_bp;
+	ddt_t *ddt = ddt_select(zio->io_spa, bp);
+	ddt_entry_t *dde = zio->io_private;
+	ddt_phys_t *ddp = &dde->dde_phys[p];
+	ddt_key_t *ddk = &dde->dde_key;
+	ASSERTV(zio_prop_t *zp = &zio->io_prop);
+
+	ddt_enter(ddt);
+
+	ASSERT(ddp->ddp_refcnt == 0);
+	ASSERT(dde->dde_lead_zio[p] == zio);
+	dde->dde_lead_zio[p] = NULL;
+
+	if (zio->io_error == 0) {
+		ASSERT(ZIO_CHECKSUM_EQUAL(bp->blk_cksum, ddk->ddk_cksum));
+		ASSERT(zp->zp_copies < SPA_DVAS_PER_BP);
+		ASSERT(zp->zp_copies == BP_GET_NDVAS(bp) - BP_IS_GANG(bp));
+		if (ddp->ddp_phys_birth != 0)
+			ddt_phys_free(ddt, ddk, ddp, zio->io_txg);
+		ddt_phys_fill(ddp, bp);
+	}
+
+	ddt_exit(ddt);
+}
+
+static int
+zio_ddt_write(zio_t *zio)
+{
+	spa_t *spa = zio->io_spa;
+	blkptr_t *bp = zio->io_bp;
+	uint64_t txg = zio->io_txg;
+	zio_prop_t *zp = &zio->io_prop;
+	int p = zp->zp_copies;
+	int ditto_copies;
+	zio_t *cio = NULL;
+	zio_t *dio = NULL;
+	ddt_t *ddt = ddt_select(spa, bp);
+	ddt_entry_t *dde;
+	ddt_phys_t *ddp;
+
+	ASSERT(BP_GET_DEDUP(bp));
+	ASSERT(BP_GET_CHECKSUM(bp) == zp->zp_checksum);
+	ASSERT(BP_IS_HOLE(bp) || zio->io_bp_override);
+
+	ddt_enter(ddt);
+	dde = ddt_lookup(ddt, bp, B_TRUE);
+	ddp = &dde->dde_phys[p];
+
+	if (zp->zp_dedup_verify && zio_ddt_collision(zio, ddt, dde)) {
+		/*
+		 * If we're using a weak checksum, upgrade to a strong checksum
+		 * and try again.  If we're already using a strong checksum,
+		 * we can't resolve it, so just convert to an ordinary write.
+		 * (And automatically e-mail a paper to Nature?)
+		 */
+		if (!zio_checksum_table[zp->zp_checksum].ci_dedup) {
+			zp->zp_checksum = spa_dedup_checksum(spa);
+			zio_pop_transforms(zio);
+			zio->io_stage = ZIO_STAGE_OPEN;
+			BP_ZERO(bp);
+		} else {
+			zp->zp_dedup = B_FALSE;
+		}
+		zio->io_pipeline = ZIO_WRITE_PIPELINE;
+		ddt_exit(ddt);
+		return (ZIO_PIPELINE_CONTINUE);
+	}
+
+	ditto_copies = ddt_ditto_copies_needed(ddt, dde, ddp);
+	ASSERT(ditto_copies < SPA_DVAS_PER_BP);
+
+	if (ditto_copies > ddt_ditto_copies_present(dde) &&
+	    dde->dde_lead_zio[DDT_PHYS_DITTO] == NULL) {
+		zio_prop_t czp = *zp;
+
+		czp.zp_copies = ditto_copies;
+
+		/*
+		 * If we arrived here with an override bp, we won't have run
+		 * the transform stack, so we won't have the data we need to
+		 * generate a child i/o.  So, toss the override bp and restart.
+		 * This is safe, because using the override bp is just an
+		 * optimization; and it's rare, so the cost doesn't matter.
+		 */
+		if (zio->io_bp_override) {
+			zio_pop_transforms(zio);
+			zio->io_stage = ZIO_STAGE_OPEN;
+			zio->io_pipeline = ZIO_WRITE_PIPELINE;
+			zio->io_bp_override = NULL;
+			BP_ZERO(bp);
+			ddt_exit(ddt);
+			return (ZIO_PIPELINE_CONTINUE);
+		}
+
+		dio = zio_write(zio, spa, txg, bp, zio->io_orig_data,
+		    zio->io_orig_size, &czp, NULL, NULL,
+		    zio_ddt_ditto_write_done, dde, zio->io_priority,
+		    ZIO_DDT_CHILD_FLAGS(zio), &zio->io_bookmark);
+
+		zio_push_transform(dio, zio->io_data, zio->io_size, 0, NULL);
+		dde->dde_lead_zio[DDT_PHYS_DITTO] = dio;
+	}
+
+	if (ddp->ddp_phys_birth != 0 || dde->dde_lead_zio[p] != NULL) {
+		if (ddp->ddp_phys_birth != 0)
+			ddt_bp_fill(ddp, bp, txg);
+		if (dde->dde_lead_zio[p] != NULL)
+			zio_add_child(zio, dde->dde_lead_zio[p]);
+		else
+			ddt_phys_addref(ddp);
+	} else if (zio->io_bp_override) {
+		ASSERT(bp->blk_birth == txg);
+		ASSERT(BP_EQUAL(bp, zio->io_bp_override));
+		ddt_phys_fill(ddp, bp);
+		ddt_phys_addref(ddp);
+	} else {
+		cio = zio_write(zio, spa, txg, bp, zio->io_orig_data,
+		    zio->io_orig_size, zp, zio_ddt_child_write_ready, NULL,
+		    zio_ddt_child_write_done, dde, zio->io_priority,
+		    ZIO_DDT_CHILD_FLAGS(zio), &zio->io_bookmark);
+
+		zio_push_transform(cio, zio->io_data, zio->io_size, 0, NULL);
+		dde->dde_lead_zio[p] = cio;
+	}
+
+	ddt_exit(ddt);
+
+	if (cio)
+		zio_nowait(cio);
+	if (dio)
+		zio_nowait(dio);
+
+	return (ZIO_PIPELINE_CONTINUE);
+}
+
+ddt_entry_t *freedde; /* for debugging */
+
+static int
+zio_ddt_free(zio_t *zio)
+{
+	spa_t *spa = zio->io_spa;
+	blkptr_t *bp = zio->io_bp;
+	ddt_t *ddt = ddt_select(spa, bp);
+	ddt_entry_t *dde;
+	ddt_phys_t *ddp;
+
+	ASSERT(BP_GET_DEDUP(bp));
+	ASSERT(zio->io_child_type == ZIO_CHILD_LOGICAL);
+
+	ddt_enter(ddt);
+	freedde = dde = ddt_lookup(ddt, bp, B_TRUE);
+	if (dde) {
+		ddp = ddt_phys_select(dde, bp);
+		if (ddp)
+			ddt_phys_decref(ddp);
+	}
+	ddt_exit(ddt);
+
+	return (ZIO_PIPELINE_CONTINUE);
+}
+
+/*
+ * ==========================================================================
+ * Allocate and free blocks
+ * ==========================================================================
+ */
+static int
+zio_dva_allocate(zio_t *zio)
+{
+	spa_t *spa = zio->io_spa;
+	metaslab_class_t *mc = spa_normal_class(spa);
+	blkptr_t *bp = zio->io_bp;
+	int error;
+	int flags = 0;
+
+	if (zio->io_gang_leader == NULL) {
+		ASSERT(zio->io_child_type > ZIO_CHILD_GANG);
+		zio->io_gang_leader = zio;
+	}
+
+	ASSERT(BP_IS_HOLE(bp));
+	ASSERT0(BP_GET_NDVAS(bp));
+	ASSERT3U(zio->io_prop.zp_copies, >, 0);
+	ASSERT3U(zio->io_prop.zp_copies, <=, spa_max_replication(spa));
+	ASSERT3U(zio->io_size, ==, BP_GET_PSIZE(bp));
+
+	/*
+	 * The dump device does not support gang blocks so allocation on
+	 * behalf of the dump device (i.e. ZIO_FLAG_NODATA) must avoid
+	 * the "fast" gang feature.
+	 */
+	flags |= (zio->io_flags & ZIO_FLAG_NODATA) ? METASLAB_GANG_AVOID : 0;
+	flags |= (zio->io_flags & ZIO_FLAG_GANG_CHILD) ?
+	    METASLAB_GANG_CHILD : 0;
+	flags |= (zio->io_flags & ZIO_FLAG_FASTWRITE) ? METASLAB_FASTWRITE : 0;
+	error = metaslab_alloc(spa, mc, zio->io_size, bp,
+	    zio->io_prop.zp_copies, zio->io_txg, NULL, flags);
+
+	if (error) {
+		spa_dbgmsg(spa, "%s: metaslab allocation failure: zio %p, "
+		    "size %llu, error %d", spa_name(spa), zio, zio->io_size,
+		    error);
+		if (error == ENOSPC && zio->io_size > SPA_MINBLOCKSIZE)
+			return (zio_write_gang_block(zio));
+		zio->io_error = error;
+	}
+
+	return (ZIO_PIPELINE_CONTINUE);
+}
+
+static int
+zio_dva_free(zio_t *zio)
+{
+	metaslab_free(zio->io_spa, zio->io_bp, zio->io_txg, B_FALSE);
+
+	return (ZIO_PIPELINE_CONTINUE);
+}
+
+static int
+zio_dva_claim(zio_t *zio)
+{
+	int error;
+
+	error = metaslab_claim(zio->io_spa, zio->io_bp, zio->io_txg);
+	if (error)
+		zio->io_error = error;
+
+	return (ZIO_PIPELINE_CONTINUE);
+}
+
+/*
+ * Undo an allocation.  This is used by zio_done() when an I/O fails
+ * and we want to give back the block we just allocated.
+ * This handles both normal blocks and gang blocks.
+ */
+static void
+zio_dva_unallocate(zio_t *zio, zio_gang_node_t *gn, blkptr_t *bp)
+{
+	int g;
+
+	ASSERT(bp->blk_birth == zio->io_txg || BP_IS_HOLE(bp));
+	ASSERT(zio->io_bp_override == NULL);
+
+	if (!BP_IS_HOLE(bp))
+		metaslab_free(zio->io_spa, bp, bp->blk_birth, B_TRUE);
+
+	if (gn != NULL) {
+		for (g = 0; g < SPA_GBH_NBLKPTRS; g++) {
+			zio_dva_unallocate(zio, gn->gn_child[g],
+			    &gn->gn_gbh->zg_blkptr[g]);
+		}
+	}
+}
+
+/*
+ * Try to allocate an intent log block.  Return 0 on success, errno on failure.
+ */
+int
+zio_alloc_zil(spa_t *spa, uint64_t txg, blkptr_t *new_bp, uint64_t size,
+    boolean_t use_slog)
+{
+	int error = 1;
+
+	ASSERT(txg > spa_syncing_txg(spa));
+
+	/*
+	 * ZIL blocks are always contiguous (i.e. not gang blocks) so we
+	 * set the METASLAB_GANG_AVOID flag so that they don't "fast gang"
+	 * when allocating them.
+	 */
+	if (use_slog) {
+		error = metaslab_alloc(spa, spa_log_class(spa), size,
+		    new_bp, 1, txg, NULL,
+		    METASLAB_FASTWRITE | METASLAB_GANG_AVOID);
+	}
+
+	if (error) {
+		error = metaslab_alloc(spa, spa_normal_class(spa), size,
+		    new_bp, 1, txg, NULL,
+		    METASLAB_FASTWRITE);
+	}
+
+	if (error == 0) {
+		BP_SET_LSIZE(new_bp, size);
+		BP_SET_PSIZE(new_bp, size);
+		BP_SET_COMPRESS(new_bp, ZIO_COMPRESS_OFF);
+		BP_SET_CHECKSUM(new_bp,
+		    spa_version(spa) >= SPA_VERSION_SLIM_ZIL
+		    ? ZIO_CHECKSUM_ZILOG2 : ZIO_CHECKSUM_ZILOG);
+		BP_SET_TYPE(new_bp, DMU_OT_INTENT_LOG);
+		BP_SET_LEVEL(new_bp, 0);
+		BP_SET_DEDUP(new_bp, 0);
+		BP_SET_BYTEORDER(new_bp, ZFS_HOST_BYTEORDER);
+	}
+
+	return (error);
+}
+
+/*
+ * Free an intent log block.
+ */
+void
+zio_free_zil(spa_t *spa, uint64_t txg, blkptr_t *bp)
+{
+	ASSERT(BP_GET_TYPE(bp) == DMU_OT_INTENT_LOG);
+	ASSERT(!BP_IS_GANG(bp));
+
+	zio_free(spa, txg, bp);
+}
+
+/*
+ * ==========================================================================
+ * Read and write to physical devices
+ * ==========================================================================
+ */
+
+
+/*
+ * Issue an I/O to the underlying vdev. Typically the issue pipeline
+ * stops after this stage and will resume upon I/O completion.
+ * However, there are instances where the vdev layer may need to
+ * continue the pipeline when an I/O was not issued. Since the I/O
+ * that was sent to the vdev layer might be different than the one
+ * currently active in the pipeline (see vdev_queue_io()), we explicitly
+ * force the underlying vdev layers to call either zio_execute() or
+ * zio_interrupt() to ensure that the pipeline continues with the correct I/O.
+ */
+static int
+zio_vdev_io_start(zio_t *zio)
+{
+	vdev_t *vd = zio->io_vd;
+	uint64_t align;
+	spa_t *spa = zio->io_spa;
+
+	ASSERT(zio->io_error == 0);
+	ASSERT(zio->io_child_error[ZIO_CHILD_VDEV] == 0);
+
+	if (vd == NULL) {
+		if (!(zio->io_flags & ZIO_FLAG_CONFIG_WRITER))
+			spa_config_enter(spa, SCL_ZIO, zio, RW_READER);
+
+		/*
+		 * The mirror_ops handle multiple DVAs in a single BP.
+		 */
+		vdev_mirror_ops.vdev_op_io_start(zio);
+		return (ZIO_PIPELINE_STOP);
+	}
+
+	/*
+	 * We keep track of time-sensitive I/Os so that the scan thread
+	 * can quickly react to certain workloads.  In particular, we care
+	 * about non-scrubbing, top-level reads and writes with the following
+	 * characteristics:
+	 *	- synchronous writes of user data to non-slog devices
+	 *	- any reads of user data
+	 * When these conditions are met, adjust the timestamp of spa_last_io
+	 * which allows the scan thread to adjust its workload accordingly.
+	 */
+	if (!(zio->io_flags & ZIO_FLAG_SCAN_THREAD) && zio->io_bp != NULL &&
+	    vd == vd->vdev_top && !vd->vdev_islog &&
+	    zio->io_bookmark.zb_objset != DMU_META_OBJSET &&
+	    zio->io_txg != spa_syncing_txg(spa)) {
+		uint64_t old = spa->spa_last_io;
+		uint64_t new = ddi_get_lbolt64();
+		if (old != new)
+			(void) atomic_cas_64(&spa->spa_last_io, old, new);
+	}
+
+	align = 1ULL << vd->vdev_top->vdev_ashift;
+
+	if (!(zio->io_flags & ZIO_FLAG_PHYSICAL) &&
+	    P2PHASE(zio->io_size, align) != 0) {
+		/* Transform logical writes to be a full physical block size. */
+		uint64_t asize = P2ROUNDUP(zio->io_size, align);
+		char *abuf = zio_buf_alloc(asize);
+		ASSERT(vd == vd->vdev_top);
+		if (zio->io_type == ZIO_TYPE_WRITE) {
+			bcopy(zio->io_data, abuf, zio->io_size);
+			bzero(abuf + zio->io_size, asize - zio->io_size);
+		}
+		zio_push_transform(zio, abuf, asize, asize, zio_subblock);
+	}
+
+	/*
+	 * If this is not a physical io, make sure that it is properly aligned
+	 * before proceeding.
+	 */
+	if (!(zio->io_flags & ZIO_FLAG_PHYSICAL)) {
+		ASSERT0(P2PHASE(zio->io_offset, align));
+		ASSERT0(P2PHASE(zio->io_size, align));
+	} else {
+		/*
+		 * For physical writes, we allow 512b aligned writes and assume
+		 * the device will perform a read-modify-write as necessary.
+		 */
+		ASSERT0(P2PHASE(zio->io_offset, SPA_MINBLOCKSIZE));
+		ASSERT0(P2PHASE(zio->io_size, SPA_MINBLOCKSIZE));
+	}
+
+	VERIFY(zio->io_type != ZIO_TYPE_WRITE || spa_writeable(spa));
+
+	/*
+	 * If this is a repair I/O, and there's no self-healing involved --
+	 * that is, we're just resilvering what we expect to resilver --
+	 * then don't do the I/O unless zio's txg is actually in vd's DTL.
+	 * This prevents spurious resilvering with nested replication.
+	 * For example, given a mirror of mirrors, (A+B)+(C+D), if only
+	 * A is out of date, we'll read from C+D, then use the data to
+	 * resilver A+B -- but we don't actually want to resilver B, just A.
+	 * The top-level mirror has no way to know this, so instead we just
+	 * discard unnecessary repairs as we work our way down the vdev tree.
+	 * The same logic applies to any form of nested replication:
+	 * ditto + mirror, RAID-Z + replacing, etc.  This covers them all.
+	 */
+	if ((zio->io_flags & ZIO_FLAG_IO_REPAIR) &&
+	    !(zio->io_flags & ZIO_FLAG_SELF_HEAL) &&
+	    zio->io_txg != 0 &&	/* not a delegated i/o */
+	    !vdev_dtl_contains(vd, DTL_PARTIAL, zio->io_txg, 1)) {
+		ASSERT(zio->io_type == ZIO_TYPE_WRITE);
+		zio_vdev_io_bypass(zio);
+		return (ZIO_PIPELINE_CONTINUE);
+	}
+
+	if (vd->vdev_ops->vdev_op_leaf &&
+	    (zio->io_type == ZIO_TYPE_READ || zio->io_type == ZIO_TYPE_WRITE)) {
+
+		if (zio->io_type == ZIO_TYPE_READ && vdev_cache_read(zio))
+			return (ZIO_PIPELINE_CONTINUE);
+
+		if ((zio = vdev_queue_io(zio)) == NULL)
+			return (ZIO_PIPELINE_STOP);
+
+		if (!vdev_accessible(vd, zio)) {
+			zio->io_error = SET_ERROR(ENXIO);
+			zio_interrupt(zio);
+			return (ZIO_PIPELINE_STOP);
+		}
+	}
+
+	vd->vdev_ops->vdev_op_io_start(zio);
+	return (ZIO_PIPELINE_STOP);
+}
+
+static int
+zio_vdev_io_done(zio_t *zio)
+{
+	vdev_t *vd = zio->io_vd;
+	vdev_ops_t *ops = vd ? vd->vdev_ops : &vdev_mirror_ops;
+	boolean_t unexpected_error = B_FALSE;
+
+	if (zio_wait_for_children(zio, ZIO_CHILD_VDEV, ZIO_WAIT_DONE))
+		return (ZIO_PIPELINE_STOP);
+
+	ASSERT(zio->io_type == ZIO_TYPE_READ || zio->io_type == ZIO_TYPE_WRITE);
+
+	if (vd != NULL && vd->vdev_ops->vdev_op_leaf) {
+
+		vdev_queue_io_done(zio);
+
+		if (zio->io_type == ZIO_TYPE_WRITE)
+			vdev_cache_write(zio);
+
+		if (zio_injection_enabled && zio->io_error == 0)
+			zio->io_error = zio_handle_device_injection(vd,
+			    zio, EIO);
+
+		if (zio_injection_enabled && zio->io_error == 0)
+			zio->io_error = zio_handle_label_injection(zio, EIO);
+
+		if (zio->io_error) {
+			if (!vdev_accessible(vd, zio)) {
+				zio->io_error = SET_ERROR(ENXIO);
+			} else {
+				unexpected_error = B_TRUE;
+			}
+		}
+	}
+
+	ops->vdev_op_io_done(zio);
+
+	if (unexpected_error)
+		VERIFY(vdev_probe(vd, zio) == NULL);
+
+	return (ZIO_PIPELINE_CONTINUE);
+}
+
+/*
+ * For non-raidz ZIOs, we can just copy aside the bad data read from the
+ * disk, and use that to finish the checksum ereport later.
+ */
+static void
+zio_vsd_default_cksum_finish(zio_cksum_report_t *zcr,
+    const void *good_buf)
+{
+	/* no processing needed */
+	zfs_ereport_finish_checksum(zcr, good_buf, zcr->zcr_cbdata, B_FALSE);
+}
+
+/*ARGSUSED*/
+void
+zio_vsd_default_cksum_report(zio_t *zio, zio_cksum_report_t *zcr, void *ignored)
+{
+	void *buf = zio_buf_alloc(zio->io_size);
+
+	bcopy(zio->io_data, buf, zio->io_size);
+
+	zcr->zcr_cbinfo = zio->io_size;
+	zcr->zcr_cbdata = buf;
+	zcr->zcr_finish = zio_vsd_default_cksum_finish;
+	zcr->zcr_free = zio_buf_free;
+}
+
+static int
+zio_vdev_io_assess(zio_t *zio)
+{
+	vdev_t *vd = zio->io_vd;
+
+	if (zio_wait_for_children(zio, ZIO_CHILD_VDEV, ZIO_WAIT_DONE))
+		return (ZIO_PIPELINE_STOP);
+
+	if (vd == NULL && !(zio->io_flags & ZIO_FLAG_CONFIG_WRITER))
+		spa_config_exit(zio->io_spa, SCL_ZIO, zio);
+
+	if (zio->io_vsd != NULL) {
+		zio->io_vsd_ops->vsd_free(zio);
+		zio->io_vsd = NULL;
+	}
+
+	if (zio_injection_enabled && zio->io_error == 0)
+		zio->io_error = zio_handle_fault_injection(zio, EIO);
+
+	/*
+	 * If the I/O failed, determine whether we should attempt to retry it.
+	 *
+	 * On retry, we cut in line in the issue queue, since we don't want
+	 * compression/checksumming/etc. work to prevent our (cheap) IO reissue.
+	 */
+	if (zio->io_error && vd == NULL &&
+	    !(zio->io_flags & (ZIO_FLAG_DONT_RETRY | ZIO_FLAG_IO_RETRY))) {
+		ASSERT(!(zio->io_flags & ZIO_FLAG_DONT_QUEUE));	/* not a leaf */
+		ASSERT(!(zio->io_flags & ZIO_FLAG_IO_BYPASS));	/* not a leaf */
+		zio->io_error = 0;
+		zio->io_flags |= ZIO_FLAG_IO_RETRY |
+		    ZIO_FLAG_DONT_CACHE | ZIO_FLAG_DONT_AGGREGATE;
+		zio->io_stage = ZIO_STAGE_VDEV_IO_START >> 1;
+		zio_taskq_dispatch(zio, ZIO_TASKQ_ISSUE,
+		    zio_requeue_io_start_cut_in_line);
+		return (ZIO_PIPELINE_STOP);
+	}
+
+	/*
+	 * If we got an error on a leaf device, convert it to ENXIO
+	 * if the device is not accessible at all.
+	 */
+	if (zio->io_error && vd != NULL && vd->vdev_ops->vdev_op_leaf &&
+	    !vdev_accessible(vd, zio))
+		zio->io_error = SET_ERROR(ENXIO);
+
+	/*
+	 * If we can't write to an interior vdev (mirror or RAID-Z),
+	 * set vdev_cant_write so that we stop trying to allocate from it.
+	 */
+	if (zio->io_error == ENXIO && zio->io_type == ZIO_TYPE_WRITE &&
+	    vd != NULL && !vd->vdev_ops->vdev_op_leaf) {
+		vd->vdev_cant_write = B_TRUE;
+	}
+
+	if (zio->io_error)
+		zio->io_pipeline = ZIO_INTERLOCK_PIPELINE;
+
+	if (vd != NULL && vd->vdev_ops->vdev_op_leaf &&
+	    zio->io_physdone != NULL) {
+		ASSERT(!(zio->io_flags & ZIO_FLAG_DELEGATED));
+		ASSERT(zio->io_child_type == ZIO_CHILD_VDEV);
+		zio->io_physdone(zio->io_logical);
+	}
+
+	return (ZIO_PIPELINE_CONTINUE);
+}
+
+void
+zio_vdev_io_reissue(zio_t *zio)
+{
+	ASSERT(zio->io_stage == ZIO_STAGE_VDEV_IO_START);
+	ASSERT(zio->io_error == 0);
+
+	zio->io_stage >>= 1;
+}
+
+void
+zio_vdev_io_redone(zio_t *zio)
+{
+	ASSERT(zio->io_stage == ZIO_STAGE_VDEV_IO_DONE);
+
+	zio->io_stage >>= 1;
+}
+
+void
+zio_vdev_io_bypass(zio_t *zio)
+{
+	ASSERT(zio->io_stage == ZIO_STAGE_VDEV_IO_START);
+	ASSERT(zio->io_error == 0);
+
+	zio->io_flags |= ZIO_FLAG_IO_BYPASS;
+	zio->io_stage = ZIO_STAGE_VDEV_IO_ASSESS >> 1;
+}
+
+/*
+ * ==========================================================================
+ * Generate and verify checksums
+ * ==========================================================================
+ */
+static int
+zio_checksum_generate(zio_t *zio)
+{
+	blkptr_t *bp = zio->io_bp;
+	enum zio_checksum checksum;
+
+	if (bp == NULL) {
+		/*
+		 * This is zio_write_phys().
+		 * We're either generating a label checksum, or none at all.
+		 */
+		checksum = zio->io_prop.zp_checksum;
+
+		if (checksum == ZIO_CHECKSUM_OFF)
+			return (ZIO_PIPELINE_CONTINUE);
+
+		ASSERT(checksum == ZIO_CHECKSUM_LABEL);
+	} else {
+		if (BP_IS_GANG(bp) && zio->io_child_type == ZIO_CHILD_GANG) {
+			ASSERT(!IO_IS_ALLOCATING(zio));
+			checksum = ZIO_CHECKSUM_GANG_HEADER;
+		} else {
+			checksum = BP_GET_CHECKSUM(bp);
+		}
+	}
+
+	zio_checksum_compute(zio, checksum, zio->io_data, zio->io_size);
+
+	return (ZIO_PIPELINE_CONTINUE);
+}
+
+static int
+zio_checksum_verify(zio_t *zio)
+{
+	zio_bad_cksum_t info;
+	blkptr_t *bp = zio->io_bp;
+	int error;
+
+	ASSERT(zio->io_vd != NULL);
+
+	if (bp == NULL) {
+		/*
+		 * This is zio_read_phys().
+		 * We're either verifying a label checksum, or nothing at all.
+		 */
+		if (zio->io_prop.zp_checksum == ZIO_CHECKSUM_OFF)
+			return (ZIO_PIPELINE_CONTINUE);
+
+		ASSERT(zio->io_prop.zp_checksum == ZIO_CHECKSUM_LABEL);
+	}
+
+	if ((error = zio_checksum_error(zio, &info)) != 0) {
+		zio->io_error = error;
+		if (error == ECKSUM &&
+		    !(zio->io_flags & ZIO_FLAG_SPECULATIVE)) {
+			zfs_ereport_start_checksum(zio->io_spa,
+			    zio->io_vd, zio, zio->io_offset,
+			    zio->io_size, NULL, &info);
+		}
+	}
+
+	return (ZIO_PIPELINE_CONTINUE);
+}
+
+/*
+ * Called by RAID-Z to ensure we don't compute the checksum twice.
+ */
+void
+zio_checksum_verified(zio_t *zio)
+{
+	zio->io_pipeline &= ~ZIO_STAGE_CHECKSUM_VERIFY;
+}
+
+/*
+ * ==========================================================================
+ * Error rank.  Error are ranked in the order 0, ENXIO, ECKSUM, EIO, other.
+ * An error of 0 indicates success.  ENXIO indicates whole-device failure,
+ * which may be transient (e.g. unplugged) or permament.  ECKSUM and EIO
+ * indicate errors that are specific to one I/O, and most likely permanent.
+ * Any other error is presumed to be worse because we weren't expecting it.
+ * ==========================================================================
+ */
+int
+zio_worst_error(int e1, int e2)
+{
+	static int zio_error_rank[] = { 0, ENXIO, ECKSUM, EIO };
+	int r1, r2;
+
+	for (r1 = 0; r1 < sizeof (zio_error_rank) / sizeof (int); r1++)
+		if (e1 == zio_error_rank[r1])
+			break;
+
+	for (r2 = 0; r2 < sizeof (zio_error_rank) / sizeof (int); r2++)
+		if (e2 == zio_error_rank[r2])
+			break;
+
+	return (r1 > r2 ? e1 : e2);
+}
+
+/*
+ * ==========================================================================
+ * I/O completion
+ * ==========================================================================
+ */
+static int
+zio_ready(zio_t *zio)
+{
+	blkptr_t *bp = zio->io_bp;
+	zio_t *pio, *pio_next;
+
+	if (zio_wait_for_children(zio, ZIO_CHILD_GANG, ZIO_WAIT_READY) ||
+	    zio_wait_for_children(zio, ZIO_CHILD_DDT, ZIO_WAIT_READY))
+		return (ZIO_PIPELINE_STOP);
+
+	if (zio->io_ready) {
+		ASSERT(IO_IS_ALLOCATING(zio));
+		ASSERT(bp->blk_birth == zio->io_txg || BP_IS_HOLE(bp) ||
+		    (zio->io_flags & ZIO_FLAG_NOPWRITE));
+		ASSERT(zio->io_children[ZIO_CHILD_GANG][ZIO_WAIT_READY] == 0);
+
+		zio->io_ready(zio);
+	}
+
+	if (bp != NULL && bp != &zio->io_bp_copy)
+		zio->io_bp_copy = *bp;
+
+	if (zio->io_error)
+		zio->io_pipeline = ZIO_INTERLOCK_PIPELINE;
+
+	mutex_enter(&zio->io_lock);
+	zio->io_state[ZIO_WAIT_READY] = 1;
+	pio = zio_walk_parents(zio);
+	mutex_exit(&zio->io_lock);
+
+	/*
+	 * As we notify zio's parents, new parents could be added.
+	 * New parents go to the head of zio's io_parent_list, however,
+	 * so we will (correctly) not notify them.  The remainder of zio's
+	 * io_parent_list, from 'pio_next' onward, cannot change because
+	 * all parents must wait for us to be done before they can be done.
+	 */
+	for (; pio != NULL; pio = pio_next) {
+		pio_next = zio_walk_parents(zio);
+		zio_notify_parent(pio, zio, ZIO_WAIT_READY);
+	}
+
+	if (zio->io_flags & ZIO_FLAG_NODATA) {
+		if (BP_IS_GANG(bp)) {
+			zio->io_flags &= ~ZIO_FLAG_NODATA;
+		} else {
+			ASSERT((uintptr_t)zio->io_data < SPA_MAXBLOCKSIZE);
+			zio->io_pipeline &= ~ZIO_VDEV_IO_STAGES;
+		}
+	}
+
+	if (zio_injection_enabled &&
+	    zio->io_spa->spa_syncing_txg == zio->io_txg)
+		zio_handle_ignored_writes(zio);
+
+	return (ZIO_PIPELINE_CONTINUE);
+}
+
+static int
+zio_done(zio_t *zio)
+{
+	zio_t *pio, *pio_next;
+	int c, w;
+
+	/*
+	 * If our children haven't all completed,
+	 * wait for them and then repeat this pipeline stage.
+	 */
+	if (zio_wait_for_children(zio, ZIO_CHILD_VDEV, ZIO_WAIT_DONE) ||
+	    zio_wait_for_children(zio, ZIO_CHILD_GANG, ZIO_WAIT_DONE) ||
+	    zio_wait_for_children(zio, ZIO_CHILD_DDT, ZIO_WAIT_DONE) ||
+	    zio_wait_for_children(zio, ZIO_CHILD_LOGICAL, ZIO_WAIT_DONE))
+		return (ZIO_PIPELINE_STOP);
+
+	for (c = 0; c < ZIO_CHILD_TYPES; c++)
+		for (w = 0; w < ZIO_WAIT_TYPES; w++)
+			ASSERT(zio->io_children[c][w] == 0);
+
+	if (zio->io_bp != NULL && !BP_IS_EMBEDDED(zio->io_bp)) {
+		ASSERT(zio->io_bp->blk_pad[0] == 0);
+		ASSERT(zio->io_bp->blk_pad[1] == 0);
+		ASSERT(bcmp(zio->io_bp, &zio->io_bp_copy,
+		    sizeof (blkptr_t)) == 0 ||
+		    (zio->io_bp == zio_unique_parent(zio)->io_bp));
+		if (zio->io_type == ZIO_TYPE_WRITE && !BP_IS_HOLE(zio->io_bp) &&
+		    zio->io_bp_override == NULL &&
+		    !(zio->io_flags & ZIO_FLAG_IO_REPAIR)) {
+			ASSERT(!BP_SHOULD_BYTESWAP(zio->io_bp));
+			ASSERT3U(zio->io_prop.zp_copies, <=,
+			    BP_GET_NDVAS(zio->io_bp));
+			ASSERT(BP_COUNT_GANG(zio->io_bp) == 0 ||
+			    (BP_COUNT_GANG(zio->io_bp) ==
+			    BP_GET_NDVAS(zio->io_bp)));
+		}
+		if (zio->io_flags & ZIO_FLAG_NOPWRITE)
+			VERIFY(BP_EQUAL(zio->io_bp, &zio->io_bp_orig));
+	}
+
+	/*
+	 * If there were child vdev/gang/ddt errors, they apply to us now.
+	 */
+	zio_inherit_child_errors(zio, ZIO_CHILD_VDEV);
+	zio_inherit_child_errors(zio, ZIO_CHILD_GANG);
+	zio_inherit_child_errors(zio, ZIO_CHILD_DDT);
+
+	/*
+	 * If the I/O on the transformed data was successful, generate any
+	 * checksum reports now while we still have the transformed data.
+	 */
+	if (zio->io_error == 0) {
+		while (zio->io_cksum_report != NULL) {
+			zio_cksum_report_t *zcr = zio->io_cksum_report;
+			uint64_t align = zcr->zcr_align;
+			uint64_t asize = P2ROUNDUP(zio->io_size, align);
+			char *abuf = zio->io_data;
+
+			if (asize != zio->io_size) {
+				abuf = zio_buf_alloc(asize);
+				bcopy(zio->io_data, abuf, zio->io_size);
+				bzero(abuf+zio->io_size, asize-zio->io_size);
+			}
+
+			zio->io_cksum_report = zcr->zcr_next;
+			zcr->zcr_next = NULL;
+			zcr->zcr_finish(zcr, abuf);
+			zfs_ereport_free_checksum(zcr);
+
+			if (asize != zio->io_size)
+				zio_buf_free(abuf, asize);
+		}
+	}
+
+	zio_pop_transforms(zio);	/* note: may set zio->io_error */
+
+	vdev_stat_update(zio, zio->io_size);
+
+	/*
+	 * If this I/O is attached to a particular vdev is slow, exceeding
+	 * 30 seconds to complete, post an error described the I/O delay.
+	 * We ignore these errors if the device is currently unavailable.
+	 */
+	if (zio->io_delay >= MSEC_TO_TICK(zio_delay_max)) {
+		if (zio->io_vd != NULL && !vdev_is_dead(zio->io_vd))
+			zfs_ereport_post(FM_EREPORT_ZFS_DELAY, zio->io_spa,
+			    zio->io_vd, zio, 0, 0);
+	}
+
+	if (zio->io_error) {
+		/*
+		 * If this I/O is attached to a particular vdev,
+		 * generate an error message describing the I/O failure
+		 * at the block level.  We ignore these errors if the
+		 * device is currently unavailable.
+		 */
+		if (zio->io_error != ECKSUM && zio->io_vd != NULL &&
+			!vdev_is_dead(zio->io_vd))
+			zfs_ereport_post(FM_EREPORT_ZFS_IO, zio->io_spa,
+						zio->io_vd, zio, 0, 0);
+
+		if ((zio->io_error == EIO || !(zio->io_flags &
+		    (ZIO_FLAG_SPECULATIVE | ZIO_FLAG_DONT_PROPAGATE))) &&
+		    zio == zio->io_logical) {
+			/*
+			 * For logical I/O requests, tell the SPA to log the
+			 * error and generate a logical data ereport.
+			 */
+			spa_log_error(zio->io_spa, zio);
+			zfs_ereport_post(FM_EREPORT_ZFS_DATA, zio->io_spa,
+			    NULL, zio, 0, 0);
+		}
+	}
+
+	if (zio->io_error && zio == zio->io_logical) {
+		/*
+		 * Determine whether zio should be reexecuted.  This will
+		 * propagate all the way to the root via zio_notify_parent().
+		 */
+		ASSERT(zio->io_vd == NULL && zio->io_bp != NULL);
+		ASSERT(zio->io_child_type == ZIO_CHILD_LOGICAL);
+
+		if (IO_IS_ALLOCATING(zio) &&
+		    !(zio->io_flags & ZIO_FLAG_CANFAIL)) {
+			if (zio->io_error != ENOSPC)
+				zio->io_reexecute |= ZIO_REEXECUTE_NOW;
+			else
+				zio->io_reexecute |= ZIO_REEXECUTE_SUSPEND;
+		}
+
+		if ((zio->io_type == ZIO_TYPE_READ ||
+		    zio->io_type == ZIO_TYPE_FREE) &&
+		    !(zio->io_flags & ZIO_FLAG_SCAN_THREAD) &&
+		    zio->io_error == ENXIO &&
+		    spa_load_state(zio->io_spa) == SPA_LOAD_NONE &&
+		    spa_get_failmode(zio->io_spa) != ZIO_FAILURE_MODE_CONTINUE)
+			zio->io_reexecute |= ZIO_REEXECUTE_SUSPEND;
+
+		if (!(zio->io_flags & ZIO_FLAG_CANFAIL) && !zio->io_reexecute)
+			zio->io_reexecute |= ZIO_REEXECUTE_SUSPEND;
+
+		/*
+		 * Here is a possibly good place to attempt to do
+		 * either combinatorial reconstruction or error correction
+		 * based on checksums.  It also might be a good place
+		 * to send out preliminary ereports before we suspend
+		 * processing.
+		 */
+	}
+
+	/*
+	 * If there were logical child errors, they apply to us now.
+	 * We defer this until now to avoid conflating logical child
+	 * errors with errors that happened to the zio itself when
+	 * updating vdev stats and reporting FMA events above.
+	 */
+	zio_inherit_child_errors(zio, ZIO_CHILD_LOGICAL);
+
+	if ((zio->io_error || zio->io_reexecute) &&
+	    IO_IS_ALLOCATING(zio) && zio->io_gang_leader == zio &&
+	    !(zio->io_flags & (ZIO_FLAG_IO_REWRITE | ZIO_FLAG_NOPWRITE)))
+		zio_dva_unallocate(zio, zio->io_gang_tree, zio->io_bp);
+
+	zio_gang_tree_free(&zio->io_gang_tree);
+
+	/*
+	 * Godfather I/Os should never suspend.
+	 */
+	if ((zio->io_flags & ZIO_FLAG_GODFATHER) &&
+	    (zio->io_reexecute & ZIO_REEXECUTE_SUSPEND))
+		zio->io_reexecute = 0;
+
+	if (zio->io_reexecute) {
+		/*
+		 * This is a logical I/O that wants to reexecute.
+		 *
+		 * Reexecute is top-down.  When an i/o fails, if it's not
+		 * the root, it simply notifies its parent and sticks around.
+		 * The parent, seeing that it still has children in zio_done(),
+		 * does the same.  This percolates all the way up to the root.
+		 * The root i/o will reexecute or suspend the entire tree.
+		 *
+		 * This approach ensures that zio_reexecute() honors
+		 * all the original i/o dependency relationships, e.g.
+		 * parents not executing until children are ready.
+		 */
+		ASSERT(zio->io_child_type == ZIO_CHILD_LOGICAL);
+
+		zio->io_gang_leader = NULL;
+
+		mutex_enter(&zio->io_lock);
+		zio->io_state[ZIO_WAIT_DONE] = 1;
+		mutex_exit(&zio->io_lock);
+
+		/*
+		 * "The Godfather" I/O monitors its children but is
+		 * not a true parent to them. It will track them through
+		 * the pipeline but severs its ties whenever they get into
+		 * trouble (e.g. suspended). This allows "The Godfather"
+		 * I/O to return status without blocking.
+		 */
+		for (pio = zio_walk_parents(zio); pio != NULL; pio = pio_next) {
+			zio_link_t *zl = zio->io_walk_link;
+			pio_next = zio_walk_parents(zio);
+
+			if ((pio->io_flags & ZIO_FLAG_GODFATHER) &&
+			    (zio->io_reexecute & ZIO_REEXECUTE_SUSPEND)) {
+				zio_remove_child(pio, zio, zl);
+				zio_notify_parent(pio, zio, ZIO_WAIT_DONE);
+			}
+		}
+
+		if ((pio = zio_unique_parent(zio)) != NULL) {
+			/*
+			 * We're not a root i/o, so there's nothing to do
+			 * but notify our parent.  Don't propagate errors
+			 * upward since we haven't permanently failed yet.
+			 */
+			ASSERT(!(zio->io_flags & ZIO_FLAG_GODFATHER));
+			zio->io_flags |= ZIO_FLAG_DONT_PROPAGATE;
+			zio_notify_parent(pio, zio, ZIO_WAIT_DONE);
+		} else if (zio->io_reexecute & ZIO_REEXECUTE_SUSPEND) {
+			/*
+			 * We'd fail again if we reexecuted now, so suspend
+			 * until conditions improve (e.g. device comes online).
+			 */
+			zio_suspend(zio->io_spa, zio);
+		} else {
+			/*
+			 * Reexecution is potentially a huge amount of work.
+			 * Hand it off to the otherwise-unused claim taskq.
+			 */
+			ASSERT(taskq_empty_ent(&zio->io_tqent));
+			spa_taskq_dispatch_ent(zio->io_spa,
+			    ZIO_TYPE_CLAIM, ZIO_TASKQ_ISSUE,
+			    (task_func_t *)zio_reexecute, zio, 0,
+			    &zio->io_tqent);
+		}
+		return (ZIO_PIPELINE_STOP);
+	}
+
+	ASSERT(zio->io_child_count == 0);
+	ASSERT(zio->io_reexecute == 0);
+	ASSERT(zio->io_error == 0 || (zio->io_flags & ZIO_FLAG_CANFAIL));
+
+	/*
+	 * Report any checksum errors, since the I/O is complete.
+	 */
+	while (zio->io_cksum_report != NULL) {
+		zio_cksum_report_t *zcr = zio->io_cksum_report;
+		zio->io_cksum_report = zcr->zcr_next;
+		zcr->zcr_next = NULL;
+		zcr->zcr_finish(zcr, NULL);
+		zfs_ereport_free_checksum(zcr);
+	}
+
+	if (zio->io_flags & ZIO_FLAG_FASTWRITE && zio->io_bp &&
+	    !BP_IS_HOLE(zio->io_bp) && !BP_IS_EMBEDDED(zio->io_bp) &&
+	    !(zio->io_flags & ZIO_FLAG_NOPWRITE)) {
+		metaslab_fastwrite_unmark(zio->io_spa, zio->io_bp);
+	}
+
+	/*
+	 * It is the responsibility of the done callback to ensure that this
+	 * particular zio is no longer discoverable for adoption, and as
+	 * such, cannot acquire any new parents.
+	 */
+	if (zio->io_done)
+		zio->io_done(zio);
+
+	mutex_enter(&zio->io_lock);
+	zio->io_state[ZIO_WAIT_DONE] = 1;
+	mutex_exit(&zio->io_lock);
+
+	for (pio = zio_walk_parents(zio); pio != NULL; pio = pio_next) {
+		zio_link_t *zl = zio->io_walk_link;
+		pio_next = zio_walk_parents(zio);
+		zio_remove_child(pio, zio, zl);
+		zio_notify_parent(pio, zio, ZIO_WAIT_DONE);
+	}
+
+	if (zio->io_waiter != NULL) {
+		mutex_enter(&zio->io_lock);
+		zio->io_executor = NULL;
+		cv_broadcast(&zio->io_cv);
+		mutex_exit(&zio->io_lock);
+	} else {
+		zio_destroy(zio);
+	}
+
+	return (ZIO_PIPELINE_STOP);
+}
+
+/*
+ * ==========================================================================
+ * I/O pipeline definition
+ * ==========================================================================
+ */
+static zio_pipe_stage_t *zio_pipeline[] = {
+	NULL,
+	zio_read_bp_init,
+	zio_free_bp_init,
+	zio_issue_async,
+	zio_write_bp_init,
+	zio_checksum_generate,
+	zio_nop_write,
+	zio_ddt_read_start,
+	zio_ddt_read_done,
+	zio_ddt_write,
+	zio_ddt_free,
+	zio_gang_assemble,
+	zio_gang_issue,
+	zio_dva_allocate,
+	zio_dva_free,
+	zio_dva_claim,
+	zio_ready,
+	zio_vdev_io_start,
+	zio_vdev_io_done,
+	zio_vdev_io_assess,
+	zio_checksum_verify,
+	zio_done
+};
+
+/* dnp is the dnode for zb1->zb_object */
+boolean_t
+zbookmark_is_before(const dnode_phys_t *dnp, const zbookmark_phys_t *zb1,
+    const zbookmark_phys_t *zb2)
+{
+	uint64_t zb1nextL0, zb2thisobj;
+
+	ASSERT(zb1->zb_objset == zb2->zb_objset);
+	ASSERT(zb2->zb_level == 0);
+
+	/* The objset_phys_t isn't before anything. */
+	if (dnp == NULL)
+		return (B_FALSE);
+
+	zb1nextL0 = (zb1->zb_blkid + 1) <<
+	    ((zb1->zb_level) * (dnp->dn_indblkshift - SPA_BLKPTRSHIFT));
+
+	zb2thisobj = zb2->zb_object ? zb2->zb_object :
+	    zb2->zb_blkid << (DNODE_BLOCK_SHIFT - DNODE_SHIFT);
+
+	if (zb1->zb_object == DMU_META_DNODE_OBJECT) {
+		uint64_t nextobj = zb1nextL0 *
+		    (dnp->dn_datablkszsec << SPA_MINBLOCKSHIFT) >> DNODE_SHIFT;
+		return (nextobj <= zb2thisobj);
+	}
+
+	if (zb1->zb_object < zb2thisobj)
+		return (B_TRUE);
+	if (zb1->zb_object > zb2thisobj)
+		return (B_FALSE);
+	if (zb2->zb_object == DMU_META_DNODE_OBJECT)
+		return (B_FALSE);
+	return (zb1nextL0 <= zb2->zb_blkid);
+}
+
+#if defined(_KERNEL) && defined(HAVE_SPL)
+EXPORT_SYMBOL(zio_type_name);
+EXPORT_SYMBOL(zio_buf_alloc);
+EXPORT_SYMBOL(zio_data_buf_alloc);
+EXPORT_SYMBOL(zio_buf_alloc_flags);
+EXPORT_SYMBOL(zio_buf_free);
+EXPORT_SYMBOL(zio_data_buf_free);
+
+module_param(zio_delay_max, int, 0644);
+MODULE_PARM_DESC(zio_delay_max, "Max zio millisec delay before posting event");
+
+module_param(zio_requeue_io_start_cut_in_line, int, 0644);
+MODULE_PARM_DESC(zio_requeue_io_start_cut_in_line, "Prioritize requeued I/O");
+
+module_param(zfs_sync_pass_deferred_free, int, 0644);
+MODULE_PARM_DESC(zfs_sync_pass_deferred_free,
+	"Defer frees starting in this pass");
+
+module_param(zfs_sync_pass_dont_compress, int, 0644);
+MODULE_PARM_DESC(zfs_sync_pass_dont_compress,
+	"Don't compress starting in this pass");
+
+module_param(zfs_sync_pass_rewrite, int, 0644);
+MODULE_PARM_DESC(zfs_sync_pass_rewrite,
+	"Rewrite new bps starting in this pass");
+#endif
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/module/zfs/zio_checksum.c
@@ -0,0 +1,275 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013 by Delphix. All rights reserved.
+ */
+
+#include <sys/zfs_context.h>
+#include <sys/spa.h>
+#include <sys/zio.h>
+#include <sys/zio_checksum.h>
+#include <sys/zil.h>
+#include <zfs_fletcher.h>
+
+/*
+ * Checksum vectors.
+ *
+ * In the SPA, everything is checksummed.  We support checksum vectors
+ * for three distinct reasons:
+ *
+ *   1. Different kinds of data need different levels of protection.
+ *	For SPA metadata, we always want a very strong checksum.
+ *	For user data, we let users make the trade-off between speed
+ *	and checksum strength.
+ *
+ *   2. Cryptographic hash and MAC algorithms are an area of active research.
+ *	It is likely that in future hash functions will be at least as strong
+ *	as current best-of-breed, and may be substantially faster as well.
+ *	We want the ability to take advantage of these new hashes as soon as
+ *	they become available.
+ *
+ *   3. If someone develops hardware that can compute a strong hash quickly,
+ *	we want the ability to take advantage of that hardware.
+ *
+ * Of course, we don't want a checksum upgrade to invalidate existing
+ * data, so we store the checksum *function* in eight bits of the bp.
+ * This gives us room for up to 256 different checksum functions.
+ *
+ * When writing a block, we always checksum it with the latest-and-greatest
+ * checksum function of the appropriate strength.  When reading a block,
+ * we compare the expected checksum against the actual checksum, which we
+ * compute via the checksum function specified by BP_GET_CHECKSUM(bp).
+ */
+
+/*ARGSUSED*/
+static void
+zio_checksum_off(const void *buf, uint64_t size, zio_cksum_t *zcp)
+{
+	ZIO_SET_CHECKSUM(zcp, 0, 0, 0, 0);
+}
+
+zio_checksum_info_t zio_checksum_table[ZIO_CHECKSUM_FUNCTIONS] = {
+	{{NULL,			NULL},			0, 0, 0, "inherit"},
+	{{NULL,			NULL},			0, 0, 0, "on"},
+	{{zio_checksum_off,	zio_checksum_off},	0, 0, 0, "off"},
+	{{zio_checksum_SHA256,	zio_checksum_SHA256},	1, 1, 0, "label"},
+	{{zio_checksum_SHA256,	zio_checksum_SHA256},	1, 1, 0, "gang_header"},
+	{{fletcher_2_native,	fletcher_2_byteswap},	0, 1, 0, "zilog"},
+	{{fletcher_2_native,	fletcher_2_byteswap},	0, 0, 0, "fletcher2"},
+	{{fletcher_4_native,	fletcher_4_byteswap},	1, 0, 0, "fletcher4"},
+	{{zio_checksum_SHA256,	zio_checksum_SHA256},	1, 0, 1, "sha256"},
+	{{fletcher_4_native,	fletcher_4_byteswap},	0, 1, 0, "zilog2"},
+};
+
+enum zio_checksum
+zio_checksum_select(enum zio_checksum child, enum zio_checksum parent)
+{
+	ASSERT(child < ZIO_CHECKSUM_FUNCTIONS);
+	ASSERT(parent < ZIO_CHECKSUM_FUNCTIONS);
+	ASSERT(parent != ZIO_CHECKSUM_INHERIT && parent != ZIO_CHECKSUM_ON);
+
+	if (child == ZIO_CHECKSUM_INHERIT)
+		return (parent);
+
+	if (child == ZIO_CHECKSUM_ON)
+		return (ZIO_CHECKSUM_ON_VALUE);
+
+	return (child);
+}
+
+enum zio_checksum
+zio_checksum_dedup_select(spa_t *spa, enum zio_checksum child,
+    enum zio_checksum parent)
+{
+	ASSERT((child & ZIO_CHECKSUM_MASK) < ZIO_CHECKSUM_FUNCTIONS);
+	ASSERT((parent & ZIO_CHECKSUM_MASK) < ZIO_CHECKSUM_FUNCTIONS);
+	ASSERT(parent != ZIO_CHECKSUM_INHERIT && parent != ZIO_CHECKSUM_ON);
+
+	if (child == ZIO_CHECKSUM_INHERIT)
+		return (parent);
+
+	if (child == ZIO_CHECKSUM_ON)
+		return (spa_dedup_checksum(spa));
+
+	if (child == (ZIO_CHECKSUM_ON | ZIO_CHECKSUM_VERIFY))
+		return (spa_dedup_checksum(spa) | ZIO_CHECKSUM_VERIFY);
+
+	ASSERT(zio_checksum_table[child & ZIO_CHECKSUM_MASK].ci_dedup ||
+	    (child & ZIO_CHECKSUM_VERIFY) || child == ZIO_CHECKSUM_OFF);
+
+	return (child);
+}
+
+/*
+ * Set the external verifier for a gang block based on <vdev, offset, txg>,
+ * a tuple which is guaranteed to be unique for the life of the pool.
+ */
+static void
+zio_checksum_gang_verifier(zio_cksum_t *zcp, blkptr_t *bp)
+{
+	const dva_t *dva = BP_IDENTITY(bp);
+	uint64_t txg = BP_PHYSICAL_BIRTH(bp);
+
+	ASSERT(BP_IS_GANG(bp));
+
+	ZIO_SET_CHECKSUM(zcp, DVA_GET_VDEV(dva), DVA_GET_OFFSET(dva), txg, 0);
+}
+
+/*
+ * Set the external verifier for a label block based on its offset.
+ * The vdev is implicit, and the txg is unknowable at pool open time --
+ * hence the logic in vdev_uberblock_load() to find the most recent copy.
+ */
+static void
+zio_checksum_label_verifier(zio_cksum_t *zcp, uint64_t offset)
+{
+	ZIO_SET_CHECKSUM(zcp, offset, 0, 0, 0);
+}
+
+/*
+ * Generate the checksum.
+ */
+void
+zio_checksum_compute(zio_t *zio, enum zio_checksum checksum,
+	void *data, uint64_t size)
+{
+	blkptr_t *bp = zio->io_bp;
+	uint64_t offset = zio->io_offset;
+	zio_checksum_info_t *ci = &zio_checksum_table[checksum];
+	zio_cksum_t cksum;
+
+	ASSERT((uint_t)checksum < ZIO_CHECKSUM_FUNCTIONS);
+	ASSERT(ci->ci_func[0] != NULL);
+
+	if (ci->ci_eck) {
+		zio_eck_t *eck;
+
+		if (checksum == ZIO_CHECKSUM_ZILOG2) {
+			zil_chain_t *zilc = data;
+
+			size = P2ROUNDUP_TYPED(zilc->zc_nused, ZIL_MIN_BLKSZ,
+			    uint64_t);
+			eck = &zilc->zc_eck;
+		} else {
+			eck = (zio_eck_t *)((char *)data + size) - 1;
+		}
+		if (checksum == ZIO_CHECKSUM_GANG_HEADER)
+			zio_checksum_gang_verifier(&eck->zec_cksum, bp);
+		else if (checksum == ZIO_CHECKSUM_LABEL)
+			zio_checksum_label_verifier(&eck->zec_cksum, offset);
+		else
+			bp->blk_cksum = eck->zec_cksum;
+		eck->zec_magic = ZEC_MAGIC;
+		ci->ci_func[0](data, size, &cksum);
+		eck->zec_cksum = cksum;
+	} else {
+		ci->ci_func[0](data, size, &bp->blk_cksum);
+	}
+}
+
+int
+zio_checksum_error(zio_t *zio, zio_bad_cksum_t *info)
+{
+	blkptr_t *bp = zio->io_bp;
+	uint_t checksum = (bp == NULL ? zio->io_prop.zp_checksum :
+	    (BP_IS_GANG(bp) ? ZIO_CHECKSUM_GANG_HEADER : BP_GET_CHECKSUM(bp)));
+	int byteswap;
+	int error;
+	uint64_t size = (bp == NULL ? zio->io_size :
+	    (BP_IS_GANG(bp) ? SPA_GANGBLOCKSIZE : BP_GET_PSIZE(bp)));
+	uint64_t offset = zio->io_offset;
+	void *data = zio->io_data;
+	zio_checksum_info_t *ci = &zio_checksum_table[checksum];
+	zio_cksum_t actual_cksum, expected_cksum, verifier;
+
+	if (checksum >= ZIO_CHECKSUM_FUNCTIONS || ci->ci_func[0] == NULL)
+		return (SET_ERROR(EINVAL));
+
+	if (ci->ci_eck) {
+		zio_eck_t *eck;
+
+		if (checksum == ZIO_CHECKSUM_ZILOG2) {
+			zil_chain_t *zilc = data;
+			uint64_t nused;
+
+			eck = &zilc->zc_eck;
+			if (eck->zec_magic == ZEC_MAGIC)
+				nused = zilc->zc_nused;
+			else if (eck->zec_magic == BSWAP_64(ZEC_MAGIC))
+				nused = BSWAP_64(zilc->zc_nused);
+			else
+				return (SET_ERROR(ECKSUM));
+
+			if (nused > size)
+				return (SET_ERROR(ECKSUM));
+
+			size = P2ROUNDUP_TYPED(nused, ZIL_MIN_BLKSZ, uint64_t);
+		} else {
+			eck = (zio_eck_t *)((char *)data + size) - 1;
+		}
+
+		if (checksum == ZIO_CHECKSUM_GANG_HEADER)
+			zio_checksum_gang_verifier(&verifier, bp);
+		else if (checksum == ZIO_CHECKSUM_LABEL)
+			zio_checksum_label_verifier(&verifier, offset);
+		else
+			verifier = bp->blk_cksum;
+
+		byteswap = (eck->zec_magic == BSWAP_64(ZEC_MAGIC));
+
+		if (byteswap)
+			byteswap_uint64_array(&verifier, sizeof (zio_cksum_t));
+
+		expected_cksum = eck->zec_cksum;
+		eck->zec_cksum = verifier;
+		ci->ci_func[byteswap](data, size, &actual_cksum);
+		eck->zec_cksum = expected_cksum;
+
+		if (byteswap)
+			byteswap_uint64_array(&expected_cksum,
+			    sizeof (zio_cksum_t));
+	} else {
+		ASSERT(!BP_IS_GANG(bp));
+		byteswap = BP_SHOULD_BYTESWAP(bp);
+		expected_cksum = bp->blk_cksum;
+		ci->ci_func[byteswap](data, size, &actual_cksum);
+	}
+
+	info->zbc_expected = expected_cksum;
+	info->zbc_actual = actual_cksum;
+	info->zbc_checksum_name = ci->ci_name;
+	info->zbc_byteswapped = byteswap;
+	info->zbc_injected = 0;
+	info->zbc_has_cksum = 1;
+
+	if (!ZIO_CHECKSUM_EQUAL(actual_cksum, expected_cksum))
+		return (SET_ERROR(ECKSUM));
+
+	if (zio_injection_enabled && !zio->io_error &&
+	    (error = zio_handle_fault_injection(zio, ECKSUM)) != 0) {
+
+		info->zbc_injected = 1;
+		return (error);
+	}
+
+	return (0);
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/module/zfs/zio_compress.c
@@ -0,0 +1,134 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * Copyright (c) 2013 by Saso Kiselkov. All rights reserved.
+ */
+
+/*
+ * Copyright (c) 2013 by Delphix. All rights reserved.
+ */
+
+#include <sys/zfs_context.h>
+#include <sys/compress.h>
+#include <sys/spa.h>
+#include <sys/zfeature.h>
+#include <sys/zio.h>
+#include <sys/zio_compress.h>
+
+/*
+ * Compression vectors.
+ */
+
+zio_compress_info_t zio_compress_table[ZIO_COMPRESS_FUNCTIONS] = {
+	{NULL,			NULL,			0,	"inherit"},
+	{NULL,			NULL,			0,	"on"},
+	{NULL,			NULL,			0,	"uncompressed"},
+	{lzjb_compress,		lzjb_decompress,	0,	"lzjb"},
+	{NULL,			NULL,			0,	"empty"},
+	{gzip_compress,		gzip_decompress,	1,	"gzip-1"},
+	{gzip_compress,		gzip_decompress,	2,	"gzip-2"},
+	{gzip_compress,		gzip_decompress,	3,	"gzip-3"},
+	{gzip_compress,		gzip_decompress,	4,	"gzip-4"},
+	{gzip_compress,		gzip_decompress,	5,	"gzip-5"},
+	{gzip_compress,		gzip_decompress,	6,	"gzip-6"},
+	{gzip_compress,		gzip_decompress,	7,	"gzip-7"},
+	{gzip_compress,		gzip_decompress,	8,	"gzip-8"},
+	{gzip_compress,		gzip_decompress,	9,	"gzip-9"},
+	{zle_compress,		zle_decompress,		64,	"zle"},
+	{lz4_compress_zfs,	lz4_decompress_zfs,	0,	"lz4"},
+};
+
+enum zio_compress
+zio_compress_select(spa_t *spa, enum zio_compress child,
+    enum zio_compress parent)
+{
+	enum zio_compress result;
+
+	ASSERT(child < ZIO_COMPRESS_FUNCTIONS);
+	ASSERT(parent < ZIO_COMPRESS_FUNCTIONS);
+	ASSERT(parent != ZIO_COMPRESS_INHERIT);
+
+	result = child;
+	if (result == ZIO_COMPRESS_INHERIT)
+		result = parent;
+
+	if (result == ZIO_COMPRESS_ON) {
+		if (spa_feature_is_active(spa, SPA_FEATURE_LZ4_COMPRESS))
+			result = ZIO_COMPRESS_LZ4_ON_VALUE;
+		else
+			result = ZIO_COMPRESS_LEGACY_ON_VALUE;
+	}
+
+	return (result);
+}
+
+size_t
+zio_compress_data(enum zio_compress c, void *src, void *dst, size_t s_len)
+{
+	uint64_t *word, *word_end;
+	size_t c_len, d_len;
+	zio_compress_info_t *ci = &zio_compress_table[c];
+
+	ASSERT((uint_t)c < ZIO_COMPRESS_FUNCTIONS);
+	ASSERT((uint_t)c == ZIO_COMPRESS_EMPTY || ci->ci_compress != NULL);
+
+	/*
+	 * If the data is all zeroes, we don't even need to allocate
+	 * a block for it.  We indicate this by returning zero size.
+	 */
+	word_end = (uint64_t *)((char *)src + s_len);
+	for (word = src; word < word_end; word++)
+		if (*word != 0)
+			break;
+
+	if (word == word_end)
+		return (0);
+
+	if (c == ZIO_COMPRESS_EMPTY)
+		return (s_len);
+
+	/* Compress at least 12.5% */
+	d_len = s_len - (s_len >> 3);
+	c_len = ci->ci_compress(src, dst, s_len, d_len, ci->ci_level);
+
+	if (c_len > d_len)
+		return (s_len);
+
+	ASSERT3U(c_len, <=, d_len);
+	return (c_len);
+}
+
+int
+zio_decompress_data(enum zio_compress c, void *src, void *dst,
+    size_t s_len, size_t d_len)
+{
+	zio_compress_info_t *ci = &zio_compress_table[c];
+
+	if ((uint_t)c >= ZIO_COMPRESS_FUNCTIONS || ci->ci_decompress == NULL)
+		return (SET_ERROR(EINVAL));
+
+	return (ci->ci_decompress(src, dst, s_len, d_len, ci->ci_level));
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/module/zfs/zio_inject.c
@@ -0,0 +1,539 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2014 by Delphix. All rights reserved.
+ */
+
+/*
+ * ZFS fault injection
+ *
+ * To handle fault injection, we keep track of a series of zinject_record_t
+ * structures which describe which logical block(s) should be injected with a
+ * fault.  These are kept in a global list.  Each record corresponds to a given
+ * spa_t and maintains a special hold on the spa_t so that it cannot be deleted
+ * or exported while the injection record exists.
+ *
+ * Device level injection is done using the 'zi_guid' field.  If this is set, it
+ * means that the error is destined for a particular device, not a piece of
+ * data.
+ *
+ * This is a rather poor data structure and algorithm, but we don't expect more
+ * than a few faults at any one time, so it should be sufficient for our needs.
+ */
+
+#include <sys/arc.h>
+#include <sys/zio_impl.h>
+#include <sys/zfs_ioctl.h>
+#include <sys/vdev_impl.h>
+#include <sys/dmu_objset.h>
+#include <sys/fs/zfs.h>
+
+uint32_t zio_injection_enabled = 0;
+
+typedef struct inject_handler {
+	int			zi_id;
+	spa_t			*zi_spa;
+	zinject_record_t	zi_record;
+	list_node_t		zi_link;
+} inject_handler_t;
+
+static list_t inject_handlers;
+static krwlock_t inject_lock;
+static int inject_next_id = 1;
+
+/*
+ * Returns true if the given record matches the I/O in progress.
+ */
+static boolean_t
+zio_match_handler(zbookmark_phys_t *zb, uint64_t type,
+    zinject_record_t *record, int error)
+{
+	/*
+	 * Check for a match against the MOS, which is based on type
+	 */
+	if (zb->zb_objset == DMU_META_OBJSET &&
+	    record->zi_objset == DMU_META_OBJSET &&
+	    record->zi_object == DMU_META_DNODE_OBJECT) {
+		if (record->zi_type == DMU_OT_NONE ||
+		    type == record->zi_type)
+			return (record->zi_freq == 0 ||
+			    spa_get_random(100) < record->zi_freq);
+		else
+			return (B_FALSE);
+	}
+
+	/*
+	 * Check for an exact match.
+	 */
+	if (zb->zb_objset == record->zi_objset &&
+	    zb->zb_object == record->zi_object &&
+	    zb->zb_level == record->zi_level &&
+	    zb->zb_blkid >= record->zi_start &&
+	    zb->zb_blkid <= record->zi_end &&
+	    error == record->zi_error)
+		return (record->zi_freq == 0 ||
+		    spa_get_random(100) < record->zi_freq);
+
+	return (B_FALSE);
+}
+
+/*
+ * Panic the system when a config change happens in the function
+ * specified by tag.
+ */
+void
+zio_handle_panic_injection(spa_t *spa, char *tag, uint64_t type)
+{
+	inject_handler_t *handler;
+
+	rw_enter(&inject_lock, RW_READER);
+
+	for (handler = list_head(&inject_handlers); handler != NULL;
+	    handler = list_next(&inject_handlers, handler)) {
+
+		if (spa != handler->zi_spa)
+			continue;
+
+		if (handler->zi_record.zi_type == type &&
+		    strcmp(tag, handler->zi_record.zi_func) == 0)
+			panic("Panic requested in function %s\n", tag);
+	}
+
+	rw_exit(&inject_lock);
+}
+
+/*
+ * Determine if the I/O in question should return failure.  Returns the errno
+ * to be returned to the caller.
+ */
+int
+zio_handle_fault_injection(zio_t *zio, int error)
+{
+	int ret = 0;
+	inject_handler_t *handler;
+
+	/*
+	 * Ignore I/O not associated with any logical data.
+	 */
+	if (zio->io_logical == NULL)
+		return (0);
+
+	/*
+	 * Currently, we only support fault injection on reads.
+	 */
+	if (zio->io_type != ZIO_TYPE_READ)
+		return (0);
+
+	rw_enter(&inject_lock, RW_READER);
+
+	for (handler = list_head(&inject_handlers); handler != NULL;
+	    handler = list_next(&inject_handlers, handler)) {
+
+		if (zio->io_spa != handler->zi_spa ||
+		    handler->zi_record.zi_cmd != ZINJECT_DATA_FAULT)
+			continue;
+
+		/* If this handler matches, return EIO */
+		if (zio_match_handler(&zio->io_logical->io_bookmark,
+		    zio->io_bp ? BP_GET_TYPE(zio->io_bp) : DMU_OT_NONE,
+		    &handler->zi_record, error)) {
+			ret = error;
+			break;
+		}
+	}
+
+	rw_exit(&inject_lock);
+
+	return (ret);
+}
+
+/*
+ * Determine if the zio is part of a label update and has an injection
+ * handler associated with that portion of the label. Currently, we
+ * allow error injection in either the nvlist or the uberblock region of
+ * of the vdev label.
+ */
+int
+zio_handle_label_injection(zio_t *zio, int error)
+{
+	inject_handler_t *handler;
+	vdev_t *vd = zio->io_vd;
+	uint64_t offset = zio->io_offset;
+	int label;
+	int ret = 0;
+
+	if (offset >= VDEV_LABEL_START_SIZE &&
+	    offset < vd->vdev_psize - VDEV_LABEL_END_SIZE)
+		return (0);
+
+	rw_enter(&inject_lock, RW_READER);
+
+	for (handler = list_head(&inject_handlers); handler != NULL;
+	    handler = list_next(&inject_handlers, handler)) {
+		uint64_t start = handler->zi_record.zi_start;
+		uint64_t end = handler->zi_record.zi_end;
+
+		if (handler->zi_record.zi_cmd != ZINJECT_LABEL_FAULT)
+			continue;
+
+		/*
+		 * The injection region is the relative offsets within a
+		 * vdev label. We must determine the label which is being
+		 * updated and adjust our region accordingly.
+		 */
+		label = vdev_label_number(vd->vdev_psize, offset);
+		start = vdev_label_offset(vd->vdev_psize, label, start);
+		end = vdev_label_offset(vd->vdev_psize, label, end);
+
+		if (zio->io_vd->vdev_guid == handler->zi_record.zi_guid &&
+		    (offset >= start && offset <= end)) {
+			ret = error;
+			break;
+		}
+	}
+	rw_exit(&inject_lock);
+	return (ret);
+}
+
+
+int
+zio_handle_device_injection(vdev_t *vd, zio_t *zio, int error)
+{
+	inject_handler_t *handler;
+	int ret = 0;
+
+	/*
+	 * We skip over faults in the labels unless it's during
+	 * device open (i.e. zio == NULL).
+	 */
+	if (zio != NULL) {
+		uint64_t offset = zio->io_offset;
+
+		if (offset < VDEV_LABEL_START_SIZE ||
+		    offset >= vd->vdev_psize - VDEV_LABEL_END_SIZE)
+			return (0);
+	}
+
+	rw_enter(&inject_lock, RW_READER);
+
+	for (handler = list_head(&inject_handlers); handler != NULL;
+	    handler = list_next(&inject_handlers, handler)) {
+
+		if (handler->zi_record.zi_cmd != ZINJECT_DEVICE_FAULT)
+			continue;
+
+		if (vd->vdev_guid == handler->zi_record.zi_guid) {
+			if (handler->zi_record.zi_failfast &&
+			    (zio == NULL || (zio->io_flags &
+			    (ZIO_FLAG_IO_RETRY | ZIO_FLAG_TRYHARD)))) {
+				continue;
+			}
+
+			/* Handle type specific I/O failures */
+			if (zio != NULL &&
+			    handler->zi_record.zi_iotype != ZIO_TYPES &&
+			    handler->zi_record.zi_iotype != zio->io_type)
+				continue;
+
+			if (handler->zi_record.zi_error == error) {
+				/*
+				 * For a failed open, pretend like the device
+				 * has gone away.
+				 */
+				if (error == ENXIO)
+					vd->vdev_stat.vs_aux =
+					    VDEV_AUX_OPEN_FAILED;
+
+				/*
+				 * Treat these errors as if they had been
+				 * retried so that all the appropriate stats
+				 * and FMA events are generated.
+				 */
+				if (!handler->zi_record.zi_failfast &&
+				    zio != NULL)
+					zio->io_flags |= ZIO_FLAG_IO_RETRY;
+
+				ret = error;
+				break;
+			}
+			if (handler->zi_record.zi_error == ENXIO) {
+				ret = SET_ERROR(EIO);
+				break;
+			}
+		}
+	}
+
+	rw_exit(&inject_lock);
+
+	return (ret);
+}
+
+/*
+ * Simulate hardware that ignores cache flushes.  For requested number
+ * of seconds nix the actual writing to disk.
+ */
+void
+zio_handle_ignored_writes(zio_t *zio)
+{
+	inject_handler_t *handler;
+
+	rw_enter(&inject_lock, RW_READER);
+
+	for (handler = list_head(&inject_handlers); handler != NULL;
+	    handler = list_next(&inject_handlers, handler)) {
+
+		/* Ignore errors not destined for this pool */
+		if (zio->io_spa != handler->zi_spa ||
+		    handler->zi_record.zi_cmd != ZINJECT_IGNORED_WRITES)
+			continue;
+
+		/*
+		 * Positive duration implies # of seconds, negative
+		 * a number of txgs
+		 */
+		if (handler->zi_record.zi_timer == 0) {
+			if (handler->zi_record.zi_duration > 0)
+				handler->zi_record.zi_timer = ddi_get_lbolt64();
+			else
+				handler->zi_record.zi_timer = zio->io_txg;
+		}
+
+		/* Have a "problem" writing 60% of the time */
+		if (spa_get_random(100) < 60)
+			zio->io_pipeline &= ~ZIO_VDEV_IO_STAGES;
+		break;
+	}
+
+	rw_exit(&inject_lock);
+}
+
+void
+spa_handle_ignored_writes(spa_t *spa)
+{
+	inject_handler_t *handler;
+
+	if (zio_injection_enabled == 0)
+		return;
+
+	rw_enter(&inject_lock, RW_READER);
+
+	for (handler = list_head(&inject_handlers); handler != NULL;
+	    handler = list_next(&inject_handlers, handler)) {
+
+		if (spa != handler->zi_spa ||
+		    handler->zi_record.zi_cmd != ZINJECT_IGNORED_WRITES)
+			continue;
+
+		if (handler->zi_record.zi_duration > 0) {
+			VERIFY(handler->zi_record.zi_timer == 0 ||
+			    ddi_time_after64(
+			    (int64_t)handler->zi_record.zi_timer +
+			    handler->zi_record.zi_duration * hz,
+			    ddi_get_lbolt64()));
+		} else {
+			/* duration is negative so the subtraction here adds */
+			VERIFY(handler->zi_record.zi_timer == 0 ||
+			    handler->zi_record.zi_timer -
+			    handler->zi_record.zi_duration >=
+			    spa_syncing_txg(spa));
+		}
+	}
+
+	rw_exit(&inject_lock);
+}
+
+uint64_t
+zio_handle_io_delay(zio_t *zio)
+{
+	vdev_t *vd = zio->io_vd;
+	inject_handler_t *handler;
+	uint64_t seconds = 0;
+
+	if (zio_injection_enabled == 0)
+		return (0);
+
+	rw_enter(&inject_lock, RW_READER);
+
+	for (handler = list_head(&inject_handlers); handler != NULL;
+	    handler = list_next(&inject_handlers, handler)) {
+
+		if (handler->zi_record.zi_cmd != ZINJECT_DELAY_IO)
+			continue;
+
+		if (vd->vdev_guid == handler->zi_record.zi_guid) {
+			seconds = handler->zi_record.zi_timer;
+			break;
+		}
+
+	}
+	rw_exit(&inject_lock);
+	return (seconds);
+}
+
+/*
+ * Create a new handler for the given record.  We add it to the list, adding
+ * a reference to the spa_t in the process.  We increment zio_injection_enabled,
+ * which is the switch to trigger all fault injection.
+ */
+int
+zio_inject_fault(char *name, int flags, int *id, zinject_record_t *record)
+{
+	inject_handler_t *handler;
+	int error;
+	spa_t *spa;
+
+	/*
+	 * If this is pool-wide metadata, make sure we unload the corresponding
+	 * spa_t, so that the next attempt to load it will trigger the fault.
+	 * We call spa_reset() to unload the pool appropriately.
+	 */
+	if (flags & ZINJECT_UNLOAD_SPA)
+		if ((error = spa_reset(name)) != 0)
+			return (error);
+
+	if (!(flags & ZINJECT_NULL)) {
+		/*
+		 * spa_inject_ref() will add an injection reference, which will
+		 * prevent the pool from being removed from the namespace while
+		 * still allowing it to be unloaded.
+		 */
+		if ((spa = spa_inject_addref(name)) == NULL)
+			return (SET_ERROR(ENOENT));
+
+		handler = kmem_alloc(sizeof (inject_handler_t), KM_SLEEP);
+
+		rw_enter(&inject_lock, RW_WRITER);
+
+		*id = handler->zi_id = inject_next_id++;
+		handler->zi_spa = spa;
+		handler->zi_record = *record;
+		list_insert_tail(&inject_handlers, handler);
+		atomic_add_32(&zio_injection_enabled, 1);
+
+		rw_exit(&inject_lock);
+	}
+
+	/*
+	 * Flush the ARC, so that any attempts to read this data will end up
+	 * going to the ZIO layer.  Note that this is a little overkill, but
+	 * we don't have the necessary ARC interfaces to do anything else, and
+	 * fault injection isn't a performance critical path.
+	 */
+	if (flags & ZINJECT_FLUSH_ARC)
+		/*
+		 * We must use FALSE to ensure arc_flush returns, since
+		 * we're not preventing concurrent ARC insertions.
+		 */
+		arc_flush(NULL, FALSE);
+
+	return (0);
+}
+
+/*
+ * Returns the next record with an ID greater than that supplied to the
+ * function.  Used to iterate over all handlers in the system.
+ */
+int
+zio_inject_list_next(int *id, char *name, size_t buflen,
+    zinject_record_t *record)
+{
+	inject_handler_t *handler;
+	int ret;
+
+	mutex_enter(&spa_namespace_lock);
+	rw_enter(&inject_lock, RW_READER);
+
+	for (handler = list_head(&inject_handlers); handler != NULL;
+	    handler = list_next(&inject_handlers, handler))
+		if (handler->zi_id > *id)
+			break;
+
+	if (handler) {
+		*record = handler->zi_record;
+		*id = handler->zi_id;
+		(void) strncpy(name, spa_name(handler->zi_spa), buflen);
+		ret = 0;
+	} else {
+		ret = SET_ERROR(ENOENT);
+	}
+
+	rw_exit(&inject_lock);
+	mutex_exit(&spa_namespace_lock);
+
+	return (ret);
+}
+
+/*
+ * Clear the fault handler with the given identifier, or return ENOENT if none
+ * exists.
+ */
+int
+zio_clear_fault(int id)
+{
+	inject_handler_t *handler;
+
+	rw_enter(&inject_lock, RW_WRITER);
+
+	for (handler = list_head(&inject_handlers); handler != NULL;
+	    handler = list_next(&inject_handlers, handler))
+		if (handler->zi_id == id)
+			break;
+
+	if (handler == NULL) {
+		rw_exit(&inject_lock);
+		return (SET_ERROR(ENOENT));
+	}
+
+	list_remove(&inject_handlers, handler);
+	rw_exit(&inject_lock);
+
+	spa_inject_delref(handler->zi_spa);
+	kmem_free(handler, sizeof (inject_handler_t));
+	atomic_add_32(&zio_injection_enabled, -1);
+
+	return (0);
+}
+
+void
+zio_inject_init(void)
+{
+	rw_init(&inject_lock, NULL, RW_DEFAULT, NULL);
+	list_create(&inject_handlers, sizeof (inject_handler_t),
+	    offsetof(inject_handler_t, zi_link));
+}
+
+void
+zio_inject_fini(void)
+{
+	list_destroy(&inject_handlers);
+	rw_destroy(&inject_lock);
+}
+
+#if defined(_KERNEL) && defined(HAVE_SPL)
+EXPORT_SYMBOL(zio_injection_enabled);
+EXPORT_SYMBOL(zio_inject_fault);
+EXPORT_SYMBOL(zio_inject_list_next);
+EXPORT_SYMBOL(zio_clear_fault);
+EXPORT_SYMBOL(zio_handle_fault_injection);
+EXPORT_SYMBOL(zio_handle_device_injection);
+EXPORT_SYMBOL(zio_handle_label_injection);
+#endif
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/module/zfs/zle.c
@@ -0,0 +1,86 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/*
+ * Zero-length encoding.  This is a fast and simple algorithm to eliminate
+ * runs of zeroes.  Each chunk of compressed data begins with a length byte, b.
+ * If b < n (where n is the compression parameter) then the next b + 1 bytes
+ * are literal values.  If b >= n then the next (256 - b + 1) bytes are zero.
+ */
+#include <sys/types.h>
+#include <sys/sysmacros.h>
+
+size_t
+zle_compress(void *s_start, void *d_start, size_t s_len, size_t d_len, int n)
+{
+	uchar_t *src = s_start;
+	uchar_t *dst = d_start;
+	uchar_t *s_end = src + s_len;
+	uchar_t *d_end = dst + d_len;
+
+	while (src < s_end && dst < d_end - 1) {
+		uchar_t *first = src;
+		uchar_t *len = dst++;
+		if (src[0] == 0) {
+			uchar_t *last = src + (256 - n);
+			while (src < MIN(last, s_end) && src[0] == 0)
+				src++;
+			*len = src - first - 1 + n;
+		} else {
+			uchar_t *last = src + n;
+			if (d_end - dst < n)
+				break;
+			while (src < MIN(last, s_end) - 1 && (src[0] | src[1]))
+				*dst++ = *src++;
+			if (src[0])
+				*dst++ = *src++;
+			*len = src - first - 1;
+		}
+	}
+	return (src == s_end ? dst - (uchar_t *)d_start : s_len);
+}
+
+int
+zle_decompress(void *s_start, void *d_start, size_t s_len, size_t d_len, int n)
+{
+	uchar_t *src = s_start;
+	uchar_t *dst = d_start;
+	uchar_t *s_end = src + s_len;
+	uchar_t *d_end = dst + d_len;
+
+	while (src < s_end && dst < d_end) {
+		int len = 1 + *src++;
+		if (len <= n) {
+			while (len-- != 0)
+				*dst++ = *src++;
+		} else {
+			len -= n;
+			while (len-- != 0)
+				*dst++ = 0;
+		}
+	}
+	return (dst == d_end ? 0 : -1);
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/module/zfs/zpl_ctldir.c
@@ -0,0 +1,542 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (C) 2011 Lawrence Livermore National Security, LLC.
+ * Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ * LLNL-CODE-403049.
+ * Rewritten for Linux by:
+ *   Rohan Puri <rohan.puri15@gmail.com>
+ *   Brian Behlendorf <behlendorf1@llnl.gov>
+ */
+
+#include <sys/zfs_vfsops.h>
+#include <sys/zfs_vnops.h>
+#include <sys/zfs_znode.h>
+#include <sys/zfs_ctldir.h>
+#include <sys/zpl.h>
+
+/*
+ * Common open routine.  Disallow any write access.
+ */
+/* ARGSUSED */
+static int
+zpl_common_open(struct inode *ip, struct file *filp)
+{
+	if (filp->f_mode & FMODE_WRITE)
+		return (-EACCES);
+
+	return (generic_file_open(ip, filp));
+}
+
+/*
+ * Get root directory contents.
+ */
+static int
+zpl_root_iterate(struct file *filp, struct dir_context *ctx)
+{
+	zfs_sb_t *zsb = ITOZSB(filp->f_path.dentry->d_inode);
+	int error = 0;
+
+	ZFS_ENTER(zsb);
+
+	if (!dir_emit_dots(filp, ctx))
+		goto out;
+
+	if (ctx->pos == 2) {
+		if (!dir_emit(ctx, ZFS_SNAPDIR_NAME, strlen(ZFS_SNAPDIR_NAME),
+		    ZFSCTL_INO_SNAPDIR, DT_DIR))
+			goto out;
+
+		ctx->pos++;
+	}
+
+	if (ctx->pos == 3) {
+		if (!dir_emit(ctx, ZFS_SHAREDIR_NAME, strlen(ZFS_SHAREDIR_NAME),
+		    ZFSCTL_INO_SHARES, DT_DIR))
+			goto out;
+
+		ctx->pos++;
+	}
+out:
+	ZFS_EXIT(zsb);
+
+	return (error);
+}
+
+#if !defined(HAVE_VFS_ITERATE)
+static int
+zpl_root_readdir(struct file *filp, void *dirent, filldir_t filldir)
+{
+	struct dir_context ctx = DIR_CONTEXT_INIT(dirent, filldir, filp->f_pos);
+	int error;
+
+	error = zpl_root_iterate(filp, &ctx);
+	filp->f_pos = ctx.pos;
+
+	return (error);
+}
+#endif /* HAVE_VFS_ITERATE */
+
+/*
+ * Get root directory attributes.
+ */
+/* ARGSUSED */
+static int
+zpl_root_getattr(struct vfsmount *mnt, struct dentry *dentry,
+    struct kstat *stat)
+{
+	int error;
+
+	error = simple_getattr(mnt, dentry, stat);
+	stat->atime = CURRENT_TIME;
+
+	return (error);
+}
+
+static struct dentry *
+#ifdef HAVE_LOOKUP_NAMEIDATA
+zpl_root_lookup(struct inode *dip, struct dentry *dentry, struct nameidata *nd)
+#else
+zpl_root_lookup(struct inode *dip, struct dentry *dentry, unsigned int flags)
+#endif
+{
+	cred_t *cr = CRED();
+	struct inode *ip;
+	int error;
+
+	crhold(cr);
+	error = -zfsctl_root_lookup(dip, dname(dentry), &ip, 0, cr, NULL, NULL);
+	ASSERT3S(error, <=, 0);
+	crfree(cr);
+
+	if (error) {
+		if (error == -ENOENT)
+			return (d_splice_alias(NULL, dentry));
+		else
+			return (ERR_PTR(error));
+	}
+
+	return (d_splice_alias(ip, dentry));
+}
+
+/*
+ * The '.zfs' control directory file and inode operations.
+ */
+const struct file_operations zpl_fops_root = {
+	.open		= zpl_common_open,
+	.llseek		= generic_file_llseek,
+	.read		= generic_read_dir,
+#ifdef HAVE_VFS_ITERATE
+	.iterate	= zpl_root_iterate,
+#else
+	.readdir	= zpl_root_readdir,
+#endif
+};
+
+const struct inode_operations zpl_ops_root = {
+	.lookup		= zpl_root_lookup,
+	.getattr	= zpl_root_getattr,
+};
+
+#ifdef HAVE_AUTOMOUNT
+static struct vfsmount *
+zpl_snapdir_automount(struct path *path)
+{
+	int error;
+
+	error = -zfsctl_snapshot_mount(path, 0);
+	if (error)
+		return (ERR_PTR(error));
+
+	/*
+	 * Rather than returning the new vfsmount for the snapshot we must
+	 * return NULL to indicate a mount collision.  This is done because
+	 * the user space mount calls do_add_mount() which adds the vfsmount
+	 * to the name space.  If we returned the new mount here it would be
+	 * added again to the vfsmount list resulting in list corruption.
+	 */
+	return (NULL);
+}
+#endif /* HAVE_AUTOMOUNT */
+
+/*
+ * Negative dentries must always be revalidated so newly created snapshots
+ * can be detected and automounted.  Normal dentries should be kept because
+ * as of the 3.18 kernel revaliding the mountpoint dentry will result in
+ * the snapshot being immediately unmounted.
+ */
+static int
+#ifdef HAVE_D_REVALIDATE_NAMEIDATA
+zpl_snapdir_revalidate(struct dentry *dentry, struct nameidata *i)
+#else
+zpl_snapdir_revalidate(struct dentry *dentry, unsigned int flags)
+#endif
+{
+	return (!!dentry->d_inode);
+}
+
+dentry_operations_t zpl_dops_snapdirs = {
+/*
+ * Auto mounting of snapshots is only supported for 2.6.37 and
+ * newer kernels.  Prior to this kernel the ops->follow_link()
+ * callback was used as a hack to trigger the mount.  The
+ * resulting vfsmount was then explicitly grafted in to the
+ * name space.  While it might be possible to add compatibility
+ * code to accomplish this it would require considerable care.
+ */
+#ifdef HAVE_AUTOMOUNT
+	.d_automount	= zpl_snapdir_automount,
+#endif /* HAVE_AUTOMOUNT */
+	.d_revalidate	= zpl_snapdir_revalidate,
+};
+
+static struct dentry *
+#ifdef HAVE_LOOKUP_NAMEIDATA
+zpl_snapdir_lookup(struct inode *dip, struct dentry *dentry,
+    struct nameidata *nd)
+#else
+zpl_snapdir_lookup(struct inode *dip, struct dentry *dentry,
+    unsigned int flags)
+#endif
+
+{
+	fstrans_cookie_t cookie;
+	cred_t *cr = CRED();
+	struct inode *ip = NULL;
+	int error;
+
+	crhold(cr);
+	cookie = spl_fstrans_mark();
+	error = -zfsctl_snapdir_lookup(dip, dname(dentry), &ip,
+	    0, cr, NULL, NULL);
+	ASSERT3S(error, <=, 0);
+	spl_fstrans_unmark(cookie);
+	crfree(cr);
+
+	if (error && error != -ENOENT)
+		return (ERR_PTR(error));
+
+	ASSERT(error == 0 || ip == NULL);
+	d_clear_d_op(dentry);
+	d_set_d_op(dentry, &zpl_dops_snapdirs);
+#ifdef HAVE_AUTOMOUNT
+	dentry->d_flags |= DCACHE_NEED_AUTOMOUNT;
+#endif
+
+	return (d_splice_alias(ip, dentry));
+}
+
+static int
+zpl_snapdir_iterate(struct file *filp, struct dir_context *ctx)
+{
+	zfs_sb_t *zsb = ITOZSB(filp->f_path.dentry->d_inode);
+	fstrans_cookie_t cookie;
+	char snapname[MAXNAMELEN];
+	boolean_t case_conflict;
+	uint64_t id, pos;
+	int error = 0;
+
+	ZFS_ENTER(zsb);
+	cookie = spl_fstrans_mark();
+
+	if (!dir_emit_dots(filp, ctx))
+		goto out;
+
+	pos = ctx->pos;
+	while (error == 0) {
+		dsl_pool_config_enter(dmu_objset_pool(zsb->z_os), FTAG);
+		error = -dmu_snapshot_list_next(zsb->z_os, MAXNAMELEN,
+		    snapname, &id, &pos, &case_conflict);
+		dsl_pool_config_exit(dmu_objset_pool(zsb->z_os), FTAG);
+		if (error)
+			goto out;
+
+		if (!dir_emit(ctx, snapname, strlen(snapname),
+		    ZFSCTL_INO_SHARES - id, DT_DIR))
+			goto out;
+
+		ctx->pos = pos;
+	}
+out:
+	spl_fstrans_unmark(cookie);
+	ZFS_EXIT(zsb);
+
+	if (error == -ENOENT)
+		return (0);
+
+	return (error);
+}
+
+#if !defined(HAVE_VFS_ITERATE)
+static int
+zpl_snapdir_readdir(struct file *filp, void *dirent, filldir_t filldir)
+{
+	struct dir_context ctx = DIR_CONTEXT_INIT(dirent, filldir, filp->f_pos);
+	int error;
+
+	error = zpl_snapdir_iterate(filp, &ctx);
+	filp->f_pos = ctx.pos;
+
+	return (error);
+}
+#endif /* HAVE_VFS_ITERATE */
+
+int
+zpl_snapdir_rename(struct inode *sdip, struct dentry *sdentry,
+    struct inode *tdip, struct dentry *tdentry)
+{
+	cred_t *cr = CRED();
+	int error;
+
+	crhold(cr);
+	error = -zfsctl_snapdir_rename(sdip, dname(sdentry),
+	    tdip, dname(tdentry), cr, 0);
+	ASSERT3S(error, <=, 0);
+	crfree(cr);
+
+	return (error);
+}
+
+static int
+zpl_snapdir_rmdir(struct inode *dip, struct dentry *dentry)
+{
+	cred_t *cr = CRED();
+	int error;
+
+	crhold(cr);
+	error = -zfsctl_snapdir_remove(dip, dname(dentry), cr, 0);
+	ASSERT3S(error, <=, 0);
+	crfree(cr);
+
+	return (error);
+}
+
+static int
+zpl_snapdir_mkdir(struct inode *dip, struct dentry *dentry, zpl_umode_t mode)
+{
+	cred_t *cr = CRED();
+	vattr_t *vap;
+	struct inode *ip;
+	int error;
+
+	crhold(cr);
+	vap = kmem_zalloc(sizeof (vattr_t), KM_SLEEP);
+	zpl_vap_init(vap, dip, mode | S_IFDIR, cr);
+
+	error = -zfsctl_snapdir_mkdir(dip, dname(dentry), vap, &ip, cr, 0);
+	if (error == 0) {
+		d_clear_d_op(dentry);
+		d_set_d_op(dentry, &zpl_dops_snapdirs);
+		d_instantiate(dentry, ip);
+	}
+
+	kmem_free(vap, sizeof (vattr_t));
+	ASSERT3S(error, <=, 0);
+	crfree(cr);
+
+	return (error);
+}
+
+/*
+ * Get snapshot directory attributes.
+ */
+/* ARGSUSED */
+static int
+zpl_snapdir_getattr(struct vfsmount *mnt, struct dentry *dentry,
+    struct kstat *stat)
+{
+	zfs_sb_t *zsb = ITOZSB(dentry->d_inode);
+	int error;
+
+	ZFS_ENTER(zsb);
+	error = simple_getattr(mnt, dentry, stat);
+	stat->nlink = stat->size = 2;
+	stat->ctime = stat->mtime = dmu_objset_snap_cmtime(zsb->z_os);
+	stat->atime = CURRENT_TIME;
+	ZFS_EXIT(zsb);
+
+	return (error);
+}
+
+/*
+ * The '.zfs/snapshot' directory file operations.  These mainly control
+ * generating the list of available snapshots when doing an 'ls' in the
+ * directory.  See zpl_snapdir_readdir().
+ */
+const struct file_operations zpl_fops_snapdir = {
+	.open		= zpl_common_open,
+	.llseek		= generic_file_llseek,
+	.read		= generic_read_dir,
+#ifdef HAVE_VFS_ITERATE
+	.iterate	= zpl_snapdir_iterate,
+#else
+	.readdir	= zpl_snapdir_readdir,
+#endif
+
+};
+
+/*
+ * The '.zfs/snapshot' directory inode operations.  These mainly control
+ * creating an inode for a snapshot directory and initializing the needed
+ * infrastructure to automount the snapshot.  See zpl_snapdir_lookup().
+ */
+const struct inode_operations zpl_ops_snapdir = {
+	.lookup		= zpl_snapdir_lookup,
+	.getattr	= zpl_snapdir_getattr,
+	.rename		= zpl_snapdir_rename,
+	.rmdir		= zpl_snapdir_rmdir,
+	.mkdir		= zpl_snapdir_mkdir,
+};
+
+static struct dentry *
+#ifdef HAVE_LOOKUP_NAMEIDATA
+zpl_shares_lookup(struct inode *dip, struct dentry *dentry,
+    struct nameidata *nd)
+#else
+zpl_shares_lookup(struct inode *dip, struct dentry *dentry,
+    unsigned int flags)
+#endif
+{
+	fstrans_cookie_t cookie;
+	cred_t *cr = CRED();
+	struct inode *ip = NULL;
+	int error;
+
+	crhold(cr);
+	cookie = spl_fstrans_mark();
+	error = -zfsctl_shares_lookup(dip, dname(dentry), &ip,
+	    0, cr, NULL, NULL);
+	ASSERT3S(error, <=, 0);
+	spl_fstrans_unmark(cookie);
+	crfree(cr);
+
+	if (error) {
+		if (error == -ENOENT)
+			return (d_splice_alias(NULL, dentry));
+		else
+			return (ERR_PTR(error));
+	}
+
+	return (d_splice_alias(ip, dentry));
+}
+
+static int
+zpl_shares_iterate(struct file *filp, struct dir_context *ctx)
+{
+	fstrans_cookie_t cookie;
+	cred_t *cr = CRED();
+	zfs_sb_t *zsb = ITOZSB(filp->f_path.dentry->d_inode);
+	znode_t *dzp;
+	int error = 0;
+
+	ZFS_ENTER(zsb);
+	cookie = spl_fstrans_mark();
+
+	if (zsb->z_shares_dir == 0) {
+		dir_emit_dots(filp, ctx);
+		goto out;
+	}
+
+	error = -zfs_zget(zsb, zsb->z_shares_dir, &dzp);
+	if (error)
+		goto out;
+
+	crhold(cr);
+	error = -zfs_readdir(ZTOI(dzp), ctx, cr);
+	crfree(cr);
+
+	iput(ZTOI(dzp));
+out:
+	spl_fstrans_unmark(cookie);
+	ZFS_EXIT(zsb);
+	ASSERT3S(error, <=, 0);
+
+	return (error);
+}
+
+#if !defined(HAVE_VFS_ITERATE)
+static int
+zpl_shares_readdir(struct file *filp, void *dirent, filldir_t filldir)
+{
+	struct dir_context ctx = DIR_CONTEXT_INIT(dirent, filldir, filp->f_pos);
+	int error;
+
+	error = zpl_shares_iterate(filp, &ctx);
+	filp->f_pos = ctx.pos;
+
+	return (error);
+}
+#endif /* HAVE_VFS_ITERATE */
+
+/* ARGSUSED */
+static int
+zpl_shares_getattr(struct vfsmount *mnt, struct dentry *dentry,
+    struct kstat *stat)
+{
+	struct inode *ip = dentry->d_inode;
+	zfs_sb_t *zsb = ITOZSB(ip);
+	znode_t *dzp;
+	int error;
+
+	ZFS_ENTER(zsb);
+
+	if (zsb->z_shares_dir == 0) {
+		error = simple_getattr(mnt, dentry, stat);
+		stat->nlink = stat->size = 2;
+		stat->atime = CURRENT_TIME;
+		ZFS_EXIT(zsb);
+		return (error);
+	}
+
+	error = -zfs_zget(zsb, zsb->z_shares_dir, &dzp);
+	if (error == 0) {
+		error = -zfs_getattr_fast(ZTOI(dzp), stat);
+		iput(ZTOI(dzp));
+	}
+
+	ZFS_EXIT(zsb);
+	ASSERT3S(error, <=, 0);
+
+	return (error);
+}
+
+/*
+ * The '.zfs/shares' directory file operations.
+ */
+const struct file_operations zpl_fops_shares = {
+	.open		= zpl_common_open,
+	.llseek		= generic_file_llseek,
+	.read		= generic_read_dir,
+#ifdef HAVE_VFS_ITERATE
+	.iterate	= zpl_shares_iterate,
+#else
+	.readdir	= zpl_shares_readdir,
+#endif
+
+};
+
+/*
+ * The '.zfs/shares' directory inode operations.
+ */
+const struct inode_operations zpl_ops_shares = {
+	.lookup		= zpl_shares_lookup,
+	.getattr	= zpl_shares_getattr,
+};
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/module/zfs/zpl_export.c
@@ -0,0 +1,176 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2011 Gunnar Beutner
+ * Copyright (c) 2012 Cyril Plisko. All rights reserved.
+ */
+
+
+#include <sys/zfs_vnops.h>
+#include <sys/zfs_znode.h>
+#include <sys/zfs_ctldir.h>
+#include <sys/zpl.h>
+
+
+static int
+#ifdef HAVE_ENCODE_FH_WITH_INODE
+zpl_encode_fh(struct inode *ip, __u32 *fh, int *max_len, struct inode *parent)
+{
+#else
+zpl_encode_fh(struct dentry *dentry, __u32 *fh, int *max_len, int connectable)
+{
+	struct inode *ip = dentry->d_inode;
+#endif /* HAVE_ENCODE_FH_WITH_INODE */
+	fstrans_cookie_t cookie;
+	fid_t *fid = (fid_t *)fh;
+	int len_bytes, rc;
+
+	len_bytes = *max_len * sizeof (__u32);
+
+	if (len_bytes < offsetof(fid_t, fid_data))
+		return (255);
+
+	fid->fid_len = len_bytes - offsetof(fid_t, fid_data);
+	cookie = spl_fstrans_mark();
+
+	if (zfsctl_is_node(ip))
+		rc = zfsctl_fid(ip, fid);
+	else
+		rc = zfs_fid(ip, fid);
+
+	spl_fstrans_unmark(cookie);
+	len_bytes = offsetof(fid_t, fid_data) + fid->fid_len;
+	*max_len = roundup(len_bytes, sizeof (__u32)) / sizeof (__u32);
+
+	return (rc == 0 ? FILEID_INO32_GEN : 255);
+}
+
+static struct dentry *
+zpl_dentry_obtain_alias(struct inode *ip)
+{
+	struct dentry *result;
+
+#ifdef HAVE_D_OBTAIN_ALIAS
+	result = d_obtain_alias(ip);
+#else
+	result = d_alloc_anon(ip);
+
+	if (result == NULL) {
+		iput(ip);
+		result = ERR_PTR(-ENOMEM);
+	}
+#endif /* HAVE_D_OBTAIN_ALIAS */
+
+	return (result);
+}
+
+static struct dentry *
+zpl_fh_to_dentry(struct super_block *sb, struct fid *fh,
+    int fh_len, int fh_type)
+{
+	fid_t *fid = (fid_t *)fh;
+	fstrans_cookie_t cookie;
+	struct inode *ip;
+	int len_bytes, rc;
+
+	len_bytes = fh_len * sizeof (__u32);
+
+	if (fh_type != FILEID_INO32_GEN ||
+	    len_bytes < offsetof(fid_t, fid_data) ||
+	    len_bytes < offsetof(fid_t, fid_data) + fid->fid_len)
+		return (ERR_PTR(-EINVAL));
+
+	cookie = spl_fstrans_mark();
+	rc = zfs_vget(sb, &ip, fid);
+	spl_fstrans_unmark(cookie);
+
+	if (rc) {
+		/*
+		 * If we see ENOENT it might mean that an NFSv4 * client
+		 * is using a cached inode value in a file handle and
+		 * that the sought after file has had its inode changed
+		 * by a third party.  So change the error to ESTALE
+		 * which will trigger a full lookup by the client and
+		 * will find the new filename/inode pair if it still
+		 * exists.
+		 */
+		if (rc == ENOENT)
+			rc = ESTALE;
+
+		return (ERR_PTR(-rc));
+	}
+
+	ASSERT((ip != NULL) && !IS_ERR(ip));
+
+	return (zpl_dentry_obtain_alias(ip));
+}
+
+static struct dentry *
+zpl_get_parent(struct dentry *child)
+{
+	cred_t *cr = CRED();
+	fstrans_cookie_t cookie;
+	struct inode *ip;
+	int error;
+
+	crhold(cr);
+	cookie = spl_fstrans_mark();
+	error = -zfs_lookup(child->d_inode, "..", &ip, 0, cr, NULL, NULL);
+	spl_fstrans_unmark(cookie);
+	crfree(cr);
+	ASSERT3S(error, <=, 0);
+
+	if (error)
+		return (ERR_PTR(error));
+
+	return (zpl_dentry_obtain_alias(ip));
+}
+
+#ifdef HAVE_COMMIT_METADATA
+static int
+zpl_commit_metadata(struct inode *inode)
+{
+	cred_t *cr = CRED();
+	fstrans_cookie_t cookie;
+	int error;
+
+	if (zfsctl_is_node(inode))
+		return (0);
+
+	crhold(cr);
+	cookie = spl_fstrans_mark();
+	error = -zfs_fsync(inode, 0, cr);
+	spl_fstrans_unmark(cookie);
+	crfree(cr);
+	ASSERT3S(error, <=, 0);
+
+	return (error);
+}
+#endif /* HAVE_COMMIT_METADATA */
+
+const struct export_operations zpl_export_operations = {
+	.encode_fh		= zpl_encode_fh,
+	.fh_to_dentry		= zpl_fh_to_dentry,
+	.get_parent		= zpl_get_parent,
+#ifdef HAVE_COMMIT_METADATA
+	.commit_metadata	= zpl_commit_metadata,
+#endif /* HAVE_COMMIT_METADATA */
+};
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/module/zfs/zpl_file.c
@@ -0,0 +1,864 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2011, Lawrence Livermore National Security, LLC.
+ * Copyright (c) 2015 by Chunwei Chen. All rights reserved.
+ */
+
+
+#ifdef CONFIG_COMPAT
+#include <linux/compat.h>
+#endif
+#include <sys/dmu_objset.h>
+#include <sys/zfs_vfsops.h>
+#include <sys/zfs_vnops.h>
+#include <sys/zfs_znode.h>
+#include <sys/zpl.h>
+
+
+static int
+zpl_open(struct inode *ip, struct file *filp)
+{
+	cred_t *cr = CRED();
+	int error;
+	fstrans_cookie_t cookie;
+
+	error = generic_file_open(ip, filp);
+	if (error)
+		return (error);
+
+	crhold(cr);
+	cookie = spl_fstrans_mark();
+	error = -zfs_open(ip, filp->f_mode, filp->f_flags, cr);
+	spl_fstrans_unmark(cookie);
+	crfree(cr);
+	ASSERT3S(error, <=, 0);
+
+	return (error);
+}
+
+static int
+zpl_release(struct inode *ip, struct file *filp)
+{
+	cred_t *cr = CRED();
+	int error;
+	fstrans_cookie_t cookie;
+
+	cookie = spl_fstrans_mark();
+	if (ITOZ(ip)->z_atime_dirty)
+		zfs_mark_inode_dirty(ip);
+
+	crhold(cr);
+	error = -zfs_close(ip, filp->f_flags, cr);
+	spl_fstrans_unmark(cookie);
+	crfree(cr);
+	ASSERT3S(error, <=, 0);
+
+	return (error);
+}
+
+static int
+zpl_iterate(struct file *filp, struct dir_context *ctx)
+{
+	struct dentry *dentry = filp->f_path.dentry;
+	cred_t *cr = CRED();
+	int error;
+	fstrans_cookie_t cookie;
+
+	crhold(cr);
+	cookie = spl_fstrans_mark();
+	error = -zfs_readdir(dentry->d_inode, ctx, cr);
+	spl_fstrans_unmark(cookie);
+	crfree(cr);
+	ASSERT3S(error, <=, 0);
+
+	return (error);
+}
+
+#if !defined(HAVE_VFS_ITERATE)
+static int
+zpl_readdir(struct file *filp, void *dirent, filldir_t filldir)
+{
+	struct dir_context ctx = DIR_CONTEXT_INIT(dirent, filldir, filp->f_pos);
+	int error;
+
+	error = zpl_iterate(filp, &ctx);
+	filp->f_pos = ctx.pos;
+
+	return (error);
+}
+#endif /* HAVE_VFS_ITERATE */
+
+#if defined(HAVE_FSYNC_WITH_DENTRY)
+/*
+ * Linux 2.6.x - 2.6.34 API,
+ * Through 2.6.34 the nfsd kernel server would pass a NULL 'file struct *'
+ * to the fops->fsync() hook.  For this reason, we must be careful not to
+ * use filp unconditionally.
+ */
+static int
+zpl_fsync(struct file *filp, struct dentry *dentry, int datasync)
+{
+	cred_t *cr = CRED();
+	int error;
+	fstrans_cookie_t cookie;
+
+	crhold(cr);
+	cookie = spl_fstrans_mark();
+	error = -zfs_fsync(dentry->d_inode, datasync, cr);
+	spl_fstrans_unmark(cookie);
+	crfree(cr);
+	ASSERT3S(error, <=, 0);
+
+	return (error);
+}
+
+static int
+zpl_aio_fsync(struct kiocb *kiocb, int datasync)
+{
+	struct file *filp = kiocb->ki_filp;
+	return (zpl_fsync(filp, filp->f_path.dentry, datasync));
+}
+#elif defined(HAVE_FSYNC_WITHOUT_DENTRY)
+/*
+ * Linux 2.6.35 - 3.0 API,
+ * As of 2.6.35 the dentry argument to the fops->fsync() hook was deemed
+ * redundant.  The dentry is still accessible via filp->f_path.dentry,
+ * and we are guaranteed that filp will never be NULL.
+ */
+static int
+zpl_fsync(struct file *filp, int datasync)
+{
+	struct inode *inode = filp->f_mapping->host;
+	cred_t *cr = CRED();
+	int error;
+	fstrans_cookie_t cookie;
+
+	crhold(cr);
+	cookie = spl_fstrans_mark();
+	error = -zfs_fsync(inode, datasync, cr);
+	spl_fstrans_unmark(cookie);
+	crfree(cr);
+	ASSERT3S(error, <=, 0);
+
+	return (error);
+}
+
+static int
+zpl_aio_fsync(struct kiocb *kiocb, int datasync)
+{
+	return (zpl_fsync(kiocb->ki_filp, datasync));
+}
+#elif defined(HAVE_FSYNC_RANGE)
+/*
+ * Linux 3.1 - 3.x API,
+ * As of 3.1 the responsibility to call filemap_write_and_wait_range() has
+ * been pushed down in to the .fsync() vfs hook.  Additionally, the i_mutex
+ * lock is no longer held by the caller, for zfs we don't require the lock
+ * to be held so we don't acquire it.
+ */
+static int
+zpl_fsync(struct file *filp, loff_t start, loff_t end, int datasync)
+{
+	struct inode *inode = filp->f_mapping->host;
+	cred_t *cr = CRED();
+	int error;
+	fstrans_cookie_t cookie;
+
+	error = filemap_write_and_wait_range(inode->i_mapping, start, end);
+	if (error)
+		return (error);
+
+	crhold(cr);
+	cookie = spl_fstrans_mark();
+	error = -zfs_fsync(inode, datasync, cr);
+	spl_fstrans_unmark(cookie);
+	crfree(cr);
+	ASSERT3S(error, <=, 0);
+
+	return (error);
+}
+
+static int
+zpl_aio_fsync(struct kiocb *kiocb, int datasync)
+{
+	return (zpl_fsync(kiocb->ki_filp, kiocb->ki_pos, -1, datasync));
+}
+#else
+#error "Unsupported fops->fsync() implementation"
+#endif
+
+static ssize_t
+zpl_read_common_iovec(struct inode *ip, const struct iovec *iovp, size_t count,
+    unsigned long nr_segs, loff_t *ppos, uio_seg_t segment, int flags,
+    cred_t *cr, size_t skip)
+{
+	ssize_t read;
+	uio_t uio;
+	int error;
+	fstrans_cookie_t cookie;
+
+	uio.uio_iov = iovp;
+	uio.uio_skip = skip;
+	uio.uio_resid = count;
+	uio.uio_iovcnt = nr_segs;
+	uio.uio_loffset = *ppos;
+	uio.uio_limit = MAXOFFSET_T;
+	uio.uio_segflg = segment;
+
+	cookie = spl_fstrans_mark();
+	error = -zfs_read(ip, &uio, flags, cr);
+	spl_fstrans_unmark(cookie);
+	if (error < 0)
+		return (error);
+
+	read = count - uio.uio_resid;
+	*ppos += read;
+	task_io_account_read(read);
+
+	return (read);
+}
+
+inline ssize_t
+zpl_read_common(struct inode *ip, const char *buf, size_t len, loff_t *ppos,
+    uio_seg_t segment, int flags, cred_t *cr)
+{
+	struct iovec iov;
+
+	iov.iov_base = (void *)buf;
+	iov.iov_len = len;
+
+	return (zpl_read_common_iovec(ip, &iov, len, 1, ppos, segment,
+	    flags, cr, 0));
+}
+
+static ssize_t
+zpl_read(struct file *filp, char __user *buf, size_t len, loff_t *ppos)
+{
+	cred_t *cr = CRED();
+	ssize_t read;
+
+	crhold(cr);
+	read = zpl_read_common(filp->f_mapping->host, buf, len, ppos,
+	    UIO_USERSPACE, filp->f_flags, cr);
+	crfree(cr);
+
+	return (read);
+}
+
+static ssize_t
+zpl_iter_read_common(struct kiocb *kiocb, const struct iovec *iovp,
+    unsigned long nr_segs, size_t count, uio_seg_t seg, size_t skip)
+{
+	cred_t *cr = CRED();
+	struct file *filp = kiocb->ki_filp;
+	ssize_t read;
+
+	crhold(cr);
+	read = zpl_read_common_iovec(filp->f_mapping->host, iovp, count,
+	    nr_segs, &kiocb->ki_pos, seg, filp->f_flags, cr, skip);
+	crfree(cr);
+
+	return (read);
+}
+
+#if defined(HAVE_VFS_RW_ITERATE)
+static ssize_t
+zpl_iter_read(struct kiocb *kiocb, struct iov_iter *to)
+{
+	ssize_t ret;
+	uio_seg_t seg = UIO_USERSPACE;
+	if (to->type & ITER_KVEC)
+		seg = UIO_SYSSPACE;
+	if (to->type & ITER_BVEC)
+		seg = UIO_BVEC;
+	ret = zpl_iter_read_common(kiocb, to->iov, to->nr_segs,
+	    iov_iter_count(to), seg, to->iov_offset);
+	if (ret > 0)
+		iov_iter_advance(to, ret);
+	return (ret);
+}
+#else
+static ssize_t
+zpl_aio_read(struct kiocb *kiocb, const struct iovec *iovp,
+    unsigned long nr_segs, loff_t pos)
+{
+	return (zpl_iter_read_common(kiocb, iovp, nr_segs, kiocb->ki_nbytes,
+	    UIO_USERSPACE, 0));
+}
+#endif /* HAVE_VFS_RW_ITERATE */
+
+static ssize_t
+zpl_write_common_iovec(struct inode *ip, const struct iovec *iovp, size_t count,
+    unsigned long nr_segs, loff_t *ppos, uio_seg_t segment, int flags,
+    cred_t *cr, size_t skip)
+{
+	ssize_t wrote;
+	uio_t uio;
+	int error;
+	fstrans_cookie_t cookie;
+
+	if (flags & O_APPEND)
+		*ppos = i_size_read(ip);
+
+	uio.uio_iov = iovp;
+	uio.uio_skip = skip;
+	uio.uio_resid = count;
+	uio.uio_iovcnt = nr_segs;
+	uio.uio_loffset = *ppos;
+	uio.uio_limit = MAXOFFSET_T;
+	uio.uio_segflg = segment;
+
+	cookie = spl_fstrans_mark();
+	error = -zfs_write(ip, &uio, flags, cr);
+	spl_fstrans_unmark(cookie);
+	if (error < 0)
+		return (error);
+
+	wrote = count - uio.uio_resid;
+	*ppos += wrote;
+	task_io_account_write(wrote);
+
+	return (wrote);
+}
+inline ssize_t
+zpl_write_common(struct inode *ip, const char *buf, size_t len, loff_t *ppos,
+    uio_seg_t segment, int flags, cred_t *cr)
+{
+	struct iovec iov;
+
+	iov.iov_base = (void *)buf;
+	iov.iov_len = len;
+
+	return (zpl_write_common_iovec(ip, &iov, len, 1, ppos, segment,
+	    flags, cr, 0));
+}
+
+static ssize_t
+zpl_write(struct file *filp, const char __user *buf, size_t len, loff_t *ppos)
+{
+	cred_t *cr = CRED();
+	ssize_t wrote;
+
+	crhold(cr);
+	wrote = zpl_write_common(filp->f_mapping->host, buf, len, ppos,
+	    UIO_USERSPACE, filp->f_flags, cr);
+	crfree(cr);
+
+	return (wrote);
+}
+
+static ssize_t
+zpl_iter_write_common(struct kiocb *kiocb, const struct iovec *iovp,
+    unsigned long nr_segs, size_t count, uio_seg_t seg, size_t skip)
+{
+	cred_t *cr = CRED();
+	struct file *filp = kiocb->ki_filp;
+	ssize_t wrote;
+
+	crhold(cr);
+	wrote = zpl_write_common_iovec(filp->f_mapping->host, iovp, count,
+	    nr_segs, &kiocb->ki_pos, seg, filp->f_flags, cr, skip);
+	crfree(cr);
+
+	return (wrote);
+}
+
+#if defined(HAVE_VFS_RW_ITERATE)
+static ssize_t
+zpl_iter_write(struct kiocb *kiocb, struct iov_iter *from)
+{
+	ssize_t ret;
+	uio_seg_t seg = UIO_USERSPACE;
+	if (from->type & ITER_KVEC)
+		seg = UIO_SYSSPACE;
+	if (from->type & ITER_BVEC)
+		seg = UIO_BVEC;
+	ret = zpl_iter_write_common(kiocb, from->iov, from->nr_segs,
+	    iov_iter_count(from), seg, from->iov_offset);
+	if (ret > 0)
+		iov_iter_advance(from, ret);
+	return (ret);
+}
+#else
+static ssize_t
+zpl_aio_write(struct kiocb *kiocb, const struct iovec *iovp,
+    unsigned long nr_segs, loff_t pos)
+{
+	return (zpl_iter_write_common(kiocb, iovp, nr_segs, kiocb->ki_nbytes,
+	    UIO_USERSPACE, 0));
+}
+#endif /* HAVE_VFS_RW_ITERATE */
+
+static loff_t
+zpl_llseek(struct file *filp, loff_t offset, int whence)
+{
+#if defined(SEEK_HOLE) && defined(SEEK_DATA)
+	fstrans_cookie_t cookie;
+
+	if (whence == SEEK_DATA || whence == SEEK_HOLE) {
+		struct inode *ip = filp->f_mapping->host;
+		loff_t maxbytes = ip->i_sb->s_maxbytes;
+		loff_t error;
+
+		spl_inode_lock(ip);
+		cookie = spl_fstrans_mark();
+		error = -zfs_holey(ip, whence, &offset);
+		spl_fstrans_unmark(cookie);
+		if (error == 0)
+			error = lseek_execute(filp, ip, offset, maxbytes);
+		spl_inode_unlock(ip);
+
+		return (error);
+	}
+#endif /* SEEK_HOLE && SEEK_DATA */
+
+	return (generic_file_llseek(filp, offset, whence));
+}
+
+/*
+ * It's worth taking a moment to describe how mmap is implemented
+ * for zfs because it differs considerably from other Linux filesystems.
+ * However, this issue is handled the same way under OpenSolaris.
+ *
+ * The issue is that by design zfs bypasses the Linux page cache and
+ * leaves all caching up to the ARC.  This has been shown to work
+ * well for the common read(2)/write(2) case.  However, mmap(2)
+ * is problem because it relies on being tightly integrated with the
+ * page cache.  To handle this we cache mmap'ed files twice, once in
+ * the ARC and a second time in the page cache.  The code is careful
+ * to keep both copies synchronized.
+ *
+ * When a file with an mmap'ed region is written to using write(2)
+ * both the data in the ARC and existing pages in the page cache
+ * are updated.  For a read(2) data will be read first from the page
+ * cache then the ARC if needed.  Neither a write(2) or read(2) will
+ * will ever result in new pages being added to the page cache.
+ *
+ * New pages are added to the page cache only via .readpage() which
+ * is called when the vfs needs to read a page off disk to back the
+ * virtual memory region.  These pages may be modified without
+ * notifying the ARC and will be written out periodically via
+ * .writepage().  This will occur due to either a sync or the usual
+ * page aging behavior.  Note because a read(2) of a mmap'ed file
+ * will always check the page cache first even when the ARC is out
+ * of date correct data will still be returned.
+ *
+ * While this implementation ensures correct behavior it does have
+ * have some drawbacks.  The most obvious of which is that it
+ * increases the required memory footprint when access mmap'ed
+ * files.  It also adds additional complexity to the code keeping
+ * both caches synchronized.
+ *
+ * Longer term it may be possible to cleanly resolve this wart by
+ * mapping page cache pages directly on to the ARC buffers.  The
+ * Linux address space operations are flexible enough to allow
+ * selection of which pages back a particular index.  The trick
+ * would be working out the details of which subsystem is in
+ * charge, the ARC, the page cache, or both.  It may also prove
+ * helpful to move the ARC buffers to a scatter-gather lists
+ * rather than a vmalloc'ed region.
+ */
+static int
+zpl_mmap(struct file *filp, struct vm_area_struct *vma)
+{
+	struct inode *ip = filp->f_mapping->host;
+	znode_t *zp = ITOZ(ip);
+	int error;
+	fstrans_cookie_t cookie;
+
+	cookie = spl_fstrans_mark();
+	error = -zfs_map(ip, vma->vm_pgoff, (caddr_t *)vma->vm_start,
+	    (size_t)(vma->vm_end - vma->vm_start), vma->vm_flags);
+	spl_fstrans_unmark(cookie);
+	if (error)
+		return (error);
+
+	error = generic_file_mmap(filp, vma);
+	if (error)
+		return (error);
+
+	mutex_enter(&zp->z_lock);
+	zp->z_is_mapped = 1;
+	mutex_exit(&zp->z_lock);
+
+	return (error);
+}
+
+/*
+ * Populate a page with data for the Linux page cache.  This function is
+ * only used to support mmap(2).  There will be an identical copy of the
+ * data in the ARC which is kept up to date via .write() and .writepage().
+ *
+ * Current this function relies on zpl_read_common() and the O_DIRECT
+ * flag to read in a page.  This works but the more correct way is to
+ * update zfs_fillpage() to be Linux friendly and use that interface.
+ */
+static int
+zpl_readpage(struct file *filp, struct page *pp)
+{
+	struct inode *ip;
+	struct page *pl[1];
+	int error = 0;
+	fstrans_cookie_t cookie;
+
+	ASSERT(PageLocked(pp));
+	ip = pp->mapping->host;
+	pl[0] = pp;
+
+	cookie = spl_fstrans_mark();
+	error = -zfs_getpage(ip, pl, 1);
+	spl_fstrans_unmark(cookie);
+
+	if (error) {
+		SetPageError(pp);
+		ClearPageUptodate(pp);
+	} else {
+		ClearPageError(pp);
+		SetPageUptodate(pp);
+		flush_dcache_page(pp);
+	}
+
+	unlock_page(pp);
+	return (error);
+}
+
+/*
+ * Populate a set of pages with data for the Linux page cache.  This
+ * function will only be called for read ahead and never for demand
+ * paging.  For simplicity, the code relies on read_cache_pages() to
+ * correctly lock each page for IO and call zpl_readpage().
+ */
+static int
+zpl_readpages(struct file *filp, struct address_space *mapping,
+	struct list_head *pages, unsigned nr_pages)
+{
+	return (read_cache_pages(mapping, pages,
+	    (filler_t *)zpl_readpage, filp));
+}
+
+int
+zpl_putpage(struct page *pp, struct writeback_control *wbc, void *data)
+{
+	struct address_space *mapping = data;
+	fstrans_cookie_t cookie;
+
+	ASSERT(PageLocked(pp));
+	ASSERT(!PageWriteback(pp));
+
+	cookie = spl_fstrans_mark();
+	(void) zfs_putpage(mapping->host, pp, wbc);
+	spl_fstrans_unmark(cookie);
+
+	return (0);
+}
+
+static int
+zpl_writepages(struct address_space *mapping, struct writeback_control *wbc)
+{
+	znode_t		*zp = ITOZ(mapping->host);
+	zfs_sb_t	*zsb = ITOZSB(mapping->host);
+	enum writeback_sync_modes sync_mode;
+	int result;
+
+	ZFS_ENTER(zsb);
+	if (zsb->z_os->os_sync == ZFS_SYNC_ALWAYS)
+		wbc->sync_mode = WB_SYNC_ALL;
+	ZFS_EXIT(zsb);
+	sync_mode = wbc->sync_mode;
+
+	/*
+	 * We don't want to run write_cache_pages() in SYNC mode here, because
+	 * that would make putpage() wait for a single page to be committed to
+	 * disk every single time, resulting in atrocious performance. Instead
+	 * we run it once in non-SYNC mode so that the ZIL gets all the data,
+	 * and then we commit it all in one go.
+	 */
+	wbc->sync_mode = WB_SYNC_NONE;
+	result = write_cache_pages(mapping, wbc, zpl_putpage, mapping);
+	if (sync_mode != wbc->sync_mode) {
+		ZFS_ENTER(zsb);
+		ZFS_VERIFY_ZP(zp);
+		if (zsb->z_log != NULL)
+			zil_commit(zsb->z_log, zp->z_id);
+		ZFS_EXIT(zsb);
+
+		/*
+		 * We need to call write_cache_pages() again (we can't just
+		 * return after the commit) because the previous call in
+		 * non-SYNC mode does not guarantee that we got all the dirty
+		 * pages (see the implementation of write_cache_pages() for
+		 * details). That being said, this is a no-op in most cases.
+		 */
+		wbc->sync_mode = sync_mode;
+		result = write_cache_pages(mapping, wbc, zpl_putpage, mapping);
+	}
+	return (result);
+}
+
+/*
+ * Write out dirty pages to the ARC, this function is only required to
+ * support mmap(2).  Mapped pages may be dirtied by memory operations
+ * which never call .write().  These dirty pages are kept in sync with
+ * the ARC buffers via this hook.
+ */
+static int
+zpl_writepage(struct page *pp, struct writeback_control *wbc)
+{
+	if (ITOZSB(pp->mapping->host)->z_os->os_sync == ZFS_SYNC_ALWAYS)
+		wbc->sync_mode = WB_SYNC_ALL;
+
+	return (zpl_putpage(pp, wbc, pp->mapping));
+}
+
+/*
+ * The only flag combination which matches the behavior of zfs_space()
+ * is FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE.  The FALLOC_FL_PUNCH_HOLE
+ * flag was introduced in the 2.6.38 kernel.
+ */
+#if defined(HAVE_FILE_FALLOCATE) || defined(HAVE_INODE_FALLOCATE)
+long
+zpl_fallocate_common(struct inode *ip, int mode, loff_t offset, loff_t len)
+{
+	int error = -EOPNOTSUPP;
+
+#if defined(FALLOC_FL_PUNCH_HOLE) && defined(FALLOC_FL_KEEP_SIZE)
+	cred_t *cr = CRED();
+	flock64_t bf;
+	loff_t olen;
+	fstrans_cookie_t cookie;
+
+	if (mode != (FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE))
+		return (error);
+
+	crhold(cr);
+
+	if (offset < 0 || len <= 0)
+		return (-EINVAL);
+
+	spl_inode_lock(ip);
+	olen = i_size_read(ip);
+
+	if (offset > olen) {
+		spl_inode_unlock(ip);
+		return (0);
+	}
+	if (offset + len > olen)
+		len = olen - offset;
+	bf.l_type = F_WRLCK;
+	bf.l_whence = 0;
+	bf.l_start = offset;
+	bf.l_len = len;
+	bf.l_pid = 0;
+
+	cookie = spl_fstrans_mark();
+	error = -zfs_space(ip, F_FREESP, &bf, FWRITE, offset, cr);
+	spl_fstrans_unmark(cookie);
+	spl_inode_unlock(ip);
+
+	crfree(cr);
+#endif /* defined(FALLOC_FL_PUNCH_HOLE) && defined(FALLOC_FL_KEEP_SIZE) */
+
+	ASSERT3S(error, <=, 0);
+	return (error);
+}
+#endif /* defined(HAVE_FILE_FALLOCATE) || defined(HAVE_INODE_FALLOCATE) */
+
+#ifdef HAVE_FILE_FALLOCATE
+static long
+zpl_fallocate(struct file *filp, int mode, loff_t offset, loff_t len)
+{
+	return zpl_fallocate_common(filp->f_path.dentry->d_inode,
+	    mode, offset, len);
+}
+#endif /* HAVE_FILE_FALLOCATE */
+
+/*
+ * Map zfs file z_pflags (xvattr_t) to linux file attributes. Only file
+ * attributes common to both Linux and Solaris are mapped.
+ */
+static int
+zpl_ioctl_getflags(struct file *filp, void __user *arg)
+{
+	struct inode *ip = file_inode(filp);
+	unsigned int ioctl_flags = 0;
+	uint64_t zfs_flags = ITOZ(ip)->z_pflags;
+	int error;
+
+	if (zfs_flags & ZFS_IMMUTABLE)
+		ioctl_flags |= FS_IMMUTABLE_FL;
+
+	if (zfs_flags & ZFS_APPENDONLY)
+		ioctl_flags |= FS_APPEND_FL;
+
+	if (zfs_flags & ZFS_NODUMP)
+		ioctl_flags |= FS_NODUMP_FL;
+
+	ioctl_flags &= FS_FL_USER_VISIBLE;
+
+	error = copy_to_user(arg, &ioctl_flags, sizeof (ioctl_flags));
+
+	return (error);
+}
+
+/*
+ * fchange() is a helper macro to detect if we have been asked to change a
+ * flag. This is ugly, but the requirement that we do this is a consequence of
+ * how the Linux file attribute interface was designed. Another consequence is
+ * that concurrent modification of files suffers from a TOCTOU race. Neither
+ * are things we can fix without modifying the kernel-userland interface, which
+ * is outside of our jurisdiction.
+ */
+
+#define	fchange(f0, f1, b0, b1) ((((f0) & (b0)) == (b0)) != \
+	(((b1) & (f1)) == (f1)))
+
+static int
+zpl_ioctl_setflags(struct file *filp, void __user *arg)
+{
+	struct inode	*ip = file_inode(filp);
+	uint64_t	zfs_flags = ITOZ(ip)->z_pflags;
+	unsigned int	ioctl_flags;
+	cred_t		*cr = CRED();
+	xvattr_t	xva;
+	xoptattr_t	*xoap;
+	int		error;
+	fstrans_cookie_t cookie;
+
+	if (copy_from_user(&ioctl_flags, arg, sizeof (ioctl_flags)))
+		return (-EFAULT);
+
+	if ((ioctl_flags & ~(FS_IMMUTABLE_FL | FS_APPEND_FL | FS_NODUMP_FL)))
+		return (-EOPNOTSUPP);
+
+	if ((ioctl_flags & ~(FS_FL_USER_MODIFIABLE)))
+		return (-EACCES);
+
+	if ((fchange(ioctl_flags, zfs_flags, FS_IMMUTABLE_FL, ZFS_IMMUTABLE) ||
+	    fchange(ioctl_flags, zfs_flags, FS_APPEND_FL, ZFS_APPENDONLY)) &&
+	    !capable(CAP_LINUX_IMMUTABLE))
+		return (-EACCES);
+
+	if (!zpl_inode_owner_or_capable(ip))
+		return (-EACCES);
+
+	xva_init(&xva);
+	xoap = xva_getxoptattr(&xva);
+
+	XVA_SET_REQ(&xva, XAT_IMMUTABLE);
+	if (ioctl_flags & FS_IMMUTABLE_FL)
+		xoap->xoa_immutable = B_TRUE;
+
+	XVA_SET_REQ(&xva, XAT_APPENDONLY);
+	if (ioctl_flags & FS_APPEND_FL)
+		xoap->xoa_appendonly = B_TRUE;
+
+	XVA_SET_REQ(&xva, XAT_NODUMP);
+	if (ioctl_flags & FS_NODUMP_FL)
+		xoap->xoa_nodump = B_TRUE;
+
+	crhold(cr);
+	cookie = spl_fstrans_mark();
+	error = -zfs_setattr(ip, (vattr_t *)&xva, 0, cr);
+	spl_fstrans_unmark(cookie);
+	crfree(cr);
+
+	return (error);
+}
+
+static long
+zpl_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
+{
+	switch (cmd) {
+	case FS_IOC_GETFLAGS:
+		return (zpl_ioctl_getflags(filp, (void *)arg));
+	case FS_IOC_SETFLAGS:
+		return (zpl_ioctl_setflags(filp, (void *)arg));
+	default:
+		return (-ENOTTY);
+	}
+}
+
+#ifdef CONFIG_COMPAT
+static long
+zpl_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
+{
+	switch (cmd) {
+	case FS_IOC32_GETFLAGS:
+		cmd = FS_IOC_GETFLAGS;
+		break;
+	case FS_IOC32_SETFLAGS:
+		cmd = FS_IOC_SETFLAGS;
+		break;
+	default:
+		return (-ENOTTY);
+	}
+	return (zpl_ioctl(filp, cmd, (unsigned long)compat_ptr(arg)));
+}
+#endif /* CONFIG_COMPAT */
+
+
+const struct address_space_operations zpl_address_space_operations = {
+	.readpages	= zpl_readpages,
+	.readpage	= zpl_readpage,
+	.writepage	= zpl_writepage,
+	.writepages	= zpl_writepages,
+};
+
+const struct file_operations zpl_file_operations = {
+	.open		= zpl_open,
+	.release	= zpl_release,
+	.llseek		= zpl_llseek,
+	.read		= zpl_read,
+	.write		= zpl_write,
+#ifdef HAVE_VFS_RW_ITERATE
+	.read_iter	= zpl_iter_read,
+	.write_iter	= zpl_iter_write,
+#else
+	.aio_read	= zpl_aio_read,
+	.aio_write	= zpl_aio_write,
+#endif
+	.mmap		= zpl_mmap,
+	.fsync		= zpl_fsync,
+	.aio_fsync	= zpl_aio_fsync,
+#ifdef HAVE_FILE_FALLOCATE
+	.fallocate	= zpl_fallocate,
+#endif /* HAVE_FILE_FALLOCATE */
+	.unlocked_ioctl	= zpl_ioctl,
+#ifdef CONFIG_COMPAT
+	.compat_ioctl	= zpl_compat_ioctl,
+#endif
+};
+
+const struct file_operations zpl_dir_file_operations = {
+	.llseek		= generic_file_llseek,
+	.read		= generic_read_dir,
+#ifdef HAVE_VFS_ITERATE
+	.iterate	= zpl_iterate,
+#else
+	.readdir	= zpl_readdir,
+#endif
+	.fsync		= zpl_fsync,
+	.unlocked_ioctl = zpl_ioctl,
+#ifdef CONFIG_COMPAT
+	.compat_ioctl   = zpl_compat_ioctl,
+#endif
+};
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/module/zfs/zpl_inode.c
@@ -0,0 +1,741 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2011, Lawrence Livermore National Security, LLC.
+ * Copyright (c) 2015 by Chunwei Chen. All rights reserved.
+ */
+
+
+#include <sys/zfs_ctldir.h>
+#include <sys/zfs_vfsops.h>
+#include <sys/zfs_vnops.h>
+#include <sys/zfs_znode.h>
+#include <sys/dmu_objset.h>
+#include <sys/vfs.h>
+#include <sys/zpl.h>
+#include <sys/file.h>
+
+
+static struct dentry *
+#ifdef HAVE_LOOKUP_NAMEIDATA
+zpl_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
+#else
+zpl_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags)
+#endif
+{
+	cred_t *cr = CRED();
+	struct inode *ip;
+	int error;
+	fstrans_cookie_t cookie;
+	pathname_t *ppn = NULL;
+	pathname_t pn;
+	int zfs_flags = 0;
+	zfs_sb_t *zsb = dentry->d_sb->s_fs_info;
+
+	if (dlen(dentry) > ZFS_MAXNAMELEN)
+		return (ERR_PTR(-ENAMETOOLONG));
+
+	crhold(cr);
+	cookie = spl_fstrans_mark();
+
+	/* If we are a case insensitive fs, we need the real name */
+	if (zsb->z_case == ZFS_CASE_INSENSITIVE) {
+		zfs_flags = FIGNORECASE;
+		pn.pn_bufsize = ZFS_MAXNAMELEN;
+		pn.pn_buf = kmem_zalloc(ZFS_MAXNAMELEN, KM_SLEEP);
+		ppn = &pn;
+	}
+
+	error = -zfs_lookup(dir, dname(dentry), &ip, zfs_flags, cr, NULL, ppn);
+	spl_fstrans_unmark(cookie);
+	ASSERT3S(error, <=, 0);
+	crfree(cr);
+
+	spin_lock(&dentry->d_lock);
+	dentry->d_time = jiffies;
+#ifndef HAVE_S_D_OP
+	d_set_d_op(dentry, &zpl_dentry_operations);
+#endif /* HAVE_S_D_OP */
+	spin_unlock(&dentry->d_lock);
+
+	if (error) {
+		/*
+		 * If we have a case sensitive fs, we do not want to
+		 * insert negative entries, so return NULL for ENOENT.
+		 * Fall through if the error is not ENOENT. Also free memory.
+		 */
+		if (ppn) {
+			kmem_free(pn.pn_buf, ZFS_MAXNAMELEN);
+			if (error == -ENOENT)
+				return (NULL);
+		}
+
+		if (error == -ENOENT)
+			return (d_splice_alias(NULL, dentry));
+		else
+			return (ERR_PTR(error));
+	}
+
+	/*
+	 * If we are case insensitive, call the correct function
+	 * to install the name.
+	 */
+	if (ppn) {
+		struct dentry *new_dentry;
+		struct qstr ci_name;
+
+		ci_name.name = pn.pn_buf;
+		ci_name.len = strlen(pn.pn_buf);
+		new_dentry = d_add_ci(dentry, ip, &ci_name);
+		kmem_free(pn.pn_buf, ZFS_MAXNAMELEN);
+		return (new_dentry);
+	} else {
+		return (d_splice_alias(ip, dentry));
+	}
+}
+
+void
+zpl_vap_init(vattr_t *vap, struct inode *dir, zpl_umode_t mode, cred_t *cr)
+{
+	vap->va_mask = ATTR_MODE;
+	vap->va_mode = mode;
+	vap->va_uid = crgetfsuid(cr);
+
+	if (dir && dir->i_mode & S_ISGID) {
+		vap->va_gid = KGID_TO_SGID(dir->i_gid);
+		if (S_ISDIR(mode))
+			vap->va_mode |= S_ISGID;
+	} else {
+		vap->va_gid = crgetfsgid(cr);
+	}
+}
+
+static int
+#ifdef HAVE_CREATE_NAMEIDATA
+zpl_create(struct inode *dir, struct dentry *dentry, zpl_umode_t mode,
+    struct nameidata *nd)
+#else
+zpl_create(struct inode *dir, struct dentry *dentry, zpl_umode_t mode,
+    bool flag)
+#endif
+{
+	cred_t *cr = CRED();
+	struct inode *ip;
+	vattr_t *vap;
+	int error;
+	fstrans_cookie_t cookie;
+
+	crhold(cr);
+	vap = kmem_zalloc(sizeof (vattr_t), KM_SLEEP);
+	zpl_vap_init(vap, dir, mode, cr);
+
+	cookie = spl_fstrans_mark();
+	error = -zfs_create(dir, dname(dentry), vap, 0, mode, &ip, cr, 0, NULL);
+	if (error == 0) {
+		d_instantiate(dentry, ip);
+
+		error = zpl_xattr_security_init(ip, dir, &dentry->d_name);
+		if (error == 0)
+			error = zpl_init_acl(ip, dir);
+
+		if (error)
+			(void) zfs_remove(dir, dname(dentry), cr);
+	}
+
+	spl_fstrans_unmark(cookie);
+	kmem_free(vap, sizeof (vattr_t));
+	crfree(cr);
+	ASSERT3S(error, <=, 0);
+
+	return (error);
+}
+
+static int
+zpl_mknod(struct inode *dir, struct dentry *dentry, zpl_umode_t mode,
+    dev_t rdev)
+{
+	cred_t *cr = CRED();
+	struct inode *ip;
+	vattr_t *vap;
+	int error;
+	fstrans_cookie_t cookie;
+
+	/*
+	 * We currently expect Linux to supply rdev=0 for all sockets
+	 * and fifos, but we want to know if this behavior ever changes.
+	 */
+	if (S_ISSOCK(mode) || S_ISFIFO(mode))
+		ASSERT(rdev == 0);
+
+	crhold(cr);
+	vap = kmem_zalloc(sizeof (vattr_t), KM_SLEEP);
+	zpl_vap_init(vap, dir, mode, cr);
+	vap->va_rdev = rdev;
+
+	cookie = spl_fstrans_mark();
+	error = -zfs_create(dir, dname(dentry), vap, 0, mode, &ip, cr, 0, NULL);
+	if (error == 0) {
+		d_instantiate(dentry, ip);
+
+		error = zpl_xattr_security_init(ip, dir, &dentry->d_name);
+		if (error == 0)
+			error = zpl_init_acl(ip, dir);
+
+		if (error)
+			(void) zfs_remove(dir, dname(dentry), cr);
+	}
+
+	spl_fstrans_unmark(cookie);
+	kmem_free(vap, sizeof (vattr_t));
+	crfree(cr);
+	ASSERT3S(error, <=, 0);
+
+	return (error);
+}
+
+static int
+zpl_unlink(struct inode *dir, struct dentry *dentry)
+{
+	cred_t *cr = CRED();
+	int error;
+	fstrans_cookie_t cookie;
+	zfs_sb_t *zsb = dentry->d_sb->s_fs_info;
+
+	crhold(cr);
+	cookie = spl_fstrans_mark();
+	error = -zfs_remove(dir, dname(dentry), cr);
+
+	/*
+	 * For a CI FS we must invalidate the dentry to prevent the
+	 * creation of negative entries.
+	 */
+	if (error == 0 && zsb->z_case == ZFS_CASE_INSENSITIVE)
+		d_invalidate(dentry);
+
+	spl_fstrans_unmark(cookie);
+	crfree(cr);
+	ASSERT3S(error, <=, 0);
+
+	return (error);
+}
+
+static int
+zpl_mkdir(struct inode *dir, struct dentry *dentry, zpl_umode_t mode)
+{
+	cred_t *cr = CRED();
+	vattr_t *vap;
+	struct inode *ip;
+	int error;
+	fstrans_cookie_t cookie;
+
+	crhold(cr);
+	vap = kmem_zalloc(sizeof (vattr_t), KM_SLEEP);
+	zpl_vap_init(vap, dir, mode | S_IFDIR, cr);
+
+	cookie = spl_fstrans_mark();
+	error = -zfs_mkdir(dir, dname(dentry), vap, &ip, cr, 0, NULL);
+	if (error == 0) {
+		d_instantiate(dentry, ip);
+
+		error = zpl_xattr_security_init(ip, dir, &dentry->d_name);
+		if (error == 0)
+			error = zpl_init_acl(ip, dir);
+
+		if (error)
+			(void) zfs_rmdir(dir, dname(dentry), NULL, cr, 0);
+	}
+
+	spl_fstrans_unmark(cookie);
+	kmem_free(vap, sizeof (vattr_t));
+	crfree(cr);
+	ASSERT3S(error, <=, 0);
+
+	return (error);
+}
+
+static int
+zpl_rmdir(struct inode * dir, struct dentry *dentry)
+{
+	cred_t *cr = CRED();
+	int error;
+	fstrans_cookie_t cookie;
+	zfs_sb_t *zsb = dentry->d_sb->s_fs_info;
+
+	crhold(cr);
+	cookie = spl_fstrans_mark();
+	error = -zfs_rmdir(dir, dname(dentry), NULL, cr, 0);
+
+	/*
+	 * For a CI FS we must invalidate the dentry to prevent the
+	 * creation of negative entries.
+	 */
+	if (error == 0 && zsb->z_case == ZFS_CASE_INSENSITIVE)
+		d_invalidate(dentry);
+
+	spl_fstrans_unmark(cookie);
+	crfree(cr);
+	ASSERT3S(error, <=, 0);
+
+	return (error);
+}
+
+static int
+zpl_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
+{
+	int error;
+	fstrans_cookie_t cookie;
+
+	cookie = spl_fstrans_mark();
+	error = -zfs_getattr_fast(dentry->d_inode, stat);
+	spl_fstrans_unmark(cookie);
+	ASSERT3S(error, <=, 0);
+
+	return (error);
+}
+
+static int
+zpl_setattr(struct dentry *dentry, struct iattr *ia)
+{
+	struct inode *ip = dentry->d_inode;
+	cred_t *cr = CRED();
+	vattr_t *vap;
+	int error;
+	fstrans_cookie_t cookie;
+
+	error = inode_change_ok(ip, ia);
+	if (error)
+		return (error);
+
+	crhold(cr);
+	vap = kmem_zalloc(sizeof (vattr_t), KM_SLEEP);
+	vap->va_mask = ia->ia_valid & ATTR_IATTR_MASK;
+	vap->va_mode = ia->ia_mode;
+	vap->va_uid = KUID_TO_SUID(ia->ia_uid);
+	vap->va_gid = KGID_TO_SGID(ia->ia_gid);
+	vap->va_size = ia->ia_size;
+	vap->va_atime = ia->ia_atime;
+	vap->va_mtime = ia->ia_mtime;
+	vap->va_ctime = ia->ia_ctime;
+
+	cookie = spl_fstrans_mark();
+	error = -zfs_setattr(ip, vap, 0, cr);
+	if (!error && (ia->ia_valid & ATTR_MODE))
+		error = zpl_chmod_acl(ip);
+
+	spl_fstrans_unmark(cookie);
+	kmem_free(vap, sizeof (vattr_t));
+	crfree(cr);
+	ASSERT3S(error, <=, 0);
+
+	return (error);
+}
+
+static int
+zpl_rename(struct inode *sdip, struct dentry *sdentry,
+    struct inode *tdip, struct dentry *tdentry)
+{
+	cred_t *cr = CRED();
+	int error;
+	fstrans_cookie_t cookie;
+
+	crhold(cr);
+	cookie = spl_fstrans_mark();
+	error = -zfs_rename(sdip, dname(sdentry), tdip, dname(tdentry), cr, 0);
+	spl_fstrans_unmark(cookie);
+	crfree(cr);
+	ASSERT3S(error, <=, 0);
+
+	return (error);
+}
+
+static int
+zpl_symlink(struct inode *dir, struct dentry *dentry, const char *name)
+{
+	cred_t *cr = CRED();
+	vattr_t *vap;
+	struct inode *ip;
+	int error;
+	fstrans_cookie_t cookie;
+
+	crhold(cr);
+	vap = kmem_zalloc(sizeof (vattr_t), KM_SLEEP);
+	zpl_vap_init(vap, dir, S_IFLNK | S_IRWXUGO, cr);
+
+	cookie = spl_fstrans_mark();
+	error = -zfs_symlink(dir, dname(dentry), vap, (char *)name, &ip, cr, 0);
+	if (error == 0) {
+		d_instantiate(dentry, ip);
+
+		error = zpl_xattr_security_init(ip, dir, &dentry->d_name);
+		if (error)
+			(void) zfs_remove(dir, dname(dentry), cr);
+	}
+
+	spl_fstrans_unmark(cookie);
+	kmem_free(vap, sizeof (vattr_t));
+	crfree(cr);
+	ASSERT3S(error, <=, 0);
+
+	return (error);
+}
+
+#if defined(HAVE_PUT_LINK_COOKIE)
+static void
+zpl_put_link(struct inode *unused, void *cookie)
+{
+	kmem_free(cookie, MAXPATHLEN);
+}
+#elif defined(HAVE_PUT_LINK_NAMEIDATA)
+static void
+zpl_put_link(struct dentry *dentry, struct nameidata *nd, void *ptr)
+{
+	const char *link = nd_get_link(nd);
+
+	if (!IS_ERR(link))
+		kmem_free(link, MAXPATHLEN);
+}
+#elif defined(HAVE_PUT_LINK_DELAYED)
+static void
+zpl_put_link(void *ptr)
+{
+	kmem_free(ptr, MAXPATHLEN);
+}
+#endif
+
+static int
+zpl_get_link_common(struct dentry *dentry, struct inode *ip, char **link)
+{
+	fstrans_cookie_t cookie;
+	cred_t *cr = CRED();
+	struct iovec iov;
+	uio_t uio;
+	int error;
+
+	crhold(cr);
+	*link = NULL;
+	iov.iov_len = MAXPATHLEN;
+	iov.iov_base = kmem_zalloc(MAXPATHLEN, KM_SLEEP);
+
+	uio.uio_iov = &iov;
+	uio.uio_iovcnt = 1;
+	uio.uio_skip = 0;
+	uio.uio_resid = (MAXPATHLEN - 1);
+	uio.uio_segflg = UIO_SYSSPACE;
+
+	cookie = spl_fstrans_mark();
+	error = -zfs_readlink(ip, &uio, cr);
+	spl_fstrans_unmark(cookie);
+	crfree(cr);
+
+	if (error)
+		kmem_free(iov.iov_base, MAXPATHLEN);
+	else
+		*link = iov.iov_base;
+
+	return (error);
+}
+
+#if defined(HAVE_GET_LINK_DELAYED)
+const char *
+zpl_get_link(struct dentry *dentry, struct inode *inode,
+    struct delayed_call *done)
+{
+	char *link = NULL;
+	int error;
+
+	if (!dentry)
+		return (ERR_PTR(-ECHILD));
+
+	error = zpl_get_link_common(dentry, inode, &link);
+	if (error)
+		return (ERR_PTR(error));
+
+	set_delayed_call(done, zpl_put_link, link);
+
+	return (link);
+}
+#elif defined(HAVE_GET_LINK_COOKIE)
+const char *
+zpl_get_link(struct dentry *dentry, struct inode *inode, void **cookie)
+{
+	char *link = NULL;
+	int error;
+
+	if (!dentry)
+		return (ERR_PTR(-ECHILD));
+
+	error = zpl_get_link_common(dentry, inode, &link);
+	if (error)
+		return (ERR_PTR(error));
+
+	return (*cookie = link);
+}
+#elif defined(HAVE_FOLLOW_LINK_COOKIE)
+const char *
+zpl_follow_link(struct dentry *dentry, void **cookie)
+{
+	char *link = NULL;
+	int error;
+
+	error = zpl_get_link_common(dentry, dentry->d_inode, &link);
+	if (error)
+		return (ERR_PTR(error));
+
+	return (*cookie = link);
+}
+#elif defined(HAVE_FOLLOW_LINK_NAMEIDATA)
+static void *
+zpl_follow_link(struct dentry *dentry, struct nameidata *nd)
+{
+	char *link = NULL;
+	int error;
+
+	error = zpl_get_link_common(dentry, dentry->d_inode, &link);
+	if (error)
+		nd_set_link(nd, ERR_PTR(error));
+	else
+		nd_set_link(nd, link);
+
+	return (NULL);
+}
+#endif
+
+static int
+zpl_link(struct dentry *old_dentry, struct inode *dir, struct dentry *dentry)
+{
+	cred_t *cr = CRED();
+	struct inode *ip = old_dentry->d_inode;
+	int error;
+	fstrans_cookie_t cookie;
+
+	if (ip->i_nlink >= ZFS_LINK_MAX)
+		return (-EMLINK);
+
+	crhold(cr);
+	ip->i_ctime = CURRENT_TIME_SEC;
+	igrab(ip); /* Use ihold() if available */
+
+	cookie = spl_fstrans_mark();
+	error = -zfs_link(dir, ip, dname(dentry), cr);
+	if (error) {
+		iput(ip);
+		goto out;
+	}
+
+	d_instantiate(dentry, ip);
+out:
+	spl_fstrans_unmark(cookie);
+	crfree(cr);
+	ASSERT3S(error, <=, 0);
+
+	return (error);
+}
+
+#ifdef HAVE_INODE_TRUNCATE_RANGE
+static void
+zpl_truncate_range(struct inode *ip, loff_t start, loff_t end)
+{
+	cred_t *cr = CRED();
+	flock64_t bf;
+	fstrans_cookie_t cookie;
+
+	ASSERT3S(start, <=, end);
+
+	/*
+	 * zfs_freesp() will interpret (len == 0) as meaning "truncate until
+	 * the end of the file". We don't want that.
+	 */
+	if (start == end)
+		return;
+
+	crhold(cr);
+
+	bf.l_type = F_WRLCK;
+	bf.l_whence = 0;
+	bf.l_start = start;
+	bf.l_len = end - start;
+	bf.l_pid = 0;
+	cookie = spl_fstrans_mark();
+	zfs_space(ip, F_FREESP, &bf, FWRITE, start, cr);
+	spl_fstrans_unmark(cookie);
+
+	crfree(cr);
+}
+#endif /* HAVE_INODE_TRUNCATE_RANGE */
+
+#ifdef HAVE_INODE_FALLOCATE
+static long
+zpl_fallocate(struct inode *ip, int mode, loff_t offset, loff_t len)
+{
+	return (zpl_fallocate_common(ip, mode, offset, len));
+}
+#endif /* HAVE_INODE_FALLOCATE */
+
+static int
+#ifdef HAVE_D_REVALIDATE_NAMEIDATA
+zpl_revalidate(struct dentry *dentry, struct nameidata *nd)
+{
+	unsigned int flags = (nd ? nd->flags : 0);
+#else
+zpl_revalidate(struct dentry *dentry, unsigned int flags)
+{
+#endif /* HAVE_D_REVALIDATE_NAMEIDATA */
+	zfs_sb_t *zsb = dentry->d_sb->s_fs_info;
+	int error;
+
+	if (flags & LOOKUP_RCU)
+		return (-ECHILD);
+
+	/*
+	 * Automounted snapshots rely on periodic dentry revalidation
+	 * to defer snapshots from being automatically unmounted.
+	 */
+	if (zsb->z_issnap) {
+		if (time_after(jiffies, zsb->z_snap_defer_time +
+		    MAX(zfs_expire_snapshot * HZ / 2, HZ))) {
+			zsb->z_snap_defer_time = jiffies;
+			zfsctl_snapshot_unmount_delay(zsb->z_os->os_spa,
+			    dmu_objset_id(zsb->z_os), zfs_expire_snapshot);
+		}
+	}
+
+	/*
+	 * After a rollback negative dentries created before the rollback
+	 * time must be invalidated.  Otherwise they can obscure files which
+	 * are only present in the rolled back dataset.
+	 */
+	if (dentry->d_inode == NULL) {
+		spin_lock(&dentry->d_lock);
+		error = time_before(dentry->d_time, zsb->z_rollback_time);
+		spin_unlock(&dentry->d_lock);
+
+		if (error)
+			return (0);
+	}
+
+	/*
+	 * The dentry may reference a stale inode if a mounted file system
+	 * was rolled back to a point in time where the object didn't exist.
+	 */
+	if (dentry->d_inode && ITOZ(dentry->d_inode)->z_is_stale)
+		return (0);
+
+	return (1);
+}
+
+const struct inode_operations zpl_inode_operations = {
+	.create		= zpl_create,
+	.link		= zpl_link,
+	.unlink		= zpl_unlink,
+	.symlink	= zpl_symlink,
+	.mkdir		= zpl_mkdir,
+	.rmdir		= zpl_rmdir,
+	.mknod		= zpl_mknod,
+	.rename		= zpl_rename,
+	.setattr	= zpl_setattr,
+	.getattr	= zpl_getattr,
+	.setxattr	= generic_setxattr,
+	.getxattr	= generic_getxattr,
+	.removexattr	= generic_removexattr,
+	.listxattr	= zpl_xattr_list,
+#ifdef HAVE_INODE_TRUNCATE_RANGE
+	.truncate_range = zpl_truncate_range,
+#endif /* HAVE_INODE_TRUNCATE_RANGE */
+#ifdef HAVE_INODE_FALLOCATE
+	.fallocate	= zpl_fallocate,
+#endif /* HAVE_INODE_FALLOCATE */
+#if defined(CONFIG_FS_POSIX_ACL)
+#if defined(HAVE_GET_ACL)
+	.get_acl	= zpl_get_acl,
+#elif defined(HAVE_CHECK_ACL)
+	.check_acl	= zpl_check_acl,
+#elif defined(HAVE_PERMISSION)
+	.permission	= zpl_permission,
+#endif /* HAVE_GET_ACL | HAVE_CHECK_ACL | HAVE_PERMISSION */
+#endif /* CONFIG_FS_POSIX_ACL */
+};
+
+const struct inode_operations zpl_dir_inode_operations = {
+	.create		= zpl_create,
+	.lookup		= zpl_lookup,
+	.link		= zpl_link,
+	.unlink		= zpl_unlink,
+	.symlink	= zpl_symlink,
+	.mkdir		= zpl_mkdir,
+	.rmdir		= zpl_rmdir,
+	.mknod		= zpl_mknod,
+	.rename		= zpl_rename,
+	.setattr	= zpl_setattr,
+	.getattr	= zpl_getattr,
+	.setxattr	= generic_setxattr,
+	.getxattr	= generic_getxattr,
+	.removexattr	= generic_removexattr,
+	.listxattr	= zpl_xattr_list,
+#if defined(CONFIG_FS_POSIX_ACL)
+#if defined(HAVE_GET_ACL)
+	.get_acl	= zpl_get_acl,
+#elif defined(HAVE_CHECK_ACL)
+	.check_acl	= zpl_check_acl,
+#elif defined(HAVE_PERMISSION)
+	.permission	= zpl_permission,
+#endif /* HAVE_GET_ACL | HAVE_CHECK_ACL | HAVE_PERMISSION */
+#endif /* CONFIG_FS_POSIX_ACL */
+};
+
+const struct inode_operations zpl_symlink_inode_operations = {
+	.readlink	= generic_readlink,
+#if defined(HAVE_GET_LINK_DELAYED) || defined(HAVE_GET_LINK_COOKIE)
+	.get_link	= zpl_get_link,
+#elif defined(HAVE_FOLLOW_LINK_COOKIE) || defined(HAVE_FOLLOW_LINK_NAMEIDATA)
+	.follow_link	= zpl_follow_link,
+#endif
+#if defined(HAVE_PUT_LINK_COOKIE) || defined(HAVE_PUT_LINK_NAMEIDATA)
+	.put_link	= zpl_put_link,
+#endif
+	.setattr	= zpl_setattr,
+	.getattr	= zpl_getattr,
+	.setxattr	= generic_setxattr,
+	.getxattr	= generic_getxattr,
+	.removexattr	= generic_removexattr,
+	.listxattr	= zpl_xattr_list,
+};
+
+const struct inode_operations zpl_special_inode_operations = {
+	.setattr	= zpl_setattr,
+	.getattr	= zpl_getattr,
+	.setxattr	= generic_setxattr,
+	.getxattr	= generic_getxattr,
+	.removexattr	= generic_removexattr,
+	.listxattr	= zpl_xattr_list,
+#if defined(CONFIG_FS_POSIX_ACL)
+#if defined(HAVE_GET_ACL)
+	.get_acl	= zpl_get_acl,
+#elif defined(HAVE_CHECK_ACL)
+	.check_acl	= zpl_check_acl,
+#elif defined(HAVE_PERMISSION)
+	.permission	= zpl_permission,
+#endif /* HAVE_GET_ACL | HAVE_CHECK_ACL | HAVE_PERMISSION */
+#endif /* CONFIG_FS_POSIX_ACL */
+};
+
+dentry_operations_t zpl_dentry_operations = {
+	.d_revalidate	= zpl_revalidate,
+};
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/module/zfs/zpl_super.c
@@ -0,0 +1,551 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2011, Lawrence Livermore National Security, LLC.
+ */
+
+
+#include <sys/zfs_vfsops.h>
+#include <sys/zfs_vnops.h>
+#include <sys/zfs_znode.h>
+#include <sys/zfs_ctldir.h>
+#include <sys/zpl.h>
+
+
+static struct inode *
+zpl_inode_alloc(struct super_block *sb)
+{
+	struct inode *ip;
+
+	VERIFY3S(zfs_inode_alloc(sb, &ip), ==, 0);
+	ip->i_version = 1;
+
+	return (ip);
+}
+
+static void
+zpl_inode_destroy(struct inode *ip)
+{
+	ASSERT(atomic_read(&ip->i_count) == 0);
+	zfs_inode_destroy(ip);
+}
+
+/*
+ * Called from __mark_inode_dirty() to reflect that something in the
+ * inode has changed.  We use it to ensure the znode system attributes
+ * are always strictly update to date with respect to the inode.
+ */
+#ifdef HAVE_DIRTY_INODE_WITH_FLAGS
+static void
+zpl_dirty_inode(struct inode *ip, int flags)
+{
+	fstrans_cookie_t cookie;
+
+	cookie = spl_fstrans_mark();
+	zfs_dirty_inode(ip, flags);
+	spl_fstrans_unmark(cookie);
+}
+#else
+static void
+zpl_dirty_inode(struct inode *ip)
+{
+	fstrans_cookie_t cookie;
+
+	cookie = spl_fstrans_mark();
+	zfs_dirty_inode(ip, 0);
+	spl_fstrans_unmark(cookie);
+}
+#endif /* HAVE_DIRTY_INODE_WITH_FLAGS */
+
+/*
+ * When ->drop_inode() is called its return value indicates if the
+ * inode should be evicted from the inode cache.  If the inode is
+ * unhashed and has no links the default policy is to evict it
+ * immediately.
+ *
+ * Prior to 2.6.36 this eviction was accomplished by the vfs calling
+ * ->delete_inode().  It was ->delete_inode()'s responsibility to
+ * truncate the inode pages and call clear_inode().  The call to
+ * clear_inode() synchronously invalidates all the buffers and
+ * calls ->clear_inode().  It was ->clear_inode()'s responsibility
+ * to cleanup and filesystem specific data before freeing the inode.
+ *
+ * This elaborate mechanism was replaced by ->evict_inode() which
+ * does the job of both ->delete_inode() and ->clear_inode().  It
+ * will be called exactly once, and when it returns the inode must
+ * be in a state where it can simply be freed.i
+ *
+ * The ->evict_inode() callback must minimally truncate the inode pages,
+ * and call clear_inode().  For 2.6.35 and later kernels this will
+ * simply update the inode state, with the sync occurring before the
+ * truncate in evict().  For earlier kernels clear_inode() maps to
+ * end_writeback() which is responsible for completing all outstanding
+ * write back.  In either case, once this is done it is safe to cleanup
+ * any remaining inode specific data via zfs_inactive().
+ * remaining filesystem specific data.
+ */
+#ifdef HAVE_EVICT_INODE
+static void
+zpl_evict_inode(struct inode *ip)
+{
+	fstrans_cookie_t cookie;
+
+	cookie = spl_fstrans_mark();
+	truncate_setsize(ip, 0);
+	clear_inode(ip);
+	zfs_inactive(ip);
+	spl_fstrans_unmark(cookie);
+}
+
+#else
+
+static void
+zpl_drop_inode(struct inode *ip)
+{
+	generic_delete_inode(ip);
+}
+
+static void
+zpl_clear_inode(struct inode *ip)
+{
+	fstrans_cookie_t cookie;
+
+	cookie = spl_fstrans_mark();
+	zfs_inactive(ip);
+	spl_fstrans_unmark(cookie);
+}
+
+static void
+zpl_inode_delete(struct inode *ip)
+{
+	truncate_setsize(ip, 0);
+	clear_inode(ip);
+}
+#endif /* HAVE_EVICT_INODE */
+
+static void
+zpl_put_super(struct super_block *sb)
+{
+	fstrans_cookie_t cookie;
+	int error;
+
+	cookie = spl_fstrans_mark();
+	error = -zfs_umount(sb);
+	spl_fstrans_unmark(cookie);
+	ASSERT3S(error, <=, 0);
+}
+
+static int
+zpl_sync_fs(struct super_block *sb, int wait)
+{
+	fstrans_cookie_t cookie;
+	cred_t *cr = CRED();
+	int error;
+
+	crhold(cr);
+	cookie = spl_fstrans_mark();
+	error = -zfs_sync(sb, wait, cr);
+	spl_fstrans_unmark(cookie);
+	crfree(cr);
+	ASSERT3S(error, <=, 0);
+
+	return (error);
+}
+
+static int
+zpl_statfs(struct dentry *dentry, struct kstatfs *statp)
+{
+	fstrans_cookie_t cookie;
+	int error;
+
+	cookie = spl_fstrans_mark();
+	error = -zfs_statvfs(dentry, statp);
+	spl_fstrans_unmark(cookie);
+	ASSERT3S(error, <=, 0);
+
+	return (error);
+}
+
+enum {
+	TOKEN_RO,
+	TOKEN_RW,
+	TOKEN_SETUID,
+	TOKEN_NOSETUID,
+	TOKEN_EXEC,
+	TOKEN_NOEXEC,
+	TOKEN_DEVICES,
+	TOKEN_NODEVICES,
+	TOKEN_DIRXATTR,
+	TOKEN_SAXATTR,
+	TOKEN_XATTR,
+	TOKEN_NOXATTR,
+	TOKEN_ATIME,
+	TOKEN_NOATIME,
+	TOKEN_RELATIME,
+	TOKEN_NORELATIME,
+	TOKEN_NBMAND,
+	TOKEN_NONBMAND,
+	TOKEN_MNTPOINT,
+	TOKEN_LAST,
+};
+
+static const match_table_t zpl_tokens = {
+	{ TOKEN_RO,		MNTOPT_RO },
+	{ TOKEN_RW,		MNTOPT_RW },
+	{ TOKEN_SETUID,		MNTOPT_SETUID },
+	{ TOKEN_NOSETUID,	MNTOPT_NOSETUID },
+	{ TOKEN_EXEC,		MNTOPT_EXEC },
+	{ TOKEN_NOEXEC,		MNTOPT_NOEXEC },
+	{ TOKEN_DEVICES,	MNTOPT_DEVICES },
+	{ TOKEN_NODEVICES,	MNTOPT_NODEVICES },
+	{ TOKEN_DIRXATTR,	MNTOPT_DIRXATTR },
+	{ TOKEN_SAXATTR,	MNTOPT_SAXATTR },
+	{ TOKEN_XATTR,		MNTOPT_XATTR },
+	{ TOKEN_NOXATTR,	MNTOPT_NOXATTR },
+	{ TOKEN_ATIME,		MNTOPT_ATIME },
+	{ TOKEN_NOATIME,	MNTOPT_NOATIME },
+	{ TOKEN_RELATIME,	MNTOPT_RELATIME },
+	{ TOKEN_NORELATIME,	MNTOPT_NORELATIME },
+	{ TOKEN_NBMAND,		MNTOPT_NBMAND },
+	{ TOKEN_NONBMAND,	MNTOPT_NONBMAND },
+	{ TOKEN_MNTPOINT,	MNTOPT_MNTPOINT "=%s" },
+	{ TOKEN_LAST,		NULL },
+};
+
+static int
+zpl_parse_option(char *option, int token, substring_t *args, zfs_mntopts_t *zmo)
+{
+	switch (token) {
+	case TOKEN_RO:
+		zmo->z_readonly = B_TRUE;
+		zmo->z_do_readonly = B_TRUE;
+		break;
+	case TOKEN_RW:
+		zmo->z_readonly = B_FALSE;
+		zmo->z_do_readonly = B_TRUE;
+		break;
+	case TOKEN_SETUID:
+		zmo->z_setuid = B_TRUE;
+		zmo->z_do_setuid = B_TRUE;
+		break;
+	case TOKEN_NOSETUID:
+		zmo->z_setuid = B_FALSE;
+		zmo->z_do_setuid = B_TRUE;
+		break;
+	case TOKEN_EXEC:
+		zmo->z_exec = B_TRUE;
+		zmo->z_do_exec = B_TRUE;
+		break;
+	case TOKEN_NOEXEC:
+		zmo->z_exec = B_FALSE;
+		zmo->z_do_exec = B_TRUE;
+		break;
+	case TOKEN_DEVICES:
+		zmo->z_devices = B_TRUE;
+		zmo->z_do_devices = B_TRUE;
+		break;
+	case TOKEN_NODEVICES:
+		zmo->z_devices = B_FALSE;
+		zmo->z_do_devices = B_TRUE;
+		break;
+	case TOKEN_DIRXATTR:
+		zmo->z_xattr = ZFS_XATTR_DIR;
+		zmo->z_do_xattr = B_TRUE;
+		break;
+	case TOKEN_SAXATTR:
+		zmo->z_xattr = ZFS_XATTR_SA;
+		zmo->z_do_xattr = B_TRUE;
+		break;
+	case TOKEN_XATTR:
+		zmo->z_xattr = ZFS_XATTR_DIR;
+		zmo->z_do_xattr = B_TRUE;
+		break;
+	case TOKEN_NOXATTR:
+		zmo->z_xattr = ZFS_XATTR_OFF;
+		zmo->z_do_xattr = B_TRUE;
+		break;
+	case TOKEN_ATIME:
+		zmo->z_atime = B_TRUE;
+		zmo->z_do_atime = B_TRUE;
+		break;
+	case TOKEN_NOATIME:
+		zmo->z_atime = B_FALSE;
+		zmo->z_do_atime = B_TRUE;
+		break;
+	case TOKEN_RELATIME:
+		zmo->z_relatime = B_TRUE;
+		zmo->z_do_relatime = B_TRUE;
+		break;
+	case TOKEN_NORELATIME:
+		zmo->z_relatime = B_FALSE;
+		zmo->z_do_relatime = B_TRUE;
+		break;
+	case TOKEN_NBMAND:
+		zmo->z_nbmand = B_TRUE;
+		zmo->z_do_nbmand = B_TRUE;
+		break;
+	case TOKEN_NONBMAND:
+		zmo->z_nbmand = B_FALSE;
+		zmo->z_do_nbmand = B_TRUE;
+		break;
+	case TOKEN_MNTPOINT:
+		zmo->z_mntpoint = match_strdup(&args[0]);
+		if (zmo->z_mntpoint == NULL)
+			return (-ENOMEM);
+
+		break;
+	default:
+		break;
+	}
+
+	return (0);
+}
+
+/*
+ * Parse the mntopts string storing the results in provided zmo argument.
+ * If an error occurs the zmo argument will not be modified.  The caller
+ * needs to set isremount when recycling an existing zfs_mntopts_t.
+ */
+static int
+zpl_parse_options(char *osname, char *mntopts, zfs_mntopts_t *zmo,
+    boolean_t isremount)
+{
+	zfs_mntopts_t *tmp_zmo;
+	int error;
+
+	tmp_zmo = zfs_mntopts_alloc();
+	tmp_zmo->z_osname = strdup(osname);
+
+	if (mntopts) {
+		substring_t args[MAX_OPT_ARGS];
+		char *tmp_mntopts, *p;
+		int token;
+
+		tmp_mntopts = strdup(mntopts);
+
+		while ((p = strsep(&tmp_mntopts, ",")) != NULL) {
+			if (!*p)
+				continue;
+
+			args[0].to = args[0].from = NULL;
+			token = match_token(p, zpl_tokens, args);
+			error = zpl_parse_option(p, token, args, tmp_zmo);
+			if (error) {
+				zfs_mntopts_free(tmp_zmo);
+				strfree(tmp_mntopts);
+				return (error);
+			}
+		}
+
+		strfree(tmp_mntopts);
+	}
+
+	if (isremount == B_TRUE) {
+		if (zmo->z_osname)
+			strfree(zmo->z_osname);
+
+		if (zmo->z_mntpoint)
+			strfree(zmo->z_mntpoint);
+	} else {
+		ASSERT3P(zmo->z_osname, ==, NULL);
+		ASSERT3P(zmo->z_mntpoint, ==, NULL);
+	}
+
+	memcpy(zmo, tmp_zmo, sizeof (zfs_mntopts_t));
+	kmem_free(tmp_zmo, sizeof (zfs_mntopts_t));
+
+	return (0);
+}
+
+static int
+zpl_remount_fs(struct super_block *sb, int *flags, char *data)
+{
+	zfs_sb_t *zsb = sb->s_fs_info;
+	fstrans_cookie_t cookie;
+	int error;
+
+	error = zpl_parse_options(zsb->z_mntopts->z_osname, data,
+	    zsb->z_mntopts, B_TRUE);
+	if (error)
+		return (error);
+
+	cookie = spl_fstrans_mark();
+	error = -zfs_remount(sb, flags, zsb->z_mntopts);
+	spl_fstrans_unmark(cookie);
+	ASSERT3S(error, <=, 0);
+
+	return (error);
+}
+
+static int
+__zpl_show_options(struct seq_file *seq, zfs_sb_t *zsb)
+{
+	seq_printf(seq, ",%s", zsb->z_flags & ZSB_XATTR ? "xattr" : "noxattr");
+
+#ifdef CONFIG_FS_POSIX_ACL
+	switch (zsb->z_acl_type) {
+	case ZFS_ACLTYPE_POSIXACL:
+		seq_puts(seq, ",posixacl");
+		break;
+	default:
+		seq_puts(seq, ",noacl");
+		break;
+	}
+#endif /* CONFIG_FS_POSIX_ACL */
+
+	return (0);
+}
+
+#ifdef HAVE_SHOW_OPTIONS_WITH_DENTRY
+static int
+zpl_show_options(struct seq_file *seq, struct dentry *root)
+{
+	return (__zpl_show_options(seq, root->d_sb->s_fs_info));
+}
+#else
+static int
+zpl_show_options(struct seq_file *seq, struct vfsmount *vfsp)
+{
+	return (__zpl_show_options(seq, vfsp->mnt_sb->s_fs_info));
+}
+#endif /* HAVE_SHOW_OPTIONS_WITH_DENTRY */
+
+static int
+zpl_fill_super(struct super_block *sb, void *data, int silent)
+{
+	zfs_mntopts_t *zmo = (zfs_mntopts_t *)data;
+	fstrans_cookie_t cookie;
+	int error;
+
+	cookie = spl_fstrans_mark();
+	error = -zfs_domount(sb, zmo, silent);
+	spl_fstrans_unmark(cookie);
+	ASSERT3S(error, <=, 0);
+
+	return (error);
+}
+
+#ifdef HAVE_MOUNT_NODEV
+static struct dentry *
+zpl_mount(struct file_system_type *fs_type, int flags,
+    const char *osname, void *data)
+{
+	zfs_mntopts_t *zmo = zfs_mntopts_alloc();
+	int error;
+
+	error = zpl_parse_options((char *)osname, (char *)data, zmo, B_FALSE);
+	if (error) {
+		zfs_mntopts_free(zmo);
+		return (ERR_PTR(error));
+	}
+
+	return (mount_nodev(fs_type, flags, zmo, zpl_fill_super));
+}
+#else
+static int
+zpl_get_sb(struct file_system_type *fs_type, int flags,
+    const char *osname, void *data, struct vfsmount *mnt)
+{
+	zfs_mntopts_t *zmo = zfs_mntopts_alloc();
+	int error;
+
+	error = zpl_parse_options((char *)osname, (char *)data, zmo, B_FALSE);
+	if (error) {
+		zfs_mntopts_free(zmo);
+		return (error);
+	}
+
+	return (get_sb_nodev(fs_type, flags, zmo, zpl_fill_super, mnt));
+}
+#endif /* HAVE_MOUNT_NODEV */
+
+static void
+zpl_kill_sb(struct super_block *sb)
+{
+	zfs_preumount(sb);
+	kill_anon_super(sb);
+
+#ifdef HAVE_S_INSTANCES_LIST_HEAD
+	sb->s_instances.next = &(zpl_fs_type.fs_supers);
+#endif /* HAVE_S_INSTANCES_LIST_HEAD */
+}
+
+void
+zpl_prune_sb(int64_t nr_to_scan, void *arg)
+{
+	struct super_block *sb = (struct super_block *)arg;
+	int objects = 0;
+
+	(void) -zfs_sb_prune(sb, nr_to_scan, &objects);
+}
+
+#ifdef HAVE_NR_CACHED_OBJECTS
+static int
+zpl_nr_cached_objects(struct super_block *sb)
+{
+	return (0);
+}
+#endif /* HAVE_NR_CACHED_OBJECTS */
+
+#ifdef HAVE_FREE_CACHED_OBJECTS
+static void
+zpl_free_cached_objects(struct super_block *sb, int nr_to_scan)
+{
+	/* noop */
+}
+#endif /* HAVE_FREE_CACHED_OBJECTS */
+
+const struct super_operations zpl_super_operations = {
+	.alloc_inode		= zpl_inode_alloc,
+	.destroy_inode		= zpl_inode_destroy,
+	.dirty_inode		= zpl_dirty_inode,
+	.write_inode		= NULL,
+#ifdef HAVE_EVICT_INODE
+	.evict_inode		= zpl_evict_inode,
+#else
+	.drop_inode		= zpl_drop_inode,
+	.clear_inode		= zpl_clear_inode,
+	.delete_inode		= zpl_inode_delete,
+#endif /* HAVE_EVICT_INODE */
+	.put_super		= zpl_put_super,
+	.sync_fs		= zpl_sync_fs,
+	.statfs			= zpl_statfs,
+	.remount_fs		= zpl_remount_fs,
+	.show_options		= zpl_show_options,
+	.show_stats		= NULL,
+#ifdef HAVE_NR_CACHED_OBJECTS
+	.nr_cached_objects	= zpl_nr_cached_objects,
+#endif /* HAVE_NR_CACHED_OBJECTS */
+#ifdef HAVE_FREE_CACHED_OBJECTS
+	.free_cached_objects	= zpl_free_cached_objects,
+#endif /* HAVE_FREE_CACHED_OBJECTS */
+};
+
+struct file_system_type zpl_fs_type = {
+	.owner			= THIS_MODULE,
+	.name			= ZFS_DRIVER,
+#ifdef HAVE_MOUNT_NODEV
+	.mount			= zpl_mount,
+#else
+	.get_sb			= zpl_get_sb,
+#endif /* HAVE_MOUNT_NODEV */
+	.kill_sb		= zpl_kill_sb,
+};
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/module/zfs/zpl_xattr.c
@@ -0,0 +1,1411 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2011, Lawrence Livermore National Security, LLC.
+ *
+ * Extended attributes (xattr) on Solaris are implemented as files
+ * which exist in a hidden xattr directory.  These extended attributes
+ * can be accessed using the attropen() system call which opens
+ * the extended attribute.  It can then be manipulated just like
+ * a standard file descriptor.  This has a couple advantages such
+ * as practically no size limit on the file, and the extended
+ * attributes permissions may differ from those of the parent file.
+ * This interface is really quite clever, but it's also completely
+ * different than what is supported on Linux.  It also comes with a
+ * steep performance penalty when accessing small xattrs because they
+ * are not stored with the parent file.
+ *
+ * Under Linux extended attributes are manipulated by the system
+ * calls getxattr(2), setxattr(2), and listxattr(2).  They consider
+ * extended attributes to be name/value pairs where the name is a
+ * NULL terminated string.  The name must also include one of the
+ * following namespace prefixes:
+ *
+ *   user     - No restrictions and is available to user applications.
+ *   trusted  - Restricted to kernel and root (CAP_SYS_ADMIN) use.
+ *   system   - Used for access control lists (system.nfs4_acl, etc).
+ *   security - Used by SELinux to store a files security context.
+ *
+ * The value under Linux to limited to 65536 bytes of binary data.
+ * In practice, individual xattrs tend to be much smaller than this
+ * and are typically less than 100 bytes.  A good example of this
+ * are the security.selinux xattrs which are less than 100 bytes and
+ * exist for every file when xattr labeling is enabled.
+ *
+ * The Linux xattr implemenation has been written to take advantage of
+ * this typical usage.  When the dataset property 'xattr=sa' is set,
+ * then xattrs will be preferentially stored as System Attributes (SA).
+ * This allows tiny xattrs (~100 bytes) to be stored with the dnode and
+ * up to 64k of xattrs to be stored in the spill block.  If additional
+ * xattr space is required, which is unlikely under Linux, they will
+ * be stored using the traditional directory approach.
+ *
+ * This optimization results in roughly a 3x performance improvement
+ * when accessing xattrs because it avoids the need to perform a seek
+ * for every xattr value.  When multiple xattrs are stored per-file
+ * the performance improvements are even greater because all of the
+ * xattrs stored in the spill block will be cached.
+ *
+ * However, by default SA based xattrs are disabled in the Linux port
+ * to maximize compatibility with other implementations.  If you do
+ * enable SA based xattrs then they will not be visible on platforms
+ * which do not support this feature.
+ *
+ * NOTE: One additional consequence of the xattr directory implementation
+ * is that when an extended attribute is manipulated an inode is created.
+ * This inode will exist in the Linux inode cache but there will be no
+ * associated entry in the dentry cache which references it.  This is
+ * safe but it may result in some confusion.  Enabling SA based xattrs
+ * largely avoids the issue except in the overflow case.
+ */
+
+#include <sys/zfs_vfsops.h>
+#include <sys/zfs_vnops.h>
+#include <sys/zfs_znode.h>
+#include <sys/zap.h>
+#include <sys/vfs.h>
+#include <sys/zpl.h>
+
+typedef struct xattr_filldir {
+	size_t size;
+	size_t offset;
+	char *buf;
+	struct dentry *dentry;
+} xattr_filldir_t;
+
+static const struct xattr_handler *zpl_xattr_handler(const char *);
+
+static int
+zpl_xattr_permission(xattr_filldir_t *xf, const char *name, int name_len)
+{
+	static const struct xattr_handler *handler;
+	struct dentry *d = xf->dentry;
+
+	handler = zpl_xattr_handler(name);
+	if (!handler)
+		return (0);
+
+	if (handler->list) {
+#if defined(HAVE_XATTR_LIST_SIMPLE)
+		if (!handler->list(d))
+			return (0);
+#elif defined(HAVE_XATTR_LIST_DENTRY)
+		if (!handler->list(d, NULL, 0, name, name_len, 0))
+			return (0);
+#elif defined(HAVE_XATTR_LIST_HANDLER)
+		if (!handler->list(handler, d, NULL, 0, name, name_len))
+			return (0);
+#elif defined(HAVE_XATTR_LIST_INODE)
+		if (!handler->list(d->d_inode, NULL, 0, name, name_len))
+			return (0);
+#endif
+	}
+
+	return (1);
+}
+
+/*
+ * Determine is a given xattr name should be visible and if so copy it
+ * in to the provided buffer (xf->buf).
+ */
+static int
+zpl_xattr_filldir(xattr_filldir_t *xf, const char *name, int name_len)
+{
+	/* Check permissions using the per-namespace list xattr handler. */
+	if (!zpl_xattr_permission(xf, name, name_len))
+		return (0);
+
+	/* When xf->buf is NULL only calculate the required size. */
+	if (xf->buf) {
+		if (xf->offset + name_len + 1 > xf->size)
+			return (-ERANGE);
+
+		memcpy(xf->buf + xf->offset, name, name_len);
+		xf->buf[xf->offset + name_len] = '\0';
+	}
+
+	xf->offset += (name_len + 1);
+
+	return (0);
+}
+
+/*
+ * Read as many directory entry names as will fit in to the provided buffer,
+ * or when no buffer is provided calculate the required buffer size.
+ */
+int
+zpl_xattr_readdir(struct inode *dxip, xattr_filldir_t *xf)
+{
+	zap_cursor_t zc;
+	zap_attribute_t	zap;
+	int error;
+
+	zap_cursor_init(&zc, ITOZSB(dxip)->z_os, ITOZ(dxip)->z_id);
+
+	while ((error = -zap_cursor_retrieve(&zc, &zap)) == 0) {
+
+		if (zap.za_integer_length != 8 || zap.za_num_integers != 1) {
+			error = -ENXIO;
+			break;
+		}
+
+		error = zpl_xattr_filldir(xf, zap.za_name, strlen(zap.za_name));
+		if (error)
+			break;
+
+		zap_cursor_advance(&zc);
+	}
+
+	zap_cursor_fini(&zc);
+
+	if (error == -ENOENT)
+		error = 0;
+
+	return (error);
+}
+
+static ssize_t
+zpl_xattr_list_dir(xattr_filldir_t *xf, cred_t *cr)
+{
+	struct inode *ip = xf->dentry->d_inode;
+	struct inode *dxip = NULL;
+	int error;
+
+	/* Lookup the xattr directory */
+	error = -zfs_lookup(ip, NULL, &dxip, LOOKUP_XATTR, cr, NULL, NULL);
+	if (error) {
+		if (error == -ENOENT)
+			error = 0;
+
+		return (error);
+	}
+
+	error = zpl_xattr_readdir(dxip, xf);
+	iput(dxip);
+
+	return (error);
+}
+
+static ssize_t
+zpl_xattr_list_sa(xattr_filldir_t *xf)
+{
+	znode_t *zp = ITOZ(xf->dentry->d_inode);
+	nvpair_t *nvp = NULL;
+	int error = 0;
+
+	mutex_enter(&zp->z_lock);
+	if (zp->z_xattr_cached == NULL)
+		error = -zfs_sa_get_xattr(zp);
+	mutex_exit(&zp->z_lock);
+
+	if (error)
+		return (error);
+
+	ASSERT(zp->z_xattr_cached);
+
+	while ((nvp = nvlist_next_nvpair(zp->z_xattr_cached, nvp)) != NULL) {
+		ASSERT3U(nvpair_type(nvp), ==, DATA_TYPE_BYTE_ARRAY);
+
+		error = zpl_xattr_filldir(xf, nvpair_name(nvp),
+		    strlen(nvpair_name(nvp)));
+		if (error)
+			return (error);
+	}
+
+	return (0);
+}
+
+ssize_t
+zpl_xattr_list(struct dentry *dentry, char *buffer, size_t buffer_size)
+{
+	znode_t *zp = ITOZ(dentry->d_inode);
+	zfs_sb_t *zsb = ZTOZSB(zp);
+	xattr_filldir_t xf = { buffer_size, 0, buffer, dentry };
+	cred_t *cr = CRED();
+	fstrans_cookie_t cookie;
+	int error = 0;
+
+	crhold(cr);
+	cookie = spl_fstrans_mark();
+	rrm_enter_read(&(zsb)->z_teardown_lock, FTAG);
+	rw_enter(&zp->z_xattr_lock, RW_READER);
+
+	if (zsb->z_use_sa && zp->z_is_sa) {
+		error = zpl_xattr_list_sa(&xf);
+		if (error)
+			goto out;
+	}
+
+	error = zpl_xattr_list_dir(&xf, cr);
+	if (error)
+		goto out;
+
+	error = xf.offset;
+out:
+
+	rw_exit(&zp->z_xattr_lock);
+	rrm_exit(&(zsb)->z_teardown_lock, FTAG);
+	spl_fstrans_unmark(cookie);
+	crfree(cr);
+
+	return (error);
+}
+
+static int
+zpl_xattr_get_dir(struct inode *ip, const char *name, void *value,
+    size_t size, cred_t *cr)
+{
+	struct inode *dxip = NULL;
+	struct inode *xip = NULL;
+	loff_t pos = 0;
+	int error;
+
+	/* Lookup the xattr directory */
+	error = -zfs_lookup(ip, NULL, &dxip, LOOKUP_XATTR, cr, NULL, NULL);
+	if (error)
+		goto out;
+
+	/* Lookup a specific xattr name in the directory */
+	error = -zfs_lookup(dxip, (char *)name, &xip, 0, cr, NULL, NULL);
+	if (error)
+		goto out;
+
+	if (!size) {
+		error = i_size_read(xip);
+		goto out;
+	}
+
+	if (size < i_size_read(xip)) {
+		error = -ERANGE;
+		goto out;
+	}
+
+	error = zpl_read_common(xip, value, size, &pos, UIO_SYSSPACE, 0, cr);
+out:
+	if (xip)
+		iput(xip);
+
+	if (dxip)
+		iput(dxip);
+
+	return (error);
+}
+
+static int
+zpl_xattr_get_sa(struct inode *ip, const char *name, void *value, size_t size)
+{
+	znode_t *zp = ITOZ(ip);
+	uchar_t *nv_value;
+	uint_t nv_size;
+	int error = 0;
+
+	ASSERT(RW_LOCK_HELD(&zp->z_xattr_lock));
+
+	mutex_enter(&zp->z_lock);
+	if (zp->z_xattr_cached == NULL)
+		error = -zfs_sa_get_xattr(zp);
+	mutex_exit(&zp->z_lock);
+
+	if (error)
+		return (error);
+
+	ASSERT(zp->z_xattr_cached);
+	error = -nvlist_lookup_byte_array(zp->z_xattr_cached, name,
+	    &nv_value, &nv_size);
+	if (error)
+		return (error);
+
+	if (!size)
+		return (nv_size);
+
+	if (size < nv_size)
+		return (-ERANGE);
+
+	memcpy(value, nv_value, nv_size);
+
+	return (nv_size);
+}
+
+static int
+__zpl_xattr_get(struct inode *ip, const char *name, void *value, size_t size,
+    cred_t *cr)
+{
+	znode_t *zp = ITOZ(ip);
+	zfs_sb_t *zsb = ZTOZSB(zp);
+	int error;
+
+	ASSERT(RW_LOCK_HELD(&zp->z_xattr_lock));
+
+	if (zsb->z_use_sa && zp->z_is_sa) {
+		error = zpl_xattr_get_sa(ip, name, value, size);
+		if (error != -ENOENT)
+			goto out;
+	}
+
+	error = zpl_xattr_get_dir(ip, name, value, size, cr);
+out:
+	if (error == -ENOENT)
+		error = -ENODATA;
+
+	return (error);
+}
+
+#define	XATTR_NOENT	0x0
+#define	XATTR_IN_SA	0x1
+#define	XATTR_IN_DIR	0x2
+/* check where the xattr resides */
+static int
+__zpl_xattr_where(struct inode *ip, const char *name, int *where, cred_t *cr)
+{
+	znode_t *zp = ITOZ(ip);
+	zfs_sb_t *zsb = ZTOZSB(zp);
+	int error;
+
+	ASSERT(where);
+	ASSERT(RW_LOCK_HELD(&zp->z_xattr_lock));
+
+	*where = XATTR_NOENT;
+	if (zsb->z_use_sa && zp->z_is_sa) {
+		error = zpl_xattr_get_sa(ip, name, NULL, 0);
+		if (error >= 0)
+			*where |= XATTR_IN_SA;
+		else if (error != -ENOENT)
+			return (error);
+	}
+
+	error = zpl_xattr_get_dir(ip, name, NULL, 0, cr);
+	if (error >= 0)
+		*where |= XATTR_IN_DIR;
+	else if (error != -ENOENT)
+		return (error);
+
+	if (*where == (XATTR_IN_SA|XATTR_IN_DIR))
+		cmn_err(CE_WARN, "ZFS: inode %p has xattr \"%s\""
+		    " in both SA and dir", ip, name);
+	if (*where == XATTR_NOENT)
+		error = -ENODATA;
+	else
+		error = 0;
+	return (error);
+}
+
+static int
+zpl_xattr_get(struct inode *ip, const char *name, void *value, size_t size)
+{
+	znode_t *zp = ITOZ(ip);
+	zfs_sb_t *zsb = ZTOZSB(zp);
+	cred_t *cr = CRED();
+	fstrans_cookie_t cookie;
+	int error;
+
+	crhold(cr);
+	cookie = spl_fstrans_mark();
+	rrm_enter_read(&(zsb)->z_teardown_lock, FTAG);
+	rw_enter(&zp->z_xattr_lock, RW_READER);
+	error = __zpl_xattr_get(ip, name, value, size, cr);
+	rw_exit(&zp->z_xattr_lock);
+	rrm_exit(&(zsb)->z_teardown_lock, FTAG);
+	spl_fstrans_unmark(cookie);
+	crfree(cr);
+
+	return (error);
+}
+
+static int
+zpl_xattr_set_dir(struct inode *ip, const char *name, const void *value,
+    size_t size, int flags, cred_t *cr)
+{
+	struct inode *dxip = NULL;
+	struct inode *xip = NULL;
+	vattr_t *vap = NULL;
+	ssize_t wrote;
+	int lookup_flags, error;
+	const int xattr_mode = S_IFREG | 0644;
+	loff_t pos = 0;
+
+	/*
+	 * Lookup the xattr directory.  When we're adding an entry pass
+	 * CREATE_XATTR_DIR to ensure the xattr directory is created.
+	 * When removing an entry this flag is not passed to avoid
+	 * unnecessarily creating a new xattr directory.
+	 */
+	lookup_flags = LOOKUP_XATTR;
+	if (value != NULL)
+		lookup_flags |= CREATE_XATTR_DIR;
+
+	error = -zfs_lookup(ip, NULL, &dxip, lookup_flags, cr, NULL, NULL);
+	if (error)
+		goto out;
+
+	/* Lookup a specific xattr name in the directory */
+	error = -zfs_lookup(dxip, (char *)name, &xip, 0, cr, NULL, NULL);
+	if (error && (error != -ENOENT))
+		goto out;
+
+	error = 0;
+
+	/* Remove a specific name xattr when value is set to NULL. */
+	if (value == NULL) {
+		if (xip)
+			error = -zfs_remove(dxip, (char *)name, cr);
+
+		goto out;
+	}
+
+	/* Lookup failed create a new xattr. */
+	if (xip == NULL) {
+		vap = kmem_zalloc(sizeof (vattr_t), KM_SLEEP);
+		vap->va_mode = xattr_mode;
+		vap->va_mask = ATTR_MODE;
+		vap->va_uid = crgetfsuid(cr);
+		vap->va_gid = crgetfsgid(cr);
+
+		error = -zfs_create(dxip, (char *)name, vap, 0, 0644, &xip,
+		    cr, 0, NULL);
+		if (error)
+			goto out;
+	}
+
+	ASSERT(xip != NULL);
+
+	error = -zfs_freesp(ITOZ(xip), 0, 0, xattr_mode, TRUE);
+	if (error)
+		goto out;
+
+	wrote = zpl_write_common(xip, value, size, &pos, UIO_SYSSPACE, 0, cr);
+	if (wrote < 0)
+		error = wrote;
+
+out:
+	if (vap)
+		kmem_free(vap, sizeof (vattr_t));
+
+	if (xip)
+		iput(xip);
+
+	if (dxip)
+		iput(dxip);
+
+	if (error == -ENOENT)
+		error = -ENODATA;
+
+	ASSERT3S(error, <=, 0);
+
+	return (error);
+}
+
+static int
+zpl_xattr_set_sa(struct inode *ip, const char *name, const void *value,
+    size_t size, int flags, cred_t *cr)
+{
+	znode_t *zp = ITOZ(ip);
+	nvlist_t *nvl;
+	size_t sa_size;
+	int error = 0;
+
+	mutex_enter(&zp->z_lock);
+	if (zp->z_xattr_cached == NULL)
+		error = -zfs_sa_get_xattr(zp);
+	mutex_exit(&zp->z_lock);
+
+	if (error)
+		return (error);
+
+	ASSERT(zp->z_xattr_cached);
+	nvl = zp->z_xattr_cached;
+
+	if (value == NULL) {
+		error = -nvlist_remove(nvl, name, DATA_TYPE_BYTE_ARRAY);
+		if (error == -ENOENT)
+			error = zpl_xattr_set_dir(ip, name, NULL, 0, flags, cr);
+	} else {
+		/* Limited to 32k to keep nvpair memory allocations small */
+		if (size > DXATTR_MAX_ENTRY_SIZE)
+			return (-EFBIG);
+
+		/* Prevent the DXATTR SA from consuming the entire SA region */
+		error = -nvlist_size(nvl, &sa_size, NV_ENCODE_XDR);
+		if (error)
+			return (error);
+
+		if (sa_size > DXATTR_MAX_SA_SIZE)
+			return (-EFBIG);
+
+		error = -nvlist_add_byte_array(nvl, name,
+		    (uchar_t *)value, size);
+	}
+
+	/*
+	 * Update the SA for additions, modifications, and removals. On
+	 * error drop the inconsistent cached version of the nvlist, it
+	 * will be reconstructed from the ARC when next accessed.
+	 */
+	if (error == 0)
+		error = -zfs_sa_set_xattr(zp);
+
+	if (error) {
+		nvlist_free(nvl);
+		zp->z_xattr_cached = NULL;
+	}
+
+	ASSERT3S(error, <=, 0);
+
+	return (error);
+}
+
+static int
+zpl_xattr_set(struct inode *ip, const char *name, const void *value,
+    size_t size, int flags)
+{
+	znode_t *zp = ITOZ(ip);
+	zfs_sb_t *zsb = ZTOZSB(zp);
+	cred_t *cr = CRED();
+	fstrans_cookie_t cookie;
+	int where;
+	int error;
+
+	crhold(cr);
+	cookie = spl_fstrans_mark();
+	rrm_enter_read(&(zsb)->z_teardown_lock, FTAG);
+	rw_enter(&ITOZ(ip)->z_xattr_lock, RW_WRITER);
+
+	/*
+	 * Before setting the xattr check to see if it already exists.
+	 * This is done to ensure the following optional flags are honored.
+	 *
+	 *   XATTR_CREATE: fail if xattr already exists
+	 *   XATTR_REPLACE: fail if xattr does not exist
+	 *
+	 * We also want to know if it resides in sa or dir, so we can make
+	 * sure we don't end up with duplicate in both places.
+	 */
+	error = __zpl_xattr_where(ip, name, &where, cr);
+	if (error < 0) {
+		if (error != -ENODATA)
+			goto out;
+		if (flags & XATTR_REPLACE)
+			goto out;
+
+		/* The xattr to be removed already doesn't exist */
+		error = 0;
+		if (value == NULL)
+			goto out;
+	} else {
+		error = -EEXIST;
+		if (flags & XATTR_CREATE)
+			goto out;
+	}
+
+	/* Preferentially store the xattr as a SA for better performance */
+	if (zsb->z_use_sa && zp->z_is_sa &&
+	    (zsb->z_xattr_sa || (value == NULL && where & XATTR_IN_SA))) {
+		error = zpl_xattr_set_sa(ip, name, value, size, flags, cr);
+		if (error == 0) {
+			/*
+			 * Successfully put into SA, we need to clear the one
+			 * in dir.
+			 */
+			if (where & XATTR_IN_DIR)
+				zpl_xattr_set_dir(ip, name, NULL, 0, 0, cr);
+			goto out;
+		}
+	}
+
+	error = zpl_xattr_set_dir(ip, name, value, size, flags, cr);
+	/*
+	 * Successfully put into dir, we need to clear the one in SA.
+	 */
+	if (error == 0 && (where & XATTR_IN_SA))
+		zpl_xattr_set_sa(ip, name, NULL, 0, 0, cr);
+out:
+	rw_exit(&ITOZ(ip)->z_xattr_lock);
+	rrm_exit(&(zsb)->z_teardown_lock, FTAG);
+	spl_fstrans_unmark(cookie);
+	crfree(cr);
+	ASSERT3S(error, <=, 0);
+
+	return (error);
+}
+
+/*
+ * Extended user attributes
+ *
+ * "Extended user attributes may be assigned to files and directories for
+ * storing arbitrary additional information such as the mime type,
+ * character set or encoding of a file.  The access permissions for user
+ * attributes are defined by the file permission bits: read permission
+ * is required to retrieve the attribute value, and writer permission is
+ * required to change it.
+ *
+ * The file permission bits of regular files and directories are
+ * interpreted differently from the file permission bits of special
+ * files and symbolic links.  For regular files and directories the file
+ * permission bits define access to the file's contents, while for
+ * device special files they define access to the device described by
+ * the special file.  The file permissions of symbolic links are not
+ * used in access checks.  These differences would allow users to
+ * consume filesystem resources in a way not controllable by disk quotas
+ * for group or world writable special files and directories.
+ *
+ * For this reason, extended user attributes are allowed only for
+ * regular files and directories, and access to extended user attributes
+ * is restricted to the owner and to users with appropriate capabilities
+ * for directories with the sticky bit set (see the chmod(1) manual page
+ * for an explanation of the sticky bit)." - xattr(7)
+ *
+ * ZFS allows extended user attributes to be disabled administratively
+ * by setting the 'xattr=off' property on the dataset.
+ */
+static int
+__zpl_xattr_user_list(struct inode *ip, char *list, size_t list_size,
+    const char *name, size_t name_len)
+{
+	return (ITOZSB(ip)->z_flags & ZSB_XATTR);
+}
+ZPL_XATTR_LIST_WRAPPER(zpl_xattr_user_list);
+
+static int
+__zpl_xattr_user_get(struct inode *ip, const char *name,
+    void *value, size_t size)
+{
+	char *xattr_name;
+	int error;
+
+	if (strcmp(name, "") == 0)
+		return (-EINVAL);
+
+	if (!(ITOZSB(ip)->z_flags & ZSB_XATTR))
+		return (-EOPNOTSUPP);
+
+	xattr_name = kmem_asprintf("%s%s", XATTR_USER_PREFIX, name);
+	error = zpl_xattr_get(ip, xattr_name, value, size);
+	strfree(xattr_name);
+
+	return (error);
+}
+ZPL_XATTR_GET_WRAPPER(zpl_xattr_user_get);
+
+static int
+__zpl_xattr_user_set(struct inode *ip, const char *name,
+    const void *value, size_t size, int flags)
+{
+	char *xattr_name;
+	int error;
+
+	if (strcmp(name, "") == 0)
+		return (-EINVAL);
+
+	if (!(ITOZSB(ip)->z_flags & ZSB_XATTR))
+		return (-EOPNOTSUPP);
+
+	xattr_name = kmem_asprintf("%s%s", XATTR_USER_PREFIX, name);
+	error = zpl_xattr_set(ip, xattr_name, value, size, flags);
+	strfree(xattr_name);
+
+	return (error);
+}
+ZPL_XATTR_SET_WRAPPER(zpl_xattr_user_set);
+
+xattr_handler_t zpl_xattr_user_handler =
+{
+	.prefix	= XATTR_USER_PREFIX,
+	.list	= zpl_xattr_user_list,
+	.get	= zpl_xattr_user_get,
+	.set	= zpl_xattr_user_set,
+};
+
+/*
+ * Trusted extended attributes
+ *
+ * "Trusted extended attributes are visible and accessible only to
+ * processes that have the CAP_SYS_ADMIN capability.  Attributes in this
+ * class are used to implement mechanisms in user space (i.e., outside
+ * the kernel) which keep information in extended attributes to which
+ * ordinary processes should not have access." - xattr(7)
+ */
+static int
+__zpl_xattr_trusted_list(struct inode *ip, char *list, size_t list_size,
+    const char *name, size_t name_len)
+{
+	return (capable(CAP_SYS_ADMIN));
+}
+ZPL_XATTR_LIST_WRAPPER(zpl_xattr_trusted_list);
+
+static int
+__zpl_xattr_trusted_get(struct inode *ip, const char *name,
+    void *value, size_t size)
+{
+	char *xattr_name;
+	int error;
+
+	if (!capable(CAP_SYS_ADMIN))
+		return (-EACCES);
+
+	if (strcmp(name, "") == 0)
+		return (-EINVAL);
+
+	xattr_name = kmem_asprintf("%s%s", XATTR_TRUSTED_PREFIX, name);
+	error = zpl_xattr_get(ip, xattr_name, value, size);
+	strfree(xattr_name);
+
+	return (error);
+}
+ZPL_XATTR_GET_WRAPPER(zpl_xattr_trusted_get);
+
+static int
+__zpl_xattr_trusted_set(struct inode *ip, const char *name,
+    const void *value, size_t size, int flags)
+{
+	char *xattr_name;
+	int error;
+
+	if (!capable(CAP_SYS_ADMIN))
+		return (-EACCES);
+
+	if (strcmp(name, "") == 0)
+		return (-EINVAL);
+
+	xattr_name = kmem_asprintf("%s%s", XATTR_TRUSTED_PREFIX, name);
+	error = zpl_xattr_set(ip, xattr_name, value, size, flags);
+	strfree(xattr_name);
+
+	return (error);
+}
+ZPL_XATTR_SET_WRAPPER(zpl_xattr_trusted_set);
+
+xattr_handler_t zpl_xattr_trusted_handler =
+{
+	.prefix	= XATTR_TRUSTED_PREFIX,
+	.list	= zpl_xattr_trusted_list,
+	.get	= zpl_xattr_trusted_get,
+	.set	= zpl_xattr_trusted_set,
+};
+
+/*
+ * Extended security attributes
+ *
+ * "The security attribute namespace is used by kernel security modules,
+ * such as Security Enhanced Linux, and also to implement file
+ * capabilities (see capabilities(7)).  Read and write access
+ * permissions to security attributes depend on the policy implemented
+ * for each security attribute by the security module.  When no security
+ * module is loaded, all processes have read access to extended security
+ * attributes, and write access is limited to processes that have the
+ * CAP_SYS_ADMIN capability." - xattr(7)
+ */
+static int
+__zpl_xattr_security_list(struct inode *ip, char *list, size_t list_size,
+    const char *name, size_t name_len)
+{
+	return (1);
+}
+ZPL_XATTR_LIST_WRAPPER(zpl_xattr_security_list);
+
+static int
+__zpl_xattr_security_get(struct inode *ip, const char *name,
+    void *value, size_t size)
+{
+	char *xattr_name;
+	int error;
+
+	if (strcmp(name, "") == 0)
+		return (-EINVAL);
+
+	xattr_name = kmem_asprintf("%s%s", XATTR_SECURITY_PREFIX, name);
+	error = zpl_xattr_get(ip, xattr_name, value, size);
+	strfree(xattr_name);
+
+	return (error);
+}
+ZPL_XATTR_GET_WRAPPER(zpl_xattr_security_get);
+
+static int
+__zpl_xattr_security_set(struct inode *ip, const char *name,
+    const void *value, size_t size, int flags)
+{
+	char *xattr_name;
+	int error;
+
+	if (strcmp(name, "") == 0)
+		return (-EINVAL);
+
+	xattr_name = kmem_asprintf("%s%s", XATTR_SECURITY_PREFIX, name);
+	error = zpl_xattr_set(ip, xattr_name, value, size, flags);
+	strfree(xattr_name);
+
+	return (error);
+}
+ZPL_XATTR_SET_WRAPPER(zpl_xattr_security_set);
+
+#ifdef HAVE_CALLBACK_SECURITY_INODE_INIT_SECURITY
+static int
+__zpl_xattr_security_init(struct inode *ip, const struct xattr *xattrs,
+    void *fs_info)
+{
+	const struct xattr *xattr;
+	int error = 0;
+
+	for (xattr = xattrs; xattr->name != NULL; xattr++) {
+		error = __zpl_xattr_security_set(ip,
+		    xattr->name, xattr->value, xattr->value_len, 0);
+
+		if (error < 0)
+			break;
+	}
+
+	return (error);
+}
+
+int
+zpl_xattr_security_init(struct inode *ip, struct inode *dip,
+    const struct qstr *qstr)
+{
+	return security_inode_init_security(ip, dip, qstr,
+	    &__zpl_xattr_security_init, NULL);
+}
+
+#else
+int
+zpl_xattr_security_init(struct inode *ip, struct inode *dip,
+    const struct qstr *qstr)
+{
+	int error;
+	size_t len;
+	void *value;
+	char *name;
+
+	error = zpl_security_inode_init_security(ip, dip, qstr,
+	    &name, &value, &len);
+	if (error) {
+		if (error == -EOPNOTSUPP)
+			return (0);
+
+		return (error);
+	}
+
+	error = __zpl_xattr_security_set(ip, name, value, len, 0);
+
+	kfree(name);
+	kfree(value);
+
+	return (error);
+}
+#endif /* HAVE_CALLBACK_SECURITY_INODE_INIT_SECURITY */
+
+/*
+ * Security xattr namespace handlers.
+ */
+xattr_handler_t zpl_xattr_security_handler = {
+	.prefix	= XATTR_SECURITY_PREFIX,
+	.list	= zpl_xattr_security_list,
+	.get	= zpl_xattr_security_get,
+	.set	= zpl_xattr_security_set,
+};
+
+/*
+ * Extended system attributes
+ *
+ * "Extended system attributes are used by the kernel to store system
+ * objects such as Access Control Lists.  Read and write access permissions
+ * to system attributes depend on the policy implemented for each system
+ * attribute implemented by filesystems in the kernel." - xattr(7)
+ */
+#ifdef CONFIG_FS_POSIX_ACL
+int
+zpl_set_acl(struct inode *ip, int type, struct posix_acl *acl)
+{
+	struct super_block *sb = ITOZSB(ip)->z_sb;
+	char *name, *value = NULL;
+	int error = 0;
+	size_t size = 0;
+
+	if (S_ISLNK(ip->i_mode))
+		return (-EOPNOTSUPP);
+
+	switch (type) {
+	case ACL_TYPE_ACCESS:
+		name = XATTR_NAME_POSIX_ACL_ACCESS;
+		if (acl) {
+			zpl_equivmode_t mode = ip->i_mode;
+			error = posix_acl_equiv_mode(acl, &mode);
+			if (error < 0) {
+				return (error);
+			} else {
+				/*
+				 * The mode bits will have been set by
+				 * ->zfs_setattr()->zfs_acl_chmod_setattr()
+				 * using the ZFS ACL conversion.  If they
+				 * differ from the Posix ACL conversion dirty
+				 * the inode to write the Posix mode bits.
+				 */
+				if (ip->i_mode != mode) {
+					ip->i_mode = mode;
+					ip->i_ctime = current_fs_time(sb);
+					zfs_mark_inode_dirty(ip);
+				}
+
+				if (error == 0)
+					acl = NULL;
+			}
+		}
+		break;
+
+	case ACL_TYPE_DEFAULT:
+		name = XATTR_NAME_POSIX_ACL_DEFAULT;
+		if (!S_ISDIR(ip->i_mode))
+			return (acl ? -EACCES : 0);
+		break;
+
+	default:
+		return (-EINVAL);
+	}
+
+	if (acl) {
+		size = posix_acl_xattr_size(acl->a_count);
+		value = kmem_alloc(size, KM_SLEEP);
+
+		error = zpl_acl_to_xattr(acl, value, size);
+		if (error < 0) {
+			kmem_free(value, size);
+			return (error);
+		}
+	}
+
+	error = zpl_xattr_set(ip, name, value, size, 0);
+	if (value)
+		kmem_free(value, size);
+
+	if (!error) {
+		if (acl)
+			zpl_set_cached_acl(ip, type, acl);
+		else
+			zpl_forget_cached_acl(ip, type);
+	}
+
+	return (error);
+}
+
+struct posix_acl *
+zpl_get_acl(struct inode *ip, int type)
+{
+	struct posix_acl *acl;
+	void *value = NULL;
+	char *name;
+	int size;
+
+#ifdef HAVE_POSIX_ACL_CACHING
+	acl = get_cached_acl(ip, type);
+	if (acl != ACL_NOT_CACHED)
+		return (acl);
+#endif /* HAVE_POSIX_ACL_CACHING */
+
+	switch (type) {
+	case ACL_TYPE_ACCESS:
+		name = XATTR_NAME_POSIX_ACL_ACCESS;
+		break;
+	case ACL_TYPE_DEFAULT:
+		name = XATTR_NAME_POSIX_ACL_DEFAULT;
+		break;
+	default:
+		return (ERR_PTR(-EINVAL));
+	}
+
+	size = zpl_xattr_get(ip, name, NULL, 0);
+	if (size > 0) {
+		value = kmem_alloc(size, KM_SLEEP);
+		size = zpl_xattr_get(ip, name, value, size);
+	}
+
+	if (size > 0) {
+		acl = zpl_acl_from_xattr(value, size);
+	} else if (size == -ENODATA || size == -ENOSYS) {
+		acl = NULL;
+	} else {
+		acl = ERR_PTR(-EIO);
+	}
+
+	if (size > 0)
+		kmem_free(value, size);
+
+	if (!IS_ERR(acl))
+		zpl_set_cached_acl(ip, type, acl);
+
+	return (acl);
+}
+
+#if !defined(HAVE_GET_ACL)
+static int
+__zpl_check_acl(struct inode *ip, int mask)
+{
+	struct posix_acl *acl;
+	int error;
+
+	acl = zpl_get_acl(ip, ACL_TYPE_ACCESS);
+	if (IS_ERR(acl))
+		return (PTR_ERR(acl));
+
+	if (acl) {
+		error = posix_acl_permission(ip, acl, mask);
+		zpl_posix_acl_release(acl);
+		return (error);
+	}
+
+	return (-EAGAIN);
+}
+
+#if defined(HAVE_CHECK_ACL_WITH_FLAGS)
+int
+zpl_check_acl(struct inode *ip, int mask, unsigned int flags)
+{
+	return (__zpl_check_acl(ip, mask));
+}
+#elif defined(HAVE_CHECK_ACL)
+int
+zpl_check_acl(struct inode *ip, int mask)
+{
+	return (__zpl_check_acl(ip, mask));
+}
+#elif defined(HAVE_PERMISSION_WITH_NAMEIDATA)
+int
+zpl_permission(struct inode *ip, int mask, struct nameidata *nd)
+{
+	return (generic_permission(ip, mask, __zpl_check_acl));
+}
+#elif defined(HAVE_PERMISSION)
+int
+zpl_permission(struct inode *ip, int mask)
+{
+	return (generic_permission(ip, mask, __zpl_check_acl));
+}
+#endif /* HAVE_CHECK_ACL | HAVE_PERMISSION */
+#endif /* !HAVE_GET_ACL */
+
+int
+zpl_init_acl(struct inode *ip, struct inode *dir)
+{
+	struct posix_acl *acl = NULL;
+	int error = 0;
+
+	if (ITOZSB(ip)->z_acl_type != ZFS_ACLTYPE_POSIXACL)
+		return (0);
+
+	if (!S_ISLNK(ip->i_mode)) {
+		if (ITOZSB(ip)->z_acl_type == ZFS_ACLTYPE_POSIXACL) {
+			acl = zpl_get_acl(dir, ACL_TYPE_DEFAULT);
+			if (IS_ERR(acl))
+				return (PTR_ERR(acl));
+		}
+
+		if (!acl) {
+			ip->i_mode &= ~current_umask();
+			ip->i_ctime = current_fs_time(ITOZSB(ip)->z_sb);
+			zfs_mark_inode_dirty(ip);
+			return (0);
+		}
+	}
+
+	if ((ITOZSB(ip)->z_acl_type == ZFS_ACLTYPE_POSIXACL) && acl) {
+		umode_t mode;
+
+		if (S_ISDIR(ip->i_mode)) {
+			error = zpl_set_acl(ip, ACL_TYPE_DEFAULT, acl);
+			if (error)
+				goto out;
+		}
+
+		mode = ip->i_mode;
+		error = __posix_acl_create(&acl, GFP_KERNEL, &mode);
+		if (error >= 0) {
+			ip->i_mode = mode;
+			zfs_mark_inode_dirty(ip);
+			if (error > 0)
+				error = zpl_set_acl(ip, ACL_TYPE_ACCESS, acl);
+		}
+	}
+out:
+	zpl_posix_acl_release(acl);
+
+	return (error);
+}
+
+int
+zpl_chmod_acl(struct inode *ip)
+{
+	struct posix_acl *acl;
+	int error;
+
+	if (ITOZSB(ip)->z_acl_type != ZFS_ACLTYPE_POSIXACL)
+		return (0);
+
+	if (S_ISLNK(ip->i_mode))
+		return (-EOPNOTSUPP);
+
+	acl = zpl_get_acl(ip, ACL_TYPE_ACCESS);
+	if (IS_ERR(acl) || !acl)
+		return (PTR_ERR(acl));
+
+	error = __posix_acl_chmod(&acl, GFP_KERNEL, ip->i_mode);
+	if (!error)
+		error = zpl_set_acl(ip, ACL_TYPE_ACCESS, acl);
+
+	zpl_posix_acl_release(acl);
+
+	return (error);
+}
+
+static int
+__zpl_xattr_acl_list_access(struct inode *ip, char *list, size_t list_size,
+    const char *name, size_t name_len)
+{
+	char *xattr_name = XATTR_NAME_POSIX_ACL_ACCESS;
+	size_t xattr_size = sizeof (XATTR_NAME_POSIX_ACL_ACCESS);
+
+	if (ITOZSB(ip)->z_acl_type != ZFS_ACLTYPE_POSIXACL)
+		return (0);
+
+	if (list && xattr_size <= list_size)
+		memcpy(list, xattr_name, xattr_size);
+
+	return (xattr_size);
+}
+ZPL_XATTR_LIST_WRAPPER(zpl_xattr_acl_list_access);
+
+static int
+__zpl_xattr_acl_list_default(struct inode *ip, char *list, size_t list_size,
+    const char *name, size_t name_len)
+{
+	char *xattr_name = XATTR_NAME_POSIX_ACL_DEFAULT;
+	size_t xattr_size = sizeof (XATTR_NAME_POSIX_ACL_DEFAULT);
+
+	if (ITOZSB(ip)->z_acl_type != ZFS_ACLTYPE_POSIXACL)
+		return (0);
+
+	if (list && xattr_size <= list_size)
+		memcpy(list, xattr_name, xattr_size);
+
+	return (xattr_size);
+}
+ZPL_XATTR_LIST_WRAPPER(zpl_xattr_acl_list_default);
+
+static int
+__zpl_xattr_acl_get_access(struct inode *ip, const char *name,
+    void *buffer, size_t size)
+{
+	struct posix_acl *acl;
+	int type = ACL_TYPE_ACCESS;
+	int error;
+
+	if (strcmp(name, "") != 0)
+		return (-EINVAL);
+
+	if (ITOZSB(ip)->z_acl_type != ZFS_ACLTYPE_POSIXACL)
+		return (-EOPNOTSUPP);
+
+	acl = zpl_get_acl(ip, type);
+	if (IS_ERR(acl))
+		return (PTR_ERR(acl));
+	if (acl == NULL)
+		return (-ENODATA);
+
+	error = zpl_acl_to_xattr(acl, buffer, size);
+	zpl_posix_acl_release(acl);
+
+	return (error);
+}
+ZPL_XATTR_GET_WRAPPER(zpl_xattr_acl_get_access);
+
+static int
+__zpl_xattr_acl_get_default(struct inode *ip, const char *name,
+    void *buffer, size_t size)
+{
+	struct posix_acl *acl;
+	int type = ACL_TYPE_DEFAULT;
+	int error;
+
+	if (strcmp(name, "") != 0)
+		return (-EINVAL);
+
+	if (ITOZSB(ip)->z_acl_type != ZFS_ACLTYPE_POSIXACL)
+		return (-EOPNOTSUPP);
+
+	acl = zpl_get_acl(ip, type);
+	if (IS_ERR(acl))
+		return (PTR_ERR(acl));
+	if (acl == NULL)
+		return (-ENODATA);
+
+	error = zpl_acl_to_xattr(acl, buffer, size);
+	zpl_posix_acl_release(acl);
+
+	return (error);
+}
+ZPL_XATTR_GET_WRAPPER(zpl_xattr_acl_get_default);
+
+static int
+__zpl_xattr_acl_set_access(struct inode *ip, const char *name,
+    const void *value, size_t size, int flags)
+{
+	struct posix_acl *acl;
+	int type = ACL_TYPE_ACCESS;
+	int error = 0;
+
+	if (strcmp(name, "") != 0)
+		return (-EINVAL);
+
+	if (ITOZSB(ip)->z_acl_type != ZFS_ACLTYPE_POSIXACL)
+		return (-EOPNOTSUPP);
+
+	if (!zpl_inode_owner_or_capable(ip))
+		return (-EPERM);
+
+	if (value) {
+		acl = zpl_acl_from_xattr(value, size);
+		if (IS_ERR(acl))
+			return (PTR_ERR(acl));
+		else if (acl) {
+			error = posix_acl_valid(acl);
+			if (error) {
+				zpl_posix_acl_release(acl);
+				return (error);
+			}
+		}
+	} else {
+		acl = NULL;
+	}
+
+	error = zpl_set_acl(ip, type, acl);
+	zpl_posix_acl_release(acl);
+
+	return (error);
+}
+ZPL_XATTR_SET_WRAPPER(zpl_xattr_acl_set_access);
+
+static int
+__zpl_xattr_acl_set_default(struct inode *ip, const char *name,
+    const void *value, size_t size, int flags)
+{
+	struct posix_acl *acl;
+	int type = ACL_TYPE_DEFAULT;
+	int error = 0;
+
+	if (strcmp(name, "") != 0)
+		return (-EINVAL);
+
+	if (ITOZSB(ip)->z_acl_type != ZFS_ACLTYPE_POSIXACL)
+		return (-EOPNOTSUPP);
+
+	if (!zpl_inode_owner_or_capable(ip))
+		return (-EPERM);
+
+	if (value) {
+		acl = zpl_acl_from_xattr(value, size);
+		if (IS_ERR(acl))
+			return (PTR_ERR(acl));
+		else if (acl) {
+			error = posix_acl_valid(acl);
+			if (error) {
+				zpl_posix_acl_release(acl);
+				return (error);
+			}
+		}
+	} else {
+		acl = NULL;
+	}
+
+	error = zpl_set_acl(ip, type, acl);
+	zpl_posix_acl_release(acl);
+
+	return (error);
+}
+ZPL_XATTR_SET_WRAPPER(zpl_xattr_acl_set_default);
+
+/*
+ * ACL access xattr namespace handlers.
+ */
+xattr_handler_t zpl_xattr_acl_access_handler =
+{
+	.prefix	= XATTR_NAME_POSIX_ACL_ACCESS,
+	.list	= zpl_xattr_acl_list_access,
+	.get	= zpl_xattr_acl_get_access,
+	.set	= zpl_xattr_acl_set_access,
+#if defined(HAVE_XATTR_LIST_SIMPLE) || \
+    defined(HAVE_XATTR_LIST_DENTRY) || \
+    defined(HAVE_XATTR_LIST_HANDLER)
+	.flags	= ACL_TYPE_ACCESS,
+#endif
+};
+
+/*
+ * ACL default xattr namespace handlers.
+ */
+xattr_handler_t zpl_xattr_acl_default_handler =
+{
+	.prefix	= XATTR_NAME_POSIX_ACL_DEFAULT,
+	.list	= zpl_xattr_acl_list_default,
+	.get	= zpl_xattr_acl_get_default,
+	.set	= zpl_xattr_acl_set_default,
+#if defined(HAVE_XATTR_LIST_SIMPLE) || \
+    defined(HAVE_XATTR_LIST_DENTRY) || \
+    defined(HAVE_XATTR_LIST_HANDLER)
+	.flags	= ACL_TYPE_DEFAULT,
+#endif
+};
+
+#endif /* CONFIG_FS_POSIX_ACL */
+
+xattr_handler_t *zpl_xattr_handlers[] = {
+	&zpl_xattr_security_handler,
+	&zpl_xattr_trusted_handler,
+	&zpl_xattr_user_handler,
+#ifdef CONFIG_FS_POSIX_ACL
+	&zpl_xattr_acl_access_handler,
+	&zpl_xattr_acl_default_handler,
+#endif /* CONFIG_FS_POSIX_ACL */
+	NULL
+};
+
+static const struct xattr_handler *
+zpl_xattr_handler(const char *name)
+{
+	if (strncmp(name, XATTR_USER_PREFIX,
+	    XATTR_USER_PREFIX_LEN) == 0)
+		return (&zpl_xattr_user_handler);
+
+	if (strncmp(name, XATTR_TRUSTED_PREFIX,
+	    XATTR_TRUSTED_PREFIX_LEN) == 0)
+		return (&zpl_xattr_trusted_handler);
+
+	if (strncmp(name, XATTR_SECURITY_PREFIX,
+	    XATTR_SECURITY_PREFIX_LEN) == 0)
+		return (&zpl_xattr_security_handler);
+
+#ifdef CONFIG_FS_POSIX_ACL
+	if (strncmp(name, XATTR_NAME_POSIX_ACL_ACCESS,
+	    sizeof (XATTR_NAME_POSIX_ACL_ACCESS)) == 0)
+		return (&zpl_xattr_acl_access_handler);
+
+	if (strncmp(name, XATTR_NAME_POSIX_ACL_DEFAULT,
+	    sizeof (XATTR_NAME_POSIX_ACL_DEFAULT)) == 0)
+		return (&zpl_xattr_acl_default_handler);
+#endif /* CONFIG_FS_POSIX_ACL */
+
+	return (NULL);
+}
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/module/zfs/zrlock.c
@@ -0,0 +1,209 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014 by Delphix. All rights reserved.
+ */
+
+/*
+ * A Zero Reference Lock (ZRL) is a reference count that can lock out new
+ * references only when the count is zero and only without waiting if the count
+ * is not already zero. It is similar to a read-write lock in that it allows
+ * multiple readers and only a single writer, but it does not allow a writer to
+ * block while waiting for readers to exit, and therefore the question of
+ * reader/writer priority is moot (no WRWANT bit). Since the equivalent of
+ * rw_enter(&lock, RW_WRITER) is disallowed and only tryenter() is allowed, it
+ * is perfectly safe for the same reader to acquire the same lock multiple
+ * times. The fact that a ZRL is reentrant for readers (through multiple calls
+ * to zrl_add()) makes it convenient for determining whether something is
+ * actively referenced without the fuss of flagging lock ownership across
+ * function calls.
+ */
+#include <sys/zrlock.h>
+#include <sys/trace_zrlock.h>
+
+/*
+ * A ZRL can be locked only while there are zero references, so ZRL_LOCKED is
+ * treated as zero references.
+ */
+#define	ZRL_LOCKED	-1
+#define	ZRL_DESTROYED	-2
+
+void
+zrl_init(zrlock_t *zrl)
+{
+	mutex_init(&zrl->zr_mtx, NULL, MUTEX_DEFAULT, NULL);
+	zrl->zr_refcount = 0;
+	cv_init(&zrl->zr_cv, NULL, CV_DEFAULT, NULL);
+#ifdef	ZFS_DEBUG
+	zrl->zr_owner = NULL;
+	zrl->zr_caller = NULL;
+#endif
+}
+
+void
+zrl_destroy(zrlock_t *zrl)
+{
+	ASSERT0(zrl->zr_refcount);
+
+	mutex_destroy(&zrl->zr_mtx);
+	zrl->zr_refcount = ZRL_DESTROYED;
+	cv_destroy(&zrl->zr_cv);
+}
+
+void
+#ifdef	ZFS_DEBUG
+zrl_add_debug(zrlock_t *zrl, const char *zc)
+#else
+zrl_add(zrlock_t *zrl)
+#endif
+{
+	uint32_t n = (uint32_t)zrl->zr_refcount;
+
+	while (n != ZRL_LOCKED) {
+		uint32_t cas = atomic_cas_32(
+		    (uint32_t *)&zrl->zr_refcount, n, n + 1);
+		if (cas == n) {
+			ASSERT3S((int32_t)n, >=, 0);
+#ifdef	ZFS_DEBUG
+			if (zrl->zr_owner == curthread) {
+				DTRACE_PROBE2(zrlock__reentry,
+				    zrlock_t *, zrl, uint32_t, n);
+			}
+			zrl->zr_owner = curthread;
+			zrl->zr_caller = zc;
+#endif
+			return;
+		}
+		n = cas;
+	}
+
+	mutex_enter(&zrl->zr_mtx);
+	while (zrl->zr_refcount == ZRL_LOCKED) {
+		cv_wait(&zrl->zr_cv, &zrl->zr_mtx);
+	}
+	ASSERT3S(zrl->zr_refcount, >=, 0);
+	zrl->zr_refcount++;
+#ifdef	ZFS_DEBUG
+	zrl->zr_owner = curthread;
+	zrl->zr_caller = zc;
+#endif
+	mutex_exit(&zrl->zr_mtx);
+}
+
+void
+zrl_remove(zrlock_t *zrl)
+{
+	uint32_t n;
+
+#ifdef	ZFS_DEBUG
+	if (zrl->zr_owner == curthread) {
+		zrl->zr_owner = NULL;
+		zrl->zr_caller = NULL;
+	}
+#endif
+	n = atomic_dec_32_nv((uint32_t *)&zrl->zr_refcount);
+	ASSERT3S((int32_t)n, >=, 0);
+}
+
+int
+zrl_tryenter(zrlock_t *zrl)
+{
+	uint32_t n = (uint32_t)zrl->zr_refcount;
+
+	if (n == 0) {
+		uint32_t cas = atomic_cas_32(
+		    (uint32_t *)&zrl->zr_refcount, 0, ZRL_LOCKED);
+		if (cas == 0) {
+#ifdef	ZFS_DEBUG
+			ASSERT3P(zrl->zr_owner, ==, NULL);
+			zrl->zr_owner = curthread;
+#endif
+			return (1);
+		}
+	}
+
+	ASSERT3S((int32_t)n, >, ZRL_DESTROYED);
+
+	return (0);
+}
+
+void
+zrl_exit(zrlock_t *zrl)
+{
+	ASSERT3S(zrl->zr_refcount, ==, ZRL_LOCKED);
+
+	mutex_enter(&zrl->zr_mtx);
+#ifdef	ZFS_DEBUG
+	ASSERT3P(zrl->zr_owner, ==, curthread);
+	zrl->zr_owner = NULL;
+	membar_producer();	/* make sure the owner store happens first */
+#endif
+	zrl->zr_refcount = 0;
+	cv_broadcast(&zrl->zr_cv);
+	mutex_exit(&zrl->zr_mtx);
+}
+
+int
+zrl_refcount(zrlock_t *zrl)
+{
+	int n;
+
+	ASSERT3S(zrl->zr_refcount, >, ZRL_DESTROYED);
+
+	n = (int)zrl->zr_refcount;
+	return (n <= 0 ? 0 : n);
+}
+
+int
+zrl_is_zero(zrlock_t *zrl)
+{
+	ASSERT3S(zrl->zr_refcount, >, ZRL_DESTROYED);
+
+	return (zrl->zr_refcount <= 0);
+}
+
+int
+zrl_is_locked(zrlock_t *zrl)
+{
+	ASSERT3S(zrl->zr_refcount, >, ZRL_DESTROYED);
+
+	return (zrl->zr_refcount == ZRL_LOCKED);
+}
+
+#ifdef	ZFS_DEBUG
+kthread_t *
+zrl_owner(zrlock_t *zrl)
+{
+	return (zrl->zr_owner);
+}
+#endif
+
+#if defined(_KERNEL) && defined(HAVE_SPL)
+
+#ifdef ZFS_DEBUG
+EXPORT_SYMBOL(zrl_add_debug);
+#else
+EXPORT_SYMBOL(zrl_add);
+#endif
+EXPORT_SYMBOL(zrl_remove);
+
+#endif
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/module/zfs/zvol.c
@@ -0,0 +1,1938 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (C) 2008-2010 Lawrence Livermore National Security, LLC.
+ * Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ * Rewritten for Linux by Brian Behlendorf <behlendorf1@llnl.gov>.
+ * LLNL-CODE-403049.
+ *
+ * ZFS volume emulation driver.
+ *
+ * Makes a DMU object look like a volume of arbitrary size, up to 2^64 bytes.
+ * Volumes are accessed through the symbolic links named:
+ *
+ * /dev/<pool_name>/<dataset_name>
+ *
+ * Volumes are persistent through reboot and module load.  No user command
+ * needs to be run before opening and using a device.
+ *
+ * Copyright (c) 2016 Actifio, Inc. All rights reserved.
+ */
+
+#include <sys/dbuf.h>
+#include <sys/dmu_traverse.h>
+#include <sys/dsl_dataset.h>
+#include <sys/dsl_prop.h>
+#include <sys/dsl_dir.h>
+#include <sys/zap.h>
+#include <sys/zfeature.h>
+#include <sys/zil_impl.h>
+#include <sys/dmu_tx.h>
+#include <sys/zio.h>
+#include <sys/zfs_rlock.h>
+#include <sys/zfs_znode.h>
+#include <sys/spa_impl.h>
+#include <sys/zvol.h>
+#include <linux/blkdev_compat.h>
+
+unsigned int zvol_inhibit_dev = 0;
+unsigned int zvol_major = ZVOL_MAJOR;
+unsigned int zvol_prefetch_bytes = (128 * 1024);
+unsigned long zvol_max_discard_blocks = 16384;
+
+static kmutex_t zvol_state_lock;
+static list_t zvol_state_list;
+static char *zvol_tag = "zvol_tag";
+
+/*
+ * The in-core state of each volume.
+ */
+typedef struct zvol_state {
+	char			zv_name[MAXNAMELEN];	/* name */
+	uint64_t		zv_volsize;		/* advertised space */
+	uint64_t		zv_volblocksize;	/* volume block size */
+	objset_t		*zv_objset;	/* objset handle */
+	uint32_t		zv_flags;	/* ZVOL_* flags */
+	uint32_t		zv_open_count;	/* open counts */
+	uint32_t		zv_changed;	/* disk changed */
+	zilog_t			*zv_zilog;	/* ZIL handle */
+	znode_t			zv_znode;	/* for range locking */
+	dmu_buf_t		*zv_dbuf;	/* bonus handle */
+	dev_t			zv_dev;		/* device id */
+	struct gendisk		*zv_disk;	/* generic disk */
+	struct request_queue	*zv_queue;	/* request queue */
+	spinlock_t		zv_lock;	/* request queue lock */
+	list_node_t		zv_next;	/* next zvol_state_t linkage */
+} zvol_state_t;
+
+typedef enum {
+	ZVOL_ASYNC_CREATE_MINORS,
+	ZVOL_ASYNC_REMOVE_MINORS,
+	ZVOL_ASYNC_RENAME_MINORS,
+	ZVOL_ASYNC_SET_SNAPDEV,
+	ZVOL_ASYNC_MAX
+} zvol_async_op_t;
+
+typedef struct {
+	zvol_async_op_t op;
+	char pool[MAXNAMELEN];
+	char name1[MAXNAMELEN];
+	char name2[MAXNAMELEN];
+	zprop_source_t source;
+	uint64_t snapdev;
+} zvol_task_t;
+
+#define	ZVOL_RDONLY	0x1
+
+/*
+ * Find the next available range of ZVOL_MINORS minor numbers.  The
+ * zvol_state_list is kept in ascending minor order so we simply need
+ * to scan the list for the first gap in the sequence.  This allows us
+ * to recycle minor number as devices are created and removed.
+ */
+static int
+zvol_find_minor(unsigned *minor)
+{
+	zvol_state_t *zv;
+
+	*minor = 0;
+	ASSERT(MUTEX_HELD(&zvol_state_lock));
+	for (zv = list_head(&zvol_state_list); zv != NULL;
+	    zv = list_next(&zvol_state_list, zv), *minor += ZVOL_MINORS) {
+		if (MINOR(zv->zv_dev) != MINOR(*minor))
+			break;
+	}
+
+	/* All minors are in use */
+	if (*minor >= (1 << MINORBITS))
+		return (SET_ERROR(ENXIO));
+
+	return (0);
+}
+
+/*
+ * Find a zvol_state_t given the full major+minor dev_t.
+ */
+static zvol_state_t *
+zvol_find_by_dev(dev_t dev)
+{
+	zvol_state_t *zv;
+
+	ASSERT(MUTEX_HELD(&zvol_state_lock));
+	for (zv = list_head(&zvol_state_list); zv != NULL;
+	    zv = list_next(&zvol_state_list, zv)) {
+		if (zv->zv_dev == dev)
+			return (zv);
+	}
+
+	return (NULL);
+}
+
+/*
+ * Find a zvol_state_t given the name provided at zvol_alloc() time.
+ */
+static zvol_state_t *
+zvol_find_by_name(const char *name)
+{
+	zvol_state_t *zv;
+
+	ASSERT(MUTEX_HELD(&zvol_state_lock));
+	for (zv = list_head(&zvol_state_list); zv != NULL;
+	    zv = list_next(&zvol_state_list, zv)) {
+		if (strncmp(zv->zv_name, name, MAXNAMELEN) == 0)
+			return (zv);
+	}
+
+	return (NULL);
+}
+
+
+/*
+ * Given a path, return TRUE if path is a ZVOL.
+ */
+boolean_t
+zvol_is_zvol(const char *device)
+{
+	struct block_device *bdev;
+	unsigned int major;
+
+	bdev = lookup_bdev(device);
+	if (IS_ERR(bdev))
+		return (B_FALSE);
+
+	major = MAJOR(bdev->bd_dev);
+	bdput(bdev);
+
+	if (major == zvol_major)
+		return (B_TRUE);
+
+	return (B_FALSE);
+}
+
+/*
+ * ZFS_IOC_CREATE callback handles dmu zvol and zap object creation.
+ */
+void
+zvol_create_cb(objset_t *os, void *arg, cred_t *cr, dmu_tx_t *tx)
+{
+	zfs_creat_t *zct = arg;
+	nvlist_t *nvprops = zct->zct_props;
+	int error;
+	uint64_t volblocksize, volsize;
+
+	VERIFY(nvlist_lookup_uint64(nvprops,
+	    zfs_prop_to_name(ZFS_PROP_VOLSIZE), &volsize) == 0);
+	if (nvlist_lookup_uint64(nvprops,
+	    zfs_prop_to_name(ZFS_PROP_VOLBLOCKSIZE), &volblocksize) != 0)
+		volblocksize = zfs_prop_default_numeric(ZFS_PROP_VOLBLOCKSIZE);
+
+	/*
+	 * These properties must be removed from the list so the generic
+	 * property setting step won't apply to them.
+	 */
+	VERIFY(nvlist_remove_all(nvprops,
+	    zfs_prop_to_name(ZFS_PROP_VOLSIZE)) == 0);
+	(void) nvlist_remove_all(nvprops,
+	    zfs_prop_to_name(ZFS_PROP_VOLBLOCKSIZE));
+
+	error = dmu_object_claim(os, ZVOL_OBJ, DMU_OT_ZVOL, volblocksize,
+	    DMU_OT_NONE, 0, tx);
+	ASSERT(error == 0);
+
+	error = zap_create_claim(os, ZVOL_ZAP_OBJ, DMU_OT_ZVOL_PROP,
+	    DMU_OT_NONE, 0, tx);
+	ASSERT(error == 0);
+
+	error = zap_update(os, ZVOL_ZAP_OBJ, "size", 8, 1, &volsize, tx);
+	ASSERT(error == 0);
+}
+
+/*
+ * ZFS_IOC_OBJSET_STATS entry point.
+ */
+int
+zvol_get_stats(objset_t *os, nvlist_t *nv)
+{
+	int error;
+	dmu_object_info_t *doi;
+	uint64_t val;
+
+	error = zap_lookup(os, ZVOL_ZAP_OBJ, "size", 8, 1, &val);
+	if (error)
+		return (SET_ERROR(error));
+
+	dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_VOLSIZE, val);
+	doi = kmem_alloc(sizeof (dmu_object_info_t), KM_SLEEP);
+	error = dmu_object_info(os, ZVOL_OBJ, doi);
+
+	if (error == 0) {
+		dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_VOLBLOCKSIZE,
+		    doi->doi_data_block_size);
+	}
+
+	kmem_free(doi, sizeof (dmu_object_info_t));
+
+	return (SET_ERROR(error));
+}
+
+static void
+zvol_size_changed(zvol_state_t *zv, uint64_t volsize)
+{
+	struct block_device *bdev;
+
+	bdev = bdget_disk(zv->zv_disk, 0);
+	if (bdev == NULL)
+		return;
+/*
+ * 2.6.28 API change
+ * Added check_disk_size_change() helper function.
+ */
+#ifdef HAVE_CHECK_DISK_SIZE_CHANGE
+	set_capacity(zv->zv_disk, volsize >> 9);
+	zv->zv_volsize = volsize;
+	check_disk_size_change(zv->zv_disk, bdev);
+#else
+	zv->zv_volsize = volsize;
+	zv->zv_changed = 1;
+	(void) check_disk_change(bdev);
+#endif /* HAVE_CHECK_DISK_SIZE_CHANGE */
+
+	bdput(bdev);
+}
+
+/*
+ * Sanity check volume size.
+ */
+int
+zvol_check_volsize(uint64_t volsize, uint64_t blocksize)
+{
+	if (volsize == 0)
+		return (SET_ERROR(EINVAL));
+
+	if (volsize % blocksize != 0)
+		return (SET_ERROR(EINVAL));
+
+#ifdef _ILP32
+	if (volsize - 1 > MAXOFFSET_T)
+		return (SET_ERROR(EOVERFLOW));
+#endif
+	return (0);
+}
+
+/*
+ * Ensure the zap is flushed then inform the VFS of the capacity change.
+ */
+static int
+zvol_update_volsize(uint64_t volsize, objset_t *os)
+{
+	dmu_tx_t *tx;
+	int error;
+
+	ASSERT(MUTEX_HELD(&zvol_state_lock));
+
+	tx = dmu_tx_create(os);
+	dmu_tx_hold_zap(tx, ZVOL_ZAP_OBJ, TRUE, NULL);
+	error = dmu_tx_assign(tx, TXG_WAIT);
+	if (error) {
+		dmu_tx_abort(tx);
+		return (SET_ERROR(error));
+	}
+
+	error = zap_update(os, ZVOL_ZAP_OBJ, "size", 8, 1,
+	    &volsize, tx);
+	dmu_tx_commit(tx);
+
+	if (error == 0)
+		error = dmu_free_long_range(os,
+		    ZVOL_OBJ, volsize, DMU_OBJECT_END);
+
+	return (error);
+}
+
+static int
+zvol_update_live_volsize(zvol_state_t *zv, uint64_t volsize)
+{
+	zvol_size_changed(zv, volsize);
+
+	/*
+	 * We should post a event here describing the expansion.  However,
+	 * the zfs_ereport_post() interface doesn't nicely support posting
+	 * events for zvols, it assumes events relate to vdevs or zios.
+	 */
+
+	return (0);
+}
+
+/*
+ * Set ZFS_PROP_VOLSIZE set entry point.
+ */
+int
+zvol_set_volsize(const char *name, uint64_t volsize)
+{
+	zvol_state_t *zv = NULL;
+	objset_t *os = NULL;
+	int error;
+	dmu_object_info_t *doi;
+	uint64_t readonly;
+	boolean_t owned = B_FALSE;
+
+	error = dsl_prop_get_integer(name,
+	    zfs_prop_to_name(ZFS_PROP_READONLY), &readonly, NULL);
+	if (error != 0)
+		return (SET_ERROR(error));
+	if (readonly)
+		return (SET_ERROR(EROFS));
+
+	mutex_enter(&zvol_state_lock);
+	zv = zvol_find_by_name(name);
+
+	if (zv == NULL || zv->zv_objset == NULL) {
+		if ((error = dmu_objset_own(name, DMU_OST_ZVOL, B_FALSE,
+		    FTAG, &os)) != 0) {
+			mutex_exit(&zvol_state_lock);
+			return (SET_ERROR(error));
+		}
+		owned = B_TRUE;
+		if (zv != NULL)
+			zv->zv_objset = os;
+	} else {
+		os = zv->zv_objset;
+	}
+
+	doi = kmem_alloc(sizeof (dmu_object_info_t), KM_SLEEP);
+
+	if ((error = dmu_object_info(os, ZVOL_OBJ, doi)) ||
+	    (error = zvol_check_volsize(volsize, doi->doi_data_block_size)))
+		goto out;
+
+	error = zvol_update_volsize(volsize, os);
+	kmem_free(doi, sizeof (dmu_object_info_t));
+
+	if (error == 0 && zv != NULL)
+		error = zvol_update_live_volsize(zv, volsize);
+out:
+	if (owned) {
+		dmu_objset_disown(os, FTAG);
+		if (zv != NULL)
+			zv->zv_objset = NULL;
+	}
+	mutex_exit(&zvol_state_lock);
+	return (error);
+}
+
+/*
+ * Sanity check volume block size.
+ */
+int
+zvol_check_volblocksize(const char *name, uint64_t volblocksize)
+{
+	/* Record sizes above 128k need the feature to be enabled */
+	if (volblocksize > SPA_OLD_MAXBLOCKSIZE) {
+		spa_t *spa;
+		int error;
+
+		if ((error = spa_open(name, &spa, FTAG)) != 0)
+			return (error);
+
+		if (!spa_feature_is_enabled(spa, SPA_FEATURE_LARGE_BLOCKS)) {
+			spa_close(spa, FTAG);
+			return (SET_ERROR(ENOTSUP));
+		}
+
+		/*
+		 * We don't allow setting the property above 1MB,
+		 * unless the tunable has been changed.
+		 */
+		if (volblocksize > zfs_max_recordsize)
+			return (SET_ERROR(EDOM));
+
+		spa_close(spa, FTAG);
+	}
+
+	if (volblocksize < SPA_MINBLOCKSIZE ||
+	    volblocksize > SPA_MAXBLOCKSIZE ||
+	    !ISP2(volblocksize))
+		return (SET_ERROR(EDOM));
+
+	return (0);
+}
+
+/*
+ * Set ZFS_PROP_VOLBLOCKSIZE set entry point.
+ */
+int
+zvol_set_volblocksize(const char *name, uint64_t volblocksize)
+{
+	zvol_state_t *zv;
+	dmu_tx_t *tx;
+	int error;
+
+	mutex_enter(&zvol_state_lock);
+
+	zv = zvol_find_by_name(name);
+	if (zv == NULL) {
+		error = SET_ERROR(ENXIO);
+		goto out;
+	}
+
+	if (zv->zv_flags & ZVOL_RDONLY) {
+		error = SET_ERROR(EROFS);
+		goto out;
+	}
+
+	tx = dmu_tx_create(zv->zv_objset);
+	dmu_tx_hold_bonus(tx, ZVOL_OBJ);
+	error = dmu_tx_assign(tx, TXG_WAIT);
+	if (error) {
+		dmu_tx_abort(tx);
+	} else {
+		error = dmu_object_set_blocksize(zv->zv_objset, ZVOL_OBJ,
+		    volblocksize, 0, tx);
+		if (error == ENOTSUP)
+			error = SET_ERROR(EBUSY);
+		dmu_tx_commit(tx);
+		if (error == 0)
+			zv->zv_volblocksize = volblocksize;
+	}
+out:
+	mutex_exit(&zvol_state_lock);
+
+	return (SET_ERROR(error));
+}
+
+/*
+ * Replay a TX_WRITE ZIL transaction that didn't get committed
+ * after a system failure
+ */
+static int
+zvol_replay_write(zvol_state_t *zv, lr_write_t *lr, boolean_t byteswap)
+{
+	objset_t *os = zv->zv_objset;
+	char *data = (char *)(lr + 1);	/* data follows lr_write_t */
+	uint64_t off = lr->lr_offset;
+	uint64_t len = lr->lr_length;
+	dmu_tx_t *tx;
+	int error;
+
+	if (byteswap)
+		byteswap_uint64_array(lr, sizeof (*lr));
+
+	tx = dmu_tx_create(os);
+	dmu_tx_hold_write(tx, ZVOL_OBJ, off, len);
+	error = dmu_tx_assign(tx, TXG_WAIT);
+	if (error) {
+		dmu_tx_abort(tx);
+	} else {
+		dmu_write(os, ZVOL_OBJ, off, len, data, tx);
+		dmu_tx_commit(tx);
+	}
+
+	return (SET_ERROR(error));
+}
+
+static int
+zvol_replay_err(zvol_state_t *zv, lr_t *lr, boolean_t byteswap)
+{
+	return (SET_ERROR(ENOTSUP));
+}
+
+/*
+ * Callback vectors for replaying records.
+ * Only TX_WRITE is needed for zvol.
+ */
+zil_replay_func_t zvol_replay_vector[TX_MAX_TYPE] = {
+	(zil_replay_func_t)zvol_replay_err,	/* no such transaction type */
+	(zil_replay_func_t)zvol_replay_err,	/* TX_CREATE */
+	(zil_replay_func_t)zvol_replay_err,	/* TX_MKDIR */
+	(zil_replay_func_t)zvol_replay_err,	/* TX_MKXATTR */
+	(zil_replay_func_t)zvol_replay_err,	/* TX_SYMLINK */
+	(zil_replay_func_t)zvol_replay_err,	/* TX_REMOVE */
+	(zil_replay_func_t)zvol_replay_err,	/* TX_RMDIR */
+	(zil_replay_func_t)zvol_replay_err,	/* TX_LINK */
+	(zil_replay_func_t)zvol_replay_err,	/* TX_RENAME */
+	(zil_replay_func_t)zvol_replay_write,	/* TX_WRITE */
+	(zil_replay_func_t)zvol_replay_err,	/* TX_TRUNCATE */
+	(zil_replay_func_t)zvol_replay_err,	/* TX_SETATTR */
+	(zil_replay_func_t)zvol_replay_err,	/* TX_ACL */
+};
+
+/*
+ * zvol_log_write() handles synchronous writes using TX_WRITE ZIL transactions.
+ *
+ * We store data in the log buffers if it's small enough.
+ * Otherwise we will later flush the data out via dmu_sync().
+ */
+ssize_t zvol_immediate_write_sz = 32768;
+
+static void
+zvol_log_write(zvol_state_t *zv, dmu_tx_t *tx, uint64_t offset,
+    uint64_t size, int sync)
+{
+	uint32_t blocksize = zv->zv_volblocksize;
+	zilog_t *zilog = zv->zv_zilog;
+	boolean_t slogging;
+	ssize_t immediate_write_sz;
+
+	if (zil_replaying(zilog, tx))
+		return;
+
+	immediate_write_sz = (zilog->zl_logbias == ZFS_LOGBIAS_THROUGHPUT)
+		? 0 : zvol_immediate_write_sz;
+	slogging = spa_has_slogs(zilog->zl_spa) &&
+		(zilog->zl_logbias == ZFS_LOGBIAS_LATENCY);
+
+	while (size) {
+		itx_t *itx;
+		lr_write_t *lr;
+		ssize_t len;
+		itx_wr_state_t write_state;
+
+		/*
+		 * Unlike zfs_log_write() we can be called with
+		 * up to DMU_MAX_ACCESS/2 (5MB) writes.
+		 */
+		if (blocksize > immediate_write_sz && !slogging &&
+		    size >= blocksize && offset % blocksize == 0) {
+			write_state = WR_INDIRECT; /* uses dmu_sync */
+			len = blocksize;
+		} else if (sync) {
+			write_state = WR_COPIED;
+			len = MIN(ZIL_MAX_LOG_DATA, size);
+		} else {
+			write_state = WR_NEED_COPY;
+			len = MIN(ZIL_MAX_LOG_DATA, size);
+		}
+
+		itx = zil_itx_create(TX_WRITE, sizeof (*lr) +
+		    (write_state == WR_COPIED ? len : 0));
+		lr = (lr_write_t *)&itx->itx_lr;
+		if (write_state == WR_COPIED && dmu_read(zv->zv_objset,
+		    ZVOL_OBJ, offset, len, lr+1, DMU_READ_NO_PREFETCH) != 0) {
+			zil_itx_destroy(itx);
+			itx = zil_itx_create(TX_WRITE, sizeof (*lr));
+			lr = (lr_write_t *)&itx->itx_lr;
+			write_state = WR_NEED_COPY;
+		}
+
+		itx->itx_wr_state = write_state;
+		if (write_state == WR_NEED_COPY)
+			itx->itx_sod += len;
+		lr->lr_foid = ZVOL_OBJ;
+		lr->lr_offset = offset;
+		lr->lr_length = len;
+		lr->lr_blkoff = 0;
+		BP_ZERO(&lr->lr_blkptr);
+
+		itx->itx_private = zv;
+		itx->itx_sync = sync;
+
+		(void) zil_itx_assign(zilog, itx, tx);
+
+		offset += len;
+		size -= len;
+	}
+}
+
+static int
+zvol_write(struct bio *bio)
+{
+	zvol_state_t *zv = bio->bi_bdev->bd_disk->private_data;
+	uint64_t offset = BIO_BI_SECTOR(bio) << 9;
+	uint64_t size = BIO_BI_SIZE(bio);
+	int error = 0;
+	dmu_tx_t *tx;
+	rl_t *rl;
+
+	ASSERT(zv && zv->zv_open_count > 0);
+
+	if (bio->bi_rw & VDEV_REQ_FLUSH)
+		zil_commit(zv->zv_zilog, ZVOL_OBJ);
+
+	/*
+	 * Some requests are just for flush and nothing else.
+	 */
+	if (size == 0)
+		goto out;
+
+	rl = zfs_range_lock(&zv->zv_znode, offset, size, RL_WRITER);
+
+	tx = dmu_tx_create(zv->zv_objset);
+	dmu_tx_hold_write(tx, ZVOL_OBJ, offset, size);
+
+	/* This will only fail for ENOSPC */
+	error = dmu_tx_assign(tx, TXG_WAIT);
+	if (error) {
+		dmu_tx_abort(tx);
+		zfs_range_unlock(rl);
+		goto out;
+	}
+
+	error = dmu_write_bio(zv->zv_objset, ZVOL_OBJ, bio, tx);
+	if (error == 0)
+		zvol_log_write(zv, tx, offset, size,
+		    !!(bio->bi_rw & VDEV_REQ_FUA));
+
+	dmu_tx_commit(tx);
+	zfs_range_unlock(rl);
+
+	if ((bio->bi_rw & VDEV_REQ_FUA) ||
+	    zv->zv_objset->os_sync == ZFS_SYNC_ALWAYS)
+		zil_commit(zv->zv_zilog, ZVOL_OBJ);
+
+out:
+	return (error);
+}
+
+static int
+zvol_discard(struct bio *bio)
+{
+	zvol_state_t *zv = bio->bi_bdev->bd_disk->private_data;
+	uint64_t start = BIO_BI_SECTOR(bio) << 9;
+	uint64_t size = BIO_BI_SIZE(bio);
+	uint64_t end = start + size;
+	int error;
+	rl_t *rl;
+
+	ASSERT(zv && zv->zv_open_count > 0);
+
+	if (end > zv->zv_volsize)
+		return (SET_ERROR(EIO));
+
+	/*
+	 * Align the request to volume block boundaries when REQ_SECURE is
+	 * available, but not requested. If we don't, then this will force
+	 * dnode_free_range() to zero out the unaligned parts, which is slow
+	 * (read-modify-write) and useless since we are not freeing any space
+	 * by doing so. Kernels that do not support REQ_SECURE (2.6.32 through
+	 * 2.6.35) will not receive this optimization.
+	 */
+#ifdef REQ_SECURE
+	if (!(bio->bi_rw & REQ_SECURE)) {
+		start = P2ROUNDUP(start, zv->zv_volblocksize);
+		end = P2ALIGN(end, zv->zv_volblocksize);
+		size = end - start;
+	}
+#endif
+
+	if (start >= end)
+		return (0);
+
+	rl = zfs_range_lock(&zv->zv_znode, start, size, RL_WRITER);
+
+	error = dmu_free_long_range(zv->zv_objset, ZVOL_OBJ, start, size);
+
+	/*
+	 * TODO: maybe we should add the operation to the log.
+	 */
+
+	zfs_range_unlock(rl);
+
+	return (error);
+}
+
+static int
+zvol_read(struct bio *bio)
+{
+	zvol_state_t *zv = bio->bi_bdev->bd_disk->private_data;
+	uint64_t offset = BIO_BI_SECTOR(bio) << 9;
+	uint64_t len = BIO_BI_SIZE(bio);
+	int error;
+	rl_t *rl;
+
+	ASSERT(zv && zv->zv_open_count > 0);
+
+	if (len == 0)
+		return (0);
+
+	rl = zfs_range_lock(&zv->zv_znode, offset, len, RL_READER);
+
+	error = dmu_read_bio(zv->zv_objset, ZVOL_OBJ, bio);
+
+	zfs_range_unlock(rl);
+
+	/* convert checksum errors into IO errors */
+	if (error == ECKSUM)
+		error = SET_ERROR(EIO);
+
+	return (error);
+}
+
+static MAKE_REQUEST_FN_RET
+zvol_request(struct request_queue *q, struct bio *bio)
+{
+	zvol_state_t *zv = q->queuedata;
+	fstrans_cookie_t cookie = spl_fstrans_mark();
+	uint64_t offset = BIO_BI_SECTOR(bio);
+	unsigned int sectors = bio_sectors(bio);
+	int rw = bio_data_dir(bio);
+#ifdef HAVE_GENERIC_IO_ACCT
+	unsigned long start = jiffies;
+#endif
+	int error = 0;
+
+	if (bio_has_data(bio) && offset + sectors >
+	    get_capacity(zv->zv_disk)) {
+		printk(KERN_INFO
+		    "%s: bad access: block=%llu, count=%lu\n",
+		    zv->zv_disk->disk_name,
+		    (long long unsigned)offset,
+		    (long unsigned)sectors);
+		error = SET_ERROR(EIO);
+		goto out1;
+	}
+
+	generic_start_io_acct(rw, sectors, &zv->zv_disk->part0);
+
+	if (rw == WRITE) {
+		if (unlikely(zv->zv_flags & ZVOL_RDONLY)) {
+			error = SET_ERROR(EROFS);
+			goto out2;
+		}
+
+		if (bio->bi_rw & VDEV_REQ_DISCARD) {
+			error = zvol_discard(bio);
+			goto out2;
+		}
+
+		error = zvol_write(bio);
+	} else
+		error = zvol_read(bio);
+
+out2:
+	generic_end_io_acct(rw, &zv->zv_disk->part0, start);
+out1:
+	BIO_END_IO(bio, -error);
+	spl_fstrans_unmark(cookie);
+#ifdef HAVE_MAKE_REQUEST_FN_RET_INT
+	return (0);
+#elif defined(HAVE_MAKE_REQUEST_FN_RET_QC)
+	return (BLK_QC_T_NONE);
+#endif
+}
+
+static void
+zvol_get_done(zgd_t *zgd, int error)
+{
+	if (zgd->zgd_db)
+		dmu_buf_rele(zgd->zgd_db, zgd);
+
+	zfs_range_unlock(zgd->zgd_rl);
+
+	if (error == 0 && zgd->zgd_bp)
+		zil_add_block(zgd->zgd_zilog, zgd->zgd_bp);
+
+	kmem_free(zgd, sizeof (zgd_t));
+}
+
+/*
+ * Get data to generate a TX_WRITE intent log record.
+ */
+static int
+zvol_get_data(void *arg, lr_write_t *lr, char *buf, zio_t *zio)
+{
+	zvol_state_t *zv = arg;
+	objset_t *os = zv->zv_objset;
+	uint64_t object = ZVOL_OBJ;
+	uint64_t offset = lr->lr_offset;
+	uint64_t size = lr->lr_length;
+	blkptr_t *bp = &lr->lr_blkptr;
+	dmu_buf_t *db;
+	zgd_t *zgd;
+	int error;
+
+	ASSERT(zio != NULL);
+	ASSERT(size != 0);
+
+	zgd = (zgd_t *)kmem_zalloc(sizeof (zgd_t), KM_SLEEP);
+	zgd->zgd_zilog = zv->zv_zilog;
+	zgd->zgd_rl = zfs_range_lock(&zv->zv_znode, offset, size, RL_READER);
+
+	/*
+	 * Write records come in two flavors: immediate and indirect.
+	 * For small writes it's cheaper to store the data with the
+	 * log record (immediate); for large writes it's cheaper to
+	 * sync the data and get a pointer to it (indirect) so that
+	 * we don't have to write the data twice.
+	 */
+	if (buf != NULL) { /* immediate write */
+		error = dmu_read(os, object, offset, size, buf,
+		    DMU_READ_NO_PREFETCH);
+	} else {
+		size = zv->zv_volblocksize;
+		offset = P2ALIGN_TYPED(offset, size, uint64_t);
+		error = dmu_buf_hold(os, object, offset, zgd, &db,
+		    DMU_READ_NO_PREFETCH);
+		if (error == 0) {
+			blkptr_t *obp = dmu_buf_get_blkptr(db);
+			if (obp) {
+				ASSERT(BP_IS_HOLE(bp));
+				*bp = *obp;
+			}
+
+			zgd->zgd_db = db;
+			zgd->zgd_bp = &lr->lr_blkptr;
+
+			ASSERT(db != NULL);
+			ASSERT(db->db_offset == offset);
+			ASSERT(db->db_size == size);
+
+			error = dmu_sync(zio, lr->lr_common.lrc_txg,
+			    zvol_get_done, zgd);
+
+			if (error == 0)
+				return (0);
+		}
+	}
+
+	zvol_get_done(zgd, error);
+
+	return (SET_ERROR(error));
+}
+
+/*
+ * The zvol_state_t's are inserted in increasing MINOR(dev_t) order.
+ */
+static void
+zvol_insert(zvol_state_t *zv_insert)
+{
+	zvol_state_t *zv = NULL;
+
+	ASSERT(MUTEX_HELD(&zvol_state_lock));
+	ASSERT3U(MINOR(zv_insert->zv_dev) & ZVOL_MINOR_MASK, ==, 0);
+	for (zv = list_head(&zvol_state_list); zv != NULL;
+	    zv = list_next(&zvol_state_list, zv)) {
+		if (MINOR(zv->zv_dev) > MINOR(zv_insert->zv_dev))
+			break;
+	}
+
+	list_insert_before(&zvol_state_list, zv, zv_insert);
+}
+
+/*
+ * Simply remove the zvol from to list of zvols.
+ */
+static void
+zvol_remove(zvol_state_t *zv_remove)
+{
+	ASSERT(MUTEX_HELD(&zvol_state_lock));
+	list_remove(&zvol_state_list, zv_remove);
+}
+
+static int
+zvol_first_open(zvol_state_t *zv)
+{
+	objset_t *os;
+	uint64_t volsize;
+	int error;
+	uint64_t ro;
+
+	/* lie and say we're read-only */
+	error = dmu_objset_own(zv->zv_name, DMU_OST_ZVOL, 1, zvol_tag, &os);
+	if (error)
+		return (SET_ERROR(-error));
+
+	zv->zv_objset = os;
+
+	error = dsl_prop_get_integer(zv->zv_name, "readonly", &ro, NULL);
+	if (error)
+		goto out_owned;
+
+	error = zap_lookup(os, ZVOL_ZAP_OBJ, "size", 8, 1, &volsize);
+	if (error)
+		goto out_owned;
+
+	error = dmu_bonus_hold(os, ZVOL_OBJ, zvol_tag, &zv->zv_dbuf);
+	if (error)
+		goto out_owned;
+
+	set_capacity(zv->zv_disk, volsize >> 9);
+	zv->zv_volsize = volsize;
+	zv->zv_zilog = zil_open(os, zvol_get_data);
+
+	if (ro || dmu_objset_is_snapshot(os) ||
+	    !spa_writeable(dmu_objset_spa(os))) {
+		set_disk_ro(zv->zv_disk, 1);
+		zv->zv_flags |= ZVOL_RDONLY;
+	} else {
+		set_disk_ro(zv->zv_disk, 0);
+		zv->zv_flags &= ~ZVOL_RDONLY;
+	}
+
+out_owned:
+	if (error) {
+		dmu_objset_disown(os, zvol_tag);
+		zv->zv_objset = NULL;
+	}
+
+	return (SET_ERROR(-error));
+}
+
+static void
+zvol_last_close(zvol_state_t *zv)
+{
+	zil_close(zv->zv_zilog);
+	zv->zv_zilog = NULL;
+
+	dmu_buf_rele(zv->zv_dbuf, zvol_tag);
+	zv->zv_dbuf = NULL;
+
+	/*
+	 * Evict cached data
+	 */
+	if (dsl_dataset_is_dirty(dmu_objset_ds(zv->zv_objset)) &&
+	    !(zv->zv_flags & ZVOL_RDONLY))
+		txg_wait_synced(dmu_objset_pool(zv->zv_objset), 0);
+	(void) dmu_objset_evict_dbufs(zv->zv_objset);
+
+	dmu_objset_disown(zv->zv_objset, zvol_tag);
+	zv->zv_objset = NULL;
+}
+
+static int
+zvol_open(struct block_device *bdev, fmode_t flag)
+{
+	zvol_state_t *zv;
+	int error = 0, drop_mutex = 0;
+
+	/*
+	 * If the caller is already holding the mutex do not take it
+	 * again, this will happen as part of zvol_create_minor_impl().
+	 * Once add_disk() is called the device is live and the kernel
+	 * will attempt to open it to read the partition information.
+	 */
+	if (!mutex_owned(&zvol_state_lock)) {
+		mutex_enter(&zvol_state_lock);
+		drop_mutex = 1;
+	}
+
+	/*
+	 * Obtain a copy of private_data under the lock to make sure
+	 * that either the result of zvol_freeg() setting
+	 * bdev->bd_disk->private_data to NULL is observed, or zvol_free()
+	 * is not called on this zv because of the positive zv_open_count.
+	 */
+	zv = bdev->bd_disk->private_data;
+	if (zv == NULL) {
+		error = -ENXIO;
+		goto out_mutex;
+	}
+
+	if (zv->zv_open_count == 0) {
+		error = zvol_first_open(zv);
+		if (error)
+			goto out_mutex;
+	}
+
+	if ((flag & FMODE_WRITE) && (zv->zv_flags & ZVOL_RDONLY)) {
+		error = -EROFS;
+		goto out_open_count;
+	}
+
+	zv->zv_open_count++;
+
+	check_disk_change(bdev);
+
+out_open_count:
+	if (zv->zv_open_count == 0)
+		zvol_last_close(zv);
+
+out_mutex:
+	if (drop_mutex)
+		mutex_exit(&zvol_state_lock);
+
+	return (SET_ERROR(error));
+}
+
+#ifdef HAVE_BLOCK_DEVICE_OPERATIONS_RELEASE_VOID
+static void
+#else
+static int
+#endif
+zvol_release(struct gendisk *disk, fmode_t mode)
+{
+	zvol_state_t *zv = disk->private_data;
+	int drop_mutex = 0;
+
+	ASSERT(zv && zv->zv_open_count > 0);
+
+	if (!mutex_owned(&zvol_state_lock)) {
+		mutex_enter(&zvol_state_lock);
+		drop_mutex = 1;
+	}
+
+	zv->zv_open_count--;
+	if (zv->zv_open_count == 0)
+		zvol_last_close(zv);
+
+	if (drop_mutex)
+		mutex_exit(&zvol_state_lock);
+
+#ifndef HAVE_BLOCK_DEVICE_OPERATIONS_RELEASE_VOID
+	return (0);
+#endif
+}
+
+static int
+zvol_ioctl(struct block_device *bdev, fmode_t mode,
+    unsigned int cmd, unsigned long arg)
+{
+	zvol_state_t *zv = bdev->bd_disk->private_data;
+	int error = 0;
+
+	ASSERT(zv && zv->zv_open_count > 0);
+
+	switch (cmd) {
+	case BLKFLSBUF:
+		zil_commit(zv->zv_zilog, ZVOL_OBJ);
+		break;
+	case BLKZNAME:
+		error = copy_to_user((void *)arg, zv->zv_name, MAXNAMELEN);
+		break;
+
+	default:
+		error = -ENOTTY;
+		break;
+
+	}
+
+	return (SET_ERROR(error));
+}
+
+#ifdef CONFIG_COMPAT
+static int
+zvol_compat_ioctl(struct block_device *bdev, fmode_t mode,
+    unsigned cmd, unsigned long arg)
+{
+	return (zvol_ioctl(bdev, mode, cmd, arg));
+}
+#else
+#define	zvol_compat_ioctl	NULL
+#endif
+
+static int zvol_media_changed(struct gendisk *disk)
+{
+	zvol_state_t *zv = disk->private_data;
+
+	ASSERT(zv && zv->zv_open_count > 0);
+
+	return (zv->zv_changed);
+}
+
+static int zvol_revalidate_disk(struct gendisk *disk)
+{
+	zvol_state_t *zv = disk->private_data;
+
+	ASSERT(zv && zv->zv_open_count > 0);
+
+	zv->zv_changed = 0;
+	set_capacity(zv->zv_disk, zv->zv_volsize >> 9);
+
+	return (0);
+}
+
+/*
+ * Provide a simple virtual geometry for legacy compatibility.  For devices
+ * smaller than 1 MiB a small head and sector count is used to allow very
+ * tiny devices.  For devices over 1 Mib a standard head and sector count
+ * is used to keep the cylinders count reasonable.
+ */
+static int
+zvol_getgeo(struct block_device *bdev, struct hd_geometry *geo)
+{
+	zvol_state_t *zv = bdev->bd_disk->private_data;
+	sector_t sectors;
+
+	ASSERT(zv && zv->zv_open_count > 0);
+
+	sectors = get_capacity(zv->zv_disk);
+
+	if (sectors > 2048) {
+		geo->heads = 16;
+		geo->sectors = 63;
+	} else {
+		geo->heads = 2;
+		geo->sectors = 4;
+	}
+
+	geo->start = 0;
+	geo->cylinders = sectors / (geo->heads * geo->sectors);
+
+	return (0);
+}
+
+static struct kobject *
+zvol_probe(dev_t dev, int *part, void *arg)
+{
+	zvol_state_t *zv;
+	struct kobject *kobj;
+
+	mutex_enter(&zvol_state_lock);
+	zv = zvol_find_by_dev(dev);
+	kobj = zv ? get_disk(zv->zv_disk) : NULL;
+	mutex_exit(&zvol_state_lock);
+
+	return (kobj);
+}
+
+#ifdef HAVE_BDEV_BLOCK_DEVICE_OPERATIONS
+static struct block_device_operations zvol_ops = {
+	.open			= zvol_open,
+	.release		= zvol_release,
+	.ioctl			= zvol_ioctl,
+	.compat_ioctl		= zvol_compat_ioctl,
+	.media_changed		= zvol_media_changed,
+	.revalidate_disk	= zvol_revalidate_disk,
+	.getgeo			= zvol_getgeo,
+	.owner			= THIS_MODULE,
+};
+
+#else /* HAVE_BDEV_BLOCK_DEVICE_OPERATIONS */
+
+static int
+zvol_open_by_inode(struct inode *inode, struct file *file)
+{
+	return (zvol_open(inode->i_bdev, file->f_mode));
+}
+
+static int
+zvol_release_by_inode(struct inode *inode, struct file *file)
+{
+	return (zvol_release(inode->i_bdev->bd_disk, file->f_mode));
+}
+
+static int
+zvol_ioctl_by_inode(struct inode *inode, struct file *file,
+    unsigned int cmd, unsigned long arg)
+{
+	if (file == NULL || inode == NULL)
+		return (SET_ERROR(-EINVAL));
+
+	return (zvol_ioctl(inode->i_bdev, file->f_mode, cmd, arg));
+}
+
+#ifdef CONFIG_COMPAT
+static long
+zvol_compat_ioctl_by_inode(struct file *file,
+    unsigned int cmd, unsigned long arg)
+{
+	if (file == NULL)
+		return (SET_ERROR(-EINVAL));
+
+	return (zvol_compat_ioctl(file->f_dentry->d_inode->i_bdev,
+	    file->f_mode, cmd, arg));
+}
+#else
+#define	zvol_compat_ioctl_by_inode	NULL
+#endif
+
+static struct block_device_operations zvol_ops = {
+	.open			= zvol_open_by_inode,
+	.release		= zvol_release_by_inode,
+	.ioctl			= zvol_ioctl_by_inode,
+	.compat_ioctl		= zvol_compat_ioctl_by_inode,
+	.media_changed		= zvol_media_changed,
+	.revalidate_disk	= zvol_revalidate_disk,
+	.getgeo			= zvol_getgeo,
+	.owner			= THIS_MODULE,
+};
+#endif /* HAVE_BDEV_BLOCK_DEVICE_OPERATIONS */
+
+/*
+ * Allocate memory for a new zvol_state_t and setup the required
+ * request queue and generic disk structures for the block device.
+ */
+static zvol_state_t *
+zvol_alloc(dev_t dev, const char *name)
+{
+	zvol_state_t *zv;
+
+	zv = kmem_zalloc(sizeof (zvol_state_t), KM_SLEEP);
+
+	spin_lock_init(&zv->zv_lock);
+	list_link_init(&zv->zv_next);
+
+	zv->zv_queue = blk_alloc_queue(GFP_ATOMIC);
+	if (zv->zv_queue == NULL)
+		goto out_kmem;
+
+	blk_queue_make_request(zv->zv_queue, zvol_request);
+
+#ifdef HAVE_BLK_QUEUE_FLUSH
+	blk_queue_flush(zv->zv_queue, VDEV_REQ_FLUSH | VDEV_REQ_FUA);
+#else
+	blk_queue_ordered(zv->zv_queue, QUEUE_ORDERED_DRAIN, NULL);
+#endif /* HAVE_BLK_QUEUE_FLUSH */
+
+	zv->zv_disk = alloc_disk(ZVOL_MINORS);
+	if (zv->zv_disk == NULL)
+		goto out_queue;
+
+	zv->zv_queue->queuedata = zv;
+	zv->zv_dev = dev;
+	zv->zv_open_count = 0;
+	strlcpy(zv->zv_name, name, MAXNAMELEN);
+
+	mutex_init(&zv->zv_znode.z_range_lock, NULL, MUTEX_DEFAULT, NULL);
+	avl_create(&zv->zv_znode.z_range_avl, zfs_range_compare,
+	    sizeof (rl_t), offsetof(rl_t, r_node));
+	zv->zv_znode.z_is_zvol = TRUE;
+
+	zv->zv_disk->major = zvol_major;
+	zv->zv_disk->first_minor = (dev & MINORMASK);
+	zv->zv_disk->fops = &zvol_ops;
+	zv->zv_disk->private_data = zv;
+	zv->zv_disk->queue = zv->zv_queue;
+	snprintf(zv->zv_disk->disk_name, DISK_NAME_LEN, "%s%d",
+	    ZVOL_DEV_NAME, (dev & MINORMASK));
+
+	return (zv);
+
+out_queue:
+	blk_cleanup_queue(zv->zv_queue);
+out_kmem:
+	kmem_free(zv, sizeof (zvol_state_t));
+
+	return (NULL);
+}
+
+/*
+ * Cleanup then free a zvol_state_t which was created by zvol_alloc().
+ */
+static void
+zvol_free(zvol_state_t *zv)
+{
+	ASSERT(MUTEX_HELD(&zvol_state_lock));
+	ASSERT(zv->zv_open_count == 0);
+
+	avl_destroy(&zv->zv_znode.z_range_avl);
+	mutex_destroy(&zv->zv_znode.z_range_lock);
+
+	zv->zv_disk->private_data = NULL;
+
+	del_gendisk(zv->zv_disk);
+	blk_cleanup_queue(zv->zv_queue);
+	put_disk(zv->zv_disk);
+
+	kmem_free(zv, sizeof (zvol_state_t));
+}
+
+/*
+ * Create a block device minor node and setup the linkage between it
+ * and the specified volume.  Once this function returns the block
+ * device is live and ready for use.
+ */
+static int
+zvol_create_minor_impl(const char *name)
+{
+	zvol_state_t *zv;
+	objset_t *os;
+	dmu_object_info_t *doi;
+	uint64_t volsize;
+	uint64_t len;
+	unsigned minor = 0;
+	int error = 0;
+
+	mutex_enter(&zvol_state_lock);
+
+	zv = zvol_find_by_name(name);
+	if (zv) {
+		error = SET_ERROR(EEXIST);
+		goto out;
+	}
+
+	doi = kmem_alloc(sizeof (dmu_object_info_t), KM_SLEEP);
+
+	error = dmu_objset_own(name, DMU_OST_ZVOL, B_TRUE, zvol_tag, &os);
+	if (error)
+		goto out_doi;
+
+	error = dmu_object_info(os, ZVOL_OBJ, doi);
+	if (error)
+		goto out_dmu_objset_disown;
+
+	error = zap_lookup(os, ZVOL_ZAP_OBJ, "size", 8, 1, &volsize);
+	if (error)
+		goto out_dmu_objset_disown;
+
+	error = zvol_find_minor(&minor);
+	if (error)
+		goto out_dmu_objset_disown;
+
+	zv = zvol_alloc(MKDEV(zvol_major, minor), name);
+	if (zv == NULL) {
+		error = SET_ERROR(EAGAIN);
+		goto out_dmu_objset_disown;
+	}
+
+	if (dmu_objset_is_snapshot(os))
+		zv->zv_flags |= ZVOL_RDONLY;
+
+	zv->zv_volblocksize = doi->doi_data_block_size;
+	zv->zv_volsize = volsize;
+	zv->zv_objset = os;
+
+	set_capacity(zv->zv_disk, zv->zv_volsize >> 9);
+
+	blk_queue_max_hw_sectors(zv->zv_queue, (DMU_MAX_ACCESS / 4) >> 9);
+	blk_queue_max_segments(zv->zv_queue, UINT16_MAX);
+	blk_queue_max_segment_size(zv->zv_queue, UINT_MAX);
+	blk_queue_physical_block_size(zv->zv_queue, zv->zv_volblocksize);
+	blk_queue_io_opt(zv->zv_queue, zv->zv_volblocksize);
+	blk_queue_max_discard_sectors(zv->zv_queue,
+	    (zvol_max_discard_blocks * zv->zv_volblocksize) >> 9);
+	blk_queue_discard_granularity(zv->zv_queue, zv->zv_volblocksize);
+	queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, zv->zv_queue);
+#ifdef QUEUE_FLAG_NONROT
+	queue_flag_set_unlocked(QUEUE_FLAG_NONROT, zv->zv_queue);
+#endif
+#ifdef QUEUE_FLAG_ADD_RANDOM
+	queue_flag_clear_unlocked(QUEUE_FLAG_ADD_RANDOM, zv->zv_queue);
+#endif
+
+	if (spa_writeable(dmu_objset_spa(os))) {
+		if (zil_replay_disable)
+			zil_destroy(dmu_objset_zil(os), B_FALSE);
+		else
+			zil_replay(os, zv, zvol_replay_vector);
+	}
+
+	/*
+	 * When udev detects the addition of the device it will immediately
+	 * invoke blkid(8) to determine the type of content on the device.
+	 * Prefetching the blocks commonly scanned by blkid(8) will speed
+	 * up this process.
+	 */
+	len = MIN(MAX(zvol_prefetch_bytes, 0), SPA_MAXBLOCKSIZE);
+	if (len > 0) {
+		dmu_prefetch(os, ZVOL_OBJ, 0, len);
+		dmu_prefetch(os, ZVOL_OBJ, volsize - len, len);
+	}
+
+	zv->zv_objset = NULL;
+out_dmu_objset_disown:
+	dmu_objset_disown(os, zvol_tag);
+out_doi:
+	kmem_free(doi, sizeof (dmu_object_info_t));
+out:
+
+	if (error == 0) {
+		zvol_insert(zv);
+		/*
+		 * Drop the lock to prevent deadlock with sys_open() ->
+		 * zvol_open(), which first takes bd_disk->bd_mutex and then
+		 * takes zvol_state_lock, whereas this code path first takes
+		 * zvol_state_lock, and then takes bd_disk->bd_mutex.
+		 */
+		mutex_exit(&zvol_state_lock);
+		add_disk(zv->zv_disk);
+	} else {
+		mutex_exit(&zvol_state_lock);
+	}
+
+	return (SET_ERROR(error));
+}
+
+/*
+ * Rename a block device minor mode for the specified volume.
+ */
+static void
+zvol_rename_minor(zvol_state_t *zv, const char *newname)
+{
+	int readonly = get_disk_ro(zv->zv_disk);
+
+	ASSERT(MUTEX_HELD(&zvol_state_lock));
+
+	strlcpy(zv->zv_name, newname, sizeof (zv->zv_name));
+
+	/*
+	 * The block device's read-only state is briefly changed causing
+	 * a KOBJ_CHANGE uevent to be issued.  This ensures udev detects
+	 * the name change and fixes the symlinks.  This does not change
+	 * ZVOL_RDONLY in zv->zv_flags so the actual read-only state never
+	 * changes.  This would normally be done using kobject_uevent() but
+	 * that is a GPL-only symbol which is why we need this workaround.
+	 */
+	set_disk_ro(zv->zv_disk, !readonly);
+	set_disk_ro(zv->zv_disk, readonly);
+}
+
+
+/*
+ * Mask errors to continue dmu_objset_find() traversal
+ */
+static int
+zvol_create_snap_minor_cb(const char *dsname, void *arg)
+{
+	const char *name = (const char *)arg;
+
+	ASSERT0(MUTEX_HELD(&spa_namespace_lock));
+
+	/* skip the designated dataset */
+	if (name && strcmp(dsname, name) == 0)
+		return (0);
+
+	/* at this point, the dsname should name a snapshot */
+	if (strchr(dsname, '@') == 0) {
+		dprintf("zvol_create_snap_minor_cb(): "
+			"%s is not a shapshot name\n", dsname);
+	} else {
+		(void) zvol_create_minor_impl(dsname);
+	}
+
+	return (0);
+}
+
+/*
+ * Mask errors to continue dmu_objset_find() traversal
+ */
+static int
+zvol_create_minors_cb(const char *dsname, void *arg)
+{
+	uint64_t snapdev;
+	int error;
+
+	ASSERT0(MUTEX_HELD(&spa_namespace_lock));
+
+	error = dsl_prop_get_integer(dsname, "snapdev", &snapdev, NULL);
+	if (error)
+		return (0);
+
+	/*
+	 * Given the name and the 'snapdev' property, create device minor nodes
+	 * with the linkages to zvols/snapshots as needed.
+	 * If the name represents a zvol, create a minor node for the zvol, then
+	 * check if its snapshots are 'visible', and if so, iterate over the
+	 * snapshots and create device minor nodes for those.
+	 */
+	if (strchr(dsname, '@') == 0) {
+		/* create minor for the 'dsname' explicitly */
+		error = zvol_create_minor_impl(dsname);
+		if ((error == 0 || error == EEXIST) &&
+		    (snapdev == ZFS_SNAPDEV_VISIBLE)) {
+			fstrans_cookie_t cookie = spl_fstrans_mark();
+			/*
+			 * traverse snapshots only, do not traverse children,
+			 * and skip the 'dsname'
+			 */
+			error = dmu_objset_find((char *)dsname,
+			    zvol_create_snap_minor_cb, (void *)dsname,
+			    DS_FIND_SNAPSHOTS);
+			spl_fstrans_unmark(cookie);
+		}
+	} else {
+		dprintf("zvol_create_minors_cb(): %s is not a zvol name\n",
+			dsname);
+	}
+
+	return (0);
+}
+
+/*
+ * Create minors for the specified dataset, including children and snapshots.
+ * Pay attention to the 'snapdev' property and iterate over the snapshots
+ * only if they are 'visible'. This approach allows one to assure that the
+ * snapshot metadata is read from disk only if it is needed.
+ *
+ * The name can represent a dataset to be recursively scanned for zvols and
+ * their snapshots, or a single zvol snapshot. If the name represents a
+ * dataset, the scan is performed in two nested stages:
+ * - scan the dataset for zvols, and
+ * - for each zvol, create a minor node, then check if the zvol's snapshots
+ *   are 'visible', and only then iterate over the snapshots if needed
+ *
+ * If the name represents a snapshot, a check is perfromed if the snapshot is
+ * 'visible' (which also verifies that the parent is a zvol), and if so,
+ * a minor node for that snapshot is created.
+ */
+static int
+zvol_create_minors_impl(const char *name)
+{
+	int error = 0;
+	fstrans_cookie_t cookie;
+	char *atp, *parent;
+
+	if (zvol_inhibit_dev)
+		return (0);
+
+	parent = kmem_alloc(MAXPATHLEN, KM_SLEEP);
+	(void) strlcpy(parent, name, MAXPATHLEN);
+
+	if ((atp = strrchr(parent, '@')) != NULL) {
+		uint64_t snapdev;
+
+		*atp = '\0';
+		error = dsl_prop_get_integer(parent, "snapdev",
+		    &snapdev, NULL);
+
+		if (error == 0 && snapdev == ZFS_SNAPDEV_VISIBLE)
+			error = zvol_create_minor_impl(name);
+	} else {
+		cookie = spl_fstrans_mark();
+		error = dmu_objset_find(parent, zvol_create_minors_cb,
+		    NULL, DS_FIND_CHILDREN);
+		spl_fstrans_unmark(cookie);
+	}
+
+	kmem_free(parent, MAXPATHLEN);
+
+	return (SET_ERROR(error));
+}
+
+/*
+ * Remove minors for specified dataset including children and snapshots.
+ */
+static void
+zvol_remove_minors_impl(const char *name)
+{
+	zvol_state_t *zv, *zv_next;
+	int namelen = ((name) ? strlen(name) : 0);
+
+	if (zvol_inhibit_dev)
+		return;
+
+	mutex_enter(&zvol_state_lock);
+
+	for (zv = list_head(&zvol_state_list); zv != NULL; zv = zv_next) {
+		zv_next = list_next(&zvol_state_list, zv);
+
+		if (name == NULL || strcmp(zv->zv_name, name) == 0 ||
+		    (strncmp(zv->zv_name, name, namelen) == 0 &&
+		    (zv->zv_name[namelen] == '/' ||
+		    zv->zv_name[namelen] == '@'))) {
+
+			/* If in use, leave alone */
+			if (zv->zv_open_count > 0)
+				continue;
+
+			zvol_remove(zv);
+			zvol_free(zv);
+		}
+	}
+
+	mutex_exit(&zvol_state_lock);
+}
+
+/* Remove minor for this specific snapshot only */
+static void
+zvol_remove_minor_impl(const char *name)
+{
+	zvol_state_t *zv, *zv_next;
+
+	if (zvol_inhibit_dev)
+		return;
+
+	if (strchr(name, '@') == NULL)
+		return;
+
+	mutex_enter(&zvol_state_lock);
+
+	for (zv = list_head(&zvol_state_list); zv != NULL; zv = zv_next) {
+		zv_next = list_next(&zvol_state_list, zv);
+
+		if (strcmp(zv->zv_name, name) == 0) {
+			/* If in use, leave alone */
+			if (zv->zv_open_count > 0)
+				continue;
+			zvol_remove(zv);
+			zvol_free(zv);
+			break;
+		}
+	}
+
+	mutex_exit(&zvol_state_lock);
+}
+
+/*
+ * Rename minors for specified dataset including children and snapshots.
+ */
+static void
+zvol_rename_minors_impl(const char *oldname, const char *newname)
+{
+	zvol_state_t *zv, *zv_next;
+	int oldnamelen, newnamelen;
+	char *name;
+
+	if (zvol_inhibit_dev)
+		return;
+
+	oldnamelen = strlen(oldname);
+	newnamelen = strlen(newname);
+	name = kmem_alloc(MAXNAMELEN, KM_SLEEP);
+
+	mutex_enter(&zvol_state_lock);
+
+	for (zv = list_head(&zvol_state_list); zv != NULL; zv = zv_next) {
+		zv_next = list_next(&zvol_state_list, zv);
+
+		/* If in use, leave alone */
+		if (zv->zv_open_count > 0)
+			continue;
+
+		if (strcmp(zv->zv_name, oldname) == 0) {
+			zvol_rename_minor(zv, newname);
+		} else if (strncmp(zv->zv_name, oldname, oldnamelen) == 0 &&
+		    (zv->zv_name[oldnamelen] == '/' ||
+		    zv->zv_name[oldnamelen] == '@')) {
+			snprintf(name, MAXNAMELEN, "%s%c%s", newname,
+			    zv->zv_name[oldnamelen],
+			    zv->zv_name + oldnamelen + 1);
+			zvol_rename_minor(zv, name);
+		}
+	}
+
+	mutex_exit(&zvol_state_lock);
+
+	kmem_free(name, MAXNAMELEN);
+}
+
+typedef struct zvol_snapdev_cb_arg {
+	uint64_t snapdev;
+} zvol_snapdev_cb_arg_t;
+
+static int
+zvol_set_snapdev_cb(const char *dsname, void *param) {
+	zvol_snapdev_cb_arg_t *arg = param;
+
+	if (strchr(dsname, '@') == NULL)
+		return (0);
+
+	switch (arg->snapdev) {
+		case ZFS_SNAPDEV_VISIBLE:
+			(void) zvol_create_minor_impl(dsname);
+			break;
+		case ZFS_SNAPDEV_HIDDEN:
+			(void) zvol_remove_minor_impl(dsname);
+			break;
+	}
+
+	return (0);
+}
+
+static void
+zvol_set_snapdev_impl(char *name, uint64_t snapdev)
+{
+	zvol_snapdev_cb_arg_t arg = {snapdev};
+	fstrans_cookie_t cookie = spl_fstrans_mark();
+	/*
+	 * The zvol_set_snapdev_sync() sets snapdev appropriately
+	 * in the dataset hierarchy. Here, we only scan snapshots.
+	 */
+	dmu_objset_find(name, zvol_set_snapdev_cb, &arg, DS_FIND_SNAPSHOTS);
+	spl_fstrans_unmark(cookie);
+}
+
+static zvol_task_t *
+zvol_task_alloc(zvol_async_op_t op, const char *name1, const char *name2,
+    uint64_t snapdev)
+{
+	zvol_task_t *task;
+	char *delim;
+
+	/* Never allow tasks on hidden names. */
+	if (name1[0] == '$')
+		return (NULL);
+
+	task = kmem_zalloc(sizeof (zvol_task_t), KM_SLEEP);
+	task->op = op;
+	task->snapdev = snapdev;
+	delim = strchr(name1, '/');
+	strlcpy(task->pool, name1, delim ? (delim - name1 + 1) : MAXNAMELEN);
+
+	strlcpy(task->name1, name1, MAXNAMELEN);
+	if (name2 != NULL)
+		strlcpy(task->name2, name2, MAXNAMELEN);
+
+	return (task);
+}
+
+static void
+zvol_task_free(zvol_task_t *task)
+{
+	kmem_free(task, sizeof (zvol_task_t));
+}
+
+/*
+ * The worker thread function performed asynchronously.
+ */
+static void
+zvol_task_cb(void *param)
+{
+	zvol_task_t *task = (zvol_task_t *)param;
+
+	switch (task->op) {
+	case ZVOL_ASYNC_CREATE_MINORS:
+		(void) zvol_create_minors_impl(task->name1);
+		break;
+	case ZVOL_ASYNC_REMOVE_MINORS:
+		zvol_remove_minors_impl(task->name1);
+		break;
+	case ZVOL_ASYNC_RENAME_MINORS:
+		zvol_rename_minors_impl(task->name1, task->name2);
+		break;
+	case ZVOL_ASYNC_SET_SNAPDEV:
+		zvol_set_snapdev_impl(task->name1, task->snapdev);
+		break;
+	default:
+		VERIFY(0);
+		break;
+	}
+
+	zvol_task_free(task);
+}
+
+typedef struct zvol_set_snapdev_arg {
+	const char *zsda_name;
+	uint64_t zsda_value;
+	zprop_source_t zsda_source;
+	dmu_tx_t *zsda_tx;
+} zvol_set_snapdev_arg_t;
+
+/*
+ * Sanity check the dataset for safe use by the sync task.  No additional
+ * conditions are imposed.
+ */
+static int
+zvol_set_snapdev_check(void *arg, dmu_tx_t *tx)
+{
+	zvol_set_snapdev_arg_t *zsda = arg;
+	dsl_pool_t *dp = dmu_tx_pool(tx);
+	dsl_dir_t *dd;
+	int error;
+
+	error = dsl_dir_hold(dp, zsda->zsda_name, FTAG, &dd, NULL);
+	if (error != 0)
+		return (error);
+
+	dsl_dir_rele(dd, FTAG);
+
+	return (error);
+}
+
+static int
+zvol_set_snapdev_sync_cb(dsl_pool_t *dp, dsl_dataset_t *ds, void *arg)
+{
+	zvol_set_snapdev_arg_t *zsda = arg;
+	char dsname[MAXNAMELEN];
+	zvol_task_t *task;
+
+	dsl_dataset_name(ds, dsname);
+	dsl_prop_set_sync_impl(ds, zfs_prop_to_name(ZFS_PROP_SNAPDEV),
+	    zsda->zsda_source, sizeof (zsda->zsda_value), 1,
+	    &zsda->zsda_value, zsda->zsda_tx);
+
+	task = zvol_task_alloc(ZVOL_ASYNC_SET_SNAPDEV, dsname,
+	    NULL, zsda->zsda_value);
+	if (task == NULL)
+		return (0);
+
+	(void) taskq_dispatch(dp->dp_spa->spa_zvol_taskq, zvol_task_cb,
+		task, TQ_SLEEP);
+	return (0);
+}
+
+/*
+ * Traverse all child snapshot datasets and apply snapdev appropriately.
+ */
+static void
+zvol_set_snapdev_sync(void *arg, dmu_tx_t *tx)
+{
+	zvol_set_snapdev_arg_t *zsda = arg;
+	dsl_pool_t *dp = dmu_tx_pool(tx);
+	dsl_dir_t *dd;
+
+	VERIFY0(dsl_dir_hold(dp, zsda->zsda_name, FTAG, &dd, NULL));
+	zsda->zsda_tx = tx;
+
+	dmu_objset_find_dp(dp, dd->dd_object, zvol_set_snapdev_sync_cb,
+	    zsda, DS_FIND_CHILDREN);
+
+	dsl_dir_rele(dd, FTAG);
+}
+
+int
+zvol_set_snapdev(const char *ddname, zprop_source_t source, uint64_t snapdev)
+{
+	zvol_set_snapdev_arg_t zsda;
+
+	zsda.zsda_name = ddname;
+	zsda.zsda_source = source;
+	zsda.zsda_value = snapdev;
+
+	return (dsl_sync_task(ddname, zvol_set_snapdev_check,
+	    zvol_set_snapdev_sync, &zsda, 0, ZFS_SPACE_CHECK_NONE));
+}
+
+void
+zvol_create_minors(spa_t *spa, const char *name, boolean_t async)
+{
+	zvol_task_t *task;
+	taskqid_t id;
+
+	task = zvol_task_alloc(ZVOL_ASYNC_CREATE_MINORS, name, NULL, ~0ULL);
+	if (task == NULL)
+		return;
+
+	id = taskq_dispatch(spa->spa_zvol_taskq, zvol_task_cb, task, TQ_SLEEP);
+	if ((async == B_FALSE) && (id != 0))
+		taskq_wait_id(spa->spa_zvol_taskq, id);
+}
+
+void
+zvol_remove_minors(spa_t *spa, const char *name, boolean_t async)
+{
+	zvol_task_t *task;
+	taskqid_t id;
+
+	task = zvol_task_alloc(ZVOL_ASYNC_REMOVE_MINORS, name, NULL, ~0ULL);
+	if (task == NULL)
+		return;
+
+	id = taskq_dispatch(spa->spa_zvol_taskq, zvol_task_cb, task, TQ_SLEEP);
+	if ((async == B_FALSE) && (id != 0))
+		taskq_wait_id(spa->spa_zvol_taskq, id);
+}
+
+void
+zvol_rename_minors(spa_t *spa, const char *name1, const char *name2,
+    boolean_t async)
+{
+	zvol_task_t *task;
+	taskqid_t id;
+
+	task = zvol_task_alloc(ZVOL_ASYNC_RENAME_MINORS, name1, name2, ~0ULL);
+	if (task == NULL)
+		return;
+
+	id = taskq_dispatch(spa->spa_zvol_taskq, zvol_task_cb, task, TQ_SLEEP);
+	if ((async == B_FALSE) && (id != 0))
+		taskq_wait_id(spa->spa_zvol_taskq, id);
+}
+
+int
+zvol_init(void)
+{
+	int error;
+
+	list_create(&zvol_state_list, sizeof (zvol_state_t),
+	    offsetof(zvol_state_t, zv_next));
+	mutex_init(&zvol_state_lock, NULL, MUTEX_DEFAULT, NULL);
+
+	error = register_blkdev(zvol_major, ZVOL_DRIVER);
+	if (error) {
+		printk(KERN_INFO "ZFS: register_blkdev() failed %d\n", error);
+		goto out;
+	}
+
+	blk_register_region(MKDEV(zvol_major, 0), 1UL << MINORBITS,
+	    THIS_MODULE, zvol_probe, NULL, NULL);
+
+	return (0);
+
+out:
+	mutex_destroy(&zvol_state_lock);
+	list_destroy(&zvol_state_list);
+
+	return (SET_ERROR(error));
+}
+
+void
+zvol_fini(void)
+{
+	zvol_remove_minors_impl(NULL);
+
+	blk_unregister_region(MKDEV(zvol_major, 0), 1UL << MINORBITS);
+	unregister_blkdev(zvol_major, ZVOL_DRIVER);
+
+	list_destroy(&zvol_state_list);
+	mutex_destroy(&zvol_state_lock);
+}
+
+module_param(zvol_inhibit_dev, uint, 0644);
+MODULE_PARM_DESC(zvol_inhibit_dev, "Do not create zvol device nodes");
+
+module_param(zvol_major, uint, 0444);
+MODULE_PARM_DESC(zvol_major, "Major number for zvol device");
+
+module_param(zvol_max_discard_blocks, ulong, 0444);
+MODULE_PARM_DESC(zvol_max_discard_blocks, "Max number of blocks to discard");
+
+module_param(zvol_prefetch_bytes, uint, 0644);
+MODULE_PARM_DESC(zvol_prefetch_bytes, "Prefetch N bytes at zvol start+end");
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/module/zpios/Makefile.in
@@ -0,0 +1,10 @@
+src = @abs_top_srcdir@/module/zpios
+obj = @abs_builddir@
+
+MODULE := zpios
+
+EXTRA_CFLAGS = $(ZFS_MODULE_CFLAGS) @KERNELCPPFLAGS@
+
+obj-$(CONFIG_ZFS) := $(MODULE).o
+
+$(MODULE)-objs += pios.o
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/module/zpios/pios.c
@@ -0,0 +1,1325 @@
+/*
+ *  ZPIOS is a heavily modified version of the original PIOS test code.
+ *  It is designed to have the test code running in the Linux kernel
+ *  against ZFS while still being flexibly controled from user space.
+ *
+ *  Copyright (C) 2008-2010 Lawrence Livermore National Security, LLC.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
+ *  LLNL-CODE-403049
+ *
+ *  Original PIOS Test Code
+ *  Copyright (C) 2004 Cluster File Systems, Inc.
+ *  Written by Peter Braam <braam@clusterfs.com>
+ *             Atul Vidwansa <atul@clusterfs.com>
+ *             Milind Dumbare <milind@clusterfs.com>
+ *
+ *  This file is part of ZFS on Linux.
+ *  For details, see <http://zfsonlinux.org/>.
+ *
+ *  ZPIOS is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  ZPIOS is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with ZPIOS.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <sys/zfs_context.h>
+#include <sys/dmu.h>
+#include <sys/txg.h>
+#include <sys/dsl_destroy.h>
+#include <linux/miscdevice.h>
+#include "zpios-internal.h"
+
+
+static char *zpios_tag = "zpios_tag";
+
+static int
+zpios_upcall(char *path, char *phase, run_args_t *run_args, int rc)
+{
+	/*
+	 * This is stack heavy but it should be OK since we are only
+	 * making the upcall between tests when the stack is shallow.
+	 */
+	char id[16], chunk_size[16], region_size[16], thread_count[16];
+	char region_count[16], offset[16], region_noise[16], chunk_noise[16];
+	char thread_delay[16], flags[16], result[8];
+	char *argv[16], *envp[4];
+
+	if ((path == NULL) || (strlen(path) == 0))
+		return (-ENOENT);
+
+	snprintf(id, 15, "%d", run_args->id);
+	snprintf(chunk_size, 15, "%lu", (long unsigned)run_args->chunk_size);
+	snprintf(region_size, 15, "%lu", (long unsigned) run_args->region_size);
+	snprintf(thread_count, 15, "%u", run_args->thread_count);
+	snprintf(region_count, 15, "%u", run_args->region_count);
+	snprintf(offset, 15, "%lu", (long unsigned)run_args->offset);
+	snprintf(region_noise, 15, "%u", run_args->region_noise);
+	snprintf(chunk_noise, 15, "%u", run_args->chunk_noise);
+	snprintf(thread_delay, 15, "%u", run_args->thread_delay);
+	snprintf(flags, 15, "0x%x", run_args->flags);
+	snprintf(result, 7, "%d", rc);
+
+	/* Passing 15 args to registered pre/post upcall */
+	argv[0] = path;
+	argv[1] = phase;
+	argv[2] = strlen(run_args->log) ? run_args->log : "<none>";
+	argv[3] = id;
+	argv[4] = run_args->pool;
+	argv[5] = chunk_size;
+	argv[6] = region_size;
+	argv[7] = thread_count;
+	argv[8] = region_count;
+	argv[9] = offset;
+	argv[10] = region_noise;
+	argv[11] = chunk_noise;
+	argv[12] = thread_delay;
+	argv[13] = flags;
+	argv[14] = result;
+	argv[15] = NULL;
+
+	/* Passing environment for user space upcall */
+	envp[0] = "HOME=/";
+	envp[1] = "TERM=linux";
+	envp[2] = "PATH=/sbin:/usr/sbin:/bin:/usr/bin";
+	envp[3] = NULL;
+
+	return (call_usermodehelper(path, argv, envp, UMH_WAIT_PROC));
+}
+
+static int
+zpios_print(struct file *file, const char *format, ...)
+{
+	zpios_info_t *info = (zpios_info_t *)file->private_data;
+	va_list adx;
+	int rc;
+
+	ASSERT(info);
+	ASSERT(info->info_buffer);
+
+	va_start(adx, format);
+	spin_lock(&info->info_lock);
+
+	/* Don't allow the kernel to start a write in the red zone */
+	if ((int)(info->info_head - info->info_buffer) >
+	    (info->info_size - ZPIOS_INFO_BUFFER_REDZONE)) {
+		rc = -EOVERFLOW;
+	} else {
+		rc = vsprintf(info->info_head, format, adx);
+		if (rc >= 0)
+			info->info_head += rc;
+	}
+
+	spin_unlock(&info->info_lock);
+	va_end(adx);
+
+	return (rc);
+}
+
+static uint64_t
+zpios_dmu_object_create(run_args_t *run_args, objset_t *os)
+{
+	struct dmu_tx *tx;
+	uint64_t obj = 0ULL;
+	int rc;
+
+	tx = dmu_tx_create(os);
+	dmu_tx_hold_write(tx, DMU_NEW_OBJECT, 0, OBJ_SIZE);
+	rc = dmu_tx_assign(tx, TXG_WAIT);
+	if (rc) {
+		zpios_print(run_args->file,
+		    "dmu_tx_assign() failed: %d\n", rc);
+		dmu_tx_abort(tx);
+		return (obj);
+	}
+
+	obj = dmu_object_alloc(os, DMU_OT_UINT64_OTHER, 0, DMU_OT_NONE, 0, tx);
+	rc = dmu_object_set_blocksize(os, obj, 128ULL << 10, 0, tx);
+	if (rc) {
+		zpios_print(run_args->file,
+			    "dmu_object_set_blocksize() failed: %d\n", rc);
+		dmu_tx_abort(tx);
+		return (obj);
+	}
+
+	dmu_tx_commit(tx);
+
+	return (obj);
+}
+
+static int
+zpios_dmu_object_free(run_args_t *run_args, objset_t *os, uint64_t obj)
+{
+	struct dmu_tx *tx;
+	int rc;
+
+	tx = dmu_tx_create(os);
+	dmu_tx_hold_free(tx, obj, 0, DMU_OBJECT_END);
+	rc = dmu_tx_assign(tx, TXG_WAIT);
+	if (rc) {
+		zpios_print(run_args->file,
+			    "dmu_tx_assign() failed: %d\n", rc);
+		dmu_tx_abort(tx);
+		return (rc);
+	}
+
+	rc = dmu_object_free(os, obj, tx);
+	if (rc) {
+		zpios_print(run_args->file,
+			    "dmu_object_free() failed: %d\n", rc);
+		dmu_tx_abort(tx);
+		return (rc);
+	}
+
+	dmu_tx_commit(tx);
+
+	return (0);
+}
+
+static int
+zpios_dmu_setup(run_args_t *run_args)
+{
+	zpios_time_t *t = &(run_args->stats.cr_time);
+	objset_t *os;
+	char name[32];
+	uint64_t obj = 0ULL;
+	int i, rc = 0, rc2;
+
+	(void) zpios_upcall(run_args->pre, PHASE_PRE_CREATE, run_args, 0);
+	t->start = zpios_timespec_now();
+
+	(void) snprintf(name, 32, "%s/id_%d", run_args->pool, run_args->id);
+	rc = dmu_objset_create(name, DMU_OST_OTHER, 0, NULL, NULL);
+	if (rc) {
+		zpios_print(run_args->file, "Error dmu_objset_create(%s, ...) "
+			    "failed: %d\n", name, rc);
+		goto out;
+	}
+
+	rc = dmu_objset_own(name, DMU_OST_OTHER, 0, zpios_tag, &os);
+	if (rc) {
+		zpios_print(run_args->file, "Error dmu_objset_own(%s, ...) "
+			    "failed: %d\n", name, rc);
+		goto out_destroy;
+	}
+
+	if (!(run_args->flags & DMU_FPP)) {
+		obj = zpios_dmu_object_create(run_args, os);
+		if (obj == 0) {
+			rc = -EBADF;
+			zpios_print(run_args->file, "Error zpios_dmu_"
+				    "object_create() failed, %d\n", rc);
+			goto out_destroy;
+		}
+	}
+
+	for (i = 0; i < run_args->region_count; i++) {
+		zpios_region_t *region;
+
+		region = &run_args->regions[i];
+		mutex_init(&region->lock, NULL, MUTEX_DEFAULT, NULL);
+
+		if (run_args->flags & DMU_FPP) {
+			/* File per process */
+			region->obj.os  = os;
+			region->obj.obj = zpios_dmu_object_create(run_args, os);
+			ASSERT(region->obj.obj > 0); /* XXX - Handle this */
+			region->wr_offset   = run_args->offset;
+			region->rd_offset   = run_args->offset;
+			region->init_offset = run_args->offset;
+			region->max_offset  = run_args->offset +
+			    run_args->region_size;
+		} else {
+			/* Single shared file */
+			region->obj.os  = os;
+			region->obj.obj = obj;
+			region->wr_offset   = run_args->offset * i;
+			region->rd_offset   = run_args->offset * i;
+			region->init_offset = run_args->offset * i;
+			region->max_offset  = run_args->offset *
+			    i + run_args->region_size;
+		}
+	}
+
+	run_args->os = os;
+out_destroy:
+	if (rc) {
+		rc2 = dsl_destroy_head(name);
+		if (rc2)
+			zpios_print(run_args->file, "Error dsl_destroy_head"
+				    "(%s, ...) failed: %d\n", name, rc2);
+	}
+out:
+	t->stop  = zpios_timespec_now();
+	t->delta = zpios_timespec_sub(t->stop, t->start);
+	(void) zpios_upcall(run_args->post, PHASE_POST_CREATE, run_args, rc);
+
+	return (rc);
+}
+
+static int
+zpios_setup_run(run_args_t **run_args, zpios_cmd_t *kcmd, struct file *file)
+{
+	run_args_t *ra;
+	int rc, size;
+
+	size = sizeof (*ra) + kcmd->cmd_region_count * sizeof (zpios_region_t);
+
+	ra = vmem_zalloc(size, KM_SLEEP);
+	if (ra == NULL) {
+		zpios_print(file, "Unable to vmem_zalloc() %d bytes "
+			    "for regions\n", size);
+		return (-ENOMEM);
+	}
+
+	*run_args = ra;
+	strncpy(ra->pool, kcmd->cmd_pool, ZPIOS_NAME_SIZE - 1);
+	strncpy(ra->pre, kcmd->cmd_pre, ZPIOS_PATH_SIZE - 1);
+	strncpy(ra->post, kcmd->cmd_post, ZPIOS_PATH_SIZE - 1);
+	strncpy(ra->log, kcmd->cmd_log, ZPIOS_PATH_SIZE - 1);
+	ra->id			= kcmd->cmd_id;
+	ra->chunk_size		= kcmd->cmd_chunk_size;
+	ra->thread_count	= kcmd->cmd_thread_count;
+	ra->region_count	= kcmd->cmd_region_count;
+	ra->region_size		= kcmd->cmd_region_size;
+	ra->offset		= kcmd->cmd_offset;
+	ra->region_noise	= kcmd->cmd_region_noise;
+	ra->chunk_noise		= kcmd->cmd_chunk_noise;
+	ra->thread_delay	= kcmd->cmd_thread_delay;
+	ra->flags		= kcmd->cmd_flags;
+	ra->stats.wr_data	= 0;
+	ra->stats.wr_chunks	= 0;
+	ra->stats.rd_data	= 0;
+	ra->stats.rd_chunks	= 0;
+	ra->region_next		= 0;
+	ra->file		= file;
+	mutex_init(&ra->lock_work, NULL, MUTEX_DEFAULT, NULL);
+	mutex_init(&ra->lock_ctl, NULL, MUTEX_DEFAULT, NULL);
+
+	(void) zpios_upcall(ra->pre, PHASE_PRE_RUN, ra, 0);
+
+	rc = zpios_dmu_setup(ra);
+	if (rc) {
+		mutex_destroy(&ra->lock_ctl);
+		mutex_destroy(&ra->lock_work);
+		vmem_free(ra, size);
+		*run_args = NULL;
+	}
+
+	return (rc);
+}
+
+static int
+zpios_get_work_item(run_args_t *run_args, dmu_obj_t *obj, __u64 *offset,
+		    __u32 *chunk_size, zpios_region_t **region, __u32 flags)
+{
+	int i, j, count = 0;
+	unsigned int random_int;
+
+	get_random_bytes(&random_int, sizeof (unsigned int));
+
+	mutex_enter(&run_args->lock_work);
+	i = run_args->region_next;
+
+	/*
+	 * XXX: I don't much care for this chunk selection mechansim
+	 * there's the potential to burn a lot of time here doing nothing
+	 * useful while holding the global lock.  This could give some
+	 * misleading performance results.  I'll fix it latter.
+	 */
+	while (count < run_args->region_count) {
+		__u64 *rw_offset;
+		zpios_time_t *rw_time;
+
+		j = i % run_args->region_count;
+		*region = &(run_args->regions[j]);
+
+		if (flags & DMU_WRITE) {
+			rw_offset = &((*region)->wr_offset);
+			rw_time = &((*region)->stats.wr_time);
+		} else {
+			rw_offset = &((*region)->rd_offset);
+			rw_time = &((*region)->stats.rd_time);
+		}
+
+		/* test if region is fully written */
+		if (*rw_offset + *chunk_size > (*region)->max_offset) {
+			i++;
+			count++;
+
+			if (unlikely(rw_time->stop.ts_sec == 0) &&
+			    unlikely(rw_time->stop.ts_nsec == 0))
+				rw_time->stop = zpios_timespec_now();
+
+			continue;
+		}
+
+		*offset = *rw_offset;
+		*obj = (*region)->obj;
+		*rw_offset += *chunk_size;
+
+		/* update ctl structure */
+		if (run_args->region_noise) {
+			get_random_bytes(&random_int, sizeof (unsigned int));
+			run_args->region_next +=
+			    random_int % run_args->region_noise;
+		} else {
+			run_args->region_next++;
+		}
+
+		mutex_exit(&run_args->lock_work);
+		return (1);
+	}
+
+	/* nothing left to do */
+	mutex_exit(&run_args->lock_work);
+
+	return (0);
+}
+
+static void
+zpios_remove_objset(run_args_t *run_args)
+{
+	zpios_time_t *t = &(run_args->stats.rm_time);
+	zpios_region_t *region;
+	char name[32];
+	int rc = 0, i;
+
+	(void) zpios_upcall(run_args->pre, PHASE_PRE_REMOVE, run_args, 0);
+	t->start = zpios_timespec_now();
+
+	(void) snprintf(name, 32, "%s/id_%d", run_args->pool, run_args->id);
+
+	if (run_args->flags & DMU_REMOVE) {
+		if (run_args->flags & DMU_FPP) {
+			for (i = 0; i < run_args->region_count; i++) {
+				region = &run_args->regions[i];
+				rc = zpios_dmu_object_free(run_args,
+				    region->obj.os, region->obj.obj);
+				if (rc)
+					zpios_print(run_args->file,
+					    "Error removing object %d, %d\n",
+					    (int)region->obj.obj, rc);
+			}
+		} else {
+			region = &run_args->regions[0];
+			rc = zpios_dmu_object_free(run_args,
+			    region->obj.os, region->obj.obj);
+			if (rc)
+				zpios_print(run_args->file,
+				    "Error removing object %d, %d\n",
+				    (int)region->obj.obj, rc);
+		}
+	}
+
+	dmu_objset_disown(run_args->os, zpios_tag);
+
+	if (run_args->flags & DMU_REMOVE) {
+		rc = dsl_destroy_head(name);
+		if (rc)
+			zpios_print(run_args->file, "Error dsl_destroy_head"
+			    "(%s, ...) failed: %d\n", name, rc);
+	}
+
+	t->stop  = zpios_timespec_now();
+	t->delta = zpios_timespec_sub(t->stop, t->start);
+	(void) zpios_upcall(run_args->post, PHASE_POST_REMOVE, run_args, rc);
+}
+
+static void
+zpios_cleanup_run(run_args_t *run_args)
+{
+	int i, size = 0;
+
+	if (run_args == NULL)
+		return;
+
+	if (run_args->threads != NULL) {
+		for (i = 0; i < run_args->thread_count; i++) {
+			if (run_args->threads[i]) {
+				mutex_destroy(&run_args->threads[i]->lock);
+				kmem_free(run_args->threads[i],
+				    sizeof (thread_data_t));
+			}
+		}
+
+		kmem_free(run_args->threads,
+		    sizeof (thread_data_t *) * run_args->thread_count);
+	}
+
+	for (i = 0; i < run_args->region_count; i++)
+		mutex_destroy(&run_args->regions[i].lock);
+
+	mutex_destroy(&run_args->lock_work);
+	mutex_destroy(&run_args->lock_ctl);
+	size = run_args->region_count * sizeof (zpios_region_t);
+
+	vmem_free(run_args, sizeof (*run_args) + size);
+}
+
+static int
+zpios_dmu_write(run_args_t *run_args, objset_t *os, uint64_t object,
+		uint64_t offset, uint64_t size, const void *buf)
+{
+	struct dmu_tx *tx;
+	int rc, how = TXG_WAIT;
+//	int flags = 0;
+
+	if (run_args->flags & DMU_WRITE_NOWAIT)
+		how = TXG_NOWAIT;
+
+	while (1) {
+		tx = dmu_tx_create(os);
+		dmu_tx_hold_write(tx, object, offset, size);
+		rc = dmu_tx_assign(tx, how);
+
+		if (rc) {
+			if (rc == ERESTART && how == TXG_NOWAIT) {
+				dmu_tx_wait(tx);
+				dmu_tx_abort(tx);
+				continue;
+			}
+			zpios_print(run_args->file,
+				    "Error in dmu_tx_assign(), %d", rc);
+			dmu_tx_abort(tx);
+			return (rc);
+		}
+		break;
+	}
+
+//	if (run_args->flags & DMU_WRITE_ZC)
+//		flags |= DMU_WRITE_ZEROCOPY;
+
+	dmu_write(os, object, offset, size, buf, tx);
+	dmu_tx_commit(tx);
+
+	return (0);
+}
+
+static int
+zpios_dmu_read(run_args_t *run_args, objset_t *os, uint64_t object,
+    uint64_t offset, uint64_t size, void *buf)
+{
+	int flags = 0;
+
+//	if (run_args->flags & DMU_READ_ZC)
+//		flags |= DMU_READ_ZEROCOPY;
+
+	if (run_args->flags & DMU_READ_NOPF)
+		flags |= DMU_READ_NO_PREFETCH;
+
+	return (dmu_read(os, object, offset, size, buf, flags));
+}
+
+static int
+zpios_thread_main(void *data)
+{
+	thread_data_t *thr = (thread_data_t *)data;
+	run_args_t *run_args = thr->run_args;
+	zpios_time_t t;
+	dmu_obj_t obj;
+	__u64 offset;
+	__u32 chunk_size;
+	zpios_region_t *region;
+	char *buf;
+	unsigned int random_int;
+	int chunk_noise = run_args->chunk_noise;
+	int chunk_noise_tmp = 0;
+	int thread_delay = run_args->thread_delay;
+	int thread_delay_tmp = 0;
+	int i, rc = 0;
+
+	if (chunk_noise) {
+		get_random_bytes(&random_int, sizeof (unsigned int));
+		chunk_noise_tmp = (random_int % (chunk_noise * 2))-chunk_noise;
+	}
+
+	/*
+	 * It's OK to vmem_alloc() this memory because it will be copied
+	 * in to the slab and pointers to the slab copy will be setup in
+	 * the bio when the IO is submitted.  This of course is not ideal
+	 * since we want a zero-copy IO path if possible.  It would be nice
+	 * to have direct access to those slab entries.
+	 */
+	chunk_size = run_args->chunk_size + chunk_noise_tmp;
+	buf = (char *)vmem_alloc(chunk_size, KM_SLEEP);
+	ASSERT(buf);
+
+	/* Trivial data verification pattern for now. */
+	if (run_args->flags & DMU_VERIFY)
+		memset(buf, 'z', chunk_size);
+
+	/* Write phase */
+	mutex_enter(&thr->lock);
+	thr->stats.wr_time.start = zpios_timespec_now();
+	mutex_exit(&thr->lock);
+
+	while (zpios_get_work_item(run_args, &obj, &offset,
+	    &chunk_size, &region, DMU_WRITE)) {
+		if (thread_delay) {
+			get_random_bytes(&random_int, sizeof (unsigned int));
+			thread_delay_tmp = random_int % thread_delay;
+			set_current_state(TASK_UNINTERRUPTIBLE);
+			schedule_timeout(thread_delay_tmp); /* In jiffies */
+		}
+
+		t.start = zpios_timespec_now();
+		rc = zpios_dmu_write(run_args, obj.os, obj.obj,
+		    offset, chunk_size, buf);
+		t.stop  = zpios_timespec_now();
+		t.delta = zpios_timespec_sub(t.stop, t.start);
+
+		if (rc) {
+			zpios_print(run_args->file, "IO error while doing "
+				    "dmu_write(): %d\n", rc);
+			break;
+		}
+
+		mutex_enter(&thr->lock);
+		thr->stats.wr_data += chunk_size;
+		thr->stats.wr_chunks++;
+		thr->stats.wr_time.delta = zpios_timespec_add(
+		    thr->stats.wr_time.delta, t.delta);
+		mutex_exit(&thr->lock);
+
+		mutex_enter(&region->lock);
+		region->stats.wr_data += chunk_size;
+		region->stats.wr_chunks++;
+		region->stats.wr_time.delta = zpios_timespec_add(
+		    region->stats.wr_time.delta, t.delta);
+
+		/* First time region was accessed */
+		if (region->init_offset == offset)
+			region->stats.wr_time.start = t.start;
+
+		mutex_exit(&region->lock);
+	}
+
+	mutex_enter(&run_args->lock_ctl);
+	run_args->threads_done++;
+	mutex_exit(&run_args->lock_ctl);
+
+	mutex_enter(&thr->lock);
+	thr->rc = rc;
+	thr->stats.wr_time.stop = zpios_timespec_now();
+	mutex_exit(&thr->lock);
+	wake_up(&run_args->waitq);
+
+	set_current_state(TASK_UNINTERRUPTIBLE);
+	schedule();
+
+	/* Check if we should exit */
+	mutex_enter(&thr->lock);
+	rc = thr->rc;
+	mutex_exit(&thr->lock);
+	if (rc)
+		goto out;
+
+	/* Read phase */
+	mutex_enter(&thr->lock);
+	thr->stats.rd_time.start = zpios_timespec_now();
+	mutex_exit(&thr->lock);
+
+	while (zpios_get_work_item(run_args, &obj, &offset,
+	    &chunk_size, &region, DMU_READ)) {
+		if (thread_delay) {
+			get_random_bytes(&random_int, sizeof (unsigned int));
+			thread_delay_tmp = random_int % thread_delay;
+			set_current_state(TASK_UNINTERRUPTIBLE);
+			schedule_timeout(thread_delay_tmp); /* In jiffies */
+		}
+
+		if (run_args->flags & DMU_VERIFY)
+			memset(buf, 0, chunk_size);
+
+		t.start = zpios_timespec_now();
+		rc = zpios_dmu_read(run_args, obj.os, obj.obj,
+				    offset, chunk_size, buf);
+		t.stop  = zpios_timespec_now();
+		t.delta = zpios_timespec_sub(t.stop, t.start);
+
+		if (rc) {
+			zpios_print(run_args->file, "IO error while doing "
+				    "dmu_read(): %d\n", rc);
+			break;
+		}
+
+		/* Trivial data verification, expensive! */
+		if (run_args->flags & DMU_VERIFY) {
+			for (i = 0; i < chunk_size; i++) {
+				if (buf[i] != 'z') {
+					zpios_print(run_args->file,
+					    "IO verify error: %d/%d/%d\n",
+					    (int)obj.obj, (int)offset,
+					    (int)chunk_size);
+					break;
+				}
+			}
+		}
+
+		mutex_enter(&thr->lock);
+		thr->stats.rd_data += chunk_size;
+		thr->stats.rd_chunks++;
+		thr->stats.rd_time.delta = zpios_timespec_add(
+		    thr->stats.rd_time.delta, t.delta);
+		mutex_exit(&thr->lock);
+
+		mutex_enter(&region->lock);
+		region->stats.rd_data += chunk_size;
+		region->stats.rd_chunks++;
+		region->stats.rd_time.delta = zpios_timespec_add(
+		    region->stats.rd_time.delta, t.delta);
+
+		/* First time region was accessed */
+		if (region->init_offset == offset)
+			region->stats.rd_time.start = t.start;
+
+		mutex_exit(&region->lock);
+	}
+
+	mutex_enter(&run_args->lock_ctl);
+	run_args->threads_done++;
+	mutex_exit(&run_args->lock_ctl);
+
+	mutex_enter(&thr->lock);
+	thr->rc = rc;
+	thr->stats.rd_time.stop = zpios_timespec_now();
+	mutex_exit(&thr->lock);
+	wake_up(&run_args->waitq);
+
+out:
+	vmem_free(buf, chunk_size);
+	do_exit(0);
+
+	return (rc); /* Unreachable, due to do_exit() */
+}
+
+static int
+zpios_thread_done(run_args_t *run_args)
+{
+	ASSERT(run_args->threads_done <= run_args->thread_count);
+	return (run_args->threads_done == run_args->thread_count);
+}
+
+static int
+zpios_threads_run(run_args_t *run_args)
+{
+	struct task_struct *tsk, **tsks;
+	thread_data_t *thr = NULL;
+	zpios_time_t *tt = &(run_args->stats.total_time);
+	zpios_time_t *tw = &(run_args->stats.wr_time);
+	zpios_time_t *tr = &(run_args->stats.rd_time);
+	int i, rc = 0, tc = run_args->thread_count;
+
+	tsks = kmem_zalloc(sizeof (struct task_struct *) * tc, KM_SLEEP);
+	if (tsks == NULL) {
+		rc = -ENOMEM;
+		goto cleanup2;
+	}
+
+	run_args->threads = kmem_zalloc(sizeof (thread_data_t *)*tc, KM_SLEEP);
+	if (run_args->threads == NULL) {
+		rc = -ENOMEM;
+		goto cleanup;
+	}
+
+	init_waitqueue_head(&run_args->waitq);
+	run_args->threads_done = 0;
+
+	/* Create all the needed threads which will sleep until awoken */
+	for (i = 0; i < tc; i++) {
+		thr = kmem_zalloc(sizeof (thread_data_t), KM_SLEEP);
+		if (thr == NULL) {
+			rc = -ENOMEM;
+			goto taskerr;
+		}
+
+		thr->thread_no = i;
+		thr->run_args = run_args;
+		thr->rc = 0;
+		mutex_init(&thr->lock, NULL, MUTEX_DEFAULT, NULL);
+		run_args->threads[i] = thr;
+
+		tsk = kthread_create(zpios_thread_main, (void *)thr,
+		    "%s/%d", "zpios_io", i);
+		if (IS_ERR(tsk)) {
+			rc = -EINVAL;
+			goto taskerr;
+		}
+
+		tsks[i] = tsk;
+	}
+
+	tt->start = zpios_timespec_now();
+
+	/* Wake up all threads for write phase */
+	(void) zpios_upcall(run_args->pre, PHASE_PRE_WRITE, run_args, 0);
+	for (i = 0; i < tc; i++)
+		wake_up_process(tsks[i]);
+
+	/* Wait for write phase to complete */
+	tw->start = zpios_timespec_now();
+	wait_event(run_args->waitq, zpios_thread_done(run_args));
+	tw->stop = zpios_timespec_now();
+	(void) zpios_upcall(run_args->post, PHASE_POST_WRITE, run_args, rc);
+
+	for (i = 0; i < tc; i++) {
+		thr = run_args->threads[i];
+
+		mutex_enter(&thr->lock);
+
+		if (!rc && thr->rc)
+			rc = thr->rc;
+
+		run_args->stats.wr_data += thr->stats.wr_data;
+		run_args->stats.wr_chunks += thr->stats.wr_chunks;
+		mutex_exit(&thr->lock);
+	}
+
+	if (rc) {
+		/* Wake up all threads and tell them to exit */
+		for (i = 0; i < tc; i++) {
+			mutex_enter(&thr->lock);
+			thr->rc = rc;
+			mutex_exit(&thr->lock);
+
+			wake_up_process(tsks[i]);
+		}
+		goto out;
+	}
+
+	mutex_enter(&run_args->lock_ctl);
+	ASSERT(run_args->threads_done == run_args->thread_count);
+	run_args->threads_done = 0;
+	mutex_exit(&run_args->lock_ctl);
+
+	/* Wake up all threads for read phase */
+	(void) zpios_upcall(run_args->pre, PHASE_PRE_READ, run_args, 0);
+	for (i = 0; i < tc; i++)
+		wake_up_process(tsks[i]);
+
+	/* Wait for read phase to complete */
+	tr->start = zpios_timespec_now();
+	wait_event(run_args->waitq, zpios_thread_done(run_args));
+	tr->stop = zpios_timespec_now();
+	(void) zpios_upcall(run_args->post, PHASE_POST_READ, run_args, rc);
+
+	for (i = 0; i < tc; i++) {
+		thr = run_args->threads[i];
+
+		mutex_enter(&thr->lock);
+
+		if (!rc && thr->rc)
+			rc = thr->rc;
+
+		run_args->stats.rd_data += thr->stats.rd_data;
+		run_args->stats.rd_chunks += thr->stats.rd_chunks;
+		mutex_exit(&thr->lock);
+	}
+out:
+	tt->stop  = zpios_timespec_now();
+	tt->delta = zpios_timespec_sub(tt->stop, tt->start);
+	tw->delta = zpios_timespec_sub(tw->stop, tw->start);
+	tr->delta = zpios_timespec_sub(tr->stop, tr->start);
+
+cleanup:
+	kmem_free(tsks, sizeof (struct task_struct *) * tc);
+cleanup2:
+	/* Returns first encountered thread error (if any) */
+	return (rc);
+
+taskerr:
+	/* Destroy all threads that were created successfully */
+	for (i = 0; i < tc; i++)
+		if (tsks[i] != NULL)
+			(void) kthread_stop(tsks[i]);
+
+	goto cleanup;
+}
+
+static int
+zpios_do_one_run(struct file *file, zpios_cmd_t *kcmd,
+    int data_size, void *data)
+{
+	run_args_t *run_args = { 0 };
+	zpios_stats_t *stats = (zpios_stats_t *)data;
+	int i, n, m, size, rc;
+
+	if ((!kcmd->cmd_chunk_size) || (!kcmd->cmd_region_size) ||
+	    (!kcmd->cmd_thread_count) || (!kcmd->cmd_region_count)) {
+		zpios_print(file, "Invalid chunk_size, region_size, "
+		    "thread_count, or region_count, %d\n", -EINVAL);
+		return (-EINVAL);
+	}
+
+	if (!(kcmd->cmd_flags & DMU_WRITE) ||
+	    !(kcmd->cmd_flags & DMU_READ)) {
+		zpios_print(file, "Invalid flags, minimally DMU_WRITE "
+		    "and DMU_READ must be set, %d\n", -EINVAL);
+		return (-EINVAL);
+	}
+
+	if ((kcmd->cmd_flags & (DMU_WRITE_ZC | DMU_READ_ZC)) &&
+	    (kcmd->cmd_flags & DMU_VERIFY)) {
+		zpios_print(file, "Invalid flags, DMU_*_ZC incompatible "
+		    "with DMU_VERIFY, used for performance analysis "
+		    "only, %d\n", -EINVAL);
+		return (-EINVAL);
+	}
+
+	/*
+	 * Opaque data on return contains structs of the following form:
+	 *
+	 * zpios_stat_t stats[];
+	 * stats[0]     = run_args->stats;
+	 * stats[1-N]   = threads[N]->stats;
+	 * stats[N+1-M] = regions[M]->stats;
+	 *
+	 * Where N is the number of threads, and M is the number of regions.
+	 */
+	size = (sizeof (zpios_stats_t) +
+	    (kcmd->cmd_thread_count * sizeof (zpios_stats_t)) +
+	    (kcmd->cmd_region_count * sizeof (zpios_stats_t)));
+	if (data_size < size) {
+		zpios_print(file, "Invalid size, command data buffer "
+		    "size too small, (%d < %d)\n", data_size, size);
+		return (-ENOSPC);
+	}
+
+	rc = zpios_setup_run(&run_args, kcmd, file);
+	if (rc)
+		return (rc);
+
+	rc = zpios_threads_run(run_args);
+	zpios_remove_objset(run_args);
+	if (rc)
+		goto cleanup;
+
+	if (stats) {
+		n = 1;
+		m = 1 + kcmd->cmd_thread_count;
+		stats[0] = run_args->stats;
+
+		for (i = 0; i < kcmd->cmd_thread_count; i++)
+			stats[n+i] = run_args->threads[i]->stats;
+
+		for (i = 0; i < kcmd->cmd_region_count; i++)
+			stats[m+i] = run_args->regions[i].stats;
+	}
+
+cleanup:
+	zpios_cleanup_run(run_args);
+
+	(void) zpios_upcall(kcmd->cmd_post, PHASE_POST_RUN, run_args, 0);
+
+	return (rc);
+}
+
+static int
+zpios_open(struct inode *inode, struct file *file)
+{
+	zpios_info_t *info;
+
+	info = (zpios_info_t *)kmem_alloc(sizeof (*info), KM_SLEEP);
+	if (info == NULL)
+		return (-ENOMEM);
+
+	spin_lock_init(&info->info_lock);
+	info->info_size = ZPIOS_INFO_BUFFER_SIZE;
+	info->info_buffer =
+	    (char *) vmem_alloc(ZPIOS_INFO_BUFFER_SIZE, KM_SLEEP);
+	if (info->info_buffer == NULL) {
+		kmem_free(info, sizeof (*info));
+		return (-ENOMEM);
+	}
+
+	info->info_head = info->info_buffer;
+	file->private_data = (void *)info;
+
+	return (0);
+}
+
+static int
+zpios_release(struct inode *inode, struct file *file)
+{
+	zpios_info_t *info = (zpios_info_t *)file->private_data;
+
+	ASSERT(info);
+	ASSERT(info->info_buffer);
+
+	vmem_free(info->info_buffer, ZPIOS_INFO_BUFFER_SIZE);
+	kmem_free(info, sizeof (*info));
+
+	return (0);
+}
+
+static int
+zpios_buffer_clear(struct file *file, zpios_cfg_t *kcfg, unsigned long arg)
+{
+	zpios_info_t *info = (zpios_info_t *)file->private_data;
+
+	ASSERT(info);
+	ASSERT(info->info_buffer);
+
+	spin_lock(&info->info_lock);
+	memset(info->info_buffer, 0, info->info_size);
+	info->info_head = info->info_buffer;
+	spin_unlock(&info->info_lock);
+
+	return (0);
+}
+
+static int
+zpios_buffer_size(struct file *file, zpios_cfg_t *kcfg, unsigned long arg)
+{
+	zpios_info_t *info = (zpios_info_t *)file->private_data;
+	char *buf;
+	int min, size, rc = 0;
+
+	ASSERT(info);
+	ASSERT(info->info_buffer);
+
+	spin_lock(&info->info_lock);
+	if (kcfg->cfg_arg1 > 0) {
+
+		size = kcfg->cfg_arg1;
+		buf = (char *)vmem_alloc(size, KM_SLEEP);
+		if (buf == NULL) {
+			rc = -ENOMEM;
+			goto out;
+		}
+
+		/* Zero fill and truncate contents when coping buffer */
+		min = ((size < info->info_size) ? size : info->info_size);
+		memset(buf, 0, size);
+		memcpy(buf, info->info_buffer, min);
+		vmem_free(info->info_buffer, info->info_size);
+		info->info_size = size;
+		info->info_buffer = buf;
+		info->info_head = info->info_buffer;
+	}
+
+	kcfg->cfg_rc1 = info->info_size;
+
+	if (copy_to_user((struct zpios_cfg_t __user *)arg,
+	    kcfg, sizeof (*kcfg)))
+		rc = -EFAULT;
+out:
+	spin_unlock(&info->info_lock);
+
+	return (rc);
+}
+
+static int
+zpios_ioctl_cfg(struct file *file, unsigned long arg)
+{
+	zpios_cfg_t kcfg;
+	int rc = 0;
+
+	if (copy_from_user(&kcfg, (zpios_cfg_t *)arg, sizeof (kcfg)))
+		return (-EFAULT);
+
+	if (kcfg.cfg_magic != ZPIOS_CFG_MAGIC) {
+		zpios_print(file, "Bad config magic 0x%x != 0x%x\n",
+		    kcfg.cfg_magic, ZPIOS_CFG_MAGIC);
+		return (-EINVAL);
+	}
+
+	switch (kcfg.cfg_cmd) {
+		case ZPIOS_CFG_BUFFER_CLEAR:
+			/*
+			 * cfg_arg1 - Unused
+			 * cfg_rc1  - Unused
+			 */
+			rc = zpios_buffer_clear(file, &kcfg, arg);
+			break;
+		case ZPIOS_CFG_BUFFER_SIZE:
+			/*
+			 * cfg_arg1 - 0 - query size; >0 resize
+			 * cfg_rc1  - Set to current buffer size
+			 */
+			rc = zpios_buffer_size(file, &kcfg, arg);
+			break;
+		default:
+			zpios_print(file, "Bad config command %d\n",
+				    kcfg.cfg_cmd);
+			rc = -EINVAL;
+			break;
+	}
+
+	return (rc);
+}
+
+static int
+zpios_ioctl_cmd(struct file *file, unsigned long arg)
+{
+	zpios_cmd_t *kcmd;
+	void *data = NULL;
+	int rc = -EINVAL;
+
+	kcmd = kmem_alloc(sizeof (zpios_cmd_t), KM_SLEEP);
+	if (kcmd == NULL) {
+		zpios_print(file, "Unable to kmem_alloc() %ld byte for "
+			    "zpios_cmd_t\n", (long int)sizeof (zpios_cmd_t));
+		return (-ENOMEM);
+	}
+
+	rc = copy_from_user(kcmd, (zpios_cfg_t *)arg, sizeof (zpios_cmd_t));
+	if (rc) {
+		zpios_print(file, "Unable to copy command structure "
+			    "from user to kernel memory, %d\n", rc);
+		goto out_cmd;
+	}
+
+	if (kcmd->cmd_magic != ZPIOS_CMD_MAGIC) {
+		zpios_print(file, "Bad command magic 0x%x != 0x%x\n",
+		    kcmd->cmd_magic, ZPIOS_CFG_MAGIC);
+		rc = (-EINVAL);
+		goto out_cmd;
+	}
+
+	/* Allocate memory for any opaque data the caller needed to pass on */
+	if (kcmd->cmd_data_size > 0) {
+		data = (void *)vmem_alloc(kcmd->cmd_data_size, KM_SLEEP);
+		if (data == NULL) {
+			zpios_print(file, "Unable to vmem_alloc() %ld "
+				    "bytes for data buffer\n",
+				    (long)kcmd->cmd_data_size);
+			rc = -ENOMEM;
+			goto out_cmd;
+		}
+
+		rc = copy_from_user(data, (void *)(arg + offsetof(zpios_cmd_t,
+		    cmd_data_str)), kcmd->cmd_data_size);
+		if (rc) {
+			zpios_print(file, "Unable to copy data buffer "
+				    "from user to kernel memory, %d\n", rc);
+			goto out_data;
+		}
+	}
+
+	rc = zpios_do_one_run(file, kcmd, kcmd->cmd_data_size, data);
+
+	if (data != NULL) {
+		/* If the test failed do not print out the stats */
+		if (rc)
+			goto out_data;
+
+		rc = copy_to_user((void *)(arg + offsetof(zpios_cmd_t,
+		    cmd_data_str)), data, kcmd->cmd_data_size);
+		if (rc) {
+			zpios_print(file, "Unable to copy data buffer "
+				    "from kernel to user memory, %d\n", rc);
+			rc = -EFAULT;
+		}
+
+out_data:
+		vmem_free(data, kcmd->cmd_data_size);
+	}
+out_cmd:
+	kmem_free(kcmd, sizeof (zpios_cmd_t));
+
+	return (rc);
+}
+
+static long
+zpios_unlocked_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+	int rc = 0;
+
+	/* Ignore tty ioctls */
+	if ((cmd & 0xffffff00) == ((int)'T') << 8)
+		return (-ENOTTY);
+
+	switch (cmd) {
+		case ZPIOS_CFG:
+			rc = zpios_ioctl_cfg(file, arg);
+			break;
+		case ZPIOS_CMD:
+			rc = zpios_ioctl_cmd(file, arg);
+			break;
+		default:
+			zpios_print(file, "Bad ioctl command %d\n", cmd);
+			rc = -EINVAL;
+			break;
+	}
+
+	return (rc);
+}
+
+#ifdef CONFIG_COMPAT
+/* Compatibility handler for ioctls from 32-bit ELF binaries */
+static long
+zpios_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+	return (zpios_unlocked_ioctl(file, cmd, arg));
+}
+#endif /* CONFIG_COMPAT */
+
+/*
+ * I'm not sure why you would want to write in to this buffer from
+ * user space since its principle use is to pass test status info
+ * back to the user space, but I don't see any reason to prevent it.
+ */
+static ssize_t
+zpios_write(struct file *file, const char __user *buf,
+    size_t count, loff_t *ppos)
+{
+	zpios_info_t *info = (zpios_info_t *)file->private_data;
+	int rc = 0;
+
+	ASSERT(info);
+	ASSERT(info->info_buffer);
+
+	spin_lock(&info->info_lock);
+
+	/* Write beyond EOF */
+	if (*ppos >= info->info_size) {
+		rc = -EFBIG;
+		goto out;
+	}
+
+	/* Resize count if beyond EOF */
+	if (*ppos + count > info->info_size)
+		count = info->info_size - *ppos;
+
+	if (copy_from_user(info->info_buffer, buf, count)) {
+		rc = -EFAULT;
+		goto out;
+	}
+
+	*ppos += count;
+	rc = count;
+out:
+	spin_unlock(&info->info_lock);
+	return (rc);
+}
+
+static ssize_t
+zpios_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
+{
+	zpios_info_t *info = (zpios_info_t *)file->private_data;
+	int rc = 0;
+
+	ASSERT(info);
+	ASSERT(info->info_buffer);
+
+	spin_lock(&info->info_lock);
+
+	/* Read beyond EOF */
+	if (*ppos >= info->info_size)
+		goto out;
+
+	/* Resize count if beyond EOF */
+	if (*ppos + count > info->info_size)
+		count = info->info_size - *ppos;
+
+	if (copy_to_user(buf, info->info_buffer + *ppos, count)) {
+		rc = -EFAULT;
+		goto out;
+	}
+
+	*ppos += count;
+	rc = count;
+out:
+	spin_unlock(&info->info_lock);
+	return (rc);
+}
+
+static loff_t zpios_seek(struct file *file, loff_t offset, int origin)
+{
+	zpios_info_t *info = (zpios_info_t *)file->private_data;
+	int rc = -EINVAL;
+
+	ASSERT(info);
+	ASSERT(info->info_buffer);
+
+	spin_lock(&info->info_lock);
+
+	switch (origin) {
+	case 0: /* SEEK_SET - No-op just do it */
+		break;
+	case 1: /* SEEK_CUR - Seek from current */
+		offset = file->f_pos + offset;
+		break;
+	case 2: /* SEEK_END - Seek from end */
+		offset = info->info_size + offset;
+		break;
+	}
+
+	if (offset >= 0) {
+		file->f_pos = offset;
+		file->f_version = 0;
+		rc = offset;
+	}
+
+	spin_unlock(&info->info_lock);
+
+	return (rc);
+}
+
+static struct file_operations zpios_fops = {
+	.owner		= THIS_MODULE,
+	.open		= zpios_open,
+	.release	= zpios_release,
+	.unlocked_ioctl	= zpios_unlocked_ioctl,
+#ifdef CONFIG_COMPAT
+	.compat_ioctl	= zpios_compat_ioctl,
+#endif
+	.read		= zpios_read,
+	.write		= zpios_write,
+	.llseek		= zpios_seek,
+};
+
+static struct miscdevice zpios_misc = {
+	.minor		= MISC_DYNAMIC_MINOR,
+	.name		= ZPIOS_NAME,
+	.fops		= &zpios_fops,
+};
+
+#ifdef DEBUG
+#define	ZFS_DEBUG_STR   " (DEBUG mode)"
+#else
+#define	ZFS_DEBUG_STR   ""
+#endif
+
+static int __init
+zpios_init(void)
+{
+	int error;
+
+	error = misc_register(&zpios_misc);
+	if (error) {
+		printk(KERN_INFO "ZPIOS: misc_register() failed %d\n", error);
+	} else {
+		printk(KERN_INFO "ZPIOS: Loaded module v%s-%s%s\n",
+		    ZFS_META_VERSION, ZFS_META_RELEASE, ZFS_DEBUG_STR);
+	}
+
+	return (error);
+}
+
+static void __exit
+zpios_fini(void)
+{
+	misc_deregister(&zpios_misc);
+
+	printk(KERN_INFO "ZPIOS: Unloaded module v%s-%s%s\n",
+	    ZFS_META_VERSION, ZFS_META_RELEASE, ZFS_DEBUG_STR);
+}
+
+module_init(zpios_init);
+module_exit(zpios_fini);
+
+MODULE_AUTHOR("LLNL / Sun");
+MODULE_DESCRIPTION("Kernel PIOS implementation");
+MODULE_LICENSE("GPL");
+MODULE_VERSION(ZFS_META_VERSION "-" ZFS_META_RELEASE);
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/rpm/Makefile.in
@@ -0,0 +1,2 @@
+%:
+	#
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/rpm/generic/Makefile.in
@@ -0,0 +1,2 @@
+%:
+	#
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/rpm/generic/zfs-dkms.spec.in
@@ -0,0 +1,2 @@
+%:
+	#
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/rpm/generic/zfs-kmod.spec.in
@@ -0,0 +1,2 @@
+%:
+	#
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/rpm/generic/zfs.spec.in
@@ -0,0 +1,2 @@
+%:
+	#
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/rpm/redhat/Makefile.in
@@ -0,0 +1,2 @@
+%:
+	#
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/rpm/redhat/zfs-dkms.spec.in
@@ -0,0 +1,2 @@
+%:
+	#
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/rpm/redhat/zfs-kmod.spec.in
@@ -0,0 +1,2 @@
+%:
+	#
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/rpm/redhat/zfs.spec.in
@@ -0,0 +1,2 @@
+%:
+	#
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/scripts/Makefile.in
@@ -0,0 +1,2 @@
+%:
+	#
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/scripts/common.sh.in
@@ -0,0 +1,2 @@
+%:
+	#
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/scripts/zpios-profile/Makefile.in
@@ -0,0 +1,2 @@
+%:
+	#
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/scripts/zpios-test/Makefile.in
@@ -0,0 +1,2 @@
+%:
+	#
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/scripts/zpool-config/Makefile.in
@@ -0,0 +1,2 @@
+%:
+	#
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/udev/Makefile.in
@@ -0,0 +1,2 @@
+%:
+	#
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/udev/rules.d/60-zvol.rules.in
@@ -0,0 +1,2 @@
+%:
+	#
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/udev/rules.d/69-vdev.rules.in
@@ -0,0 +1,2 @@
+%:
+	#
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/udev/rules.d/90-zfs.rules.in
@@ -0,0 +1,2 @@
+%:
+	#
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/udev/rules.d/Makefile.in
@@ -0,0 +1,2 @@
+%:
+	#
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/zfs-script-config.sh.in
@@ -0,0 +1,66 @@
+#!/bin/bash
+
+KERNELSRC=@LINUX@
+KERNELBUILD=@LINUX_OBJ@
+KERNELSRCVER=@LINUX_VERSION@
+KERNELMOD=/lib/modules/${KERNELSRCVER}/kernel
+
+SPLSRC=@SPL@
+SPLBUILD=@SPL_OBJ@
+SPLSRCVER=@SPL_VERSION@
+
+SRCDIR=@abs_top_srcdir@
+BUILDDIR=@abs_top_builddir@
+LIBDIR=${BUILDDIR}/lib
+CMDDIR=${BUILDDIR}/cmd
+MODDIR=${BUILDDIR}/module
+SCRIPTDIR=${BUILDDIR}/scripts
+ZPOOLDIR=${BUILDDIR}/scripts/zpool-config
+ZPIOSDIR=${BUILDDIR}/scripts/zpios-test
+ZPIOSPROFILEDIR=${BUILDDIR}/scripts/zpios-profile
+ETCDIR=${SRCDIR}/etc
+
+ZDB=${CMDDIR}/zdb/zdb
+ZFS=${CMDDIR}/zfs/zfs
+ZINJECT=${CMDDIR}/zinject/zinject
+ZPOOL=${CMDDIR}/zpool/zpool
+ZTEST=${CMDDIR}/ztest/ztest
+ZPIOS=${CMDDIR}/zpios/zpios
+
+COMMON_SH=${SCRIPTDIR}/common.sh
+ZFS_SH=${SCRIPTDIR}/zfs.sh
+ZPOOL_CREATE_SH=${SCRIPTDIR}/zpool-create.sh
+ZPIOS_SH=${SCRIPTDIR}/zpios.sh
+ZPIOS_SURVEY_SH=${SCRIPTDIR}/zpios-survey.sh
+
+INTREE=1
+LDMOD=/sbin/insmod
+
+ZED_PIDFILE=@runstatedir@/zed.pid
+
+KERNEL_MODULES=(                                      \
+        ${KERNELMOD}/lib/zlib_deflate/zlib_deflate.ko \
+        ${KERNELMOD}/lib/zlib_inflate/zlib_inflate.ko \
+)
+
+SPL_MODULES=(                                         \
+        ${SPLBUILD}/module/spl/spl.ko                 \
+        ${SPLBUILD}/module/splat/splat.ko             \
+)
+
+ZFS_MODULES=(                                         \
+        ${MODDIR}/avl/zavl.ko                         \
+        ${MODDIR}/nvpair/znvpair.ko                   \
+        ${MODDIR}/unicode/zunicode.ko                 \
+        ${MODDIR}/zcommon/zcommon.ko                  \
+        ${MODDIR}/zfs/zfs.ko                          \
+)
+
+ZPIOS_MODULES=(                                       \
+        ${MODDIR}/zpios/zpios.ko                      \
+)
+
+MODULES=(                                             \
+        ${SPL_MODULES[*]}                             \
+        ${ZFS_MODULES[*]}                             \
+)
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/zfs.release.in
@@ -0,0 +1 @@
+@ZFS_META_VERSION@-@ZFS_META_RELEASE@
--- /dev/null
+++ zfcpdump-kernel-4.4/zfs/zfs_config.h.in
@@ -0,0 +1,455 @@
+/* zfs_config.h.in.  Generated from configure.ac by autoheader.  */
+
+/* Define to 1 to enabled dmu tx validation */
+#undef DEBUG_DMU_TX
+
+/* bio_end_io_t wants 1 arg */
+#undef HAVE_1ARG_BIO_END_IO_T
+
+/* invalidate_bdev() wants 1 arg */
+#undef HAVE_1ARG_INVALIDATE_BDEV
+
+/* kmap_atomic wants 1 args */
+#undef HAVE_1ARG_KMAP_ATOMIC
+
+/* bdi_setup_and_register() wants 2 args */
+#undef HAVE_2ARGS_BDI_SETUP_AND_REGISTER
+
+/* bdi_setup_and_register() wants 3 args */
+#undef HAVE_3ARGS_BDI_SETUP_AND_REGISTER
+
+/* blkdev_get() wants 3 args */
+#undef HAVE_3ARG_BLKDEV_GET
+
+/* sget() wants 5 args */
+#undef HAVE_5ARG_SGET
+
+/* security_inode_init_security wants 6 args */
+#undef HAVE_6ARGS_SECURITY_INODE_INIT_SECURITY
+
+/* dops->automount() exists */
+#undef HAVE_AUTOMOUNT
+
+/* struct block_device_operations use bdevs */
+#undef HAVE_BDEV_BLOCK_DEVICE_OPERATIONS
+
+/* bdev_logical_block_size() is available */
+#undef HAVE_BDEV_LOGICAL_BLOCK_SIZE
+
+/* bdev_physical_block_size() is available */
+#undef HAVE_BDEV_PHYSICAL_BLOCK_SIZE
+
+/* bio has bi_iter */
+#undef HAVE_BIO_BVEC_ITER
+
+/* BIO_RW_BARRIER is defined */
+#undef HAVE_BIO_RW_BARRIER
+
+/* BIO_RW_DISCARD is defined */
+#undef HAVE_BIO_RW_DISCARD
+
+/* BIO_RW_FAILFAST_* are defined */
+#undef HAVE_BIO_RW_FAILFAST_DTD
+
+/* blkdev_get_by_path() is available */
+#undef HAVE_BLKDEV_GET_BY_PATH
+
+/* blk_queue_flush() is available */
+#undef HAVE_BLK_QUEUE_FLUSH
+
+/* blk_queue_flush() is GPL-only */
+#undef HAVE_BLK_QUEUE_FLUSH_GPL_ONLY
+
+/* blk_queue_max_hw_sectors() is available */
+#undef HAVE_BLK_QUEUE_MAX_HW_SECTORS
+
+/* blk_queue_max_segments() is available */
+#undef HAVE_BLK_QUEUE_MAX_SEGMENTS
+
+/* struct block_device_operations.release returns void */
+#undef HAVE_BLOCK_DEVICE_OPERATIONS_RELEASE_VOID
+
+/* security_inode_init_security wants callback */
+#undef HAVE_CALLBACK_SECURITY_INODE_INIT_SECURITY
+
+/* iops->check_acl() exists */
+#undef HAVE_CHECK_ACL
+
+/* iops->check_acl() wants flags */
+#undef HAVE_CHECK_ACL_WITH_FLAGS
+
+/* check_disk_size_change() is available */
+#undef HAVE_CHECK_DISK_SIZE_CHANGE
+
+/* clear_inode() is available */
+#undef HAVE_CLEAR_INODE
+
+/* eops->commit_metadata() exists */
+#undef HAVE_COMMIT_METADATA
+
+/* dentry uses const struct dentry_operations */
+#undef HAVE_CONST_DENTRY_OPERATIONS
+
+/* super_block uses const struct xattr_handler */
+#undef HAVE_CONST_XATTR_HANDLER
+
+/* iops->create() passes nameidata */
+#undef HAVE_CREATE_NAMEIDATA
+
+/* current->bio_list exists */
+#undef HAVE_CURRENT_BIO_LIST
+
+/* current->bio_tail exists */
+#undef HAVE_CURRENT_BIO_TAIL
+
+/* current_umask() exists */
+#undef HAVE_CURRENT_UMASK
+
+/* DECLARE_EVENT_CLASS() is available */
+#undef HAVE_DECLARE_EVENT_CLASS
+
+/* sops->dirty_inode() wants flags */
+#undef HAVE_DIRTY_INODE_WITH_FLAGS
+
+/* ql->discard_granularity is available */
+#undef HAVE_DISCARD_GRANULARITY
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#undef HAVE_DLFCN_H
+
+/* d_make_root() is available */
+#undef HAVE_D_MAKE_ROOT
+
+/* d_obtain_alias() is available */
+#undef HAVE_D_OBTAIN_ALIAS
+
+/* d_prune_aliases() is available */
+#undef HAVE_D_PRUNE_ALIASES
+
+/* dops->d_revalidate() operation takes nameidata */
+#undef HAVE_D_REVALIDATE_NAMEIDATA
+
+/* d_set_d_op() is available */
+#undef HAVE_D_SET_D_OP
+
+/* elevator_change() is available */
+#undef HAVE_ELEVATOR_CHANGE
+
+/* eops->encode_fh() wants child and parent inodes */
+#undef HAVE_ENCODE_FH_WITH_INODE
+
+/* sops->evict_inode() exists */
+#undef HAVE_EVICT_INODE
+
+/* fops->fallocate() exists */
+#undef HAVE_FILE_FALLOCATE
+
+/* file_inode() is available */
+#undef HAVE_FILE_INODE
+
+/* kernel defines fmode_t */
+#undef HAVE_FMODE_T
+
+/* follow_down_one() is available */
+#undef HAVE_FOLLOW_DOWN_ONE
+
+/* iops->follow_link() cookie */
+#undef HAVE_FOLLOW_LINK_COOKIE
+
+/* iops->follow_link() nameidata */
+#undef HAVE_FOLLOW_LINK_NAMEIDATA
+
+/* sops->free_cached_objects() exists */
+#undef HAVE_FREE_CACHED_OBJECTS
+
+/* fops->fsync() with range */
+#undef HAVE_FSYNC_RANGE
+
+/* fops->fsync() without dentry */
+#undef HAVE_FSYNC_WITHOUT_DENTRY
+
+/* fops->fsync() with dentry */
+#undef HAVE_FSYNC_WITH_DENTRY
+
+/* generic_start_io_acct()/generic_end_io_acct() avaliable */
+#undef HAVE_GENERIC_IO_ACCT
+
+/* iops->get_acl() exists */
+#undef HAVE_GET_ACL
+
+/* blk_disk_ro() is available */
+#undef HAVE_GET_DISK_RO
+
+/* get_gendisk() is available */
+#undef HAVE_GET_GENDISK
+
+/* iops->get_link() cookie */
+#undef HAVE_GET_LINK_COOKIE
+
+/* iops->get_link() delayed */
+#undef HAVE_GET_LINK_DELAYED
+
+/* fops->fallocate() exists */
+#undef HAVE_INODE_FALLOCATE
+
+/* inode_owner_or_capable() exists */
+#undef HAVE_INODE_OWNER_OR_CAPABLE
+
+/* iops->truncate_range() exists */
+#undef HAVE_INODE_TRUNCATE_RANGE
+
+/* insert_inode_locked() is available */
+#undef HAVE_INSERT_INODE_LOCKED
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#undef HAVE_INTTYPES_H
+
+/* is_owner_or_cap() exists */
+#undef HAVE_IS_OWNER_OR_CAP
+
+/* kernel defines KOBJ_NAME_LEN */
+#undef HAVE_KOBJ_NAME_LEN
+
+/* Define if you have libblkid */
+#undef HAVE_LIBBLKID
+
+/* Define if you have libuuid */
+#undef HAVE_LIBUUID
+
+/* Define to 1 if you have the `z' library (-lz). */
+#undef HAVE_LIBZ
+
+/* lookup_bdev() is available */
+#undef HAVE_LOOKUP_BDEV
+
+/* iops->lookup() passes nameidata */
+#undef HAVE_LOOKUP_NAMEIDATA
+
+/* lseek_execute() is available */
+#undef HAVE_LSEEK_EXECUTE
+
+/* Noting that make_request_fn() returns int */
+#undef HAVE_MAKE_REQUEST_FN_RET_INT
+
+/* Noting that make_request_fn() returns blk_qc_t */
+#undef HAVE_MAKE_REQUEST_FN_RET_QC
+
+/* Define to 1 if you have the <memory.h> header file. */
+#undef HAVE_MEMORY_H
+
+/* iops->create()/mkdir()/mknod() take umode_t */
+#undef HAVE_MKDIR_UMODE_T
+
+/* Define to 1 if you have the `mlockall' function. */
+#undef HAVE_MLOCKALL
+
+/* mount_nodev() is available */
+#undef HAVE_MOUNT_NODEV
+
+/* sops->nr_cached_objects() exists */
+#undef HAVE_NR_CACHED_OBJECTS
+
+/* open_bdev_exclusive() is available */
+#undef HAVE_OPEN_BDEV_EXCLUSIVE
+
+/* iops->permission() exists */
+#undef HAVE_PERMISSION
+
+/* iops->permission() with nameidata exists */
+#undef HAVE_PERMISSION_WITH_NAMEIDATA
+
+/* inode contains i_acl and i_default_acl */
+#undef HAVE_POSIX_ACL_CACHING
+
+/* posix_acl_chmod() exists */
+#undef HAVE_POSIX_ACL_CHMOD
+
+/* posix_acl_equiv_mode wants umode_t* */
+#undef HAVE_POSIX_ACL_EQUIV_MODE_UMODE_T
+
+/* posix_acl_from_xattr() needs user_ns */
+#undef HAVE_POSIX_ACL_FROM_XATTR_USERNS
+
+/* posix_acl_release() is available */
+#undef HAVE_POSIX_ACL_RELEASE
+
+/* posix_acl_release() is GPL-only */
+#undef HAVE_POSIX_ACL_RELEASE_GPL_ONLY
+
+/* iops->put_link() cookie */
+#undef HAVE_PUT_LINK_COOKIE
+
+/* iops->put_link() delayed */
+#undef HAVE_PUT_LINK_DELAYED
+
+/* iops->put_link() nameidata */
+#undef HAVE_PUT_LINK_NAMEIDATA
+
+/* REQ_FAILFAST_MASK is defined */
+#undef HAVE_REQ_FAILFAST_MASK
+
+/* set_nlink() is available */
+#undef HAVE_SET_NLINK
+
+/* sops->show_options() with dentry */
+#undef HAVE_SHOW_OPTIONS_WITH_DENTRY
+
+/* struct super_block has s_shrink */
+#undef HAVE_SHRINK
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#undef HAVE_STDINT_H
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#undef HAVE_STDLIB_H
+
+/* Define to 1 if you have the <strings.h> header file. */
+#undef HAVE_STRINGS_H
+
+/* Define to 1 if you have the <string.h> header file. */
+#undef HAVE_STRING_H
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#undef HAVE_SYS_STAT_H
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#undef HAVE_SYS_TYPES_H
+
+/* struct super_block has s_d_op */
+#undef HAVE_S_D_OP
+
+/* struct super_block has s_instances list_head */
+#undef HAVE_S_INSTANCES_LIST_HEAD
+
+/* truncate_setsize() is available */
+#undef HAVE_TRUNCATE_SETSIZE
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#undef HAVE_UNISTD_H
+
+/* fops->iterate() is available */
+#undef HAVE_VFS_ITERATE
+
+/* fops->readdir() is available */
+#undef HAVE_VFS_READDIR
+
+/* fops->read/write_iter() are available */
+#undef HAVE_VFS_RW_ITERATE
+
+/* xattr_handler->get() wants dentry */
+#undef HAVE_XATTR_GET_DENTRY
+
+/* xattr_handler->get() wants xattr_handler */
+#undef HAVE_XATTR_GET_HANDLER
+
+/* xattr_handler->get() wants inode */
+#undef HAVE_XATTR_GET_INODE
+
+/* xattr_handler->list() wants dentry */
+#undef HAVE_XATTR_LIST_DENTRY
+
+/* xattr_handler->list() wants xattr_handler */
+#undef HAVE_XATTR_LIST_HANDLER
+
+/* xattr_handler->list() wants inode */
+#undef HAVE_XATTR_LIST_INODE
+
+/* xattr_handler->list() wants simple */
+#undef HAVE_XATTR_LIST_SIMPLE
+
+/* xattr_handler->set() wants dentry */
+#undef HAVE_XATTR_SET_DENTRY
+
+/* xattr_handler->set() wants xattr_handler */
+#undef HAVE_XATTR_SET_HANDLER
+
+/* xattr_handler->set() wants inode */
+#undef HAVE_XATTR_SET_INODE
+
+/* Define if you have zlib */
+#undef HAVE_ZLIB
+
+/* __posix_acl_chmod() exists */
+#undef HAVE___POSIX_ACL_CHMOD
+
+/* Define to the sub-directory where libtool stores uninstalled libraries. */
+#undef LT_OBJDIR
+
+/* make_request_fn() returns blk_qc_t */
+#undef MAKE_REQUEST_FN_RET
+
+/* Name of package */
+#undef PACKAGE
+
+/* Define to the address where bug reports for this package should be sent. */
+#undef PACKAGE_BUGREPORT
+
+/* Define to the full name of this package. */
+#undef PACKAGE_NAME
+
+/* Define to the full name and version of this package. */
+#undef PACKAGE_STRING
+
+/* Define to the one symbol short name of this package. */
+#undef PACKAGE_TARNAME
+
+/* Define to the home page for this package. */
+#undef PACKAGE_URL
+
+/* Define to the version of this package. */
+#undef PACKAGE_VERSION
+
+/* struct shrink_control has nid */
+#undef SHRINK_CONTROL_HAS_NID
+
+/* Define to 1 if you have the ANSI C header files. */
+#undef STDC_HEADERS
+
+/* Version number of package */
+#undef VERSION
+
+/* zfs debugging enabled */
+#undef ZFS_DEBUG
+
+/* Define to 1 if GPL-only symbols can be used */
+#undef ZFS_IS_GPL_COMPATIBLE
+
+/* Define the project alias string. */
+#undef ZFS_META_ALIAS
+
+/* Define the project author. */
+#undef ZFS_META_AUTHOR
+
+/* Define the project release date. */
+#undef ZFS_META_DATA
+
+/* Define the project license. */
+#undef ZFS_META_LICENSE
+
+/* Define the libtool library 'age' version information. */
+#undef ZFS_META_LT_AGE
+
+/* Define the libtool library 'current' version information. */
+#undef ZFS_META_LT_CURRENT
+
+/* Define the libtool library 'revision' version information. */
+#undef ZFS_META_LT_REVISION
+
+/* Define the project name. */
+#undef ZFS_META_NAME
+
+/* Define the project release. */
+#undef ZFS_META_RELEASE
+
+/* Define the project version. */
+#undef ZFS_META_VERSION
+
+
+#undef PACKAGE
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+#undef STDC_HEADERS
+#undef VERSION
